diff --git a/product/src/gui/GraphTool/GraphTool.pro b/product/src/gui/GraphTool/GraphTool.pro index 8f55944b..ffa729f5 100644 --- a/product/src/gui/GraphTool/GraphTool.pro +++ b/product/src/gui/GraphTool/GraphTool.pro @@ -1,3 +1,3 @@ -TEMPLATE=subdirs -CONFIG += ordered -SUBDIRS+= fileSync NavigationApi NavigationTool IconActTool +TEMPLATE=subdirs +CONFIG += ordered +SUBDIRS+= fileSync NavigationApi NavigationTool IconActTool diff --git a/product/src/gui/GraphTool/IconActTool/CFileOpt.cpp b/product/src/gui/GraphTool/IconActTool/CFileOpt.cpp index 5052fa62..1addb11f 100644 --- a/product/src/gui/GraphTool/IconActTool/CFileOpt.cpp +++ b/product/src/gui/GraphTool/IconActTool/CFileOpt.cpp @@ -1,238 +1,238 @@ -#include "CFileOpt.h" -#include "public/pub_logger_api/logger.h" -#include "public/pub_utility_api/FileUtil.h" -#include -#include -#include -#include -#include -#include -#include - -CFileOpt::CFileOpt() -{ - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - readColorCofig(QString::fromStdString(currentPath) + "/../../data/model/colorConfig.xml", m_strategyMap); - readIconDefaultStrategy(QString::fromStdString(currentPath) + "/../../data/model/toolbox.xml", m_iconDefaultStrategyMap); -} - -QString CFileOpt::getDefaultStrategy(const QString &icon) -{ - QString strategy = m_iconDefaultStrategyMap.value(icon); - if(!strategy.isEmpty()) - { - return getStrategyDesc(strategy); - } - return QString(); -} - -QMap CFileOpt::getStrategyMap() -{ - return m_strategyMap; -} - -QString CFileOpt::getStrategyDesc(const QVariant &key) -{ - return m_strategyMap.value(key); -} - -void CFileOpt::readColorCofig(const QString &path, QMap &map) -{ - QFile file(path); - if(!file.open(QIODevice::ReadOnly)) - { - LOGERROR("CFileOpt::readColorCofig cannot open file, path: %s", path.toStdString().c_str()); - return; - } - QDomDocument document; - bool ret = document.setContent(&file); - file.close(); - if(!ret) - { - LOGERROR("CFileOpt::readColorCofig error"); - return; - } - QDomElement root = document.documentElement(); - QDomNodeList nodeList = root.childNodes(); - QString name; - QString desc; - for(int nIndex(0); nIndex &list) -{ - QFile file(path); - QByteArray readJson; - if(file.open(QIODevice::ReadOnly)) - { - readJson = file.readAll(); - file.close(); - } - else - { - LOGERROR("CFileOpt::readIconAction cannot open file, path: %s", path.toStdString().c_str()); - return; - } - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CFileOpt:readIconAction error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return; - } - QJsonObject root = readJsonResponse.object(); - QJsonObject::const_iterator rootIter = root.constBegin(); - ST_ICONACT st_icon; - QString strategy; - for(; rootIter != root.constEnd(); rootIter++) - { - QJsonObject item = rootIter.value().toObject(); - st_icon.name = rootIter.key(); - st_icon.action = item.value("Action").toInt(); - st_icon.panel = item.value("Panel").toString(); - st_icon.simulate = item.value("Simulate").toInt(); - strategy = m_iconDefaultStrategyMap.value(st_icon.name); - if(!strategy.isEmpty()) - { - st_icon.strategy = getStrategyDesc(strategy); - } - else - { - st_icon.strategy = QString(); - } - list.append(st_icon); - } -} - -bool CFileOpt::saveIconAction(const QString &path, const QList &list) -{ - QFile file(path); - if(!file.open(QIODevice::WriteOnly)) - { - LOGERROR("CFileOpt::saveIconAction cannot open file, path: %s", path.toStdString().c_str()); - return false; - } - QJsonDocument doc; - QJsonObject obj; - foreach (ST_ICONACT st_icon, list) { - QJsonObject temp; - temp.insert("Action", st_icon.action); - temp.insert("Panel", st_icon.panel); - temp.insert("Simulate", st_icon.simulate); - obj.insert(st_icon.name, temp); - } - doc.setObject(obj); - if(-1 == file.write(doc.toJson())) - { - LOGERROR("CFileOpt::saveIconAction write false, path: %s", path.toStdString().c_str()); - file.close(); - return false; - } - file.close(); - return true; -} - -void CFileOpt::readIconDefaultStrategy(const QString &path, QMap &map) -{ - QFile file(path); - if(!file.open(QIODevice::ReadOnly)) - { - LOGERROR("CFileOpt::readToolbox cannot open file, path: %s", path.toStdString().c_str()); - return; - } - QDomDocument document; - bool ret = document.setContent(&file); - file.close(); - if(!ret) - { - LOGERROR("CFileOpt::readToolbox error"); - return; - } - QDomElement root = document.documentElement(); - makeIconDefaultStrategy(root, map); -} - -bool CFileOpt::saveIconDefaultStrategy(const QString &path, const QMap &map) -{ - QFile file(path); - if(!file.open(QIODevice::ReadOnly)) - { - LOGERROR("CFileOpt::readToolbox cannot open file, path: %s", path.toStdString().c_str()); - return false; - } - QDomDocument document; - bool ret = document.setContent(&file); - file.close(); - if(!ret) - { - LOGERROR("CFileOpt::readToolbox error"); - return false; - } - QDomElement root = document.documentElement(); - replaceIconDefaultStretegy(root, map); - if(!file.open(QIODevice::WriteOnly)) - { - LOGERROR("CFileOpt::readToolbox cannot open file, path: %s", path.toStdString().c_str()); - return false; - } - QTextStream content(&file); - document.save(content, 1); - file.close(); - return true; -} - -void CFileOpt::makeIconDefaultStrategy(QDomElement element, QMap &map) -{ - QString strategy; - QDomNodeList nodeList = element.childNodes(); - for(int nIndex(0); nIndex &map) -{ - QString strategy; - QString newStrategy; - QDomNodeList nodeList = element.childNodes(); - for(int nIndex(0); nIndex::const_iterator iter = map.find(node.tagName()); - if(iter == map.constEnd()) - { - replaceIconDefaultStretegy(node, map); - continue; - } - newStrategy = map[node.tagName()]; - if(strategy != newStrategy) - { - node.setAttribute("strategy", newStrategy); - if(newStrategy.isEmpty()) - { - node.removeAttribute("strategy"); - } - element.replaceChild(node, oldNode); - } - replaceIconDefaultStretegy(node, map); - } -} +#include "CFileOpt.h" +#include "public/pub_logger_api/logger.h" +#include "public/pub_utility_api/FileUtil.h" +#include +#include +#include +#include +#include +#include +#include + +CFileOpt::CFileOpt() +{ + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + readColorCofig(QString::fromStdString(currentPath) + "/../../data/model/colorConfig.xml", m_strategyMap); + readIconDefaultStrategy(QString::fromStdString(currentPath) + "/../../data/model/toolbox.xml", m_iconDefaultStrategyMap); +} + +QString CFileOpt::getDefaultStrategy(const QString &icon) +{ + QString strategy = m_iconDefaultStrategyMap.value(icon); + if(!strategy.isEmpty()) + { + return getStrategyDesc(strategy); + } + return QString(); +} + +QMap CFileOpt::getStrategyMap() +{ + return m_strategyMap; +} + +QString CFileOpt::getStrategyDesc(const QVariant &key) +{ + return m_strategyMap.value(key); +} + +void CFileOpt::readColorCofig(const QString &path, QMap &map) +{ + QFile file(path); + if(!file.open(QIODevice::ReadOnly)) + { + LOGERROR("CFileOpt::readColorCofig cannot open file, path: %s", path.toStdString().c_str()); + return; + } + QDomDocument document; + bool ret = document.setContent(&file); + file.close(); + if(!ret) + { + LOGERROR("CFileOpt::readColorCofig error"); + return; + } + QDomElement root = document.documentElement(); + QDomNodeList nodeList = root.childNodes(); + QString name; + QString desc; + for(int nIndex(0); nIndex &list) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + else + { + LOGERROR("CFileOpt::readIconAction cannot open file, path: %s", path.toStdString().c_str()); + return; + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CFileOpt:readIconAction error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + QJsonObject::const_iterator rootIter = root.constBegin(); + ST_ICONACT st_icon; + QString strategy; + for(; rootIter != root.constEnd(); rootIter++) + { + QJsonObject item = rootIter.value().toObject(); + st_icon.name = rootIter.key(); + st_icon.action = item.value("Action").toInt(); + st_icon.panel = item.value("Panel").toString(); + st_icon.simulate = item.value("Simulate").toInt(); + strategy = m_iconDefaultStrategyMap.value(st_icon.name); + if(!strategy.isEmpty()) + { + st_icon.strategy = getStrategyDesc(strategy); + } + else + { + st_icon.strategy = QString(); + } + list.append(st_icon); + } +} + +bool CFileOpt::saveIconAction(const QString &path, const QList &list) +{ + QFile file(path); + if(!file.open(QIODevice::WriteOnly)) + { + LOGERROR("CFileOpt::saveIconAction cannot open file, path: %s", path.toStdString().c_str()); + return false; + } + QJsonDocument doc; + QJsonObject obj; + foreach (ST_ICONACT st_icon, list) { + QJsonObject temp; + temp.insert("Action", st_icon.action); + temp.insert("Panel", st_icon.panel); + temp.insert("Simulate", st_icon.simulate); + obj.insert(st_icon.name, temp); + } + doc.setObject(obj); + if(-1 == file.write(doc.toJson())) + { + LOGERROR("CFileOpt::saveIconAction write false, path: %s", path.toStdString().c_str()); + file.close(); + return false; + } + file.close(); + return true; +} + +void CFileOpt::readIconDefaultStrategy(const QString &path, QMap &map) +{ + QFile file(path); + if(!file.open(QIODevice::ReadOnly)) + { + LOGERROR("CFileOpt::readToolbox cannot open file, path: %s", path.toStdString().c_str()); + return; + } + QDomDocument document; + bool ret = document.setContent(&file); + file.close(); + if(!ret) + { + LOGERROR("CFileOpt::readToolbox error"); + return; + } + QDomElement root = document.documentElement(); + makeIconDefaultStrategy(root, map); +} + +bool CFileOpt::saveIconDefaultStrategy(const QString &path, const QMap &map) +{ + QFile file(path); + if(!file.open(QIODevice::ReadOnly)) + { + LOGERROR("CFileOpt::readToolbox cannot open file, path: %s", path.toStdString().c_str()); + return false; + } + QDomDocument document; + bool ret = document.setContent(&file); + file.close(); + if(!ret) + { + LOGERROR("CFileOpt::readToolbox error"); + return false; + } + QDomElement root = document.documentElement(); + replaceIconDefaultStretegy(root, map); + if(!file.open(QIODevice::WriteOnly)) + { + LOGERROR("CFileOpt::readToolbox cannot open file, path: %s", path.toStdString().c_str()); + return false; + } + QTextStream content(&file); + document.save(content, 1); + file.close(); + return true; +} + +void CFileOpt::makeIconDefaultStrategy(QDomElement element, QMap &map) +{ + QString strategy; + QDomNodeList nodeList = element.childNodes(); + for(int nIndex(0); nIndex &map) +{ + QString strategy; + QString newStrategy; + QDomNodeList nodeList = element.childNodes(); + for(int nIndex(0); nIndex::const_iterator iter = map.find(node.tagName()); + if(iter == map.constEnd()) + { + replaceIconDefaultStretegy(node, map); + continue; + } + newStrategy = map[node.tagName()]; + if(strategy != newStrategy) + { + node.setAttribute("strategy", newStrategy); + if(newStrategy.isEmpty()) + { + node.removeAttribute("strategy"); + } + element.replaceChild(node, oldNode); + } + replaceIconDefaultStretegy(node, map); + } +} diff --git a/product/src/gui/GraphTool/IconActTool/CFileOpt.h b/product/src/gui/GraphTool/IconActTool/CFileOpt.h index 142f2c7f..f542d223 100644 --- a/product/src/gui/GraphTool/IconActTool/CFileOpt.h +++ b/product/src/gui/GraphTool/IconActTool/CFileOpt.h @@ -1,35 +1,35 @@ -#ifndef CFILEOPT_H -#define CFILEOPT_H - -#include -#include -#include "CIconActPublic.h" - -class QDomElement; -class CFileOpt -{ -public: - CFileOpt(); - - QString getDefaultStrategy(const QString& icon); - QMap getStrategyMap(); - QString getStrategyDesc(const QVariant &key); - - void readColorCofig(const QString &path, QMap &map); - - void readIconAction(const QString &path, QList &list); - bool saveIconAction(const QString &path, const QList &list); - - void readIconDefaultStrategy(const QString &path, QMap &map); - bool saveIconDefaultStrategy(const QString &path, const QMap &map); - -private: - void makeIconDefaultStrategy(QDomElement element, QMap &map); - void replaceIconDefaultStretegy(QDomElement &element, const QMap &map); - -private: - QMap m_iconDefaultStrategyMap; - QMap m_strategyMap; -}; - -#endif // CFILEOPT_H +#ifndef CFILEOPT_H +#define CFILEOPT_H + +#include +#include +#include "CIconActPublic.h" + +class QDomElement; +class CFileOpt +{ +public: + CFileOpt(); + + QString getDefaultStrategy(const QString& icon); + QMap getStrategyMap(); + QString getStrategyDesc(const QVariant &key); + + void readColorCofig(const QString &path, QMap &map); + + void readIconAction(const QString &path, QList &list); + bool saveIconAction(const QString &path, const QList &list); + + void readIconDefaultStrategy(const QString &path, QMap &map); + bool saveIconDefaultStrategy(const QString &path, const QMap &map); + +private: + void makeIconDefaultStrategy(QDomElement element, QMap &map); + void replaceIconDefaultStretegy(QDomElement &element, const QMap &map); + +private: + QMap m_iconDefaultStrategyMap; + QMap m_strategyMap; +}; + +#endif // CFILEOPT_H diff --git a/product/src/gui/GraphTool/IconActTool/CIconActDialog.cpp b/product/src/gui/GraphTool/IconActTool/CIconActDialog.cpp index 6edb8ab2..dbe72bec 100644 --- a/product/src/gui/GraphTool/IconActTool/CIconActDialog.cpp +++ b/product/src/gui/GraphTool/IconActTool/CIconActDialog.cpp @@ -1,189 +1,189 @@ -#include "CIconActDialog.h" -#include "ui_CIconActDialog.h" -#include "public/pub_utility_api/FileUtil.h" -#include "CTableModel.h" -#include "CTableDelegate.h" -#include "CFileOpt.h" -#include -#include -#include -#include -#include - -CIconActDialog::CIconActDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CIconActDialog), - m_pTableModel(Q_NULLPTR), - m_pFileOpt(Q_NULLPTR) -{ - ui->setupUi(this); - - initialize(); -} - -CIconActDialog::~CIconActDialog() -{ - if(m_pFileOpt) - { - delete m_pFileOpt; - } - m_pFileOpt = Q_NULLPTR; - - if(m_pTableModel) - { - delete m_pTableModel; - } - m_pTableModel = Q_NULLPTR; - - delete ui; -} - -QMap CIconActDialog::getActMap() -{ - return m_actMap; -} - -QString CIconActDialog::getActDesc(const QVariant &Act) -{ - return m_actMap.value(Act, QString()); -} - -QMap CIconActDialog::getSimMap() -{ - return m_simMap; -} - -QString CIconActDialog::getSimDesc(const QVariant &Sim) -{ - return m_simMap.value(Sim, QString()); -} - -QMap CIconActDialog::getStrategyMap() -{ - if(m_pFileOpt) - { - return m_pFileOpt->getStrategyMap(); - } - return QMap(); -} - -void CIconActDialog::onAddBtnClicked() -{ - CTableDelegate * delegate = dynamic_cast(ui->m_tableView->itemDelegateForColumn(0)); - if(!delegate) - { - return; - } - - QDir dir(delegate->getFilePath()); - QStringList fileList = QFileDialog::getOpenFileNames(this, tr("选择文件"), dir.path(), "*.ilx"); - if(fileList.isEmpty()) - { - return; - } - - QStringList existFile; - m_pTableModel->getExistIcon(existFile); - QString name; - QList appendList; - for(int nIndex(0); nIndexgetDefaultStrategy(name); - appendList.append(st_icon); - } - m_pTableModel->addRows(appendList); -} - -void CIconActDialog::onDelBtnClicked() -{ - QModelIndexList indexList = ui->m_tableView->selectionModel()->selectedRows(); - m_pTableModel->removeRows(indexList); -} - -void CIconActDialog::onConfimClicked() -{ - const QList& dataList = m_pTableModel->getDataList(); - bool ret = m_pFileOpt->saveIconAction(m_strActionFile, dataList); - if(!ret) - { - QMessageBox::information(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return; - } - - QMap map; - foreach (ST_ICONACT st_icon, dataList) { - map[st_icon.name] = st_icon.strategy.section(":",0,0); - } - m_pFileOpt->saveIconDefaultStrategy(m_strToolBoxFile, map); - if(!ret) - { - QMessageBox::information(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return; - } - accept(); -} - -void CIconActDialog::onCancelClicked() -{ - reject(); -} - -void CIconActDialog::contextMenuEvent(QContextMenuEvent *event) -{ - QMenu menu; - menu.addAction(ui->m_addBtn->toolTip(), this, &CIconActDialog::onAddBtnClicked); - menu.addAction(ui->m_delBtn->toolTip(), this, &CIconActDialog::onDelBtnClicked); - menu.exec(event->globalPos()); -} - -void CIconActDialog::initialize() -{ - m_pFileOpt = new CFileOpt(); - m_pTableModel = new CTableModel(this); - ui->m_tableView->setModel(m_pTableModel); - ui->m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->m_tableView->horizontalHeader()->setStretchLastSection(true); - ui->m_tableView->setColumnWidth(CTableModel::NAME,180); - ui->m_tableView->setColumnWidth(CTableModel::ACTION,100); - ui->m_tableView->setColumnWidth(CTableModel::PANEL,200); - ui->m_tableView->setColumnWidth(CTableModel::STRATEGY,150); - - m_actMap.insert(ACT_LEFT_CLICK, tr("左键单击")); - m_actMap.insert(ACT_LEFT_DOUCLICK, tr("左键双击")); - m_simMap.insert(SIM_FORBID, tr("禁止")); - m_simMap.insert(SIM_ALLOW, tr("允许")); - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - CTableDelegate * iconDelegate = new CTableDelegate(this, CTableDelegate::IconFile); - iconDelegate->setFilePath(QString::fromStdString(currentPath) + "/../../data/icon/"); - CTableDelegate * actnDelegate = new CTableDelegate(this, CTableDelegate::ComboBox); - actnDelegate->setComboMap(getActMap()); - CTableDelegate * paneDelegate = new CTableDelegate(this, CTableDelegate::PicFile); - paneDelegate->setFilePath(QString::fromStdString(currentPath) + "/../../data/pic/"); - CTableDelegate * straDelegate = new CTableDelegate(this, CTableDelegate::ComboBox, true); - straDelegate->setComboMap(getStrategyMap()); - CTableDelegate * simuDelegate = new CTableDelegate(this, CTableDelegate::ComboBox); - simuDelegate->setComboMap(getSimMap()); - ui->m_tableView->setItemDelegateForColumn(CTableModel::NAME, iconDelegate); - ui->m_tableView->setItemDelegateForColumn(CTableModel::ACTION, actnDelegate); - ui->m_tableView->setItemDelegateForColumn(CTableModel::PANEL, paneDelegate); - ui->m_tableView->setItemDelegateForColumn(CTableModel::STRATEGY, straDelegate); - ui->m_tableView->setItemDelegateForColumn(CTableModel::SIMULATE, simuDelegate); - - QList stList; - m_strActionFile = QString::fromStdString(currentPath) + "../../data/model/iconAction.json"; - m_strToolBoxFile = QString::fromStdString(currentPath) + "../../data/model/toolbox.xml"; - m_pFileOpt->readIconAction(m_strActionFile, stList); - m_pTableModel->updateData(stList); - - connect(ui->m_addBtn, &QPushButton::clicked, this, &CIconActDialog::onAddBtnClicked); - connect(ui->m_delBtn, &QPushButton::clicked, this, &CIconActDialog::onDelBtnClicked); - connect(ui->m_confirmBtn, &QPushButton::clicked, this, &CIconActDialog::onConfimClicked); - connect(ui->m_cancelBtn,&QPushButton::clicked, this, &CIconActDialog::onCancelClicked); -} +#include "CIconActDialog.h" +#include "ui_CIconActDialog.h" +#include "public/pub_utility_api/FileUtil.h" +#include "CTableModel.h" +#include "CTableDelegate.h" +#include "CFileOpt.h" +#include +#include +#include +#include +#include + +CIconActDialog::CIconActDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CIconActDialog), + m_pTableModel(Q_NULLPTR), + m_pFileOpt(Q_NULLPTR) +{ + ui->setupUi(this); + + initialize(); +} + +CIconActDialog::~CIconActDialog() +{ + if(m_pFileOpt) + { + delete m_pFileOpt; + } + m_pFileOpt = Q_NULLPTR; + + if(m_pTableModel) + { + delete m_pTableModel; + } + m_pTableModel = Q_NULLPTR; + + delete ui; +} + +QMap CIconActDialog::getActMap() +{ + return m_actMap; +} + +QString CIconActDialog::getActDesc(const QVariant &Act) +{ + return m_actMap.value(Act, QString()); +} + +QMap CIconActDialog::getSimMap() +{ + return m_simMap; +} + +QString CIconActDialog::getSimDesc(const QVariant &Sim) +{ + return m_simMap.value(Sim, QString()); +} + +QMap CIconActDialog::getStrategyMap() +{ + if(m_pFileOpt) + { + return m_pFileOpt->getStrategyMap(); + } + return QMap(); +} + +void CIconActDialog::onAddBtnClicked() +{ + CTableDelegate * delegate = dynamic_cast(ui->m_tableView->itemDelegateForColumn(0)); + if(!delegate) + { + return; + } + + QDir dir(delegate->getFilePath()); + QStringList fileList = QFileDialog::getOpenFileNames(this, tr("选择文件"), dir.path(), "*.ilx"); + if(fileList.isEmpty()) + { + return; + } + + QStringList existFile; + m_pTableModel->getExistIcon(existFile); + QString name; + QList appendList; + for(int nIndex(0); nIndexgetDefaultStrategy(name); + appendList.append(st_icon); + } + m_pTableModel->addRows(appendList); +} + +void CIconActDialog::onDelBtnClicked() +{ + QModelIndexList indexList = ui->m_tableView->selectionModel()->selectedRows(); + m_pTableModel->removeRows(indexList); +} + +void CIconActDialog::onConfimClicked() +{ + const QList& dataList = m_pTableModel->getDataList(); + bool ret = m_pFileOpt->saveIconAction(m_strActionFile, dataList); + if(!ret) + { + QMessageBox::information(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return; + } + + QMap map; + foreach (ST_ICONACT st_icon, dataList) { + map[st_icon.name] = st_icon.strategy.section(":",0,0); + } + m_pFileOpt->saveIconDefaultStrategy(m_strToolBoxFile, map); + if(!ret) + { + QMessageBox::information(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return; + } + accept(); +} + +void CIconActDialog::onCancelClicked() +{ + reject(); +} + +void CIconActDialog::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu; + menu.addAction(ui->m_addBtn->toolTip(), this, &CIconActDialog::onAddBtnClicked); + menu.addAction(ui->m_delBtn->toolTip(), this, &CIconActDialog::onDelBtnClicked); + menu.exec(event->globalPos()); +} + +void CIconActDialog::initialize() +{ + m_pFileOpt = new CFileOpt(); + m_pTableModel = new CTableModel(this); + ui->m_tableView->setModel(m_pTableModel); + ui->m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->m_tableView->horizontalHeader()->setStretchLastSection(true); + ui->m_tableView->setColumnWidth(CTableModel::NAME,180); + ui->m_tableView->setColumnWidth(CTableModel::ACTION,100); + ui->m_tableView->setColumnWidth(CTableModel::PANEL,200); + ui->m_tableView->setColumnWidth(CTableModel::STRATEGY,150); + + m_actMap.insert(ACT_LEFT_CLICK, tr("左键单击")); + m_actMap.insert(ACT_LEFT_DOUCLICK, tr("左键双击")); + m_simMap.insert(SIM_FORBID, tr("禁止")); + m_simMap.insert(SIM_ALLOW, tr("允许")); + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + CTableDelegate * iconDelegate = new CTableDelegate(this, CTableDelegate::IconFile); + iconDelegate->setFilePath(QString::fromStdString(currentPath) + "/../../data/icon/"); + CTableDelegate * actnDelegate = new CTableDelegate(this, CTableDelegate::ComboBox); + actnDelegate->setComboMap(getActMap()); + CTableDelegate * paneDelegate = new CTableDelegate(this, CTableDelegate::PicFile); + paneDelegate->setFilePath(QString::fromStdString(currentPath) + "/../../data/pic/"); + CTableDelegate * straDelegate = new CTableDelegate(this, CTableDelegate::ComboBox, true); + straDelegate->setComboMap(getStrategyMap()); + CTableDelegate * simuDelegate = new CTableDelegate(this, CTableDelegate::ComboBox); + simuDelegate->setComboMap(getSimMap()); + ui->m_tableView->setItemDelegateForColumn(CTableModel::NAME, iconDelegate); + ui->m_tableView->setItemDelegateForColumn(CTableModel::ACTION, actnDelegate); + ui->m_tableView->setItemDelegateForColumn(CTableModel::PANEL, paneDelegate); + ui->m_tableView->setItemDelegateForColumn(CTableModel::STRATEGY, straDelegate); + ui->m_tableView->setItemDelegateForColumn(CTableModel::SIMULATE, simuDelegate); + + QList stList; + m_strActionFile = QString::fromStdString(currentPath) + "../../data/model/iconAction.json"; + m_strToolBoxFile = QString::fromStdString(currentPath) + "../../data/model/toolbox.xml"; + m_pFileOpt->readIconAction(m_strActionFile, stList); + m_pTableModel->updateData(stList); + + connect(ui->m_addBtn, &QPushButton::clicked, this, &CIconActDialog::onAddBtnClicked); + connect(ui->m_delBtn, &QPushButton::clicked, this, &CIconActDialog::onDelBtnClicked); + connect(ui->m_confirmBtn, &QPushButton::clicked, this, &CIconActDialog::onConfimClicked); + connect(ui->m_cancelBtn,&QPushButton::clicked, this, &CIconActDialog::onCancelClicked); +} diff --git a/product/src/gui/GraphTool/IconActTool/CIconActDialog.h b/product/src/gui/GraphTool/IconActTool/CIconActDialog.h index 8f14c2d5..38d52867 100644 --- a/product/src/gui/GraphTool/IconActTool/CIconActDialog.h +++ b/product/src/gui/GraphTool/IconActTool/CIconActDialog.h @@ -1,49 +1,49 @@ -#ifndef CICONACTDIALOG_H -#define CICONACTDIALOG_H - -#include -#include - -namespace Ui { -class CIconActDialog; -} - -class CTableModel; -class CFileOpt; -class CIconActDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CIconActDialog(QWidget *parent = 0); - ~CIconActDialog(); - - QMap getActMap(); - QString getActDesc(const QVariant& Act); - QMap getSimMap(); - QString getSimDesc(const QVariant& Sim); - QMap getStrategyMap(); - -private slots: - void onAddBtnClicked(); - void onDelBtnClicked(); - void onConfimClicked(); - void onCancelClicked(); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - -private: - void initialize(); - -private: - Ui::CIconActDialog *ui; - CTableModel * m_pTableModel; - CFileOpt * m_pFileOpt; - QMap m_actMap; - QMap m_simMap; - QString m_strActionFile; - QString m_strToolBoxFile; -}; - -#endif // CICONACTDIALOG_H +#ifndef CICONACTDIALOG_H +#define CICONACTDIALOG_H + +#include +#include + +namespace Ui { +class CIconActDialog; +} + +class CTableModel; +class CFileOpt; +class CIconActDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CIconActDialog(QWidget *parent = 0); + ~CIconActDialog(); + + QMap getActMap(); + QString getActDesc(const QVariant& Act); + QMap getSimMap(); + QString getSimDesc(const QVariant& Sim); + QMap getStrategyMap(); + +private slots: + void onAddBtnClicked(); + void onDelBtnClicked(); + void onConfimClicked(); + void onCancelClicked(); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +private: + void initialize(); + +private: + Ui::CIconActDialog *ui; + CTableModel * m_pTableModel; + CFileOpt * m_pFileOpt; + QMap m_actMap; + QMap m_simMap; + QString m_strActionFile; + QString m_strToolBoxFile; +}; + +#endif // CICONACTDIALOG_H diff --git a/product/src/gui/GraphTool/IconActTool/CIconActDialog.ui b/product/src/gui/GraphTool/IconActTool/CIconActDialog.ui index 64d9e28e..e6691260 100644 --- a/product/src/gui/GraphTool/IconActTool/CIconActDialog.ui +++ b/product/src/gui/GraphTool/IconActTool/CIconActDialog.ui @@ -1,166 +1,166 @@ - - - CIconActDialog - - - - 0 - 0 - 781 - 491 - - - - 图元动作 - - - - 6 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 3 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 25 - 25 - - - - - 25 - 25 - - - - 添加 - - - + - - - - - - - - 25 - 25 - - - - - 25 - 25 - - - - 删除 - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 236 - 20 - - - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - - - Qt::Horizontal - - - - 235 - 20 - - - - - - - - - - + + + CIconActDialog + + + + 0 + 0 + 781 + 491 + + + + 图元动作 + + + + 6 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 3 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 25 + 25 + + + + + 25 + 25 + + + + 添加 + + + + + + + + + + + + 25 + 25 + + + + + 25 + 25 + + + + 删除 + + + - + + + + + + + + + + + + Qt::Horizontal + + + + 236 + 20 + + + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + + + Qt::Horizontal + + + + 235 + 20 + + + + + + + + + + diff --git a/product/src/gui/GraphTool/IconActTool/CIconActPublic.h b/product/src/gui/GraphTool/IconActTool/CIconActPublic.h index f4551e1e..277dfd99 100644 --- a/product/src/gui/GraphTool/IconActTool/CIconActPublic.h +++ b/product/src/gui/GraphTool/IconActTool/CIconActPublic.h @@ -1,34 +1,34 @@ -#ifndef CICONACTPUBLIC_H -#define CICONACTPUBLIC_H - -#include - -struct ST_ICONACT -{ - QString name; - int action; - QString panel; - QString strategy; - int simulate; - - ST_ICONACT(){ - action = 0; - simulate = 0; - } -}; - -//< 触发动作 -enum EN_ACTION -{ - ACT_LEFT_CLICK = 0, - ACT_LEFT_DOUCLICK -}; - -//< 模拟操作 -enum EN_SIMULATE -{ - SIM_FORBID = 0, - SIM_ALLOW -}; - -#endif // CICONACTPUBLIC_H +#ifndef CICONACTPUBLIC_H +#define CICONACTPUBLIC_H + +#include + +struct ST_ICONACT +{ + QString name; + int action; + QString panel; + QString strategy; + int simulate; + + ST_ICONACT(){ + action = 0; + simulate = 0; + } +}; + +//< 触发动作 +enum EN_ACTION +{ + ACT_LEFT_CLICK = 0, + ACT_LEFT_DOUCLICK +}; + +//< 模拟操作 +enum EN_SIMULATE +{ + SIM_FORBID = 0, + SIM_ALLOW +}; + +#endif // CICONACTPUBLIC_H diff --git a/product/src/gui/GraphTool/IconActTool/CLineEditWithBt.cpp b/product/src/gui/GraphTool/IconActTool/CLineEditWithBt.cpp index b7e1c268..c1f713df 100644 --- a/product/src/gui/GraphTool/IconActTool/CLineEditWithBt.cpp +++ b/product/src/gui/GraphTool/IconActTool/CLineEditWithBt.cpp @@ -1,97 +1,97 @@ -#include "CLineEditWithBt.h" -#include -#include -#include -#include -#include -#include -#include - -CLineEditWithBt::CLineEditWithBt(QWidget *parent, const QString &filePath, Option option) - :QWidget(parent),m_filePath(filePath),m_option(option) -{ - QHBoxLayout *layout = new QHBoxLayout(this); - m_edit = new QLineEdit(this); - m_edit->installEventFilter(this); - m_button = new QToolButton(this); - m_button->setText("..."); - m_button->setFixedSize(21,20); - layout->addWidget(m_edit); - layout->addWidget(m_button); - layout->setMargin(0); - layout->setSpacing(0); - this->setLayout(layout); - - connect(m_button, SIGNAL(clicked()), this, SLOT(getFilePath())); -} - -CLineEditWithBt::~CLineEditWithBt() -{ - -} - -QString CLineEditWithBt::text() -{ - return m_edit->text(); -} - -void CLineEditWithBt::setText(const QString &text) -{ - m_edit->setText(text); -} - -void CLineEditWithBt::getFilePath() -{ - QFileDialog *dialog = new QFileDialog(this, tr("选择文件"), m_filePath+text()); - dialog->setOption(QFileDialog::DontUseNativeDialog); - dialog->setAttribute(Qt::WA_DeleteOnClose); - connect(dialog, SIGNAL(fileSelected(QString)), this, SLOT(setFilePath(QString))); - dialog->show(); -} - -void CLineEditWithBt::setFilePath(const QString &name) -{ - if(name != QString()) - { - QDir dir; - switch (m_option) { - case GetFile: - { - dir.cd(m_filePath); - break; - } - case GetPath: - { - dir.cd(QCoreApplication::applicationDirPath()); - break; - } - default: - break; - } - - QString text = dir.relativeFilePath(name); - if(text.right(4) == ".exe") - { - text.remove(-4, 4); - } - setText(text); - } -} - -bool CLineEditWithBt::eventFilter(QObject *watched, QEvent *event) -{ - if(watched == m_edit) - { - if (event->type() == QEvent::FocusOut) - { - this->setFocus(); - return true; - } - else - { - return false; - } - } - - return QWidget::eventFilter(watched, event); -} +#include "CLineEditWithBt.h" +#include +#include +#include +#include +#include +#include +#include + +CLineEditWithBt::CLineEditWithBt(QWidget *parent, const QString &filePath, Option option) + :QWidget(parent),m_filePath(filePath),m_option(option) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + m_edit = new QLineEdit(this); + m_edit->installEventFilter(this); + m_button = new QToolButton(this); + m_button->setText("..."); + m_button->setFixedSize(21,20); + layout->addWidget(m_edit); + layout->addWidget(m_button); + layout->setMargin(0); + layout->setSpacing(0); + this->setLayout(layout); + + connect(m_button, SIGNAL(clicked()), this, SLOT(getFilePath())); +} + +CLineEditWithBt::~CLineEditWithBt() +{ + +} + +QString CLineEditWithBt::text() +{ + return m_edit->text(); +} + +void CLineEditWithBt::setText(const QString &text) +{ + m_edit->setText(text); +} + +void CLineEditWithBt::getFilePath() +{ + QFileDialog *dialog = new QFileDialog(this, tr("选择文件"), m_filePath+text()); + dialog->setOption(QFileDialog::DontUseNativeDialog); + dialog->setAttribute(Qt::WA_DeleteOnClose); + connect(dialog, SIGNAL(fileSelected(QString)), this, SLOT(setFilePath(QString))); + dialog->show(); +} + +void CLineEditWithBt::setFilePath(const QString &name) +{ + if(name != QString()) + { + QDir dir; + switch (m_option) { + case GetFile: + { + dir.cd(m_filePath); + break; + } + case GetPath: + { + dir.cd(QCoreApplication::applicationDirPath()); + break; + } + default: + break; + } + + QString text = dir.relativeFilePath(name); + if(text.right(4) == ".exe") + { + text.remove(-4, 4); + } + setText(text); + } +} + +bool CLineEditWithBt::eventFilter(QObject *watched, QEvent *event) +{ + if(watched == m_edit) + { + if (event->type() == QEvent::FocusOut) + { + this->setFocus(); + return true; + } + else + { + return false; + } + } + + return QWidget::eventFilter(watched, event); +} diff --git a/product/src/gui/GraphTool/IconActTool/CLineEditWithBt.h b/product/src/gui/GraphTool/IconActTool/CLineEditWithBt.h index 4a2205ae..c8d2b380 100644 --- a/product/src/gui/GraphTool/IconActTool/CLineEditWithBt.h +++ b/product/src/gui/GraphTool/IconActTool/CLineEditWithBt.h @@ -1,37 +1,37 @@ -#ifndef CLINEEDITWITHBT_H -#define CLINEEDITWITHBT_H - -#include - -class QLineEdit; -class QToolButton; -class CLineEditWithBt : public QWidget -{ - Q_OBJECT -public: - enum Option{ - GetFile = 0, - GetPath = 1 - }; - - CLineEditWithBt(QWidget *parent = 0, const QString& filePath = "", Option option = GetFile); - ~CLineEditWithBt(); - - void setText(const QString& text); - QString text(); - -protected: - bool eventFilter(QObject *watched, QEvent *event); - -private slots: - void getFilePath(); - void setFilePath(const QString& name); - -private: - QString m_filePath; - Option m_option; - QLineEdit *m_edit; - QToolButton *m_button; -}; - -#endif // CLINEEDITWITHBT_H +#ifndef CLINEEDITWITHBT_H +#define CLINEEDITWITHBT_H + +#include + +class QLineEdit; +class QToolButton; +class CLineEditWithBt : public QWidget +{ + Q_OBJECT +public: + enum Option{ + GetFile = 0, + GetPath = 1 + }; + + CLineEditWithBt(QWidget *parent = 0, const QString& filePath = "", Option option = GetFile); + ~CLineEditWithBt(); + + void setText(const QString& text); + QString text(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private slots: + void getFilePath(); + void setFilePath(const QString& name); + +private: + QString m_filePath; + Option m_option; + QLineEdit *m_edit; + QToolButton *m_button; +}; + +#endif // CLINEEDITWITHBT_H diff --git a/product/src/gui/GraphTool/IconActTool/CTableDelegate.cpp b/product/src/gui/GraphTool/IconActTool/CTableDelegate.cpp index 35e96953..97c73650 100644 --- a/product/src/gui/GraphTool/IconActTool/CTableDelegate.cpp +++ b/product/src/gui/GraphTool/IconActTool/CTableDelegate.cpp @@ -1,126 +1,126 @@ -#include "CTableDelegate.h" -#include "CLineEditWithBt.h" -#include -#include - -CTableDelegate::CTableDelegate(QObject *parent, DelegateWidget type, bool editable) - : QStyledItemDelegate(parent), - m_type(type), - m_editable(editable) -{ - -} - -CTableDelegate::~CTableDelegate() -{ - -} - -void CTableDelegate::setComboMap(const QMap &map) -{ - m_mapComboBox = map; -} - -void CTableDelegate::setFilePath(const QString &path) -{ - m_strFilePath = path; -} - -QString CTableDelegate::getFilePath() -{ - return m_strFilePath; -} - -QWidget *CTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - switch(m_type){ - case ReadOnly: - return NULL; - case LineEdit: - return new QLineEdit(parent); - case ComboBox: - { - QComboBox *box= new QComboBox(parent); - box->setEditable(m_editable); - QMap::const_iterator iter - = m_mapComboBox.constBegin(); - for(; iter != m_mapComboBox.constEnd(); iter ++) - { - box->addItem(iter.value(), iter.key()); - } - return box; - } - case PicFile: - case IconFile: - { - return new CLineEditWithBt(parent, m_strFilePath); - } - default: - return QStyledItemDelegate::createEditor(parent, option, index); - } -} - -void CTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - switch(m_type){ - case LineEdit: - { - QLineEdit *edit = static_cast(editor); - edit->setText(index.data(Qt::DisplayRole).toString()); - break; - } - case ComboBox: - { - QComboBox *comb = static_cast(editor); - comb->setCurrentIndex(comb->findText(index.data(Qt::DisplayRole).toString())); - break; - } - case PicFile: - case IconFile: - { - CLineEditWithBt *edit = static_cast(editor); - edit->setText(index.data(Qt::DisplayRole).toString()); - break; - } - default: - QStyledItemDelegate::setEditorData(editor, index); - } -} - -void CTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - switch (m_type) { - case LineEdit: - { - QLineEdit *edit = static_cast(editor); - model->setData(index, edit->text(), Qt::DisplayRole); - break; - } - case ComboBox: - { - QComboBox *comb = static_cast(editor); - if(model->data(index, Qt::DisplayRole) != comb->currentText()) - { - model->setData(index, comb->currentText(), Qt::DisplayRole); - model->setData(index, comb->currentData(), Qt::UserRole); - } - break; - } - case PicFile: - case IconFile: - { - CLineEditWithBt *edit = static_cast(editor); - model->setData(index, edit->text(), Qt::DisplayRole); - model->setData(index, edit->text(), Qt::UserRole); - break; - } - default: - QStyledItemDelegate::setModelData(editor, model, index); - } -} - -void CTableDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(index) - editor->setGeometry(option.rect); -} +#include "CTableDelegate.h" +#include "CLineEditWithBt.h" +#include +#include + +CTableDelegate::CTableDelegate(QObject *parent, DelegateWidget type, bool editable) + : QStyledItemDelegate(parent), + m_type(type), + m_editable(editable) +{ + +} + +CTableDelegate::~CTableDelegate() +{ + +} + +void CTableDelegate::setComboMap(const QMap &map) +{ + m_mapComboBox = map; +} + +void CTableDelegate::setFilePath(const QString &path) +{ + m_strFilePath = path; +} + +QString CTableDelegate::getFilePath() +{ + return m_strFilePath; +} + +QWidget *CTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + switch(m_type){ + case ReadOnly: + return NULL; + case LineEdit: + return new QLineEdit(parent); + case ComboBox: + { + QComboBox *box= new QComboBox(parent); + box->setEditable(m_editable); + QMap::const_iterator iter + = m_mapComboBox.constBegin(); + for(; iter != m_mapComboBox.constEnd(); iter ++) + { + box->addItem(iter.value(), iter.key()); + } + return box; + } + case PicFile: + case IconFile: + { + return new CLineEditWithBt(parent, m_strFilePath); + } + default: + return QStyledItemDelegate::createEditor(parent, option, index); + } +} + +void CTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + switch(m_type){ + case LineEdit: + { + QLineEdit *edit = static_cast(editor); + edit->setText(index.data(Qt::DisplayRole).toString()); + break; + } + case ComboBox: + { + QComboBox *comb = static_cast(editor); + comb->setCurrentIndex(comb->findText(index.data(Qt::DisplayRole).toString())); + break; + } + case PicFile: + case IconFile: + { + CLineEditWithBt *edit = static_cast(editor); + edit->setText(index.data(Qt::DisplayRole).toString()); + break; + } + default: + QStyledItemDelegate::setEditorData(editor, index); + } +} + +void CTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + switch (m_type) { + case LineEdit: + { + QLineEdit *edit = static_cast(editor); + model->setData(index, edit->text(), Qt::DisplayRole); + break; + } + case ComboBox: + { + QComboBox *comb = static_cast(editor); + if(model->data(index, Qt::DisplayRole) != comb->currentText()) + { + model->setData(index, comb->currentText(), Qt::DisplayRole); + model->setData(index, comb->currentData(), Qt::UserRole); + } + break; + } + case PicFile: + case IconFile: + { + CLineEditWithBt *edit = static_cast(editor); + model->setData(index, edit->text(), Qt::DisplayRole); + model->setData(index, edit->text(), Qt::UserRole); + break; + } + default: + QStyledItemDelegate::setModelData(editor, model, index); + } +} + +void CTableDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect); +} diff --git a/product/src/gui/GraphTool/IconActTool/CTableDelegate.h b/product/src/gui/GraphTool/IconActTool/CTableDelegate.h index 9629935a..e511bbcb 100644 --- a/product/src/gui/GraphTool/IconActTool/CTableDelegate.h +++ b/product/src/gui/GraphTool/IconActTool/CTableDelegate.h @@ -1,55 +1,55 @@ -#ifndef CTREEITEMDELEGATE_H -#define CTREEITEMDELEGATE_H - -#include - -class CTableDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - enum DelegateWidget{ - ReadOnly = 0, - LineEdit = 1, - ComboBox = 2, - PicFile = 3, - IconFile = 4 - }; - - CTableDelegate(QObject *parent = 0, DelegateWidget type = LineEdit, bool editable = false); - ~CTableDelegate(); - - /** - * @brief setComboMap DelegateWidget::ComboBox 有效 - * @param map - */ - void setComboMap(const QMap &map); - - /** - * @brief setFilePath DelegateWidget::PicFile/IconFile 有效 - * @param path - */ - void setFilePath(const QString &path); - - QString getFilePath(); - - QWidget *createEditor(QWidget *parent, - const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE; - - void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; - void setModelData(QWidget *editor, - QAbstractItemModel *model, - const QModelIndex &index) const Q_DECL_OVERRIDE; - - void updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE; - -private: - DelegateWidget m_type; - bool m_editable; - QMap m_mapComboBox; - QString m_strFilePath; -}; - -#endif // CTREEITEMDELEGATE_H +#ifndef CTREEITEMDELEGATE_H +#define CTREEITEMDELEGATE_H + +#include + +class CTableDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + enum DelegateWidget{ + ReadOnly = 0, + LineEdit = 1, + ComboBox = 2, + PicFile = 3, + IconFile = 4 + }; + + CTableDelegate(QObject *parent = 0, DelegateWidget type = LineEdit, bool editable = false); + ~CTableDelegate(); + + /** + * @brief setComboMap DelegateWidget::ComboBox 有效 + * @param map + */ + void setComboMap(const QMap &map); + + /** + * @brief setFilePath DelegateWidget::PicFile/IconFile 有效 + * @param path + */ + void setFilePath(const QString &path); + + QString getFilePath(); + + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; + void setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const Q_DECL_OVERRIDE; + + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &index) const Q_DECL_OVERRIDE; + +private: + DelegateWidget m_type; + bool m_editable; + QMap m_mapComboBox; + QString m_strFilePath; +}; + +#endif // CTREEITEMDELEGATE_H diff --git a/product/src/gui/GraphTool/IconActTool/CTableModel.cpp b/product/src/gui/GraphTool/IconActTool/CTableModel.cpp index a869186e..80fa13d5 100644 --- a/product/src/gui/GraphTool/IconActTool/CTableModel.cpp +++ b/product/src/gui/GraphTool/IconActTool/CTableModel.cpp @@ -1,182 +1,182 @@ -#include "CTableModel.h" -#include "CIconActDialog.h" - -CTableModel::CTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_parent = dynamic_cast(parent); - m_headerList << tr("图元名称") << tr("触发动作") << tr("控制面板") << tr("默认着色策略") << tr("模拟操作"); -} - -const QList &CTableModel::getDataList() -{ - return m_dataList; -} - -void CTableModel::updateData(QList &dataList) -{ - beginResetModel(); - m_dataList.swap(dataList); - endResetModel(); -} - -void CTableModel::addRows(const QList &dataList) -{ - if(dataList.isEmpty()) - { - return; - } - beginInsertRows(QModelIndex(), rowCount(), rowCount() + dataList.length()-1); - m_dataList.append(dataList); - endInsertRows(); -} - -void CTableModel::removeRows(const QModelIndexList &rowIndexList) -{ - beginResetModel(); - for(int nIndex(rowIndexList.length()-1); nIndex>=0; nIndex--){ - m_dataList.removeAt(rowIndexList[nIndex].row()); - } - endResetModel(); -} - -void CTableModel::getExistIcon(QStringList &nameList) -{ - foreach (ST_ICONACT st_icon, m_dataList) { - nameList.append(st_icon.name); - } -} - -QVariant CTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_headerList.at(section); - } - } - return QVariant(); -} - -int CTableModel::rowCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_dataList.length(); -} - -int CTableModel::columnCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_headerList.length(); -} - -QVariant CTableModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid()) - return QVariant(); - - if(Qt::TextAlignmentRole == role) - { - return Qt::AlignCenter; - } - \ - if(Qt::DisplayRole != role) - { - return QVariant(); - } - - switch(index.column()){ - case NAME: - { - return m_dataList.at(index.row()).name; - break; - } - case ACTION: - { - return m_parent->getActDesc( m_dataList.at(index.row()).action ); - break; - } - case PANEL: - { - return m_dataList.at(index.row()).panel; - break; - } - case STRATEGY: - { - return m_dataList.at(index.row()).strategy; - break; - } - case SIMULATE: - { - return m_parent->getSimDesc( m_dataList.at(index.row()).simulate ); - break; - } - default: - break; - } - return QVariant(); -} - -bool CTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if(!index.isValid()) - { - return false; - } - if(Qt::DisplayRole == role) - { - switch(index.column()){ - case NAME: - { - m_dataList[index.row()].name = value.toString(); - break; - } - case PANEL: - { - m_dataList[index.row()].panel = value.toString(); - break; - } - case STRATEGY: - { - m_dataList[index.row()].strategy = value.toString(); - break; - } - default: - break; - } - } - if(Qt::UserRole == role) - { - switch(index.column()){ - case ACTION: - { - m_dataList[index.row()].action = value.toInt(); - break; - } - case SIMULATE: - { - m_dataList[index.row()].simulate = value.toInt(); - break; - } - default: - break; - } - } - - return true; -} - -Qt::ItemFlags CTableModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; -} +#include "CTableModel.h" +#include "CIconActDialog.h" + +CTableModel::CTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_parent = dynamic_cast(parent); + m_headerList << tr("图元名称") << tr("触发动作") << tr("控制面板") << tr("默认着色策略") << tr("模拟操作"); +} + +const QList &CTableModel::getDataList() +{ + return m_dataList; +} + +void CTableModel::updateData(QList &dataList) +{ + beginResetModel(); + m_dataList.swap(dataList); + endResetModel(); +} + +void CTableModel::addRows(const QList &dataList) +{ + if(dataList.isEmpty()) + { + return; + } + beginInsertRows(QModelIndex(), rowCount(), rowCount() + dataList.length()-1); + m_dataList.append(dataList); + endInsertRows(); +} + +void CTableModel::removeRows(const QModelIndexList &rowIndexList) +{ + beginResetModel(); + for(int nIndex(rowIndexList.length()-1); nIndex>=0; nIndex--){ + m_dataList.removeAt(rowIndexList[nIndex].row()); + } + endResetModel(); +} + +void CTableModel::getExistIcon(QStringList &nameList) +{ + foreach (ST_ICONACT st_icon, m_dataList) { + nameList.append(st_icon.name); + } +} + +QVariant CTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_headerList.at(section); + } + } + return QVariant(); +} + +int CTableModel::rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_dataList.length(); +} + +int CTableModel::columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_headerList.length(); +} + +QVariant CTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(Qt::TextAlignmentRole == role) + { + return Qt::AlignCenter; + } + \ + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + switch(index.column()){ + case NAME: + { + return m_dataList.at(index.row()).name; + break; + } + case ACTION: + { + return m_parent->getActDesc( m_dataList.at(index.row()).action ); + break; + } + case PANEL: + { + return m_dataList.at(index.row()).panel; + break; + } + case STRATEGY: + { + return m_dataList.at(index.row()).strategy; + break; + } + case SIMULATE: + { + return m_parent->getSimDesc( m_dataList.at(index.row()).simulate ); + break; + } + default: + break; + } + return QVariant(); +} + +bool CTableModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid()) + { + return false; + } + if(Qt::DisplayRole == role) + { + switch(index.column()){ + case NAME: + { + m_dataList[index.row()].name = value.toString(); + break; + } + case PANEL: + { + m_dataList[index.row()].panel = value.toString(); + break; + } + case STRATEGY: + { + m_dataList[index.row()].strategy = value.toString(); + break; + } + default: + break; + } + } + if(Qt::UserRole == role) + { + switch(index.column()){ + case ACTION: + { + m_dataList[index.row()].action = value.toInt(); + break; + } + case SIMULATE: + { + m_dataList[index.row()].simulate = value.toInt(); + break; + } + default: + break; + } + } + + return true; +} + +Qt::ItemFlags CTableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; +} diff --git a/product/src/gui/GraphTool/IconActTool/CTableModel.h b/product/src/gui/GraphTool/IconActTool/CTableModel.h index 2d3787c7..cb2f2417 100644 --- a/product/src/gui/GraphTool/IconActTool/CTableModel.h +++ b/product/src/gui/GraphTool/IconActTool/CTableModel.h @@ -1,50 +1,50 @@ -#ifndef CTABLEMODEL_H -#define CTABLEMODEL_H - -#include -#include -#include "CIconActPublic.h" - -class CIconActDialog; -class CTableModel : public QAbstractTableModel -{ - Q_OBJECT -public: - enum ColumnField - { - NAME = 0, - ACTION, - PANEL, - STRATEGY, - SIMULATE - }; - - CTableModel(QObject *parent = Q_NULLPTR); - - const QList& getDataList(); - - void updateData(QList &dataList); - - void addRows(const QList &dataList); - - void removeRows(const QModelIndexList &rowIndexList); - - void getExistIcon(QStringList &nameList); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - -private: - QStringList m_headerList; - QList m_dataList; - CIconActDialog * m_parent; -}; - -#endif // CTABLEMODEL_H +#ifndef CTABLEMODEL_H +#define CTABLEMODEL_H + +#include +#include +#include "CIconActPublic.h" + +class CIconActDialog; +class CTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + enum ColumnField + { + NAME = 0, + ACTION, + PANEL, + STRATEGY, + SIMULATE + }; + + CTableModel(QObject *parent = Q_NULLPTR); + + const QList& getDataList(); + + void updateData(QList &dataList); + + void addRows(const QList &dataList); + + void removeRows(const QModelIndexList &rowIndexList); + + void getExistIcon(QStringList &nameList); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + +private: + QStringList m_headerList; + QList m_dataList; + CIconActDialog * m_parent; +}; + +#endif // CTABLEMODEL_H diff --git a/product/src/gui/GraphTool/IconActTool/IconActTool.pro b/product/src/gui/GraphTool/IconActTool/IconActTool.pro index b0306410..e72679c1 100644 --- a/product/src/gui/GraphTool/IconActTool/IconActTool.pro +++ b/product/src/gui/GraphTool/IconActTool/IconActTool.pro @@ -1,56 +1,56 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-08-27T08:57:32 -# -#------------------------------------------------- - -QT += core gui xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = IconActTool -TEMPLATE = app - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - main.cpp \ - CIconActDialog.cpp \ - CTableModel.cpp \ - CLineEditWithBt.cpp \ - CTableDelegate.cpp \ - CFileOpt.cpp - -HEADERS += \ - CIconActDialog.h \ - CTableModel.h \ - CIconActPublic.h \ - CLineEditWithBt.h \ - CTableDelegate.h \ - CFileOpt.h - -FORMS += \ - CIconActDialog.ui - -LIBS += \ - -lpub_utility_api \ - -llog4cplus \ - -lpub_logger_api - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2021-08-27T08:57:32 +# +#------------------------------------------------- + +QT += core gui xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = IconActTool +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + CIconActDialog.cpp \ + CTableModel.cpp \ + CLineEditWithBt.cpp \ + CTableDelegate.cpp \ + CFileOpt.cpp + +HEADERS += \ + CIconActDialog.h \ + CTableModel.h \ + CIconActPublic.h \ + CLineEditWithBt.h \ + CTableDelegate.h \ + CFileOpt.h + +FORMS += \ + CIconActDialog.ui + +LIBS += \ + -lpub_utility_api \ + -llog4cplus \ + -lpub_logger_api + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/GraphTool/IconActTool/main.cpp b/product/src/gui/GraphTool/IconActTool/main.cpp index b408e2ec..2a4c14be 100644 --- a/product/src/gui/GraphTool/IconActTool/main.cpp +++ b/product/src/gui/GraphTool/IconActTool/main.cpp @@ -1,19 +1,19 @@ - -#include -#include -#include "common/QtAppGlobalSet.h" -#include "CIconActDialog.h" - -int main(int argc, char *argv[]) -{ - kbd_common::doQtAppGlobalSet(); - - QTextCodec *codec = QTextCodec::codecForName("UTF-8"); - QTextCodec::setCodecForLocale(codec); - - QApplication a(argc, argv); - CIconActDialog w; - w.show(); - - return a.exec(); -} + +#include +#include +#include "common/QtAppGlobalSet.h" +#include "CIconActDialog.h" + +int main(int argc, char *argv[]) +{ + kbd_common::doQtAppGlobalSet(); + + QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + QTextCodec::setCodecForLocale(codec); + + QApplication a(argc, argv); + CIconActDialog w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/GraphTool/NavigationApi/CJsonOpt.cpp b/product/src/gui/GraphTool/NavigationApi/CJsonOpt.cpp index 152a37c1..460c8d51 100644 --- a/product/src/gui/GraphTool/NavigationApi/CJsonOpt.cpp +++ b/product/src/gui/GraphTool/NavigationApi/CJsonOpt.cpp @@ -1,307 +1,307 @@ -#include "gui/GraphTool/NavigationApi/CJsonOpt.h" -#include "public/pub_utility_api/FileUtil.h" -#include "public/pub_logger_api/logger.h" -#include -#include -#include -#include -#include -#include - -CJsonOpt::CJsonOpt() -{ - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - QDir dir(QString::fromStdString(currentPath)); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - dir.cd("model"); - - m_strButtonFile = dir.filePath("ButtonGroupWidget.json"); - m_strNavFile = dir.filePath("NavigationWidget.json"); - readBtnJson(m_strButtonFile); - readNavJson(m_strNavFile); - onFirst(); -} - -QString &CJsonOpt::getSeparatorPath() -{ - return m_strSeparator; -} - -QMap &CJsonOpt::getButtonMap() -{ - return m_mapButton; -} - -ST_NODE CJsonOpt::getStButton(const QString &key) -{ - return m_mapButton.value(key); -} - -QMap > > &CJsonOpt::getNavMap() -{ - return m_mapNav; -} - -bool CJsonOpt::saveJson(const QMap &btMap, - const QMap > > &navMap) -{ - bool success = false; - success = saveButtonJson(btMap); - if(!success) - { - return false; - } - success = saveNavJson(navMap); - if(!success) - { - saveButtonJson(m_mapButton); - return false; - } - return true; -} - -bool CJsonOpt::saveButtonJson(const QMap &map) -{ - QFile file(m_strButtonFile); - if(!file.exists()) - { - file.setFileName(m_strButtonFile); - } - if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) - { - return false; - } - file.resize(0); - - QJsonObject root; - root.insert("separator", m_strSeparator); - QMap::const_iterator iter = map.constBegin(); - for(; iter != map.constEnd(); iter++) - { - QJsonObject button; - button.insert("name", iter.value().name); - button.insert("used", iter.value().used); - button.insert("opt", iter.value().type); - button.insert("icon", iter.value().icon); - button.insert("web" , iter.value().web); - button.insert("data", iter.value().data); - button.insert("webData", iter.value().webData); - root.insert(iter.key(), button); - } - QJsonDocument doc; - doc.setObject(root); - if(-1 == file.write(doc.toJson())) - { - file.close(); - return false; - } - file.close(); - return true; -} - -bool CJsonOpt::saveNavJson(const QMap > > &map) -{ - QFile file(m_strNavFile); - if(!file.exists()) - { - file.setFileName(m_strNavFile); - } - if(!file.open(QIODevice::ReadWrite)) - { - return false; - } - QByteArray readJson = file.readAll(); - file.resize(0); - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return false; - } - QJsonObject root; - QJsonObject configure = readJsonResponse.object().value("configure").toObject(); - root.insert("configure", configure); - root.insert("items", getSaveItems(map, -1)); - QJsonDocument doc; - doc.setObject(root); - if(-1 == file.write(doc.toJson())) - { - file.close(); - return false; - } - file.close(); - return true; -} - -void CJsonOpt::readBtnJson(const QString &path) -{ - QFile file(path); - QByteArray readJson; - if(file.open(QIODevice::ReadOnly)) - { - readJson = file.readAll(); - file.close(); - } - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return; - } - QJsonObject root = readJsonResponse.object(); - QJsonObject::const_iterator rootIter = root.constBegin(); - for(; rootIter != root.constEnd(); rootIter++) - { - if(rootIter.key() == "separator") - { - m_strSeparator = rootIter.value().toString(); - continue; - } - QJsonObject item = rootIter.value().toObject(); - ST_NODE st_Node; - makeStButton(st_Node, item); - m_mapButton.insert(rootIter.key(), st_Node); - } -} - -void CJsonOpt::readNavJson(const QString &path) -{ - QFile file(path); - QByteArray readJson; - if(file.open(QIODevice::ReadOnly)) - { - readJson = file.readAll(); - file.close(); - } - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return; - } - QJsonObject root = readJsonResponse.object(); - if(root.contains("items")) - { - QJsonArray itemArray = root.value("items").toArray(); - int nItemNumber = 0; - for(int nIndex(0); nIndex< itemArray.size(); nIndex++) - { - ST_NODE st_Node_Top; - QJsonObject topLevelObject = itemArray[nIndex].toObject(); - makeStButton(st_Node_Top, topLevelObject); - QPair topMap; - int nTopNumber = nItemNumber; - topMap.first = nItemNumber++; - topMap.second = st_Node_Top; - - QJsonArray childArray = topLevelObject.value("items").toArray(); - for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) - { - ST_NODE st_Node_Child; - QJsonObject childLevelObject = childArray[nChildIndex].toObject(); - makeStButton(st_Node_Child, childLevelObject); - QPair childMap; - int nChildNumber = nItemNumber; - childMap.first = nItemNumber++; - childMap.second = st_Node_Child; - - QJsonArray leafArray = childLevelObject.value("items").toArray(); - for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) - { - ST_NODE st_Node_Leaf; - QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); - makeStButton(st_Node_Leaf, leafLevelObject); - QPair leafMap; - leafMap.first = nItemNumber++; - leafMap.second = st_Node_Leaf; - m_mapNav[nChildNumber].append(leafMap); - } - m_mapNav[nTopNumber].append(childMap); - } - m_mapNav[-1].append(topMap); - } - } -} - -QJsonArray CJsonOpt::getSaveItems(const QMap > > &map, int key) -{ - QJsonArray root; - QList> rootList = map.value(key); - for(int n=0; n +#include +#include +#include +#include +#include + +CJsonOpt::CJsonOpt() +{ + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + QDir dir(QString::fromStdString(currentPath)); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("model"); + + m_strButtonFile = dir.filePath("ButtonGroupWidget.json"); + m_strNavFile = dir.filePath("NavigationWidget.json"); + readBtnJson(m_strButtonFile); + readNavJson(m_strNavFile); + onFirst(); +} + +QString &CJsonOpt::getSeparatorPath() +{ + return m_strSeparator; +} + +QMap &CJsonOpt::getButtonMap() +{ + return m_mapButton; +} + +ST_NODE CJsonOpt::getStButton(const QString &key) +{ + return m_mapButton.value(key); +} + +QMap > > &CJsonOpt::getNavMap() +{ + return m_mapNav; +} + +bool CJsonOpt::saveJson(const QMap &btMap, + const QMap > > &navMap) +{ + bool success = false; + success = saveButtonJson(btMap); + if(!success) + { + return false; + } + success = saveNavJson(navMap); + if(!success) + { + saveButtonJson(m_mapButton); + return false; + } + return true; +} + +bool CJsonOpt::saveButtonJson(const QMap &map) +{ + QFile file(m_strButtonFile); + if(!file.exists()) + { + file.setFileName(m_strButtonFile); + } + if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + return false; + } + file.resize(0); + + QJsonObject root; + root.insert("separator", m_strSeparator); + QMap::const_iterator iter = map.constBegin(); + for(; iter != map.constEnd(); iter++) + { + QJsonObject button; + button.insert("name", iter.value().name); + button.insert("used", iter.value().used); + button.insert("opt", iter.value().type); + button.insert("icon", iter.value().icon); + button.insert("web" , iter.value().web); + button.insert("data", iter.value().data); + button.insert("webData", iter.value().webData); + root.insert(iter.key(), button); + } + QJsonDocument doc; + doc.setObject(root); + if(-1 == file.write(doc.toJson())) + { + file.close(); + return false; + } + file.close(); + return true; +} + +bool CJsonOpt::saveNavJson(const QMap > > &map) +{ + QFile file(m_strNavFile); + if(!file.exists()) + { + file.setFileName(m_strNavFile); + } + if(!file.open(QIODevice::ReadWrite)) + { + return false; + } + QByteArray readJson = file.readAll(); + file.resize(0); + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return false; + } + QJsonObject root; + QJsonObject configure = readJsonResponse.object().value("configure").toObject(); + root.insert("configure", configure); + root.insert("items", getSaveItems(map, -1)); + QJsonDocument doc; + doc.setObject(root); + if(-1 == file.write(doc.toJson())) + { + file.close(); + return false; + } + file.close(); + return true; +} + +void CJsonOpt::readBtnJson(const QString &path) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + QJsonObject::const_iterator rootIter = root.constBegin(); + for(; rootIter != root.constEnd(); rootIter++) + { + if(rootIter.key() == "separator") + { + m_strSeparator = rootIter.value().toString(); + continue; + } + QJsonObject item = rootIter.value().toObject(); + ST_NODE st_Node; + makeStButton(st_Node, item); + m_mapButton.insert(rootIter.key(), st_Node); + } +} + +void CJsonOpt::readNavJson(const QString &path) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + if(root.contains("items")) + { + QJsonArray itemArray = root.value("items").toArray(); + int nItemNumber = 0; + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + ST_NODE st_Node_Top; + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + makeStButton(st_Node_Top, topLevelObject); + QPair topMap; + int nTopNumber = nItemNumber; + topMap.first = nItemNumber++; + topMap.second = st_Node_Top; + + QJsonArray childArray = topLevelObject.value("items").toArray(); + for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) + { + ST_NODE st_Node_Child; + QJsonObject childLevelObject = childArray[nChildIndex].toObject(); + makeStButton(st_Node_Child, childLevelObject); + QPair childMap; + int nChildNumber = nItemNumber; + childMap.first = nItemNumber++; + childMap.second = st_Node_Child; + + QJsonArray leafArray = childLevelObject.value("items").toArray(); + for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) + { + ST_NODE st_Node_Leaf; + QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); + makeStButton(st_Node_Leaf, leafLevelObject); + QPair leafMap; + leafMap.first = nItemNumber++; + leafMap.second = st_Node_Leaf; + m_mapNav[nChildNumber].append(leafMap); + } + m_mapNav[nTopNumber].append(childMap); + } + m_mapNav[-1].append(topMap); + } + } +} + +QJsonArray CJsonOpt::getSaveItems(const QMap > > &map, int key) +{ + QJsonArray root; + QList> rootList = map.value(key); + for(int n=0; n -#include -#include -#include -#include -#include -#include - -CLineEditWithBt::CLineEditWithBt(QWidget *parent, const QString &filePath, Option option) - :QWidget(parent),m_filePath(filePath),m_option(option) -{ - QHBoxLayout *layout = new QHBoxLayout(this); - m_edit = new QLineEdit(this); - m_edit->installEventFilter(this); - m_button = new QToolButton(this); - m_button->setText("..."); - m_button->setFixedSize(21,20); - layout->addWidget(m_edit); - layout->addWidget(m_button); - layout->setMargin(0); - layout->setSpacing(0); - this->setLayout(layout); - - connect(m_button, SIGNAL(clicked()), this, SLOT(getFilePath())); -} - -CLineEditWithBt::~CLineEditWithBt() -{ - -} - -QString CLineEditWithBt::text() -{ - return m_edit->text(); -} - -void CLineEditWithBt::setText(const QString &text) -{ - m_edit->setText(text); -} - -void CLineEditWithBt::getFilePath() -{ - QFileDialog *dialog = new QFileDialog(this, tr("选择文件"), m_filePath); - dialog->setOption(QFileDialog::DontUseNativeDialog); - dialog->setAttribute(Qt::WA_DeleteOnClose); - connect(dialog, SIGNAL(fileSelected(QString)), this, SLOT(setFilePath(QString))); - dialog->show(); -} - -void CLineEditWithBt::setFilePath(const QString &name) -{ - if(name != QString()) - { - QDir dir; - switch (m_option) { - case GetFile: - { - dir.cd(m_filePath); - break; - } - case GetPath: - { - dir.cd(QCoreApplication::applicationDirPath()); - break; - } - default: - break; - } - - QString text = dir.relativeFilePath(name); - if(text.right(4) == ".exe") - { - text.remove(-4, 4); - } - setText(text); - } -} - -bool CLineEditWithBt::eventFilter(QObject *watched, QEvent *event) -{ - if(watched == m_edit) - { - if (event->type() == QEvent::FocusOut) - { - this->setFocus(); - return true; - } - else - { - return false; - } - } - - return QWidget::eventFilter(watched, event); -} +#include "CLineEditWithBt.h" +#include +#include +#include +#include +#include +#include +#include + +CLineEditWithBt::CLineEditWithBt(QWidget *parent, const QString &filePath, Option option) + :QWidget(parent),m_filePath(filePath),m_option(option) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + m_edit = new QLineEdit(this); + m_edit->installEventFilter(this); + m_button = new QToolButton(this); + m_button->setText("..."); + m_button->setFixedSize(21,20); + layout->addWidget(m_edit); + layout->addWidget(m_button); + layout->setMargin(0); + layout->setSpacing(0); + this->setLayout(layout); + + connect(m_button, SIGNAL(clicked()), this, SLOT(getFilePath())); +} + +CLineEditWithBt::~CLineEditWithBt() +{ + +} + +QString CLineEditWithBt::text() +{ + return m_edit->text(); +} + +void CLineEditWithBt::setText(const QString &text) +{ + m_edit->setText(text); +} + +void CLineEditWithBt::getFilePath() +{ + QFileDialog *dialog = new QFileDialog(this, tr("选择文件"), m_filePath); + dialog->setOption(QFileDialog::DontUseNativeDialog); + dialog->setAttribute(Qt::WA_DeleteOnClose); + connect(dialog, SIGNAL(fileSelected(QString)), this, SLOT(setFilePath(QString))); + dialog->show(); +} + +void CLineEditWithBt::setFilePath(const QString &name) +{ + if(name != QString()) + { + QDir dir; + switch (m_option) { + case GetFile: + { + dir.cd(m_filePath); + break; + } + case GetPath: + { + dir.cd(QCoreApplication::applicationDirPath()); + break; + } + default: + break; + } + + QString text = dir.relativeFilePath(name); + if(text.right(4) == ".exe") + { + text.remove(-4, 4); + } + setText(text); + } +} + +bool CLineEditWithBt::eventFilter(QObject *watched, QEvent *event) +{ + if(watched == m_edit) + { + if (event->type() == QEvent::FocusOut) + { + this->setFocus(); + return true; + } + else + { + return false; + } + } + + return QWidget::eventFilter(watched, event); +} diff --git a/product/src/gui/GraphTool/NavigationTool/CLineEditWithBt.h b/product/src/gui/GraphTool/NavigationTool/CLineEditWithBt.h index 4a2205ae..c8d2b380 100644 --- a/product/src/gui/GraphTool/NavigationTool/CLineEditWithBt.h +++ b/product/src/gui/GraphTool/NavigationTool/CLineEditWithBt.h @@ -1,37 +1,37 @@ -#ifndef CLINEEDITWITHBT_H -#define CLINEEDITWITHBT_H - -#include - -class QLineEdit; -class QToolButton; -class CLineEditWithBt : public QWidget -{ - Q_OBJECT -public: - enum Option{ - GetFile = 0, - GetPath = 1 - }; - - CLineEditWithBt(QWidget *parent = 0, const QString& filePath = "", Option option = GetFile); - ~CLineEditWithBt(); - - void setText(const QString& text); - QString text(); - -protected: - bool eventFilter(QObject *watched, QEvent *event); - -private slots: - void getFilePath(); - void setFilePath(const QString& name); - -private: - QString m_filePath; - Option m_option; - QLineEdit *m_edit; - QToolButton *m_button; -}; - -#endif // CLINEEDITWITHBT_H +#ifndef CLINEEDITWITHBT_H +#define CLINEEDITWITHBT_H + +#include + +class QLineEdit; +class QToolButton; +class CLineEditWithBt : public QWidget +{ + Q_OBJECT +public: + enum Option{ + GetFile = 0, + GetPath = 1 + }; + + CLineEditWithBt(QWidget *parent = 0, const QString& filePath = "", Option option = GetFile); + ~CLineEditWithBt(); + + void setText(const QString& text); + QString text(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private slots: + void getFilePath(); + void setFilePath(const QString& name); + +private: + QString m_filePath; + Option m_option; + QLineEdit *m_edit; + QToolButton *m_button; +}; + +#endif // CLINEEDITWITHBT_H diff --git a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.cpp b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.cpp index 54d050fb..836e4e67 100644 --- a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.cpp +++ b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.cpp @@ -1,835 +1,835 @@ -#include "CNavigationDialog.h" -#include "ui_CNavigationDialog.h" -#include "CTreeItemDelegate.h" -#include "public/pub_utility_api/FileUtil.h" -#include -#include -#include -#include -#include -#include -#include - -const int Item_Role = Qt::UserRole + 1; - -CNavigationDialog::CNavigationDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CNavigationDialog), - m_itemIndex(0) -{ - ui->setupUi(this); - - initialize(); -} - -CNavigationDialog::~CNavigationDialog() -{ - if(m_pJsonOpt) - { - delete m_pJsonOpt; - } - m_pJsonOpt = NULL; - - m_mapEnable.clear(); - m_mapType.clear(); - - delete ui; -} - -void CNavigationDialog::initialize() -{ - ui->m_treeWidget->setDragEnabled(true); - ui->m_treeWidget->setAcceptDrops(true); - ui->m_treeWidget->setDropIndicatorShown(true); - ui->m_treeWidget->setDragDropMode(QAbstractItemView::InternalMove); - ui->m_treeWidget->setDefaultDropAction(Qt::MoveAction); - ui->m_treeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); - ui->m_treeWidget->setColumnCount(8); - ui->m_treeWidget->setHeaderLabels(QStringList() << tr("属性") - << tr("是否使用") - << tr("操作") - << tr("图标") - << tr("数据") - << tr("Web发布") - << tr("Web类型") - << tr("网址")); - ui->m_treeWidget->header()->setDefaultAlignment(Qt::AlignCenter); - setColumnWidth(0, 220); - setColumnWidth(4, 220); - - m_mapEnable.clear(); - m_mapEnable.insert(Enable, tr("是")); - m_mapEnable.insert(Disable, tr("否")); - CTreeItemDelegate *boxDelegate1 = new CTreeItemDelegate(this, CTreeItemDelegate::ComboBox); - boxDelegate1->setComboMap(m_mapEnable); - - m_mapType.clear(); - m_mapType.insert(SWITCH_GRAPH, tr("切换画面")); - m_mapType.insert(SWITCH_NAV, tr("切换导航")); - m_mapType.insert(EXTERN_PRO, tr("调用程序")); - m_mapType.insert(LOAD_WEBURL, tr("加载网页")); - CTreeItemDelegate *boxDelegate2 = new CTreeItemDelegate(this, CTreeItemDelegate::ComboBox); - boxDelegate2->setComboMap(m_mapType); - - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - QDir dir(QString::fromStdString(currentPath)); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - m_strFileHomePath = dir.path() + QDir::separator(); - dir.cd("back_pixmap"); - CTreeItemDelegate *iconDelegate = new CTreeItemDelegate(this, CTreeItemDelegate::IconFile); - iconDelegate->setFilePath(dir.path()); - - CTreeItemDelegate *picDelegate = new CTreeItemDelegate(this, CTreeItemDelegate::PicFile); - picDelegate->setComboMap(makePathMap()); - - CTreeItemDelegate *editDelegate = new CTreeItemDelegate(this, CTreeItemDelegate::LineEdit); - ui->m_treeWidget->setItemDelegateForColumn(0, editDelegate); - ui->m_treeWidget->setItemDelegateForColumn(1, boxDelegate1); - ui->m_treeWidget->setItemDelegateForColumn(2, boxDelegate2); - ui->m_treeWidget->setItemDelegateForColumn(3, iconDelegate); - ui->m_treeWidget->setItemDelegateForColumn(4, picDelegate); - ui->m_treeWidget->setItemDelegateForColumn(5, boxDelegate1); - ui->m_treeWidget->setItemDelegateForColumn(6, editDelegate); - ui->m_treeWidget->setItemDelegateForColumn(7, editDelegate); - - connect(ui->m_treeWidget, &QTreeWidget::itemChanged, this, &CNavigationDialog::slotItemChanged); - connect(ui->m_add, &QPushButton::clicked, this, &CNavigationDialog::onAddClicked); - connect(ui->m_upAdd, &QPushButton::clicked, this, &CNavigationDialog::onUpAddClicked); - connect(ui->m_delete, &QPushButton::clicked, this, &CNavigationDialog::onDeleteClicked); - connect(ui->m_clear, &QPushButton::clicked, this, &CNavigationDialog::onClearClicked); - connect(ui->m_moveUp, &QPushButton::clicked, this, &CNavigationDialog::onMoveUpClicked); - connect(ui->m_moveDown, &QPushButton::clicked, this, &CNavigationDialog::onMoveDownClicked); - connect(ui->m_confirm, &QPushButton::clicked, this, &CNavigationDialog::onConfirmClicked); - connect(ui->m_cancel, &QPushButton::clicked, this, &CNavigationDialog::onCancelClicked); - connect(ui->m_export, &QPushButton::clicked, this, &CNavigationDialog::onExport); - connect(ui->m_import, &QPushButton::clicked, this, &CNavigationDialog::onImport); - - m_pJsonOpt = new CJsonOpt(); - makeTree(m_pJsonOpt->getButtonMap(), m_pJsonOpt->getNavMap()); -} - -void CNavigationDialog::setTextAlignment(QTreeWidgetItem *item) -{ - item->setTextAlignment(1, Qt::AlignCenter); - item->setTextAlignment(2, Qt::AlignCenter); - item->setTextAlignment(5, Qt::AlignCenter); -} - -void CNavigationDialog::makeTree(const QMap &btMap, - const QMap > > &navMap) -{ - QStringList showList; - QMap::const_iterator btIter = btMap.constBegin(); - for(; btIter != btMap.constEnd(); btIter++) - { - QTreeWidgetItem *item = getAddLevelItem(btIter.value()); - ui->m_treeWidget->addTopLevelItem(item); - if(btIter.value().type != SWITCH_NAV) - { - continue; - } - showList = btIter.value().data.split(","); - QList> nodeList = navMap.value(-1); - for(int nIndex=0; nIndex= showList.length()) - { - continue; - } - if(showList[nIndex] == "0") - { - continue; - } - addChildLevelItem(item, nodeList[nIndex], navMap); - } - } - //< 未关联到按钮的导航栏节点 - QList< QPair > navList = navMap.value(-1); - if(showList.length() < navList.length()) - { - ST_NODE st_node; - st_node.name = tr("自定义项目"); - st_node.type = SWITCH_NAV; - st_node.used = Disable; - st_node.web = Disable; - QTreeWidgetItem *item = getAddLevelItem(st_node); - ui->m_treeWidget->addTopLevelItem(item); - for(int nIndex=showList.length(); nIndexm_treeWidget->expandAll(); -} - -void CNavigationDialog::addChildLevelItem(QTreeWidgetItem *item, const QPair &node, - const QMap > > &navMap) -{ - QTreeWidgetItem *childItem = getAddLevelItem(node.second); - item->addChild(childItem); - - const QList > childList = navMap.value(node.first); - for(int nIndex=0; nIndexsetData(0, Qt::DisplayRole, tr("新建项目_") + QString::number(m_itemIndex++)); - } - else - { - childItem->setData(0, Qt::DisplayRole, st_node.name); - } - childItem->setData(1, Qt::DisplayRole, getEnableStr(st_node.used)); - childItem->setData(2, Qt::DisplayRole, getTypeStr(st_node.type)); - childItem->setData(3, Qt::DisplayRole, st_node.icon); - if(st_node.type != SWITCH_NAV) - { - childItem->setData(4, Qt::DisplayRole, st_node.data); - } - childItem->setData(5, Qt::DisplayRole, getEnableStr(st_node.web)); - childItem->setData(1, Qt::UserRole, st_node.used); - childItem->setData(2, Qt::UserRole, st_node.type); - childItem->setData(4, Qt::UserRole, st_node.data); - childItem->setData(5, Qt::UserRole, st_node.web); - childItem->setData(6, Qt::DisplayRole, st_node.webType); - childItem->setData(7, Qt::DisplayRole, st_node.url); - childItem->setFlags(childItem->flags() | Qt::ItemIsEditable); - setTextAlignment(childItem); - if(!st_node.icon.isEmpty()) - { - QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); - childItem->setIcon(0, QIcon(iconDir.absoluteFilePath(st_node.icon))); - } - return childItem; -} - -void CNavigationDialog::getSaveMap(QMap &btMap, - QMap > > &navMap) -{ - int topCount = ui->m_treeWidget->topLevelItemCount(); - int nBtCount = 1; - int nNavCount= 1; - QStringList dataList; - QStringList webDataList; - for(int nTopIndex=0; nTopIndexm_treeWidget->topLevelItem(nTopIndex); - QString tag = "m_button" + QString::number(nBtCount++); - ST_NODE st_node_top; - getSaveStNode(topItem, st_node_top); - - int length = dataList.length(); - for(int n=0; nchildCount(); nChildIndex++) - { - dataList.append(topItem->child(nChildIndex)->data(1, Qt::UserRole).toString()); - webDataList.append(topItem->child(nChildIndex)->data(5, Qt::UserRole).toString()); - getSaveNavMap(topItem->child(nChildIndex), -1, nNavCount, navMap); - } - - if(st_node_top.type == SWITCH_NAV) - { - st_node_top.data = dataList.join(","); - st_node_top.webData = webDataList.join(","); - btMap.insert(tag, st_node_top); - } - else - { - btMap.insert(tag, st_node_top); - if(nChildIndex > 0) - { - st_node_top.data = dataList.join(","); - st_node_top.webData = webDataList.join(","); - st_node_top.name = tr("自定义项目"); - st_node_top.type = SWITCH_NAV; - st_node_top.used = Disable; - st_node_top.web = Disable; - tag = "m_button" + QString::number(nBtCount++); - btMap.insert(tag, st_node_top); - } - } - } -} - -void CNavigationDialog::getSaveNavMap(QTreeWidgetItem *item, int key, int &count, - QMap > > &navMap) -{ - if(item == NULL) - { - return; - } - - ST_NODE st_node_nav; - getSaveStNode(item, st_node_nav); - QPair pair; - pair.first = count; - pair.second = st_node_nav; - navMap[key].append(pair); - int temp = count; - count++; - for(int nIndex=0; nIndexchildCount(); nIndex++) - { - getSaveNavMap(item->child(nIndex), temp, count, navMap); - } -} - -void CNavigationDialog::getSaveStNode(QTreeWidgetItem *item, ST_NODE &st_node) -{ - if(item == NULL) - { - return; - } - st_node.name = item->data(0, Qt::DisplayRole).toString(); - st_node.used = item->data(1, Qt::UserRole).toInt(); - st_node.type = item->data(2, Qt::UserRole).toInt(); - st_node.icon = item->data(3, Qt::DisplayRole).toString(); - st_node.web = item->data(5, Qt::UserRole).toInt(); - st_node.webType = item->data(6, Qt::DisplayRole).toString(); - st_node.url = item->data(7, Qt::DisplayRole).toString(); - if(st_node.type != SWITCH_NAV) - { - st_node.data = item->data(4, Qt::UserRole).toString(); - st_node.webData = st_node.data; - } -} - -void CNavigationDialog::addChildItemByImport(const QList &parents, QTreeWidgetItem *item) -{ - if(parents.isEmpty()) - { - ui->m_treeWidget->addTopLevelItem(item); - return; - } - - for(int nIndex(0); nIndex < ui->m_treeWidget->topLevelItemCount(); nIndex++) - { - QTreeWidgetItem *topItem = ui->m_treeWidget->topLevelItem(nIndex); - if(topItem->data(0, Item_Role).toInt() == parents.at(0)) - { - if(1 == parents.size()) - { - topItem->addChild(item); - return; - } - for(int nFirIndex(0); nFirIndex < topItem->childCount(); nFirIndex++) - { - QTreeWidgetItem *firItem = topItem->child(nFirIndex); - if(firItem->data(0, Item_Role).toInt() == parents.at(1)) - { - if(2 == parents.size()) - { - firItem->addChild(item); - return; - } - for(int nSecIndex(0); nSecIndex < firItem->childCount(); nSecIndex++) - { - QTreeWidgetItem *secItem = firItem->child(nSecIndex); - if(secItem->data(0, Item_Role).toInt() == parents.at(2)) - { - if(3 == parents.size()) - { - secItem->addChild(item); - return; - } - } - } - } - } - } - } -} - -QString CNavigationDialog::checkTreeValid() -{ - QString data; - int topCount = ui->m_treeWidget->topLevelItemCount(); - for(int nTop=0; nTopm_treeWidget->topLevelItem(nTop); - data = top->data(4, Qt::DisplayRole).toString(); - for(int nSec=0; nSecchildCount(); nSec++) - { - QTreeWidgetItem *sec = top->child(nSec); - data = sec->data(4, Qt::DisplayRole).toString(); - for(int nTh=0; nThchildCount(); nTh++) - { - QTreeWidgetItem *th = sec->child(nTh); - data = th->data(4, Qt::DisplayRole).toString(); - for(int nLeaf=0; nLeafchildCount(); nLeaf++) - { - QTreeWidgetItem *leaf = th->child(nLeaf); - data = leaf->data(4, Qt::DisplayRole).toString(); - if(leaf->childCount()) - { - return tr("最大支持四层结构: %1-%2-%3-%4") - .arg(top->text(0)) - .arg(sec->text(0)) - .arg(th->text(0)) - .arg(leaf->text(0)); - } - } - } - } - } - return ""; -} - -void CNavigationDialog::contextMenuEvent(QContextMenuEvent *event) -{ - QMenu menu; - menu.addAction(ui->m_add->toolTip(), this, &CNavigationDialog::onAddClicked); - menu.addAction(ui->m_upAdd->toolTip(), this, &CNavigationDialog::onUpAddClicked); - menu.addAction(ui->m_delete->toolTip(), this, &CNavigationDialog::onDeleteClicked); - menu.addAction(ui->m_clear->toolTip(), this, &CNavigationDialog::onClearClicked); - menu.addAction(ui->m_moveUp->toolTip(), this, &CNavigationDialog::onMoveUpClicked); - menu.addAction(ui->m_moveDown->toolTip(), this, &CNavigationDialog::onMoveDownClicked); - menu.addAction(tr("全部展开"), this, [=](){ui->m_treeWidget->expandAll();}); - menu.addAction(tr("全部收缩"), this, [=](){ui->m_treeWidget->collapseAll();}); - menu.exec(event->globalPos()); -} - -void CNavigationDialog::slotItemChanged(QTreeWidgetItem *item, int column) -{ - if(item == NULL) - { - return; - } - //< tr("图标") - if(column == 3) - { - QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); - item->setIcon(0, QIcon(iconDir.absoluteFilePath(item->text(column)))); - } -} - -void CNavigationDialog::setColumnWidth(int col, int width) -{ - if(col < ui->m_treeWidget->columnCount()) - { - ui->m_treeWidget->setColumnWidth(col, width); - } -} - -void CNavigationDialog::onAddClicked() -{ - QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); - if(item) - { - ST_NODE st_node; - QTreeWidgetItem *child = getAddLevelItem(st_node); - if(item->parent() == NULL) - { - ui->m_treeWidget->insertTopLevelItem(ui->m_treeWidget->indexOfTopLevelItem(item), child); - } - else - { - item->parent()->insertChild(item->parent()->indexOfChild(item), child); - } - } - else - { - ST_NODE st_node; - st_node.type = SWITCH_NAV; - ui->m_treeWidget->addTopLevelItem(getAddLevelItem(st_node)); - } -} - -void CNavigationDialog::onUpAddClicked() -{ - QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); - if(item) - { - if(item->parent() && item->parent()->parent() && - item->parent()->parent()->parent()) - { - return; - } - QTreeWidgetItem *child = getAddLevelItem(ST_NODE()); - item->insertChild(item->childCount(), child); - item->setExpanded(true); - } - else - { - ST_NODE st_node; - st_node.type = SWITCH_NAV; - ui->m_treeWidget->addTopLevelItem(getAddLevelItem(st_node)); - } -} - -void CNavigationDialog::onDeleteClicked() -{ - QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); - if(item) - { - if(item->parent() == NULL) - { - ui->m_treeWidget->takeTopLevelItem(ui->m_treeWidget->indexOfTopLevelItem(item)); - } - else - { - item->parent()->removeChild(item); - } - } -} - -void CNavigationDialog::onClearClicked() -{ - ui->m_treeWidget->clear(); -} - -void CNavigationDialog::onMoveUpClicked() -{ - QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); - if(item) - { - if(item->parent() == NULL) - { - int index = ui->m_treeWidget->indexOfTopLevelItem(item); - if(index <= 0) - { - return; - } - item = ui->m_treeWidget->takeTopLevelItem(index); - ui->m_treeWidget->insertTopLevelItem(index-1, item); - } - else - { - QTreeWidgetItem * parent = item->parent(); - int index = parent->indexOfChild(item); - if(index <= 0) - { - return; - } - item = parent->takeChild(index); - parent->insertChild(index-1, item); - } - ui->m_treeWidget->setCurrentItem(item); - } -} - -void CNavigationDialog::onMoveDownClicked() -{ - QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); - if(item) - { - if(item->parent() == NULL) - { - int index = ui->m_treeWidget->indexOfTopLevelItem(item); - if(index < 0 || index >= ui->m_treeWidget->topLevelItemCount()-1) - { - return; - } - item = ui->m_treeWidget->takeTopLevelItem(index); - ui->m_treeWidget->insertTopLevelItem(index+1, item); - } - else - { - QTreeWidgetItem * parent = item->parent(); - int index = parent->indexOfChild(item); - if(index < 0 || index >= parent->childCount()-1) - { - return; - } - item = parent->takeChild(index); - parent->insertChild(index+1, item); - } - ui->m_treeWidget->setCurrentItem(item); - } -} - -void CNavigationDialog::onConfirmClicked() -{ - QString valid = checkTreeValid(); - if(!valid.isEmpty()) - { - QMessageBox::information(this, tr("提示"), valid, QMessageBox::Ok); - return; - } - QMap btMap; - QMap > > navMap; - getSaveMap(btMap, navMap); - if(!m_pJsonOpt->saveJson(btMap, navMap)) - { - QMessageBox::information(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return; - } - accept(); -} - -void CNavigationDialog::onCancelClicked() -{ - reject(); -} - -void CNavigationDialog::onExport() -{ - QString valid = checkTreeValid(); - if(!valid.isEmpty()) - { - QMessageBox::information(this, tr("提示"), valid, QMessageBox::Ok); - return; - } - - QString filePath = QFileDialog::getSaveFileName(this, tr("导出"), "nav.xlsx", "*.xlsx"); - if(filePath.isEmpty()) - return; - - QXlsx::Document xlsx; - xlsx.write(hexTo26(0)+"1", tr("页面")); - xlsx.write(hexTo26(1)+"1", tr("一级")); - xlsx.write(hexTo26(2)+"1", tr("二级")); - xlsx.write(hexTo26(3)+"1", tr("三级")); - xlsx.write(hexTo26(4)+"1", tr("是否使用")); - xlsx.write(hexTo26(5)+"1", tr("操作")); - xlsx.write(hexTo26(6)+"1", tr("图标")); - xlsx.write(hexTo26(7)+"1", tr("数据")); - xlsx.write(hexTo26(8)+"1", tr("web发布")); - xlsx.write(hexTo26(9)+"1", tr("web类型")); - xlsx.write(hexTo26(10)+"1", tr("网址")); - xlsx.setColumnWidth(1, 9, 25); - - int row = 2; - int topCount = ui->m_treeWidget->topLevelItemCount(); - for(int nTopIndex=0; nTopIndexm_treeWidget->topLevelItem(nTopIndex); - ST_NODE st_node_top; - getSaveStNode(topItem, st_node_top); - xlsxWrite(xlsx, row, st_node_top.name, "", "", "", st_node_top); - for(int nFirIndex=0; nFirIndexchildCount(); nFirIndex++) - { - QTreeWidgetItem * firItem = topItem->child(nFirIndex); - ST_NODE st_node_fir; - getSaveStNode(firItem, st_node_fir); - xlsxWrite(xlsx, row, st_node_top.name, st_node_fir.name, "", "", st_node_fir); - for(int nChildIndex=0; nChildIndexchildCount(); nChildIndex++) - { - QTreeWidgetItem * childItem = firItem->child(nChildIndex); - ST_NODE st_node_child; - getSaveStNode(childItem, st_node_child); - xlsxWrite(xlsx, row, st_node_top.name, st_node_fir.name, st_node_child.name, "", st_node_child); - for(int nLeafIndex=0; nLeafIndexchildCount(); nLeafIndex++) - { - QTreeWidgetItem * leafItem = childItem->child(nLeafIndex); - ST_NODE st_node_leaf; - getSaveStNode(leafItem, st_node_leaf); - xlsxWrite(xlsx, row, st_node_top.name, st_node_fir.name, st_node_child.name, st_node_leaf.name, st_node_leaf); - } - } - } - } - - if(xlsx.saveAs(filePath)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); - } - else - { - QMessageBox::information(this,tr("提示"),tr("导出失败")); - } -} - -void CNavigationDialog::onImport() -{ - QString filePath = QFileDialog::getOpenFileName(this, tr("导入"), "", "*.xlsx"); - if(filePath.isEmpty()) - return; - - ui->m_treeWidget->clear(); - m_itemIndex = 0; - - QXlsx::Document xlsx(filePath); - QXlsx::CellRange cellRange = xlsx.currentWorksheet()->dimension(); - QMultiMap uniqMap; - for(int row=cellRange.firstRow()+1; row<=cellRange.lastRow(); row++) - { - ST_NODE st_node; - QString topName = xlsx.read(row, 1).toString(); - if(topName.isEmpty()) - { - continue; - } - QString firName = xlsx.read(row, 2).toString().trimmed(); - QString secName = xlsx.read(row, 3).toString().trimmed(); - QString trdName = xlsx.read(row, 4).toString().trimmed(); - QString enable = xlsx.read(row, 5).toString(); - QString type = xlsx.read(row, 6).toString(); - QString webEnable = xlsx.read(row, 9).toString(); - st_node.used = getEnable(enable); - st_node.type = getType(type); - st_node.icon = xlsx.read(row, 7).toString(); - st_node.data = xlsx.read(row, 8).toString(); - st_node.web = getEnable(webEnable); - st_node.webType = xlsx.read(row, 10).toString(); - st_node.url = xlsx.read(row, 11).toString(); - if(st_node.used == -1) - { - ui->m_treeWidget->clear(); - QMessageBox::information(this,tr("提示"),tr("行: %1, [%2] 不符合规范!").arg(row).arg(enable)); - return; - } - if(st_node.type == -1) - { - ui->m_treeWidget->clear(); - QMessageBox::information(this,tr("提示"),tr("行: %1, [%2] 不符合规范!").arg(row).arg(type)); - return; - } - if(st_node.web == -1) - { - ui->m_treeWidget->clear(); - QMessageBox::information(this,tr("提示"),tr("行: %1, [%2] 不符合规范!").arg(row).arg(webEnable)); - return; - } - QList parent; - QTreeWidgetItem *item; - if(firName.isEmpty()) - { - st_node.name = topName; - item = getAddLevelItem(st_node); - } - else if(secName.isEmpty()) - { - st_node.name = firName; - item = getAddLevelItem(st_node); - parent.append(findValue(uniqMap, topName)); - } - else if(trdName.isEmpty()) - { - st_node.name = secName; - item = getAddLevelItem(st_node); - parent.append(findValue(uniqMap, topName)); - parent.append(findValue(uniqMap, firName)); - } - else - { - st_node.name = trdName; - item = getAddLevelItem(st_node); - parent.append(findValue(uniqMap, topName)); - parent.append(findValue(uniqMap, firName)); - parent.append(findValue(uniqMap, secName)); - } - item->setData(0, Item_Role, m_itemIndex); - uniqMap.insert(st_node.name, m_itemIndex++); - addChildItemByImport(parent, item); - } - ui->m_treeWidget->expandAll(); -} - -int CNavigationDialog::findValue(const QMap &map, const QString &key) -{ - QMap::const_iterator iter = --map.constEnd(); - for(; iter != --map.constBegin(); iter--) - { - if(iter.key() == key) - { - return iter.value(); - } - } - return -1; -} - -QString CNavigationDialog::getEnableStr(const int &value) -{ - return m_mapEnable.value(value, tr("否")); -} - -QString CNavigationDialog::getTypeStr(const int &value) -{ - return m_mapType.value(value, tr("")); -} - -int CNavigationDialog::getEnable(const QString &value) -{ - QMap::const_iterator iter = m_mapEnable.constBegin(); - for(; iter != m_mapEnable.constEnd(); iter++) - { - if(iter.value() == value) - { - return iter.key(); - } - } - return -1; -} - -int CNavigationDialog::getType(const QString &value) -{ - QMap::const_iterator iter = m_mapType.constBegin(); - for(; iter != m_mapType.constEnd(); iter++) - { - if(iter.value() == value) - { - return iter.key(); - } - } - return -1; -} - -QMap CNavigationDialog::makePathMap() -{ - QMap fileMap; - QDir picDir(m_strFileHomePath + "pic" + QDir::separator()); - std::string exePath = kbd_public::CFileUtil::getCurModuleDir(); - fileMap.insert(SWITCH_GRAPH, picDir.path()); - fileMap.insert(LOAD_WEBURL, picDir.path()); - fileMap.insert(EXTERN_PRO, QString::fromStdString(exePath)); - return fileMap; -} - -QString CNavigationDialog::hexTo26(int number) -{ - int p = 26; //进制 - int c = 0; //取余后的数字 - QString temp; - - while (true) { - c = number % p; - number = number / p; - if(number != 0) - { - temp.prepend(QString(QChar(0x41 + c))); - } - else - { - temp.prepend(QString(QChar(0x41 + c))); - break; - } - number--; - } - - return temp; -} - -void CNavigationDialog::xlsxWrite(QXlsx::Document &xlsx, int &row, - const QString &topName, - const QString &firName, - const QString &secName, - const QString &thirdName, - const ST_NODE &st_node) -{ - xlsx.write(hexTo26(0)+QString::number(row), topName); - xlsx.write(hexTo26(1)+QString::number(row), firName); - xlsx.write(hexTo26(2)+QString::number(row), secName); - xlsx.write(hexTo26(3)+QString::number(row), thirdName); - xlsx.write(hexTo26(4)+QString::number(row), getEnableStr(st_node.used)); - xlsx.write(hexTo26(5)+QString::number(row), getTypeStr(st_node.type)); - xlsx.write(hexTo26(6)+QString::number(row), st_node.icon); - xlsx.write(hexTo26(7)+QString::number(row), st_node.data); - xlsx.write(hexTo26(8)+QString::number(row), getEnableStr(st_node.web)); - xlsx.write(hexTo26(9)+QString::number(row), st_node.webType); - xlsx.write(hexTo26(10)+QString::number(row++), st_node.url); -} +#include "CNavigationDialog.h" +#include "ui_CNavigationDialog.h" +#include "CTreeItemDelegate.h" +#include "public/pub_utility_api/FileUtil.h" +#include +#include +#include +#include +#include +#include +#include + +const int Item_Role = Qt::UserRole + 1; + +CNavigationDialog::CNavigationDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CNavigationDialog), + m_itemIndex(0) +{ + ui->setupUi(this); + + initialize(); +} + +CNavigationDialog::~CNavigationDialog() +{ + if(m_pJsonOpt) + { + delete m_pJsonOpt; + } + m_pJsonOpt = NULL; + + m_mapEnable.clear(); + m_mapType.clear(); + + delete ui; +} + +void CNavigationDialog::initialize() +{ + ui->m_treeWidget->setDragEnabled(true); + ui->m_treeWidget->setAcceptDrops(true); + ui->m_treeWidget->setDropIndicatorShown(true); + ui->m_treeWidget->setDragDropMode(QAbstractItemView::InternalMove); + ui->m_treeWidget->setDefaultDropAction(Qt::MoveAction); + ui->m_treeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); + ui->m_treeWidget->setColumnCount(8); + ui->m_treeWidget->setHeaderLabels(QStringList() << tr("属性") + << tr("是否使用") + << tr("操作") + << tr("图标") + << tr("数据") + << tr("Web发布") + << tr("Web类型") + << tr("网址")); + ui->m_treeWidget->header()->setDefaultAlignment(Qt::AlignCenter); + setColumnWidth(0, 220); + setColumnWidth(4, 220); + + m_mapEnable.clear(); + m_mapEnable.insert(Enable, tr("是")); + m_mapEnable.insert(Disable, tr("否")); + CTreeItemDelegate *boxDelegate1 = new CTreeItemDelegate(this, CTreeItemDelegate::ComboBox); + boxDelegate1->setComboMap(m_mapEnable); + + m_mapType.clear(); + m_mapType.insert(SWITCH_GRAPH, tr("切换画面")); + m_mapType.insert(SWITCH_NAV, tr("切换导航")); + m_mapType.insert(EXTERN_PRO, tr("调用程序")); + m_mapType.insert(LOAD_WEBURL, tr("加载网页")); + CTreeItemDelegate *boxDelegate2 = new CTreeItemDelegate(this, CTreeItemDelegate::ComboBox); + boxDelegate2->setComboMap(m_mapType); + + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + QDir dir(QString::fromStdString(currentPath)); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + m_strFileHomePath = dir.path() + QDir::separator(); + dir.cd("back_pixmap"); + CTreeItemDelegate *iconDelegate = new CTreeItemDelegate(this, CTreeItemDelegate::IconFile); + iconDelegate->setFilePath(dir.path()); + + CTreeItemDelegate *picDelegate = new CTreeItemDelegate(this, CTreeItemDelegate::PicFile); + picDelegate->setComboMap(makePathMap()); + + CTreeItemDelegate *editDelegate = new CTreeItemDelegate(this, CTreeItemDelegate::LineEdit); + ui->m_treeWidget->setItemDelegateForColumn(0, editDelegate); + ui->m_treeWidget->setItemDelegateForColumn(1, boxDelegate1); + ui->m_treeWidget->setItemDelegateForColumn(2, boxDelegate2); + ui->m_treeWidget->setItemDelegateForColumn(3, iconDelegate); + ui->m_treeWidget->setItemDelegateForColumn(4, picDelegate); + ui->m_treeWidget->setItemDelegateForColumn(5, boxDelegate1); + ui->m_treeWidget->setItemDelegateForColumn(6, editDelegate); + ui->m_treeWidget->setItemDelegateForColumn(7, editDelegate); + + connect(ui->m_treeWidget, &QTreeWidget::itemChanged, this, &CNavigationDialog::slotItemChanged); + connect(ui->m_add, &QPushButton::clicked, this, &CNavigationDialog::onAddClicked); + connect(ui->m_upAdd, &QPushButton::clicked, this, &CNavigationDialog::onUpAddClicked); + connect(ui->m_delete, &QPushButton::clicked, this, &CNavigationDialog::onDeleteClicked); + connect(ui->m_clear, &QPushButton::clicked, this, &CNavigationDialog::onClearClicked); + connect(ui->m_moveUp, &QPushButton::clicked, this, &CNavigationDialog::onMoveUpClicked); + connect(ui->m_moveDown, &QPushButton::clicked, this, &CNavigationDialog::onMoveDownClicked); + connect(ui->m_confirm, &QPushButton::clicked, this, &CNavigationDialog::onConfirmClicked); + connect(ui->m_cancel, &QPushButton::clicked, this, &CNavigationDialog::onCancelClicked); + connect(ui->m_export, &QPushButton::clicked, this, &CNavigationDialog::onExport); + connect(ui->m_import, &QPushButton::clicked, this, &CNavigationDialog::onImport); + + m_pJsonOpt = new CJsonOpt(); + makeTree(m_pJsonOpt->getButtonMap(), m_pJsonOpt->getNavMap()); +} + +void CNavigationDialog::setTextAlignment(QTreeWidgetItem *item) +{ + item->setTextAlignment(1, Qt::AlignCenter); + item->setTextAlignment(2, Qt::AlignCenter); + item->setTextAlignment(5, Qt::AlignCenter); +} + +void CNavigationDialog::makeTree(const QMap &btMap, + const QMap > > &navMap) +{ + QStringList showList; + QMap::const_iterator btIter = btMap.constBegin(); + for(; btIter != btMap.constEnd(); btIter++) + { + QTreeWidgetItem *item = getAddLevelItem(btIter.value()); + ui->m_treeWidget->addTopLevelItem(item); + if(btIter.value().type != SWITCH_NAV) + { + continue; + } + showList = btIter.value().data.split(","); + QList> nodeList = navMap.value(-1); + for(int nIndex=0; nIndex= showList.length()) + { + continue; + } + if(showList[nIndex] == "0") + { + continue; + } + addChildLevelItem(item, nodeList[nIndex], navMap); + } + } + //< 未关联到按钮的导航栏节点 + QList< QPair > navList = navMap.value(-1); + if(showList.length() < navList.length()) + { + ST_NODE st_node; + st_node.name = tr("自定义项目"); + st_node.type = SWITCH_NAV; + st_node.used = Disable; + st_node.web = Disable; + QTreeWidgetItem *item = getAddLevelItem(st_node); + ui->m_treeWidget->addTopLevelItem(item); + for(int nIndex=showList.length(); nIndexm_treeWidget->expandAll(); +} + +void CNavigationDialog::addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap) +{ + QTreeWidgetItem *childItem = getAddLevelItem(node.second); + item->addChild(childItem); + + const QList > childList = navMap.value(node.first); + for(int nIndex=0; nIndexsetData(0, Qt::DisplayRole, tr("新建项目_") + QString::number(m_itemIndex++)); + } + else + { + childItem->setData(0, Qt::DisplayRole, st_node.name); + } + childItem->setData(1, Qt::DisplayRole, getEnableStr(st_node.used)); + childItem->setData(2, Qt::DisplayRole, getTypeStr(st_node.type)); + childItem->setData(3, Qt::DisplayRole, st_node.icon); + if(st_node.type != SWITCH_NAV) + { + childItem->setData(4, Qt::DisplayRole, st_node.data); + } + childItem->setData(5, Qt::DisplayRole, getEnableStr(st_node.web)); + childItem->setData(1, Qt::UserRole, st_node.used); + childItem->setData(2, Qt::UserRole, st_node.type); + childItem->setData(4, Qt::UserRole, st_node.data); + childItem->setData(5, Qt::UserRole, st_node.web); + childItem->setData(6, Qt::DisplayRole, st_node.webType); + childItem->setData(7, Qt::DisplayRole, st_node.url); + childItem->setFlags(childItem->flags() | Qt::ItemIsEditable); + setTextAlignment(childItem); + if(!st_node.icon.isEmpty()) + { + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + childItem->setIcon(0, QIcon(iconDir.absoluteFilePath(st_node.icon))); + } + return childItem; +} + +void CNavigationDialog::getSaveMap(QMap &btMap, + QMap > > &navMap) +{ + int topCount = ui->m_treeWidget->topLevelItemCount(); + int nBtCount = 1; + int nNavCount= 1; + QStringList dataList; + QStringList webDataList; + for(int nTopIndex=0; nTopIndexm_treeWidget->topLevelItem(nTopIndex); + QString tag = "m_button" + QString::number(nBtCount++); + ST_NODE st_node_top; + getSaveStNode(topItem, st_node_top); + + int length = dataList.length(); + for(int n=0; nchildCount(); nChildIndex++) + { + dataList.append(topItem->child(nChildIndex)->data(1, Qt::UserRole).toString()); + webDataList.append(topItem->child(nChildIndex)->data(5, Qt::UserRole).toString()); + getSaveNavMap(topItem->child(nChildIndex), -1, nNavCount, navMap); + } + + if(st_node_top.type == SWITCH_NAV) + { + st_node_top.data = dataList.join(","); + st_node_top.webData = webDataList.join(","); + btMap.insert(tag, st_node_top); + } + else + { + btMap.insert(tag, st_node_top); + if(nChildIndex > 0) + { + st_node_top.data = dataList.join(","); + st_node_top.webData = webDataList.join(","); + st_node_top.name = tr("自定义项目"); + st_node_top.type = SWITCH_NAV; + st_node_top.used = Disable; + st_node_top.web = Disable; + tag = "m_button" + QString::number(nBtCount++); + btMap.insert(tag, st_node_top); + } + } + } +} + +void CNavigationDialog::getSaveNavMap(QTreeWidgetItem *item, int key, int &count, + QMap > > &navMap) +{ + if(item == NULL) + { + return; + } + + ST_NODE st_node_nav; + getSaveStNode(item, st_node_nav); + QPair pair; + pair.first = count; + pair.second = st_node_nav; + navMap[key].append(pair); + int temp = count; + count++; + for(int nIndex=0; nIndexchildCount(); nIndex++) + { + getSaveNavMap(item->child(nIndex), temp, count, navMap); + } +} + +void CNavigationDialog::getSaveStNode(QTreeWidgetItem *item, ST_NODE &st_node) +{ + if(item == NULL) + { + return; + } + st_node.name = item->data(0, Qt::DisplayRole).toString(); + st_node.used = item->data(1, Qt::UserRole).toInt(); + st_node.type = item->data(2, Qt::UserRole).toInt(); + st_node.icon = item->data(3, Qt::DisplayRole).toString(); + st_node.web = item->data(5, Qt::UserRole).toInt(); + st_node.webType = item->data(6, Qt::DisplayRole).toString(); + st_node.url = item->data(7, Qt::DisplayRole).toString(); + if(st_node.type != SWITCH_NAV) + { + st_node.data = item->data(4, Qt::UserRole).toString(); + st_node.webData = st_node.data; + } +} + +void CNavigationDialog::addChildItemByImport(const QList &parents, QTreeWidgetItem *item) +{ + if(parents.isEmpty()) + { + ui->m_treeWidget->addTopLevelItem(item); + return; + } + + for(int nIndex(0); nIndex < ui->m_treeWidget->topLevelItemCount(); nIndex++) + { + QTreeWidgetItem *topItem = ui->m_treeWidget->topLevelItem(nIndex); + if(topItem->data(0, Item_Role).toInt() == parents.at(0)) + { + if(1 == parents.size()) + { + topItem->addChild(item); + return; + } + for(int nFirIndex(0); nFirIndex < topItem->childCount(); nFirIndex++) + { + QTreeWidgetItem *firItem = topItem->child(nFirIndex); + if(firItem->data(0, Item_Role).toInt() == parents.at(1)) + { + if(2 == parents.size()) + { + firItem->addChild(item); + return; + } + for(int nSecIndex(0); nSecIndex < firItem->childCount(); nSecIndex++) + { + QTreeWidgetItem *secItem = firItem->child(nSecIndex); + if(secItem->data(0, Item_Role).toInt() == parents.at(2)) + { + if(3 == parents.size()) + { + secItem->addChild(item); + return; + } + } + } + } + } + } + } +} + +QString CNavigationDialog::checkTreeValid() +{ + QString data; + int topCount = ui->m_treeWidget->topLevelItemCount(); + for(int nTop=0; nTopm_treeWidget->topLevelItem(nTop); + data = top->data(4, Qt::DisplayRole).toString(); + for(int nSec=0; nSecchildCount(); nSec++) + { + QTreeWidgetItem *sec = top->child(nSec); + data = sec->data(4, Qt::DisplayRole).toString(); + for(int nTh=0; nThchildCount(); nTh++) + { + QTreeWidgetItem *th = sec->child(nTh); + data = th->data(4, Qt::DisplayRole).toString(); + for(int nLeaf=0; nLeafchildCount(); nLeaf++) + { + QTreeWidgetItem *leaf = th->child(nLeaf); + data = leaf->data(4, Qt::DisplayRole).toString(); + if(leaf->childCount()) + { + return tr("最大支持四层结构: %1-%2-%3-%4") + .arg(top->text(0)) + .arg(sec->text(0)) + .arg(th->text(0)) + .arg(leaf->text(0)); + } + } + } + } + } + return ""; +} + +void CNavigationDialog::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu; + menu.addAction(ui->m_add->toolTip(), this, &CNavigationDialog::onAddClicked); + menu.addAction(ui->m_upAdd->toolTip(), this, &CNavigationDialog::onUpAddClicked); + menu.addAction(ui->m_delete->toolTip(), this, &CNavigationDialog::onDeleteClicked); + menu.addAction(ui->m_clear->toolTip(), this, &CNavigationDialog::onClearClicked); + menu.addAction(ui->m_moveUp->toolTip(), this, &CNavigationDialog::onMoveUpClicked); + menu.addAction(ui->m_moveDown->toolTip(), this, &CNavigationDialog::onMoveDownClicked); + menu.addAction(tr("全部展开"), this, [=](){ui->m_treeWidget->expandAll();}); + menu.addAction(tr("全部收缩"), this, [=](){ui->m_treeWidget->collapseAll();}); + menu.exec(event->globalPos()); +} + +void CNavigationDialog::slotItemChanged(QTreeWidgetItem *item, int column) +{ + if(item == NULL) + { + return; + } + //< tr("图标") + if(column == 3) + { + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + item->setIcon(0, QIcon(iconDir.absoluteFilePath(item->text(column)))); + } +} + +void CNavigationDialog::setColumnWidth(int col, int width) +{ + if(col < ui->m_treeWidget->columnCount()) + { + ui->m_treeWidget->setColumnWidth(col, width); + } +} + +void CNavigationDialog::onAddClicked() +{ + QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); + if(item) + { + ST_NODE st_node; + QTreeWidgetItem *child = getAddLevelItem(st_node); + if(item->parent() == NULL) + { + ui->m_treeWidget->insertTopLevelItem(ui->m_treeWidget->indexOfTopLevelItem(item), child); + } + else + { + item->parent()->insertChild(item->parent()->indexOfChild(item), child); + } + } + else + { + ST_NODE st_node; + st_node.type = SWITCH_NAV; + ui->m_treeWidget->addTopLevelItem(getAddLevelItem(st_node)); + } +} + +void CNavigationDialog::onUpAddClicked() +{ + QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); + if(item) + { + if(item->parent() && item->parent()->parent() && + item->parent()->parent()->parent()) + { + return; + } + QTreeWidgetItem *child = getAddLevelItem(ST_NODE()); + item->insertChild(item->childCount(), child); + item->setExpanded(true); + } + else + { + ST_NODE st_node; + st_node.type = SWITCH_NAV; + ui->m_treeWidget->addTopLevelItem(getAddLevelItem(st_node)); + } +} + +void CNavigationDialog::onDeleteClicked() +{ + QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); + if(item) + { + if(item->parent() == NULL) + { + ui->m_treeWidget->takeTopLevelItem(ui->m_treeWidget->indexOfTopLevelItem(item)); + } + else + { + item->parent()->removeChild(item); + } + } +} + +void CNavigationDialog::onClearClicked() +{ + ui->m_treeWidget->clear(); +} + +void CNavigationDialog::onMoveUpClicked() +{ + QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); + if(item) + { + if(item->parent() == NULL) + { + int index = ui->m_treeWidget->indexOfTopLevelItem(item); + if(index <= 0) + { + return; + } + item = ui->m_treeWidget->takeTopLevelItem(index); + ui->m_treeWidget->insertTopLevelItem(index-1, item); + } + else + { + QTreeWidgetItem * parent = item->parent(); + int index = parent->indexOfChild(item); + if(index <= 0) + { + return; + } + item = parent->takeChild(index); + parent->insertChild(index-1, item); + } + ui->m_treeWidget->setCurrentItem(item); + } +} + +void CNavigationDialog::onMoveDownClicked() +{ + QTreeWidgetItem * item = ui->m_treeWidget->currentItem(); + if(item) + { + if(item->parent() == NULL) + { + int index = ui->m_treeWidget->indexOfTopLevelItem(item); + if(index < 0 || index >= ui->m_treeWidget->topLevelItemCount()-1) + { + return; + } + item = ui->m_treeWidget->takeTopLevelItem(index); + ui->m_treeWidget->insertTopLevelItem(index+1, item); + } + else + { + QTreeWidgetItem * parent = item->parent(); + int index = parent->indexOfChild(item); + if(index < 0 || index >= parent->childCount()-1) + { + return; + } + item = parent->takeChild(index); + parent->insertChild(index+1, item); + } + ui->m_treeWidget->setCurrentItem(item); + } +} + +void CNavigationDialog::onConfirmClicked() +{ + QString valid = checkTreeValid(); + if(!valid.isEmpty()) + { + QMessageBox::information(this, tr("提示"), valid, QMessageBox::Ok); + return; + } + QMap btMap; + QMap > > navMap; + getSaveMap(btMap, navMap); + if(!m_pJsonOpt->saveJson(btMap, navMap)) + { + QMessageBox::information(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return; + } + accept(); +} + +void CNavigationDialog::onCancelClicked() +{ + reject(); +} + +void CNavigationDialog::onExport() +{ + QString valid = checkTreeValid(); + if(!valid.isEmpty()) + { + QMessageBox::information(this, tr("提示"), valid, QMessageBox::Ok); + return; + } + + QString filePath = QFileDialog::getSaveFileName(this, tr("导出"), "nav.xlsx", "*.xlsx"); + if(filePath.isEmpty()) + return; + + QXlsx::Document xlsx; + xlsx.write(hexTo26(0)+"1", tr("页面")); + xlsx.write(hexTo26(1)+"1", tr("一级")); + xlsx.write(hexTo26(2)+"1", tr("二级")); + xlsx.write(hexTo26(3)+"1", tr("三级")); + xlsx.write(hexTo26(4)+"1", tr("是否使用")); + xlsx.write(hexTo26(5)+"1", tr("操作")); + xlsx.write(hexTo26(6)+"1", tr("图标")); + xlsx.write(hexTo26(7)+"1", tr("数据")); + xlsx.write(hexTo26(8)+"1", tr("web发布")); + xlsx.write(hexTo26(9)+"1", tr("web类型")); + xlsx.write(hexTo26(10)+"1", tr("网址")); + xlsx.setColumnWidth(1, 9, 25); + + int row = 2; + int topCount = ui->m_treeWidget->topLevelItemCount(); + for(int nTopIndex=0; nTopIndexm_treeWidget->topLevelItem(nTopIndex); + ST_NODE st_node_top; + getSaveStNode(topItem, st_node_top); + xlsxWrite(xlsx, row, st_node_top.name, "", "", "", st_node_top); + for(int nFirIndex=0; nFirIndexchildCount(); nFirIndex++) + { + QTreeWidgetItem * firItem = topItem->child(nFirIndex); + ST_NODE st_node_fir; + getSaveStNode(firItem, st_node_fir); + xlsxWrite(xlsx, row, st_node_top.name, st_node_fir.name, "", "", st_node_fir); + for(int nChildIndex=0; nChildIndexchildCount(); nChildIndex++) + { + QTreeWidgetItem * childItem = firItem->child(nChildIndex); + ST_NODE st_node_child; + getSaveStNode(childItem, st_node_child); + xlsxWrite(xlsx, row, st_node_top.name, st_node_fir.name, st_node_child.name, "", st_node_child); + for(int nLeafIndex=0; nLeafIndexchildCount(); nLeafIndex++) + { + QTreeWidgetItem * leafItem = childItem->child(nLeafIndex); + ST_NODE st_node_leaf; + getSaveStNode(leafItem, st_node_leaf); + xlsxWrite(xlsx, row, st_node_top.name, st_node_fir.name, st_node_child.name, st_node_leaf.name, st_node_leaf); + } + } + } + } + + if(xlsx.saveAs(filePath)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); + } + else + { + QMessageBox::information(this,tr("提示"),tr("导出失败")); + } +} + +void CNavigationDialog::onImport() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("导入"), "", "*.xlsx"); + if(filePath.isEmpty()) + return; + + ui->m_treeWidget->clear(); + m_itemIndex = 0; + + QXlsx::Document xlsx(filePath); + QXlsx::CellRange cellRange = xlsx.currentWorksheet()->dimension(); + QMultiMap uniqMap; + for(int row=cellRange.firstRow()+1; row<=cellRange.lastRow(); row++) + { + ST_NODE st_node; + QString topName = xlsx.read(row, 1).toString(); + if(topName.isEmpty()) + { + continue; + } + QString firName = xlsx.read(row, 2).toString().trimmed(); + QString secName = xlsx.read(row, 3).toString().trimmed(); + QString trdName = xlsx.read(row, 4).toString().trimmed(); + QString enable = xlsx.read(row, 5).toString(); + QString type = xlsx.read(row, 6).toString(); + QString webEnable = xlsx.read(row, 9).toString(); + st_node.used = getEnable(enable); + st_node.type = getType(type); + st_node.icon = xlsx.read(row, 7).toString(); + st_node.data = xlsx.read(row, 8).toString(); + st_node.web = getEnable(webEnable); + st_node.webType = xlsx.read(row, 10).toString(); + st_node.url = xlsx.read(row, 11).toString(); + if(st_node.used == -1) + { + ui->m_treeWidget->clear(); + QMessageBox::information(this,tr("提示"),tr("行: %1, [%2] 不符合规范!").arg(row).arg(enable)); + return; + } + if(st_node.type == -1) + { + ui->m_treeWidget->clear(); + QMessageBox::information(this,tr("提示"),tr("行: %1, [%2] 不符合规范!").arg(row).arg(type)); + return; + } + if(st_node.web == -1) + { + ui->m_treeWidget->clear(); + QMessageBox::information(this,tr("提示"),tr("行: %1, [%2] 不符合规范!").arg(row).arg(webEnable)); + return; + } + QList parent; + QTreeWidgetItem *item; + if(firName.isEmpty()) + { + st_node.name = topName; + item = getAddLevelItem(st_node); + } + else if(secName.isEmpty()) + { + st_node.name = firName; + item = getAddLevelItem(st_node); + parent.append(findValue(uniqMap, topName)); + } + else if(trdName.isEmpty()) + { + st_node.name = secName; + item = getAddLevelItem(st_node); + parent.append(findValue(uniqMap, topName)); + parent.append(findValue(uniqMap, firName)); + } + else + { + st_node.name = trdName; + item = getAddLevelItem(st_node); + parent.append(findValue(uniqMap, topName)); + parent.append(findValue(uniqMap, firName)); + parent.append(findValue(uniqMap, secName)); + } + item->setData(0, Item_Role, m_itemIndex); + uniqMap.insert(st_node.name, m_itemIndex++); + addChildItemByImport(parent, item); + } + ui->m_treeWidget->expandAll(); +} + +int CNavigationDialog::findValue(const QMap &map, const QString &key) +{ + QMap::const_iterator iter = --map.constEnd(); + for(; iter != --map.constBegin(); iter--) + { + if(iter.key() == key) + { + return iter.value(); + } + } + return -1; +} + +QString CNavigationDialog::getEnableStr(const int &value) +{ + return m_mapEnable.value(value, tr("否")); +} + +QString CNavigationDialog::getTypeStr(const int &value) +{ + return m_mapType.value(value, tr("")); +} + +int CNavigationDialog::getEnable(const QString &value) +{ + QMap::const_iterator iter = m_mapEnable.constBegin(); + for(; iter != m_mapEnable.constEnd(); iter++) + { + if(iter.value() == value) + { + return iter.key(); + } + } + return -1; +} + +int CNavigationDialog::getType(const QString &value) +{ + QMap::const_iterator iter = m_mapType.constBegin(); + for(; iter != m_mapType.constEnd(); iter++) + { + if(iter.value() == value) + { + return iter.key(); + } + } + return -1; +} + +QMap CNavigationDialog::makePathMap() +{ + QMap fileMap; + QDir picDir(m_strFileHomePath + "pic" + QDir::separator()); + std::string exePath = kbd_public::CFileUtil::getCurModuleDir(); + fileMap.insert(SWITCH_GRAPH, picDir.path()); + fileMap.insert(LOAD_WEBURL, picDir.path()); + fileMap.insert(EXTERN_PRO, QString::fromStdString(exePath)); + return fileMap; +} + +QString CNavigationDialog::hexTo26(int number) +{ + int p = 26; //进制 + int c = 0; //取余后的数字 + QString temp; + + while (true) { + c = number % p; + number = number / p; + if(number != 0) + { + temp.prepend(QString(QChar(0x41 + c))); + } + else + { + temp.prepend(QString(QChar(0x41 + c))); + break; + } + number--; + } + + return temp; +} + +void CNavigationDialog::xlsxWrite(QXlsx::Document &xlsx, int &row, + const QString &topName, + const QString &firName, + const QString &secName, + const QString &thirdName, + const ST_NODE &st_node) +{ + xlsx.write(hexTo26(0)+QString::number(row), topName); + xlsx.write(hexTo26(1)+QString::number(row), firName); + xlsx.write(hexTo26(2)+QString::number(row), secName); + xlsx.write(hexTo26(3)+QString::number(row), thirdName); + xlsx.write(hexTo26(4)+QString::number(row), getEnableStr(st_node.used)); + xlsx.write(hexTo26(5)+QString::number(row), getTypeStr(st_node.type)); + xlsx.write(hexTo26(6)+QString::number(row), st_node.icon); + xlsx.write(hexTo26(7)+QString::number(row), st_node.data); + xlsx.write(hexTo26(8)+QString::number(row), getEnableStr(st_node.web)); + xlsx.write(hexTo26(9)+QString::number(row), st_node.webType); + xlsx.write(hexTo26(10)+QString::number(row++), st_node.url); +} diff --git a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.h b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.h index a1be3d57..5d623445 100644 --- a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.h +++ b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.h @@ -1,83 +1,83 @@ -#ifndef CNAVIGATIONDIALOG_H -#define CNAVIGATIONDIALOG_H - -#include -#include "gui/GraphTool/NavigationApi/CJsonOpt.h" -#include "model_excel/xlsx/xlsxdocument.h" - -namespace Ui { -class CNavigationDialog; -} - -extern const int Item_Role; //< 节点数-仅导入使用 - -class QTreeWidgetItem; -class CNavigationDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CNavigationDialog(QWidget *parent = 0); - ~CNavigationDialog(); - -public slots: - void setColumnWidth(int col, int width); - -private: - void initialize(); - void setTextAlignment(QTreeWidgetItem *item); - void makeTree(const QMap &btMap, - const QMap > > &navMap); - void addChildLevelItem(QTreeWidgetItem *item, const QPair &node, - const QMap > > &navMap); - QTreeWidgetItem* getAddLevelItem(const ST_NODE& st_node); - void getSaveMap(QMap &btMap, - QMap > > &navMap); - void getSaveNavMap(QTreeWidgetItem *item, int key, int &count, - QMap > > &navMap); - void getSaveStNode(QTreeWidgetItem *item, - ST_NODE &st_node); - void addChildItemByImport(const QList &parents, QTreeWidgetItem *item); - QString checkTreeValid(); - -protected: - void contextMenuEvent(QContextMenuEvent *event) override; - -private slots: - void slotItemChanged(QTreeWidgetItem *item, int column); - void onAddClicked(); - void onUpAddClicked(); - void onDeleteClicked(); - void onClearClicked(); - void onMoveUpClicked(); - void onMoveDownClicked(); - void onConfirmClicked(); - void onCancelClicked(); - void onExport(); - void onImport(); - -private: - int findValue(const QMap &map, const QString &key); - QString getEnableStr(const int &value); - QString getTypeStr(const int &value); - int getEnable(const QString &value); - int getType(const QString &value); - QMap makePathMap(); - QString hexTo26(int number); - void xlsxWrite(QXlsx::Document &xlsx, int &row, - const QString &topName, - const QString &firName, - const QString &secName, - const QString &thirdName, - const ST_NODE &st_node); - -private: - Ui::CNavigationDialog *ui; - CJsonOpt *m_pJsonOpt; - int m_itemIndex; - QString m_strFileHomePath; - QMap m_mapEnable; - QMap m_mapType; -}; - -#endif // CNAVIGATIONDIALOG_H +#ifndef CNAVIGATIONDIALOG_H +#define CNAVIGATIONDIALOG_H + +#include +#include "gui/GraphTool/NavigationApi/CJsonOpt.h" +#include "model_excel/xlsx/xlsxdocument.h" + +namespace Ui { +class CNavigationDialog; +} + +extern const int Item_Role; //< 节点数-仅导入使用 + +class QTreeWidgetItem; +class CNavigationDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CNavigationDialog(QWidget *parent = 0); + ~CNavigationDialog(); + +public slots: + void setColumnWidth(int col, int width); + +private: + void initialize(); + void setTextAlignment(QTreeWidgetItem *item); + void makeTree(const QMap &btMap, + const QMap > > &navMap); + void addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap); + QTreeWidgetItem* getAddLevelItem(const ST_NODE& st_node); + void getSaveMap(QMap &btMap, + QMap > > &navMap); + void getSaveNavMap(QTreeWidgetItem *item, int key, int &count, + QMap > > &navMap); + void getSaveStNode(QTreeWidgetItem *item, + ST_NODE &st_node); + void addChildItemByImport(const QList &parents, QTreeWidgetItem *item); + QString checkTreeValid(); + +protected: + void contextMenuEvent(QContextMenuEvent *event) override; + +private slots: + void slotItemChanged(QTreeWidgetItem *item, int column); + void onAddClicked(); + void onUpAddClicked(); + void onDeleteClicked(); + void onClearClicked(); + void onMoveUpClicked(); + void onMoveDownClicked(); + void onConfirmClicked(); + void onCancelClicked(); + void onExport(); + void onImport(); + +private: + int findValue(const QMap &map, const QString &key); + QString getEnableStr(const int &value); + QString getTypeStr(const int &value); + int getEnable(const QString &value); + int getType(const QString &value); + QMap makePathMap(); + QString hexTo26(int number); + void xlsxWrite(QXlsx::Document &xlsx, int &row, + const QString &topName, + const QString &firName, + const QString &secName, + const QString &thirdName, + const ST_NODE &st_node); + +private: + Ui::CNavigationDialog *ui; + CJsonOpt *m_pJsonOpt; + int m_itemIndex; + QString m_strFileHomePath; + QMap m_mapEnable; + QMap m_mapType; +}; + +#endif // CNAVIGATIONDIALOG_H diff --git a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.ui b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.ui index d3ccba73..78529a16 100644 --- a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.ui +++ b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.ui @@ -1,288 +1,288 @@ - - - CNavigationDialog - - - - 0 - 0 - 1087 - 673 - - - - 导航栏配置工具 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 添加节点 - - - + - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 添加子节点 - - - - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 删除节点 - - - - - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 清空节点 - - - × - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 上移节点 - - - - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 下移节点 - - - - - - - - - - - - Qt::Horizontal - - - - 484 - 17 - - - - - - - - - - 导入 - - - - - - - 导出 - - - - - - - - - - 1 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - CTreeWidget - QTreeWidget -
CTreeWidget.h
-
-
- - -
+ + + CNavigationDialog + + + + 0 + 0 + 1087 + 673 + + + + 导航栏配置工具 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 添加节点 + + + + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 添加子节点 + + + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 删除节点 + + + - + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 清空节点 + + + × + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 上移节点 + + + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 下移节点 + + + + + + + + + + + + Qt::Horizontal + + + + 484 + 17 + + + + + + + + + + 导入 + + + + + + + 导出 + + + + + + + + + + 1 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + CTreeWidget + QTreeWidget +
CTreeWidget.h
+
+
+ + +
diff --git a/product/src/gui/GraphTool/NavigationTool/CTreeItemDelegate.cpp b/product/src/gui/GraphTool/NavigationTool/CTreeItemDelegate.cpp index 257ecd28..f5a447d4 100644 --- a/product/src/gui/GraphTool/NavigationTool/CTreeItemDelegate.cpp +++ b/product/src/gui/GraphTool/NavigationTool/CTreeItemDelegate.cpp @@ -1,145 +1,145 @@ -#include "CTreeItemDelegate.h" -#include "CLineEditWithBt.h" -#include "gui/GraphTool/NavigationApi/CJsonOpt.h" -#include -#include - -CTreeItemDelegate::CTreeItemDelegate(QObject *parent, DelegateWidget type) - : QStyledItemDelegate(parent), - m_type(type) -{ - -} - -CTreeItemDelegate::~CTreeItemDelegate() -{ - -} - -void CTreeItemDelegate::setComboMap(const QMap &map) -{ - m_mapComboBox = map; -} - -void CTreeItemDelegate::setFilePath(const QString &path) -{ - m_strFilePath = path; -} - -QWidget *CTreeItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - switch(m_type){ - case ReadOnly: - return NULL; - case LineEdit: - return new QLineEdit(parent); - case ComboBox: - { - QComboBox *box= new QComboBox(parent); - QMap::const_iterator iter - = m_mapComboBox.constBegin(); - for(; iter != m_mapComboBox.constEnd(); iter ++) - { - if(iter.value() == tr("切换导航") && index.parent() != QModelIndex()) - { - continue; - } - if(iter.value() == tr("加载网页") && index.parent() == QModelIndex()) - { - continue; - } - box->addItem(iter.value(), iter.key()); - } - return box; - } - case PicFile: - { - const QAbstractItemModel *model = index.model(); - if(model) - { - //< tr("操作") - int type = model->index(index.row(), 2, index.parent()).data(Qt::UserRole).toInt(); - QString path = m_mapComboBox.value(type, ""); - if(path.isEmpty()) - { - return new CLineEditWithBt(parent); - } - else - { - return new CLineEditWithBt(parent, path); - } - } - } - case IconFile: - { - return new CLineEditWithBt(parent, m_strFilePath); - } - default: - return QStyledItemDelegate::createEditor(parent, option, index); - } -} - -void CTreeItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - switch(m_type){ - case LineEdit: - { - QLineEdit *edit = static_cast(editor); - edit->setText(index.data(Qt::DisplayRole).toString()); - break; - } - case ComboBox: - { - QComboBox *comb = static_cast(editor); - comb->setCurrentIndex(comb->findText(index.data(Qt::DisplayRole).toString())); - break; - } - case PicFile: - case IconFile: - { - CLineEditWithBt *edit = static_cast(editor); - edit->setText(index.data(Qt::DisplayRole).toString()); - break; - } - default: - QStyledItemDelegate::setEditorData(editor, index); - } -} - -void CTreeItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - switch (m_type) { - case LineEdit: - { - QLineEdit *edit = static_cast(editor); - model->setData(index, edit->text(), Qt::DisplayRole); - break; - } - case ComboBox: - { - QComboBox *comb = static_cast(editor); - if(model->data(index, Qt::DisplayRole) != comb->currentText()) - { - model->setData(index, comb->currentText(), Qt::DisplayRole); - model->setData(index, comb->currentData().toInt(), Qt::UserRole); - } - break; - } - case PicFile: - case IconFile: - { - CLineEditWithBt *edit = static_cast(editor); - model->setData(index, edit->text(), Qt::DisplayRole); - model->setData(index, edit->text(), Qt::UserRole); - break; - } - default: - QStyledItemDelegate::setModelData(editor, model, index); - } -} - -void CTreeItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(index) - editor->setGeometry(option.rect); -} +#include "CTreeItemDelegate.h" +#include "CLineEditWithBt.h" +#include "gui/GraphTool/NavigationApi/CJsonOpt.h" +#include +#include + +CTreeItemDelegate::CTreeItemDelegate(QObject *parent, DelegateWidget type) + : QStyledItemDelegate(parent), + m_type(type) +{ + +} + +CTreeItemDelegate::~CTreeItemDelegate() +{ + +} + +void CTreeItemDelegate::setComboMap(const QMap &map) +{ + m_mapComboBox = map; +} + +void CTreeItemDelegate::setFilePath(const QString &path) +{ + m_strFilePath = path; +} + +QWidget *CTreeItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + switch(m_type){ + case ReadOnly: + return NULL; + case LineEdit: + return new QLineEdit(parent); + case ComboBox: + { + QComboBox *box= new QComboBox(parent); + QMap::const_iterator iter + = m_mapComboBox.constBegin(); + for(; iter != m_mapComboBox.constEnd(); iter ++) + { + if(iter.value() == tr("切换导航") && index.parent() != QModelIndex()) + { + continue; + } + if(iter.value() == tr("加载网页") && index.parent() == QModelIndex()) + { + continue; + } + box->addItem(iter.value(), iter.key()); + } + return box; + } + case PicFile: + { + const QAbstractItemModel *model = index.model(); + if(model) + { + //< tr("操作") + int type = model->index(index.row(), 2, index.parent()).data(Qt::UserRole).toInt(); + QString path = m_mapComboBox.value(type, ""); + if(path.isEmpty()) + { + return new CLineEditWithBt(parent); + } + else + { + return new CLineEditWithBt(parent, path); + } + } + } + case IconFile: + { + return new CLineEditWithBt(parent, m_strFilePath); + } + default: + return QStyledItemDelegate::createEditor(parent, option, index); + } +} + +void CTreeItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + switch(m_type){ + case LineEdit: + { + QLineEdit *edit = static_cast(editor); + edit->setText(index.data(Qt::DisplayRole).toString()); + break; + } + case ComboBox: + { + QComboBox *comb = static_cast(editor); + comb->setCurrentIndex(comb->findText(index.data(Qt::DisplayRole).toString())); + break; + } + case PicFile: + case IconFile: + { + CLineEditWithBt *edit = static_cast(editor); + edit->setText(index.data(Qt::DisplayRole).toString()); + break; + } + default: + QStyledItemDelegate::setEditorData(editor, index); + } +} + +void CTreeItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + switch (m_type) { + case LineEdit: + { + QLineEdit *edit = static_cast(editor); + model->setData(index, edit->text(), Qt::DisplayRole); + break; + } + case ComboBox: + { + QComboBox *comb = static_cast(editor); + if(model->data(index, Qt::DisplayRole) != comb->currentText()) + { + model->setData(index, comb->currentText(), Qt::DisplayRole); + model->setData(index, comb->currentData().toInt(), Qt::UserRole); + } + break; + } + case PicFile: + case IconFile: + { + CLineEditWithBt *edit = static_cast(editor); + model->setData(index, edit->text(), Qt::DisplayRole); + model->setData(index, edit->text(), Qt::UserRole); + break; + } + default: + QStyledItemDelegate::setModelData(editor, model, index); + } +} + +void CTreeItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect); +} diff --git a/product/src/gui/GraphTool/NavigationTool/CTreeItemDelegate.h b/product/src/gui/GraphTool/NavigationTool/CTreeItemDelegate.h index 0c51791c..8a849137 100644 --- a/product/src/gui/GraphTool/NavigationTool/CTreeItemDelegate.h +++ b/product/src/gui/GraphTool/NavigationTool/CTreeItemDelegate.h @@ -1,52 +1,52 @@ -#ifndef CTREEITEMDELEGATE_H -#define CTREEITEMDELEGATE_H - -#include - -class CTreeItemDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - enum DelegateWidget{ - ReadOnly = 0, - LineEdit = 1, - ComboBox = 2, - PicFile = 3, - IconFile = 4 - }; - - CTreeItemDelegate(QObject *parent = 0, DelegateWidget type = LineEdit); - ~CTreeItemDelegate(); - - /** - * @brief setComboMap DelegateWidget::ComboBox/PicFile/IconFile 有效 - * @param map - */ - void setComboMap(const QMap &map); - - /** - * @brief setFilePath DelegateWidget::IconFile 有效 - * @param path - */ - void setFilePath(const QString &path); - - QWidget *createEditor(QWidget *parent, - const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE; - - void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; - void setModelData(QWidget *editor, - QAbstractItemModel *model, - const QModelIndex &index) const Q_DECL_OVERRIDE; - - void updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE; - -private: - DelegateWidget m_type; - QMap m_mapComboBox; - QString m_strFilePath; -}; - -#endif // CTREEITEMDELEGATE_H +#ifndef CTREEITEMDELEGATE_H +#define CTREEITEMDELEGATE_H + +#include + +class CTreeItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + enum DelegateWidget{ + ReadOnly = 0, + LineEdit = 1, + ComboBox = 2, + PicFile = 3, + IconFile = 4 + }; + + CTreeItemDelegate(QObject *parent = 0, DelegateWidget type = LineEdit); + ~CTreeItemDelegate(); + + /** + * @brief setComboMap DelegateWidget::ComboBox/PicFile/IconFile 有效 + * @param map + */ + void setComboMap(const QMap &map); + + /** + * @brief setFilePath DelegateWidget::IconFile 有效 + * @param path + */ + void setFilePath(const QString &path); + + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; + void setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const Q_DECL_OVERRIDE; + + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &index) const Q_DECL_OVERRIDE; + +private: + DelegateWidget m_type; + QMap m_mapComboBox; + QString m_strFilePath; +}; + +#endif // CTREEITEMDELEGATE_H diff --git a/product/src/gui/GraphTool/NavigationTool/CTreeWidget.cpp b/product/src/gui/GraphTool/NavigationTool/CTreeWidget.cpp index 8b0d4bf8..69863577 100644 --- a/product/src/gui/GraphTool/NavigationTool/CTreeWidget.cpp +++ b/product/src/gui/GraphTool/NavigationTool/CTreeWidget.cpp @@ -1,18 +1,18 @@ -#include "CTreeWidget.h" -#include - -CTreeWidget::CTreeWidget(QWidget *parent) - : QTreeWidget(parent) -{ - -} - -void CTreeWidget::mousePressEvent(QMouseEvent *event) -{ - QTreeWidget::mousePressEvent(event); - QModelIndex modelIndex = indexAt(event->pos()); - if(!modelIndex.isValid()) - { - setCurrentIndex(QModelIndex()); - } -} +#include "CTreeWidget.h" +#include + +CTreeWidget::CTreeWidget(QWidget *parent) + : QTreeWidget(parent) +{ + +} + +void CTreeWidget::mousePressEvent(QMouseEvent *event) +{ + QTreeWidget::mousePressEvent(event); + QModelIndex modelIndex = indexAt(event->pos()); + if(!modelIndex.isValid()) + { + setCurrentIndex(QModelIndex()); + } +} diff --git a/product/src/gui/GraphTool/NavigationTool/CTreeWidget.h b/product/src/gui/GraphTool/NavigationTool/CTreeWidget.h index 245ace5c..eb77cf55 100644 --- a/product/src/gui/GraphTool/NavigationTool/CTreeWidget.h +++ b/product/src/gui/GraphTool/NavigationTool/CTreeWidget.h @@ -1,16 +1,16 @@ -#ifndef CTREEWIDGET_H -#define CTREEWIDGET_H - -#include - -class CTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - CTreeWidget(QWidget *parent = Q_NULLPTR); - -protected: - void mousePressEvent(QMouseEvent *event) override; -}; - -#endif // CTREEWIDGET_H +#ifndef CTREEWIDGET_H +#define CTREEWIDGET_H + +#include + +class CTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + CTreeWidget(QWidget *parent = Q_NULLPTR); + +protected: + void mousePressEvent(QMouseEvent *event) override; +}; + +#endif // CTREEWIDGET_H diff --git a/product/src/gui/GraphTool/NavigationTool/NavigationTool.pro b/product/src/gui/GraphTool/NavigationTool/NavigationTool.pro index aa3472e1..738a18b6 100644 --- a/product/src/gui/GraphTool/NavigationTool/NavigationTool.pro +++ b/product/src/gui/GraphTool/NavigationTool/NavigationTool.pro @@ -1,55 +1,55 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-04-08T17:00:16 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = NavigationTool -TEMPLATE = app - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - main.cpp \ - CNavigationDialog.cpp \ - CTreeItemDelegate.cpp \ - CLineEditWithBt.cpp \ - CTreeWidget.cpp - -HEADERS += \ - CNavigationDialog.h \ - CTreeItemDelegate.h \ - CLineEditWithBt.h \ - ../../../include/gui/GraphTool/NavigationApi/CJsonOpt.h \ - CTreeWidget.h - -FORMS += \ - CNavigationDialog.ui - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lpub_utility_api \ - -lmodel_excel \ - -lNavigationApi - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-04-08T17:00:16 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = NavigationTool +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + CNavigationDialog.cpp \ + CTreeItemDelegate.cpp \ + CLineEditWithBt.cpp \ + CTreeWidget.cpp + +HEADERS += \ + CNavigationDialog.h \ + CTreeItemDelegate.h \ + CLineEditWithBt.h \ + ../../../include/gui/GraphTool/NavigationApi/CJsonOpt.h \ + CTreeWidget.h + +FORMS += \ + CNavigationDialog.ui + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lpub_utility_api \ + -lmodel_excel \ + -lNavigationApi + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/GraphTool/NavigationTool/main.cpp b/product/src/gui/GraphTool/NavigationTool/main.cpp index ca1f591c..67009be8 100644 --- a/product/src/gui/GraphTool/NavigationTool/main.cpp +++ b/product/src/gui/GraphTool/NavigationTool/main.cpp @@ -1,15 +1,15 @@ - -#include -#include "common/QtAppGlobalSet.h" -#include "CNavigationDialog.h" - -int main(int argc, char *argv[]) -{ - kbd_common::doQtAppGlobalSet(); - - QApplication a(argc, argv); - CNavigationDialog w; - w.show(); - - return a.exec(); -} + +#include +#include "common/QtAppGlobalSet.h" +#include "CNavigationDialog.h" + +int main(int argc, char *argv[]) +{ + kbd_common::doQtAppGlobalSet(); + + QApplication a(argc, argv); + CNavigationDialog w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/GraphTool/fileSync/CConfirmDialog.cpp b/product/src/gui/GraphTool/fileSync/CConfirmDialog.cpp index 6be41487..b564d43c 100644 --- a/product/src/gui/GraphTool/fileSync/CConfirmDialog.cpp +++ b/product/src/gui/GraphTool/fileSync/CConfirmDialog.cpp @@ -1,334 +1,334 @@ -#include "CConfirmDialog.h" -#include "ui_CConfirmDialog.h" - -CConfirmDialog::CConfirmDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CConfirmDialog) -{ - ui->setupUi(this); - setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); - initTable(); -} - -CConfirmDialog::~CConfirmDialog() -{ - delete ui; -} - -void CConfirmDialog::setNameMap(const QMap &nameMap) -{ - m_nameMap = nameMap; - initTableData(); -} - -void CConfirmDialog::setRootPath(const QString &path) -{ - m_strRoot = path; -} - -void CConfirmDialog::getAllPath(QStringList& path) -{ - QMap::const_iterator it = m_nameMap.begin(); - for(;it!=m_nameMap.end();++it) - { -#ifdef WIN32 - path.append(m_strRoot + "\\" + it.key()); -#else - path.append(m_strRoot + "/" + it.key()); -#endif - } -} - -QString CConfirmDialog::getMessage() -{ - return ui->m_msgEdit->toPlainText(); -} - -QString CConfirmDialog::getStrByState(enFirstColums state) -{ - QString ret; - switch (state) { - case FIRST_NO_CHANGED: - { - ret = tr("无修改"); - break; - } - case FIRST_ADD: - { - ret = tr("添加"); - break; - } - case FIRST_CONFLICTED: - { - ret = tr("冲突"); - break; - } - case FIRST_DELETED: - { - ret = tr("删除"); - break; - } - case FIRST_IGNORED: - { - ret = tr("忽略"); - break; - } - case FIRST_MODIFIED: - { - ret = tr("修改"); - break; - } - case FIRST_REPLACED: - { - ret = tr("替换"); - break; - } - case FIRST_EXTERNALS_DEFINE: - { - ret = tr("未纳入版本控制的目录,被外部引用的目录所创建"); - break; - } - case FIRST_NOT_VERSION_CONTROL: - { - ret = tr("未纳入版本控制"); - break; - } - case FIRST_MISS: - { - ret = tr("遗失"); - break; - } - case FIRST_OBSTRUCTED: - { - ret = tr("重名"); - break; - } - case FIRST_ILLEGAL: - { - ret = tr("自定义非法状态"); - break; - } - default: - break; - } - return ret; -} - -QString CConfirmDialog::getStrBySecond(enSecondColumn state) -{ - QString ret; - switch (state) { - case SECOND_NO_CHANGED: - { - ret = tr("无修改"); - break; - } - case SECOND_CONFLICTED: - { - ret = tr("冲突"); - break; - } - case SECOND_MODIFIED: - { - ret = tr("改变"); - break; - } - case SECOND_ILLEGAL: - { - ret = tr("自定义非法状态"); - break; - } - default: - break; - } - return ret; -} - -QString CConfirmDialog::getStrByThird(enThirdColumns state) -{ - QString ret; - switch (state) { - case THIRD_NOT_LOCKED: - { - ret = tr("未锁定"); - break; - } - case THIRD_LOCKED: - { - ret = tr("锁定"); - break; - } - case THIRD_ILLEGAL: - { - ret = tr("自定义非法状态"); - break; - } - default: - break; - } - return ret; -} - -QString CConfirmDialog::getStrByFourth(enFourthColumn state) -{ - QString ret; - switch (state) { - case FOURTH_NOT_HISTORY: - { - ret = tr("没有历史"); - break; - } - case FOURTH_CONTAIN_HISTORY: - { - ret = tr("包含历史"); - break; - } - case FOURTH_ILLEGAL: - { - ret = tr("自定义非法状态"); - break; - } - default: - break; - } - return ret; -} - -QString CConfirmDialog::getStrByFifth(enFifthColumn state) -{ - QString ret; - switch (state) { - case FIFTH_NORMAL: - { - ret = tr("正常"); - break; - } - case FIFTH_SWICTCH: - { - ret = tr("以切换"); - break; - } - case FIFTH_EXTERNAL_REFER_CREATE: - { - ret = tr("被外部引用创建的文件"); - break; - } - case FIFTH_ILLEGAL: - { - ret = tr("自定义非法状态"); - break; - } - default: - break; - } - return ret; -} - -QString CConfirmDialog::getStrBySixth(enSixthColumn state) -{ - QString ret; - switch (state) { - case SIXTH_NOT_LOCKED: - { - ret = tr("没有被锁定标记"); - break; - } - case SIXTH_LOCKED: - { - ret = tr("存在锁定标记"); - break; - } - case SIXTH_ILLEGAL: - { - ret = tr("自定义非法状态"); - break; - } - default: - break; - } - return ret; -} - -QString CConfirmDialog::getStrBySeventh(enSeventhColumn state) -{ - QString ret; - switch (state) { - case SEVENTH_NORMAL: - { - ret = tr("正常"); - break; - } - case SEVENTH_TREE_CONFFLICT: - { - ret = tr("树冲突"); - break; - } - case SEVENTH_ILLEGAL: - { - ret = tr("自定义非法状态"); - break; - } - default: - break; - } - return ret; -} - -void CConfirmDialog::initTable() -{ - ui->m_table->setColumnCount(2); - ui->m_table->setHorizontalHeaderLabels(QStringList() << tr("名称") << tr("状态")); - ui->m_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); - ui->m_table->horizontalHeader()->setStretchLastSection(true); - ui->m_table->verticalHeader()->hide(); - ui->m_table->setColumnWidth(0,200); - ui->m_table->setEditTriggers(0); - ui->m_table->setSelectionBehavior(QAbstractItemView::SelectRows); -} - -void CConfirmDialog::initTableData() -{ - int rowCount = m_nameMap.size(); - ui->m_table->setRowCount(rowCount); - QMap::const_iterator it = m_nameMap.begin(); - for(int row=0;it!=m_nameMap.end();++it,++row) - { - QTableWidgetItem *name = new QTableWidgetItem(it.key()); - QTableWidgetItem *state = new QTableWidgetItem(it.value()); - ui->m_table->setItem(row, 0, name); - ui->m_table->setItem(row, 1, state); - ui->m_table->item(row,0)->setData(5,it.value()); - ui->m_table->item(row,0)->setCheckState(Qt::Checked); - } - connect(ui->m_table,SIGNAL(cellChanged(int,int)),this,SLOT(slot_cellChange(int,int))); -} - -void CConfirmDialog::slot_cellChange(int row, int column) -{ - if(ui->m_table->item(row,column)->checkState() == Qt::Checked) - { - QMap::const_iterator it = m_nameMap.find(ui->m_table->item(row,0)->text()); - if(it == m_nameMap.end()) - { - m_nameMap.insert(ui->m_table->item(row,0)->text(), ui->m_table->item(row,1)->text()); - } - } - else if(ui->m_table->item(row,column)->checkState() == Qt::Unchecked) - { - QMap::const_iterator it = m_nameMap.find(ui->m_table->item(row,0)->text()); - if(it != m_nameMap.end()) - { - m_nameMap.remove(ui->m_table->item(row,0)->text()); - } - } -} - -void CConfirmDialog::on_m_confirmBtn_clicked() -{ - accept(); -} - -void CConfirmDialog::on_m_cancelBtn_clicked() -{ - reject(); -} +#include "CConfirmDialog.h" +#include "ui_CConfirmDialog.h" + +CConfirmDialog::CConfirmDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CConfirmDialog) +{ + ui->setupUi(this); + setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); + initTable(); +} + +CConfirmDialog::~CConfirmDialog() +{ + delete ui; +} + +void CConfirmDialog::setNameMap(const QMap &nameMap) +{ + m_nameMap = nameMap; + initTableData(); +} + +void CConfirmDialog::setRootPath(const QString &path) +{ + m_strRoot = path; +} + +void CConfirmDialog::getAllPath(QStringList& path) +{ + QMap::const_iterator it = m_nameMap.begin(); + for(;it!=m_nameMap.end();++it) + { +#ifdef WIN32 + path.append(m_strRoot + "\\" + it.key()); +#else + path.append(m_strRoot + "/" + it.key()); +#endif + } +} + +QString CConfirmDialog::getMessage() +{ + return ui->m_msgEdit->toPlainText(); +} + +QString CConfirmDialog::getStrByState(enFirstColums state) +{ + QString ret; + switch (state) { + case FIRST_NO_CHANGED: + { + ret = tr("无修改"); + break; + } + case FIRST_ADD: + { + ret = tr("添加"); + break; + } + case FIRST_CONFLICTED: + { + ret = tr("冲突"); + break; + } + case FIRST_DELETED: + { + ret = tr("删除"); + break; + } + case FIRST_IGNORED: + { + ret = tr("忽略"); + break; + } + case FIRST_MODIFIED: + { + ret = tr("修改"); + break; + } + case FIRST_REPLACED: + { + ret = tr("替换"); + break; + } + case FIRST_EXTERNALS_DEFINE: + { + ret = tr("未纳入版本控制的目录,被外部引用的目录所创建"); + break; + } + case FIRST_NOT_VERSION_CONTROL: + { + ret = tr("未纳入版本控制"); + break; + } + case FIRST_MISS: + { + ret = tr("遗失"); + break; + } + case FIRST_OBSTRUCTED: + { + ret = tr("重名"); + break; + } + case FIRST_ILLEGAL: + { + ret = tr("自定义非法状态"); + break; + } + default: + break; + } + return ret; +} + +QString CConfirmDialog::getStrBySecond(enSecondColumn state) +{ + QString ret; + switch (state) { + case SECOND_NO_CHANGED: + { + ret = tr("无修改"); + break; + } + case SECOND_CONFLICTED: + { + ret = tr("冲突"); + break; + } + case SECOND_MODIFIED: + { + ret = tr("改变"); + break; + } + case SECOND_ILLEGAL: + { + ret = tr("自定义非法状态"); + break; + } + default: + break; + } + return ret; +} + +QString CConfirmDialog::getStrByThird(enThirdColumns state) +{ + QString ret; + switch (state) { + case THIRD_NOT_LOCKED: + { + ret = tr("未锁定"); + break; + } + case THIRD_LOCKED: + { + ret = tr("锁定"); + break; + } + case THIRD_ILLEGAL: + { + ret = tr("自定义非法状态"); + break; + } + default: + break; + } + return ret; +} + +QString CConfirmDialog::getStrByFourth(enFourthColumn state) +{ + QString ret; + switch (state) { + case FOURTH_NOT_HISTORY: + { + ret = tr("没有历史"); + break; + } + case FOURTH_CONTAIN_HISTORY: + { + ret = tr("包含历史"); + break; + } + case FOURTH_ILLEGAL: + { + ret = tr("自定义非法状态"); + break; + } + default: + break; + } + return ret; +} + +QString CConfirmDialog::getStrByFifth(enFifthColumn state) +{ + QString ret; + switch (state) { + case FIFTH_NORMAL: + { + ret = tr("正常"); + break; + } + case FIFTH_SWICTCH: + { + ret = tr("以切换"); + break; + } + case FIFTH_EXTERNAL_REFER_CREATE: + { + ret = tr("被外部引用创建的文件"); + break; + } + case FIFTH_ILLEGAL: + { + ret = tr("自定义非法状态"); + break; + } + default: + break; + } + return ret; +} + +QString CConfirmDialog::getStrBySixth(enSixthColumn state) +{ + QString ret; + switch (state) { + case SIXTH_NOT_LOCKED: + { + ret = tr("没有被锁定标记"); + break; + } + case SIXTH_LOCKED: + { + ret = tr("存在锁定标记"); + break; + } + case SIXTH_ILLEGAL: + { + ret = tr("自定义非法状态"); + break; + } + default: + break; + } + return ret; +} + +QString CConfirmDialog::getStrBySeventh(enSeventhColumn state) +{ + QString ret; + switch (state) { + case SEVENTH_NORMAL: + { + ret = tr("正常"); + break; + } + case SEVENTH_TREE_CONFFLICT: + { + ret = tr("树冲突"); + break; + } + case SEVENTH_ILLEGAL: + { + ret = tr("自定义非法状态"); + break; + } + default: + break; + } + return ret; +} + +void CConfirmDialog::initTable() +{ + ui->m_table->setColumnCount(2); + ui->m_table->setHorizontalHeaderLabels(QStringList() << tr("名称") << tr("状态")); + ui->m_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); + ui->m_table->horizontalHeader()->setStretchLastSection(true); + ui->m_table->verticalHeader()->hide(); + ui->m_table->setColumnWidth(0,200); + ui->m_table->setEditTriggers(0); + ui->m_table->setSelectionBehavior(QAbstractItemView::SelectRows); +} + +void CConfirmDialog::initTableData() +{ + int rowCount = m_nameMap.size(); + ui->m_table->setRowCount(rowCount); + QMap::const_iterator it = m_nameMap.begin(); + for(int row=0;it!=m_nameMap.end();++it,++row) + { + QTableWidgetItem *name = new QTableWidgetItem(it.key()); + QTableWidgetItem *state = new QTableWidgetItem(it.value()); + ui->m_table->setItem(row, 0, name); + ui->m_table->setItem(row, 1, state); + ui->m_table->item(row,0)->setData(5,it.value()); + ui->m_table->item(row,0)->setCheckState(Qt::Checked); + } + connect(ui->m_table,SIGNAL(cellChanged(int,int)),this,SLOT(slot_cellChange(int,int))); +} + +void CConfirmDialog::slot_cellChange(int row, int column) +{ + if(ui->m_table->item(row,column)->checkState() == Qt::Checked) + { + QMap::const_iterator it = m_nameMap.find(ui->m_table->item(row,0)->text()); + if(it == m_nameMap.end()) + { + m_nameMap.insert(ui->m_table->item(row,0)->text(), ui->m_table->item(row,1)->text()); + } + } + else if(ui->m_table->item(row,column)->checkState() == Qt::Unchecked) + { + QMap::const_iterator it = m_nameMap.find(ui->m_table->item(row,0)->text()); + if(it != m_nameMap.end()) + { + m_nameMap.remove(ui->m_table->item(row,0)->text()); + } + } +} + +void CConfirmDialog::on_m_confirmBtn_clicked() +{ + accept(); +} + +void CConfirmDialog::on_m_cancelBtn_clicked() +{ + reject(); +} diff --git a/product/src/gui/GraphTool/fileSync/CConfirmDialog.h b/product/src/gui/GraphTool/fileSync/CConfirmDialog.h index b6e9a56b..fa3537ab 100644 --- a/product/src/gui/GraphTool/fileSync/CConfirmDialog.h +++ b/product/src/gui/GraphTool/fileSync/CConfirmDialog.h @@ -1,48 +1,48 @@ -#ifndef CCONFIRMDIALOG_H -#define CCONFIRMDIALOG_H - -#include -#include -#include "../../include/sys/sys_svn_file_sync_api/CSysFileSyncApi.h" - -namespace Ui { -class CConfirmDialog; -} - -using namespace kbd_sys; -class CConfirmDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CConfirmDialog(QWidget *parent = 0); - ~CConfirmDialog(); - - void setNameMap(const QMap &nameMap); - void setRootPath(const QString& path); - void getAllPath(QStringList &path); - QString getMessage(); - static QString getStrByState(enFirstColums state); - static QString getStrBySecond(enSecondColumn state); - static QString getStrByThird(enThirdColumns state); - static QString getStrByFourth(enFourthColumn state); - static QString getStrByFifth(enFifthColumn state); - static QString getStrBySixth(enSixthColumn state); - static QString getStrBySeventh(enSeventhColumn state); - -private slots: - void slot_cellChange(int row, int column); - void on_m_confirmBtn_clicked(); - void on_m_cancelBtn_clicked(); - -private: - void initTable(); - void initTableData(); - -private: - Ui::CConfirmDialog *ui; - QMap m_nameMap; - QString m_strRoot; -}; - -#endif // CCONFIRMDIALOG_H +#ifndef CCONFIRMDIALOG_H +#define CCONFIRMDIALOG_H + +#include +#include +#include "../../include/sys/sys_svn_file_sync_api/CSysFileSyncApi.h" + +namespace Ui { +class CConfirmDialog; +} + +using namespace kbd_sys; +class CConfirmDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CConfirmDialog(QWidget *parent = 0); + ~CConfirmDialog(); + + void setNameMap(const QMap &nameMap); + void setRootPath(const QString& path); + void getAllPath(QStringList &path); + QString getMessage(); + static QString getStrByState(enFirstColums state); + static QString getStrBySecond(enSecondColumn state); + static QString getStrByThird(enThirdColumns state); + static QString getStrByFourth(enFourthColumn state); + static QString getStrByFifth(enFifthColumn state); + static QString getStrBySixth(enSixthColumn state); + static QString getStrBySeventh(enSeventhColumn state); + +private slots: + void slot_cellChange(int row, int column); + void on_m_confirmBtn_clicked(); + void on_m_cancelBtn_clicked(); + +private: + void initTable(); + void initTableData(); + +private: + Ui::CConfirmDialog *ui; + QMap m_nameMap; + QString m_strRoot; +}; + +#endif // CCONFIRMDIALOG_H diff --git a/product/src/gui/GraphTool/fileSync/CConfirmDialog.ui b/product/src/gui/GraphTool/fileSync/CConfirmDialog.ui index 7f3faeab..4a50747b 100644 --- a/product/src/gui/GraphTool/fileSync/CConfirmDialog.ui +++ b/product/src/gui/GraphTool/fileSync/CConfirmDialog.ui @@ -1,163 +1,163 @@ - - - CConfirmDialog - - - - 0 - 0 - 379 - 370 - - - - 提交 - - - - 3 - - - 3 - - - 3 - - - 3 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 日志信息: - - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - - - - - - - 0 - 30 - - - - - 16777215 - 30 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 331 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - - - - - + + + CConfirmDialog + + + + 0 + 0 + 379 + 370 + + + + 提交 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 日志信息: + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + + + + + 0 + 30 + + + + + 16777215 + 30 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 331 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + + + + + diff --git a/product/src/gui/GraphTool/fileSync/CFileSyncDialog.cpp b/product/src/gui/GraphTool/fileSync/CFileSyncDialog.cpp index a3a3e06c..a3be281c 100644 --- a/product/src/gui/GraphTool/fileSync/CFileSyncDialog.cpp +++ b/product/src/gui/GraphTool/fileSync/CFileSyncDialog.cpp @@ -1,568 +1,568 @@ -#include "CFileSyncDialog.h" -#include "ui_CFileSyncDialog.h" -#include "CConfirmDialog.h" -#include "../include/public/pub_utility_api/I18N.h" -#include -#include -#include -#include -#include - -#ifdef CODEC_EXECUTE -#pragma execution_character_set("utf-8") -#endif - -CFileSyncDialog::CFileSyncDialog(QDialog *parent) : - QDialog(parent), - ui(new Ui::CFileSyncDialog) -{ - QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf8")); - - if(kbd_public::getCurLanguage() == "en") - { - QTranslator * sysTranslator = new QTranslator(this); - sysTranslator->load(":/fileSync_en.qm"); - QApplication::installTranslator(sysTranslator); - } - - ui->setupUi(this); - - m_FileTypeList << "docx" << "txt" << "glx" << "ilx" << "qss" << "xml" << "json" << "png" << "jpg"; - m_ptrSysFileSync = new CSysFileSyncApi(); - - ui->m_filePathComb->setEditable(true); - initFileTable(); - initMenu(); - initComb(); -} - -CFileSyncDialog::~CFileSyncDialog() -{ - if(m_ptrSysFileSync) - { - delete m_ptrSysFileSync; - m_ptrSysFileSync = NULL; - } - delete ui; -} - -void CFileSyncDialog::getFileNameByPath(const QStringList& path, QStringList &name) -{ - for(int i=0; i statusMap; - for(int i=0; i::const_iterator iter = statusMap.constBegin(); - for(;iter != statusMap.constEnd(); ++iter) - { - if(iter.value().itemChange == FIRST_ADD - || iter.value().itemChange == FIRST_DELETED - || iter.value().itemChange == FIRST_MODIFIED - || iter.value().itemChange == FIRST_REPLACED) - { - commitList.append(QString::fromStdString(iter.value().strFilePath)); - } - } - if(commitList.length() == 0) - { - isSuccess = true; - return; - } - - QString strOutPut; - int ret = m_ptrSysFileSync->exeCommit(commitList, strOutPut, errStr, - "", "", "web发布"); - - if(ret == 0) - { - isSuccess = true; - } - else - { - isSuccess = false; - } -} - -void CFileSyncDialog::slot_add() -{ - QString strOutPut; - QString strError; - - stSelectedPath st; - st.isAllSelect = false; - st.action = ACTION_ADD; - getSelectsPath(st); - QStringList& path = st.path; - - QStringList nameList; - getFileNameByPath(path, nameList); - if(nameList.length() == 0) - { - QMessageBox::information(this,tr("提示"),tr("无需添加"),QMessageBox::Ok); - return; - } - - QString text; - for(int i=0;iexeAdd(path, strOutPut, strError); - if(ret != 0) - { - QMessageBox::information(this,tr("提示"),tr("添加失败: ") + QString("%1").arg(strError),QMessageBox::Ok); - return; - } - emit ui->m_filePathComb->editTextChanged(ui->m_filePathComb->currentText()); - } -} - -void CFileSyncDialog::slot_commit() -{ - stSelectedPath st; - st.isAllSelect = false; - st.action = ACTION_COMMIT; - getSelectsPath(st); - commit(st.path); -} - -void CFileSyncDialog::slot_delete() -{ - QString strOutPut; - QString strError; - - stSelectedPath st; - st.isAllSelect = false; - st.action = ACTION_DELETE; - getSelectsPath(st); - QStringList& path = st.path; - - QStringList nameList; - getFileNameByPath(path, nameList); - if(nameList.length() == 0) - { - QMessageBox::information(this,tr("提示"),tr("无需删除"),QMessageBox::Ok); - return; - } - - QString text; - for(int i=0;iexeDelete(path, strOutPut, strError); - if(ret != 0) - { - QMessageBox::information(this,tr("提示"),tr("删除失败: ") + QString("%1").arg(strError),QMessageBox::Ok); - return; - } - emit ui->m_filePathComb->editTextChanged(ui->m_filePathComb->currentText()); - } -} - -void CFileSyncDialog::slot_allCommit() -{ - stSelectedPath st; - st.isAllSelect = true; - st.action = ACTION_COMMIT; - getSelectsPath(st); - commit(st.path); -} - -void CFileSyncDialog::on_m_filePathComb_editTextChanged(const QString &arg1) -{ - QString path = ui->m_filePathComb->currentText(); - if(path == "") - { - return; - } - QFileInfoList list; - QMap svnMap; - QString strError = QString(); - getFileInfos(arg1, list); - getSvnFile(path, svnMap, strError); - updatFileTable(list, svnMap); -} - -void CFileSyncDialog::on_m_selectFileBtn_clicked() -{ - QString fileName = QFileDialog::getExistingDirectory(this,tr("选择文件"),"../../data"); - if(fileName == "") - { - return; - } - - ui->m_filePathComb->setCurrentText(fileName); -} - -void CFileSyncDialog::on_m_reloadBtn_clicked() -{ - emit ui->m_filePathComb->editTextChanged(ui->m_filePathComb->currentText()); -} - -void CFileSyncDialog::on_m_fileTextTable_customContextMenuRequested(const QPoint &pos) -{ - if(ui->m_fileTextTable->itemAt(pos)) - { - m_menu->addAction(ui->m_actionAdd); - m_menu->addAction(ui->m_actionDelete); - m_menu->addAction(ui->m_actionCommit); - m_menu->removeAction(ui->m_actionAllCommit); - } - else - { - m_menu->addAction(ui->m_actionAllCommit); - m_menu->removeAction(ui->m_actionAdd); - m_menu->removeAction(ui->m_actionDelete); - m_menu->removeAction(ui->m_actionCommit); - } - m_menu->exec(QCursor::pos()); -} - -void CFileSyncDialog::initFileTable() -{ - ui->m_fileTextTable->setColumnCount(3); - ui->m_fileTextTable->setColumnWidth(0,350); - ui->m_fileTextTable->hideColumn(1); - ui->m_fileTextTable->verticalHeader()->hide(); - ui->m_fileTextTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); - ui->m_fileTextTable->setHorizontalHeaderLabels(QStringList() << tr("名称") << tr("修改日期") << tr("状态")); - ui->m_fileTextTable->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->m_fileTextTable->setEditTriggers(0); -} - -void CFileSyncDialog::initMenu() -{ - m_menu = new QMenu(this); - - connect(ui->m_actionAdd,SIGNAL(triggered(bool)),this,SLOT(slot_add())); - connect(ui->m_actionCommit,SIGNAL(triggered(bool)),this,SLOT(slot_commit())); - connect(ui->m_actionDelete,SIGNAL(triggered(bool)),this,SLOT(slot_delete())); - connect(ui->m_actionAllCommit,SIGNAL(triggered(bool)),this,SLOT(slot_allCommit())); -} - -void CFileSyncDialog::initComb() -{ - QDir dir = QDir::current(); - dir.cdUp(); - dir.cdUp(); - ui->m_filePathComb->addItem(dir.path() + "/data/pic"); - ui->m_filePathComb->addItem(dir.path() + "/data/icon"); -} - -void CFileSyncDialog::getFileInfos(const QString &path, QFileInfoList &list) -{ - QDir dir(path); - QStringList nameFilters; - list = dir.entryInfoList(nameFilters, QDir::Files|QDir::Readable, QDir::Name|QDir::Time|QDir::Type|QDir::Size); -} - -void CFileSyncDialog::getSvnFile(const QString &path, QMap &name, QString& error) -{ - QVector vecFileStatus; - - QStringList list; - list.append(path); - int ret = m_ptrSysFileSync->exeStatus(list, vecFileStatus, error); - if(ret == 0) - { - for(int i=0; i& svnMap) -{ - fileFilter(list, svnMap); //< 过滤出无修改的文件 - int rowCount = list.length() + svnMap.size(); - ui->m_fileTextTable->clearContents(); - ui->m_fileTextTable->setRowCount(rowCount); - QIcon icon(":/icon/NormalIcon.ico"); - - QMap::const_iterator it = svnMap.begin(); - for(int j=0;it!=svnMap.end();++it,++j) - { - const stFileStatus& st = it.value(); - QTableWidgetItem *name = new QTableWidgetItem(QIcon(getIconByState(st.itemChange)),it.key()); - QTableWidgetItem *status = new QTableWidgetItem(getStatusStr(st)); - ui->m_fileTextTable->setItem(j, 0, name); - ui->m_fileTextTable->setItem(j, 2, status); - ui->m_fileTextTable->item(j,0)->setData(5,int(st.itemChange)); - } - - for(int i=svnMap.size(); im_fileTextTable->setItem(i, 0, fileName); - ui->m_fileTextTable->setItem(i, 1, lastModify); - ui->m_fileTextTable->setItem(i, 2, normalStatus); - ui->m_fileTextTable->item(i,0)->setData(5,1); //test changed - } -} - -void CFileSyncDialog::fileFilter(QFileInfoList &list, const QMap& svnMap) -{ - for(int i=0;i::const_iterator it = svnMap.find(list.at(i).fileName()); - if(it != svnMap.end()) - { - list.removeAt(i); - --i; - } - } -} - -QString CFileSyncDialog::getStatusStr(const stFileStatus &st) -{ - QString ret = CConfirmDialog::getStrByState(st.itemChange); - if((st.propertiesChange != SECOND_NO_CHANGED) - || (st.workingCopyLocked != THIRD_NOT_LOCKED) - || (st.commitContainHistory != FOURTH_NOT_HISTORY) - || (st.SwitchOrExternalRefer != FIFTH_NORMAL) - || (st.versionLocked != SIXTH_NOT_LOCKED) - || (st.projectConflict != SEVENTH_NORMAL)) - { - ret += tr(" (异常) "); - } - return ret; -} - -QString CFileSyncDialog::getIconByState(enFirstColums status) -{ - QString ret; - switch (status) { - case FIRST_NO_CHANGED: - { - ret = ":/icon/NormalIcon.ico"; - break; - } - case FIRST_ADD: - { - ret = ":/icon/AddedIcon.ico"; - break; - } - case FIRST_CONFLICTED: - { - ret = ":/icon/ConflictIcon.ico"; - break; - } - case FIRST_DELETED: - { - ret = ":/icon/DeletedIcon.ico"; - break; - } - case FIRST_IGNORED: - { - ret = ":/icon/IgnoredIcon.ico"; - break; - } - case FIRST_MODIFIED: - case FIRST_REPLACED: - { - ret = ":/icon/ModifiedIcon.ico"; - break; - } - case FIRST_EXTERNALS_DEFINE: - case FIRST_NOT_VERSION_CONTROL: - { - ret = ":/icon/UnversionedIcon.ico"; - break; - } - case FIRST_MISS: - { - ret = ""; - break; - } - case FIRST_OBSTRUCTED: - { - ret = ""; - break; - } - case FIRST_ILLEGAL: - { - ret = ""; - break; - } - default: - break; - } - return ret; -} - -void CFileSyncDialog::getSelectsPath(stSelectedPath &stPath) -{ - QList list = ui->m_fileTextTable->selectedRanges(); - if(stPath.isAllSelect) - { - QTableWidgetSelectionRange range(0, 0, ui->m_fileTextTable->rowCount()-1, ui->m_fileTextTable->columnCount()-1); - list.clear(); - list.append(range); - } - for(int i=0;im_filePathComb->currentText() + "\\" + ui->m_fileTextTable->item(row+list.at(i).topRow(),0)->text()); -#else - stPath.path.append(ui->m_filePathComb->currentText() + "/" + ui->m_fileTextTable->item(row+list.at(i).topRow(),0)->text()); -#endif - } - } -} - -bool CFileSyncDialog::checkIsNeedAppend(int row, enOptAction action) -{ - bool ret = false; - int current = ui->m_fileTextTable->item(row,0)->data(5).toInt(); - switch (action) { - case ACTION_ADD: - { - if(current == FIRST_EXTERNALS_DEFINE || current == FIRST_NOT_VERSION_CONTROL) - { - ret = true; - } - break; - } - case ACTION_DELETE: - { - if(current == FIRST_NO_CHANGED) - { - ret = true; - } - break; - } - case ACTION_COMMIT: - { - if(current == FIRST_ADD || current == FIRST_DELETED || current == FIRST_MODIFIED || current == FIRST_REPLACED) - { - ret = true; - } - break; - } - default: - ret = true; - break; - } - return ret; -} - -void CFileSyncDialog::commit(const QStringList &path) -{ - QString strOutPut; - QString strError; - - QStringList nameList; - getFileNameByPath(path, nameList); - if(nameList.length() == 0) - { - QMessageBox::information(this,tr("提示"),tr("无需提交"),QMessageBox::Ok); - return; - } - QMap map; - getCommitMap(nameList, map); - CConfirmDialog dialog(this); - dialog.setNameMap(map); - dialog.setRootPath(ui->m_filePathComb->currentText()); - if(dialog.exec()) - { - QStringList allPath; - dialog.getAllPath(allPath); - QString message = dialog.getMessage(); - int ret = m_ptrSysFileSync->exeCommit(allPath, strOutPut, strError, - "","",message); - if(ret != 0) - { - QMessageBox::information(this,tr("提示"),tr("提交失败: ") + QString("%1").arg(strError),QMessageBox::Ok); - return; - } - emit ui->m_filePathComb->editTextChanged(ui->m_filePathComb->currentText()); - } -} - -void CFileSyncDialog::getCommitMap(const QStringList &name, QMap &map) -{ - for(int i=0;im_fileTextTable->rowCount();++row) - { - if(name.at(i) == ui->m_fileTextTable->item(row,0)->text()) - { - map.insert(name.at(i), ui->m_fileTextTable->item(row,2)->text()); - break; - } - } - } -} +#include "CFileSyncDialog.h" +#include "ui_CFileSyncDialog.h" +#include "CConfirmDialog.h" +#include "../include/public/pub_utility_api/I18N.h" +#include +#include +#include +#include +#include + +#ifdef CODEC_EXECUTE +#pragma execution_character_set("utf-8") +#endif + +CFileSyncDialog::CFileSyncDialog(QDialog *parent) : + QDialog(parent), + ui(new Ui::CFileSyncDialog) +{ + QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf8")); + + if(kbd_public::getCurLanguage() == "en") + { + QTranslator * sysTranslator = new QTranslator(this); + sysTranslator->load(":/fileSync_en.qm"); + QApplication::installTranslator(sysTranslator); + } + + ui->setupUi(this); + + m_FileTypeList << "docx" << "txt" << "glx" << "ilx" << "qss" << "xml" << "json" << "png" << "jpg"; + m_ptrSysFileSync = new CSysFileSyncApi(); + + ui->m_filePathComb->setEditable(true); + initFileTable(); + initMenu(); + initComb(); +} + +CFileSyncDialog::~CFileSyncDialog() +{ + if(m_ptrSysFileSync) + { + delete m_ptrSysFileSync; + m_ptrSysFileSync = NULL; + } + delete ui; +} + +void CFileSyncDialog::getFileNameByPath(const QStringList& path, QStringList &name) +{ + for(int i=0; i statusMap; + for(int i=0; i::const_iterator iter = statusMap.constBegin(); + for(;iter != statusMap.constEnd(); ++iter) + { + if(iter.value().itemChange == FIRST_ADD + || iter.value().itemChange == FIRST_DELETED + || iter.value().itemChange == FIRST_MODIFIED + || iter.value().itemChange == FIRST_REPLACED) + { + commitList.append(QString::fromStdString(iter.value().strFilePath)); + } + } + if(commitList.length() == 0) + { + isSuccess = true; + return; + } + + QString strOutPut; + int ret = m_ptrSysFileSync->exeCommit(commitList, strOutPut, errStr, + "", "", "web发布"); + + if(ret == 0) + { + isSuccess = true; + } + else + { + isSuccess = false; + } +} + +void CFileSyncDialog::slot_add() +{ + QString strOutPut; + QString strError; + + stSelectedPath st; + st.isAllSelect = false; + st.action = ACTION_ADD; + getSelectsPath(st); + QStringList& path = st.path; + + QStringList nameList; + getFileNameByPath(path, nameList); + if(nameList.length() == 0) + { + QMessageBox::information(this,tr("提示"),tr("无需添加"),QMessageBox::Ok); + return; + } + + QString text; + for(int i=0;iexeAdd(path, strOutPut, strError); + if(ret != 0) + { + QMessageBox::information(this,tr("提示"),tr("添加失败: ") + QString("%1").arg(strError),QMessageBox::Ok); + return; + } + emit ui->m_filePathComb->editTextChanged(ui->m_filePathComb->currentText()); + } +} + +void CFileSyncDialog::slot_commit() +{ + stSelectedPath st; + st.isAllSelect = false; + st.action = ACTION_COMMIT; + getSelectsPath(st); + commit(st.path); +} + +void CFileSyncDialog::slot_delete() +{ + QString strOutPut; + QString strError; + + stSelectedPath st; + st.isAllSelect = false; + st.action = ACTION_DELETE; + getSelectsPath(st); + QStringList& path = st.path; + + QStringList nameList; + getFileNameByPath(path, nameList); + if(nameList.length() == 0) + { + QMessageBox::information(this,tr("提示"),tr("无需删除"),QMessageBox::Ok); + return; + } + + QString text; + for(int i=0;iexeDelete(path, strOutPut, strError); + if(ret != 0) + { + QMessageBox::information(this,tr("提示"),tr("删除失败: ") + QString("%1").arg(strError),QMessageBox::Ok); + return; + } + emit ui->m_filePathComb->editTextChanged(ui->m_filePathComb->currentText()); + } +} + +void CFileSyncDialog::slot_allCommit() +{ + stSelectedPath st; + st.isAllSelect = true; + st.action = ACTION_COMMIT; + getSelectsPath(st); + commit(st.path); +} + +void CFileSyncDialog::on_m_filePathComb_editTextChanged(const QString &arg1) +{ + QString path = ui->m_filePathComb->currentText(); + if(path == "") + { + return; + } + QFileInfoList list; + QMap svnMap; + QString strError = QString(); + getFileInfos(arg1, list); + getSvnFile(path, svnMap, strError); + updatFileTable(list, svnMap); +} + +void CFileSyncDialog::on_m_selectFileBtn_clicked() +{ + QString fileName = QFileDialog::getExistingDirectory(this,tr("选择文件"),"../../data"); + if(fileName == "") + { + return; + } + + ui->m_filePathComb->setCurrentText(fileName); +} + +void CFileSyncDialog::on_m_reloadBtn_clicked() +{ + emit ui->m_filePathComb->editTextChanged(ui->m_filePathComb->currentText()); +} + +void CFileSyncDialog::on_m_fileTextTable_customContextMenuRequested(const QPoint &pos) +{ + if(ui->m_fileTextTable->itemAt(pos)) + { + m_menu->addAction(ui->m_actionAdd); + m_menu->addAction(ui->m_actionDelete); + m_menu->addAction(ui->m_actionCommit); + m_menu->removeAction(ui->m_actionAllCommit); + } + else + { + m_menu->addAction(ui->m_actionAllCommit); + m_menu->removeAction(ui->m_actionAdd); + m_menu->removeAction(ui->m_actionDelete); + m_menu->removeAction(ui->m_actionCommit); + } + m_menu->exec(QCursor::pos()); +} + +void CFileSyncDialog::initFileTable() +{ + ui->m_fileTextTable->setColumnCount(3); + ui->m_fileTextTable->setColumnWidth(0,350); + ui->m_fileTextTable->hideColumn(1); + ui->m_fileTextTable->verticalHeader()->hide(); + ui->m_fileTextTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); + ui->m_fileTextTable->setHorizontalHeaderLabels(QStringList() << tr("名称") << tr("修改日期") << tr("状态")); + ui->m_fileTextTable->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->m_fileTextTable->setEditTriggers(0); +} + +void CFileSyncDialog::initMenu() +{ + m_menu = new QMenu(this); + + connect(ui->m_actionAdd,SIGNAL(triggered(bool)),this,SLOT(slot_add())); + connect(ui->m_actionCommit,SIGNAL(triggered(bool)),this,SLOT(slot_commit())); + connect(ui->m_actionDelete,SIGNAL(triggered(bool)),this,SLOT(slot_delete())); + connect(ui->m_actionAllCommit,SIGNAL(triggered(bool)),this,SLOT(slot_allCommit())); +} + +void CFileSyncDialog::initComb() +{ + QDir dir = QDir::current(); + dir.cdUp(); + dir.cdUp(); + ui->m_filePathComb->addItem(dir.path() + "/data/pic"); + ui->m_filePathComb->addItem(dir.path() + "/data/icon"); +} + +void CFileSyncDialog::getFileInfos(const QString &path, QFileInfoList &list) +{ + QDir dir(path); + QStringList nameFilters; + list = dir.entryInfoList(nameFilters, QDir::Files|QDir::Readable, QDir::Name|QDir::Time|QDir::Type|QDir::Size); +} + +void CFileSyncDialog::getSvnFile(const QString &path, QMap &name, QString& error) +{ + QVector vecFileStatus; + + QStringList list; + list.append(path); + int ret = m_ptrSysFileSync->exeStatus(list, vecFileStatus, error); + if(ret == 0) + { + for(int i=0; i& svnMap) +{ + fileFilter(list, svnMap); //< 过滤出无修改的文件 + int rowCount = list.length() + svnMap.size(); + ui->m_fileTextTable->clearContents(); + ui->m_fileTextTable->setRowCount(rowCount); + QIcon icon(":/icon/NormalIcon.ico"); + + QMap::const_iterator it = svnMap.begin(); + for(int j=0;it!=svnMap.end();++it,++j) + { + const stFileStatus& st = it.value(); + QTableWidgetItem *name = new QTableWidgetItem(QIcon(getIconByState(st.itemChange)),it.key()); + QTableWidgetItem *status = new QTableWidgetItem(getStatusStr(st)); + ui->m_fileTextTable->setItem(j, 0, name); + ui->m_fileTextTable->setItem(j, 2, status); + ui->m_fileTextTable->item(j,0)->setData(5,int(st.itemChange)); + } + + for(int i=svnMap.size(); im_fileTextTable->setItem(i, 0, fileName); + ui->m_fileTextTable->setItem(i, 1, lastModify); + ui->m_fileTextTable->setItem(i, 2, normalStatus); + ui->m_fileTextTable->item(i,0)->setData(5,1); //test changed + } +} + +void CFileSyncDialog::fileFilter(QFileInfoList &list, const QMap& svnMap) +{ + for(int i=0;i::const_iterator it = svnMap.find(list.at(i).fileName()); + if(it != svnMap.end()) + { + list.removeAt(i); + --i; + } + } +} + +QString CFileSyncDialog::getStatusStr(const stFileStatus &st) +{ + QString ret = CConfirmDialog::getStrByState(st.itemChange); + if((st.propertiesChange != SECOND_NO_CHANGED) + || (st.workingCopyLocked != THIRD_NOT_LOCKED) + || (st.commitContainHistory != FOURTH_NOT_HISTORY) + || (st.SwitchOrExternalRefer != FIFTH_NORMAL) + || (st.versionLocked != SIXTH_NOT_LOCKED) + || (st.projectConflict != SEVENTH_NORMAL)) + { + ret += tr(" (异常) "); + } + return ret; +} + +QString CFileSyncDialog::getIconByState(enFirstColums status) +{ + QString ret; + switch (status) { + case FIRST_NO_CHANGED: + { + ret = ":/icon/NormalIcon.ico"; + break; + } + case FIRST_ADD: + { + ret = ":/icon/AddedIcon.ico"; + break; + } + case FIRST_CONFLICTED: + { + ret = ":/icon/ConflictIcon.ico"; + break; + } + case FIRST_DELETED: + { + ret = ":/icon/DeletedIcon.ico"; + break; + } + case FIRST_IGNORED: + { + ret = ":/icon/IgnoredIcon.ico"; + break; + } + case FIRST_MODIFIED: + case FIRST_REPLACED: + { + ret = ":/icon/ModifiedIcon.ico"; + break; + } + case FIRST_EXTERNALS_DEFINE: + case FIRST_NOT_VERSION_CONTROL: + { + ret = ":/icon/UnversionedIcon.ico"; + break; + } + case FIRST_MISS: + { + ret = ""; + break; + } + case FIRST_OBSTRUCTED: + { + ret = ""; + break; + } + case FIRST_ILLEGAL: + { + ret = ""; + break; + } + default: + break; + } + return ret; +} + +void CFileSyncDialog::getSelectsPath(stSelectedPath &stPath) +{ + QList list = ui->m_fileTextTable->selectedRanges(); + if(stPath.isAllSelect) + { + QTableWidgetSelectionRange range(0, 0, ui->m_fileTextTable->rowCount()-1, ui->m_fileTextTable->columnCount()-1); + list.clear(); + list.append(range); + } + for(int i=0;im_filePathComb->currentText() + "\\" + ui->m_fileTextTable->item(row+list.at(i).topRow(),0)->text()); +#else + stPath.path.append(ui->m_filePathComb->currentText() + "/" + ui->m_fileTextTable->item(row+list.at(i).topRow(),0)->text()); +#endif + } + } +} + +bool CFileSyncDialog::checkIsNeedAppend(int row, enOptAction action) +{ + bool ret = false; + int current = ui->m_fileTextTable->item(row,0)->data(5).toInt(); + switch (action) { + case ACTION_ADD: + { + if(current == FIRST_EXTERNALS_DEFINE || current == FIRST_NOT_VERSION_CONTROL) + { + ret = true; + } + break; + } + case ACTION_DELETE: + { + if(current == FIRST_NO_CHANGED) + { + ret = true; + } + break; + } + case ACTION_COMMIT: + { + if(current == FIRST_ADD || current == FIRST_DELETED || current == FIRST_MODIFIED || current == FIRST_REPLACED) + { + ret = true; + } + break; + } + default: + ret = true; + break; + } + return ret; +} + +void CFileSyncDialog::commit(const QStringList &path) +{ + QString strOutPut; + QString strError; + + QStringList nameList; + getFileNameByPath(path, nameList); + if(nameList.length() == 0) + { + QMessageBox::information(this,tr("提示"),tr("无需提交"),QMessageBox::Ok); + return; + } + QMap map; + getCommitMap(nameList, map); + CConfirmDialog dialog(this); + dialog.setNameMap(map); + dialog.setRootPath(ui->m_filePathComb->currentText()); + if(dialog.exec()) + { + QStringList allPath; + dialog.getAllPath(allPath); + QString message = dialog.getMessage(); + int ret = m_ptrSysFileSync->exeCommit(allPath, strOutPut, strError, + "","",message); + if(ret != 0) + { + QMessageBox::information(this,tr("提示"),tr("提交失败: ") + QString("%1").arg(strError),QMessageBox::Ok); + return; + } + emit ui->m_filePathComb->editTextChanged(ui->m_filePathComb->currentText()); + } +} + +void CFileSyncDialog::getCommitMap(const QStringList &name, QMap &map) +{ + for(int i=0;im_fileTextTable->rowCount();++row) + { + if(name.at(i) == ui->m_fileTextTable->item(row,0)->text()) + { + map.insert(name.at(i), ui->m_fileTextTable->item(row,2)->text()); + break; + } + } + } +} diff --git a/product/src/gui/GraphTool/fileSync/CFileSyncDialog.h b/product/src/gui/GraphTool/fileSync/CFileSyncDialog.h index 66f9161f..026f762c 100644 --- a/product/src/gui/GraphTool/fileSync/CFileSyncDialog.h +++ b/product/src/gui/GraphTool/fileSync/CFileSyncDialog.h @@ -1,85 +1,85 @@ -#ifndef CFILESYNCDIALOG_H -#define CFILESYNCDIALOG_H - -#include "../../include/sys/sys_svn_file_sync_api/CSysFileSyncApi.h" -#include -#include -#include -#include - -namespace Ui { -class CFileSyncDialog; -} - -enum enOptAction -{ - ACTION_DEFAULT, - ACTION_ADD, - ACTION_DELETE, - ACTION_COMMIT -}; - -struct stSelectedPath -{ - bool isAllSelect; - enOptAction action; - QStringList path; -}; - -using namespace kbd_sys; -class CFileSyncDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CFileSyncDialog(QDialog *parent = 0); - ~CFileSyncDialog(); - - void getFileNameByPath(const QStringList &path, QStringList& name); - -public slots: - /** - * @brief webPublish web发布 - * @param pathList 全路径文件夹 - * @param isSuccess 是否成功 - * @param errStr 错误信息,无错为空字符串 - */ - void webPublish(const QStringList& pathList, bool &isSuccess, QString& errStr); - -private slots: - void slot_add(); - void slot_commit(); - void slot_delete(); - void slot_allCommit(); - void on_m_filePathComb_editTextChanged(const QString &arg1); - void on_m_selectFileBtn_clicked(); //选择路径 - void on_m_reloadBtn_clicked(); //重新加载文件 - void on_m_fileTextTable_customContextMenuRequested(const QPoint &pos); - -private: - void initFileTable(); - void initMenu(); - void initComb(); - - void getFileInfos(const QString &path, QFileInfoList &list); //获取路径下的所有文件信息 - void getSvnFile(const QString &path, QMap &name, QString &error); - QString getTimeStr(const QDateTime& time); - void updatFileTable(QFileInfoList &list, const QMap &svnMap); - void fileFilter(QFileInfoList &list, const QMap &svnMap); - QString getStatusStr(const stFileStatus& st); - - QString getIconByState(enFirstColums status); - - void getSelectsPath(stSelectedPath& stPath); //合并所有选择的文件路径 - bool checkIsNeedAppend(int row, enOptAction action); - void commit(const QStringList &path); - void getCommitMap(const QStringList& name, QMap &map); - -private: - Ui::CFileSyncDialog *ui; - QMenu *m_menu; - CSysFileSyncApi *m_ptrSysFileSync; - QStringList m_FileTypeList; -}; - -#endif // CFILESYNCDIALOG_H +#ifndef CFILESYNCDIALOG_H +#define CFILESYNCDIALOG_H + +#include "../../include/sys/sys_svn_file_sync_api/CSysFileSyncApi.h" +#include +#include +#include +#include + +namespace Ui { +class CFileSyncDialog; +} + +enum enOptAction +{ + ACTION_DEFAULT, + ACTION_ADD, + ACTION_DELETE, + ACTION_COMMIT +}; + +struct stSelectedPath +{ + bool isAllSelect; + enOptAction action; + QStringList path; +}; + +using namespace kbd_sys; +class CFileSyncDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CFileSyncDialog(QDialog *parent = 0); + ~CFileSyncDialog(); + + void getFileNameByPath(const QStringList &path, QStringList& name); + +public slots: + /** + * @brief webPublish web发布 + * @param pathList 全路径文件夹 + * @param isSuccess 是否成功 + * @param errStr 错误信息,无错为空字符串 + */ + void webPublish(const QStringList& pathList, bool &isSuccess, QString& errStr); + +private slots: + void slot_add(); + void slot_commit(); + void slot_delete(); + void slot_allCommit(); + void on_m_filePathComb_editTextChanged(const QString &arg1); + void on_m_selectFileBtn_clicked(); //选择路径 + void on_m_reloadBtn_clicked(); //重新加载文件 + void on_m_fileTextTable_customContextMenuRequested(const QPoint &pos); + +private: + void initFileTable(); + void initMenu(); + void initComb(); + + void getFileInfos(const QString &path, QFileInfoList &list); //获取路径下的所有文件信息 + void getSvnFile(const QString &path, QMap &name, QString &error); + QString getTimeStr(const QDateTime& time); + void updatFileTable(QFileInfoList &list, const QMap &svnMap); + void fileFilter(QFileInfoList &list, const QMap &svnMap); + QString getStatusStr(const stFileStatus& st); + + QString getIconByState(enFirstColums status); + + void getSelectsPath(stSelectedPath& stPath); //合并所有选择的文件路径 + bool checkIsNeedAppend(int row, enOptAction action); + void commit(const QStringList &path); + void getCommitMap(const QStringList& name, QMap &map); + +private: + Ui::CFileSyncDialog *ui; + QMenu *m_menu; + CSysFileSyncApi *m_ptrSysFileSync; + QStringList m_FileTypeList; +}; + +#endif // CFILESYNCDIALOG_H diff --git a/product/src/gui/GraphTool/fileSync/CFileSyncDialog.ui b/product/src/gui/GraphTool/fileSync/CFileSyncDialog.ui index b9aa3d82..41375e28 100644 --- a/product/src/gui/GraphTool/fileSync/CFileSyncDialog.ui +++ b/product/src/gui/GraphTool/fileSync/CFileSyncDialog.ui @@ -1,121 +1,121 @@ - - - CFileSyncDialog - - - - 0 - 0 - 497 - 325 - - - - 文件同步 - - - - - - - 0 - 30 - - - - - 16777215 - 30 - - - - - - - - - 30 - 30 - - - - - 30 - 30 - - - - - - - - - - - :/icon/open.png:/icon/open.png - - - - - - - - 30 - 30 - - - - - 30 - 30 - - - - - - - - - - - :/icon/reload.png:/icon/reload.png - - - - - - - Qt::CustomContextMenu - - - false - - - - - - - 提交 - - - - - 删除 - - - - - 添加 - - - - - 提交 - - - - - - - - + + + CFileSyncDialog + + + + 0 + 0 + 497 + 325 + + + + 文件同步 + + + + + + + 0 + 30 + + + + + 16777215 + 30 + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + + :/icon/open.png:/icon/open.png + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + + :/icon/reload.png:/icon/reload.png + + + + + + + Qt::CustomContextMenu + + + false + + + + + + + 提交 + + + + + 删除 + + + + + 添加 + + + + + 提交 + + + + + + + + diff --git a/product/src/gui/GraphTool/fileSync/fileSync.pro b/product/src/gui/GraphTool/fileSync/fileSync.pro index eb9c228f..2c234118 100644 --- a/product/src/gui/GraphTool/fileSync/fileSync.pro +++ b/product/src/gui/GraphTool/fileSync/fileSync.pro @@ -1,58 +1,58 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-04-25T14:51:57 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = fileSync -TEMPLATE = app - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -DEFAULTCODEC = utf-8 - -SOURCES += \ - main.cpp \ - CConfirmDialog.cpp \ - CFileSyncDialog.cpp - -HEADERS += \ - CConfirmDialog.h \ - CFileSyncDialog.h - -FORMS += \ - CFileSyncDialog.ui \ - CConfirmDialog.ui - - -RESOURCES += \ - resource.qrc - -win32{ - DEFINES += DLL_OUT -} - -LIBS += \ - -lsys_svn_file_sync_api \ - -lpub_utility_api - -#------------------------------------------------------------------- -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2019-04-25T14:51:57 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = fileSync +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 +DEFAULTCODEC = utf-8 + +SOURCES += \ + main.cpp \ + CConfirmDialog.cpp \ + CFileSyncDialog.cpp + +HEADERS += \ + CConfirmDialog.h \ + CFileSyncDialog.h + +FORMS += \ + CFileSyncDialog.ui \ + CConfirmDialog.ui + + +RESOURCES += \ + resource.qrc + +win32{ + DEFINES += DLL_OUT +} + +LIBS += \ + -lsys_svn_file_sync_api \ + -lpub_utility_api + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/GraphTool/fileSync/fileSync_en.ts b/product/src/gui/GraphTool/fileSync/fileSync_en.ts index ccbe4382..e8e1353f 100644 --- a/product/src/gui/GraphTool/fileSync/fileSync_en.ts +++ b/product/src/gui/GraphTool/fileSync/fileSync_en.ts @@ -1,260 +1,260 @@ - - - - - CConfirmDialog - - - 提交 - Commit - - - - 日志信息: - Log Infomation : - - - - 确认 - Confirm - - - - 取消 - Cancel - - - - - 无修改 - Normal - - - - 添加 - Add - - - - - 冲突 - Conflict - - - - 删除 - Delete - - - - 忽略 - Ignore - - - - 修改 - Modified - - - - 替换 - Replace - - - - 未纳入版本控制的目录,被外部引用的目录所创建 - Externals-Define - - - - 未纳入版本控制 - Non-Versioned - - - - 遗失 - Missing - - - - 重名 - Same Name - - - - - - - - - - 自定义非法状态 - Illegal - - - - 改变 - Modified - - - - 未锁定 - Not-Locked - - - - 锁定 - Locked - - - - 没有历史 - Not-History - - - - 包含历史 - Contain-History - - - - - 正常 - Normal - - - - 以切换 - Switch - - - - 被外部引用创建的文件 - External Refer Created - - - - 没有被锁定标记 - Not-Locked - - - - 存在锁定标记 - Locked - - - - 树冲突 - Tree Conflict - - - - 名称 - Name - - - - 状态 - State - - - - CFileSyncDialog - - - 文件同步 - FileSync - - - - - 提交 - Commit - - - - 删除 - Delete - - - - 添加 - Add - - - - - - - - - 提示 - Prompt - - - - 无需添加 - Don't need to add - - - - 确认添加 - Add Confirm - - - - 添加失败: - Add Failure: - - - - 无需删除 - Don't need to delete - - - - 确认删除 - Delete Confirm - - - - 删除失败: - Delete Failure: - - - - 选择文件 - Select File - - - - 名称 - Name - - - - 修改日期 - Modification Date - - - - 状态 - State - - - - (异常) - (abnormal) - - - - 无需提交 - Don't need to commit - - - - 提交失败: - Commit Failure: - - - + + + + + CConfirmDialog + + + 提交 + Commit + + + + 日志信息: + Log Infomation : + + + + 确认 + Confirm + + + + 取消 + Cancel + + + + + 无修改 + Normal + + + + 添加 + Add + + + + + 冲突 + Conflict + + + + 删除 + Delete + + + + 忽略 + Ignore + + + + 修改 + Modified + + + + 替换 + Replace + + + + 未纳入版本控制的目录,被外部引用的目录所创建 + Externals-Define + + + + 未纳入版本控制 + Non-Versioned + + + + 遗失 + Missing + + + + 重名 + Same Name + + + + + + + + + + 自定义非法状态 + Illegal + + + + 改变 + Modified + + + + 未锁定 + Not-Locked + + + + 锁定 + Locked + + + + 没有历史 + Not-History + + + + 包含历史 + Contain-History + + + + + 正常 + Normal + + + + 以切换 + Switch + + + + 被外部引用创建的文件 + External Refer Created + + + + 没有被锁定标记 + Not-Locked + + + + 存在锁定标记 + Locked + + + + 树冲突 + Tree Conflict + + + + 名称 + Name + + + + 状态 + State + + + + CFileSyncDialog + + + 文件同步 + FileSync + + + + + 提交 + Commit + + + + 删除 + Delete + + + + 添加 + Add + + + + + + + + + 提示 + Prompt + + + + 无需添加 + Don't need to add + + + + 确认添加 + Add Confirm + + + + 添加失败: + Add Failure: + + + + 无需删除 + Don't need to delete + + + + 确认删除 + Delete Confirm + + + + 删除失败: + Delete Failure: + + + + 选择文件 + Select File + + + + 名称 + Name + + + + 修改日期 + Modification Date + + + + 状态 + State + + + + (异常) + (abnormal) + + + + 无需提交 + Don't need to commit + + + + 提交失败: + Commit Failure: + + + diff --git a/product/src/gui/GraphTool/fileSync/main.cpp b/product/src/gui/GraphTool/fileSync/main.cpp index d3a8c15a..aec7b826 100644 --- a/product/src/gui/GraphTool/fileSync/main.cpp +++ b/product/src/gui/GraphTool/fileSync/main.cpp @@ -1,15 +1,15 @@ - -#include -#include "common/QtAppGlobalSet.h" -#include "CFileSyncDialog.h" - -int main(int argc, char *argv[]) -{ - kbd_common::doQtAppGlobalSet(); - - QApplication a(argc, argv); - CFileSyncDialog w; - w.show(); - - return a.exec(); -} + +#include +#include "common/QtAppGlobalSet.h" +#include "CFileSyncDialog.h" + +int main(int argc, char *argv[]) +{ + kbd_common::doQtAppGlobalSet(); + + QApplication a(argc, argv); + CFileSyncDialog w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/GraphTool/fileSync/resource.qrc b/product/src/gui/GraphTool/fileSync/resource.qrc index f7bfb8bf..7347f1af 100644 --- a/product/src/gui/GraphTool/fileSync/resource.qrc +++ b/product/src/gui/GraphTool/fileSync/resource.qrc @@ -1,16 +1,16 @@ - - - icon/AddedIcon.ico - icon/ConflictIcon.ico - icon/DeletedIcon.ico - icon/IgnoredIcon.ico - icon/LockedIcon.ico - icon/ModifiedIcon.ico - icon/NormalIcon.ico - icon/ReadOnlyIcon.ico - icon/UnversionedIcon.ico - icon/open.png - icon/reload.png - fileSync_en.qm - - + + + icon/AddedIcon.ico + icon/ConflictIcon.ico + icon/DeletedIcon.ico + icon/IgnoredIcon.ico + icon/LockedIcon.ico + icon/ModifiedIcon.ico + icon/NormalIcon.ico + icon/ReadOnlyIcon.ico + icon/UnversionedIcon.ico + icon/open.png + icon/reload.png + fileSync_en.qm + + diff --git a/product/src/gui/gui.pro b/product/src/gui/gui.pro index fb8388f2..5d57b708 100644 --- a/product/src/gui/gui.pro +++ b/product/src/gui/gui.pro @@ -1,10 +1,10 @@ - -#各子工程按书写顺序编译,清注意各子工程的依赖关系,被依赖的库应写在前面。 - -TEMPLATE = subdirs -CONFIG += ordered - -SUBDIRS += \ - GraphTool \ - plugin - + +#各子工程按书写顺序编译,清注意各子工程的依赖关系,被依赖的库应写在前面。 + +TEMPLATE = subdirs +CONFIG += ordered + +SUBDIRS += \ + GraphTool \ + plugin + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/AlarmAnalyzeWidget.pro b/product/src/gui/plugin/AlarmAnalyzeWidget/AlarmAnalyzeWidget.pro index f93cbb61..b11b1047 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/AlarmAnalyzeWidget.pro +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/AlarmAnalyzeWidget.pro @@ -1,84 +1,84 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-11-05T10:04:14 -# -#------------------------------------------------- - -QT += core gui charts sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = AlarmAnalyzeWidget -TEMPLATE = lib -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - main.cpp \ - CAlarmStatistics.cpp \ - CAlarmModel.cpp \ - CAlarmCompare.cpp \ - CProcessDialog.cpp \ - CCompareQueryThread.cpp \ - CommonFunction.cpp \ - CStatisticsQueryThread.cpp \ - CWaveListDialog.cpp \ - CAlarmStatisticsPluginWidget.cpp \ - CAlarmReport.cpp \ - CTableWidget.cpp - -HEADERS += \ - CAlarmStatistics.h \ - CAlarmModel.h \ - SAlarmInfo.h \ - SAlarmList.h \ - CAlarmLevelComboBox.h \ - SAlarmLevel.h \ - CAlarmCompare.h \ - CProcessDialog.h \ - CCompareQueryThread.h \ - CommonDefine.h \ - CommonFunction.h \ - CStatisticsQueryThread.h \ - SDeviceGroup.h \ - SLocation.h \ - CWaveListDialog.h \ - CAlarmStatisticsPluginWidget.h \ - CAlarmReport.h \ - CTableWidget.h - -FORMS += \ - CAlarmStatistics.ui \ - CAlarmCompare.ui \ - CProcessDialog.ui \ - CWaveListDialog.ui \ - CAlarmReport.ui - -LIBS += -llog4cplus \ - -lpub_logger_api \ - -ldb_base_api \ - -ldb_api_ex \ - -lboost_system \ - -lboost_thread \ - -ldb_sysinfo_api \ - -lpub_utility_api \ - -lmodel_excel \ - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2019-11-05T10:04:14 +# +#------------------------------------------------- + +QT += core gui charts sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = AlarmAnalyzeWidget +TEMPLATE = lib +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + CAlarmStatistics.cpp \ + CAlarmModel.cpp \ + CAlarmCompare.cpp \ + CProcessDialog.cpp \ + CCompareQueryThread.cpp \ + CommonFunction.cpp \ + CStatisticsQueryThread.cpp \ + CWaveListDialog.cpp \ + CAlarmStatisticsPluginWidget.cpp \ + CAlarmReport.cpp \ + CTableWidget.cpp + +HEADERS += \ + CAlarmStatistics.h \ + CAlarmModel.h \ + SAlarmInfo.h \ + SAlarmList.h \ + CAlarmLevelComboBox.h \ + SAlarmLevel.h \ + CAlarmCompare.h \ + CProcessDialog.h \ + CCompareQueryThread.h \ + CommonDefine.h \ + CommonFunction.h \ + CStatisticsQueryThread.h \ + SDeviceGroup.h \ + SLocation.h \ + CWaveListDialog.h \ + CAlarmStatisticsPluginWidget.h \ + CAlarmReport.h \ + CTableWidget.h + +FORMS += \ + CAlarmStatistics.ui \ + CAlarmCompare.ui \ + CProcessDialog.ui \ + CWaveListDialog.ui \ + CAlarmReport.ui + +LIBS += -llog4cplus \ + -lpub_logger_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lboost_system \ + -lboost_thread \ + -ldb_sysinfo_api \ + -lpub_utility_api \ + -lmodel_excel \ + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.cpp index 05f1d85d..d1740b2e 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.cpp @@ -1,574 +1,574 @@ -#include "CAlarmCompare.h" -#include "ui_CAlarmCompare.h" - -CAlarmCompare::CAlarmCompare(QWidget *parent) : - QWidget(parent), - ui(new Ui::CAlarmCompare), - m_pChart(Q_NULLPTR) -{ - ui->setupUi(this); - - initVariate(); - initUi(); - initBar(); - initLevelChoose(); -} - -CAlarmCompare::~CAlarmCompare() -{ - delete ui; - - delete m_pLabelValue; - m_pLabelValue = NULL; - - delete m_pAlarmLevelComboBox; - m_pAlarmLevelComboBox = NULL; - - delete m_pProcessDialog; - m_pProcessDialog = NULL; - - delete m_pQueryThread; - m_pQueryThread = NULL; - - qDeleteAll( m_listAlarmLevelCheckBox ); - m_listAlarmLevelCheckBox.clear(); -} - -void CAlarmCompare::setHiddenOptColumn(bool hide) -{ - if(m_pQueryThread) - { - m_pQueryThread->setHiddenOptColumn(hide); - } -} - -void CAlarmCompare::initVariate() -{ - m_pLabelValue = new QLabel(this); - m_pLabelValue->setObjectName( "value2" ); - m_pLabelValue->hide(); - m_bAfterMsgBox = false; - - m_pAlarmLevelComboBox = new CAlarmLevelComboBox( ui->comboBox_level ); - m_pProcessDialog = new CProcessDialog(); - m_pProcessDialog->hide(); - - m_pQueryThread = new CCompareQueryThread(); - - m_nCurrentLocationIndex = 0; -} - -void CAlarmCompare::initUi() -{ - this->setWindowTitle("告警比对"); - this->setWindowFlags( ( this->windowFlags() & ~Qt::WindowMinimizeButtonHint ) | Qt::WindowStaysOnTopHint | Qt::Dialog ); - - ui->splitter_2->setStretchFactor( 0, 3 ); - ui->splitter_2->setStretchFactor( 1, 7 ); - ui->splitter->setStretchFactor( 0, 5 ); - ui->splitter->setStretchFactor( 1, 5 ); - - ui->comboBox_level->setMinimumWidth( 120 ); - - ui->dateEdit_start->setDate( QDate::currentDate().addDays(-6) ); - ui->dateEdit_end->setDate( QDate::currentDate() ); - - ui->tableView_alarm->setModel( m_pQueryThread->m_pAlarmModel ); - ui->tableView_alarm->setColumnHidden( 4, true ); - ui->tableView_alarm->setObjectName( "alarm2" ); - ui->tableView_alarm->setEditTriggers( QAbstractItemView::NoEditTriggers ); - ui->tableView_alarm->setSelectionBehavior( QAbstractItemView::SelectRows ); - ui->tableView_alarm->setSelectionMode( QAbstractItemView::SingleSelection ); - - ui->rb_day->setChecked( true ); - - ui->toolBox->setMinimumWidth( 200 ); - - // 初始化左侧复选框(stackWidget 第0页) - QVBoxLayout *pFrmLayout = new QVBoxLayout(); - pFrmLayout->setMargin( 0 ); - pFrmLayout->setSpacing( 0 ); - for ( int i=0; im_listLocation.count(); i++ ) - { - SLocation* pLocation = m_pQueryThread->m_listLocation.at(i); - QCheckBox* pCheckBox = new QCheckBox(); - pCheckBox->setText( pLocation->sName ); - pCheckBox->setChecked( false ); - pCheckBox->setFixedHeight( 32 ); - pCheckBox->setProperty( "id", pLocation->nId ); - m_listCheckBoxLocation << pCheckBox; - QVBoxLayout *pLayout = new QVBoxLayout(); - pLayout->setMargin( 0 ); - pLayout->addWidget( pCheckBox ); - QFrame* pFrm = new QFrame(); - pFrm->setLayout( pLayout ); - pFrmLayout->addWidget( pFrm ); - } - QSpacerItem* pSpacerItem = new QSpacerItem(1,1,QSizePolicy::Minimum,QSizePolicy::Expanding ); - pFrmLayout->addSpacerItem( pSpacerItem ); - ui->frame_location->setLayout( pFrmLayout ); - - // 初始化左侧复选框(stackWidget 第1页) - for ( int i=0; im_listLocation.count(); i++ ) - { - SLocation* pLocation = m_pQueryThread->m_listLocation.at(i); - QVBoxLayout *pLayout = new QVBoxLayout(); - for ( int l=0; llistDeviceGroup.count(); l++ ) - { - SDeviceGroup* pDeviceGroup = pLocation->listDeviceGroup.at(l); - QCheckBox* pCheckBox = new QCheckBox(); - pCheckBox->setText( pDeviceGroup->sName ); - pCheckBox->setChecked( false ); - pCheckBox->setProperty( "id", pDeviceGroup->sTagName ); - m_listCheckBoxDeviceGroup << pCheckBox; - pLayout->addWidget( pCheckBox ); - // 最后一个时添加spacer - if ( l == pLocation->listDeviceGroup.count()-1 ) - { - //pLayout->addSpacerItem( new QSpacerItem(1,1,QSizePolicy::Minimum,QSizePolicy::Expanding) ); - pLayout->addStretch(); - } - } - QGroupBox *pGroupBox = new QGroupBox( ui->toolBox ); - pGroupBox->setLayout( pLayout ); - ui->toolBox->addItem( pGroupBox, pLocation->sName ); - } - // 删除原始第一页 - ui->toolBox->widget(0)->hide(); - ui->toolBox->removeItem( 0 ); - - m_pAlarmLevelComboBox->init( m_pQueryThread->m_listAlarmLevel ); - - connect( ui->pb_query, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonQueryClicked(bool)) ); - connect( m_pQueryThread, SIGNAL(signalQueryPercent(int)), m_pProcessDialog, SLOT(slotSetValue(int)) ); - connect( m_pQueryThread, SIGNAL(signalQueryEnd()), this, SLOT(slotQueryEnd()) ); - connect( m_pProcessDialog, SIGNAL(signalCancel()), m_pQueryThread, SLOT(slotCancel()) );; -} - -void CAlarmCompare::initBar() -{ - m_pChart = new QChart(); - m_pChart->setContentsMargins( 0,0,0,0 ); - m_pChart->setMargins(QMargins(0,0,0,0)); - m_pChart->setBackgroundRoundness( 0 ); - m_pChart->legend()->setVisible(false); - m_pChart->setBackgroundBrush( QBrush(QColor(3,22,36)) ); - - QChartView *pChartView = new QChartView( ui->frame_bar ); - pChartView->setChart( m_pChart ); - pChartView->setRenderHint(QPainter::Antialiasing); - pChartView->setMinimumHeight( 200 ); - QLayout* pLayout = ui->frame_bar->layout(); - pLayout->addWidget( pChartView ); - ui->frame_bar->setLayout( pLayout ); -} - -void CAlarmCompare::initLevelChoose() -{ - for ( int i=0; im_listAlarmLevel.count(); i++ ) - { - SAlarmLevel* pAlarmLevel = m_pQueryThread->m_listAlarmLevel.at(i); - QCheckBox* pCheckBox = new QCheckBox( pAlarmLevel->sName ); - pCheckBox->setObjectName( QString("checkBox_level%1").arg(pAlarmLevel->nPriority) ); - pCheckBox->setProperty( "id", pAlarmLevel->nId ); - pCheckBox->setChecked( true ); - ui->horizontalLayout_2->addWidget( pCheckBox ); - if ( i < m_pQueryThread->m_listAlarmLevelColor.count() ) - { - QColor tmpColor = m_pQueryThread->m_listAlarmLevelColor.at(i); - pCheckBox->setStyleSheet( QString("QCheckBox::indicator:checked{background-color: rgb(%1,%2,%3);}") - .arg(tmpColor.red()).arg(tmpColor.green()).arg(tmpColor.blue()) ); - } - m_listAlarmLevelCheckBox.append( pCheckBox ); - connect( pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxStateChanged(int)) ); - } -} - -void CAlarmCompare::resetUi() -{ - // 清空柱状图 - m_pChart->removeAllSeries(); - - // 清空查询线程 - m_pQueryThread->clear(); -} - -void CAlarmCompare::setCurrentLocationIndex( int nIndex ) -{ - m_nCurrentLocationIndex = nIndex; - if ( m_nCurrentLocationIndex == 0 ) - ui->stackedWidget->setCurrentIndex( 0 ); - else - ui->stackedWidget->setCurrentIndex( 1 ); -} - -QColor CAlarmCompare::chartBackground() -{ - return m_chartBackground; -} - -void CAlarmCompare::setChartBackground(const QColor& color) -{ - m_chartBackground = color; - - if(m_pChart != Q_NULLPTR) - { - m_pChart->setBackgroundBrush( QBrush(m_chartBackground) ); - } -} - -QColor CAlarmCompare::chartLabelColor() -{ - return m_chartLabelColor; -} - -void CAlarmCompare::setChartLabelColor(const QColor &color) -{ - m_chartLabelColor = color; - - if(m_pChart == Q_NULLPTR) - { - return; - } - if(m_pChart->axisX()) - { - m_pChart->axisX()->setLabelsBrush( QBrush(m_chartLabelColor)); - } - if(m_pChart->axisY()) - { - m_pChart->axisY()->setLabelsBrush( QBrush(m_chartLabelColor)); - } -} - -QColor CAlarmCompare::chartLineColor() -{ - return m_chartLineColor; -} - -void CAlarmCompare::setChartLineColor(const QColor &color) -{ - m_chartLineColor = color; - - if(m_pChart == Q_NULLPTR) - { - return; - } - if(m_pChart->axisX()) - { - m_pChart->axisX()->setLinePenColor( m_chartLineColor); - } - if(m_pChart->axisY()) - { - m_pChart->axisY()->setLinePenColor( m_chartLineColor); - } -} - -void CAlarmCompare::showBar() -{ - // 清空柱状图 - m_pChart->removeAllSeries(); - - // 清空barset列表 - m_listBarSet.clear(); - - // 没有设备或者没有数据是返回 - if ( m_pQueryThread->m_listAlarm.count() <= 0 || m_pQueryThread->m_listAlarm[0].count() <= 0 ) - return; - - QBarCategoryAxis *pAxis = new QBarCategoryAxis(); - for ( int m=0; mm_listAlarm.count(); m++ ) - { - QList tmpListBarSet; - QList tmpListAlarm = m_pQueryThread->m_listAlarm.at(m); - QStackedBarSeries* pBarSeries = new QStackedBarSeries(); - connect( pBarSeries, SIGNAL(hovered(bool,int,QBarSet*)), this, SLOT(slotBarMouseMoveHovered(bool,int,QBarSet*)) ); - connect( pBarSeries, SIGNAL(clicked(int,QBarSet*)), this, SLOT(slotBarClicked(int,QBarSet*)) ); - - for ( int i=0; im_listAlarmLevel.count(); i++ ) - { - QBarSet *pSet0 = new QBarSet(QString("%1_%2").arg(m).arg(i+1)); - tmpListBarSet.append( pSet0 ); - pBarSeries->append( pSet0 ); - } - - for ( int i=0; iappend( pAlarmList->sName ); - - for ( int l=0; llistLevelCount.count(); l++ ) - { - if ( m_listAlarmLevelCheckBox.at(l)->isChecked() ) - *tmpListBarSet[l] << pAlarmList->listLevelCount.at(l); - else - *tmpListBarSet[l] << 0; - } - } - m_pChart->addSeries( pBarSeries ); - m_listBarSet << tmpListBarSet; - } - - m_pChart->createDefaultAxes(); - m_pChart->setAxisX( pAxis ); - if ( m_pChart->axisX() ) - { - m_pChart->axisX()->setLabelsBrush( QBrush(m_chartLabelColor)); - m_pChart->axisX()->setLinePenColor( m_chartLineColor); - m_pChart->axisX()->setGridLineVisible( false ); - } - if ( m_pChart->axisY() ) - { - m_pChart->axisY()->setLabelsBrush( QBrush(m_chartLabelColor)); - m_pChart->axisY()->setLinePenColor( m_chartLineColor); - m_pChart->axisY()->setGridLineVisible( false ); - } - - QList listSeries = m_pChart->series(); - for ( int i=0; i(listSeries.at(i)); - if ( pBarSeries == NULL ) - continue; - QList listBar = pBarSeries->barSets(); - for ( int l=0; lsetBrush( QBrush(m_pQueryThread->m_listAlarmLevelColor.at(l)) ); - } -} - -void CAlarmCompare::slotPushButtonQueryClicked( bool ) -{ - // 清空界面 - resetUi(); - - // 清空线程 - m_pQueryThread->clear(); - - // 获取告警级别选择的字符串 - QList listLevelId; - m_pAlarmLevelComboBox->getSelectData( listLevelId ); - if ( listLevelId.count() <= 0 ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("未选择告警等级") ); - return; - } - for ( int i=0; im_sSelectedLevel = m_pQueryThread->m_sSelectedLevel + QString::number(listLevelId.at(i)) + ","; - m_pQueryThread->m_sSelectedLevel = m_pQueryThread->m_sSelectedLevel.left( m_pQueryThread->m_sSelectedLevel.count()-1 ); - - // 开始时间结束时间 - QDate dataStart = ui->dateEdit_start->date(); - QDate dataEnd = ui->dateEdit_end->date(); - if ( dataStart > dataEnd ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("开始时间需小于等于结束时间") ); - return; - } - else if ( ui->rb_day->isChecked() ) - { - if ( dataStart.addDays(7-1) < dataEnd ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("当前类型最多七天") ); - return; - } - else - m_pQueryThread->m_eDateType = CCompareQueryThread::EN_DateType_Day; - } - else if ( ui->rb_month->isChecked() ) - { - QDate tmpDate = dataStart.addMonths(6-1); - if ( tmpDate < dataEnd ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("当前类型最多六个月") ); - return; - } - else - m_pQueryThread->m_eDateType = CCompareQueryThread::EN_DateType_Month; - } - else - { - return; - } - m_pQueryThread->m_nStartMs = ui->dateEdit_start->dateTime().toMSecsSinceEpoch(); - m_pQueryThread->m_nEndMs = ui->dateEdit_end->dateTime().addDays(1).toMSecsSinceEpoch(); - - // 当前站 - m_pQueryThread->m_nCurrentLocationIndex = m_nCurrentLocationIndex; - - // 置复选框 - if ( m_nCurrentLocationIndex == 0 ) - { - for ( int i=0; iisChecked() ) - m_pQueryThread->m_listCheckBox << m_listCheckBoxLocation.at(i); - } - if ( m_pQueryThread->m_listCheckBox.count() == 0 ) - { - showMsg( QMessageBox::Warning,tr("警告"), tr("请选择位置")); - return; - } - else if ( m_pQueryThread->m_listCheckBox.count() < 2 ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("位置最少选择2个") ); - return; - } - else if ( m_pQueryThread->m_listCheckBox.count() > CN_MAXBARCOUNT ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("位置最多选择%1个").arg(CN_MAXBARCOUNT) ); - return; - } - } - else - { - for ( int i=0; iisChecked() ) - m_pQueryThread->m_listCheckBox << m_listCheckBoxDeviceGroup.at(i); - } - if ( m_pQueryThread->m_listCheckBox.count() == 0 ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("请选择设备组") ); - return; - } - else if ( m_pQueryThread->m_listCheckBox.count() < 2 ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("位置最少选择2个") ); - return; - } - else if ( m_pQueryThread->m_listCheckBox.count() > CN_MAXBARCOUNT ) - { - showMsg( QMessageBox::Warning, tr("警告"), tr("设备组最多选择%1个").arg(CN_MAXBARCOUNT) ); - return; - } - } - - // 查询关键字 - m_pQueryThread->m_sKeyWord = ui->lineEdit_keyWord->text(); - - // 开始在线程中查询 - m_pProcessDialog->reset(); - m_pProcessDialog->show(); - this->setCursor(Qt::WaitCursor); - m_pQueryThread->start(); -} - -void CAlarmCompare::slotQueryEnd() -{ - // 显示柱状图 - showBar(); - - // 隐藏进度条,恢复鼠标形状 - m_pProcessDialog->hide(); - this->setCursor(Qt::ArrowCursor); - - // 显示告警详细信息 - if ( m_listBarSet.count() > 0 && m_listBarSet.at(0).count() > 0 ) - slotBarClicked( 0, m_listBarSet.at(0).at(0) ); -} - -void CAlarmCompare::slotCheckBoxStateChanged( int ) -{ - showBar(); -} - -void CAlarmCompare::slotBarMouseMoveHovered( bool bStatus, int nIndex, QBarSet* pBarset ) -{ - if ( m_bAfterMsgBox ) - { - m_bAfterMsgBox = false; - return; - } - - if ( !bStatus ) - { - m_pLabelValue->hide();//进行隐藏 - return; - } - - int nDeviceIndex = pBarset->label().split("_").at(0).toInt(); - if ( nDeviceIndex < 0 ) - return; - - QString sShow = m_pQueryThread->m_listCheckBox.at(nDeviceIndex)->text() + "\n"; - for ( int i=0; im_listAlarmLevel.count(); i++ ) - { - sShow = sShow + m_pQueryThread->m_listAlarmLevel.at(i)->sName + " : " + - QString::number(m_listBarSet.at(nDeviceIndex).at(i)->at(nIndex)); - if ( i != m_pQueryThread->m_listAlarmLevel.count() - 1 ) - sShow += "\n"; - } - - m_pLabelValue->setText( sShow ); - QPoint curPos = mapFromGlobal( QCursor::pos() ); - m_pLabelValue->move( curPos.x()-100, curPos.y()+10 );//移动数值 - m_pLabelValue->show();//显示出来 - m_pLabelValue->adjustSize(); -} - -void CAlarmCompare::slotBarClicked( int nIndex, QBarSet* pBarset ) -{ - m_pQueryThread->m_pAlarmModel->beginReset(); - m_pQueryThread->m_pAlarmModel->clearAlarmList(); - m_pQueryThread->m_pAlarmModel->endReset(); - - int nDeviceIndex = pBarset->label().split("_").at(0).toInt(); - if ( nDeviceIndex < 0 ) - return; - - m_pQueryThread->m_pAlarmModel->beginReset(); - m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarm.at(nDeviceIndex).at(nIndex)->listAlarmInfo ); - m_pQueryThread->m_pAlarmModel->endReset(); - resizeColumnsToContents( ui->tableView_alarm ); - ui->label_name->setText( m_pQueryThread->m_listCheckBox.at(nDeviceIndex)->text() + " " + - m_pQueryThread->m_listAlarm.at(nDeviceIndex).at(nIndex)->sName ); - - if ( m_pQueryThread->m_listAlarm.at(nDeviceIndex).at(nIndex)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - { - m_pLabelValue->hide(); - showMsg( QMessageBox::Information, tr("提示"), QString(tr("告警条数过多,仅显示前 %1 条")).arg(CN_ALARMINFO_MAXROW) ); - m_bAfterMsgBox = true; - } -} - -void CAlarmCompare::resizeEvent( QResizeEvent* ) -{ - resizeColumnsToContents( ui->tableView_alarm ); -} - -void CAlarmCompare::paintEvent(QPaintEvent *pEvent) -{ - //< 用于qss设置背景图片 - Q_UNUSED(pEvent) - - QStyleOption op; - op.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &op, &p, this); -} - - - - - - - - - - - - - - - - - - - - - - - - - - +#include "CAlarmCompare.h" +#include "ui_CAlarmCompare.h" + +CAlarmCompare::CAlarmCompare(QWidget *parent) : + QWidget(parent), + ui(new Ui::CAlarmCompare), + m_pChart(Q_NULLPTR) +{ + ui->setupUi(this); + + initVariate(); + initUi(); + initBar(); + initLevelChoose(); +} + +CAlarmCompare::~CAlarmCompare() +{ + delete ui; + + delete m_pLabelValue; + m_pLabelValue = NULL; + + delete m_pAlarmLevelComboBox; + m_pAlarmLevelComboBox = NULL; + + delete m_pProcessDialog; + m_pProcessDialog = NULL; + + delete m_pQueryThread; + m_pQueryThread = NULL; + + qDeleteAll( m_listAlarmLevelCheckBox ); + m_listAlarmLevelCheckBox.clear(); +} + +void CAlarmCompare::setHiddenOptColumn(bool hide) +{ + if(m_pQueryThread) + { + m_pQueryThread->setHiddenOptColumn(hide); + } +} + +void CAlarmCompare::initVariate() +{ + m_pLabelValue = new QLabel(this); + m_pLabelValue->setObjectName( "value2" ); + m_pLabelValue->hide(); + m_bAfterMsgBox = false; + + m_pAlarmLevelComboBox = new CAlarmLevelComboBox( ui->comboBox_level ); + m_pProcessDialog = new CProcessDialog(); + m_pProcessDialog->hide(); + + m_pQueryThread = new CCompareQueryThread(); + + m_nCurrentLocationIndex = 0; +} + +void CAlarmCompare::initUi() +{ + this->setWindowTitle("告警比对"); + this->setWindowFlags( ( this->windowFlags() & ~Qt::WindowMinimizeButtonHint ) | Qt::WindowStaysOnTopHint | Qt::Dialog ); + + ui->splitter_2->setStretchFactor( 0, 3 ); + ui->splitter_2->setStretchFactor( 1, 7 ); + ui->splitter->setStretchFactor( 0, 5 ); + ui->splitter->setStretchFactor( 1, 5 ); + + ui->comboBox_level->setMinimumWidth( 120 ); + + ui->dateEdit_start->setDate( QDate::currentDate().addDays(-6) ); + ui->dateEdit_end->setDate( QDate::currentDate() ); + + ui->tableView_alarm->setModel( m_pQueryThread->m_pAlarmModel ); + ui->tableView_alarm->setColumnHidden( 4, true ); + ui->tableView_alarm->setObjectName( "alarm2" ); + ui->tableView_alarm->setEditTriggers( QAbstractItemView::NoEditTriggers ); + ui->tableView_alarm->setSelectionBehavior( QAbstractItemView::SelectRows ); + ui->tableView_alarm->setSelectionMode( QAbstractItemView::SingleSelection ); + + ui->rb_day->setChecked( true ); + + ui->toolBox->setMinimumWidth( 200 ); + + // 初始化左侧复选框(stackWidget 第0页) + QVBoxLayout *pFrmLayout = new QVBoxLayout(); + pFrmLayout->setMargin( 0 ); + pFrmLayout->setSpacing( 0 ); + for ( int i=0; im_listLocation.count(); i++ ) + { + SLocation* pLocation = m_pQueryThread->m_listLocation.at(i); + QCheckBox* pCheckBox = new QCheckBox(); + pCheckBox->setText( pLocation->sName ); + pCheckBox->setChecked( false ); + pCheckBox->setFixedHeight( 32 ); + pCheckBox->setProperty( "id", pLocation->nId ); + m_listCheckBoxLocation << pCheckBox; + QVBoxLayout *pLayout = new QVBoxLayout(); + pLayout->setMargin( 0 ); + pLayout->addWidget( pCheckBox ); + QFrame* pFrm = new QFrame(); + pFrm->setLayout( pLayout ); + pFrmLayout->addWidget( pFrm ); + } + QSpacerItem* pSpacerItem = new QSpacerItem(1,1,QSizePolicy::Minimum,QSizePolicy::Expanding ); + pFrmLayout->addSpacerItem( pSpacerItem ); + ui->frame_location->setLayout( pFrmLayout ); + + // 初始化左侧复选框(stackWidget 第1页) + for ( int i=0; im_listLocation.count(); i++ ) + { + SLocation* pLocation = m_pQueryThread->m_listLocation.at(i); + QVBoxLayout *pLayout = new QVBoxLayout(); + for ( int l=0; llistDeviceGroup.count(); l++ ) + { + SDeviceGroup* pDeviceGroup = pLocation->listDeviceGroup.at(l); + QCheckBox* pCheckBox = new QCheckBox(); + pCheckBox->setText( pDeviceGroup->sName ); + pCheckBox->setChecked( false ); + pCheckBox->setProperty( "id", pDeviceGroup->sTagName ); + m_listCheckBoxDeviceGroup << pCheckBox; + pLayout->addWidget( pCheckBox ); + // 最后一个时添加spacer + if ( l == pLocation->listDeviceGroup.count()-1 ) + { + //pLayout->addSpacerItem( new QSpacerItem(1,1,QSizePolicy::Minimum,QSizePolicy::Expanding) ); + pLayout->addStretch(); + } + } + QGroupBox *pGroupBox = new QGroupBox( ui->toolBox ); + pGroupBox->setLayout( pLayout ); + ui->toolBox->addItem( pGroupBox, pLocation->sName ); + } + // 删除原始第一页 + ui->toolBox->widget(0)->hide(); + ui->toolBox->removeItem( 0 ); + + m_pAlarmLevelComboBox->init( m_pQueryThread->m_listAlarmLevel ); + + connect( ui->pb_query, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonQueryClicked(bool)) ); + connect( m_pQueryThread, SIGNAL(signalQueryPercent(int)), m_pProcessDialog, SLOT(slotSetValue(int)) ); + connect( m_pQueryThread, SIGNAL(signalQueryEnd()), this, SLOT(slotQueryEnd()) ); + connect( m_pProcessDialog, SIGNAL(signalCancel()), m_pQueryThread, SLOT(slotCancel()) );; +} + +void CAlarmCompare::initBar() +{ + m_pChart = new QChart(); + m_pChart->setContentsMargins( 0,0,0,0 ); + m_pChart->setMargins(QMargins(0,0,0,0)); + m_pChart->setBackgroundRoundness( 0 ); + m_pChart->legend()->setVisible(false); + m_pChart->setBackgroundBrush( QBrush(QColor(3,22,36)) ); + + QChartView *pChartView = new QChartView( ui->frame_bar ); + pChartView->setChart( m_pChart ); + pChartView->setRenderHint(QPainter::Antialiasing); + pChartView->setMinimumHeight( 200 ); + QLayout* pLayout = ui->frame_bar->layout(); + pLayout->addWidget( pChartView ); + ui->frame_bar->setLayout( pLayout ); +} + +void CAlarmCompare::initLevelChoose() +{ + for ( int i=0; im_listAlarmLevel.count(); i++ ) + { + SAlarmLevel* pAlarmLevel = m_pQueryThread->m_listAlarmLevel.at(i); + QCheckBox* pCheckBox = new QCheckBox( pAlarmLevel->sName ); + pCheckBox->setObjectName( QString("checkBox_level%1").arg(pAlarmLevel->nPriority) ); + pCheckBox->setProperty( "id", pAlarmLevel->nId ); + pCheckBox->setChecked( true ); + ui->horizontalLayout_2->addWidget( pCheckBox ); + if ( i < m_pQueryThread->m_listAlarmLevelColor.count() ) + { + QColor tmpColor = m_pQueryThread->m_listAlarmLevelColor.at(i); + pCheckBox->setStyleSheet( QString("QCheckBox::indicator:checked{background-color: rgb(%1,%2,%3);}") + .arg(tmpColor.red()).arg(tmpColor.green()).arg(tmpColor.blue()) ); + } + m_listAlarmLevelCheckBox.append( pCheckBox ); + connect( pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxStateChanged(int)) ); + } +} + +void CAlarmCompare::resetUi() +{ + // 清空柱状图 + m_pChart->removeAllSeries(); + + // 清空查询线程 + m_pQueryThread->clear(); +} + +void CAlarmCompare::setCurrentLocationIndex( int nIndex ) +{ + m_nCurrentLocationIndex = nIndex; + if ( m_nCurrentLocationIndex == 0 ) + ui->stackedWidget->setCurrentIndex( 0 ); + else + ui->stackedWidget->setCurrentIndex( 1 ); +} + +QColor CAlarmCompare::chartBackground() +{ + return m_chartBackground; +} + +void CAlarmCompare::setChartBackground(const QColor& color) +{ + m_chartBackground = color; + + if(m_pChart != Q_NULLPTR) + { + m_pChart->setBackgroundBrush( QBrush(m_chartBackground) ); + } +} + +QColor CAlarmCompare::chartLabelColor() +{ + return m_chartLabelColor; +} + +void CAlarmCompare::setChartLabelColor(const QColor &color) +{ + m_chartLabelColor = color; + + if(m_pChart == Q_NULLPTR) + { + return; + } + if(m_pChart->axisX()) + { + m_pChart->axisX()->setLabelsBrush( QBrush(m_chartLabelColor)); + } + if(m_pChart->axisY()) + { + m_pChart->axisY()->setLabelsBrush( QBrush(m_chartLabelColor)); + } +} + +QColor CAlarmCompare::chartLineColor() +{ + return m_chartLineColor; +} + +void CAlarmCompare::setChartLineColor(const QColor &color) +{ + m_chartLineColor = color; + + if(m_pChart == Q_NULLPTR) + { + return; + } + if(m_pChart->axisX()) + { + m_pChart->axisX()->setLinePenColor( m_chartLineColor); + } + if(m_pChart->axisY()) + { + m_pChart->axisY()->setLinePenColor( m_chartLineColor); + } +} + +void CAlarmCompare::showBar() +{ + // 清空柱状图 + m_pChart->removeAllSeries(); + + // 清空barset列表 + m_listBarSet.clear(); + + // 没有设备或者没有数据是返回 + if ( m_pQueryThread->m_listAlarm.count() <= 0 || m_pQueryThread->m_listAlarm[0].count() <= 0 ) + return; + + QBarCategoryAxis *pAxis = new QBarCategoryAxis(); + for ( int m=0; mm_listAlarm.count(); m++ ) + { + QList tmpListBarSet; + QList tmpListAlarm = m_pQueryThread->m_listAlarm.at(m); + QStackedBarSeries* pBarSeries = new QStackedBarSeries(); + connect( pBarSeries, SIGNAL(hovered(bool,int,QBarSet*)), this, SLOT(slotBarMouseMoveHovered(bool,int,QBarSet*)) ); + connect( pBarSeries, SIGNAL(clicked(int,QBarSet*)), this, SLOT(slotBarClicked(int,QBarSet*)) ); + + for ( int i=0; im_listAlarmLevel.count(); i++ ) + { + QBarSet *pSet0 = new QBarSet(QString("%1_%2").arg(m).arg(i+1)); + tmpListBarSet.append( pSet0 ); + pBarSeries->append( pSet0 ); + } + + for ( int i=0; iappend( pAlarmList->sName ); + + for ( int l=0; llistLevelCount.count(); l++ ) + { + if ( m_listAlarmLevelCheckBox.at(l)->isChecked() ) + *tmpListBarSet[l] << pAlarmList->listLevelCount.at(l); + else + *tmpListBarSet[l] << 0; + } + } + m_pChart->addSeries( pBarSeries ); + m_listBarSet << tmpListBarSet; + } + + m_pChart->createDefaultAxes(); + m_pChart->setAxisX( pAxis ); + if ( m_pChart->axisX() ) + { + m_pChart->axisX()->setLabelsBrush( QBrush(m_chartLabelColor)); + m_pChart->axisX()->setLinePenColor( m_chartLineColor); + m_pChart->axisX()->setGridLineVisible( false ); + } + if ( m_pChart->axisY() ) + { + m_pChart->axisY()->setLabelsBrush( QBrush(m_chartLabelColor)); + m_pChart->axisY()->setLinePenColor( m_chartLineColor); + m_pChart->axisY()->setGridLineVisible( false ); + } + + QList listSeries = m_pChart->series(); + for ( int i=0; i(listSeries.at(i)); + if ( pBarSeries == NULL ) + continue; + QList listBar = pBarSeries->barSets(); + for ( int l=0; lsetBrush( QBrush(m_pQueryThread->m_listAlarmLevelColor.at(l)) ); + } +} + +void CAlarmCompare::slotPushButtonQueryClicked( bool ) +{ + // 清空界面 + resetUi(); + + // 清空线程 + m_pQueryThread->clear(); + + // 获取告警级别选择的字符串 + QList listLevelId; + m_pAlarmLevelComboBox->getSelectData( listLevelId ); + if ( listLevelId.count() <= 0 ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("未选择告警等级") ); + return; + } + for ( int i=0; im_sSelectedLevel = m_pQueryThread->m_sSelectedLevel + QString::number(listLevelId.at(i)) + ","; + m_pQueryThread->m_sSelectedLevel = m_pQueryThread->m_sSelectedLevel.left( m_pQueryThread->m_sSelectedLevel.count()-1 ); + + // 开始时间结束时间 + QDate dataStart = ui->dateEdit_start->date(); + QDate dataEnd = ui->dateEdit_end->date(); + if ( dataStart > dataEnd ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("开始时间需小于等于结束时间") ); + return; + } + else if ( ui->rb_day->isChecked() ) + { + if ( dataStart.addDays(7-1) < dataEnd ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("当前类型最多七天") ); + return; + } + else + m_pQueryThread->m_eDateType = CCompareQueryThread::EN_DateType_Day; + } + else if ( ui->rb_month->isChecked() ) + { + QDate tmpDate = dataStart.addMonths(6-1); + if ( tmpDate < dataEnd ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("当前类型最多六个月") ); + return; + } + else + m_pQueryThread->m_eDateType = CCompareQueryThread::EN_DateType_Month; + } + else + { + return; + } + m_pQueryThread->m_nStartMs = ui->dateEdit_start->dateTime().toMSecsSinceEpoch(); + m_pQueryThread->m_nEndMs = ui->dateEdit_end->dateTime().addDays(1).toMSecsSinceEpoch(); + + // 当前站 + m_pQueryThread->m_nCurrentLocationIndex = m_nCurrentLocationIndex; + + // 置复选框 + if ( m_nCurrentLocationIndex == 0 ) + { + for ( int i=0; iisChecked() ) + m_pQueryThread->m_listCheckBox << m_listCheckBoxLocation.at(i); + } + if ( m_pQueryThread->m_listCheckBox.count() == 0 ) + { + showMsg( QMessageBox::Warning,tr("警告"), tr("请选择位置")); + return; + } + else if ( m_pQueryThread->m_listCheckBox.count() < 2 ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("位置最少选择2个") ); + return; + } + else if ( m_pQueryThread->m_listCheckBox.count() > CN_MAXBARCOUNT ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("位置最多选择%1个").arg(CN_MAXBARCOUNT) ); + return; + } + } + else + { + for ( int i=0; iisChecked() ) + m_pQueryThread->m_listCheckBox << m_listCheckBoxDeviceGroup.at(i); + } + if ( m_pQueryThread->m_listCheckBox.count() == 0 ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("请选择设备组") ); + return; + } + else if ( m_pQueryThread->m_listCheckBox.count() < 2 ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("位置最少选择2个") ); + return; + } + else if ( m_pQueryThread->m_listCheckBox.count() > CN_MAXBARCOUNT ) + { + showMsg( QMessageBox::Warning, tr("警告"), tr("设备组最多选择%1个").arg(CN_MAXBARCOUNT) ); + return; + } + } + + // 查询关键字 + m_pQueryThread->m_sKeyWord = ui->lineEdit_keyWord->text(); + + // 开始在线程中查询 + m_pProcessDialog->reset(); + m_pProcessDialog->show(); + this->setCursor(Qt::WaitCursor); + m_pQueryThread->start(); +} + +void CAlarmCompare::slotQueryEnd() +{ + // 显示柱状图 + showBar(); + + // 隐藏进度条,恢复鼠标形状 + m_pProcessDialog->hide(); + this->setCursor(Qt::ArrowCursor); + + // 显示告警详细信息 + if ( m_listBarSet.count() > 0 && m_listBarSet.at(0).count() > 0 ) + slotBarClicked( 0, m_listBarSet.at(0).at(0) ); +} + +void CAlarmCompare::slotCheckBoxStateChanged( int ) +{ + showBar(); +} + +void CAlarmCompare::slotBarMouseMoveHovered( bool bStatus, int nIndex, QBarSet* pBarset ) +{ + if ( m_bAfterMsgBox ) + { + m_bAfterMsgBox = false; + return; + } + + if ( !bStatus ) + { + m_pLabelValue->hide();//进行隐藏 + return; + } + + int nDeviceIndex = pBarset->label().split("_").at(0).toInt(); + if ( nDeviceIndex < 0 ) + return; + + QString sShow = m_pQueryThread->m_listCheckBox.at(nDeviceIndex)->text() + "\n"; + for ( int i=0; im_listAlarmLevel.count(); i++ ) + { + sShow = sShow + m_pQueryThread->m_listAlarmLevel.at(i)->sName + " : " + + QString::number(m_listBarSet.at(nDeviceIndex).at(i)->at(nIndex)); + if ( i != m_pQueryThread->m_listAlarmLevel.count() - 1 ) + sShow += "\n"; + } + + m_pLabelValue->setText( sShow ); + QPoint curPos = mapFromGlobal( QCursor::pos() ); + m_pLabelValue->move( curPos.x()-100, curPos.y()+10 );//移动数值 + m_pLabelValue->show();//显示出来 + m_pLabelValue->adjustSize(); +} + +void CAlarmCompare::slotBarClicked( int nIndex, QBarSet* pBarset ) +{ + m_pQueryThread->m_pAlarmModel->beginReset(); + m_pQueryThread->m_pAlarmModel->clearAlarmList(); + m_pQueryThread->m_pAlarmModel->endReset(); + + int nDeviceIndex = pBarset->label().split("_").at(0).toInt(); + if ( nDeviceIndex < 0 ) + return; + + m_pQueryThread->m_pAlarmModel->beginReset(); + m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarm.at(nDeviceIndex).at(nIndex)->listAlarmInfo ); + m_pQueryThread->m_pAlarmModel->endReset(); + resizeColumnsToContents( ui->tableView_alarm ); + ui->label_name->setText( m_pQueryThread->m_listCheckBox.at(nDeviceIndex)->text() + " " + + m_pQueryThread->m_listAlarm.at(nDeviceIndex).at(nIndex)->sName ); + + if ( m_pQueryThread->m_listAlarm.at(nDeviceIndex).at(nIndex)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + { + m_pLabelValue->hide(); + showMsg( QMessageBox::Information, tr("提示"), QString(tr("告警条数过多,仅显示前 %1 条")).arg(CN_ALARMINFO_MAXROW) ); + m_bAfterMsgBox = true; + } +} + +void CAlarmCompare::resizeEvent( QResizeEvent* ) +{ + resizeColumnsToContents( ui->tableView_alarm ); +} + +void CAlarmCompare::paintEvent(QPaintEvent *pEvent) +{ + //< 用于qss设置背景图片 + Q_UNUSED(pEvent) + + QStyleOption op; + op.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &op, &p, this); +} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.h index 298560df..39f07438 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.h @@ -1,101 +1,101 @@ -#ifndef CALARMCOMPARE_H -#define CALARMCOMPARE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CAlarmModel.h" -#include "CAlarmLevelComboBox.h" -#include "SAlarmLevel.h" -#include "CProcessDialog.h" -#include "CCompareQueryThread.h" -#include "CommonDefine.h" -#include "CommonFunction.h" - -QT_CHARTS_USE_NAMESPACE - -namespace Ui { -class CAlarmCompare; -} - -class CAlarmCompare : public QWidget -{ - Q_OBJECT - Q_PROPERTY(QColor chartBackground READ chartBackground WRITE setChartBackground) - Q_PROPERTY(QColor chartLabelColor READ chartLabelColor WRITE setChartLabelColor) - Q_PROPERTY(QColor chartLineColor READ chartLineColor WRITE setChartLineColor) -public: - explicit CAlarmCompare(QWidget *parent = 0); - ~CAlarmCompare(); - - void setHiddenOptColumn(bool hide); -public: - void initVariate(); - void initUi(); - void initBar(); - void resetUi(); - void showBar(); - void initLevelChoose(); - void setCurrentLocationIndex( int nIndex ); - - QColor chartBackground(); - void setChartBackground(const QColor& color); - - QColor chartLabelColor(); - void setChartLabelColor(const QColor& color); - - QColor chartLineColor(); - void setChartLineColor(const QColor& color); - -public slots: - void slotQueryEnd(); - void slotCheckBoxStateChanged( int ); - void slotPushButtonQueryClicked( bool bChecked = false ); - void slotBarMouseMoveHovered( bool bStatus, int nIndex, QBarSet* pBarset ); - void slotBarClicked( int nIndex, QBarSet* pBarset ); - -protected: - void resizeEvent( QResizeEvent* pEvent ); - void paintEvent( QPaintEvent * pEvent); - -private: - Ui::CAlarmCompare *ui; - QChart *m_pChart;// 柱状图 - QLabel* m_pLabelValue;// 鼠标移动到柱状图上显示的提示窗口 - bool m_bAfterMsgBox;// 是否是在弹出告警条数过多之后第一次进入显示提示窗口的函数 - QList > m_listBarSet; - CAlarmLevelComboBox* m_pAlarmLevelComboBox;// 告警级别选择的下拉框 - QList m_listAlarmLevelCheckBox;// 柱状图告警等级选择的复选框集合 - CProcessDialog* m_pProcessDialog;// 等待窗口 - CCompareQueryThread* m_pQueryThread;// 查询线程 - int m_nCurrentLocationIndex;// 当前站序号,0表示全部站,其余表示第几个 - QList m_listCheckBoxLocation;// stackwidget page0 站列表 - QList m_listCheckBoxDeviceGroup;// stackwidget page1 设备组列表 - - QColor m_chartBackground; - QColor m_chartLabelColor; - QColor m_chartLineColor; -}; - -#endif // CALARMCOMPARE_H +#ifndef CALARMCOMPARE_H +#define CALARMCOMPARE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmModel.h" +#include "CAlarmLevelComboBox.h" +#include "SAlarmLevel.h" +#include "CProcessDialog.h" +#include "CCompareQueryThread.h" +#include "CommonDefine.h" +#include "CommonFunction.h" + +QT_CHARTS_USE_NAMESPACE + +namespace Ui { +class CAlarmCompare; +} + +class CAlarmCompare : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor chartBackground READ chartBackground WRITE setChartBackground) + Q_PROPERTY(QColor chartLabelColor READ chartLabelColor WRITE setChartLabelColor) + Q_PROPERTY(QColor chartLineColor READ chartLineColor WRITE setChartLineColor) +public: + explicit CAlarmCompare(QWidget *parent = 0); + ~CAlarmCompare(); + + void setHiddenOptColumn(bool hide); +public: + void initVariate(); + void initUi(); + void initBar(); + void resetUi(); + void showBar(); + void initLevelChoose(); + void setCurrentLocationIndex( int nIndex ); + + QColor chartBackground(); + void setChartBackground(const QColor& color); + + QColor chartLabelColor(); + void setChartLabelColor(const QColor& color); + + QColor chartLineColor(); + void setChartLineColor(const QColor& color); + +public slots: + void slotQueryEnd(); + void slotCheckBoxStateChanged( int ); + void slotPushButtonQueryClicked( bool bChecked = false ); + void slotBarMouseMoveHovered( bool bStatus, int nIndex, QBarSet* pBarset ); + void slotBarClicked( int nIndex, QBarSet* pBarset ); + +protected: + void resizeEvent( QResizeEvent* pEvent ); + void paintEvent( QPaintEvent * pEvent); + +private: + Ui::CAlarmCompare *ui; + QChart *m_pChart;// 柱状图 + QLabel* m_pLabelValue;// 鼠标移动到柱状图上显示的提示窗口 + bool m_bAfterMsgBox;// 是否是在弹出告警条数过多之后第一次进入显示提示窗口的函数 + QList > m_listBarSet; + CAlarmLevelComboBox* m_pAlarmLevelComboBox;// 告警级别选择的下拉框 + QList m_listAlarmLevelCheckBox;// 柱状图告警等级选择的复选框集合 + CProcessDialog* m_pProcessDialog;// 等待窗口 + CCompareQueryThread* m_pQueryThread;// 查询线程 + int m_nCurrentLocationIndex;// 当前站序号,0表示全部站,其余表示第几个 + QList m_listCheckBoxLocation;// stackwidget page0 站列表 + QList m_listCheckBoxDeviceGroup;// stackwidget page1 设备组列表 + + QColor m_chartBackground; + QColor m_chartLabelColor; + QColor m_chartLineColor; +}; + +#endif // CALARMCOMPARE_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.ui b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.ui index 65178aa8..f774aec6 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.ui +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmCompare.ui @@ -1,450 +1,450 @@ - - - CAlarmCompare - - - - 0 - 0 - 1080 - 654 - - - - Form - - - - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 0 - 24 - - - - 告警等级 - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - 统计类型 - - - - - - - - - - buttonGroup - - - - - - - - - - buttonGroup - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - 时间段 - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - yyyy-MM-dd - - - true - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - yyyy-MM-dd - - - true - - - - - - - - 0 - 24 - - - - - - - - - - 告警内容关键字 - - - - - - - 查询 - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - Qt::Horizontal - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - - 0 - 0 - 98 - 28 - - - - - - - - - - - - - - Qt::Vertical - - - - QFrame::Box - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 4 - - - 9 - - - 9 - - - 9 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - 0 - 24 - - - - - - - - - - - Qt::Horizontal - - - - 40 - 24 - - - - - - - - - - 11 - - - 22 - - - 33 - - - - - - - - - - - - - - - CTableView - QTableView -
CTableWidget.h
-
-
- - - - - -
+ + + CAlarmCompare + + + + 0 + 0 + 1080 + 654 + + + + Form + + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 告警等级 + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 统计类型 + + + + + + + + + + buttonGroup + + + + + + + + + + buttonGroup + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 时间段 + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + yyyy-MM-dd + + + true + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + - + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + yyyy-MM-dd + + + true + + + + + + + + 0 + 24 + + + + + + + + + + 告警内容关键字 + + + + + + + 查询 + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + Qt::Vertical + + + + QFrame::Box + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 4 + + + 9 + + + 9 + + + 9 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + 24 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 24 + + + + + + + + + + 11 + + + 22 + + + 33 + + + + + + + + + + + + + + + CTableView + QTableView +
CTableWidget.h
+
+
+ + + + + +
diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmLevelComboBox.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmLevelComboBox.h index e61ee1da..a29111d1 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmLevelComboBox.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmLevelComboBox.h @@ -1,80 +1,80 @@ -#ifndef CALARMLEVELCOMBOBOX_H -#define CALARMLEVELCOMBOBOX_H - -#include -#include -#include -#include -#include -#include -#include -#include "SAlarmLevel.h" - -class CAlarmLevelComboBox : public QListWidget -{ - Q_OBJECT - -public: - CAlarmLevelComboBox( QComboBox* pComboBox ) - { - setViewMode( QListWidget::ListMode ); - setSelectionMode( QAbstractItemView::SingleSelection ); - QLineEdit *pLineEdit = new QLineEdit; - pLineEdit->setReadOnly( true ); - m_pCombobox = pComboBox; - m_pCombobox->setLineEdit( pLineEdit ); - m_pCombobox->setModel( model() ); - m_pCombobox->setView( this ); - m_pCombobox->setEditable( true ); - } - -public: - void init( QList listAlarmLevel ) - { - for ( int i=0; inId ); - QListWidgetItem *item = new QListWidgetItem(); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |Qt::ItemIsEnabled); - insertItem( model()->rowCount(), item ); - QCheckBox* pCheckBox = new QCheckBox( listAlarmLevel.at(i)->sName ); - setItemWidget( item, pCheckBox ); - m_listCheckBox.append( pCheckBox ); - pCheckBox->setChecked( false ); - connect( pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setSelectItem(int)) ); - pCheckBox->setChecked( true ); - } - connect( m_pCombobox, SIGNAL(activated(int)), this, SLOT(setSelectItem(int)) ); - } - void getSelectData( QList& data ) - { - for( int i=0; iisChecked() ) - data.append( m_listData.at(i) ); - } - } - -private slots: - //QCheckBox复选消息处理 - void setSelectItem( int ) - { - QString sName; - for( int i=0; iisChecked() ) - { - sName += m_listCheckBox.at(i)->text(); - sName += ","; - } - } - m_pCombobox->setEditText( sName ); - } - -private: - QComboBox* m_pCombobox; - QList m_listCheckBox; - QList m_listData; -}; - -#endif // CALARMLEVELCOMBOBOX_H +#ifndef CALARMLEVELCOMBOBOX_H +#define CALARMLEVELCOMBOBOX_H + +#include +#include +#include +#include +#include +#include +#include +#include "SAlarmLevel.h" + +class CAlarmLevelComboBox : public QListWidget +{ + Q_OBJECT + +public: + CAlarmLevelComboBox( QComboBox* pComboBox ) + { + setViewMode( QListWidget::ListMode ); + setSelectionMode( QAbstractItemView::SingleSelection ); + QLineEdit *pLineEdit = new QLineEdit; + pLineEdit->setReadOnly( true ); + m_pCombobox = pComboBox; + m_pCombobox->setLineEdit( pLineEdit ); + m_pCombobox->setModel( model() ); + m_pCombobox->setView( this ); + m_pCombobox->setEditable( true ); + } + +public: + void init( QList listAlarmLevel ) + { + for ( int i=0; inId ); + QListWidgetItem *item = new QListWidgetItem(); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |Qt::ItemIsEnabled); + insertItem( model()->rowCount(), item ); + QCheckBox* pCheckBox = new QCheckBox( listAlarmLevel.at(i)->sName ); + setItemWidget( item, pCheckBox ); + m_listCheckBox.append( pCheckBox ); + pCheckBox->setChecked( false ); + connect( pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setSelectItem(int)) ); + pCheckBox->setChecked( true ); + } + connect( m_pCombobox, SIGNAL(activated(int)), this, SLOT(setSelectItem(int)) ); + } + void getSelectData( QList& data ) + { + for( int i=0; iisChecked() ) + data.append( m_listData.at(i) ); + } + } + +private slots: + //QCheckBox复选消息处理 + void setSelectItem( int ) + { + QString sName; + for( int i=0; iisChecked() ) + { + sName += m_listCheckBox.at(i)->text(); + sName += ","; + } + } + m_pCombobox->setEditText( sName ); + } + +private: + QComboBox* m_pCombobox; + QList m_listCheckBox; + QList m_listData; +}; + +#endif // CALARMLEVELCOMBOBOX_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmModel.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmModel.cpp index 8e3d4e64..3934d5b8 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmModel.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmModel.cpp @@ -1,128 +1,128 @@ -#include "CAlarmModel.h" - -CAlarmModel::CAlarmModel() -{ - m_listHeadText << tr("时间") - << tr("优先级") - << tr("所属位置") - << tr("告警内容") - << tr("操作"); -} - -CAlarmModel::~CAlarmModel() -{ - -} - -void CAlarmModel::setHiddenOptColumn(bool hide) -{ - if(hide) - { - m_listHeadText.pop_back(); - } - else - { - m_listHeadText.push_back(tr("操作")); - } -} - -QVariant CAlarmModel::headerData( int section, Qt::Orientation orientation, int role) const -{ - if ( role == Qt::DisplayRole && orientation == Qt::Horizontal ) - { - return m_listHeadText.at(section); - } - return QAbstractTableModel::headerData(section,orientation,role); -} - -Qt::ItemFlags CAlarmModel::flags(const QModelIndex &index) const -{ - return Qt::ItemIsEditable | QAbstractTableModel::flags(index); -} - -int CAlarmModel::rowCount( const QModelIndex& ) const -{ - return m_listAlarm.count(); -} - -int CAlarmModel::columnCount( const QModelIndex& ) const -{ - return m_listHeadText.count(); -} - -QVariant CAlarmModel::data( const QModelIndex &index, int role ) const -{ - if ( !index.isValid() )//没有索引返回无效数据,不要直接返回0 - { - return QVariant(); - } - - if ( role == Qt::TextAlignmentRole ) - { - return int(Qt::AlignHCenter | Qt::AlignVCenter); - } - else if ( role == Qt::DisplayRole || role == Qt::EditRole ) - { - QVariant oVal; - switch ( index.column() ) - { - case 0: - oVal = m_listAlarm.at(index.row())->sTime; - break; - case 1: - oVal = m_listAlarm.at(index.row())->sLevel; - break; - case 2: - oVal = m_listAlarm.at(index.row())->sLocation; - break; - case 3: - oVal = m_listAlarm.at(index.row())->sContent; - break; - case 4: - if ( m_listAlarm.at(index.row())->sKeyIdTag.startsWith("analog") ) - oVal = tr("趋势"); - else if ( m_listAlarm.at(index.row())->sKeyIdTag.startsWith("digital") ) - oVal = tr("录波"); - } - return oVal; - } - - return QVariant(); -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#include "CAlarmModel.h" + +CAlarmModel::CAlarmModel() +{ + m_listHeadText << tr("时间") + << tr("优先级") + << tr("所属位置") + << tr("告警内容") + << tr("操作"); +} + +CAlarmModel::~CAlarmModel() +{ + +} + +void CAlarmModel::setHiddenOptColumn(bool hide) +{ + if(hide) + { + m_listHeadText.pop_back(); + } + else + { + m_listHeadText.push_back(tr("操作")); + } +} + +QVariant CAlarmModel::headerData( int section, Qt::Orientation orientation, int role) const +{ + if ( role == Qt::DisplayRole && orientation == Qt::Horizontal ) + { + return m_listHeadText.at(section); + } + return QAbstractTableModel::headerData(section,orientation,role); +} + +Qt::ItemFlags CAlarmModel::flags(const QModelIndex &index) const +{ + return Qt::ItemIsEditable | QAbstractTableModel::flags(index); +} + +int CAlarmModel::rowCount( const QModelIndex& ) const +{ + return m_listAlarm.count(); +} + +int CAlarmModel::columnCount( const QModelIndex& ) const +{ + return m_listHeadText.count(); +} + +QVariant CAlarmModel::data( const QModelIndex &index, int role ) const +{ + if ( !index.isValid() )//没有索引返回无效数据,不要直接返回0 + { + return QVariant(); + } + + if ( role == Qt::TextAlignmentRole ) + { + return int(Qt::AlignHCenter | Qt::AlignVCenter); + } + else if ( role == Qt::DisplayRole || role == Qt::EditRole ) + { + QVariant oVal; + switch ( index.column() ) + { + case 0: + oVal = m_listAlarm.at(index.row())->sTime; + break; + case 1: + oVal = m_listAlarm.at(index.row())->sLevel; + break; + case 2: + oVal = m_listAlarm.at(index.row())->sLocation; + break; + case 3: + oVal = m_listAlarm.at(index.row())->sContent; + break; + case 4: + if ( m_listAlarm.at(index.row())->sKeyIdTag.startsWith("analog") ) + oVal = tr("趋势"); + else if ( m_listAlarm.at(index.row())->sKeyIdTag.startsWith("digital") ) + oVal = tr("录波"); + } + return oVal; + } + + return QVariant(); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmModel.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmModel.h index d2e195e2..4876ae4c 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmModel.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmModel.h @@ -1,41 +1,41 @@ -#ifndef CALARMMODEL_H -#define CALARMMODEL_H - -#include -#include -#include -#include -#include -#include -#include -#include "SAlarmInfo.h" -#include "SAlarmList.h" - -class CAlarmModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - CAlarmModel(); - ~CAlarmModel(); - - void setHiddenOptColumn(bool hide); -public: - void beginReset(){ this->beginResetModel(); } - void endReset(){ this->endResetModel(); } - void setAlarmList( QList& listAlarm ) { m_listAlarm = listAlarm; } - void clearAlarmList(){ m_listAlarm.clear(); } - -public: - QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - int rowCount( const QModelIndex &parent = QModelIndex() ) const; - int columnCount( const QModelIndex &parent = QModelIndex() ) const; - QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; - -public: - QStringList m_listHeadText; - QList m_listAlarm; -}; - -#endif // CALARMMODEL_H +#ifndef CALARMMODEL_H +#define CALARMMODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include "SAlarmInfo.h" +#include "SAlarmList.h" + +class CAlarmModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + CAlarmModel(); + ~CAlarmModel(); + + void setHiddenOptColumn(bool hide); +public: + void beginReset(){ this->beginResetModel(); } + void endReset(){ this->endResetModel(); } + void setAlarmList( QList& listAlarm ) { m_listAlarm = listAlarm; } + void clearAlarmList(){ m_listAlarm.clear(); } + +public: + QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + int rowCount( const QModelIndex &parent = QModelIndex() ) const; + int columnCount( const QModelIndex &parent = QModelIndex() ) const; + QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; + +public: + QStringList m_listHeadText; + QList m_listAlarm; +}; + +#endif // CALARMMODEL_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.cpp index bf767468..e6168a22 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.cpp @@ -1,183 +1,183 @@ -#include "CAlarmReport.h" -#include "ui_CAlarmReport.h" -#include "CommonFunction.h" - -CAlarmReport::CAlarmReport(QWidget *parent) : - QWidget(parent), - ui(new Ui::CAlarmReport) -{ - ui->setupUi(this); - - this->setWindowFlags( ( this->windowFlags() & ~Qt::WindowMinimizeButtonHint ) | Qt::WindowStaysOnTopHint | Qt::Dialog ); - this->setWindowTitle( "分析报告" ); - ui->splitter->setStretchFactor( 0, 0 ); - ui->splitter->setStretchFactor( 1, 1 ); - ui->tableWidget->horizontalHeader()->setStretchLastSection( true ); - ui->tableWidget->setEditTriggers( QAbstractItemView::NoEditTriggers ); - ui->tableWidget->setSelectionBehavior( QAbstractItemView::SelectRows ); - ui->textEdit->setText( "报告内容: " ); - ui->textEdit->setEnabled( false ); - - connect( ui->pushButton_export, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonExportClicked(bool)) ); - - loadConfig(); -} - -CAlarmReport::~CAlarmReport() -{ - delete ui; -} - -void CAlarmReport::loadConfig() -{ - QString sFileName = "alarm_statistics.ini"; - if ( !QFile::exists(sFileName) ) - { - m_nNormalAlarmCount = 1000; - m_nSmartAlarmCount = 1000; - QSettings oSettings( sFileName, QSettings::IniFormat, 0 ); - oSettings.setValue( "AlarmReport/NormalAlarm", m_nNormalAlarmCount ); - oSettings.setValue( "AlarmReport/SmartAlarm", m_nSmartAlarmCount ); - } - else - { - QSettings oSettings( sFileName, QSettings::IniFormat, 0 ); - m_nNormalAlarmCount = oSettings.value( "AlarmReport/NormalAlarm", 1000 ).toInt(); - m_nSmartAlarmCount = oSettings.value( "AlarmReport/SmartAlarm", 1000 ).toInt(); - } -} - -void CAlarmReport::initData( QTableWidget* pTableWidget ) -{ - if ( pTableWidget == NULL ) - return; - - ui->tableWidget->clear(); - ui->tableWidget->setRowCount(0); - - int nRowCount = pTableWidget->rowCount(); - int nColCount = pTableWidget->horizontalHeader()->count(); - QStringList listHeader; - for ( int i=0; ihorizontalHeaderItem(i)->text(); - ui->tableWidget->setColumnCount( nColCount ); - ui->tableWidget->setHorizontalHeaderLabels( listHeader ); - - int nIndex = 1; - for ( int i=0; itableWidget->insertRow( i ); - for ( int l=0; litem(i,l)->text() ); - pItem->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( i, l, pItem ); - - // 将记录写入右侧文本框 - if ( l == 1 ) - { - QStringList listCount = pTableWidget->item(i,l)->text().split("/"); - if ( listCount.count() == 2 ) - { - if ( listCount.at(0).toInt() >= m_nNormalAlarmCount ) - { - QString sText = ui->textEdit->toHtml(); - sText = sText + QString("%1:%2,普通告警偏高; \n").arg(nIndex++).arg(pTableWidget->item(i,0)->text()); - ui->textEdit->setText( sText ); - } - if ( listCount.at(1).toInt() >= m_nSmartAlarmCount ) - { - QString sText = ui->textEdit->toHtml(); - sText = sText + QString("%1:%2,智能告警偏高; \n").arg(nIndex++).arg(pTableWidget->item(i,0)->text()); - ui->textEdit->setText( sText ); - } - } - } - } - } -} - -void CAlarmReport::slotPushButtonExportClicked( bool ) -{ - QDir dir(QCoreApplication::applicationDirPath()); - dir.cdUp(); - dir.cdUp(); - - QString sPath = QFileDialog::getExistingDirectory(this, tr("选择导出目录"), - dir.absolutePath(), - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - - if ( sPath == "" ) - return; - - QString sExcelFileName = QString("告警分析报告.xlsx"); - QXlsx::Document xlsx; - xlsx.addSheet( "sheet1" ); - - // 宽度 - xlsx.setColumnWidth( 1, 20 ); - xlsx.setColumnWidth( 2, 20 ); - xlsx.setColumnWidth( 3, 50 ); - - // 写横向表头 - xlsx.write( 1, 1, "名称" ); - xlsx.write( 1, 2, "告警数/智能告警数" ); - - // 写内容 - int nRowCount = ui->tableWidget->rowCount(); - int nColCount = ui->tableWidget->horizontalHeader()->count(); - for ( int i=0; itableWidget->item(i,l)->text() ); - } - } - - // 写报告内容 - QStringList listReport = ui->textEdit->toPlainText().split(" "); - for ( int i=0; idrawPrimitive(QStyle::PE_Widget, &op, &p, this); -} - - - - - - - - - - - - - - - - - - - - - - - - - +#include "CAlarmReport.h" +#include "ui_CAlarmReport.h" +#include "CommonFunction.h" + +CAlarmReport::CAlarmReport(QWidget *parent) : + QWidget(parent), + ui(new Ui::CAlarmReport) +{ + ui->setupUi(this); + + this->setWindowFlags( ( this->windowFlags() & ~Qt::WindowMinimizeButtonHint ) | Qt::WindowStaysOnTopHint | Qt::Dialog ); + this->setWindowTitle( "分析报告" ); + ui->splitter->setStretchFactor( 0, 0 ); + ui->splitter->setStretchFactor( 1, 1 ); + ui->tableWidget->horizontalHeader()->setStretchLastSection( true ); + ui->tableWidget->setEditTriggers( QAbstractItemView::NoEditTriggers ); + ui->tableWidget->setSelectionBehavior( QAbstractItemView::SelectRows ); + ui->textEdit->setText( "报告内容: " ); + ui->textEdit->setEnabled( false ); + + connect( ui->pushButton_export, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonExportClicked(bool)) ); + + loadConfig(); +} + +CAlarmReport::~CAlarmReport() +{ + delete ui; +} + +void CAlarmReport::loadConfig() +{ + QString sFileName = "alarm_statistics.ini"; + if ( !QFile::exists(sFileName) ) + { + m_nNormalAlarmCount = 1000; + m_nSmartAlarmCount = 1000; + QSettings oSettings( sFileName, QSettings::IniFormat, 0 ); + oSettings.setValue( "AlarmReport/NormalAlarm", m_nNormalAlarmCount ); + oSettings.setValue( "AlarmReport/SmartAlarm", m_nSmartAlarmCount ); + } + else + { + QSettings oSettings( sFileName, QSettings::IniFormat, 0 ); + m_nNormalAlarmCount = oSettings.value( "AlarmReport/NormalAlarm", 1000 ).toInt(); + m_nSmartAlarmCount = oSettings.value( "AlarmReport/SmartAlarm", 1000 ).toInt(); + } +} + +void CAlarmReport::initData( QTableWidget* pTableWidget ) +{ + if ( pTableWidget == NULL ) + return; + + ui->tableWidget->clear(); + ui->tableWidget->setRowCount(0); + + int nRowCount = pTableWidget->rowCount(); + int nColCount = pTableWidget->horizontalHeader()->count(); + QStringList listHeader; + for ( int i=0; ihorizontalHeaderItem(i)->text(); + ui->tableWidget->setColumnCount( nColCount ); + ui->tableWidget->setHorizontalHeaderLabels( listHeader ); + + int nIndex = 1; + for ( int i=0; itableWidget->insertRow( i ); + for ( int l=0; litem(i,l)->text() ); + pItem->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( i, l, pItem ); + + // 将记录写入右侧文本框 + if ( l == 1 ) + { + QStringList listCount = pTableWidget->item(i,l)->text().split("/"); + if ( listCount.count() == 2 ) + { + if ( listCount.at(0).toInt() >= m_nNormalAlarmCount ) + { + QString sText = ui->textEdit->toHtml(); + sText = sText + QString("%1:%2,普通告警偏高; \n").arg(nIndex++).arg(pTableWidget->item(i,0)->text()); + ui->textEdit->setText( sText ); + } + if ( listCount.at(1).toInt() >= m_nSmartAlarmCount ) + { + QString sText = ui->textEdit->toHtml(); + sText = sText + QString("%1:%2,智能告警偏高; \n").arg(nIndex++).arg(pTableWidget->item(i,0)->text()); + ui->textEdit->setText( sText ); + } + } + } + } + } +} + +void CAlarmReport::slotPushButtonExportClicked( bool ) +{ + QDir dir(QCoreApplication::applicationDirPath()); + dir.cdUp(); + dir.cdUp(); + + QString sPath = QFileDialog::getExistingDirectory(this, tr("选择导出目录"), + dir.absolutePath(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + if ( sPath == "" ) + return; + + QString sExcelFileName = QString("告警分析报告.xlsx"); + QXlsx::Document xlsx; + xlsx.addSheet( "sheet1" ); + + // 宽度 + xlsx.setColumnWidth( 1, 20 ); + xlsx.setColumnWidth( 2, 20 ); + xlsx.setColumnWidth( 3, 50 ); + + // 写横向表头 + xlsx.write( 1, 1, "名称" ); + xlsx.write( 1, 2, "告警数/智能告警数" ); + + // 写内容 + int nRowCount = ui->tableWidget->rowCount(); + int nColCount = ui->tableWidget->horizontalHeader()->count(); + for ( int i=0; itableWidget->item(i,l)->text() ); + } + } + + // 写报告内容 + QStringList listReport = ui->textEdit->toPlainText().split(" "); + for ( int i=0; idrawPrimitive(QStyle::PE_Widget, &op, &p, this); +} + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.h index 24e079c0..de90b4ef 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.h @@ -1,45 +1,45 @@ -#ifndef CALARMREPORT_H -#define CALARMREPORT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "model_excel/xlsx/xlsxdocument.h" - -namespace Ui { -class CAlarmReport; -} - -class CAlarmReport : public QWidget -{ - Q_OBJECT - -public: - explicit CAlarmReport(QWidget *parent = 0); - ~CAlarmReport(); - -public: - void initData( QTableWidget* pTableWidget ); - void loadConfig(); - -public slots: - void slotPushButtonExportClicked( bool bChecked ); - -protected: - void paintEvent(QPaintEvent *pEvent); - -private: - Ui::CAlarmReport *ui; - int m_nNormalAlarmCount; // 普通告警条数,从配置中获取,大于此条数则认为异常 - int m_nSmartAlarmCount; // 智能告警条数,从配置中获取,大于此条数则认为异常 -}; - -#endif // CALARMREPORT_H +#ifndef CALARMREPORT_H +#define CALARMREPORT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "model_excel/xlsx/xlsxdocument.h" + +namespace Ui { +class CAlarmReport; +} + +class CAlarmReport : public QWidget +{ + Q_OBJECT + +public: + explicit CAlarmReport(QWidget *parent = 0); + ~CAlarmReport(); + +public: + void initData( QTableWidget* pTableWidget ); + void loadConfig(); + +public slots: + void slotPushButtonExportClicked( bool bChecked ); + +protected: + void paintEvent(QPaintEvent *pEvent); + +private: + Ui::CAlarmReport *ui; + int m_nNormalAlarmCount; // 普通告警条数,从配置中获取,大于此条数则认为异常 + int m_nSmartAlarmCount; // 智能告警条数,从配置中获取,大于此条数则认为异常 +}; + +#endif // CALARMREPORT_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.ui b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.ui index be40498f..cf4b6e76 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.ui +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmReport.ui @@ -1,73 +1,73 @@ - - - CAlarmReport - - - - 0 - 0 - 762 - 431 - - - - Dialog - - - - - - Qt::Horizontal - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 80 - 24 - - - - 导出 - - - - - - - - - - - - - - CTableWidget - QTableWidget -
CTableWidget.h
-
-
- - -
+ + + CAlarmReport + + + + 0 + 0 + 762 + 431 + + + + Dialog + + + + + + Qt::Horizontal + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 80 + 24 + + + + 导出 + + + + + + + + + + + + + + CTableWidget + QTableWidget +
CTableWidget.h
+
+
+ + +
diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.cpp index b0a5eaff..e68cc996 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.cpp @@ -1,817 +1,817 @@ -#include "CAlarmStatistics.h" -#include "ui_CAlarmStatistics.h" -#include "pub_utility_api/I18N.h" -#include "pub_utility_api/FileStyle.h" - -using namespace kbd_public; -using namespace kbd_dbms; - -//#ff0000 255,0,0 -//#ff7414 255,116,20 -//#bbe242 187,226,66 -//#90e6bd 144,230,189 -//#f4e497 244,228,151 - -CAlarmStatistics::CAlarmStatistics(QWidget *parent,bool editMode) : - CAlarmStatisticsPluginWidget(parent), - m_bEditMode( editMode ), - ui(new Ui::CAlarmStatistics), - m_pChart(Q_NULLPTR) -{ - ui->setupUi(this); - - ui->comboBox_level->setView(new QListView()); - ui->comboBox_location->setView(new QListView()); - // 加载qss文件 - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm_statistics.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - else - { - qDebug() << "alarm_statistics.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - - if ( !m_bEditMode ) - { - initVariate(); - initUi(); - initBar(); - loadData(); - initLevelChoose(); - } -} - -void CAlarmStatistics::initialize( int /*nMode*/ ) -{ - -} - -CAlarmStatistics::~CAlarmStatistics() -{ - delete ui; - - if ( !m_bEditMode ) - { - delete m_pAlarmLevelComboBox; - m_pAlarmLevelComboBox = NULL; - - delete m_pLabelValue; - m_pLabelValue = NULL; - - delete m_pProcessDialog; - m_pProcessDialog = NULL; - - m_pQueryThread->wait(); - delete m_pQueryThread; - m_pQueryThread = NULL; - - qDeleteAll( m_listAlarmLevelCheckBox ); - m_listAlarmLevelCheckBox.clear(); - } -} - -void CAlarmStatistics::initVariate() -{ - m_pLabelValue = new QLabel(this); - m_pLabelValue->setObjectName( "value" ); - m_pLabelValue->hide(); - - m_pAlarmLevelComboBox = new CAlarmLevelComboBox( ui->comboBox_level ); - m_pProcessDialog = new CProcessDialog(); - m_pProcessDialog->setModal( true ); - m_pProcessDialog->hide(); - - m_pQueryThread = new CStatisticsQueryThread(); - - m_pAlarmCompare = new CAlarmCompare(this); - m_pAlarmCompare->setWindowModality(Qt::WindowModal); - m_pAlarmCompare->setStyleSheet( this->styleSheet() ); - m_pAlarmCompare->hide(); - - m_pAlarmReport = new CAlarmReport(this); - m_pAlarmReport->setWindowModality(Qt::WindowModal); - m_pAlarmReport->setStyleSheet( this->styleSheet() ); - m_pAlarmReport->hide(); - - m_pWageListDialog = new CWaveListDialog( this ); - - m_pBarSeriesNormal = NULL; - m_pBarSeriesSmart = NULL; - m_nLastRow = -1; - - m_bAfterMsgBox = false; -} - -void CAlarmStatistics::initUi() -{ - ui->splitter_2->setStretchFactor( 0, 0 ); - ui->splitter_2->setStretchFactor( 1, 1 ); - ui->splitter->setStretchFactor( 0, 5 ); - ui->splitter->setStretchFactor( 1, 5 ); - - ui->checkBox_alarm_normal->setChecked( true ); - ui->checkBox_alarm_smart->setChecked( true ); - - ui->comboBox_level->setMinimumWidth( 120 ); - - ui->dateEdit_start->setDate( QDate::currentDate().addDays(-30) ); - ui->dateEdit_end->setDate( QDate::currentDate() ); - - ui->tableWidget_location->setColumnCount( 2 ); - QStringList listHeader; - listHeader<tableWidget_location->setHorizontalHeaderLabels( listHeader ); - ui->tableWidget_location->horizontalHeader()->setStretchLastSection( true ); - ui->tableWidget_location->verticalHeader()->hide(); - ui->tableWidget_location->setEditTriggers( QAbstractItemView::NoEditTriggers ); - ui->tableWidget_location->setSelectionBehavior( QAbstractItemView::SelectRows ); - ui->tableWidget_location->setSelectionMode( QAbstractItemView::SingleSelection ); - - ui->tableView_alarm->setModel( m_pQueryThread->m_pAlarmModel ); - ui->tableView_alarm->setEditTriggers( QAbstractItemView::NoEditTriggers ); - ui->tableView_alarm->setSelectionBehavior( QAbstractItemView::SelectRows ); - ui->tableView_alarm->setSelectionMode( QAbstractItemView::SingleSelection ); - ui->tableView_alarm->setObjectName( "alarm" ); -// ui->tableView_alarm->horizontalHeader()->setSectionResizeMode(3,QHeaderView::Stretch); -// ui->tableView_alarm->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); -// ui->tableView_alarm->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed); -// ui->tableView_alarm->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Fixed); -// ui->tableView_alarm->horizontalHeader()->setm(0, 200);//设置固定宽度 -// ui->tableView_alarm->setColumnWidth(1, 80);//设置固定宽度 -// ui->tableView_alarm->setColumnWidth(4, 80);//设置固定宽度 - - connect( ui->pb_query, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonQueryClicked(bool)) ); - connect( ui->checkBox_alarm_normal, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxStateChanged(int)) ); - connect( ui->checkBox_alarm_smart, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxStateChanged(int)) ); - connect( m_pQueryThread, SIGNAL(signalQueryPercent(int)), m_pProcessDialog, SLOT(slotSetValue(int)) ); - connect( m_pQueryThread, SIGNAL(signalQueryEnd()), this, SLOT(slotQueryEnd()) ); - connect( m_pProcessDialog, SIGNAL(signalCancel()), m_pQueryThread, SLOT(slotCancel()) ); - connect( ui->pb_compare, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonCompareClicked(bool)) ); - connect( ui->tableView_alarm, SIGNAL(clicked(const QModelIndex&)), this, SLOT(slotTableViewAlarmClicked(const QModelIndex&)) ); - connect( ui->pushButton_report, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonReportClicked(bool)) ); - connect( ui->tableWidget_location, SIGNAL(cellClicked(int,int)), this, SLOT(slotTableWidgetLocationCellClicked(int,int)) ); -} - -void CAlarmStatistics::initBar() -{ - m_pChart = new QChart(); - m_pChart->setContentsMargins( 0,0,0,0 ); - m_pChart->setMargins(QMargins(0,0,0,0)); - m_pChart->setBackgroundRoundness( 0 ); - m_pChart->legend()->setVisible(false); - m_pChart->setBackgroundBrush( QBrush(QColor(3,22,36)) ); - - QChartView *pChartView = new QChartView( ui->frame_bar ); - pChartView->setChart( m_pChart ); - pChartView->setRenderHint(QPainter::Antialiasing); - pChartView->setMinimumHeight( 200 ); - QLayout* pLayout = ui->frame_bar->layout(); - pLayout->addWidget( pChartView ); - ui->frame_bar->setLayout( pLayout ); -} - -void CAlarmStatistics::initLevelChoose() -{ - for ( int i=0; im_listAlarmLevel.count(); i++ ) - { - SAlarmLevel* pAlarmLevel = m_pQueryThread->m_listAlarmLevel.at(i); - QCheckBox* pCheckBox = new QCheckBox( pAlarmLevel->sName ); - pCheckBox->setObjectName( QString("checkBox_level%1").arg(pAlarmLevel->nPriority) ); - pCheckBox->setProperty( "id", pAlarmLevel->nId ); - pCheckBox->setChecked( true ); - ui->horizontalLayout_2->addWidget( pCheckBox ); - if ( i < m_pQueryThread->m_listAlarmLevelColor.count() ) - { - QColor tmpColor = m_pQueryThread->m_listAlarmLevelColor.at(i); - pCheckBox->setStyleSheet( QString("QCheckBox::indicator:checked{background-color: rgb(%1,%2,%3);}") - .arg(tmpColor.red()).arg(tmpColor.green()).arg(tmpColor.blue()) ); - } - m_listAlarmLevelCheckBox.append( pCheckBox ); - connect( pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxStateChanged(int)) ); - } -} - -void CAlarmStatistics::loadData() -{ - for ( int i=0; im_listLocation.count(); i++ ) - ui->comboBox_location->addItem( m_pQueryThread->m_listLocation.at(i)->sName, m_pQueryThread->m_listLocation.at(i)->nId ); - - m_pAlarmLevelComboBox->init( m_pQueryThread->m_listAlarmLevel ); - -// qint64 time = QDateTime::currentMSecsSinceEpoch(); -// //qint64 timee = time +1000ll*86400*30*12; -// qint64 timee = time +1000ll*86400; - -// qint64 ts = QDateTime::currentMSecsSinceEpoch(); -// int nCount = 0; -// QString sSmartUuid = ""; -// while (timem_pDbInterface->execute(sSql) ) -// { -// qDebug()<m_pDbInterface->getErrMsg(); -// break; -// } -// } - -// QString sSql = QString("insert into his_event_di_change values(%1,%2,%3,%4,%5,%6,'%7',%8,%9,%10,'%11',%12,%13,'%14','%15','%16','%17')") -// .arg(2).arg(112).arg(time).arg(1) -// .arg(1)//位置 -// .arg(4).arg("C相电压 230.00kV 越上上限") -// .arg(l)//优先级 -// .arg(146).arg(1) -// .arg("analog.QHB.302JGXX620Xinst256.VC.value").arg(0).arg(0).arg("") -// .arg("station1.pcs4") -// .arg(sNormalUuid) -// .arg(sSmartUuid);//间隔 -// time = time + 2000; -// if ( 0 != m_pQueryThread->m_pDbInterface->execute(sSql) ) -// { -// qDebug()<m_pDbInterface->getErrMsg(); -// break; -// } -// nCount++; -// if ( nCount % 100000 == 0 ) -// { -// qDebug()<m_pDbInterface->execute(sSql) ) -// { -// qDebug()<m_pDbInterface->getErrMsg(); -// break; -// } -// nCount++; -// if ( nCount % 50000 == 0 ) -// { -// qDebug()<hide();//进行隐藏 - return; - } - - QString sShow = ""; - if ( pBarset->label().startsWith("normal") ) - { - sShow = "普通告警\n"; - for ( int i=0; im_listAlarmLevel.count(); i++ ) - { - sShow = sShow + m_pQueryThread->m_listAlarmLevel.at(i)->sName + " : " + QString::number(m_listBarSetNormal.at(i)->at(nIndex)); - if ( i != m_pQueryThread->m_listAlarmLevel.count() - 1 ) - sShow += "\n"; - } - } - if ( pBarset->label().startsWith("smart") ) - { - sShow = "智能告警\n"; - for ( int i=0; im_listAlarmLevel.count(); i++ ) - { - sShow = sShow + m_pQueryThread->m_listAlarmLevel.at(i)->sName + " : " + QString::number(m_listBarSetSmart.at(i)->at(nIndex)); - if ( i != m_pQueryThread->m_listAlarmLevel.count() - 1 ) - sShow += "\n"; - } - } - - m_pLabelValue->setText( sShow ); - QPoint curPos = mapFromGlobal( QCursor::pos() ); - m_pLabelValue->move( curPos.x()-100, curPos.y()+10 );//移动数值 - m_pLabelValue->show();//显示出来 - m_pLabelValue->adjustSize(); -} - -void CAlarmStatistics::slotBarClicked( int nIndex, QBarSet* pBarset ) -{ - m_pQueryThread->m_pAlarmModel->beginReset(); - m_pQueryThread->m_pAlarmModel->clearAlarmList(); - m_pQueryThread->m_pAlarmModel->endReset(); - - if ( pBarset->label().startsWith("normal") ) - { - ui->tableView_alarm->setColumnHidden( 4, false ); - m_pQueryThread->m_pAlarmModel->beginReset(); - m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarmNormal.at(nIndex)->listAlarmInfo ); - m_pQueryThread->m_pAlarmModel->endReset(); - resizeColumnsToContents( ui->tableView_alarm ); - if ( m_pQueryThread->m_listAlarmNormal.at(nIndex)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - { - QMessageBox::information( 0, "提示", QString("告警条数过多,仅显示前 %1 条").arg(CN_ALARMINFO_MAXROW) ); - m_bAfterMsgBox = true; - } - } - else - { - ui->tableView_alarm->setColumnHidden( 4, true ); - m_pQueryThread->m_pAlarmModel->beginReset(); - m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarmSmart.at(nIndex)->listAlarmInfo ); - m_pQueryThread->m_pAlarmModel->endReset(); - resizeColumnsToContents( ui->tableView_alarm ); - if ( m_pQueryThread->m_listAlarmSmart.at(nIndex)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - { - QMessageBox::information( 0, "提示", QString("告警条数过多,仅显示前 %1 条").arg(CN_ALARMINFO_MAXROW) ); - m_bAfterMsgBox = true; - } - - } - - ui->label_name->setText( m_pQueryThread->m_listAlarmNormal.at(nIndex)->sName ); -} - -void CAlarmStatistics::resetUi() -{ - // 清空左侧设备列表 - ui->tableWidget_location->clearContents(); - ui->tableWidget_location->setRowCount( 0 ); - - // 清空柱状图 - m_pChart->removeAllSeries(); - - // 清空查询线程 - m_pQueryThread->clear(); -} - -void CAlarmStatistics::resetBar() -{ - -} - -void CAlarmStatistics::showBar() -{ - // 清空柱状图 - m_pChart->removeAllSeries(); - - // 清空barset列表 - m_listBarSetNormal.clear(); - m_listBarSetSmart.clear(); - - if ( m_pQueryThread->m_listAlarmNormal.count() <= 0 ) - return; - - if ( m_pBarSeriesNormal != NULL ) - { - m_pBarSeriesNormal->clear(); - delete m_pBarSeriesNormal; - } - m_pBarSeriesNormal = new QStackedBarSeries(); - connect( m_pBarSeriesNormal, SIGNAL(hovered(bool,int,QBarSet*)), this, SLOT(slotBarMouseMoveHovered(bool,int,QBarSet*)) ); - connect( m_pBarSeriesNormal, SIGNAL(clicked(int,QBarSet*)), this, SLOT(slotBarClicked(int,QBarSet*)) ); - if ( m_pBarSeriesSmart != NULL ) - { - m_pBarSeriesSmart->clear(); - delete m_pBarSeriesSmart; - } - m_pBarSeriesSmart = new QStackedBarSeries(); - connect( m_pBarSeriesSmart, SIGNAL(hovered(bool,int,QBarSet*)), this, SLOT(slotBarMouseMoveHovered(bool,int,QBarSet*)) ); - connect( m_pBarSeriesSmart, SIGNAL(clicked(int,QBarSet*)), this, SLOT(slotBarClicked(int,QBarSet*)) ); - - for ( int i=0; im_listAlarmLevel.count(); i++ ) - { - QBarSet *pSet0 = new QBarSet(QString("normal_level%1").arg(i+1)); - m_listBarSetNormal.append( pSet0 ); - m_pBarSeriesNormal->append( pSet0 ); - QBarSet *pSet1 = new QBarSet(QString("smart_level%1").arg(i+1)); - m_listBarSetSmart.append( pSet1 ); - m_pBarSeriesSmart->append( pSet1 ); - } - - QBarCategoryAxis *pAxis = new QBarCategoryAxis(); - for ( int i=0; im_listAlarmNormal.count(); i++ ) - { - if ( i >= CN_MAXBARSERIES ) - break; - - SAlarmList* pAlarmList = m_pQueryThread->m_listAlarmNormal.at(i); - SAlarmList* pSmartAlarmList = m_pQueryThread->m_listAlarmSmart.at(i); - pAxis->append( pAlarmList->sName ); - for ( int l=0; llistLevelCount.count(); l++ ) - { - if ( m_listAlarmLevelCheckBox.at(l)->isChecked() ) - { - *m_listBarSetNormal[l] << pAlarmList->listLevelCount.at(l); - *m_listBarSetSmart[l] << pSmartAlarmList->listLevelCount.at(l); - } - else - { - *m_listBarSetNormal[l] << 0; - *m_listBarSetSmart[l] << 0; - } - } - } - - if ( ui->checkBox_alarm_normal->isChecked() ) - { - m_pChart->addSeries( m_pBarSeriesNormal ); - m_pBarSeriesNormal = NULL; - } - if ( ui->checkBox_alarm_smart->isChecked() ) - { - m_pChart->addSeries( m_pBarSeriesSmart ); - m_pBarSeriesSmart = NULL; - } - m_pChart->createDefaultAxes(); - m_pChart->setAxisX( pAxis ); - - if ( m_pChart->axisX() ) - { - m_pChart->axisX()->setLabelsBrush( QBrush(m_chartLabelColor)); - m_pChart->axisX()->setLinePenColor( m_chartLineColor); - m_pChart->axisX()->setGridLineVisible( false ); - } - if ( m_pChart->axisY() ) - { - m_pChart->axisY()->setLabelsBrush( QBrush(m_chartLabelColor)); - m_pChart->axisY()->setLinePenColor( m_chartLineColor); - m_pChart->axisY()->setGridLineVisible( false ); - } - - QList listSeries = m_pChart->series(); - for ( int i=0; i< listSeries.count(); i++ ) - { - QStackedBarSeries* pBarSeries = dynamic_cast(listSeries.at(i)); - if ( pBarSeries == NULL ) - continue; - QList listBar = pBarSeries->barSets(); - for ( int l=0; lsetBrush( QBrush(m_pQueryThread->m_listAlarmLevelColor.at(l)) ); - } -} - -QColor CAlarmStatistics::chartBackground() -{ - return m_chartBackground; -} - -void CAlarmStatistics::setChartBackground(const QColor& color) -{ - m_chartBackground = color; - - if(m_pChart != Q_NULLPTR) - { - m_pChart->setBackgroundBrush( QBrush(m_chartBackground) ); - } -} - -QColor CAlarmStatistics::chartLabelColor() -{ - return m_chartLabelColor; -} - -void CAlarmStatistics::setChartLabelColor(const QColor &color) -{ - m_chartLabelColor = color; - - if(m_pChart == Q_NULLPTR) - { - return; - } - if(m_pChart->axisX()) - { - m_pChart->axisX()->setLabelsBrush( QBrush(m_chartLabelColor)); - } - if(m_pChart->axisY()) - { - m_pChart->axisY()->setLabelsBrush( QBrush(m_chartLabelColor)); - } -} - -QColor CAlarmStatistics::chartLineColor() -{ - return m_chartLineColor; -} - -void CAlarmStatistics::setChartLineColor(const QColor &color) -{ - m_chartLineColor = color; - - if(m_pChart == Q_NULLPTR) - { - return; - } - if(m_pChart->axisX()) - { - m_pChart->axisX()->setLinePenColor( m_chartLineColor); - } - if(m_pChart->axisY()) - { - m_pChart->axisY()->setLinePenColor( m_chartLineColor); - } -} - -void CAlarmStatistics::slotPushButtonQueryClicked( bool ) -{ - // 没有查找到任何站信息 - if ( ui->comboBox_location->count() <= 1 ) - return; - - this->setCursor(Qt::WaitCursor); - m_pProcessDialog->reset(); - m_pProcessDialog->show(); - - // 清空界面 - resetUi(); - - // 清空线程 - m_pQueryThread->clear(); - - // 获取告警级别选择的字符串 - QList listLevelId; - m_pAlarmLevelComboBox->getSelectData( listLevelId ); - if ( listLevelId.count() <= 0 ) - { - m_pProcessDialog->hide(); - this->setCursor(Qt::ArrowCursor); - QMessageBox::warning( 0, tr("警告"), tr("未选择告警等级") ); - return; - } - for ( int i=0; im_sSelectedLevel = m_pQueryThread->m_sSelectedLevel + QString::number(listLevelId.at(i)) + ","; - m_pQueryThread->m_sSelectedLevel = m_pQueryThread->m_sSelectedLevel.left( m_pQueryThread->m_sSelectedLevel.count()-1 ); - - // 开始时间结束时间 - m_pQueryThread->m_nStartMs = ui->dateEdit_start->dateTime().toMSecsSinceEpoch(); - m_pQueryThread->m_nEndMs = ui->dateEdit_end->dateTime().addDays(1).toMSecsSinceEpoch(); - if ( ui->dateEdit_start->dateTime() > ui->dateEdit_end->dateTime() ) - { - m_pProcessDialog->hide(); - this->setCursor(Qt::ArrowCursor); - QMessageBox::warning( 0, tr("警告"), tr("开始时间需小于等于结束时间") ); - return; - } - - // 当前站 - m_pQueryThread->m_nCurrentLocationIndex = ui->comboBox_location->currentIndex(); - - // 关键字 - m_pQueryThread->m_sKeyWord = ui->lineEdit_keyWord->text(); - - // 开始在线程中查询 - m_pQueryThread->start(); -} - -void CAlarmStatistics::slotCheckBoxStateChanged( int ) -{ - showBar(); -} - -void CAlarmStatistics::slotQueryEnd() -{ - // 重新初始化左边的设备列表 - for ( int i=0; im_listAlarmNormal.count(); i++ ) - { - SAlarmList* pAlarmList = m_pQueryThread->m_listAlarmNormal.at(i); - SAlarmList* pSmartAlarmList = m_pQueryThread->m_listAlarmSmart.at(i); - QTableWidgetItem* pItem0 = new QTableWidgetItem( pAlarmList->sName ); - pItem0->setTextAlignment( Qt::AlignLeft | Qt::AlignVCenter ); - //pItem0->setData( Qt::UserRole, 1 ); - QTableWidgetItem* pItem1 = new QTableWidgetItem(); - pItem1->setTextAlignment( Qt::AlignCenter ); - pItem1->setText( QString::number(pAlarmList->getAllLevelAlarmCount()) + "/" + - QString::number(pSmartAlarmList->getAllLevelAlarmCount())); - if ( i < CN_MAXBARSERIES ) - pItem1->setTextColor( QColor(255,0,0) ); - else - pItem1->setTextColor( QColor(0,255,0) ); - ui->tableWidget_location->insertRow( i ); - ui->tableWidget_location->setItem( i, 0, pItem0 ); - ui->tableWidget_location->setItem( i, 1, pItem1 ); - } - - // 显示柱状图 - showBar(); - - // 显示告警详细信息 - if ( m_pQueryThread->m_listAlarmNormal.count() > 0 ) - { - m_pQueryThread->m_pAlarmModel->beginReset(); - m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarmNormal.at(0)->listAlarmInfo ); - m_pQueryThread->m_pAlarmModel->endReset(); - resizeColumnsToContents( ui->tableView_alarm ); - ui->label_name->setText( m_pQueryThread->m_listAlarmNormal.at(0)->sName ); - } - - m_pProcessDialog->hide(); - this->setCursor(Qt::ArrowCursor); - - if(m_pQueryThread->m_listAlarmNormal.count()>0) - { - if ( m_pQueryThread->m_listAlarmNormal.at(0)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - { - QMessageBox::information( 0, "提示", QString("告警条数过多,仅显示前 %1 条").arg(CN_ALARMINFO_MAXROW) ); - } - } - else - { - QMessageBox::information( 0, "提示", QString("当前条件没有查到告警信息!") ); - } - return; -} - -void CAlarmStatistics::slotPushButtonCompareClicked( bool ) -{ - m_pAlarmCompare->setCurrentLocationIndex( ui->comboBox_location->currentIndex() ); - m_pAlarmCompare->show(); -} - -void CAlarmStatistics::slotTableViewAlarmClicked( const QModelIndex& index ) -{ - int nRow = index.row(); - int nCol = index.column(); - if ( nRow < 0 || nCol < 0 || nCol != 4 ) - return; - - QString sType = m_pQueryThread->m_pAlarmModel->data(index).toString();// 趋势 or 录波 - qint64 nTimeMs = QDateTime::fromString(m_pQueryThread->m_pAlarmModel->m_listAlarm.at(nRow)->sTime,"yyyy-MM-dd hh:mm:ss.zzz").toMSecsSinceEpoch(); - QString sKeyIdTag = m_pQueryThread->m_pAlarmModel->m_listAlarm.at(nRow)->sKeyIdTag; - - QStringList listKeyIdTag = sKeyIdTag.split("."); - if ( listKeyIdTag.count() != 5 ) - { - //QMessageBox::critical( 0, "错误", "历史表KEY_ID_TAG解析错误" ); - return; - } - listKeyIdTag.pop_front(); - listKeyIdTag.pop_back(); - QString sAppTagName = listKeyIdTag.join("."); - - if ( sType == "录波" ) - { - QString sPath = ""; - QString sErrorMsg = ""; - m_pQueryThread->getWavePath( sAppTagName, sPath, sErrorMsg ); - if ( sErrorMsg != "" ) - { - QMessageBox::critical( 0, "错误", sErrorMsg ); - return; - } - QDir dir( sPath ); - if ( !dir.exists() ) - { - QMessageBox::critical( 0, "错误", QString("文件夹 %1 不存在").arg(sPath) ); - return; - } - sPath = dir.absolutePath(); - QStringList listNameFilter; - listNameFilter << "*.cfg"; - QStringList listFile = dir.entryList(listNameFilter, QDir::Files|QDir::Readable, QDir::Name); //获取录波文件LIST - - if(listFile.count()>0) - { - m_pWageListDialog->clear(); - m_pWageListDialog->addFileNameList( sPath, listFile ); - m_pWageListDialog->show(); - } - else - { - QMessageBox::information( 0, "提示", QString("文件夹 '%1' 当前无录波文件!").arg(sPath) ); - return; - } - - } - else if ( sType == "趋势" ) - { - emit signalShowYCHistoryData( sAppTagName, nTimeMs ); - } - else - { - QMessageBox::critical( 0, "错误", "类型不正确" ); - } -} - -void CAlarmStatistics::slotPushButtonReportClicked( bool ) -{ - m_pAlarmReport->initData( ui->tableWidget_location ); - m_pAlarmReport->show(); -} - -void CAlarmStatistics::slotTableWidgetLocationCellClicked( int nRow, int ) -{// 左侧设备树点击后显示该设备的普通告警 - if ( m_nLastRow == nRow ) - return; - else - m_nLastRow = nRow; - - m_pQueryThread->m_pAlarmModel->beginReset(); - m_pQueryThread->m_pAlarmModel->clearAlarmList(); - m_pQueryThread->m_pAlarmModel->endReset(); - - ui->tableView_alarm->setColumnHidden( 4, false ); - m_pQueryThread->m_pAlarmModel->beginReset(); - m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarmNormal.at(nRow)->listAlarmInfo ); - m_pQueryThread->m_pAlarmModel->endReset(); - resizeColumnsToContents( ui->tableView_alarm ); - if ( m_pQueryThread->m_listAlarmNormal.at(nRow)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - { - QMessageBox::information( 0, "提示", QString("告警条数过多,仅显示前 %1 条").arg(CN_ALARMINFO_MAXROW) ); - } - - ui->label_name->setText( m_pQueryThread->m_listAlarmNormal.at(nRow)->sName ); -} - -void CAlarmStatistics::slotSetHiddenReport(bool hide) -{ - ui->pushButton_report->setHidden(hide); -} - -void CAlarmStatistics::slotSetHiddenOptColumn(bool hide) -{ - if(m_pQueryThread) - { - m_pQueryThread->setHiddenOptColumn(hide); - } - if(m_pAlarmCompare) - { - m_pAlarmCompare->setHiddenOptColumn(hide); - } -} - -void CAlarmStatistics::resizeEvent( QResizeEvent* ) -{ - resizeColumnsToContents( ui->tableView_alarm ); -} - - - - - - - - - - +#include "CAlarmStatistics.h" +#include "ui_CAlarmStatistics.h" +#include "pub_utility_api/I18N.h" +#include "pub_utility_api/FileStyle.h" + +using namespace kbd_public; +using namespace kbd_dbms; + +//#ff0000 255,0,0 +//#ff7414 255,116,20 +//#bbe242 187,226,66 +//#90e6bd 144,230,189 +//#f4e497 244,228,151 + +CAlarmStatistics::CAlarmStatistics(QWidget *parent,bool editMode) : + CAlarmStatisticsPluginWidget(parent), + m_bEditMode( editMode ), + ui(new Ui::CAlarmStatistics), + m_pChart(Q_NULLPTR) +{ + ui->setupUi(this); + + ui->comboBox_level->setView(new QListView()); + ui->comboBox_location->setView(new QListView()); + // 加载qss文件 + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm_statistics.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + else + { + qDebug() << "alarm_statistics.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + + if ( !m_bEditMode ) + { + initVariate(); + initUi(); + initBar(); + loadData(); + initLevelChoose(); + } +} + +void CAlarmStatistics::initialize( int /*nMode*/ ) +{ + +} + +CAlarmStatistics::~CAlarmStatistics() +{ + delete ui; + + if ( !m_bEditMode ) + { + delete m_pAlarmLevelComboBox; + m_pAlarmLevelComboBox = NULL; + + delete m_pLabelValue; + m_pLabelValue = NULL; + + delete m_pProcessDialog; + m_pProcessDialog = NULL; + + m_pQueryThread->wait(); + delete m_pQueryThread; + m_pQueryThread = NULL; + + qDeleteAll( m_listAlarmLevelCheckBox ); + m_listAlarmLevelCheckBox.clear(); + } +} + +void CAlarmStatistics::initVariate() +{ + m_pLabelValue = new QLabel(this); + m_pLabelValue->setObjectName( "value" ); + m_pLabelValue->hide(); + + m_pAlarmLevelComboBox = new CAlarmLevelComboBox( ui->comboBox_level ); + m_pProcessDialog = new CProcessDialog(); + m_pProcessDialog->setModal( true ); + m_pProcessDialog->hide(); + + m_pQueryThread = new CStatisticsQueryThread(); + + m_pAlarmCompare = new CAlarmCompare(this); + m_pAlarmCompare->setWindowModality(Qt::WindowModal); + m_pAlarmCompare->setStyleSheet( this->styleSheet() ); + m_pAlarmCompare->hide(); + + m_pAlarmReport = new CAlarmReport(this); + m_pAlarmReport->setWindowModality(Qt::WindowModal); + m_pAlarmReport->setStyleSheet( this->styleSheet() ); + m_pAlarmReport->hide(); + + m_pWageListDialog = new CWaveListDialog( this ); + + m_pBarSeriesNormal = NULL; + m_pBarSeriesSmart = NULL; + m_nLastRow = -1; + + m_bAfterMsgBox = false; +} + +void CAlarmStatistics::initUi() +{ + ui->splitter_2->setStretchFactor( 0, 0 ); + ui->splitter_2->setStretchFactor( 1, 1 ); + ui->splitter->setStretchFactor( 0, 5 ); + ui->splitter->setStretchFactor( 1, 5 ); + + ui->checkBox_alarm_normal->setChecked( true ); + ui->checkBox_alarm_smart->setChecked( true ); + + ui->comboBox_level->setMinimumWidth( 120 ); + + ui->dateEdit_start->setDate( QDate::currentDate().addDays(-30) ); + ui->dateEdit_end->setDate( QDate::currentDate() ); + + ui->tableWidget_location->setColumnCount( 2 ); + QStringList listHeader; + listHeader<tableWidget_location->setHorizontalHeaderLabels( listHeader ); + ui->tableWidget_location->horizontalHeader()->setStretchLastSection( true ); + ui->tableWidget_location->verticalHeader()->hide(); + ui->tableWidget_location->setEditTriggers( QAbstractItemView::NoEditTriggers ); + ui->tableWidget_location->setSelectionBehavior( QAbstractItemView::SelectRows ); + ui->tableWidget_location->setSelectionMode( QAbstractItemView::SingleSelection ); + + ui->tableView_alarm->setModel( m_pQueryThread->m_pAlarmModel ); + ui->tableView_alarm->setEditTriggers( QAbstractItemView::NoEditTriggers ); + ui->tableView_alarm->setSelectionBehavior( QAbstractItemView::SelectRows ); + ui->tableView_alarm->setSelectionMode( QAbstractItemView::SingleSelection ); + ui->tableView_alarm->setObjectName( "alarm" ); +// ui->tableView_alarm->horizontalHeader()->setSectionResizeMode(3,QHeaderView::Stretch); +// ui->tableView_alarm->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); +// ui->tableView_alarm->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed); +// ui->tableView_alarm->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Fixed); +// ui->tableView_alarm->horizontalHeader()->setm(0, 200);//设置固定宽度 +// ui->tableView_alarm->setColumnWidth(1, 80);//设置固定宽度 +// ui->tableView_alarm->setColumnWidth(4, 80);//设置固定宽度 + + connect( ui->pb_query, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonQueryClicked(bool)) ); + connect( ui->checkBox_alarm_normal, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxStateChanged(int)) ); + connect( ui->checkBox_alarm_smart, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxStateChanged(int)) ); + connect( m_pQueryThread, SIGNAL(signalQueryPercent(int)), m_pProcessDialog, SLOT(slotSetValue(int)) ); + connect( m_pQueryThread, SIGNAL(signalQueryEnd()), this, SLOT(slotQueryEnd()) ); + connect( m_pProcessDialog, SIGNAL(signalCancel()), m_pQueryThread, SLOT(slotCancel()) ); + connect( ui->pb_compare, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonCompareClicked(bool)) ); + connect( ui->tableView_alarm, SIGNAL(clicked(const QModelIndex&)), this, SLOT(slotTableViewAlarmClicked(const QModelIndex&)) ); + connect( ui->pushButton_report, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonReportClicked(bool)) ); + connect( ui->tableWidget_location, SIGNAL(cellClicked(int,int)), this, SLOT(slotTableWidgetLocationCellClicked(int,int)) ); +} + +void CAlarmStatistics::initBar() +{ + m_pChart = new QChart(); + m_pChart->setContentsMargins( 0,0,0,0 ); + m_pChart->setMargins(QMargins(0,0,0,0)); + m_pChart->setBackgroundRoundness( 0 ); + m_pChart->legend()->setVisible(false); + m_pChart->setBackgroundBrush( QBrush(QColor(3,22,36)) ); + + QChartView *pChartView = new QChartView( ui->frame_bar ); + pChartView->setChart( m_pChart ); + pChartView->setRenderHint(QPainter::Antialiasing); + pChartView->setMinimumHeight( 200 ); + QLayout* pLayout = ui->frame_bar->layout(); + pLayout->addWidget( pChartView ); + ui->frame_bar->setLayout( pLayout ); +} + +void CAlarmStatistics::initLevelChoose() +{ + for ( int i=0; im_listAlarmLevel.count(); i++ ) + { + SAlarmLevel* pAlarmLevel = m_pQueryThread->m_listAlarmLevel.at(i); + QCheckBox* pCheckBox = new QCheckBox( pAlarmLevel->sName ); + pCheckBox->setObjectName( QString("checkBox_level%1").arg(pAlarmLevel->nPriority) ); + pCheckBox->setProperty( "id", pAlarmLevel->nId ); + pCheckBox->setChecked( true ); + ui->horizontalLayout_2->addWidget( pCheckBox ); + if ( i < m_pQueryThread->m_listAlarmLevelColor.count() ) + { + QColor tmpColor = m_pQueryThread->m_listAlarmLevelColor.at(i); + pCheckBox->setStyleSheet( QString("QCheckBox::indicator:checked{background-color: rgb(%1,%2,%3);}") + .arg(tmpColor.red()).arg(tmpColor.green()).arg(tmpColor.blue()) ); + } + m_listAlarmLevelCheckBox.append( pCheckBox ); + connect( pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxStateChanged(int)) ); + } +} + +void CAlarmStatistics::loadData() +{ + for ( int i=0; im_listLocation.count(); i++ ) + ui->comboBox_location->addItem( m_pQueryThread->m_listLocation.at(i)->sName, m_pQueryThread->m_listLocation.at(i)->nId ); + + m_pAlarmLevelComboBox->init( m_pQueryThread->m_listAlarmLevel ); + +// qint64 time = QDateTime::currentMSecsSinceEpoch(); +// //qint64 timee = time +1000ll*86400*30*12; +// qint64 timee = time +1000ll*86400; + +// qint64 ts = QDateTime::currentMSecsSinceEpoch(); +// int nCount = 0; +// QString sSmartUuid = ""; +// while (timem_pDbInterface->execute(sSql) ) +// { +// qDebug()<m_pDbInterface->getErrMsg(); +// break; +// } +// } + +// QString sSql = QString("insert into his_event_di_change values(%1,%2,%3,%4,%5,%6,'%7',%8,%9,%10,'%11',%12,%13,'%14','%15','%16','%17')") +// .arg(2).arg(112).arg(time).arg(1) +// .arg(1)//位置 +// .arg(4).arg("C相电压 230.00kV 越上上限") +// .arg(l)//优先级 +// .arg(146).arg(1) +// .arg("analog.QHB.302JGXX620Xinst256.VC.value").arg(0).arg(0).arg("") +// .arg("station1.pcs4") +// .arg(sNormalUuid) +// .arg(sSmartUuid);//间隔 +// time = time + 2000; +// if ( 0 != m_pQueryThread->m_pDbInterface->execute(sSql) ) +// { +// qDebug()<m_pDbInterface->getErrMsg(); +// break; +// } +// nCount++; +// if ( nCount % 100000 == 0 ) +// { +// qDebug()<m_pDbInterface->execute(sSql) ) +// { +// qDebug()<m_pDbInterface->getErrMsg(); +// break; +// } +// nCount++; +// if ( nCount % 50000 == 0 ) +// { +// qDebug()<hide();//进行隐藏 + return; + } + + QString sShow = ""; + if ( pBarset->label().startsWith("normal") ) + { + sShow = "普通告警\n"; + for ( int i=0; im_listAlarmLevel.count(); i++ ) + { + sShow = sShow + m_pQueryThread->m_listAlarmLevel.at(i)->sName + " : " + QString::number(m_listBarSetNormal.at(i)->at(nIndex)); + if ( i != m_pQueryThread->m_listAlarmLevel.count() - 1 ) + sShow += "\n"; + } + } + if ( pBarset->label().startsWith("smart") ) + { + sShow = "智能告警\n"; + for ( int i=0; im_listAlarmLevel.count(); i++ ) + { + sShow = sShow + m_pQueryThread->m_listAlarmLevel.at(i)->sName + " : " + QString::number(m_listBarSetSmart.at(i)->at(nIndex)); + if ( i != m_pQueryThread->m_listAlarmLevel.count() - 1 ) + sShow += "\n"; + } + } + + m_pLabelValue->setText( sShow ); + QPoint curPos = mapFromGlobal( QCursor::pos() ); + m_pLabelValue->move( curPos.x()-100, curPos.y()+10 );//移动数值 + m_pLabelValue->show();//显示出来 + m_pLabelValue->adjustSize(); +} + +void CAlarmStatistics::slotBarClicked( int nIndex, QBarSet* pBarset ) +{ + m_pQueryThread->m_pAlarmModel->beginReset(); + m_pQueryThread->m_pAlarmModel->clearAlarmList(); + m_pQueryThread->m_pAlarmModel->endReset(); + + if ( pBarset->label().startsWith("normal") ) + { + ui->tableView_alarm->setColumnHidden( 4, false ); + m_pQueryThread->m_pAlarmModel->beginReset(); + m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarmNormal.at(nIndex)->listAlarmInfo ); + m_pQueryThread->m_pAlarmModel->endReset(); + resizeColumnsToContents( ui->tableView_alarm ); + if ( m_pQueryThread->m_listAlarmNormal.at(nIndex)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + { + QMessageBox::information( 0, "提示", QString("告警条数过多,仅显示前 %1 条").arg(CN_ALARMINFO_MAXROW) ); + m_bAfterMsgBox = true; + } + } + else + { + ui->tableView_alarm->setColumnHidden( 4, true ); + m_pQueryThread->m_pAlarmModel->beginReset(); + m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarmSmart.at(nIndex)->listAlarmInfo ); + m_pQueryThread->m_pAlarmModel->endReset(); + resizeColumnsToContents( ui->tableView_alarm ); + if ( m_pQueryThread->m_listAlarmSmart.at(nIndex)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + { + QMessageBox::information( 0, "提示", QString("告警条数过多,仅显示前 %1 条").arg(CN_ALARMINFO_MAXROW) ); + m_bAfterMsgBox = true; + } + + } + + ui->label_name->setText( m_pQueryThread->m_listAlarmNormal.at(nIndex)->sName ); +} + +void CAlarmStatistics::resetUi() +{ + // 清空左侧设备列表 + ui->tableWidget_location->clearContents(); + ui->tableWidget_location->setRowCount( 0 ); + + // 清空柱状图 + m_pChart->removeAllSeries(); + + // 清空查询线程 + m_pQueryThread->clear(); +} + +void CAlarmStatistics::resetBar() +{ + +} + +void CAlarmStatistics::showBar() +{ + // 清空柱状图 + m_pChart->removeAllSeries(); + + // 清空barset列表 + m_listBarSetNormal.clear(); + m_listBarSetSmart.clear(); + + if ( m_pQueryThread->m_listAlarmNormal.count() <= 0 ) + return; + + if ( m_pBarSeriesNormal != NULL ) + { + m_pBarSeriesNormal->clear(); + delete m_pBarSeriesNormal; + } + m_pBarSeriesNormal = new QStackedBarSeries(); + connect( m_pBarSeriesNormal, SIGNAL(hovered(bool,int,QBarSet*)), this, SLOT(slotBarMouseMoveHovered(bool,int,QBarSet*)) ); + connect( m_pBarSeriesNormal, SIGNAL(clicked(int,QBarSet*)), this, SLOT(slotBarClicked(int,QBarSet*)) ); + if ( m_pBarSeriesSmart != NULL ) + { + m_pBarSeriesSmart->clear(); + delete m_pBarSeriesSmart; + } + m_pBarSeriesSmart = new QStackedBarSeries(); + connect( m_pBarSeriesSmart, SIGNAL(hovered(bool,int,QBarSet*)), this, SLOT(slotBarMouseMoveHovered(bool,int,QBarSet*)) ); + connect( m_pBarSeriesSmart, SIGNAL(clicked(int,QBarSet*)), this, SLOT(slotBarClicked(int,QBarSet*)) ); + + for ( int i=0; im_listAlarmLevel.count(); i++ ) + { + QBarSet *pSet0 = new QBarSet(QString("normal_level%1").arg(i+1)); + m_listBarSetNormal.append( pSet0 ); + m_pBarSeriesNormal->append( pSet0 ); + QBarSet *pSet1 = new QBarSet(QString("smart_level%1").arg(i+1)); + m_listBarSetSmart.append( pSet1 ); + m_pBarSeriesSmart->append( pSet1 ); + } + + QBarCategoryAxis *pAxis = new QBarCategoryAxis(); + for ( int i=0; im_listAlarmNormal.count(); i++ ) + { + if ( i >= CN_MAXBARSERIES ) + break; + + SAlarmList* pAlarmList = m_pQueryThread->m_listAlarmNormal.at(i); + SAlarmList* pSmartAlarmList = m_pQueryThread->m_listAlarmSmart.at(i); + pAxis->append( pAlarmList->sName ); + for ( int l=0; llistLevelCount.count(); l++ ) + { + if ( m_listAlarmLevelCheckBox.at(l)->isChecked() ) + { + *m_listBarSetNormal[l] << pAlarmList->listLevelCount.at(l); + *m_listBarSetSmart[l] << pSmartAlarmList->listLevelCount.at(l); + } + else + { + *m_listBarSetNormal[l] << 0; + *m_listBarSetSmart[l] << 0; + } + } + } + + if ( ui->checkBox_alarm_normal->isChecked() ) + { + m_pChart->addSeries( m_pBarSeriesNormal ); + m_pBarSeriesNormal = NULL; + } + if ( ui->checkBox_alarm_smart->isChecked() ) + { + m_pChart->addSeries( m_pBarSeriesSmart ); + m_pBarSeriesSmart = NULL; + } + m_pChart->createDefaultAxes(); + m_pChart->setAxisX( pAxis ); + + if ( m_pChart->axisX() ) + { + m_pChart->axisX()->setLabelsBrush( QBrush(m_chartLabelColor)); + m_pChart->axisX()->setLinePenColor( m_chartLineColor); + m_pChart->axisX()->setGridLineVisible( false ); + } + if ( m_pChart->axisY() ) + { + m_pChart->axisY()->setLabelsBrush( QBrush(m_chartLabelColor)); + m_pChart->axisY()->setLinePenColor( m_chartLineColor); + m_pChart->axisY()->setGridLineVisible( false ); + } + + QList listSeries = m_pChart->series(); + for ( int i=0; i< listSeries.count(); i++ ) + { + QStackedBarSeries* pBarSeries = dynamic_cast(listSeries.at(i)); + if ( pBarSeries == NULL ) + continue; + QList listBar = pBarSeries->barSets(); + for ( int l=0; lsetBrush( QBrush(m_pQueryThread->m_listAlarmLevelColor.at(l)) ); + } +} + +QColor CAlarmStatistics::chartBackground() +{ + return m_chartBackground; +} + +void CAlarmStatistics::setChartBackground(const QColor& color) +{ + m_chartBackground = color; + + if(m_pChart != Q_NULLPTR) + { + m_pChart->setBackgroundBrush( QBrush(m_chartBackground) ); + } +} + +QColor CAlarmStatistics::chartLabelColor() +{ + return m_chartLabelColor; +} + +void CAlarmStatistics::setChartLabelColor(const QColor &color) +{ + m_chartLabelColor = color; + + if(m_pChart == Q_NULLPTR) + { + return; + } + if(m_pChart->axisX()) + { + m_pChart->axisX()->setLabelsBrush( QBrush(m_chartLabelColor)); + } + if(m_pChart->axisY()) + { + m_pChart->axisY()->setLabelsBrush( QBrush(m_chartLabelColor)); + } +} + +QColor CAlarmStatistics::chartLineColor() +{ + return m_chartLineColor; +} + +void CAlarmStatistics::setChartLineColor(const QColor &color) +{ + m_chartLineColor = color; + + if(m_pChart == Q_NULLPTR) + { + return; + } + if(m_pChart->axisX()) + { + m_pChart->axisX()->setLinePenColor( m_chartLineColor); + } + if(m_pChart->axisY()) + { + m_pChart->axisY()->setLinePenColor( m_chartLineColor); + } +} + +void CAlarmStatistics::slotPushButtonQueryClicked( bool ) +{ + // 没有查找到任何站信息 + if ( ui->comboBox_location->count() <= 1 ) + return; + + this->setCursor(Qt::WaitCursor); + m_pProcessDialog->reset(); + m_pProcessDialog->show(); + + // 清空界面 + resetUi(); + + // 清空线程 + m_pQueryThread->clear(); + + // 获取告警级别选择的字符串 + QList listLevelId; + m_pAlarmLevelComboBox->getSelectData( listLevelId ); + if ( listLevelId.count() <= 0 ) + { + m_pProcessDialog->hide(); + this->setCursor(Qt::ArrowCursor); + QMessageBox::warning( 0, tr("警告"), tr("未选择告警等级") ); + return; + } + for ( int i=0; im_sSelectedLevel = m_pQueryThread->m_sSelectedLevel + QString::number(listLevelId.at(i)) + ","; + m_pQueryThread->m_sSelectedLevel = m_pQueryThread->m_sSelectedLevel.left( m_pQueryThread->m_sSelectedLevel.count()-1 ); + + // 开始时间结束时间 + m_pQueryThread->m_nStartMs = ui->dateEdit_start->dateTime().toMSecsSinceEpoch(); + m_pQueryThread->m_nEndMs = ui->dateEdit_end->dateTime().addDays(1).toMSecsSinceEpoch(); + if ( ui->dateEdit_start->dateTime() > ui->dateEdit_end->dateTime() ) + { + m_pProcessDialog->hide(); + this->setCursor(Qt::ArrowCursor); + QMessageBox::warning( 0, tr("警告"), tr("开始时间需小于等于结束时间") ); + return; + } + + // 当前站 + m_pQueryThread->m_nCurrentLocationIndex = ui->comboBox_location->currentIndex(); + + // 关键字 + m_pQueryThread->m_sKeyWord = ui->lineEdit_keyWord->text(); + + // 开始在线程中查询 + m_pQueryThread->start(); +} + +void CAlarmStatistics::slotCheckBoxStateChanged( int ) +{ + showBar(); +} + +void CAlarmStatistics::slotQueryEnd() +{ + // 重新初始化左边的设备列表 + for ( int i=0; im_listAlarmNormal.count(); i++ ) + { + SAlarmList* pAlarmList = m_pQueryThread->m_listAlarmNormal.at(i); + SAlarmList* pSmartAlarmList = m_pQueryThread->m_listAlarmSmart.at(i); + QTableWidgetItem* pItem0 = new QTableWidgetItem( pAlarmList->sName ); + pItem0->setTextAlignment( Qt::AlignLeft | Qt::AlignVCenter ); + //pItem0->setData( Qt::UserRole, 1 ); + QTableWidgetItem* pItem1 = new QTableWidgetItem(); + pItem1->setTextAlignment( Qt::AlignCenter ); + pItem1->setText( QString::number(pAlarmList->getAllLevelAlarmCount()) + "/" + + QString::number(pSmartAlarmList->getAllLevelAlarmCount())); + if ( i < CN_MAXBARSERIES ) + pItem1->setTextColor( QColor(255,0,0) ); + else + pItem1->setTextColor( QColor(0,255,0) ); + ui->tableWidget_location->insertRow( i ); + ui->tableWidget_location->setItem( i, 0, pItem0 ); + ui->tableWidget_location->setItem( i, 1, pItem1 ); + } + + // 显示柱状图 + showBar(); + + // 显示告警详细信息 + if ( m_pQueryThread->m_listAlarmNormal.count() > 0 ) + { + m_pQueryThread->m_pAlarmModel->beginReset(); + m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarmNormal.at(0)->listAlarmInfo ); + m_pQueryThread->m_pAlarmModel->endReset(); + resizeColumnsToContents( ui->tableView_alarm ); + ui->label_name->setText( m_pQueryThread->m_listAlarmNormal.at(0)->sName ); + } + + m_pProcessDialog->hide(); + this->setCursor(Qt::ArrowCursor); + + if(m_pQueryThread->m_listAlarmNormal.count()>0) + { + if ( m_pQueryThread->m_listAlarmNormal.at(0)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + { + QMessageBox::information( 0, "提示", QString("告警条数过多,仅显示前 %1 条").arg(CN_ALARMINFO_MAXROW) ); + } + } + else + { + QMessageBox::information( 0, "提示", QString("当前条件没有查到告警信息!") ); + } + return; +} + +void CAlarmStatistics::slotPushButtonCompareClicked( bool ) +{ + m_pAlarmCompare->setCurrentLocationIndex( ui->comboBox_location->currentIndex() ); + m_pAlarmCompare->show(); +} + +void CAlarmStatistics::slotTableViewAlarmClicked( const QModelIndex& index ) +{ + int nRow = index.row(); + int nCol = index.column(); + if ( nRow < 0 || nCol < 0 || nCol != 4 ) + return; + + QString sType = m_pQueryThread->m_pAlarmModel->data(index).toString();// 趋势 or 录波 + qint64 nTimeMs = QDateTime::fromString(m_pQueryThread->m_pAlarmModel->m_listAlarm.at(nRow)->sTime,"yyyy-MM-dd hh:mm:ss.zzz").toMSecsSinceEpoch(); + QString sKeyIdTag = m_pQueryThread->m_pAlarmModel->m_listAlarm.at(nRow)->sKeyIdTag; + + QStringList listKeyIdTag = sKeyIdTag.split("."); + if ( listKeyIdTag.count() != 5 ) + { + //QMessageBox::critical( 0, "错误", "历史表KEY_ID_TAG解析错误" ); + return; + } + listKeyIdTag.pop_front(); + listKeyIdTag.pop_back(); + QString sAppTagName = listKeyIdTag.join("."); + + if ( sType == "录波" ) + { + QString sPath = ""; + QString sErrorMsg = ""; + m_pQueryThread->getWavePath( sAppTagName, sPath, sErrorMsg ); + if ( sErrorMsg != "" ) + { + QMessageBox::critical( 0, "错误", sErrorMsg ); + return; + } + QDir dir( sPath ); + if ( !dir.exists() ) + { + QMessageBox::critical( 0, "错误", QString("文件夹 %1 不存在").arg(sPath) ); + return; + } + sPath = dir.absolutePath(); + QStringList listNameFilter; + listNameFilter << "*.cfg"; + QStringList listFile = dir.entryList(listNameFilter, QDir::Files|QDir::Readable, QDir::Name); //获取录波文件LIST + + if(listFile.count()>0) + { + m_pWageListDialog->clear(); + m_pWageListDialog->addFileNameList( sPath, listFile ); + m_pWageListDialog->show(); + } + else + { + QMessageBox::information( 0, "提示", QString("文件夹 '%1' 当前无录波文件!").arg(sPath) ); + return; + } + + } + else if ( sType == "趋势" ) + { + emit signalShowYCHistoryData( sAppTagName, nTimeMs ); + } + else + { + QMessageBox::critical( 0, "错误", "类型不正确" ); + } +} + +void CAlarmStatistics::slotPushButtonReportClicked( bool ) +{ + m_pAlarmReport->initData( ui->tableWidget_location ); + m_pAlarmReport->show(); +} + +void CAlarmStatistics::slotTableWidgetLocationCellClicked( int nRow, int ) +{// 左侧设备树点击后显示该设备的普通告警 + if ( m_nLastRow == nRow ) + return; + else + m_nLastRow = nRow; + + m_pQueryThread->m_pAlarmModel->beginReset(); + m_pQueryThread->m_pAlarmModel->clearAlarmList(); + m_pQueryThread->m_pAlarmModel->endReset(); + + ui->tableView_alarm->setColumnHidden( 4, false ); + m_pQueryThread->m_pAlarmModel->beginReset(); + m_pQueryThread->m_pAlarmModel->setAlarmList( m_pQueryThread->m_listAlarmNormal.at(nRow)->listAlarmInfo ); + m_pQueryThread->m_pAlarmModel->endReset(); + resizeColumnsToContents( ui->tableView_alarm ); + if ( m_pQueryThread->m_listAlarmNormal.at(nRow)->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + { + QMessageBox::information( 0, "提示", QString("告警条数过多,仅显示前 %1 条").arg(CN_ALARMINFO_MAXROW) ); + } + + ui->label_name->setText( m_pQueryThread->m_listAlarmNormal.at(nRow)->sName ); +} + +void CAlarmStatistics::slotSetHiddenReport(bool hide) +{ + ui->pushButton_report->setHidden(hide); +} + +void CAlarmStatistics::slotSetHiddenOptColumn(bool hide) +{ + if(m_pQueryThread) + { + m_pQueryThread->setHiddenOptColumn(hide); + } + if(m_pAlarmCompare) + { + m_pAlarmCompare->setHiddenOptColumn(hide); + } +} + +void CAlarmStatistics::resizeEvent( QResizeEvent* ) +{ + resizeColumnsToContents( ui->tableView_alarm ); +} + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.h index 28c18c2c..91dccd46 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.h @@ -1,119 +1,119 @@ -#ifndef CALARMSTATISTICS_H -#define CALARMSTATISTICS_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CAlarmModel.h" -#include "CAlarmLevelComboBox.h" -#include "SAlarmLevel.h" -#include "CProcessDialog.h" -#include "CStatisticsQueryThread.h" -#include "CAlarmCompare.h" -#include "CWaveListDialog.h" -#include "CAlarmStatisticsPluginWidget.h" -#include "CAlarmReport.h" - -QT_CHARTS_USE_NAMESPACE - -namespace Ui { -class CAlarmStatistics; -} - -class CAlarmStatistics : public CAlarmStatisticsPluginWidget -{ - Q_OBJECT - Q_PROPERTY(QColor chartBackground READ chartBackground WRITE setChartBackground) - Q_PROPERTY(QColor chartLabelColor READ chartLabelColor WRITE setChartLabelColor) - Q_PROPERTY(QColor chartLineColor READ chartLineColor WRITE setChartLineColor) -public: - explicit CAlarmStatistics(QWidget *parent = 0, bool editMode = true); - ~CAlarmStatistics(); - -public: - void initialize( int nMode ); - void initVariate(); - void initUi(); - void initBar(); - void initLevelChoose(); - void loadData(); - void resetUi(); - void resetBar(); - void showBar(); - - QColor chartBackground(); - void setChartBackground(const QColor& color); - - QColor chartLabelColor(); - void setChartLabelColor(const QColor& color); - - QColor chartLineColor(); - void setChartLineColor(const QColor& color); - -public slots: - void slotBarMouseMoveHovered( bool bStatus, int nIndex, QBarSet* pBarset ); - void slotBarClicked( int nIndex, QBarSet* pBarset ); - void slotCheckBoxStateChanged( int ); - void slotQueryEnd(); - void slotPushButtonQueryClicked( bool bChecked = false ); - void slotPushButtonCompareClicked( bool bChecked = false ); - void slotTableViewAlarmClicked( const QModelIndex& index ); - void slotPushButtonReportClicked( bool bCheaked = false ); - void slotTableWidgetLocationCellClicked( int nRow, int nColumn ); - void slotSetHiddenReport(bool hide); - void slotSetHiddenOptColumn(bool hide); - -signals: - void signalShowYCHistoryData( QString sYCTagName, qint64 nDateTimeMs ); - -protected: - void resizeEvent( QResizeEvent* pEvent ); - -private: - bool m_bEditMode;// 是否编辑态 - bool m_bAfterMsgBox;// 是否是在弹出告警条数过多之后第一次进入显示提示窗口的函数 - - int m_nLastRow; - - Ui::CAlarmStatistics *ui; - CStatisticsQueryThread* m_pQueryThread;// 查询数据线程 - QChart *m_pChart;// 柱状图 - QLabel* m_pLabelValue;// 鼠标移动到柱状图上显示的提示窗口 - QList m_listBarSetNormal; - QList m_listBarSetSmart; - CAlarmLevelComboBox* m_pAlarmLevelComboBox;// 告警级别选择的下拉框 - QList m_listAlarmLevelCheckBox;// 柱状图告警等级选择的复选框集合 - CProcessDialog* m_pProcessDialog;// 等待窗口 - CAlarmCompare* m_pAlarmCompare;// 告警比对窗口 - CAlarmReport* m_pAlarmReport;// 告警比对窗口 - CWaveListDialog* m_pWageListDialog;// 录波文件列表框 - - QStackedBarSeries* m_pBarSeriesNormal; - QStackedBarSeries* m_pBarSeriesSmart; - - QColor m_chartBackground; - QColor m_chartLabelColor; - QColor m_chartLineColor; -}; - -#endif // CALARMSTATISTICS_H +#ifndef CALARMSTATISTICS_H +#define CALARMSTATISTICS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmModel.h" +#include "CAlarmLevelComboBox.h" +#include "SAlarmLevel.h" +#include "CProcessDialog.h" +#include "CStatisticsQueryThread.h" +#include "CAlarmCompare.h" +#include "CWaveListDialog.h" +#include "CAlarmStatisticsPluginWidget.h" +#include "CAlarmReport.h" + +QT_CHARTS_USE_NAMESPACE + +namespace Ui { +class CAlarmStatistics; +} + +class CAlarmStatistics : public CAlarmStatisticsPluginWidget +{ + Q_OBJECT + Q_PROPERTY(QColor chartBackground READ chartBackground WRITE setChartBackground) + Q_PROPERTY(QColor chartLabelColor READ chartLabelColor WRITE setChartLabelColor) + Q_PROPERTY(QColor chartLineColor READ chartLineColor WRITE setChartLineColor) +public: + explicit CAlarmStatistics(QWidget *parent = 0, bool editMode = true); + ~CAlarmStatistics(); + +public: + void initialize( int nMode ); + void initVariate(); + void initUi(); + void initBar(); + void initLevelChoose(); + void loadData(); + void resetUi(); + void resetBar(); + void showBar(); + + QColor chartBackground(); + void setChartBackground(const QColor& color); + + QColor chartLabelColor(); + void setChartLabelColor(const QColor& color); + + QColor chartLineColor(); + void setChartLineColor(const QColor& color); + +public slots: + void slotBarMouseMoveHovered( bool bStatus, int nIndex, QBarSet* pBarset ); + void slotBarClicked( int nIndex, QBarSet* pBarset ); + void slotCheckBoxStateChanged( int ); + void slotQueryEnd(); + void slotPushButtonQueryClicked( bool bChecked = false ); + void slotPushButtonCompareClicked( bool bChecked = false ); + void slotTableViewAlarmClicked( const QModelIndex& index ); + void slotPushButtonReportClicked( bool bCheaked = false ); + void slotTableWidgetLocationCellClicked( int nRow, int nColumn ); + void slotSetHiddenReport(bool hide); + void slotSetHiddenOptColumn(bool hide); + +signals: + void signalShowYCHistoryData( QString sYCTagName, qint64 nDateTimeMs ); + +protected: + void resizeEvent( QResizeEvent* pEvent ); + +private: + bool m_bEditMode;// 是否编辑态 + bool m_bAfterMsgBox;// 是否是在弹出告警条数过多之后第一次进入显示提示窗口的函数 + + int m_nLastRow; + + Ui::CAlarmStatistics *ui; + CStatisticsQueryThread* m_pQueryThread;// 查询数据线程 + QChart *m_pChart;// 柱状图 + QLabel* m_pLabelValue;// 鼠标移动到柱状图上显示的提示窗口 + QList m_listBarSetNormal; + QList m_listBarSetSmart; + CAlarmLevelComboBox* m_pAlarmLevelComboBox;// 告警级别选择的下拉框 + QList m_listAlarmLevelCheckBox;// 柱状图告警等级选择的复选框集合 + CProcessDialog* m_pProcessDialog;// 等待窗口 + CAlarmCompare* m_pAlarmCompare;// 告警比对窗口 + CAlarmReport* m_pAlarmReport;// 告警比对窗口 + CWaveListDialog* m_pWageListDialog;// 录波文件列表框 + + QStackedBarSeries* m_pBarSeriesNormal; + QStackedBarSeries* m_pBarSeriesSmart; + + QColor m_chartBackground; + QColor m_chartLabelColor; + QColor m_chartLineColor; +}; + +#endif // CALARMSTATISTICS_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.ui b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.ui index c4679eea..ad73d100 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.ui +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.ui @@ -1,451 +1,451 @@ - - - CAlarmStatistics - - - - 0 - 0 - 989 - 641 - - - - CAlarmStatistics - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 0 - 24 - - - - 位置 - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - 告警等级 - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - 时间段 - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - yyyy-MM-dd - - - true - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - yyyy-MM-dd - - - true - - - - - - - - 0 - 24 - - - - 告警内容关键字 - - - - - - - 查询 - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - Qt::Horizontal - - - - - Qt::Vertical - - - - QFrame::Box - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 4 - - - 9 - - - 9 - - - 9 - - - - - 普通告警 - - - - - - - 智能告警 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - 0 - 24 - - - - - - - - - - - Qt::Horizontal - - - - 40 - 24 - - - - - - - - - 0 - 0 - - - - - 80 - 24 - - - - 告警比对 - - - - - - - - 0 - 0 - - - - - 80 - 24 - - - - 分析报告 - - - - - - - - - 22 - - - 33 - - - - - - - - - - - - - - - - - - - - - CTableWidget - QTableWidget -
CTableWidget.h
-
- - CTableView - QTableView -
CTableWidget.h
-
-
- - -
+ + + CAlarmStatistics + + + + 0 + 0 + 989 + 641 + + + + CAlarmStatistics + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 位置 + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 告警等级 + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 时间段 + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + yyyy-MM-dd + + + true + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + - + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + yyyy-MM-dd + + + true + + + + + + + + 0 + 24 + + + + 告警内容关键字 + + + + + + + 查询 + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + + + Qt::Vertical + + + + QFrame::Box + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 4 + + + 9 + + + 9 + + + 9 + + + + + 普通告警 + + + + + + + 智能告警 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + 24 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 24 + + + + + + + + + 0 + 0 + + + + + 80 + 24 + + + + 告警比对 + + + + + + + + 0 + 0 + + + + + 80 + 24 + + + + 分析报告 + + + + + + + + + 22 + + + 33 + + + + + + + + + + + + + + + + + + + + + CTableWidget + QTableWidget +
CTableWidget.h
+
+ + CTableView + QTableView +
CTableWidget.h
+
+
+ + +
diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.cpp index cd7fc317..adc4ad1a 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.cpp @@ -1,28 +1,28 @@ -#include -#include "CAlarmStatisticsPluginWidget.h" -#include "CAlarmStatistics.h" - -CAlarmStatisticsPluginWidget::CAlarmStatisticsPluginWidget(QWidget *parent): QWidget(parent) -{ - -} - -CAlarmStatisticsPluginWidget::~CAlarmStatisticsPluginWidget() -{ - -} - -bool CAlarmStatisticsPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CAlarmStatistics *pWidget = new CAlarmStatistics(parent, editMode); - //pWidget->initialize((int)E_Alarm_Dock); - *widget = (QWidget *)pWidget; - *alarmWidget = (IPluginWidget *)pWidget; - return true; -} - -void CAlarmStatisticsPluginWidget::release() -{ - -} +#include +#include "CAlarmStatisticsPluginWidget.h" +#include "CAlarmStatistics.h" + +CAlarmStatisticsPluginWidget::CAlarmStatisticsPluginWidget(QWidget *parent): QWidget(parent) +{ + +} + +CAlarmStatisticsPluginWidget::~CAlarmStatisticsPluginWidget() +{ + +} + +bool CAlarmStatisticsPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CAlarmStatistics *pWidget = new CAlarmStatistics(parent, editMode); + //pWidget->initialize((int)E_Alarm_Dock); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + return true; +} + +void CAlarmStatisticsPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.h index ebe3aa2c..5876e1bd 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.h @@ -1,29 +1,29 @@ -#ifndef CALARMSTATISTICSPLUGINWIDGET_H -#define CALARMSTATISTICSPLUGINWIDGET_H - -#include -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CAlarmStatisticsPluginWidget : public QWidget, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CAlarmStatisticsPluginWidget(QWidget *parent = 0); - ~CAlarmStatisticsPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); - void release(); -}; - -#endif //CALARMSTATISTICSPLUGINWIDGET_H - - - - - - - +#ifndef CALARMSTATISTICSPLUGINWIDGET_H +#define CALARMSTATISTICSPLUGINWIDGET_H + +#include +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CAlarmStatisticsPluginWidget : public QWidget, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CAlarmStatisticsPluginWidget(QWidget *parent = 0); + ~CAlarmStatisticsPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif //CALARMSTATISTICSPLUGINWIDGET_H + + + + + + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CCompareQueryThread.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CCompareQueryThread.cpp index d4bbc48a..2dadb1f9 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CCompareQueryThread.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CCompareQueryThread.cpp @@ -1,267 +1,267 @@ -#include "CCompareQueryThread.h" - -using namespace kbd_public; -using namespace kbd_dbms; - -CCompareQueryThread::CCompareQueryThread() -{ - initVariate(); - loadData(); - clear(); -} - -CCompareQueryThread::~CCompareQueryThread() -{ - delete m_pDb; - m_pDb = NULL; - - delete m_pAlarmModel; - m_pAlarmModel = NULL; - - qDeleteAll( m_listAlarmLevel ); - m_listAlarmLevel.clear(); -} - -void CCompareQueryThread::setHiddenOptColumn(bool hide) -{ - if(m_pAlarmModel) - { - m_pAlarmModel->setHiddenOptColumn(hide); - } -} - -void CCompareQueryThread::initVariate() -{ - m_pAlarmModel = new CAlarmModel(); - - m_listAlarmLevelColor.push_back( QColor(255,0,0) ); - m_listAlarmLevelColor.push_back( QColor(255,116,20) ); - m_listAlarmLevelColor.push_back( QColor(187,226,66) ); - m_listAlarmLevelColor.push_back( QColor(144,230,189) ); - m_listAlarmLevelColor.push_back( QColor(244,228,151) ); - - m_nLastId = -1; - m_nLastIndex = -1; -} - -void CCompareQueryThread::loadData() -{ - m_pDb = new CDbApi(DB_CONN_MODEL_READ); - if ( m_pDb->open() ) - { - LOGINFO("initialize and open database success!"); - } - else - { - LOGERROR("initialize or open database failed!"); - return; - } - - LOGINFO("DatabaseName: [%s]", m_pDb->getCurrentDbPara().getDatabaseName().toStdString().c_str()); - LOGINFO("HostName: [%s]", m_pDb->getCurrentDbPara().getHostName().toStdString().c_str()); - LOGINFO("UserName: [%s]", m_pDb->getCurrentDbPara().getUserName().toStdString().c_str()); - - // 查询位置信息 - QSqlQuery query; - QString sSql = "select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"; - m_pDb->execute(sSql, query); - while( query.next() ) - { - SLocation* pLocation = new SLocation; - pLocation->nId = query.value(0).toInt(); - pLocation->sName = query.value(1).toString(); - m_listLocation << pLocation; - } - query.clear(); - - // 查询设备组信息 - for ( int i=0; inId ); - m_pDb->execute(sSql, query); - while( query.next() ) - { - SDeviceGroup* pDeviceGroup = new SDeviceGroup; - pDeviceGroup->sTagName = query.value(0).toString(); - pDeviceGroup->sName = query.value(1).toString(); - m_listLocation[i]->listDeviceGroup << pDeviceGroup; - } - query.clear(); - } - - // 查询告警等级信息 - sSql = "select PRIORITY_ID,PRIORITY_ORDER,PRIORITY_NAME from alarm_level_define order by PRIORITY_ORDER"; - m_pDb->execute(sSql, query); - while( query.next() ) - { - SAlarmLevel* pAlarmLevel = new SAlarmLevel; - pAlarmLevel->nId = query.value(0).toInt(); - pAlarmLevel->nPriority = query.value(1).toInt(); - pAlarmLevel->sName = query.value(2).toString(); - m_listAlarmLevel.append( pAlarmLevel ); - } - query.clear(); -} - -void CCompareQueryThread::clear() -{ - m_bCancel = false; - m_nCurrentLocationIndex = 0; - m_nStartMs = 0; - m_nEndMs = 0; - m_sSelectedLevel = ""; - - // 清空告警显示 - m_pAlarmModel->beginReset(); - m_pAlarmModel->clearAlarmList(); - m_pAlarmModel->endReset(); - - // 清空告警详细信息 - for ( int i=0; i tmpListAlarm; - for ( int l=0; llistLevelCount.count() < m_listAlarmLevel.count() ) - pAlarmList->listLevelCount.append(0); - tmpListAlarm.append( pAlarmList ); - if ( m_eDateType == EN_DateType_Day ) - pAlarmList->sName = QDateTime::fromMSecsSinceEpoch(m_listTimePoint.at(l)).toString("yyyy-MM-dd"); - else if ( m_eDateType == EN_DateType_Month ) - pAlarmList->sName = QDateTime::fromMSecsSinceEpoch(m_listTimePoint.at(l)).toString("yyyy-MM"); - - QSqlQuery query; - QString sSql = ""; - if ( m_nCurrentLocationIndex == 0 ) - { - pAlarmList->nId = pCheckBox->property("id").toInt(); - sSql = QString("select TIME_STAMP,PRIORITY,CONTENT from %1 \ - where TIME_STAMP between %2 and %3 and LOCATION_ID=%4 and PRIORITY in(%5) \ - order by TIME_STAMP") - .arg(CN_NORMALALARMTABLE).arg(m_listTimePoint.at(l)) - .arg(m_listTimePoint.at(l+1)).arg(pAlarmList->nId).arg(m_sSelectedLevel); - } - else - { - pAlarmList->sTagName = pCheckBox->property("id").toString(); - sSql = QString("select TIME_STAMP,PRIORITY,CONTENT from %1 \ - where TIME_STAMP between %2 and %3 and DEV_GROUP_TAG='%4' and PRIORITY in(%5) \ - order by TIME_STAMP") - .arg(CN_NORMALALARMTABLE).arg(m_listTimePoint.at(l)) - .arg(m_listTimePoint.at(l+1)).arg(pAlarmList->sTagName).arg(m_sSelectedLevel); - } - m_pDb->execute(sSql, query); - while( query.next() ) - { - if ( m_bCancel ) - break; - - // 有关键字 - if ( m_sKeyWord != "" ) - { - if ( !query.value(2).toString().contains(m_sKeyWord) ) - continue; - } - - SAlarmLevel* pAlarmLevel = NULL; - int nLevelIndex = getAlarmLevelIndexById( query.value(1).toInt(), pAlarmLevel ); - if ( nLevelIndex < 0 ) - continue; - - pAlarmList->listLevelCount[nLevelIndex]++; - if ( pAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - continue; - - SAlarmInfo* pAlarmInfo = new SAlarmInfo; - pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); - pAlarmInfo->sLevel = pAlarmLevel->sName; - pAlarmInfo->sLocation = pCheckBox->text(); - pAlarmInfo->sContent = query.value(2).toString(); - pAlarmList->listAlarmInfo.append( pAlarmInfo ); - } - signalQueryPercent( l*100/(m_listTimePoint.count()-1)/m_listCheckBox.count() - + i*100/m_listCheckBox.count() ); - query.clear(); - } - m_listAlarm << tmpListAlarm; - } - - // 发送查询完成信号 - signalQueryEnd(); -} - -int CCompareQueryThread::getAlarmLevelIndexById( int nId, SAlarmLevel* &pAlarmLevel ) -{ - if ( m_nLastId == nId && m_nLastIndex >= 0 ) - { - pAlarmLevel = m_listAlarmLevel.at(m_nLastIndex); - return m_nLastIndex; - } - - m_nLastId = nId; - for ( int i=0; inId == nId ) - { - m_nLastIndex = i; - pAlarmLevel = m_listAlarmLevel.at(i); - break; - } - } - return m_nLastIndex; -} - - +#include "CCompareQueryThread.h" + +using namespace kbd_public; +using namespace kbd_dbms; + +CCompareQueryThread::CCompareQueryThread() +{ + initVariate(); + loadData(); + clear(); +} + +CCompareQueryThread::~CCompareQueryThread() +{ + delete m_pDb; + m_pDb = NULL; + + delete m_pAlarmModel; + m_pAlarmModel = NULL; + + qDeleteAll( m_listAlarmLevel ); + m_listAlarmLevel.clear(); +} + +void CCompareQueryThread::setHiddenOptColumn(bool hide) +{ + if(m_pAlarmModel) + { + m_pAlarmModel->setHiddenOptColumn(hide); + } +} + +void CCompareQueryThread::initVariate() +{ + m_pAlarmModel = new CAlarmModel(); + + m_listAlarmLevelColor.push_back( QColor(255,0,0) ); + m_listAlarmLevelColor.push_back( QColor(255,116,20) ); + m_listAlarmLevelColor.push_back( QColor(187,226,66) ); + m_listAlarmLevelColor.push_back( QColor(144,230,189) ); + m_listAlarmLevelColor.push_back( QColor(244,228,151) ); + + m_nLastId = -1; + m_nLastIndex = -1; +} + +void CCompareQueryThread::loadData() +{ + m_pDb = new CDbApi(DB_CONN_MODEL_READ); + if ( m_pDb->open() ) + { + LOGINFO("initialize and open database success!"); + } + else + { + LOGERROR("initialize or open database failed!"); + return; + } + + LOGINFO("DatabaseName: [%s]", m_pDb->getCurrentDbPara().getDatabaseName().toStdString().c_str()); + LOGINFO("HostName: [%s]", m_pDb->getCurrentDbPara().getHostName().toStdString().c_str()); + LOGINFO("UserName: [%s]", m_pDb->getCurrentDbPara().getUserName().toStdString().c_str()); + + // 查询位置信息 + QSqlQuery query; + QString sSql = "select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"; + m_pDb->execute(sSql, query); + while( query.next() ) + { + SLocation* pLocation = new SLocation; + pLocation->nId = query.value(0).toInt(); + pLocation->sName = query.value(1).toString(); + m_listLocation << pLocation; + } + query.clear(); + + // 查询设备组信息 + for ( int i=0; inId ); + m_pDb->execute(sSql, query); + while( query.next() ) + { + SDeviceGroup* pDeviceGroup = new SDeviceGroup; + pDeviceGroup->sTagName = query.value(0).toString(); + pDeviceGroup->sName = query.value(1).toString(); + m_listLocation[i]->listDeviceGroup << pDeviceGroup; + } + query.clear(); + } + + // 查询告警等级信息 + sSql = "select PRIORITY_ID,PRIORITY_ORDER,PRIORITY_NAME from alarm_level_define order by PRIORITY_ORDER"; + m_pDb->execute(sSql, query); + while( query.next() ) + { + SAlarmLevel* pAlarmLevel = new SAlarmLevel; + pAlarmLevel->nId = query.value(0).toInt(); + pAlarmLevel->nPriority = query.value(1).toInt(); + pAlarmLevel->sName = query.value(2).toString(); + m_listAlarmLevel.append( pAlarmLevel ); + } + query.clear(); +} + +void CCompareQueryThread::clear() +{ + m_bCancel = false; + m_nCurrentLocationIndex = 0; + m_nStartMs = 0; + m_nEndMs = 0; + m_sSelectedLevel = ""; + + // 清空告警显示 + m_pAlarmModel->beginReset(); + m_pAlarmModel->clearAlarmList(); + m_pAlarmModel->endReset(); + + // 清空告警详细信息 + for ( int i=0; i tmpListAlarm; + for ( int l=0; llistLevelCount.count() < m_listAlarmLevel.count() ) + pAlarmList->listLevelCount.append(0); + tmpListAlarm.append( pAlarmList ); + if ( m_eDateType == EN_DateType_Day ) + pAlarmList->sName = QDateTime::fromMSecsSinceEpoch(m_listTimePoint.at(l)).toString("yyyy-MM-dd"); + else if ( m_eDateType == EN_DateType_Month ) + pAlarmList->sName = QDateTime::fromMSecsSinceEpoch(m_listTimePoint.at(l)).toString("yyyy-MM"); + + QSqlQuery query; + QString sSql = ""; + if ( m_nCurrentLocationIndex == 0 ) + { + pAlarmList->nId = pCheckBox->property("id").toInt(); + sSql = QString("select TIME_STAMP,PRIORITY,CONTENT from %1 \ + where TIME_STAMP between %2 and %3 and LOCATION_ID=%4 and PRIORITY in(%5) \ + order by TIME_STAMP") + .arg(CN_NORMALALARMTABLE).arg(m_listTimePoint.at(l)) + .arg(m_listTimePoint.at(l+1)).arg(pAlarmList->nId).arg(m_sSelectedLevel); + } + else + { + pAlarmList->sTagName = pCheckBox->property("id").toString(); + sSql = QString("select TIME_STAMP,PRIORITY,CONTENT from %1 \ + where TIME_STAMP between %2 and %3 and DEV_GROUP_TAG='%4' and PRIORITY in(%5) \ + order by TIME_STAMP") + .arg(CN_NORMALALARMTABLE).arg(m_listTimePoint.at(l)) + .arg(m_listTimePoint.at(l+1)).arg(pAlarmList->sTagName).arg(m_sSelectedLevel); + } + m_pDb->execute(sSql, query); + while( query.next() ) + { + if ( m_bCancel ) + break; + + // 有关键字 + if ( m_sKeyWord != "" ) + { + if ( !query.value(2).toString().contains(m_sKeyWord) ) + continue; + } + + SAlarmLevel* pAlarmLevel = NULL; + int nLevelIndex = getAlarmLevelIndexById( query.value(1).toInt(), pAlarmLevel ); + if ( nLevelIndex < 0 ) + continue; + + pAlarmList->listLevelCount[nLevelIndex]++; + if ( pAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + continue; + + SAlarmInfo* pAlarmInfo = new SAlarmInfo; + pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); + pAlarmInfo->sLevel = pAlarmLevel->sName; + pAlarmInfo->sLocation = pCheckBox->text(); + pAlarmInfo->sContent = query.value(2).toString(); + pAlarmList->listAlarmInfo.append( pAlarmInfo ); + } + signalQueryPercent( l*100/(m_listTimePoint.count()-1)/m_listCheckBox.count() + + i*100/m_listCheckBox.count() ); + query.clear(); + } + m_listAlarm << tmpListAlarm; + } + + // 发送查询完成信号 + signalQueryEnd(); +} + +int CCompareQueryThread::getAlarmLevelIndexById( int nId, SAlarmLevel* &pAlarmLevel ) +{ + if ( m_nLastId == nId && m_nLastIndex >= 0 ) + { + pAlarmLevel = m_listAlarmLevel.at(m_nLastIndex); + return m_nLastIndex; + } + + m_nLastId = nId; + for ( int i=0; inId == nId ) + { + m_nLastIndex = i; + pAlarmLevel = m_listAlarmLevel.at(i); + break; + } + } + return m_nLastIndex; +} + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CCompareQueryThread.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CCompareQueryThread.h index d53927be..fec33c2c 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CCompareQueryThread.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CCompareQueryThread.h @@ -1,70 +1,70 @@ -#ifndef CCOMPAREQUERYTHREAD_H -#define CCOMPAREQUERYTHREAD_H - -#include -#include -#include -#include -#include -#include "CommonDefine.h" -#include "pub_logger_api/logger.h" -#include "db_sysinfo_api/CDbSysInfo.h" -#include "db_api_ex/CDbApi.h" -#include "CAlarmModel.h" -#include "SAlarmLevel.h" -#include "SLocation.h" - -class CCompareQueryThread : public QThread -{ - Q_OBJECT - -public: - enum EN_DateType - { - EN_DateType_Day = 0, - EN_DateType_Month = 1 - }; - -public: - CCompareQueryThread(); - ~CCompareQueryThread(); - - void setHiddenOptColumn(bool hide); -signals: - void signalQueryPercent( int nPercent );// 查询完成百分比 - void signalQueryEnd();// 查询结束 - -public slots: - void slotCancel(){ m_bCancel = true; } - -public: - void initVariate(); - void loadData(); - void run(); - void clear(); - void calcTimePoint(); - int getAlarmLevelIndexById( int nId, SAlarmLevel* &pAlarmLevel ); - -public: - kbd_dbms::CDbApi* m_pDb; // 数据库接口 - CAlarmModel* m_pAlarmModel; // 详细告警信息显示窗的model - QList m_listAlarmLevelColor; // 告警优先级的颜色集合 - QList m_listAlarmLevel; // 告警级别列表 - QList > m_listAlarm;// 第一层是设备集合,第二次是时间集合 - - int m_nCurrentLocationIndex;// 当前站序号,0表示全部站 - qint64 m_nStartMs;// 开始时间 ms - qint64 m_nEndMs;// 结束时间 ms - QString m_sSelectedLevel;// 已选择的告警等级 - bool m_bCancel;// 是否取消 - - QList m_listLocation;// 位置信息列表 - QList m_listCheckBox;// 选择列表(站或者设备组) - EN_DateType m_eDateType;// 查询日期类型 - QList m_listTimePoint;// 根据开始时间、结束时间、查询类型计算的时间点 - QString m_sKeyWord;// 查询关键字 - int m_nLastId; - int m_nLastIndex; -}; - -#endif // CCOMPAREQUERYTHREAD_H +#ifndef CCOMPAREQUERYTHREAD_H +#define CCOMPAREQUERYTHREAD_H + +#include +#include +#include +#include +#include +#include "CommonDefine.h" +#include "pub_logger_api/logger.h" +#include "db_sysinfo_api/CDbSysInfo.h" +#include "db_api_ex/CDbApi.h" +#include "CAlarmModel.h" +#include "SAlarmLevel.h" +#include "SLocation.h" + +class CCompareQueryThread : public QThread +{ + Q_OBJECT + +public: + enum EN_DateType + { + EN_DateType_Day = 0, + EN_DateType_Month = 1 + }; + +public: + CCompareQueryThread(); + ~CCompareQueryThread(); + + void setHiddenOptColumn(bool hide); +signals: + void signalQueryPercent( int nPercent );// 查询完成百分比 + void signalQueryEnd();// 查询结束 + +public slots: + void slotCancel(){ m_bCancel = true; } + +public: + void initVariate(); + void loadData(); + void run(); + void clear(); + void calcTimePoint(); + int getAlarmLevelIndexById( int nId, SAlarmLevel* &pAlarmLevel ); + +public: + kbd_dbms::CDbApi* m_pDb; // 数据库接口 + CAlarmModel* m_pAlarmModel; // 详细告警信息显示窗的model + QList m_listAlarmLevelColor; // 告警优先级的颜色集合 + QList m_listAlarmLevel; // 告警级别列表 + QList > m_listAlarm;// 第一层是设备集合,第二次是时间集合 + + int m_nCurrentLocationIndex;// 当前站序号,0表示全部站 + qint64 m_nStartMs;// 开始时间 ms + qint64 m_nEndMs;// 结束时间 ms + QString m_sSelectedLevel;// 已选择的告警等级 + bool m_bCancel;// 是否取消 + + QList m_listLocation;// 位置信息列表 + QList m_listCheckBox;// 选择列表(站或者设备组) + EN_DateType m_eDateType;// 查询日期类型 + QList m_listTimePoint;// 根据开始时间、结束时间、查询类型计算的时间点 + QString m_sKeyWord;// 查询关键字 + int m_nLastId; + int m_nLastIndex; +}; + +#endif // CCOMPAREQUERYTHREAD_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.cpp index fb78c232..e4e61fd1 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.cpp @@ -1,32 +1,32 @@ -#include "CProcessDialog.h" -#include "ui_CProcessDialog.h" -#include - -CProcessDialog::CProcessDialog(QDialog *parent) : - QDialog(parent), - ui(new Ui::CProcessDialog) -{ - ui->setupUi(this); - setWindowFlags(windowFlags()|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); - connect( ui->pb_cancel, SIGNAL(clicked(bool)), this, SLOT(slotPbcancelClicked(bool)), Qt::DirectConnection ); -} - -CProcessDialog::~CProcessDialog() -{ - delete ui; -} - -void CProcessDialog::slotPbcancelClicked( bool ) -{ - signalCancel(); -} - -void CProcessDialog::slotSetValue( int nValue ) -{ - ui->progressBar->setValue( nValue ); -} - -void CProcessDialog::reset() -{ - ui->progressBar->setValue( 0 ); -} +#include "CProcessDialog.h" +#include "ui_CProcessDialog.h" +#include + +CProcessDialog::CProcessDialog(QDialog *parent) : + QDialog(parent), + ui(new Ui::CProcessDialog) +{ + ui->setupUi(this); + setWindowFlags(windowFlags()|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); + connect( ui->pb_cancel, SIGNAL(clicked(bool)), this, SLOT(slotPbcancelClicked(bool)), Qt::DirectConnection ); +} + +CProcessDialog::~CProcessDialog() +{ + delete ui; +} + +void CProcessDialog::slotPbcancelClicked( bool ) +{ + signalCancel(); +} + +void CProcessDialog::slotSetValue( int nValue ) +{ + ui->progressBar->setValue( nValue ); +} + +void CProcessDialog::reset() +{ + ui->progressBar->setValue( 0 ); +} diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.h index 2f322338..bb06cd74 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.h @@ -1,32 +1,32 @@ -#ifndef CPROCESSDIALOG_H -#define CPROCESSDIALOG_H - -#include - -namespace Ui { -class CProcessDialog; -} - -class CProcessDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CProcessDialog(QDialog *parent = 0); - ~CProcessDialog(); - -signals: - void signalCancel(); - -public slots: - void slotPbcancelClicked( bool bChecked ); - void slotSetValue( int nValue ); - -public: - void reset(); - -private: - Ui::CProcessDialog *ui; -}; - -#endif // CPROCESSDIALOG_H +#ifndef CPROCESSDIALOG_H +#define CPROCESSDIALOG_H + +#include + +namespace Ui { +class CProcessDialog; +} + +class CProcessDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CProcessDialog(QDialog *parent = 0); + ~CProcessDialog(); + +signals: + void signalCancel(); + +public slots: + void slotPbcancelClicked( bool bChecked ); + void slotSetValue( int nValue ); + +public: + void reset(); + +private: + Ui::CProcessDialog *ui; +}; + +#endif // CPROCESSDIALOG_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.ui b/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.ui index 5c0c5d70..206716dc 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.ui +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CProcessDialog.ui @@ -1,71 +1,71 @@ - - - CProcessDialog - - - - 0 - 0 - 400 - 28 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 28 - - - - 0 - - - Qt::Horizontal - - - - - - - - 0 - 28 - - - - 取消 - - - false - - - false - - - - - - - - + + + CProcessDialog + + + + 0 + 0 + 400 + 28 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 28 + + + + 0 + + + Qt::Horizontal + + + + + + + + 0 + 28 + + + + 取消 + + + false + + + false + + + + + + + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CStatisticsQueryThread.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CStatisticsQueryThread.cpp index 295dda47..fd4a1c3d 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CStatisticsQueryThread.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CStatisticsQueryThread.cpp @@ -1,552 +1,552 @@ -#include "CStatisticsQueryThread.h" - -using namespace kbd_public; -using namespace kbd_dbms; - -CStatisticsQueryThread::CStatisticsQueryThread() -{ - initVariate(); - loadData(); - clear(); -} - -CStatisticsQueryThread::~CStatisticsQueryThread() -{ - m_bCancel = true; - quit(); - wait(); - - delete m_pDb; - m_pDb = NULL; - - delete m_pAlarmModel; - m_pAlarmModel = NULL; - - qDeleteAll( m_listAlarmLevel ); - m_listAlarmLevel.clear(); - - qDeleteAll( m_listLocation ); - m_listLocation.clear(); - - qDeleteAll( m_listAlarmNormal ); - m_listAlarmNormal.clear(); - - qDeleteAll( m_listAlarmSmart ); - m_listAlarmSmart.clear(); -} - -void CStatisticsQueryThread::setHiddenOptColumn(bool hide) -{ - if(m_pAlarmModel) - { - m_pAlarmModel->setHiddenOptColumn(hide); - } -} - -void CStatisticsQueryThread::initVariate() -{ - m_pAlarmModel = new CAlarmModel(); - - m_listAlarmLevelColor.push_back( QColor(255,0,0) ); - m_listAlarmLevelColor.push_back( QColor(255,116,20) ); - m_listAlarmLevelColor.push_back( QColor(187,226,66) ); - m_listAlarmLevelColor.push_back( QColor(144,230,189) ); - m_listAlarmLevelColor.push_back( QColor(244,228,151) ); - - m_nLastId = -1; - m_nLastIndex = -1; -} - -void CStatisticsQueryThread::loadData() -{ - m_pDb = new CDbApi(DB_CONN_MODEL_READ); - if ( m_pDb->open() ) - { - LOGINFO("initialize and open database success!"); - } - else - { - LOGERROR("initialize or open database failed!"); - return; - } - - LOGINFO("DatabaseName: [%s]", m_pDb->getCurrentDbPara().getDatabaseName().toStdString().c_str()); - LOGINFO("HostName: [%s]", m_pDb->getCurrentDbPara().getHostName().toStdString().c_str()); - LOGINFO("UserName: [%s]", m_pDb->getCurrentDbPara().getUserName().toStdString().c_str()); - - // 查询位置信息 - SLocation* pLocation = new SLocation; - pLocation->nId = -1; - pLocation->sName = "全部"; - m_listLocation << pLocation; - QSqlQuery query; - QString sSql = "select LOCATION_ID,DESCRIPTION,TAG_NAME from sys_model_location_info order by LOCATION_NO"; - if ( !m_pDb->execute(sSql, query) ) - { - return; - } - while( query.next() ) - { - SLocation* pLocation = new SLocation; - pLocation->nId = query.value(0).toInt(); - pLocation->sName = query.value(1).toString(); - pLocation->sTagName = query.value(2).toString(); - m_listLocation << pLocation; - } - query.clear(); - - // 查询设备组信息 - for ( int i=0; inId ); - if ( !m_pDb->execute(sSql, query) ) - { - return; - } - while( query.next() ) - { - SDeviceGroup* pDeviceGroup = new SDeviceGroup; - pDeviceGroup->sTagName = query.value(0).toString(); - pDeviceGroup->sName = query.value(1).toString(); - m_listLocation[i]->listDeviceGroup << pDeviceGroup; - } - query.clear(); - } - - // 查询告警等级信息 - sSql = "select PRIORITY_ID,PRIORITY_ORDER,PRIORITY_NAME from alarm_level_define order by PRIORITY_ORDER"; - if ( !m_pDb->execute(sSql, query) ) - { - return; - } - while( query.next() ) - { - SAlarmLevel* pAlarmLevel = new SAlarmLevel; - pAlarmLevel->nId = query.value(0).toInt(); - pAlarmLevel->nPriority = query.value(1).toInt(); - pAlarmLevel->sName = query.value(2).toString(); - m_listAlarmLevel.append( pAlarmLevel ); - } - query.clear(); -} - -void CStatisticsQueryThread::clear() -{ - m_bCancel = false; - m_nCurrentLocationIndex = 0; - m_nStartMs = 0; - m_nEndMs = 0; - m_sSelectedLevel = ""; - m_sKeyWord = ""; - - // 清空告警显示 - m_pAlarmModel->beginReset(); - m_pAlarmModel->clearAlarmList(); - m_pAlarmModel->endReset(); - - // 清空告警详细信息 - qDeleteAll( m_listAlarmNormal ); - m_listAlarmNormal.clear(); - qDeleteAll( m_listAlarmSmart ); - m_listAlarmSmart.clear(); -} - -void CStatisticsQueryThread::run() -{ - int nLocationCount = m_listLocation.count()-1; - - // 根据选的全部站或某个站分别处理 - QString sLocationName = m_listLocation.at(m_nCurrentLocationIndex)->sName; - int nLocationId = m_listLocation.at(m_nCurrentLocationIndex)->nId; - if ( nLocationId == -1 )// 显示所有站 - { - // 查询所有事件信息 - for ( int l=1; lnId; - QString sLocationNameInTable = m_listLocation.at(l)->sName; - qint64 nRealStartMs = m_nStartMs; - - SAlarmList* pAlarmList = new SAlarmList; - while ( pAlarmList->listLevelCount.count() < m_listAlarmLevel.count() ) - pAlarmList->listLevelCount.append(0); - pAlarmList->nId = nLocationIdInTable; - pAlarmList->sName = sLocationNameInTable; - m_listAlarmNormal.append( pAlarmList ); - - SAlarmList* pSmartAlarmList = new SAlarmList; - while ( pSmartAlarmList->listLevelCount.count() < m_listAlarmLevel.count() ) - pSmartAlarmList->listLevelCount.append(0); - pSmartAlarmList->nId = nLocationIdInTable; - pSmartAlarmList->sName = sLocationNameInTable; - m_listAlarmSmart.append( pSmartAlarmList ); - - QSqlQuery query; - while ( nRealStartMs < m_nEndMs ) - { - if ( m_bCancel ) - break; - - qint64 nRealEndMs = nRealStartMs+86400000ll*CN_DAYSOFSINGLEQUERY > m_nEndMs ? m_nEndMs : nRealStartMs+86400000ll*CN_DAYSOFSINGLEQUERY; - // 普通告警 - QString sSql = QString("select TIME_STAMP,PRIORITY,CONTENT,KEY_ID_TAG from %1 \ - where TIME_STAMP between %2 and %3 and LOCATION_ID=%4 and PRIORITY in(%5) \ - order by TIME_STAMP") - .arg(CN_NORMALALARMTABLE) - .arg(nRealStartMs) - .arg(nRealEndMs-1) - .arg(nLocationIdInTable) - .arg(m_sSelectedLevel); - //qDebug()<<"----"<execute(sSql, query) ) - { - break; - } - //qDebug()<listLevelCount[nLevelIndex]++; - if ( pAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - continue; - - SAlarmInfo* pAlarmInfo = new SAlarmInfo; - pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); - pAlarmInfo->sLevel = pAlarmLevel->sName; - pAlarmInfo->sLocation = sLocationNameInTable; - pAlarmInfo->sContent = query.value(2).toString(); - pAlarmInfo->sKeyIdTag = query.value(3).toString(); - pAlarmList->listAlarmInfo.append( pAlarmInfo ); - } - query.clear(); - - // 智能告警 - sSql = QString("select a.TIME_STAMP,a.PRIORITY,a.CONTENT from %1 as a inner join %2 as b on a.MAIN_ALM_UUID = b.uuid_base64 \ - where a.TIME_STAMP between %3 and %4 and LOCATION_ID=%5 and a.PRIORITY in(%6) order by a.TIME_STAMP") - .arg(CN_SMARTALARMTABLE) - .arg(CN_NORMALALARMTABLE) - .arg(nRealStartMs) - .arg(nRealEndMs-1) - .arg(nLocationIdInTable) - .arg(m_sSelectedLevel); - //qDebug()<execute(sSql, query) ) - { - break; - } - //qDebug()<listLevelCount[nLevelIndex]++; - if ( pSmartAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - continue; - - SAlarmInfo* pAlarmInfo = new SAlarmInfo; - pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); - pAlarmInfo->sLevel = pAlarmLevel->sName; - pAlarmInfo->sLocation = sLocationNameInTable; - pAlarmInfo->sContent = query.value(2).toString(); - pSmartAlarmList->listAlarmInfo.append( pAlarmInfo ); - } - query.clear(); - - // 发送查询进度信号 - signalQueryPercent( 100*(nRealEndMs-m_nStartMs)/(m_nEndMs-m_nStartMs)/nLocationCount+((l-1)*100/nLocationCount) ); - nRealStartMs = nRealEndMs; - } - } - } - else// 显示一个站中的所有设备组 - { - for ( int i=0; ilistDeviceGroup.count(); i++ ) - { - SAlarmList* pAlarmList = new SAlarmList; - while ( pAlarmList->listLevelCount.count() < m_listAlarmLevel.count() ) - pAlarmList->listLevelCount.append(0); - m_listAlarmNormal.append( pAlarmList ); - - pAlarmList->nId = 0; - pAlarmList->sTagName = m_listLocation.at(m_nCurrentLocationIndex)->listDeviceGroup.at(i)->sTagName; - pAlarmList->sName = m_listLocation.at(m_nCurrentLocationIndex)->listDeviceGroup.at(i)->sName; - - SAlarmList* pSmartAlarmList = new SAlarmList; - while ( pSmartAlarmList->listLevelCount.count() < m_listAlarmLevel.count() ) - pSmartAlarmList->listLevelCount.append(0); - m_listAlarmSmart.append( pSmartAlarmList ); - - pSmartAlarmList->nId = 0; - pSmartAlarmList->sTagName = m_listLocation.at(m_nCurrentLocationIndex)->listDeviceGroup.at(i)->sTagName; - pSmartAlarmList->sName = m_listLocation.at(m_nCurrentLocationIndex)->listDeviceGroup.at(i)->sName; - } - - for ( int i=0; i m_nEndMs ? m_nEndMs : nRealStartMs+86400000ll*CN_DAYSOFSINGLEQUERY; - - // 普通告警 - QString sSql = QString("select TIME_STAMP,PRIORITY,CONTENT,KEY_ID_TAG from %1 \ - where TIME_STAMP between %2 and %3 and DEV_GROUP_TAG='%4' and PRIORITY in(%5) \ - order by TIME_STAMP") - .arg(CN_NORMALALARMTABLE) - .arg(nRealStartMs) - .arg(nRealEndMs-1) - .arg(pAlarmList->sTagName) - .arg(m_sSelectedLevel); - if ( !m_pDb->execute(sSql, query) ) - { - break; - } - while( query.next() ) - { - if ( m_bCancel ) - break; - - // 有关键字 - if ( m_sKeyWord != "" ) - { - if ( !query.value(2).toString().contains(m_sKeyWord) ) - continue; - } - - SAlarmLevel* pAlarmLevel = NULL; - int nLevelIndex = getAlarmLevelIndexById( query.value(1).toInt(), pAlarmLevel ); - if ( nLevelIndex < 0 ) - continue; - - pAlarmList->listLevelCount[nLevelIndex]++; - if ( pAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - continue; - - SAlarmInfo* pAlarmInfo = new SAlarmInfo; - pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); - pAlarmInfo->sLevel = pAlarmLevel->sName; - pAlarmInfo->sLocation = sLocationName; - pAlarmInfo->sContent = query.value(2).toString(); - pAlarmInfo->sKeyIdTag = query.value(3).toString(); - pAlarmList->listAlarmInfo.append( pAlarmInfo ); - } - query.clear(); - - // 智能告警 - sSql = QString("select a.TIME_STAMP,a.PRIORITY,a.CONTENT from %1 as a inner join %2 as b on a.MAIN_ALM_UUID = b.uuid_base64 \ - where a.TIME_STAMP between %3 and %4 and DEV_GROUP_TAG='%5' and a.PRIORITY in(%6) order by a.TIME_STAMP") - .arg(CN_SMARTALARMTABLE) - .arg(CN_NORMALALARMTABLE) - .arg(nRealStartMs) - .arg(nRealEndMs-1) - .arg(pSmartAlarmList->sTagName) - .arg(m_sSelectedLevel); - if ( !m_pDb->execute(sSql, query) ) - { - break; - } - while( query.next() ) - { - if ( m_bCancel ) - break; - - // 有关键字 - if ( m_sKeyWord != "" ) - { - if ( !query.value(2).toString().contains(m_sKeyWord) ) - continue; - } - - SAlarmLevel* pAlarmLevel = NULL; - int nLevelIndex = getAlarmLevelIndexById( query.value(1).toInt(), pAlarmLevel ); - if ( nLevelIndex < 0 ) - continue; - - pSmartAlarmList->listLevelCount[nLevelIndex]++; - if ( pSmartAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) - continue; - - SAlarmInfo* pAlarmInfo = new SAlarmInfo; - pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); - pAlarmInfo->sLevel = pAlarmLevel->sName; - pAlarmInfo->sLocation = sLocationName; - pAlarmInfo->sContent = query.value(2).toString(); - pSmartAlarmList->listAlarmInfo.append( pAlarmInfo ); - } - query.clear(); - - - // 发送查询进度信号 - signalQueryPercent( 100*(nRealEndMs-m_nStartMs)/(m_nEndMs-m_nStartMs)/m_listAlarmNormal.count()+(i*100/m_listAlarmNormal.count()) ); - nRealStartMs = nRealEndMs; - } - } - } - - // 对设备按告警数进行排序 - for ( int i=0; igetAllLevelAlarmCount() + m_listAlarmSmart.at(l)->getAllLevelAlarmCount() < - m_listAlarmNormal.at(l+1)->getAllLevelAlarmCount() + m_listAlarmSmart.at(l+1)->getAllLevelAlarmCount() ) - { - SAlarmList* pAlarmList = m_listAlarmNormal.at(l); - m_listAlarmNormal[l] = m_listAlarmNormal.at(l+1); - m_listAlarmNormal[l+1] = pAlarmList; - pAlarmList = m_listAlarmSmart.at(l); - m_listAlarmSmart[l] = m_listAlarmSmart.at(l+1); - m_listAlarmSmart[l+1] = pAlarmList; - } - } - } - - // 发送查询完成信号 - signalQueryEnd(); -} - -int CStatisticsQueryThread::getAlarmLevelIndexById( int nId, SAlarmLevel* &pAlarmLevel ) -{ - if ( m_nLastId == nId && m_nLastIndex >= 0 ) - { - pAlarmLevel = m_listAlarmLevel.at(m_nLastIndex); - return m_nLastIndex; - } - - m_nLastId = nId; - for ( int i=0; inId == nId ) - { - m_nLastIndex = i; - pAlarmLevel = m_listAlarmLevel.at(i); - break; - } - } - return m_nLastIndex; -} - -void CStatisticsQueryThread::getWavePath( QString sAppTagName, QString& sPath, QString& sErrorMsg ) -{ - sPath = ""; - sErrorMsg = ""; - QString sDeviceName = ""; - QString sDeviceTagName = ""; - QString sLocationName = ""; - QString sLocationTagName = sAppTagName.split(".").at(0); - - for ( int i=0; isTagName == sLocationTagName ) - { - sLocationName = m_listLocation.at(i)->sName; - break; - } - } - if ( sLocationName == "" ) - { - sErrorMsg = "未获取到位置名称"; - return; - } - - QSqlQuery query; - QString sSql = QString("select DEV_TAG from fes_digital where APP_TAG_NAME='%1'").arg(sAppTagName); - m_pDb->execute(sSql, query); - if ( query.next() ) - sDeviceTagName = query.value(0).toString(); - query.clear(); - if ( sDeviceTagName == "" ) - { - sErrorMsg = "未从fes_digital表中找到设备标签"; - return; - } - - sSql = QString("select DEV_DESC from fes_dev_info where TAG_NAME='%1'").arg(sDeviceTagName); - m_pDb->execute(sSql, query); - if ( query.next() ) - sDeviceName = query.value(0).toString(); - query.clear(); - if ( sDeviceName == "" ) - { - sErrorMsg = "未从fes_dev_info表中找到设备名称"; - return; - } - QString sDeviceNameTemp = sDeviceName.trimmed();//去掉设备名称前后空格 - QString sTmpPath = QCoreApplication::applicationDirPath(); - sPath = sTmpPath + QString("/../../data/rec/%1/%2").arg(sLocationName).arg(sDeviceNameTemp); -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#include "CStatisticsQueryThread.h" + +using namespace kbd_public; +using namespace kbd_dbms; + +CStatisticsQueryThread::CStatisticsQueryThread() +{ + initVariate(); + loadData(); + clear(); +} + +CStatisticsQueryThread::~CStatisticsQueryThread() +{ + m_bCancel = true; + quit(); + wait(); + + delete m_pDb; + m_pDb = NULL; + + delete m_pAlarmModel; + m_pAlarmModel = NULL; + + qDeleteAll( m_listAlarmLevel ); + m_listAlarmLevel.clear(); + + qDeleteAll( m_listLocation ); + m_listLocation.clear(); + + qDeleteAll( m_listAlarmNormal ); + m_listAlarmNormal.clear(); + + qDeleteAll( m_listAlarmSmart ); + m_listAlarmSmart.clear(); +} + +void CStatisticsQueryThread::setHiddenOptColumn(bool hide) +{ + if(m_pAlarmModel) + { + m_pAlarmModel->setHiddenOptColumn(hide); + } +} + +void CStatisticsQueryThread::initVariate() +{ + m_pAlarmModel = new CAlarmModel(); + + m_listAlarmLevelColor.push_back( QColor(255,0,0) ); + m_listAlarmLevelColor.push_back( QColor(255,116,20) ); + m_listAlarmLevelColor.push_back( QColor(187,226,66) ); + m_listAlarmLevelColor.push_back( QColor(144,230,189) ); + m_listAlarmLevelColor.push_back( QColor(244,228,151) ); + + m_nLastId = -1; + m_nLastIndex = -1; +} + +void CStatisticsQueryThread::loadData() +{ + m_pDb = new CDbApi(DB_CONN_MODEL_READ); + if ( m_pDb->open() ) + { + LOGINFO("initialize and open database success!"); + } + else + { + LOGERROR("initialize or open database failed!"); + return; + } + + LOGINFO("DatabaseName: [%s]", m_pDb->getCurrentDbPara().getDatabaseName().toStdString().c_str()); + LOGINFO("HostName: [%s]", m_pDb->getCurrentDbPara().getHostName().toStdString().c_str()); + LOGINFO("UserName: [%s]", m_pDb->getCurrentDbPara().getUserName().toStdString().c_str()); + + // 查询位置信息 + SLocation* pLocation = new SLocation; + pLocation->nId = -1; + pLocation->sName = "全部"; + m_listLocation << pLocation; + QSqlQuery query; + QString sSql = "select LOCATION_ID,DESCRIPTION,TAG_NAME from sys_model_location_info order by LOCATION_NO"; + if ( !m_pDb->execute(sSql, query) ) + { + return; + } + while( query.next() ) + { + SLocation* pLocation = new SLocation; + pLocation->nId = query.value(0).toInt(); + pLocation->sName = query.value(1).toString(); + pLocation->sTagName = query.value(2).toString(); + m_listLocation << pLocation; + } + query.clear(); + + // 查询设备组信息 + for ( int i=0; inId ); + if ( !m_pDb->execute(sSql, query) ) + { + return; + } + while( query.next() ) + { + SDeviceGroup* pDeviceGroup = new SDeviceGroup; + pDeviceGroup->sTagName = query.value(0).toString(); + pDeviceGroup->sName = query.value(1).toString(); + m_listLocation[i]->listDeviceGroup << pDeviceGroup; + } + query.clear(); + } + + // 查询告警等级信息 + sSql = "select PRIORITY_ID,PRIORITY_ORDER,PRIORITY_NAME from alarm_level_define order by PRIORITY_ORDER"; + if ( !m_pDb->execute(sSql, query) ) + { + return; + } + while( query.next() ) + { + SAlarmLevel* pAlarmLevel = new SAlarmLevel; + pAlarmLevel->nId = query.value(0).toInt(); + pAlarmLevel->nPriority = query.value(1).toInt(); + pAlarmLevel->sName = query.value(2).toString(); + m_listAlarmLevel.append( pAlarmLevel ); + } + query.clear(); +} + +void CStatisticsQueryThread::clear() +{ + m_bCancel = false; + m_nCurrentLocationIndex = 0; + m_nStartMs = 0; + m_nEndMs = 0; + m_sSelectedLevel = ""; + m_sKeyWord = ""; + + // 清空告警显示 + m_pAlarmModel->beginReset(); + m_pAlarmModel->clearAlarmList(); + m_pAlarmModel->endReset(); + + // 清空告警详细信息 + qDeleteAll( m_listAlarmNormal ); + m_listAlarmNormal.clear(); + qDeleteAll( m_listAlarmSmart ); + m_listAlarmSmart.clear(); +} + +void CStatisticsQueryThread::run() +{ + int nLocationCount = m_listLocation.count()-1; + + // 根据选的全部站或某个站分别处理 + QString sLocationName = m_listLocation.at(m_nCurrentLocationIndex)->sName; + int nLocationId = m_listLocation.at(m_nCurrentLocationIndex)->nId; + if ( nLocationId == -1 )// 显示所有站 + { + // 查询所有事件信息 + for ( int l=1; lnId; + QString sLocationNameInTable = m_listLocation.at(l)->sName; + qint64 nRealStartMs = m_nStartMs; + + SAlarmList* pAlarmList = new SAlarmList; + while ( pAlarmList->listLevelCount.count() < m_listAlarmLevel.count() ) + pAlarmList->listLevelCount.append(0); + pAlarmList->nId = nLocationIdInTable; + pAlarmList->sName = sLocationNameInTable; + m_listAlarmNormal.append( pAlarmList ); + + SAlarmList* pSmartAlarmList = new SAlarmList; + while ( pSmartAlarmList->listLevelCount.count() < m_listAlarmLevel.count() ) + pSmartAlarmList->listLevelCount.append(0); + pSmartAlarmList->nId = nLocationIdInTable; + pSmartAlarmList->sName = sLocationNameInTable; + m_listAlarmSmart.append( pSmartAlarmList ); + + QSqlQuery query; + while ( nRealStartMs < m_nEndMs ) + { + if ( m_bCancel ) + break; + + qint64 nRealEndMs = nRealStartMs+86400000ll*CN_DAYSOFSINGLEQUERY > m_nEndMs ? m_nEndMs : nRealStartMs+86400000ll*CN_DAYSOFSINGLEQUERY; + // 普通告警 + QString sSql = QString("select TIME_STAMP,PRIORITY,CONTENT,KEY_ID_TAG from %1 \ + where TIME_STAMP between %2 and %3 and LOCATION_ID=%4 and PRIORITY in(%5) \ + order by TIME_STAMP") + .arg(CN_NORMALALARMTABLE) + .arg(nRealStartMs) + .arg(nRealEndMs-1) + .arg(nLocationIdInTable) + .arg(m_sSelectedLevel); + //qDebug()<<"----"<execute(sSql, query) ) + { + break; + } + //qDebug()<listLevelCount[nLevelIndex]++; + if ( pAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + continue; + + SAlarmInfo* pAlarmInfo = new SAlarmInfo; + pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); + pAlarmInfo->sLevel = pAlarmLevel->sName; + pAlarmInfo->sLocation = sLocationNameInTable; + pAlarmInfo->sContent = query.value(2).toString(); + pAlarmInfo->sKeyIdTag = query.value(3).toString(); + pAlarmList->listAlarmInfo.append( pAlarmInfo ); + } + query.clear(); + + // 智能告警 + sSql = QString("select a.TIME_STAMP,a.PRIORITY,a.CONTENT from %1 as a inner join %2 as b on a.MAIN_ALM_UUID = b.uuid_base64 \ + where a.TIME_STAMP between %3 and %4 and LOCATION_ID=%5 and a.PRIORITY in(%6) order by a.TIME_STAMP") + .arg(CN_SMARTALARMTABLE) + .arg(CN_NORMALALARMTABLE) + .arg(nRealStartMs) + .arg(nRealEndMs-1) + .arg(nLocationIdInTable) + .arg(m_sSelectedLevel); + //qDebug()<execute(sSql, query) ) + { + break; + } + //qDebug()<listLevelCount[nLevelIndex]++; + if ( pSmartAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + continue; + + SAlarmInfo* pAlarmInfo = new SAlarmInfo; + pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); + pAlarmInfo->sLevel = pAlarmLevel->sName; + pAlarmInfo->sLocation = sLocationNameInTable; + pAlarmInfo->sContent = query.value(2).toString(); + pSmartAlarmList->listAlarmInfo.append( pAlarmInfo ); + } + query.clear(); + + // 发送查询进度信号 + signalQueryPercent( 100*(nRealEndMs-m_nStartMs)/(m_nEndMs-m_nStartMs)/nLocationCount+((l-1)*100/nLocationCount) ); + nRealStartMs = nRealEndMs; + } + } + } + else// 显示一个站中的所有设备组 + { + for ( int i=0; ilistDeviceGroup.count(); i++ ) + { + SAlarmList* pAlarmList = new SAlarmList; + while ( pAlarmList->listLevelCount.count() < m_listAlarmLevel.count() ) + pAlarmList->listLevelCount.append(0); + m_listAlarmNormal.append( pAlarmList ); + + pAlarmList->nId = 0; + pAlarmList->sTagName = m_listLocation.at(m_nCurrentLocationIndex)->listDeviceGroup.at(i)->sTagName; + pAlarmList->sName = m_listLocation.at(m_nCurrentLocationIndex)->listDeviceGroup.at(i)->sName; + + SAlarmList* pSmartAlarmList = new SAlarmList; + while ( pSmartAlarmList->listLevelCount.count() < m_listAlarmLevel.count() ) + pSmartAlarmList->listLevelCount.append(0); + m_listAlarmSmart.append( pSmartAlarmList ); + + pSmartAlarmList->nId = 0; + pSmartAlarmList->sTagName = m_listLocation.at(m_nCurrentLocationIndex)->listDeviceGroup.at(i)->sTagName; + pSmartAlarmList->sName = m_listLocation.at(m_nCurrentLocationIndex)->listDeviceGroup.at(i)->sName; + } + + for ( int i=0; i m_nEndMs ? m_nEndMs : nRealStartMs+86400000ll*CN_DAYSOFSINGLEQUERY; + + // 普通告警 + QString sSql = QString("select TIME_STAMP,PRIORITY,CONTENT,KEY_ID_TAG from %1 \ + where TIME_STAMP between %2 and %3 and DEV_GROUP_TAG='%4' and PRIORITY in(%5) \ + order by TIME_STAMP") + .arg(CN_NORMALALARMTABLE) + .arg(nRealStartMs) + .arg(nRealEndMs-1) + .arg(pAlarmList->sTagName) + .arg(m_sSelectedLevel); + if ( !m_pDb->execute(sSql, query) ) + { + break; + } + while( query.next() ) + { + if ( m_bCancel ) + break; + + // 有关键字 + if ( m_sKeyWord != "" ) + { + if ( !query.value(2).toString().contains(m_sKeyWord) ) + continue; + } + + SAlarmLevel* pAlarmLevel = NULL; + int nLevelIndex = getAlarmLevelIndexById( query.value(1).toInt(), pAlarmLevel ); + if ( nLevelIndex < 0 ) + continue; + + pAlarmList->listLevelCount[nLevelIndex]++; + if ( pAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + continue; + + SAlarmInfo* pAlarmInfo = new SAlarmInfo; + pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); + pAlarmInfo->sLevel = pAlarmLevel->sName; + pAlarmInfo->sLocation = sLocationName; + pAlarmInfo->sContent = query.value(2).toString(); + pAlarmInfo->sKeyIdTag = query.value(3).toString(); + pAlarmList->listAlarmInfo.append( pAlarmInfo ); + } + query.clear(); + + // 智能告警 + sSql = QString("select a.TIME_STAMP,a.PRIORITY,a.CONTENT from %1 as a inner join %2 as b on a.MAIN_ALM_UUID = b.uuid_base64 \ + where a.TIME_STAMP between %3 and %4 and DEV_GROUP_TAG='%5' and a.PRIORITY in(%6) order by a.TIME_STAMP") + .arg(CN_SMARTALARMTABLE) + .arg(CN_NORMALALARMTABLE) + .arg(nRealStartMs) + .arg(nRealEndMs-1) + .arg(pSmartAlarmList->sTagName) + .arg(m_sSelectedLevel); + if ( !m_pDb->execute(sSql, query) ) + { + break; + } + while( query.next() ) + { + if ( m_bCancel ) + break; + + // 有关键字 + if ( m_sKeyWord != "" ) + { + if ( !query.value(2).toString().contains(m_sKeyWord) ) + continue; + } + + SAlarmLevel* pAlarmLevel = NULL; + int nLevelIndex = getAlarmLevelIndexById( query.value(1).toInt(), pAlarmLevel ); + if ( nLevelIndex < 0 ) + continue; + + pSmartAlarmList->listLevelCount[nLevelIndex]++; + if ( pSmartAlarmList->listAlarmInfo.count() >= CN_ALARMINFO_MAXROW ) + continue; + + SAlarmInfo* pAlarmInfo = new SAlarmInfo; + pAlarmInfo->sTime = QDateTime::fromMSecsSinceEpoch(query.value(0).toULongLong()).toString("yyyy-MM-dd hh:mm:ss.zzz"); + pAlarmInfo->sLevel = pAlarmLevel->sName; + pAlarmInfo->sLocation = sLocationName; + pAlarmInfo->sContent = query.value(2).toString(); + pSmartAlarmList->listAlarmInfo.append( pAlarmInfo ); + } + query.clear(); + + + // 发送查询进度信号 + signalQueryPercent( 100*(nRealEndMs-m_nStartMs)/(m_nEndMs-m_nStartMs)/m_listAlarmNormal.count()+(i*100/m_listAlarmNormal.count()) ); + nRealStartMs = nRealEndMs; + } + } + } + + // 对设备按告警数进行排序 + for ( int i=0; igetAllLevelAlarmCount() + m_listAlarmSmart.at(l)->getAllLevelAlarmCount() < + m_listAlarmNormal.at(l+1)->getAllLevelAlarmCount() + m_listAlarmSmart.at(l+1)->getAllLevelAlarmCount() ) + { + SAlarmList* pAlarmList = m_listAlarmNormal.at(l); + m_listAlarmNormal[l] = m_listAlarmNormal.at(l+1); + m_listAlarmNormal[l+1] = pAlarmList; + pAlarmList = m_listAlarmSmart.at(l); + m_listAlarmSmart[l] = m_listAlarmSmart.at(l+1); + m_listAlarmSmart[l+1] = pAlarmList; + } + } + } + + // 发送查询完成信号 + signalQueryEnd(); +} + +int CStatisticsQueryThread::getAlarmLevelIndexById( int nId, SAlarmLevel* &pAlarmLevel ) +{ + if ( m_nLastId == nId && m_nLastIndex >= 0 ) + { + pAlarmLevel = m_listAlarmLevel.at(m_nLastIndex); + return m_nLastIndex; + } + + m_nLastId = nId; + for ( int i=0; inId == nId ) + { + m_nLastIndex = i; + pAlarmLevel = m_listAlarmLevel.at(i); + break; + } + } + return m_nLastIndex; +} + +void CStatisticsQueryThread::getWavePath( QString sAppTagName, QString& sPath, QString& sErrorMsg ) +{ + sPath = ""; + sErrorMsg = ""; + QString sDeviceName = ""; + QString sDeviceTagName = ""; + QString sLocationName = ""; + QString sLocationTagName = sAppTagName.split(".").at(0); + + for ( int i=0; isTagName == sLocationTagName ) + { + sLocationName = m_listLocation.at(i)->sName; + break; + } + } + if ( sLocationName == "" ) + { + sErrorMsg = "未获取到位置名称"; + return; + } + + QSqlQuery query; + QString sSql = QString("select DEV_TAG from fes_digital where APP_TAG_NAME='%1'").arg(sAppTagName); + m_pDb->execute(sSql, query); + if ( query.next() ) + sDeviceTagName = query.value(0).toString(); + query.clear(); + if ( sDeviceTagName == "" ) + { + sErrorMsg = "未从fes_digital表中找到设备标签"; + return; + } + + sSql = QString("select DEV_DESC from fes_dev_info where TAG_NAME='%1'").arg(sDeviceTagName); + m_pDb->execute(sSql, query); + if ( query.next() ) + sDeviceName = query.value(0).toString(); + query.clear(); + if ( sDeviceName == "" ) + { + sErrorMsg = "未从fes_dev_info表中找到设备名称"; + return; + } + QString sDeviceNameTemp = sDeviceName.trimmed();//去掉设备名称前后空格 + QString sTmpPath = QCoreApplication::applicationDirPath(); + sPath = sTmpPath + QString("/../../data/rec/%1/%2").arg(sLocationName).arg(sDeviceNameTemp); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CStatisticsQueryThread.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CStatisticsQueryThread.h index 41462715..f9d0250f 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CStatisticsQueryThread.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CStatisticsQueryThread.h @@ -1,57 +1,57 @@ -#ifndef CSTATISTICSQUERYTHREAD_H -#define CSTATISTICSQUERYTHREAD_H - -#include -#include -#include -#include "CommonDefine.h" -#include "pub_logger_api/logger.h" -#include "db_sysinfo_api/CDbSysInfo.h" -#include "db_api_ex/CDbApi.h" -#include "CAlarmModel.h" -#include "SAlarmLevel.h" -#include "SLocation.h" - -class CStatisticsQueryThread : public QThread -{ - Q_OBJECT - -public: - CStatisticsQueryThread(); - ~CStatisticsQueryThread(); - - void setHiddenOptColumn(bool hide); -signals: - void signalQueryPercent( int nPercent );// 查询完成百分比 - void signalQueryEnd();// 查询结束 - -public slots: - void slotCancel(){ m_bCancel = true; } - -public: - void initVariate(); - void loadData(); - void run(); - void clear(); - int getAlarmLevelIndexById( int nId, SAlarmLevel* &pAlarmLevel ); - void getWavePath( QString sAppTagName, QString& sPath, QString& sErrorMsg ); - -public: - kbd_dbms::CDbApi* m_pDb; // 数据库接口 - CAlarmModel* m_pAlarmModel; // 详细告警信息显示窗的model - QList m_listAlarmLevelColor; // 告警优先级的颜色集合 - QList m_listAlarmLevel; // 告警级别列表 - QList m_listAlarmNormal; // 所有站或者一个站的所有设备组的普通告警列表 - QList m_listAlarmSmart; // 所有站或者一个站的所有设备组的智能告警列表 - QList m_listLocation; // 位置信息列表 - int m_nCurrentLocationIndex; - qint64 m_nStartMs; - qint64 m_nEndMs; - QString m_sSelectedLevel; - bool m_bCancel; - QString m_sKeyWord;// 查询关键字 - int m_nLastId; - int m_nLastIndex; -}; - -#endif // CSTATISTICSQUERYTHREAD_H +#ifndef CSTATISTICSQUERYTHREAD_H +#define CSTATISTICSQUERYTHREAD_H + +#include +#include +#include +#include "CommonDefine.h" +#include "pub_logger_api/logger.h" +#include "db_sysinfo_api/CDbSysInfo.h" +#include "db_api_ex/CDbApi.h" +#include "CAlarmModel.h" +#include "SAlarmLevel.h" +#include "SLocation.h" + +class CStatisticsQueryThread : public QThread +{ + Q_OBJECT + +public: + CStatisticsQueryThread(); + ~CStatisticsQueryThread(); + + void setHiddenOptColumn(bool hide); +signals: + void signalQueryPercent( int nPercent );// 查询完成百分比 + void signalQueryEnd();// 查询结束 + +public slots: + void slotCancel(){ m_bCancel = true; } + +public: + void initVariate(); + void loadData(); + void run(); + void clear(); + int getAlarmLevelIndexById( int nId, SAlarmLevel* &pAlarmLevel ); + void getWavePath( QString sAppTagName, QString& sPath, QString& sErrorMsg ); + +public: + kbd_dbms::CDbApi* m_pDb; // 数据库接口 + CAlarmModel* m_pAlarmModel; // 详细告警信息显示窗的model + QList m_listAlarmLevelColor; // 告警优先级的颜色集合 + QList m_listAlarmLevel; // 告警级别列表 + QList m_listAlarmNormal; // 所有站或者一个站的所有设备组的普通告警列表 + QList m_listAlarmSmart; // 所有站或者一个站的所有设备组的智能告警列表 + QList m_listLocation; // 位置信息列表 + int m_nCurrentLocationIndex; + qint64 m_nStartMs; + qint64 m_nEndMs; + QString m_sSelectedLevel; + bool m_bCancel; + QString m_sKeyWord;// 查询关键字 + int m_nLastId; + int m_nLastIndex; +}; + +#endif // CSTATISTICSQUERYTHREAD_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CTableWidget.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CTableWidget.cpp index 54de4eaf..5360c04b 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CTableWidget.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CTableWidget.cpp @@ -1,62 +1,62 @@ -#include "CTableWidget.h" -#include - -CTableWidget::CTableWidget(QWidget *parent) - : QTableWidget(parent) -{ - -} - -int CTableWidget::tableColumnWidth() -{ - return m_nTableColWidth; -} - -void CTableWidget::setTableColumnWidth(const int &nWidth) -{ - m_nTableColWidth = nWidth; - - horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); -} - -int CTableWidget::tableRowHeight() -{ - return m_nTableRowHeight; -} - -void CTableWidget::setTableRowHeight(const int &nHeight) -{ - m_nTableRowHeight = nHeight; - - verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); -} - -CTableView::CTableView(QWidget *parent) - : QTableView(parent) -{ - -} - -int CTableView::tableColumnWidth() -{ - return m_nTableColWidth; -} - -void CTableView::setTableColumnWidth(const int &nWidth) -{ - m_nTableColWidth = nWidth; - - horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); -} - -int CTableView::tableRowHeight() -{ - return m_nTableRowHeight; -} - -void CTableView::setTableRowHeight(const int &nHeight) -{ - m_nTableRowHeight = nHeight; - - verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); -} +#include "CTableWidget.h" +#include + +CTableWidget::CTableWidget(QWidget *parent) + : QTableWidget(parent) +{ + +} + +int CTableWidget::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CTableWidget::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CTableWidget::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CTableWidget::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} + +CTableView::CTableView(QWidget *parent) + : QTableView(parent) +{ + +} + +int CTableView::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CTableView::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CTableView::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CTableView::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CTableWidget.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CTableWidget.h index 135f76e8..c0b48870 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CTableWidget.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CTableWidget.h @@ -1,46 +1,46 @@ -#ifndef CTABLEWIDGET_H -#define CTABLEWIDGET_H - -#include - -class CTableWidget : public QTableWidget -{ - Q_OBJECT - Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) - Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) - -public: - CTableWidget(QWidget *parent = Q_NULLPTR); - - int tableColumnWidth(); - void setTableColumnWidth(const int &nWidth); - - int tableRowHeight(); - void setTableRowHeight(const int &nHeight); - -private: - int m_nTableColWidth; - int m_nTableRowHeight; -}; - -class CTableView : public QTableView -{ - Q_OBJECT - Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) - Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) - -public: - CTableView(QWidget *parent = Q_NULLPTR); - - int tableColumnWidth(); - void setTableColumnWidth(const int &nWidth); - - int tableRowHeight(); - void setTableRowHeight(const int &nHeight); - -private: - int m_nTableColWidth; - int m_nTableRowHeight; -}; - -#endif // CTABLEWIDGET_H +#ifndef CTABLEWIDGET_H +#define CTABLEWIDGET_H + +#include + +class CTableWidget : public QTableWidget +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + CTableWidget(QWidget *parent = Q_NULLPTR); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + +private: + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +class CTableView : public QTableView +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + CTableView(QWidget *parent = Q_NULLPTR); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + +private: + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +#endif // CTABLEWIDGET_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.cpp index 7aa35939..14d8c868 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.cpp @@ -1,49 +1,49 @@ -#include -#include "CWaveListDialog.h" -#include "ui_CWaveListDialog.h" -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileUtil.h" - -CWaveListDialog::CWaveListDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CWaveListDialog) -{ - ui->setupUi(this); - setWindowTitle( "录波列表" ); - - connect( ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotShowWave(QListWidgetItem*)) ); -} - -CWaveListDialog::~CWaveListDialog() -{ - delete ui; -} - -void CWaveListDialog::clear() -{ - m_sPath = ""; - ui->listWidget->clear(); -} - -void CWaveListDialog::addFileNameList( QString sPath, QStringList listName ) -{ - m_sPath = sPath; - ui->listWidget->addItems( listName ); -} - -void CWaveListDialog::slotShowWave( QListWidgetItem* pItem ) -{ - const std::string strPath = std::move(kbd_public::CFileUtil::getPathOfBinFile( - std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); - if(strPath.empty()) - { - LOGERROR("未找到可执行文件WaveAnalyze"); - return; - } - - QStringList listArgument; - listArgument << m_sPath+"/"+pItem->text(); - - QProcess::startDetached( strPath.c_str(), listArgument ); -} - +#include +#include "CWaveListDialog.h" +#include "ui_CWaveListDialog.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileUtil.h" + +CWaveListDialog::CWaveListDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CWaveListDialog) +{ + ui->setupUi(this); + setWindowTitle( "录波列表" ); + + connect( ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotShowWave(QListWidgetItem*)) ); +} + +CWaveListDialog::~CWaveListDialog() +{ + delete ui; +} + +void CWaveListDialog::clear() +{ + m_sPath = ""; + ui->listWidget->clear(); +} + +void CWaveListDialog::addFileNameList( QString sPath, QStringList listName ) +{ + m_sPath = sPath; + ui->listWidget->addItems( listName ); +} + +void CWaveListDialog::slotShowWave( QListWidgetItem* pItem ) +{ + const std::string strPath = std::move(kbd_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); + if(strPath.empty()) + { + LOGERROR("未找到可执行文件WaveAnalyze"); + return; + } + + QStringList listArgument; + listArgument << m_sPath+"/"+pItem->text(); + + QProcess::startDetached( strPath.c_str(), listArgument ); +} + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.h index 8c86daca..d26a3627 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.h @@ -1,31 +1,31 @@ -#ifndef CWAVELISTDIALOG_H -#define CWAVELISTDIALOG_H - -#include -#include - -namespace Ui { -class CWaveListDialog; -} - -class CWaveListDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CWaveListDialog(QWidget *parent = 0); - ~CWaveListDialog(); - -public: - void clear(); - void addFileNameList( QString sPath, QStringList listName ); - -public slots: - void slotShowWave( QListWidgetItem* pItem ); - -private: - Ui::CWaveListDialog *ui; - QString m_sPath; -}; - -#endif // CWAVELISTDIALOG_H +#ifndef CWAVELISTDIALOG_H +#define CWAVELISTDIALOG_H + +#include +#include + +namespace Ui { +class CWaveListDialog; +} + +class CWaveListDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CWaveListDialog(QWidget *parent = 0); + ~CWaveListDialog(); + +public: + void clear(); + void addFileNameList( QString sPath, QStringList listName ); + +public slots: + void slotShowWave( QListWidgetItem* pItem ); + +private: + Ui::CWaveListDialog *ui; + QString m_sPath; +}; + +#endif // CWAVELISTDIALOG_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.ui b/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.ui index dd07347d..b760413f 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.ui +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CWaveListDialog.ui @@ -1,24 +1,24 @@ - - - CWaveListDialog - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - - - - - - - - + + + CWaveListDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CommonDefine.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CommonDefine.h index 926679fa..bb9a6f5c 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CommonDefine.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CommonDefine.h @@ -1,11 +1,11 @@ -#ifndef COMMONDEFINE_H -#define COMMONDEFINE_H - -#define CN_MAXBARSERIES 5 // 最多柱状图组数 -#define CN_ALARMINFO_MAXROW 5000 // 告警信息窗最多显示的条数 -#define CN_DAYSOFSINGLEQUERY 1 // 单次查询的天数 -#define CN_MAXBARCOUNT 3 // 告警比对站(或设备组)最多个数 -#define CN_NORMALALARMTABLE "his_event" // 普通告警的表名 -#define CN_SMARTALARMTABLE "his_intelli_alm" // 智能告警的表名 - -#endif // COMMONDEFINE_H +#ifndef COMMONDEFINE_H +#define COMMONDEFINE_H + +#define CN_MAXBARSERIES 5 // 最多柱状图组数 +#define CN_ALARMINFO_MAXROW 5000 // 告警信息窗最多显示的条数 +#define CN_DAYSOFSINGLEQUERY 1 // 单次查询的天数 +#define CN_MAXBARCOUNT 3 // 告警比对站(或设备组)最多个数 +#define CN_NORMALALARMTABLE "his_event" // 普通告警的表名 +#define CN_SMARTALARMTABLE "his_intelli_alm" // 智能告警的表名 + +#endif // COMMONDEFINE_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CommonFunction.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CommonFunction.cpp index c31cf8c4..2e1d9513 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CommonFunction.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CommonFunction.cpp @@ -1,39 +1,39 @@ -#include "CommonFunction.h" - -void resizeColumnsToContents(QTableView* pView , int scaleColumn) -{ - if ( pView == NULL || pView->model() == NULL ) - return; - - int nColWidth = pView->width(); - if ( nColWidth <= 200 ) - return; - - pView->resizeColumnsToContents(); - - float fRatio = 1.0f; - int nCurrentColWidth = 0; - int nColCount = pView->model()->columnCount(); - for ( int i=0; icolumnWidth( i ); - fRatio = float(nColWidth-20)/nCurrentColWidth; - if(fRatio > 1.0) - { - for ( int i=0; isetColumnWidth( i, pView->columnWidth(i)*fRatio ); - } - else - { - int nOffset = nColWidth - nCurrentColWidth - 25; - if(nColCount > scaleColumn) - pView->setColumnWidth( scaleColumn, pView->columnWidth(scaleColumn)+nOffset); - } -} - -void showMsg( QMessageBox::Icon icon, QString sTitle, QString sText ) -{ - QMessageBox* pMsgBox = new QMessageBox(icon,sTitle,sText); - pMsgBox->setWindowFlags( ( pMsgBox->windowFlags() & ~Qt::WindowMinimizeButtonHint ) | Qt::WindowStaysOnTopHint | Qt::Dialog ); - pMsgBox->exec(); - delete pMsgBox; -} +#include "CommonFunction.h" + +void resizeColumnsToContents(QTableView* pView , int scaleColumn) +{ + if ( pView == NULL || pView->model() == NULL ) + return; + + int nColWidth = pView->width(); + if ( nColWidth <= 200 ) + return; + + pView->resizeColumnsToContents(); + + float fRatio = 1.0f; + int nCurrentColWidth = 0; + int nColCount = pView->model()->columnCount(); + for ( int i=0; icolumnWidth( i ); + fRatio = float(nColWidth-20)/nCurrentColWidth; + if(fRatio > 1.0) + { + for ( int i=0; isetColumnWidth( i, pView->columnWidth(i)*fRatio ); + } + else + { + int nOffset = nColWidth - nCurrentColWidth - 25; + if(nColCount > scaleColumn) + pView->setColumnWidth( scaleColumn, pView->columnWidth(scaleColumn)+nOffset); + } +} + +void showMsg( QMessageBox::Icon icon, QString sTitle, QString sText ) +{ + QMessageBox* pMsgBox = new QMessageBox(icon,sTitle,sText); + pMsgBox->setWindowFlags( ( pMsgBox->windowFlags() & ~Qt::WindowMinimizeButtonHint ) | Qt::WindowStaysOnTopHint | Qt::Dialog ); + pMsgBox->exec(); + delete pMsgBox; +} diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CommonFunction.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CommonFunction.h index b094252f..0acc53aa 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CommonFunction.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CommonFunction.h @@ -1,10 +1,10 @@ -#ifndef COMMONFUNCTION_H -#define COMMONFUNCTION_H - -#include -#include - -void resizeColumnsToContents( QTableView* pView, int scaleColumn = 3 ); -void showMsg( QMessageBox::Icon icon, QString sTitle, QString sText ); - -#endif // COMMONFUNCTION_H +#ifndef COMMONFUNCTION_H +#define COMMONFUNCTION_H + +#include +#include + +void resizeColumnsToContents( QTableView* pView, int scaleColumn = 3 ); +void showMsg( QMessageBox::Icon icon, QString sTitle, QString sText ); + +#endif // COMMONFUNCTION_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmInfo.h b/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmInfo.h index 6b86b36c..fbf73d73 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmInfo.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmInfo.h @@ -1,23 +1,23 @@ -#ifndef SALARMINFO_H -#define SALARMINFO_H - -#include - -struct SAlarmInfo -{ - QString sTime; // 时间, 示例: 2019-01-02 09:12:44.267 - QString sLevel; // 级别,示例: 一级 - QString sLocation; // 位置,示例:清湖北站 - QString sContent; // 内容,示例:302间隔信息 C相电压 230.00kV 越上上限 - QString sKeyIdTag; // key_id_tag - SAlarmInfo() - { - sTime = ""; - sLevel = ""; - sLocation = ""; - sContent = ""; - sKeyIdTag = ""; - } -}; - -#endif // SALARMINFO_H +#ifndef SALARMINFO_H +#define SALARMINFO_H + +#include + +struct SAlarmInfo +{ + QString sTime; // 时间, 示例: 2019-01-02 09:12:44.267 + QString sLevel; // 级别,示例: 一级 + QString sLocation; // 位置,示例:清湖北站 + QString sContent; // 内容,示例:302间隔信息 C相电压 230.00kV 越上上限 + QString sKeyIdTag; // key_id_tag + SAlarmInfo() + { + sTime = ""; + sLevel = ""; + sLocation = ""; + sContent = ""; + sKeyIdTag = ""; + } +}; + +#endif // SALARMINFO_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmLevel.h b/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmLevel.h index 541bd5b6..e12de2b0 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmLevel.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmLevel.h @@ -1,20 +1,20 @@ -#ifndef SALARMLEVEL_H -#define SALARMLEVEL_H - -#include - -struct SAlarmLevel -{ - int nId; // id - int nPriority; // 级别 - QString sName; // 名称 -public: - SAlarmLevel() - { - nId = 0; - nPriority = 0; - sName = ""; - } -}; - -#endif // SALARMLEVEL_H +#ifndef SALARMLEVEL_H +#define SALARMLEVEL_H + +#include + +struct SAlarmLevel +{ + int nId; // id + int nPriority; // 级别 + QString sName; // 名称 +public: + SAlarmLevel() + { + nId = 0; + nPriority = 0; + sName = ""; + } +}; + +#endif // SALARMLEVEL_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmList.h b/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmList.h index 630fcff1..becccbdc 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmList.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/SAlarmList.h @@ -1,37 +1,37 @@ -#ifndef SALARMLIST_H -#define SALARMLIST_H - -#include -#include "SAlarmInfo.h" - -struct SAlarmList -{ - int nId;// 站id - QString sName;// 站或者设备组名称 - QString sTagName; // 设备组tag - QList listLevelCount;//每级告警个数,下标表示优先级的顺序,不是优先级的值,也不是优先级的id - QList listAlarmInfo;//不分等级,前CN_ALARMINFO_MAXROW个 - SAlarmList() - { - nId = 0; - sName = ""; - sTagName = ""; - listLevelCount.clear(); - listAlarmInfo.clear(); - } - ~SAlarmList() - { - listLevelCount.clear(); - qDeleteAll( listAlarmInfo ); - listAlarmInfo.clear(); - } - int getAllLevelAlarmCount()// 获取所有告警的数目(所有等级) - { - int nCount = 0; - for ( int i=0; i +#include "SAlarmInfo.h" + +struct SAlarmList +{ + int nId;// 站id + QString sName;// 站或者设备组名称 + QString sTagName; // 设备组tag + QList listLevelCount;//每级告警个数,下标表示优先级的顺序,不是优先级的值,也不是优先级的id + QList listAlarmInfo;//不分等级,前CN_ALARMINFO_MAXROW个 + SAlarmList() + { + nId = 0; + sName = ""; + sTagName = ""; + listLevelCount.clear(); + listAlarmInfo.clear(); + } + ~SAlarmList() + { + listLevelCount.clear(); + qDeleteAll( listAlarmInfo ); + listAlarmInfo.clear(); + } + int getAllLevelAlarmCount()// 获取所有告警的数目(所有等级) + { + int nCount = 0; + for ( int i=0; i - -struct SDeviceGroup -{ - QString sTagName; - QString sName; - SDeviceGroup() - { - sTagName = ""; - sName = ""; - } -}; - -#endif // SDEVICEGROUP_H +#ifndef SDEVICEGROUP_H +#define SDEVICEGROUP_H + +#include + +struct SDeviceGroup +{ + QString sTagName; + QString sName; + SDeviceGroup() + { + sTagName = ""; + sName = ""; + } +}; + +#endif // SDEVICEGROUP_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/SLocation.h b/product/src/gui/plugin/AlarmAnalyzeWidget/SLocation.h index 3816e373..26a55659 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/SLocation.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/SLocation.h @@ -1,27 +1,27 @@ -#ifndef SLOCATION_H -#define SLOCATION_H - -#include -#include "SDeviceGroup.h" - -struct SLocation -{ - int nId; - QString sName; - QString sTagName; - QList listDeviceGroup; - SLocation() - { - nId = 0; - sName = ""; - sTagName = ""; - } - ~SLocation() - { - qDeleteAll( listDeviceGroup ); - listDeviceGroup.clear(); - } -}; - - -#endif // SLOCATION_H +#ifndef SLOCATION_H +#define SLOCATION_H + +#include +#include "SDeviceGroup.h" + +struct SLocation +{ + int nId; + QString sName; + QString sTagName; + QList listDeviceGroup; + SLocation() + { + nId = 0; + sName = ""; + sTagName = ""; + } + ~SLocation() + { + qDeleteAll( listDeviceGroup ); + listDeviceGroup.clear(); + } +}; + + +#endif // SLOCATION_H diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/main.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/main.cpp index 1732a492..15c6adb3 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/main.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/main.cpp @@ -1,17 +1,17 @@ -#include "CAlarmStatistics.h" -#include -#include -#include "pub_logger_api/logger.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - kbd_public::StartLogSystem( "BASE", "alarm_statistics" ); - - CAlarmStatistics w( 0, false ); - w.show(); - int nRet = a.exec(); - - kbd_public::StopLogSystem(); - return nRet; -} +#include "CAlarmStatistics.h" +#include +#include +#include "pub_logger_api/logger.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + kbd_public::StartLogSystem( "BASE", "alarm_statistics" ); + + CAlarmStatistics w( 0, false ); + w.show(); + int nRet = a.exec(); + + kbd_public::StopLogSystem(); + return nRet; +} diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/resource.qrc b/product/src/gui/plugin/AlarmAnalyzeWidget/resource.qrc index 46021c07..ddfae26c 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/resource.qrc +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/resource.qrc @@ -1,7 +1,7 @@ - - - - resource/combobox-drop-down.png - resource/icon.png - - + + + + resource/combobox-drop-down.png + resource/icon.png + + diff --git a/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.cpp b/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.cpp index 6a420384..47bc84ad 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.cpp @@ -1,509 +1,509 @@ -#include "AddObjAlarmDialog.h" -#include "ui_AddObjAlarmDialog.h" -#include "AlarmMng.h" -#include "AlarmCalcParaTableDelegate.h" -#include -#include -#include "model_table/CustomWidget/kbdselectpointdlg.h" -#include "model_table/CustomWidget/kbdfindpointwidget.h" -#include -#include "AlarmUuidBase64.h" -#include "pub_logger_api/logger.h" -#include "kbdtabledatamgr.h" -#include -AddObjAlarmDialog::AddObjAlarmDialog(QList devList, QWidget *parent) : - QDialog(parent), - m_pWriteDb(Q_NULLPTR), - m_devList(devList), - m_model(Q_NULLPTR), - m_delegate(Q_NULLPTR), - ui(new Ui::AddObjAlarmDialog) -{ - ui->setupUi(this); - Qt::WindowFlags flags=Qt::Dialog; - flags |=Qt::WindowCloseButtonHint; - setWindowFlags(flags); - - this->setWindowTitle(tr("新增告警点")); - KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); - initLayout(); - initMember(); - initData(); - initConnect(); - initView(); -} - -AddObjAlarmDialog::~AddObjAlarmDialog() -{ - if(m_pWriteDb) - { - m_pWriteDb->close(); - delete m_pWriteDb; - } - m_pWriteDb = NULL; - if(m_model) - { - delete m_model; - } - m_model = NULL; - delete ui; -} - -void AddObjAlarmDialog::slotViewUpdate() -{ - ui->tableView->viewport()->update(); -} - -void AddObjAlarmDialog::slotSelectPoint(AlarmCalcInfoPtr info) -{ - - LOGDEBUG("选点--------------------------------------------------"); -// TestDialog dlg; -// dlg.exec(); - KbdSelectPointDlg dlg; - QStringList list; - list << QString("sql@SELECT * FROM SYS_MODEL_LOCATION_INFO order by LOCATION_NO;LOCATION_ID:DESCRIPTION") - <getSelectDescByIndex(6) == "") - return; - QString tagStr = QString("%1.%2.%3") - .arg(dlg.findPointWidget()->getSelectDataByIndex(5)) - .arg(dlg.findPointWidget()->getSelectDataByIndex(6)) - .arg(dlg.findPointWidget()->getSelectDataByIndex(7)); - info->m_tag = tagStr; - -} - -void AddObjAlarmDialog::initLayout() -{ - ui->comboBox->setView(new QListView()); - ui->comboBox_2->setView(new QListView()); - ui->comboBox_3->setView(new QListView()); - ui->comboBox_4->setView(new QListView()); - ui->cbObjType->setView(new QListView()); -} - -void AddObjAlarmDialog::initMember() -{ - if(m_pWriteDb == NULL) - { - m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); - m_pWriteDb->open(); - } - if(m_model == NULL) - { - m_model = new AlarmCalcParaTableModel(this,ui->tableView); - } - if(m_delegate == NULL) - { - m_delegate = new AlarmCalcParaTableDelegate(m_model,this); - } - ui->tableView->setAlternatingRowColors(true); - ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - ui->tableView->horizontalHeader()->setStretchLastSection(true); - ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); - //ui->tableView->setHorizontalScrollMode(ScrollPerPixel); - ui->tableView->setModel(m_model); - ui->tableView->setItemDelegateForColumn(2,m_delegate); - ui->tableView->setColumnWidth(0,110); - ui->tableView->setColumnWidth(1,380); -} - -void AddObjAlarmDialog::initData() -{ - m_alarmLevelMap = AlarmMng::instance()->getAlarmLevel(); - m_alarmLevelActionMap = AlarmMng::instance()->getAlarmLevelAction(); - m_alarmActionMap = AlarmMng::instance()->getAlarmAction(); - m_funcMap = AlarmMng::instance()->getFuncInfo(); - m_calcInfoMap = AlarmMng::instance()->getCalcInfo(); - m_diTextList = AlarmMng::instance()->getDiText(); -} - -void AddObjAlarmDialog::initConnect() -{ - connect(ui->cbObjType,SIGNAL(currentIndexChanged(int)),this,SLOT(pointTypeChange(int))); - connect(ui->comboBox_2,SIGNAL(currentIndexChanged(int)),this,SLOT(alarmLevelChange(int))); - connect(ui->comboBox_3,SIGNAL(currentIndexChanged(int)),this,SLOT(funcChange(int))); - connect(this,&AddObjAlarmDialog::sigChangePara,m_model,&AlarmCalcParaTableModel::slotChangePara); - connect(this,&AddObjAlarmDialog::sigClearPara,m_model,&AlarmCalcParaTableModel::slotClearPara); - connect(m_delegate,&AlarmCalcParaTableDelegate::sigViewUpdate,this,&AddObjAlarmDialog::slotViewUpdate); - connect(m_delegate,&AlarmCalcParaTableDelegate::sigselectPoint,this,&AddObjAlarmDialog::slotSelectPoint); - connect(ui->pushButton,&QPushButton::clicked,this,&AddObjAlarmDialog::addObj); - connect(ui->pushButton_2,&QPushButton::clicked,this,&AddObjAlarmDialog::reject); -} - -void AddObjAlarmDialog::initView() -{ - ui->comboBox->clear(); - for(int index(0);indexcomboBox->addItem(m_devList.at(index).strDevDesc,m_devList.at(index).strDev); - } - - ui->cbObjType->clear(); - ui->cbObjType->addItem(tr("模拟量"),0); - ui->cbObjType->addItem(tr("数字量"),1); - - ui->comboBox_2->clear(); - int index = 0; - QMap::iterator it_level = m_alarmLevelMap.begin(); - while (it_level != m_alarmLevelMap.end()) { - ui->comboBox_2->addItem(it_level.value(),it_level.key()); - m_alarmLevelIndexMap[it_level.key()] = index++; - it_level++; - } - - QHBoxLayout *hLayout = new QHBoxLayout; - QVBoxLayout *vLayout0 = new QVBoxLayout; - QVBoxLayout *vLayout1 = new QVBoxLayout; - QVBoxLayout *vLayout2 = new QVBoxLayout; - index = 0; - QMap::iterator it = m_alarmActionMap.begin(); - while (it != m_alarmActionMap.end()) { - - QCheckBox *box = new QCheckBox(it.value(),ui->widget); - box->setMinimumHeight(19); - m_alarmActionCheckMap[it.key()] = box; - if(index % 3 == 0) - { - vLayout0->addWidget(box); - }else if(index % 3 == 1) - { - vLayout1->addWidget(box); - }else if(index % 3 == 2) - { - vLayout2->addWidget(box); - } - index++; - it++; - } - vLayout0->addStretch(100); - vLayout1->addStretch(100); - vLayout2->addStretch(100); - - hLayout->addLayout(vLayout0); - - hLayout->addLayout(vLayout1); - hLayout->addLayout(vLayout2); - ui->widget->setLayout(hLayout); - ui->widget->setEnabled(false); - - ui->comboBox_3->clear(); - QMap::iterator pos = m_funcMap.begin(); - while (pos != m_funcMap.end()) { - ui->comboBox_3->addItem(pos.value(),pos.key()); - pos++; - } - ui->comboBox_4->clear(); - for(int index(0);indexcomboBox_4->addItem(m_diTextList.at(index),m_diTextList.at(index)); - } - - hideDiText(); - alarmLevelChange(0); - funcChange(0); -} - -bool AddObjAlarmDialog::checkIfAdd() -{ - QString st = ui->lineEdit->text(); - if(st.isEmpty()) - { - QMessageBox::warning(0,tr("提示"),tr("自定义告警名称不能为空!")); - return false; - } - QString func = ui->comboBox_3->currentData().toString(); - if(func.isEmpty()) - { - QMessageBox::warning(0,tr("提示"),tr("无告警点计算函数,请先配置计算点函数!")); - return false; - } - QMap >::iterator it= m_calcInfoMap.find(func); - if(it != m_calcInfoMap.end()) - { - QList paraList = it.value(); - QList::iterator pos = paraList.begin(); - while (pos != paraList.end()) { - if((*pos)->m_tag.isEmpty()) - { - QMessageBox::warning(0,tr("提示"),tr("参数:%1的参数标签不能为空!").arg((*pos)->m_strTip)); - return false; - } - pos++; - } - } - int type = ui->cbObjType->currentData().toInt(); - if(type == 0) - { - //模拟量 - int limitUp1 = ui->doubleSpinBox->value(); - int limitLow1 = ui->doubleSpinBox_2->value(); - if(limitLow1>=limitUp1) - { - QMessageBox::warning(0,tr("提示"),tr("越下限值必须小于越上限值!")); - return false; - } - }else - { - //数字量 - QString diText = ui->comboBox_4->currentData().toString(); - if(diText.isEmpty()) - { - QMessageBox::warning(0,tr("提示"),tr("无数字量文本,请先配置数字量文本!")); - return false; - } - } - return true; -} - -void AddObjAlarmDialog::hideDiText() -{ - -} - -void AddObjAlarmDialog::saveAi() -{ - QString tag = getOneTagName(); - QString tableTagValue = "analog."+tag+".value"; - int devType = getDevType(); - int loction = getLoctionId(); - QString desc =ui->lineEdit->text(); - QString devTag = ui->comboBox->currentData().toString(); - double limitUp1 = ui->doubleSpinBox->value(); - double limitLow1 = ui->doubleSpinBox_2->value(); - int priority = ui->comboBox_2->currentData().toInt(); - QString funcName = ui->comboBox_3->currentData().toString(); - m_pWriteDb->transaction(); - QString sql = QString("insert into %1 (tag_name,description,dev_type,device" - ",location_id,sub_system,unit_id,region_id,is_limit" - ",point_type,point_property,is_sample,sample_period,sample_deadband) values('%2','%3',%4,'%5'" - ",%6,4,1,1,1,0,1,1,5,0.5)").arg("analog").arg(tag).arg(desc).arg(devType).arg(devTag).arg(loction); - if(!execute(sql)) - { - return ; - } - - //< analog触发器自动生成一条analog_limit_info - sql = QString("update %1 set limit_type=%2,limit_num=%3,limit_up1=%4,limit_low1=%5,cross_percent=%6,return_percent=%7,is_obj_alm_manner=%8," - "alarm_priority=%9 where tag_name='%10'").arg("analog_limit_info").arg(1).arg(1).arg(limitUp1).arg(limitLow1).arg(5).arg(5).arg(1).arg(priority).arg(tag); - - if(!execute(sql)) - { - return ; - } - - sql = QString("insert into %1 (key_id_tag,description,location_id,sub_system,func_name,calc_flag) values('%2','%3',%4,4,'%5',1)").arg("calc_out_para").arg(tableTagValue).arg(desc).arg(loction).arg(funcName); - if(!execute(sql)) - { - return ; - } - sql = ""; - QMap >::iterator it= m_calcInfoMap.find(funcName); - if(it != m_calcInfoMap.end()) - { - sql =QString("insert into %1 (key_id_tag,para_seq_no,para_key_tag,description,location_id,sub_system,calc_flag) values ").arg("calc_in_para"); - QList paraList = it.value(); - for(int index(0);indexm_nId)).arg(paraList.at(index)->m_tag).arg(paraList.at(index)->m_strTip).arg(loction); - }else - { - sql += QString("('%1',%2,'%3','%4',%5,4,1),").arg(tableTagValue).arg((paraList.at(index)->m_nId)).arg(paraList.at(index)->m_tag).arg(paraList.at(index)->m_strTip).arg(loction); - } - } - } - - if(!sql.isEmpty() && !execute(sql)) - { - return ; - } - - if(!m_pWriteDb->commit()) - { - QMessageBox::warning(0,tr("提示"),tr("添加失败!正在回滚事务~")); - LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); - m_pWriteDb->rollback(); - }else - { - accept(); - QMessageBox::warning(0,tr("提示"),tr("添加成功")); - } -} - -void AddObjAlarmDialog::saveDi() -{ - QString tag = getOneTagName(); - QString tableTagValue = "digital."+tag+".value"; - int devType = getDevType(); - int loction = getLoctionId(); - QString desc =ui->lineEdit->text(); - QString devTag = ui->comboBox->currentData().toString(); - QString diText = ui->comboBox_4->currentData().toString(); - int priority = ui->comboBox_2->currentData().toInt(); - QString funcName = ui->comboBox_3->currentData().toString(); - m_pWriteDb->transaction(); - QString sql = QString("insert into %1 (tag_name,description,device" - ",location_id,sub_system,state_text_name,value_num,is_obj_alm_manner,alarm_priority,alarm_priority_soe" - ",is_water_alm,region_id,point_type,point_property,point_sort,dev_type" - ",is_sample,sample_period,alarm_freq,alarm_freq_desc,alarm_time,alarm_time_desc,alarm_freq_range) values('%2','%3','%4'" - ",%5,4,'%6',1,1,%7,3,1,1,1,1,300,%8,1,5,10,'%9',5,'%10',30)").arg("digital").arg(tag).arg(desc).arg(devTag) - .arg(loction).arg(diText).arg(priority).arg(devType).arg(tr("计次告警描述")).arg(tr("计时告警描述")); - if(!execute(sql)) - { - return ; - } - - sql = QString("insert into %1 (key_id_tag,description,location_id,sub_system,func_name,calc_flag) values('%2','%3',%4,4,'%5',1)").arg("calc_out_para").arg(tableTagValue).arg(desc).arg(loction).arg(funcName); - if(!execute(sql)) - { - return ; - } - QMap >::iterator it= m_calcInfoMap.find(funcName); - sql = ""; - if(it != m_calcInfoMap.end()) - { - sql =QString("insert into %1 (key_id_tag,para_seq_no,para_key_tag,description,location_id,sub_system,calc_flag) values ").arg("calc_in_para"); - QList paraList = it.value(); - for(int index(0);indexm_nId)).arg(paraList.at(index)->m_tag).arg(paraList.at(index)->m_strTip).arg(loction); - }else - { - sql += QString("('%1',%2,'%3','%4',%5,4,1),").arg(tableTagValue).arg((paraList.at(index)->m_nId)).arg(paraList.at(index)->m_tag).arg(paraList.at(index)->m_strTip).arg(loction); - } - } - } - if(!sql.isEmpty() && !execute(sql)) - { - return ; - } - if(!m_pWriteDb->commit()) - { - QMessageBox::warning(0,tr("提示"),tr("添加失败!正在回滚事务~")); - LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); - m_pWriteDb->rollback(); - }else - { - accept(); - QMessageBox::warning(0,tr("提示"),tr("添加成功")); - } -} - -QString AddObjAlarmDialog::getOneTagName() -{ - AlarmUuidBase64 uuid; - - QString dev = ui->comboBox->currentData().toString(); - QString tag = QString("%1.%2").arg(dev).arg(uuid.generateUuidBase64()); - - return tag; -} - -int AddObjAlarmDialog::getDevType() -{ - QString devTag = ui->comboBox->currentData().toString(); - for(int index(0);indexcomboBox->currentData().toString(); - for(int index(0);indexexecute(sql)) - { - QMessageBox::warning(0,tr("提示"),tr("添加失败!正在回滚事务~")); - LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); - m_pWriteDb->rollback(); - return false; - } - return true; -} - -void AddObjAlarmDialog::pointTypeChange(int index) -{ - ui->stackedWidget->setCurrentIndex(index); -} - -void AddObjAlarmDialog::alarmLevelChange(int index) -{ - Q_UNUSED(index); - int priority = ui->comboBox_2->currentData().toInt(); - int act = m_alarmLevelActionMap.value(priority,0); - QMap::iterator it = m_alarmActionCheckMap.begin(); - while (it != m_alarmActionCheckMap.end()) { - it.value()->setChecked(false); - if(act>>(it.key()-1) & 0x0001) - { - it.value()->setChecked(true); - } - it++; - } -} - -void AddObjAlarmDialog::funcChange(int index) -{ - Q_UNUSED(index); - emit sigClearPara(); - QString func = ui->comboBox_3->currentData().toString(); - QMap >::iterator it = m_calcInfoMap.find(func); - if(it != m_calcInfoMap.end()) - { - QList paraList = it.value(); - for(int index(0);indexm_tag = QString(); - } - emit sigChangePara(paraList); - } -} - -void AddObjAlarmDialog::addObj() -{ - if(!checkIfAdd()) - { - return ; - } - int type = ui->cbObjType->currentData().toInt(); - if(type == 0) - { - saveAi(); - }else - { - saveDi(); - } -} +#include "AddObjAlarmDialog.h" +#include "ui_AddObjAlarmDialog.h" +#include "AlarmMng.h" +#include "AlarmCalcParaTableDelegate.h" +#include +#include +#include "model_table/CustomWidget/kbdselectpointdlg.h" +#include "model_table/CustomWidget/kbdfindpointwidget.h" +#include +#include "AlarmUuidBase64.h" +#include "pub_logger_api/logger.h" +#include "kbdtabledatamgr.h" +#include +AddObjAlarmDialog::AddObjAlarmDialog(QList devList, QWidget *parent) : + QDialog(parent), + m_pWriteDb(Q_NULLPTR), + m_devList(devList), + m_model(Q_NULLPTR), + m_delegate(Q_NULLPTR), + ui(new Ui::AddObjAlarmDialog) +{ + ui->setupUi(this); + Qt::WindowFlags flags=Qt::Dialog; + flags |=Qt::WindowCloseButtonHint; + setWindowFlags(flags); + + this->setWindowTitle(tr("新增告警点")); + KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); + initLayout(); + initMember(); + initData(); + initConnect(); + initView(); +} + +AddObjAlarmDialog::~AddObjAlarmDialog() +{ + if(m_pWriteDb) + { + m_pWriteDb->close(); + delete m_pWriteDb; + } + m_pWriteDb = NULL; + if(m_model) + { + delete m_model; + } + m_model = NULL; + delete ui; +} + +void AddObjAlarmDialog::slotViewUpdate() +{ + ui->tableView->viewport()->update(); +} + +void AddObjAlarmDialog::slotSelectPoint(AlarmCalcInfoPtr info) +{ + + LOGDEBUG("选点--------------------------------------------------"); +// TestDialog dlg; +// dlg.exec(); + KbdSelectPointDlg dlg; + QStringList list; + list << QString("sql@SELECT * FROM SYS_MODEL_LOCATION_INFO order by LOCATION_NO;LOCATION_ID:DESCRIPTION") + <getSelectDescByIndex(6) == "") + return; + QString tagStr = QString("%1.%2.%3") + .arg(dlg.findPointWidget()->getSelectDataByIndex(5)) + .arg(dlg.findPointWidget()->getSelectDataByIndex(6)) + .arg(dlg.findPointWidget()->getSelectDataByIndex(7)); + info->m_tag = tagStr; + +} + +void AddObjAlarmDialog::initLayout() +{ + ui->comboBox->setView(new QListView()); + ui->comboBox_2->setView(new QListView()); + ui->comboBox_3->setView(new QListView()); + ui->comboBox_4->setView(new QListView()); + ui->cbObjType->setView(new QListView()); +} + +void AddObjAlarmDialog::initMember() +{ + if(m_pWriteDb == NULL) + { + m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); + m_pWriteDb->open(); + } + if(m_model == NULL) + { + m_model = new AlarmCalcParaTableModel(this,ui->tableView); + } + if(m_delegate == NULL) + { + m_delegate = new AlarmCalcParaTableDelegate(m_model,this); + } + ui->tableView->setAlternatingRowColors(true); + ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + ui->tableView->horizontalHeader()->setStretchLastSection(true); + ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); + //ui->tableView->setHorizontalScrollMode(ScrollPerPixel); + ui->tableView->setModel(m_model); + ui->tableView->setItemDelegateForColumn(2,m_delegate); + ui->tableView->setColumnWidth(0,110); + ui->tableView->setColumnWidth(1,380); +} + +void AddObjAlarmDialog::initData() +{ + m_alarmLevelMap = AlarmMng::instance()->getAlarmLevel(); + m_alarmLevelActionMap = AlarmMng::instance()->getAlarmLevelAction(); + m_alarmActionMap = AlarmMng::instance()->getAlarmAction(); + m_funcMap = AlarmMng::instance()->getFuncInfo(); + m_calcInfoMap = AlarmMng::instance()->getCalcInfo(); + m_diTextList = AlarmMng::instance()->getDiText(); +} + +void AddObjAlarmDialog::initConnect() +{ + connect(ui->cbObjType,SIGNAL(currentIndexChanged(int)),this,SLOT(pointTypeChange(int))); + connect(ui->comboBox_2,SIGNAL(currentIndexChanged(int)),this,SLOT(alarmLevelChange(int))); + connect(ui->comboBox_3,SIGNAL(currentIndexChanged(int)),this,SLOT(funcChange(int))); + connect(this,&AddObjAlarmDialog::sigChangePara,m_model,&AlarmCalcParaTableModel::slotChangePara); + connect(this,&AddObjAlarmDialog::sigClearPara,m_model,&AlarmCalcParaTableModel::slotClearPara); + connect(m_delegate,&AlarmCalcParaTableDelegate::sigViewUpdate,this,&AddObjAlarmDialog::slotViewUpdate); + connect(m_delegate,&AlarmCalcParaTableDelegate::sigselectPoint,this,&AddObjAlarmDialog::slotSelectPoint); + connect(ui->pushButton,&QPushButton::clicked,this,&AddObjAlarmDialog::addObj); + connect(ui->pushButton_2,&QPushButton::clicked,this,&AddObjAlarmDialog::reject); +} + +void AddObjAlarmDialog::initView() +{ + ui->comboBox->clear(); + for(int index(0);indexcomboBox->addItem(m_devList.at(index).strDevDesc,m_devList.at(index).strDev); + } + + ui->cbObjType->clear(); + ui->cbObjType->addItem(tr("模拟量"),0); + ui->cbObjType->addItem(tr("数字量"),1); + + ui->comboBox_2->clear(); + int index = 0; + QMap::iterator it_level = m_alarmLevelMap.begin(); + while (it_level != m_alarmLevelMap.end()) { + ui->comboBox_2->addItem(it_level.value(),it_level.key()); + m_alarmLevelIndexMap[it_level.key()] = index++; + it_level++; + } + + QHBoxLayout *hLayout = new QHBoxLayout; + QVBoxLayout *vLayout0 = new QVBoxLayout; + QVBoxLayout *vLayout1 = new QVBoxLayout; + QVBoxLayout *vLayout2 = new QVBoxLayout; + index = 0; + QMap::iterator it = m_alarmActionMap.begin(); + while (it != m_alarmActionMap.end()) { + + QCheckBox *box = new QCheckBox(it.value(),ui->widget); + box->setMinimumHeight(19); + m_alarmActionCheckMap[it.key()] = box; + if(index % 3 == 0) + { + vLayout0->addWidget(box); + }else if(index % 3 == 1) + { + vLayout1->addWidget(box); + }else if(index % 3 == 2) + { + vLayout2->addWidget(box); + } + index++; + it++; + } + vLayout0->addStretch(100); + vLayout1->addStretch(100); + vLayout2->addStretch(100); + + hLayout->addLayout(vLayout0); + + hLayout->addLayout(vLayout1); + hLayout->addLayout(vLayout2); + ui->widget->setLayout(hLayout); + ui->widget->setEnabled(false); + + ui->comboBox_3->clear(); + QMap::iterator pos = m_funcMap.begin(); + while (pos != m_funcMap.end()) { + ui->comboBox_3->addItem(pos.value(),pos.key()); + pos++; + } + ui->comboBox_4->clear(); + for(int index(0);indexcomboBox_4->addItem(m_diTextList.at(index),m_diTextList.at(index)); + } + + hideDiText(); + alarmLevelChange(0); + funcChange(0); +} + +bool AddObjAlarmDialog::checkIfAdd() +{ + QString st = ui->lineEdit->text(); + if(st.isEmpty()) + { + QMessageBox::warning(0,tr("提示"),tr("自定义告警名称不能为空!")); + return false; + } + QString func = ui->comboBox_3->currentData().toString(); + if(func.isEmpty()) + { + QMessageBox::warning(0,tr("提示"),tr("无告警点计算函数,请先配置计算点函数!")); + return false; + } + QMap >::iterator it= m_calcInfoMap.find(func); + if(it != m_calcInfoMap.end()) + { + QList paraList = it.value(); + QList::iterator pos = paraList.begin(); + while (pos != paraList.end()) { + if((*pos)->m_tag.isEmpty()) + { + QMessageBox::warning(0,tr("提示"),tr("参数:%1的参数标签不能为空!").arg((*pos)->m_strTip)); + return false; + } + pos++; + } + } + int type = ui->cbObjType->currentData().toInt(); + if(type == 0) + { + //模拟量 + int limitUp1 = ui->doubleSpinBox->value(); + int limitLow1 = ui->doubleSpinBox_2->value(); + if(limitLow1>=limitUp1) + { + QMessageBox::warning(0,tr("提示"),tr("越下限值必须小于越上限值!")); + return false; + } + }else + { + //数字量 + QString diText = ui->comboBox_4->currentData().toString(); + if(diText.isEmpty()) + { + QMessageBox::warning(0,tr("提示"),tr("无数字量文本,请先配置数字量文本!")); + return false; + } + } + return true; +} + +void AddObjAlarmDialog::hideDiText() +{ + +} + +void AddObjAlarmDialog::saveAi() +{ + QString tag = getOneTagName(); + QString tableTagValue = "analog."+tag+".value"; + int devType = getDevType(); + int loction = getLoctionId(); + QString desc =ui->lineEdit->text(); + QString devTag = ui->comboBox->currentData().toString(); + double limitUp1 = ui->doubleSpinBox->value(); + double limitLow1 = ui->doubleSpinBox_2->value(); + int priority = ui->comboBox_2->currentData().toInt(); + QString funcName = ui->comboBox_3->currentData().toString(); + m_pWriteDb->transaction(); + QString sql = QString("insert into %1 (tag_name,description,dev_type,device" + ",location_id,sub_system,unit_id,region_id,is_limit" + ",point_type,point_property,is_sample,sample_period,sample_deadband) values('%2','%3',%4,'%5'" + ",%6,4,1,1,1,0,1,1,5,0.5)").arg("analog").arg(tag).arg(desc).arg(devType).arg(devTag).arg(loction); + if(!execute(sql)) + { + return ; + } + + //< analog触发器自动生成一条analog_limit_info + sql = QString("update %1 set limit_type=%2,limit_num=%3,limit_up1=%4,limit_low1=%5,cross_percent=%6,return_percent=%7,is_obj_alm_manner=%8," + "alarm_priority=%9 where tag_name='%10'").arg("analog_limit_info").arg(1).arg(1).arg(limitUp1).arg(limitLow1).arg(5).arg(5).arg(1).arg(priority).arg(tag); + + if(!execute(sql)) + { + return ; + } + + sql = QString("insert into %1 (key_id_tag,description,location_id,sub_system,func_name,calc_flag) values('%2','%3',%4,4,'%5',1)").arg("calc_out_para").arg(tableTagValue).arg(desc).arg(loction).arg(funcName); + if(!execute(sql)) + { + return ; + } + sql = ""; + QMap >::iterator it= m_calcInfoMap.find(funcName); + if(it != m_calcInfoMap.end()) + { + sql =QString("insert into %1 (key_id_tag,para_seq_no,para_key_tag,description,location_id,sub_system,calc_flag) values ").arg("calc_in_para"); + QList paraList = it.value(); + for(int index(0);indexm_nId)).arg(paraList.at(index)->m_tag).arg(paraList.at(index)->m_strTip).arg(loction); + }else + { + sql += QString("('%1',%2,'%3','%4',%5,4,1),").arg(tableTagValue).arg((paraList.at(index)->m_nId)).arg(paraList.at(index)->m_tag).arg(paraList.at(index)->m_strTip).arg(loction); + } + } + } + + if(!sql.isEmpty() && !execute(sql)) + { + return ; + } + + if(!m_pWriteDb->commit()) + { + QMessageBox::warning(0,tr("提示"),tr("添加失败!正在回滚事务~")); + LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); + m_pWriteDb->rollback(); + }else + { + accept(); + QMessageBox::warning(0,tr("提示"),tr("添加成功")); + } +} + +void AddObjAlarmDialog::saveDi() +{ + QString tag = getOneTagName(); + QString tableTagValue = "digital."+tag+".value"; + int devType = getDevType(); + int loction = getLoctionId(); + QString desc =ui->lineEdit->text(); + QString devTag = ui->comboBox->currentData().toString(); + QString diText = ui->comboBox_4->currentData().toString(); + int priority = ui->comboBox_2->currentData().toInt(); + QString funcName = ui->comboBox_3->currentData().toString(); + m_pWriteDb->transaction(); + QString sql = QString("insert into %1 (tag_name,description,device" + ",location_id,sub_system,state_text_name,value_num,is_obj_alm_manner,alarm_priority,alarm_priority_soe" + ",is_water_alm,region_id,point_type,point_property,point_sort,dev_type" + ",is_sample,sample_period,alarm_freq,alarm_freq_desc,alarm_time,alarm_time_desc,alarm_freq_range) values('%2','%3','%4'" + ",%5,4,'%6',1,1,%7,3,1,1,1,1,300,%8,1,5,10,'%9',5,'%10',30)").arg("digital").arg(tag).arg(desc).arg(devTag) + .arg(loction).arg(diText).arg(priority).arg(devType).arg(tr("计次告警描述")).arg(tr("计时告警描述")); + if(!execute(sql)) + { + return ; + } + + sql = QString("insert into %1 (key_id_tag,description,location_id,sub_system,func_name,calc_flag) values('%2','%3',%4,4,'%5',1)").arg("calc_out_para").arg(tableTagValue).arg(desc).arg(loction).arg(funcName); + if(!execute(sql)) + { + return ; + } + QMap >::iterator it= m_calcInfoMap.find(funcName); + sql = ""; + if(it != m_calcInfoMap.end()) + { + sql =QString("insert into %1 (key_id_tag,para_seq_no,para_key_tag,description,location_id,sub_system,calc_flag) values ").arg("calc_in_para"); + QList paraList = it.value(); + for(int index(0);indexm_nId)).arg(paraList.at(index)->m_tag).arg(paraList.at(index)->m_strTip).arg(loction); + }else + { + sql += QString("('%1',%2,'%3','%4',%5,4,1),").arg(tableTagValue).arg((paraList.at(index)->m_nId)).arg(paraList.at(index)->m_tag).arg(paraList.at(index)->m_strTip).arg(loction); + } + } + } + if(!sql.isEmpty() && !execute(sql)) + { + return ; + } + if(!m_pWriteDb->commit()) + { + QMessageBox::warning(0,tr("提示"),tr("添加失败!正在回滚事务~")); + LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); + m_pWriteDb->rollback(); + }else + { + accept(); + QMessageBox::warning(0,tr("提示"),tr("添加成功")); + } +} + +QString AddObjAlarmDialog::getOneTagName() +{ + AlarmUuidBase64 uuid; + + QString dev = ui->comboBox->currentData().toString(); + QString tag = QString("%1.%2").arg(dev).arg(uuid.generateUuidBase64()); + + return tag; +} + +int AddObjAlarmDialog::getDevType() +{ + QString devTag = ui->comboBox->currentData().toString(); + for(int index(0);indexcomboBox->currentData().toString(); + for(int index(0);indexexecute(sql)) + { + QMessageBox::warning(0,tr("提示"),tr("添加失败!正在回滚事务~")); + LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); + m_pWriteDb->rollback(); + return false; + } + return true; +} + +void AddObjAlarmDialog::pointTypeChange(int index) +{ + ui->stackedWidget->setCurrentIndex(index); +} + +void AddObjAlarmDialog::alarmLevelChange(int index) +{ + Q_UNUSED(index); + int priority = ui->comboBox_2->currentData().toInt(); + int act = m_alarmLevelActionMap.value(priority,0); + QMap::iterator it = m_alarmActionCheckMap.begin(); + while (it != m_alarmActionCheckMap.end()) { + it.value()->setChecked(false); + if(act>>(it.key()-1) & 0x0001) + { + it.value()->setChecked(true); + } + it++; + } +} + +void AddObjAlarmDialog::funcChange(int index) +{ + Q_UNUSED(index); + emit sigClearPara(); + QString func = ui->comboBox_3->currentData().toString(); + QMap >::iterator it = m_calcInfoMap.find(func); + if(it != m_calcInfoMap.end()) + { + QList paraList = it.value(); + for(int index(0);indexm_tag = QString(); + } + emit sigChangePara(paraList); + } +} + +void AddObjAlarmDialog::addObj() +{ + if(!checkIfAdd()) + { + return ; + } + int type = ui->cbObjType->currentData().toInt(); + if(type == 0) + { + saveAi(); + }else + { + saveDi(); + } +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.h b/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.h index 85b58faa..984bfc85 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.h +++ b/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.h @@ -1,94 +1,94 @@ -#ifndef ADDOBJALARMDIALOG_H -#define ADDOBJALARMDIALOG_H - -#include -#include "db_api_ex/CDbApi.h" -#include -#include "AlarmCalcInfo.h" -#include "AlarmManageCommon.h" -#include "AlarmCalcParaTableModel.h" -#include "AlarmCalcParaTableDelegate.h" - -namespace Ui { -class AddObjAlarmDialog; -} - -class AddObjAlarmDialog : public QDialog -{ - Q_OBJECT - -public: - explicit AddObjAlarmDialog(QList devList,QWidget *parent = 0); - ~AddObjAlarmDialog(); - -signals: - void sigChangePara(QList); - - void sigClearPara(); - -public slots: - void slotViewUpdate(); - - void slotSelectPoint(AlarmCalcInfoPtr info); -private: - void initLayout(); - - void initMember(); - - void initData(); - - void initConnect(); - - void initView(); - - bool checkIfAdd(); - - void hideDiText(); - - void saveAi(); - - void saveDi(); - - QString getOneTagName(); - - int getDevType(); - - int getLoctionId(); - - bool execute(const QString &sql); - -private slots: - void pointTypeChange(int index); - - void alarmLevelChange(int index); - - void funcChange(int index); - - void addObj(); - -private: - Ui::AddObjAlarmDialog *ui; - - kbd_dbms::CDbApi *m_pWriteDb; - - QMap m_alarmActionCheckMap;//选中的告警动作 - - QMap m_alarmActionMap; //告警动作 - QMap m_alarmLevelActionMap; //等级--动作 - QMap m_alarmLevelMap; //等级--等级描述 - - QMap m_alarmLevelIndexMap; - - QMap m_funcMap; //计算公式 - - QMap > m_calcInfoMap; //计算公式参数 - - QList m_devList; - - QList m_diTextList; - AlarmCalcParaTableModel *m_model; - AlarmCalcParaTableDelegate *m_delegate; - -}; - -#endif // ADDOBJALARMDIALOG_H +#ifndef ADDOBJALARMDIALOG_H +#define ADDOBJALARMDIALOG_H + +#include +#include "db_api_ex/CDbApi.h" +#include +#include "AlarmCalcInfo.h" +#include "AlarmManageCommon.h" +#include "AlarmCalcParaTableModel.h" +#include "AlarmCalcParaTableDelegate.h" + +namespace Ui { +class AddObjAlarmDialog; +} + +class AddObjAlarmDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AddObjAlarmDialog(QList devList,QWidget *parent = 0); + ~AddObjAlarmDialog(); + +signals: + void sigChangePara(QList); + + void sigClearPara(); + +public slots: + void slotViewUpdate(); + + void slotSelectPoint(AlarmCalcInfoPtr info); +private: + void initLayout(); + + void initMember(); + + void initData(); + + void initConnect(); + + void initView(); + + bool checkIfAdd(); + + void hideDiText(); + + void saveAi(); + + void saveDi(); + + QString getOneTagName(); + + int getDevType(); + + int getLoctionId(); + + bool execute(const QString &sql); + +private slots: + void pointTypeChange(int index); + + void alarmLevelChange(int index); + + void funcChange(int index); + + void addObj(); + +private: + Ui::AddObjAlarmDialog *ui; + + kbd_dbms::CDbApi *m_pWriteDb; + + QMap m_alarmActionCheckMap;//选中的告警动作 + + QMap m_alarmActionMap; //告警动作 + QMap m_alarmLevelActionMap; //等级--动作 + QMap m_alarmLevelMap; //等级--等级描述 + + QMap m_alarmLevelIndexMap; + + QMap m_funcMap; //计算公式 + + QMap > m_calcInfoMap; //计算公式参数 + + QList m_devList; + + QList m_diTextList; + AlarmCalcParaTableModel *m_model; + AlarmCalcParaTableDelegate *m_delegate; + +}; + +#endif // ADDOBJALARMDIALOG_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.ui b/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.ui index c02e5d22..732f6317 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.ui +++ b/product/src/gui/plugin/AlarmManageWidget/AddObjAlarmDialog.ui @@ -1,335 +1,335 @@ - - - AddObjAlarmDialog - - - - 0 - 0 - 655 - 554 - - - - - 655 - 554 - - - - - 655 - 554 - - - - Dialog - - - - - - - - - 90 - 0 - - - - 设备 - - - - - - - - 0 - 0 - - - - - - - - - - - - - 90 - 0 - - - - 自定义告警名称 - - - - - - - - - - 类型 - - - - - - - - 0 - 0 - - - - - - - - - - - - - 90 - 0 - - - - 告警等级定义 - - - - - - - - 100 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - - - - - 90 - 0 - - - - 告警点计算函数 - - - - - - - - 0 - 0 - - - - - - - - - - - 16777215 - 88 - - - - 告警规则 - - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - - - - - 越上限值 - - - - - - - - 0 - 0 - - - - 6 - - - -100000000.000000000000000 - - - 100000000.000000000000000 - - - - - - - 越下限值 - - - - - - - - 0 - 0 - - - - 6 - - - -100000000.000000000000000 - - - 100000000.000000000000000 - - - 0.000000000000000 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - - - 数字量文本: - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 添加 - - - - - - - 取消 - - - - - - - - 0 - 0 - - - - - - - - - + + + AddObjAlarmDialog + + + + 0 + 0 + 655 + 554 + + + + + 655 + 554 + + + + + 655 + 554 + + + + Dialog + + + + + + + + + 90 + 0 + + + + 设备 + + + + + + + + 0 + 0 + + + + + + + + + + + + + 90 + 0 + + + + 自定义告警名称 + + + + + + + + + + 类型 + + + + + + + + 0 + 0 + + + + + + + + + + + + + 90 + 0 + + + + 告警等级定义 + + + + + + + + 100 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + + + + + 90 + 0 + + + + 告警点计算函数 + + + + + + + + 0 + 0 + + + + + + + + + + + 16777215 + 88 + + + + 告警规则 + + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + + + + + 越上限值 + + + + + + + + 0 + 0 + + + + 6 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + + + + + 越下限值 + + + + + + + + 0 + 0 + + + + 6 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + 0.000000000000000 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + + + 数字量文本: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 添加 + + + + + + + 取消 + + + + + + + + 0 + 0 + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcInfo.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcInfo.cpp index d0320304..5bca2473 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcInfo.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcInfo.cpp @@ -1,9 +1,9 @@ -#include "AlarmCalcInfo.h" - -AlarmCalcInfo::AlarmCalcInfo() -{ - m_nId = -1; //第几个 - m_strTip = QString(); - m_tag = QString(); - m_desc = QString(); //可空 -} +#include "AlarmCalcInfo.h" + +AlarmCalcInfo::AlarmCalcInfo() +{ + m_nId = -1; //第几个 + m_strTip = QString(); + m_tag = QString(); + m_desc = QString(); //可空 +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcInfo.h b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcInfo.h index 0ae186f4..8195d702 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcInfo.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcInfo.h @@ -1,23 +1,23 @@ -#ifndef ALARMCALCINFO_H -#define ALARMCALCINFO_H - -#include - -class AlarmCalcInfo; -typedef QSharedPointer AlarmCalcInfoPtr; - -class AlarmCalcInfo -{ -public: - AlarmCalcInfo(); - - int m_nId; //第几个 - QString m_strTip; - QString m_tag; - QString m_desc; //可空 - -}; -Q_DECLARE_METATYPE(AlarmCalcInfo) -Q_DECLARE_METATYPE(AlarmCalcInfoPtr) - -#endif // ALARMCALCINFO_H +#ifndef ALARMCALCINFO_H +#define ALARMCALCINFO_H + +#include + +class AlarmCalcInfo; +typedef QSharedPointer AlarmCalcInfoPtr; + +class AlarmCalcInfo +{ +public: + AlarmCalcInfo(); + + int m_nId; //第几个 + QString m_strTip; + QString m_tag; + QString m_desc; //可空 + +}; +Q_DECLARE_METATYPE(AlarmCalcInfo) +Q_DECLARE_METATYPE(AlarmCalcInfoPtr) + +#endif // ALARMCALCINFO_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableDelegate.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableDelegate.cpp index 4c1d251c..7cf3903f 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableDelegate.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableDelegate.cpp @@ -1,74 +1,74 @@ -#include "AlarmCalcParaTableDelegate.h" -#include -#include -#include -#include "AlarmCalcInfo.h" -#include -#include "public/pub_logger_api/logger.h" - -AlarmCalcParaTableDelegate::AlarmCalcParaTableDelegate(AlarmCalcParaTableModel *model, QObject *parent) - :m_pModel(model), - QStyledItemDelegate(parent) -{ - -} - -void AlarmCalcParaTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - AlarmCalcInfoPtr info = m_pModel->getCalcParaInfo(index); - if(info == NULL) - { - return ; - } - QStyleOptionButton buttonOption; - buttonOption.state |= QStyle::State_Enabled; - buttonOption.state |= QStyle::State_On; - buttonOption.features = QStyleOptionButton::Flat; -// bool hover = index.model()->data(index, Qt::UserRole).toBool(); -// if(hover) -// { -// buttonOption.state |= QStyle::State_On; -// } -// else -// { -// buttonOption.state |= QStyle::State_Off; -// } - - buttonOption.rect = option.rect; - buttonOption.rect.adjust(option.rect.width()/2-32,2,-(option.rect.width()/2-32),-2); - buttonOption.text = "···"; - painter->save(); - - if(option.state & QStyle::State_Selected){ - painter->fillRect(option.rect,option.palette.highlight()); - } - painter->restore(); - - QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter); -} - -bool AlarmCalcParaTableDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - Q_UNUSED(model); - AlarmCalcInfoPtr info = m_pModel->getCalcParaInfo(index); - if(event->type() == QEvent::MouseButtonRelease){ - - QMouseEvent *e = (QMouseEvent*)event; - - if((e != NULL && e->button() == Qt::LeftButton && e->type() == QMouseEvent::MouseButtonRelease)) - { - - QStyleOptionButton buttonOption; - buttonOption.rect = option.rect; - buttonOption.rect.adjust(option.rect.width()/2-32,2,-(option.rect.width()/2-32),-2); - QRect rect = buttonOption.rect; - - if(rect.contains(e->pos())) - { - LOGDEBUG("选点---------------------------------111111-----------------"); - emit sigselectPoint(info); - } - } - } - return true; -} +#include "AlarmCalcParaTableDelegate.h" +#include +#include +#include +#include "AlarmCalcInfo.h" +#include +#include "public/pub_logger_api/logger.h" + +AlarmCalcParaTableDelegate::AlarmCalcParaTableDelegate(AlarmCalcParaTableModel *model, QObject *parent) + :m_pModel(model), + QStyledItemDelegate(parent) +{ + +} + +void AlarmCalcParaTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + AlarmCalcInfoPtr info = m_pModel->getCalcParaInfo(index); + if(info == NULL) + { + return ; + } + QStyleOptionButton buttonOption; + buttonOption.state |= QStyle::State_Enabled; + buttonOption.state |= QStyle::State_On; + buttonOption.features = QStyleOptionButton::Flat; +// bool hover = index.model()->data(index, Qt::UserRole).toBool(); +// if(hover) +// { +// buttonOption.state |= QStyle::State_On; +// } +// else +// { +// buttonOption.state |= QStyle::State_Off; +// } + + buttonOption.rect = option.rect; + buttonOption.rect.adjust(option.rect.width()/2-32,2,-(option.rect.width()/2-32),-2); + buttonOption.text = "···"; + painter->save(); + + if(option.state & QStyle::State_Selected){ + painter->fillRect(option.rect,option.palette.highlight()); + } + painter->restore(); + + QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter); +} + +bool AlarmCalcParaTableDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + Q_UNUSED(model); + AlarmCalcInfoPtr info = m_pModel->getCalcParaInfo(index); + if(event->type() == QEvent::MouseButtonRelease){ + + QMouseEvent *e = (QMouseEvent*)event; + + if((e != NULL && e->button() == Qt::LeftButton && e->type() == QMouseEvent::MouseButtonRelease)) + { + + QStyleOptionButton buttonOption; + buttonOption.rect = option.rect; + buttonOption.rect.adjust(option.rect.width()/2-32,2,-(option.rect.width()/2-32),-2); + QRect rect = buttonOption.rect; + + if(rect.contains(e->pos())) + { + LOGDEBUG("选点---------------------------------111111-----------------"); + emit sigselectPoint(info); + } + } + } + return true; +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableDelegate.h b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableDelegate.h index 55c4836a..742cc974 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableDelegate.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableDelegate.h @@ -1,28 +1,28 @@ -#ifndef ALARMCALCPARATABLEDELEGATE_H -#define ALARMCALCPARATABLEDELEGATE_H - -#include -#include - - -class AlarmCalcParaTableDelegate : public QStyledItemDelegate -{ - Q_OBJECT - -public: - AlarmCalcParaTableDelegate(AlarmCalcParaTableModel *model, QObject *parent = 0); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; - -signals: - void sigViewUpdate(); - - void sigselectPoint(AlarmCalcInfoPtr info); - -private: - AlarmCalcParaTableModel * m_pModel; -}; - -#endif // ALARMCALCPARATABLEDELEGATE_H +#ifndef ALARMCALCPARATABLEDELEGATE_H +#define ALARMCALCPARATABLEDELEGATE_H + +#include +#include + + +class AlarmCalcParaTableDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + AlarmCalcParaTableDelegate(AlarmCalcParaTableModel *model, QObject *parent = 0); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; + +signals: + void sigViewUpdate(); + + void sigselectPoint(AlarmCalcInfoPtr info); + +private: + AlarmCalcParaTableModel * m_pModel; +}; + +#endif // ALARMCALCPARATABLEDELEGATE_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableModel.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableModel.cpp index 021587a0..d33b7c4a 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableModel.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableModel.cpp @@ -1,122 +1,122 @@ -#include "AlarmCalcParaTableModel.h" - -AlarmCalcParaTableModel::AlarmCalcParaTableModel(QObject *parent,QTableView *view) - : m_view(view), - QAbstractTableModel(parent) -{ - m_header <m_strTip; - break; - case 1: - return m_list.at(index.row())->m_tag; - break; - case 2: - return QVariant(); - break; - default: - break; - } - } - return QVariant(); -} - -bool AlarmCalcParaTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if ( role == Qt::EditRole ) - { - int nCol = index.column(); - if ( value.toString() == "" ) - return false; - switch ( nCol ) - { - case 1: - if ( m_list.at(index.row())->m_tag != value.toString() ) - { - m_list.at(index.row())->m_tag = value.toString(); - } - break; - default: - break; - } - } - - return false; -} - -Qt::ItemFlags AlarmCalcParaTableModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - if(index.column() == 1) - { - return Qt::ItemIsEditable | QAbstractTableModel::flags(index); - }else - { - return QAbstractTableModel::flags(index); - } -} - -AlarmCalcInfoPtr AlarmCalcParaTableModel::getCalcParaInfo(const QModelIndex &index) -{ - if(m_list.count()>index.row()) - { - return m_list.value(index.row()); - } - return NULL; -} - -void AlarmCalcParaTableModel::slotChangePara(QList paraList) -{ - beginResetModel(); - m_list.clear(); - m_list = paraList; - endResetModel(); -} - -void AlarmCalcParaTableModel::slotClearPara() -{ - beginResetModel(); - m_list.clear(); - endResetModel(); -} +#include "AlarmCalcParaTableModel.h" + +AlarmCalcParaTableModel::AlarmCalcParaTableModel(QObject *parent,QTableView *view) + : m_view(view), + QAbstractTableModel(parent) +{ + m_header <m_strTip; + break; + case 1: + return m_list.at(index.row())->m_tag; + break; + case 2: + return QVariant(); + break; + default: + break; + } + } + return QVariant(); +} + +bool AlarmCalcParaTableModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if ( role == Qt::EditRole ) + { + int nCol = index.column(); + if ( value.toString() == "" ) + return false; + switch ( nCol ) + { + case 1: + if ( m_list.at(index.row())->m_tag != value.toString() ) + { + m_list.at(index.row())->m_tag = value.toString(); + } + break; + default: + break; + } + } + + return false; +} + +Qt::ItemFlags AlarmCalcParaTableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + if(index.column() == 1) + { + return Qt::ItemIsEditable | QAbstractTableModel::flags(index); + }else + { + return QAbstractTableModel::flags(index); + } +} + +AlarmCalcInfoPtr AlarmCalcParaTableModel::getCalcParaInfo(const QModelIndex &index) +{ + if(m_list.count()>index.row()) + { + return m_list.value(index.row()); + } + return NULL; +} + +void AlarmCalcParaTableModel::slotChangePara(QList paraList) +{ + beginResetModel(); + m_list.clear(); + m_list = paraList; + endResetModel(); +} + +void AlarmCalcParaTableModel::slotClearPara() +{ + beginResetModel(); + m_list.clear(); + endResetModel(); +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableModel.h b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableModel.h index 390ec362..55e6ab40 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableModel.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmCalcParaTableModel.h @@ -1,38 +1,38 @@ -#ifndef ALARMCALCPARATABLEMODEL_H -#define ALARMCALCPARATABLEMODEL_H - -#include -#include "AlarmCalcInfo.h" -#include - -class AlarmCalcParaTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit AlarmCalcParaTableModel(QObject *parent = nullptr,QTableView *view = Q_NULLPTR); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ); - Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; - - - AlarmCalcInfoPtr getCalcParaInfo(const QModelIndex &index); -public slots: - void slotChangePara(QList paraList); - - void slotClearPara(); -private: - QTableView *m_view; - QStringList m_header; - QList m_list; -}; - -#endif // ALARMCALCPARATABLEMODEL_H +#ifndef ALARMCALCPARATABLEMODEL_H +#define ALARMCALCPARATABLEMODEL_H + +#include +#include "AlarmCalcInfo.h" +#include + +class AlarmCalcParaTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit AlarmCalcParaTableModel(QObject *parent = nullptr,QTableView *view = Q_NULLPTR); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ); + Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; + + + AlarmCalcInfoPtr getCalcParaInfo(const QModelIndex &index); +public slots: + void slotChangePara(QList paraList); + + void slotClearPara(); +private: + QTableView *m_view; + QStringList m_header; + QList m_list; +}; + +#endif // ALARMCALCPARATABLEMODEL_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeModel.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeModel.cpp index c6ab9f66..0676e1e4 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeModel.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeModel.cpp @@ -1,233 +1,233 @@ -#include "AlarmDevTreeModel.h" -#include "AlarmDevTreeView.h" -#include "QTreeWidgetItem" -#include -#include "AlarmMng.h" - -AlarmDevTreeModel::AlarmDevTreeModel(QObject *parent,QTreeView *view) - : QAbstractItemModel(parent), - m_pView(view), - m_isLink(false), - m_root(Q_NULLPTR) -{ - m_root = new QTreeWidgetItem(); - m_devTypeMap = AlarmMng::instance()->getDevType(); - init(); -} - -AlarmDevTreeModel::~AlarmDevTreeModel() -{ - if(Q_NULLPTR != m_root) - { - delete m_root; - } - m_root = Q_NULLPTR; -} - -QVariant AlarmDevTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(section) - Q_UNUSED(role) - if(role == Qt::DisplayRole) - { - if(orientation == Qt::Horizontal) - { - return QVariant(tr("位置/设备组")); - } - } - return QVariant(); -} - -QModelIndex AlarmDevTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if(!hasIndex(row, column, parent) || Q_NULLPTR == m_root) - { - return QModelIndex(); - } - - QTreeWidgetItem * parentItem; - if(!parent.isValid()) - { - parentItem = m_root; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - if(parentItem) - { - QTreeWidgetItem *childItem = parentItem->child(row); - if(childItem) - { - return createIndex(row,0,childItem); - } - } - - return QModelIndex(); -} - -QModelIndex AlarmDevTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - QTreeWidgetItem *childItem = static_cast(index.internalPointer()); - if (!childItem) - { - return QModelIndex(); - } - - QTreeWidgetItem *parentItem = childItem->parent(); - - if (parentItem == m_root) - { - return QModelIndex(); - } - - int row = parentItem->parent()->indexOfChild(parentItem); - return createIndex(row, 0, parentItem); -} - -int AlarmDevTreeModel::rowCount(const QModelIndex &parent) const -{ - if(!parent.isValid()) - { - if (NULL != m_root) - { - return m_root->childCount(); - } - else - { - return 0; - } - } - else - { - QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); - } -} - -int AlarmDevTreeModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return 1; -} - -QVariant AlarmDevTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item) - { - return item->data(index.column(), role); - } - return QVariant(); -} - -Qt::ItemFlags AlarmDevTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - if(index.column()==0) - { - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; - } - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} - -void AlarmDevTreeModel::setFilter(QString text) -{ - m_fltText = text.toStdString(); - updateDevTreeNodeStatus(); - m_pView->viewport()->update(); -} - -void AlarmDevTreeModel::init() -{ - beginResetModel(); - QList locList = AlarmMng::instance()->getLocOrder(); - foreach (const int loc, locList) { - QString locdesc = AlarmMng::instance()->getLocDescById(loc); - QList devgList = AlarmMng::instance()->getDevGroupInfo(loc); - if(devgList.isEmpty()) - { - continue; - } - QTreeWidgetItem * locItem = new QTreeWidgetItem(m_root, QStringList() << locdesc); - locItem->setData(0, Qt::UserRole, loc); - locItem->setData(0, Qt::UserRole+1,LOCATION_TYPE); - locItem->setData(0, Qt::UserRole+2,locdesc); - for(int index(0);indexgetDevgDescByTag(devgList.at(index)); - QTreeWidgetItem * devgItem = new QTreeWidgetItem(locItem, QStringList() << devgdesc); - devgItem->setData(0, Qt::UserRole, devgList.at(index)); - devgItem->setData(0, Qt::UserRole+1,DEV_GROUP_TYPE); - devgItem->setData(0, Qt::UserRole+2,devgdesc); - } - } - endResetModel(); -} - -void AlarmDevTreeModel::updateDevTreeNodeStatus() -{ - if(!m_root) - { - return ; - } - if(m_fltText.empty()) - { - for(int nIndex(0); nIndexsetRowHidden(devgIndex,locModelIndex,false); - isShow = true; - } - else - { - m_pView->setRowHidden(devgIndex,locModelIndex,true); - } - } - m_pView->setRowHidden(locIndex, parent(locModelIndex), !isShow); - } - else - { - setAllChildShow(locModelIndex); - } - } -} - -void AlarmDevTreeModel::setAllChildShow(const QModelIndex &parent) -{ - m_pView->setRowHidden(parent.row(), parent.parent(), false); - int childCount = rowCount(parent); - for(int nIndex(0); nIndex < childCount; nIndex++) - { - m_pView->setRowHidden(nIndex, parent, false); - setAllChildShow(index(nIndex, 0, parent)); - } -} +#include "AlarmDevTreeModel.h" +#include "AlarmDevTreeView.h" +#include "QTreeWidgetItem" +#include +#include "AlarmMng.h" + +AlarmDevTreeModel::AlarmDevTreeModel(QObject *parent,QTreeView *view) + : QAbstractItemModel(parent), + m_pView(view), + m_isLink(false), + m_root(Q_NULLPTR) +{ + m_root = new QTreeWidgetItem(); + m_devTypeMap = AlarmMng::instance()->getDevType(); + init(); +} + +AlarmDevTreeModel::~AlarmDevTreeModel() +{ + if(Q_NULLPTR != m_root) + { + delete m_root; + } + m_root = Q_NULLPTR; +} + +QVariant AlarmDevTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(role) + if(role == Qt::DisplayRole) + { + if(orientation == Qt::Horizontal) + { + return QVariant(tr("位置/设备组")); + } + } + return QVariant(); +} + +QModelIndex AlarmDevTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_root) + { + return QModelIndex(); + } + + QTreeWidgetItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_root; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + QTreeWidgetItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,0,childItem); + } + } + + return QModelIndex(); +} + +QModelIndex AlarmDevTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + QTreeWidgetItem *childItem = static_cast(index.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + QTreeWidgetItem *parentItem = childItem->parent(); + + if (parentItem == m_root) + { + return QModelIndex(); + } + + int row = parentItem->parent()->indexOfChild(parentItem); + return createIndex(row, 0, parentItem); +} + +int AlarmDevTreeModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (NULL != m_root) + { + return m_root->childCount(); + } + else + { + return 0; + } + } + else + { + QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int AlarmDevTreeModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant AlarmDevTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + return item->data(index.column(), role); + } + return QVariant(); +} + +Qt::ItemFlags AlarmDevTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + if(index.column()==0) + { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +void AlarmDevTreeModel::setFilter(QString text) +{ + m_fltText = text.toStdString(); + updateDevTreeNodeStatus(); + m_pView->viewport()->update(); +} + +void AlarmDevTreeModel::init() +{ + beginResetModel(); + QList locList = AlarmMng::instance()->getLocOrder(); + foreach (const int loc, locList) { + QString locdesc = AlarmMng::instance()->getLocDescById(loc); + QList devgList = AlarmMng::instance()->getDevGroupInfo(loc); + if(devgList.isEmpty()) + { + continue; + } + QTreeWidgetItem * locItem = new QTreeWidgetItem(m_root, QStringList() << locdesc); + locItem->setData(0, Qt::UserRole, loc); + locItem->setData(0, Qt::UserRole+1,LOCATION_TYPE); + locItem->setData(0, Qt::UserRole+2,locdesc); + for(int index(0);indexgetDevgDescByTag(devgList.at(index)); + QTreeWidgetItem * devgItem = new QTreeWidgetItem(locItem, QStringList() << devgdesc); + devgItem->setData(0, Qt::UserRole, devgList.at(index)); + devgItem->setData(0, Qt::UserRole+1,DEV_GROUP_TYPE); + devgItem->setData(0, Qt::UserRole+2,devgdesc); + } + } + endResetModel(); +} + +void AlarmDevTreeModel::updateDevTreeNodeStatus() +{ + if(!m_root) + { + return ; + } + if(m_fltText.empty()) + { + for(int nIndex(0); nIndexsetRowHidden(devgIndex,locModelIndex,false); + isShow = true; + } + else + { + m_pView->setRowHidden(devgIndex,locModelIndex,true); + } + } + m_pView->setRowHidden(locIndex, parent(locModelIndex), !isShow); + } + else + { + setAllChildShow(locModelIndex); + } + } +} + +void AlarmDevTreeModel::setAllChildShow(const QModelIndex &parent) +{ + m_pView->setRowHidden(parent.row(), parent.parent(), false); + int childCount = rowCount(parent); + for(int nIndex(0); nIndex < childCount; nIndex++) + { + m_pView->setRowHidden(nIndex, parent, false); + setAllChildShow(index(nIndex, 0, parent)); + } +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeModel.h b/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeModel.h index bf7e1ff5..7ed62cad 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeModel.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeModel.h @@ -1,73 +1,73 @@ -#ifndef ALARMDEVTREEMODEL_H -#define ALARMDEVTREEMODEL_H - -#include - -class AlarmDevTreeView; -class QTreeWidgetItem; -class QTreeView; - - -enum EN_ALARM_DEV_TREE_NODE -{ - ROOT_TYPE = 0, - LOCATION_TYPE, - DEV_GROUP_TYPE, - DEV_TYPE -}; - -class AlarmDevTreeModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - explicit AlarmDevTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR); - ~AlarmDevTreeModel(); - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - void setFilter(QString text); - -signals: - void itemCheckStateChanged(QStringList tagList,bool checked); - -public slots: - -private: - void init(); - - void setChildCheck(QTreeWidgetItem *item); - - void setParentCheck(QTreeWidgetItem *item); - - void updateDevTreeNodeStatus(); - - void setAllChildShow(const QModelIndex &parent); - -private: - QTreeView *m_pView; - - QStringList m_header; - - QTreeWidgetItem *m_root; - - bool m_isLink; - - std::string m_fltText; - - QMap m_devTypeMap; -}; - -#endif // ALARMDEVTREEMODEL_H +#ifndef ALARMDEVTREEMODEL_H +#define ALARMDEVTREEMODEL_H + +#include + +class AlarmDevTreeView; +class QTreeWidgetItem; +class QTreeView; + + +enum EN_ALARM_DEV_TREE_NODE +{ + ROOT_TYPE = 0, + LOCATION_TYPE, + DEV_GROUP_TYPE, + DEV_TYPE +}; + +class AlarmDevTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit AlarmDevTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR); + ~AlarmDevTreeModel(); + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setFilter(QString text); + +signals: + void itemCheckStateChanged(QStringList tagList,bool checked); + +public slots: + +private: + void init(); + + void setChildCheck(QTreeWidgetItem *item); + + void setParentCheck(QTreeWidgetItem *item); + + void updateDevTreeNodeStatus(); + + void setAllChildShow(const QModelIndex &parent); + +private: + QTreeView *m_pView; + + QStringList m_header; + + QTreeWidgetItem *m_root; + + bool m_isLink; + + std::string m_fltText; + + QMap m_devTypeMap; +}; + +#endif // ALARMDEVTREEMODEL_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeView.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeView.cpp index 96c01315..2c082800 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeView.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeView.cpp @@ -1,7 +1,7 @@ -#include "AlarmDevTreeView.h" - -AlarmDevTreeView::AlarmDevTreeView(QWidget *parent) - :QTreeView(parent) -{ - -} +#include "AlarmDevTreeView.h" + +AlarmDevTreeView::AlarmDevTreeView(QWidget *parent) + :QTreeView(parent) +{ + +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeView.h b/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeView.h index db1d22af..5194ab70 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeView.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmDevTreeView.h @@ -1,13 +1,13 @@ -#ifndef ALARMDEVTREEVIEW_H -#define ALARMDEVTREEVIEW_H - -#include - -class AlarmDevTreeView : public QTreeView -{ - Q_OBJECT -public: - AlarmDevTreeView(QWidget *parent = Q_NULLPTR); -}; - -#endif // ALARMDEVTREEVIEW_H +#ifndef ALARMDEVTREEVIEW_H +#define ALARMDEVTREEVIEW_H + +#include + +class AlarmDevTreeView : public QTreeView +{ + Q_OBJECT +public: + AlarmDevTreeView(QWidget *parent = Q_NULLPTR); +}; + +#endif // ALARMDEVTREEVIEW_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManageCommon.h b/product/src/gui/plugin/AlarmManageWidget/AlarmManageCommon.h index fd3b07e9..3e51774a 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManageCommon.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManageCommon.h @@ -1,75 +1,75 @@ -#ifndef ALARMMANAGECOMMON_H -#define ALARMMANAGECOMMON_H -#include - -enum EN_POINT_TYPE_INDEX -{ - EN_POINT_AI_INDEX =0, - EN_POINT_DI_INDEX =1 -}; - -struct ST_OBJ_INFO -{ - bool bIsObj; - int iPriority; - QString strPushPic; - QString strVoice; - ST_OBJ_INFO() - { - bIsObj = false; - iPriority = 0; - strPushPic =QString(); - strVoice = QString(); - } -}; - -struct ST_LIMIT_INFO -{ - bool bIsLimit; - int iLevel; // 0,1,2 - double dLimitUp1; - double dLimitDown1; - double dLimitUp2; - double dLimitDown2; - ST_LIMIT_INFO() - { - bIsLimit =false; - iLevel =0; - dLimitUp1 = 0.0; - dLimitDown1 = 0.0; - dLimitUp2 = 0.0; - dLimitDown2 = 0.0; - } -}; -struct ST_USER_DEF -{ - int iId; - QString strName; - QString strAlias; - QString strDesc; - ST_USER_DEF() { - - iId = -1; - strName = QString(); - strAlias= QString(); - strDesc = QString(); - } -}; - -struct ST_DEV_INFO -{ - QString strDev; - QString strDevDesc; - int nLocId; - int nSubId; - int nDevType; - ST_DEV_INFO() - { - strDev = QString(); - strDevDesc = QString(); - nLocId = -1; - nSubId = -1; - nDevType = -1; - } -}; -#endif // ALARMMANAGECOMMON_H +#ifndef ALARMMANAGECOMMON_H +#define ALARMMANAGECOMMON_H +#include + +enum EN_POINT_TYPE_INDEX +{ + EN_POINT_AI_INDEX =0, + EN_POINT_DI_INDEX =1 +}; + +struct ST_OBJ_INFO +{ + bool bIsObj; + int iPriority; + QString strPushPic; + QString strVoice; + ST_OBJ_INFO() + { + bIsObj = false; + iPriority = 0; + strPushPic =QString(); + strVoice = QString(); + } +}; + +struct ST_LIMIT_INFO +{ + bool bIsLimit; + int iLevel; // 0,1,2 + double dLimitUp1; + double dLimitDown1; + double dLimitUp2; + double dLimitDown2; + ST_LIMIT_INFO() + { + bIsLimit =false; + iLevel =0; + dLimitUp1 = 0.0; + dLimitDown1 = 0.0; + dLimitUp2 = 0.0; + dLimitDown2 = 0.0; + } +}; +struct ST_USER_DEF +{ + int iId; + QString strName; + QString strAlias; + QString strDesc; + ST_USER_DEF() { + + iId = -1; + strName = QString(); + strAlias= QString(); + strDesc = QString(); + } +}; + +struct ST_DEV_INFO +{ + QString strDev; + QString strDevDesc; + int nLocId; + int nSubId; + int nDevType; + ST_DEV_INFO() + { + strDev = QString(); + strDevDesc = QString(); + nLocId = -1; + nSubId = -1; + nDevType = -1; + } +}; +#endif // ALARMMANAGECOMMON_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.cpp index 17ff14c1..d5d832af 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.cpp @@ -1,84 +1,84 @@ -#include "AlarmManageForm.h" -#include "ui_AlarmManageForm.h" - -#include "AlarmManageWidget.h" -#include -#include "net_msg_bus_api/MsgBusApi.h" -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" - -AlarmManageForm::AlarmManageForm(QWidget *parent,bool edit) : - QWidget(parent), - m_bEdit(edit), - m_alarmWidget(Q_NULLPTR), - ui(new Ui::AlarmManageForm) -{ - ui->setupUi(this); - QString qss = QString(); - - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarmmng.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - else - { - qDebug() << "alarmmng.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - initLayout(); - initMember(); -} - -AlarmManageForm::~AlarmManageForm() -{ - if(m_alarmWidget) - { - delete m_alarmWidget; - m_alarmWidget = NULL; - } - delete ui; -} - -void AlarmManageForm::initLayout() -{ - -} - -void AlarmManageForm::initMember() -{ - if(m_alarmWidget == NULL) - { - m_alarmWidget = new AlarmManageWidget(this,m_bEdit); - addWidget(); - } -} - -void AlarmManageForm::addWidget() -{ - QGridLayout *gridLayout = new QGridLayout(ui->widget); - gridLayout->setSpacing(6); - gridLayout->setContentsMargins(0, 0, 0, 0); - gridLayout->addWidget(m_alarmWidget, 0, 0, 1, 1); -} +#include "AlarmManageForm.h" +#include "ui_AlarmManageForm.h" + +#include "AlarmManageWidget.h" +#include +#include "net_msg_bus_api/MsgBusApi.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" + +AlarmManageForm::AlarmManageForm(QWidget *parent,bool edit) : + QWidget(parent), + m_bEdit(edit), + m_alarmWidget(Q_NULLPTR), + ui(new Ui::AlarmManageForm) +{ + ui->setupUi(this); + QString qss = QString(); + + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarmmng.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + else + { + qDebug() << "alarmmng.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + initLayout(); + initMember(); +} + +AlarmManageForm::~AlarmManageForm() +{ + if(m_alarmWidget) + { + delete m_alarmWidget; + m_alarmWidget = NULL; + } + delete ui; +} + +void AlarmManageForm::initLayout() +{ + +} + +void AlarmManageForm::initMember() +{ + if(m_alarmWidget == NULL) + { + m_alarmWidget = new AlarmManageWidget(this,m_bEdit); + addWidget(); + } +} + +void AlarmManageForm::addWidget() +{ + QGridLayout *gridLayout = new QGridLayout(ui->widget); + gridLayout->setSpacing(6); + gridLayout->setContentsMargins(0, 0, 0, 0); + gridLayout->addWidget(m_alarmWidget, 0, 0, 1, 1); +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.h b/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.h index 38bc2ff3..732865c0 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.h @@ -1,32 +1,32 @@ -#ifndef ALARMMANAGEFORM_H -#define ALARMMANAGEFORM_H - -#include - -namespace Ui { -class AlarmManageForm; -} - -class AlarmManageForm : public QWidget -{ - Q_OBJECT - -public: - explicit AlarmManageForm(QWidget *parent = 0, bool edit = false); - ~AlarmManageForm(); - - void initLayout(); - - void initMember(); - -private: - void addWidget(); -private: - Ui::AlarmManageForm *ui; - - QWidget *m_alarmWidget; - - bool m_bEdit; -}; - -#endif // ALARMMANAGEFORM_H +#ifndef ALARMMANAGEFORM_H +#define ALARMMANAGEFORM_H + +#include + +namespace Ui { +class AlarmManageForm; +} + +class AlarmManageForm : public QWidget +{ + Q_OBJECT + +public: + explicit AlarmManageForm(QWidget *parent = 0, bool edit = false); + ~AlarmManageForm(); + + void initLayout(); + + void initMember(); + +private: + void addWidget(); +private: + Ui::AlarmManageForm *ui; + + QWidget *m_alarmWidget; + + bool m_bEdit; +}; + +#endif // ALARMMANAGEFORM_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.ui b/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.ui index e093bfb5..58a85fbe 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.ui +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManageForm.ui @@ -1,36 +1,36 @@ - - - AlarmManageForm - - - - 0 - 0 - 1157 - 610 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - + + + AlarmManageForm + + + + 0 + 0 + 1157 + 610 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.cpp index 0dff7624..2cd3cd80 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.cpp @@ -1,25 +1,25 @@ -#include "AlarmManagePluginWidget.h" -#include "AlarmManageForm.h" -AlarmManagePluginWidget::AlarmManagePluginWidget(QObject *parent): QObject(parent) -{ - -} - -AlarmManagePluginWidget::~AlarmManagePluginWidget() -{ - -} - -bool AlarmManagePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - AlarmManageForm *pWidget = new AlarmManageForm(parent, editMode); - *widget = (QWidget *)pWidget; - *alarmWidget = (IPluginWidget *)pWidget; - return true; -} - -void AlarmManagePluginWidget::release() -{ - -} +#include "AlarmManagePluginWidget.h" +#include "AlarmManageForm.h" +AlarmManagePluginWidget::AlarmManagePluginWidget(QObject *parent): QObject(parent) +{ + +} + +AlarmManagePluginWidget::~AlarmManagePluginWidget() +{ + +} + +bool AlarmManagePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + AlarmManageForm *pWidget = new AlarmManageForm(parent, editMode); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + return true; +} + +void AlarmManagePluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.h b/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.h index a1a4582a..70c0e510 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.h @@ -1,22 +1,22 @@ -#ifndef ALARMMANAGEPLUGINWIDGET_H -#define ALARMMANAGEPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - - -class AlarmManagePluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - AlarmManagePluginWidget(QObject *parent = 0); - ~AlarmManagePluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); - void release(); -}; - -#endif // ALARMMANAGEPLUGINWIDGET_H +#ifndef ALARMMANAGEPLUGINWIDGET_H +#define ALARMMANAGEPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + + +class AlarmManagePluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + AlarmManagePluginWidget(QObject *parent = 0); + ~AlarmManagePluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif // ALARMMANAGEPLUGINWIDGET_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.cpp index 052a163c..b7312e86 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.cpp @@ -1,1193 +1,1193 @@ -#include "AlarmManageWidget.h" -#include "ui_AlarmManageWidget.h" -#include "pub_logger_api/logger.h" -#include "perm_mng_api/PermMngApi.h" -#include "boost/asio/ip/host_name.hpp" - -#include -#include -#include "net_msg_bus_api/MsgBusApi.h" -#include "AlarmDevTreeView.h" -#include "AlarmDevTreeModel.h" -#include "AlarmMng.h" -#include "AlarmPointTableModel.h" -#include "AlarmManageCommon.h" -#include "AddObjAlarmDialog.h" -#include "pub_utility_api/I18N.h" -#include "pub_utility_api/FileUtil.h" - -AlarmManageWidget::AlarmManageWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::AlarmManageWidget), - m_pDevTreeModel(Q_NULLPTR), - m_pAiPointTableModel(Q_NULLPTR), - m_pDiPointTableModel(Q_NULLPTR), - m_pThread(Q_NULLPTR), - m_pReadDb(Q_NULLPTR), - m_pWriteDb(Q_NULLPTR), - m_bIsEditMode(editMode), - m_devgName(QString()), - m_buttonGroup(Q_NULLPTR), - m_curStackIndex(0) -{ - ui->setupUi(this); - m_strMediaPath = ""; - qRegisterMetaType("PointInfo"); - qRegisterMetaType("QStringList"); - qRegisterMetaType >("ListPointInfoPtr"); - - qRegisterMetaType >("ListAlarmCalcInfoPtr"); - - initLayout(); - if(!m_bIsEditMode) - { - m_buttonGroup = new QButtonGroup; - m_buttonGroup->setExclusive(true); - m_buttonGroup->addButton(ui->aibt,0); - m_buttonGroup->addButton(ui->dibt,1); - initMember(); - initData(); - initCurUser(); - initConnect(); - initView(); - m_pThread->start(); - } - QDir dir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - dir.cd("sound"); - - m_strMediaPath = dir.absolutePath(); -} - -AlarmManageWidget::~AlarmManageWidget() -{ - AlarmMng::instance()->destory(); - delete ui; -} - -void AlarmManageWidget::initLayout() -{ - ui->hsplitter->setSizes(QList()<<200<<900<<300); - - ui->cbAlarmPriority->setView(new QListView()); - ui->cbIfLimit->setView(new QListView()); - ui->cbIfObj->setView(new QListView()); - ui->cbLevel->setView(new QListView()); -} - -void AlarmManageWidget::initMember() -{ - initModel(); - if(m_pThread == NULL) - { - m_pThread = new QThread(); - } - - AlarmMng::instance()->moveToThread(m_pThread); - m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - if(!m_pWriteDb->open()) - { - LOGERROR("打开数据库失败,error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); - } - if(!m_pReadDb->open()) - { - LOGERROR("打开数据库失败,error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); - } - - m_hostName = QString::fromStdString(boost::asio::ip::host_name()); - ui->widget_3->setMinimumWidth(300); - -} - -void AlarmManageWidget::initModel() -{ - if(m_pDevTreeModel == NULL) - { - m_pDevTreeModel = new AlarmDevTreeModel(this,ui->devTreeView); - } - //ui->devTreeView->header()->setHidden(true); - ui->devTreeView->setModel(m_pDevTreeModel); - ui->devTreeView->expandAll(); - - if(m_pAiPointTableModel == NULL) - { - m_pAiPointTableModel = new AlarmPointTableModel(this,ui->aitableView); - } - ui->aitableView->setModel(m_pAiPointTableModel); - ui->aitableView->setColumnWidth(0,200); - ui->aitableView->setColumnWidth(1,140); - ui->aitableView->setColumnWidth(2,180); - ui->aitableView->setColumnWidth(3,140); - ui->aitableView->setColumnWidth(4,60); - - if(m_pDiPointTableModel == NULL) - { - m_pDiPointTableModel = new AlarmPointTableModel(this,ui->ditableView); - } - ui->ditableView->setModel(m_pDiPointTableModel); - ui->ditableView->setColumnWidth(0,200); - ui->ditableView->setColumnWidth(1,140); - ui->ditableView->setColumnWidth(2,180); - ui->ditableView->setColumnWidth(3,140); - ui->ditableView->setColumnWidth(4,60); -} - -void AlarmManageWidget::initData() -{ - ui->cbIfObj->clear(); - ui->cbIfObj->addItem(tr("是"),1); - ui->cbIfObj->addItem(tr("否"),0); - ui->cbIfObj->setCurrentIndex(1); - - ui->cbAlarmPriority->clear(); - m_alarmLevelMap = AlarmMng::instance()->getAlarmLevel(); - int index = 0; - QMap::iterator it_level = m_alarmLevelMap.begin(); - while (it_level != m_alarmLevelMap.end()) { - ui->cbAlarmPriority->addItem(it_level.value(),it_level.key()); - m_alarmLevelIndexMap[it_level.key()] = index++; - it_level++; - } - - m_alarmLevelActionMap = AlarmMng::instance()->getAlarmLevelAction(); - m_alarmActionMap = AlarmMng::instance()->getAlarmAction(); - QHBoxLayout *hLayout = new QHBoxLayout; - QVBoxLayout *vLayout0 = new QVBoxLayout; - QVBoxLayout *vLayout1 = new QVBoxLayout; - - index = 0; - QMap::iterator it = m_alarmActionMap.begin(); - while (it != m_alarmActionMap.end()) { - - QCheckBox *box = new QCheckBox(it.value(),ui->widget_4); - m_alarmActionCheckMap[it.key()] = box; - if(index % 2 == 0) - { - vLayout0->addWidget(box); - }else if(index % 2 == 1) - { - vLayout1->addWidget(box); - } - index++; - it++; - } - vLayout0->addStretch(100); - vLayout1->addStretch(100); - //vLayout2->addStretch(100); - - hLayout->addLayout(vLayout0); - - hLayout->addLayout(vLayout1); - //hLayout->addLayout(vLayout2); - ui->widget_4->setLayout(hLayout); - ui->widget_4->setEnabled(false); - alarmActionCheckChange(0); - - ui->cbIfLimit->clear(); - ui->cbIfLimit->addItem(tr("是"),1); - ui->cbIfLimit->addItem(tr("否"),0); - - ui->cbLevel->clear(); - ui->cbLevel->addItem(tr("0"),0); - ui->cbLevel->addItem(tr("1"),1); - ui->cbLevel->addItem(tr("2"),2); - - setEnableProperty(false); -} - -bool AlarmManageWidget::initCurUser() -{ - m_userId = -1; - m_usergId = -1; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - - int userId; - int usergId; - int level; - int loginSec; - std::string name; - - std::string userName; - std::string usergName; - - if(permMngPtr->CurUser(userName,usergName,level,loginSec,name) == 0) - { - //qDebug()<CurUser(userId, usergId,level,loginSec,name) == 0) - { - m_userId = userId; - m_usergId = usergId; - }else - { - LOGERROR("获取当前登录用户失败!"); - return false; - } - return true; -} - -void AlarmManageWidget::initConnect() -{ - connect(ui->lineEdit, &QLineEdit::returnPressed, this, &AlarmManageWidget::filter); //过滤 - connect(ui->search,&QPushButton::clicked,this,&AlarmManageWidget::filter); //过滤 - connect(AlarmMng::instance(),&AlarmMng::addAiPoint,m_pAiPointTableModel,&AlarmPointTableModel::addPoint,Qt::QueuedConnection); - connect(AlarmMng::instance(),&AlarmMng::addDiPoint,m_pDiPointTableModel,&AlarmPointTableModel::addPoint,Qt::QueuedConnection); - connect(ui->cbAlarmPriority,SIGNAL(currentIndexChanged(int)),this,SLOT(alarmActionCheckChange(int))); - connect(ui->cbIfLimit,&QComboBox::currentTextChanged,this,&AlarmManageWidget::ifLimitChange); - connect(ui->cbIfObj,&QComboBox::currentTextChanged,this,&AlarmManageWidget::ifObjChange); - - connect(ui->push,&QPushButton::clicked,this,&AlarmManageWidget::getPushPicPath); - connect(ui->voice,&QPushButton::clicked,this,&AlarmManageWidget::getVoicePath); -// connect(ui->aitableView,&AlarmPointTableView::clicked,this,&AlarmManageWidget::showAiAlarmProperty); -// connect(ui->ditableView,&AlarmPointTableView::clicked,this,&AlarmManageWidget::showDiAlarmProperty); - - connect(ui->devTreeView,&AlarmDevTreeView::clicked,this,&AlarmManageWidget::checkClick,Qt::QueuedConnection); - connect(this,&AlarmManageWidget::sigSelectPoint,AlarmMng::instance(),&AlarmMng::slotSelectPoint,Qt::QueuedConnection); - connect(this,&AlarmManageWidget::sigClearPointTable,m_pAiPointTableModel,&AlarmPointTableModel::slotClearPointTable,Qt::QueuedConnection); - connect(this,&AlarmManageWidget::sigClearPointTable,m_pDiPointTableModel,&AlarmPointTableModel::slotClearPointTable,Qt::QueuedConnection); - - connect(ui->cbLevel,&QComboBox::currentTextChanged,this,&AlarmManageWidget::ifLimitLevelChange); - - connect(ui->pushButton_5,&QPushButton::clicked,this,&AlarmManageWidget::save); - - connect(ui->pushButton_2,&QPushButton::clicked,this,&AlarmManageWidget::addObjAlarm); - connect(m_buttonGroup,SIGNAL(buttonClicked(int)),this,SLOT(updateStack(int))); - connect(ui->pointFilter,&QPushButton::clicked,this,&AlarmManageWidget::filterPoint); - connect(ui->checkBox,&QCheckBox::stateChanged,this,&AlarmManageWidget::sigOrMul); - - connect(ui->aitableView,&AlarmPointTableView::sigBrushProperty,this,&AlarmManageWidget::showAiProperty); - connect(ui->ditableView,&AlarmPointTableView::sigBrushProperty,this,&AlarmManageWidget::showDiProperty); -} - -void AlarmManageWidget::setEnableProperty(bool enable) -{ - ui->widget_3->setEnabled(enable); -} - -void AlarmManageWidget::setEnableDesc(bool enable) -{ - ui->groupBox_4->setEnabled(enable); -} - -void AlarmManageWidget::setEnableObjAlarm(bool enable) -{ - ui->groupBox_2->setEnabled(enable); - ui->groupBox_2->setHidden(!enable); -} - -void AlarmManageWidget::setEnableLimitAlarm(bool enable) -{ - ui->groupBox_3->setEnabled(enable); - ui->groupBox_3->setHidden(!enable); -} - -void AlarmManageWidget::saveAi() -{ - QModelIndexList aiList = ui->aitableView->selectionModel()->selectedRows(0); - if(aiList.size() < 1) - { - return ; - } - if(aiList.size() == 1) - { - QString desc = ui->lineEdit_3->text(); - - if(desc.isEmpty()) - { - QMessageBox::warning(0,tr("提示"),tr("点描述不能为空!")); - return ; - } - } - if(!checkAiIfSave()) - { - return ; - } - - //1越限首先要修改点表,然后去修改越限表 - QString desc = ui->lineEdit_3->text(); - m_pWriteDb->transaction(); - //先修改描述(描述应不支持批量修改) - QList pointList; - foreach (QModelIndex index, aiList) { - - pointList.append(m_pAiPointTableModel->getPointInfoByRow(index.row())); - } - if(pointList.size() == 1) - { - QString sqlUpTag =QString("update %1 set description ='%2' where tag_name ='%3'").arg("analog").arg(desc).arg(pointList.at(0)->m_tag); - m_pWriteDb->execute(sqlUpTag); - }else - { - desc = QString(); - } - QString condition=QString(); - for(int conIndex = 0;conIndex m_tag); - } - if(!condition.isEmpty()) - { - condition.resize(condition.size() - 2); - condition = QString("%1 in (%2)").arg("tag_name").arg(condition); - } - - double limitup1 = ui->doubleSpinBox->value(); - double limitup2 = ui->doubleSpinBox_3->value(); - double limitlow1 = ui->doubleSpinBox_2->value(); - double limitlow2 = ui->doubleSpinBox_4->value(); - - int obj = ui->cbIfObj->currentData().toInt(); - - int priority = ui->cbAlarmPriority->currentData().toInt(); - - QString push = ui->pushText->text(); - QString voice = ui->voiceText->text(); - - int isLimit = ui->cbIfLimit->currentData().toInt(); - QString sqlupdate; - - sqlupdate = QString("update %1 set is_limit = %2,sound_name1 ='%3' where %4 ").arg("analog").arg(isLimit).arg(voice).arg(condition); - m_pWriteDb->execute(sqlupdate); - QString sqldelete; - sqldelete = QString("delete from %1 where %4").arg("analog_limit_info").arg(condition); - m_pWriteDb->execute(sqldelete); - - int limitLevel = ui->cbLevel->currentData().toInt(); - if(isLimit == 1) - { - QString sqlinsert; - sqlinsert = QString("insert into %1 (tag_name,location_id,sub_system,limit_type,limit_num,limit_up1,limit_low1,limit_up2,limit_low2,cross_percent,return_percent,is_obj_alm_manner,alarm_priority,pic_name,is_water_alm) values ").arg("analog_limit_info"); - for(int idx = 0; idx m_tag).arg(pointList.at(idx)->m_loc).arg(pointList.at(idx)->m_sub).arg(1).arg(limitLevel). - arg(limitup1).arg(limitlow1).arg(limitup2).arg(limitlow2).arg(5).arg(5).arg(obj).arg(priority).arg(push); - } - sqlinsert.resize(sqlinsert.size() - 2); - m_pWriteDb->execute(sqlinsert); - } - if(!m_pWriteDb->commit()) - { - QMessageBox::warning(0,tr("提示"),tr("保存失败!正在回滚事务~")); - LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); - m_pWriteDb->rollback(); - }else - { - for(int index = 0;index m_desc =desc.isEmpty() ? pointList.at(index)->m_desc : desc; - pointList.at(index)->m_obj = isLimit == 1 ? obj: 0; - pointList.at(index)->m_priority = isLimit == 1 ? priority: -1; - } - QMessageBox::information(0,tr("提示"),tr("保存成功!")); - } -} - -void AlarmManageWidget::saveDi() -{ - QModelIndexList diList = ui->ditableView->selectionModel()->selectedRows(0); - if(diList.size() < 1) - { - return ; - } - if(diList.size() == 1) - { - QString desc = ui->lineEdit_3->text(); - - if(desc.isEmpty()) - { - QMessageBox::warning(0,tr("提示"),tr("点描述不能为空!")); - return ; - } - } - - QString desc = ui->lineEdit_3->text(); - m_pWriteDb->transaction(); - //先修改描述(描述应不支持批量修改) - QList pointList; - foreach (QModelIndex index, diList) { - - pointList.append(m_pDiPointTableModel->getPointInfoByRow(index.row())); - } - if(pointList.size() == 1) - { - QString sqlUpTag =QString("update %1 set description ='%2' where tag_name ='%3'").arg("digital").arg(desc).arg(pointList.at(0)->m_tag); - m_pWriteDb->execute(sqlUpTag); - }else - { - desc = QString(); - } - - QString condition=QString(); - for(int conIndex = 0;conIndex m_tag); - } - if(!condition.isEmpty()) - { - condition.resize(condition.size() - 2); - condition = QString("%1 in (%2)").arg("tag_name").arg(condition); - } - - int obj = ui->cbIfObj->currentData().toInt(); - int priority = ui->cbAlarmPriority->currentData().toInt(); - QString push = ui->pushText->text(); - QString voice = ui->voiceText->text(); - - QString sql = QString("update %1 set is_obj_alm_manner = %2,alarm_priority = %3,pic_name ='%4' ,sound_name1= '%5' where" - " %6 ").arg("digital").arg(obj).arg(priority).arg(push).arg(voice).arg(condition); - - m_pWriteDb->execute(sql); - - if(!m_pWriteDb->commit()) - { - QMessageBox::warning(0,tr("提示"),tr("保存失败!正在回滚事务~")); - LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); - m_pWriteDb->rollback(); - }else - { - for(int index = 0;index m_desc =desc.isEmpty() ? pointList.at(index)->m_desc : desc; - pointList.at(index)->m_obj = obj; - pointList.at(index)->m_priority = priority; - } - QMessageBox::information(0,tr("提示"),tr("保存成功!")); - } -} - -void AlarmManageWidget::showShieldProperty() -{ - ui->widget_6->setEnabled(true); -} - -void AlarmManageWidget::initView() -{ - //禁用属性框 - setEnableProperty(false); - //清空点表格 - emit sigClearPointTable(); - - //初始化属性窗 - initProperty(); - - initHide(); -} - -void AlarmManageWidget::initProperty() -{ - ui->lineEdit_3->setText(""); //点标签初始化为空 - - ui->cbIfObj->setCurrentIndex(0); - ui->cbAlarmPriority->setCurrentIndex(0); - ui->pushText->setText(""); - ui->voiceText->setText(""); - - ui->cbIfLimit->setCurrentIndex(1); - ui->cbLevel->setCurrentIndex(0); - ui->doubleSpinBox->setValue(0.0); - ui->doubleSpinBox_2->setValue(0.0); - ui->doubleSpinBox_3->setValue(0.0); - ui->doubleSpinBox_4->setValue(0.0); -} - -void AlarmManageWidget::initHide() -{ - ifLimitChange(""); - ifObjChange(""); - ifLimitLevelChange(""); -} - -void AlarmManageWidget::reLoadData(const QString &filter) -{ - if(!m_devgName.isEmpty()) - { - emit sigSelectPoint(m_devgName,m_curStackIndex,filter); - } -} - -void AlarmManageWidget::deleteAi() -{ - QModelIndexList aiList = ui->aitableView->selectionModel()->selectedRows(0); - if(aiList.size() < 1) - { - return ; - } - if(QMessageBox::No == QMessageBox::question(0, tr("提示"), tr("确认删除?"))) - { - return; - } - - //1删除越限表中信息 2删除测点表中信息 3删除计算量输出表中信息 - - m_pWriteDb->transaction(); - QList pointList; - foreach (QModelIndex index, aiList) { - - pointList.append(m_pAiPointTableModel->getPointInfoByRow(index.row())); - } - QString condition=QString(); - QString calCondition=QString(); - for(int conIndex = 0;conIndex m_tag); - calCondition+= QString("'analog.%1.value', ").arg(pointList.at(conIndex)->m_tag); - } - if(!condition.isEmpty()) - { - condition.resize(condition.size() - 2); - condition = QString("%1 in (%2)").arg("tag_name").arg(condition); - } - if(!calCondition.isEmpty()) - { - calCondition.resize(calCondition.size() - 2); - calCondition = QString("%1 in (%2)").arg("key_id_tag").arg(calCondition); - } - QString sqldel; - sqldel = QString("delete from %1 where %2").arg("analog").arg(condition); - m_pWriteDb->execute(sqldel); - sqldel = QString("delete from %1 where %4").arg("analog_limit_info").arg(condition); - m_pWriteDb->execute(sqldel); - sqldel = QString("delete from %1 where %2").arg("calc_out_para").arg(calCondition); - m_pWriteDb->execute(sqldel); - if(!m_pWriteDb->commit()) - { - QMessageBox::warning(0,tr("提示"),tr("删除失败!正在回滚事务~")); - LOGERROR("删除失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); - m_pWriteDb->rollback(); - }else - { - initView(); - reLoadData(); - } -} - -void AlarmManageWidget::deleteDi() -{ - QModelIndexList diList = ui->ditableView->selectionModel()->selectedRows(0); - if(diList.size() < 1) - { - return ; - } - if(QMessageBox::No == QMessageBox::question(0, tr("提示"), tr("确认删除?"))) - { - return; - } - - m_pWriteDb->transaction(); - QList pointList; - foreach (QModelIndex index, diList) { - - pointList.append(m_pDiPointTableModel->getPointInfoByRow(index.row())); - } - QString condition=QString(); - QString calCondition=QString(); - for(int conIndex = 0;conIndex m_tag); - calCondition+= QString("'digital.%1.value', ").arg(pointList.at(conIndex)->m_tag); - } - if(!condition.isEmpty()) - { - condition.resize(condition.size() - 2); - condition = QString("%1 in (%2)").arg("tag_name").arg(condition); - } - if(!calCondition.isEmpty()) - { - calCondition.resize(calCondition.size() - 2); - calCondition = QString("%1 in (%2)").arg("key_id_tag").arg(calCondition); - } - QString sqldel; - sqldel = QString("delete from %1 where %2").arg("digital").arg(condition); - m_pWriteDb->execute(sqldel); - sqldel = QString("delete from %1 where %2").arg("calc_out_para").arg(calCondition); - m_pWriteDb->execute(sqldel); - if(!m_pWriteDb->commit()) - { - QMessageBox::warning(0,tr("提示"),tr("删除失败!正在回滚事务~")); - LOGERROR("删除失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); - m_pWriteDb->rollback(); - }else - { - initView(); - reLoadData(); - } -} - -void AlarmManageWidget::filter() -{ - QString searchText = ui->lineEdit->text(); - m_pDevTreeModel->setFilter(searchText); -} - -void AlarmManageWidget::alarmActionCheckChange(int index) -{ - Q_UNUSED(index); - int priority = ui->cbAlarmPriority->currentData().toInt(); - int act = m_alarmLevelActionMap.value(priority,0); - QMap::iterator it = m_alarmActionCheckMap.begin(); - while (it != m_alarmActionCheckMap.end()) { - it.value()->setChecked(false); - if(act>>(it.key()-1) & 0x0001) - { - it.value()->setChecked(true); - } - it++; - } -} - -void AlarmManageWidget::ifLimitChange(const QString &) -{ - int index = ui->cbIfLimit->currentData().toInt(); - - if(index == 1) - { - ui->widget_7->setEnabled(true); - ui->widget_7->setHidden(false); - ui->widget_10->setHidden(false); - setEnableObjAlarm(true); - - }else if(index == 0) - { - ui->widget_7->setEnabled(false); - ui->widget_10->setHidden(true); - setEnableObjAlarm(false); - } -} - -void AlarmManageWidget::ifObjChange(const QString &) -{ - int index = ui->cbIfObj->currentData().toInt(); - - if(index == 1) - { - ui->cbAlarmPriority->setEnabled(true); - }else if(index == 0) - { - ui->cbAlarmPriority->setEnabled(false); - } -} - -void AlarmManageWidget::getPushPicPath() -{ - QString fileName = QFileDialog::getOpenFileName(this, - tr("Open Pic"), "../../data/pic", tr("Pic Files (*.glx)")); - if(!fileName.isEmpty()) - { - QStringList list = fileName.split("pic/"); - ui->pushText->setText(list.at(list.size()-1)); - } -} - -void AlarmManageWidget::getVoicePath() -{ - QString fileName = QFileDialog::getOpenFileName(this, - tr("Open Voice"), m_strMediaPath, tr("Pic Files (*.wav)")); - if(!fileName.isEmpty()) - { - QStringList list = fileName.split("/"); - ui->voiceText->setText(list.at(list.size()-1)); - } -} - -void AlarmManageWidget::showAiAlarmProperty(const QModelIndex &cur) -{ - initProperty(); - initHide(); - - setEnableProperty(true); - setEnableDesc(true); - setEnableObjAlarm(true); - setEnableLimitAlarm(true); - ui->widget_10->setHidden(false); - QModelIndexList indexList = ui->aitableView->selectionModel()->selectedRows(0); - QList rowList; - QString strText; - for(QModelIndex index :indexList) - { - rowList.append(index.row()); - strText = QString("%1 %2").arg(strText).arg(index.row()); - } - int size = rowList.size(); - - if(size < 1) - { - setEnableProperty(false); - setEnableLimitAlarm(true); - setEnableObjAlarm(false); - ui->widget_10->setHidden(true); - return ; - } - PointInfoPtr info; - if(rowList.contains(cur.row())) - { - info = m_pAiPointTableModel->getPointInfoByRow(cur.row()); - }else - { - info = m_pAiPointTableModel->getPointInfoByRow(rowList.last()); - } - ui->lineEdit_3->setText(info->m_desc); - - ST_LIMIT_INFO limitInfo; - ST_OBJ_INFO objInfo; - bool isLimit = AlarmMng::instance()->isAiObjAlarm(info,objInfo,limitInfo); - if(isLimit) - { - setEnableObjAlarm(true); - - ui->cbIfLimit->setCurrentIndex(0); - ui->cbLevel->setCurrentIndex(limitInfo.iLevel); - ui->doubleSpinBox->setValue(limitInfo.dLimitUp1); - ui->doubleSpinBox_2->setValue(limitInfo.dLimitDown1); - ui->doubleSpinBox_3->setValue(limitInfo.dLimitUp2); - ui->doubleSpinBox_4->setValue(limitInfo.dLimitDown2); - - ui->voiceText->setText(objInfo.strVoice); - ui->pushText->setText(objInfo.strPushPic); - - ui->cbIfObj->setCurrentIndex(objInfo.bIsObj ? 0:1); - ui->cbAlarmPriority->setCurrentIndex(m_alarmLevelIndexMap.value(objInfo.iPriority)); - }else - { - ui->cbIfLimit->setCurrentIndex(1); - ui->widget_10->setHidden(true); - ui->doubleSpinBox->setValue(0.0); - ui->doubleSpinBox_2->setValue(0.0); - ui->doubleSpinBox_3->setValue(0.0); - ui->doubleSpinBox_4->setValue(0.0); - } - ifLimitChange(""); - ifObjChange(""); - - if(size > 1) - { - ui->lineEdit_3->setText(""); //点标签初始化为空 - setEnableDesc(false); - } -} - -void AlarmManageWidget::showDiAlarmProperty(const QModelIndex &index) -{ - initProperty(); - initHide(); - - setEnableProperty(true); - setEnableDesc(true); - setEnableObjAlarm(true); - setEnableLimitAlarm(false); - - ui->widget_10->setHidden(false); - QModelIndexList indexList = ui->ditableView->selectionModel()->selectedRows(0); - QList rowList; - for(QModelIndex index :indexList) - { - rowList.append(index.row()); - } - int size = rowList.size(); - if(size < 1) - { - setEnableProperty(false); - return ; - } - - PointInfoPtr info; - if(indexList.contains(index)) - { - info = m_pDiPointTableModel->getPointInfoByRow(index.row()); - }else - { - info = m_pDiPointTableModel->getPointInfoByRow(rowList.last()); - } - - ui->lineEdit_3->setText(info->m_desc); - ST_OBJ_INFO objInfo; - bool isObj = AlarmMng::instance()->isDiObjAlarm(info,objInfo); - ui->pushText->setText(objInfo.strPushPic); - ui->voiceText->setText(objInfo.strVoice); - - ui->cbIfObj->setCurrentIndex(isObj ? 0:1); - ui->cbAlarmPriority->setCurrentIndex(m_alarmLevelIndexMap.value(objInfo.iPriority)); - ifObjChange(""); - - if(size > 1) - { - ui->lineEdit_3->setText(""); //点标签初始化为空 - setEnableDesc(false); - } -} - -void AlarmManageWidget::showAiProperty() -{ - initProperty(); - initHide(); - - setEnableProperty(true); - setEnableDesc(true); - setEnableObjAlarm(true); - setEnableLimitAlarm(true); - ui->widget->setHidden(false); - QModelIndexList indexList = ui->aitableView->selectionModel()->selectedRows(0); - QList rowList; - for(QModelIndex index :indexList) - { - rowList.append(index.row()); - } - int size = rowList.size(); - - if(size < 1) - { - setEnableProperty(false); - setEnableLimitAlarm(true); - setEnableObjAlarm(false); - ui->widget_10->setHidden(true); - return ; - } - PointInfoPtr info = m_pAiPointTableModel->getPointInfoByRow(rowList.last()); - - ui->lineEdit_3->setText(info->m_desc); - - ST_LIMIT_INFO limitInfo; - ST_OBJ_INFO objInfo; - bool isLimit = AlarmMng::instance()->isAiObjAlarm(info,objInfo,limitInfo); - if(isLimit) - { - setEnableObjAlarm(true); - - ui->cbIfLimit->setCurrentIndex(0); - ui->cbLevel->setCurrentIndex(limitInfo.iLevel); - ui->doubleSpinBox->setValue(limitInfo.dLimitUp1); - ui->doubleSpinBox_2->setValue(limitInfo.dLimitDown1); - ui->doubleSpinBox_3->setValue(limitInfo.dLimitUp2); - ui->doubleSpinBox_4->setValue(limitInfo.dLimitDown2); - - ui->voiceText->setText(objInfo.strVoice); - ui->pushText->setText(objInfo.strPushPic); - - ui->cbIfObj->setCurrentIndex(objInfo.bIsObj ? 0:1); - ui->cbAlarmPriority->setCurrentIndex(m_alarmLevelIndexMap.value(objInfo.iPriority)); - }else - { - ui->cbIfLimit->setCurrentIndex(1); - ui->widget_10->setHidden(true); - ui->doubleSpinBox->setValue(0.0); - ui->doubleSpinBox_2->setValue(0.0); - ui->doubleSpinBox_3->setValue(0.0); - ui->doubleSpinBox_4->setValue(0.0); - } - ifLimitChange(""); - ifObjChange(""); - - if(size > 1) - { - ui->lineEdit_3->setText(""); //点标签初始化为空 - setEnableDesc(false); - } -} - -void AlarmManageWidget::showDiProperty() -{ - initProperty(); - initHide(); - - setEnableProperty(true); - setEnableDesc(true); - setEnableObjAlarm(true); - setEnableLimitAlarm(false); - - ui->widget_10->setHidden(false); - QModelIndexList indexList = ui->ditableView->selectionModel()->selectedRows(0); - QList rowList; - for(QModelIndex index :indexList) - { - rowList.append(index.row()); - } - int size = rowList.size(); - if(size < 1) - { - setEnableProperty(false); - return ; - } - - PointInfoPtr info = m_pDiPointTableModel->getPointInfoByRow(rowList.last()); - - ui->lineEdit_3->setText(info->m_desc); - ST_OBJ_INFO objInfo; - bool isObj = AlarmMng::instance()->isDiObjAlarm(info,objInfo); - ui->pushText->setText(objInfo.strPushPic); - ui->voiceText->setText(objInfo.strVoice); - - ui->cbIfObj->setCurrentIndex(isObj ? 0:1); - ui->cbAlarmPriority->setCurrentIndex(m_alarmLevelIndexMap.value(objInfo.iPriority)); - ifObjChange(""); - - if(size > 1) - { - ui->lineEdit_3->setText(""); //点标签初始化为空 - setEnableDesc(false); - } -} - -void AlarmManageWidget::checkClick(const QModelIndex &index) -{ - int type =index.data(Qt::UserRole+1).toInt(); - initView(); - m_devgName = QString(); - if(type != DEV_GROUP_TYPE) - { - return; - } - m_devgName = index.data(Qt::UserRole).toString(); - reLoadData(); - if(m_curStackIndex == EN_POINT_AI_INDEX) - { - setEnableObjAlarm(false); - setEnableLimitAlarm(true); - ui->widget_10->setHidden(true); - }else - { - setEnableLimitAlarm(false); - setEnableObjAlarm(true); - ui->widget_10->setHidden(false); - } -} - -void AlarmManageWidget::ifLimitLevelChange(const QString &) -{ - int index = ui->cbLevel->currentData().toInt(); - - if(index == 1) - { - ui->doubleSpinBox->setEnabled(true); - ui->doubleSpinBox_2->setEnabled(true); - ui->doubleSpinBox_3->setEnabled(false); - ui->doubleSpinBox_4->setEnabled(false); - }else if(index == 2) - { - ui->doubleSpinBox->setEnabled(true); - ui->doubleSpinBox_2->setEnabled(true); - ui->doubleSpinBox_3->setEnabled(true); - ui->doubleSpinBox_4->setEnabled(true); - }else if(index == 0) - { - ui->doubleSpinBox->setEnabled(false); - ui->doubleSpinBox_2->setEnabled(false); - ui->doubleSpinBox_3->setEnabled(false); - ui->doubleSpinBox_4->setEnabled(false); - } -} - -void AlarmManageWidget::save() -{ - if(!AlarmMng::instance()->getNomRptEditPerm()) - { - QMessageBox::warning(this,tr("提示"),tr("当前登录用户无修改权限!")); - return; - } - if(m_curStackIndex == EN_POINT_AI_INDEX) - { - saveAi(); - }else if(m_curStackIndex == EN_POINT_DI_INDEX) - { - saveDi(); - } -} - -bool AlarmManageWidget::checkAiIfSave() -{ - int isLimit = ui->cbIfLimit->currentData().toInt(); - if(isLimit == 1) - { - int level = ui->cbLevel->currentData().toInt(); - double limitup1 = ui->doubleSpinBox->value(); - double limitup2 = ui->doubleSpinBox_3->value(); - double limitlow1 = ui->doubleSpinBox_2->value(); - double limitlow2 = ui->doubleSpinBox_4->value(); - if(level == 2) - { - if(limitlow2 >= limitlow1) - { - QMessageBox::warning(0,tr("提示"),tr("越下下限值必须小于越下限值")); - return false; - } - if(limitlow1>= limitup1) - { - QMessageBox::warning(0,tr("提示"),tr("越下限值必须小于越上限值")); - return false; - } - if(limitup1>=limitup2) - { - QMessageBox::warning(0,tr("提示"),tr("越上限值必须小于越上上限值")); - return false; - } - }else if(level == 1) - { - if(limitlow1>=limitup1) - { - QMessageBox::warning(0,tr("提示"),tr("越下限值必须小于越上限值")); - return false; - } - } - } - return true; -} - -void AlarmManageWidget::addObjAlarm() -{ - if(!AlarmMng::instance()->getNomRptEditPerm()) - { - QMessageBox::warning(this,tr("提示"),tr("当前登录用户无新增告警点权限!")); - return; - } - if(m_devgName.isEmpty()) - { - QMessageBox::warning(this,tr("提示"),tr("请选择要添加自定义告警的设备组!")); - return ; - } - QList devList; - devList = AlarmMng::instance()->getDevInfoByDevGroup(m_devgName); - if(devList.isEmpty()) - { - QMessageBox::warning(this,tr("提示"),tr("此设备组下无可用设备,请重新选择设备组!")); - return ; - } - AddObjAlarmDialog dlg(devList,this); - dlg.setModal(true); - if(dlg.exec() == QDialog::Accepted) - { - initView(); - reLoadData();//重新刷新数据,防止数据不一致 - } - -} - -void AlarmManageWidget::updateStack(int index) -{ - if(m_curStackIndex == index) - { - return ; - } - m_curStackIndex = index; - initView(); - reLoadData(); - ui->stackedWidget->setCurrentIndex(index); - if(m_curStackIndex == EN_POINT_AI_INDEX) - { - setEnableObjAlarm(false); - setEnableLimitAlarm(true); - ui->widget_10->setHidden(true); - }else - { - setEnableLimitAlarm(false); - setEnableObjAlarm(true); - ui->widget_10->setHidden(false); - } -} - -void AlarmManageWidget::filterPoint() -{ - QString searchText = ui->pointFilterLineEdit->text(); - initView(); - reLoadData(searchText); -} - -void AlarmManageWidget::sigOrMul(int checked) -{ - ui->aitableView->clearSelection(); - ui->ditableView->clearSelection(); - - if(checked == 2) - { - ui->aitableView->setSelectionMode(QAbstractItemView::MultiSelection); - ui->ditableView->setSelectionMode(QAbstractItemView::MultiSelection); - }else if(checked == 0) - { - ui->aitableView->setSelectionMode(QAbstractItemView::SingleSelection); - ui->ditableView->setSelectionMode(QAbstractItemView::SingleSelection); - } - initProperty(); - setEnableProperty(false); -} - -void AlarmManageWidget::contextMenuEvent(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - if(m_curStackIndex == EN_POINT_AI_INDEX) - { - if(!m_pAiPointTableModel) - { - return ; - } - if(event->pos().x() < ui->aitableView->pos().x()) - { - return; - } - QRect headerRect = ui->aitableView->horizontalHeader()->rect(); - headerRect.moveTopLeft(ui->aitableView->mapTo(this, QPoint())); - if(!headerRect.contains(event->pos())) - { - QModelIndex index_ = ui->aitableView->indexAt(ui->aitableView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index_.isValid()) - { - return; - } - QMenu menu(this); - if(!ui->checkBox->isChecked()) - { -// showAiProperty(); -// return ; - }else - { - QAction * selectAction = menu.addAction(tr("全选")); - connect(selectAction, &QAction::triggered, [=](){ui->aitableView->selectAll();showAiProperty();}); - } - QAction * cancleAction = menu.addAction(tr("全不选")); - connect(cancleAction,&QAction::triggered,[=](){ui->aitableView->clearSelection();setEnableProperty(false);initProperty();}); - QAction * delAction = menu.addAction(tr("删除")); - connect(delAction,&QAction::triggered,[=](){deleteAi();}); - menu.exec(QCursor::pos()); - } - }else - { - if(!m_pDiPointTableModel) - { - return ; - } - if(event->pos().x() < ui->ditableView->pos().x()) - { - return; - } - QRect headerRect = ui->ditableView->horizontalHeader()->rect(); - headerRect.moveTopLeft(ui->ditableView->mapTo(this, QPoint())); - if(!headerRect.contains(event->pos())) - { - QModelIndex index_ = ui->ditableView->indexAt(ui->ditableView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index_.isValid()) - { - return; - } - QMenu menu(this); - if(!ui->checkBox->isChecked()) - { -// showDiProperty(); -// return ; - }else - { - QAction * selectAction = menu.addAction(tr("全选")); - connect(selectAction, &QAction::triggered, [=](){ui->ditableView->selectAll();showDiProperty();}); - } - QAction * cancleAction = menu.addAction(tr("全不选")); - connect(cancleAction,&QAction::triggered,[=](){ui->ditableView->clearSelection();setEnableProperty(false);initProperty();}); - QAction * delAction = menu.addAction(tr("删除")); - connect(delAction,&QAction::triggered,[=](){deleteDi();}); - menu.exec(QCursor::pos()); - } - } -} +#include "AlarmManageWidget.h" +#include "ui_AlarmManageWidget.h" +#include "pub_logger_api/logger.h" +#include "perm_mng_api/PermMngApi.h" +#include "boost/asio/ip/host_name.hpp" + +#include +#include +#include "net_msg_bus_api/MsgBusApi.h" +#include "AlarmDevTreeView.h" +#include "AlarmDevTreeModel.h" +#include "AlarmMng.h" +#include "AlarmPointTableModel.h" +#include "AlarmManageCommon.h" +#include "AddObjAlarmDialog.h" +#include "pub_utility_api/I18N.h" +#include "pub_utility_api/FileUtil.h" + +AlarmManageWidget::AlarmManageWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::AlarmManageWidget), + m_pDevTreeModel(Q_NULLPTR), + m_pAiPointTableModel(Q_NULLPTR), + m_pDiPointTableModel(Q_NULLPTR), + m_pThread(Q_NULLPTR), + m_pReadDb(Q_NULLPTR), + m_pWriteDb(Q_NULLPTR), + m_bIsEditMode(editMode), + m_devgName(QString()), + m_buttonGroup(Q_NULLPTR), + m_curStackIndex(0) +{ + ui->setupUi(this); + m_strMediaPath = ""; + qRegisterMetaType("PointInfo"); + qRegisterMetaType("QStringList"); + qRegisterMetaType >("ListPointInfoPtr"); + + qRegisterMetaType >("ListAlarmCalcInfoPtr"); + + initLayout(); + if(!m_bIsEditMode) + { + m_buttonGroup = new QButtonGroup; + m_buttonGroup->setExclusive(true); + m_buttonGroup->addButton(ui->aibt,0); + m_buttonGroup->addButton(ui->dibt,1); + initMember(); + initData(); + initCurUser(); + initConnect(); + initView(); + m_pThread->start(); + } + QDir dir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("sound"); + + m_strMediaPath = dir.absolutePath(); +} + +AlarmManageWidget::~AlarmManageWidget() +{ + AlarmMng::instance()->destory(); + delete ui; +} + +void AlarmManageWidget::initLayout() +{ + ui->hsplitter->setSizes(QList()<<200<<900<<300); + + ui->cbAlarmPriority->setView(new QListView()); + ui->cbIfLimit->setView(new QListView()); + ui->cbIfObj->setView(new QListView()); + ui->cbLevel->setView(new QListView()); +} + +void AlarmManageWidget::initMember() +{ + initModel(); + if(m_pThread == NULL) + { + m_pThread = new QThread(); + } + + AlarmMng::instance()->moveToThread(m_pThread); + m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + if(!m_pWriteDb->open()) + { + LOGERROR("打开数据库失败,error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); + } + if(!m_pReadDb->open()) + { + LOGERROR("打开数据库失败,error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); + } + + m_hostName = QString::fromStdString(boost::asio::ip::host_name()); + ui->widget_3->setMinimumWidth(300); + +} + +void AlarmManageWidget::initModel() +{ + if(m_pDevTreeModel == NULL) + { + m_pDevTreeModel = new AlarmDevTreeModel(this,ui->devTreeView); + } + //ui->devTreeView->header()->setHidden(true); + ui->devTreeView->setModel(m_pDevTreeModel); + ui->devTreeView->expandAll(); + + if(m_pAiPointTableModel == NULL) + { + m_pAiPointTableModel = new AlarmPointTableModel(this,ui->aitableView); + } + ui->aitableView->setModel(m_pAiPointTableModel); + ui->aitableView->setColumnWidth(0,200); + ui->aitableView->setColumnWidth(1,140); + ui->aitableView->setColumnWidth(2,180); + ui->aitableView->setColumnWidth(3,140); + ui->aitableView->setColumnWidth(4,60); + + if(m_pDiPointTableModel == NULL) + { + m_pDiPointTableModel = new AlarmPointTableModel(this,ui->ditableView); + } + ui->ditableView->setModel(m_pDiPointTableModel); + ui->ditableView->setColumnWidth(0,200); + ui->ditableView->setColumnWidth(1,140); + ui->ditableView->setColumnWidth(2,180); + ui->ditableView->setColumnWidth(3,140); + ui->ditableView->setColumnWidth(4,60); +} + +void AlarmManageWidget::initData() +{ + ui->cbIfObj->clear(); + ui->cbIfObj->addItem(tr("是"),1); + ui->cbIfObj->addItem(tr("否"),0); + ui->cbIfObj->setCurrentIndex(1); + + ui->cbAlarmPriority->clear(); + m_alarmLevelMap = AlarmMng::instance()->getAlarmLevel(); + int index = 0; + QMap::iterator it_level = m_alarmLevelMap.begin(); + while (it_level != m_alarmLevelMap.end()) { + ui->cbAlarmPriority->addItem(it_level.value(),it_level.key()); + m_alarmLevelIndexMap[it_level.key()] = index++; + it_level++; + } + + m_alarmLevelActionMap = AlarmMng::instance()->getAlarmLevelAction(); + m_alarmActionMap = AlarmMng::instance()->getAlarmAction(); + QHBoxLayout *hLayout = new QHBoxLayout; + QVBoxLayout *vLayout0 = new QVBoxLayout; + QVBoxLayout *vLayout1 = new QVBoxLayout; + + index = 0; + QMap::iterator it = m_alarmActionMap.begin(); + while (it != m_alarmActionMap.end()) { + + QCheckBox *box = new QCheckBox(it.value(),ui->widget_4); + m_alarmActionCheckMap[it.key()] = box; + if(index % 2 == 0) + { + vLayout0->addWidget(box); + }else if(index % 2 == 1) + { + vLayout1->addWidget(box); + } + index++; + it++; + } + vLayout0->addStretch(100); + vLayout1->addStretch(100); + //vLayout2->addStretch(100); + + hLayout->addLayout(vLayout0); + + hLayout->addLayout(vLayout1); + //hLayout->addLayout(vLayout2); + ui->widget_4->setLayout(hLayout); + ui->widget_4->setEnabled(false); + alarmActionCheckChange(0); + + ui->cbIfLimit->clear(); + ui->cbIfLimit->addItem(tr("是"),1); + ui->cbIfLimit->addItem(tr("否"),0); + + ui->cbLevel->clear(); + ui->cbLevel->addItem(tr("0"),0); + ui->cbLevel->addItem(tr("1"),1); + ui->cbLevel->addItem(tr("2"),2); + + setEnableProperty(false); +} + +bool AlarmManageWidget::initCurUser() +{ + m_userId = -1; + m_usergId = -1; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + + int userId; + int usergId; + int level; + int loginSec; + std::string name; + + std::string userName; + std::string usergName; + + if(permMngPtr->CurUser(userName,usergName,level,loginSec,name) == 0) + { + //qDebug()<CurUser(userId, usergId,level,loginSec,name) == 0) + { + m_userId = userId; + m_usergId = usergId; + }else + { + LOGERROR("获取当前登录用户失败!"); + return false; + } + return true; +} + +void AlarmManageWidget::initConnect() +{ + connect(ui->lineEdit, &QLineEdit::returnPressed, this, &AlarmManageWidget::filter); //过滤 + connect(ui->search,&QPushButton::clicked,this,&AlarmManageWidget::filter); //过滤 + connect(AlarmMng::instance(),&AlarmMng::addAiPoint,m_pAiPointTableModel,&AlarmPointTableModel::addPoint,Qt::QueuedConnection); + connect(AlarmMng::instance(),&AlarmMng::addDiPoint,m_pDiPointTableModel,&AlarmPointTableModel::addPoint,Qt::QueuedConnection); + connect(ui->cbAlarmPriority,SIGNAL(currentIndexChanged(int)),this,SLOT(alarmActionCheckChange(int))); + connect(ui->cbIfLimit,&QComboBox::currentTextChanged,this,&AlarmManageWidget::ifLimitChange); + connect(ui->cbIfObj,&QComboBox::currentTextChanged,this,&AlarmManageWidget::ifObjChange); + + connect(ui->push,&QPushButton::clicked,this,&AlarmManageWidget::getPushPicPath); + connect(ui->voice,&QPushButton::clicked,this,&AlarmManageWidget::getVoicePath); +// connect(ui->aitableView,&AlarmPointTableView::clicked,this,&AlarmManageWidget::showAiAlarmProperty); +// connect(ui->ditableView,&AlarmPointTableView::clicked,this,&AlarmManageWidget::showDiAlarmProperty); + + connect(ui->devTreeView,&AlarmDevTreeView::clicked,this,&AlarmManageWidget::checkClick,Qt::QueuedConnection); + connect(this,&AlarmManageWidget::sigSelectPoint,AlarmMng::instance(),&AlarmMng::slotSelectPoint,Qt::QueuedConnection); + connect(this,&AlarmManageWidget::sigClearPointTable,m_pAiPointTableModel,&AlarmPointTableModel::slotClearPointTable,Qt::QueuedConnection); + connect(this,&AlarmManageWidget::sigClearPointTable,m_pDiPointTableModel,&AlarmPointTableModel::slotClearPointTable,Qt::QueuedConnection); + + connect(ui->cbLevel,&QComboBox::currentTextChanged,this,&AlarmManageWidget::ifLimitLevelChange); + + connect(ui->pushButton_5,&QPushButton::clicked,this,&AlarmManageWidget::save); + + connect(ui->pushButton_2,&QPushButton::clicked,this,&AlarmManageWidget::addObjAlarm); + connect(m_buttonGroup,SIGNAL(buttonClicked(int)),this,SLOT(updateStack(int))); + connect(ui->pointFilter,&QPushButton::clicked,this,&AlarmManageWidget::filterPoint); + connect(ui->checkBox,&QCheckBox::stateChanged,this,&AlarmManageWidget::sigOrMul); + + connect(ui->aitableView,&AlarmPointTableView::sigBrushProperty,this,&AlarmManageWidget::showAiProperty); + connect(ui->ditableView,&AlarmPointTableView::sigBrushProperty,this,&AlarmManageWidget::showDiProperty); +} + +void AlarmManageWidget::setEnableProperty(bool enable) +{ + ui->widget_3->setEnabled(enable); +} + +void AlarmManageWidget::setEnableDesc(bool enable) +{ + ui->groupBox_4->setEnabled(enable); +} + +void AlarmManageWidget::setEnableObjAlarm(bool enable) +{ + ui->groupBox_2->setEnabled(enable); + ui->groupBox_2->setHidden(!enable); +} + +void AlarmManageWidget::setEnableLimitAlarm(bool enable) +{ + ui->groupBox_3->setEnabled(enable); + ui->groupBox_3->setHidden(!enable); +} + +void AlarmManageWidget::saveAi() +{ + QModelIndexList aiList = ui->aitableView->selectionModel()->selectedRows(0); + if(aiList.size() < 1) + { + return ; + } + if(aiList.size() == 1) + { + QString desc = ui->lineEdit_3->text(); + + if(desc.isEmpty()) + { + QMessageBox::warning(0,tr("提示"),tr("点描述不能为空!")); + return ; + } + } + if(!checkAiIfSave()) + { + return ; + } + + //1越限首先要修改点表,然后去修改越限表 + QString desc = ui->lineEdit_3->text(); + m_pWriteDb->transaction(); + //先修改描述(描述应不支持批量修改) + QList pointList; + foreach (QModelIndex index, aiList) { + + pointList.append(m_pAiPointTableModel->getPointInfoByRow(index.row())); + } + if(pointList.size() == 1) + { + QString sqlUpTag =QString("update %1 set description ='%2' where tag_name ='%3'").arg("analog").arg(desc).arg(pointList.at(0)->m_tag); + m_pWriteDb->execute(sqlUpTag); + }else + { + desc = QString(); + } + QString condition=QString(); + for(int conIndex = 0;conIndex m_tag); + } + if(!condition.isEmpty()) + { + condition.resize(condition.size() - 2); + condition = QString("%1 in (%2)").arg("tag_name").arg(condition); + } + + double limitup1 = ui->doubleSpinBox->value(); + double limitup2 = ui->doubleSpinBox_3->value(); + double limitlow1 = ui->doubleSpinBox_2->value(); + double limitlow2 = ui->doubleSpinBox_4->value(); + + int obj = ui->cbIfObj->currentData().toInt(); + + int priority = ui->cbAlarmPriority->currentData().toInt(); + + QString push = ui->pushText->text(); + QString voice = ui->voiceText->text(); + + int isLimit = ui->cbIfLimit->currentData().toInt(); + QString sqlupdate; + + sqlupdate = QString("update %1 set is_limit = %2,sound_name1 ='%3' where %4 ").arg("analog").arg(isLimit).arg(voice).arg(condition); + m_pWriteDb->execute(sqlupdate); + QString sqldelete; + sqldelete = QString("delete from %1 where %4").arg("analog_limit_info").arg(condition); + m_pWriteDb->execute(sqldelete); + + int limitLevel = ui->cbLevel->currentData().toInt(); + if(isLimit == 1) + { + QString sqlinsert; + sqlinsert = QString("insert into %1 (tag_name,location_id,sub_system,limit_type,limit_num,limit_up1,limit_low1,limit_up2,limit_low2,cross_percent,return_percent,is_obj_alm_manner,alarm_priority,pic_name,is_water_alm) values ").arg("analog_limit_info"); + for(int idx = 0; idx m_tag).arg(pointList.at(idx)->m_loc).arg(pointList.at(idx)->m_sub).arg(1).arg(limitLevel). + arg(limitup1).arg(limitlow1).arg(limitup2).arg(limitlow2).arg(5).arg(5).arg(obj).arg(priority).arg(push); + } + sqlinsert.resize(sqlinsert.size() - 2); + m_pWriteDb->execute(sqlinsert); + } + if(!m_pWriteDb->commit()) + { + QMessageBox::warning(0,tr("提示"),tr("保存失败!正在回滚事务~")); + LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); + m_pWriteDb->rollback(); + }else + { + for(int index = 0;index m_desc =desc.isEmpty() ? pointList.at(index)->m_desc : desc; + pointList.at(index)->m_obj = isLimit == 1 ? obj: 0; + pointList.at(index)->m_priority = isLimit == 1 ? priority: -1; + } + QMessageBox::information(0,tr("提示"),tr("保存成功!")); + } +} + +void AlarmManageWidget::saveDi() +{ + QModelIndexList diList = ui->ditableView->selectionModel()->selectedRows(0); + if(diList.size() < 1) + { + return ; + } + if(diList.size() == 1) + { + QString desc = ui->lineEdit_3->text(); + + if(desc.isEmpty()) + { + QMessageBox::warning(0,tr("提示"),tr("点描述不能为空!")); + return ; + } + } + + QString desc = ui->lineEdit_3->text(); + m_pWriteDb->transaction(); + //先修改描述(描述应不支持批量修改) + QList pointList; + foreach (QModelIndex index, diList) { + + pointList.append(m_pDiPointTableModel->getPointInfoByRow(index.row())); + } + if(pointList.size() == 1) + { + QString sqlUpTag =QString("update %1 set description ='%2' where tag_name ='%3'").arg("digital").arg(desc).arg(pointList.at(0)->m_tag); + m_pWriteDb->execute(sqlUpTag); + }else + { + desc = QString(); + } + + QString condition=QString(); + for(int conIndex = 0;conIndex m_tag); + } + if(!condition.isEmpty()) + { + condition.resize(condition.size() - 2); + condition = QString("%1 in (%2)").arg("tag_name").arg(condition); + } + + int obj = ui->cbIfObj->currentData().toInt(); + int priority = ui->cbAlarmPriority->currentData().toInt(); + QString push = ui->pushText->text(); + QString voice = ui->voiceText->text(); + + QString sql = QString("update %1 set is_obj_alm_manner = %2,alarm_priority = %3,pic_name ='%4' ,sound_name1= '%5' where" + " %6 ").arg("digital").arg(obj).arg(priority).arg(push).arg(voice).arg(condition); + + m_pWriteDb->execute(sql); + + if(!m_pWriteDb->commit()) + { + QMessageBox::warning(0,tr("提示"),tr("保存失败!正在回滚事务~")); + LOGERROR("保存失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); + m_pWriteDb->rollback(); + }else + { + for(int index = 0;index m_desc =desc.isEmpty() ? pointList.at(index)->m_desc : desc; + pointList.at(index)->m_obj = obj; + pointList.at(index)->m_priority = priority; + } + QMessageBox::information(0,tr("提示"),tr("保存成功!")); + } +} + +void AlarmManageWidget::showShieldProperty() +{ + ui->widget_6->setEnabled(true); +} + +void AlarmManageWidget::initView() +{ + //禁用属性框 + setEnableProperty(false); + //清空点表格 + emit sigClearPointTable(); + + //初始化属性窗 + initProperty(); + + initHide(); +} + +void AlarmManageWidget::initProperty() +{ + ui->lineEdit_3->setText(""); //点标签初始化为空 + + ui->cbIfObj->setCurrentIndex(0); + ui->cbAlarmPriority->setCurrentIndex(0); + ui->pushText->setText(""); + ui->voiceText->setText(""); + + ui->cbIfLimit->setCurrentIndex(1); + ui->cbLevel->setCurrentIndex(0); + ui->doubleSpinBox->setValue(0.0); + ui->doubleSpinBox_2->setValue(0.0); + ui->doubleSpinBox_3->setValue(0.0); + ui->doubleSpinBox_4->setValue(0.0); +} + +void AlarmManageWidget::initHide() +{ + ifLimitChange(""); + ifObjChange(""); + ifLimitLevelChange(""); +} + +void AlarmManageWidget::reLoadData(const QString &filter) +{ + if(!m_devgName.isEmpty()) + { + emit sigSelectPoint(m_devgName,m_curStackIndex,filter); + } +} + +void AlarmManageWidget::deleteAi() +{ + QModelIndexList aiList = ui->aitableView->selectionModel()->selectedRows(0); + if(aiList.size() < 1) + { + return ; + } + if(QMessageBox::No == QMessageBox::question(0, tr("提示"), tr("确认删除?"))) + { + return; + } + + //1删除越限表中信息 2删除测点表中信息 3删除计算量输出表中信息 + + m_pWriteDb->transaction(); + QList pointList; + foreach (QModelIndex index, aiList) { + + pointList.append(m_pAiPointTableModel->getPointInfoByRow(index.row())); + } + QString condition=QString(); + QString calCondition=QString(); + for(int conIndex = 0;conIndex m_tag); + calCondition+= QString("'analog.%1.value', ").arg(pointList.at(conIndex)->m_tag); + } + if(!condition.isEmpty()) + { + condition.resize(condition.size() - 2); + condition = QString("%1 in (%2)").arg("tag_name").arg(condition); + } + if(!calCondition.isEmpty()) + { + calCondition.resize(calCondition.size() - 2); + calCondition = QString("%1 in (%2)").arg("key_id_tag").arg(calCondition); + } + QString sqldel; + sqldel = QString("delete from %1 where %2").arg("analog").arg(condition); + m_pWriteDb->execute(sqldel); + sqldel = QString("delete from %1 where %4").arg("analog_limit_info").arg(condition); + m_pWriteDb->execute(sqldel); + sqldel = QString("delete from %1 where %2").arg("calc_out_para").arg(calCondition); + m_pWriteDb->execute(sqldel); + if(!m_pWriteDb->commit()) + { + QMessageBox::warning(0,tr("提示"),tr("删除失败!正在回滚事务~")); + LOGERROR("删除失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); + m_pWriteDb->rollback(); + }else + { + initView(); + reLoadData(); + } +} + +void AlarmManageWidget::deleteDi() +{ + QModelIndexList diList = ui->ditableView->selectionModel()->selectedRows(0); + if(diList.size() < 1) + { + return ; + } + if(QMessageBox::No == QMessageBox::question(0, tr("提示"), tr("确认删除?"))) + { + return; + } + + m_pWriteDb->transaction(); + QList pointList; + foreach (QModelIndex index, diList) { + + pointList.append(m_pDiPointTableModel->getPointInfoByRow(index.row())); + } + QString condition=QString(); + QString calCondition=QString(); + for(int conIndex = 0;conIndex m_tag); + calCondition+= QString("'digital.%1.value', ").arg(pointList.at(conIndex)->m_tag); + } + if(!condition.isEmpty()) + { + condition.resize(condition.size() - 2); + condition = QString("%1 in (%2)").arg("tag_name").arg(condition); + } + if(!calCondition.isEmpty()) + { + calCondition.resize(calCondition.size() - 2); + calCondition = QString("%1 in (%2)").arg("key_id_tag").arg(calCondition); + } + QString sqldel; + sqldel = QString("delete from %1 where %2").arg("digital").arg(condition); + m_pWriteDb->execute(sqldel); + sqldel = QString("delete from %1 where %2").arg("calc_out_para").arg(calCondition); + m_pWriteDb->execute(sqldel); + if(!m_pWriteDb->commit()) + { + QMessageBox::warning(0,tr("提示"),tr("删除失败!正在回滚事务~")); + LOGERROR("删除失败!error:%s",m_pWriteDb->getLastErrorString().toStdString().c_str()); + m_pWriteDb->rollback(); + }else + { + initView(); + reLoadData(); + } +} + +void AlarmManageWidget::filter() +{ + QString searchText = ui->lineEdit->text(); + m_pDevTreeModel->setFilter(searchText); +} + +void AlarmManageWidget::alarmActionCheckChange(int index) +{ + Q_UNUSED(index); + int priority = ui->cbAlarmPriority->currentData().toInt(); + int act = m_alarmLevelActionMap.value(priority,0); + QMap::iterator it = m_alarmActionCheckMap.begin(); + while (it != m_alarmActionCheckMap.end()) { + it.value()->setChecked(false); + if(act>>(it.key()-1) & 0x0001) + { + it.value()->setChecked(true); + } + it++; + } +} + +void AlarmManageWidget::ifLimitChange(const QString &) +{ + int index = ui->cbIfLimit->currentData().toInt(); + + if(index == 1) + { + ui->widget_7->setEnabled(true); + ui->widget_7->setHidden(false); + ui->widget_10->setHidden(false); + setEnableObjAlarm(true); + + }else if(index == 0) + { + ui->widget_7->setEnabled(false); + ui->widget_10->setHidden(true); + setEnableObjAlarm(false); + } +} + +void AlarmManageWidget::ifObjChange(const QString &) +{ + int index = ui->cbIfObj->currentData().toInt(); + + if(index == 1) + { + ui->cbAlarmPriority->setEnabled(true); + }else if(index == 0) + { + ui->cbAlarmPriority->setEnabled(false); + } +} + +void AlarmManageWidget::getPushPicPath() +{ + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open Pic"), "../../data/pic", tr("Pic Files (*.glx)")); + if(!fileName.isEmpty()) + { + QStringList list = fileName.split("pic/"); + ui->pushText->setText(list.at(list.size()-1)); + } +} + +void AlarmManageWidget::getVoicePath() +{ + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open Voice"), m_strMediaPath, tr("Pic Files (*.wav)")); + if(!fileName.isEmpty()) + { + QStringList list = fileName.split("/"); + ui->voiceText->setText(list.at(list.size()-1)); + } +} + +void AlarmManageWidget::showAiAlarmProperty(const QModelIndex &cur) +{ + initProperty(); + initHide(); + + setEnableProperty(true); + setEnableDesc(true); + setEnableObjAlarm(true); + setEnableLimitAlarm(true); + ui->widget_10->setHidden(false); + QModelIndexList indexList = ui->aitableView->selectionModel()->selectedRows(0); + QList rowList; + QString strText; + for(QModelIndex index :indexList) + { + rowList.append(index.row()); + strText = QString("%1 %2").arg(strText).arg(index.row()); + } + int size = rowList.size(); + + if(size < 1) + { + setEnableProperty(false); + setEnableLimitAlarm(true); + setEnableObjAlarm(false); + ui->widget_10->setHidden(true); + return ; + } + PointInfoPtr info; + if(rowList.contains(cur.row())) + { + info = m_pAiPointTableModel->getPointInfoByRow(cur.row()); + }else + { + info = m_pAiPointTableModel->getPointInfoByRow(rowList.last()); + } + ui->lineEdit_3->setText(info->m_desc); + + ST_LIMIT_INFO limitInfo; + ST_OBJ_INFO objInfo; + bool isLimit = AlarmMng::instance()->isAiObjAlarm(info,objInfo,limitInfo); + if(isLimit) + { + setEnableObjAlarm(true); + + ui->cbIfLimit->setCurrentIndex(0); + ui->cbLevel->setCurrentIndex(limitInfo.iLevel); + ui->doubleSpinBox->setValue(limitInfo.dLimitUp1); + ui->doubleSpinBox_2->setValue(limitInfo.dLimitDown1); + ui->doubleSpinBox_3->setValue(limitInfo.dLimitUp2); + ui->doubleSpinBox_4->setValue(limitInfo.dLimitDown2); + + ui->voiceText->setText(objInfo.strVoice); + ui->pushText->setText(objInfo.strPushPic); + + ui->cbIfObj->setCurrentIndex(objInfo.bIsObj ? 0:1); + ui->cbAlarmPriority->setCurrentIndex(m_alarmLevelIndexMap.value(objInfo.iPriority)); + }else + { + ui->cbIfLimit->setCurrentIndex(1); + ui->widget_10->setHidden(true); + ui->doubleSpinBox->setValue(0.0); + ui->doubleSpinBox_2->setValue(0.0); + ui->doubleSpinBox_3->setValue(0.0); + ui->doubleSpinBox_4->setValue(0.0); + } + ifLimitChange(""); + ifObjChange(""); + + if(size > 1) + { + ui->lineEdit_3->setText(""); //点标签初始化为空 + setEnableDesc(false); + } +} + +void AlarmManageWidget::showDiAlarmProperty(const QModelIndex &index) +{ + initProperty(); + initHide(); + + setEnableProperty(true); + setEnableDesc(true); + setEnableObjAlarm(true); + setEnableLimitAlarm(false); + + ui->widget_10->setHidden(false); + QModelIndexList indexList = ui->ditableView->selectionModel()->selectedRows(0); + QList rowList; + for(QModelIndex index :indexList) + { + rowList.append(index.row()); + } + int size = rowList.size(); + if(size < 1) + { + setEnableProperty(false); + return ; + } + + PointInfoPtr info; + if(indexList.contains(index)) + { + info = m_pDiPointTableModel->getPointInfoByRow(index.row()); + }else + { + info = m_pDiPointTableModel->getPointInfoByRow(rowList.last()); + } + + ui->lineEdit_3->setText(info->m_desc); + ST_OBJ_INFO objInfo; + bool isObj = AlarmMng::instance()->isDiObjAlarm(info,objInfo); + ui->pushText->setText(objInfo.strPushPic); + ui->voiceText->setText(objInfo.strVoice); + + ui->cbIfObj->setCurrentIndex(isObj ? 0:1); + ui->cbAlarmPriority->setCurrentIndex(m_alarmLevelIndexMap.value(objInfo.iPriority)); + ifObjChange(""); + + if(size > 1) + { + ui->lineEdit_3->setText(""); //点标签初始化为空 + setEnableDesc(false); + } +} + +void AlarmManageWidget::showAiProperty() +{ + initProperty(); + initHide(); + + setEnableProperty(true); + setEnableDesc(true); + setEnableObjAlarm(true); + setEnableLimitAlarm(true); + ui->widget->setHidden(false); + QModelIndexList indexList = ui->aitableView->selectionModel()->selectedRows(0); + QList rowList; + for(QModelIndex index :indexList) + { + rowList.append(index.row()); + } + int size = rowList.size(); + + if(size < 1) + { + setEnableProperty(false); + setEnableLimitAlarm(true); + setEnableObjAlarm(false); + ui->widget_10->setHidden(true); + return ; + } + PointInfoPtr info = m_pAiPointTableModel->getPointInfoByRow(rowList.last()); + + ui->lineEdit_3->setText(info->m_desc); + + ST_LIMIT_INFO limitInfo; + ST_OBJ_INFO objInfo; + bool isLimit = AlarmMng::instance()->isAiObjAlarm(info,objInfo,limitInfo); + if(isLimit) + { + setEnableObjAlarm(true); + + ui->cbIfLimit->setCurrentIndex(0); + ui->cbLevel->setCurrentIndex(limitInfo.iLevel); + ui->doubleSpinBox->setValue(limitInfo.dLimitUp1); + ui->doubleSpinBox_2->setValue(limitInfo.dLimitDown1); + ui->doubleSpinBox_3->setValue(limitInfo.dLimitUp2); + ui->doubleSpinBox_4->setValue(limitInfo.dLimitDown2); + + ui->voiceText->setText(objInfo.strVoice); + ui->pushText->setText(objInfo.strPushPic); + + ui->cbIfObj->setCurrentIndex(objInfo.bIsObj ? 0:1); + ui->cbAlarmPriority->setCurrentIndex(m_alarmLevelIndexMap.value(objInfo.iPriority)); + }else + { + ui->cbIfLimit->setCurrentIndex(1); + ui->widget_10->setHidden(true); + ui->doubleSpinBox->setValue(0.0); + ui->doubleSpinBox_2->setValue(0.0); + ui->doubleSpinBox_3->setValue(0.0); + ui->doubleSpinBox_4->setValue(0.0); + } + ifLimitChange(""); + ifObjChange(""); + + if(size > 1) + { + ui->lineEdit_3->setText(""); //点标签初始化为空 + setEnableDesc(false); + } +} + +void AlarmManageWidget::showDiProperty() +{ + initProperty(); + initHide(); + + setEnableProperty(true); + setEnableDesc(true); + setEnableObjAlarm(true); + setEnableLimitAlarm(false); + + ui->widget_10->setHidden(false); + QModelIndexList indexList = ui->ditableView->selectionModel()->selectedRows(0); + QList rowList; + for(QModelIndex index :indexList) + { + rowList.append(index.row()); + } + int size = rowList.size(); + if(size < 1) + { + setEnableProperty(false); + return ; + } + + PointInfoPtr info = m_pDiPointTableModel->getPointInfoByRow(rowList.last()); + + ui->lineEdit_3->setText(info->m_desc); + ST_OBJ_INFO objInfo; + bool isObj = AlarmMng::instance()->isDiObjAlarm(info,objInfo); + ui->pushText->setText(objInfo.strPushPic); + ui->voiceText->setText(objInfo.strVoice); + + ui->cbIfObj->setCurrentIndex(isObj ? 0:1); + ui->cbAlarmPriority->setCurrentIndex(m_alarmLevelIndexMap.value(objInfo.iPriority)); + ifObjChange(""); + + if(size > 1) + { + ui->lineEdit_3->setText(""); //点标签初始化为空 + setEnableDesc(false); + } +} + +void AlarmManageWidget::checkClick(const QModelIndex &index) +{ + int type =index.data(Qt::UserRole+1).toInt(); + initView(); + m_devgName = QString(); + if(type != DEV_GROUP_TYPE) + { + return; + } + m_devgName = index.data(Qt::UserRole).toString(); + reLoadData(); + if(m_curStackIndex == EN_POINT_AI_INDEX) + { + setEnableObjAlarm(false); + setEnableLimitAlarm(true); + ui->widget_10->setHidden(true); + }else + { + setEnableLimitAlarm(false); + setEnableObjAlarm(true); + ui->widget_10->setHidden(false); + } +} + +void AlarmManageWidget::ifLimitLevelChange(const QString &) +{ + int index = ui->cbLevel->currentData().toInt(); + + if(index == 1) + { + ui->doubleSpinBox->setEnabled(true); + ui->doubleSpinBox_2->setEnabled(true); + ui->doubleSpinBox_3->setEnabled(false); + ui->doubleSpinBox_4->setEnabled(false); + }else if(index == 2) + { + ui->doubleSpinBox->setEnabled(true); + ui->doubleSpinBox_2->setEnabled(true); + ui->doubleSpinBox_3->setEnabled(true); + ui->doubleSpinBox_4->setEnabled(true); + }else if(index == 0) + { + ui->doubleSpinBox->setEnabled(false); + ui->doubleSpinBox_2->setEnabled(false); + ui->doubleSpinBox_3->setEnabled(false); + ui->doubleSpinBox_4->setEnabled(false); + } +} + +void AlarmManageWidget::save() +{ + if(!AlarmMng::instance()->getNomRptEditPerm()) + { + QMessageBox::warning(this,tr("提示"),tr("当前登录用户无修改权限!")); + return; + } + if(m_curStackIndex == EN_POINT_AI_INDEX) + { + saveAi(); + }else if(m_curStackIndex == EN_POINT_DI_INDEX) + { + saveDi(); + } +} + +bool AlarmManageWidget::checkAiIfSave() +{ + int isLimit = ui->cbIfLimit->currentData().toInt(); + if(isLimit == 1) + { + int level = ui->cbLevel->currentData().toInt(); + double limitup1 = ui->doubleSpinBox->value(); + double limitup2 = ui->doubleSpinBox_3->value(); + double limitlow1 = ui->doubleSpinBox_2->value(); + double limitlow2 = ui->doubleSpinBox_4->value(); + if(level == 2) + { + if(limitlow2 >= limitlow1) + { + QMessageBox::warning(0,tr("提示"),tr("越下下限值必须小于越下限值")); + return false; + } + if(limitlow1>= limitup1) + { + QMessageBox::warning(0,tr("提示"),tr("越下限值必须小于越上限值")); + return false; + } + if(limitup1>=limitup2) + { + QMessageBox::warning(0,tr("提示"),tr("越上限值必须小于越上上限值")); + return false; + } + }else if(level == 1) + { + if(limitlow1>=limitup1) + { + QMessageBox::warning(0,tr("提示"),tr("越下限值必须小于越上限值")); + return false; + } + } + } + return true; +} + +void AlarmManageWidget::addObjAlarm() +{ + if(!AlarmMng::instance()->getNomRptEditPerm()) + { + QMessageBox::warning(this,tr("提示"),tr("当前登录用户无新增告警点权限!")); + return; + } + if(m_devgName.isEmpty()) + { + QMessageBox::warning(this,tr("提示"),tr("请选择要添加自定义告警的设备组!")); + return ; + } + QList devList; + devList = AlarmMng::instance()->getDevInfoByDevGroup(m_devgName); + if(devList.isEmpty()) + { + QMessageBox::warning(this,tr("提示"),tr("此设备组下无可用设备,请重新选择设备组!")); + return ; + } + AddObjAlarmDialog dlg(devList,this); + dlg.setModal(true); + if(dlg.exec() == QDialog::Accepted) + { + initView(); + reLoadData();//重新刷新数据,防止数据不一致 + } + +} + +void AlarmManageWidget::updateStack(int index) +{ + if(m_curStackIndex == index) + { + return ; + } + m_curStackIndex = index; + initView(); + reLoadData(); + ui->stackedWidget->setCurrentIndex(index); + if(m_curStackIndex == EN_POINT_AI_INDEX) + { + setEnableObjAlarm(false); + setEnableLimitAlarm(true); + ui->widget_10->setHidden(true); + }else + { + setEnableLimitAlarm(false); + setEnableObjAlarm(true); + ui->widget_10->setHidden(false); + } +} + +void AlarmManageWidget::filterPoint() +{ + QString searchText = ui->pointFilterLineEdit->text(); + initView(); + reLoadData(searchText); +} + +void AlarmManageWidget::sigOrMul(int checked) +{ + ui->aitableView->clearSelection(); + ui->ditableView->clearSelection(); + + if(checked == 2) + { + ui->aitableView->setSelectionMode(QAbstractItemView::MultiSelection); + ui->ditableView->setSelectionMode(QAbstractItemView::MultiSelection); + }else if(checked == 0) + { + ui->aitableView->setSelectionMode(QAbstractItemView::SingleSelection); + ui->ditableView->setSelectionMode(QAbstractItemView::SingleSelection); + } + initProperty(); + setEnableProperty(false); +} + +void AlarmManageWidget::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(m_curStackIndex == EN_POINT_AI_INDEX) + { + if(!m_pAiPointTableModel) + { + return ; + } + if(event->pos().x() < ui->aitableView->pos().x()) + { + return; + } + QRect headerRect = ui->aitableView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->aitableView->mapTo(this, QPoint())); + if(!headerRect.contains(event->pos())) + { + QModelIndex index_ = ui->aitableView->indexAt(ui->aitableView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QMenu menu(this); + if(!ui->checkBox->isChecked()) + { +// showAiProperty(); +// return ; + }else + { + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction, &QAction::triggered, [=](){ui->aitableView->selectAll();showAiProperty();}); + } + QAction * cancleAction = menu.addAction(tr("全不选")); + connect(cancleAction,&QAction::triggered,[=](){ui->aitableView->clearSelection();setEnableProperty(false);initProperty();}); + QAction * delAction = menu.addAction(tr("删除")); + connect(delAction,&QAction::triggered,[=](){deleteAi();}); + menu.exec(QCursor::pos()); + } + }else + { + if(!m_pDiPointTableModel) + { + return ; + } + if(event->pos().x() < ui->ditableView->pos().x()) + { + return; + } + QRect headerRect = ui->ditableView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->ditableView->mapTo(this, QPoint())); + if(!headerRect.contains(event->pos())) + { + QModelIndex index_ = ui->ditableView->indexAt(ui->ditableView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QMenu menu(this); + if(!ui->checkBox->isChecked()) + { +// showDiProperty(); +// return ; + }else + { + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction, &QAction::triggered, [=](){ui->ditableView->selectAll();showDiProperty();}); + } + QAction * cancleAction = menu.addAction(tr("全不选")); + connect(cancleAction,&QAction::triggered,[=](){ui->ditableView->clearSelection();setEnableProperty(false);initProperty();}); + QAction * delAction = menu.addAction(tr("删除")); + connect(delAction,&QAction::triggered,[=](){deleteDi();}); + menu.exec(QCursor::pos()); + } + } +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.h b/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.h index 054a8df5..f53dd394 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.h @@ -1,146 +1,146 @@ -#ifndef ALARMMANAGEWIDGET_H -#define ALARMMANAGEWIDGET_H - -#include -#include -#include -#include "PointInfo.h" -#include "db_api_ex/CDbApi.h" -class QComboBox; -class QLineEdit; -class QPushButton; -class AlarmDevTreeView; -class AlarmDevTreeModel; -class QThread; -class AlarmPointTableModel; -class QCheckBox; - - -namespace Ui { -class AlarmManageWidget; -} - -class AlarmManageWidget : public QWidget -{ - Q_OBJECT - -public: - explicit AlarmManageWidget(QWidget *parent = 0, bool editMode = false); - ~AlarmManageWidget(); - -signals: - void sigSelectPoint(const QString &devg,const int index,const QString &filter = ""); - - void sigClearPointTable(); -private: - void initLayout(); - - void initMember(); - - void initModel(); - - void initData(); - - bool initCurUser(); - - void initConnect(); - - void setEnableProperty(bool enable); - - void setEnableDesc(bool enable); - - void setEnableObjAlarm(bool enable); - - void setEnableLimitAlarm(bool enable); - - void saveAi(); - - void saveDi(); - - void showShieldProperty(); - - void initView(); - - void initProperty(); - - void initHide(); - - void reLoadData(const QString &filter =""); - - void deleteAi(); - - void deleteDi(); - -private slots: - void filter(); - - void alarmActionCheckChange(int index); - - void ifLimitChange(const QString & ); - - void ifObjChange(const QString &); - - void getPushPicPath(); - - void getVoicePath(); - - void showAiAlarmProperty(const QModelIndex &cur); - - void showDiAlarmProperty(const QModelIndex &cur); - - void showAiProperty(); - - void showDiProperty(); - - void checkClick(const QModelIndex &index); - - void ifLimitLevelChange(const QString &); - - void save(); - - bool checkAiIfSave(); - - void addObjAlarm(); - - void updateStack(int index); - - void filterPoint(); - - void sigOrMul(int checked); -protected: - void contextMenuEvent(QContextMenuEvent *event); - -private: - Ui::AlarmManageWidget *ui; - - QThread *m_pThread; - - AlarmDevTreeModel *m_pDevTreeModel; - AlarmPointTableModel * m_pAiPointTableModel; - AlarmPointTableModel * m_pDiPointTableModel; - QMap m_alarmActionCheckMap;//选中的告警动作 - - QMap m_alarmActionMap; //告警动作 - QMap m_alarmLevelActionMap; //等级--动作 - QMap m_alarmLevelMap; //等级--等级描述 - - QMap m_alarmLevelIndexMap; - - kbd_dbms::CDbApi *m_pReadDb; - kbd_dbms::CDbApi *m_pWriteDb; - - int m_userId; - int m_usergId; - - QString m_hostName; - - QString m_devgName; - - bool m_bIsEditMode; - QString m_strMediaPath; - - QButtonGroup *m_buttonGroup; - int m_curStackIndex; -}; - -#endif // ALARMMANAGEWIDGET_H +#ifndef ALARMMANAGEWIDGET_H +#define ALARMMANAGEWIDGET_H + +#include +#include +#include +#include "PointInfo.h" +#include "db_api_ex/CDbApi.h" +class QComboBox; +class QLineEdit; +class QPushButton; +class AlarmDevTreeView; +class AlarmDevTreeModel; +class QThread; +class AlarmPointTableModel; +class QCheckBox; + + +namespace Ui { +class AlarmManageWidget; +} + +class AlarmManageWidget : public QWidget +{ + Q_OBJECT + +public: + explicit AlarmManageWidget(QWidget *parent = 0, bool editMode = false); + ~AlarmManageWidget(); + +signals: + void sigSelectPoint(const QString &devg,const int index,const QString &filter = ""); + + void sigClearPointTable(); +private: + void initLayout(); + + void initMember(); + + void initModel(); + + void initData(); + + bool initCurUser(); + + void initConnect(); + + void setEnableProperty(bool enable); + + void setEnableDesc(bool enable); + + void setEnableObjAlarm(bool enable); + + void setEnableLimitAlarm(bool enable); + + void saveAi(); + + void saveDi(); + + void showShieldProperty(); + + void initView(); + + void initProperty(); + + void initHide(); + + void reLoadData(const QString &filter =""); + + void deleteAi(); + + void deleteDi(); + +private slots: + void filter(); + + void alarmActionCheckChange(int index); + + void ifLimitChange(const QString & ); + + void ifObjChange(const QString &); + + void getPushPicPath(); + + void getVoicePath(); + + void showAiAlarmProperty(const QModelIndex &cur); + + void showDiAlarmProperty(const QModelIndex &cur); + + void showAiProperty(); + + void showDiProperty(); + + void checkClick(const QModelIndex &index); + + void ifLimitLevelChange(const QString &); + + void save(); + + bool checkAiIfSave(); + + void addObjAlarm(); + + void updateStack(int index); + + void filterPoint(); + + void sigOrMul(int checked); +protected: + void contextMenuEvent(QContextMenuEvent *event); + +private: + Ui::AlarmManageWidget *ui; + + QThread *m_pThread; + + AlarmDevTreeModel *m_pDevTreeModel; + AlarmPointTableModel * m_pAiPointTableModel; + AlarmPointTableModel * m_pDiPointTableModel; + QMap m_alarmActionCheckMap;//选中的告警动作 + + QMap m_alarmActionMap; //告警动作 + QMap m_alarmLevelActionMap; //等级--动作 + QMap m_alarmLevelMap; //等级--等级描述 + + QMap m_alarmLevelIndexMap; + + kbd_dbms::CDbApi *m_pReadDb; + kbd_dbms::CDbApi *m_pWriteDb; + + int m_userId; + int m_usergId; + + QString m_hostName; + + QString m_devgName; + + bool m_bIsEditMode; + QString m_strMediaPath; + + QButtonGroup *m_buttonGroup; + int m_curStackIndex; +}; + +#endif // ALARMMANAGEWIDGET_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.pro b/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.pro index d94f16be..0aaaf105 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.pro +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.pro @@ -1,91 +1,91 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-09-01T08:48:38 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = AlarmManageWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_table \ - $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx - -SOURCES += \ - AlarmManageWidget.cpp \ - AlarmDevTreeView.cpp \ - AlarmDevTreeModel.cpp \ - AlarmPointTableView.cpp \ - AlarmPointTableModel.cpp \ - PointInfo.cpp \ - AlarmMng.cpp \ - AlarmManageForm.cpp \ - AlarmManagePluginWidget.cpp \ - AddObjAlarmDialog.cpp \ - #main.cpp \ - AlarmCalcInfo.cpp \ - AlarmCalcParaTableDelegate.cpp \ - AlarmCalcParaTableModel.cpp \ - AlarmUuidBase64.cpp - -HEADERS += \ - AlarmManageWidget.h \ - AlarmDevTreeView.h \ - AlarmDevTreeModel.h \ - AlarmPointTableView.h \ - AlarmPointTableModel.h \ - PointInfo.h \ - AlarmMng.h \ - AlarmManageCommon.h \ - AlarmManageForm.h \ - AlarmManagePluginWidget.h \ - AddObjAlarmDialog.h \ - AlarmCalcInfo.h \ - AlarmCalcParaTableDelegate.h \ - AlarmCalcParaTableModel.h \ - AlarmUuidBase64.h - -FORMS += \ - AlarmManageWidget.ui \ - AlarmManageForm.ui \ - AddObjAlarmDialog.ui - - -LIBS += -lboost_system -lboost_chrono -LIBS += -llog4cplus -lpub_logger_api -LIBS += -lpub_utility_api -lpub_sysinfo_api -LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api -LIBS += -lperm_mng_api -ldp_chg_data_api -LIBS += -lnet_msg_bus_api - -LIBS += -lmodel_table - -win32-msvc* { - LIBS += -lbcrypt -} - -LIBS += -lboost_system -lboost_chrono -lboost_program_options -LIBS += -lboost_filesystem - -exists($$PWD/../../../common.pri) { - include($$PWD/../../../common.pri) -}else { - error("FATAL error: connot find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2020-09-01T08:48:38 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = AlarmManageWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_table \ + $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx + +SOURCES += \ + AlarmManageWidget.cpp \ + AlarmDevTreeView.cpp \ + AlarmDevTreeModel.cpp \ + AlarmPointTableView.cpp \ + AlarmPointTableModel.cpp \ + PointInfo.cpp \ + AlarmMng.cpp \ + AlarmManageForm.cpp \ + AlarmManagePluginWidget.cpp \ + AddObjAlarmDialog.cpp \ + #main.cpp \ + AlarmCalcInfo.cpp \ + AlarmCalcParaTableDelegate.cpp \ + AlarmCalcParaTableModel.cpp \ + AlarmUuidBase64.cpp + +HEADERS += \ + AlarmManageWidget.h \ + AlarmDevTreeView.h \ + AlarmDevTreeModel.h \ + AlarmPointTableView.h \ + AlarmPointTableModel.h \ + PointInfo.h \ + AlarmMng.h \ + AlarmManageCommon.h \ + AlarmManageForm.h \ + AlarmManagePluginWidget.h \ + AddObjAlarmDialog.h \ + AlarmCalcInfo.h \ + AlarmCalcParaTableDelegate.h \ + AlarmCalcParaTableModel.h \ + AlarmUuidBase64.h + +FORMS += \ + AlarmManageWidget.ui \ + AlarmManageForm.ui \ + AddObjAlarmDialog.ui + + +LIBS += -lboost_system -lboost_chrono +LIBS += -llog4cplus -lpub_logger_api +LIBS += -lpub_utility_api -lpub_sysinfo_api +LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api +LIBS += -lperm_mng_api -ldp_chg_data_api +LIBS += -lnet_msg_bus_api + +LIBS += -lmodel_table + +win32-msvc* { + LIBS += -lbcrypt +} + +LIBS += -lboost_system -lboost_chrono -lboost_program_options +LIBS += -lboost_filesystem + +exists($$PWD/../../../common.pri) { + include($$PWD/../../../common.pri) +}else { + error("FATAL error: connot find common.pri") +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.ui b/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.ui index 5a736f6f..b3cef54d 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.ui +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManageWidget.ui @@ -1,1002 +1,1002 @@ - - - AlarmManageWidget - - - - 0 - 0 - 1438 - 928 - - - - AlarmManageWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - Qt::Horizontal - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - - 0 - 19 - - - - 请输入搜索内容 - - - - - - - - 0 - 19 - - - - 查询 - - - - - - - - 0 - 0 - - - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - Qt::Horizontal - - - - 368 - 20 - - - - - - - - - 0 - 0 - - - - - 0 - 19 - - - - 新增告警点 - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - 模拟量 - - - true - - - true - - - - - - - 数字量 - - - true - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 2 - - - 2 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - - - - 查询 - - - - - - - 多选 - - - true - - - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - false - - - false - - - - - - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - false - - - false - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - - - 27 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 9 - - - 0 - - - - - 10 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 保存 - - - - - - - - - 描述设置 - - - - - - - - - 90 - 0 - - - - 测点描述 - - - - - - - - 0 - 0 - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - - - 0 - - - - - 告警动作 - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 90 - 0 - - - - 告警优先级 - - - - - - - - 0 - 0 - - - - - - - - - - - - - 90 - 0 - - - - 告警动作 - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - - 90 - 0 - - - - 是否自定义告警 - - - - - - - - 0 - 0 - - - - - - - - - - - - - - 0 - - - 0 - - - - - - - - 越限设置 - - - - 9 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 90 - 0 - - - - 越限等级 - - - - - - - - 0 - 0 - - - - - - - - - - - - - 90 - 0 - - - - 越上限值 - - - - - - - - 0 - 0 - - - - 6 - - - -100000000.000000000000000 - - - 100000000.000000000000000 - - - - - - - - - - - - 90 - 0 - - - - 越下限值 - - - - - - - - 0 - 0 - - - - 6 - - - -100000000.000000000000000 - - - 100000000.000000000000000 - - - - - - - - - - - - 90 - 0 - - - - 越上上限值 - - - - - - - - 0 - 0 - - - - 6 - - - -100000000.000000000000000 - - - 100000000.000000000000000 - - - - - - - - - - - - 90 - 0 - - - - 越下下限值 - - - - - - - - 0 - 0 - - - - 6 - - - -100000000.000000000000000 - - - 100000000.000000000000000 - - - - - - - - - - - - - - - 90 - 0 - - - - 越限告警 - - - - - - - - 0 - 0 - - - - - - - - - - - - - - 0 - - - 0 - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - 6 - - - 0 - - - 0 - - - - - - 90 - 0 - - - - 告警推图文件 - - - - - - - - - - 选择 - - - - - - - - - 6 - - - 0 - - - 0 - - - - - - 90 - 0 - - - - 告警声音文件 - - - - - - - - - - 选择 - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - - - AlarmPointTableView - QTableView -
AlarmPointTableView.h
-
- - AlarmDevTreeView - QTreeView -
AlarmDevTreeView.h
-
-
- - -
+ + + AlarmManageWidget + + + + 0 + 0 + 1438 + 928 + + + + AlarmManageWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Horizontal + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + + 0 + 19 + + + + 请输入搜索内容 + + + + + + + + 0 + 19 + + + + 查询 + + + + + + + + 0 + 0 + + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + Qt::Horizontal + + + + 368 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 19 + + + + 新增告警点 + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 模拟量 + + + true + + + true + + + + + + + 数字量 + + + true + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 2 + + + 2 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + + + + 查询 + + + + + + + 多选 + + + true + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + false + + + false + + + + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + false + + + false + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 27 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 9 + + + 0 + + + + + 10 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 保存 + + + + + + + + + 描述设置 + + + + + + + + + 90 + 0 + + + + 测点描述 + + + + + + + + 0 + 0 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + + + 0 + + + + + 告警动作 + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 90 + 0 + + + + 告警优先级 + + + + + + + + 0 + 0 + + + + + + + + + + + + + 90 + 0 + + + + 告警动作 + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + 90 + 0 + + + + 是否自定义告警 + + + + + + + + 0 + 0 + + + + + + + + + + + + + + 0 + + + 0 + + + + + + + + 越限设置 + + + + 9 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 90 + 0 + + + + 越限等级 + + + + + + + + 0 + 0 + + + + + + + + + + + + + 90 + 0 + + + + 越上限值 + + + + + + + + 0 + 0 + + + + 6 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + + + + + + + + + + 90 + 0 + + + + 越下限值 + + + + + + + + 0 + 0 + + + + 6 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + + + + + + + + + + 90 + 0 + + + + 越上上限值 + + + + + + + + 0 + 0 + + + + 6 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + + + + + + + + + + 90 + 0 + + + + 越下下限值 + + + + + + + + 0 + 0 + + + + 6 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + + + + + + + + + + + + + 90 + 0 + + + + 越限告警 + + + + + + + + 0 + 0 + + + + + + + + + + + + + + 0 + + + 0 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 6 + + + 0 + + + 0 + + + + + + 90 + 0 + + + + 告警推图文件 + + + + + + + + + + 选择 + + + + + + + + + 6 + + + 0 + + + 0 + + + + + + 90 + 0 + + + + 告警声音文件 + + + + + + + + + + 选择 + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + + AlarmPointTableView + QTableView +
AlarmPointTableView.h
+
+ + AlarmDevTreeView + QTreeView +
AlarmDevTreeView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmMng.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmMng.cpp index 58579b55..ea15bc3d 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmMng.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmMng.cpp @@ -1,818 +1,818 @@ -#include "AlarmMng.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_utility_api/CharUtil.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" -#include -#include - -using namespace kbd_dbms; -using namespace kbd_public; -using namespace std; - -AlarmMng *AlarmMng::pInstance = NULL; -AlarmMng *AlarmMng::instance() -{ - if(pInstance == NULL) - { - pInstance = new AlarmMng(); - qRegisterMetaType("QStringList"); - } - return pInstance; -} - -void AlarmMng::destory() -{ - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - m_locMap.clear(); - m_locOrder.clear(); - m_devgMap.clear(); - m_devMap.clear(); - m_devTreeInfo.clear(); - - if(m_pReadDb) - { - delete m_pReadDb; - } - m_pReadDb = NULL; - pInstance = NULL; - delete this; -} - -QMap AlarmMng::getDevTpType() -{ - QMutexLocker locker(mutex); - return m_devTpTypeMap; -} - -QMap > > AlarmMng::getDevTreeInfo() -{ - QMutexLocker locker(mutex); - return m_devTreeInfo; -} - -QMap > AlarmMng::getDevGroupTreeInfo() -{ - QMutexLocker locker(mutex); - return m_devgTreeInfo; -} - -QList AlarmMng::getDevGroupInfo(int locId) -{ - QMutexLocker locker(mutex); - return m_devgTreeInfo.value(locId); -} - -QString AlarmMng::getLocDescById(int locId) -{ - LOGDEBUG("车站id:%d",locId); - return m_locMap.value(locId,tr("未知车站")); -} - -QString AlarmMng::getDevgDescByTag(const QString &tag) -{ - return m_devgMap.value(tag,tr("未知设备组")); -} - -QString AlarmMng::getDevDescByTag(const QString &tag) -{ - return m_devMap.value(tag,tr("未知设备")); -} - -QMap AlarmMng::getDevInfo() -{ - return m_devMap; -} - -QMap AlarmMng::getDevgInfo() -{ - return m_devgMap; -} - -QMap AlarmMng::getLocInfo() -{ - return m_locMap; -} - -QList AlarmMng::getLocOrder() -{ - return m_locOrder; -} - -QMap AlarmMng::getDevType() -{ - return m_devTypeMap; -} - -QMap AlarmMng::getAlarmAction() -{ - return m_alarmActionMap; -} - -QMap AlarmMng::getAlarmLevelAction() -{ - return m_alarmLevelActionMap; -} - -QMap AlarmMng::getAlarmLevel() -{ - return m_alarmLevelMap; -} - -bool AlarmMng::isDiObjAlarm(PointInfoPtr info,ST_OBJ_INFO &objInfo) -{ - QSqlQuery query; - QString table = "digital"; - QString sql = QString("select is_obj_alm_manner,alarm_priority," - "pic_name,sound_name1 from %1 where tag_name = '%2' limit 1").arg(table).arg(info->m_tag); - - if(!m_pReadDb->isOpen()) - { - return false; - } - - if(m_pReadDb->execute(sql,query)) - { - while (query.next()) { - - bool isObj = query.value(0).toBool(); - objInfo.bIsObj = isObj; - objInfo.iPriority = query.value(1).toInt(); - objInfo.strPushPic = query.value(2).toString(); - objInfo.strVoice = query.value(3).toString(); - return isObj; - - } - } - - return false; -} - -bool AlarmMng::isAiObjAlarm(PointInfoPtr info, ST_OBJ_INFO &objInfo, ST_LIMIT_INFO &limitInfo) -{ - QSqlQuery query; - bool isLimit = false; - QString table = "analog"; - QString tableLimit = "analog_limit_info"; - QString stVoice; - QString sql =QString("select is_limit,sound_name1 from %1 where tag_name = '%2' limit 1").arg(table).arg(info->m_tag); - - if(!m_pReadDb->isOpen()) - { - return false; - } - - if(m_pReadDb->execute(sql,query)) - { - while (query.next()) { - - isLimit = query.value(0).toBool(); - stVoice = query.value(1).toString(); - break; - } - } - limitInfo.bIsLimit =isLimit; - objInfo.strVoice = stVoice; - objInfo.bIsObj = false; - if(!isLimit) - { - return isLimit; - }else - { - sql = QString("select limit_num,limit_up1,limit_low1,limit_up2,limit_low2,is_obj_alm_manner" - ",alarm_priority,pic_name from %1 where tag_name = '%2' limit 1").arg(tableLimit).arg(info->m_tag); - if(m_pReadDb->execute(sql,query)) - { - while (query.next()) { - limitInfo.iLevel = query.value(0).toInt(); - limitInfo.dLimitUp1 = query.value(1).toDouble(); - limitInfo.dLimitDown1 = query.value(2).toDouble(); - limitInfo.dLimitUp2 = query.value(3).toDouble(); - limitInfo.dLimitDown2 = query.value(4).toDouble(); - - objInfo.bIsObj = query.value(5).toBool(); - objInfo.iPriority = query.value(6).toInt(); - objInfo.strPushPic = query.value(7).toString(); - break; - } - } - } - return isLimit; - -} - -QMap AlarmMng::getUserInfo() -{ - return m_userInfo; -} - -QMap AlarmMng::getFuncInfo() -{ - return m_funcMap; -} - -QMap > AlarmMng::getCalcInfo() -{ - return m_calcInfoMap; -} - -QList AlarmMng::getDevInfoByDevGroup(const QString devGroup) -{ - QList devList; - QMap >::iterator it = m_devgDevMap.find(devGroup); - if(it!= m_devgDevMap.end()) - { - QList devTagList =it.value(); - for(int index(0);index AlarmMng::getDiText() -{ - return m_diTextList; -} - -bool AlarmMng::getNomRptEditPerm() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - std::string tmpStr = "FUNC_NOM_RPT_EDIT"; - if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) - { - return false; - } - return true; -} - -void AlarmMng::slotSelectPoint(const QString &devg, const int index, const QString &filter) -{ - if(devg.isEmpty()) - { - return ; - } - QStringList devList = m_devgDevMap.value(devg); - loadPointByDev(devList,index,filter); -} - -AlarmMng::AlarmMng() - : QObject() -{ - mutex = new QMutex; - - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - if(!m_pReadDb->open()) - { - LOGERROR("打开数据库失败,error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); - } - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - loadLocInfo(); - loadDevgInfo(); - loadDevInfo(); - loadDevType(); - loadAlarmAction(); - loadAlarmLevel(); - loadUserInfo(); - loadFuncInfo(); - loadCalcInfo(); - loadDiText(); -} - -void AlarmMng::loadLocInfo() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return; - } - int level; - std::vector vecLocationId; - std::vector vecPermPic; - - if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) - { - LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); - return; - } - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - QPair id_value; - id_value.first = "location_id"; - id_value.second = "description"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back(id_value.first); - columns.push_back(id_value.second); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - m_locMap.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - - std::vector ::const_iterator it = vecLocationId.cbegin(); - while (it != vecLocationId.cend()) - { - if(key.toInt() == *it) - { - m_locMap[key.toInt()] = QString::fromStdString(value.toStdString()); - m_locOrder.push_back(key.toInt()); - } - ++it; - } - } - } - } -} - -void AlarmMng::loadDevgInfo() -{ - QList devList; - QSqlQuery query; - - QString strLoctionFilter; - if(m_locMap.keys().isEmpty()) - { - return ; - } - QStringList listLocation; - foreach (int nLocationID, m_locMap.keys()) - { - listLocation.append(QString::number(nLocationID)); - } - strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); - - QString sqlSequenceQuery = QString("select tag_name, description, location_id from dev_group where sub_system > 3"); - if(!strLoctionFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); - }else - { - sqlSequenceQuery.append(QString(" order by dev_group_no asc;")); - } - - if(m_pReadDb->execute(sqlSequenceQuery,query)) - { - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - int loc = query.value(2).toInt(); - - m_devgMap[tag] = desc; - m_devGlocIdMap[tag] = loc; - m_devTreeInfo[loc].insert(tag, devList); - m_devgTreeInfo[loc].append(tag); - } - } - -} - -void AlarmMng::loadDevInfo() -{ - QSqlQuery query; - - QString strLoctionFilter; - if(m_devgMap.isEmpty()) - return; - - strLoctionFilter = QString("(group_tag_name in ('%1'))").arg(m_devgMap.keys().join("','")); - QString sqlSequenceQuery = QString("select tag_name, description, group_tag_name, location_id,dev_tp_name,dev_type from dev_info"); - if(!strLoctionFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" where %1;").arg(strLoctionFilter)); - } - if(m_pReadDb->execute(sqlSequenceQuery,query)) - { - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - QString devg = query.value(2).toString(); - int locId = query.value(3).toInt(); - QString devType = query.value(4).toString(); - int nDevType = query.value(5).toInt(); - m_devTypeMap[tag] = devType; - m_devMap[tag] = desc; - m_devTreeInfo[locId][devg].append(tag); - m_devgDevMap[devg].append(tag); - m_devTypeIdMap[tag] = nDevType; - } - } - -} - -void AlarmMng::loadDevType() -{ - QSqlQuery query; - - QString sqlSequenceQuery = QString("select tag_name, description from dev_temp_def where sub_system > 3"); - - if(m_pReadDb->execute(sqlSequenceQuery,query)) - { - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - m_devTpTypeMap[tag] = desc; - } - } - -} - -void AlarmMng::loadAlarmAction() -{ - QSqlQuery query; - QString sqlSequenceQuery = QString("select action_id, action_name from alarm_action_define"); - if(m_pReadDb->execute(sqlSequenceQuery,query)) - { - while(query.next()) - { - int id = query.value(0).toInt(); - QString name = query.value(1).toString(); - m_alarmActionMap[id] = name; - } - } -} - -void AlarmMng::loadAlarmLevel() -{ - QSqlQuery query; - QString sqlSequenceQuery = QString("select priority_id, priority_name ,alarm_actions from alarm_level_define"); - if(m_pReadDb->execute(sqlSequenceQuery,query)) - { - while(query.next()) - { - int id = query.value(0).toInt(); - QString name = query.value(1).toString(); - int action = query.value(2).toInt(); - m_alarmLevelMap[id] = name; - m_alarmLevelActionMap[id] = action; - } - } -} - -void AlarmMng::loadPointByDev(const QStringList &devList, const int index, const QString &filter) -{ - QList pointList; - switch (index) { - case EN_POINT_AI_INDEX: - loadAi(pointList,devList); - filterPoint(pointList,filter); - if(pointList.size()>0) - { - emit addAiPoint(pointList); - } - - break; - case EN_POINT_DI_INDEX: - loadDi(pointList,devList); - filterPoint(pointList,filter); - if(pointList.size()>0) - { - emit addDiPoint(pointList); - } - break; - default: - break; - } -} - -void AlarmMng::loadAi(QList &pointList, const QStringList &devList) -{ - QSqlQuery query; - QString strDeviceFilter; - QString tableName = "analog"; - - strDeviceFilter = "'" + devList.join("', '") + "'"; - strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); - QString sql = QString("select %1.tag_name,%1.description,%1.device,%1.location_id,%1.is_limit" - ",%2.group_tag_name from %1 left join %2 on %1.device" - " = %2.tag_name where %3").arg(tableName).arg("dev_info").arg(strDeviceFilter); - if(m_pReadDb->execute(sql,query)) - { - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - QString dev = query.value(2).toString(); - int locId = query.value(3).toInt(); - int isLimit = query.value(4).toInt(); - - QString devg = query.value(5).toString(); - PointInfoPtr info(new PointInfo()); - info->m_tag = tag; - if(isLimit == 1) - { - getAlarmObj(info); - } - - info->m_desc = desc; - info->m_dev = dev; - info->m_devg = devg; - info->m_loc = locId; - info->m_sub = 4; - info->m_type = EN_POINT_ANALOG; - pointList.append(info); - } - } -} - -void AlarmMng::loadDi(QList &pointList, const QStringList &devList) -{ - QSqlQuery query; - QString strDeviceFilter; - QString tableName = "digital"; - - strDeviceFilter = "'" + devList.join("', '") + "'"; - strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); - QString sql = QString("select %1.tag_name,%1.description,%1.device,%1.location_id,%1.is_obj_alm_manner,%1.alarm_priority" - ",%2.group_tag_name from %1 left join %2 on %1.device" - " = %2.tag_name where %3").arg(tableName).arg("dev_info").arg(strDeviceFilter); - - if(m_pReadDb->execute(sql,query)) - { - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - QString dev = query.value(2).toString(); - int locId = query.value(3).toInt(); - int is_obj = query.value(4).toInt(); - int priority = -1; - QString devg = query.value(6).toString(); - - priority = query.value(5).toInt(); - - PointInfoPtr info(new PointInfo()); - info->m_tag = tag; - //getAlarmShield(info); - info->m_desc = desc; - info->m_dev = dev; - info->m_devg = devg; - info->m_sub = 4; - info->m_loc = locId; - info->m_obj = is_obj; - info->m_type = EN_POINT_DIGITAL; - info->m_priority = priority; - pointList.append(info); - } - } -} - -void AlarmMng::loadPi(QList &pointList, const QStringList &devList) -{ - QSqlQuery query; - QString strDeviceFilter; - QString tableName = "accuml"; - - strDeviceFilter = "'" + devList.join("', '") + "'"; - strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); - QString sql = QString("select %1.tag_name,%1.description,%1.device,%1.location_id" - ",%2.group_tag_name from %1 left join %2 on %1.device" - " = %2.tag_name where %3").arg(tableName).arg("dev_info").arg(strDeviceFilter); - - if(m_pReadDb->execute(sql,query)) - { - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - QString dev = query.value(2).toString(); - int locId = query.value(3).toInt(); - QString devg = query.value(4).toString(); - - PointInfoPtr info(new PointInfo()); - info->m_tag = tag; - info->m_desc = desc; - info->m_dev = dev; - info->m_devg = devg; - info->m_loc = locId; - info->m_type = EN_POINT_ACCUML; - pointList.append(info); - } - } -} - -void AlarmMng::loadUserInfo() -{ - QSqlQuery query; - QString tableName = "rm_user_def"; - QString sql = QString("select %1.perm_id,%1.perm_name,%1.perm_alias,%1.perm_desc from %1").arg(tableName); - if(m_pReadDb->execute(sql,query)) - { - while (query.next()) { - ST_USER_DEF user; - user.iId = query.value(0).toInt(); - user.strName = query.value(1).toString(); - user.strAlias = query.value(2).toString(); - user.strDesc = query.value(3).toString(); - m_userInfo[user.iId] = user; - } - } -} - -void AlarmMng::loadFuncInfo() -{ - QSqlQuery query; - QString tableName = "calc_func_def"; - QString sql = QString("select %1.func_name,%1.description from %1").arg(tableName); - if(m_pReadDb->execute(sql,query)) - { - while (query.next()) { - m_funcMap[query.value(0).toString()] = query.value(1).toString(); - } - } -} - -void AlarmMng::loadCalcInfo() -{ - m_calcInfoMap.clear(); - QSqlQuery query; - QString tableName = "calc_para_def"; - QString sql = QString("select %1.func_name,%1.para_seq_no,%1.description from %1 ").arg(tableName); - if(m_pReadDb->execute(sql,query)) - { - while (query.next()) { - AlarmCalcInfoPtr info(new AlarmCalcInfo()); - info->m_tag = query.value(0).toString(); - info->m_nId = query.value(1).toInt(); - info->m_strTip = query.value(2).toString(); - m_calcInfoMap[info->m_tag].append(info); - } - } -} - -void AlarmMng::loadDiText() -{ - m_diTextList.clear(); - - QSqlQuery query; - QString tableName = "dict_state_text_info"; - QString sql = QString("select state_text_name from %1 where sub_system >3 group by state_text_name").arg(tableName); - if(m_pReadDb->execute(sql,query)) - { - while (query.next()) { - QString text = query.value(0).toString(); - m_diTextList.append(text); - } - } -} - -void AlarmMng::filterPoint(QList &pointList, const QString &filter) -{ - if(!filter.isEmpty()) - { - QList::iterator iter = pointList.begin(); - while (iter != pointList.end()) { - if(!conditionFilter(*iter,filter)) - { - iter = pointList.erase(iter); - //pointList.erase(iter++); - }else - { - iter++; - } - } - } -} - -bool AlarmMng::conditionFilter(PointInfoPtr info,const QString &filter) -{ - if(info->m_desc.indexOf(filter) != -1) - { - return true; - } - if(m_locMap.value(info->m_loc,"").indexOf(filter) != -1) - { - return true; - } - if(m_devgMap.value(info->m_devg,"").indexOf(filter) != -1) - { - return true; - } - if(m_devMap.value(info->m_dev).indexOf(filter) != -1) - { - return true; - } - if(m_alarmLevelMap.value(info->m_priority,tr("未知")).indexOf(filter) != -1) - { - return true; - } - QString text; - int priority = info->m_priority; - if( priority < 0) - { - text = "-"; - }else - { - int act = m_alarmLevelActionMap.value(priority,0); - QMap::const_iterator it = m_alarmActionMap.cbegin(); - while (it != m_alarmActionMap.cend()) { - if(act>>(it.key()-1) & 0x0001) - { - text += QString("%2 ").arg(it.value()); - } - it++; - } - } - if(text.indexOf(filter) != -1) - { - return true; - } - return false; -} - -void AlarmMng::getAlarmObj(PointInfoPtr info) -{ - QSqlQuery query; - QString tableName = "analog_limit_info"; - QString sql = QString("select %1.is_obj_alm_manner,%1.alarm_priority from %1 where tag_name = '%2' ").arg(tableName).arg(info->m_tag); - if(m_pReadDb->execute(sql,query)) - { - while (query.next()) { - int is_obj = query.value(0).toInt(); - int priority = query.value(1).toInt(); - info->m_obj = is_obj; - info->m_priority = priority; - return ; - } - } - return ; -} - -//void AlarmMng::getAlarmShield(PointInfoPtr info) -//{ -// QSqlQuery query; -// QString sql = QString("select shield_id,key_id_tag from %1 where shield_object ='%2' limit 1").arg("opt_shield_obj").arg(info->m_tag); -// if(m_pReadDb->execute(sql,query)) -// { -// while (query.next()) { -// int shield_id =query.value(0).toInt(); -// QString key_id_tag = query.value(1).toString(); -// info->m_bShield = true; -// info->m_keyIdTag =key_id_tag; -// info->m_shieldId = shield_id; -// break; -// } -// } -// //查询屏蔽描述和时段 -// if(!info->m_bShield) -// { -// return ; -// } -// query.clear(); -// sql = QString("select shield_name,time_id from %1 where shield_id =%2 limit 1").arg("opt_shield_info").arg(info->m_shieldId); -// if(m_pReadDb->execute(sql,query)) -// { -// while (query.next()) { -// info->m_shieldDesc = query.value(0).toString(); -// int time_id =query.value(1).toInt(); -// info->m_timeId = time_id; -// break; -// } -// } -// if(info->m_timeId < 0) -// { -// return ; -// } -// query.clear(); -// sql = QString("select time_type,start_time,end_time,time_option from %1 where time_id = %2 limit 1").arg("opt_shield_time").arg(info->m_timeId); -// if(m_pReadDb->execute(sql,query)) -// { -// while (query.next()) { -// info->m_timeType = query.value(0).toInt(); -// info->m_startTime = query.value(1).toString(); -// info->m_endTime = query.value(2).toString(); -// info->m_timeOption = query.value(3).toInt(); -// break; -// } -// } -//} +#include "AlarmMng.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_utility_api/CharUtil.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" +#include +#include + +using namespace kbd_dbms; +using namespace kbd_public; +using namespace std; + +AlarmMng *AlarmMng::pInstance = NULL; +AlarmMng *AlarmMng::instance() +{ + if(pInstance == NULL) + { + pInstance = new AlarmMng(); + qRegisterMetaType("QStringList"); + } + return pInstance; +} + +void AlarmMng::destory() +{ + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_locMap.clear(); + m_locOrder.clear(); + m_devgMap.clear(); + m_devMap.clear(); + m_devTreeInfo.clear(); + + if(m_pReadDb) + { + delete m_pReadDb; + } + m_pReadDb = NULL; + pInstance = NULL; + delete this; +} + +QMap AlarmMng::getDevTpType() +{ + QMutexLocker locker(mutex); + return m_devTpTypeMap; +} + +QMap > > AlarmMng::getDevTreeInfo() +{ + QMutexLocker locker(mutex); + return m_devTreeInfo; +} + +QMap > AlarmMng::getDevGroupTreeInfo() +{ + QMutexLocker locker(mutex); + return m_devgTreeInfo; +} + +QList AlarmMng::getDevGroupInfo(int locId) +{ + QMutexLocker locker(mutex); + return m_devgTreeInfo.value(locId); +} + +QString AlarmMng::getLocDescById(int locId) +{ + LOGDEBUG("车站id:%d",locId); + return m_locMap.value(locId,tr("未知车站")); +} + +QString AlarmMng::getDevgDescByTag(const QString &tag) +{ + return m_devgMap.value(tag,tr("未知设备组")); +} + +QString AlarmMng::getDevDescByTag(const QString &tag) +{ + return m_devMap.value(tag,tr("未知设备")); +} + +QMap AlarmMng::getDevInfo() +{ + return m_devMap; +} + +QMap AlarmMng::getDevgInfo() +{ + return m_devgMap; +} + +QMap AlarmMng::getLocInfo() +{ + return m_locMap; +} + +QList AlarmMng::getLocOrder() +{ + return m_locOrder; +} + +QMap AlarmMng::getDevType() +{ + return m_devTypeMap; +} + +QMap AlarmMng::getAlarmAction() +{ + return m_alarmActionMap; +} + +QMap AlarmMng::getAlarmLevelAction() +{ + return m_alarmLevelActionMap; +} + +QMap AlarmMng::getAlarmLevel() +{ + return m_alarmLevelMap; +} + +bool AlarmMng::isDiObjAlarm(PointInfoPtr info,ST_OBJ_INFO &objInfo) +{ + QSqlQuery query; + QString table = "digital"; + QString sql = QString("select is_obj_alm_manner,alarm_priority," + "pic_name,sound_name1 from %1 where tag_name = '%2' limit 1").arg(table).arg(info->m_tag); + + if(!m_pReadDb->isOpen()) + { + return false; + } + + if(m_pReadDb->execute(sql,query)) + { + while (query.next()) { + + bool isObj = query.value(0).toBool(); + objInfo.bIsObj = isObj; + objInfo.iPriority = query.value(1).toInt(); + objInfo.strPushPic = query.value(2).toString(); + objInfo.strVoice = query.value(3).toString(); + return isObj; + + } + } + + return false; +} + +bool AlarmMng::isAiObjAlarm(PointInfoPtr info, ST_OBJ_INFO &objInfo, ST_LIMIT_INFO &limitInfo) +{ + QSqlQuery query; + bool isLimit = false; + QString table = "analog"; + QString tableLimit = "analog_limit_info"; + QString stVoice; + QString sql =QString("select is_limit,sound_name1 from %1 where tag_name = '%2' limit 1").arg(table).arg(info->m_tag); + + if(!m_pReadDb->isOpen()) + { + return false; + } + + if(m_pReadDb->execute(sql,query)) + { + while (query.next()) { + + isLimit = query.value(0).toBool(); + stVoice = query.value(1).toString(); + break; + } + } + limitInfo.bIsLimit =isLimit; + objInfo.strVoice = stVoice; + objInfo.bIsObj = false; + if(!isLimit) + { + return isLimit; + }else + { + sql = QString("select limit_num,limit_up1,limit_low1,limit_up2,limit_low2,is_obj_alm_manner" + ",alarm_priority,pic_name from %1 where tag_name = '%2' limit 1").arg(tableLimit).arg(info->m_tag); + if(m_pReadDb->execute(sql,query)) + { + while (query.next()) { + limitInfo.iLevel = query.value(0).toInt(); + limitInfo.dLimitUp1 = query.value(1).toDouble(); + limitInfo.dLimitDown1 = query.value(2).toDouble(); + limitInfo.dLimitUp2 = query.value(3).toDouble(); + limitInfo.dLimitDown2 = query.value(4).toDouble(); + + objInfo.bIsObj = query.value(5).toBool(); + objInfo.iPriority = query.value(6).toInt(); + objInfo.strPushPic = query.value(7).toString(); + break; + } + } + } + return isLimit; + +} + +QMap AlarmMng::getUserInfo() +{ + return m_userInfo; +} + +QMap AlarmMng::getFuncInfo() +{ + return m_funcMap; +} + +QMap > AlarmMng::getCalcInfo() +{ + return m_calcInfoMap; +} + +QList AlarmMng::getDevInfoByDevGroup(const QString devGroup) +{ + QList devList; + QMap >::iterator it = m_devgDevMap.find(devGroup); + if(it!= m_devgDevMap.end()) + { + QList devTagList =it.value(); + for(int index(0);index AlarmMng::getDiText() +{ + return m_diTextList; +} + +bool AlarmMng::getNomRptEditPerm() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string tmpStr = "FUNC_NOM_RPT_EDIT"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + return false; + } + return true; +} + +void AlarmMng::slotSelectPoint(const QString &devg, const int index, const QString &filter) +{ + if(devg.isEmpty()) + { + return ; + } + QStringList devList = m_devgDevMap.value(devg); + loadPointByDev(devList,index,filter); +} + +AlarmMng::AlarmMng() + : QObject() +{ + mutex = new QMutex; + + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + LOGERROR("打开数据库失败,error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); + } + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + loadLocInfo(); + loadDevgInfo(); + loadDevInfo(); + loadDevType(); + loadAlarmAction(); + loadAlarmLevel(); + loadUserInfo(); + loadFuncInfo(); + loadCalcInfo(); + loadDiText(); +} + +void AlarmMng::loadLocInfo() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + int level; + std::vector vecLocationId; + std::vector vecPermPic; + + if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) + { + LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); + return; + } + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + QPair id_value; + id_value.first = "location_id"; + id_value.second = "description"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back(id_value.first); + columns.push_back(id_value.second); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + m_locMap.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + std::vector ::const_iterator it = vecLocationId.cbegin(); + while (it != vecLocationId.cend()) + { + if(key.toInt() == *it) + { + m_locMap[key.toInt()] = QString::fromStdString(value.toStdString()); + m_locOrder.push_back(key.toInt()); + } + ++it; + } + } + } + } +} + +void AlarmMng::loadDevgInfo() +{ + QList devList; + QSqlQuery query; + + QString strLoctionFilter; + if(m_locMap.keys().isEmpty()) + { + return ; + } + QStringList listLocation; + foreach (int nLocationID, m_locMap.keys()) + { + listLocation.append(QString::number(nLocationID)); + } + strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); + + QString sqlSequenceQuery = QString("select tag_name, description, location_id from dev_group where sub_system > 3"); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); + }else + { + sqlSequenceQuery.append(QString(" order by dev_group_no asc;")); + } + + if(m_pReadDb->execute(sqlSequenceQuery,query)) + { + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + int loc = query.value(2).toInt(); + + m_devgMap[tag] = desc; + m_devGlocIdMap[tag] = loc; + m_devTreeInfo[loc].insert(tag, devList); + m_devgTreeInfo[loc].append(tag); + } + } + +} + +void AlarmMng::loadDevInfo() +{ + QSqlQuery query; + + QString strLoctionFilter; + if(m_devgMap.isEmpty()) + return; + + strLoctionFilter = QString("(group_tag_name in ('%1'))").arg(m_devgMap.keys().join("','")); + QString sqlSequenceQuery = QString("select tag_name, description, group_tag_name, location_id,dev_tp_name,dev_type from dev_info"); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" where %1;").arg(strLoctionFilter)); + } + if(m_pReadDb->execute(sqlSequenceQuery,query)) + { + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + QString devg = query.value(2).toString(); + int locId = query.value(3).toInt(); + QString devType = query.value(4).toString(); + int nDevType = query.value(5).toInt(); + m_devTypeMap[tag] = devType; + m_devMap[tag] = desc; + m_devTreeInfo[locId][devg].append(tag); + m_devgDevMap[devg].append(tag); + m_devTypeIdMap[tag] = nDevType; + } + } + +} + +void AlarmMng::loadDevType() +{ + QSqlQuery query; + + QString sqlSequenceQuery = QString("select tag_name, description from dev_temp_def where sub_system > 3"); + + if(m_pReadDb->execute(sqlSequenceQuery,query)) + { + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + m_devTpTypeMap[tag] = desc; + } + } + +} + +void AlarmMng::loadAlarmAction() +{ + QSqlQuery query; + QString sqlSequenceQuery = QString("select action_id, action_name from alarm_action_define"); + if(m_pReadDb->execute(sqlSequenceQuery,query)) + { + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + m_alarmActionMap[id] = name; + } + } +} + +void AlarmMng::loadAlarmLevel() +{ + QSqlQuery query; + QString sqlSequenceQuery = QString("select priority_id, priority_name ,alarm_actions from alarm_level_define"); + if(m_pReadDb->execute(sqlSequenceQuery,query)) + { + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + int action = query.value(2).toInt(); + m_alarmLevelMap[id] = name; + m_alarmLevelActionMap[id] = action; + } + } +} + +void AlarmMng::loadPointByDev(const QStringList &devList, const int index, const QString &filter) +{ + QList pointList; + switch (index) { + case EN_POINT_AI_INDEX: + loadAi(pointList,devList); + filterPoint(pointList,filter); + if(pointList.size()>0) + { + emit addAiPoint(pointList); + } + + break; + case EN_POINT_DI_INDEX: + loadDi(pointList,devList); + filterPoint(pointList,filter); + if(pointList.size()>0) + { + emit addDiPoint(pointList); + } + break; + default: + break; + } +} + +void AlarmMng::loadAi(QList &pointList, const QStringList &devList) +{ + QSqlQuery query; + QString strDeviceFilter; + QString tableName = "analog"; + + strDeviceFilter = "'" + devList.join("', '") + "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); + QString sql = QString("select %1.tag_name,%1.description,%1.device,%1.location_id,%1.is_limit" + ",%2.group_tag_name from %1 left join %2 on %1.device" + " = %2.tag_name where %3").arg(tableName).arg("dev_info").arg(strDeviceFilter); + if(m_pReadDb->execute(sql,query)) + { + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + QString dev = query.value(2).toString(); + int locId = query.value(3).toInt(); + int isLimit = query.value(4).toInt(); + + QString devg = query.value(5).toString(); + PointInfoPtr info(new PointInfo()); + info->m_tag = tag; + if(isLimit == 1) + { + getAlarmObj(info); + } + + info->m_desc = desc; + info->m_dev = dev; + info->m_devg = devg; + info->m_loc = locId; + info->m_sub = 4; + info->m_type = EN_POINT_ANALOG; + pointList.append(info); + } + } +} + +void AlarmMng::loadDi(QList &pointList, const QStringList &devList) +{ + QSqlQuery query; + QString strDeviceFilter; + QString tableName = "digital"; + + strDeviceFilter = "'" + devList.join("', '") + "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); + QString sql = QString("select %1.tag_name,%1.description,%1.device,%1.location_id,%1.is_obj_alm_manner,%1.alarm_priority" + ",%2.group_tag_name from %1 left join %2 on %1.device" + " = %2.tag_name where %3").arg(tableName).arg("dev_info").arg(strDeviceFilter); + + if(m_pReadDb->execute(sql,query)) + { + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + QString dev = query.value(2).toString(); + int locId = query.value(3).toInt(); + int is_obj = query.value(4).toInt(); + int priority = -1; + QString devg = query.value(6).toString(); + + priority = query.value(5).toInt(); + + PointInfoPtr info(new PointInfo()); + info->m_tag = tag; + //getAlarmShield(info); + info->m_desc = desc; + info->m_dev = dev; + info->m_devg = devg; + info->m_sub = 4; + info->m_loc = locId; + info->m_obj = is_obj; + info->m_type = EN_POINT_DIGITAL; + info->m_priority = priority; + pointList.append(info); + } + } +} + +void AlarmMng::loadPi(QList &pointList, const QStringList &devList) +{ + QSqlQuery query; + QString strDeviceFilter; + QString tableName = "accuml"; + + strDeviceFilter = "'" + devList.join("', '") + "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); + QString sql = QString("select %1.tag_name,%1.description,%1.device,%1.location_id" + ",%2.group_tag_name from %1 left join %2 on %1.device" + " = %2.tag_name where %3").arg(tableName).arg("dev_info").arg(strDeviceFilter); + + if(m_pReadDb->execute(sql,query)) + { + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + QString dev = query.value(2).toString(); + int locId = query.value(3).toInt(); + QString devg = query.value(4).toString(); + + PointInfoPtr info(new PointInfo()); + info->m_tag = tag; + info->m_desc = desc; + info->m_dev = dev; + info->m_devg = devg; + info->m_loc = locId; + info->m_type = EN_POINT_ACCUML; + pointList.append(info); + } + } +} + +void AlarmMng::loadUserInfo() +{ + QSqlQuery query; + QString tableName = "rm_user_def"; + QString sql = QString("select %1.perm_id,%1.perm_name,%1.perm_alias,%1.perm_desc from %1").arg(tableName); + if(m_pReadDb->execute(sql,query)) + { + while (query.next()) { + ST_USER_DEF user; + user.iId = query.value(0).toInt(); + user.strName = query.value(1).toString(); + user.strAlias = query.value(2).toString(); + user.strDesc = query.value(3).toString(); + m_userInfo[user.iId] = user; + } + } +} + +void AlarmMng::loadFuncInfo() +{ + QSqlQuery query; + QString tableName = "calc_func_def"; + QString sql = QString("select %1.func_name,%1.description from %1").arg(tableName); + if(m_pReadDb->execute(sql,query)) + { + while (query.next()) { + m_funcMap[query.value(0).toString()] = query.value(1).toString(); + } + } +} + +void AlarmMng::loadCalcInfo() +{ + m_calcInfoMap.clear(); + QSqlQuery query; + QString tableName = "calc_para_def"; + QString sql = QString("select %1.func_name,%1.para_seq_no,%1.description from %1 ").arg(tableName); + if(m_pReadDb->execute(sql,query)) + { + while (query.next()) { + AlarmCalcInfoPtr info(new AlarmCalcInfo()); + info->m_tag = query.value(0).toString(); + info->m_nId = query.value(1).toInt(); + info->m_strTip = query.value(2).toString(); + m_calcInfoMap[info->m_tag].append(info); + } + } +} + +void AlarmMng::loadDiText() +{ + m_diTextList.clear(); + + QSqlQuery query; + QString tableName = "dict_state_text_info"; + QString sql = QString("select state_text_name from %1 where sub_system >3 group by state_text_name").arg(tableName); + if(m_pReadDb->execute(sql,query)) + { + while (query.next()) { + QString text = query.value(0).toString(); + m_diTextList.append(text); + } + } +} + +void AlarmMng::filterPoint(QList &pointList, const QString &filter) +{ + if(!filter.isEmpty()) + { + QList::iterator iter = pointList.begin(); + while (iter != pointList.end()) { + if(!conditionFilter(*iter,filter)) + { + iter = pointList.erase(iter); + //pointList.erase(iter++); + }else + { + iter++; + } + } + } +} + +bool AlarmMng::conditionFilter(PointInfoPtr info,const QString &filter) +{ + if(info->m_desc.indexOf(filter) != -1) + { + return true; + } + if(m_locMap.value(info->m_loc,"").indexOf(filter) != -1) + { + return true; + } + if(m_devgMap.value(info->m_devg,"").indexOf(filter) != -1) + { + return true; + } + if(m_devMap.value(info->m_dev).indexOf(filter) != -1) + { + return true; + } + if(m_alarmLevelMap.value(info->m_priority,tr("未知")).indexOf(filter) != -1) + { + return true; + } + QString text; + int priority = info->m_priority; + if( priority < 0) + { + text = "-"; + }else + { + int act = m_alarmLevelActionMap.value(priority,0); + QMap::const_iterator it = m_alarmActionMap.cbegin(); + while (it != m_alarmActionMap.cend()) { + if(act>>(it.key()-1) & 0x0001) + { + text += QString("%2 ").arg(it.value()); + } + it++; + } + } + if(text.indexOf(filter) != -1) + { + return true; + } + return false; +} + +void AlarmMng::getAlarmObj(PointInfoPtr info) +{ + QSqlQuery query; + QString tableName = "analog_limit_info"; + QString sql = QString("select %1.is_obj_alm_manner,%1.alarm_priority from %1 where tag_name = '%2' ").arg(tableName).arg(info->m_tag); + if(m_pReadDb->execute(sql,query)) + { + while (query.next()) { + int is_obj = query.value(0).toInt(); + int priority = query.value(1).toInt(); + info->m_obj = is_obj; + info->m_priority = priority; + return ; + } + } + return ; +} + +//void AlarmMng::getAlarmShield(PointInfoPtr info) +//{ +// QSqlQuery query; +// QString sql = QString("select shield_id,key_id_tag from %1 where shield_object ='%2' limit 1").arg("opt_shield_obj").arg(info->m_tag); +// if(m_pReadDb->execute(sql,query)) +// { +// while (query.next()) { +// int shield_id =query.value(0).toInt(); +// QString key_id_tag = query.value(1).toString(); +// info->m_bShield = true; +// info->m_keyIdTag =key_id_tag; +// info->m_shieldId = shield_id; +// break; +// } +// } +// //查询屏蔽描述和时段 +// if(!info->m_bShield) +// { +// return ; +// } +// query.clear(); +// sql = QString("select shield_name,time_id from %1 where shield_id =%2 limit 1").arg("opt_shield_info").arg(info->m_shieldId); +// if(m_pReadDb->execute(sql,query)) +// { +// while (query.next()) { +// info->m_shieldDesc = query.value(0).toString(); +// int time_id =query.value(1).toInt(); +// info->m_timeId = time_id; +// break; +// } +// } +// if(info->m_timeId < 0) +// { +// return ; +// } +// query.clear(); +// sql = QString("select time_type,start_time,end_time,time_option from %1 where time_id = %2 limit 1").arg("opt_shield_time").arg(info->m_timeId); +// if(m_pReadDb->execute(sql,query)) +// { +// while (query.next()) { +// info->m_timeType = query.value(0).toInt(); +// info->m_startTime = query.value(1).toString(); +// info->m_endTime = query.value(2).toString(); +// info->m_timeOption = query.value(3).toInt(); +// break; +// } +// } +//} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmMng.h b/product/src/gui/plugin/AlarmManageWidget/AlarmMng.h index cf82fd86..208ff2fa 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmMng.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmMng.h @@ -1,153 +1,153 @@ -#ifndef ALARMMNG_H -#define ALARMMNG_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "PointInfo.h" -#include "AlarmManageCommon.h" - -#include "db_api_ex/CDbApi.h" -#include "AlarmCalcInfo.h" - - -class QMutex; - - -class AlarmMng :public QObject -{ - Q_OBJECT -public: - static AlarmMng * instance(); - void destory(); - - QMap getDevTpType(); - - QMap > > getDevTreeInfo(); - - QMap > getDevGroupTreeInfo(); - - QList getDevGroupInfo(int locId); - - QString getLocDescById(int locId); - - QString getDevgDescByTag(const QString &tag); - - QString getDevDescByTag(const QString &tag); - - QMap getDevInfo(); - - QMap getDevgInfo(); - - QMap getLocInfo(); - - QList getLocOrder(); - - QMap getDevType(); - - QMap getAlarmAction(); - - QMap getAlarmLevelAction(); - - QMap getAlarmLevel(); - - bool isDiObjAlarm(PointInfoPtr info, ST_OBJ_INFO &objInfo); - - bool isAiObjAlarm(PointInfoPtr info, ST_OBJ_INFO &objInfo,ST_LIMIT_INFO &limitInfo); - - QMap getUserInfo(); - - QMap getFuncInfo(); - - QMap > getCalcInfo(); - - QList getDevInfoByDevGroup(const QString devGroup); - - QList getDiText(); - - bool getNomRptEditPerm(); - -signals: - void addAiPoint(QList pointList); - - void addDiPoint(QList pointList); - -public slots: - - void slotSelectPoint(const QString &devg, const int index,const QString &filter); - -private: - AlarmMng(); - - void loadLocInfo(); - - void loadDevgInfo(); - - void loadDevInfo(); - - void loadDevType(); - - void loadAlarmAction(); - - void loadAlarmLevel(); - - void loadPointByDev(const QStringList &devList, const int index, const QString &filter); - - void loadAi(QList &pointList,const QStringList &devList); - - void loadDi(QList &pointList,const QStringList &devList); - - void loadPi(QList &pointList,const QStringList &devList); - - void loadUserInfo(); - - void loadFuncInfo(); - - void loadCalcInfo(); - - void loadDiText(); - - void filterPoint(QList &pointList,const QString &filter); - - bool conditionFilter(PointInfoPtr info, const QString &filter); - -private: - void getAlarmObj(PointInfoPtr info); - -private: - - QMutex * mutex; - static AlarmMng * pInstance; - - - kbd_dbms::CDbApi * m_pReadDb; - - kbd_dbms::CRdbAccess * m_rtdbAccess; - QMap m_locMap; //<车站ID,车站描述> - QMap m_devgMap; //<设备组标签,设备组描述> - QMap m_devMap; //<设备标签,设备描述> - QMap m_devTpTypeMap; //<类型名称,类型描述> - QMap m_devTypeMap; //<设备标签,设备类型> - QMap m_devTypeIdMap; //<设备标签,设备类型id> - QMap > > m_devTreeInfo; // <车站ID,<设备组标签,<设备标签>> - QMap > m_devgTreeInfo; // <车站ID,<设备组标签>> - QMap > m_devgDevMap; //<设备组标签 QList<设备标签> > - QMap m_devGlocIdMap; //<设备组标签,车站id> 生成点使用 - - QMap m_alarmActionMap; //告警动作 - - QMap m_alarmLevelActionMap; - QMap m_alarmLevelMap; - - QMap m_userInfo; - - QMap m_funcMap; //tag_name desc - - QMap > m_calcInfoMap; - - QList m_diTextList; - QList m_locOrder; //< location_id: 按location_no排序 - - -}; - -#endif // ALARMMNG_H +#ifndef ALARMMNG_H +#define ALARMMNG_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "PointInfo.h" +#include "AlarmManageCommon.h" + +#include "db_api_ex/CDbApi.h" +#include "AlarmCalcInfo.h" + + +class QMutex; + + +class AlarmMng :public QObject +{ + Q_OBJECT +public: + static AlarmMng * instance(); + void destory(); + + QMap getDevTpType(); + + QMap > > getDevTreeInfo(); + + QMap > getDevGroupTreeInfo(); + + QList getDevGroupInfo(int locId); + + QString getLocDescById(int locId); + + QString getDevgDescByTag(const QString &tag); + + QString getDevDescByTag(const QString &tag); + + QMap getDevInfo(); + + QMap getDevgInfo(); + + QMap getLocInfo(); + + QList getLocOrder(); + + QMap getDevType(); + + QMap getAlarmAction(); + + QMap getAlarmLevelAction(); + + QMap getAlarmLevel(); + + bool isDiObjAlarm(PointInfoPtr info, ST_OBJ_INFO &objInfo); + + bool isAiObjAlarm(PointInfoPtr info, ST_OBJ_INFO &objInfo,ST_LIMIT_INFO &limitInfo); + + QMap getUserInfo(); + + QMap getFuncInfo(); + + QMap > getCalcInfo(); + + QList getDevInfoByDevGroup(const QString devGroup); + + QList getDiText(); + + bool getNomRptEditPerm(); + +signals: + void addAiPoint(QList pointList); + + void addDiPoint(QList pointList); + +public slots: + + void slotSelectPoint(const QString &devg, const int index,const QString &filter); + +private: + AlarmMng(); + + void loadLocInfo(); + + void loadDevgInfo(); + + void loadDevInfo(); + + void loadDevType(); + + void loadAlarmAction(); + + void loadAlarmLevel(); + + void loadPointByDev(const QStringList &devList, const int index, const QString &filter); + + void loadAi(QList &pointList,const QStringList &devList); + + void loadDi(QList &pointList,const QStringList &devList); + + void loadPi(QList &pointList,const QStringList &devList); + + void loadUserInfo(); + + void loadFuncInfo(); + + void loadCalcInfo(); + + void loadDiText(); + + void filterPoint(QList &pointList,const QString &filter); + + bool conditionFilter(PointInfoPtr info, const QString &filter); + +private: + void getAlarmObj(PointInfoPtr info); + +private: + + QMutex * mutex; + static AlarmMng * pInstance; + + + kbd_dbms::CDbApi * m_pReadDb; + + kbd_dbms::CRdbAccess * m_rtdbAccess; + QMap m_locMap; //<车站ID,车站描述> + QMap m_devgMap; //<设备组标签,设备组描述> + QMap m_devMap; //<设备标签,设备描述> + QMap m_devTpTypeMap; //<类型名称,类型描述> + QMap m_devTypeMap; //<设备标签,设备类型> + QMap m_devTypeIdMap; //<设备标签,设备类型id> + QMap > > m_devTreeInfo; // <车站ID,<设备组标签,<设备标签>> + QMap > m_devgTreeInfo; // <车站ID,<设备组标签>> + QMap > m_devgDevMap; //<设备组标签 QList<设备标签> > + QMap m_devGlocIdMap; //<设备组标签,车站id> 生成点使用 + + QMap m_alarmActionMap; //告警动作 + + QMap m_alarmLevelActionMap; + QMap m_alarmLevelMap; + + QMap m_userInfo; + + QMap m_funcMap; //tag_name desc + + QMap > m_calcInfoMap; + + QList m_diTextList; + QList m_locOrder; //< location_id: 按location_no排序 + + +}; + +#endif // ALARMMNG_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableModel.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableModel.cpp index 377f7069..ae6363ba 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableModel.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableModel.cpp @@ -1,154 +1,154 @@ -#include "AlarmPointTableModel.h" -#include "AlarmMng.h" -#include - -AlarmPointTableModel::AlarmPointTableModel(QObject *parent,QTableView *view) - : m_view(view), - QAbstractTableModel(parent), - m_stFilter(QString()) -{ - m_header<getDevInfo(); - m_devg = AlarmMng::instance()->getDevgInfo(); - m_loc = AlarmMng::instance()->getLocInfo(); - m_act = AlarmMng::instance()->getAlarmAction(); - m_levelAct = AlarmMng::instance()->getAlarmLevelAction(); - m_levelMap = AlarmMng::instance()->getAlarmLevel(); -} - -QVariant AlarmPointTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(orientation == Qt::Horizontal && role == Qt::DisplayRole) - { - return QVariant(m_header.at(section)); - } - return QVariant(); -} - -int AlarmPointTableModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_listInfo.count(); -} - -int AlarmPointTableModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.count(); -} - -QVariant AlarmPointTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if(role == Qt::TextAlignmentRole) - { - if(index.column() == 5) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(Qt::AlignCenter); - } - }else if(role == Qt::DisplayRole) - { - switch (index.column()) - { - case 0 : - { - return m_listInfo.at(index.row())->m_desc; - } - case 1 : - { - return m_loc.value(m_listInfo.at(index.row())->m_loc); - } - case 2 : - { - return m_devg.value(m_listInfo.at(index.row())->m_devg); - } - case 3 : - { - return m_dev.value(m_listInfo.at(index.row())->m_dev); - } - case 4: - { - int priority = m_listInfo.at(index.row())->m_priority; - if( priority < 0) - { - return "-"; - } - return m_levelMap.value(m_listInfo.at(index.row())->m_priority,tr("未知")); - break; - } - case 5: - { - QString text; - int priority = m_listInfo.at(index.row())->m_priority; - if( priority < 0) - { - text = "-"; - }else - { - int act = m_levelAct.value(priority,0); - QMap::const_iterator it = m_act.cbegin(); - while (it != m_act.cend()) { - if(act>>(it.key()-1) & 0x0001) - { - text += QString("%2 ").arg(it.value()); - } - it++; - } - } - return text; - } - default: - return QVariant(); - } - } - - return QVariant(); -} - -Qt::ItemFlags AlarmPointTableModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - return Qt::ItemIsEnabled | Qt::ItemIsSelectable;; -} - -PointInfoPtr AlarmPointTableModel::getPointInfoByRow(int row) -{ - if(row>=m_listInfo.size()) - { - return NULL; - }else - { - return m_listInfo.at(row); - } -} - -void AlarmPointTableModel::addPoint(QList pointList) -{ - beginInsertRows(QModelIndex(), m_listInfo.size(), m_listInfo.size()+pointList.size()-1); - QList::iterator it =pointList.begin(); - while (it != pointList.end()) { - m_listInfo.append(*it); - it++; - } - endInsertRows(); -} - -void AlarmPointTableModel::slotClearPointTable() -{ - beginResetModel(); - m_listInfo.clear(); - endResetModel(); -} +#include "AlarmPointTableModel.h" +#include "AlarmMng.h" +#include + +AlarmPointTableModel::AlarmPointTableModel(QObject *parent,QTableView *view) + : m_view(view), + QAbstractTableModel(parent), + m_stFilter(QString()) +{ + m_header<getDevInfo(); + m_devg = AlarmMng::instance()->getDevgInfo(); + m_loc = AlarmMng::instance()->getLocInfo(); + m_act = AlarmMng::instance()->getAlarmAction(); + m_levelAct = AlarmMng::instance()->getAlarmLevelAction(); + m_levelMap = AlarmMng::instance()->getAlarmLevel(); +} + +QVariant AlarmPointTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +int AlarmPointTableModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_listInfo.count(); +} + +int AlarmPointTableModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.count(); +} + +QVariant AlarmPointTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if(role == Qt::TextAlignmentRole) + { + if(index.column() == 5) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(Qt::AlignCenter); + } + }else if(role == Qt::DisplayRole) + { + switch (index.column()) + { + case 0 : + { + return m_listInfo.at(index.row())->m_desc; + } + case 1 : + { + return m_loc.value(m_listInfo.at(index.row())->m_loc); + } + case 2 : + { + return m_devg.value(m_listInfo.at(index.row())->m_devg); + } + case 3 : + { + return m_dev.value(m_listInfo.at(index.row())->m_dev); + } + case 4: + { + int priority = m_listInfo.at(index.row())->m_priority; + if( priority < 0) + { + return "-"; + } + return m_levelMap.value(m_listInfo.at(index.row())->m_priority,tr("未知")); + break; + } + case 5: + { + QString text; + int priority = m_listInfo.at(index.row())->m_priority; + if( priority < 0) + { + text = "-"; + }else + { + int act = m_levelAct.value(priority,0); + QMap::const_iterator it = m_act.cbegin(); + while (it != m_act.cend()) { + if(act>>(it.key()-1) & 0x0001) + { + text += QString("%2 ").arg(it.value()); + } + it++; + } + } + return text; + } + default: + return QVariant(); + } + } + + return QVariant(); +} + +Qt::ItemFlags AlarmPointTableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable;; +} + +PointInfoPtr AlarmPointTableModel::getPointInfoByRow(int row) +{ + if(row>=m_listInfo.size()) + { + return NULL; + }else + { + return m_listInfo.at(row); + } +} + +void AlarmPointTableModel::addPoint(QList pointList) +{ + beginInsertRows(QModelIndex(), m_listInfo.size(), m_listInfo.size()+pointList.size()-1); + QList::iterator it =pointList.begin(); + while (it != pointList.end()) { + m_listInfo.append(*it); + it++; + } + endInsertRows(); +} + +void AlarmPointTableModel::slotClearPointTable() +{ + beginResetModel(); + m_listInfo.clear(); + endResetModel(); +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableModel.h b/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableModel.h index d93dc8be..f66f0b08 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableModel.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableModel.h @@ -1,50 +1,50 @@ -#ifndef ALARMPOINTTABLEMODEL_H -#define ALARMPOINTTABLEMODEL_H - -#include -#include "PointInfo.h" - -class QTableView; - -class AlarmPointTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit AlarmPointTableModel(QObject *parent = nullptr, QTableView *view = Q_NULLPTR); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - PointInfoPtr getPointInfoByRow(int row); - -public slots: - void addPoint(QList pointList); - - void slotClearPointTable(); - -private: - -private: - QTableView *m_view; - QStringList m_header; - QList m_listInfo; - QMap m_dev; - QMap m_devg; - QMap m_loc; - QMap m_act; //告警动作 - QMap m_levelAct; //告警优先级对应的告警动作 - QMap m_levelMap; - - QString m_stFilter; -}; - -#endif // ALARMPOINTTABLEMODEL_H +#ifndef ALARMPOINTTABLEMODEL_H +#define ALARMPOINTTABLEMODEL_H + +#include +#include "PointInfo.h" + +class QTableView; + +class AlarmPointTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit AlarmPointTableModel(QObject *parent = nullptr, QTableView *view = Q_NULLPTR); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + PointInfoPtr getPointInfoByRow(int row); + +public slots: + void addPoint(QList pointList); + + void slotClearPointTable(); + +private: + +private: + QTableView *m_view; + QStringList m_header; + QList m_listInfo; + QMap m_dev; + QMap m_devg; + QMap m_loc; + QMap m_act; //告警动作 + QMap m_levelAct; //告警优先级对应的告警动作 + QMap m_levelMap; + + QString m_stFilter; +}; + +#endif // ALARMPOINTTABLEMODEL_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableView.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableView.cpp index 8dda6dfb..6eebe83b 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableView.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableView.cpp @@ -1,26 +1,26 @@ -#include "AlarmPointTableView.h" -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -AlarmPointTableView::AlarmPointTableView(QWidget *parent) - :QTableView(parent) -{ - setAlternatingRowColors(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - horizontalHeader()->setStretchLastSection(true); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::MultiSelection); - setHorizontalScrollMode(ScrollPerPixel); -} - -void AlarmPointTableView::mouseReleaseEvent(QMouseEvent *event) -{ - if(event != NULL && event->button() == Qt::LeftButton ) - { - LOGDEBUG("鼠标左键释放!---------"); - emit sigBrushProperty(); - } - QAbstractItemView::event(event); -} +#include "AlarmPointTableView.h" +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +AlarmPointTableView::AlarmPointTableView(QWidget *parent) + :QTableView(parent) +{ + setAlternatingRowColors(true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + horizontalHeader()->setStretchLastSection(true); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::MultiSelection); + setHorizontalScrollMode(ScrollPerPixel); +} + +void AlarmPointTableView::mouseReleaseEvent(QMouseEvent *event) +{ + if(event != NULL && event->button() == Qt::LeftButton ) + { + LOGDEBUG("鼠标左键释放!---------"); + emit sigBrushProperty(); + } + QAbstractItemView::event(event); +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableView.h b/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableView.h index e4d48e99..85899a27 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableView.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmPointTableView.h @@ -1,18 +1,18 @@ -#ifndef ALARMPOINTTABLEVIEW_H -#define ALARMPOINTTABLEVIEW_H - -#include - -class AlarmPointTableView : public QTableView -{ - Q_OBJECT -public: - AlarmPointTableView(QWidget *parent = Q_NULLPTR); - -protected: - void mouseReleaseEvent(QMouseEvent *event); -signals: - void sigBrushProperty(); -}; - -#endif // ALARMPOINTTABLEVIEW_H +#ifndef ALARMPOINTTABLEVIEW_H +#define ALARMPOINTTABLEVIEW_H + +#include + +class AlarmPointTableView : public QTableView +{ + Q_OBJECT +public: + AlarmPointTableView(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *event); +signals: + void sigBrushProperty(); +}; + +#endif // ALARMPOINTTABLEVIEW_H diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmUuidBase64.cpp b/product/src/gui/plugin/AlarmManageWidget/AlarmUuidBase64.cpp index 360b8f1c..95e79356 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmUuidBase64.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmUuidBase64.cpp @@ -1,82 +1,82 @@ -#include "AlarmUuidBase64.h" -#include "boost/typeof/typeof.hpp" -#include "boost/algorithm/string/replace.hpp" - -#include "boost/chrono.hpp" - -#include "boost/uuid/random_generator.hpp" -#include "boost/unordered_map.hpp" - - -AlarmUuidBase64::AlarmUuidBase64() -{ - -} - -QString AlarmUuidBase64::generateUuidBase64() -{ - boost::uint8_t m_baUuid[18]; - boost::uint8_t m_baBase64[24]; - boost::uuids::detail::random_provider m_randomGen; - std::string strOut; - { - boost::uint64_t nNow = boost::chrono::time_point_cast( - boost::chrono::system_clock::now()).time_since_epoch().count(); - -#include "boost/predef/detail/endian_compat.h" - -#ifdef BOOST_LITTLE_ENDIAN - -#define Swap64(ll) (((ll) >> 56) |\ -(((ll) & 0x00ff000000000000) >> 40) |\ -(((ll) & 0x0000ff0000000000) >> 24) |\ -(((ll) & 0x000000ff00000000) >> 8) |\ -(((ll) & 0x00000000ff000000) << 8) |\ -(((ll) & 0x0000000000ff0000) << 24) |\ -(((ll) & 0x000000000000ff00) << 40) |\ -(((ll) << 56))) - - nNow = Swap64(nNow); -#endif - - memcpy(m_baUuid, ((boost::uint8_t *) &nNow) + 4, 4); - } - - //< 填充 12byte 随机数 - m_randomGen.get_random_bytes(&(m_baUuid[4]), 12); - - //< 最后填充 0 - m_baUuid[16] = 0; - m_baUuid[17] = 0; - - //< 编码为 base64 - { - //< 这是标准的base64编码方式,但原始值递增的情况下,输出字符串的ascii码不是递增的,对数据库索引效率可能略有影响 - //static const char *szBase64Array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - //< 这是自定义的,不是标准base64,以解决上述问题 - static const char *szBase64Array = "+/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - boost::uint8_t *pData = m_baUuid; - int nDestIndex = 0; - for (int i = 0; i < 18; i = i + 3) - { - boost::uint32_t nData = ((boost::uint32_t) *pData << 16) + - ((boost::uint32_t) *(pData + 1) << 8) + (*(pData + 2)); - m_baBase64[nDestIndex] = szBase64Array[nData >> 18]; - m_baBase64[nDestIndex + 1] = szBase64Array[nData >> 12 & (boost::uint32_t) 0x3f]; - m_baBase64[nDestIndex + 2] = szBase64Array[nData >> 6 & (boost::uint32_t) 0x3f]; - m_baBase64[nDestIndex + 3] = szBase64Array[nData & (boost::uint32_t) 0x3f]; - pData = pData + 3; - nDestIndex = nDestIndex + 4; - } - m_baBase64[22] = 0; - m_baBase64[23] = 0; - } - - //< 输出 - strOut.assign((const char *) m_baBase64, 22); - strOut.shrink_to_fit(); - - return QString::fromStdString(strOut); -} +#include "AlarmUuidBase64.h" +#include "boost/typeof/typeof.hpp" +#include "boost/algorithm/string/replace.hpp" + +#include "boost/chrono.hpp" + +#include "boost/uuid/random_generator.hpp" +#include "boost/unordered_map.hpp" + + +AlarmUuidBase64::AlarmUuidBase64() +{ + +} + +QString AlarmUuidBase64::generateUuidBase64() +{ + boost::uint8_t m_baUuid[18]; + boost::uint8_t m_baBase64[24]; + boost::uuids::detail::random_provider m_randomGen; + std::string strOut; + { + boost::uint64_t nNow = boost::chrono::time_point_cast( + boost::chrono::system_clock::now()).time_since_epoch().count(); + +#include "boost/predef/detail/endian_compat.h" + +#ifdef BOOST_LITTLE_ENDIAN + +#define Swap64(ll) (((ll) >> 56) |\ +(((ll) & 0x00ff000000000000) >> 40) |\ +(((ll) & 0x0000ff0000000000) >> 24) |\ +(((ll) & 0x000000ff00000000) >> 8) |\ +(((ll) & 0x00000000ff000000) << 8) |\ +(((ll) & 0x0000000000ff0000) << 24) |\ +(((ll) & 0x000000000000ff00) << 40) |\ +(((ll) << 56))) + + nNow = Swap64(nNow); +#endif + + memcpy(m_baUuid, ((boost::uint8_t *) &nNow) + 4, 4); + } + + //< 填充 12byte 随机数 + m_randomGen.get_random_bytes(&(m_baUuid[4]), 12); + + //< 最后填充 0 + m_baUuid[16] = 0; + m_baUuid[17] = 0; + + //< 编码为 base64 + { + //< 这是标准的base64编码方式,但原始值递增的情况下,输出字符串的ascii码不是递增的,对数据库索引效率可能略有影响 + //static const char *szBase64Array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + //< 这是自定义的,不是标准base64,以解决上述问题 + static const char *szBase64Array = "+/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + boost::uint8_t *pData = m_baUuid; + int nDestIndex = 0; + for (int i = 0; i < 18; i = i + 3) + { + boost::uint32_t nData = ((boost::uint32_t) *pData << 16) + + ((boost::uint32_t) *(pData + 1) << 8) + (*(pData + 2)); + m_baBase64[nDestIndex] = szBase64Array[nData >> 18]; + m_baBase64[nDestIndex + 1] = szBase64Array[nData >> 12 & (boost::uint32_t) 0x3f]; + m_baBase64[nDestIndex + 2] = szBase64Array[nData >> 6 & (boost::uint32_t) 0x3f]; + m_baBase64[nDestIndex + 3] = szBase64Array[nData & (boost::uint32_t) 0x3f]; + pData = pData + 3; + nDestIndex = nDestIndex + 4; + } + m_baBase64[22] = 0; + m_baBase64[23] = 0; + } + + //< 输出 + strOut.assign((const char *) m_baBase64, 22); + strOut.shrink_to_fit(); + + return QString::fromStdString(strOut); +} diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmUuidBase64.h b/product/src/gui/plugin/AlarmManageWidget/AlarmUuidBase64.h index b0b67c59..c626d30a 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmUuidBase64.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmUuidBase64.h @@ -1,15 +1,15 @@ -#ifndef ALARMUUIDBASE64_H -#define ALARMUUIDBASE64_H - -#include - -class AlarmUuidBase64 -{ -public: - AlarmUuidBase64(); - - QString generateUuidBase64(); - -}; - -#endif // ALARMUUIDBASE64_H +#ifndef ALARMUUIDBASE64_H +#define ALARMUUIDBASE64_H + +#include + +class AlarmUuidBase64 +{ +public: + AlarmUuidBase64(); + + QString generateUuidBase64(); + +}; + +#endif // ALARMUUIDBASE64_H diff --git a/product/src/gui/plugin/AlarmManageWidget/PointInfo.cpp b/product/src/gui/plugin/AlarmManageWidget/PointInfo.cpp index ec134eb6..e1ee3c5a 100644 --- a/product/src/gui/plugin/AlarmManageWidget/PointInfo.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/PointInfo.cpp @@ -1,28 +1,28 @@ -#include "PointInfo.h" - -PointInfo::PointInfo() -{ - //基本属性 - m_tag = QString(); - m_desc = QString(); - m_dev = QString(); - m_devg = QString(); - m_loc = -1; - m_sub = -1; - m_obj = 0; - m_type = EN_POINT_ANALOG; - m_priority = -1; -} - -PointInfo::PointInfo(const PointInfo &info) -{ - m_tag = info.m_tag; - m_desc = info.m_desc; - m_dev = info.m_dev; - m_devg = info.m_devg; - m_loc = info.m_loc; - m_sub = info.m_sub; - m_type = info.m_type; - m_obj = info.m_obj; - m_priority = info.m_priority; -} +#include "PointInfo.h" + +PointInfo::PointInfo() +{ + //基本属性 + m_tag = QString(); + m_desc = QString(); + m_dev = QString(); + m_devg = QString(); + m_loc = -1; + m_sub = -1; + m_obj = 0; + m_type = EN_POINT_ANALOG; + m_priority = -1; +} + +PointInfo::PointInfo(const PointInfo &info) +{ + m_tag = info.m_tag; + m_desc = info.m_desc; + m_dev = info.m_dev; + m_devg = info.m_devg; + m_loc = info.m_loc; + m_sub = info.m_sub; + m_type = info.m_type; + m_obj = info.m_obj; + m_priority = info.m_priority; +} diff --git a/product/src/gui/plugin/AlarmManageWidget/PointInfo.h b/product/src/gui/plugin/AlarmManageWidget/PointInfo.h index 9d248c6d..3b1ed5c9 100644 --- a/product/src/gui/plugin/AlarmManageWidget/PointInfo.h +++ b/product/src/gui/plugin/AlarmManageWidget/PointInfo.h @@ -1,37 +1,37 @@ -#ifndef POINTINFO_H -#define POINTINFO_H - -#include - -class PointInfo; -typedef QSharedPointer PointInfoPtr; -enum EN_POINT_TYPE -{ - EN_POINT_ANALOG = 0, - EN_POINT_DIGITAL, - EN_POINT_ACCUML, - EN_POINT_MIX -}; -class PointInfo -{ -public: - PointInfo(); - - PointInfo(const PointInfo &info); - - QString m_tag; - QString m_desc; - QString m_dev; - QString m_devg; - int m_loc; - int m_sub; - int m_obj; - EN_POINT_TYPE m_type; - - int m_priority; -}; - -Q_DECLARE_METATYPE(PointInfo) -Q_DECLARE_METATYPE(PointInfoPtr) - -#endif // POINTINFO_H +#ifndef POINTINFO_H +#define POINTINFO_H + +#include + +class PointInfo; +typedef QSharedPointer PointInfoPtr; +enum EN_POINT_TYPE +{ + EN_POINT_ANALOG = 0, + EN_POINT_DIGITAL, + EN_POINT_ACCUML, + EN_POINT_MIX +}; +class PointInfo +{ +public: + PointInfo(); + + PointInfo(const PointInfo &info); + + QString m_tag; + QString m_desc; + QString m_dev; + QString m_devg; + int m_loc; + int m_sub; + int m_obj; + EN_POINT_TYPE m_type; + + int m_priority; +}; + +Q_DECLARE_METATYPE(PointInfo) +Q_DECLARE_METATYPE(PointInfoPtr) + +#endif // POINTINFO_H diff --git a/product/src/gui/plugin/AlarmManageWidget/main.cpp b/product/src/gui/plugin/AlarmManageWidget/main.cpp index e35ef28f..25a22048 100644 --- a/product/src/gui/plugin/AlarmManageWidget/main.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/main.cpp @@ -1,37 +1,37 @@ -#include "AlarmManageForm.h" -#include -#include "pub_logger_api/logger.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "net_msg_bus_api/MsgBusApi.h" -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - - std::string name="admin"; - std::string password ="kbdct"; - kbd_public::StartLogSystem("HMI", "hmi"); - - kbd_net::initMsgBus("HMI", "HMI"); - - int group =1; - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin(name, password, group, 12*60*60, "hmi") != 0) - { - return -1; - } - { - AlarmManageForm w; - w.show(); - a.exec(); - } - kbd_net::releaseMsgBus(); - - kbd_public::StopLogSystem(); - - return 0; -} +#include "AlarmManageForm.h" +#include +#include "pub_logger_api/logger.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "net_msg_bus_api/MsgBusApi.h" +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + std::string name="admin"; + std::string password ="kbdct"; + kbd_public::StartLogSystem("HMI", "hmi"); + + kbd_net::initMsgBus("HMI", "HMI"); + + int group =1; + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin(name, password, group, 12*60*60, "hmi") != 0) + { + return -1; + } + { + AlarmManageForm w; + w.show(); + a.exec(); + } + kbd_net::releaseMsgBus(); + + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/AlarmShieldWidget.pro b/product/src/gui/plugin/AlarmShieldWidget/AlarmShieldWidget.pro index 750e21f6..cc7f4e24 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/AlarmShieldWidget.pro +++ b/product/src/gui/plugin/AlarmShieldWidget/AlarmShieldWidget.pro @@ -1,68 +1,68 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-01-06T08:51:31 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = AlarmShieldWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CAlarmShield.cpp \ - CDevTreeView.cpp \ - CDevTreeModel.cpp \ - CDbInfoManage.cpp \ - CShieldTableModel.cpp \ - CShieldTableDelegate.cpp \ - CHeaderView.cpp \ - CAddShieldDialog.cpp \ - CAlarmShieldPluginWidget.cpp - -HEADERS += \ - CAlarmShield.h \ - CDevTreeView.h \ - CDevTreeModel.h \ - CDbInfoManage.h \ - CShieldTableModel.h \ - CShieldinfo.h \ - CShieldTableDelegate.h \ - CHeaderView.h \ - CAddShieldDialog.h \ - CAlarmShieldPluginWidget.h - -FORMS += \ - CAlarmShield.ui \ - CAddShieldDialog.ui - -LIBS += -ldb_base_api \ - -ldb_api_ex \ - -lrdb_api \ - -lperm_mng_api \ - -lpub_sysinfo_api \ - -lpub_utility_api - -LIBS += -llog4cplus -lpub_logger_api - -exists($$PWD/../../../common.pri) { - include($$PWD/../../../common.pri) -}else { - error("FATAL error: connot find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-01-06T08:51:31 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = AlarmShieldWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CAlarmShield.cpp \ + CDevTreeView.cpp \ + CDevTreeModel.cpp \ + CDbInfoManage.cpp \ + CShieldTableModel.cpp \ + CShieldTableDelegate.cpp \ + CHeaderView.cpp \ + CAddShieldDialog.cpp \ + CAlarmShieldPluginWidget.cpp + +HEADERS += \ + CAlarmShield.h \ + CDevTreeView.h \ + CDevTreeModel.h \ + CDbInfoManage.h \ + CShieldTableModel.h \ + CShieldinfo.h \ + CShieldTableDelegate.h \ + CHeaderView.h \ + CAddShieldDialog.h \ + CAlarmShieldPluginWidget.h + +FORMS += \ + CAlarmShield.ui \ + CAddShieldDialog.ui + +LIBS += -ldb_base_api \ + -ldb_api_ex \ + -lrdb_api \ + -lperm_mng_api \ + -lpub_sysinfo_api \ + -lpub_utility_api + +LIBS += -llog4cplus -lpub_logger_api + +exists($$PWD/../../../common.pri) { + include($$PWD/../../../common.pri) +}else { + error("FATAL error: connot find common.pri") +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.cpp b/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.cpp index 0b0b1542..889c2aea 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.cpp @@ -1,549 +1,549 @@ -#include "CAddShieldDialog.h" -#include "ui_CAddShieldDialog.h" -#include "CDbInfoManage.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" -#include -#include - -CAddShieldDialog::CAddShieldDialog(QWidget *parent, bool add) : - QDialog(parent), - ui(new Ui::CAddShieldDialog), - m_pModel(Q_NULLPTR), - m_bAdd(add), - m_perm(true) -{ - ui->setupUi(this); - - initialize(); - if(!m_bAdd) - { - ui->label->hide(); - ui->m_objType->hide(); - ui->m_add->setText(tr("保存")); - setWindowTitle(tr("编辑告警屏蔽")); - } -} - -CAddShieldDialog::~CAddShieldDialog() -{ - if(m_pModel) - { - delete m_pModel; - } - m_pModel = NULL; - - delete ui; -} - -void CAddShieldDialog::setInfo(ST_Shield_Info &info, QList &objList) -{ - if(objList.length() <= 0) - { - return; - } - int type = CDbInfoManage::instance()->getTreeItemType(E_Shield_Mode(objList[0].m_shieldMode)); - int index = ui->m_objType->findData(type); - ui->m_objType->setCurrentIndex(index); - - foreach (ST_Shield_Obj obj, objList) { - m_editObjMap.insert(obj.m_shieldObject, obj.m_shieldMode); - m_shieldObjMap.insert(obj.m_shieldObject, obj.m_shieldMode); - emit sigUpdateTagCheckState(obj.m_shieldObject, true); - } - m_objPreInfo = info; - ui->m_objName->setText(info.m_shieldName); - int shieldIndex = ui->m_shieldType->findData(info.m_shieldType, Qt::UserRole); - if(shieldIndex >= 0) - { - ui->m_shieldType->setCurrentIndex(shieldIndex); - } - - int timeType = info.m_timeType; - int timeTypeIndex = ui->m_timeType->findData(info.m_timeType, Qt::UserRole); - if(timeTypeIndex >= 0) - { - ui->m_timeType->setCurrentIndex(timeTypeIndex); - } - - switch (timeType) { - case 1: - { - ui->m_startTime->setDateTime(QDateTime::fromString(info.m_startTime, "yyyy-MM-dd hh:mm:ss")); - ui->m_endTime->setDateTime(QDateTime::fromString(info.m_endTime, "yyyy-MM-dd hh:mm:ss")); - break; - } - case 2: - { - setWeekOption(info.m_timeOption); - ui->m_startTimeWeek->setDateTime(QDateTime::fromString(info.m_startTime, "hh:mm:ss")); - ui->m_endTimeWeek->setDateTime(QDateTime::fromString(info.m_endTime, "hh:mm:ss")); - break; - } - case 3: - { - setMonthOption(info.m_timeOption); - ui->m_startTimeMonth->setDateTime(QDateTime::fromString(info.m_startTime, "hh:mm:ss")); - ui->m_endTimeMonth->setDateTime(QDateTime::fromString(info.m_endTime, "hh:mm:ss")); - break; - } - default: - break; - } - - ui->m_description->setPlainText(info.m_shieldDesc); - - m_perm = permCheck(); -} - -void CAddShieldDialog::initialize() -{ - ui->m_check->hide(); - ui->m_objType->clear(); - ui->m_objType->addItem(tr("位置"), Item_Location_Type); - ui->m_objType->addItem(tr("设备组"), Item_DevGroup_Type); - ui->m_objType->addItem(tr("设备"), Item_Device_Type); - //< 服务不支持 -// ui->m_objType->addItem(tr("测点"), Item_Point_Type); - connect(ui->m_objType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotObjTypeChanged(int))); - - ui->m_objName->setMaxLength(64); - QHBoxLayout *hLayout = new QHBoxLayout(); - QMap proMap = CDbInfoManage::instance()->getShieldPropMap(); - QMap::const_iterator iter = proMap.constBegin(); - while (iter != proMap.constEnd()) - { - QCheckBox * checkBox = new QCheckBox(iter.value(), this); - checkBox->setCheckable(true); - checkBox->setEnabled(false); - hLayout->addWidget(checkBox); - m_shieldCheckBoxMap.insert(iter.key(), checkBox); - iter++; - } - hLayout->setMargin(0); - ui->m_shieldProp->setLayout(hLayout); - ui->m_shieldType->clear(); - QMap > shieldDefMap = CDbInfoManage::instance()->getShieldDefInfo(); - QMap >::const_iterator it = shieldDefMap.constBegin(); - for(; it != shieldDefMap.constEnd(); it++) - { - ui->m_shieldType->addItem(it.value().first, it.key()); - } - connect(ui->m_shieldType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotShieldTypeChanged(int))); - emit ui->m_shieldType->currentIndexChanged(0); - - ui->m_timeType->clear(); - ui->m_timeType->addItem(tr("一次性"), 1); - ui->m_timeType->addItem(tr("每周"), 2); - ui->m_timeType->addItem(tr("每月"), 3); - connect(ui->m_timeType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotTimeTypeChanged(int))); - ui->m_startTime->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); - ui->m_endTime->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); - ui->m_startTimeWeek->setDisplayFormat("hh:mm:ss"); - ui->m_endTimeWeek->setDisplayFormat("hh:mm:ss"); - ui->m_startTimeMonth->setDisplayFormat("hh:mm:ss"); - ui->m_endTimeMonth->setDisplayFormat("hh:mm:ss"); - ui->m_startTime->setDateTime(QDateTime::currentDateTime()); - ui->m_endTime->setDateTime(QDateTime::currentDateTime().addSecs(3600)); - ui->m_endTimeWeek->setTime(QTime(1,0)); - ui->m_endTimeMonth->setTime(QTime(1,0)); - ui->m_spinBox1->setMinimum(1); - ui->m_spinBox2->setMinimum(1); - ui->m_spinBox1->setMaximum(31); - ui->m_spinBox2->setMaximum(31); - ui->splitter->setStretchFactor(1, 2); - - m_pModel = new CDevTreeModel(this, ui->m_devTreeView, true); - ui->m_devTreeView->setModel(m_pModel); - ui->m_devTreeView->setHeaderHidden(true); - ui->m_devTreeView->expandsOnDoubleClick(); - ui->m_devTreeView->expandAll(); - connect(this, SIGNAL(sigUpdateTagCheckState(QString,bool)), - m_pModel, SLOT(slotUpdateTagCheckState(QString,bool))); - connect(m_pModel, SIGNAL(sigCheck(QString,E_Tree_ItemType,int)), - this, SLOT(slotTreeCheck(QString,E_Tree_ItemType,int))); - emit ui->m_objType->currentIndexChanged(0); - - connect(ui->m_check, SIGNAL(toggled(bool)), this, SLOT(slotCheck(bool))); - connect(ui->m_add, SIGNAL(clicked()), this, SLOT(slotSaveShield())); - connect(ui->m_cancel, SIGNAL(clicked()), this, SLOT(slotCancel())); - connect(ui->m_filter, SIGNAL(textChanged(QString)), this, SLOT(slotFilter(QString))); -} - -void CAddShieldDialog::slotObjTypeChanged(int index) -{ - m_editObjMap.clear(); - m_shieldObjMap.clear(); - E_Tree_ItemType type = E_Tree_ItemType(ui->m_objType->itemData(index).toInt()); - m_pModel->updateTree(type); - ui->m_devTreeView->expandAll(); - ui->m_check->setChecked(false); - ui->m_check->show(); - ui->m_filter->clear(); -} - -void CAddShieldDialog::slotShieldTypeChanged(int index) -{ - int id = ui->m_shieldType->itemData(index).toInt(); - int value = CDbInfoManage::instance()->getShieldProp(id); - QMap::const_iterator iter = m_shieldCheckBoxMap.constBegin(); - for(; iter != m_shieldCheckBoxMap.constEnd(); iter++) - { - iter.value()->setChecked(false); - if(value & 1<setChecked(true); - } - } -} - -void CAddShieldDialog::slotTimeTypeChanged(int index) -{ - ui->stackedWidget->setCurrentIndex(index); -} - -void CAddShieldDialog::slotCheck(bool checked) -{ - ui->m_filter->blockSignals(true); - ui->m_filter->clear(); - ui->m_filter->blockSignals(false); - ui->m_devTreeView->setShowCheckedOnly(checked); -} - -void CAddShieldDialog::slotSaveShield() -{ - if(m_objPreInfo.m_shieldEnable == Shiled_Enable) - { - qint64 endTime = QDateTime::fromString(m_objPreInfo.m_endTime, "yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); - qint64 curTime = QDateTime::currentMSecsSinceEpoch(); - if(endTime >= curTime) - { - showMessage(tr("请先取消屏蔽!")); - return; - } - } - if(m_shieldObjMap.isEmpty()) - { - showMessage(tr("请至少勾选一项!")); - return; - } - if(m_perm == false || permCheck() == false) - { - showMessage(tr("当前用户无标签设置功能权限!")); - return; - } - QString shieldName = ui->m_objName->text(); - if(shieldName.isEmpty()) - { - showMessage(tr("对象名称不能为空!")); - return; - } - int shieldType = ui->m_shieldType->currentData().toInt(); - if(ui->m_shieldType->currentIndex() < 0) - { - showMessage(tr("屏蔽类型为空!")); - return; - } - int timeType = ui->m_timeType->currentData().toInt(); - if(ui->m_timeType->currentIndex() < 0) - { - showMessage(tr("时段类型为空!")); - return; - } - QString startTime; - QString endTime; - qint64 nStartTime; - qint64 nEndTime; - int timeOption = 0; - switch (timeType) { - case 1: - { - startTime = ui->m_startTime->text(); - endTime = ui->m_endTime->text(); - nStartTime = ui->m_startTime->dateTime().toMSecsSinceEpoch(); - nEndTime = ui->m_endTime->dateTime().toMSecsSinceEpoch(); - break; - } - case 2: - { - startTime = ui->m_startTimeWeek->text(); - endTime = ui->m_endTimeWeek->text(); - nStartTime = ui->m_startTimeWeek->dateTime().toMSecsSinceEpoch(); - nEndTime = ui->m_endTimeWeek->dateTime().toMSecsSinceEpoch(); - timeOption = getWeekOption(); - break; - } - case 3: - { - startTime = ui->m_startTimeMonth->text(); - endTime = ui->m_endTimeMonth->text(); - nStartTime = ui->m_startTimeMonth->dateTime().toMSecsSinceEpoch(); - nEndTime = ui->m_endTimeMonth->dateTime().toMSecsSinceEpoch(); - timeOption = getMonthOption(); - break; - } - default: - break; - } - if(nStartTime >= nEndTime) - { - showMessage(tr("开始时间不能大于结束时间!")); - return; - } - if(timeType == 2 - && !ui->m_checkBox1->isChecked() - && !ui->m_checkBox2->isChecked() - && !ui->m_checkBox3->isChecked() - && !ui->m_checkBox4->isChecked() - && !ui->m_checkBox5->isChecked() - && !ui->m_checkBox6->isChecked() - && !ui->m_checkBox7->isChecked()) - { - showMessage(tr("周一到周七至少需要选择一天!")); - return; - } - QString shieldDesc = ui->m_description->toPlainText(); - int userId; - int usergId; - QString hostName; - int locationId; - if(!getCurUser(userId, usergId, hostName, locationId)) - { - showMessage(tr("获取当前登录用户失败!")); - return; - } - - ST_Shield_Info info; - info.m_shieldName = shieldName; - info.m_shieldType = shieldType; - info.m_shieldStatus = 0; - info.m_shieldEnable = m_bAdd ? Shiled_Enable : m_objPreInfo.m_shieldEnable;; - info.m_location = locationId; - info.m_subsystem = 4; - info.m_shieldTime = QDateTime::currentSecsSinceEpoch(); - info.m_hostName = hostName; - info.m_userId = userId; - info.m_usergId = usergId; - info.m_shieldDesc = shieldDesc; - info.m_timeType = timeType; - info.m_startTime = startTime; - info.m_endTime = endTime; - info.m_timeOption = timeOption; - info.m_shieldId = m_objPreInfo.m_shieldId; - info.m_timeId = m_objPreInfo.m_timeId; - - bool isSuccess; - if(m_bAdd) - { - isSuccess = CDbInfoManage::instance()->insertShield(info, m_shieldObjMap); - } - else - { - isSuccess = CDbInfoManage::instance()->updateShield(info, m_editObjMap, m_shieldObjMap); - } - - if(!isSuccess) - { - showMessage(tr("保存失败!")); - } - else - { - accept(); - } -} - -void CAddShieldDialog::slotCancel() -{ - reject(); -} - -void CAddShieldDialog::slotTreeCheck(const QString &objTag, const E_Tree_ItemType &type, const int &checkState) -{ - if(checkState == Qt::Checked) - { - m_shieldObjMap.insert(objTag, CDbInfoManage::instance()->getShieldMode(type)); - } - else - { - m_shieldObjMap.remove(objTag); - } -} - -void CAddShieldDialog::slotFilter(const QString &text) -{ - ui->m_check->blockSignals(true); - ui->m_check->setChecked(false); - ui->m_check->blockSignals(false); - ui->m_devTreeView->filter(text); -} - -void CAddShieldDialog::showMessage(const QString &text) -{ - QMessageBox::information(this, tr("提示"), text, QMessageBox::Ok); -} - -void CAddShieldDialog::setWeekOption(int option) -{ - ui->m_checkBox1->setChecked(false); - if(option & (int)pow(2,0)) - { - ui->m_checkBox1->setChecked(true); - } - ui->m_checkBox2->setChecked(false); - if(option & (int)pow(2,1)) - { - ui->m_checkBox2->setChecked(true); - } - ui->m_checkBox3->setChecked(false); - if(option & (int)pow(2,2)) - { - ui->m_checkBox3->setChecked(true); - } - ui->m_checkBox4->setChecked(false); - if(option & (int)pow(2,3)) - { - ui->m_checkBox4->setChecked(true); - } - ui->m_checkBox5->setChecked(false); - if(option & (int)pow(2,4)) - { - ui->m_checkBox5->setChecked(true); - } - ui->m_checkBox6->setChecked(false); - if(option & (int)pow(2,5)) - { - ui->m_checkBox6->setChecked(true); - } - ui->m_checkBox7->setChecked(false); - if(option & (int)pow(2,6)) - { - ui->m_checkBox7->setChecked(true); - } -} - -void CAddShieldDialog::setMonthOption(int option) -{ - int first = 0; - int end = 0; - for(int index(1);index<32;index++) - { - if(option & (int)pow(2,index-1)) - { - if(first == 0) - { - first = index; - } - end = index; - } - } - if(first == 0) - { - first = 1; - } - if(end == 0) - { - end = 1; - } - ui->m_spinBox1->setValue(first); - ui->m_spinBox2->setValue(end); -} - -int CAddShieldDialog::getWeekOption() -{ - int option = 0; - if(ui->m_checkBox1->isChecked()) - { - option += 1; - } - if(ui->m_checkBox2->isChecked()) - { - option += 2; - } - if(ui->m_checkBox3->isChecked()) - { - option += 4; - } - if(ui->m_checkBox4->isChecked()) - { - option += 8; - } - if(ui->m_checkBox5->isChecked()) - { - option += 16; - } - if(ui->m_checkBox6->isChecked()) - { - option += 32; - } - if(ui->m_checkBox7->isChecked()) - { - option += 64; - } - return option; -} - -int CAddShieldDialog::getMonthOption() -{ - int option = 0; - int startDay = ui->m_spinBox1->value(); - - int endDay = ui->m_spinBox2->value(); - for(int index(startDay);indexPermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - - int level; - int loginSec; - std::string name; - - if(permMngPtr->CurUser(userId, usergId, level, loginSec, name) < 0) - { - LOGERROR("获取当前登录用户失败!"); - return false; - } - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return false; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - hostName = QString::fromStdString(stNodeInfo.strName); - locationId = stNodeInfo.nLocationId; - return true; -} - -bool CAddShieldDialog::permCheck() -{ - std::vector vecRegionOptId; - std::vector vecLocationOptId; - QMap::const_iterator iter = m_shieldObjMap.constBegin(); - for(; iter != m_shieldObjMap.constEnd(); iter++) - { - if(iter.value() == Shield_Location) - { - vecLocationOptId.push_back(iter.key().toInt()); - } - else if(iter.value() >= Shield_DevGroup) - { - vecRegionOptId.push_back(CDbInfoManage::instance()->getRegionId(iter.key())); - vecLocationOptId.push_back(CDbInfoManage::instance()->getLocationId(iter.key().section(".",0,0))); - } - } - bool perm = CDbInfoManage::instance()->checkOptPerm(vecRegionOptId, vecLocationOptId); - return perm; -} +#include "CAddShieldDialog.h" +#include "ui_CAddShieldDialog.h" +#include "CDbInfoManage.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include +#include + +CAddShieldDialog::CAddShieldDialog(QWidget *parent, bool add) : + QDialog(parent), + ui(new Ui::CAddShieldDialog), + m_pModel(Q_NULLPTR), + m_bAdd(add), + m_perm(true) +{ + ui->setupUi(this); + + initialize(); + if(!m_bAdd) + { + ui->label->hide(); + ui->m_objType->hide(); + ui->m_add->setText(tr("保存")); + setWindowTitle(tr("编辑告警屏蔽")); + } +} + +CAddShieldDialog::~CAddShieldDialog() +{ + if(m_pModel) + { + delete m_pModel; + } + m_pModel = NULL; + + delete ui; +} + +void CAddShieldDialog::setInfo(ST_Shield_Info &info, QList &objList) +{ + if(objList.length() <= 0) + { + return; + } + int type = CDbInfoManage::instance()->getTreeItemType(E_Shield_Mode(objList[0].m_shieldMode)); + int index = ui->m_objType->findData(type); + ui->m_objType->setCurrentIndex(index); + + foreach (ST_Shield_Obj obj, objList) { + m_editObjMap.insert(obj.m_shieldObject, obj.m_shieldMode); + m_shieldObjMap.insert(obj.m_shieldObject, obj.m_shieldMode); + emit sigUpdateTagCheckState(obj.m_shieldObject, true); + } + m_objPreInfo = info; + ui->m_objName->setText(info.m_shieldName); + int shieldIndex = ui->m_shieldType->findData(info.m_shieldType, Qt::UserRole); + if(shieldIndex >= 0) + { + ui->m_shieldType->setCurrentIndex(shieldIndex); + } + + int timeType = info.m_timeType; + int timeTypeIndex = ui->m_timeType->findData(info.m_timeType, Qt::UserRole); + if(timeTypeIndex >= 0) + { + ui->m_timeType->setCurrentIndex(timeTypeIndex); + } + + switch (timeType) { + case 1: + { + ui->m_startTime->setDateTime(QDateTime::fromString(info.m_startTime, "yyyy-MM-dd hh:mm:ss")); + ui->m_endTime->setDateTime(QDateTime::fromString(info.m_endTime, "yyyy-MM-dd hh:mm:ss")); + break; + } + case 2: + { + setWeekOption(info.m_timeOption); + ui->m_startTimeWeek->setDateTime(QDateTime::fromString(info.m_startTime, "hh:mm:ss")); + ui->m_endTimeWeek->setDateTime(QDateTime::fromString(info.m_endTime, "hh:mm:ss")); + break; + } + case 3: + { + setMonthOption(info.m_timeOption); + ui->m_startTimeMonth->setDateTime(QDateTime::fromString(info.m_startTime, "hh:mm:ss")); + ui->m_endTimeMonth->setDateTime(QDateTime::fromString(info.m_endTime, "hh:mm:ss")); + break; + } + default: + break; + } + + ui->m_description->setPlainText(info.m_shieldDesc); + + m_perm = permCheck(); +} + +void CAddShieldDialog::initialize() +{ + ui->m_check->hide(); + ui->m_objType->clear(); + ui->m_objType->addItem(tr("位置"), Item_Location_Type); + ui->m_objType->addItem(tr("设备组"), Item_DevGroup_Type); + ui->m_objType->addItem(tr("设备"), Item_Device_Type); + //< 服务不支持 +// ui->m_objType->addItem(tr("测点"), Item_Point_Type); + connect(ui->m_objType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotObjTypeChanged(int))); + + ui->m_objName->setMaxLength(64); + QHBoxLayout *hLayout = new QHBoxLayout(); + QMap proMap = CDbInfoManage::instance()->getShieldPropMap(); + QMap::const_iterator iter = proMap.constBegin(); + while (iter != proMap.constEnd()) + { + QCheckBox * checkBox = new QCheckBox(iter.value(), this); + checkBox->setCheckable(true); + checkBox->setEnabled(false); + hLayout->addWidget(checkBox); + m_shieldCheckBoxMap.insert(iter.key(), checkBox); + iter++; + } + hLayout->setMargin(0); + ui->m_shieldProp->setLayout(hLayout); + ui->m_shieldType->clear(); + QMap > shieldDefMap = CDbInfoManage::instance()->getShieldDefInfo(); + QMap >::const_iterator it = shieldDefMap.constBegin(); + for(; it != shieldDefMap.constEnd(); it++) + { + ui->m_shieldType->addItem(it.value().first, it.key()); + } + connect(ui->m_shieldType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotShieldTypeChanged(int))); + emit ui->m_shieldType->currentIndexChanged(0); + + ui->m_timeType->clear(); + ui->m_timeType->addItem(tr("一次性"), 1); + ui->m_timeType->addItem(tr("每周"), 2); + ui->m_timeType->addItem(tr("每月"), 3); + connect(ui->m_timeType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotTimeTypeChanged(int))); + ui->m_startTime->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); + ui->m_endTime->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); + ui->m_startTimeWeek->setDisplayFormat("hh:mm:ss"); + ui->m_endTimeWeek->setDisplayFormat("hh:mm:ss"); + ui->m_startTimeMonth->setDisplayFormat("hh:mm:ss"); + ui->m_endTimeMonth->setDisplayFormat("hh:mm:ss"); + ui->m_startTime->setDateTime(QDateTime::currentDateTime()); + ui->m_endTime->setDateTime(QDateTime::currentDateTime().addSecs(3600)); + ui->m_endTimeWeek->setTime(QTime(1,0)); + ui->m_endTimeMonth->setTime(QTime(1,0)); + ui->m_spinBox1->setMinimum(1); + ui->m_spinBox2->setMinimum(1); + ui->m_spinBox1->setMaximum(31); + ui->m_spinBox2->setMaximum(31); + ui->splitter->setStretchFactor(1, 2); + + m_pModel = new CDevTreeModel(this, ui->m_devTreeView, true); + ui->m_devTreeView->setModel(m_pModel); + ui->m_devTreeView->setHeaderHidden(true); + ui->m_devTreeView->expandsOnDoubleClick(); + ui->m_devTreeView->expandAll(); + connect(this, SIGNAL(sigUpdateTagCheckState(QString,bool)), + m_pModel, SLOT(slotUpdateTagCheckState(QString,bool))); + connect(m_pModel, SIGNAL(sigCheck(QString,E_Tree_ItemType,int)), + this, SLOT(slotTreeCheck(QString,E_Tree_ItemType,int))); + emit ui->m_objType->currentIndexChanged(0); + + connect(ui->m_check, SIGNAL(toggled(bool)), this, SLOT(slotCheck(bool))); + connect(ui->m_add, SIGNAL(clicked()), this, SLOT(slotSaveShield())); + connect(ui->m_cancel, SIGNAL(clicked()), this, SLOT(slotCancel())); + connect(ui->m_filter, SIGNAL(textChanged(QString)), this, SLOT(slotFilter(QString))); +} + +void CAddShieldDialog::slotObjTypeChanged(int index) +{ + m_editObjMap.clear(); + m_shieldObjMap.clear(); + E_Tree_ItemType type = E_Tree_ItemType(ui->m_objType->itemData(index).toInt()); + m_pModel->updateTree(type); + ui->m_devTreeView->expandAll(); + ui->m_check->setChecked(false); + ui->m_check->show(); + ui->m_filter->clear(); +} + +void CAddShieldDialog::slotShieldTypeChanged(int index) +{ + int id = ui->m_shieldType->itemData(index).toInt(); + int value = CDbInfoManage::instance()->getShieldProp(id); + QMap::const_iterator iter = m_shieldCheckBoxMap.constBegin(); + for(; iter != m_shieldCheckBoxMap.constEnd(); iter++) + { + iter.value()->setChecked(false); + if(value & 1<setChecked(true); + } + } +} + +void CAddShieldDialog::slotTimeTypeChanged(int index) +{ + ui->stackedWidget->setCurrentIndex(index); +} + +void CAddShieldDialog::slotCheck(bool checked) +{ + ui->m_filter->blockSignals(true); + ui->m_filter->clear(); + ui->m_filter->blockSignals(false); + ui->m_devTreeView->setShowCheckedOnly(checked); +} + +void CAddShieldDialog::slotSaveShield() +{ + if(m_objPreInfo.m_shieldEnable == Shiled_Enable) + { + qint64 endTime = QDateTime::fromString(m_objPreInfo.m_endTime, "yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); + qint64 curTime = QDateTime::currentMSecsSinceEpoch(); + if(endTime >= curTime) + { + showMessage(tr("请先取消屏蔽!")); + return; + } + } + if(m_shieldObjMap.isEmpty()) + { + showMessage(tr("请至少勾选一项!")); + return; + } + if(m_perm == false || permCheck() == false) + { + showMessage(tr("当前用户无标签设置功能权限!")); + return; + } + QString shieldName = ui->m_objName->text(); + if(shieldName.isEmpty()) + { + showMessage(tr("对象名称不能为空!")); + return; + } + int shieldType = ui->m_shieldType->currentData().toInt(); + if(ui->m_shieldType->currentIndex() < 0) + { + showMessage(tr("屏蔽类型为空!")); + return; + } + int timeType = ui->m_timeType->currentData().toInt(); + if(ui->m_timeType->currentIndex() < 0) + { + showMessage(tr("时段类型为空!")); + return; + } + QString startTime; + QString endTime; + qint64 nStartTime; + qint64 nEndTime; + int timeOption = 0; + switch (timeType) { + case 1: + { + startTime = ui->m_startTime->text(); + endTime = ui->m_endTime->text(); + nStartTime = ui->m_startTime->dateTime().toMSecsSinceEpoch(); + nEndTime = ui->m_endTime->dateTime().toMSecsSinceEpoch(); + break; + } + case 2: + { + startTime = ui->m_startTimeWeek->text(); + endTime = ui->m_endTimeWeek->text(); + nStartTime = ui->m_startTimeWeek->dateTime().toMSecsSinceEpoch(); + nEndTime = ui->m_endTimeWeek->dateTime().toMSecsSinceEpoch(); + timeOption = getWeekOption(); + break; + } + case 3: + { + startTime = ui->m_startTimeMonth->text(); + endTime = ui->m_endTimeMonth->text(); + nStartTime = ui->m_startTimeMonth->dateTime().toMSecsSinceEpoch(); + nEndTime = ui->m_endTimeMonth->dateTime().toMSecsSinceEpoch(); + timeOption = getMonthOption(); + break; + } + default: + break; + } + if(nStartTime >= nEndTime) + { + showMessage(tr("开始时间不能大于结束时间!")); + return; + } + if(timeType == 2 + && !ui->m_checkBox1->isChecked() + && !ui->m_checkBox2->isChecked() + && !ui->m_checkBox3->isChecked() + && !ui->m_checkBox4->isChecked() + && !ui->m_checkBox5->isChecked() + && !ui->m_checkBox6->isChecked() + && !ui->m_checkBox7->isChecked()) + { + showMessage(tr("周一到周七至少需要选择一天!")); + return; + } + QString shieldDesc = ui->m_description->toPlainText(); + int userId; + int usergId; + QString hostName; + int locationId; + if(!getCurUser(userId, usergId, hostName, locationId)) + { + showMessage(tr("获取当前登录用户失败!")); + return; + } + + ST_Shield_Info info; + info.m_shieldName = shieldName; + info.m_shieldType = shieldType; + info.m_shieldStatus = 0; + info.m_shieldEnable = m_bAdd ? Shiled_Enable : m_objPreInfo.m_shieldEnable;; + info.m_location = locationId; + info.m_subsystem = 4; + info.m_shieldTime = QDateTime::currentSecsSinceEpoch(); + info.m_hostName = hostName; + info.m_userId = userId; + info.m_usergId = usergId; + info.m_shieldDesc = shieldDesc; + info.m_timeType = timeType; + info.m_startTime = startTime; + info.m_endTime = endTime; + info.m_timeOption = timeOption; + info.m_shieldId = m_objPreInfo.m_shieldId; + info.m_timeId = m_objPreInfo.m_timeId; + + bool isSuccess; + if(m_bAdd) + { + isSuccess = CDbInfoManage::instance()->insertShield(info, m_shieldObjMap); + } + else + { + isSuccess = CDbInfoManage::instance()->updateShield(info, m_editObjMap, m_shieldObjMap); + } + + if(!isSuccess) + { + showMessage(tr("保存失败!")); + } + else + { + accept(); + } +} + +void CAddShieldDialog::slotCancel() +{ + reject(); +} + +void CAddShieldDialog::slotTreeCheck(const QString &objTag, const E_Tree_ItemType &type, const int &checkState) +{ + if(checkState == Qt::Checked) + { + m_shieldObjMap.insert(objTag, CDbInfoManage::instance()->getShieldMode(type)); + } + else + { + m_shieldObjMap.remove(objTag); + } +} + +void CAddShieldDialog::slotFilter(const QString &text) +{ + ui->m_check->blockSignals(true); + ui->m_check->setChecked(false); + ui->m_check->blockSignals(false); + ui->m_devTreeView->filter(text); +} + +void CAddShieldDialog::showMessage(const QString &text) +{ + QMessageBox::information(this, tr("提示"), text, QMessageBox::Ok); +} + +void CAddShieldDialog::setWeekOption(int option) +{ + ui->m_checkBox1->setChecked(false); + if(option & (int)pow(2,0)) + { + ui->m_checkBox1->setChecked(true); + } + ui->m_checkBox2->setChecked(false); + if(option & (int)pow(2,1)) + { + ui->m_checkBox2->setChecked(true); + } + ui->m_checkBox3->setChecked(false); + if(option & (int)pow(2,2)) + { + ui->m_checkBox3->setChecked(true); + } + ui->m_checkBox4->setChecked(false); + if(option & (int)pow(2,3)) + { + ui->m_checkBox4->setChecked(true); + } + ui->m_checkBox5->setChecked(false); + if(option & (int)pow(2,4)) + { + ui->m_checkBox5->setChecked(true); + } + ui->m_checkBox6->setChecked(false); + if(option & (int)pow(2,5)) + { + ui->m_checkBox6->setChecked(true); + } + ui->m_checkBox7->setChecked(false); + if(option & (int)pow(2,6)) + { + ui->m_checkBox7->setChecked(true); + } +} + +void CAddShieldDialog::setMonthOption(int option) +{ + int first = 0; + int end = 0; + for(int index(1);index<32;index++) + { + if(option & (int)pow(2,index-1)) + { + if(first == 0) + { + first = index; + } + end = index; + } + } + if(first == 0) + { + first = 1; + } + if(end == 0) + { + end = 1; + } + ui->m_spinBox1->setValue(first); + ui->m_spinBox2->setValue(end); +} + +int CAddShieldDialog::getWeekOption() +{ + int option = 0; + if(ui->m_checkBox1->isChecked()) + { + option += 1; + } + if(ui->m_checkBox2->isChecked()) + { + option += 2; + } + if(ui->m_checkBox3->isChecked()) + { + option += 4; + } + if(ui->m_checkBox4->isChecked()) + { + option += 8; + } + if(ui->m_checkBox5->isChecked()) + { + option += 16; + } + if(ui->m_checkBox6->isChecked()) + { + option += 32; + } + if(ui->m_checkBox7->isChecked()) + { + option += 64; + } + return option; +} + +int CAddShieldDialog::getMonthOption() +{ + int option = 0; + int startDay = ui->m_spinBox1->value(); + + int endDay = ui->m_spinBox2->value(); + for(int index(startDay);indexPermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + + int level; + int loginSec; + std::string name; + + if(permMngPtr->CurUser(userId, usergId, level, loginSec, name) < 0) + { + LOGERROR("获取当前登录用户失败!"); + return false; + } + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + hostName = QString::fromStdString(stNodeInfo.strName); + locationId = stNodeInfo.nLocationId; + return true; +} + +bool CAddShieldDialog::permCheck() +{ + std::vector vecRegionOptId; + std::vector vecLocationOptId; + QMap::const_iterator iter = m_shieldObjMap.constBegin(); + for(; iter != m_shieldObjMap.constEnd(); iter++) + { + if(iter.value() == Shield_Location) + { + vecLocationOptId.push_back(iter.key().toInt()); + } + else if(iter.value() >= Shield_DevGroup) + { + vecRegionOptId.push_back(CDbInfoManage::instance()->getRegionId(iter.key())); + vecLocationOptId.push_back(CDbInfoManage::instance()->getLocationId(iter.key().section(".",0,0))); + } + } + bool perm = CDbInfoManage::instance()->checkOptPerm(vecRegionOptId, vecLocationOptId); + return perm; +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.h b/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.h index 6d59e200..f23daf2d 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.h @@ -1,58 +1,58 @@ -#ifndef CADDSHIELDDIALOG_H -#define CADDSHIELDDIALOG_H - -#include -#include "CDevTreeModel.h" - -namespace Ui { -class CAddShieldDialog; -} - -class QCheckBox; -class CAddShieldDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CAddShieldDialog(QWidget *parent = 0, bool add = true); - ~CAddShieldDialog(); - - void setInfo(ST_Shield_Info &info, QList &objList); - -signals: - void sigUpdateTagCheckState(const QString &tag, const bool &checked); - -private: - void initialize(); - -private slots: - void slotObjTypeChanged(int index); - void slotShieldTypeChanged(int index); - void slotTimeTypeChanged(int index); - void slotCheck(bool checked); - void slotSaveShield(); - void slotCancel(); - void slotTreeCheck(const QString &objTag, const E_Tree_ItemType &type, const int &checkState); - void slotFilter(const QString &text); - -private: - void showMessage(const QString &text); - void setWeekOption(int option); - void setMonthOption(int option); - int getWeekOption(); - int getMonthOption(); - bool getCurUser(int &userId, int &usergId, QString &hostName, int &locationId); - bool permCheck(); - -private: - Ui::CAddShieldDialog *ui; - QMap m_shieldCheckBoxMap; - CDevTreeModel *m_pModel; - QMap m_editObjMap; - QMap m_shieldObjMap; - bool m_bAdd; - bool m_perm; - ST_Shield_Info m_objPreInfo; -}; - -#endif // CADDSHIELDDIALOG_H +#ifndef CADDSHIELDDIALOG_H +#define CADDSHIELDDIALOG_H + +#include +#include "CDevTreeModel.h" + +namespace Ui { +class CAddShieldDialog; +} + +class QCheckBox; +class CAddShieldDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CAddShieldDialog(QWidget *parent = 0, bool add = true); + ~CAddShieldDialog(); + + void setInfo(ST_Shield_Info &info, QList &objList); + +signals: + void sigUpdateTagCheckState(const QString &tag, const bool &checked); + +private: + void initialize(); + +private slots: + void slotObjTypeChanged(int index); + void slotShieldTypeChanged(int index); + void slotTimeTypeChanged(int index); + void slotCheck(bool checked); + void slotSaveShield(); + void slotCancel(); + void slotTreeCheck(const QString &objTag, const E_Tree_ItemType &type, const int &checkState); + void slotFilter(const QString &text); + +private: + void showMessage(const QString &text); + void setWeekOption(int option); + void setMonthOption(int option); + int getWeekOption(); + int getMonthOption(); + bool getCurUser(int &userId, int &usergId, QString &hostName, int &locationId); + bool permCheck(); + +private: + Ui::CAddShieldDialog *ui; + QMap m_shieldCheckBoxMap; + CDevTreeModel *m_pModel; + QMap m_editObjMap; + QMap m_shieldObjMap; + bool m_bAdd; + bool m_perm; + ST_Shield_Info m_objPreInfo; +}; + +#endif // CADDSHIELDDIALOG_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.ui b/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.ui index d0eef18e..5361a51b 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.ui +++ b/product/src/gui/plugin/AlarmShieldWidget/CAddShieldDialog.ui @@ -1,575 +1,575 @@ - - - CAddShieldDialog - - - - 0 - 0 - 720 - 489 - - - - 新增告警屏蔽 - - - - 6 - - - 6 - - - 6 - - - 6 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - - - - - - - 对象类型 - - - - - - - 6 - - - 6 - - - 3 - - - 3 - - - - - 显示勾选项 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 关键字过滤 - - - - - - - - - - - - 6 - - - - - - - 对象名称 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - - - 屏蔽类型 - - - - - - - - - - Qt::Horizontal - - - - 151 - 20 - - - - - - - - 名称 - - - - - - - - 0 - 16 - - - - - - - - - - - - - - - - - - 时段类型 - - - - - - - Qt::Horizontal - - - - 348 - 20 - - - - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - 时段类型 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - 结束时间 - - - - - - - - - - 开始时间 - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 开始时间 - - - - - - - 结束时间 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - 开始时间 - - - - - - - 日期 - - - - - - - 结束时间 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - - - - - - - - - 屏蔽描述 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Horizontal - - - - 217 - 20 - - - - - - - - - - 新增 - - - - - - - 取消 - - - - - - - - - - - - - - - - - CDevTreeView - QTreeView -
CDevTreeView.h
-
-
- - -
+ + + CAddShieldDialog + + + + 0 + 0 + 720 + 489 + + + + 新增告警屏蔽 + + + + 6 + + + 6 + + + 6 + + + 6 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + + + + + + + 对象类型 + + + + + + + 6 + + + 6 + + + 3 + + + 3 + + + + + 显示勾选项 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 关键字过滤 + + + + + + + + + + + + 6 + + + + + + + 对象名称 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + + + 屏蔽类型 + + + + + + + + + + Qt::Horizontal + + + + 151 + 20 + + + + + + + + 名称 + + + + + + + + 0 + 16 + + + + + + + + + + + + + + + + + + 时段类型 + + + + + + + Qt::Horizontal + + + + 348 + 20 + + + + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 时段类型 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + 结束时间 + + + + + + + + + + 开始时间 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 开始时间 + + + + + + + 结束时间 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + 开始时间 + + + + + + + 日期 + + + + + + + 结束时间 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + 屏蔽描述 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + + 217 + 20 + + + + + + + + + + 新增 + + + + + + + 取消 + + + + + + + + + + + + + + + + + CDevTreeView + QTreeView +
CDevTreeView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.cpp b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.cpp index f7cdbcf2..851856de 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.cpp @@ -1,390 +1,390 @@ -#include "CAlarmShield.h" -#include "ui_CAlarmShield.h" -#include "CDbInfoManage.h" -#include "CShieldTableDelegate.h" -#include "CHeaderView.h" -#include "CAddShieldDialog.h" -#include "pub_utility_api/FileStyle.h" -#include - -CAlarmShield::CAlarmShield(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CAlarmShield), - m_pDevTreeModel(Q_NULLPTR), - m_pTableModel(Q_NULLPTR), - m_pTableDelegate(Q_NULLPTR) -{ - ui->setupUi(this); - - initialize(editMode); - - if(!editMode) - { - QString style = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile file1(QString::fromStdString(strFullPath)); - if (file1.open(QIODevice::ReadOnly)) - { - QTextStream styleStream(&file1); - style += styleStream.readAll(); - //setStyleSheet(style); - } - file1.close(); - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarmShield.qss") ; - QFile file2(QString::fromStdString(strFullPath)); - if (file2.open(QIODevice::ReadOnly)) - { - QTextStream styleStream(&file2); - style += styleStream.readAll(); - //setStyleSheet(style); - } - file2.close(); - if(!style.isEmpty()) - { - setStyleSheet(style); - } - } -} - -CAlarmShield::~CAlarmShield() -{ - if(m_pDevTreeModel) - { - delete m_pDevTreeModel; - } - m_pDevTreeModel = NULL; - - if(m_pTableDelegate) - { - delete m_pTableDelegate; - } - m_pTableDelegate = NULL; - - if(m_pTableModel) - { - delete m_pTableModel; - } - m_pTableModel = NULL; - - CDbInfoManage::instance()->destory(); - - delete ui; -} - -QColor CAlarmShield::buttonBackground() -{ - return m_buttonBack; -} - -void CAlarmShield::setButtonBackground(const QColor &color) -{ - m_buttonBack = color; - - m_pTableDelegate->setButtonBackground(color); -} - -QColor CAlarmShield::buttonColor() -{ - return m_buttonColor; -} - -void CAlarmShield::setButtonColor(const QColor &color) -{ - m_buttonColor = color; - - m_pTableDelegate->setButtonColor(color); -} - -void CAlarmShield::setColumnWidth(int column, int width) -{ - if(ui->m_shieldTableView) - { - ui->m_shieldTableView->setColumnWidth(column, width); - } -} - -void CAlarmShield::reload() -{ - CDbInfoManage::instance()->destory(); - - if(m_pDevTreeModel) - { - m_pDevTreeModel->updateTree(); - ui->m_devTreeView->setCurrentIndex(m_pDevTreeModel->index(0,0)); - emit ui->m_devTreeView->clicked(m_pDevTreeModel->index(0,0)); - } -} - -void CAlarmShield::slotUpdateShieldTable(const QModelIndex &index) -{ - if(!index.isValid()) - { - return; - } - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item){ - QList > keyList; - getShieldObjTag(item, keyList); - m_pTableModel->reset(keyList); - ui->m_filterEdit->clear(); - ui->m_filterComb->setCurrentIndex(0); - emit ui->m_filter->click(); - emit ui->m_filterComb->currentIndexChanged(0); - } -} - -void CAlarmShield::slotFilterCombChanged(int index) -{ - ui->m_filterEdit->clear(); - int type = ui->m_filterComb->itemData(index, Qt::UserRole).toInt(); - QString desc = ui->m_filterComb->itemData(index, Qt::DisplayRole).toString(); - for (int nIndex = 0; nIndex < m_pTableModel->rowCount(); nIndex++) - { - if(type == -1) - { - ui->m_shieldTableView->setRowHidden(nIndex, false); - continue; - } - QString enable = m_pTableModel->data(m_pTableModel->index(nIndex, 5), Qt::DisplayRole).toString(); - if (enable != desc) - { - ui->m_shieldTableView->setRowHidden(nIndex, true); - } - else - { - ui->m_shieldTableView->setRowHidden(nIndex, false); - } - } -} - -void CAlarmShield::slotFilterTextChanged() -{ - QString text = ui->m_filterEdit->text(); - int type = ui->m_filterComb->itemData(ui->m_filterComb->currentIndex(), Qt::UserRole).toInt(); - QString desc = ui->m_filterComb->itemData(ui->m_filterComb->currentIndex(), Qt::DisplayRole).toString(); - for (int nIndex = 0; nIndex < m_pTableModel->rowCount(); nIndex++) - { - QString enable = m_pTableModel->data(m_pTableModel->index(nIndex, 5), Qt::DisplayRole).toString(); - QString name = m_pTableModel->data(m_pTableModel->index(nIndex, 1), Qt::DisplayRole).toString(); - if ((enable == desc || type == -1) && (text.isEmpty() || name.contains(text))) - { - ui->m_shieldTableView->setRowHidden(nIndex, false); - } - else - { - ui->m_shieldTableView->setRowHidden(nIndex, true); - } - } -} - -void CAlarmShield::slotShield() -{ - QList shieldIdList; - QList indexList; - QList &infoList = m_pTableModel->getInfoList(); -// qint64 curTime = QDateTime::currentMSecsSinceEpoch(); -// qint64 endTime; - for(int nIndex=0; nIndexmultiShield(shieldIdList)) - { - QMessageBox::information(this, tr("提示"), tr("屏蔽失败!")); - } - else - { - foreach (int index, indexList) { - infoList[index].m_shieldEnable = Shiled_Enable; - } - m_pTableModel->updateEnable(); - } -} - -void CAlarmShield::slotUnshield() -{ - QList shieldIdList; - QList indexList; - QList &infoList = m_pTableModel->getInfoList(); - for(int nIndex=0; nIndexmultiUnShield(shieldIdList)) - { - QMessageBox::information(this, tr("提示"), tr("解除失败!")); - } - else - { - foreach (int index, indexList) { - infoList[index].m_shieldEnable = Shiled_Disable; - } - m_pTableModel->updateEnable(); - } -} - -void CAlarmShield::slotDelete() -{ - QList timeIdList; - QList shieldIdList; - QList &infoList = m_pTableModel->getInfoList(); - foreach (ST_Shield_Info info, infoList) { - if(!info.m_check) - { - continue; - } - if(info.m_shieldEnable == Shiled_Enable) - { - QMessageBox::information(0, tr("提示"), tr("请先取消屏蔽!")); - return; - } - timeIdList.append(info.m_timeId); - shieldIdList.append(info.m_shieldId); - } - if(shieldIdList.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("请勾选一条屏蔽信息!")); - return; - } - if(!CDbInfoManage::instance()->multiDelShield(timeIdList, shieldIdList)) - { - QMessageBox::information(this, tr("提示"), tr("删除失败!")); - } - else - { - m_pTableModel->deleteShield(shieldIdList); - } -} - -void CAlarmShield::slotAddShield() -{ - CAddShieldDialog *dialog = new CAddShieldDialog(this); - - if(dialog->exec() == QDialog::Accepted) - { - emit ui->m_devTreeView->clicked(ui->m_devTreeView->currentIndex()); - } - - delete dialog; - dialog = NULL; -} - -void CAlarmShield::slotUpdateShield(const QModelIndex &index) -{ - ST_Shield_Info &info = m_pTableModel->getInfo(index.row()); - QList objList; - CDbInfoManage::instance()->loadShieldObj(info.m_shieldId, objList); - CAddShieldDialog *dialog = new CAddShieldDialog(this, false); - dialog->setInfo(info, objList); - if(dialog->exec() == QDialog::Accepted) - { - emit ui->m_devTreeView->clicked(ui->m_devTreeView->currentIndex()); - } - - delete dialog; - dialog = NULL; -} - -void CAlarmShield::initialize(bool editMode) -{ - m_pDevTreeModel = new CDevTreeModel(this, ui->m_devTreeView); - ui->m_devTreeView->setModel(m_pDevTreeModel); - //ui->m_devTreeView->setHeaderHidden(true); - ui->m_devTreeView->expandsOnDoubleClick(); - ui->m_devTreeView->expandAll(); - connect(ui->m_devTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(slotUpdateShieldTable(QModelIndex))); - - m_pTableModel = new CShieldTableModel(this); - ui->m_shieldTableView->setModel(m_pTableModel); - ui->m_shieldTableView->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->m_shieldTableView->setSelectionMode(QAbstractItemView::SingleSelection); - - CHeaderView * headerView = new CHeaderView(this); - ui->m_shieldTableView->setHorizontalHeader(headerView); - ui->m_shieldTableView->horizontalHeader()->setStretchLastSection(true); - ui->m_shieldTableView->setColumnWidth(COLUMN_CHECK, 20); - ui->m_shieldTableView->setColumnWidth(COLUMN_OPT, 140); - - m_pTableDelegate = new CShieldTableDelegate(m_pTableModel, this); - ui->m_shieldTableView->setItemDelegateForColumn(COLUMN_OPT, m_pTableDelegate); - connect(headerView, SIGNAL(sigColumnCheck(int,bool)), m_pTableModel, SLOT(slotColumnCheck(int,bool))); - connect(ui->m_devTreeView, SIGNAL(clicked(QModelIndex)), headerView, SLOT(clearCheck())); - - ui->m_filterComb->addItem(tr("全部"),"-1"); - ui->m_filterComb->addItem(tr("未启用"),"0"); - ui->m_filterComb->addItem(tr("已启用"),"1"); - ui->m_filterComb->addItem(tr("已过期"),"2"); - connect(ui->m_filterComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotFilterCombChanged(int))); - connect(ui->m_filter, SIGNAL(clicked()), this, SLOT(slotFilterTextChanged())); - connect(ui->m_shield, SIGNAL(clicked()), this, SLOT(slotShield())); - connect(ui->m_unshield, SIGNAL(clicked()), this, SLOT(slotUnshield())); - connect(ui->m_delete, SIGNAL(clicked()), this, SLOT(slotDelete())); - connect(ui->m_add, SIGNAL(clicked()), this, SLOT(slotAddShield())); - ui->m_shieldTableView->setEditTriggers(QAbstractItemView::DoubleClicked); - connect(ui->m_shieldTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotUpdateShield(QModelIndex))); - - ui->splitter->setStretchFactor(1, 2); - if(!editMode) - { - m_pDevTreeModel->updateTree(); - ui->m_devTreeView->setCurrentIndex(m_pDevTreeModel->index(0,0)); - emit ui->m_devTreeView->clicked(m_pDevTreeModel->index(0,0)); - } -} - -void CAlarmShield::getShieldObjTag(QTreeWidgetItem *item, QList > &keyList) -{ - QPair obj; - obj.first = CDbInfoManage::instance()->getShieldMode(E_Tree_ItemType(item->type())); - obj.second = item->data(0, Qt::UserRole).toString(); - if(obj.first != Shield_Invalid) - { - keyList.append(obj); - } - - int childCount = item->childCount(); - if(childCount <= 0) - { - return; - } - - for(int nIndex=0; nIndexchild(nIndex), keyList); - } -} +#include "CAlarmShield.h" +#include "ui_CAlarmShield.h" +#include "CDbInfoManage.h" +#include "CShieldTableDelegate.h" +#include "CHeaderView.h" +#include "CAddShieldDialog.h" +#include "pub_utility_api/FileStyle.h" +#include + +CAlarmShield::CAlarmShield(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CAlarmShield), + m_pDevTreeModel(Q_NULLPTR), + m_pTableModel(Q_NULLPTR), + m_pTableDelegate(Q_NULLPTR) +{ + ui->setupUi(this); + + initialize(editMode); + + if(!editMode) + { + QString style = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile file1(QString::fromStdString(strFullPath)); + if (file1.open(QIODevice::ReadOnly)) + { + QTextStream styleStream(&file1); + style += styleStream.readAll(); + //setStyleSheet(style); + } + file1.close(); + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarmShield.qss") ; + QFile file2(QString::fromStdString(strFullPath)); + if (file2.open(QIODevice::ReadOnly)) + { + QTextStream styleStream(&file2); + style += styleStream.readAll(); + //setStyleSheet(style); + } + file2.close(); + if(!style.isEmpty()) + { + setStyleSheet(style); + } + } +} + +CAlarmShield::~CAlarmShield() +{ + if(m_pDevTreeModel) + { + delete m_pDevTreeModel; + } + m_pDevTreeModel = NULL; + + if(m_pTableDelegate) + { + delete m_pTableDelegate; + } + m_pTableDelegate = NULL; + + if(m_pTableModel) + { + delete m_pTableModel; + } + m_pTableModel = NULL; + + CDbInfoManage::instance()->destory(); + + delete ui; +} + +QColor CAlarmShield::buttonBackground() +{ + return m_buttonBack; +} + +void CAlarmShield::setButtonBackground(const QColor &color) +{ + m_buttonBack = color; + + m_pTableDelegate->setButtonBackground(color); +} + +QColor CAlarmShield::buttonColor() +{ + return m_buttonColor; +} + +void CAlarmShield::setButtonColor(const QColor &color) +{ + m_buttonColor = color; + + m_pTableDelegate->setButtonColor(color); +} + +void CAlarmShield::setColumnWidth(int column, int width) +{ + if(ui->m_shieldTableView) + { + ui->m_shieldTableView->setColumnWidth(column, width); + } +} + +void CAlarmShield::reload() +{ + CDbInfoManage::instance()->destory(); + + if(m_pDevTreeModel) + { + m_pDevTreeModel->updateTree(); + ui->m_devTreeView->setCurrentIndex(m_pDevTreeModel->index(0,0)); + emit ui->m_devTreeView->clicked(m_pDevTreeModel->index(0,0)); + } +} + +void CAlarmShield::slotUpdateShieldTable(const QModelIndex &index) +{ + if(!index.isValid()) + { + return; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item){ + QList > keyList; + getShieldObjTag(item, keyList); + m_pTableModel->reset(keyList); + ui->m_filterEdit->clear(); + ui->m_filterComb->setCurrentIndex(0); + emit ui->m_filter->click(); + emit ui->m_filterComb->currentIndexChanged(0); + } +} + +void CAlarmShield::slotFilterCombChanged(int index) +{ + ui->m_filterEdit->clear(); + int type = ui->m_filterComb->itemData(index, Qt::UserRole).toInt(); + QString desc = ui->m_filterComb->itemData(index, Qt::DisplayRole).toString(); + for (int nIndex = 0; nIndex < m_pTableModel->rowCount(); nIndex++) + { + if(type == -1) + { + ui->m_shieldTableView->setRowHidden(nIndex, false); + continue; + } + QString enable = m_pTableModel->data(m_pTableModel->index(nIndex, 5), Qt::DisplayRole).toString(); + if (enable != desc) + { + ui->m_shieldTableView->setRowHidden(nIndex, true); + } + else + { + ui->m_shieldTableView->setRowHidden(nIndex, false); + } + } +} + +void CAlarmShield::slotFilterTextChanged() +{ + QString text = ui->m_filterEdit->text(); + int type = ui->m_filterComb->itemData(ui->m_filterComb->currentIndex(), Qt::UserRole).toInt(); + QString desc = ui->m_filterComb->itemData(ui->m_filterComb->currentIndex(), Qt::DisplayRole).toString(); + for (int nIndex = 0; nIndex < m_pTableModel->rowCount(); nIndex++) + { + QString enable = m_pTableModel->data(m_pTableModel->index(nIndex, 5), Qt::DisplayRole).toString(); + QString name = m_pTableModel->data(m_pTableModel->index(nIndex, 1), Qt::DisplayRole).toString(); + if ((enable == desc || type == -1) && (text.isEmpty() || name.contains(text))) + { + ui->m_shieldTableView->setRowHidden(nIndex, false); + } + else + { + ui->m_shieldTableView->setRowHidden(nIndex, true); + } + } +} + +void CAlarmShield::slotShield() +{ + QList shieldIdList; + QList indexList; + QList &infoList = m_pTableModel->getInfoList(); +// qint64 curTime = QDateTime::currentMSecsSinceEpoch(); +// qint64 endTime; + for(int nIndex=0; nIndexmultiShield(shieldIdList)) + { + QMessageBox::information(this, tr("提示"), tr("屏蔽失败!")); + } + else + { + foreach (int index, indexList) { + infoList[index].m_shieldEnable = Shiled_Enable; + } + m_pTableModel->updateEnable(); + } +} + +void CAlarmShield::slotUnshield() +{ + QList shieldIdList; + QList indexList; + QList &infoList = m_pTableModel->getInfoList(); + for(int nIndex=0; nIndexmultiUnShield(shieldIdList)) + { + QMessageBox::information(this, tr("提示"), tr("解除失败!")); + } + else + { + foreach (int index, indexList) { + infoList[index].m_shieldEnable = Shiled_Disable; + } + m_pTableModel->updateEnable(); + } +} + +void CAlarmShield::slotDelete() +{ + QList timeIdList; + QList shieldIdList; + QList &infoList = m_pTableModel->getInfoList(); + foreach (ST_Shield_Info info, infoList) { + if(!info.m_check) + { + continue; + } + if(info.m_shieldEnable == Shiled_Enable) + { + QMessageBox::information(0, tr("提示"), tr("请先取消屏蔽!")); + return; + } + timeIdList.append(info.m_timeId); + shieldIdList.append(info.m_shieldId); + } + if(shieldIdList.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("请勾选一条屏蔽信息!")); + return; + } + if(!CDbInfoManage::instance()->multiDelShield(timeIdList, shieldIdList)) + { + QMessageBox::information(this, tr("提示"), tr("删除失败!")); + } + else + { + m_pTableModel->deleteShield(shieldIdList); + } +} + +void CAlarmShield::slotAddShield() +{ + CAddShieldDialog *dialog = new CAddShieldDialog(this); + + if(dialog->exec() == QDialog::Accepted) + { + emit ui->m_devTreeView->clicked(ui->m_devTreeView->currentIndex()); + } + + delete dialog; + dialog = NULL; +} + +void CAlarmShield::slotUpdateShield(const QModelIndex &index) +{ + ST_Shield_Info &info = m_pTableModel->getInfo(index.row()); + QList objList; + CDbInfoManage::instance()->loadShieldObj(info.m_shieldId, objList); + CAddShieldDialog *dialog = new CAddShieldDialog(this, false); + dialog->setInfo(info, objList); + if(dialog->exec() == QDialog::Accepted) + { + emit ui->m_devTreeView->clicked(ui->m_devTreeView->currentIndex()); + } + + delete dialog; + dialog = NULL; +} + +void CAlarmShield::initialize(bool editMode) +{ + m_pDevTreeModel = new CDevTreeModel(this, ui->m_devTreeView); + ui->m_devTreeView->setModel(m_pDevTreeModel); + //ui->m_devTreeView->setHeaderHidden(true); + ui->m_devTreeView->expandsOnDoubleClick(); + ui->m_devTreeView->expandAll(); + connect(ui->m_devTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(slotUpdateShieldTable(QModelIndex))); + + m_pTableModel = new CShieldTableModel(this); + ui->m_shieldTableView->setModel(m_pTableModel); + ui->m_shieldTableView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->m_shieldTableView->setSelectionMode(QAbstractItemView::SingleSelection); + + CHeaderView * headerView = new CHeaderView(this); + ui->m_shieldTableView->setHorizontalHeader(headerView); + ui->m_shieldTableView->horizontalHeader()->setStretchLastSection(true); + ui->m_shieldTableView->setColumnWidth(COLUMN_CHECK, 20); + ui->m_shieldTableView->setColumnWidth(COLUMN_OPT, 140); + + m_pTableDelegate = new CShieldTableDelegate(m_pTableModel, this); + ui->m_shieldTableView->setItemDelegateForColumn(COLUMN_OPT, m_pTableDelegate); + connect(headerView, SIGNAL(sigColumnCheck(int,bool)), m_pTableModel, SLOT(slotColumnCheck(int,bool))); + connect(ui->m_devTreeView, SIGNAL(clicked(QModelIndex)), headerView, SLOT(clearCheck())); + + ui->m_filterComb->addItem(tr("全部"),"-1"); + ui->m_filterComb->addItem(tr("未启用"),"0"); + ui->m_filterComb->addItem(tr("已启用"),"1"); + ui->m_filterComb->addItem(tr("已过期"),"2"); + connect(ui->m_filterComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotFilterCombChanged(int))); + connect(ui->m_filter, SIGNAL(clicked()), this, SLOT(slotFilterTextChanged())); + connect(ui->m_shield, SIGNAL(clicked()), this, SLOT(slotShield())); + connect(ui->m_unshield, SIGNAL(clicked()), this, SLOT(slotUnshield())); + connect(ui->m_delete, SIGNAL(clicked()), this, SLOT(slotDelete())); + connect(ui->m_add, SIGNAL(clicked()), this, SLOT(slotAddShield())); + ui->m_shieldTableView->setEditTriggers(QAbstractItemView::DoubleClicked); + connect(ui->m_shieldTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotUpdateShield(QModelIndex))); + + ui->splitter->setStretchFactor(1, 2); + if(!editMode) + { + m_pDevTreeModel->updateTree(); + ui->m_devTreeView->setCurrentIndex(m_pDevTreeModel->index(0,0)); + emit ui->m_devTreeView->clicked(m_pDevTreeModel->index(0,0)); + } +} + +void CAlarmShield::getShieldObjTag(QTreeWidgetItem *item, QList > &keyList) +{ + QPair obj; + obj.first = CDbInfoManage::instance()->getShieldMode(E_Tree_ItemType(item->type())); + obj.second = item->data(0, Qt::UserRole).toString(); + if(obj.first != Shield_Invalid) + { + keyList.append(obj); + } + + int childCount = item->childCount(); + if(childCount <= 0) + { + return; + } + + for(int nIndex=0; nIndexchild(nIndex), keyList); + } +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.h b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.h index 85d66323..2496ba71 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.h @@ -1,56 +1,56 @@ -#ifndef CALARMSHIELD_H -#define CALARMSHIELD_H - -#include -#include -#include "CDevTreeModel.h" -#include "CShieldTableModel.h" -#include "CShieldTableDelegate.h" - -namespace Ui { -class CAlarmShield; -} - -class CAlarmShield : public QWidget -{ - Q_OBJECT - Q_PROPERTY(QColor buttonBackground READ buttonBackground WRITE setButtonBackground) - Q_PROPERTY(QColor buttonColor READ buttonColor WRITE setButtonColor) -public: - explicit CAlarmShield(QWidget *parent = 0, bool editMode = false); - ~CAlarmShield(); - - QColor buttonBackground(); - void setButtonBackground(const QColor &color); - - QColor buttonColor(); - void setButtonColor(const QColor &color); - -public slots: - void setColumnWidth(int column, int width); - void reload(); - -private slots: - void slotUpdateShieldTable(const QModelIndex &index); - void slotFilterCombChanged(int index); - void slotFilterTextChanged(); - void slotShield(); - void slotUnshield(); - void slotDelete(); - void slotAddShield(); - void slotUpdateShield(const QModelIndex &index); - -private: - void initialize(bool editMode = false); - void getShieldObjTag(QTreeWidgetItem *item, QList > &keyList); - -private: - Ui::CAlarmShield *ui; - CDevTreeModel *m_pDevTreeModel; - CShieldTableModel *m_pTableModel; - CShieldTableDelegate *m_pTableDelegate; - QColor m_buttonBack; - QColor m_buttonColor; -}; - -#endif // CALARMSHIELD_H +#ifndef CALARMSHIELD_H +#define CALARMSHIELD_H + +#include +#include +#include "CDevTreeModel.h" +#include "CShieldTableModel.h" +#include "CShieldTableDelegate.h" + +namespace Ui { +class CAlarmShield; +} + +class CAlarmShield : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor buttonBackground READ buttonBackground WRITE setButtonBackground) + Q_PROPERTY(QColor buttonColor READ buttonColor WRITE setButtonColor) +public: + explicit CAlarmShield(QWidget *parent = 0, bool editMode = false); + ~CAlarmShield(); + + QColor buttonBackground(); + void setButtonBackground(const QColor &color); + + QColor buttonColor(); + void setButtonColor(const QColor &color); + +public slots: + void setColumnWidth(int column, int width); + void reload(); + +private slots: + void slotUpdateShieldTable(const QModelIndex &index); + void slotFilterCombChanged(int index); + void slotFilterTextChanged(); + void slotShield(); + void slotUnshield(); + void slotDelete(); + void slotAddShield(); + void slotUpdateShield(const QModelIndex &index); + +private: + void initialize(bool editMode = false); + void getShieldObjTag(QTreeWidgetItem *item, QList > &keyList); + +private: + Ui::CAlarmShield *ui; + CDevTreeModel *m_pDevTreeModel; + CShieldTableModel *m_pTableModel; + CShieldTableDelegate *m_pTableDelegate; + QColor m_buttonBack; + QColor m_buttonColor; +}; + +#endif // CALARMSHIELD_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.ui b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.ui index 8cb64e31..afafd0ce 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.ui +++ b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShield.ui @@ -1,163 +1,163 @@ - - - CAlarmShield - - - - 0 - 0 - 1010 - 613 - - - - CAlarmShield - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 9 - - - 9 - - - 9 - - - 9 - - - 6 - - - - - Qt::Horizontal - - - - - - - - - - - - 3 - - - - - 6 - - - - - 新增 - - - - - - - 批量启用 - - - - - - - 批量取消 - - - - - - - 批量删除 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 屏蔽状态 - - - - - - - - - - 名称 - - - - - - - - - - 查询 - - - - - - - - - - - - - - - - - - - - - + + + CAlarmShield + + + + 0 + 0 + 1010 + 613 + + + + CAlarmShield + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + Qt::Horizontal + + + + + + + + + + + + 3 + + + + + 6 + + + + + 新增 + + + + + + + 批量启用 + + + + + + + 批量取消 + + + + + + + 批量删除 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 屏蔽状态 + + + + + + + + + + 名称 + + + + + + + + + + 查询 + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.cpp b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.cpp index eaa86c90..c65368bf 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.cpp @@ -1,28 +1,28 @@ -#include -#include "CAlarmShieldPluginWidget.h" -#include "CAlarmShield.h" - -CAlarmShieldPluginWidget::CAlarmShieldPluginWidget(QObject *parent) - : QObject(parent) -{ - -} - -CAlarmShieldPluginWidget::~CAlarmShieldPluginWidget() -{ - -} - -bool CAlarmShieldPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CAlarmShield *pWidget = new CAlarmShield(parent, editMode); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CAlarmShieldPluginWidget::release() -{ - -} +#include +#include "CAlarmShieldPluginWidget.h" +#include "CAlarmShield.h" + +CAlarmShieldPluginWidget::CAlarmShieldPluginWidget(QObject *parent) + : QObject(parent) +{ + +} + +CAlarmShieldPluginWidget::~CAlarmShieldPluginWidget() +{ + +} + +bool CAlarmShieldPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CAlarmShield *pWidget = new CAlarmShield(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CAlarmShieldPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.h b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.h index 513b9e16..6571d3e1 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CALARMSHIELDPLUGINWIDGET_H -#define CALARMSHIELDPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CAlarmShieldPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CAlarmShieldPluginWidget(QObject *parent = 0); - ~CAlarmShieldPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CALARMSHIELDPLUGINWIDGET_H +#ifndef CALARMSHIELDPLUGINWIDGET_H +#define CALARMSHIELDPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CAlarmShieldPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CAlarmShieldPluginWidget(QObject *parent = 0); + ~CAlarmShieldPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CALARMSHIELDPLUGINWIDGET_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CDbInfoManage.cpp b/product/src/gui/plugin/AlarmShieldWidget/CDbInfoManage.cpp index 2d548f62..2470f8bc 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CDbInfoManage.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CDbInfoManage.cpp @@ -1,1126 +1,1126 @@ -#include "CDbInfoManage.h" -#include "pub_logger_api/logger.h" -#include - -CDbInfoManage *CDbInfoManage::m_pInstance = NULL; - -CDbInfoManage *CDbInfoManage::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CDbInfoManage(); - } - return m_pInstance; -} - -void CDbInfoManage::destory() -{ - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - if(m_pWriteDb) - { - delete m_pWriteDb; - } - m_pWriteDb = NULL; - - m_regionMap.clear(); - m_locationInfo.clear(); - m_locationTag.clear(); - m_locationList.clear(); - m_devGroupInfo.clear(); - m_deviceInfo.clear(); - m_devTagName.clear(); - m_tagInfo.clear(); - m_userInfo.clear(); - m_vecRegionOptId.clear(); - m_vecLocationOptId.clear(); - m_shieldDefMap.clear(); - m_shieldPropertyMap.clear(); - m_pInstance = NULL; - delete this; -} - -QString CDbInfoManage::getLocationTag(const int &location) -{ - return m_locationTag.value(location, QString()); -} - -int CDbInfoManage::getLocationId(const QString &tag) -{ - QMap::const_iterator iter = m_locationTag.constBegin(); - while(iter != m_locationTag.constEnd()) - { - if(iter.value() == tag) - { - return iter.key(); - } - iter++; - } - return -1; -} - -QList CDbInfoManage::getLocationList() -{ - return m_locationList; -} - -QMap CDbInfoManage::getLocationInfo() -{ - return m_locationInfo; -} - -QString CDbInfoManage::getLocationDesc(const int &location) -{ - return m_locationInfo.value(location); -} - -QMap CDbInfoManage::getDevGroup(const int &location) -{ - return m_devGroupInfo.value(location, QMap()); -} - -QList > CDbInfoManage::getDevGroupInfoList(const int &location) -{ - return m_devGroupInfoMap.value(location, QList >()); -} - -QMap CDbInfoManage::getDevice(const QString &devGroup) -{ - return m_deviceInfo.value(devGroup, QMap()); -} - -QStringList CDbInfoManage::getTagList(const QString &device) -{ - return m_devTagName.value(device, QStringList()); -} - -QString CDbInfoManage::getTagDesc(const QString &tagName) -{ - QStringList value = m_tagInfo.value(tagName, QStringList()); - if(value.isEmpty()) - { - return QString(); - } - return value[0]; -} - -QString CDbInfoManage::getTagType(const QString &tagName) -{ - QStringList value = m_tagInfo.value(tagName, QStringList()); - if(value.isEmpty()) - { - return QString(); - } - return value[1]; -} - -QString CDbInfoManage::getUserAlias(const int &userId) -{ - return m_userInfo.value(userId, QString()); -} - -int CDbInfoManage::getRegionId(const QString &tag) -{ - return m_regionMap.value(tag, -1); -} - -QMap > CDbInfoManage::getShieldDefInfo() -{ - return m_shieldDefMap; -} - -QString CDbInfoManage::getShieldDef(const int &type) -{ - return m_shieldDefMap.value(type).first; -} - -int CDbInfoManage::getShieldProp(const int &type) -{ - return m_shieldDefMap.value(type).second; -} - -QMap CDbInfoManage::getShieldPropMap() -{ - return m_shieldPropertyMap; -} - -bool CDbInfoManage::loadShieldObj(const int &shieldId, QList &objList) -{ - kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); - bool ret = objReadDb.open(); - if(!ret) - { - LOGERROR("%s", objReadDb.getLastErrorString().toStdString().c_str()); - return false; - } - - objList.clear(); - - QSqlQuery query; - QString sql = QString("select " - "shield_id," - "key_id_tag," - "shield_mode," - "shield_object " - "from opt_shield_obj " - "where shield_id=%1").arg(shieldId); - - if(objReadDb.execute(sql, query)) - { - while(query.next()) - { - ST_Shield_Obj info; - info.m_shieldId = query.value(0).toInt(); - info.m_keyIdTag = query.value(1).toString(); - info.m_shieldMode = query.value(2).toInt(); - info.m_shieldObject = query.value(3).toString(); - setOptPerm(info); - objList.append(info); - } - return true; - } - return false; -} - -bool CDbInfoManage::loadShieldObj(const QStringList &objList, QMap > &objMap) -{ - kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); - bool ret = objReadDb.open(); - if(!ret) - { - LOGERROR("%s", objReadDb.getLastErrorString().toStdString().c_str()); - return false; - } - - objMap.clear(); - - QString keyTagStr = ""; - foreach (QString tag, objList) { - QString temp = " key_id_tag like '" + tag + "%' or"; - keyTagStr += temp; - } - keyTagStr.remove(-2,2); - QSqlQuery query; - QString sql = QString("select " - "shield_id," - "key_id_tag," - "shield_mode," - "shield_object " - "from opt_shield_obj " - "where %1").arg(keyTagStr); - - if(objReadDb.execute(sql, query)) - { - while(query.next()) - { - ST_Shield_Obj info; - info.m_shieldId = query.value(0).toInt(); - info.m_keyIdTag = query.value(1).toString(); - info.m_shieldMode = query.value(2).toInt(); - info.m_shieldObject = query.value(3).toString(); - setOptPerm(info); - objMap[info.m_shieldId].append(info); - } - return true; - } - return false; -} - -bool CDbInfoManage::loadShieldInfo(const QList &objList, QList &infoList) -{ - kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); - bool ret = objReadDb.open(); - if(!ret) - { - LOGERROR("%s", objReadDb.getLastErrorString().toStdString().c_str()); - return false; - } - - infoList.clear(); - - QString keyTagStr = ""; - foreach (int id, objList) { - keyTagStr += QString("%1,").arg(QString::number(id)); - } - keyTagStr.remove(-1,1); - QSqlQuery query; - QString sql = QString("select " - "t1.shield_id," - "t1.shield_name," - "t1.shield_type," - "t1.shield_status," - "t1.shield_enable," - "t1.time_id," - "t1.host_name," - "t1.user_id," - "t1.description," - "t2.time_type," - "t2.start_time," - "t2.end_time," - "t2.time_option " - "from opt_shield_info as t1 " - "left join opt_shield_time as t2 " - "on t1.time_id = t2.time_id " - "where t1.shield_id in (%1)").arg(keyTagStr); - - if(objReadDb.execute(sql, query)) - { - while(query.next()) - { - ST_Shield_Info info; - info.m_shieldId = query.value(0).toInt(); - info.m_shieldName = query.value(1).toString(); - info.m_shieldType = query.value(2).toInt(); - info.m_shieldStatus = query.value(3).toInt(); - info.m_shieldEnable = query.value(4).toInt(); - info.m_timeId = query.value(5).toInt(); - info.m_hostName = query.value(6).toString(); - info.m_userId = query.value(7).toInt(); - info.m_shieldDesc = query.value(8).toString(); - info.m_timeType = query.value(9).toInt(); - info.m_startTime = query.value(10).toString(); - info.m_endTime = query.value(11).toString(); - info.m_timeOption = query.value(12).toInt(); - info.m_check = false; - info.m_perm = true; - infoList.append(info); - } - return true; - } - return false; -} - -bool CDbInfoManage::multiShield(const QList &shieldId) -{ - if(shieldId.isEmpty()) - return true; - QString sql = QString("update %1 set shield_enable = %2 where shield_id in (%3)").arg("opt_shield_info").arg(1).arg(getJoinStr(shieldId, ',')); - return m_pWriteDb->execute(sql); -} - -bool CDbInfoManage::multiUnShield(const QList &shieldId) -{ - if(shieldId.isEmpty()) - return true; - QString sql = QString("update %1 set shield_enable = %2 where shield_id in (%3)").arg("opt_shield_info").arg(0).arg(getJoinStr(shieldId, ',')); - return m_pWriteDb->execute(sql); -} - -bool CDbInfoManage::multiDelShield(const QList &timeId, const QList &shieldId) -{ - if(shieldId.isEmpty() || timeId.isEmpty()) - return true; - - m_pWriteDb->transaction(); - - bool isSuccess; - QString sql = QString("delete from %1 where time_id in (%2)").arg("opt_shield_time").arg(getJoinStr(timeId, ',')); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - sql = QString("delete from %1 where shield_id in (%2)").arg("opt_shield_info").arg(getJoinStr(shieldId, ',')); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - sql = QString("delete from %1 where shield_id in (%2)").arg("opt_shield_obj").arg(getJoinStr(shieldId, ',')); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - if(!m_pWriteDb->commit()) - { - m_pWriteDb->rollback(); - return false; - } - return true; -} - -bool CDbInfoManage::shield(const int &shieldId) -{ - QString sql = QString("update %1 set shield_enable = %2 where shield_id = %3").arg("opt_shield_info").arg(1).arg(shieldId); - return m_pWriteDb->execute(sql); -} - -bool CDbInfoManage::unshield(const int &shieldId) -{ - QString sql = QString("update %1 set shield_enable = %2 where shield_id = %3").arg("opt_shield_info").arg(0).arg(shieldId); - return m_pWriteDb->execute(sql); -} - -bool CDbInfoManage::delShield(const int &timeId, const int &shieldId) -{ - m_pWriteDb->transaction(); - - bool isSuccess; - QString sql = QString("delete from %1 where time_id = %2").arg("opt_shield_time").arg(timeId); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - sql = QString("delete from %1 where shield_id = %2").arg("opt_shield_info").arg(shieldId); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - sql = QString("delete from %1 where shield_id = %2").arg("opt_shield_obj").arg(shieldId); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - if(!m_pWriteDb->commit()) - { - m_pWriteDb->rollback(); - return false; - } - return true; -} - -bool CDbInfoManage::insertShield(const ST_Shield_Info &info, const QMap &objMap) -{ - int timeId = 1; - int shieldId = 1; - if(!getMaxId(timeId, shieldId)) - { - return false; - } - - bool isSuccess; - QString sql; - m_pWriteDb->transaction(); - - sql = QString("insert into %1 (time_id,time_type,start_time,end_time,time_option) values (%2,%3,'%4','%5',%6)") - .arg("opt_shield_time") - .arg(timeId) - .arg(info.m_timeType) - .arg(info.m_startTime) - .arg(info.m_endTime) - .arg(info.m_timeOption); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - sql = QString("insert into %1 (shield_id,shield_name,shield_type,shield_status,shield_enable,location_id,sub_system,shield_time,time_id" - ",host_name,user_id,user_group_id,description) values (%2,'%3',%4,%5,%6,%7,%8,%9,%10,'%11',%12,%13,'%14')") - .arg("opt_shield_info") - .arg(shieldId) - .arg(info.m_shieldName) - .arg(info.m_shieldType) - .arg(info.m_shieldStatus) - .arg(info.m_shieldEnable) - .arg(info.m_location) - .arg(info.m_subsystem) - .arg(info.m_shieldTime) - .arg(timeId) - .arg(info.m_hostName) - .arg(info.m_userId) - .arg(info.m_usergId) - .arg(info.m_shieldDesc); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - QMap::const_iterator iter = objMap.constBegin(); - for(; iter != objMap.constEnd(); iter++) - { - QString keyIdTag; - CDbInfoManage::instance()->getShieldKeyIdTag(iter.value(), iter.key(), keyIdTag); - if(keyIdTag.isEmpty()) - { - continue; - } - - int locationId; - if(iter.value() == Shield_Location) - { - locationId = iter.key().toInt(); - } - else - { - locationId = getLocationId(iter.key().section(".", 0, 0)); - } - if(locationId == -1) - { - continue; - } - - sql = QString("insert into %1 (shield_id,key_id_tag,shield_mode,location_id,sub_system,shield_object) values (%2,'%3',%4,%5,%6,'%7')") - .arg("opt_shield_obj") - .arg(shieldId) - .arg(keyIdTag) - .arg(iter.value()) - .arg(locationId) - .arg(info.m_subsystem) - .arg(iter.key()); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - break; - } - } - - if(!isSuccess || !m_pWriteDb->commit()) - { - m_pWriteDb->rollback(); - return false; - } - return true; -} - -bool CDbInfoManage::updateShield(const ST_Shield_Info &info, const QMap &preObjMap, const QMap &objMap) -{ - bool isSuccess; - QString sql; - m_pWriteDb->transaction(); - - sql = QString("update %1 set time_type=%2,start_time='%3',end_time='%4',time_option=%5 where time_id=%6") - .arg("opt_shield_time") - .arg(info.m_timeType) - .arg(info.m_startTime) - .arg(info.m_endTime) - .arg(info.m_timeOption) - .arg(info.m_timeId); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - sql = QString("update %1 set shield_name='%2',shield_type=%3,shield_enable=%4,location_id=%5,sub_system=%6,shield_time=%7,time_id=%8" - ",host_name='%9',user_id=%10,user_group_id=%11,description='%12' where shield_id=%13") - .arg("opt_shield_info") - .arg(info.m_shieldName) - .arg(info.m_shieldType) - .arg(info.m_shieldEnable) - .arg(info.m_location) - .arg(info.m_subsystem) - .arg(info.m_shieldTime) - .arg(info.m_timeId) - .arg(info.m_hostName) - .arg(info.m_userId) - .arg(info.m_usergId) - .arg(info.m_shieldDesc) - .arg(info.m_shieldId); - isSuccess = m_pWriteDb->execute(sql); - - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - - QMap objModeMap = objMap; - QMap::const_iterator preIter = preObjMap.constBegin(); - for(; preIter != preObjMap.constEnd(); preIter++) - { - QMap::iterator it = objModeMap.find(preIter.key()); - if(it != objModeMap.end()) - { - objModeMap.erase(it); - } - else - { - QString keyIdTag; - getShieldKeyIdTag(preIter.value(), preIter.key(), keyIdTag); - sql = QString("delete from opt_shield_obj where shield_id=%1 and key_id_tag='%2'") - .arg(info.m_shieldId) - .arg(keyIdTag); - isSuccess = m_pWriteDb->execute(sql); - - if(!isSuccess) - { - m_pWriteDb->rollback(); - return false; - } - } - } - - QMap::const_iterator iter = objModeMap.constBegin(); - for(; iter != objModeMap.constEnd(); iter++) - { - QString keyIdTag; - getShieldKeyIdTag(iter.value(), iter.key(), keyIdTag); - if(keyIdTag.isEmpty()) - { - continue; - } - - int locationId; - if(iter.value() == Shield_Location) - { - locationId = iter.key().toInt(); - } - else - { - locationId = getLocationId(iter.key().section(".", 0, 0)); - } - if(locationId == -1) - { - continue; - } - - sql = QString("insert into %1 (shield_id,key_id_tag,shield_mode,location_id,sub_system,shield_object) values (%2,'%3',%4,%5,%6,'%7')") - .arg("opt_shield_obj") - .arg(info.m_shieldId) - .arg(keyIdTag) - .arg(iter.value()) - .arg(locationId) - .arg(info.m_subsystem) - .arg(iter.key()); - isSuccess = m_pWriteDb->execute(sql); - if(!isSuccess) - { - break; - } - } - - if(!isSuccess || !m_pWriteDb->commit()) - { - m_pWriteDb->rollback(); - return false; - } - return true; -} - -E_Shield_Mode CDbInfoManage::getShieldMode(const E_Tree_ItemType &type) -{ - switch (type) { - case Item_Root_Type: - { - return Shield_Invalid; - break; - } - case Item_Location_Type: - { - return Shield_Location; - break; - } - case Item_DevGroup_Type: - { - return Shield_DevGroup; - break; - } - case Item_Device_Type: - { - return Shield_Device; - break; - } - case Item_Point_Type: - { - return Shield_Point; - break; - } - case Item_Voltage_Type: - { - return Shield_Voltage; - break; - } - case Item_Region_Type: - { - return Shield_Region; - break; - } - default: - break; - } - return Shield_Invalid; -} - -E_Tree_ItemType CDbInfoManage::getTreeItemType(const E_Shield_Mode &mode) -{ - switch (mode) { - case Shield_Invalid: - { - return Item_Root_Type; - break; - } - case Shield_Location: - { - return Item_Location_Type; - break; - } - case Shield_DevGroup: - { - return Item_DevGroup_Type; - break; - } - case Shield_Device: - { - return Item_Device_Type; - break; - } - case Shield_Point: - { - return Item_Point_Type; - break; - } - case Shield_Voltage: - { - return Item_Voltage_Type; - break; - } - case Shield_Region: - { - return Item_Region_Type; - break; - } - default: - break; - } - return Item_Root_Type; -} - -void CDbInfoManage::getShieldKeyIdTag(const int &mode, const QString &obj, QString &mid) -{ - switch (E_Shield_Mode(mode)) { - case Shield_Invalid: - { - break; - } - case Shield_Location: - { - mid = QString("MODE[%1]LOCATION[%2]") - .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) - .arg(CDbInfoManage::instance()->getDoubleNumber(obj.toInt())); - break; - } - case Shield_Voltage: - { - mid = QString("MODE[%1]VLEVEL[%2]") - .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) - .arg(obj); - break; - } - case Shield_Region: - { - mid = QString("MODE[%1]REGION[%2]") - .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) - .arg(obj); - break; - } - case Shield_DevGroup: - { - mid = QString("MODE[%1]DEVGRP[%2]") - .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) - .arg(obj); - break; - } - case Shield_Device: - { - mid = QString("MODE[%1]DEVICE[%2]") - .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) - .arg(obj); - break; - } - case Shield_Point: - { - mid = QString("MODE[%1]DEVPOINT[%2]") - .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) - .arg(obj); - break; - } - default: - break; - } -} - -QString CDbInfoManage::getDoubleNumber(const int &number) -{ - QString ret; - if(number < 10) - { - ret = QString("0%1").arg(number); - } - else - { - ret = QString::number(number); - } - return ret; -} - -void CDbInfoManage::setOptPerm(ST_Shield_Obj &shiledObj) -{ - std::vector vecRegionOptId; - std::vector vecLocationOptId; - if(shiledObj.m_shieldMode == Shield_Location) - { - vecLocationOptId.push_back(shiledObj.m_shieldObject.toInt()); - } - else if(shiledObj.m_shieldMode >= Shield_DevGroup) - { - vecRegionOptId.push_back(getRegionId(shiledObj.m_shieldObject)); - vecLocationOptId.push_back(getLocationId(shiledObj.m_shieldObject.section(".",0,0))); - } - - shiledObj.m_perm = checkOptPerm(vecRegionOptId, vecLocationOptId); -} - -bool CDbInfoManage::checkOptPerm(const std::vector &vecRegionOptId, const std::vector &vecLocationId) -{ - if (m_ptrPermMng == NULL) - { - return false; - } - - if(vecRegionOptId.size() > 0) - { - foreach (int RegionOptId, vecRegionOptId) { - std::vector::iterator rIter = find(m_vecRegionOptId.begin(), m_vecRegionOptId.end(), RegionOptId); - if(rIter == m_vecRegionOptId.end()) - { - return false; - } - } - } - - if(vecLocationId.size() > 0) - { - foreach (int LocationOptId, vecLocationId) { - std::vector::iterator lIter = find(m_vecLocationOptId.begin(), m_vecLocationOptId.end(), LocationOptId); - if(lIter == m_vecLocationOptId.end()) - { - return false; - } - } - } - - return true; -} - -CDbInfoManage::CDbInfoManage() -{ - initPermMng(); - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); - m_pWriteDb->open(); - -// m_tagInfo.reserve(5000); - - kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); - bool ret = objReadDb.open(); - if(!ret) - { - LOGERROR("%s", objReadDb.getLastErrorString().toStdString().c_str()); - return; - } - - loadRTLocation(); - loadDevGroupInfo(objReadDb); - loadDeviceInfo(objReadDb); -// loadPointInfo(objReadDb); - loadUserInfo(objReadDb); - loadShieldDefine(objReadDb); - loadShieldProperty(objReadDb); -} - -void CDbInfoManage::initPermMng() -{ - m_ptrPermMng = kbd_service::getPermMngInstance("base"); - if(m_ptrPermMng == NULL || (PERM_NORMAL != m_ptrPermMng->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return; - } - std::string tmp = "FUNC_SPE_OPT_OVERRIDE"; - if(PERM_NORMAL != m_ptrPermMng->GetSpeFunc(tmp, m_vecRegionOptId, m_vecLocationOptId)) - { - LOGERROR("权限接口获取当前登录用户的特殊功能责任区和车站信息失败!"); - return; - } -} - -QString CDbInfoManage::getJoinStr(const QList &list, char c) -{ - QString str = ""; - foreach (int id, list) { - str.append(c); - str.append(QString::number(id)); - } - if(str.length() > 1) - { - str.remove(0,1); - } - return str; -} - -void CDbInfoManage::loadRTLocation() -{ - if(m_ptrPermMng == NULL) - { - return; - } - int level; - std::vector vecLocationId; - std::vector vecPermPic; - if (PERM_NORMAL != m_ptrPermMng->GetUsergInfo(level, vecLocationId, vecPermPic)) - { - LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); - return; - } - - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("location_id"); - columns.push_back("tag_name"); - columns.push_back("description"); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - m_locationInfo.clear(); - m_locationTag.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType location_id; - kbd_dbms::CVarType tag_name; - kbd_dbms::CVarType description; - result.getColumnValue(nIndex, 0, location_id); - result.getColumnValue(nIndex, 1, tag_name); - result.getColumnValue(nIndex, 2, description); - - std::vector ::const_iterator it = vecLocationId.cbegin(); - while (it != vecLocationId.cend()) - { - if(location_id.toInt() == *it) - { - m_locationInfo[location_id.toInt()] = QString::fromStdString(description.toStdString()); - m_locationTag[location_id.toInt()] = QString::fromStdString(tag_name.toStdString()); - m_locationList.push_back(location_id.toInt()); - } - ++it; - } - } - } - } - m_rtdbAccess->close(); -} - -void CDbInfoManage::loadDevGroupInfo(kbd_dbms::CDbApi &objReadDb) -{ - QSqlQuery query; - - QString strLoctionFilter; - if(!m_locationInfo.keys().isEmpty()) - { - QStringList listLocation; - foreach (int nLocationID, m_locationInfo.keys()) - { - listLocation.append(QString::number(nLocationID)); - } - strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); - } - QString sqlSequenceQuery = QString("select tag_name, description, location_id, region_id from dev_group where sub_system > 3"); - if(!strLoctionFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); - }else - { - sqlSequenceQuery.append(QString(" order by dev_group_no asc;")); - } - objReadDb.execute(sqlSequenceQuery, query); - while(query.next()) - { - QPair pair; - pair.first = query.value(0).toString(); - pair.second = query.value(1).toString(); - QMap > >::iterator it = m_devGroupInfoMap.find(query.value(2).toInt()); - if(it !=m_devGroupInfoMap.end()) - { - QList > &devgList = it.value(); - devgList.append(pair); - }else - { - QList > devgList; - devgList.append(pair); - m_devGroupInfoMap[query.value(2).toInt()] = devgList; - } - m_devGroupInfo[query.value(2).toInt()].insert(query.value(0).toString(), query.value(1).toString()); - m_regionMap.insert(query.value(0).toString(), query.value(3).toInt()); - } -} - -void CDbInfoManage::loadDeviceInfo(kbd_dbms::CDbApi &objReadDb) -{ - QSqlQuery query; - - QString strLoctionFilter; - QList > listDevGroup = m_devGroupInfo.values(); - if(!listDevGroup.isEmpty()) - { - QStringList listLocation; - for(int i=0; i >::const_iterator iter = m_deviceInfo.constBegin(); - while (iter != m_deviceInfo.constEnd()) - { - listDevice.append(iter.value().keys()); - ++iter; - } - strDeviceFilter = "'" + listDevice.join("', '") + "'"; - strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); - } - - for(int nIndex(0); nIndex < listType.size(); nIndex++) - { - QString sqlSequenceQuery = QString("select tag_name,description,device,region_id from %1 where sub_system > 3 and ").arg(listType.at(nIndex)); - if(!strDeviceFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" %1 ORDER BY SEQ_NO asc;").arg(strDeviceFilter)); - } - - objReadDb.execute(sqlSequenceQuery, query); - while(query.next()) - { - const QString tagName = query.value(0).toString(); - const QString tagDesc = query.value(1).toString(); - const QString device = query.value(2).toString(); - m_devTagName[device].append(tagName); - m_tagInfo.insert(tagName, QStringList() << tagDesc << listType.at(nIndex)); - m_regionMap.insert(query.value(0).toString(), query.value(3).toInt()); - } - } -} - -void CDbInfoManage::loadUserInfo(kbd_dbms::CDbApi &objReadDb) -{ - QSqlQuery query; - QString sql = QString("select perm_id,perm_alias from rm_user_def"); - if(objReadDb.execute(sql,query)) - { - while (query.next()) { - int perm_id = query.value(0).toInt(); - QString perm_alias = query.value(1).toString(); - m_userInfo[perm_id] = perm_alias; - } - } -} - -void CDbInfoManage::loadShieldDefine(kbd_dbms::CDbApi &objReadDb) -{ - QSqlQuery query; - QString sql = QString("select shield_id,description,shield_prop from opt_shield_define"); - if(objReadDb.execute(sql,query)) - { - while (query.next()) { - int id = query.value(0).toInt(); - QString desc = query.value(1).toString(); - int value = query.value(2).toInt(); - m_shieldDefMap[id] = QPair(desc,value); - } - } -} - -void CDbInfoManage::loadShieldProperty(kbd_dbms::CDbApi &objReadDb) -{ - QSqlQuery query; - QString sql = QString("select actual_value,display_value from dict_menu_info where menu_name = '%1' ").arg("屏蔽属性"); - if(objReadDb.execute(sql,query)) - { - while (query.next()) { - int id = query.value(0).toInt(); - QString desc = query.value(1).toString(); - m_shieldPropertyMap[id] = desc; - } - } -} - -bool CDbInfoManage::getMaxId(int &timeId, int &shieldId) -{ - bool ret = false; - kbd_dbms::CDbApi readDb(DB_CONN_MODEL_READ); - if(!readDb.open()) - { - return false; - } - QSqlQuery query; - QString sql = QString("select max(time_id) from %1").arg("opt_shield_time"); - if(!readDb.execute(sql,query)) - { - return false; - } - while(query.next()) - { - timeId = query.value(0).toInt()+1; - ret = true; - } - if(!ret) - { - return false; - } - - QString sql1 = QString("select max(shield_id) from %1").arg("opt_shield_info"); - if(!readDb.execute(sql1,query)) - { - return false; - } - while(query.next()) - { - shieldId = query.value(0).toInt()+1; - return true; - } - return false; -} +#include "CDbInfoManage.h" +#include "pub_logger_api/logger.h" +#include + +CDbInfoManage *CDbInfoManage::m_pInstance = NULL; + +CDbInfoManage *CDbInfoManage::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDbInfoManage(); + } + return m_pInstance; +} + +void CDbInfoManage::destory() +{ + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + if(m_pWriteDb) + { + delete m_pWriteDb; + } + m_pWriteDb = NULL; + + m_regionMap.clear(); + m_locationInfo.clear(); + m_locationTag.clear(); + m_locationList.clear(); + m_devGroupInfo.clear(); + m_deviceInfo.clear(); + m_devTagName.clear(); + m_tagInfo.clear(); + m_userInfo.clear(); + m_vecRegionOptId.clear(); + m_vecLocationOptId.clear(); + m_shieldDefMap.clear(); + m_shieldPropertyMap.clear(); + m_pInstance = NULL; + delete this; +} + +QString CDbInfoManage::getLocationTag(const int &location) +{ + return m_locationTag.value(location, QString()); +} + +int CDbInfoManage::getLocationId(const QString &tag) +{ + QMap::const_iterator iter = m_locationTag.constBegin(); + while(iter != m_locationTag.constEnd()) + { + if(iter.value() == tag) + { + return iter.key(); + } + iter++; + } + return -1; +} + +QList CDbInfoManage::getLocationList() +{ + return m_locationList; +} + +QMap CDbInfoManage::getLocationInfo() +{ + return m_locationInfo; +} + +QString CDbInfoManage::getLocationDesc(const int &location) +{ + return m_locationInfo.value(location); +} + +QMap CDbInfoManage::getDevGroup(const int &location) +{ + return m_devGroupInfo.value(location, QMap()); +} + +QList > CDbInfoManage::getDevGroupInfoList(const int &location) +{ + return m_devGroupInfoMap.value(location, QList >()); +} + +QMap CDbInfoManage::getDevice(const QString &devGroup) +{ + return m_deviceInfo.value(devGroup, QMap()); +} + +QStringList CDbInfoManage::getTagList(const QString &device) +{ + return m_devTagName.value(device, QStringList()); +} + +QString CDbInfoManage::getTagDesc(const QString &tagName) +{ + QStringList value = m_tagInfo.value(tagName, QStringList()); + if(value.isEmpty()) + { + return QString(); + } + return value[0]; +} + +QString CDbInfoManage::getTagType(const QString &tagName) +{ + QStringList value = m_tagInfo.value(tagName, QStringList()); + if(value.isEmpty()) + { + return QString(); + } + return value[1]; +} + +QString CDbInfoManage::getUserAlias(const int &userId) +{ + return m_userInfo.value(userId, QString()); +} + +int CDbInfoManage::getRegionId(const QString &tag) +{ + return m_regionMap.value(tag, -1); +} + +QMap > CDbInfoManage::getShieldDefInfo() +{ + return m_shieldDefMap; +} + +QString CDbInfoManage::getShieldDef(const int &type) +{ + return m_shieldDefMap.value(type).first; +} + +int CDbInfoManage::getShieldProp(const int &type) +{ + return m_shieldDefMap.value(type).second; +} + +QMap CDbInfoManage::getShieldPropMap() +{ + return m_shieldPropertyMap; +} + +bool CDbInfoManage::loadShieldObj(const int &shieldId, QList &objList) +{ + kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); + bool ret = objReadDb.open(); + if(!ret) + { + LOGERROR("%s", objReadDb.getLastErrorString().toStdString().c_str()); + return false; + } + + objList.clear(); + + QSqlQuery query; + QString sql = QString("select " + "shield_id," + "key_id_tag," + "shield_mode," + "shield_object " + "from opt_shield_obj " + "where shield_id=%1").arg(shieldId); + + if(objReadDb.execute(sql, query)) + { + while(query.next()) + { + ST_Shield_Obj info; + info.m_shieldId = query.value(0).toInt(); + info.m_keyIdTag = query.value(1).toString(); + info.m_shieldMode = query.value(2).toInt(); + info.m_shieldObject = query.value(3).toString(); + setOptPerm(info); + objList.append(info); + } + return true; + } + return false; +} + +bool CDbInfoManage::loadShieldObj(const QStringList &objList, QMap > &objMap) +{ + kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); + bool ret = objReadDb.open(); + if(!ret) + { + LOGERROR("%s", objReadDb.getLastErrorString().toStdString().c_str()); + return false; + } + + objMap.clear(); + + QString keyTagStr = ""; + foreach (QString tag, objList) { + QString temp = " key_id_tag like '" + tag + "%' or"; + keyTagStr += temp; + } + keyTagStr.remove(-2,2); + QSqlQuery query; + QString sql = QString("select " + "shield_id," + "key_id_tag," + "shield_mode," + "shield_object " + "from opt_shield_obj " + "where %1").arg(keyTagStr); + + if(objReadDb.execute(sql, query)) + { + while(query.next()) + { + ST_Shield_Obj info; + info.m_shieldId = query.value(0).toInt(); + info.m_keyIdTag = query.value(1).toString(); + info.m_shieldMode = query.value(2).toInt(); + info.m_shieldObject = query.value(3).toString(); + setOptPerm(info); + objMap[info.m_shieldId].append(info); + } + return true; + } + return false; +} + +bool CDbInfoManage::loadShieldInfo(const QList &objList, QList &infoList) +{ + kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); + bool ret = objReadDb.open(); + if(!ret) + { + LOGERROR("%s", objReadDb.getLastErrorString().toStdString().c_str()); + return false; + } + + infoList.clear(); + + QString keyTagStr = ""; + foreach (int id, objList) { + keyTagStr += QString("%1,").arg(QString::number(id)); + } + keyTagStr.remove(-1,1); + QSqlQuery query; + QString sql = QString("select " + "t1.shield_id," + "t1.shield_name," + "t1.shield_type," + "t1.shield_status," + "t1.shield_enable," + "t1.time_id," + "t1.host_name," + "t1.user_id," + "t1.description," + "t2.time_type," + "t2.start_time," + "t2.end_time," + "t2.time_option " + "from opt_shield_info as t1 " + "left join opt_shield_time as t2 " + "on t1.time_id = t2.time_id " + "where t1.shield_id in (%1)").arg(keyTagStr); + + if(objReadDb.execute(sql, query)) + { + while(query.next()) + { + ST_Shield_Info info; + info.m_shieldId = query.value(0).toInt(); + info.m_shieldName = query.value(1).toString(); + info.m_shieldType = query.value(2).toInt(); + info.m_shieldStatus = query.value(3).toInt(); + info.m_shieldEnable = query.value(4).toInt(); + info.m_timeId = query.value(5).toInt(); + info.m_hostName = query.value(6).toString(); + info.m_userId = query.value(7).toInt(); + info.m_shieldDesc = query.value(8).toString(); + info.m_timeType = query.value(9).toInt(); + info.m_startTime = query.value(10).toString(); + info.m_endTime = query.value(11).toString(); + info.m_timeOption = query.value(12).toInt(); + info.m_check = false; + info.m_perm = true; + infoList.append(info); + } + return true; + } + return false; +} + +bool CDbInfoManage::multiShield(const QList &shieldId) +{ + if(shieldId.isEmpty()) + return true; + QString sql = QString("update %1 set shield_enable = %2 where shield_id in (%3)").arg("opt_shield_info").arg(1).arg(getJoinStr(shieldId, ',')); + return m_pWriteDb->execute(sql); +} + +bool CDbInfoManage::multiUnShield(const QList &shieldId) +{ + if(shieldId.isEmpty()) + return true; + QString sql = QString("update %1 set shield_enable = %2 where shield_id in (%3)").arg("opt_shield_info").arg(0).arg(getJoinStr(shieldId, ',')); + return m_pWriteDb->execute(sql); +} + +bool CDbInfoManage::multiDelShield(const QList &timeId, const QList &shieldId) +{ + if(shieldId.isEmpty() || timeId.isEmpty()) + return true; + + m_pWriteDb->transaction(); + + bool isSuccess; + QString sql = QString("delete from %1 where time_id in (%2)").arg("opt_shield_time").arg(getJoinStr(timeId, ',')); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + sql = QString("delete from %1 where shield_id in (%2)").arg("opt_shield_info").arg(getJoinStr(shieldId, ',')); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + sql = QString("delete from %1 where shield_id in (%2)").arg("opt_shield_obj").arg(getJoinStr(shieldId, ',')); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + if(!m_pWriteDb->commit()) + { + m_pWriteDb->rollback(); + return false; + } + return true; +} + +bool CDbInfoManage::shield(const int &shieldId) +{ + QString sql = QString("update %1 set shield_enable = %2 where shield_id = %3").arg("opt_shield_info").arg(1).arg(shieldId); + return m_pWriteDb->execute(sql); +} + +bool CDbInfoManage::unshield(const int &shieldId) +{ + QString sql = QString("update %1 set shield_enable = %2 where shield_id = %3").arg("opt_shield_info").arg(0).arg(shieldId); + return m_pWriteDb->execute(sql); +} + +bool CDbInfoManage::delShield(const int &timeId, const int &shieldId) +{ + m_pWriteDb->transaction(); + + bool isSuccess; + QString sql = QString("delete from %1 where time_id = %2").arg("opt_shield_time").arg(timeId); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + sql = QString("delete from %1 where shield_id = %2").arg("opt_shield_info").arg(shieldId); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + sql = QString("delete from %1 where shield_id = %2").arg("opt_shield_obj").arg(shieldId); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + if(!m_pWriteDb->commit()) + { + m_pWriteDb->rollback(); + return false; + } + return true; +} + +bool CDbInfoManage::insertShield(const ST_Shield_Info &info, const QMap &objMap) +{ + int timeId = 1; + int shieldId = 1; + if(!getMaxId(timeId, shieldId)) + { + return false; + } + + bool isSuccess; + QString sql; + m_pWriteDb->transaction(); + + sql = QString("insert into %1 (time_id,time_type,start_time,end_time,time_option) values (%2,%3,'%4','%5',%6)") + .arg("opt_shield_time") + .arg(timeId) + .arg(info.m_timeType) + .arg(info.m_startTime) + .arg(info.m_endTime) + .arg(info.m_timeOption); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + sql = QString("insert into %1 (shield_id,shield_name,shield_type,shield_status,shield_enable,location_id,sub_system,shield_time,time_id" + ",host_name,user_id,user_group_id,description) values (%2,'%3',%4,%5,%6,%7,%8,%9,%10,'%11',%12,%13,'%14')") + .arg("opt_shield_info") + .arg(shieldId) + .arg(info.m_shieldName) + .arg(info.m_shieldType) + .arg(info.m_shieldStatus) + .arg(info.m_shieldEnable) + .arg(info.m_location) + .arg(info.m_subsystem) + .arg(info.m_shieldTime) + .arg(timeId) + .arg(info.m_hostName) + .arg(info.m_userId) + .arg(info.m_usergId) + .arg(info.m_shieldDesc); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + QMap::const_iterator iter = objMap.constBegin(); + for(; iter != objMap.constEnd(); iter++) + { + QString keyIdTag; + CDbInfoManage::instance()->getShieldKeyIdTag(iter.value(), iter.key(), keyIdTag); + if(keyIdTag.isEmpty()) + { + continue; + } + + int locationId; + if(iter.value() == Shield_Location) + { + locationId = iter.key().toInt(); + } + else + { + locationId = getLocationId(iter.key().section(".", 0, 0)); + } + if(locationId == -1) + { + continue; + } + + sql = QString("insert into %1 (shield_id,key_id_tag,shield_mode,location_id,sub_system,shield_object) values (%2,'%3',%4,%5,%6,'%7')") + .arg("opt_shield_obj") + .arg(shieldId) + .arg(keyIdTag) + .arg(iter.value()) + .arg(locationId) + .arg(info.m_subsystem) + .arg(iter.key()); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + break; + } + } + + if(!isSuccess || !m_pWriteDb->commit()) + { + m_pWriteDb->rollback(); + return false; + } + return true; +} + +bool CDbInfoManage::updateShield(const ST_Shield_Info &info, const QMap &preObjMap, const QMap &objMap) +{ + bool isSuccess; + QString sql; + m_pWriteDb->transaction(); + + sql = QString("update %1 set time_type=%2,start_time='%3',end_time='%4',time_option=%5 where time_id=%6") + .arg("opt_shield_time") + .arg(info.m_timeType) + .arg(info.m_startTime) + .arg(info.m_endTime) + .arg(info.m_timeOption) + .arg(info.m_timeId); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + sql = QString("update %1 set shield_name='%2',shield_type=%3,shield_enable=%4,location_id=%5,sub_system=%6,shield_time=%7,time_id=%8" + ",host_name='%9',user_id=%10,user_group_id=%11,description='%12' where shield_id=%13") + .arg("opt_shield_info") + .arg(info.m_shieldName) + .arg(info.m_shieldType) + .arg(info.m_shieldEnable) + .arg(info.m_location) + .arg(info.m_subsystem) + .arg(info.m_shieldTime) + .arg(info.m_timeId) + .arg(info.m_hostName) + .arg(info.m_userId) + .arg(info.m_usergId) + .arg(info.m_shieldDesc) + .arg(info.m_shieldId); + isSuccess = m_pWriteDb->execute(sql); + + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + + QMap objModeMap = objMap; + QMap::const_iterator preIter = preObjMap.constBegin(); + for(; preIter != preObjMap.constEnd(); preIter++) + { + QMap::iterator it = objModeMap.find(preIter.key()); + if(it != objModeMap.end()) + { + objModeMap.erase(it); + } + else + { + QString keyIdTag; + getShieldKeyIdTag(preIter.value(), preIter.key(), keyIdTag); + sql = QString("delete from opt_shield_obj where shield_id=%1 and key_id_tag='%2'") + .arg(info.m_shieldId) + .arg(keyIdTag); + isSuccess = m_pWriteDb->execute(sql); + + if(!isSuccess) + { + m_pWriteDb->rollback(); + return false; + } + } + } + + QMap::const_iterator iter = objModeMap.constBegin(); + for(; iter != objModeMap.constEnd(); iter++) + { + QString keyIdTag; + getShieldKeyIdTag(iter.value(), iter.key(), keyIdTag); + if(keyIdTag.isEmpty()) + { + continue; + } + + int locationId; + if(iter.value() == Shield_Location) + { + locationId = iter.key().toInt(); + } + else + { + locationId = getLocationId(iter.key().section(".", 0, 0)); + } + if(locationId == -1) + { + continue; + } + + sql = QString("insert into %1 (shield_id,key_id_tag,shield_mode,location_id,sub_system,shield_object) values (%2,'%3',%4,%5,%6,'%7')") + .arg("opt_shield_obj") + .arg(info.m_shieldId) + .arg(keyIdTag) + .arg(iter.value()) + .arg(locationId) + .arg(info.m_subsystem) + .arg(iter.key()); + isSuccess = m_pWriteDb->execute(sql); + if(!isSuccess) + { + break; + } + } + + if(!isSuccess || !m_pWriteDb->commit()) + { + m_pWriteDb->rollback(); + return false; + } + return true; +} + +E_Shield_Mode CDbInfoManage::getShieldMode(const E_Tree_ItemType &type) +{ + switch (type) { + case Item_Root_Type: + { + return Shield_Invalid; + break; + } + case Item_Location_Type: + { + return Shield_Location; + break; + } + case Item_DevGroup_Type: + { + return Shield_DevGroup; + break; + } + case Item_Device_Type: + { + return Shield_Device; + break; + } + case Item_Point_Type: + { + return Shield_Point; + break; + } + case Item_Voltage_Type: + { + return Shield_Voltage; + break; + } + case Item_Region_Type: + { + return Shield_Region; + break; + } + default: + break; + } + return Shield_Invalid; +} + +E_Tree_ItemType CDbInfoManage::getTreeItemType(const E_Shield_Mode &mode) +{ + switch (mode) { + case Shield_Invalid: + { + return Item_Root_Type; + break; + } + case Shield_Location: + { + return Item_Location_Type; + break; + } + case Shield_DevGroup: + { + return Item_DevGroup_Type; + break; + } + case Shield_Device: + { + return Item_Device_Type; + break; + } + case Shield_Point: + { + return Item_Point_Type; + break; + } + case Shield_Voltage: + { + return Item_Voltage_Type; + break; + } + case Shield_Region: + { + return Item_Region_Type; + break; + } + default: + break; + } + return Item_Root_Type; +} + +void CDbInfoManage::getShieldKeyIdTag(const int &mode, const QString &obj, QString &mid) +{ + switch (E_Shield_Mode(mode)) { + case Shield_Invalid: + { + break; + } + case Shield_Location: + { + mid = QString("MODE[%1]LOCATION[%2]") + .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) + .arg(CDbInfoManage::instance()->getDoubleNumber(obj.toInt())); + break; + } + case Shield_Voltage: + { + mid = QString("MODE[%1]VLEVEL[%2]") + .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) + .arg(obj); + break; + } + case Shield_Region: + { + mid = QString("MODE[%1]REGION[%2]") + .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) + .arg(obj); + break; + } + case Shield_DevGroup: + { + mid = QString("MODE[%1]DEVGRP[%2]") + .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) + .arg(obj); + break; + } + case Shield_Device: + { + mid = QString("MODE[%1]DEVICE[%2]") + .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) + .arg(obj); + break; + } + case Shield_Point: + { + mid = QString("MODE[%1]DEVPOINT[%2]") + .arg(CDbInfoManage::instance()->getDoubleNumber(mode)) + .arg(obj); + break; + } + default: + break; + } +} + +QString CDbInfoManage::getDoubleNumber(const int &number) +{ + QString ret; + if(number < 10) + { + ret = QString("0%1").arg(number); + } + else + { + ret = QString::number(number); + } + return ret; +} + +void CDbInfoManage::setOptPerm(ST_Shield_Obj &shiledObj) +{ + std::vector vecRegionOptId; + std::vector vecLocationOptId; + if(shiledObj.m_shieldMode == Shield_Location) + { + vecLocationOptId.push_back(shiledObj.m_shieldObject.toInt()); + } + else if(shiledObj.m_shieldMode >= Shield_DevGroup) + { + vecRegionOptId.push_back(getRegionId(shiledObj.m_shieldObject)); + vecLocationOptId.push_back(getLocationId(shiledObj.m_shieldObject.section(".",0,0))); + } + + shiledObj.m_perm = checkOptPerm(vecRegionOptId, vecLocationOptId); +} + +bool CDbInfoManage::checkOptPerm(const std::vector &vecRegionOptId, const std::vector &vecLocationId) +{ + if (m_ptrPermMng == NULL) + { + return false; + } + + if(vecRegionOptId.size() > 0) + { + foreach (int RegionOptId, vecRegionOptId) { + std::vector::iterator rIter = find(m_vecRegionOptId.begin(), m_vecRegionOptId.end(), RegionOptId); + if(rIter == m_vecRegionOptId.end()) + { + return false; + } + } + } + + if(vecLocationId.size() > 0) + { + foreach (int LocationOptId, vecLocationId) { + std::vector::iterator lIter = find(m_vecLocationOptId.begin(), m_vecLocationOptId.end(), LocationOptId); + if(lIter == m_vecLocationOptId.end()) + { + return false; + } + } + } + + return true; +} + +CDbInfoManage::CDbInfoManage() +{ + initPermMng(); + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); + m_pWriteDb->open(); + +// m_tagInfo.reserve(5000); + + kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); + bool ret = objReadDb.open(); + if(!ret) + { + LOGERROR("%s", objReadDb.getLastErrorString().toStdString().c_str()); + return; + } + + loadRTLocation(); + loadDevGroupInfo(objReadDb); + loadDeviceInfo(objReadDb); +// loadPointInfo(objReadDb); + loadUserInfo(objReadDb); + loadShieldDefine(objReadDb); + loadShieldProperty(objReadDb); +} + +void CDbInfoManage::initPermMng() +{ + m_ptrPermMng = kbd_service::getPermMngInstance("base"); + if(m_ptrPermMng == NULL || (PERM_NORMAL != m_ptrPermMng->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + std::string tmp = "FUNC_SPE_OPT_OVERRIDE"; + if(PERM_NORMAL != m_ptrPermMng->GetSpeFunc(tmp, m_vecRegionOptId, m_vecLocationOptId)) + { + LOGERROR("权限接口获取当前登录用户的特殊功能责任区和车站信息失败!"); + return; + } +} + +QString CDbInfoManage::getJoinStr(const QList &list, char c) +{ + QString str = ""; + foreach (int id, list) { + str.append(c); + str.append(QString::number(id)); + } + if(str.length() > 1) + { + str.remove(0,1); + } + return str; +} + +void CDbInfoManage::loadRTLocation() +{ + if(m_ptrPermMng == NULL) + { + return; + } + int level; + std::vector vecLocationId; + std::vector vecPermPic; + if (PERM_NORMAL != m_ptrPermMng->GetUsergInfo(level, vecLocationId, vecPermPic)) + { + LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); + return; + } + + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("tag_name"); + columns.push_back("description"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + m_locationInfo.clear(); + m_locationTag.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType location_id; + kbd_dbms::CVarType tag_name; + kbd_dbms::CVarType description; + result.getColumnValue(nIndex, 0, location_id); + result.getColumnValue(nIndex, 1, tag_name); + result.getColumnValue(nIndex, 2, description); + + std::vector ::const_iterator it = vecLocationId.cbegin(); + while (it != vecLocationId.cend()) + { + if(location_id.toInt() == *it) + { + m_locationInfo[location_id.toInt()] = QString::fromStdString(description.toStdString()); + m_locationTag[location_id.toInt()] = QString::fromStdString(tag_name.toStdString()); + m_locationList.push_back(location_id.toInt()); + } + ++it; + } + } + } + } + m_rtdbAccess->close(); +} + +void CDbInfoManage::loadDevGroupInfo(kbd_dbms::CDbApi &objReadDb) +{ + QSqlQuery query; + + QString strLoctionFilter; + if(!m_locationInfo.keys().isEmpty()) + { + QStringList listLocation; + foreach (int nLocationID, m_locationInfo.keys()) + { + listLocation.append(QString::number(nLocationID)); + } + strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); + } + QString sqlSequenceQuery = QString("select tag_name, description, location_id, region_id from dev_group where sub_system > 3"); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); + }else + { + sqlSequenceQuery.append(QString(" order by dev_group_no asc;")); + } + objReadDb.execute(sqlSequenceQuery, query); + while(query.next()) + { + QPair pair; + pair.first = query.value(0).toString(); + pair.second = query.value(1).toString(); + QMap > >::iterator it = m_devGroupInfoMap.find(query.value(2).toInt()); + if(it !=m_devGroupInfoMap.end()) + { + QList > &devgList = it.value(); + devgList.append(pair); + }else + { + QList > devgList; + devgList.append(pair); + m_devGroupInfoMap[query.value(2).toInt()] = devgList; + } + m_devGroupInfo[query.value(2).toInt()].insert(query.value(0).toString(), query.value(1).toString()); + m_regionMap.insert(query.value(0).toString(), query.value(3).toInt()); + } +} + +void CDbInfoManage::loadDeviceInfo(kbd_dbms::CDbApi &objReadDb) +{ + QSqlQuery query; + + QString strLoctionFilter; + QList > listDevGroup = m_devGroupInfo.values(); + if(!listDevGroup.isEmpty()) + { + QStringList listLocation; + for(int i=0; i >::const_iterator iter = m_deviceInfo.constBegin(); + while (iter != m_deviceInfo.constEnd()) + { + listDevice.append(iter.value().keys()); + ++iter; + } + strDeviceFilter = "'" + listDevice.join("', '") + "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); + } + + for(int nIndex(0); nIndex < listType.size(); nIndex++) + { + QString sqlSequenceQuery = QString("select tag_name,description,device,region_id from %1 where sub_system > 3 and ").arg(listType.at(nIndex)); + if(!strDeviceFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" %1 ORDER BY SEQ_NO asc;").arg(strDeviceFilter)); + } + + objReadDb.execute(sqlSequenceQuery, query); + while(query.next()) + { + const QString tagName = query.value(0).toString(); + const QString tagDesc = query.value(1).toString(); + const QString device = query.value(2).toString(); + m_devTagName[device].append(tagName); + m_tagInfo.insert(tagName, QStringList() << tagDesc << listType.at(nIndex)); + m_regionMap.insert(query.value(0).toString(), query.value(3).toInt()); + } + } +} + +void CDbInfoManage::loadUserInfo(kbd_dbms::CDbApi &objReadDb) +{ + QSqlQuery query; + QString sql = QString("select perm_id,perm_alias from rm_user_def"); + if(objReadDb.execute(sql,query)) + { + while (query.next()) { + int perm_id = query.value(0).toInt(); + QString perm_alias = query.value(1).toString(); + m_userInfo[perm_id] = perm_alias; + } + } +} + +void CDbInfoManage::loadShieldDefine(kbd_dbms::CDbApi &objReadDb) +{ + QSqlQuery query; + QString sql = QString("select shield_id,description,shield_prop from opt_shield_define"); + if(objReadDb.execute(sql,query)) + { + while (query.next()) { + int id = query.value(0).toInt(); + QString desc = query.value(1).toString(); + int value = query.value(2).toInt(); + m_shieldDefMap[id] = QPair(desc,value); + } + } +} + +void CDbInfoManage::loadShieldProperty(kbd_dbms::CDbApi &objReadDb) +{ + QSqlQuery query; + QString sql = QString("select actual_value,display_value from dict_menu_info where menu_name = '%1' ").arg("屏蔽属性"); + if(objReadDb.execute(sql,query)) + { + while (query.next()) { + int id = query.value(0).toInt(); + QString desc = query.value(1).toString(); + m_shieldPropertyMap[id] = desc; + } + } +} + +bool CDbInfoManage::getMaxId(int &timeId, int &shieldId) +{ + bool ret = false; + kbd_dbms::CDbApi readDb(DB_CONN_MODEL_READ); + if(!readDb.open()) + { + return false; + } + QSqlQuery query; + QString sql = QString("select max(time_id) from %1").arg("opt_shield_time"); + if(!readDb.execute(sql,query)) + { + return false; + } + while(query.next()) + { + timeId = query.value(0).toInt()+1; + ret = true; + } + if(!ret) + { + return false; + } + + QString sql1 = QString("select max(shield_id) from %1").arg("opt_shield_info"); + if(!readDb.execute(sql1,query)) + { + return false; + } + while(query.next()) + { + shieldId = query.value(0).toInt()+1; + return true; + } + return false; +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CDbInfoManage.h b/product/src/gui/plugin/AlarmShieldWidget/CDbInfoManage.h index e259e139..108e693b 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CDbInfoManage.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CDbInfoManage.h @@ -1,92 +1,92 @@ -#ifndef CDBINFOMANAGE_H -#define CDBINFOMANAGE_H - -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/db_api_ex/CDbApi.h" -#include "perm_mng_api/PermMngApi.h" -#include "CShieldinfo.h" - -class CDbInfoManage -{ -public: - static CDbInfoManage *instance(); - void destory(); - - QMap getLocationInfo(); - QString getLocationDesc(const int &location); - QString getLocationTag(const int &location); - int getLocationId(const QString &tag); - QList getLocationList(); - QMap getDevGroup(const int &location); - QList > getDevGroupInfoList(const int& location); - - QMap getDevice(const QString &devGroup); - QStringList getTagList(const QString &device); - QString getTagDesc(const QString &tagName); - QString getTagType(const QString &tagName); - QString getUserAlias(const int &userId); - int getRegionId(const QString &tag); - - QMap > getShieldDefInfo(); - QString getShieldDef(const int &type); - int getShieldProp(const int &type); - QMap getShieldPropMap(); - bool loadShieldObj(const int &shieldId, QList &objList); - bool loadShieldObj(const QStringList &objList, QMap > &objMap); - bool loadShieldInfo(const QList &objList, QList &infoList); - bool multiShield(const QList &shieldId); - bool multiUnShield(const QList &shieldId); - bool multiDelShield(const QList &timeId, const QList &shieldId); - bool shield(const int &shieldId); - bool unshield(const int &shieldId); - bool delShield(const int &timeId, const int &shieldId); - bool insertShield(const ST_Shield_Info &info, const QMap &objMap); - bool updateShield(const ST_Shield_Info &info, const QMap &preObjMap, const QMap &objMap); - - E_Shield_Mode getShieldMode(const E_Tree_ItemType &type); - E_Tree_ItemType getTreeItemType(const E_Shield_Mode &mode); - void getShieldKeyIdTag(const int &mode, const QString &obj, QString &mid); - QString getDoubleNumber(const int &number); - - void setOptPerm(ST_Shield_Obj &shiledObj); - bool checkOptPerm(const std::vector &vecRegionOptId, const std::vector &vecLocationId); - -private: - CDbInfoManage(); - void initPermMng(); - QString getJoinStr(const QList &list, char c); - - void loadRTLocation(); - void loadDevGroupInfo(kbd_dbms::CDbApi &objReadDb); - void loadDeviceInfo(kbd_dbms::CDbApi &objReadDb); - void loadPointInfo(kbd_dbms::CDbApi &objReadDb); - void loadUserInfo(kbd_dbms::CDbApi &objReadDb); - void loadShieldDefine(kbd_dbms::CDbApi &objReadDb); - void loadShieldProperty(kbd_dbms::CDbApi &objReadDb); - - bool getMaxId(int &timeId, int &shieldId); - -private: - static CDbInfoManage * m_pInstance; - kbd_service::CPermMngApiPtr m_ptrPermMng; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CDbApi *m_pWriteDb; - QMap m_regionMap; - QMap m_locationInfo; - QMap m_locationTag; - QList m_locationList; //< location_id: 按location_no排序 - QMap > m_devGroupInfo; - QMap > > m_devGroupInfoMap; - QMap > m_deviceInfo; - QMap m_devTagName; - QHash m_tagInfo; - //< 用户相关 - QMap m_userInfo; - std::vector m_vecRegionOptId; - std::vector m_vecLocationOptId; - //< 屏蔽相关 - QMap > m_shieldDefMap; - QMap m_shieldPropertyMap; -}; - -#endif // CDBINFOMANAGE_H +#ifndef CDBINFOMANAGE_H +#define CDBINFOMANAGE_H + +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "CShieldinfo.h" + +class CDbInfoManage +{ +public: + static CDbInfoManage *instance(); + void destory(); + + QMap getLocationInfo(); + QString getLocationDesc(const int &location); + QString getLocationTag(const int &location); + int getLocationId(const QString &tag); + QList getLocationList(); + QMap getDevGroup(const int &location); + QList > getDevGroupInfoList(const int& location); + + QMap getDevice(const QString &devGroup); + QStringList getTagList(const QString &device); + QString getTagDesc(const QString &tagName); + QString getTagType(const QString &tagName); + QString getUserAlias(const int &userId); + int getRegionId(const QString &tag); + + QMap > getShieldDefInfo(); + QString getShieldDef(const int &type); + int getShieldProp(const int &type); + QMap getShieldPropMap(); + bool loadShieldObj(const int &shieldId, QList &objList); + bool loadShieldObj(const QStringList &objList, QMap > &objMap); + bool loadShieldInfo(const QList &objList, QList &infoList); + bool multiShield(const QList &shieldId); + bool multiUnShield(const QList &shieldId); + bool multiDelShield(const QList &timeId, const QList &shieldId); + bool shield(const int &shieldId); + bool unshield(const int &shieldId); + bool delShield(const int &timeId, const int &shieldId); + bool insertShield(const ST_Shield_Info &info, const QMap &objMap); + bool updateShield(const ST_Shield_Info &info, const QMap &preObjMap, const QMap &objMap); + + E_Shield_Mode getShieldMode(const E_Tree_ItemType &type); + E_Tree_ItemType getTreeItemType(const E_Shield_Mode &mode); + void getShieldKeyIdTag(const int &mode, const QString &obj, QString &mid); + QString getDoubleNumber(const int &number); + + void setOptPerm(ST_Shield_Obj &shiledObj); + bool checkOptPerm(const std::vector &vecRegionOptId, const std::vector &vecLocationId); + +private: + CDbInfoManage(); + void initPermMng(); + QString getJoinStr(const QList &list, char c); + + void loadRTLocation(); + void loadDevGroupInfo(kbd_dbms::CDbApi &objReadDb); + void loadDeviceInfo(kbd_dbms::CDbApi &objReadDb); + void loadPointInfo(kbd_dbms::CDbApi &objReadDb); + void loadUserInfo(kbd_dbms::CDbApi &objReadDb); + void loadShieldDefine(kbd_dbms::CDbApi &objReadDb); + void loadShieldProperty(kbd_dbms::CDbApi &objReadDb); + + bool getMaxId(int &timeId, int &shieldId); + +private: + static CDbInfoManage * m_pInstance; + kbd_service::CPermMngApiPtr m_ptrPermMng; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CDbApi *m_pWriteDb; + QMap m_regionMap; + QMap m_locationInfo; + QMap m_locationTag; + QList m_locationList; //< location_id: 按location_no排序 + QMap > m_devGroupInfo; + QMap > > m_devGroupInfoMap; + QMap > m_deviceInfo; + QMap m_devTagName; + QHash m_tagInfo; + //< 用户相关 + QMap m_userInfo; + std::vector m_vecRegionOptId; + std::vector m_vecLocationOptId; + //< 屏蔽相关 + QMap > m_shieldDefMap; + QMap m_shieldPropertyMap; +}; + +#endif // CDBINFOMANAGE_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.cpp b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.cpp index 3fa51678..0a2d324c 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.cpp @@ -1,299 +1,299 @@ -#include "CDevTreeModel.h" -#include "CDbInfoManage.h" -#include "CDevTreeView.h" - -CDevTreeModel::CDevTreeModel(QObject *parent, QTreeView *view, bool checkable) - : QAbstractItemModel(parent), - m_pRoot(Q_NULLPTR), - m_bCheckable(checkable), - m_curType(Item_Root_Type), - m_pView(view) -{ - -} - -CDevTreeModel::~CDevTreeModel() -{ - if(Q_NULLPTR != m_pRoot) - { - delete m_pRoot; - } - m_pRoot = Q_NULLPTR; -} - -void CDevTreeModel::updateTree(E_Tree_ItemType itemType) -{ - beginResetModel(); - - if(Q_NULLPTR != m_pRoot) - { - delete m_pRoot; - } - m_pRoot = new QTreeWidgetItem(Item_Root_Type); - m_curType = itemType; - - QList locationList = CDbInfoManage::instance()->getLocationList(); - foreach (const int locId, locationList) { - const QString locDesc = CDbInfoManage::instance()->getLocationDesc(locId); - QTreeWidgetItem *locItem = new QTreeWidgetItem(m_pRoot, Item_Location_Type); - locItem->setText(0, locDesc); - locItem->setData(0, Qt::UserRole, locId); - if(itemType <= Item_Location_Type) - continue; - QList > devGroupInfoList = CDbInfoManage::instance()->getDevGroupInfoList(locId); - for(int index(0);indexsetText(0, devGroupInfoList.at(index).second); - devgItem->setData(0, Qt::UserRole, devGroupInfoList.at(index).first); - if(itemType <= Item_DevGroup_Type) - continue; - const QMap &device = CDbInfoManage::instance()->getDevice(devGroupInfoList.at(index).first); - QMap::const_iterator devIter = device.constBegin(); - for(; devIter != device.constEnd(); devIter++) - { - QTreeWidgetItem *devItem = new QTreeWidgetItem(devgItem, Item_Device_Type); - devItem->setText(0, devIter.value()); - devItem->setData(0, Qt::UserRole, devIter.key()); - if(itemType <= Item_Device_Type) - continue; - const QStringList &pointList = CDbInfoManage::instance()->getTagList(devIter.key()); - for(int nIndex=0; nIndexsetText(0, CDbInfoManage::instance()->getTagDesc(pointList.at(nIndex))); - pointItem->setData(0, Qt::UserRole, pointList.at(nIndex)); - pointItem->setCheckState(0, Qt::Unchecked); - } - } - } - } - endResetModel(); - if(m_pView == Q_NULLPTR) - { - return; - } - for(int n=0; nchildCount(); n++) - { - m_pView->expand(index(n,0)); - } -} - -E_Tree_ItemType CDevTreeModel::currentType() -{ - return m_curType; -} - -QVariant CDevTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(role == Qt::DisplayRole) - { - if(orientation == Qt::Horizontal) - { - return QVariant(tr("位置/设备组/设备")); - } - } - - return QVariant(); -} - -QModelIndex CDevTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if(!hasIndex(row, column, parent) || Q_NULLPTR == m_pRoot) - { - return QModelIndex(); - } - - QTreeWidgetItem * parentItem; - if(!parent.isValid()) - { - parentItem = m_pRoot; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - if(parentItem) - { - QTreeWidgetItem *childItem = parentItem->child(row); - if(childItem) - { - return createIndex(row,0,childItem); - } - } - - return QModelIndex(); -} - -QModelIndex CDevTreeModel::parent(const QModelIndex &child) const -{ - if (!child.isValid()) - { - return QModelIndex(); - } - - QTreeWidgetItem *childItem = static_cast(child.internalPointer()); - if (!childItem) - { - return QModelIndex(); - } - - QTreeWidgetItem *parentItem = childItem->parent(); - - if (parentItem == m_pRoot) - { - return QModelIndex(); - } - - int row = parentItem->parent()->indexOfChild(parentItem); - return createIndex(row, 0, parentItem); -} - -int CDevTreeModel::rowCount(const QModelIndex &parent) const -{ - if(!parent.isValid()) - { - if (Q_NULLPTR != m_pRoot) - { - return m_pRoot->childCount(); - } - else - { - return 0; - } - } - else - { - QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); - } -} - -int CDevTreeModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return 1; -} - -QVariant CDevTreeModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid()) - return QVariant(); - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item) - { - if(m_bCheckable && item->type() == m_curType && Qt::CheckStateRole == role && 0 == index.column()) - { - return item->checkState(index.column()); - } - return item->data(index.column(), role); - } - return QVariant(); -} - -bool CDevTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if(!index.isValid()) - return false; - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item) - { - if(Qt::CheckStateRole == role && 0 == index.column() && item->type() == m_curType) - { - emit sigCheck(index.data(Qt::UserRole).toString(), E_Tree_ItemType(item->type()), value.toInt()); - } - item->setData(index.column(), role, value); - } - return true; -} - -Qt::ItemFlags CDevTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - if(index.column()== 0) - { - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item) - { - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; - } - } - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CDevTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state) -{ - if(!index.isValid()) - { - return; - } - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(!item) - { - return; - } - - int childCount = item->childCount(); - if(childCount <= 0) - { - return; - } - - for(int nChildIndex(0); nChildIndex < childCount; nChildIndex++) - { - setChildrenCheckState(this->index(nChildIndex, 0, index), state); - - if(item->child(nChildIndex)->type() != m_curType) - { - continue; - } - if(this->index(nChildIndex, 0, index).flags() != Qt::NoItemFlags) - { - setData(this->index(nChildIndex, 0, index), state, Qt::CheckStateRole); - emit sigCheck(this->index(nChildIndex, 0, index).data(Qt::UserRole).toString() - , E_Tree_ItemType(item->child(nChildIndex)->type()), int(state)); - } - } - m_pView->update(); -} - -void CDevTreeModel::slotUpdateTagCheckState(const QString &tag, const bool &checked) -{ - updateTagCheckState(tag, checked, m_pRoot); -} - -bool CDevTreeModel::updateTagCheckState(const QString &tag, const bool &checked, QTreeWidgetItem *item) -{ - if(!item) - { - return false; - } - - if(tag == item->data(0, Qt::UserRole).toString()) - { - item->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); - return true; - } - - int childCount = item->childCount(); - if(childCount <= 0) - { - return false; - } - - for(int nChildIndex(0); nChildIndex < childCount; nChildIndex++) - { - bool ret = updateTagCheckState(tag, checked, item->child(nChildIndex)); - if(ret) - { - return true; - } - } - return false; -} +#include "CDevTreeModel.h" +#include "CDbInfoManage.h" +#include "CDevTreeView.h" + +CDevTreeModel::CDevTreeModel(QObject *parent, QTreeView *view, bool checkable) + : QAbstractItemModel(parent), + m_pRoot(Q_NULLPTR), + m_bCheckable(checkable), + m_curType(Item_Root_Type), + m_pView(view) +{ + +} + +CDevTreeModel::~CDevTreeModel() +{ + if(Q_NULLPTR != m_pRoot) + { + delete m_pRoot; + } + m_pRoot = Q_NULLPTR; +} + +void CDevTreeModel::updateTree(E_Tree_ItemType itemType) +{ + beginResetModel(); + + if(Q_NULLPTR != m_pRoot) + { + delete m_pRoot; + } + m_pRoot = new QTreeWidgetItem(Item_Root_Type); + m_curType = itemType; + + QList locationList = CDbInfoManage::instance()->getLocationList(); + foreach (const int locId, locationList) { + const QString locDesc = CDbInfoManage::instance()->getLocationDesc(locId); + QTreeWidgetItem *locItem = new QTreeWidgetItem(m_pRoot, Item_Location_Type); + locItem->setText(0, locDesc); + locItem->setData(0, Qt::UserRole, locId); + if(itemType <= Item_Location_Type) + continue; + QList > devGroupInfoList = CDbInfoManage::instance()->getDevGroupInfoList(locId); + for(int index(0);indexsetText(0, devGroupInfoList.at(index).second); + devgItem->setData(0, Qt::UserRole, devGroupInfoList.at(index).first); + if(itemType <= Item_DevGroup_Type) + continue; + const QMap &device = CDbInfoManage::instance()->getDevice(devGroupInfoList.at(index).first); + QMap::const_iterator devIter = device.constBegin(); + for(; devIter != device.constEnd(); devIter++) + { + QTreeWidgetItem *devItem = new QTreeWidgetItem(devgItem, Item_Device_Type); + devItem->setText(0, devIter.value()); + devItem->setData(0, Qt::UserRole, devIter.key()); + if(itemType <= Item_Device_Type) + continue; + const QStringList &pointList = CDbInfoManage::instance()->getTagList(devIter.key()); + for(int nIndex=0; nIndexsetText(0, CDbInfoManage::instance()->getTagDesc(pointList.at(nIndex))); + pointItem->setData(0, Qt::UserRole, pointList.at(nIndex)); + pointItem->setCheckState(0, Qt::Unchecked); + } + } + } + } + endResetModel(); + if(m_pView == Q_NULLPTR) + { + return; + } + for(int n=0; nchildCount(); n++) + { + m_pView->expand(index(n,0)); + } +} + +E_Tree_ItemType CDevTreeModel::currentType() +{ + return m_curType; +} + +QVariant CDevTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(role == Qt::DisplayRole) + { + if(orientation == Qt::Horizontal) + { + return QVariant(tr("位置/设备组/设备")); + } + } + + return QVariant(); +} + +QModelIndex CDevTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_pRoot) + { + return QModelIndex(); + } + + QTreeWidgetItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_pRoot; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + QTreeWidgetItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,0,childItem); + } + } + + return QModelIndex(); +} + +QModelIndex CDevTreeModel::parent(const QModelIndex &child) const +{ + if (!child.isValid()) + { + return QModelIndex(); + } + + QTreeWidgetItem *childItem = static_cast(child.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + QTreeWidgetItem *parentItem = childItem->parent(); + + if (parentItem == m_pRoot) + { + return QModelIndex(); + } + + int row = parentItem->parent()->indexOfChild(parentItem); + return createIndex(row, 0, parentItem); +} + +int CDevTreeModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (Q_NULLPTR != m_pRoot) + { + return m_pRoot->childCount(); + } + else + { + return 0; + } + } + else + { + QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int CDevTreeModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return 1; +} + +QVariant CDevTreeModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(m_bCheckable && item->type() == m_curType && Qt::CheckStateRole == role && 0 == index.column()) + { + return item->checkState(index.column()); + } + return item->data(index.column(), role); + } + return QVariant(); +} + +bool CDevTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid()) + return false; + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(Qt::CheckStateRole == role && 0 == index.column() && item->type() == m_curType) + { + emit sigCheck(index.data(Qt::UserRole).toString(), E_Tree_ItemType(item->type()), value.toInt()); + } + item->setData(index.column(), role, value); + } + return true; +} + +Qt::ItemFlags CDevTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + if(index.column()== 0) + { + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + } + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CDevTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } + + int childCount = item->childCount(); + if(childCount <= 0) + { + return; + } + + for(int nChildIndex(0); nChildIndex < childCount; nChildIndex++) + { + setChildrenCheckState(this->index(nChildIndex, 0, index), state); + + if(item->child(nChildIndex)->type() != m_curType) + { + continue; + } + if(this->index(nChildIndex, 0, index).flags() != Qt::NoItemFlags) + { + setData(this->index(nChildIndex, 0, index), state, Qt::CheckStateRole); + emit sigCheck(this->index(nChildIndex, 0, index).data(Qt::UserRole).toString() + , E_Tree_ItemType(item->child(nChildIndex)->type()), int(state)); + } + } + m_pView->update(); +} + +void CDevTreeModel::slotUpdateTagCheckState(const QString &tag, const bool &checked) +{ + updateTagCheckState(tag, checked, m_pRoot); +} + +bool CDevTreeModel::updateTagCheckState(const QString &tag, const bool &checked, QTreeWidgetItem *item) +{ + if(!item) + { + return false; + } + + if(tag == item->data(0, Qt::UserRole).toString()) + { + item->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); + return true; + } + + int childCount = item->childCount(); + if(childCount <= 0) + { + return false; + } + + for(int nChildIndex(0); nChildIndex < childCount; nChildIndex++) + { + bool ret = updateTagCheckState(tag, checked, item->child(nChildIndex)); + if(ret) + { + return true; + } + } + return false; +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.h b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.h index 0ab2f65c..c1663c51 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.h @@ -1,55 +1,55 @@ -#ifndef CDEVTREEMODEL_H -#define CDEVTREEMODEL_H - -#include -#include -#include -#include "CShieldinfo.h" - -class CDevTreeModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - CDevTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR, bool checkable = false); - ~CDevTreeModel(); - - void updateTree(E_Tree_ItemType itemType = Item_Device_Type); - - E_Tree_ItemType currentType(); - - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &child) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - void setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state); - -public slots: - void slotUpdateTagCheckState(const QString &tag, const bool &checked); - -private: - bool updateTagCheckState(const QString &tag, const bool &checked, QTreeWidgetItem * item); - -signals: - void sigCheck(const QString &objTag, const E_Tree_ItemType &type, const int &checkState); - -private: - QTreeWidgetItem * m_pRoot; - bool m_bCheckable; - E_Tree_ItemType m_curType; - QTreeView *m_pView; -}; - -#endif // CDEVTREEMODEL_H +#ifndef CDEVTREEMODEL_H +#define CDEVTREEMODEL_H + +#include +#include +#include +#include "CShieldinfo.h" + +class CDevTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + CDevTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR, bool checkable = false); + ~CDevTreeModel(); + + void updateTree(E_Tree_ItemType itemType = Item_Device_Type); + + E_Tree_ItemType currentType(); + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state); + +public slots: + void slotUpdateTagCheckState(const QString &tag, const bool &checked); + +private: + bool updateTagCheckState(const QString &tag, const bool &checked, QTreeWidgetItem * item); + +signals: + void sigCheck(const QString &objTag, const E_Tree_ItemType &type, const int &checkState); + +private: + QTreeWidgetItem * m_pRoot; + bool m_bCheckable; + E_Tree_ItemType m_curType; + QTreeView *m_pView; +}; + +#endif // CDEVTREEMODEL_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeView.cpp b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeView.cpp index db34150e..c26a1083 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeView.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeView.cpp @@ -1,126 +1,126 @@ -#include "CDevTreeView.h" -#include "CDevTreeModel.h" -#include -#include - -CDevTreeView::CDevTreeView(QWidget *parent) - : QTreeView(parent) -{ - -} - -void CDevTreeView::filter(const QString &text) -{ - CDevTreeModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR == pModel) - { - return; - } - for(int nIndex(0); nIndexrowCount(); nIndex++) - { - filter(pModel->index(nIndex, 0), pModel, text); - } -} - -void CDevTreeView::setShowCheckedOnly(bool checked) -{ - CDevTreeModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR == pModel) - { - return; - } - for(int nIndex(0); nIndexrowCount(); nIndex++) - { - setShowCheckedOnly(pModel->index(nIndex, 0), pModel, checked); - } -} - -bool CDevTreeView::filter(const QModelIndex &curIndex, CDevTreeModel *pModel, const QString &text) -{ - bool isHidden = true; - QString temp = pModel->data(curIndex).toString(); - if(text.isEmpty() || temp.contains(text)) - { - setAllChildShow(curIndex, pModel); - isHidden = false; - } - else - { - if(pModel->rowCount(curIndex) > 0) - { - for(int nIndex(0); nIndexrowCount(curIndex); nIndex++) - { - if(!filter(pModel->index(nIndex, 0, curIndex), pModel, text)) - { - isHidden = false; - } - } - } - else - { - isHidden = true; - } - } - - setRowHidden(curIndex.row(), pModel->parent(curIndex), isHidden); - return isHidden; -} - -bool CDevTreeView::setShowCheckedOnly(const QModelIndex &curIndex, CDevTreeModel *pModel, bool checked) -{ - bool isHidden = true; - if(pModel->rowCount(curIndex) > 0) - { - for(int nIndex(0); nIndexrowCount(curIndex); nIndex++) - { - if(!setShowCheckedOnly(pModel->index(nIndex, 0, curIndex), pModel, checked)) - { - isHidden = false; - } - } - } - else - { - if(checked && pModel->data(curIndex, Qt::CheckStateRole).toInt() == Qt::Unchecked) - { - isHidden = true; - } - else - { - isHidden = false; - } - } - setRowHidden(curIndex.row(), pModel->parent(curIndex), isHidden); - return isHidden; -} - -void CDevTreeView::setAllChildShow(const QModelIndex &parent, CDevTreeModel *pModel) -{ - int childCount = pModel->rowCount(parent); - for(int nIndex(0); nIndex < childCount; nIndex++) - { - setRowHidden(nIndex, parent, false); - setAllChildShow(pModel->index(nIndex, 0, parent), pModel); - } -} - -void CDevTreeView::contextMenuEvent(QContextMenuEvent *event) -{ - CDevTreeModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR != pModel) - { - if(pModel->currentType() == Item_Location_Type) - { - return; - } - QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); - if(Q_NULLPTR != pItem) - { - QMenu menu; - menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); - menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Unchecked); }); - menu.exec(event->globalPos()); - } - } - return; -} +#include "CDevTreeView.h" +#include "CDevTreeModel.h" +#include +#include + +CDevTreeView::CDevTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} + +void CDevTreeView::filter(const QString &text) +{ + CDevTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR == pModel) + { + return; + } + for(int nIndex(0); nIndexrowCount(); nIndex++) + { + filter(pModel->index(nIndex, 0), pModel, text); + } +} + +void CDevTreeView::setShowCheckedOnly(bool checked) +{ + CDevTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR == pModel) + { + return; + } + for(int nIndex(0); nIndexrowCount(); nIndex++) + { + setShowCheckedOnly(pModel->index(nIndex, 0), pModel, checked); + } +} + +bool CDevTreeView::filter(const QModelIndex &curIndex, CDevTreeModel *pModel, const QString &text) +{ + bool isHidden = true; + QString temp = pModel->data(curIndex).toString(); + if(text.isEmpty() || temp.contains(text)) + { + setAllChildShow(curIndex, pModel); + isHidden = false; + } + else + { + if(pModel->rowCount(curIndex) > 0) + { + for(int nIndex(0); nIndexrowCount(curIndex); nIndex++) + { + if(!filter(pModel->index(nIndex, 0, curIndex), pModel, text)) + { + isHidden = false; + } + } + } + else + { + isHidden = true; + } + } + + setRowHidden(curIndex.row(), pModel->parent(curIndex), isHidden); + return isHidden; +} + +bool CDevTreeView::setShowCheckedOnly(const QModelIndex &curIndex, CDevTreeModel *pModel, bool checked) +{ + bool isHidden = true; + if(pModel->rowCount(curIndex) > 0) + { + for(int nIndex(0); nIndexrowCount(curIndex); nIndex++) + { + if(!setShowCheckedOnly(pModel->index(nIndex, 0, curIndex), pModel, checked)) + { + isHidden = false; + } + } + } + else + { + if(checked && pModel->data(curIndex, Qt::CheckStateRole).toInt() == Qt::Unchecked) + { + isHidden = true; + } + else + { + isHidden = false; + } + } + setRowHidden(curIndex.row(), pModel->parent(curIndex), isHidden); + return isHidden; +} + +void CDevTreeView::setAllChildShow(const QModelIndex &parent, CDevTreeModel *pModel) +{ + int childCount = pModel->rowCount(parent); + for(int nIndex(0); nIndex < childCount; nIndex++) + { + setRowHidden(nIndex, parent, false); + setAllChildShow(pModel->index(nIndex, 0, parent), pModel); + } +} + +void CDevTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CDevTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + if(pModel->currentType() == Item_Location_Type) + { + return; + } + QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if(Q_NULLPTR != pItem) + { + QMenu menu; + menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); + menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Unchecked); }); + menu.exec(event->globalPos()); + } + } + return; +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeView.h b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeView.h index 196d2919..b3e7d12d 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeView.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeView.h @@ -1,30 +1,30 @@ -#ifndef CDEVTREEVIEW_H -#define CDEVTREEVIEW_H - -#include - -class CDevTreeModel; -class CDevTreeView : public QTreeView -{ - Q_OBJECT - -public: - CDevTreeView(QWidget *parent = Q_NULLPTR); - - void filter(const QString &text); - - void setShowCheckedOnly(bool checked); - -private: - bool filter(const QModelIndex &curIndex, CDevTreeModel *pModel, const QString &text); - - bool setShowCheckedOnly(const QModelIndex &curIndex, CDevTreeModel *pModel, bool checked); - - void setAllChildShow(const QModelIndex &parent, CDevTreeModel *pModel); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - -}; - -#endif // CDEVTREEVIEW_H +#ifndef CDEVTREEVIEW_H +#define CDEVTREEVIEW_H + +#include + +class CDevTreeModel; +class CDevTreeView : public QTreeView +{ + Q_OBJECT + +public: + CDevTreeView(QWidget *parent = Q_NULLPTR); + + void filter(const QString &text); + + void setShowCheckedOnly(bool checked); + +private: + bool filter(const QModelIndex &curIndex, CDevTreeModel *pModel, const QString &text); + + bool setShowCheckedOnly(const QModelIndex &curIndex, CDevTreeModel *pModel, bool checked); + + void setAllChildShow(const QModelIndex &parent, CDevTreeModel *pModel); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +}; + +#endif // CDEVTREEVIEW_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CHeaderView.cpp b/product/src/gui/plugin/AlarmShieldWidget/CHeaderView.cpp index 25e69e4e..477cb075 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CHeaderView.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CHeaderView.cpp @@ -1,83 +1,83 @@ -#include "CHeaderView.h" -#include -#include -#include -#include "pub_utility_api/FileUtil.h" - -CHeaderView::CHeaderView(QWidget *parent, int nAddCheckBoxColumn): - QHeaderView(Qt::Horizontal, parent), - m_bChecked(false) -{ - m_indicatorCheck = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/ckb-select.png").c_str(); - m_indicatorUnCheck = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/unchecked.png").c_str(); - - setSectionsClickable(true); - connect(this, SIGNAL(sectionClicked(int)), this, SLOT(onHeaderClicked(int))); - m_nAddCheckBoxColumn = nAddCheckBoxColumn; -} - -QString CHeaderView::plotIndicatorCheck() -{ - return m_indicatorCheck; -} - -void CHeaderView::setPlotIndicatorCheck(const QString &url) -{ - m_indicatorCheck = url; -} - -QString CHeaderView::plotIndicatorUnCheck() -{ - return m_indicatorUnCheck; -} - -void CHeaderView::setPlotIndicatorUnCheck(const QString &url) -{ - m_indicatorUnCheck = url; -} - -void CHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const -{ - painter->save(); - QHeaderView::paintSection(painter,rect,logicalIndex); - painter->restore(); - - if(logicalIndex == m_nAddCheckBoxColumn) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - QRect rc(rect.left()+(rect.width()-20)/2,rect.top()+(rect.height()-20)/2,20,20); - button.rect = rc; - QString file; - if(m_bChecked) - { - file = m_indicatorCheck; - }else - { - file = m_indicatorUnCheck; - } - - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(file); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } -} - -void CHeaderView::onHeaderClicked(int index) -{ - if(index == m_nAddCheckBoxColumn) - { - m_bChecked = !m_bChecked; - this->repaint(); - emit sigColumnCheck(0, m_bChecked); - } -} - -void CHeaderView::clearCheck() -{ - m_bChecked = false; - emit sigColumnCheck(0, m_bChecked); -} +#include "CHeaderView.h" +#include +#include +#include +#include "pub_utility_api/FileUtil.h" + +CHeaderView::CHeaderView(QWidget *parent, int nAddCheckBoxColumn): + QHeaderView(Qt::Horizontal, parent), + m_bChecked(false) +{ + m_indicatorCheck = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/ckb-select.png").c_str(); + m_indicatorUnCheck = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/unchecked.png").c_str(); + + setSectionsClickable(true); + connect(this, SIGNAL(sectionClicked(int)), this, SLOT(onHeaderClicked(int))); + m_nAddCheckBoxColumn = nAddCheckBoxColumn; +} + +QString CHeaderView::plotIndicatorCheck() +{ + return m_indicatorCheck; +} + +void CHeaderView::setPlotIndicatorCheck(const QString &url) +{ + m_indicatorCheck = url; +} + +QString CHeaderView::plotIndicatorUnCheck() +{ + return m_indicatorUnCheck; +} + +void CHeaderView::setPlotIndicatorUnCheck(const QString &url) +{ + m_indicatorUnCheck = url; +} + +void CHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const +{ + painter->save(); + QHeaderView::paintSection(painter,rect,logicalIndex); + painter->restore(); + + if(logicalIndex == m_nAddCheckBoxColumn) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + QRect rc(rect.left()+(rect.width()-20)/2,rect.top()+(rect.height()-20)/2,20,20); + button.rect = rc; + QString file; + if(m_bChecked) + { + file = m_indicatorCheck; + }else + { + file = m_indicatorUnCheck; + } + + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } +} + +void CHeaderView::onHeaderClicked(int index) +{ + if(index == m_nAddCheckBoxColumn) + { + m_bChecked = !m_bChecked; + this->repaint(); + emit sigColumnCheck(0, m_bChecked); + } +} + +void CHeaderView::clearCheck() +{ + m_bChecked = false; + emit sigColumnCheck(0, m_bChecked); +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CHeaderView.h b/product/src/gui/plugin/AlarmShieldWidget/CHeaderView.h index 05a5fc52..ba4f3ed0 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CHeaderView.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CHeaderView.h @@ -1,38 +1,38 @@ -#ifndef CHEADERVIEW_H -#define CHEADERVIEW_H - -#include - -class CHeaderView : public QHeaderView -{ - Q_OBJECT - Q_PROPERTY(QString plotIndicatorCheck READ plotIndicatorCheck WRITE setPlotIndicatorCheck) - Q_PROPERTY(QString plotIndicatorUnCheck READ plotIndicatorUnCheck WRITE setPlotIndicatorUnCheck) - -public: - CHeaderView(QWidget *parent = 0, int nAddCheckBoxColumn = 0); - - QString plotIndicatorCheck(); - void setPlotIndicatorCheck(const QString &url); - - QString plotIndicatorUnCheck(); - void setPlotIndicatorUnCheck(const QString &url); - -signals: - void sigColumnCheck(int logicalIndex, bool bChecked); - -protected: - void paintSection(QPainter *painter, const QRect &rect , int logicalIndex) const override; - -public slots: - void onHeaderClicked(int index); - void clearCheck(); - -private: - QString m_indicatorCheck; - QString m_indicatorUnCheck; - bool m_bChecked; - int m_nAddCheckBoxColumn; -}; - -#endif // CHEADERVIEW_H +#ifndef CHEADERVIEW_H +#define CHEADERVIEW_H + +#include + +class CHeaderView : public QHeaderView +{ + Q_OBJECT + Q_PROPERTY(QString plotIndicatorCheck READ plotIndicatorCheck WRITE setPlotIndicatorCheck) + Q_PROPERTY(QString plotIndicatorUnCheck READ plotIndicatorUnCheck WRITE setPlotIndicatorUnCheck) + +public: + CHeaderView(QWidget *parent = 0, int nAddCheckBoxColumn = 0); + + QString plotIndicatorCheck(); + void setPlotIndicatorCheck(const QString &url); + + QString plotIndicatorUnCheck(); + void setPlotIndicatorUnCheck(const QString &url); + +signals: + void sigColumnCheck(int logicalIndex, bool bChecked); + +protected: + void paintSection(QPainter *painter, const QRect &rect , int logicalIndex) const override; + +public slots: + void onHeaderClicked(int index); + void clearCheck(); + +private: + QString m_indicatorCheck; + QString m_indicatorUnCheck; + bool m_bChecked; + int m_nAddCheckBoxColumn; +}; + +#endif // CHEADERVIEW_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CShieldTableDelegate.cpp b/product/src/gui/plugin/AlarmShieldWidget/CShieldTableDelegate.cpp index 6223d346..efad7b18 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CShieldTableDelegate.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CShieldTableDelegate.cpp @@ -1,150 +1,150 @@ -#include "CShieldTableDelegate.h" -#include "CShieldTableModel.h" -#include "CDbInfoManage.h" -#include -#include -#include -#include - -CShieldTableDelegate::CShieldTableDelegate(CShieldTableModel *model, QObject *parent) - : QStyledItemDelegate(parent), - m_pModel(model), - m_buttonBack(Qt::white), - m_buttonColor(Qt::black) -{ - -} - -void CShieldTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QStyledItemDelegate::paint(painter, option, index); - - ST_Shield_Info &info = m_pModel->getInfo(index.row()); - - QString delText = tr("删除"); - QString optText; - if(info.m_shieldEnable == Shiled_Disable) - { - optText = tr("启用"); - } - else - { - optText = tr("取消"); - } - QRect optRect = option.rect.adjusted(option.rect.width()/2-62,2,-(option.rect.width()/2+2),-2); - QRect delRect = option.rect.adjusted(option.rect.width()/2+2,2,-(option.rect.width()/2-62),-2); - QPalette palette; - palette.setColor(QPalette::Text, m_buttonColor); - - painter->save(); - painter->setPen(m_buttonColor); - painter->setBrush(m_buttonBack); - painter->drawRect(optRect); - painter->drawRect(delRect); - QApplication::style()->drawItemText(painter, optRect, Qt::AlignCenter, palette, true, optText); - QApplication::style()->drawItemText(painter, delRect, Qt::AlignCenter, palette, true, delText); - painter->restore(); -} - -bool CShieldTableDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent && mouseEvent->type() == QEvent::MouseButtonRelease) - { - ST_Shield_Info &info = m_pModel->getInfo(index.row()); - if(info.m_perm) - { - QRect optRect = option.rect.adjusted(option.rect.width()/2-62,2,-(option.rect.width()/2+2),-2); - QRect delRect = option.rect.adjusted(option.rect.width()/2+2,2,-(option.rect.width()/2-62),-2); - - if(optRect.contains(mouseEvent->pos())) - { - if(info.m_shieldEnable == Shiled_Disable) - { - shield(info); - } - else - { - unshield(info); - } - } - else if(delRect.contains(mouseEvent->pos())) - { - delShield(info); - } - } - else - { - QMessageBox::information(0, tr("提示"), tr("当前用户无标签设置功能权限!")); - } - } - - return QStyledItemDelegate::editorEvent(event, model, option, index); -} - -QColor CShieldTableDelegate::buttonBackground() -{ - return m_buttonBack; -} - -void CShieldTableDelegate::setButtonBackground(const QColor &color) -{ - m_buttonBack = color; -} - -QColor CShieldTableDelegate::buttonColor() -{ - return m_buttonColor; -} - -void CShieldTableDelegate::setButtonColor(const QColor &color) -{ - m_buttonColor = color; -} - -void CShieldTableDelegate::shield(ST_Shield_Info &info) -{ -// qint64 endTime = QDateTime::fromString(info.m_endTime, "yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); -// qint64 curTime = QDateTime::currentMSecsSinceEpoch(); -// if(endTime < curTime) -// { -// QMessageBox::information(0, tr("提示"), tr("屏蔽时段已过期!")); -// return; -// } - - bool isSuccess = CDbInfoManage::instance()->shield(info.m_shieldId); - if(isSuccess) - { - info.m_shieldEnable = Shiled_Enable; - } - m_pModel->updateEnable(); -} - -void CShieldTableDelegate::unshield(ST_Shield_Info &info) -{ - bool isSuccess = CDbInfoManage::instance()->unshield(info.m_shieldId); - if(isSuccess) - { - info.m_shieldEnable = Shiled_Disable; - } - m_pModel->updateEnable(); -} - -void CShieldTableDelegate::delShield(ST_Shield_Info &info) -{ - if(info.m_shieldEnable == Shiled_Enable) - { - QMessageBox::information(0, tr("提示"), tr("请先取消屏蔽!")); - return; - } - bool isSuccess = CDbInfoManage::instance()->delShield(info.m_timeId, info.m_shieldId); - if(isSuccess) - { -// QMessageBox::information(0, tr("提示"), tr("删除成功!")); - m_pModel->deleteShield(info.m_shieldId); - } - else - { - QMessageBox::information(0, tr("提示"), tr("删除失败!")); - } -} +#include "CShieldTableDelegate.h" +#include "CShieldTableModel.h" +#include "CDbInfoManage.h" +#include +#include +#include +#include + +CShieldTableDelegate::CShieldTableDelegate(CShieldTableModel *model, QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(model), + m_buttonBack(Qt::white), + m_buttonColor(Qt::black) +{ + +} + +void CShieldTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter, option, index); + + ST_Shield_Info &info = m_pModel->getInfo(index.row()); + + QString delText = tr("删除"); + QString optText; + if(info.m_shieldEnable == Shiled_Disable) + { + optText = tr("启用"); + } + else + { + optText = tr("取消"); + } + QRect optRect = option.rect.adjusted(option.rect.width()/2-62,2,-(option.rect.width()/2+2),-2); + QRect delRect = option.rect.adjusted(option.rect.width()/2+2,2,-(option.rect.width()/2-62),-2); + QPalette palette; + palette.setColor(QPalette::Text, m_buttonColor); + + painter->save(); + painter->setPen(m_buttonColor); + painter->setBrush(m_buttonBack); + painter->drawRect(optRect); + painter->drawRect(delRect); + QApplication::style()->drawItemText(painter, optRect, Qt::AlignCenter, palette, true, optText); + QApplication::style()->drawItemText(painter, delRect, Qt::AlignCenter, palette, true, delText); + painter->restore(); +} + +bool CShieldTableDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent && mouseEvent->type() == QEvent::MouseButtonRelease) + { + ST_Shield_Info &info = m_pModel->getInfo(index.row()); + if(info.m_perm) + { + QRect optRect = option.rect.adjusted(option.rect.width()/2-62,2,-(option.rect.width()/2+2),-2); + QRect delRect = option.rect.adjusted(option.rect.width()/2+2,2,-(option.rect.width()/2-62),-2); + + if(optRect.contains(mouseEvent->pos())) + { + if(info.m_shieldEnable == Shiled_Disable) + { + shield(info); + } + else + { + unshield(info); + } + } + else if(delRect.contains(mouseEvent->pos())) + { + delShield(info); + } + } + else + { + QMessageBox::information(0, tr("提示"), tr("当前用户无标签设置功能权限!")); + } + } + + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +QColor CShieldTableDelegate::buttonBackground() +{ + return m_buttonBack; +} + +void CShieldTableDelegate::setButtonBackground(const QColor &color) +{ + m_buttonBack = color; +} + +QColor CShieldTableDelegate::buttonColor() +{ + return m_buttonColor; +} + +void CShieldTableDelegate::setButtonColor(const QColor &color) +{ + m_buttonColor = color; +} + +void CShieldTableDelegate::shield(ST_Shield_Info &info) +{ +// qint64 endTime = QDateTime::fromString(info.m_endTime, "yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); +// qint64 curTime = QDateTime::currentMSecsSinceEpoch(); +// if(endTime < curTime) +// { +// QMessageBox::information(0, tr("提示"), tr("屏蔽时段已过期!")); +// return; +// } + + bool isSuccess = CDbInfoManage::instance()->shield(info.m_shieldId); + if(isSuccess) + { + info.m_shieldEnable = Shiled_Enable; + } + m_pModel->updateEnable(); +} + +void CShieldTableDelegate::unshield(ST_Shield_Info &info) +{ + bool isSuccess = CDbInfoManage::instance()->unshield(info.m_shieldId); + if(isSuccess) + { + info.m_shieldEnable = Shiled_Disable; + } + m_pModel->updateEnable(); +} + +void CShieldTableDelegate::delShield(ST_Shield_Info &info) +{ + if(info.m_shieldEnable == Shiled_Enable) + { + QMessageBox::information(0, tr("提示"), tr("请先取消屏蔽!")); + return; + } + bool isSuccess = CDbInfoManage::instance()->delShield(info.m_timeId, info.m_shieldId); + if(isSuccess) + { +// QMessageBox::information(0, tr("提示"), tr("删除成功!")); + m_pModel->deleteShield(info.m_shieldId); + } + else + { + QMessageBox::information(0, tr("提示"), tr("删除失败!")); + } +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CShieldTableDelegate.h b/product/src/gui/plugin/AlarmShieldWidget/CShieldTableDelegate.h index 1187e6af..959cbf15 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CShieldTableDelegate.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CShieldTableDelegate.h @@ -1,38 +1,38 @@ -#ifndef CSHIELDTABLEDELEGATE_H -#define CSHIELDTABLEDELEGATE_H - -#include -#include "CShieldinfo.h" - -class CShieldTableModel; -class CShieldTableDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CShieldTableDelegate(CShieldTableModel *model, QObject *parent = 0); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; - - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; - - QColor buttonBackground(); - void setButtonBackground(const QColor &color); - - QColor buttonColor(); - void setButtonColor(const QColor &color); - -private: - void shield(ST_Shield_Info &info); - - void unshield(ST_Shield_Info &info); - - void delShield(ST_Shield_Info &info); - -private: - CShieldTableModel * m_pModel; - QColor m_buttonBack; - QColor m_buttonColor; -}; - -#endif // CSHIELDTABLEDELEGATE_H +#ifndef CSHIELDTABLEDELEGATE_H +#define CSHIELDTABLEDELEGATE_H + +#include +#include "CShieldinfo.h" + +class CShieldTableModel; +class CShieldTableDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CShieldTableDelegate(CShieldTableModel *model, QObject *parent = 0); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; + + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; + + QColor buttonBackground(); + void setButtonBackground(const QColor &color); + + QColor buttonColor(); + void setButtonColor(const QColor &color); + +private: + void shield(ST_Shield_Info &info); + + void unshield(ST_Shield_Info &info); + + void delShield(ST_Shield_Info &info); + +private: + CShieldTableModel * m_pModel; + QColor m_buttonBack; + QColor m_buttonColor; +}; + +#endif // CSHIELDTABLEDELEGATE_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CShieldTableModel.cpp b/product/src/gui/plugin/AlarmShieldWidget/CShieldTableModel.cpp index b16bd288..1ca65ccf 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CShieldTableModel.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CShieldTableModel.cpp @@ -1,401 +1,401 @@ -#include "CShieldTableModel.h" -#include "CDbInfoManage.h" - -CShieldTableModel::CShieldTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header<< tr("") - << tr("名称") - << tr("屏蔽类型") - << tr("屏蔽属性") - << tr("屏蔽模式") - << tr("是否启用") - << tr("时段类型") - << tr("屏蔽时段") - << tr("操作用户") - << tr("操作主机") - << tr("屏蔽描述") - << tr("操作"); -} - -QList &CShieldTableModel::getInfoList() -{ - return m_infoList; -} - -ST_Shield_Info &CShieldTableModel::getInfo(const int &index) -{ - return m_infoList[index]; -} - -void CShieldTableModel::reset(const QList > &shieldList) -{ - beginResetModel(); - - QStringList objTagList; - for(int nIndex=0; nIndexgetShieldKeyIdTag(shieldList[nIndex].first, shieldList[nIndex].second, mid); - if(mid.isEmpty()) - { - continue; - } - objTagList.append(mid); - if(shieldList[nIndex].first == Shield_Device) - { - objTagList.append(QString("MODE[%1]DEVPOINT[%2.") - .arg(CDbInfoManage::instance()->getDoubleNumber(Shield_Point)) - .arg(shieldList[nIndex].second)); - } - } - - CDbInfoManage::instance()->loadShieldObj(objTagList, m_objMap); - CDbInfoManage::instance()->loadShieldInfo(m_objMap.keys(), m_infoList); - setInfoPerm(); - - endResetModel(); -} - -void CShieldTableModel::updateEnable() -{ - QModelIndex topLeft = createIndex(0, COLUMN_ENABLE); - QModelIndex bottomRight = createIndex(rowCount() - 1, COLUMN_OPT); - emit dataChanged(topLeft, bottomRight); -} - -void CShieldTableModel::deleteShield(const int &shield_id) -{ - beginResetModel(); - - QList::iterator iter = m_infoList.begin(); - for(; iter != m_infoList.end(); iter++) - { - if((*iter).m_shieldId == shield_id) - { - m_infoList.erase(iter); - break; - } - } - - endResetModel(); -} - -void CShieldTableModel::deleteShield(const QList &shieldIdList) -{ - beginResetModel(); - - QList::iterator iter = m_infoList.begin(); - while(iter != m_infoList.end()) - { - if(shieldIdList.indexOf((*iter).m_shieldId) != -1) - { - iter = m_infoList.erase(iter); - continue; - } - iter++; - } - - endResetModel(); -} - -QVariant CShieldTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(role == Qt::DisplayRole) - { - if(orientation == Qt::Horizontal) - { - return QVariant(m_header.at(section)); - } - } - return QVariant(); -} - -int CShieldTableModel::rowCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_infoList.count(); -} - -int CShieldTableModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.count(); -} - -QVariant CShieldTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if(role == Qt::TextAlignmentRole) - { - if(index.column() == COLUMN_OPT) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - } - else - { - return QVariant(Qt::AlignCenter); - } - } - - if(role == Qt::CheckStateRole && index.column() == COLUMN_CHECK) - { - return m_infoList.at(index.row()).m_check ? Qt::Checked : Qt::Unchecked; - } - - if(role == Qt::UserRole && index.column() == COLUMN_SHIELD_MODE) - { - return m_objMap[m_infoList.at(index.row()).m_shieldId][0].m_shieldMode; - } - - if(role != Qt::DisplayRole) - { - return QVariant(); - } - - switch (index.column()) { - case COLUMN_CHECK: - { - return ""; - } - case COLUMN_NAME: - { - return m_infoList.at(index.row()).m_shieldName; - } - case COLUMN_SHIELD_TYPE: - { - return CDbInfoManage::instance()->getShieldDef(m_infoList.at(index.row()).m_shieldType); - } - case COLUMN_SHIELD_PROP: - { - int value = CDbInfoManage::instance()->getShieldProp(m_infoList.at(index.row()).m_shieldType); - QString text; - QMap proMap = CDbInfoManage::instance()->getShieldPropMap(); - QMap::const_iterator it= proMap.constBegin(); - while (it != proMap.constEnd()) { - if(value & 1<<(it.key())) - { - text += it.value(); - text += " "; - } - it++; - } - return text.trimmed(); - } - case COLUMN_SHIELD_MODE: - { - int value = m_objMap[m_infoList.at(index.row()).m_shieldId][0].m_shieldMode; - switch (value) { - case 1: - return tr("全站屏蔽"); - break; - case 2: - return tr("电压屏蔽"); - break; - case 3: - return tr("责任区屏蔽"); - break; - case 4: - return tr("设备组屏蔽"); - break; - case 5: - return tr("设备屏蔽"); - break; - case 6: - return tr("测点屏蔽"); - break; - default: - break; - } - return tr("未知"); - } - case COLUMN_ENABLE: - { - if(m_infoList.at(index.row()).m_timeType == 1) - { - qint64 endTime = QDateTime::fromString(m_infoList.at(index.row()).m_endTime, "yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); - qint64 curTime = QDateTime::currentMSecsSinceEpoch(); - if(endTime < curTime) - { - return tr("已过期"); - } - } - int value = m_infoList.at(index.row()).m_shieldEnable; - if(value == 1) - { - return tr("已启用"); - }else - { - return tr("未启用"); - } - } - case COLUMN_TIMETYPE: - { - int value = m_infoList.at(index.row()).m_timeType; - switch (value) { - case 1: - return tr("一次性屏蔽"); - break; - case 2: - return tr("每周"); - break; - case 3: - return tr("每月"); - break; - default: - break; - } - return tr("未知"); - } - case COLUMN_SHIELD_TIME: - { - QString text = "~"; - int timeType = m_infoList.at(index.row()).m_timeType; - int option_week = 0; - int option_mon = 0; - switch (timeType) { - case 1://一次性 - text = QString("%1~%2").arg(m_infoList.at(index.row()).m_startTime).arg(m_infoList.at(index.row()).m_endTime); - return text; - break; - case 2://每周 - text = tr("每周("); - option_week = m_infoList.at(index.row()).m_timeOption; - for(int index(1);index<8;index++) - { - if(option_week>>(index-1) & 0x0001) - { - text+=tr("%1 ").arg(index); - } - } - text += QString (") %1~%2").arg(m_infoList.at(index.row()).m_startTime).arg(m_infoList.at(index.row()).m_endTime); - return text; - break; - case 3://每月 - { - text = tr("每月("); - option_mon = m_infoList.at(index.row()).m_timeOption; - int firstDay = 0; - int endDay = 0; - for(int index(1);index<32;index++) - { - if(option_mon>>(index-1) & 0x0001) - { - if(firstDay == 0) - { - firstDay =index; - } - endDay = index; - } - } - if(firstDay == endDay) - { - text += QString("%1").arg(firstDay); - }else - { - text += QString("%1-%2").arg(firstDay).arg(endDay); - } - - text += QString (") %1~%2").arg(m_infoList.at(index.row()).m_startTime).arg(m_infoList.at(index.row()).m_endTime); - return text; - break; - } - default: - return text; - break; - } - } - case COLUMN_USER: - { - return CDbInfoManage::instance()->getUserAlias(m_infoList.at(index.row()).m_userId); - } - case COLUMN_HOSTNAME: - { - return m_infoList.at(index.row()).m_hostName; - } - case COLUMN_SHIELD_DESC: - { - return m_infoList.at(index.row()).m_shieldDesc; - } - case COLUMN_OPT: - { - return QVariant(); - } - default: - break; - } - - return QVariant(); -} - -bool CShieldTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if(!index.isValid()) - { - return false; - } - if(role == Qt::CheckStateRole && index.column() == COLUMN_CHECK) - { - m_infoList[index.row()].m_check = value.toBool(); - } - - return true; -} - -Qt::ItemFlags CShieldTableModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - if(index.column()== COLUMN_CHECK) - { - if(m_infoList[index.row()].m_perm) - { - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; - } - else - { - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; - } - } - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CShieldTableModel::slotColumnCheck(int logicalIndex, bool bChecked) -{ - if(logicalIndex != COLUMN_CHECK) - { - return ; - } - QList::iterator it = m_infoList.begin(); - while(it != m_infoList.end()) - { - if((*it).m_perm == true) - { - (*it).m_check = bChecked; - } - it++; - } - emit dataChanged(createIndex(0, COLUMN_CHECK), createIndex(rowCount()-1, COLUMN_CHECK)); -} - -void CShieldTableModel::setInfoPerm() -{ - for(int nIndex(0); nIndex &objList = m_objMap[info.m_shieldId]; - foreach (ST_Shield_Obj obj, objList) { - if(obj.m_perm == false) - { - info.m_perm = false; - } - } - } -} +#include "CShieldTableModel.h" +#include "CDbInfoManage.h" + +CShieldTableModel::CShieldTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header<< tr("") + << tr("名称") + << tr("屏蔽类型") + << tr("屏蔽属性") + << tr("屏蔽模式") + << tr("是否启用") + << tr("时段类型") + << tr("屏蔽时段") + << tr("操作用户") + << tr("操作主机") + << tr("屏蔽描述") + << tr("操作"); +} + +QList &CShieldTableModel::getInfoList() +{ + return m_infoList; +} + +ST_Shield_Info &CShieldTableModel::getInfo(const int &index) +{ + return m_infoList[index]; +} + +void CShieldTableModel::reset(const QList > &shieldList) +{ + beginResetModel(); + + QStringList objTagList; + for(int nIndex=0; nIndexgetShieldKeyIdTag(shieldList[nIndex].first, shieldList[nIndex].second, mid); + if(mid.isEmpty()) + { + continue; + } + objTagList.append(mid); + if(shieldList[nIndex].first == Shield_Device) + { + objTagList.append(QString("MODE[%1]DEVPOINT[%2.") + .arg(CDbInfoManage::instance()->getDoubleNumber(Shield_Point)) + .arg(shieldList[nIndex].second)); + } + } + + CDbInfoManage::instance()->loadShieldObj(objTagList, m_objMap); + CDbInfoManage::instance()->loadShieldInfo(m_objMap.keys(), m_infoList); + setInfoPerm(); + + endResetModel(); +} + +void CShieldTableModel::updateEnable() +{ + QModelIndex topLeft = createIndex(0, COLUMN_ENABLE); + QModelIndex bottomRight = createIndex(rowCount() - 1, COLUMN_OPT); + emit dataChanged(topLeft, bottomRight); +} + +void CShieldTableModel::deleteShield(const int &shield_id) +{ + beginResetModel(); + + QList::iterator iter = m_infoList.begin(); + for(; iter != m_infoList.end(); iter++) + { + if((*iter).m_shieldId == shield_id) + { + m_infoList.erase(iter); + break; + } + } + + endResetModel(); +} + +void CShieldTableModel::deleteShield(const QList &shieldIdList) +{ + beginResetModel(); + + QList::iterator iter = m_infoList.begin(); + while(iter != m_infoList.end()) + { + if(shieldIdList.indexOf((*iter).m_shieldId) != -1) + { + iter = m_infoList.erase(iter); + continue; + } + iter++; + } + + endResetModel(); +} + +QVariant CShieldTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(role == Qt::DisplayRole) + { + if(orientation == Qt::Horizontal) + { + return QVariant(m_header.at(section)); + } + } + return QVariant(); +} + +int CShieldTableModel::rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_infoList.count(); +} + +int CShieldTableModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.count(); +} + +QVariant CShieldTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if(role == Qt::TextAlignmentRole) + { + if(index.column() == COLUMN_OPT) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + } + else + { + return QVariant(Qt::AlignCenter); + } + } + + if(role == Qt::CheckStateRole && index.column() == COLUMN_CHECK) + { + return m_infoList.at(index.row()).m_check ? Qt::Checked : Qt::Unchecked; + } + + if(role == Qt::UserRole && index.column() == COLUMN_SHIELD_MODE) + { + return m_objMap[m_infoList.at(index.row()).m_shieldId][0].m_shieldMode; + } + + if(role != Qt::DisplayRole) + { + return QVariant(); + } + + switch (index.column()) { + case COLUMN_CHECK: + { + return ""; + } + case COLUMN_NAME: + { + return m_infoList.at(index.row()).m_shieldName; + } + case COLUMN_SHIELD_TYPE: + { + return CDbInfoManage::instance()->getShieldDef(m_infoList.at(index.row()).m_shieldType); + } + case COLUMN_SHIELD_PROP: + { + int value = CDbInfoManage::instance()->getShieldProp(m_infoList.at(index.row()).m_shieldType); + QString text; + QMap proMap = CDbInfoManage::instance()->getShieldPropMap(); + QMap::const_iterator it= proMap.constBegin(); + while (it != proMap.constEnd()) { + if(value & 1<<(it.key())) + { + text += it.value(); + text += " "; + } + it++; + } + return text.trimmed(); + } + case COLUMN_SHIELD_MODE: + { + int value = m_objMap[m_infoList.at(index.row()).m_shieldId][0].m_shieldMode; + switch (value) { + case 1: + return tr("全站屏蔽"); + break; + case 2: + return tr("电压屏蔽"); + break; + case 3: + return tr("责任区屏蔽"); + break; + case 4: + return tr("设备组屏蔽"); + break; + case 5: + return tr("设备屏蔽"); + break; + case 6: + return tr("测点屏蔽"); + break; + default: + break; + } + return tr("未知"); + } + case COLUMN_ENABLE: + { + if(m_infoList.at(index.row()).m_timeType == 1) + { + qint64 endTime = QDateTime::fromString(m_infoList.at(index.row()).m_endTime, "yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); + qint64 curTime = QDateTime::currentMSecsSinceEpoch(); + if(endTime < curTime) + { + return tr("已过期"); + } + } + int value = m_infoList.at(index.row()).m_shieldEnable; + if(value == 1) + { + return tr("已启用"); + }else + { + return tr("未启用"); + } + } + case COLUMN_TIMETYPE: + { + int value = m_infoList.at(index.row()).m_timeType; + switch (value) { + case 1: + return tr("一次性屏蔽"); + break; + case 2: + return tr("每周"); + break; + case 3: + return tr("每月"); + break; + default: + break; + } + return tr("未知"); + } + case COLUMN_SHIELD_TIME: + { + QString text = "~"; + int timeType = m_infoList.at(index.row()).m_timeType; + int option_week = 0; + int option_mon = 0; + switch (timeType) { + case 1://一次性 + text = QString("%1~%2").arg(m_infoList.at(index.row()).m_startTime).arg(m_infoList.at(index.row()).m_endTime); + return text; + break; + case 2://每周 + text = tr("每周("); + option_week = m_infoList.at(index.row()).m_timeOption; + for(int index(1);index<8;index++) + { + if(option_week>>(index-1) & 0x0001) + { + text+=tr("%1 ").arg(index); + } + } + text += QString (") %1~%2").arg(m_infoList.at(index.row()).m_startTime).arg(m_infoList.at(index.row()).m_endTime); + return text; + break; + case 3://每月 + { + text = tr("每月("); + option_mon = m_infoList.at(index.row()).m_timeOption; + int firstDay = 0; + int endDay = 0; + for(int index(1);index<32;index++) + { + if(option_mon>>(index-1) & 0x0001) + { + if(firstDay == 0) + { + firstDay =index; + } + endDay = index; + } + } + if(firstDay == endDay) + { + text += QString("%1").arg(firstDay); + }else + { + text += QString("%1-%2").arg(firstDay).arg(endDay); + } + + text += QString (") %1~%2").arg(m_infoList.at(index.row()).m_startTime).arg(m_infoList.at(index.row()).m_endTime); + return text; + break; + } + default: + return text; + break; + } + } + case COLUMN_USER: + { + return CDbInfoManage::instance()->getUserAlias(m_infoList.at(index.row()).m_userId); + } + case COLUMN_HOSTNAME: + { + return m_infoList.at(index.row()).m_hostName; + } + case COLUMN_SHIELD_DESC: + { + return m_infoList.at(index.row()).m_shieldDesc; + } + case COLUMN_OPT: + { + return QVariant(); + } + default: + break; + } + + return QVariant(); +} + +bool CShieldTableModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid()) + { + return false; + } + if(role == Qt::CheckStateRole && index.column() == COLUMN_CHECK) + { + m_infoList[index.row()].m_check = value.toBool(); + } + + return true; +} + +Qt::ItemFlags CShieldTableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + if(index.column()== COLUMN_CHECK) + { + if(m_infoList[index.row()].m_perm) + { + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + } + else + { + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + } + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CShieldTableModel::slotColumnCheck(int logicalIndex, bool bChecked) +{ + if(logicalIndex != COLUMN_CHECK) + { + return ; + } + QList::iterator it = m_infoList.begin(); + while(it != m_infoList.end()) + { + if((*it).m_perm == true) + { + (*it).m_check = bChecked; + } + it++; + } + emit dataChanged(createIndex(0, COLUMN_CHECK), createIndex(rowCount()-1, COLUMN_CHECK)); +} + +void CShieldTableModel::setInfoPerm() +{ + for(int nIndex(0); nIndex &objList = m_objMap[info.m_shieldId]; + foreach (ST_Shield_Obj obj, objList) { + if(obj.m_perm == false) + { + info.m_perm = false; + } + } + } +} diff --git a/product/src/gui/plugin/AlarmShieldWidget/CShieldTableModel.h b/product/src/gui/plugin/AlarmShieldWidget/CShieldTableModel.h index 8f37aa85..3d90b49f 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CShieldTableModel.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CShieldTableModel.h @@ -1,64 +1,64 @@ -#ifndef CSHIELDTABLEMODEL_H -#define CSHIELDTABLEMODEL_H - -#include -#include "CShieldinfo.h" - -enum EN_TABLE_COLUMN{ - COLUMN_CHECK = 0, - COLUMN_NAME, - COLUMN_SHIELD_TYPE, - COLUMN_SHIELD_PROP, - COLUMN_SHIELD_MODE, - COLUMN_ENABLE, - COLUMN_TIMETYPE, - COLUMN_SHIELD_TIME, - COLUMN_USER, - COLUMN_HOSTNAME, - COLUMN_SHIELD_DESC, - COLUMN_OPT -}; - -class CShieldTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - CShieldTableModel(QObject *parent = nullptr); - - QList &getInfoList(); - - ST_Shield_Info &getInfo(const int &index); - - void reset(const QList> &shieldList); - - void updateEnable(); - - void deleteShield(const int &shield_id); - - void deleteShield(const QList &shieldIdList); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - -public slots: - void slotColumnCheck(int logicalIndex, bool bChecked); - -private: - void setInfoPerm(); - -private: - QStringList m_header; - QMap > m_objMap; - QList m_infoList; -}; - -#endif // CSHIELDTABLEMODEL_H +#ifndef CSHIELDTABLEMODEL_H +#define CSHIELDTABLEMODEL_H + +#include +#include "CShieldinfo.h" + +enum EN_TABLE_COLUMN{ + COLUMN_CHECK = 0, + COLUMN_NAME, + COLUMN_SHIELD_TYPE, + COLUMN_SHIELD_PROP, + COLUMN_SHIELD_MODE, + COLUMN_ENABLE, + COLUMN_TIMETYPE, + COLUMN_SHIELD_TIME, + COLUMN_USER, + COLUMN_HOSTNAME, + COLUMN_SHIELD_DESC, + COLUMN_OPT +}; + +class CShieldTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + CShieldTableModel(QObject *parent = nullptr); + + QList &getInfoList(); + + ST_Shield_Info &getInfo(const int &index); + + void reset(const QList> &shieldList); + + void updateEnable(); + + void deleteShield(const int &shield_id); + + void deleteShield(const QList &shieldIdList); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + +public slots: + void slotColumnCheck(int logicalIndex, bool bChecked); + +private: + void setInfoPerm(); + +private: + QStringList m_header; + QMap > m_objMap; + QList m_infoList; +}; + +#endif // CSHIELDTABLEMODEL_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/CShieldinfo.h b/product/src/gui/plugin/AlarmShieldWidget/CShieldinfo.h index 711ff82a..085b58af 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CShieldinfo.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CShieldinfo.h @@ -1,67 +1,67 @@ -#ifndef CSHIELDINFO_H -#define CSHIELDINFO_H - -#include - -enum E_Tree_ItemType -{ - Item_Root_Type = 1001, - Item_Location_Type, - Item_DevGroup_Type, - Item_Device_Type, - Item_Point_Type, - Item_Voltage_Type, - Item_Region_Type -}; - -enum E_Shield_Mode -{ - Shield_Invalid = -1, - Shield_Location = 1, - Shield_Voltage, - Shield_Region, - Shield_DevGroup, - Shield_Device, - Shield_Point -}; - -enum E_Shiled_Enable -{ - Shiled_Disable = 0, - Shiled_Enable = 1 -}; - -struct ST_Shield_Obj -{ - int m_shieldId; - QString m_keyIdTag; - int m_shieldMode; - QString m_shieldObject; - bool m_perm; -}; - -struct ST_Shield_Info -{ - int m_shieldId; - QString m_shieldName; - int m_shieldType; - int m_shieldStatus; - int m_shieldEnable; - int m_timeId; - QString m_hostName; - int m_userId; - int m_timeType; - QString m_startTime; - QString m_endTime; - int m_timeOption; - QString m_shieldDesc; - - int m_location; - int m_subsystem; - int m_usergId; - int m_shieldTime; - bool m_check; - bool m_perm; -}; - -#endif // CSHIELDINFO_H +#ifndef CSHIELDINFO_H +#define CSHIELDINFO_H + +#include + +enum E_Tree_ItemType +{ + Item_Root_Type = 1001, + Item_Location_Type, + Item_DevGroup_Type, + Item_Device_Type, + Item_Point_Type, + Item_Voltage_Type, + Item_Region_Type +}; + +enum E_Shield_Mode +{ + Shield_Invalid = -1, + Shield_Location = 1, + Shield_Voltage, + Shield_Region, + Shield_DevGroup, + Shield_Device, + Shield_Point +}; + +enum E_Shiled_Enable +{ + Shiled_Disable = 0, + Shiled_Enable = 1 +}; + +struct ST_Shield_Obj +{ + int m_shieldId; + QString m_keyIdTag; + int m_shieldMode; + QString m_shieldObject; + bool m_perm; +}; + +struct ST_Shield_Info +{ + int m_shieldId; + QString m_shieldName; + int m_shieldType; + int m_shieldStatus; + int m_shieldEnable; + int m_timeId; + QString m_hostName; + int m_userId; + int m_timeType; + QString m_startTime; + QString m_endTime; + int m_timeOption; + QString m_shieldDesc; + + int m_location; + int m_subsystem; + int m_usergId; + int m_shieldTime; + bool m_check; + bool m_perm; +}; + +#endif // CSHIELDINFO_H diff --git a/product/src/gui/plugin/AlarmShieldWidget/main.cpp b/product/src/gui/plugin/AlarmShieldWidget/main.cpp index 73c654cc..b29c1705 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/main.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/main.cpp @@ -1,30 +1,30 @@ -#include "CAlarmShield.h" -#include -#include "pub_logger_api/logger.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - kbd_public::StartLogSystem("", "hmi"); - - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - - QApplication a(argc, argv); - CAlarmShield w; - w.show(); - - a.exec(); - - kbd_public::StopLogSystem(); - return 0; -} +#include "CAlarmShield.h" +#include +#include "pub_logger_api/logger.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + kbd_public::StartLogSystem("", "hmi"); + + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + + QApplication a(argc, argv); + CAlarmShield w; + w.show(); + + a.exec(); + + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/AlarmStatisWidget.pro b/product/src/gui/plugin/AlarmStatisWidget/AlarmStatisWidget.pro index 7088da35..b7fa5879 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/AlarmStatisWidget.pro +++ b/product/src/gui/plugin/AlarmStatisWidget/AlarmStatisWidget.pro @@ -1,90 +1,90 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-11-07T15:25:58 -# -#------------------------------------------------- - -QT += core gui sql printsupport charts xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = AlarmStatisWidget -TEMPLATE = lib - -CONFIG += plugin -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CTableViewPrinter.cpp \ - CAlarmStatisPluginWidget.cpp \ - CHisEventManage.cpp \ - widget/CSWitchButton.cpp \ - CStatisWidget.cpp \ - ContrastWidget.cpp \ - CMainWidget.cpp \ -# main.cpp \ - CDataInfoManage.cpp \ - CTsdbQuery.cpp \ - CCurveChartView.cpp \ - widget/CToolTip.cpp \ - CTableModel.cpp \ - CTableViewExport.cpp \ - CDrillDownChart.cpp \ - CDrillDownSeries.cpp - -HEADERS += \ - CTableViewPrinter.h \ - CAlarmStatisPluginWidget.h \ - CHisEventManage.h \ - widget/CSWitchButton.h \ - CStatisWidget.h \ - ContrastWidget.h \ - CMainWidget.h \ - CDataInfoManage.h \ - CTsdbQuery.h \ - CCurveChartView.h \ - CStatisCommon.h \ - widget/CToolTip.h \ - CTableModel.h \ - CTableViewExport.h \ - CDrillDownChart.h \ - CDrillDownSeries.h - -FORMS += \ - CStatisWidget.ui \ - ContrastWidget.ui - -LIBS += \ - -ldb_base_api \ - -ldb_api_ex \ - -lrdb_api \ - -lrdb_net_api \ - -ltsdb_api \ - -ldb_his_query_api \ - -lpub_sysinfo_api \ - -lpub_utility_api \ - -lpub_logger_api \ - -llog4cplus \ - -lmodel_excel - -#LIBS += -lnet_msg_bus_api -lperm_mng_api - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2019-11-07T15:25:58 +# +#------------------------------------------------- + +QT += core gui sql printsupport charts xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = AlarmStatisWidget +TEMPLATE = lib + +CONFIG += plugin +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CTableViewPrinter.cpp \ + CAlarmStatisPluginWidget.cpp \ + CHisEventManage.cpp \ + widget/CSWitchButton.cpp \ + CStatisWidget.cpp \ + ContrastWidget.cpp \ + CMainWidget.cpp \ +# main.cpp \ + CDataInfoManage.cpp \ + CTsdbQuery.cpp \ + CCurveChartView.cpp \ + widget/CToolTip.cpp \ + CTableModel.cpp \ + CTableViewExport.cpp \ + CDrillDownChart.cpp \ + CDrillDownSeries.cpp + +HEADERS += \ + CTableViewPrinter.h \ + CAlarmStatisPluginWidget.h \ + CHisEventManage.h \ + widget/CSWitchButton.h \ + CStatisWidget.h \ + ContrastWidget.h \ + CMainWidget.h \ + CDataInfoManage.h \ + CTsdbQuery.h \ + CCurveChartView.h \ + CStatisCommon.h \ + widget/CToolTip.h \ + CTableModel.h \ + CTableViewExport.h \ + CDrillDownChart.h \ + CDrillDownSeries.h + +FORMS += \ + CStatisWidget.ui \ + ContrastWidget.ui + +LIBS += \ + -ldb_base_api \ + -ldb_api_ex \ + -lrdb_api \ + -lrdb_net_api \ + -ltsdb_api \ + -ldb_his_query_api \ + -lpub_sysinfo_api \ + -lpub_utility_api \ + -lpub_logger_api \ + -llog4cplus \ + -lmodel_excel + +#LIBS += -lnet_msg_bus_api -lperm_mng_api + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.cpp b/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.cpp index a200d50c..fe71f8a2 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CAlarmStatisPluginWidget.h" -#include "CMainWidget.h" -#include - -CAlarmStatisPluginWidget::CAlarmStatisPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CAlarmStatisPluginWidget::~CAlarmStatisPluginWidget() -{ - -} - -bool CAlarmStatisPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CMainWidget *pWidget = new CMainWidget(editMode, ptrVec, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CAlarmStatisPluginWidget::release() -{ - -} +#include "CAlarmStatisPluginWidget.h" +#include "CMainWidget.h" +#include + +CAlarmStatisPluginWidget::CAlarmStatisPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CAlarmStatisPluginWidget::~CAlarmStatisPluginWidget() +{ + +} + +bool CAlarmStatisPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CMainWidget *pWidget = new CMainWidget(editMode, ptrVec, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CAlarmStatisPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.h b/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.h index 337299f1..9766f721 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.h @@ -1,20 +1,20 @@ -#ifndef CALARMSTATISPLUGINWIDGET_H -#define CALARMSTATISPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CAlarmStatisPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CAlarmStatisPluginWidget(QObject *parent = 0); - ~CAlarmStatisPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CALARMSTATISPLUGINWIDGET_H +#ifndef CALARMSTATISPLUGINWIDGET_H +#define CALARMSTATISPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CAlarmStatisPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CAlarmStatisPluginWidget(QObject *parent = 0); + ~CAlarmStatisPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CALARMSTATISPLUGINWIDGET_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CCurveChartView.cpp b/product/src/gui/plugin/AlarmStatisWidget/CCurveChartView.cpp index ed6ba4ae..504f849a 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CCurveChartView.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CCurveChartView.cpp @@ -1,359 +1,359 @@ -#include "CCurveChartView.h" -#include - -CCurveChartView::CCurveChartView(QWidget *parent) - : QChartView(parent) -{ - initialize(); -} - -CCurveChartView::~CCurveChartView() -{ - clearSeries(); -} - -void CCurveChartView::initialize() -{ - m_pChart = new QChart(); - m_pChart->legend()->setVisible(true); - m_pChart->legend()->setAlignment(Qt::AlignTop); - m_pChart->setMargins(QMargins(0,0,0,0)); - m_pChart->setBackgroundRoundness(0); - - m_axisX = new QDateTimeAxis(); - m_axisX->setTickCount(3); - m_axisX->setGridLineVisible(true); - m_axisX->setFormat("yyyy-MM-dd"); - m_pChart->addAxis(m_axisX, Qt::AlignBottom); - setAxisXRange(0,2145887999999); - - m_axisY = new QValueAxis(); - m_axisY->setTickCount(5); - m_axisY->setGridLineVisible(true); - m_pChart->addAxis(m_axisY, Qt::AlignLeft); - setAxisYRange(0,1); - - setRenderHint(QPainter::Antialiasing); - setChart(m_pChart); - setStyleSheet("background-color:transparent"); - m_leftBottom.setX(0); - m_leftBottom.setY(1); - m_rightTop.setX(0); - m_rightTop.setY(1); - m_nMarkerSize=10; - m_pText = new QGraphicsSimpleTextItem(m_pChart); - m_pText->setPos(m_pChart->x(), m_pChart->y()); - m_pText->setVisible(false); - m_pValue = NULL; -} - -void CCurveChartView::setAxisXTickCount(int count) -{ - m_axisX->setTickCount(count); -} - -void CCurveChartView::setAxisYTickCount(int count) -{ - m_axisY->setTickCount(count); -} - -void CCurveChartView::setAxisXFormat(const QString &format) -{ - m_axisX->setFormat(format); -} - -void CCurveChartView::setAxisXLabelsAngle(int angle) -{ - m_axisX->setLabelsAngle(angle); -} - -void CCurveChartView::setAxisXPixelSize(int size) -{ - QFont font = m_axisX->labelsFont(); - font.setPixelSize(size); - m_axisX->setLabelsFont(font); -} - -void CCurveChartView::setAxisXRange(double min, double max) -{ - m_axisX->setRange(QDateTime::fromMSecsSinceEpoch(min), QDateTime::fromMSecsSinceEpoch(max)); -} - -void CCurveChartView::setAxisYRange(double min, double max) -{ - m_axisY->setRange(min, max); -} - -void CCurveChartView::insertLineSeries(const QList &listPoint, const QString& name, - const QString &loc, const QString &devType) -{ - if(listPoint.isEmpty()) - { - return; - } - if(loc.isEmpty() || devType.isEmpty()) - { - m_pText->setText(""); - } - else - { - m_pText->setText(tr("位置:") + loc + " " + tr("设备类型:") + devType); - } - QXYSeries *series; - if(listPoint.length() == 1) - { - series = new QScatterSeries(); - QScatterSeries *scatter = dynamic_cast(series); - scatter->setMarkerSize(m_nMarkerSize); - } - else - { - series = new QLineSeries(); - } - - connect(series, &QXYSeries::hovered, this, &CCurveChartView::seriesHovered); - series->setName(name); - m_pChart->addSeries(series); - series->replace(listPoint); - series->attachAxis(m_axisX); - series->attachAxis(m_axisY); - if(m_listColor.length() >= m_pChart->series().size()) - { - series->setColor(m_listColor.at(m_pChart->series().size()-1)); - } - updateAxisRange(listPoint); - m_valueMap.insert(name, listPoint); -} - -void CCurveChartView::clearSeries() -{ - clearValueText(); - m_valueMap.clear(); - QList seriesList = m_pChart->series(); - QList::iterator iter = seriesList.begin(); - while(iter != seriesList.end()) - { - delete *iter; - ++iter; - } - m_leftBottom.setX(0); - m_leftBottom.setY(1); - m_rightTop.setX(0); - m_rightTop.setY(1); - setAxisXRange(0,2145887999999); - setAxisYRange(0,1); - m_pText->setText(""); -} - -void CCurveChartView::setColorList(const QList &listColor) -{ - m_listColor = listColor; -} - -void CCurveChartView::setTextItemVisible(bool visible) -{ - m_pText->setVisible(visible); - - clearValueText(); - if(visible) - addValueText(); -} - -void CCurveChartView::setSeriesVisible(const QString &name, bool visible) -{ - QList seriesList = m_pChart->series(); - foreach (QAbstractSeries * series, seriesList) { - if(series->name() == name) - { - series->setVisible(visible); - update(); - } - } -} - -QColor CCurveChartView::plotBackgroundColor() -{ - return m_backGroundColor; -} - -void CCurveChartView::setPlotBackgroundColor(const QColor &color) -{ - m_backGroundColor = color; - - m_pChart->setBackgroundBrush(color); -} - -QColor CCurveChartView::plotTickColor() -{ - return m_tickColor; -} - -void CCurveChartView::setPlotTickColor(const QColor &color) -{ - m_tickColor = color; - - m_pChart->axisX()->setLabelsColor(color); - m_pChart->axisY()->setLabelsColor(color); -} - -QColor CCurveChartView::plotGridColor() -{ - return m_gridColor; -} - -void CCurveChartView::setPlotGridColor(const QColor &color) -{ - m_gridColor = color; - - m_pChart->axisX()->setGridLineColor(color); - m_pChart->axisY()->setGridLineColor(color); -} - -QColor CCurveChartView::plotLinePen() -{ - return m_linePen; -} - -void CCurveChartView::setPlotLinePen(const QColor &color) -{ - m_pChart->axisX()->setLinePen(color); - m_pChart->axisY()->setLinePen(color); -} - -QColor CCurveChartView::plotLegendColor() -{ - return m_legendColor; -} - -void CCurveChartView::setPlotLegendColor(const QColor &color) -{ - m_pChart->legend()->setLabelBrush(color); -} - -int CCurveChartView::MarkerSize() -{ - return m_nMarkerSize; -} - -void CCurveChartView::setMarkerSize(int nSize) -{ - m_nMarkerSize = nSize; -} - -void CCurveChartView::seriesHovered(const QPointF &point, bool state) -{ - if(m_pValue == NULL) - m_pValue = new QGraphicsSimpleTextItem(m_pChart); - - if(state) - { - QXYSeries *series = dynamic_cast(sender()); - if(!series){ - m_pValue->hide(); - return; - } - QList points = series->points(); - foreach (QPointF p, points) { - qreal xRange = abs(axisXCoordToPixel(point.x())-axisXCoordToPixel(p.x())); - qreal yRange = abs(axisYCoordToPixel(point.y())-axisYCoordToPixel(p.y())); - if(xRange < 8 && yRange < 8) - { - QPointF coord = m_pChart->mapToPosition(point); - m_pValue->setText(QString::number(p.y(), 'f', 0)); - m_pValue->setPos(coord + QPointF(0,-15)); - m_pValue->show(); - } - } - } - else{ - m_pValue->hide(); - } -} - -void CCurveChartView::updateAxisRange(const QList& listPoint) -{ - if(m_pChart->series().size() == 1) - { - m_leftBottom.setX(listPoint.at(0).x()); - m_leftBottom.setY(listPoint.at(0).y()); - m_rightTop.setX(listPoint.at(0).x()); - m_rightTop.setY(listPoint.at(0).y()); - } - - foreach (QPointF point, listPoint) { - if(point.x() < m_leftBottom.x()) - { - m_leftBottom.setX(point.x()); - } - else if(point.x() > m_rightTop.x()) - { - m_rightTop.setX(point.x()); - } - if(point.y() < m_leftBottom.y()) - { - m_leftBottom.setY(point.y()); - } - else if(point.y() > m_rightTop.y()) - { - m_rightTop.setY(point.y()); - } - } - m_axisY->setRange(m_leftBottom.y(), m_rightTop.y() + (m_rightTop.y()-m_leftBottom.y())/5.); -} - -void CCurveChartView::addValueText() -{ - QStringList inVisible; - QList seriesList = m_pChart->series(); - foreach (QAbstractSeries *series, seriesList) { - if(!series->isVisible()) - inVisible.append(series->name()); - } - QMap >::const_iterator iter = m_valueMap.constBegin(); - for(; iter != m_valueMap.constEnd(); iter++) - { - if(inVisible.indexOf(iter.key()) != -1) - continue; - for(int nIndex(0); nIndexmapToPosition(iter.value()[nIndex]); - pText->setText(QString::number(iter.value()[nIndex].y(), 'f', 0)); - pText->setPos(coord + QPointF(0, -15)); - pText->show(); - m_valueTextMap[iter.key()].append(pText); - } - } -} - -void CCurveChartView::clearValueText() -{ - QMap>::iterator iter - = m_valueTextMap.begin(); - while(iter != m_valueTextMap.end()) - { - foreach (QGraphicsSimpleTextItem *item, iter.value()) { - delete item; - } - iter.value().clear(); - ++iter; - } - m_valueTextMap.clear(); -} - -qreal CCurveChartView::axisXCoordToPixel(qreal value) -{ - qreal min = m_axisX->min().toMSecsSinceEpoch(); - qreal max = m_axisX->max().toMSecsSinceEpoch(); - qreal rate = (value - min) / (max - min); - return rate * m_pChart->rect().width() + m_pChart->rect().left(); -} - -qreal CCurveChartView::axisYCoordToPixel(qreal value) -{ - qreal min = m_axisY->min(); - qreal max = m_axisY->max(); - qreal rate = (value - min) / (max - min); - return rate * m_pChart->rect().height() + m_pChart->rect().top(); -} - +#include "CCurveChartView.h" +#include + +CCurveChartView::CCurveChartView(QWidget *parent) + : QChartView(parent) +{ + initialize(); +} + +CCurveChartView::~CCurveChartView() +{ + clearSeries(); +} + +void CCurveChartView::initialize() +{ + m_pChart = new QChart(); + m_pChart->legend()->setVisible(true); + m_pChart->legend()->setAlignment(Qt::AlignTop); + m_pChart->setMargins(QMargins(0,0,0,0)); + m_pChart->setBackgroundRoundness(0); + + m_axisX = new QDateTimeAxis(); + m_axisX->setTickCount(3); + m_axisX->setGridLineVisible(true); + m_axisX->setFormat("yyyy-MM-dd"); + m_pChart->addAxis(m_axisX, Qt::AlignBottom); + setAxisXRange(0,2145887999999); + + m_axisY = new QValueAxis(); + m_axisY->setTickCount(5); + m_axisY->setGridLineVisible(true); + m_pChart->addAxis(m_axisY, Qt::AlignLeft); + setAxisYRange(0,1); + + setRenderHint(QPainter::Antialiasing); + setChart(m_pChart); + setStyleSheet("background-color:transparent"); + m_leftBottom.setX(0); + m_leftBottom.setY(1); + m_rightTop.setX(0); + m_rightTop.setY(1); + m_nMarkerSize=10; + m_pText = new QGraphicsSimpleTextItem(m_pChart); + m_pText->setPos(m_pChart->x(), m_pChart->y()); + m_pText->setVisible(false); + m_pValue = NULL; +} + +void CCurveChartView::setAxisXTickCount(int count) +{ + m_axisX->setTickCount(count); +} + +void CCurveChartView::setAxisYTickCount(int count) +{ + m_axisY->setTickCount(count); +} + +void CCurveChartView::setAxisXFormat(const QString &format) +{ + m_axisX->setFormat(format); +} + +void CCurveChartView::setAxisXLabelsAngle(int angle) +{ + m_axisX->setLabelsAngle(angle); +} + +void CCurveChartView::setAxisXPixelSize(int size) +{ + QFont font = m_axisX->labelsFont(); + font.setPixelSize(size); + m_axisX->setLabelsFont(font); +} + +void CCurveChartView::setAxisXRange(double min, double max) +{ + m_axisX->setRange(QDateTime::fromMSecsSinceEpoch(min), QDateTime::fromMSecsSinceEpoch(max)); +} + +void CCurveChartView::setAxisYRange(double min, double max) +{ + m_axisY->setRange(min, max); +} + +void CCurveChartView::insertLineSeries(const QList &listPoint, const QString& name, + const QString &loc, const QString &devType) +{ + if(listPoint.isEmpty()) + { + return; + } + if(loc.isEmpty() || devType.isEmpty()) + { + m_pText->setText(""); + } + else + { + m_pText->setText(tr("位置:") + loc + " " + tr("设备类型:") + devType); + } + QXYSeries *series; + if(listPoint.length() == 1) + { + series = new QScatterSeries(); + QScatterSeries *scatter = dynamic_cast(series); + scatter->setMarkerSize(m_nMarkerSize); + } + else + { + series = new QLineSeries(); + } + + connect(series, &QXYSeries::hovered, this, &CCurveChartView::seriesHovered); + series->setName(name); + m_pChart->addSeries(series); + series->replace(listPoint); + series->attachAxis(m_axisX); + series->attachAxis(m_axisY); + if(m_listColor.length() >= m_pChart->series().size()) + { + series->setColor(m_listColor.at(m_pChart->series().size()-1)); + } + updateAxisRange(listPoint); + m_valueMap.insert(name, listPoint); +} + +void CCurveChartView::clearSeries() +{ + clearValueText(); + m_valueMap.clear(); + QList seriesList = m_pChart->series(); + QList::iterator iter = seriesList.begin(); + while(iter != seriesList.end()) + { + delete *iter; + ++iter; + } + m_leftBottom.setX(0); + m_leftBottom.setY(1); + m_rightTop.setX(0); + m_rightTop.setY(1); + setAxisXRange(0,2145887999999); + setAxisYRange(0,1); + m_pText->setText(""); +} + +void CCurveChartView::setColorList(const QList &listColor) +{ + m_listColor = listColor; +} + +void CCurveChartView::setTextItemVisible(bool visible) +{ + m_pText->setVisible(visible); + + clearValueText(); + if(visible) + addValueText(); +} + +void CCurveChartView::setSeriesVisible(const QString &name, bool visible) +{ + QList seriesList = m_pChart->series(); + foreach (QAbstractSeries * series, seriesList) { + if(series->name() == name) + { + series->setVisible(visible); + update(); + } + } +} + +QColor CCurveChartView::plotBackgroundColor() +{ + return m_backGroundColor; +} + +void CCurveChartView::setPlotBackgroundColor(const QColor &color) +{ + m_backGroundColor = color; + + m_pChart->setBackgroundBrush(color); +} + +QColor CCurveChartView::plotTickColor() +{ + return m_tickColor; +} + +void CCurveChartView::setPlotTickColor(const QColor &color) +{ + m_tickColor = color; + + m_pChart->axisX()->setLabelsColor(color); + m_pChart->axisY()->setLabelsColor(color); +} + +QColor CCurveChartView::plotGridColor() +{ + return m_gridColor; +} + +void CCurveChartView::setPlotGridColor(const QColor &color) +{ + m_gridColor = color; + + m_pChart->axisX()->setGridLineColor(color); + m_pChart->axisY()->setGridLineColor(color); +} + +QColor CCurveChartView::plotLinePen() +{ + return m_linePen; +} + +void CCurveChartView::setPlotLinePen(const QColor &color) +{ + m_pChart->axisX()->setLinePen(color); + m_pChart->axisY()->setLinePen(color); +} + +QColor CCurveChartView::plotLegendColor() +{ + return m_legendColor; +} + +void CCurveChartView::setPlotLegendColor(const QColor &color) +{ + m_pChart->legend()->setLabelBrush(color); +} + +int CCurveChartView::MarkerSize() +{ + return m_nMarkerSize; +} + +void CCurveChartView::setMarkerSize(int nSize) +{ + m_nMarkerSize = nSize; +} + +void CCurveChartView::seriesHovered(const QPointF &point, bool state) +{ + if(m_pValue == NULL) + m_pValue = new QGraphicsSimpleTextItem(m_pChart); + + if(state) + { + QXYSeries *series = dynamic_cast(sender()); + if(!series){ + m_pValue->hide(); + return; + } + QList points = series->points(); + foreach (QPointF p, points) { + qreal xRange = abs(axisXCoordToPixel(point.x())-axisXCoordToPixel(p.x())); + qreal yRange = abs(axisYCoordToPixel(point.y())-axisYCoordToPixel(p.y())); + if(xRange < 8 && yRange < 8) + { + QPointF coord = m_pChart->mapToPosition(point); + m_pValue->setText(QString::number(p.y(), 'f', 0)); + m_pValue->setPos(coord + QPointF(0,-15)); + m_pValue->show(); + } + } + } + else{ + m_pValue->hide(); + } +} + +void CCurveChartView::updateAxisRange(const QList& listPoint) +{ + if(m_pChart->series().size() == 1) + { + m_leftBottom.setX(listPoint.at(0).x()); + m_leftBottom.setY(listPoint.at(0).y()); + m_rightTop.setX(listPoint.at(0).x()); + m_rightTop.setY(listPoint.at(0).y()); + } + + foreach (QPointF point, listPoint) { + if(point.x() < m_leftBottom.x()) + { + m_leftBottom.setX(point.x()); + } + else if(point.x() > m_rightTop.x()) + { + m_rightTop.setX(point.x()); + } + if(point.y() < m_leftBottom.y()) + { + m_leftBottom.setY(point.y()); + } + else if(point.y() > m_rightTop.y()) + { + m_rightTop.setY(point.y()); + } + } + m_axisY->setRange(m_leftBottom.y(), m_rightTop.y() + (m_rightTop.y()-m_leftBottom.y())/5.); +} + +void CCurveChartView::addValueText() +{ + QStringList inVisible; + QList seriesList = m_pChart->series(); + foreach (QAbstractSeries *series, seriesList) { + if(!series->isVisible()) + inVisible.append(series->name()); + } + QMap >::const_iterator iter = m_valueMap.constBegin(); + for(; iter != m_valueMap.constEnd(); iter++) + { + if(inVisible.indexOf(iter.key()) != -1) + continue; + for(int nIndex(0); nIndexmapToPosition(iter.value()[nIndex]); + pText->setText(QString::number(iter.value()[nIndex].y(), 'f', 0)); + pText->setPos(coord + QPointF(0, -15)); + pText->show(); + m_valueTextMap[iter.key()].append(pText); + } + } +} + +void CCurveChartView::clearValueText() +{ + QMap>::iterator iter + = m_valueTextMap.begin(); + while(iter != m_valueTextMap.end()) + { + foreach (QGraphicsSimpleTextItem *item, iter.value()) { + delete item; + } + iter.value().clear(); + ++iter; + } + m_valueTextMap.clear(); +} + +qreal CCurveChartView::axisXCoordToPixel(qreal value) +{ + qreal min = m_axisX->min().toMSecsSinceEpoch(); + qreal max = m_axisX->max().toMSecsSinceEpoch(); + qreal rate = (value - min) / (max - min); + return rate * m_pChart->rect().width() + m_pChart->rect().left(); +} + +qreal CCurveChartView::axisYCoordToPixel(qreal value) +{ + qreal min = m_axisY->min(); + qreal max = m_axisY->max(); + qreal rate = (value - min) / (max - min); + return rate * m_pChart->rect().height() + m_pChart->rect().top(); +} + diff --git a/product/src/gui/plugin/AlarmStatisWidget/CCurveChartView.h b/product/src/gui/plugin/AlarmStatisWidget/CCurveChartView.h index aa0bb5f4..fde54cb4 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CCurveChartView.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CCurveChartView.h @@ -1,102 +1,102 @@ -#ifndef CURVECHARTVIEW_H -#define CURVECHARTVIEW_H - -#include -#include -#include -#include -#include -#include - -QT_CHARTS_USE_NAMESPACE - -class CCurveChartView : public QChartView -{ - Q_OBJECT - Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) - Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) - Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) - Q_PROPERTY(QColor plotLinePen READ plotLinePen WRITE setPlotLinePen) - Q_PROPERTY(QColor plotLegendColor READ plotLegendColor WRITE setPlotLegendColor) - Q_PROPERTY(int MarkerSize READ MarkerSize WRITE setMarkerSize) - -public: - explicit CCurveChartView(QWidget *parent = Q_NULLPTR); - ~CCurveChartView(); - - void initialize(); - - void setAxisXTickCount(int count); - - void setAxisYTickCount(int count); - - void setAxisXFormat(const QString &format); - - void setAxisXLabelsAngle(int angle); - - void setAxisXPixelSize(int size); - - void setAxisXRange(double min, double max); - - void setAxisYRange(double min, double max); - - void insertLineSeries(const QList &listPoint, const QString &name, - const QString &loc = QString(), const QString &devType = QString()); - - void clearSeries(); - - void setColorList(const QList &listColor); - - void setTextItemVisible(bool visible); - - void setSeriesVisible(const QString &name, bool visible); - - //< 样式 - QColor plotBackgroundColor(); - void setPlotBackgroundColor(const QColor &color); - - QColor plotTickColor(); - void setPlotTickColor(const QColor &color); - - QColor plotGridColor(); - void setPlotGridColor(const QColor &color); - - QColor plotLinePen(); - void setPlotLinePen(const QColor &color); - - QColor plotLegendColor(); - void setPlotLegendColor(const QColor &color); - - int MarkerSize(); - void setMarkerSize(int nSize); - -protected slots: - void seriesHovered(const QPointF &point, bool state); - -private: - void updateAxisRange(const QList &listPoint); - void addValueText(); - void clearValueText(); - qreal axisXCoordToPixel(qreal value); - qreal axisYCoordToPixel(qreal value); - -private: - QChart * m_pChart; - QList m_listColor; - QDateTimeAxis * m_axisX; - QValueAxis * m_axisY; - QColor m_backGroundColor; - QColor m_tickColor; - QColor m_gridColor; - QColor m_linePen; - QColor m_legendColor; - int m_nMarkerSize; - QPointF m_leftBottom; - QPointF m_rightTop; - QGraphicsSimpleTextItem *m_pText; - QGraphicsSimpleTextItem *m_pValue; - QMap > m_valueMap; - QMap> m_valueTextMap; -}; - -#endif // CCURVECHARTVIEW_H +#ifndef CURVECHARTVIEW_H +#define CURVECHARTVIEW_H + +#include +#include +#include +#include +#include +#include + +QT_CHARTS_USE_NAMESPACE + +class CCurveChartView : public QChartView +{ + Q_OBJECT + Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) + Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) + Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) + Q_PROPERTY(QColor plotLinePen READ plotLinePen WRITE setPlotLinePen) + Q_PROPERTY(QColor plotLegendColor READ plotLegendColor WRITE setPlotLegendColor) + Q_PROPERTY(int MarkerSize READ MarkerSize WRITE setMarkerSize) + +public: + explicit CCurveChartView(QWidget *parent = Q_NULLPTR); + ~CCurveChartView(); + + void initialize(); + + void setAxisXTickCount(int count); + + void setAxisYTickCount(int count); + + void setAxisXFormat(const QString &format); + + void setAxisXLabelsAngle(int angle); + + void setAxisXPixelSize(int size); + + void setAxisXRange(double min, double max); + + void setAxisYRange(double min, double max); + + void insertLineSeries(const QList &listPoint, const QString &name, + const QString &loc = QString(), const QString &devType = QString()); + + void clearSeries(); + + void setColorList(const QList &listColor); + + void setTextItemVisible(bool visible); + + void setSeriesVisible(const QString &name, bool visible); + + //< 样式 + QColor plotBackgroundColor(); + void setPlotBackgroundColor(const QColor &color); + + QColor plotTickColor(); + void setPlotTickColor(const QColor &color); + + QColor plotGridColor(); + void setPlotGridColor(const QColor &color); + + QColor plotLinePen(); + void setPlotLinePen(const QColor &color); + + QColor plotLegendColor(); + void setPlotLegendColor(const QColor &color); + + int MarkerSize(); + void setMarkerSize(int nSize); + +protected slots: + void seriesHovered(const QPointF &point, bool state); + +private: + void updateAxisRange(const QList &listPoint); + void addValueText(); + void clearValueText(); + qreal axisXCoordToPixel(qreal value); + qreal axisYCoordToPixel(qreal value); + +private: + QChart * m_pChart; + QList m_listColor; + QDateTimeAxis * m_axisX; + QValueAxis * m_axisY; + QColor m_backGroundColor; + QColor m_tickColor; + QColor m_gridColor; + QColor m_linePen; + QColor m_legendColor; + int m_nMarkerSize; + QPointF m_leftBottom; + QPointF m_rightTop; + QGraphicsSimpleTextItem *m_pText; + QGraphicsSimpleTextItem *m_pValue; + QMap > m_valueMap; + QMap> m_valueTextMap; +}; + +#endif // CCURVECHARTVIEW_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CDataInfoManage.cpp b/product/src/gui/plugin/AlarmStatisWidget/CDataInfoManage.cpp index cc10c1b1..016baf59 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CDataInfoManage.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CDataInfoManage.cpp @@ -1,517 +1,517 @@ -#include "CDataInfoManage.h" -#include "dbms/db_api_ex/CDbApi.h" -#include "CStatisCommon.h" - -using namespace kbd_dbms; - -CDataInfoManage *CDataInfoManage::m_pInstance = NULL; - -CDataInfoManage::CDataInfoManage() -{ - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_rtdbNetAcs = new kbd_dbms::CRdbNetApi(); - m_nDomain = CN_InvalidDomainId; - if(kbd_public::createSysInfoInstance(m_ptrSysInfo)) - { - kbd_public::SNodeInfo sNodeInfo; - m_ptrSysInfo->getLocalNodeInfo(sNodeInfo); - m_nDomain = sNodeInfo.nDomainId; - } - m_nChgType = -1; - m_nSoeType = -1; - - QTime time; - time.start(); - loadAlarmLevel(); - loadLocation(); - loadDevType(); - loadDevInfo(); - loadAlarmType(); - loadAlarmStatus(); - loadAlarmManner(); -// loadDevPoint(); -} - -CDataInfoManage *CDataInfoManage::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CDataInfoManage(); - } - return m_pInstance; -} - -void CDataInfoManage::destory() -{ - if(m_rtdbAccess) - { - delete m_rtdbAccess; - } - m_rtdbAccess = Q_NULLPTR; - - if(m_rtdbNetAcs) - { - delete m_rtdbNetAcs; - } - m_rtdbNetAcs = Q_NULLPTR; - - m_nChgType = -1; - m_nSoeType = -1; - - m_alarmLevelMap.clear(); - m_alarmOrderMap.clear(); - m_locationMap.clear(); - m_devTypeMap.clear(); - m_devInfoMap.clear(); - m_devDescMap.clear(); - m_customAlarmDevMap.clear(); - m_alarmStatusMap.clear(); - m_alarmMannerMap.clear(); - m_devPointMap.clear(); - - m_pInstance = NULL; - delete this; -} - -QMap CDataInfoManage::getAlarmLevel() -{ - return m_alarmLevelMap; -} - -QMap CDataInfoManage::getAlarmOrder() -{ - return m_alarmOrderMap; -} - -QMap CDataInfoManage::getLocation() -{ - return m_locationMap; -} - -QString CDataInfoManage::getLocationDesc(int location) -{ - QMap::const_iterator iter = m_locationMap.constBegin(); - for(; iter != m_locationMap.constEnd(); iter++) - { - foreach (QString str, iter.value()) { - QStringList list = str.split(","); - if(list.length() != 3) - { - continue; - } - if(QString(list[0]).toInt() == location) - { - return list[1]; - } - } - } - return QString(); -} - -QMap CDataInfoManage::getDevType() -{ - return m_devTypeMap; -} - -QString CDataInfoManage::getDevTypeDesc(int devType) -{ - return m_devTypeMap.value(devType); -} - -QStringList CDataInfoManage::getDevice(int location, int devType) -{ - QStringList result; - int loc, type; - QMap >::const_iterator iter - = m_devInfoMap.constBegin(); - for(; iter != m_devInfoMap.constEnd(); iter++) - { - loc = iter.value().first; - if(location != -1 && location != loc) - { - continue; - } - type = iter.value().second; - if(devType != -1 && devType != type) - { - continue; - } - result.append(iter.key()); - } - return result; -} - -QPair CDataInfoManage::getDeviceBelong(const QString &device) -{ - QMap >::const_iterator iter = m_devInfoMap.find(device); - if(iter == m_devInfoMap.constEnd()) - { - return QPair(); - } - QPair pair; - pair.first = getLocationDesc(iter.value().first); - pair.second = m_devTypeMap.value(iter.value().second, QString()); - return pair; -} - -QString CDataInfoManage::getDevDesc(const QString &device) -{ - return m_devDescMap.value(device, QString()); -} - -QMap CDataInfoManage::getPoint(const QString &device) -{ - if(m_devPointMap.isEmpty()) - { - loadDevPoint(); - } - return m_devPointMap.value(device, QMap()); -} - -bool CDataInfoManage::getCustomAlmLevel(const QString &key, QPair &pair) -{ - QMap >::const_iterator iter = m_customAlarmDevMap.find(key); - if(iter == m_customAlarmDevMap.constEnd()) - { - return false; - } - pair = m_customAlarmDevMap.value(key); - return true; -} - -int CDataInfoManage::getAlarmManner(const QPair &alarm) -{ - return m_alarmStatusMap.value(alarm, -1); -} - -int CDataInfoManage::getAlarmPriority(const int &alarmManner) -{ - return m_alarmMannerMap.value(alarmManner, -1); -} - -int CDataInfoManage::getChgType() -{ - return m_nChgType; -} - -int CDataInfoManage::getSoeType() -{ - return m_nSoeType; -} - -void CDataInfoManage::loadAlarmLevel() -{ - std::string strApplicationName = CN_AppName_BASE; - std::string strTableName = "alarm_level_define"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("priority_id"); - columns.push_back("priority_name"); - columns.push_back("priority_order"); - - CONDINFO condition; - memcpy(condition.name, "if_event", strlen("if_event")); - condition.logicalop = ATTRCOND_AND; - condition.relationop = ATTRCOND_EQU; - condition.conditionval = 0; - - if(m_rtdbAccess->select(condition, result, columns)) - { - m_alarmLevelMap.clear(); - m_alarmOrderMap.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - kbd_dbms::CVarType order; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - result.getColumnValue(nIndex, 2, order); - - m_alarmLevelMap[key.toInt()] = QString::fromStdString(value.toStdString()); - m_alarmOrderMap[key.toInt()] = order.toInt(); - } - } - } - m_rtdbAccess->close(); -} - -void CDataInfoManage::loadLocation() -{ - std::string strApplicationName = CN_AppName_BASE; - std::string strTableName = "sys_model_location_info"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("location_id"); - columns.push_back("description"); - columns.push_back("plocation_id"); - columns.push_back("location_type"); - std::string sOrderColumn = "location_no"; - - QList idList; - QMap locationMap; - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType id; - kbd_dbms::CVarType desc; - kbd_dbms::CVarType p_id; - kbd_dbms::CVarType type; - result.getColumnValue(nIndex, 0, id); - result.getColumnValue(nIndex, 1, desc); - result.getColumnValue(nIndex, 2, p_id); - result.getColumnValue(nIndex, 3, type); - - idList.append(id.toInt()); - locationMap[p_id.toInt()].append(QString("%1,%2,%3") - .arg(QString::number(id.toInt())) - .arg(QString::fromStdString(desc.toStdString())) - .arg(QString::number(type.toInt()))); - } - } - - m_locationMap.clear(); - QMap::const_iterator iter = locationMap.constBegin(); - for(; iter != locationMap.constEnd(); iter++) - { - if(idList.indexOf(iter.key()) == -1) - { - m_locationMap[-1].append(iter.value()); - } - else - { - m_locationMap[iter.key()].append(iter.value()); - } - } - } - m_rtdbAccess->close(); -} - -void CDataInfoManage::loadDevType() -{ - std::string strApplicationName = CN_AppName_BASE; - std::string strTableName = "dev_type_def"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("dev_type_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - m_devTypeMap.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - - m_devTypeMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - m_rtdbAccess->close(); -} - -void CDataInfoManage::loadDevInfo() -{ - std::string strTableName = "dev_info"; - m_rtdbNetAcs->connect(m_nDomain, CN_AppId_PSCADA); - kbd_idlfile::RdbRet objRet; - std::vector columns; - columns.push_back("tag_name"); - columns.push_back("description"); - columns.push_back("location_id"); - columns.push_back("dev_type"); - - if(m_rtdbNetAcs->queryTotal(strTableName, columns, objRet)) - { - m_devInfoMap.clear(); - m_devDescMap.clear(); - int recordNum = objRet.msgrecord_size(); - for (int i = 0; i < recordNum; ++i) - { - std::string tag_name = objRet.msgrecord(i).msgvaluearray(0).strvalue(); - std::string description = objRet.msgrecord(i).msgvaluearray(1).strvalue(); - int location_id = objRet.msgrecord(i).msgvaluearray(2).nvalue(); - int dev_type = objRet.msgrecord(i).msgvaluearray(3).nvalue(); - - QPair pair; - pair.first = location_id; - pair.second = dev_type; - m_devInfoMap[QString::fromStdString(tag_name)] = pair; - m_devDescMap[QString::fromStdString(tag_name)] = QString::fromStdString(description); - } - } -} - -void CDataInfoManage::loadAlarmType() -{ - CDbApi dbRead(DB_CONN_MODEL_READ); - if(dbRead.open()) - { - QSqlQuery query; - QList columns; - columns.push_back("type_id"); - columns.push_back("macro_name"); - if(dbRead.select("alarm_type_define", columns, query)) - { - while(query.next()) - { - int alarm_type = query.value(0).toInt(); - QString macro_name = query.value(1).toString(); - if(macro_name.contains("SOE")) - { - m_nSoeType = alarm_type; - } - else if(macro_name.contains("CHANGE")) - { - m_nChgType = alarm_type; - } - } - } - } -} - -void CDataInfoManage::loadAlarmStatus() -{ - std::string strApplicationName = CN_AppName_BASE; - std::string strTableName = "alarm_status_define"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("alarm_type"); - columns.push_back("status_value"); - columns.push_back("alarm_manner"); - - if(m_rtdbAccess->select(result, columns)) - { - m_alarmStatusMap.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType alarm_type; - kbd_dbms::CVarType status_value; - kbd_dbms::CVarType alarm_manner; - result.getColumnValue(nIndex, 0, alarm_type); - result.getColumnValue(nIndex, 1, status_value); - result.getColumnValue(nIndex, 2, alarm_manner); - - QPair pair; - pair.first = alarm_type.toInt(); - pair.second = status_value.toInt(); - m_alarmStatusMap[pair] = alarm_manner.toInt(); - } - } - } - m_rtdbAccess->close(); -} - -void CDataInfoManage::loadAlarmManner() -{ - std::string strApplicationName = CN_AppName_BASE; - std::string strTableName = "alarm_manner_define"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("manner_id"); - columns.push_back("alarm_priority"); - - if(m_rtdbAccess->select(result, columns)) - { - m_alarmMannerMap.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - - m_alarmMannerMap[key.toInt()] = value.toInt(); - } - } - } - m_rtdbAccess->close(); -} - -void CDataInfoManage::loadDevPoint() -{ - QList listTable; - listTable.append("analog"); - listTable.append("digital"); - listTable.append("accuml"); - listTable.append("mix"); - - m_devPointMap.clear(); - m_customAlarmDevMap.clear(); - for(int nIndex=0; nIndexconnect(m_nDomain, CN_AppId_PSCADA); - kbd_idlfile::RdbRet objRet; - std::vector columns; - columns.push_back("tag_name"); - columns.push_back("device"); - if(listTable[nIndex] == "digital") - { - columns.push_back("is_obj_alm_manner"); - columns.push_back("alarm_priority"); - columns.push_back("alarm_priority_soe"); - } - else if(listTable[nIndex] == "mix") - { - columns.push_back("is_obj_alm_manner"); - columns.push_back("alarm_priority"); - } - - if(m_rtdbNetAcs->queryTotal(listTable[nIndex].toStdString().c_str(), columns, objRet)) - { - int recordNum = objRet.msgrecord_size(); - for (int i = 0; i < recordNum; ++i) - { - std::string key = objRet.msgrecord(i).msgvaluearray(0).strvalue(); - std::string device = objRet.msgrecord(i).msgvaluearray(1).strvalue(); - - m_devPointMap[QString::fromStdString(device)][listTable[nIndex]] - .append(QString::fromStdString(key)); - - int is_obj_alm_manner; - int alarm_priority; - int alarm_priority_soe; - if(listTable[nIndex] == "digital" || listTable[nIndex] == "mix") - { - is_obj_alm_manner = objRet.msgrecord(i).msgvaluearray(2).nvalue(); - if(is_obj_alm_manner != 1) - { - continue; - } - alarm_priority = objRet.msgrecord(i).msgvaluearray(3).nvalue(); - if(listTable[nIndex] == "digital") - { - alarm_priority_soe = objRet.msgrecord(i).msgvaluearray(4).nvalue(); - } - else - { - alarm_priority_soe = -1; - } - QPair pair; - pair.first = alarm_priority; - pair.second = alarm_priority_soe; - m_customAlarmDevMap[QString::fromStdString(key)] = pair; - } - } - } - } -} +#include "CDataInfoManage.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "CStatisCommon.h" + +using namespace kbd_dbms; + +CDataInfoManage *CDataInfoManage::m_pInstance = NULL; + +CDataInfoManage::CDataInfoManage() +{ + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_rtdbNetAcs = new kbd_dbms::CRdbNetApi(); + m_nDomain = CN_InvalidDomainId; + if(kbd_public::createSysInfoInstance(m_ptrSysInfo)) + { + kbd_public::SNodeInfo sNodeInfo; + m_ptrSysInfo->getLocalNodeInfo(sNodeInfo); + m_nDomain = sNodeInfo.nDomainId; + } + m_nChgType = -1; + m_nSoeType = -1; + + QTime time; + time.start(); + loadAlarmLevel(); + loadLocation(); + loadDevType(); + loadDevInfo(); + loadAlarmType(); + loadAlarmStatus(); + loadAlarmManner(); +// loadDevPoint(); +} + +CDataInfoManage *CDataInfoManage::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDataInfoManage(); + } + return m_pInstance; +} + +void CDataInfoManage::destory() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + + if(m_rtdbNetAcs) + { + delete m_rtdbNetAcs; + } + m_rtdbNetAcs = Q_NULLPTR; + + m_nChgType = -1; + m_nSoeType = -1; + + m_alarmLevelMap.clear(); + m_alarmOrderMap.clear(); + m_locationMap.clear(); + m_devTypeMap.clear(); + m_devInfoMap.clear(); + m_devDescMap.clear(); + m_customAlarmDevMap.clear(); + m_alarmStatusMap.clear(); + m_alarmMannerMap.clear(); + m_devPointMap.clear(); + + m_pInstance = NULL; + delete this; +} + +QMap CDataInfoManage::getAlarmLevel() +{ + return m_alarmLevelMap; +} + +QMap CDataInfoManage::getAlarmOrder() +{ + return m_alarmOrderMap; +} + +QMap CDataInfoManage::getLocation() +{ + return m_locationMap; +} + +QString CDataInfoManage::getLocationDesc(int location) +{ + QMap::const_iterator iter = m_locationMap.constBegin(); + for(; iter != m_locationMap.constEnd(); iter++) + { + foreach (QString str, iter.value()) { + QStringList list = str.split(","); + if(list.length() != 3) + { + continue; + } + if(QString(list[0]).toInt() == location) + { + return list[1]; + } + } + } + return QString(); +} + +QMap CDataInfoManage::getDevType() +{ + return m_devTypeMap; +} + +QString CDataInfoManage::getDevTypeDesc(int devType) +{ + return m_devTypeMap.value(devType); +} + +QStringList CDataInfoManage::getDevice(int location, int devType) +{ + QStringList result; + int loc, type; + QMap >::const_iterator iter + = m_devInfoMap.constBegin(); + for(; iter != m_devInfoMap.constEnd(); iter++) + { + loc = iter.value().first; + if(location != -1 && location != loc) + { + continue; + } + type = iter.value().second; + if(devType != -1 && devType != type) + { + continue; + } + result.append(iter.key()); + } + return result; +} + +QPair CDataInfoManage::getDeviceBelong(const QString &device) +{ + QMap >::const_iterator iter = m_devInfoMap.find(device); + if(iter == m_devInfoMap.constEnd()) + { + return QPair(); + } + QPair pair; + pair.first = getLocationDesc(iter.value().first); + pair.second = m_devTypeMap.value(iter.value().second, QString()); + return pair; +} + +QString CDataInfoManage::getDevDesc(const QString &device) +{ + return m_devDescMap.value(device, QString()); +} + +QMap CDataInfoManage::getPoint(const QString &device) +{ + if(m_devPointMap.isEmpty()) + { + loadDevPoint(); + } + return m_devPointMap.value(device, QMap()); +} + +bool CDataInfoManage::getCustomAlmLevel(const QString &key, QPair &pair) +{ + QMap >::const_iterator iter = m_customAlarmDevMap.find(key); + if(iter == m_customAlarmDevMap.constEnd()) + { + return false; + } + pair = m_customAlarmDevMap.value(key); + return true; +} + +int CDataInfoManage::getAlarmManner(const QPair &alarm) +{ + return m_alarmStatusMap.value(alarm, -1); +} + +int CDataInfoManage::getAlarmPriority(const int &alarmManner) +{ + return m_alarmMannerMap.value(alarmManner, -1); +} + +int CDataInfoManage::getChgType() +{ + return m_nChgType; +} + +int CDataInfoManage::getSoeType() +{ + return m_nSoeType; +} + +void CDataInfoManage::loadAlarmLevel() +{ + std::string strApplicationName = CN_AppName_BASE; + std::string strTableName = "alarm_level_define"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("priority_id"); + columns.push_back("priority_name"); + columns.push_back("priority_order"); + + CONDINFO condition; + memcpy(condition.name, "if_event", strlen("if_event")); + condition.logicalop = ATTRCOND_AND; + condition.relationop = ATTRCOND_EQU; + condition.conditionval = 0; + + if(m_rtdbAccess->select(condition, result, columns)) + { + m_alarmLevelMap.clear(); + m_alarmOrderMap.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + kbd_dbms::CVarType order; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + result.getColumnValue(nIndex, 2, order); + + m_alarmLevelMap[key.toInt()] = QString::fromStdString(value.toStdString()); + m_alarmOrderMap[key.toInt()] = order.toInt(); + } + } + } + m_rtdbAccess->close(); +} + +void CDataInfoManage::loadLocation() +{ + std::string strApplicationName = CN_AppName_BASE; + std::string strTableName = "sys_model_location_info"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("description"); + columns.push_back("plocation_id"); + columns.push_back("location_type"); + std::string sOrderColumn = "location_no"; + + QList idList; + QMap locationMap; + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType id; + kbd_dbms::CVarType desc; + kbd_dbms::CVarType p_id; + kbd_dbms::CVarType type; + result.getColumnValue(nIndex, 0, id); + result.getColumnValue(nIndex, 1, desc); + result.getColumnValue(nIndex, 2, p_id); + result.getColumnValue(nIndex, 3, type); + + idList.append(id.toInt()); + locationMap[p_id.toInt()].append(QString("%1,%2,%3") + .arg(QString::number(id.toInt())) + .arg(QString::fromStdString(desc.toStdString())) + .arg(QString::number(type.toInt()))); + } + } + + m_locationMap.clear(); + QMap::const_iterator iter = locationMap.constBegin(); + for(; iter != locationMap.constEnd(); iter++) + { + if(idList.indexOf(iter.key()) == -1) + { + m_locationMap[-1].append(iter.value()); + } + else + { + m_locationMap[iter.key()].append(iter.value()); + } + } + } + m_rtdbAccess->close(); +} + +void CDataInfoManage::loadDevType() +{ + std::string strApplicationName = CN_AppName_BASE; + std::string strTableName = "dev_type_def"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("dev_type_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + m_devTypeMap.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + m_devTypeMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + m_rtdbAccess->close(); +} + +void CDataInfoManage::loadDevInfo() +{ + std::string strTableName = "dev_info"; + m_rtdbNetAcs->connect(m_nDomain, CN_AppId_PSCADA); + kbd_idlfile::RdbRet objRet; + std::vector columns; + columns.push_back("tag_name"); + columns.push_back("description"); + columns.push_back("location_id"); + columns.push_back("dev_type"); + + if(m_rtdbNetAcs->queryTotal(strTableName, columns, objRet)) + { + m_devInfoMap.clear(); + m_devDescMap.clear(); + int recordNum = objRet.msgrecord_size(); + for (int i = 0; i < recordNum; ++i) + { + std::string tag_name = objRet.msgrecord(i).msgvaluearray(0).strvalue(); + std::string description = objRet.msgrecord(i).msgvaluearray(1).strvalue(); + int location_id = objRet.msgrecord(i).msgvaluearray(2).nvalue(); + int dev_type = objRet.msgrecord(i).msgvaluearray(3).nvalue(); + + QPair pair; + pair.first = location_id; + pair.second = dev_type; + m_devInfoMap[QString::fromStdString(tag_name)] = pair; + m_devDescMap[QString::fromStdString(tag_name)] = QString::fromStdString(description); + } + } +} + +void CDataInfoManage::loadAlarmType() +{ + CDbApi dbRead(DB_CONN_MODEL_READ); + if(dbRead.open()) + { + QSqlQuery query; + QList columns; + columns.push_back("type_id"); + columns.push_back("macro_name"); + if(dbRead.select("alarm_type_define", columns, query)) + { + while(query.next()) + { + int alarm_type = query.value(0).toInt(); + QString macro_name = query.value(1).toString(); + if(macro_name.contains("SOE")) + { + m_nSoeType = alarm_type; + } + else if(macro_name.contains("CHANGE")) + { + m_nChgType = alarm_type; + } + } + } + } +} + +void CDataInfoManage::loadAlarmStatus() +{ + std::string strApplicationName = CN_AppName_BASE; + std::string strTableName = "alarm_status_define"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("alarm_type"); + columns.push_back("status_value"); + columns.push_back("alarm_manner"); + + if(m_rtdbAccess->select(result, columns)) + { + m_alarmStatusMap.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType alarm_type; + kbd_dbms::CVarType status_value; + kbd_dbms::CVarType alarm_manner; + result.getColumnValue(nIndex, 0, alarm_type); + result.getColumnValue(nIndex, 1, status_value); + result.getColumnValue(nIndex, 2, alarm_manner); + + QPair pair; + pair.first = alarm_type.toInt(); + pair.second = status_value.toInt(); + m_alarmStatusMap[pair] = alarm_manner.toInt(); + } + } + } + m_rtdbAccess->close(); +} + +void CDataInfoManage::loadAlarmManner() +{ + std::string strApplicationName = CN_AppName_BASE; + std::string strTableName = "alarm_manner_define"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("manner_id"); + columns.push_back("alarm_priority"); + + if(m_rtdbAccess->select(result, columns)) + { + m_alarmMannerMap.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + m_alarmMannerMap[key.toInt()] = value.toInt(); + } + } + } + m_rtdbAccess->close(); +} + +void CDataInfoManage::loadDevPoint() +{ + QList listTable; + listTable.append("analog"); + listTable.append("digital"); + listTable.append("accuml"); + listTable.append("mix"); + + m_devPointMap.clear(); + m_customAlarmDevMap.clear(); + for(int nIndex=0; nIndexconnect(m_nDomain, CN_AppId_PSCADA); + kbd_idlfile::RdbRet objRet; + std::vector columns; + columns.push_back("tag_name"); + columns.push_back("device"); + if(listTable[nIndex] == "digital") + { + columns.push_back("is_obj_alm_manner"); + columns.push_back("alarm_priority"); + columns.push_back("alarm_priority_soe"); + } + else if(listTable[nIndex] == "mix") + { + columns.push_back("is_obj_alm_manner"); + columns.push_back("alarm_priority"); + } + + if(m_rtdbNetAcs->queryTotal(listTable[nIndex].toStdString().c_str(), columns, objRet)) + { + int recordNum = objRet.msgrecord_size(); + for (int i = 0; i < recordNum; ++i) + { + std::string key = objRet.msgrecord(i).msgvaluearray(0).strvalue(); + std::string device = objRet.msgrecord(i).msgvaluearray(1).strvalue(); + + m_devPointMap[QString::fromStdString(device)][listTable[nIndex]] + .append(QString::fromStdString(key)); + + int is_obj_alm_manner; + int alarm_priority; + int alarm_priority_soe; + if(listTable[nIndex] == "digital" || listTable[nIndex] == "mix") + { + is_obj_alm_manner = objRet.msgrecord(i).msgvaluearray(2).nvalue(); + if(is_obj_alm_manner != 1) + { + continue; + } + alarm_priority = objRet.msgrecord(i).msgvaluearray(3).nvalue(); + if(listTable[nIndex] == "digital") + { + alarm_priority_soe = objRet.msgrecord(i).msgvaluearray(4).nvalue(); + } + else + { + alarm_priority_soe = -1; + } + QPair pair; + pair.first = alarm_priority; + pair.second = alarm_priority_soe; + m_customAlarmDevMap[QString::fromStdString(key)] = pair; + } + } + } + } +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CDataInfoManage.h b/product/src/gui/plugin/AlarmStatisWidget/CDataInfoManage.h index 5b0c80fa..736628a0 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CDataInfoManage.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CDataInfoManage.h @@ -1,66 +1,66 @@ -#ifndef CDATAINFOMANAGE_H -#define CDATAINFOMANAGE_H - -#include "Common.h" -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/rdb_net_api/CRdbNetApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include - -class CDataInfoManage -{ -public: - static CDataInfoManage * instance(); - - void destory(); - - QMap getAlarmLevel(); - QMap getAlarmOrder(); - QMap getLocation(); - QString getLocationDesc(int location); - QMap getDevType(); - QString getDevTypeDesc(int devType); - QStringList getDevice(int location = -1, int devType = -1); - QPair getDeviceBelong(const QString &device); - QString getDevDesc(const QString &device); - QMap getPoint(const QString &device); - bool getCustomAlmLevel(const QString &key, QPair &pair); - int getAlarmManner(const QPair &alarm); - int getAlarmPriority(const int &alarmManner); - int getChgType(); - int getSoeType(); - -private: - CDataInfoManage(); - - void loadAlarmLevel(); - void loadLocation(); - void loadDevType(); - void loadDevInfo(); - void loadAlarmType(); - void loadAlarmStatus(); - void loadAlarmManner(); - void loadDevPoint(); - -private: - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CRdbNetApi * m_rtdbNetAcs; - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; - int m_nDomain; - QMap m_alarmLevelMap; //< alarm_level_define PRIORITY_ID - PRIORITY_NAME - QMap m_alarmOrderMap; //< alarm_level_define PRIORITY_ID - PRIORITY_ORDER - QMap m_locationMap; //< sys_model_location_info, LOCATION_ID - QMap m_devTypeMap; //< dev_type_def, DEV_TYPE_ID - DESCRIPTION - QMap > m_devInfoMap; //< dev_info, TAG_NAME - - QMap m_devDescMap; // dev_info TAG_NAME - DESCRIPTION - QMap > m_customAlarmDevMap; //< dev_info.TAG_NAME - - QMap, int> m_alarmStatusMap; //< alarm_status_define, - ALARM_MANNER - QMap m_alarmMannerMap; //< alarm_manner_define, MANNER_ID - ALARM_PRIORITY - QMap> m_devPointMap;//< DEVICE - - int m_nChgType; - int m_nSoeType; - - static CDataInfoManage * m_pInstance; -}; - -#endif // CDATAINFOMANAGE_H +#ifndef CDATAINFOMANAGE_H +#define CDATAINFOMANAGE_H + +#include "Common.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_net_api/CRdbNetApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include + +class CDataInfoManage +{ +public: + static CDataInfoManage * instance(); + + void destory(); + + QMap getAlarmLevel(); + QMap getAlarmOrder(); + QMap getLocation(); + QString getLocationDesc(int location); + QMap getDevType(); + QString getDevTypeDesc(int devType); + QStringList getDevice(int location = -1, int devType = -1); + QPair getDeviceBelong(const QString &device); + QString getDevDesc(const QString &device); + QMap getPoint(const QString &device); + bool getCustomAlmLevel(const QString &key, QPair &pair); + int getAlarmManner(const QPair &alarm); + int getAlarmPriority(const int &alarmManner); + int getChgType(); + int getSoeType(); + +private: + CDataInfoManage(); + + void loadAlarmLevel(); + void loadLocation(); + void loadDevType(); + void loadDevInfo(); + void loadAlarmType(); + void loadAlarmStatus(); + void loadAlarmManner(); + void loadDevPoint(); + +private: + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CRdbNetApi * m_rtdbNetAcs; + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; + int m_nDomain; + QMap m_alarmLevelMap; //< alarm_level_define PRIORITY_ID - PRIORITY_NAME + QMap m_alarmOrderMap; //< alarm_level_define PRIORITY_ID - PRIORITY_ORDER + QMap m_locationMap; //< sys_model_location_info, LOCATION_ID + QMap m_devTypeMap; //< dev_type_def, DEV_TYPE_ID - DESCRIPTION + QMap > m_devInfoMap; //< dev_info, TAG_NAME - + QMap m_devDescMap; // dev_info TAG_NAME - DESCRIPTION + QMap > m_customAlarmDevMap; //< dev_info.TAG_NAME - + QMap, int> m_alarmStatusMap; //< alarm_status_define, - ALARM_MANNER + QMap m_alarmMannerMap; //< alarm_manner_define, MANNER_ID - ALARM_PRIORITY + QMap> m_devPointMap;//< DEVICE - + int m_nChgType; + int m_nSoeType; + + static CDataInfoManage * m_pInstance; +}; + +#endif // CDATAINFOMANAGE_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CDrillDownChart.cpp b/product/src/gui/plugin/AlarmStatisWidget/CDrillDownChart.cpp index 213f3eff..ae0805dd 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CDrillDownChart.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CDrillDownChart.cpp @@ -1,295 +1,295 @@ -#include "CDrillDownChart.h" -#include "widget/CToolTip.h" -#include - -CDrillDownChart::CDrillDownChart(QWidget *parent) - : QChartView(parent), - m_parent(parent), - m_currentSeries(0), - m_pTip(Q_NULLPTR), - m_labelColor(Qt::black), - m_gridLineColor("#cccfd9"), - m_labelsColor("#666666"), - m_titleColor(Qt::black), - m_legendColor(Qt::black), - m_backgroundColor(Qt::white) -{ - m_pChart = new QChart(); - m_pChart->setAnimationOptions(QChart::SeriesAnimations); - clearSeries(); - setStyleSheet("background-color:transparent"); - setRenderHint(QPainter::Antialiasing); - setChart(m_pChart); -} - -CDrillDownChart::~CDrillDownChart() -{ - if(m_pTip) - { - delete m_pTip; - } - m_pTip = Q_NULLPTR; - - if(m_currentSeries) - { - delete m_currentSeries; - } - m_currentSeries = Q_NULLPTR; - - if(m_pChart) - { - delete m_pChart; - } - m_pChart = Q_NULLPTR; - m_parent = Q_NULLPTR; -} - -void CDrillDownChart::clearSeries() -{ - if (m_currentSeries) - m_pChart->removeSeries(m_currentSeries); - - QBarCategoryAxis *axisX = new QBarCategoryAxis(); - axisX->append(tr("位置")); - axisX->setGridLineColor(m_gridLineColor); - axisX->setLabelsColor(m_labelsColor); - QValueAxis *axisY = new QValueAxis(); - axisY->setGridLineColor(m_gridLineColor); - axisY->setLabelsColor(m_labelsColor); - axisY->setMin(0); - axisY->setMax(1); - m_pChart->setAxisX(axisX); - m_pChart->setAxisY(axisY); -} - -void CDrillDownChart::updateSeries(const QString &title, const QStringList &alarmLevel, - const QMap > &locDevMap, - const QMap > > &locLevelMap, - const QString &tip) -{ - const QStringList location = locDevMap.keys(); - CDrillDownSeries *locSeries = new CDrillDownSeries(location, this); - locSeries->setName(title); - - for (int locIndex = 0; locIndex < location.count(); locIndex++) { - const QStringList devType = locDevMap[location[locIndex]]; - CDrillDownSeries *devSeries = new CDrillDownSeries(devType, this); - locSeries->mapDrilldownSeries(locIndex, devSeries); - - for (int devIndex = 0; devIndex < devType.count(); devIndex++) { - devSeries->mapDrilldownSeries(devIndex, locSeries); - devSeries->setName(location[locIndex]); - } - - QObject::connect(devSeries, &CDrillDownSeries::clicked, - this, &CDrillDownChart::handleClicked); - QObject::connect(devSeries, &CDrillDownSeries::hovered, - this, &CDrillDownChart::handleHovered); - } - - QObject::connect(locSeries, &CDrillDownSeries::clicked, - this, &CDrillDownChart::handleClicked); - QObject::connect(locSeries, &CDrillDownSeries::hovered, - this, &CDrillDownChart::handleHovered); - - for (int levIndex = 0; levIndex < alarmLevel.count(); levIndex++) - { - QBarSet *locCrop = new QBarSet(alarmLevel.at(levIndex)); - locCrop->setLabelColor(m_labelColor); - if(m_listColor.length() > levIndex) - locCrop->setBrush(m_listColor.at(levIndex)); - for (int locIndex = 0; locIndex < location.count(); locIndex++) - { - QBarSet *devCrop = new QBarSet(alarmLevel.at(levIndex)); - devCrop->setLabelColor(m_labelColor); - if(m_listColor.length() > levIndex) - devCrop->setBrush(m_listColor.at(levIndex)); - - const QList> devType = locLevelMap[location[locIndex]]; - for (int devIndex = 0; devIndex < devType.count(); devIndex++) - { - *devCrop << devType[devIndex].value(levIndex); - } - - locSeries->drilldownSeries(locIndex)->append(devCrop); - *locCrop << devCrop->sum(); - } - locSeries->append(locCrop); - } - - changeSeries(locSeries); - m_pChart->setTitle(locSeries->name()); - setTip(tip); - - m_pChart->legend()->setVisible(true); -} - -void CDrillDownChart::setColorList(const QList &listColor) -{ - m_listColor = listColor; -} - -void CDrillDownChart::setTipVisible(bool visible) -{ - if(m_pTip) - { - m_pTip->setVisible(visible); - } - - QList seriesList = m_pChart->series(); - if(seriesList.length() <= 0) - { - return; - } - - CDrillDownSeries *drSeries = dynamic_cast(seriesList[0]); - drSeries->setLabelsPosition(QAbstractBarSeries::LabelsCenter); - drSeries->setLabelsVisible(visible); -} - -QColor CDrillDownChart::labelColor() -{ - return m_labelColor; -} - -void CDrillDownChart::setLabelColor(const QColor &color) -{ - m_labelColor = color; -} - -QColor CDrillDownChart::gridLineColor() -{ - return m_gridLineColor; -} - -void CDrillDownChart::setGridLineColor(const QColor &color) -{ - m_gridLineColor = color; - m_pChart->axisX()->setGridLineColor(color); - m_pChart->axisY()->setGridLineColor(color); -} - -QColor CDrillDownChart::labelsColor() -{ - return m_labelsColor; -} - -void CDrillDownChart::setLabelsColor(const QColor &color) -{ - m_labelsColor = color; - m_pChart->axisX()->setLabelsColor(color); - m_pChart->axisY()->setLabelsColor(color); -} - -QColor CDrillDownChart::titleColor() -{ - return m_titleColor; -} - -void CDrillDownChart::setTitleColor(const QColor &color) -{ - m_titleColor = color; - m_pChart->setTitleBrush(m_titleColor); -} - -QColor CDrillDownChart::legendColor() -{ - return m_legendColor; -} - -void CDrillDownChart::setLegendColor(const QColor &color) -{ - m_legendColor = color; - m_pChart->legend()->setLabelColor(m_legendColor); -} - -QColor CDrillDownChart::backgroundColor() -{ - return m_backgroundColor; -} - -void CDrillDownChart::setBackgroundColor(const QColor &color) -{ - m_backgroundColor = color; - m_pChart->setBackgroundBrush(color); -} - -void CDrillDownChart::handleClicked(int index, QBarSet *barset) -{ - Q_UNUSED(barset) - CDrillDownSeries *series = static_cast(sender()); - changeSeries(series->drilldownSeries(index)); - emit sigHandleClicked(series->categories().value(index)); -} - -void CDrillDownChart::handleHovered(bool status, int index, QBarSet *barset) -{ - Q_UNUSED(barset) - if(status) - { - QList seriesList = m_pChart->series(); - if(seriesList.length() <= 0) - { - return; - } - QString text; - qreal total = 0; - CDrillDownSeries *drSeries = dynamic_cast(seriesList[0]); - QList barList = drSeries->barSets(); - for(int nIndex(0); nIndexat(index); - text += barList[nIndex]->label() + ": " + QString::number(barList[nIndex]->at(index), 'f', 0) + "\n"; - } - text.push_front(tr("总共: ") + QString::number(total, 'f', 0) + "\n"); - text.remove(-1, 2); - - QPoint point = QCursor::pos(); - CToolTip::popup(QPoint(point.x()-70, point.y()-100), text, m_parent); - } -} - -void CDrillDownChart::changeSeries(CDrillDownSeries *series) -{ - if (m_currentSeries) - m_pChart->removeSeries(m_currentSeries); - - m_currentSeries = series; - - QBarCategoryAxis *axisX = new QBarCategoryAxis(); - axisX->setGridLineColor(m_gridLineColor); - axisX->setLabelsColor(m_labelsColor); - axisX->append(m_currentSeries->categories()); - if(m_currentSeries->categories().length() > 25) - { - axisX->setLabelsAngle(90); - } - else if(m_currentSeries->categories().length() > 15) - { - axisX->setLabelsAngle(-45); - } - - QValueAxis *axisY = new QValueAxis(); - axisY->setGridLineColor(m_gridLineColor); - axisY->setLabelsColor(m_labelsColor); - - m_pChart->addSeries(series); - - m_pChart->createDefaultAxes(); - m_pChart->setAxisX(axisX, series); - m_pChart->setAxisY(axisY, series); - m_pChart->axisX()->setGridLineVisible(false); - - m_pChart->setTitle(series->name()); -} - -void CDrillDownChart::setTip(const QString &tip) -{ - if(m_pTip == Q_NULLPTR) - { - m_pTip = new QGraphicsSimpleTextItem(m_pChart); - } - m_pTip->setText(tip); - m_pTip->setPos(0, 0); - m_pTip->hide(); -} +#include "CDrillDownChart.h" +#include "widget/CToolTip.h" +#include + +CDrillDownChart::CDrillDownChart(QWidget *parent) + : QChartView(parent), + m_parent(parent), + m_currentSeries(0), + m_pTip(Q_NULLPTR), + m_labelColor(Qt::black), + m_gridLineColor("#cccfd9"), + m_labelsColor("#666666"), + m_titleColor(Qt::black), + m_legendColor(Qt::black), + m_backgroundColor(Qt::white) +{ + m_pChart = new QChart(); + m_pChart->setAnimationOptions(QChart::SeriesAnimations); + clearSeries(); + setStyleSheet("background-color:transparent"); + setRenderHint(QPainter::Antialiasing); + setChart(m_pChart); +} + +CDrillDownChart::~CDrillDownChart() +{ + if(m_pTip) + { + delete m_pTip; + } + m_pTip = Q_NULLPTR; + + if(m_currentSeries) + { + delete m_currentSeries; + } + m_currentSeries = Q_NULLPTR; + + if(m_pChart) + { + delete m_pChart; + } + m_pChart = Q_NULLPTR; + m_parent = Q_NULLPTR; +} + +void CDrillDownChart::clearSeries() +{ + if (m_currentSeries) + m_pChart->removeSeries(m_currentSeries); + + QBarCategoryAxis *axisX = new QBarCategoryAxis(); + axisX->append(tr("位置")); + axisX->setGridLineColor(m_gridLineColor); + axisX->setLabelsColor(m_labelsColor); + QValueAxis *axisY = new QValueAxis(); + axisY->setGridLineColor(m_gridLineColor); + axisY->setLabelsColor(m_labelsColor); + axisY->setMin(0); + axisY->setMax(1); + m_pChart->setAxisX(axisX); + m_pChart->setAxisY(axisY); +} + +void CDrillDownChart::updateSeries(const QString &title, const QStringList &alarmLevel, + const QMap > &locDevMap, + const QMap > > &locLevelMap, + const QString &tip) +{ + const QStringList location = locDevMap.keys(); + CDrillDownSeries *locSeries = new CDrillDownSeries(location, this); + locSeries->setName(title); + + for (int locIndex = 0; locIndex < location.count(); locIndex++) { + const QStringList devType = locDevMap[location[locIndex]]; + CDrillDownSeries *devSeries = new CDrillDownSeries(devType, this); + locSeries->mapDrilldownSeries(locIndex, devSeries); + + for (int devIndex = 0; devIndex < devType.count(); devIndex++) { + devSeries->mapDrilldownSeries(devIndex, locSeries); + devSeries->setName(location[locIndex]); + } + + QObject::connect(devSeries, &CDrillDownSeries::clicked, + this, &CDrillDownChart::handleClicked); + QObject::connect(devSeries, &CDrillDownSeries::hovered, + this, &CDrillDownChart::handleHovered); + } + + QObject::connect(locSeries, &CDrillDownSeries::clicked, + this, &CDrillDownChart::handleClicked); + QObject::connect(locSeries, &CDrillDownSeries::hovered, + this, &CDrillDownChart::handleHovered); + + for (int levIndex = 0; levIndex < alarmLevel.count(); levIndex++) + { + QBarSet *locCrop = new QBarSet(alarmLevel.at(levIndex)); + locCrop->setLabelColor(m_labelColor); + if(m_listColor.length() > levIndex) + locCrop->setBrush(m_listColor.at(levIndex)); + for (int locIndex = 0; locIndex < location.count(); locIndex++) + { + QBarSet *devCrop = new QBarSet(alarmLevel.at(levIndex)); + devCrop->setLabelColor(m_labelColor); + if(m_listColor.length() > levIndex) + devCrop->setBrush(m_listColor.at(levIndex)); + + const QList> devType = locLevelMap[location[locIndex]]; + for (int devIndex = 0; devIndex < devType.count(); devIndex++) + { + *devCrop << devType[devIndex].value(levIndex); + } + + locSeries->drilldownSeries(locIndex)->append(devCrop); + *locCrop << devCrop->sum(); + } + locSeries->append(locCrop); + } + + changeSeries(locSeries); + m_pChart->setTitle(locSeries->name()); + setTip(tip); + + m_pChart->legend()->setVisible(true); +} + +void CDrillDownChart::setColorList(const QList &listColor) +{ + m_listColor = listColor; +} + +void CDrillDownChart::setTipVisible(bool visible) +{ + if(m_pTip) + { + m_pTip->setVisible(visible); + } + + QList seriesList = m_pChart->series(); + if(seriesList.length() <= 0) + { + return; + } + + CDrillDownSeries *drSeries = dynamic_cast(seriesList[0]); + drSeries->setLabelsPosition(QAbstractBarSeries::LabelsCenter); + drSeries->setLabelsVisible(visible); +} + +QColor CDrillDownChart::labelColor() +{ + return m_labelColor; +} + +void CDrillDownChart::setLabelColor(const QColor &color) +{ + m_labelColor = color; +} + +QColor CDrillDownChart::gridLineColor() +{ + return m_gridLineColor; +} + +void CDrillDownChart::setGridLineColor(const QColor &color) +{ + m_gridLineColor = color; + m_pChart->axisX()->setGridLineColor(color); + m_pChart->axisY()->setGridLineColor(color); +} + +QColor CDrillDownChart::labelsColor() +{ + return m_labelsColor; +} + +void CDrillDownChart::setLabelsColor(const QColor &color) +{ + m_labelsColor = color; + m_pChart->axisX()->setLabelsColor(color); + m_pChart->axisY()->setLabelsColor(color); +} + +QColor CDrillDownChart::titleColor() +{ + return m_titleColor; +} + +void CDrillDownChart::setTitleColor(const QColor &color) +{ + m_titleColor = color; + m_pChart->setTitleBrush(m_titleColor); +} + +QColor CDrillDownChart::legendColor() +{ + return m_legendColor; +} + +void CDrillDownChart::setLegendColor(const QColor &color) +{ + m_legendColor = color; + m_pChart->legend()->setLabelColor(m_legendColor); +} + +QColor CDrillDownChart::backgroundColor() +{ + return m_backgroundColor; +} + +void CDrillDownChart::setBackgroundColor(const QColor &color) +{ + m_backgroundColor = color; + m_pChart->setBackgroundBrush(color); +} + +void CDrillDownChart::handleClicked(int index, QBarSet *barset) +{ + Q_UNUSED(barset) + CDrillDownSeries *series = static_cast(sender()); + changeSeries(series->drilldownSeries(index)); + emit sigHandleClicked(series->categories().value(index)); +} + +void CDrillDownChart::handleHovered(bool status, int index, QBarSet *barset) +{ + Q_UNUSED(barset) + if(status) + { + QList seriesList = m_pChart->series(); + if(seriesList.length() <= 0) + { + return; + } + QString text; + qreal total = 0; + CDrillDownSeries *drSeries = dynamic_cast(seriesList[0]); + QList barList = drSeries->barSets(); + for(int nIndex(0); nIndexat(index); + text += barList[nIndex]->label() + ": " + QString::number(barList[nIndex]->at(index), 'f', 0) + "\n"; + } + text.push_front(tr("总共: ") + QString::number(total, 'f', 0) + "\n"); + text.remove(-1, 2); + + QPoint point = QCursor::pos(); + CToolTip::popup(QPoint(point.x()-70, point.y()-100), text, m_parent); + } +} + +void CDrillDownChart::changeSeries(CDrillDownSeries *series) +{ + if (m_currentSeries) + m_pChart->removeSeries(m_currentSeries); + + m_currentSeries = series; + + QBarCategoryAxis *axisX = new QBarCategoryAxis(); + axisX->setGridLineColor(m_gridLineColor); + axisX->setLabelsColor(m_labelsColor); + axisX->append(m_currentSeries->categories()); + if(m_currentSeries->categories().length() > 25) + { + axisX->setLabelsAngle(90); + } + else if(m_currentSeries->categories().length() > 15) + { + axisX->setLabelsAngle(-45); + } + + QValueAxis *axisY = new QValueAxis(); + axisY->setGridLineColor(m_gridLineColor); + axisY->setLabelsColor(m_labelsColor); + + m_pChart->addSeries(series); + + m_pChart->createDefaultAxes(); + m_pChart->setAxisX(axisX, series); + m_pChart->setAxisY(axisY, series); + m_pChart->axisX()->setGridLineVisible(false); + + m_pChart->setTitle(series->name()); +} + +void CDrillDownChart::setTip(const QString &tip) +{ + if(m_pTip == Q_NULLPTR) + { + m_pTip = new QGraphicsSimpleTextItem(m_pChart); + } + m_pTip->setText(tip); + m_pTip->setPos(0, 0); + m_pTip->hide(); +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CDrillDownChart.h b/product/src/gui/plugin/AlarmStatisWidget/CDrillDownChart.h index 562362dc..7b5eb16e 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CDrillDownChart.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CDrillDownChart.h @@ -1,77 +1,77 @@ -#ifndef CDRILLDOWNCHART_H -#define CDRILLDOWNCHART_H - -#include -#include -#include -#include "CDrillDownSeries.h" - -class CDrillDownChart : public QChartView -{ - Q_OBJECT - Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) - Q_PROPERTY(QColor gridLineColor READ gridLineColor WRITE setGridLineColor) - Q_PROPERTY(QColor labelsColor READ labelsColor WRITE setLabelsColor) - Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor) - Q_PROPERTY(QColor legendColor READ legendColor WRITE setLegendColor) - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) -public: - explicit CDrillDownChart(QWidget *parent = Q_NULLPTR); - ~CDrillDownChart(); - - void updateSeries(const QString &title, - const QStringList &alarmLevel, - const QMap>& locDevMap, - const QMap > > &locLevelMap, - const QString &tip = QString()); - - void clearSeries(); - - void setColorList(const QList &listColor); - - void setTipVisible(bool visible); - - QColor labelColor(); - void setLabelColor(const QColor &color); - - QColor gridLineColor(); - void setGridLineColor(const QColor &color); - - QColor labelsColor(); - void setLabelsColor(const QColor &color); - - QColor titleColor(); - void setTitleColor(const QColor &color); - - QColor legendColor(); - void setLegendColor(const QColor &color); - - QColor backgroundColor(); - void setBackgroundColor(const QColor &color); - -signals: - void sigHandleClicked(const QString &name); - -public slots: - void handleClicked(int index, QBarSet *barset); - void handleHovered(bool status, int index, QBarSet *barset); - -private: - void changeSeries(CDrillDownSeries *series); - void setTip(const QString &tip); - -private: - QWidget * m_parent; - QChart * m_pChart; - CDrillDownSeries *m_currentSeries; - QList m_listColor; - QGraphicsSimpleTextItem *m_pTip; - QColor m_labelColor; - QColor m_gridLineColor; - QColor m_labelsColor; - QColor m_titleColor; - QColor m_legendColor; - QColor m_backgroundColor; -}; - -#endif // CDRILLDOWNCHART_H +#ifndef CDRILLDOWNCHART_H +#define CDRILLDOWNCHART_H + +#include +#include +#include +#include "CDrillDownSeries.h" + +class CDrillDownChart : public QChartView +{ + Q_OBJECT + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QColor gridLineColor READ gridLineColor WRITE setGridLineColor) + Q_PROPERTY(QColor labelsColor READ labelsColor WRITE setLabelsColor) + Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor) + Q_PROPERTY(QColor legendColor READ legendColor WRITE setLegendColor) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) +public: + explicit CDrillDownChart(QWidget *parent = Q_NULLPTR); + ~CDrillDownChart(); + + void updateSeries(const QString &title, + const QStringList &alarmLevel, + const QMap>& locDevMap, + const QMap > > &locLevelMap, + const QString &tip = QString()); + + void clearSeries(); + + void setColorList(const QList &listColor); + + void setTipVisible(bool visible); + + QColor labelColor(); + void setLabelColor(const QColor &color); + + QColor gridLineColor(); + void setGridLineColor(const QColor &color); + + QColor labelsColor(); + void setLabelsColor(const QColor &color); + + QColor titleColor(); + void setTitleColor(const QColor &color); + + QColor legendColor(); + void setLegendColor(const QColor &color); + + QColor backgroundColor(); + void setBackgroundColor(const QColor &color); + +signals: + void sigHandleClicked(const QString &name); + +public slots: + void handleClicked(int index, QBarSet *barset); + void handleHovered(bool status, int index, QBarSet *barset); + +private: + void changeSeries(CDrillDownSeries *series); + void setTip(const QString &tip); + +private: + QWidget * m_parent; + QChart * m_pChart; + CDrillDownSeries *m_currentSeries; + QList m_listColor; + QGraphicsSimpleTextItem *m_pTip; + QColor m_labelColor; + QColor m_gridLineColor; + QColor m_labelsColor; + QColor m_titleColor; + QColor m_legendColor; + QColor m_backgroundColor; +}; + +#endif // CDRILLDOWNCHART_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CDrillDownSeries.cpp b/product/src/gui/plugin/AlarmStatisWidget/CDrillDownSeries.cpp index f0b0e13d..4c321449 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CDrillDownSeries.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CDrillDownSeries.cpp @@ -1,22 +1,22 @@ -#include "CDrillDownSeries.h" - -CDrillDownSeries::CDrillDownSeries(QStringList categories, QObject *parent) - : QStackedBarSeries(parent) -{ - m_categories = categories; -} - -void CDrillDownSeries::mapDrilldownSeries(int index, CDrillDownSeries *drilldownSeries) -{ - m_DrilldownSeries[index] = drilldownSeries; -} - -CDrillDownSeries *CDrillDownSeries::drilldownSeries(int index) -{ - return m_DrilldownSeries[index]; -} - -QStringList CDrillDownSeries::categories() -{ - return m_categories; -} +#include "CDrillDownSeries.h" + +CDrillDownSeries::CDrillDownSeries(QStringList categories, QObject *parent) + : QStackedBarSeries(parent) +{ + m_categories = categories; +} + +void CDrillDownSeries::mapDrilldownSeries(int index, CDrillDownSeries *drilldownSeries) +{ + m_DrilldownSeries[index] = drilldownSeries; +} + +CDrillDownSeries *CDrillDownSeries::drilldownSeries(int index) +{ + return m_DrilldownSeries[index]; +} + +QStringList CDrillDownSeries::categories() +{ + return m_categories; +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CDrillDownSeries.h b/product/src/gui/plugin/AlarmStatisWidget/CDrillDownSeries.h index d2ef5dd1..04973bf3 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CDrillDownSeries.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CDrillDownSeries.h @@ -1,26 +1,26 @@ -#ifndef CDRILLDOWNSERIES_H -#define CDRILLDOWNSERIES_H - -#include -#include - -QT_CHARTS_USE_NAMESPACE - -class CDrillDownSeries : public QStackedBarSeries -{ - Q_OBJECT -public: - CDrillDownSeries(QStringList categories, QObject *parent = 0); - - void mapDrilldownSeries(int index, CDrillDownSeries *drilldownSeries); - - CDrillDownSeries *drilldownSeries(int index); - - QStringList categories(); - -private: - QMap m_DrilldownSeries; - QStringList m_categories; -}; - -#endif // CDRILLDOWNSERIES_H +#ifndef CDRILLDOWNSERIES_H +#define CDRILLDOWNSERIES_H + +#include +#include + +QT_CHARTS_USE_NAMESPACE + +class CDrillDownSeries : public QStackedBarSeries +{ + Q_OBJECT +public: + CDrillDownSeries(QStringList categories, QObject *parent = 0); + + void mapDrilldownSeries(int index, CDrillDownSeries *drilldownSeries); + + CDrillDownSeries *drilldownSeries(int index); + + QStringList categories(); + +private: + QMap m_DrilldownSeries; + QStringList m_categories; +}; + +#endif // CDRILLDOWNSERIES_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CHisEventManage.cpp b/product/src/gui/plugin/AlarmStatisWidget/CHisEventManage.cpp index 6dca0157..1e53a114 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CHisEventManage.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CHisEventManage.cpp @@ -1,101 +1,101 @@ -#include "CHisEventManage.h" -#include "CDataInfoManage.h" -#include "public/pub_logger_api/logger.h" -#include - -CHisEventManage::CHisEventManage(QObject *parent) - : QObject(parent) -{ -} - -void CHisEventManage::release() -{ - delete this; -} - -void CHisEventManage::queryHisEventStatis(int location, int devType, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode) -{ - QTime time; - time.start(); - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - if(!getValidTsdbConnPtr(tsdbConnPtr)) - { - LOGERROR("CTsdbQuery: 未获取到有效的TSDB连接!"); - emit updateHisEventStatis(QMap >()); - return; - } - - QMap > record; - QStringList devList = CDataInfoManage::instance()->getDevice(location, devType); - for(int nIndex=0; nIndex selectedList, qint64 startTime, qint64 endTime, EN_STATIS_STYLE style) -{ - QTime time; - time.start(); - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - if(!getValidTsdbConnPtr(tsdbConnPtr)) - { - LOGERROR("CTsdbQuery: 未获取到有效的TSDB连接!"); - emit updateHisEventContrast(QMap >()); - return; - } - - QMap > record; - foreach (int select, selectedList) { - QStringList devList; - if(STYLE_LOCATION == style) - { - devList = CDataInfoManage::instance()->getDevice(select, -1); - } - else if(STYLE_DEVTYPE == style) - { - devList = CDataInfoManage::instance()->getDevice(-1, select); - } - for(int nIndex=0; nIndexpingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - } - else - { - m_tsdbConnPtr = getOneUseableConn(true); - if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - else - { - m_tsdbConnPtr = getOneUseableConn(false); - if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - } - } - return false; -} +#include "CHisEventManage.h" +#include "CDataInfoManage.h" +#include "public/pub_logger_api/logger.h" +#include + +CHisEventManage::CHisEventManage(QObject *parent) + : QObject(parent) +{ +} + +void CHisEventManage::release() +{ + delete this; +} + +void CHisEventManage::queryHisEventStatis(int location, int devType, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode) +{ + QTime time; + time.start(); + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + if(!getValidTsdbConnPtr(tsdbConnPtr)) + { + LOGERROR("CTsdbQuery: 未获取到有效的TSDB连接!"); + emit updateHisEventStatis(QMap >()); + return; + } + + QMap > record; + QStringList devList = CDataInfoManage::instance()->getDevice(location, devType); + for(int nIndex=0; nIndex selectedList, qint64 startTime, qint64 endTime, EN_STATIS_STYLE style) +{ + QTime time; + time.start(); + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + if(!getValidTsdbConnPtr(tsdbConnPtr)) + { + LOGERROR("CTsdbQuery: 未获取到有效的TSDB连接!"); + emit updateHisEventContrast(QMap >()); + return; + } + + QMap > record; + foreach (int select, selectedList) { + QStringList devList; + if(STYLE_LOCATION == style) + { + devList = CDataInfoManage::instance()->getDevice(select, -1); + } + else if(STYLE_DEVTYPE == style) + { + devList = CDataInfoManage::instance()->getDevice(-1, select); + } + for(int nIndex=0; nIndexpingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + else + { + m_tsdbConnPtr = getOneUseableConn(true); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + else + { + m_tsdbConnPtr = getOneUseableConn(false); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + } + return false; +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CHisEventManage.h b/product/src/gui/plugin/AlarmStatisWidget/CHisEventManage.h index b7ced644..a1c9795f 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CHisEventManage.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CHisEventManage.h @@ -1,33 +1,33 @@ -#ifndef CHISEVENTMANAGE_H -#define CHISEVENTMANAGE_H - -#include -#include "CStatisCommon.h" -#include "CTsdbQuery.h" - -class CHisEventManage : public QObject -{ - Q_OBJECT -public: - CHisEventManage(QObject *parent = Q_NULLPTR); - - void release(); - -public slots: - void queryHisEventStatis(int location, int devType, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode); - - void queryHisEventContrast(QList selectedList, qint64 startTime, qint64 endTime, EN_STATIS_STYLE style); - -private: - bool getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr); - -signals: - void updateHisEventStatis(const QMap > &event); - - void updateHisEventContrast(const QMap > &event); - -private: - kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; -}; - -#endif // CHISEVENTMANAGE_H +#ifndef CHISEVENTMANAGE_H +#define CHISEVENTMANAGE_H + +#include +#include "CStatisCommon.h" +#include "CTsdbQuery.h" + +class CHisEventManage : public QObject +{ + Q_OBJECT +public: + CHisEventManage(QObject *parent = Q_NULLPTR); + + void release(); + +public slots: + void queryHisEventStatis(int location, int devType, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode); + + void queryHisEventContrast(QList selectedList, qint64 startTime, qint64 endTime, EN_STATIS_STYLE style); + +private: + bool getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr); + +signals: + void updateHisEventStatis(const QMap > &event); + + void updateHisEventContrast(const QMap > &event); + +private: + kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; +}; + +#endif // CHISEVENTMANAGE_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CMainWidget.cpp b/product/src/gui/plugin/AlarmStatisWidget/CMainWidget.cpp index 74fff131..fe25fcaf 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CMainWidget.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CMainWidget.cpp @@ -1,179 +1,179 @@ -#include "CMainWidget.h" -#include "CStatisWidget.h" -#include "ContrastWidget.h" -#include "CHisEventManage.h" -#include "tsdb_api/TsdbApi.h" -#include "pub_utility_api/FileStyle.h" -#include "pub_utility_api/FileUtil.h" -#include -#include -#include -#include -#include - -CMainWidget::CMainWidget(bool editMode, QVector ptrVec, QWidget *parent) - : QWidget(parent), - m_editMode(editMode), - m_pStatisWidget(Q_NULLPTR), - m_pContrastWidget(Q_NULLPTR), - m_pHisEventThread(Q_NULLPTR), - m_pHisEventManage(Q_NULLPTR) -{ - Q_UNUSED(ptrVec) - - initialize(); -} - -CMainWidget::~CMainWidget() -{ - if(!m_editMode) - { - kbd_dbms::releaseTsdbApi(); - } - - if(m_pHisEventManage) - { - emit releaseHisEventThread(); - m_pHisEventManage = Q_NULLPTR; - } - - if(m_pHisEventThread) - { - m_pHisEventThread->quit(); - m_pHisEventThread->wait(); - } - m_pHisEventThread = Q_NULLPTR; - - if(m_pStatisWidget) - { - delete m_pStatisWidget; - } - m_pStatisWidget = Q_NULLPTR; - - if(m_pContrastWidget) - { - delete m_pContrastWidget; - } - m_pContrastWidget = Q_NULLPTR; - - CDataInfoManage::instance()->destory(); -} - -void CMainWidget::initialize() -{ - m_pStatisWidget = new CStatisWidget(m_editMode, this); - m_pContrastWidget = new ContrastWidget(m_editMode, this); - - QTabWidget *widget = new QTabWidget(); - widget->addTab(m_pStatisWidget, tr("告警统计")); - widget->addTab(m_pContrastWidget, tr("告警对比")); - QGridLayout *layout = new QGridLayout(); - layout->addWidget(widget); - layout->setMargin(6); - setLayout(layout); - - initStyleSheet(); - - if(!m_editMode) - { - kbd_dbms::initTsdbApi(); - - loadAlarmColor(); - - initHisEventManage(); - } -} - -void CMainWidget::initStyleSheet() -{ - QString style = QString(); - std::string strFullPath = kbd_public::CFileStyle - ::getPathOfStyleFile("public.qss") ; - QFile file1(QString::fromStdString(strFullPath)); - if (file1.open(QIODevice::ReadOnly)) - { - QTextStream styleStream(&file1); - style += styleStream.readAll(); - //setStyleSheet(style); - } - file1.close(); - - strFullPath = kbd_public::CFileStyle - ::getPathOfStyleFile("AlarmStatisWidget.qss") ; - QFile file2(QString::fromStdString(strFullPath)); - if (file2.open(QIODevice::ReadOnly)) - { - QTextStream styleStream(&file2); - style += styleStream.readAll(); - //setStyleSheet(style); - } - file2.close(); - if(!style.isEmpty()) - { - setStyleSheet(style); - } -} - -void CMainWidget::loadAlarmColor() -{ - QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) - + QString("../../data/model/alarm_color_define.xml"); - - QDomDocument document; - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly)) - { - return; - } - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - QMap almColorMap; - QDomElement element = document.documentElement(); - QDomNode node = element.firstChild(); - while(!node.isNull()) - { - QDomElement attr = node.toElement(); - if(!attr.isNull()) - { - if(QString("Level") == attr.tagName()) - { - int priority = attr.attribute("priority").toInt(); - QColor color = QColor(attr.attribute("active_text_color")); - almColorMap[priority] = color; - } - } - node = node.nextSibling(); - } - - QList listColor; - QMap orderMap = CDataInfoManage::instance()->getAlarmOrder(); - QMap::const_iterator iter = orderMap.constBegin(); - for(; iter != orderMap.constEnd(); iter++) - { - listColor.append(almColorMap.value(iter.value(), Qt::black)); - } - m_pStatisWidget->setCurveColor(listColor); - m_pContrastWidget->setCurveColor(listColor); -} - -void CMainWidget::initHisEventManage() -{ - m_pHisEventManage = new CHisEventManage; - m_pHisEventThread = new QThread(this); - m_pHisEventManage->moveToThread(m_pHisEventThread); - connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); - connect(this, &CMainWidget::releaseHisEventThread, m_pHisEventManage, &CHisEventManage::release, Qt::BlockingQueuedConnection); - - connect(m_pStatisWidget, &CStatisWidget::sigQueryEvent, m_pHisEventManage, &CHisEventManage::queryHisEventStatis, Qt::QueuedConnection); - connect(m_pHisEventManage, &CHisEventManage::updateHisEventStatis, m_pStatisWidget, &CStatisWidget::updateEventNum ,Qt::QueuedConnection); - - connect(m_pContrastWidget, &ContrastWidget::sigQueryEvent, m_pHisEventManage, &CHisEventManage::queryHisEventContrast, Qt::QueuedConnection); - connect(m_pHisEventManage, &CHisEventManage::updateHisEventContrast, m_pContrastWidget, &ContrastWidget::updateEventNum, Qt::QueuedConnection); - - m_pHisEventThread->start(); -} +#include "CMainWidget.h" +#include "CStatisWidget.h" +#include "ContrastWidget.h" +#include "CHisEventManage.h" +#include "tsdb_api/TsdbApi.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_utility_api/FileUtil.h" +#include +#include +#include +#include +#include + +CMainWidget::CMainWidget(bool editMode, QVector ptrVec, QWidget *parent) + : QWidget(parent), + m_editMode(editMode), + m_pStatisWidget(Q_NULLPTR), + m_pContrastWidget(Q_NULLPTR), + m_pHisEventThread(Q_NULLPTR), + m_pHisEventManage(Q_NULLPTR) +{ + Q_UNUSED(ptrVec) + + initialize(); +} + +CMainWidget::~CMainWidget() +{ + if(!m_editMode) + { + kbd_dbms::releaseTsdbApi(); + } + + if(m_pHisEventManage) + { + emit releaseHisEventThread(); + m_pHisEventManage = Q_NULLPTR; + } + + if(m_pHisEventThread) + { + m_pHisEventThread->quit(); + m_pHisEventThread->wait(); + } + m_pHisEventThread = Q_NULLPTR; + + if(m_pStatisWidget) + { + delete m_pStatisWidget; + } + m_pStatisWidget = Q_NULLPTR; + + if(m_pContrastWidget) + { + delete m_pContrastWidget; + } + m_pContrastWidget = Q_NULLPTR; + + CDataInfoManage::instance()->destory(); +} + +void CMainWidget::initialize() +{ + m_pStatisWidget = new CStatisWidget(m_editMode, this); + m_pContrastWidget = new ContrastWidget(m_editMode, this); + + QTabWidget *widget = new QTabWidget(); + widget->addTab(m_pStatisWidget, tr("告警统计")); + widget->addTab(m_pContrastWidget, tr("告警对比")); + QGridLayout *layout = new QGridLayout(); + layout->addWidget(widget); + layout->setMargin(6); + setLayout(layout); + + initStyleSheet(); + + if(!m_editMode) + { + kbd_dbms::initTsdbApi(); + + loadAlarmColor(); + + initHisEventManage(); + } +} + +void CMainWidget::initStyleSheet() +{ + QString style = QString(); + std::string strFullPath = kbd_public::CFileStyle + ::getPathOfStyleFile("public.qss") ; + QFile file1(QString::fromStdString(strFullPath)); + if (file1.open(QIODevice::ReadOnly)) + { + QTextStream styleStream(&file1); + style += styleStream.readAll(); + //setStyleSheet(style); + } + file1.close(); + + strFullPath = kbd_public::CFileStyle + ::getPathOfStyleFile("AlarmStatisWidget.qss") ; + QFile file2(QString::fromStdString(strFullPath)); + if (file2.open(QIODevice::ReadOnly)) + { + QTextStream styleStream(&file2); + style += styleStream.readAll(); + //setStyleSheet(style); + } + file2.close(); + if(!style.isEmpty()) + { + setStyleSheet(style); + } +} + +void CMainWidget::loadAlarmColor() +{ + QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + + QString("../../data/model/alarm_color_define.xml"); + + QDomDocument document; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QMap almColorMap; + QDomElement element = document.documentElement(); + QDomNode node = element.firstChild(); + while(!node.isNull()) + { + QDomElement attr = node.toElement(); + if(!attr.isNull()) + { + if(QString("Level") == attr.tagName()) + { + int priority = attr.attribute("priority").toInt(); + QColor color = QColor(attr.attribute("active_text_color")); + almColorMap[priority] = color; + } + } + node = node.nextSibling(); + } + + QList listColor; + QMap orderMap = CDataInfoManage::instance()->getAlarmOrder(); + QMap::const_iterator iter = orderMap.constBegin(); + for(; iter != orderMap.constEnd(); iter++) + { + listColor.append(almColorMap.value(iter.value(), Qt::black)); + } + m_pStatisWidget->setCurveColor(listColor); + m_pContrastWidget->setCurveColor(listColor); +} + +void CMainWidget::initHisEventManage() +{ + m_pHisEventManage = new CHisEventManage; + m_pHisEventThread = new QThread(this); + m_pHisEventManage->moveToThread(m_pHisEventThread); + connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); + connect(this, &CMainWidget::releaseHisEventThread, m_pHisEventManage, &CHisEventManage::release, Qt::BlockingQueuedConnection); + + connect(m_pStatisWidget, &CStatisWidget::sigQueryEvent, m_pHisEventManage, &CHisEventManage::queryHisEventStatis, Qt::QueuedConnection); + connect(m_pHisEventManage, &CHisEventManage::updateHisEventStatis, m_pStatisWidget, &CStatisWidget::updateEventNum ,Qt::QueuedConnection); + + connect(m_pContrastWidget, &ContrastWidget::sigQueryEvent, m_pHisEventManage, &CHisEventManage::queryHisEventContrast, Qt::QueuedConnection); + connect(m_pHisEventManage, &CHisEventManage::updateHisEventContrast, m_pContrastWidget, &ContrastWidget::updateEventNum, Qt::QueuedConnection); + + m_pHisEventThread->start(); +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CMainWidget.h b/product/src/gui/plugin/AlarmStatisWidget/CMainWidget.h index 045f1ac7..3618aa21 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CMainWidget.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CMainWidget.h @@ -1,35 +1,35 @@ -#ifndef CMAINWIDGET_H -#define CMAINWIDGET_H - -#include -#include - -class CStatisWidget; -class ContrastWidget; -class CHisEventManage; -class CMainWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CMainWidget(bool editMode, QVector ptrVec, QWidget *parent = 0); - ~CMainWidget(); - -signals: - void releaseHisEventThread(); - -private: - void initialize(); - void initStyleSheet(); - void loadAlarmColor(); - void initHisEventManage(); - -private: - bool m_editMode; - CStatisWidget * m_pStatisWidget; - ContrastWidget * m_pContrastWidget; - QThread *m_pHisEventThread; - CHisEventManage *m_pHisEventManage; -}; - -#endif // CMAINWIDGET_H +#ifndef CMAINWIDGET_H +#define CMAINWIDGET_H + +#include +#include + +class CStatisWidget; +class ContrastWidget; +class CHisEventManage; +class CMainWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CMainWidget(bool editMode, QVector ptrVec, QWidget *parent = 0); + ~CMainWidget(); + +signals: + void releaseHisEventThread(); + +private: + void initialize(); + void initStyleSheet(); + void loadAlarmColor(); + void initHisEventManage(); + +private: + bool m_editMode; + CStatisWidget * m_pStatisWidget; + ContrastWidget * m_pContrastWidget; + QThread *m_pHisEventThread; + CHisEventManage *m_pHisEventManage; +}; + +#endif // CMAINWIDGET_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CStatisCommon.h b/product/src/gui/plugin/AlarmStatisWidget/CStatisCommon.h index 17d46502..512de15a 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CStatisCommon.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CStatisCommon.h @@ -1,35 +1,35 @@ -#ifndef CSTATISCOMMON_H -#define CSTATISCOMMON_H - -#include -#include - -const std::string CN_AppName_PSCADA = "PSCADA"; -const int CN_AppId_PSCADA = 4; -const int LINE_X_MAX_TICK = 32; -const int SERIOUS_DEV_NUM = 5; - -enum EN_STATIS_MODE -{ - MODE_DAY = 0, - MODE_MONTH, - MODE_YEAR -}; - -enum EN_STATIS_STYLE -{ - STYLE_LOCATION = 0, - STYLE_DEVTYPE -}; - -struct SHisData -{ - qint64 time; - EN_STATIS_MODE mode; - QString location; - QString devType; - QList number; -}; - - -#endif // CSTATISCOMMON_H +#ifndef CSTATISCOMMON_H +#define CSTATISCOMMON_H + +#include +#include + +const std::string CN_AppName_PSCADA = "PSCADA"; +const int CN_AppId_PSCADA = 4; +const int LINE_X_MAX_TICK = 32; +const int SERIOUS_DEV_NUM = 5; + +enum EN_STATIS_MODE +{ + MODE_DAY = 0, + MODE_MONTH, + MODE_YEAR +}; + +enum EN_STATIS_STYLE +{ + STYLE_LOCATION = 0, + STYLE_DEVTYPE +}; + +struct SHisData +{ + qint64 time; + EN_STATIS_MODE mode; + QString location; + QString devType; + QList number; +}; + + +#endif // CSTATISCOMMON_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.cpp b/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.cpp index 8dd89324..7ba1e438 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.cpp @@ -1,536 +1,536 @@ -#include "CStatisWidget.h" -#include "ui_CStatisWidget.h" -#include "CTableViewExport.h" -#include "CCurveChartView.h" -#include -#include -#include -#include -#include - -CStatisWidget::CStatisWidget(bool editMode, QWidget *parent) : - QWidget(parent), - ui(new Ui::CStatisWidget), - m_model(Q_NULLPTR) -{ - ui->setupUi(this); - - initView(); - - if(!editMode) - { - qRegisterMetaType< EN_STATIS_MODE >("EN_STATIS_MODE"); - initData(); - } -} - -CStatisWidget::~CStatisWidget() -{ - if(m_model) - { - delete m_model; - } - m_model = Q_NULLPTR; - - if(m_pCurve) - { - delete m_pCurve; - } - m_pCurve = Q_NULLPTR; - delete ui; -} - -void CStatisWidget::setCurveColor(const QList &color) -{ - m_pCurve->setColorList(color); -} - -int CStatisWidget::currentLocationId() -{ - return ui->m_locationComb->currentData().toInt(); -} - -QString CStatisWidget::currentLocation() -{ - return ui->m_locationComb->currentText(); -} - -int CStatisWidget::currentDevType() -{ - return ui->m_devTypeComb->currentData().toInt(); -} - -QString CStatisWidget::currentDevTyepDesc() -{ - return ui->m_devTypeComb->currentText(); -} - -EN_STATIS_MODE CStatisWidget::currentStaisMode() -{ - return EN_STATIS_MODE(ui->m_statisticComb->currentData().toInt()); -} - -qint64 CStatisWidget::currentStartTime() -{ - return ui->m_startTime->dateTime().toMSecsSinceEpoch(); -} - -qint64 CStatisWidget::currentEndTime() -{ - return ui->m_endTime->dateTime().toMSecsSinceEpoch(); -} - -QString CStatisWidget::currentFormat() -{ - QString ret; - switch (currentStaisMode()) { - case MODE_DAY:{ - ret = "yyyy-MM-dd"; - break; - } - case MODE_MONTH:{ - ret = "yyyy-MM-dd"; - break; - } - case MODE_YEAR:{ - ret = "yyyy"; - break; - } - default: - break; - } - return ret; -} - -qint64 CStatisWidget::getAddMses(qint64 time, int add) -{ - qint64 ret; - QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(time); - switch (currentStaisMode()) { - case MODE_DAY:{ - ret = dateTime.addDays(add).toMSecsSinceEpoch(); - break; - } - case MODE_MONTH:{ - ret = dateTime.addMonths(add).toMSecsSinceEpoch(); - break; - } - case MODE_YEAR:{ - ret = dateTime.addYears(add).toMSecsSinceEpoch(); - break; - } - default: - break; - } - return ret; -} - -void CStatisWidget::initView() -{ - ui->m_statisTable->horizontalHeader()->setStretchLastSection(true); - ui->m_statisTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - ui->m_statisTable->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->m_statisTable->verticalHeader()->setVisible(false); - - ui->m_switchBtn->setMinimumWidth(60); - ui->m_switchBtn->setText(tr("报表")); - ui->m_switchBtn->setCheckedText(tr("图表")); - - m_pCurve = new CCurveChartView(); - QGridLayout *layout = new QGridLayout(); - layout->addWidget(m_pCurve); - layout->setMargin(0); - ui->m_lineChart->setLayout(layout); - - ui->m_printBtn->setVisible(false); - ui->m_alarmLevel->setEnabled(false); -} - -void CStatisWidget::initData() -{ - QMap locationMap = CDataInfoManage::instance()->getLocation(); - QMap::const_iterator locationIter = locationMap.constBegin(); - for(; locationIter != locationMap.constEnd(); ++locationIter) - { - foreach (QString locStr, locationIter.value()) { - QStringList temp = locStr.split(","); - if(temp.length() != 3) - { - continue; - } - if(temp[2] != "0") - { - continue; - } - ui->m_locationComb->addItem(temp[1], QString(temp[0]).toInt()); - } - } - - QMap devTypeMap = CDataInfoManage::instance()->getDevType(); - QMap::const_iterator devTypeIter = devTypeMap.constBegin(); - for(; devTypeIter != devTypeMap.constEnd(); ++devTypeIter) - { - ui->m_devTypeComb->addItem(devTypeIter.value(), devTypeIter.key()); - } - - ui->m_statisticComb->addItem(tr("日统计"), MODE_DAY); - ui->m_statisticComb->addItem(tr("月统计"), MODE_MONTH); - ui->m_statisticComb->addItem(tr("年统计"), MODE_YEAR); - - QMap alarmLevel = CDataInfoManage::instance()->getAlarmLevel(); - m_model = new CTableModel(ui->m_statisTable, alarmLevel.values()); - ui->m_statisTable->setModel(m_model); - - QMap::const_iterator iter = alarmLevel.constBegin(); - QHBoxLayout *layout = new QHBoxLayout; - for(; iter != alarmLevel.constEnd(); iter++) - { - QCheckBox *checkBox = new QCheckBox(iter.value(), this); - checkBox->setChecked(true); - layout->addWidget(checkBox); - m_alarmLevelMap.insert(iter.key(), checkBox); - connect(checkBox, SIGNAL(toggled(bool)), this, SLOT(slotLevelChange(bool))); - } - layout->setMargin(0); - ui->m_alarmLevel->setLayout(layout); - - connect(ui->m_switchBtn, SIGNAL(toggled(bool)), this, SLOT(slotModeSwitch(bool))); - connect(ui->m_startTime->calendarWidget(), SIGNAL(currentPageChanged(int,int)), this, SLOT(slotStartPageChanged(int,int))); - connect(ui->m_endTime->calendarWidget(), SIGNAL(currentPageChanged(int,int)), this, SLOT(slotEndPageChanged(int,int))); -} - -void CStatisWidget::on_m_statisticComb_currentIndexChanged(int index) -{ - switch (index) { - case MODE_DAY:{ - ui->m_startTime->setDisplayFormat("yyyy-MM-dd"); - ui->m_endTime->setDisplayFormat("yyyy-MM-dd"); - - QDateTime dateTime = QDateTime::currentDateTime(); - dateTime.setTime(QTime(0,0,0,0)); - ui->m_startTime->setDateTime(dateTime); - dateTime.setTime(QTime(23,59,59,999)); - ui->m_endTime->setDateTime(dateTime); - break; - } - case MODE_MONTH:{ - ui->m_startTime->setDisplayFormat("yyyy-MM"); - ui->m_endTime->setDisplayFormat("yyyy-MM"); - - QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(currentStartTime()); - QDate date = dateTime.date(); - date.setDate(date.year(), date.month(), 1); - ui->m_startTime->setDateTime(QDateTime(date, QTime(0,0,0,0))); - date.setDate(date.year(), date.month(), date.daysInMonth()); - ui->m_endTime->setDateTime(QDateTime(date, QTime(23,59,59,999))); - break; - } - case MODE_YEAR:{ - ui->m_startTime->setDisplayFormat("yyyy"); - ui->m_endTime->setDisplayFormat("yyyy"); - - QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(currentStartTime()); - QDate date = dateTime.date(); - date.setDate(date.year(), 1, 1); - ui->m_startTime->setDateTime(QDateTime(date, QTime(0,0,0,0))); - date.setDate(date.year(), 12, 31); - ui->m_endTime->setDateTime(QDateTime(date, QTime(23,59,59,999))); - break; - } - default: - break; - } -} - -void CStatisWidget::on_m_endTime_dateChanged(const QDate &date) -{ - if(currentStaisMode() != MODE_MONTH) - { - return; - } - blockSignals(true); - QDate dateTemp(date.year(), date.month(), date.daysInMonth()); - ui->m_endTime->setDateTime(QDateTime(dateTemp, QTime(23,59,59,999))); - blockSignals(false); -} - -void CStatisWidget::on_m_searchBtn_clicked() -{ - ui->m_searchBtn->setEnabled(false); - ui->m_alarmLevel->setEnabled(false); - m_model->clear(); - m_pCurve->clearSeries(); - if(!searchEnable()) - { - ui->m_searchBtn->setEnabled(true); - if(ui->m_switchBtn->isToggled()) - ui->m_alarmLevel->setEnabled(true); - return; - } - - emit sigQueryEvent(currentLocationId(), currentDevType(), currentStartTime(), currentEndTime(), currentStaisMode()); -} - -void CStatisWidget::on_m_excelBtn_clicked() -{ - CTableViewExport paint; - paint.paintExcel(ui->m_statisTable); -} - -void CStatisWidget::on_m_pdfBtn_clicked() -{ - CTableViewExport paint; - paint.paintPdf(ui->m_statisTable); -} - -void CStatisWidget::on_m_printBtn_clicked() -{ - QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/default.jpg"), tr("(*.jpg)")); - if(strFileName.isEmpty()) - { - return; - } - - m_pCurve->setTextItemVisible(true); - QImage buffer = ui->m_lineChart->grab().toImage(); - m_pCurve->setTextItemVisible(false); - int dotsPerMeter = 96/0.0254; - buffer.setDotsPerMeterX(dotsPerMeter); - buffer.setDotsPerMeterY(dotsPerMeter); - if (!buffer.isNull()) - { - if(buffer.save(strFileName, "JPG", -1)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+strFileName); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } - } -} - -void CStatisWidget::slotModeSwitch(bool checked) -{ - if(checked) - { - ui->stackedWidget->setCurrentIndex(1); - } - else - { - ui->stackedWidget->setCurrentIndex(0); - } - - if(ui->m_searchBtn->isEnabled()) - ui->m_alarmLevel->setEnabled(checked); - ui->m_excelBtn->setVisible(!checked); - ui->m_pdfBtn->setVisible(!checked); - ui->m_printBtn->setVisible(checked); - QMap::const_iterator iter = m_alarmLevelMap.constBegin(); - for(; iter != m_alarmLevelMap.constEnd(); iter++) - { - iter.value()->setChecked(true); - } -} - -void CStatisWidget::slotLevelChange(bool checked) -{ - QCheckBox *box = static_cast(sender()); - if(box) - { - m_pCurve->setSeriesVisible(box->text(), checked); - } -} - -void CStatisWidget::slotStartPageChanged(int year, int month) -{ - EN_STATIS_MODE mode = currentStaisMode(); - if(MODE_MONTH == mode || MODE_YEAR == mode) - { - QDate date = ui->m_startTime->date(); - date.setDate(year, month, 1); - ui->m_startTime->setDate(date); - } -} - -void CStatisWidget::slotEndPageChanged(int year, int month) -{ - EN_STATIS_MODE mode = currentStaisMode(); - if(MODE_MONTH == mode || MODE_YEAR == mode) - { - QDate date = ui->m_endTime->date(); - date.setDate(year, month, 1); - ui->m_endTime->setDate(date); - } -} - -void CStatisWidget::updateEventNum(const QMap > &hisEventMap) -{ - if(hisEventMap.isEmpty()) - { - ui->m_searchBtn->setEnabled(true); - if(ui->m_switchBtn->isToggled()) - ui->m_alarmLevel->setEnabled(true); - return; - } - - QList dataList; - parseEvent(hisEventMap, dataList); - updateTable(dataList); - updateCurve(dataList); - - ui->m_searchBtn->setEnabled(true); - if(ui->m_switchBtn->isToggled()) - ui->m_alarmLevel->setEnabled(true); -} - -void CStatisWidget::parseEvent(const QMap> &hisEventMap, QList &dataList) -{ - QList levelList = m_alarmLevelMap.keys(); - QList temp; - for(int n=0; n >::ConstIterator iter = hisEventMap.constBegin(); - while(iter != hisEventMap.constEnd()) - { - SHisData data; - data.mode = currentStaisMode(); - data.location = currentLocation(); - data.devType = currentDevTyepDesc(); - data.time = iter.key(); - data.number = temp; - - const QMap& number = iter.value(); - QMap::ConstIterator numIter = number.constBegin(); - int index = -1; - for(; numIter != number.constEnd(); ++numIter) - { - index = levelList.indexOf(numIter.key()); - if(index == -1) - { - continue; - } - data.number.replace(index, numIter.value()); - } - dataList.append(data); - ++iter; - } -} - -void CStatisWidget::updateTable(const QList &dataList) -{ - m_model->update(dataList); -} - -void CStatisWidget::updateCurve(const QList &dataList) -{ - m_pCurve->clearSeries(); - m_pCurve->setAxisXFormat(currentFormat()); - if(dataList.first().time == dataList.last().time) - { - m_pCurve->setAxisXRange(getAddMses(dataList.first().time, -1), - getAddMses(dataList.first().time, 1)); - } - else - { - m_pCurve->setAxisXRange(dataList.first().time, - dataList.last().time); - } - if(dataList.length() > LINE_X_MAX_TICK) - { - m_pCurve->setAxisXTickCount(LINE_X_MAX_TICK); - } - else - { - m_pCurve->setAxisXTickCount(dataList.length()); - } - if(dataList.length() > LINE_X_MAX_TICK / 2) - { - m_pCurve->setAxisXPixelSize(9); - } - else - { - m_pCurve->setAxisXPixelSize(12); - } - - QList> seriesList; - for(int n=0; n()); - } - - for(int nIndex(0); nIndex eventList = dataList[nIndex].number; - for(int nLevel(0); nLevelinsertLineSeries(seriesList[nIndex], m_alarmLevelMap.values()[nIndex]->text(), - currentLocation(), currentDevTyepDesc()); - } -} - -bool CStatisWidget::searchEnable() -{ - if(currentEndTime() < currentStartTime()) - { - QMessageBox::information(this, tr("提示"), tr("结束时间不能小于开始时间!"), QMessageBox::Ok); - return false; - } - - switch (currentStaisMode()) { - case MODE_DAY: - { - if(currentEndTime() > ui->m_startTime->dateTime().addDays(31).toMSecsSinceEpoch()) - { - QMessageBox::information(this, tr("提示"), tr("日统计最多查询31天!"), QMessageBox::Ok); - return false; - } - break; - } - case MODE_MONTH: - { - if(currentEndTime() > ui->m_startTime->dateTime().addMonths(12).toMSecsSinceEpoch()) - { - QMessageBox::information(this, tr("提示"), tr("月统计最多查询12月!"), QMessageBox::Ok); - return false; - } - break; - } - case MODE_YEAR: - { - if(currentEndTime() > ui->m_startTime->dateTime().addYears(2).toMSecsSinceEpoch()) - { - QMessageBox::information(this, tr("提示"), tr("年统计最多查询2年!"), QMessageBox::Ok); - return false; - } - break; - } - default: - break; - } - - bool check = false; - QMap::const_iterator iter = m_alarmLevelMap.constBegin(); - for(; iter != m_alarmLevelMap.constEnd(); iter++) - { - if(iter.value()->isChecked()) - { - check = true; - } - iter.value()->setChecked(true); - } - if(!check) - { - QMessageBox::information(this, tr("提示"), tr("至少勾选一个告警等级!"), QMessageBox::Ok); - return false; - } - return true; -} +#include "CStatisWidget.h" +#include "ui_CStatisWidget.h" +#include "CTableViewExport.h" +#include "CCurveChartView.h" +#include +#include +#include +#include +#include + +CStatisWidget::CStatisWidget(bool editMode, QWidget *parent) : + QWidget(parent), + ui(new Ui::CStatisWidget), + m_model(Q_NULLPTR) +{ + ui->setupUi(this); + + initView(); + + if(!editMode) + { + qRegisterMetaType< EN_STATIS_MODE >("EN_STATIS_MODE"); + initData(); + } +} + +CStatisWidget::~CStatisWidget() +{ + if(m_model) + { + delete m_model; + } + m_model = Q_NULLPTR; + + if(m_pCurve) + { + delete m_pCurve; + } + m_pCurve = Q_NULLPTR; + delete ui; +} + +void CStatisWidget::setCurveColor(const QList &color) +{ + m_pCurve->setColorList(color); +} + +int CStatisWidget::currentLocationId() +{ + return ui->m_locationComb->currentData().toInt(); +} + +QString CStatisWidget::currentLocation() +{ + return ui->m_locationComb->currentText(); +} + +int CStatisWidget::currentDevType() +{ + return ui->m_devTypeComb->currentData().toInt(); +} + +QString CStatisWidget::currentDevTyepDesc() +{ + return ui->m_devTypeComb->currentText(); +} + +EN_STATIS_MODE CStatisWidget::currentStaisMode() +{ + return EN_STATIS_MODE(ui->m_statisticComb->currentData().toInt()); +} + +qint64 CStatisWidget::currentStartTime() +{ + return ui->m_startTime->dateTime().toMSecsSinceEpoch(); +} + +qint64 CStatisWidget::currentEndTime() +{ + return ui->m_endTime->dateTime().toMSecsSinceEpoch(); +} + +QString CStatisWidget::currentFormat() +{ + QString ret; + switch (currentStaisMode()) { + case MODE_DAY:{ + ret = "yyyy-MM-dd"; + break; + } + case MODE_MONTH:{ + ret = "yyyy-MM-dd"; + break; + } + case MODE_YEAR:{ + ret = "yyyy"; + break; + } + default: + break; + } + return ret; +} + +qint64 CStatisWidget::getAddMses(qint64 time, int add) +{ + qint64 ret; + QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(time); + switch (currentStaisMode()) { + case MODE_DAY:{ + ret = dateTime.addDays(add).toMSecsSinceEpoch(); + break; + } + case MODE_MONTH:{ + ret = dateTime.addMonths(add).toMSecsSinceEpoch(); + break; + } + case MODE_YEAR:{ + ret = dateTime.addYears(add).toMSecsSinceEpoch(); + break; + } + default: + break; + } + return ret; +} + +void CStatisWidget::initView() +{ + ui->m_statisTable->horizontalHeader()->setStretchLastSection(true); + ui->m_statisTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + ui->m_statisTable->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->m_statisTable->verticalHeader()->setVisible(false); + + ui->m_switchBtn->setMinimumWidth(60); + ui->m_switchBtn->setText(tr("报表")); + ui->m_switchBtn->setCheckedText(tr("图表")); + + m_pCurve = new CCurveChartView(); + QGridLayout *layout = new QGridLayout(); + layout->addWidget(m_pCurve); + layout->setMargin(0); + ui->m_lineChart->setLayout(layout); + + ui->m_printBtn->setVisible(false); + ui->m_alarmLevel->setEnabled(false); +} + +void CStatisWidget::initData() +{ + QMap locationMap = CDataInfoManage::instance()->getLocation(); + QMap::const_iterator locationIter = locationMap.constBegin(); + for(; locationIter != locationMap.constEnd(); ++locationIter) + { + foreach (QString locStr, locationIter.value()) { + QStringList temp = locStr.split(","); + if(temp.length() != 3) + { + continue; + } + if(temp[2] != "0") + { + continue; + } + ui->m_locationComb->addItem(temp[1], QString(temp[0]).toInt()); + } + } + + QMap devTypeMap = CDataInfoManage::instance()->getDevType(); + QMap::const_iterator devTypeIter = devTypeMap.constBegin(); + for(; devTypeIter != devTypeMap.constEnd(); ++devTypeIter) + { + ui->m_devTypeComb->addItem(devTypeIter.value(), devTypeIter.key()); + } + + ui->m_statisticComb->addItem(tr("日统计"), MODE_DAY); + ui->m_statisticComb->addItem(tr("月统计"), MODE_MONTH); + ui->m_statisticComb->addItem(tr("年统计"), MODE_YEAR); + + QMap alarmLevel = CDataInfoManage::instance()->getAlarmLevel(); + m_model = new CTableModel(ui->m_statisTable, alarmLevel.values()); + ui->m_statisTable->setModel(m_model); + + QMap::const_iterator iter = alarmLevel.constBegin(); + QHBoxLayout *layout = new QHBoxLayout; + for(; iter != alarmLevel.constEnd(); iter++) + { + QCheckBox *checkBox = new QCheckBox(iter.value(), this); + checkBox->setChecked(true); + layout->addWidget(checkBox); + m_alarmLevelMap.insert(iter.key(), checkBox); + connect(checkBox, SIGNAL(toggled(bool)), this, SLOT(slotLevelChange(bool))); + } + layout->setMargin(0); + ui->m_alarmLevel->setLayout(layout); + + connect(ui->m_switchBtn, SIGNAL(toggled(bool)), this, SLOT(slotModeSwitch(bool))); + connect(ui->m_startTime->calendarWidget(), SIGNAL(currentPageChanged(int,int)), this, SLOT(slotStartPageChanged(int,int))); + connect(ui->m_endTime->calendarWidget(), SIGNAL(currentPageChanged(int,int)), this, SLOT(slotEndPageChanged(int,int))); +} + +void CStatisWidget::on_m_statisticComb_currentIndexChanged(int index) +{ + switch (index) { + case MODE_DAY:{ + ui->m_startTime->setDisplayFormat("yyyy-MM-dd"); + ui->m_endTime->setDisplayFormat("yyyy-MM-dd"); + + QDateTime dateTime = QDateTime::currentDateTime(); + dateTime.setTime(QTime(0,0,0,0)); + ui->m_startTime->setDateTime(dateTime); + dateTime.setTime(QTime(23,59,59,999)); + ui->m_endTime->setDateTime(dateTime); + break; + } + case MODE_MONTH:{ + ui->m_startTime->setDisplayFormat("yyyy-MM"); + ui->m_endTime->setDisplayFormat("yyyy-MM"); + + QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(currentStartTime()); + QDate date = dateTime.date(); + date.setDate(date.year(), date.month(), 1); + ui->m_startTime->setDateTime(QDateTime(date, QTime(0,0,0,0))); + date.setDate(date.year(), date.month(), date.daysInMonth()); + ui->m_endTime->setDateTime(QDateTime(date, QTime(23,59,59,999))); + break; + } + case MODE_YEAR:{ + ui->m_startTime->setDisplayFormat("yyyy"); + ui->m_endTime->setDisplayFormat("yyyy"); + + QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(currentStartTime()); + QDate date = dateTime.date(); + date.setDate(date.year(), 1, 1); + ui->m_startTime->setDateTime(QDateTime(date, QTime(0,0,0,0))); + date.setDate(date.year(), 12, 31); + ui->m_endTime->setDateTime(QDateTime(date, QTime(23,59,59,999))); + break; + } + default: + break; + } +} + +void CStatisWidget::on_m_endTime_dateChanged(const QDate &date) +{ + if(currentStaisMode() != MODE_MONTH) + { + return; + } + blockSignals(true); + QDate dateTemp(date.year(), date.month(), date.daysInMonth()); + ui->m_endTime->setDateTime(QDateTime(dateTemp, QTime(23,59,59,999))); + blockSignals(false); +} + +void CStatisWidget::on_m_searchBtn_clicked() +{ + ui->m_searchBtn->setEnabled(false); + ui->m_alarmLevel->setEnabled(false); + m_model->clear(); + m_pCurve->clearSeries(); + if(!searchEnable()) + { + ui->m_searchBtn->setEnabled(true); + if(ui->m_switchBtn->isToggled()) + ui->m_alarmLevel->setEnabled(true); + return; + } + + emit sigQueryEvent(currentLocationId(), currentDevType(), currentStartTime(), currentEndTime(), currentStaisMode()); +} + +void CStatisWidget::on_m_excelBtn_clicked() +{ + CTableViewExport paint; + paint.paintExcel(ui->m_statisTable); +} + +void CStatisWidget::on_m_pdfBtn_clicked() +{ + CTableViewExport paint; + paint.paintPdf(ui->m_statisTable); +} + +void CStatisWidget::on_m_printBtn_clicked() +{ + QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/default.jpg"), tr("(*.jpg)")); + if(strFileName.isEmpty()) + { + return; + } + + m_pCurve->setTextItemVisible(true); + QImage buffer = ui->m_lineChart->grab().toImage(); + m_pCurve->setTextItemVisible(false); + int dotsPerMeter = 96/0.0254; + buffer.setDotsPerMeterX(dotsPerMeter); + buffer.setDotsPerMeterY(dotsPerMeter); + if (!buffer.isNull()) + { + if(buffer.save(strFileName, "JPG", -1)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+strFileName); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } + } +} + +void CStatisWidget::slotModeSwitch(bool checked) +{ + if(checked) + { + ui->stackedWidget->setCurrentIndex(1); + } + else + { + ui->stackedWidget->setCurrentIndex(0); + } + + if(ui->m_searchBtn->isEnabled()) + ui->m_alarmLevel->setEnabled(checked); + ui->m_excelBtn->setVisible(!checked); + ui->m_pdfBtn->setVisible(!checked); + ui->m_printBtn->setVisible(checked); + QMap::const_iterator iter = m_alarmLevelMap.constBegin(); + for(; iter != m_alarmLevelMap.constEnd(); iter++) + { + iter.value()->setChecked(true); + } +} + +void CStatisWidget::slotLevelChange(bool checked) +{ + QCheckBox *box = static_cast(sender()); + if(box) + { + m_pCurve->setSeriesVisible(box->text(), checked); + } +} + +void CStatisWidget::slotStartPageChanged(int year, int month) +{ + EN_STATIS_MODE mode = currentStaisMode(); + if(MODE_MONTH == mode || MODE_YEAR == mode) + { + QDate date = ui->m_startTime->date(); + date.setDate(year, month, 1); + ui->m_startTime->setDate(date); + } +} + +void CStatisWidget::slotEndPageChanged(int year, int month) +{ + EN_STATIS_MODE mode = currentStaisMode(); + if(MODE_MONTH == mode || MODE_YEAR == mode) + { + QDate date = ui->m_endTime->date(); + date.setDate(year, month, 1); + ui->m_endTime->setDate(date); + } +} + +void CStatisWidget::updateEventNum(const QMap > &hisEventMap) +{ + if(hisEventMap.isEmpty()) + { + ui->m_searchBtn->setEnabled(true); + if(ui->m_switchBtn->isToggled()) + ui->m_alarmLevel->setEnabled(true); + return; + } + + QList dataList; + parseEvent(hisEventMap, dataList); + updateTable(dataList); + updateCurve(dataList); + + ui->m_searchBtn->setEnabled(true); + if(ui->m_switchBtn->isToggled()) + ui->m_alarmLevel->setEnabled(true); +} + +void CStatisWidget::parseEvent(const QMap> &hisEventMap, QList &dataList) +{ + QList levelList = m_alarmLevelMap.keys(); + QList temp; + for(int n=0; n >::ConstIterator iter = hisEventMap.constBegin(); + while(iter != hisEventMap.constEnd()) + { + SHisData data; + data.mode = currentStaisMode(); + data.location = currentLocation(); + data.devType = currentDevTyepDesc(); + data.time = iter.key(); + data.number = temp; + + const QMap& number = iter.value(); + QMap::ConstIterator numIter = number.constBegin(); + int index = -1; + for(; numIter != number.constEnd(); ++numIter) + { + index = levelList.indexOf(numIter.key()); + if(index == -1) + { + continue; + } + data.number.replace(index, numIter.value()); + } + dataList.append(data); + ++iter; + } +} + +void CStatisWidget::updateTable(const QList &dataList) +{ + m_model->update(dataList); +} + +void CStatisWidget::updateCurve(const QList &dataList) +{ + m_pCurve->clearSeries(); + m_pCurve->setAxisXFormat(currentFormat()); + if(dataList.first().time == dataList.last().time) + { + m_pCurve->setAxisXRange(getAddMses(dataList.first().time, -1), + getAddMses(dataList.first().time, 1)); + } + else + { + m_pCurve->setAxisXRange(dataList.first().time, + dataList.last().time); + } + if(dataList.length() > LINE_X_MAX_TICK) + { + m_pCurve->setAxisXTickCount(LINE_X_MAX_TICK); + } + else + { + m_pCurve->setAxisXTickCount(dataList.length()); + } + if(dataList.length() > LINE_X_MAX_TICK / 2) + { + m_pCurve->setAxisXPixelSize(9); + } + else + { + m_pCurve->setAxisXPixelSize(12); + } + + QList> seriesList; + for(int n=0; n()); + } + + for(int nIndex(0); nIndex eventList = dataList[nIndex].number; + for(int nLevel(0); nLevelinsertLineSeries(seriesList[nIndex], m_alarmLevelMap.values()[nIndex]->text(), + currentLocation(), currentDevTyepDesc()); + } +} + +bool CStatisWidget::searchEnable() +{ + if(currentEndTime() < currentStartTime()) + { + QMessageBox::information(this, tr("提示"), tr("结束时间不能小于开始时间!"), QMessageBox::Ok); + return false; + } + + switch (currentStaisMode()) { + case MODE_DAY: + { + if(currentEndTime() > ui->m_startTime->dateTime().addDays(31).toMSecsSinceEpoch()) + { + QMessageBox::information(this, tr("提示"), tr("日统计最多查询31天!"), QMessageBox::Ok); + return false; + } + break; + } + case MODE_MONTH: + { + if(currentEndTime() > ui->m_startTime->dateTime().addMonths(12).toMSecsSinceEpoch()) + { + QMessageBox::information(this, tr("提示"), tr("月统计最多查询12月!"), QMessageBox::Ok); + return false; + } + break; + } + case MODE_YEAR: + { + if(currentEndTime() > ui->m_startTime->dateTime().addYears(2).toMSecsSinceEpoch()) + { + QMessageBox::information(this, tr("提示"), tr("年统计最多查询2年!"), QMessageBox::Ok); + return false; + } + break; + } + default: + break; + } + + bool check = false; + QMap::const_iterator iter = m_alarmLevelMap.constBegin(); + for(; iter != m_alarmLevelMap.constEnd(); iter++) + { + if(iter.value()->isChecked()) + { + check = true; + } + iter.value()->setChecked(true); + } + if(!check) + { + QMessageBox::information(this, tr("提示"), tr("至少勾选一个告警等级!"), QMessageBox::Ok); + return false; + } + return true; +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.h b/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.h index 66df4932..b391d2af 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.h @@ -1,69 +1,69 @@ -#ifndef CSTATISWIDGET_H -#define CSTATISWIDGET_H - -#include -#include -#include "CTableModel.h" -#include "CDataInfoManage.h" - -namespace Ui { -class CStatisWidget; -} - -class CCurveChartView; -class CStatisWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CStatisWidget(bool editMode, QWidget *parent = 0); - ~CStatisWidget(); - - void setCurveColor(const QList &color); - - int currentLocationId(); - QString currentLocation(); - int currentDevType(); - QString currentDevTyepDesc(); - EN_STATIS_MODE currentStaisMode(); - qint64 currentStartTime(); - qint64 currentEndTime(); - QString currentFormat(); - qint64 getAddMses(qint64 time, int add); - -public slots: - void updateEventNum(const QMap > &hisEventMap); - -signals: - void sigQueryEvent(int location, int devType, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode); - -private slots: - void on_m_statisticComb_currentIndexChanged(int index); - void on_m_endTime_dateChanged(const QDate &date); - void on_m_searchBtn_clicked(); - void on_m_excelBtn_clicked(); - void on_m_pdfBtn_clicked(); - void on_m_printBtn_clicked(); - -private slots: - void slotModeSwitch(bool checked); - void slotLevelChange(bool checked); - void slotStartPageChanged(int year, int month); - void slotEndPageChanged(int year, int month); - -private: - void initView(); - void initData(); - void parseEvent(const QMap> &hisEventMap, QList &dataList); - void updateTable(const QList &dataList); - void updateCurve(const QList &dataList); - bool searchEnable(); - -private: - Ui::CStatisWidget *ui; - QMap m_alarmLevelMap; - CTableModel *m_model; - CCurveChartView *m_pCurve; -}; - -#endif // CSTATISWIDGET_H +#ifndef CSTATISWIDGET_H +#define CSTATISWIDGET_H + +#include +#include +#include "CTableModel.h" +#include "CDataInfoManage.h" + +namespace Ui { +class CStatisWidget; +} + +class CCurveChartView; +class CStatisWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CStatisWidget(bool editMode, QWidget *parent = 0); + ~CStatisWidget(); + + void setCurveColor(const QList &color); + + int currentLocationId(); + QString currentLocation(); + int currentDevType(); + QString currentDevTyepDesc(); + EN_STATIS_MODE currentStaisMode(); + qint64 currentStartTime(); + qint64 currentEndTime(); + QString currentFormat(); + qint64 getAddMses(qint64 time, int add); + +public slots: + void updateEventNum(const QMap > &hisEventMap); + +signals: + void sigQueryEvent(int location, int devType, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode); + +private slots: + void on_m_statisticComb_currentIndexChanged(int index); + void on_m_endTime_dateChanged(const QDate &date); + void on_m_searchBtn_clicked(); + void on_m_excelBtn_clicked(); + void on_m_pdfBtn_clicked(); + void on_m_printBtn_clicked(); + +private slots: + void slotModeSwitch(bool checked); + void slotLevelChange(bool checked); + void slotStartPageChanged(int year, int month); + void slotEndPageChanged(int year, int month); + +private: + void initView(); + void initData(); + void parseEvent(const QMap> &hisEventMap, QList &dataList); + void updateTable(const QList &dataList); + void updateCurve(const QList &dataList); + bool searchEnable(); + +private: + Ui::CStatisWidget *ui; + QMap m_alarmLevelMap; + CTableModel *m_model; + CCurveChartView *m_pCurve; +}; + +#endif // CSTATISWIDGET_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.ui b/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.ui index 2e794ac7..7f01ac89 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.ui +++ b/product/src/gui/plugin/AlarmStatisWidget/CStatisWidget.ui @@ -1,364 +1,364 @@ - - - CStatisWidget - - - - 0 - 0 - 1260 - 752 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 3 - - - 3 - - - 3 - - - 3 - - - 6 - - - 0 - - - - - 3 - - - 3 - - - 6 - - - - - - 80 - 0 - - - - 位置: - - - - - - - - 150 - 0 - - - - - - - - - 80 - 0 - - - - 统计方式: - - - - - - - - - - - - 3 - - - 6 - - - - - - 150 - 0 - - - - yyyy-MM-dd - - - true - - - - - - - - 80 - 0 - - - - 设备类型: - - - - - - - yyyy-MM-dd - - - true - - - - - - - - 80 - 0 - - - - 开始时间: - - - - - - - - 80 - 0 - - - - 结束时间: - - - - - - - - 150 - 0 - - - - - - - - 查询 - - - - - - - Qt::Horizontal - - - - 158 - 20 - - - - - - - - - - Qt::Horizontal - - - - 55 - 20 - - - - - - - - - - - 6 - - - 6 - - - - - 告警等级: - - - - - - - - - - - - - Excel - - - - - - - Pdf - - - - - - - 打印 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - CSWitchButton - QWidget -
./widget/CSWitchButton.h
- 1 -
-
- - -
+ + + CStatisWidget + + + + 0 + 0 + 1260 + 752 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + 3 + + + 3 + + + 3 + + + 3 + + + 6 + + + 0 + + + + + 3 + + + 3 + + + 6 + + + + + + 80 + 0 + + + + 位置: + + + + + + + + 150 + 0 + + + + + + + + + 80 + 0 + + + + 统计方式: + + + + + + + + + + + + 3 + + + 6 + + + + + + 150 + 0 + + + + yyyy-MM-dd + + + true + + + + + + + + 80 + 0 + + + + 设备类型: + + + + + + + yyyy-MM-dd + + + true + + + + + + + + 80 + 0 + + + + 开始时间: + + + + + + + + 80 + 0 + + + + 结束时间: + + + + + + + + 150 + 0 + + + + + + + + 查询 + + + + + + + Qt::Horizontal + + + + 158 + 20 + + + + + + + + + + Qt::Horizontal + + + + 55 + 20 + + + + + + + + + + + 6 + + + 6 + + + + + 告警等级: + + + + + + + + + + + + + Excel + + + + + + + Pdf + + + + + + + 打印 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + CSWitchButton + QWidget +
./widget/CSWitchButton.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/AlarmStatisWidget/CTableModel.cpp b/product/src/gui/plugin/AlarmStatisWidget/CTableModel.cpp index e6eeb97a..364e6566 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CTableModel.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CTableModel.cpp @@ -1,134 +1,134 @@ -#include "CTableModel.h" -#include - -CTableModel::CTableModel(QObject *parent, const QStringList &alarmLevel) - : QAbstractTableModel(parent) -{ - m_header << tr("统计日期") << tr("区域名称") << tr("设备类型"); - - for(int nIndex=0; nIndex &dataList) -{ - beginResetModel(); - m_dataList.clear(); - m_dataList = dataList; - endResetModel(); -} - -void CTableModel::clear() -{ - beginResetModel(); - m_dataList.clear(); - endResetModel(); -} - -QVariant CTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_header.at(section); - } - } - return QVariant(); -} - -int CTableModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_dataList.length(); -} - -int CTableModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.count(); -} - -QVariant CTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.row() > m_dataList.length()) - return QVariant(); - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - - if(Qt::DisplayRole != role) - { - return QVariant(); - } - - if(index.column() > COLUMN_DEVTYPE) - { - return m_dataList.at(index.row()).number.at(index.column() - 3); - } - - switch (index.column()) - { - case COLUMN_DATE: - { - return getDispDateTime(m_dataList.at(index.row()).time, m_dataList.at(index.row()).mode); - } - break; - case COLUMN_LOCATION: - { - return m_dataList.at(index.row()).location; - } - break; - case COLUMN_DEVTYPE: - { - return m_dataList.at(index.row()).devType; - } - break; - default: - break; - } - - return QVariant(); -} - -bool CTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_UNUSED(value); - Q_UNUSED(role); - if(!index.isValid()) - { - return false; - } - - return true; -} - -QString CTableModel::getDispDateTime(qint64 time, EN_STATIS_MODE mode) const -{ - QString ret; - switch (mode) { - case MODE_DAY:{ - ret = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM-dd"); - break; - } - case MODE_MONTH:{ - ret = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM"); - break; - } - case MODE_YEAR:{ - ret = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy"); - break; - } - default: - break; - } - return ret; -} +#include "CTableModel.h" +#include + +CTableModel::CTableModel(QObject *parent, const QStringList &alarmLevel) + : QAbstractTableModel(parent) +{ + m_header << tr("统计日期") << tr("区域名称") << tr("设备类型"); + + for(int nIndex=0; nIndex &dataList) +{ + beginResetModel(); + m_dataList.clear(); + m_dataList = dataList; + endResetModel(); +} + +void CTableModel::clear() +{ + beginResetModel(); + m_dataList.clear(); + endResetModel(); +} + +QVariant CTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); +} + +int CTableModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_dataList.length(); +} + +int CTableModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.count(); +} + +QVariant CTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() > m_dataList.length()) + return QVariant(); + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + if(index.column() > COLUMN_DEVTYPE) + { + return m_dataList.at(index.row()).number.at(index.column() - 3); + } + + switch (index.column()) + { + case COLUMN_DATE: + { + return getDispDateTime(m_dataList.at(index.row()).time, m_dataList.at(index.row()).mode); + } + break; + case COLUMN_LOCATION: + { + return m_dataList.at(index.row()).location; + } + break; + case COLUMN_DEVTYPE: + { + return m_dataList.at(index.row()).devType; + } + break; + default: + break; + } + + return QVariant(); +} + +bool CTableModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(value); + Q_UNUSED(role); + if(!index.isValid()) + { + return false; + } + + return true; +} + +QString CTableModel::getDispDateTime(qint64 time, EN_STATIS_MODE mode) const +{ + QString ret; + switch (mode) { + case MODE_DAY:{ + ret = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM-dd"); + break; + } + case MODE_MONTH:{ + ret = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy-MM"); + break; + } + case MODE_YEAR:{ + ret = QDateTime::fromMSecsSinceEpoch(time).toString("yyyy"); + break; + } + default: + break; + } + return ret; +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CTableModel.h b/product/src/gui/plugin/AlarmStatisWidget/CTableModel.h index 05ab46fb..fb7510c9 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CTableModel.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CTableModel.h @@ -1,41 +1,41 @@ -#ifndef CTABLEMODEL_H -#define CTABLEMODEL_H - -#include -#include "CStatisCommon.h" - -enum EN_COLUMN -{ - COLUMN_DATE, - COLUMN_LOCATION, - COLUMN_DEVTYPE -}; - -class CTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CTableModel(QObject *parent = nullptr, const QStringList &alarmLevel = QStringList()); - - void update(const QList& dataList); - - void clear(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - -private: - QString getDispDateTime(qint64 time, EN_STATIS_MODE mode) const; - -private: - QStringList m_header; - QList m_dataList; -}; - -#endif // CTABLEMODEL_H +#ifndef CTABLEMODEL_H +#define CTABLEMODEL_H + +#include +#include "CStatisCommon.h" + +enum EN_COLUMN +{ + COLUMN_DATE, + COLUMN_LOCATION, + COLUMN_DEVTYPE +}; + +class CTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CTableModel(QObject *parent = nullptr, const QStringList &alarmLevel = QStringList()); + + void update(const QList& dataList); + + void clear(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + +private: + QString getDispDateTime(qint64 time, EN_STATIS_MODE mode) const; + +private: + QStringList m_header; + QList m_dataList; +}; + +#endif // CTABLEMODEL_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CTableViewExport.cpp b/product/src/gui/plugin/AlarmStatisWidget/CTableViewExport.cpp index e24efbea..8598241a 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CTableViewExport.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CTableViewExport.cpp @@ -1,93 +1,93 @@ -#include "CTableViewExport.h" -#include "model_excel/xlsx/xlsxdocument.h" -#include "CTableViewPrinter.h" -#include -#include -#include -#include - -CTableViewExport::CTableViewExport(QObject *parent) - : QObject(parent) -{ - -} - -void CTableViewExport::paintExcel(QTableView *view) -{ - QString filePath = QFileDialog::getSaveFileName(view, tr("保存"), QString("/default.xlsx"), "*.xlsx"); - if(filePath.isEmpty()) - return; - - QXlsx::Document xlsx; - - for(int col = 0; col < view->model()->columnCount(); col++) - { - xlsx.write(hexTo26(col)+"1", view->model()->headerData(col, Qt::Horizontal, Qt::DisplayRole)); - xlsx.setColumnWidth(col+1, (view->columnWidth(col))/7); - } - - for(int row = 0; row < view->model()->rowCount(); row++) - { - for(int col = 0; col < view->model()->columnCount(); col++) - { - QModelIndex index = view->model()->index(row, col); - xlsx.write(hexTo26(col)+QString::number(row+2), view->model()->data(index)); - } - } - - if(xlsx.saveAs(filePath)) - { - QMessageBox::information(view,tr("提示"),tr("导出成功!\n导出路径:")+filePath); - } - else - { - QMessageBox::information(view,tr("提示"),tr("保存失败")); - } -} - -void CTableViewExport::paintPdf(QTableView *view) -{ - QString filePath = QFileDialog::getSaveFileName(view, tr("保存"), QString("/default.pdf"), "*.pdf"); - if(filePath.isEmpty()) - return; - - QPrinter printer; - printer.setPageSize(QPagedPaintDevice::A4); - printer.setPageOrientation(QPageLayout::Landscape); - printer.setOutputFileName(filePath); - printer.setOutputFormat(QPrinter::PdfFormat); - - CTableViewPrinter viewPrinter(view); - if(viewPrinter.print(&printer)) - { - QMessageBox::information(view,tr("提示"),tr("导出成功!\n导出路径:")+filePath); - } - else - { - QMessageBox::information(view,tr("提示"),tr("保存失败")); - } -} - -QString CTableViewExport::hexTo26(int number) -{ - int p = 26; //进制 - int c = 0; //取余后的数字 - QString temp; - - while (true) { - c = number % p; - number = number / p; - if(number != 0) - { - temp.prepend(QString(QChar(0x41 + c))); - } - else - { - temp.prepend(QString(QChar(0x41 + c))); - break; - } - number--; - } - - return temp; -} +#include "CTableViewExport.h" +#include "model_excel/xlsx/xlsxdocument.h" +#include "CTableViewPrinter.h" +#include +#include +#include +#include + +CTableViewExport::CTableViewExport(QObject *parent) + : QObject(parent) +{ + +} + +void CTableViewExport::paintExcel(QTableView *view) +{ + QString filePath = QFileDialog::getSaveFileName(view, tr("保存"), QString("/default.xlsx"), "*.xlsx"); + if(filePath.isEmpty()) + return; + + QXlsx::Document xlsx; + + for(int col = 0; col < view->model()->columnCount(); col++) + { + xlsx.write(hexTo26(col)+"1", view->model()->headerData(col, Qt::Horizontal, Qt::DisplayRole)); + xlsx.setColumnWidth(col+1, (view->columnWidth(col))/7); + } + + for(int row = 0; row < view->model()->rowCount(); row++) + { + for(int col = 0; col < view->model()->columnCount(); col++) + { + QModelIndex index = view->model()->index(row, col); + xlsx.write(hexTo26(col)+QString::number(row+2), view->model()->data(index)); + } + } + + if(xlsx.saveAs(filePath)) + { + QMessageBox::information(view,tr("提示"),tr("导出成功!\n导出路径:")+filePath); + } + else + { + QMessageBox::information(view,tr("提示"),tr("保存失败")); + } +} + +void CTableViewExport::paintPdf(QTableView *view) +{ + QString filePath = QFileDialog::getSaveFileName(view, tr("保存"), QString("/default.pdf"), "*.pdf"); + if(filePath.isEmpty()) + return; + + QPrinter printer; + printer.setPageSize(QPagedPaintDevice::A4); + printer.setPageOrientation(QPageLayout::Landscape); + printer.setOutputFileName(filePath); + printer.setOutputFormat(QPrinter::PdfFormat); + + CTableViewPrinter viewPrinter(view); + if(viewPrinter.print(&printer)) + { + QMessageBox::information(view,tr("提示"),tr("导出成功!\n导出路径:")+filePath); + } + else + { + QMessageBox::information(view,tr("提示"),tr("保存失败")); + } +} + +QString CTableViewExport::hexTo26(int number) +{ + int p = 26; //进制 + int c = 0; //取余后的数字 + QString temp; + + while (true) { + c = number % p; + number = number / p; + if(number != 0) + { + temp.prepend(QString(QChar(0x41 + c))); + } + else + { + temp.prepend(QString(QChar(0x41 + c))); + break; + } + number--; + } + + return temp; +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CTableViewExport.h b/product/src/gui/plugin/AlarmStatisWidget/CTableViewExport.h index d32c6ce9..2284c1ec 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CTableViewExport.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CTableViewExport.h @@ -1,22 +1,22 @@ -#ifndef CTABLEVIEWEXPORT_H -#define CTABLEVIEWEXPORT_H - -#include - -class QTableView; -class CTableViewExport : public QObject -{ - Q_OBJECT -public: - explicit CTableViewExport(QObject *parent=Q_NULLPTR); - - void paintExcel(QTableView *view); - - void paintPdf(QTableView *view); - -private: - QString hexTo26(int number); - -}; - -#endif // CTABLEVIEWEXPORT_H +#ifndef CTABLEVIEWEXPORT_H +#define CTABLEVIEWEXPORT_H + +#include + +class QTableView; +class CTableViewExport : public QObject +{ + Q_OBJECT +public: + explicit CTableViewExport(QObject *parent=Q_NULLPTR); + + void paintExcel(QTableView *view); + + void paintPdf(QTableView *view); + +private: + QString hexTo26(int number); + +}; + +#endif // CTABLEVIEWEXPORT_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/AlarmStatisWidget/CTableViewPrinter.cpp index bedfa772..6da493f1 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CTableViewPrinter.cpp @@ -1,128 +1,128 @@ -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include - -CTableViewPrinter::CTableViewPrinter(QTableView *view) - : m_pView(view) -{ - m_pModel = view->model(); -} - -bool CTableViewPrinter::print(QPrinter * printer) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - - qreal marginHorizontal = 20; - qreal marginVertical = 20; - - QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); - printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); - - int length = 0; - horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); - for(int nSection(3); nSection < horizontalHeader->count(); nSection++) - { - length += horizontalHeader->sectionSize(nSection); - } - horizontalHeader->resizeSection(0, (horizontalHeader->width() - length)/3); - horizontalHeader->resizeSection(1, (horizontalHeader->width() - length)/3); - horizontalHeader->resizeSection(2, (horizontalHeader->width() - length)/3); - - QPainter painter(printer); - if(!painter.isActive()) - { - return false; - } - - renderHeader(painter); - - int offset = 0; - int currentPage = 0; - int horizontalHeaderHeight = horizontalHeader->height(); - for(int row(0); row < m_pModel->rowCount(); row++) - { - if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) - { - horizontalHeaderHeight = 0; - } - - if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) - { - printer->newPage(); - currentPage++; - offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - } - - for(int column(0); column < m_pModel->columnCount(); column++) - { - int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - int rowHeight = m_pView->rowHeight(row); - int columnWidth = m_pView->columnWidth(column); - - //< draw item - QStyleOptionViewItem opt; - opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); - painter.save(); - painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); - painter.restore(); - - //< Vertical Line - if(column == 0) - { - QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - //< Horizontal Line - int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; - QPoint left(verticalHeader->width(), rowPosition); - QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); - drawGridLine(&painter, left, right); - - } - return true; -} - -void CTableViewPrinter::renderHeader(QPainter &painter) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - for(int column(0); column < horizontalHeader->count(); column++) - { - painter.save(); - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); - painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); - painter.restore(); - } - int columnPosition = horizontalHeader->width() + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); -} - -void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) -{ - painter->save(); - QStyleOptionViewItem opt; - const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); - const QColor gridColor = static_cast(gridHint); - painter->setPen(gridColor); - painter->drawLine(p1, p2); - painter->restore(); -} +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include + +CTableViewPrinter::CTableViewPrinter(QTableView *view) + : m_pView(view) +{ + m_pModel = view->model(); +} + +bool CTableViewPrinter::print(QPrinter * printer) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); + printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + + int length = 0; + horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); + for(int nSection(3); nSection < horizontalHeader->count(); nSection++) + { + length += horizontalHeader->sectionSize(nSection); + } + horizontalHeader->resizeSection(0, (horizontalHeader->width() - length)/3); + horizontalHeader->resizeSection(1, (horizontalHeader->width() - length)/3); + horizontalHeader->resizeSection(2, (horizontalHeader->width() - length)/3); + + QPainter painter(printer); + if(!painter.isActive()) + { + return false; + } + + renderHeader(painter); + + int offset = 0; + int currentPage = 0; + int horizontalHeaderHeight = horizontalHeader->height(); + for(int row(0); row < m_pModel->rowCount(); row++) + { + if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) + { + horizontalHeaderHeight = 0; + } + + if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) + { + printer->newPage(); + currentPage++; + offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + } + + for(int column(0); column < m_pModel->columnCount(); column++) + { + int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + int rowHeight = m_pView->rowHeight(row); + int columnWidth = m_pView->columnWidth(column); + + //< draw item + QStyleOptionViewItem opt; + opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); + painter.save(); + painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); + painter.restore(); + + //< Vertical Line + if(column == 0) + { + QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + //< Horizontal Line + int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; + QPoint left(verticalHeader->width(), rowPosition); + QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); + drawGridLine(&painter, left, right); + + } + return true; +} + +void CTableViewPrinter::renderHeader(QPainter &painter) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + for(int column(0); column < horizontalHeader->count(); column++) + { + painter.save(); + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); + painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); + painter.restore(); + } + int columnPosition = horizontalHeader->width() + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); +} + +void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + QStyleOptionViewItem opt; + const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); + const QColor gridColor = static_cast(gridHint); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CTableViewPrinter.h b/product/src/gui/plugin/AlarmStatisWidget/CTableViewPrinter.h index 66c17c5a..0a80e9fb 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CTableViewPrinter.h @@ -1,24 +1,24 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H - -class QPointF; -class QPainter; -class QPrinter; -class QTableView; -class QAbstractItemModel; - -class CTableViewPrinter -{ -public: - explicit CTableViewPrinter(QTableView * view); - - bool print(QPrinter *printer); - void renderHeader(QPainter &painter); - void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); - -private: - QTableView * m_pView; - QAbstractItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H + +class QPointF; +class QPainter; +class QPrinter; +class QTableView; +class QAbstractItemModel; + +class CTableViewPrinter +{ +public: + explicit CTableViewPrinter(QTableView * view); + + bool print(QPrinter *printer); + void renderHeader(QPainter &painter); + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + +private: + QTableView * m_pView; + QAbstractItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/CTsdbQuery.cpp b/product/src/gui/plugin/AlarmStatisWidget/CTsdbQuery.cpp index 34fb69ed..06ff62ec 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CTsdbQuery.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/CTsdbQuery.cpp @@ -1,255 +1,255 @@ -#include "CTsdbQuery.h" -#include "db_his_query_api/DbHisQueryApi.h" -#include "public/pub_logger_api/logger.h" -#include "CDataInfoManage.h" -#include - -CTsdbQuery::CTsdbQuery(const QString &device, CTsdbConnPtr &tsdbConnPtr) -{ - m_strDevice = device; - m_tsdbConnPtr = tsdbConnPtr; - m_pVecMpKey = new std::vector(); - m_pVecResult = new std::vector *>(); - LOGINFO("device: %s", m_strDevice.toStdString().c_str()); - QMap PointMap = CDataInfoManage::instance()->getPoint(m_strDevice); - QMap::const_iterator iter = PointMap.constBegin(); - for(; iter != PointMap.constEnd(); iter++) - { - foreach (QString tagName, iter.value()) { - SMeasPointKey key; - std::string tmp = tagName.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(iter.key()); - m_pVecMpKey->push_back(key); - } - } -} - -CTsdbQuery::~CTsdbQuery() -{ - int64 resultSize = 0; - //< 释放结果集 - std::vector *>::iterator res = m_pVecResult->begin(); - while(res != m_pVecResult->end()) - { - resultSize += (*res)->size(); - delete (*res); - ++res; - } - delete m_pVecResult; - LOGINFO("CTsdbQuery resultSize:%d", resultSize); - - //< 释放测点信息 - std::vector::iterator key = m_pVecMpKey->begin(); - while(m_pVecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - } - m_pVecMpKey->clear(); - delete m_pVecMpKey; -} - -bool CTsdbQuery::queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, QMap > &record) -{ - QTime time; - time.start(); - - for(size_t nIndex(0); nIndex < m_pVecMpKey->size(); nIndex++) - { - m_pVecResult->push_back(new std::vector()); - } - int msec1 = time.elapsed(); - if(!getHisEventPoint(*m_tsdbConnPtr, 10000, *m_pVecMpKey, startTime, endTime, *m_pVecResult)) - { - LOGERROR("CTsdbQuery::queryEventByPeriod: 查询超时!Lower: %I64u, Upper: %I64u", startTime, endTime); - return false; - } - int msec2 = time.elapsed(); - LOGINFO("CTsdbQuery::queryEventByPeriod() Lower: %I64u, Upper: %I64u size: %d influx begin: %d end: %d", - startTime, endTime, m_pVecMpKey->size(), msec1, msec2); - - parseResult(startTime, endTime, mode, record); - - return true; -} - -bool CTsdbQuery::queryEventByUnit(qint64 startTime, qint64 endTime, QMap > &record) -{ - QTime time; - time.start(); - - for(size_t nIndex(0); nIndex < m_pVecMpKey->size(); nIndex++) - { - m_pVecResult->push_back(new std::vector()); - } - int msec1 = time.elapsed(); - if(!getHisEventPoint(*m_tsdbConnPtr, 10000, *m_pVecMpKey, startTime, endTime, *m_pVecResult)) - { - LOGERROR("CTsdbQuery::queryEventByUnit: 查询超时!Lower: %I64u, Upper: %I64u", startTime, endTime); - return false; - } - int msec2 = time.elapsed(); - LOGINFO("CTsdbQuery::queryEventByUnit() Lower: %I64u, Upper: %I64u size: %d influx begin: %d end: %d", - startTime, endTime, m_pVecMpKey->size(), msec1, msec2); - - for(size_t nIndex(0); nIndex < m_pVecResult->size(); nIndex++) - { - std::vector *evetVector = m_pVecResult->at(nIndex); - std::vector::iterator iter = evetVector->begin(); - for(; iter != evetVector->end(); iter++) - { - int priority = getAlarmLevel(m_pVecMpKey->at(nIndex).m_pszTagName, - iter->m_nAlmType, - iter->m_nAlmStatus); - - record[m_strDevice][priority] += 1; - } - } - return true; -} - -EnMeasPiontType CTsdbQuery::getMeasType(const QString &type) -{ - if ("analog" == type) - { - return MPT_AI; //< 模拟量 - } - else if ("digital" == type) - { - return MPT_DI; //< 数字量 - } - else if ("mix" == type) - { - return MPT_MIX; //< 混合量 - } - else if ("accuml" == type) - { - return MPT_ACC; //< 累计(电度)量 - } - return MPT_AI; //< INVALID -} - -qint64 CTsdbQuery::getAddMsecByMode(qint64 time, EN_STATIS_MODE mode) -{ - qint64 ret = time; - switch (mode) { - case MODE_DAY: - { - ret = QDateTime::fromMSecsSinceEpoch(time).addDays(1).toMSecsSinceEpoch(); - break; - } - case MODE_MONTH: - { - ret = QDateTime::fromMSecsSinceEpoch(time).addMonths(1).toMSecsSinceEpoch(); - break; - } - case MODE_YEAR: - { - ret = QDateTime::fromMSecsSinceEpoch(time).addYears(1).toMSecsSinceEpoch(); - break; - } - default: - break; - } - return ret; -} - -qint64 CTsdbQuery::getStartMsecByMode(qint64 time, EN_STATIS_MODE mode) -{ - qint64 ret = time; - QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(time); - dateTime.setTime(QTime(0,0)); - switch (mode) { - case MODE_DAY: - { - break; - } - case MODE_MONTH: - { - dateTime.setDate(QDate(dateTime.date().year(), dateTime.date().month(), 1)); - break; - } - case MODE_YEAR: - { - dateTime.setDate(QDate(dateTime.date().year(), 1, 1)); - break; - } - default: - break; - } - ret = dateTime.toMSecsSinceEpoch(); - return ret; -} - -void CTsdbQuery::parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, QMap > &record) -{ - for(size_t nIndex(0); nIndex < m_pVecResult->size(); nIndex++) - { - std::vector *evetVector = m_pVecResult->at(nIndex); - std::vector::iterator iter = evetVector->begin(); - qint64 time = startTime; - qint64 addTime = getAddMsecByMode(time, mode); - for(; iter != evetVector->end(); iter++) - { - int priority = getAlarmLevel(m_pVecMpKey->at(nIndex).m_pszTagName, - iter->m_nAlmType, - iter->m_nAlmStatus); - if(iter->m_nTime < addTime) - { - record[time][priority] += 1; - } - else - { - time = getStartMsecByMode(iter->m_nTime, mode); - addTime = getAddMsecByMode(time, mode); - record[time][priority] += 1; - } - } - } - if(record.isEmpty()) - { - return; - } - qint64 time = startTime; - QMap >::iterator iter = record.begin(); - for(; iter != record.end(); iter++) - { - if(iter.key() != time) - { - record[time][-1] = 0; - } - time = getAddMsecByMode(time, mode); - } - while(time <= endTime) - { - record[time][-1] = 0; - time = getAddMsecByMode(time, mode); - } -} - -int CTsdbQuery::getAlarmLevel(const QString &tag, int almType, int almStatus) -{ - QPair custom; - bool isCustom = CDataInfoManage::instance()->getCustomAlmLevel(tag, custom); - if(isCustom) - { - int chgType = CDataInfoManage::instance()->getChgType(); - if(almType == chgType) - { - return custom.first; - } - int soeType = CDataInfoManage::instance()->getSoeType(); - if(almType == soeType) - { - return custom.second; - } - } - - QPair pair(almType, almStatus); - int alarmManner = CDataInfoManage::instance()->getAlarmManner(pair); - return CDataInfoManage::instance()->getAlarmPriority(alarmManner); -} +#include "CTsdbQuery.h" +#include "db_his_query_api/DbHisQueryApi.h" +#include "public/pub_logger_api/logger.h" +#include "CDataInfoManage.h" +#include + +CTsdbQuery::CTsdbQuery(const QString &device, CTsdbConnPtr &tsdbConnPtr) +{ + m_strDevice = device; + m_tsdbConnPtr = tsdbConnPtr; + m_pVecMpKey = new std::vector(); + m_pVecResult = new std::vector *>(); + LOGINFO("device: %s", m_strDevice.toStdString().c_str()); + QMap PointMap = CDataInfoManage::instance()->getPoint(m_strDevice); + QMap::const_iterator iter = PointMap.constBegin(); + for(; iter != PointMap.constEnd(); iter++) + { + foreach (QString tagName, iter.value()) { + SMeasPointKey key; + std::string tmp = tagName.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(iter.key()); + m_pVecMpKey->push_back(key); + } + } +} + +CTsdbQuery::~CTsdbQuery() +{ + int64 resultSize = 0; + //< 释放结果集 + std::vector *>::iterator res = m_pVecResult->begin(); + while(res != m_pVecResult->end()) + { + resultSize += (*res)->size(); + delete (*res); + ++res; + } + delete m_pVecResult; + LOGINFO("CTsdbQuery resultSize:%d", resultSize); + + //< 释放测点信息 + std::vector::iterator key = m_pVecMpKey->begin(); + while(m_pVecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + m_pVecMpKey->clear(); + delete m_pVecMpKey; +} + +bool CTsdbQuery::queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, QMap > &record) +{ + QTime time; + time.start(); + + for(size_t nIndex(0); nIndex < m_pVecMpKey->size(); nIndex++) + { + m_pVecResult->push_back(new std::vector()); + } + int msec1 = time.elapsed(); + if(!getHisEventPoint(*m_tsdbConnPtr, 10000, *m_pVecMpKey, startTime, endTime, *m_pVecResult)) + { + LOGERROR("CTsdbQuery::queryEventByPeriod: 查询超时!Lower: %I64u, Upper: %I64u", startTime, endTime); + return false; + } + int msec2 = time.elapsed(); + LOGINFO("CTsdbQuery::queryEventByPeriod() Lower: %I64u, Upper: %I64u size: %d influx begin: %d end: %d", + startTime, endTime, m_pVecMpKey->size(), msec1, msec2); + + parseResult(startTime, endTime, mode, record); + + return true; +} + +bool CTsdbQuery::queryEventByUnit(qint64 startTime, qint64 endTime, QMap > &record) +{ + QTime time; + time.start(); + + for(size_t nIndex(0); nIndex < m_pVecMpKey->size(); nIndex++) + { + m_pVecResult->push_back(new std::vector()); + } + int msec1 = time.elapsed(); + if(!getHisEventPoint(*m_tsdbConnPtr, 10000, *m_pVecMpKey, startTime, endTime, *m_pVecResult)) + { + LOGERROR("CTsdbQuery::queryEventByUnit: 查询超时!Lower: %I64u, Upper: %I64u", startTime, endTime); + return false; + } + int msec2 = time.elapsed(); + LOGINFO("CTsdbQuery::queryEventByUnit() Lower: %I64u, Upper: %I64u size: %d influx begin: %d end: %d", + startTime, endTime, m_pVecMpKey->size(), msec1, msec2); + + for(size_t nIndex(0); nIndex < m_pVecResult->size(); nIndex++) + { + std::vector *evetVector = m_pVecResult->at(nIndex); + std::vector::iterator iter = evetVector->begin(); + for(; iter != evetVector->end(); iter++) + { + int priority = getAlarmLevel(m_pVecMpKey->at(nIndex).m_pszTagName, + iter->m_nAlmType, + iter->m_nAlmStatus); + + record[m_strDevice][priority] += 1; + } + } + return true; +} + +EnMeasPiontType CTsdbQuery::getMeasType(const QString &type) +{ + if ("analog" == type) + { + return MPT_AI; //< 模拟量 + } + else if ("digital" == type) + { + return MPT_DI; //< 数字量 + } + else if ("mix" == type) + { + return MPT_MIX; //< 混合量 + } + else if ("accuml" == type) + { + return MPT_ACC; //< 累计(电度)量 + } + return MPT_AI; //< INVALID +} + +qint64 CTsdbQuery::getAddMsecByMode(qint64 time, EN_STATIS_MODE mode) +{ + qint64 ret = time; + switch (mode) { + case MODE_DAY: + { + ret = QDateTime::fromMSecsSinceEpoch(time).addDays(1).toMSecsSinceEpoch(); + break; + } + case MODE_MONTH: + { + ret = QDateTime::fromMSecsSinceEpoch(time).addMonths(1).toMSecsSinceEpoch(); + break; + } + case MODE_YEAR: + { + ret = QDateTime::fromMSecsSinceEpoch(time).addYears(1).toMSecsSinceEpoch(); + break; + } + default: + break; + } + return ret; +} + +qint64 CTsdbQuery::getStartMsecByMode(qint64 time, EN_STATIS_MODE mode) +{ + qint64 ret = time; + QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(time); + dateTime.setTime(QTime(0,0)); + switch (mode) { + case MODE_DAY: + { + break; + } + case MODE_MONTH: + { + dateTime.setDate(QDate(dateTime.date().year(), dateTime.date().month(), 1)); + break; + } + case MODE_YEAR: + { + dateTime.setDate(QDate(dateTime.date().year(), 1, 1)); + break; + } + default: + break; + } + ret = dateTime.toMSecsSinceEpoch(); + return ret; +} + +void CTsdbQuery::parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, QMap > &record) +{ + for(size_t nIndex(0); nIndex < m_pVecResult->size(); nIndex++) + { + std::vector *evetVector = m_pVecResult->at(nIndex); + std::vector::iterator iter = evetVector->begin(); + qint64 time = startTime; + qint64 addTime = getAddMsecByMode(time, mode); + for(; iter != evetVector->end(); iter++) + { + int priority = getAlarmLevel(m_pVecMpKey->at(nIndex).m_pszTagName, + iter->m_nAlmType, + iter->m_nAlmStatus); + if(iter->m_nTime < addTime) + { + record[time][priority] += 1; + } + else + { + time = getStartMsecByMode(iter->m_nTime, mode); + addTime = getAddMsecByMode(time, mode); + record[time][priority] += 1; + } + } + } + if(record.isEmpty()) + { + return; + } + qint64 time = startTime; + QMap >::iterator iter = record.begin(); + for(; iter != record.end(); iter++) + { + if(iter.key() != time) + { + record[time][-1] = 0; + } + time = getAddMsecByMode(time, mode); + } + while(time <= endTime) + { + record[time][-1] = 0; + time = getAddMsecByMode(time, mode); + } +} + +int CTsdbQuery::getAlarmLevel(const QString &tag, int almType, int almStatus) +{ + QPair custom; + bool isCustom = CDataInfoManage::instance()->getCustomAlmLevel(tag, custom); + if(isCustom) + { + int chgType = CDataInfoManage::instance()->getChgType(); + if(almType == chgType) + { + return custom.first; + } + int soeType = CDataInfoManage::instance()->getSoeType(); + if(almType == soeType) + { + return custom.second; + } + } + + QPair pair(almType, almStatus); + int alarmManner = CDataInfoManage::instance()->getAlarmManner(pair); + return CDataInfoManage::instance()->getAlarmPriority(alarmManner); +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/CTsdbQuery.h b/product/src/gui/plugin/AlarmStatisWidget/CTsdbQuery.h index 5e74fa8b..5a821502 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CTsdbQuery.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CTsdbQuery.h @@ -1,35 +1,35 @@ -#ifndef CTSDBQUERY_H -#define CTSDBQUERY_H - -#include "CStatisCommon.h" -#include "tsdb_api/TsdbApi.h" -#include "db_his_query_api/DbHisQueryBase.h" - -using namespace kbd_dbms; -class CTsdbQuery -{ -public: - CTsdbQuery(const QString& device, CTsdbConnPtr &tsdbConnPtr); - ~CTsdbQuery(); - - bool queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, QMap >& record); - - bool queryEventByUnit(qint64 startTime, qint64 endTime, QMap> &record); - -private: - EnMeasPiontType getMeasType(const QString &type); - qint64 getAddMsecByMode(qint64 time, EN_STATIS_MODE mode); - qint64 getStartMsecByMode(qint64 time, EN_STATIS_MODE mode); - void parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, QMap > &record); - int getAlarmLevel(const QString &tag, int almType, int almStatus); - -private: - std::vector * m_pVecMpKey; - std::vector *> *m_pVecResult; - -private: - kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; - QString m_strDevice; -}; - -#endif // CTSDBQUERY_H +#ifndef CTSDBQUERY_H +#define CTSDBQUERY_H + +#include "CStatisCommon.h" +#include "tsdb_api/TsdbApi.h" +#include "db_his_query_api/DbHisQueryBase.h" + +using namespace kbd_dbms; +class CTsdbQuery +{ +public: + CTsdbQuery(const QString& device, CTsdbConnPtr &tsdbConnPtr); + ~CTsdbQuery(); + + bool queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, QMap >& record); + + bool queryEventByUnit(qint64 startTime, qint64 endTime, QMap> &record); + +private: + EnMeasPiontType getMeasType(const QString &type); + qint64 getAddMsecByMode(qint64 time, EN_STATIS_MODE mode); + qint64 getStartMsecByMode(qint64 time, EN_STATIS_MODE mode); + void parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, QMap > &record); + int getAlarmLevel(const QString &tag, int almType, int almStatus); + +private: + std::vector * m_pVecMpKey; + std::vector *> *m_pVecResult; + +private: + kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; + QString m_strDevice; +}; + +#endif // CTSDBQUERY_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.cpp b/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.cpp index 372c1e03..72fe9c8d 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.cpp @@ -1,804 +1,804 @@ -#include "ContrastWidget.h" -#include "ui_ContrastWidget.h" -#include "widget/CToolTip.h" -#include "CDataInfoManage.h" -#include "CTableModel.h" -#include "CDrillDownChart.h" -#include "CTableViewExport.h" -#include -#include -#include -#include - -QT_CHARTS_USE_NAMESPACE - -ContrastWidget::ContrastWidget(bool editMode, QWidget *parent) : - QWidget(parent), - ui(new Ui::ContrastWidget), - m_labelColor(Qt::black), - m_gridLineColor("#cccfd9"), - m_labelsColor("#666666"), - m_titleColor(Qt::black), - m_legendColor(Qt::black), - m_backgroundColor(Qt::white), - m_model(Q_NULLPTR), - m_pChart(Q_NULLPTR), - m_pDevChart(Q_NULLPTR) -{ - ui->setupUi(this); - - initView(); - - if(!editMode) - { - qRegisterMetaType< EN_STATIS_STYLE >("EN_STATIS_STYLE"); - qRegisterMetaType< QList >("QList"); - initData(); - } -} - -ContrastWidget::~ContrastWidget() -{ - if(m_model) - { - delete m_model; - } - m_model = Q_NULLPTR; - - if(m_pChart) - { - delete m_pChart; - } - m_pChart = Q_NULLPTR; - - if(m_pDevChart) - { - delete m_pDevChart; - } - m_pDevChart = Q_NULLPTR; - - delete ui; -} - -QList ContrastWidget::currentSelected() -{ - QList list; - QList selected = ui->m_treeWidget->selectedItems(); - foreach (QTreeWidgetItem* item, selected) { - int id = item->data(0, Qt::UserRole).toInt(); - if(list.indexOf(id) == -1) - { - list.append(id); - } - appendSelectChild(list, item); - } - return list; -} - -void ContrastWidget::appendSelectChild(QList &list, QTreeWidgetItem *parent) -{ - int childCount = parent->childCount(); - if(childCount == 0) - { - return; - } - for(int nIndex=0; nIndexchild(nIndex); - int id = child->data(0, Qt::UserRole).toInt(); - if(list.indexOf(id) == -1) - { - list.append(id); - } - appendSelectChild(list, child); - } -} - -EN_STATIS_MODE ContrastWidget::currentStatisMode() -{ - return EN_STATIS_MODE(ui->m_contrasComb->currentData(Qt::UserRole).toInt()); -} - -EN_STATIS_STYLE ContrastWidget::currentStatisStyle() -{ - return EN_STATIS_STYLE(ui->m_statisticComb->currentData(Qt::UserRole).toInt()); -} - -QPair ContrastWidget::currentDateTime() -{ - QPair pair; - QDate date = ui->m_contrastTime->date(); - QDateTime dateTime; - switch (currentStatisMode()) { - case MODE_DAY: - { - dateTime.setDate(date); - dateTime.setTime(QTime(0,0,0,0)); - pair.first = dateTime.toMSecsSinceEpoch(); - dateTime.setTime(QTime(23,59,59,999)); - pair.second = dateTime.toMSecsSinceEpoch(); - break; - } - case MODE_MONTH: - { - dateTime.setDate(QDate(date.year(), date.month(), 1)); - dateTime.setTime(QTime(0,0,0,0)); - pair.first = dateTime.toMSecsSinceEpoch(); - dateTime.setDate(QDate(date.year(), date.month(), date.daysInMonth())); - dateTime.setTime(QTime(23,59,59,999)); - pair.second = dateTime.toMSecsSinceEpoch(); - break; - } - case MODE_YEAR: - { - dateTime.setDate(QDate(date.year(), 1, 1)); - dateTime.setTime(QTime(0,0,0,0)); - pair.first = dateTime.toMSecsSinceEpoch(); - dateTime.setDate(QDate(date.year(), 12, date.daysInMonth())); - dateTime.setTime(QTime(23,59,59,999)); - pair.second = dateTime.toMSecsSinceEpoch(); - break; - } - default: - break; - } - return pair; -} - -void ContrastWidget::setCurveColor(const QList &color) -{ - m_listColor = color; - m_pChart->setColorList(color); -} - -QColor ContrastWidget::labelColor() -{ - return m_labelColor; -} - -void ContrastWidget::setLabelColor(const QColor &color) -{ - m_labelColor = color; -} - -QColor ContrastWidget::gridLineColor() -{ - return m_gridLineColor; -} - -void ContrastWidget::setGridLineColor(const QColor &color) -{ - m_gridLineColor = color; - m_pDevChart->axisX()->setGridLineColor(m_gridLineColor); - m_pDevChart->axisY()->setGridLineColor(m_gridLineColor); -} - -QColor ContrastWidget::labelsColor() -{ - return m_labelsColor; -} - -void ContrastWidget::setLabelsColor(const QColor &color) -{ - m_labelsColor = color; - m_pDevChart->axisX()->setLabelsColor(m_labelsColor); - m_pDevChart->axisY()->setLabelsColor(m_labelsColor); -} - -QColor ContrastWidget::titleColor() -{ - return m_titleColor; -} - -void ContrastWidget::setTitleColor(const QColor &color) -{ - m_titleColor = color; - m_pDevChart->setTitleBrush(m_titleColor); -} - -QColor ContrastWidget::legendColor() -{ - return m_legendColor; -} - -void ContrastWidget::setLegendColor(const QColor &color) -{ - m_legendColor = color; - m_pDevChart->legend()->setLabelColor(m_legendColor); -} - -QColor ContrastWidget::backgroundColor() -{ - return m_backgroundColor; -} - -void ContrastWidget::setBackgroundColor(const QColor &color) -{ - m_backgroundColor = color; - m_pDevChart->setBackgroundBrush(color); -} - -void ContrastWidget::updateEventNum(const QMap > &hisEventMap) -{ - if(hisEventMap.isEmpty()) - { - ui->m_searchBtn->setEnabled(true); - return; - } - - m_serAlmMap.clear(); - m_serAlmList.clear(); - QMap> locDevMap; - QMap>> locLevelMap; - parseEvent(hisEventMap, locDevMap, locLevelMap); - updateTable(locDevMap, locLevelMap); - updateSeries(locDevMap, locLevelMap); - updateDevSeries(m_serAlmList); - - ui->m_searchBtn->setEnabled(true); -} - -void ContrastWidget::initView() -{ - ui->m_statisTable->horizontalHeader()->setStretchLastSection(true); - ui->m_statisTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - ui->m_statisTable->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->m_statisTable->verticalHeader()->setVisible(false); - - ui->m_treeWidget->header()->setVisible(false); - ui->m_treeWidget->setColumnCount(1); - ui->m_treeWidget->setSelectionMode(QAbstractItemView::MultiSelection); - - ui->m_switchBtn->setMinimumWidth(60); - ui->m_switchBtn->setText(tr("报表")); - ui->m_switchBtn->setCheckedText(tr("图表")); - - m_pChart = new CDrillDownChart(this); - connect(m_pChart, &CDrillDownChart::sigHandleClicked, this, &ContrastWidget::slotUpdateSerDev); - QGridLayout *layout = new QGridLayout(); - layout->addWidget(m_pChart); - layout->setMargin(0); - layout->setSpacing(0); - ui->m_barChart->setLayout(layout); - - m_pDevChart = new QChart(); - m_pDevChart->setAnimationOptions(QChart::SeriesAnimations); - m_pDevChart->setTitle(tr("最严重告警设备")); - QValueAxis *axisX = new QValueAxis(); - axisX->setGridLineColor(m_gridLineColor); - axisX->setLabelsColor(m_labelsColor); - axisX->setMin(0); - axisX->setMax(1); - QBarCategoryAxis *axisY = new QBarCategoryAxis(); - axisY->setGridLineColor(m_gridLineColor); - axisY->setLabelsColor(m_labelsColor); - axisY->append(tr("设备")); - m_pDevChart->setAxisX(axisX); - m_pDevChart->setAxisY(axisY); - - QChartView *devChartView = new QChartView(m_pDevChart); - devChartView->setStyleSheet("background-color:transparent"); - QGridLayout *devLayout = new QGridLayout(); - devLayout->addWidget(devChartView); - devLayout->setMargin(0); - devLayout->setSpacing(0); - ui->m_devChart->setLayout(devLayout); - - ui->m_printBtn->setVisible(false); -} - -void ContrastWidget::initData() -{ - ui->m_statisticComb->addItem(tr("按位置统计"), 0); - ui->m_statisticComb->addItem(tr("按设备类型统计"), 1); - connect(ui->m_statisticComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateList(int))); - - ui->m_contrasComb->addItem(tr("日"), MODE_DAY); - ui->m_contrasComb->addItem(tr("月"), MODE_MONTH); - ui->m_contrasComb->addItem(tr("年"), MODE_YEAR); - connect(ui->m_contrasComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateDate(int))); - - QMap alarmLevel = CDataInfoManage::instance()->getAlarmLevel(); - m_model = new CTableModel(ui->m_statisTable, alarmLevel.values()); - ui->m_statisTable->setModel(m_model); - - connect(ui->m_switchBtn, SIGNAL(toggled(bool)), this, SLOT(slotModeSwitch(bool))); - connect(ui->m_searchBtn, SIGNAL(clicked(bool)), this, SLOT(slotSearch())); - - connect(ui->m_contrastTime->calendarWidget(), SIGNAL(currentPageChanged(int,int)), this, SLOT(slotCurrentPageChanged(int,int))); - - emit ui->m_statisticComb->currentIndexChanged(0); - emit ui->m_contrasComb->currentIndexChanged(0); -} - -void ContrastWidget::parseEvent(const QMap > &hisEventMap, - QMap > &locDevMap, - QMap > > &locLevelMap) -{ - QList levelList = CDataInfoManage::instance()->getAlarmLevel().keys(); - QMap >::const_iterator eventIter = hisEventMap.constBegin(); - while(eventIter != hisEventMap.constEnd()) - { - QPair pair = CDataInfoManage::instance()->getDeviceBelong(eventIter.key()); - - QList temp; - for(int n=0; n::const_iterator iter = eventIter.value().constBegin(); - int index = -1; - for(; iter != eventIter.value().constEnd(); ++iter) - { - index = levelList.indexOf(iter.key()); - if(index == -1) - { - continue; - } - temp[index] += iter.value(); - } - - QString first = pair.first; - QString second = pair.second; - if(STYLE_DEVTYPE == currentStatisStyle()) - { - first = pair.second; - second = pair.first; - } - - int secIndex = locDevMap.value(first).indexOf(second); - if(secIndex != -1) - { - addList(locLevelMap[first][secIndex], temp); - } - else - { - locDevMap[first].append(second); - locLevelMap[first].append(temp); - } - - //< the most serious device - - addSeriousDev(m_serAlmList, eventIter.key(), temp); - - if(m_serAlmMap.value(first).length() == 0) - { - QPair> device; - device.first = eventIter.key(); - device.second = temp; - m_serAlmMap[first].append(device); - } - else - { - addSeriousDev(m_serAlmMap[first], eventIter.key(), temp); - } - - eventIter++; - } -} - -void ContrastWidget::updateTable(const QMap > &locDevMap, - const QMap > > &locLevelMap) -{ - QList dataList; - QList levelList = CDataInfoManage::instance()->getAlarmLevel().keys(); - QList temp; - for(int n=0; n>::const_iterator locDevIter = locDevMap.constBegin(); - while(locDevIter != locDevMap.constEnd()) - { - SHisData data; - data.mode = currentStatisMode(); - data.location = locDevIter.key(); - data.devType = locDevIter.key(); - data.time = currentDateTime().first; - data.number = temp; - - const QList> &tempList = locLevelMap.value(locDevIter.key()); - foreach (QList number, tempList) { - addList(data.number, number); - } - dataList.append(data); - locDevIter++; - } - m_model->update(dataList); - if(STYLE_LOCATION == currentStatisStyle()) - { - ui->m_statisTable->setColumnHidden(COLUMN_DEVTYPE, true); - } - else if(STYLE_DEVTYPE == currentStatisStyle()) - { - ui->m_statisTable->setColumnHidden(COLUMN_LOCATION, true); - } -} - -void ContrastWidget::updateSeries(const QMap> &locDevMap, - const QMap > > &locLevelMap) -{ - m_pChart->updateSeries(ui->m_statisticComb->currentText(), - CDataInfoManage::instance()->getAlarmLevel().values(), - locDevMap, locLevelMap, - ui->m_contrastTime->text()); -} - -void ContrastWidget::addSeriousDev(QList > > &seriousList, - const QString &device, const QList &alarm) -{ - bool isAdd = false; - for(int nIndex(0); nIndex> pair; - pair.first = device; - pair.second = alarm; - seriousList.insert(nIndex, pair); - isAdd = true; - break; - } - } - if(!isAdd && seriousList.length() < SERIOUS_DEV_NUM) - { - QPair> pair; - pair.first = device; - pair.second = alarm; - seriousList.append(pair); - } - else if(seriousList.length() > SERIOUS_DEV_NUM) - { - seriousList.takeLast(); - } -} - -void ContrastWidget::updateDevSeries(const QList > > &seriousList) -{ - QStringList levelList = CDataInfoManage::instance()->getAlarmLevel().values(); - - QStringList cateList; - for (int nIndex = seriousList.count()-1; nIndex >= 0; nIndex--) { - QString device = seriousList[nIndex].first; - cateList.append(QString("%1.%2-%3") - .arg(nIndex+1) - .arg(CDataInfoManage::instance()->getDeviceBelong(device).first) - .arg(CDataInfoManage::instance()->getDevDesc(device))); - } - - QHorizontalStackedBarSeries *locSeries = new QHorizontalStackedBarSeries(m_pDevChart); - connect(locSeries, &QHorizontalStackedBarSeries::hovered, - this, &ContrastWidget::horizonBarHovered); - - for (int level = 0; level < levelList.count(); level++) { - QBarSet *locCrop = new QBarSet(levelList.at(level)); - locCrop->setLabelColor(m_labelColor); - if(m_listColor.length() > level) - locCrop->setBrush(m_listColor.at(level)); - for(int devIndex = seriousList.count()-1; devIndex >= 0; devIndex--) { - *locCrop << seriousList[devIndex].second.value(level, 0); - } - locSeries->append(locCrop); - } - - QBarCategoryAxis *axisY = new QBarCategoryAxis(); - axisY->append(cateList); - axisY->setGridLineColor(m_gridLineColor); - axisY->setLabelsColor(m_labelsColor); - QValueAxis *axisX = new QValueAxis(); - axisX->setGridLineColor(m_gridLineColor); - axisX->setLabelsColor(m_labelsColor); - - m_pDevChart->addSeries(locSeries); - m_pDevChart->createDefaultAxes(); - m_pDevChart->setAxisX(axisX, locSeries); - m_pDevChart->setAxisY(axisY, locSeries); - m_pDevChart->axisY()->setGridLineVisible(false); - m_pDevChart->legend()->setAlignment(Qt::AlignRight); -} - -void ContrastWidget::addList(QList &first, const QList &add) -{ - if(first.length() != add.length()) - { - return; - } - for(int nIndex(0); nIndex &lhs, const QList &rhs) -{ - if(lhs.length() != rhs.length()) - { - return false; - } - int lNum = 0; - int rNum = 0; - for(int nIndex(0); nIndex= rNum) - { - return true; - } - return false; -} - -void ContrastWidget::setDevSeriesTip(bool visible) -{ - QList seriesList = m_pDevChart->series(); - if(seriesList.length()>0) - { - QHorizontalStackedBarSeries *drSeries = dynamic_cast(seriesList[0]); - drSeries->setLabelsPosition(QAbstractBarSeries::LabelsCenter); - drSeries->setLabelsVisible(visible); - } -} - -void ContrastWidget::makeLocationTree(QMap &map) -{ - QList keyList = map.keys(); - for(int nIndex=0; nIndexsetText(0, temp[1]); - item->setData(0, Qt::UserRole, QString(temp[0]).toInt()); - ui->m_treeWidget->addTopLevelItem(item); - - appendChild(item, map.value(QString(temp[0]).toInt()), map); - } - } -} - -void ContrastWidget::appendChild(QTreeWidgetItem *parent, const QStringList &strList, QMap &map) -{ - if(strList.isEmpty()) - { - return; - } - - foreach (QString str, strList) { - QStringList temp = str.split(","); - if(temp.length() != 3) - { - continue; - } - QTreeWidgetItem *item = new QTreeWidgetItem(); - item->setText(0, temp[1]); - item->setData(0, Qt::UserRole, QString(temp[0]).toInt()); - parent->addChild(item); - - appendChild(item, map.value(QString(temp[0]).toInt()), map); - } -} - -void ContrastWidget::slotUpdateList(int index) -{ - ui->m_treeWidget->clear(); - switch (index) { - case 0: - { - QMap map = CDataInfoManage::instance()->getLocation(); - makeLocationTree(map); - break; - } - case 1: - { - QMap map = CDataInfoManage::instance()->getDevType(); - QMap::const_iterator iter = map.constBegin(); - int rowCount = 0; - for(; iter != map.constEnd(); iter++) - { - QTreeWidgetItem *item = new QTreeWidgetItem(); - item->setText(0, iter.value()); - item->setData(0, Qt::UserRole, iter.key()); - ui->m_treeWidget->insertTopLevelItem(rowCount, item); - } - break; - } - default: - break; - } -} - -void ContrastWidget::slotUpdateDate(int index) -{ - switch (index) { - case MODE_DAY:{ - ui->m_contrastTime->setDisplayFormat("yyyy-MM-dd"); - break; - } - case MODE_MONTH:{ - ui->m_contrastTime->setDisplayFormat("yyyy-MM"); - break; - } - case MODE_YEAR:{ - ui->m_contrastTime->setDisplayFormat("yyyy"); - break; - } - default: - break; - } - QDate date = QDate::currentDate(); - ui->m_contrastTime->setDate(date); -} - -void ContrastWidget::slotModeSwitch(bool checked) -{ - if(checked) - { - ui->stackedWidget->setCurrentIndex(1); - ui->m_excelBtn->setVisible(false); - ui->m_pdfBtn->setVisible(false); - ui->m_printBtn->setVisible(true); - } - else - { - ui->stackedWidget->setCurrentIndex(0); - ui->m_excelBtn->setVisible(true); - ui->m_pdfBtn->setVisible(true); - ui->m_printBtn->setVisible(false); - } -} - -void ContrastWidget::slotSearch() -{ - if(ui->m_treeWidget->selectedItems().length() <= 0) - { - QMessageBox::information(this,tr("提示"),tr("请至少选择一项!")); - return; - } - ui->m_searchBtn->setEnabled(false); - for(int nIndex(0); nIndexcolumnCount(); nIndex++) - { - ui->m_statisTable->setColumnHidden(nIndex, false); - } - m_model->clear(); - m_pChart->clearSeries(); - QList seriesList = m_pDevChart->series(); - foreach (QAbstractSeries *series, seriesList) { - m_pDevChart->removeSeries(series); - } - QValueAxis *axisX = new QValueAxis(); - axisX->setGridLineColor(m_gridLineColor); - axisX->setLabelsColor(m_labelsColor); - axisX->setMin(0); - axisX->setMax(1); - QBarCategoryAxis *axisY = new QBarCategoryAxis(); - axisY->setGridLineColor(m_gridLineColor); - axisY->setLabelsColor(m_labelsColor); - axisY->append(tr("设备")); - m_pDevChart->setAxisX(axisX); - m_pDevChart->setAxisY(axisY); - - QPair datePair = currentDateTime(); - emit sigQueryEvent(currentSelected(), datePair.first, datePair.second, currentStatisStyle()); -} - -void ContrastWidget::slotUpdateSerDev(const QString &name) -{ - QList seriesList = m_pDevChart->series(); - foreach (QAbstractSeries *series, seriesList) { - m_pDevChart->removeSeries(series); - } - - QList>> serList = m_serAlmMap.value(name); - if(!serList.isEmpty()) - { - updateDevSeries(serList); - } - else - { - updateDevSeries(m_serAlmList); - } -} - -void ContrastWidget::horizonBarHovered(bool status, int index, QBarSet *barset) -{ - Q_UNUSED(barset) - if(status) - { - QList seriesList = m_pDevChart->series(); - if(seriesList.length() <= 0) - { - return; - } - QString text; - qreal total = 0; - QHorizontalStackedBarSeries *drSeries = dynamic_cast(seriesList[0]); - QList barList = drSeries->barSets(); - for(int nIndex(0); nIndexat(index); - text += barList[nIndex]->label() + tr(": ") + QString::number(barList[nIndex]->at(index), 'f', 0) + "\n"; - } - text.push_front(tr("总共: ") + QString::number(total, 'f', 0) + "\n"); - text.remove(-1, 2); - - QPoint point = QCursor::pos(); - CToolTip::popup(QPoint(point.x()-70, point.y()-100), text, this); - } -} - -void ContrastWidget::contextMenuEvent(QContextMenuEvent *event) -{ - QRect rect = ui->m_treeWidget->rect(); - rect.setTopLeft(ui->m_treeWidget->pos()); - rect.setHeight(rect.height()+ui->m_treeWidget->pos().y()); - rect.setWidth(rect.width()+ui->m_treeWidget->pos().x()); - if(rect.contains(event->pos())) - { - QMenu menu; - menu.addAction(tr("清空"), [=](){ ui->m_treeWidget->clearSelection();}); - menu.addAction(tr("全选"), [=](){ ui->m_treeWidget->selectAll();}); - menu.exec(event->globalPos()); - } -} - -void ContrastWidget::on_m_excelBtn_clicked() -{ - CTableViewExport paint; - paint.paintExcel(ui->m_statisTable); -} - -void ContrastWidget::on_m_pdfBtn_clicked() -{ - CTableViewExport paint; - paint.paintPdf(ui->m_statisTable); -} - -void ContrastWidget::on_m_printBtn_clicked() -{ - QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/default.jpg"), tr("(*.jpg)")); - if(strFileName.isEmpty()) - { - return; - } - - m_pChart->setTipVisible(true); - setDevSeriesTip(true); - QImage buffer = ui->page_2->grab().toImage(); - setDevSeriesTip(false); - m_pChart->setTipVisible(false); - int dotsPerMeter = 96/0.0254; - buffer.setDotsPerMeterX(dotsPerMeter); - buffer.setDotsPerMeterY(dotsPerMeter); - if (!buffer.isNull()) - { - if(buffer.save(strFileName, "JPG", -1)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+strFileName); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } - } -} - -void ContrastWidget::slotCurrentPageChanged(int year, int month) -{ - EN_STATIS_MODE mode = currentStatisMode(); - if(MODE_MONTH == mode || MODE_YEAR == mode) - { - QDate date = ui->m_contrastTime->date(); - date.setDate(year, month, 1); - ui->m_contrastTime->setDate(date); - } -} +#include "ContrastWidget.h" +#include "ui_ContrastWidget.h" +#include "widget/CToolTip.h" +#include "CDataInfoManage.h" +#include "CTableModel.h" +#include "CDrillDownChart.h" +#include "CTableViewExport.h" +#include +#include +#include +#include + +QT_CHARTS_USE_NAMESPACE + +ContrastWidget::ContrastWidget(bool editMode, QWidget *parent) : + QWidget(parent), + ui(new Ui::ContrastWidget), + m_labelColor(Qt::black), + m_gridLineColor("#cccfd9"), + m_labelsColor("#666666"), + m_titleColor(Qt::black), + m_legendColor(Qt::black), + m_backgroundColor(Qt::white), + m_model(Q_NULLPTR), + m_pChart(Q_NULLPTR), + m_pDevChart(Q_NULLPTR) +{ + ui->setupUi(this); + + initView(); + + if(!editMode) + { + qRegisterMetaType< EN_STATIS_STYLE >("EN_STATIS_STYLE"); + qRegisterMetaType< QList >("QList"); + initData(); + } +} + +ContrastWidget::~ContrastWidget() +{ + if(m_model) + { + delete m_model; + } + m_model = Q_NULLPTR; + + if(m_pChart) + { + delete m_pChart; + } + m_pChart = Q_NULLPTR; + + if(m_pDevChart) + { + delete m_pDevChart; + } + m_pDevChart = Q_NULLPTR; + + delete ui; +} + +QList ContrastWidget::currentSelected() +{ + QList list; + QList selected = ui->m_treeWidget->selectedItems(); + foreach (QTreeWidgetItem* item, selected) { + int id = item->data(0, Qt::UserRole).toInt(); + if(list.indexOf(id) == -1) + { + list.append(id); + } + appendSelectChild(list, item); + } + return list; +} + +void ContrastWidget::appendSelectChild(QList &list, QTreeWidgetItem *parent) +{ + int childCount = parent->childCount(); + if(childCount == 0) + { + return; + } + for(int nIndex=0; nIndexchild(nIndex); + int id = child->data(0, Qt::UserRole).toInt(); + if(list.indexOf(id) == -1) + { + list.append(id); + } + appendSelectChild(list, child); + } +} + +EN_STATIS_MODE ContrastWidget::currentStatisMode() +{ + return EN_STATIS_MODE(ui->m_contrasComb->currentData(Qt::UserRole).toInt()); +} + +EN_STATIS_STYLE ContrastWidget::currentStatisStyle() +{ + return EN_STATIS_STYLE(ui->m_statisticComb->currentData(Qt::UserRole).toInt()); +} + +QPair ContrastWidget::currentDateTime() +{ + QPair pair; + QDate date = ui->m_contrastTime->date(); + QDateTime dateTime; + switch (currentStatisMode()) { + case MODE_DAY: + { + dateTime.setDate(date); + dateTime.setTime(QTime(0,0,0,0)); + pair.first = dateTime.toMSecsSinceEpoch(); + dateTime.setTime(QTime(23,59,59,999)); + pair.second = dateTime.toMSecsSinceEpoch(); + break; + } + case MODE_MONTH: + { + dateTime.setDate(QDate(date.year(), date.month(), 1)); + dateTime.setTime(QTime(0,0,0,0)); + pair.first = dateTime.toMSecsSinceEpoch(); + dateTime.setDate(QDate(date.year(), date.month(), date.daysInMonth())); + dateTime.setTime(QTime(23,59,59,999)); + pair.second = dateTime.toMSecsSinceEpoch(); + break; + } + case MODE_YEAR: + { + dateTime.setDate(QDate(date.year(), 1, 1)); + dateTime.setTime(QTime(0,0,0,0)); + pair.first = dateTime.toMSecsSinceEpoch(); + dateTime.setDate(QDate(date.year(), 12, date.daysInMonth())); + dateTime.setTime(QTime(23,59,59,999)); + pair.second = dateTime.toMSecsSinceEpoch(); + break; + } + default: + break; + } + return pair; +} + +void ContrastWidget::setCurveColor(const QList &color) +{ + m_listColor = color; + m_pChart->setColorList(color); +} + +QColor ContrastWidget::labelColor() +{ + return m_labelColor; +} + +void ContrastWidget::setLabelColor(const QColor &color) +{ + m_labelColor = color; +} + +QColor ContrastWidget::gridLineColor() +{ + return m_gridLineColor; +} + +void ContrastWidget::setGridLineColor(const QColor &color) +{ + m_gridLineColor = color; + m_pDevChart->axisX()->setGridLineColor(m_gridLineColor); + m_pDevChart->axisY()->setGridLineColor(m_gridLineColor); +} + +QColor ContrastWidget::labelsColor() +{ + return m_labelsColor; +} + +void ContrastWidget::setLabelsColor(const QColor &color) +{ + m_labelsColor = color; + m_pDevChart->axisX()->setLabelsColor(m_labelsColor); + m_pDevChart->axisY()->setLabelsColor(m_labelsColor); +} + +QColor ContrastWidget::titleColor() +{ + return m_titleColor; +} + +void ContrastWidget::setTitleColor(const QColor &color) +{ + m_titleColor = color; + m_pDevChart->setTitleBrush(m_titleColor); +} + +QColor ContrastWidget::legendColor() +{ + return m_legendColor; +} + +void ContrastWidget::setLegendColor(const QColor &color) +{ + m_legendColor = color; + m_pDevChart->legend()->setLabelColor(m_legendColor); +} + +QColor ContrastWidget::backgroundColor() +{ + return m_backgroundColor; +} + +void ContrastWidget::setBackgroundColor(const QColor &color) +{ + m_backgroundColor = color; + m_pDevChart->setBackgroundBrush(color); +} + +void ContrastWidget::updateEventNum(const QMap > &hisEventMap) +{ + if(hisEventMap.isEmpty()) + { + ui->m_searchBtn->setEnabled(true); + return; + } + + m_serAlmMap.clear(); + m_serAlmList.clear(); + QMap> locDevMap; + QMap>> locLevelMap; + parseEvent(hisEventMap, locDevMap, locLevelMap); + updateTable(locDevMap, locLevelMap); + updateSeries(locDevMap, locLevelMap); + updateDevSeries(m_serAlmList); + + ui->m_searchBtn->setEnabled(true); +} + +void ContrastWidget::initView() +{ + ui->m_statisTable->horizontalHeader()->setStretchLastSection(true); + ui->m_statisTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + ui->m_statisTable->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->m_statisTable->verticalHeader()->setVisible(false); + + ui->m_treeWidget->header()->setVisible(false); + ui->m_treeWidget->setColumnCount(1); + ui->m_treeWidget->setSelectionMode(QAbstractItemView::MultiSelection); + + ui->m_switchBtn->setMinimumWidth(60); + ui->m_switchBtn->setText(tr("报表")); + ui->m_switchBtn->setCheckedText(tr("图表")); + + m_pChart = new CDrillDownChart(this); + connect(m_pChart, &CDrillDownChart::sigHandleClicked, this, &ContrastWidget::slotUpdateSerDev); + QGridLayout *layout = new QGridLayout(); + layout->addWidget(m_pChart); + layout->setMargin(0); + layout->setSpacing(0); + ui->m_barChart->setLayout(layout); + + m_pDevChart = new QChart(); + m_pDevChart->setAnimationOptions(QChart::SeriesAnimations); + m_pDevChart->setTitle(tr("最严重告警设备")); + QValueAxis *axisX = new QValueAxis(); + axisX->setGridLineColor(m_gridLineColor); + axisX->setLabelsColor(m_labelsColor); + axisX->setMin(0); + axisX->setMax(1); + QBarCategoryAxis *axisY = new QBarCategoryAxis(); + axisY->setGridLineColor(m_gridLineColor); + axisY->setLabelsColor(m_labelsColor); + axisY->append(tr("设备")); + m_pDevChart->setAxisX(axisX); + m_pDevChart->setAxisY(axisY); + + QChartView *devChartView = new QChartView(m_pDevChart); + devChartView->setStyleSheet("background-color:transparent"); + QGridLayout *devLayout = new QGridLayout(); + devLayout->addWidget(devChartView); + devLayout->setMargin(0); + devLayout->setSpacing(0); + ui->m_devChart->setLayout(devLayout); + + ui->m_printBtn->setVisible(false); +} + +void ContrastWidget::initData() +{ + ui->m_statisticComb->addItem(tr("按位置统计"), 0); + ui->m_statisticComb->addItem(tr("按设备类型统计"), 1); + connect(ui->m_statisticComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateList(int))); + + ui->m_contrasComb->addItem(tr("日"), MODE_DAY); + ui->m_contrasComb->addItem(tr("月"), MODE_MONTH); + ui->m_contrasComb->addItem(tr("年"), MODE_YEAR); + connect(ui->m_contrasComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateDate(int))); + + QMap alarmLevel = CDataInfoManage::instance()->getAlarmLevel(); + m_model = new CTableModel(ui->m_statisTable, alarmLevel.values()); + ui->m_statisTable->setModel(m_model); + + connect(ui->m_switchBtn, SIGNAL(toggled(bool)), this, SLOT(slotModeSwitch(bool))); + connect(ui->m_searchBtn, SIGNAL(clicked(bool)), this, SLOT(slotSearch())); + + connect(ui->m_contrastTime->calendarWidget(), SIGNAL(currentPageChanged(int,int)), this, SLOT(slotCurrentPageChanged(int,int))); + + emit ui->m_statisticComb->currentIndexChanged(0); + emit ui->m_contrasComb->currentIndexChanged(0); +} + +void ContrastWidget::parseEvent(const QMap > &hisEventMap, + QMap > &locDevMap, + QMap > > &locLevelMap) +{ + QList levelList = CDataInfoManage::instance()->getAlarmLevel().keys(); + QMap >::const_iterator eventIter = hisEventMap.constBegin(); + while(eventIter != hisEventMap.constEnd()) + { + QPair pair = CDataInfoManage::instance()->getDeviceBelong(eventIter.key()); + + QList temp; + for(int n=0; n::const_iterator iter = eventIter.value().constBegin(); + int index = -1; + for(; iter != eventIter.value().constEnd(); ++iter) + { + index = levelList.indexOf(iter.key()); + if(index == -1) + { + continue; + } + temp[index] += iter.value(); + } + + QString first = pair.first; + QString second = pair.second; + if(STYLE_DEVTYPE == currentStatisStyle()) + { + first = pair.second; + second = pair.first; + } + + int secIndex = locDevMap.value(first).indexOf(second); + if(secIndex != -1) + { + addList(locLevelMap[first][secIndex], temp); + } + else + { + locDevMap[first].append(second); + locLevelMap[first].append(temp); + } + + //< the most serious device + + addSeriousDev(m_serAlmList, eventIter.key(), temp); + + if(m_serAlmMap.value(first).length() == 0) + { + QPair> device; + device.first = eventIter.key(); + device.second = temp; + m_serAlmMap[first].append(device); + } + else + { + addSeriousDev(m_serAlmMap[first], eventIter.key(), temp); + } + + eventIter++; + } +} + +void ContrastWidget::updateTable(const QMap > &locDevMap, + const QMap > > &locLevelMap) +{ + QList dataList; + QList levelList = CDataInfoManage::instance()->getAlarmLevel().keys(); + QList temp; + for(int n=0; n>::const_iterator locDevIter = locDevMap.constBegin(); + while(locDevIter != locDevMap.constEnd()) + { + SHisData data; + data.mode = currentStatisMode(); + data.location = locDevIter.key(); + data.devType = locDevIter.key(); + data.time = currentDateTime().first; + data.number = temp; + + const QList> &tempList = locLevelMap.value(locDevIter.key()); + foreach (QList number, tempList) { + addList(data.number, number); + } + dataList.append(data); + locDevIter++; + } + m_model->update(dataList); + if(STYLE_LOCATION == currentStatisStyle()) + { + ui->m_statisTable->setColumnHidden(COLUMN_DEVTYPE, true); + } + else if(STYLE_DEVTYPE == currentStatisStyle()) + { + ui->m_statisTable->setColumnHidden(COLUMN_LOCATION, true); + } +} + +void ContrastWidget::updateSeries(const QMap> &locDevMap, + const QMap > > &locLevelMap) +{ + m_pChart->updateSeries(ui->m_statisticComb->currentText(), + CDataInfoManage::instance()->getAlarmLevel().values(), + locDevMap, locLevelMap, + ui->m_contrastTime->text()); +} + +void ContrastWidget::addSeriousDev(QList > > &seriousList, + const QString &device, const QList &alarm) +{ + bool isAdd = false; + for(int nIndex(0); nIndex> pair; + pair.first = device; + pair.second = alarm; + seriousList.insert(nIndex, pair); + isAdd = true; + break; + } + } + if(!isAdd && seriousList.length() < SERIOUS_DEV_NUM) + { + QPair> pair; + pair.first = device; + pair.second = alarm; + seriousList.append(pair); + } + else if(seriousList.length() > SERIOUS_DEV_NUM) + { + seriousList.takeLast(); + } +} + +void ContrastWidget::updateDevSeries(const QList > > &seriousList) +{ + QStringList levelList = CDataInfoManage::instance()->getAlarmLevel().values(); + + QStringList cateList; + for (int nIndex = seriousList.count()-1; nIndex >= 0; nIndex--) { + QString device = seriousList[nIndex].first; + cateList.append(QString("%1.%2-%3") + .arg(nIndex+1) + .arg(CDataInfoManage::instance()->getDeviceBelong(device).first) + .arg(CDataInfoManage::instance()->getDevDesc(device))); + } + + QHorizontalStackedBarSeries *locSeries = new QHorizontalStackedBarSeries(m_pDevChart); + connect(locSeries, &QHorizontalStackedBarSeries::hovered, + this, &ContrastWidget::horizonBarHovered); + + for (int level = 0; level < levelList.count(); level++) { + QBarSet *locCrop = new QBarSet(levelList.at(level)); + locCrop->setLabelColor(m_labelColor); + if(m_listColor.length() > level) + locCrop->setBrush(m_listColor.at(level)); + for(int devIndex = seriousList.count()-1; devIndex >= 0; devIndex--) { + *locCrop << seriousList[devIndex].second.value(level, 0); + } + locSeries->append(locCrop); + } + + QBarCategoryAxis *axisY = new QBarCategoryAxis(); + axisY->append(cateList); + axisY->setGridLineColor(m_gridLineColor); + axisY->setLabelsColor(m_labelsColor); + QValueAxis *axisX = new QValueAxis(); + axisX->setGridLineColor(m_gridLineColor); + axisX->setLabelsColor(m_labelsColor); + + m_pDevChart->addSeries(locSeries); + m_pDevChart->createDefaultAxes(); + m_pDevChart->setAxisX(axisX, locSeries); + m_pDevChart->setAxisY(axisY, locSeries); + m_pDevChart->axisY()->setGridLineVisible(false); + m_pDevChart->legend()->setAlignment(Qt::AlignRight); +} + +void ContrastWidget::addList(QList &first, const QList &add) +{ + if(first.length() != add.length()) + { + return; + } + for(int nIndex(0); nIndex &lhs, const QList &rhs) +{ + if(lhs.length() != rhs.length()) + { + return false; + } + int lNum = 0; + int rNum = 0; + for(int nIndex(0); nIndex= rNum) + { + return true; + } + return false; +} + +void ContrastWidget::setDevSeriesTip(bool visible) +{ + QList seriesList = m_pDevChart->series(); + if(seriesList.length()>0) + { + QHorizontalStackedBarSeries *drSeries = dynamic_cast(seriesList[0]); + drSeries->setLabelsPosition(QAbstractBarSeries::LabelsCenter); + drSeries->setLabelsVisible(visible); + } +} + +void ContrastWidget::makeLocationTree(QMap &map) +{ + QList keyList = map.keys(); + for(int nIndex=0; nIndexsetText(0, temp[1]); + item->setData(0, Qt::UserRole, QString(temp[0]).toInt()); + ui->m_treeWidget->addTopLevelItem(item); + + appendChild(item, map.value(QString(temp[0]).toInt()), map); + } + } +} + +void ContrastWidget::appendChild(QTreeWidgetItem *parent, const QStringList &strList, QMap &map) +{ + if(strList.isEmpty()) + { + return; + } + + foreach (QString str, strList) { + QStringList temp = str.split(","); + if(temp.length() != 3) + { + continue; + } + QTreeWidgetItem *item = new QTreeWidgetItem(); + item->setText(0, temp[1]); + item->setData(0, Qt::UserRole, QString(temp[0]).toInt()); + parent->addChild(item); + + appendChild(item, map.value(QString(temp[0]).toInt()), map); + } +} + +void ContrastWidget::slotUpdateList(int index) +{ + ui->m_treeWidget->clear(); + switch (index) { + case 0: + { + QMap map = CDataInfoManage::instance()->getLocation(); + makeLocationTree(map); + break; + } + case 1: + { + QMap map = CDataInfoManage::instance()->getDevType(); + QMap::const_iterator iter = map.constBegin(); + int rowCount = 0; + for(; iter != map.constEnd(); iter++) + { + QTreeWidgetItem *item = new QTreeWidgetItem(); + item->setText(0, iter.value()); + item->setData(0, Qt::UserRole, iter.key()); + ui->m_treeWidget->insertTopLevelItem(rowCount, item); + } + break; + } + default: + break; + } +} + +void ContrastWidget::slotUpdateDate(int index) +{ + switch (index) { + case MODE_DAY:{ + ui->m_contrastTime->setDisplayFormat("yyyy-MM-dd"); + break; + } + case MODE_MONTH:{ + ui->m_contrastTime->setDisplayFormat("yyyy-MM"); + break; + } + case MODE_YEAR:{ + ui->m_contrastTime->setDisplayFormat("yyyy"); + break; + } + default: + break; + } + QDate date = QDate::currentDate(); + ui->m_contrastTime->setDate(date); +} + +void ContrastWidget::slotModeSwitch(bool checked) +{ + if(checked) + { + ui->stackedWidget->setCurrentIndex(1); + ui->m_excelBtn->setVisible(false); + ui->m_pdfBtn->setVisible(false); + ui->m_printBtn->setVisible(true); + } + else + { + ui->stackedWidget->setCurrentIndex(0); + ui->m_excelBtn->setVisible(true); + ui->m_pdfBtn->setVisible(true); + ui->m_printBtn->setVisible(false); + } +} + +void ContrastWidget::slotSearch() +{ + if(ui->m_treeWidget->selectedItems().length() <= 0) + { + QMessageBox::information(this,tr("提示"),tr("请至少选择一项!")); + return; + } + ui->m_searchBtn->setEnabled(false); + for(int nIndex(0); nIndexcolumnCount(); nIndex++) + { + ui->m_statisTable->setColumnHidden(nIndex, false); + } + m_model->clear(); + m_pChart->clearSeries(); + QList seriesList = m_pDevChart->series(); + foreach (QAbstractSeries *series, seriesList) { + m_pDevChart->removeSeries(series); + } + QValueAxis *axisX = new QValueAxis(); + axisX->setGridLineColor(m_gridLineColor); + axisX->setLabelsColor(m_labelsColor); + axisX->setMin(0); + axisX->setMax(1); + QBarCategoryAxis *axisY = new QBarCategoryAxis(); + axisY->setGridLineColor(m_gridLineColor); + axisY->setLabelsColor(m_labelsColor); + axisY->append(tr("设备")); + m_pDevChart->setAxisX(axisX); + m_pDevChart->setAxisY(axisY); + + QPair datePair = currentDateTime(); + emit sigQueryEvent(currentSelected(), datePair.first, datePair.second, currentStatisStyle()); +} + +void ContrastWidget::slotUpdateSerDev(const QString &name) +{ + QList seriesList = m_pDevChart->series(); + foreach (QAbstractSeries *series, seriesList) { + m_pDevChart->removeSeries(series); + } + + QList>> serList = m_serAlmMap.value(name); + if(!serList.isEmpty()) + { + updateDevSeries(serList); + } + else + { + updateDevSeries(m_serAlmList); + } +} + +void ContrastWidget::horizonBarHovered(bool status, int index, QBarSet *barset) +{ + Q_UNUSED(barset) + if(status) + { + QList seriesList = m_pDevChart->series(); + if(seriesList.length() <= 0) + { + return; + } + QString text; + qreal total = 0; + QHorizontalStackedBarSeries *drSeries = dynamic_cast(seriesList[0]); + QList barList = drSeries->barSets(); + for(int nIndex(0); nIndexat(index); + text += barList[nIndex]->label() + tr(": ") + QString::number(barList[nIndex]->at(index), 'f', 0) + "\n"; + } + text.push_front(tr("总共: ") + QString::number(total, 'f', 0) + "\n"); + text.remove(-1, 2); + + QPoint point = QCursor::pos(); + CToolTip::popup(QPoint(point.x()-70, point.y()-100), text, this); + } +} + +void ContrastWidget::contextMenuEvent(QContextMenuEvent *event) +{ + QRect rect = ui->m_treeWidget->rect(); + rect.setTopLeft(ui->m_treeWidget->pos()); + rect.setHeight(rect.height()+ui->m_treeWidget->pos().y()); + rect.setWidth(rect.width()+ui->m_treeWidget->pos().x()); + if(rect.contains(event->pos())) + { + QMenu menu; + menu.addAction(tr("清空"), [=](){ ui->m_treeWidget->clearSelection();}); + menu.addAction(tr("全选"), [=](){ ui->m_treeWidget->selectAll();}); + menu.exec(event->globalPos()); + } +} + +void ContrastWidget::on_m_excelBtn_clicked() +{ + CTableViewExport paint; + paint.paintExcel(ui->m_statisTable); +} + +void ContrastWidget::on_m_pdfBtn_clicked() +{ + CTableViewExport paint; + paint.paintPdf(ui->m_statisTable); +} + +void ContrastWidget::on_m_printBtn_clicked() +{ + QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/default.jpg"), tr("(*.jpg)")); + if(strFileName.isEmpty()) + { + return; + } + + m_pChart->setTipVisible(true); + setDevSeriesTip(true); + QImage buffer = ui->page_2->grab().toImage(); + setDevSeriesTip(false); + m_pChart->setTipVisible(false); + int dotsPerMeter = 96/0.0254; + buffer.setDotsPerMeterX(dotsPerMeter); + buffer.setDotsPerMeterY(dotsPerMeter); + if (!buffer.isNull()) + { + if(buffer.save(strFileName, "JPG", -1)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+strFileName); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } + } +} + +void ContrastWidget::slotCurrentPageChanged(int year, int month) +{ + EN_STATIS_MODE mode = currentStatisMode(); + if(MODE_MONTH == mode || MODE_YEAR == mode) + { + QDate date = ui->m_contrastTime->date(); + date.setDate(year, month, 1); + ui->m_contrastTime->setDate(date); + } +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.h b/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.h index 27dc69e1..2c4bf8ec 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.h +++ b/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.h @@ -1,128 +1,128 @@ -#ifndef CONTRASTWIDGET_H -#define CONTRASTWIDGET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "CStatisCommon.h" - -QT_CHARTS_USE_NAMESPACE - -namespace Ui { -class ContrastWidget; -} - -class CTableModel; -class CDrillDownChart; -class ContrastWidget : public QWidget -{ - Q_OBJECT - Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) - Q_PROPERTY(QColor gridLineColor READ gridLineColor WRITE setGridLineColor) - Q_PROPERTY(QColor labelsColor READ labelsColor WRITE setLabelsColor) - Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor) - Q_PROPERTY(QColor legendColor READ legendColor WRITE setLegendColor) - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) -public: - explicit ContrastWidget(bool editMode, QWidget *parent = 0); - ~ContrastWidget(); - - QList currentSelected(); - void appendSelectChild(QList &list, QTreeWidgetItem *parent); - EN_STATIS_MODE currentStatisMode(); - EN_STATIS_STYLE currentStatisStyle(); - QPair currentDateTime(); - - void setCurveColor(const QList &color); - - QColor labelColor(); - void setLabelColor(const QColor &color); - - QColor gridLineColor(); - void setGridLineColor(const QColor &color); - - QColor labelsColor(); - void setLabelsColor(const QColor &color); - - QColor titleColor(); - void setTitleColor(const QColor &color); - - QColor legendColor(); - void setLegendColor(const QColor &color); - - QColor backgroundColor(); - void setBackgroundColor(const QColor &color); - -public slots: - void updateEventNum(const QMap > &hisEventMap); - -signals: - void sigQueryEvent(QList list, qint64 startTime, qint64 endTime, EN_STATIS_STYLE style); - -private: - void initView(); - void initData(); - void parseEvent(const QMap > &hisEventMap, - QMap> &locDevMap, - QMap>> &locLevelMap); - - void updateTable(const QMap> &locDevMap, - const QMap>> &locLevelMap); - - void updateSeries(const QMap> &locDevMap, - const QMap>> &locLevelMap); - - void addSeriousDev(QList>> &seriousList, - const QString &device, const QList &alarm); - - void updateDevSeries(const QList>> &seriousList); - - void addList(QList &first, const QList &add); - bool seriousContrast(const QList &lhs, const QList &rhs); - - void setDevSeriesTip(bool visible); - void makeLocationTree(QMap& map); - void appendChild(QTreeWidgetItem *parent, const QStringList &strList, - QMap &map); - -private slots: - void slotUpdateList(int index); - void slotUpdateDate(int index); - void slotModeSwitch(bool checked); - void slotSearch(); - void slotUpdateSerDev(const QString &name); - - void on_m_excelBtn_clicked(); - void on_m_pdfBtn_clicked(); - void on_m_printBtn_clicked(); - - void slotCurrentPageChanged(int year, int month); - -protected slots: - void horizonBarHovered(bool status, int index, QBarSet *barset); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - -private: - Ui::ContrastWidget *ui; - QColor m_labelColor; - QColor m_gridLineColor; - QColor m_labelsColor; - QColor m_titleColor; - QColor m_legendColor; - QColor m_backgroundColor; - CTableModel *m_model; - CDrillDownChart *m_pChart; - QChart *m_pDevChart; - QList m_listColor; - QList>> m_serAlmList; //< the most serious device - QMap>>> m_serAlmMap; //< location - the most serious device -}; - -#endif // CONTRASTWIDGET_H +#ifndef CONTRASTWIDGET_H +#define CONTRASTWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CStatisCommon.h" + +QT_CHARTS_USE_NAMESPACE + +namespace Ui { +class ContrastWidget; +} + +class CTableModel; +class CDrillDownChart; +class ContrastWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QColor gridLineColor READ gridLineColor WRITE setGridLineColor) + Q_PROPERTY(QColor labelsColor READ labelsColor WRITE setLabelsColor) + Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor) + Q_PROPERTY(QColor legendColor READ legendColor WRITE setLegendColor) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) +public: + explicit ContrastWidget(bool editMode, QWidget *parent = 0); + ~ContrastWidget(); + + QList currentSelected(); + void appendSelectChild(QList &list, QTreeWidgetItem *parent); + EN_STATIS_MODE currentStatisMode(); + EN_STATIS_STYLE currentStatisStyle(); + QPair currentDateTime(); + + void setCurveColor(const QList &color); + + QColor labelColor(); + void setLabelColor(const QColor &color); + + QColor gridLineColor(); + void setGridLineColor(const QColor &color); + + QColor labelsColor(); + void setLabelsColor(const QColor &color); + + QColor titleColor(); + void setTitleColor(const QColor &color); + + QColor legendColor(); + void setLegendColor(const QColor &color); + + QColor backgroundColor(); + void setBackgroundColor(const QColor &color); + +public slots: + void updateEventNum(const QMap > &hisEventMap); + +signals: + void sigQueryEvent(QList list, qint64 startTime, qint64 endTime, EN_STATIS_STYLE style); + +private: + void initView(); + void initData(); + void parseEvent(const QMap > &hisEventMap, + QMap> &locDevMap, + QMap>> &locLevelMap); + + void updateTable(const QMap> &locDevMap, + const QMap>> &locLevelMap); + + void updateSeries(const QMap> &locDevMap, + const QMap>> &locLevelMap); + + void addSeriousDev(QList>> &seriousList, + const QString &device, const QList &alarm); + + void updateDevSeries(const QList>> &seriousList); + + void addList(QList &first, const QList &add); + bool seriousContrast(const QList &lhs, const QList &rhs); + + void setDevSeriesTip(bool visible); + void makeLocationTree(QMap& map); + void appendChild(QTreeWidgetItem *parent, const QStringList &strList, + QMap &map); + +private slots: + void slotUpdateList(int index); + void slotUpdateDate(int index); + void slotModeSwitch(bool checked); + void slotSearch(); + void slotUpdateSerDev(const QString &name); + + void on_m_excelBtn_clicked(); + void on_m_pdfBtn_clicked(); + void on_m_printBtn_clicked(); + + void slotCurrentPageChanged(int year, int month); + +protected slots: + void horizonBarHovered(bool status, int index, QBarSet *barset); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +private: + Ui::ContrastWidget *ui; + QColor m_labelColor; + QColor m_gridLineColor; + QColor m_labelsColor; + QColor m_titleColor; + QColor m_legendColor; + QColor m_backgroundColor; + CTableModel *m_model; + CDrillDownChart *m_pChart; + QChart *m_pDevChart; + QList m_listColor; + QList>> m_serAlmList; //< the most serious device + QMap>>> m_serAlmMap; //< location - the most serious device +}; + +#endif // CONTRASTWIDGET_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.ui b/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.ui index 0753a567..a486e420 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.ui +++ b/product/src/gui/plugin/AlarmStatisWidget/ContrastWidget.ui @@ -1,218 +1,218 @@ - - - ContrastWidget - - - - 0 - 0 - 1277 - 711 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - - - - 80 - 0 - - - - 统计方式: - - - - - - - - 1 - - - - - - - - - - - - 对比方式: - - - - - - - - - - 对比时间: - - - - - - - yyyy/MM/dd - - - true - - - - - - - 查询 - - - - - - - - - - Excel - - - - - - - Pdf - - - - - - - 打印 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - CSWitchButton - QWidget -
./widget/CSWitchButton.h
- 1 -
-
- - -
+ + + ContrastWidget + + + + 0 + 0 + 1277 + 711 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + + 80 + 0 + + + + 统计方式: + + + + + + + + 1 + + + + + + + + + + + + 对比方式: + + + + + + + + + + 对比时间: + + + + + + + yyyy/MM/dd + + + true + + + + + + + 查询 + + + + + + + + + + Excel + + + + + + + Pdf + + + + + + + 打印 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + CSWitchButton + QWidget +
./widget/CSWitchButton.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/AlarmStatisWidget/main.cpp b/product/src/gui/plugin/AlarmStatisWidget/main.cpp index a1e7417c..cb0aa7c7 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/main.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/main.cpp @@ -1,44 +1,44 @@ -#include -#include "CMainWidget.h" -#include "pub_logger_api/logger.h" -//#include "dp_chg_data_api/CDpcdaForApp.h" -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - kbd_public::StartLogSystem("HMI", "AlarmStatisWidget"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - -// kbd_service::CDpcdaForApp::initGlobalThread(); - - { - LOGINFO("=========================== AlarmStatisWidget ==========================="); - QApplication app(argc, argv); - - CMainWidget w(false, QVector()); - w.show(); - - app.exec(); - } - -// kbd_service::CDpcdaForApp::releaseGlobalThread(); - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include +#include "CMainWidget.h" +#include "pub_logger_api/logger.h" +//#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + kbd_public::StartLogSystem("HMI", "AlarmStatisWidget"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + +// kbd_service::CDpcdaForApp::initGlobalThread(); + + { + LOGINFO("=========================== AlarmStatisWidget ==========================="); + QApplication app(argc, argv); + + CMainWidget w(false, QVector()); + w.show(); + + app.exec(); + } + +// kbd_service::CDpcdaForApp::releaseGlobalThread(); + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/widget/CSWitchButton.cpp b/product/src/gui/plugin/AlarmStatisWidget/widget/CSWitchButton.cpp index 8ef5c397..4752c08a 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/widget/CSWitchButton.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/widget/CSWitchButton.cpp @@ -1,221 +1,221 @@ -#include -#include -#include -#include "CSWitchButton.h" - -CSWitchButton::CSWitchButton(QWidget *parent) - : QWidget(parent), - m_bChecked(false), - m_background(Qt::gray), - m_checkedColor(Qt::gray), - m_disabledColor(Qt::darkGray), - m_handleColor(Qt::white), - m_textColor(Qt::black), - m_radius(5.0), - m_borderColor(Qt::gray), - m_nHeight(12), - m_nMargin(0) -{ - setCursor(Qt::PointingHandCursor); - - connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); -} - -// 绘制开关 -void CSWitchButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter painter(this); - painter.setPen(m_borderColor); - painter.setRenderHint(QPainter::Antialiasing); - - QPainterPath path; - QColor background; - QColor handleColor; - QString text; - if (isEnabled()) { // 可用状态 - if (m_bChecked) { // 打开状态 - background = m_checkedColor; - handleColor = m_handleColor; - text = m_strText; - } else { //关闭状态 - background = m_background; - handleColor = m_handleColor; - text = m_strCheckText; - } - } else { // 不可用状态 - background = m_disabledColor; - handleColor = m_disabledColor; - } - // 绘制边界 - painter.setBrush(background); - - path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width(), height()), m_radius, m_radius); - painter.drawPath(path.simplified()); - - // 绘制滑块 - painter.setBrush(handleColor); - painter.drawRoundedRect(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), width()/2, height()), m_radius, m_radius); - painter.setPen(m_textColor); - painter.drawText(QRectF(width()/2 - m_nX + (m_nHeight / 2), height()/5, width()/2, height()), text); -} - -// 鼠标按下事件 -void CSWitchButton::mousePressEvent(QMouseEvent *event) -{ - if (isEnabled()) { - if (event->buttons() & Qt::LeftButton) { - event->accept(); - } else { - event->ignore(); - } - } -} - -// 鼠标释放事件 - 切换开关状态、发射toggled()信号 -void CSWitchButton::mouseReleaseEvent(QMouseEvent *event) -{ - if (isEnabled()) { - if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { - event->accept(); - m_timer.start(10); - m_bChecked = !m_bChecked; - emit toggled(m_bChecked); - } else { - event->ignore(); - } - } -} - -// 大小改变事件 -void CSWitchButton::resizeEvent(QResizeEvent *event) -{ - m_nX = m_nHeight / 2; - m_nY = m_nHeight / 2; - QWidget::resizeEvent(event); -} - -// 默认大小 -QSize CSWitchButton::sizeHint() const -{ - return minimumSizeHint(); -} - -// 最小大小 -QSize CSWitchButton::minimumSizeHint() const -{ - return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); -} - -// 切换状态 - 滑动 -void CSWitchButton::onTimeout() -{ - if (m_bChecked) { - m_nX += 3; - if (m_nX >= width()/2 + m_nHeight / 2) - { - m_nX = width()/2 + m_nHeight / 2; - m_timer.stop(); - } - } else { - m_nX -= 3; - if (m_nX <= m_nHeight / 2) - { - m_nX = m_nHeight / 2; - m_timer.stop(); - } - } - update(); -} - -bool CSWitchButton::isToggled() -{ - return m_bChecked; -} - -void CSWitchButton::setToggle(bool checked) -{ - m_bChecked = checked; -} - -void CSWitchButton::setText(QString text) -{ - m_strText = text; -} - -void CSWitchButton::setCheckedText(QString text) -{ - m_strCheckText = text; -} - -QColor CSWitchButton::backgroundColor() -{ - return m_background; -} - -void CSWitchButton::setBackgroundColor(QColor color) -{ - m_background = color; -} - -QColor CSWitchButton::checkedColor() -{ - return m_checkedColor; -} - -void CSWitchButton::setCheckedColor(QColor color) -{ - m_checkedColor = color; -} - -QColor CSWitchButton::disableColor() -{ - return m_disabledColor; -} - -void CSWitchButton::setDisableColor(QColor color) -{ - m_disabledColor = color; -} - -QColor CSWitchButton::handleColor() -{ - return m_handleColor; -} - -void CSWitchButton::setHandleColor(QColor color) -{ - m_handleColor = color; -} - -QColor CSWitchButton::textColor() -{ - return m_textColor; -} - -void CSWitchButton::setTextColor(QColor color) -{ - m_textColor = color; -} - -qreal CSWitchButton::radius() -{ - return m_radius; -} - -void CSWitchButton::setRadius(qreal radius) -{ - m_radius = radius; -} - -QColor CSWitchButton::borderColor() -{ - return m_borderColor; -} - -void CSWitchButton::setBorderColor(QColor color) -{ - m_borderColor = color; -} - +#include +#include +#include +#include "CSWitchButton.h" + +CSWitchButton::CSWitchButton(QWidget *parent) + : QWidget(parent), + m_bChecked(false), + m_background(Qt::gray), + m_checkedColor(Qt::gray), + m_disabledColor(Qt::darkGray), + m_handleColor(Qt::white), + m_textColor(Qt::black), + m_radius(5.0), + m_borderColor(Qt::gray), + m_nHeight(12), + m_nMargin(0) +{ + setCursor(Qt::PointingHandCursor); + + connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); +} + +// 绘制开关 +void CSWitchButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + painter.setPen(m_borderColor); + painter.setRenderHint(QPainter::Antialiasing); + + QPainterPath path; + QColor background; + QColor handleColor; + QString text; + if (isEnabled()) { // 可用状态 + if (m_bChecked) { // 打开状态 + background = m_checkedColor; + handleColor = m_handleColor; + text = m_strText; + } else { //关闭状态 + background = m_background; + handleColor = m_handleColor; + text = m_strCheckText; + } + } else { // 不可用状态 + background = m_disabledColor; + handleColor = m_disabledColor; + } + // 绘制边界 + painter.setBrush(background); + + path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width(), height()), m_radius, m_radius); + painter.drawPath(path.simplified()); + + // 绘制滑块 + painter.setBrush(handleColor); + painter.drawRoundedRect(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), width()/2, height()), m_radius, m_radius); + painter.setPen(m_textColor); + painter.drawText(QRectF(width()/2 - m_nX + (m_nHeight / 2), height()/5, width()/2, height()), text); +} + +// 鼠标按下事件 +void CSWitchButton::mousePressEvent(QMouseEvent *event) +{ + if (isEnabled()) { + if (event->buttons() & Qt::LeftButton) { + event->accept(); + } else { + event->ignore(); + } + } +} + +// 鼠标释放事件 - 切换开关状态、发射toggled()信号 +void CSWitchButton::mouseReleaseEvent(QMouseEvent *event) +{ + if (isEnabled()) { + if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { + event->accept(); + m_timer.start(10); + m_bChecked = !m_bChecked; + emit toggled(m_bChecked); + } else { + event->ignore(); + } + } +} + +// 大小改变事件 +void CSWitchButton::resizeEvent(QResizeEvent *event) +{ + m_nX = m_nHeight / 2; + m_nY = m_nHeight / 2; + QWidget::resizeEvent(event); +} + +// 默认大小 +QSize CSWitchButton::sizeHint() const +{ + return minimumSizeHint(); +} + +// 最小大小 +QSize CSWitchButton::minimumSizeHint() const +{ + return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); +} + +// 切换状态 - 滑动 +void CSWitchButton::onTimeout() +{ + if (m_bChecked) { + m_nX += 3; + if (m_nX >= width()/2 + m_nHeight / 2) + { + m_nX = width()/2 + m_nHeight / 2; + m_timer.stop(); + } + } else { + m_nX -= 3; + if (m_nX <= m_nHeight / 2) + { + m_nX = m_nHeight / 2; + m_timer.stop(); + } + } + update(); +} + +bool CSWitchButton::isToggled() +{ + return m_bChecked; +} + +void CSWitchButton::setToggle(bool checked) +{ + m_bChecked = checked; +} + +void CSWitchButton::setText(QString text) +{ + m_strText = text; +} + +void CSWitchButton::setCheckedText(QString text) +{ + m_strCheckText = text; +} + +QColor CSWitchButton::backgroundColor() +{ + return m_background; +} + +void CSWitchButton::setBackgroundColor(QColor color) +{ + m_background = color; +} + +QColor CSWitchButton::checkedColor() +{ + return m_checkedColor; +} + +void CSWitchButton::setCheckedColor(QColor color) +{ + m_checkedColor = color; +} + +QColor CSWitchButton::disableColor() +{ + return m_disabledColor; +} + +void CSWitchButton::setDisableColor(QColor color) +{ + m_disabledColor = color; +} + +QColor CSWitchButton::handleColor() +{ + return m_handleColor; +} + +void CSWitchButton::setHandleColor(QColor color) +{ + m_handleColor = color; +} + +QColor CSWitchButton::textColor() +{ + return m_textColor; +} + +void CSWitchButton::setTextColor(QColor color) +{ + m_textColor = color; +} + +qreal CSWitchButton::radius() +{ + return m_radius; +} + +void CSWitchButton::setRadius(qreal radius) +{ + m_radius = radius; +} + +QColor CSWitchButton::borderColor() +{ + return m_borderColor; +} + +void CSWitchButton::setBorderColor(QColor color) +{ + m_borderColor = color; +} + diff --git a/product/src/gui/plugin/AlarmStatisWidget/widget/CSWitchButton.h b/product/src/gui/plugin/AlarmStatisWidget/widget/CSWitchButton.h index abe3466d..f477243e 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/widget/CSWitchButton.h +++ b/product/src/gui/plugin/AlarmStatisWidget/widget/CSWitchButton.h @@ -1,92 +1,92 @@ -#ifndef SWITCHBUTTON_H -#define SWITCHBUTTON_H - -#include -#include - -class CSWitchButton : public QWidget -{ - Q_OBJECT - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) - Q_PROPERTY(QColor checkedColor READ checkedColor WRITE setCheckedColor) - Q_PROPERTY(QColor disableColor READ disableColor WRITE setDisableColor) - Q_PROPERTY(QColor handleColor READ handleColor WRITE setHandleColor) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(qreal radius READ radius WRITE setRadius) - Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) - -public: - explicit CSWitchButton(QWidget *parent = 0); - - bool isToggled(); - - void setToggle(bool checked); - - void setText(QString text); - - void setCheckedText(QString text); - - QColor backgroundColor(); - void setBackgroundColor(QColor color); - - QColor checkedColor(); - void setCheckedColor(QColor color); - - QColor disableColor(); - void setDisableColor(QColor color); - - QColor handleColor(); - void setHandleColor(QColor color); - - QColor textColor(); - void setTextColor(QColor color); - - qreal radius(); - void setRadius(qreal radius); - - QColor borderColor(); - void setBorderColor(QColor color); - -protected: - // 绘制开关 - void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - - // 鼠标按下事件 - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // 鼠标释放事件 - 切换开关状态、发射toggled()信号 - void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // 大小改变事件 - void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; - - // 缺省大小 - QSize sizeHint() const Q_DECL_OVERRIDE; - QSize minimumSizeHint() const Q_DECL_OVERRIDE; - -signals: - void toggled(bool checked); - -private slots: - // 状态切换时,用于产生滑动效果 - void onTimeout(); - -private: - bool m_bChecked; - QColor m_background; - QColor m_checkedColor; - QColor m_disabledColor; - QColor m_handleColor; - QColor m_textColor; - qreal m_radius; - QColor m_borderColor; - QString m_strText; - QString m_strCheckText; - qreal m_nX{}; - qreal m_nY{}; - qint16 m_nHeight; - qint16 m_nMargin; - QTimer m_timer; -}; - -#endif // SWITCHBUTTON_H +#ifndef SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include +#include + +class CSWitchButton : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(QColor checkedColor READ checkedColor WRITE setCheckedColor) + Q_PROPERTY(QColor disableColor READ disableColor WRITE setDisableColor) + Q_PROPERTY(QColor handleColor READ handleColor WRITE setHandleColor) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(qreal radius READ radius WRITE setRadius) + Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) + +public: + explicit CSWitchButton(QWidget *parent = 0); + + bool isToggled(); + + void setToggle(bool checked); + + void setText(QString text); + + void setCheckedText(QString text); + + QColor backgroundColor(); + void setBackgroundColor(QColor color); + + QColor checkedColor(); + void setCheckedColor(QColor color); + + QColor disableColor(); + void setDisableColor(QColor color); + + QColor handleColor(); + void setHandleColor(QColor color); + + QColor textColor(); + void setTextColor(QColor color); + + qreal radius(); + void setRadius(qreal radius); + + QColor borderColor(); + void setBorderColor(QColor color); + +protected: + // 绘制开关 + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + // 鼠标按下事件 + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 鼠标释放事件 - 切换开关状态、发射toggled()信号 + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 大小改变事件 + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + + // 缺省大小 + QSize sizeHint() const Q_DECL_OVERRIDE; + QSize minimumSizeHint() const Q_DECL_OVERRIDE; + +signals: + void toggled(bool checked); + +private slots: + // 状态切换时,用于产生滑动效果 + void onTimeout(); + +private: + bool m_bChecked; + QColor m_background; + QColor m_checkedColor; + QColor m_disabledColor; + QColor m_handleColor; + QColor m_textColor; + qreal m_radius; + QColor m_borderColor; + QString m_strText; + QString m_strCheckText; + qreal m_nX{}; + qreal m_nY{}; + qint16 m_nHeight; + qint16 m_nMargin; + QTimer m_timer; +}; + +#endif // SWITCHBUTTON_H diff --git a/product/src/gui/plugin/AlarmStatisWidget/widget/CToolTip.cpp b/product/src/gui/plugin/AlarmStatisWidget/widget/CToolTip.cpp index 3558c6cd..4de7c190 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/widget/CToolTip.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/widget/CToolTip.cpp @@ -1,66 +1,66 @@ -#include "CToolTip.h" -#include -#include -#include -#include -#include - -CToolTip::CToolTip(QWidget *parent) - : QDialog(parent) -{ - setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); - setAttribute(Qt::WA_DeleteOnClose); - setObjectName("ToolTip"); - label_ = new QLabel(this); - label_->setMouseTracking(true); - label_->installEventFilter(parent); - QHBoxLayout *mLayout = new QHBoxLayout(this); - mLayout->addWidget(label_); - mLayout->setMargin(0); - installEventFilter(this); - label_->setObjectName("tipLabel"); -} - -CToolTip::~CToolTip() -{ -} - -QString CToolTip::text() -{ - return label_->text(); -} - -void CToolTip::setText(const QString &text) -{ - label_->setText(text); -} - -bool CToolTip::eventFilter(QObject *object, QEvent *event) -{ - if (object == this) - { - if (QEvent::WindowDeactivate == event->type()) - { - this->close(); - event->accept(); - return true; - } - } - return QWidget::eventFilter(object, event); -} - -void CToolTip::popup(QPoint pos, const QString &text, QWidget *parent) -{ - CToolTip * tip = new CToolTip(parent); - tip->setText(text); - tip->show(); - int screenWidth = QApplication::desktop()->screenGeometry().width(); - if((tip->width() + pos.x()) < screenWidth) - { - tip->move(pos); - } - else - { - tip->move(pos.x() - tip->width(), pos.y()); - } -} +#include "CToolTip.h" +#include +#include +#include +#include +#include + +CToolTip::CToolTip(QWidget *parent) + : QDialog(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_DeleteOnClose); + setObjectName("ToolTip"); + label_ = new QLabel(this); + label_->setMouseTracking(true); + label_->installEventFilter(parent); + QHBoxLayout *mLayout = new QHBoxLayout(this); + mLayout->addWidget(label_); + mLayout->setMargin(0); + installEventFilter(this); + label_->setObjectName("tipLabel"); +} + +CToolTip::~CToolTip() +{ +} + +QString CToolTip::text() +{ + return label_->text(); +} + +void CToolTip::setText(const QString &text) +{ + label_->setText(text); +} + +bool CToolTip::eventFilter(QObject *object, QEvent *event) +{ + if (object == this) + { + if (QEvent::WindowDeactivate == event->type()) + { + this->close(); + event->accept(); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +void CToolTip::popup(QPoint pos, const QString &text, QWidget *parent) +{ + CToolTip * tip = new CToolTip(parent); + tip->setText(text); + tip->show(); + int screenWidth = QApplication::desktop()->screenGeometry().width(); + if((tip->width() + pos.x()) < screenWidth) + { + tip->move(pos); + } + else + { + tip->move(pos.x() - tip->width(), pos.y()); + } +} diff --git a/product/src/gui/plugin/AlarmStatisWidget/widget/CToolTip.h b/product/src/gui/plugin/AlarmStatisWidget/widget/CToolTip.h index 92ec4b3f..27affd5a 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/widget/CToolTip.h +++ b/product/src/gui/plugin/AlarmStatisWidget/widget/CToolTip.h @@ -1,25 +1,25 @@ -#ifndef CTOOLTIP_H -#define CTOOLTIP_H - -#include - -class QLabel; -class CToolTip : public QDialog -{ - Q_OBJECT -public: - CToolTip(QWidget *parent = nullptr); - ~CToolTip(); - - QString text(); - void setText(const QString &text); - static void popup(QPoint pos, const QString &text, QWidget *parent = nullptr); - -protected: - bool eventFilter(QObject *object, QEvent *event); - -private: - QLabel *label_; -}; - -#endif // CTOOLTIP_H +#ifndef CTOOLTIP_H +#define CTOOLTIP_H + +#include + +class QLabel; +class CToolTip : public QDialog +{ + Q_OBJECT +public: + CToolTip(QWidget *parent = nullptr); + ~CToolTip(); + + QString text(); + void setText(const QString &text); + static void popup(QPoint pos, const QString &text, QWidget *parent = nullptr); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private: + QLabel *label_; +}; + +#endif // CTOOLTIP_H diff --git a/product/src/gui/plugin/AlarmWidget/AlarmWidget.pro b/product/src/gui/plugin/AlarmWidget/AlarmWidget.pro index cc4bf06a..802b12a2 100644 --- a/product/src/gui/plugin/AlarmWidget/AlarmWidget.pro +++ b/product/src/gui/plugin/AlarmWidget/AlarmWidget.pro @@ -1,120 +1,120 @@ -QT += core sql xml multimedia webenginewidgets texttospeech - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = AlarmWidget - -CONFIG += plugin - - -HEADERS = \ - CAlarmBaseData.h \ - CAlarmItemModel.h \ - CAlarmShiledDialog.h \ - CAlarmView.h \ - CAlarmDelegate.h \ - CAlarmForm.h \ - CAlarmFilterDialog.h \ - CAlarmWidget.h \ - CAlarmDataCollect.h \ - CAlarmMsgInfo.h \ - CAlarmPlugin.h \ - CAlarmMsgManage.h \ - CAlarmPluginWidget.h \ - CAlarmMediaPlayer.h \ - CTableViewPrinter.h \ - CAlarmInhibitDialog.h \ - CAlarmDeviceTreeItem.h \ - CAlarmDeviceTreeModel.h \ - CAlarmDeviceTreeView.h \ - CAlarmCommon.h \ - CMyListWidget.h \ - CMyCalendar.h \ - CMyCheckBox.h \ - CAiAlarmTreeView.h \ - CAiAlarmMsgInfo.h \ - CAiAlarmDataCollect.h \ - CAiAlarmTreeItem.h \ - CAiAlarmTreeModel.h \ - CAiAlarmDelegate.h \ - CDisposalPlanDialog.h \ - CTreeViewPrinter.h \ - CPdfPrinter.h \ - CAlarmTaskMngDlg.h \ - CAlarmSetDlg.h \ - CAlarmColorInfo.h \ - CAlarmSetMng.h \ - CAlarmColorWidget.h \ - CAccidentReviewDialog.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h - -SOURCES = \ - CAlarmBaseData.cpp \ - CAlarmItemModel.cpp \ - CAlarmShiledDialog.cpp \ - CAlarmView.cpp \ - CAlarmDelegate.cpp \ - CAlarmForm.cpp \ - CAlarmFilterDialog.cpp \ - CAlarmWidget.cpp \ - CAlarmDataCollect.cpp \ - CAlarmMsgInfo.cpp \ - CAlarmPlugin.cpp \ - CAlarmMsgManage.cpp \ - CAlarmPluginWidget.cpp \ - CAlarmMediaPlayer.cpp \ - CTableViewPrinter.cpp \ - CAlarmInhibitDialog.cpp \ - CAlarmDeviceTreeModel.cpp \ - CAlarmDeviceTreeItem.cpp \ - CAlarmDeviceTreeView.cpp \ - CMyListWidget.cpp \ - CMyCalendar.cpp \ - CMyCheckBox.cpp \ - CAiAlarmTreeView.cpp \ - CAiAlarmMsgInfo.cpp \ - CAiAlarmDataCollect.cpp \ - CAiAlarmTreeItem.cpp \ - CAiAlarmTreeModel.cpp \ - CAiAlarmDelegate.cpp \ - CDisposalPlanDialog.cpp \ - CTreeViewPrinter.cpp \ - CPdfPrinter.cpp \ - CAlarmTaskMngDlg.cpp \ - CAlarmSetDlg.cpp \ - CAlarmColorInfo.cpp \ - CAlarmSetMng.cpp \ - CAlarmColorWidget.cpp \ - CAccidentReviewDialog.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp - -FORMS += \ - CAlarmFilterDialog.ui \ - CAlarmForm.ui \ - CAlarmInhibitDialog.ui \ - CAlarmShiledDialog.ui \ - CMyCalendar.ui \ - CDisposalPlanDialog.ui \ - CAlarmTaskMngDlg.ui \ - CAlarmSetDlg.ui \ - CAlarmColorWidget.ui - - -LIBS += -llog4cplus -lboost_system -lboost_filesystem -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lrdb_net_api -lperm_mng_api -lpub_sysinfo_api -LIBS += -lnet_msg_bus_api -lalarm_server_api -lintelli_alm_api -lmodel_excel -lidong_srv_api - -win32{ - # CAlarmMediaPlayer.cpp 检测声卡的代码使用 - LIBS += -lole32 -} - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +QT += core sql xml multimedia webenginewidgets texttospeech + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = AlarmWidget + +CONFIG += plugin + + +HEADERS = \ + CAlarmBaseData.h \ + CAlarmItemModel.h \ + CAlarmShiledDialog.h \ + CAlarmView.h \ + CAlarmDelegate.h \ + CAlarmForm.h \ + CAlarmFilterDialog.h \ + CAlarmWidget.h \ + CAlarmDataCollect.h \ + CAlarmMsgInfo.h \ + CAlarmPlugin.h \ + CAlarmMsgManage.h \ + CAlarmPluginWidget.h \ + CAlarmMediaPlayer.h \ + CTableViewPrinter.h \ + CAlarmInhibitDialog.h \ + CAlarmDeviceTreeItem.h \ + CAlarmDeviceTreeModel.h \ + CAlarmDeviceTreeView.h \ + CAlarmCommon.h \ + CMyListWidget.h \ + CMyCalendar.h \ + CMyCheckBox.h \ + CAiAlarmTreeView.h \ + CAiAlarmMsgInfo.h \ + CAiAlarmDataCollect.h \ + CAiAlarmTreeItem.h \ + CAiAlarmTreeModel.h \ + CAiAlarmDelegate.h \ + CDisposalPlanDialog.h \ + CTreeViewPrinter.h \ + CPdfPrinter.h \ + CAlarmTaskMngDlg.h \ + CAlarmSetDlg.h \ + CAlarmColorInfo.h \ + CAlarmSetMng.h \ + CAlarmColorWidget.h \ + CAccidentReviewDialog.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h + +SOURCES = \ + CAlarmBaseData.cpp \ + CAlarmItemModel.cpp \ + CAlarmShiledDialog.cpp \ + CAlarmView.cpp \ + CAlarmDelegate.cpp \ + CAlarmForm.cpp \ + CAlarmFilterDialog.cpp \ + CAlarmWidget.cpp \ + CAlarmDataCollect.cpp \ + CAlarmMsgInfo.cpp \ + CAlarmPlugin.cpp \ + CAlarmMsgManage.cpp \ + CAlarmPluginWidget.cpp \ + CAlarmMediaPlayer.cpp \ + CTableViewPrinter.cpp \ + CAlarmInhibitDialog.cpp \ + CAlarmDeviceTreeModel.cpp \ + CAlarmDeviceTreeItem.cpp \ + CAlarmDeviceTreeView.cpp \ + CMyListWidget.cpp \ + CMyCalendar.cpp \ + CMyCheckBox.cpp \ + CAiAlarmTreeView.cpp \ + CAiAlarmMsgInfo.cpp \ + CAiAlarmDataCollect.cpp \ + CAiAlarmTreeItem.cpp \ + CAiAlarmTreeModel.cpp \ + CAiAlarmDelegate.cpp \ + CDisposalPlanDialog.cpp \ + CTreeViewPrinter.cpp \ + CPdfPrinter.cpp \ + CAlarmTaskMngDlg.cpp \ + CAlarmSetDlg.cpp \ + CAlarmColorInfo.cpp \ + CAlarmSetMng.cpp \ + CAlarmColorWidget.cpp \ + CAccidentReviewDialog.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp + +FORMS += \ + CAlarmFilterDialog.ui \ + CAlarmForm.ui \ + CAlarmInhibitDialog.ui \ + CAlarmShiledDialog.ui \ + CMyCalendar.ui \ + CDisposalPlanDialog.ui \ + CAlarmTaskMngDlg.ui \ + CAlarmSetDlg.ui \ + CAlarmColorWidget.ui + + +LIBS += -llog4cplus -lboost_system -lboost_filesystem -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lrdb_net_api -lperm_mng_api -lpub_sysinfo_api +LIBS += -lnet_msg_bus_api -lalarm_server_api -lintelli_alm_api -lmodel_excel -lidong_srv_api + +win32{ + # CAlarmMediaPlayer.cpp 检测声卡的代码使用 + LIBS += -lole32 +} + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/AlarmWidget/CAccidentReviewDialog.cpp b/product/src/gui/plugin/AlarmWidget/CAccidentReviewDialog.cpp index f0b59bb7..493f740a 100644 --- a/product/src/gui/plugin/AlarmWidget/CAccidentReviewDialog.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAccidentReviewDialog.cpp @@ -1,289 +1,289 @@ -#include "CAccidentReviewDialog.h" -#include "public/pub_utility_api/FileUtil.h" -#include "public/pub_logger_api/logger.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -CAccidentReviewDialog::CAccidentReviewDialog(const QString &path, QWidget *parent) - : QDialog(parent) -{ - resize(350,450); - getFilterNames(path); - initView(); - initTree(); -} - -CAccidentReviewDialog::~CAccidentReviewDialog() -{ - -} - -QString CAccidentReviewDialog::getCurrentGraph() -{ - if(m_treeWidget->currentItem()) - { - return m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); - } - return QString(); -} - -void CAccidentReviewDialog::initView() -{ - setWindowTitle(tr("事故追忆")); - m_treeWidget = new QTreeWidget(this); - m_treeWidget->headerItem()->setHidden(true); - - QSpacerItem * spacer = new QSpacerItem(10, 0, QSizePolicy::Preferred); - m_confirmBtn = new QPushButton(tr("确认"), this); - m_cancelBtn = new QPushButton(tr("取消"), this); - connect(m_confirmBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotConfirm); - connect(m_cancelBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotCancel); - - QGridLayout * layout = new QGridLayout(); - layout->addWidget(m_treeWidget, 0, 0, 1, 3); - layout->addItem(spacer, 1, 0); - layout->addWidget(m_confirmBtn, 1, 1); - layout->addWidget(m_cancelBtn, 1, 2); - setLayout(layout); -} - -void CAccidentReviewDialog::initTree() -{ - QMap>> m_mapNav; - readNavJson(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) - + QString("../../data/model/NavigationWidget.json"), m_mapNav); - QList> nodeList = m_mapNav.value(-1); - for(int nIndex=0; nIndexaddTopLevelItem(item); - - addChildLevelItem(item, nodeList[nIndex], m_mapNav); - } - treeFilter(); - m_treeWidget->expandAll(); -} - -void CAccidentReviewDialog::getFilterNames(const QString &path) -{ - QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) - + QString("../../data/pic/"); - m_fileNameList = getAllFile(filePath, filePath, path); -} - -QStringList CAccidentReviewDialog::getAllFile(const QString &path, const QString &relativePath, const QString &filter) -{ - QDir dir(path); - QDir relativeDir(relativePath); - QStringList allFile; - - QString fileName; - QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoSymLinks); - for(QFileInfo &file : fileList) - { - fileName = relativeDir.relativeFilePath(file.filePath()); - if(fileName.contains(filter)) - { - allFile.append(fileName); - } - } - - QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - for(QFileInfo &folder : folderList) - { - allFile.append(getAllFile(folder.absoluteFilePath(), relativePath, filter)); - } - - return allFile; -} - -void CAccidentReviewDialog::treeFilter() -{ - bool topShow,childShow,leafShow; - int nTopCount = m_treeWidget->topLevelItemCount(); - for(int nTopIndex(0); nTopIndextopLevelItem(nTopIndex); - topShow = m_fileNameList.contains(topItem->data(0, Qt::UserRole).toString()); - - int nChildCount = topItem->childCount(); - for(int nChildIndex(0); nChildIndexchild(nChildIndex); - childShow = m_fileNameList.contains(childItem->data(0, Qt::UserRole).toString()); - - int nLeafCount = childItem->childCount(); - for(int nLeafIndex(0); nLeafIndexchild(nLeafIndex); - leafShow = m_fileNameList.contains(leafItem->data(0, Qt::UserRole).toString()); - leafItem->setHidden(!leafShow); - if(leafShow) - { - childShow = true; - } - } - childItem->setHidden(!childShow); - if(childShow) - { - topShow = true; - } - } - topItem->setHidden(!topShow); - } -} - -void CAccidentReviewDialog::slotConfirm() -{ - if(m_treeWidget->currentItem() == NULL) - { - QMessageBox::information(this, tr("提示"), tr("请选择一张画面!"), QMessageBox::Ok); - return; - } - QString data = m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); - if(data.isEmpty() || !m_fileNameList.contains(data)) - { - QMessageBox::information(this, tr("提示"), tr("请选择其他画面!"), QMessageBox::Ok); - return; - } - accept(); -} - -void CAccidentReviewDialog::slotCancel() -{ - reject(); -} - -void CAccidentReviewDialog::addChildLevelItem(QTreeWidgetItem *item, const QPair &node, - const QMap > > &navMap) -{ - const QList > childList = navMap.value(node.first); - for(int nIndex=0; nIndexaddChild(childItem); - - addChildLevelItem(childItem, childList[nIndex], navMap); - } -} - -QTreeWidgetItem *CAccidentReviewDialog::getAddLevelItem(const ST_NODE &st_node) -{ - if(st_node.used == Disable) - { - return NULL; - } - - QTreeWidgetItem * childItem = new QTreeWidgetItem(); - childItem->setData(0, Qt::DisplayRole, st_node.name); - childItem->setData(0, Qt::UserRole, st_node.data); - return childItem; -} - -void CAccidentReviewDialog::readNavJson(const QString &path, QMap > > &map) -{ - QFile file(path); - QByteArray readJson; - if(file.open(QIODevice::ReadOnly)) - { - readJson = file.readAll(); - file.close(); - } - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return; - } - QJsonObject root = readJsonResponse.object(); - if(root.contains("items")) - { - QJsonArray itemArray = root.value("items").toArray(); - int nItemNumber = 0; - for(int nIndex(0); nIndex< itemArray.size(); nIndex++) - { - ST_NODE st_Node_Top; - QJsonObject topLevelObject = itemArray[nIndex].toObject(); - makeStButton(st_Node_Top, topLevelObject); - QPair topMap; - int nTopNumber = nItemNumber; - topMap.first = nItemNumber++; - topMap.second = st_Node_Top; - - QJsonArray childArray = topLevelObject.value("items").toArray(); - for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) - { - ST_NODE st_Node_Child; - QJsonObject childLevelObject = childArray[nChildIndex].toObject(); - makeStButton(st_Node_Child, childLevelObject); - QPair childMap; - int nChildNumber = nItemNumber; - childMap.first = nItemNumber++; - childMap.second = st_Node_Child; - - QJsonArray leafArray = childLevelObject.value("items").toArray(); - for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) - { - ST_NODE st_Node_Leaf; - QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); - makeStButton(st_Node_Leaf, leafLevelObject); - QPair leafMap; - leafMap.first = nItemNumber++; - leafMap.second = st_Node_Leaf; - map[nChildNumber].append(leafMap); - } - map[nTopNumber].append(childMap); - } - map[-1].append(topMap); - } - } -} - -void CAccidentReviewDialog::makeStButton(ST_NODE &st_Node, const QJsonObject &object) -{ - if(!object.value("name").isUndefined()) - { - st_Node.name = object.value("name").toString(); - } - if(!object.value("icon").isUndefined()) - { - st_Node.icon = object.value("icon").toString(); - } - if(!object.value("data").isUndefined()) - { - st_Node.data = object.value("data").toString(); - } - if(!object.value("opt").isUndefined()) - { - st_Node.type = object.value("opt").toInt(); - } - if(!object.value("used").isUndefined()) - { - st_Node.used = object.value("used").toInt(); - } - if(!object.value("web").isUndefined()) - { - st_Node.web = object.value("web").toInt(); - } - if(!object.value("webData").isUndefined()) - { - st_Node.webData = object.value("webData").toString(); - } -} +#include "CAccidentReviewDialog.h" +#include "public/pub_utility_api/FileUtil.h" +#include "public/pub_logger_api/logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CAccidentReviewDialog::CAccidentReviewDialog(const QString &path, QWidget *parent) + : QDialog(parent) +{ + resize(350,450); + getFilterNames(path); + initView(); + initTree(); +} + +CAccidentReviewDialog::~CAccidentReviewDialog() +{ + +} + +QString CAccidentReviewDialog::getCurrentGraph() +{ + if(m_treeWidget->currentItem()) + { + return m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); + } + return QString(); +} + +void CAccidentReviewDialog::initView() +{ + setWindowTitle(tr("事故追忆")); + m_treeWidget = new QTreeWidget(this); + m_treeWidget->headerItem()->setHidden(true); + + QSpacerItem * spacer = new QSpacerItem(10, 0, QSizePolicy::Preferred); + m_confirmBtn = new QPushButton(tr("确认"), this); + m_cancelBtn = new QPushButton(tr("取消"), this); + connect(m_confirmBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotConfirm); + connect(m_cancelBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotCancel); + + QGridLayout * layout = new QGridLayout(); + layout->addWidget(m_treeWidget, 0, 0, 1, 3); + layout->addItem(spacer, 1, 0); + layout->addWidget(m_confirmBtn, 1, 1); + layout->addWidget(m_cancelBtn, 1, 2); + setLayout(layout); +} + +void CAccidentReviewDialog::initTree() +{ + QMap>> m_mapNav; + readNavJson(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + + QString("../../data/model/NavigationWidget.json"), m_mapNav); + QList> nodeList = m_mapNav.value(-1); + for(int nIndex=0; nIndexaddTopLevelItem(item); + + addChildLevelItem(item, nodeList[nIndex], m_mapNav); + } + treeFilter(); + m_treeWidget->expandAll(); +} + +void CAccidentReviewDialog::getFilterNames(const QString &path) +{ + QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + + QString("../../data/pic/"); + m_fileNameList = getAllFile(filePath, filePath, path); +} + +QStringList CAccidentReviewDialog::getAllFile(const QString &path, const QString &relativePath, const QString &filter) +{ + QDir dir(path); + QDir relativeDir(relativePath); + QStringList allFile; + + QString fileName; + QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoSymLinks); + for(QFileInfo &file : fileList) + { + fileName = relativeDir.relativeFilePath(file.filePath()); + if(fileName.contains(filter)) + { + allFile.append(fileName); + } + } + + QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for(QFileInfo &folder : folderList) + { + allFile.append(getAllFile(folder.absoluteFilePath(), relativePath, filter)); + } + + return allFile; +} + +void CAccidentReviewDialog::treeFilter() +{ + bool topShow,childShow,leafShow; + int nTopCount = m_treeWidget->topLevelItemCount(); + for(int nTopIndex(0); nTopIndextopLevelItem(nTopIndex); + topShow = m_fileNameList.contains(topItem->data(0, Qt::UserRole).toString()); + + int nChildCount = topItem->childCount(); + for(int nChildIndex(0); nChildIndexchild(nChildIndex); + childShow = m_fileNameList.contains(childItem->data(0, Qt::UserRole).toString()); + + int nLeafCount = childItem->childCount(); + for(int nLeafIndex(0); nLeafIndexchild(nLeafIndex); + leafShow = m_fileNameList.contains(leafItem->data(0, Qt::UserRole).toString()); + leafItem->setHidden(!leafShow); + if(leafShow) + { + childShow = true; + } + } + childItem->setHidden(!childShow); + if(childShow) + { + topShow = true; + } + } + topItem->setHidden(!topShow); + } +} + +void CAccidentReviewDialog::slotConfirm() +{ + if(m_treeWidget->currentItem() == NULL) + { + QMessageBox::information(this, tr("提示"), tr("请选择一张画面!"), QMessageBox::Ok); + return; + } + QString data = m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); + if(data.isEmpty() || !m_fileNameList.contains(data)) + { + QMessageBox::information(this, tr("提示"), tr("请选择其他画面!"), QMessageBox::Ok); + return; + } + accept(); +} + +void CAccidentReviewDialog::slotCancel() +{ + reject(); +} + +void CAccidentReviewDialog::addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap) +{ + const QList > childList = navMap.value(node.first); + for(int nIndex=0; nIndexaddChild(childItem); + + addChildLevelItem(childItem, childList[nIndex], navMap); + } +} + +QTreeWidgetItem *CAccidentReviewDialog::getAddLevelItem(const ST_NODE &st_node) +{ + if(st_node.used == Disable) + { + return NULL; + } + + QTreeWidgetItem * childItem = new QTreeWidgetItem(); + childItem->setData(0, Qt::DisplayRole, st_node.name); + childItem->setData(0, Qt::UserRole, st_node.data); + return childItem; +} + +void CAccidentReviewDialog::readNavJson(const QString &path, QMap > > &map) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + if(root.contains("items")) + { + QJsonArray itemArray = root.value("items").toArray(); + int nItemNumber = 0; + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + ST_NODE st_Node_Top; + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + makeStButton(st_Node_Top, topLevelObject); + QPair topMap; + int nTopNumber = nItemNumber; + topMap.first = nItemNumber++; + topMap.second = st_Node_Top; + + QJsonArray childArray = topLevelObject.value("items").toArray(); + for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) + { + ST_NODE st_Node_Child; + QJsonObject childLevelObject = childArray[nChildIndex].toObject(); + makeStButton(st_Node_Child, childLevelObject); + QPair childMap; + int nChildNumber = nItemNumber; + childMap.first = nItemNumber++; + childMap.second = st_Node_Child; + + QJsonArray leafArray = childLevelObject.value("items").toArray(); + for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) + { + ST_NODE st_Node_Leaf; + QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); + makeStButton(st_Node_Leaf, leafLevelObject); + QPair leafMap; + leafMap.first = nItemNumber++; + leafMap.second = st_Node_Leaf; + map[nChildNumber].append(leafMap); + } + map[nTopNumber].append(childMap); + } + map[-1].append(topMap); + } + } +} + +void CAccidentReviewDialog::makeStButton(ST_NODE &st_Node, const QJsonObject &object) +{ + if(!object.value("name").isUndefined()) + { + st_Node.name = object.value("name").toString(); + } + if(!object.value("icon").isUndefined()) + { + st_Node.icon = object.value("icon").toString(); + } + if(!object.value("data").isUndefined()) + { + st_Node.data = object.value("data").toString(); + } + if(!object.value("opt").isUndefined()) + { + st_Node.type = object.value("opt").toInt(); + } + if(!object.value("used").isUndefined()) + { + st_Node.used = object.value("used").toInt(); + } + if(!object.value("web").isUndefined()) + { + st_Node.web = object.value("web").toInt(); + } + if(!object.value("webData").isUndefined()) + { + st_Node.webData = object.value("webData").toString(); + } +} diff --git a/product/src/gui/plugin/AlarmWidget/CAccidentReviewDialog.h b/product/src/gui/plugin/AlarmWidget/CAccidentReviewDialog.h index a2d69b28..080fb279 100644 --- a/product/src/gui/plugin/AlarmWidget/CAccidentReviewDialog.h +++ b/product/src/gui/plugin/AlarmWidget/CAccidentReviewDialog.h @@ -1,56 +1,56 @@ -#ifndef CACCIDENTREVIEWDIALOG_H -#define CACCIDENTREVIEWDIALOG_H - -#include -#include -#include - -struct ST_NODE -{ - QString name; - int used; - int type; - QString icon; - int web; - QString data; - QString webData; -}; - -class QTreeWidget; -class QTreeWidgetItem; -class CAccidentReviewDialog : public QDialog -{ - Q_OBJECT -public: - enum Node_Enable{Enable = 1,Disable = 2}; - CAccidentReviewDialog(const QString &path, QWidget *parent = Q_NULLPTR); - ~CAccidentReviewDialog(); - - QString getCurrentGraph(); - -private slots: - void slotConfirm(); - void slotCancel(); - -private: - void initView(); - void initTree(); - void getFilterNames(const QString &path); - QStringList getAllFile(const QString &path, const QString &relativePath, - const QString &filter); - void treeFilter(); - - void addChildLevelItem(QTreeWidgetItem *item, const QPair &node, - const QMap > > &navMap); - QTreeWidgetItem* getAddLevelItem(const ST_NODE& st_node); - void readNavJson(const QString &path, QMap>>& map); - void makeStButton(ST_NODE &st_Node, const QJsonObject &object); - -private: - QTreeWidget * m_treeWidget; - QPushButton * m_confirmBtn; - QPushButton * m_cancelBtn; - QStringList m_fileNameList; -}; - -#endif // CACCIDENTREVIEWDIALOG_H +#ifndef CACCIDENTREVIEWDIALOG_H +#define CACCIDENTREVIEWDIALOG_H + +#include +#include +#include + +struct ST_NODE +{ + QString name; + int used; + int type; + QString icon; + int web; + QString data; + QString webData; +}; + +class QTreeWidget; +class QTreeWidgetItem; +class CAccidentReviewDialog : public QDialog +{ + Q_OBJECT +public: + enum Node_Enable{Enable = 1,Disable = 2}; + CAccidentReviewDialog(const QString &path, QWidget *parent = Q_NULLPTR); + ~CAccidentReviewDialog(); + + QString getCurrentGraph(); + +private slots: + void slotConfirm(); + void slotCancel(); + +private: + void initView(); + void initTree(); + void getFilterNames(const QString &path); + QStringList getAllFile(const QString &path, const QString &relativePath, + const QString &filter); + void treeFilter(); + + void addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap); + QTreeWidgetItem* getAddLevelItem(const ST_NODE& st_node); + void readNavJson(const QString &path, QMap>>& map); + void makeStButton(ST_NODE &st_Node, const QJsonObject &object); + +private: + QTreeWidget * m_treeWidget; + QPushButton * m_confirmBtn; + QPushButton * m_cancelBtn; + QStringList m_fileNameList; +}; + +#endif // CACCIDENTREVIEWDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmDataCollect.cpp b/product/src/gui/plugin/AlarmWidget/CAiAlarmDataCollect.cpp index 86873389..f2654e31 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmDataCollect.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmDataCollect.cpp @@ -1,239 +1,239 @@ -#include "CAiAlarmDataCollect.h" -#include "pub_logger_api/logger.h" -#include "CAlarmMsgManage.h" -#include -#include "CAlarmDataCollect.h" -using namespace kbd_service; -CAiAlarmDataCollect * CAiAlarmDataCollect::m_pInstance = NULL; -CAiAlarmDataCollect::CAiAlarmDataCollect() - : CIntelliAlmApi4Clt(), - m_referenceCount(0), - m_bFaultRecallState(false), - m_pAlternateTimer(Q_NULLPTR) -{ - m_rtdbMutex = new QMutex(); - m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); - m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); -} - -CAiAlarmDataCollect::~CAiAlarmDataCollect() -{ - LOGDEBUG("CAiAlarmDataCollect::~CAiAlarmDataCollect()"); - qDebug() << "~CAiAlarmDataCollect()"; -} - -void CAiAlarmDataCollect::refrence() -{ - m_referenceCount++; -} - -int CAiAlarmDataCollect::getRefrenceCount() -{ - return m_referenceCount; -} - -CAiAlarmDataCollect *CAiAlarmDataCollect::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CAiAlarmDataCollect(); - } - return m_pInstance; -} - -void CAiAlarmDataCollect::initialize() -{ - resumeThread(); - if(!m_pAlternateTimer) - { - m_pAlternateTimer = new QTimer(); - m_pAlternateTimer->setInterval(1000); - connect(m_pAlternateTimer, &QTimer::timeout, this, &CAiAlarmDataCollect::slotAiAlarmStateChanged); - connect(this, &CAiAlarmDataCollect::sigTimerShot, this, &CAiAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); - } - if(!m_bFaultRecallState) - { - emit sigTimerShot(true); - } -} - -void CAiAlarmDataCollect::release() -{ - emit sigTimerShot(false); - suspendThread(true); -} - -bool CAiAlarmDataCollect::isFaultRecallState() -{ - return m_bFaultRecallState; -} - -bool CAiAlarmDataCollect::requestDelAlm(kbd_idlfile::SIntelliAlmDel &objDelAlm) -{ - LOGDEBUG("请求删除!"); - return kbd_service::CIntelliAlmApi4Clt::requestDelAlm(objDelAlm); -} - -bool CAiAlarmDataCollect::requestSeprAlm(kbd_idlfile::SIntelliAlmSepr &objSeprAlm) -{ - LOGDEBUG("请求分离!"); - return kbd_service::CIntelliAlmApi4Clt::requestSeprAlm(objSeprAlm); -} - -bool CAiAlarmDataCollect::requestMergeAlm(kbd_idlfile::SIntelliAlmMerge &objMergeAlm) -{ - LOGDEBUG("请求合并!"); - return kbd_service::CIntelliAlmApi4Clt::requestMergeAlm(objMergeAlm); -} - -void CAiAlarmDataCollect::handleAllAlmMsg(int nDomainId, kbd_idlfile::SIntelliAlmAdd &objAllAlm) -{ - LOGINFO("========== AiAlarmDataCollect handleAllAlmMsg =========="); - - //< 清空该域缓存 - QMutexLocker locker(m_rtdbMutex); - CAlarmMsgManage::instance()->removeAiAlarmMsgByDomainID(nDomainId); - //构建告警 - int nAlarmCount = objAllAlm.alm_info_size(); - QList almList; - for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) - { - kbd_idlfile::SIntelliAlmInfo msg = objAllAlm.alm_info(nAddMsgIndex); - AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); - alm->initialize(msg); - alm->priorityOrder = queryPriorityOrder(alm->priority); - almList.append(alm); - } - CAlarmMsgManage::instance()->addAiAllAlarmMsg(almList);//添加全部完成后,通知model重新拉取数据 - LOGDEBUG("AiAlarmDataCollect handleAllAlmMsg():count[%d]",nAlarmCount); - emit sigMsgRefresh(); -} - -void CAiAlarmDataCollect::handleAddAlmMsg(kbd_idlfile::SIntelliAlmAdd &objAddAlm) -{ - LOGINFO("========== AiAlarmDataCollect handleAddAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - //构建告警 - int nAlarmCount = objAddAlm.alm_info_size(); - QList almList; - for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) - { - kbd_idlfile::SIntelliAlmInfo msg = objAddAlm.alm_info(nAddMsgIndex); - AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); - alm->initialize(msg); - alm->priorityOrder = queryPriorityOrder(alm->priority); - almList.append(alm); - } - CAlarmMsgManage::instance()->addAiAlarmMsg(almList); //单独添加的时候,来一条通知一次model添加 - LOGDEBUG("AiAlarmDataCollect handleAddAlmMsg():count[%d]",nAlarmCount); -} - -void CAiAlarmDataCollect::handleDelAlmMsg(kbd_idlfile::SIntelliAlmDel &objDelAlm) -{ - LOGINFO("========== AiAlarmDataCollect handleDelAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - //构建告警 - int nAlarmCount = objDelAlm.uuid_base64_size(); - QList uuidList; - for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) - { - QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); - uuidList.append(uuid); - } - CAlarmMsgManage::instance()->delAiAlarmMsg(uuidList); - LOGDEBUG("AiAlarmDataCollect handleDelAlmMsg():count[%d]",nAlarmCount); -} - -void CAiAlarmDataCollect::handleBrokenAlmMsg(kbd_idlfile::SIntelliAlmBroken &objBrokenAlm) -{ - //先保证能够编译通过 - LOGINFO("========== AiAlarmDataCollect handleBrokenAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - int nAlarmCount = objBrokenAlm.uuid_base64_size(); - QList uuidList; - for(int nBrokenMsgIndex(0); nBrokenMsgIndex < nAlarmCount; nBrokenMsgIndex++) - { - QString uuid = QString::fromStdString(objBrokenAlm.uuid_base64(nBrokenMsgIndex)); - uuidList.append(uuid); - } - CAlarmMsgManage::instance()->brokenAiAlarmMsg(uuidList); - LOGDEBUG("AiAlarmDataCollect handleBrokenAlmMsg():count[%d]",nAlarmCount); -} - -void CAiAlarmDataCollect::handleReleaseAlmMsg(kbd_idlfile::SIntelliAlmRelease &objReleaseAlm) -{ - //先保证能够编译通过 - LOGINFO("========== AiAlarmDataCollect handleReleaseAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - int nAlarmCount = objReleaseAlm.uuid_base64_size(); - QList uuidList; - for(int nReleaseMsgIndex(0); nReleaseMsgIndex < nAlarmCount; nReleaseMsgIndex++) - { - QString uuid = QString::fromStdString(objReleaseAlm.uuid_base64(nReleaseMsgIndex)); - uuidList.append(uuid); - } - CAlarmMsgManage::instance()->releaseAiAlarmMsg(uuidList); - LOGDEBUG("AiAlarmDataCollect handleReleaseAlmMsg():count[%d]",nAlarmCount); -} - -void CAiAlarmDataCollect::destory() -{ - LOGINFO("退出时:CAiAlarmDataCollect::destory()打开窗口的个数m_referenceCount:[%d]",m_referenceCount); - if(--m_referenceCount > 0) - { - return; - } - slotTimerShot(false); - suspendThread(); - { - QMutexLocker locker(m_rtdbMutex); - if(Q_NULLPTR != m_pAlternateTimer) - { - m_pAlternateTimer->stop(); - m_pAlternateTimer->deleteLater(); - } - m_pAlternateTimer = Q_NULLPTR; - } - delete m_rtdbMutex; - delete m_rtdbPriorityOrderAccess; - m_pInstance = NULL; - delete this; -} - -void CAiAlarmDataCollect::slotTimerShot(const bool start) -{ - if(m_pAlternateTimer) - { - if(start) - { - m_pAlternateTimer->start(); - } - else - { - m_pAlternateTimer->stop(); - } - } -} - -void CAiAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) -{ - m_bFaultRecallState = bFaultRecallState; - release(); - m_pInstance->reinit(m_bFaultRecallState); - CAlarmMsgManage::instance()->release(); - //initialize(); -} - -int CAiAlarmDataCollect::queryPriorityOrder(int &id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); - kbd_dbms::CVarType value = -1000; - m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); - return value.toInt(); -} - -void CAiAlarmDataCollect::slotAiAlarmStateChanged() -{ - QMutexLocker locker(m_rtdbMutex); - CAlarmMsgManage::instance()->dealDelayAi(); -} +#include "CAiAlarmDataCollect.h" +#include "pub_logger_api/logger.h" +#include "CAlarmMsgManage.h" +#include +#include "CAlarmDataCollect.h" +using namespace kbd_service; +CAiAlarmDataCollect * CAiAlarmDataCollect::m_pInstance = NULL; +CAiAlarmDataCollect::CAiAlarmDataCollect() + : CIntelliAlmApi4Clt(), + m_referenceCount(0), + m_bFaultRecallState(false), + m_pAlternateTimer(Q_NULLPTR) +{ + m_rtdbMutex = new QMutex(); + m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); +} + +CAiAlarmDataCollect::~CAiAlarmDataCollect() +{ + LOGDEBUG("CAiAlarmDataCollect::~CAiAlarmDataCollect()"); + qDebug() << "~CAiAlarmDataCollect()"; +} + +void CAiAlarmDataCollect::refrence() +{ + m_referenceCount++; +} + +int CAiAlarmDataCollect::getRefrenceCount() +{ + return m_referenceCount; +} + +CAiAlarmDataCollect *CAiAlarmDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAiAlarmDataCollect(); + } + return m_pInstance; +} + +void CAiAlarmDataCollect::initialize() +{ + resumeThread(); + if(!m_pAlternateTimer) + { + m_pAlternateTimer = new QTimer(); + m_pAlternateTimer->setInterval(1000); + connect(m_pAlternateTimer, &QTimer::timeout, this, &CAiAlarmDataCollect::slotAiAlarmStateChanged); + connect(this, &CAiAlarmDataCollect::sigTimerShot, this, &CAiAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); + } + if(!m_bFaultRecallState) + { + emit sigTimerShot(true); + } +} + +void CAiAlarmDataCollect::release() +{ + emit sigTimerShot(false); + suspendThread(true); +} + +bool CAiAlarmDataCollect::isFaultRecallState() +{ + return m_bFaultRecallState; +} + +bool CAiAlarmDataCollect::requestDelAlm(kbd_idlfile::SIntelliAlmDel &objDelAlm) +{ + LOGDEBUG("请求删除!"); + return kbd_service::CIntelliAlmApi4Clt::requestDelAlm(objDelAlm); +} + +bool CAiAlarmDataCollect::requestSeprAlm(kbd_idlfile::SIntelliAlmSepr &objSeprAlm) +{ + LOGDEBUG("请求分离!"); + return kbd_service::CIntelliAlmApi4Clt::requestSeprAlm(objSeprAlm); +} + +bool CAiAlarmDataCollect::requestMergeAlm(kbd_idlfile::SIntelliAlmMerge &objMergeAlm) +{ + LOGDEBUG("请求合并!"); + return kbd_service::CIntelliAlmApi4Clt::requestMergeAlm(objMergeAlm); +} + +void CAiAlarmDataCollect::handleAllAlmMsg(int nDomainId, kbd_idlfile::SIntelliAlmAdd &objAllAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleAllAlmMsg =========="); + + //< 清空该域缓存 + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->removeAiAlarmMsgByDomainID(nDomainId); + //构建告警 + int nAlarmCount = objAllAlm.alm_info_size(); + QList almList; + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + kbd_idlfile::SIntelliAlmInfo msg = objAllAlm.alm_info(nAddMsgIndex); + AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + almList.append(alm); + } + CAlarmMsgManage::instance()->addAiAllAlarmMsg(almList);//添加全部完成后,通知model重新拉取数据 + LOGDEBUG("AiAlarmDataCollect handleAllAlmMsg():count[%d]",nAlarmCount); + emit sigMsgRefresh(); +} + +void CAiAlarmDataCollect::handleAddAlmMsg(kbd_idlfile::SIntelliAlmAdd &objAddAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleAddAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //构建告警 + int nAlarmCount = objAddAlm.alm_info_size(); + QList almList; + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + kbd_idlfile::SIntelliAlmInfo msg = objAddAlm.alm_info(nAddMsgIndex); + AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + almList.append(alm); + } + CAlarmMsgManage::instance()->addAiAlarmMsg(almList); //单独添加的时候,来一条通知一次model添加 + LOGDEBUG("AiAlarmDataCollect handleAddAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::handleDelAlmMsg(kbd_idlfile::SIntelliAlmDel &objDelAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleDelAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //构建告警 + int nAlarmCount = objDelAlm.uuid_base64_size(); + QList uuidList; + for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) + { + QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->delAiAlarmMsg(uuidList); + LOGDEBUG("AiAlarmDataCollect handleDelAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::handleBrokenAlmMsg(kbd_idlfile::SIntelliAlmBroken &objBrokenAlm) +{ + //先保证能够编译通过 + LOGINFO("========== AiAlarmDataCollect handleBrokenAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objBrokenAlm.uuid_base64_size(); + QList uuidList; + for(int nBrokenMsgIndex(0); nBrokenMsgIndex < nAlarmCount; nBrokenMsgIndex++) + { + QString uuid = QString::fromStdString(objBrokenAlm.uuid_base64(nBrokenMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->brokenAiAlarmMsg(uuidList); + LOGDEBUG("AiAlarmDataCollect handleBrokenAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::handleReleaseAlmMsg(kbd_idlfile::SIntelliAlmRelease &objReleaseAlm) +{ + //先保证能够编译通过 + LOGINFO("========== AiAlarmDataCollect handleReleaseAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objReleaseAlm.uuid_base64_size(); + QList uuidList; + for(int nReleaseMsgIndex(0); nReleaseMsgIndex < nAlarmCount; nReleaseMsgIndex++) + { + QString uuid = QString::fromStdString(objReleaseAlm.uuid_base64(nReleaseMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->releaseAiAlarmMsg(uuidList); + LOGDEBUG("AiAlarmDataCollect handleReleaseAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::destory() +{ + LOGINFO("退出时:CAiAlarmDataCollect::destory()打开窗口的个数m_referenceCount:[%d]",m_referenceCount); + if(--m_referenceCount > 0) + { + return; + } + slotTimerShot(false); + suspendThread(); + { + QMutexLocker locker(m_rtdbMutex); + if(Q_NULLPTR != m_pAlternateTimer) + { + m_pAlternateTimer->stop(); + m_pAlternateTimer->deleteLater(); + } + m_pAlternateTimer = Q_NULLPTR; + } + delete m_rtdbMutex; + delete m_rtdbPriorityOrderAccess; + m_pInstance = NULL; + delete this; +} + +void CAiAlarmDataCollect::slotTimerShot(const bool start) +{ + if(m_pAlternateTimer) + { + if(start) + { + m_pAlternateTimer->start(); + } + else + { + m_pAlternateTimer->stop(); + } + } +} + +void CAiAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) +{ + m_bFaultRecallState = bFaultRecallState; + release(); + m_pInstance->reinit(m_bFaultRecallState); + CAlarmMsgManage::instance()->release(); + //initialize(); +} + +int CAiAlarmDataCollect::queryPriorityOrder(int &id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + kbd_dbms::CVarType value = -1000; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +void CAiAlarmDataCollect::slotAiAlarmStateChanged() +{ + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->dealDelayAi(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmDataCollect.h b/product/src/gui/plugin/AlarmWidget/CAiAlarmDataCollect.h index 90f50bfd..4b142cdd 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmDataCollect.h +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmDataCollect.h @@ -1,84 +1,84 @@ -#ifndef CAIALARMDATACOLLECT_H -#define CAIALARMDATACOLLECT_H - -#include -#include -#include -#include -#include -#include "IntelliAlmMsg.pb.h" -#include "CAiAlarmMsgInfo.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "dbms/rdb_api/CRdbAccess.h" - -class CAiAlarmDataCollect : public QObject, public kbd_service::CIntelliAlmApi4Clt -{ - Q_OBJECT -public: - static CAiAlarmDataCollect *instance(); - - virtual ~CAiAlarmDataCollect(); - - void refrence(); - - int getRefrenceCount(); - - bool isFaultRecallState(); - - virtual bool requestDelAlm(kbd_idlfile::SIntelliAlmDel &objDelAlm); - - virtual bool requestSeprAlm(kbd_idlfile::SIntelliAlmSepr &objSeprAlm); - - virtual bool requestMergeAlm(kbd_idlfile::SIntelliAlmMerge &objMergeAlm); - - virtual void handleAllAlmMsg(int nDomainId,kbd_idlfile::SIntelliAlmAdd &objAllAlm); - - virtual void handleAddAlmMsg(kbd_idlfile::SIntelliAlmAdd &objAddAlm); - - virtual void handleDelAlmMsg(kbd_idlfile::SIntelliAlmDel &objDelAlm); - - virtual void handleBrokenAlmMsg(kbd_idlfile::SIntelliAlmBroken &objBrokenAlm); - - virtual void handleReleaseAlmMsg(kbd_idlfile::SIntelliAlmRelease &objReleaseAlm); -signals: - //< 启停定时器 - void sigTimerShot(const bool bStop); - - //< 定时更新,通知model刷新界面 - void sigUpdateAlarmView(); - - //< 通知所有告警插件禁用/使能告警操作 - void sigAlarmOperateEnable(const bool &bEnable); - - //< 通知model重新拉取告警消息 - void sigMsgRefresh(); - - -public slots: - - void initialize(); - - void release(); - - void destory(); - - void slotTimerShot(const bool start); - - void slotSwitchFaultRecallState(bool bFaultRecallState); - -private: - CAiAlarmDataCollect(); - - int queryPriorityOrder(int &id); -private slots: - void slotAiAlarmStateChanged(); -private: - int m_referenceCount; - bool m_bFaultRecallState; - QMutex *m_rtdbMutex; - QTimer * m_pAlternateTimer; - kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; - static CAiAlarmDataCollect * m_pInstance; -}; - -#endif // CAIALARMDATACOLLECT_H +#ifndef CAIALARMDATACOLLECT_H +#define CAIALARMDATACOLLECT_H + +#include +#include +#include +#include +#include +#include "IntelliAlmMsg.pb.h" +#include "CAiAlarmMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" + +class CAiAlarmDataCollect : public QObject, public kbd_service::CIntelliAlmApi4Clt +{ + Q_OBJECT +public: + static CAiAlarmDataCollect *instance(); + + virtual ~CAiAlarmDataCollect(); + + void refrence(); + + int getRefrenceCount(); + + bool isFaultRecallState(); + + virtual bool requestDelAlm(kbd_idlfile::SIntelliAlmDel &objDelAlm); + + virtual bool requestSeprAlm(kbd_idlfile::SIntelliAlmSepr &objSeprAlm); + + virtual bool requestMergeAlm(kbd_idlfile::SIntelliAlmMerge &objMergeAlm); + + virtual void handleAllAlmMsg(int nDomainId,kbd_idlfile::SIntelliAlmAdd &objAllAlm); + + virtual void handleAddAlmMsg(kbd_idlfile::SIntelliAlmAdd &objAddAlm); + + virtual void handleDelAlmMsg(kbd_idlfile::SIntelliAlmDel &objDelAlm); + + virtual void handleBrokenAlmMsg(kbd_idlfile::SIntelliAlmBroken &objBrokenAlm); + + virtual void handleReleaseAlmMsg(kbd_idlfile::SIntelliAlmRelease &objReleaseAlm); +signals: + //< 启停定时器 + void sigTimerShot(const bool bStop); + + //< 定时更新,通知model刷新界面 + void sigUpdateAlarmView(); + + //< 通知所有告警插件禁用/使能告警操作 + void sigAlarmOperateEnable(const bool &bEnable); + + //< 通知model重新拉取告警消息 + void sigMsgRefresh(); + + +public slots: + + void initialize(); + + void release(); + + void destory(); + + void slotTimerShot(const bool start); + + void slotSwitchFaultRecallState(bool bFaultRecallState); + +private: + CAiAlarmDataCollect(); + + int queryPriorityOrder(int &id); +private slots: + void slotAiAlarmStateChanged(); +private: + int m_referenceCount; + bool m_bFaultRecallState; + QMutex *m_rtdbMutex; + QTimer * m_pAlternateTimer; + kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + static CAiAlarmDataCollect * m_pInstance; +}; + +#endif // CAIALARMDATACOLLECT_H diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmDelegate.cpp b/product/src/gui/plugin/AlarmWidget/CAiAlarmDelegate.cpp index a9f6fbfa..cf45ced8 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmDelegate.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmDelegate.cpp @@ -1,408 +1,408 @@ -#include "CAiAlarmDelegate.h" -#include -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/FileStyle.h" -#include "pub_logger_api/logger.h" -#include -#include -#include -#include -#include - -CAiAlarmDelegate::CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent) - : QStyledItemDelegate(parent), - m_pModel(model), - m_enableTrend(true), - m_enableLevel(false), - m_enableVideo(true), - m_enableWave(true), - m_selectIsEmpty(false) -{ - slotLoadConfig(); -} - -void CAiAlarmDelegate::setEnableTrend(bool isNeed) -{ - m_enableTrend = isNeed; -} - -void CAiAlarmDelegate::setEnableLevel(bool isNeed) -{ - m_enableLevel = isNeed; -} - -void CAiAlarmDelegate::setEnableVideo(bool isNeed) -{ - m_enableVideo = isNeed; -} - -void CAiAlarmDelegate::setEnableWave(bool isNeed) -{ - m_enableWave = isNeed; -} - -void CAiAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - if(!index.isValid()) - { - return; - } - CAiAlarmTreeItem *item = m_pModel->getItem(index); - - bool select = option.state & QStyle::State_Selected; - QColor fillColor; - QColor penColor; - if(item->isAi()) - { - AiAlarmMsgPtr aiptr = NULL; - if(item->getAiPtr(aiptr) && aiptr != NULL) - { - painter->save(); - - if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aiptr->uuid_base64)) //包含的原始告警没有全部被确认 - { - if(select) - { - fillColor = m_select_background_color; - if(m_selectIsEmpty) - { - penColor = m_colorMap.value(aiptr->priorityOrder).active_text_color; - }else - { - penColor = m_select_text_color; - } - - } - else - { - if(aiptr->main_state == E_ALS_RETURN || aiptr->main_state == E_ALS_RETURN_CFM - || aiptr->main_state == E_ALS_RETURN_DEL || aiptr->main_state == E_ALS_RETURN_CFM_DEL) - { - penColor = m_colorMap.value(aiptr->priorityOrder).resume_text_color; - }else - { - penColor = m_colorMap.value(aiptr->priorityOrder).active_text_color; - } - - fillColor = m_colorMap.value(aiptr->priorityOrder).background_color; - } - }else //此条智能告警可以删除(置灰) - { - if(select) - { - fillColor = m_select_background_color; - } - else - { - fillColor = m_colorMap.value(aiptr->priorityOrder).confirm_color; - } - penColor = m_colorMap.value(aiptr->priorityOrder).confirm_text_color; - } - painter->setPen(penColor); - painter->fillRect(option.rect, fillColor); - if(m_enableVideo && BUTTON_COLUMN == index.column() && aiptr->m_needVideoAlm) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(m_strVideoPath); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - - if(m_enableLevel && ICON_COLUMN == index.column()) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); - QString file = m_colorMap.value(aiptr->priorityOrder).icon; - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(file); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - - if( m_enableTrend && BUTTON_COLUMN == index.column() && (aiptr->m_tagname_type == E_TAGNAME_ANA || aiptr->m_tagname_type == E_TAGNAME_ACC)) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(m_strTrendPath); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); - painter->restore(); - }else - { - return ; - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) && ptr != NULL) - { - painter->save(); - if(ptr->logic_state == E_ALS_RETURN || ptr->logic_state == E_ALS_RETURN_DEL)//返回未确认 - { - if(select) - { - fillColor = m_select_background_color; - if(m_selectIsEmpty) - { - penColor = m_colorMap.value(ptr->priorityOrder).resume_text_color; - }else - { - penColor = m_select_text_color; - } - } - else - { - penColor = m_colorMap.value(ptr->priorityOrder).resume_text_color; - fillColor = m_colorMap.value(ptr->priorityOrder).background_color; - } - }else if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_ALARM_DEL)//告警未确认 - { - if(select) - { - fillColor = m_select_background_color; - if(m_selectIsEmpty) - { - penColor = m_colorMap.value(ptr->priorityOrder).active_text_color; - }else - { - penColor = m_select_text_color; - } - } - else - { - penColor = m_colorMap.value(ptr->priorityOrder).active_text_color; - fillColor = m_colorMap.value(ptr->priorityOrder).background_color; - } - }else - { - if(select) - { - fillColor = m_select_background_color; - } - else - { - fillColor = m_colorMap.value(ptr->priorityOrder).confirm_color; - } - penColor = m_colorMap.value(ptr->priorityOrder).confirm_text_color; - } - painter->setPen(penColor); - painter->fillRect(option.rect, fillColor); - - if(m_enableVideo && BUTTON_COLUMN == index.column() && ptr->m_needVideoAlm) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(m_strVideoPath); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - - if(m_enableLevel && ICON_COLUMN == index.column()) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); - QString file = m_colorMap.value(ptr->priorityOrder).icon; - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(file); - button.features = QStyleOptionButton::Flat; - - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - - if( m_enableTrend && BUTTON_COLUMN == index.column() && (ptr->m_tagname_type == E_TAGNAME_ANA || ptr->m_tagname_type == E_TAGNAME_ACC)) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(m_strTrendPath); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - - if( m_enableWave && BUTTON_COLUMN == index.column() && !ptr->wave_file.isEmpty()) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40 -40 -40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(m_strWavePath); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - - painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); - painter->restore(); - }else - { - return ; - } - } -} - -bool CAiAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - if(!index.isValid()) - { - return false; - } - if(index.column() != BUTTON_COLUMN) - { - return false; - } - QMouseEvent *mouseEvent = static_cast(event); - CAiAlarmTreeItem *item = m_pModel->getItem(index); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) && ptr != NULL) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - if(m_enableVideo && ptr->m_needVideoAlm) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - QString pointTag = ptr->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); - } - } - if( m_enableTrend && (ptr->m_tagname_type == E_TAGNAME_ACC || ptr->m_tagname_type == E_TAGNAME_ANA)) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); - QRect rect = button.rect; - - if(rect.contains(mouseEvent->pos())) - { - QStringList trendList; - trendList.append(ptr->key_id_tag); - emit openTrend(ptr->time_stamp,trendList); - } - } - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) && ptr != NULL) - { - if(m_enableVideo && ptr->m_needVideoAlm) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); - QRect rect = button.rect; - QString pointTag = ptr->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - if(rect.contains(mouseEvent->pos())) - { - QString pointTag = ptr->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); - } - } - } - if(m_enableTrend && (ptr->m_tagname_type == E_TAGNAME_ACC || ptr->m_tagname_type == E_TAGNAME_ANA)) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - QStringList trendList; - trendList.append(ptr->key_id_tag); - emit openTrend(ptr->time_stamp,trendList); - } - } - } - if(m_enableWave && !ptr->wave_file.isEmpty()) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - QString wave = ptr->wave_file; - wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); - LOGINFO("录波文件为:%s",wave.toStdString().c_str()); - - const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( - std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); - if(strProc.empty()) - LOGERROR("未找到可执行文件WaveAnalyze"); - else - QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); - } - } - } - } - } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} - -void CAiAlarmDelegate::slotLoadConfig() -{ - CAlarmSetMng::instance()->getColorMap(m_colorMap); - CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); - CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); - //CAlarmColorMng::instance()->getActAndFunc(m_act,m_func); - - std::string style = kbd_public::CFileStyle::getCurStyle(); - m_strTrendPath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/trend_"+style+".png").c_str(); - m_strVideoPath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video_"+style+".png").c_str(); - m_strWavePath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); -} +#include "CAiAlarmDelegate.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include +#include + +CAiAlarmDelegate::CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(model), + m_enableTrend(true), + m_enableLevel(false), + m_enableVideo(true), + m_enableWave(true), + m_selectIsEmpty(false) +{ + slotLoadConfig(); +} + +void CAiAlarmDelegate::setEnableTrend(bool isNeed) +{ + m_enableTrend = isNeed; +} + +void CAiAlarmDelegate::setEnableLevel(bool isNeed) +{ + m_enableLevel = isNeed; +} + +void CAiAlarmDelegate::setEnableVideo(bool isNeed) +{ + m_enableVideo = isNeed; +} + +void CAiAlarmDelegate::setEnableWave(bool isNeed) +{ + m_enableWave = isNeed; +} + +void CAiAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + CAiAlarmTreeItem *item = m_pModel->getItem(index); + + bool select = option.state & QStyle::State_Selected; + QColor fillColor; + QColor penColor; + if(item->isAi()) + { + AiAlarmMsgPtr aiptr = NULL; + if(item->getAiPtr(aiptr) && aiptr != NULL) + { + painter->save(); + + if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aiptr->uuid_base64)) //包含的原始告警没有全部被确认 + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(aiptr->priorityOrder).active_text_color; + }else + { + penColor = m_select_text_color; + } + + } + else + { + if(aiptr->main_state == E_ALS_RETURN || aiptr->main_state == E_ALS_RETURN_CFM + || aiptr->main_state == E_ALS_RETURN_DEL || aiptr->main_state == E_ALS_RETURN_CFM_DEL) + { + penColor = m_colorMap.value(aiptr->priorityOrder).resume_text_color; + }else + { + penColor = m_colorMap.value(aiptr->priorityOrder).active_text_color; + } + + fillColor = m_colorMap.value(aiptr->priorityOrder).background_color; + } + }else //此条智能告警可以删除(置灰) + { + if(select) + { + fillColor = m_select_background_color; + } + else + { + fillColor = m_colorMap.value(aiptr->priorityOrder).confirm_color; + } + penColor = m_colorMap.value(aiptr->priorityOrder).confirm_text_color; + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + if(m_enableVideo && BUTTON_COLUMN == index.column() && aiptr->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strVideoPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if(m_enableLevel && ICON_COLUMN == index.column()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); + QString file = m_colorMap.value(aiptr->priorityOrder).icon; + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if( m_enableTrend && BUTTON_COLUMN == index.column() && (aiptr->m_tagname_type == E_TAGNAME_ANA || aiptr->m_tagname_type == E_TAGNAME_ACC)) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strTrendPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + }else + { + return ; + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + painter->save(); + if(ptr->logic_state == E_ALS_RETURN || ptr->logic_state == E_ALS_RETURN_DEL)//返回未确认 + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(ptr->priorityOrder).resume_text_color; + }else + { + penColor = m_select_text_color; + } + } + else + { + penColor = m_colorMap.value(ptr->priorityOrder).resume_text_color; + fillColor = m_colorMap.value(ptr->priorityOrder).background_color; + } + }else if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_ALARM_DEL)//告警未确认 + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(ptr->priorityOrder).active_text_color; + }else + { + penColor = m_select_text_color; + } + } + else + { + penColor = m_colorMap.value(ptr->priorityOrder).active_text_color; + fillColor = m_colorMap.value(ptr->priorityOrder).background_color; + } + }else + { + if(select) + { + fillColor = m_select_background_color; + } + else + { + fillColor = m_colorMap.value(ptr->priorityOrder).confirm_color; + } + penColor = m_colorMap.value(ptr->priorityOrder).confirm_text_color; + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + + if(m_enableVideo && BUTTON_COLUMN == index.column() && ptr->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strVideoPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if(m_enableLevel && ICON_COLUMN == index.column()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); + QString file = m_colorMap.value(ptr->priorityOrder).icon; + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if( m_enableTrend && BUTTON_COLUMN == index.column() && (ptr->m_tagname_type == E_TAGNAME_ANA || ptr->m_tagname_type == E_TAGNAME_ACC)) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strTrendPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if( m_enableWave && BUTTON_COLUMN == index.column() && !ptr->wave_file.isEmpty()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40 -40 -40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strWavePath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + }else + { + return ; + } + } +} + +bool CAiAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(index.column() != BUTTON_COLUMN) + { + return false; + } + QMouseEvent *mouseEvent = static_cast(event); + CAiAlarmTreeItem *item = m_pModel->getItem(index); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) && ptr != NULL) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + if(m_enableVideo && ptr->m_needVideoAlm) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); + } + } + if( m_enableTrend && (ptr->m_tagname_type == E_TAGNAME_ACC || ptr->m_tagname_type == E_TAGNAME_ANA)) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); + QRect rect = button.rect; + + if(rect.contains(mouseEvent->pos())) + { + QStringList trendList; + trendList.append(ptr->key_id_tag); + emit openTrend(ptr->time_stamp,trendList); + } + } + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + if(m_enableVideo && ptr->m_needVideoAlm) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + if(rect.contains(mouseEvent->pos())) + { + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); + } + } + } + if(m_enableTrend && (ptr->m_tagname_type == E_TAGNAME_ACC || ptr->m_tagname_type == E_TAGNAME_ANA)) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QStringList trendList; + trendList.append(ptr->key_id_tag); + emit openTrend(ptr->time_stamp,trendList); + } + } + } + if(m_enableWave && !ptr->wave_file.isEmpty()) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString wave = ptr->wave_file; + wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); + LOGINFO("录波文件为:%s",wave.toStdString().c_str()); + + const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); + } + } + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +void CAiAlarmDelegate::slotLoadConfig() +{ + CAlarmSetMng::instance()->getColorMap(m_colorMap); + CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); + CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); + //CAlarmColorMng::instance()->getActAndFunc(m_act,m_func); + + std::string style = kbd_public::CFileStyle::getCurStyle(); + m_strTrendPath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/trend_"+style+".png").c_str(); + m_strVideoPath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video_"+style+".png").c_str(); + m_strWavePath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmDelegate.h b/product/src/gui/plugin/AlarmWidget/CAiAlarmDelegate.h index d615d109..2aba53c1 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmDelegate.h +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmDelegate.h @@ -1,50 +1,50 @@ -#ifndef CAIALARMDELEGATE_H -#define CAIALARMDELEGATE_H - -#include -#include -#include "CAiAlarmTreeModel.h" -#include "CAlarmSetMng.h" - -class CAiAlarmDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent = 0); - void setEnableTrend(bool isNeed); - void setEnableLevel(bool isNeed); - void setEnableVideo(bool isNeed); - void setEnableWave(bool isNeed); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); -signals: - void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); - void openTrend(quint64 time_stamp,QStringList tagList); - -public slots: - void slotLoadConfig(); - -private: - CAiAlarmTreeModel *m_pModel; - - bool m_enableTrend; - bool m_enableLevel; - bool m_enableVideo; - bool m_enableWave; - - QMap m_colorMap; - QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 - bool m_selectIsEmpty; - - QColor m_emptyBackgroundColor,m_emptyTipColor; - QString m_emptyTip; - int m_act; - int m_func; - - QString m_strWavePath; - QString m_strVideoPath; - QString m_strTrendPath; -}; - -#endif // CAIALARMDELEGATE_H +#ifndef CAIALARMDELEGATE_H +#define CAIALARMDELEGATE_H + +#include +#include +#include "CAiAlarmTreeModel.h" +#include "CAlarmSetMng.h" + +class CAiAlarmDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent = 0); + void setEnableTrend(bool isNeed); + void setEnableLevel(bool isNeed); + void setEnableVideo(bool isNeed); + void setEnableWave(bool isNeed); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); +signals: + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + void openTrend(quint64 time_stamp,QStringList tagList); + +public slots: + void slotLoadConfig(); + +private: + CAiAlarmTreeModel *m_pModel; + + bool m_enableTrend; + bool m_enableLevel; + bool m_enableVideo; + bool m_enableWave; + + QMap m_colorMap; + QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 + bool m_selectIsEmpty; + + QColor m_emptyBackgroundColor,m_emptyTipColor; + QString m_emptyTip; + int m_act; + int m_func; + + QString m_strWavePath; + QString m_strVideoPath; + QString m_strTrendPath; +}; + +#endif // CAIALARMDELEGATE_H diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmMsgInfo.cpp b/product/src/gui/plugin/AlarmWidget/CAiAlarmMsgInfo.cpp index 6e31cbbe..1d7e14ec 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmMsgInfo.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmMsgInfo.cpp @@ -1,466 +1,466 @@ -#include "CAiAlarmMsgInfo.h" -#include -#include "CAlarmDataCollect.h" -#include - -CAiAlarmMsgInfo::CAiAlarmMsgInfo() -{ - logic_state = E_AiALM_IALS_NORMAL; - main_state = E_ALS_BAD; - domain_id = -1; - priority = -1; - time_stamp = 1000; - - uuid_base64 = QString(); - content = QString(); - disposal_plan = QString(); - raw_alm_uuid.clear(); - - priorityOrder = -1; - deleteFlag = false; - brokenFlag = false; - releaseFlag = false; - m_needVideoAlm =false; - app_id = -1; - main_uuid_base64 = QString(); - key_id_tag = QString(); - m_tagname_type = E_TAGNAME_ERROR; -} - -CAiAlarmMsgInfo::CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other): priority(0) -{ - logic_state = other.logic_state; - main_state = other.main_state; - domain_id = other.domain_id; - time_stamp = other.time_stamp; - - uuid_base64 = other.uuid_base64; - content = other.content; - disposal_plan = other.disposal_plan; - raw_alm_uuid = other.raw_alm_uuid; - - priorityOrder = other.priorityOrder; - deleteFlag = other.deleteFlag; - brokenFlag = other.brokenFlag; - releaseFlag = other.releaseFlag; - - m_needVideoAlm = other.m_needVideoAlm; - app_id = other.app_id; - main_uuid_base64 = other.main_uuid_base64; - key_id_tag = other.key_id_tag; - m_tagname_type = other.m_tagname_type; -} - -void CAiAlarmMsgInfo::initialize(const kbd_idlfile::SIntelliAlmInfo &alarmInfo) -{ - - logic_state = (E_AiALARM_LOGICSTATE)alarmInfo.logic_state(); - domain_id = alarmInfo.domain_id(); - priority = alarmInfo.priority(); - time_stamp = alarmInfo.time_stamp(); - - uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); - content = QString::fromStdString(alarmInfo.content()); - disposal_plan = QString::fromStdString(alarmInfo.disposal_plan()); - raw_alm_uuid.clear(); //< 关联的原始告警uuid - for(int x(0); x < alarmInfo.raw_alm_uuid_size(); x++) - { - if(x == 0) - { - main_uuid_base64 = QString::fromStdString(alarmInfo.raw_alm_uuid(x)); - } - raw_alm_uuid.append(QString::fromStdString(alarmInfo.raw_alm_uuid(x))); - } - - priorityOrder = -1; - if(logic_state == E_AIALM_IALS_DELETED) - { - deleteFlag = true; - }else - { - deleteFlag = false; - } - if(logic_state == E_AIALM_IALS_BROKEN) - { - brokenFlag = true; - }else - { - brokenFlag = false; - } - releaseFlag = false; - m_needVideoAlm =false; -} - -bool CAiAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priorityOrder > info->priorityOrder) - { - return true; - }else if(priorityOrder < info->priorityOrder) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp < info->time_stamp) - { - return true; - }else if(time_stamp > info->time_stamp) - { - return false; - }else - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return false; - break; - case E_SORT_REGION: - return false; - break; - case E_SORT_TYPE: - return false; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return false; - case E_SORT_ALM_STATE: - return false; - break; - case E_SORT_STYLE: - return false; - break; - default: - break; - } - return false; -} - -bool CAiAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priorityOrder < info->priorityOrder) - { - return true; - }else if(priorityOrder > info->priorityOrder) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_TIME: - if(time_stamp > info->time_stamp) - { - return true; - }else if(time_stamp < info->time_stamp) - { - return false; - }else - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return true; - break; - case E_SORT_REGION: - return true; - break; - case E_SORT_TYPE: - return true; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content < info->content) - { - return false; - } - else if(content > info->content) - { - return true; - } - else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_LOGICSTATE: - return true; - break; - case E_SORT_ALM_STATE: - return true; - break; - case E_SORT_STYLE: - return true; - break; - default: - break; - } - return false; -} -//< 智能告警-前者小[不包含的字段进行比较排序] -bool CAiAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priorityOrder > info->priorityOrder) - { - return true; - }else if(priorityOrder < info->priorityOrder) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp < info->time_stamp) - { - return true; - }else if(time_stamp > info->time_stamp) - { - return false; - }else - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return true; - break; - case E_SORT_REGION: - return true; - break; - case E_SORT_TYPE: - return true; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return true; - case E_SORT_ALM_STATE: - return true; - break; - case E_SORT_STYLE: - return true; - break; - default: - break; - } - return false; -} - -bool CAiAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priorityOrder < info->priorityOrder) - { - return true; - }else if(priorityOrder > info->priorityOrder) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_TIME: - if(time_stamp > info->time_stamp) - { - return true; - }else if(time_stamp < info->time_stamp) - { - return false; - }else - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return false; - break; - case E_SORT_REGION: - return false; - break; - case E_SORT_TYPE: - return false; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content < info->content) - { - return false; - } - else if(content > info->content) - { - return true; - } - else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_LOGICSTATE: - return false; - break; - case E_SORT_ALM_STATE: - return false; - break; - case E_SORT_STYLE: - return false; - break; - default: - break; - } - return false; -} - -bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target) -{ - if(source.uuid_base64 == target.uuid_base64) - { - return true; - } - return false; -// //替换式告警且车站、测点ID相同 -// if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) -// { -// return true; -// } -// //流水账告警且时标、告警内容相同 -// else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) -// { -// return true; -// } -// return false; -} +#include "CAiAlarmMsgInfo.h" +#include +#include "CAlarmDataCollect.h" +#include + +CAiAlarmMsgInfo::CAiAlarmMsgInfo() +{ + logic_state = E_AiALM_IALS_NORMAL; + main_state = E_ALS_BAD; + domain_id = -1; + priority = -1; + time_stamp = 1000; + + uuid_base64 = QString(); + content = QString(); + disposal_plan = QString(); + raw_alm_uuid.clear(); + + priorityOrder = -1; + deleteFlag = false; + brokenFlag = false; + releaseFlag = false; + m_needVideoAlm =false; + app_id = -1; + main_uuid_base64 = QString(); + key_id_tag = QString(); + m_tagname_type = E_TAGNAME_ERROR; +} + +CAiAlarmMsgInfo::CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other): priority(0) +{ + logic_state = other.logic_state; + main_state = other.main_state; + domain_id = other.domain_id; + time_stamp = other.time_stamp; + + uuid_base64 = other.uuid_base64; + content = other.content; + disposal_plan = other.disposal_plan; + raw_alm_uuid = other.raw_alm_uuid; + + priorityOrder = other.priorityOrder; + deleteFlag = other.deleteFlag; + brokenFlag = other.brokenFlag; + releaseFlag = other.releaseFlag; + + m_needVideoAlm = other.m_needVideoAlm; + app_id = other.app_id; + main_uuid_base64 = other.main_uuid_base64; + key_id_tag = other.key_id_tag; + m_tagname_type = other.m_tagname_type; +} + +void CAiAlarmMsgInfo::initialize(const kbd_idlfile::SIntelliAlmInfo &alarmInfo) +{ + + logic_state = (E_AiALARM_LOGICSTATE)alarmInfo.logic_state(); + domain_id = alarmInfo.domain_id(); + priority = alarmInfo.priority(); + time_stamp = alarmInfo.time_stamp(); + + uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); + content = QString::fromStdString(alarmInfo.content()); + disposal_plan = QString::fromStdString(alarmInfo.disposal_plan()); + raw_alm_uuid.clear(); //< 关联的原始告警uuid + for(int x(0); x < alarmInfo.raw_alm_uuid_size(); x++) + { + if(x == 0) + { + main_uuid_base64 = QString::fromStdString(alarmInfo.raw_alm_uuid(x)); + } + raw_alm_uuid.append(QString::fromStdString(alarmInfo.raw_alm_uuid(x))); + } + + priorityOrder = -1; + if(logic_state == E_AIALM_IALS_DELETED) + { + deleteFlag = true; + }else + { + deleteFlag = false; + } + if(logic_state == E_AIALM_IALS_BROKEN) + { + brokenFlag = true; + }else + { + brokenFlag = false; + } + releaseFlag = false; + m_needVideoAlm =false; +} + +bool CAiAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder > info->priorityOrder) + { + return true; + }else if(priorityOrder < info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return false; + case E_SORT_ALM_STATE: + return false; + break; + case E_SORT_STYLE: + return false; + break; + default: + break; + } + return false; +} + +bool CAiAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder < info->priorityOrder) + { + return true; + }else if(priorityOrder > info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content > info->content) + { + return true; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_LOGICSTATE: + return true; + break; + case E_SORT_ALM_STATE: + return true; + break; + case E_SORT_STYLE: + return true; + break; + default: + break; + } + return false; +} +//< 智能告警-前者小[不包含的字段进行比较排序] +bool CAiAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder > info->priorityOrder) + { + return true; + }else if(priorityOrder < info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return true; + case E_SORT_ALM_STATE: + return true; + break; + case E_SORT_STYLE: + return true; + break; + default: + break; + } + return false; +} + +bool CAiAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder < info->priorityOrder) + { + return true; + }else if(priorityOrder > info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content > info->content) + { + return true; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_LOGICSTATE: + return false; + break; + case E_SORT_ALM_STATE: + return false; + break; + case E_SORT_STYLE: + return false; + break; + default: + break; + } + return false; +} + +bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target) +{ + if(source.uuid_base64 == target.uuid_base64) + { + return true; + } + return false; +// //替换式告警且车站、测点ID相同 +// if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) +// { +// return true; +// } +// //流水账告警且时标、告警内容相同 +// else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) +// { +// return true; +// } +// return false; +} diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmMsgInfo.h b/product/src/gui/plugin/AlarmWidget/CAiAlarmMsgInfo.h index 4d1910fb..3ce35b9f 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmMsgInfo.h +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmMsgInfo.h @@ -1,60 +1,60 @@ -#ifndef CAIALARMMSGINFO_H -#define CAIALARMMSGINFO_H - - -#include -#include -#include -#include "intelli_alm_api/CIntelliAlmApi4Clt.h" -#include -#include -#include -#include -enum E_AiALARM_LOGICSTATE -{ - E_AiALM_IALS_NORMAL = 1, //正常 - E_AIALM_IALS_DELETED = 2, //已删除 - E_AIALM_IALS_BROKEN = 3, //不完整的 -}; -class CAiAlarmMsgInfo -{ -public: - CAiAlarmMsgInfo(); - CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other); - void initialize(const kbd_idlfile::SIntelliAlmInfo &alarmInfo); - - //< [优先级越小表示越大]-智能告警窗调用 - bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - E_AiALARM_LOGICSTATE logic_state; //< 状态 - E_ALARM_LOGICSTATE main_state; //< 主告警逻辑状态 - qint32 domain_id; //< 域ID - qint32 priority; //< 告警优先级id - quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) - QString uuid_base64; //< uuid 主键 - QString content; //< 告警内容 - QString disposal_plan; //< 处置预案 - QVector raw_alm_uuid; //< 关联的原始告警uuid - //< Extend - qint32 priorityOrder; //< 优先级 - bool deleteFlag; //< 是否被删除 - bool brokenFlag; //< 是否不完整 - bool releaseFlag; //< 是否被释放 - //和主原始告警相关 - bool m_needVideoAlm; //是否需要视频告警 - qint32 app_id; //主原始告警应用id - QString main_uuid_base64; //主原始告警uuid - QString key_id_tag; //主原始告警标签 - E_TAGNAME_TYPE m_tagname_type; -}; - -bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target); - -Q_DECLARE_METATYPE(CAiAlarmMsgInfo) -Q_DECLARE_METATYPE(AiAlarmMsgPtr) - -#endif // CAIALARMMSGINFO_H +#ifndef CAIALARMMSGINFO_H +#define CAIALARMMSGINFO_H + + +#include +#include +#include +#include "intelli_alm_api/CIntelliAlmApi4Clt.h" +#include +#include +#include +#include +enum E_AiALARM_LOGICSTATE +{ + E_AiALM_IALS_NORMAL = 1, //正常 + E_AIALM_IALS_DELETED = 2, //已删除 + E_AIALM_IALS_BROKEN = 3, //不完整的 +}; +class CAiAlarmMsgInfo +{ +public: + CAiAlarmMsgInfo(); + CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other); + void initialize(const kbd_idlfile::SIntelliAlmInfo &alarmInfo); + + //< [优先级越小表示越大]-智能告警窗调用 + bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + E_AiALARM_LOGICSTATE logic_state; //< 状态 + E_ALARM_LOGICSTATE main_state; //< 主告警逻辑状态 + qint32 domain_id; //< 域ID + qint32 priority; //< 告警优先级id + quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) + QString uuid_base64; //< uuid 主键 + QString content; //< 告警内容 + QString disposal_plan; //< 处置预案 + QVector raw_alm_uuid; //< 关联的原始告警uuid + //< Extend + qint32 priorityOrder; //< 优先级 + bool deleteFlag; //< 是否被删除 + bool brokenFlag; //< 是否不完整 + bool releaseFlag; //< 是否被释放 + //和主原始告警相关 + bool m_needVideoAlm; //是否需要视频告警 + qint32 app_id; //主原始告警应用id + QString main_uuid_base64; //主原始告警uuid + QString key_id_tag; //主原始告警标签 + E_TAGNAME_TYPE m_tagname_type; +}; + +bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target); + +Q_DECLARE_METATYPE(CAiAlarmMsgInfo) +Q_DECLARE_METATYPE(AiAlarmMsgPtr) + +#endif // CAIALARMMSGINFO_H diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeItem.cpp b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeItem.cpp index 2b2c8570..27812968 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeItem.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeItem.cpp @@ -1,416 +1,416 @@ -#include "CAiAlarmTreeItem.h" -#include "CAiAlarmMsgInfo.h" -#include "CAlarmMsgInfo.h" -#include "CAlarmCommon.h" -#include "pub_logger_api/logger.h" -#include -#include -#include "CAlarmBaseData.h" -CAiAlarmTreeItem::CAiAlarmTreeItem(const QVector &data, CAiAlarmTreeItem *parent) - : m_uuid(QString()), - m_bIsAi(false), - m_parent(parent), - m_data(data), - m_alarmPtr(NULL), - m_aialarmPtr(NULL) -{ - -} - -CAiAlarmTreeItem::~CAiAlarmTreeItem() -{ - qDeleteAll(m_child); - m_child.clear(); -} - -CAiAlarmTreeItem *CAiAlarmTreeItem::child(int row) -{ - return m_child.at(row); -} - -CAiAlarmTreeItem *CAiAlarmTreeItem::parent() -{ - return m_parent; -} - -int CAiAlarmTreeItem::childCount() const -{ - return m_child.count(); -} - -int CAiAlarmTreeItem::columnCount() const -{ - return m_data.count(); -} - -int CAiAlarmTreeItem::childNumber() const -{ - if(m_parent) - { - return m_parent->m_child.indexOf(const_cast(this)); - } - return 0; -} - -QVariant CAiAlarmTreeItem::data(int column, int role) -{ - if(E_DisplayRole == role) - { - if(m_bIsAi == true) - { - return aigetDataByColumn(column); - }else - { - return getDataByColumn(column); - } - } - else - { - return QVariant(); - } -} - -bool CAiAlarmTreeItem::setData(int column, const QVariant &value, int role) -{ - Q_UNUSED(role) - Q_UNUSED(value) - if (column < 0 || column >= m_data.size()) - return false; - return true; -} - -bool CAiAlarmTreeItem::setPtr(AlarmMsgPtr ptr) -{ - m_alarmPtr = ptr; - m_bIsAi = false; - m_uuid = ptr->uuid_base64; - return true; -} - -bool CAiAlarmTreeItem::setAiPtr(AiAlarmMsgPtr aiPtr) -{ - m_aialarmPtr = aiPtr; - m_bIsAi = true; - m_uuid = aiPtr->uuid_base64; - return true; -} - -bool CAiAlarmTreeItem::insertChildren(int position, int count, int columns) -{ - if (position < 0 || position > m_child.size()) - return false; - - for (int row = 0; row < count; ++row) { - QVector data(columns); - CAiAlarmTreeItem *item = new CAiAlarmTreeItem(data, this); - m_child.insert(position, item); - } - - return true; -} - -bool CAiAlarmTreeItem::removeChildren(int position, int count, int columns) -{ - Q_UNUSED(columns) - if (position < 0 || position + count > m_child.size()) - return false; - - for (int row = 0; row < count; ++row) - delete m_child.takeAt(position); - - return true; -} - -bool CAiAlarmTreeItem::isAi() -{ - return m_bIsAi; -} - -AlarmMsgPtr CAiAlarmTreeItem::ptr() -{ - if(m_alarmPtr == NULL) - return NULL; - else - return m_alarmPtr; -} - -bool CAiAlarmTreeItem::getPtr(AlarmMsgPtr &ptr) -{ - if(!m_bIsAi &&m_alarmPtr != NULL) - { - ptr = m_alarmPtr; - return true; - } - else - { - ptr = NULL; - return false; - } -} - -bool CAiAlarmTreeItem::getAiPtr(AiAlarmMsgPtr &aiPtr) -{ - if(m_bIsAi &&m_aialarmPtr != NULL) - { - aiPtr = m_aialarmPtr; - return true; - } - else - { - aiPtr = NULL; - return false; - } -} - -QList CAiAlarmTreeItem::getChildAlarmPtr() -{ - QList ptrList; - foreach (CAiAlarmTreeItem* item, m_child) { - if(item->ptr() != NULL) - { - ptrList.append(item->ptr()); - } - } - return ptrList; -} - -int CAiAlarmTreeItem::index(const QString uuid) -{ - for(int index(0);indexm_uuid == uuid) - { - return index; - } - } - return -1; -} - -bool CAiAlarmTreeItem::lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) -{ - AiAlarmMsgPtr aiptr = NULL; - AlarmMsgPtr ptr= NULL; - if(m_bIsAi) - { - if(info->isAi()) - { - if(info->getAiPtr(aiptr) && aiptr != NULL) - return m_aialarmPtr->ailessThan(aiptr,sortkey); - }else - { - if(info->getPtr(ptr) && ptr != NULL) - return m_aialarmPtr->ailessThan(ptr,sortkey); - } - - }else - { - if(info->isAi()) - { - if(info->getAiPtr(aiptr) && aiptr != NULL) - return m_alarmPtr->ailessThan(aiptr,sortkey); - }else - { - if(info->getPtr(ptr) && ptr != NULL) - return m_alarmPtr->ailessThan(ptr,sortkey); - } - } - LOGERROR("lessThan():比较大小出错!"); - return false; -} - -bool CAiAlarmTreeItem::moreThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) -{ - AiAlarmMsgPtr aiptr = NULL; - AlarmMsgPtr ptr= NULL; - if(m_bIsAi) - { - if(info->isAi()) - { - if(info->getAiPtr(aiptr) && aiptr != NULL) - return m_aialarmPtr->aimoreThan(aiptr,sortkey); - }else - { - if(info->getPtr(ptr) && ptr != NULL) - return m_aialarmPtr->aimoreThan(ptr,sortkey); - } - }else - { - if(info->isAi()) - { - if(info->getAiPtr(aiptr) && aiptr != NULL) - return m_alarmPtr->aimoreThan(aiptr,sortkey); - }else - { - if(info->getPtr(ptr) && ptr != NULL) - return m_alarmPtr->aimoreThan(ptr,sortkey); - } - } - LOGERROR("moreThan():比较大小出错!"); - return false; -} - -QList CAiAlarmTreeItem::getChild() -{ - return m_child; -} - -void CAiAlarmTreeItem::setChild(QList itemList) -{ - m_child.clear(); - m_child = itemList; -} - -QList CAiAlarmTreeItem::getChildItemList() -{ - return m_child; -} - -QVector CAiAlarmTreeItem::getContent() -{ - QVector vec; - for(int index(0);indextime_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); - return m_data[0]; - case PRIORITY: - m_data[1] = CAlarmBaseData::instance()->queryPriorityDesc(m_aialarmPtr->priority); - return m_data[1]; - case LOCATION: - m_data[2] = CAlarmMsgManage::instance()->queryLocationDesc(m_aialarmPtr->uuid_base64); - return m_data[2]; - case REGION: - m_data[3] ="-"; - return m_data[3]; - case TYPE: - m_data[4] ="-"; - return "-"; - case STATUS: - m_data[5] ="-"; - return "-"; - case RETURNSTATUS: - m_data[6] ="-"; - return "-"; - case CONFIRM: - m_data[7] = QString("%1/%2").arg(getConfirm()).arg(m_child.size()); - return m_data[7]; - case CONTENT: - m_data[8] = m_aialarmPtr->content; - return m_data[8]; - default: - break; - } - } - return QVariant(); -} - -QVariant CAiAlarmTreeItem::getDataByColumn(int column) -{ - if(m_alarmPtr != NULL) - { - switch (column) { - case TIME: - { - m_data[0] = QDateTime::fromMSecsSinceEpoch(m_alarmPtr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); - return m_data[0]; - } - case PRIORITY: - { - m_data[1] = CAlarmBaseData::instance()->queryPriorityDesc(m_alarmPtr->priority); - return m_data[1]; - } - case LOCATION: - { - m_data[2] = CAlarmBaseData::instance()->queryLocationDesc(m_alarmPtr->location_id); - return m_data[2]; - } - case REGION: - { - m_data[3] = CAlarmBaseData::instance()->queryRegionDesc(m_alarmPtr->region_id); - return m_data[3]; - } - case TYPE: - { - m_data[4] = CAlarmBaseData::instance()->queryAlarmTypeDesc(m_alarmPtr->alm_type); - return m_data[4]; - } - case STATUS: - { - m_data[5] = CAlarmBaseData::instance()->queryAlarmStatusDesc(m_alarmPtr->alm_status); - return m_data[5]; - } - case RETURNSTATUS: - { - if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_ALARM_CFM == m_alarmPtr->logic_state || - E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_ALARM_CFM_DEL == m_alarmPtr->logic_state) //未复归 - { - m_data[6] = QObject::tr("未复归"); - return m_data[6]; - } - else if(E_ALS_RETURN == m_alarmPtr->logic_state || E_ALS_RETURN_CFM == m_alarmPtr->logic_state || - E_ALS_RETURN_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_CFM_DEL == m_alarmPtr->logic_state) - { - m_data[6] = QObject::tr("已复归"); - return m_data[6]; - }else - { - m_data[6] = QObject::tr("-"); - return m_data[6]; - } - } - case CONFIRM: - { - if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_RETURN == m_alarmPtr->logic_state - || E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_DEL == m_alarmPtr->logic_state) //< 未确认 - { - m_data[7] = QObject::tr("未确认"); - return m_data[7]; - } - else if(E_ALS_ALARM_CFM == m_alarmPtr->logic_state || E_ALS_RETURN_CFM == m_alarmPtr->logic_state || - E_ALS_ALARM_CFM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_CFM_DEL == m_alarmPtr->logic_state || - ALS_EVT_ONLY == m_alarmPtr->logic_state) - { - m_data[7] = QObject::tr("已确认"); - return m_data[7]; - } - } - case CONTENT: - { - m_data[8] = m_alarmPtr->content; - return m_data[8]; - } - default: - break; - } - } - return QVariant(); -} - -int CAiAlarmTreeItem::getConfirm() -{ - int size = 0; - QList::iterator it = m_child.begin(); - while (it != m_child.end()) { - AlarmMsgPtr ptr; - if((*it)->getPtr(ptr)) - { - if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM - || ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) - { - size++; - } - } - it++; - } - return size; -} +#include "CAiAlarmTreeItem.h" +#include "CAiAlarmMsgInfo.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmCommon.h" +#include "pub_logger_api/logger.h" +#include +#include +#include "CAlarmBaseData.h" +CAiAlarmTreeItem::CAiAlarmTreeItem(const QVector &data, CAiAlarmTreeItem *parent) + : m_uuid(QString()), + m_bIsAi(false), + m_parent(parent), + m_data(data), + m_alarmPtr(NULL), + m_aialarmPtr(NULL) +{ + +} + +CAiAlarmTreeItem::~CAiAlarmTreeItem() +{ + qDeleteAll(m_child); + m_child.clear(); +} + +CAiAlarmTreeItem *CAiAlarmTreeItem::child(int row) +{ + return m_child.at(row); +} + +CAiAlarmTreeItem *CAiAlarmTreeItem::parent() +{ + return m_parent; +} + +int CAiAlarmTreeItem::childCount() const +{ + return m_child.count(); +} + +int CAiAlarmTreeItem::columnCount() const +{ + return m_data.count(); +} + +int CAiAlarmTreeItem::childNumber() const +{ + if(m_parent) + { + return m_parent->m_child.indexOf(const_cast(this)); + } + return 0; +} + +QVariant CAiAlarmTreeItem::data(int column, int role) +{ + if(E_DisplayRole == role) + { + if(m_bIsAi == true) + { + return aigetDataByColumn(column); + }else + { + return getDataByColumn(column); + } + } + else + { + return QVariant(); + } +} + +bool CAiAlarmTreeItem::setData(int column, const QVariant &value, int role) +{ + Q_UNUSED(role) + Q_UNUSED(value) + if (column < 0 || column >= m_data.size()) + return false; + return true; +} + +bool CAiAlarmTreeItem::setPtr(AlarmMsgPtr ptr) +{ + m_alarmPtr = ptr; + m_bIsAi = false; + m_uuid = ptr->uuid_base64; + return true; +} + +bool CAiAlarmTreeItem::setAiPtr(AiAlarmMsgPtr aiPtr) +{ + m_aialarmPtr = aiPtr; + m_bIsAi = true; + m_uuid = aiPtr->uuid_base64; + return true; +} + +bool CAiAlarmTreeItem::insertChildren(int position, int count, int columns) +{ + if (position < 0 || position > m_child.size()) + return false; + + for (int row = 0; row < count; ++row) { + QVector data(columns); + CAiAlarmTreeItem *item = new CAiAlarmTreeItem(data, this); + m_child.insert(position, item); + } + + return true; +} + +bool CAiAlarmTreeItem::removeChildren(int position, int count, int columns) +{ + Q_UNUSED(columns) + if (position < 0 || position + count > m_child.size()) + return false; + + for (int row = 0; row < count; ++row) + delete m_child.takeAt(position); + + return true; +} + +bool CAiAlarmTreeItem::isAi() +{ + return m_bIsAi; +} + +AlarmMsgPtr CAiAlarmTreeItem::ptr() +{ + if(m_alarmPtr == NULL) + return NULL; + else + return m_alarmPtr; +} + +bool CAiAlarmTreeItem::getPtr(AlarmMsgPtr &ptr) +{ + if(!m_bIsAi &&m_alarmPtr != NULL) + { + ptr = m_alarmPtr; + return true; + } + else + { + ptr = NULL; + return false; + } +} + +bool CAiAlarmTreeItem::getAiPtr(AiAlarmMsgPtr &aiPtr) +{ + if(m_bIsAi &&m_aialarmPtr != NULL) + { + aiPtr = m_aialarmPtr; + return true; + } + else + { + aiPtr = NULL; + return false; + } +} + +QList CAiAlarmTreeItem::getChildAlarmPtr() +{ + QList ptrList; + foreach (CAiAlarmTreeItem* item, m_child) { + if(item->ptr() != NULL) + { + ptrList.append(item->ptr()); + } + } + return ptrList; +} + +int CAiAlarmTreeItem::index(const QString uuid) +{ + for(int index(0);indexm_uuid == uuid) + { + return index; + } + } + return -1; +} + +bool CAiAlarmTreeItem::lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) +{ + AiAlarmMsgPtr aiptr = NULL; + AlarmMsgPtr ptr= NULL; + if(m_bIsAi) + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_aialarmPtr->ailessThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_aialarmPtr->ailessThan(ptr,sortkey); + } + + }else + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_alarmPtr->ailessThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_alarmPtr->ailessThan(ptr,sortkey); + } + } + LOGERROR("lessThan():比较大小出错!"); + return false; +} + +bool CAiAlarmTreeItem::moreThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) +{ + AiAlarmMsgPtr aiptr = NULL; + AlarmMsgPtr ptr= NULL; + if(m_bIsAi) + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_aialarmPtr->aimoreThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_aialarmPtr->aimoreThan(ptr,sortkey); + } + }else + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_alarmPtr->aimoreThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_alarmPtr->aimoreThan(ptr,sortkey); + } + } + LOGERROR("moreThan():比较大小出错!"); + return false; +} + +QList CAiAlarmTreeItem::getChild() +{ + return m_child; +} + +void CAiAlarmTreeItem::setChild(QList itemList) +{ + m_child.clear(); + m_child = itemList; +} + +QList CAiAlarmTreeItem::getChildItemList() +{ + return m_child; +} + +QVector CAiAlarmTreeItem::getContent() +{ + QVector vec; + for(int index(0);indextime_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + return m_data[0]; + case PRIORITY: + m_data[1] = CAlarmBaseData::instance()->queryPriorityDesc(m_aialarmPtr->priority); + return m_data[1]; + case LOCATION: + m_data[2] = CAlarmMsgManage::instance()->queryLocationDesc(m_aialarmPtr->uuid_base64); + return m_data[2]; + case REGION: + m_data[3] ="-"; + return m_data[3]; + case TYPE: + m_data[4] ="-"; + return "-"; + case STATUS: + m_data[5] ="-"; + return "-"; + case RETURNSTATUS: + m_data[6] ="-"; + return "-"; + case CONFIRM: + m_data[7] = QString("%1/%2").arg(getConfirm()).arg(m_child.size()); + return m_data[7]; + case CONTENT: + m_data[8] = m_aialarmPtr->content; + return m_data[8]; + default: + break; + } + } + return QVariant(); +} + +QVariant CAiAlarmTreeItem::getDataByColumn(int column) +{ + if(m_alarmPtr != NULL) + { + switch (column) { + case TIME: + { + m_data[0] = QDateTime::fromMSecsSinceEpoch(m_alarmPtr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + return m_data[0]; + } + case PRIORITY: + { + m_data[1] = CAlarmBaseData::instance()->queryPriorityDesc(m_alarmPtr->priority); + return m_data[1]; + } + case LOCATION: + { + m_data[2] = CAlarmBaseData::instance()->queryLocationDesc(m_alarmPtr->location_id); + return m_data[2]; + } + case REGION: + { + m_data[3] = CAlarmBaseData::instance()->queryRegionDesc(m_alarmPtr->region_id); + return m_data[3]; + } + case TYPE: + { + m_data[4] = CAlarmBaseData::instance()->queryAlarmTypeDesc(m_alarmPtr->alm_type); + return m_data[4]; + } + case STATUS: + { + m_data[5] = CAlarmBaseData::instance()->queryAlarmStatusDesc(m_alarmPtr->alm_status); + return m_data[5]; + } + case RETURNSTATUS: + { + if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_ALARM_CFM == m_alarmPtr->logic_state || + E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_ALARM_CFM_DEL == m_alarmPtr->logic_state) //未复归 + { + m_data[6] = QObject::tr("未复归"); + return m_data[6]; + } + else if(E_ALS_RETURN == m_alarmPtr->logic_state || E_ALS_RETURN_CFM == m_alarmPtr->logic_state || + E_ALS_RETURN_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_CFM_DEL == m_alarmPtr->logic_state) + { + m_data[6] = QObject::tr("已复归"); + return m_data[6]; + }else + { + m_data[6] = QObject::tr("-"); + return m_data[6]; + } + } + case CONFIRM: + { + if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_RETURN == m_alarmPtr->logic_state + || E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_DEL == m_alarmPtr->logic_state) //< 未确认 + { + m_data[7] = QObject::tr("未确认"); + return m_data[7]; + } + else if(E_ALS_ALARM_CFM == m_alarmPtr->logic_state || E_ALS_RETURN_CFM == m_alarmPtr->logic_state || + E_ALS_ALARM_CFM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_CFM_DEL == m_alarmPtr->logic_state || + ALS_EVT_ONLY == m_alarmPtr->logic_state) + { + m_data[7] = QObject::tr("已确认"); + return m_data[7]; + } + } + case CONTENT: + { + m_data[8] = m_alarmPtr->content; + return m_data[8]; + } + default: + break; + } + } + return QVariant(); +} + +int CAiAlarmTreeItem::getConfirm() +{ + int size = 0; + QList::iterator it = m_child.begin(); + while (it != m_child.end()) { + AlarmMsgPtr ptr; + if((*it)->getPtr(ptr)) + { + if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM + || ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) + { + size++; + } + } + it++; + } + return size; +} diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeItem.h b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeItem.h index 88694b8a..48e76b19 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeItem.h +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeItem.h @@ -1,81 +1,81 @@ -#ifndef CAIALARMTREEITEM_H -#define CAIALARMTREEITEM_H - -#include -#include -#include "CAlarmMsgManage.h" -enum E_ItemDataRole -{ - E_IfAiFlag =0x0101, //< 是否智能告警 - E_DisplayRole =0x0102, - E_UserRole = 0x0103, //< uuid - E_CheckStateRole = 0x0104 -}; -enum ColumnField -{ - TIME = 0, - PRIORITY, - LOCATION, - REGION, - TYPE, - STATUS, - RETURNSTATUS, - CONFIRM, - CONTENT -}; -class CAiAlarmTreeItem -{ -public: - explicit CAiAlarmTreeItem(const QVector &data,CAiAlarmTreeItem *parent = Q_NULLPTR); - ~CAiAlarmTreeItem(); - - CAiAlarmTreeItem *child(int row); - CAiAlarmTreeItem *parent(); - - int childCount() const; - int columnCount() const; - //返回行数 - int childNumber() const; - QVariant data(int column,int role = E_DisplayRole); - bool setData(int column,const QVariant &value,int role); - bool setPtr(AlarmMsgPtr ptr); - bool setAiPtr(AiAlarmMsgPtr aiPtr); - bool insertChildren(int position, int count, int columns); - bool removeChildren(int position, int count, int columns); - bool isAi(); - - //若确定是原始告警可以直接使用 - AlarmMsgPtr ptr(); - bool getPtr(AlarmMsgPtr &ptr); - bool getAiPtr(AiAlarmMsgPtr &aiPtr); - QList getChildAlarmPtr(); - - int index(const QString uuid); - - bool lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool moreThan(CAiAlarmTreeItem* info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - QList getChild(); - void setChild(QList itemList); - - QList getChildItemList(); - - QVector getContent(); -private: - QVariant aigetDataByColumn(int column); - QVariant getDataByColumn(int column); - int getConfirm(); -private: - QString m_uuid; - bool m_bIsAi; - QList m_child; - CAiAlarmTreeItem *m_parent; - - QVector m_data; - AlarmMsgPtr m_alarmPtr; - AiAlarmMsgPtr m_aialarmPtr; - - //Qt::CheckState m_checkState; -}; - -#endif // CAIALARMTREEITEM_H +#ifndef CAIALARMTREEITEM_H +#define CAIALARMTREEITEM_H + +#include +#include +#include "CAlarmMsgManage.h" +enum E_ItemDataRole +{ + E_IfAiFlag =0x0101, //< 是否智能告警 + E_DisplayRole =0x0102, + E_UserRole = 0x0103, //< uuid + E_CheckStateRole = 0x0104 +}; +enum ColumnField +{ + TIME = 0, + PRIORITY, + LOCATION, + REGION, + TYPE, + STATUS, + RETURNSTATUS, + CONFIRM, + CONTENT +}; +class CAiAlarmTreeItem +{ +public: + explicit CAiAlarmTreeItem(const QVector &data,CAiAlarmTreeItem *parent = Q_NULLPTR); + ~CAiAlarmTreeItem(); + + CAiAlarmTreeItem *child(int row); + CAiAlarmTreeItem *parent(); + + int childCount() const; + int columnCount() const; + //返回行数 + int childNumber() const; + QVariant data(int column,int role = E_DisplayRole); + bool setData(int column,const QVariant &value,int role); + bool setPtr(AlarmMsgPtr ptr); + bool setAiPtr(AiAlarmMsgPtr aiPtr); + bool insertChildren(int position, int count, int columns); + bool removeChildren(int position, int count, int columns); + bool isAi(); + + //若确定是原始告警可以直接使用 + AlarmMsgPtr ptr(); + bool getPtr(AlarmMsgPtr &ptr); + bool getAiPtr(AiAlarmMsgPtr &aiPtr); + QList getChildAlarmPtr(); + + int index(const QString uuid); + + bool lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(CAiAlarmTreeItem* info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + QList getChild(); + void setChild(QList itemList); + + QList getChildItemList(); + + QVector getContent(); +private: + QVariant aigetDataByColumn(int column); + QVariant getDataByColumn(int column); + int getConfirm(); +private: + QString m_uuid; + bool m_bIsAi; + QList m_child; + CAiAlarmTreeItem *m_parent; + + QVector m_data; + AlarmMsgPtr m_alarmPtr; + AiAlarmMsgPtr m_aialarmPtr; + + //Qt::CheckState m_checkState; +}; + +#endif // CAIALARMTREEITEM_H diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeModel.cpp b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeModel.cpp index 8018d0d4..29170081 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeModel.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeModel.cpp @@ -1,1134 +1,1134 @@ -#include "CAiAlarmTreeModel.h" -#include "CAlarmMsgManage.h" -#include "CAiAlarmDataCollect.h" -#include "CAlarmDataCollect.h" -#include "pub_logger_api/logger.h" -#include -#include -#include "CAlarmBaseData.h" - -CAiAlarmTreeModel::CAiAlarmTreeModel(QObject *parent) - : QAbstractItemModel(parent), - m_sortKey(E_SORT_TIME), - m_order(Qt::DescendingOrder), - m_nShowNum(0), - m_nShowAiNum(0) -{ - m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") <)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgAdd,this,&CAiAlarmTreeModel::slotAiMsgAdd,Qt::QueuedConnection); - - connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgRemove,this,&CAiAlarmTreeModel::slotAiMsgRemove,Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigMsgRemove,this,&CAiAlarmTreeModel::slotMsgRemove,Qt::QueuedConnection); - - connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); - connect(CAiAlarmDataCollect::instance(),&CAiAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); - - slotMsgRefresh(); -} - -CAiAlarmTreeModel::~CAiAlarmTreeModel() -{ - m_listHorAlignmentFlags.clear(); - m_header.clear(); -} - -void CAiAlarmTreeModel::initialize() -{ - m_listHorAlignmentFlags.clear(); - for (int nIndex(0); nIndex < m_header.size(); nIndex++) - { - m_listHorAlignmentFlags.append(Qt::AlignHCenter); - } - - initFilter(); - - slotMsgRefresh(); -} - -QVariant CAiAlarmTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(m_header.at(section)); - } - return QVariant(); -} - -QModelIndex CAiAlarmTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!hasIndex(row, column, parent)) - { - return QModelIndex(); - } - - CAiAlarmTreeItem *parentItem; - - if (!parent.isValid()) - { - parentItem = m_root; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - CAiAlarmTreeItem *childItem = parentItem->child(row); - if (childItem) - { - return createIndex(row, column, childItem); - } - else - { - return QModelIndex(); - } -} - -QModelIndex CAiAlarmTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - CAiAlarmTreeItem *childItem = static_cast(index.internalPointer()); - - CAiAlarmTreeItem *parentItem = childItem->parent(); - if (parentItem == m_root) - { - return QModelIndex(); - } - - return createIndex(parentItem->childNumber(), 0, parentItem); -} - -int CAiAlarmTreeModel::rowCount(const QModelIndex &parent) const -{ - CAiAlarmTreeItem *parentItem; - if (!parent.isValid()) - { - parentItem = m_root; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - return parentItem->childCount(); -} - -int CAiAlarmTreeModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return static_cast(parent.internalPointer())->columnCount(); - } - else - { - return m_root->columnCount(); - } -} - -QVariant CAiAlarmTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - { - return QVariant(); - } - if(Qt::TextAlignmentRole == role) - { - if(index.column() == (int)CONTENT) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); - } - - }else if (Qt::DisplayRole == role) - { - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - return item->data(index.column(),E_DisplayRole); - }else if(Qt::ToolTipRole == role) - { - if(index.column() == (int)CONTENT) - { - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - QString tip = item->data(index.column(),E_DisplayRole).toString(); - return tip; - } - } - return QVariant(); -} - -bool CAiAlarmTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_UNUSED(value); - Q_UNUSED(role); - if (!index.isValid() || index.column()) - { - return false; - } - return true; -} - -bool CAiAlarmTreeModel::insertRows(int row, int count, const QModelIndex &parent) -{ - bool success; - CAiAlarmTreeItem *parentItem = getItem(parent); - beginInsertRows(parent, row, row + count - 1); - success = parentItem->insertChildren(row, count, m_root->columnCount()); - endInsertRows(); - return success; -} - -bool CAiAlarmTreeModel::removeRows(int row, int count, const QModelIndex &parent) -{ - bool success; - CAiAlarmTreeItem *parentItem = getItem(parent); - beginRemoveRows(parent, row, row + count - 1); - success = parentItem->removeChildren(row, count, m_root->columnCount()); - endRemoveRows(); - return success; -} - -void CAiAlarmTreeModel::setModel() -{ - setModelData(m_root); -} - -void CAiAlarmTreeModel::slotAiMsgAdd(const QList &aimsgList) -{ - QList::const_iterator itpos = aimsgList.begin(); - while (itpos != aimsgList.end()) { - if((*itpos)->deleteFlag == true ||(*itpos)->brokenFlag == true) - { - itpos++; - continue ; - } - QList almList; - conditionAiFilter(*itpos,almList); - int size = almList.size(); - - if(size > 0) - { - m_nShowNum += size; - m_nShowAiNum++; - insertAlarmMsg(*itpos,almList); - } - itpos++; - } -} - -void CAiAlarmTreeModel::slotAiMsgRemove(const QList &uuidList) -{ - QList::const_iterator itpos = uuidList.begin(); - while (itpos != uuidList.end()) { - int x= m_root->index(*itpos); - if(x != -1) - { - m_nShowNum -= m_root->child(x)->childCount(); - m_nShowAiNum--; - beginRemoveRows(QModelIndex(), x,x); - m_root->removeChildren(x, 1, m_root->columnCount()); - endRemoveRows(); - } - itpos++; - } -} - -void CAiAlarmTreeModel::slotMsgRefresh() -{ - if(m_root->childCount() > 0) - { - beginRemoveRows(QModelIndex(), 0, m_root->childCount()-1); - m_root->removeChildren(0, m_root->childCount(), m_root->columnCount()); - endRemoveRows(); - } - m_nShowNum = 0; - m_nShowAiNum = 0; - setModel(); -} - -void CAiAlarmTreeModel::sortColumn(int column, Qt::SortOrder order) -{ - if(order == Qt::AscendingOrder) - { - m_order = Qt::DescendingOrder; - } - else - { - m_order = Qt::AscendingOrder; - } - - switch ((ColumnField)column) - { - case TIME: - { - m_sortKey = E_SORT_TIME; - break; - } - case PRIORITY: - { - m_sortKey = E_SORT_PRIORITY; - break; - } - case LOCATION: - { - m_sortKey = E_SORT_LOCATION; - break; - } - case REGION: - { - m_sortKey = E_SORT_REGION; - break; - } - case TYPE: - { - m_sortKey = E_SORT_TYPE; - break; - } - case STATUS: - { - m_sortKey = E_SORT_ALM_STATE; - break; - } - case RETURNSTATUS: - { - m_sortKey = E_SORT_STYLE; - break; - } - case CONFIRM: - { - m_sortKey = E_SORT_LOGICSTATE; - break; - } - case CONTENT: - { - m_sortKey = E_SORT_CONTENT; - break; - } - default: - break; - } - - beginResetModel(); - sort(); - endResetModel(); -} - -void CAiAlarmTreeModel::slotMsgRemove(const QVector deluuid) -{ - if(deluuid.size()>=1000) - { - beginResetModel(); - for(int index(0);indexindex(deluuid.at(index)); - if(x != -1) - { - m_nShowNum--; - m_root->removeChildren(x, 1, m_root->columnCount()); - } - } - endResetModel(); - }else - { - for(int index(0);indexindex(deluuid.at(index)); - if(x != -1) - { - m_nShowNum--; - beginRemoveRows(QModelIndex(),x,x); - m_root->removeChildren(x, 1, m_root->columnCount()); - endRemoveRows(); - } - } - } -} - -void CAiAlarmTreeModel::setModelData(CAiAlarmTreeItem *parent) -{ - m_nShowNum = 0; - m_nShowAiNum = 0; - QList listAlarm; - QList listaiAlarm; - listAlarm.clear(); - listaiAlarm.clear(); - int columnCount = m_root->columnCount(); - CAlarmMsgManage::instance()->getAlarmInfo(listAlarm,listaiAlarm); - foreach (AlarmMsgPtr almPtr, listAlarm) { - if(almPtr == NULL) - { - continue; - } - if(almPtr->deleteFlag == true || almPtr->releaseFlag == true) - { - continue; - } - if(conditionFilter(almPtr)) - { - m_nShowNum++; - parent->insertChildren(parent->childCount(), 1, columnCount); - parent->child(parent->childCount() - 1)->setPtr(almPtr); - } - } - foreach (AiAlarmMsgPtr aialmPtr, listaiAlarm) { - if(aialmPtr == NULL) - { - continue; - } - if(aialmPtr->deleteFlag == true || aialmPtr->brokenFlag == true) - { - continue; - } - QList almList; - conditionAiFilter(aialmPtr,almList); - int size = almList.size(); - if(size > 0) - { - m_root->insertChildren(m_root->childCount(), 1, columnCount); - m_nShowAiNum++; - m_root->child(m_root->childCount() - 1)->setAiPtr(aialmPtr); - int childCount = m_root->childCount(); - CAiAlarmTreeItem *item = m_root->child(childCount- 1); - - for(int index(0);index < size; index++) - { - m_nShowNum++; - item->insertChildren(item->childCount(),1,columnCount); - item->child(item->childCount() - 1)->setPtr(almList.at(index)); - } - } - } - beginResetModel(); - sort(); - endResetModel(); -} - -void CAiAlarmTreeModel::sort() -{ - QMap mapTree1AlarmInfo; - //<分 - for(int nIndex(0); nIndex < m_root->childCount(); nIndex++) - { - CAiAlarmTreeItem *item = m_root->child(nIndex); - mapTree1AlarmInfo[nIndex / 1000].second.append(item); - } - //<快速排序1级节点 - for(int nMapIndex(0); nMapIndex < mapTree1AlarmInfo.count(); nMapIndex++) - { - qucikSort(mapTree1AlarmInfo[nMapIndex].second, 0, mapTree1AlarmInfo[nMapIndex].second.count() - 1); - } - PAIRLISTAIALARMINFO tempListTree1AlarmInfo = mapTree1AlarmInfo[0]; - for(int nPairIndex(1); nPairIndex < mapTree1AlarmInfo.count(); nPairIndex++) - { - //<归并 - tempListTree1AlarmInfo.first = 0; - mapTree1AlarmInfo[nPairIndex].first = 0; - while(mapTree1AlarmInfo[nPairIndex].first < mapTree1AlarmInfo[nPairIndex].second.count()) - { - if(tempListTree1AlarmInfo.first >= tempListTree1AlarmInfo.second.count()) - { - tempListTree1AlarmInfo.second.append(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); - mapTree1AlarmInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListTree1AlarmInfo.second[tempListTree1AlarmInfo.first]->lessThan(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListTree1AlarmInfo.second.insert(tempListTree1AlarmInfo.first, mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); - mapTree1AlarmInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListTree1AlarmInfo.second[tempListTree1AlarmInfo.first]->moreThan(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListTree1AlarmInfo.second.insert(tempListTree1AlarmInfo.first, mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); - mapTree1AlarmInfo[nPairIndex].first += 1; - } - } - } - tempListTree1AlarmInfo.first += 1; - } - } - QList itemList = tempListTree1AlarmInfo.second; - for(int index(0);indexisAi()) - { - QList item = itemList.at(index)->getChild(); - //小于500才排序, - if(item.size()<500) - { - qucikSort(item,0,item.size()-1); - itemList.at(index)->setChild(item); - } - } - } - m_root->setChild(tempListTree1AlarmInfo.second); -} - -void CAiAlarmTreeModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CAiAlarmTreeModel::partitionAscendingOrder(QList &list, int start, int last) -{ - CAiAlarmTreeItem * info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(left < right && list[left]->lessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CAiAlarmTreeModel::partitionDescendingOrder(QList &list, int start, int last) -{ - CAiAlarmTreeItem * info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -void CAiAlarmTreeModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CAiAlarmTreeModel::partitionAscendingOrder(QList &list, int start, int last) -{ - AlarmMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftlessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CAiAlarmTreeModel::partitionDescendingOrder(QList &list, int start, int last) -{ - AlarmMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CAiAlarmTreeModel::calcLeft(const AiAlarmMsgPtr &info) -{ - int mid = -1; - int left = 0; - int right = m_root->childCount() - 1; - while(left <= right) - { - mid = (left + right) / 2; - - if (Qt::AscendingOrder == m_order) - { - CAiAlarmTreeItem *item =m_root->child(mid); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) &&ptr != NULL) - { - if(info->ailessThan(ptr, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) &&ptr != NULL) - { - if(info->ailessThan(ptr, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - } - else - { - CAiAlarmTreeItem *item =m_root->child(mid); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) &&ptr != NULL) - { - if(ptr->ailessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) &&ptr != NULL) - { - if(ptr->ailessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - } - } - return left; -} - -int CAiAlarmTreeModel::calcLeft(const AlarmMsgPtr &info) -{ - int mid = -1; - int left = 0; - int right = m_root->childCount() - 1; - while(left <= right) - { - mid = (left + right) / 2; - - if (Qt::AscendingOrder == m_order) - { - CAiAlarmTreeItem *item =m_root->child(mid); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) && ptr != NULL) - { - if(info->ailessThan(ptr, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) && ptr != NULL) - { - if(info->ailessThan(ptr, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - } - else - { - CAiAlarmTreeItem *item =m_root->child(mid); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) && ptr != NULL) - { - if(ptr->ailessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) && ptr != NULL) - { - if(ptr->ailessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - } - } - return left; -} - -CAiAlarmTreeItem *CAiAlarmTreeModel::getItem(const QModelIndex &index) const -{ - if (index.isValid()) { - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - if (item) - return item; - } - return m_root; -} - -CAiAlarmTreeItem *CAiAlarmTreeModel::getItem() const -{ - return m_root; -} - -void CAiAlarmTreeModel::initFilter() -{ - m_isLevelFilterEnable = false; - m_isLocationFilterEnable = false; - m_isRegionFilterEnable = false; - m_isStatusFilterEnable = false; - m_isDeviceTypeFileter = false; - m_isKeywordEnable = false; - m_timeFilterEnable = false; - m_confirmFilterEnable = false; - m_returnFilterEnable = false; - removeDeviceGroupFilter(); -} - -void CAiAlarmTreeModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, const bool &isStationFilterEnable, const QList &stationFilter, const bool &isRegionFilterEnable, const QList ®ionFilter, const bool &isStatusFilterEnable, const QList &statusFilter, const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, const bool &isKeywordFilterEnable, const QString &keyword, const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, const bool &confirmFilterEnable, const bool &isConfirm, const bool &returnFilterEnable, const bool &isReturn) -{ - m_isLevelFilterEnable = isLevelFilterEnable; - m_levelFilter = levelFilter; - m_isLocationFilterEnable = isStationFilterEnable; - m_locationFilter = stationFilter; - m_isRegionFilterEnable = isRegionFilterEnable; - m_regionFilter = regionFilter; - m_isStatusFilterEnable = isStatusFilterEnable; - m_statusFilter2 = statusFilter; - m_statusFilter = statusFilter; - if(statusFilter.contains(OTHERSTATUS)) - { - QMap alarmOtherStatus = CAlarmBaseData::instance()->getAlarmOtherStatus(); - QMap::iterator it = alarmOtherStatus.begin(); - for(;it != alarmOtherStatus.end(); ++it) - { - m_statusFilter.append(it.key()); - } - } - m_isDeviceTypeFileter = isDeviceTypeFilter; - m_subSystem = subSystem; - m_deviceType = deviceType; - m_isKeywordEnable = isKeywordFilterEnable; - m_keyowrd = keyword; - m_timeFilterEnable = timeFilterEnable; - m_startTime = startTime; - m_endTime = endTime; - m_confirmFilterEnable = confirmFilterEnable; - m_isConfirm = isConfirm; - m_returnFilterEnable =returnFilterEnable; - m_isReturn = isReturn; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::addDeviceGroupFilter(const QString &deviceGroup) -{ - m_deviceGroupFilter.insert(deviceGroup); - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::removeDeviceGroupFilter() -{ - m_deviceGroupFilter.clear(); -} - -void CAiAlarmTreeModel::removeDeviceGroupFilter(const QString &deviceGroup) -{ - m_deviceGroupFilter.remove(deviceGroup); - slotMsgRefresh(); -} - -bool CAiAlarmTreeModel::conditionFilter(const AlarmMsgPtr ptr) -{ - //(满足所有条件就展示) - //判断是否被禁止 - if(CAlarmMsgManage::instance()->ifInhibit(ptr->key_id_tag)) - { - return false; - } - - //是否被释放 - if(ptr->releaseFlag) - { - return false; - } - - //< 车站 - if(m_isLocationFilterEnable && !m_locationFilter.contains(ptr->location_id)) - { - return false; - } - - //< 等级 - if(m_isLevelFilterEnable && !m_levelFilter.contains(ptr->priority)) - { - return false; - } - - //< 责任区 - if(m_isRegionFilterEnable && !m_regionFilter.contains(ptr->region_id)) - { - return false; - } - - //< 类型 - if(m_isStatusFilterEnable && !m_statusFilter.contains(ptr->alm_status)) - { - return false; - } - - //< 设备类型 - if(m_isDeviceTypeFileter) - { - int dev_type = CAlarmBaseData::instance()->queryDevTypeByDesc(m_deviceType); - if(dev_type != ptr->dev_type) - { - return false; - } - } - - //< 设备组 - if(m_deviceGroupFilter.contains(ptr->dev_group_tag)) - { - return false; - } - - //< 关键字 - if(m_isKeywordEnable && !ptr->content.contains(m_keyowrd)) - { - return false; - } - - //< 时间 - if(m_timeFilterEnable) - { - if(m_startTime.toMSecsSinceEpoch() >= (qint64)(ptr->time_stamp)) - { - return false; - } - if(m_endTime.toMSecsSinceEpoch() <= (qint64)(ptr->time_stamp)) - { - return false; - } - } - - //< 是否已确认 - if(m_confirmFilterEnable) - { - if(m_isConfirm) - { - if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_RETURN || - ptr->logic_state ==E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_RETURN_DEL) - { - return false; - } - } - else - { - if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM || - ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) - { - return false; - } - } - } - if(m_returnFilterEnable) - { - if(m_isReturn) - { - if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_ALARM_CFM || - ptr->logic_state ==E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) - { - return false; - } - } - else - { - if(ptr->logic_state == E_ALS_RETURN || ptr->logic_state == E_ALS_RETURN_CFM || - ptr->logic_state == E_ALS_RETURN_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) - { - return false; - } - } - } - return true; -} - -void CAiAlarmTreeModel::conditionAiFilter(const AiAlarmMsgPtr ptr,QList &almList) -{ - //(满足一个条件就展示智能告警,但是原始告警该不展示的也不展示) - - QList almptrList = CAlarmMsgManage::instance()->getAlarmPtrByuuid(ptr->raw_alm_uuid); - for(int index(0);index < almptrList.size();index++) - { - if(conditionFilter(almptrList.at(index))) - { - almList.append(almptrList.at(index)); - } - } -} - -void CAiAlarmTreeModel::sortAlm(QList &almList) -{ - qucikSort(almList,0,almList.size()-1); -} - -void CAiAlarmTreeModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - m_isLevelFilterEnable = isCheck; - m_levelFilter = priorityFilter; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::setLocationFilter(bool &isCheck, QList &locationFilter) -{ - m_isLocationFilterEnable = isCheck; - m_locationFilter = locationFilter; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other) -{ - m_isStatusFilterEnable = isCheck; - m_statusFilter2 = alarmTypeFilter; - m_statusFilter = alarmTypeFilter; - if(other == true) - { - QMap alarmOtherStatus = CAlarmBaseData::instance()->getAlarmOtherStatus(); - QMap::iterator it = alarmOtherStatus.begin(); - for(;it != alarmOtherStatus.end(); ++it) - { - m_statusFilter.append(it.key()); - } - } - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) -{ - m_timeFilterEnable = isCheck; - if(isCheck) - { - QTime time_1(0,0,0); - QTime time_2(23,59,59); - m_startTime.setDate(startTime); - m_startTime.setTime(time_1); - m_endTime.setDate(endTime); - m_endTime.setTime(time_2); - } - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck) -{ - m_timeFilterEnable = isCheck; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::insertAlarmMsg(const QList &infoList) -{ - if(infoList.size() >= 1000) - { - beginResetModel(); - QList::const_iterator itpos = infoList.begin(); - while (itpos != infoList.end()) { - int left =calcLeft(*itpos); - m_root->insertChildren(left,1,m_root->columnCount()); - m_root->child(left)->setPtr(*itpos); - itpos++; - } - endResetModel(); - }else - { - QList::const_iterator itpos = infoList.begin(); - while (itpos != infoList.end()) { - int left =calcLeft(*itpos); - beginInsertRows(QModelIndex(), left, left); - m_root->insertChildren(left,1,m_root->columnCount()); - m_root->child(left)->setPtr(*itpos); - endInsertRows(); - itpos++; - } - } -} - -//过滤对智能告警下的原始告警同样起作用时修改 -void CAiAlarmTreeModel::insertAlarmMsg(const AiAlarmMsgPtr info,QList &almList) -{ - //当智能告警下的原始告警数小于500时,对此条智能告警下的原始告警排序,否则不排序 - if(almList.size()<500) - { - sortAlm(almList); - } - - if(almList.size()>=1000) - { - beginResetModel(); - int left = calcLeft(info); - m_root->insertChildren(left,1,m_root->columnCount()); - m_root->child(left)->setAiPtr(info); - - CAiAlarmTreeItem *item = m_root->child(left); - for(int num(0);numinsertChildren(num,1,m_root->columnCount()); - item->child(num)->setPtr(almList.at(num)); - } - endResetModel(); - }else - { - int left = calcLeft(info); - beginInsertRows(QModelIndex(), left, left); - m_root->insertChildren(left,1,m_root->columnCount()); - m_root->child(left)->setAiPtr(info); - endInsertRows(); - - CAiAlarmTreeItem *item = m_root->child(left); - for(int num(0);numinsertChildren(num,1,m_root->columnCount()); - item->child(num)->setPtr(almList.at(num)); - endInsertRows(); - } - } -} - -int CAiAlarmTreeModel::getShowNum() -{ - return m_nShowNum; -} - -int CAiAlarmTreeModel::getShowAi() -{ - return m_nShowAiNum; -} - -void CAiAlarmTreeModel::slotMsgArrived(QList listMsg) -{ - QList::const_iterator it = listMsg.constBegin(); - QList addMsgList; - while (it != listMsg.constEnd()) - { - if((*it)->deleteFlag != true) - { - if(conditionFilter(*it)) - { - m_nShowNum++; - addMsgList.append(*it); - } - } - ++it; - } - insertAlarmMsg(addMsgList); -} +#include "CAiAlarmTreeModel.h" +#include "CAlarmMsgManage.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmDataCollect.h" +#include "pub_logger_api/logger.h" +#include +#include +#include "CAlarmBaseData.h" + +CAiAlarmTreeModel::CAiAlarmTreeModel(QObject *parent) + : QAbstractItemModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::DescendingOrder), + m_nShowNum(0), + m_nShowAiNum(0) +{ + m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") <)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgAdd,this,&CAiAlarmTreeModel::slotAiMsgAdd,Qt::QueuedConnection); + + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgRemove,this,&CAiAlarmTreeModel::slotAiMsgRemove,Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigMsgRemove,this,&CAiAlarmTreeModel::slotMsgRemove,Qt::QueuedConnection); + + connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); + connect(CAiAlarmDataCollect::instance(),&CAiAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); + + slotMsgRefresh(); +} + +CAiAlarmTreeModel::~CAiAlarmTreeModel() +{ + m_listHorAlignmentFlags.clear(); + m_header.clear(); +} + +void CAiAlarmTreeModel::initialize() +{ + m_listHorAlignmentFlags.clear(); + for (int nIndex(0); nIndex < m_header.size(); nIndex++) + { + m_listHorAlignmentFlags.append(Qt::AlignHCenter); + } + + initFilter(); + + slotMsgRefresh(); +} + +QVariant CAiAlarmTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +QModelIndex CAiAlarmTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + CAiAlarmTreeItem *parentItem; + + if (!parent.isValid()) + { + parentItem = m_root; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + CAiAlarmTreeItem *childItem = parentItem->child(row); + if (childItem) + { + return createIndex(row, column, childItem); + } + else + { + return QModelIndex(); + } +} + +QModelIndex CAiAlarmTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CAiAlarmTreeItem *childItem = static_cast(index.internalPointer()); + + CAiAlarmTreeItem *parentItem = childItem->parent(); + if (parentItem == m_root) + { + return QModelIndex(); + } + + return createIndex(parentItem->childNumber(), 0, parentItem); +} + +int CAiAlarmTreeModel::rowCount(const QModelIndex &parent) const +{ + CAiAlarmTreeItem *parentItem; + if (!parent.isValid()) + { + parentItem = m_root; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +int CAiAlarmTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return static_cast(parent.internalPointer())->columnCount(); + } + else + { + return m_root->columnCount(); + } +} + +QVariant CAiAlarmTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + if(Qt::TextAlignmentRole == role) + { + if(index.column() == (int)CONTENT) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + } + + }else if (Qt::DisplayRole == role) + { + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + return item->data(index.column(),E_DisplayRole); + }else if(Qt::ToolTipRole == role) + { + if(index.column() == (int)CONTENT) + { + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + QString tip = item->data(index.column(),E_DisplayRole).toString(); + return tip; + } + } + return QVariant(); +} + +bool CAiAlarmTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(value); + Q_UNUSED(role); + if (!index.isValid() || index.column()) + { + return false; + } + return true; +} + +bool CAiAlarmTreeModel::insertRows(int row, int count, const QModelIndex &parent) +{ + bool success; + CAiAlarmTreeItem *parentItem = getItem(parent); + beginInsertRows(parent, row, row + count - 1); + success = parentItem->insertChildren(row, count, m_root->columnCount()); + endInsertRows(); + return success; +} + +bool CAiAlarmTreeModel::removeRows(int row, int count, const QModelIndex &parent) +{ + bool success; + CAiAlarmTreeItem *parentItem = getItem(parent); + beginRemoveRows(parent, row, row + count - 1); + success = parentItem->removeChildren(row, count, m_root->columnCount()); + endRemoveRows(); + return success; +} + +void CAiAlarmTreeModel::setModel() +{ + setModelData(m_root); +} + +void CAiAlarmTreeModel::slotAiMsgAdd(const QList &aimsgList) +{ + QList::const_iterator itpos = aimsgList.begin(); + while (itpos != aimsgList.end()) { + if((*itpos)->deleteFlag == true ||(*itpos)->brokenFlag == true) + { + itpos++; + continue ; + } + QList almList; + conditionAiFilter(*itpos,almList); + int size = almList.size(); + + if(size > 0) + { + m_nShowNum += size; + m_nShowAiNum++; + insertAlarmMsg(*itpos,almList); + } + itpos++; + } +} + +void CAiAlarmTreeModel::slotAiMsgRemove(const QList &uuidList) +{ + QList::const_iterator itpos = uuidList.begin(); + while (itpos != uuidList.end()) { + int x= m_root->index(*itpos); + if(x != -1) + { + m_nShowNum -= m_root->child(x)->childCount(); + m_nShowAiNum--; + beginRemoveRows(QModelIndex(), x,x); + m_root->removeChildren(x, 1, m_root->columnCount()); + endRemoveRows(); + } + itpos++; + } +} + +void CAiAlarmTreeModel::slotMsgRefresh() +{ + if(m_root->childCount() > 0) + { + beginRemoveRows(QModelIndex(), 0, m_root->childCount()-1); + m_root->removeChildren(0, m_root->childCount(), m_root->columnCount()); + endRemoveRows(); + } + m_nShowNum = 0; + m_nShowAiNum = 0; + setModel(); +} + +void CAiAlarmTreeModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + + switch ((ColumnField)column) + { + case TIME: + { + m_sortKey = E_SORT_TIME; + break; + } + case PRIORITY: + { + m_sortKey = E_SORT_PRIORITY; + break; + } + case LOCATION: + { + m_sortKey = E_SORT_LOCATION; + break; + } + case REGION: + { + m_sortKey = E_SORT_REGION; + break; + } + case TYPE: + { + m_sortKey = E_SORT_TYPE; + break; + } + case STATUS: + { + m_sortKey = E_SORT_ALM_STATE; + break; + } + case RETURNSTATUS: + { + m_sortKey = E_SORT_STYLE; + break; + } + case CONFIRM: + { + m_sortKey = E_SORT_LOGICSTATE; + break; + } + case CONTENT: + { + m_sortKey = E_SORT_CONTENT; + break; + } + default: + break; + } + + beginResetModel(); + sort(); + endResetModel(); +} + +void CAiAlarmTreeModel::slotMsgRemove(const QVector deluuid) +{ + if(deluuid.size()>=1000) + { + beginResetModel(); + for(int index(0);indexindex(deluuid.at(index)); + if(x != -1) + { + m_nShowNum--; + m_root->removeChildren(x, 1, m_root->columnCount()); + } + } + endResetModel(); + }else + { + for(int index(0);indexindex(deluuid.at(index)); + if(x != -1) + { + m_nShowNum--; + beginRemoveRows(QModelIndex(),x,x); + m_root->removeChildren(x, 1, m_root->columnCount()); + endRemoveRows(); + } + } + } +} + +void CAiAlarmTreeModel::setModelData(CAiAlarmTreeItem *parent) +{ + m_nShowNum = 0; + m_nShowAiNum = 0; + QList listAlarm; + QList listaiAlarm; + listAlarm.clear(); + listaiAlarm.clear(); + int columnCount = m_root->columnCount(); + CAlarmMsgManage::instance()->getAlarmInfo(listAlarm,listaiAlarm); + foreach (AlarmMsgPtr almPtr, listAlarm) { + if(almPtr == NULL) + { + continue; + } + if(almPtr->deleteFlag == true || almPtr->releaseFlag == true) + { + continue; + } + if(conditionFilter(almPtr)) + { + m_nShowNum++; + parent->insertChildren(parent->childCount(), 1, columnCount); + parent->child(parent->childCount() - 1)->setPtr(almPtr); + } + } + foreach (AiAlarmMsgPtr aialmPtr, listaiAlarm) { + if(aialmPtr == NULL) + { + continue; + } + if(aialmPtr->deleteFlag == true || aialmPtr->brokenFlag == true) + { + continue; + } + QList almList; + conditionAiFilter(aialmPtr,almList); + int size = almList.size(); + if(size > 0) + { + m_root->insertChildren(m_root->childCount(), 1, columnCount); + m_nShowAiNum++; + m_root->child(m_root->childCount() - 1)->setAiPtr(aialmPtr); + int childCount = m_root->childCount(); + CAiAlarmTreeItem *item = m_root->child(childCount- 1); + + for(int index(0);index < size; index++) + { + m_nShowNum++; + item->insertChildren(item->childCount(),1,columnCount); + item->child(item->childCount() - 1)->setPtr(almList.at(index)); + } + } + } + beginResetModel(); + sort(); + endResetModel(); +} + +void CAiAlarmTreeModel::sort() +{ + QMap mapTree1AlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_root->childCount(); nIndex++) + { + CAiAlarmTreeItem *item = m_root->child(nIndex); + mapTree1AlarmInfo[nIndex / 1000].second.append(item); + } + //<快速排序1级节点 + for(int nMapIndex(0); nMapIndex < mapTree1AlarmInfo.count(); nMapIndex++) + { + qucikSort(mapTree1AlarmInfo[nMapIndex].second, 0, mapTree1AlarmInfo[nMapIndex].second.count() - 1); + } + PAIRLISTAIALARMINFO tempListTree1AlarmInfo = mapTree1AlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapTree1AlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListTree1AlarmInfo.first = 0; + mapTree1AlarmInfo[nPairIndex].first = 0; + while(mapTree1AlarmInfo[nPairIndex].first < mapTree1AlarmInfo[nPairIndex].second.count()) + { + if(tempListTree1AlarmInfo.first >= tempListTree1AlarmInfo.second.count()) + { + tempListTree1AlarmInfo.second.append(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); + mapTree1AlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListTree1AlarmInfo.second[tempListTree1AlarmInfo.first]->lessThan(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListTree1AlarmInfo.second.insert(tempListTree1AlarmInfo.first, mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); + mapTree1AlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListTree1AlarmInfo.second[tempListTree1AlarmInfo.first]->moreThan(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListTree1AlarmInfo.second.insert(tempListTree1AlarmInfo.first, mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); + mapTree1AlarmInfo[nPairIndex].first += 1; + } + } + } + tempListTree1AlarmInfo.first += 1; + } + } + QList itemList = tempListTree1AlarmInfo.second; + for(int index(0);indexisAi()) + { + QList item = itemList.at(index)->getChild(); + //小于500才排序, + if(item.size()<500) + { + qucikSort(item,0,item.size()-1); + itemList.at(index)->setChild(item); + } + } + } + m_root->setChild(tempListTree1AlarmInfo.second); +} + +void CAiAlarmTreeModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CAiAlarmTreeModel::partitionAscendingOrder(QList &list, int start, int last) +{ + CAiAlarmTreeItem * info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(left < right && list[left]->lessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAiAlarmTreeModel::partitionDescendingOrder(QList &list, int start, int last) +{ + CAiAlarmTreeItem * info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CAiAlarmTreeModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CAiAlarmTreeModel::partitionAscendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAiAlarmTreeModel::partitionDescendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAiAlarmTreeModel::calcLeft(const AiAlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_root->childCount() - 1; + while(left <= right) + { + mid = (left + right) / 2; + + if (Qt::AscendingOrder == m_order) + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) &&ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) &&ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + else + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) &&ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) &&ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + } + return left; +} + +int CAiAlarmTreeModel::calcLeft(const AlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_root->childCount() - 1; + while(left <= right) + { + mid = (left + right) / 2; + + if (Qt::AscendingOrder == m_order) + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) && ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + else + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) && ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + } + return left; +} + +CAiAlarmTreeItem *CAiAlarmTreeModel::getItem(const QModelIndex &index) const +{ + if (index.isValid()) { + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if (item) + return item; + } + return m_root; +} + +CAiAlarmTreeItem *CAiAlarmTreeModel::getItem() const +{ + return m_root; +} + +void CAiAlarmTreeModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_isLocationFilterEnable = false; + m_isRegionFilterEnable = false; + m_isStatusFilterEnable = false; + m_isDeviceTypeFileter = false; + m_isKeywordEnable = false; + m_timeFilterEnable = false; + m_confirmFilterEnable = false; + m_returnFilterEnable = false; + removeDeviceGroupFilter(); +} + +void CAiAlarmTreeModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, const bool &isStationFilterEnable, const QList &stationFilter, const bool &isRegionFilterEnable, const QList ®ionFilter, const bool &isStatusFilterEnable, const QList &statusFilter, const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, const bool &isKeywordFilterEnable, const QString &keyword, const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, const bool &confirmFilterEnable, const bool &isConfirm, const bool &returnFilterEnable, const bool &isReturn) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isStatusFilterEnable = isStatusFilterEnable; + m_statusFilter2 = statusFilter; + m_statusFilter = statusFilter; + if(statusFilter.contains(OTHERSTATUS)) + { + QMap alarmOtherStatus = CAlarmBaseData::instance()->getAlarmOtherStatus(); + QMap::iterator it = alarmOtherStatus.begin(); + for(;it != alarmOtherStatus.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyowrd = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + m_confirmFilterEnable = confirmFilterEnable; + m_isConfirm = isConfirm; + m_returnFilterEnable =returnFilterEnable; + m_isReturn = isReturn; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::addDeviceGroupFilter(const QString &deviceGroup) +{ + m_deviceGroupFilter.insert(deviceGroup); + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::removeDeviceGroupFilter() +{ + m_deviceGroupFilter.clear(); +} + +void CAiAlarmTreeModel::removeDeviceGroupFilter(const QString &deviceGroup) +{ + m_deviceGroupFilter.remove(deviceGroup); + slotMsgRefresh(); +} + +bool CAiAlarmTreeModel::conditionFilter(const AlarmMsgPtr ptr) +{ + //(满足所有条件就展示) + //判断是否被禁止 + if(CAlarmMsgManage::instance()->ifInhibit(ptr->key_id_tag)) + { + return false; + } + + //是否被释放 + if(ptr->releaseFlag) + { + return false; + } + + //< 车站 + if(m_isLocationFilterEnable && !m_locationFilter.contains(ptr->location_id)) + { + return false; + } + + //< 等级 + if(m_isLevelFilterEnable && !m_levelFilter.contains(ptr->priority)) + { + return false; + } + + //< 责任区 + if(m_isRegionFilterEnable && !m_regionFilter.contains(ptr->region_id)) + { + return false; + } + + //< 类型 + if(m_isStatusFilterEnable && !m_statusFilter.contains(ptr->alm_status)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { + int dev_type = CAlarmBaseData::instance()->queryDevTypeByDesc(m_deviceType); + if(dev_type != ptr->dev_type) + { + return false; + } + } + + //< 设备组 + if(m_deviceGroupFilter.contains(ptr->dev_group_tag)) + { + return false; + } + + //< 关键字 + if(m_isKeywordEnable && !ptr->content.contains(m_keyowrd)) + { + return false; + } + + //< 时间 + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() >= (qint64)(ptr->time_stamp)) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() <= (qint64)(ptr->time_stamp)) + { + return false; + } + } + + //< 是否已确认 + if(m_confirmFilterEnable) + { + if(m_isConfirm) + { + if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_RETURN || + ptr->logic_state ==E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_RETURN_DEL) + { + return false; + } + } + else + { + if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM || + ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + } + if(m_returnFilterEnable) + { + if(m_isReturn) + { + if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_ALARM_CFM || + ptr->logic_state ==E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + else + { + if(ptr->logic_state == E_ALS_RETURN || ptr->logic_state == E_ALS_RETURN_CFM || + ptr->logic_state == E_ALS_RETURN_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + } + return true; +} + +void CAiAlarmTreeModel::conditionAiFilter(const AiAlarmMsgPtr ptr,QList &almList) +{ + //(满足一个条件就展示智能告警,但是原始告警该不展示的也不展示) + + QList almptrList = CAlarmMsgManage::instance()->getAlarmPtrByuuid(ptr->raw_alm_uuid); + for(int index(0);index < almptrList.size();index++) + { + if(conditionFilter(almptrList.at(index))) + { + almList.append(almptrList.at(index)); + } + } +} + +void CAiAlarmTreeModel::sortAlm(QList &almList) +{ + qucikSort(almList,0,almList.size()-1); +} + +void CAiAlarmTreeModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other) +{ + m_isStatusFilterEnable = isCheck; + m_statusFilter2 = alarmTypeFilter; + m_statusFilter = alarmTypeFilter; + if(other == true) + { + QMap alarmOtherStatus = CAlarmBaseData::instance()->getAlarmOtherStatus(); + QMap::iterator it = alarmOtherStatus.begin(); + for(;it != alarmOtherStatus.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::insertAlarmMsg(const QList &infoList) +{ + if(infoList.size() >= 1000) + { + beginResetModel(); + QList::const_iterator itpos = infoList.begin(); + while (itpos != infoList.end()) { + int left =calcLeft(*itpos); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setPtr(*itpos); + itpos++; + } + endResetModel(); + }else + { + QList::const_iterator itpos = infoList.begin(); + while (itpos != infoList.end()) { + int left =calcLeft(*itpos); + beginInsertRows(QModelIndex(), left, left); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setPtr(*itpos); + endInsertRows(); + itpos++; + } + } +} + +//过滤对智能告警下的原始告警同样起作用时修改 +void CAiAlarmTreeModel::insertAlarmMsg(const AiAlarmMsgPtr info,QList &almList) +{ + //当智能告警下的原始告警数小于500时,对此条智能告警下的原始告警排序,否则不排序 + if(almList.size()<500) + { + sortAlm(almList); + } + + if(almList.size()>=1000) + { + beginResetModel(); + int left = calcLeft(info); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setAiPtr(info); + + CAiAlarmTreeItem *item = m_root->child(left); + for(int num(0);numinsertChildren(num,1,m_root->columnCount()); + item->child(num)->setPtr(almList.at(num)); + } + endResetModel(); + }else + { + int left = calcLeft(info); + beginInsertRows(QModelIndex(), left, left); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setAiPtr(info); + endInsertRows(); + + CAiAlarmTreeItem *item = m_root->child(left); + for(int num(0);numinsertChildren(num,1,m_root->columnCount()); + item->child(num)->setPtr(almList.at(num)); + endInsertRows(); + } + } +} + +int CAiAlarmTreeModel::getShowNum() +{ + return m_nShowNum; +} + +int CAiAlarmTreeModel::getShowAi() +{ + return m_nShowAiNum; +} + +void CAiAlarmTreeModel::slotMsgArrived(QList listMsg) +{ + QList::const_iterator it = listMsg.constBegin(); + QList addMsgList; + while (it != listMsg.constEnd()) + { + if((*it)->deleteFlag != true) + { + if(conditionFilter(*it)) + { + m_nShowNum++; + addMsgList.append(*it); + } + } + ++it; + } + insertAlarmMsg(addMsgList); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeModel.h b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeModel.h index 3c25a608..021eddea 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeModel.h +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeModel.h @@ -1,310 +1,310 @@ -#ifndef CAIALARMTREEMODEL_H -#define CAIALARMTREEMODEL_H - -#include -#include -#include - -#include -#include - -typedef QPair > PAIRLISTAIALARMINFO; -class CAiAlarmTreeModel : public QAbstractItemModel -{ - Q_OBJECT -public: - explicit CAiAlarmTreeModel(QObject *parent = nullptr); - ~CAiAlarmTreeModel(); - - void initialize(); - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role); - // Add data: - bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - - // Remove data: - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - - void setModel(); - - CAiAlarmTreeItem *getItem(const QModelIndex &index) const; - - CAiAlarmTreeItem *getItem() const; - - void initFilter(); - - void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isStatusFilterEnable, const QList &statusFilter, - const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), - const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), - const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), - const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false, - const bool &returnFilterEnable = false, const bool &isReturn =false); - - /** - * @brief addDeviceGroupFilter 添加设备组过滤 - * @param deviceGroup 设备组名称 - */ - void addDeviceGroupFilter(const QString &deviceGroup); - void removeDeviceGroupFilter(); - /** - * @brief removeDeviceGroupFilter 移除设备组过滤 - * @param deviceGroup 设备组名称 - */ - void removeDeviceGroupFilter(const QString &deviceGroup); - - /** - * @brief conditionFilter 判断原始告警是否需要展示 - * @param ptr 原始告警智能指针 - * @return 允许返回true 否则返回false - */ - bool conditionFilter(const AlarmMsgPtr ptr); - - /** - * @brief conditionAiFilter 判断智能告警是否需要展示,并获取需要展示的原始告警 (当almList的size大于0时,则认为智能告警需要展示) - * @param ptr 智能告警智能指针 - * @param almList 获取的要展示的原始告警智能指针 - */ - void conditionAiFilter(const AiAlarmMsgPtr ptr, QList &almList); - - /** - * @brief sortAlm 对原始告警进行排序(此处是用在对智能告警二级节点上的原始告警排序) - * @param almList 需要排序的原始告警列表 - */ - void sortAlm(QList &almList); - -public: - /** - * @brief setPriorityFilter 设置优先级过滤 - * @param isCheck 是否设置 - * @param priorityFilter 过滤的条件集合 - */ - void setPriorityFilter(bool &isCheck, QList &priorityFilter); - - /** - * @brief setLocationFilter 设置车站过滤 - * @param isCheck 是否设置 - * @param locationFilter 过滤的条件集合 - */ - void setLocationFilter(bool &isCheck, QList &locationFilter); - - /** - * @brief setAlarmTypeFilter 设置告警类型过滤 - * @param isCheck 是否设置 - * @param alarmTypeFilter 过滤的条件集合 - * @param other 是否包含其他条件(此处只得是不属于下拉框中的告警类型) - */ - void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other); - - /** - * @brief setAlarmTimeFilter 设置告警时间过滤 - * @param isCheck 是否设置 - * @param startTime 开始时间 - * @param endTime 结束时间 - */ - void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); - - /** - * @brief setAlarmTimeFilter 设置是否需要时间过滤 (此处用法是告警大窗日历中点击取消调用) - * @param isCheck 是否设置 - */ - void setAlarmTimeFilter(bool &isCheck); - - /** - * @brief insertAlarmMsg 插入原始告警 - * @param infoList 原始告警智能指针集合 - */ - void insertAlarmMsg(const QList &infoList); - - /** - * @brief insertAlarmMsg 插入智能告警 - * @param info 智能告警智能指针 - * @param almList 智能告警包含的原始告警智能指针集合 - */ - void insertAlarmMsg(const AiAlarmMsgPtr info, QList &almList); - - /** - * @brief getShowNum 获取显示的原始告警数量 - * @return 原始告警数量 - */ - int getShowNum(); - - /** - * @brief getShowAi 获取显示的智能告警数量 - * @return 智能告警数量 - */ - int getShowAi(); - -public slots: - - /** - * @brief slotMsgArrived 接收原始告警 - * @param listMsg 原始告警智能智能集合 - */ - void slotMsgArrived(QList listMsg); - - /** - * @brief slotAiMsgAdd 接收智能告警 - * @param aimsgList 智能告警智能指针集合 - */ - void slotAiMsgAdd(const QList &aimsgList); - - /** - * @brief slotAiMsgRemove 接收要移除的智能告警 - * @param uuidList 要移除的智能告警uuid集合 - */ - void slotAiMsgRemove(const QList &uuidList); - - /** - * @brief slotMsgRefresh 重新获取告警数据 - */ - void slotMsgRefresh(); - - /** - * @brief sortColumn 根据列排序 - * @param column 列号 - * @param order 升序或者降序 - */ - void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); - - /** - * @brief slotMsgRemove 接收要删除的原始告警(一级节点上的) - * @param deluuid 原始告警uuid - */ - void slotMsgRemove(const QVector deluuid); - -private: - /** - * @brief setModelData 设置模型 - * @param parent 父节点指针 - */ - void setModelData(CAiAlarmTreeItem *parent); - - /** - * @brief sort 排序 - */ - void sort(); - - /** - * @brief qucikSort 快排 - * @param list 需要排序的集合 - * @param start 开始下标 - * @param last 结束下标 - */ - void qucikSort(QList &list, int start, int last); - - /** - * @brief partitionAscendingOrder 升序排序 - * @param list 排序列表 - * @param start 开始位置 - * @param last 结束位置 - * @return 排序位置 - */ - int partitionAscendingOrder(QList &list, int start, int last); - - /** - * @brief partitionAscendingOrder 降序排序 - * @param list 排序列表 - * @param start 开始位置 - * @param last 结束位置 - * @return 排序位置 - */ - int partitionDescendingOrder(QList &list, int start, int last); - - /** - * @brief qucikSort 快排 - * @param list 需要排序的集合 - * @param start 开始下标 - * @param last 结束下标 - */ - void qucikSort(QList &list, int start, int last); - - /** - * @brief partitionAscendingOrder 升序排序 - * @param list 排序列表 - * @param start 开始位置 - * @param last 结束位置 - * @return 排序位置 - */ - int partitionAscendingOrder(QList &list, int start, int last); - - /** - * @brief partitionAscendingOrder 降序排序 - * @param list 排序列表 - * @param start 开始位置 - * @param last 结束位置 - * @return 排序位置 - */ - int partitionDescendingOrder(QList &list, int start, int last); - - /** - * @brief calcLeft 计算位置 - * @param info 智能告警智能指针 - * @return 排序位置 - */ - int calcLeft(const AiAlarmMsgPtr &info); - - /** - * @brief calcLeft 计算位置 - * @param info 原始告警智能指针 - * @return 排序位置 - */ - int calcLeft(const AlarmMsgPtr &info); - -private: - - CAiAlarmTreeItem *m_root; - QVector m_header; - QList m_listHorAlignmentFlags; //< 水平对齐方式 - - //< Filter - bool m_isLevelFilterEnable; //是否按告警级别过滤 - QList m_levelFilter; //告警级别过滤 - bool m_isLocationFilterEnable; //是否按车站过滤 - QList m_locationFilter; //车站过滤 - bool m_isRegionFilterEnable; //是否按责任区过滤 - QList m_regionFilter; //责任区过滤 - bool m_isStatusFilterEnable; //是否按告警类型过滤 - QList m_statusFilter; //告警类型过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) - QList m_statusFilter2; //告警类型过滤(显示在过滤窗中的告警状态) - bool m_isDeviceTypeFileter; //设备类型过滤 - QString m_subSystem; //子系统 - QString m_deviceType; //设备类型 - bool m_isKeywordEnable; //关键字过滤 - QString m_keyowrd; //关键字 - bool m_timeFilterEnable; //是否根据时间过滤 - QDateTime m_startTime; //起始时间 - QDateTime m_endTime; //终止时间 - bool m_confirmFilterEnable; //是否根据状态确认过滤 - bool m_isConfirm; //状态是否确认 - - bool m_returnFilterEnable; //是否根据复归状态过滤 - bool m_isReturn; //是否已复归 - - - QSet m_deviceFilter; //< 设备过滤 - QSet m_pointFilter; //标签过滤 - QSet m_deviceGroupFilter; //<设备组过滤 - - E_ALARM_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - - int m_nShowNum; - int m_nShowAiNum; - -}; - -#endif // CAIALARMTREEMODEL_H +#ifndef CAIALARMTREEMODEL_H +#define CAIALARMTREEMODEL_H + +#include +#include +#include + +#include +#include + +typedef QPair > PAIRLISTAIALARMINFO; +class CAiAlarmTreeModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit CAiAlarmTreeModel(QObject *parent = nullptr); + ~CAiAlarmTreeModel(); + + void initialize(); + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role); + // Add data: + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + // Remove data: + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + void setModel(); + + CAiAlarmTreeItem *getItem(const QModelIndex &index) const; + + CAiAlarmTreeItem *getItem() const; + + void initFilter(); + + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isStatusFilterEnable, const QList &statusFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false, + const bool &returnFilterEnable = false, const bool &isReturn =false); + + /** + * @brief addDeviceGroupFilter 添加设备组过滤 + * @param deviceGroup 设备组名称 + */ + void addDeviceGroupFilter(const QString &deviceGroup); + void removeDeviceGroupFilter(); + /** + * @brief removeDeviceGroupFilter 移除设备组过滤 + * @param deviceGroup 设备组名称 + */ + void removeDeviceGroupFilter(const QString &deviceGroup); + + /** + * @brief conditionFilter 判断原始告警是否需要展示 + * @param ptr 原始告警智能指针 + * @return 允许返回true 否则返回false + */ + bool conditionFilter(const AlarmMsgPtr ptr); + + /** + * @brief conditionAiFilter 判断智能告警是否需要展示,并获取需要展示的原始告警 (当almList的size大于0时,则认为智能告警需要展示) + * @param ptr 智能告警智能指针 + * @param almList 获取的要展示的原始告警智能指针 + */ + void conditionAiFilter(const AiAlarmMsgPtr ptr, QList &almList); + + /** + * @brief sortAlm 对原始告警进行排序(此处是用在对智能告警二级节点上的原始告警排序) + * @param almList 需要排序的原始告警列表 + */ + void sortAlm(QList &almList); + +public: + /** + * @brief setPriorityFilter 设置优先级过滤 + * @param isCheck 是否设置 + * @param priorityFilter 过滤的条件集合 + */ + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + + /** + * @brief setLocationFilter 设置车站过滤 + * @param isCheck 是否设置 + * @param locationFilter 过滤的条件集合 + */ + void setLocationFilter(bool &isCheck, QList &locationFilter); + + /** + * @brief setAlarmTypeFilter 设置告警类型过滤 + * @param isCheck 是否设置 + * @param alarmTypeFilter 过滤的条件集合 + * @param other 是否包含其他条件(此处只得是不属于下拉框中的告警类型) + */ + void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other); + + /** + * @brief setAlarmTimeFilter 设置告警时间过滤 + * @param isCheck 是否设置 + * @param startTime 开始时间 + * @param endTime 结束时间 + */ + void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); + + /** + * @brief setAlarmTimeFilter 设置是否需要时间过滤 (此处用法是告警大窗日历中点击取消调用) + * @param isCheck 是否设置 + */ + void setAlarmTimeFilter(bool &isCheck); + + /** + * @brief insertAlarmMsg 插入原始告警 + * @param infoList 原始告警智能指针集合 + */ + void insertAlarmMsg(const QList &infoList); + + /** + * @brief insertAlarmMsg 插入智能告警 + * @param info 智能告警智能指针 + * @param almList 智能告警包含的原始告警智能指针集合 + */ + void insertAlarmMsg(const AiAlarmMsgPtr info, QList &almList); + + /** + * @brief getShowNum 获取显示的原始告警数量 + * @return 原始告警数量 + */ + int getShowNum(); + + /** + * @brief getShowAi 获取显示的智能告警数量 + * @return 智能告警数量 + */ + int getShowAi(); + +public slots: + + /** + * @brief slotMsgArrived 接收原始告警 + * @param listMsg 原始告警智能智能集合 + */ + void slotMsgArrived(QList listMsg); + + /** + * @brief slotAiMsgAdd 接收智能告警 + * @param aimsgList 智能告警智能指针集合 + */ + void slotAiMsgAdd(const QList &aimsgList); + + /** + * @brief slotAiMsgRemove 接收要移除的智能告警 + * @param uuidList 要移除的智能告警uuid集合 + */ + void slotAiMsgRemove(const QList &uuidList); + + /** + * @brief slotMsgRefresh 重新获取告警数据 + */ + void slotMsgRefresh(); + + /** + * @brief sortColumn 根据列排序 + * @param column 列号 + * @param order 升序或者降序 + */ + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + + /** + * @brief slotMsgRemove 接收要删除的原始告警(一级节点上的) + * @param deluuid 原始告警uuid + */ + void slotMsgRemove(const QVector deluuid); + +private: + /** + * @brief setModelData 设置模型 + * @param parent 父节点指针 + */ + void setModelData(CAiAlarmTreeItem *parent); + + /** + * @brief sort 排序 + */ + void sort(); + + /** + * @brief qucikSort 快排 + * @param list 需要排序的集合 + * @param start 开始下标 + * @param last 结束下标 + */ + void qucikSort(QList &list, int start, int last); + + /** + * @brief partitionAscendingOrder 升序排序 + * @param list 排序列表 + * @param start 开始位置 + * @param last 结束位置 + * @return 排序位置 + */ + int partitionAscendingOrder(QList &list, int start, int last); + + /** + * @brief partitionAscendingOrder 降序排序 + * @param list 排序列表 + * @param start 开始位置 + * @param last 结束位置 + * @return 排序位置 + */ + int partitionDescendingOrder(QList &list, int start, int last); + + /** + * @brief qucikSort 快排 + * @param list 需要排序的集合 + * @param start 开始下标 + * @param last 结束下标 + */ + void qucikSort(QList &list, int start, int last); + + /** + * @brief partitionAscendingOrder 升序排序 + * @param list 排序列表 + * @param start 开始位置 + * @param last 结束位置 + * @return 排序位置 + */ + int partitionAscendingOrder(QList &list, int start, int last); + + /** + * @brief partitionAscendingOrder 降序排序 + * @param list 排序列表 + * @param start 开始位置 + * @param last 结束位置 + * @return 排序位置 + */ + int partitionDescendingOrder(QList &list, int start, int last); + + /** + * @brief calcLeft 计算位置 + * @param info 智能告警智能指针 + * @return 排序位置 + */ + int calcLeft(const AiAlarmMsgPtr &info); + + /** + * @brief calcLeft 计算位置 + * @param info 原始告警智能指针 + * @return 排序位置 + */ + int calcLeft(const AlarmMsgPtr &info); + +private: + + CAiAlarmTreeItem *m_root; + QVector m_header; + QList m_listHorAlignmentFlags; //< 水平对齐方式 + + //< Filter + bool m_isLevelFilterEnable; //是否按告警级别过滤 + QList m_levelFilter; //告警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isStatusFilterEnable; //是否按告警类型过滤 + QList m_statusFilter; //告警类型过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) + QList m_statusFilter2; //告警类型过滤(显示在过滤窗中的告警状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyowrd; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + bool m_confirmFilterEnable; //是否根据状态确认过滤 + bool m_isConfirm; //状态是否确认 + + bool m_returnFilterEnable; //是否根据复归状态过滤 + bool m_isReturn; //是否已复归 + + + QSet m_deviceFilter; //< 设备过滤 + QSet m_pointFilter; //标签过滤 + QSet m_deviceGroupFilter; //<设备组过滤 + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + int m_nShowNum; + int m_nShowAiNum; + +}; + +#endif // CAIALARMTREEMODEL_H diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeView.cpp b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeView.cpp index 3fb826a7..2c23b6bd 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeView.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeView.cpp @@ -1,22 +1,22 @@ -#include "CAiAlarmTreeView.h" -#include -#include -#include -CAiAlarmTreeView::CAiAlarmTreeView(QWidget *parent) - :QTreeView(parent) -{ - -} - -void CAiAlarmTreeView::initialize() -{ - setSortingEnabled(true); - setAlternatingRowColors(true); - header()->setDefaultAlignment(Qt::AlignCenter); - header()->setStretchLastSection(true); - header()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - //setSelectionMode(QAbstractItemView::MultiSelection); - //setHorizontalScrollMode(ScrollPerPixel); - setUniformRowHeights(true); -} +#include "CAiAlarmTreeView.h" +#include +#include +#include +CAiAlarmTreeView::CAiAlarmTreeView(QWidget *parent) + :QTreeView(parent) +{ + +} + +void CAiAlarmTreeView::initialize() +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + header()->setDefaultAlignment(Qt::AlignCenter); + header()->setStretchLastSection(true); + header()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + //setSelectionMode(QAbstractItemView::MultiSelection); + //setHorizontalScrollMode(ScrollPerPixel); + setUniformRowHeights(true); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeView.h b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeView.h index 001ef81a..e4af5631 100644 --- a/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeView.h +++ b/product/src/gui/plugin/AlarmWidget/CAiAlarmTreeView.h @@ -1,15 +1,15 @@ -#ifndef CAIALARMTREEVIEW_H -#define CAIALARMTREEVIEW_H - -#include - -class CAiAlarmTreeView : public QTreeView -{ - Q_OBJECT -public: - CAiAlarmTreeView(QWidget *parent = Q_NULLPTR); - - void initialize(); -}; - -#endif // CAIALARMTREEVIEW_H +#ifndef CAIALARMTREEVIEW_H +#define CAIALARMTREEVIEW_H + +#include + +class CAiAlarmTreeView : public QTreeView +{ + Q_OBJECT +public: + CAiAlarmTreeView(QWidget *parent = Q_NULLPTR); + + void initialize(); +}; + +#endif // CAIALARMTREEVIEW_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.cpp index 964693c8..ca90b3de 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.cpp @@ -1,659 +1,659 @@ -#include "CAlarmBaseData.h" -#include "perm_mng_api/PermMngApi.h" -#include "CAlarmCommon.h" -#include "pub_logger_api/logger.h" -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CharUtil.h" - -using namespace kbd_public; -using namespace std; - -CAlarmBaseData *CAlarmBaseData::pInstance = NULL; -CAlarmBaseData *CAlarmBaseData::instance() -{ - if(pInstance == NULL) - { - pInstance = new CAlarmBaseData(); - } - return pInstance; -} - -CAlarmBaseData::~CAlarmBaseData() -{ - LOGDEBUG("~CAlarmBaseData()"); -} - -void CAlarmBaseData::destory() -{ - if(m_rtdbAccess) - { - delete m_rtdbAccess; - } - - m_rtdbAccess = Q_NULLPTR; - pInstance = NULL; - deleteLater(); -} - -void CAlarmBaseData::initData() -{ - loadPermInfo(); - loadAlarmInfoConfig(); -} - -QString CAlarmBaseData::queryPriorityDesc(int id) -{ - return m_priorityDescriptionMap.value(id,QString()); -} - -QString CAlarmBaseData::queryLocationDesc(int id) -{ - return m_locationDescriptionMap.value(id,QString()); -} - -QString CAlarmBaseData::queryRegionDesc(int id) -{ - return m_regionDescriptionMap.value(id,QString()); -} - -QString CAlarmBaseData::queryAlarmTypeDesc(int id) -{ - return m_alarmTypeDescriptionMap.value(id,QString()); -} - -QString CAlarmBaseData::queryAlarmStatusDesc(int id) -{ - return m_alarmStatusDescriptionMap.value(id,QString()); -} - -int CAlarmBaseData::queryDevTypeByDesc(QString &desc) -{ - return m_deviceTypeDescriptionMap.key(desc); -} - -QList CAlarmBaseData::getDevGroupTagList() -{ - return m_deviceGroupDescriptionMap.keys(); -} - -QMap CAlarmBaseData::getAlarmOtherStatus() -{ - return m_alarmOtherStatusDescriptionMap; -} - -CAlarmBaseData::CAlarmBaseData(QObject *parent) : - QObject(parent), - m_rtdbAccess(Q_NULLPTR) -{ - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); - m_pWriteDb->open(); - createSysInfoInstance(m_ptrSysInfo); - initData(); -} - -void CAlarmBaseData::loadPermInfo() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecRegionId; - std::vector vecLocationId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_VIEW, vecRegionId, vecLocationId)) - { - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - m_listPermLocationId.append(*location++); - } - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - m_listPermRegionId.append(*region++); - } - } - } -} - -void CAlarmBaseData::loadAlarmInfoConfig() -{ - loadPriorityDescription(); - loadLocationDescription(); - loadRegionDescription(); - loadAlarmTypeDescription(); - loadAlarmStatusDescription(); - loadDeviceTypeDescription(); - loadDeviceGroupDescription(); - loadAlarmShowStatusDescription(); - loadAlarmOtherStatusDescription(); -} - -int CAlarmBaseData::queryDomainIdByLocId(int loactionId) -{ - if(m_ptrSysInfo) - { - SLocationInfo stLocationInfo; - if(kbdSuccess == m_ptrSysInfo->getLocationInfoById(loactionId, stLocationInfo)) - { - return stLocationInfo.nDomainId; - } - } - return CN_InvalidDomainId; -} - -bool CAlarmBaseData::queryAllPointDevGroup(int nDomainId, int nSubsystemId, const QString &strDevg, QList &pointList) -{ - if(!m_ptrSysInfo) - { - return false; - } - SAppInfo stAppInfo; - if(kbdSuccess != m_ptrSysInfo->getAppInfoBySubsystemId(nSubsystemId, stAppInfo)) - { - LOGERROR("queryAllPointDevGroup 获取应用ID失败"); - return false; - } - kbd_dbms::CRdbNetApi rdbNetApi; - rdbNetApi.connect(nDomainId, stAppInfo.nId); - - //< 查询所有设备 - QList devList; - if(!queryAllDeviceDevGroup(rdbNetApi, strDevg, devList)) - { - return false; - } - - //< 查询所有测点 - for(int n(0); n CAlarmBaseData::getPriorityMap() -{ - return m_priorityDescriptionMap; -} - -QMap CAlarmBaseData::getPermPriorityMap() -{ - return m_priorityPermDescriptionMap; -} - -QMap CAlarmBaseData::getPriorityOrderMap() -{ - return m_priorityOrderDescriptionMap; -} - -QMap CAlarmBaseData::getPermLocationMap() -{ - return m_locationPermDescriptionMap; -} - -QMap CAlarmBaseData::getPermRegionMap() -{ - return m_regionPermDescriptionMap; -} - -QMap CAlarmBaseData::getAlarmShowStatusMap() -{ - return m_alarmShowStatusDescriptionMap; -} - -QMap > CAlarmBaseData::getAreaLocMap() -{ - return m_areaLocMap; -} - -QMap CAlarmBaseData::getAreaInfoMap() -{ - return m_areaInfoMap; -} - -QList CAlarmBaseData::getPermLocationIdList() -{ - return m_listPermLocationId; -} - -QList CAlarmBaseData::getPermRegionIdList() -{ - return m_listPermRegionId; -} - -QList CAlarmBaseData::getPermLocationOrder() -{ - return m_listPermLocationOrder; -} - -QString CAlarmBaseData::getPermLocationDesc(const int &locationId) -{ - return m_locationPermDescriptionMap.value(locationId); -} - -void CAlarmBaseData::loadPriorityDescription() -{ - if(m_rtdbAccess->open("base", "alarm_level_define")) - { - m_priorityDescriptionMap.clear(); - m_priorityOrderDescriptionMap.clear(); - m_priorityPermDescriptionMap.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("priority_id"); - columns.push_back("priority_order"); - columns.push_back("priority_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType order; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, order); - result.getColumnValue(nIndex, 2, value); - if(key.toInt() != 0 ) - { - m_priorityPermDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - m_priorityOrderDescriptionMap[order.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmBaseData::loadLocationDescription() -{ - m_areaInfoMap.clear(); - m_areaLocMap.clear(); - if(m_rtdbAccess->open("base", "sys_model_location_info")) - { - m_locationDescriptionMap.clear(); - m_locationPermDescriptionMap.clear(); - m_listPermLocationOrder.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("location_id"); - columns.push_back("description"); - columns.push_back("tag_name"); - columns.push_back("location_type"); - columns.push_back("plocation_id"); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType id; - kbd_dbms::CVarType desc; - kbd_dbms::CVarType tag; - kbd_dbms::CVarType type; - kbd_dbms::CVarType pid; - result.getColumnValue(nIndex, 0, id); - result.getColumnValue(nIndex, 1, desc); - result.getColumnValue(nIndex, 2, tag); - result.getColumnValue(nIndex, 3, type); - result.getColumnValue(nIndex, 4, pid); - - if(m_listPermLocationId.contains(id.toInt())) - { - m_locationPermDescriptionMap[id.toInt()] = QString::fromStdString(desc.toStdString()); - m_listPermLocationOrder.push_back(id.toInt()); - } - m_locationDescriptionMap[id.toInt()] = QString::fromStdString(desc.toStdString()); - - - SAreaInfo info; - info.nId =id.toInt(); - info.stTag =QString::fromStdString(tag.toStdString()); - info.stDes =QString::fromStdString(desc.toStdString()); - if(type.toInt() != (int)E_LOCATION_NODE) - { - info.eType = E_LOCATION_AREA; - }else - { - info.eType = E_LOCATION_NODE; - } - - info.nPareaId =pid.toInt(); - m_areaInfoMap[info.nId] = info; - } - } - } - - QMap::iterator it= m_areaInfoMap.begin(); - while (it != m_areaInfoMap.end()) { - if(m_listPermLocationId.contains(it.key())) - { - if(it.value().eType == (int)E_LOCATION_NODE) - { - QMap >::iterator pos = m_areaLocMap.find(it.value().nPareaId); - if(pos == m_areaLocMap.end()) - { - QVector locVec; - locVec.append(it.value().nId); - m_areaLocMap.insert(it.value().nPareaId,locVec); - }else - { - QVector &locVec = pos.value(); - locVec.append(it.value().nId); - } - }else - { - QMap >::iterator pos = m_areaLocMap.find(it.key()); - if(pos == m_areaLocMap.end()) - { - QVector locVec; - locVec.append(it.value().nId); - m_areaLocMap.insert(it.key(),locVec); - }else - { - QVector &locVec = pos.value(); - locVec.append(it.value().nId); - } - } - } - it++; - } -} - -void CAlarmBaseData::loadRegionDescription() -{ - if(m_rtdbAccess->open("base", "region_info")) - { - m_regionDescriptionMap.clear(); - m_regionPermDescriptionMap.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("region_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - if(m_listPermRegionId.contains(key.toInt())) - { - m_regionPermDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - m_regionDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - m_regionPermDescriptionMap[-1] = QString(); - m_regionDescriptionMap[-1] = QString(); -} - -void CAlarmBaseData::loadAlarmTypeDescription() -{ - if(m_rtdbAccess->open("base", "alarm_type_define")) - { - m_alarmTypeDescriptionMap.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("type_id"); - columns.push_back("type_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmBaseData::loadAlarmStatusDescription() -{ - if(m_rtdbAccess->open("base", "alarm_status_define")) - { - m_alarmStatusDescriptionMap.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("status_value"); - columns.push_back("display_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmStatusDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmBaseData::loadDeviceTypeDescription() -{ - if(m_rtdbAccess->open("base", "dev_type_def")) - { - m_deviceTypeDescriptionMap.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("dev_type_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmBaseData::loadDeviceGroupDescription() -{ - if(m_rtdbAccess->open("base", "dev_group")) - { - m_deviceGroupDescriptionMap.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("tag_name"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmBaseData::loadAlarmShowStatusDescription() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - m_alarmShowStatusDescriptionMap.clear(); - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - std::string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - if(StringToInt(strKey) != OTHERSTATUS) - { - m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; - }else - { - m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = tr("其他"); - } - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -void CAlarmBaseData::loadAlarmOtherStatusDescription() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - m_alarmOtherStatusDescriptionMap.clear(); - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - m_alarmOtherStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -bool CAlarmBaseData::queryAllDeviceDevGroup(kbd_dbms::CRdbNetApi &rdbNetApi, const QString &devg, QList &devList) -{ - //< 查询设备组所有设备 - kbd_idlfile::RdbQuery msgQuery; - msgQuery.set_strtablename("dev_info"); - msgQuery.add_strselectcolnamearr("tag_name"); - kbd_idlfile::RdbCondition *pCondtion = msgQuery.add_msgcondition(); - pCondtion->set_enlogic(kbd_idlfile::ENConditionLogic::enumCondAnd); - pCondtion->set_enrelation(kbd_idlfile::ENConditionRelation::enumCondEqual); - pCondtion->set_strcolumnname("group_tag_name"); - kbd_idlfile::SVariable *pCondValue = pCondtion->mutable_msgvalue(); - pCondValue->set_edatatype(kbd_idlfile::DataType::CN_DATATYPE_STRING); - pCondValue->set_strvalue(devg.toStdString()); - - kbd_idlfile::RdbRet retMsg; - bool bRet; - bRet = rdbNetApi.query(msgQuery, retMsg); - if (false == bRet) - { - LOGERROR("queryAllDeviceDevGroup,未查询到条目"); - return false; - } - else - { - for (int i = 0; i < retMsg.msgrecord_size(); ++i) - { - if(retMsg.msgrecord(i).msgvaluearray_size() != 1) - { - LOGERROR("queryAllDeviceDevGroup,查询结果不对"); - continue; - } - - devList.append(QString::fromStdString(retMsg.msgrecord(i).msgvaluearray(0).strvalue())); - } - } - return true; -} - -bool CAlarmBaseData::queryAllPointDevice(kbd_dbms::CRdbNetApi &rdbNetApi, const QString &device, const QString &table, QList &pointList) -{ - kbd_idlfile::RdbQuery msgQuery; - msgQuery.set_strtablename(table.toStdString().c_str()); - msgQuery.add_strselectcolnamearr("tag_name"); - kbd_idlfile::RdbCondition *pCondtion = msgQuery.add_msgcondition(); - pCondtion->set_enlogic(kbd_idlfile::ENConditionLogic::enumCondAnd); - pCondtion->set_enrelation(kbd_idlfile::ENConditionRelation::enumCondEqual); - pCondtion->set_strcolumnname("device"); - kbd_idlfile::SVariable *pCondValue = pCondtion->mutable_msgvalue(); - pCondValue->set_edatatype(kbd_idlfile::DataType::CN_DATATYPE_STRING); - pCondValue->set_strvalue(device.toStdString().c_str()); - - kbd_idlfile::RdbRet retMsg; - bool bRet; - bRet = rdbNetApi.query(msgQuery, retMsg); - if (false == bRet) - { - LOGERROR("queryAllPointDevice,未查询到条目"); - return false; - } - else - { - for (int i = 0; i < retMsg.msgrecord_size(); ++i) - { - if(retMsg.msgrecord(i).msgvaluearray_size() != 1) - { - LOGERROR("queryAllPointDevice,查询结果不对"); - continue; - } - - pointList.append(QString("%1.%2.%3").arg(table) - .arg(QString::fromStdString(retMsg.msgrecord(i).msgvaluearray(0).strvalue())) - .arg("value")); - } - } - return true; -} +#include "CAlarmBaseData.h" +#include "perm_mng_api/PermMngApi.h" +#include "CAlarmCommon.h" +#include "pub_logger_api/logger.h" +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" + +using namespace kbd_public; +using namespace std; + +CAlarmBaseData *CAlarmBaseData::pInstance = NULL; +CAlarmBaseData *CAlarmBaseData::instance() +{ + if(pInstance == NULL) + { + pInstance = new CAlarmBaseData(); + } + return pInstance; +} + +CAlarmBaseData::~CAlarmBaseData() +{ + LOGDEBUG("~CAlarmBaseData()"); +} + +void CAlarmBaseData::destory() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + + m_rtdbAccess = Q_NULLPTR; + pInstance = NULL; + deleteLater(); +} + +void CAlarmBaseData::initData() +{ + loadPermInfo(); + loadAlarmInfoConfig(); +} + +QString CAlarmBaseData::queryPriorityDesc(int id) +{ + return m_priorityDescriptionMap.value(id,QString()); +} + +QString CAlarmBaseData::queryLocationDesc(int id) +{ + return m_locationDescriptionMap.value(id,QString()); +} + +QString CAlarmBaseData::queryRegionDesc(int id) +{ + return m_regionDescriptionMap.value(id,QString()); +} + +QString CAlarmBaseData::queryAlarmTypeDesc(int id) +{ + return m_alarmTypeDescriptionMap.value(id,QString()); +} + +QString CAlarmBaseData::queryAlarmStatusDesc(int id) +{ + return m_alarmStatusDescriptionMap.value(id,QString()); +} + +int CAlarmBaseData::queryDevTypeByDesc(QString &desc) +{ + return m_deviceTypeDescriptionMap.key(desc); +} + +QList CAlarmBaseData::getDevGroupTagList() +{ + return m_deviceGroupDescriptionMap.keys(); +} + +QMap CAlarmBaseData::getAlarmOtherStatus() +{ + return m_alarmOtherStatusDescriptionMap; +} + +CAlarmBaseData::CAlarmBaseData(QObject *parent) : + QObject(parent), + m_rtdbAccess(Q_NULLPTR) +{ + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); + m_pWriteDb->open(); + createSysInfoInstance(m_ptrSysInfo); + initData(); +} + +void CAlarmBaseData::loadPermInfo() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecRegionId; + std::vector vecLocationId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_VIEW, vecRegionId, vecLocationId)) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listPermLocationId.append(*location++); + } + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listPermRegionId.append(*region++); + } + } + } +} + +void CAlarmBaseData::loadAlarmInfoConfig() +{ + loadPriorityDescription(); + loadLocationDescription(); + loadRegionDescription(); + loadAlarmTypeDescription(); + loadAlarmStatusDescription(); + loadDeviceTypeDescription(); + loadDeviceGroupDescription(); + loadAlarmShowStatusDescription(); + loadAlarmOtherStatusDescription(); +} + +int CAlarmBaseData::queryDomainIdByLocId(int loactionId) +{ + if(m_ptrSysInfo) + { + SLocationInfo stLocationInfo; + if(kbdSuccess == m_ptrSysInfo->getLocationInfoById(loactionId, stLocationInfo)) + { + return stLocationInfo.nDomainId; + } + } + return CN_InvalidDomainId; +} + +bool CAlarmBaseData::queryAllPointDevGroup(int nDomainId, int nSubsystemId, const QString &strDevg, QList &pointList) +{ + if(!m_ptrSysInfo) + { + return false; + } + SAppInfo stAppInfo; + if(kbdSuccess != m_ptrSysInfo->getAppInfoBySubsystemId(nSubsystemId, stAppInfo)) + { + LOGERROR("queryAllPointDevGroup 获取应用ID失败"); + return false; + } + kbd_dbms::CRdbNetApi rdbNetApi; + rdbNetApi.connect(nDomainId, stAppInfo.nId); + + //< 查询所有设备 + QList devList; + if(!queryAllDeviceDevGroup(rdbNetApi, strDevg, devList)) + { + return false; + } + + //< 查询所有测点 + for(int n(0); n CAlarmBaseData::getPriorityMap() +{ + return m_priorityDescriptionMap; +} + +QMap CAlarmBaseData::getPermPriorityMap() +{ + return m_priorityPermDescriptionMap; +} + +QMap CAlarmBaseData::getPriorityOrderMap() +{ + return m_priorityOrderDescriptionMap; +} + +QMap CAlarmBaseData::getPermLocationMap() +{ + return m_locationPermDescriptionMap; +} + +QMap CAlarmBaseData::getPermRegionMap() +{ + return m_regionPermDescriptionMap; +} + +QMap CAlarmBaseData::getAlarmShowStatusMap() +{ + return m_alarmShowStatusDescriptionMap; +} + +QMap > CAlarmBaseData::getAreaLocMap() +{ + return m_areaLocMap; +} + +QMap CAlarmBaseData::getAreaInfoMap() +{ + return m_areaInfoMap; +} + +QList CAlarmBaseData::getPermLocationIdList() +{ + return m_listPermLocationId; +} + +QList CAlarmBaseData::getPermRegionIdList() +{ + return m_listPermRegionId; +} + +QList CAlarmBaseData::getPermLocationOrder() +{ + return m_listPermLocationOrder; +} + +QString CAlarmBaseData::getPermLocationDesc(const int &locationId) +{ + return m_locationPermDescriptionMap.value(locationId); +} + +void CAlarmBaseData::loadPriorityDescription() +{ + if(m_rtdbAccess->open("base", "alarm_level_define")) + { + m_priorityDescriptionMap.clear(); + m_priorityOrderDescriptionMap.clear(); + m_priorityPermDescriptionMap.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("priority_id"); + columns.push_back("priority_order"); + columns.push_back("priority_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType order; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, order); + result.getColumnValue(nIndex, 2, value); + if(key.toInt() != 0 ) + { + m_priorityPermDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + m_priorityOrderDescriptionMap[order.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadLocationDescription() +{ + m_areaInfoMap.clear(); + m_areaLocMap.clear(); + if(m_rtdbAccess->open("base", "sys_model_location_info")) + { + m_locationDescriptionMap.clear(); + m_locationPermDescriptionMap.clear(); + m_listPermLocationOrder.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("description"); + columns.push_back("tag_name"); + columns.push_back("location_type"); + columns.push_back("plocation_id"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType id; + kbd_dbms::CVarType desc; + kbd_dbms::CVarType tag; + kbd_dbms::CVarType type; + kbd_dbms::CVarType pid; + result.getColumnValue(nIndex, 0, id); + result.getColumnValue(nIndex, 1, desc); + result.getColumnValue(nIndex, 2, tag); + result.getColumnValue(nIndex, 3, type); + result.getColumnValue(nIndex, 4, pid); + + if(m_listPermLocationId.contains(id.toInt())) + { + m_locationPermDescriptionMap[id.toInt()] = QString::fromStdString(desc.toStdString()); + m_listPermLocationOrder.push_back(id.toInt()); + } + m_locationDescriptionMap[id.toInt()] = QString::fromStdString(desc.toStdString()); + + + SAreaInfo info; + info.nId =id.toInt(); + info.stTag =QString::fromStdString(tag.toStdString()); + info.stDes =QString::fromStdString(desc.toStdString()); + if(type.toInt() != (int)E_LOCATION_NODE) + { + info.eType = E_LOCATION_AREA; + }else + { + info.eType = E_LOCATION_NODE; + } + + info.nPareaId =pid.toInt(); + m_areaInfoMap[info.nId] = info; + } + } + } + + QMap::iterator it= m_areaInfoMap.begin(); + while (it != m_areaInfoMap.end()) { + if(m_listPermLocationId.contains(it.key())) + { + if(it.value().eType == (int)E_LOCATION_NODE) + { + QMap >::iterator pos = m_areaLocMap.find(it.value().nPareaId); + if(pos == m_areaLocMap.end()) + { + QVector locVec; + locVec.append(it.value().nId); + m_areaLocMap.insert(it.value().nPareaId,locVec); + }else + { + QVector &locVec = pos.value(); + locVec.append(it.value().nId); + } + }else + { + QMap >::iterator pos = m_areaLocMap.find(it.key()); + if(pos == m_areaLocMap.end()) + { + QVector locVec; + locVec.append(it.value().nId); + m_areaLocMap.insert(it.key(),locVec); + }else + { + QVector &locVec = pos.value(); + locVec.append(it.value().nId); + } + } + } + it++; + } +} + +void CAlarmBaseData::loadRegionDescription() +{ + if(m_rtdbAccess->open("base", "region_info")) + { + m_regionDescriptionMap.clear(); + m_regionPermDescriptionMap.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("region_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + if(m_listPermRegionId.contains(key.toInt())) + { + m_regionPermDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + m_regionDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + m_regionPermDescriptionMap[-1] = QString(); + m_regionDescriptionMap[-1] = QString(); +} + +void CAlarmBaseData::loadAlarmTypeDescription() +{ + if(m_rtdbAccess->open("base", "alarm_type_define")) + { + m_alarmTypeDescriptionMap.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("type_id"); + columns.push_back("type_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadAlarmStatusDescription() +{ + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + m_alarmStatusDescriptionMap.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("status_value"); + columns.push_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadDeviceTypeDescription() +{ + if(m_rtdbAccess->open("base", "dev_type_def")) + { + m_deviceTypeDescriptionMap.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("dev_type_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadDeviceGroupDescription() +{ + if(m_rtdbAccess->open("base", "dev_group")) + { + m_deviceGroupDescriptionMap.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("tag_name"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadAlarmShowStatusDescription() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + m_alarmShowStatusDescriptionMap.clear(); + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + std::string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + if(StringToInt(strKey) != OTHERSTATUS) + { + m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; + }else + { + m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = tr("其他"); + } + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CAlarmBaseData::loadAlarmOtherStatusDescription() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + m_alarmOtherStatusDescriptionMap.clear(); + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + m_alarmOtherStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +bool CAlarmBaseData::queryAllDeviceDevGroup(kbd_dbms::CRdbNetApi &rdbNetApi, const QString &devg, QList &devList) +{ + //< 查询设备组所有设备 + kbd_idlfile::RdbQuery msgQuery; + msgQuery.set_strtablename("dev_info"); + msgQuery.add_strselectcolnamearr("tag_name"); + kbd_idlfile::RdbCondition *pCondtion = msgQuery.add_msgcondition(); + pCondtion->set_enlogic(kbd_idlfile::ENConditionLogic::enumCondAnd); + pCondtion->set_enrelation(kbd_idlfile::ENConditionRelation::enumCondEqual); + pCondtion->set_strcolumnname("group_tag_name"); + kbd_idlfile::SVariable *pCondValue = pCondtion->mutable_msgvalue(); + pCondValue->set_edatatype(kbd_idlfile::DataType::CN_DATATYPE_STRING); + pCondValue->set_strvalue(devg.toStdString()); + + kbd_idlfile::RdbRet retMsg; + bool bRet; + bRet = rdbNetApi.query(msgQuery, retMsg); + if (false == bRet) + { + LOGERROR("queryAllDeviceDevGroup,未查询到条目"); + return false; + } + else + { + for (int i = 0; i < retMsg.msgrecord_size(); ++i) + { + if(retMsg.msgrecord(i).msgvaluearray_size() != 1) + { + LOGERROR("queryAllDeviceDevGroup,查询结果不对"); + continue; + } + + devList.append(QString::fromStdString(retMsg.msgrecord(i).msgvaluearray(0).strvalue())); + } + } + return true; +} + +bool CAlarmBaseData::queryAllPointDevice(kbd_dbms::CRdbNetApi &rdbNetApi, const QString &device, const QString &table, QList &pointList) +{ + kbd_idlfile::RdbQuery msgQuery; + msgQuery.set_strtablename(table.toStdString().c_str()); + msgQuery.add_strselectcolnamearr("tag_name"); + kbd_idlfile::RdbCondition *pCondtion = msgQuery.add_msgcondition(); + pCondtion->set_enlogic(kbd_idlfile::ENConditionLogic::enumCondAnd); + pCondtion->set_enrelation(kbd_idlfile::ENConditionRelation::enumCondEqual); + pCondtion->set_strcolumnname("device"); + kbd_idlfile::SVariable *pCondValue = pCondtion->mutable_msgvalue(); + pCondValue->set_edatatype(kbd_idlfile::DataType::CN_DATATYPE_STRING); + pCondValue->set_strvalue(device.toStdString().c_str()); + + kbd_idlfile::RdbRet retMsg; + bool bRet; + bRet = rdbNetApi.query(msgQuery, retMsg); + if (false == bRet) + { + LOGERROR("queryAllPointDevice,未查询到条目"); + return false; + } + else + { + for (int i = 0; i < retMsg.msgrecord_size(); ++i) + { + if(retMsg.msgrecord(i).msgvaluearray_size() != 1) + { + LOGERROR("queryAllPointDevice,查询结果不对"); + continue; + } + + pointList.append(QString("%1.%2.%3").arg(table) + .arg(QString::fromStdString(retMsg.msgrecord(i).msgvaluearray(0).strvalue())) + .arg("value")); + } + } + return true; +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.h b/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.h index e143eef4..39bcc5dd 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.h @@ -1,197 +1,197 @@ -#ifndef CALARMBASEDATA_H -#define CALARMBASEDATA_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/rdb_net_api/CRdbNetApi.h" -#include "dbms/db_api_ex/CDbApi.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include -#include "CAlarmCommon.h" -#include - -class CAlarmBaseData : public QObject -{ - Q_OBJECT -public: - static CAlarmBaseData * instance(); - - ~CAlarmBaseData(); - - void destory(); - -public: - /** - * @brief initData 初始化数据 - */ - void initData(); - /** - * @brief queryPriorityDesc 根据id查询优先级描述 - * @param id 优先级id - * @return 优先级描述 - */ - QString queryPriorityDesc(int id); - /** - * @brief queryLocationDesc 根据位置id查询位置描述 - * @param id 位置id - * @return 位置描述 - */ - QString queryLocationDesc(int id); - /** - * @brief queryRegionDesc 根据责任区id查询责任区描述 - * @param id 责任区id - * @return 责任区描述 - */ - QString queryRegionDesc(int id); - /** - * @brief queryAlarmTypeDesc 根据告警类型id查询告警类型描述 - * @param id 告警类型id - * @return 告警类型描述 - */ - QString queryAlarmTypeDesc(int id); - /** - * @brief queryAlarmStatusDesc 根据告警状态id查询告警状态描述 - * @param id 告警状态id - * @return 告警状态描述 - */ - QString queryAlarmStatusDesc(int id); - /** - * @brief queryDevTypeByDesc 根据设备类型描述查询设备类型id - * @param desc 设备描述 - * @return 设备id - */ - int queryDevTypeByDesc(QString &desc); - - QList getDevGroupTagList(); - /** - * @brief getAlarmOtherStatus 获取其他告警状态集合 - * @return 其他告警状态集合 - */ - QMap getAlarmOtherStatus(); - /** - * @brief loadAlarmInfoConfig 加载告警配置信息 - */ - void loadAlarmInfoConfig(); - - /** - * @brief queryDomainIdByLocId 通过车站ID得到域ID - * @param loactionId - */ - int queryDomainIdByLocId(int loactionId); - - bool queryAllPointDevGroup(int nDomainId, int nSubsystemId, const QString &strDevg, QList &pointList); - - QMap getPriorityMap(); - - QMap getPermPriorityMap(); - - QMap getPriorityOrderMap(); - - QMap getPermLocationMap(); - - QMap getPermRegionMap(); - - QMap getAlarmShowStatusMap(); - - QMap > getAreaLocMap(); - - QMap getAreaInfoMap(); - - QList getPermLocationIdList(); - - QList getPermRegionIdList(); - - QList getPermLocationOrder(); - - QString getPermLocationDesc(const int &locationId); - -private: - explicit CAlarmBaseData(QObject *parent = nullptr); - /** - * @brief loadPermInfo 加载权限 - */ - void loadPermInfo(); - - /** - * @brief loadPriorityDescription 加载优先级描述 - */ - void loadPriorityDescription(); - /** - * @brief loadLocationDescription 加载位置描述 - */ - void loadLocationDescription(); - /** - * @brief loadRegionDescription 加载责任区描述 - */ - void loadRegionDescription(); - /** - * @brief loadAlarmTypeDescription 加载告警类型 - */ - void loadAlarmTypeDescription(); - /** - * @brief loadAlarmStatusDescription 加载告警状态描述 - */ - void loadAlarmStatusDescription(); - /** - * @brief loadDeviceTypeDescription 加载设备类型描述 - */ - void loadDeviceTypeDescription(); - /** - * @brief loadDeviceGroupDescription 加载设备组描述 - */ - void loadDeviceGroupDescription(); - /** - * @brief loadAlarmShowStatusDescription 加载需要显示在告警窗下拉框中的告警状态描述 - */ - void loadAlarmShowStatusDescription(); - /** - * @brief loadAlarmOtherStatusDescription 加载其他告警状态描述 - */ - void loadAlarmOtherStatusDescription(); - - /** - * @brief queryAllDeviceDevGroup 查询设备组下所有设备 - * @param rdbNetApi - * @param devg - */ - bool queryAllDeviceDevGroup(kbd_dbms::CRdbNetApi &rdbNetApi, const QString &devg, QList &devList); - /** - * @brief queryAllPointDevice 查询表中设备下所有测点 - * @param rdbNetApi - * @param device - * @param table - * @param pointList "digital.station.G01_dlq.r.value" - * @return - */ - bool queryAllPointDevice(kbd_dbms::CRdbNetApi &rdbNetApi, const QString &device, const QString &table, QList &pointList); - -private: - static CAlarmBaseData * pInstance; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CDbApi *m_pWriteDb; - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; - QList m_listPermLocationId; //< 原始告警车站权限 - QList m_listPermRegionId; //< 原始告警责任区权限 - QList m_listPermLocationOrder; //< 有权限的loaction_id: 按location_no排序 - - QMap m_priorityDescriptionMap; - QMap m_priorityPermDescriptionMap; - QMap m_priorityOrderDescriptionMap; - QMap m_locationDescriptionMap; - QMap m_regionDescriptionMap; - QMap m_locationPermDescriptionMap; //有权限的 - QMap m_regionPermDescriptionMap; //有权限的 - QMap m_alarmTypeDescriptionMap; - QMap m_alarmStatusDescriptionMap; - QMap m_deviceTypeDescriptionMap; - QMap m_deviceGroupDescriptionMap; - QMap m_alarmShowStatusDescriptionMap; - QMap m_alarmOtherStatusDescriptionMap; - - - QMap m_areaInfoMap; //区域信息 - - QMap > m_areaLocMap; //区域映射 -}; - -#endif // CALARMBASEDATA_H +#ifndef CALARMBASEDATA_H +#define CALARMBASEDATA_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_net_api/CRdbNetApi.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include +#include "CAlarmCommon.h" +#include + +class CAlarmBaseData : public QObject +{ + Q_OBJECT +public: + static CAlarmBaseData * instance(); + + ~CAlarmBaseData(); + + void destory(); + +public: + /** + * @brief initData 初始化数据 + */ + void initData(); + /** + * @brief queryPriorityDesc 根据id查询优先级描述 + * @param id 优先级id + * @return 优先级描述 + */ + QString queryPriorityDesc(int id); + /** + * @brief queryLocationDesc 根据位置id查询位置描述 + * @param id 位置id + * @return 位置描述 + */ + QString queryLocationDesc(int id); + /** + * @brief queryRegionDesc 根据责任区id查询责任区描述 + * @param id 责任区id + * @return 责任区描述 + */ + QString queryRegionDesc(int id); + /** + * @brief queryAlarmTypeDesc 根据告警类型id查询告警类型描述 + * @param id 告警类型id + * @return 告警类型描述 + */ + QString queryAlarmTypeDesc(int id); + /** + * @brief queryAlarmStatusDesc 根据告警状态id查询告警状态描述 + * @param id 告警状态id + * @return 告警状态描述 + */ + QString queryAlarmStatusDesc(int id); + /** + * @brief queryDevTypeByDesc 根据设备类型描述查询设备类型id + * @param desc 设备描述 + * @return 设备id + */ + int queryDevTypeByDesc(QString &desc); + + QList getDevGroupTagList(); + /** + * @brief getAlarmOtherStatus 获取其他告警状态集合 + * @return 其他告警状态集合 + */ + QMap getAlarmOtherStatus(); + /** + * @brief loadAlarmInfoConfig 加载告警配置信息 + */ + void loadAlarmInfoConfig(); + + /** + * @brief queryDomainIdByLocId 通过车站ID得到域ID + * @param loactionId + */ + int queryDomainIdByLocId(int loactionId); + + bool queryAllPointDevGroup(int nDomainId, int nSubsystemId, const QString &strDevg, QList &pointList); + + QMap getPriorityMap(); + + QMap getPermPriorityMap(); + + QMap getPriorityOrderMap(); + + QMap getPermLocationMap(); + + QMap getPermRegionMap(); + + QMap getAlarmShowStatusMap(); + + QMap > getAreaLocMap(); + + QMap getAreaInfoMap(); + + QList getPermLocationIdList(); + + QList getPermRegionIdList(); + + QList getPermLocationOrder(); + + QString getPermLocationDesc(const int &locationId); + +private: + explicit CAlarmBaseData(QObject *parent = nullptr); + /** + * @brief loadPermInfo 加载权限 + */ + void loadPermInfo(); + + /** + * @brief loadPriorityDescription 加载优先级描述 + */ + void loadPriorityDescription(); + /** + * @brief loadLocationDescription 加载位置描述 + */ + void loadLocationDescription(); + /** + * @brief loadRegionDescription 加载责任区描述 + */ + void loadRegionDescription(); + /** + * @brief loadAlarmTypeDescription 加载告警类型 + */ + void loadAlarmTypeDescription(); + /** + * @brief loadAlarmStatusDescription 加载告警状态描述 + */ + void loadAlarmStatusDescription(); + /** + * @brief loadDeviceTypeDescription 加载设备类型描述 + */ + void loadDeviceTypeDescription(); + /** + * @brief loadDeviceGroupDescription 加载设备组描述 + */ + void loadDeviceGroupDescription(); + /** + * @brief loadAlarmShowStatusDescription 加载需要显示在告警窗下拉框中的告警状态描述 + */ + void loadAlarmShowStatusDescription(); + /** + * @brief loadAlarmOtherStatusDescription 加载其他告警状态描述 + */ + void loadAlarmOtherStatusDescription(); + + /** + * @brief queryAllDeviceDevGroup 查询设备组下所有设备 + * @param rdbNetApi + * @param devg + */ + bool queryAllDeviceDevGroup(kbd_dbms::CRdbNetApi &rdbNetApi, const QString &devg, QList &devList); + /** + * @brief queryAllPointDevice 查询表中设备下所有测点 + * @param rdbNetApi + * @param device + * @param table + * @param pointList "digital.station.G01_dlq.r.value" + * @return + */ + bool queryAllPointDevice(kbd_dbms::CRdbNetApi &rdbNetApi, const QString &device, const QString &table, QList &pointList); + +private: + static CAlarmBaseData * pInstance; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CDbApi *m_pWriteDb; + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; + QList m_listPermLocationId; //< 原始告警车站权限 + QList m_listPermRegionId; //< 原始告警责任区权限 + QList m_listPermLocationOrder; //< 有权限的loaction_id: 按location_no排序 + + QMap m_priorityDescriptionMap; + QMap m_priorityPermDescriptionMap; + QMap m_priorityOrderDescriptionMap; + QMap m_locationDescriptionMap; + QMap m_regionDescriptionMap; + QMap m_locationPermDescriptionMap; //有权限的 + QMap m_regionPermDescriptionMap; //有权限的 + QMap m_alarmTypeDescriptionMap; + QMap m_alarmStatusDescriptionMap; + QMap m_deviceTypeDescriptionMap; + QMap m_deviceGroupDescriptionMap; + QMap m_alarmShowStatusDescriptionMap; + QMap m_alarmOtherStatusDescriptionMap; + + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 +}; + +#endif // CALARMBASEDATA_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmColorInfo.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmColorInfo.cpp index d3a38b78..023dd0cb 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmColorInfo.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmColorInfo.cpp @@ -1,6 +1,6 @@ -#include "CAlarmColorInfo.h" - -CAlarmColorInfo::CAlarmColorInfo() -{ - -} +#include "CAlarmColorInfo.h" + +CAlarmColorInfo::CAlarmColorInfo() +{ + +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmColorInfo.h b/product/src/gui/plugin/AlarmWidget/CAlarmColorInfo.h index 1d05cb0e..79146fc2 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmColorInfo.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmColorInfo.h @@ -1,21 +1,21 @@ -#ifndef CALARMCOLORINFO_H -#define CALARMCOLORINFO_H - -#include - -class CAlarmColorInfo -{ -public: - CAlarmColorInfo(); - - int priority; - QColor background_color; - QColor alternating_color; - QColor confirm_color; - QColor active_text_color; - QColor resume_text_color; - QColor confirm_text_color; - QString icon; -}; - -#endif // CALARMCOLORINFO_H +#ifndef CALARMCOLORINFO_H +#define CALARMCOLORINFO_H + +#include + +class CAlarmColorInfo +{ +public: + CAlarmColorInfo(); + + int priority; + QColor background_color; + QColor alternating_color; + QColor confirm_color; + QColor active_text_color; + QColor resume_text_color; + QColor confirm_text_color; + QString icon; +}; + +#endif // CALARMCOLORINFO_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.cpp index 30bc028c..3b55c115 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.cpp @@ -1,129 +1,129 @@ -#include "CAlarmColorWidget.h" -#include "ui_CAlarmColorWidget.h" -#include -#include "CAlarmSetMng.h" - -CAlarmColorWidget::CAlarmColorWidget(CAlarmColorInfo *info, QWidget *parent) : - QWidget(parent), - ui(new Ui::CAlarmColorWidget), - m_info(info) -{ - ui->setupUi(this); - ui->label_2->installEventFilter(this); - ui->label_4->installEventFilter(this); - ui->label_6->installEventFilter(this); - ui->label_9->installEventFilter(this); - - QString title = CAlarmSetMng::instance()->getPriorityDescByOrder(m_info->priority); - title+=":"; - ui->label_7->setText(title); - updateColorLabel(ui->label_2, m_info->active_text_color); - updateColorLabel(ui->label_4, m_info->resume_text_color); - updateColorLabel(ui->label_6, m_info->confirm_text_color); - updateColorLabel(ui->label_9, m_info->alternating_color); -} - -CAlarmColorWidget::~CAlarmColorWidget() -{ - delete ui; -} - -bool CAlarmColorWidget::eventFilter(QObject *watched, QEvent *event) -{ - if(watched == ui->label_2) - { - if(event->type() == QMouseEvent::MouseButtonPress) - { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == Qt::LeftButton) - { - chooseColor(ui->label_2, &(m_info->active_text_color)); - }else - { - return false; - } - }else - { - return false; - } - }else if(watched == ui->label_4) - { - if(event->type() == QMouseEvent::MouseButtonPress) - { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == Qt::LeftButton) - { - chooseColor(ui->label_4, &(m_info->resume_text_color)); - }else - { - return false; - } - }else - { - return false; - } - }else if(watched == ui->label_6) - { - if(event->type() == QMouseEvent::MouseButtonPress) - { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == Qt::LeftButton) - { - chooseColor(ui->label_6, &(m_info->confirm_text_color)); - }else - { - return false; - } - }else - { - return false; - } - }else if(watched == ui->label_9) - { - if(event->type() == QMouseEvent::MouseButtonPress) - { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == Qt::LeftButton) - { - chooseColor(ui->label_9, &(m_info->alternating_color)); - }else - { - return false; - } - }else - { - return false; - } - }else - { - return QWidget::eventFilter(watched,event); - } - return true; -} - -void CAlarmColorWidget::chooseColor(QLabel *label, QColor *color) -{ - QColor newColor=QColorDialog::getColor(*color,this); - if(newColor.isValid()){ - *color=newColor; - updateColorLabel(label,*color); - } -} - -void CAlarmColorWidget::updateColorLabel(QLabel *label, const QColor &color) -{ - label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(color.red()).arg(color.green()).arg(color.blue())); - if(label == ui->label_2) - { - m_info->active_text_color = color; - }else if(label == ui->label_4) - { - m_info->resume_text_color = color; - }else if(label == ui->label_6) - { - m_info->confirm_text_color = color; - }else if(label == ui->label_9) - { - m_info->alternating_color = color; - } -} +#include "CAlarmColorWidget.h" +#include "ui_CAlarmColorWidget.h" +#include +#include "CAlarmSetMng.h" + +CAlarmColorWidget::CAlarmColorWidget(CAlarmColorInfo *info, QWidget *parent) : + QWidget(parent), + ui(new Ui::CAlarmColorWidget), + m_info(info) +{ + ui->setupUi(this); + ui->label_2->installEventFilter(this); + ui->label_4->installEventFilter(this); + ui->label_6->installEventFilter(this); + ui->label_9->installEventFilter(this); + + QString title = CAlarmSetMng::instance()->getPriorityDescByOrder(m_info->priority); + title+=":"; + ui->label_7->setText(title); + updateColorLabel(ui->label_2, m_info->active_text_color); + updateColorLabel(ui->label_4, m_info->resume_text_color); + updateColorLabel(ui->label_6, m_info->confirm_text_color); + updateColorLabel(ui->label_9, m_info->alternating_color); +} + +CAlarmColorWidget::~CAlarmColorWidget() +{ + delete ui; +} + +bool CAlarmColorWidget::eventFilter(QObject *watched, QEvent *event) +{ + if(watched == ui->label_2) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_2, &(m_info->active_text_color)); + }else + { + return false; + } + }else + { + return false; + } + }else if(watched == ui->label_4) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_4, &(m_info->resume_text_color)); + }else + { + return false; + } + }else + { + return false; + } + }else if(watched == ui->label_6) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_6, &(m_info->confirm_text_color)); + }else + { + return false; + } + }else + { + return false; + } + }else if(watched == ui->label_9) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_9, &(m_info->alternating_color)); + }else + { + return false; + } + }else + { + return false; + } + }else + { + return QWidget::eventFilter(watched,event); + } + return true; +} + +void CAlarmColorWidget::chooseColor(QLabel *label, QColor *color) +{ + QColor newColor=QColorDialog::getColor(*color,this); + if(newColor.isValid()){ + *color=newColor; + updateColorLabel(label,*color); + } +} + +void CAlarmColorWidget::updateColorLabel(QLabel *label, const QColor &color) +{ + label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(color.red()).arg(color.green()).arg(color.blue())); + if(label == ui->label_2) + { + m_info->active_text_color = color; + }else if(label == ui->label_4) + { + m_info->resume_text_color = color; + }else if(label == ui->label_6) + { + m_info->confirm_text_color = color; + }else if(label == ui->label_9) + { + m_info->alternating_color = color; + } +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.h b/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.h index 37f37757..afa257e1 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.h @@ -1,31 +1,31 @@ -#ifndef CALARMCOLORWIDGET_H -#define CALARMCOLORWIDGET_H - -#include -#include -#include "CAlarmColorInfo.h" -#include - -namespace Ui { -class CAlarmColorWidget; -} - -class CAlarmColorWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CAlarmColorWidget(CAlarmColorInfo *info,QWidget *parent = 0); - ~CAlarmColorWidget(); - bool eventFilter(QObject *watched, QEvent *event); - -private: - void chooseColor(QLabel *label, QColor *color); - void updateColorLabel(QLabel *label, const QColor &color); - -private: - Ui::CAlarmColorWidget *ui; - CAlarmColorInfo *m_info; -}; - -#endif // CALARMCOLORWIDGET_H +#ifndef CALARMCOLORWIDGET_H +#define CALARMCOLORWIDGET_H + +#include +#include +#include "CAlarmColorInfo.h" +#include + +namespace Ui { +class CAlarmColorWidget; +} + +class CAlarmColorWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CAlarmColorWidget(CAlarmColorInfo *info,QWidget *parent = 0); + ~CAlarmColorWidget(); + bool eventFilter(QObject *watched, QEvent *event); + +private: + void chooseColor(QLabel *label, QColor *color); + void updateColorLabel(QLabel *label, const QColor &color); + +private: + Ui::CAlarmColorWidget *ui; + CAlarmColorInfo *m_info; +}; + +#endif // CALARMCOLORWIDGET_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.ui b/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.ui index f938749b..6acb5c24 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmColorWidget.ui @@ -1,151 +1,151 @@ - - - CAlarmColorWidget - - - - 0 - 0 - 455 - 36 - - - - Form - - - - 0 - - - 0 - - - 9 - - - - - - - 动作颜色 - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - - - - - - - - 恢复颜色 - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - - - - - - - - 确认颜色 - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - - - - - - - - 闪烁颜色 - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - - - - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - - 40 - 16777215 - - - - - - - - - - - - + + + CAlarmColorWidget + + + + 0 + 0 + 455 + 36 + + + + Form + + + + 0 + + + 0 + + + 9 + + + + + + + 动作颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + 恢复颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + 确认颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + 闪烁颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 40 + 16777215 + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmCommon.h b/product/src/gui/plugin/AlarmWidget/CAlarmCommon.h index fb5d9ca0..b361f6b6 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmCommon.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmCommon.h @@ -1,103 +1,103 @@ -#ifndef CALARMCOMMON_H -#define CALARMCOMMON_H - -#include -class CAlarmMsgInfo; -class CAiAlarmMsgInfo; - -typedef QSharedPointer AlarmMsgPtr; -typedef QSharedPointer AiAlarmMsgPtr; -typedef QPair > PAIRLISTALARMINFO; - - -const QString fun_ia_edit = "FUNC_NOM_IA_EDIT"; //智能告警编辑权限 -#define FUNC_SPE_ALARM_VIEW ("FUNC_SPE_ALARM_VIEW") -#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") - -#define VIDEO_TIME 30*1000 -#define FAULT_RECORD_TIME 30*1000 -#define BUTTON_COLUMN 8 //按钮所在列 -#define ICON_COLUMN 1 //图标所在列 -const int OTHERSTATUS = 9999; -//窗口 -enum E_Alarm_Mode -{ - E_Alarm_Dock, - E_Alarm_Window, - E_Alarm_Pop -}; -enum E_TAGNAME_TYPE -{ - E_TAGNAME_ANA =0, - E_TAGNAME_ACC, - E_TAGNAME_MIX, - E_TAGNAME_DIG, - E_TAGNAME_ERROR -}; -//排序 -enum E_ALARM_SORTKEY -{ - E_SORT_TIME=0, //< 时间戳 - E_SORT_PRIORITY , //< 优先级 - E_SORT_LOCATION, //< 车站 - E_SORT_REGION, //< 责任区 - E_SORT_TYPE, //< 告警类型 - E_SORT_ALM_STATE, //< 告警状态 - E_SORT_STYLE, //< 复归状态 - E_SORT_LOGICSTATE, //< 逻辑状态 - E_SORT_CONTENT //< 告警内容 -}; -//告警动作 -enum E_ALARM_SOUND_VOICE -{ - E_ALARM_SOUND = 0, //声音告警 - E_ALARM_VOICE //语音告警 -}; -//告警方式 -enum E_ALARM_STYLE{ - E_STYLE_REPEAT_X = -2, - E_STYLE_REPEAT = -1, - E_STYLE_NO_ALARM = 0 -}; - -enum E_LOCATION_TYPE -{ - E_LOCATION_NODE = 0, - E_LOCATION_AREA -}; - -struct SAiConfirm -{ - int nConfirm; - int nTotal; - SAiConfirm() { - nConfirm = 0; - nTotal = 0; - } -}; - -struct SAreaInfo -{ - int nId; - QString stTag; - QString stDes; - E_LOCATION_TYPE eType; - int nPareaId; - SAreaInfo() { - nId = -1; - stTag = QString(); - stDes = QString(); - eType = E_LOCATION_NODE; - nPareaId = -1; - } -}; - -struct SDevGroupInfo{ - QString tag_name; - QString description; - int domain; - int location; - int sub_system; - int region; -}; -#endif // CALARMCOMMON_H +#ifndef CALARMCOMMON_H +#define CALARMCOMMON_H + +#include +class CAlarmMsgInfo; +class CAiAlarmMsgInfo; + +typedef QSharedPointer AlarmMsgPtr; +typedef QSharedPointer AiAlarmMsgPtr; +typedef QPair > PAIRLISTALARMINFO; + + +const QString fun_ia_edit = "FUNC_NOM_IA_EDIT"; //智能告警编辑权限 +#define FUNC_SPE_ALARM_VIEW ("FUNC_SPE_ALARM_VIEW") +#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") + +#define VIDEO_TIME 30*1000 +#define FAULT_RECORD_TIME 30*1000 +#define BUTTON_COLUMN 8 //按钮所在列 +#define ICON_COLUMN 1 //图标所在列 +const int OTHERSTATUS = 9999; +//窗口 +enum E_Alarm_Mode +{ + E_Alarm_Dock, + E_Alarm_Window, + E_Alarm_Pop +}; +enum E_TAGNAME_TYPE +{ + E_TAGNAME_ANA =0, + E_TAGNAME_ACC, + E_TAGNAME_MIX, + E_TAGNAME_DIG, + E_TAGNAME_ERROR +}; +//排序 +enum E_ALARM_SORTKEY +{ + E_SORT_TIME=0, //< 时间戳 + E_SORT_PRIORITY , //< 优先级 + E_SORT_LOCATION, //< 车站 + E_SORT_REGION, //< 责任区 + E_SORT_TYPE, //< 告警类型 + E_SORT_ALM_STATE, //< 告警状态 + E_SORT_STYLE, //< 复归状态 + E_SORT_LOGICSTATE, //< 逻辑状态 + E_SORT_CONTENT //< 告警内容 +}; +//告警动作 +enum E_ALARM_SOUND_VOICE +{ + E_ALARM_SOUND = 0, //声音告警 + E_ALARM_VOICE //语音告警 +}; +//告警方式 +enum E_ALARM_STYLE{ + E_STYLE_REPEAT_X = -2, + E_STYLE_REPEAT = -1, + E_STYLE_NO_ALARM = 0 +}; + +enum E_LOCATION_TYPE +{ + E_LOCATION_NODE = 0, + E_LOCATION_AREA +}; + +struct SAiConfirm +{ + int nConfirm; + int nTotal; + SAiConfirm() { + nConfirm = 0; + nTotal = 0; + } +}; + +struct SAreaInfo +{ + int nId; + QString stTag; + QString stDes; + E_LOCATION_TYPE eType; + int nPareaId; + SAreaInfo() { + nId = -1; + stTag = QString(); + stDes = QString(); + eType = E_LOCATION_NODE; + nPareaId = -1; + } +}; + +struct SDevGroupInfo{ + QString tag_name; + QString description; + int domain; + int location; + int sub_system; + int region; +}; +#endif // CALARMCOMMON_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDataCollect.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmDataCollect.cpp index 6c4e77d2..0267401d 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDataCollect.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDataCollect.cpp @@ -1,356 +1,356 @@ -#include "CAlarmDataCollect.h" -#include -#include "pub_logger_api/logger.h" -#include "CAlarmMsgManage.h" -#include -#include "CAiAlarmDataCollect.h" -#include "alarm_server_api/AlarmCommonDef.h" - -using namespace kbd_service; -using namespace kbd_dbms; -CAlarmDataCollect * CAlarmDataCollect::m_pInstance = NULL; - -CAlarmDataCollect::CAlarmDataCollect() - : CAlmApiForAlmClt(), - m_referenceCount(0), - m_bFaultRecallState(false), - m_pAlternateTimer(Q_NULLPTR), m_rtdbAlmLvlDefTab(nullptr), m_rtdbAlmActDefTab(nullptr), - m_bIsNeedUpdate(false), - m_bIsNeedRemove(false), m_bIsNeedRelease(false), - m_removeNum(0) -{ - m_rtdbMutex = new QMutex(); - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_rtdbAccess->open("base", "alarm_level_define"); -} - -CAlarmDataCollect::~CAlarmDataCollect() -{ - LOGINFO("CAlarmDataCollect::~CAlarmDataCollect()"); - qDebug() << "~CAlarmDataCollect()"; -} - -void CAlarmDataCollect::refrence() -{ - m_referenceCount++; -} - -CAlarmDataCollect *CAlarmDataCollect::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CAlarmDataCollect(); - } - return m_pInstance; -} - -void CAlarmDataCollect::initialize() -{ - resumeThread(); - if(!m_pAlternateTimer) - { - m_pAlternateTimer = new QTimer(); - m_pAlternateTimer->setInterval(1000); - connect(m_pAlternateTimer, &QTimer::timeout, this, &CAlarmDataCollect::slotAlarmStateChanged); - connect(this, &CAlarmDataCollect::sigTimerShot, this, &CAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); - } - if(!m_bFaultRecallState) - { - emit sigTimerShot(true); - } -} - -void CAlarmDataCollect::release() -{ - LOGINFO("CAlarmDataCollect::release()"); - emit sigTimerShot(false); - suspendThread(true); - QMutexLocker locker(m_rtdbMutex); - m_bIsNeedUpdate = false; - m_bIsNeedRemove = false; - m_removeNum = 0; -} - - -int CAlarmDataCollect::getRefrenceCount() -{ - return m_referenceCount; -} - -bool CAlarmDataCollect::isFaultRecallState() -{ - return m_bFaultRecallState; -} - -void CAlarmDataCollect::destory() -{ - LOGINFO("退出时:CAlarmDataCollect::destory()打开窗口的个数m_referenceCount:[%d]",m_referenceCount); - if(--m_referenceCount > 0) - { - return; - } - slotTimerShot(false); - suspendThread(); - { - QMutexLocker locker(m_rtdbMutex); - if(Q_NULLPTR != m_pAlternateTimer) - { - m_pAlternateTimer->stop(); - m_pAlternateTimer->deleteLater(); - } - m_pAlternateTimer = Q_NULLPTR; - m_bIsNeedUpdate = false; - m_bIsNeedRemove = false; - } - delete m_rtdbMutex; - delete m_rtdbAccess; - m_pInstance = NULL; - delete this; -} - -void CAlarmDataCollect::slotTimerShot(const bool start) -{ - if(m_pAlternateTimer) - { - if(start) - { - m_pAlternateTimer->start(); - } - else - { - m_pAlternateTimer->stop(); - } - } -} - -void CAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) -{ - m_bFaultRecallState = bFaultRecallState; - release(); - m_pInstance->reinit(m_bFaultRecallState); - CAiAlarmDataCollect::instance()->slotSwitchFaultRecallState(bFaultRecallState); - emit sigAlarmStateChanged(0, 0); - emit sigMsgRefresh(); - - initialize(); - CAiAlarmDataCollect::instance()->initialize(); - - emit sigAlarmOperateEnable(!m_bFaultRecallState); -} - -bool CAlarmDataCollect::requestCfmAlm(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm) -{ - return kbd_service::CAlmApiForAlmClt::requestCfmAlm(objCfmAlm); -} - -bool CAlarmDataCollect::requestDelAlm(kbd_idlfile::SAlmCltDelAlm &objDelAlm) -{ - return kbd_service::CAlmApiForAlmClt::requestDelAlm(objDelAlm); -} - -void CAlarmDataCollect::handleAllAlmMsg(int domainId, kbd_idlfile::SAlmCltAddAlm &objAllAlm) -{ - if(!m_referenceCount) - { - return; - } - LOGINFO("========== AlarmDataCollect handleAllAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - //< 清空该域缓存 - - CAlarmMsgManage::instance()->removeAlarmMsgByDomainID(domainId); - - //< 构建告警 - int nAlarmCount = objAllAlm.alm_info_size(); - QList almList; - for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) - { - kbd_idlfile::SAlmInfoToAlmClt msg = objAllAlm.alm_info(nAddMsgIndex); - AlarmMsgPtr alm(new CAlarmMsgInfo()); - alm->initialize(msg); - alm->priorityOrder = queryPriorityOrder(alm->priority); - //是否需要视频告警 - int alarmAction = queryAlarmAction(alm->priority); - if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (ALM_ACT_VIDEO_ALM == (alarmAction & ALM_ACT_VIDEO_ALM))) - { - alm->m_needVideoAlm = true; - }else - { - alm->m_needVideoAlm = false; - } - almList.append(alm); - } - CAlarmMsgManage::instance()->addAlarmMsg(almList); - emit sigDevTreeUpdate(); - emit sigMsgRefresh(); - - LOGDEBUG("handleAllAlmMsg END[%d] ",nAlarmCount); - if(m_bFaultRecallState) - { - int total = CAlarmMsgManage::instance()->getAlarmTotalSize(); - int unConfirm = CAlarmMsgManage::instance()->getUnConfirmSize(); - emit sigAlarmStateChanged(total, unConfirm); - emit sigUpdateAlarmView(); - } -} - -void CAlarmDataCollect::handleAddAlmMsg(kbd_idlfile::SAlmCltAddAlm &objAddAlm) -{ - if(!m_referenceCount) - { - return; - } - LOGINFO("========== AlarmDataCollect handleAddAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - //< 构建告警 - int nAlarmCount = objAddAlm.alm_info_size(); - QList almList; - for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) - { - kbd_idlfile::SAlmInfoToAlmClt msg = objAddAlm.alm_info(nAddMsgIndex); - AlarmMsgPtr alm(new CAlarmMsgInfo()); - alm->initialize(msg); - alm->priorityOrder = queryPriorityOrder(alm->priority); - //是否需要视频告警 - int alarmAction = queryAlarmAction(alm->priority); - if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (ALM_ACT_VIDEO_ALM == (alarmAction & ALM_ACT_VIDEO_ALM))) - { - alm->m_needVideoAlm = true; - }else - { - alm->m_needVideoAlm = false; - } - almList.append(alm); - } - CAlarmMsgManage::instance()->addAlarmToAllInfo(almList); - CAlarmMsgManage::instance()->addAlarmCacheMsg(almList); - LOGINFO("handleAddAlmMsg END[%d] ",nAlarmCount); -} - -void CAlarmDataCollect::handleCfmAlmMsg(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm) -{ - if(!m_referenceCount) - { - return; - } - LOGINFO("========== AlarmDataCollect handleCfmAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - QList uuidList; - int nAlarmCount = objCfmAlm.uuid_base64_size(); - for(int nCfmMsgIndex(0); nCfmMsgIndex < nAlarmCount; nCfmMsgIndex++) - { - QString uuid = QString::fromStdString(objCfmAlm.uuid_base64(nCfmMsgIndex)); - uuidList.append(uuid); - } - CAlarmMsgManage::instance()->confirmAlarmMsg(uuidList); - m_bIsNeedUpdate = true; - LOGINFO("handleCfmAlmMsg END[%d] ",nAlarmCount); -} - -void CAlarmDataCollect::handleDelAlmMsg(kbd_idlfile::SAlmCltDelAlm &objDelAlm) -{ - if(!m_referenceCount) - { - return; - } - - LOGINFO("========== AlarmDataCollect handleDelAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - QList uuidList; - int nAlarmCount = objDelAlm.uuid_base64_size(); - for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) - { - QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); - uuidList.append(uuid); - } - int size = CAlarmMsgManage::instance()->removeAlarmMsg(uuidList); - m_removeNum += size; - m_bIsNeedRemove = true; - LOGINFO("handleDelAlmMsg END[%d] ",nAlarmCount); -} - -void CAlarmDataCollect::handleReleaseAlmMsg(kbd_idlfile::SAlmCltReleaseAlm &objRelAlm) -{ - if(!m_referenceCount) - { - return; - } - LOGINFO("========== AlarmDataCollect handleReleaseAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - int nAlarmCount = objRelAlm.uuid_base64_size(); - QList uuidList; - for(int nRelMsgIndex(0); nRelMsgIndex < nAlarmCount; nRelMsgIndex++) - { - QString uuid = QString::fromStdString(objRelAlm.uuid_base64(nRelMsgIndex)); - uuidList.append(uuid); - } - int size = CAlarmMsgManage::instance()->removeAlarmMsg(uuidList); - m_removeNum += size; - m_bIsNeedRemove = true; - CAlarmMsgManage::instance()->releaseAlarmMsg(uuidList); - LOGINFO("handleReleaseAlmMsg END[%d] ",nAlarmCount); -} - -void CAlarmDataCollect::handleLinkWave2AlmMsg(kbd_idlfile::SAlmCltLinkWave2Alm &objWave2Alm) -{ - if(!m_referenceCount) - { - return; - } - LOGINFO("========== CAlarmDataCollect handleLinkWave2AlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - QString waveFile = QString::fromStdString(objWave2Alm.wave_file()); - int nAlarmCount = objWave2Alm.uuid_base64_size(); - QList uuidList; - for(int nRelMsgIndex(0); nRelMsgIndex < nAlarmCount; nRelMsgIndex++) - { - QString uuid = QString::fromStdString(objWave2Alm.uuid_base64(nRelMsgIndex)); - uuidList.append(uuid); - } - CAlarmMsgManage::instance()->linkWave2AlmMsg(uuidList,waveFile); -} - -void CAlarmDataCollect::refresh() -{ - emit sigMsgRefresh(); -} - -void CAlarmDataCollect::slotAlarmStateChanged() -{ - QMutexLocker locker(m_rtdbMutex); - CAlarmMsgManage::instance()->msgArrived(); - if(m_bIsNeedUpdate) - { - emit sigMsgConfirm(); - m_bIsNeedUpdate = false; - } - - if(m_bIsNeedRemove) - { - emit sigMsgRemove(m_removeNum); - m_removeNum = 0; - m_bIsNeedRemove = false; - } - int total = CAlarmMsgManage::instance()->getAlarmTotalSize(); - int unConfirm = CAlarmMsgManage::instance()->getUnConfirmSize(); - //CAlarmMsgManage::instance()->output(); - emit sigAlarmStateChanged(total, unConfirm); - emit sigUpdateAlarmView(); - emit sigDevTreeUpdate(); -} - -int CAlarmDataCollect::queryPriorityOrder(int &id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CVarType value = -1000; - m_rtdbAccess->getColumnValueByKey((void*)&id, "priority_order", value); - return value.toInt(); -} - -int CAlarmDataCollect::queryAlarmAction(const int &priority) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CVarType value; - m_rtdbAccess->getColumnValueByKey((void*)&priority, "alarm_actions",value); - return value.toInt(); -} +#include "CAlarmDataCollect.h" +#include +#include "pub_logger_api/logger.h" +#include "CAlarmMsgManage.h" +#include +#include "CAiAlarmDataCollect.h" +#include "alarm_server_api/AlarmCommonDef.h" + +using namespace kbd_service; +using namespace kbd_dbms; +CAlarmDataCollect * CAlarmDataCollect::m_pInstance = NULL; + +CAlarmDataCollect::CAlarmDataCollect() + : CAlmApiForAlmClt(), + m_referenceCount(0), + m_bFaultRecallState(false), + m_pAlternateTimer(Q_NULLPTR), m_rtdbAlmLvlDefTab(nullptr), m_rtdbAlmActDefTab(nullptr), + m_bIsNeedUpdate(false), + m_bIsNeedRemove(false), m_bIsNeedRelease(false), + m_removeNum(0) +{ + m_rtdbMutex = new QMutex(); + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_rtdbAccess->open("base", "alarm_level_define"); +} + +CAlarmDataCollect::~CAlarmDataCollect() +{ + LOGINFO("CAlarmDataCollect::~CAlarmDataCollect()"); + qDebug() << "~CAlarmDataCollect()"; +} + +void CAlarmDataCollect::refrence() +{ + m_referenceCount++; +} + +CAlarmDataCollect *CAlarmDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAlarmDataCollect(); + } + return m_pInstance; +} + +void CAlarmDataCollect::initialize() +{ + resumeThread(); + if(!m_pAlternateTimer) + { + m_pAlternateTimer = new QTimer(); + m_pAlternateTimer->setInterval(1000); + connect(m_pAlternateTimer, &QTimer::timeout, this, &CAlarmDataCollect::slotAlarmStateChanged); + connect(this, &CAlarmDataCollect::sigTimerShot, this, &CAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); + } + if(!m_bFaultRecallState) + { + emit sigTimerShot(true); + } +} + +void CAlarmDataCollect::release() +{ + LOGINFO("CAlarmDataCollect::release()"); + emit sigTimerShot(false); + suspendThread(true); + QMutexLocker locker(m_rtdbMutex); + m_bIsNeedUpdate = false; + m_bIsNeedRemove = false; + m_removeNum = 0; +} + + +int CAlarmDataCollect::getRefrenceCount() +{ + return m_referenceCount; +} + +bool CAlarmDataCollect::isFaultRecallState() +{ + return m_bFaultRecallState; +} + +void CAlarmDataCollect::destory() +{ + LOGINFO("退出时:CAlarmDataCollect::destory()打开窗口的个数m_referenceCount:[%d]",m_referenceCount); + if(--m_referenceCount > 0) + { + return; + } + slotTimerShot(false); + suspendThread(); + { + QMutexLocker locker(m_rtdbMutex); + if(Q_NULLPTR != m_pAlternateTimer) + { + m_pAlternateTimer->stop(); + m_pAlternateTimer->deleteLater(); + } + m_pAlternateTimer = Q_NULLPTR; + m_bIsNeedUpdate = false; + m_bIsNeedRemove = false; + } + delete m_rtdbMutex; + delete m_rtdbAccess; + m_pInstance = NULL; + delete this; +} + +void CAlarmDataCollect::slotTimerShot(const bool start) +{ + if(m_pAlternateTimer) + { + if(start) + { + m_pAlternateTimer->start(); + } + else + { + m_pAlternateTimer->stop(); + } + } +} + +void CAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) +{ + m_bFaultRecallState = bFaultRecallState; + release(); + m_pInstance->reinit(m_bFaultRecallState); + CAiAlarmDataCollect::instance()->slotSwitchFaultRecallState(bFaultRecallState); + emit sigAlarmStateChanged(0, 0); + emit sigMsgRefresh(); + + initialize(); + CAiAlarmDataCollect::instance()->initialize(); + + emit sigAlarmOperateEnable(!m_bFaultRecallState); +} + +bool CAlarmDataCollect::requestCfmAlm(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm) +{ + return kbd_service::CAlmApiForAlmClt::requestCfmAlm(objCfmAlm); +} + +bool CAlarmDataCollect::requestDelAlm(kbd_idlfile::SAlmCltDelAlm &objDelAlm) +{ + return kbd_service::CAlmApiForAlmClt::requestDelAlm(objDelAlm); +} + +void CAlarmDataCollect::handleAllAlmMsg(int domainId, kbd_idlfile::SAlmCltAddAlm &objAllAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleAllAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //< 清空该域缓存 + + CAlarmMsgManage::instance()->removeAlarmMsgByDomainID(domainId); + + //< 构建告警 + int nAlarmCount = objAllAlm.alm_info_size(); + QList almList; + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + kbd_idlfile::SAlmInfoToAlmClt msg = objAllAlm.alm_info(nAddMsgIndex); + AlarmMsgPtr alm(new CAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + //是否需要视频告警 + int alarmAction = queryAlarmAction(alm->priority); + if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (ALM_ACT_VIDEO_ALM == (alarmAction & ALM_ACT_VIDEO_ALM))) + { + alm->m_needVideoAlm = true; + }else + { + alm->m_needVideoAlm = false; + } + almList.append(alm); + } + CAlarmMsgManage::instance()->addAlarmMsg(almList); + emit sigDevTreeUpdate(); + emit sigMsgRefresh(); + + LOGDEBUG("handleAllAlmMsg END[%d] ",nAlarmCount); + if(m_bFaultRecallState) + { + int total = CAlarmMsgManage::instance()->getAlarmTotalSize(); + int unConfirm = CAlarmMsgManage::instance()->getUnConfirmSize(); + emit sigAlarmStateChanged(total, unConfirm); + emit sigUpdateAlarmView(); + } +} + +void CAlarmDataCollect::handleAddAlmMsg(kbd_idlfile::SAlmCltAddAlm &objAddAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleAddAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //< 构建告警 + int nAlarmCount = objAddAlm.alm_info_size(); + QList almList; + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + kbd_idlfile::SAlmInfoToAlmClt msg = objAddAlm.alm_info(nAddMsgIndex); + AlarmMsgPtr alm(new CAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + //是否需要视频告警 + int alarmAction = queryAlarmAction(alm->priority); + if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (ALM_ACT_VIDEO_ALM == (alarmAction & ALM_ACT_VIDEO_ALM))) + { + alm->m_needVideoAlm = true; + }else + { + alm->m_needVideoAlm = false; + } + almList.append(alm); + } + CAlarmMsgManage::instance()->addAlarmToAllInfo(almList); + CAlarmMsgManage::instance()->addAlarmCacheMsg(almList); + LOGINFO("handleAddAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleCfmAlmMsg(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleCfmAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + QList uuidList; + int nAlarmCount = objCfmAlm.uuid_base64_size(); + for(int nCfmMsgIndex(0); nCfmMsgIndex < nAlarmCount; nCfmMsgIndex++) + { + QString uuid = QString::fromStdString(objCfmAlm.uuid_base64(nCfmMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->confirmAlarmMsg(uuidList); + m_bIsNeedUpdate = true; + LOGINFO("handleCfmAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleDelAlmMsg(kbd_idlfile::SAlmCltDelAlm &objDelAlm) +{ + if(!m_referenceCount) + { + return; + } + + LOGINFO("========== AlarmDataCollect handleDelAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + QList uuidList; + int nAlarmCount = objDelAlm.uuid_base64_size(); + for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) + { + QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); + uuidList.append(uuid); + } + int size = CAlarmMsgManage::instance()->removeAlarmMsg(uuidList); + m_removeNum += size; + m_bIsNeedRemove = true; + LOGINFO("handleDelAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleReleaseAlmMsg(kbd_idlfile::SAlmCltReleaseAlm &objRelAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleReleaseAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objRelAlm.uuid_base64_size(); + QList uuidList; + for(int nRelMsgIndex(0); nRelMsgIndex < nAlarmCount; nRelMsgIndex++) + { + QString uuid = QString::fromStdString(objRelAlm.uuid_base64(nRelMsgIndex)); + uuidList.append(uuid); + } + int size = CAlarmMsgManage::instance()->removeAlarmMsg(uuidList); + m_removeNum += size; + m_bIsNeedRemove = true; + CAlarmMsgManage::instance()->releaseAlarmMsg(uuidList); + LOGINFO("handleReleaseAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleLinkWave2AlmMsg(kbd_idlfile::SAlmCltLinkWave2Alm &objWave2Alm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== CAlarmDataCollect handleLinkWave2AlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + QString waveFile = QString::fromStdString(objWave2Alm.wave_file()); + int nAlarmCount = objWave2Alm.uuid_base64_size(); + QList uuidList; + for(int nRelMsgIndex(0); nRelMsgIndex < nAlarmCount; nRelMsgIndex++) + { + QString uuid = QString::fromStdString(objWave2Alm.uuid_base64(nRelMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->linkWave2AlmMsg(uuidList,waveFile); +} + +void CAlarmDataCollect::refresh() +{ + emit sigMsgRefresh(); +} + +void CAlarmDataCollect::slotAlarmStateChanged() +{ + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->msgArrived(); + if(m_bIsNeedUpdate) + { + emit sigMsgConfirm(); + m_bIsNeedUpdate = false; + } + + if(m_bIsNeedRemove) + { + emit sigMsgRemove(m_removeNum); + m_removeNum = 0; + m_bIsNeedRemove = false; + } + int total = CAlarmMsgManage::instance()->getAlarmTotalSize(); + int unConfirm = CAlarmMsgManage::instance()->getUnConfirmSize(); + //CAlarmMsgManage::instance()->output(); + emit sigAlarmStateChanged(total, unConfirm); + emit sigUpdateAlarmView(); + emit sigDevTreeUpdate(); +} + +int CAlarmDataCollect::queryPriorityOrder(int &id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CVarType value = -1000; + m_rtdbAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +int CAlarmDataCollect::queryAlarmAction(const int &priority) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CVarType value; + m_rtdbAccess->getColumnValueByKey((void*)&priority, "alarm_actions",value); + return value.toInt(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDataCollect.h b/product/src/gui/plugin/AlarmWidget/CAlarmDataCollect.h index 9a77f75f..ccfda0d7 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDataCollect.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDataCollect.h @@ -1,111 +1,111 @@ -#ifndef CALARMDATACOLLECT_H -#define CALARMDATACOLLECT_H - -#include -#include -#include -#include -#include -#include "AlarmMessage.pb.h" -#include "CAlarmMsgInfo.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "dbms/rdb_api/CRdbAccess.h" - -class CAlarmDataCollect : public QObject, public kbd_service::CAlmApiForAlmClt -{ - Q_OBJECT -public: - static CAlarmDataCollect *instance(); - - virtual ~CAlarmDataCollect(); - - void refrence(); - - int getRefrenceCount(); - - bool isFaultRecallState(); - - virtual bool requestCfmAlm(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm); - - virtual bool requestDelAlm(kbd_idlfile::SAlmCltDelAlm &objDelAlm); - - virtual void handleAllAlmMsg(int domainId, kbd_idlfile::SAlmCltAddAlm &objAllAlm); - - virtual void handleAddAlmMsg(kbd_idlfile::SAlmCltAddAlm &objAddAlm); - - virtual void handleCfmAlmMsg(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm); - - virtual void handleDelAlmMsg(kbd_idlfile::SAlmCltDelAlm &objDelAlm); - - virtual void handleReleaseAlmMsg(kbd_idlfile::SAlmCltReleaseAlm &objDelAlm); - - virtual void handleLinkWave2AlmMsg(kbd_idlfile::SAlmCltLinkWave2Alm &objWave2Alm); - - void refresh(); -signals: - //< 启停定时器 - void sigTimerShot(const bool bStop); - - //< 定时更新,通知model刷新界面 - void sigUpdateAlarmView(); - - //< 通知所有告警插件禁用/使能告警操作 - void sigAlarmOperateEnable(const bool &bEnable); - - //< 通知model重新拉取告警消息 - void sigMsgRefresh(); - - //< 通知model告警消息到达 - //void sigMsgArrived(); - - //< 通知model告警消息确认 - void sigMsgConfirm(); - - //< 通知model告警消息删除(原始告警 删除数量) - void sigMsgRemove(int removeNum); - - //< 告警数量或状态改变时触发。 - void sigAlarmStateChanged(int total, int unConfirm); - - void sigDevTreeUpdate(); - -public slots: - - void initialize(); - - void release(); - - void destory(); - - void slotTimerShot(const bool start); - - void slotSwitchFaultRecallState(bool bFaultRecallState); - -private: - CAlarmDataCollect(); - - int queryPriorityOrder(int &id); - int queryAlarmAction(const int &priority); - -private slots: - void slotAlarmStateChanged(); - -private: - int m_referenceCount; - bool m_bFaultRecallState; //是否处于事故追忆 - QMutex * m_rtdbMutex; - QTimer * m_pAlternateTimer; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CRdbAccess * m_rtdbAlmLvlDefTab; // 告警等级定义表 - kbd_dbms::CRdbAccess * m_rtdbAlmActDefTab; // 告警动作定义表 - bool m_bIsNeedUpdate; //< 是否消息确认(每秒更新) - bool m_bIsNeedRemove; //< 是否需要删除(每秒更新) - bool m_bIsNeedRelease; //< 是否需要释放(每秒更新)- - static CAlarmDataCollect * m_pInstance; - - //1秒需要删除的条数 (在这里统计这个,原因是当删除大量数据时,一条一条删除没有重置模型效率高,此处当大于1000时,会重置模型,小于的话,则一条一条删) - //beginRemoveRows() 和beginResetModel() 没有深入研究临界值,目前先采用1000 - int m_removeNum; -}; - -#endif // CALARMDATACOLLECT_H +#ifndef CALARMDATACOLLECT_H +#define CALARMDATACOLLECT_H + +#include +#include +#include +#include +#include +#include "AlarmMessage.pb.h" +#include "CAlarmMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" + +class CAlarmDataCollect : public QObject, public kbd_service::CAlmApiForAlmClt +{ + Q_OBJECT +public: + static CAlarmDataCollect *instance(); + + virtual ~CAlarmDataCollect(); + + void refrence(); + + int getRefrenceCount(); + + bool isFaultRecallState(); + + virtual bool requestCfmAlm(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm); + + virtual bool requestDelAlm(kbd_idlfile::SAlmCltDelAlm &objDelAlm); + + virtual void handleAllAlmMsg(int domainId, kbd_idlfile::SAlmCltAddAlm &objAllAlm); + + virtual void handleAddAlmMsg(kbd_idlfile::SAlmCltAddAlm &objAddAlm); + + virtual void handleCfmAlmMsg(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm); + + virtual void handleDelAlmMsg(kbd_idlfile::SAlmCltDelAlm &objDelAlm); + + virtual void handleReleaseAlmMsg(kbd_idlfile::SAlmCltReleaseAlm &objDelAlm); + + virtual void handleLinkWave2AlmMsg(kbd_idlfile::SAlmCltLinkWave2Alm &objWave2Alm); + + void refresh(); +signals: + //< 启停定时器 + void sigTimerShot(const bool bStop); + + //< 定时更新,通知model刷新界面 + void sigUpdateAlarmView(); + + //< 通知所有告警插件禁用/使能告警操作 + void sigAlarmOperateEnable(const bool &bEnable); + + //< 通知model重新拉取告警消息 + void sigMsgRefresh(); + + //< 通知model告警消息到达 + //void sigMsgArrived(); + + //< 通知model告警消息确认 + void sigMsgConfirm(); + + //< 通知model告警消息删除(原始告警 删除数量) + void sigMsgRemove(int removeNum); + + //< 告警数量或状态改变时触发。 + void sigAlarmStateChanged(int total, int unConfirm); + + void sigDevTreeUpdate(); + +public slots: + + void initialize(); + + void release(); + + void destory(); + + void slotTimerShot(const bool start); + + void slotSwitchFaultRecallState(bool bFaultRecallState); + +private: + CAlarmDataCollect(); + + int queryPriorityOrder(int &id); + int queryAlarmAction(const int &priority); + +private slots: + void slotAlarmStateChanged(); + +private: + int m_referenceCount; + bool m_bFaultRecallState; //是否处于事故追忆 + QMutex * m_rtdbMutex; + QTimer * m_pAlternateTimer; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CRdbAccess * m_rtdbAlmLvlDefTab; // 告警等级定义表 + kbd_dbms::CRdbAccess * m_rtdbAlmActDefTab; // 告警动作定义表 + bool m_bIsNeedUpdate; //< 是否消息确认(每秒更新) + bool m_bIsNeedRemove; //< 是否需要删除(每秒更新) + bool m_bIsNeedRelease; //< 是否需要释放(每秒更新)- + static CAlarmDataCollect * m_pInstance; + + //1秒需要删除的条数 (在这里统计这个,原因是当删除大量数据时,一条一条删除没有重置模型效率高,此处当大于1000时,会重置模型,小于的话,则一条一条删) + //beginRemoveRows() 和beginResetModel() 没有深入研究临界值,目前先采用1000 + int m_removeNum; +}; + +#endif // CALARMDATACOLLECT_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDelegate.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmDelegate.cpp index e83c57e9..1812bab7 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDelegate.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDelegate.cpp @@ -1,307 +1,307 @@ -#include -#include -#include -#include "CAlarmDelegate.h" -#include "CAlarmMsgInfo.h" -#include "CAlarmItemModel.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include "pub_logger_api/logger.h" -#include - -CAlarmDelegate::CAlarmDelegate(CAlarmItemModel * model, QObject *parent) - : QStyledItemDelegate(parent), - m_pModel(model), - m_isFlash(false), - m_enableTrend(true), - m_enableLevel(false), - m_enableVideo(true), - m_enableWave(true), - m_selectIsEmpty(false) -{ - slotLoadConfig(); -} - -void CAlarmDelegate::setEnableTrend(bool isNeed) -{ - m_enableTrend = isNeed; -} - -void CAlarmDelegate::setEnableLevel(bool isNeed) -{ - m_enableLevel = isNeed; -} - -void CAlarmDelegate::setEnableVideo(bool isNeed) -{ - m_enableVideo = isNeed; -} - -void CAlarmDelegate::setEnableWave(bool isNeed) -{ - m_enableWave = isNeed; -} - -void CAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - if(!index.isValid()) - { - return; - } - QColor fillColor; - QColor penColor; - bool select = option.state & QStyle::State_Selected; - //< Dock Empty - if(E_Alarm_Dock == m_pModel->getAlarmMode() && 0 == m_pModel->getShowAlarmCount()) - { - painter->fillRect(option.rect, m_emptyBackgroundColor); - if(CAlarmItemModel::CONTENT == index.column() && parent()) - { - QRect rt = option.rect; - QWidget * parentWidget = dynamic_cast(parent()); - if(parentWidget) - { - rt.setLeft(0); - rt.setWidth(parentWidget->width()); - painter->save(); - painter->setPen(m_emptyTipColor); - painter->drawText(rt, Qt::AlignHCenter | Qt::AlignVCenter, m_emptyTip); - painter->restore(); - } - } - return; - } - - //< Common - AlarmMsgPtr info = m_pModel->getAlarmInfo(index); - - - if(info != Q_NULLPTR) - { - painter->save(); - - if(E_ALS_RETURN == info->logic_state) - { - if(select) - { - fillColor = m_select_background_color; - if(m_selectIsEmpty) - { - penColor = m_colorMap.value(info->priorityOrder).resume_text_color; - }else - { - penColor = m_select_text_color; - } - } - else - { - if(m_isFlash && m_pModel->alternate()) - { - penColor = m_colorMap.value(info->priorityOrder).alternating_color; - } - else - { - penColor = m_colorMap.value(info->priorityOrder).resume_text_color; - } - fillColor = m_colorMap.value(info->priorityOrder).background_color; - } - }else if(E_ALS_ALARM == info->logic_state) - { - if(select) - { - fillColor = m_select_background_color; - if(m_selectIsEmpty) - { - penColor = m_colorMap.value(info->priorityOrder).active_text_color; - }else - { - penColor = m_select_text_color; - } - } - else - { - if(m_isFlash && m_pModel->alternate()) - { - penColor = m_colorMap.value(info->priorityOrder).alternating_color; - } - else - { - penColor = m_colorMap.value(info->priorityOrder).active_text_color; - } - fillColor = m_colorMap.value(info->priorityOrder).background_color; - } - }else - { - if(select) - { - fillColor = m_select_background_color; - } - else - { - fillColor = m_colorMap.value(info->priorityOrder).confirm_color; - } - penColor = m_colorMap.value(info->priorityOrder).confirm_text_color; - } - painter->setPen(penColor); - painter->fillRect(option.rect, fillColor); - - if(m_enableLevel && ICON_COLUMN == index.column()) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); - QString file = m_colorMap.value(info->priorityOrder).icon; - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(file); - button.features = QStyleOptionButton::Flat; - - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - if(m_enableVideo && BUTTON_COLUMN == index.column() && info->m_needVideoAlm) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(m_strVideoPath); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - if( m_enableTrend && BUTTON_COLUMN == index.column() && (info->m_tagname_type == E_TAGNAME_ANA || info->m_tagname_type == E_TAGNAME_ACC)) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(m_strTrendPath); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - if(m_enableWave && BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(m_strWavePath); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - - painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); - painter->restore(); - } -} - -bool CAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - if(!index.isValid()) - { - return false; - } - if(index.column() != BUTTON_COLUMN) - { - return false; - } - AlarmMsgPtr info = m_pModel->getAlarmInfo(index); - QMouseEvent *mouseEvent = static_cast(event); - if(info && m_enableVideo && info->m_needVideoAlm) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - QString pointTag = info->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - emit openVideo(info->domain_id,info->app_id,pointTag,info->time_stamp-VIDEO_TIME,info->time_stamp+VIDEO_TIME); - } - } - } - if(info && m_enableTrend && (info->m_tagname_type == E_TAGNAME_ACC || info->m_tagname_type == E_TAGNAME_ANA )) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - QStringList trendList; - trendList.append(info->key_id_tag); - emit openTrend(info->time_stamp,trendList); - } - } - } - if(info && m_enableWave && !info->wave_file.isEmpty()) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - QString wave = info->wave_file; - wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); - LOGINFO("录波文件为:%s",wave.toStdString().c_str()); - - const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( - std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); - if(strProc.empty()) - LOGERROR("未找到可执行文件WaveAnalyze"); - else - QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); - } - } - } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} - -void CAlarmDelegate::slotLoadConfig() -{ - CAlarmSetMng::instance()->getColorMap(m_colorMap); - CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); - CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); - //CAlarmColorMng::instance()->getActAndFunc(m_act,m_func); - if(E_Alarm_Pop == m_pModel->getAlarmMode()) - { - m_isFlash = false; - } - else if(E_Alarm_Dock == m_pModel->getAlarmMode()) - { - m_isFlash = true; - } - else if(E_Alarm_Window == m_pModel->getAlarmMode()) - { - m_isFlash = false; - } - - std::string style = kbd_public::CFileStyle::getCurStyle(); - m_strTrendPath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/trend_"+style+".png").c_str(); - m_strVideoPath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video_"+style+".png").c_str(); - m_strWavePath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); -} +#include +#include +#include +#include "CAlarmDelegate.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include "pub_logger_api/logger.h" +#include + +CAlarmDelegate::CAlarmDelegate(CAlarmItemModel * model, QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(model), + m_isFlash(false), + m_enableTrend(true), + m_enableLevel(false), + m_enableVideo(true), + m_enableWave(true), + m_selectIsEmpty(false) +{ + slotLoadConfig(); +} + +void CAlarmDelegate::setEnableTrend(bool isNeed) +{ + m_enableTrend = isNeed; +} + +void CAlarmDelegate::setEnableLevel(bool isNeed) +{ + m_enableLevel = isNeed; +} + +void CAlarmDelegate::setEnableVideo(bool isNeed) +{ + m_enableVideo = isNeed; +} + +void CAlarmDelegate::setEnableWave(bool isNeed) +{ + m_enableWave = isNeed; +} + +void CAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + QColor fillColor; + QColor penColor; + bool select = option.state & QStyle::State_Selected; + //< Dock Empty + if(E_Alarm_Dock == m_pModel->getAlarmMode() && 0 == m_pModel->getShowAlarmCount()) + { + painter->fillRect(option.rect, m_emptyBackgroundColor); + if(CAlarmItemModel::CONTENT == index.column() && parent()) + { + QRect rt = option.rect; + QWidget * parentWidget = dynamic_cast(parent()); + if(parentWidget) + { + rt.setLeft(0); + rt.setWidth(parentWidget->width()); + painter->save(); + painter->setPen(m_emptyTipColor); + painter->drawText(rt, Qt::AlignHCenter | Qt::AlignVCenter, m_emptyTip); + painter->restore(); + } + } + return; + } + + //< Common + AlarmMsgPtr info = m_pModel->getAlarmInfo(index); + + + if(info != Q_NULLPTR) + { + painter->save(); + + if(E_ALS_RETURN == info->logic_state) + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(info->priorityOrder).resume_text_color; + }else + { + penColor = m_select_text_color; + } + } + else + { + if(m_isFlash && m_pModel->alternate()) + { + penColor = m_colorMap.value(info->priorityOrder).alternating_color; + } + else + { + penColor = m_colorMap.value(info->priorityOrder).resume_text_color; + } + fillColor = m_colorMap.value(info->priorityOrder).background_color; + } + }else if(E_ALS_ALARM == info->logic_state) + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(info->priorityOrder).active_text_color; + }else + { + penColor = m_select_text_color; + } + } + else + { + if(m_isFlash && m_pModel->alternate()) + { + penColor = m_colorMap.value(info->priorityOrder).alternating_color; + } + else + { + penColor = m_colorMap.value(info->priorityOrder).active_text_color; + } + fillColor = m_colorMap.value(info->priorityOrder).background_color; + } + }else + { + if(select) + { + fillColor = m_select_background_color; + } + else + { + fillColor = m_colorMap.value(info->priorityOrder).confirm_color; + } + penColor = m_colorMap.value(info->priorityOrder).confirm_text_color; + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + + if(m_enableLevel && ICON_COLUMN == index.column()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); + QString file = m_colorMap.value(info->priorityOrder).icon; + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + if(m_enableVideo && BUTTON_COLUMN == index.column() && info->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strVideoPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + if( m_enableTrend && BUTTON_COLUMN == index.column() && (info->m_tagname_type == E_TAGNAME_ANA || info->m_tagname_type == E_TAGNAME_ACC)) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strTrendPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + if(m_enableWave && BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strWavePath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + } +} + +bool CAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(index.column() != BUTTON_COLUMN) + { + return false; + } + AlarmMsgPtr info = m_pModel->getAlarmInfo(index); + QMouseEvent *mouseEvent = static_cast(event); + if(info && m_enableVideo && info->m_needVideoAlm) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString pointTag = info->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(info->domain_id,info->app_id,pointTag,info->time_stamp-VIDEO_TIME,info->time_stamp+VIDEO_TIME); + } + } + } + if(info && m_enableTrend && (info->m_tagname_type == E_TAGNAME_ACC || info->m_tagname_type == E_TAGNAME_ANA )) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QStringList trendList; + trendList.append(info->key_id_tag); + emit openTrend(info->time_stamp,trendList); + } + } + } + if(info && m_enableWave && !info->wave_file.isEmpty()) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString wave = info->wave_file; + wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); + LOGINFO("录波文件为:%s",wave.toStdString().c_str()); + + const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +void CAlarmDelegate::slotLoadConfig() +{ + CAlarmSetMng::instance()->getColorMap(m_colorMap); + CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); + CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); + //CAlarmColorMng::instance()->getActAndFunc(m_act,m_func); + if(E_Alarm_Pop == m_pModel->getAlarmMode()) + { + m_isFlash = false; + } + else if(E_Alarm_Dock == m_pModel->getAlarmMode()) + { + m_isFlash = true; + } + else if(E_Alarm_Window == m_pModel->getAlarmMode()) + { + m_isFlash = false; + } + + std::string style = kbd_public::CFileStyle::getCurStyle(); + m_strTrendPath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/trend_"+style+".png").c_str(); + m_strVideoPath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video_"+style+".png").c_str(); + m_strWavePath = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDelegate.h b/product/src/gui/plugin/AlarmWidget/CAlarmDelegate.h index 1a399757..a81ea972 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDelegate.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDelegate.h @@ -1,53 +1,53 @@ -#ifndef CALARMDELEGATE_H -#define CALARMDELEGATE_H - -#include -#include "CAlarmSetMng.h" - -class CAlarmItemModel; - -class CAlarmDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CAlarmDelegate(CAlarmItemModel *model, QObject *parent = 0); - void setEnableTrend(bool isNeed); - void setEnableLevel(bool isNeed); - void setEnableVideo(bool isNeed); - void setEnableWave(bool isNeed); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; - -signals: - void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); - void openTrend(quint64 time_stamp,QStringList tagList); - -public slots: - void slotLoadConfig(); - -private: - CAlarmItemModel * m_pModel; - bool m_isFlash; - - bool m_enableTrend; - bool m_enableLevel; - bool m_enableVideo; - bool m_enableWave; - - QMap m_colorMap; - QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 - bool m_selectIsEmpty; - - QColor m_emptyBackgroundColor,m_emptyTipColor; - QString m_emptyTip; - int m_act; - int m_func; - - QString m_strWavePath; - QString m_strVideoPath; - QString m_strTrendPath; -}; - -#endif +#ifndef CALARMDELEGATE_H +#define CALARMDELEGATE_H + +#include +#include "CAlarmSetMng.h" + +class CAlarmItemModel; + +class CAlarmDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CAlarmDelegate(CAlarmItemModel *model, QObject *parent = 0); + void setEnableTrend(bool isNeed); + void setEnableLevel(bool isNeed); + void setEnableVideo(bool isNeed); + void setEnableWave(bool isNeed); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; + +signals: + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + void openTrend(quint64 time_stamp,QStringList tagList); + +public slots: + void slotLoadConfig(); + +private: + CAlarmItemModel * m_pModel; + bool m_isFlash; + + bool m_enableTrend; + bool m_enableLevel; + bool m_enableVideo; + bool m_enableWave; + + QMap m_colorMap; + QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 + bool m_selectIsEmpty; + + QColor m_emptyBackgroundColor,m_emptyTipColor; + QString m_emptyTip; + int m_act; + int m_func; + + QString m_strWavePath; + QString m_strVideoPath; + QString m_strTrendPath; +}; + +#endif diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeItem.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeItem.cpp index c0d84ada..64301f10 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeItem.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeItem.cpp @@ -1,159 +1,159 @@ -#include -#include "CAlarmDeviceTreeItem.h" -#include "pub_logger_api/logger.h" -#include "Common.h" - -const int TypeRole = Qt::UserRole + 1; -const int TagRole = Qt::UserRole + 2; -const int DomainRole = Qt::UserRole + 3; -const int LocationRole = Qt::UserRole + 4; -const int SubsystemRole = Qt::UserRole + 5; -const int RegionRole = Qt::UserRole + 6; - -CAlarmDeviceTreeItem::CAlarmDeviceTreeItem(const QString &data, CAlarmDeviceTreeItem *parent) - : m_tag(QString()), - m_nDomain(CN_InvalidDomainId), - m_nLocation(CN_InvalidLocationId), - m_nSubsystem(CN_InvalidSubsystemId), - m_nType(0), - m_nRegion(0), - m_parentItem(parent) -{ - if(m_parentItem) - { - m_parentItem->m_childItems.append(this); - } - - m_data = data; - m_checkState = Qt::Checked; -} - -CAlarmDeviceTreeItem::~CAlarmDeviceTreeItem() -{ - qDeleteAll(m_childItems); - m_childItems.clear(); -} - -CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::child(int row) -{ - return m_childItems.value(row); -} - -CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::parentItem() -{ - return m_parentItem; -} - -int CAlarmDeviceTreeItem::row() const -{ - if (m_parentItem) - { - return m_parentItem->m_childItems.indexOf(const_cast(this)); - } - - return 0; -} - -int CAlarmDeviceTreeItem::childCount() const -{ - return m_childItems.count(); -} - -int CAlarmDeviceTreeItem::columnCount() const -{ - return 1; -} - -QVariant CAlarmDeviceTreeItem::data(Qt::ItemDataRole role) const -{ - if(Qt::DisplayRole == role) - { - return m_data; - } - else if(Qt::CheckStateRole == role) - { - return m_checkState; - } - else if(Qt::ItemDataRole(TypeRole) == role) - { - return m_nType; - } - else if(Qt::ItemDataRole(TagRole) == role) - { - return m_tag; - } - else if(Qt::ItemDataRole(DomainRole) == role) - { - return m_nDomain; - } - else if(Qt::ItemDataRole(LocationRole) == role) - { - return m_nLocation; - } - else if(Qt::ItemDataRole(SubsystemRole) == role) - { - return m_nSubsystem; - } - else if(Qt::ItemDataRole(RegionRole) == role) - { - return m_nRegion; - } - return QVariant(); -} - -bool CAlarmDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) -{ - if(Qt::DisplayRole == role) - { - m_data = value.toString(); - return true; - } - else if(Qt::CheckStateRole == role) - { - m_checkState = (Qt::CheckState)value.toInt(); - return true; - } - else if(TypeRole == role) - { - m_nType = value.toInt(); - return true; - } - else if(TagRole == role) - { - m_tag = value.toString(); - return true; - } - else if(DomainRole == role) - { - m_nDomain = value.toInt(); - return true; - } - else if(LocationRole == role) - { - m_nLocation = value.toInt(); - return true; - } - else if(SubsystemRole == role) - { - m_nSubsystem = value.toInt(); - return true; - } - else if(RegionRole == role) - { - m_nRegion = value.toInt(); - return true; - } - return false; -} - -bool CAlarmDeviceTreeItem::removeChildren(int position, int count, int columns) -{ - Q_UNUSED(columns) - if (position < 0 || position + count > m_childItems.size()) - return false; - - for (int row = 0; row < count; ++row) - delete m_childItems.takeAt(position); - - return true; -} +#include +#include "CAlarmDeviceTreeItem.h" +#include "pub_logger_api/logger.h" +#include "Common.h" + +const int TypeRole = Qt::UserRole + 1; +const int TagRole = Qt::UserRole + 2; +const int DomainRole = Qt::UserRole + 3; +const int LocationRole = Qt::UserRole + 4; +const int SubsystemRole = Qt::UserRole + 5; +const int RegionRole = Qt::UserRole + 6; + +CAlarmDeviceTreeItem::CAlarmDeviceTreeItem(const QString &data, CAlarmDeviceTreeItem *parent) + : m_tag(QString()), + m_nDomain(CN_InvalidDomainId), + m_nLocation(CN_InvalidLocationId), + m_nSubsystem(CN_InvalidSubsystemId), + m_nType(0), + m_nRegion(0), + m_parentItem(parent) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } + + m_data = data; + m_checkState = Qt::Checked; +} + +CAlarmDeviceTreeItem::~CAlarmDeviceTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::child(int row) +{ + return m_childItems.value(row); +} + +CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::parentItem() +{ + return m_parentItem; +} + +int CAlarmDeviceTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CAlarmDeviceTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CAlarmDeviceTreeItem::columnCount() const +{ + return 1; +} + +QVariant CAlarmDeviceTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } + else if(Qt::ItemDataRole(TypeRole) == role) + { + return m_nType; + } + else if(Qt::ItemDataRole(TagRole) == role) + { + return m_tag; + } + else if(Qt::ItemDataRole(DomainRole) == role) + { + return m_nDomain; + } + else if(Qt::ItemDataRole(LocationRole) == role) + { + return m_nLocation; + } + else if(Qt::ItemDataRole(SubsystemRole) == role) + { + return m_nSubsystem; + } + else if(Qt::ItemDataRole(RegionRole) == role) + { + return m_nRegion; + } + return QVariant(); +} + +bool CAlarmDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + else if(TypeRole == role) + { + m_nType = value.toInt(); + return true; + } + else if(TagRole == role) + { + m_tag = value.toString(); + return true; + } + else if(DomainRole == role) + { + m_nDomain = value.toInt(); + return true; + } + else if(LocationRole == role) + { + m_nLocation = value.toInt(); + return true; + } + else if(SubsystemRole == role) + { + m_nSubsystem = value.toInt(); + return true; + } + else if(RegionRole == role) + { + m_nRegion = value.toInt(); + return true; + } + return false; +} + +bool CAlarmDeviceTreeItem::removeChildren(int position, int count, int columns) +{ + Q_UNUSED(columns) + if (position < 0 || position + count > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) + delete m_childItems.takeAt(position); + + return true; +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeItem.h b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeItem.h index 7c695758..35f93129 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeItem.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeItem.h @@ -1,95 +1,95 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CALARMDEVICETREEITEM_H -#define CALARMDEVICETREEITEM_H - -#include -#include - -extern const int TypeRole; -extern const int TagRole; -extern const int DomainRole; -extern const int LocationRole; -extern const int SubsystemRole; -extern const int RegionRole; - -class CAlarmDeviceTreeItem -{ -public: - explicit CAlarmDeviceTreeItem(const QString &data = QString(), CAlarmDeviceTreeItem *parentItem = Q_NULLPTR); - ~CAlarmDeviceTreeItem(); - - CAlarmDeviceTreeItem *child(int row); - CAlarmDeviceTreeItem *parentItem(); - - int row() const; - - int childCount() const; - int columnCount() const; - - QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; - bool setData(const QVariant &value, Qt::ItemDataRole role); - bool removeChildren(int position, int count, int columns); -private: - QString m_tag; - int m_nDomain; - int m_nLocation; - int m_nSubsystem; - int m_nRegion; - int m_nType; - QString m_data; - Qt::CheckState m_checkState; - - QList m_childItems; - CAlarmDeviceTreeItem *m_parentItem; -}; - -#endif // CALARMDEVICETREEITEM_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CALARMDEVICETREEITEM_H +#define CALARMDEVICETREEITEM_H + +#include +#include + +extern const int TypeRole; +extern const int TagRole; +extern const int DomainRole; +extern const int LocationRole; +extern const int SubsystemRole; +extern const int RegionRole; + +class CAlarmDeviceTreeItem +{ +public: + explicit CAlarmDeviceTreeItem(const QString &data = QString(), CAlarmDeviceTreeItem *parentItem = Q_NULLPTR); + ~CAlarmDeviceTreeItem(); + + CAlarmDeviceTreeItem *child(int row); + CAlarmDeviceTreeItem *parentItem(); + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + bool removeChildren(int position, int count, int columns); +private: + QString m_tag; + int m_nDomain; + int m_nLocation; + int m_nSubsystem; + int m_nRegion; + int m_nType; + QString m_data; + Qt::CheckState m_checkState; + + QList m_childItems; + CAlarmDeviceTreeItem *m_parentItem; +}; + +#endif // CALARMDEVICETREEITEM_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.cpp index bb9fb78c..baee60de 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.cpp @@ -1,259 +1,259 @@ -#include "CAlarmDeviceTreeItem.h" -#include "CAlarmDeviceTreeModel.h" -#include "CAlarmMsgManage.h" -#include "CAlarmBaseData.h" -#include -#include "pub_logger_api/logger.h" -CAlarmDeviceTreeModel::CAlarmDeviceTreeModel(QObject *parent) - : QAbstractItemModel(parent) -{ - rootItem = new CAlarmDeviceTreeItem(); -} - -CAlarmDeviceTreeModel::~CAlarmDeviceTreeModel() -{ - m_devTagIndex.clear(); - m_devNameIndex.clear(); - delete rootItem; -} - -void CAlarmDeviceTreeModel::setupModelData(const QMap > locationInfos, const QList &locationList) -{ - for(int nLocIndex(0); nLocIndexgetPermLocationDesc(locationList[nLocIndex]); - CAlarmDeviceTreeItem * location = new CAlarmDeviceTreeItem(locDesc, rootItem); - location->setData(TYPE_LOCATION,Qt::ItemDataRole(TypeRole)); - const QVector vec = locationInfos.value(locationList[nLocIndex]); - for(int nDevIndex(0); nDevIndex < vec.size(); ++nDevIndex) - { - CAlarmDeviceTreeItem * device = new CAlarmDeviceTreeItem(vec.at(nDevIndex).description, location); - device->setData(vec.at(nDevIndex).tag_name, Qt::ItemDataRole(TagRole)); - device->setData(TYPE_DEVGROUP, Qt::ItemDataRole(TypeRole)); - device->setData(vec.at(nDevIndex).domain, Qt::ItemDataRole(DomainRole)); - device->setData(vec.at(nDevIndex).location, Qt::ItemDataRole(LocationRole)); - device->setData(vec.at(nDevIndex).sub_system, Qt::ItemDataRole(SubsystemRole)); - device->setData(vec.at(nDevIndex).region, Qt::ItemDataRole(RegionRole)); - QModelIndex modelIndex = createIndex(nDevIndex, 0, device); - m_devTagIndex.insert(vec.at(nDevIndex).tag_name, modelIndex); - m_devNameIndex.insert(locDesc + "." + vec.at(nDevIndex).description, modelIndex); - } - } -} - -const HashIndex &CAlarmDeviceTreeModel::indexTagList() const -{ - return m_devTagIndex; -} - -const HashIndex &CAlarmDeviceTreeModel::indexNameList() const -{ - return m_devNameIndex; -} - -QModelIndex CAlarmDeviceTreeModel::indexOfDeviceTag(const QString &tag) -{ - return m_devTagIndex.value(tag, QModelIndex()); -} - -QModelIndex CAlarmDeviceTreeModel::indexOfDeviceName(const QString &name) -{ - return m_devNameIndex.value(name, QModelIndex()); -} - -QVariant CAlarmDeviceTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(section) - Q_UNUSED(orientation) - Q_UNUSED(role) - return QVariant(); -} - -QModelIndex CAlarmDeviceTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!hasIndex(row, column, parent)) - { - return QModelIndex(); - } - - CAlarmDeviceTreeItem *parentItem; - - if (!parent.isValid()) - { - parentItem = rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - CAlarmDeviceTreeItem *childItem = parentItem->child(row); - if (childItem) - { - return createIndex(row, column, childItem); - } - else - { - return QModelIndex(); - } -} - -QModelIndex CAlarmDeviceTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - CAlarmDeviceTreeItem *childItem = static_cast(index.internalPointer()); - - CAlarmDeviceTreeItem *parentItem = childItem->parentItem(); - if (parentItem == rootItem) - { - return QModelIndex(); - } - - return createIndex(parentItem->row(), 0, parentItem); -} - -int CAlarmDeviceTreeModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - { - return 0; - } - - CAlarmDeviceTreeItem *parentItem; - if (!parent.isValid()) - { - parentItem = rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - return parentItem->childCount(); -} - -int CAlarmDeviceTreeModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return static_cast(parent.internalPointer())->columnCount(); - } - else - { - return rootItem->columnCount(); - } -} - - -QVariant CAlarmDeviceTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.column()) - { - return QVariant(); - } - - CAlarmDeviceTreeItem *item = static_cast(index.internalPointer()); - if (Qt::DisplayRole == role) - { - const QString &deviceGroup = item->data(Qt::ItemDataRole(TagRole)).toString(); - if(deviceGroup.isEmpty()) - { - return item->data(Qt::DisplayRole).toString(); - } - return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(m_alarmDeviceGroupStatistical.value(deviceGroup,0)); - } - else if(Qt::CheckStateRole == role && QModelIndex() != index.parent()) - { - return item->data(Qt::CheckStateRole); - } - - return QVariant(); -} - -bool CAlarmDeviceTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid() || index.column()) - { - return false; - } - if(Qt::CheckStateRole == role) - { - emit itemCheckStateChanged(static_cast(index.internalPointer())->data(Qt::ItemDataRole(TagRole)).toString(), value.toBool()); - } - return static_cast(index.internalPointer())->setData(value, (Qt::ItemDataRole)role); -} - -Qt::ItemFlags CAlarmDeviceTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - if(!index.column()) - { - return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; - } - - return QAbstractItemModel::flags(index); -} - -void CAlarmDeviceTreeModel::setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state) -{ - if(!index.isValid()) - { - return; - } - CAlarmDeviceTreeItem * pItem = static_cast(index.internalPointer()); - if(pItem) - { - int nChildCount = pItem->childCount(); - for( int nIndex(0); nIndex < nChildCount; nIndex++) - { - pItem->child(nIndex)->setData(state, Qt::CheckStateRole); - emit itemCheckStateChanged(pItem->child(nIndex)->data(Qt::ItemDataRole(TagRole)).toString(), state); - } - } -} - -void CAlarmDeviceTreeModel::setAllDeviceCheckState(const Qt::CheckState &state) -{ - HashIndex::const_iterator iter = m_devTagIndex.constBegin(); - while (iter != m_devTagIndex.constEnd()) - { - CAlarmDeviceTreeItem * pItem = static_cast(iter.value().internalPointer()); - if(pItem) - { - pItem->setData(state, Qt::CheckStateRole); - emit itemCheckStateChanged(pItem->data(Qt::ItemDataRole(TagRole)).toString(), state); - } - ++iter; - } -} - -void CAlarmDeviceTreeModel::removeData() -{ - m_alarmDeviceGroupStatistical.clear(); - QModelIndex modelindex = QModelIndex(); - if(rootItem->childCount()>0) - { - beginRemoveRows(modelindex, 0, rootItem->childCount()-1); - rootItem->removeChildren(0, rootItem->childCount(), rootItem->columnCount()); - endRemoveRows(); - } -} - -QHash CAlarmDeviceTreeModel::getDeviceStatisticalInfo() -{ - return m_alarmDeviceGroupStatistical; -} - -void CAlarmDeviceTreeModel::slotDevTreeUpdate() -{ - m_alarmDeviceGroupStatistical.clear(); - m_alarmDeviceGroupStatistical = CAlarmMsgManage::instance()->getDeviceStatisticalInfo(); -} +#include "CAlarmDeviceTreeItem.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmMsgManage.h" +#include "CAlarmBaseData.h" +#include +#include "pub_logger_api/logger.h" +CAlarmDeviceTreeModel::CAlarmDeviceTreeModel(QObject *parent) + : QAbstractItemModel(parent) +{ + rootItem = new CAlarmDeviceTreeItem(); +} + +CAlarmDeviceTreeModel::~CAlarmDeviceTreeModel() +{ + m_devTagIndex.clear(); + m_devNameIndex.clear(); + delete rootItem; +} + +void CAlarmDeviceTreeModel::setupModelData(const QMap > locationInfos, const QList &locationList) +{ + for(int nLocIndex(0); nLocIndexgetPermLocationDesc(locationList[nLocIndex]); + CAlarmDeviceTreeItem * location = new CAlarmDeviceTreeItem(locDesc, rootItem); + location->setData(TYPE_LOCATION,Qt::ItemDataRole(TypeRole)); + const QVector vec = locationInfos.value(locationList[nLocIndex]); + for(int nDevIndex(0); nDevIndex < vec.size(); ++nDevIndex) + { + CAlarmDeviceTreeItem * device = new CAlarmDeviceTreeItem(vec.at(nDevIndex).description, location); + device->setData(vec.at(nDevIndex).tag_name, Qt::ItemDataRole(TagRole)); + device->setData(TYPE_DEVGROUP, Qt::ItemDataRole(TypeRole)); + device->setData(vec.at(nDevIndex).domain, Qt::ItemDataRole(DomainRole)); + device->setData(vec.at(nDevIndex).location, Qt::ItemDataRole(LocationRole)); + device->setData(vec.at(nDevIndex).sub_system, Qt::ItemDataRole(SubsystemRole)); + device->setData(vec.at(nDevIndex).region, Qt::ItemDataRole(RegionRole)); + QModelIndex modelIndex = createIndex(nDevIndex, 0, device); + m_devTagIndex.insert(vec.at(nDevIndex).tag_name, modelIndex); + m_devNameIndex.insert(locDesc + "." + vec.at(nDevIndex).description, modelIndex); + } + } +} + +const HashIndex &CAlarmDeviceTreeModel::indexTagList() const +{ + return m_devTagIndex; +} + +const HashIndex &CAlarmDeviceTreeModel::indexNameList() const +{ + return m_devNameIndex; +} + +QModelIndex CAlarmDeviceTreeModel::indexOfDeviceTag(const QString &tag) +{ + return m_devTagIndex.value(tag, QModelIndex()); +} + +QModelIndex CAlarmDeviceTreeModel::indexOfDeviceName(const QString &name) +{ + return m_devNameIndex.value(name, QModelIndex()); +} + +QVariant CAlarmDeviceTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CAlarmDeviceTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + CAlarmDeviceTreeItem *parentItem; + + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + CAlarmDeviceTreeItem *childItem = parentItem->child(row); + if (childItem) + { + return createIndex(row, column, childItem); + } + else + { + return QModelIndex(); + } +} + +QModelIndex CAlarmDeviceTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CAlarmDeviceTreeItem *childItem = static_cast(index.internalPointer()); + + CAlarmDeviceTreeItem *parentItem = childItem->parentItem(); + if (parentItem == rootItem) + { + return QModelIndex(); + } + + return createIndex(parentItem->row(), 0, parentItem); +} + +int CAlarmDeviceTreeModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + { + return 0; + } + + CAlarmDeviceTreeItem *parentItem; + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +int CAlarmDeviceTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return static_cast(parent.internalPointer())->columnCount(); + } + else + { + return rootItem->columnCount(); + } +} + + +QVariant CAlarmDeviceTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.column()) + { + return QVariant(); + } + + CAlarmDeviceTreeItem *item = static_cast(index.internalPointer()); + if (Qt::DisplayRole == role) + { + const QString &deviceGroup = item->data(Qt::ItemDataRole(TagRole)).toString(); + if(deviceGroup.isEmpty()) + { + return item->data(Qt::DisplayRole).toString(); + } + return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(m_alarmDeviceGroupStatistical.value(deviceGroup,0)); + } + else if(Qt::CheckStateRole == role && QModelIndex() != index.parent()) + { + return item->data(Qt::CheckStateRole); + } + + return QVariant(); +} + +bool CAlarmDeviceTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.column()) + { + return false; + } + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(static_cast(index.internalPointer())->data(Qt::ItemDataRole(TagRole)).toString(), value.toBool()); + } + return static_cast(index.internalPointer())->setData(value, (Qt::ItemDataRole)role); +} + +Qt::ItemFlags CAlarmDeviceTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + if(!index.column()) + { + return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; + } + + return QAbstractItemModel::flags(index); +} + +void CAlarmDeviceTreeModel::setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + CAlarmDeviceTreeItem * pItem = static_cast(index.internalPointer()); + if(pItem) + { + int nChildCount = pItem->childCount(); + for( int nIndex(0); nIndex < nChildCount; nIndex++) + { + pItem->child(nIndex)->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->child(nIndex)->data(Qt::ItemDataRole(TagRole)).toString(), state); + } + } +} + +void CAlarmDeviceTreeModel::setAllDeviceCheckState(const Qt::CheckState &state) +{ + HashIndex::const_iterator iter = m_devTagIndex.constBegin(); + while (iter != m_devTagIndex.constEnd()) + { + CAlarmDeviceTreeItem * pItem = static_cast(iter.value().internalPointer()); + if(pItem) + { + pItem->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::ItemDataRole(TagRole)).toString(), state); + } + ++iter; + } +} + +void CAlarmDeviceTreeModel::removeData() +{ + m_alarmDeviceGroupStatistical.clear(); + QModelIndex modelindex = QModelIndex(); + if(rootItem->childCount()>0) + { + beginRemoveRows(modelindex, 0, rootItem->childCount()-1); + rootItem->removeChildren(0, rootItem->childCount(), rootItem->columnCount()); + endRemoveRows(); + } +} + +QHash CAlarmDeviceTreeModel::getDeviceStatisticalInfo() +{ + return m_alarmDeviceGroupStatistical; +} + +void CAlarmDeviceTreeModel::slotDevTreeUpdate() +{ + m_alarmDeviceGroupStatistical.clear(); + m_alarmDeviceGroupStatistical = CAlarmMsgManage::instance()->getDeviceStatisticalInfo(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.h b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.h index 17d9d74f..4a4e7208 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.h @@ -1,124 +1,124 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CALARMDEVICETREEMODEL_H -#define CALARMDEVICETREEMODEL_H - -#include "CAlarmCommon.h" -#include -#include -#include -#include - -enum enTreeNodeType{ - TYPE_LOCATION = 0, - TYPE_DEVGROUP -}; -typedef QHash< QString, QModelIndex > HashIndex; //< Device - -class CAlarmDeviceTreeItem; - -class CAlarmDeviceTreeModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - explicit CAlarmDeviceTreeModel(QObject *parent = 0); - ~CAlarmDeviceTreeModel(); - - //< @param locationInfos [ locationDesc[ devTag, devDesc ] ] - void setupModelData(const QMap > locationInfos, const QList &locationList); - - const HashIndex &indexTagList() const; - - const HashIndex &indexNameList() const; - - QModelIndex indexOfDeviceTag(const QString &tag); - - QModelIndex indexOfDeviceName(const QString &name); - - QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - void setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state); - - void setAllDeviceCheckState(const Qt::CheckState &state); - - void removeData(); - - QHash getDeviceStatisticalInfo(); - -signals: - void itemCheckStateChanged(const QString &device, const bool &checked); - - void inhibitDevGroupAlm(const QString &devGroup, int nDomain, int nLocation, int nSubsystem, int nRegion); - -public slots: - void slotDevTreeUpdate(); -private: - CAlarmDeviceTreeItem *rootItem; - HashIndex m_devTagIndex; - HashIndex m_devNameIndex; - HashIndex m_devGroupIndex; - QHash m_alarmDeviceGroupStatistical; //<设备组告警数量统计 -}; - -#endif // CALARMDEVICETREEMODEL_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CALARMDEVICETREEMODEL_H +#define CALARMDEVICETREEMODEL_H + +#include "CAlarmCommon.h" +#include +#include +#include +#include + +enum enTreeNodeType{ + TYPE_LOCATION = 0, + TYPE_DEVGROUP +}; +typedef QHash< QString, QModelIndex > HashIndex; //< Device + +class CAlarmDeviceTreeItem; + +class CAlarmDeviceTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CAlarmDeviceTreeModel(QObject *parent = 0); + ~CAlarmDeviceTreeModel(); + + //< @param locationInfos [ locationDesc[ devTag, devDesc ] ] + void setupModelData(const QMap > locationInfos, const QList &locationList); + + const HashIndex &indexTagList() const; + + const HashIndex &indexNameList() const; + + QModelIndex indexOfDeviceTag(const QString &tag); + + QModelIndex indexOfDeviceName(const QString &name); + + QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void setAllDeviceCheckState(const Qt::CheckState &state); + + void removeData(); + + QHash getDeviceStatisticalInfo(); + +signals: + void itemCheckStateChanged(const QString &device, const bool &checked); + + void inhibitDevGroupAlm(const QString &devGroup, int nDomain, int nLocation, int nSubsystem, int nRegion); + +public slots: + void slotDevTreeUpdate(); +private: + CAlarmDeviceTreeItem *rootItem; + HashIndex m_devTagIndex; + HashIndex m_devNameIndex; + HashIndex m_devGroupIndex; + QHash m_alarmDeviceGroupStatistical; //<设备组告警数量统计 +}; + +#endif // CALARMDEVICETREEMODEL_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.cpp index a6bd46c5..485c5238 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.cpp @@ -1,57 +1,57 @@ -#include "CAlarmDeviceTreeView.h" -#include "CAlarmDeviceTreeModel.h" -#include "CAlarmDeviceTreeItem.h" -#include -#include - -CAlarmDeviceTreeView::CAlarmDeviceTreeView(QWidget *parent) - : QTreeView(parent) -{ - -} - -void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) -{ - CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR != pModel) - { - QMenu menu; - CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); - if (pItem) - { - if(pItem->data(Qt::ItemDataRole(TypeRole)).toInt() == TYPE_DEVGROUP) - { - menu.addAction(tr("禁止告警"), [=](){ emit pModel->inhibitDevGroupAlm(pItem->data(Qt::ItemDataRole(TagRole)).toString(), - pItem->data(Qt::ItemDataRole(DomainRole)).toInt(), - pItem->data(Qt::ItemDataRole(LocationRole)).toInt(), - pItem->data(Qt::ItemDataRole(SubsystemRole)).toInt(), - pItem->data(Qt::ItemDataRole(RegionRole)).toInt()); }); - - menu.exec(event->globalPos()); - } - } - } - return; -} - -//void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) -//{ -// CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); -// if(Q_NULLPTR != pModel) -// { -// QMenu menu; -// CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); -// if (Q_NULLPTR == pItem) -// { -// menu.addAction(tr("全选"), [=](){ pModel->setAllDeviceCheckState(Qt::Checked); }); -// menu.addAction(tr("清空"), [=](){ pModel->setAllDeviceCheckState(Qt::Unchecked); }); -// } -// else if (Q_NULLPTR != pItem && pItem->childCount() > 0) -// { -// menu.addAction(tr("选择"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Checked); }); -// menu.addAction(tr("清除"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Unchecked); }); -// } -// menu.exec(event->globalPos()); -// } -// return; -//} +#include "CAlarmDeviceTreeView.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmDeviceTreeItem.h" +#include +#include + +CAlarmDeviceTreeView::CAlarmDeviceTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} + +void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QMenu menu; + CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if (pItem) + { + if(pItem->data(Qt::ItemDataRole(TypeRole)).toInt() == TYPE_DEVGROUP) + { + menu.addAction(tr("禁止告警"), [=](){ emit pModel->inhibitDevGroupAlm(pItem->data(Qt::ItemDataRole(TagRole)).toString(), + pItem->data(Qt::ItemDataRole(DomainRole)).toInt(), + pItem->data(Qt::ItemDataRole(LocationRole)).toInt(), + pItem->data(Qt::ItemDataRole(SubsystemRole)).toInt(), + pItem->data(Qt::ItemDataRole(RegionRole)).toInt()); }); + + menu.exec(event->globalPos()); + } + } + } + return; +} + +//void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) +//{ +// CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); +// if(Q_NULLPTR != pModel) +// { +// QMenu menu; +// CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); +// if (Q_NULLPTR == pItem) +// { +// menu.addAction(tr("全选"), [=](){ pModel->setAllDeviceCheckState(Qt::Checked); }); +// menu.addAction(tr("清空"), [=](){ pModel->setAllDeviceCheckState(Qt::Unchecked); }); +// } +// else if (Q_NULLPTR != pItem && pItem->childCount() > 0) +// { +// menu.addAction(tr("选择"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Checked); }); +// menu.addAction(tr("清除"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Unchecked); }); +// } +// menu.exec(event->globalPos()); +// } +// return; +//} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.h b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.h index 58276451..b2f6d6d5 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.h @@ -1,16 +1,16 @@ -#ifndef CALARMDEVICETREEVIEW_H -#define CALARMDEVICETREEVIEW_H - -#include - -class CAlarmDeviceTreeView : public QTreeView -{ - Q_OBJECT -public: - CAlarmDeviceTreeView(QWidget *parent = Q_NULLPTR); - -protected: - void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // CALARMDEVICETREEVIEW_H +#ifndef CALARMDEVICETREEVIEW_H +#define CALARMDEVICETREEVIEW_H + +#include + +class CAlarmDeviceTreeView : public QTreeView +{ + Q_OBJECT +public: + CAlarmDeviceTreeView(QWidget *parent = Q_NULLPTR); + +protected: + void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // CALARMDEVICETREEVIEW_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.cpp index 97de6278..d14357dd 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.cpp @@ -1,828 +1,828 @@ -#include "CAlarmFilterDialog.h" -#include "ui_CAlarmFilterDialog.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_utility_api/FileStyle.h" -#include "pub_logger_api/logger.h" -#include -#include -#include -#include -#include "CAlarmBaseData.h" - -int CAlarmFilterDialog::windowMinWidth() -{ - return m_nMinWidth; -} - -void CAlarmFilterDialog::setWindowMinWidth(int nWidth) -{ - m_nMinWidth = nWidth; - setMinimumWidth(m_nMinWidth); -} - -int CAlarmFilterDialog::windowMinHeigth() -{ - return m_nMinHeight; -} - -void CAlarmFilterDialog::setWindowMinHeigth(int nHeight) -{ - m_nMinHeight = nHeight; - setMinimumHeight(m_nMinHeight); -} - -CAlarmFilterDialog::CAlarmFilterDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CAlarmFilterDialog), - m_rtdbAccess(Q_NULLPTR), - m_nMinWidth(657), - m_nMinHeight(510) -{ - ui->setupUi(this); - setObjectName("alarm_dialog"); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - ui->subSystem->setView(new QListView()); - ui->deviceType->setView(new QListView()); - m_priorityMap = CAlarmBaseData::instance()->getPermPriorityMap(); - m_locationMap = CAlarmBaseData::instance()->getPermLocationMap(); - m_regionMap = CAlarmBaseData::instance()->getPermRegionMap(); - m_alarmStatusMap = CAlarmBaseData::instance()->getAlarmShowStatusMap(); - m_areaLocMap = CAlarmBaseData::instance()->getAreaLocMap(); - m_areaInfoMap= CAlarmBaseData::instance()->getAreaInfoMap(); -} - -CAlarmFilterDialog::~CAlarmFilterDialog() -{ - if(m_rtdbAccess) - { - delete m_rtdbAccess; - } - m_rtdbAccess = Q_NULLPTR; - delete ui; -} - -void CAlarmFilterDialog::initialize() -{ - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - ui->level->setSelectionMode(QAbstractItemView::MultiSelection); - //ui->location->setSelectionMode(QAbstractItemView::MultiSelection); - ui->region->setSelectionMode(QAbstractItemView::MultiSelection); - ui->status->setSelectionMode(QAbstractItemView::MultiSelection); - - foreach (QString value, m_priorityMap) - { - ui->level->addItem(value); - } - ui->area->clear(); - ui->area->setColumnCount(1); - bool isArea = false; - QMap >::iterator it = m_areaLocMap.begin(); - while (it != m_areaLocMap.end()) { - if(it.key()<= 0) - { - QVector locVec = it.value(); - for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); - firstItem->setData(0,Qt::UserRole,locVec.at(index)); - firstItem->setData(0,Qt::UserRole+1,it.key()); - firstItem->setCheckState(0,Qt::Unchecked); - firstItem->setToolTip(0,getDescByAreaId(locVec.at(index))); - ui->area->addTopLevelItem(firstItem); - } - }else - { - QTreeWidgetItem *firstItem = new QTreeWidgetItem(); - firstItem->setText(0,getDescByAreaId(it.key())); - firstItem->setData(0,Qt::UserRole,it.key()); - firstItem->setData(0,Qt::UserRole+1,-1); - firstItem->setCheckState(0,Qt::Unchecked); - firstItem->setToolTip(0,getDescByAreaId(it.key())); - QVector locVec = it.value(); - for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); - secondItem->setData(0,Qt::UserRole,locVec.at(index)); - secondItem->setData(0,Qt::UserRole+1,it.key()); - secondItem->setCheckState(0,Qt::Unchecked); - secondItem->setToolTip(0,getDescByAreaId(locVec.at(index))); - firstItem->addChild(secondItem); - } - ui->area->addTopLevelItem(firstItem); - isArea = true; - } - - it++; - } - //< 无区域配置时不缩进,尽可能展示完全 - if(!isArea) - { - ui->area->setIndentation(0); - } - foreach (QString value, m_regionMap) - { - ui->region->addItem(value); - } - - foreach (QString value, m_alarmStatusMap) - { - ui->status->addItem(value); - } - - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - std::vector vecSubsystemInfo; - spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); - foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) - { - if(info.nId <= CN_AppId_COMAPP) - { - continue; - } - ui->subSystem->addItem(QString::fromStdString(info.strDesc)); - } - } - - ui->subSystem->setCurrentIndex(-1); - - connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); - connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); - connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); - connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); - connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); - connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); - connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); - connect(ui->area,&QTreeWidget::itemChanged, this, &CAlarmFilterDialog::slot_updateCheckLocationState); - connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); - connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); - connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); - connect(ui->checkStatus, SIGNAL(pressed()), this, SLOT(slot_checkStatusPressed())); - connect(ui->checkStatus, SIGNAL(stateChanged(int)), this, SLOT(slot_statusSelectChange(int))); - connect(ui->status, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckStatusState())); - connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); - if(ui->subSystem->count() > 0) - { - ui->subSystem->setCurrentIndex(0); - } -} - -void CAlarmFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) -{ - ui->levelFilter->setChecked(isLevelFilterEnable); -} - -void CAlarmFilterDialog::setLevelFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->level->count(); nIndex++) - { - int nLevelID = m_priorityMap.key(ui->level->item(nIndex)->text()); - if(filter.contains(nLevelID)) - { - ui->level->item(nIndex)->setSelected(true); - } - else - { - ui->level->item(nIndex)->setSelected(false); - } - } -} - -void CAlarmFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) -{ - ui->locationFilter->setChecked(isLocationFilterEnable); -} - -void CAlarmFilterDialog::setLocationFilter(const QList &filter) -{ - if(filter.isEmpty()) - { - return; - } - ui->area->blockSignals(true); - int count = ui->area->topLevelItemCount(); - for(int index(0);indexarea->topLevelItem(index); - int areaId = firstItem->data(0,Qt::UserRole).toInt(); - if(filter.contains(areaId)) - { - firstItem->setCheckState(0,Qt::Checked); - } - int childCount = firstItem->childCount(); - - for(int locIndex(0);locIndex child(locIndex); - int locId = secondItem->data(0,Qt::UserRole).toInt(); - if(filter.contains(locId)) - { - secondItem->setCheckState(0,Qt::Checked); - } - } - } - int selectNum = 0; - int allNum = 0; - for(int index(0);indexarea->topLevelItem(index); - if(firstItem->checkState(0) == Qt::Checked) - { - selectNum += 1; - } - int childNum = firstItem->childCount(); - for(int secIndex(0);secIndexchild(secIndex); - allNum++; - if(secondItem->checkState(0) == Qt::Checked) - { - selectNum += 1; - } - } - } - - if(selectNum == 0) - { - ui->checkLocation->setCheckState(Qt::Unchecked); - }else if(selectNum == allNum) - { - ui->checkLocation->setCheckState(Qt::Checked); - }else - { - ui->checkLocation->setCheckState(Qt::PartiallyChecked); - } - ui->area->blockSignals(false); -} - -void CAlarmFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) -{ - ui->regionFilter->setChecked(isRegionFilterEnable); -} - -void CAlarmFilterDialog::setRegionFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->region->count(); nIndex++) - { - int nRegionID = m_regionMap.key(ui->region->item(nIndex)->text()); - if(filter.contains(nRegionID)) - { - ui->region->item(nIndex)->setSelected(true); - } - else - { - ui->region->item(nIndex)->setSelected(false); - } - } -} - -void CAlarmFilterDialog::setAlarmStatusFilterEnable(const bool &isAlarmStatusEnable) -{ - ui->alarmStatusFilter->setChecked(isAlarmStatusEnable); -} - -void CAlarmFilterDialog::setAlarmStatusFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->status->count(); nIndex++) - { - int nAlarmTypeID = m_alarmStatusMap.key(ui->status->item(nIndex)->text()); - if(filter.contains(nAlarmTypeID)) - { - ui->status->item(nIndex)->setSelected(true); - } - else - { - ui->status->item(nIndex)->setSelected(false); - } - } -} - -void CAlarmFilterDialog::setDeviceFilterEnable(const bool &filter) -{ - ui->deviceFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setSubSystem(const QString &subSystem) -{ - if(ui->deviceFilterEnable->isChecked()) - { - ui->subSystem->setCurrentText(subSystem); - } -} - -void CAlarmFilterDialog::setDeviceType(const QString &deviceType) -{ - if(ui->deviceFilterEnable->isChecked()) - { - ui->deviceType->setCurrentText(deviceType); - } -} - -void CAlarmFilterDialog::setTimeFilterEnable(const bool &filter) -{ - ui->timeFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setStartTimeFilter(const QDateTime &filter) -{ - if(ui->timeFilterEnable->isChecked()) - { - ui->startTime->setDateTime(filter); - } - else - { - QDateTime dataTime(QDateTime::currentDateTime()); - dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),0,0)); - ui->startTime->setDateTime(dataTime); - } -} - -void CAlarmFilterDialog::setEndTimeFilter(const QDateTime &filter) -{ - if(ui->timeFilterEnable->isChecked()) - { - ui->endTime->setDateTime(filter); - } - else - { - QDateTime dataTime(QDateTime::currentDateTime()); - dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),59,999)); - ui->endTime->setDateTime(dataTime); - } -} - -void CAlarmFilterDialog::setStateFilterEnable(const bool &filter) -{ - ui->stateFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setStateFilter(const bool &filter) -{ - if(filter) - { - ui->confirm->setChecked(true); - } - else - { - ui->unConfirm->setChecked(true); - } -} - -void CAlarmFilterDialog::setkeyWordFilterEnable(const bool &filter) -{ - ui->keywordFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setkeyWordFilteContent(const QString &content) -{ - if(ui->keywordFilterEnable->isChecked()) - { - ui->keyWord->setText(content); - } -} - -void CAlarmFilterDialog::setReturnFilterEnable(const bool &filter) -{ - ui->returnFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setReturnFilter(const bool &filter) -{ - if(filter) - { - ui->hasReturn->setChecked(true); - } - else - { - ui->notReturn->setChecked(true); - } -} - -void CAlarmFilterDialog::slot_updateFilter() -{ - bool isLevelFilter = ui->levelFilter->isChecked(); - QList listLevel; - foreach (QListWidgetItem *item, ui->level->selectedItems()) - { - listLevel << m_priorityMap.key(item->text()); - } - - bool isLocationFilter = ui->locationFilter->isChecked(); - QList listLocation; - - int count = ui->area->topLevelItemCount(); - for(int index(0);indexarea->topLevelItem(index); - if(firstItem->checkState(0) == Qt::Checked) - { - listLocation.append(firstItem->data(0,Qt::UserRole).toInt()); - } - int locCount = firstItem->childCount(); - for(int locIndex(0);locIndexchild(locIndex); - if(secondItem->checkState(0) == Qt::Checked) - { - listLocation.append(secondItem->data(0,Qt::UserRole).toInt()); - } - } - } - - bool isRegionFilter = ui->regionFilter->isChecked(); - QList listRegion; - foreach (QListWidgetItem *item, ui->region->selectedItems()) - { - listRegion << m_regionMap.key(item->text()); - } - - bool isAlarmStatusFilter = ui->alarmStatusFilter->isChecked(); - QList listAlarmStatus; - foreach (QListWidgetItem *item, ui->status->selectedItems()) - { - listAlarmStatus << m_alarmStatusMap.key(item->text()); - } - - bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); - QString subSystem = ui->subSystem->currentText(); - QString deviceType = ui->deviceType->currentText(); - - bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); - QString strKeyWord =ui->keyWord->text(); - - bool isTimeFilter = ui->timeFilterEnable->isChecked(); - QDateTime startTime = QDateTime(); - QDateTime endTime = QDateTime(); - if(isTimeFilter) - { - startTime = ui->startTime->dateTime(); - endTime = ui->endTime->dateTime(); - } - - bool isConfirmFilter = ui->stateFilterEnable->isChecked(); - bool confirm = ui->confirm->isChecked(); - bool isReturnFilter =ui->returnFilterEnable->isChecked(); - bool breturn = ui->hasReturn->isChecked(); - - emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmStatusFilter, listAlarmStatus, - isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,breturn); - accept(); -} - -//Level -void CAlarmFilterDialog::slot_checkLevelPressed() -{ - if( Qt::Unchecked == ui->checkLevel->checkState()) - { - ui->checkLevel->setTristate(false); - } -} - -void CAlarmFilterDialog::slot_levelSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->level->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->level->selectAll(); - } -} - -void CAlarmFilterDialog::slot_updateCheckLevelState() -{ - if( ui->level->count() == ui->level->selectedItems().count() ) - { - if( Qt::Checked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->level->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Location -void CAlarmFilterDialog::slot_checkLocationPressed() -{ - if( Qt::Unchecked == ui->checkLocation->checkState()) - { - ui->checkLocation->setTristate(false); - } -} - -void CAlarmFilterDialog::slot_locationSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - clearTreeSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - allTreeSelection(); - } -} - -void CAlarmFilterDialog::slot_updateCheckLocationState(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - ui->area->blockSignals(true); - if(item->parent() == NULL) //父节点 - { - childItemSelection(item); - }else if(item->childCount()<= 0) //子节点 - { - //parentItemSelection(item); - } - - int selectNum = 0; - int count = ui->area->topLevelItemCount(); - int allNum = 0; - for(int index(0);indexarea->topLevelItem(index); - if(firstItem->checkState(0) == Qt::Checked) - { - selectNum += 1; - } - int childNum = firstItem->childCount(); - for(int secIndex(0);secIndexchild(secIndex); - allNum++; - if(secondItem->checkState(0) == Qt::Checked) - { - selectNum += 1; - } - } - } - - if(selectNum == 0) - { - ui->checkLocation->setCheckState(Qt::Unchecked); - }else if(selectNum == allNum) - { - ui->checkLocation->setCheckState(Qt::Checked); - }else - { - ui->checkLocation->setCheckState(Qt::PartiallyChecked); - } - - - ui->area->blockSignals(false); -} - -//Region -void CAlarmFilterDialog::slot_checkRegionPressed() -{ - if( Qt::Unchecked == ui->checkRegion->checkState()) - { - ui->checkRegion->setTristate(false); - } -} - -void CAlarmFilterDialog::slot_regionSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->region->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->region->selectAll(); - } -} - -void CAlarmFilterDialog::slot_updateCheckRegionState() -{ - if( ui->region->count() == ui->region->selectedItems().count() ) - { - if( Qt::Checked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->region->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Type -void CAlarmFilterDialog::slot_checkStatusPressed() -{ - if( Qt::Unchecked == ui->checkStatus->checkState()) - { - ui->checkStatus->setTristate(false); - } -} - -void CAlarmFilterDialog::slot_statusSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->status->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->status->selectAll(); - } -} - -void CAlarmFilterDialog::slot_updateCheckStatusState() -{ - if( ui->status->count() == ui->status->selectedItems().count() ) - { - if( Qt::Checked != ui->checkStatus->checkState() ) - { - ui->checkStatus->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->status->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkStatus->checkState() ) - { - ui->checkStatus->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkStatus->checkState() ) - { - ui->checkStatus->setCheckState(Qt::PartiallyChecked); - } - } -} - -void CAlarmFilterDialog::slot_updateDevice(const QString &subSystem) -{ - int nSubSystemId = -1; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - std::vector vecSubsystemInfo; - spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); - foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) - { - if(subSystem.toStdString() == info.strDesc) - { - nSubSystemId = info.nId; - } - } - } - - ui->deviceType->clear(); - - QList values; - - if(nSubSystemId != -1) - { - kbd_dbms::CVarType subSystemId = nSubSystemId; - if(m_rtdbAccess->open("base", "dev_type_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CONDINFO condition; - condition.relationop = ATTRCOND_EQU; - memcpy(condition.name, "sub_system", strlen("sub_system") ); - condition.conditionval = subSystemId; - std::vector columns; - columns.push_back("description"); - - kbd_dbms::CRdbQueryResult result; - if(m_rtdbAccess->select(condition, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, value); - values.append(value); - } - } - } - } - foreach (kbd_dbms::CVarType value, values) - { - ui->deviceType->addItem(value.c_str()); - } -} - -QString CAlarmFilterDialog::getDescByAreaId(int areaId) -{ - SAreaInfo info; - return m_areaInfoMap.value(areaId,info).stDes; -} - -void CAlarmFilterDialog::clearTreeSelection() -{ - int count = ui->area->topLevelItemCount(); - for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Unchecked); - slot_updateCheckLocationState(ui->area->topLevelItem(index),0); - } -} - -void CAlarmFilterDialog::childItemSelection(QTreeWidgetItem *item) -{ - Qt::CheckState status = item->checkState(0); - - int count = item->childCount(); - for(int index(0);indexchild(index)->setCheckState(0,status); - } -} - -void CAlarmFilterDialog::parentItemSelection(QTreeWidgetItem *item) -{ - QTreeWidgetItem *parent = item->parent(); - int count = parent->childCount(); - int checkNum = 0; - for(int index(0);indexchild(index)->checkState(0) == Qt::Checked) - { - checkNum += 1; - } - } - if(checkNum == count) - { - parent->setCheckState(0,Qt::Checked); - }else if(checkNum == 0) - { - parent->setCheckState(0,Qt::Unchecked); - }else - { - parent->setCheckState(0,Qt::PartiallyChecked); - } -} - -void CAlarmFilterDialog::allTreeSelection() -{ - int count = ui->area->topLevelItemCount(); - for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Checked); - slot_updateCheckLocationState(ui->area->topLevelItem(index),0); - } -} +#include "CAlarmFilterDialog.h" +#include "ui_CAlarmFilterDialog.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include +#include "CAlarmBaseData.h" + +int CAlarmFilterDialog::windowMinWidth() +{ + return m_nMinWidth; +} + +void CAlarmFilterDialog::setWindowMinWidth(int nWidth) +{ + m_nMinWidth = nWidth; + setMinimumWidth(m_nMinWidth); +} + +int CAlarmFilterDialog::windowMinHeigth() +{ + return m_nMinHeight; +} + +void CAlarmFilterDialog::setWindowMinHeigth(int nHeight) +{ + m_nMinHeight = nHeight; + setMinimumHeight(m_nMinHeight); +} + +CAlarmFilterDialog::CAlarmFilterDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmFilterDialog), + m_rtdbAccess(Q_NULLPTR), + m_nMinWidth(657), + m_nMinHeight(510) +{ + ui->setupUi(this); + setObjectName("alarm_dialog"); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + ui->subSystem->setView(new QListView()); + ui->deviceType->setView(new QListView()); + m_priorityMap = CAlarmBaseData::instance()->getPermPriorityMap(); + m_locationMap = CAlarmBaseData::instance()->getPermLocationMap(); + m_regionMap = CAlarmBaseData::instance()->getPermRegionMap(); + m_alarmStatusMap = CAlarmBaseData::instance()->getAlarmShowStatusMap(); + m_areaLocMap = CAlarmBaseData::instance()->getAreaLocMap(); + m_areaInfoMap= CAlarmBaseData::instance()->getAreaInfoMap(); +} + +CAlarmFilterDialog::~CAlarmFilterDialog() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + delete ui; +} + +void CAlarmFilterDialog::initialize() +{ + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + ui->level->setSelectionMode(QAbstractItemView::MultiSelection); + //ui->location->setSelectionMode(QAbstractItemView::MultiSelection); + ui->region->setSelectionMode(QAbstractItemView::MultiSelection); + ui->status->setSelectionMode(QAbstractItemView::MultiSelection); + + foreach (QString value, m_priorityMap) + { + ui->level->addItem(value); + } + ui->area->clear(); + ui->area->setColumnCount(1); + bool isArea = false; + QMap >::iterator it = m_areaLocMap.begin(); + while (it != m_areaLocMap.end()) { + if(it.key()<= 0) + { + QVector locVec = it.value(); + for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); + firstItem->setData(0,Qt::UserRole,locVec.at(index)); + firstItem->setData(0,Qt::UserRole+1,it.key()); + firstItem->setCheckState(0,Qt::Unchecked); + firstItem->setToolTip(0,getDescByAreaId(locVec.at(index))); + ui->area->addTopLevelItem(firstItem); + } + }else + { + QTreeWidgetItem *firstItem = new QTreeWidgetItem(); + firstItem->setText(0,getDescByAreaId(it.key())); + firstItem->setData(0,Qt::UserRole,it.key()); + firstItem->setData(0,Qt::UserRole+1,-1); + firstItem->setCheckState(0,Qt::Unchecked); + firstItem->setToolTip(0,getDescByAreaId(it.key())); + QVector locVec = it.value(); + for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); + secondItem->setData(0,Qt::UserRole,locVec.at(index)); + secondItem->setData(0,Qt::UserRole+1,it.key()); + secondItem->setCheckState(0,Qt::Unchecked); + secondItem->setToolTip(0,getDescByAreaId(locVec.at(index))); + firstItem->addChild(secondItem); + } + ui->area->addTopLevelItem(firstItem); + isArea = true; + } + + it++; + } + //< 无区域配置时不缩进,尽可能展示完全 + if(!isArea) + { + ui->area->setIndentation(0); + } + foreach (QString value, m_regionMap) + { + ui->region->addItem(value); + } + + foreach (QString value, m_alarmStatusMap) + { + ui->status->addItem(value); + } + + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(info.nId <= CN_AppId_COMAPP) + { + continue; + } + ui->subSystem->addItem(QString::fromStdString(info.strDesc)); + } + } + + ui->subSystem->setCurrentIndex(-1); + + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); + connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); + connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); + connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); + connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); + connect(ui->area,&QTreeWidget::itemChanged, this, &CAlarmFilterDialog::slot_updateCheckLocationState); + connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); + connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); + connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); + connect(ui->checkStatus, SIGNAL(pressed()), this, SLOT(slot_checkStatusPressed())); + connect(ui->checkStatus, SIGNAL(stateChanged(int)), this, SLOT(slot_statusSelectChange(int))); + connect(ui->status, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckStatusState())); + connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); + if(ui->subSystem->count() > 0) + { + ui->subSystem->setCurrentIndex(0); + } +} + +void CAlarmFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) +{ + ui->levelFilter->setChecked(isLevelFilterEnable); +} + +void CAlarmFilterDialog::setLevelFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->level->count(); nIndex++) + { + int nLevelID = m_priorityMap.key(ui->level->item(nIndex)->text()); + if(filter.contains(nLevelID)) + { + ui->level->item(nIndex)->setSelected(true); + } + else + { + ui->level->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) +{ + ui->locationFilter->setChecked(isLocationFilterEnable); +} + +void CAlarmFilterDialog::setLocationFilter(const QList &filter) +{ + if(filter.isEmpty()) + { + return; + } + ui->area->blockSignals(true); + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index); + int areaId = firstItem->data(0,Qt::UserRole).toInt(); + if(filter.contains(areaId)) + { + firstItem->setCheckState(0,Qt::Checked); + } + int childCount = firstItem->childCount(); + + for(int locIndex(0);locIndex child(locIndex); + int locId = secondItem->data(0,Qt::UserRole).toInt(); + if(filter.contains(locId)) + { + secondItem->setCheckState(0,Qt::Checked); + } + } + } + int selectNum = 0; + int allNum = 0; + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + int childNum = firstItem->childCount(); + for(int secIndex(0);secIndexchild(secIndex); + allNum++; + if(secondItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + } + } + + if(selectNum == 0) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + }else if(selectNum == allNum) + { + ui->checkLocation->setCheckState(Qt::Checked); + }else + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + ui->area->blockSignals(false); +} + +void CAlarmFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) +{ + ui->regionFilter->setChecked(isRegionFilterEnable); +} + +void CAlarmFilterDialog::setRegionFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->region->count(); nIndex++) + { + int nRegionID = m_regionMap.key(ui->region->item(nIndex)->text()); + if(filter.contains(nRegionID)) + { + ui->region->item(nIndex)->setSelected(true); + } + else + { + ui->region->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setAlarmStatusFilterEnable(const bool &isAlarmStatusEnable) +{ + ui->alarmStatusFilter->setChecked(isAlarmStatusEnable); +} + +void CAlarmFilterDialog::setAlarmStatusFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->status->count(); nIndex++) + { + int nAlarmTypeID = m_alarmStatusMap.key(ui->status->item(nIndex)->text()); + if(filter.contains(nAlarmTypeID)) + { + ui->status->item(nIndex)->setSelected(true); + } + else + { + ui->status->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setDeviceFilterEnable(const bool &filter) +{ + ui->deviceFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setSubSystem(const QString &subSystem) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->subSystem->setCurrentText(subSystem); + } +} + +void CAlarmFilterDialog::setDeviceType(const QString &deviceType) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->deviceType->setCurrentText(deviceType); + } +} + +void CAlarmFilterDialog::setTimeFilterEnable(const bool &filter) +{ + ui->timeFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setStartTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->startTime->setDateTime(filter); + } + else + { + QDateTime dataTime(QDateTime::currentDateTime()); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),0,0)); + ui->startTime->setDateTime(dataTime); + } +} + +void CAlarmFilterDialog::setEndTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->endTime->setDateTime(filter); + } + else + { + QDateTime dataTime(QDateTime::currentDateTime()); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),59,999)); + ui->endTime->setDateTime(dataTime); + } +} + +void CAlarmFilterDialog::setStateFilterEnable(const bool &filter) +{ + ui->stateFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setStateFilter(const bool &filter) +{ + if(filter) + { + ui->confirm->setChecked(true); + } + else + { + ui->unConfirm->setChecked(true); + } +} + +void CAlarmFilterDialog::setkeyWordFilterEnable(const bool &filter) +{ + ui->keywordFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setkeyWordFilteContent(const QString &content) +{ + if(ui->keywordFilterEnable->isChecked()) + { + ui->keyWord->setText(content); + } +} + +void CAlarmFilterDialog::setReturnFilterEnable(const bool &filter) +{ + ui->returnFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setReturnFilter(const bool &filter) +{ + if(filter) + { + ui->hasReturn->setChecked(true); + } + else + { + ui->notReturn->setChecked(true); + } +} + +void CAlarmFilterDialog::slot_updateFilter() +{ + bool isLevelFilter = ui->levelFilter->isChecked(); + QList listLevel; + foreach (QListWidgetItem *item, ui->level->selectedItems()) + { + listLevel << m_priorityMap.key(item->text()); + } + + bool isLocationFilter = ui->locationFilter->isChecked(); + QList listLocation; + + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + listLocation.append(firstItem->data(0,Qt::UserRole).toInt()); + } + int locCount = firstItem->childCount(); + for(int locIndex(0);locIndexchild(locIndex); + if(secondItem->checkState(0) == Qt::Checked) + { + listLocation.append(secondItem->data(0,Qt::UserRole).toInt()); + } + } + } + + bool isRegionFilter = ui->regionFilter->isChecked(); + QList listRegion; + foreach (QListWidgetItem *item, ui->region->selectedItems()) + { + listRegion << m_regionMap.key(item->text()); + } + + bool isAlarmStatusFilter = ui->alarmStatusFilter->isChecked(); + QList listAlarmStatus; + foreach (QListWidgetItem *item, ui->status->selectedItems()) + { + listAlarmStatus << m_alarmStatusMap.key(item->text()); + } + + bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); + QString subSystem = ui->subSystem->currentText(); + QString deviceType = ui->deviceType->currentText(); + + bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); + QString strKeyWord =ui->keyWord->text(); + + bool isTimeFilter = ui->timeFilterEnable->isChecked(); + QDateTime startTime = QDateTime(); + QDateTime endTime = QDateTime(); + if(isTimeFilter) + { + startTime = ui->startTime->dateTime(); + endTime = ui->endTime->dateTime(); + } + + bool isConfirmFilter = ui->stateFilterEnable->isChecked(); + bool confirm = ui->confirm->isChecked(); + bool isReturnFilter =ui->returnFilterEnable->isChecked(); + bool breturn = ui->hasReturn->isChecked(); + + emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmStatusFilter, listAlarmStatus, + isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,breturn); + accept(); +} + +//Level +void CAlarmFilterDialog::slot_checkLevelPressed() +{ + if( Qt::Unchecked == ui->checkLevel->checkState()) + { + ui->checkLevel->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_levelSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->level->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->level->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckLevelState() +{ + if( ui->level->count() == ui->level->selectedItems().count() ) + { + if( Qt::Checked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->level->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Location +void CAlarmFilterDialog::slot_checkLocationPressed() +{ + if( Qt::Unchecked == ui->checkLocation->checkState()) + { + ui->checkLocation->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_locationSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + clearTreeSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + allTreeSelection(); + } +} + +void CAlarmFilterDialog::slot_updateCheckLocationState(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + ui->area->blockSignals(true); + if(item->parent() == NULL) //父节点 + { + childItemSelection(item); + }else if(item->childCount()<= 0) //子节点 + { + //parentItemSelection(item); + } + + int selectNum = 0; + int count = ui->area->topLevelItemCount(); + int allNum = 0; + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + int childNum = firstItem->childCount(); + for(int secIndex(0);secIndexchild(secIndex); + allNum++; + if(secondItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + } + } + + if(selectNum == 0) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + }else if(selectNum == allNum) + { + ui->checkLocation->setCheckState(Qt::Checked); + }else + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + + + ui->area->blockSignals(false); +} + +//Region +void CAlarmFilterDialog::slot_checkRegionPressed() +{ + if( Qt::Unchecked == ui->checkRegion->checkState()) + { + ui->checkRegion->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_regionSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->region->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->region->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckRegionState() +{ + if( ui->region->count() == ui->region->selectedItems().count() ) + { + if( Qt::Checked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->region->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Type +void CAlarmFilterDialog::slot_checkStatusPressed() +{ + if( Qt::Unchecked == ui->checkStatus->checkState()) + { + ui->checkStatus->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_statusSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->status->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->status->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckStatusState() +{ + if( ui->status->count() == ui->status->selectedItems().count() ) + { + if( Qt::Checked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->status->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::PartiallyChecked); + } + } +} + +void CAlarmFilterDialog::slot_updateDevice(const QString &subSystem) +{ + int nSubSystemId = -1; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(subSystem.toStdString() == info.strDesc) + { + nSubSystemId = info.nId; + } + } + } + + ui->deviceType->clear(); + + QList values; + + if(nSubSystemId != -1) + { + kbd_dbms::CVarType subSystemId = nSubSystemId; + if(m_rtdbAccess->open("base", "dev_type_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CONDINFO condition; + condition.relationop = ATTRCOND_EQU; + memcpy(condition.name, "sub_system", strlen("sub_system") ); + condition.conditionval = subSystemId; + std::vector columns; + columns.push_back("description"); + + kbd_dbms::CRdbQueryResult result; + if(m_rtdbAccess->select(condition, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, value); + values.append(value); + } + } + } + } + foreach (kbd_dbms::CVarType value, values) + { + ui->deviceType->addItem(value.c_str()); + } +} + +QString CAlarmFilterDialog::getDescByAreaId(int areaId) +{ + SAreaInfo info; + return m_areaInfoMap.value(areaId,info).stDes; +} + +void CAlarmFilterDialog::clearTreeSelection() +{ + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Unchecked); + slot_updateCheckLocationState(ui->area->topLevelItem(index),0); + } +} + +void CAlarmFilterDialog::childItemSelection(QTreeWidgetItem *item) +{ + Qt::CheckState status = item->checkState(0); + + int count = item->childCount(); + for(int index(0);indexchild(index)->setCheckState(0,status); + } +} + +void CAlarmFilterDialog::parentItemSelection(QTreeWidgetItem *item) +{ + QTreeWidgetItem *parent = item->parent(); + int count = parent->childCount(); + int checkNum = 0; + for(int index(0);indexchild(index)->checkState(0) == Qt::Checked) + { + checkNum += 1; + } + } + if(checkNum == count) + { + parent->setCheckState(0,Qt::Checked); + }else if(checkNum == 0) + { + parent->setCheckState(0,Qt::Unchecked); + }else + { + parent->setCheckState(0,Qt::PartiallyChecked); + } +} + +void CAlarmFilterDialog::allTreeSelection() +{ + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Checked); + slot_updateCheckLocationState(ui->area->topLevelItem(index),0); + } +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.h b/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.h index 9d29629d..90d42e3c 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.h @@ -1,123 +1,123 @@ -#ifndef CALARMFILTERDIALOG_H -#define CALARMFILTERDIALOG_H - -#include -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "CAlarmCommon.h" - -class QTreeWidgetItem; - -namespace Ui { -class CAlarmFilterDialog; -} - -class CAlarmFilterDialog : public QDialog -{ - Q_OBJECT - Q_PROPERTY(int windowMinWidth READ windowMinWidth WRITE setWindowMinWidth) - Q_PROPERTY(int windowMinHeigth READ windowMinHeigth WRITE setWindowMinHeigth) - -public slots: - int windowMinWidth(); - void setWindowMinWidth(int nWidth); - int windowMinHeigth(); - void setWindowMinHeigth(int nHeight); - -public: - explicit CAlarmFilterDialog(QWidget *parent = 0); - ~CAlarmFilterDialog(); - - void initialize(); - void setLevelFilterEnable(const bool &isLevelFilterEnable); - void setLevelFilter(const QList &filter); - void setLocationFilterEnable(const bool &isLocationFilterEnable); - void setLocationFilter(const QList &filter); - - void setRegionFilterEnable(const bool &isRegionFilterEnable); - void setRegionFilter(const QList &filter); - /** - * @brief setAlarmTypeFilterEnable 过滤窗新增告警状态代替告警类型 - * @param isAlarmTypeEnable - */ - void setAlarmStatusFilterEnable(const bool &isAlarmStatusEnable); - /** - * @brief setAlarmStatusFilter 过滤窗新增告警状态代替告警类型 - * @param filter - */ - void setAlarmStatusFilter(const QList &filter); - - void setDeviceFilterEnable(const bool &filter); - void setSubSystem(const QString &subSystem); - void setDeviceType(const QString &deviceType); - void setTimeFilterEnable(const bool &filter); - void setStartTimeFilter(const QDateTime &filter); - void setEndTimeFilter(const QDateTime &filter); - void setStateFilterEnable(const bool &filter); - void setStateFilter(const bool &filter); - void setkeyWordFilterEnable(const bool &filter); - void setkeyWordFilteContent(const QString &content); - void setReturnFilterEnable(const bool &filter); - void setReturnFilter(const bool &filter); -signals: - /** - * @brief sig_updateFilter - * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm - */ - void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool,bool,bool); - -private slots: - void slot_updateFilter(); - - //Level - void slot_checkLevelPressed(); - void slot_levelSelectChange(const int &state); - void slot_updateCheckLevelState(); - - //Station - void slot_checkLocationPressed(); - void slot_locationSelectChange(const int &state); - void slot_updateCheckLocationState(QTreeWidgetItem *item, int column); - - //Region - void slot_checkRegionPressed(); - void slot_regionSelectChange(const int &state); - void slot_updateCheckRegionState(); - - //AlarmStatus - void slot_checkStatusPressed(); - void slot_statusSelectChange(const int &state); - void slot_updateCheckStatusState(); - - //DeviceType - void slot_updateDevice(const QString &subSystem); - -private: - QString getDescByAreaId(int areaId); - void clearTreeSelection(); - void childItemSelection(QTreeWidgetItem *item); - void parentItemSelection(QTreeWidgetItem *item); - void allTreeSelection(); -private: - Ui::CAlarmFilterDialog *ui; - - kbd_dbms::CRdbAccess * m_rtdbAccess; - QMap m_priorityMap; - QMap m_locationMap; - QMap m_regionMap; - QMap m_alarmTypeMap; - /** - * @brief m_alarmStatusMap 过滤窗新增告警状态代替告警类型 - */ - QMap m_alarmStatusMap; - - QMap m_areaInfoMap; //区域信息 - - QMap > m_areaLocMap; //区域映射 - - int m_nMinWidth; - int m_nMinHeight; -}; - -#endif // ALARMFILTERDIALOG_H +#ifndef CALARMFILTERDIALOG_H +#define CALARMFILTERDIALOG_H + +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "CAlarmCommon.h" + +class QTreeWidgetItem; + +namespace Ui { +class CAlarmFilterDialog; +} + +class CAlarmFilterDialog : public QDialog +{ + Q_OBJECT + Q_PROPERTY(int windowMinWidth READ windowMinWidth WRITE setWindowMinWidth) + Q_PROPERTY(int windowMinHeigth READ windowMinHeigth WRITE setWindowMinHeigth) + +public slots: + int windowMinWidth(); + void setWindowMinWidth(int nWidth); + int windowMinHeigth(); + void setWindowMinHeigth(int nHeight); + +public: + explicit CAlarmFilterDialog(QWidget *parent = 0); + ~CAlarmFilterDialog(); + + void initialize(); + void setLevelFilterEnable(const bool &isLevelFilterEnable); + void setLevelFilter(const QList &filter); + void setLocationFilterEnable(const bool &isLocationFilterEnable); + void setLocationFilter(const QList &filter); + + void setRegionFilterEnable(const bool &isRegionFilterEnable); + void setRegionFilter(const QList &filter); + /** + * @brief setAlarmTypeFilterEnable 过滤窗新增告警状态代替告警类型 + * @param isAlarmTypeEnable + */ + void setAlarmStatusFilterEnable(const bool &isAlarmStatusEnable); + /** + * @brief setAlarmStatusFilter 过滤窗新增告警状态代替告警类型 + * @param filter + */ + void setAlarmStatusFilter(const QList &filter); + + void setDeviceFilterEnable(const bool &filter); + void setSubSystem(const QString &subSystem); + void setDeviceType(const QString &deviceType); + void setTimeFilterEnable(const bool &filter); + void setStartTimeFilter(const QDateTime &filter); + void setEndTimeFilter(const QDateTime &filter); + void setStateFilterEnable(const bool &filter); + void setStateFilter(const bool &filter); + void setkeyWordFilterEnable(const bool &filter); + void setkeyWordFilteContent(const QString &content); + void setReturnFilterEnable(const bool &filter); + void setReturnFilter(const bool &filter); +signals: + /** + * @brief sig_updateFilter + * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm + */ + void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool,bool,bool); + +private slots: + void slot_updateFilter(); + + //Level + void slot_checkLevelPressed(); + void slot_levelSelectChange(const int &state); + void slot_updateCheckLevelState(); + + //Station + void slot_checkLocationPressed(); + void slot_locationSelectChange(const int &state); + void slot_updateCheckLocationState(QTreeWidgetItem *item, int column); + + //Region + void slot_checkRegionPressed(); + void slot_regionSelectChange(const int &state); + void slot_updateCheckRegionState(); + + //AlarmStatus + void slot_checkStatusPressed(); + void slot_statusSelectChange(const int &state); + void slot_updateCheckStatusState(); + + //DeviceType + void slot_updateDevice(const QString &subSystem); + +private: + QString getDescByAreaId(int areaId); + void clearTreeSelection(); + void childItemSelection(QTreeWidgetItem *item); + void parentItemSelection(QTreeWidgetItem *item); + void allTreeSelection(); +private: + Ui::CAlarmFilterDialog *ui; + + kbd_dbms::CRdbAccess * m_rtdbAccess; + QMap m_priorityMap; + QMap m_locationMap; + QMap m_regionMap; + QMap m_alarmTypeMap; + /** + * @brief m_alarmStatusMap 过滤窗新增告警状态代替告警类型 + */ + QMap m_alarmStatusMap; + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 + + int m_nMinWidth; + int m_nMinHeight; +}; + +#endif // ALARMFILTERDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.ui b/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.ui index 77174ba7..697a1be9 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.ui @@ -1,470 +1,470 @@ - - - CAlarmFilterDialog - - - - 0 - 0 - 657 - 510 - - - - - 530 - 0 - - - - - 16777215 - 16777215 - - - - 过滤 - - - - - - - - 优先级 - - - true - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - 全选 - - - true - - - true - - - - - - - - - - - - - 位置 - - - true - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - 全选 - - - true - - - - - - - QAbstractItemView::NoSelection - - - false - - - - 1 - - - - - - - - - - - 责任区 - - - true - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - 全选 - - - true - - - - - - - - - - - - - 告警状态 - - - true - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - 全选 - - - true - - - - - - - - - - - - - - - - - - - 状态 - - - false - - - true - - - false - - - - - - 未确认 - - - - - - - 已确认 - - - true - - - - - - - - - - 告警内容关键字 - - - true - - - false - - - - - - - - - - - - - - 复归 - - - true - - - false - - - - - - 已复归 - - - true - - - - - - - 未复归 - - - - - - - - - - - - 设备类型 - - - true - - - false - - - - - - - - - - - - - - - - - - - - - - - 时间 - - - true - - - false - - - - - - - - 开始时间 - - - - - - - - 0 - 0 - 0 - 2018 - 1 - 1 - - - - - 2018 - 1 - 1 - - - - - 23 - 59 - 59 - 2050 - 12 - 31 - - - - - 2050 - 12 - 31 - - - - - 2000 - 1 - 1 - - - - yyyy/MM/dd hh:mm - - - - - - - - - - - 结束时间 - - - - - - - - 2018 - 1 - 1 - - - - - 2050 - 12 - 31 - - - - - 2000 - 1 - 1 - - - - yyyy/MM/dd hh:mm - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 281 - 20 - - - - - - - - 确定 - - - - - - - 取消 - - - - - - - - - - + + + CAlarmFilterDialog + + + + 0 + 0 + 657 + 510 + + + + + 530 + 0 + + + + + 16777215 + 16777215 + + + + 过滤 + + + + + + + + 优先级 + + + true + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 全选 + + + true + + + true + + + + + + + + + + + + + 位置 + + + true + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 全选 + + + true + + + + + + + QAbstractItemView::NoSelection + + + false + + + + 1 + + + + + + + + + + + 责任区 + + + true + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 全选 + + + true + + + + + + + + + + + + + 告警状态 + + + true + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 全选 + + + true + + + + + + + + + + + + + + + + + + + 状态 + + + false + + + true + + + false + + + + + + 未确认 + + + + + + + 已确认 + + + true + + + + + + + + + + 告警内容关键字 + + + true + + + false + + + + + + + + + + + + + + 复归 + + + true + + + false + + + + + + 已复归 + + + true + + + + + + + 未复归 + + + + + + + + + + + + 设备类型 + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + 时间 + + + true + + + false + + + + + + + + 开始时间 + + + + + + + + 0 + 0 + 0 + 2018 + 1 + 1 + + + + + 2018 + 1 + 1 + + + + + 23 + 59 + 59 + 2050 + 12 + 31 + + + + + 2050 + 12 + 31 + + + + + 2000 + 1 + 1 + + + + yyyy/MM/dd hh:mm + + + + + + + + + + + 结束时间 + + + + + + + + 2018 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + + 2000 + 1 + 1 + + + + yyyy/MM/dd hh:mm + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 281 + 20 + + + + + + + + 确定 + + + + + + + 取消 + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmForm.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmForm.cpp index d75d2961..e40845c1 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmForm.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmForm.cpp @@ -1,3054 +1,3054 @@ -#include "CAlarmForm.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ui_CAlarmForm.h" -#include "CAlarmDelegate.h" -#include "CAiAlarmDelegate.h" -#include "CAlarmItemModel.h" -#include "CAlarmFilterDialog.h" -#include "CAlarmMsgManage.h" -#include "CTableViewPrinter.h" -#include "CAlarmDataCollect.h" -#include "CAiAlarmDataCollect.h" -#include "CAlarmInhibitDialog.h" -#include "CAlarmDeviceTreeModel.h" -#include "CAlarmDeviceTreeItem.h" -#include "CAiAlarmTreeItem.h" -#include "CAiAlarmTreeModel.h" -#include "perm_mng_api/PermMngApi.h" -#include -#include -#include "CMyListWidget.h" -#include "CMyCheckBox.h" -#include "CDisposalPlanDialog.h" -#include "CTreeViewPrinter.h" -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileUtil.h" -#include -#include "CAlarmTaskMngDlg.h" -#include -#include "CAlarmSetDlg.h" -#include "CAlarmBaseData.h" -#include "CAlarmShiledDialog.h" -#include "CAccidentReviewDialog.h" -CAlarmForm::CAlarmForm(QWidget *parent) : - QWidget(parent), - m_ptrSysInfo(Q_NULLPTR), - m_pReadDb(Q_NULLPTR), - m_aiOptPerm(true), - m_pModel(Q_NULLPTR), - m_delegate(Q_NULLPTR), - m_aiDelegate(Q_NULLPTR), - m_treeModel(Q_NULLPTR), - m_communicator(Q_NULLPTR), - ui(new Ui::CAlarmForm), - m_isNormal(true), - m_isNeedAccidentReview(true), - m_strAccidenPath(QString()) -{ - m_communicator = new kbd_net::CMbCommunicator(); - qRegisterMetaType("QItemSelection"); - qRegisterMetaType< QList > >("QList >"); - qRegisterMetaType >("QVector"); - qRegisterMetaType >("QVector"); - qRegisterMetaType >("QVector"); - ui->setupUi(this); - ui->alarmView->setObjectName("alarmView"); - ui->splitter->setStretchFactor(0,1); - ui->splitter->setStretchFactor(1,6); - - QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->deviceView->header()); - m_pSearchTextEdit = new QLineEdit(ui->deviceView->header()); - m_pSearchTextEdit->setObjectName("searchTextEdit"); - m_pSearchTextEdit->setTextMargins(0, 0, 21, 0); - m_pSearchTextEdit->setPlaceholderText(tr("按设备组关键字搜索")); - pHBoxLayout->addWidget(m_pSearchTextEdit); - pHBoxLayout->setContentsMargins(2,0,2,0); - pHBoxLayout->setSpacing(0); - ui->deviceView->header()->setLayout(pHBoxLayout); - ui->deviceView->header()->setObjectName("deviceHeader"); - //ui->deviceView->header()->setFixedHeight(30); - - m_pSearchButton = new QPushButton(this); - m_pSearchButton->setObjectName("searchButton"); - m_pSearchButton->setText(""); - m_pSearchButton->setMaximumSize(21, 22); - m_pSearchButton->setCursor(QCursor(Qt::ArrowCursor)); - - QHBoxLayout * pSearchLayout = new QHBoxLayout(); - pSearchLayout->setContentsMargins(1, 1, 1, 1); - pSearchLayout->addStretch(); - pSearchLayout->addWidget(m_pSearchButton); - m_pSearchTextEdit->setLayout(pSearchLayout); - - connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CAlarmForm::searchDeviceName); - connect(m_pSearchButton, &QPushButton::clicked, this, &CAlarmForm::searchDeviceName); - m_pListWidget1 = new CMyListWidget(this); - m_pListWidget2 = new CMyListWidget(this); - m_pListWidget3 = new CMyListWidget(this); - m_pLineEdit1 = new QLineEdit(this); - m_pLineEdit2 = new QLineEdit(this); - m_pLineEdit3 = new QLineEdit(this); - m_timeIcon = new QPushButton(this); - //时间过滤 - m_myCalendar = new CMyCalendar(this); - QWidgetAction *widgetAction=new QWidgetAction(this); - m_timeMenu = new QMenu(this); - widgetAction->setDefaultWidget(m_myCalendar); - m_timeMenu->addAction(widgetAction); - m_timeIcon->setObjectName("iconButton"); - m_timeIcon->setText(""); - m_timeIcon->setMaximumSize(21, 22); - m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); - QHBoxLayout * pTimeLayout = new QHBoxLayout(); - pTimeLayout->setContentsMargins(1, 1, 1, 1); - pTimeLayout->addStretch(); - pTimeLayout->addWidget(m_timeIcon); - ui->lineEdit->setLayout(pTimeLayout); - connect(m_timeIcon,&QPushButton::clicked,this,&CAlarmForm::myCalendarShow); - connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CAlarmForm::myCalendarHide); - connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CAlarmForm::cancleTimeFilter); - ui->lineEdit->setText(tr("请选择时间")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit->setObjectName("iconLineEdit"); - - m_pdfPrinter = new CPdfPrinter(); - m_thread = new QThread(); - m_pdfPrinter->moveToThread(m_thread); - connect(m_thread,&QThread::started,m_pdfPrinter,&CPdfPrinter::initialize); - connect(m_thread,&QThread::finished,m_pdfPrinter,&CPdfPrinter::deleteLater); - connect(this,&CAlarmForm::printExcel,m_pdfPrinter,&CPdfPrinter::printerByModel); - connect(this,&CAlarmForm::printExcelAlm,m_pdfPrinter,&CPdfPrinter::printerAlmByModel); - connect(m_pdfPrinter,&CPdfPrinter::printResult,this,&CAlarmForm::printMess); - ui->aiAlarmTreeView->setUpdatesEnabled(false); - ui->alarmView->setUpdatesEnabled(false); - m_thread->start(); -} - -CAlarmForm::~CAlarmForm() -{ - if(m_communicator != Q_NULLPTR) - { - delete m_communicator; - } - m_communicator =Q_NULLPTR; - - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - if(m_delegate) - { - delete m_delegate; - } - m_delegate = Q_NULLPTR; - - if(m_aiDelegate) - { - delete m_aiDelegate; - } - m_aiDelegate = Q_NULLPTR; - - if(m_pdfPrinter) - { - delete m_pdfPrinter; - } - m_pdfPrinter = Q_NULLPTR; - - if(m_thread) - { - m_thread->quit(); - m_thread->wait(); - } - - delete ui; - LOGDEBUG("CAlarmForm::~CAlarmForm()"); -} - -void CAlarmForm::initialize() -{ - if (!kbd_public::createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - } - if(m_pReadDb == NULL) - { - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - if(!m_pReadDb->open()) - { - LOGERROR("数据库打开失败,%s",m_pReadDb->getLastErrorString().toStdString().c_str()); - } - } - m_pDeviceModel = new CAlarmDeviceTreeModel(this); - ui->deviceView->setModel(m_pDeviceModel); - connect(ui->set,&QPushButton::clicked,this,&CAlarmForm::slot_showColorSet); - connect(ui->checkBox,SIGNAL(stateChanged(int)),this,SLOT(slot_changePage(int))); - connect(ui->filter, SIGNAL(clicked()), this, SLOT(updateFilter())); - connect(ui->remove, SIGNAL(clicked()), this, SLOT(slot_removeAlarm())); - connect(ui->confirm, SIGNAL(clicked()), this, SLOT(slot_confirmAlarm())); - - //connect(ui->inhibit, SIGNAL(clicked()), this, SLOT(slot_showInhibitAlarm())); - connect(ui->inhibit, SIGNAL(clicked()), this, SLOT(slot_showShiledAlarm())); - - connect(ui->print, SIGNAL(clicked()), this, SLOT(print())); - connect(ui->closeBtn, &QPushButton::clicked, this, &CAlarmForm::closeBtnClicked); - connect(ui->inhiAlarm, &QPushButton::clicked, this, &CAlarmForm::slotInhibitAlarm); - setHiddenInhiAlarmButton(true); - updateAlarmOperatePerm(); - - //< lingdaoyaoqiu - { - QSettings columFlags("KBD_HMI", "alarm config"); - if(!columFlags.contains(QString("alarm/colum_0"))) - { - columFlags.setValue(QString("alarm/colum_0"), false); //< 时间 - columFlags.setValue(QString("alarm/colum_1"), false); //< 优先级 - columFlags.setValue(QString("alarm/colum_2"), false); //< 位置 - columFlags.setValue(QString("alarm/colum_3"), true); //< 责任区 - columFlags.setValue(QString("alarm/colum_4"), true); //< 告警类型 - columFlags.setValue(QString("alarm/colum_5"), false); //< 告警状态 - columFlags.setValue(QString("alarm/colum_6"), false); //< 确认状态 - columFlags.setValue(QString("alarm/colum_7"), false); //< - } - } - ui->comboBox->setModel(m_pListWidget1->model()); - ui->comboBox->setView(m_pListWidget1); - ui->comboBox->setLineEdit(m_pLineEdit1); - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - m_pLineEdit1->setReadOnly(true); - connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 - ui->comboBox_2->setModel(m_pListWidget2->model()); - ui->comboBox_2->setView(m_pListWidget2); - ui->comboBox_2->setLineEdit(m_pLineEdit2); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - m_pLineEdit2->setReadOnly(true); - connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); - ui->comboBox_3->setModel(m_pListWidget3->model()); - ui->comboBox_3->setView(m_pListWidget3); - ui->comboBox_3->setLineEdit(m_pLineEdit3); - m_strText3 = tr("请选择告警状态"); - m_pLineEdit3->setText(tr("请选择告警状态")); - m_pLineEdit3->setReadOnly(true); - connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); -} - -void CAlarmForm::init() -{ - reloadDevTree(); - initFilter(); -} - -void CAlarmForm::updateAlarmOperatePerm() -{ - m_listRegionOptId.clear(); - m_listLocationOptId.clear(); - m_listRegionDelId.clear(); - m_listLocationDelId.clear(); - kbd_public::SNodeInfo stNodeInfo; - if (!m_ptrSysInfo) - { - if(!createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return; - } - } - m_ptrSysInfo->getLocalNodeInfo(stNodeInfo); - m_nodeName = stNodeInfo.strName; - m_nDomainId = stNodeInfo.nDomainId; - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(PERM_NORMAL != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - m_userId = -1; - LOGERROR("用户ID获取失败!"); - return; - } - std::vector vecRegionOptId; - std::vector vecLocationOptId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionOptId, vecLocationOptId)) - { - std::vector ::iterator region = vecRegionOptId.begin(); - while (region != vecRegionOptId.end()) - { - m_listRegionOptId.append(*region++); - } - - std::vector ::iterator location = vecLocationOptId.begin(); - while (location != vecLocationOptId.end()) - { - m_listLocationOptId.append(*location++); - } - } - std::vector vecRegionDelId; - std::vector vecLocationDelId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, vecRegionDelId, vecLocationDelId)) - { - std::vector ::iterator region = vecRegionDelId.begin(); - while (region != vecRegionDelId.end()) - { - m_listRegionDelId.append(*region++); - } - - std::vector ::iterator location = vecLocationDelId.begin(); - while (location != vecLocationDelId.end()) - { - m_listLocationDelId.append(*location++); - } - } - - std::string str = "FUNC_NOM_IA_EDIT"; - if(PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF,&str)) - { - m_aiOptPerm = false; - LOGINFO("无智能告警编辑权限"); - }else - { - m_aiOptPerm = true; - } - } -} - -void CAlarmForm::setAlarmOperateEnable(const bool &bEnable) -{ - ui->confirm->setEnabled(bEnable); - ui->remove->setEnabled(bEnable); - m_isNormal = bEnable; -} - -void CAlarmForm::setColumnWidth(const int &column, const int &width) -{ - if(ui->alarmView != Q_NULLPTR) - { - ui->alarmView->setColumnWidth(column, width); - } - if(ui->aiAlarmTreeView != Q_NULLPTR) - { - ui->aiAlarmTreeView->setColumnWidth(column, width); - } -} - -void CAlarmForm::setColumnVisible(const int &column, const bool &visible) -{ - if(ui->alarmView != Q_NULLPTR) - { - ui->alarmView->setColumnHidden(column, !visible); - } - if(ui->aiAlarmTreeView != Q_NULLPTR) - { - ui->aiAlarmTreeView->setColumnHidden(column, !visible); - } -} - -void CAlarmForm::setEnableAccidentReview(bool isNeed) -{ - m_isNeedAccidentReview = isNeed; -} - -void CAlarmForm::setEnableTrend(bool isNeed) -{ - if(m_delegate) - { - m_delegate->setEnableTrend(isNeed); - } - if(m_aiDelegate) - { - m_aiDelegate->setEnableTrend(isNeed); - } -} - -void CAlarmForm::setEnableVideo(bool isNeed) -{ - if(m_delegate) - { - m_delegate->setEnableVideo(isNeed); - } - if(m_aiDelegate) - { - m_aiDelegate->setEnableVideo(isNeed); - } -} - -void CAlarmForm::setEnableWave(bool isNeed) -{ - if(m_delegate) - { - m_delegate->setEnableWave(isNeed); - } - if(m_aiDelegate) - { - m_aiDelegate->setEnableWave(isNeed); - } -} - -void CAlarmForm::setEnableLevel(bool isNeed) -{ - if(m_delegate) - { - m_delegate->setEnableLevel(isNeed); - } - if(m_aiDelegate) - { - m_aiDelegate->setEnableLevel(isNeed); - } -} - -void CAlarmForm::setHiddenLocation(bool hide) -{ - ui->label_4->setHidden(hide); - ui->comboBox_2->setHidden(hide); -} - -void CAlarmForm::setHiddenTime(bool hide) -{ - ui->label_6->setHidden(hide); - ui->lineEdit->setHidden(hide); -} - -void CAlarmForm::setHiddenStatus(bool hide) -{ - ui->label_5->setHidden(hide); - ui->comboBox_3->setHidden(hide); -} - -void CAlarmForm::setHiddenPriority(bool hide) -{ - ui->label_3->setHidden(hide); - ui->comboBox->setHidden(hide); -} - -void CAlarmForm::setHiddenCheckBox(bool hide) -{ - ui->checkBox->setHidden(hide); -} - -void CAlarmForm::setHiddenSetConfig(bool hide) -{ - ui->set->setHidden(hide); -} - -void CAlarmForm::setHiddenCloseButton(bool hide) -{ - ui->closeBtn->setHidden(hide); -} - -void CAlarmForm::setHiddenInhiAlarmButton(bool hide) -{ - ui->inhiAlarm->setHidden(hide); -} - -void CAlarmForm::setShowAiAlarmView(bool show) -{ - if(m_treeModel) - { - ui->checkBox->setHidden(false); - ui->checkBox->setChecked(show); - }else - { - ui->checkBox->setHidden(true); - } -} - -void CAlarmForm::setRowHeight(int height) -{ - if(ui->alarmView != Q_NULLPTR) - { - ui->alarmView->setDefaultRowHeight(height); - } -} - -void CAlarmForm::setAccidentReviewPath(const QString &path) -{ - m_strAccidenPath = path; -} - -void CAlarmForm::initFilter() -{ - m_pListWidget1->clear(); - m_pListWidget2->clear(); - m_pListWidget3->clear(); - QMap priority = CAlarmBaseData::instance()->getPermPriorityMap(); - QMap alarmStatus = CAlarmBaseData::instance()->getAlarmShowStatusMap(); - for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); - pItem->setData(Qt::UserRole, it1.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it1.value()); - m_pListWidget1->addItem(pItem); - m_pListWidget1->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); - } - - QList locationList = CAlarmBaseData::instance()->getPermLocationOrder(); - foreach (const int locId, locationList) { - QString locDesc = CAlarmBaseData::instance()->getPermLocationDesc(locId); - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); - pItem->setData(Qt::UserRole, locId); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(locDesc); - m_pListWidget2->addItem(pItem); - m_pListWidget2->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); - } - - for(QMap::iterator it3 = alarmStatus.begin();it3 != alarmStatus.end();++it3) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); - pItem->setData(Qt::UserRole, it3.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it3.value()); - m_pListWidget3->addItem(pItem); - m_pListWidget3->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); - } - m_strText1 = tr("请选择优先级"); - m_strText2 = tr("请选择位置"); - m_strText3 = tr("请选择告警状态"); - m_pLineEdit1->setText(m_strText1); - m_pLineEdit2->setText(m_strText2); - m_pLineEdit3->setText(m_strText3); -} - -void CAlarmForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) -{ - if(isLevelFilter == true && listLevel.size() > 0) - { - QString strText(""); - for (int i = 0; i < m_pListWidget1->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listLevel.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText1 = strText; - m_pLineEdit1->setText(strText); - }else - { - for (int i = 0; i < m_pListWidget1->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - } -} - -void CAlarmForm::setLocationComboBox(bool &isLocationFilter,QList &listLocation) -{ - if(isLocationFilter == true && listLocation.size() > 0) - { - QString strText(""); - for (int i = 0; i < m_pListWidget2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listLocation.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText2 = strText; - m_pLineEdit2->setText(strText); - }else - { - for (int i = 0; i < m_pListWidget2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - } -} - -void CAlarmForm::setAlarmStatusComboBox(bool &isAlarmTypeFilter, QList &listAlarmStatus) -{ - if(isAlarmTypeFilter == true && listAlarmStatus.size() > 0) - { - QString strText(""); - for (int i = 0; i < m_pListWidget3->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listAlarmStatus.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText3 = strText; - m_pLineEdit3->setText(strText); - }else - { - for (int i = 0; i < m_pListWidget3->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText3 = tr("请选择告警状态"); - m_pLineEdit3->setText(tr("请选择告警状态")); - } -} - -void CAlarmForm::setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) -{ - if(isTimeFilter == true) - { - ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); - }else - { - ui->lineEdit->setText(tr("请选择时间")); - } -} - -void CAlarmForm::setAlarmModel(CAlarmItemModel *model,CAiAlarmTreeModel *treeModel) -{ - ui->checkBox->setChecked(true); - slot_changePage(0); - ui->alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); - ui->aiAlarmTreeView->header()->setSortIndicator(0, Qt::AscendingOrder); - m_pModel = model; - m_delegate = new CAlarmDelegate(m_pModel, ui->alarmView); - connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); - connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); - connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); - ui->alarmView->initialize(); - ui->aiAlarmTreeView->initialize(); - ui->alarmView->setItemDelegate(m_delegate); - ui->alarmView->setModel(m_pModel); - m_treeModel = treeModel; - m_aiDelegate = new CAiAlarmDelegate(m_treeModel,ui->aiAlarmTreeView); - ui->aiAlarmTreeView->setItemDelegate(m_aiDelegate); - ui->aiAlarmTreeView->setModel(m_treeModel); - connect(m_aiDelegate,&CAiAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); - connect(m_aiDelegate,&CAiAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); - connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_aiDelegate,&CAiAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); - //< 性能损耗 - //connect(ui->alarmView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(slot_selectionChanged()), Qt::QueuedConnection); - - connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); - connect(ui->aiAlarmTreeView->header(),&QHeaderView::sortIndicatorChanged, m_treeModel,&CAiAlarmTreeModel::sortColumn); - connect(ui->aiAlarmTreeView,&CAiAlarmTreeView::doubleClicked, this,&CAlarmForm::aiAlmDoubleClicked); - ui->confirm->setEnabled(true); - ui->remove->setEnabled(true); - //原始告警窗 - - ui->alarmView->setColumnWidth(0, 230); - ui->alarmView->setColumnWidth(1, 120); - ui->alarmView->setColumnWidth(2, 150); - ui->alarmView->setColumnWidth(5, 150); - ui->alarmView->setColumnWidth(6, 120); - - QSettings columFlags("KBD_HMI", "alarm config"); - for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount() - 1; nColumnIndex++) - { - bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); - ui->alarmView->setColumnHidden(nColumnIndex, visible); - } - ui->alarmView->setColumnHidden(m_pModel->columnCount() - 1, false); - //智能告警窗 - ui->aiAlarmTreeView->setColumnWidth(0, 230); - ui->aiAlarmTreeView->setColumnWidth(1, 120); - ui->aiAlarmTreeView->setColumnWidth(2, 150); - ui->aiAlarmTreeView->setColumnWidth(5, 150); - ui->aiAlarmTreeView->setColumnWidth(6, 120); - - for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount(); nColumnIndex++) - { - bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); - ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, visible); - } - - loadDeviceGroupFilterWidget(); - if(m_pDeviceModel) - { - connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); - connect(m_pDeviceModel, &CAlarmDeviceTreeModel::inhibitDevGroupAlm, this, &CAlarmForm::slotInhibitDevGroupAlm); - connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigDevTreeUpdate,m_pDeviceModel,&CAlarmDeviceTreeModel::slotDevTreeUpdate); - } - initFilter(); -} - -void CAlarmForm::setAlarmModel(CAlarmItemModel *model) -{ - ui->checkBox->setChecked(false); - ui->checkBox->setHidden(true); - slot_changePage(0); - ui->alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); - m_pModel = model; - m_delegate = new CAlarmDelegate(m_pModel, ui->alarmView); - connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); - connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); - connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); - ui->alarmView->initialize(); - ui->alarmView->setItemDelegate(m_delegate); - ui->alarmView->setModel(m_pModel); - - - connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); - ui->confirm->setEnabled(true); - ui->remove->setEnabled(true); - //原始告警窗 - - ui->alarmView->setColumnWidth(0, 230); - ui->alarmView->setColumnWidth(1, 120); - ui->alarmView->setColumnWidth(2, 150); - ui->alarmView->setColumnWidth(5, 150); - ui->alarmView->setColumnWidth(6, 120); - - - QSettings columFlags("KBD_HMI", "alarm config"); - for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount() - 1; nColumnIndex++) - { - bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); - ui->alarmView->setColumnHidden(nColumnIndex, visible); - } - ui->alarmView->setColumnHidden(m_pModel->columnCount() - 1, false); - - loadDeviceGroupFilterWidget(); - if(m_pDeviceModel) - { - connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); - connect(m_pDeviceModel, &CAlarmDeviceTreeModel::inhibitDevGroupAlm, this, &CAlarmForm::slotInhibitDevGroupAlm); - } - initFilter(); -} - -void CAlarmForm::updateView() -{ - updateRowTips(); - updateDeviceGroupHiddenState(); -} - -void CAlarmForm::updateFilter() -{ - bool isLevelFilter; - QList levelFilter; - bool isLocationFilter; - QList locationFilter; - bool isRegionFilter; - QList regionFilter; - bool isAlarmStatusFilter; //告警状态过滤 - QList typeFilter; - bool deviceTypeFilter; - QString subSystem; - QString deviceType; - bool keywordFilter; - QString keyword; - bool isTimeFilterEnable; - QDateTime startTime; - QDateTime endTime; - bool isStateFilterEnable; - bool isConfirm; - bool isReturnFilterEnable; - bool isReturn; - - CAlarmFilterDialog filterDlg; - m_pModel->getFilter(isLevelFilter, levelFilter, - isLocationFilter, locationFilter, - isRegionFilter, regionFilter, - isAlarmStatusFilter, typeFilter, - deviceTypeFilter, subSystem, deviceType, - keywordFilter, keyword, - isTimeFilterEnable, startTime, endTime, - isStateFilterEnable, isConfirm, - isReturnFilterEnable,isReturn); - filterDlg.initialize(); - filterDlg.setLevelFilterEnable(isLevelFilter); - filterDlg.setLevelFilter(levelFilter); - filterDlg.setLocationFilterEnable(isLocationFilter); - filterDlg.setLocationFilter(locationFilter); - filterDlg.setRegionFilterEnable(isRegionFilter); - filterDlg.setRegionFilter(regionFilter); - filterDlg.setAlarmStatusFilterEnable(isAlarmStatusFilter); - filterDlg.setAlarmStatusFilter(typeFilter); - filterDlg.setDeviceFilterEnable(deviceTypeFilter); - filterDlg.setSubSystem(subSystem); - filterDlg.setDeviceType(deviceType); - filterDlg.setkeyWordFilterEnable(keywordFilter); - filterDlg.setkeyWordFilteContent(keyword); - filterDlg.setTimeFilterEnable(isTimeFilterEnable); - filterDlg.setStartTimeFilter(startTime); - filterDlg.setEndTimeFilter(endTime); - filterDlg.setStateFilterEnable(isStateFilterEnable); - filterDlg.setStateFilter(isConfirm); - filterDlg.setReturnFilterEnable(isReturnFilterEnable); - filterDlg.setReturnFilter(isReturn); - connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool, bool, bool)), - this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool, bool, bool))); - filterDlg.exec(); -} - -void CAlarmForm::deviceGroupFilterChanged(const QString &device, const bool &checked) -{ - if(checked) - { - m_pModel->removeDeviceGroupFilter(device); - if(m_treeModel) - { - m_treeModel->removeDeviceGroupFilter(device); - } - - } - else - { - m_pModel->addDeviceGroupFilter(device); - if(m_treeModel) - { - m_treeModel->addDeviceGroupFilter(device); - } - } -} - -void CAlarmForm::slot_changePage(int i) -{ - Q_UNUSED(i) - if(!ui->checkBox->isChecked()) - { - ui->stackedWidget->setCurrentIndex(0); - ui->aiAlarmTreeView->setUpdatesEnabled(false); - ui->alarmView->setUpdatesEnabled(true); - ui->inhiAlarm->setEnabled(true); - }else - { - ui->stackedWidget->setCurrentIndex(1); - ui->alarmView->setUpdatesEnabled(false); - ui->aiAlarmTreeView->setUpdatesEnabled(true); - ui->inhiAlarm->setEnabled(false); - } -} - -void CAlarmForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmStatus, - bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm, bool isReturnFilter, bool isReturn) -{ - m_pModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,isReturn); - if(m_treeModel) - { - m_treeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,isReturn); - } - //设置下拉框的值 - setLevelComboBox(isLevelFilter,listLevel); - setLocationComboBox(isLocationFilter,listLocation); - setAlarmStatusComboBox(isAlarmTypeFilter,listAlarmStatus); - setAlarmTimeLineEdit(isTimeFilter, startTime, endTime); -} - -void CAlarmForm::slot_removeAlarm() -{ - updateAlarmOperatePerm(); - if(!ui->checkBox->isChecked()) - { - removeAlarm0(); - }else - { - removeAlarm1(); - } -} - -void CAlarmForm::slot_confirmAlarm() -{ - updateAlarmOperatePerm(); - if(!ui->checkBox->isChecked()) - { - confirmAlarm0(); - }else - { - confirmAlarm1(); - } -} - -void CAlarmForm::slot_showInhibitAlarm() -{ - CAlarmInhibitDialog dlg; - QList almList; - CAlarmMsgManage::instance()->getAllInhibitAlm(almList); - - dlg.setInhibitAlarmList(almList); - connect(&dlg, &CAlarmInhibitDialog::removeInhibitAlarmList, this, &CAlarmForm::removeInhibitAlarm); - dlg.exec(); - -} - -void CAlarmForm::slot_showShiledAlarm() -{ - CAlarmShiledDialog dlg; - dlg.exec(); -} - -void CAlarmForm::slot_showColorSet() -{ - CAlarmSetDlg dlg; - dlg.exec(); -} - -void CAlarmForm::removeInhibitAlarm(QList alarmList) -{ - foreach (AlarmMsgPtr alm, alarmList) - { - CAlarmMsgManage::instance()->removeInhibitTag(alm->key_id_tag); - } -} - -void CAlarmForm::searchDeviceName() -{ - QItemSelection selection; - QString content = m_pSearchTextEdit->text(); - ui->deviceView->selectionModel()->select(selection, QItemSelectionModel::Clear); - if(content.isEmpty()) - { - return; - } - const QHash< QString, QModelIndex > &indexNameList = m_pDeviceModel->indexNameList(); - QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); - while (iter != indexNameList.constEnd()) - { - if(ui->deviceView->isRowHidden(iter.value().row(), iter.value().parent())) - { - iter++; - continue; - } - if(iter.key().section(".", 1).contains(content, Qt::CaseInsensitive)) - { - selection.append(QItemSelectionRange(iter.value(), iter.value())); - selection.append(QItemSelectionRange(iter.value().parent(), iter.value().parent())); - } - iter++; - } - ui->deviceView->selectionModel()->select(selection, QItemSelectionModel::Select); -} - -void CAlarmForm::updateRowTips() -{ - if(!ui->checkBox->isChecked()) - { - if(m_pModel) - { - ui->alarmView->viewport()->update(); - ui->showRow->setText(QString::number(m_pModel->rowCount())); - int nNumber = m_pModel->filterCount(); - if(nNumber<0) nNumber = 0 ; - ui->filterRow->setText(QString::number(nNumber)); - } - } - else - { - if(m_treeModel) - { - ui->aiAlarmTreeView->viewport()->update(); - int showNum = m_treeModel->getShowNum(); - int showAiNum = m_treeModel->getShowAi(); - int filterAi = CAlarmMsgManage::instance()->getAiCount() -showAiNum; - int showTotal = CAlarmMsgManage::instance()->getAlmTotal(); - ui->showRow->setText(QString("%1/%2").arg(showNum).arg(showAiNum)); - int nNumber = showTotal - showNum; - if(nNumber<0) nNumber = 0 ; - if(filterAi<0) filterAi = 0; - ui->filterRow->setText(QString("%1/%2").arg(nNumber).arg(filterAi)); - } - } -} - -void CAlarmForm::print() -{ - //QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); - QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"*.xlsx");//获取保存路径*.xls - if(!ui->checkBox->isChecked()) - { - print0(fileName); - }else - { - print1(fileName); - } -} - -void CAlarmForm::stateChanged1(int state) -{ - Q_UNUSED(state) - QString strText(""); - m_priorityList.clear(); - int nCount = m_pListWidget1->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_priorityList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText1 = strText; - m_pLineEdit1->setText(strText); - } - else - { - m_pLineEdit1->clear(); - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - } - bool isCheck = false; - if(m_priorityList.size() > 0) - { - isCheck = true; - } - if(m_pModel) - { - m_pModel->setPriorityFilter(isCheck,m_priorityList); - } - if(m_treeModel) - { - m_treeModel->setPriorityFilter(isCheck,m_priorityList); - } -} - -void CAlarmForm::stateChanged2(int state) -{ - Q_UNUSED(state) - QString strText(""); - m_locationList.clear(); - int nCount = m_pListWidget2->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_locationList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText2 = strText; - m_pLineEdit2->setText(strText); - } - else - { - m_pLineEdit2->clear(); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - } - bool isCheck = false; - if(m_locationList.size() > 0) - { - isCheck = true; - } - if(m_pModel) - { - m_pModel->setLocationFilter(isCheck,m_locationList); - } - if(m_treeModel) - { - m_treeModel->setLocationFilter(isCheck,m_locationList); - } -} - -void CAlarmForm::stateChanged3(int state) -{ - Q_UNUSED(state) - QString strText(""); - m_alarmStatusList.clear(); - bool other = false; - int nCount = m_pListWidget3->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - if(nData == OTHERSTATUS) - { - other = true; - } - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_alarmStatusList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText3 = strText; - m_pLineEdit3->setText(strText); - } - else - { - m_pLineEdit3->clear(); - m_strText3 = tr("请选择告警状态"); - m_pLineEdit3->setText(tr("请选择告警状态")); - } - bool isCheck = false; - if(m_alarmStatusList.size() > 0) - { - isCheck = true; - } - if(m_pModel) - { - m_pModel->setAlarmTypeFilter(isCheck,m_alarmStatusList,other); - } - if(m_treeModel) - { - m_treeModel->setAlarmTypeFilter(isCheck,m_alarmStatusList,other); - } -} - -void CAlarmForm::textChanged1(const QString &text) -{ - Q_UNUSED(text) - m_pLineEdit1->setText(m_strText1); -} - -void CAlarmForm::textChanged2(const QString &text) -{ - Q_UNUSED(text) - m_pLineEdit2->setText(m_strText2); -} - -void CAlarmForm::textChanged3(const QString &text) -{ - Q_UNUSED(text) - m_pLineEdit3->setText(m_strText3); -} - -void CAlarmForm::myCalendarHide(QDate startTime,QDate endTime) -{ - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); - //开始过滤 - bool isCheck = true; - if(m_pModel) - { - m_pModel->setAlarmTimeFilter(isCheck,startTime,endTime); - } - if(m_treeModel) - { - m_treeModel->setAlarmTimeFilter(isCheck,startTime,endTime); - } - m_timeMenu->hide(); -} - -void CAlarmForm::myCalendarShow() -{ - QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); - m_timeMenu->move(point); - m_timeMenu->show(); -} - -void CAlarmForm::cancleTimeFilter() -{ - ui->lineEdit->setText(tr("请选择时间")); - //取消过滤 - bool isCheck = false; - if(m_pModel) - { - m_pModel->setAlarmTimeFilter(isCheck); - } - if(m_treeModel) - { - m_treeModel->setAlarmTimeFilter(isCheck); - } - - m_timeMenu->hide(); -} - -void CAlarmForm::aiAlmDoubleClicked(const QModelIndex &index) -{ - if(m_treeModel == NULL) - { - return ; - } - if(!index.isValid()) - { - return ; - } - CAiAlarmTreeItem *item =static_cast(index.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr aiPtr; - if(item->getAiPtr(aiPtr)) - { - CDisposalPlanDialog dialog(aiPtr); - dialog.exec(); - }else - { - LOGERROR("aiAlmDoubleClicked():标识符错误!"); - } - } -} - -void CAlarmForm::printMess(QString fileName) -{ - Q_UNUSED(fileName); - QMessageBox::information( 0, tr("提示"), tr("导出成功")); -} - -void CAlarmForm::slotInhibitDevGroupAlm(const QString &strDevg, int nDomainId, int nLocationId, int nSubsystemId, int nRegionId) -{ - if(!permCheck(nLocationId,nRegionId)) - { - return; - } - QList pointList; - if(!CAlarmBaseData::instance()->queryAllPointDevGroup(nDomainId, nSubsystemId, strDevg, pointList)) - { - QMessageBox::information(this, tr("提示"), tr("禁止告警失败,请检查实时库连接!")); - return; - } - for(int n(0); ndomain_id = nDomainId; - almMsgPtr->location_id = nLocationId; - almMsgPtr->sub_system = nSubsystemId; - almMsgPtr->key_id_tag = pointList[n]; - inhibitAlm(almMsgPtr); - } -} - -void CAlarmForm::slotInhibitAlarm() -{ - if(!m_pModel) - { - return; - } - QModelIndex index = ui->alarmView->currentIndex(); - if(!index.isValid()) - { - QMessageBox::information(this, tr("提示"), tr("请选择一条告警!")); - return; - } - AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); - if(!permCheck(alm->location_id,alm->region_id)) - { - return; - } - inhibitAlm(alm); -} - -void CAlarmForm::contextMenuEvent(QContextMenuEvent *event) -{ - if(!m_isNormal) - { - return ; - } - updateAlarmOperatePerm(); - if(ui->stackedWidget->currentIndex() == 0) - { - contextMenuStack0Event(event); - }else if(ui->stackedWidget->currentIndex() == 1) - { - contextMenuStack1Event(event); - } -} - -void CAlarmForm::contextMenuStack0Event(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - if(!m_pModel) - { - return; - } - if(event->pos().x() < ui->alarmView->pos().x()) - { - return; - } - QRect headerRect = ui->alarmView->horizontalHeader()->rect(); - headerRect.moveTopLeft(ui->alarmView->mapTo(this, QPoint())); - if(headerRect.contains(event->pos())) - { - QMenu columnMenu(this); - - for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount()-1; nColumnIndex++) - { - QAction * action = columnMenu.addAction(m_pModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); - action->setCheckable(true); - action->setChecked(!ui->alarmView->isColumnHidden(nColumnIndex)); - connect(action, &QAction::triggered, [=](){ - ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); - ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags("KBD_HMI", "alarm config"); - columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); - }); - } - columnMenu.exec(QCursor::pos()); - } - else - { - QModelIndex index_ = ui->alarmView->indexAt(ui->alarmView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index_.isValid()) - { - return; - } - QModelIndexList indexLists = ui->alarmView->selectionModel()->selectedIndexes(); - //判断右键位置是否在选中区 - QModelIndex index = ui->alarmView->currentIndex(); - if(!indexLists.contains(index)) - { - ui->alarmView->clearSelection(); - ui->alarmView->setCurrentIndex(index); - } - AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); - QMenu menu(this); - QAction * selectAction = menu.addAction(tr("全选")); - connect(selectAction, &QAction::triggered, [=](){ui->alarmView->selectAll();}); - QAction * cancleAction = menu.addAction(tr("全不选")); - connect(cancleAction,&QAction::triggered,[=](){ui->alarmView->clearSelection();}); - menu.addSeparator(); - - QAction * confirmAction = menu.addAction(tr("确认")); - connect(confirmAction,&QAction::triggered,[=](){ - rightConfirm0(); - }); - QAction * removeAction = menu.addAction(tr("删除")); - connect(removeAction,&QAction::triggered,[=](){ - rightRemove0(); - }); - - menu.addSeparator(); - - // QAction * trendAction = menu.addAction(tr("趋势")); - - // connect(trendAction,&QAction::triggered,[=](){ - // rightTrend0(); - // }); - if(alm->m_needVideoAlm) - { - QAction * videoAction = menu.addAction(tr("视频")); - connect(videoAction,&QAction::triggered,[=](){ - rightVideo0(); - }); - } - // QAction * faultRecordAction = menu.addAction(tr("故障录播")); - // connect(faultRecordAction,&QAction::triggered,[=](){ - // rightFaultRecord0(); - // }); - - - if(m_isNeedAccidentReview) - { - QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); - connect(accidentReviewAction,&QAction::triggered,[=](){ - rightAccidentReview0(); - }); - } - - QAction * InhibitAction = menu.addAction(tr("禁止告警")); - connect(InhibitAction, &QAction::triggered, [=](){ -// bool isContains = false; -// QList almList; -// CAlarmMsgManage::instance()->getAllInhibitAlm(almList); - if(!permCheck(alm->location_id,alm->region_id)) - { - return; - } - inhibitAlm(alm); -// foreach (AlarmMsgPtr alarm, almList) -// { -// if(alarm->key_id_tag == alm->key_id_tag) -// { -// isContains = true; -// break; -// } -// } -// if(isContains) -// { -// QMessageBox::warning(this, tr("警告"), tr("当前测点告警已禁止,无需重复禁止!"), QMessageBox::Ok); -// } -// else -// { -// CAlarmMsgManage::instance()->addInhibitAlm(alm); -// } - }); - - menu.exec(QCursor::pos()); - } -} - -void CAlarmForm::contextMenuStack1Event(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - if(!m_treeModel) - { - return; - } - if(event->pos().x() < ui->aiAlarmTreeView->pos().x()) - { - return; - } - QRect headerRect = ui->aiAlarmTreeView->header()->rect(); - headerRect.moveTopLeft(ui->aiAlarmTreeView->mapTo(this, QPoint())); - if(headerRect.contains(event->pos())) - { - QMenu columnMenu(this); - - for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount()-1; nColumnIndex++) - { - QAction * action = columnMenu.addAction(m_treeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); - action->setCheckable(true); - action->setChecked(!ui->aiAlarmTreeView->isColumnHidden(nColumnIndex)); - connect(action, &QAction::triggered, [=](){ - ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); - ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags("KBD_HMI", "alarm config"); - columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); - }); - } - columnMenu.exec(QCursor::pos()); - }else - { - QModelIndex index_ = ui->aiAlarmTreeView->indexAt(ui->aiAlarmTreeView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index_.isValid()) - { - return; - } - QMenu menu(this); - QModelIndex index = ui->aiAlarmTreeView->currentIndex(); - if(!index.isValid()) - { - return ; - } - QModelIndexList indexLists = ui->aiAlarmTreeView->selectionModel()->selectedIndexes(); - - //判断右键位置是否在选中区 - if(!indexLists.contains(index)) - { - ui->aiAlarmTreeView->clearSelection(); - ui->aiAlarmTreeView->setCurrentIndex(index); - } - QAction * selectAction = menu.addAction(tr("全选")); - connect(selectAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->selectAll();}); - QAction * cancleAction = menu.addAction(tr("全不选")); - connect(cancleAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->clearSelection();}); - menu.addSeparator(); - QAction * confirmAction = menu.addAction(tr("确认")); - connect(confirmAction,&QAction::triggered,[=](){ - rightConfirm1(); - }); - QAction * removeAction = menu.addAction(tr("删除")); - connect(removeAction,&QAction::triggered,[=](){ - rightRemove1(); - }); - menu.addSeparator(); - QAction * mergeAction = menu.addAction(tr("合并")); - connect(mergeAction,&QAction::triggered,[=](){ - rightMerge1(); - }); - QAction * seprAction = menu.addAction(tr("分离")); - connect(seprAction,&QAction::triggered,[=](){ - rightSepr1(); - }); - menu.addSeparator(); - //讨论删除右键趋势2020-6-17 jxd sjq zlx - - // QAction * trendAction = menu.addAction(tr("趋势")); - // connect(trendAction,&QAction::triggered,[=](){ - // rightTrend1(); - // }); - - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - if(!item->isAi()) - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - if(ptr->m_needVideoAlm) - { - QAction * videoAction = menu.addAction(tr("视频")); - connect(videoAction,&QAction::triggered,[=](){ - rightVideo1(); - }); - } - } - } - // QAction * faultRecordAction = menu.addAction(tr("故障录播")); - // connect(faultRecordAction,&QAction::triggered,[=](){ - // rightFaultRecord1(); - // }); - if(m_isNeedAccidentReview) - { - QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); - connect(accidentReviewAction,&QAction::triggered,[=](){ - rightAccidentReview1(); - }); - } - menu.exec(QCursor::pos()); - } -} - -void CAlarmForm::loadDeviceGroupFilterWidget() -{ - if(!m_pModel) - { - return; - } - QMap< int, QVector< SDevGroupInfo > > locationInfos; - - QList locationList = CAlarmBaseData::instance()->getPermLocationOrder(); - - if(m_pReadDb->isOpen()) - { - for(int nIndex(0); nIndex dev; - - QSqlQuery query; - QString sqlSequenceQuery = QString("select tag_name, description,sub_system,region_id from dev_group where location_id = %1;").arg(locationList[nIndex]); - if(m_pReadDb->execute(sqlSequenceQuery, query)) - { - while(query.next()) - { - SDevGroupInfo _stDevGroupInfo; - _stDevGroupInfo.tag_name = query.value(0).toString(); - _stDevGroupInfo.description = query.value(1).toString(); - _stDevGroupInfo.domain = CAlarmBaseData::instance()->queryDomainIdByLocId(locationList[nIndex]); - _stDevGroupInfo.location = locationList[nIndex]; - _stDevGroupInfo.sub_system = query.value(2).toInt(); - _stDevGroupInfo.region = query.value(3).toInt(); - dev.push_back(_stDevGroupInfo); - } - locationInfos.insert(locationList[nIndex], dev); - }else - { - LOGERROR("load device info error, dbInterface execute failed!"); - } - } - } - else - { - LOGERROR("load deviceGroup info error, database open failed!"); - } - m_pDeviceModel->removeData(); - m_pDeviceModel->setupModelData(locationInfos,locationList); - updateDeviceGroupHiddenState(); - ui->deviceView->expandAll(); -} - -void CAlarmForm::updateDeviceGroupHiddenState() -{ - QHash listDeviceStatisticalInfo = m_pDeviceModel->getDeviceStatisticalInfo(); - for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) - { - QModelIndex topLevelIndex = m_pDeviceModel->index(nTopLevelRow, 0); - for(int nChildRow(0); nChildRow < m_pDeviceModel->rowCount(topLevelIndex); nChildRow++) - { - CAlarmDeviceTreeItem *item = static_cast(m_pDeviceModel->index(nChildRow, 0, topLevelIndex).internalPointer()); - ui->deviceView->setRowHidden(nChildRow, topLevelIndex, !listDeviceStatisticalInfo.value(item->data(Qt::ItemDataRole(TagRole)).toString(), 0)); - } - } -} - -void CAlarmForm::print0(QString fileName) -{ - if(!fileName.isEmpty() && m_pModel) - { - if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) - fileName = fileName + ".xlsx"; - emit printExcelAlm(m_pModel,fileName); - } -} - -void CAlarmForm::print1(QString fileName) -{ - if(!fileName.isEmpty() && m_treeModel) - { - if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) - fileName = fileName + ".xlsx"; - emit printExcel(m_treeModel,fileName); - } -} - -void CAlarmForm::removeAlarm0() -{ - QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList listInfo = m_pModel->getListShowAlarmInfo(); - //声明告警删除package - QMap pkgMap; //Domain-DelPkg; - int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 - int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 - - QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); - for(;modelIndexIter != modelIndexList.end();modelIndexIter++) - { - AlarmMsgPtr info = listInfo.at(modelIndexIter->row()); - //< 权限过滤 - - if(!m_listLocationDelId.contains(info->location_id) || (!m_listRegionDelId.contains(info->region_id) && info->region_id != -1)) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox = NULL; - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox = NULL; - permSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox = NULL; - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - - //删除条件 - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) - { - if(1 != unConfirmSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含未确认告警!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox = NULL; - unConfirmSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox = NULL; - unConfirmSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox = NULL; - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - - //构建告警删除package - QMap::iterator it = pkgMap.find(info->domain_id); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); - pkg->set_domain_id(info->domain_id); - pkgMap[info->domain_id] = pkg; - } - pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); - } - //请求删除 - foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) - { - if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) - { - LOGERROR("请求删除原始告警失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - ui->alarmView->setFocus(); -} - -void CAlarmForm::removeAlarm1() -{ - if(!m_treeModel) - { - return ; - } - QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList aimsgList; //选中的智能告警 - QList msgList; //选中的原始告警 - //声明智能告警删除package - QMap aipkgMap; //Domain-DelPkg; ai - QMap pkgMap; //Domain-DelPkg; alarm - int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 - int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 - QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); - for(;modelIndexIter != modelIndexList.end();modelIndexIter++) - { - if(!modelIndexIter->isValid()) - { - continue; - } - CAiAlarmTreeItem *item = static_cast(modelIndexIter->internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - aimsgList.append(ptr); - } - }else - { - if(item->parent() == m_treeModel->getItem()) - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - msgList.append(ptr); - } - } - } - } - if(aimsgList.size() <= 0 && msgList.size() <= 0) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何智能告警和未聚类的原始告警!"), QMessageBox::Ok); - return; - } - //处理原始告警 - for(int alarm(0);alarmlocation_id) || (!m_listRegionDelId.contains(info->region_id) && info->region_id != -1)) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox = NULL; - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox = NULL; - permSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox = NULL; - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - //删除条件 - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) - { - if(1 != unConfirmSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含未确认告警!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox = NULL; - unConfirmSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox = NULL; - unConfirmSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox = NULL; - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - //构建告警删除package - QMap::iterator it = pkgMap.find(info->domain_id); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); - pkg->set_domain_id(info->domain_id); - pkgMap[info->domain_id] = pkg; - } - pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); - } - //处理智能告警 - for(int aialarm(0);aialarmsetObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox = NULL; - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox = NULL; - permSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox = NULL; - qDeleteAll(aipkgMap); - aipkgMap.clear(); - return; - } - } - else - { - continue; - } - } - if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aimsgList.at(aialarm)->uuid_base64)) - { - if(1 != unConfirmSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含未确认原始告警告警!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox = NULL; - unConfirmSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox = NULL; - unConfirmSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox = NULL; - qDeleteAll(aipkgMap); - aipkgMap.clear(); - return; - } - } - else - { - continue; - } - } - int domain_id = aimsgList.at(aialarm)->domain_id; - QString aiuuid = aimsgList.at(aialarm)->uuid_base64; - QMap::iterator it = aipkgMap.find(domain_id); - if(it == aipkgMap.end()) - { - kbd_idlfile::SIntelliAlmDel * pkg = new kbd_idlfile::SIntelliAlmDel(); - pkg->set_domain_id(domain_id); - aipkgMap[domain_id] = pkg; - } - aipkgMap.value(domain_id)->add_uuid_base64(aiuuid.toStdString()); - } - //请求删除 - foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) - { - if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) - { - LOGDEBUG("请求删除原始告警失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - //请求删除 - foreach (kbd_idlfile::SIntelliAlmDel * pkg, aipkgMap) - { - if(CAiAlarmDataCollect::instance()->requestDelAlm(*pkg) != true) - { - LOGDEBUG("请求删除智能告警失败!"); - } - } - qDeleteAll(aipkgMap); - aipkgMap.clear(); - ui->aiAlarmTreeView->setFocus(); -} - -void CAlarmForm::confirmAlarm0() -{ - LOGINFO("开始确认告警"); - QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList listInfo = m_pModel->getListShowAlarmInfo(); - if(listInfo.isEmpty()) - { - return; - } - - //构建告警确认package - QMap msgMap; //要确认的告警 - QMap pkgMap; //Domain-DelPkg; - - int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 - QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); - for(;modelIndexIter != modelIndexList.end();modelIndexIter++) - { - AlarmMsgPtr info = listInfo.at(modelIndexIter->row()); - if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || - info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL ) - { - continue; - } - msgMap[info->uuid_base64] = info; - } - QMap::iterator almIter = msgMap.begin(); - for(;almIter != msgMap.end();almIter++) - { - if(!m_listLocationOptId.contains(almIter.value()->location_id) || (!m_listRegionOptId.contains(almIter.value()->region_id) && almIter.value()->region_id != -1)) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox = NULL; - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox = NULL; - permSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox = NULL; - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - - QString key = QString("%1_%2_%3").arg(almIter.value()->domain_id).arg(almIter.value()->alm_type).arg(almIter.value()->app_id); - QMap::iterator it = pkgMap.find(key); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); - pkg->set_node_name(m_nodeName); - pkg->set_user_id(m_userId); - pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); - pkg->set_domain_id(almIter.value()->domain_id); - pkg->set_app_id(almIter.value()->app_id); - pkg->set_alm_type(almIter.value()->alm_type); - pkgMap[key] = pkg; - } - pkgMap.value(key)->add_key_id_tag(almIter.value()->key_id_tag.toStdString()); - pkgMap.value(key)->add_time_stamp(almIter.value()->time_stamp); - pkgMap.value(key)->add_uuid_base64(almIter.value()->uuid_base64.toStdString()); - } - - //请求确认 - foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) - { - if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) - { - LOGERROR("请求确认告警失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - ui->alarmView->setFocus(); - LOGINFO("结束确认告警"); -} - -void CAlarmForm::confirmAlarm1() -{ - if(!m_treeModel) - { - return ; - } - QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QMap msgMap; //要确认的告警 - msgMap.clear(); - //构建告警确认package - QMap pkgMap; //Domain-DelPkg; - int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 - QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); - for(;modelIndexIter != modelIndexList.end();modelIndexIter++) - { - if(!modelIndexIter->isValid()) - { - continue; - } - CAiAlarmTreeItem *item = static_cast(modelIndexIter->internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - QList listPtr = item->getChildAlarmPtr(); - for(int x(0);xlogic_state == E_ALS_ALARM_CFM || listPtr.at(x)->logic_state == E_ALS_RETURN_CFM || - listPtr.at(x)->logic_state == E_ALS_ALARM_CFM_DEL || listPtr.at(x)->logic_state == E_ALS_RETURN_CFM_DEL ) - { - continue; - } - msgMap[listPtr.at(x)->uuid_base64] = listPtr.at(x); - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM || - ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL ) - { - continue; - } - msgMap[ptr->uuid_base64] = ptr; - } - } - } - QMap::iterator almIter = msgMap.begin(); - for(;almIter != msgMap.end();almIter++) - { - if(!m_listLocationOptId.contains(almIter.value()->location_id) || (!m_listRegionOptId.contains(almIter.value()->region_id) && almIter.value()->region_id != -1)) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox = NULL; - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox = NULL; - permSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox = NULL; - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - QString key = QString("%1_%2_%3").arg(almIter.value()->domain_id).arg(almIter.value()->alm_type).arg(almIter.value()->app_id); - QMap::iterator it = pkgMap.find(key); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); - pkg->set_node_name(m_nodeName); - pkg->set_user_id(m_userId); - pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); - pkg->set_domain_id(almIter.value()->domain_id); - pkg->set_app_id(almIter.value()->app_id); - pkg->set_alm_type(almIter.value()->alm_type); - pkgMap[key] = pkg; - } - pkgMap.value(key)->add_key_id_tag(almIter.value()->key_id_tag.toStdString()); - pkgMap.value(key)->add_time_stamp(almIter.value()->time_stamp); - pkgMap.value(key)->add_uuid_base64(almIter.value()->uuid_base64.toStdString()); - } - foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) - { - if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) - { - LOGERROR("请求确认告警失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - ui->aiAlarmTreeView->setFocus(); -} - -void CAlarmForm::rightConfirm0() -{ - confirmAlarm0(); -} - -void CAlarmForm::rightConfirm1() -{ - confirmAlarm1(); -} - -void CAlarmForm::rightRemove0() -{ - removeAlarm0(); -} - -void CAlarmForm::rightRemove1() -{ - removeAlarm1(); -} - -void CAlarmForm::rightMerge1() -{ - if(!m_treeModel) - { - return ; - } - QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); - QList aimsgList; - QList msgList; - - foreach (QModelIndex modelIndex, indexList) - { - if(!modelIndex.isValid()) - { - continue; - } - CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - aimsgList.append(ptr); - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - msgList.append(ptr); - } - } - } - QMap pkgMap; - QList listPtr; - listPtr.clear(); - int permSkip = -1; - if(aimsgList.size() > 0) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("包含智能告警,无法合并!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("包含智能告警,无法合并!"), QMessageBox::Ok); - return ; - } - - for(int alarmIndex(0);alarmIndex < msgList.size();alarmIndex++) - { - if(msgList.at(alarmIndex) != NULL) - { - //判断此原始告警是否已经被聚类 - if(CAlarmMsgManage::instance()->isBelongAi(msgList.at(alarmIndex)->uuid_base64)) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("包含已经聚类的原始告警,无法合并!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("包含已经聚类的原始告警,无法合并!"), QMessageBox::Ok); - return ; - } - //判断权限 - if(!m_aiOptPerm) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户无此条原始告警合并权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - delete msgBox; - msgBox =NULL; - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - delete msgBox; - msgBox =NULL; - permSkip = 1; - continue; - } - else - { - delete msgBox; - msgBox =NULL; - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - }else - { - listPtr.append(msgList.at(alarmIndex)); - } - } - } - //过滤后等于0直接返回 - if(listPtr.size() <= 0) - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return ; - } - for(int x(0);xdomain_id; - if(!pkgMap.keys().contains(domain_id)) - { - kbd_idlfile::SIntelliAlmMerge *pkg =new kbd_idlfile::SIntelliAlmMerge(); - pkg->set_domain_id(domain_id); - pkgMap[domain_id] = pkg; - } - pkgMap.value(domain_id)->add_raw_alm_uuid(listPtr.at(x)->uuid_base64.toStdString()); - LOGINFO("UUID:%s",listPtr.at(x)->uuid_base64.toStdString().c_str()); - } - if(pkgMap.size() != 1) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("包含不同域的原始告警,无法合并!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("包含不同域的原始告警,无法合并!"), QMessageBox::Ok); - qDeleteAll(pkgMap); - pkgMap.clear(); - return ; - } - foreach (kbd_idlfile::SIntelliAlmMerge * pkg, pkgMap) - { - if(CAiAlarmDataCollect::instance()->requestMergeAlm(*pkg) != true) - { - LOGERROR("请求合并告警失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - ui->aiAlarmTreeView->setFocus(); - LOGINFO("合并结束!"); -} - -void CAlarmForm::rightSepr1() -{ - if(!m_treeModel) - { - return ; - } - QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); - QList aimsgList; - QList msgList; - - foreach (QModelIndex modelIndex, indexList) - { - if(!modelIndex.isValid()) - { - continue; - } - CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - aimsgList.append(ptr); - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - msgList.append(ptr); - } - } - } - if(aimsgList.size() != 0) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("包含智能告警,无法分离!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("包含智能告警,无法分离!"), QMessageBox::Ok); - return ; - } - if(msgList.size() <= 0) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("无原始告警,无法分离!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("无原始告警,无法分离!"), QMessageBox::Ok); - return ; - } - QString aiuuid = ""; - if(!CAlarmMsgManage::instance()->getAiuuid(msgList.at(0)->uuid_base64,aiuuid)) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("包含未聚类的原始告警,无法分离!"), QMessageBox::Ok); - return ; - } - //权限过滤 - if(!m_aiOptPerm) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("无此条智能告警的编辑权限!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("无此条智能告警的编辑权限!"), QMessageBox::Ok); - return ; - } - //遍历所有原始告警 - for(int index(1);indexgetAiuuid(msgList.at(index)->uuid_base64,uuid)) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("包含未聚类的原始告警,无法分离!"), QMessageBox::Ok); - return ; - } - if(uuid != aiuuid) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("包含不同智能告警下的原始告警,无法分离!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("包含不同智能告警下的原始告警,无法分离!"), QMessageBox::Ok); - return ; - } - } - //拼包 - int domain_id = msgList.at(0)->domain_id; - kbd_idlfile::SIntelliAlmSepr *pkg = new kbd_idlfile::SIntelliAlmSepr(); - pkg->set_domain_id(domain_id); - for(int index(0);indexadd_raw_alm_uuid(msgList.at(index)->uuid_base64.toStdString()); - } - //发送 - if(CAiAlarmDataCollect::instance()->requestSeprAlm(*pkg) != true) - { - LOGERROR("请求分离告警失败!"); - } - pkg = NULL; - delete pkg; -} - -void CAlarmForm::rightTrend0() -{ - quint64 time_stamp = 0; - QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList listInfo = m_pModel->getListShowAlarmInfo(); - QMap trendMap; - foreach (QModelIndex index, modelIndexList) - { - AlarmMsgPtr info = listInfo.at(index.row()); - if(info->m_tagname_type == E_TAGNAME_ANA || info->m_tagname_type == E_TAGNAME_ACC) - { - time_stamp = info->time_stamp; - trendMap[info->uuid_base64] = info->key_id_tag; - } - } - if(trendMap.size()<= 0) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("请选中含有趋势的告警(模拟量和累积量)!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("请选中含有趋势的告警(模拟量和累积量)!"), QMessageBox::Ok); - return ; - }else - { - //发出打开趋势的信号 - emit openTrend(time_stamp,trendMap.values()); - //test(trendMap.values()); - } -} - -void CAlarmForm::rightTrend1() -{ - if(!m_treeModel) - { - return ; - } - quint64 time_stamp = 0; - QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); - QMap trendMap; - foreach (QModelIndex modelIndex, indexList) - { - if(!modelIndex.isValid()) - { - continue; - } - CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - QList listPtr = item->getChildAlarmPtr(); - for(int index(0);indexm_tagname_type == E_TAGNAME_ANA || listPtr.at(index)->m_tagname_type == E_TAGNAME_ACC) - { - time_stamp = listPtr.at(index)->time_stamp; - trendMap[listPtr.at(index)->uuid_base64] = listPtr.at(index)->key_id_tag; - } - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - if(ptr->m_tagname_type == E_TAGNAME_ANA || ptr->m_tagname_type == E_TAGNAME_ACC) - { - time_stamp = ptr->time_stamp; - trendMap[ptr->uuid_base64] = ptr->key_id_tag; - } - } - } - } - if(trendMap.size()<= 0) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("请选中含有趋势的告警(模拟量和累积量)!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("请选中含有趋势的告警(模拟量和累积量)!"), QMessageBox::Ok); - return ; - }else - { - //发出打开趋势的信号 - emit openTrend(time_stamp,trendMap.values()); - //test(trendMap.values()); - } -} - -void CAlarmForm::rightVideo0() -{ - QModelIndex index = ui->alarmView->currentIndex(); - if(!index.isValid()) - { - return ; - } - QList listInfo = m_pModel->getListShowAlarmInfo(); - AlarmMsgPtr info = listInfo.at(index.row()); - if(info != NULL) - { - if(info->m_needVideoAlm) - { - QString pointTag = info->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - emit openVideo(info->domain_id,info->app_id,pointTag,info->time_stamp-VIDEO_TIME,info->time_stamp+VIDEO_TIME); - }else - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("请选中具有视频的告警!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); - return ; - } - } -} - -void CAlarmForm::rightVideo1() -{ - if(!m_treeModel) - { - return; - } - QModelIndex index = ui->aiAlarmTreeView->currentIndex(); - if(!index.isValid()) - { - return ; - } - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - if(item->isAi()) - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("请选中具有视频的告警!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); - return ; - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - if(ptr->m_needVideoAlm) - { - QString pointTag = ptr->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); - }else - { - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("请选中具有视频的告警!")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); - return ; - } - } - } -} - -void CAlarmForm::rightFaultRecord0() -{ - QModelIndex index = ui->alarmView->currentIndex(); - if(!index.isValid()) - { - return ; - } - QList listInfo = m_pModel->getListShowAlarmInfo(); - AlarmMsgPtr info = listInfo.at(index.row()); - if(info != NULL) - { - //故障录播暂不实现 - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("故障录播暂不实现")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); - return ; - } -} - -void CAlarmForm::rightFaultRecord1() -{ - if(!m_treeModel) - { - return ; - } - QModelIndex index = ui->aiAlarmTreeView->currentIndex(); - if(!index.isValid()) - { - return ; - } - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - //故障录播暂时不实现 - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("故障录播暂不实现")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); - return ; - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - //故障录播暂时不实现 - // QMessageBox *msgBox = new QMessageBox(this); - // msgBox->setObjectName("msgbox"); - // msgBox->setText(tr("故障录播暂不实现")); - // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - // msgBox->setDefaultButton(skip); - // msgBox->exec(); - QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); - return ; - } - } -} - -void CAlarmForm::rightAccidentReview0() -{ - QModelIndex index = ui->alarmView->currentIndex(); - if(!index.isValid()) - { - return ; - } - QList listInfo = m_pModel->getListShowAlarmInfo(); - AlarmMsgPtr info = listInfo.at(index.row()); - if(info != NULL) - { - if(!info->graph_name.isEmpty()) - { - emit openAccidentReview(info->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,info->graph_name); - } - else - { - CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); - if(dialog->exec() == QDialog::Accepted) - { - emit openAccidentReview(info->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); - } - delete dialog; - dialog = NULL; - } - } -} - -void CAlarmForm::rightAccidentReview1() -{ - if(!m_treeModel) - { - return ; - } - QModelIndex index = ui->aiAlarmTreeView->currentIndex(); - if(!index.isValid()) - { - return ; - } - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); - if(dialog->exec() == QDialog::Accepted) - { - emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); - } - delete dialog; - dialog = NULL; - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - if(!ptr->graph_name.isEmpty()) - { - emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,ptr->graph_name); - } - else - { - CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); - if(dialog->exec() == QDialog::Accepted) - { - emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); - } - delete dialog; - dialog = NULL; - } - } - } -} -/** - * @brief CAlarmForm::test 测试输出 - * @param tagList - */ -void CAlarmForm::test(QStringList tagList) -{ - QString tag = QString(); - for(int index(0);indexsetObjectName("msgbox"); - msgBox->setText(tag); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; -} - -void CAlarmForm::inhibitAlm(const AlarmMsgPtr &alm) -{ - kbd_net::CMbMessage msg; - msg.setSubject(alm->sub_system, CH_HMI_TO_OPT_OPTCMD_DOWN); - SOptTagSet sOptTagSet; - SOptTagQueue optTagQueue; - COptTagSet cOptTagSet; - - if(createReqHead(sOptTagSet.stHead,alm)!= kbdSuccess) - { - return ; - } - QString keyIdTag = alm->key_id_tag; - if(keyIdTag.endsWith(".value")) - { - //禁止告警和实时数据代码一致,要不实时数据 插件取消告警会失败; - // keyIdTag.replace(QString(".value"),QString(".status")); - }else - { - return ; - } - - optTagQueue.strKeyIdTag = keyIdTag.toStdString(); - optTagQueue.nIsSet = 1;// 0:取消;1:设置; - optTagQueue.fSetValue = 1; - optTagQueue.strStateText = ""; - optTagQueue.bIsPointQuery = false; - optTagQueue.nLocationId = alm->location_id; - optTagQueue.nSubSystem = alm->sub_system; - - sOptTagSet.vecTagQueue.push_back(optTagQueue); - std::string content = cOptTagSet.generate(sOptTagSet); - - msg.setMsgType(MT_OPT_PINHIBIT_ALARM); - - msg.setData(content); - LOGINFO("%s",QString::fromStdString(content).toStdString().c_str()); - if(m_communicator == Q_NULLPTR) - { - QMessageBox::warning(this, tr("提示"), tr("禁止告警失败!"), QMessageBox::Ok); - } - if(!m_communicator->sendMsgToDomain(msg, alm->domain_id)) - { - QMessageBox::warning(this, tr("提示"), tr("禁止告警失败!"), QMessageBox::Ok); - } -} - -bool CAlarmForm::permCheck(int location, int region) -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - int userId; - if(PERM_NORMAL != permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - userId = -1; - return false; - } - std::vector vecRegionOptId; - QList regList; - QList locList; - std::vector vecLocationOptId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) - { - - std::vector ::iterator region = vecRegionOptId.begin(); - while (region != vecRegionOptId.end()) - { - regList.append(*region++); - } - - std::vector ::iterator location = vecLocationOptId.begin(); - while (location != vecLocationOptId.end()) - { - locList.append(*location++); - } - } - if(locList.contains(location) && regList.contains(region)) - { - return true; - }else - { - QMessageBox::warning(this, tr("警告"), tr("无禁止告警权限!"), QMessageBox::Ok); - return false; - } - } - QMessageBox::warning(this, tr("警告"), tr("初始化权限失败!"), QMessageBox::Ok); - return false; -} - -int CAlarmForm::createReqHead(SOptReqHead &head, const AlarmMsgPtr &alm) -{ - if(!m_ptrSysInfo) - { - if(!createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return kbdFailed; - } - } - - int userID = -1; - int usergID = -1; - int level; - int loginSec; - std::string instanceName; - - kbd_service::CPermMngApiPtr permMng = kbd_service::getPermMngInstance("base"); - if(permMng != NULL) - { - if(permMng->PermDllInit() != PERM_NORMAL) - { - LOGERROR("权限接口初始化失败!"); - return kbdFailed; - }else - { - if(PERM_NORMAL != permMng->CurUser(userID, usergID, level, loginSec, instanceName)) - { - userID = -1; - return kbdFailed; - } - } - } - head.strSrcTag = "alarm_window"; - head.nSrcDomainID = m_nDomainId; - head.nDstDomainID = alm->domain_id; - - if(m_ptrSysInfo != Q_NULLPTR) - { - kbd_public::SAppInfo stAppInfo; - m_ptrSysInfo->getAppInfoBySubsystemId(alm->sub_system,stAppInfo); - head.nAppID = stAppInfo.nId; - }else - { - head.nAppID = alm->sub_system; - } - head.strHostName = m_nodeName; - head.strInstName = instanceName; - head.strCommName = m_communicator->getName(); - head.nUserID = userID; - head.nUserGroupID = usergID; - head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - - return kbdSuccess; -} - -void CAlarmForm::reloadDevTree() -{ - updateAlarmOperatePerm(); - loadDeviceGroupFilterWidget(); -} +#include "CAlarmForm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ui_CAlarmForm.h" +#include "CAlarmDelegate.h" +#include "CAiAlarmDelegate.h" +#include "CAlarmItemModel.h" +#include "CAlarmFilterDialog.h" +#include "CAlarmMsgManage.h" +#include "CTableViewPrinter.h" +#include "CAlarmDataCollect.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmInhibitDialog.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmDeviceTreeItem.h" +#include "CAiAlarmTreeItem.h" +#include "CAiAlarmTreeModel.h" +#include "perm_mng_api/PermMngApi.h" +#include +#include +#include "CMyListWidget.h" +#include "CMyCheckBox.h" +#include "CDisposalPlanDialog.h" +#include "CTreeViewPrinter.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileUtil.h" +#include +#include "CAlarmTaskMngDlg.h" +#include +#include "CAlarmSetDlg.h" +#include "CAlarmBaseData.h" +#include "CAlarmShiledDialog.h" +#include "CAccidentReviewDialog.h" +CAlarmForm::CAlarmForm(QWidget *parent) : + QWidget(parent), + m_ptrSysInfo(Q_NULLPTR), + m_pReadDb(Q_NULLPTR), + m_aiOptPerm(true), + m_pModel(Q_NULLPTR), + m_delegate(Q_NULLPTR), + m_aiDelegate(Q_NULLPTR), + m_treeModel(Q_NULLPTR), + m_communicator(Q_NULLPTR), + ui(new Ui::CAlarmForm), + m_isNormal(true), + m_isNeedAccidentReview(true), + m_strAccidenPath(QString()) +{ + m_communicator = new kbd_net::CMbCommunicator(); + qRegisterMetaType("QItemSelection"); + qRegisterMetaType< QList > >("QList >"); + qRegisterMetaType >("QVector"); + qRegisterMetaType >("QVector"); + qRegisterMetaType >("QVector"); + ui->setupUi(this); + ui->alarmView->setObjectName("alarmView"); + ui->splitter->setStretchFactor(0,1); + ui->splitter->setStretchFactor(1,6); + + QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->deviceView->header()); + m_pSearchTextEdit = new QLineEdit(ui->deviceView->header()); + m_pSearchTextEdit->setObjectName("searchTextEdit"); + m_pSearchTextEdit->setTextMargins(0, 0, 21, 0); + m_pSearchTextEdit->setPlaceholderText(tr("按设备组关键字搜索")); + pHBoxLayout->addWidget(m_pSearchTextEdit); + pHBoxLayout->setContentsMargins(2,0,2,0); + pHBoxLayout->setSpacing(0); + ui->deviceView->header()->setLayout(pHBoxLayout); + ui->deviceView->header()->setObjectName("deviceHeader"); + //ui->deviceView->header()->setFixedHeight(30); + + m_pSearchButton = new QPushButton(this); + m_pSearchButton->setObjectName("searchButton"); + m_pSearchButton->setText(""); + m_pSearchButton->setMaximumSize(21, 22); + m_pSearchButton->setCursor(QCursor(Qt::ArrowCursor)); + + QHBoxLayout * pSearchLayout = new QHBoxLayout(); + pSearchLayout->setContentsMargins(1, 1, 1, 1); + pSearchLayout->addStretch(); + pSearchLayout->addWidget(m_pSearchButton); + m_pSearchTextEdit->setLayout(pSearchLayout); + + connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CAlarmForm::searchDeviceName); + connect(m_pSearchButton, &QPushButton::clicked, this, &CAlarmForm::searchDeviceName); + m_pListWidget1 = new CMyListWidget(this); + m_pListWidget2 = new CMyListWidget(this); + m_pListWidget3 = new CMyListWidget(this); + m_pLineEdit1 = new QLineEdit(this); + m_pLineEdit2 = new QLineEdit(this); + m_pLineEdit3 = new QLineEdit(this); + m_timeIcon = new QPushButton(this); + //时间过滤 + m_myCalendar = new CMyCalendar(this); + QWidgetAction *widgetAction=new QWidgetAction(this); + m_timeMenu = new QMenu(this); + widgetAction->setDefaultWidget(m_myCalendar); + m_timeMenu->addAction(widgetAction); + m_timeIcon->setObjectName("iconButton"); + m_timeIcon->setText(""); + m_timeIcon->setMaximumSize(21, 22); + m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_timeIcon); + ui->lineEdit->setLayout(pTimeLayout); + connect(m_timeIcon,&QPushButton::clicked,this,&CAlarmForm::myCalendarShow); + connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CAlarmForm::myCalendarHide); + connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CAlarmForm::cancleTimeFilter); + ui->lineEdit->setText(tr("请选择时间")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit->setObjectName("iconLineEdit"); + + m_pdfPrinter = new CPdfPrinter(); + m_thread = new QThread(); + m_pdfPrinter->moveToThread(m_thread); + connect(m_thread,&QThread::started,m_pdfPrinter,&CPdfPrinter::initialize); + connect(m_thread,&QThread::finished,m_pdfPrinter,&CPdfPrinter::deleteLater); + connect(this,&CAlarmForm::printExcel,m_pdfPrinter,&CPdfPrinter::printerByModel); + connect(this,&CAlarmForm::printExcelAlm,m_pdfPrinter,&CPdfPrinter::printerAlmByModel); + connect(m_pdfPrinter,&CPdfPrinter::printResult,this,&CAlarmForm::printMess); + ui->aiAlarmTreeView->setUpdatesEnabled(false); + ui->alarmView->setUpdatesEnabled(false); + m_thread->start(); +} + +CAlarmForm::~CAlarmForm() +{ + if(m_communicator != Q_NULLPTR) + { + delete m_communicator; + } + m_communicator =Q_NULLPTR; + + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + if(m_delegate) + { + delete m_delegate; + } + m_delegate = Q_NULLPTR; + + if(m_aiDelegate) + { + delete m_aiDelegate; + } + m_aiDelegate = Q_NULLPTR; + + if(m_pdfPrinter) + { + delete m_pdfPrinter; + } + m_pdfPrinter = Q_NULLPTR; + + if(m_thread) + { + m_thread->quit(); + m_thread->wait(); + } + + delete ui; + LOGDEBUG("CAlarmForm::~CAlarmForm()"); +} + +void CAlarmForm::initialize() +{ + if (!kbd_public::createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + if(m_pReadDb == NULL) + { + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + LOGERROR("数据库打开失败,%s",m_pReadDb->getLastErrorString().toStdString().c_str()); + } + } + m_pDeviceModel = new CAlarmDeviceTreeModel(this); + ui->deviceView->setModel(m_pDeviceModel); + connect(ui->set,&QPushButton::clicked,this,&CAlarmForm::slot_showColorSet); + connect(ui->checkBox,SIGNAL(stateChanged(int)),this,SLOT(slot_changePage(int))); + connect(ui->filter, SIGNAL(clicked()), this, SLOT(updateFilter())); + connect(ui->remove, SIGNAL(clicked()), this, SLOT(slot_removeAlarm())); + connect(ui->confirm, SIGNAL(clicked()), this, SLOT(slot_confirmAlarm())); + + //connect(ui->inhibit, SIGNAL(clicked()), this, SLOT(slot_showInhibitAlarm())); + connect(ui->inhibit, SIGNAL(clicked()), this, SLOT(slot_showShiledAlarm())); + + connect(ui->print, SIGNAL(clicked()), this, SLOT(print())); + connect(ui->closeBtn, &QPushButton::clicked, this, &CAlarmForm::closeBtnClicked); + connect(ui->inhiAlarm, &QPushButton::clicked, this, &CAlarmForm::slotInhibitAlarm); + setHiddenInhiAlarmButton(true); + updateAlarmOperatePerm(); + + //< lingdaoyaoqiu + { + QSettings columFlags("KBD_HMI", "alarm config"); + if(!columFlags.contains(QString("alarm/colum_0"))) + { + columFlags.setValue(QString("alarm/colum_0"), false); //< 时间 + columFlags.setValue(QString("alarm/colum_1"), false); //< 优先级 + columFlags.setValue(QString("alarm/colum_2"), false); //< 位置 + columFlags.setValue(QString("alarm/colum_3"), true); //< 责任区 + columFlags.setValue(QString("alarm/colum_4"), true); //< 告警类型 + columFlags.setValue(QString("alarm/colum_5"), false); //< 告警状态 + columFlags.setValue(QString("alarm/colum_6"), false); //< 确认状态 + columFlags.setValue(QString("alarm/colum_7"), false); //< + } + } + ui->comboBox->setModel(m_pListWidget1->model()); + ui->comboBox->setView(m_pListWidget1); + ui->comboBox->setLineEdit(m_pLineEdit1); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + m_pLineEdit1->setReadOnly(true); + connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 + ui->comboBox_2->setModel(m_pListWidget2->model()); + ui->comboBox_2->setView(m_pListWidget2); + ui->comboBox_2->setLineEdit(m_pLineEdit2); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + m_pLineEdit2->setReadOnly(true); + connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); + ui->comboBox_3->setModel(m_pListWidget3->model()); + ui->comboBox_3->setView(m_pListWidget3); + ui->comboBox_3->setLineEdit(m_pLineEdit3); + m_strText3 = tr("请选择告警状态"); + m_pLineEdit3->setText(tr("请选择告警状态")); + m_pLineEdit3->setReadOnly(true); + connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); +} + +void CAlarmForm::init() +{ + reloadDevTree(); + initFilter(); +} + +void CAlarmForm::updateAlarmOperatePerm() +{ + m_listRegionOptId.clear(); + m_listLocationOptId.clear(); + m_listRegionDelId.clear(); + m_listLocationDelId.clear(); + kbd_public::SNodeInfo stNodeInfo; + if (!m_ptrSysInfo) + { + if(!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + } + m_ptrSysInfo->getLocalNodeInfo(stNodeInfo); + m_nodeName = stNodeInfo.strName; + m_nDomainId = stNodeInfo.nDomainId; + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(PERM_NORMAL != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + m_userId = -1; + LOGERROR("用户ID获取失败!"); + return; + } + std::vector vecRegionOptId; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionOptId, vecLocationOptId)) + { + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + m_listRegionOptId.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + m_listLocationOptId.append(*location++); + } + } + std::vector vecRegionDelId; + std::vector vecLocationDelId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, vecRegionDelId, vecLocationDelId)) + { + std::vector ::iterator region = vecRegionDelId.begin(); + while (region != vecRegionDelId.end()) + { + m_listRegionDelId.append(*region++); + } + + std::vector ::iterator location = vecLocationDelId.begin(); + while (location != vecLocationDelId.end()) + { + m_listLocationDelId.append(*location++); + } + } + + std::string str = "FUNC_NOM_IA_EDIT"; + if(PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF,&str)) + { + m_aiOptPerm = false; + LOGINFO("无智能告警编辑权限"); + }else + { + m_aiOptPerm = true; + } + } +} + +void CAlarmForm::setAlarmOperateEnable(const bool &bEnable) +{ + ui->confirm->setEnabled(bEnable); + ui->remove->setEnabled(bEnable); + m_isNormal = bEnable; +} + +void CAlarmForm::setColumnWidth(const int &column, const int &width) +{ + if(ui->alarmView != Q_NULLPTR) + { + ui->alarmView->setColumnWidth(column, width); + } + if(ui->aiAlarmTreeView != Q_NULLPTR) + { + ui->aiAlarmTreeView->setColumnWidth(column, width); + } +} + +void CAlarmForm::setColumnVisible(const int &column, const bool &visible) +{ + if(ui->alarmView != Q_NULLPTR) + { + ui->alarmView->setColumnHidden(column, !visible); + } + if(ui->aiAlarmTreeView != Q_NULLPTR) + { + ui->aiAlarmTreeView->setColumnHidden(column, !visible); + } +} + +void CAlarmForm::setEnableAccidentReview(bool isNeed) +{ + m_isNeedAccidentReview = isNeed; +} + +void CAlarmForm::setEnableTrend(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableTrend(isNeed); + } + if(m_aiDelegate) + { + m_aiDelegate->setEnableTrend(isNeed); + } +} + +void CAlarmForm::setEnableVideo(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableVideo(isNeed); + } + if(m_aiDelegate) + { + m_aiDelegate->setEnableVideo(isNeed); + } +} + +void CAlarmForm::setEnableWave(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableWave(isNeed); + } + if(m_aiDelegate) + { + m_aiDelegate->setEnableWave(isNeed); + } +} + +void CAlarmForm::setEnableLevel(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableLevel(isNeed); + } + if(m_aiDelegate) + { + m_aiDelegate->setEnableLevel(isNeed); + } +} + +void CAlarmForm::setHiddenLocation(bool hide) +{ + ui->label_4->setHidden(hide); + ui->comboBox_2->setHidden(hide); +} + +void CAlarmForm::setHiddenTime(bool hide) +{ + ui->label_6->setHidden(hide); + ui->lineEdit->setHidden(hide); +} + +void CAlarmForm::setHiddenStatus(bool hide) +{ + ui->label_5->setHidden(hide); + ui->comboBox_3->setHidden(hide); +} + +void CAlarmForm::setHiddenPriority(bool hide) +{ + ui->label_3->setHidden(hide); + ui->comboBox->setHidden(hide); +} + +void CAlarmForm::setHiddenCheckBox(bool hide) +{ + ui->checkBox->setHidden(hide); +} + +void CAlarmForm::setHiddenSetConfig(bool hide) +{ + ui->set->setHidden(hide); +} + +void CAlarmForm::setHiddenCloseButton(bool hide) +{ + ui->closeBtn->setHidden(hide); +} + +void CAlarmForm::setHiddenInhiAlarmButton(bool hide) +{ + ui->inhiAlarm->setHidden(hide); +} + +void CAlarmForm::setShowAiAlarmView(bool show) +{ + if(m_treeModel) + { + ui->checkBox->setHidden(false); + ui->checkBox->setChecked(show); + }else + { + ui->checkBox->setHidden(true); + } +} + +void CAlarmForm::setRowHeight(int height) +{ + if(ui->alarmView != Q_NULLPTR) + { + ui->alarmView->setDefaultRowHeight(height); + } +} + +void CAlarmForm::setAccidentReviewPath(const QString &path) +{ + m_strAccidenPath = path; +} + +void CAlarmForm::initFilter() +{ + m_pListWidget1->clear(); + m_pListWidget2->clear(); + m_pListWidget3->clear(); + QMap priority = CAlarmBaseData::instance()->getPermPriorityMap(); + QMap alarmStatus = CAlarmBaseData::instance()->getAlarmShowStatusMap(); + for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); + pItem->setData(Qt::UserRole, it1.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it1.value()); + m_pListWidget1->addItem(pItem); + m_pListWidget1->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); + } + + QList locationList = CAlarmBaseData::instance()->getPermLocationOrder(); + foreach (const int locId, locationList) { + QString locDesc = CAlarmBaseData::instance()->getPermLocationDesc(locId); + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); + pItem->setData(Qt::UserRole, locId); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(locDesc); + m_pListWidget2->addItem(pItem); + m_pListWidget2->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); + } + + for(QMap::iterator it3 = alarmStatus.begin();it3 != alarmStatus.end();++it3) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); + pItem->setData(Qt::UserRole, it3.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it3.value()); + m_pListWidget3->addItem(pItem); + m_pListWidget3->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); + } + m_strText1 = tr("请选择优先级"); + m_strText2 = tr("请选择位置"); + m_strText3 = tr("请选择告警状态"); + m_pLineEdit1->setText(m_strText1); + m_pLineEdit2->setText(m_strText2); + m_pLineEdit3->setText(m_strText3); +} + +void CAlarmForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) +{ + if(isLevelFilter == true && listLevel.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget1->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLevel.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText1 = strText; + m_pLineEdit1->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget1->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } +} + +void CAlarmForm::setLocationComboBox(bool &isLocationFilter,QList &listLocation) +{ + if(isLocationFilter == true && listLocation.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLocation.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText2 = strText; + m_pLineEdit2->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } +} + +void CAlarmForm::setAlarmStatusComboBox(bool &isAlarmTypeFilter, QList &listAlarmStatus) +{ + if(isAlarmTypeFilter == true && listAlarmStatus.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listAlarmStatus.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText3 = strText; + m_pLineEdit3->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText3 = tr("请选择告警状态"); + m_pLineEdit3->setText(tr("请选择告警状态")); + } +} + +void CAlarmForm::setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) +{ + if(isTimeFilter == true) + { + ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); + }else + { + ui->lineEdit->setText(tr("请选择时间")); + } +} + +void CAlarmForm::setAlarmModel(CAlarmItemModel *model,CAiAlarmTreeModel *treeModel) +{ + ui->checkBox->setChecked(true); + slot_changePage(0); + ui->alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + ui->aiAlarmTreeView->header()->setSortIndicator(0, Qt::AscendingOrder); + m_pModel = model; + m_delegate = new CAlarmDelegate(m_pModel, ui->alarmView); + connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); + connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + ui->alarmView->initialize(); + ui->aiAlarmTreeView->initialize(); + ui->alarmView->setItemDelegate(m_delegate); + ui->alarmView->setModel(m_pModel); + m_treeModel = treeModel; + m_aiDelegate = new CAiAlarmDelegate(m_treeModel,ui->aiAlarmTreeView); + ui->aiAlarmTreeView->setItemDelegate(m_aiDelegate); + ui->aiAlarmTreeView->setModel(m_treeModel); + connect(m_aiDelegate,&CAiAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); + connect(m_aiDelegate,&CAiAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_aiDelegate,&CAiAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + //< 性能损耗 + //connect(ui->alarmView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(slot_selectionChanged()), Qt::QueuedConnection); + + connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); + connect(ui->aiAlarmTreeView->header(),&QHeaderView::sortIndicatorChanged, m_treeModel,&CAiAlarmTreeModel::sortColumn); + connect(ui->aiAlarmTreeView,&CAiAlarmTreeView::doubleClicked, this,&CAlarmForm::aiAlmDoubleClicked); + ui->confirm->setEnabled(true); + ui->remove->setEnabled(true); + //原始告警窗 + + ui->alarmView->setColumnWidth(0, 230); + ui->alarmView->setColumnWidth(1, 120); + ui->alarmView->setColumnWidth(2, 150); + ui->alarmView->setColumnWidth(5, 150); + ui->alarmView->setColumnWidth(6, 120); + + QSettings columFlags("KBD_HMI", "alarm config"); + for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount() - 1; nColumnIndex++) + { + bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); + ui->alarmView->setColumnHidden(nColumnIndex, visible); + } + ui->alarmView->setColumnHidden(m_pModel->columnCount() - 1, false); + //智能告警窗 + ui->aiAlarmTreeView->setColumnWidth(0, 230); + ui->aiAlarmTreeView->setColumnWidth(1, 120); + ui->aiAlarmTreeView->setColumnWidth(2, 150); + ui->aiAlarmTreeView->setColumnWidth(5, 150); + ui->aiAlarmTreeView->setColumnWidth(6, 120); + + for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount(); nColumnIndex++) + { + bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, visible); + } + + loadDeviceGroupFilterWidget(); + if(m_pDeviceModel) + { + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::inhibitDevGroupAlm, this, &CAlarmForm::slotInhibitDevGroupAlm); + connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigDevTreeUpdate,m_pDeviceModel,&CAlarmDeviceTreeModel::slotDevTreeUpdate); + } + initFilter(); +} + +void CAlarmForm::setAlarmModel(CAlarmItemModel *model) +{ + ui->checkBox->setChecked(false); + ui->checkBox->setHidden(true); + slot_changePage(0); + ui->alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + m_pModel = model; + m_delegate = new CAlarmDelegate(m_pModel, ui->alarmView); + connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); + connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + ui->alarmView->initialize(); + ui->alarmView->setItemDelegate(m_delegate); + ui->alarmView->setModel(m_pModel); + + + connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); + ui->confirm->setEnabled(true); + ui->remove->setEnabled(true); + //原始告警窗 + + ui->alarmView->setColumnWidth(0, 230); + ui->alarmView->setColumnWidth(1, 120); + ui->alarmView->setColumnWidth(2, 150); + ui->alarmView->setColumnWidth(5, 150); + ui->alarmView->setColumnWidth(6, 120); + + + QSettings columFlags("KBD_HMI", "alarm config"); + for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount() - 1; nColumnIndex++) + { + bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); + ui->alarmView->setColumnHidden(nColumnIndex, visible); + } + ui->alarmView->setColumnHidden(m_pModel->columnCount() - 1, false); + + loadDeviceGroupFilterWidget(); + if(m_pDeviceModel) + { + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::inhibitDevGroupAlm, this, &CAlarmForm::slotInhibitDevGroupAlm); + } + initFilter(); +} + +void CAlarmForm::updateView() +{ + updateRowTips(); + updateDeviceGroupHiddenState(); +} + +void CAlarmForm::updateFilter() +{ + bool isLevelFilter; + QList levelFilter; + bool isLocationFilter; + QList locationFilter; + bool isRegionFilter; + QList regionFilter; + bool isAlarmStatusFilter; //告警状态过滤 + QList typeFilter; + bool deviceTypeFilter; + QString subSystem; + QString deviceType; + bool keywordFilter; + QString keyword; + bool isTimeFilterEnable; + QDateTime startTime; + QDateTime endTime; + bool isStateFilterEnable; + bool isConfirm; + bool isReturnFilterEnable; + bool isReturn; + + CAlarmFilterDialog filterDlg; + m_pModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmStatusFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime, + isStateFilterEnable, isConfirm, + isReturnFilterEnable,isReturn); + filterDlg.initialize(); + filterDlg.setLevelFilterEnable(isLevelFilter); + filterDlg.setLevelFilter(levelFilter); + filterDlg.setLocationFilterEnable(isLocationFilter); + filterDlg.setLocationFilter(locationFilter); + filterDlg.setRegionFilterEnable(isRegionFilter); + filterDlg.setRegionFilter(regionFilter); + filterDlg.setAlarmStatusFilterEnable(isAlarmStatusFilter); + filterDlg.setAlarmStatusFilter(typeFilter); + filterDlg.setDeviceFilterEnable(deviceTypeFilter); + filterDlg.setSubSystem(subSystem); + filterDlg.setDeviceType(deviceType); + filterDlg.setkeyWordFilterEnable(keywordFilter); + filterDlg.setkeyWordFilteContent(keyword); + filterDlg.setTimeFilterEnable(isTimeFilterEnable); + filterDlg.setStartTimeFilter(startTime); + filterDlg.setEndTimeFilter(endTime); + filterDlg.setStateFilterEnable(isStateFilterEnable); + filterDlg.setStateFilter(isConfirm); + filterDlg.setReturnFilterEnable(isReturnFilterEnable); + filterDlg.setReturnFilter(isReturn); + connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool, bool, bool)), + this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool, bool, bool))); + filterDlg.exec(); +} + +void CAlarmForm::deviceGroupFilterChanged(const QString &device, const bool &checked) +{ + if(checked) + { + m_pModel->removeDeviceGroupFilter(device); + if(m_treeModel) + { + m_treeModel->removeDeviceGroupFilter(device); + } + + } + else + { + m_pModel->addDeviceGroupFilter(device); + if(m_treeModel) + { + m_treeModel->addDeviceGroupFilter(device); + } + } +} + +void CAlarmForm::slot_changePage(int i) +{ + Q_UNUSED(i) + if(!ui->checkBox->isChecked()) + { + ui->stackedWidget->setCurrentIndex(0); + ui->aiAlarmTreeView->setUpdatesEnabled(false); + ui->alarmView->setUpdatesEnabled(true); + ui->inhiAlarm->setEnabled(true); + }else + { + ui->stackedWidget->setCurrentIndex(1); + ui->alarmView->setUpdatesEnabled(false); + ui->aiAlarmTreeView->setUpdatesEnabled(true); + ui->inhiAlarm->setEnabled(false); + } +} + +void CAlarmForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmStatus, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm, bool isReturnFilter, bool isReturn) +{ + m_pModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,isReturn); + if(m_treeModel) + { + m_treeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,isReturn); + } + //设置下拉框的值 + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setAlarmStatusComboBox(isAlarmTypeFilter,listAlarmStatus); + setAlarmTimeLineEdit(isTimeFilter, startTime, endTime); +} + +void CAlarmForm::slot_removeAlarm() +{ + updateAlarmOperatePerm(); + if(!ui->checkBox->isChecked()) + { + removeAlarm0(); + }else + { + removeAlarm1(); + } +} + +void CAlarmForm::slot_confirmAlarm() +{ + updateAlarmOperatePerm(); + if(!ui->checkBox->isChecked()) + { + confirmAlarm0(); + }else + { + confirmAlarm1(); + } +} + +void CAlarmForm::slot_showInhibitAlarm() +{ + CAlarmInhibitDialog dlg; + QList almList; + CAlarmMsgManage::instance()->getAllInhibitAlm(almList); + + dlg.setInhibitAlarmList(almList); + connect(&dlg, &CAlarmInhibitDialog::removeInhibitAlarmList, this, &CAlarmForm::removeInhibitAlarm); + dlg.exec(); + +} + +void CAlarmForm::slot_showShiledAlarm() +{ + CAlarmShiledDialog dlg; + dlg.exec(); +} + +void CAlarmForm::slot_showColorSet() +{ + CAlarmSetDlg dlg; + dlg.exec(); +} + +void CAlarmForm::removeInhibitAlarm(QList alarmList) +{ + foreach (AlarmMsgPtr alm, alarmList) + { + CAlarmMsgManage::instance()->removeInhibitTag(alm->key_id_tag); + } +} + +void CAlarmForm::searchDeviceName() +{ + QItemSelection selection; + QString content = m_pSearchTextEdit->text(); + ui->deviceView->selectionModel()->select(selection, QItemSelectionModel::Clear); + if(content.isEmpty()) + { + return; + } + const QHash< QString, QModelIndex > &indexNameList = m_pDeviceModel->indexNameList(); + QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); + while (iter != indexNameList.constEnd()) + { + if(ui->deviceView->isRowHidden(iter.value().row(), iter.value().parent())) + { + iter++; + continue; + } + if(iter.key().section(".", 1).contains(content, Qt::CaseInsensitive)) + { + selection.append(QItemSelectionRange(iter.value(), iter.value())); + selection.append(QItemSelectionRange(iter.value().parent(), iter.value().parent())); + } + iter++; + } + ui->deviceView->selectionModel()->select(selection, QItemSelectionModel::Select); +} + +void CAlarmForm::updateRowTips() +{ + if(!ui->checkBox->isChecked()) + { + if(m_pModel) + { + ui->alarmView->viewport()->update(); + ui->showRow->setText(QString::number(m_pModel->rowCount())); + int nNumber = m_pModel->filterCount(); + if(nNumber<0) nNumber = 0 ; + ui->filterRow->setText(QString::number(nNumber)); + } + } + else + { + if(m_treeModel) + { + ui->aiAlarmTreeView->viewport()->update(); + int showNum = m_treeModel->getShowNum(); + int showAiNum = m_treeModel->getShowAi(); + int filterAi = CAlarmMsgManage::instance()->getAiCount() -showAiNum; + int showTotal = CAlarmMsgManage::instance()->getAlmTotal(); + ui->showRow->setText(QString("%1/%2").arg(showNum).arg(showAiNum)); + int nNumber = showTotal - showNum; + if(nNumber<0) nNumber = 0 ; + if(filterAi<0) filterAi = 0; + ui->filterRow->setText(QString("%1/%2").arg(nNumber).arg(filterAi)); + } + } +} + +void CAlarmForm::print() +{ + //QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); + QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"*.xlsx");//获取保存路径*.xls + if(!ui->checkBox->isChecked()) + { + print0(fileName); + }else + { + print1(fileName); + } +} + +void CAlarmForm::stateChanged1(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_priorityList.clear(); + int nCount = m_pListWidget1->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_priorityList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText1 = strText; + m_pLineEdit1->setText(strText); + } + else + { + m_pLineEdit1->clear(); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } + bool isCheck = false; + if(m_priorityList.size() > 0) + { + isCheck = true; + } + if(m_pModel) + { + m_pModel->setPriorityFilter(isCheck,m_priorityList); + } + if(m_treeModel) + { + m_treeModel->setPriorityFilter(isCheck,m_priorityList); + } +} + +void CAlarmForm::stateChanged2(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_locationList.clear(); + int nCount = m_pListWidget2->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_locationList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText2 = strText; + m_pLineEdit2->setText(strText); + } + else + { + m_pLineEdit2->clear(); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } + bool isCheck = false; + if(m_locationList.size() > 0) + { + isCheck = true; + } + if(m_pModel) + { + m_pModel->setLocationFilter(isCheck,m_locationList); + } + if(m_treeModel) + { + m_treeModel->setLocationFilter(isCheck,m_locationList); + } +} + +void CAlarmForm::stateChanged3(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_alarmStatusList.clear(); + bool other = false; + int nCount = m_pListWidget3->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + if(nData == OTHERSTATUS) + { + other = true; + } + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_alarmStatusList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText3 = strText; + m_pLineEdit3->setText(strText); + } + else + { + m_pLineEdit3->clear(); + m_strText3 = tr("请选择告警状态"); + m_pLineEdit3->setText(tr("请选择告警状态")); + } + bool isCheck = false; + if(m_alarmStatusList.size() > 0) + { + isCheck = true; + } + if(m_pModel) + { + m_pModel->setAlarmTypeFilter(isCheck,m_alarmStatusList,other); + } + if(m_treeModel) + { + m_treeModel->setAlarmTypeFilter(isCheck,m_alarmStatusList,other); + } +} + +void CAlarmForm::textChanged1(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit1->setText(m_strText1); +} + +void CAlarmForm::textChanged2(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit2->setText(m_strText2); +} + +void CAlarmForm::textChanged3(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit3->setText(m_strText3); +} + +void CAlarmForm::myCalendarHide(QDate startTime,QDate endTime) +{ + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); + //开始过滤 + bool isCheck = true; + if(m_pModel) + { + m_pModel->setAlarmTimeFilter(isCheck,startTime,endTime); + } + if(m_treeModel) + { + m_treeModel->setAlarmTimeFilter(isCheck,startTime,endTime); + } + m_timeMenu->hide(); +} + +void CAlarmForm::myCalendarShow() +{ + QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); + m_timeMenu->move(point); + m_timeMenu->show(); +} + +void CAlarmForm::cancleTimeFilter() +{ + ui->lineEdit->setText(tr("请选择时间")); + //取消过滤 + bool isCheck = false; + if(m_pModel) + { + m_pModel->setAlarmTimeFilter(isCheck); + } + if(m_treeModel) + { + m_treeModel->setAlarmTimeFilter(isCheck); + } + + m_timeMenu->hide(); +} + +void CAlarmForm::aiAlmDoubleClicked(const QModelIndex &index) +{ + if(m_treeModel == NULL) + { + return ; + } + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item =static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr aiPtr; + if(item->getAiPtr(aiPtr)) + { + CDisposalPlanDialog dialog(aiPtr); + dialog.exec(); + }else + { + LOGERROR("aiAlmDoubleClicked():标识符错误!"); + } + } +} + +void CAlarmForm::printMess(QString fileName) +{ + Q_UNUSED(fileName); + QMessageBox::information( 0, tr("提示"), tr("导出成功")); +} + +void CAlarmForm::slotInhibitDevGroupAlm(const QString &strDevg, int nDomainId, int nLocationId, int nSubsystemId, int nRegionId) +{ + if(!permCheck(nLocationId,nRegionId)) + { + return; + } + QList pointList; + if(!CAlarmBaseData::instance()->queryAllPointDevGroup(nDomainId, nSubsystemId, strDevg, pointList)) + { + QMessageBox::information(this, tr("提示"), tr("禁止告警失败,请检查实时库连接!")); + return; + } + for(int n(0); ndomain_id = nDomainId; + almMsgPtr->location_id = nLocationId; + almMsgPtr->sub_system = nSubsystemId; + almMsgPtr->key_id_tag = pointList[n]; + inhibitAlm(almMsgPtr); + } +} + +void CAlarmForm::slotInhibitAlarm() +{ + if(!m_pModel) + { + return; + } + QModelIndex index = ui->alarmView->currentIndex(); + if(!index.isValid()) + { + QMessageBox::information(this, tr("提示"), tr("请选择一条告警!")); + return; + } + AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); + if(!permCheck(alm->location_id,alm->region_id)) + { + return; + } + inhibitAlm(alm); +} + +void CAlarmForm::contextMenuEvent(QContextMenuEvent *event) +{ + if(!m_isNormal) + { + return ; + } + updateAlarmOperatePerm(); + if(ui->stackedWidget->currentIndex() == 0) + { + contextMenuStack0Event(event); + }else if(ui->stackedWidget->currentIndex() == 1) + { + contextMenuStack1Event(event); + } +} + +void CAlarmForm::contextMenuStack0Event(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(!m_pModel) + { + return; + } + if(event->pos().x() < ui->alarmView->pos().x()) + { + return; + } + QRect headerRect = ui->alarmView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->alarmView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + + for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->alarmView->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags("KBD_HMI", "alarm config"); + columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + columnMenu.exec(QCursor::pos()); + } + else + { + QModelIndex index_ = ui->alarmView->indexAt(ui->alarmView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QModelIndexList indexLists = ui->alarmView->selectionModel()->selectedIndexes(); + //判断右键位置是否在选中区 + QModelIndex index = ui->alarmView->currentIndex(); + if(!indexLists.contains(index)) + { + ui->alarmView->clearSelection(); + ui->alarmView->setCurrentIndex(index); + } + AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); + QMenu menu(this); + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction, &QAction::triggered, [=](){ui->alarmView->selectAll();}); + QAction * cancleAction = menu.addAction(tr("全不选")); + connect(cancleAction,&QAction::triggered,[=](){ui->alarmView->clearSelection();}); + menu.addSeparator(); + + QAction * confirmAction = menu.addAction(tr("确认")); + connect(confirmAction,&QAction::triggered,[=](){ + rightConfirm0(); + }); + QAction * removeAction = menu.addAction(tr("删除")); + connect(removeAction,&QAction::triggered,[=](){ + rightRemove0(); + }); + + menu.addSeparator(); + + // QAction * trendAction = menu.addAction(tr("趋势")); + + // connect(trendAction,&QAction::triggered,[=](){ + // rightTrend0(); + // }); + if(alm->m_needVideoAlm) + { + QAction * videoAction = menu.addAction(tr("视频")); + connect(videoAction,&QAction::triggered,[=](){ + rightVideo0(); + }); + } + // QAction * faultRecordAction = menu.addAction(tr("故障录播")); + // connect(faultRecordAction,&QAction::triggered,[=](){ + // rightFaultRecord0(); + // }); + + + if(m_isNeedAccidentReview) + { + QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); + connect(accidentReviewAction,&QAction::triggered,[=](){ + rightAccidentReview0(); + }); + } + + QAction * InhibitAction = menu.addAction(tr("禁止告警")); + connect(InhibitAction, &QAction::triggered, [=](){ +// bool isContains = false; +// QList almList; +// CAlarmMsgManage::instance()->getAllInhibitAlm(almList); + if(!permCheck(alm->location_id,alm->region_id)) + { + return; + } + inhibitAlm(alm); +// foreach (AlarmMsgPtr alarm, almList) +// { +// if(alarm->key_id_tag == alm->key_id_tag) +// { +// isContains = true; +// break; +// } +// } +// if(isContains) +// { +// QMessageBox::warning(this, tr("警告"), tr("当前测点告警已禁止,无需重复禁止!"), QMessageBox::Ok); +// } +// else +// { +// CAlarmMsgManage::instance()->addInhibitAlm(alm); +// } + }); + + menu.exec(QCursor::pos()); + } +} + +void CAlarmForm::contextMenuStack1Event(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(!m_treeModel) + { + return; + } + if(event->pos().x() < ui->aiAlarmTreeView->pos().x()) + { + return; + } + QRect headerRect = ui->aiAlarmTreeView->header()->rect(); + headerRect.moveTopLeft(ui->aiAlarmTreeView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + + for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_treeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->aiAlarmTreeView->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags("KBD_HMI", "alarm config"); + columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + columnMenu.exec(QCursor::pos()); + }else + { + QModelIndex index_ = ui->aiAlarmTreeView->indexAt(ui->aiAlarmTreeView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QMenu menu(this); + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QModelIndexList indexLists = ui->aiAlarmTreeView->selectionModel()->selectedIndexes(); + + //判断右键位置是否在选中区 + if(!indexLists.contains(index)) + { + ui->aiAlarmTreeView->clearSelection(); + ui->aiAlarmTreeView->setCurrentIndex(index); + } + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->selectAll();}); + QAction * cancleAction = menu.addAction(tr("全不选")); + connect(cancleAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->clearSelection();}); + menu.addSeparator(); + QAction * confirmAction = menu.addAction(tr("确认")); + connect(confirmAction,&QAction::triggered,[=](){ + rightConfirm1(); + }); + QAction * removeAction = menu.addAction(tr("删除")); + connect(removeAction,&QAction::triggered,[=](){ + rightRemove1(); + }); + menu.addSeparator(); + QAction * mergeAction = menu.addAction(tr("合并")); + connect(mergeAction,&QAction::triggered,[=](){ + rightMerge1(); + }); + QAction * seprAction = menu.addAction(tr("分离")); + connect(seprAction,&QAction::triggered,[=](){ + rightSepr1(); + }); + menu.addSeparator(); + //讨论删除右键趋势2020-6-17 jxd sjq zlx + + // QAction * trendAction = menu.addAction(tr("趋势")); + // connect(trendAction,&QAction::triggered,[=](){ + // rightTrend1(); + // }); + + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(!item->isAi()) + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(ptr->m_needVideoAlm) + { + QAction * videoAction = menu.addAction(tr("视频")); + connect(videoAction,&QAction::triggered,[=](){ + rightVideo1(); + }); + } + } + } + // QAction * faultRecordAction = menu.addAction(tr("故障录播")); + // connect(faultRecordAction,&QAction::triggered,[=](){ + // rightFaultRecord1(); + // }); + if(m_isNeedAccidentReview) + { + QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); + connect(accidentReviewAction,&QAction::triggered,[=](){ + rightAccidentReview1(); + }); + } + menu.exec(QCursor::pos()); + } +} + +void CAlarmForm::loadDeviceGroupFilterWidget() +{ + if(!m_pModel) + { + return; + } + QMap< int, QVector< SDevGroupInfo > > locationInfos; + + QList locationList = CAlarmBaseData::instance()->getPermLocationOrder(); + + if(m_pReadDb->isOpen()) + { + for(int nIndex(0); nIndex dev; + + QSqlQuery query; + QString sqlSequenceQuery = QString("select tag_name, description,sub_system,region_id from dev_group where location_id = %1;").arg(locationList[nIndex]); + if(m_pReadDb->execute(sqlSequenceQuery, query)) + { + while(query.next()) + { + SDevGroupInfo _stDevGroupInfo; + _stDevGroupInfo.tag_name = query.value(0).toString(); + _stDevGroupInfo.description = query.value(1).toString(); + _stDevGroupInfo.domain = CAlarmBaseData::instance()->queryDomainIdByLocId(locationList[nIndex]); + _stDevGroupInfo.location = locationList[nIndex]; + _stDevGroupInfo.sub_system = query.value(2).toInt(); + _stDevGroupInfo.region = query.value(3).toInt(); + dev.push_back(_stDevGroupInfo); + } + locationInfos.insert(locationList[nIndex], dev); + }else + { + LOGERROR("load device info error, dbInterface execute failed!"); + } + } + } + else + { + LOGERROR("load deviceGroup info error, database open failed!"); + } + m_pDeviceModel->removeData(); + m_pDeviceModel->setupModelData(locationInfos,locationList); + updateDeviceGroupHiddenState(); + ui->deviceView->expandAll(); +} + +void CAlarmForm::updateDeviceGroupHiddenState() +{ + QHash listDeviceStatisticalInfo = m_pDeviceModel->getDeviceStatisticalInfo(); + for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) + { + QModelIndex topLevelIndex = m_pDeviceModel->index(nTopLevelRow, 0); + for(int nChildRow(0); nChildRow < m_pDeviceModel->rowCount(topLevelIndex); nChildRow++) + { + CAlarmDeviceTreeItem *item = static_cast(m_pDeviceModel->index(nChildRow, 0, topLevelIndex).internalPointer()); + ui->deviceView->setRowHidden(nChildRow, topLevelIndex, !listDeviceStatisticalInfo.value(item->data(Qt::ItemDataRole(TagRole)).toString(), 0)); + } + } +} + +void CAlarmForm::print0(QString fileName) +{ + if(!fileName.isEmpty() && m_pModel) + { + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + fileName = fileName + ".xlsx"; + emit printExcelAlm(m_pModel,fileName); + } +} + +void CAlarmForm::print1(QString fileName) +{ + if(!fileName.isEmpty() && m_treeModel) + { + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + fileName = fileName + ".xlsx"; + emit printExcel(m_treeModel,fileName); + } +} + +void CAlarmForm::removeAlarm0() +{ + QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + //声明告警删除package + QMap pkgMap; //Domain-DelPkg; + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 + + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + AlarmMsgPtr info = listInfo.at(modelIndexIter->row()); + //< 权限过滤 + + if(!m_listLocationDelId.contains(info->location_id) || (!m_listRegionDelId.contains(info->region_id) && info->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + //删除条件 + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + //构建告警删除package + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + //请求删除 + foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) + { + LOGERROR("请求删除原始告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->alarmView->setFocus(); +} + +void CAlarmForm::removeAlarm1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList aimsgList; //选中的智能告警 + QList msgList; //选中的原始告警 + //声明智能告警删除package + QMap aipkgMap; //Domain-DelPkg; ai + QMap pkgMap; //Domain-DelPkg; alarm + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + if(!modelIndexIter->isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndexIter->internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + } + }else + { + if(item->parent() == m_treeModel->getItem()) + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + } + } + } + } + if(aimsgList.size() <= 0 && msgList.size() <= 0) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何智能告警和未聚类的原始告警!"), QMessageBox::Ok); + return; + } + //处理原始告警 + for(int alarm(0);alarmlocation_id) || (!m_listRegionDelId.contains(info->region_id) && info->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + //删除条件 + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + //构建告警删除package + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + //处理智能告警 + for(int aialarm(0);aialarmsetObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(aipkgMap); + aipkgMap.clear(); + return; + } + } + else + { + continue; + } + } + if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aimsgList.at(aialarm)->uuid_base64)) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认原始告警告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(aipkgMap); + aipkgMap.clear(); + return; + } + } + else + { + continue; + } + } + int domain_id = aimsgList.at(aialarm)->domain_id; + QString aiuuid = aimsgList.at(aialarm)->uuid_base64; + QMap::iterator it = aipkgMap.find(domain_id); + if(it == aipkgMap.end()) + { + kbd_idlfile::SIntelliAlmDel * pkg = new kbd_idlfile::SIntelliAlmDel(); + pkg->set_domain_id(domain_id); + aipkgMap[domain_id] = pkg; + } + aipkgMap.value(domain_id)->add_uuid_base64(aiuuid.toStdString()); + } + //请求删除 + foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) + { + LOGDEBUG("请求删除原始告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + //请求删除 + foreach (kbd_idlfile::SIntelliAlmDel * pkg, aipkgMap) + { + if(CAiAlarmDataCollect::instance()->requestDelAlm(*pkg) != true) + { + LOGDEBUG("请求删除智能告警失败!"); + } + } + qDeleteAll(aipkgMap); + aipkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); +} + +void CAlarmForm::confirmAlarm0() +{ + LOGINFO("开始确认告警"); + QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + if(listInfo.isEmpty()) + { + return; + } + + //构建告警确认package + QMap msgMap; //要确认的告警 + QMap pkgMap; //Domain-DelPkg; + + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + AlarmMsgPtr info = listInfo.at(modelIndexIter->row()); + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || + info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL ) + { + continue; + } + msgMap[info->uuid_base64] = info; + } + QMap::iterator almIter = msgMap.begin(); + for(;almIter != msgMap.end();almIter++) + { + if(!m_listLocationOptId.contains(almIter.value()->location_id) || (!m_listRegionOptId.contains(almIter.value()->region_id) && almIter.value()->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + QString key = QString("%1_%2_%3").arg(almIter.value()->domain_id).arg(almIter.value()->alm_type).arg(almIter.value()->app_id); + QMap::iterator it = pkgMap.find(key); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(almIter.value()->domain_id); + pkg->set_app_id(almIter.value()->app_id); + pkg->set_alm_type(almIter.value()->alm_type); + pkgMap[key] = pkg; + } + pkgMap.value(key)->add_key_id_tag(almIter.value()->key_id_tag.toStdString()); + pkgMap.value(key)->add_time_stamp(almIter.value()->time_stamp); + pkgMap.value(key)->add_uuid_base64(almIter.value()->uuid_base64.toStdString()); + } + + //请求确认 + foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) + { + LOGERROR("请求确认告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->alarmView->setFocus(); + LOGINFO("结束确认告警"); +} + +void CAlarmForm::confirmAlarm1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QMap msgMap; //要确认的告警 + msgMap.clear(); + //构建告警确认package + QMap pkgMap; //Domain-DelPkg; + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + if(!modelIndexIter->isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndexIter->internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + QList listPtr = item->getChildAlarmPtr(); + for(int x(0);xlogic_state == E_ALS_ALARM_CFM || listPtr.at(x)->logic_state == E_ALS_RETURN_CFM || + listPtr.at(x)->logic_state == E_ALS_ALARM_CFM_DEL || listPtr.at(x)->logic_state == E_ALS_RETURN_CFM_DEL ) + { + continue; + } + msgMap[listPtr.at(x)->uuid_base64] = listPtr.at(x); + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM || + ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL ) + { + continue; + } + msgMap[ptr->uuid_base64] = ptr; + } + } + } + QMap::iterator almIter = msgMap.begin(); + for(;almIter != msgMap.end();almIter++) + { + if(!m_listLocationOptId.contains(almIter.value()->location_id) || (!m_listRegionOptId.contains(almIter.value()->region_id) && almIter.value()->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + QString key = QString("%1_%2_%3").arg(almIter.value()->domain_id).arg(almIter.value()->alm_type).arg(almIter.value()->app_id); + QMap::iterator it = pkgMap.find(key); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(almIter.value()->domain_id); + pkg->set_app_id(almIter.value()->app_id); + pkg->set_alm_type(almIter.value()->alm_type); + pkgMap[key] = pkg; + } + pkgMap.value(key)->add_key_id_tag(almIter.value()->key_id_tag.toStdString()); + pkgMap.value(key)->add_time_stamp(almIter.value()->time_stamp); + pkgMap.value(key)->add_uuid_base64(almIter.value()->uuid_base64.toStdString()); + } + foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) + { + LOGERROR("请求确认告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); +} + +void CAlarmForm::rightConfirm0() +{ + confirmAlarm0(); +} + +void CAlarmForm::rightConfirm1() +{ + confirmAlarm1(); +} + +void CAlarmForm::rightRemove0() +{ + removeAlarm0(); +} + +void CAlarmForm::rightRemove1() +{ + removeAlarm1(); +} + +void CAlarmForm::rightMerge1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + QList aimsgList; + QList msgList; + + foreach (QModelIndex modelIndex, indexList) + { + if(!modelIndex.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + } + } + } + QMap pkgMap; + QList listPtr; + listPtr.clear(); + int permSkip = -1; + if(aimsgList.size() > 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含智能告警,无法合并!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含智能告警,无法合并!"), QMessageBox::Ok); + return ; + } + + for(int alarmIndex(0);alarmIndex < msgList.size();alarmIndex++) + { + if(msgList.at(alarmIndex) != NULL) + { + //判断此原始告警是否已经被聚类 + if(CAlarmMsgManage::instance()->isBelongAi(msgList.at(alarmIndex)->uuid_base64)) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含已经聚类的原始告警,无法合并!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含已经聚类的原始告警,无法合并!"), QMessageBox::Ok); + return ; + } + //判断权限 + if(!m_aiOptPerm) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户无此条原始告警合并权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox =NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox =NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox =NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + }else + { + listPtr.append(msgList.at(alarmIndex)); + } + } + } + //过滤后等于0直接返回 + if(listPtr.size() <= 0) + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return ; + } + for(int x(0);xdomain_id; + if(!pkgMap.keys().contains(domain_id)) + { + kbd_idlfile::SIntelliAlmMerge *pkg =new kbd_idlfile::SIntelliAlmMerge(); + pkg->set_domain_id(domain_id); + pkgMap[domain_id] = pkg; + } + pkgMap.value(domain_id)->add_raw_alm_uuid(listPtr.at(x)->uuid_base64.toStdString()); + LOGINFO("UUID:%s",listPtr.at(x)->uuid_base64.toStdString().c_str()); + } + if(pkgMap.size() != 1) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含不同域的原始告警,无法合并!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含不同域的原始告警,无法合并!"), QMessageBox::Ok); + qDeleteAll(pkgMap); + pkgMap.clear(); + return ; + } + foreach (kbd_idlfile::SIntelliAlmMerge * pkg, pkgMap) + { + if(CAiAlarmDataCollect::instance()->requestMergeAlm(*pkg) != true) + { + LOGERROR("请求合并告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); + LOGINFO("合并结束!"); +} + +void CAlarmForm::rightSepr1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + QList aimsgList; + QList msgList; + + foreach (QModelIndex modelIndex, indexList) + { + if(!modelIndex.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + } + } + } + if(aimsgList.size() != 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含智能告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含智能告警,无法分离!"), QMessageBox::Ok); + return ; + } + if(msgList.size() <= 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("无原始告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("无原始告警,无法分离!"), QMessageBox::Ok); + return ; + } + QString aiuuid = ""; + if(!CAlarmMsgManage::instance()->getAiuuid(msgList.at(0)->uuid_base64,aiuuid)) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含未聚类的原始告警,无法分离!"), QMessageBox::Ok); + return ; + } + //权限过滤 + if(!m_aiOptPerm) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("无此条智能告警的编辑权限!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("无此条智能告警的编辑权限!"), QMessageBox::Ok); + return ; + } + //遍历所有原始告警 + for(int index(1);indexgetAiuuid(msgList.at(index)->uuid_base64,uuid)) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含未聚类的原始告警,无法分离!"), QMessageBox::Ok); + return ; + } + if(uuid != aiuuid) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含不同智能告警下的原始告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含不同智能告警下的原始告警,无法分离!"), QMessageBox::Ok); + return ; + } + } + //拼包 + int domain_id = msgList.at(0)->domain_id; + kbd_idlfile::SIntelliAlmSepr *pkg = new kbd_idlfile::SIntelliAlmSepr(); + pkg->set_domain_id(domain_id); + for(int index(0);indexadd_raw_alm_uuid(msgList.at(index)->uuid_base64.toStdString()); + } + //发送 + if(CAiAlarmDataCollect::instance()->requestSeprAlm(*pkg) != true) + { + LOGERROR("请求分离告警失败!"); + } + pkg = NULL; + delete pkg; +} + +void CAlarmForm::rightTrend0() +{ + quint64 time_stamp = 0; + QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + QMap trendMap; + foreach (QModelIndex index, modelIndexList) + { + AlarmMsgPtr info = listInfo.at(index.row()); + if(info->m_tagname_type == E_TAGNAME_ANA || info->m_tagname_type == E_TAGNAME_ACC) + { + time_stamp = info->time_stamp; + trendMap[info->uuid_base64] = info->key_id_tag; + } + } + if(trendMap.size()<= 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中含有趋势的告警(模拟量和累积量)!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中含有趋势的告警(模拟量和累积量)!"), QMessageBox::Ok); + return ; + }else + { + //发出打开趋势的信号 + emit openTrend(time_stamp,trendMap.values()); + //test(trendMap.values()); + } +} + +void CAlarmForm::rightTrend1() +{ + if(!m_treeModel) + { + return ; + } + quint64 time_stamp = 0; + QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + QMap trendMap; + foreach (QModelIndex modelIndex, indexList) + { + if(!modelIndex.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + QList listPtr = item->getChildAlarmPtr(); + for(int index(0);indexm_tagname_type == E_TAGNAME_ANA || listPtr.at(index)->m_tagname_type == E_TAGNAME_ACC) + { + time_stamp = listPtr.at(index)->time_stamp; + trendMap[listPtr.at(index)->uuid_base64] = listPtr.at(index)->key_id_tag; + } + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(ptr->m_tagname_type == E_TAGNAME_ANA || ptr->m_tagname_type == E_TAGNAME_ACC) + { + time_stamp = ptr->time_stamp; + trendMap[ptr->uuid_base64] = ptr->key_id_tag; + } + } + } + } + if(trendMap.size()<= 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中含有趋势的告警(模拟量和累积量)!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中含有趋势的告警(模拟量和累积量)!"), QMessageBox::Ok); + return ; + }else + { + //发出打开趋势的信号 + emit openTrend(time_stamp,trendMap.values()); + //test(trendMap.values()); + } +} + +void CAlarmForm::rightVideo0() +{ + QModelIndex index = ui->alarmView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + AlarmMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + if(info->m_needVideoAlm) + { + QString pointTag = info->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(info->domain_id,info->app_id,pointTag,info->time_stamp-VIDEO_TIME,info->time_stamp+VIDEO_TIME); + }else + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中具有视频的告警!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); + return ; + } + } +} + +void CAlarmForm::rightVideo1() +{ + if(!m_treeModel) + { + return; + } + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(item->isAi()) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中具有视频的告警!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); + return ; + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(ptr->m_needVideoAlm) + { + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); + }else + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中具有视频的告警!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); + return ; + } + } + } +} + +void CAlarmForm::rightFaultRecord0() +{ + QModelIndex index = ui->alarmView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + AlarmMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + //故障录播暂不实现 + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("故障录播暂不实现")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); + return ; + } +} + +void CAlarmForm::rightFaultRecord1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + //故障录播暂时不实现 + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("故障录播暂不实现")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); + return ; + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + //故障录播暂时不实现 + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("故障录播暂不实现")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); + return ; + } + } +} + +void CAlarmForm::rightAccidentReview0() +{ + QModelIndex index = ui->alarmView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + AlarmMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + if(!info->graph_name.isEmpty()) + { + emit openAccidentReview(info->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,info->graph_name); + } + else + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReview(info->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } + } +} + +void CAlarmForm::rightAccidentReview1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(!ptr->graph_name.isEmpty()) + { + emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,ptr->graph_name); + } + else + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } + } + } +} +/** + * @brief CAlarmForm::test 测试输出 + * @param tagList + */ +void CAlarmForm::test(QStringList tagList) +{ + QString tag = QString(); + for(int index(0);indexsetObjectName("msgbox"); + msgBox->setText(tag); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; +} + +void CAlarmForm::inhibitAlm(const AlarmMsgPtr &alm) +{ + kbd_net::CMbMessage msg; + msg.setSubject(alm->sub_system, CH_HMI_TO_OPT_OPTCMD_DOWN); + SOptTagSet sOptTagSet; + SOptTagQueue optTagQueue; + COptTagSet cOptTagSet; + + if(createReqHead(sOptTagSet.stHead,alm)!= kbdSuccess) + { + return ; + } + QString keyIdTag = alm->key_id_tag; + if(keyIdTag.endsWith(".value")) + { + //禁止告警和实时数据代码一致,要不实时数据 插件取消告警会失败; + // keyIdTag.replace(QString(".value"),QString(".status")); + }else + { + return ; + } + + optTagQueue.strKeyIdTag = keyIdTag.toStdString(); + optTagQueue.nIsSet = 1;// 0:取消;1:设置; + optTagQueue.fSetValue = 1; + optTagQueue.strStateText = ""; + optTagQueue.bIsPointQuery = false; + optTagQueue.nLocationId = alm->location_id; + optTagQueue.nSubSystem = alm->sub_system; + + sOptTagSet.vecTagQueue.push_back(optTagQueue); + std::string content = cOptTagSet.generate(sOptTagSet); + + msg.setMsgType(MT_OPT_PINHIBIT_ALARM); + + msg.setData(content); + LOGINFO("%s",QString::fromStdString(content).toStdString().c_str()); + if(m_communicator == Q_NULLPTR) + { + QMessageBox::warning(this, tr("提示"), tr("禁止告警失败!"), QMessageBox::Ok); + } + if(!m_communicator->sendMsgToDomain(msg, alm->domain_id)) + { + QMessageBox::warning(this, tr("提示"), tr("禁止告警失败!"), QMessageBox::Ok); + } +} + +bool CAlarmForm::permCheck(int location, int region) +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + int userId; + if(PERM_NORMAL != permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + userId = -1; + return false; + } + std::vector vecRegionOptId; + QList regList; + QList locList; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) + { + + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + regList.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + locList.append(*location++); + } + } + if(locList.contains(location) && regList.contains(region)) + { + return true; + }else + { + QMessageBox::warning(this, tr("警告"), tr("无禁止告警权限!"), QMessageBox::Ok); + return false; + } + } + QMessageBox::warning(this, tr("警告"), tr("初始化权限失败!"), QMessageBox::Ok); + return false; +} + +int CAlarmForm::createReqHead(SOptReqHead &head, const AlarmMsgPtr &alm) +{ + if(!m_ptrSysInfo) + { + if(!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return kbdFailed; + } + } + + int userID = -1; + int usergID = -1; + int level; + int loginSec; + std::string instanceName; + + kbd_service::CPermMngApiPtr permMng = kbd_service::getPermMngInstance("base"); + if(permMng != NULL) + { + if(permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + return kbdFailed; + }else + { + if(PERM_NORMAL != permMng->CurUser(userID, usergID, level, loginSec, instanceName)) + { + userID = -1; + return kbdFailed; + } + } + } + head.strSrcTag = "alarm_window"; + head.nSrcDomainID = m_nDomainId; + head.nDstDomainID = alm->domain_id; + + if(m_ptrSysInfo != Q_NULLPTR) + { + kbd_public::SAppInfo stAppInfo; + m_ptrSysInfo->getAppInfoBySubsystemId(alm->sub_system,stAppInfo); + head.nAppID = stAppInfo.nId; + }else + { + head.nAppID = alm->sub_system; + } + head.strHostName = m_nodeName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = userID; + head.nUserGroupID = usergID; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + return kbdSuccess; +} + +void CAlarmForm::reloadDevTree() +{ + updateAlarmOperatePerm(); + loadDeviceGroupFilterWidget(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmForm.h b/product/src/gui/plugin/AlarmWidget/CAlarmForm.h index 489a811f..25530d2e 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmForm.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmForm.h @@ -1,268 +1,268 @@ -#ifndef CALARMFORM_H -#define CALARMFORM_H - -#include -#include -#include -#include "CAlarmMsgInfo.h" -#include "CAiAlarmMsgInfo.h" -#include -#include -#include "CMyCalendar.h" -#include -#include -#include -#include -#include -#include "dbms/db_api_ex/CDbApi.h" - -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "service/operate_server_api/JsonMessageStruct.h" -#include "service/operate_server_api/JsonOptCommand.h" -#include "common/MessageChannel.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" - -namespace Ui { -class CAlarmForm; -} - -class QLineEdit; -class QPushButton; -class QTreeWidgetItem; -class CAlarmItemModel; -class CAlarmDelegate; -class CAiAlarmDelegate; -class CAlarmDeviceTreeModel; -class CAiAlarmTreeModel; -typedef QList QModelIndexList; - - -class CAlarmForm : public QWidget -{ - Q_OBJECT - -public: - explicit CAlarmForm(QWidget *parent = 0); - ~CAlarmForm(); - - void initialize(); - - void init(); - - void setAlarmModel(CAlarmItemModel * model, CAiAlarmTreeModel *treeModel); - - void setAlarmModel(CAlarmItemModel * model); - void updateView(); - void updateAlarmOperatePerm(); //更新原始告警权限和智能告警操作权限 - - void setAlarmOperateEnable(const bool &bEnable); - - void setColumnWidth(const int &column, const int &width); - - void setColumnVisible(const int &column, const bool &visible); - - void setEnableAccidentReview(bool isNeed); - - void setEnableTrend(bool isNeed); - - void setEnableVideo(bool isNeed); - - void setEnableWave(bool isNeed); - - void setEnableLevel(bool isNeed); - - void setHiddenLocation(bool hide); - - void setHiddenTime(bool hide); - - void setHiddenStatus(bool hide); - - void setHiddenPriority(bool hide); - - void setHiddenCheckBox(bool hide); - - void setHiddenSetConfig(bool hide); - - void setHiddenCloseButton(bool hide); - - void setHiddenInhiAlarmButton(bool hide); - - void setShowAiAlarmView(bool show); - - void setRowHeight(int height); - - void setAccidentReviewPath(const QString& path); - -public: - void initFilter(); - void setLevelComboBox(bool &isLevelFilter,QList &listLevel); - void setLocationComboBox(bool &isLocationFilter,QList &listLocation); - void setAlarmStatusComboBox(bool &isAlarmTypeFilter,QList &listAlarmStatus); - void setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); - void reloadDevTree(); -signals: - void sigAudioCuesEnable(bool bEnable); - - void closeBtnClicked(); - - void printer(QVector header,QList > data,QString fileName,QVector columnHidden,QVector columnWidth); - void printExcel(CAiAlarmTreeModel * model,QString fileName); - void printExcelAlm(CAlarmItemModel * model,QString fileName); - - void openTrend(quint64 time_stamp,QStringList tagList); - void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); - void openAccidentReview(quint64 starTime,quint64 keepTime,QString graph=QString()); -protected slots: - void updateFilter(); - void deviceGroupFilterChanged(const QString &device, const bool &checked); - void slot_changePage(int i); - void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmType, - bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, - QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm,bool isReturnFilter,bool isReturn); - - void slot_removeAlarm(); - void slot_confirmAlarm(); - - void slot_showInhibitAlarm(); - - void slot_showShiledAlarm(); - - void slot_showColorSet(); - void removeInhibitAlarm(QList alarmList); - - void searchDeviceName(); - - void updateRowTips(); - - void print(); - void stateChanged1(int state); - void stateChanged2(int state); - void stateChanged3(int state); - void textChanged1(const QString &text); - void textChanged2(const QString &text); - void textChanged3(const QString &text); - void myCalendarHide(QDate startTime, QDate endTime); - void myCalendarShow(); - void cancleTimeFilter(); - - void aiAlmDoubleClicked(const QModelIndex &index); - - void printMess(QString fileName); - - void slotInhibitDevGroupAlm(const QString &strDevg, int nDomainId, int nLocationId, int nSubsystemId, int nRegionId); - void slotInhibitAlarm(); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - - void contextMenuStack0Event(QContextMenuEvent *event); - - void contextMenuStack1Event(QContextMenuEvent *event); - - void loadDeviceGroupFilterWidget(); - - void updateDeviceGroupHiddenState(); -private: - //原始告警窗点击打印(打印原始告警) - void print0(QString fileName); - //智能告警窗点击打印(打印智能和原始告警) - void print1(QString fileName); - //原始告警窗点击删除(删除原始告警) - void removeAlarm0(); - //智能告警窗点击删除(删除智能告警) - void removeAlarm1(); - //原始告警窗点击确认(确认原始告警) - void confirmAlarm0(); - //智能告警窗点击确认(确认原始告警) - void confirmAlarm1(); - - void rightConfirm0(); - - void rightConfirm1(); - - void rightRemove0(); - - void rightRemove1(); - - void rightMerge1(); - - void rightSepr1(); - - void rightTrend0(); - - void rightTrend1(); - - void rightVideo0(); - - void rightVideo1(); - - void rightFaultRecord0(); - - void rightFaultRecord1(); - - void rightAccidentReview0(); - - void rightAccidentReview1(); - - void test(QStringList tagList); - - void inhibitAlm(const AlarmMsgPtr &alm); - - bool permCheck(int location ,int region); - - int createReqHead(SOptReqHead &head, const AlarmMsgPtr &alm); - -private: - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; - kbd_dbms::CDbApi *m_pReadDb; - - QLineEdit * m_pSearchTextEdit; - QPushButton * m_pSearchButton; - QList m_listRegionOptId; - QList m_listLocationOptId; - - QList m_listRegionDelId; - QList m_listLocationDelId; - bool m_aiOptPerm; //智能告警操作权限 - - CAlarmItemModel * m_pModel; - CAlarmDelegate * m_delegate; - CAiAlarmDelegate * m_aiDelegate; - CAlarmDeviceTreeModel * m_pDeviceModel; - CAiAlarmTreeModel *m_treeModel; - kbd_net::CMbCommunicator *m_communicator; - int m_userId; - std::string m_nodeName; - int m_nDomainId; - - QListWidget *m_pListWidget1; - QListWidget *m_pListWidget2; - QListWidget *m_pListWidget3; - - QLineEdit *m_pLineEdit1; - QLineEdit *m_pLineEdit2; - QLineEdit *m_pLineEdit3; - QList m_priorityList; - QList m_locationList; - QList m_alarmStatusList; - QString m_strText1; - QString m_strText2; - QString m_strText3; - Ui::CAlarmForm *ui; - QPushButton *m_timeIcon; - - CMyCalendar * m_myCalendar; - QMenu *m_timeMenu; - - QThread *m_thread; //打印线程 - CPdfPrinter *m_pdfPrinter; - bool m_isNormal; //是否正常状态 否代表事故追忆状态 - bool m_isNeedAccidentReview; - - bool m_enableAi; - QString m_strAccidenPath; - -}; - -#endif // ALARMFORM_H +#ifndef CALARMFORM_H +#define CALARMFORM_H + +#include +#include +#include +#include "CAlarmMsgInfo.h" +#include "CAiAlarmMsgInfo.h" +#include +#include +#include "CMyCalendar.h" +#include +#include +#include +#include +#include +#include "dbms/db_api_ex/CDbApi.h" + +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "common/MessageChannel.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" + +namespace Ui { +class CAlarmForm; +} + +class QLineEdit; +class QPushButton; +class QTreeWidgetItem; +class CAlarmItemModel; +class CAlarmDelegate; +class CAiAlarmDelegate; +class CAlarmDeviceTreeModel; +class CAiAlarmTreeModel; +typedef QList QModelIndexList; + + +class CAlarmForm : public QWidget +{ + Q_OBJECT + +public: + explicit CAlarmForm(QWidget *parent = 0); + ~CAlarmForm(); + + void initialize(); + + void init(); + + void setAlarmModel(CAlarmItemModel * model, CAiAlarmTreeModel *treeModel); + + void setAlarmModel(CAlarmItemModel * model); + void updateView(); + void updateAlarmOperatePerm(); //更新原始告警权限和智能告警操作权限 + + void setAlarmOperateEnable(const bool &bEnable); + + void setColumnWidth(const int &column, const int &width); + + void setColumnVisible(const int &column, const bool &visible); + + void setEnableAccidentReview(bool isNeed); + + void setEnableTrend(bool isNeed); + + void setEnableVideo(bool isNeed); + + void setEnableWave(bool isNeed); + + void setEnableLevel(bool isNeed); + + void setHiddenLocation(bool hide); + + void setHiddenTime(bool hide); + + void setHiddenStatus(bool hide); + + void setHiddenPriority(bool hide); + + void setHiddenCheckBox(bool hide); + + void setHiddenSetConfig(bool hide); + + void setHiddenCloseButton(bool hide); + + void setHiddenInhiAlarmButton(bool hide); + + void setShowAiAlarmView(bool show); + + void setRowHeight(int height); + + void setAccidentReviewPath(const QString& path); + +public: + void initFilter(); + void setLevelComboBox(bool &isLevelFilter,QList &listLevel); + void setLocationComboBox(bool &isLocationFilter,QList &listLocation); + void setAlarmStatusComboBox(bool &isAlarmTypeFilter,QList &listAlarmStatus); + void setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); + void reloadDevTree(); +signals: + void sigAudioCuesEnable(bool bEnable); + + void closeBtnClicked(); + + void printer(QVector header,QList > data,QString fileName,QVector columnHidden,QVector columnWidth); + void printExcel(CAiAlarmTreeModel * model,QString fileName); + void printExcelAlm(CAlarmItemModel * model,QString fileName); + + void openTrend(quint64 time_stamp,QStringList tagList); + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + void openAccidentReview(quint64 starTime,quint64 keepTime,QString graph=QString()); +protected slots: + void updateFilter(); + void deviceGroupFilterChanged(const QString &device, const bool &checked); + void slot_changePage(int i); + void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmType, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, + QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm,bool isReturnFilter,bool isReturn); + + void slot_removeAlarm(); + void slot_confirmAlarm(); + + void slot_showInhibitAlarm(); + + void slot_showShiledAlarm(); + + void slot_showColorSet(); + void removeInhibitAlarm(QList alarmList); + + void searchDeviceName(); + + void updateRowTips(); + + void print(); + void stateChanged1(int state); + void stateChanged2(int state); + void stateChanged3(int state); + void textChanged1(const QString &text); + void textChanged2(const QString &text); + void textChanged3(const QString &text); + void myCalendarHide(QDate startTime, QDate endTime); + void myCalendarShow(); + void cancleTimeFilter(); + + void aiAlmDoubleClicked(const QModelIndex &index); + + void printMess(QString fileName); + + void slotInhibitDevGroupAlm(const QString &strDevg, int nDomainId, int nLocationId, int nSubsystemId, int nRegionId); + void slotInhibitAlarm(); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + + void contextMenuStack0Event(QContextMenuEvent *event); + + void contextMenuStack1Event(QContextMenuEvent *event); + + void loadDeviceGroupFilterWidget(); + + void updateDeviceGroupHiddenState(); +private: + //原始告警窗点击打印(打印原始告警) + void print0(QString fileName); + //智能告警窗点击打印(打印智能和原始告警) + void print1(QString fileName); + //原始告警窗点击删除(删除原始告警) + void removeAlarm0(); + //智能告警窗点击删除(删除智能告警) + void removeAlarm1(); + //原始告警窗点击确认(确认原始告警) + void confirmAlarm0(); + //智能告警窗点击确认(确认原始告警) + void confirmAlarm1(); + + void rightConfirm0(); + + void rightConfirm1(); + + void rightRemove0(); + + void rightRemove1(); + + void rightMerge1(); + + void rightSepr1(); + + void rightTrend0(); + + void rightTrend1(); + + void rightVideo0(); + + void rightVideo1(); + + void rightFaultRecord0(); + + void rightFaultRecord1(); + + void rightAccidentReview0(); + + void rightAccidentReview1(); + + void test(QStringList tagList); + + void inhibitAlm(const AlarmMsgPtr &alm); + + bool permCheck(int location ,int region); + + int createReqHead(SOptReqHead &head, const AlarmMsgPtr &alm); + +private: + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; + kbd_dbms::CDbApi *m_pReadDb; + + QLineEdit * m_pSearchTextEdit; + QPushButton * m_pSearchButton; + QList m_listRegionOptId; + QList m_listLocationOptId; + + QList m_listRegionDelId; + QList m_listLocationDelId; + bool m_aiOptPerm; //智能告警操作权限 + + CAlarmItemModel * m_pModel; + CAlarmDelegate * m_delegate; + CAiAlarmDelegate * m_aiDelegate; + CAlarmDeviceTreeModel * m_pDeviceModel; + CAiAlarmTreeModel *m_treeModel; + kbd_net::CMbCommunicator *m_communicator; + int m_userId; + std::string m_nodeName; + int m_nDomainId; + + QListWidget *m_pListWidget1; + QListWidget *m_pListWidget2; + QListWidget *m_pListWidget3; + + QLineEdit *m_pLineEdit1; + QLineEdit *m_pLineEdit2; + QLineEdit *m_pLineEdit3; + QList m_priorityList; + QList m_locationList; + QList m_alarmStatusList; + QString m_strText1; + QString m_strText2; + QString m_strText3; + Ui::CAlarmForm *ui; + QPushButton *m_timeIcon; + + CMyCalendar * m_myCalendar; + QMenu *m_timeMenu; + + QThread *m_thread; //打印线程 + CPdfPrinter *m_pdfPrinter; + bool m_isNormal; //是否正常状态 否代表事故追忆状态 + bool m_isNeedAccidentReview; + + bool m_enableAi; + QString m_strAccidenPath; + +}; + +#endif // ALARMFORM_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmForm.ui b/product/src/gui/plugin/AlarmWidget/CAlarmForm.ui index 4efd8fb9..bbceb998 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmForm.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmForm.ui @@ -1,608 +1,608 @@ - - - CAlarmForm - - - - 0 - 0 - 1558 - 631 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - QFrame::Sunken - - - 0 - - - - 0 - - - 9 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 9 - - - 0 - - - 0 - - - - - 6 - - - - - - 100 - 0 - - - - - 100 - 26 - - - - 禁止列表 - - - - - - - - 0 - 0 - - - - - 45 - 0 - - - - - 45 - 26 - - - - 过滤 - - - - - - - - 0 - 0 - - - - - 45 - 0 - - - - - 45 - 26 - - - - 导出 - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 优先级: - - - - - - - - 125 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 位置: - - - - - - - - 113 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 告警状态: - - - - - - - - 138 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 时间: - - - - - - - - 0 - 0 - - - - - 200 - 0 - - - - - 200 - 26 - - - - - - - - 0 - - - 2 - - - 3 - - - - - - 55 - 0 - - - - 0 - - - - - - - 过滤告警数量: - - - - - - - 当前显示数量: - - - - - - - - 55 - 0 - - - - 0 - - - - - - - - - - 80 - 26 - - - - - 16777215 - 26 - - - - 智能告警 - - - true - - - false - - - - - - - Qt::Horizontal - - - - 13 - 20 - - - - - - - - false - - - - 45 - 26 - - - - - - - 确认 - - - - - - - false - - - - 45 - 26 - - - - 删除 - - - - - - - - 45 - 26 - - - - 禁止告警 - - - - - - - - 45 - 26 - - - - 设置 - - - - - - - - 45 - 26 - - - - 关闭 - - - - - - - - - - - - - 0 - 0 - - - - - 300 - 0 - - - - Qt::Horizontal - - - - - 210 - 0 - - - - false - - - - - 1 - - - - - QLayout::SetDefaultConstraint - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 600 - 0 - - - - QFrame::Sunken - - - false - - - false - - - - - - - - - QLayout::SetDefaultConstraint - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::ScrollPerPixel - - - false - - - - - - - - - - - - - - - - CAlarmView - QTableView -
CAlarmView.h
-
- - CAlarmDeviceTreeView - QTreeView -
CAlarmDeviceTreeView.h
-
- - CAiAlarmTreeView - QTreeView -
CAiAlarmTreeView.h
-
-
- - - - updateFilter() - -
+ + + CAlarmForm + + + + 0 + 0 + 1558 + 631 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Sunken + + + 0 + + + + 0 + + + 9 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 9 + + + 0 + + + 0 + + + + + 6 + + + + + + 100 + 0 + + + + + 100 + 26 + + + + 禁止列表 + + + + + + + + 0 + 0 + + + + + 45 + 0 + + + + + 45 + 26 + + + + 过滤 + + + + + + + + 0 + 0 + + + + + 45 + 0 + + + + + 45 + 26 + + + + 导出 + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 优先级: + + + + + + + + 125 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 位置: + + + + + + + + 113 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 告警状态: + + + + + + + + 138 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 时间: + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 26 + + + + + + + + 0 + + + 2 + + + 3 + + + + + + 55 + 0 + + + + 0 + + + + + + + 过滤告警数量: + + + + + + + 当前显示数量: + + + + + + + + 55 + 0 + + + + 0 + + + + + + + + + + 80 + 26 + + + + + 16777215 + 26 + + + + 智能告警 + + + true + + + false + + + + + + + Qt::Horizontal + + + + 13 + 20 + + + + + + + + false + + + + 45 + 26 + + + + + + + 确认 + + + + + + + false + + + + 45 + 26 + + + + 删除 + + + + + + + + 45 + 26 + + + + 禁止告警 + + + + + + + + 45 + 26 + + + + 设置 + + + + + + + + 45 + 26 + + + + 关闭 + + + + + + + + + + + + + 0 + 0 + + + + + 300 + 0 + + + + Qt::Horizontal + + + + + 210 + 0 + + + + false + + + + + 1 + + + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 600 + 0 + + + + QFrame::Sunken + + + false + + + false + + + + + + + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::ScrollPerPixel + + + false + + + + + + + + + + + + + + + + CAlarmView + QTableView +
CAlarmView.h
+
+ + CAlarmDeviceTreeView + QTreeView +
CAlarmDeviceTreeView.h
+
+ + CAiAlarmTreeView + QTreeView +
CAiAlarmTreeView.h
+
+
+ + + + updateFilter() + +
diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.cpp index c7eae171..ecd71d67 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.cpp @@ -1,138 +1,138 @@ -#include "CAlarmInhibitDialog.h" -#include "ui_CAlarmInhibitDialog.h" -#include -#include -#include -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" -#include "CAlarmBaseData.h" - -CAlarmInhibitDialog::CAlarmInhibitDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CAlarmInhibitDialog) -{ - ui->setupUi(this); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - connect(ui->ok, &QPushButton::clicked, this, &CAlarmInhibitDialog::onRemoveInhibit); - connect(ui->cancle, &QPushButton::clicked, [=](){ - reject(); - }); -} - -CAlarmInhibitDialog::~CAlarmInhibitDialog() -{ - delete ui; -} - -void CAlarmInhibitDialog::setInhibitAlarmList(const QList &alarmList) -{ - m_inhibitAlarmList = alarmList; - ui->tableWidget->setRowCount(m_inhibitAlarmList.size()); - ui->tableWidget->setColumnCount(7); - for(int nRow(0); nRow < m_inhibitAlarmList.size(); nRow++) - { - QTableWidgetItem *item; - QString time_stamp = QDateTime::fromMSecsSinceEpoch(m_inhibitAlarmList.at(nRow)->time_stamp).toString("yyyy-MM-dd hh:mm:ss"); - item = new QTableWidgetItem(time_stamp); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 0, item); - - QString priority = CAlarmBaseData::instance()->queryPriorityDesc(m_inhibitAlarmList.at(nRow)->priority); - item = new QTableWidgetItem(priority); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 1, item); - - QString location = CAlarmBaseData::instance()->queryLocationDesc(m_inhibitAlarmList.at(nRow)->location_id); - item = new QTableWidgetItem(location); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 2, item); - - QString region = CAlarmBaseData::instance()->queryRegionDesc(m_inhibitAlarmList.at(nRow)->region_id); - item = new QTableWidgetItem(region); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 3, item); - - QString type = CAlarmBaseData::instance()->queryAlarmTypeDesc(m_inhibitAlarmList.at(nRow)->alm_type); - item = new QTableWidgetItem(type); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 4, item); - - QString state; - if(E_ALS_ALARM == m_inhibitAlarmList.at(nRow)->logic_state || E_ALS_RETURN == m_inhibitAlarmList.at(nRow)->logic_state) //< 未确认 - { - state = tr("未确认"); - } - else - { - state = tr("已确认"); - } - item = new QTableWidgetItem(state); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 5, item); - - item = new QTableWidgetItem(m_inhibitAlarmList.at(nRow)->content); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 6, item); - } - - ui->tableWidget->setColumnWidth(0, 230); - ui->tableWidget->setColumnWidth(1, 100); - ui->tableWidget->setColumnWidth(2, 150); - ui->tableWidget->setColumnWidth(3, 150); - ui->tableWidget->setColumnWidth(4, 120); - ui->tableWidget->setColumnWidth(5, 80); - -} - -void CAlarmInhibitDialog::onRemoveInhibit() -{ - QModelIndexList indexList = ui->tableWidget->selectionModel()->selectedRows(0); - if(indexList.isEmpty()) - { - QMessageBox::information(this, tr("警告"), tr("请选择取消禁止告警所在的行!"), QMessageBox::Ok); - return; - } - std::sort(indexList.begin(), indexList.end()); - QList removedInhibitAlarmList; - for(int nRow(indexList.size() - 1); nRow >= 0; nRow--) - { - removedInhibitAlarmList.append(m_inhibitAlarmList.takeAt(indexList.at(nRow).row())); - ui->tableWidget->removeRow(indexList.at(nRow).row()); - } - emit removeInhibitAlarmList(removedInhibitAlarmList); -} - -void CAlarmInhibitDialog::contextMenuEvent(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - QMenu menu(this); - QAction * InhibitAction = menu.addAction(tr("取消禁止告警")); - connect(InhibitAction, &QAction::triggered,this,&CAlarmInhibitDialog::onRemoveInhibit); - setUpdatesEnabled(false); - menu.exec(QCursor::pos()); - setUpdatesEnabled(true); -} +#include "CAlarmInhibitDialog.h" +#include "ui_CAlarmInhibitDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" +#include "CAlarmBaseData.h" + +CAlarmInhibitDialog::CAlarmInhibitDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmInhibitDialog) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + connect(ui->ok, &QPushButton::clicked, this, &CAlarmInhibitDialog::onRemoveInhibit); + connect(ui->cancle, &QPushButton::clicked, [=](){ + reject(); + }); +} + +CAlarmInhibitDialog::~CAlarmInhibitDialog() +{ + delete ui; +} + +void CAlarmInhibitDialog::setInhibitAlarmList(const QList &alarmList) +{ + m_inhibitAlarmList = alarmList; + ui->tableWidget->setRowCount(m_inhibitAlarmList.size()); + ui->tableWidget->setColumnCount(7); + for(int nRow(0); nRow < m_inhibitAlarmList.size(); nRow++) + { + QTableWidgetItem *item; + QString time_stamp = QDateTime::fromMSecsSinceEpoch(m_inhibitAlarmList.at(nRow)->time_stamp).toString("yyyy-MM-dd hh:mm:ss"); + item = new QTableWidgetItem(time_stamp); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 0, item); + + QString priority = CAlarmBaseData::instance()->queryPriorityDesc(m_inhibitAlarmList.at(nRow)->priority); + item = new QTableWidgetItem(priority); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 1, item); + + QString location = CAlarmBaseData::instance()->queryLocationDesc(m_inhibitAlarmList.at(nRow)->location_id); + item = new QTableWidgetItem(location); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 2, item); + + QString region = CAlarmBaseData::instance()->queryRegionDesc(m_inhibitAlarmList.at(nRow)->region_id); + item = new QTableWidgetItem(region); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 3, item); + + QString type = CAlarmBaseData::instance()->queryAlarmTypeDesc(m_inhibitAlarmList.at(nRow)->alm_type); + item = new QTableWidgetItem(type); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 4, item); + + QString state; + if(E_ALS_ALARM == m_inhibitAlarmList.at(nRow)->logic_state || E_ALS_RETURN == m_inhibitAlarmList.at(nRow)->logic_state) //< 未确认 + { + state = tr("未确认"); + } + else + { + state = tr("已确认"); + } + item = new QTableWidgetItem(state); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 5, item); + + item = new QTableWidgetItem(m_inhibitAlarmList.at(nRow)->content); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 6, item); + } + + ui->tableWidget->setColumnWidth(0, 230); + ui->tableWidget->setColumnWidth(1, 100); + ui->tableWidget->setColumnWidth(2, 150); + ui->tableWidget->setColumnWidth(3, 150); + ui->tableWidget->setColumnWidth(4, 120); + ui->tableWidget->setColumnWidth(5, 80); + +} + +void CAlarmInhibitDialog::onRemoveInhibit() +{ + QModelIndexList indexList = ui->tableWidget->selectionModel()->selectedRows(0); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("警告"), tr("请选择取消禁止告警所在的行!"), QMessageBox::Ok); + return; + } + std::sort(indexList.begin(), indexList.end()); + QList removedInhibitAlarmList; + for(int nRow(indexList.size() - 1); nRow >= 0; nRow--) + { + removedInhibitAlarmList.append(m_inhibitAlarmList.takeAt(indexList.at(nRow).row())); + ui->tableWidget->removeRow(indexList.at(nRow).row()); + } + emit removeInhibitAlarmList(removedInhibitAlarmList); +} + +void CAlarmInhibitDialog::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + QMenu menu(this); + QAction * InhibitAction = menu.addAction(tr("取消禁止告警")); + connect(InhibitAction, &QAction::triggered,this,&CAlarmInhibitDialog::onRemoveInhibit); + setUpdatesEnabled(false); + menu.exec(QCursor::pos()); + setUpdatesEnabled(true); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.h b/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.h index 6cb7908b..764ffd42 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.h @@ -1,36 +1,36 @@ -#ifndef CALARMINHIBITDIALOG_H -#define CALARMINHIBITDIALOG_H - -#include -#include -#include "CAlarmMsgInfo.h" - -namespace Ui { -class CAlarmInhibitDialog; -} - -class CAlarmInhibitDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CAlarmInhibitDialog(QWidget *parent = 0); - ~CAlarmInhibitDialog(); - - void setInhibitAlarmList(const QList &alarmList); - -signals: - void removeInhibitAlarmList(QList alarmList); - -protected slots: - void onRemoveInhibit(); -protected: - void contextMenuEvent(QContextMenuEvent *event); - -private: - Ui::CAlarmInhibitDialog *ui; - - QList m_inhibitAlarmList; -}; - -#endif // CALARMINHIBITDIALOG_H +#ifndef CALARMINHIBITDIALOG_H +#define CALARMINHIBITDIALOG_H + +#include +#include +#include "CAlarmMsgInfo.h" + +namespace Ui { +class CAlarmInhibitDialog; +} + +class CAlarmInhibitDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmInhibitDialog(QWidget *parent = 0); + ~CAlarmInhibitDialog(); + + void setInhibitAlarmList(const QList &alarmList); + +signals: + void removeInhibitAlarmList(QList alarmList); + +protected slots: + void onRemoveInhibit(); +protected: + void contextMenuEvent(QContextMenuEvent *event); + +private: + Ui::CAlarmInhibitDialog *ui; + + QList m_inhibitAlarmList; +}; + +#endif // CALARMINHIBITDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.ui b/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.ui index 3332edb1..22412d53 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmInhibitDialog.ui @@ -1,114 +1,114 @@ - - - CAlarmInhibitDialog - - - - 0 - 0 - 1094 - 433 - - - - 禁止告警列表 - - - - 3 - - - 3 - - - 3 - - - 6 - - - 3 - - - 6 - - - - - 关闭 - - - - - - - 取消禁止告警 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QAbstractItemView::MultiSelection - - - QAbstractItemView::SelectRows - - - true - - - - 时间 - - - - - 优先级 - - - - - 位置 - - - - - 责任区 - - - - - 告警类型 - - - - - 确认状态 - - - - - 告警内容 - - - - - - - - - + + + CAlarmInhibitDialog + + + + 0 + 0 + 1094 + 433 + + + + 禁止告警列表 + + + + 3 + + + 3 + + + 3 + + + 6 + + + 3 + + + 6 + + + + + 关闭 + + + + + + + 取消禁止告警 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QAbstractItemView::MultiSelection + + + QAbstractItemView::SelectRows + + + true + + + + 时间 + + + + + 优先级 + + + + + 位置 + + + + + 责任区 + + + + + 告警类型 + + + + + 确认状态 + + + + + 告警内容 + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.cpp index a0262049..ca31a217 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.cpp @@ -1,859 +1,859 @@ -#include "CAlarmItemModel.h" -#include "CAlarmMsgInfo.h" -#include -#include -#include -#include -#include "CAlarmDataCollect.h" -#include "CAlarmMsgManage.h" -#include "perm_mng_api/PermMngApi.h" -#include -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" -#include "Common.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CharUtil.h" -#include "pub_logger_api/logger.h" -#include -#include -#include -#include "CAlarmBaseData.h" - -///////////////////////////////////////////////////////////////////////////// - -using namespace kbd_public; -using namespace std; -const int DOCK_ROW_COUNT = 3; -const int MAX_ROW_COUNT = 15000; - -CAlarmItemModel::CAlarmItemModel(E_Alarm_Mode mode, QObject *parent) - :QAbstractTableModel(parent), - m_mode(mode), - m_order(Qt::DescendingOrder) -{ - m_nTotalSize = 0; - m_alternateFlag = true; - //增加复归状态 - m_header <)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); - connect(CAlarmDataCollect::instance(), SIGNAL(sigAlarmStateChanged(int, int)), this, SLOT(slotAlarmStateChanged(int, int)), Qt::QueuedConnection); - - connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigMsgRemove,this,&CAlarmItemModel::slotMsgRemove,Qt::QueuedConnection); -} - -CAlarmItemModel::~CAlarmItemModel() -{ - m_listShowAlarmInfo.clear(); -} - -void CAlarmItemModel::initialize() -{ - m_listHorAlignmentFlags.clear(); - for (int nIndex(0); nIndex < m_header.size(); nIndex++) - { - m_listHorAlignmentFlags.append(Qt::AlignHCenter); - } - initFilter(); - - slotMsgRefresh(); -} - -void CAlarmItemModel::initFilter() -{ - m_isLevelFilterEnable = false; - m_isLocationFilterEnable = false; - m_isRegionFilterEnable = false; - m_isStatusFilterEnable = false; - m_isDeviceTypeFileter = false; - m_isKeywordEnable = false; - m_timeFilterEnable = false; - m_confirmFilterEnable = false; - m_returnFilterEnable = false; - if(m_mode != E_Alarm_Pop) - { - removeDeviceGroupFilter(); - } -} - -E_Alarm_Mode CAlarmItemModel::getAlarmMode() const -{ - return m_mode; -} - -int CAlarmItemModel::getShowAlarmCount() const -{ - return m_listShowAlarmInfo.size(); -} - -AlarmMsgPtr CAlarmItemModel::getAlarmInfo(const QModelIndex &index) -{ - if(index.row() < m_listShowAlarmInfo.size()) - { - return m_listShowAlarmInfo.at(index.row()); - } - return AlarmMsgPtr(Q_NULLPTR); -} - -const QList CAlarmItemModel::getListShowAlarmInfo() const -{ - return m_listShowAlarmInfo; -} - -void CAlarmItemModel::setColumnAlign(const int &column, const int &alignFlag) -{ - Qt::AlignmentFlag flag = Qt::AlignHCenter; - if(Qt::AlignLeft == (Qt::AlignmentFlag)alignFlag || Qt::AlignRight == (Qt::AlignmentFlag)alignFlag) - { - flag = (Qt::AlignmentFlag)alignFlag; - } - m_listHorAlignmentFlags.replace(column, flag); -} - -void CAlarmItemModel::insertAlarmMsg(const QList &infoList) -{ - if(infoList.size() > 1000 || E_Alarm_Dock == m_mode) - { - beginResetModel(); - QList::const_iterator itpos = infoList.begin(); - while(itpos != infoList.end()) - { - int left = calcLeft(*itpos); - m_listShowAlarmInfo.insert(left, *itpos); - itpos++; - } - endResetModel(); - }else - { - QList::const_iterator itpos = infoList.begin(); - while(itpos != infoList.end()) - { - int left = calcLeft(*itpos); - beginInsertRows(QModelIndex(), left, left); - m_listShowAlarmInfo.insert(left, *itpos); - endInsertRows(); - itpos++; - } - } -} - -int CAlarmItemModel::calcLeft(const AlarmMsgPtr &info) -{ - int mid = -1; - int left = 0; - int right = m_listShowAlarmInfo.size() - 1; - while(left <= right) - { - mid = (left + right) / 2; - if (Qt::AscendingOrder == m_order) - { - if(info->lessThan(m_listShowAlarmInfo[mid], m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - else - { - if(m_listShowAlarmInfo[mid]->lessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - return left; -} - -bool CAlarmItemModel::alternate() const -{ - return m_alternateFlag; -} - -int CAlarmItemModel::filterCount() -{ - if (0 == m_nTotalSize) - { - return 0; - } - int nCount = m_nTotalSize - m_listShowAlarmInfo.size(); - if( nCount< 0) - { - return 0; - }else - { - return nCount; - } -} - -QVariant CAlarmItemModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(m_header.at(section)); - } - return QVariant(); -} - -QVariant CAlarmItemModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid() || index.row() >= m_listShowAlarmInfo.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == (int)CONTENT) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); - } - - } - else if(Qt::DisplayRole == role) - { - switch ( index.column() ) - { - case TIME : - { - return QDateTime::fromMSecsSinceEpoch(m_listShowAlarmInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - case PRIORITY : - { - return CAlarmBaseData::instance()->queryPriorityDesc(m_listShowAlarmInfo.at(index.row())->priority); - } - case LOCATION : - { - return CAlarmBaseData::instance()->queryLocationDesc(m_listShowAlarmInfo.at(index.row())->location_id); - } - case REGION : - { - return CAlarmBaseData::instance()->queryRegionDesc(m_listShowAlarmInfo.at(index.row())->region_id); - } - case TYPE : - { - return CAlarmBaseData::instance()->queryAlarmTypeDesc(m_listShowAlarmInfo.at(index.row())->alm_type); - } - case STATUS : - { - return CAlarmBaseData::instance()->queryAlarmStatusDesc(m_listShowAlarmInfo.at(index.row())->alm_status); - } - case RETURNSTATUS: - { - if(E_ALS_ALARM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_ALARM_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || - E_ALS_ALARM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_ALARM_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) //未复归 - { - return tr("未复归"); - } - else if(E_ALS_RETURN == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || - E_ALS_RETURN_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) - { - return tr("已复归"); - }else - { - return tr("-"); - } - } - case CONFIRM : - { - if(E_ALS_ALARM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN == m_listShowAlarmInfo.at(index.row())->logic_state || - E_ALS_ALARM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) //< 未确认 - { - return tr("未确认"); - } - else if(E_ALS_ALARM_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || - E_ALS_ALARM_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || - ALS_EVT_ONLY == m_listShowAlarmInfo.at(index.row())->logic_state) //< 已确认 - { - return tr("已确认"); - } - } - case CONTENT : - { - return m_listShowAlarmInfo.at(index.row())->content; - } - default: - break; - } - } - - else if(Qt::ToolTipRole == role) - { - if(index.column() == (int)CONTENT && !QToolTip::isVisible()) - { - QString tip = m_listShowAlarmInfo.at(index.row())->content; - - return tip; - } - } - return QVariant(); -} - -int CAlarmItemModel::columnCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - - return m_header.count(); -} - -int CAlarmItemModel::rowCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - - if(E_Alarm_Dock == m_mode) - { - return DOCK_ROW_COUNT; - } - else - { - return m_listShowAlarmInfo.count(); - } -} - -Qt::ItemFlags CAlarmItemModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CAlarmItemModel::sortColumn(int column, Qt::SortOrder order) -{ - if(order == Qt::AscendingOrder) - { - m_order = Qt::DescendingOrder; - } - else - { - m_order = Qt::AscendingOrder; - } - m_sortKey = (E_ALARM_SORTKEY)column; - beginResetModel(); - sort(); - endResetModel(); -} - -//<归并排序 -void CAlarmItemModel::sort() -{ - QMap mapAlarmInfo; - //<分 - for(int nIndex(0); nIndex < m_listShowAlarmInfo.count(); nIndex++) - { - AlarmMsgPtr temp = m_listShowAlarmInfo.at(nIndex); - mapAlarmInfo[nIndex / 1000].second.append(temp); - } - - //<快速排序 - for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) - { - qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); - } - - PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; - for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) - { - //<归并 - tempListAlarmInfo.first = 0; - mapAlarmInfo[nPairIndex].first = 0; - while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) - { - if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) - { - tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - } - tempListAlarmInfo.first += 1; - } - } - m_listShowAlarmInfo = tempListAlarmInfo.second; -} - - -void CAlarmItemModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CAlarmItemModel::partitionAscendingOrder(QList &list, int start, int last) -{ - AlarmMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftlessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CAlarmItemModel::partitionDescendingOrder(QList &list, int start, int last) -{ - AlarmMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -void CAlarmItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - m_isLevelFilterEnable = isCheck; - m_levelFilter = priorityFilter; - slotMsgRefresh(); -} - -void CAlarmItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) -{ - m_isLocationFilterEnable = isCheck; - m_locationFilter = locationFilter; - slotMsgRefresh(); -} - -void CAlarmItemModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter,bool &other) -{ - m_isStatusFilterEnable = isCheck; - m_statusFilter2 = alarmTypeFilter; - m_statusFilter = alarmTypeFilter; - if(other == true) - { - QMap otherStatusMap = CAlarmBaseData::instance()->getAlarmOtherStatus(); - QMap::iterator it = otherStatusMap.begin(); - for(;it != otherStatusMap.end(); ++it) - { - m_statusFilter.append(it.key()); - } - } - slotMsgRefresh(); -} - -void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) -{ - m_timeFilterEnable = isCheck; - if(isCheck) - { - QTime time_1(0,0,0,0); - QTime time_2(23,59,59,999); - m_startTime.setDate(startTime); - m_startTime.setTime(time_1); - m_endTime.setDate(endTime); - m_endTime.setTime(time_2); - } - slotMsgRefresh(); -} - -void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck) -{ - m_timeFilterEnable = isCheck; - slotMsgRefresh(); -} - -void CAlarmItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isStatusFilterEnable, const QList &statusFilter, - const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, - const bool &isKeywordFilterEnable, const QString &keyword, - const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, - const bool &confirmFilterEnable, const bool &isConfirm, - const bool &returnFilterEnable, const bool &isReturn) -{ - m_isLevelFilterEnable = isLevelFilterEnable; - m_levelFilter = levelFilter; - m_isLocationFilterEnable = isStationFilterEnable; - m_locationFilter = stationFilter; - m_isRegionFilterEnable = isRegionFilterEnable; - m_regionFilter = regionFilter; - m_isStatusFilterEnable = isStatusFilterEnable; - m_statusFilter2 = statusFilter; - m_statusFilter = statusFilter; - if(statusFilter.contains(OTHERSTATUS)) - { - QMap otherStatusMap = CAlarmBaseData::instance()->getAlarmOtherStatus(); - QMap::iterator it = otherStatusMap.begin(); - for(;it != otherStatusMap.end(); ++it) - { - m_statusFilter.append(it.key()); - } - } - m_isDeviceTypeFileter = isDeviceTypeFilter; - m_subSystem = subSystem; - m_deviceType = deviceType; - m_isKeywordEnable = isKeywordFilterEnable; - m_keyowrd = keyword; - m_timeFilterEnable = timeFilterEnable; - m_startTime = startTime; - m_endTime = endTime; - m_confirmFilterEnable = confirmFilterEnable; - m_returnFilterEnable = returnFilterEnable; - m_isConfirm = isConfirm; - m_isReturn = isReturn; - - slotMsgRefresh(); -} - -void CAlarmItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isStatusFilterEnable, QList &alarmStatusFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, - bool &confirmFilterEnable, bool &isConfirm, - bool &returnFilterEnable, bool &isReturn) -{ - isLevelFilterEnable = m_isLevelFilterEnable; - levelFilter = m_levelFilter; - isLocationFilterEnable = m_isLocationFilterEnable; - locationFilter = m_locationFilter; - isRegionFilterEnable = m_isRegionFilterEnable; - regionFilter = m_regionFilter; - isStatusFilterEnable = m_isStatusFilterEnable; - alarmStatusFilter = m_statusFilter2; - subSystem = m_subSystem; - deviceTypeFilter = m_isDeviceTypeFileter; - deviceType = m_deviceType; - keywordFilterEnable = m_isKeywordEnable; - keyword = m_keyowrd; - timeFilterEnable = m_timeFilterEnable; - startTime = m_startTime; - endTime = m_endTime; - confirmFilterEnable = m_confirmFilterEnable; - isConfirm = m_isConfirm; - returnFilterEnable = m_returnFilterEnable; - isReturn = m_isReturn; -} - -void CAlarmItemModel::addDeviceFilter(const QString &device) -{ - m_deviceFilter.insert(device); - //slotMsgRefresh(); -} - -void CAlarmItemModel::removeDeviceFilter(const QString &device) -{ - m_deviceFilter.remove(device); - //slotMsgRefresh(); -} - -void CAlarmItemModel::addPointTagFilter(const QList &pointList) -{ - for(int i =0;igetDevGroupTagList()) - { - m_deviceGroupFilter.insert(group); - } - slotMsgRefresh(); -} - -void CAlarmItemModel::removeDeviceGroupFilter() -{ - m_deviceGroupFilter.clear(); -} - -void CAlarmItemModel::addDeviceGroupFilter(const QString &device) -{ - QString deviceG = device; - QStringList devGList = deviceG.split(","); - foreach (QString devG, devGList) { - m_deviceGroupFilter.insert(devG); - } - slotMsgRefresh(); -} - -void CAlarmItemModel::removeDeviceGroupFilter(const QString &device) -{ - m_deviceGroupFilter.remove(device); - slotMsgRefresh(); -} - -bool CAlarmItemModel::conditionFilter(const AlarmMsgPtr &info) -{ - //===========================错误优先级、车站、责任区、告警类型将显示==============================// - //< 等级 - if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) - { - return false; - } - - //< 车站 - if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) - { - return false; - } - //< 责任区 - if(m_isRegionFilterEnable && !m_regionFilter.contains(info->region_id)) - { - return false; - } - - //< 类型 - if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) - { - return false; - } - - //< 设备类型 - if(m_isDeviceTypeFileter) - { - if(CAlarmBaseData::instance()->queryDevTypeByDesc(m_deviceType) != info->dev_type) - { - return false; - } - } - - //< 点-设备或设备组 - if(E_Alarm_Pop == m_mode) - { - //点标签过滤 - if(info->device.isEmpty() || !m_deviceGroupFilter.contains(info->dev_group_tag)) - { - return false; - } - } - else if(m_deviceGroupFilter.contains(info->dev_group_tag)) - { - return false; - } - - - //< 关键字 - if(m_isKeywordEnable && !info->content.contains(m_keyowrd)) - { - return false; - } - - //< 时间 - if(m_timeFilterEnable) - { - if(m_startTime.toMSecsSinceEpoch() > (qint64)(info->time_stamp)) - { - return false; - } - if(m_endTime.toMSecsSinceEpoch() < (qint64)(info->time_stamp)) - { - return false; - } - } - - //< 是否已确认 - if(m_confirmFilterEnable) - { - if(m_isConfirm) - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) - { - return false; - } - } - else - { - if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM) - { - return false; - } - } - } - if(m_returnFilterEnable) - { - if(m_isReturn) - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_ALARM_CFM || info->logic_state == ALS_EVT_ONLY) - { - return false; - } - } - else - { - if(info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == ALS_EVT_ONLY) - { - return false; - } - } - } - return true; -} - -void CAlarmItemModel::updateAlternate() -{ - m_alternateFlag = !m_alternateFlag; -} - - -void CAlarmItemModel::slotMsgRefresh() -{ - beginResetModel(); - m_listShowAlarmInfo.clear(); - QList listAlarmInfo = CAlarmMsgManage::instance()->getListAlarmInfo(); - foreach (AlarmMsgPtr info, listAlarmInfo) - { - if(conditionFilter(info)) - { - m_listShowAlarmInfo.append(info); - } - } - sort(); - endResetModel(); - slotMsgConfirm(); -} - -void CAlarmItemModel::slotMsgArrived(QList listMsg) -{ - //处理新告警消息 - QList::const_iterator it = listMsg.constBegin(); - QList addMsgList; - while (it != listMsg.constEnd()) - { - if(conditionFilter(*it)) - { - addMsgList.append(*it); - } - ++it; - } - insertAlarmMsg(addMsgList); -} - -void CAlarmItemModel::slotMsgConfirm() -{ - if(E_Alarm_Dock == m_mode) - { - beginResetModel(); - for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) - { - E_ALARM_LOGICSTATE state = m_listShowAlarmInfo.at(nIndex)->logic_state; - if(state == E_ALS_ALARM_CFM || state == E_ALS_RETURN_CFM) - { - m_listShowAlarmInfo.removeAt(nIndex); - } - } - endResetModel(); - } -} - -void CAlarmItemModel::slotMsgRemove(int removeNum) -{ - if(removeNum >1000 || E_Alarm_Dock == m_mode) - { - beginResetModel(); - for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) - { - if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) - { - m_listShowAlarmInfo.removeAt(nIndex); - } - } - endResetModel(); - }else - { - for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) - { - if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) - { - beginRemoveRows(QModelIndex(), nIndex, nIndex); - m_listShowAlarmInfo.removeAt(nIndex); - endRemoveRows(); - } - } - } -} - -void CAlarmItemModel::slotAlarmStateChanged(int total, int unConfirm) -{ - Q_UNUSED(unConfirm) - m_nTotalSize = total; -} +#include "CAlarmItemModel.h" +#include "CAlarmMsgInfo.h" +#include +#include +#include +#include +#include "CAlarmDataCollect.h" +#include "CAlarmMsgManage.h" +#include "perm_mng_api/PermMngApi.h" +#include +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include "CAlarmBaseData.h" + +///////////////////////////////////////////////////////////////////////////// + +using namespace kbd_public; +using namespace std; +const int DOCK_ROW_COUNT = 3; +const int MAX_ROW_COUNT = 15000; + +CAlarmItemModel::CAlarmItemModel(E_Alarm_Mode mode, QObject *parent) + :QAbstractTableModel(parent), + m_mode(mode), + m_order(Qt::DescendingOrder) +{ + m_nTotalSize = 0; + m_alternateFlag = true; + //增加复归状态 + m_header <)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); + connect(CAlarmDataCollect::instance(), SIGNAL(sigAlarmStateChanged(int, int)), this, SLOT(slotAlarmStateChanged(int, int)), Qt::QueuedConnection); + + connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigMsgRemove,this,&CAlarmItemModel::slotMsgRemove,Qt::QueuedConnection); +} + +CAlarmItemModel::~CAlarmItemModel() +{ + m_listShowAlarmInfo.clear(); +} + +void CAlarmItemModel::initialize() +{ + m_listHorAlignmentFlags.clear(); + for (int nIndex(0); nIndex < m_header.size(); nIndex++) + { + m_listHorAlignmentFlags.append(Qt::AlignHCenter); + } + initFilter(); + + slotMsgRefresh(); +} + +void CAlarmItemModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_isLocationFilterEnable = false; + m_isRegionFilterEnable = false; + m_isStatusFilterEnable = false; + m_isDeviceTypeFileter = false; + m_isKeywordEnable = false; + m_timeFilterEnable = false; + m_confirmFilterEnable = false; + m_returnFilterEnable = false; + if(m_mode != E_Alarm_Pop) + { + removeDeviceGroupFilter(); + } +} + +E_Alarm_Mode CAlarmItemModel::getAlarmMode() const +{ + return m_mode; +} + +int CAlarmItemModel::getShowAlarmCount() const +{ + return m_listShowAlarmInfo.size(); +} + +AlarmMsgPtr CAlarmItemModel::getAlarmInfo(const QModelIndex &index) +{ + if(index.row() < m_listShowAlarmInfo.size()) + { + return m_listShowAlarmInfo.at(index.row()); + } + return AlarmMsgPtr(Q_NULLPTR); +} + +const QList CAlarmItemModel::getListShowAlarmInfo() const +{ + return m_listShowAlarmInfo; +} + +void CAlarmItemModel::setColumnAlign(const int &column, const int &alignFlag) +{ + Qt::AlignmentFlag flag = Qt::AlignHCenter; + if(Qt::AlignLeft == (Qt::AlignmentFlag)alignFlag || Qt::AlignRight == (Qt::AlignmentFlag)alignFlag) + { + flag = (Qt::AlignmentFlag)alignFlag; + } + m_listHorAlignmentFlags.replace(column, flag); +} + +void CAlarmItemModel::insertAlarmMsg(const QList &infoList) +{ + if(infoList.size() > 1000 || E_Alarm_Dock == m_mode) + { + beginResetModel(); + QList::const_iterator itpos = infoList.begin(); + while(itpos != infoList.end()) + { + int left = calcLeft(*itpos); + m_listShowAlarmInfo.insert(left, *itpos); + itpos++; + } + endResetModel(); + }else + { + QList::const_iterator itpos = infoList.begin(); + while(itpos != infoList.end()) + { + int left = calcLeft(*itpos); + beginInsertRows(QModelIndex(), left, left); + m_listShowAlarmInfo.insert(left, *itpos); + endInsertRows(); + itpos++; + } + } +} + +int CAlarmItemModel::calcLeft(const AlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_listShowAlarmInfo.size() - 1; + while(left <= right) + { + mid = (left + right) / 2; + if (Qt::AscendingOrder == m_order) + { + if(info->lessThan(m_listShowAlarmInfo[mid], m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + else + { + if(m_listShowAlarmInfo[mid]->lessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + return left; +} + +bool CAlarmItemModel::alternate() const +{ + return m_alternateFlag; +} + +int CAlarmItemModel::filterCount() +{ + if (0 == m_nTotalSize) + { + return 0; + } + int nCount = m_nTotalSize - m_listShowAlarmInfo.size(); + if( nCount< 0) + { + return 0; + }else + { + return nCount; + } +} + +QVariant CAlarmItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +QVariant CAlarmItemModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowAlarmInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == (int)CONTENT) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + } + + } + else if(Qt::DisplayRole == role) + { + switch ( index.column() ) + { + case TIME : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowAlarmInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case PRIORITY : + { + return CAlarmBaseData::instance()->queryPriorityDesc(m_listShowAlarmInfo.at(index.row())->priority); + } + case LOCATION : + { + return CAlarmBaseData::instance()->queryLocationDesc(m_listShowAlarmInfo.at(index.row())->location_id); + } + case REGION : + { + return CAlarmBaseData::instance()->queryRegionDesc(m_listShowAlarmInfo.at(index.row())->region_id); + } + case TYPE : + { + return CAlarmBaseData::instance()->queryAlarmTypeDesc(m_listShowAlarmInfo.at(index.row())->alm_type); + } + case STATUS : + { + return CAlarmBaseData::instance()->queryAlarmStatusDesc(m_listShowAlarmInfo.at(index.row())->alm_status); + } + case RETURNSTATUS: + { + if(E_ALS_ALARM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_ALARM_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || + E_ALS_ALARM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_ALARM_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) //未复归 + { + return tr("未复归"); + } + else if(E_ALS_RETURN == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || + E_ALS_RETURN_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) + { + return tr("已复归"); + }else + { + return tr("-"); + } + } + case CONFIRM : + { + if(E_ALS_ALARM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN == m_listShowAlarmInfo.at(index.row())->logic_state || + E_ALS_ALARM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) //< 未确认 + { + return tr("未确认"); + } + else if(E_ALS_ALARM_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || + E_ALS_ALARM_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || + ALS_EVT_ONLY == m_listShowAlarmInfo.at(index.row())->logic_state) //< 已确认 + { + return tr("已确认"); + } + } + case CONTENT : + { + return m_listShowAlarmInfo.at(index.row())->content; + } + default: + break; + } + } + + else if(Qt::ToolTipRole == role) + { + if(index.column() == (int)CONTENT && !QToolTip::isVisible()) + { + QString tip = m_listShowAlarmInfo.at(index.row())->content; + + return tip; + } + } + return QVariant(); +} + +int CAlarmItemModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return m_header.count(); +} + +int CAlarmItemModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + if(E_Alarm_Dock == m_mode) + { + return DOCK_ROW_COUNT; + } + else + { + return m_listShowAlarmInfo.count(); + } +} + +Qt::ItemFlags CAlarmItemModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CAlarmItemModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + m_sortKey = (E_ALARM_SORTKEY)column; + beginResetModel(); + sort(); + endResetModel(); +} + +//<归并排序 +void CAlarmItemModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_listShowAlarmInfo.count(); nIndex++) + { + AlarmMsgPtr temp = m_listShowAlarmInfo.at(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(temp); + } + + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + m_listShowAlarmInfo = tempListAlarmInfo.second; +} + + +void CAlarmItemModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CAlarmItemModel::partitionAscendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAlarmItemModel::partitionDescendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CAlarmItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + slotMsgRefresh(); +} + +void CAlarmItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter,bool &other) +{ + m_isStatusFilterEnable = isCheck; + m_statusFilter2 = alarmTypeFilter; + m_statusFilter = alarmTypeFilter; + if(other == true) + { + QMap otherStatusMap = CAlarmBaseData::instance()->getAlarmOtherStatus(); + QMap::iterator it = otherStatusMap.begin(); + for(;it != otherStatusMap.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0,0); + QTime time_2(23,59,59,999); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + slotMsgRefresh(); +} + +void CAlarmItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isStatusFilterEnable, const QList &statusFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, + const bool &confirmFilterEnable, const bool &isConfirm, + const bool &returnFilterEnable, const bool &isReturn) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isStatusFilterEnable = isStatusFilterEnable; + m_statusFilter2 = statusFilter; + m_statusFilter = statusFilter; + if(statusFilter.contains(OTHERSTATUS)) + { + QMap otherStatusMap = CAlarmBaseData::instance()->getAlarmOtherStatus(); + QMap::iterator it = otherStatusMap.begin(); + for(;it != otherStatusMap.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyowrd = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + m_confirmFilterEnable = confirmFilterEnable; + m_returnFilterEnable = returnFilterEnable; + m_isConfirm = isConfirm; + m_isReturn = isReturn; + + slotMsgRefresh(); +} + +void CAlarmItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isStatusFilterEnable, QList &alarmStatusFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &confirmFilterEnable, bool &isConfirm, + bool &returnFilterEnable, bool &isReturn) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isStatusFilterEnable = m_isStatusFilterEnable; + alarmStatusFilter = m_statusFilter2; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyowrd; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; + confirmFilterEnable = m_confirmFilterEnable; + isConfirm = m_isConfirm; + returnFilterEnable = m_returnFilterEnable; + isReturn = m_isReturn; +} + +void CAlarmItemModel::addDeviceFilter(const QString &device) +{ + m_deviceFilter.insert(device); + //slotMsgRefresh(); +} + +void CAlarmItemModel::removeDeviceFilter(const QString &device) +{ + m_deviceFilter.remove(device); + //slotMsgRefresh(); +} + +void CAlarmItemModel::addPointTagFilter(const QList &pointList) +{ + for(int i =0;igetDevGroupTagList()) + { + m_deviceGroupFilter.insert(group); + } + slotMsgRefresh(); +} + +void CAlarmItemModel::removeDeviceGroupFilter() +{ + m_deviceGroupFilter.clear(); +} + +void CAlarmItemModel::addDeviceGroupFilter(const QString &device) +{ + QString deviceG = device; + QStringList devGList = deviceG.split(","); + foreach (QString devG, devGList) { + m_deviceGroupFilter.insert(devG); + } + slotMsgRefresh(); +} + +void CAlarmItemModel::removeDeviceGroupFilter(const QString &device) +{ + m_deviceGroupFilter.remove(device); + slotMsgRefresh(); +} + +bool CAlarmItemModel::conditionFilter(const AlarmMsgPtr &info) +{ + //===========================错误优先级、车站、责任区、告警类型将显示==============================// + //< 等级 + if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) + { + return false; + } + + //< 车站 + if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) + { + return false; + } + //< 责任区 + if(m_isRegionFilterEnable && !m_regionFilter.contains(info->region_id)) + { + return false; + } + + //< 类型 + if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { + if(CAlarmBaseData::instance()->queryDevTypeByDesc(m_deviceType) != info->dev_type) + { + return false; + } + } + + //< 点-设备或设备组 + if(E_Alarm_Pop == m_mode) + { + //点标签过滤 + if(info->device.isEmpty() || !m_deviceGroupFilter.contains(info->dev_group_tag)) + { + return false; + } + } + else if(m_deviceGroupFilter.contains(info->dev_group_tag)) + { + return false; + } + + + //< 关键字 + if(m_isKeywordEnable && !info->content.contains(m_keyowrd)) + { + return false; + } + + //< 时间 + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() > (qint64)(info->time_stamp)) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() < (qint64)(info->time_stamp)) + { + return false; + } + } + + //< 是否已确认 + if(m_confirmFilterEnable) + { + if(m_isConfirm) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + return false; + } + } + else + { + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM) + { + return false; + } + } + } + if(m_returnFilterEnable) + { + if(m_isReturn) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_ALARM_CFM || info->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + else + { + if(info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + } + return true; +} + +void CAlarmItemModel::updateAlternate() +{ + m_alternateFlag = !m_alternateFlag; +} + + +void CAlarmItemModel::slotMsgRefresh() +{ + beginResetModel(); + m_listShowAlarmInfo.clear(); + QList listAlarmInfo = CAlarmMsgManage::instance()->getListAlarmInfo(); + foreach (AlarmMsgPtr info, listAlarmInfo) + { + if(conditionFilter(info)) + { + m_listShowAlarmInfo.append(info); + } + } + sort(); + endResetModel(); + slotMsgConfirm(); +} + +void CAlarmItemModel::slotMsgArrived(QList listMsg) +{ + //处理新告警消息 + QList::const_iterator it = listMsg.constBegin(); + QList addMsgList; + while (it != listMsg.constEnd()) + { + if(conditionFilter(*it)) + { + addMsgList.append(*it); + } + ++it; + } + insertAlarmMsg(addMsgList); +} + +void CAlarmItemModel::slotMsgConfirm() +{ + if(E_Alarm_Dock == m_mode) + { + beginResetModel(); + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + E_ALARM_LOGICSTATE state = m_listShowAlarmInfo.at(nIndex)->logic_state; + if(state == E_ALS_ALARM_CFM || state == E_ALS_RETURN_CFM) + { + m_listShowAlarmInfo.removeAt(nIndex); + } + } + endResetModel(); + } +} + +void CAlarmItemModel::slotMsgRemove(int removeNum) +{ + if(removeNum >1000 || E_Alarm_Dock == m_mode) + { + beginResetModel(); + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) + { + m_listShowAlarmInfo.removeAt(nIndex); + } + } + endResetModel(); + }else + { + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) + { + beginRemoveRows(QModelIndex(), nIndex, nIndex); + m_listShowAlarmInfo.removeAt(nIndex); + endRemoveRows(); + } + } + } +} + +void CAlarmItemModel::slotAlarmStateChanged(int total, int unConfirm) +{ + Q_UNUSED(unConfirm) + m_nTotalSize = total; +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.h b/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.h index e81ca48b..94f6ffa0 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.h @@ -1,192 +1,192 @@ -#ifndef CALARMITEMMODEL_H -#define CALARMITEMMODEL_H - -#include -#include -#include -#include -#include "CAlarmMsgInfo.h" -#include "CAlarmCommon.h" -extern const int DOCK_ROW_COUNT; -extern const int MAX_ROW_COUNT; - - - -class CAlarmView; -class CAlarmMsgInfo; - -class CAlarmItemModel : public QAbstractTableModel -{ - Q_OBJECT -public: - - enum ColumnField - { - TIME = 0, - PRIORITY, - LOCATION, - REGION, - TYPE, - STATUS, - RETURNSTATUS, - CONFIRM, - CONTENT - }; - - CAlarmItemModel(E_Alarm_Mode mode, QObject *parent = Q_NULLPTR); - ~CAlarmItemModel(); - - void initialize(); - - void initFilter(); - - E_Alarm_Mode getAlarmMode() const; - - int getShowAlarmCount() const; - - AlarmMsgPtr getAlarmInfo(const QModelIndex &index); - - const QList getListShowAlarmInfo() const; - - - void setColumnAlign(const int &column, const int &alignFlag); - - /** - * @brief insertAlarmMsg 数采通知模型告警到达 - * @param info - */ - void insertAlarmMsg(const QList & infoList); - - int calcLeft(const AlarmMsgPtr &info); - /** - * @brief alternate 闪烁状态切换 - * @return - */ - bool alternate() const; - - int filterCount(); - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual int columnCount(const QModelIndex &index = QModelIndex()) const; - virtual int rowCount(const QModelIndex &index = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - - void sort(); - void qucikSort(QList &listAlarmInfo, int left, int right); - int partitionAscendingOrder(QList &list, int start, int last); - int partitionDescendingOrder(QList &list, int start, int last); - - void setPriorityFilter(bool &isCheck, QList &priorityFilter); - void setLocationFilter(bool &isCheck, QList &locationFilter); - void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other); - void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); - void setAlarmTimeFilter(bool &isCheck); - /** - * 设置模型数据过滤条件,过滤显示数据 - */ - void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isStatusFilterEnable, const QList &statusFilter, - const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), - const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), - const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), - const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false,const bool &returnFilterEnable = false, const bool &isReturn= false); - - /** - * 获取模型数据过滤条件,用于初始化过滤对话框 - */ - void getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isStatusFilterEnable, QList &alarmStatusFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, - bool &confirmFilterEnable, bool &isConfirm, - bool &returnFilterEnable, bool &isReturn); - - - void addDeviceFilter(const QString &device); - void removeDeviceFilter(const QString &device); - - void addPointTagFilter(const QList &pointList); - void addDeviceGroupFilter(); - void removeDeviceGroupFilter(); - void addDeviceGroupFilter(const QString &device); - void removeDeviceGroupFilter(const QString &device); - - bool conditionFilter(const AlarmMsgPtr &info); - - void updateAlternate(); - -public slots: - void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); - - /** - * @brief slotMsgRefresh 更新model,重新拉取数据 - */ - void slotMsgRefresh(); - -private slots: - /** - * @brief slotMsgArrived 告警消息到达 - * @param info - */ - void slotMsgArrived(QList listMsg); - - /** - * @brief slotMsgConfirm 告警消息确认 - */ - void slotMsgConfirm(); - - /** - * @brief slotMsgArrived 告警消息删除 - */ - void slotMsgRemove(int removeNum); - - void slotAlarmStateChanged(int total, int unConfirm); - -private: - E_Alarm_Mode m_mode; - QStringList m_header; - QList m_listShowAlarmInfo; - bool m_alternateFlag; //闪烁颜色切换 - E_ALARM_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - - int m_nTotalSize; - - QList m_listHorAlignmentFlags; //< 水平对齐方式 - - //< Filter - bool m_isLevelFilterEnable; //是否按告警级别过滤 - QList m_levelFilter; //告警级别过滤 - bool m_isLocationFilterEnable; //是否按车站过滤 - QList m_locationFilter; //车站过滤 - bool m_isRegionFilterEnable; //是否按责任区过滤 - QList m_regionFilter; //责任区过滤 - bool m_isStatusFilterEnable; //是否按告警类型过滤 - QList m_statusFilter; //告警类型过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) - QList m_statusFilter2; //告警类型过滤(显示在过滤窗中的告警状态) - bool m_isDeviceTypeFileter; //设备类型过滤 - QString m_subSystem; //子系统 - QString m_deviceType; //设备类型 - bool m_isKeywordEnable; //关键字过滤 - QString m_keyowrd; //关键字 - bool m_timeFilterEnable; //是否根据时间过滤 - QDateTime m_startTime; //起始时间 - QDateTime m_endTime; //终止时间 - bool m_confirmFilterEnable; //是否根据状态确认过滤 - bool m_isConfirm; //状态是否确认 - - bool m_returnFilterEnable; //是否根据复归状态过滤 - bool m_isReturn; //是否已复归 - - QSet m_deviceFilter; //< 设备过滤 - QSet m_pointFilter; //标签过滤 - QSet m_deviceGroupFilter; //<设备组过滤 -}; - -#endif // ALARMITEMMODEL_H +#ifndef CALARMITEMMODEL_H +#define CALARMITEMMODEL_H + +#include +#include +#include +#include +#include "CAlarmMsgInfo.h" +#include "CAlarmCommon.h" +extern const int DOCK_ROW_COUNT; +extern const int MAX_ROW_COUNT; + + + +class CAlarmView; +class CAlarmMsgInfo; + +class CAlarmItemModel : public QAbstractTableModel +{ + Q_OBJECT +public: + + enum ColumnField + { + TIME = 0, + PRIORITY, + LOCATION, + REGION, + TYPE, + STATUS, + RETURNSTATUS, + CONFIRM, + CONTENT + }; + + CAlarmItemModel(E_Alarm_Mode mode, QObject *parent = Q_NULLPTR); + ~CAlarmItemModel(); + + void initialize(); + + void initFilter(); + + E_Alarm_Mode getAlarmMode() const; + + int getShowAlarmCount() const; + + AlarmMsgPtr getAlarmInfo(const QModelIndex &index); + + const QList getListShowAlarmInfo() const; + + + void setColumnAlign(const int &column, const int &alignFlag); + + /** + * @brief insertAlarmMsg 数采通知模型告警到达 + * @param info + */ + void insertAlarmMsg(const QList & infoList); + + int calcLeft(const AlarmMsgPtr &info); + /** + * @brief alternate 闪烁状态切换 + * @return + */ + bool alternate() const; + + int filterCount(); + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + void sort(); + void qucikSort(QList &listAlarmInfo, int left, int right); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other); + void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); + void setAlarmTimeFilter(bool &isCheck); + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isStatusFilterEnable, const QList &statusFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false,const bool &returnFilterEnable = false, const bool &isReturn= false); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isStatusFilterEnable, QList &alarmStatusFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &confirmFilterEnable, bool &isConfirm, + bool &returnFilterEnable, bool &isReturn); + + + void addDeviceFilter(const QString &device); + void removeDeviceFilter(const QString &device); + + void addPointTagFilter(const QList &pointList); + void addDeviceGroupFilter(); + void removeDeviceGroupFilter(); + void addDeviceGroupFilter(const QString &device); + void removeDeviceGroupFilter(const QString &device); + + bool conditionFilter(const AlarmMsgPtr &info); + + void updateAlternate(); + +public slots: + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + + /** + * @brief slotMsgRefresh 更新model,重新拉取数据 + */ + void slotMsgRefresh(); + +private slots: + /** + * @brief slotMsgArrived 告警消息到达 + * @param info + */ + void slotMsgArrived(QList listMsg); + + /** + * @brief slotMsgConfirm 告警消息确认 + */ + void slotMsgConfirm(); + + /** + * @brief slotMsgArrived 告警消息删除 + */ + void slotMsgRemove(int removeNum); + + void slotAlarmStateChanged(int total, int unConfirm); + +private: + E_Alarm_Mode m_mode; + QStringList m_header; + QList m_listShowAlarmInfo; + bool m_alternateFlag; //闪烁颜色切换 + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + int m_nTotalSize; + + QList m_listHorAlignmentFlags; //< 水平对齐方式 + + //< Filter + bool m_isLevelFilterEnable; //是否按告警级别过滤 + QList m_levelFilter; //告警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isStatusFilterEnable; //是否按告警类型过滤 + QList m_statusFilter; //告警类型过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) + QList m_statusFilter2; //告警类型过滤(显示在过滤窗中的告警状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyowrd; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + bool m_confirmFilterEnable; //是否根据状态确认过滤 + bool m_isConfirm; //状态是否确认 + + bool m_returnFilterEnable; //是否根据复归状态过滤 + bool m_isReturn; //是否已复归 + + QSet m_deviceFilter; //< 设备过滤 + QSet m_pointFilter; //标签过滤 + QSet m_deviceGroupFilter; //<设备组过滤 +}; + +#endif // ALARMITEMMODEL_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.cpp index 546987a0..ceb5b378 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.cpp @@ -1,644 +1,644 @@ - -#ifdef OS_WINDOWS -//< 为了检测可用声卡 -#include -#include -#endif - -#include -#include -#include -#include -#include "CAlarmMediaPlayer.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_logger_api/logger.h" -#include "pub_utility_api/I18N.h" -#include "CAlarmSetMng.h" -#include "service/alarm_server_api/AlarmCommonDef.h" -#include "CAlarmMsgManage.h" -#include -#include -#include -#include -#include - -using namespace kbd_public; -CAlarmMediaPlayer * CAlarmMediaPlayer::m_pInstance = NULL; -CAlarmMediaPlayer *CAlarmMediaPlayer::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CAlarmMediaPlayer(); - } - return m_pInstance; -} - -CAlarmMediaPlayer::CAlarmMediaPlayer() - :m_bHaveValidAudioDev(true),m_pMediaPlayer(Q_NULLPTR),m_pTextToSpeech(Q_NULLPTR),m_pTimerCheckAudioDev(Q_NULLPTR),m_voice(100) -{ - m_readFlag = true; - QDir dir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - dir.cd("sound"); - initSetCfg(); - m_strMediaPath = dir.absolutePath() + QDir::separator(); - m_bChange = true; - m_pTimerCheckAudioDev = new QTimer(); - m_pTimerCheckAudioDev->setInterval(5000); - connect(m_pTimerCheckAudioDev, SIGNAL(timeout()), this, SLOT(checkAudioDev()),Qt::QueuedConnection); - m_pTimerCheckAudioStatus = new QTimer(); - m_pTimerCheckAudioStatus->setInterval(30000); - connect(m_pTimerCheckAudioStatus,&QTimer::timeout, this, &CAlarmMediaPlayer::checkAudioStatus,Qt::QueuedConnection); - checkAudioDev(); - checkAudioStatus(); - m_pTimerCheckAudioDev->start(); - m_pTimerCheckAudioStatus->start(); - - //< 需在checkAudioDev()之后调用 - - if(m_act == (int)E_ALARM_SOUND) - { - initPlayer(); - }else - { - initSpeech(); - } -} - -void CAlarmMediaPlayer::updateAudioCues() -{ - if(m_act == (int)E_ALARM_SOUND) - { - updateAudioCuesPlayer(); - }else - { - updateAudioCuesSpeech(); - } -} - -CAlarmMediaPlayer::~CAlarmMediaPlayer() -{ - if(Q_NULLPTR != m_pTimerCheckAudioDev) - { - m_pTimerCheckAudioDev->stop(); - m_pTimerCheckAudioDev->deleteLater(); - } - m_pTimerCheckAudioDev = NULL; - if(Q_NULLPTR != m_pTimerCheckAudioStatus) - { - m_pTimerCheckAudioStatus->stop(); - m_pTimerCheckAudioStatus->deleteLater(); - } - m_pTimerCheckAudioStatus = NULL; - if(Q_NULLPTR != m_pMediaPlayer) - { - if(QMediaPlayer::StoppedState != m_pMediaPlayer->state()) - { - m_pMediaPlayer->disconnect(); - m_pMediaPlayer->stop(); - } - delete m_pMediaPlayer; - } - m_pMediaPlayer = Q_NULLPTR; - - if(Q_NULLPTR != m_pTextToSpeech) - { - if(QTextToSpeech::Ready != m_pTextToSpeech->state()) - { - m_pTextToSpeech->disconnect(); - m_pTextToSpeech->stop(); - } - delete m_pTextToSpeech; - } - m_pTextToSpeech = Q_NULLPTR; - delete m_pInstance; - m_pInstance = Q_NULLPTR; -} - -void CAlarmMediaPlayer::initPlayer() -{ - if(Q_NULLPTR != m_pMediaPlayer) - { - return; - } - m_pMediaPlayer = new QMediaPlayer(); - m_pMediaPlayer->setVolume(m_voice); - connect(m_pMediaPlayer, &QMediaPlayer::stateChanged, this, &CAlarmMediaPlayer::playerStateChanged,Qt::QueuedConnection); - connect(m_pMediaPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(printError(QMediaPlayer::Error)),Qt::QueuedConnection); - - QMediaPlaylist *pPlayList = new QMediaPlaylist(this); - pPlayList->setPlaybackMode(QMediaPlaylist::Sequential); - pPlayList->clear(); - m_pMediaPlayer->setPlaylist(pPlayList); -} - -void CAlarmMediaPlayer::initSpeech() -{ - if(Q_NULLPTR != m_pTextToSpeech) - { - return; - } - - QStringList engineList = QTextToSpeech::availableEngines(); - - if(engineList.isEmpty()) - { - return ; - } - if(m_engine.isEmpty() || !engineList.contains(m_engine)) - { -#ifdef OS_LINUX - m_pTextToSpeech = Q_NULLPTR; - return; -#else - m_pTextToSpeech = new QTextToSpeech(this); -#endif - }else - { - m_pTextToSpeech = new QTextToSpeech(m_engine,this); - } - m_pTextToSpeech->setVolume(m_voice); - connect(m_pTextToSpeech, &QTextToSpeech::stateChanged, this, &CAlarmMediaPlayer::speechStateChanged,Qt::QueuedConnection); - QVector locales = m_pTextToSpeech->availableLocales(); - if(!m_language.isEmpty()) - { - foreach (const QLocale &locale, locales) { - if (locale.name() == m_language) - { - m_pTextToSpeech->setLocale(locale); - break; - } - } - } - QVector voices = m_pTextToSpeech->availableVoices(); - if(!m_voiceName.isEmpty()) - { - foreach (const QVoice &voice, voices) { - if (voice.name() == m_voiceName) - { - m_pTextToSpeech->setVoice(voice); - break; - } - } - } - //添加语音转文本处理条件 - QFile file(kbd_public::CFileUtil::getPathOfCfgFile("alarmSpeechTextTrans.xml" , CN_DIR_PRODUCT).c_str()); - if (!file.open(QFile::ReadWrite)) - { - LOGERROR("打开语音文本转换文件失败,默认不进行语音转换"); - return; - } - - QDomDocument doc; - if (!doc.setContent(&file)) - { - file.close(); - LOGERROR("打开语音文本转换文件失败,默认不进行语音转换"); - return; - } - file.close(); - - QDomElement root = doc.documentElement(); - if(root.isElement()) - { - QDomNodeList nodeList = root.childNodes(); - for(int i = 0 ; i < nodeList.count() ; i++) - { - QDomNode node = nodeList.at(i); - if(node.isElement()) - { - QDomElement element = node.toElement(); - if(element.tagName() == "Condition" && element.attribute("enable") == "true") - { - m_mapSpeechTxtTrans.insert(element.attribute("key"),element.attribute("value")); - } - } - } - } - -} - -void CAlarmMediaPlayer::initSetCfg() -{ - CAlarmSetMng::instance()->getActAndNum(m_act,m_num,m_style); - CAlarmSetMng::instance()->getEngine(m_engine,m_language,m_voiceName); - LOGDEBUG("获取当前语音引擎:%s-%s-%s",m_engine.toStdString().c_str(),m_language.toStdString().c_str(),m_voiceName.toStdString().c_str()); -} - -void CAlarmMediaPlayer::removeAudioCuesStop() -{ - if(m_act == (int)E_ALARM_SOUND) - { - if(m_pMediaPlayer != NULL) - { - m_pMediaPlayer->stop(); - } - }else - { - if(m_pTextToSpeech != NULL) - { - m_pTextToSpeech->stop(); - emit m_pTextToSpeech->stateChanged(m_pTextToSpeech->state()); - } - } -} - -void CAlarmMediaPlayer::insertAudioCuesStop(const AlarmMsgPtr &info) -{ - if(m_act == (int)E_ALARM_SOUND && ALM_ACT_SOUND == (info->m_alarmAction & ALM_ACT_SOUND)) - { - if(m_pMediaPlayer != NULL) - { - m_pMediaPlayer->stop(); - } - }else if(m_act == (int)E_ALARM_VOICE && ALM_ACT_VOICE == (info->m_alarmAction & ALM_ACT_VOICE)) - { - if(m_pTextToSpeech != NULL) - { - m_pTextToSpeech->stop(); - emit m_pTextToSpeech->stateChanged(m_pTextToSpeech->state()); - } - } -} - -void CAlarmMediaPlayer::speechTextTrans(QString &strContent) -{ -// strContent = "110KV回路503弹簧开关10A保护A线"; - //文本转换处理 - auto iter = m_mapSpeechTxtTrans.begin(); - for(;iter != m_mapSpeechTxtTrans.end() ; iter++) - { - strContent.replace(QRegExp(iter.key() , Qt::CaseInsensitive) , iter.value()); - } -} - -void CAlarmMediaPlayer::setVolumeEnable(bool bEnable) -{ - if(bEnable) - { - m_voice = 100; - if(m_pMediaPlayer != Q_NULLPTR) - { - m_pMediaPlayer->setVolume(m_voice); - } - - if(m_pTextToSpeech != Q_NULLPTR) - { - m_pTextToSpeech->setVolume(m_voice); - } - - } - else - { - m_voice = 0; - if(m_pMediaPlayer != Q_NULLPTR) - { - m_pMediaPlayer->setVolume(m_voice); - } - - if(m_pTextToSpeech != Q_NULLPTR) - { - m_pTextToSpeech->setVolume(m_voice); - } - } -} - -void CAlarmMediaPlayer::release() -{ - LOGINFO("CAlarmMediaPlayer::release()"); - if(m_pMediaPlayer) - { - m_pMediaPlayer->stop(); - } - if(m_pTextToSpeech) - { - m_pTextToSpeech->stop(); - } -} - -void CAlarmMediaPlayer::destory() -{ - if(m_pMediaPlayer) - { - m_pMediaPlayer->disconnect(); - m_pMediaPlayer->stop(); - } - if(m_pTextToSpeech) - { - m_pTextToSpeech->disconnect(); - m_pTextToSpeech->stop(); - } - m_pInstance = NULL; - deleteLater(); -} - -void CAlarmMediaPlayer::slotLoadConfig() -{ - LOGINFO("CAlarmMediaPlayer::slotLoadConfig()"); - if(m_pMediaPlayer) - { - m_pMediaPlayer->disconnect(); - m_pMediaPlayer->stop(); - delete m_pMediaPlayer; - m_pMediaPlayer = Q_NULLPTR; - } - if(m_pTextToSpeech) - { - m_pTextToSpeech->disconnect(); - m_pTextToSpeech->stop(); - delete m_pTextToSpeech; - m_pTextToSpeech = Q_NULLPTR; - } - initSetCfg(); - - - if(m_act == (int)E_ALARM_SOUND) - { - initPlayer(); - updateAudioCuesPlayer(); - }else - { - initSpeech(); - updateAudioCuesSpeech(); - } -} - -void CAlarmMediaPlayer::slotReadFlag() -{ - LOGDEBUG("slotReadFlag"); - m_readFlag = true; - - if(m_style != E_STYLE_NO_ALARM) - { - updateAudioCues(); - } -} - -void CAlarmMediaPlayer::playerStateChanged(QMediaPlayer::State state) -{ - if(m_act != (int)E_ALARM_SOUND) - { - return ; - } - m_bChange = true; - if(state == QMediaPlayer::StoppedState) - { - updateAudioCuesPlayer(); - } -} - -void CAlarmMediaPlayer::speechStateChanged(QTextToSpeech::State state) -{ - if(m_act != (int)E_ALARM_VOICE) - { - return ; - } - if(state == QTextToSpeech::Ready) - { - updateAudioCuesSpeech(); - } -} - -void CAlarmMediaPlayer::updateAudioCuesPlayer() -{ - if(!m_bHaveValidAudioDev || !m_pMediaPlayer || !m_readFlag || m_pMediaPlayer->state() != QMediaPlayer::StoppedState) - { - LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesPlayer(),return"); - return; - } - AlarmMsgPtr info; - if(m_style == E_STYLE_REPEAT) - { - info = CAlarmMsgManage::instance()->getOnePlayerAlm(-1); - } - else if(m_style == E_STYLE_REPEAT_X) - { - info = CAlarmMsgManage::instance()->getOnePlayerAlm(m_num); - } - if(info == Q_NULLPTR) - { - m_readFlag = false; - return ; - } - QStringList strAudioFileNames = info->sound_file; - - m_pMediaPlayer->playlist()->clear(); - foreach (QString fileName, strAudioFileNames) - { - if(!fileName.isEmpty()) - { - fileName = m_strMediaPath + fileName; - if(QFile::exists(fileName)) - { - m_pMediaPlayer->playlist()->addMedia(QUrl::fromLocalFile(fileName)); - } - } - } - if(!m_pMediaPlayer->playlist()->isEmpty()) - { - m_pMediaPlayer->play(); - } -} - -void CAlarmMediaPlayer::updateAudioCuesSpeech() -{ - if(!m_bHaveValidAudioDev || !m_pTextToSpeech || !m_readFlag || m_pTextToSpeech->state() != QTextToSpeech::Ready) - { - LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesSpeech(),return"); - return; - } - AlarmMsgPtr info; - if(m_style == E_STYLE_REPEAT) - { - info = CAlarmMsgManage::instance()->getOneSpeechAlm(-1); - } - else if(m_style == E_STYLE_REPEAT_X) - { - info = CAlarmMsgManage::instance()->getOneSpeechAlm(m_num); - } - if(info == Q_NULLPTR) - { - m_readFlag = false; - return ; - } - QString alarmContent = info->content; - - if(!alarmContent.isEmpty()) - { - //读取配置文件,更改读取方式 - speechTextTrans(alarmContent); - m_pTextToSpeech->say(alarmContent); - } -} - -void CAlarmMediaPlayer::printError(QMediaPlayer::Error error) -{ - if(m_pMediaPlayer) - { - LOGERROR("QMediaPlayer error == %d , errorString : %s",error,m_pMediaPlayer->errorString().toStdString().c_str()); - } -} - -void CAlarmMediaPlayer::checkAudioDev() -{ - //< 周期性检测音频设备有效性,因为: - //< 1、声卡是可以热拔插的,比如USB声卡 - //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 - - bool bHaveValidDev = false; - - //< 注意:在win系统,qt5.9.9以及5.12.9上测试,下面使用QAudioDeviceInfo检测的方法,本身会导致内存上涨 - { - // //< 测试结果:无论windows audio服务是否启动,defaultOutputDevice看上去都是对的,所以,不能用这个判断是否有效 - - // QList listDev(QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)); - - // //< 不能仅仅检测列表是否为空,还需要检测有效性 - // //< 当有声卡硬件,但是Windows Audio服务未启动时,设备列表不为空,但如果播放依然可能导致内存上涨问题 - // foreach (QAudioDeviceInfo objDev, listDev) - // { - // //< 当Window Audio服务未启动时,无法获取有效的格式信息,以此判断 - // if(objDev.preferredFormat().isValid()) - // { - // bHaveValidDev = true; - // break; - // } - // } - } - - //< 不得已,使用win系统原生API条件编译 -#ifdef OS_WINDOWS - { - //< 获取系统默认主设备的音量,如果成功则至少说明: - //< 1、有声卡; 2、Windows Audio服务正常 - - CoInitialize(NULL); - IMMDeviceEnumerator *pDevEnumerator = NULL; - CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDevEnumerator); - - if(NULL != pDevEnumerator) - { - IMMDevice *pDefaultDev = NULL; - pDevEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDefaultDev); - - pDevEnumerator->Release(); - pDevEnumerator = NULL; - - if(NULL != pDefaultDev) - { - IAudioEndpointVolume *pEndpointVol = NULL; - pDefaultDev->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&pEndpointVol); - - pDefaultDev->Release(); - pDefaultDev = NULL; - - if(NULL != pEndpointVol) - { - float fVol; - const HRESULT nResult = pEndpointVol->GetMasterVolumeLevelScalar(&fVol); - if(S_OK == nResult) - bHaveValidDev = true; - - pEndpointVol->Release(); - pEndpointVol = NULL; - } - } - } - - CoUninitialize(); - } -#else - //< 在Linux系统下测试,即使没有声卡也未见问题,暂时不做检测 - bHaveValidDev = true; -#endif - if(m_act == (int)E_ALARM_SOUND) // - { - if(m_bHaveValidAudioDev && !bHaveValidDev) - { - LOGERROR("No valid audio output device !"); - m_bHaveValidAudioDev = false; - if(m_pMediaPlayer != Q_NULLPTR) - { - m_pMediaPlayer->disconnect(); - m_pMediaPlayer->stop(); - delete m_pMediaPlayer; - m_pMediaPlayer = Q_NULLPTR; - } - } - else if(!m_bHaveValidAudioDev && bHaveValidDev) - { - LOGINFO("Valid audio output device detected !"); - - //< 不重新构造可能不能正常播放 - if(m_pMediaPlayer) - { - m_pMediaPlayer->disconnect(); - delete m_pMediaPlayer; - m_pMediaPlayer = Q_NULLPTR; - } - - m_bHaveValidAudioDev = true; - initPlayer(); - updateAudioCuesPlayer(); - } - }else - { - if(m_bHaveValidAudioDev && !bHaveValidDev) - { - LOGERROR("No valid audio output device !"); - m_bHaveValidAudioDev = false; - if(m_pTextToSpeech != Q_NULLPTR) - { - m_pTextToSpeech->disconnect(); - m_pTextToSpeech->stop(); - delete m_pTextToSpeech; - m_pTextToSpeech = Q_NULLPTR; - } - } - else if(!m_bHaveValidAudioDev && bHaveValidDev) - { - LOGINFO("Valid audio output device detected !"); - - //< 不重新构造可能不能正常播放 - if(m_pTextToSpeech) - { - m_pTextToSpeech->disconnect(); - m_pTextToSpeech->stop(); - delete m_pTextToSpeech; - m_pTextToSpeech = Q_NULLPTR; - } - m_bHaveValidAudioDev = true; - initSpeech(); - updateAudioCuesSpeech(); - } - } -} -//因QMediaPlayer自身bug问题 此处只检测QMediaPlayer -void CAlarmMediaPlayer::checkAudioStatus() -{ - if(!m_readFlag) - { - return ; - } - if(m_act == (int)E_ALARM_VOICE) //语音告警无需检测 - { - return ; - } - if(!m_bChange) - { - //< 不重新构造可能不能正常播放 - if(m_pMediaPlayer) - { - m_pMediaPlayer->disconnect(); - m_pMediaPlayer->stop(); - delete m_pMediaPlayer; - m_pMediaPlayer = Q_NULLPTR; - } - m_bHaveValidAudioDev = true; - initPlayer(); - updateAudioCuesPlayer(); - } - m_bChange = false; -} + +#ifdef OS_WINDOWS +//< 为了检测可用声卡 +#include +#include +#endif + +#include +#include +#include +#include +#include "CAlarmMediaPlayer.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/I18N.h" +#include "CAlarmSetMng.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include "CAlarmMsgManage.h" +#include +#include +#include +#include +#include + +using namespace kbd_public; +CAlarmMediaPlayer * CAlarmMediaPlayer::m_pInstance = NULL; +CAlarmMediaPlayer *CAlarmMediaPlayer::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAlarmMediaPlayer(); + } + return m_pInstance; +} + +CAlarmMediaPlayer::CAlarmMediaPlayer() + :m_bHaveValidAudioDev(true),m_pMediaPlayer(Q_NULLPTR),m_pTextToSpeech(Q_NULLPTR),m_pTimerCheckAudioDev(Q_NULLPTR),m_voice(100) +{ + m_readFlag = true; + QDir dir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("sound"); + initSetCfg(); + m_strMediaPath = dir.absolutePath() + QDir::separator(); + m_bChange = true; + m_pTimerCheckAudioDev = new QTimer(); + m_pTimerCheckAudioDev->setInterval(5000); + connect(m_pTimerCheckAudioDev, SIGNAL(timeout()), this, SLOT(checkAudioDev()),Qt::QueuedConnection); + m_pTimerCheckAudioStatus = new QTimer(); + m_pTimerCheckAudioStatus->setInterval(30000); + connect(m_pTimerCheckAudioStatus,&QTimer::timeout, this, &CAlarmMediaPlayer::checkAudioStatus,Qt::QueuedConnection); + checkAudioDev(); + checkAudioStatus(); + m_pTimerCheckAudioDev->start(); + m_pTimerCheckAudioStatus->start(); + + //< 需在checkAudioDev()之后调用 + + if(m_act == (int)E_ALARM_SOUND) + { + initPlayer(); + }else + { + initSpeech(); + } +} + +void CAlarmMediaPlayer::updateAudioCues() +{ + if(m_act == (int)E_ALARM_SOUND) + { + updateAudioCuesPlayer(); + }else + { + updateAudioCuesSpeech(); + } +} + +CAlarmMediaPlayer::~CAlarmMediaPlayer() +{ + if(Q_NULLPTR != m_pTimerCheckAudioDev) + { + m_pTimerCheckAudioDev->stop(); + m_pTimerCheckAudioDev->deleteLater(); + } + m_pTimerCheckAudioDev = NULL; + if(Q_NULLPTR != m_pTimerCheckAudioStatus) + { + m_pTimerCheckAudioStatus->stop(); + m_pTimerCheckAudioStatus->deleteLater(); + } + m_pTimerCheckAudioStatus = NULL; + if(Q_NULLPTR != m_pMediaPlayer) + { + if(QMediaPlayer::StoppedState != m_pMediaPlayer->state()) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + } + delete m_pMediaPlayer; + } + m_pMediaPlayer = Q_NULLPTR; + + if(Q_NULLPTR != m_pTextToSpeech) + { + if(QTextToSpeech::Ready != m_pTextToSpeech->state()) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + } + delete m_pTextToSpeech; + } + m_pTextToSpeech = Q_NULLPTR; + delete m_pInstance; + m_pInstance = Q_NULLPTR; +} + +void CAlarmMediaPlayer::initPlayer() +{ + if(Q_NULLPTR != m_pMediaPlayer) + { + return; + } + m_pMediaPlayer = new QMediaPlayer(); + m_pMediaPlayer->setVolume(m_voice); + connect(m_pMediaPlayer, &QMediaPlayer::stateChanged, this, &CAlarmMediaPlayer::playerStateChanged,Qt::QueuedConnection); + connect(m_pMediaPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(printError(QMediaPlayer::Error)),Qt::QueuedConnection); + + QMediaPlaylist *pPlayList = new QMediaPlaylist(this); + pPlayList->setPlaybackMode(QMediaPlaylist::Sequential); + pPlayList->clear(); + m_pMediaPlayer->setPlaylist(pPlayList); +} + +void CAlarmMediaPlayer::initSpeech() +{ + if(Q_NULLPTR != m_pTextToSpeech) + { + return; + } + + QStringList engineList = QTextToSpeech::availableEngines(); + + if(engineList.isEmpty()) + { + return ; + } + if(m_engine.isEmpty() || !engineList.contains(m_engine)) + { +#ifdef OS_LINUX + m_pTextToSpeech = Q_NULLPTR; + return; +#else + m_pTextToSpeech = new QTextToSpeech(this); +#endif + }else + { + m_pTextToSpeech = new QTextToSpeech(m_engine,this); + } + m_pTextToSpeech->setVolume(m_voice); + connect(m_pTextToSpeech, &QTextToSpeech::stateChanged, this, &CAlarmMediaPlayer::speechStateChanged,Qt::QueuedConnection); + QVector locales = m_pTextToSpeech->availableLocales(); + if(!m_language.isEmpty()) + { + foreach (const QLocale &locale, locales) { + if (locale.name() == m_language) + { + m_pTextToSpeech->setLocale(locale); + break; + } + } + } + QVector voices = m_pTextToSpeech->availableVoices(); + if(!m_voiceName.isEmpty()) + { + foreach (const QVoice &voice, voices) { + if (voice.name() == m_voiceName) + { + m_pTextToSpeech->setVoice(voice); + break; + } + } + } + //添加语音转文本处理条件 + QFile file(kbd_public::CFileUtil::getPathOfCfgFile("alarmSpeechTextTrans.xml" , CN_DIR_PRODUCT).c_str()); + if (!file.open(QFile::ReadWrite)) + { + LOGERROR("打开语音文本转换文件失败,默认不进行语音转换"); + return; + } + + QDomDocument doc; + if (!doc.setContent(&file)) + { + file.close(); + LOGERROR("打开语音文本转换文件失败,默认不进行语音转换"); + return; + } + file.close(); + + QDomElement root = doc.documentElement(); + if(root.isElement()) + { + QDomNodeList nodeList = root.childNodes(); + for(int i = 0 ; i < nodeList.count() ; i++) + { + QDomNode node = nodeList.at(i); + if(node.isElement()) + { + QDomElement element = node.toElement(); + if(element.tagName() == "Condition" && element.attribute("enable") == "true") + { + m_mapSpeechTxtTrans.insert(element.attribute("key"),element.attribute("value")); + } + } + } + } + +} + +void CAlarmMediaPlayer::initSetCfg() +{ + CAlarmSetMng::instance()->getActAndNum(m_act,m_num,m_style); + CAlarmSetMng::instance()->getEngine(m_engine,m_language,m_voiceName); + LOGDEBUG("获取当前语音引擎:%s-%s-%s",m_engine.toStdString().c_str(),m_language.toStdString().c_str(),m_voiceName.toStdString().c_str()); +} + +void CAlarmMediaPlayer::removeAudioCuesStop() +{ + if(m_act == (int)E_ALARM_SOUND) + { + if(m_pMediaPlayer != NULL) + { + m_pMediaPlayer->stop(); + } + }else + { + if(m_pTextToSpeech != NULL) + { + m_pTextToSpeech->stop(); + emit m_pTextToSpeech->stateChanged(m_pTextToSpeech->state()); + } + } +} + +void CAlarmMediaPlayer::insertAudioCuesStop(const AlarmMsgPtr &info) +{ + if(m_act == (int)E_ALARM_SOUND && ALM_ACT_SOUND == (info->m_alarmAction & ALM_ACT_SOUND)) + { + if(m_pMediaPlayer != NULL) + { + m_pMediaPlayer->stop(); + } + }else if(m_act == (int)E_ALARM_VOICE && ALM_ACT_VOICE == (info->m_alarmAction & ALM_ACT_VOICE)) + { + if(m_pTextToSpeech != NULL) + { + m_pTextToSpeech->stop(); + emit m_pTextToSpeech->stateChanged(m_pTextToSpeech->state()); + } + } +} + +void CAlarmMediaPlayer::speechTextTrans(QString &strContent) +{ +// strContent = "110KV回路503弹簧开关10A保护A线"; + //文本转换处理 + auto iter = m_mapSpeechTxtTrans.begin(); + for(;iter != m_mapSpeechTxtTrans.end() ; iter++) + { + strContent.replace(QRegExp(iter.key() , Qt::CaseInsensitive) , iter.value()); + } +} + +void CAlarmMediaPlayer::setVolumeEnable(bool bEnable) +{ + if(bEnable) + { + m_voice = 100; + if(m_pMediaPlayer != Q_NULLPTR) + { + m_pMediaPlayer->setVolume(m_voice); + } + + if(m_pTextToSpeech != Q_NULLPTR) + { + m_pTextToSpeech->setVolume(m_voice); + } + + } + else + { + m_voice = 0; + if(m_pMediaPlayer != Q_NULLPTR) + { + m_pMediaPlayer->setVolume(m_voice); + } + + if(m_pTextToSpeech != Q_NULLPTR) + { + m_pTextToSpeech->setVolume(m_voice); + } + } +} + +void CAlarmMediaPlayer::release() +{ + LOGINFO("CAlarmMediaPlayer::release()"); + if(m_pMediaPlayer) + { + m_pMediaPlayer->stop(); + } + if(m_pTextToSpeech) + { + m_pTextToSpeech->stop(); + } +} + +void CAlarmMediaPlayer::destory() +{ + if(m_pMediaPlayer) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + } + if(m_pTextToSpeech) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + } + m_pInstance = NULL; + deleteLater(); +} + +void CAlarmMediaPlayer::slotLoadConfig() +{ + LOGINFO("CAlarmMediaPlayer::slotLoadConfig()"); + if(m_pMediaPlayer) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + } + if(m_pTextToSpeech) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + delete m_pTextToSpeech; + m_pTextToSpeech = Q_NULLPTR; + } + initSetCfg(); + + + if(m_act == (int)E_ALARM_SOUND) + { + initPlayer(); + updateAudioCuesPlayer(); + }else + { + initSpeech(); + updateAudioCuesSpeech(); + } +} + +void CAlarmMediaPlayer::slotReadFlag() +{ + LOGDEBUG("slotReadFlag"); + m_readFlag = true; + + if(m_style != E_STYLE_NO_ALARM) + { + updateAudioCues(); + } +} + +void CAlarmMediaPlayer::playerStateChanged(QMediaPlayer::State state) +{ + if(m_act != (int)E_ALARM_SOUND) + { + return ; + } + m_bChange = true; + if(state == QMediaPlayer::StoppedState) + { + updateAudioCuesPlayer(); + } +} + +void CAlarmMediaPlayer::speechStateChanged(QTextToSpeech::State state) +{ + if(m_act != (int)E_ALARM_VOICE) + { + return ; + } + if(state == QTextToSpeech::Ready) + { + updateAudioCuesSpeech(); + } +} + +void CAlarmMediaPlayer::updateAudioCuesPlayer() +{ + if(!m_bHaveValidAudioDev || !m_pMediaPlayer || !m_readFlag || m_pMediaPlayer->state() != QMediaPlayer::StoppedState) + { + LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesPlayer(),return"); + return; + } + AlarmMsgPtr info; + if(m_style == E_STYLE_REPEAT) + { + info = CAlarmMsgManage::instance()->getOnePlayerAlm(-1); + } + else if(m_style == E_STYLE_REPEAT_X) + { + info = CAlarmMsgManage::instance()->getOnePlayerAlm(m_num); + } + if(info == Q_NULLPTR) + { + m_readFlag = false; + return ; + } + QStringList strAudioFileNames = info->sound_file; + + m_pMediaPlayer->playlist()->clear(); + foreach (QString fileName, strAudioFileNames) + { + if(!fileName.isEmpty()) + { + fileName = m_strMediaPath + fileName; + if(QFile::exists(fileName)) + { + m_pMediaPlayer->playlist()->addMedia(QUrl::fromLocalFile(fileName)); + } + } + } + if(!m_pMediaPlayer->playlist()->isEmpty()) + { + m_pMediaPlayer->play(); + } +} + +void CAlarmMediaPlayer::updateAudioCuesSpeech() +{ + if(!m_bHaveValidAudioDev || !m_pTextToSpeech || !m_readFlag || m_pTextToSpeech->state() != QTextToSpeech::Ready) + { + LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesSpeech(),return"); + return; + } + AlarmMsgPtr info; + if(m_style == E_STYLE_REPEAT) + { + info = CAlarmMsgManage::instance()->getOneSpeechAlm(-1); + } + else if(m_style == E_STYLE_REPEAT_X) + { + info = CAlarmMsgManage::instance()->getOneSpeechAlm(m_num); + } + if(info == Q_NULLPTR) + { + m_readFlag = false; + return ; + } + QString alarmContent = info->content; + + if(!alarmContent.isEmpty()) + { + //读取配置文件,更改读取方式 + speechTextTrans(alarmContent); + m_pTextToSpeech->say(alarmContent); + } +} + +void CAlarmMediaPlayer::printError(QMediaPlayer::Error error) +{ + if(m_pMediaPlayer) + { + LOGERROR("QMediaPlayer error == %d , errorString : %s",error,m_pMediaPlayer->errorString().toStdString().c_str()); + } +} + +void CAlarmMediaPlayer::checkAudioDev() +{ + //< 周期性检测音频设备有效性,因为: + //< 1、声卡是可以热拔插的,比如USB声卡 + //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 + + bool bHaveValidDev = false; + + //< 注意:在win系统,qt5.9.9以及5.12.9上测试,下面使用QAudioDeviceInfo检测的方法,本身会导致内存上涨 + { + // //< 测试结果:无论windows audio服务是否启动,defaultOutputDevice看上去都是对的,所以,不能用这个判断是否有效 + + // QList listDev(QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)); + + // //< 不能仅仅检测列表是否为空,还需要检测有效性 + // //< 当有声卡硬件,但是Windows Audio服务未启动时,设备列表不为空,但如果播放依然可能导致内存上涨问题 + // foreach (QAudioDeviceInfo objDev, listDev) + // { + // //< 当Window Audio服务未启动时,无法获取有效的格式信息,以此判断 + // if(objDev.preferredFormat().isValid()) + // { + // bHaveValidDev = true; + // break; + // } + // } + } + + //< 不得已,使用win系统原生API条件编译 +#ifdef OS_WINDOWS + { + //< 获取系统默认主设备的音量,如果成功则至少说明: + //< 1、有声卡; 2、Windows Audio服务正常 + + CoInitialize(NULL); + IMMDeviceEnumerator *pDevEnumerator = NULL; + CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDevEnumerator); + + if(NULL != pDevEnumerator) + { + IMMDevice *pDefaultDev = NULL; + pDevEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDefaultDev); + + pDevEnumerator->Release(); + pDevEnumerator = NULL; + + if(NULL != pDefaultDev) + { + IAudioEndpointVolume *pEndpointVol = NULL; + pDefaultDev->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&pEndpointVol); + + pDefaultDev->Release(); + pDefaultDev = NULL; + + if(NULL != pEndpointVol) + { + float fVol; + const HRESULT nResult = pEndpointVol->GetMasterVolumeLevelScalar(&fVol); + if(S_OK == nResult) + bHaveValidDev = true; + + pEndpointVol->Release(); + pEndpointVol = NULL; + } + } + } + + CoUninitialize(); + } +#else + //< 在Linux系统下测试,即使没有声卡也未见问题,暂时不做检测 + bHaveValidDev = true; +#endif + if(m_act == (int)E_ALARM_SOUND) // + { + if(m_bHaveValidAudioDev && !bHaveValidDev) + { + LOGERROR("No valid audio output device !"); + m_bHaveValidAudioDev = false; + if(m_pMediaPlayer != Q_NULLPTR) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + } + } + else if(!m_bHaveValidAudioDev && bHaveValidDev) + { + LOGINFO("Valid audio output device detected !"); + + //< 不重新构造可能不能正常播放 + if(m_pMediaPlayer) + { + m_pMediaPlayer->disconnect(); + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + } + + m_bHaveValidAudioDev = true; + initPlayer(); + updateAudioCuesPlayer(); + } + }else + { + if(m_bHaveValidAudioDev && !bHaveValidDev) + { + LOGERROR("No valid audio output device !"); + m_bHaveValidAudioDev = false; + if(m_pTextToSpeech != Q_NULLPTR) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + delete m_pTextToSpeech; + m_pTextToSpeech = Q_NULLPTR; + } + } + else if(!m_bHaveValidAudioDev && bHaveValidDev) + { + LOGINFO("Valid audio output device detected !"); + + //< 不重新构造可能不能正常播放 + if(m_pTextToSpeech) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + delete m_pTextToSpeech; + m_pTextToSpeech = Q_NULLPTR; + } + m_bHaveValidAudioDev = true; + initSpeech(); + updateAudioCuesSpeech(); + } + } +} +//因QMediaPlayer自身bug问题 此处只检测QMediaPlayer +void CAlarmMediaPlayer::checkAudioStatus() +{ + if(!m_readFlag) + { + return ; + } + if(m_act == (int)E_ALARM_VOICE) //语音告警无需检测 + { + return ; + } + if(!m_bChange) + { + //< 不重新构造可能不能正常播放 + if(m_pMediaPlayer) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + } + m_bHaveValidAudioDev = true; + initPlayer(); + updateAudioCuesPlayer(); + } + m_bChange = false; +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.h b/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.h index e97f8a56..e8de5d58 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.h @@ -1,102 +1,102 @@ -#ifndef CALARMMEDIAPLAYER_H -#define CALARMMEDIAPLAYER_H - -#include -#include -#include -#include -#include "CAlarmMsgInfo.h" -#include - -//< 告警语音最大条数 -//extern const int MAX_AUDIO_COUNT; - -class CAlarmMediaPlayer : public QObject -{ - Q_OBJECT -public: - static CAlarmMediaPlayer * instance(); - ~CAlarmMediaPlayer(); - - /** - * @brief slotAudioCuesEnable 静音使能 - * @param bEnable - */ - void setVolumeEnable(bool bEnable); - - void release(); - -public slots: - void destory(); - void slotLoadConfig(); - - void slotReadFlag(); - -private: - CAlarmMediaPlayer(); - - void updateAudioCues(); - /** - * @brief updateAudioCuesPlayer 更新播放文件 - */ - void updateAudioCuesPlayer(); - - void updateAudioCuesSpeech(); - - void initPlayer(); - - void initSpeech(); - - void initSetCfg(); - - void removeAudioCuesStop(); - - void insertAudioCuesStop(const AlarmMsgPtr &info); - - void speechTextTrans(QString &strContent);//读取配置文件,调整文本语音输出 - -private slots: - /** - * @brief playerStateChanged 播放器状态变化 - */ - void playerStateChanged(QMediaPlayer::State state); - - void speechStateChanged(QTextToSpeech::State state); - - void printError(QMediaPlayer::Error error); - - void checkAudioDev(); - - void checkAudioStatus(); -private: - //< 机器有有效的音频输出设备 - //< 如果没有输出设备,会导致内存上涨,在Windows Server 2016上实测如此 - bool m_bHaveValidAudioDev; - static CAlarmMediaPlayer * m_pInstance; - QString m_strMediaPath; - QMediaPlayer *m_pMediaPlayer; - QTextToSpeech *m_pTextToSpeech; - - //< 周期性检测音频设备有效性,因为: - //< 1、声卡是可以热拔插的,比如USB声卡 - //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 - QTimer *m_pTimerCheckAudioDev; - QTimer *m_pTimerCheckAudioStatus; - int m_voice; //语音大小 - bool m_bChange; - - int m_act; - int m_num; - int m_style; - - QString m_engine; - QString m_language; - QString m_voiceName; - QMap m_mapSpeechTxtTrans; - - bool m_readFlag; - - -}; - -#endif // CALARMMEDIAPLAYER_H +#ifndef CALARMMEDIAPLAYER_H +#define CALARMMEDIAPLAYER_H + +#include +#include +#include +#include +#include "CAlarmMsgInfo.h" +#include + +//< 告警语音最大条数 +//extern const int MAX_AUDIO_COUNT; + +class CAlarmMediaPlayer : public QObject +{ + Q_OBJECT +public: + static CAlarmMediaPlayer * instance(); + ~CAlarmMediaPlayer(); + + /** + * @brief slotAudioCuesEnable 静音使能 + * @param bEnable + */ + void setVolumeEnable(bool bEnable); + + void release(); + +public slots: + void destory(); + void slotLoadConfig(); + + void slotReadFlag(); + +private: + CAlarmMediaPlayer(); + + void updateAudioCues(); + /** + * @brief updateAudioCuesPlayer 更新播放文件 + */ + void updateAudioCuesPlayer(); + + void updateAudioCuesSpeech(); + + void initPlayer(); + + void initSpeech(); + + void initSetCfg(); + + void removeAudioCuesStop(); + + void insertAudioCuesStop(const AlarmMsgPtr &info); + + void speechTextTrans(QString &strContent);//读取配置文件,调整文本语音输出 + +private slots: + /** + * @brief playerStateChanged 播放器状态变化 + */ + void playerStateChanged(QMediaPlayer::State state); + + void speechStateChanged(QTextToSpeech::State state); + + void printError(QMediaPlayer::Error error); + + void checkAudioDev(); + + void checkAudioStatus(); +private: + //< 机器有有效的音频输出设备 + //< 如果没有输出设备,会导致内存上涨,在Windows Server 2016上实测如此 + bool m_bHaveValidAudioDev; + static CAlarmMediaPlayer * m_pInstance; + QString m_strMediaPath; + QMediaPlayer *m_pMediaPlayer; + QTextToSpeech *m_pTextToSpeech; + + //< 周期性检测音频设备有效性,因为: + //< 1、声卡是可以热拔插的,比如USB声卡 + //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 + QTimer *m_pTimerCheckAudioDev; + QTimer *m_pTimerCheckAudioStatus; + int m_voice; //语音大小 + bool m_bChange; + + int m_act; + int m_num; + int m_style; + + QString m_engine; + QString m_language; + QString m_voiceName; + QMap m_mapSpeechTxtTrans; + + bool m_readFlag; + + +}; + +#endif // CALARMMEDIAPLAYER_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMsgInfo.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmMsgInfo.cpp index 81c7e169..e66b6752 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMsgInfo.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMsgInfo.cpp @@ -1,1189 +1,1189 @@ -#include "CAlarmMsgInfo.h" -#include -#include "CAlarmDataCollect.h" -#include -#include "CAiAlarmMsgInfo.h" -#include "pub_logger_api/logger.h" - -using namespace std; -CAlarmMsgInfo::CAlarmMsgInfo(): m_alarmAction(0) -{ - alm_type = -1; - alm_status = -1; - logic_state = E_ALS_ALARM; - time_stamp = 1000; - domain_id = -1; - - location_id = -1; - app_id = -1; - uuid_base64 = QString(); - content = QString(); - priority = -1; - - if_water_alm = -1; - sound_file = QStringList(); - sub_system = 0; - dev_type = -1; - region_id = -1; - dev_group_tag = QString(); - - key_id_tag = QString(); - graph_name = QString(); - priorityOrder = -1; - deleteFlag = false; - releaseFlag = false; - device = QString(); - m_needVideoAlm = false; - m_camera = QString(); - m_preset = QString(); - m_tagname_type = E_TAGNAME_ERROR; - m_playNum = 0; - wave_file = QString(); -} - -CAlarmMsgInfo::CAlarmMsgInfo(const CAlarmMsgInfo &other): m_alarmAction(0) -{ - alm_type = other.alm_type; - alm_status = other.alm_status; - logic_state = other.logic_state; - time_stamp = other.time_stamp; - domain_id = other.domain_id; - - location_id = other.location_id; - app_id = other.app_id; - uuid_base64 = other.uuid_base64; - content = other.content; - priority = other.priority; - - priorityOrder = other.priorityOrder; - if_water_alm = other.if_water_alm; - sound_file = other.sound_file; - sub_system = other.sub_system; - dev_type = other.dev_type; - region_id = other.region_id; - - dev_group_tag = other.dev_group_tag; - key_id_tag = other.key_id_tag; - graph_name = other.graph_name; - deleteFlag = other.deleteFlag; - releaseFlag = other.releaseFlag; - device = other.device; - m_needVideoAlm = other.m_needVideoAlm; - m_camera = other.m_camera; - m_preset = other.m_preset; - m_tagname_type = other.m_tagname_type; - m_playNum = other.m_playNum; - wave_file = other.wave_file; -} - -void CAlarmMsgInfo::initialize(const kbd_idlfile::SAlmInfoToAlmClt &alarmInfo) -{ - alm_type = alarmInfo.alm_type(); - alm_status = alarmInfo.alm_status(); - logic_state = (E_ALARM_LOGICSTATE)alarmInfo.logic_state(); - time_stamp = alarmInfo.time_stamp(); - domain_id = alarmInfo.domain_id(); - - location_id = alarmInfo.location_id(); - app_id = alarmInfo.app_id(); - - uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); - - - content = QString::fromStdString(alarmInfo.content()); - priority = alarmInfo.priority(); - - if_water_alm = alarmInfo.if_water_alm(); - sub_system = alarmInfo.sub_system(); - sound_file.clear(); - for(int nIndex(0); nIndex < alarmInfo.sound_file_size(); nIndex++) - { - sound_file << QString::fromStdString(alarmInfo.sound_file(nIndex)); - } - - dev_type = alarmInfo.dev_type(); - if(alarmInfo.has_region_id() && alarmInfo.region_id() > 0) - { - region_id = alarmInfo.region_id(); - } - else - { - region_id = -1; - } - - if(alarmInfo.has_dev_group_tag()) - { - dev_group_tag = QString::fromStdString(alarmInfo.dev_group_tag()); - } - - if(alarmInfo.has_key_id_tag()) - { - key_id_tag = QString::fromStdString(alarmInfo.key_id_tag()); - QStringList tagList = key_id_tag.split("."); - if(tagList.size() == 5) - { - device = tagList.at(1) + "." + tagList.at(2); - } - if(tagList.at(0) == "analog") - { - m_tagname_type = E_TAGNAME_ANA; - }else if(tagList.at(0) == "digital") - { - m_tagname_type = E_TAGNAME_DIG; - }else if(tagList.at(0) == "mix") - { - m_tagname_type = E_TAGNAME_MIX; - }else if(tagList.at(0) == "accuml") - { - m_tagname_type = E_TAGNAME_ACC; - }else - { - m_tagname_type = E_TAGNAME_ERROR; - } - } - - if(alarmInfo.has_graph_name()) - { - graph_name = QString::fromStdString(alarmInfo.graph_name()); - } - if(logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_ALARM_CFM_DEL || - logic_state == E_ALS_RETURN_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) - { - deleteFlag = true; - }else - { - deleteFlag = false; - } - releaseFlag = false; - m_camera = QString::fromStdString(alarmInfo.camera_tag()); - m_preset = QString::fromStdString(alarmInfo.camera_preset()); - wave_file = QString::fromStdString(alarmInfo.wave_file()); - //wave_file = "D:\\Development_Repository\\ISCS6000_HOME\\data\\rec\\18-1-24-17-15-30587_1_S40_0"; -} - -bool CAlarmMsgInfo::lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) - { - case E_SORT_PRIORITY: - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - else if(priorityOrder < info->priorityOrder) - { - return false; - } - else if(priorityOrder == info->priorityOrder) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_TIME: - { - if(time_stamp < info->time_stamp) - { - return true; - } - if(time_stamp > info->time_stamp) - { - return false; - } - else if(time_stamp == info->time_stamp) - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - return false; - } - break; - } - case E_SORT_LOCATION: - { - if(location_id < info->location_id) - { - return true; - } - else if(location_id > info->location_id) - { - return false; - } - else if(location_id == info->location_id) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_REGION: - { - if(region_id < info->region_id) - { - return true; - } - else if(region_id > info->region_id) - { - return false; - } - else if(region_id == info->region_id) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_TYPE: - { - if(alm_type < info->alm_type) - { - return true; - } - else if(alm_type > info->alm_type) - { - return false; - } - else if(alm_type == info->alm_type) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_LOGICSTATE://已确认小于未确认 - { - if(logic_state ==E_ALS_ALARM_CFM|| logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY)//等于已确认 - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) //等于未确认 - { - return true; - } - } - if(logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)//等于未确认 - { - if(info->logic_state ==E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL || info->logic_state == ALS_EVT_ONLY)//等于已确认 - { - return false; - } - } - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - break; - } - case E_SORT_STYLE://动作小于复归小于事件 - { - if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 - { - if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 - { - return true; - } - } - if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 - { - if(info->logic_state == ALS_EVT_ONLY)//等于事件 - { - return true; - }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 - { - return false; - } - } - if(logic_state == ALS_EVT_ONLY)//等于事件 - { - if(info->logic_state != ALS_EVT_ONLY)//不等于事件 - { - return false; - } - } - - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - - break; - } - case E_SORT_ALM_STATE: - { - if(alm_status < info->alm_status) - { - return true; - } - else if(alm_status > info->alm_status) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_CONTENT: - { - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else if(content == info->content) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - default: - break; - } - return false; -} - -bool CAlarmMsgInfo::moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) - { - case E_SORT_PRIORITY: - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - else if(priorityOrder > info->priorityOrder) - { - return false; - } - else if(priorityOrder == info->priorityOrder) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TIME: - { - if(time_stamp > info->time_stamp) - { - return true; - } - if(time_stamp < info->time_stamp) - { - return false; - } - else if(time_stamp == info->time_stamp) - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - return false; - } - break; - } - case E_SORT_LOCATION: - { - if(location_id > info->location_id) - { - return true; - } - else if(location_id < info->location_id) - { - return false; - } - else if(location_id == info->location_id) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_REGION: - { - if(region_id > info->region_id) - { - return true; - } - else if(region_id < info->region_id) - { - return false; - } - else if(region_id == info->region_id) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TYPE: - { - if(alm_type > info->alm_type) - { - return true; - } - else if(alm_type < info->alm_type) - { - return false; - } - else if(alm_type == info->alm_type) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_LOGICSTATE: - { - if(logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL) //等于未确认 - { - if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL|| info->logic_state == ALS_EVT_ONLY) - { - return true; - } - } - if(logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) - { - return false; - } - } - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - - break; - } - case E_SORT_STYLE://动作小于复归小于事件 - { - if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 - { - if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 - { - return false; - } - } - if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 - { - if(info->logic_state == ALS_EVT_ONLY)//等于事件 - { - return false; - }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 - { - return true; - } - } - if(logic_state == ALS_EVT_ONLY)//等于事件 - { - if(info->logic_state != ALS_EVT_ONLY)//不等于事件 - { - return true; - } - } - - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - - break; - } - case E_SORT_ALM_STATE: - { - if(alm_status > info->alm_status) - { - return true; - } - else if(alm_status < info->alm_status) - { - return false; - } - else if(alm_status == info->alm_status) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_CONTENT: - { - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content > info->content) - { - return true; - } - else if(content < info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - default: - break; - } - return false; -} - -bool CAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priorityOrder > info->priorityOrder) - { - return true; - }else if(priorityOrder < info->priorityOrder) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp < info->time_stamp) - { - return true; - }else if(time_stamp > info->time_stamp) - { - return false; - }else - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - if(location_id < info->location_id) - { - return true; - }else if(location_id > info->location_id) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_REGION: - if(region_id < info->region_id) - { - return true; - }else if(region_id > info->region_id) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - - break; - case E_SORT_TYPE: - if(alm_type < info->alm_type) - { - return true; - }else if(alm_type > info->alm_type) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE://已确认小于未确认 - { - if(logic_state ==E_ALS_ALARM_CFM|| logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY)//等于已确认 - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) //等于未确认 - { - return true; - } - } - if(logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)//等于未确认 - { - if(info->logic_state ==E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL || info->logic_state == ALS_EVT_ONLY)//等于已确认 - { - return false; - } - } - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - break; - } - case E_SORT_STYLE://动作小于复归小于事件 - { - if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 - { - if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 - { - return true; - } - } - if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 - { - if(info->logic_state == ALS_EVT_ONLY)//等于事件 - { - return true; - }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 - { - return false; - } - } - if(logic_state == ALS_EVT_ONLY)//等于事件 - { - if(info->logic_state != ALS_EVT_ONLY)//不等于事件 - { - return false; - } - } - - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - - break; - } - case E_SORT_ALM_STATE: - if(alm_status < info->alm_status) - { - return true; - }else if(alm_status > info->alm_status) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - default: - break; - } - return false; -} -//< 优先级小的大于优先级大的、时间大的大于时间小的、车站id大的大于车站id小的、责任区id大的大于责任区id小的、告警类型大的大于告警类型小的、 -//< 告警内容都为空,则前者小于后者、告警内容为空的小于告警内容不为空的、告警未确认的大于告警已确认的、告警状态大的大于告警状态小的 -bool CAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priorityOrder < info->priorityOrder) - { - return true; - }else if(priorityOrder > info->priorityOrder) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_TIME: - if(time_stamp > info->time_stamp) - { - return true; - }else if(time_stamp < info->time_stamp) - { - return false; - }else - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - if(location_id > info->location_id) - { - return true; - }else if(location_id < info->location_id) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_REGION: - if(region_id > info->region_id) - { - return true; - }else if(region_id < info->region_id) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - - break; - case E_SORT_TYPE: - if(alm_type > info->alm_type) - { - return true; - }else if(alm_type < info->alm_type) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content > info->content) - { - return true; - } - else if(content < info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_LOGICSTATE: - { - if(logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL) //等于未确认 - { - if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL|| info->logic_state == ALS_EVT_ONLY) - { - return true; - } - } - if(logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) - { - return false; - } - } - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - - break; - } - case E_SORT_STYLE://动作小于复归小于事件 - { - if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 - { - if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 - { - return false; - } - } - if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 - { - if(info->logic_state == ALS_EVT_ONLY)//等于事件 - { - return false; - }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 - { - return true; - } - } - if(logic_state == ALS_EVT_ONLY)//等于事件 - { - if(info->logic_state != ALS_EVT_ONLY)//不等于事件 - { - return true; - } - } - - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - - break; - } - case E_SORT_ALM_STATE: - if(alm_status > info->alm_status) - { - return true; - }else if(alm_status < info->alm_status) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - default: - break; - } - return false; -} - -bool CAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priorityOrder > info->priorityOrder) - { - return true; - }else if(priorityOrder < info->priorityOrder) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp < info->time_stamp) - { - return true; - }else if(time_stamp > info->time_stamp) - { - return false; - }else - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return true; - break; - case E_SORT_REGION: - return true; - break; - case E_SORT_TYPE: - return true; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return true; - case E_SORT_STYLE: - return true; - case E_SORT_ALM_STATE: - return true; - break; - default: - break; - } - return false; -} - -bool CAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priorityOrder < info->priorityOrder) - { - return true; - }else if(priorityOrder > info->priorityOrder) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_TIME: - if(time_stamp > info->time_stamp) - { - return true; - }else if(time_stamp < info->time_stamp) - { - return false; - }else - { - if(priorityOrder < info->priorityOrder) - { - return false; - } - return true; - } - break; - case E_SORT_LOCATION: - return false; - break; - case E_SORT_REGION: - return false; - break; - case E_SORT_TYPE: - return false; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content > info->content) - { - return true; - } - else if(content < info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_LOGICSTATE: - return false; - break; - case E_SORT_STYLE: - return false; - break; - case E_SORT_ALM_STATE: - return false; - break; - default: - break; - } - return false; -} - -bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target) -{ - if(source.uuid_base64 == target.uuid_base64) - { - return true; - } - return false; - // //替换式告警且车站、测点ID相同 - // if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) - // { - // return true; - // } - // //流水账告警且时标、告警内容相同 - // else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) - // { - // return true; - // } - // return false; -} +#include "CAlarmMsgInfo.h" +#include +#include "CAlarmDataCollect.h" +#include +#include "CAiAlarmMsgInfo.h" +#include "pub_logger_api/logger.h" + +using namespace std; +CAlarmMsgInfo::CAlarmMsgInfo(): m_alarmAction(0) +{ + alm_type = -1; + alm_status = -1; + logic_state = E_ALS_ALARM; + time_stamp = 1000; + domain_id = -1; + + location_id = -1; + app_id = -1; + uuid_base64 = QString(); + content = QString(); + priority = -1; + + if_water_alm = -1; + sound_file = QStringList(); + sub_system = 0; + dev_type = -1; + region_id = -1; + dev_group_tag = QString(); + + key_id_tag = QString(); + graph_name = QString(); + priorityOrder = -1; + deleteFlag = false; + releaseFlag = false; + device = QString(); + m_needVideoAlm = false; + m_camera = QString(); + m_preset = QString(); + m_tagname_type = E_TAGNAME_ERROR; + m_playNum = 0; + wave_file = QString(); +} + +CAlarmMsgInfo::CAlarmMsgInfo(const CAlarmMsgInfo &other): m_alarmAction(0) +{ + alm_type = other.alm_type; + alm_status = other.alm_status; + logic_state = other.logic_state; + time_stamp = other.time_stamp; + domain_id = other.domain_id; + + location_id = other.location_id; + app_id = other.app_id; + uuid_base64 = other.uuid_base64; + content = other.content; + priority = other.priority; + + priorityOrder = other.priorityOrder; + if_water_alm = other.if_water_alm; + sound_file = other.sound_file; + sub_system = other.sub_system; + dev_type = other.dev_type; + region_id = other.region_id; + + dev_group_tag = other.dev_group_tag; + key_id_tag = other.key_id_tag; + graph_name = other.graph_name; + deleteFlag = other.deleteFlag; + releaseFlag = other.releaseFlag; + device = other.device; + m_needVideoAlm = other.m_needVideoAlm; + m_camera = other.m_camera; + m_preset = other.m_preset; + m_tagname_type = other.m_tagname_type; + m_playNum = other.m_playNum; + wave_file = other.wave_file; +} + +void CAlarmMsgInfo::initialize(const kbd_idlfile::SAlmInfoToAlmClt &alarmInfo) +{ + alm_type = alarmInfo.alm_type(); + alm_status = alarmInfo.alm_status(); + logic_state = (E_ALARM_LOGICSTATE)alarmInfo.logic_state(); + time_stamp = alarmInfo.time_stamp(); + domain_id = alarmInfo.domain_id(); + + location_id = alarmInfo.location_id(); + app_id = alarmInfo.app_id(); + + uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); + + + content = QString::fromStdString(alarmInfo.content()); + priority = alarmInfo.priority(); + + if_water_alm = alarmInfo.if_water_alm(); + sub_system = alarmInfo.sub_system(); + sound_file.clear(); + for(int nIndex(0); nIndex < alarmInfo.sound_file_size(); nIndex++) + { + sound_file << QString::fromStdString(alarmInfo.sound_file(nIndex)); + } + + dev_type = alarmInfo.dev_type(); + if(alarmInfo.has_region_id() && alarmInfo.region_id() > 0) + { + region_id = alarmInfo.region_id(); + } + else + { + region_id = -1; + } + + if(alarmInfo.has_dev_group_tag()) + { + dev_group_tag = QString::fromStdString(alarmInfo.dev_group_tag()); + } + + if(alarmInfo.has_key_id_tag()) + { + key_id_tag = QString::fromStdString(alarmInfo.key_id_tag()); + QStringList tagList = key_id_tag.split("."); + if(tagList.size() == 5) + { + device = tagList.at(1) + "." + tagList.at(2); + } + if(tagList.at(0) == "analog") + { + m_tagname_type = E_TAGNAME_ANA; + }else if(tagList.at(0) == "digital") + { + m_tagname_type = E_TAGNAME_DIG; + }else if(tagList.at(0) == "mix") + { + m_tagname_type = E_TAGNAME_MIX; + }else if(tagList.at(0) == "accuml") + { + m_tagname_type = E_TAGNAME_ACC; + }else + { + m_tagname_type = E_TAGNAME_ERROR; + } + } + + if(alarmInfo.has_graph_name()) + { + graph_name = QString::fromStdString(alarmInfo.graph_name()); + } + if(logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_ALARM_CFM_DEL || + logic_state == E_ALS_RETURN_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) + { + deleteFlag = true; + }else + { + deleteFlag = false; + } + releaseFlag = false; + m_camera = QString::fromStdString(alarmInfo.camera_tag()); + m_preset = QString::fromStdString(alarmInfo.camera_preset()); + wave_file = QString::fromStdString(alarmInfo.wave_file()); + //wave_file = "D:\\Development_Repository\\ISCS6000_HOME\\data\\rec\\18-1-24-17-15-30587_1_S40_0"; +} + +bool CAlarmMsgInfo::lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + else if(priorityOrder < info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp < info->time_stamp) + { + return true; + } + if(time_stamp > info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id < info->location_id) + { + return true; + } + else if(location_id > info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_REGION: + { + if(region_id < info->region_id) + { + return true; + } + else if(region_id > info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type < info->alm_type) + { + return true; + } + else if(alm_type > info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOGICSTATE://已确认小于未确认 + { + if(logic_state ==E_ALS_ALARM_CFM|| logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY)//等于已确认 + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) //等于未确认 + { + return true; + } + } + if(logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)//等于未确认 + { + if(info->logic_state ==E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL || info->logic_state == ALS_EVT_ONLY)//等于已确认 + { + return false; + } + } + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + break; + } + case E_SORT_STYLE://动作小于复归小于事件 + { + if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 + { + if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 + { + return true; + } + } + if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 + { + if(info->logic_state == ALS_EVT_ONLY)//等于事件 + { + return true; + }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 + { + return false; + } + } + if(logic_state == ALS_EVT_ONLY)//等于事件 + { + if(info->logic_state != ALS_EVT_ONLY)//不等于事件 + { + return false; + } + } + + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_ALM_STATE: + { + if(alm_status < info->alm_status) + { + return true; + } + else if(alm_status > info->alm_status) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + else if(priorityOrder > info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp > info->time_stamp) + { + return true; + } + if(time_stamp < info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id > info->location_id) + { + return true; + } + else if(location_id < info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id > info->region_id) + { + return true; + } + else if(region_id < info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type > info->alm_type) + { + return true; + } + else if(alm_type < info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_LOGICSTATE: + { + if(logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL) //等于未确认 + { + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL|| info->logic_state == ALS_EVT_ONLY) + { + return true; + } + } + if(logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) + { + return false; + } + } + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_STYLE://动作小于复归小于事件 + { + if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 + { + if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 + { + return false; + } + } + if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 + { + if(info->logic_state == ALS_EVT_ONLY)//等于事件 + { + return false; + }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 + { + return true; + } + } + if(logic_state == ALS_EVT_ONLY)//等于事件 + { + if(info->logic_state != ALS_EVT_ONLY)//不等于事件 + { + return true; + } + } + + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_ALM_STATE: + { + if(alm_status > info->alm_status) + { + return true; + } + else if(alm_status < info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder > info->priorityOrder) + { + return true; + }else if(priorityOrder < info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + if(location_id < info->location_id) + { + return true; + }else if(location_id > info->location_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_REGION: + if(region_id < info->region_id) + { + return true; + }else if(region_id > info->region_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + + break; + case E_SORT_TYPE: + if(alm_type < info->alm_type) + { + return true; + }else if(alm_type > info->alm_type) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE://已确认小于未确认 + { + if(logic_state ==E_ALS_ALARM_CFM|| logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY)//等于已确认 + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) //等于未确认 + { + return true; + } + } + if(logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)//等于未确认 + { + if(info->logic_state ==E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL || info->logic_state == ALS_EVT_ONLY)//等于已确认 + { + return false; + } + } + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + break; + } + case E_SORT_STYLE://动作小于复归小于事件 + { + if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 + { + if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 + { + return true; + } + } + if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 + { + if(info->logic_state == ALS_EVT_ONLY)//等于事件 + { + return true; + }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 + { + return false; + } + } + if(logic_state == ALS_EVT_ONLY)//等于事件 + { + if(info->logic_state != ALS_EVT_ONLY)//不等于事件 + { + return false; + } + } + + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_ALM_STATE: + if(alm_status < info->alm_status) + { + return true; + }else if(alm_status > info->alm_status) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + default: + break; + } + return false; +} +//< 优先级小的大于优先级大的、时间大的大于时间小的、车站id大的大于车站id小的、责任区id大的大于责任区id小的、告警类型大的大于告警类型小的、 +//< 告警内容都为空,则前者小于后者、告警内容为空的小于告警内容不为空的、告警未确认的大于告警已确认的、告警状态大的大于告警状态小的 +bool CAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder < info->priorityOrder) + { + return true; + }else if(priorityOrder > info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + if(location_id > info->location_id) + { + return true; + }else if(location_id < info->location_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_REGION: + if(region_id > info->region_id) + { + return true; + }else if(region_id < info->region_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + + break; + case E_SORT_TYPE: + if(alm_type > info->alm_type) + { + return true; + }else if(alm_type < info->alm_type) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_LOGICSTATE: + { + if(logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL) //等于未确认 + { + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL|| info->logic_state == ALS_EVT_ONLY) + { + return true; + } + } + if(logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) + { + return false; + } + } + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_STYLE://动作小于复归小于事件 + { + if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 + { + if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 + { + return false; + } + } + if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 + { + if(info->logic_state == ALS_EVT_ONLY)//等于事件 + { + return false; + }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 + { + return true; + } + } + if(logic_state == ALS_EVT_ONLY)//等于事件 + { + if(info->logic_state != ALS_EVT_ONLY)//不等于事件 + { + return true; + } + } + + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_ALM_STATE: + if(alm_status > info->alm_status) + { + return true; + }else if(alm_status < info->alm_status) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder > info->priorityOrder) + { + return true; + }else if(priorityOrder < info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return true; + case E_SORT_STYLE: + return true; + case E_SORT_ALM_STATE: + return true; + break; + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder < info->priorityOrder) + { + return true; + }else if(priorityOrder > info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priorityOrder < info->priorityOrder) + { + return false; + } + return true; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_LOGICSTATE: + return false; + break; + case E_SORT_STYLE: + return false; + break; + case E_SORT_ALM_STATE: + return false; + break; + default: + break; + } + return false; +} + +bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target) +{ + if(source.uuid_base64 == target.uuid_base64) + { + return true; + } + return false; + // //替换式告警且车站、测点ID相同 + // if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) + // { + // return true; + // } + // //流水账告警且时标、告警内容相同 + // else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) + // { + // return true; + // } + // return false; +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMsgInfo.h b/product/src/gui/plugin/AlarmWidget/CAlarmMsgInfo.h index d94b75ed..ebe9100e 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMsgInfo.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMsgInfo.h @@ -1,88 +1,88 @@ -#ifndef ALARMMSGINFO_H -#define ALARMMSGINFO_H - -#include -#include -#include -#include "alarm_server_api/CAlmApiForAlmClt.h" -#include "CAlarmCommon.h" -//< 告警操作 权限定义 -#define FUNC_SPE_ALARM_OPERATE ("FUNC_SPE_ALARM_OPERATE") -#define FUNC_SPE_ALARM_DELETE ("FUNC_SPE_ALARM_DELETE") -// 逻辑状态 -enum E_ALARM_LOGICSTATE -{ - E_ALS_ALARM = 0, // 告警状态 - E_ALS_ALARM_CFM =1, // 告警确认状态 - E_ALS_RETURN=2, // 告警返回状态 - E_ALS_RETURN_CFM=3, // 告警返回确认状态 - ALS_EVT_ONLY = 4, // 仅事件 - - //在原始告警窗删除后,可能还需要在智能告警窗展示 - E_ALS_ALARM_DEL = 20, // 告警状态,且在原始告警窗已删除,可能是达到数量上限而删除 - E_ALS_ALARM_CFM_DEL =21, // 告警确认状态,且在原始告警窗已删除 - E_ALS_RETURN_DEL=22, // 告警返回状态,且在原始告警窗已删除,可能是达到数量上限而删除 - E_ALS_RETURN_CFM_DEL=23, // 告警返回确认状态,且在原始告警窗已删除 - E_ALS_BAD = 100 -}; -class CAlarmMsgInfo -{ -public: - CAlarmMsgInfo(); - CAlarmMsgInfo(const CAlarmMsgInfo &other); - void initialize(const kbd_idlfile::SAlmInfoToAlmClt &alarmInfo); - int getCameraInfoByTag(const QString &tag); - - //< [优先级越小表示越大]-原始告警窗调用 - bool lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - //< [优先级越小表示越大]-智能告警窗调用 - bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - qint32 alm_type; //< 告警类型 - int alm_status; //< 告警状态 - E_ALARM_LOGICSTATE logic_state; //< 逻辑状态 - quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) - qint32 domain_id; //< 域ID - qint32 location_id; //< 位置ID - qint32 app_id; //< 应用号 - qint32 priority; //< 告警优先级id - qint32 if_water_alm; //< 是否流水账告警(0 替换式告警,1 流水账告警) - QString uuid_base64; //< uuid 主键 - QString content; //< 告警内容 - QStringList sound_file; //< 语音文件名 - //可选 - qint32 sub_system; //< 专业 - qint32 dev_type; //< 设备类型ID - qint32 region_id; //< 责任区ID - QString dev_group_tag; //< 设备组 - QString key_id_tag; //< 测点ID - QString graph_name; //< 告警关联画面名称 - QString wave_file; //< 录波画面 - //< Extend - qint32 priorityOrder; //< 优先级 - QString device; //< 设备 (保留) - bool deleteFlag; //< 是否被删除 - bool releaseFlag; //< 释放标志 - bool m_needVideoAlm; //< 是否需要视频告警 - QString m_camera; - QString m_preset; - E_TAGNAME_TYPE m_tagname_type; - - - //程序使用 - int m_playNum; // 播放次数 默认0次 - int m_alarmAction; //此告警对应的告警动作 - -}; - -bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target); - -Q_DECLARE_METATYPE(CAlarmMsgInfo) -Q_DECLARE_METATYPE(AlarmMsgPtr) - -#endif // ALARMMSGINFO_H +#ifndef ALARMMSGINFO_H +#define ALARMMSGINFO_H + +#include +#include +#include +#include "alarm_server_api/CAlmApiForAlmClt.h" +#include "CAlarmCommon.h" +//< 告警操作 权限定义 +#define FUNC_SPE_ALARM_OPERATE ("FUNC_SPE_ALARM_OPERATE") +#define FUNC_SPE_ALARM_DELETE ("FUNC_SPE_ALARM_DELETE") +// 逻辑状态 +enum E_ALARM_LOGICSTATE +{ + E_ALS_ALARM = 0, // 告警状态 + E_ALS_ALARM_CFM =1, // 告警确认状态 + E_ALS_RETURN=2, // 告警返回状态 + E_ALS_RETURN_CFM=3, // 告警返回确认状态 + ALS_EVT_ONLY = 4, // 仅事件 + + //在原始告警窗删除后,可能还需要在智能告警窗展示 + E_ALS_ALARM_DEL = 20, // 告警状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_ALARM_CFM_DEL =21, // 告警确认状态,且在原始告警窗已删除 + E_ALS_RETURN_DEL=22, // 告警返回状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_RETURN_CFM_DEL=23, // 告警返回确认状态,且在原始告警窗已删除 + E_ALS_BAD = 100 +}; +class CAlarmMsgInfo +{ +public: + CAlarmMsgInfo(); + CAlarmMsgInfo(const CAlarmMsgInfo &other); + void initialize(const kbd_idlfile::SAlmInfoToAlmClt &alarmInfo); + int getCameraInfoByTag(const QString &tag); + + //< [优先级越小表示越大]-原始告警窗调用 + bool lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + //< [优先级越小表示越大]-智能告警窗调用 + bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + qint32 alm_type; //< 告警类型 + int alm_status; //< 告警状态 + E_ALARM_LOGICSTATE logic_state; //< 逻辑状态 + quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) + qint32 domain_id; //< 域ID + qint32 location_id; //< 位置ID + qint32 app_id; //< 应用号 + qint32 priority; //< 告警优先级id + qint32 if_water_alm; //< 是否流水账告警(0 替换式告警,1 流水账告警) + QString uuid_base64; //< uuid 主键 + QString content; //< 告警内容 + QStringList sound_file; //< 语音文件名 + //可选 + qint32 sub_system; //< 专业 + qint32 dev_type; //< 设备类型ID + qint32 region_id; //< 责任区ID + QString dev_group_tag; //< 设备组 + QString key_id_tag; //< 测点ID + QString graph_name; //< 告警关联画面名称 + QString wave_file; //< 录波画面 + //< Extend + qint32 priorityOrder; //< 优先级 + QString device; //< 设备 (保留) + bool deleteFlag; //< 是否被删除 + bool releaseFlag; //< 释放标志 + bool m_needVideoAlm; //< 是否需要视频告警 + QString m_camera; + QString m_preset; + E_TAGNAME_TYPE m_tagname_type; + + + //程序使用 + int m_playNum; // 播放次数 默认0次 + int m_alarmAction; //此告警对应的告警动作 + +}; + +bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target); + +Q_DECLARE_METATYPE(CAlarmMsgInfo) +Q_DECLARE_METATYPE(AlarmMsgPtr) + +#endif // ALARMMSGINFO_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.cpp index c7ba44f3..603c52bd 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.cpp @@ -1,1897 +1,1897 @@ -#include "CAlarmMsgManage.h" -#include -#include -#include -#include -#include "CAlarmDataCollect.h" -#include "service/alarm_server_api/AlarmCommonDef.h" -#include -#include "perm_mng_api/PermMngApi.h" - -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" -#include "Common.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CharUtil.h" -#include "pub_logger_api/logger.h" -#include "CAlarmBaseData.h" - -using namespace kbd_public; -using namespace std; - -CAlarmMsgManage *CAlarmMsgManage::pInstance = NULL; -CAlarmMsgManage *CAlarmMsgManage::instance() -{ - if(pInstance == NULL) - { - pInstance = new CAlarmMsgManage(); - } - return pInstance; -} - -CAlarmMsgManage::CAlarmMsgManage() - : QObject(), - m_nNDelComAlarmCount(0), - m_nAlmNum(0), - m_nAlmTotal(0) -{ - mutex = new QMutex(); - QDir dir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - dir.cd("sound"); - m_strMediaPath = dir.absolutePath() + QDir::separator(); - - m_infos.clear(); - m_alarmDeviceStatistical.clear(); - m_alarmDeviceGroupStatistical.clear(); - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - m_listMsgAddCache.clear(); - m_inhibitFilter.clear(); - m_aiinfos.clear(); - m_aicount.clear(); - m_alarm.clear(); - m_idToid.clear(); - m_aitolocation.clear(); - //根据需求 - m_all.clear(); - m_aiall.clear(); - - m_rtdbAlarmActionAccess = new kbd_dbms::CRdbAccess(); - m_rtdbAlarmActionAccess->open("base", "alarm_level_define"); - - m_rtdbLocationDescriptionAccess = new kbd_dbms::CRdbAccess(); - m_rtdbLocationDescriptionAccess->open("base", "sys_model_location_info"); - - m_rtdbAppDescriptionAccess = new kbd_dbms::CRdbAccess(); - m_rtdbAppDescriptionAccess->open("base", "sys_model_app_info"); - - loadPermInfo(); -} - -void CAlarmMsgManage::refreshCache() -{ - QMutexLocker locker(mutex); - m_listMsgAddCache.clear(); -} - -bool CAlarmMsgManage::ifInhibit(const QString &tag_name) -{ - QMutexLocker locker(mutex); - for(int index(0);indexkey_id_tag == tag_name) - { - return true; - } - } - return false; -} - -bool CAlarmMsgManage::isInhibit(const QString &tag_name) -{ - for(int index(0);indexkey_id_tag == tag_name) - { - return true; - } - } - return false; -} - -void CAlarmMsgManage::addInhibitAlm(const AlarmMsgPtr &info) -{ - QMutexLocker locker(mutex); - m_inhibitFilter.append(info); -} - -void CAlarmMsgManage::removeInhibitTag(const QString &tag_name) -{ - QMutexLocker locker(mutex); - for(int index(m_inhibitFilter.size()-1);index >= 0;index--) - { - if(m_inhibitFilter[index]->key_id_tag == tag_name) - { - m_inhibitFilter.removeAt(index); - } - } -} - -QMap CAlarmMsgManage::getDevAlarm(const QString &device) -{ - // QMutexLocker locker(mutex); - QMap alarm; - alarm.clear(); - return m_alarmDevPriority.value(device,alarm); -} - -QMap > CAlarmMsgManage::getDevGroupPriorityDevNum(const QString &deviceGroup) -{ - QMutexLocker locker(mutex); - QMap > alarm; - alarm.clear(); - - return m_alarmDGPDev.value(deviceGroup,alarm); -} - -QHash > CAlarmMsgManage::getLocAlmInfo() -{ - QMutexLocker locker(mutex); - return m_alarmLPAlm; -} - -void CAlarmMsgManage::updataDevGroupByDev(QString devGroup, QString device) -{ - QHash >::iterator it = m_alarmDevPriority.find(device); - int devMaxPriority =-1;//最高优先级 - if(it != m_alarmDevPriority.end()) - { - QMap::iterator itor= --it.value().end(); - - for(;itor!= --it.value().begin();itor--) - { - if(itor.value()>0) - { - devMaxPriority = itor.key(); - break; - } - } - } - QHash > >::iterator pos = m_alarmDGPDev.find(devGroup); - if(pos != m_alarmDGPDev.end()) - { - QMap > &priorityMap = pos.value(); - QMap >::iterator itor = priorityMap.begin(); - - while(itor != priorityMap.end()) { - QList &list = itor.value(); - if(list.contains(device)) - { - list.removeOne(device); - } - itor++; - } - if(devMaxPriority == -1) - return ; - itor =priorityMap.find(devMaxPriority); - if(itor != priorityMap.end()) - { - QList &devList = itor.value(); - if(!devList.contains(device)) - { - devList.append(device); - } - }else - { - QList list; - list.append(device); - priorityMap.insert(devMaxPriority,list); - } - }else - { - QList list; - list.append(device); - QMap > priorityMap; - priorityMap.insert(devMaxPriority,list); - m_alarmDGPDev.insert(devGroup,priorityMap); - } -} - -QHash > > CAlarmMsgManage::getLocNotConfirmAlmInfo() -{ - QMutexLocker locker(mutex); - return m_alarmLNCAlm; -} - -void CAlarmMsgManage::getAllInhibitAlm(QList &almList) -{ - QMutexLocker locker(mutex); - almList = m_inhibitFilter; -} - -void CAlarmMsgManage::slotLogin() -{ - QMutexLocker locker(mutex); - //emit sigClearAudioCues(); - m_playerList.clear(); - m_infos.clear(); - m_alarmDeviceStatistical.clear(); - m_alarmDeviceGroupStatistical.clear(); - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - m_listMsgAddCache.clear(); - m_inhibitFilter.clear(); - m_aiinfos.clear(); - m_aicount.clear(); - m_alarm.clear(); - m_idToid.clear(); - m_aitolocation.clear(); - - m_nNDelComAlarmCount = 0; - m_nAlmNum = 0; - m_nAlmTotal = 0; - m_alarmDevPriority.clear(); - m_alarmDGPDev.clear(); - m_alarmLPAlm.clear(); - m_delaydeal.clear(); - - //清空告警推图 - emit sigAlarmPushGraphClear(); - - loadPermInfo(); - initAlarm(); - initAiAlarm(); - - emit sigAllViewReload(); -} - -void CAlarmMsgManage::removeAiAlarmMsgByDomainID(const int &domainId) -{ - QMutexLocker locker(mutex); - /* 清除全缓存 - */ - QHash::iterator pos = m_aiall.begin(); - while(pos != m_aiall.end()) { - if(domainId == (*pos)->domain_id) - { - pos = m_aiall.erase(pos); - continue; - } - pos++; - } - /* 清除有权限和未禁止的缓存 - */ - QHash::iterator it = m_aiinfos.begin(); - while(it != m_aiinfos.end()) - { - if(domainId == (*it)->domain_id) - { - eraseaicount((*it)->uuid_base64); - eraseidtoid((*it)->uuid_base64); - eraseidtolocation((*it)->uuid_base64); - m_nAlmTotal -= (*it)->raw_alm_uuid.size(); - it = m_aiinfos.erase(it); - continue; - } - it++; - } - //清除延迟处理的智能告警 - QList::iterator itpos =m_delaydeal.begin(); - while(itpos !=m_delaydeal.end()) { - if(domainId == (*itpos)->domain_id) - { - - itpos = m_delaydeal.erase(itpos); - continue; - } - itpos++; - } -} - -void CAlarmMsgManage::addAiAllAlarmMsg(const QList &msgList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = msgList.begin(); - while(itpos != msgList.end()) { - m_aiall.insert((*itpos)->uuid_base64,*itpos); - QVector uuidVec = (*itpos)->raw_alm_uuid; - addidtoid(uuidVec,(*itpos)->uuid_base64); //记录原始告警uuid和智能告警uuid键值对 ,一直到release - QVector deluuidVec; - updatealarm(uuidVec,deluuidVec);//不可删除 //更新智能告警窗上的未聚类的原始告警,防止由于先后顺序导致显示出错 - if((*itpos)->deleteFlag || (*itpos)->brokenFlag) - { - itpos++; - continue; - } - //检查此智能告警下的原始告警是否完整 - //若完整则继续执行 - //不完整(此处指的是智能告警先到,原始告警未到的情况,并非告警服务通知的不完整)则延时处理 ,延时处理的不需要调用addidtoid()和updatealarm() - QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 - if(!isHaveAlm(uuidVec,almInfoList)) - { - m_delaydeal.append(*itpos); //延后处理 - itpos++; - continue; - } - QHash::iterator it = m_all.find((*itpos)->main_uuid_base64); - if(it != m_all.end()) - { - (*itpos)->main_state = (*it)->logic_state; - } - //检查是否具有权限 - if(checkLookPerm(almInfoList)) - { - addaicount(almInfoList,(*itpos)->uuid_base64); - addaitolocation(almInfoList,(*itpos)->uuid_base64); - initaivideo(*itpos); - m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); - m_aiinfos.insert((*itpos)->uuid_base64,*itpos); - } - itpos++; - } -} - -void CAlarmMsgManage::addAiAlarmMsg(const QList &msgList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = msgList.begin(); - QVector deluuidVec; - QList aiMsgList; - while(itpos != msgList.end()) { - m_aiall.insert((*itpos)->uuid_base64,*itpos); - QVector uuidVec = (*itpos)->raw_alm_uuid; - addidtoid(uuidVec,(*itpos)->uuid_base64); - updatealarm(uuidVec,deluuidVec); - if((*itpos)->deleteFlag || (*itpos)->brokenFlag) - { - itpos++; - continue; - } - QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 - if(!isHaveAlm(uuidVec,almInfoList)) - { - m_delaydeal.append(*itpos); //延后处理 - itpos++; - continue; - } - QHash::iterator it = m_all.find((*itpos)->main_uuid_base64); - if(it != m_all.end()) - { - (*itpos)->main_state = (*it)->logic_state; - } - if(checkLookPerm(almInfoList)) - { - addaicount(almInfoList,(*itpos)->uuid_base64); - addaitolocation(almInfoList,(*itpos)->uuid_base64); - initaivideo(*itpos); - m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); - m_aiinfos.insert((*itpos)->uuid_base64,*itpos); - aiMsgList.append(*itpos); - } - itpos++; - } - if(deluuidVec.size()>0) - { - emit sigMsgRemove(deluuidVec); - } - if(aiMsgList.size()>0) - { - emit sigAiMsgAdd(aiMsgList); - } -} - -void CAlarmMsgManage::delAiAlarmMsg(const QList &uuidList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = uuidList.begin(); - QList aiuuidList; - while (itpos != uuidList.end()) { - QString aiuuid = *itpos; - //先在有权限的里面找,若有则不用去全部里面找 - QHash::iterator itinfos = m_aiinfos.find(aiuuid); - if(itinfos != m_aiinfos.end()) - { - m_nAlmTotal -= itinfos.value()->raw_alm_uuid.size(); - itinfos.value()->deleteFlag = true; - m_aiinfos.erase(itinfos); - aiuuidList.append(aiuuid); - }else - { - QHash::iterator itall = m_aiall.find(aiuuid); - if(itall != m_aiall.end()) - { - itall.value()->deleteFlag = true; - } - } - - //清除延迟处理的智能告警 - QList::iterator pos =m_delaydeal.begin(); - while(pos !=m_delaydeal.end()) { - if(aiuuid == (*pos)->uuid_base64) - { - pos = m_delaydeal.erase(pos); - break; - } - pos++; - } - itpos++; - } - if(aiuuidList.size()>0) - { - emit sigAiMsgRemove(aiuuidList); - } -} - -void CAlarmMsgManage::brokenAiAlarmMsg(const QList &uuidList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = uuidList.begin(); - QList aiuuidList; - while(itpos != uuidList.end()) - { - QString aiuuid = *itpos; - //先在有权限的告警中找 - QHash::iterator itinfos = m_aiinfos.find(aiuuid); - if(itinfos != m_aiinfos.end()) - { - m_nAlmTotal -= itinfos.value()->raw_alm_uuid.size(); - itinfos.value()->brokenFlag = true; - m_aiinfos.erase(itinfos); - aiuuidList.append(aiuuid); - }else - { - QHash::iterator itall = m_aiall.find(aiuuid); - if(itall != m_aiall.end()) - { - itall.value()->brokenFlag = true; - } - } - - //清除延迟处理的智能告警 - QList::iterator pos =m_delaydeal.begin(); - while(pos !=m_delaydeal.end()) { - if(aiuuid == (*pos)->uuid_base64) - { - pos = m_delaydeal.erase(pos); - break; - } - pos++; - } - itpos++; - } - if(aiuuidList.size()>0) - { - emit sigAiMsgRemove(aiuuidList); - } -} - -void CAlarmMsgManage::releaseAiAlarmMsg(const QList &uuidList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = uuidList.begin(); - QList aiuuidList; - QList m_listMsg; - while (itpos != uuidList.end()) { - QString aiuuid = *itpos; - QVector uuidVec; - QHash::iterator itinfos = m_aiinfos.find(aiuuid); - if(itinfos != m_aiinfos.end()) - { - uuidVec = itinfos.value()->raw_alm_uuid; - m_nAlmTotal -= uuidVec.size(); - for(int index(0);indexdeleteFlag == true || almPtr->releaseFlag == true) - { - continue; - } - - if(!m_listPermLocationId.contains(almPtr->location_id) || (!m_listPermRegionId.contains(almPtr->region_id) && almPtr->region_id != -1)) - { - continue; - } - - if(isInhibit(almPtr->key_id_tag)) - { - continue; - } - m_alarm.insert(almPtr->uuid_base64,almPtr); - m_listMsg.append(almPtr); - } - m_aiinfos.erase(itinfos); - aiuuidList.append(aiuuid); - } - - QHash::iterator itall = m_aiall.find(aiuuid); - if(itall != m_aiall.end()) - { - eraseaicount(aiuuid); - eraseidtoid(aiuuid); - eraseidtolocation(aiuuid); - m_aiall.erase(itall); - } - - //清除延迟处理的智能告警 - QList::iterator pos =m_delaydeal.begin(); - while (pos !=m_delaydeal.end()) { - if(aiuuid == (*pos)->uuid_base64) - { - pos = m_delaydeal.erase(pos); - break; - } - pos++; - } - itpos++; - } - if(aiuuidList.size()>0) - { - emit sigAiMsgRemove(aiuuidList); - } - - if(m_listMsg.size() > 0) - { - emit sigMsgArrivedToAi(m_listMsg); - } -} - -bool CAlarmMsgManage::getAiuuid(const QString &uuid, QString &aiuuid) -{ - QMutexLocker locker(mutex); - aiuuid = m_idToid.value(uuid,""); - if(aiuuid.isEmpty()) - { - return false; - } - return true; -} - -bool CAlarmMsgManage::isBelongAi(const QString &uuid) -{ - QMutexLocker locker(mutex); - if(m_idToid.value(uuid,"").isEmpty()) - { - return false; - } - return true; -} - -AlarmMsgPtr CAlarmMsgManage::getOnePlayerAlm(int num) -{ - QMutexLocker locker(mutex); - QList::iterator it = m_playerList.begin(); - - QStringList strAudioFileNames; - while (it != m_playerList.end()) { - strAudioFileNames.clear(); - if((*it)->deleteFlag || (*it)->releaseFlag) - { - it = m_playerList.erase(it); - }else if(ALM_ACT_SOUND != ((*it)->m_alarmAction & ALM_ACT_SOUND)) - { - it = m_playerList.erase(it); - }else - { - strAudioFileNames = (*it)->sound_file; - if(strAudioFileNames.isEmpty()) - { - it = m_playerList.erase(it); - }else if(num >= 0 && (*it)->m_playNum >= num) - { - strAudioFileNames.clear(); - it = m_playerList.erase(it); - }else - { - int fileNum = 0; - foreach (QString fileName, strAudioFileNames) - { - if(!fileName.isEmpty()) - { - fileName = m_strMediaPath + fileName; - if(QFile::exists(fileName)) - { - fileNum++; - } - } - } - if(fileNum == 0) - { - it = m_playerList.erase(it); - }else if(num < 0) - { - return *it; - }else - { - (*it)->m_playNum++; - return *it; - } - } - } - } - return Q_NULLPTR; -} - -AlarmMsgPtr CAlarmMsgManage::getOneSpeechAlm(int num) -{ - QMutexLocker locker(mutex); - QList::iterator it = m_playerList.begin(); - - QString alarmContent; - while (it != m_playerList.end()) { - alarmContent = QString(); - if((*it)->deleteFlag || (*it)->releaseFlag) - { - it = m_playerList.erase(it); - }else if(ALM_ACT_VOICE != ((*it)->m_alarmAction & ALM_ACT_VOICE)) - { - it = m_playerList.erase(it); - }else - { - alarmContent = (*it)->content; - if(alarmContent.isEmpty()) - { - it = m_playerList.erase(it); - }else if(num >= 0 && (*it)->m_playNum >= num) - { - alarmContent.clear(); - it = m_playerList.erase(it); - }else if(num < 0) - { - return *it; - }else - { - (*it)->m_playNum++; - return *it; - } - } - } - return Q_NULLPTR; -} - -void CAlarmMsgManage::eraseaicount(const QString &aiuuid) -{ - QHash::iterator it = m_aicount.find(aiuuid); - if(it != m_aicount.end()) - { - m_aicount.erase(it); - } -} - -void CAlarmMsgManage::eraseidtoid(const QString &aiuuid) -{ - QHash::iterator it = m_idToid.begin(); - - while (it != m_idToid.end()) { - if(aiuuid == it.value()) - { - it = m_idToid.erase(it); - continue; - } - it++; - } -} - -void CAlarmMsgManage::eraseidtolocation(const QString &aiuuid) -{ - QHash >::iterator it = m_aitolocation.find(aiuuid); - if(it != m_aitolocation.end()) - { - m_aitolocation.erase(it); - } -} - -bool CAlarmMsgManage::isHaveAlm(const QVector &uuidVec, QList &almInfoList) -{ - for(int x(0);x < uuidVec.count(); x++) - { - QHash::iterator it = m_all.find(uuidVec.at(x)); - if(it == m_all.end()) - { - return false; - } - almInfoList.append(*it); - } - return true; -} - -bool CAlarmMsgManage::checkLookPerm(const QList &almInfoList) -{ - QList::const_iterator it = almInfoList.begin(); - while (it != almInfoList.end()) { - qint32 location_id = (*it)->location_id; - qint32 region_id = (*it)->region_id; - if(m_listPermLocationId.contains(location_id) && (m_listPermRegionId.contains(region_id) || region_id == -1)) - { - return true; - } - it++; - } - return false; -} - -void CAlarmMsgManage::addidtoid(const QVector &uuidVec,const QString &aiuuid) -{ - for(int x(0);x < uuidVec.count();x++) - { - m_idToid[uuidVec.value(x)] = aiuuid; - } -} - -void CAlarmMsgManage::addaicount(const QList &almInfoList,const QString &aiuuid) -{ - int confirm = 0; - QList::const_iterator it = almInfoList.begin(); - while (it != almInfoList.end()) { - - if((*it)->logic_state == E_ALS_ALARM_CFM || (*it)->logic_state == E_ALS_RETURN_CFM || - (*it)->logic_state == E_ALS_ALARM_CFM_DEL || (*it)->logic_state == E_ALS_RETURN_CFM_DEL || (*it)->logic_state == ALS_EVT_ONLY) - { - confirm++; - } - it++; - } - SAiConfirm aiConfirm; - aiConfirm.nConfirm = confirm; - aiConfirm.nTotal = almInfoList.size(); - m_aicount.insert(aiuuid,aiConfirm); -} - -void CAlarmMsgManage::addaitolocation(const QList &almInfoList,const QString &aiuuid) -{ - QHash >::iterator it =m_aitolocation.find(aiuuid); - if(it != m_aitolocation.end()) - { - m_aitolocation.erase(it); - } - QList locationList; - QList::const_iterator pos = almInfoList.begin(); - while (pos != almInfoList.end()) { - if(!locationList.contains((*pos)->location_id)) - { - locationList.append((*pos)->location_id); - } - pos++; - } - m_aitolocation.insert(aiuuid,locationList); -} - -void CAlarmMsgManage::initaivideo(AiAlarmMsgPtr msg) -{ - AlarmMsgPtr ptr = m_all.value(msg->main_uuid_base64,NULL); - if(ptr != NULL) - { - msg->m_needVideoAlm = ptr->m_needVideoAlm; - msg->app_id = ptr->app_id; - msg->key_id_tag = ptr->key_id_tag; - msg->m_tagname_type = ptr->m_tagname_type; - } -} - -//<添加智能告警时,需要删除此条智能告警下还存在一级节点上的原始告警 -void CAlarmMsgManage::updatealarm(QVector &uuidVec,QVector &deluuidVec) -{ - for(int index(0);index::iterator it =m_alarm.find(uuidVec.at(index)); - if(it != m_alarm.end()) - { - m_alarm.remove(uuidVec.at(index)); - deluuidVec.append(uuidVec.at(index)); - } - } -} - -void CAlarmMsgManage::almStats(const AlarmMsgPtr &msg, int addOrSub) -{ - if(addOrSub == 1) - { - almAddStats(msg); - }else - { - almSubStats(msg); - } -} - -void CAlarmMsgManage::almAddStats(const AlarmMsgPtr &msg) -{ - devDevGTotAlmAddStats(msg); - devDevGAddStats(msg); - locAddStats(msg); -} - -void CAlarmMsgManage::almSubStats(const AlarmMsgPtr &msg) -{ - devDevGTotAlmSubStats(msg); - devDevGSubStats(msg); - locSubStats(msg); -} - -void CAlarmMsgManage::devDevGTotAlmAddStats(const AlarmMsgPtr &msg) -{ - - int dCount = m_alarmDeviceStatistical.value(msg->device, 0);//设备告警数量 - int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 - - ++dgCount; // +1 - ++dCount; // +1 - - if(dCount <= 0) - { - m_alarmDeviceStatistical.remove(msg->device); - } - else - { - m_alarmDeviceStatistical.insert(msg->device, dCount); - } - if(dgCount <= 0) - { - m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); - } - else - { - m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); - } -} - -void CAlarmMsgManage::devDevGTotAlmSubStats(const AlarmMsgPtr &msg) -{ - int dCount = m_alarmDeviceStatistical.value(msg->device, 0); //设备告警数量 - int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 - - --dgCount; - --dCount; - - if(dCount <= 0) - { - m_alarmDeviceStatistical.remove(msg->device); - } - else - { - m_alarmDeviceStatistical.insert(msg->device, dCount); - } - if(dgCount <= 0) - { - m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); - } - else - { - m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); - } -} - -void CAlarmMsgManage::devDevGAddStats(const AlarmMsgPtr &msg) -{ - QHash >::iterator posit = m_alarmDevPriority.find(msg->device); - if(posit != m_alarmDevPriority.end()) - { - QMap &priority = posit.value(); - QMap::iterator itor =priority.find(msg->priority); - if(itor != priority.end()) - itor.value()++; - else - priority.insert(msg->priority,1); - }else - { - QMap priority; - priority.insert(msg->priority,1); - m_alarmDevPriority.insert(msg->device,priority); - } - updataDevGroupByDev(msg->dev_group_tag,msg->device); -} - -void CAlarmMsgManage::devDevGSubStats(const AlarmMsgPtr &msg) -{ - QHash >::iterator posit = m_alarmDevPriority.find(msg->device); - if(posit != m_alarmDevPriority.end()) - { - QMap &priority = posit.value(); - QMap::iterator itor =priority.find(msg->priority); - if(itor != priority.end()) - itor.value()--; - } - updataDevGroupByDev(msg->dev_group_tag,msg->device); -} - -void CAlarmMsgManage::locAddStats(const AlarmMsgPtr &msg) -{ - QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); - if(posit != m_alarmLPAlm.end()) - { - QMap &priority = posit.value(); - QMap::iterator itor =priority.find(msg->priority); - if(itor != priority.end()) - itor.value()++; - else - priority.insert(msg->priority,1); - }else - { - QMap priority; - priority.insert(msg->priority,1); - m_alarmLPAlm.insert(msg->location_id,priority); - } -} - -void CAlarmMsgManage::locSubStats(const AlarmMsgPtr &msg) -{ - QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); - if(posit != m_alarmLPAlm.end()) - { - QMap &priority = posit.value(); - QMap::iterator itor =priority.find(msg->priority); - if(itor != priority.end()) - { - itor.value()--; - } - } -} - -void CAlarmMsgManage::addNotConfirmAlm(int locId, const QString &devg, const QString &uuid) -{ - QHash > >::iterator it =m_alarmLNCAlm.find(locId); - if(it != m_alarmLNCAlm.end()) - { - QMap > &devgMap = it.value(); - QMap >::iterator pos = devgMap.find(devg); - if(pos != devgMap.end()) - { - pos.value().insert(uuid); - }else - { - QSet uuidSet; - uuidSet.insert(uuid); - devgMap[devg] = uuidSet; - } - }else - { - QMap > devgMap; - QSet uuidSet; - uuidSet.insert(uuid); - devgMap[devg] = uuidSet; - m_alarmLNCAlm[locId] = devgMap; - } -} - -void CAlarmMsgManage::delNotConfirmAlm(int locId, const QString &devg, const QString &uuid) -{ - QHash > >::iterator it =m_alarmLNCAlm.find(locId); - if(it != m_alarmLNCAlm.end()) - { - QMap > &devgMap = it.value(); - QMap >::iterator pos = devgMap.find(devg); - if(pos != devgMap.end()) - { - pos.value().remove(uuid); - } - } -} - -QString CAlarmMsgManage::queryLocationDesc(QString &aiuuid) -{ - QMutexLocker locker(mutex); - QString desc = QString(); - QList listLocationId = m_aitolocation.value(aiuuid); - for(int index(0);indexqueryLocationDesc(listLocationId.at(index)); - desc +=" "; - } - return desc; -} - -QString CAlarmMsgManage::queryConfirm(const QString &aiuuid) -{ - QMutexLocker locker(mutex); - SAiConfirm confirm = m_aicount.value(aiuuid); - QString st = QString("%1/%2").arg(confirm.nConfirm).arg(confirm.nTotal); - return st; -} - -int CAlarmMsgManage::queryAiTotal(const QString &aiuuid) -{ - QMutexLocker locker(mutex); - SAiConfirm confirm = m_aicount.value(aiuuid); - return confirm.nTotal; -} - -void CAlarmMsgManage::getAlarmInfo(QList &listAlarm, QList &listaiAlarm) -{ - QMutexLocker locker(mutex); - listAlarm = m_alarm.values(); - listaiAlarm = m_aiinfos.values(); -} - -QList CAlarmMsgManage::getAlarmPtrByuuid(const QVector &uuidVec) -{ - QMutexLocker locker(mutex); - QList list; - for(int index(0);index CAlarmMsgManage::getalmuuidByAiuuid(const QString &aiuuid) -{ - QList uuidList; - QHash::iterator it = m_idToid.begin(); - while(it != m_idToid.end()) { - if(it.value() == aiuuid) - { - uuidList.append(it.key()); - } - it++; - } - return uuidList; -} - -int CAlarmMsgManage::getAlmTotal() -{ - QMutexLocker locker(mutex); - return m_nAlmTotal + m_alarm.size(); -} - -int CAlarmMsgManage::getAiCount() -{ - QMutexLocker locker(mutex); - return m_aiinfos.size(); -} - -void CAlarmMsgManage::initAlarm() -{ - QHash::const_iterator itpos = m_all.begin(); - while (itpos != m_all.end()) { - - if(isInhibit((*itpos)->key_id_tag)) - { - itpos++; - continue; - } - if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) - { - itpos++; - continue ; - } - if((*itpos)->deleteFlag == true || (*itpos)->releaseFlag == true) //已经删除的不会保存到中 - { - itpos++; - continue ; - } - - if(E_ALS_ALARM == (*itpos)->logic_state || E_ALS_RETURN == (*itpos)->logic_state )//未确认数量(界面显示未确认) - { - addNotConfirmAlm((*itpos)->location_id,(*itpos)->dev_group_tag,(*itpos)->uuid_base64); - ++m_nNDelComAlarmCount; - } - updateMsgAction((*itpos)); - m_infos.insert((*itpos)->uuid_base64, (*itpos)); - //更新告警统计 - almStats((*itpos),1); - //更新未聚类但是需要展示的原始告警 - QHash::iterator it = m_idToid.find((*itpos)->uuid_base64); - if(it == m_idToid.end()) - { - m_alarm.insert((*itpos)->uuid_base64,(*itpos)); - } - itpos++; - } -} - -void CAlarmMsgManage::initAiAlarm() -{ - QHash::const_iterator itpos = m_aiall.begin(); - while(itpos != m_aiall.end()) - { - QVector uuidVec = (*itpos)->raw_alm_uuid; - addidtoid(uuidVec,(*itpos)->uuid_base64); //记录原始告警uuid和智能告警uuid键值对 ,一直到release - QVector deluuidVec; - updatealarm(uuidVec,deluuidVec);//不可删除 //更新智能告警窗上的未聚类的原始告警,防止由于先后顺序导致显示出错 - if((*itpos)->deleteFlag || (*itpos)->brokenFlag) - { - itpos++; - continue; - } - //检查此智能告警下的原始告警是否完整 - //若完整则继续执行 - //不完整(此处指的是智能告警先到,原始告警未到的情况,并非告警服务通知的不完整)则延时处理 ,延时处理的不需要调用addidtoid()和updatealarm() - QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 - if(!isHaveAlm(uuidVec,almInfoList)) - { - m_delaydeal.append(*itpos); //延后处理 - itpos++; - continue; - } - //检查是否具有权限 - if(checkLookPerm(almInfoList)) - { - addaicount(almInfoList,(*itpos)->uuid_base64); - addaitolocation(almInfoList,(*itpos)->uuid_base64); - initaivideo(*itpos); - m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); - m_aiinfos.insert((*itpos)->uuid_base64,*itpos); - } - itpos++; - } -} - -void CAlarmMsgManage::insertAudioCues(const AlarmMsgPtr &info) -{ - bool insertResult = false; - //LOGDEBUG("insertAudioCues %s",info->content.toStdString().c_str()); - if(!m_playerList.isEmpty()) - { - for(int nIndex(m_playerList.size() - 1); nIndex >= 0; --nIndex) - { - if(info->priorityOrder > m_playerList[nIndex]->priorityOrder) - { - m_playerList.insert(nIndex + 1, info); - insertResult = true; - break; - } - } - } - if(!insertResult) - { - if(m_playerList.isEmpty()) - { - m_playerList.append(info); - } - else - { - m_playerList.prepend(info); - } - } - if(m_playerList.count() >= MAX_AUDIO_ALM_COUNT) - { - m_playerList.removeLast(); - } -} - -void CAlarmMsgManage::removeAudioCues(const AlarmMsgPtr &info) -{ - QList::iterator it = m_playerList.begin(); - while (it != m_playerList.end()) - { - if(info->uuid_base64 == (*it)->uuid_base64) - { - m_playerList.erase(it); - break; - } - ++it; - } -} - -void CAlarmMsgManage::setReadFlag() -{ - if(!m_playerList.isEmpty()) - { - emit sigReadFlag(); - } -} - -CAlarmMsgManage::~CAlarmMsgManage() -{ - LOGDEBUG("CAlarmMsgManage::~CAlarmMsgManage()"); -} - -void CAlarmMsgManage::destory() -{ - { - QMutexLocker locker(mutex); - m_infos.clear(); - m_all.clear(); - m_alarmDeviceStatistical.clear(); - m_alarmDeviceGroupStatistical.clear(); - delete m_rtdbAlarmActionAccess; - delete m_rtdbLocationDescriptionAccess; - delete m_rtdbAppDescriptionAccess; - } - delete mutex; - pInstance = NULL; - - deleteLater(); -} - -void CAlarmMsgManage::initialize() -{ - release(); -} - -void CAlarmMsgManage::release() -{ - QMutexLocker locker(mutex); - m_infos.clear(); - m_alarmDeviceStatistical.clear(); - m_alarmDeviceGroupStatistical.clear(); - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - m_listMsgAddCache.clear(); - m_inhibitFilter.clear(); - m_aiinfos.clear(); - m_aicount.clear(); - m_alarm.clear(); - m_idToid.clear(); - m_aitolocation.clear(); - //根据需求 - m_all.clear(); - m_aiall.clear(); - - m_nNDelComAlarmCount = 0; - m_nAlmNum = 0; - m_nAlmTotal = 0; - m_alarmDevPriority.clear(); - m_alarmDGPDev.clear(); - m_alarmLPAlm.clear(); - m_delaydeal.clear(); - m_playerList.clear(); - loadPermInfo(); -} - -QList CAlarmMsgManage::getListAlarmInfo() -{ - //不需要清空1秒缓存 - QMutexLocker locker(mutex); - return m_infos.values(); -} - -QHash CAlarmMsgManage::getDeviceStatisticalInfo() -{ - QMutexLocker locker(mutex); - - return m_alarmDeviceGroupStatistical; -} - -int CAlarmMsgManage::deviceGroupAlarmStatistical(const QString &deviceGroup) -{ - QMutexLocker locker(mutex); - if(deviceGroup.isEmpty()) - { - return 0; - } - - return m_alarmDeviceGroupStatistical.value(deviceGroup, 0); -} - -int CAlarmMsgManage::getAlarmTotalSize() -{ - QMutexLocker locker(mutex); - return m_infos.size(); -} - -int CAlarmMsgManage::getUnConfirmSize() -{ - QMutexLocker locker(mutex); - return m_nNDelComAlarmCount; -} - -void CAlarmMsgManage::output() -{ - QMutexLocker locker(mutex); - LOGDEBUG("内存告警数量展示:所有原始告警:%d,所有展示的原始告警:%d,所有智能告警:%d,所有展示的智能告警:%d,所有未聚合的原始告警:%d",m_all.size(),m_infos.size(),m_aiall.size(),m_aiinfos.size(),m_alarm.size()); -} - - -void CAlarmMsgManage::addAlarmMsg(const QList &msgList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = msgList.begin(); - while (itpos != msgList.end()) { - m_all.insert((*itpos)->uuid_base64,(*itpos)); - if(isInhibit((*itpos)->key_id_tag)) - { - itpos++; - continue; - } - if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) - { - itpos++; - continue ; - } - if((*itpos)->deleteFlag == true || (*itpos)->releaseFlag == true) //已经删除的不会保存到中 - { - itpos++; - continue ; - } - if(E_ALS_ALARM == (*itpos)->logic_state || E_ALS_RETURN == (*itpos)->logic_state )//未确认数量(界面显示未确认) - { - addNotConfirmAlm((*itpos)->location_id,(*itpos)->dev_group_tag,(*itpos)->uuid_base64); - ++m_nNDelComAlarmCount; - } - updateMsgAction(*itpos); - m_infos.insert((*itpos)->uuid_base64, (*itpos)); - //更新告警统计 - almStats((*itpos),1); - //更新未聚类但是需要展示的原始告警 - QHash::iterator it = m_idToid.find((*itpos)->uuid_base64); - if(it == m_idToid.end()) - { - m_alarm.insert((*itpos)->uuid_base64,(*itpos)); - } - itpos++; - } - //设置标志可读 - setReadFlag(); -} - - -void CAlarmMsgManage::addAlarmToAllInfo(const QList &msgList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = msgList.begin(); - while (itpos != msgList.end()) { - m_all.insert((*itpos)->uuid_base64,(*itpos)); - itpos++; - } - -} - -void CAlarmMsgManage::addAlarmCacheMsg(const QList &msgList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = msgList.begin(); - while (itpos != msgList.end()) { - if(isInhibit((*itpos)->key_id_tag)) - { - itpos++; - continue; - } - if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) - { - itpos++; - continue ; - } - if((*itpos)->deleteFlag == true) - { - itpos++; - continue ; - } - m_listMsgAddCache.append(*itpos); - itpos++; - } -} -//不用考虑事件 因为事件不会发送过来 默认事件是已确认已删除状态 -void CAlarmMsgManage::confirmAlarmMsg(const QList &uuidList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = uuidList.begin(); - while (itpos != uuidList.end()) { - QString uuid = *itpos; - AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); - if(!oldMsg.isNull()) - { - removeAudioCues(oldMsg); - if(E_ALS_ALARM == oldMsg->logic_state) - { - oldMsg->logic_state = E_ALS_ALARM_CFM; - --m_nNDelComAlarmCount; - } - else if(E_ALS_RETURN == oldMsg->logic_state) - { - oldMsg->logic_state = E_ALS_RETURN_CFM; - --m_nNDelComAlarmCount; - } - delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); - }else - { - AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); - if(!oldMsg_.isNull()) - { - if(E_ALS_ALARM == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_ALARM_CFM; - } - else if(E_ALS_RETURN == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_RETURN_CFM; - } - else if(E_ALS_ALARM_DEL == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; - } - else if(E_ALS_RETURN_DEL == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; - } - } - } - //确认告警时更新告警确认数量(性能优化:事实证明,当数据量很大时,使用迭代器的效率是contains()的几十倍,随着数据量的增大倍数增大----数据很少可以忽略) - QHash::iterator it = m_idToid.find(uuid); - if(it != m_idToid.end()) - { - QString aiuuid = m_idToid.value(uuid); - SAiConfirm confirm = m_aicount.value(aiuuid); - confirm.nConfirm++; - m_aicount[aiuuid]=confirm; - } - itpos++; - } - //设置标志可读 - setReadFlag(); -} - -int CAlarmMsgManage::removeAlarmMsg(const QList &uuidList) -{ - QMutexLocker locker(mutex); - int size = 0;//删除的个数 - QVector deluuidVec; - QList::const_iterator itpos = uuidList.begin(); - while (itpos != uuidList.end()) { - QString uuid = *itpos; - AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); - if(!oldMsg.isNull()) - { - if(oldMsg->deleteFlag) - { - itpos++; - continue; - } - if(E_ALS_ALARM == oldMsg->logic_state) - { - delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); - --m_nNDelComAlarmCount; - oldMsg->logic_state = E_ALS_ALARM_DEL; - } - else if(E_ALS_ALARM_CFM == oldMsg->logic_state) - { - oldMsg->logic_state = E_ALS_ALARM_CFM_DEL; - } - else if(E_ALS_RETURN == oldMsg->logic_state) - { - delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); - --m_nNDelComAlarmCount; - oldMsg->logic_state = E_ALS_RETURN_DEL; - } - else if(E_ALS_RETURN_CFM == oldMsg->logic_state) - { - oldMsg->logic_state = E_ALS_RETURN_CFM_DEL; - } - - oldMsg->deleteFlag = true; - almStats(oldMsg,0); - m_infos.remove(uuid); - size++; - }else - { - AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); - if(!oldMsg_.isNull()) - { - if(oldMsg_->deleteFlag) - { - itpos++; - continue; - } - if(E_ALS_ALARM == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_ALARM_DEL; - } - else if(E_ALS_ALARM_CFM == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; - } - else if(E_ALS_RETURN == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_RETURN_DEL; - } - else if(E_ALS_RETURN_CFM == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; - } - oldMsg_->deleteFlag = true; - } - } - //从m_alarm中删除未聚类但有删除标志的告警 - QHash::iterator it = m_alarm.find(uuid); - if(it != m_alarm.end()) - { - m_alarm.erase(it); - deluuidVec.push_back(uuid); - } - itpos++; - } - if(deluuidVec.size()>0) - { - emit sigMsgRemove(deluuidVec);//通知智能告警模型删除1级节点上的未聚类原始告警 - } - //设置标志可读 - setReadFlag(); - return size; -} - -void CAlarmMsgManage::releaseAlarmMsg(const QList &uuidList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = uuidList.begin(); - while (itpos != uuidList.end()) { - QString uuid = *itpos; - AlarmMsgPtr oldMsg = m_all.value(uuid, NULL); - if(!oldMsg.isNull()) - { - oldMsg->releaseFlag =true; - m_all.remove(uuid); - } - itpos++; - } - //设置标志可读 - setReadFlag(); -} - -void CAlarmMsgManage::linkWave2AlmMsg(const QList &uuidList, const QString &waveFile) -{ - QMutexLocker locker(mutex); - for(int index(0);index::iterator it = m_all.find(uuidList.at(index)); - if(it != m_all.end()) - { - (*it)->wave_file = waveFile; - }else - { - LOGERROR("linkWave2AlmMsg()未找到uuid为[%s]的告警,链接录波文件为:[%s],请自主查看!",uuidList.at(index).toStdString().c_str(),waveFile.toStdString().c_str()); - } - } -} - -void CAlarmMsgManage::removeAlarmMsgByDomainID(const int &domainId) -{ - QMutexLocker locker(mutex); - /* 清除全缓存 - */ - QHash::iterator pos = m_all.begin(); - while (pos != m_all.end()) { - if(domainId == (*pos)->domain_id) - { - pos = m_all.erase(pos); - continue; - } - pos++; - } - /* 清除有权限和未禁止的缓存 - */ - QHash::iterator it = m_infos.begin(); - while (it != m_infos.end()) - { - if(domainId == (*it)->domain_id) - { - if(E_ALS_ALARM == (*it)->logic_state || E_ALS_RETURN == (*it)->logic_state) - { - delNotConfirmAlm((*it)->location_id,(*it)->dev_group_tag,(*it)->uuid_base64); - --m_nNDelComAlarmCount; - } - removeAudioCues(it.value()); - almStats((*it),0); - it = m_infos.erase(it); - continue; - } - it++; - } - //清空告警缓存(每秒更新) - QList::iterator itpos =m_listMsgAddCache.begin(); - while (itpos != m_listMsgAddCache.end()) { - if((*itpos)->domain_id == domainId) - { - itpos =m_listMsgAddCache.erase(itpos); - continue; - } - itpos++; - } - - //清空 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗) - QHash::iterator itor = m_alarm.begin(); - while(itor != m_alarm.end()) - { - if(domainId == (*itor)->domain_id) - { - itor = m_alarm.erase(itor); - continue; - } - itor++; - } -} - -void CAlarmMsgManage::updateMsgAction(const QList &msgList) -{ - QMutexLocker locker(mutex); - QList::const_iterator itpos = msgList.begin(); - while (itpos != msgList.end()) { - if(isInhibit((*itpos)->key_id_tag)) - { - itpos++; - continue ; - } - if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) - { - itpos++; - continue ; - } - if((*itpos)->deleteFlag || (*itpos)->releaseFlag) - { - itpos++; - continue ; - } - if((*itpos)->logic_state == E_ALS_ALARM || (*itpos)->logic_state == E_ALS_RETURN) - { - int alarmAction = queryAlarmAction((*itpos)->priority); - (*itpos)->m_alarmAction = alarmAction; - if(ALM_ACT_PUSH_PIC == (alarmAction & ALM_ACT_PUSH_PIC) && !(*itpos)->graph_name.isEmpty()) - { - //第1位,推画面 - QString alarmInfo; - //< 等级 - alarmInfo.append(QString::number((*itpos)->priorityOrder) + QString(",")); - //< 时间 - alarmInfo.append(QDateTime::fromMSecsSinceEpoch((*itpos)->time_stamp).toString("yyyy-MM-dd hh:mm:ss") + QString(",")); - //< 车站 - alarmInfo.append(queryLocationDescription((*itpos)->location_id) + QString(",")); - //< 应用 - alarmInfo.append(queryAppDescription((*itpos)->app_id) + QString(",")); - //< 内容 - alarmInfo.append((*itpos)->content + QString(",")); - //< 画面名称 - alarmInfo.append((*itpos)->graph_name); - - pushGraphics(alarmInfo); - } - if(ALM_ACT_PRINT == (alarmAction & ALM_ACT_PRINT)) - { - //第2位,打印 - print(); - } - if(ALM_ACT_SHORT_MSG == (alarmAction & ALM_ACT_SHORT_MSG)) - { - //第3位,短消息 - shortMessage(); - } - if(ALM_ACT_SOUND == (alarmAction & ALM_ACT_SOUND) || ALM_ACT_VOICE == (alarmAction & ALM_ACT_VOICE)) - { - //第4位,声音告警 第9位 语音告警 - //emit sigInsertAudioCues(*itpos, (*itpos)->sound_file); - insertAudioCues(*itpos); - } - if(ALM_ACT_PA == (alarmAction & ALM_ACT_PA)) - { - //第5位,广播告警 - paNotify(); - } - } - itpos++; - } -} - -void CAlarmMsgManage::updateMsgAction(const AlarmMsgPtr &msg) -{ - if(msg->logic_state == E_ALS_ALARM) - { - int alarmAction = queryAlarmAction(msg->priority); - msg->m_alarmAction = alarmAction; - if(ALM_ACT_PUSH_PIC == (alarmAction & ALM_ACT_PUSH_PIC) && !msg->graph_name.isEmpty()) - { - //第1位,推画面 - QString alarmInfo; - //< 等级 - alarmInfo.append(QString::number(msg->priorityOrder) + QString(",")); - //< 时间 - alarmInfo.append(QDateTime::fromMSecsSinceEpoch(msg->time_stamp).toString("yyyy-MM-dd hh:mm:ss") + QString(",")); - //< 车站 - alarmInfo.append(queryLocationDescription(msg->location_id) + QString(",")); - //< 应用 - alarmInfo.append(queryAppDescription(msg->app_id) + QString(",")); - //< 内容 - alarmInfo.append(msg->content + QString(",")); - //< 画面名称 - alarmInfo.append(msg->graph_name); - - pushGraphics(alarmInfo); - } - if(ALM_ACT_PRINT == (alarmAction & ALM_ACT_PRINT)) - { - //第2位,打印 - print(); - } - if(ALM_ACT_SHORT_MSG == (alarmAction & ALM_ACT_SHORT_MSG)) - { - //第3位,短消息 - shortMessage(); - } - if(ALM_ACT_SOUND == (alarmAction & ALM_ACT_SOUND) || ALM_ACT_VOICE == (alarmAction & ALM_ACT_VOICE)) - { - //第4位,声音告警 第9位 语音告警 - //emit sigInsertAudioCues(msg, msg->sound_file); - insertAudioCues(msg); - } - if(ALM_ACT_PA == (alarmAction & ALM_ACT_PA)) - { - //第5位,广播告警 - paNotify(); - } - } -} - -void CAlarmMsgManage::pushGraphics(const QString &info) -{ - emit sigAlarmPushGraph(info); -} - -void CAlarmMsgManage::print() -{ - -} - -void CAlarmMsgManage::shortMessage() -{ - -} - -void CAlarmMsgManage::sounds(const AlarmMsgPtr info, const QStringList soundFileNames) -{ - //播放告警音频 - if(!soundFileNames.isEmpty()) - { - emit sigInsertAudioCues(info, soundFileNames); - } -} - -void CAlarmMsgManage::stopSounds(const AlarmMsgPtr info) -{ - removeAudioCues(info); -} - -void CAlarmMsgManage::paNotify() -{ - -} - -bool CAlarmMsgManage::isBindMediaPlayer() -{ - return isSignalConnected(QMetaMethod::fromSignal(&CAlarmMsgManage::sigReadFlag)); -} - -void CAlarmMsgManage::msgArrived() -{ - QMutexLocker locker(mutex); - QList m_ailistMsg; //需要在智能告警窗展示 - QList m_listMsg; //需要在原始告警窗展示 - m_listMsg.clear(); - for(int num(0);numkey_id_tag)) - { - continue ; - } - if(!m_listPermLocationId.contains(m_listMsgAddCache.at(num)->location_id) || (!m_listPermRegionId.contains(m_listMsgAddCache.at(num)->region_id) && m_listMsgAddCache.at(num)->region_id != -1)) - { - continue ; - } - if(m_listMsgAddCache.at(num)->deleteFlag || m_listMsgAddCache.at(num)->releaseFlag) - { - continue ; - } - - if(E_ALS_ALARM == m_listMsgAddCache.at(num)->logic_state || E_ALS_RETURN == m_listMsgAddCache.at(num)->logic_state )//未删除未确认数量(界面显示未确认) - { - addNotConfirmAlm(m_listMsgAddCache.at(num)->location_id,m_listMsgAddCache.at(num)->dev_group_tag,m_listMsgAddCache.at(num)->uuid_base64); - ++m_nNDelComAlarmCount; - } - updateMsgAction(m_listMsgAddCache.at(num)); - m_infos.insert(m_listMsgAddCache.at(num)->uuid_base64, m_listMsgAddCache.at(num)); - m_listMsg.append(m_listMsgAddCache.at(num)); - //更新告警数量 - almStats(m_listMsgAddCache.at(num),1); - //更新未聚类但是需要展示的原始告警 - QHash::iterator it = m_idToid.find(m_listMsgAddCache.at(num)->uuid_base64); - if(it == m_idToid.end()) - { - m_alarm.insert(m_listMsgAddCache.at(num)->uuid_base64,m_listMsgAddCache.at(num)); - m_ailistMsg.append(m_listMsgAddCache.at(num)); - } - } - m_listMsgAddCache.clear(); - if(m_listMsg.size()>0) - { - emit sigMsgArrived(m_listMsg); - m_listMsg.clear(); - } - if(m_ailistMsg.size()>0) - { - emit sigMsgArrivedToAi(m_ailistMsg); - m_ailistMsg.clear(); - } - //设置标志可读 - setReadFlag(); -} - -void CAlarmMsgManage::dealDelayAi() -{ - QMutexLocker locker(mutex); - QList delaydeal = m_delaydeal; - m_delaydeal.clear(); - //QVector deluuidVec; - QList aiMsgList; - if(delaydeal.size() > 0) - { - for(int index(0);index uuidVec = delaydeal.at(index)->raw_alm_uuid; - if(delaydeal.at(index)->deleteFlag || delaydeal.at(index)->brokenFlag) - { - continue; - } - QList almInfoList; - if(!isHaveAlm(uuidVec,almInfoList)) - { - m_delaydeal.append(delaydeal.at(index)); //延后处理 - continue; - } - QHash::iterator it = m_all.find(delaydeal.at(index)->main_uuid_base64); - if(it != m_all.end()) - { - delaydeal.at(index)->main_state = (*it)->logic_state; - } - if(checkLookPerm(almInfoList)) - { - addaicount(almInfoList,delaydeal.at(index)->uuid_base64); - addaitolocation(almInfoList,delaydeal.at(index)->uuid_base64); - initaivideo(delaydeal.at(index)); - if(delaydeal.at(index)->deleteFlag != true && delaydeal.at(index)->brokenFlag != true) - { - m_nAlmTotal += delaydeal.at(index)->raw_alm_uuid.size(); - m_aiinfos.insert(delaydeal.at(index)->uuid_base64,delaydeal.at(index)); - aiMsgList.append(delaydeal.at(index)); - } - } - } - if(aiMsgList.size()>0) - { - emit sigAiMsgAdd(aiMsgList); - } - } -} - -int CAlarmMsgManage::queryAlarmAction(const int &priority) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbAlarmActionAccess); - kbd_dbms::CVarType value; - m_rtdbAlarmActionAccess->getColumnValueByKey((void*)&priority, "alarm_actions",value); - return value.toInt(); -} - -QString CAlarmMsgManage::queryLocationDescription(int id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbLocationDescriptionAccess); - kbd_dbms::CVarType value; - m_rtdbLocationDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); - return value.c_str(); -} - -QString CAlarmMsgManage::queryAppDescription(int id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbAppDescriptionAccess); - kbd_dbms::CVarType value; - m_rtdbAppDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); - return value.c_str(); -} - -void CAlarmMsgManage::loadPermInfo() -{ - m_listPermLocationId = CAlarmBaseData::instance()->getPermLocationIdList(); - m_listPermRegionId = CAlarmBaseData::instance()->getPermRegionIdList(); -} +#include "CAlarmMsgManage.h" +#include +#include +#include +#include +#include "CAlarmDataCollect.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include +#include "perm_mng_api/PermMngApi.h" + +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_logger_api/logger.h" +#include "CAlarmBaseData.h" + +using namespace kbd_public; +using namespace std; + +CAlarmMsgManage *CAlarmMsgManage::pInstance = NULL; +CAlarmMsgManage *CAlarmMsgManage::instance() +{ + if(pInstance == NULL) + { + pInstance = new CAlarmMsgManage(); + } + return pInstance; +} + +CAlarmMsgManage::CAlarmMsgManage() + : QObject(), + m_nNDelComAlarmCount(0), + m_nAlmNum(0), + m_nAlmTotal(0) +{ + mutex = new QMutex(); + QDir dir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("sound"); + m_strMediaPath = dir.absolutePath() + QDir::separator(); + + m_infos.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + m_listMsgAddCache.clear(); + m_inhibitFilter.clear(); + m_aiinfos.clear(); + m_aicount.clear(); + m_alarm.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + //根据需求 + m_all.clear(); + m_aiall.clear(); + + m_rtdbAlarmActionAccess = new kbd_dbms::CRdbAccess(); + m_rtdbAlarmActionAccess->open("base", "alarm_level_define"); + + m_rtdbLocationDescriptionAccess = new kbd_dbms::CRdbAccess(); + m_rtdbLocationDescriptionAccess->open("base", "sys_model_location_info"); + + m_rtdbAppDescriptionAccess = new kbd_dbms::CRdbAccess(); + m_rtdbAppDescriptionAccess->open("base", "sys_model_app_info"); + + loadPermInfo(); +} + +void CAlarmMsgManage::refreshCache() +{ + QMutexLocker locker(mutex); + m_listMsgAddCache.clear(); +} + +bool CAlarmMsgManage::ifInhibit(const QString &tag_name) +{ + QMutexLocker locker(mutex); + for(int index(0);indexkey_id_tag == tag_name) + { + return true; + } + } + return false; +} + +bool CAlarmMsgManage::isInhibit(const QString &tag_name) +{ + for(int index(0);indexkey_id_tag == tag_name) + { + return true; + } + } + return false; +} + +void CAlarmMsgManage::addInhibitAlm(const AlarmMsgPtr &info) +{ + QMutexLocker locker(mutex); + m_inhibitFilter.append(info); +} + +void CAlarmMsgManage::removeInhibitTag(const QString &tag_name) +{ + QMutexLocker locker(mutex); + for(int index(m_inhibitFilter.size()-1);index >= 0;index--) + { + if(m_inhibitFilter[index]->key_id_tag == tag_name) + { + m_inhibitFilter.removeAt(index); + } + } +} + +QMap CAlarmMsgManage::getDevAlarm(const QString &device) +{ + // QMutexLocker locker(mutex); + QMap alarm; + alarm.clear(); + return m_alarmDevPriority.value(device,alarm); +} + +QMap > CAlarmMsgManage::getDevGroupPriorityDevNum(const QString &deviceGroup) +{ + QMutexLocker locker(mutex); + QMap > alarm; + alarm.clear(); + + return m_alarmDGPDev.value(deviceGroup,alarm); +} + +QHash > CAlarmMsgManage::getLocAlmInfo() +{ + QMutexLocker locker(mutex); + return m_alarmLPAlm; +} + +void CAlarmMsgManage::updataDevGroupByDev(QString devGroup, QString device) +{ + QHash >::iterator it = m_alarmDevPriority.find(device); + int devMaxPriority =-1;//最高优先级 + if(it != m_alarmDevPriority.end()) + { + QMap::iterator itor= --it.value().end(); + + for(;itor!= --it.value().begin();itor--) + { + if(itor.value()>0) + { + devMaxPriority = itor.key(); + break; + } + } + } + QHash > >::iterator pos = m_alarmDGPDev.find(devGroup); + if(pos != m_alarmDGPDev.end()) + { + QMap > &priorityMap = pos.value(); + QMap >::iterator itor = priorityMap.begin(); + + while(itor != priorityMap.end()) { + QList &list = itor.value(); + if(list.contains(device)) + { + list.removeOne(device); + } + itor++; + } + if(devMaxPriority == -1) + return ; + itor =priorityMap.find(devMaxPriority); + if(itor != priorityMap.end()) + { + QList &devList = itor.value(); + if(!devList.contains(device)) + { + devList.append(device); + } + }else + { + QList list; + list.append(device); + priorityMap.insert(devMaxPriority,list); + } + }else + { + QList list; + list.append(device); + QMap > priorityMap; + priorityMap.insert(devMaxPriority,list); + m_alarmDGPDev.insert(devGroup,priorityMap); + } +} + +QHash > > CAlarmMsgManage::getLocNotConfirmAlmInfo() +{ + QMutexLocker locker(mutex); + return m_alarmLNCAlm; +} + +void CAlarmMsgManage::getAllInhibitAlm(QList &almList) +{ + QMutexLocker locker(mutex); + almList = m_inhibitFilter; +} + +void CAlarmMsgManage::slotLogin() +{ + QMutexLocker locker(mutex); + //emit sigClearAudioCues(); + m_playerList.clear(); + m_infos.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + m_listMsgAddCache.clear(); + m_inhibitFilter.clear(); + m_aiinfos.clear(); + m_aicount.clear(); + m_alarm.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + + m_nNDelComAlarmCount = 0; + m_nAlmNum = 0; + m_nAlmTotal = 0; + m_alarmDevPriority.clear(); + m_alarmDGPDev.clear(); + m_alarmLPAlm.clear(); + m_delaydeal.clear(); + + //清空告警推图 + emit sigAlarmPushGraphClear(); + + loadPermInfo(); + initAlarm(); + initAiAlarm(); + + emit sigAllViewReload(); +} + +void CAlarmMsgManage::removeAiAlarmMsgByDomainID(const int &domainId) +{ + QMutexLocker locker(mutex); + /* 清除全缓存 + */ + QHash::iterator pos = m_aiall.begin(); + while(pos != m_aiall.end()) { + if(domainId == (*pos)->domain_id) + { + pos = m_aiall.erase(pos); + continue; + } + pos++; + } + /* 清除有权限和未禁止的缓存 + */ + QHash::iterator it = m_aiinfos.begin(); + while(it != m_aiinfos.end()) + { + if(domainId == (*it)->domain_id) + { + eraseaicount((*it)->uuid_base64); + eraseidtoid((*it)->uuid_base64); + eraseidtolocation((*it)->uuid_base64); + m_nAlmTotal -= (*it)->raw_alm_uuid.size(); + it = m_aiinfos.erase(it); + continue; + } + it++; + } + //清除延迟处理的智能告警 + QList::iterator itpos =m_delaydeal.begin(); + while(itpos !=m_delaydeal.end()) { + if(domainId == (*itpos)->domain_id) + { + + itpos = m_delaydeal.erase(itpos); + continue; + } + itpos++; + } +} + +void CAlarmMsgManage::addAiAllAlarmMsg(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while(itpos != msgList.end()) { + m_aiall.insert((*itpos)->uuid_base64,*itpos); + QVector uuidVec = (*itpos)->raw_alm_uuid; + addidtoid(uuidVec,(*itpos)->uuid_base64); //记录原始告警uuid和智能告警uuid键值对 ,一直到release + QVector deluuidVec; + updatealarm(uuidVec,deluuidVec);//不可删除 //更新智能告警窗上的未聚类的原始告警,防止由于先后顺序导致显示出错 + if((*itpos)->deleteFlag || (*itpos)->brokenFlag) + { + itpos++; + continue; + } + //检查此智能告警下的原始告警是否完整 + //若完整则继续执行 + //不完整(此处指的是智能告警先到,原始告警未到的情况,并非告警服务通知的不完整)则延时处理 ,延时处理的不需要调用addidtoid()和updatealarm() + QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 + if(!isHaveAlm(uuidVec,almInfoList)) + { + m_delaydeal.append(*itpos); //延后处理 + itpos++; + continue; + } + QHash::iterator it = m_all.find((*itpos)->main_uuid_base64); + if(it != m_all.end()) + { + (*itpos)->main_state = (*it)->logic_state; + } + //检查是否具有权限 + if(checkLookPerm(almInfoList)) + { + addaicount(almInfoList,(*itpos)->uuid_base64); + addaitolocation(almInfoList,(*itpos)->uuid_base64); + initaivideo(*itpos); + m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); + m_aiinfos.insert((*itpos)->uuid_base64,*itpos); + } + itpos++; + } +} + +void CAlarmMsgManage::addAiAlarmMsg(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + QVector deluuidVec; + QList aiMsgList; + while(itpos != msgList.end()) { + m_aiall.insert((*itpos)->uuid_base64,*itpos); + QVector uuidVec = (*itpos)->raw_alm_uuid; + addidtoid(uuidVec,(*itpos)->uuid_base64); + updatealarm(uuidVec,deluuidVec); + if((*itpos)->deleteFlag || (*itpos)->brokenFlag) + { + itpos++; + continue; + } + QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 + if(!isHaveAlm(uuidVec,almInfoList)) + { + m_delaydeal.append(*itpos); //延后处理 + itpos++; + continue; + } + QHash::iterator it = m_all.find((*itpos)->main_uuid_base64); + if(it != m_all.end()) + { + (*itpos)->main_state = (*it)->logic_state; + } + if(checkLookPerm(almInfoList)) + { + addaicount(almInfoList,(*itpos)->uuid_base64); + addaitolocation(almInfoList,(*itpos)->uuid_base64); + initaivideo(*itpos); + m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); + m_aiinfos.insert((*itpos)->uuid_base64,*itpos); + aiMsgList.append(*itpos); + } + itpos++; + } + if(deluuidVec.size()>0) + { + emit sigMsgRemove(deluuidVec); + } + if(aiMsgList.size()>0) + { + emit sigAiMsgAdd(aiMsgList); + } +} + +void CAlarmMsgManage::delAiAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + QList aiuuidList; + while (itpos != uuidList.end()) { + QString aiuuid = *itpos; + //先在有权限的里面找,若有则不用去全部里面找 + QHash::iterator itinfos = m_aiinfos.find(aiuuid); + if(itinfos != m_aiinfos.end()) + { + m_nAlmTotal -= itinfos.value()->raw_alm_uuid.size(); + itinfos.value()->deleteFlag = true; + m_aiinfos.erase(itinfos); + aiuuidList.append(aiuuid); + }else + { + QHash::iterator itall = m_aiall.find(aiuuid); + if(itall != m_aiall.end()) + { + itall.value()->deleteFlag = true; + } + } + + //清除延迟处理的智能告警 + QList::iterator pos =m_delaydeal.begin(); + while(pos !=m_delaydeal.end()) { + if(aiuuid == (*pos)->uuid_base64) + { + pos = m_delaydeal.erase(pos); + break; + } + pos++; + } + itpos++; + } + if(aiuuidList.size()>0) + { + emit sigAiMsgRemove(aiuuidList); + } +} + +void CAlarmMsgManage::brokenAiAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + QList aiuuidList; + while(itpos != uuidList.end()) + { + QString aiuuid = *itpos; + //先在有权限的告警中找 + QHash::iterator itinfos = m_aiinfos.find(aiuuid); + if(itinfos != m_aiinfos.end()) + { + m_nAlmTotal -= itinfos.value()->raw_alm_uuid.size(); + itinfos.value()->brokenFlag = true; + m_aiinfos.erase(itinfos); + aiuuidList.append(aiuuid); + }else + { + QHash::iterator itall = m_aiall.find(aiuuid); + if(itall != m_aiall.end()) + { + itall.value()->brokenFlag = true; + } + } + + //清除延迟处理的智能告警 + QList::iterator pos =m_delaydeal.begin(); + while(pos !=m_delaydeal.end()) { + if(aiuuid == (*pos)->uuid_base64) + { + pos = m_delaydeal.erase(pos); + break; + } + pos++; + } + itpos++; + } + if(aiuuidList.size()>0) + { + emit sigAiMsgRemove(aiuuidList); + } +} + +void CAlarmMsgManage::releaseAiAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + QList aiuuidList; + QList m_listMsg; + while (itpos != uuidList.end()) { + QString aiuuid = *itpos; + QVector uuidVec; + QHash::iterator itinfos = m_aiinfos.find(aiuuid); + if(itinfos != m_aiinfos.end()) + { + uuidVec = itinfos.value()->raw_alm_uuid; + m_nAlmTotal -= uuidVec.size(); + for(int index(0);indexdeleteFlag == true || almPtr->releaseFlag == true) + { + continue; + } + + if(!m_listPermLocationId.contains(almPtr->location_id) || (!m_listPermRegionId.contains(almPtr->region_id) && almPtr->region_id != -1)) + { + continue; + } + + if(isInhibit(almPtr->key_id_tag)) + { + continue; + } + m_alarm.insert(almPtr->uuid_base64,almPtr); + m_listMsg.append(almPtr); + } + m_aiinfos.erase(itinfos); + aiuuidList.append(aiuuid); + } + + QHash::iterator itall = m_aiall.find(aiuuid); + if(itall != m_aiall.end()) + { + eraseaicount(aiuuid); + eraseidtoid(aiuuid); + eraseidtolocation(aiuuid); + m_aiall.erase(itall); + } + + //清除延迟处理的智能告警 + QList::iterator pos =m_delaydeal.begin(); + while (pos !=m_delaydeal.end()) { + if(aiuuid == (*pos)->uuid_base64) + { + pos = m_delaydeal.erase(pos); + break; + } + pos++; + } + itpos++; + } + if(aiuuidList.size()>0) + { + emit sigAiMsgRemove(aiuuidList); + } + + if(m_listMsg.size() > 0) + { + emit sigMsgArrivedToAi(m_listMsg); + } +} + +bool CAlarmMsgManage::getAiuuid(const QString &uuid, QString &aiuuid) +{ + QMutexLocker locker(mutex); + aiuuid = m_idToid.value(uuid,""); + if(aiuuid.isEmpty()) + { + return false; + } + return true; +} + +bool CAlarmMsgManage::isBelongAi(const QString &uuid) +{ + QMutexLocker locker(mutex); + if(m_idToid.value(uuid,"").isEmpty()) + { + return false; + } + return true; +} + +AlarmMsgPtr CAlarmMsgManage::getOnePlayerAlm(int num) +{ + QMutexLocker locker(mutex); + QList::iterator it = m_playerList.begin(); + + QStringList strAudioFileNames; + while (it != m_playerList.end()) { + strAudioFileNames.clear(); + if((*it)->deleteFlag || (*it)->releaseFlag) + { + it = m_playerList.erase(it); + }else if(ALM_ACT_SOUND != ((*it)->m_alarmAction & ALM_ACT_SOUND)) + { + it = m_playerList.erase(it); + }else + { + strAudioFileNames = (*it)->sound_file; + if(strAudioFileNames.isEmpty()) + { + it = m_playerList.erase(it); + }else if(num >= 0 && (*it)->m_playNum >= num) + { + strAudioFileNames.clear(); + it = m_playerList.erase(it); + }else + { + int fileNum = 0; + foreach (QString fileName, strAudioFileNames) + { + if(!fileName.isEmpty()) + { + fileName = m_strMediaPath + fileName; + if(QFile::exists(fileName)) + { + fileNum++; + } + } + } + if(fileNum == 0) + { + it = m_playerList.erase(it); + }else if(num < 0) + { + return *it; + }else + { + (*it)->m_playNum++; + return *it; + } + } + } + } + return Q_NULLPTR; +} + +AlarmMsgPtr CAlarmMsgManage::getOneSpeechAlm(int num) +{ + QMutexLocker locker(mutex); + QList::iterator it = m_playerList.begin(); + + QString alarmContent; + while (it != m_playerList.end()) { + alarmContent = QString(); + if((*it)->deleteFlag || (*it)->releaseFlag) + { + it = m_playerList.erase(it); + }else if(ALM_ACT_VOICE != ((*it)->m_alarmAction & ALM_ACT_VOICE)) + { + it = m_playerList.erase(it); + }else + { + alarmContent = (*it)->content; + if(alarmContent.isEmpty()) + { + it = m_playerList.erase(it); + }else if(num >= 0 && (*it)->m_playNum >= num) + { + alarmContent.clear(); + it = m_playerList.erase(it); + }else if(num < 0) + { + return *it; + }else + { + (*it)->m_playNum++; + return *it; + } + } + } + return Q_NULLPTR; +} + +void CAlarmMsgManage::eraseaicount(const QString &aiuuid) +{ + QHash::iterator it = m_aicount.find(aiuuid); + if(it != m_aicount.end()) + { + m_aicount.erase(it); + } +} + +void CAlarmMsgManage::eraseidtoid(const QString &aiuuid) +{ + QHash::iterator it = m_idToid.begin(); + + while (it != m_idToid.end()) { + if(aiuuid == it.value()) + { + it = m_idToid.erase(it); + continue; + } + it++; + } +} + +void CAlarmMsgManage::eraseidtolocation(const QString &aiuuid) +{ + QHash >::iterator it = m_aitolocation.find(aiuuid); + if(it != m_aitolocation.end()) + { + m_aitolocation.erase(it); + } +} + +bool CAlarmMsgManage::isHaveAlm(const QVector &uuidVec, QList &almInfoList) +{ + for(int x(0);x < uuidVec.count(); x++) + { + QHash::iterator it = m_all.find(uuidVec.at(x)); + if(it == m_all.end()) + { + return false; + } + almInfoList.append(*it); + } + return true; +} + +bool CAlarmMsgManage::checkLookPerm(const QList &almInfoList) +{ + QList::const_iterator it = almInfoList.begin(); + while (it != almInfoList.end()) { + qint32 location_id = (*it)->location_id; + qint32 region_id = (*it)->region_id; + if(m_listPermLocationId.contains(location_id) && (m_listPermRegionId.contains(region_id) || region_id == -1)) + { + return true; + } + it++; + } + return false; +} + +void CAlarmMsgManage::addidtoid(const QVector &uuidVec,const QString &aiuuid) +{ + for(int x(0);x < uuidVec.count();x++) + { + m_idToid[uuidVec.value(x)] = aiuuid; + } +} + +void CAlarmMsgManage::addaicount(const QList &almInfoList,const QString &aiuuid) +{ + int confirm = 0; + QList::const_iterator it = almInfoList.begin(); + while (it != almInfoList.end()) { + + if((*it)->logic_state == E_ALS_ALARM_CFM || (*it)->logic_state == E_ALS_RETURN_CFM || + (*it)->logic_state == E_ALS_ALARM_CFM_DEL || (*it)->logic_state == E_ALS_RETURN_CFM_DEL || (*it)->logic_state == ALS_EVT_ONLY) + { + confirm++; + } + it++; + } + SAiConfirm aiConfirm; + aiConfirm.nConfirm = confirm; + aiConfirm.nTotal = almInfoList.size(); + m_aicount.insert(aiuuid,aiConfirm); +} + +void CAlarmMsgManage::addaitolocation(const QList &almInfoList,const QString &aiuuid) +{ + QHash >::iterator it =m_aitolocation.find(aiuuid); + if(it != m_aitolocation.end()) + { + m_aitolocation.erase(it); + } + QList locationList; + QList::const_iterator pos = almInfoList.begin(); + while (pos != almInfoList.end()) { + if(!locationList.contains((*pos)->location_id)) + { + locationList.append((*pos)->location_id); + } + pos++; + } + m_aitolocation.insert(aiuuid,locationList); +} + +void CAlarmMsgManage::initaivideo(AiAlarmMsgPtr msg) +{ + AlarmMsgPtr ptr = m_all.value(msg->main_uuid_base64,NULL); + if(ptr != NULL) + { + msg->m_needVideoAlm = ptr->m_needVideoAlm; + msg->app_id = ptr->app_id; + msg->key_id_tag = ptr->key_id_tag; + msg->m_tagname_type = ptr->m_tagname_type; + } +} + +//<添加智能告警时,需要删除此条智能告警下还存在一级节点上的原始告警 +void CAlarmMsgManage::updatealarm(QVector &uuidVec,QVector &deluuidVec) +{ + for(int index(0);index::iterator it =m_alarm.find(uuidVec.at(index)); + if(it != m_alarm.end()) + { + m_alarm.remove(uuidVec.at(index)); + deluuidVec.append(uuidVec.at(index)); + } + } +} + +void CAlarmMsgManage::almStats(const AlarmMsgPtr &msg, int addOrSub) +{ + if(addOrSub == 1) + { + almAddStats(msg); + }else + { + almSubStats(msg); + } +} + +void CAlarmMsgManage::almAddStats(const AlarmMsgPtr &msg) +{ + devDevGTotAlmAddStats(msg); + devDevGAddStats(msg); + locAddStats(msg); +} + +void CAlarmMsgManage::almSubStats(const AlarmMsgPtr &msg) +{ + devDevGTotAlmSubStats(msg); + devDevGSubStats(msg); + locSubStats(msg); +} + +void CAlarmMsgManage::devDevGTotAlmAddStats(const AlarmMsgPtr &msg) +{ + + int dCount = m_alarmDeviceStatistical.value(msg->device, 0);//设备告警数量 + int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 + + ++dgCount; // +1 + ++dCount; // +1 + + if(dCount <= 0) + { + m_alarmDeviceStatistical.remove(msg->device); + } + else + { + m_alarmDeviceStatistical.insert(msg->device, dCount); + } + if(dgCount <= 0) + { + m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); + } + else + { + m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); + } +} + +void CAlarmMsgManage::devDevGTotAlmSubStats(const AlarmMsgPtr &msg) +{ + int dCount = m_alarmDeviceStatistical.value(msg->device, 0); //设备告警数量 + int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 + + --dgCount; + --dCount; + + if(dCount <= 0) + { + m_alarmDeviceStatistical.remove(msg->device); + } + else + { + m_alarmDeviceStatistical.insert(msg->device, dCount); + } + if(dgCount <= 0) + { + m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); + } + else + { + m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); + } +} + +void CAlarmMsgManage::devDevGAddStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit = m_alarmDevPriority.find(msg->device); + if(posit != m_alarmDevPriority.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()++; + else + priority.insert(msg->priority,1); + }else + { + QMap priority; + priority.insert(msg->priority,1); + m_alarmDevPriority.insert(msg->device,priority); + } + updataDevGroupByDev(msg->dev_group_tag,msg->device); +} + +void CAlarmMsgManage::devDevGSubStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit = m_alarmDevPriority.find(msg->device); + if(posit != m_alarmDevPriority.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()--; + } + updataDevGroupByDev(msg->dev_group_tag,msg->device); +} + +void CAlarmMsgManage::locAddStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); + if(posit != m_alarmLPAlm.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()++; + else + priority.insert(msg->priority,1); + }else + { + QMap priority; + priority.insert(msg->priority,1); + m_alarmLPAlm.insert(msg->location_id,priority); + } +} + +void CAlarmMsgManage::locSubStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); + if(posit != m_alarmLPAlm.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + { + itor.value()--; + } + } +} + +void CAlarmMsgManage::addNotConfirmAlm(int locId, const QString &devg, const QString &uuid) +{ + QHash > >::iterator it =m_alarmLNCAlm.find(locId); + if(it != m_alarmLNCAlm.end()) + { + QMap > &devgMap = it.value(); + QMap >::iterator pos = devgMap.find(devg); + if(pos != devgMap.end()) + { + pos.value().insert(uuid); + }else + { + QSet uuidSet; + uuidSet.insert(uuid); + devgMap[devg] = uuidSet; + } + }else + { + QMap > devgMap; + QSet uuidSet; + uuidSet.insert(uuid); + devgMap[devg] = uuidSet; + m_alarmLNCAlm[locId] = devgMap; + } +} + +void CAlarmMsgManage::delNotConfirmAlm(int locId, const QString &devg, const QString &uuid) +{ + QHash > >::iterator it =m_alarmLNCAlm.find(locId); + if(it != m_alarmLNCAlm.end()) + { + QMap > &devgMap = it.value(); + QMap >::iterator pos = devgMap.find(devg); + if(pos != devgMap.end()) + { + pos.value().remove(uuid); + } + } +} + +QString CAlarmMsgManage::queryLocationDesc(QString &aiuuid) +{ + QMutexLocker locker(mutex); + QString desc = QString(); + QList listLocationId = m_aitolocation.value(aiuuid); + for(int index(0);indexqueryLocationDesc(listLocationId.at(index)); + desc +=" "; + } + return desc; +} + +QString CAlarmMsgManage::queryConfirm(const QString &aiuuid) +{ + QMutexLocker locker(mutex); + SAiConfirm confirm = m_aicount.value(aiuuid); + QString st = QString("%1/%2").arg(confirm.nConfirm).arg(confirm.nTotal); + return st; +} + +int CAlarmMsgManage::queryAiTotal(const QString &aiuuid) +{ + QMutexLocker locker(mutex); + SAiConfirm confirm = m_aicount.value(aiuuid); + return confirm.nTotal; +} + +void CAlarmMsgManage::getAlarmInfo(QList &listAlarm, QList &listaiAlarm) +{ + QMutexLocker locker(mutex); + listAlarm = m_alarm.values(); + listaiAlarm = m_aiinfos.values(); +} + +QList CAlarmMsgManage::getAlarmPtrByuuid(const QVector &uuidVec) +{ + QMutexLocker locker(mutex); + QList list; + for(int index(0);index CAlarmMsgManage::getalmuuidByAiuuid(const QString &aiuuid) +{ + QList uuidList; + QHash::iterator it = m_idToid.begin(); + while(it != m_idToid.end()) { + if(it.value() == aiuuid) + { + uuidList.append(it.key()); + } + it++; + } + return uuidList; +} + +int CAlarmMsgManage::getAlmTotal() +{ + QMutexLocker locker(mutex); + return m_nAlmTotal + m_alarm.size(); +} + +int CAlarmMsgManage::getAiCount() +{ + QMutexLocker locker(mutex); + return m_aiinfos.size(); +} + +void CAlarmMsgManage::initAlarm() +{ + QHash::const_iterator itpos = m_all.begin(); + while (itpos != m_all.end()) { + + if(isInhibit((*itpos)->key_id_tag)) + { + itpos++; + continue; + } + if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) + { + itpos++; + continue ; + } + if((*itpos)->deleteFlag == true || (*itpos)->releaseFlag == true) //已经删除的不会保存到中 + { + itpos++; + continue ; + } + + if(E_ALS_ALARM == (*itpos)->logic_state || E_ALS_RETURN == (*itpos)->logic_state )//未确认数量(界面显示未确认) + { + addNotConfirmAlm((*itpos)->location_id,(*itpos)->dev_group_tag,(*itpos)->uuid_base64); + ++m_nNDelComAlarmCount; + } + updateMsgAction((*itpos)); + m_infos.insert((*itpos)->uuid_base64, (*itpos)); + //更新告警统计 + almStats((*itpos),1); + //更新未聚类但是需要展示的原始告警 + QHash::iterator it = m_idToid.find((*itpos)->uuid_base64); + if(it == m_idToid.end()) + { + m_alarm.insert((*itpos)->uuid_base64,(*itpos)); + } + itpos++; + } +} + +void CAlarmMsgManage::initAiAlarm() +{ + QHash::const_iterator itpos = m_aiall.begin(); + while(itpos != m_aiall.end()) + { + QVector uuidVec = (*itpos)->raw_alm_uuid; + addidtoid(uuidVec,(*itpos)->uuid_base64); //记录原始告警uuid和智能告警uuid键值对 ,一直到release + QVector deluuidVec; + updatealarm(uuidVec,deluuidVec);//不可删除 //更新智能告警窗上的未聚类的原始告警,防止由于先后顺序导致显示出错 + if((*itpos)->deleteFlag || (*itpos)->brokenFlag) + { + itpos++; + continue; + } + //检查此智能告警下的原始告警是否完整 + //若完整则继续执行 + //不完整(此处指的是智能告警先到,原始告警未到的情况,并非告警服务通知的不完整)则延时处理 ,延时处理的不需要调用addidtoid()和updatealarm() + QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 + if(!isHaveAlm(uuidVec,almInfoList)) + { + m_delaydeal.append(*itpos); //延后处理 + itpos++; + continue; + } + //检查是否具有权限 + if(checkLookPerm(almInfoList)) + { + addaicount(almInfoList,(*itpos)->uuid_base64); + addaitolocation(almInfoList,(*itpos)->uuid_base64); + initaivideo(*itpos); + m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); + m_aiinfos.insert((*itpos)->uuid_base64,*itpos); + } + itpos++; + } +} + +void CAlarmMsgManage::insertAudioCues(const AlarmMsgPtr &info) +{ + bool insertResult = false; + //LOGDEBUG("insertAudioCues %s",info->content.toStdString().c_str()); + if(!m_playerList.isEmpty()) + { + for(int nIndex(m_playerList.size() - 1); nIndex >= 0; --nIndex) + { + if(info->priorityOrder > m_playerList[nIndex]->priorityOrder) + { + m_playerList.insert(nIndex + 1, info); + insertResult = true; + break; + } + } + } + if(!insertResult) + { + if(m_playerList.isEmpty()) + { + m_playerList.append(info); + } + else + { + m_playerList.prepend(info); + } + } + if(m_playerList.count() >= MAX_AUDIO_ALM_COUNT) + { + m_playerList.removeLast(); + } +} + +void CAlarmMsgManage::removeAudioCues(const AlarmMsgPtr &info) +{ + QList::iterator it = m_playerList.begin(); + while (it != m_playerList.end()) + { + if(info->uuid_base64 == (*it)->uuid_base64) + { + m_playerList.erase(it); + break; + } + ++it; + } +} + +void CAlarmMsgManage::setReadFlag() +{ + if(!m_playerList.isEmpty()) + { + emit sigReadFlag(); + } +} + +CAlarmMsgManage::~CAlarmMsgManage() +{ + LOGDEBUG("CAlarmMsgManage::~CAlarmMsgManage()"); +} + +void CAlarmMsgManage::destory() +{ + { + QMutexLocker locker(mutex); + m_infos.clear(); + m_all.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + delete m_rtdbAlarmActionAccess; + delete m_rtdbLocationDescriptionAccess; + delete m_rtdbAppDescriptionAccess; + } + delete mutex; + pInstance = NULL; + + deleteLater(); +} + +void CAlarmMsgManage::initialize() +{ + release(); +} + +void CAlarmMsgManage::release() +{ + QMutexLocker locker(mutex); + m_infos.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + m_listMsgAddCache.clear(); + m_inhibitFilter.clear(); + m_aiinfos.clear(); + m_aicount.clear(); + m_alarm.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + //根据需求 + m_all.clear(); + m_aiall.clear(); + + m_nNDelComAlarmCount = 0; + m_nAlmNum = 0; + m_nAlmTotal = 0; + m_alarmDevPriority.clear(); + m_alarmDGPDev.clear(); + m_alarmLPAlm.clear(); + m_delaydeal.clear(); + m_playerList.clear(); + loadPermInfo(); +} + +QList CAlarmMsgManage::getListAlarmInfo() +{ + //不需要清空1秒缓存 + QMutexLocker locker(mutex); + return m_infos.values(); +} + +QHash CAlarmMsgManage::getDeviceStatisticalInfo() +{ + QMutexLocker locker(mutex); + + return m_alarmDeviceGroupStatistical; +} + +int CAlarmMsgManage::deviceGroupAlarmStatistical(const QString &deviceGroup) +{ + QMutexLocker locker(mutex); + if(deviceGroup.isEmpty()) + { + return 0; + } + + return m_alarmDeviceGroupStatistical.value(deviceGroup, 0); +} + +int CAlarmMsgManage::getAlarmTotalSize() +{ + QMutexLocker locker(mutex); + return m_infos.size(); +} + +int CAlarmMsgManage::getUnConfirmSize() +{ + QMutexLocker locker(mutex); + return m_nNDelComAlarmCount; +} + +void CAlarmMsgManage::output() +{ + QMutexLocker locker(mutex); + LOGDEBUG("内存告警数量展示:所有原始告警:%d,所有展示的原始告警:%d,所有智能告警:%d,所有展示的智能告警:%d,所有未聚合的原始告警:%d",m_all.size(),m_infos.size(),m_aiall.size(),m_aiinfos.size(),m_alarm.size()); +} + + +void CAlarmMsgManage::addAlarmMsg(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while (itpos != msgList.end()) { + m_all.insert((*itpos)->uuid_base64,(*itpos)); + if(isInhibit((*itpos)->key_id_tag)) + { + itpos++; + continue; + } + if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) + { + itpos++; + continue ; + } + if((*itpos)->deleteFlag == true || (*itpos)->releaseFlag == true) //已经删除的不会保存到中 + { + itpos++; + continue ; + } + if(E_ALS_ALARM == (*itpos)->logic_state || E_ALS_RETURN == (*itpos)->logic_state )//未确认数量(界面显示未确认) + { + addNotConfirmAlm((*itpos)->location_id,(*itpos)->dev_group_tag,(*itpos)->uuid_base64); + ++m_nNDelComAlarmCount; + } + updateMsgAction(*itpos); + m_infos.insert((*itpos)->uuid_base64, (*itpos)); + //更新告警统计 + almStats((*itpos),1); + //更新未聚类但是需要展示的原始告警 + QHash::iterator it = m_idToid.find((*itpos)->uuid_base64); + if(it == m_idToid.end()) + { + m_alarm.insert((*itpos)->uuid_base64,(*itpos)); + } + itpos++; + } + //设置标志可读 + setReadFlag(); +} + + +void CAlarmMsgManage::addAlarmToAllInfo(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while (itpos != msgList.end()) { + m_all.insert((*itpos)->uuid_base64,(*itpos)); + itpos++; + } + +} + +void CAlarmMsgManage::addAlarmCacheMsg(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while (itpos != msgList.end()) { + if(isInhibit((*itpos)->key_id_tag)) + { + itpos++; + continue; + } + if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) + { + itpos++; + continue ; + } + if((*itpos)->deleteFlag == true) + { + itpos++; + continue ; + } + m_listMsgAddCache.append(*itpos); + itpos++; + } +} +//不用考虑事件 因为事件不会发送过来 默认事件是已确认已删除状态 +void CAlarmMsgManage::confirmAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + while (itpos != uuidList.end()) { + QString uuid = *itpos; + AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); + if(!oldMsg.isNull()) + { + removeAudioCues(oldMsg); + if(E_ALS_ALARM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_ALARM_CFM; + --m_nNDelComAlarmCount; + } + else if(E_ALS_RETURN == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_RETURN_CFM; + --m_nNDelComAlarmCount; + } + delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + }else + { + AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); + if(!oldMsg_.isNull()) + { + if(E_ALS_ALARM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM; + } + else if(E_ALS_RETURN == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM; + } + else if(E_ALS_ALARM_DEL == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN_DEL == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; + } + } + } + //确认告警时更新告警确认数量(性能优化:事实证明,当数据量很大时,使用迭代器的效率是contains()的几十倍,随着数据量的增大倍数增大----数据很少可以忽略) + QHash::iterator it = m_idToid.find(uuid); + if(it != m_idToid.end()) + { + QString aiuuid = m_idToid.value(uuid); + SAiConfirm confirm = m_aicount.value(aiuuid); + confirm.nConfirm++; + m_aicount[aiuuid]=confirm; + } + itpos++; + } + //设置标志可读 + setReadFlag(); +} + +int CAlarmMsgManage::removeAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + int size = 0;//删除的个数 + QVector deluuidVec; + QList::const_iterator itpos = uuidList.begin(); + while (itpos != uuidList.end()) { + QString uuid = *itpos; + AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); + if(!oldMsg.isNull()) + { + if(oldMsg->deleteFlag) + { + itpos++; + continue; + } + if(E_ALS_ALARM == oldMsg->logic_state) + { + delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + --m_nNDelComAlarmCount; + oldMsg->logic_state = E_ALS_ALARM_DEL; + } + else if(E_ALS_ALARM_CFM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN == oldMsg->logic_state) + { + delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + --m_nNDelComAlarmCount; + oldMsg->logic_state = E_ALS_RETURN_DEL; + } + else if(E_ALS_RETURN_CFM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_RETURN_CFM_DEL; + } + + oldMsg->deleteFlag = true; + almStats(oldMsg,0); + m_infos.remove(uuid); + size++; + }else + { + AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); + if(!oldMsg_.isNull()) + { + if(oldMsg_->deleteFlag) + { + itpos++; + continue; + } + if(E_ALS_ALARM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_DEL; + } + else if(E_ALS_ALARM_CFM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_DEL; + } + else if(E_ALS_RETURN_CFM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; + } + oldMsg_->deleteFlag = true; + } + } + //从m_alarm中删除未聚类但有删除标志的告警 + QHash::iterator it = m_alarm.find(uuid); + if(it != m_alarm.end()) + { + m_alarm.erase(it); + deluuidVec.push_back(uuid); + } + itpos++; + } + if(deluuidVec.size()>0) + { + emit sigMsgRemove(deluuidVec);//通知智能告警模型删除1级节点上的未聚类原始告警 + } + //设置标志可读 + setReadFlag(); + return size; +} + +void CAlarmMsgManage::releaseAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + while (itpos != uuidList.end()) { + QString uuid = *itpos; + AlarmMsgPtr oldMsg = m_all.value(uuid, NULL); + if(!oldMsg.isNull()) + { + oldMsg->releaseFlag =true; + m_all.remove(uuid); + } + itpos++; + } + //设置标志可读 + setReadFlag(); +} + +void CAlarmMsgManage::linkWave2AlmMsg(const QList &uuidList, const QString &waveFile) +{ + QMutexLocker locker(mutex); + for(int index(0);index::iterator it = m_all.find(uuidList.at(index)); + if(it != m_all.end()) + { + (*it)->wave_file = waveFile; + }else + { + LOGERROR("linkWave2AlmMsg()未找到uuid为[%s]的告警,链接录波文件为:[%s],请自主查看!",uuidList.at(index).toStdString().c_str(),waveFile.toStdString().c_str()); + } + } +} + +void CAlarmMsgManage::removeAlarmMsgByDomainID(const int &domainId) +{ + QMutexLocker locker(mutex); + /* 清除全缓存 + */ + QHash::iterator pos = m_all.begin(); + while (pos != m_all.end()) { + if(domainId == (*pos)->domain_id) + { + pos = m_all.erase(pos); + continue; + } + pos++; + } + /* 清除有权限和未禁止的缓存 + */ + QHash::iterator it = m_infos.begin(); + while (it != m_infos.end()) + { + if(domainId == (*it)->domain_id) + { + if(E_ALS_ALARM == (*it)->logic_state || E_ALS_RETURN == (*it)->logic_state) + { + delNotConfirmAlm((*it)->location_id,(*it)->dev_group_tag,(*it)->uuid_base64); + --m_nNDelComAlarmCount; + } + removeAudioCues(it.value()); + almStats((*it),0); + it = m_infos.erase(it); + continue; + } + it++; + } + //清空告警缓存(每秒更新) + QList::iterator itpos =m_listMsgAddCache.begin(); + while (itpos != m_listMsgAddCache.end()) { + if((*itpos)->domain_id == domainId) + { + itpos =m_listMsgAddCache.erase(itpos); + continue; + } + itpos++; + } + + //清空 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗) + QHash::iterator itor = m_alarm.begin(); + while(itor != m_alarm.end()) + { + if(domainId == (*itor)->domain_id) + { + itor = m_alarm.erase(itor); + continue; + } + itor++; + } +} + +void CAlarmMsgManage::updateMsgAction(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while (itpos != msgList.end()) { + if(isInhibit((*itpos)->key_id_tag)) + { + itpos++; + continue ; + } + if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) + { + itpos++; + continue ; + } + if((*itpos)->deleteFlag || (*itpos)->releaseFlag) + { + itpos++; + continue ; + } + if((*itpos)->logic_state == E_ALS_ALARM || (*itpos)->logic_state == E_ALS_RETURN) + { + int alarmAction = queryAlarmAction((*itpos)->priority); + (*itpos)->m_alarmAction = alarmAction; + if(ALM_ACT_PUSH_PIC == (alarmAction & ALM_ACT_PUSH_PIC) && !(*itpos)->graph_name.isEmpty()) + { + //第1位,推画面 + QString alarmInfo; + //< 等级 + alarmInfo.append(QString::number((*itpos)->priorityOrder) + QString(",")); + //< 时间 + alarmInfo.append(QDateTime::fromMSecsSinceEpoch((*itpos)->time_stamp).toString("yyyy-MM-dd hh:mm:ss") + QString(",")); + //< 车站 + alarmInfo.append(queryLocationDescription((*itpos)->location_id) + QString(",")); + //< 应用 + alarmInfo.append(queryAppDescription((*itpos)->app_id) + QString(",")); + //< 内容 + alarmInfo.append((*itpos)->content + QString(",")); + //< 画面名称 + alarmInfo.append((*itpos)->graph_name); + + pushGraphics(alarmInfo); + } + if(ALM_ACT_PRINT == (alarmAction & ALM_ACT_PRINT)) + { + //第2位,打印 + print(); + } + if(ALM_ACT_SHORT_MSG == (alarmAction & ALM_ACT_SHORT_MSG)) + { + //第3位,短消息 + shortMessage(); + } + if(ALM_ACT_SOUND == (alarmAction & ALM_ACT_SOUND) || ALM_ACT_VOICE == (alarmAction & ALM_ACT_VOICE)) + { + //第4位,声音告警 第9位 语音告警 + //emit sigInsertAudioCues(*itpos, (*itpos)->sound_file); + insertAudioCues(*itpos); + } + if(ALM_ACT_PA == (alarmAction & ALM_ACT_PA)) + { + //第5位,广播告警 + paNotify(); + } + } + itpos++; + } +} + +void CAlarmMsgManage::updateMsgAction(const AlarmMsgPtr &msg) +{ + if(msg->logic_state == E_ALS_ALARM) + { + int alarmAction = queryAlarmAction(msg->priority); + msg->m_alarmAction = alarmAction; + if(ALM_ACT_PUSH_PIC == (alarmAction & ALM_ACT_PUSH_PIC) && !msg->graph_name.isEmpty()) + { + //第1位,推画面 + QString alarmInfo; + //< 等级 + alarmInfo.append(QString::number(msg->priorityOrder) + QString(",")); + //< 时间 + alarmInfo.append(QDateTime::fromMSecsSinceEpoch(msg->time_stamp).toString("yyyy-MM-dd hh:mm:ss") + QString(",")); + //< 车站 + alarmInfo.append(queryLocationDescription(msg->location_id) + QString(",")); + //< 应用 + alarmInfo.append(queryAppDescription(msg->app_id) + QString(",")); + //< 内容 + alarmInfo.append(msg->content + QString(",")); + //< 画面名称 + alarmInfo.append(msg->graph_name); + + pushGraphics(alarmInfo); + } + if(ALM_ACT_PRINT == (alarmAction & ALM_ACT_PRINT)) + { + //第2位,打印 + print(); + } + if(ALM_ACT_SHORT_MSG == (alarmAction & ALM_ACT_SHORT_MSG)) + { + //第3位,短消息 + shortMessage(); + } + if(ALM_ACT_SOUND == (alarmAction & ALM_ACT_SOUND) || ALM_ACT_VOICE == (alarmAction & ALM_ACT_VOICE)) + { + //第4位,声音告警 第9位 语音告警 + //emit sigInsertAudioCues(msg, msg->sound_file); + insertAudioCues(msg); + } + if(ALM_ACT_PA == (alarmAction & ALM_ACT_PA)) + { + //第5位,广播告警 + paNotify(); + } + } +} + +void CAlarmMsgManage::pushGraphics(const QString &info) +{ + emit sigAlarmPushGraph(info); +} + +void CAlarmMsgManage::print() +{ + +} + +void CAlarmMsgManage::shortMessage() +{ + +} + +void CAlarmMsgManage::sounds(const AlarmMsgPtr info, const QStringList soundFileNames) +{ + //播放告警音频 + if(!soundFileNames.isEmpty()) + { + emit sigInsertAudioCues(info, soundFileNames); + } +} + +void CAlarmMsgManage::stopSounds(const AlarmMsgPtr info) +{ + removeAudioCues(info); +} + +void CAlarmMsgManage::paNotify() +{ + +} + +bool CAlarmMsgManage::isBindMediaPlayer() +{ + return isSignalConnected(QMetaMethod::fromSignal(&CAlarmMsgManage::sigReadFlag)); +} + +void CAlarmMsgManage::msgArrived() +{ + QMutexLocker locker(mutex); + QList m_ailistMsg; //需要在智能告警窗展示 + QList m_listMsg; //需要在原始告警窗展示 + m_listMsg.clear(); + for(int num(0);numkey_id_tag)) + { + continue ; + } + if(!m_listPermLocationId.contains(m_listMsgAddCache.at(num)->location_id) || (!m_listPermRegionId.contains(m_listMsgAddCache.at(num)->region_id) && m_listMsgAddCache.at(num)->region_id != -1)) + { + continue ; + } + if(m_listMsgAddCache.at(num)->deleteFlag || m_listMsgAddCache.at(num)->releaseFlag) + { + continue ; + } + + if(E_ALS_ALARM == m_listMsgAddCache.at(num)->logic_state || E_ALS_RETURN == m_listMsgAddCache.at(num)->logic_state )//未删除未确认数量(界面显示未确认) + { + addNotConfirmAlm(m_listMsgAddCache.at(num)->location_id,m_listMsgAddCache.at(num)->dev_group_tag,m_listMsgAddCache.at(num)->uuid_base64); + ++m_nNDelComAlarmCount; + } + updateMsgAction(m_listMsgAddCache.at(num)); + m_infos.insert(m_listMsgAddCache.at(num)->uuid_base64, m_listMsgAddCache.at(num)); + m_listMsg.append(m_listMsgAddCache.at(num)); + //更新告警数量 + almStats(m_listMsgAddCache.at(num),1); + //更新未聚类但是需要展示的原始告警 + QHash::iterator it = m_idToid.find(m_listMsgAddCache.at(num)->uuid_base64); + if(it == m_idToid.end()) + { + m_alarm.insert(m_listMsgAddCache.at(num)->uuid_base64,m_listMsgAddCache.at(num)); + m_ailistMsg.append(m_listMsgAddCache.at(num)); + } + } + m_listMsgAddCache.clear(); + if(m_listMsg.size()>0) + { + emit sigMsgArrived(m_listMsg); + m_listMsg.clear(); + } + if(m_ailistMsg.size()>0) + { + emit sigMsgArrivedToAi(m_ailistMsg); + m_ailistMsg.clear(); + } + //设置标志可读 + setReadFlag(); +} + +void CAlarmMsgManage::dealDelayAi() +{ + QMutexLocker locker(mutex); + QList delaydeal = m_delaydeal; + m_delaydeal.clear(); + //QVector deluuidVec; + QList aiMsgList; + if(delaydeal.size() > 0) + { + for(int index(0);index uuidVec = delaydeal.at(index)->raw_alm_uuid; + if(delaydeal.at(index)->deleteFlag || delaydeal.at(index)->brokenFlag) + { + continue; + } + QList almInfoList; + if(!isHaveAlm(uuidVec,almInfoList)) + { + m_delaydeal.append(delaydeal.at(index)); //延后处理 + continue; + } + QHash::iterator it = m_all.find(delaydeal.at(index)->main_uuid_base64); + if(it != m_all.end()) + { + delaydeal.at(index)->main_state = (*it)->logic_state; + } + if(checkLookPerm(almInfoList)) + { + addaicount(almInfoList,delaydeal.at(index)->uuid_base64); + addaitolocation(almInfoList,delaydeal.at(index)->uuid_base64); + initaivideo(delaydeal.at(index)); + if(delaydeal.at(index)->deleteFlag != true && delaydeal.at(index)->brokenFlag != true) + { + m_nAlmTotal += delaydeal.at(index)->raw_alm_uuid.size(); + m_aiinfos.insert(delaydeal.at(index)->uuid_base64,delaydeal.at(index)); + aiMsgList.append(delaydeal.at(index)); + } + } + } + if(aiMsgList.size()>0) + { + emit sigAiMsgAdd(aiMsgList); + } + } +} + +int CAlarmMsgManage::queryAlarmAction(const int &priority) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbAlarmActionAccess); + kbd_dbms::CVarType value; + m_rtdbAlarmActionAccess->getColumnValueByKey((void*)&priority, "alarm_actions",value); + return value.toInt(); +} + +QString CAlarmMsgManage::queryLocationDescription(int id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbLocationDescriptionAccess); + kbd_dbms::CVarType value; + m_rtdbLocationDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); + return value.c_str(); +} + +QString CAlarmMsgManage::queryAppDescription(int id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbAppDescriptionAccess); + kbd_dbms::CVarType value; + m_rtdbAppDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); + return value.c_str(); +} + +void CAlarmMsgManage::loadPermInfo() +{ + m_listPermLocationId = CAlarmBaseData::instance()->getPermLocationIdList(); + m_listPermRegionId = CAlarmBaseData::instance()->getPermRegionIdList(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.h b/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.h index 0a39dfd0..1cd27591 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.h @@ -1,420 +1,420 @@ -#ifndef CALARMMSGMANAGE_H -#define CALARMMSGMANAGE_H - -#include -#include -#include "CAlarmMsgInfo.h" -#include "CAiAlarmMsgInfo.h" -#include "dbms/rdb_api/CRdbAccess.h" - -#include "CAlarmCommon.h" -#include - -const int MAX_AUDIO_ALM_COUNT = 1000; - -class QMutex; -class CAlarmItemModel; -class CAlarmMsgManage : public QObject -{ - Q_OBJECT -public: - static CAlarmMsgManage * instance(); - - ~CAlarmMsgManage(); - - void destory(); - - void initialize(); - - void release(); - - QList getListAlarmInfo(); - - QHash getDeviceStatisticalInfo(); - - int deviceGroupAlarmStatistical(const QString &deviceGroup); - - int getAlarmTotalSize(); - - int getUnConfirmSize(); - - void output(); - - void addAlarmMsg(const QList &msgList); - - void addAlarmToAllInfo(const QList &msgList); - - void addAlarmCacheMsg(const QList &msgList); - - void confirmAlarmMsg(const QList &uuidList); - - int removeAlarmMsg(const QList &uuidList); - - void releaseAlarmMsg(const QList &uuidList); - - void linkWave2AlmMsg(const QList &uuidList,const QString &waveFile); - - void removeAlarmMsgByDomainID(const int &domainId); - - void updateMsgAction(const QList &msgList); - void updateMsgAction(const AlarmMsgPtr &msg); - //< 告警动作 - void pushGraphics(const QString &info); - void print(); - void shortMessage(); - void sounds(const AlarmMsgPtr info, const QStringList soundFileNames); - void stopSounds(const AlarmMsgPtr info); - void paNotify(); - - bool isBindMediaPlayer(); - void msgArrived(); - void dealDelayAi(); - - void addInhibitAlm(const AlarmMsgPtr &info); - void removeInhibitTag(const QString &tag_name); - QMap getDevAlarm(const QString &device); - - QMap >getDevGroupPriorityDevNum(const QString &deviceGroup); - - QHash > getLocAlmInfo(); - void updataDevGroupByDev(QString devGroup, QString device); - - QHash > > getLocNotConfirmAlmInfo(); - - void getAllInhibitAlm(QList &almList); -signals: - void sigInsertAudioCues(const AlarmMsgPtr &info, const QStringList &soundFileNames); - void sigStopAudioCues(const AlarmMsgPtr &info); - void sigAlarmPushGraph(const QString &alarmInfo); - void sigAlarmPushGraphClear(); - void sigAlarmReplaced(); - void sigMsgArrived(QList listMsg); //只通知表格模型 - /** - * @brief sigMsgArrivedToAi 通知树模型未聚类的原始告警到达 - * @param listMsg - */ - void sigMsgArrivedToAi(QList listMsg); //只通知树模型 - - void sigAllViewReload(); - - void sigReadFlag(); - -public slots: - void slotLogin(); - -private: - CAlarmMsgManage(); - int queryAlarmAction(const int &priority); - QString queryLocationDescription(int id); - QString queryAppDescription(int id); - - void loadPermInfo(); - - void refreshCache(); - -public: - bool ifInhibit(const QString &tag_name); - bool isInhibit(const QString &tag_name); - /** - * @brief removeAiAlarmMsgByDomainID 移除此域所有智能告警,并清除,维护相关结构 - * @param domainId 域id - */ - void removeAiAlarmMsgByDomainID(const int &domainId); - /** - * @brief addAiAllAlarmMsg 全数据时调用,不会通知模型,全部接收完会自动通知模型刷新(重新装载数据) - * @param msg 智能告警指针 - */ - void addAiAllAlarmMsg(const QList &msgList); - /** - * @brief addAiAlarmMsg 非全数据时调用,会通知模型添加智能告警,删除相关原始告警 - * @param msg 智能告警指针 - */ - void addAiAlarmMsg(const QList &msgList); - /** - * @brief delAiAlarmMsg 根据智能告警uuid删除智能告警 - * @param aiuuid 智能告警uuid - */ - void delAiAlarmMsg(const QList &uuidList); - /** - * @brief brokenAiAlarmMsg 处理不完整的智能告警 - * @param aiuuid - */ - void brokenAiAlarmMsg(const QList &uuidList); - /** - * @brief releaseAiAlarmMsg 根据智能告警uuid释放智能告警 - * @param aiuuid 智能告警uuid - */ - void releaseAiAlarmMsg(const QList &uuidList); - /** - * @brief getAiuuid 根据原始告警uuid获取智能告警uuid - * @param uuid 原始告警uuid - * @param aiuuid 智能告警uuid - * @return 成功返回true,失败返回false - */ - bool getAiuuid(const QString &uuid, QString &aiuuid); - /** - * @brief isBelongAi 是否属于某个智能告警(已经被某个智能告警聚类) - * @param uuid 原始告警uuid - * @return true-已经被聚类 false-还未被聚类 - */ - bool isBelongAi(const QString &uuid); - - AlarmMsgPtr getOnePlayerAlm(int num); - - AlarmMsgPtr getOneSpeechAlm(int num); -private: - /** - * @brief eraseaicount 删除key为aiuuid的键值对 (<智能告警id,SAiConfirm>) - * @param aiuuid 智能告警uuid - */ - void eraseaicount(const QString &aiuuid); - /** - * @brief eraseidtoid 删除值为aiuuid的所有键值对(<原始告警id,智能告警id>) - * @param aiuuid 智能告警uuid - */ - void eraseidtoid(const QString &aiuuid); - /** - * @brief eraseidtolocation 删除key为aiuuid的键值对 (<智能告警id,与此条智能告警相关的所有位置id>) - * @param aiuuid 智能告警uuid - */ - void eraseidtolocation(const QString &aiuuid); - /** - * @brief isHaveAlm 查询m_all中是否包含uuidVec中的告警(确保智能告警下的原始告警一定存在) - * @param uuidVec - * @return - */ - /** - * @brief isHaveAlm isHaveAlm 查询m_all中是否包含uuidVec中的告警(确保智能告警下的原始告警一定存在) - * @param uuidVec 原始告警uuid集合 - * @param almInfoList 原始告警智能指针集合 - * @return 全部包含返回true,否则返回false - */ - bool isHaveAlm(const QVector &uuidVec, QList &almInfoList); - /** - * @brief checkLookPerm 检查当前登陆用户是否具有此条智能告警的权限(若可以看到其中任意一条,则具有权限) - * @param uuidVec 智能告警下原始告警uuid集合 - * @return 有权限返回 true 否则返回false - */ - /** - * @brief checkLookPerm checkLookPerm 检查当前登陆用户是否具有此条智能告警的权限(若可以看到其中任意一条,则具有权限) - * @param almInfoList 原始告警智能指针集合 - * @return 具有权限返回true 否则返回false - */ - bool checkLookPerm(const QList &almInfoList); - /** - * @brief addidtoid 添加原始告警uuid和智能告警uuid的映射 - * @param uuidVec 原始告警uuid集合 - * @param aiuuid 智能告警uuid - */ - void addidtoid(const QVector &uuidVec, const QString &aiuuid); - /** - * @brief addaicount 添加智能告警下原始告警的已确认和总数 - * @param uuidVec 原始告警uuid集合 - * @param aiuuid 智能告警uuid - */ - /** - * @brief addaicount 添加智能告警下原始告警的已确认和总数 - * @param almInfoList 原始告警智能指针的集合 - * @param aiuuid 智能告警aiuuid - */ - void addaicount(const QList &almInfoList, const QString &aiuuid); - /** - * @brief addaitolocation addaitolocation 添加智能告警uuid和与此告警相关位置的id - * @param almInfoList 原始告警智能指针集合 - * @param aiuuid 智能告警aiuuid - */ - void addaitolocation(const QList &almInfoList, const QString &aiuuid); - /** - * @brief initaivideo initaivideo 初始化智能告警下原始告警的相关信息 - * @param msg - */ - void initaivideo(AiAlarmMsgPtr msg); - /** - * @brief updatealarm 更新需要展示在智能告警窗上未聚类的原始告警 - * @param uuidVec 某条智能告警下的所有原始告警的uuid - * @param deluuidVec 需要被删除的一级节点上的未聚类的原始告警uuid - */ - void updatealarm(QVector &uuidVec, QVector &deluuidVec); - /** - * @brief almStats 告警统计 - * @param msg 告警指针 - * @param addOrSub 1--add 0--sub(1添加,0删除) - */ - void almStats(const AlarmMsgPtr &msg,int addOrSub); - /** - * @brief almAddStats 告警添加统计 - * @param msg 告警指针 - */ - void almAddStats(const AlarmMsgPtr &msg); - /** - * @brief almSubStats 告警删除统计 - * @param msg 告警指针 - */ - void almSubStats(const AlarmMsgPtr &msg); - /** - * @brief devDevGTotAlmAddStats 设备设备组按优先级添加统计 - * @param msg 告警指针 - */ - void devDevGTotAlmAddStats(const AlarmMsgPtr &msg); - /** - * @brief devDevGTotAlmSubStats 设备设备组按优先级删除统计 - * @param msg 告警指针 - */ - void devDevGTotAlmSubStats(const AlarmMsgPtr &msg); - void devDevGAddStats(const AlarmMsgPtr &msg); - void devDevGSubStats(const AlarmMsgPtr &msg); - void locAddStats(const AlarmMsgPtr &msg); - void locSubStats(const AlarmMsgPtr &msg); - /** - * @brief addNotConfirmAlm 添加未确认的告警uuid - * @param locId - * @param devg - * @param uuid - */ - void addNotConfirmAlm(int locId,const QString &devg,const QString &uuid); - /** - * @brief delNotConfirmAlm 从未确认的告警uuid集合中删除(删除的不一定被确认 可能是数据重发) - * @param locId - * @param devg - * @param uuid - */ - void delNotConfirmAlm(int locId,const QString &devg,const QString &uuid); -signals: - /** - * @brief sigAiMsgRemove 通知智能告警模型删除智能告警 - * @param aiuuidList 智能告警aiuuid列表 - */ - void sigAiMsgRemove(const QList & aiuuidList); - /** - * @brief sigAiMsgAdd 通知智能告警模型添加某条智能告警 - * @param aimsgList 智能告警指针列表 - */ - void sigAiMsgAdd(const QList& aimsgList); - /** - * @brief sigMsgRemove 通知智能告警模型删除一级节点上的原始告警 - * @param deluuid 需要删除的原始告警uuid的集合 - */ - void sigMsgRemove(const QVector deluuid); -public: - /** - * @brief queryLocationDesc 根据智能告警uuid查询位置描述(可能包含多个位置) - * @param aiuuid 智能告警uuid - * @return 位置描述 - */ - QString queryLocationDesc(QString &aiuuid); - /** - * @brief queryConfirm 根据智能告警uuid查询确认数和总数 - * @param aiuuid 智能告警uuid - * @return 确认数/总数(ex:20/30) - */ - QString queryConfirm(const QString &aiuuid); - /** - * @brief queryAiTotal 根据智能告警uuid 查询原始告警条数 - * @param aiuuid 智能告警uuid - * @return 原始告警条数 - */ - int queryAiTotal(const QString &aiuuid); - /** - * @brief getAlarmInfo 获取所有有权限的原始告警和智能告警 (接口:给智能告警模型使用) - * @param listAlarm 原始告警指针集合 - * @param listaiAlarm 智能告警指针集合 - */ - void getAlarmInfo(QList &listAlarm,QList &listaiAlarm); - /** - * @brief getAlarmPtrByuuid 根据原始告警uuid获取原始告警指针 - * @param uuid 原始告警uuid列表 - * @return 原始告警指针列表 - */ - QList getAlarmPtrByuuid(const QVector &uuidVec); - /** - * @brief ifhaveNotConfirmAlmByuuid 根据智能告警uuid查询是否还有未确认的原始告警 - * @param aiuuid 智能告警uuid - * @return 如果包含未确认原始告警返回true,否则返回false - */ - bool ifhaveNotConfirmAlmByuuid(QString &aiuuid); - /** - * @brief getAiLocationList 根据智能告警uuid获取有关的位置集合 - * @param aiuuid 智能告警uuid - * @return 与之有关的位置集合 - */ - QList getAiLocationList(QString &aiuuid); - /** - * @brief getalmuuidByAiuuid 根据智能告警uuid获取相关原始告警uuid - * @param aiuuid 智能告警uuid - * @return 原始告警uuidList - */ - QList getalmuuidByAiuuid(const QString &aiuuid); - /** - * @brief getAlmTotal 获取智能告警窗显示原始告警总数 - * @return 数量 - */ - int getAlmTotal(); - /** - * @brief getAiCount 获取未过滤时的智能告警条数 - * @return - */ - int getAiCount(); - -private: - - void initAlarm(); - - void initAiAlarm(); - - void insertAudioCues(const AlarmMsgPtr &info); - - void removeAudioCues(const AlarmMsgPtr &info); - - void setReadFlag(); - -private: - static CAlarmMsgManage * pInstance; - - QMutex * mutex; - - kbd_dbms::CRdbAccess * m_rtdbAlarmActionAccess; - kbd_dbms::CRdbAccess * m_rtdbLocationDescriptionAccess; - kbd_dbms::CRdbAccess * m_rtdbAppDescriptionAccess; - - int m_nNDelComAlarmCount; //< 未删除未确认数量 N--not Del--delete Com--confirm - QHash m_infos; - QHash m_all; - - - QList m_listPermLocationId; //< 原始告警车站权限 - QList m_listPermRegionId; //< 原始告警责任区权限 - - - //缓存从collect调整到mng - QList m_listMsgAddCache; //< 告警缓存(每秒更新) - QList m_inhibitFilter; //< 告警抑制[界面] - - //智能告警新加 - QHash m_alarm; //< 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗)(两个线程共同维护) - QHash m_aiinfos; //< 有权限的智能告警 - QHash m_aiall; //< 所有智能告警 - - QHash m_aicount; //< <智能告警uuid,已确认数/总数 > - QHash m_idToid; //< <原始告警uuid,智能告警uuid > 用于确认原始告警之后便于更新智能告警中的已确认总数 - - QHash > m_aitolocation;//< <智能告警uuid,包含的原始告警车站id> - - QHash m_alarmDeviceStatistical; //< 设备告警数量统计 - QHash m_alarmDeviceGroupStatistical; //<设备组告警数量统计 - QHash > m_alarmDevPriority; //< 设备告警等级数量统计 - QHash > > m_alarmDGPDev; //< <设备组,<告警等级,设备> > - QHash > m_alarmLPAlm; //< <车站id,<告警等级,告警数量> > - - QHash > > m_alarmLNCAlm;//< <车站id,<设备组,<未确认告警uuid> > > - - QList m_delaydeal; //延迟处理的智能告警 - - int m_nAlmNum; //智能告警窗原始告警个数 - int m_nAlmTotal; //智能告警窗原始告警总数 - - QList m_playerList; - - QString m_strMediaPath; -}; - -#endif // CALARMMSGMANAGE_H +#ifndef CALARMMSGMANAGE_H +#define CALARMMSGMANAGE_H + +#include +#include +#include "CAlarmMsgInfo.h" +#include "CAiAlarmMsgInfo.h" +#include "dbms/rdb_api/CRdbAccess.h" + +#include "CAlarmCommon.h" +#include + +const int MAX_AUDIO_ALM_COUNT = 1000; + +class QMutex; +class CAlarmItemModel; +class CAlarmMsgManage : public QObject +{ + Q_OBJECT +public: + static CAlarmMsgManage * instance(); + + ~CAlarmMsgManage(); + + void destory(); + + void initialize(); + + void release(); + + QList getListAlarmInfo(); + + QHash getDeviceStatisticalInfo(); + + int deviceGroupAlarmStatistical(const QString &deviceGroup); + + int getAlarmTotalSize(); + + int getUnConfirmSize(); + + void output(); + + void addAlarmMsg(const QList &msgList); + + void addAlarmToAllInfo(const QList &msgList); + + void addAlarmCacheMsg(const QList &msgList); + + void confirmAlarmMsg(const QList &uuidList); + + int removeAlarmMsg(const QList &uuidList); + + void releaseAlarmMsg(const QList &uuidList); + + void linkWave2AlmMsg(const QList &uuidList,const QString &waveFile); + + void removeAlarmMsgByDomainID(const int &domainId); + + void updateMsgAction(const QList &msgList); + void updateMsgAction(const AlarmMsgPtr &msg); + //< 告警动作 + void pushGraphics(const QString &info); + void print(); + void shortMessage(); + void sounds(const AlarmMsgPtr info, const QStringList soundFileNames); + void stopSounds(const AlarmMsgPtr info); + void paNotify(); + + bool isBindMediaPlayer(); + void msgArrived(); + void dealDelayAi(); + + void addInhibitAlm(const AlarmMsgPtr &info); + void removeInhibitTag(const QString &tag_name); + QMap getDevAlarm(const QString &device); + + QMap >getDevGroupPriorityDevNum(const QString &deviceGroup); + + QHash > getLocAlmInfo(); + void updataDevGroupByDev(QString devGroup, QString device); + + QHash > > getLocNotConfirmAlmInfo(); + + void getAllInhibitAlm(QList &almList); +signals: + void sigInsertAudioCues(const AlarmMsgPtr &info, const QStringList &soundFileNames); + void sigStopAudioCues(const AlarmMsgPtr &info); + void sigAlarmPushGraph(const QString &alarmInfo); + void sigAlarmPushGraphClear(); + void sigAlarmReplaced(); + void sigMsgArrived(QList listMsg); //只通知表格模型 + /** + * @brief sigMsgArrivedToAi 通知树模型未聚类的原始告警到达 + * @param listMsg + */ + void sigMsgArrivedToAi(QList listMsg); //只通知树模型 + + void sigAllViewReload(); + + void sigReadFlag(); + +public slots: + void slotLogin(); + +private: + CAlarmMsgManage(); + int queryAlarmAction(const int &priority); + QString queryLocationDescription(int id); + QString queryAppDescription(int id); + + void loadPermInfo(); + + void refreshCache(); + +public: + bool ifInhibit(const QString &tag_name); + bool isInhibit(const QString &tag_name); + /** + * @brief removeAiAlarmMsgByDomainID 移除此域所有智能告警,并清除,维护相关结构 + * @param domainId 域id + */ + void removeAiAlarmMsgByDomainID(const int &domainId); + /** + * @brief addAiAllAlarmMsg 全数据时调用,不会通知模型,全部接收完会自动通知模型刷新(重新装载数据) + * @param msg 智能告警指针 + */ + void addAiAllAlarmMsg(const QList &msgList); + /** + * @brief addAiAlarmMsg 非全数据时调用,会通知模型添加智能告警,删除相关原始告警 + * @param msg 智能告警指针 + */ + void addAiAlarmMsg(const QList &msgList); + /** + * @brief delAiAlarmMsg 根据智能告警uuid删除智能告警 + * @param aiuuid 智能告警uuid + */ + void delAiAlarmMsg(const QList &uuidList); + /** + * @brief brokenAiAlarmMsg 处理不完整的智能告警 + * @param aiuuid + */ + void brokenAiAlarmMsg(const QList &uuidList); + /** + * @brief releaseAiAlarmMsg 根据智能告警uuid释放智能告警 + * @param aiuuid 智能告警uuid + */ + void releaseAiAlarmMsg(const QList &uuidList); + /** + * @brief getAiuuid 根据原始告警uuid获取智能告警uuid + * @param uuid 原始告警uuid + * @param aiuuid 智能告警uuid + * @return 成功返回true,失败返回false + */ + bool getAiuuid(const QString &uuid, QString &aiuuid); + /** + * @brief isBelongAi 是否属于某个智能告警(已经被某个智能告警聚类) + * @param uuid 原始告警uuid + * @return true-已经被聚类 false-还未被聚类 + */ + bool isBelongAi(const QString &uuid); + + AlarmMsgPtr getOnePlayerAlm(int num); + + AlarmMsgPtr getOneSpeechAlm(int num); +private: + /** + * @brief eraseaicount 删除key为aiuuid的键值对 (<智能告警id,SAiConfirm>) + * @param aiuuid 智能告警uuid + */ + void eraseaicount(const QString &aiuuid); + /** + * @brief eraseidtoid 删除值为aiuuid的所有键值对(<原始告警id,智能告警id>) + * @param aiuuid 智能告警uuid + */ + void eraseidtoid(const QString &aiuuid); + /** + * @brief eraseidtolocation 删除key为aiuuid的键值对 (<智能告警id,与此条智能告警相关的所有位置id>) + * @param aiuuid 智能告警uuid + */ + void eraseidtolocation(const QString &aiuuid); + /** + * @brief isHaveAlm 查询m_all中是否包含uuidVec中的告警(确保智能告警下的原始告警一定存在) + * @param uuidVec + * @return + */ + /** + * @brief isHaveAlm isHaveAlm 查询m_all中是否包含uuidVec中的告警(确保智能告警下的原始告警一定存在) + * @param uuidVec 原始告警uuid集合 + * @param almInfoList 原始告警智能指针集合 + * @return 全部包含返回true,否则返回false + */ + bool isHaveAlm(const QVector &uuidVec, QList &almInfoList); + /** + * @brief checkLookPerm 检查当前登陆用户是否具有此条智能告警的权限(若可以看到其中任意一条,则具有权限) + * @param uuidVec 智能告警下原始告警uuid集合 + * @return 有权限返回 true 否则返回false + */ + /** + * @brief checkLookPerm checkLookPerm 检查当前登陆用户是否具有此条智能告警的权限(若可以看到其中任意一条,则具有权限) + * @param almInfoList 原始告警智能指针集合 + * @return 具有权限返回true 否则返回false + */ + bool checkLookPerm(const QList &almInfoList); + /** + * @brief addidtoid 添加原始告警uuid和智能告警uuid的映射 + * @param uuidVec 原始告警uuid集合 + * @param aiuuid 智能告警uuid + */ + void addidtoid(const QVector &uuidVec, const QString &aiuuid); + /** + * @brief addaicount 添加智能告警下原始告警的已确认和总数 + * @param uuidVec 原始告警uuid集合 + * @param aiuuid 智能告警uuid + */ + /** + * @brief addaicount 添加智能告警下原始告警的已确认和总数 + * @param almInfoList 原始告警智能指针的集合 + * @param aiuuid 智能告警aiuuid + */ + void addaicount(const QList &almInfoList, const QString &aiuuid); + /** + * @brief addaitolocation addaitolocation 添加智能告警uuid和与此告警相关位置的id + * @param almInfoList 原始告警智能指针集合 + * @param aiuuid 智能告警aiuuid + */ + void addaitolocation(const QList &almInfoList, const QString &aiuuid); + /** + * @brief initaivideo initaivideo 初始化智能告警下原始告警的相关信息 + * @param msg + */ + void initaivideo(AiAlarmMsgPtr msg); + /** + * @brief updatealarm 更新需要展示在智能告警窗上未聚类的原始告警 + * @param uuidVec 某条智能告警下的所有原始告警的uuid + * @param deluuidVec 需要被删除的一级节点上的未聚类的原始告警uuid + */ + void updatealarm(QVector &uuidVec, QVector &deluuidVec); + /** + * @brief almStats 告警统计 + * @param msg 告警指针 + * @param addOrSub 1--add 0--sub(1添加,0删除) + */ + void almStats(const AlarmMsgPtr &msg,int addOrSub); + /** + * @brief almAddStats 告警添加统计 + * @param msg 告警指针 + */ + void almAddStats(const AlarmMsgPtr &msg); + /** + * @brief almSubStats 告警删除统计 + * @param msg 告警指针 + */ + void almSubStats(const AlarmMsgPtr &msg); + /** + * @brief devDevGTotAlmAddStats 设备设备组按优先级添加统计 + * @param msg 告警指针 + */ + void devDevGTotAlmAddStats(const AlarmMsgPtr &msg); + /** + * @brief devDevGTotAlmSubStats 设备设备组按优先级删除统计 + * @param msg 告警指针 + */ + void devDevGTotAlmSubStats(const AlarmMsgPtr &msg); + void devDevGAddStats(const AlarmMsgPtr &msg); + void devDevGSubStats(const AlarmMsgPtr &msg); + void locAddStats(const AlarmMsgPtr &msg); + void locSubStats(const AlarmMsgPtr &msg); + /** + * @brief addNotConfirmAlm 添加未确认的告警uuid + * @param locId + * @param devg + * @param uuid + */ + void addNotConfirmAlm(int locId,const QString &devg,const QString &uuid); + /** + * @brief delNotConfirmAlm 从未确认的告警uuid集合中删除(删除的不一定被确认 可能是数据重发) + * @param locId + * @param devg + * @param uuid + */ + void delNotConfirmAlm(int locId,const QString &devg,const QString &uuid); +signals: + /** + * @brief sigAiMsgRemove 通知智能告警模型删除智能告警 + * @param aiuuidList 智能告警aiuuid列表 + */ + void sigAiMsgRemove(const QList & aiuuidList); + /** + * @brief sigAiMsgAdd 通知智能告警模型添加某条智能告警 + * @param aimsgList 智能告警指针列表 + */ + void sigAiMsgAdd(const QList& aimsgList); + /** + * @brief sigMsgRemove 通知智能告警模型删除一级节点上的原始告警 + * @param deluuid 需要删除的原始告警uuid的集合 + */ + void sigMsgRemove(const QVector deluuid); +public: + /** + * @brief queryLocationDesc 根据智能告警uuid查询位置描述(可能包含多个位置) + * @param aiuuid 智能告警uuid + * @return 位置描述 + */ + QString queryLocationDesc(QString &aiuuid); + /** + * @brief queryConfirm 根据智能告警uuid查询确认数和总数 + * @param aiuuid 智能告警uuid + * @return 确认数/总数(ex:20/30) + */ + QString queryConfirm(const QString &aiuuid); + /** + * @brief queryAiTotal 根据智能告警uuid 查询原始告警条数 + * @param aiuuid 智能告警uuid + * @return 原始告警条数 + */ + int queryAiTotal(const QString &aiuuid); + /** + * @brief getAlarmInfo 获取所有有权限的原始告警和智能告警 (接口:给智能告警模型使用) + * @param listAlarm 原始告警指针集合 + * @param listaiAlarm 智能告警指针集合 + */ + void getAlarmInfo(QList &listAlarm,QList &listaiAlarm); + /** + * @brief getAlarmPtrByuuid 根据原始告警uuid获取原始告警指针 + * @param uuid 原始告警uuid列表 + * @return 原始告警指针列表 + */ + QList getAlarmPtrByuuid(const QVector &uuidVec); + /** + * @brief ifhaveNotConfirmAlmByuuid 根据智能告警uuid查询是否还有未确认的原始告警 + * @param aiuuid 智能告警uuid + * @return 如果包含未确认原始告警返回true,否则返回false + */ + bool ifhaveNotConfirmAlmByuuid(QString &aiuuid); + /** + * @brief getAiLocationList 根据智能告警uuid获取有关的位置集合 + * @param aiuuid 智能告警uuid + * @return 与之有关的位置集合 + */ + QList getAiLocationList(QString &aiuuid); + /** + * @brief getalmuuidByAiuuid 根据智能告警uuid获取相关原始告警uuid + * @param aiuuid 智能告警uuid + * @return 原始告警uuidList + */ + QList getalmuuidByAiuuid(const QString &aiuuid); + /** + * @brief getAlmTotal 获取智能告警窗显示原始告警总数 + * @return 数量 + */ + int getAlmTotal(); + /** + * @brief getAiCount 获取未过滤时的智能告警条数 + * @return + */ + int getAiCount(); + +private: + + void initAlarm(); + + void initAiAlarm(); + + void insertAudioCues(const AlarmMsgPtr &info); + + void removeAudioCues(const AlarmMsgPtr &info); + + void setReadFlag(); + +private: + static CAlarmMsgManage * pInstance; + + QMutex * mutex; + + kbd_dbms::CRdbAccess * m_rtdbAlarmActionAccess; + kbd_dbms::CRdbAccess * m_rtdbLocationDescriptionAccess; + kbd_dbms::CRdbAccess * m_rtdbAppDescriptionAccess; + + int m_nNDelComAlarmCount; //< 未删除未确认数量 N--not Del--delete Com--confirm + QHash m_infos; + QHash m_all; + + + QList m_listPermLocationId; //< 原始告警车站权限 + QList m_listPermRegionId; //< 原始告警责任区权限 + + + //缓存从collect调整到mng + QList m_listMsgAddCache; //< 告警缓存(每秒更新) + QList m_inhibitFilter; //< 告警抑制[界面] + + //智能告警新加 + QHash m_alarm; //< 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗)(两个线程共同维护) + QHash m_aiinfos; //< 有权限的智能告警 + QHash m_aiall; //< 所有智能告警 + + QHash m_aicount; //< <智能告警uuid,已确认数/总数 > + QHash m_idToid; //< <原始告警uuid,智能告警uuid > 用于确认原始告警之后便于更新智能告警中的已确认总数 + + QHash > m_aitolocation;//< <智能告警uuid,包含的原始告警车站id> + + QHash m_alarmDeviceStatistical; //< 设备告警数量统计 + QHash m_alarmDeviceGroupStatistical; //<设备组告警数量统计 + QHash > m_alarmDevPriority; //< 设备告警等级数量统计 + QHash > > m_alarmDGPDev; //< <设备组,<告警等级,设备> > + QHash > m_alarmLPAlm; //< <车站id,<告警等级,告警数量> > + + QHash > > m_alarmLNCAlm;//< <车站id,<设备组,<未确认告警uuid> > > + + QList m_delaydeal; //延迟处理的智能告警 + + int m_nAlmNum; //智能告警窗原始告警个数 + int m_nAlmTotal; //智能告警窗原始告警总数 + + QList m_playerList; + + QString m_strMediaPath; +}; + +#endif // CALARMMSGMANAGE_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.cpp index ac3bea99..5eee59ca 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.cpp @@ -1,1390 +1,1390 @@ -#include "CAlarmPlugin.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "CAlarmView.h" -#include "CAlarmForm.h" -#include "CAlarmWidget.h" -#include "CAlarmItemModel.h" -#include "CAlarmDelegate.h" -#include "CAiAlarmDataCollect.h" -#include "CAlarmDataCollect.h" -#include "CAlarmMsgManage.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/FileStyle.h" -#include -#include "CAlarmBaseData.h" - -QThread * CAlarmPlugin::m_pDataCollectThread = NULL; -QThread * CAlarmPlugin::m_pMediaPlayerThread = NULL; -CAlarmPlugin::CAlarmPlugin(QWidget *parent, bool editMode) - : QWidget(parent), - m_mode(E_Alarm_Window), - m_bIsEditMode(editMode), - m_alarmForm(Q_NULLPTR), - m_alarmWidget(Q_NULLPTR), - m_alarmView(Q_NULLPTR), - m_pModel(Q_NULLPTR), - m_pTreeModel(Q_NULLPTR), - m_enableAi(false) -{ - QString qss = QString(); -#ifdef OS_LINUX - QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/plugins"); -#endif - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - qRegisterMetaType< CAlarmMsgInfo >("CAlarmMsgInfo"); - qRegisterMetaType< AlarmMsgPtr >("AlarmMsgPtr"); - qRegisterMetaType< QList >("ListAlarmMsgPtr"); - - if(!m_bIsEditMode) - { - CAlarmBaseData::instance(); -// if(!m_pMediaPlayerThread) -// { -// m_pMediaPlayerThread = new QThread(); -// CAlarmMediaPlayer::instance()->moveToThread(m_pMediaPlayerThread); -// m_pMediaPlayerThread->start(); -// } - if(!m_pDataCollectThread) - { - m_pDataCollectThread = new QThread(); - CAlarmMsgManage::instance()->moveToThread(m_pDataCollectThread); - CAlarmSetMng::instance()->moveToThread(m_pDataCollectThread); - - connect(m_pDataCollectThread, &QThread::started, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::initialize, Qt::QueuedConnection); - connect(m_pDataCollectThread, &QThread::started, CAlarmDataCollect::instance(), &CAlarmDataCollect::initialize, Qt::QueuedConnection); - connect(m_pDataCollectThread, &QThread::finished, m_pDataCollectThread, &QThread::deleteLater, Qt::QueuedConnection); - m_pDataCollectThread->start(); - } - connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigAlarmStateChanged, this, &CAlarmPlugin::recvAlarmNumChanged, Qt::QueuedConnection); - //connect(this, &CAlarmPlugin::sigSwitchFaultRecallState, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::slotSwitchFaultRecallState, Qt::QueuedConnection); - connect(this, &CAlarmPlugin::sigSwitchFaultRecallState, CAlarmDataCollect::instance(), &CAlarmDataCollect::slotSwitchFaultRecallState, Qt::QueuedConnection); - CAlarmDataCollect::instance()->refrence(); - CAiAlarmDataCollect::instance()->refrence(); - connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigUpdateAlarmView, this, &CAlarmPlugin::slotUpdateAlarmView, Qt::QueuedConnection); - connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigAlarmOperateEnable, this, &CAlarmPlugin::slotUpdateAlarmOperateEnable, Qt::QueuedConnection); - connect(this,&CAlarmPlugin::sigLogin,CAlarmMsgManage::instance(),&CAlarmMsgManage::slotLogin, Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAllViewReload,this,&CAlarmPlugin::slotAllViewReload, Qt::QueuedConnection); - } -} - -CAlarmPlugin::~CAlarmPlugin() -{ - if(!m_bIsEditMode) - { - - int almCount = CAlarmDataCollect::instance()->getRefrenceCount(); - int aialmCount = CAiAlarmDataCollect::instance()->getRefrenceCount(); - CAlarmDataCollect::instance()->destory(); - CAiAlarmDataCollect::instance()->destory(); - if(1 == almCount || aialmCount == 1) - { - //< 退出托管线程 - if(m_pDataCollectThread) - { - m_pDataCollectThread->quit(); - m_pDataCollectThread->wait(); - delete m_pDataCollectThread; - } - m_pDataCollectThread = Q_NULLPTR; - CAlarmMsgManage::instance()->destory(); - CAlarmSetMng::instance()->destory(); - -// if(m_pMediaPlayerThread) -// { -// m_pMediaPlayerThread->quit(); -// m_pMediaPlayerThread->wait(); -// delete m_pMediaPlayerThread; -// } -// m_pMediaPlayerThread = Q_NULLPTR; - CAlarmMediaPlayer::instance()->destory(); - CAlarmBaseData::instance()->destory(); - } - } - reset(); - int mode = (int)m_mode; - LOGDEBUG("CAlarmPlugin::~CAlarmPlugin()model[%d]",mode); -} - -void CAlarmPlugin::initialize(int mode) -{ - if(E_Alarm_Dock != mode && E_Alarm_Window != mode && E_Alarm_Pop != mode) - { - return; - } - reset(); - - updateAlarmOperatePerm(); - - m_mode = (E_Alarm_Mode)mode; - - //初始界面:视图、模型 - QHBoxLayout * layout = new QHBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->setMargin(0); - if (E_Alarm_Window == mode) - { - loadConfig(); - m_alarmForm = new CAlarmForm(); - if(!m_bIsEditMode) - { - m_alarmForm->initialize(); - m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); - if(m_enableAi) - { - m_pTreeModel = new CAiAlarmTreeModel(this); - m_alarmForm->setAlarmModel(m_pModel,m_pTreeModel); - }else - { - m_alarmForm->setAlarmModel(m_pModel); - } - - connect(m_alarmForm, &CAlarmForm::closeBtnClicked, this, &CAlarmPlugin::closeBtnClicked, Qt::QueuedConnection); - connect(m_alarmForm,&CAlarmForm::openTrend,this,&CAlarmPlugin::openTrendDialog,Qt::QueuedConnection); - connect(m_alarmForm,&CAlarmForm::openVideo,this,&CAlarmPlugin::openVideoDialog,Qt::QueuedConnection); - connect(m_alarmForm,&CAlarmForm::openAccidentReview,this,&CAlarmPlugin::openAccidentReviewDialog,Qt::QueuedConnection); - } - else - { - m_alarmForm->setEnabled(false); - } - layout->addWidget(m_alarmForm); - } - else if (E_Alarm_Dock == mode) - { - m_alarmWidget = new CAlarmWidget(); - if(!m_bIsEditMode) - { - m_alarmWidget->initialize(); - m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); - m_alarmWidget->setAlarmModel(m_pModel); - - connect(m_alarmWidget, &CAlarmWidget::alarmWidgetDoubleClicked, this, &CAlarmPlugin::alarmDockDoubleClicked, Qt::QueuedConnection);// dock 双击 - connect(m_alarmWidget, &CAlarmWidget::openVideo, this, &CAlarmPlugin::openVideoDialog, Qt::QueuedConnection); - connect(m_alarmWidget, &CAlarmWidget::openTrend, this, &CAlarmPlugin::openTrendDialog, Qt::QueuedConnection); - if(!CAlarmMsgManage::instance()->isBindMediaPlayer())//判断信号是否被连接 - { - //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigInsertAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::insertAudioCues, Qt::QueuedConnection); - //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigStopAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::removeAudioCues, Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigReadFlag, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::slotReadFlag, Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigAlarmPushGraph, this, &CAlarmPlugin::alarmPush, Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigAlarmPushGraphClear, this, &CAlarmPlugin::alarmPushClear, Qt::QueuedConnection); - //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigClearAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::clearAudioCues, Qt::QueuedConnection); - connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,CAlarmMediaPlayer::instance(),&CAlarmMediaPlayer::slotLoadConfig,Qt::QueuedConnection); - } -// if(!CAlarmSetMng::instance()->isBindMediaPlayer()) -// { -// connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,CAlarmMediaPlayer::instance(),&CAlarmMediaPlayer::slotLoadConfig,Qt::QueuedConnection); -// } - } - else - { - m_alarmWidget->initializeEdit(); - m_alarmWidget->setEnabled(false); - } - layout->addWidget(m_alarmWidget); - } - else if (E_Alarm_Pop == mode) - { - m_alarmView = new CAlarmView(this); - if(!m_bIsEditMode) - { - m_alarmView->initialize(); - m_alarmView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); - m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); - m_alarmView->setModel(m_pModel); - connect(m_alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); - m_alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); - CAlarmDelegate * pDelegate = new CAlarmDelegate(m_pModel, this); - m_alarmView->setItemDelegate(pDelegate); - connect(pDelegate,&CAlarmDelegate::openVideo,this, &CAlarmPlugin::openVideoDialog, Qt::QueuedConnection); - connect(pDelegate,&CAlarmDelegate::openTrend,this, &CAlarmPlugin::openTrendDialog, Qt::QueuedConnection); - connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,pDelegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); - } - else - { - m_alarmView->setEnabled(false); - } - layout->addWidget(m_alarmView); - } - setLayout(layout); - slotUpdateAlarmOperateEnable(!CAlarmDataCollect::instance()->isFaultRecallState()); -} - -void CAlarmPlugin::loadConfig() -{ - QFile file(kbd_public::CFileUtil::getPathOfCfgFile("intelli_alm_cfg.xml",CN_DIR_PLATFORM).c_str()); - if (!file.open(QFile::ReadWrite)) - { - LOGERROR("打开智能告警配置文件失败,默认不启动"); - return; - } - - QDomDocument doc; - if (!doc.setContent(&file)) - { - file.close(); - LOGERROR("加载智能告警配置文件失败,默认不启动"); - return; - } - file.close(); - - QDomElement root = doc.documentElement(); //返回根节点 root - QDomNode node = root.firstChild(); //获得第一个子节点 - - while (!node.isNull()) //如果节点不空 - { - QDomElement element = node.toElement(); - if(element.tagName() == "intelli_alm_srv") - { - if(element.attribute("enable") == "true") - { - m_enableAi =true; - }else - { - m_enableAi =false; - } - break; - } - node = node.nextSibling(); - } -} - -void CAlarmPlugin::login() -{ - if(!m_bIsEditMode) - { - LOGINFO("CAlarmPlugin::login():"); - if(m_mode != E_Alarm_Dock && m_mode != E_Alarm_Pop) - { - return ; - } - if(m_pModel == NULL) - { - LOGERROR("登录出错,空指针!"); - return ; - } - CAlarmBaseData::instance()->initData(); - updateAlarmOperatePerm(); - emit sigLogin(); - } -} - -void CAlarmPlugin::logout() -{ -// if(!m_bIsEditMode) -// { -// updateAlarmOperatePerm(); -// CAiAlarmDataCollect::instance()->release(); -// CAlarmMediaPlayer::instance()->release(); -// } -} - -void CAlarmPlugin::switchFaultRecallState(bool bFaultRecallState) -{ - if(!m_bIsEditMode) - { - updateAlarmOperatePerm(); - CAlarmMediaPlayer::instance()->release(); - emit sigSwitchFaultRecallState(bFaultRecallState); - } -} - -int CAlarmPlugin::confirmAlarm(const QList &msgs) -{ - int cofirmNum = 0; - if(msgs.isEmpty()) - { - return cofirmNum; - } - - if(m_vecRegionOptId.empty() || m_vecLocationOptId.empty()) - { - return cofirmNum; - } - //< 可能有部分告警没有确认权限 - QMap pkgMap; //Domain-DelPkg; - for(int nIndex(0); nIndex < msgs.size(); nIndex++) - { - AlarmMsgPtr info = msgs.at(nIndex); - if(E_ALS_ALARM != info->logic_state && E_ALS_RETURN != info->logic_state) - { - continue; - } - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionOptId.begin(); - while (region != m_vecRegionOptId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationOptId.begin(); - while (location != m_vecLocationOptId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - QString key = QString("%1_%2_%3").arg(info->domain_id).arg(info->alm_type).arg(info->app_id); - QMap::iterator it = pkgMap.find(key); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); - pkg->set_node_name(m_currentNodeName); - pkg->set_user_id(m_currentUsrId); - pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); - pkg->set_domain_id(info->domain_id); - pkg->set_app_id(info->app_id); - pkg->set_alm_type(info->alm_type); - pkgMap[key] = pkg; - } - cofirmNum++; - pkgMap.value(key)->add_time_stamp(info->time_stamp); - pkgMap.value(key)->add_uuid_base64(info->uuid_base64.toStdString()); - pkgMap.value(key)->add_key_id_tag(info->key_id_tag.toStdString()); - } - } - //请求确认 - foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) - { - if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) - { - cofirmNum = cofirmNum -pkg->uuid_base64_size(); - LOGERROR("请求告警确认失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - return cofirmNum; -} - -int CAlarmPlugin::removeAlarm(const QList &msgs) -{ - if(msgs.isEmpty()) - { - return -1; - } - - if(m_vecRegionDelId.empty() || m_vecLocationDelId.empty()) - { - return -1; - } - //< 可能有部分告警没有删除权限 - QMap pkgMap; - for(int nIndex(0); nIndex < msgs.size(); nIndex++) - { - AlarmMsgPtr info = msgs.at(nIndex); - - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionDelId.begin(); - while (region != m_vecRegionDelId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationDelId.begin(); - while (location != m_vecLocationDelId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - QMap::iterator it = pkgMap.find(info->domain_id); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); - pkg->set_domain_id(info->domain_id); - pkgMap[info->domain_id] = pkg; - } - pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); - } - } - //请求删除 - foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) - { - if(CAlarmDataCollect::instance()->requestDelAlm(*pkg) != true) - { - LOGERROR("请求删除告警失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - return 0; -} - - -void CAlarmPlugin::setVolumeEnable(bool bEnable) -{ - CAlarmMediaPlayer::instance()->setVolumeEnable(bEnable); -} - -void CAlarmPlugin::recvAlarmNumChanged(const int &total, const int &unConfirm) -{ - emit alarmNumChanged(total, unConfirm); -} - -void CAlarmPlugin::setColumnAlign(const int &column, const int &alignFlag) -{ - if(m_bIsEditMode) - { - return; - } - if(!m_pModel) - { - return; - } - m_pModel->setColumnAlign(column, alignFlag); -} - -void CAlarmPlugin::setEnableAccidentReview(bool isNeed) -{ - if(m_bIsEditMode) - { - return; - } - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->setEnableAccidentReview(isNeed); - } -} - -void CAlarmPlugin::setAccidentReviewPath(const QString &path) -{ - if(m_bIsEditMode) - { - return; - } - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->setAccidentReviewPath(path); - } -} - -void CAlarmPlugin::setShowAiAlarmView(bool show) -{ - if(m_bIsEditMode) - { - return; - } - - if(E_Alarm_Window != m_mode || m_alarmForm == Q_NULLPTR ) - { - return; - } - m_alarmForm->setShowAiAlarmView(show); -} - -void CAlarmPlugin::setEnableTrend(bool isNeed) -{ - if(m_bIsEditMode) - { - return; - } - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->setEnableTrend(isNeed); - }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->setEnableTrend(isNeed); - }else if(E_Alarm_Pop == m_mode) - { - ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableTrend(isNeed); - } -} - -void CAlarmPlugin::setEnableVideo(bool isNeed) -{ - if(m_bIsEditMode) - { - return; - } - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->setEnableVideo(isNeed); - }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->setEnableVideo(isNeed); - }else if(E_Alarm_Pop == m_mode) - { - ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableVideo(isNeed); - } -} - -void CAlarmPlugin::setEnableWave(bool isNeed) -{ - if(m_bIsEditMode) - { - return; - } - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->setEnableWave(isNeed); - }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->setEnableWave(isNeed); - }else if(E_Alarm_Pop == m_mode) - { - ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableWave(isNeed); - } -} - -void CAlarmPlugin::setEnableLevel(bool isNeed) -{ - if(m_bIsEditMode) - { - return; - } - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->setEnableLevel(isNeed); - }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->setEnableLevel(isNeed); - }else if(E_Alarm_Pop == m_mode) - { - ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableLevel(isNeed); - } -} - -void CAlarmPlugin::setDockRowHeight(const int &height) -{ - if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->setRowHeight(height); - return ; - } - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->setRowHeight(height); - return ; - } - if(E_Alarm_Pop == m_mode && m_alarmView != Q_NULLPTR) - { - m_alarmView->setDefaultRowHeight(height); - return ; - } -} - -void CAlarmPlugin::setDockColumnVisible(const int &column, const bool &visbile) -{ - if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->setDockColumnVisible(column, visbile); - } -} - -int CAlarmPlugin::confirmAllPermAlarm(bool tips) -{ - int result = 0; - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - - if(m_bIsEditMode || E_Alarm_Dock != m_mode || bFaultRecallState) - { - return result; - } - if(!m_alarmWidget || !m_pModel) - { - return result; - } - QList msgs =CAlarmMsgManage::instance()->getListAlarmInfo(); - int confirmNum = confirmAlarm(msgs); - if(tips) - { - QMessageBox::information(this, tr("提示"), tr("此次一共确认")+QString::number(confirmNum)+tr("条告警"), QMessageBox::Ok); - } - return confirmNum; -} - -QStringList CAlarmPlugin::getDevAlmInfo(const QString device) -{ - QMap alarm = CAlarmMsgManage::instance()->getDevAlarm(device); - QStringList result; - result.clear(); - QMap::iterator it= alarm.begin(); - while (it!= alarm.end()) { - QString alarmNum= QString("%1_%2").arg(it.key()).arg(it.value()); - result.append(alarmNum); - it++; - } - return result; -} - -QStringList CAlarmPlugin::getDevGroupAlmInfo(const QString deviceGroup) -{ - QMap > listMap = CAlarmMsgManage::instance()->getDevGroupPriorityDevNum(deviceGroup); - QStringList result; - result.clear(); - QMap >::iterator it =listMap.begin(); - for(;it != listMap.end();it++) - { - //优先级_设备数量 - QString priDev= QString("%1_%2").arg(it.key()).arg(it.value().size()); - result.append(priDev); - } - return result; -} - -QStringList CAlarmPlugin::getLocAlmInfo() -{ - QHash > locAlm = CAlarmMsgManage::instance()->getLocAlmInfo(); - QStringList list; - list.clear(); - QHash >::iterator it = locAlm.begin(); - while (it != locAlm.end()) { - QMap &priAlmNum =it.value(); - QMap::iterator pos = priAlmNum.begin(); - while (pos != priAlmNum.end()) { - QString priAlm = QString("%1_%2_%3").arg(it.key()).arg(pos.key()).arg(pos.value()); - list.append(priAlm); - pos++; - } - it++; - } - return list; -} - -int CAlarmPlugin::getLocNotConfirmAlmCount(int loc) -{ - int count =0; - if(loc<0) - { - return count; - } - QHash > > locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); - - QHash > >::iterator it = locCountMap.find(loc); - if(it !=locCountMap.end()) - { - QMap > devgCountMap = it.value(); - QMap >::iterator pos = devgCountMap.begin(); - while (pos != devgCountMap.end()) { - - count += pos.value().count(); - pos++; - } - } - - return count; -} - -int CAlarmPlugin::getDevgNotConfirmAlmCount(const QString &devg) -{ - int count =0; - if(devg.isEmpty()) - { - return count; - } - QHash > > locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); - - QHash > >::iterator it = locCountMap.begin(); - while (it !=locCountMap.end()) - { - QMap > devgCountMap = it.value(); - QMap >::iterator pos = devgCountMap.find(devg); - if(pos != devgCountMap.end()) - { - count = pos.value().count(); - break; - } - it++; - } - - return count; -} - -void CAlarmPlugin::setHiddenLocation(bool hide) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setHiddenLocation(hide); - } -} - -void CAlarmPlugin::setHiddenTime(bool hide) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setHiddenTime(hide); - } -} - -void CAlarmPlugin::setHiddenStatus(bool hide) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setHiddenStatus(hide); - } -} - -void CAlarmPlugin::setHiddenPriority(bool hide) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setHiddenPriority(hide); - } -} - -void CAlarmPlugin::setHiddenCheckBox(bool hide) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setHiddenCheckBox(hide); - } -} - -void CAlarmPlugin::setHiddenSetConfig(bool hide) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setHiddenSetConfig(hide); - } -} - -void CAlarmPlugin::setHiddenCloseButton(bool hide) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setHiddenCloseButton(hide); - } -} - -void CAlarmPlugin::setHiddenInhiAlarmButton(bool hide) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setHiddenInhiAlarmButton(hide); - } -} - -void CAlarmPlugin::setFormColumnVisible(const int &column, const bool &visible) -{ - if(m_bIsEditMode || E_Alarm_Window != m_mode) - { - return; - } - if(!m_alarmForm) - { - return ; - }else - { - m_alarmForm->setColumnVisible(column, visible); - } -} - -void CAlarmPlugin::setDevice(const QString &device) -{ - if(m_bIsEditMode || E_Alarm_Pop != m_mode) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - m_pModel->addDeviceFilter(device); -} - -void CAlarmPlugin::setDeviceGroup(const QString &deviceGroup) -{ - if(m_bIsEditMode || E_Alarm_Pop != m_mode) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - if(deviceGroup.isEmpty()) - { - m_pModel->addDeviceGroupFilter(); - }else - { - m_pModel->addDeviceGroupFilter(deviceGroup); - } - -} - -void CAlarmPlugin::setPointTag(const QString &pointList) -{ - if(m_bIsEditMode || E_Alarm_Pop != m_mode) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - QStringList s= pointList.split(","); - QList pointTagList; - for(int i = 0;iaddPointTagFilter(pointTagList); -} - -void CAlarmPlugin::setColumnVisible(const int &column, const bool &visible) -{ - if(m_bIsEditMode || E_Alarm_Pop != m_mode) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - m_alarmView->setColumnHidden(column, !visible); -} - -void CAlarmPlugin::confirmFirstAlarm(int index) -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Dock != m_mode || bFaultRecallState) - { - return; - } - if(!m_pModel) - { - return; - } - m_alarmWidget->confirmAlarm(index); -} - -void CAlarmPlugin::setColumnWidth(const int &column, const int &width) -{ - if(m_bIsEditMode) - { - return; - } - if(E_Alarm_Window == m_mode) - { - if(!m_alarmForm) - { - return; - } - m_alarmForm->setColumnWidth(column, width); - } - else if(E_Alarm_Dock == m_mode) - { - if(!m_alarmWidget) - { - return; - } - m_alarmWidget->setColumnWidth(column, width); - } - else if(E_Alarm_Pop == m_mode) - { - if(!m_alarmView || !m_pModel) - { - return; - } - m_alarmView->setColumnWidth(column, width); - } -} - -int CAlarmPlugin::currentSelectCount() -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) - { - return 0; - } - if(!m_alarmView || !m_pModel) - { - return 0; - } - QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(); - return listModelIndex.size(); -} - -void CAlarmPlugin::confirmCurrentAlarm() -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(0); - - bool permSkip = false; - QList msgs; - foreach (QModelIndex index, listModelIndex) - { - AlarmMsgPtr info = m_pModel->getAlarmInfo(index); - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionOptId.begin(); - while (region != m_vecRegionOptId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationOptId.begin(); - while (location != m_vecLocationOptId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - msgs.append(info); - } - else - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox.setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox.addButton(tr("取消"), QMessageBox::RejectRole); - msgBox.setDefaultButton(skip); - msgBox.exec(); - if (msgBox.clickedButton() == skip) - { - continue; - } - else if (msgBox.clickedButton() == skipAll) - { - permSkip = true; - continue; - } - else - { - return; - } - } - - } - - confirmAlarm(msgs); - m_alarmView->clearSelection(); -} - -void CAlarmPlugin::confirmAllAlarm() -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - - bool permSkip = false; - QList msgs; - for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) - { - AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionOptId.begin(); - while (region != m_vecRegionOptId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationOptId.begin(); - while (location != m_vecLocationOptId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - msgs.append(info); - } - else - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox.setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox.addButton(tr("取消"), QMessageBox::RejectRole); - msgBox.setDefaultButton(skip); - msgBox.exec(); - if (msgBox.clickedButton() == skip) - { - continue; - } - else if (msgBox.clickedButton() == skipAll) - { - permSkip = true; - continue; - } - else - { - return; - } - } - } - confirmAlarm(msgs); - m_alarmView->clearSelection(); -} - -void CAlarmPlugin::removeAllAlarm() -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - - bool permSkip = false; - bool unConfirmSkip = false; - QList msgs; - for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) - { - AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionDelId.begin(); - while (region != m_vecRegionDelId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationDelId.begin(); - while (location != m_vecLocationDelId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) - { - if(!unConfirmSkip) - { - QMessageBox msgBox; - msgBox.setText(tr("包含未确认告警!")); - msgBox.setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox.addButton(tr("取消"), QMessageBox::RejectRole); - msgBox.setDefaultButton(skip); - msgBox.exec(); - if (msgBox.clickedButton() == skip) - { - continue; - } - else if (msgBox.clickedButton() == skipAll) - { - unConfirmSkip = true; - continue; - } - else - { - return; - } - } - else - { - continue; - } - } - else - { - msgs.append(info); - } - } - else - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox.setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox.addButton(tr("取消"), QMessageBox::RejectRole); - msgBox.setDefaultButton(skip); - msgBox.exec(); - if (msgBox.clickedButton() == skip) - { - continue; - } - else if (msgBox.clickedButton() == skipAll) - { - permSkip = true; - continue; - } - else - { - return; - } - } - } - removeAlarm(msgs); - m_alarmView->clearSelection(); -} - -void CAlarmPlugin::slotUpdateAlarmView() -{ - if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->updateView(); - } - else if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->updateView(); - } - else if(E_Alarm_Pop == m_mode && m_alarmView != Q_NULLPTR) - { - m_alarmView->viewport()->update(); - } -} - -void CAlarmPlugin::slotUpdateAiAlarmView() -{ - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->updateView(); - } - -} - -void CAlarmPlugin::slotUpdateAlarmOperateEnable(const bool &bEnable) -{ - if(!m_bIsEditMode) - { - if (E_Alarm_Window == m_mode) - { - m_alarmForm->setAlarmOperateEnable(bEnable); - - } - else if (E_Alarm_Dock == m_mode) - { - m_alarmWidget->setAlarmOperateEnable(bEnable); - - } - else if (E_Alarm_Pop == m_mode) - { - //< 禁用确认、删除接口, 见E_Alarm_Pop模式接口 - } - } -} - -void CAlarmPlugin::slotAllViewReload() -{ - if(m_mode == E_Alarm_Dock) - { - m_pModel->initialize(); - }else if(m_mode == E_Alarm_Window) - { - m_pModel->initialize(); - if(m_enableAi) - { - m_pTreeModel->initialize(); - } - m_alarmForm->init(); - }else if(m_mode == E_Alarm_Pop) - { - m_pModel->initialize(); - } -} - -void CAlarmPlugin::reset() -{ - if(Q_NULLPTR != m_pModel) - { - m_pModel->disconnect(); - delete m_pModel; - } - m_pModel = Q_NULLPTR; - if(Q_NULLPTR != m_pTreeModel) - { - m_pTreeModel->disconnect(); - delete m_pTreeModel; - } - m_pTreeModel = Q_NULLPTR; - - if(Q_NULLPTR != m_alarmForm) - { - delete m_alarmForm; - } - m_alarmForm = Q_NULLPTR; - - if(Q_NULLPTR != m_alarmWidget) - { - delete m_alarmWidget; - } - m_alarmWidget = Q_NULLPTR; - - if(Q_NULLPTR != m_alarmView) - { - delete m_alarmView; - } - m_alarmView = Q_NULLPTR; - - QLayout * lyt = layout(); - if(Q_NULLPTR != lyt) - { - delete lyt; - } -} - -void CAlarmPlugin::updateAlarmOperatePerm() -{ - m_currentUsrId = -1; - m_currentNodeName = ""; - m_vecRegionOptId.clear(); - m_vecLocationOptId.clear(); - m_vecRegionDelId.clear(); - m_vecLocationDelId.clear(); - - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - - m_currentNodeName = stNodeInfo.strName; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(0 != permMngPtr->CurUser(m_currentUsrId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - LOGERROR("用户ID获取失败!"); - return; - } - if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, m_vecRegionOptId, m_vecLocationOptId)) - { - LOGERROR("用户不具备告警操作权限!"); - } - if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, m_vecRegionDelId, m_vecLocationDelId)) - { - LOGERROR("用户不具备告警删除权限!"); - } - } -} +#include "CAlarmPlugin.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmView.h" +#include "CAlarmForm.h" +#include "CAlarmWidget.h" +#include "CAlarmItemModel.h" +#include "CAlarmDelegate.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmDataCollect.h" +#include "CAlarmMsgManage.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include +#include "CAlarmBaseData.h" + +QThread * CAlarmPlugin::m_pDataCollectThread = NULL; +QThread * CAlarmPlugin::m_pMediaPlayerThread = NULL; +CAlarmPlugin::CAlarmPlugin(QWidget *parent, bool editMode) + : QWidget(parent), + m_mode(E_Alarm_Window), + m_bIsEditMode(editMode), + m_alarmForm(Q_NULLPTR), + m_alarmWidget(Q_NULLPTR), + m_alarmView(Q_NULLPTR), + m_pModel(Q_NULLPTR), + m_pTreeModel(Q_NULLPTR), + m_enableAi(false) +{ + QString qss = QString(); +#ifdef OS_LINUX + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/plugins"); +#endif + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + qRegisterMetaType< CAlarmMsgInfo >("CAlarmMsgInfo"); + qRegisterMetaType< AlarmMsgPtr >("AlarmMsgPtr"); + qRegisterMetaType< QList >("ListAlarmMsgPtr"); + + if(!m_bIsEditMode) + { + CAlarmBaseData::instance(); +// if(!m_pMediaPlayerThread) +// { +// m_pMediaPlayerThread = new QThread(); +// CAlarmMediaPlayer::instance()->moveToThread(m_pMediaPlayerThread); +// m_pMediaPlayerThread->start(); +// } + if(!m_pDataCollectThread) + { + m_pDataCollectThread = new QThread(); + CAlarmMsgManage::instance()->moveToThread(m_pDataCollectThread); + CAlarmSetMng::instance()->moveToThread(m_pDataCollectThread); + + connect(m_pDataCollectThread, &QThread::started, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::initialize, Qt::QueuedConnection); + connect(m_pDataCollectThread, &QThread::started, CAlarmDataCollect::instance(), &CAlarmDataCollect::initialize, Qt::QueuedConnection); + connect(m_pDataCollectThread, &QThread::finished, m_pDataCollectThread, &QThread::deleteLater, Qt::QueuedConnection); + m_pDataCollectThread->start(); + } + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigAlarmStateChanged, this, &CAlarmPlugin::recvAlarmNumChanged, Qt::QueuedConnection); + //connect(this, &CAlarmPlugin::sigSwitchFaultRecallState, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::slotSwitchFaultRecallState, Qt::QueuedConnection); + connect(this, &CAlarmPlugin::sigSwitchFaultRecallState, CAlarmDataCollect::instance(), &CAlarmDataCollect::slotSwitchFaultRecallState, Qt::QueuedConnection); + CAlarmDataCollect::instance()->refrence(); + CAiAlarmDataCollect::instance()->refrence(); + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigUpdateAlarmView, this, &CAlarmPlugin::slotUpdateAlarmView, Qt::QueuedConnection); + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigAlarmOperateEnable, this, &CAlarmPlugin::slotUpdateAlarmOperateEnable, Qt::QueuedConnection); + connect(this,&CAlarmPlugin::sigLogin,CAlarmMsgManage::instance(),&CAlarmMsgManage::slotLogin, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAllViewReload,this,&CAlarmPlugin::slotAllViewReload, Qt::QueuedConnection); + } +} + +CAlarmPlugin::~CAlarmPlugin() +{ + if(!m_bIsEditMode) + { + + int almCount = CAlarmDataCollect::instance()->getRefrenceCount(); + int aialmCount = CAiAlarmDataCollect::instance()->getRefrenceCount(); + CAlarmDataCollect::instance()->destory(); + CAiAlarmDataCollect::instance()->destory(); + if(1 == almCount || aialmCount == 1) + { + //< 退出托管线程 + if(m_pDataCollectThread) + { + m_pDataCollectThread->quit(); + m_pDataCollectThread->wait(); + delete m_pDataCollectThread; + } + m_pDataCollectThread = Q_NULLPTR; + CAlarmMsgManage::instance()->destory(); + CAlarmSetMng::instance()->destory(); + +// if(m_pMediaPlayerThread) +// { +// m_pMediaPlayerThread->quit(); +// m_pMediaPlayerThread->wait(); +// delete m_pMediaPlayerThread; +// } +// m_pMediaPlayerThread = Q_NULLPTR; + CAlarmMediaPlayer::instance()->destory(); + CAlarmBaseData::instance()->destory(); + } + } + reset(); + int mode = (int)m_mode; + LOGDEBUG("CAlarmPlugin::~CAlarmPlugin()model[%d]",mode); +} + +void CAlarmPlugin::initialize(int mode) +{ + if(E_Alarm_Dock != mode && E_Alarm_Window != mode && E_Alarm_Pop != mode) + { + return; + } + reset(); + + updateAlarmOperatePerm(); + + m_mode = (E_Alarm_Mode)mode; + + //初始界面:视图、模型 + QHBoxLayout * layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setMargin(0); + if (E_Alarm_Window == mode) + { + loadConfig(); + m_alarmForm = new CAlarmForm(); + if(!m_bIsEditMode) + { + m_alarmForm->initialize(); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + if(m_enableAi) + { + m_pTreeModel = new CAiAlarmTreeModel(this); + m_alarmForm->setAlarmModel(m_pModel,m_pTreeModel); + }else + { + m_alarmForm->setAlarmModel(m_pModel); + } + + connect(m_alarmForm, &CAlarmForm::closeBtnClicked, this, &CAlarmPlugin::closeBtnClicked, Qt::QueuedConnection); + connect(m_alarmForm,&CAlarmForm::openTrend,this,&CAlarmPlugin::openTrendDialog,Qt::QueuedConnection); + connect(m_alarmForm,&CAlarmForm::openVideo,this,&CAlarmPlugin::openVideoDialog,Qt::QueuedConnection); + connect(m_alarmForm,&CAlarmForm::openAccidentReview,this,&CAlarmPlugin::openAccidentReviewDialog,Qt::QueuedConnection); + } + else + { + m_alarmForm->setEnabled(false); + } + layout->addWidget(m_alarmForm); + } + else if (E_Alarm_Dock == mode) + { + m_alarmWidget = new CAlarmWidget(); + if(!m_bIsEditMode) + { + m_alarmWidget->initialize(); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + m_alarmWidget->setAlarmModel(m_pModel); + + connect(m_alarmWidget, &CAlarmWidget::alarmWidgetDoubleClicked, this, &CAlarmPlugin::alarmDockDoubleClicked, Qt::QueuedConnection);// dock 双击 + connect(m_alarmWidget, &CAlarmWidget::openVideo, this, &CAlarmPlugin::openVideoDialog, Qt::QueuedConnection); + connect(m_alarmWidget, &CAlarmWidget::openTrend, this, &CAlarmPlugin::openTrendDialog, Qt::QueuedConnection); + if(!CAlarmMsgManage::instance()->isBindMediaPlayer())//判断信号是否被连接 + { + //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigInsertAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::insertAudioCues, Qt::QueuedConnection); + //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigStopAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::removeAudioCues, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigReadFlag, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::slotReadFlag, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigAlarmPushGraph, this, &CAlarmPlugin::alarmPush, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigAlarmPushGraphClear, this, &CAlarmPlugin::alarmPushClear, Qt::QueuedConnection); + //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigClearAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::clearAudioCues, Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,CAlarmMediaPlayer::instance(),&CAlarmMediaPlayer::slotLoadConfig,Qt::QueuedConnection); + } +// if(!CAlarmSetMng::instance()->isBindMediaPlayer()) +// { +// connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,CAlarmMediaPlayer::instance(),&CAlarmMediaPlayer::slotLoadConfig,Qt::QueuedConnection); +// } + } + else + { + m_alarmWidget->initializeEdit(); + m_alarmWidget->setEnabled(false); + } + layout->addWidget(m_alarmWidget); + } + else if (E_Alarm_Pop == mode) + { + m_alarmView = new CAlarmView(this); + if(!m_bIsEditMode) + { + m_alarmView->initialize(); + m_alarmView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + m_alarmView->setModel(m_pModel); + connect(m_alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); + m_alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + CAlarmDelegate * pDelegate = new CAlarmDelegate(m_pModel, this); + m_alarmView->setItemDelegate(pDelegate); + connect(pDelegate,&CAlarmDelegate::openVideo,this, &CAlarmPlugin::openVideoDialog, Qt::QueuedConnection); + connect(pDelegate,&CAlarmDelegate::openTrend,this, &CAlarmPlugin::openTrendDialog, Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,pDelegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + } + else + { + m_alarmView->setEnabled(false); + } + layout->addWidget(m_alarmView); + } + setLayout(layout); + slotUpdateAlarmOperateEnable(!CAlarmDataCollect::instance()->isFaultRecallState()); +} + +void CAlarmPlugin::loadConfig() +{ + QFile file(kbd_public::CFileUtil::getPathOfCfgFile("intelli_alm_cfg.xml",CN_DIR_PLATFORM).c_str()); + if (!file.open(QFile::ReadWrite)) + { + LOGERROR("打开智能告警配置文件失败,默认不启动"); + return; + } + + QDomDocument doc; + if (!doc.setContent(&file)) + { + file.close(); + LOGERROR("加载智能告警配置文件失败,默认不启动"); + return; + } + file.close(); + + QDomElement root = doc.documentElement(); //返回根节点 root + QDomNode node = root.firstChild(); //获得第一个子节点 + + while (!node.isNull()) //如果节点不空 + { + QDomElement element = node.toElement(); + if(element.tagName() == "intelli_alm_srv") + { + if(element.attribute("enable") == "true") + { + m_enableAi =true; + }else + { + m_enableAi =false; + } + break; + } + node = node.nextSibling(); + } +} + +void CAlarmPlugin::login() +{ + if(!m_bIsEditMode) + { + LOGINFO("CAlarmPlugin::login():"); + if(m_mode != E_Alarm_Dock && m_mode != E_Alarm_Pop) + { + return ; + } + if(m_pModel == NULL) + { + LOGERROR("登录出错,空指针!"); + return ; + } + CAlarmBaseData::instance()->initData(); + updateAlarmOperatePerm(); + emit sigLogin(); + } +} + +void CAlarmPlugin::logout() +{ +// if(!m_bIsEditMode) +// { +// updateAlarmOperatePerm(); +// CAiAlarmDataCollect::instance()->release(); +// CAlarmMediaPlayer::instance()->release(); +// } +} + +void CAlarmPlugin::switchFaultRecallState(bool bFaultRecallState) +{ + if(!m_bIsEditMode) + { + updateAlarmOperatePerm(); + CAlarmMediaPlayer::instance()->release(); + emit sigSwitchFaultRecallState(bFaultRecallState); + } +} + +int CAlarmPlugin::confirmAlarm(const QList &msgs) +{ + int cofirmNum = 0; + if(msgs.isEmpty()) + { + return cofirmNum; + } + + if(m_vecRegionOptId.empty() || m_vecLocationOptId.empty()) + { + return cofirmNum; + } + //< 可能有部分告警没有确认权限 + QMap pkgMap; //Domain-DelPkg; + for(int nIndex(0); nIndex < msgs.size(); nIndex++) + { + AlarmMsgPtr info = msgs.at(nIndex); + if(E_ALS_ALARM != info->logic_state && E_ALS_RETURN != info->logic_state) + { + continue; + } + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionOptId.begin(); + while (region != m_vecRegionOptId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationOptId.begin(); + while (location != m_vecLocationOptId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + QString key = QString("%1_%2_%3").arg(info->domain_id).arg(info->alm_type).arg(info->app_id); + QMap::iterator it = pkgMap.find(key); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); + pkg->set_node_name(m_currentNodeName); + pkg->set_user_id(m_currentUsrId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(info->domain_id); + pkg->set_app_id(info->app_id); + pkg->set_alm_type(info->alm_type); + pkgMap[key] = pkg; + } + cofirmNum++; + pkgMap.value(key)->add_time_stamp(info->time_stamp); + pkgMap.value(key)->add_uuid_base64(info->uuid_base64.toStdString()); + pkgMap.value(key)->add_key_id_tag(info->key_id_tag.toStdString()); + } + } + //请求确认 + foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) + { + cofirmNum = cofirmNum -pkg->uuid_base64_size(); + LOGERROR("请求告警确认失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + return cofirmNum; +} + +int CAlarmPlugin::removeAlarm(const QList &msgs) +{ + if(msgs.isEmpty()) + { + return -1; + } + + if(m_vecRegionDelId.empty() || m_vecLocationDelId.empty()) + { + return -1; + } + //< 可能有部分告警没有删除权限 + QMap pkgMap; + for(int nIndex(0); nIndex < msgs.size(); nIndex++) + { + AlarmMsgPtr info = msgs.at(nIndex); + + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionDelId.begin(); + while (region != m_vecRegionDelId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationDelId.begin(); + while (location != m_vecLocationDelId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + } + //请求删除 + foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestDelAlm(*pkg) != true) + { + LOGERROR("请求删除告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + return 0; +} + + +void CAlarmPlugin::setVolumeEnable(bool bEnable) +{ + CAlarmMediaPlayer::instance()->setVolumeEnable(bEnable); +} + +void CAlarmPlugin::recvAlarmNumChanged(const int &total, const int &unConfirm) +{ + emit alarmNumChanged(total, unConfirm); +} + +void CAlarmPlugin::setColumnAlign(const int &column, const int &alignFlag) +{ + if(m_bIsEditMode) + { + return; + } + if(!m_pModel) + { + return; + } + m_pModel->setColumnAlign(column, alignFlag); +} + +void CAlarmPlugin::setEnableAccidentReview(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableAccidentReview(isNeed); + } +} + +void CAlarmPlugin::setAccidentReviewPath(const QString &path) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setAccidentReviewPath(path); + } +} + +void CAlarmPlugin::setShowAiAlarmView(bool show) +{ + if(m_bIsEditMode) + { + return; + } + + if(E_Alarm_Window != m_mode || m_alarmForm == Q_NULLPTR ) + { + return; + } + m_alarmForm->setShowAiAlarmView(show); +} + +void CAlarmPlugin::setEnableTrend(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableTrend(isNeed); + }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setEnableTrend(isNeed); + }else if(E_Alarm_Pop == m_mode) + { + ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableTrend(isNeed); + } +} + +void CAlarmPlugin::setEnableVideo(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableVideo(isNeed); + }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setEnableVideo(isNeed); + }else if(E_Alarm_Pop == m_mode) + { + ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableVideo(isNeed); + } +} + +void CAlarmPlugin::setEnableWave(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableWave(isNeed); + }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setEnableWave(isNeed); + }else if(E_Alarm_Pop == m_mode) + { + ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableWave(isNeed); + } +} + +void CAlarmPlugin::setEnableLevel(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableLevel(isNeed); + }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setEnableLevel(isNeed); + }else if(E_Alarm_Pop == m_mode) + { + ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableLevel(isNeed); + } +} + +void CAlarmPlugin::setDockRowHeight(const int &height) +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setRowHeight(height); + return ; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setRowHeight(height); + return ; + } + if(E_Alarm_Pop == m_mode && m_alarmView != Q_NULLPTR) + { + m_alarmView->setDefaultRowHeight(height); + return ; + } +} + +void CAlarmPlugin::setDockColumnVisible(const int &column, const bool &visbile) +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setDockColumnVisible(column, visbile); + } +} + +int CAlarmPlugin::confirmAllPermAlarm(bool tips) +{ + int result = 0; + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + + if(m_bIsEditMode || E_Alarm_Dock != m_mode || bFaultRecallState) + { + return result; + } + if(!m_alarmWidget || !m_pModel) + { + return result; + } + QList msgs =CAlarmMsgManage::instance()->getListAlarmInfo(); + int confirmNum = confirmAlarm(msgs); + if(tips) + { + QMessageBox::information(this, tr("提示"), tr("此次一共确认")+QString::number(confirmNum)+tr("条告警"), QMessageBox::Ok); + } + return confirmNum; +} + +QStringList CAlarmPlugin::getDevAlmInfo(const QString device) +{ + QMap alarm = CAlarmMsgManage::instance()->getDevAlarm(device); + QStringList result; + result.clear(); + QMap::iterator it= alarm.begin(); + while (it!= alarm.end()) { + QString alarmNum= QString("%1_%2").arg(it.key()).arg(it.value()); + result.append(alarmNum); + it++; + } + return result; +} + +QStringList CAlarmPlugin::getDevGroupAlmInfo(const QString deviceGroup) +{ + QMap > listMap = CAlarmMsgManage::instance()->getDevGroupPriorityDevNum(deviceGroup); + QStringList result; + result.clear(); + QMap >::iterator it =listMap.begin(); + for(;it != listMap.end();it++) + { + //优先级_设备数量 + QString priDev= QString("%1_%2").arg(it.key()).arg(it.value().size()); + result.append(priDev); + } + return result; +} + +QStringList CAlarmPlugin::getLocAlmInfo() +{ + QHash > locAlm = CAlarmMsgManage::instance()->getLocAlmInfo(); + QStringList list; + list.clear(); + QHash >::iterator it = locAlm.begin(); + while (it != locAlm.end()) { + QMap &priAlmNum =it.value(); + QMap::iterator pos = priAlmNum.begin(); + while (pos != priAlmNum.end()) { + QString priAlm = QString("%1_%2_%3").arg(it.key()).arg(pos.key()).arg(pos.value()); + list.append(priAlm); + pos++; + } + it++; + } + return list; +} + +int CAlarmPlugin::getLocNotConfirmAlmCount(int loc) +{ + int count =0; + if(loc<0) + { + return count; + } + QHash > > locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); + + QHash > >::iterator it = locCountMap.find(loc); + if(it !=locCountMap.end()) + { + QMap > devgCountMap = it.value(); + QMap >::iterator pos = devgCountMap.begin(); + while (pos != devgCountMap.end()) { + + count += pos.value().count(); + pos++; + } + } + + return count; +} + +int CAlarmPlugin::getDevgNotConfirmAlmCount(const QString &devg) +{ + int count =0; + if(devg.isEmpty()) + { + return count; + } + QHash > > locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); + + QHash > >::iterator it = locCountMap.begin(); + while (it !=locCountMap.end()) + { + QMap > devgCountMap = it.value(); + QMap >::iterator pos = devgCountMap.find(devg); + if(pos != devgCountMap.end()) + { + count = pos.value().count(); + break; + } + it++; + } + + return count; +} + +void CAlarmPlugin::setHiddenLocation(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenLocation(hide); + } +} + +void CAlarmPlugin::setHiddenTime(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenTime(hide); + } +} + +void CAlarmPlugin::setHiddenStatus(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenStatus(hide); + } +} + +void CAlarmPlugin::setHiddenPriority(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenPriority(hide); + } +} + +void CAlarmPlugin::setHiddenCheckBox(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenCheckBox(hide); + } +} + +void CAlarmPlugin::setHiddenSetConfig(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenSetConfig(hide); + } +} + +void CAlarmPlugin::setHiddenCloseButton(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenCloseButton(hide); + } +} + +void CAlarmPlugin::setHiddenInhiAlarmButton(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenInhiAlarmButton(hide); + } +} + +void CAlarmPlugin::setFormColumnVisible(const int &column, const bool &visible) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setColumnVisible(column, visible); + } +} + +void CAlarmPlugin::setDevice(const QString &device) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + m_pModel->addDeviceFilter(device); +} + +void CAlarmPlugin::setDeviceGroup(const QString &deviceGroup) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + if(deviceGroup.isEmpty()) + { + m_pModel->addDeviceGroupFilter(); + }else + { + m_pModel->addDeviceGroupFilter(deviceGroup); + } + +} + +void CAlarmPlugin::setPointTag(const QString &pointList) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + QStringList s= pointList.split(","); + QList pointTagList; + for(int i = 0;iaddPointTagFilter(pointTagList); +} + +void CAlarmPlugin::setColumnVisible(const int &column, const bool &visible) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + m_alarmView->setColumnHidden(column, !visible); +} + +void CAlarmPlugin::confirmFirstAlarm(int index) +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Dock != m_mode || bFaultRecallState) + { + return; + } + if(!m_pModel) + { + return; + } + m_alarmWidget->confirmAlarm(index); +} + +void CAlarmPlugin::setColumnWidth(const int &column, const int &width) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode) + { + if(!m_alarmForm) + { + return; + } + m_alarmForm->setColumnWidth(column, width); + } + else if(E_Alarm_Dock == m_mode) + { + if(!m_alarmWidget) + { + return; + } + m_alarmWidget->setColumnWidth(column, width); + } + else if(E_Alarm_Pop == m_mode) + { + if(!m_alarmView || !m_pModel) + { + return; + } + m_alarmView->setColumnWidth(column, width); + } +} + +int CAlarmPlugin::currentSelectCount() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return 0; + } + if(!m_alarmView || !m_pModel) + { + return 0; + } + QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(); + return listModelIndex.size(); +} + +void CAlarmPlugin::confirmCurrentAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(0); + + bool permSkip = false; + QList msgs; + foreach (QModelIndex index, listModelIndex) + { + AlarmMsgPtr info = m_pModel->getAlarmInfo(index); + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionOptId.begin(); + while (region != m_vecRegionOptId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationOptId.begin(); + while (location != m_vecLocationOptId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + msgs.append(info); + } + else + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + permSkip = true; + continue; + } + else + { + return; + } + } + + } + + confirmAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::confirmAllAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + + bool permSkip = false; + QList msgs; + for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) + { + AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionOptId.begin(); + while (region != m_vecRegionOptId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationOptId.begin(); + while (location != m_vecLocationOptId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + msgs.append(info); + } + else + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + permSkip = true; + continue; + } + else + { + return; + } + } + } + confirmAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::removeAllAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + + bool permSkip = false; + bool unConfirmSkip = false; + QList msgs; + for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) + { + AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionDelId.begin(); + while (region != m_vecRegionDelId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationDelId.begin(); + while (location != m_vecLocationDelId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(!unConfirmSkip) + { + QMessageBox msgBox; + msgBox.setText(tr("包含未确认告警!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + unConfirmSkip = true; + continue; + } + else + { + return; + } + } + else + { + continue; + } + } + else + { + msgs.append(info); + } + } + else + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + permSkip = true; + continue; + } + else + { + return; + } + } + } + removeAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::slotUpdateAlarmView() +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->updateView(); + } + else if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->updateView(); + } + else if(E_Alarm_Pop == m_mode && m_alarmView != Q_NULLPTR) + { + m_alarmView->viewport()->update(); + } +} + +void CAlarmPlugin::slotUpdateAiAlarmView() +{ + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->updateView(); + } + +} + +void CAlarmPlugin::slotUpdateAlarmOperateEnable(const bool &bEnable) +{ + if(!m_bIsEditMode) + { + if (E_Alarm_Window == m_mode) + { + m_alarmForm->setAlarmOperateEnable(bEnable); + + } + else if (E_Alarm_Dock == m_mode) + { + m_alarmWidget->setAlarmOperateEnable(bEnable); + + } + else if (E_Alarm_Pop == m_mode) + { + //< 禁用确认、删除接口, 见E_Alarm_Pop模式接口 + } + } +} + +void CAlarmPlugin::slotAllViewReload() +{ + if(m_mode == E_Alarm_Dock) + { + m_pModel->initialize(); + }else if(m_mode == E_Alarm_Window) + { + m_pModel->initialize(); + if(m_enableAi) + { + m_pTreeModel->initialize(); + } + m_alarmForm->init(); + }else if(m_mode == E_Alarm_Pop) + { + m_pModel->initialize(); + } +} + +void CAlarmPlugin::reset() +{ + if(Q_NULLPTR != m_pModel) + { + m_pModel->disconnect(); + delete m_pModel; + } + m_pModel = Q_NULLPTR; + if(Q_NULLPTR != m_pTreeModel) + { + m_pTreeModel->disconnect(); + delete m_pTreeModel; + } + m_pTreeModel = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmForm) + { + delete m_alarmForm; + } + m_alarmForm = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmWidget) + { + delete m_alarmWidget; + } + m_alarmWidget = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmView) + { + delete m_alarmView; + } + m_alarmView = Q_NULLPTR; + + QLayout * lyt = layout(); + if(Q_NULLPTR != lyt) + { + delete lyt; + } +} + +void CAlarmPlugin::updateAlarmOperatePerm() +{ + m_currentUsrId = -1; + m_currentNodeName = ""; + m_vecRegionOptId.clear(); + m_vecLocationOptId.clear(); + m_vecRegionDelId.clear(); + m_vecLocationDelId.clear(); + + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + + m_currentNodeName = stNodeInfo.strName; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(0 != permMngPtr->CurUser(m_currentUsrId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + LOGERROR("用户ID获取失败!"); + return; + } + if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, m_vecRegionOptId, m_vecLocationOptId)) + { + LOGERROR("用户不具备告警操作权限!"); + } + if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, m_vecRegionDelId, m_vecLocationDelId)) + { + LOGERROR("用户不具备告警删除权限!"); + } + } +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.h b/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.h index 26a22b7e..e4efa550 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.h @@ -1,346 +1,346 @@ -#ifndef CALARMPLUGIN_H -#define CALARMPLUGIN_H - -#include -#include "CAlarmMsgInfo.h" -#include "CAlarmItemModel.h" -#include "CAlarmMediaPlayer.h" -#include "CAlarmSetMng.h" -#include "CAiAlarmTreeModel.h" -class CAlarmView; -class CAlarmForm; -class CAlarmWidget; -class CAlarmItemModel; - -class CAlarmPlugin : public QWidget -{ - Q_OBJECT -public: - CAlarmPlugin(QWidget *parent, bool editMode = false); - ~CAlarmPlugin(); - - int confirmAlarm(const QList &msgs); - - int removeAlarm(const QList &msgs); - -public slots: - /*************************以下接口为公共接口*****************************/ - /** - * @brief initialize 初始化模型 - * @param mode E_Alarm_Dock-小窗(0) E_Alarm_Window-大窗(1) E_Alarm_Pop-弹窗(2) - */ - void initialize(int mode); - /** - * @brief login 用户登录(用户登录时调用) - */ - void login(); - /** - * @brief logout 用户退出(用户退出时调用) - */ - void logout(); - /** - * @brief switchFaultRecallState 事故追忆切换 - * @param bFaultRecallState true-事故追忆 false-非事故追忆 - */ - void switchFaultRecallState(bool bFaultRecallState); - /** - * @brief setAudioVolumeEnable 音量使能(仅设置一次即可) - */ - void setVolumeEnable(bool bEnable); - /** - * @brief setColumnWidth 设置列宽 - * @param column 列 - * @param width 宽 - */ - void setColumnWidth(const int &column, const int &width); - /** - * @brief setColumnAlign 设置列对其方式 - * @param column 列 - * @param alignFlag 1-AlignLeft; 2-AlignRight; other-AlignHCenter - */ - void setColumnAlign(const int &column, const int &alignFlag); - /** - * @brief setEnableTrend 设置是否显示趋势图标 (程序默认显示) - * @param isNeed true-显示 false-不显示 - */ - void setEnableTrend(bool isNeed =true); - /** - * @brief setEnableVideo 设置是否显示视频图标 (程序默认显示) - * @param isNeed true-显示 false-不显示 - */ - void setEnableVideo(bool isNeed =true); - /** - * @brief setEnableWave 设置是否显示录波图标(程序默认显示) - * @param isNeed true-显示 false-不显示 - */ - void setEnableWave(bool isNeed = true); - /** - * @brief setEnableLevel 设置是否显示等级图标 (程序默认不显示) - * @param isNeed true-显示 false-不显示 - */ - void setEnableLevel(bool isNeed =true); - /** - * @brief getDevAlmInfo 获取设备告警信息 - * @param device 设备 - * @return QString 格式为: 告警等级_告警数量 ex:1_2 含义为 告警等级为1的告警数为2 - */ - QStringList getDevAlmInfo(const QString device); - /** - * @brief getDevGroupAlmInfo 获取设备组下每个告警等级的设备数量 - * @param deviceGroup 设备组 - * @return QString 格式为: 告警等级_设备数量 ex:1_23 含义为 告警等级为1的设备数量为23 - */ - QStringList getDevGroupAlmInfo(const QString deviceGroup); - /** - * @brief getLocAlmInfo 获取车站告警数量(优先级分组) - * @return QString 格式为: 车站id_告警等级_告警数量 ex:1_1_23 含义为 车站1告警等级为1的告警数量为23 - */ - QStringList getLocAlmInfo(); - /** - * @brief getLocNotConfirmAlmCount 获取位置的未确认告警条数 - * @param loc 位置id - * @return 未确认告警条数 - */ - int getLocNotConfirmAlmCount(int loc); - /** - * @brief getDevgNotConfirmAlmCount 获取设备组的未确认告警条数 - * @param devg 设备组 - * @return 未确认告警条数数 - */ - int getDevgNotConfirmAlmCount(const QString & devg); - /***************************************************************************/ - - /****************以下接口仅针对E_Alarm_Window模式[告警大窗]有效********************/ - /** - * @brief setEnableAccidentReview 设置告警大窗右键是否显示事故追忆 - * @param isNeed isNeed true-显示 false-不显示 (程序默认显示) - */ - void setEnableAccidentReview(bool isNeed = true); - /** - * @brief setAccidentReviewPath 设置事故追忆画面选择对话框路径 相对于pic - * @param path - */ - void setAccidentReviewPath(const QString& path); - /** - * @brief setShowAiAlarmView 设置第一次是否显示智能告警(根据是否启用智能告警,一般不需要调用) - * @param show true-显示 false-不显示 (根据是否启用智能告警) 不配置智能告警调用显示也无效 - */ - void setShowAiAlarmView(bool show = true); - /** - * @brief setHiddenLocation 设置是否在告警大窗顶部隐藏车站过滤 - * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) - */ - void setHiddenLocation(bool hide); - /** - * @brief setHiddenTime 设置是否在告警大窗顶部隐藏时间过滤 - * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) - */ - void setHiddenTime(bool hide); - /** - * @brief setHiddenStatus 设置是否在告警大窗顶部隐藏状态过滤 - * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) - */ - void setHiddenStatus(bool hide); - /** - * @brief setHiddenPriority 设置是否在告警大窗顶部隐藏优先级过滤 - * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) - */ - void setHiddenPriority(bool hide); - /** - * @brief setHiddenCheckBox 设置是否在告警大窗顶部隐藏智能告警勾选框 - * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) - */ - void setHiddenCheckBox(bool hide); - /** - * @brief setHiddenSetConfig 设置是否隐藏设置按钮 - * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) - */ - void setHiddenSetConfig(bool hide); - /** - * @brief setHiddenCloseButton 设置是否隐藏关闭按钮 - * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) - */ - void setHiddenCloseButton(bool hide); - - /** - * @brief setHiddenInhiAlarmButton 设置是否隐藏禁止告警按钮 - * @param hide true-隐藏 false-不隐藏(程序默认隐藏) - */ - void setHiddenInhiAlarmButton(bool hide); - - /** - * @brief setFormColumnVisible 设置列是否显示 - * @param column 列 - * @param visible true-显示 false-不显示 - */ - void setFormColumnVisible(const int &column, const bool &visible = true); - /***************************************************************************/ - - /****************以下接口仅针对E_Alarm_Dock模式[底部告警栏]有效********************/ - /** - * @brief confirmFirstAlarm 确认第一条告警 - * @param index 确认第几条(最大值为2) - */ - void confirmFirstAlarm(int index= 0); - /** - * @brief setDockRowHeight 设置行高 - * @param height 行高 - */ - void setDockRowHeight(const int &height); - /** - * @brief setDockColumnVisible 设置列是否显示 - * @param column 列 - * @param visbile true-显示 false-不显示 - */ - void setDockColumnVisible(const int &column, const bool &visbile = true); - /** - * @brief confirmAllPermAlarm 确认当前有权限的所有告警 - * @param tips true-确认后提示确认总数 false-确认后不需要提示确认总数 - * @return 确认总数 - */ - int confirmAllPermAlarm(bool tips = true); - /***************************************************************************/ - - /****************以下接口仅针对E_Alarm_Pop模式[设备对话框]有效********************/ - /** - * @brief setDevice 设置设备显示(已无效,保留只为兼容) - * @param device 设备 - */ - void setDevice(const QString &device); - /** - * @brief setDeviceGroup 设置设备组显示 - * @param deviceGroup 设备组 - */ - void setDeviceGroup(const QString &deviceGroup); - /** - * @brief setPointTag 设置点过滤(已无效,保留只为兼容) - * @param pointList 点集合 - */ - void setPointTag(const QString &pointList); - /** - * @brief setColumnVisible 设置列是否显示 - * @param column 列 - * @param visible true-显示 false-不显示 - */ - void setColumnVisible(const int &column, const bool &visible); - /** - * @brief currentSelectCount 获取选中的告警条数 - * @return 告警条数 - */ - int currentSelectCount(); - /** - * @brief confirmCurrentAlarm 确认当前告警 - */ - void confirmCurrentAlarm(); - /** - * @brief confirmAllAlarm 确认所有告警 - */ - void confirmAllAlarm(); - /** - * @brief removeAllAlarm 删除所有告警 - */ - void removeAllAlarm(); - - /***************************************************************************/ - /** - * @brief recvAlarmNumChanged 告警数量变化 - * @param total 总数 - * @param unConfirm 未确认数 - */ - void recvAlarmNumChanged(const int &total, const int &unConfirm); - -signals: - /** - * @brief alarmNumChanged 告警数量变化 - */ - void alarmNumChanged(const int &total, const int &unConfirm); //脚本更新数量 - /** - * @brief alarmPush 告警推图 - */ - void alarmPush(const QString &info); - /** - * @brief alarmPushClear 清空告警推图 - */ - void alarmPushClear(); - /** - * @brief alarmDockDoubleClicked 告警窗[Dock] 双击信号 - */ - void alarmDockDoubleClicked(); - /** - * @brief closeBtnClicked 告警窗[Window] 关闭按钮点击信号 - */ - void closeBtnClicked(); - /** - * @brief openVideoDialog 打开视频窗 - * @param domainId 域id - * @param appId 应用id - * @param tag 点标签 - * @param startTime 开始时间 - * @param endTime 结束时间 - */ - void openVideoDialog(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); - /** - * @brief openTrendDialog 打开趋势窗口 - * @param time_stamp 时间戳 - * @param tagList 标签集合 - */ - void openTrendDialog(quint64 time_stamp,QStringList tagList); - /** - * @brief openAccidentReviewDialog 开始进行事故追忆 - * @param starTime 开始时间 - * @param keepTime 保持时间 - */ - void openAccidentReviewDialog(quint64 starTime,quint64 keepTime,QString graph=QString()); - /** - * @brief sigSwitchFaultRecallState 触发事故追忆(非hmi使用) - * @param bFaultRecallState true-事故追忆 false-非事故追忆 - */ - void sigSwitchFaultRecallState(bool bFaultRecallState); - - void sigLogin(); - -private slots: - /** - * @brief slotUpdateAlarmView 更新视图 - */ - void slotUpdateAlarmView(); - void slotUpdateAiAlarmView(); - /** - * @brief slotUpdateAlarmOperateEnable 更新界面告警操作接口 - * @param bEnable - */ - void slotUpdateAlarmOperateEnable(const bool &bEnable); - - void slotAllViewReload(); - -private: - - void loadConfig(); - - void reset(); - - void updateAlarmOperatePerm(); - -private: - E_Alarm_Mode m_mode; - bool m_bIsEditMode; - CAlarmForm * m_alarmForm; - CAlarmWidget * m_alarmWidget; - CAlarmView * m_alarmView; - CAlarmItemModel * m_pModel; - CAiAlarmTreeModel * m_pTreeModel; - int m_currentUsrId{}; - std::string m_currentNodeName; - std::vector m_vecRegionOptId; //告警操作权限责任区 - std::vector m_vecLocationOptId;//告警操作权限车站 - - std::vector m_vecRegionDelId; //告警删除权限责任区 - std::vector m_vecLocationDelId;//告警删除权限车站 - - //static int m_number; - static QThread * m_pDataCollectThread; - static QThread * m_pMediaPlayerThread; - bool m_enableAi; -}; - -#endif // CALARMPLUGIN_H +#ifndef CALARMPLUGIN_H +#define CALARMPLUGIN_H + +#include +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "CAlarmMediaPlayer.h" +#include "CAlarmSetMng.h" +#include "CAiAlarmTreeModel.h" +class CAlarmView; +class CAlarmForm; +class CAlarmWidget; +class CAlarmItemModel; + +class CAlarmPlugin : public QWidget +{ + Q_OBJECT +public: + CAlarmPlugin(QWidget *parent, bool editMode = false); + ~CAlarmPlugin(); + + int confirmAlarm(const QList &msgs); + + int removeAlarm(const QList &msgs); + +public slots: + /*************************以下接口为公共接口*****************************/ + /** + * @brief initialize 初始化模型 + * @param mode E_Alarm_Dock-小窗(0) E_Alarm_Window-大窗(1) E_Alarm_Pop-弹窗(2) + */ + void initialize(int mode); + /** + * @brief login 用户登录(用户登录时调用) + */ + void login(); + /** + * @brief logout 用户退出(用户退出时调用) + */ + void logout(); + /** + * @brief switchFaultRecallState 事故追忆切换 + * @param bFaultRecallState true-事故追忆 false-非事故追忆 + */ + void switchFaultRecallState(bool bFaultRecallState); + /** + * @brief setAudioVolumeEnable 音量使能(仅设置一次即可) + */ + void setVolumeEnable(bool bEnable); + /** + * @brief setColumnWidth 设置列宽 + * @param column 列 + * @param width 宽 + */ + void setColumnWidth(const int &column, const int &width); + /** + * @brief setColumnAlign 设置列对其方式 + * @param column 列 + * @param alignFlag 1-AlignLeft; 2-AlignRight; other-AlignHCenter + */ + void setColumnAlign(const int &column, const int &alignFlag); + /** + * @brief setEnableTrend 设置是否显示趋势图标 (程序默认显示) + * @param isNeed true-显示 false-不显示 + */ + void setEnableTrend(bool isNeed =true); + /** + * @brief setEnableVideo 设置是否显示视频图标 (程序默认显示) + * @param isNeed true-显示 false-不显示 + */ + void setEnableVideo(bool isNeed =true); + /** + * @brief setEnableWave 设置是否显示录波图标(程序默认显示) + * @param isNeed true-显示 false-不显示 + */ + void setEnableWave(bool isNeed = true); + /** + * @brief setEnableLevel 设置是否显示等级图标 (程序默认不显示) + * @param isNeed true-显示 false-不显示 + */ + void setEnableLevel(bool isNeed =true); + /** + * @brief getDevAlmInfo 获取设备告警信息 + * @param device 设备 + * @return QString 格式为: 告警等级_告警数量 ex:1_2 含义为 告警等级为1的告警数为2 + */ + QStringList getDevAlmInfo(const QString device); + /** + * @brief getDevGroupAlmInfo 获取设备组下每个告警等级的设备数量 + * @param deviceGroup 设备组 + * @return QString 格式为: 告警等级_设备数量 ex:1_23 含义为 告警等级为1的设备数量为23 + */ + QStringList getDevGroupAlmInfo(const QString deviceGroup); + /** + * @brief getLocAlmInfo 获取车站告警数量(优先级分组) + * @return QString 格式为: 车站id_告警等级_告警数量 ex:1_1_23 含义为 车站1告警等级为1的告警数量为23 + */ + QStringList getLocAlmInfo(); + /** + * @brief getLocNotConfirmAlmCount 获取位置的未确认告警条数 + * @param loc 位置id + * @return 未确认告警条数 + */ + int getLocNotConfirmAlmCount(int loc); + /** + * @brief getDevgNotConfirmAlmCount 获取设备组的未确认告警条数 + * @param devg 设备组 + * @return 未确认告警条数数 + */ + int getDevgNotConfirmAlmCount(const QString & devg); + /***************************************************************************/ + + /****************以下接口仅针对E_Alarm_Window模式[告警大窗]有效********************/ + /** + * @brief setEnableAccidentReview 设置告警大窗右键是否显示事故追忆 + * @param isNeed isNeed true-显示 false-不显示 (程序默认显示) + */ + void setEnableAccidentReview(bool isNeed = true); + /** + * @brief setAccidentReviewPath 设置事故追忆画面选择对话框路径 相对于pic + * @param path + */ + void setAccidentReviewPath(const QString& path); + /** + * @brief setShowAiAlarmView 设置第一次是否显示智能告警(根据是否启用智能告警,一般不需要调用) + * @param show true-显示 false-不显示 (根据是否启用智能告警) 不配置智能告警调用显示也无效 + */ + void setShowAiAlarmView(bool show = true); + /** + * @brief setHiddenLocation 设置是否在告警大窗顶部隐藏车站过滤 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenLocation(bool hide); + /** + * @brief setHiddenTime 设置是否在告警大窗顶部隐藏时间过滤 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenTime(bool hide); + /** + * @brief setHiddenStatus 设置是否在告警大窗顶部隐藏状态过滤 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenStatus(bool hide); + /** + * @brief setHiddenPriority 设置是否在告警大窗顶部隐藏优先级过滤 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenPriority(bool hide); + /** + * @brief setHiddenCheckBox 设置是否在告警大窗顶部隐藏智能告警勾选框 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenCheckBox(bool hide); + /** + * @brief setHiddenSetConfig 设置是否隐藏设置按钮 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenSetConfig(bool hide); + /** + * @brief setHiddenCloseButton 设置是否隐藏关闭按钮 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenCloseButton(bool hide); + + /** + * @brief setHiddenInhiAlarmButton 设置是否隐藏禁止告警按钮 + * @param hide true-隐藏 false-不隐藏(程序默认隐藏) + */ + void setHiddenInhiAlarmButton(bool hide); + + /** + * @brief setFormColumnVisible 设置列是否显示 + * @param column 列 + * @param visible true-显示 false-不显示 + */ + void setFormColumnVisible(const int &column, const bool &visible = true); + /***************************************************************************/ + + /****************以下接口仅针对E_Alarm_Dock模式[底部告警栏]有效********************/ + /** + * @brief confirmFirstAlarm 确认第一条告警 + * @param index 确认第几条(最大值为2) + */ + void confirmFirstAlarm(int index= 0); + /** + * @brief setDockRowHeight 设置行高 + * @param height 行高 + */ + void setDockRowHeight(const int &height); + /** + * @brief setDockColumnVisible 设置列是否显示 + * @param column 列 + * @param visbile true-显示 false-不显示 + */ + void setDockColumnVisible(const int &column, const bool &visbile = true); + /** + * @brief confirmAllPermAlarm 确认当前有权限的所有告警 + * @param tips true-确认后提示确认总数 false-确认后不需要提示确认总数 + * @return 确认总数 + */ + int confirmAllPermAlarm(bool tips = true); + /***************************************************************************/ + + /****************以下接口仅针对E_Alarm_Pop模式[设备对话框]有效********************/ + /** + * @brief setDevice 设置设备显示(已无效,保留只为兼容) + * @param device 设备 + */ + void setDevice(const QString &device); + /** + * @brief setDeviceGroup 设置设备组显示 + * @param deviceGroup 设备组 + */ + void setDeviceGroup(const QString &deviceGroup); + /** + * @brief setPointTag 设置点过滤(已无效,保留只为兼容) + * @param pointList 点集合 + */ + void setPointTag(const QString &pointList); + /** + * @brief setColumnVisible 设置列是否显示 + * @param column 列 + * @param visible true-显示 false-不显示 + */ + void setColumnVisible(const int &column, const bool &visible); + /** + * @brief currentSelectCount 获取选中的告警条数 + * @return 告警条数 + */ + int currentSelectCount(); + /** + * @brief confirmCurrentAlarm 确认当前告警 + */ + void confirmCurrentAlarm(); + /** + * @brief confirmAllAlarm 确认所有告警 + */ + void confirmAllAlarm(); + /** + * @brief removeAllAlarm 删除所有告警 + */ + void removeAllAlarm(); + + /***************************************************************************/ + /** + * @brief recvAlarmNumChanged 告警数量变化 + * @param total 总数 + * @param unConfirm 未确认数 + */ + void recvAlarmNumChanged(const int &total, const int &unConfirm); + +signals: + /** + * @brief alarmNumChanged 告警数量变化 + */ + void alarmNumChanged(const int &total, const int &unConfirm); //脚本更新数量 + /** + * @brief alarmPush 告警推图 + */ + void alarmPush(const QString &info); + /** + * @brief alarmPushClear 清空告警推图 + */ + void alarmPushClear(); + /** + * @brief alarmDockDoubleClicked 告警窗[Dock] 双击信号 + */ + void alarmDockDoubleClicked(); + /** + * @brief closeBtnClicked 告警窗[Window] 关闭按钮点击信号 + */ + void closeBtnClicked(); + /** + * @brief openVideoDialog 打开视频窗 + * @param domainId 域id + * @param appId 应用id + * @param tag 点标签 + * @param startTime 开始时间 + * @param endTime 结束时间 + */ + void openVideoDialog(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + /** + * @brief openTrendDialog 打开趋势窗口 + * @param time_stamp 时间戳 + * @param tagList 标签集合 + */ + void openTrendDialog(quint64 time_stamp,QStringList tagList); + /** + * @brief openAccidentReviewDialog 开始进行事故追忆 + * @param starTime 开始时间 + * @param keepTime 保持时间 + */ + void openAccidentReviewDialog(quint64 starTime,quint64 keepTime,QString graph=QString()); + /** + * @brief sigSwitchFaultRecallState 触发事故追忆(非hmi使用) + * @param bFaultRecallState true-事故追忆 false-非事故追忆 + */ + void sigSwitchFaultRecallState(bool bFaultRecallState); + + void sigLogin(); + +private slots: + /** + * @brief slotUpdateAlarmView 更新视图 + */ + void slotUpdateAlarmView(); + void slotUpdateAiAlarmView(); + /** + * @brief slotUpdateAlarmOperateEnable 更新界面告警操作接口 + * @param bEnable + */ + void slotUpdateAlarmOperateEnable(const bool &bEnable); + + void slotAllViewReload(); + +private: + + void loadConfig(); + + void reset(); + + void updateAlarmOperatePerm(); + +private: + E_Alarm_Mode m_mode; + bool m_bIsEditMode; + CAlarmForm * m_alarmForm; + CAlarmWidget * m_alarmWidget; + CAlarmView * m_alarmView; + CAlarmItemModel * m_pModel; + CAiAlarmTreeModel * m_pTreeModel; + int m_currentUsrId{}; + std::string m_currentNodeName; + std::vector m_vecRegionOptId; //告警操作权限责任区 + std::vector m_vecLocationOptId;//告警操作权限车站 + + std::vector m_vecRegionDelId; //告警删除权限责任区 + std::vector m_vecLocationDelId;//告警删除权限车站 + + //static int m_number; + static QThread * m_pDataCollectThread; + static QThread * m_pMediaPlayerThread; + bool m_enableAi; +}; + +#endif // CALARMPLUGIN_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.cpp index 481755c9..5337d7e3 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.cpp @@ -1,29 +1,29 @@ -#include -#include "CAlarmPluginWidget.h" -#include "CAlarmPlugin.h" -#include "pub_logger_api/logger.h" - -CAlarmPluginWidget::CAlarmPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CAlarmPluginWidget::~CAlarmPluginWidget() -{ - -} - -bool CAlarmPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CAlarmPlugin *pWidget = new CAlarmPlugin(parent, editMode); - pWidget->initialize((int)E_Alarm_Dock); - *widget = (QWidget *)pWidget; - *alarmWidget = (IPluginWidget *)pWidget; - return true; -} - -void CAlarmPluginWidget::release() -{ - -} +#include +#include "CAlarmPluginWidget.h" +#include "CAlarmPlugin.h" +#include "pub_logger_api/logger.h" + +CAlarmPluginWidget::CAlarmPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CAlarmPluginWidget::~CAlarmPluginWidget() +{ + +} + +bool CAlarmPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CAlarmPlugin *pWidget = new CAlarmPlugin(parent, editMode); + pWidget->initialize((int)E_Alarm_Dock); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + return true; +} + +void CAlarmPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.h b/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.h index e68fdfa9..5c706ea9 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CALARMPLUGINWIDGET_H -#define CALARMPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CAlarmPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CAlarmPluginWidget(QObject *parent = 0); - ~CAlarmPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); - void release(); -}; - -#endif //CALARMPLUGINWIDGET_H - +#ifndef CALARMPLUGINWIDGET_H +#define CALARMPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CAlarmPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CAlarmPluginWidget(QObject *parent = 0); + ~CAlarmPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif //CALARMPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.cpp index a2e8bb3e..2a5413b0 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.cpp @@ -1,429 +1,429 @@ -#include "CAlarmSetDlg.h" -#include "ui_CAlarmSetDlg.h" -#include -#include "pub_utility_api/FileUtil.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CAlarmColorWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" -#include -#include "CAlarmCommon.h" - -CAlarmSetDlg::CAlarmSetDlg(QWidget *parent) : - QDialog(parent), - ui(new Ui::CAlarmSetDlg), - m_pTextToSpeech(Q_NULLPTR) -{ - ui->setupUi(this); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - init(); - ui->label->installEventFilter(this); - ui->label_2->installEventFilter(this); - ui->label_7->installEventFilter(this); - connect(ui->pushButton_20,&QPushButton::clicked,this,&CAlarmSetDlg::save); - connect(ui->pushButton_21,&QPushButton::clicked,this,&CAlarmSetDlg::cancle); - connect(ui->radioButton,&QRadioButton::clicked,this,&CAlarmSetDlg::soundClicked); - connect(ui->radioButton_2,&QRadioButton::clicked,this,&CAlarmSetDlg::voiceClicked); - ui->alarmStyle->setView(new QListView()); - ui->engine->setView(new QListView()); - ui->language->setView(new QListView()); - ui->voiceName->setView(new QListView()); -} - -CAlarmSetDlg::~CAlarmSetDlg() -{ - delete ui; -} - -void CAlarmSetDlg::engineSelected(int index) -{ - disconnect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); - ui->language->clear(); - disconnect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); - ui->voiceName->clear(); - - QString engineName = ui->engine->itemData(index).toString(); - if(m_pTextToSpeech != Q_NULLPTR) - { - delete m_pTextToSpeech; - m_pTextToSpeech = Q_NULLPTR; - } - - m_engine = engineName; - - if(m_engine == "default") - { -#ifdef OS_LINUX - m_pTextToSpeech = Q_NULLPTR; - return; -#else - m_pTextToSpeech = new QTextToSpeech(this); -#endif - }else - { - m_pTextToSpeech = new QTextToSpeech(m_engine,this); - } - -// disconnect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); -// ui->language->clear(); - QVector locales = m_pTextToSpeech->availableLocales(); - QLocale current = m_pTextToSpeech->locale(); - - foreach (const QLocale &locale, locales) { - QString name(QString("%1 (%2)") - .arg(QLocale::languageToString(locale.language())) - .arg(QLocale::countryToString(locale.country()))); - QVariant localeVariant(locale); - ui->language->addItem(name, locale.name()); - if (locale.name() == m_language) - current = locale; - } - - connect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); - localeChanged(current); -} - -void CAlarmSetDlg::languageSelected(int language) -{ - QLocale locale = ui->language->itemData(language).toLocale(); - m_pTextToSpeech->setLocale(locale); -} - -void CAlarmSetDlg::localeChanged(const QLocale &locale) -{ - QVariant localeVariant(locale); - ui->language->setCurrentIndex(ui->language->findData(QVariant(locale.name()))); - - disconnect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); - ui->voiceName->clear(); - - m_voices = m_pTextToSpeech->availableVoices(); - QVoice currentVoice = m_pTextToSpeech->voice(); - foreach (const QVoice &voice, m_voices) { - ui->voiceName->addItem(QString("%1 - %2 - %3").arg(voice.name()) - .arg(QVoice::genderName(voice.gender())) - .arg(QVoice::ageName(voice.age())),voice.name()); - if (voice.name() == m_voiceName) - ui->voiceName->setCurrentIndex(ui->voiceName->count() - 1); - } - connect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); -} - -void CAlarmSetDlg::voiceSelected(int index) -{ - m_pTextToSpeech->setVoice(m_voices.at(index)); -} - -void CAlarmSetDlg::init() -{ - CAlarmSetMng::instance()->getColorMap(m_colorMap); - CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); - CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); - CAlarmSetMng::instance()->getActAndNum(m_act,m_num,m_style); - CAlarmSetMng::instance()->getEngine(m_engine,m_language,m_voiceName); - - ui->alarmStyle->addItem(tr("不报"), E_STYLE_NO_ALARM); - ui->alarmStyle->addItem(tr("重复"), E_STYLE_REPEAT); - ui->alarmStyle->addItem(tr("重复x次"), E_STYLE_REPEAT_X); - initView(); - connect(ui->alarmStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(styleChanged(int))); - emit ui->alarmStyle->currentIndexChanged(ui->alarmStyle->currentIndex()); -} - -void CAlarmSetDlg::initView() -{ - if(m_act == 0) - { - ui->radioButton->setChecked(true); - ui->radioButton_2->setChecked(false); - soundClicked(true); - }else - { - ui->radioButton->setChecked(false); - ui->radioButton_2->setChecked(true); - voiceClicked(true); - } - int style = ui->alarmStyle->findData(m_style); - if(style != -1) - { - ui->alarmStyle->setCurrentIndex(style); - } - ui->spinBox->setValue(m_num); - QMap::iterator it= m_colorMap.begin(); - QVBoxLayout *vlayout = new QVBoxLayout(ui->widget_2); - while (it!=m_colorMap.end()) { - CAlarmColorWidget *form = new CAlarmColorWidget(&(it.value()),this); - vlayout->addWidget(form); - it++; - } - ui->widget_2->setContentsMargins(0,0,0,0); - ui->widget_2->setLayout(vlayout); - - ui->label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_select_text_color.red()).arg(m_select_text_color.green()).arg(m_select_text_color.blue())); - ui->label_2->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_emptyTipColor.red()).arg(m_emptyTipColor.green()).arg(m_emptyTipColor.blue())); - ui->label_7->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_select_background_color.red()).arg(m_select_background_color.green()).arg(m_select_background_color.blue())); - - ui->engine->addItem("default", QString("default")); - QStringList engineList; -#ifdef OS_LINUX - //< TODO: centos选择语音告警,打开QtAV相关程序(IpcPluginWidget等)卡死。暂时隐藏。 -#else - engineList = QTextToSpeech::availableEngines(); - if(engineList.isEmpty()) - { - return; - } - foreach (QString engine, engineList) - { - ui->engine->addItem(engine, engine); - } -#endif - - if(m_engine.isEmpty() || !engineList.contains(m_engine)) - { - m_engine = "default"; - } - ui->engine->setCurrentText(m_engine); - - int index= ui->engine->currentIndex(); - engineSelected(index); - connect(ui->engine, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::engineSelected); - -} - -bool CAlarmSetDlg::eventFilter(QObject *obj, QEvent *event) -{ - if(obj == ui->label) - { - if(event->type() == QMouseEvent::MouseButtonPress) - { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == Qt::LeftButton) - { - chooseColor(ui->label, &m_select_text_color); - }else - { - return false; - } - }else - { - return false; - } - }else if(obj == ui->label_2) - { - if(event->type() == QMouseEvent::MouseButtonPress) - { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == Qt::LeftButton) - { - chooseColor(ui->label_2, &m_emptyTipColor); - }else - { - return false; - } - }else - { - return false; - } - }else if(obj == ui->label_7) - { - if(event->type() == QMouseEvent::MouseButtonPress) - { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == Qt::LeftButton) - { - chooseColor(ui->label_7, &m_select_background_color); - }else - { - return false; - } - }else - { - return false; - } - }else - { - return QWidget::eventFilter(obj,event); - } - return true; -} - -void CAlarmSetDlg::chooseColor(QLabel *label, QColor *color) -{ - QColor newColor=QColorDialog::getColor(*color,this); - if(newColor.isValid()){ - *color=newColor; - updateColorLabel(label,*color); - } -} - -void CAlarmSetDlg::updateColorLabel(QLabel *label, const QColor &color) -{ - label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(color.red()).arg(color.green()).arg(color.blue())); - if(label == ui->label) - { - m_select_text_color = color; - }else if(label == ui->label_2) - { - m_emptyTipColor = color; - }else if(label == ui->label_7) - { - m_select_background_color = color; - } -} - -bool CAlarmSetDlg::saveXML() -{ - m_engine = ui->engine->currentData().toString(); - m_language = ui->language->currentData().toString(); - m_voiceName = ui->voiceName->currentData().toString(); - //写文本 - QString sFileName = QCoreApplication::applicationDirPath() + "/../../data/model/alarm_color_define.xml"; - QFile oFile( sFileName ); - if ( !oFile.exists() ) - { - QMessageBox::critical( 0, "错误", QString("配置文件【%1】不存在,保存失败").arg(sFileName) ); - return false; - } - if ( !oFile.open(QIODevice::WriteOnly | QIODevice::Text) ) - { - QMessageBox::critical( 0, "错误", QString("配置文件【%1】打开失败,保存失败").arg(sFileName) ); - return false; - } - m_num = ui->spinBox->value(); - QXmlStreamWriter writer(&oFile); - writer.setAutoFormatting(true); - writer.writeStartDocument(); - writer.writeStartElement("profile"); - - writer.writeStartElement("Flash"); - writer.writeAttribute( "alternate" ,QString::number(0)); - writer.writeEndElement(); - - QMap::iterator it= m_colorMap.begin(); - - while (it!=m_colorMap.end()) { - writer.writeStartElement("Level"); - writer.writeAttribute( "priority" ,QString::number(it.key())); - writer.writeAttribute( "background_color" ,"transparent"); - writer.writeAttribute( "alternating_color" ,it.value().alternating_color.name()); - writer.writeAttribute( "confirm_color" ,"transparent"); - writer.writeAttribute( "active_text_color" ,it.value().active_text_color.name()); - writer.writeAttribute( "resume_text_color" ,it.value().resume_text_color.name()); - writer.writeAttribute( "confirm_text_color" ,it.value().confirm_text_color.name()); - writer.writeAttribute( "icon" ,it.value().icon); - writer.writeEndElement(); - it++; - } - writer.writeStartElement("Select"); - writer.writeAttribute( "background_color" ,m_select_background_color.name()); - writer.writeAttribute( "text_color" ,m_select_text_color.name()); - writer.writeEndElement(); - - writer.writeStartElement("NoItem"); - writer.writeAttribute( "background_color" ,"transparent"); - writer.writeAttribute( "tips_color" ,m_emptyTipColor.name()); - writer.writeAttribute( "tips" ,m_emptyTip); - writer.writeEndElement(); - - writer.writeStartElement("Alarm"); - writer.writeAttribute( "act" ,QString::number(m_act)); - writer.writeAttribute("actDesc","0-声音告警 1-语音告警"); - writer.writeAttribute( "num" ,QString::number(m_num)); - writer.writeAttribute("style",QString::number(m_style)); - writer.writeEndElement(); - - writer.writeStartElement("VoiceEngine"); - writer.writeAttribute( "engine" ,m_engine); - writer.writeAttribute( "language" ,m_language); - writer.writeAttribute( "voice_name" ,m_voiceName); - writer.writeEndElement(); - writer.writeEndElement(); - return true; -} - -void CAlarmSetDlg::soundClicked(bool checked) -{ - if(checked) - { - m_act = 0; - } - ui->engine->setEnabled(!checked); - ui->language->setEnabled(!checked); - ui->voiceName->setEnabled(!checked); -} - -void CAlarmSetDlg::voiceClicked(bool checked) -{ - if(checked) - { - m_act = 1; - } - ui->engine->setEnabled(checked); - ui->language->setEnabled(checked); - ui->voiceName->setEnabled(checked); -} - - -void CAlarmSetDlg::save() -{ - if(saveXML()) - { - CAlarmSetMng::instance()->setColorMap(m_colorMap); - m_selectIsEmpty = false; - CAlarmSetMng::instance()->setSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); - CAlarmSetMng::instance()->setEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); - CAlarmSetMng::instance()->setActAndNum(m_act,m_num,m_style); - CAlarmSetMng::instance()->setEngine(m_engine,m_language,m_voiceName); - CAlarmSetMng::instance()->sigUpdateColor(); - accept(); - } -} - -void CAlarmSetDlg::cancle() -{ - reject(); -} - -void CAlarmSetDlg::styleChanged(int index) -{ - Q_UNUSED(index) - m_style = ui->alarmStyle->currentData().toInt(); - if(E_STYLE_REPEAT_X == m_style) - { - ui->spinBox->setEnabled(true); - } - else - { - ui->spinBox->setEnabled(false); - } -} +#include "CAlarmSetDlg.h" +#include "ui_CAlarmSetDlg.h" +#include +#include "pub_utility_api/FileUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmColorWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" +#include +#include "CAlarmCommon.h" + +CAlarmSetDlg::CAlarmSetDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmSetDlg), + m_pTextToSpeech(Q_NULLPTR) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + init(); + ui->label->installEventFilter(this); + ui->label_2->installEventFilter(this); + ui->label_7->installEventFilter(this); + connect(ui->pushButton_20,&QPushButton::clicked,this,&CAlarmSetDlg::save); + connect(ui->pushButton_21,&QPushButton::clicked,this,&CAlarmSetDlg::cancle); + connect(ui->radioButton,&QRadioButton::clicked,this,&CAlarmSetDlg::soundClicked); + connect(ui->radioButton_2,&QRadioButton::clicked,this,&CAlarmSetDlg::voiceClicked); + ui->alarmStyle->setView(new QListView()); + ui->engine->setView(new QListView()); + ui->language->setView(new QListView()); + ui->voiceName->setView(new QListView()); +} + +CAlarmSetDlg::~CAlarmSetDlg() +{ + delete ui; +} + +void CAlarmSetDlg::engineSelected(int index) +{ + disconnect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); + ui->language->clear(); + disconnect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); + ui->voiceName->clear(); + + QString engineName = ui->engine->itemData(index).toString(); + if(m_pTextToSpeech != Q_NULLPTR) + { + delete m_pTextToSpeech; + m_pTextToSpeech = Q_NULLPTR; + } + + m_engine = engineName; + + if(m_engine == "default") + { +#ifdef OS_LINUX + m_pTextToSpeech = Q_NULLPTR; + return; +#else + m_pTextToSpeech = new QTextToSpeech(this); +#endif + }else + { + m_pTextToSpeech = new QTextToSpeech(m_engine,this); + } + +// disconnect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); +// ui->language->clear(); + QVector locales = m_pTextToSpeech->availableLocales(); + QLocale current = m_pTextToSpeech->locale(); + + foreach (const QLocale &locale, locales) { + QString name(QString("%1 (%2)") + .arg(QLocale::languageToString(locale.language())) + .arg(QLocale::countryToString(locale.country()))); + QVariant localeVariant(locale); + ui->language->addItem(name, locale.name()); + if (locale.name() == m_language) + current = locale; + } + + connect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); + localeChanged(current); +} + +void CAlarmSetDlg::languageSelected(int language) +{ + QLocale locale = ui->language->itemData(language).toLocale(); + m_pTextToSpeech->setLocale(locale); +} + +void CAlarmSetDlg::localeChanged(const QLocale &locale) +{ + QVariant localeVariant(locale); + ui->language->setCurrentIndex(ui->language->findData(QVariant(locale.name()))); + + disconnect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); + ui->voiceName->clear(); + + m_voices = m_pTextToSpeech->availableVoices(); + QVoice currentVoice = m_pTextToSpeech->voice(); + foreach (const QVoice &voice, m_voices) { + ui->voiceName->addItem(QString("%1 - %2 - %3").arg(voice.name()) + .arg(QVoice::genderName(voice.gender())) + .arg(QVoice::ageName(voice.age())),voice.name()); + if (voice.name() == m_voiceName) + ui->voiceName->setCurrentIndex(ui->voiceName->count() - 1); + } + connect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); +} + +void CAlarmSetDlg::voiceSelected(int index) +{ + m_pTextToSpeech->setVoice(m_voices.at(index)); +} + +void CAlarmSetDlg::init() +{ + CAlarmSetMng::instance()->getColorMap(m_colorMap); + CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); + CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); + CAlarmSetMng::instance()->getActAndNum(m_act,m_num,m_style); + CAlarmSetMng::instance()->getEngine(m_engine,m_language,m_voiceName); + + ui->alarmStyle->addItem(tr("不报"), E_STYLE_NO_ALARM); + ui->alarmStyle->addItem(tr("重复"), E_STYLE_REPEAT); + ui->alarmStyle->addItem(tr("重复x次"), E_STYLE_REPEAT_X); + initView(); + connect(ui->alarmStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(styleChanged(int))); + emit ui->alarmStyle->currentIndexChanged(ui->alarmStyle->currentIndex()); +} + +void CAlarmSetDlg::initView() +{ + if(m_act == 0) + { + ui->radioButton->setChecked(true); + ui->radioButton_2->setChecked(false); + soundClicked(true); + }else + { + ui->radioButton->setChecked(false); + ui->radioButton_2->setChecked(true); + voiceClicked(true); + } + int style = ui->alarmStyle->findData(m_style); + if(style != -1) + { + ui->alarmStyle->setCurrentIndex(style); + } + ui->spinBox->setValue(m_num); + QMap::iterator it= m_colorMap.begin(); + QVBoxLayout *vlayout = new QVBoxLayout(ui->widget_2); + while (it!=m_colorMap.end()) { + CAlarmColorWidget *form = new CAlarmColorWidget(&(it.value()),this); + vlayout->addWidget(form); + it++; + } + ui->widget_2->setContentsMargins(0,0,0,0); + ui->widget_2->setLayout(vlayout); + + ui->label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_select_text_color.red()).arg(m_select_text_color.green()).arg(m_select_text_color.blue())); + ui->label_2->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_emptyTipColor.red()).arg(m_emptyTipColor.green()).arg(m_emptyTipColor.blue())); + ui->label_7->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_select_background_color.red()).arg(m_select_background_color.green()).arg(m_select_background_color.blue())); + + ui->engine->addItem("default", QString("default")); + QStringList engineList; +#ifdef OS_LINUX + //< TODO: centos选择语音告警,打开QtAV相关程序(IpcPluginWidget等)卡死。暂时隐藏。 +#else + engineList = QTextToSpeech::availableEngines(); + if(engineList.isEmpty()) + { + return; + } + foreach (QString engine, engineList) + { + ui->engine->addItem(engine, engine); + } +#endif + + if(m_engine.isEmpty() || !engineList.contains(m_engine)) + { + m_engine = "default"; + } + ui->engine->setCurrentText(m_engine); + + int index= ui->engine->currentIndex(); + engineSelected(index); + connect(ui->engine, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::engineSelected); + +} + +bool CAlarmSetDlg::eventFilter(QObject *obj, QEvent *event) +{ + if(obj == ui->label) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label, &m_select_text_color); + }else + { + return false; + } + }else + { + return false; + } + }else if(obj == ui->label_2) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_2, &m_emptyTipColor); + }else + { + return false; + } + }else + { + return false; + } + }else if(obj == ui->label_7) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_7, &m_select_background_color); + }else + { + return false; + } + }else + { + return false; + } + }else + { + return QWidget::eventFilter(obj,event); + } + return true; +} + +void CAlarmSetDlg::chooseColor(QLabel *label, QColor *color) +{ + QColor newColor=QColorDialog::getColor(*color,this); + if(newColor.isValid()){ + *color=newColor; + updateColorLabel(label,*color); + } +} + +void CAlarmSetDlg::updateColorLabel(QLabel *label, const QColor &color) +{ + label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(color.red()).arg(color.green()).arg(color.blue())); + if(label == ui->label) + { + m_select_text_color = color; + }else if(label == ui->label_2) + { + m_emptyTipColor = color; + }else if(label == ui->label_7) + { + m_select_background_color = color; + } +} + +bool CAlarmSetDlg::saveXML() +{ + m_engine = ui->engine->currentData().toString(); + m_language = ui->language->currentData().toString(); + m_voiceName = ui->voiceName->currentData().toString(); + //写文本 + QString sFileName = QCoreApplication::applicationDirPath() + "/../../data/model/alarm_color_define.xml"; + QFile oFile( sFileName ); + if ( !oFile.exists() ) + { + QMessageBox::critical( 0, "错误", QString("配置文件【%1】不存在,保存失败").arg(sFileName) ); + return false; + } + if ( !oFile.open(QIODevice::WriteOnly | QIODevice::Text) ) + { + QMessageBox::critical( 0, "错误", QString("配置文件【%1】打开失败,保存失败").arg(sFileName) ); + return false; + } + m_num = ui->spinBox->value(); + QXmlStreamWriter writer(&oFile); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + writer.writeStartElement("profile"); + + writer.writeStartElement("Flash"); + writer.writeAttribute( "alternate" ,QString::number(0)); + writer.writeEndElement(); + + QMap::iterator it= m_colorMap.begin(); + + while (it!=m_colorMap.end()) { + writer.writeStartElement("Level"); + writer.writeAttribute( "priority" ,QString::number(it.key())); + writer.writeAttribute( "background_color" ,"transparent"); + writer.writeAttribute( "alternating_color" ,it.value().alternating_color.name()); + writer.writeAttribute( "confirm_color" ,"transparent"); + writer.writeAttribute( "active_text_color" ,it.value().active_text_color.name()); + writer.writeAttribute( "resume_text_color" ,it.value().resume_text_color.name()); + writer.writeAttribute( "confirm_text_color" ,it.value().confirm_text_color.name()); + writer.writeAttribute( "icon" ,it.value().icon); + writer.writeEndElement(); + it++; + } + writer.writeStartElement("Select"); + writer.writeAttribute( "background_color" ,m_select_background_color.name()); + writer.writeAttribute( "text_color" ,m_select_text_color.name()); + writer.writeEndElement(); + + writer.writeStartElement("NoItem"); + writer.writeAttribute( "background_color" ,"transparent"); + writer.writeAttribute( "tips_color" ,m_emptyTipColor.name()); + writer.writeAttribute( "tips" ,m_emptyTip); + writer.writeEndElement(); + + writer.writeStartElement("Alarm"); + writer.writeAttribute( "act" ,QString::number(m_act)); + writer.writeAttribute("actDesc","0-声音告警 1-语音告警"); + writer.writeAttribute( "num" ,QString::number(m_num)); + writer.writeAttribute("style",QString::number(m_style)); + writer.writeEndElement(); + + writer.writeStartElement("VoiceEngine"); + writer.writeAttribute( "engine" ,m_engine); + writer.writeAttribute( "language" ,m_language); + writer.writeAttribute( "voice_name" ,m_voiceName); + writer.writeEndElement(); + writer.writeEndElement(); + return true; +} + +void CAlarmSetDlg::soundClicked(bool checked) +{ + if(checked) + { + m_act = 0; + } + ui->engine->setEnabled(!checked); + ui->language->setEnabled(!checked); + ui->voiceName->setEnabled(!checked); +} + +void CAlarmSetDlg::voiceClicked(bool checked) +{ + if(checked) + { + m_act = 1; + } + ui->engine->setEnabled(checked); + ui->language->setEnabled(checked); + ui->voiceName->setEnabled(checked); +} + + +void CAlarmSetDlg::save() +{ + if(saveXML()) + { + CAlarmSetMng::instance()->setColorMap(m_colorMap); + m_selectIsEmpty = false; + CAlarmSetMng::instance()->setSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); + CAlarmSetMng::instance()->setEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); + CAlarmSetMng::instance()->setActAndNum(m_act,m_num,m_style); + CAlarmSetMng::instance()->setEngine(m_engine,m_language,m_voiceName); + CAlarmSetMng::instance()->sigUpdateColor(); + accept(); + } +} + +void CAlarmSetDlg::cancle() +{ + reject(); +} + +void CAlarmSetDlg::styleChanged(int index) +{ + Q_UNUSED(index) + m_style = ui->alarmStyle->currentData().toInt(); + if(E_STYLE_REPEAT_X == m_style) + { + ui->spinBox->setEnabled(true); + } + else + { + ui->spinBox->setEnabled(false); + } +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.h b/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.h index 61ec1736..cf8da490 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.h @@ -1,72 +1,72 @@ -#ifndef CALARMSETDLG_H -#define CALARMSETDLG_H - -#include -#include "CAlarmColorInfo.h" -#include "CAlarmSetMng.h" -#include -#include -namespace Ui { -class CAlarmSetDlg; -} - -class CAlarmSetDlg : public QDialog -{ - Q_OBJECT - -public: - explicit CAlarmSetDlg(QWidget *parent = 0); - ~CAlarmSetDlg(); - -public slots: - void engineSelected(int index); - - void languageSelected(int language); - void localeChanged(const QLocale &locale); - void voiceSelected(int index); - -private: - void init(); - void initView(); - - bool eventFilter(QObject *obj, QEvent *event); - -private: - void chooseColor(QLabel *label, QColor *color); - void updateColorLabel(QLabel *label, const QColor &color); - - bool saveXML(); - -private slots: - - void soundClicked(bool checked); - - void voiceClicked(bool checked); - - void save(); - - void cancle(); - - void styleChanged(int index); - -private: - Ui::CAlarmSetDlg *ui; - QTextToSpeech *m_pTextToSpeech; - QMap m_colorMap; - QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 - bool m_selectIsEmpty; - - QColor m_emptyBackgroundColor,m_emptyTipColor; - QString m_emptyTip; - int m_act; - int m_num; - int m_style; - - QString m_engine; - QString m_language; - QString m_voiceName; - - QVector m_voices; -}; - -#endif // CALARMSETDLG_H +#ifndef CALARMSETDLG_H +#define CALARMSETDLG_H + +#include +#include "CAlarmColorInfo.h" +#include "CAlarmSetMng.h" +#include +#include +namespace Ui { +class CAlarmSetDlg; +} + +class CAlarmSetDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmSetDlg(QWidget *parent = 0); + ~CAlarmSetDlg(); + +public slots: + void engineSelected(int index); + + void languageSelected(int language); + void localeChanged(const QLocale &locale); + void voiceSelected(int index); + +private: + void init(); + void initView(); + + bool eventFilter(QObject *obj, QEvent *event); + +private: + void chooseColor(QLabel *label, QColor *color); + void updateColorLabel(QLabel *label, const QColor &color); + + bool saveXML(); + +private slots: + + void soundClicked(bool checked); + + void voiceClicked(bool checked); + + void save(); + + void cancle(); + + void styleChanged(int index); + +private: + Ui::CAlarmSetDlg *ui; + QTextToSpeech *m_pTextToSpeech; + QMap m_colorMap; + QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 + bool m_selectIsEmpty; + + QColor m_emptyBackgroundColor,m_emptyTipColor; + QString m_emptyTip; + int m_act; + int m_num; + int m_style; + + QString m_engine; + QString m_language; + QString m_voiceName; + + QVector m_voices; +}; + +#endif // CALARMSETDLG_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.ui b/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.ui index f205d021..8cec9d25 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmSetDlg.ui @@ -1,354 +1,354 @@ - - - CAlarmSetDlg - - - - 0 - 0 - 699 - 406 - - - - 设置 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 动作选择 - - - - - - 声音告警 - - - - - - - 语音告警 - - - - - - - - - - 告警方式 - - - - - - 方式 - - - - - - - - 0 - 0 - - - - - - - - 次数 - - - - - - - - 0 - 0 - - - - -1 - - - -1 - - - - - - - - - - - - 优先级颜色选择 - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - - 0 - 0 - - - - - - - - - - - - - <html><head/><body><p>选中告警时,告警的文字颜色</p></body></html> - - - 选中文字颜色 - - - - - - 颜色 - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - - - - - - - - - - - <html><head/><body><p>选中告警时,告警的背景颜色</p></body></html> - - - 选中背景颜色 - - - - - - 颜色 - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - - - - - - - - - - - <html><head/><body><p>无告警时,告警小窗中&quot;当前无告警&quot;文字颜色</p></body></html> - - - 无告警文字颜色 - - - - - - 颜色 - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - - - - - - - - - - - - - 语音引擎 - - - - - - - 0 - 0 - - - - 引擎 - - - - - - - 语言 - - - - - - - 语音名称 - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - - - Qt::Horizontal - - - - 220 - 20 - - - - - - - - 确定 - - - - - - - 取消 - - - - - - - - - - - + + + CAlarmSetDlg + + + + 0 + 0 + 699 + 406 + + + + 设置 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 动作选择 + + + + + + 声音告警 + + + + + + + 语音告警 + + + + + + + + + + 告警方式 + + + + + + 方式 + + + + + + + + 0 + 0 + + + + + + + + 次数 + + + + + + + + 0 + 0 + + + + -1 + + + -1 + + + + + + + + + + + + 优先级颜色选择 + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + 0 + 0 + + + + + + + + + + + + + <html><head/><body><p>选中告警时,告警的文字颜色</p></body></html> + + + 选中文字颜色 + + + + + + 颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + + + + <html><head/><body><p>选中告警时,告警的背景颜色</p></body></html> + + + 选中背景颜色 + + + + + + 颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + + + + <html><head/><body><p>无告警时,告警小窗中&quot;当前无告警&quot;文字颜色</p></body></html> + + + 无告警文字颜色 + + + + + + 颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + + + + + + 语音引擎 + + + + + + + 0 + 0 + + + + 引擎 + + + + + + + 语言 + + + + + + + 语音名称 + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + + 220 + 20 + + + + + + + + 确定 + + + + + + + 取消 + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmSetMng.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmSetMng.cpp index cf3ff3e4..870aa9f6 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmSetMng.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmSetMng.cpp @@ -1,200 +1,200 @@ -#include "CAlarmSetMng.h" -#include -#include "pub_logger_api/logger.h" -#include -#include "pub_utility_api/FileUtil.h" -#include "CAlarmBaseData.h" - -using namespace kbd_public; -using namespace std; - -CAlarmSetMng *CAlarmSetMng::pInstance = NULL; - - -CAlarmSetMng *CAlarmSetMng::instance() -{ - if(pInstance == NULL) - { - pInstance = new CAlarmSetMng(); - } - return pInstance; -} - -CAlarmSetMng::~CAlarmSetMng() -{ - LOGDEBUG("CAlarmSetMng::~CAlarmSetMng()"); -} - -bool CAlarmSetMng::isBindMediaPlayer() -{ - return isSignalConnected(QMetaMethod::fromSignal(&CAlarmSetMng::sigLoadConfig)); -} - -CAlarmSetMng::CAlarmSetMng() - : QObject() -{ - mutex = new QMutex(); - m_priorityOrderDescriptionMap = CAlarmBaseData::instance()->getPriorityOrderMap(); - loadXMLCfg(); -} - -void CAlarmSetMng::loadXMLCfg() -{ - m_colorMap.clear(); - QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); - QDomDocument document; - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly)) - { - return; - } - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - QDomElement element = document.documentElement(); - QDomNode node = element.firstChild(); - while(!node.isNull()) - { - QDomElement attr = node.toElement(); - if(!attr.isNull()) - { - if(QString("Level") == attr.tagName()) - { - CAlarmColorInfo info; - info.priority = attr.attribute("priority").toInt(); - info.background_color = QColor(attr.attribute("background_color")); - info.alternating_color = QColor(attr.attribute("alternating_color")); - info.confirm_color = QColor(attr.attribute("confirm_color")); - - info.active_text_color = QColor(attr.attribute("active_text_color")); - info.confirm_text_color = QColor(attr.attribute("confirm_text_color")); - info.resume_text_color = QColor(attr.attribute("resume_text_color")); - info.icon = attr.attribute("icon"); - m_colorMap[info.priority] = info; - } - else if(QString("Select") == attr.tagName()) - { - m_select_background_color = QColor(attr.attribute("background_color")); - if(attr.attribute("text_color").isEmpty()) - { - m_selectIsEmpty = true; - }else - { - m_selectIsEmpty = false; - m_select_text_color = QColor(attr.attribute("text_color")); - } - } - else if(QString("NoItem") == attr.tagName()) - { - m_emptyBackgroundColor = QColor(attr.attribute("background_color")); - m_emptyTipColor = QColor(attr.attribute("tips_color")); - m_emptyTip = tr("当前无告警!"); - }else if(QString("Alarm") == attr.tagName()) - { - m_act =attr.attribute("act").toInt(); - m_actDesc = attr.attribute("actDesc"); - m_num =attr.attribute("num").toInt(); - m_style = attr.attribute("style").toInt(); - }else if(QString("VoiceEngine") == attr.tagName()) - { - m_engine = attr.attribute("engine"); - m_language = attr.attribute("language"); - m_voiceName = attr.attribute("voice_name"); - } - } - node = node.nextSibling(); - } -} - -void CAlarmSetMng::destory() -{ - pInstance = NULL; - deleteLater(); -} - -void CAlarmSetMng::getPriorityInfo(QMap &priorityOrderDescriptionMap) -{ - priorityOrderDescriptionMap.clear(); - priorityOrderDescriptionMap = m_priorityOrderDescriptionMap; -} - -void CAlarmSetMng::getColorMap(QMap &colorMap) -{ - colorMap.clear(); - colorMap = m_colorMap; -} - -void CAlarmSetMng::getSelectInfo(bool &selectIsEmpty, QColor &select_background_color, QColor &select_text_color) -{ - selectIsEmpty = m_selectIsEmpty; - select_background_color = m_select_background_color; - select_text_color = m_select_text_color; -} - -void CAlarmSetMng::getEmptyInfo(QColor &emptyBackgroundColor, QColor &emptyTipColor, QString &emptyTip) -{ - emptyBackgroundColor = m_emptyBackgroundColor; - emptyTipColor = m_emptyTipColor; - emptyTip = m_emptyTip; -} - -void CAlarmSetMng::getActAndNum(int &act, int &num, int &style) -{ - act = m_act; - num = m_num; - style = m_style; -} - -void CAlarmSetMng::getEngine(QString &engine, QString &language, QString &voiceName) -{ - engine = m_engine; - language = m_language; - voiceName = m_voiceName; -} - -QString CAlarmSetMng::getPriorityDescByOrder(int order) -{ - return m_priorityOrderDescriptionMap.value(order,tr("未知告警等级")); -} - -void CAlarmSetMng::setColorMap(const QMap &colorMap) -{ - m_colorMap = colorMap; -} - -void CAlarmSetMng::setSelectInfo(const bool &selectIsEmpty,const QColor &select_background_color,const QColor &select_text_color) -{ - m_selectIsEmpty = selectIsEmpty; - m_select_background_color = select_background_color; - m_select_text_color = select_text_color; -} - -void CAlarmSetMng::setEmptyInfo(const QColor &emptyBackgroundColor, const QColor &emptyTipColor, const QString &emptyTip) -{ - m_emptyBackgroundColor= emptyBackgroundColor; - m_emptyTipColor = emptyTipColor; - m_emptyTip = emptyTip; -} - -void CAlarmSetMng::setActAndNum(const int &act, const int &num, const int &style) -{ - m_act = act; - m_num = num; - m_style = style; -} - -void CAlarmSetMng::setEngine(const QString &engine, const QString &language, const QString &voiceName) -{ - m_engine = engine; - m_language = language; - m_voiceName = voiceName; -} - -void CAlarmSetMng::sigUpdateColor() -{ - emit sigLoadConfig(); -} +#include "CAlarmSetMng.h" +#include +#include "pub_logger_api/logger.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "CAlarmBaseData.h" + +using namespace kbd_public; +using namespace std; + +CAlarmSetMng *CAlarmSetMng::pInstance = NULL; + + +CAlarmSetMng *CAlarmSetMng::instance() +{ + if(pInstance == NULL) + { + pInstance = new CAlarmSetMng(); + } + return pInstance; +} + +CAlarmSetMng::~CAlarmSetMng() +{ + LOGDEBUG("CAlarmSetMng::~CAlarmSetMng()"); +} + +bool CAlarmSetMng::isBindMediaPlayer() +{ + return isSignalConnected(QMetaMethod::fromSignal(&CAlarmSetMng::sigLoadConfig)); +} + +CAlarmSetMng::CAlarmSetMng() + : QObject() +{ + mutex = new QMutex(); + m_priorityOrderDescriptionMap = CAlarmBaseData::instance()->getPriorityOrderMap(); + loadXMLCfg(); +} + +void CAlarmSetMng::loadXMLCfg() +{ + m_colorMap.clear(); + QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); + QDomDocument document; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement element = document.documentElement(); + QDomNode node = element.firstChild(); + while(!node.isNull()) + { + QDomElement attr = node.toElement(); + if(!attr.isNull()) + { + if(QString("Level") == attr.tagName()) + { + CAlarmColorInfo info; + info.priority = attr.attribute("priority").toInt(); + info.background_color = QColor(attr.attribute("background_color")); + info.alternating_color = QColor(attr.attribute("alternating_color")); + info.confirm_color = QColor(attr.attribute("confirm_color")); + + info.active_text_color = QColor(attr.attribute("active_text_color")); + info.confirm_text_color = QColor(attr.attribute("confirm_text_color")); + info.resume_text_color = QColor(attr.attribute("resume_text_color")); + info.icon = attr.attribute("icon"); + m_colorMap[info.priority] = info; + } + else if(QString("Select") == attr.tagName()) + { + m_select_background_color = QColor(attr.attribute("background_color")); + if(attr.attribute("text_color").isEmpty()) + { + m_selectIsEmpty = true; + }else + { + m_selectIsEmpty = false; + m_select_text_color = QColor(attr.attribute("text_color")); + } + } + else if(QString("NoItem") == attr.tagName()) + { + m_emptyBackgroundColor = QColor(attr.attribute("background_color")); + m_emptyTipColor = QColor(attr.attribute("tips_color")); + m_emptyTip = tr("当前无告警!"); + }else if(QString("Alarm") == attr.tagName()) + { + m_act =attr.attribute("act").toInt(); + m_actDesc = attr.attribute("actDesc"); + m_num =attr.attribute("num").toInt(); + m_style = attr.attribute("style").toInt(); + }else if(QString("VoiceEngine") == attr.tagName()) + { + m_engine = attr.attribute("engine"); + m_language = attr.attribute("language"); + m_voiceName = attr.attribute("voice_name"); + } + } + node = node.nextSibling(); + } +} + +void CAlarmSetMng::destory() +{ + pInstance = NULL; + deleteLater(); +} + +void CAlarmSetMng::getPriorityInfo(QMap &priorityOrderDescriptionMap) +{ + priorityOrderDescriptionMap.clear(); + priorityOrderDescriptionMap = m_priorityOrderDescriptionMap; +} + +void CAlarmSetMng::getColorMap(QMap &colorMap) +{ + colorMap.clear(); + colorMap = m_colorMap; +} + +void CAlarmSetMng::getSelectInfo(bool &selectIsEmpty, QColor &select_background_color, QColor &select_text_color) +{ + selectIsEmpty = m_selectIsEmpty; + select_background_color = m_select_background_color; + select_text_color = m_select_text_color; +} + +void CAlarmSetMng::getEmptyInfo(QColor &emptyBackgroundColor, QColor &emptyTipColor, QString &emptyTip) +{ + emptyBackgroundColor = m_emptyBackgroundColor; + emptyTipColor = m_emptyTipColor; + emptyTip = m_emptyTip; +} + +void CAlarmSetMng::getActAndNum(int &act, int &num, int &style) +{ + act = m_act; + num = m_num; + style = m_style; +} + +void CAlarmSetMng::getEngine(QString &engine, QString &language, QString &voiceName) +{ + engine = m_engine; + language = m_language; + voiceName = m_voiceName; +} + +QString CAlarmSetMng::getPriorityDescByOrder(int order) +{ + return m_priorityOrderDescriptionMap.value(order,tr("未知告警等级")); +} + +void CAlarmSetMng::setColorMap(const QMap &colorMap) +{ + m_colorMap = colorMap; +} + +void CAlarmSetMng::setSelectInfo(const bool &selectIsEmpty,const QColor &select_background_color,const QColor &select_text_color) +{ + m_selectIsEmpty = selectIsEmpty; + m_select_background_color = select_background_color; + m_select_text_color = select_text_color; +} + +void CAlarmSetMng::setEmptyInfo(const QColor &emptyBackgroundColor, const QColor &emptyTipColor, const QString &emptyTip) +{ + m_emptyBackgroundColor= emptyBackgroundColor; + m_emptyTipColor = emptyTipColor; + m_emptyTip = emptyTip; +} + +void CAlarmSetMng::setActAndNum(const int &act, const int &num, const int &style) +{ + m_act = act; + m_num = num; + m_style = style; +} + +void CAlarmSetMng::setEngine(const QString &engine, const QString &language, const QString &voiceName) +{ + m_engine = engine; + m_language = language; + m_voiceName = voiceName; +} + +void CAlarmSetMng::sigUpdateColor() +{ + emit sigLoadConfig(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmSetMng.h b/product/src/gui/plugin/AlarmWidget/CAlarmSetMng.h index c49b5577..5b3a485a 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmSetMng.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmSetMng.h @@ -1,90 +1,90 @@ -#ifndef CALARMSETMNG_H -#define CALARMSETMNG_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include -#include -#include "CAlarmColorInfo.h" - -class CAlarmSetMng : public QObject -{ - Q_OBJECT -public: - static CAlarmSetMng * instance(); - ~CAlarmSetMng(); - - void initialize(); - - bool isBindMediaPlayer(); - -signals: - void sigLoadConfig(); - -private: - - CAlarmSetMng(); - - void loadXMLCfg(); - -public slots: - void destory(); - - void sigUpdateColor(); - -public: - - void getPriorityInfo(QMap &priorityOrderDescriptionMap); - - void getColorMap(QMap &colorMap); - - void getSelectInfo(bool &selectIsEmpty,QColor &select_background_color,QColor &select_text_color); - - void getEmptyInfo(QColor &emptyBackgroundColor, QColor &emptyTipColor, QString &emptyTip); - - void getActAndNum(int &act,int &num, int &style); - - void getEngine(QString &engine,QString &language,QString &voiceName); - - QString getPriorityDescByOrder(int order); - - void setColorMap(const QMap &colorMap); - - void setSelectInfo(const bool &selectIsEmpty,const QColor &select_background_color,const QColor &select_text_color); - - void setEmptyInfo(const QColor &emptyBackgroundColor, const QColor &emptyTipColor, const QString &emptyTip); - - void setActAndNum(const int &act,const int &num,const int &style); - - void setEngine(const QString &engine,const QString &language,const QString &voiceName); - - - - -private: - QMutex * mutex; - static CAlarmSetMng * pInstance; - - - kbd_dbms::CRdbAccess * m_rtdbAccess; - - QMap m_priorityOrderDescriptionMap; - - QMap m_colorMap; - QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 - bool m_selectIsEmpty; - - QColor m_emptyBackgroundColor,m_emptyTipColor; - QString m_emptyTip; - int m_act; - int m_num; - - QString m_actDesc; - int m_style; - - QString m_engine; - QString m_language; - QString m_voiceName; -}; - -#endif // CALARMSETMNG_H +#ifndef CALARMSETMNG_H +#define CALARMSETMNG_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include +#include +#include "CAlarmColorInfo.h" + +class CAlarmSetMng : public QObject +{ + Q_OBJECT +public: + static CAlarmSetMng * instance(); + ~CAlarmSetMng(); + + void initialize(); + + bool isBindMediaPlayer(); + +signals: + void sigLoadConfig(); + +private: + + CAlarmSetMng(); + + void loadXMLCfg(); + +public slots: + void destory(); + + void sigUpdateColor(); + +public: + + void getPriorityInfo(QMap &priorityOrderDescriptionMap); + + void getColorMap(QMap &colorMap); + + void getSelectInfo(bool &selectIsEmpty,QColor &select_background_color,QColor &select_text_color); + + void getEmptyInfo(QColor &emptyBackgroundColor, QColor &emptyTipColor, QString &emptyTip); + + void getActAndNum(int &act,int &num, int &style); + + void getEngine(QString &engine,QString &language,QString &voiceName); + + QString getPriorityDescByOrder(int order); + + void setColorMap(const QMap &colorMap); + + void setSelectInfo(const bool &selectIsEmpty,const QColor &select_background_color,const QColor &select_text_color); + + void setEmptyInfo(const QColor &emptyBackgroundColor, const QColor &emptyTipColor, const QString &emptyTip); + + void setActAndNum(const int &act,const int &num,const int &style); + + void setEngine(const QString &engine,const QString &language,const QString &voiceName); + + + + +private: + QMutex * mutex; + static CAlarmSetMng * pInstance; + + + kbd_dbms::CRdbAccess * m_rtdbAccess; + + QMap m_priorityOrderDescriptionMap; + + QMap m_colorMap; + QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 + bool m_selectIsEmpty; + + QColor m_emptyBackgroundColor,m_emptyTipColor; + QString m_emptyTip; + int m_act; + int m_num; + + QString m_actDesc; + int m_style; + + QString m_engine; + QString m_language; + QString m_voiceName; +}; + +#endif // CALARMSETMNG_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.cpp index 2621736a..a5425a1d 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.cpp @@ -1,118 +1,118 @@ -#include "CAlarmShiledDialog.h" -#include "ui_CAlarmShiledDialog.h" -#include -#include -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/FileStyle.h" -#include -#include - -CAlarmShiledDialog::CAlarmShiledDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CAlarmShiledDialog), - m_pWidget(Q_NULLPTR), - m_pPluginWidget(Q_NULLPTR) -{ - ui->setupUi(this); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - m_pWidget = createCustomWidget("DataOptWidget"); - QGridLayout *layout = new QGridLayout(this); - layout->addWidget(m_pWidget); - layout->setContentsMargins(0,0,0,0); - ui->shield_frame->setLayout(layout); - -} - -CAlarmShiledDialog::~CAlarmShiledDialog() -{ - if(m_pWidget) - { - delete m_pWidget; - } - m_pWidget = Q_NULLPTR; - if(m_pPluginWidget) - { - - } - delete ui; -} - -QWidget *CAlarmShiledDialog::createCustomWidget(const QString &name) -{ - QWidget *customWidget = NULL; - QString fileName; - QString path; - - try - { -#ifdef OS_WINDOWS - fileName = name; - fileName += ".dll"; -#else - if (name.contains(QRegExp("^lib"))) - { - fileName = name; - } - else - { - fileName += "lib"; - fileName += name; - } - fileName += ".so"; -#endif - std::string filePath = kbd_public::CFileUtil::getPathOfBinFile(fileName.toStdString()); - path = QString::fromStdString(filePath); - QPluginLoader loader(path); - QObject *plugin = loader.instance(); - if (plugin) - { - CPluginWidgetInterface *plugInInterface = qobject_cast(plugin); - if (plugInInterface) - { - QVector ptrVect/* = getScene()->getDataAccess()->getPtr()*/; - void *d= NULL; - ptrVect.push_back(d); - - plugInInterface->createWidget(this, false, &customWidget, - &m_pPluginWidget, ptrVect); - - } - - } - else - { - } - - if (!customWidget) - { - customWidget = new QPushButton(tr("未找到插件"), this); - } - - return customWidget; - } - catch (...) - { - customWidget = new QPushButton(tr("装载异常"), this); - return customWidget; - } -} +#include "CAlarmShiledDialog.h" +#include "ui_CAlarmShiledDialog.h" +#include +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include +#include + +CAlarmShiledDialog::CAlarmShiledDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmShiledDialog), + m_pWidget(Q_NULLPTR), + m_pPluginWidget(Q_NULLPTR) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + m_pWidget = createCustomWidget("DataOptWidget"); + QGridLayout *layout = new QGridLayout(this); + layout->addWidget(m_pWidget); + layout->setContentsMargins(0,0,0,0); + ui->shield_frame->setLayout(layout); + +} + +CAlarmShiledDialog::~CAlarmShiledDialog() +{ + if(m_pWidget) + { + delete m_pWidget; + } + m_pWidget = Q_NULLPTR; + if(m_pPluginWidget) + { + + } + delete ui; +} + +QWidget *CAlarmShiledDialog::createCustomWidget(const QString &name) +{ + QWidget *customWidget = NULL; + QString fileName; + QString path; + + try + { +#ifdef OS_WINDOWS + fileName = name; + fileName += ".dll"; +#else + if (name.contains(QRegExp("^lib"))) + { + fileName = name; + } + else + { + fileName += "lib"; + fileName += name; + } + fileName += ".so"; +#endif + std::string filePath = kbd_public::CFileUtil::getPathOfBinFile(fileName.toStdString()); + path = QString::fromStdString(filePath); + QPluginLoader loader(path); + QObject *plugin = loader.instance(); + if (plugin) + { + CPluginWidgetInterface *plugInInterface = qobject_cast(plugin); + if (plugInInterface) + { + QVector ptrVect/* = getScene()->getDataAccess()->getPtr()*/; + void *d= NULL; + ptrVect.push_back(d); + + plugInInterface->createWidget(this, false, &customWidget, + &m_pPluginWidget, ptrVect); + + } + + } + else + { + } + + if (!customWidget) + { + customWidget = new QPushButton(tr("未找到插件"), this); + } + + return customWidget; + } + catch (...) + { + customWidget = new QPushButton(tr("装载异常"), this); + return customWidget; + } +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.h b/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.h index bba63c03..9f82b9e0 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.h @@ -1,28 +1,28 @@ -#ifndef CALARMSHILEDDIALOG_H -#define CALARMSHILEDDIALOG_H - -#include -#include "../AlarmShieldWidget/CAlarmShield.h" -#include "GraphShape/CPluginWidget.h" -namespace Ui { -class CAlarmShiledDialog; -} - -class CAlarmShiledDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CAlarmShiledDialog(QWidget *parent = nullptr); - ~CAlarmShiledDialog(); - -private: - QWidget *createCustomWidget(const QString &name); -private: - Ui::CAlarmShiledDialog *ui; - - QWidget *m_pWidget ; - IPluginWidget *m_pPluginWidget; -}; - -#endif // CALARMSHILEDDIALOG_H +#ifndef CALARMSHILEDDIALOG_H +#define CALARMSHILEDDIALOG_H + +#include +#include "../AlarmShieldWidget/CAlarmShield.h" +#include "GraphShape/CPluginWidget.h" +namespace Ui { +class CAlarmShiledDialog; +} + +class CAlarmShiledDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmShiledDialog(QWidget *parent = nullptr); + ~CAlarmShiledDialog(); + +private: + QWidget *createCustomWidget(const QString &name); +private: + Ui::CAlarmShiledDialog *ui; + + QWidget *m_pWidget ; + IPluginWidget *m_pPluginWidget; +}; + +#endif // CALARMSHILEDDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.ui b/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.ui index 07f66bb8..1f469ad3 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmShiledDialog.ui @@ -1,49 +1,49 @@ - - - CAlarmShiledDialog - - - - 0 - 0 - 1261 - 542 - - - - 禁止告警 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - + + + CAlarmShiledDialog + + + + 0 + 0 + 1261 + 542 + + + + 禁止告警 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.cpp index 1e50afe8..c2d58414 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.cpp @@ -1,134 +1,134 @@ -#include "CAlarmTaskMngDlg.h" -#include "ui_CAlarmTaskMngDlg.h" -#include -#include -#include - - -const int viewTaskHeight = 500; -const int viewTaskWidth = 540; - -CAlarmTaskMngDlg::CAlarmTaskMngDlg(AlarmMsgPtr info, QWidget *parent) : - QDialog(parent), - ui(new Ui::CAlarmTaskMngDlg), - m_info(info) -{ - setWindowFlags (windowFlags () & (~Qt::WindowContextHelpButtonHint)); - ui->setupUi(this); - initUi(); -} - -CAlarmTaskMngDlg::~CAlarmTaskMngDlg() -{ - delete ui; - delete m_view; -} - -void CAlarmTaskMngDlg::initUi() -{ - this->resize(this->width(),ui->label->height()); - ui->btnCreat->setHidden(true); - ui->btnViewProp->setHidden(true); - ui->btnViewTsk->setHidden(true); - ui->widget->setHidden(true); - m_view = new QWebEngineView(this); - QGridLayout* layout = new QGridLayout; - ui->widget->setLayout(layout); - layout->setContentsMargins(0,0,0,0); - layout->addWidget(m_view); - - if(!m_idongSrvApi.isValid()) - { - QMessageBox::information(this,tr("提醒"),tr("艾动接口初始化失败")); - return; - } - - std::string templateUUid; - if(!m_idongSrvApi.getTaskTemplate(m_info->key_id_tag.toStdString(),templateUUid)) - { - ui->labelTskGrpSts->setText(tr("未关联作业组,请先关联作业组")); - ui->btnCreat->setHidden(true); - return; - } - showTaskGrpStatus(); -} - -void CAlarmTaskMngDlg::showTaskGrpStatus() -{ - int status; - if(!m_idongSrvApi.getTaskGrpStatus(m_info->uuid_base64.toStdString(),status)) - { - LOGERROR("cannot get task group status"); - ui->labelTskGrpSts->setText("未能获取到作业组状态信息,请先创建作业组"); - ui->btnCreat->setHidden(false); - return; - } - - if(status >= 2) - { - ui->btnViewTsk->setHidden(false); - } - switch (status) { - case 2: - ui->labelTskGrpSts->setText("已发布"); - break; - case 3: - ui->labelTskGrpSts->setText("已创建"); - break; - case 4: - ui->labelTskGrpSts->setText("已执行"); - break; - case 5: - ui->labelTskGrpSts->setText("已延期"); - break; - case 6: - ui->labelTskGrpSts->setText("已过期"); - break; - case 7: - ui->labelTskGrpSts->setText("已超时"); - break; - default: - break; - } - -} - - -void CAlarmTaskMngDlg::on_btnCreat_clicked() -{ - std::string templateUUid; - if(!m_idongSrvApi.getTaskTemplate(m_info->key_id_tag.toStdString(),templateUUid)) - { - ui->labelTskGrpSts->setText(tr("未关联作业组,请先关联作业组")); - return; - } - if(m_idongSrvApi.createTaskGroupEx(m_info->uuid_base64.toStdString(),templateUUid,(m_info->content + "__巡检").toStdString())) - { - QMessageBox::information(this,tr("提醒"),tr("创建作业组成功")); - - /** - 展示成功画面,状态显示,那七个状态,然后,显示展示按钮。 - **/ - showTaskGrpStatus(); - ui->btnCreat->setHidden(true); - }else - { - QMessageBox::information(this,tr("提醒"),tr("创建作业组失败")); - } -} - -void CAlarmTaskMngDlg::on_btnViewTsk_clicked() -{ - this->resize(viewTaskWidth,viewTaskHeight); - QString urlDst; - if(!m_idongSrvApi.getTaskGrpLink(m_info->uuid_base64.toStdString(),urlDst)) - { - QMessageBox::information(this,tr("提醒"),tr("获取作业组信息失败")); - return; - } - LOGINFO("作业组链接:%s",QUrl::fromPercentEncoding(urlDst.toStdString().c_str()).toStdString().c_str()); - m_view->load( urlDst ); - ui->widget->setHidden(false); - ui->btnViewTsk->setHidden(true); - -} +#include "CAlarmTaskMngDlg.h" +#include "ui_CAlarmTaskMngDlg.h" +#include +#include +#include + + +const int viewTaskHeight = 500; +const int viewTaskWidth = 540; + +CAlarmTaskMngDlg::CAlarmTaskMngDlg(AlarmMsgPtr info, QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmTaskMngDlg), + m_info(info) +{ + setWindowFlags (windowFlags () & (~Qt::WindowContextHelpButtonHint)); + ui->setupUi(this); + initUi(); +} + +CAlarmTaskMngDlg::~CAlarmTaskMngDlg() +{ + delete ui; + delete m_view; +} + +void CAlarmTaskMngDlg::initUi() +{ + this->resize(this->width(),ui->label->height()); + ui->btnCreat->setHidden(true); + ui->btnViewProp->setHidden(true); + ui->btnViewTsk->setHidden(true); + ui->widget->setHidden(true); + m_view = new QWebEngineView(this); + QGridLayout* layout = new QGridLayout; + ui->widget->setLayout(layout); + layout->setContentsMargins(0,0,0,0); + layout->addWidget(m_view); + + if(!m_idongSrvApi.isValid()) + { + QMessageBox::information(this,tr("提醒"),tr("艾动接口初始化失败")); + return; + } + + std::string templateUUid; + if(!m_idongSrvApi.getTaskTemplate(m_info->key_id_tag.toStdString(),templateUUid)) + { + ui->labelTskGrpSts->setText(tr("未关联作业组,请先关联作业组")); + ui->btnCreat->setHidden(true); + return; + } + showTaskGrpStatus(); +} + +void CAlarmTaskMngDlg::showTaskGrpStatus() +{ + int status; + if(!m_idongSrvApi.getTaskGrpStatus(m_info->uuid_base64.toStdString(),status)) + { + LOGERROR("cannot get task group status"); + ui->labelTskGrpSts->setText("未能获取到作业组状态信息,请先创建作业组"); + ui->btnCreat->setHidden(false); + return; + } + + if(status >= 2) + { + ui->btnViewTsk->setHidden(false); + } + switch (status) { + case 2: + ui->labelTskGrpSts->setText("已发布"); + break; + case 3: + ui->labelTskGrpSts->setText("已创建"); + break; + case 4: + ui->labelTskGrpSts->setText("已执行"); + break; + case 5: + ui->labelTskGrpSts->setText("已延期"); + break; + case 6: + ui->labelTskGrpSts->setText("已过期"); + break; + case 7: + ui->labelTskGrpSts->setText("已超时"); + break; + default: + break; + } + +} + + +void CAlarmTaskMngDlg::on_btnCreat_clicked() +{ + std::string templateUUid; + if(!m_idongSrvApi.getTaskTemplate(m_info->key_id_tag.toStdString(),templateUUid)) + { + ui->labelTskGrpSts->setText(tr("未关联作业组,请先关联作业组")); + return; + } + if(m_idongSrvApi.createTaskGroupEx(m_info->uuid_base64.toStdString(),templateUUid,(m_info->content + "__巡检").toStdString())) + { + QMessageBox::information(this,tr("提醒"),tr("创建作业组成功")); + + /** + 展示成功画面,状态显示,那七个状态,然后,显示展示按钮。 + **/ + showTaskGrpStatus(); + ui->btnCreat->setHidden(true); + }else + { + QMessageBox::information(this,tr("提醒"),tr("创建作业组失败")); + } +} + +void CAlarmTaskMngDlg::on_btnViewTsk_clicked() +{ + this->resize(viewTaskWidth,viewTaskHeight); + QString urlDst; + if(!m_idongSrvApi.getTaskGrpLink(m_info->uuid_base64.toStdString(),urlDst)) + { + QMessageBox::information(this,tr("提醒"),tr("获取作业组信息失败")); + return; + } + LOGINFO("作业组链接:%s",QUrl::fromPercentEncoding(urlDst.toStdString().c_str()).toStdString().c_str()); + m_view->load( urlDst ); + ui->widget->setHidden(false); + ui->btnViewTsk->setHidden(true); + +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.h b/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.h index 5a555f3b..ef38a280 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.h @@ -1,37 +1,37 @@ -#ifndef CALARMTASKMNGDLG_H -#define CALARMTASKMNGDLG_H - -#include -#include "CAlarmCommon.h" -#include "application/idong_srv_api/CIDongSrvApi.h" -#include - - -namespace Ui { -class CAlarmTaskMngDlg; -} - -class CAlarmTaskMngDlg : public QDialog -{ - Q_OBJECT - -public: - explicit CAlarmTaskMngDlg(AlarmMsgPtr info,QWidget *parent = 0); - ~CAlarmTaskMngDlg(); - -private slots: - void on_btnCreat_clicked(); - - void on_btnViewTsk_clicked(); - -private: - void initUi(); - void showTaskGrpStatus(); - - Ui::CAlarmTaskMngDlg *ui; - AlarmMsgPtr m_info; - CIDongSrvApi m_idongSrvApi; - QWebEngineView *m_view; -}; - -#endif // CALARMTASKMNGDLG_H +#ifndef CALARMTASKMNGDLG_H +#define CALARMTASKMNGDLG_H + +#include +#include "CAlarmCommon.h" +#include "application/idong_srv_api/CIDongSrvApi.h" +#include + + +namespace Ui { +class CAlarmTaskMngDlg; +} + +class CAlarmTaskMngDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmTaskMngDlg(AlarmMsgPtr info,QWidget *parent = 0); + ~CAlarmTaskMngDlg(); + +private slots: + void on_btnCreat_clicked(); + + void on_btnViewTsk_clicked(); + +private: + void initUi(); + void showTaskGrpStatus(); + + Ui::CAlarmTaskMngDlg *ui; + AlarmMsgPtr m_info; + CIDongSrvApi m_idongSrvApi; + QWebEngineView *m_view; +}; + +#endif // CALARMTASKMNGDLG_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.ui b/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.ui index eca990f0..69f2e40c 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmTaskMngDlg.ui @@ -1,76 +1,76 @@ - - - CAlarmTaskMngDlg - - - - 0 - 0 - 427 - 211 - - - - 工单管理 - - - - - - - - 作业组状态: - - - - - - - - 0 - 0 - - - - 未创建 - - - - - - - 创建作业组 - - - - - - - 查看作业组 - - - - - - - 查看资产 - - - - - - - - - - 0 - 0 - - - - - - - - - + + + CAlarmTaskMngDlg + + + + 0 + 0 + 427 + 211 + + + + 工单管理 + + + + + + + + 作业组状态: + + + + + + + + 0 + 0 + + + + 未创建 + + + + + + + 创建作业组 + + + + + + + 查看作业组 + + + + + + + 查看资产 + + + + + + + + + + 0 + 0 + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmView.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmView.cpp index a2d5a358..9968b060 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmView.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmView.cpp @@ -1,34 +1,34 @@ -#include -#include -#include "CAlarmView.h" -#include - -CAlarmView::CAlarmView(QWidget *parent) - : QTableView(parent) -{ - -} - -void CAlarmView::initialize() -{ - setSortingEnabled(true); - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - //setSelectionMode(QAbstractItemView::MultiSelection); - //setHorizontalScrollMode(ScrollPerPixel); - setAutoScroll(false); -} - -void CAlarmView::setDefaultRowHeight(int height) -{ - verticalHeader()->setDefaultSectionSize(height); -} - - -void CAlarmView::mouseDoubleClickEvent(QMouseEvent *event) -{ - emit alarmViewDoubleClicked(); - QTableView::mouseDoubleClickEvent(event); -} +#include +#include +#include "CAlarmView.h" +#include + +CAlarmView::CAlarmView(QWidget *parent) + : QTableView(parent) +{ + +} + +void CAlarmView::initialize() +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + //setSelectionMode(QAbstractItemView::MultiSelection); + //setHorizontalScrollMode(ScrollPerPixel); + setAutoScroll(false); +} + +void CAlarmView::setDefaultRowHeight(int height) +{ + verticalHeader()->setDefaultSectionSize(height); +} + + +void CAlarmView::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit alarmViewDoubleClicked(); + QTableView::mouseDoubleClickEvent(event); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmView.h b/product/src/gui/plugin/AlarmWidget/CAlarmView.h index 49a18ab8..d2adb96d 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmView.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmView.h @@ -1,26 +1,26 @@ -#ifndef CALARMVIEW_H -#define CALARMVIEW_H - -#include - -class CAlarmView : public QTableView -{ - Q_OBJECT -public: - CAlarmView(QWidget *parent = Q_NULLPTR); - - void initialize(); - - void setDefaultRowHeight(int height); -signals: - void alarmViewDoubleClicked(); - - void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); - - void openTrend(quint64 time_stamp,QStringList tagList); -protected: - void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - -}; - -#endif // ALARMVIEW_H +#ifndef CALARMVIEW_H +#define CALARMVIEW_H + +#include + +class CAlarmView : public QTableView +{ + Q_OBJECT +public: + CAlarmView(QWidget *parent = Q_NULLPTR); + + void initialize(); + + void setDefaultRowHeight(int height); +signals: + void alarmViewDoubleClicked(); + + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + + void openTrend(quint64 time_stamp,QStringList tagList); +protected: + void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +}; + +#endif // ALARMVIEW_H diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmWidget.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmWidget.cpp index d6057fdf..e9bda3bf 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmWidget.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmWidget.cpp @@ -1,435 +1,435 @@ -#include "CAlarmWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include "CAlarmForm.h" -#include "CAlarmView.h" -#include "CAlarmMsgInfo.h" -#include "CAlarmItemModel.h" -#include "CAlarmDataCollect.h" -#include "CAlarmDelegate.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include -#include -#include "pub_logger_api/logger.h" - -CAlarmWidget::CAlarmWidget(QWidget *parent) - : QWidget(parent), - m_pView(Q_NULLPTR), - m_pModel(Q_NULLPTR), - m_delegate(Q_NULLPTR), m_userId(0), - m_pConfirmButtonRow0(Q_NULLPTR), - m_pConfirmButtonRow1(Q_NULLPTR), - m_pConfirmButtonRow2(Q_NULLPTR) -{ - //initialize(); -} - -CAlarmWidget::~CAlarmWidget() -{ - if(Q_NULLPTR != m_delegate) - { - delete m_delegate; - } - m_delegate = Q_NULLPTR; - qDebug() << "~CAlarmWidget()"; -} - -void CAlarmWidget::setAlarmModel(CAlarmItemModel *pModel) -{ - if(!pModel) - { - return; - } - m_pModel = pModel; - m_pView->setModel(m_pModel); - - if(!m_delegate) - { - m_delegate = new CAlarmDelegate(m_pModel, this); - m_pView->setItemDelegate(m_delegate); - connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmWidget::openVideo,Qt::QueuedConnection); - connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmWidget::openTrend,Qt::QueuedConnection); - connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); - } - - connect(m_pConfirmButtonRow0, SIGNAL(clicked()), this, SLOT(slotConfirmRow0())); - connect(m_pConfirmButtonRow1, SIGNAL(clicked()), this, SLOT(slotConfirmRow1())); - connect(m_pConfirmButtonRow2, SIGNAL(clicked()), this, SLOT(slotConfirmRow2())); - - - m_pView->setColumnHidden(0, false); - m_pView->setColumnHidden(1, false); - m_pView->setColumnHidden(2, false); - m_pView->setColumnHidden(3, true); - m_pView->setColumnHidden(4, true); - m_pView->setColumnHidden(5, false); - m_pView->setColumnHidden(6, false); - m_pView->setColumnHidden(7, false); - - - m_pView->setColumnWidth(0, 230); - m_pView->setColumnWidth(1, 120); - m_pView->setColumnWidth(2, 150); - m_pView->setColumnWidth(5, 150); - m_pView->setColumnWidth(6, 120); - - updateRowHeight(); -} - -void CAlarmWidget::setRowHeight(const int &height) -{ - if(m_pView) - { - m_pView->setRowHeight(0, height); - m_pView->setRowHeight(1, height); - m_pView->setRowHeight(2, height); - updateRowHeight(); - } -} - -void CAlarmWidget::setDockColumnVisible(const int &column, const bool &visbile) -{ - if(m_pView) - { - m_pView->setColumnHidden(column, !visbile); - } -} - -void CAlarmWidget::updateRowHeight() -{ - int nHeight = m_pView->rowHeight(0); - m_pConfirmButtonRow0->setMinimumHeight(nHeight); - m_pConfirmButtonRow1->setMinimumHeight(nHeight); - m_pConfirmButtonRow2->setMinimumHeight(nHeight); - setFixedHeight(nHeight * 3 + 1); -} - -void CAlarmWidget::updateView() -{ - if(m_pView != Q_NULLPTR) - { - m_pView->setShowGrid(m_pModel->getShowAlarmCount()); - m_pModel->updateAlternate(); - m_pView->viewport()->update(); - } -} - -void CAlarmWidget::setAlarmOperateEnable(const bool &bEnable) -{ - m_pConfirmButtonRow0->setEnabled(bEnable); - m_pConfirmButtonRow1->setEnabled(bEnable); - m_pConfirmButtonRow2->setEnabled(bEnable); -} - -void CAlarmWidget::setColumnWidth(const int &column, const int &width) -{ - if(m_pView != Q_NULLPTR) - { - m_pView->setColumnWidth(column, width); - } -} - -void CAlarmWidget::initialize() -{ - QHBoxLayout * pLayout = new QHBoxLayout(this); - pLayout->setMargin(0); - setLayout(pLayout); - - m_pView = new CAlarmView(this); - m_pView->setAlternatingRowColors(true); - m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_pView->setSelectionMode(QAbstractItemView::NoSelection); - m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_pView->horizontalHeader()->setStretchLastSection(true); - m_pView->horizontalHeader()->setVisible(false); - - m_pView->verticalHeader()->setVisible(false); - m_pView->setColumnWidth(0, 150); - pLayout->addWidget(m_pView); - QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); - m_pConfirmButtonRow0 = new QPushButton(tr("确认")); - m_pConfirmButtonRow1 = new QPushButton(tr("确认")); - m_pConfirmButtonRow2 = new QPushButton(tr("确认")); - int nHeight = 23; - m_pConfirmButtonRow0->setMinimumHeight(nHeight); - m_pConfirmButtonRow1->setMinimumHeight(nHeight); - m_pConfirmButtonRow2->setMinimumHeight(nHeight); - setMinimumHeight(nHeight * 3); - - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); - - pConfirmBtnLayout->addStretch(); - pLayout->addLayout(pConfirmBtnLayout); - layout()->setSpacing(0); - - updateAlarmOperatePerm(); - - m_pConfirmButtonRow0->setVisible(false); - m_pConfirmButtonRow1->setVisible(false); - m_pConfirmButtonRow2->setVisible(false); - connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); -} - -void CAlarmWidget::initializeEdit() -{ - QHBoxLayout * pLayout = new QHBoxLayout(this); - pLayout->setMargin(0); - setLayout(pLayout); - //m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") << tr("确认状态") << tr("告警内容"); - QStandardItemModel *model = new QStandardItemModel(); - model->setItem(0,0,new QStandardItem("2020-01-01 12:59:59.999")); - model->setItem(0,1,new QStandardItem("高")); - model->setItem(0,2,new QStandardItem("XX位置")); - model->setItem(0,3,new QStandardItem("-")); - model->setItem(0,4,new QStandardItem("系统信息")); - model->setItem(0,5,new QStandardItem("通道异常")); - model->setItem(0,6,new QStandardItem("未确认")); - model->setItem(0,7,new QStandardItem("通道:chanX,通道状态:通讯中断!")); - model->item(0,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,1)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,2)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,3)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,4)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,5)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,6)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,7)->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); - m_pView = new CAlarmView(this); - m_pView->setAlternatingRowColors(true); - m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_pView->setSelectionMode(QAbstractItemView::NoSelection); - m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_pView->horizontalHeader()->setStretchLastSection(true); - m_pView->horizontalHeader()->setVisible(false); - m_pView->verticalHeader()->setVisible(false); - - //m_pView->setColumnWidth(0, 150); - pLayout->addWidget(m_pView); - QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); - m_pConfirmButtonRow0 = new QPushButton(tr("确认")); - m_pConfirmButtonRow1 = new QPushButton(tr("确认")); - m_pConfirmButtonRow2 = new QPushButton(tr("确认")); - int nHeight = 23; - m_pConfirmButtonRow0->setMinimumHeight(nHeight); - m_pConfirmButtonRow1->setMinimumHeight(nHeight); - m_pConfirmButtonRow2->setMinimumHeight(nHeight); - setMinimumHeight(nHeight * 3); - - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); - - pConfirmBtnLayout->addStretch(); - pLayout->addLayout(pConfirmBtnLayout); - layout()->setSpacing(0); - - updateAlarmOperatePerm(); - - m_pConfirmButtonRow0->setVisible(false); - m_pConfirmButtonRow1->setVisible(false); - m_pConfirmButtonRow2->setVisible(false); - - - m_pView->setModel(model); - m_pView->setColumnHidden(0, false); - m_pView->setColumnHidden(1, false); - m_pView->setColumnHidden(2, false); - m_pView->setColumnHidden(3, true); - m_pView->setColumnHidden(4, true); - m_pView->setColumnHidden(5, false); - m_pView->setColumnHidden(6, false); - m_pView->setColumnHidden(7, false); - - - m_pView->setColumnWidth(0, 230); - m_pView->setColumnWidth(1, 120); - m_pView->setColumnWidth(2, 150); - m_pView->setColumnWidth(5, 150); - m_pView->setColumnWidth(6, 120); - - m_pView->setRowHeight(0,50); - - //connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); -} - -void CAlarmWidget::closeEvent(QCloseEvent *event) -{ - Q_UNUSED(event) - if(Q_NULLPTR != m_pConfirmButtonRow0) - { - delete m_pConfirmButtonRow0; - m_pConfirmButtonRow0 = Q_NULLPTR; - } - if(Q_NULLPTR != m_pConfirmButtonRow1) - { - delete m_pConfirmButtonRow1; - m_pConfirmButtonRow1 = Q_NULLPTR; - } - if(Q_NULLPTR != m_pConfirmButtonRow2) - { - delete m_pConfirmButtonRow2; - m_pConfirmButtonRow2 = Q_NULLPTR; - } - QWidget::closeEvent(event); -} - -void CAlarmWidget::confirmAlarm(const int &row) -{ - //构建告警确认package - if(row >= m_pModel->getListShowAlarmInfo().count()) - { - return; - } - AlarmMsgPtr info = m_pModel->getListShowAlarmInfo().at(row); - - updateAlarmOperatePerm(); - if(!m_listLocationOptId.contains(info->location_id)) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警所在位置的操作权限!")); - msgBox.exec(); - return; - } - if(!m_listRegionOptId.contains(info->region_id) && info->region_id != -1) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警所在责任区的操作权限!")); - msgBox.exec(); - return; - } - - kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); - pkg->set_node_name(m_nodeName); - pkg->set_user_id(m_userId); - pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); - pkg->set_domain_id(info->domain_id); - pkg->set_app_id(info->app_id); - pkg->set_alm_type(info->alm_type); - pkg->add_key_id_tag(info->key_id_tag.toStdString()); - pkg->add_time_stamp(info->time_stamp); - pkg->add_uuid_base64(info->uuid_base64.toStdString()); - //请求确认 - CAlarmDataCollect::instance()->requestCfmAlm(*pkg); - - delete pkg; -} - -void CAlarmWidget::setEnableTrend(bool isNeed) -{ - if(m_delegate) - { - m_delegate->setEnableTrend(isNeed); - } -} - -void CAlarmWidget::setEnableVideo(bool isNeed) -{ - if(m_delegate) - { - m_delegate->setEnableVideo(isNeed); - } -} - -void CAlarmWidget::setEnableWave(bool isNeed) -{ - if(m_delegate) - { - m_delegate->setEnableWave(isNeed); - } -} - -void CAlarmWidget::setEnableLevel(bool isNeed) -{ - if(m_delegate) - { - m_delegate->setEnableLevel(isNeed); - } -} - -bool CAlarmWidget::updateAlarmOperatePerm() -{ - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return false; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - m_nodeName = stNodeInfo.strName; - m_listLocationOptId.clear(); - m_listRegionOptId.clear(); - m_listLocationDelId.clear(); - m_listRegionDelId.clear(); - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(0 != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - m_userId = -1; - LOGERROR("用户ID获取失败!"); - return false; - } - std::vector vecRegionOptId; - std::vector vecLocationOptId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionOptId, vecLocationOptId)) - { - std::vector ::iterator region = vecRegionOptId.begin(); - while (region != vecRegionOptId.end()) - { - m_listRegionOptId.append(*region++); - } - - std::vector ::iterator location = vecLocationOptId.begin(); - while (location != vecLocationOptId.end()) - { - m_listLocationOptId.append(*location++); - } - } - std::vector vecRegionDelId; - std::vector vecLocationDelId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, vecRegionDelId, vecLocationDelId)) - { - std::vector ::iterator region = vecRegionDelId.begin(); - while (region != vecRegionDelId.end()) - { - m_listRegionDelId.append(*region++); - } - - std::vector ::iterator location = vecLocationDelId.begin(); - while (location != vecLocationDelId.end()) - { - m_listLocationDelId.append(*location++); - } - } - return true; - } - return false; -} - -void CAlarmWidget::slotConfirmRow0() -{ - confirmAlarm(0); -} - -void CAlarmWidget::slotConfirmRow1() -{ - confirmAlarm(1); -} - -void CAlarmWidget::slotConfirmRow2() -{ - confirmAlarm(2); -} +#include "CAlarmWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmForm.h" +#include "CAlarmView.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "CAlarmDataCollect.h" +#include "CAlarmDelegate.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include +#include "pub_logger_api/logger.h" + +CAlarmWidget::CAlarmWidget(QWidget *parent) + : QWidget(parent), + m_pView(Q_NULLPTR), + m_pModel(Q_NULLPTR), + m_delegate(Q_NULLPTR), m_userId(0), + m_pConfirmButtonRow0(Q_NULLPTR), + m_pConfirmButtonRow1(Q_NULLPTR), + m_pConfirmButtonRow2(Q_NULLPTR) +{ + //initialize(); +} + +CAlarmWidget::~CAlarmWidget() +{ + if(Q_NULLPTR != m_delegate) + { + delete m_delegate; + } + m_delegate = Q_NULLPTR; + qDebug() << "~CAlarmWidget()"; +} + +void CAlarmWidget::setAlarmModel(CAlarmItemModel *pModel) +{ + if(!pModel) + { + return; + } + m_pModel = pModel; + m_pView->setModel(m_pModel); + + if(!m_delegate) + { + m_delegate = new CAlarmDelegate(m_pModel, this); + m_pView->setItemDelegate(m_delegate); + connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmWidget::openVideo,Qt::QueuedConnection); + connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmWidget::openTrend,Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + } + + connect(m_pConfirmButtonRow0, SIGNAL(clicked()), this, SLOT(slotConfirmRow0())); + connect(m_pConfirmButtonRow1, SIGNAL(clicked()), this, SLOT(slotConfirmRow1())); + connect(m_pConfirmButtonRow2, SIGNAL(clicked()), this, SLOT(slotConfirmRow2())); + + + m_pView->setColumnHidden(0, false); + m_pView->setColumnHidden(1, false); + m_pView->setColumnHidden(2, false); + m_pView->setColumnHidden(3, true); + m_pView->setColumnHidden(4, true); + m_pView->setColumnHidden(5, false); + m_pView->setColumnHidden(6, false); + m_pView->setColumnHidden(7, false); + + + m_pView->setColumnWidth(0, 230); + m_pView->setColumnWidth(1, 120); + m_pView->setColumnWidth(2, 150); + m_pView->setColumnWidth(5, 150); + m_pView->setColumnWidth(6, 120); + + updateRowHeight(); +} + +void CAlarmWidget::setRowHeight(const int &height) +{ + if(m_pView) + { + m_pView->setRowHeight(0, height); + m_pView->setRowHeight(1, height); + m_pView->setRowHeight(2, height); + updateRowHeight(); + } +} + +void CAlarmWidget::setDockColumnVisible(const int &column, const bool &visbile) +{ + if(m_pView) + { + m_pView->setColumnHidden(column, !visbile); + } +} + +void CAlarmWidget::updateRowHeight() +{ + int nHeight = m_pView->rowHeight(0); + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setFixedHeight(nHeight * 3 + 1); +} + +void CAlarmWidget::updateView() +{ + if(m_pView != Q_NULLPTR) + { + m_pView->setShowGrid(m_pModel->getShowAlarmCount()); + m_pModel->updateAlternate(); + m_pView->viewport()->update(); + } +} + +void CAlarmWidget::setAlarmOperateEnable(const bool &bEnable) +{ + m_pConfirmButtonRow0->setEnabled(bEnable); + m_pConfirmButtonRow1->setEnabled(bEnable); + m_pConfirmButtonRow2->setEnabled(bEnable); +} + +void CAlarmWidget::setColumnWidth(const int &column, const int &width) +{ + if(m_pView != Q_NULLPTR) + { + m_pView->setColumnWidth(column, width); + } +} + +void CAlarmWidget::initialize() +{ + QHBoxLayout * pLayout = new QHBoxLayout(this); + pLayout->setMargin(0); + setLayout(pLayout); + + m_pView = new CAlarmView(this); + m_pView->setAlternatingRowColors(true); + m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pView->setSelectionMode(QAbstractItemView::NoSelection); + m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_pView->horizontalHeader()->setStretchLastSection(true); + m_pView->horizontalHeader()->setVisible(false); + + m_pView->verticalHeader()->setVisible(false); + m_pView->setColumnWidth(0, 150); + pLayout->addWidget(m_pView); + QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); + m_pConfirmButtonRow0 = new QPushButton(tr("确认")); + m_pConfirmButtonRow1 = new QPushButton(tr("确认")); + m_pConfirmButtonRow2 = new QPushButton(tr("确认")); + int nHeight = 23; + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setMinimumHeight(nHeight * 3); + + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); + + pConfirmBtnLayout->addStretch(); + pLayout->addLayout(pConfirmBtnLayout); + layout()->setSpacing(0); + + updateAlarmOperatePerm(); + + m_pConfirmButtonRow0->setVisible(false); + m_pConfirmButtonRow1->setVisible(false); + m_pConfirmButtonRow2->setVisible(false); + connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); +} + +void CAlarmWidget::initializeEdit() +{ + QHBoxLayout * pLayout = new QHBoxLayout(this); + pLayout->setMargin(0); + setLayout(pLayout); + //m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") << tr("确认状态") << tr("告警内容"); + QStandardItemModel *model = new QStandardItemModel(); + model->setItem(0,0,new QStandardItem("2020-01-01 12:59:59.999")); + model->setItem(0,1,new QStandardItem("高")); + model->setItem(0,2,new QStandardItem("XX位置")); + model->setItem(0,3,new QStandardItem("-")); + model->setItem(0,4,new QStandardItem("系统信息")); + model->setItem(0,5,new QStandardItem("通道异常")); + model->setItem(0,6,new QStandardItem("未确认")); + model->setItem(0,7,new QStandardItem("通道:chanX,通道状态:通讯中断!")); + model->item(0,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,1)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,2)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,3)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,4)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,5)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,6)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,7)->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); + m_pView = new CAlarmView(this); + m_pView->setAlternatingRowColors(true); + m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pView->setSelectionMode(QAbstractItemView::NoSelection); + m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_pView->horizontalHeader()->setStretchLastSection(true); + m_pView->horizontalHeader()->setVisible(false); + m_pView->verticalHeader()->setVisible(false); + + //m_pView->setColumnWidth(0, 150); + pLayout->addWidget(m_pView); + QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); + m_pConfirmButtonRow0 = new QPushButton(tr("确认")); + m_pConfirmButtonRow1 = new QPushButton(tr("确认")); + m_pConfirmButtonRow2 = new QPushButton(tr("确认")); + int nHeight = 23; + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setMinimumHeight(nHeight * 3); + + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); + + pConfirmBtnLayout->addStretch(); + pLayout->addLayout(pConfirmBtnLayout); + layout()->setSpacing(0); + + updateAlarmOperatePerm(); + + m_pConfirmButtonRow0->setVisible(false); + m_pConfirmButtonRow1->setVisible(false); + m_pConfirmButtonRow2->setVisible(false); + + + m_pView->setModel(model); + m_pView->setColumnHidden(0, false); + m_pView->setColumnHidden(1, false); + m_pView->setColumnHidden(2, false); + m_pView->setColumnHidden(3, true); + m_pView->setColumnHidden(4, true); + m_pView->setColumnHidden(5, false); + m_pView->setColumnHidden(6, false); + m_pView->setColumnHidden(7, false); + + + m_pView->setColumnWidth(0, 230); + m_pView->setColumnWidth(1, 120); + m_pView->setColumnWidth(2, 150); + m_pView->setColumnWidth(5, 150); + m_pView->setColumnWidth(6, 120); + + m_pView->setRowHeight(0,50); + + //connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); +} + +void CAlarmWidget::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event) + if(Q_NULLPTR != m_pConfirmButtonRow0) + { + delete m_pConfirmButtonRow0; + m_pConfirmButtonRow0 = Q_NULLPTR; + } + if(Q_NULLPTR != m_pConfirmButtonRow1) + { + delete m_pConfirmButtonRow1; + m_pConfirmButtonRow1 = Q_NULLPTR; + } + if(Q_NULLPTR != m_pConfirmButtonRow2) + { + delete m_pConfirmButtonRow2; + m_pConfirmButtonRow2 = Q_NULLPTR; + } + QWidget::closeEvent(event); +} + +void CAlarmWidget::confirmAlarm(const int &row) +{ + //构建告警确认package + if(row >= m_pModel->getListShowAlarmInfo().count()) + { + return; + } + AlarmMsgPtr info = m_pModel->getListShowAlarmInfo().at(row); + + updateAlarmOperatePerm(); + if(!m_listLocationOptId.contains(info->location_id)) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警所在位置的操作权限!")); + msgBox.exec(); + return; + } + if(!m_listRegionOptId.contains(info->region_id) && info->region_id != -1) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警所在责任区的操作权限!")); + msgBox.exec(); + return; + } + + kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(info->domain_id); + pkg->set_app_id(info->app_id); + pkg->set_alm_type(info->alm_type); + pkg->add_key_id_tag(info->key_id_tag.toStdString()); + pkg->add_time_stamp(info->time_stamp); + pkg->add_uuid_base64(info->uuid_base64.toStdString()); + //请求确认 + CAlarmDataCollect::instance()->requestCfmAlm(*pkg); + + delete pkg; +} + +void CAlarmWidget::setEnableTrend(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableTrend(isNeed); + } +} + +void CAlarmWidget::setEnableVideo(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableVideo(isNeed); + } +} + +void CAlarmWidget::setEnableWave(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableWave(isNeed); + } +} + +void CAlarmWidget::setEnableLevel(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableLevel(isNeed); + } +} + +bool CAlarmWidget::updateAlarmOperatePerm() +{ + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + m_nodeName = stNodeInfo.strName; + m_listLocationOptId.clear(); + m_listRegionOptId.clear(); + m_listLocationDelId.clear(); + m_listRegionDelId.clear(); + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(0 != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + m_userId = -1; + LOGERROR("用户ID获取失败!"); + return false; + } + std::vector vecRegionOptId; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionOptId, vecLocationOptId)) + { + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + m_listRegionOptId.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + m_listLocationOptId.append(*location++); + } + } + std::vector vecRegionDelId; + std::vector vecLocationDelId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, vecRegionDelId, vecLocationDelId)) + { + std::vector ::iterator region = vecRegionDelId.begin(); + while (region != vecRegionDelId.end()) + { + m_listRegionDelId.append(*region++); + } + + std::vector ::iterator location = vecLocationDelId.begin(); + while (location != vecLocationDelId.end()) + { + m_listLocationDelId.append(*location++); + } + } + return true; + } + return false; +} + +void CAlarmWidget::slotConfirmRow0() +{ + confirmAlarm(0); +} + +void CAlarmWidget::slotConfirmRow1() +{ + confirmAlarm(1); +} + +void CAlarmWidget::slotConfirmRow2() +{ + confirmAlarm(2); +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmWidget.h b/product/src/gui/plugin/AlarmWidget/CAlarmWidget.h index 7037f9cd..da4d8f4a 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmWidget.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmWidget.h @@ -1,79 +1,79 @@ -#ifndef CALARMWINDOW_H -#define CALARMWINDOW_H - -#include - -class QPushButton; -class QMouseEvent; -class CAlarmView; -class CAlarmDelegate; -class CAlarmItemModel; - -class CAlarmWidget : public QWidget -{ - Q_OBJECT -public: - explicit CAlarmWidget(QWidget *parent = nullptr); - ~CAlarmWidget(); - - void setAlarmModel(CAlarmItemModel * pModel); - - void setRowHeight(const int &height); - - void setDockColumnVisible(const int &column, const bool &visbile); - - void updateRowHeight(); - - void updateView(); - - void setAlarmOperateEnable(const bool &bEnable); - - void setColumnWidth(const int &column, const int &width); - - void confirmAlarm(const int &row); - - void setEnableTrend(bool isNeed); - - void setEnableVideo(bool isNeed); - - void setEnableWave(bool isNeed); - - void setEnableLevel(bool isNeed); - -signals: - void alarmWidgetDoubleClicked(); - - void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); - - void openTrend(quint64 time_stamp,QStringList tagList); -protected: - void closeEvent(QCloseEvent *event); - - bool updateAlarmOperatePerm(); - -public slots: - void initialize(); - - void initializeEdit(); - void slotConfirmRow0(); - void slotConfirmRow1(); - void slotConfirmRow2(); - - -private: - CAlarmView * m_pView; - CAlarmItemModel * m_pModel; - CAlarmDelegate * m_delegate; - int m_userId; - std::string m_nodeName; - QList m_listRegionOptId; - QList m_listLocationOptId; - - QList m_listRegionDelId; - QList m_listLocationDelId; - QPushButton * m_pConfirmButtonRow0; - QPushButton * m_pConfirmButtonRow1; - QPushButton * m_pConfirmButtonRow2; -}; - -#endif // ALARMWINDOW_H +#ifndef CALARMWINDOW_H +#define CALARMWINDOW_H + +#include + +class QPushButton; +class QMouseEvent; +class CAlarmView; +class CAlarmDelegate; +class CAlarmItemModel; + +class CAlarmWidget : public QWidget +{ + Q_OBJECT +public: + explicit CAlarmWidget(QWidget *parent = nullptr); + ~CAlarmWidget(); + + void setAlarmModel(CAlarmItemModel * pModel); + + void setRowHeight(const int &height); + + void setDockColumnVisible(const int &column, const bool &visbile); + + void updateRowHeight(); + + void updateView(); + + void setAlarmOperateEnable(const bool &bEnable); + + void setColumnWidth(const int &column, const int &width); + + void confirmAlarm(const int &row); + + void setEnableTrend(bool isNeed); + + void setEnableVideo(bool isNeed); + + void setEnableWave(bool isNeed); + + void setEnableLevel(bool isNeed); + +signals: + void alarmWidgetDoubleClicked(); + + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + + void openTrend(quint64 time_stamp,QStringList tagList); +protected: + void closeEvent(QCloseEvent *event); + + bool updateAlarmOperatePerm(); + +public slots: + void initialize(); + + void initializeEdit(); + void slotConfirmRow0(); + void slotConfirmRow1(); + void slotConfirmRow2(); + + +private: + CAlarmView * m_pView; + CAlarmItemModel * m_pModel; + CAlarmDelegate * m_delegate; + int m_userId; + std::string m_nodeName; + QList m_listRegionOptId; + QList m_listLocationOptId; + + QList m_listRegionDelId; + QList m_listLocationDelId; + QPushButton * m_pConfirmButtonRow0; + QPushButton * m_pConfirmButtonRow1; + QPushButton * m_pConfirmButtonRow2; +}; + +#endif // ALARMWINDOW_H diff --git a/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.cpp b/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.cpp index 76ecc8a0..cc76816e 100644 --- a/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.cpp +++ b/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.cpp @@ -1,28 +1,28 @@ -#include "CDisposalPlanDialog.h" -#include "ui_CDisposalPlanDialog.h" -#include "CAiAlarmMsgInfo.h" -#include -CDisposalPlanDialog::CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr, QWidget *parent) : - QDialog(parent), - ui(new Ui::CDisposalPlanDialog), - m_aiptr(aiptr) -{ - ui->setupUi(this); - setWindowTitle(tr("处置预案")); - Qt::WindowFlags flags=Qt::Dialog; - flags |=Qt::WindowCloseButtonHint; - setWindowFlags(flags); - - ui->time->setReadOnly(true); - ui->content->setReadOnly(true); - ui->displan->setReadOnly(true); - - ui->time->setText(QDateTime::fromMSecsSinceEpoch(m_aiptr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); - ui->content->setText(m_aiptr->content); - ui->displan->setText(m_aiptr->disposal_plan); -} - -CDisposalPlanDialog::~CDisposalPlanDialog() -{ - delete ui; -} +#include "CDisposalPlanDialog.h" +#include "ui_CDisposalPlanDialog.h" +#include "CAiAlarmMsgInfo.h" +#include +CDisposalPlanDialog::CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr, QWidget *parent) : + QDialog(parent), + ui(new Ui::CDisposalPlanDialog), + m_aiptr(aiptr) +{ + ui->setupUi(this); + setWindowTitle(tr("处置预案")); + Qt::WindowFlags flags=Qt::Dialog; + flags |=Qt::WindowCloseButtonHint; + setWindowFlags(flags); + + ui->time->setReadOnly(true); + ui->content->setReadOnly(true); + ui->displan->setReadOnly(true); + + ui->time->setText(QDateTime::fromMSecsSinceEpoch(m_aiptr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); + ui->content->setText(m_aiptr->content); + ui->displan->setText(m_aiptr->disposal_plan); +} + +CDisposalPlanDialog::~CDisposalPlanDialog() +{ + delete ui; +} diff --git a/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.h b/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.h index 802ea751..3dccca2c 100644 --- a/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.h +++ b/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.h @@ -1,23 +1,23 @@ -#ifndef CDISPOSALPLANDIALOG_H -#define CDISPOSALPLANDIALOG_H - -#include -#include "CAlarmCommon.h" -namespace Ui { -class CDisposalPlanDialog; -} - -class CDisposalPlanDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr,QWidget *parent = 0); - ~CDisposalPlanDialog(); - -private: - Ui::CDisposalPlanDialog *ui; - AiAlarmMsgPtr m_aiptr; -}; - -#endif // CDISPOSALPLANDIALOG_H +#ifndef CDISPOSALPLANDIALOG_H +#define CDISPOSALPLANDIALOG_H + +#include +#include "CAlarmCommon.h" +namespace Ui { +class CDisposalPlanDialog; +} + +class CDisposalPlanDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr,QWidget *parent = 0); + ~CDisposalPlanDialog(); + +private: + Ui::CDisposalPlanDialog *ui; + AiAlarmMsgPtr m_aiptr; +}; + +#endif // CDISPOSALPLANDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.ui b/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.ui index 43b98f2b..4e69345b 100644 --- a/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.ui +++ b/product/src/gui/plugin/AlarmWidget/CDisposalPlanDialog.ui @@ -1,140 +1,140 @@ - - - CDisposalPlanDialog - - - - 0 - 0 - 391 - 389 - - - - Dialog - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - Qt::Vertical - - - - - - - 告警时间: - - - - - - - - - - - - 0 - 20 - - - - - 16777215 - 20 - - - - 告警内容: - - - - - - 0 - 50 - - - - - - - 0 - 20 - - - - - 16777215 - 20 - - - - 处置预案: - - - - - - 0 - 50 - - - - - - - - - - - - - - - - + + + CDisposalPlanDialog + + + + 0 + 0 + 391 + 389 + + + + Dialog + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Vertical + + + + + + + 告警时间: + + + + + + + + + + + + 0 + 20 + + + + + 16777215 + 20 + + + + 告警内容: + + + + + + 0 + 50 + + + + + + + 0 + 20 + + + + + 16777215 + 20 + + + + 处置预案: + + + + + + 0 + 50 + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CMyCalendar.cpp b/product/src/gui/plugin/AlarmWidget/CMyCalendar.cpp index cfc6822e..9dca56ae 100644 --- a/product/src/gui/plugin/AlarmWidget/CMyCalendar.cpp +++ b/product/src/gui/plugin/AlarmWidget/CMyCalendar.cpp @@ -1,57 +1,57 @@ -#include "CMyCalendar.h" -#include "ui_CMyCalendar.h" -#include -#include -#include -CMyCalendar::CMyCalendar(QWidget *parent) : - QWidget(parent), - ui(new Ui::CMyCalendar) -{ - ui->setupUi(this); - connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); - connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); - connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); - m_startTime = QDate::currentDate(); - m_endTime = QDate::currentDate(); - ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); - ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit_2->setReadOnly(true); -} - -CMyCalendar::~CMyCalendar() -{ - delete ui; -} - -void CMyCalendar::keyPressEvent(QKeyEvent *event) -{ - if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) - { - return ; - } - QWidget::keyPressEvent(event); -} - -void CMyCalendar::slot_endTime(QDate date) -{ - ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); - m_endTime = date; - if(m_startTime.isNull() || m_endTime < m_startTime) - { - //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); - return; - } - emit sig_endTimeClick(m_startTime,m_endTime); -} - -void CMyCalendar::slot_startTime(QDate date) -{ - m_startTime = date; - ui->lineEdit->setText(date.toString("yyyy-MM-dd")); -} - -void CMyCalendar::slot_cancle() -{ - emit sig_cancle(); -} +#include "CMyCalendar.h" +#include "ui_CMyCalendar.h" +#include +#include +#include +CMyCalendar::CMyCalendar(QWidget *parent) : + QWidget(parent), + ui(new Ui::CMyCalendar) +{ + ui->setupUi(this); + connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); + connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); + connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); + m_startTime = QDate::currentDate(); + m_endTime = QDate::currentDate(); + ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); + ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit_2->setReadOnly(true); +} + +CMyCalendar::~CMyCalendar() +{ + delete ui; +} + +void CMyCalendar::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) + { + return ; + } + QWidget::keyPressEvent(event); +} + +void CMyCalendar::slot_endTime(QDate date) +{ + ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); + m_endTime = date; + if(m_startTime.isNull() || m_endTime < m_startTime) + { + //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); + return; + } + emit sig_endTimeClick(m_startTime,m_endTime); +} + +void CMyCalendar::slot_startTime(QDate date) +{ + m_startTime = date; + ui->lineEdit->setText(date.toString("yyyy-MM-dd")); +} + +void CMyCalendar::slot_cancle() +{ + emit sig_cancle(); +} diff --git a/product/src/gui/plugin/AlarmWidget/CMyCalendar.h b/product/src/gui/plugin/AlarmWidget/CMyCalendar.h index 2b103611..339fb73c 100644 --- a/product/src/gui/plugin/AlarmWidget/CMyCalendar.h +++ b/product/src/gui/plugin/AlarmWidget/CMyCalendar.h @@ -1,34 +1,34 @@ -#ifndef CMYCALENDAR_H -#define CMYCALENDAR_H - -#include -#include - -namespace Ui { -class CMyCalendar; -} - -class CMyCalendar : public QWidget -{ - Q_OBJECT -signals: - void sig_endTimeClick(QDate startDate,QDate endDate); - void sig_startTimeClick(QDate date); - void sig_cancle(); -public: - explicit CMyCalendar(QWidget *parent = 0); - ~CMyCalendar(); -protected: - virtual void keyPressEvent(QKeyEvent *event); - -public slots: - void slot_endTime(QDate date); - void slot_startTime(QDate date); - void slot_cancle(); -private: - Ui::CMyCalendar *ui; - QDate m_startTime; - QDate m_endTime; -}; - -#endif // CMYCALENDAR_H +#ifndef CMYCALENDAR_H +#define CMYCALENDAR_H + +#include +#include + +namespace Ui { +class CMyCalendar; +} + +class CMyCalendar : public QWidget +{ + Q_OBJECT +signals: + void sig_endTimeClick(QDate startDate,QDate endDate); + void sig_startTimeClick(QDate date); + void sig_cancle(); +public: + explicit CMyCalendar(QWidget *parent = 0); + ~CMyCalendar(); +protected: + virtual void keyPressEvent(QKeyEvent *event); + +public slots: + void slot_endTime(QDate date); + void slot_startTime(QDate date); + void slot_cancle(); +private: + Ui::CMyCalendar *ui; + QDate m_startTime; + QDate m_endTime; +}; + +#endif // CMYCALENDAR_H diff --git a/product/src/gui/plugin/AlarmWidget/CMyCalendar.ui b/product/src/gui/plugin/AlarmWidget/CMyCalendar.ui index 8df14ac2..9610c481 100644 --- a/product/src/gui/plugin/AlarmWidget/CMyCalendar.ui +++ b/product/src/gui/plugin/AlarmWidget/CMyCalendar.ui @@ -1,140 +1,140 @@ - - - CMyCalendar - - - - 0 - 0 - 538 - 270 - - - - Form - - - 1.000000000000000 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - 0 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - 0 - - - - - - - - - 20 - 0 - - - - - 20 - 16777215 - - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - false - - - 0 - - - - - - Qt::AlignCenter - - - - - - - - - - 取消 - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - + + + CMyCalendar + + + + 0 + 0 + 538 + 270 + + + + Form + + + 1.000000000000000 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + + + + + + + + + 20 + 0 + + + + + 20 + 16777215 + + + + Qt::NoContextMenu + + + Qt::LeftToRight + + + false + + + 0 + + + + + + Qt::AlignCenter + + + + + + + + + + 取消 + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CMyCheckBox.cpp b/product/src/gui/plugin/AlarmWidget/CMyCheckBox.cpp index 2be14b81..c30c3224 100644 --- a/product/src/gui/plugin/AlarmWidget/CMyCheckBox.cpp +++ b/product/src/gui/plugin/AlarmWidget/CMyCheckBox.cpp @@ -1,21 +1,21 @@ -#include "CMyCheckBox.h" -#include - -CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) - :QCheckBox(text,parent) -{ - -} - -CMyCheckBox::CMyCheckBox(QWidget *parent) - :QCheckBox(parent) -{ - -} - -void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) -{ - Q_UNUSED(e); - setChecked(!isChecked()); - emit clicked(isChecked()); -} +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e); + setChecked(!isChecked()); + emit clicked(isChecked()); +} diff --git a/product/src/gui/plugin/AlarmWidget/CMyCheckBox.h b/product/src/gui/plugin/AlarmWidget/CMyCheckBox.h index 36947db5..bdba8dbc 100644 --- a/product/src/gui/plugin/AlarmWidget/CMyCheckBox.h +++ b/product/src/gui/plugin/AlarmWidget/CMyCheckBox.h @@ -1,16 +1,16 @@ -#ifndef MYCHECKBOX_H -#define MYCHECKBOX_H - -#include - -class CMyCheckBox : public QCheckBox -{ -public: - CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); - CMyCheckBox(QWidget *parent = Q_NULLPTR); - -protected: - void mouseReleaseEvent(QMouseEvent *e); -}; - -#endif // MYCHECKBOX_H +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/AlarmWidget/CMyListWidget.cpp b/product/src/gui/plugin/AlarmWidget/CMyListWidget.cpp index 3b542202..ded92615 100644 --- a/product/src/gui/plugin/AlarmWidget/CMyListWidget.cpp +++ b/product/src/gui/plugin/AlarmWidget/CMyListWidget.cpp @@ -1,12 +1,12 @@ -#include "CMyListWidget.h" - -CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) -{ - -} - -void CMyListWidget::showEvent(QShowEvent *event) -{ - this->updateGeometries(); - QListWidget::showEvent(event); -} +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/AlarmWidget/CMyListWidget.h b/product/src/gui/plugin/AlarmWidget/CMyListWidget.h index 9fc4491f..3e92461e 100644 --- a/product/src/gui/plugin/AlarmWidget/CMyListWidget.h +++ b/product/src/gui/plugin/AlarmWidget/CMyListWidget.h @@ -1,15 +1,15 @@ -#ifndef CMYLISTWIDGET_H -#define CMYLISTWIDGET_H - -#include - -class CMyListWidget : public QListWidget -{ -public: - explicit CMyListWidget(QWidget *parent = 0); - -protected: - void showEvent(QShowEvent *event); -}; - -#endif // CMYLISTWIDGET_H +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/AlarmWidget/CPdfPrinter.cpp b/product/src/gui/plugin/AlarmWidget/CPdfPrinter.cpp index de050ab0..f11342f0 100644 --- a/product/src/gui/plugin/AlarmWidget/CPdfPrinter.cpp +++ b/product/src/gui/plugin/AlarmWidget/CPdfPrinter.cpp @@ -1,112 +1,112 @@ -#include "CPdfPrinter.h" -#include -#include -#include -#include - -CPdfPrinter::CPdfPrinter(QObject *parent) : QObject(parent) -{ - -} - -void CPdfPrinter::initialize() -{ - -} - -void CPdfPrinter::printerByModel(CAiAlarmTreeModel *treeModel, QString fileName) -{ - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "智能告警" ); - // 写横向表头 - QXlsx::Format formatheader; - formatheader.setFontBold(true); - formatheader.setFontColor(Qt::black); - - QXlsx::Format formatAi; - formatAi.setFontBold(true); - formatAi.setFontColor(Qt::red); - - QXlsx::Format formatMergedAlm; - formatMergedAlm.setFontBold(false); - formatMergedAlm.setFontColor(Qt::darkGreen); - QXlsx::Format formatAlm; - formatAlm.setFontBold(false); - formatAlm.setFontColor(Qt::darkYellow); - int colcount = treeModel->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString(),formatheader); - } - - // 写内容 - int rowNum = 1; - CAiAlarmTreeItem *item = treeModel->getItem(); - QList itemList = item->getChildItemList(); - for(int index(0);indexisAi()) - { - for(int j(0);jdata(j).toString(); - xlsx.write( rowNum +1, j+1, sText,formatAi ); - } - rowNum++; - QList itemList_ =itemList.at(index)->getChildItemList(); - for(int indexAlm(0);indexAlmdata(i).toString(); - xlsx.write( rowNum +1, i+1, sText,formatMergedAlm ); - } - rowNum++; - } - }else - { - for(int j(0);jdata(j).toString(); - xlsx.write( rowNum +1, j+1, sText,formatAlm ); - } - rowNum++; - } - } - - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - - // 提示导出路径 - emit printResult(sExcelFileName); -} - -void CPdfPrinter::printerAlmByModel(CAlarmItemModel *model, QString fileName) -{ - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "原始告警" ); - // 写横向表头 - int rowcount=model->rowCount(); - int colcount=model->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - - // 写内容 - for ( int i=0; idata(model->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText); - } - } - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - - // 提示导出路径 - emit printResult(sExcelFileName); -} +#include "CPdfPrinter.h" +#include +#include +#include +#include + +CPdfPrinter::CPdfPrinter(QObject *parent) : QObject(parent) +{ + +} + +void CPdfPrinter::initialize() +{ + +} + +void CPdfPrinter::printerByModel(CAiAlarmTreeModel *treeModel, QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "智能告警" ); + // 写横向表头 + QXlsx::Format formatheader; + formatheader.setFontBold(true); + formatheader.setFontColor(Qt::black); + + QXlsx::Format formatAi; + formatAi.setFontBold(true); + formatAi.setFontColor(Qt::red); + + QXlsx::Format formatMergedAlm; + formatMergedAlm.setFontBold(false); + formatMergedAlm.setFontColor(Qt::darkGreen); + QXlsx::Format formatAlm; + formatAlm.setFontBold(false); + formatAlm.setFontColor(Qt::darkYellow); + int colcount = treeModel->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString(),formatheader); + } + + // 写内容 + int rowNum = 1; + CAiAlarmTreeItem *item = treeModel->getItem(); + QList itemList = item->getChildItemList(); + for(int index(0);indexisAi()) + { + for(int j(0);jdata(j).toString(); + xlsx.write( rowNum +1, j+1, sText,formatAi ); + } + rowNum++; + QList itemList_ =itemList.at(index)->getChildItemList(); + for(int indexAlm(0);indexAlmdata(i).toString(); + xlsx.write( rowNum +1, i+1, sText,formatMergedAlm ); + } + rowNum++; + } + }else + { + for(int j(0);jdata(j).toString(); + xlsx.write( rowNum +1, j+1, sText,formatAlm ); + } + rowNum++; + } + } + + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + + // 提示导出路径 + emit printResult(sExcelFileName); +} + +void CPdfPrinter::printerAlmByModel(CAlarmItemModel *model, QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "原始告警" ); + // 写横向表头 + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString()); + } + + // 写内容 + for ( int i=0; idata(model->index(i, j)).toString(); + xlsx.write( i+2, j+1, sText); + } + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + + // 提示导出路径 + emit printResult(sExcelFileName); +} diff --git a/product/src/gui/plugin/AlarmWidget/CPdfPrinter.h b/product/src/gui/plugin/AlarmWidget/CPdfPrinter.h index d71c8062..297f96b1 100644 --- a/product/src/gui/plugin/AlarmWidget/CPdfPrinter.h +++ b/product/src/gui/plugin/AlarmWidget/CPdfPrinter.h @@ -1,39 +1,39 @@ -/** -* @file AlarmWidget 之前是做pdf打印,因需求修改,现在改为excel ,但是类名不变,维护请注意 -* @brief -* @author jxd -* @date 2020-01-08 -*/ -#ifndef CPDFPRINTER_H -#define CPDFPRINTER_H - -#include -#include -#include -#include -#include -#include "model_excel/xlsx/xlsxdocument.h" -#include "model_excel/xlsx/xlsxformat.h" - -class CPdfPrinter : public QObject -{ - Q_OBJECT -public: - explicit CPdfPrinter(QObject *parent = nullptr); - - void initialize(); - -signals: - void printResult(QString fileName); -public slots: - void printerByModel(CAiAlarmTreeModel *treeModel, QString fileName); - void printerAlmByModel(CAlarmItemModel *model,QString fileName); -private: - QString m_fileName; - QVector m_columnHidden; - QVector m_columnWidth; - int m_headHeight; - int m_height; - int m_width; -}; -#endif // CPDFPRINTER_H +/** +* @file AlarmWidget 之前是做pdf打印,因需求修改,现在改为excel ,但是类名不变,维护请注意 +* @brief +* @author jxd +* @date 2020-01-08 +*/ +#ifndef CPDFPRINTER_H +#define CPDFPRINTER_H + +#include +#include +#include +#include +#include +#include "model_excel/xlsx/xlsxdocument.h" +#include "model_excel/xlsx/xlsxformat.h" + +class CPdfPrinter : public QObject +{ + Q_OBJECT +public: + explicit CPdfPrinter(QObject *parent = nullptr); + + void initialize(); + +signals: + void printResult(QString fileName); +public slots: + void printerByModel(CAiAlarmTreeModel *treeModel, QString fileName); + void printerAlmByModel(CAlarmItemModel *model,QString fileName); +private: + QString m_fileName; + QVector m_columnHidden; + QVector m_columnWidth; + int m_headHeight; + int m_height; + int m_width; +}; +#endif // CPDFPRINTER_H diff --git a/product/src/gui/plugin/AlarmWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/AlarmWidget/CTableViewPrinter.cpp index 29dd845d..ae316e25 100644 --- a/product/src/gui/plugin/AlarmWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/AlarmWidget/CTableViewPrinter.cpp @@ -1,54 +1,54 @@ -#include "CTableViewPrinter.h" -#include "CAlarmCommon.h" -#include "CAlarmBaseData.h" -CTableViewPrinter::CTableViewPrinter(CAlarmItemModel *model): - m_pModel(model) -{ - -} - -QVector CTableViewPrinter::getHead() -{ - int columnCount = m_pModel->columnCount(); - QVector header; - for(int index(0);index headerData(index,Qt::Horizontal).toString()); - } - return header; -} - -QList > CTableViewPrinter::getData() -{ - QList > data; - QList list = m_pModel->getListShowAlarmInfo(); - for(int index(0);index content; - //1.时间 - content.append(QDateTime::fromMSecsSinceEpoch(list.at(index)->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); - //2.优先级 - content.append(CAlarmBaseData::instance()->queryPriorityDesc(list.at(index)->priority)); - //3.位置 - content.append(CAlarmBaseData::instance()->queryLocationDesc(list.at(index)->location_id)); - //4.责任区 - content.append(CAlarmBaseData::instance()->queryRegionDesc(list.at(index)->region_id)); - //5.类型 - content.append(CAlarmBaseData::instance()->queryAlarmTypeDesc(list.at(index)->alm_type)); - //6.状态 - content.append(CAlarmBaseData::instance()->queryAlarmStatusDesc(list.at(index)->alm_status)); - //7.确认状态 - if(list.at(index)->logic_state == E_ALS_ALARM || list.at(index)->logic_state == E_ALS_RETURN) - { - content.append(QObject::tr("未确认")); - }else - { - content.append(QObject::tr("已确认")); - } - //8.内容 - content.append(list.at(index)->content); - data.append(content); - } - return data; -} - +#include "CTableViewPrinter.h" +#include "CAlarmCommon.h" +#include "CAlarmBaseData.h" +CTableViewPrinter::CTableViewPrinter(CAlarmItemModel *model): + m_pModel(model) +{ + +} + +QVector CTableViewPrinter::getHead() +{ + int columnCount = m_pModel->columnCount(); + QVector header; + for(int index(0);index headerData(index,Qt::Horizontal).toString()); + } + return header; +} + +QList > CTableViewPrinter::getData() +{ + QList > data; + QList list = m_pModel->getListShowAlarmInfo(); + for(int index(0);index content; + //1.时间 + content.append(QDateTime::fromMSecsSinceEpoch(list.at(index)->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); + //2.优先级 + content.append(CAlarmBaseData::instance()->queryPriorityDesc(list.at(index)->priority)); + //3.位置 + content.append(CAlarmBaseData::instance()->queryLocationDesc(list.at(index)->location_id)); + //4.责任区 + content.append(CAlarmBaseData::instance()->queryRegionDesc(list.at(index)->region_id)); + //5.类型 + content.append(CAlarmBaseData::instance()->queryAlarmTypeDesc(list.at(index)->alm_type)); + //6.状态 + content.append(CAlarmBaseData::instance()->queryAlarmStatusDesc(list.at(index)->alm_status)); + //7.确认状态 + if(list.at(index)->logic_state == E_ALS_ALARM || list.at(index)->logic_state == E_ALS_RETURN) + { + content.append(QObject::tr("未确认")); + }else + { + content.append(QObject::tr("已确认")); + } + //8.内容 + content.append(list.at(index)->content); + data.append(content); + } + return data; +} + diff --git a/product/src/gui/plugin/AlarmWidget/CTableViewPrinter.h b/product/src/gui/plugin/AlarmWidget/CTableViewPrinter.h index d464b6d8..b911e7a8 100644 --- a/product/src/gui/plugin/AlarmWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/AlarmWidget/CTableViewPrinter.h @@ -1,15 +1,15 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H -#include "CAlarmItemModel.h" -class QVariant; -class CTableViewPrinter -{ -public: - CTableViewPrinter(CAlarmItemModel *model); - QVector getHead(); - QList > getData(); -private: - CAlarmItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H +#include "CAlarmItemModel.h" +class QVariant; +class CTableViewPrinter +{ +public: + CTableViewPrinter(CAlarmItemModel *model); + QVector getHead(); + QList > getData(); +private: + CAlarmItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/AlarmWidget/CTreeViewPrinter.cpp b/product/src/gui/plugin/AlarmWidget/CTreeViewPrinter.cpp index fbcbdf1d..673ee6af 100644 --- a/product/src/gui/plugin/AlarmWidget/CTreeViewPrinter.cpp +++ b/product/src/gui/plugin/AlarmWidget/CTreeViewPrinter.cpp @@ -1,42 +1,42 @@ -#include "CTreeViewPrinter.h" -#include "CAiAlarmTreeItem.h" -CTreeViewPrinter::CTreeViewPrinter(CAiAlarmTreeModel *model): - m_pModel(model) -{ - -} - -QVector CTreeViewPrinter::getHead() -{ - int columnCount = m_pModel->columnCount(); - QVector header; - for(int index(0);index headerData(index,Qt::Horizontal).toString()); - } - return header; -} - -QList > CTreeViewPrinter::getData() -{ - QList > data; - CAiAlarmTreeItem *item = ((CAiAlarmTreeModel*)m_pModel)->getItem(); - QList itemList = item->getChildItemList(); - for(int index(0);index content; - content = itemList.at(index)->getContent(); - data.append(content); - if(itemList.at(index)->isAi()) - { - QList itemlist = itemList.at(index)->getChildItemList(); - for(int dex(0);dex almInfo; - almInfo = itemlist.at(dex)->getContent(); - data.append(almInfo); - } - } - } - return data; -} +#include "CTreeViewPrinter.h" +#include "CAiAlarmTreeItem.h" +CTreeViewPrinter::CTreeViewPrinter(CAiAlarmTreeModel *model): + m_pModel(model) +{ + +} + +QVector CTreeViewPrinter::getHead() +{ + int columnCount = m_pModel->columnCount(); + QVector header; + for(int index(0);index headerData(index,Qt::Horizontal).toString()); + } + return header; +} + +QList > CTreeViewPrinter::getData() +{ + QList > data; + CAiAlarmTreeItem *item = ((CAiAlarmTreeModel*)m_pModel)->getItem(); + QList itemList = item->getChildItemList(); + for(int index(0);index content; + content = itemList.at(index)->getContent(); + data.append(content); + if(itemList.at(index)->isAi()) + { + QList itemlist = itemList.at(index)->getChildItemList(); + for(int dex(0);dex almInfo; + almInfo = itemlist.at(dex)->getContent(); + data.append(almInfo); + } + } + } + return data; +} diff --git a/product/src/gui/plugin/AlarmWidget/CTreeViewPrinter.h b/product/src/gui/plugin/AlarmWidget/CTreeViewPrinter.h index ff13552a..a28a4498 100644 --- a/product/src/gui/plugin/AlarmWidget/CTreeViewPrinter.h +++ b/product/src/gui/plugin/AlarmWidget/CTreeViewPrinter.h @@ -1,15 +1,15 @@ -#ifndef CTREEVIEWPRINTER_H -#define CTREEVIEWPRINTER_H -#include "CAiAlarmTreeModel.h" -class QVariant; -class CTreeViewPrinter -{ -public: - CTreeViewPrinter(CAiAlarmTreeModel *model); - QVector getHead(); - QList > getData(); -private: - CAiAlarmTreeModel * m_pModel; -}; - -#endif // CTREEVIEWPRINTER_H +#ifndef CTREEVIEWPRINTER_H +#define CTREEVIEWPRINTER_H +#include "CAiAlarmTreeModel.h" +class QVariant; +class CTreeViewPrinter +{ +public: + CTreeViewPrinter(CAiAlarmTreeModel *model); + QVector getHead(); + QList > getData(); +private: + CAiAlarmTreeModel * m_pModel; +}; + +#endif // CTREEVIEWPRINTER_H diff --git a/product/src/gui/plugin/AlarmWidget/main.cpp b/product/src/gui/plugin/AlarmWidget/main.cpp index a830fc28..cd3812e2 100644 --- a/product/src/gui/plugin/AlarmWidget/main.cpp +++ b/product/src/gui/plugin/AlarmWidget/main.cpp @@ -1,75 +1,75 @@ -#include -#include "CAlarmPlugin.h" -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - //<初始化消息总线 - QStringList arguments=QCoreApplication::arguments(); - std::string name="admin"; - std::string password ="kbdct"; - int group =1; - for(int index(0);indexPermDllInit()) - { - return -1; - } - - if(perm->SysLogin(name, password, group, 12*60*60, "hmi") != 0) - { - return -1; - } - - { - CAlarmPlugin n(NULL, false); - n.initialize(E_Alarm_Dock); - //n.initialize(E_Alarm_Window); - - n.show(); - app.exec(); - } - - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} - +#include +#include "CAlarmPlugin.h" +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + //<初始化消息总线 + QStringList arguments=QCoreApplication::arguments(); + std::string name="admin"; + std::string password ="kbdct"; + int group =1; + for(int index(0);indexPermDllInit()) + { + return -1; + } + + if(perm->SysLogin(name, password, group, 12*60*60, "hmi") != 0) + { + return -1; + } + + { + CAlarmPlugin n(NULL, false); + n.initialize(E_Alarm_Dock); + //n.initialize(E_Alarm_Window); + + n.show(); + app.exec(); + } + + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} + diff --git a/product/src/gui/plugin/AssetWidget/AssetWidget.pro b/product/src/gui/plugin/AssetWidget/AssetWidget.pro index 78ba777c..cc77d109 100644 --- a/product/src/gui/plugin/AssetWidget/AssetWidget.pro +++ b/product/src/gui/plugin/AssetWidget/AssetWidget.pro @@ -1,71 +1,71 @@ -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = AssetWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any Qt feature that has been marked deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if it uses deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - CAssetDataMng.cpp \ - CAssetDelegate.cpp \ - CAssetPluginWidget.cpp \ - CAssetTableModel.cpp \ - CAssetView.cpp \ - CPropertyDialog.cpp \ - CRecordDialog.cpp \ - CRecordPropertyDialog.cpp \ - CRecordTablModel.cpp \ - CWorker.cpp \ - #main.cpp \ - CAssetWidget.cpp \ - CAssetUuid.cpp - -HEADERS += \ - CAssetCommon.h \ - CAssetDataMng.h \ - CAssetDelegate.h \ - CAssetPluginWidget.h \ - CAssetTableModel.h \ - CAssetView.h \ - CAssetWidget.h \ - CPropertyDialog.h \ - CRecordDialog.h \ - CRecordPropertyDialog.h \ - CRecordTablModel.h \ - CWorker.h \ - CAssetUuid.h - -FORMS += \ - CAssetWidget.ui \ - CPropertyDialog.ui \ - CRecordDialog.ui \ - CRecordPropertyDialog.ui - -LIBS += -llog4cplus -lboost_system -lboost_chrono -lboost_filesystem -lprotobuf -lpub_logger_api -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api -ldb_base_api -ldb_api_ex -lmodel_excel - - -win32-msvc* { - LIBS += -lbcrypt -} - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = AssetWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + CAssetDataMng.cpp \ + CAssetDelegate.cpp \ + CAssetPluginWidget.cpp \ + CAssetTableModel.cpp \ + CAssetView.cpp \ + CPropertyDialog.cpp \ + CRecordDialog.cpp \ + CRecordPropertyDialog.cpp \ + CRecordTablModel.cpp \ + CWorker.cpp \ + #main.cpp \ + CAssetWidget.cpp \ + CAssetUuid.cpp + +HEADERS += \ + CAssetCommon.h \ + CAssetDataMng.h \ + CAssetDelegate.h \ + CAssetPluginWidget.h \ + CAssetTableModel.h \ + CAssetView.h \ + CAssetWidget.h \ + CPropertyDialog.h \ + CRecordDialog.h \ + CRecordPropertyDialog.h \ + CRecordTablModel.h \ + CWorker.h \ + CAssetUuid.h + +FORMS += \ + CAssetWidget.ui \ + CPropertyDialog.ui \ + CRecordDialog.ui \ + CRecordPropertyDialog.ui + +LIBS += -llog4cplus -lboost_system -lboost_chrono -lboost_filesystem -lprotobuf -lpub_logger_api -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api -ldb_base_api -ldb_api_ex -lmodel_excel + + +win32-msvc* { + LIBS += -lbcrypt +} + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/AssetWidget/CAssetCommon.h b/product/src/gui/plugin/AssetWidget/CAssetCommon.h index d373be12..f2cc80eb 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetCommon.h +++ b/product/src/gui/plugin/AssetWidget/CAssetCommon.h @@ -1,92 +1,92 @@ -#ifndef CASSETCOMMON_H -#define CASSETCOMMON_H - -#include - -struct AssetInfo -{ - QString id; - QString name; - QString type; - QString param; - qint64 setUpTime; - QString status; - QString contact; - QString backup; - QString dev_group; - double maintain_period; - - AssetInfo(){ - - } -}; - -struct AssetRecord{ - - QString id; - QString dev_id; - QString dev_name; - QString record_name; - QString opt_user; - qint64 startTime; - qint64 endTime; - QString content; - - AssetRecord(){ - - } -}; - -enum EN_TREE_TYPE -{ - EN_TREE_LOC = 1001, - EN_TREE_DEVG = 1002 -}; -enum EN_ASSET_STATUS -{ - EN_ASSET_DISENABLE =0, - EN_ASSET_ENABLE = 1 -}; - -enum AssetColumnHead -{ - ASSET_ID =0, - ASSET_NAME=1, - ASSET_TYPE, - ASSET_PARAM, - ASSET_SETUP, - ASSET_STATUS, - ASSET_CONTACT, - ASSET_PERIOD, - ASSET_BACKUP -}; -enum RecordColumnHead -{ - RECORD_ASSET_NAME = 0, - RECORD_NAME, - RECORD_USER, - RECORD_STARTTIME, - RECORD_ENDTIME, - RECORD_CONTENT -}; - -enum EN_Property_Mode -{ - EN_Property_Add =0, - EN_Property_Edit = 1 -}; -enum EN_Asset_Mode -{ - EN_Asset_Pop =0, - EN_Asset_Window -}; - -enum EN_Period_Type -{ - EN_Period_One_Month = 1, - EN_Period_Three_Month = 3, - EN_Period_Six_Month = 6, - EN_Period_One_Year = 12, - EN_Period_Other = 13 -}; -#endif // CASSETCOMMON_H +#ifndef CASSETCOMMON_H +#define CASSETCOMMON_H + +#include + +struct AssetInfo +{ + QString id; + QString name; + QString type; + QString param; + qint64 setUpTime; + QString status; + QString contact; + QString backup; + QString dev_group; + double maintain_period; + + AssetInfo(){ + + } +}; + +struct AssetRecord{ + + QString id; + QString dev_id; + QString dev_name; + QString record_name; + QString opt_user; + qint64 startTime; + qint64 endTime; + QString content; + + AssetRecord(){ + + } +}; + +enum EN_TREE_TYPE +{ + EN_TREE_LOC = 1001, + EN_TREE_DEVG = 1002 +}; +enum EN_ASSET_STATUS +{ + EN_ASSET_DISENABLE =0, + EN_ASSET_ENABLE = 1 +}; + +enum AssetColumnHead +{ + ASSET_ID =0, + ASSET_NAME=1, + ASSET_TYPE, + ASSET_PARAM, + ASSET_SETUP, + ASSET_STATUS, + ASSET_CONTACT, + ASSET_PERIOD, + ASSET_BACKUP +}; +enum RecordColumnHead +{ + RECORD_ASSET_NAME = 0, + RECORD_NAME, + RECORD_USER, + RECORD_STARTTIME, + RECORD_ENDTIME, + RECORD_CONTENT +}; + +enum EN_Property_Mode +{ + EN_Property_Add =0, + EN_Property_Edit = 1 +}; +enum EN_Asset_Mode +{ + EN_Asset_Pop =0, + EN_Asset_Window +}; + +enum EN_Period_Type +{ + EN_Period_One_Month = 1, + EN_Period_Three_Month = 3, + EN_Period_Six_Month = 6, + EN_Period_One_Year = 12, + EN_Period_Other = 13 +}; +#endif // CASSETCOMMON_H diff --git a/product/src/gui/plugin/AssetWidget/CAssetDataMng.cpp b/product/src/gui/plugin/AssetWidget/CAssetDataMng.cpp index 40983778..61ae03a8 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetDataMng.cpp +++ b/product/src/gui/plugin/AssetWidget/CAssetDataMng.cpp @@ -1,700 +1,700 @@ -#include "CAssetDataMng.h" -#include "Common.h" -#include "pub_logger_api/logger.h" -#include -#include "CAssetUuid.h" - -using namespace kbd_dbms; - -CAssetDataMng *CAssetDataMng::m_pInstance = NULL; - - -CAssetDataMng *CAssetDataMng::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CAssetDataMng(); - } - return m_pInstance; -} - -void CAssetDataMng::destory() -{ - if(m_pWriteDb) - { - m_pWriteDb->close(); - delete m_pWriteDb; - } - m_pWriteDb = NULL; - m_pInstance = NULL; - delete this; -} - -QMap CAssetDataMng::readLocation() -{ - if(!m_pWriteDb->isOpen()) - { - return QMap(); - } - QMap map; - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"); - LOGDEBUG("readLocation():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - int id = query.value(0).toInt(); - QString desc = query.value(1).toString(); - - map.insert(id, desc); - } - return map; -} - -QList CAssetDataMng::readLocationOrder() -{ - if(!m_pWriteDb->isOpen()) - { - return QList(); - } - QList result; - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID from sys_model_location_info order by LOCATION_NO"); - LOGDEBUG("readLocationOrder():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - result.append(query.value(0).toInt()); - } - return result; -} - -QMap CAssetDataMng::readDevg() -{ - QMap devgMap; - if(!m_pWriteDb->isOpen()) - { - return devgMap; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group"); - LOGDEBUG("readDevg():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - devgMap.insert(tag, desc); - } - return devgMap; -} - -QMap CAssetDataMng::readDevgByLoc(int loc) -{ - QMap devgMap; - if(!m_pWriteDb->isOpen()) - { - return devgMap; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group where location_id = %1").arg(loc); - LOGDEBUG("readDevgByLoc():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - devgMap.insert(tag, desc); - } - return devgMap; -} - -QMap CAssetDataMng::readDev() -{ - QMap devMap; - if(!m_pWriteDb->isOpen()) - { - return devMap; - } - QSqlQuery query; - - QString sqlQuery= QString("select DEV_ID,DEV_NAME from asset_info order by SETUP_DATE desc"); - - LOGDEBUG("getAssetInfoByDevg():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString id = query.value(0).toString(); - QString name = query.value(1).toString(); - devMap[id] = name; - } - return devMap; -} - -void CAssetDataMng::readLocDevgMap(QMap &devgMap,QMap > & locDevgMap) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,LOCATION_ID from dev_group"); - LOGDEBUG("readLocDevgMap():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - int loc = query.value(2).toInt(); - QMap >::iterator itor = locDevgMap.find(loc); - if(itor != locDevgMap.end()) - { - itor.value().append(tag); - }else - { - QList devgList; - devgList.append(tag); - locDevgMap[loc] = devgList; - } - devgMap.insert(tag, desc); - } -} - -int CAssetDataMng::readLocIdByDevg(const QString &devg,int &loc) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID from dev_group where TAG_NAME='%1'").arg(devg); - LOGDEBUG("readLocDevgMap():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - loc = query.value(0).toInt(); - return kbdSuccess; - } - return kbdFailed; -} - -QList CAssetDataMng::getAssetInfoByDevg(const QStringList &devgList) -{ - QList assetList; - if(!m_pWriteDb->isOpen()) - { - return assetList; - } - QSqlQuery query; - QString condition = buildDevgCon(devgList); - QString sqlQuery; - if(condition.isEmpty()) - { - return assetList; - }else - { - sqlQuery= QString("select DEV_ID,DEV_NAME,DEV_TYPE,DEV_PARAM,SETUP_DATE,DEV_STATUS,CONTACT,BACKUP,DEV_GROUP,MAINTAIN_PERIOD from asset_info %1 order by SETUP_DATE desc").arg(condition); - } - LOGDEBUG("getAssetInfoByDevg():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - AssetInfo info; - info.id = query.value(0).toString(); - info.name = query.value(1).toString(); - info.type = query.value(2).toString(); - info.param = query.value(3).toString(); - info.setUpTime = query.value(4).toLongLong(); - info.status = query.value(5).toString(); - info.contact = query.value(6).toString(); - info.backup = query.value(7).toString(); - info.dev_group = query.value(8).toString(); - info.maintain_period = query.value(9).toDouble(); - assetList.append(info); - } - return assetList; -} - -QList CAssetDataMng::getRecordInfoByDevId(const QString &devId) -{ - QList recordList; - if(!m_pWriteDb->isOpen()) - { - return recordList; - } - QSqlQuery query; - - //QString sqlQuery = QString("select RECORD_ID,dev_id,RECORD_NAME,OPT_USER,START_TIME,END_TIME,CONTENT from asset_records where dev_id='%1' order by START_TIME desc").arg(devTag); - QString sqlQuery = QString("select %1.RECORD_ID,%1.DEV_ID,%2.DEV_NAME,%1.RECORD_NAME,%1.OPT_USER,%1.START_TIME,%1.END_TIME,%1.CONTENT from %1 left join %2 on %1.DEV_ID=%2.DEV_ID where %1.DEV_ID='%3' order by %1.START_TIME desc").arg("asset_records").arg("asset_info").arg(devId); - - LOGDEBUG("getRecordInfoByDevTag():sql[%s]",sqlQuery.toStdString().c_str()); - qDebug()<execute(sqlQuery, query); - - while(query.next()) - { - AssetRecord info; - info.id = query.value(0).toString(); - info.dev_id = query.value(1).toString(); - info.dev_name = query.value(2).toString(); - info.record_name = query.value(3).toString(); - info.opt_user = query.value(4).toString(); - info.startTime = query.value(5).toLongLong(); - info.endTime = query.value(6).toLongLong(); - info.content = query.value(7).toString(); - recordList.append(info); - } - return recordList; -} - -QList CAssetDataMng::getRecordInfoByDevId(const QList &idList) -{ - QList recordList; - if(!m_pWriteDb->isOpen()) - { - return recordList; - } - - QSqlQuery query; - - QString condition = buildDevCon(idList); - QString sqlQuery; - if(condition.isEmpty()) - { - return recordList; - }else - { - sqlQuery= QString("select %1.RECORD_ID,%1.dev_id,%2.DEV_NAME,%1.RECORD_NAME,%1.OPT_USER,%1.START_TIME,%1.END_TIME,%1.CONTENT from %1 left join %2 on %1.dev_id=%2.dev_id %3").arg("asset_records").arg("asset_info").arg(condition); - } - qDebug()<execute(sqlQuery, query); - - while(query.next()) - { - AssetRecord info; - info.id = query.value(0).toString(); - info.dev_id = query.value(1).toString(); - info.dev_name = query.value(2).toString(); - info.record_name = query.value(3).toString(); - info.opt_user = query.value(4).toString(); - info.startTime = query.value(5).toLongLong(); - info.endTime = query.value(6).toLongLong(); - info.content = query.value(7).toString(); - recordList.append(info); - } - return recordList; -} - -QList CAssetDataMng::getStatus() -{ - QList statusList; - if(!m_pWriteDb->isOpen()) - { - return statusList; - } - QSqlQuery query; - - QString sqlQuery = QString("select DISTINCT DEV_STATUS from asset_info "); - LOGDEBUG("getStatus():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString status; - status = query.value(0).toString(); - statusList.append(status); - } - return statusList; -} - -QString CAssetDataMng::buildDevgCon(const QStringList &devgList) -{ - QString text = QString(); - for(int index(0);index &idList) -{ - QString text = QString(); - for(int index(0);indexisOpen()) - { - m_error = m_pWriteDb->getLastErrorString(); - return kbdFailed; - } - - QString sqlQuery= QString("insert into asset_info(dev_id,dev_name,dev_type,dev_param,setup_date,dev_status,contact,backup,dev_group,maintain_period) values('%1','%2','%3','%4',%5,'%6','%7','%8','%9',%10)").arg(getRandomId()).arg(info.name).arg(info.type).arg(info.param).arg(info.setUpTime) - .arg(info.status).arg(info.contact).arg(info.backup).arg(info.dev_group).arg(info.maintain_period); - LOGDEBUG("addAsset():sql[%s]",sqlQuery.toStdString().c_str()); - if(m_pWriteDb->execute(sqlQuery) == false) - { - m_error = m_pWriteDb->getLastErrorString(); - return kbdFailed; - } - return kbdSuccess; -} - -void CAssetDataMng::importAsset(const QMap &infoMap,QString &mess) -{ - if(infoMap.isEmpty()) - { - mess = tr("需要导入的资产信息为空"); - return ; - } - - if(!m_pWriteDb->isOpen()) - { - mess = tr("数据库打开失败,导入资产信息失败"); - m_error = m_pWriteDb->getLastErrorString(); - return ; - } - QStringList assetIdList = getAllAssetIdList(); - QList assetInfoList; - - if(!assetIdList.isEmpty()) - { - QMap::const_iterator it =infoMap.begin(); - while (it != infoMap.end()) { - if(!assetIdList.contains(it.key())) - { - assetInfoList.append(it.value()); - } - it++; - } - }else - { - assetInfoList = infoMap.values(); - } - - if(assetInfoList.isEmpty()) - { - mess = tr("满足条件的导入条数为0"); - return ; - } - - QString sqlQuery = QString("insert into asset_info(dev_id,dev_name,dev_type,dev_param,setup_date,dev_status,contact,backup,dev_group,maintain_period) values"); - for(int index(0);indexexecute(sqlQuery) == false) - { - mess = tr("执行插入语句失败,导入资产信息失败"); - m_error = m_pWriteDb->getLastErrorString(); - return ; - }else - { - mess = tr("一共%1条,成功导入%2条").arg(QString::number(infoMap.count())).arg(QString::number(assetInfoList.count())); - return ; - } -} - -int CAssetDataMng::updateAsset(const AssetInfo &info) -{ - if(!m_pWriteDb->isOpen()) - { - m_error = m_pWriteDb->getLastErrorString(); - return kbdFailed; - } - QSqlQuery query; - QString sqlQuery =QString("update asset_info set dev_name='%1',dev_type='%2',dev_param='%3',setup_date=%4,dev_status='%5',contact='%6',backup='%7',dev_group='%8',maintain_period= %9 " - "where dev_id = '%10'").arg(info.name).arg(info.type).arg(info.param).arg(info.setUpTime) - .arg(info.status).arg(info.contact).arg(info.backup).arg(info.dev_group).arg(info.maintain_period).arg(info.id); - LOGDEBUG("updateAsset():sql[%s]",sqlQuery.toStdString().c_str()); - if(m_pWriteDb->execute(sqlQuery, query) == false) - { - m_error = m_pWriteDb->getLastErrorString(); - return kbdFailed; - } - return kbdSuccess; -} - -int CAssetDataMng::delAsset(const QList &idList) -{ - if(!m_pWriteDb->isOpen()) - { - m_error = m_pWriteDb->getLastErrorString(); - return kbdFailed; - } - if(idList.isEmpty()) - { - return kbdSuccess; - } - if(m_pWriteDb->transaction() == false) - { - m_error = m_pWriteDb->getLastErrorString(); - return kbdFailed; - } - QString con = QString("dev_id in ("); - for(int index(0);indexexecute(sqlQuery); - sqlQuery = QString("delete from asset_records where %1").arg(con); - LOGDEBUG("delAsset():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery); - if(m_pWriteDb->commit() == false) - { - m_error = m_pWriteDb->getLastErrorString(); - m_pWriteDb->rollback(); - return kbdFailed; - } - return kbdSuccess; -} - -int CAssetDataMng::addRecord(const AssetRecord &info) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QString sqlQuery= QString("insert into asset_records(record_id,dev_id,record_name,opt_user,start_time,end_time,content) values('%1','%2','%3','%4',%5,%6,'%7')").arg(getRandomId()).arg(info.dev_id).arg(info.record_name).arg(info.opt_user).arg(info.startTime) - .arg(info.endTime).arg(info.content); - LOGDEBUG("addRecord():sql[%s]",sqlQuery.toStdString().c_str()); - if(m_pWriteDb->execute(sqlQuery) == false) - { - m_error = m_pWriteDb->getLastErrorString(); - return kbdFailed; - } - return kbdSuccess; -} - -void CAssetDataMng::importRecord(const QMap &infoMap, QString &mess) -{ - if(infoMap.isEmpty()) - { - mess = tr("需要导入的维护记录为空"); - return ; - } - if(!m_pWriteDb->isOpen()) - { - mess = tr("数据库打开失败,导入维护记录失败"); - m_error = m_pWriteDb->getLastErrorString(); - return ; - } - QStringList recordIdList = getAllRecordIdList(); - QList recordInfoList; - if(!recordIdList.isEmpty()) - { - QMap::const_iterator it =infoMap.begin(); - while (it != infoMap.end()) { - if(!recordIdList.contains(it.key())) - { - recordInfoList.append(it.value()); - } - it++; - } - }else - { - recordInfoList = infoMap.values(); - } - if(recordInfoList.isEmpty()) - { - mess = tr("满足条件的导入条数为0"); - return ; - } - QString sqlQuery = QString("insert into asset_records(record_id,dev_id,record_name,opt_user,start_time,end_time,content) values"); - for(int index(0);indexexecute(sqlQuery) == false) - { - mess = tr("执行插入语句失败,导入维护记录失败"); - m_error = m_pWriteDb->getLastErrorString(); - return ; - }else - { - mess = tr("一共%1条,成功导入%2条").arg(QString::number(infoMap.count())).arg(QString::number(recordInfoList.count())); - return ; - } -} - -int CAssetDataMng::updateRecord(const AssetRecord &info) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QSqlQuery query; - QString sqlQuery =QString("update asset_records set dev_id='%1',record_name='%2',opt_user='%3',start_time=%4,end_time=%5,content='%6' " - "where record_id = '%7'").arg(info.dev_id).arg(info.record_name).arg(info.opt_user).arg(info.startTime) - .arg(info.endTime).arg(info.content).arg(info.id); - LOGDEBUG("updateRecord():sql[%s]",sqlQuery.toStdString().c_str()); - if(m_pWriteDb->execute(sqlQuery, query) == false) - { - return kbdFailed; - } - return kbdSuccess; -} - -int CAssetDataMng::delRecord(const QList &intList) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - if(intList.isEmpty()) - { - return kbdSuccess; - } - QString con = QString("record_id in ("); - for(int index(0);indexexecute(sqlQuery); - return kbdSuccess; -} - -int CAssetDataMng::getCount() -{ - return m_referenceCount; -} - -void CAssetDataMng::addCount() -{ - m_referenceCount++; -} - -void CAssetDataMng::subCount() -{ - m_referenceCount--; -} - -QString CAssetDataMng::getError() -{ - return m_error; -} - -QString CAssetDataMng::getRandomId() -{ - CAssetUuid dev_uuid; - return dev_uuid.getAssetUuid(); -} - -CAssetDataMng::CAssetDataMng(): - m_referenceCount(0) -{ - m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); - m_pWriteDb->open(); -} - -QStringList CAssetDataMng::getAllAssetIdList() -{ - QStringList assetIdList; - if(!m_pWriteDb->isOpen()) - { - return assetIdList; - } - QSqlQuery query; - - QString sqlQuery = QString("select DEV_ID from asset_info"); - - LOGDEBUG("getAllAssetId():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - assetIdList.append(query.value(0).toString()); - } - return assetIdList; -} - -QStringList CAssetDataMng::getAllRecordIdList() -{ - QStringList recordIdList; - if(!m_pWriteDb->isOpen()) - { - return recordIdList; - } - QSqlQuery query; - - QString sqlQuery = QString("select RECORD_ID from asset_records"); - - LOGDEBUG("getAllAssetId():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - recordIdList.append(query.value(0).toString()); - } - return recordIdList; -} +#include "CAssetDataMng.h" +#include "Common.h" +#include "pub_logger_api/logger.h" +#include +#include "CAssetUuid.h" + +using namespace kbd_dbms; + +CAssetDataMng *CAssetDataMng::m_pInstance = NULL; + + +CAssetDataMng *CAssetDataMng::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAssetDataMng(); + } + return m_pInstance; +} + +void CAssetDataMng::destory() +{ + if(m_pWriteDb) + { + m_pWriteDb->close(); + delete m_pWriteDb; + } + m_pWriteDb = NULL; + m_pInstance = NULL; + delete this; +} + +QMap CAssetDataMng::readLocation() +{ + if(!m_pWriteDb->isOpen()) + { + return QMap(); + } + QMap map; + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"); + LOGDEBUG("readLocation():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString desc = query.value(1).toString(); + + map.insert(id, desc); + } + return map; +} + +QList CAssetDataMng::readLocationOrder() +{ + if(!m_pWriteDb->isOpen()) + { + return QList(); + } + QList result; + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID from sys_model_location_info order by LOCATION_NO"); + LOGDEBUG("readLocationOrder():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + result.append(query.value(0).toInt()); + } + return result; +} + +QMap CAssetDataMng::readDevg() +{ + QMap devgMap; + if(!m_pWriteDb->isOpen()) + { + return devgMap; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group"); + LOGDEBUG("readDevg():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + devgMap.insert(tag, desc); + } + return devgMap; +} + +QMap CAssetDataMng::readDevgByLoc(int loc) +{ + QMap devgMap; + if(!m_pWriteDb->isOpen()) + { + return devgMap; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group where location_id = %1").arg(loc); + LOGDEBUG("readDevgByLoc():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + devgMap.insert(tag, desc); + } + return devgMap; +} + +QMap CAssetDataMng::readDev() +{ + QMap devMap; + if(!m_pWriteDb->isOpen()) + { + return devMap; + } + QSqlQuery query; + + QString sqlQuery= QString("select DEV_ID,DEV_NAME from asset_info order by SETUP_DATE desc"); + + LOGDEBUG("getAssetInfoByDevg():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString id = query.value(0).toString(); + QString name = query.value(1).toString(); + devMap[id] = name; + } + return devMap; +} + +void CAssetDataMng::readLocDevgMap(QMap &devgMap,QMap > & locDevgMap) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,LOCATION_ID from dev_group"); + LOGDEBUG("readLocDevgMap():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + int loc = query.value(2).toInt(); + QMap >::iterator itor = locDevgMap.find(loc); + if(itor != locDevgMap.end()) + { + itor.value().append(tag); + }else + { + QList devgList; + devgList.append(tag); + locDevgMap[loc] = devgList; + } + devgMap.insert(tag, desc); + } +} + +int CAssetDataMng::readLocIdByDevg(const QString &devg,int &loc) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID from dev_group where TAG_NAME='%1'").arg(devg); + LOGDEBUG("readLocDevgMap():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + loc = query.value(0).toInt(); + return kbdSuccess; + } + return kbdFailed; +} + +QList CAssetDataMng::getAssetInfoByDevg(const QStringList &devgList) +{ + QList assetList; + if(!m_pWriteDb->isOpen()) + { + return assetList; + } + QSqlQuery query; + QString condition = buildDevgCon(devgList); + QString sqlQuery; + if(condition.isEmpty()) + { + return assetList; + }else + { + sqlQuery= QString("select DEV_ID,DEV_NAME,DEV_TYPE,DEV_PARAM,SETUP_DATE,DEV_STATUS,CONTACT,BACKUP,DEV_GROUP,MAINTAIN_PERIOD from asset_info %1 order by SETUP_DATE desc").arg(condition); + } + LOGDEBUG("getAssetInfoByDevg():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + AssetInfo info; + info.id = query.value(0).toString(); + info.name = query.value(1).toString(); + info.type = query.value(2).toString(); + info.param = query.value(3).toString(); + info.setUpTime = query.value(4).toLongLong(); + info.status = query.value(5).toString(); + info.contact = query.value(6).toString(); + info.backup = query.value(7).toString(); + info.dev_group = query.value(8).toString(); + info.maintain_period = query.value(9).toDouble(); + assetList.append(info); + } + return assetList; +} + +QList CAssetDataMng::getRecordInfoByDevId(const QString &devId) +{ + QList recordList; + if(!m_pWriteDb->isOpen()) + { + return recordList; + } + QSqlQuery query; + + //QString sqlQuery = QString("select RECORD_ID,dev_id,RECORD_NAME,OPT_USER,START_TIME,END_TIME,CONTENT from asset_records where dev_id='%1' order by START_TIME desc").arg(devTag); + QString sqlQuery = QString("select %1.RECORD_ID,%1.DEV_ID,%2.DEV_NAME,%1.RECORD_NAME,%1.OPT_USER,%1.START_TIME,%1.END_TIME,%1.CONTENT from %1 left join %2 on %1.DEV_ID=%2.DEV_ID where %1.DEV_ID='%3' order by %1.START_TIME desc").arg("asset_records").arg("asset_info").arg(devId); + + LOGDEBUG("getRecordInfoByDevTag():sql[%s]",sqlQuery.toStdString().c_str()); + qDebug()<execute(sqlQuery, query); + + while(query.next()) + { + AssetRecord info; + info.id = query.value(0).toString(); + info.dev_id = query.value(1).toString(); + info.dev_name = query.value(2).toString(); + info.record_name = query.value(3).toString(); + info.opt_user = query.value(4).toString(); + info.startTime = query.value(5).toLongLong(); + info.endTime = query.value(6).toLongLong(); + info.content = query.value(7).toString(); + recordList.append(info); + } + return recordList; +} + +QList CAssetDataMng::getRecordInfoByDevId(const QList &idList) +{ + QList recordList; + if(!m_pWriteDb->isOpen()) + { + return recordList; + } + + QSqlQuery query; + + QString condition = buildDevCon(idList); + QString sqlQuery; + if(condition.isEmpty()) + { + return recordList; + }else + { + sqlQuery= QString("select %1.RECORD_ID,%1.dev_id,%2.DEV_NAME,%1.RECORD_NAME,%1.OPT_USER,%1.START_TIME,%1.END_TIME,%1.CONTENT from %1 left join %2 on %1.dev_id=%2.dev_id %3").arg("asset_records").arg("asset_info").arg(condition); + } + qDebug()<execute(sqlQuery, query); + + while(query.next()) + { + AssetRecord info; + info.id = query.value(0).toString(); + info.dev_id = query.value(1).toString(); + info.dev_name = query.value(2).toString(); + info.record_name = query.value(3).toString(); + info.opt_user = query.value(4).toString(); + info.startTime = query.value(5).toLongLong(); + info.endTime = query.value(6).toLongLong(); + info.content = query.value(7).toString(); + recordList.append(info); + } + return recordList; +} + +QList CAssetDataMng::getStatus() +{ + QList statusList; + if(!m_pWriteDb->isOpen()) + { + return statusList; + } + QSqlQuery query; + + QString sqlQuery = QString("select DISTINCT DEV_STATUS from asset_info "); + LOGDEBUG("getStatus():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString status; + status = query.value(0).toString(); + statusList.append(status); + } + return statusList; +} + +QString CAssetDataMng::buildDevgCon(const QStringList &devgList) +{ + QString text = QString(); + for(int index(0);index &idList) +{ + QString text = QString(); + for(int index(0);indexisOpen()) + { + m_error = m_pWriteDb->getLastErrorString(); + return kbdFailed; + } + + QString sqlQuery= QString("insert into asset_info(dev_id,dev_name,dev_type,dev_param,setup_date,dev_status,contact,backup,dev_group,maintain_period) values('%1','%2','%3','%4',%5,'%6','%7','%8','%9',%10)").arg(getRandomId()).arg(info.name).arg(info.type).arg(info.param).arg(info.setUpTime) + .arg(info.status).arg(info.contact).arg(info.backup).arg(info.dev_group).arg(info.maintain_period); + LOGDEBUG("addAsset():sql[%s]",sqlQuery.toStdString().c_str()); + if(m_pWriteDb->execute(sqlQuery) == false) + { + m_error = m_pWriteDb->getLastErrorString(); + return kbdFailed; + } + return kbdSuccess; +} + +void CAssetDataMng::importAsset(const QMap &infoMap,QString &mess) +{ + if(infoMap.isEmpty()) + { + mess = tr("需要导入的资产信息为空"); + return ; + } + + if(!m_pWriteDb->isOpen()) + { + mess = tr("数据库打开失败,导入资产信息失败"); + m_error = m_pWriteDb->getLastErrorString(); + return ; + } + QStringList assetIdList = getAllAssetIdList(); + QList assetInfoList; + + if(!assetIdList.isEmpty()) + { + QMap::const_iterator it =infoMap.begin(); + while (it != infoMap.end()) { + if(!assetIdList.contains(it.key())) + { + assetInfoList.append(it.value()); + } + it++; + } + }else + { + assetInfoList = infoMap.values(); + } + + if(assetInfoList.isEmpty()) + { + mess = tr("满足条件的导入条数为0"); + return ; + } + + QString sqlQuery = QString("insert into asset_info(dev_id,dev_name,dev_type,dev_param,setup_date,dev_status,contact,backup,dev_group,maintain_period) values"); + for(int index(0);indexexecute(sqlQuery) == false) + { + mess = tr("执行插入语句失败,导入资产信息失败"); + m_error = m_pWriteDb->getLastErrorString(); + return ; + }else + { + mess = tr("一共%1条,成功导入%2条").arg(QString::number(infoMap.count())).arg(QString::number(assetInfoList.count())); + return ; + } +} + +int CAssetDataMng::updateAsset(const AssetInfo &info) +{ + if(!m_pWriteDb->isOpen()) + { + m_error = m_pWriteDb->getLastErrorString(); + return kbdFailed; + } + QSqlQuery query; + QString sqlQuery =QString("update asset_info set dev_name='%1',dev_type='%2',dev_param='%3',setup_date=%4,dev_status='%5',contact='%6',backup='%7',dev_group='%8',maintain_period= %9 " + "where dev_id = '%10'").arg(info.name).arg(info.type).arg(info.param).arg(info.setUpTime) + .arg(info.status).arg(info.contact).arg(info.backup).arg(info.dev_group).arg(info.maintain_period).arg(info.id); + LOGDEBUG("updateAsset():sql[%s]",sqlQuery.toStdString().c_str()); + if(m_pWriteDb->execute(sqlQuery, query) == false) + { + m_error = m_pWriteDb->getLastErrorString(); + return kbdFailed; + } + return kbdSuccess; +} + +int CAssetDataMng::delAsset(const QList &idList) +{ + if(!m_pWriteDb->isOpen()) + { + m_error = m_pWriteDb->getLastErrorString(); + return kbdFailed; + } + if(idList.isEmpty()) + { + return kbdSuccess; + } + if(m_pWriteDb->transaction() == false) + { + m_error = m_pWriteDb->getLastErrorString(); + return kbdFailed; + } + QString con = QString("dev_id in ("); + for(int index(0);indexexecute(sqlQuery); + sqlQuery = QString("delete from asset_records where %1").arg(con); + LOGDEBUG("delAsset():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery); + if(m_pWriteDb->commit() == false) + { + m_error = m_pWriteDb->getLastErrorString(); + m_pWriteDb->rollback(); + return kbdFailed; + } + return kbdSuccess; +} + +int CAssetDataMng::addRecord(const AssetRecord &info) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QString sqlQuery= QString("insert into asset_records(record_id,dev_id,record_name,opt_user,start_time,end_time,content) values('%1','%2','%3','%4',%5,%6,'%7')").arg(getRandomId()).arg(info.dev_id).arg(info.record_name).arg(info.opt_user).arg(info.startTime) + .arg(info.endTime).arg(info.content); + LOGDEBUG("addRecord():sql[%s]",sqlQuery.toStdString().c_str()); + if(m_pWriteDb->execute(sqlQuery) == false) + { + m_error = m_pWriteDb->getLastErrorString(); + return kbdFailed; + } + return kbdSuccess; +} + +void CAssetDataMng::importRecord(const QMap &infoMap, QString &mess) +{ + if(infoMap.isEmpty()) + { + mess = tr("需要导入的维护记录为空"); + return ; + } + if(!m_pWriteDb->isOpen()) + { + mess = tr("数据库打开失败,导入维护记录失败"); + m_error = m_pWriteDb->getLastErrorString(); + return ; + } + QStringList recordIdList = getAllRecordIdList(); + QList recordInfoList; + if(!recordIdList.isEmpty()) + { + QMap::const_iterator it =infoMap.begin(); + while (it != infoMap.end()) { + if(!recordIdList.contains(it.key())) + { + recordInfoList.append(it.value()); + } + it++; + } + }else + { + recordInfoList = infoMap.values(); + } + if(recordInfoList.isEmpty()) + { + mess = tr("满足条件的导入条数为0"); + return ; + } + QString sqlQuery = QString("insert into asset_records(record_id,dev_id,record_name,opt_user,start_time,end_time,content) values"); + for(int index(0);indexexecute(sqlQuery) == false) + { + mess = tr("执行插入语句失败,导入维护记录失败"); + m_error = m_pWriteDb->getLastErrorString(); + return ; + }else + { + mess = tr("一共%1条,成功导入%2条").arg(QString::number(infoMap.count())).arg(QString::number(recordInfoList.count())); + return ; + } +} + +int CAssetDataMng::updateRecord(const AssetRecord &info) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QSqlQuery query; + QString sqlQuery =QString("update asset_records set dev_id='%1',record_name='%2',opt_user='%3',start_time=%4,end_time=%5,content='%6' " + "where record_id = '%7'").arg(info.dev_id).arg(info.record_name).arg(info.opt_user).arg(info.startTime) + .arg(info.endTime).arg(info.content).arg(info.id); + LOGDEBUG("updateRecord():sql[%s]",sqlQuery.toStdString().c_str()); + if(m_pWriteDb->execute(sqlQuery, query) == false) + { + return kbdFailed; + } + return kbdSuccess; +} + +int CAssetDataMng::delRecord(const QList &intList) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + if(intList.isEmpty()) + { + return kbdSuccess; + } + QString con = QString("record_id in ("); + for(int index(0);indexexecute(sqlQuery); + return kbdSuccess; +} + +int CAssetDataMng::getCount() +{ + return m_referenceCount; +} + +void CAssetDataMng::addCount() +{ + m_referenceCount++; +} + +void CAssetDataMng::subCount() +{ + m_referenceCount--; +} + +QString CAssetDataMng::getError() +{ + return m_error; +} + +QString CAssetDataMng::getRandomId() +{ + CAssetUuid dev_uuid; + return dev_uuid.getAssetUuid(); +} + +CAssetDataMng::CAssetDataMng(): + m_referenceCount(0) +{ + m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); + m_pWriteDb->open(); +} + +QStringList CAssetDataMng::getAllAssetIdList() +{ + QStringList assetIdList; + if(!m_pWriteDb->isOpen()) + { + return assetIdList; + } + QSqlQuery query; + + QString sqlQuery = QString("select DEV_ID from asset_info"); + + LOGDEBUG("getAllAssetId():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + assetIdList.append(query.value(0).toString()); + } + return assetIdList; +} + +QStringList CAssetDataMng::getAllRecordIdList() +{ + QStringList recordIdList; + if(!m_pWriteDb->isOpen()) + { + return recordIdList; + } + QSqlQuery query; + + QString sqlQuery = QString("select RECORD_ID from asset_records"); + + LOGDEBUG("getAllAssetId():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + recordIdList.append(query.value(0).toString()); + } + return recordIdList; +} diff --git a/product/src/gui/plugin/AssetWidget/CAssetDataMng.h b/product/src/gui/plugin/AssetWidget/CAssetDataMng.h index 64524136..2a9e438f 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetDataMng.h +++ b/product/src/gui/plugin/AssetWidget/CAssetDataMng.h @@ -1,78 +1,78 @@ -#ifndef CASSETDATAMNG_H -#define CASSETDATAMNG_H - -#include "db_api_ex/CDbApi.h" -#include "CAssetCommon.h" -#include -#include - -class CAssetDataMng :public QObject -{ -public: - static CAssetDataMng *instance(); - - void destory(); - - QMap readLocation(); - - QList readLocationOrder(); - - QMap readDevg(); - - QMap readDevgByLoc(int loc); - - QMap readDev(); - - void readLocDevgMap(QMap &devgMap,QMap > & locDevgMap); - - int readLocIdByDevg(const QString &devg, int &loc); - - QList getAssetInfoByDevg(const QStringList &devgList); - QList getRecordInfoByDevId(const QString &devId); - QList getRecordInfoByDevId(const QList &idList); - - QList getStatus(); - QString buildDevgCon(const QStringList &devgList); - QString buildDevCon(const QList &idList); - - int addAsset(const AssetInfo & info); - - void importAsset(const QMap &infoMap, QString &mess); - - int updateAsset(const AssetInfo & info); - - int delAsset(const QList &idList); - - int addRecord(const AssetRecord & info); - - void importRecord(const QMap &infoMap, QString &mess); - - int updateRecord(const AssetRecord & info); - int delRecord(const QList &intList); - - int getCount(); - - void addCount(); - - void subCount(); - - QString getError(); - QString getRandomId(); -private: - CAssetDataMng(); - - QStringList getAllAssetIdList(); - - QStringList getAllRecordIdList(); - -private: - static CAssetDataMng * m_pInstance; - - kbd_dbms::CDbApi *m_pWriteDb; - - int m_referenceCount; - - QString m_error; -}; - -#endif // CASSETDATAMNG_H +#ifndef CASSETDATAMNG_H +#define CASSETDATAMNG_H + +#include "db_api_ex/CDbApi.h" +#include "CAssetCommon.h" +#include +#include + +class CAssetDataMng :public QObject +{ +public: + static CAssetDataMng *instance(); + + void destory(); + + QMap readLocation(); + + QList readLocationOrder(); + + QMap readDevg(); + + QMap readDevgByLoc(int loc); + + QMap readDev(); + + void readLocDevgMap(QMap &devgMap,QMap > & locDevgMap); + + int readLocIdByDevg(const QString &devg, int &loc); + + QList getAssetInfoByDevg(const QStringList &devgList); + QList getRecordInfoByDevId(const QString &devId); + QList getRecordInfoByDevId(const QList &idList); + + QList getStatus(); + QString buildDevgCon(const QStringList &devgList); + QString buildDevCon(const QList &idList); + + int addAsset(const AssetInfo & info); + + void importAsset(const QMap &infoMap, QString &mess); + + int updateAsset(const AssetInfo & info); + + int delAsset(const QList &idList); + + int addRecord(const AssetRecord & info); + + void importRecord(const QMap &infoMap, QString &mess); + + int updateRecord(const AssetRecord & info); + int delRecord(const QList &intList); + + int getCount(); + + void addCount(); + + void subCount(); + + QString getError(); + QString getRandomId(); +private: + CAssetDataMng(); + + QStringList getAllAssetIdList(); + + QStringList getAllRecordIdList(); + +private: + static CAssetDataMng * m_pInstance; + + kbd_dbms::CDbApi *m_pWriteDb; + + int m_referenceCount; + + QString m_error; +}; + +#endif // CASSETDATAMNG_H diff --git a/product/src/gui/plugin/AssetWidget/CAssetDelegate.cpp b/product/src/gui/plugin/AssetWidget/CAssetDelegate.cpp index faae520c..677d962f 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetDelegate.cpp +++ b/product/src/gui/plugin/AssetWidget/CAssetDelegate.cpp @@ -1,86 +1,86 @@ -#include "CAssetDelegate.h" -#include -#include -#include -#include "CAssetTableModel.h" -#include "Common.h" -#include "pub_utility_api/FileStyle.h" -#include "pub_utility_api/FileUtil.h" -CAssetDelegate::CAssetDelegate(CAssetTableModel *model, QObject *parent) - :QStyledItemDelegate(parent), - m_pModel(model), - style(QString()) -{ - style = QString::fromStdString(kbd_public::CFileStyle::getCurStyle()) ; -} - -void CAssetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - painter->save(); - if(style != "light") - { - if(option.state & QStyle::State_Selected){ - QColor penColor(2,239,239); - QColor fillColor(19,74,114); - painter->setPen(penColor); - painter->fillRect(option.rect,fillColor); - } - }else - { - if(option.state & QStyle::State_Selected){ - painter->fillRect(option.rect,option.palette.highlight()); - } - } - - painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); - painter->restore(); - - if( ASSET_BACKUP== index.column()) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); - //QString file = "../../common/resource/zh/gui/icon/asset/record.png"; - QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/asset/record.png").c_str(); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(file); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } -} - -bool CAssetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - if(!index.isValid()) - { - return false; - } - if(index.column() != ASSET_BACKUP) - { - return false; - } - AssetInfo info; - if(m_pModel->getAssetInfo(index,info) != kbdSuccess) - { - return false; - } - QMouseEvent *mouseEvent = static_cast(event); - - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - emit sigOpenAssetRecord(info); - } - } - - return QStyledItemDelegate::editorEvent(event, model, option, index); -} +#include "CAssetDelegate.h" +#include +#include +#include +#include "CAssetTableModel.h" +#include "Common.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_utility_api/FileUtil.h" +CAssetDelegate::CAssetDelegate(CAssetTableModel *model, QObject *parent) + :QStyledItemDelegate(parent), + m_pModel(model), + style(QString()) +{ + style = QString::fromStdString(kbd_public::CFileStyle::getCurStyle()) ; +} + +void CAssetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + painter->save(); + if(style != "light") + { + if(option.state & QStyle::State_Selected){ + QColor penColor(2,239,239); + QColor fillColor(19,74,114); + painter->setPen(penColor); + painter->fillRect(option.rect,fillColor); + } + }else + { + if(option.state & QStyle::State_Selected){ + painter->fillRect(option.rect,option.palette.highlight()); + } + } + + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + + if( ASSET_BACKUP== index.column()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + //QString file = "../../common/resource/zh/gui/icon/asset/record.png"; + QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/asset/record.png").c_str(); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } +} + +bool CAssetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(index.column() != ASSET_BACKUP) + { + return false; + } + AssetInfo info; + if(m_pModel->getAssetInfo(index,info) != kbdSuccess) + { + return false; + } + QMouseEvent *mouseEvent = static_cast(event); + + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + emit sigOpenAssetRecord(info); + } + } + + return QStyledItemDelegate::editorEvent(event, model, option, index); +} diff --git a/product/src/gui/plugin/AssetWidget/CAssetDelegate.h b/product/src/gui/plugin/AssetWidget/CAssetDelegate.h index 46e16267..fe1af6e9 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetDelegate.h +++ b/product/src/gui/plugin/AssetWidget/CAssetDelegate.h @@ -1,30 +1,30 @@ -#ifndef CASSETDELEGATE_H -#define CASSETDELEGATE_H - -#include -#include "CAssetCommon.h" - -class CAssetTableModel; - -class CAssetDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CAssetDelegate(CAssetTableModel *model, QObject *parent = 0); - - - void paint(QPainter *painter, - const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; -protected: - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; - -signals: - void sigOpenAssetRecord(const AssetInfo &info); - -private: - CAssetTableModel * m_pModel; - QString style; -}; - -#endif // CASSETDELEGATE_H +#ifndef CASSETDELEGATE_H +#define CASSETDELEGATE_H + +#include +#include "CAssetCommon.h" + +class CAssetTableModel; + +class CAssetDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CAssetDelegate(CAssetTableModel *model, QObject *parent = 0); + + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; +protected: + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; + +signals: + void sigOpenAssetRecord(const AssetInfo &info); + +private: + CAssetTableModel * m_pModel; + QString style; +}; + +#endif // CASSETDELEGATE_H diff --git a/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.cpp b/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.cpp index d9765ba8..39a0bc28 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.cpp +++ b/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.cpp @@ -1,29 +1,29 @@ -#include "CAssetPluginWidget.h" -#include -#include "CAssetWidget.h" -#include "pub_logger_api/logger.h" - - -CAssetPluginWidget::CAssetPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CAssetPluginWidget::~CAssetPluginWidget() -{ - -} - -bool CAssetPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CAssetWidget *pWidget = new CAssetWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *alarmWidget = (IPluginWidget *)pWidget; - return true; -} - -void CAssetPluginWidget::release() -{ - -} +#include "CAssetPluginWidget.h" +#include +#include "CAssetWidget.h" +#include "pub_logger_api/logger.h" + + +CAssetPluginWidget::CAssetPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CAssetPluginWidget::~CAssetPluginWidget() +{ + +} + +bool CAssetPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CAssetWidget *pWidget = new CAssetWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + return true; +} + +void CAssetPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.h b/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.h index a24b1a61..f6c102a3 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.h +++ b/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CASSETPLUGINWIDGET_H -#define CASSETPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CAssetPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CAssetPluginWidget(QObject *parent = 0); - ~CAssetPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); - void release(); -}; - -#endif // CASSETPLUGINWIDGET_H +#ifndef CASSETPLUGINWIDGET_H +#define CASSETPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CAssetPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CAssetPluginWidget(QObject *parent = 0); + ~CAssetPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif // CASSETPLUGINWIDGET_H diff --git a/product/src/gui/plugin/AssetWidget/CAssetTableModel.cpp b/product/src/gui/plugin/AssetWidget/CAssetTableModel.cpp index baa02b76..8f25058d 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetTableModel.cpp +++ b/product/src/gui/plugin/AssetWidget/CAssetTableModel.cpp @@ -1,171 +1,171 @@ -#include "CAssetTableModel.h" -#include -#include "Common.h" -CAssetTableModel::CAssetTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header <= m_listShowInfo.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == ASSET_BACKUP) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); - } - - } - else if(Qt::DisplayRole == role) - { - switch ( index.column() ) - { - case ASSET_ID : - { - return m_listShowInfo[index.row()].id; - } - case ASSET_NAME : - { - return m_listShowInfo[index.row()].name; - } - case ASSET_TYPE : - { - return m_listShowInfo[index.row()].type; - } - case ASSET_PARAM : - { - return m_listShowInfo[index.row()].param; - } - case ASSET_SETUP : - { - return QDate::fromString(QString::number(m_listShowInfo[index.row()].setUpTime),"yyyyMMdd").toString("yyyy-MM-dd"); - } - case ASSET_STATUS : - { - return m_listShowInfo[index.row()].status; - } - case ASSET_CONTACT : - { - return m_listShowInfo[index.row()].contact; - } - case ASSET_PERIOD : - { - int period = m_listShowInfo[index.row()].maintain_period; - switch (period) { - case EN_Period_One_Month: - return tr("一个月"); - case EN_Period_Three_Month: - return tr("三个月"); - case EN_Period_Six_Month: - return tr("半年"); - case EN_Period_One_Year: - return tr("一年"); - default: - return QVariant(); - - } - return QString::number(m_listShowInfo[index.row()].maintain_period); - } - case ASSET_BACKUP : - { - return m_listShowInfo[index.row()].backup; - } - default: - break; - } - } - return QVariant(); -} - -Qt::ItemFlags CAssetTableModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CAssetTableModel::setColumnAlign(const int &column, const int &alignFlag) -{ - Qt::AlignmentFlag flag = Qt::AlignHCenter; - if(Qt::AlignLeft == (Qt::AlignmentFlag)alignFlag || Qt::AlignRight == (Qt::AlignmentFlag)alignFlag) - { - flag = (Qt::AlignmentFlag)alignFlag; - } - m_listHorAlignmentFlags.replace(column, flag); -} - -int CAssetTableModel::getAssetInfo(const QModelIndex &index,AssetInfo &info) -{ - if(index.row() < m_listShowInfo.size()) - { - info = m_listShowInfo.at(index.row()); - return kbdSuccess; - }else - { - return kbdFailed; - } -} - -void CAssetTableModel::updateData(const QList &assetList) -{ - beginResetModel(); - m_listShowInfo = assetList; - endResetModel(); -} - -QList CAssetTableModel::getListShowInfo() -{ - return m_listShowInfo; -} - -QList CAssetTableModel::getHeadInfo() -{ - return m_header; -} +#include "CAssetTableModel.h" +#include +#include "Common.h" +CAssetTableModel::CAssetTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header <= m_listShowInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == ASSET_BACKUP) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + } + + } + else if(Qt::DisplayRole == role) + { + switch ( index.column() ) + { + case ASSET_ID : + { + return m_listShowInfo[index.row()].id; + } + case ASSET_NAME : + { + return m_listShowInfo[index.row()].name; + } + case ASSET_TYPE : + { + return m_listShowInfo[index.row()].type; + } + case ASSET_PARAM : + { + return m_listShowInfo[index.row()].param; + } + case ASSET_SETUP : + { + return QDate::fromString(QString::number(m_listShowInfo[index.row()].setUpTime),"yyyyMMdd").toString("yyyy-MM-dd"); + } + case ASSET_STATUS : + { + return m_listShowInfo[index.row()].status; + } + case ASSET_CONTACT : + { + return m_listShowInfo[index.row()].contact; + } + case ASSET_PERIOD : + { + int period = m_listShowInfo[index.row()].maintain_period; + switch (period) { + case EN_Period_One_Month: + return tr("一个月"); + case EN_Period_Three_Month: + return tr("三个月"); + case EN_Period_Six_Month: + return tr("半年"); + case EN_Period_One_Year: + return tr("一年"); + default: + return QVariant(); + + } + return QString::number(m_listShowInfo[index.row()].maintain_period); + } + case ASSET_BACKUP : + { + return m_listShowInfo[index.row()].backup; + } + default: + break; + } + } + return QVariant(); +} + +Qt::ItemFlags CAssetTableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CAssetTableModel::setColumnAlign(const int &column, const int &alignFlag) +{ + Qt::AlignmentFlag flag = Qt::AlignHCenter; + if(Qt::AlignLeft == (Qt::AlignmentFlag)alignFlag || Qt::AlignRight == (Qt::AlignmentFlag)alignFlag) + { + flag = (Qt::AlignmentFlag)alignFlag; + } + m_listHorAlignmentFlags.replace(column, flag); +} + +int CAssetTableModel::getAssetInfo(const QModelIndex &index,AssetInfo &info) +{ + if(index.row() < m_listShowInfo.size()) + { + info = m_listShowInfo.at(index.row()); + return kbdSuccess; + }else + { + return kbdFailed; + } +} + +void CAssetTableModel::updateData(const QList &assetList) +{ + beginResetModel(); + m_listShowInfo = assetList; + endResetModel(); +} + +QList CAssetTableModel::getListShowInfo() +{ + return m_listShowInfo; +} + +QList CAssetTableModel::getHeadInfo() +{ + return m_header; +} diff --git a/product/src/gui/plugin/AssetWidget/CAssetTableModel.h b/product/src/gui/plugin/AssetWidget/CAssetTableModel.h index d63b7103..2bdff79d 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetTableModel.h +++ b/product/src/gui/plugin/AssetWidget/CAssetTableModel.h @@ -1,41 +1,41 @@ -#ifndef CASSETTABLEMODEL_H -#define CASSETTABLEMODEL_H - -#include -#include "CAssetCommon.h" - -class CAssetTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - - explicit CAssetTableModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; - - void setColumnAlign(const int &column, const int &alignFlag); - - int getAssetInfo(const QModelIndex &index, AssetInfo &info); - - void updateData(const QList & assetList); - - QList getListShowInfo(); - - QList getHeadInfo(); -private: - QStringList m_header; - QList m_listShowInfo; - - QList m_listHorAlignmentFlags; //< 水平对齐方式 -}; - -#endif // CASSETTABLEMODEL_H +#ifndef CASSETTABLEMODEL_H +#define CASSETTABLEMODEL_H + +#include +#include "CAssetCommon.h" + +class CAssetTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + + explicit CAssetTableModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setColumnAlign(const int &column, const int &alignFlag); + + int getAssetInfo(const QModelIndex &index, AssetInfo &info); + + void updateData(const QList & assetList); + + QList getListShowInfo(); + + QList getHeadInfo(); +private: + QStringList m_header; + QList m_listShowInfo; + + QList m_listHorAlignmentFlags; //< 水平对齐方式 +}; + +#endif // CASSETTABLEMODEL_H diff --git a/product/src/gui/plugin/AssetWidget/CAssetUuid.cpp b/product/src/gui/plugin/AssetWidget/CAssetUuid.cpp index 420c05aa..517a7081 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetUuid.cpp +++ b/product/src/gui/plugin/AssetWidget/CAssetUuid.cpp @@ -1,82 +1,82 @@ -#include "CAssetUuid.h" -#include "boost/typeof/typeof.hpp" -#include "boost/algorithm/string/replace.hpp" - -#include "boost/chrono.hpp" - -#include "boost/uuid/random_generator.hpp" -#include "boost/unordered_map.hpp" - - -CAssetUuid::CAssetUuid() -{ - -} - -QString CAssetUuid::getAssetUuid() -{ - boost::uint8_t m_baUuid[18]; - boost::uint8_t m_baBase64[24]; - boost::uuids::detail::random_provider m_randomGen; - std::string strOut; - { - boost::uint64_t nNow = boost::chrono::time_point_cast( - boost::chrono::system_clock::now()).time_since_epoch().count(); - -#include "boost/predef/detail/endian_compat.h" - -#ifdef BOOST_LITTLE_ENDIAN - -#define Swap64(ll) (((ll) >> 56) |\ -(((ll) & 0x00ff000000000000) >> 40) |\ -(((ll) & 0x0000ff0000000000) >> 24) |\ -(((ll) & 0x000000ff00000000) >> 8) |\ -(((ll) & 0x00000000ff000000) << 8) |\ -(((ll) & 0x0000000000ff0000) << 24) |\ -(((ll) & 0x000000000000ff00) << 40) |\ -(((ll) << 56))) - - nNow = Swap64(nNow); -#endif - - memcpy(m_baUuid, ((boost::uint8_t *) &nNow) + 4, 4); - } - - //< 填充 12byte 随机数 - m_randomGen.get_random_bytes(&(m_baUuid[4]), 12); - - //< 最后填充 0 - m_baUuid[16] = 0; - m_baUuid[17] = 0; - - //< 编码为 base64 - { - //< 这是标准的base64编码方式,但原始值递增的情况下,输出字符串的ascii码不是递增的,对数据库索引效率可能略有影响 - //static const char *szBase64Array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - //< 这是自定义的,不是标准base64,以解决上述问题 - static const char *szBase64Array = "+/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - boost::uint8_t *pData = m_baUuid; - int nDestIndex = 0; - for (int i = 0; i < 18; i = i + 3) - { - boost::uint32_t nData = ((boost::uint32_t) *pData << 16) + - ((boost::uint32_t) *(pData + 1) << 8) + (*(pData + 2)); - m_baBase64[nDestIndex] = szBase64Array[nData >> 18]; - m_baBase64[nDestIndex + 1] = szBase64Array[nData >> 12 & (boost::uint32_t) 0x3f]; - m_baBase64[nDestIndex + 2] = szBase64Array[nData >> 6 & (boost::uint32_t) 0x3f]; - m_baBase64[nDestIndex + 3] = szBase64Array[nData & (boost::uint32_t) 0x3f]; - pData = pData + 3; - nDestIndex = nDestIndex + 4; - } - m_baBase64[22] = 0; - m_baBase64[23] = 0; - } - - //< 输出 - strOut.assign((const char *) m_baBase64, 22); - strOut.shrink_to_fit(); - - return QString::fromStdString(strOut); -} +#include "CAssetUuid.h" +#include "boost/typeof/typeof.hpp" +#include "boost/algorithm/string/replace.hpp" + +#include "boost/chrono.hpp" + +#include "boost/uuid/random_generator.hpp" +#include "boost/unordered_map.hpp" + + +CAssetUuid::CAssetUuid() +{ + +} + +QString CAssetUuid::getAssetUuid() +{ + boost::uint8_t m_baUuid[18]; + boost::uint8_t m_baBase64[24]; + boost::uuids::detail::random_provider m_randomGen; + std::string strOut; + { + boost::uint64_t nNow = boost::chrono::time_point_cast( + boost::chrono::system_clock::now()).time_since_epoch().count(); + +#include "boost/predef/detail/endian_compat.h" + +#ifdef BOOST_LITTLE_ENDIAN + +#define Swap64(ll) (((ll) >> 56) |\ +(((ll) & 0x00ff000000000000) >> 40) |\ +(((ll) & 0x0000ff0000000000) >> 24) |\ +(((ll) & 0x000000ff00000000) >> 8) |\ +(((ll) & 0x00000000ff000000) << 8) |\ +(((ll) & 0x0000000000ff0000) << 24) |\ +(((ll) & 0x000000000000ff00) << 40) |\ +(((ll) << 56))) + + nNow = Swap64(nNow); +#endif + + memcpy(m_baUuid, ((boost::uint8_t *) &nNow) + 4, 4); + } + + //< 填充 12byte 随机数 + m_randomGen.get_random_bytes(&(m_baUuid[4]), 12); + + //< 最后填充 0 + m_baUuid[16] = 0; + m_baUuid[17] = 0; + + //< 编码为 base64 + { + //< 这是标准的base64编码方式,但原始值递增的情况下,输出字符串的ascii码不是递增的,对数据库索引效率可能略有影响 + //static const char *szBase64Array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + //< 这是自定义的,不是标准base64,以解决上述问题 + static const char *szBase64Array = "+/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + boost::uint8_t *pData = m_baUuid; + int nDestIndex = 0; + for (int i = 0; i < 18; i = i + 3) + { + boost::uint32_t nData = ((boost::uint32_t) *pData << 16) + + ((boost::uint32_t) *(pData + 1) << 8) + (*(pData + 2)); + m_baBase64[nDestIndex] = szBase64Array[nData >> 18]; + m_baBase64[nDestIndex + 1] = szBase64Array[nData >> 12 & (boost::uint32_t) 0x3f]; + m_baBase64[nDestIndex + 2] = szBase64Array[nData >> 6 & (boost::uint32_t) 0x3f]; + m_baBase64[nDestIndex + 3] = szBase64Array[nData & (boost::uint32_t) 0x3f]; + pData = pData + 3; + nDestIndex = nDestIndex + 4; + } + m_baBase64[22] = 0; + m_baBase64[23] = 0; + } + + //< 输出 + strOut.assign((const char *) m_baBase64, 22); + strOut.shrink_to_fit(); + + return QString::fromStdString(strOut); +} diff --git a/product/src/gui/plugin/AssetWidget/CAssetUuid.h b/product/src/gui/plugin/AssetWidget/CAssetUuid.h index 845011a7..52ee23d5 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetUuid.h +++ b/product/src/gui/plugin/AssetWidget/CAssetUuid.h @@ -1,14 +1,14 @@ -#ifndef CASSETUUID_H -#define CASSETUUID_H - -#include - -class CAssetUuid -{ -public: - CAssetUuid(); - - QString getAssetUuid(); -}; - -#endif // CASSETUUID_H +#ifndef CASSETUUID_H +#define CASSETUUID_H + +#include + +class CAssetUuid +{ +public: + CAssetUuid(); + + QString getAssetUuid(); +}; + +#endif // CASSETUUID_H diff --git a/product/src/gui/plugin/AssetWidget/CAssetView.cpp b/product/src/gui/plugin/AssetWidget/CAssetView.cpp index a42155b7..dec85247 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetView.cpp +++ b/product/src/gui/plugin/AssetWidget/CAssetView.cpp @@ -1,27 +1,27 @@ -#include "CAssetView.h" -#include -#include -#include -#include - -CAssetView::CAssetView(QWidget *parent) - : QTableView(parent) -{ - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); -// setSelectionMode(QAbstractItemView::MultiSelection); -// setHorizontalScrollMode(ScrollPerPixel); - horizontalHeader()->setVisible(true); -} - -void CAssetView::contextMenuEvent(QContextMenuEvent *) -{ - QMenu menu(this); - QAction * selectAction = menu.addAction(tr("全选")); - connect(selectAction, &QAction::triggered, [=](){this->selectAll();}); - QAction * cancleAction = menu.addAction(tr("全不选")); - connect(cancleAction,&QAction::triggered,[=](){this->clearSelection();}); - menu.exec(QCursor::pos()); -} +#include "CAssetView.h" +#include +#include +#include +#include + +CAssetView::CAssetView(QWidget *parent) + : QTableView(parent) +{ + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); +// setSelectionMode(QAbstractItemView::MultiSelection); +// setHorizontalScrollMode(ScrollPerPixel); + horizontalHeader()->setVisible(true); +} + +void CAssetView::contextMenuEvent(QContextMenuEvent *) +{ + QMenu menu(this); + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction, &QAction::triggered, [=](){this->selectAll();}); + QAction * cancleAction = menu.addAction(tr("全不选")); + connect(cancleAction,&QAction::triggered,[=](){this->clearSelection();}); + menu.exec(QCursor::pos()); +} diff --git a/product/src/gui/plugin/AssetWidget/CAssetView.h b/product/src/gui/plugin/AssetWidget/CAssetView.h index 3816099a..896bc046 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetView.h +++ b/product/src/gui/plugin/AssetWidget/CAssetView.h @@ -1,18 +1,18 @@ -#ifndef CASSETVIEW_H -#define CASSETVIEW_H - -#include - -class CAssetView : public QTableView -{ - Q_OBJECT - -public: - CAssetView(QWidget *parent = Q_NULLPTR); - -protected: - - void contextMenuEvent(QContextMenuEvent *) Q_DECL_OVERRIDE; -}; - -#endif // CASSETVIEW_H +#ifndef CASSETVIEW_H +#define CASSETVIEW_H + +#include + +class CAssetView : public QTableView +{ + Q_OBJECT + +public: + CAssetView(QWidget *parent = Q_NULLPTR); + +protected: + + void contextMenuEvent(QContextMenuEvent *) Q_DECL_OVERRIDE; +}; + +#endif // CASSETVIEW_H diff --git a/product/src/gui/plugin/AssetWidget/CAssetWidget.cpp b/product/src/gui/plugin/AssetWidget/CAssetWidget.cpp index f5917b09..8a3307cc 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetWidget.cpp +++ b/product/src/gui/plugin/AssetWidget/CAssetWidget.cpp @@ -1,611 +1,611 @@ -#include "CAssetWidget.h" -#include "ui_CAssetWidget.h" -#include "pub_logger_api/logger.h" -#include -#include -#include "CAssetView.h" -#include "Common.h" -#include "CPropertyDialog.h" -#include -#include "CRecordDialog.h" -#include -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" - -CAssetWidget::CAssetWidget(QWidget *parent, bool editMode) - : QWidget(parent), - ui(new Ui::CAssetWidget), - m_edit(editMode), - m_pModel(Q_NULLPTR), - m_delegate(Q_NULLPTR), - m_thread(Q_NULLPTR), - m_worker(Q_NULLPTR) -{ - ui->setupUi(this); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("asset.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - else - { - qDebug() << "asset.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - qRegisterMetaType< AssetInfo >("AssetInfo"); - qRegisterMetaType< QList >("QList"); - qRegisterMetaType< QList >("QList"); - qRegisterMetaType< QMap >("QMap"); - qRegisterMetaType< QList >("QList"); - - ui->cDevg->setView(new QListView()); - loadConfig(); - initUi(); - m_mode = EN_Asset_Window; - CAssetDataMng::instance()->addCount(); - if(!m_edit) - { - connect(ui->bAdd,&QPushButton::clicked,this,&CAssetWidget::addAsset); - connect(ui->bDel,&QPushButton::clicked,this,&CAssetWidget::delAsset); - connect(ui->bIn,&QPushButton::clicked,this,&CAssetWidget::inAsset); - connect(ui->bOut,&QPushButton::clicked,this,&CAssetWidget::outAsset); - connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CAssetWidget::treeItemClicked); - connect(ui->cDevg,SIGNAL(currentIndexChanged(int)), this, SLOT(slotDevgUpdate(int))); - connect(ui->tableView,&CAssetView::doubleClicked,this,&CAssetWidget::assetDoubleClicked); - connect(ui->bSearch,&QPushButton::clicked,this,&CAssetWidget::searchAsset); - - if(m_pModel == Q_NULLPTR) - { - m_pModel = new CAssetTableModel(); - ui->tableView->setModel(m_pModel); - ui->tableView->setColumnHidden(0,true); - ui->tableView->setColumnWidth(1, 180); - ui->tableView->setColumnWidth(2, 180); - ui->tableView->setColumnWidth(3, 180); - ui->tableView->setColumnWidth(4, 150); - ui->tableView->setColumnWidth(5, 120); - ui->tableView->setColumnWidth(6, 180); - ui->tableView->setColumnWidth(7, 120); - } - if(m_delegate == Q_NULLPTR) - { - m_delegate = new CAssetDelegate(m_pModel); - ui->tableView->setItemDelegate(m_delegate); - } - connect(m_delegate,&CAssetDelegate::sigOpenAssetRecord,this,&CAssetWidget::slotOpenAssetRecord); - - m_thread = new QThread(); - m_worker = new CWorker(); - m_worker->moveToThread(m_thread); - connect(this,&CAssetWidget::sigExportAsset,m_worker,&CWorker::slotExportAsset,Qt::QueuedConnection); - connect(this,&CAssetWidget::sigExportRecord,m_worker,&CWorker::slotExportRecord,Qt::QueuedConnection); - connect(m_worker,&CWorker::sigExportEnd,this,&CAssetWidget::slotExportEnd,Qt::QueuedConnection); - - connect(this,&CAssetWidget::sigImportAsset,m_worker,&CWorker::slotImportAsset,Qt::QueuedConnection); - connect(this,&CAssetWidget::sigImportRecord,m_worker,&CWorker::slotImportRecord,Qt::QueuedConnection); - connect(m_worker,&CWorker::sigImportEnd,this,&CAssetWidget::slotImportEnd,Qt::QueuedConnection); - - m_thread->start(); - } -} - -CAssetWidget::~CAssetWidget() -{ - if(m_pModel) - { - delete m_pModel; - } - m_pModel = Q_NULLPTR; - if(m_delegate) - { - delete m_delegate; - } - m_delegate = Q_NULLPTR; - if(m_thread) - { - m_thread->quit(); - m_thread->wait(); - delete m_thread; - } - m_thread = Q_NULLPTR; - if(m_worker) - { - delete m_worker; - } - m_worker = Q_NULLPTR; - - CAssetDataMng::instance()->subCount(); - int count = CAssetDataMng::instance()->getCount(); - LOGDEBUG("~CAssetWidget():还剩余数量%d",count); - if(count <= 0) - { - CAssetDataMng::instance()->destory(); - } - delete ui; -} - -void CAssetWidget::initUi() -{ - ui->widget->heightForWidth(20); - ui->bAdd->setToolTip(tr("添加资产信息")); - ui->bDel->setToolTip(tr("同时会删除维护记录")); - ui->lKey->setToolTip(tr("对设备名称、型号、参数和内容生效")); - ui->cDevg->setHidden(true); - ui->label->setHidden(true); - ui->splitter->setSizes(QList()<<220<<1200); - initTreeWidget(); -} - -void CAssetWidget::loadConfig() -{ - loadLoc(); - loadLocAndDevg(); -} - -void CAssetWidget::loadLoc() -{ - m_locMap = CAssetDataMng::instance()->readLocation(); -} - -void CAssetWidget::loadLocAndDevg() -{ - m_devgMap.clear(); - m_locDevgMap.clear(); - m_devgMap = CAssetDataMng::instance()->readDevg(); -} - -void CAssetWidget::initTreeWidget() -{ - cleanTreeWidget(); - ui->treeWidget->setColumnCount(1); - QList locList = CAssetDataMng::instance()->readLocationOrder(); - foreach (const int locId, locList) { - QList devgList = CAssetDataMng::instance()->readDevgByLoc(locId).keys(); - if(devgList.isEmpty()) - { - continue; - } - QString locDesc = m_locMap.value(locId,tr("未知位置")); - QTreeWidgetItem *locItem = new QTreeWidgetItem(); - locItem->setText(0,locDesc); - locItem->setData(0,Qt::UserRole,(int)EN_TREE_LOC);//类型 - locItem->setData(0,Qt::UserRole+1,locId);//值 - ui->treeWidget->addTopLevelItem(locItem); - m_locDevgMap.insert(locId, devgList); - for(int index(0);indexsetText(0,devgDesc); - devgItem->setData(0,Qt::UserRole,(int)EN_TREE_DEVG);//类型 - devgItem->setData(0,Qt::UserRole+1,devgTag);//值 - locItem->addChild(devgItem); - } - } -} - -void CAssetWidget::cleanTreeWidget() -{ - for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) - { - QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); - delete item; - } -} - -void CAssetWidget::messBox(const QString &mess) -{ - QMessageBox::information(this, tr("提示"), mess, QMessageBox::Ok); -} - -bool CAssetWidget::containsFilterText(const AssetInfo &info, const QString &filterText) -{ - if(info.name.contains(filterText)) - { - return true; - } - if(info.type.contains(filterText)) - { - return true; - } - if(info.param.contains(filterText)) - { - return true; - } - if(info.backup.contains(filterText)) - { - return true; - } - return false; -} - -void CAssetWidget::inAssetInfo() -{ - QString fileName= QString(); - if(kbdSuccess !=getOpenFileName(fileName)) - { - return ; - } - - emit sigImportAsset(fileName); -} - -void CAssetWidget::inRecordInfo() -{ - - QString fileName= QString(); - if(kbdSuccess !=getOpenFileName(fileName)) - { - return ; - } - - emit sigImportRecord(fileName); -} - -void CAssetWidget::outAssetInfo() -{ - QString fileName= QString(); - if(kbdSuccess !=getSaveFileName(fileName)) - { - return ; - } - - QList headList = m_pModel->getHeadInfo(); - headList.append(tr("所属设备组")); - QList assetList = m_pModel->getListShowInfo(); - emit sigExportAsset(fileName,assetList); -} - -void CAssetWidget::outRecordInfo() -{ - QString fileName= QString(); - if(kbdSuccess !=getSaveFileName(fileName)) - { - return ; - } - QList assetList = m_pModel->getListShowInfo(); - QList devTagList; - for(int index(0);index recordList = CAssetDataMng::instance()->getRecordInfoByDevId(devTagList); - - emit sigExportRecord(fileName,recordList); -} - -int CAssetWidget::getSaveFileName(QString &fileName) -{ - fileName = QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xlsx)");//获取保存路径*.xls - if(fileName.isEmpty()) - { - return kbdFailed; - } - if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) - { - fileName = fileName+".xlsx"; - } - return kbdSuccess; -} - -int CAssetWidget::getOpenFileName(QString &fileName) -{ - fileName = QFileDialog::getOpenFileName(this,tr("Open File"),"","Excel(*.xlsx)"); - if(fileName.isEmpty()) - { - return kbdFailed; - } - return kbdSuccess; -} - -void CAssetWidget::filterText(QList &assetList) -{ - QString filterText =ui->lKey->text(); - if(!filterText.isEmpty()) - { - QList::iterator it = assetList.begin(); - while (it != assetList.end()) { - - if(!containsFilterText(*it,filterText)) - { - it = assetList.erase(it); - }else - { - it++; - } - } - } -} - -void CAssetWidget::filterTime(QList &assetList) -{ - Q_UNUSED(assetList); -} - -void CAssetWidget::setDevg(QStringList devgList) -{ - m_mode = EN_Asset_Pop; - ui->widget->heightForWidth(20); - ui->frame_2->setHidden(true); - ui->title->setHidden(true); - ui->cDevg->setHidden(false); - ui->label->setHidden(false); - ui->cDevg->blockSignals(true); - ui->cDevg->clear(); - foreach (QString devg, devgList) { - ui->cDevg->addItem(m_devgMap.value(devg),devg); - } - - ui->cDevg->blockSignals(false); - m_searchdevgList.clear(); - m_searchdevgList.append(ui->cDevg->currentData().toString()); - brush(); -} - -void CAssetWidget::setColumnWidth(const int &column, const int &width) -{ - if(m_edit) - { - return; - } - if(m_pModel) - { - ui->tableView->setColumnWidth(column, width); - } -} - -void CAssetWidget::setColumnAlign(const int &column, const int &alignFlag) -{ - if(m_edit) - { - return; - } - if(m_pModel) - { - m_pModel->setColumnAlign(column, alignFlag); - } -} - -void CAssetWidget::setColumnHide(const int &column, const bool hide) -{ - if(m_edit) - { - return; - } - if(column< m_pModel->columnCount() && column > -1) - { - ui->tableView->setColumnHidden(column,hide); - } -} - -void CAssetWidget::treeItemClicked(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - if(item == Q_NULLPTR) - { - return ; - } - if(item->data(0,Qt::UserRole).toInt() == EN_TREE_LOC) - { - int loc =item->data(0,Qt::UserRole+1).toInt(); - m_searchdevgList.clear(); - QMap >::iterator it= m_locDevgMap.find(loc); - if(it != m_locDevgMap.end()) - { - m_searchdevgList = it.value(); - } - }else if(item->data(0,Qt::UserRole).toInt() == EN_TREE_DEVG) - { - QString devg =item->data(0,Qt::UserRole+1).toString(); - m_searchdevgList.clear(); - m_searchdevgList.append(devg); - } - brush(); -} - -void CAssetWidget::slotDevgUpdate(int index) -{ - Q_UNUSED(index); - m_searchdevgList.clear(); - m_searchdevgList.append(ui->cDevg->currentData().toString()); - brush(); -} - -void CAssetWidget::addAsset() -{ - int loc = -1; - QString devg = QString(); - if(ui->cDevg->isHidden()) - { - if(ui->treeWidget->selectedItems().isEmpty()) - { - messBox(tr("请先选中位置或设备组")); - return ; - }else - { - QTreeWidgetItem *item =ui->treeWidget->selectedItems().at(0); - if(item->data(0,Qt::UserRole).toInt()== EN_TREE_LOC) - { - loc = item->data(0,Qt::UserRole+1).toInt(); - }else - { - devg = item->data(0,Qt::UserRole+1).toString(); - } - } - }else - { - if(ui->cDevg->count()<=0) - { - messBox(tr("设备组为空")); - return ; - }else - { - devg = ui->cDevg->currentData().toString(); - } - } - if(loc == -1 && !devg.isEmpty()) - { - if(kbdFailed == CAssetDataMng::instance()->readLocIdByDevg(devg,loc)) - { - return ; - } - } - CPropertyDialog dlg(EN_Property_Add,loc,devg); - if(dlg.exec() == QDialog::Accepted) - { - brush(); - messBox(tr("添加成功!")); - } -} - -void CAssetWidget::delAsset() -{ - QModelIndexList modelIndexList = ui->tableView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList listInfo = m_pModel->getListShowInfo(); - QList idList; - QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); - for(;modelIndexIter != modelIndexList.end();modelIndexIter++) - { - idList.append(listInfo.at(modelIndexIter->row()).id); - } - if(idList.isEmpty()) - { - return ; - } - if(CAssetDataMng::instance()->delAsset(idList) == kbdFailed) - { - messBox(tr("删除失败!")); - }else - { - brush(); - messBox(tr("删除成功!")); - } -} - -void CAssetWidget::inAsset() -{ - QMenu menu(this); - QAction * selectAction = menu.addAction(tr("资产信息")); - connect(selectAction, &QAction::triggered, [=](){inAssetInfo();}); - QAction * cancleAction = menu.addAction(tr("维护记录")); - connect(cancleAction,&QAction::triggered,[=](){inRecordInfo();}); - QPoint point = ui->bIn->mapToGlobal(QPoint()); - point.setY(point.y()-2*ui->bIn->height()); - menu.exec(point); -} - -void CAssetWidget::outAsset() -{ - QMenu menu(this); - QAction * selectAction = menu.addAction(tr("资产信息")); - connect(selectAction, &QAction::triggered, [=](){outAssetInfo();}); - QAction * cancleAction = menu.addAction(tr("维护记录")); - connect(cancleAction,&QAction::triggered,[=](){outRecordInfo();}); - QPoint point = ui->bOut->mapToGlobal(QPoint()); - point.setY(point.y()-2*ui->bOut->height()); - menu.exec(point); -} - -void CAssetWidget::brush() -{ - QList assetList; - m_pModel->updateData(assetList); - if(m_searchdevgList.isEmpty()) - { - return ; - } - - assetList = CAssetDataMng::instance()->getAssetInfoByDevg(m_searchdevgList); - filterText(assetList); - filterTime(assetList); - - m_pModel->updateData(assetList); - -} - -void CAssetWidget::assetDoubleClicked(const QModelIndex &index) -{ - if(m_pModel == Q_NULLPTR) - { - return ; - } - - if(!index.isValid()) - { - return ; - } - AssetInfo info; - if(m_pModel->getAssetInfo(index,info) != kbdSuccess) - { - return ; - } - int loc = 0; - if(CAssetDataMng::instance()->readLocIdByDevg(info.dev_group,loc) == kbdFailed) - { - return ; - } - - CPropertyDialog dlg(EN_Property_Edit,loc,info.dev_group); - dlg.init(info); - if(dlg.exec() == QDialog::Accepted) - { - brush(); - messBox("编辑成功!"); - } -} - -void CAssetWidget::slotOpenAssetRecord(const AssetInfo &info) -{ - CRecordDialog dlg(m_mode,info); - dlg.exec(); -} - -void CAssetWidget::searchAsset() -{ - brush(); -} - -void CAssetWidget::slotImportEnd(const QString &result) -{ - brush(); - messBox(result); -} - -void CAssetWidget::slotExportEnd(const QString &result) -{ - brush(); - messBox(result); -} +#include "CAssetWidget.h" +#include "ui_CAssetWidget.h" +#include "pub_logger_api/logger.h" +#include +#include +#include "CAssetView.h" +#include "Common.h" +#include "CPropertyDialog.h" +#include +#include "CRecordDialog.h" +#include +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" + +CAssetWidget::CAssetWidget(QWidget *parent, bool editMode) + : QWidget(parent), + ui(new Ui::CAssetWidget), + m_edit(editMode), + m_pModel(Q_NULLPTR), + m_delegate(Q_NULLPTR), + m_thread(Q_NULLPTR), + m_worker(Q_NULLPTR) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("asset.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + else + { + qDebug() << "asset.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + qRegisterMetaType< AssetInfo >("AssetInfo"); + qRegisterMetaType< QList >("QList"); + qRegisterMetaType< QList >("QList"); + qRegisterMetaType< QMap >("QMap"); + qRegisterMetaType< QList >("QList"); + + ui->cDevg->setView(new QListView()); + loadConfig(); + initUi(); + m_mode = EN_Asset_Window; + CAssetDataMng::instance()->addCount(); + if(!m_edit) + { + connect(ui->bAdd,&QPushButton::clicked,this,&CAssetWidget::addAsset); + connect(ui->bDel,&QPushButton::clicked,this,&CAssetWidget::delAsset); + connect(ui->bIn,&QPushButton::clicked,this,&CAssetWidget::inAsset); + connect(ui->bOut,&QPushButton::clicked,this,&CAssetWidget::outAsset); + connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CAssetWidget::treeItemClicked); + connect(ui->cDevg,SIGNAL(currentIndexChanged(int)), this, SLOT(slotDevgUpdate(int))); + connect(ui->tableView,&CAssetView::doubleClicked,this,&CAssetWidget::assetDoubleClicked); + connect(ui->bSearch,&QPushButton::clicked,this,&CAssetWidget::searchAsset); + + if(m_pModel == Q_NULLPTR) + { + m_pModel = new CAssetTableModel(); + ui->tableView->setModel(m_pModel); + ui->tableView->setColumnHidden(0,true); + ui->tableView->setColumnWidth(1, 180); + ui->tableView->setColumnWidth(2, 180); + ui->tableView->setColumnWidth(3, 180); + ui->tableView->setColumnWidth(4, 150); + ui->tableView->setColumnWidth(5, 120); + ui->tableView->setColumnWidth(6, 180); + ui->tableView->setColumnWidth(7, 120); + } + if(m_delegate == Q_NULLPTR) + { + m_delegate = new CAssetDelegate(m_pModel); + ui->tableView->setItemDelegate(m_delegate); + } + connect(m_delegate,&CAssetDelegate::sigOpenAssetRecord,this,&CAssetWidget::slotOpenAssetRecord); + + m_thread = new QThread(); + m_worker = new CWorker(); + m_worker->moveToThread(m_thread); + connect(this,&CAssetWidget::sigExportAsset,m_worker,&CWorker::slotExportAsset,Qt::QueuedConnection); + connect(this,&CAssetWidget::sigExportRecord,m_worker,&CWorker::slotExportRecord,Qt::QueuedConnection); + connect(m_worker,&CWorker::sigExportEnd,this,&CAssetWidget::slotExportEnd,Qt::QueuedConnection); + + connect(this,&CAssetWidget::sigImportAsset,m_worker,&CWorker::slotImportAsset,Qt::QueuedConnection); + connect(this,&CAssetWidget::sigImportRecord,m_worker,&CWorker::slotImportRecord,Qt::QueuedConnection); + connect(m_worker,&CWorker::sigImportEnd,this,&CAssetWidget::slotImportEnd,Qt::QueuedConnection); + + m_thread->start(); + } +} + +CAssetWidget::~CAssetWidget() +{ + if(m_pModel) + { + delete m_pModel; + } + m_pModel = Q_NULLPTR; + if(m_delegate) + { + delete m_delegate; + } + m_delegate = Q_NULLPTR; + if(m_thread) + { + m_thread->quit(); + m_thread->wait(); + delete m_thread; + } + m_thread = Q_NULLPTR; + if(m_worker) + { + delete m_worker; + } + m_worker = Q_NULLPTR; + + CAssetDataMng::instance()->subCount(); + int count = CAssetDataMng::instance()->getCount(); + LOGDEBUG("~CAssetWidget():还剩余数量%d",count); + if(count <= 0) + { + CAssetDataMng::instance()->destory(); + } + delete ui; +} + +void CAssetWidget::initUi() +{ + ui->widget->heightForWidth(20); + ui->bAdd->setToolTip(tr("添加资产信息")); + ui->bDel->setToolTip(tr("同时会删除维护记录")); + ui->lKey->setToolTip(tr("对设备名称、型号、参数和内容生效")); + ui->cDevg->setHidden(true); + ui->label->setHidden(true); + ui->splitter->setSizes(QList()<<220<<1200); + initTreeWidget(); +} + +void CAssetWidget::loadConfig() +{ + loadLoc(); + loadLocAndDevg(); +} + +void CAssetWidget::loadLoc() +{ + m_locMap = CAssetDataMng::instance()->readLocation(); +} + +void CAssetWidget::loadLocAndDevg() +{ + m_devgMap.clear(); + m_locDevgMap.clear(); + m_devgMap = CAssetDataMng::instance()->readDevg(); +} + +void CAssetWidget::initTreeWidget() +{ + cleanTreeWidget(); + ui->treeWidget->setColumnCount(1); + QList locList = CAssetDataMng::instance()->readLocationOrder(); + foreach (const int locId, locList) { + QList devgList = CAssetDataMng::instance()->readDevgByLoc(locId).keys(); + if(devgList.isEmpty()) + { + continue; + } + QString locDesc = m_locMap.value(locId,tr("未知位置")); + QTreeWidgetItem *locItem = new QTreeWidgetItem(); + locItem->setText(0,locDesc); + locItem->setData(0,Qt::UserRole,(int)EN_TREE_LOC);//类型 + locItem->setData(0,Qt::UserRole+1,locId);//值 + ui->treeWidget->addTopLevelItem(locItem); + m_locDevgMap.insert(locId, devgList); + for(int index(0);indexsetText(0,devgDesc); + devgItem->setData(0,Qt::UserRole,(int)EN_TREE_DEVG);//类型 + devgItem->setData(0,Qt::UserRole+1,devgTag);//值 + locItem->addChild(devgItem); + } + } +} + +void CAssetWidget::cleanTreeWidget() +{ + for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) + { + QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); + delete item; + } +} + +void CAssetWidget::messBox(const QString &mess) +{ + QMessageBox::information(this, tr("提示"), mess, QMessageBox::Ok); +} + +bool CAssetWidget::containsFilterText(const AssetInfo &info, const QString &filterText) +{ + if(info.name.contains(filterText)) + { + return true; + } + if(info.type.contains(filterText)) + { + return true; + } + if(info.param.contains(filterText)) + { + return true; + } + if(info.backup.contains(filterText)) + { + return true; + } + return false; +} + +void CAssetWidget::inAssetInfo() +{ + QString fileName= QString(); + if(kbdSuccess !=getOpenFileName(fileName)) + { + return ; + } + + emit sigImportAsset(fileName); +} + +void CAssetWidget::inRecordInfo() +{ + + QString fileName= QString(); + if(kbdSuccess !=getOpenFileName(fileName)) + { + return ; + } + + emit sigImportRecord(fileName); +} + +void CAssetWidget::outAssetInfo() +{ + QString fileName= QString(); + if(kbdSuccess !=getSaveFileName(fileName)) + { + return ; + } + + QList headList = m_pModel->getHeadInfo(); + headList.append(tr("所属设备组")); + QList assetList = m_pModel->getListShowInfo(); + emit sigExportAsset(fileName,assetList); +} + +void CAssetWidget::outRecordInfo() +{ + QString fileName= QString(); + if(kbdSuccess !=getSaveFileName(fileName)) + { + return ; + } + QList assetList = m_pModel->getListShowInfo(); + QList devTagList; + for(int index(0);index recordList = CAssetDataMng::instance()->getRecordInfoByDevId(devTagList); + + emit sigExportRecord(fileName,recordList); +} + +int CAssetWidget::getSaveFileName(QString &fileName) +{ + fileName = QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xlsx)");//获取保存路径*.xls + if(fileName.isEmpty()) + { + return kbdFailed; + } + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + { + fileName = fileName+".xlsx"; + } + return kbdSuccess; +} + +int CAssetWidget::getOpenFileName(QString &fileName) +{ + fileName = QFileDialog::getOpenFileName(this,tr("Open File"),"","Excel(*.xlsx)"); + if(fileName.isEmpty()) + { + return kbdFailed; + } + return kbdSuccess; +} + +void CAssetWidget::filterText(QList &assetList) +{ + QString filterText =ui->lKey->text(); + if(!filterText.isEmpty()) + { + QList::iterator it = assetList.begin(); + while (it != assetList.end()) { + + if(!containsFilterText(*it,filterText)) + { + it = assetList.erase(it); + }else + { + it++; + } + } + } +} + +void CAssetWidget::filterTime(QList &assetList) +{ + Q_UNUSED(assetList); +} + +void CAssetWidget::setDevg(QStringList devgList) +{ + m_mode = EN_Asset_Pop; + ui->widget->heightForWidth(20); + ui->frame_2->setHidden(true); + ui->title->setHidden(true); + ui->cDevg->setHidden(false); + ui->label->setHidden(false); + ui->cDevg->blockSignals(true); + ui->cDevg->clear(); + foreach (QString devg, devgList) { + ui->cDevg->addItem(m_devgMap.value(devg),devg); + } + + ui->cDevg->blockSignals(false); + m_searchdevgList.clear(); + m_searchdevgList.append(ui->cDevg->currentData().toString()); + brush(); +} + +void CAssetWidget::setColumnWidth(const int &column, const int &width) +{ + if(m_edit) + { + return; + } + if(m_pModel) + { + ui->tableView->setColumnWidth(column, width); + } +} + +void CAssetWidget::setColumnAlign(const int &column, const int &alignFlag) +{ + if(m_edit) + { + return; + } + if(m_pModel) + { + m_pModel->setColumnAlign(column, alignFlag); + } +} + +void CAssetWidget::setColumnHide(const int &column, const bool hide) +{ + if(m_edit) + { + return; + } + if(column< m_pModel->columnCount() && column > -1) + { + ui->tableView->setColumnHidden(column,hide); + } +} + +void CAssetWidget::treeItemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + if(item == Q_NULLPTR) + { + return ; + } + if(item->data(0,Qt::UserRole).toInt() == EN_TREE_LOC) + { + int loc =item->data(0,Qt::UserRole+1).toInt(); + m_searchdevgList.clear(); + QMap >::iterator it= m_locDevgMap.find(loc); + if(it != m_locDevgMap.end()) + { + m_searchdevgList = it.value(); + } + }else if(item->data(0,Qt::UserRole).toInt() == EN_TREE_DEVG) + { + QString devg =item->data(0,Qt::UserRole+1).toString(); + m_searchdevgList.clear(); + m_searchdevgList.append(devg); + } + brush(); +} + +void CAssetWidget::slotDevgUpdate(int index) +{ + Q_UNUSED(index); + m_searchdevgList.clear(); + m_searchdevgList.append(ui->cDevg->currentData().toString()); + brush(); +} + +void CAssetWidget::addAsset() +{ + int loc = -1; + QString devg = QString(); + if(ui->cDevg->isHidden()) + { + if(ui->treeWidget->selectedItems().isEmpty()) + { + messBox(tr("请先选中位置或设备组")); + return ; + }else + { + QTreeWidgetItem *item =ui->treeWidget->selectedItems().at(0); + if(item->data(0,Qt::UserRole).toInt()== EN_TREE_LOC) + { + loc = item->data(0,Qt::UserRole+1).toInt(); + }else + { + devg = item->data(0,Qt::UserRole+1).toString(); + } + } + }else + { + if(ui->cDevg->count()<=0) + { + messBox(tr("设备组为空")); + return ; + }else + { + devg = ui->cDevg->currentData().toString(); + } + } + if(loc == -1 && !devg.isEmpty()) + { + if(kbdFailed == CAssetDataMng::instance()->readLocIdByDevg(devg,loc)) + { + return ; + } + } + CPropertyDialog dlg(EN_Property_Add,loc,devg); + if(dlg.exec() == QDialog::Accepted) + { + brush(); + messBox(tr("添加成功!")); + } +} + +void CAssetWidget::delAsset() +{ + QModelIndexList modelIndexList = ui->tableView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList listInfo = m_pModel->getListShowInfo(); + QList idList; + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + idList.append(listInfo.at(modelIndexIter->row()).id); + } + if(idList.isEmpty()) + { + return ; + } + if(CAssetDataMng::instance()->delAsset(idList) == kbdFailed) + { + messBox(tr("删除失败!")); + }else + { + brush(); + messBox(tr("删除成功!")); + } +} + +void CAssetWidget::inAsset() +{ + QMenu menu(this); + QAction * selectAction = menu.addAction(tr("资产信息")); + connect(selectAction, &QAction::triggered, [=](){inAssetInfo();}); + QAction * cancleAction = menu.addAction(tr("维护记录")); + connect(cancleAction,&QAction::triggered,[=](){inRecordInfo();}); + QPoint point = ui->bIn->mapToGlobal(QPoint()); + point.setY(point.y()-2*ui->bIn->height()); + menu.exec(point); +} + +void CAssetWidget::outAsset() +{ + QMenu menu(this); + QAction * selectAction = menu.addAction(tr("资产信息")); + connect(selectAction, &QAction::triggered, [=](){outAssetInfo();}); + QAction * cancleAction = menu.addAction(tr("维护记录")); + connect(cancleAction,&QAction::triggered,[=](){outRecordInfo();}); + QPoint point = ui->bOut->mapToGlobal(QPoint()); + point.setY(point.y()-2*ui->bOut->height()); + menu.exec(point); +} + +void CAssetWidget::brush() +{ + QList assetList; + m_pModel->updateData(assetList); + if(m_searchdevgList.isEmpty()) + { + return ; + } + + assetList = CAssetDataMng::instance()->getAssetInfoByDevg(m_searchdevgList); + filterText(assetList); + filterTime(assetList); + + m_pModel->updateData(assetList); + +} + +void CAssetWidget::assetDoubleClicked(const QModelIndex &index) +{ + if(m_pModel == Q_NULLPTR) + { + return ; + } + + if(!index.isValid()) + { + return ; + } + AssetInfo info; + if(m_pModel->getAssetInfo(index,info) != kbdSuccess) + { + return ; + } + int loc = 0; + if(CAssetDataMng::instance()->readLocIdByDevg(info.dev_group,loc) == kbdFailed) + { + return ; + } + + CPropertyDialog dlg(EN_Property_Edit,loc,info.dev_group); + dlg.init(info); + if(dlg.exec() == QDialog::Accepted) + { + brush(); + messBox("编辑成功!"); + } +} + +void CAssetWidget::slotOpenAssetRecord(const AssetInfo &info) +{ + CRecordDialog dlg(m_mode,info); + dlg.exec(); +} + +void CAssetWidget::searchAsset() +{ + brush(); +} + +void CAssetWidget::slotImportEnd(const QString &result) +{ + brush(); + messBox(result); +} + +void CAssetWidget::slotExportEnd(const QString &result) +{ + brush(); + messBox(result); +} diff --git a/product/src/gui/plugin/AssetWidget/CAssetWidget.h b/product/src/gui/plugin/AssetWidget/CAssetWidget.h index 36d3480c..a391f3aa 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetWidget.h +++ b/product/src/gui/plugin/AssetWidget/CAssetWidget.h @@ -1,119 +1,119 @@ -#ifndef CASSETWIDGET_H -#define CASSETWIDGET_H - -#include -#include -#include -#include "CAssetCommon.h" -#include "CAssetTableModel.h" -#include "CAssetDelegate.h" -#include -#include "CWorker.h" - -QT_BEGIN_NAMESPACE -namespace Ui { class CAssetWidget; } -QT_END_NAMESPACE - - - -class CAssetWidget : public QWidget -{ - Q_OBJECT - -public: - CAssetWidget(QWidget *parent, bool editMode = false); - ~CAssetWidget(); - -signals: - void sigExportAsset(const QString &fileName,const QList &assetList); - void sigExportRecord(const QString &fileName,const QList &recordList); - - void sigImportAsset(const QString &fileName); - void sigImportRecord(const QString &fileName); -private: - void initUi(); - void loadConfig(); - - void loadLoc(); - void loadLocAndDevg(); - - void initTreeWidget(); - void cleanTreeWidget(); - - void messBox(const QString &mess); - - bool containsFilterText(const AssetInfo &info,const QString &filterText); - - void inAssetInfo(); - - void inRecordInfo(); - - void outAssetInfo(); - - void outRecordInfo(); - - int getSaveFileName(QString &fileName); - - int getOpenFileName(QString &fileName); - - void filterText(QList &assetList); - - void filterTime(QList &assetList); - -public slots: - - void setDevg(QStringList devgList); - - void setColumnWidth(const int &column, const int &width); - - void setColumnAlign(const int &column, const int &alignFlag); - - void setColumnHide(const int &column,const bool hide); - - void treeItemClicked(QTreeWidgetItem *item, int column); - - void slotDevgUpdate(int index); - - void addAsset(); - - void delAsset(); - - void inAsset(); - - void outAsset(); - - void brush(); - - void assetDoubleClicked(const QModelIndex &index); - - void slotOpenAssetRecord(const AssetInfo &info); - - void searchAsset(); - - void slotImportEnd(const QString &result); - - void slotExportEnd(const QString &result); - -private: - Ui::CAssetWidget *ui; - bool m_edit; - QString m_path; - - QMap m_locMap; - QMap m_devgMap; - QMap > m_locDevgMap; - - QStringList m_devgList; //下拉框中的设备组 - - QStringList m_searchdevgList; - - CAssetTableModel * m_pModel; - CAssetDelegate * m_delegate; - - int m_mode; - - QThread *m_thread; - CWorker *m_worker; - -}; -#endif // CASSETWIDGET_H +#ifndef CASSETWIDGET_H +#define CASSETWIDGET_H + +#include +#include +#include +#include "CAssetCommon.h" +#include "CAssetTableModel.h" +#include "CAssetDelegate.h" +#include +#include "CWorker.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class CAssetWidget; } +QT_END_NAMESPACE + + + +class CAssetWidget : public QWidget +{ + Q_OBJECT + +public: + CAssetWidget(QWidget *parent, bool editMode = false); + ~CAssetWidget(); + +signals: + void sigExportAsset(const QString &fileName,const QList &assetList); + void sigExportRecord(const QString &fileName,const QList &recordList); + + void sigImportAsset(const QString &fileName); + void sigImportRecord(const QString &fileName); +private: + void initUi(); + void loadConfig(); + + void loadLoc(); + void loadLocAndDevg(); + + void initTreeWidget(); + void cleanTreeWidget(); + + void messBox(const QString &mess); + + bool containsFilterText(const AssetInfo &info,const QString &filterText); + + void inAssetInfo(); + + void inRecordInfo(); + + void outAssetInfo(); + + void outRecordInfo(); + + int getSaveFileName(QString &fileName); + + int getOpenFileName(QString &fileName); + + void filterText(QList &assetList); + + void filterTime(QList &assetList); + +public slots: + + void setDevg(QStringList devgList); + + void setColumnWidth(const int &column, const int &width); + + void setColumnAlign(const int &column, const int &alignFlag); + + void setColumnHide(const int &column,const bool hide); + + void treeItemClicked(QTreeWidgetItem *item, int column); + + void slotDevgUpdate(int index); + + void addAsset(); + + void delAsset(); + + void inAsset(); + + void outAsset(); + + void brush(); + + void assetDoubleClicked(const QModelIndex &index); + + void slotOpenAssetRecord(const AssetInfo &info); + + void searchAsset(); + + void slotImportEnd(const QString &result); + + void slotExportEnd(const QString &result); + +private: + Ui::CAssetWidget *ui; + bool m_edit; + QString m_path; + + QMap m_locMap; + QMap m_devgMap; + QMap > m_locDevgMap; + + QStringList m_devgList; //下拉框中的设备组 + + QStringList m_searchdevgList; + + CAssetTableModel * m_pModel; + CAssetDelegate * m_delegate; + + int m_mode; + + QThread *m_thread; + CWorker *m_worker; + +}; +#endif // CASSETWIDGET_H diff --git a/product/src/gui/plugin/AssetWidget/CAssetWidget.ui b/product/src/gui/plugin/AssetWidget/CAssetWidget.ui index 6b1b7f70..7e5cf0a4 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetWidget.ui +++ b/product/src/gui/plugin/AssetWidget/CAssetWidget.ui @@ -1,303 +1,303 @@ - - - CAssetWidget - - - - 0 - 0 - 1375 - 586 - - - - CAssetWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - Qt::Horizontal - - - - 1028 - 20 - - - - - - - - 添加 - - - - - - - 删除 - - - - - - - 导入 - - - - - - - 导出 - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - 0 - - - - - Qt::Horizontal - - - 4 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 位置/设备组 - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - 0 - - - - - 6 - - - - - 设备组 - - - - - - - - - - 关键字 - - - - - - - - - - 查询 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - 0 - 0 - - - - - - - 设备管理 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - CAssetView - QTableView -
CAssetView.h
-
-
- - -
+ + + CAssetWidget + + + + 0 + 0 + 1375 + 586 + + + + CAssetWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Horizontal + + + + 1028 + 20 + + + + + + + + 添加 + + + + + + + 删除 + + + + + + + 导入 + + + + + + + 导出 + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + 0 + + + + + Qt::Horizontal + + + 4 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 位置/设备组 + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + 0 + + + + + 6 + + + + + 设备组 + + + + + + + + + + 关键字 + + + + + + + + + + 查询 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + 0 + 0 + + + + + + + 设备管理 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + CAssetView + QTableView +
CAssetView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/AssetWidget/CPropertyDialog.cpp b/product/src/gui/plugin/AssetWidget/CPropertyDialog.cpp index 98d07905..3dcf879c 100644 --- a/product/src/gui/plugin/AssetWidget/CPropertyDialog.cpp +++ b/product/src/gui/plugin/AssetWidget/CPropertyDialog.cpp @@ -1,198 +1,198 @@ -#include "CPropertyDialog.h" -#include "ui_CPropertyDialog.h" -#include "CAssetDataMng.h" -#include -#include -#include "Common.h" -#include -#include "pub_utility_api/FileStyle.h" -CPropertyDialog::CPropertyDialog(int mode, int loc, QString devg, QWidget *parent) : - QDialog(parent), - ui(new Ui::CPropertyDialog), - m_mode(mode), - m_loc(loc), - m_devg(devg) -{ - ui->setupUi(this); - this->setWindowTitle(tr("添加")); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("asset.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - else - { - qDebug() << "asset.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - initView(); - connect(ui->ok,&QPushButton::clicked,this,&CPropertyDialog::okClicked); - connect(ui->cancel,&QPushButton::clicked,this,&CPropertyDialog::cancelClicked); -} - -CPropertyDialog::~CPropertyDialog() -{ - delete ui; -} - -void CPropertyDialog::initView() -{ - ui->cStatus->setView(new QListView()); - ui->cDevG->setView(new QListView()); - ui->dDate->setDate(QDate::currentDate()); - ui->cStatus->clear(); - ui->cStatus->setEditable(true); - ui->cStatus->setMaxVisibleItems(10); - QList statusList = CAssetDataMng::instance()->getStatus(); - for(int index(0);indexcStatus->addItem(statusList[index]); - } - if(ui->cStatus->count() == 0) - { - ui->cStatus->addItem(tr("已启用")); - } - ui->cDevG->clear(); - ui->cDevG->setEditable(true); - ui->cDevG->setMaxVisibleItems(10); - QMap devgMap = CAssetDataMng::instance()->readDevgByLoc(m_loc); - QMap::iterator it= devgMap.begin(); - while (it != devgMap.end()) { - ui->cDevG->addItem(it.value(),it.key()); - it++; - } - - ui->cPeriod->addItem(tr("一个月"),1); - ui->cPeriod->addItem(tr("三个月"),3); - ui->cPeriod->addItem(tr("半年"),6); - ui->cPeriod->addItem(tr("一年"),12); - - if(!m_devg.isEmpty()) - { - for(int index(0);indexcDevG->count();index++) - { - if(ui->cDevG->itemData(index).toString() == m_devg) - { - ui->cDevG->setCurrentIndex(index); - break; - } - } - } -} - -void CPropertyDialog::init(AssetInfo &info) -{ - this->setWindowTitle(tr("编辑")); - m_assetInfo = info; - ui->lName->setText(m_assetInfo.name); - ui->lType->setText(m_assetInfo.type); - ui->lParam->setText(m_assetInfo.param); - ui->dDate->setDate(QDate::fromString(QString::number(m_assetInfo.setUpTime),"yyyyMMdd")); - for(int index(0);indexcStatus->count();index++) - { - if(ui->cStatus->itemText(index)==m_assetInfo.status) - { - ui->cStatus->setCurrentIndex(index); - break; - } - } - - ui->lContact->setText(m_assetInfo.contact); - - for(int index(0);indexcPeriod->count();index++) - { - if(ui->cPeriod->itemData(index).toInt()==m_assetInfo.maintain_period) - { - ui->cPeriod->setCurrentIndex(index); - break; - } - } - - if(!m_assetInfo.dev_group.isEmpty()) - { - for(int index(0);indexcDevG->count();index++) - { - if(ui->cDevG->itemData(index).toString() == m_assetInfo.dev_group) - { - ui->cDevG->setCurrentIndex(index); - break; - } - } - } - ui->tBackup->setText(m_assetInfo.backup); -} - -void CPropertyDialog::messBox(const QString &mess) -{ - QMessageBox::information(this, tr("提示"), mess, QMessageBox::Ok); -} - -void CPropertyDialog::okClicked() -{ - m_assetInfo.name = ui->lName->text(); - if(m_assetInfo.name.isEmpty()) - { - messBox(tr("设备名称不能为空!")); - return ; - } - m_assetInfo.type = ui->lType->text(); - - m_assetInfo.param = ui->lParam->text(); - m_assetInfo.setUpTime = ui->dDate->date().toString("yyyyMMdd").toLongLong(); - m_assetInfo.status = ui->cStatus->lineEdit()->text(); - m_assetInfo.contact = ui->lContact->text(); - m_assetInfo.maintain_period = ui->cPeriod->currentData().toInt(); - m_assetInfo.dev_group = ui->cDevG->currentData().toString(); - m_assetInfo.backup = ui->tBackup->toPlainText(); - - if(save() == kbdSuccess) - { - accept(); - }else - { - messBox(tr("操作失败,请重新操作!")); - } -} - -void CPropertyDialog::cancelClicked() -{ - reject(); -} - -int CPropertyDialog::save() -{ - if(m_mode == EN_Property_Add) - { - return CAssetDataMng::instance()->addAsset(m_assetInfo); - }else - { - return CAssetDataMng::instance()->updateAsset(m_assetInfo); - } - return kbdFailed; -} +#include "CPropertyDialog.h" +#include "ui_CPropertyDialog.h" +#include "CAssetDataMng.h" +#include +#include +#include "Common.h" +#include +#include "pub_utility_api/FileStyle.h" +CPropertyDialog::CPropertyDialog(int mode, int loc, QString devg, QWidget *parent) : + QDialog(parent), + ui(new Ui::CPropertyDialog), + m_mode(mode), + m_loc(loc), + m_devg(devg) +{ + ui->setupUi(this); + this->setWindowTitle(tr("添加")); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("asset.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + else + { + qDebug() << "asset.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + initView(); + connect(ui->ok,&QPushButton::clicked,this,&CPropertyDialog::okClicked); + connect(ui->cancel,&QPushButton::clicked,this,&CPropertyDialog::cancelClicked); +} + +CPropertyDialog::~CPropertyDialog() +{ + delete ui; +} + +void CPropertyDialog::initView() +{ + ui->cStatus->setView(new QListView()); + ui->cDevG->setView(new QListView()); + ui->dDate->setDate(QDate::currentDate()); + ui->cStatus->clear(); + ui->cStatus->setEditable(true); + ui->cStatus->setMaxVisibleItems(10); + QList statusList = CAssetDataMng::instance()->getStatus(); + for(int index(0);indexcStatus->addItem(statusList[index]); + } + if(ui->cStatus->count() == 0) + { + ui->cStatus->addItem(tr("已启用")); + } + ui->cDevG->clear(); + ui->cDevG->setEditable(true); + ui->cDevG->setMaxVisibleItems(10); + QMap devgMap = CAssetDataMng::instance()->readDevgByLoc(m_loc); + QMap::iterator it= devgMap.begin(); + while (it != devgMap.end()) { + ui->cDevG->addItem(it.value(),it.key()); + it++; + } + + ui->cPeriod->addItem(tr("一个月"),1); + ui->cPeriod->addItem(tr("三个月"),3); + ui->cPeriod->addItem(tr("半年"),6); + ui->cPeriod->addItem(tr("一年"),12); + + if(!m_devg.isEmpty()) + { + for(int index(0);indexcDevG->count();index++) + { + if(ui->cDevG->itemData(index).toString() == m_devg) + { + ui->cDevG->setCurrentIndex(index); + break; + } + } + } +} + +void CPropertyDialog::init(AssetInfo &info) +{ + this->setWindowTitle(tr("编辑")); + m_assetInfo = info; + ui->lName->setText(m_assetInfo.name); + ui->lType->setText(m_assetInfo.type); + ui->lParam->setText(m_assetInfo.param); + ui->dDate->setDate(QDate::fromString(QString::number(m_assetInfo.setUpTime),"yyyyMMdd")); + for(int index(0);indexcStatus->count();index++) + { + if(ui->cStatus->itemText(index)==m_assetInfo.status) + { + ui->cStatus->setCurrentIndex(index); + break; + } + } + + ui->lContact->setText(m_assetInfo.contact); + + for(int index(0);indexcPeriod->count();index++) + { + if(ui->cPeriod->itemData(index).toInt()==m_assetInfo.maintain_period) + { + ui->cPeriod->setCurrentIndex(index); + break; + } + } + + if(!m_assetInfo.dev_group.isEmpty()) + { + for(int index(0);indexcDevG->count();index++) + { + if(ui->cDevG->itemData(index).toString() == m_assetInfo.dev_group) + { + ui->cDevG->setCurrentIndex(index); + break; + } + } + } + ui->tBackup->setText(m_assetInfo.backup); +} + +void CPropertyDialog::messBox(const QString &mess) +{ + QMessageBox::information(this, tr("提示"), mess, QMessageBox::Ok); +} + +void CPropertyDialog::okClicked() +{ + m_assetInfo.name = ui->lName->text(); + if(m_assetInfo.name.isEmpty()) + { + messBox(tr("设备名称不能为空!")); + return ; + } + m_assetInfo.type = ui->lType->text(); + + m_assetInfo.param = ui->lParam->text(); + m_assetInfo.setUpTime = ui->dDate->date().toString("yyyyMMdd").toLongLong(); + m_assetInfo.status = ui->cStatus->lineEdit()->text(); + m_assetInfo.contact = ui->lContact->text(); + m_assetInfo.maintain_period = ui->cPeriod->currentData().toInt(); + m_assetInfo.dev_group = ui->cDevG->currentData().toString(); + m_assetInfo.backup = ui->tBackup->toPlainText(); + + if(save() == kbdSuccess) + { + accept(); + }else + { + messBox(tr("操作失败,请重新操作!")); + } +} + +void CPropertyDialog::cancelClicked() +{ + reject(); +} + +int CPropertyDialog::save() +{ + if(m_mode == EN_Property_Add) + { + return CAssetDataMng::instance()->addAsset(m_assetInfo); + }else + { + return CAssetDataMng::instance()->updateAsset(m_assetInfo); + } + return kbdFailed; +} diff --git a/product/src/gui/plugin/AssetWidget/CPropertyDialog.h b/product/src/gui/plugin/AssetWidget/CPropertyDialog.h index a79763f8..e8579153 100644 --- a/product/src/gui/plugin/AssetWidget/CPropertyDialog.h +++ b/product/src/gui/plugin/AssetWidget/CPropertyDialog.h @@ -1,42 +1,42 @@ -#ifndef CPROPERTYDIALOG_H -#define CPROPERTYDIALOG_H - -#include -#include "CAssetCommon.h" -namespace Ui { -class CPropertyDialog; -} - -class CPropertyDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CPropertyDialog(int mode, int loc,QString devg, QWidget *parent = nullptr); - ~CPropertyDialog(); - - void initView(); - void init(AssetInfo &info); - - void messBox(const QString &mess); - -private slots: - - void okClicked(); - - void cancelClicked(); - -private: - int save(); - -private: - Ui::CPropertyDialog *ui; - - int m_mode; - AssetInfo m_assetInfo; - - int m_loc; - QString m_devg; -}; - -#endif // CPROPERTYDIALOG_H +#ifndef CPROPERTYDIALOG_H +#define CPROPERTYDIALOG_H + +#include +#include "CAssetCommon.h" +namespace Ui { +class CPropertyDialog; +} + +class CPropertyDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CPropertyDialog(int mode, int loc,QString devg, QWidget *parent = nullptr); + ~CPropertyDialog(); + + void initView(); + void init(AssetInfo &info); + + void messBox(const QString &mess); + +private slots: + + void okClicked(); + + void cancelClicked(); + +private: + int save(); + +private: + Ui::CPropertyDialog *ui; + + int m_mode; + AssetInfo m_assetInfo; + + int m_loc; + QString m_devg; +}; + +#endif // CPROPERTYDIALOG_H diff --git a/product/src/gui/plugin/AssetWidget/CPropertyDialog.ui b/product/src/gui/plugin/AssetWidget/CPropertyDialog.ui index 2e5e3146..0990d7b1 100644 --- a/product/src/gui/plugin/AssetWidget/CPropertyDialog.ui +++ b/product/src/gui/plugin/AssetWidget/CPropertyDialog.ui @@ -1,157 +1,157 @@ - - - CPropertyDialog - - - - 0 - 0 - 366 - 438 - - - - Dialog - - - - - - - - 安装日期 - - - - - - - 型号 - - - - - - - 备注 - - - - - - - - - - 参数 - - - - - - - - - - 设备名称 - - - - - - - - - - - - - 维护周期 - - - - - - - yyyy-MM-dd - - - - 2021 - 1 - 1 - - - - - - - - 厂家联系方式 - - - - - - - - - - - - - - - - 所属设备组 - - - - - - - 状态 - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - - - - + + + CPropertyDialog + + + + 0 + 0 + 366 + 438 + + + + Dialog + + + + + + + + 安装日期 + + + + + + + 型号 + + + + + + + 备注 + + + + + + + + + + 参数 + + + + + + + + + + 设备名称 + + + + + + + + + + + + + 维护周期 + + + + + + + yyyy-MM-dd + + + + 2021 + 1 + 1 + + + + + + + + 厂家联系方式 + + + + + + + + + + + + + + + + 所属设备组 + + + + + + + 状态 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + + + + diff --git a/product/src/gui/plugin/AssetWidget/CRecordDialog.cpp b/product/src/gui/plugin/AssetWidget/CRecordDialog.cpp index f1eb1952..64a7ec10 100644 --- a/product/src/gui/plugin/AssetWidget/CRecordDialog.cpp +++ b/product/src/gui/plugin/AssetWidget/CRecordDialog.cpp @@ -1,297 +1,297 @@ -#include "CRecordDialog.h" -#include "ui_CRecordDialog.h" -#include -#include "CAssetDataMng.h" -#include "CRecordPropertyDialog.h" -#include "Common.h" -#include -#include "pub_utility_api/FileStyle.h" - -CRecordDialog::CRecordDialog(int mode, AssetInfo info, QWidget *parent) : - QDialog(parent), - ui(new Ui::CRecordDialog), - m_mode(mode), - m_info(info), - m_pModel(Q_NULLPTR), - m_thread(Q_NULLPTR), - m_worker(Q_NULLPTR) -{ - ui->setupUi(this); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("asset.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - else - { - qDebug() << "asset.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - initUi(); - - m_thread = new QThread(); - m_worker = new CWorker(); - m_worker->moveToThread(m_thread); - connect(this,&CRecordDialog::sigExportRecord,m_worker,&CWorker::slotExportRecord,Qt::QueuedConnection); - - connect(m_worker,&CWorker::sigExportEnd,this,&CRecordDialog::slotExportEnd,Qt::QueuedConnection); - - m_thread->start(); - - brush(); -} - -CRecordDialog::~CRecordDialog() -{ - if(m_pModel) - { - delete m_pModel; - } - m_pModel = Q_NULLPTR; - - delete ui; -} - -void CRecordDialog::initUi() -{ - ui->dStartDate->setToolTip(tr("对开始时间和结束时间日期生效")); - ui->dEndDate->setToolTip(tr("对开始时间和结束时间日期生效")); - ui->lKey->setToolTip(tr("对设备名称、记录名称、操作人和维护内容生效")); - QString title = tr("%1 维护记录").arg(m_info.name); - this->setWindowTitle(title); - if(m_pModel == Q_NULLPTR) - { - m_pModel = new CRecordTablModel(); - ui->tableView->setModel(m_pModel); - ui->tableView->setColumnWidth(0, 180); - ui->tableView->setColumnWidth(1, 180); - ui->tableView->setColumnWidth(2, 180); - ui->tableView->setColumnWidth(3, 180); - ui->tableView->setColumnWidth(4, 150); - ui->tableView->setColumnWidth(5, 120); - ui->tableView->setColumnWidth(6, 180); - ui->tableView->setColumnWidth(7, 120); - } - ui->dStartDate->setDate(QDate::currentDate().addDays(-30)); - ui->dEndDate->setDate(QDate::currentDate()); - connect(ui->bAdd,&QPushButton::clicked,this,&CRecordDialog::addRecord); - connect(ui->bDel,&QPushButton::clicked,this,&CRecordDialog::delRecord); - connect(ui->bOut,&QPushButton::clicked,this,&CRecordDialog::outRecord); - connect(ui->bSearch,&QPushButton::clicked,this,&CRecordDialog::searchRecord); - connect(ui->tableView,&CAssetView::doubleClicked,this,&CRecordDialog::recordDoubleClicked); -} - -void CRecordDialog::addRecord() -{ - CRecordPropertyDialog dlg(EN_Property_Add,m_info); - if(dlg.exec() == QDialog::Accepted) - { - brush(); - messBox("添加成功!"); - } -} - -void CRecordDialog::delRecord() -{ - QModelIndexList modelIndexList = ui->tableView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList listInfo = m_pModel->getListShowInfo(); - QList idList; - QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); - for(;modelIndexIter != modelIndexList.end();modelIndexIter++) - { - idList.append(listInfo.at(modelIndexIter->row()).id); - } - if(idList.isEmpty()) - { - return ; - } - if(CAssetDataMng::instance()->delRecord(idList) == kbdFailed) - { - messBox(tr("删除失败!")); - }else - { - brush(); - messBox(tr("删除成功!")); - } -} - -void CRecordDialog::outRecord() -{ - QString fileName= QString(); - if(kbdSuccess !=getFileName(fileName)) - { - return ; - } - QList idList; - - idList.append(m_info.id); - - if(idList.isEmpty()) - { - return ; - } - QList recordList = m_pModel->getListShowInfo(); - - emit sigExportRecord(fileName,recordList); -} - -void CRecordDialog::searchRecord() -{ - qint64 startDate = ui->dStartDate->date().toString("yyyyMMdd").toLongLong(); - qint64 endDate = ui->dEndDate->date().toString("yyyyMMdd").toLongLong(); - if(startDate>endDate) - { - messBox(tr("开始时间不能大于结束时间!")); - return ; - } - brush(); -} - -void CRecordDialog::recordDoubleClicked(const QModelIndex &index) -{ - if(m_pModel == Q_NULLPTR) - { - return ; - } - - if(!index.isValid()) - { - return ; - } - AssetRecord info; - if(m_pModel->getRecordInfo(index,info) != kbdSuccess) - { - return ; - } - CRecordPropertyDialog dlg(EN_Property_Edit,m_info); - dlg.init(info); - if(dlg.exec() == QDialog::Accepted) - { - brush(); - messBox("编辑成功!"); - } -} - -void CRecordDialog::slotExportEnd(const QString &result) -{ - messBox(result); -} - -void CRecordDialog::brush() -{ - QList recordList; - m_pModel->updateData(recordList); - if(m_info.id <0 ) - { - return ; - } - - recordList = CAssetDataMng::instance()->getRecordInfoByDevId(m_info.id); - filterText(recordList); - filterTime(recordList); - - m_pModel->updateData(recordList); -} - -void CRecordDialog::messBox(const QString &mess) -{ - QMessageBox::information(this, tr("提示"), mess, QMessageBox::Ok); -} - -void CRecordDialog::filterText(QList &recordList) -{ - QString filterText =ui->lKey->text(); - if(!filterText.isEmpty()) - { - QList::iterator it = recordList.begin(); - while (it != recordList.end()) { - - if(!containsFilterText(*it,filterText)) - { - it = recordList.erase(it); - }else - { - it++; - } - } - } -} - -void CRecordDialog::filterTime(QList &recordList) -{ - qint64 startDate = ui->dStartDate->date().toString("yyyyMMdd").toLongLong(); - qint64 endDate = ui->dEndDate->date().toString("yyyyMMdd").toLongLong(); - QList::iterator it = recordList.begin(); - while (it != recordList.end()) { - - if(it->startTime< startDate || it->endTime > endDate ) - { - it = recordList.erase(it); - }else - { - it++; - } - } -} - -bool CRecordDialog::containsFilterText(const AssetRecord &record, const QString &filterText) -{ - if(record.dev_name.contains(filterText)) - { - return true; - } - if(record.opt_user.contains(filterText)) - { - return true; - } - if(record.record_name.contains(filterText)) - { - return true; - } - if(record.content.contains(filterText)) - { - return true; - } - return false; -} - -int CRecordDialog::getFileName(QString &fileName) -{ - fileName = QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xlsx)");//获取保存路径*.xls - if(fileName.isEmpty()) - { - return kbdFailed; - } - if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) - { - fileName = fileName+".xlsx"; - } - return kbdSuccess; -} +#include "CRecordDialog.h" +#include "ui_CRecordDialog.h" +#include +#include "CAssetDataMng.h" +#include "CRecordPropertyDialog.h" +#include "Common.h" +#include +#include "pub_utility_api/FileStyle.h" + +CRecordDialog::CRecordDialog(int mode, AssetInfo info, QWidget *parent) : + QDialog(parent), + ui(new Ui::CRecordDialog), + m_mode(mode), + m_info(info), + m_pModel(Q_NULLPTR), + m_thread(Q_NULLPTR), + m_worker(Q_NULLPTR) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("asset.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + else + { + qDebug() << "asset.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + initUi(); + + m_thread = new QThread(); + m_worker = new CWorker(); + m_worker->moveToThread(m_thread); + connect(this,&CRecordDialog::sigExportRecord,m_worker,&CWorker::slotExportRecord,Qt::QueuedConnection); + + connect(m_worker,&CWorker::sigExportEnd,this,&CRecordDialog::slotExportEnd,Qt::QueuedConnection); + + m_thread->start(); + + brush(); +} + +CRecordDialog::~CRecordDialog() +{ + if(m_pModel) + { + delete m_pModel; + } + m_pModel = Q_NULLPTR; + + delete ui; +} + +void CRecordDialog::initUi() +{ + ui->dStartDate->setToolTip(tr("对开始时间和结束时间日期生效")); + ui->dEndDate->setToolTip(tr("对开始时间和结束时间日期生效")); + ui->lKey->setToolTip(tr("对设备名称、记录名称、操作人和维护内容生效")); + QString title = tr("%1 维护记录").arg(m_info.name); + this->setWindowTitle(title); + if(m_pModel == Q_NULLPTR) + { + m_pModel = new CRecordTablModel(); + ui->tableView->setModel(m_pModel); + ui->tableView->setColumnWidth(0, 180); + ui->tableView->setColumnWidth(1, 180); + ui->tableView->setColumnWidth(2, 180); + ui->tableView->setColumnWidth(3, 180); + ui->tableView->setColumnWidth(4, 150); + ui->tableView->setColumnWidth(5, 120); + ui->tableView->setColumnWidth(6, 180); + ui->tableView->setColumnWidth(7, 120); + } + ui->dStartDate->setDate(QDate::currentDate().addDays(-30)); + ui->dEndDate->setDate(QDate::currentDate()); + connect(ui->bAdd,&QPushButton::clicked,this,&CRecordDialog::addRecord); + connect(ui->bDel,&QPushButton::clicked,this,&CRecordDialog::delRecord); + connect(ui->bOut,&QPushButton::clicked,this,&CRecordDialog::outRecord); + connect(ui->bSearch,&QPushButton::clicked,this,&CRecordDialog::searchRecord); + connect(ui->tableView,&CAssetView::doubleClicked,this,&CRecordDialog::recordDoubleClicked); +} + +void CRecordDialog::addRecord() +{ + CRecordPropertyDialog dlg(EN_Property_Add,m_info); + if(dlg.exec() == QDialog::Accepted) + { + brush(); + messBox("添加成功!"); + } +} + +void CRecordDialog::delRecord() +{ + QModelIndexList modelIndexList = ui->tableView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList listInfo = m_pModel->getListShowInfo(); + QList idList; + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + idList.append(listInfo.at(modelIndexIter->row()).id); + } + if(idList.isEmpty()) + { + return ; + } + if(CAssetDataMng::instance()->delRecord(idList) == kbdFailed) + { + messBox(tr("删除失败!")); + }else + { + brush(); + messBox(tr("删除成功!")); + } +} + +void CRecordDialog::outRecord() +{ + QString fileName= QString(); + if(kbdSuccess !=getFileName(fileName)) + { + return ; + } + QList idList; + + idList.append(m_info.id); + + if(idList.isEmpty()) + { + return ; + } + QList recordList = m_pModel->getListShowInfo(); + + emit sigExportRecord(fileName,recordList); +} + +void CRecordDialog::searchRecord() +{ + qint64 startDate = ui->dStartDate->date().toString("yyyyMMdd").toLongLong(); + qint64 endDate = ui->dEndDate->date().toString("yyyyMMdd").toLongLong(); + if(startDate>endDate) + { + messBox(tr("开始时间不能大于结束时间!")); + return ; + } + brush(); +} + +void CRecordDialog::recordDoubleClicked(const QModelIndex &index) +{ + if(m_pModel == Q_NULLPTR) + { + return ; + } + + if(!index.isValid()) + { + return ; + } + AssetRecord info; + if(m_pModel->getRecordInfo(index,info) != kbdSuccess) + { + return ; + } + CRecordPropertyDialog dlg(EN_Property_Edit,m_info); + dlg.init(info); + if(dlg.exec() == QDialog::Accepted) + { + brush(); + messBox("编辑成功!"); + } +} + +void CRecordDialog::slotExportEnd(const QString &result) +{ + messBox(result); +} + +void CRecordDialog::brush() +{ + QList recordList; + m_pModel->updateData(recordList); + if(m_info.id <0 ) + { + return ; + } + + recordList = CAssetDataMng::instance()->getRecordInfoByDevId(m_info.id); + filterText(recordList); + filterTime(recordList); + + m_pModel->updateData(recordList); +} + +void CRecordDialog::messBox(const QString &mess) +{ + QMessageBox::information(this, tr("提示"), mess, QMessageBox::Ok); +} + +void CRecordDialog::filterText(QList &recordList) +{ + QString filterText =ui->lKey->text(); + if(!filterText.isEmpty()) + { + QList::iterator it = recordList.begin(); + while (it != recordList.end()) { + + if(!containsFilterText(*it,filterText)) + { + it = recordList.erase(it); + }else + { + it++; + } + } + } +} + +void CRecordDialog::filterTime(QList &recordList) +{ + qint64 startDate = ui->dStartDate->date().toString("yyyyMMdd").toLongLong(); + qint64 endDate = ui->dEndDate->date().toString("yyyyMMdd").toLongLong(); + QList::iterator it = recordList.begin(); + while (it != recordList.end()) { + + if(it->startTime< startDate || it->endTime > endDate ) + { + it = recordList.erase(it); + }else + { + it++; + } + } +} + +bool CRecordDialog::containsFilterText(const AssetRecord &record, const QString &filterText) +{ + if(record.dev_name.contains(filterText)) + { + return true; + } + if(record.opt_user.contains(filterText)) + { + return true; + } + if(record.record_name.contains(filterText)) + { + return true; + } + if(record.content.contains(filterText)) + { + return true; + } + return false; +} + +int CRecordDialog::getFileName(QString &fileName) +{ + fileName = QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xlsx)");//获取保存路径*.xls + if(fileName.isEmpty()) + { + return kbdFailed; + } + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + { + fileName = fileName+".xlsx"; + } + return kbdSuccess; +} diff --git a/product/src/gui/plugin/AssetWidget/CRecordDialog.h b/product/src/gui/plugin/AssetWidget/CRecordDialog.h index 92336034..fa54cd5f 100644 --- a/product/src/gui/plugin/AssetWidget/CRecordDialog.h +++ b/product/src/gui/plugin/AssetWidget/CRecordDialog.h @@ -1,65 +1,65 @@ -#ifndef CRECORDDIALOG_H -#define CRECORDDIALOG_H - -#include -#include "CRecordTablModel.h" -#include "CAssetCommon.h" -#include "CWorker.h" -namespace Ui { -class CRecordDialog; -} - -class CRecordDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CRecordDialog(int mode, AssetInfo info, QWidget *parent = nullptr); - ~CRecordDialog(); - - void initUi(); - -signals: - void sigExportRecord(const QString &fileName,const QList &recordList); - -private slots: - - void addRecord(); - - void delRecord(); - - void outRecord(); - - void searchRecord(); - - void recordDoubleClicked(const QModelIndex &index); - -public slots: - void slotExportEnd(const QString &result); - -private: - void brush(); - - void messBox(const QString &mess); - - - void filterText(QList &recordList); - - void filterTime(QList &recordList); - - bool containsFilterText(const AssetRecord &record, const QString &filterText); - - int getFileName(QString &fileName); - -private: - Ui::CRecordDialog *ui; - int m_mode; - AssetInfo m_info; - - CRecordTablModel *m_pModel; - - QThread *m_thread; - CWorker *m_worker; -}; - -#endif // CRECORDDIALOG_H +#ifndef CRECORDDIALOG_H +#define CRECORDDIALOG_H + +#include +#include "CRecordTablModel.h" +#include "CAssetCommon.h" +#include "CWorker.h" +namespace Ui { +class CRecordDialog; +} + +class CRecordDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CRecordDialog(int mode, AssetInfo info, QWidget *parent = nullptr); + ~CRecordDialog(); + + void initUi(); + +signals: + void sigExportRecord(const QString &fileName,const QList &recordList); + +private slots: + + void addRecord(); + + void delRecord(); + + void outRecord(); + + void searchRecord(); + + void recordDoubleClicked(const QModelIndex &index); + +public slots: + void slotExportEnd(const QString &result); + +private: + void brush(); + + void messBox(const QString &mess); + + + void filterText(QList &recordList); + + void filterTime(QList &recordList); + + bool containsFilterText(const AssetRecord &record, const QString &filterText); + + int getFileName(QString &fileName); + +private: + Ui::CRecordDialog *ui; + int m_mode; + AssetInfo m_info; + + CRecordTablModel *m_pModel; + + QThread *m_thread; + CWorker *m_worker; +}; + +#endif // CRECORDDIALOG_H diff --git a/product/src/gui/plugin/AssetWidget/CRecordDialog.ui b/product/src/gui/plugin/AssetWidget/CRecordDialog.ui index 3200cad5..b5f43caf 100644 --- a/product/src/gui/plugin/AssetWidget/CRecordDialog.ui +++ b/product/src/gui/plugin/AssetWidget/CRecordDialog.ui @@ -1,119 +1,119 @@ - - - CRecordDialog - - - - 0 - 0 - 1156 - 507 - - - - Dialog - - - - - - 导出 - - - - - - - 删除 - - - - - - - 添加 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 时间 - - - - - - - - - - ~ - - - - - - - - - - 关键字 - - - - - - - - - - 查询 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - CAssetView - QTableView -
CAssetView.h
-
-
- - -
+ + + CRecordDialog + + + + 0 + 0 + 1156 + 507 + + + + Dialog + + + + + + 导出 + + + + + + + 删除 + + + + + + + 添加 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 时间 + + + + + + + + + + ~ + + + + + + + + + + 关键字 + + + + + + + + + + 查询 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + CAssetView + QTableView +
CAssetView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.cpp b/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.cpp index 12891d7f..229346c3 100644 --- a/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.cpp +++ b/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.cpp @@ -1,125 +1,125 @@ -#include "CRecordPropertyDialog.h" -#include "ui_CRecordPropertyDialog.h" -#include -#include "Common.h" -#include "CAssetDataMng.h" -#include "pub_utility_api/FileStyle.h" -CRecordPropertyDialog::CRecordPropertyDialog(int mode, const AssetInfo &assetInfo, QWidget *parent) : - QDialog(parent), - ui(new Ui::CRecordPropertyDialog), - m_mode(mode), - m_assetInfo(assetInfo) -{ - ui->setupUi(this); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("asset.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - else - { - qDebug() << "asset.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - this->setWindowTitle(tr("添加")); - initView(); - connect(ui->ok,&QPushButton::clicked,this,&CRecordPropertyDialog::okClicked); - connect(ui->cancel,&QPushButton::clicked,this,&CRecordPropertyDialog::cancelClicked); -} - -CRecordPropertyDialog::~CRecordPropertyDialog() -{ - delete ui; -} - -void CRecordPropertyDialog::initView() -{ - ui->dStartDate->setDate(QDate::currentDate()); - ui->dEndDate->setDate(QDate::currentDate()); -} - -void CRecordPropertyDialog::init(AssetRecord &info) -{ - this->setWindowTitle(tr("编辑")); - m_assetRecord = info; - ui->lName->setText(m_assetRecord.record_name); - ui->lUser->setText(m_assetRecord.opt_user); - - ui->dStartDate->setDate(QDate::fromString(QString::number(m_assetRecord.startTime),"yyyyMMdd")); - ui->dEndDate->setDate(QDate::fromString(QString::number(m_assetRecord.endTime),"yyyyMMdd")); - ui->tContent->setText(m_assetRecord.content); - -} - -void CRecordPropertyDialog::messBox(const QString &mess) -{ - QMessageBox::information(this, tr("提示"), mess, QMessageBox::Ok); -} - -void CRecordPropertyDialog::okClicked() -{ - m_assetRecord.dev_id = m_assetInfo.id; - m_assetRecord.record_name = ui->lName->text(); - if(m_assetRecord.record_name.isEmpty()) - { - messBox(tr("记录名称不能为空!")); - return ; - } - m_assetRecord.opt_user = ui->lUser->text(); - - m_assetRecord.startTime = ui->dStartDate->date().toString("yyyyMMdd").toLongLong(); - m_assetRecord.endTime = ui->dEndDate->date().toString("yyyyMMdd").toLongLong(); - m_assetRecord.content = ui->tContent->toPlainText(); - - if(m_assetRecord.startTime>m_assetRecord.endTime) - { - messBox(tr("开始时间不能大于结束时间!")); - return ; - } - if(save() == kbdSuccess) - { - accept(); - }else - { - messBox(tr("操作失败,请重新操作!")); - } -} - -void CRecordPropertyDialog::cancelClicked() -{ - reject(); -} - -int CRecordPropertyDialog::save() -{ - if(m_mode == EN_Property_Add) - { - return CAssetDataMng::instance()->addRecord(m_assetRecord); - }else - { - return CAssetDataMng::instance()->updateRecord(m_assetRecord); - } - return kbdFailed; -} +#include "CRecordPropertyDialog.h" +#include "ui_CRecordPropertyDialog.h" +#include +#include "Common.h" +#include "CAssetDataMng.h" +#include "pub_utility_api/FileStyle.h" +CRecordPropertyDialog::CRecordPropertyDialog(int mode, const AssetInfo &assetInfo, QWidget *parent) : + QDialog(parent), + ui(new Ui::CRecordPropertyDialog), + m_mode(mode), + m_assetInfo(assetInfo) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("asset.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + else + { + qDebug() << "asset.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + this->setWindowTitle(tr("添加")); + initView(); + connect(ui->ok,&QPushButton::clicked,this,&CRecordPropertyDialog::okClicked); + connect(ui->cancel,&QPushButton::clicked,this,&CRecordPropertyDialog::cancelClicked); +} + +CRecordPropertyDialog::~CRecordPropertyDialog() +{ + delete ui; +} + +void CRecordPropertyDialog::initView() +{ + ui->dStartDate->setDate(QDate::currentDate()); + ui->dEndDate->setDate(QDate::currentDate()); +} + +void CRecordPropertyDialog::init(AssetRecord &info) +{ + this->setWindowTitle(tr("编辑")); + m_assetRecord = info; + ui->lName->setText(m_assetRecord.record_name); + ui->lUser->setText(m_assetRecord.opt_user); + + ui->dStartDate->setDate(QDate::fromString(QString::number(m_assetRecord.startTime),"yyyyMMdd")); + ui->dEndDate->setDate(QDate::fromString(QString::number(m_assetRecord.endTime),"yyyyMMdd")); + ui->tContent->setText(m_assetRecord.content); + +} + +void CRecordPropertyDialog::messBox(const QString &mess) +{ + QMessageBox::information(this, tr("提示"), mess, QMessageBox::Ok); +} + +void CRecordPropertyDialog::okClicked() +{ + m_assetRecord.dev_id = m_assetInfo.id; + m_assetRecord.record_name = ui->lName->text(); + if(m_assetRecord.record_name.isEmpty()) + { + messBox(tr("记录名称不能为空!")); + return ; + } + m_assetRecord.opt_user = ui->lUser->text(); + + m_assetRecord.startTime = ui->dStartDate->date().toString("yyyyMMdd").toLongLong(); + m_assetRecord.endTime = ui->dEndDate->date().toString("yyyyMMdd").toLongLong(); + m_assetRecord.content = ui->tContent->toPlainText(); + + if(m_assetRecord.startTime>m_assetRecord.endTime) + { + messBox(tr("开始时间不能大于结束时间!")); + return ; + } + if(save() == kbdSuccess) + { + accept(); + }else + { + messBox(tr("操作失败,请重新操作!")); + } +} + +void CRecordPropertyDialog::cancelClicked() +{ + reject(); +} + +int CRecordPropertyDialog::save() +{ + if(m_mode == EN_Property_Add) + { + return CAssetDataMng::instance()->addRecord(m_assetRecord); + }else + { + return CAssetDataMng::instance()->updateRecord(m_assetRecord); + } + return kbdFailed; +} diff --git a/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.h b/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.h index 2c0abde0..80140b22 100644 --- a/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.h +++ b/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.h @@ -1,42 +1,42 @@ -#ifndef CRECORDPROPERTYDIALOG_H -#define CRECORDPROPERTYDIALOG_H - -#include -#include "CAssetCommon.h" - -namespace Ui { -class CRecordPropertyDialog; -} - -class CRecordPropertyDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CRecordPropertyDialog(int mode,const AssetInfo &assetInfo,QWidget *parent = nullptr); - ~CRecordPropertyDialog(); - - void initView(); - - void init(AssetRecord &info); - - void messBox(const QString &mess); - -private slots: - - void okClicked(); - - void cancelClicked(); - -private: - int save(); - -private: - Ui::CRecordPropertyDialog *ui; - - int m_mode; - AssetInfo m_assetInfo; - AssetRecord m_assetRecord; -}; - -#endif // CRECORDPROPERTYDIALOG_H +#ifndef CRECORDPROPERTYDIALOG_H +#define CRECORDPROPERTYDIALOG_H + +#include +#include "CAssetCommon.h" + +namespace Ui { +class CRecordPropertyDialog; +} + +class CRecordPropertyDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CRecordPropertyDialog(int mode,const AssetInfo &assetInfo,QWidget *parent = nullptr); + ~CRecordPropertyDialog(); + + void initView(); + + void init(AssetRecord &info); + + void messBox(const QString &mess); + +private slots: + + void okClicked(); + + void cancelClicked(); + +private: + int save(); + +private: + Ui::CRecordPropertyDialog *ui; + + int m_mode; + AssetInfo m_assetInfo; + AssetRecord m_assetRecord; +}; + +#endif // CRECORDPROPERTYDIALOG_H diff --git a/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.ui b/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.ui index 5e0e9677..6bdaec8d 100644 --- a/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.ui +++ b/product/src/gui/plugin/AssetWidget/CRecordPropertyDialog.ui @@ -1,128 +1,128 @@ - - - CRecordPropertyDialog - - - - 0 - 0 - 378 - 348 - - - - Dialog - - - - - - - - 维护名称 - - - - - - - - - - 维护人 - - - - - - - - - - 维护开始时间 - - - - - - - yyyy-MM-dd - - - - 2020 - 1 - 1 - - - - - - - - 维护结束时间 - - - - - - - yyyy-MM-dd - - - - 2020 - 1 - 1 - - - - - - - - 维护内容 - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - - - - + + + CRecordPropertyDialog + + + + 0 + 0 + 378 + 348 + + + + Dialog + + + + + + + + 维护名称 + + + + + + + + + + 维护人 + + + + + + + + + + 维护开始时间 + + + + + + + yyyy-MM-dd + + + + 2020 + 1 + 1 + + + + + + + + 维护结束时间 + + + + + + + yyyy-MM-dd + + + + 2020 + 1 + 1 + + + + + + + + 维护内容 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + + + + diff --git a/product/src/gui/plugin/AssetWidget/CRecordTablModel.cpp b/product/src/gui/plugin/AssetWidget/CRecordTablModel.cpp index e5bbdbd1..e6c8eb00 100644 --- a/product/src/gui/plugin/AssetWidget/CRecordTablModel.cpp +++ b/product/src/gui/plugin/AssetWidget/CRecordTablModel.cpp @@ -1,127 +1,127 @@ -#include "CRecordTablModel.h" -#include -#include "Common.h" - -CRecordTablModel::CRecordTablModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header<= m_listShowInfo.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == ASSET_BACKUP) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - - } - else if(Qt::DisplayRole == role) - { - switch ( index.column() ) - { - case RECORD_ASSET_NAME : - { - return m_listShowInfo[index.row()].dev_name; - } - case RECORD_NAME : - { - return m_listShowInfo[index.row()].record_name; - } - case RECORD_USER : - { - return m_listShowInfo[index.row()].opt_user; - } - case RECORD_STARTTIME : - { - return QDate::fromString(QString::number(m_listShowInfo[index.row()].startTime),"yyyyMMdd").toString("yyyy-MM-dd"); - } - case RECORD_ENDTIME : - { - return QDate::fromString(QString::number(m_listShowInfo[index.row()].endTime),"yyyyMMdd").toString("yyyy-MM-dd"); - } - case RECORD_CONTENT : - { - return m_listShowInfo[index.row()].content; - } - default: - break; - } - } - return QVariant(); -} - -Qt::ItemFlags CRecordTablModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -int CRecordTablModel::getRecordInfo(const QModelIndex &index, AssetRecord &info) -{ - if(index.row() < m_listShowInfo.size()) - { - info = m_listShowInfo.at(index.row()); - return kbdSuccess; - }else - { - return kbdFailed; - } -} - -void CRecordTablModel::updateData(const QList &recordList) -{ - beginResetModel(); - m_listShowInfo = recordList; - endResetModel(); -} - -QList CRecordTablModel::getListShowInfo() -{ - return m_listShowInfo; -} +#include "CRecordTablModel.h" +#include +#include "Common.h" + +CRecordTablModel::CRecordTablModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header<= m_listShowInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == ASSET_BACKUP) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + } + else if(Qt::DisplayRole == role) + { + switch ( index.column() ) + { + case RECORD_ASSET_NAME : + { + return m_listShowInfo[index.row()].dev_name; + } + case RECORD_NAME : + { + return m_listShowInfo[index.row()].record_name; + } + case RECORD_USER : + { + return m_listShowInfo[index.row()].opt_user; + } + case RECORD_STARTTIME : + { + return QDate::fromString(QString::number(m_listShowInfo[index.row()].startTime),"yyyyMMdd").toString("yyyy-MM-dd"); + } + case RECORD_ENDTIME : + { + return QDate::fromString(QString::number(m_listShowInfo[index.row()].endTime),"yyyyMMdd").toString("yyyy-MM-dd"); + } + case RECORD_CONTENT : + { + return m_listShowInfo[index.row()].content; + } + default: + break; + } + } + return QVariant(); +} + +Qt::ItemFlags CRecordTablModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +int CRecordTablModel::getRecordInfo(const QModelIndex &index, AssetRecord &info) +{ + if(index.row() < m_listShowInfo.size()) + { + info = m_listShowInfo.at(index.row()); + return kbdSuccess; + }else + { + return kbdFailed; + } +} + +void CRecordTablModel::updateData(const QList &recordList) +{ + beginResetModel(); + m_listShowInfo = recordList; + endResetModel(); +} + +QList CRecordTablModel::getListShowInfo() +{ + return m_listShowInfo; +} diff --git a/product/src/gui/plugin/AssetWidget/CRecordTablModel.h b/product/src/gui/plugin/AssetWidget/CRecordTablModel.h index 2b585279..7c4e216a 100644 --- a/product/src/gui/plugin/AssetWidget/CRecordTablModel.h +++ b/product/src/gui/plugin/AssetWidget/CRecordTablModel.h @@ -1,34 +1,34 @@ -#ifndef CRECORDTABLMODEL_H -#define CRECORDTABLMODEL_H - -#include -#include "CAssetCommon.h" - -class CRecordTablModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CRecordTablModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; - - int getRecordInfo(const QModelIndex &index, AssetRecord &info); - - void updateData(const QList & recordList); - - QList getListShowInfo(); -private: - QStringList m_header; - QList m_listShowInfo; -}; - -#endif // CRECORDTABLMODEL_H +#ifndef CRECORDTABLMODEL_H +#define CRECORDTABLMODEL_H + +#include +#include "CAssetCommon.h" + +class CRecordTablModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CRecordTablModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; + + int getRecordInfo(const QModelIndex &index, AssetRecord &info); + + void updateData(const QList & recordList); + + QList getListShowInfo(); +private: + QStringList m_header; + QList m_listShowInfo; +}; + +#endif // CRECORDTABLMODEL_H diff --git a/product/src/gui/plugin/AssetWidget/CWorker.cpp b/product/src/gui/plugin/AssetWidget/CWorker.cpp index 681fed86..3e941947 100644 --- a/product/src/gui/plugin/AssetWidget/CWorker.cpp +++ b/product/src/gui/plugin/AssetWidget/CWorker.cpp @@ -1,230 +1,230 @@ -#include "CWorker.h" -#include "model_excel/xlsx/xlsxdocument.h" -#include "model_excel/xlsx/xlsxformat.h" -#include -#include "CAssetDataMng.h" -#include "Common.h" -#include "pub_logger_api/logger.h" - -CWorker::CWorker(QObject *parent) : QObject(parent) -{ - -} - -void CWorker::slotExportAsset(const QString &fileName, const QList &assetList) -{ - QList headList; - headList< devg =CAssetDataMng::instance()->readDevg(); - for(int index(0);index &recordList) -{ - QList headList; - headList< assetList; - QMap assetMap; - int row =2; - QMap devgMap = CAssetDataMng::instance()->readDevg(); - do{ - AssetInfo info; - QString key = xlsx.read(row,ASSET_ID+1).toString(); - info.name = xlsx.read(row,ASSET_NAME+1).toString(); - info.type = xlsx.read(row,ASSET_TYPE+1).toString(); - info.param = xlsx.read(row,ASSET_PARAM+1).toString(); - info.setUpTime = QDate::fromString(xlsx.read(row,ASSET_SETUP+1).toString(),"yyyy-MM-dd").toString("yyyyMMdd").toLongLong(); - info.status = xlsx.read(row,ASSET_STATUS+1).toString(); - info.contact = xlsx.read(row,ASSET_CONTACT+1).toString(); - info.maintain_period = xlsx.read(row,ASSET_PERIOD+1).toDouble(); - info.backup = xlsx.read(row,ASSET_BACKUP+1).toString(); - info.dev_group = xlsx.read(row,ASSET_BACKUP+3).toString(); - qDebug()<importAsset(assetMap,mess2); - mess = mess1+mess2; - emit sigImportEnd(mess); - } - - file.close(); -} - -void CWorker::slotImportRecord(const QString &fileName) -{ - QString mess; - QString mess1; - QString mess2; - QFile file(fileName); - if(!file.open(QIODevice::ReadOnly)) - { - emit sigExportEnd(tr("导入维护记录失败,文件打开失败!")); - }else{ - QXlsx::Document xlsx(&file); - xlsx.selectSheet("RECORD"); - QList recordList; - QMap recordMap; - int row =2; - QMap devMap = CAssetDataMng::instance()->readDev(); - do{ - AssetRecord info; - info.id =xlsx.read(row,RECORD_ASSET_NAME+1).toString(); - info.dev_id = xlsx.read(row,RECORD_ASSET_NAME+2).toString(); - //info.dev_id = xlsx.read(row,RECORD_ASSET_NAME+1).toInt(); - - info.record_name = xlsx.read(row,RECORD_NAME+3).toString(); - info.opt_user = xlsx.read(row,RECORD_USER+3).toString(); - info.startTime = QDate::fromString(xlsx.read(row,RECORD_STARTTIME+3).toString(),"yyyy-MM-dd").toString("yyyyMMdd").toLongLong(); - info.endTime = QDate::fromString(xlsx.read(row,RECORD_ENDTIME+3).toString(),"yyyy-MM-dd").toString("yyyyMMdd").toLongLong(); - info.content = xlsx.read(row,RECORD_CONTENT+3).toString(); - if(info.id.isEmpty()) - { - break; - }else - { - if(devMap.keys().contains(info.dev_id)) - { - recordMap[info.id] = info; - recordList.append(info); - }else - { - LOGINFO("不存在标签为%s的资产,跳过!",info.dev_id.toStdString().c_str()); - mess1 = tr("部分资产不存在 "); - //mess += tr("不存在id为%1的设备,跳过!").arg(info.dev_id); - } - row++; - } - - }while (true); - CAssetDataMng::instance()->importRecord(recordMap,mess2); - - mess = mess1+mess2; - emit sigImportEnd(mess); - } - - file.close(); -} +#include "CWorker.h" +#include "model_excel/xlsx/xlsxdocument.h" +#include "model_excel/xlsx/xlsxformat.h" +#include +#include "CAssetDataMng.h" +#include "Common.h" +#include "pub_logger_api/logger.h" + +CWorker::CWorker(QObject *parent) : QObject(parent) +{ + +} + +void CWorker::slotExportAsset(const QString &fileName, const QList &assetList) +{ + QList headList; + headList< devg =CAssetDataMng::instance()->readDevg(); + for(int index(0);index &recordList) +{ + QList headList; + headList< assetList; + QMap assetMap; + int row =2; + QMap devgMap = CAssetDataMng::instance()->readDevg(); + do{ + AssetInfo info; + QString key = xlsx.read(row,ASSET_ID+1).toString(); + info.name = xlsx.read(row,ASSET_NAME+1).toString(); + info.type = xlsx.read(row,ASSET_TYPE+1).toString(); + info.param = xlsx.read(row,ASSET_PARAM+1).toString(); + info.setUpTime = QDate::fromString(xlsx.read(row,ASSET_SETUP+1).toString(),"yyyy-MM-dd").toString("yyyyMMdd").toLongLong(); + info.status = xlsx.read(row,ASSET_STATUS+1).toString(); + info.contact = xlsx.read(row,ASSET_CONTACT+1).toString(); + info.maintain_period = xlsx.read(row,ASSET_PERIOD+1).toDouble(); + info.backup = xlsx.read(row,ASSET_BACKUP+1).toString(); + info.dev_group = xlsx.read(row,ASSET_BACKUP+3).toString(); + qDebug()<importAsset(assetMap,mess2); + mess = mess1+mess2; + emit sigImportEnd(mess); + } + + file.close(); +} + +void CWorker::slotImportRecord(const QString &fileName) +{ + QString mess; + QString mess1; + QString mess2; + QFile file(fileName); + if(!file.open(QIODevice::ReadOnly)) + { + emit sigExportEnd(tr("导入维护记录失败,文件打开失败!")); + }else{ + QXlsx::Document xlsx(&file); + xlsx.selectSheet("RECORD"); + QList recordList; + QMap recordMap; + int row =2; + QMap devMap = CAssetDataMng::instance()->readDev(); + do{ + AssetRecord info; + info.id =xlsx.read(row,RECORD_ASSET_NAME+1).toString(); + info.dev_id = xlsx.read(row,RECORD_ASSET_NAME+2).toString(); + //info.dev_id = xlsx.read(row,RECORD_ASSET_NAME+1).toInt(); + + info.record_name = xlsx.read(row,RECORD_NAME+3).toString(); + info.opt_user = xlsx.read(row,RECORD_USER+3).toString(); + info.startTime = QDate::fromString(xlsx.read(row,RECORD_STARTTIME+3).toString(),"yyyy-MM-dd").toString("yyyyMMdd").toLongLong(); + info.endTime = QDate::fromString(xlsx.read(row,RECORD_ENDTIME+3).toString(),"yyyy-MM-dd").toString("yyyyMMdd").toLongLong(); + info.content = xlsx.read(row,RECORD_CONTENT+3).toString(); + if(info.id.isEmpty()) + { + break; + }else + { + if(devMap.keys().contains(info.dev_id)) + { + recordMap[info.id] = info; + recordList.append(info); + }else + { + LOGINFO("不存在标签为%s的资产,跳过!",info.dev_id.toStdString().c_str()); + mess1 = tr("部分资产不存在 "); + //mess += tr("不存在id为%1的设备,跳过!").arg(info.dev_id); + } + row++; + } + + }while (true); + CAssetDataMng::instance()->importRecord(recordMap,mess2); + + mess = mess1+mess2; + emit sigImportEnd(mess); + } + + file.close(); +} diff --git a/product/src/gui/plugin/AssetWidget/CWorker.h b/product/src/gui/plugin/AssetWidget/CWorker.h index 6af92f90..7cea21ae 100644 --- a/product/src/gui/plugin/AssetWidget/CWorker.h +++ b/product/src/gui/plugin/AssetWidget/CWorker.h @@ -1,24 +1,24 @@ -#ifndef CWORKER_H -#define CWORKER_H - -#include -#include "CAssetCommon.h" - -class CWorker :public QObject -{ - Q_OBJECT -public: - CWorker(QObject *parent = nullptr); - -signals: - void sigExportEnd(const QString & result); - void sigImportEnd(const QString & result); -public slots: - void slotExportAsset(const QString &fileName, const QList &assetList); - void slotExportRecord(const QString &fileName, const QList &recordList); - - void slotImportAsset(const QString &fileName); - void slotImportRecord(const QString &fileName); -}; - -#endif // CWORKER_H +#ifndef CWORKER_H +#define CWORKER_H + +#include +#include "CAssetCommon.h" + +class CWorker :public QObject +{ + Q_OBJECT +public: + CWorker(QObject *parent = nullptr); + +signals: + void sigExportEnd(const QString & result); + void sigImportEnd(const QString & result); +public slots: + void slotExportAsset(const QString &fileName, const QList &assetList); + void slotExportRecord(const QString &fileName, const QList &recordList); + + void slotImportAsset(const QString &fileName); + void slotImportRecord(const QString &fileName); +}; + +#endif // CWORKER_H diff --git a/product/src/gui/plugin/AssetWidget/main.cpp b/product/src/gui/plugin/AssetWidget/main.cpp index e85f2068..3fd2fb97 100644 --- a/product/src/gui/plugin/AssetWidget/main.cpp +++ b/product/src/gui/plugin/AssetWidget/main.cpp @@ -1,12 +1,12 @@ -#include "CAssetWidget.h" - -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CAssetWidget w(NULL, false); - QStringList devList; - w.show(); - return a.exec(); -} +#include "CAssetWidget.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CAssetWidget w(NULL, false); + QStringList devList; + w.show(); + return a.exec(); +} diff --git a/product/src/gui/plugin/BIWidget/BIWidget.pro b/product/src/gui/plugin/BIWidget/BIWidget.pro index a48606c8..120528bf 100644 --- a/product/src/gui/plugin/BIWidget/BIWidget.pro +++ b/product/src/gui/plugin/BIWidget/BIWidget.pro @@ -1,49 +1,49 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-08-26T11:27:20 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = BIWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ -# main.cpp \ - CBIPluginWidget.cpp \ - CBIWidget.cpp - -HEADERS += \ - CBIPluginWidget.h \ - CBIWidget.h - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lpub_utility_api \ - -lperm_mng_api - - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2020-08-26T11:27:20 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = BIWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ +# main.cpp \ + CBIPluginWidget.cpp \ + CBIWidget.cpp + +HEADERS += \ + CBIPluginWidget.h \ + CBIWidget.h + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lpub_utility_api \ + -lperm_mng_api + + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/BIWidget/CBIPluginWidget.cpp b/product/src/gui/plugin/BIWidget/CBIPluginWidget.cpp index 9a5353c6..a4decc5f 100644 --- a/product/src/gui/plugin/BIWidget/CBIPluginWidget.cpp +++ b/product/src/gui/plugin/BIWidget/CBIPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "CBIPluginWidget.h" -#include "CBIWidget.h" -#include - -CBIPluginWidget::CBIPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CBIPluginWidget::~CBIPluginWidget() -{ - -} - -bool CBIPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CBIWidget *pWidget = new CBIWidget(editMode, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CBIPluginWidget::release() -{ - -} +#include "CBIPluginWidget.h" +#include "CBIWidget.h" +#include + +CBIPluginWidget::CBIPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CBIPluginWidget::~CBIPluginWidget() +{ + +} + +bool CBIPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CBIWidget *pWidget = new CBIWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CBIPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/BIWidget/CBIPluginWidget.h b/product/src/gui/plugin/BIWidget/CBIPluginWidget.h index 84c3ec1d..4f3c8e2b 100644 --- a/product/src/gui/plugin/BIWidget/CBIPluginWidget.h +++ b/product/src/gui/plugin/BIWidget/CBIPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CBIPLUGINWIDGET_H -#define CBIPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CBIPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CBIPluginWidget(QObject *parent = 0); - ~CBIPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CBIPLUGINWIDGET_H +#ifndef CBIPLUGINWIDGET_H +#define CBIPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CBIPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CBIPluginWidget(QObject *parent = 0); + ~CBIPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CBIPLUGINWIDGET_H diff --git a/product/src/gui/plugin/BIWidget/CBIWidget.cpp b/product/src/gui/plugin/BIWidget/CBIWidget.cpp index ed5aa628..c3b7e7c2 100644 --- a/product/src/gui/plugin/BIWidget/CBIWidget.cpp +++ b/product/src/gui/plugin/BIWidget/CBIWidget.cpp @@ -1,244 +1,244 @@ -#include "CBIWidget.h" -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/FileStyle.h" - -CBIWidget::CBIWidget(bool editMode, QWidget *parent) - : QWidget(parent), - m_timer(Q_NULLPTR), - m_permMng(Q_NULLPTR), - m_isRecognizing(false) -{ - initWidget(editMode); -} - -CBIWidget::~CBIWidget() -{ - if(m_timer) - { - m_timer->stop(); - delete m_timer; - } - m_timer = Q_NULLPTR; - - if(m_permMng) - { - m_permMng->cancelBioIdentify(); - } - - delete layout(); -} - -void CBIWidget::initWidget(bool editMode) -{ - QGridLayout *layout = new QGridLayout(this); - m_imageLabel = new QLabel(this); - m_imageLabel->setScaledContents(true); - std::string style = kbd_public::CFileStyle::getCurStyle(); - QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/bi/face_"+style+".png").c_str(); - m_imageLabel->setPixmap(QPixmap(file)); - layout->addWidget(m_imageLabel); - setLayout(layout); - - if(!editMode) - { - m_permMng = getPermMngInstance("base"); - if(m_permMng) - { - m_permMng->PermDllInit(); - } - - m_timer = new QTimer(this); - connect(m_timer, SIGNAL(timeout()), this, SLOT(slotRecvBioResult())); - m_timer->start(500); - } -} - -bool CBIWidget::slotBIdentify() -{ - if(m_isRecognizing) - { - return true; - } - std::string style = kbd_public::CFileStyle::getCurStyle(); - QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/bi/face_"+style+".png").c_str(); - m_imageLabel->setPixmap(QPixmap(file)); - if(!m_permMng) - { - return false; - } - m_permMng->startBioIdentify(); - m_isRecognizing = true; - return true; -} - -void CBIWidget::slotCancelBIdentify() -{ - if(m_permMng) - { - m_isRecognizing = false; - m_permMng->cancelBioIdentify(); - std::string style = kbd_public::CFileStyle::getCurStyle(); - QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/bi/face_"+style+".png").c_str(); - m_imageLabel->setPixmap(QPixmap(file)); - } -} - -QString CBIWidget::sysLogin(const QString &userName, const QString &passWord, int groupId, int expireTime) -{ - QString errorStr; - int retCode = PERM_MALLOC_FAIL; - if(m_permMng) - { - retCode = m_permMng->SysLogin(userName.toLocal8Bit().data(), passWord.toLocal8Bit().data(), groupId, expireTime, ""); - switch(retCode) - { - case PERM_NORMAL: - { - errorStr = "0"; - } - break; - case PERM_PERMIT: - { - errorStr = "0"; - } - break; - case PERM_FORBIT: - { - errorStr = tr("用户不具有指定权限"); - } - break; - case PERM_NO_USER_LOGIN: - { - errorStr = tr("无用户登录信息"); - } - break; - case PERM_NO_NAME: - { - errorStr = tr("输入名称不存在"); - } - break; - case PERM_REDUP_NAME: - { - errorStr = tr("输入名称不唯一"); - } - break; - case PERM_NODE_DENY: - { - errorStr = tr("不允许在该节点登录"); - } - break; - case PERM_PASSWORD_ERROR: - { - errorStr = tr("用户口令错误"); - } - break; - case PERM_USER_EXPIRED: - { - errorStr = tr("用户已失效"); - } - break; - case PERM_USER_LOCKED: - { - errorStr = tr("用户已锁定"); - } - break; - case PERM_USERG_ERROR: - { - errorStr = tr("用户不属于所选用户组"); - } - break; - case PERM_ERROR: - { - errorStr = tr("未知错误,系统可能未正常启动"); - } - break; - default: - { - errorStr = tr("未知错误"); - } - break; - } - } - else - { - errorStr = tr("内存出错"); - } - QString loginTime = QDateTime::currentDateTime().toString(); - LOGINFO("sysLogin userName:%s, expireTime:%d, time :%s, ret:%d", - userName.toLocal8Bit().data(), expireTime, loginTime.toLocal8Bit().data(), retCode); - - return errorStr; -} - -int CBIWidget::checkUserValid(const QString &strUserName, const QString &password) -{ - int retCode = PERM_MALLOC_FAIL; - if(m_permMng) - { - retCode = m_permMng->CheckUserValid(strUserName.toLocal8Bit().data(), password.toLocal8Bit().data()); - } - - return retCode; -} - -void CBIWidget::slotRecvBioResult() -{ - if(!m_isRecognizing || !m_permMng) - { - return; - } - - std::string strUserName; - std::string strTempPwd; - std::string strAcsDevTag; - std::string strPic; - std::string strErr; - int result = m_permMng->getBioIdentifyResult(strUserName, strTempPwd, strAcsDevTag, strPic, strErr); - switch (result) { - case 0: - { - QByteArray byteArray(strPic.c_str(), (int)strPic.size()); - QPixmap pixmap; - uchar* img = new uchar[byteArray.size()]; - memcpy(img, byteArray.data(), byteArray.size()); - pixmap.loadFromData(img, byteArray.size()); - delete[] img; - if(pixmap.isNull()) - { - std::string style = kbd_public::CFileStyle::getCurStyle(); - QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/bi/face_"+style+".png").c_str(); - m_imageLabel->setPixmap(QPixmap(file)); - } - else - { - m_imageLabel->setPixmap(pixmap); - } - std::vector vecUsergInfo; - m_permMng->GetUsergByUserName(strUserName, vecUsergInfo); - QVariantList userGroup; - userGroup.push_back(QVariant::fromValue(vecUsergInfo.size())); - foreach (SUsergIdName userg, vecUsergInfo) { - userGroup.push_back(QVariant(QString::fromStdString(userg.userg_name))); - userGroup.push_back(QVariant(userg.userg_id)); - } - emit BIdentifyResult(result, QString::fromStdString(strUserName), QString::fromStdString(strTempPwd), QString::fromStdString(strAcsDevTag), userGroup); - m_isRecognizing = false; - break; - } - case 1: - case 3: - { - emit BIdentifyResult(result, QString(),QString(),QString(),QVariantList(),QString::fromStdString(strErr)); - m_isRecognizing = false; - break; - } - case 2: - default: - break; - } -} +#include "CBIWidget.h" +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" + +CBIWidget::CBIWidget(bool editMode, QWidget *parent) + : QWidget(parent), + m_timer(Q_NULLPTR), + m_permMng(Q_NULLPTR), + m_isRecognizing(false) +{ + initWidget(editMode); +} + +CBIWidget::~CBIWidget() +{ + if(m_timer) + { + m_timer->stop(); + delete m_timer; + } + m_timer = Q_NULLPTR; + + if(m_permMng) + { + m_permMng->cancelBioIdentify(); + } + + delete layout(); +} + +void CBIWidget::initWidget(bool editMode) +{ + QGridLayout *layout = new QGridLayout(this); + m_imageLabel = new QLabel(this); + m_imageLabel->setScaledContents(true); + std::string style = kbd_public::CFileStyle::getCurStyle(); + QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/bi/face_"+style+".png").c_str(); + m_imageLabel->setPixmap(QPixmap(file)); + layout->addWidget(m_imageLabel); + setLayout(layout); + + if(!editMode) + { + m_permMng = getPermMngInstance("base"); + if(m_permMng) + { + m_permMng->PermDllInit(); + } + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(slotRecvBioResult())); + m_timer->start(500); + } +} + +bool CBIWidget::slotBIdentify() +{ + if(m_isRecognizing) + { + return true; + } + std::string style = kbd_public::CFileStyle::getCurStyle(); + QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/bi/face_"+style+".png").c_str(); + m_imageLabel->setPixmap(QPixmap(file)); + if(!m_permMng) + { + return false; + } + m_permMng->startBioIdentify(); + m_isRecognizing = true; + return true; +} + +void CBIWidget::slotCancelBIdentify() +{ + if(m_permMng) + { + m_isRecognizing = false; + m_permMng->cancelBioIdentify(); + std::string style = kbd_public::CFileStyle::getCurStyle(); + QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/bi/face_"+style+".png").c_str(); + m_imageLabel->setPixmap(QPixmap(file)); + } +} + +QString CBIWidget::sysLogin(const QString &userName, const QString &passWord, int groupId, int expireTime) +{ + QString errorStr; + int retCode = PERM_MALLOC_FAIL; + if(m_permMng) + { + retCode = m_permMng->SysLogin(userName.toLocal8Bit().data(), passWord.toLocal8Bit().data(), groupId, expireTime, ""); + switch(retCode) + { + case PERM_NORMAL: + { + errorStr = "0"; + } + break; + case PERM_PERMIT: + { + errorStr = "0"; + } + break; + case PERM_FORBIT: + { + errorStr = tr("用户不具有指定权限"); + } + break; + case PERM_NO_USER_LOGIN: + { + errorStr = tr("无用户登录信息"); + } + break; + case PERM_NO_NAME: + { + errorStr = tr("输入名称不存在"); + } + break; + case PERM_REDUP_NAME: + { + errorStr = tr("输入名称不唯一"); + } + break; + case PERM_NODE_DENY: + { + errorStr = tr("不允许在该节点登录"); + } + break; + case PERM_PASSWORD_ERROR: + { + errorStr = tr("用户口令错误"); + } + break; + case PERM_USER_EXPIRED: + { + errorStr = tr("用户已失效"); + } + break; + case PERM_USER_LOCKED: + { + errorStr = tr("用户已锁定"); + } + break; + case PERM_USERG_ERROR: + { + errorStr = tr("用户不属于所选用户组"); + } + break; + case PERM_ERROR: + { + errorStr = tr("未知错误,系统可能未正常启动"); + } + break; + default: + { + errorStr = tr("未知错误"); + } + break; + } + } + else + { + errorStr = tr("内存出错"); + } + QString loginTime = QDateTime::currentDateTime().toString(); + LOGINFO("sysLogin userName:%s, expireTime:%d, time :%s, ret:%d", + userName.toLocal8Bit().data(), expireTime, loginTime.toLocal8Bit().data(), retCode); + + return errorStr; +} + +int CBIWidget::checkUserValid(const QString &strUserName, const QString &password) +{ + int retCode = PERM_MALLOC_FAIL; + if(m_permMng) + { + retCode = m_permMng->CheckUserValid(strUserName.toLocal8Bit().data(), password.toLocal8Bit().data()); + } + + return retCode; +} + +void CBIWidget::slotRecvBioResult() +{ + if(!m_isRecognizing || !m_permMng) + { + return; + } + + std::string strUserName; + std::string strTempPwd; + std::string strAcsDevTag; + std::string strPic; + std::string strErr; + int result = m_permMng->getBioIdentifyResult(strUserName, strTempPwd, strAcsDevTag, strPic, strErr); + switch (result) { + case 0: + { + QByteArray byteArray(strPic.c_str(), (int)strPic.size()); + QPixmap pixmap; + uchar* img = new uchar[byteArray.size()]; + memcpy(img, byteArray.data(), byteArray.size()); + pixmap.loadFromData(img, byteArray.size()); + delete[] img; + if(pixmap.isNull()) + { + std::string style = kbd_public::CFileStyle::getCurStyle(); + QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/bi/face_"+style+".png").c_str(); + m_imageLabel->setPixmap(QPixmap(file)); + } + else + { + m_imageLabel->setPixmap(pixmap); + } + std::vector vecUsergInfo; + m_permMng->GetUsergByUserName(strUserName, vecUsergInfo); + QVariantList userGroup; + userGroup.push_back(QVariant::fromValue(vecUsergInfo.size())); + foreach (SUsergIdName userg, vecUsergInfo) { + userGroup.push_back(QVariant(QString::fromStdString(userg.userg_name))); + userGroup.push_back(QVariant(userg.userg_id)); + } + emit BIdentifyResult(result, QString::fromStdString(strUserName), QString::fromStdString(strTempPwd), QString::fromStdString(strAcsDevTag), userGroup); + m_isRecognizing = false; + break; + } + case 1: + case 3: + { + emit BIdentifyResult(result, QString(),QString(),QString(),QVariantList(),QString::fromStdString(strErr)); + m_isRecognizing = false; + break; + } + case 2: + default: + break; + } +} diff --git a/product/src/gui/plugin/BIWidget/CBIWidget.h b/product/src/gui/plugin/BIWidget/CBIWidget.h index ab644639..fcdcbc63 100644 --- a/product/src/gui/plugin/BIWidget/CBIWidget.h +++ b/product/src/gui/plugin/BIWidget/CBIWidget.h @@ -1,41 +1,41 @@ -#ifndef BIWIDGET_H -#define BIWIDGET_H - -#include -#include -#include -#include "perm_mng_api/PermMngApi.h" - -using namespace kbd_service; - -class CBIWidget : public QWidget -{ - Q_OBJECT - -public: - CBIWidget(bool editMode, QWidget *parent = 0); - ~CBIWidget(); - -signals: - void BIdentifyResult(int code, const QString &userName, const QString &tempPwd, const QString &devTag, const QVariantList &userGroup, const QString &strErr = QString()); - -public slots: - bool slotBIdentify(); - void slotCancelBIdentify(); - QString sysLogin(const QString &userName, const QString &passWord, int groupId, int expireTime); - int checkUserValid(const QString &strUserName, const QString &password); - -private: - void initWidget(bool editMode); - -private slots: - void slotRecvBioResult(); - -private: - QLabel * m_imageLabel; - QTimer * m_timer; - CPermMngApiPtr m_permMng; - bool m_isRecognizing; -}; - -#endif // BIWIDGET_H +#ifndef BIWIDGET_H +#define BIWIDGET_H + +#include +#include +#include +#include "perm_mng_api/PermMngApi.h" + +using namespace kbd_service; + +class CBIWidget : public QWidget +{ + Q_OBJECT + +public: + CBIWidget(bool editMode, QWidget *parent = 0); + ~CBIWidget(); + +signals: + void BIdentifyResult(int code, const QString &userName, const QString &tempPwd, const QString &devTag, const QVariantList &userGroup, const QString &strErr = QString()); + +public slots: + bool slotBIdentify(); + void slotCancelBIdentify(); + QString sysLogin(const QString &userName, const QString &passWord, int groupId, int expireTime); + int checkUserValid(const QString &strUserName, const QString &password); + +private: + void initWidget(bool editMode); + +private slots: + void slotRecvBioResult(); + +private: + QLabel * m_imageLabel; + QTimer * m_timer; + CPermMngApiPtr m_permMng; + bool m_isRecognizing; +}; + +#endif // BIWIDGET_H diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/BreadcrumbNavWidget.pro b/product/src/gui/plugin/BreadcrumbNavWidget/BreadcrumbNavWidget.pro index c156deb4..5fe35085 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/BreadcrumbNavWidget.pro +++ b/product/src/gui/plugin/BreadcrumbNavWidget/BreadcrumbNavWidget.pro @@ -1,49 +1,49 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-08-02T16:19:52 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = BreadcrumbNavWidget -TEMPLATE = lib - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ -# main.cpp \ - CBreadcrumbNavWidget.cpp \ - CNavInfoManage.cpp \ - CToolButton.cpp \ - CBreadcrumbPluginWidget.cpp - -HEADERS += \ - CBreadcrumbNavWidget.h \ - CNavInfoManage.h \ - CToolButton.h \ - CBreadcrumbPluginWidget.h - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lpub_utility_api - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-08-02T16:19:52 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = BreadcrumbNavWidget +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ +# main.cpp \ + CBreadcrumbNavWidget.cpp \ + CNavInfoManage.cpp \ + CToolButton.cpp \ + CBreadcrumbPluginWidget.cpp + +HEADERS += \ + CBreadcrumbNavWidget.h \ + CNavInfoManage.h \ + CToolButton.h \ + CBreadcrumbPluginWidget.h + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lpub_utility_api + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbNavWidget.cpp b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbNavWidget.cpp index fab98a26..c2383331 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbNavWidget.cpp +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbNavWidget.cpp @@ -1,158 +1,158 @@ -#include "CBreadcrumbNavWidget.h" -#include "public/pub_utility_api/FileStyle.h" -#include "public/pub_utility_api/FileUtil.h" -#include "CNavInfoManage.h" -#include "CToolButton.h" -#include -#include -#include -#include -#include - -CBreadcrumbNavWidget::CBreadcrumbNavWidget(bool editMode, QWidget *parent) - : m_isEditMode(editMode), - QWidget(parent), - m_pNavManage(NULL) -{ - initialize(); - - initStyleSheet(); -} - -CBreadcrumbNavWidget::~CBreadcrumbNavWidget() -{ - if(m_pNavManage) - { - delete m_pNavManage; - } - m_pNavManage = NULL; -} - -void CBreadcrumbNavWidget::initialize() -{ - m_pNavManage = new CNavInfoManage; - - QHBoxLayout * layout = new QHBoxLayout(this); - for(int nIndex=0; nIndexsetObjectName(QString("button_%1").arg(nIndex)); - layout->addWidget(button); - QMenu * menu = new QMenu(this); - button->setMenu(menu); - QPushButton * pixmap = new QPushButton(this); - pixmap->setObjectName(QString("pixmap_%1").arg(nIndex)); - pixmap->setEnabled(false); - layout->addWidget(pixmap); - } - QSpacerItem *item = new QSpacerItem(10, 0, QSizePolicy::Expanding); - layout->addSpacerItem(item); - layout->setMargin(0); - layout->setSpacing(0); - setLayout(layout); -} - -void CBreadcrumbNavWidget::initStyleSheet() -{ - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("breadcrumbNav.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - setStyleSheet(QLatin1String(qssfile2.readAll())); - qssfile2.close(); - } -} - -void CBreadcrumbNavWidget::setCurrentGraph(const QString &data, const QString &name) -{ - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - QDir dir(QString::fromStdString(currentPath)); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - dir.cd("pic"); - QString rData = dir.relativeFilePath(data); - - QStringList parents; - if(!name.isEmpty()) - { - m_pNavManage->getParentBreadcrumb(name+":"+rData, parents); - } - if(parents.isEmpty()) - { - m_pNavManage->getParentBreadcrumb(rData, parents); - } - - QString objName; - for(int nIndex=0; nIndexfindChild(objName); - objName = QString("pixmap_%1").arg(nIndex); - QPushButton * pixmap = this->findChild(objName); - if(nIndexsetText(parents[nIndex]); - button->setVisible(true); - pixmap->setVisible(true); - } - else - { - button->setVisible(false); - pixmap->setVisible(false); - } - } - objName = QString("pixmap_%1").arg(parents.length()-1); - QPushButton * pixmap = this->findChild(objName); - if(pixmap) - { - pixmap->setVisible(false); - } - for(int nIndex=parents.length(); nIndex>0; nIndex--) - { - QList> nodeList; - m_pNavManage->getSameLevelNode(parents, nodeList); - objName = QString("button_%1").arg(parents.length()-1); - CToolButton * button = this->findChild(objName); - if(!button) - { - continue; - } - QMenu * menu = button->menu(); - menu->clear(); - QPair node; - for(int n=0; nsetGraph(QString()); - if(button->text() == node.second.text) - { - button->setGraph(node.first); - button->setOpt(node.second.opt); - button->setUrl(node.second.url); - } - menu->addAction(node.second.text, this, [=](){emit sigNodeClicked(node.second.text, node.first, node.second.opt, node.second.url);}); - } - if(parents.length() > 1) - { - parents.takeLast(); - } - } -} - -void CBreadcrumbNavWidget::slotButtonClicked() -{ - CToolButton * button = dynamic_cast(sender()); - if(button) - { - QString graph = button->getGraph(); - int opt = button->getOpt(); - QString url = button->getUrl(); - if(graph.isEmpty()) - { - return; - } - emit sigNodeClicked(button->text(), graph, opt, url); - } -} +#include "CBreadcrumbNavWidget.h" +#include "public/pub_utility_api/FileStyle.h" +#include "public/pub_utility_api/FileUtil.h" +#include "CNavInfoManage.h" +#include "CToolButton.h" +#include +#include +#include +#include +#include + +CBreadcrumbNavWidget::CBreadcrumbNavWidget(bool editMode, QWidget *parent) + : m_isEditMode(editMode), + QWidget(parent), + m_pNavManage(NULL) +{ + initialize(); + + initStyleSheet(); +} + +CBreadcrumbNavWidget::~CBreadcrumbNavWidget() +{ + if(m_pNavManage) + { + delete m_pNavManage; + } + m_pNavManage = NULL; +} + +void CBreadcrumbNavWidget::initialize() +{ + m_pNavManage = new CNavInfoManage; + + QHBoxLayout * layout = new QHBoxLayout(this); + for(int nIndex=0; nIndexsetObjectName(QString("button_%1").arg(nIndex)); + layout->addWidget(button); + QMenu * menu = new QMenu(this); + button->setMenu(menu); + QPushButton * pixmap = new QPushButton(this); + pixmap->setObjectName(QString("pixmap_%1").arg(nIndex)); + pixmap->setEnabled(false); + layout->addWidget(pixmap); + } + QSpacerItem *item = new QSpacerItem(10, 0, QSizePolicy::Expanding); + layout->addSpacerItem(item); + layout->setMargin(0); + layout->setSpacing(0); + setLayout(layout); +} + +void CBreadcrumbNavWidget::initStyleSheet() +{ + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("breadcrumbNav.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + setStyleSheet(QLatin1String(qssfile2.readAll())); + qssfile2.close(); + } +} + +void CBreadcrumbNavWidget::setCurrentGraph(const QString &data, const QString &name) +{ + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + QDir dir(QString::fromStdString(currentPath)); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("pic"); + QString rData = dir.relativeFilePath(data); + + QStringList parents; + if(!name.isEmpty()) + { + m_pNavManage->getParentBreadcrumb(name+":"+rData, parents); + } + if(parents.isEmpty()) + { + m_pNavManage->getParentBreadcrumb(rData, parents); + } + + QString objName; + for(int nIndex=0; nIndexfindChild(objName); + objName = QString("pixmap_%1").arg(nIndex); + QPushButton * pixmap = this->findChild(objName); + if(nIndexsetText(parents[nIndex]); + button->setVisible(true); + pixmap->setVisible(true); + } + else + { + button->setVisible(false); + pixmap->setVisible(false); + } + } + objName = QString("pixmap_%1").arg(parents.length()-1); + QPushButton * pixmap = this->findChild(objName); + if(pixmap) + { + pixmap->setVisible(false); + } + for(int nIndex=parents.length(); nIndex>0; nIndex--) + { + QList> nodeList; + m_pNavManage->getSameLevelNode(parents, nodeList); + objName = QString("button_%1").arg(parents.length()-1); + CToolButton * button = this->findChild(objName); + if(!button) + { + continue; + } + QMenu * menu = button->menu(); + menu->clear(); + QPair node; + for(int n=0; nsetGraph(QString()); + if(button->text() == node.second.text) + { + button->setGraph(node.first); + button->setOpt(node.second.opt); + button->setUrl(node.second.url); + } + menu->addAction(node.second.text, this, [=](){emit sigNodeClicked(node.second.text, node.first, node.second.opt, node.second.url);}); + } + if(parents.length() > 1) + { + parents.takeLast(); + } + } +} + +void CBreadcrumbNavWidget::slotButtonClicked() +{ + CToolButton * button = dynamic_cast(sender()); + if(button) + { + QString graph = button->getGraph(); + int opt = button->getOpt(); + QString url = button->getUrl(); + if(graph.isEmpty()) + { + return; + } + emit sigNodeClicked(button->text(), graph, opt, url); + } +} diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbNavWidget.h b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbNavWidget.h index 43f75527..5b4e1133 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbNavWidget.h +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbNavWidget.h @@ -1,34 +1,34 @@ -#ifndef CBREADCRUMBNAVWIDGET_H -#define CBREADCRUMBNAVWIDGET_H - -#include - -class CNavInfoManage; -class CBreadcrumbNavWidget : public QWidget -{ - Q_OBJECT - -public: - CBreadcrumbNavWidget(bool editMode = true, QWidget *parent = 0); - ~CBreadcrumbNavWidget(); - -signals: - void sigNodeClicked(const QString &name, const QString &data, int opt = 1, const QString &url = QString()); - -public slots: - void setCurrentGraph(const QString &data, const QString &name = QString()); - -private slots: - void slotButtonClicked(); - -private: - void initialize(); - void initStyleSheet(); - -private: - bool m_isEditMode; - CNavInfoManage *m_pNavManage; - const static int TOOLBUTTON_MAX_NUMBER = 4; -}; - -#endif // CBREADCRUMBNAVWIDGET_H +#ifndef CBREADCRUMBNAVWIDGET_H +#define CBREADCRUMBNAVWIDGET_H + +#include + +class CNavInfoManage; +class CBreadcrumbNavWidget : public QWidget +{ + Q_OBJECT + +public: + CBreadcrumbNavWidget(bool editMode = true, QWidget *parent = 0); + ~CBreadcrumbNavWidget(); + +signals: + void sigNodeClicked(const QString &name, const QString &data, int opt = 1, const QString &url = QString()); + +public slots: + void setCurrentGraph(const QString &data, const QString &name = QString()); + +private slots: + void slotButtonClicked(); + +private: + void initialize(); + void initStyleSheet(); + +private: + bool m_isEditMode; + CNavInfoManage *m_pNavManage; + const static int TOOLBUTTON_MAX_NUMBER = 4; +}; + +#endif // CBREADCRUMBNAVWIDGET_H diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.cpp b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.cpp index babbc4c8..4eb9639e 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.cpp +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "CBreadcrumbPluginWidget.h" -#include "CBreadcrumbNavWidget.h" -#include - -CBreadcrumbPluginWidget::CBreadcrumbPluginWidget() -{ - -} - -CBreadcrumbPluginWidget::~CBreadcrumbPluginWidget() -{ - -} - -bool CBreadcrumbPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CBreadcrumbNavWidget *pWidget = new CBreadcrumbNavWidget(editMode, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CBreadcrumbPluginWidget::release() -{ - -} +#include "CBreadcrumbPluginWidget.h" +#include "CBreadcrumbNavWidget.h" +#include + +CBreadcrumbPluginWidget::CBreadcrumbPluginWidget() +{ + +} + +CBreadcrumbPluginWidget::~CBreadcrumbPluginWidget() +{ + +} + +bool CBreadcrumbPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CBreadcrumbNavWidget *pWidget = new CBreadcrumbNavWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CBreadcrumbPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.h b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.h index 02e7f378..9759e9b8 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.h +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CBREADCRUMBPLUGINWIDGET_H -#define CBREADCRUMBPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CBreadcrumbPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CBreadcrumbPluginWidget(); - ~CBreadcrumbPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - - -#endif // CBREADCRUMBPLUGINWIDGET_H +#ifndef CBREADCRUMBPLUGINWIDGET_H +#define CBREADCRUMBPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CBreadcrumbPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CBreadcrumbPluginWidget(); + ~CBreadcrumbPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + + +#endif // CBREADCRUMBPLUGINWIDGET_H diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CNavInfoManage.cpp b/product/src/gui/plugin/BreadcrumbNavWidget/CNavInfoManage.cpp index 1fa8e65f..bf607cf5 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CNavInfoManage.cpp +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CNavInfoManage.cpp @@ -1,297 +1,297 @@ -#include "CNavInfoManage.h" -#include "public/pub_utility_api/FileUtil.h" -#include "public/pub_logger_api/logger.h" -#include -#include -#include -#include -#include - -CNavInfoManage::CNavInfoManage(QObject *parent) - : QObject(parent) -{ - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - QDir dir(QString::fromStdString(currentPath)); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - dir.cd("model"); - - m_strButtonFile = dir.filePath("ButtonGroupWidget.json"); - m_strNavFile = dir.filePath("NavigationWidget.json"); - readBtnJson(m_strButtonFile); - readNavJson(m_strNavFile); -} - -void CNavInfoManage::getParentBreadcrumb(const QString &fileName, QStringList &parents) -{ - parents = m_parentsMap.value(fileName, QStringList()); -} - -void CNavInfoManage::getSameLevelNode(const QStringList &curList, QList > &nodelist) -{ - int length = curList.length(); - if(length < 2) - { - return; - } - QPair key; - key.first = length; - QString menuTopName; - for(int i=0; i, QList> >::const_iterator iter = m_levelMap.constBegin(); - for(; iter != m_levelMap.constEnd(); iter++) - { - if(iter.key() == key) - { - nodelist.append(iter.value()); - } - } -} - -void CNavInfoManage::readBtnJson(const QString &path) -{ - QFile file(path); - QByteArray readJson; - if(file.open(QIODevice::ReadOnly)) - { - readJson = file.readAll(); - file.close(); - } - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return; - } - QString name; - QString data; - QJsonObject root = readJsonResponse.object(); - QJsonObject::const_iterator rootIter = root.constBegin(); - for(; rootIter != root.constEnd(); rootIter++) - { - if(rootIter.key() == "separator") - { - continue; - } - QJsonObject item = rootIter.value().toObject(); - if(item.value("used").toInt() != 1) - { - continue; - } - if(item.value("opt").toInt() != 2) - { - continue; - } - name = item.value("name").toString(); - data = item.value("data").toString(); - QStringList tempList = data.split(","); - int nIndex=0; - foreach (QString temp, tempList) { - if(temp != '0') - { - m_btnMap[nIndex] = name; - } - nIndex++; - } - } -} - -void CNavInfoManage::readNavJson(const QString &path) -{ - QFile file(path); - QByteArray readJson; - if(file.open(QIODevice::ReadOnly)) - { - readJson = file.readAll(); - file.close(); - } - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return; - } - QString menuTopName; - QJsonObject root = readJsonResponse.object(); - if(root.contains("items")) - { - QJsonArray itemArray = root.value("items").toArray(); - int nItemNumber = 0; - for(int nIndex(0); nIndex< itemArray.size(); nIndex++) - { - QJsonObject topLevelObject = itemArray[nIndex].toObject(); - QString topName = topLevelObject.value("name").toString(); - QString topData = topLevelObject.value("data").toString(); - QString topLink = topName + ":" + topData; - STNodeInfo stNodeTop; - int topUsed = topLevelObject.value("used").toInt(); - if(topUsed != 1) - { - nItemNumber++; - continue; - } - QString menu = m_btnMap.value(nItemNumber); - if(!topData.isEmpty()) - { - if(m_parentsMap[topLink].isEmpty()) - { - m_parentsMap[topLink].append(menu); - m_parentsMap[topLink].append(topName); - } - if(m_parentsMap[topData].isEmpty()) - { - m_parentsMap[topData].append(menu); - m_parentsMap[topData].append(topName); - } - stNodeTop.data = topData; - stNodeTop.text = topName; - stNodeTop.opt = topLevelObject.value("opt").toInt(); - stNodeTop.url = topLevelObject.value("url").toString(); - menuTopName = menu; - m_levelMap[QPair(2, menuTopName)].append(QPair(topData, stNodeTop)); - } - - QJsonArray childArray = topLevelObject.value("items").toArray(); - for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) - { - QJsonObject childLevelObject = childArray[nChildIndex].toObject(); - QString childName = childLevelObject.value("name").toString(); - QString childData = childLevelObject.value("data").toString(); - QString childLink = childName + ":" + childData; - STNodeInfo stNodeChild; - int childUsed = topLevelObject.value("used").toInt(); - if(childUsed != 1) - { - continue; - } - if(!childData.isEmpty()) - { - if(m_parentsMap[childLink].isEmpty()) - { - m_parentsMap[childLink].append(menu); - m_parentsMap[childLink].append(topName); - m_parentsMap[childLink].append(childName); - } - if(m_parentsMap[childData].isEmpty()) - { - m_parentsMap[childData].append(menu); - m_parentsMap[childData].append(topName); - m_parentsMap[childData].append(childName); - } - stNodeChild.data = childData; - stNodeChild.text = childName; - stNodeChild.opt = childLevelObject.value("opt").toInt(); - stNodeChild.url = childLevelObject.value("url").toString(); - menuTopName = menu+"/"+topName; - m_levelMap[QPair(3, menuTopName)].append(QPair(childData, stNodeChild)); - if(topData.isEmpty()) - { - topLink = topName + ":" + childData; - if(m_parentsMap[topLink].isEmpty()) - { - m_parentsMap[topLink].append(menu); - m_parentsMap[topLink].append(topName); - m_parentsMap[topLink].append(childName); - } - topData = childData; - stNodeTop.data = childData; - stNodeTop.text = topName; - stNodeTop.opt = stNodeChild.opt; - stNodeTop.url = stNodeChild.url; - menuTopName = menu; - m_levelMap[QPair(2, menuTopName)].append(QPair(topData, stNodeTop)); - } - } - - QJsonArray leafArray = childLevelObject.value("items").toArray(); - for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) - { - QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); - QString leafName = leafLevelObject.value("name").toString(); - QString leafData = leafLevelObject.value("data").toString(); - QString leafLink = leafName + ":" + leafData; - STNodeInfo stNodeleaf; - int leafUsed = topLevelObject.value("used").toInt(); - if(leafUsed != 1) - { - continue; - } - if(!leafData.isEmpty()) - { - if(m_parentsMap[leafLink].isEmpty()) - { - m_parentsMap[leafLink].append(menu); - m_parentsMap[leafLink].append(topName); - m_parentsMap[leafLink].append(childName); - m_parentsMap[leafLink].append(leafName); - } - if(m_parentsMap[leafData].isEmpty()) - { - m_parentsMap[leafData].append(menu); - m_parentsMap[leafData].append(topName); - m_parentsMap[leafData].append(childName); - m_parentsMap[leafData].append(leafName); - } - stNodeleaf.data = leafData; - stNodeleaf.text = leafName; - stNodeleaf.opt = leafLevelObject.value("opt").toInt(); - stNodeleaf.url = leafLevelObject.value("url").toString(); - menuTopName = menu+"/"+topName+"/"+childName; - m_levelMap[QPair(4, menuTopName)].append(QPair(leafData, stNodeleaf)); - if(childData.isEmpty()) - { - childLink = childName + ":" + leafData; - if(m_parentsMap[childLink].isEmpty()) - { - m_parentsMap[childLink].append(menu); - m_parentsMap[childLink].append(topName); - m_parentsMap[childLink].append(childName); - m_parentsMap[childLink].append(leafName); - } - childData = leafData; - stNodeChild.data = leafData; - stNodeChild.text = childName; - stNodeChild.opt = stNodeleaf.opt; - stNodeChild.url = stNodeleaf.url; - menuTopName = menu+"/"+topName; - m_levelMap[QPair(3, menuTopName)].append(QPair(childData, stNodeChild)); - if(topData.isEmpty()) - { - topLink = topName + ":" + leafData; - if(m_parentsMap[topLink].isEmpty()) - { - m_parentsMap[topLink].append(menu); - m_parentsMap[topLink].append(topName); - m_parentsMap[topLink].append(childName); - m_parentsMap[topLink].append(leafName); - } - topData = leafData; - stNodeTop.data = leafData; - stNodeTop.text = topName; - stNodeTop.opt = stNodeleaf.opt; - stNodeTop.url = stNodeleaf.url; - menuTopName = menu; - m_levelMap[QPair(2, menuTopName)].append(QPair(topData, stNodeTop)); - } - } - } - } - } - nItemNumber++; - } - } -} +#include "CNavInfoManage.h" +#include "public/pub_utility_api/FileUtil.h" +#include "public/pub_logger_api/logger.h" +#include +#include +#include +#include +#include + +CNavInfoManage::CNavInfoManage(QObject *parent) + : QObject(parent) +{ + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + QDir dir(QString::fromStdString(currentPath)); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("model"); + + m_strButtonFile = dir.filePath("ButtonGroupWidget.json"); + m_strNavFile = dir.filePath("NavigationWidget.json"); + readBtnJson(m_strButtonFile); + readNavJson(m_strNavFile); +} + +void CNavInfoManage::getParentBreadcrumb(const QString &fileName, QStringList &parents) +{ + parents = m_parentsMap.value(fileName, QStringList()); +} + +void CNavInfoManage::getSameLevelNode(const QStringList &curList, QList > &nodelist) +{ + int length = curList.length(); + if(length < 2) + { + return; + } + QPair key; + key.first = length; + QString menuTopName; + for(int i=0; i, QList> >::const_iterator iter = m_levelMap.constBegin(); + for(; iter != m_levelMap.constEnd(); iter++) + { + if(iter.key() == key) + { + nodelist.append(iter.value()); + } + } +} + +void CNavInfoManage::readBtnJson(const QString &path) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QString name; + QString data; + QJsonObject root = readJsonResponse.object(); + QJsonObject::const_iterator rootIter = root.constBegin(); + for(; rootIter != root.constEnd(); rootIter++) + { + if(rootIter.key() == "separator") + { + continue; + } + QJsonObject item = rootIter.value().toObject(); + if(item.value("used").toInt() != 1) + { + continue; + } + if(item.value("opt").toInt() != 2) + { + continue; + } + name = item.value("name").toString(); + data = item.value("data").toString(); + QStringList tempList = data.split(","); + int nIndex=0; + foreach (QString temp, tempList) { + if(temp != '0') + { + m_btnMap[nIndex] = name; + } + nIndex++; + } + } +} + +void CNavInfoManage::readNavJson(const QString &path) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QString menuTopName; + QJsonObject root = readJsonResponse.object(); + if(root.contains("items")) + { + QJsonArray itemArray = root.value("items").toArray(); + int nItemNumber = 0; + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + QString topName = topLevelObject.value("name").toString(); + QString topData = topLevelObject.value("data").toString(); + QString topLink = topName + ":" + topData; + STNodeInfo stNodeTop; + int topUsed = topLevelObject.value("used").toInt(); + if(topUsed != 1) + { + nItemNumber++; + continue; + } + QString menu = m_btnMap.value(nItemNumber); + if(!topData.isEmpty()) + { + if(m_parentsMap[topLink].isEmpty()) + { + m_parentsMap[topLink].append(menu); + m_parentsMap[topLink].append(topName); + } + if(m_parentsMap[topData].isEmpty()) + { + m_parentsMap[topData].append(menu); + m_parentsMap[topData].append(topName); + } + stNodeTop.data = topData; + stNodeTop.text = topName; + stNodeTop.opt = topLevelObject.value("opt").toInt(); + stNodeTop.url = topLevelObject.value("url").toString(); + menuTopName = menu; + m_levelMap[QPair(2, menuTopName)].append(QPair(topData, stNodeTop)); + } + + QJsonArray childArray = topLevelObject.value("items").toArray(); + for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) + { + QJsonObject childLevelObject = childArray[nChildIndex].toObject(); + QString childName = childLevelObject.value("name").toString(); + QString childData = childLevelObject.value("data").toString(); + QString childLink = childName + ":" + childData; + STNodeInfo stNodeChild; + int childUsed = topLevelObject.value("used").toInt(); + if(childUsed != 1) + { + continue; + } + if(!childData.isEmpty()) + { + if(m_parentsMap[childLink].isEmpty()) + { + m_parentsMap[childLink].append(menu); + m_parentsMap[childLink].append(topName); + m_parentsMap[childLink].append(childName); + } + if(m_parentsMap[childData].isEmpty()) + { + m_parentsMap[childData].append(menu); + m_parentsMap[childData].append(topName); + m_parentsMap[childData].append(childName); + } + stNodeChild.data = childData; + stNodeChild.text = childName; + stNodeChild.opt = childLevelObject.value("opt").toInt(); + stNodeChild.url = childLevelObject.value("url").toString(); + menuTopName = menu+"/"+topName; + m_levelMap[QPair(3, menuTopName)].append(QPair(childData, stNodeChild)); + if(topData.isEmpty()) + { + topLink = topName + ":" + childData; + if(m_parentsMap[topLink].isEmpty()) + { + m_parentsMap[topLink].append(menu); + m_parentsMap[topLink].append(topName); + m_parentsMap[topLink].append(childName); + } + topData = childData; + stNodeTop.data = childData; + stNodeTop.text = topName; + stNodeTop.opt = stNodeChild.opt; + stNodeTop.url = stNodeChild.url; + menuTopName = menu; + m_levelMap[QPair(2, menuTopName)].append(QPair(topData, stNodeTop)); + } + } + + QJsonArray leafArray = childLevelObject.value("items").toArray(); + for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) + { + QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); + QString leafName = leafLevelObject.value("name").toString(); + QString leafData = leafLevelObject.value("data").toString(); + QString leafLink = leafName + ":" + leafData; + STNodeInfo stNodeleaf; + int leafUsed = topLevelObject.value("used").toInt(); + if(leafUsed != 1) + { + continue; + } + if(!leafData.isEmpty()) + { + if(m_parentsMap[leafLink].isEmpty()) + { + m_parentsMap[leafLink].append(menu); + m_parentsMap[leafLink].append(topName); + m_parentsMap[leafLink].append(childName); + m_parentsMap[leafLink].append(leafName); + } + if(m_parentsMap[leafData].isEmpty()) + { + m_parentsMap[leafData].append(menu); + m_parentsMap[leafData].append(topName); + m_parentsMap[leafData].append(childName); + m_parentsMap[leafData].append(leafName); + } + stNodeleaf.data = leafData; + stNodeleaf.text = leafName; + stNodeleaf.opt = leafLevelObject.value("opt").toInt(); + stNodeleaf.url = leafLevelObject.value("url").toString(); + menuTopName = menu+"/"+topName+"/"+childName; + m_levelMap[QPair(4, menuTopName)].append(QPair(leafData, stNodeleaf)); + if(childData.isEmpty()) + { + childLink = childName + ":" + leafData; + if(m_parentsMap[childLink].isEmpty()) + { + m_parentsMap[childLink].append(menu); + m_parentsMap[childLink].append(topName); + m_parentsMap[childLink].append(childName); + m_parentsMap[childLink].append(leafName); + } + childData = leafData; + stNodeChild.data = leafData; + stNodeChild.text = childName; + stNodeChild.opt = stNodeleaf.opt; + stNodeChild.url = stNodeleaf.url; + menuTopName = menu+"/"+topName; + m_levelMap[QPair(3, menuTopName)].append(QPair(childData, stNodeChild)); + if(topData.isEmpty()) + { + topLink = topName + ":" + leafData; + if(m_parentsMap[topLink].isEmpty()) + { + m_parentsMap[topLink].append(menu); + m_parentsMap[topLink].append(topName); + m_parentsMap[topLink].append(childName); + m_parentsMap[topLink].append(leafName); + } + topData = leafData; + stNodeTop.data = leafData; + stNodeTop.text = topName; + stNodeTop.opt = stNodeleaf.opt; + stNodeTop.url = stNodeleaf.url; + menuTopName = menu; + m_levelMap[QPair(2, menuTopName)].append(QPair(topData, stNodeTop)); + } + } + } + } + } + nItemNumber++; + } + } +} diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CNavInfoManage.h b/product/src/gui/plugin/BreadcrumbNavWidget/CNavInfoManage.h index 9a08978f..8718e052 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CNavInfoManage.h +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CNavInfoManage.h @@ -1,37 +1,37 @@ -#ifndef CJSONREADER_H -#define CJSONREADER_H - -#include -#include - -struct STNodeInfo -{ - QString text; - QString data; - int opt; - QString url; -}; -class CNavInfoManage : public QObject -{ - Q_OBJECT -public: - enum EN_NODE{NODE_MENU=0,NODE_TOP,NODE_CHILD,NODE_LEAF}; - CNavInfoManage(QObject * parent = 0); - - void getParentBreadcrumb(const QString &fileName, QStringList &parents); - - void getSameLevelNode(const QStringList &curList, QList > &nodelist); - -private: - void readBtnJson(const QString &path); - void readNavJson(const QString &path); - -private: - QString m_strButtonFile; - QString m_strNavFile; - QMap m_btnMap; - QMap m_parentsMap; - QMap, QList> > m_levelMap; -}; - -#endif // CJSONREADER_H +#ifndef CJSONREADER_H +#define CJSONREADER_H + +#include +#include + +struct STNodeInfo +{ + QString text; + QString data; + int opt; + QString url; +}; +class CNavInfoManage : public QObject +{ + Q_OBJECT +public: + enum EN_NODE{NODE_MENU=0,NODE_TOP,NODE_CHILD,NODE_LEAF}; + CNavInfoManage(QObject * parent = 0); + + void getParentBreadcrumb(const QString &fileName, QStringList &parents); + + void getSameLevelNode(const QStringList &curList, QList > &nodelist); + +private: + void readBtnJson(const QString &path); + void readNavJson(const QString &path); + +private: + QString m_strButtonFile; + QString m_strNavFile; + QMap m_btnMap; + QMap m_parentsMap; + QMap, QList> > m_levelMap; +}; + +#endif // CJSONREADER_H diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CToolButton.cpp b/product/src/gui/plugin/BreadcrumbNavWidget/CToolButton.cpp index bc3cb028..bde40e1c 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CToolButton.cpp +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CToolButton.cpp @@ -1,40 +1,40 @@ -#include "CToolButton.h" - -CToolButton::CToolButton(QWidget *parent) - : QToolButton(parent) -{ - setArrowType(Qt::NoArrow); - setToolButtonStyle(Qt::ToolButtonTextOnly); - setPopupMode(QToolButton::InstantPopup); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); -} - -void CToolButton::setGraph(const QString &graph) -{ - m_strGraph = graph; -} - -QString CToolButton::getGraph() -{ - return m_strGraph; -} - -void CToolButton::setOpt(int opt) -{ - m_nOpt = opt; -} - -int CToolButton::getOpt() -{ - return m_nOpt; -} - -void CToolButton::setUrl(const QString &url) -{ - m_strUrl = url; -} - -QString CToolButton::getUrl() -{ - return m_strUrl; -} +#include "CToolButton.h" + +CToolButton::CToolButton(QWidget *parent) + : QToolButton(parent) +{ + setArrowType(Qt::NoArrow); + setToolButtonStyle(Qt::ToolButtonTextOnly); + setPopupMode(QToolButton::InstantPopup); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); +} + +void CToolButton::setGraph(const QString &graph) +{ + m_strGraph = graph; +} + +QString CToolButton::getGraph() +{ + return m_strGraph; +} + +void CToolButton::setOpt(int opt) +{ + m_nOpt = opt; +} + +int CToolButton::getOpt() +{ + return m_nOpt; +} + +void CToolButton::setUrl(const QString &url) +{ + m_strUrl = url; +} + +QString CToolButton::getUrl() +{ + return m_strUrl; +} diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CToolButton.h b/product/src/gui/plugin/BreadcrumbNavWidget/CToolButton.h index 551c0a06..92356988 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CToolButton.h +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CToolButton.h @@ -1,25 +1,25 @@ -#ifndef CTOOLBUTTON_H -#define CTOOLBUTTON_H - -#include -#include - -class CToolButton : public QToolButton -{ -public: - CToolButton(QWidget *parent = Q_NULLPTR); - - void setGraph(const QString &graph); - QString getGraph(); - void setOpt(int opt); - int getOpt(); - void setUrl(const QString &url); - QString getUrl(); - -private: - QString m_strGraph; - int m_nOpt{}; - QString m_strUrl; -}; - -#endif // CTOOLBUTTON_H +#ifndef CTOOLBUTTON_H +#define CTOOLBUTTON_H + +#include +#include + +class CToolButton : public QToolButton +{ +public: + CToolButton(QWidget *parent = Q_NULLPTR); + + void setGraph(const QString &graph); + QString getGraph(); + void setOpt(int opt); + int getOpt(); + void setUrl(const QString &url); + QString getUrl(); + +private: + QString m_strGraph; + int m_nOpt{}; + QString m_strUrl; +}; + +#endif // CTOOLBUTTON_H diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/main.cpp b/product/src/gui/plugin/BreadcrumbNavWidget/main.cpp index 6c29ba6b..3df68299 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/main.cpp +++ b/product/src/gui/plugin/BreadcrumbNavWidget/main.cpp @@ -1,11 +1,11 @@ -#include "CBreadcrumbNavWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CBreadcrumbNavWidget w(false); - w.show(); - - return a.exec(); -} +#include "CBreadcrumbNavWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CBreadcrumbNavWidget w(false); + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/BriefReportWidget/BriefReportCommon.h b/product/src/gui/plugin/BriefReportWidget/BriefReportCommon.h index 4a764244..5da8d6fb 100644 --- a/product/src/gui/plugin/BriefReportWidget/BriefReportCommon.h +++ b/product/src/gui/plugin/BriefReportWidget/BriefReportCommon.h @@ -1,17 +1,17 @@ -#ifndef BRIEFREPORTCOMMON_H -#define BRIEFREPORTCOMMON_H - -typedef struct -{ - qint64 TIME_STAMP; - std::string CONTENT; - int LOCATION_ID; -}HIS_EVENT_BRIEF; - -typedef struct -{ - qint64 LOCATION_ID; - std::string DESCRIPTION; -}SYS_MODEL_LOCATION_INFO; - -#endif // BRIEFREPORTCOMMON_H +#ifndef BRIEFREPORTCOMMON_H +#define BRIEFREPORTCOMMON_H + +typedef struct +{ + qint64 TIME_STAMP; + std::string CONTENT; + int LOCATION_ID; +}HIS_EVENT_BRIEF; + +typedef struct +{ + qint64 LOCATION_ID; + std::string DESCRIPTION; +}SYS_MODEL_LOCATION_INFO; + +#endif // BRIEFREPORTCOMMON_H diff --git a/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.cpp b/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.cpp index 5475be5c..02822fbf 100644 --- a/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.cpp +++ b/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "BriefReportPluginWidget.h" -#include "BriefReportWidget.h" - -BriefReportPluginWidget::BriefReportPluginWidget(QObject *parent): QObject(parent) -{ - -} - -BriefReportPluginWidget::~BriefReportPluginWidget() -{ - -} - -bool BriefReportPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **PluginWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - BriefReportWidget *pWidget = new BriefReportWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *PluginWidget = (IPluginWidget *)pWidget; - return true; -} - -void BriefReportPluginWidget::release() -{ - -} +#include "BriefReportPluginWidget.h" +#include "BriefReportWidget.h" + +BriefReportPluginWidget::BriefReportPluginWidget(QObject *parent): QObject(parent) +{ + +} + +BriefReportPluginWidget::~BriefReportPluginWidget() +{ + +} + +bool BriefReportPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **PluginWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + BriefReportWidget *pWidget = new BriefReportWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *PluginWidget = (IPluginWidget *)pWidget; + return true; +} + +void BriefReportPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.h b/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.h index 7c066e4b..7f9eba40 100644 --- a/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.h +++ b/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.h @@ -1,20 +1,20 @@ -#ifndef BRIEFREPORTPLUGINWIDGET_H -#define BRIEFREPORTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class BriefReportPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - BriefReportPluginWidget(QObject *parent = 0); - ~BriefReportPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **PluginWidget, QVector ptrVec); - void release(); -}; - -#endif // BRIEFREPORTPLUGINWIDGET_H +#ifndef BRIEFREPORTPLUGINWIDGET_H +#define BRIEFREPORTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class BriefReportPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + BriefReportPluginWidget(QObject *parent = 0); + ~BriefReportPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **PluginWidget, QVector ptrVec); + void release(); +}; + +#endif // BRIEFREPORTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.cpp b/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.cpp index 78ce9323..99f45885 100644 --- a/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.cpp +++ b/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.cpp @@ -1,539 +1,539 @@ -#include "BriefReportWidget.h" -#include "ui_BriefReportWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" - -BriefReportWidget::BriefReportWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::BriefReportWidget), - m_isEditMode(editMode) -{ - m_thread = NULL; - - ui->setupUi(this); - - QString qss; - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssFile1(QString::fromStdString(strFullPath)); - qssFile1.open(QFile::ReadOnly); - if (qssFile1.isOpen()) - { - qss += QLatin1String(qssFile1.readAll()); - //setStyleSheet(qss); - qssFile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("BriefReport.qss") ; - QFile qssFile2(QString::fromStdString(strFullPath)); - qssFile2.open(QFile::ReadOnly); - if (qssFile2.isOpen()) - { - qss += QLatin1String(qssFile2.readAll()); - //setStyleSheet(qss); - qssFile2.close(); - } - else - { - qDebug() << "BriefReport.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - ui->tabWidget->tabBar()->hide(); - if(!m_isEditMode) - { - Init(); - InitData(); - } -} - -BriefReportWidget::~BriefReportWidget() -{ - delete ui; - -// kbd_public::StopLogSystem(); -} - -void BriefReportWidget::Init() -{ -// kbd_public::StartLogSystem("HMI", "BriefReportWidget" ); - - ui->PushButton3->setVisible(false); - ui->PushButton4->setVisible(false); - - ui->PushButton1->setCheckable(true); - ui->PushButton2->setCheckable(true); - ui->PushButton3->setCheckable(true); - ui->PushButton4->setCheckable(true); - isBeginQuery=false; - - ui->DayButton->setCheckable(true); - ui->WeekButton->setCheckable(true); - ui->MonthButton->setCheckable(true); - ui->QuarterButton->setCheckable(true); - ui->YearButton->setCheckable(true); - - QButtonGroup *buttonGroup = new QButtonGroup(this); - buttonGroup->addButton(ui->DayButton); - buttonGroup->addButton(ui->WeekButton); - buttonGroup->addButton(ui->MonthButton); - buttonGroup->addButton(ui->QuarterButton); - buttonGroup->addButton(ui->YearButton); - - QButtonGroup *buttonGroup1 = new QButtonGroup(this); - buttonGroup1->addButton(ui->PushButton1); - buttonGroup1->addButton(ui->PushButton2); - buttonGroup1->addButton(ui->PushButton3); - buttonGroup1->addButton(ui->PushButton4); - - m_timeIcon = new QPushButton(this); - m_myCalendar = new CMyCalendar(this); - QWidgetAction *widgetAction=new QWidgetAction(this); - m_timeMenu = new QMenu(this); - widgetAction->setDefaultWidget(m_myCalendar); - m_timeMenu->addAction(widgetAction); - m_timeIcon->setObjectName("iconButton"); - m_timeIcon->setText(""); - m_timeIcon->setMaximumSize(21, 22); - m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); - QHBoxLayout * pTimeLayout = new QHBoxLayout(); - pTimeLayout->setContentsMargins(1, 1, 1, 1); - pTimeLayout->addStretch(); - pTimeLayout->addWidget(m_timeIcon); - ui->lineEdit->setLayout(pTimeLayout); - connect(m_timeIcon,&QPushButton::clicked,this,&BriefReportWidget::myCalendarShow); - connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&BriefReportWidget::myCalendarHide); - connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&BriefReportWidget::cancleTimeFilter); - //ui->lineEdit->setText(tr("请选择时间")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit->setObjectName("iconLineEdit"); - - ui->TableWidget1->setColumnCount(3); - QStringList header1; - header1<<"时间"<<"位置"<<"关键告警"; - ui->TableWidget1->setHorizontalHeaderLabels(header1); - ui->TableWidget1->verticalHeader()->setVisible(false); - //ui->TableWidget1->horizontalHeader()->setVisible(false); - ui->TableWidget1->horizontalHeader()->setStretchLastSection(true); - ui->TableWidget1->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->TableWidget1->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->TableWidget1->setFocusPolicy(Qt::NoFocus); - ui->TableWidget1->setColumnWidth(0,200); - ui->TableWidget1->setColumnWidth(1,200); - - ui->TableWidget2->setColumnCount(3); - QStringList header2; - header2<<"时间"<<"位置"<<"操作记录"; - ui->TableWidget2->setHorizontalHeaderLabels(header2); - ui->TableWidget2->verticalHeader()->setVisible(false); - //ui->TableWidget2->horizontalHeader()->setVisible(false); - ui->TableWidget2->horizontalHeader()->setStretchLastSection(true); - ui->TableWidget2->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->TableWidget2->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->TableWidget2->setFocusPolicy(Qt::NoFocus); - ui->TableWidget2->setColumnWidth(0,200); - ui->TableWidget2->setColumnWidth(1,200); - - ui->TableWidget3->setColumnCount(3); - QStringList header3; - header3<<"时间"<<"位置"<<"巡检记录"; - ui->TableWidget3->setHorizontalHeaderLabels(header3); - ui->TableWidget3->verticalHeader()->setVisible(false); - //ui->TableWidget3->horizontalHeader()->setVisible(false); - ui->TableWidget3->horizontalHeader()->setStretchLastSection(true); - ui->TableWidget3->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->TableWidget3->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->TableWidget3->setFocusPolicy(Qt::NoFocus); - - ui->TableWidget4->setColumnCount(3); - QStringList header4; - header4<<"时间"<<"位置"<<"检修记录"; - ui->TableWidget4->setHorizontalHeaderLabels(header4); - ui->TableWidget4->verticalHeader()->setVisible(false); - //ui->TableWidget4->horizontalHeader()->setVisible(false); - ui->TableWidget4->horizontalHeader()->setStretchLastSection(true); - ui->TableWidget4->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->TableWidget4->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->TableWidget4->setFocusPolicy(Qt::NoFocus); -} - -void BriefReportWidget::InitData() -{ - kbd_dbms::CDbApi *m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - if(!m_pReadDb->open()) - { - LOGERROR("打开数据库连接失败! %s", m_pReadDb->getLastErrorString().toStdString().c_str()); - delete m_pReadDb; - return; - } - QString strSql; - QSqlQuery objRet; - - SYS_MODEL_LOCATION_INFO Location; - strSql = "select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Location.LOCATION_ID=objRet.value(0).toLongLong(); - Location.DESCRIPTION=objRet.value(1).toString().toStdString(); - Locations.push_back(Location); - } - } - ui->LocationBox->addItem("全部"); - for(size_t i=0;iLocationBox->addItem(Locations.at(i).DESCRIPTION.c_str()); - } - - QDateTime begin_time=QDateTime::currentDateTime(); - QString time=begin_time.toString("yyyy-MM-dd 00:00:00.000"); - begin_time=QDateTime::fromString(time,"yyyy-MM-dd hh:mm:ss.zzz"); - QDateTime end_time=QDateTime::currentDateTime(); - QString time1=end_time.toString("yyyy-MM-dd 23:59:59.999"); - end_time=QDateTime::fromString(time1,"yyyy-MM-dd hh:mm:ss.zzz"); - - ui->lineEdit->setText(begin_time.toString("yyyy-MM-dd hh:mm") +" ~ "+end_time.toString("yyyy-MM-dd hh:mm")); - m_start=begin_time; - m_end=end_time; - ui->DayButton->setChecked(true); - ui->PushButton1->setChecked(true); - m_pReadDb->close(); - delete m_pReadDb; -} - -void BriefReportWidget::QueryDB(QDateTime startTime, QDateTime endTime) -{ - //ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); - - if(m_thread) - { - delete m_thread; - m_thread=NULL; - } - - m_thread=new QueryThread(); - m_thread->start_time=startTime; - m_thread->end_time=endTime; - if(ui->LocationBox->currentIndex()>0) - { - m_thread->islocation=true; - for(size_t i=0;iLocationBox->currentText()==Locations.at(i).DESCRIPTION.c_str()) - { - m_thread->location_id=Locations.at(i).LOCATION_ID; - } - } - } - qRegisterMetaType>("std::vector"); - connect(m_thread,&QueryThread::signal_QueryEnd,this,&BriefReportWidget::slot_QueryEnd); - - m_thread->start(); - - m_dlg=new QProgressDialog(); - m_dlg->setWindowFlag(Qt::FramelessWindowHint); - //dlg->setAttribute(Qt::WA_TranslucentBackground); - - m_bar=new QProgressBar(); - m_bar->setAlignment(Qt::AlignCenter); - m_bar->setOrientation(Qt::Horizontal); - m_bar->setMinimum(0); - m_bar->setMaximum(0); - m_dlg->setBar(m_bar); - m_button=new QPushButton(); - connect(m_button,&QPushButton::clicked,this,&BriefReportWidget::slot_QueryStop); - m_button->setText("取消"); - m_dlg->setCancelButton(m_button); - m_dlg->setLabelText("查询中,请等待..."); - m_dlg->exec(); -} - -void BriefReportWidget::myCalendarHide(QDateTime startTime, QDateTime endTime) -{ - m_timeMenu->hide(); - //开始查询 - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); - m_start=startTime; - m_end=endTime; - - //QueryDB(startTime,endTime); -} - -void BriefReportWidget::myCalendarShow() -{ - QPoint point(QCursor::pos().x()-250,QCursor::pos().y()+15); - m_timeMenu->move(point); - m_timeMenu->show(); -} - -void BriefReportWidget::cancleTimeFilter() -{ - m_timeMenu->hide(); -} - -void BriefReportWidget::slot_QueryEnd(std::vector Events, std::vector Events_Operates) -{ - m_dlg->close(); - - QDateTime date_time; - QString time; - ui->PushButton1->setText("关键告警\n"+QString::number(Events.size(),10)); - ui->TableWidget1->setRowCount(0); - for(quint64 i=0;iTableWidget1->insertRow(ui->TableWidget1->rowCount()); - ui->TableWidget1->setItem(i,0,new QTableWidgetItem(time)); - for(size_t j=0;jTableWidget1->setItem(i,1,new QTableWidgetItem(Locations.at(j).DESCRIPTION.c_str())); - } - } - ui->TableWidget1->setItem(i,2,new QTableWidgetItem(Events.at(i).CONTENT.c_str())); - } - - ui->PushButton2->setText("操作记录\n"+QString::number(Events_Operates.size(),10)); - ui->TableWidget2->setRowCount(0); - for(quint64 i=0;iTableWidget2->insertRow(ui->TableWidget2->rowCount()); - ui->TableWidget2->setItem(i,0,new QTableWidgetItem(time)); - for(size_t j=0;jTableWidget2->setItem(i,1,new QTableWidgetItem(Locations.at(j).DESCRIPTION.c_str())); - } - } - ui->TableWidget2->setItem(i,2,new QTableWidgetItem(Events_Operates.at(i).CONTENT.c_str())); - } - if(m_thread) - { - delete m_thread; - m_thread=NULL; - } -} - -void BriefReportWidget::slot_QueryStop() -{ - if(m_thread) - { - m_thread->terminate(); - delete m_thread; - m_thread=NULL; - } -} - -void BriefReportWidget::on_DayButton_clicked() -{ - QDateTime startTime=QDateTime::currentDateTime(); - QDateTime endTime=QDateTime::currentDateTime(); - startTime.setTime(QTime(0,0,0,0)); - endTime.setTime(QTime(23,59,59,999)); - - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); - m_start=startTime; - m_end=endTime; - - ui->DayButton->setChecked(true); - //QueryDB(startTime,endTime); -} - -void BriefReportWidget::on_WeekButton_clicked() -{ - QDateTime current = QDateTime::currentDateTime(); - QDateTime endTime=current.addDays(7-current.date().dayOfWeek());; - QDateTime startTime=current.addDays(-current.date().dayOfWeek()+1);; - startTime.setTime(QTime(0,0,0,0)); - endTime.setTime(QTime(23,59,59,999)); - - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); - m_start=startTime; - m_end=endTime; - - ui->WeekButton->setChecked(true); - //QueryDB(startTime,endTime); -} - -void BriefReportWidget::on_MonthButton_clicked() -{ - QDateTime current = QDateTime::currentDateTime(); - current.setTime(QTime(0,0,0,0)); - current.setDate(QDate(current.date().year(), current.date().month(), 1)); - QDateTime startTime=current; - current.setDate(QDate(current.date().year(), current.date().month(), current.date().daysInMonth())); - current.setTime(QTime(23,59,59,999)); - QDateTime endTime=current; - - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); - m_start=startTime; - m_end=endTime; - - ui->MonthButton->setChecked(true); - //QueryDB(startTime,endTime); -} - -void BriefReportWidget::on_QuarterButton_clicked() -{ - QDateTime current = QDateTime::currentDateTime(); - QDateTime startTime = current; - QDateTime endTime = current; - QString month = QString::number(current.date().month()); - if(QString("1,2,3").split(",").indexOf(month) != -1) - { - endTime.setDate(QDate(current.date().year(), 3, 31)); - startTime.setDate(QDate(current.date().year(), 1, 1)); - } - else if(QString("4,5,6").split(",").indexOf(month) != -1) - { - endTime.setDate(QDate(current.date().year(), 6, 30)); - startTime.setDate(QDate(current.date().year(), 4, 1)); - } - else if(QString("7,8,9").split(",").indexOf(month) != -1) - { - endTime.setDate(QDate(current.date().year(), 9, 30)); - startTime.setDate(QDate(current.date().year(), 7, 1)); - } - else if(QString("10,11,12").split(",").indexOf(month) != -1) - { - endTime.setDate(QDate(current.date().year(), 12, 31)); - startTime.setDate(QDate(current.date().year(), 10, 1)); - } - - startTime.setTime(QTime(0,0,0,0)); - endTime.setTime(QTime(23,59,59,999)); - - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); - m_start=startTime; - m_end=endTime; - - ui->QuarterButton->setChecked(true); - //QueryDB(startTime,endTime); -} - -void BriefReportWidget::on_YearButton_clicked() -{ - QDateTime current = QDateTime::currentDateTime(); - current.setDate(QDate(current.date().year(), 1, 1)); - current.setTime(QTime(0,0,0,0)); - QDateTime startTime=current; - current.setDate(QDate(current.date().year(), 12, 31)); - current.setTime(QTime(23,59,59,999)); - QDateTime endTime=current; - - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); - m_start=startTime; - m_end=endTime; - - ui->YearButton->setChecked(true); - //QueryDB(startTime,endTime); -} - -void BriefReportWidget::on_PushButton1_clicked() -{ - ui->tabWidget->setCurrentIndex(0); -} - -void BriefReportWidget::on_PushButton2_clicked() -{ - ui->tabWidget->setCurrentIndex(1); -} - -void BriefReportWidget::on_PushButton3_clicked() -{ - ui->tabWidget->setCurrentIndex(2); -} - -void BriefReportWidget::on_PushButton4_clicked() -{ - ui->tabWidget->setCurrentIndex(3); -} - -void BriefReportWidget::on_ExportButton_clicked() -{ - if(ui->TableWidget1->rowCount()<1 && ui->TableWidget2->rowCount()<1) - { - QMessageBox::critical(this,"提示","没有记录,无法导出"); - return; - } - QString sExcelFileName = QString("Report(%1~%2).xlsx") - .arg(m_start.toString("yyyyMMddhhmm")) - .arg(m_end.toString("yyyyMMddhhmm")); - - QString fileName=QFileDialog::getSaveFileName(this,tr("保存"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) - +QDir::separator()+sExcelFileName,"Excel 文件(*.xlsx)");//获取保存路径*.xls - if(!fileName.isEmpty()) - { - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "关键告警" ); - // 写横向表头 - QStringList header1; - header1<TableWidget1->rowCount(); - int colcount=ui->TableWidget1->columnCount(); - // 写内容 - for ( int i=0; iTableWidget1->item(i,j)->text(); - xlsx.write( i+2, j+1, sText ); - } - } - - xlsx.addSheet( "操作记录" ); - // 写横向表头 - QStringList header2; - header2<TableWidget2->rowCount(); - colcount=ui->TableWidget2->columnCount(); - // 写内容 - for ( int i=0; iTableWidget2->item(i,j)->text(); - xlsx.write( i+2, j+1, sText ); - } - } - - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - - // 提示导出路径 - QMessageBox::information( 0, "提示", "导出完成\n文件为:"+sExcelFileName); - } -} - -void BriefReportWidget::on_QueryButton_clicked() -{ - QueryDB(m_start,m_end); -} +#include "BriefReportWidget.h" +#include "ui_BriefReportWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" + +BriefReportWidget::BriefReportWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::BriefReportWidget), + m_isEditMode(editMode) +{ + m_thread = NULL; + + ui->setupUi(this); + + QString qss; + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssFile1(QString::fromStdString(strFullPath)); + qssFile1.open(QFile::ReadOnly); + if (qssFile1.isOpen()) + { + qss += QLatin1String(qssFile1.readAll()); + //setStyleSheet(qss); + qssFile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("BriefReport.qss") ; + QFile qssFile2(QString::fromStdString(strFullPath)); + qssFile2.open(QFile::ReadOnly); + if (qssFile2.isOpen()) + { + qss += QLatin1String(qssFile2.readAll()); + //setStyleSheet(qss); + qssFile2.close(); + } + else + { + qDebug() << "BriefReport.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + ui->tabWidget->tabBar()->hide(); + if(!m_isEditMode) + { + Init(); + InitData(); + } +} + +BriefReportWidget::~BriefReportWidget() +{ + delete ui; + +// kbd_public::StopLogSystem(); +} + +void BriefReportWidget::Init() +{ +// kbd_public::StartLogSystem("HMI", "BriefReportWidget" ); + + ui->PushButton3->setVisible(false); + ui->PushButton4->setVisible(false); + + ui->PushButton1->setCheckable(true); + ui->PushButton2->setCheckable(true); + ui->PushButton3->setCheckable(true); + ui->PushButton4->setCheckable(true); + isBeginQuery=false; + + ui->DayButton->setCheckable(true); + ui->WeekButton->setCheckable(true); + ui->MonthButton->setCheckable(true); + ui->QuarterButton->setCheckable(true); + ui->YearButton->setCheckable(true); + + QButtonGroup *buttonGroup = new QButtonGroup(this); + buttonGroup->addButton(ui->DayButton); + buttonGroup->addButton(ui->WeekButton); + buttonGroup->addButton(ui->MonthButton); + buttonGroup->addButton(ui->QuarterButton); + buttonGroup->addButton(ui->YearButton); + + QButtonGroup *buttonGroup1 = new QButtonGroup(this); + buttonGroup1->addButton(ui->PushButton1); + buttonGroup1->addButton(ui->PushButton2); + buttonGroup1->addButton(ui->PushButton3); + buttonGroup1->addButton(ui->PushButton4); + + m_timeIcon = new QPushButton(this); + m_myCalendar = new CMyCalendar(this); + QWidgetAction *widgetAction=new QWidgetAction(this); + m_timeMenu = new QMenu(this); + widgetAction->setDefaultWidget(m_myCalendar); + m_timeMenu->addAction(widgetAction); + m_timeIcon->setObjectName("iconButton"); + m_timeIcon->setText(""); + m_timeIcon->setMaximumSize(21, 22); + m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_timeIcon); + ui->lineEdit->setLayout(pTimeLayout); + connect(m_timeIcon,&QPushButton::clicked,this,&BriefReportWidget::myCalendarShow); + connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&BriefReportWidget::myCalendarHide); + connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&BriefReportWidget::cancleTimeFilter); + //ui->lineEdit->setText(tr("请选择时间")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit->setObjectName("iconLineEdit"); + + ui->TableWidget1->setColumnCount(3); + QStringList header1; + header1<<"时间"<<"位置"<<"关键告警"; + ui->TableWidget1->setHorizontalHeaderLabels(header1); + ui->TableWidget1->verticalHeader()->setVisible(false); + //ui->TableWidget1->horizontalHeader()->setVisible(false); + ui->TableWidget1->horizontalHeader()->setStretchLastSection(true); + ui->TableWidget1->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->TableWidget1->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->TableWidget1->setFocusPolicy(Qt::NoFocus); + ui->TableWidget1->setColumnWidth(0,200); + ui->TableWidget1->setColumnWidth(1,200); + + ui->TableWidget2->setColumnCount(3); + QStringList header2; + header2<<"时间"<<"位置"<<"操作记录"; + ui->TableWidget2->setHorizontalHeaderLabels(header2); + ui->TableWidget2->verticalHeader()->setVisible(false); + //ui->TableWidget2->horizontalHeader()->setVisible(false); + ui->TableWidget2->horizontalHeader()->setStretchLastSection(true); + ui->TableWidget2->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->TableWidget2->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->TableWidget2->setFocusPolicy(Qt::NoFocus); + ui->TableWidget2->setColumnWidth(0,200); + ui->TableWidget2->setColumnWidth(1,200); + + ui->TableWidget3->setColumnCount(3); + QStringList header3; + header3<<"时间"<<"位置"<<"巡检记录"; + ui->TableWidget3->setHorizontalHeaderLabels(header3); + ui->TableWidget3->verticalHeader()->setVisible(false); + //ui->TableWidget3->horizontalHeader()->setVisible(false); + ui->TableWidget3->horizontalHeader()->setStretchLastSection(true); + ui->TableWidget3->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->TableWidget3->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->TableWidget3->setFocusPolicy(Qt::NoFocus); + + ui->TableWidget4->setColumnCount(3); + QStringList header4; + header4<<"时间"<<"位置"<<"检修记录"; + ui->TableWidget4->setHorizontalHeaderLabels(header4); + ui->TableWidget4->verticalHeader()->setVisible(false); + //ui->TableWidget4->horizontalHeader()->setVisible(false); + ui->TableWidget4->horizontalHeader()->setStretchLastSection(true); + ui->TableWidget4->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->TableWidget4->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->TableWidget4->setFocusPolicy(Qt::NoFocus); +} + +void BriefReportWidget::InitData() +{ + kbd_dbms::CDbApi *m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + LOGERROR("打开数据库连接失败! %s", m_pReadDb->getLastErrorString().toStdString().c_str()); + delete m_pReadDb; + return; + } + QString strSql; + QSqlQuery objRet; + + SYS_MODEL_LOCATION_INFO Location; + strSql = "select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Location.LOCATION_ID=objRet.value(0).toLongLong(); + Location.DESCRIPTION=objRet.value(1).toString().toStdString(); + Locations.push_back(Location); + } + } + ui->LocationBox->addItem("全部"); + for(size_t i=0;iLocationBox->addItem(Locations.at(i).DESCRIPTION.c_str()); + } + + QDateTime begin_time=QDateTime::currentDateTime(); + QString time=begin_time.toString("yyyy-MM-dd 00:00:00.000"); + begin_time=QDateTime::fromString(time,"yyyy-MM-dd hh:mm:ss.zzz"); + QDateTime end_time=QDateTime::currentDateTime(); + QString time1=end_time.toString("yyyy-MM-dd 23:59:59.999"); + end_time=QDateTime::fromString(time1,"yyyy-MM-dd hh:mm:ss.zzz"); + + ui->lineEdit->setText(begin_time.toString("yyyy-MM-dd hh:mm") +" ~ "+end_time.toString("yyyy-MM-dd hh:mm")); + m_start=begin_time; + m_end=end_time; + ui->DayButton->setChecked(true); + ui->PushButton1->setChecked(true); + m_pReadDb->close(); + delete m_pReadDb; +} + +void BriefReportWidget::QueryDB(QDateTime startTime, QDateTime endTime) +{ + //ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); + + if(m_thread) + { + delete m_thread; + m_thread=NULL; + } + + m_thread=new QueryThread(); + m_thread->start_time=startTime; + m_thread->end_time=endTime; + if(ui->LocationBox->currentIndex()>0) + { + m_thread->islocation=true; + for(size_t i=0;iLocationBox->currentText()==Locations.at(i).DESCRIPTION.c_str()) + { + m_thread->location_id=Locations.at(i).LOCATION_ID; + } + } + } + qRegisterMetaType>("std::vector"); + connect(m_thread,&QueryThread::signal_QueryEnd,this,&BriefReportWidget::slot_QueryEnd); + + m_thread->start(); + + m_dlg=new QProgressDialog(); + m_dlg->setWindowFlag(Qt::FramelessWindowHint); + //dlg->setAttribute(Qt::WA_TranslucentBackground); + + m_bar=new QProgressBar(); + m_bar->setAlignment(Qt::AlignCenter); + m_bar->setOrientation(Qt::Horizontal); + m_bar->setMinimum(0); + m_bar->setMaximum(0); + m_dlg->setBar(m_bar); + m_button=new QPushButton(); + connect(m_button,&QPushButton::clicked,this,&BriefReportWidget::slot_QueryStop); + m_button->setText("取消"); + m_dlg->setCancelButton(m_button); + m_dlg->setLabelText("查询中,请等待..."); + m_dlg->exec(); +} + +void BriefReportWidget::myCalendarHide(QDateTime startTime, QDateTime endTime) +{ + m_timeMenu->hide(); + //开始查询 + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); + m_start=startTime; + m_end=endTime; + + //QueryDB(startTime,endTime); +} + +void BriefReportWidget::myCalendarShow() +{ + QPoint point(QCursor::pos().x()-250,QCursor::pos().y()+15); + m_timeMenu->move(point); + m_timeMenu->show(); +} + +void BriefReportWidget::cancleTimeFilter() +{ + m_timeMenu->hide(); +} + +void BriefReportWidget::slot_QueryEnd(std::vector Events, std::vector Events_Operates) +{ + m_dlg->close(); + + QDateTime date_time; + QString time; + ui->PushButton1->setText("关键告警\n"+QString::number(Events.size(),10)); + ui->TableWidget1->setRowCount(0); + for(quint64 i=0;iTableWidget1->insertRow(ui->TableWidget1->rowCount()); + ui->TableWidget1->setItem(i,0,new QTableWidgetItem(time)); + for(size_t j=0;jTableWidget1->setItem(i,1,new QTableWidgetItem(Locations.at(j).DESCRIPTION.c_str())); + } + } + ui->TableWidget1->setItem(i,2,new QTableWidgetItem(Events.at(i).CONTENT.c_str())); + } + + ui->PushButton2->setText("操作记录\n"+QString::number(Events_Operates.size(),10)); + ui->TableWidget2->setRowCount(0); + for(quint64 i=0;iTableWidget2->insertRow(ui->TableWidget2->rowCount()); + ui->TableWidget2->setItem(i,0,new QTableWidgetItem(time)); + for(size_t j=0;jTableWidget2->setItem(i,1,new QTableWidgetItem(Locations.at(j).DESCRIPTION.c_str())); + } + } + ui->TableWidget2->setItem(i,2,new QTableWidgetItem(Events_Operates.at(i).CONTENT.c_str())); + } + if(m_thread) + { + delete m_thread; + m_thread=NULL; + } +} + +void BriefReportWidget::slot_QueryStop() +{ + if(m_thread) + { + m_thread->terminate(); + delete m_thread; + m_thread=NULL; + } +} + +void BriefReportWidget::on_DayButton_clicked() +{ + QDateTime startTime=QDateTime::currentDateTime(); + QDateTime endTime=QDateTime::currentDateTime(); + startTime.setTime(QTime(0,0,0,0)); + endTime.setTime(QTime(23,59,59,999)); + + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); + m_start=startTime; + m_end=endTime; + + ui->DayButton->setChecked(true); + //QueryDB(startTime,endTime); +} + +void BriefReportWidget::on_WeekButton_clicked() +{ + QDateTime current = QDateTime::currentDateTime(); + QDateTime endTime=current.addDays(7-current.date().dayOfWeek());; + QDateTime startTime=current.addDays(-current.date().dayOfWeek()+1);; + startTime.setTime(QTime(0,0,0,0)); + endTime.setTime(QTime(23,59,59,999)); + + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); + m_start=startTime; + m_end=endTime; + + ui->WeekButton->setChecked(true); + //QueryDB(startTime,endTime); +} + +void BriefReportWidget::on_MonthButton_clicked() +{ + QDateTime current = QDateTime::currentDateTime(); + current.setTime(QTime(0,0,0,0)); + current.setDate(QDate(current.date().year(), current.date().month(), 1)); + QDateTime startTime=current; + current.setDate(QDate(current.date().year(), current.date().month(), current.date().daysInMonth())); + current.setTime(QTime(23,59,59,999)); + QDateTime endTime=current; + + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); + m_start=startTime; + m_end=endTime; + + ui->MonthButton->setChecked(true); + //QueryDB(startTime,endTime); +} + +void BriefReportWidget::on_QuarterButton_clicked() +{ + QDateTime current = QDateTime::currentDateTime(); + QDateTime startTime = current; + QDateTime endTime = current; + QString month = QString::number(current.date().month()); + if(QString("1,2,3").split(",").indexOf(month) != -1) + { + endTime.setDate(QDate(current.date().year(), 3, 31)); + startTime.setDate(QDate(current.date().year(), 1, 1)); + } + else if(QString("4,5,6").split(",").indexOf(month) != -1) + { + endTime.setDate(QDate(current.date().year(), 6, 30)); + startTime.setDate(QDate(current.date().year(), 4, 1)); + } + else if(QString("7,8,9").split(",").indexOf(month) != -1) + { + endTime.setDate(QDate(current.date().year(), 9, 30)); + startTime.setDate(QDate(current.date().year(), 7, 1)); + } + else if(QString("10,11,12").split(",").indexOf(month) != -1) + { + endTime.setDate(QDate(current.date().year(), 12, 31)); + startTime.setDate(QDate(current.date().year(), 10, 1)); + } + + startTime.setTime(QTime(0,0,0,0)); + endTime.setTime(QTime(23,59,59,999)); + + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); + m_start=startTime; + m_end=endTime; + + ui->QuarterButton->setChecked(true); + //QueryDB(startTime,endTime); +} + +void BriefReportWidget::on_YearButton_clicked() +{ + QDateTime current = QDateTime::currentDateTime(); + current.setDate(QDate(current.date().year(), 1, 1)); + current.setTime(QTime(0,0,0,0)); + QDateTime startTime=current; + current.setDate(QDate(current.date().year(), 12, 31)); + current.setTime(QTime(23,59,59,999)); + QDateTime endTime=current; + + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd hh:mm") +" ~ "+endTime.toString("yyyy-MM-dd hh:mm")); + m_start=startTime; + m_end=endTime; + + ui->YearButton->setChecked(true); + //QueryDB(startTime,endTime); +} + +void BriefReportWidget::on_PushButton1_clicked() +{ + ui->tabWidget->setCurrentIndex(0); +} + +void BriefReportWidget::on_PushButton2_clicked() +{ + ui->tabWidget->setCurrentIndex(1); +} + +void BriefReportWidget::on_PushButton3_clicked() +{ + ui->tabWidget->setCurrentIndex(2); +} + +void BriefReportWidget::on_PushButton4_clicked() +{ + ui->tabWidget->setCurrentIndex(3); +} + +void BriefReportWidget::on_ExportButton_clicked() +{ + if(ui->TableWidget1->rowCount()<1 && ui->TableWidget2->rowCount()<1) + { + QMessageBox::critical(this,"提示","没有记录,无法导出"); + return; + } + QString sExcelFileName = QString("Report(%1~%2).xlsx") + .arg(m_start.toString("yyyyMMddhhmm")) + .arg(m_end.toString("yyyyMMddhhmm")); + + QString fileName=QFileDialog::getSaveFileName(this,tr("保存"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + +QDir::separator()+sExcelFileName,"Excel 文件(*.xlsx)");//获取保存路径*.xls + if(!fileName.isEmpty()) + { + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "关键告警" ); + // 写横向表头 + QStringList header1; + header1<TableWidget1->rowCount(); + int colcount=ui->TableWidget1->columnCount(); + // 写内容 + for ( int i=0; iTableWidget1->item(i,j)->text(); + xlsx.write( i+2, j+1, sText ); + } + } + + xlsx.addSheet( "操作记录" ); + // 写横向表头 + QStringList header2; + header2<TableWidget2->rowCount(); + colcount=ui->TableWidget2->columnCount(); + // 写内容 + for ( int i=0; iTableWidget2->item(i,j)->text(); + xlsx.write( i+2, j+1, sText ); + } + } + + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + + // 提示导出路径 + QMessageBox::information( 0, "提示", "导出完成\n文件为:"+sExcelFileName); + } +} + +void BriefReportWidget::on_QueryButton_clicked() +{ + QueryDB(m_start,m_end); +} diff --git a/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.h b/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.h index 33ff5edf..a0147cd9 100644 --- a/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.h +++ b/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.h @@ -1,84 +1,84 @@ -#ifndef BRIEFREPORTWIDGET_H -#define BRIEFREPORTWIDGET_H - -#include -#include -#include "CMyCalendar.h" -#include "BriefReportCommon.h" -#include "QueryThread.h" -#include -#include "model_excel/xlsx/xlsxdocument.h" -#include "dbms/db_api_ex/CDbApi.h" - -namespace Ui { -class BriefReportWidget; -} - -class BriefReportWidget : public QWidget -{ - Q_OBJECT - -public: - explicit BriefReportWidget(QWidget *parent = 0, bool editMode = false); - ~BriefReportWidget(); - - void Init(); - void InitData(); - - void QueryDB(QDateTime startTime, QDateTime endTime); -protected slots: - void myCalendarHide(QDateTime startTime, QDateTime endTime); - void myCalendarShow(); - void cancleTimeFilter(); - - void slot_QueryEnd(std::vector Events,std::vector Events_Operates); - - void slot_QueryStop(); - -private slots: - void on_DayButton_clicked(); - - void on_WeekButton_clicked(); - - void on_MonthButton_clicked(); - - void on_QuarterButton_clicked(); - - void on_YearButton_clicked(); - - void on_PushButton1_clicked(); - - void on_PushButton2_clicked(); - - void on_PushButton3_clicked(); - - void on_PushButton4_clicked(); - - void on_ExportButton_clicked(); - - void on_QueryButton_clicked(); - -private: - Ui::BriefReportWidget *ui; - - bool m_isEditMode; - - QPushButton *m_timeIcon; - CMyCalendar * m_myCalendar; - QMenu *m_timeMenu; - - QueryThread *m_thread; - - QProgressDialog *m_dlg; - QProgressBar *m_bar; - QPushButton *m_button; - - QDateTime m_start; - QDateTime m_end; - - bool isBeginQuery; - - std::vector Locations; -}; - -#endif // BRIEFREPORTWIDGET_H +#ifndef BRIEFREPORTWIDGET_H +#define BRIEFREPORTWIDGET_H + +#include +#include +#include "CMyCalendar.h" +#include "BriefReportCommon.h" +#include "QueryThread.h" +#include +#include "model_excel/xlsx/xlsxdocument.h" +#include "dbms/db_api_ex/CDbApi.h" + +namespace Ui { +class BriefReportWidget; +} + +class BriefReportWidget : public QWidget +{ + Q_OBJECT + +public: + explicit BriefReportWidget(QWidget *parent = 0, bool editMode = false); + ~BriefReportWidget(); + + void Init(); + void InitData(); + + void QueryDB(QDateTime startTime, QDateTime endTime); +protected slots: + void myCalendarHide(QDateTime startTime, QDateTime endTime); + void myCalendarShow(); + void cancleTimeFilter(); + + void slot_QueryEnd(std::vector Events,std::vector Events_Operates); + + void slot_QueryStop(); + +private slots: + void on_DayButton_clicked(); + + void on_WeekButton_clicked(); + + void on_MonthButton_clicked(); + + void on_QuarterButton_clicked(); + + void on_YearButton_clicked(); + + void on_PushButton1_clicked(); + + void on_PushButton2_clicked(); + + void on_PushButton3_clicked(); + + void on_PushButton4_clicked(); + + void on_ExportButton_clicked(); + + void on_QueryButton_clicked(); + +private: + Ui::BriefReportWidget *ui; + + bool m_isEditMode; + + QPushButton *m_timeIcon; + CMyCalendar * m_myCalendar; + QMenu *m_timeMenu; + + QueryThread *m_thread; + + QProgressDialog *m_dlg; + QProgressBar *m_bar; + QPushButton *m_button; + + QDateTime m_start; + QDateTime m_end; + + bool isBeginQuery; + + std::vector Locations; +}; + +#endif // BRIEFREPORTWIDGET_H diff --git a/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.pro b/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.pro index 5879a7a1..f383317a 100644 --- a/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.pro +++ b/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.pro @@ -1,62 +1,62 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-11-26T16:09:59 -# -#------------------------------------------------- - -QT += core gui printsupport sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - - -TARGET = BriefReportWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -LIBS += -ldb_base_api -ldb_api_ex -lpub_utility_api -lmodel_excel -llog4cplus -lpub_logger_api - -SOURCES += \ - main.cpp \ - BriefReportWidget.cpp \ - CMyCalendar.cpp \ - CTableViewPrinter.cpp \ - BriefReportPluginWidget.cpp \ - QueryThread.cpp - -HEADERS += \ - BriefReportWidget.h \ - CMyCalendar.h \ - CTableViewPrinter.h \ - BriefReportCommon.h \ - BriefReportPluginWidget.h \ - QueryThread.h - -FORMS += \ - BriefReportWidget.ui \ - CMyCalendar.ui - -#include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -RESOURCES += \ - resource.qrc - -DISTFILES += +#------------------------------------------------- +# +# Project created by QtCreator 2019-11-26T16:09:59 +# +#------------------------------------------------- + +QT += core gui printsupport sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + + +TARGET = BriefReportWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +LIBS += -ldb_base_api -ldb_api_ex -lpub_utility_api -lmodel_excel -llog4cplus -lpub_logger_api + +SOURCES += \ + main.cpp \ + BriefReportWidget.cpp \ + CMyCalendar.cpp \ + CTableViewPrinter.cpp \ + BriefReportPluginWidget.cpp \ + QueryThread.cpp + +HEADERS += \ + BriefReportWidget.h \ + CMyCalendar.h \ + CTableViewPrinter.h \ + BriefReportCommon.h \ + BriefReportPluginWidget.h \ + QueryThread.h + +FORMS += \ + BriefReportWidget.ui \ + CMyCalendar.ui + +#include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +RESOURCES += \ + resource.qrc + +DISTFILES += diff --git a/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.ui b/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.ui index fca8a31c..97d7cb34 100644 --- a/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.ui +++ b/product/src/gui/plugin/BriefReportWidget/BriefReportWidget.ui @@ -1,411 +1,411 @@ - - - BriefReportWidget - - - - 0 - 0 - 1080 - 515 - - - - 运行简报 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 位置 - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - 400 - 16777215 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 查询 - - - - - - - Qt::Horizontal - - - - 129 - 20 - - - - - - - - 导出 - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 220 - 60 - - - - - 8 - - - - 关键告警 - - - - :/res/记录.png:/res/记录.png - - - - 40 - 40 - - - - false - - - - - - - - 220 - 60 - - - - - 8 - - - - 操作记录 - - - - :/res/记录.png:/res/记录.png - - - - 40 - 40 - - - - - - - - - 220 - 60 - - - - - 8 - - - - 巡检记录 - - - - :/res/记录.png:/res/记录.png - - - - 40 - 40 - - - - - - - - - 220 - 60 - - - - - 8 - - - - 检修记录 - - - - :/res/记录.png:/res/记录.png - - - - 40 - 40 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - 0 - - - - Tab 1 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - Tab 2 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - Tab 3 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 16777215 - 16777215 - - - - - - - - - Tab 4 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - - - - - - - + + + BriefReportWidget + + + + 0 + 0 + 1080 + 515 + + + + 运行简报 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 位置 + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 400 + 16777215 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 查询 + + + + + + + Qt::Horizontal + + + + 129 + 20 + + + + + + + + 导出 + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 220 + 60 + + + + + 8 + + + + 关键告警 + + + + :/res/记录.png:/res/记录.png + + + + 40 + 40 + + + + false + + + + + + + + 220 + 60 + + + + + 8 + + + + 操作记录 + + + + :/res/记录.png:/res/记录.png + + + + 40 + 40 + + + + + + + + + 220 + 60 + + + + + 8 + + + + 巡检记录 + + + + :/res/记录.png:/res/记录.png + + + + 40 + 40 + + + + + + + + + 220 + 60 + + + + + 8 + + + + 检修记录 + + + + :/res/记录.png:/res/记录.png + + + + 40 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + + + + Tab 1 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + Tab 2 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + Tab 3 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 16777215 + 16777215 + + + + + + + + + Tab 4 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/BriefReportWidget/CMyCalendar.cpp b/product/src/gui/plugin/BriefReportWidget/CMyCalendar.cpp index b5c252b6..3981b7bb 100644 --- a/product/src/gui/plugin/BriefReportWidget/CMyCalendar.cpp +++ b/product/src/gui/plugin/BriefReportWidget/CMyCalendar.cpp @@ -1,67 +1,67 @@ -#include "CMyCalendar.h" -#include "ui_CMyCalendar.h" -#include "pub_logger_api/logger.h" -#include - -CMyCalendar::CMyCalendar(QWidget *parent) : - QWidget(parent), - ui(new Ui::CMyCalendar) -{ - ui->setupUi(this); - connect(ui->calendarWidget1,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); - connect(ui->calendarWidget2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); - connect(ui->pushButton1,SIGNAL(clicked()),this,SLOT(slot_cancle())); - connect(ui->pushButton2,SIGNAL(clicked()),this,SLOT(slot_ok())); - m_startTime = QDateTime::currentDateTime(); - m_endTime = QDateTime::currentDateTime(); - //ui->lineEdit1->setText(m_startTime.toString("yyyy-MM-dd hh:mm")); - //ui->lineEdit2->setText(m_endTime.toString("yyyy-MM-dd hh:mm")); - //ui->lineEdit1->setReadOnly(true); - //ui->lineEdit2->setReadOnly(true); - ui->timeEdit1->setTime(QTime::currentTime()); - ui->timeEdit2->setTime(QTime::currentTime()); -} - -CMyCalendar::~CMyCalendar() -{ - delete ui; -} - -void CMyCalendar::slot_endTime(QDate date) -{ - QString str=date.toString("yyyy-MM-dd")+ui->timeEdit2->time().toString(" hh:mm"); - m_endTime = QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); - /*str=ui->calendarWidget1->selectedDate().toString("yyyy-MM-dd")+ui->timeEdit1->time().toString(" hh:mm"); - m_startTime=QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); - if(m_startTime.isNull() || m_endTime < m_startTime) - { - return; - } - emit sig_endTimeClick(m_startTime,m_endTime);*/ -} - -void CMyCalendar::slot_startTime(QDate date) -{ - QString str=date.toString("yyyy-MM-dd")+ui->timeEdit1->time().toString(" hh:mm"); - m_startTime = QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); - //ui->lineEdit1->setText(m_startTime.toString("yyyy-MM-dd hh:mm")); -} - -void CMyCalendar::slot_cancle() -{ - emit sig_cancle(); -} - -void CMyCalendar::slot_ok() -{ - QString str=ui->calendarWidget2->selectedDate().toString("yyyy-MM-dd")+ui->timeEdit2->time().toString(" hh:mm"); - m_endTime = QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); - str=ui->calendarWidget1->selectedDate().toString("yyyy-MM-dd")+ui->timeEdit1->time().toString(" hh:mm"); - m_startTime=QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); - if(m_startTime.isNull() || m_endTime < m_startTime) - { - return; - } - emit sig_endTimeClick(m_startTime,m_endTime); -} - +#include "CMyCalendar.h" +#include "ui_CMyCalendar.h" +#include "pub_logger_api/logger.h" +#include + +CMyCalendar::CMyCalendar(QWidget *parent) : + QWidget(parent), + ui(new Ui::CMyCalendar) +{ + ui->setupUi(this); + connect(ui->calendarWidget1,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); + connect(ui->calendarWidget2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); + connect(ui->pushButton1,SIGNAL(clicked()),this,SLOT(slot_cancle())); + connect(ui->pushButton2,SIGNAL(clicked()),this,SLOT(slot_ok())); + m_startTime = QDateTime::currentDateTime(); + m_endTime = QDateTime::currentDateTime(); + //ui->lineEdit1->setText(m_startTime.toString("yyyy-MM-dd hh:mm")); + //ui->lineEdit2->setText(m_endTime.toString("yyyy-MM-dd hh:mm")); + //ui->lineEdit1->setReadOnly(true); + //ui->lineEdit2->setReadOnly(true); + ui->timeEdit1->setTime(QTime::currentTime()); + ui->timeEdit2->setTime(QTime::currentTime()); +} + +CMyCalendar::~CMyCalendar() +{ + delete ui; +} + +void CMyCalendar::slot_endTime(QDate date) +{ + QString str=date.toString("yyyy-MM-dd")+ui->timeEdit2->time().toString(" hh:mm"); + m_endTime = QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); + /*str=ui->calendarWidget1->selectedDate().toString("yyyy-MM-dd")+ui->timeEdit1->time().toString(" hh:mm"); + m_startTime=QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); + if(m_startTime.isNull() || m_endTime < m_startTime) + { + return; + } + emit sig_endTimeClick(m_startTime,m_endTime);*/ +} + +void CMyCalendar::slot_startTime(QDate date) +{ + QString str=date.toString("yyyy-MM-dd")+ui->timeEdit1->time().toString(" hh:mm"); + m_startTime = QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); + //ui->lineEdit1->setText(m_startTime.toString("yyyy-MM-dd hh:mm")); +} + +void CMyCalendar::slot_cancle() +{ + emit sig_cancle(); +} + +void CMyCalendar::slot_ok() +{ + QString str=ui->calendarWidget2->selectedDate().toString("yyyy-MM-dd")+ui->timeEdit2->time().toString(" hh:mm"); + m_endTime = QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); + str=ui->calendarWidget1->selectedDate().toString("yyyy-MM-dd")+ui->timeEdit1->time().toString(" hh:mm"); + m_startTime=QDateTime::fromString(str,"yyyy-MM-dd hh:mm"); + if(m_startTime.isNull() || m_endTime < m_startTime) + { + return; + } + emit sig_endTimeClick(m_startTime,m_endTime); +} + diff --git a/product/src/gui/plugin/BriefReportWidget/CMyCalendar.h b/product/src/gui/plugin/BriefReportWidget/CMyCalendar.h index 3e8f3893..90389b06 100644 --- a/product/src/gui/plugin/BriefReportWidget/CMyCalendar.h +++ b/product/src/gui/plugin/BriefReportWidget/CMyCalendar.h @@ -1,31 +1,31 @@ -#ifndef CMYCALENDAR_H -#define CMYCALENDAR_H - -#include -#include -namespace Ui { -class CMyCalendar; -} - -class CMyCalendar : public QWidget -{ - Q_OBJECT -signals: - void sig_endTimeClick(QDateTime startDate,QDateTime endDate); - void sig_cancle(); -public: - explicit CMyCalendar(QWidget *parent = 0); - ~CMyCalendar(); -public slots: - void slot_endTime(QDate date); - void slot_startTime(QDate date); - void slot_cancle(); - void slot_ok(); - -private: - Ui::CMyCalendar *ui; - QDateTime m_startTime; - QDateTime m_endTime; -}; - -#endif // CMYCALENDAR_H +#ifndef CMYCALENDAR_H +#define CMYCALENDAR_H + +#include +#include +namespace Ui { +class CMyCalendar; +} + +class CMyCalendar : public QWidget +{ + Q_OBJECT +signals: + void sig_endTimeClick(QDateTime startDate,QDateTime endDate); + void sig_cancle(); +public: + explicit CMyCalendar(QWidget *parent = 0); + ~CMyCalendar(); +public slots: + void slot_endTime(QDate date); + void slot_startTime(QDate date); + void slot_cancle(); + void slot_ok(); + +private: + Ui::CMyCalendar *ui; + QDateTime m_startTime; + QDateTime m_endTime; +}; + +#endif // CMYCALENDAR_H diff --git a/product/src/gui/plugin/BriefReportWidget/CMyCalendar.ui b/product/src/gui/plugin/BriefReportWidget/CMyCalendar.ui index 64122cfa..ab79a529 100644 --- a/product/src/gui/plugin/BriefReportWidget/CMyCalendar.ui +++ b/product/src/gui/plugin/BriefReportWidget/CMyCalendar.ui @@ -1,113 +1,113 @@ - - - CMyCalendar - - - - 0 - 0 - 538 - 264 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 1 - - - - - 2 - - - - - - - - - - - - - - - - - - - 0 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - - - - - - - + + + CMyCalendar + + + + 0 + 0 + 538 + 264 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 1 + + + + + 2 + + + + + + + + + + + + + + + + + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/BriefReportWidget/CMyCheckBox.cpp b/product/src/gui/plugin/BriefReportWidget/CMyCheckBox.cpp index 9bc0eddb..b2bc5d95 100644 --- a/product/src/gui/plugin/BriefReportWidget/CMyCheckBox.cpp +++ b/product/src/gui/plugin/BriefReportWidget/CMyCheckBox.cpp @@ -1,21 +1,21 @@ -#include "CMyCheckBox.h" -#include - -CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) - :QCheckBox(text,parent) -{ - -} - -CMyCheckBox::CMyCheckBox(QWidget *parent) - :QCheckBox(parent) -{ - -} - -void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) -{ - setChecked(!isChecked()); - emit clicked(isChecked()); - -} +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + setChecked(!isChecked()); + emit clicked(isChecked()); + +} diff --git a/product/src/gui/plugin/BriefReportWidget/CMyCheckBox.h b/product/src/gui/plugin/BriefReportWidget/CMyCheckBox.h index 36947db5..bdba8dbc 100644 --- a/product/src/gui/plugin/BriefReportWidget/CMyCheckBox.h +++ b/product/src/gui/plugin/BriefReportWidget/CMyCheckBox.h @@ -1,16 +1,16 @@ -#ifndef MYCHECKBOX_H -#define MYCHECKBOX_H - -#include - -class CMyCheckBox : public QCheckBox -{ -public: - CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); - CMyCheckBox(QWidget *parent = Q_NULLPTR); - -protected: - void mouseReleaseEvent(QMouseEvent *e); -}; - -#endif // MYCHECKBOX_H +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/BriefReportWidget/CMyListWidget.cpp b/product/src/gui/plugin/BriefReportWidget/CMyListWidget.cpp index 3b542202..ded92615 100644 --- a/product/src/gui/plugin/BriefReportWidget/CMyListWidget.cpp +++ b/product/src/gui/plugin/BriefReportWidget/CMyListWidget.cpp @@ -1,12 +1,12 @@ -#include "CMyListWidget.h" - -CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) -{ - -} - -void CMyListWidget::showEvent(QShowEvent *event) -{ - this->updateGeometries(); - QListWidget::showEvent(event); -} +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/BriefReportWidget/CMyListWidget.h b/product/src/gui/plugin/BriefReportWidget/CMyListWidget.h index 9fc4491f..3e92461e 100644 --- a/product/src/gui/plugin/BriefReportWidget/CMyListWidget.h +++ b/product/src/gui/plugin/BriefReportWidget/CMyListWidget.h @@ -1,15 +1,15 @@ -#ifndef CMYLISTWIDGET_H -#define CMYLISTWIDGET_H - -#include - -class CMyListWidget : public QListWidget -{ -public: - explicit CMyListWidget(QWidget *parent = 0); - -protected: - void showEvent(QShowEvent *event); -}; - -#endif // CMYLISTWIDGET_H +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/BriefReportWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/BriefReportWidget/CTableViewPrinter.cpp index e8d0b703..afbf955c 100644 --- a/product/src/gui/plugin/BriefReportWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/BriefReportWidget/CTableViewPrinter.cpp @@ -1,122 +1,122 @@ -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include - -CTableViewPrinter::CTableViewPrinter(QTableView *view) - : m_pView(view) -{ - m_pModel = view->model(); -} - -void CTableViewPrinter::print(QPrinter * printer) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - - qreal marginHorizontal = 20; - qreal marginVertical = 20; - - QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); - printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); - - int length = 0; - horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); - for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) - { - length += horizontalHeader->sectionSize(nSection); - } - horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); - - QPainter painter(printer); - - renderHeader(painter); - - int offset = 0; - int currentPage = 0; - int horizontalHeaderHeight = horizontalHeader->height(); - for(int row(0); row < m_pModel->rowCount(); row++) - { - if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) - { - horizontalHeaderHeight = 0; - } - - - if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) - { - printer->newPage(); - currentPage++; - offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - } - - for(int column(0); column < m_pModel->columnCount(); column++) - { - int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - int rowHeight = m_pView->rowHeight(row); - int columnWidth = m_pView->columnWidth(column); - - //< draw item - QStyleOptionViewItem opt; - opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); - painter.save(); - painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); - painter.restore(); - - //< Vertical Line - if(column == 0) - { - QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - //< Horizontal Line - int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; - QPoint left(verticalHeader->width(), rowPosition); - QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); - drawGridLine(&painter, left, right); - - } -} - -void CTableViewPrinter::renderHeader(QPainter &painter) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - for(int column(0); column < horizontalHeader->count(); column++) - { - painter.save(); - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); - painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); - painter.restore(); - } - int columnPosition = horizontalHeader->width() + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); -} - -void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) -{ - painter->save(); - QStyleOptionViewItem opt; - const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); - const QColor gridColor = static_cast(gridHint); - painter->setPen(gridColor); - painter->drawLine(p1, p2); - painter->restore(); -} +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include + +CTableViewPrinter::CTableViewPrinter(QTableView *view) + : m_pView(view) +{ + m_pModel = view->model(); +} + +void CTableViewPrinter::print(QPrinter * printer) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); + printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + + int length = 0; + horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); + for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) + { + length += horizontalHeader->sectionSize(nSection); + } + horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); + + QPainter painter(printer); + + renderHeader(painter); + + int offset = 0; + int currentPage = 0; + int horizontalHeaderHeight = horizontalHeader->height(); + for(int row(0); row < m_pModel->rowCount(); row++) + { + if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) + { + horizontalHeaderHeight = 0; + } + + + if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) + { + printer->newPage(); + currentPage++; + offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + } + + for(int column(0); column < m_pModel->columnCount(); column++) + { + int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + int rowHeight = m_pView->rowHeight(row); + int columnWidth = m_pView->columnWidth(column); + + //< draw item + QStyleOptionViewItem opt; + opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); + painter.save(); + painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); + painter.restore(); + + //< Vertical Line + if(column == 0) + { + QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + //< Horizontal Line + int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; + QPoint left(verticalHeader->width(), rowPosition); + QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); + drawGridLine(&painter, left, right); + + } +} + +void CTableViewPrinter::renderHeader(QPainter &painter) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + for(int column(0); column < horizontalHeader->count(); column++) + { + painter.save(); + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); + painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); + painter.restore(); + } + int columnPosition = horizontalHeader->width() + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); +} + +void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + QStyleOptionViewItem opt; + const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); + const QColor gridColor = static_cast(gridHint); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} diff --git a/product/src/gui/plugin/BriefReportWidget/CTableViewPrinter.h b/product/src/gui/plugin/BriefReportWidget/CTableViewPrinter.h index 82304f16..839198f2 100644 --- a/product/src/gui/plugin/BriefReportWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/BriefReportWidget/CTableViewPrinter.h @@ -1,24 +1,24 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H - -class QPointF; -class QPainter; -class QPrinter; -class QTableView; -class QAbstractItemModel; - -class CTableViewPrinter -{ -public: - explicit CTableViewPrinter(QTableView * view); - - void print(QPrinter *printer); - void renderHeader(QPainter &painter); - void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); - -private: - QTableView * m_pView; - QAbstractItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H + +class QPointF; +class QPainter; +class QPrinter; +class QTableView; +class QAbstractItemModel; + +class CTableViewPrinter +{ +public: + explicit CTableViewPrinter(QTableView * view); + + void print(QPrinter *printer); + void renderHeader(QPainter &painter); + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + +private: + QTableView * m_pView; + QAbstractItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/BriefReportWidget/QueryThread.cpp b/product/src/gui/plugin/BriefReportWidget/QueryThread.cpp index ccd25b24..582b51e8 100644 --- a/product/src/gui/plugin/BriefReportWidget/QueryThread.cpp +++ b/product/src/gui/plugin/BriefReportWidget/QueryThread.cpp @@ -1,96 +1,96 @@ -#include "QueryThread.h" -#include "pub_logger_api/logger.h" - -QueryThread::QueryThread(): location_id(0) -{ - isStop = false; - islocation = false; - - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); - if (!m_pReadDb->open()) - { - LOGERROR("打开数据库连接失败! %s", m_pReadDb->getLastErrorString().toStdString().c_str()); - } -} - -void QueryThread::closeThread() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - m_pReadDb=NULL; - } - isStop=true; -} - -void QueryThread::run() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QString strSql; - QSqlQuery objRet; - qint64 msecTime_start=start_time.toMSecsSinceEpoch(); - qint64 msecTime_end=end_time.toMSecsSinceEpoch(); - - - /* - select his_intelli_alm.TIME_STAMP,his_intelli_alm.CONTENT,his_event.LOCATION_ID from his_intelli_alm, his_event - where his_intelli_alm.TIME_STAMP>=1578358500000 and his_intelli_alm.TIME_STAMP<1578876900000 - and his_intelli_alm.MAIN_ALM_UUID = his_event.UUID_BASE64 - and his_event.LOCATION_ID=1 order by his_intelli_alm.TIME_STAMP desc - */ - - HIS_EVENT_BRIEF Event; - - Events.clear(); - strSql = "select his_intelli_alm.TIME_STAMP,his_intelli_alm.CONTENT,his_event.LOCATION_ID from his_intelli_alm,his_event where "; - strSql += "his_intelli_alm.TIME_STAMP>="+QString::number(msecTime_start,10)+" and his_intelli_alm.TIME_STAMP<"+QString::number(msecTime_end,10); - strSql += " and his_intelli_alm.MAIN_ALM_UUID = his_event.UUID_BASE64 "; - if(islocation==true) - { - strSql += "and his_event.LOCATION_ID="+QString::number(location_id,10);// order by his_intelli_alm.TIME_STAMP desc" - //strSql="select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<="+QString::number(msecTime_end,10)+" and LOCATION_ID="+QString::number(location_id,10)+" order by TIME_STAMP desc"; - qDebug() << strSql <execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Event.TIME_STAMP=objRet.value(0).toLongLong(); - Event.CONTENT=objRet.value(1).toString().toStdString(); - Event.LOCATION_ID=objRet.value(2).toInt(); - Events.push_back(Event); - } - } - - Events_Operates.clear(); - strSql = "select TIME_STAMP,CONTENT,LOCATION_ID from his_event where ALM_TYPE=4 and TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<="+QString::number(msecTime_end,10); - if(islocation==true) - { - strSql=strSql+" and LOCATION_ID="+QString::number(location_id,10); - } - strSql=strSql+" order by TIME_STAMP desc"; - - LOGINFO("查询历史事件告警SQL语句=%s",strSql.toStdString().c_str()); - - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Event.TIME_STAMP=objRet.value(0).toLongLong(); - Event.CONTENT=objRet.value(1).toString().toStdString(); - Event.LOCATION_ID=objRet.value(2).toInt(); - Events_Operates.push_back(Event); - } - } - emit signal_QueryEnd(Events,Events_Operates); -} +#include "QueryThread.h" +#include "pub_logger_api/logger.h" + +QueryThread::QueryThread(): location_id(0) +{ + isStop = false; + islocation = false; + + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); + if (!m_pReadDb->open()) + { + LOGERROR("打开数据库连接失败! %s", m_pReadDb->getLastErrorString().toStdString().c_str()); + } +} + +void QueryThread::closeThread() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + m_pReadDb=NULL; + } + isStop=true; +} + +void QueryThread::run() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QString strSql; + QSqlQuery objRet; + qint64 msecTime_start=start_time.toMSecsSinceEpoch(); + qint64 msecTime_end=end_time.toMSecsSinceEpoch(); + + + /* + select his_intelli_alm.TIME_STAMP,his_intelli_alm.CONTENT,his_event.LOCATION_ID from his_intelli_alm, his_event + where his_intelli_alm.TIME_STAMP>=1578358500000 and his_intelli_alm.TIME_STAMP<1578876900000 + and his_intelli_alm.MAIN_ALM_UUID = his_event.UUID_BASE64 + and his_event.LOCATION_ID=1 order by his_intelli_alm.TIME_STAMP desc + */ + + HIS_EVENT_BRIEF Event; + + Events.clear(); + strSql = "select his_intelli_alm.TIME_STAMP,his_intelli_alm.CONTENT,his_event.LOCATION_ID from his_intelli_alm,his_event where "; + strSql += "his_intelli_alm.TIME_STAMP>="+QString::number(msecTime_start,10)+" and his_intelli_alm.TIME_STAMP<"+QString::number(msecTime_end,10); + strSql += " and his_intelli_alm.MAIN_ALM_UUID = his_event.UUID_BASE64 "; + if(islocation==true) + { + strSql += "and his_event.LOCATION_ID="+QString::number(location_id,10);// order by his_intelli_alm.TIME_STAMP desc" + //strSql="select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<="+QString::number(msecTime_end,10)+" and LOCATION_ID="+QString::number(location_id,10)+" order by TIME_STAMP desc"; + qDebug() << strSql <execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Event.TIME_STAMP=objRet.value(0).toLongLong(); + Event.CONTENT=objRet.value(1).toString().toStdString(); + Event.LOCATION_ID=objRet.value(2).toInt(); + Events.push_back(Event); + } + } + + Events_Operates.clear(); + strSql = "select TIME_STAMP,CONTENT,LOCATION_ID from his_event where ALM_TYPE=4 and TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<="+QString::number(msecTime_end,10); + if(islocation==true) + { + strSql=strSql+" and LOCATION_ID="+QString::number(location_id,10); + } + strSql=strSql+" order by TIME_STAMP desc"; + + LOGINFO("查询历史事件告警SQL语句=%s",strSql.toStdString().c_str()); + + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Event.TIME_STAMP=objRet.value(0).toLongLong(); + Event.CONTENT=objRet.value(1).toString().toStdString(); + Event.LOCATION_ID=objRet.value(2).toInt(); + Events_Operates.push_back(Event); + } + } + emit signal_QueryEnd(Events,Events_Operates); +} diff --git a/product/src/gui/plugin/BriefReportWidget/QueryThread.h b/product/src/gui/plugin/BriefReportWidget/QueryThread.h index 9bb5f550..79e4cf24 100644 --- a/product/src/gui/plugin/BriefReportWidget/QueryThread.h +++ b/product/src/gui/plugin/BriefReportWidget/QueryThread.h @@ -1,38 +1,38 @@ -#ifndef QUERYTHREAD_H -#define QUERYTHREAD_H - -#include -#include "BriefReportCommon.h" -#include "db_api_ex/CDbApi.h" - -class QueryThread : public QThread -{ - Q_OBJECT -public: - QueryThread(); - - void closeThread(); - - QDateTime start_time; - QDateTime end_time; - - bool islocation; - qint64 location_id; - -signals: - void signal_QueryEnd(std::vector Events,std::vector Events_Operates); - -protected: - virtual void run(); -private: - volatile bool isStop; - - std::vector Events; - //QVector Events; - std::vector Events_Operates; - //QVector Events_Operates; - - kbd_dbms::CDbApi *m_pReadDb; -}; - -#endif // QUERYTHREAD_H +#ifndef QUERYTHREAD_H +#define QUERYTHREAD_H + +#include +#include "BriefReportCommon.h" +#include "db_api_ex/CDbApi.h" + +class QueryThread : public QThread +{ + Q_OBJECT +public: + QueryThread(); + + void closeThread(); + + QDateTime start_time; + QDateTime end_time; + + bool islocation; + qint64 location_id; + +signals: + void signal_QueryEnd(std::vector Events,std::vector Events_Operates); + +protected: + virtual void run(); +private: + volatile bool isStop; + + std::vector Events; + //QVector Events; + std::vector Events_Operates; + //QVector Events_Operates; + + kbd_dbms::CDbApi *m_pReadDb; +}; + +#endif // QUERYTHREAD_H diff --git a/product/src/gui/plugin/BriefReportWidget/main.cpp b/product/src/gui/plugin/BriefReportWidget/main.cpp index e8d917e1..155b7c59 100644 --- a/product/src/gui/plugin/BriefReportWidget/main.cpp +++ b/product/src/gui/plugin/BriefReportWidget/main.cpp @@ -1,11 +1,11 @@ -#include "BriefReportWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - BriefReportWidget w; - w.show(); - - return a.exec(); -} +#include "BriefReportWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + BriefReportWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/BriefReportWidget/resource.qrc b/product/src/gui/plugin/BriefReportWidget/resource.qrc index cfc1562a..00ae7947 100644 --- a/product/src/gui/plugin/BriefReportWidget/resource.qrc +++ b/product/src/gui/plugin/BriefReportWidget/resource.qrc @@ -1,5 +1,5 @@ - - - res/记录.png - - + + + res/记录.png + + diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/BTRealDataCollect.cpp b/product/src/gui/plugin/BusbarTemperatureWidget/BTRealDataCollect.cpp index 91bdc0a9..59dfb42e 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/BTRealDataCollect.cpp +++ b/product/src/gui/plugin/BusbarTemperatureWidget/BTRealDataCollect.cpp @@ -1,247 +1,247 @@ -#include "BTRealDataCollect.h" - -#include - -BTRealDataCollect* BTRealDataCollect::m_pInstance = NULL; - -BTRealDataCollect::BTRealDataCollect() - : m_pMbComm(NULL), - m_pTimer(NULL), - m_nTimeCount(0) -{ - initMsg(); - if(!addSub()) - { - return; - } - - m_pTimer = new QTimer(this); - connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); - m_pTimer->start(100); -} - -BTRealDataCollect* BTRealDataCollect::instance() -{ - if(m_pInstance == NULL) - { - m_pInstance = new BTRealDataCollect(); - } - return m_pInstance; -} - - -void BTRealDataCollect::release() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - delSub(); - closeMsg(); - m_pInstance = NULL; - delete this; -} - -void BTRealDataCollect::initMsg() -{ - if(m_pMbComm == NULL) - { - m_pMbComm = new kbd_net::CMbCommunicator("BusbarTemperatureWidget"); - } -} - -void BTRealDataCollect::closeMsg() -{ - if(m_pMbComm != NULL) - { - delete m_pMbComm; - } - m_pMbComm = NULL; -} - -void BTRealDataCollect::clearMsg() -{ - if(m_pMbComm) - { - kbd_net::CMbMessage objMsg; - while(m_pMbComm->recvMsg(objMsg, 0)) - {} - } -} - -bool BTRealDataCollect::addSub() -{ - if(m_pMbComm) - { - return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else - { - return false; - } -} - -bool BTRealDataCollect::delSub() -{ - if(m_pMbComm) - { - return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else - { - return false; - } -} - -void BTRealDataCollect::recvMessage() -{ - m_nTimeCount = (m_nTimeCount + 1) % 36000; - - if(m_nTimeCount % 10 == 0) - { - processChangeData(); - } - - try - { - kbd_net::CMbMessage objMsg; - for(int i = 0; i < 6; i++) - { - if(m_pMbComm->recvMsg(objMsg, 0)) - { - if(objMsg.isValid()) - { - if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) - { - continue; - } - if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) - { - continue; - } - parserMsg(objMsg); - } - } - } - } - catch(...) - { - - } -} - -void BTRealDataCollect::processChangeData() -{ - if(!m_aiMap.isEmpty()) - { - emit signal_updateAi(m_aiMap); - m_aiMap.clear(); - } - - if(!m_diMap.isEmpty()) - { - emit signal_updateDi(m_diMap); - m_diMap.clear(); - } - - if(!m_piMap.isEmpty()) - { - emit signal_updatePi(m_piMap); - m_piMap.clear(); - } - - if(!m_miMap.isEmpty()) - { - emit signal_updateMi(m_miMap); - m_miMap.clear(); - } -} - -int BTRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) -{ - kbd_idlfile::SRealTimeDataPkg changeDataPackage; - try - { - changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); - int aiSize = changeDataPackage.stairtd_size(); - if(aiSize > 0) - { - kbd_idlfile::SAiRealTimeData aiStru; - QString tagName; - float value; - uint status; - for(int i = 0; i < aiSize;++i) - { - aiStru = changeDataPackage.stairtd(i); - tagName = QString::fromStdString(aiStru.strtagname()); - value = aiStru.fvalue(); - status = aiStru.ustatus(); - m_aiMap[tagName] = qMakePair(value, status); - - //QString logParserMsgAiMap = QString("BTRealDataCollect parserMsg-tagName-value-status-->%1-%2-%3").arg(tagName).arg(value).arg(status); - //LOGERROR(logParserMsgAiMap.toStdString().c_str()); - } - } - - /* - int diSize = changeDataPackage.stdirtd_size(); - if(diSize > 0) - { - kbd_idlfile::SDiRealTimeData diStu; - QString tagName; - int value; - uint status; - for(int i = 0; i < diSize; ++i) - { - diStu = changeDataPackage.stdirtd(i); - tagName = QString::fromStdString(diStu.strtagname()); - value = diStu.nvalue(); - status = diStu.ustatus(); - m_diMap[tagName] = qMakePair(value, status); - } - } - - int piSize = changeDataPackage.stpirtd_size(); - if(piSize > 0) - { - kbd_idlfile::SPiRealTimeData piStu; - QString tagName; - double value; - uint status; - for(int i = 0 ; i < piSize; ++i) - { - piStu = changeDataPackage.stpirtd(i); - tagName = QString::fromStdString(piStu.strtagname()); - value = piStu.dvalue(); - status = piStu.ustatus(); - m_piMap[tagName] = qMakePair(value, status); - } - } - - int miSize = changeDataPackage.stmirtd_size(); - if(miSize > 0) - { - kbd_idlfile::SMiRealTimeData miStu; - QString tagName; - int value; - uint status; - for(int i = 0 ; i < miSize ; ++i) - { - miStu = changeDataPackage.stmirtd(i); - tagName = QString::fromStdString(miStu.strtagname()); - value = miStu.nvalue(); - status = miStu.ustatus(); - m_miMap[tagName] = qMakePair(value, status); - } - }*/ - } - catch(...) - { - return 0; - } - return 1; -} - +#include "BTRealDataCollect.h" + +#include + +BTRealDataCollect* BTRealDataCollect::m_pInstance = NULL; + +BTRealDataCollect::BTRealDataCollect() + : m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0) +{ + initMsg(); + if(!addSub()) + { + return; + } + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +BTRealDataCollect* BTRealDataCollect::instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new BTRealDataCollect(); + } + return m_pInstance; +} + + +void BTRealDataCollect::release() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(); + closeMsg(); + m_pInstance = NULL; + delete this; +} + +void BTRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new kbd_net::CMbCommunicator("BusbarTemperatureWidget"); + } +} + +void BTRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +void BTRealDataCollect::clearMsg() +{ + if(m_pMbComm) + { + kbd_net::CMbMessage objMsg; + while(m_pMbComm->recvMsg(objMsg, 0)) + {} + } +} + +bool BTRealDataCollect::addSub() +{ + if(m_pMbComm) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +bool BTRealDataCollect::delSub() +{ + if(m_pMbComm) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +void BTRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { + processChangeData(); + } + + try + { + kbd_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) + { + continue; + } + if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) + { + continue; + } + parserMsg(objMsg); + } + } + } + } + catch(...) + { + + } +} + +void BTRealDataCollect::processChangeData() +{ + if(!m_aiMap.isEmpty()) + { + emit signal_updateAi(m_aiMap); + m_aiMap.clear(); + } + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + + if(!m_piMap.isEmpty()) + { + emit signal_updatePi(m_piMap); + m_piMap.clear(); + } + + if(!m_miMap.isEmpty()) + { + emit signal_updateMi(m_miMap); + m_miMap.clear(); + } +} + +int BTRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) +{ + kbd_idlfile::SRealTimeDataPkg changeDataPackage; + try + { + changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); + int aiSize = changeDataPackage.stairtd_size(); + if(aiSize > 0) + { + kbd_idlfile::SAiRealTimeData aiStru; + QString tagName; + float value; + uint status; + for(int i = 0; i < aiSize;++i) + { + aiStru = changeDataPackage.stairtd(i); + tagName = QString::fromStdString(aiStru.strtagname()); + value = aiStru.fvalue(); + status = aiStru.ustatus(); + m_aiMap[tagName] = qMakePair(value, status); + + //QString logParserMsgAiMap = QString("BTRealDataCollect parserMsg-tagName-value-status-->%1-%2-%3").arg(tagName).arg(value).arg(status); + //LOGERROR(logParserMsgAiMap.toStdString().c_str()); + } + } + + /* + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + kbd_idlfile::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); + m_diMap[tagName] = qMakePair(value, status); + } + } + + int piSize = changeDataPackage.stpirtd_size(); + if(piSize > 0) + { + kbd_idlfile::SPiRealTimeData piStu; + QString tagName; + double value; + uint status; + for(int i = 0 ; i < piSize; ++i) + { + piStu = changeDataPackage.stpirtd(i); + tagName = QString::fromStdString(piStu.strtagname()); + value = piStu.dvalue(); + status = piStu.ustatus(); + m_piMap[tagName] = qMakePair(value, status); + } + } + + int miSize = changeDataPackage.stmirtd_size(); + if(miSize > 0) + { + kbd_idlfile::SMiRealTimeData miStu; + QString tagName; + int value; + uint status; + for(int i = 0 ; i < miSize ; ++i) + { + miStu = changeDataPackage.stmirtd(i); + tagName = QString::fromStdString(miStu.strtagname()); + value = miStu.nvalue(); + status = miStu.ustatus(); + m_miMap[tagName] = qMakePair(value, status); + } + }*/ + } + catch(...) + { + return 0; + } + return 1; +} + diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/BTRealDataCollect.h b/product/src/gui/plugin/BusbarTemperatureWidget/BTRealDataCollect.h index b1e0c2bf..6ddd3d39 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/BTRealDataCollect.h +++ b/product/src/gui/plugin/BusbarTemperatureWidget/BTRealDataCollect.h @@ -1,55 +1,55 @@ -#ifndef BTREALDATACOLLECT_H -#define BTREALDATACOLLECT_H - -#include -#include -#include -#include -#include "net_msg_bus_api/CMbCommunicator.h" -#include "pub_logger_api/logger.h" -#include "MessageChannel.h" -#include "DataProcMessage.pb.h" -#include -#include -#include - -class BTRealDataCollect : public QObject -{ - Q_OBJECT -public: - static BTRealDataCollect* instance(); - void release(); - -signals: - void signal_updateAi(QMap> aiMap); - void signal_updateDi(QMap> diMap); - void signal_updatePi(QMap> piMap); - void signal_updateMi(QMap> miMap); - -private slots: - void recvMessage(); - void processChangeData(); - -private: - BTRealDataCollect(); - - void initMsg(); - void closeMsg(); - void clearMsg(); - bool addSub(); - bool delSub(); - - int parserMsg(const kbd_net::CMbMessage &); - - kbd_net::CMbCommunicator *m_pMbComm; - QTimer * m_pTimer; - int m_nTimeCount; - QMap> m_aiMap; - QMap> m_diMap; - QMap> m_piMap; - QMap> m_miMap; - - static BTRealDataCollect * m_pInstance; -}; - -#endif // BTREALDATACOLLECT_H +#ifndef BTREALDATACOLLECT_H +#define BTREALDATACOLLECT_H + +#include +#include +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "pub_logger_api/logger.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" +#include +#include +#include + +class BTRealDataCollect : public QObject +{ + Q_OBJECT +public: + static BTRealDataCollect* instance(); + void release(); + +signals: + void signal_updateAi(QMap> aiMap); + void signal_updateDi(QMap> diMap); + void signal_updatePi(QMap> piMap); + void signal_updateMi(QMap> miMap); + +private slots: + void recvMessage(); + void processChangeData(); + +private: + BTRealDataCollect(); + + void initMsg(); + void closeMsg(); + void clearMsg(); + bool addSub(); + bool delSub(); + + int parserMsg(const kbd_net::CMbMessage &); + + kbd_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + QMap> m_aiMap; + QMap> m_diMap; + QMap> m_piMap; + QMap> m_miMap; + + static BTRealDataCollect * m_pInstance; +}; + +#endif // BTREALDATACOLLECT_H diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperaturePluginWidget.cpp b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperaturePluginWidget.cpp index a02e70c6..adb36598 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperaturePluginWidget.cpp +++ b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperaturePluginWidget.cpp @@ -1,27 +1,27 @@ -#include "BusbarTemperaturePluginWidget.h" -#include "BusbarTemperatureWidget.h" - -BusbarTemperaturePluginWidget::BusbarTemperaturePluginWidget() -{ - -} - -BusbarTemperaturePluginWidget::~BusbarTemperaturePluginWidget() -{ - -} - - -bool BusbarTemperaturePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - BusbarTemperatureWidget *pWidget = new BusbarTemperatureWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void BusbarTemperaturePluginWidget::release() -{ - -} +#include "BusbarTemperaturePluginWidget.h" +#include "BusbarTemperatureWidget.h" + +BusbarTemperaturePluginWidget::BusbarTemperaturePluginWidget() +{ + +} + +BusbarTemperaturePluginWidget::~BusbarTemperaturePluginWidget() +{ + +} + + +bool BusbarTemperaturePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + BusbarTemperatureWidget *pWidget = new BusbarTemperatureWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void BusbarTemperaturePluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperaturePluginWidget.h b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperaturePluginWidget.h index aeef737a..4dda2358 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperaturePluginWidget.h +++ b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperaturePluginWidget.h @@ -1,21 +1,21 @@ -#ifndef BUSBARTEMPERATUREPLUGINWIDGET_H -#define BUSBARTEMPERATUREPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class BusbarTemperaturePluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - BusbarTemperaturePluginWidget(); - ~BusbarTemperaturePluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // BUSBARTEMPERATUREPLUGINWIDGET_H +#ifndef BUSBARTEMPERATUREPLUGINWIDGET_H +#define BUSBARTEMPERATUREPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class BusbarTemperaturePluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + BusbarTemperaturePluginWidget(); + ~BusbarTemperaturePluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // BUSBARTEMPERATUREPLUGINWIDGET_H diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.cpp b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.cpp index b72103b3..e5edd50e 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.cpp +++ b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.cpp @@ -1,687 +1,687 @@ -#include "BusbarTemperatureWidget.h" -#include "ui_BusbarTemperatureWidget.h" - - -BusbarTemperatureWidget::BusbarTemperatureWidget(QWidget *parent, bool isEditMode) - :QWidget(parent), - m_isEditMode(isEditMode), - ui(new Ui::BusbarTemperatureWidget) -{ - ui->setupUi(this); - setDeviceTitle(); - m_pPopupWidget = new ShowInfoWidget(QString(), this); - m_pSet = new QBarSet("测点温度"); - - m_axisX = new QValueAxis(); - m_axisY = new QValueAxis(); - m_pChart = new QChart(); - m_pSeriesBar = new QBarSeries(); - m_pScatterSeries = new QScatterSeries(); - m_pLineSeries = new QLineSeries(); - - ui->m_pSearchTextEdit->setPlaceholderText("搜索母线"); - connect(ui->m_pSearchTextEdit, &QLineEdit::textChanged, this, &BusbarTemperatureWidget::FindTagName); - - connect(ui->treeFiles, &QTreeWidget::itemClicked, this, &BusbarTemperatureWidget::onTreeClicked); - return; -} - - -QString BusbarTemperatureWidget::setYAxisRange(const int& minValue, const int& maxValue) -{ - yAxisMin = minValue; - yAxisMax = maxValue; - - initializeChart(); - // m_pChart->axisY()->setRange(yAxisMin,yAxisMax); - return QString(); -} - -QString BusbarTemperatureWidget::setXAxisRange(const int &minValue, const int &maxValue) -{ - xAxisMin = minValue; - xAxisMax = maxValue; - // m_axisX->setRange(xAxisMin, xAxisMax); - return QString(); -} - -QString BusbarTemperatureWidget::setDeviceTitle() -{ - //测试读取csv - QMap, QString> setTitleCsvMap; - QFile file("../../data/BusbarTemperatureWidget/setDeviceTitle.csv"); - if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ - QMessageBox::warning(NULL, "警告", "打开data/BusbarTemperatureWidget/setDeviceTitle.csv文件错误!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - return QString(); - } - else - { - ui->treeFiles->clear();//清除目录树所有节点 - ui->treeFiles->setHeaderLabel(""); - - QTextStream in(&file); - in.setCodec("GB2312"); - int row = 0; - QTreeWidgetItem* item_cz; - QTreeWidgetItem* item_mx; - - while(!in.atEnd()) - { - QString line = in.readLine(); - QStringList fileds = line.split(","); - - - if(row >0) - { - //插入数节点 - if(fileds.length() >= 3) - { - if(fileds[2] =="1") - { - //插入厂站节点 - item_cz=new QTreeWidgetItem( ui->treeFiles); //新建节点时设定类型为 itTopItem - item_cz->setText(0,fileds[0]); //设置第2列的文字 - item_cz->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); - ui->treeFiles->addTopLevelItem(item_cz);//添加顶层节点 - - } - else - { - //插入母校节点 - item_mx=new QTreeWidgetItem(item_cz); //新建节点时设定类型为 itTopItem - item_mx->setText(0,fileds[0]); // - item_mx->setText(1,fileds[1]); // - item_mx->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); - - } - } - - } - row++; - } - file.close(); - } - - /* QStringList titleList; - QStringList measurePointList; - QMap, QString>::const_iterator iter = setTitleCsvMap.constBegin(); - QString listViewTitle = iter.value(); - //iter = iter + 2; - iter = iter + 3; - - for(; iter != setTitleCsvMap.constEnd(); iter++) - { - if(iter.key().second == 0) - { - titleList.append(iter.value()); - } - - if(iter.key().second == 1) - { - measurePointList.append(iter.value()); - } - - }*/ - - - ui->label_listViewTitle->setText("母线名称"); //设置列表标题 - ui->label_listViewTitle->setAlignment(Qt::AlignLeft); //设置标题文字居中 - - - return QString(); -} - - - -void BusbarTemperatureWidget::initializeChart() -{ - m_pChart->legend()->setVisible(true); - m_pChart->legend()->setAlignment(Qt::AlignRight); - m_pChart->setMargins(QMargins(0,0,0,0)); - m_pChart->setBackgroundRoundness(0); - //设置横坐标 - - m_axisX->setRange(xAxisMin, xAxisMax); - m_axisX->setLabelFormat("%d m"); - m_axisX->setTickCount(21); - m_axisX->setGridLineVisible(false); - m_axisX->setTitleText("长度(米)"); - - m_pChart->addAxis(m_axisX, Qt::AlignBottom); - - //设置Y - m_axisY->setTickCount(5); - m_axisY->setTitleText("温度/℃"); - m_axisY->setGridLineVisible(true); - m_axisY->setGridLineColor("#778899"); - m_pChart->addAxis(m_axisY, Qt::AlignLeft); - - m_axisY->setRange(yAxisMin, yAxisMax); - m_axisY->setLinePen(Qt::NoPen); - - m_pSet->setColor("#4169E1"); - m_pSet->setPen(QPen(Qt::NoPen)); - - //设置最大值, - for(int i = 0; i < m_MaxBar; i++) - { - *m_pSet << yAxisMax; - } - - // *m_pSet << 0 << ; - - m_pSeriesBar->append(m_pSet); - - m_pLineSeries->setName("测点温度(线)"); - m_pScatterSeries->setName("测点温度(点)"); - m_pChart->addSeries(m_pSeriesBar); - m_pChart->addSeries(m_pScatterSeries); - m_pChart->addSeries(m_pLineSeries); - - m_pScatterSeries->setColor(Qt::blue); - m_pScatterSeries->attachAxis(m_axisX); //序列 series0 附加坐标轴 - m_pScatterSeries->attachAxis(m_axisY); - - m_pLineSeries->setColor(Qt::blue); - m_pLineSeries->attachAxis(m_axisX); //序列 series0 附加坐标轴 - m_pLineSeries->attachAxis(m_axisY); - - m_pSeriesBar->setVisible(true); - m_pScatterSeries->setVisible(false); - m_pLineSeries->setVisible(false); - - m_pScatterSeries->setPointLabelsFormat("@yPoint"); - // m_pScatterSeries->setPointLabelsVisible(); - m_pScatterSeries->setMarkerSize(8); - - // m_pChart->setTitle("母线温度"); - m_pChart->setAnimationOptions(QChart::SeriesAnimations); - - ui->chartView->setRenderHint(QPainter::Antialiasing); - ui->chartView->setChart(m_pChart); - - - //柱状图清零 - m_space =xAxisMax / m_MaxBar; - for(int i = 0; i < m_MaxBar; i++) - { - m_pSet->replace(i, 0); - } - - if(m_isEditMode) - { - return; - } - - initStyle(); - - kbd_service::CDpcdaForApp::initGlobalThread(); - m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); - - //接收实时数据信号槽 - connect(BTRealDataCollect::instance(), &BTRealDataCollect::signal_updateAi, this, &BusbarTemperatureWidget::slotUpdateAi); - - //鼠标悬停显示坐标信号槽 - connect(m_pSeriesBar, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(AxisXHovered(bool, int, QBarSet*))); - connect(m_pScatterSeries, SIGNAL(hovered(const QPointF&,bool)), this, SLOT(showPos(const QPointF&, bool))); - - //切换显示方式 - connect(ui->radioButtonBar, SIGNAL(toggled(bool)), this, SLOT(slotShowChange(bool))); -} - -void BusbarTemperatureWidget::initStyle() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - qssfile1.close(); - - std::string style = kbd_public::CFileStyle::getPathOfStyleFile("busbarTemperature.qss") ; - QFile file(QString::fromStdString(style)); - file.open(QFile::ReadOnly); - if (file.isOpen()) - { - setStyleSheet(QLatin1String(file.readAll())); - file.close(); - } -} - -//增加一条特定值的y值的警戒线 -void BusbarTemperatureWidget::setAlarmYaxis(const int& yValue) -{ - QChart* chart = ui->chartView->chart(); - QValueAxis* axisY = qobject_cast(chart->axisY()); - QLineSeries* lineSeries = new QLineSeries; - lineSeries->setName(QString("告警线(%1℃)").arg(yValue)); - lineSeries->append(0, yValue); - lineSeries->append(m_MaxBar, yValue); - lineSeries->setColor(Qt::red); - chart->addSeries(lineSeries); - lineSeries->attachAxis(axisY); - -} - - -//柱状图间隔及图表宽度 -void BusbarTemperatureWidget::setWidth(const float& BarWidth,const int& chartWidth ) -{ - m_pSeriesBar->setBarWidth(BarWidth); - ui->scrollAreaWidgetContents->setMinimumWidth(chartWidth); - -} - -void BusbarTemperatureWidget::setMaxBar(const int &Max) -{ - m_MaxBar =Max; - m_columnTotal =m_MaxBar; -} - -void BusbarTemperatureWidget::setLeftListWidth(const int &Width) -{ - ui->treeFiles->setMaximumWidth(Width); - ui->treeFiles->setMinimumWidth(Width); - - ui->m_pSearchTextEdit->setMaximumWidth(Width); - ui->m_pSearchTextEdit->setMinimumWidth(Width); -} - - -void BusbarTemperatureWidget::showPos(const QPointF& point, bool state) -{ - /* if(m_rowSelected < 0) - { - m_rowSelected =0; - }*/ - - int index =point.x() / m_space; - QString windowTitle =m_curNode;// m_rowNameList[m_rowSelected]; - QString des=m_pointDes[index];//"F23-1-N4-01_2F-13X_1_2_137-1-K36_温度" - // des="F23-1-N4-01_2F-13X_1_2_137-1-K36_温度"; - QStringList list =des.split("_"); - QString label; - QString busLine; //母线 - QString weizhi; //位置 - QString zhuji; //主机 - QString caijiqi; //采集器 - QString jietou; //接头编号 - if(list.length() >=5) - { - busLine = list[0]; //母线 - weizhi = list[1]; //位置 - zhuji = list[2]; //主机 - caijiqi = list[3]; //采集器 - jietou = list[4]; //接头编号 - - } - label = QString("序号:%1\n" - "母线: %2\n" - "位置: %3\n" - "主机: %4\n" - "采集器: %5\n" - "接头编号: %6\n" - "温度: %7℃").arg(index).arg(busLine).arg(weizhi).arg(zhuji).arg(caijiqi).arg(jietou).arg(point.y()); - - ShowInfoWidget *popup = new ShowInfoWidget(label, this); // 创建弹窗窗口; - if(state) { - popup->setWindowTitle(windowTitle); - m_pPopupWidget = popup; - m_pPopupWidget->show(); // 显示弹窗窗口 - }else { - m_pPopupWidget->close(); - } -} - -void BusbarTemperatureWidget::AxisXHovered(const bool& status, const int& index, QBarSet* barSet) -{ - if(m_curNode =="") - { - return; - } - - QString windowTitle =m_curNode;// m_rowNameList[m_rowSelected]; - QString des=m_pointDes[index]; - - // QString des=m_pointDes[index];//"F23-1-N4-01_2F-13X_1_2_137-1-K36_温度" - // des="F23-1-N4-01_2F-13X_1_2_137-1-K36_温度"; - QStringList list =des.split("_"); - QString label; - QString busLine; //母线 - QString weizhi; //位置 - QString zhuji; //主机 - QString caijiqi; //采集器 - QString jietou; //接头编号 - if(list.length() >=5) - { - busLine = list[0]; //母线 - weizhi = list[1]; //位置 - zhuji = list[2]; //主机 - caijiqi = list[3]; //采集器 - jietou = list[4]; //接头编号 - - } - label = QString("序号:%1\n" - "母线: %2\n" - "位置: %3\n" - "主机: %4\n" - "采集器: %5\n" - "接头编号: %6\n" - "温度: %7℃").arg(index).arg(busLine).arg(weizhi).arg(zhuji).arg(caijiqi).arg(jietou).arg(barSet->at(index)); - - // QString label = QString("名称:%1\r\n测点位置: %2\n温度值: %3℃").arg(des).arg(index).arg(barSet->at(index)); - - ShowInfoWidget *popup = new ShowInfoWidget(label, this); // 创建弹窗窗口; - if(status) { - popup->setWindowTitle(windowTitle); - m_pPopupWidget = popup; - m_pPopupWidget->show(); // 显示弹窗窗口 - }else { - m_pPopupWidget->close(); - } -} - -void BusbarTemperatureWidget::subscribe() -{ - if(m_pDpcdaForApp == Q_NULLPTR) - { - return; - } - unsubscribeAll(); - - QMap::const_iterator iter = m_tagNameMap.constBegin(); - for(; iter != m_tagNameMap.constEnd(); iter++) - { - m_pDpcdaForApp->subscribe("analog", iter.value().toStdString(), "value"); - m_pDpcdaForApp->subscribe("analog", iter.value().toStdString(), "status"); - } - return; -} - -void BusbarTemperatureWidget::unsubscribeAll() -{ - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - } -} - -void BusbarTemperatureWidget::slotUpdateAi(const QMap>& aiMap) -{ -// LOGERROR("slotUpdateAi Start!"); - QMap >::const_iterator iter = aiMap.constBegin(); - // logBarYValueMapTag = iter.key().split(".")[0] + iter.key().split(".")[1]; //测试log用 - for(; iter != aiMap.constEnd(); iter++) - { - QString tagNameKey = iter.key().split(".")[2]; - QString sDeviceTagName = iter.key().split(".")[0]+ "."+ iter.key().split(".")[1]; - - if( m_sSelDevice != sDeviceTagName) //实例: T1 ->statio27.S1MXCE1_jgxh.T1 - { - continue; - } - - int number; - QString xValue = iter.key().split(".")[2]; - QString temp; - for(int i = 0; i < xValue.length(); i++) - { - if(xValue[i] >= '0' && xValue[i] <= '9') - temp.append(xValue[i]); - } - number = temp.toInt(); - - m_barYValueMap[number] = qMakePair(xValue, iter.value().first); //11 YC11 234.45 - } - updateChart(); -} - -void BusbarTemperatureWidget::FindTagName() -{ - QString searchword = ui->m_pSearchTextEdit->text(); - - // ui->treeFiles->selectionMode().selectionModel()->select(selection, QItemSelectionModel::Select); - - for(int m=0;m< ui->treeFiles->topLevelItemCount(); ++m) //遍历所有父节点 - { - QTreeWidgetItem * CurTopLevItm = ui->treeFiles->topLevelItem(m); //显示与关键字匹配的馈线 - QString TopNodText=CurTopLevItm->text(0); - bool IsContain=TopNodText.contains(searchword,Qt::CaseInsensitive); //节点名字是否包含关键字 - if(IsContain) - { - if(CurTopLevItm->isHidden()) - CurTopLevItm->setHidden(false); //显示此节点 - } - else - { - CurTopLevItm->setHidden(true); - } - - //遍历该父节点下的子节点 - for(int n =0;nchildCount();++n) - { - QTreeWidgetItem * CurChidItm = CurTopLevItm->child(n); - QString ChilNodText=CurChidItm->text(0); - bool IsContain = ChilNodText.contains(searchword,Qt::CaseInsensitive); //节点名字是否包含关键字 - - if(!IsContain) //与关键字不匹配 - { - CurChidItm->setHidden(true); - continue; - } - CurChidItm->setHidden(false); //与关键字匹配 - if(CurTopLevItm->isHidden()) //显示其父节点 - CurTopLevItm->setHidden(false); - if(!CurTopLevItm->isExpanded()) - CurTopLevItm->setExpanded(true); //展开父节点 - } - } - -} - -void BusbarTemperatureWidget::onTreeClicked(QTreeWidgetItem *item, int column) -{ - QString code = item->text(1); - if(code =="") - { - return; - } - - - //改变图表名字,柱状图清零 - QChart* chart = m_pChart; - - QString Title = item->text(0); - chart->setTitle(Title); - QBarSeries* series = qobject_cast(chart->series().at(0)); - QBarSet* barSet = series->barSets().at(0); - for(int i = 0; i < m_MaxBar; i++) - { - barSet->replace(i, 0); - } - - m_pScatterSeries->clear(); - m_pLineSeries->clear(); - chart->update(); - - //订阅实时数据 - kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); - if(!objReader.open()) - { - return;// tr("数据库连接打开失败!"); - } - QString deviceAnalog = code;//m_busBarSelectMap[index.row()]; - deviceAnalog = deviceAnalog.mid(deviceAnalog.indexOf(".") + 1); - m_tagNameMap = QueryAnalogTagName(deviceAnalog, objReader); - - m_sSelDevice = deviceAnalog ; - m_curNode =item->text(0); - // m_rowSelected = index.row(); //选中的行号 - m_columnTotal = m_tagNameMap.count(); //柱状图柱子条数 - if(m_columnTotal > m_MaxBar) - { - m_columnTotal =m_MaxBar; - } - - subscribe(); - - m_barYValueMap.clear(); -} - -void BusbarTemperatureWidget::updateChart() -{ - QChart* chart = m_pChart; - QBarSeries* series = qobject_cast(chart->series().at(0)); - QBarSet* barSet = series->barSets().at(0); - - m_pScatterSeries->clear(); - m_pLineSeries->clear(); - for(int i = 1; i <= m_columnTotal && i< m_MaxBar; i++) - { - if(m_barYValueMap[i].second > 0) - { - barSet->replace(i, m_barYValueMap[i].second); - m_pScatterSeries->append(i * m_space,m_barYValueMap[i].second); - m_pLineSeries->append(i * m_space,m_barYValueMap[i].second); - } - else - { - barSet->replace(i, 0); - m_pScatterSeries->append(i * m_space,0); - m_pLineSeries->append(i * m_space,m_barYValueMap[i].second); - } - } - - chart->update(); -} - - - -void BusbarTemperatureWidget::slotShowChange(bool checked) -{ - if (checked) - { - m_pSeriesBar->setVisible(false); - m_pScatterSeries->setVisible(true); - m_pLineSeries->setVisible(true); - - }else - { - m_pSeriesBar->setVisible(true); - m_pScatterSeries->setVisible(false); - m_pLineSeries->setVisible(false); - - } - -} - -QString BusbarTemperatureWidget::QueryDevinfoTagName(const QString& groupTagName, kbd_dbms::CDbApi& objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QList listColName; - listColName.append("DESCRIPTION"); - kbd_dbms::CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_value = groupTagName; - objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; - - QSqlQuery objQuery; - if(objReader.select("dev_info", listColName, objCondition, objQuery)) - { - while(objQuery.next()) - { - return objQuery.value(0).toString(); - } - } - return QString(); -} - -QMap BusbarTemperatureWidget::QueryAnalogTagName(const QString& device, kbd_dbms::CDbApi& objReader) -{ - if(!objReader.isOpen()) - { - return QMap(); - } - - QList listColName; - listColName.append("TAG_NAME"); - listColName.append("DESCRIPTION"); - - kbd_dbms::CDbCondition objCondition; - objCondition.m_sColName = "DEVICE"; - objCondition.m_value = device; - objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; - - QSqlQuery objQuery; - QMap analogTagName; - m_pointDes.clear(); - - - if(objReader.select("analog", listColName, objCondition, objQuery)) - { - while(objQuery.next()) - { - QString tagNameStr = objQuery.value(0).toString(); - QString DESCRIPTION = objQuery.value(1).toString(); - - QString TagNameMapKey = tagNameStr.split(".")[2]; - analogTagName[TagNameMapKey] = tagNameStr; - - - - int number; - QString xValue = TagNameMapKey; - QString temp; - for(int i = 0; i < xValue.length(); i++) - { - if(xValue[i] >= '0' && xValue[i] <= '9') - temp.append(xValue[i]); - } - number = temp.toInt(); - m_pointDes[number] = DESCRIPTION; - - } - - QMap::iterator iter = analogTagName.begin(); //测试现场log - for(; iter != analogTagName.end(); iter++){ -// QString logQueryAnalogTagName = QString("QueryAnalogTagName analogTagName-key-value-->%1-%2").arg(iter.key()).arg(iter.value()); -// LOGERROR(logQueryAnalogTagName.toStdString().c_str()); - - } - return analogTagName; - } - return QMap(); -} - -BusbarTemperatureWidget::~BusbarTemperatureWidget() -{ - delete ui; - - if(m_pSet) - delete m_pSet; - - if(m_pSeriesBar) - delete m_pSeriesBar; - - if(m_axisX) - delete m_axisX; - - if(m_axisY) - delete m_axisY; - - if(m_pPopupWidget) - delete m_pPopupWidget; - unsubscribeAll(); -} - - +#include "BusbarTemperatureWidget.h" +#include "ui_BusbarTemperatureWidget.h" + + +BusbarTemperatureWidget::BusbarTemperatureWidget(QWidget *parent, bool isEditMode) + :QWidget(parent), + m_isEditMode(isEditMode), + ui(new Ui::BusbarTemperatureWidget) +{ + ui->setupUi(this); + setDeviceTitle(); + m_pPopupWidget = new ShowInfoWidget(QString(), this); + m_pSet = new QBarSet("测点温度"); + + m_axisX = new QValueAxis(); + m_axisY = new QValueAxis(); + m_pChart = new QChart(); + m_pSeriesBar = new QBarSeries(); + m_pScatterSeries = new QScatterSeries(); + m_pLineSeries = new QLineSeries(); + + ui->m_pSearchTextEdit->setPlaceholderText("搜索母线"); + connect(ui->m_pSearchTextEdit, &QLineEdit::textChanged, this, &BusbarTemperatureWidget::FindTagName); + + connect(ui->treeFiles, &QTreeWidget::itemClicked, this, &BusbarTemperatureWidget::onTreeClicked); + return; +} + + +QString BusbarTemperatureWidget::setYAxisRange(const int& minValue, const int& maxValue) +{ + yAxisMin = minValue; + yAxisMax = maxValue; + + initializeChart(); + // m_pChart->axisY()->setRange(yAxisMin,yAxisMax); + return QString(); +} + +QString BusbarTemperatureWidget::setXAxisRange(const int &minValue, const int &maxValue) +{ + xAxisMin = minValue; + xAxisMax = maxValue; + // m_axisX->setRange(xAxisMin, xAxisMax); + return QString(); +} + +QString BusbarTemperatureWidget::setDeviceTitle() +{ + //测试读取csv + QMap, QString> setTitleCsvMap; + QFile file("../../data/BusbarTemperatureWidget/setDeviceTitle.csv"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + QMessageBox::warning(NULL, "警告", "打开data/BusbarTemperatureWidget/setDeviceTitle.csv文件错误!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + return QString(); + } + else + { + ui->treeFiles->clear();//清除目录树所有节点 + ui->treeFiles->setHeaderLabel(""); + + QTextStream in(&file); + in.setCodec("GB2312"); + int row = 0; + QTreeWidgetItem* item_cz; + QTreeWidgetItem* item_mx; + + while(!in.atEnd()) + { + QString line = in.readLine(); + QStringList fileds = line.split(","); + + + if(row >0) + { + //插入数节点 + if(fileds.length() >= 3) + { + if(fileds[2] =="1") + { + //插入厂站节点 + item_cz=new QTreeWidgetItem( ui->treeFiles); //新建节点时设定类型为 itTopItem + item_cz->setText(0,fileds[0]); //设置第2列的文字 + item_cz->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); + ui->treeFiles->addTopLevelItem(item_cz);//添加顶层节点 + + } + else + { + //插入母校节点 + item_mx=new QTreeWidgetItem(item_cz); //新建节点时设定类型为 itTopItem + item_mx->setText(0,fileds[0]); // + item_mx->setText(1,fileds[1]); // + item_mx->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate); + + } + } + + } + row++; + } + file.close(); + } + + /* QStringList titleList; + QStringList measurePointList; + QMap, QString>::const_iterator iter = setTitleCsvMap.constBegin(); + QString listViewTitle = iter.value(); + //iter = iter + 2; + iter = iter + 3; + + for(; iter != setTitleCsvMap.constEnd(); iter++) + { + if(iter.key().second == 0) + { + titleList.append(iter.value()); + } + + if(iter.key().second == 1) + { + measurePointList.append(iter.value()); + } + + }*/ + + + ui->label_listViewTitle->setText("母线名称"); //设置列表标题 + ui->label_listViewTitle->setAlignment(Qt::AlignLeft); //设置标题文字居中 + + + return QString(); +} + + + +void BusbarTemperatureWidget::initializeChart() +{ + m_pChart->legend()->setVisible(true); + m_pChart->legend()->setAlignment(Qt::AlignRight); + m_pChart->setMargins(QMargins(0,0,0,0)); + m_pChart->setBackgroundRoundness(0); + //设置横坐标 + + m_axisX->setRange(xAxisMin, xAxisMax); + m_axisX->setLabelFormat("%d m"); + m_axisX->setTickCount(21); + m_axisX->setGridLineVisible(false); + m_axisX->setTitleText("长度(米)"); + + m_pChart->addAxis(m_axisX, Qt::AlignBottom); + + //设置Y + m_axisY->setTickCount(5); + m_axisY->setTitleText("温度/℃"); + m_axisY->setGridLineVisible(true); + m_axisY->setGridLineColor("#778899"); + m_pChart->addAxis(m_axisY, Qt::AlignLeft); + + m_axisY->setRange(yAxisMin, yAxisMax); + m_axisY->setLinePen(Qt::NoPen); + + m_pSet->setColor("#4169E1"); + m_pSet->setPen(QPen(Qt::NoPen)); + + //设置最大值, + for(int i = 0; i < m_MaxBar; i++) + { + *m_pSet << yAxisMax; + } + + // *m_pSet << 0 << ; + + m_pSeriesBar->append(m_pSet); + + m_pLineSeries->setName("测点温度(线)"); + m_pScatterSeries->setName("测点温度(点)"); + m_pChart->addSeries(m_pSeriesBar); + m_pChart->addSeries(m_pScatterSeries); + m_pChart->addSeries(m_pLineSeries); + + m_pScatterSeries->setColor(Qt::blue); + m_pScatterSeries->attachAxis(m_axisX); //序列 series0 附加坐标轴 + m_pScatterSeries->attachAxis(m_axisY); + + m_pLineSeries->setColor(Qt::blue); + m_pLineSeries->attachAxis(m_axisX); //序列 series0 附加坐标轴 + m_pLineSeries->attachAxis(m_axisY); + + m_pSeriesBar->setVisible(true); + m_pScatterSeries->setVisible(false); + m_pLineSeries->setVisible(false); + + m_pScatterSeries->setPointLabelsFormat("@yPoint"); + // m_pScatterSeries->setPointLabelsVisible(); + m_pScatterSeries->setMarkerSize(8); + + // m_pChart->setTitle("母线温度"); + m_pChart->setAnimationOptions(QChart::SeriesAnimations); + + ui->chartView->setRenderHint(QPainter::Antialiasing); + ui->chartView->setChart(m_pChart); + + + //柱状图清零 + m_space =xAxisMax / m_MaxBar; + for(int i = 0; i < m_MaxBar; i++) + { + m_pSet->replace(i, 0); + } + + if(m_isEditMode) + { + return; + } + + initStyle(); + + kbd_service::CDpcdaForApp::initGlobalThread(); + m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); + + //接收实时数据信号槽 + connect(BTRealDataCollect::instance(), &BTRealDataCollect::signal_updateAi, this, &BusbarTemperatureWidget::slotUpdateAi); + + //鼠标悬停显示坐标信号槽 + connect(m_pSeriesBar, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(AxisXHovered(bool, int, QBarSet*))); + connect(m_pScatterSeries, SIGNAL(hovered(const QPointF&,bool)), this, SLOT(showPos(const QPointF&, bool))); + + //切换显示方式 + connect(ui->radioButtonBar, SIGNAL(toggled(bool)), this, SLOT(slotShowChange(bool))); +} + +void BusbarTemperatureWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + qssfile1.close(); + + std::string style = kbd_public::CFileStyle::getPathOfStyleFile("busbarTemperature.qss") ; + QFile file(QString::fromStdString(style)); + file.open(QFile::ReadOnly); + if (file.isOpen()) + { + setStyleSheet(QLatin1String(file.readAll())); + file.close(); + } +} + +//增加一条特定值的y值的警戒线 +void BusbarTemperatureWidget::setAlarmYaxis(const int& yValue) +{ + QChart* chart = ui->chartView->chart(); + QValueAxis* axisY = qobject_cast(chart->axisY()); + QLineSeries* lineSeries = new QLineSeries; + lineSeries->setName(QString("告警线(%1℃)").arg(yValue)); + lineSeries->append(0, yValue); + lineSeries->append(m_MaxBar, yValue); + lineSeries->setColor(Qt::red); + chart->addSeries(lineSeries); + lineSeries->attachAxis(axisY); + +} + + +//柱状图间隔及图表宽度 +void BusbarTemperatureWidget::setWidth(const float& BarWidth,const int& chartWidth ) +{ + m_pSeriesBar->setBarWidth(BarWidth); + ui->scrollAreaWidgetContents->setMinimumWidth(chartWidth); + +} + +void BusbarTemperatureWidget::setMaxBar(const int &Max) +{ + m_MaxBar =Max; + m_columnTotal =m_MaxBar; +} + +void BusbarTemperatureWidget::setLeftListWidth(const int &Width) +{ + ui->treeFiles->setMaximumWidth(Width); + ui->treeFiles->setMinimumWidth(Width); + + ui->m_pSearchTextEdit->setMaximumWidth(Width); + ui->m_pSearchTextEdit->setMinimumWidth(Width); +} + + +void BusbarTemperatureWidget::showPos(const QPointF& point, bool state) +{ + /* if(m_rowSelected < 0) + { + m_rowSelected =0; + }*/ + + int index =point.x() / m_space; + QString windowTitle =m_curNode;// m_rowNameList[m_rowSelected]; + QString des=m_pointDes[index];//"F23-1-N4-01_2F-13X_1_2_137-1-K36_温度" + // des="F23-1-N4-01_2F-13X_1_2_137-1-K36_温度"; + QStringList list =des.split("_"); + QString label; + QString busLine; //母线 + QString weizhi; //位置 + QString zhuji; //主机 + QString caijiqi; //采集器 + QString jietou; //接头编号 + if(list.length() >=5) + { + busLine = list[0]; //母线 + weizhi = list[1]; //位置 + zhuji = list[2]; //主机 + caijiqi = list[3]; //采集器 + jietou = list[4]; //接头编号 + + } + label = QString("序号:%1\n" + "母线: %2\n" + "位置: %3\n" + "主机: %4\n" + "采集器: %5\n" + "接头编号: %6\n" + "温度: %7℃").arg(index).arg(busLine).arg(weizhi).arg(zhuji).arg(caijiqi).arg(jietou).arg(point.y()); + + ShowInfoWidget *popup = new ShowInfoWidget(label, this); // 创建弹窗窗口; + if(state) { + popup->setWindowTitle(windowTitle); + m_pPopupWidget = popup; + m_pPopupWidget->show(); // 显示弹窗窗口 + }else { + m_pPopupWidget->close(); + } +} + +void BusbarTemperatureWidget::AxisXHovered(const bool& status, const int& index, QBarSet* barSet) +{ + if(m_curNode =="") + { + return; + } + + QString windowTitle =m_curNode;// m_rowNameList[m_rowSelected]; + QString des=m_pointDes[index]; + + // QString des=m_pointDes[index];//"F23-1-N4-01_2F-13X_1_2_137-1-K36_温度" + // des="F23-1-N4-01_2F-13X_1_2_137-1-K36_温度"; + QStringList list =des.split("_"); + QString label; + QString busLine; //母线 + QString weizhi; //位置 + QString zhuji; //主机 + QString caijiqi; //采集器 + QString jietou; //接头编号 + if(list.length() >=5) + { + busLine = list[0]; //母线 + weizhi = list[1]; //位置 + zhuji = list[2]; //主机 + caijiqi = list[3]; //采集器 + jietou = list[4]; //接头编号 + + } + label = QString("序号:%1\n" + "母线: %2\n" + "位置: %3\n" + "主机: %4\n" + "采集器: %5\n" + "接头编号: %6\n" + "温度: %7℃").arg(index).arg(busLine).arg(weizhi).arg(zhuji).arg(caijiqi).arg(jietou).arg(barSet->at(index)); + + // QString label = QString("名称:%1\r\n测点位置: %2\n温度值: %3℃").arg(des).arg(index).arg(barSet->at(index)); + + ShowInfoWidget *popup = new ShowInfoWidget(label, this); // 创建弹窗窗口; + if(status) { + popup->setWindowTitle(windowTitle); + m_pPopupWidget = popup; + m_pPopupWidget->show(); // 显示弹窗窗口 + }else { + m_pPopupWidget->close(); + } +} + +void BusbarTemperatureWidget::subscribe() +{ + if(m_pDpcdaForApp == Q_NULLPTR) + { + return; + } + unsubscribeAll(); + + QMap::const_iterator iter = m_tagNameMap.constBegin(); + for(; iter != m_tagNameMap.constEnd(); iter++) + { + m_pDpcdaForApp->subscribe("analog", iter.value().toStdString(), "value"); + m_pDpcdaForApp->subscribe("analog", iter.value().toStdString(), "status"); + } + return; +} + +void BusbarTemperatureWidget::unsubscribeAll() +{ + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + } +} + +void BusbarTemperatureWidget::slotUpdateAi(const QMap>& aiMap) +{ +// LOGERROR("slotUpdateAi Start!"); + QMap >::const_iterator iter = aiMap.constBegin(); + // logBarYValueMapTag = iter.key().split(".")[0] + iter.key().split(".")[1]; //测试log用 + for(; iter != aiMap.constEnd(); iter++) + { + QString tagNameKey = iter.key().split(".")[2]; + QString sDeviceTagName = iter.key().split(".")[0]+ "."+ iter.key().split(".")[1]; + + if( m_sSelDevice != sDeviceTagName) //实例: T1 ->statio27.S1MXCE1_jgxh.T1 + { + continue; + } + + int number; + QString xValue = iter.key().split(".")[2]; + QString temp; + for(int i = 0; i < xValue.length(); i++) + { + if(xValue[i] >= '0' && xValue[i] <= '9') + temp.append(xValue[i]); + } + number = temp.toInt(); + + m_barYValueMap[number] = qMakePair(xValue, iter.value().first); //11 YC11 234.45 + } + updateChart(); +} + +void BusbarTemperatureWidget::FindTagName() +{ + QString searchword = ui->m_pSearchTextEdit->text(); + + // ui->treeFiles->selectionMode().selectionModel()->select(selection, QItemSelectionModel::Select); + + for(int m=0;m< ui->treeFiles->topLevelItemCount(); ++m) //遍历所有父节点 + { + QTreeWidgetItem * CurTopLevItm = ui->treeFiles->topLevelItem(m); //显示与关键字匹配的馈线 + QString TopNodText=CurTopLevItm->text(0); + bool IsContain=TopNodText.contains(searchword,Qt::CaseInsensitive); //节点名字是否包含关键字 + if(IsContain) + { + if(CurTopLevItm->isHidden()) + CurTopLevItm->setHidden(false); //显示此节点 + } + else + { + CurTopLevItm->setHidden(true); + } + + //遍历该父节点下的子节点 + for(int n =0;nchildCount();++n) + { + QTreeWidgetItem * CurChidItm = CurTopLevItm->child(n); + QString ChilNodText=CurChidItm->text(0); + bool IsContain = ChilNodText.contains(searchword,Qt::CaseInsensitive); //节点名字是否包含关键字 + + if(!IsContain) //与关键字不匹配 + { + CurChidItm->setHidden(true); + continue; + } + CurChidItm->setHidden(false); //与关键字匹配 + if(CurTopLevItm->isHidden()) //显示其父节点 + CurTopLevItm->setHidden(false); + if(!CurTopLevItm->isExpanded()) + CurTopLevItm->setExpanded(true); //展开父节点 + } + } + +} + +void BusbarTemperatureWidget::onTreeClicked(QTreeWidgetItem *item, int column) +{ + QString code = item->text(1); + if(code =="") + { + return; + } + + + //改变图表名字,柱状图清零 + QChart* chart = m_pChart; + + QString Title = item->text(0); + chart->setTitle(Title); + QBarSeries* series = qobject_cast(chart->series().at(0)); + QBarSet* barSet = series->barSets().at(0); + for(int i = 0; i < m_MaxBar; i++) + { + barSet->replace(i, 0); + } + + m_pScatterSeries->clear(); + m_pLineSeries->clear(); + chart->update(); + + //订阅实时数据 + kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); + if(!objReader.open()) + { + return;// tr("数据库连接打开失败!"); + } + QString deviceAnalog = code;//m_busBarSelectMap[index.row()]; + deviceAnalog = deviceAnalog.mid(deviceAnalog.indexOf(".") + 1); + m_tagNameMap = QueryAnalogTagName(deviceAnalog, objReader); + + m_sSelDevice = deviceAnalog ; + m_curNode =item->text(0); + // m_rowSelected = index.row(); //选中的行号 + m_columnTotal = m_tagNameMap.count(); //柱状图柱子条数 + if(m_columnTotal > m_MaxBar) + { + m_columnTotal =m_MaxBar; + } + + subscribe(); + + m_barYValueMap.clear(); +} + +void BusbarTemperatureWidget::updateChart() +{ + QChart* chart = m_pChart; + QBarSeries* series = qobject_cast(chart->series().at(0)); + QBarSet* barSet = series->barSets().at(0); + + m_pScatterSeries->clear(); + m_pLineSeries->clear(); + for(int i = 1; i <= m_columnTotal && i< m_MaxBar; i++) + { + if(m_barYValueMap[i].second > 0) + { + barSet->replace(i, m_barYValueMap[i].second); + m_pScatterSeries->append(i * m_space,m_barYValueMap[i].second); + m_pLineSeries->append(i * m_space,m_barYValueMap[i].second); + } + else + { + barSet->replace(i, 0); + m_pScatterSeries->append(i * m_space,0); + m_pLineSeries->append(i * m_space,m_barYValueMap[i].second); + } + } + + chart->update(); +} + + + +void BusbarTemperatureWidget::slotShowChange(bool checked) +{ + if (checked) + { + m_pSeriesBar->setVisible(false); + m_pScatterSeries->setVisible(true); + m_pLineSeries->setVisible(true); + + }else + { + m_pSeriesBar->setVisible(true); + m_pScatterSeries->setVisible(false); + m_pLineSeries->setVisible(false); + + } + +} + +QString BusbarTemperatureWidget::QueryDevinfoTagName(const QString& groupTagName, kbd_dbms::CDbApi& objReader) const +{ + if(!objReader.isOpen()) + { + return QString(); + } + + QList listColName; + listColName.append("DESCRIPTION"); + kbd_dbms::CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_value = groupTagName; + objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; + + QSqlQuery objQuery; + if(objReader.select("dev_info", listColName, objCondition, objQuery)) + { + while(objQuery.next()) + { + return objQuery.value(0).toString(); + } + } + return QString(); +} + +QMap BusbarTemperatureWidget::QueryAnalogTagName(const QString& device, kbd_dbms::CDbApi& objReader) +{ + if(!objReader.isOpen()) + { + return QMap(); + } + + QList listColName; + listColName.append("TAG_NAME"); + listColName.append("DESCRIPTION"); + + kbd_dbms::CDbCondition objCondition; + objCondition.m_sColName = "DEVICE"; + objCondition.m_value = device; + objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; + + QSqlQuery objQuery; + QMap analogTagName; + m_pointDes.clear(); + + + if(objReader.select("analog", listColName, objCondition, objQuery)) + { + while(objQuery.next()) + { + QString tagNameStr = objQuery.value(0).toString(); + QString DESCRIPTION = objQuery.value(1).toString(); + + QString TagNameMapKey = tagNameStr.split(".")[2]; + analogTagName[TagNameMapKey] = tagNameStr; + + + + int number; + QString xValue = TagNameMapKey; + QString temp; + for(int i = 0; i < xValue.length(); i++) + { + if(xValue[i] >= '0' && xValue[i] <= '9') + temp.append(xValue[i]); + } + number = temp.toInt(); + m_pointDes[number] = DESCRIPTION; + + } + + QMap::iterator iter = analogTagName.begin(); //测试现场log + for(; iter != analogTagName.end(); iter++){ +// QString logQueryAnalogTagName = QString("QueryAnalogTagName analogTagName-key-value-->%1-%2").arg(iter.key()).arg(iter.value()); +// LOGERROR(logQueryAnalogTagName.toStdString().c_str()); + + } + return analogTagName; + } + return QMap(); +} + +BusbarTemperatureWidget::~BusbarTemperatureWidget() +{ + delete ui; + + if(m_pSet) + delete m_pSet; + + if(m_pSeriesBar) + delete m_pSeriesBar; + + if(m_axisX) + delete m_axisX; + + if(m_axisY) + delete m_axisY; + + if(m_pPopupWidget) + delete m_pPopupWidget; + unsubscribeAll(); +} + + diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.h b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.h index 0a97a194..509c3758 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.h +++ b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.h @@ -1,155 +1,155 @@ -#ifndef BUSBARTEMPERATUREWIDGET_H -#define BUSBARTEMPERATUREWIDGET_H - -#include -#include "public/pub_utility_api/FileStyle.h" -#include "db_api_ex/CDbApi.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "pub_logger_api/logger.h" -#include "BTRealDataCollect.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Ui { -class BusbarTemperatureWidget; -} - -/** - * 鼠标悬停在坐标图上是显示该点信息 - */ -class ShowInfoWidget : public QWidget -{ - Q_OBJECT - -public: - ShowInfoWidget(const QString &label, QWidget *parent = nullptr) : QWidget(parent) - { - QVBoxLayout *layout = new QVBoxLayout(this); // 创建一个垂直布局 - QLabel *labelWidget = new QLabel(label, this); // 创建一个标签 - // labelWidget->setAlignment(Qt::AlignCenter); // 设置标签居中对齐 - // labelWidget->setAlignment(Qt::LeftArrow); // 设置标签居中对齐 - labelWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // 标签自适应 - - layout->addWidget(labelWidget); // 将标签添加到布局中 - - setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); // 设置窗口标志 - } -}; - -class BusbarTemperatureWidget : public QWidget -{ - Q_OBJECT - -public: - explicit BusbarTemperatureWidget(QWidget *parent = 0, bool isEditMode = true); - ~BusbarTemperatureWidget(); - -public slots: - /** - * @brief setYAxisRange 设置y轴坐标范围 - * @param minValue y轴最小值 - * @param maxValue y轴最大值 - * @return 空值 - */ - QString setYAxisRange(const int& minValue, const int& maxValue); - - /** - * @brief setYAxisRange 设置x轴坐标范围 - * @param minValue x轴最小值 - * @param maxValue x轴最大值 - * @return 空值 - */ - QString setXAxisRange(const int& minValue, const int& maxValue); - - /** - * @brief setYAxisRange 设置y轴告警线 - * @param yValue y轴最小值 - * @return 空值 - */ - void setAlarmYaxis(const int& yValue); - - /** - * @brief setWidth 设置棒图宽度 - * @param BarWidth 帮图间隔宽度 - * @param chartWidth 图形宽度 - * @return 空值 - */ - void setWidth(const float& BarWidth,const int& chartWidth ); - - /** - * @brief setMaxBar 设置最大帮图数目 - * @param Max 最大数目 - * @return 空值 - */ - void setMaxBar(const int& Max ); - - /** - * @brief setLeftListWidth 设置左侧列表宽度 - * @param Width 左侧列表宽度 - * @return 空值 - */ - void setLeftListWidth(const int& Width ); - -private slots: - // QString onListViewClicked(const QModelIndex& index); - void AxisXHovered(const bool& status, const int& index, QBarSet* barSet); - void showPos(const QPointF& point, bool state); - void slotUpdateAi(const QMap>& aiMap); - - void FindTagName(); - void onTreeClicked(QTreeWidgetItem *item, int column); - void slotShowChange(bool checked); -private: - Ui::BusbarTemperatureWidget *ui; - - void initializeChart(); - void initStyle(); - bool m_isEditMode; - kbd_service::CDpcdaForApp* m_pDpcdaForApp; - void subscribe(); - void unsubscribeAll(); - void updateChart(); - - int yAxisMin=0, yAxisMax=100, xAxisMin=0, xAxisMax=130; - QBarSet *m_pSet; - QBarSeries* m_pSeriesBar; // 柱状图 - QLineSeries* m_pLineSeries ; - QScatterSeries* m_pScatterSeries ; - QChart* m_pChart; - - QValueAxis* m_axisX; - QValueAxis* m_axisY; - - int m_rowSelected; - QString m_curNode; - - int m_columnTotal = 130; - int m_MaxBar = 130; - int m_space; - - QMap m_pointDes; - - QMap m_tagNameMap; //储存取到的analog表TAG_NAME值 - QMap> m_barYValueMap; - - - QMap QueryAnalogTagName(const QString& device, kbd_dbms::CDbApi& objReader) ; - QString QueryDevinfoTagName(const QString& groupTagName, kbd_dbms::CDbApi& objReader) const; - - QString setDeviceTitle(); - ShowInfoWidget* m_pPopupWidget; - - // QString logBarYValueMapTag; - QString m_sSelDevice; -}; - -#endif // BUSBARTEMPERATUREWIDGET_H +#ifndef BUSBARTEMPERATUREWIDGET_H +#define BUSBARTEMPERATUREWIDGET_H + +#include +#include "public/pub_utility_api/FileStyle.h" +#include "db_api_ex/CDbApi.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "pub_logger_api/logger.h" +#include "BTRealDataCollect.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { +class BusbarTemperatureWidget; +} + +/** + * 鼠标悬停在坐标图上是显示该点信息 + */ +class ShowInfoWidget : public QWidget +{ + Q_OBJECT + +public: + ShowInfoWidget(const QString &label, QWidget *parent = nullptr) : QWidget(parent) + { + QVBoxLayout *layout = new QVBoxLayout(this); // 创建一个垂直布局 + QLabel *labelWidget = new QLabel(label, this); // 创建一个标签 + // labelWidget->setAlignment(Qt::AlignCenter); // 设置标签居中对齐 + // labelWidget->setAlignment(Qt::LeftArrow); // 设置标签居中对齐 + labelWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // 标签自适应 + + layout->addWidget(labelWidget); // 将标签添加到布局中 + + setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); // 设置窗口标志 + } +}; + +class BusbarTemperatureWidget : public QWidget +{ + Q_OBJECT + +public: + explicit BusbarTemperatureWidget(QWidget *parent = 0, bool isEditMode = true); + ~BusbarTemperatureWidget(); + +public slots: + /** + * @brief setYAxisRange 设置y轴坐标范围 + * @param minValue y轴最小值 + * @param maxValue y轴最大值 + * @return 空值 + */ + QString setYAxisRange(const int& minValue, const int& maxValue); + + /** + * @brief setYAxisRange 设置x轴坐标范围 + * @param minValue x轴最小值 + * @param maxValue x轴最大值 + * @return 空值 + */ + QString setXAxisRange(const int& minValue, const int& maxValue); + + /** + * @brief setYAxisRange 设置y轴告警线 + * @param yValue y轴最小值 + * @return 空值 + */ + void setAlarmYaxis(const int& yValue); + + /** + * @brief setWidth 设置棒图宽度 + * @param BarWidth 帮图间隔宽度 + * @param chartWidth 图形宽度 + * @return 空值 + */ + void setWidth(const float& BarWidth,const int& chartWidth ); + + /** + * @brief setMaxBar 设置最大帮图数目 + * @param Max 最大数目 + * @return 空值 + */ + void setMaxBar(const int& Max ); + + /** + * @brief setLeftListWidth 设置左侧列表宽度 + * @param Width 左侧列表宽度 + * @return 空值 + */ + void setLeftListWidth(const int& Width ); + +private slots: + // QString onListViewClicked(const QModelIndex& index); + void AxisXHovered(const bool& status, const int& index, QBarSet* barSet); + void showPos(const QPointF& point, bool state); + void slotUpdateAi(const QMap>& aiMap); + + void FindTagName(); + void onTreeClicked(QTreeWidgetItem *item, int column); + void slotShowChange(bool checked); +private: + Ui::BusbarTemperatureWidget *ui; + + void initializeChart(); + void initStyle(); + bool m_isEditMode; + kbd_service::CDpcdaForApp* m_pDpcdaForApp; + void subscribe(); + void unsubscribeAll(); + void updateChart(); + + int yAxisMin=0, yAxisMax=100, xAxisMin=0, xAxisMax=130; + QBarSet *m_pSet; + QBarSeries* m_pSeriesBar; // 柱状图 + QLineSeries* m_pLineSeries ; + QScatterSeries* m_pScatterSeries ; + QChart* m_pChart; + + QValueAxis* m_axisX; + QValueAxis* m_axisY; + + int m_rowSelected; + QString m_curNode; + + int m_columnTotal = 130; + int m_MaxBar = 130; + int m_space; + + QMap m_pointDes; + + QMap m_tagNameMap; //储存取到的analog表TAG_NAME值 + QMap> m_barYValueMap; + + + QMap QueryAnalogTagName(const QString& device, kbd_dbms::CDbApi& objReader) ; + QString QueryDevinfoTagName(const QString& groupTagName, kbd_dbms::CDbApi& objReader) const; + + QString setDeviceTitle(); + ShowInfoWidget* m_pPopupWidget; + + // QString logBarYValueMapTag; + QString m_sSelDevice; +}; + +#endif // BUSBARTEMPERATUREWIDGET_H diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.pro b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.pro index 39cdb8b8..2770910e 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.pro +++ b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.pro @@ -1,65 +1,65 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2023-05-06T20:51:10 -# -#------------------------------------------------- - -QT += core gui charts sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = BusbarTemperatureWidget -TEMPLATE = lib -#TEMPLATE = app - -DEFINES += QT_DEPRECATED_WARNINGS - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - BusbarTemperaturePluginWidget.cpp \ - BusbarTemperatureWidget.cpp \ - BTRealDataCollect.cpp \ - main.cpp - -HEADERS += \ - BusbarTemperaturePluginWidget.h \ - BusbarTemperatureWidget.h \ - BTRealDataCollect.h - -FORMS += \ - BusbarTemperatureWidget.ui - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lrdb_api \ - -ldb_base_api \ - -ldb_api_ex \ - -lprotobuf \ - -lnet_msg_bus_api \ - -ldp_chg_data_api \ - -lpub_utility_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -unix { - target.path = /usr/lib - INSTALLS += target -} +#------------------------------------------------- +# +# Project created by QtCreator 2023-05-06T20:51:10 +# +#------------------------------------------------- + +QT += core gui charts sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = BusbarTemperatureWidget +TEMPLATE = lib +#TEMPLATE = app + +DEFINES += QT_DEPRECATED_WARNINGS + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + BusbarTemperaturePluginWidget.cpp \ + BusbarTemperatureWidget.cpp \ + BTRealDataCollect.cpp \ + main.cpp + +HEADERS += \ + BusbarTemperaturePluginWidget.h \ + BusbarTemperatureWidget.h \ + BTRealDataCollect.h + +FORMS += \ + BusbarTemperatureWidget.ui + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lrdb_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lprotobuf \ + -lnet_msg_bus_api \ + -ldp_chg_data_api \ + -lpub_utility_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +unix { + target.path = /usr/lib + INSTALLS += target +} diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.ui b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.ui index 56c96531..39b1448b 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.ui +++ b/product/src/gui/plugin/BusbarTemperatureWidget/BusbarTemperatureWidget.ui @@ -1,142 +1,142 @@ - - - BusbarTemperatureWidget - - - - 0 - 0 - 1047 - 674 - - - - Form - - - - - - - - background-color: transparent; - - - 母线测温 - - - - - - - - 300 - 16777215 - - - - - - - - - 300 - 16777215 - - - - - 1 - - - - - - - - - - true - - - - - 0 - 0 - 2000 - 637 - - - - - 2000 - 200 - - - - - - - - - Qt::Horizontal - - - - 488 - 20 - - - - - - - - 柱状图 - - - true - - - - - - - 折线 - - - - - - - - - - 500 - 0 - - - - - - - - - - - - - - - - QChartView - QGraphicsView -
qchartview.h
-
-
- - - - updateTest_clicked() - -
+ + + BusbarTemperatureWidget + + + + 0 + 0 + 1047 + 674 + + + + Form + + + + + + + + background-color: transparent; + + + 母线测温 + + + + + + + + 300 + 16777215 + + + + + + + + + 300 + 16777215 + + + + + 1 + + + + + + + + + + true + + + + + 0 + 0 + 2000 + 637 + + + + + 2000 + 200 + + + + + + + + + Qt::Horizontal + + + + 488 + 20 + + + + + + + + 柱状图 + + + true + + + + + + + 折线 + + + + + + + + + + 500 + 0 + + + + + + + + + + + + + + + + QChartView + QGraphicsView +
qchartview.h
+
+
+ + + + updateTest_clicked() + +
diff --git a/product/src/gui/plugin/BusbarTemperatureWidget/main.cpp b/product/src/gui/plugin/BusbarTemperatureWidget/main.cpp index f6b77d02..f4d3ef98 100644 --- a/product/src/gui/plugin/BusbarTemperatureWidget/main.cpp +++ b/product/src/gui/plugin/BusbarTemperatureWidget/main.cpp @@ -1,18 +1,18 @@ -#include "BusbarTemperatureWidget.h" -#include -#include -#include "pub_logger_api/logger.h" - - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - kbd_public::StartLogSystem( "BASE", "alarm_statistics" ); - - BusbarTemperatureWidget w( 0, false ); - w.show(); - int nRet = a.exec(); - - kbd_public::StopLogSystem(); - return nRet; -} +#include "BusbarTemperatureWidget.h" +#include +#include +#include "pub_logger_api/logger.h" + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + kbd_public::StartLogSystem( "BASE", "alarm_statistics" ); + + BusbarTemperatureWidget w( 0, false ); + w.show(); + int nRet = a.exec(); + + kbd_public::StopLogSystem(); + return nRet; +} diff --git a/product/src/gui/plugin/ButtonGroupWidget/ButtonGroupWidget.pro b/product/src/gui/plugin/ButtonGroupWidget/ButtonGroupWidget.pro index 0c44da97..94e8cb18 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/ButtonGroupWidget.pro +++ b/product/src/gui/plugin/ButtonGroupWidget/ButtonGroupWidget.pro @@ -1,50 +1,50 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-07-02T15:52:44 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = ButtonGroupWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ -# main.cpp \ - CButtonGroupWidget.cpp \ - CJsonReader.cpp \ - CButtonGroupPluginWidget.cpp - -HEADERS += \ - CButtonGroupWidget.h \ - CJsonReader.h \ - CButtonGroupPluginWidget.h - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lpub_utility_api - - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-07-02T15:52:44 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ButtonGroupWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ +# main.cpp \ + CButtonGroupWidget.cpp \ + CJsonReader.cpp \ + CButtonGroupPluginWidget.cpp + +HEADERS += \ + CButtonGroupWidget.h \ + CJsonReader.h \ + CButtonGroupPluginWidget.h + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lpub_utility_api + + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.cpp b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.cpp index 1a7e3427..c9543b18 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.cpp +++ b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "CButtonGroupPluginWidget.h" -#include "CButtonGroupWidget.h" - -CButtonGroupPluginWidget::CButtonGroupPluginWidget(QObject *parent) - : QObject(parent) -{ - -} - -CButtonGroupPluginWidget::~CButtonGroupPluginWidget() -{ - -} - -bool CButtonGroupPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CButtonGroupWidget *pWidget = new CButtonGroupWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *pNavigationWidget = (IPluginWidget *)pWidget; - return true; -} - -void CButtonGroupPluginWidget::release() -{ - -} +#include "CButtonGroupPluginWidget.h" +#include "CButtonGroupWidget.h" + +CButtonGroupPluginWidget::CButtonGroupPluginWidget(QObject *parent) + : QObject(parent) +{ + +} + +CButtonGroupPluginWidget::~CButtonGroupPluginWidget() +{ + +} + +bool CButtonGroupPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CButtonGroupWidget *pWidget = new CButtonGroupWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pNavigationWidget = (IPluginWidget *)pWidget; + return true; +} + +void CButtonGroupPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.h b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.h index 1c437099..2d5b75ac 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.h +++ b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CBUTTONGROUPPLUGINWIDGET_H -#define CBUTTONGROUPPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CButtonGroupPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CButtonGroupPluginWidget(QObject *parent = 0); - ~CButtonGroupPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec); - void release(); -}; - -#endif // CBUTTONGROUPPLUGINWIDGET_H +#ifndef CBUTTONGROUPPLUGINWIDGET_H +#define CBUTTONGROUPPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CButtonGroupPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CButtonGroupPluginWidget(QObject *parent = 0); + ~CButtonGroupPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec); + void release(); +}; + +#endif // CBUTTONGROUPPLUGINWIDGET_H diff --git a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.cpp b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.cpp index 4fd354a3..e0a5d404 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.cpp +++ b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.cpp @@ -1,155 +1,155 @@ -#include "CButtonGroupWidget.h" -#include "CJsonReader.h" -#include "public/pub_utility_api/FileUtil.h" -#include -#include -#include -#include -#include -#include - -CButtonGroupWidget::CButtonGroupWidget(QWidget *parent, bool editMode) - : QWidget(parent), - m_pJsonReader(NULL), - m_isEdit(editMode) -{ - initView(); -} - -CButtonGroupWidget::~CButtonGroupWidget() -{ - if(m_pJsonReader) - { - delete m_pJsonReader; - } - m_pJsonReader = NULL; -} - -void CButtonGroupWidget::onButtonClicked(int index) -{ - QList buttonList = this->findChildren(); - if(index < buttonList.length()) - { - emit buttonList[index]->clicked(); - buttonList[index]->setChecked(true); - } - else if(buttonList.length() > 0) - { - emit buttonList[0]->clicked(); - buttonList[0]->setChecked(true); - } -} - -int CButtonGroupWidget::getCheckedButton() -{ - QButtonGroup *group = this->findChild(); - if(group) - { - if(group->checkedButton()) - { - return group->id(group->checkedButton()); - } - } - return 0; -} - -void CButtonGroupWidget::setCheckedButton(int index) -{ - QList buttonList = this->findChildren(); - if(index < buttonList.length()) - { - buttonList[index]->setChecked(true); - } - else if(buttonList.length() > 0) - { - buttonList[0]->setChecked(true); - } -} - -void CButtonGroupWidget::slotButtonClicked() -{ - QString obj = sender()->objectName(); - ST_BUTTON stButton = m_pJsonReader->getStButton(obj); - switch (stButton.type) - { - case SWITCH_GRAPH: - { - emit onGraphClicked(stButton.name, stButton.data); - break; - } - case SWITCH_NAV: - { - stButton.data.replace("2", "0"); - emit onNavigationClicked(stButton.name, stButton.data); - break; - } - case EXTERN_PRO: - { - emit onExternClicked(stButton.name, stButton.data); - break; - } - default: - break; - } -} - -void CButtonGroupWidget::initView() -{ - m_pJsonReader = new CJsonReader(this); - QMap buttonMap = m_pJsonReader->getButtonMap(); - QString separator = m_pJsonReader->getSeparatorPath(); - if(buttonMap.isEmpty()) - { - QGridLayout *layout = new QGridLayout(this); - layout->addWidget(new QPushButton(tr("配置错误!"))); - setLayout(layout); - return; - } - - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - QDir dir(QString::fromStdString(currentPath)); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - dir.cd("back_pixmap"); - - QHBoxLayout *layout = new QHBoxLayout(this); - QWidget *widget; - QButtonGroup *buttonGroup = new QButtonGroup(this); - int id = 0; - QMap::const_iterator iter - = buttonMap.constBegin(); - for(; iter != buttonMap.constEnd(); iter++) - { - if(iter.value().used == 2) - { - continue; - } - QPushButton *button = new QPushButton(QIcon(dir.absoluteFilePath(iter.value().icon)), iter.value().name); - button->setObjectName(iter.key()); - button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - button->setCheckable(true); - buttonGroup->addButton(button, id++); - if(!m_isEdit) - { - connect(button, &QPushButton::clicked, this, &CButtonGroupWidget::slotButtonClicked); - } - layout->addWidget(button); - - if(!separator.isEmpty()) - { - QPixmap pixmap(dir.absoluteFilePath(separator)); - QLabel *label = new QLabel(); - label->setPixmap(pixmap); - layout->addWidget(label); - widget = label; - } - } - if(!separator.isEmpty() && widget) - { - layout->removeWidget(widget); - delete widget; - } - layout->setMargin(0); - setLayout(layout); -} +#include "CButtonGroupWidget.h" +#include "CJsonReader.h" +#include "public/pub_utility_api/FileUtil.h" +#include +#include +#include +#include +#include +#include + +CButtonGroupWidget::CButtonGroupWidget(QWidget *parent, bool editMode) + : QWidget(parent), + m_pJsonReader(NULL), + m_isEdit(editMode) +{ + initView(); +} + +CButtonGroupWidget::~CButtonGroupWidget() +{ + if(m_pJsonReader) + { + delete m_pJsonReader; + } + m_pJsonReader = NULL; +} + +void CButtonGroupWidget::onButtonClicked(int index) +{ + QList buttonList = this->findChildren(); + if(index < buttonList.length()) + { + emit buttonList[index]->clicked(); + buttonList[index]->setChecked(true); + } + else if(buttonList.length() > 0) + { + emit buttonList[0]->clicked(); + buttonList[0]->setChecked(true); + } +} + +int CButtonGroupWidget::getCheckedButton() +{ + QButtonGroup *group = this->findChild(); + if(group) + { + if(group->checkedButton()) + { + return group->id(group->checkedButton()); + } + } + return 0; +} + +void CButtonGroupWidget::setCheckedButton(int index) +{ + QList buttonList = this->findChildren(); + if(index < buttonList.length()) + { + buttonList[index]->setChecked(true); + } + else if(buttonList.length() > 0) + { + buttonList[0]->setChecked(true); + } +} + +void CButtonGroupWidget::slotButtonClicked() +{ + QString obj = sender()->objectName(); + ST_BUTTON stButton = m_pJsonReader->getStButton(obj); + switch (stButton.type) + { + case SWITCH_GRAPH: + { + emit onGraphClicked(stButton.name, stButton.data); + break; + } + case SWITCH_NAV: + { + stButton.data.replace("2", "0"); + emit onNavigationClicked(stButton.name, stButton.data); + break; + } + case EXTERN_PRO: + { + emit onExternClicked(stButton.name, stButton.data); + break; + } + default: + break; + } +} + +void CButtonGroupWidget::initView() +{ + m_pJsonReader = new CJsonReader(this); + QMap buttonMap = m_pJsonReader->getButtonMap(); + QString separator = m_pJsonReader->getSeparatorPath(); + if(buttonMap.isEmpty()) + { + QGridLayout *layout = new QGridLayout(this); + layout->addWidget(new QPushButton(tr("配置错误!"))); + setLayout(layout); + return; + } + + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + QDir dir(QString::fromStdString(currentPath)); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("back_pixmap"); + + QHBoxLayout *layout = new QHBoxLayout(this); + QWidget *widget; + QButtonGroup *buttonGroup = new QButtonGroup(this); + int id = 0; + QMap::const_iterator iter + = buttonMap.constBegin(); + for(; iter != buttonMap.constEnd(); iter++) + { + if(iter.value().used == 2) + { + continue; + } + QPushButton *button = new QPushButton(QIcon(dir.absoluteFilePath(iter.value().icon)), iter.value().name); + button->setObjectName(iter.key()); + button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + button->setCheckable(true); + buttonGroup->addButton(button, id++); + if(!m_isEdit) + { + connect(button, &QPushButton::clicked, this, &CButtonGroupWidget::slotButtonClicked); + } + layout->addWidget(button); + + if(!separator.isEmpty()) + { + QPixmap pixmap(dir.absoluteFilePath(separator)); + QLabel *label = new QLabel(); + label->setPixmap(pixmap); + layout->addWidget(label); + widget = label; + } + } + if(!separator.isEmpty() && widget) + { + layout->removeWidget(widget); + delete widget; + } + layout->setMargin(0); + setLayout(layout); +} diff --git a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.h b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.h index d60b6478..94eaadef 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.h +++ b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.h @@ -1,62 +1,62 @@ -#ifndef CBUTTONGROUPWIDGET_H -#define CBUTTONGROUPWIDGET_H - -#include - -class CJsonReader; -class CButtonGroupWidget : public QWidget -{ - Q_OBJECT - -public: - enum EN_BUTTON_TYPE - { - NONE = 0, //< 无操作 - SWITCH_GRAPH, //< 切换画面 - SWITCH_NAV, //< 切换导航 - EXTERN_PRO, //< 调用程序 - }; - - CButtonGroupWidget(QWidget *parent = 0, bool editMode = true); - ~CButtonGroupWidget(); - -public slots: - void onButtonClicked(int index = 0); - int getCheckedButton(); - void setCheckedButton(int index = 0); - -signals: - /** - * @brief onNavigationClicked - * @param objName 按钮名称 - * @param naviNode 导航栏显示节点 “1,1,1,1,0,1,0,1” - */ - void onNavigationClicked(QString objName, QString naviNode); - - /** - * @brief onGraphClicked - * @param objName 按钮名称 - * @param graph 画面名称 “主接线图.glx” - */ - void onGraphClicked(QString objName, QString graph); - - /** - * @brief onExternClicked - * @param objName 按钮名称 - * @param program 执行程序 “sys_starup” - */ - void onExternClicked(QString objName, QString program); - -private slots: - void slotButtonClicked(); - -private: - void initView(); - -private: - CJsonReader *m_pJsonReader; - bool m_isEdit; - -}; - -#endif // CBUTTONGROUPWIDGET_H +#ifndef CBUTTONGROUPWIDGET_H +#define CBUTTONGROUPWIDGET_H + +#include + +class CJsonReader; +class CButtonGroupWidget : public QWidget +{ + Q_OBJECT + +public: + enum EN_BUTTON_TYPE + { + NONE = 0, //< 无操作 + SWITCH_GRAPH, //< 切换画面 + SWITCH_NAV, //< 切换导航 + EXTERN_PRO, //< 调用程序 + }; + + CButtonGroupWidget(QWidget *parent = 0, bool editMode = true); + ~CButtonGroupWidget(); + +public slots: + void onButtonClicked(int index = 0); + int getCheckedButton(); + void setCheckedButton(int index = 0); + +signals: + /** + * @brief onNavigationClicked + * @param objName 按钮名称 + * @param naviNode 导航栏显示节点 “1,1,1,1,0,1,0,1” + */ + void onNavigationClicked(QString objName, QString naviNode); + + /** + * @brief onGraphClicked + * @param objName 按钮名称 + * @param graph 画面名称 “主接线图.glx” + */ + void onGraphClicked(QString objName, QString graph); + + /** + * @brief onExternClicked + * @param objName 按钮名称 + * @param program 执行程序 “sys_starup” + */ + void onExternClicked(QString objName, QString program); + +private slots: + void slotButtonClicked(); + +private: + void initView(); + +private: + CJsonReader *m_pJsonReader; + bool m_isEdit; + +}; + +#endif // CBUTTONGROUPWIDGET_H diff --git a/product/src/gui/plugin/ButtonGroupWidget/CJsonReader.cpp b/product/src/gui/plugin/ButtonGroupWidget/CJsonReader.cpp index 24264a52..756d98e0 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CJsonReader.cpp +++ b/product/src/gui/plugin/ButtonGroupWidget/CJsonReader.cpp @@ -1,73 +1,73 @@ -#include "CJsonReader.h" -#include "public/pub_utility_api/FileUtil.h" -#include "public/pub_logger_api/logger.h" -#include -#include -#include -#include - -CJsonReader::CJsonReader(QObject *parent) - : QObject(parent) -{ - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - QDir dir(QString::fromStdString(currentPath)); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - dir.cd("model"); - - readJson(dir.filePath("ButtonGroupWidget.json")); -} - -QString CJsonReader::getSeparatorPath() -{ - return m_strSeparator; -} - -QMap CJsonReader::getButtonMap() -{ - return m_mapButton; -} - -ST_BUTTON CJsonReader::getStButton(const QString &key) -{ - return m_mapButton.value(key); -} - -void CJsonReader::readJson(const QString &path) -{ - QFile file(path); - QByteArray readJson; - if(file.open(QIODevice::ReadOnly)) - { - readJson = file.readAll(); - file.close(); - } - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return; - } - QJsonObject root = readJsonResponse.object(); - QJsonObject::const_iterator rootIter = root.constBegin(); - for(; rootIter != root.constEnd(); rootIter++) - { - if(rootIter.key() == "separator") - { - m_strSeparator = rootIter.value().toString(); - continue; - } - QJsonObject item = rootIter.value().toObject(); - ST_BUTTON st_Button; - st_Button.name = item["name"].toString(); - st_Button.used = item["used"].toInt(); - st_Button.type = item["opt"].toInt(); - st_Button.icon = item["icon"].toString(); - st_Button.web = item["web"].toInt(); - st_Button.data = item["data"].toString(); - st_Button.webData = item["webData"].toString(); - m_mapButton.insert(rootIter.key(), st_Button); - } -} +#include "CJsonReader.h" +#include "public/pub_utility_api/FileUtil.h" +#include "public/pub_logger_api/logger.h" +#include +#include +#include +#include + +CJsonReader::CJsonReader(QObject *parent) + : QObject(parent) +{ + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + QDir dir(QString::fromStdString(currentPath)); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("model"); + + readJson(dir.filePath("ButtonGroupWidget.json")); +} + +QString CJsonReader::getSeparatorPath() +{ + return m_strSeparator; +} + +QMap CJsonReader::getButtonMap() +{ + return m_mapButton; +} + +ST_BUTTON CJsonReader::getStButton(const QString &key) +{ + return m_mapButton.value(key); +} + +void CJsonReader::readJson(const QString &path) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + QJsonObject::const_iterator rootIter = root.constBegin(); + for(; rootIter != root.constEnd(); rootIter++) + { + if(rootIter.key() == "separator") + { + m_strSeparator = rootIter.value().toString(); + continue; + } + QJsonObject item = rootIter.value().toObject(); + ST_BUTTON st_Button; + st_Button.name = item["name"].toString(); + st_Button.used = item["used"].toInt(); + st_Button.type = item["opt"].toInt(); + st_Button.icon = item["icon"].toString(); + st_Button.web = item["web"].toInt(); + st_Button.data = item["data"].toString(); + st_Button.webData = item["webData"].toString(); + m_mapButton.insert(rootIter.key(), st_Button); + } +} diff --git a/product/src/gui/plugin/ButtonGroupWidget/CJsonReader.h b/product/src/gui/plugin/ButtonGroupWidget/CJsonReader.h index 5ec88a48..67f739c6 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CJsonReader.h +++ b/product/src/gui/plugin/ButtonGroupWidget/CJsonReader.h @@ -1,39 +1,39 @@ -#ifndef CJSONREADER_H -#define CJSONREADER_H - -#include -#include - -struct ST_BUTTON -{ - QString name; - int used; - int type; - QString icon; - int web; - QString data; - QString webData; -}; - -class CJsonReader : public QObject -{ - Q_OBJECT - -public: - CJsonReader(QObject *parent = 0); - - QString getSeparatorPath(); - - QMap getButtonMap(); - - ST_BUTTON getStButton(const QString &key); - -private: - void readJson(const QString &path); - -private: - QString m_strSeparator; - QMap m_mapButton; -}; - -#endif // CJSONREADER_H +#ifndef CJSONREADER_H +#define CJSONREADER_H + +#include +#include + +struct ST_BUTTON +{ + QString name; + int used; + int type; + QString icon; + int web; + QString data; + QString webData; +}; + +class CJsonReader : public QObject +{ + Q_OBJECT + +public: + CJsonReader(QObject *parent = 0); + + QString getSeparatorPath(); + + QMap getButtonMap(); + + ST_BUTTON getStButton(const QString &key); + +private: + void readJson(const QString &path); + +private: + QString m_strSeparator; + QMap m_mapButton; +}; + +#endif // CJSONREADER_H diff --git a/product/src/gui/plugin/ButtonGroupWidget/main.cpp b/product/src/gui/plugin/ButtonGroupWidget/main.cpp index a115f7d7..fdd5fd9a 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/main.cpp +++ b/product/src/gui/plugin/ButtonGroupWidget/main.cpp @@ -1,11 +1,11 @@ -#include "CButtonGroupWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CButtonGroupWidget w; - w.show(); - - return a.exec(); -} +#include "CButtonGroupWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CButtonGroupWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.cpp b/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.cpp index 53f680da..d522b457 100644 --- a/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.cpp +++ b/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.cpp @@ -1,299 +1,299 @@ -#include "CRealDataCollect.h" -#include -#include - -CRealDataCollect* CRealDataCollect::m_pInstance = NULL; - -CRealDataCollect::CRealDataCollect() - : m_pMbComm(NULL), - m_pTimer(NULL), - m_nTimeCount(0) -{ - initMsg(); - if(!addSub()) - { - return; - } - - m_pTimer = new QTimer(this); - connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); - m_pTimer->start(100); -} - -CRealDataCollect *CRealDataCollect::instance() -{ - if(m_pInstance == NULL) - { - m_pInstance = new CRealDataCollect(); - } - return m_pInstance; -} - -void CRealDataCollect::release() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - delSub(); - closeMsg(); - m_pInstance = NULL; - delete this; -} - -void CRealDataCollect::initMsg() -{ - if(m_pMbComm == NULL) - { - m_pMbComm = new kbd_net::CMbCommunicator("ChanStatusWidget"); - } -} - -void CRealDataCollect::closeMsg() -{ - if(m_pMbComm != NULL) - { - delete m_pMbComm; - } - m_pMbComm = NULL; -} - -void CRealDataCollect::clearMsg() -{ - if(m_pMbComm) - { - kbd_net::CMbMessage objMsg; - while(m_pMbComm->recvMsg(objMsg, 0)) - {} - } -} - -bool CRealDataCollect::addSub() -{ - if(m_pMbComm) - { - return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else - { - return false; - } -} - -bool CRealDataCollect::delSub() -{ - if(m_pMbComm) - { - return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else - { - return false; - } -} - -void CRealDataCollect::recvMessage() -{ - m_nTimeCount = (m_nTimeCount + 1) % 36000; - - if(m_nTimeCount % 10 == 0) - { - processChangeData(); - } - - try - { - kbd_net::CMbMessage objMsg; - for(int i = 0; i < 6; i++) - { - if(m_pMbComm->recvMsg(objMsg, 0)) - { - if(objMsg.isValid()) - { - if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) - { - continue; - } - if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) - { - continue; - } - parserMsg(objMsg); - } - } - } - } - catch(...) - { - - } -} - -void CRealDataCollect::processChangeData() -{ - if(!m_aiMap.isEmpty()) - { - emit signal_updateAi(m_aiMap); - m_aiMap.clear(); - } - - if(!m_diMap.isEmpty()) - { - emit signal_updateDi(m_diMap); - m_diMap.clear(); - } - - if(!m_piMap.isEmpty()) - { - emit signal_updatePi(m_piMap); - m_piMap.clear(); - } - - if(!m_miMap.isEmpty()) - { - emit signal_updateMi(m_miMap); - m_miMap.clear(); - } - - if(!m_uiMap.isEmpty()) - { - emit signal_updateUi(m_uiMap); - m_uiMap.clear(); - } -} - -int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) -{ - kbd_idlfile::SRealTimeDataPkg changeDataPackage; - try - { - changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); - int aiSize = changeDataPackage.stairtd_size(); - if(aiSize > 0) - { - kbd_idlfile::SAiRealTimeData aiStru; - QString tagName; - float value; - uint status; - for(int i = 0; i < aiSize;++i) - { - aiStru = changeDataPackage.stairtd(i); - tagName = QString::fromStdString(aiStru.strtagname()); - value = aiStru.fvalue(); - status = aiStru.ustatus(); - m_aiMap[tagName] = qMakePair(value, status); - } - } - - int diSize = changeDataPackage.stdirtd_size(); - if(diSize > 0) - { - kbd_idlfile::SDiRealTimeData diStu; - QString tagName; - int value; - uint status; - for(int i = 0; i < diSize; ++i) - { - diStu = changeDataPackage.stdirtd(i); - tagName = QString::fromStdString(diStu.strtagname()); - value = diStu.nvalue(); - status = diStu.ustatus(); - m_diMap[tagName] = qMakePair(value, status); - } - } - - int piSize = changeDataPackage.stpirtd_size(); - if(piSize > 0) - { - kbd_idlfile::SPiRealTimeData piStu; - QString tagName; - double value; - uint status; - for(int i = 0 ; i < piSize; ++i) - { - piStu = changeDataPackage.stpirtd(i); - tagName = QString::fromStdString(piStu.strtagname()); - value = piStu.dvalue(); - status = piStu.ustatus(); - m_piMap[tagName] = qMakePair(value, status); - } - } - - int miSize = changeDataPackage.stmirtd_size(); - if(miSize > 0) - { - kbd_idlfile::SMiRealTimeData miStu; - QString tagName; - int value; - uint status; - for(int i = 0 ; i < miSize ; ++i) - { - miStu = changeDataPackage.stmirtd(i); - tagName = QString::fromStdString(miStu.strtagname()); - value = miStu.nvalue(); - status = miStu.ustatus(); - m_miMap[tagName] = qMakePair(value, status); - } - } - - int utSize = changeDataPackage.sttblrtd_size(); - if(utSize > 0) - { - kbd_idlfile::STableRealTimeData uiStu; - QString tagName; - QVariant value; - for(int i = 0;i < utSize; i++) - { - uiStu = changeDataPackage.sttblrtd(i); - tagName = QString::fromStdString(uiStu.strtagname()); - kbd_idlfile::SVariable temp = uiStu.varvalue(); - if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_BOOL) - { - value = QVariant::fromValue(temp.bvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_UINT32) - { - value = QVariant::fromValue(temp.uvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_INT32) - { - value = QVariant::fromValue(temp.nvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_UINT64) - { - value = QVariant::fromValue(temp.ulvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_INT64) - { - value = QVariant::fromValue(temp.lvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_FLOAT) - { - value = QVariant::fromValue(temp.fvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_DOUBLE) - { - value = QVariant::fromValue(temp.dvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_STRING || - temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_BYTES) - { - QString str = QString::fromStdString(temp.strvalue()); - value = QVariant::fromValue(str); - } - else - {} - - m_uiMap[tagName] = value; - } - } - } - catch(...) - { - return 0; - } - return 1; -} +#include "CRealDataCollect.h" +#include +#include + +CRealDataCollect* CRealDataCollect::m_pInstance = NULL; + +CRealDataCollect::CRealDataCollect() + : m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0) +{ + initMsg(); + if(!addSub()) + { + return; + } + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CRealDataCollect *CRealDataCollect::instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CRealDataCollect(); + } + return m_pInstance; +} + +void CRealDataCollect::release() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(); + closeMsg(); + m_pInstance = NULL; + delete this; +} + +void CRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new kbd_net::CMbCommunicator("ChanStatusWidget"); + } +} + +void CRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +void CRealDataCollect::clearMsg() +{ + if(m_pMbComm) + { + kbd_net::CMbMessage objMsg; + while(m_pMbComm->recvMsg(objMsg, 0)) + {} + } +} + +bool CRealDataCollect::addSub() +{ + if(m_pMbComm) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +bool CRealDataCollect::delSub() +{ + if(m_pMbComm) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +void CRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { + processChangeData(); + } + + try + { + kbd_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) + { + continue; + } + if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) + { + continue; + } + parserMsg(objMsg); + } + } + } + } + catch(...) + { + + } +} + +void CRealDataCollect::processChangeData() +{ + if(!m_aiMap.isEmpty()) + { + emit signal_updateAi(m_aiMap); + m_aiMap.clear(); + } + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + + if(!m_piMap.isEmpty()) + { + emit signal_updatePi(m_piMap); + m_piMap.clear(); + } + + if(!m_miMap.isEmpty()) + { + emit signal_updateMi(m_miMap); + m_miMap.clear(); + } + + if(!m_uiMap.isEmpty()) + { + emit signal_updateUi(m_uiMap); + m_uiMap.clear(); + } +} + +int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) +{ + kbd_idlfile::SRealTimeDataPkg changeDataPackage; + try + { + changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); + int aiSize = changeDataPackage.stairtd_size(); + if(aiSize > 0) + { + kbd_idlfile::SAiRealTimeData aiStru; + QString tagName; + float value; + uint status; + for(int i = 0; i < aiSize;++i) + { + aiStru = changeDataPackage.stairtd(i); + tagName = QString::fromStdString(aiStru.strtagname()); + value = aiStru.fvalue(); + status = aiStru.ustatus(); + m_aiMap[tagName] = qMakePair(value, status); + } + } + + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + kbd_idlfile::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); + m_diMap[tagName] = qMakePair(value, status); + } + } + + int piSize = changeDataPackage.stpirtd_size(); + if(piSize > 0) + { + kbd_idlfile::SPiRealTimeData piStu; + QString tagName; + double value; + uint status; + for(int i = 0 ; i < piSize; ++i) + { + piStu = changeDataPackage.stpirtd(i); + tagName = QString::fromStdString(piStu.strtagname()); + value = piStu.dvalue(); + status = piStu.ustatus(); + m_piMap[tagName] = qMakePair(value, status); + } + } + + int miSize = changeDataPackage.stmirtd_size(); + if(miSize > 0) + { + kbd_idlfile::SMiRealTimeData miStu; + QString tagName; + int value; + uint status; + for(int i = 0 ; i < miSize ; ++i) + { + miStu = changeDataPackage.stmirtd(i); + tagName = QString::fromStdString(miStu.strtagname()); + value = miStu.nvalue(); + status = miStu.ustatus(); + m_miMap[tagName] = qMakePair(value, status); + } + } + + int utSize = changeDataPackage.sttblrtd_size(); + if(utSize > 0) + { + kbd_idlfile::STableRealTimeData uiStu; + QString tagName; + QVariant value; + for(int i = 0;i < utSize; i++) + { + uiStu = changeDataPackage.sttblrtd(i); + tagName = QString::fromStdString(uiStu.strtagname()); + kbd_idlfile::SVariable temp = uiStu.varvalue(); + if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_BOOL) + { + value = QVariant::fromValue(temp.bvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_UINT32) + { + value = QVariant::fromValue(temp.uvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_INT32) + { + value = QVariant::fromValue(temp.nvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_UINT64) + { + value = QVariant::fromValue(temp.ulvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_INT64) + { + value = QVariant::fromValue(temp.lvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_FLOAT) + { + value = QVariant::fromValue(temp.fvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_DOUBLE) + { + value = QVariant::fromValue(temp.dvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_STRING || + temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_BYTES) + { + QString str = QString::fromStdString(temp.strvalue()); + value = QVariant::fromValue(str); + } + else + {} + + m_uiMap[tagName] = value; + } + } + } + catch(...) + { + return 0; + } + return 1; +} diff --git a/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.h b/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.h index 0dec53e6..d8f1bea9 100644 --- a/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.h +++ b/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.h @@ -1,55 +1,55 @@ -#ifndef CREALDATACOLLECT_H -#define CREALDATACOLLECT_H - -#include -#include -#include -#include "net_msg_bus_api/CMbCommunicator.h" -#include "MessageChannel.h" -#include "DataProcMessage.pb.h" - -class QTimer; -class CRealDataCollect : public QObject -{ - Q_OBJECT -public: - static CRealDataCollect * instance(); - - void release(); - -private: - CRealDataCollect(); - - void initMsg(); - void closeMsg(); - void clearMsg(); - bool addSub(); - bool delSub(); - - int parserMsg(const kbd_net::CMbMessage &); - -private slots: - void recvMessage(); - void processChangeData(); - -signals: - void signal_updateAi(QMap> aiMap); - void signal_updateDi(QMap> diMap); - void signal_updatePi(QMap> piMap); - void signal_updateMi(QMap> miMap); - void signal_updateUi(QMap uiMap); - -private: - kbd_net::CMbCommunicator *m_pMbComm; - QTimer * m_pTimer; - int m_nTimeCount; - QMap> m_aiMap; - QMap> m_diMap; - QMap> m_piMap; - QMap> m_miMap; - QMap m_uiMap; - - static CRealDataCollect * m_pInstance; -}; - -#endif // CREALDATACOLLECT_H +#ifndef CREALDATACOLLECT_H +#define CREALDATACOLLECT_H + +#include +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" + +class QTimer; +class CRealDataCollect : public QObject +{ + Q_OBJECT +public: + static CRealDataCollect * instance(); + + void release(); + +private: + CRealDataCollect(); + + void initMsg(); + void closeMsg(); + void clearMsg(); + bool addSub(); + bool delSub(); + + int parserMsg(const kbd_net::CMbMessage &); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateAi(QMap> aiMap); + void signal_updateDi(QMap> diMap); + void signal_updatePi(QMap> piMap); + void signal_updateMi(QMap> miMap); + void signal_updateUi(QMap uiMap); + +private: + kbd_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + QMap> m_aiMap; + QMap> m_diMap; + QMap> m_piMap; + QMap> m_miMap; + QMap m_uiMap; + + static CRealDataCollect * m_pInstance; +}; + +#endif // CREALDATACOLLECT_H diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanCommon.h b/product/src/gui/plugin/ChanStatusWidget/ChanCommon.h index 1fc7baa2..55710e83 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanCommon.h +++ b/product/src/gui/plugin/ChanStatusWidget/ChanCommon.h @@ -1,40 +1,40 @@ -#ifndef CHANCOMMON_H -#define CHANCOMMON_H - -#include - -//通道状态 -const int CN_FesChanNotUsed = 0; //保留未用 -const int CN_FesChanCheck = 1; //通道检测,使用但未正常通信 -const int CN_FesChanRun = 2; //通道运行 -const int CN_FesChanStop = 3; //通道停止 -const int CN_FesChanErrRate = 4; //接收帧错误率高 错误率可以设置 - -struct SChanStatus -{ - QString strTag; - QString strLoc; - QString strChan; - int nChanNo; - QString strUsed; - QString strProtoType; - QString strCommProperty; - int nStatus; - QString strIpAddr; - bool isInit; - - SChanStatus(){ - strTag = ""; - strLoc = ""; - strChan = ""; - nChanNo = 0; - strUsed = ""; - strProtoType = ""; - strCommProperty = ""; - nStatus = CN_FesChanNotUsed; - strIpAddr = ""; - isInit = false; - } -}; - -#endif // CHANCOMMON_H +#ifndef CHANCOMMON_H +#define CHANCOMMON_H + +#include + +//通道状态 +const int CN_FesChanNotUsed = 0; //保留未用 +const int CN_FesChanCheck = 1; //通道检测,使用但未正常通信 +const int CN_FesChanRun = 2; //通道运行 +const int CN_FesChanStop = 3; //通道停止 +const int CN_FesChanErrRate = 4; //接收帧错误率高 错误率可以设置 + +struct SChanStatus +{ + QString strTag; + QString strLoc; + QString strChan; + int nChanNo; + QString strUsed; + QString strProtoType; + QString strCommProperty; + int nStatus; + QString strIpAddr; + bool isInit; + + SChanStatus(){ + strTag = ""; + strLoc = ""; + strChan = ""; + nChanNo = 0; + strUsed = ""; + strProtoType = ""; + strCommProperty = ""; + nStatus = CN_FesChanNotUsed; + strIpAddr = ""; + isInit = false; + } +}; + +#endif // CHANCOMMON_H diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.cpp b/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.cpp index 96a80dbb..3d1218d6 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.cpp +++ b/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.cpp @@ -1,25 +1,25 @@ -#include "ChanPluginWidget.h" -#include "ChanStatusWidget.h" - -ChanPluginWidget::ChanPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -ChanPluginWidget::~ChanPluginWidget() -{ - -} - -bool ChanPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - ChanStatusWidget *pWidget = new ChanStatusWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void ChanPluginWidget::release() -{ - -} +#include "ChanPluginWidget.h" +#include "ChanStatusWidget.h" + +ChanPluginWidget::ChanPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +ChanPluginWidget::~ChanPluginWidget() +{ + +} + +bool ChanPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + ChanStatusWidget *pWidget = new ChanStatusWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void ChanPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.h b/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.h index 9288d2bf..d399eaf2 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.h +++ b/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CHANPLUGINWIDGET_H -#define CHANPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class ChanPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - ChanPluginWidget(QObject *parent = 0); - ~ChanPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CHANPLUGINWIDGET_H +#ifndef CHANPLUGINWIDGET_H +#define CHANPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class ChanPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + ChanPluginWidget(QObject *parent = 0); + ~ChanPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CHANPLUGINWIDGET_H diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.cpp b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.cpp index 60ebac45..83119d0e 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.cpp +++ b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.cpp @@ -1,402 +1,402 @@ -#include "ChanStatusWidget.h" -#include "CRealDataCollect.h" -#include "ChanTableModel.h" -#include "db_api_ex/CDbApi.h" -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include -#include -#include -#include -#include "model_excel/xlsx/xlsxdocument.h" -#include - -ChanStatusWidget::ChanStatusWidget(QWidget *parent, bool editMode) - : QWidget(parent), - m_pChanModel(Q_NULLPTR), - m_pDpcdaForApp(Q_NULLPTR) -{ - initStyle(); - initView(); - if(!editMode) - { - initData(); - initConnect(); - } -} - -ChanStatusWidget::~ChanStatusWidget() -{ - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - delete m_pDpcdaForApp; - } - m_pDpcdaForApp = NULL; - - if(m_pChanModel) - { - delete m_pChanModel; - } - m_pChanModel = Q_NULLPTR; - - m_dataMap.clear(); - m_locMap.clear(); -} - -void ChanStatusWidget::setLocation(const QString &locTag) -{ - QMap>::const_iterator iter = m_dataMap.find(locTag); - if(iter == m_dataMap.cend()) - { - return; - } - m_pTreeWidget->hide(); - - int nTopCount = m_pTreeWidget->topLevelItemCount(); - for(int nIndex(0); nIndextopLevelItem(nIndex); - if(locTag == item->data(0, Qt::UserRole).toString()) - { - m_pTreeWidget->setCurrentItem(item); - emit m_pTreeWidget->itemClicked(item, 0); - break; - } - } - - m_pDpcdaForApp->unsubscribeAll(); - foreach (const SChanStatus& sChanStatus, iter.value()) { - m_pDpcdaForApp->subscribe("fes_channel_para", sChanStatus.strTag.toStdString(), "status"); - } -} - -void ChanStatusWidget::setColumnWidth(int column, int width) -{ - if(m_pTableView) - { - m_pTableView->setColumnWidth(column, width); - } -} - -void ChanStatusWidget::initStyle() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("chanStatus.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void ChanStatusWidget::initView() -{ - m_pTreeWidget = new QTreeWidget; - m_pTreeWidget->setColumnCount(1); - m_pTreeWidget->setHeaderLabel(tr("位置")); - - - QSplitter * splitter = new QSplitter(Qt::Horizontal); - splitter->addWidget(m_pTreeWidget); - - QWidget *rightwidget = new QWidget(splitter); - m_btnExport = new QPushButton(tr("导出"), rightwidget); - m_pTableView = new QTableView(rightwidget); - m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_pTableView->setSelectionMode(QAbstractItemView::NoSelection); - m_pTableView->horizontalHeader()->setStretchLastSection(true); - m_pChanModel = new ChanTableModel; - m_pTableView->setModel(m_pChanModel); - - QVBoxLayout *rightLayout = new QVBoxLayout(rightwidget); - rightLayout->addWidget(m_pTableView); - rightLayout->addWidget(m_btnExport); - - splitter->addWidget(rightwidget); - splitter->setStretchFactor(0, 1); - splitter->setStretchFactor(1, 3); - QHBoxLayout * layout = new QHBoxLayout; - layout->addWidget(splitter); - setLayout(layout); -} - -void ChanStatusWidget::initData() -{ - kbd_dbms::CDbApi objDbApi(DB_CONN_MODEL_READ); - if(!objDbApi.open()) - { - LOGERROR("关系库打开失败 %s", objDbApi.getLastErrorString().toStdString().c_str()); - return; - } - - { - //< 初始化位置树 - QSqlQuery objQuery; - QList listColName; - listColName << "LOCATION_ID"; - listColName << "TAG_NAME"; - listColName << "DESCRIPTION"; - QList listOrderBy; - listOrderBy << kbd_dbms::CDbOrder("LOCATION_ID", kbd_dbms::CDbOrder::ORDER_ASC); - if(!objDbApi.select("sys_model_location_info", listColName, listOrderBy, objQuery)) - { - LOGERROR("查询位置信息失败 %s", objDbApi.getLastErrorString().toStdString().c_str()); - return; - } - while(objQuery.next()) - { - m_locMap[objQuery.value(0).toInt()] = qMakePair( - objQuery.value(1).toString(), - objQuery.value(2).toString()); - - QTreeWidgetItem * item = new QTreeWidgetItem; - item->setData(0, Qt::UserRole, objQuery.value(1).toString()); - item->setText(0, objQuery.value(2).toString()); - m_pTreeWidget->addTopLevelItem(item); - } - } - QMap objProtocolMap; - { - //< 通讯规约 - QSqlQuery objQuery; - QList listColName; - listColName << "PROTOCOL_ID"; - listColName << "PROTOCOL_DESC"; - if(!objDbApi.select("fes_protocol", listColName, objQuery)) - { - LOGERROR("查询规约信息失败 %s", objDbApi.getLastErrorString().toStdString().c_str()); - return; - } - while(objQuery.next()) - { - objProtocolMap[objQuery.value(0).toInt()] = objQuery.value(1).toString(); - } - } - { - //< 初始化通道表格 - QSqlQuery objQuery; - QList listColName; - listColName << "TAG_NAME"; - listColName << "DESCRIPTION"; - listColName << "CHAN_NO"; - listColName << "IS_USED"; - listColName << "LOCATION_ID"; - listColName << "PROTO_TYPE"; - listColName << "NET_DESC1"; - listColName << "NET_DESC2"; - listColName << "NET_DESC3"; - listColName << "NET_DESC4"; - listColName << "COMM_PROPERTY"; - QList listOrderBy; - listOrderBy << kbd_dbms::CDbOrder("CHAN_NO", kbd_dbms::CDbOrder::ORDER_ASC); - if(!objDbApi.select("fes_channel_para", listColName, listOrderBy, objQuery)) - { - LOGERROR("查询通道信息失败 %s", objDbApi.getLastErrorString().toStdString().c_str()); - return; - } - while(objQuery.next()) - { - QString tag_name = objQuery.value(0).toString(); - QString chan_name = objQuery.value(1).toString(); - int chan_no = objQuery.value(2).toInt(); - int is_used = objQuery.value(3).toInt(); - int location_id = objQuery.value(4).toInt(); - int proto_type = objQuery.value(5).toInt(); - QString net_desc1 = objQuery.value(6).toString(); - QString net_desc2 = objQuery.value(7).toString(); - QString net_desc3 = objQuery.value(8).toString(); - QString net_desc4 = objQuery.value(9).toString(); - int comm_property = objQuery.value(10).toInt(); - QMap>::iterator locIter = m_locMap.find(location_id); - if(locIter == m_locMap.end()) - { - LOGINFO("通道所属位置在位置信息表中未找到"); - continue; - } - QString net_desc = net_desc1; - if(!net_desc2.isEmpty()) - { - net_desc += "/"; - net_desc += net_desc2; - } - if(!net_desc3.isEmpty()) - { - net_desc += "/"; - net_desc += net_desc3; - } - if(!net_desc4.isEmpty()) - { - net_desc += "/"; - net_desc += net_desc4; - } - QString strUsed = QString::number(is_used); - switch (is_used) { - case 0: - { - strUsed = tr("否"); - break; - } - case 1: - { - strUsed = tr("是"); - break; - } - default: - break; - } - QString strProtoType = objProtocolMap.value(proto_type, tr("未知")); - QString strCommProperty = QString::number(comm_property); - switch (comm_property) { - case 0: - { - strCommProperty = tr("采集通道"); - break; - } - case 1: - { - strCommProperty = tr("转发通道"); - break; - } - default: - break; - } - - SChanStatus sChanStatus; - sChanStatus.strTag = tag_name; - sChanStatus.strChan = chan_name; - sChanStatus.nChanNo = chan_no; - sChanStatus.strUsed = strUsed; - sChanStatus.strLoc = locIter.value().second; - sChanStatus.strProtoType = strProtoType; - sChanStatus.strIpAddr = net_desc; - sChanStatus.strCommProperty = strCommProperty; - m_dataMap[locIter.value().first].append(sChanStatus); - } - } -} - -void ChanStatusWidget::initConnect() -{ - m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); - - connect(m_pTreeWidget, &QTreeWidget::itemClicked, this, &ChanStatusWidget::slotItemClicked); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateUi, this, &ChanStatusWidget::slotUpdateUi); - - connect(m_btnExport, &QPushButton::clicked, this, &ChanStatusWidget::soltExportExcel); - - if(m_pTreeWidget->topLevelItem(0)) - { - m_pTreeWidget->setCurrentItem(m_pTreeWidget->topLevelItem(0)); - emit m_pTreeWidget->itemClicked(m_pTreeWidget->topLevelItem(0), 0); - } - - //< 订阅所有通道状态 - QMap>::const_iterator iter = m_dataMap.cbegin(); - for(; iter != m_dataMap.cend(); iter++) - { - foreach (const SChanStatus& sChanStatus, iter.value()) { - m_pDpcdaForApp->subscribe("fes_channel_para", sChanStatus.strTag.toStdString(), "status"); - } - } -} - -void ChanStatusWidget::slotUpdateUi(QMap uiMap) -{ - QStringList tagList = uiMap.keys(); - QMap>::iterator iter = m_dataMap.begin(); - for(; iter != m_dataMap.end(); iter++) - { - QList &sChanList = iter.value(); - for(int n(0); n < sChanList.length(); n++){ - SChanStatus &sChanStatus = sChanList[n]; - if(tagList.contains(sChanStatus.strTag)) - { - sChanStatus.isInit = true; - sChanStatus.nStatus = uiMap[sChanStatus.strTag].toInt(); - } - } - } - - QTreeWidgetItem * item = m_pTreeWidget->currentItem(); - if(item) - { - QMap>::iterator iter = m_dataMap.find(item->data(0, Qt::UserRole).toString()); - if(iter != m_dataMap.end()) - { - QList dataList = iter.value(); - m_pChanModel->updateRealValue(dataList); - } - } -} - -void ChanStatusWidget::slotItemClicked(QTreeWidgetItem *item, int column) -{ - QList dataList; - if(item == Q_NULLPTR) - { - m_pChanModel->updateRealData(dataList); - return; - } - QString locTag = item->data(column, Qt::UserRole).toString(); - QMap>::const_iterator iter = m_dataMap.find(locTag); - if(iter == m_dataMap.cend()) - { - m_pChanModel->updateRealData(dataList); - return; - } - - dataList = iter.value(); - m_pChanModel->updateRealData(dataList); -} - -void ChanStatusWidget::soltExportExcel() -{ - QString sExcelFileName = QFileDialog::getSaveFileName(this, tr("保存"), QString(""), "*.xlsx"); - if(sExcelFileName.isEmpty()) - return; - - QXlsx::Document xlsx; - - int rowcount=m_pChanModel->rowCount(); - int colcount=m_pChanModel->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - // 写内容 - for ( int i=0; idata(m_pChanModel->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText ); - } - } - // 保存到文件 - if(xlsx.saveAs(sExcelFileName)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!")); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } -} +#include "ChanStatusWidget.h" +#include "CRealDataCollect.h" +#include "ChanTableModel.h" +#include "db_api_ex/CDbApi.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include +#include +#include +#include +#include "model_excel/xlsx/xlsxdocument.h" +#include + +ChanStatusWidget::ChanStatusWidget(QWidget *parent, bool editMode) + : QWidget(parent), + m_pChanModel(Q_NULLPTR), + m_pDpcdaForApp(Q_NULLPTR) +{ + initStyle(); + initView(); + if(!editMode) + { + initData(); + initConnect(); + } +} + +ChanStatusWidget::~ChanStatusWidget() +{ + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = NULL; + + if(m_pChanModel) + { + delete m_pChanModel; + } + m_pChanModel = Q_NULLPTR; + + m_dataMap.clear(); + m_locMap.clear(); +} + +void ChanStatusWidget::setLocation(const QString &locTag) +{ + QMap>::const_iterator iter = m_dataMap.find(locTag); + if(iter == m_dataMap.cend()) + { + return; + } + m_pTreeWidget->hide(); + + int nTopCount = m_pTreeWidget->topLevelItemCount(); + for(int nIndex(0); nIndextopLevelItem(nIndex); + if(locTag == item->data(0, Qt::UserRole).toString()) + { + m_pTreeWidget->setCurrentItem(item); + emit m_pTreeWidget->itemClicked(item, 0); + break; + } + } + + m_pDpcdaForApp->unsubscribeAll(); + foreach (const SChanStatus& sChanStatus, iter.value()) { + m_pDpcdaForApp->subscribe("fes_channel_para", sChanStatus.strTag.toStdString(), "status"); + } +} + +void ChanStatusWidget::setColumnWidth(int column, int width) +{ + if(m_pTableView) + { + m_pTableView->setColumnWidth(column, width); + } +} + +void ChanStatusWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("chanStatus.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void ChanStatusWidget::initView() +{ + m_pTreeWidget = new QTreeWidget; + m_pTreeWidget->setColumnCount(1); + m_pTreeWidget->setHeaderLabel(tr("位置")); + + + QSplitter * splitter = new QSplitter(Qt::Horizontal); + splitter->addWidget(m_pTreeWidget); + + QWidget *rightwidget = new QWidget(splitter); + m_btnExport = new QPushButton(tr("导出"), rightwidget); + m_pTableView = new QTableView(rightwidget); + m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pTableView->setSelectionMode(QAbstractItemView::NoSelection); + m_pTableView->horizontalHeader()->setStretchLastSection(true); + m_pChanModel = new ChanTableModel; + m_pTableView->setModel(m_pChanModel); + + QVBoxLayout *rightLayout = new QVBoxLayout(rightwidget); + rightLayout->addWidget(m_pTableView); + rightLayout->addWidget(m_btnExport); + + splitter->addWidget(rightwidget); + splitter->setStretchFactor(0, 1); + splitter->setStretchFactor(1, 3); + QHBoxLayout * layout = new QHBoxLayout; + layout->addWidget(splitter); + setLayout(layout); +} + +void ChanStatusWidget::initData() +{ + kbd_dbms::CDbApi objDbApi(DB_CONN_MODEL_READ); + if(!objDbApi.open()) + { + LOGERROR("关系库打开失败 %s", objDbApi.getLastErrorString().toStdString().c_str()); + return; + } + + { + //< 初始化位置树 + QSqlQuery objQuery; + QList listColName; + listColName << "LOCATION_ID"; + listColName << "TAG_NAME"; + listColName << "DESCRIPTION"; + QList listOrderBy; + listOrderBy << kbd_dbms::CDbOrder("LOCATION_ID", kbd_dbms::CDbOrder::ORDER_ASC); + if(!objDbApi.select("sys_model_location_info", listColName, listOrderBy, objQuery)) + { + LOGERROR("查询位置信息失败 %s", objDbApi.getLastErrorString().toStdString().c_str()); + return; + } + while(objQuery.next()) + { + m_locMap[objQuery.value(0).toInt()] = qMakePair( + objQuery.value(1).toString(), + objQuery.value(2).toString()); + + QTreeWidgetItem * item = new QTreeWidgetItem; + item->setData(0, Qt::UserRole, objQuery.value(1).toString()); + item->setText(0, objQuery.value(2).toString()); + m_pTreeWidget->addTopLevelItem(item); + } + } + QMap objProtocolMap; + { + //< 通讯规约 + QSqlQuery objQuery; + QList listColName; + listColName << "PROTOCOL_ID"; + listColName << "PROTOCOL_DESC"; + if(!objDbApi.select("fes_protocol", listColName, objQuery)) + { + LOGERROR("查询规约信息失败 %s", objDbApi.getLastErrorString().toStdString().c_str()); + return; + } + while(objQuery.next()) + { + objProtocolMap[objQuery.value(0).toInt()] = objQuery.value(1).toString(); + } + } + { + //< 初始化通道表格 + QSqlQuery objQuery; + QList listColName; + listColName << "TAG_NAME"; + listColName << "DESCRIPTION"; + listColName << "CHAN_NO"; + listColName << "IS_USED"; + listColName << "LOCATION_ID"; + listColName << "PROTO_TYPE"; + listColName << "NET_DESC1"; + listColName << "NET_DESC2"; + listColName << "NET_DESC3"; + listColName << "NET_DESC4"; + listColName << "COMM_PROPERTY"; + QList listOrderBy; + listOrderBy << kbd_dbms::CDbOrder("CHAN_NO", kbd_dbms::CDbOrder::ORDER_ASC); + if(!objDbApi.select("fes_channel_para", listColName, listOrderBy, objQuery)) + { + LOGERROR("查询通道信息失败 %s", objDbApi.getLastErrorString().toStdString().c_str()); + return; + } + while(objQuery.next()) + { + QString tag_name = objQuery.value(0).toString(); + QString chan_name = objQuery.value(1).toString(); + int chan_no = objQuery.value(2).toInt(); + int is_used = objQuery.value(3).toInt(); + int location_id = objQuery.value(4).toInt(); + int proto_type = objQuery.value(5).toInt(); + QString net_desc1 = objQuery.value(6).toString(); + QString net_desc2 = objQuery.value(7).toString(); + QString net_desc3 = objQuery.value(8).toString(); + QString net_desc4 = objQuery.value(9).toString(); + int comm_property = objQuery.value(10).toInt(); + QMap>::iterator locIter = m_locMap.find(location_id); + if(locIter == m_locMap.end()) + { + LOGINFO("通道所属位置在位置信息表中未找到"); + continue; + } + QString net_desc = net_desc1; + if(!net_desc2.isEmpty()) + { + net_desc += "/"; + net_desc += net_desc2; + } + if(!net_desc3.isEmpty()) + { + net_desc += "/"; + net_desc += net_desc3; + } + if(!net_desc4.isEmpty()) + { + net_desc += "/"; + net_desc += net_desc4; + } + QString strUsed = QString::number(is_used); + switch (is_used) { + case 0: + { + strUsed = tr("否"); + break; + } + case 1: + { + strUsed = tr("是"); + break; + } + default: + break; + } + QString strProtoType = objProtocolMap.value(proto_type, tr("未知")); + QString strCommProperty = QString::number(comm_property); + switch (comm_property) { + case 0: + { + strCommProperty = tr("采集通道"); + break; + } + case 1: + { + strCommProperty = tr("转发通道"); + break; + } + default: + break; + } + + SChanStatus sChanStatus; + sChanStatus.strTag = tag_name; + sChanStatus.strChan = chan_name; + sChanStatus.nChanNo = chan_no; + sChanStatus.strUsed = strUsed; + sChanStatus.strLoc = locIter.value().second; + sChanStatus.strProtoType = strProtoType; + sChanStatus.strIpAddr = net_desc; + sChanStatus.strCommProperty = strCommProperty; + m_dataMap[locIter.value().first].append(sChanStatus); + } + } +} + +void ChanStatusWidget::initConnect() +{ + m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); + + connect(m_pTreeWidget, &QTreeWidget::itemClicked, this, &ChanStatusWidget::slotItemClicked); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateUi, this, &ChanStatusWidget::slotUpdateUi); + + connect(m_btnExport, &QPushButton::clicked, this, &ChanStatusWidget::soltExportExcel); + + if(m_pTreeWidget->topLevelItem(0)) + { + m_pTreeWidget->setCurrentItem(m_pTreeWidget->topLevelItem(0)); + emit m_pTreeWidget->itemClicked(m_pTreeWidget->topLevelItem(0), 0); + } + + //< 订阅所有通道状态 + QMap>::const_iterator iter = m_dataMap.cbegin(); + for(; iter != m_dataMap.cend(); iter++) + { + foreach (const SChanStatus& sChanStatus, iter.value()) { + m_pDpcdaForApp->subscribe("fes_channel_para", sChanStatus.strTag.toStdString(), "status"); + } + } +} + +void ChanStatusWidget::slotUpdateUi(QMap uiMap) +{ + QStringList tagList = uiMap.keys(); + QMap>::iterator iter = m_dataMap.begin(); + for(; iter != m_dataMap.end(); iter++) + { + QList &sChanList = iter.value(); + for(int n(0); n < sChanList.length(); n++){ + SChanStatus &sChanStatus = sChanList[n]; + if(tagList.contains(sChanStatus.strTag)) + { + sChanStatus.isInit = true; + sChanStatus.nStatus = uiMap[sChanStatus.strTag].toInt(); + } + } + } + + QTreeWidgetItem * item = m_pTreeWidget->currentItem(); + if(item) + { + QMap>::iterator iter = m_dataMap.find(item->data(0, Qt::UserRole).toString()); + if(iter != m_dataMap.end()) + { + QList dataList = iter.value(); + m_pChanModel->updateRealValue(dataList); + } + } +} + +void ChanStatusWidget::slotItemClicked(QTreeWidgetItem *item, int column) +{ + QList dataList; + if(item == Q_NULLPTR) + { + m_pChanModel->updateRealData(dataList); + return; + } + QString locTag = item->data(column, Qt::UserRole).toString(); + QMap>::const_iterator iter = m_dataMap.find(locTag); + if(iter == m_dataMap.cend()) + { + m_pChanModel->updateRealData(dataList); + return; + } + + dataList = iter.value(); + m_pChanModel->updateRealData(dataList); +} + +void ChanStatusWidget::soltExportExcel() +{ + QString sExcelFileName = QFileDialog::getSaveFileName(this, tr("保存"), QString(""), "*.xlsx"); + if(sExcelFileName.isEmpty()) + return; + + QXlsx::Document xlsx; + + int rowcount=m_pChanModel->rowCount(); + int colcount=m_pChanModel->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString()); + } + // 写内容 + for ( int i=0; idata(m_pChanModel->index(i, j)).toString(); + xlsx.write( i+2, j+1, sText ); + } + } + // 保存到文件 + if(xlsx.saveAs(sExcelFileName)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!")); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } +} diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.h b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.h index fb8a08bc..e6ae2b06 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.h +++ b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.h @@ -1,50 +1,50 @@ -#ifndef CHANSTATUSWIDGET_H -#define CHANSTATUSWIDGET_H - -#include "ChanCommon.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include -#include -#include -#include - -class QTreeWidget; -class QTableView; -class ChanTableModel; -class QTreeWidgetItem; - - -class ChanStatusWidget : public QWidget -{ - Q_OBJECT - -public: - ChanStatusWidget(QWidget *parent = 0, bool editMode = false); - ~ChanStatusWidget(); - -public slots: - void setLocation(const QString& locTag); - - void setColumnWidth(int column, int width); - -private: - void initStyle(); - void initView(); - void initData(); - void initConnect(); - -private slots: - void slotUpdateUi(QMap uiMap); - void slotItemClicked(QTreeWidgetItem *item, int column); - void soltExportExcel(); -private: - QTreeWidget * m_pTreeWidget; - QTableView * m_pTableView; - QPushButton * m_btnExport; - ChanTableModel * m_pChanModel; - kbd_service::CDpcdaForApp *m_pDpcdaForApp; - QMap > m_locMap; //< ID, - QMap> m_dataMap; //< LOC_TAG - Chan -}; - -#endif // CHANSTATUSWIDGET_H +#ifndef CHANSTATUSWIDGET_H +#define CHANSTATUSWIDGET_H + +#include "ChanCommon.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include +#include +#include +#include + +class QTreeWidget; +class QTableView; +class ChanTableModel; +class QTreeWidgetItem; + + +class ChanStatusWidget : public QWidget +{ + Q_OBJECT + +public: + ChanStatusWidget(QWidget *parent = 0, bool editMode = false); + ~ChanStatusWidget(); + +public slots: + void setLocation(const QString& locTag); + + void setColumnWidth(int column, int width); + +private: + void initStyle(); + void initView(); + void initData(); + void initConnect(); + +private slots: + void slotUpdateUi(QMap uiMap); + void slotItemClicked(QTreeWidgetItem *item, int column); + void soltExportExcel(); +private: + QTreeWidget * m_pTreeWidget; + QTableView * m_pTableView; + QPushButton * m_btnExport; + ChanTableModel * m_pChanModel; + kbd_service::CDpcdaForApp *m_pDpcdaForApp; + QMap > m_locMap; //< ID, + QMap> m_dataMap; //< LOC_TAG - Chan +}; + +#endif // CHANSTATUSWIDGET_H diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.pro b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.pro index 52e5f077..21c030ed 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.pro +++ b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.pro @@ -1,57 +1,57 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2022-02-22T08:59:19 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = ChanStatusWidget -TEMPLATE = lib - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - ChanStatusWidget.cpp \ - CRealDataCollect.cpp \ - ChanTableModel.cpp \ - ChanPluginWidget.cpp - -HEADERS += \ - ChanStatusWidget.h \ - CRealDataCollect.h \ - ChanTableModel.h \ - ChanCommon.h \ - ChanPluginWidget.h - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -ldb_base_api \ - -ldb_api_ex \ - -lprotobuf \ - -lnet_msg_bus_api \ - -ldp_chg_data_api \ - -lpub_utility_api \ - -lmodel_excel - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2022-02-22T08:59:19 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ChanStatusWidget +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + ChanStatusWidget.cpp \ + CRealDataCollect.cpp \ + ChanTableModel.cpp \ + ChanPluginWidget.cpp + +HEADERS += \ + ChanStatusWidget.h \ + CRealDataCollect.h \ + ChanTableModel.h \ + ChanCommon.h \ + ChanPluginWidget.h + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lprotobuf \ + -lnet_msg_bus_api \ + -ldp_chg_data_api \ + -lpub_utility_api \ + -lmodel_excel + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.cpp b/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.cpp index 104d25f7..9e703c47 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.cpp +++ b/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.cpp @@ -1,172 +1,172 @@ -#include "ChanTableModel.h" -#include - -ChanTableModel::ChanTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header << tr("序号") << tr("位置") << tr("通道号") << tr("通道描述") << tr("通道使能") << tr("通讯性质") << tr("通讯规约") << tr("通道地址") << tr("通道状态"); -} - -ChanTableModel::~ChanTableModel() -{ - m_dataList.clear(); -} - -void ChanTableModel::updateRealData(const QList &dataList) -{ - beginResetModel(); - m_dataList.clear(); - m_dataList = dataList; - endResetModel(); -} - -void ChanTableModel::updateRealValue(QList &dataList) -{ - m_dataList.swap(dataList); - update(); -} - -void ChanTableModel::update() -{ - QModelIndex topLeft = createIndex(0, 8); - QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount()); - emit dataChanged(topLeft, bottomRight); -} - -QVariant ChanTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_header.at(section); - } - } - return QVariant(); -} - -int ChanTableModel::rowCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_dataList.size(); -} - -int ChanTableModel::columnCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_header.size(); -} - -QVariant ChanTableModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - return Qt::AlignCenter; - } - - if(Qt::TextColorRole == role && index.column() == 8) - { - if(!m_dataList.at(index.row()).isInit) - { - return QVariant(); - } - if(m_dataList.at(index.row()).nStatus == CN_FesChanStop - || m_dataList.at(index.row()).nStatus == CN_FesChanErrRate) - { - return QVariant(QBrush(QColor(255,0,0))); - } - return QVariant(); - } - - if(Qt::DisplayRole != role) - { - return QVariant(); - } - - switch (index.column()) { - case 0: - { - return index.row()+1; - } - case 1: - { - return m_dataList.at(index.row()).strLoc; - } - case 2: - { - return m_dataList.at(index.row()).nChanNo; - } - case 3: - { - return m_dataList.at(index.row()).strChan; - } - case 4: - { - return m_dataList.at(index.row()).strUsed; - } - case 5: - { - return m_dataList.at(index.row()).strCommProperty; - } - case 6: - { - return m_dataList.at(index.row()).strProtoType; - } - case 7: - { - return m_dataList.at(index.row()).strIpAddr; - } - case 8: - { - if(!m_dataList.at(index.row()).isInit) - { - return QVariant(); - } - - return getChanStatusDesc(m_dataList.at(index.row()).nStatus); - } - default: - break; - } - - return QVariant(); -} - -QString ChanTableModel::getChanStatusDesc(const int &status) const -{ - switch (status) { - case CN_FesChanNotUsed: - { - return tr("保留未用"); - } - case CN_FesChanCheck: - { - return tr("通道检测"); - } - case CN_FesChanRun: - { - return tr("通道运行"); - } - case CN_FesChanStop: - { - return tr("通道停止"); - } - case CN_FesChanErrRate: - { - return tr("接收帧错误率高"); - } - default: - break; - } - - return QString(); -} +#include "ChanTableModel.h" +#include + +ChanTableModel::ChanTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header << tr("序号") << tr("位置") << tr("通道号") << tr("通道描述") << tr("通道使能") << tr("通讯性质") << tr("通讯规约") << tr("通道地址") << tr("通道状态"); +} + +ChanTableModel::~ChanTableModel() +{ + m_dataList.clear(); +} + +void ChanTableModel::updateRealData(const QList &dataList) +{ + beginResetModel(); + m_dataList.clear(); + m_dataList = dataList; + endResetModel(); +} + +void ChanTableModel::updateRealValue(QList &dataList) +{ + m_dataList.swap(dataList); + update(); +} + +void ChanTableModel::update() +{ + QModelIndex topLeft = createIndex(0, 8); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount()); + emit dataChanged(topLeft, bottomRight); +} + +QVariant ChanTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); +} + +int ChanTableModel::rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_dataList.size(); +} + +int ChanTableModel::columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_header.size(); +} + +QVariant ChanTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + return Qt::AlignCenter; + } + + if(Qt::TextColorRole == role && index.column() == 8) + { + if(!m_dataList.at(index.row()).isInit) + { + return QVariant(); + } + if(m_dataList.at(index.row()).nStatus == CN_FesChanStop + || m_dataList.at(index.row()).nStatus == CN_FesChanErrRate) + { + return QVariant(QBrush(QColor(255,0,0))); + } + return QVariant(); + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + switch (index.column()) { + case 0: + { + return index.row()+1; + } + case 1: + { + return m_dataList.at(index.row()).strLoc; + } + case 2: + { + return m_dataList.at(index.row()).nChanNo; + } + case 3: + { + return m_dataList.at(index.row()).strChan; + } + case 4: + { + return m_dataList.at(index.row()).strUsed; + } + case 5: + { + return m_dataList.at(index.row()).strCommProperty; + } + case 6: + { + return m_dataList.at(index.row()).strProtoType; + } + case 7: + { + return m_dataList.at(index.row()).strIpAddr; + } + case 8: + { + if(!m_dataList.at(index.row()).isInit) + { + return QVariant(); + } + + return getChanStatusDesc(m_dataList.at(index.row()).nStatus); + } + default: + break; + } + + return QVariant(); +} + +QString ChanTableModel::getChanStatusDesc(const int &status) const +{ + switch (status) { + case CN_FesChanNotUsed: + { + return tr("保留未用"); + } + case CN_FesChanCheck: + { + return tr("通道检测"); + } + case CN_FesChanRun: + { + return tr("通道运行"); + } + case CN_FesChanStop: + { + return tr("通道停止"); + } + case CN_FesChanErrRate: + { + return tr("接收帧错误率高"); + } + default: + break; + } + + return QString(); +} diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.h b/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.h index b3abacc3..6fef4d20 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.h +++ b/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.h @@ -1,32 +1,32 @@ -#ifndef CHANTABLEMODEL_H -#define CHANTABLEMODEL_H - -#include -#include "ChanCommon.h" - -class ChanTableModel : public QAbstractTableModel -{ -public: - ChanTableModel(QObject *parent = Q_NULLPTR); - ~ChanTableModel(); - - void updateRealData(const QList &dataList); - - void updateRealValue(QList &dataList); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; -private: - void update(); - -private: - QString getChanStatusDesc(const int &status) const; - -private: - QStringList m_header; - QList m_dataList; -}; - -#endif // CHANTABLEMODEL_H +#ifndef CHANTABLEMODEL_H +#define CHANTABLEMODEL_H + +#include +#include "ChanCommon.h" + +class ChanTableModel : public QAbstractTableModel +{ +public: + ChanTableModel(QObject *parent = Q_NULLPTR); + ~ChanTableModel(); + + void updateRealData(const QList &dataList); + + void updateRealValue(QList &dataList); + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; +private: + void update(); + +private: + QString getChanStatusDesc(const int &status) const; + +private: + QStringList m_header; + QList m_dataList; +}; + +#endif // CHANTABLEMODEL_H diff --git a/product/src/gui/plugin/ChanStatusWidget/main.cpp b/product/src/gui/plugin/ChanStatusWidget/main.cpp index 7e0b1548..4cfcb9f1 100644 --- a/product/src/gui/plugin/ChanStatusWidget/main.cpp +++ b/product/src/gui/plugin/ChanStatusWidget/main.cpp @@ -1,31 +1,31 @@ -#include "ChanStatusWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "net/net_msg_bus_api/MsgBusApi.h" - -int main(int argc, char *argv[]) -{ - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - - kbd_service::CDpcdaForApp::initGlobalThread(); - - { - QApplication a(argc, argv); - ChanStatusWidget w; - w.show(); - - a.exec(); - } - - kbd_service::CDpcdaForApp::releaseGlobalThread(); - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include "ChanStatusWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" + +int main(int argc, char *argv[]) +{ + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + + kbd_service::CDpcdaForApp::initGlobalThread(); + + { + QApplication a(argc, argv); + ChanStatusWidget w; + w.show(); + + a.exec(); + } + + kbd_service::CDpcdaForApp::releaseGlobalThread(); + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/ConstCurves/CConstCurves.cpp b/product/src/gui/plugin/ConstCurves/CConstCurves.cpp index 8843eea0..33ac160b 100644 --- a/product/src/gui/plugin/ConstCurves/CConstCurves.cpp +++ b/product/src/gui/plugin/ConstCurves/CConstCurves.cpp @@ -1,324 +1,324 @@ -#include "CConstCurves.h" -#include "ui_CConstCurves.h" -#include "pub_logger_api/logger.h" -#include -#include "pub_utility_api/FileStyle.h" - -const int MAX_TIME = 35; -CConstCurves::CConstCurves(bool editMode, QVector ptrVec, QWidget *parent) : - QWidget(parent), - ui(new Ui::CConstCurves), - m_dbInterface(NULL), - m_messageMng(NULL) -{ - Q_UNUSED(ptrVec) - ui->setupUi(this); - - initView(); - QString style = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("constCurves.qss") ; - QFile file1(QString::fromStdString(strFullPath)); - if (file1.open(QIODevice::ReadOnly)) - { - QTextStream styleStream(&file1); - style += styleStream.readAll(); - //setStyleSheet(style); - } - file1.close(); - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("constCurves.qss") ; - QFile file2(QString::fromStdString(strFullPath)); - if (file2.open(QIODevice::ReadOnly)) - { - QTextStream styleStream(&file2); - style += styleStream.readAll(); - //setStyleSheet(style); - } - file2.close(); - - if(!style.isEmpty()) - { - setStyleSheet(style); - } - - if(!editMode) - { - initialize(); - } -} - -CConstCurves::~CConstCurves() -{ - if(m_dbInterface) - { - delete m_dbInterface; - } - m_dbInterface = NULL; - - if(m_messageMng) - { - delete m_messageMng; - } - m_messageMng = NULL; - - delete ui; -} - -void CConstCurves::slotDevItemChanged(QTreeWidgetItem* item,int column) -{ - Q_UNUSED(column); - devItemChanged(item); -} - -void CConstCurves::slotDataChanged(const SReplyQueue &reply) -{ - if(!m_isReading) - { - return; - } - - for(int nIndex=0; nIndexm_constTree->topLevelItemCount(); ++nIndex) - { - QString devId = ui->m_constTree->topLevelItem(nIndex)->data(0, Qt::UserRole).toString().section(",", 1, 1); - QString rtuTg = ui->m_constTree->topLevelItem(nIndex)->data(0, Qt::UserRole+2).toString(); - if(reply.dev_id == devId.toInt() - && reply.rtu_tag == rtuTg) - { - if(reply.isSuccess == 0) - { - QMessageBox::information(this, tr("提示"), tr("%1 定值读取失败: %2").arg(m_strDevName).arg(reply.resultStr), QMessageBox::Ok); - break; - } - - ui->m_constTree->topLevelItem(nIndex)->setText(1, "(当前执行组:"+QString::number(reply.cur_group)+")"); - updateValue(ui->m_constTree->topLevelItem(nIndex), reply.dotList, reply.valueList); - insertCurve(ui->m_constTree->topLevelItem(nIndex)); - break; - } - } - m_isReading = false; -} - -void CConstCurves::on_m_readBtn_clicked() -{ - m_queueList.clear(); - ui->m_curveWidget->clearSeries(); - int deviceNum = ui->m_constTree->topLevelItemCount(); - for(int nIndex=0; nIndexm_constTree->topLevelItem(nIndex); - sReadQueue.dev_id = item->data(0, Qt::UserRole).toString().section(",", 1, 1).toInt(); - sReadQueue.tag_name = item->data(0, Qt::UserRole+1).toString(); - sReadQueue.rtu_tag = item->data(0, Qt::UserRole+2).toString(); - sReadQueue.dev_name = item->text(0); - - m_queueList.push_back(sReadQueue); - } - ui->m_readBtn->setEnabled(false); -} - -void CConstCurves::ontime() -{ - if(!m_isReading) - { - if(m_queueList.isEmpty()) - { - ui->m_readBtn->setEnabled(true); - return; - } - - sendMessage(m_queueList.takeFirst()); - return; - } - - m_nTimerSec += 1; - if(m_nTimerSec > MAX_TIME) - { - QMessageBox::information(this, tr("提示"), tr("%1 定值读取超时").arg(m_strDevName), QMessageBox::Ok); - m_isReading = false; - return; - } -} - -void CConstCurves::initialize() -{ - QString strColorConfig; - QFile colorFile("://resource/color.cfg"); - if (colorFile.open(QIODevice::ReadOnly)) - { - QTextStream colorStream(&colorFile); - strColorConfig= colorStream.readAll(); - } - QStringList listColor = strColorConfig.split("\n"); - ui->m_curveWidget->setColorList(listColor); - - m_dbInterface = new CDbInterface(); - m_messageMng = new CMessageManage(this); - - connect(m_messageMng, SIGNAL(dataChanged(SReplyQueue)), this, SLOT(slotDataChanged(SReplyQueue))); - - if(!createSysInfoInstance(m_sysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - } - - SNodeInfo sNodeInfo; - m_sysInfo->getLocalNodeInfo(sNodeInfo); - m_nDomainID = sNodeInfo.nDomainId; - - initDevTree(); - m_isReading = false; - QTimer *timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(ontime())); - timer->start(1000); -} - -void CConstCurves::initView() -{ - ui->m_devTree->setColumnCount(1); - ui->m_devTree->header()->hide(); - connect(ui->m_devTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(slotDevItemChanged(QTreeWidgetItem*,int))); - - ui->m_constTree->setColumnCount(2); - ui->m_constTree->setColumnWidth(0, 500); - ui->m_constTree->setHeaderLabels(QStringList() << tr("名称") << tr("值")); - - ui->splitter->setStretchFactor(1,1); -} - -void CConstCurves::initDevTree() -{ - QMap locMap; - QList locList; - m_dbInterface->readLocationInfo(m_nDomainID, locMap, locList); - foreach (const int locId, locList) { - QMap device = m_dbInterface->readFesDevInfo(locId); - if(!device.size()) - { - continue; - } - - QTreeWidgetItem *item = new QTreeWidgetItem(LOCATION_TYPE); - item->setText(0, locMap.value(locId)); - QMap::const_iterator device_iter = device.constBegin(); - while(device_iter != device.constEnd()) - { - QList constList = m_dbInterface->queryFesConst(device_iter.key().section(",", 0, 0)); - if(constList.length() == 0) - { - ++device_iter; - continue; - } - - QTreeWidgetItem *devItem = new QTreeWidgetItem(DEV_TYPE); - devItem->setText(0, device_iter.value()); - devItem->setData(0, Qt::UserRole, device_iter.key()); - devItem->setData(0, Qt::CheckStateRole, Qt::Unchecked); - item->addChild(devItem); - ++device_iter; - } - ui->m_devTree->addTopLevelItem(item); - } - ui->m_devTree->expandAll(); -} - -void CConstCurves::devItemChanged(QTreeWidgetItem *item) -{ - if(item->data(0, Qt::CheckStateRole) == Qt::Checked) - { - QList constList = m_dbInterface->queryFesConst(item->data(0, Qt::UserRole).toString().section(",", 0, 0)); - if(constList.length() == 0) - { - return; - } - QTreeWidgetItem *devItem = new QTreeWidgetItem(DEV_TYPE); - devItem->setText(0, item->text(0)); - devItem->setData(0, Qt::UserRole, item->data(0, Qt::UserRole).toString()); //devTag,devID - for(int i=0; isetData(0, Qt::UserRole+1, constList.at(i).tag_name); - devItem->setData(0, Qt::UserRole+2, constList.at(i).rtu_tag); - } - if(constList.at(i).value_type != 1) - { - continue; - } - if(devItem->data(0, Qt::UserRole+1).toString() == QString()) - { - devItem->setData(0, Qt::UserRole+1, constList.at(i).tag_name); - devItem->setData(0, Qt::UserRole+2, constList.at(i).rtu_tag); - } - QTreeWidgetItem *tagItem = new QTreeWidgetItem(TAG_TYPE); - tagItem->setText(0, constList.at(i).description); - tagItem->setData(0, Qt::UserRole, constList.at(i).seq_no); - tagItem->setData(1, Qt::UserRole, QString("%1,%2").arg(constList.at(i).value_ratio).arg(constList.at(i).value_added)); - devItem->addChild(tagItem); - } - ui->m_constTree->addTopLevelItem(devItem); - ui->m_constTree->expandItem(devItem); - } - else if(item->data(0, Qt::CheckStateRole) == Qt::Unchecked) - { - int topCount = ui->m_constTree->topLevelItemCount(); - for(int i=0; im_constTree->topLevelItem(i)->data(0, Qt::UserRole).toString() == item->data(0, Qt::UserRole).toString()) - { - ui->m_constTree->takeTopLevelItem(i); - return; - } - } - } -} - -void CConstCurves::updateValue(QTreeWidgetItem* item, QList dotList, QList valueList) -{ - for(int nIndex=0; nIndexchildCount(); ++nIndex) - { - QTreeWidgetItem *tagItem = item->child(nIndex); - for(int dIndex=0; dIndexdata(0, Qt::UserRole).toInt() == dotList.at(dIndex)) - { - double ratio = tagItem->data(1, Qt::UserRole).toString().section(",", 0, 0).toDouble(); - double added = tagItem->data(1, Qt::UserRole).toString().section(",", 1, 1).toDouble(); - QString display = QString::number(valueList.at(dIndex) * ratio + added); - tagItem->setText(1, display); - break; - } - } - } -} - -void CConstCurves::insertCurve(QTreeWidgetItem *item) -{ - QList pointList; - int nCount = item->childCount(); - for(int nIndex=0; nIndexchild(nIndex++)->text(1).toDouble()); - point.setX(item->child(nIndex)->text(1).toDouble()); - pointList.append(point); - } - - ui->m_curveWidget->insertLineSeries(pointList, m_strDevName); -} - -void CConstCurves::sendMessage(const SReadQueue& sReadQueue) -{ - if(!m_messageMng->sendMessage(sReadQueue, m_nDomainID)) - { - QMessageBox::information(this, tr("提示"), tr("%1 下发定值读取命令失败").arg(sReadQueue.dev_name), QMessageBox::Ok); - return; - } - - m_nTimerSec = 0; - m_strDevName = sReadQueue.dev_name; - m_isReading = true; -} - - +#include "CConstCurves.h" +#include "ui_CConstCurves.h" +#include "pub_logger_api/logger.h" +#include +#include "pub_utility_api/FileStyle.h" + +const int MAX_TIME = 35; +CConstCurves::CConstCurves(bool editMode, QVector ptrVec, QWidget *parent) : + QWidget(parent), + ui(new Ui::CConstCurves), + m_dbInterface(NULL), + m_messageMng(NULL) +{ + Q_UNUSED(ptrVec) + ui->setupUi(this); + + initView(); + QString style = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("constCurves.qss") ; + QFile file1(QString::fromStdString(strFullPath)); + if (file1.open(QIODevice::ReadOnly)) + { + QTextStream styleStream(&file1); + style += styleStream.readAll(); + //setStyleSheet(style); + } + file1.close(); + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("constCurves.qss") ; + QFile file2(QString::fromStdString(strFullPath)); + if (file2.open(QIODevice::ReadOnly)) + { + QTextStream styleStream(&file2); + style += styleStream.readAll(); + //setStyleSheet(style); + } + file2.close(); + + if(!style.isEmpty()) + { + setStyleSheet(style); + } + + if(!editMode) + { + initialize(); + } +} + +CConstCurves::~CConstCurves() +{ + if(m_dbInterface) + { + delete m_dbInterface; + } + m_dbInterface = NULL; + + if(m_messageMng) + { + delete m_messageMng; + } + m_messageMng = NULL; + + delete ui; +} + +void CConstCurves::slotDevItemChanged(QTreeWidgetItem* item,int column) +{ + Q_UNUSED(column); + devItemChanged(item); +} + +void CConstCurves::slotDataChanged(const SReplyQueue &reply) +{ + if(!m_isReading) + { + return; + } + + for(int nIndex=0; nIndexm_constTree->topLevelItemCount(); ++nIndex) + { + QString devId = ui->m_constTree->topLevelItem(nIndex)->data(0, Qt::UserRole).toString().section(",", 1, 1); + QString rtuTg = ui->m_constTree->topLevelItem(nIndex)->data(0, Qt::UserRole+2).toString(); + if(reply.dev_id == devId.toInt() + && reply.rtu_tag == rtuTg) + { + if(reply.isSuccess == 0) + { + QMessageBox::information(this, tr("提示"), tr("%1 定值读取失败: %2").arg(m_strDevName).arg(reply.resultStr), QMessageBox::Ok); + break; + } + + ui->m_constTree->topLevelItem(nIndex)->setText(1, "(当前执行组:"+QString::number(reply.cur_group)+")"); + updateValue(ui->m_constTree->topLevelItem(nIndex), reply.dotList, reply.valueList); + insertCurve(ui->m_constTree->topLevelItem(nIndex)); + break; + } + } + m_isReading = false; +} + +void CConstCurves::on_m_readBtn_clicked() +{ + m_queueList.clear(); + ui->m_curveWidget->clearSeries(); + int deviceNum = ui->m_constTree->topLevelItemCount(); + for(int nIndex=0; nIndexm_constTree->topLevelItem(nIndex); + sReadQueue.dev_id = item->data(0, Qt::UserRole).toString().section(",", 1, 1).toInt(); + sReadQueue.tag_name = item->data(0, Qt::UserRole+1).toString(); + sReadQueue.rtu_tag = item->data(0, Qt::UserRole+2).toString(); + sReadQueue.dev_name = item->text(0); + + m_queueList.push_back(sReadQueue); + } + ui->m_readBtn->setEnabled(false); +} + +void CConstCurves::ontime() +{ + if(!m_isReading) + { + if(m_queueList.isEmpty()) + { + ui->m_readBtn->setEnabled(true); + return; + } + + sendMessage(m_queueList.takeFirst()); + return; + } + + m_nTimerSec += 1; + if(m_nTimerSec > MAX_TIME) + { + QMessageBox::information(this, tr("提示"), tr("%1 定值读取超时").arg(m_strDevName), QMessageBox::Ok); + m_isReading = false; + return; + } +} + +void CConstCurves::initialize() +{ + QString strColorConfig; + QFile colorFile("://resource/color.cfg"); + if (colorFile.open(QIODevice::ReadOnly)) + { + QTextStream colorStream(&colorFile); + strColorConfig= colorStream.readAll(); + } + QStringList listColor = strColorConfig.split("\n"); + ui->m_curveWidget->setColorList(listColor); + + m_dbInterface = new CDbInterface(); + m_messageMng = new CMessageManage(this); + + connect(m_messageMng, SIGNAL(dataChanged(SReplyQueue)), this, SLOT(slotDataChanged(SReplyQueue))); + + if(!createSysInfoInstance(m_sysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + + SNodeInfo sNodeInfo; + m_sysInfo->getLocalNodeInfo(sNodeInfo); + m_nDomainID = sNodeInfo.nDomainId; + + initDevTree(); + m_isReading = false; + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(ontime())); + timer->start(1000); +} + +void CConstCurves::initView() +{ + ui->m_devTree->setColumnCount(1); + ui->m_devTree->header()->hide(); + connect(ui->m_devTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(slotDevItemChanged(QTreeWidgetItem*,int))); + + ui->m_constTree->setColumnCount(2); + ui->m_constTree->setColumnWidth(0, 500); + ui->m_constTree->setHeaderLabels(QStringList() << tr("名称") << tr("值")); + + ui->splitter->setStretchFactor(1,1); +} + +void CConstCurves::initDevTree() +{ + QMap locMap; + QList locList; + m_dbInterface->readLocationInfo(m_nDomainID, locMap, locList); + foreach (const int locId, locList) { + QMap device = m_dbInterface->readFesDevInfo(locId); + if(!device.size()) + { + continue; + } + + QTreeWidgetItem *item = new QTreeWidgetItem(LOCATION_TYPE); + item->setText(0, locMap.value(locId)); + QMap::const_iterator device_iter = device.constBegin(); + while(device_iter != device.constEnd()) + { + QList constList = m_dbInterface->queryFesConst(device_iter.key().section(",", 0, 0)); + if(constList.length() == 0) + { + ++device_iter; + continue; + } + + QTreeWidgetItem *devItem = new QTreeWidgetItem(DEV_TYPE); + devItem->setText(0, device_iter.value()); + devItem->setData(0, Qt::UserRole, device_iter.key()); + devItem->setData(0, Qt::CheckStateRole, Qt::Unchecked); + item->addChild(devItem); + ++device_iter; + } + ui->m_devTree->addTopLevelItem(item); + } + ui->m_devTree->expandAll(); +} + +void CConstCurves::devItemChanged(QTreeWidgetItem *item) +{ + if(item->data(0, Qt::CheckStateRole) == Qt::Checked) + { + QList constList = m_dbInterface->queryFesConst(item->data(0, Qt::UserRole).toString().section(",", 0, 0)); + if(constList.length() == 0) + { + return; + } + QTreeWidgetItem *devItem = new QTreeWidgetItem(DEV_TYPE); + devItem->setText(0, item->text(0)); + devItem->setData(0, Qt::UserRole, item->data(0, Qt::UserRole).toString()); //devTag,devID + for(int i=0; isetData(0, Qt::UserRole+1, constList.at(i).tag_name); + devItem->setData(0, Qt::UserRole+2, constList.at(i).rtu_tag); + } + if(constList.at(i).value_type != 1) + { + continue; + } + if(devItem->data(0, Qt::UserRole+1).toString() == QString()) + { + devItem->setData(0, Qt::UserRole+1, constList.at(i).tag_name); + devItem->setData(0, Qt::UserRole+2, constList.at(i).rtu_tag); + } + QTreeWidgetItem *tagItem = new QTreeWidgetItem(TAG_TYPE); + tagItem->setText(0, constList.at(i).description); + tagItem->setData(0, Qt::UserRole, constList.at(i).seq_no); + tagItem->setData(1, Qt::UserRole, QString("%1,%2").arg(constList.at(i).value_ratio).arg(constList.at(i).value_added)); + devItem->addChild(tagItem); + } + ui->m_constTree->addTopLevelItem(devItem); + ui->m_constTree->expandItem(devItem); + } + else if(item->data(0, Qt::CheckStateRole) == Qt::Unchecked) + { + int topCount = ui->m_constTree->topLevelItemCount(); + for(int i=0; im_constTree->topLevelItem(i)->data(0, Qt::UserRole).toString() == item->data(0, Qt::UserRole).toString()) + { + ui->m_constTree->takeTopLevelItem(i); + return; + } + } + } +} + +void CConstCurves::updateValue(QTreeWidgetItem* item, QList dotList, QList valueList) +{ + for(int nIndex=0; nIndexchildCount(); ++nIndex) + { + QTreeWidgetItem *tagItem = item->child(nIndex); + for(int dIndex=0; dIndexdata(0, Qt::UserRole).toInt() == dotList.at(dIndex)) + { + double ratio = tagItem->data(1, Qt::UserRole).toString().section(",", 0, 0).toDouble(); + double added = tagItem->data(1, Qt::UserRole).toString().section(",", 1, 1).toDouble(); + QString display = QString::number(valueList.at(dIndex) * ratio + added); + tagItem->setText(1, display); + break; + } + } + } +} + +void CConstCurves::insertCurve(QTreeWidgetItem *item) +{ + QList pointList; + int nCount = item->childCount(); + for(int nIndex=0; nIndexchild(nIndex++)->text(1).toDouble()); + point.setX(item->child(nIndex)->text(1).toDouble()); + pointList.append(point); + } + + ui->m_curveWidget->insertLineSeries(pointList, m_strDevName); +} + +void CConstCurves::sendMessage(const SReadQueue& sReadQueue) +{ + if(!m_messageMng->sendMessage(sReadQueue, m_nDomainID)) + { + QMessageBox::information(this, tr("提示"), tr("%1 下发定值读取命令失败").arg(sReadQueue.dev_name), QMessageBox::Ok); + return; + } + + m_nTimerSec = 0; + m_strDevName = sReadQueue.dev_name; + m_isReading = true; +} + + diff --git a/product/src/gui/plugin/ConstCurves/CConstCurves.h b/product/src/gui/plugin/ConstCurves/CConstCurves.h index 3ecf8541..ee7a1eb0 100644 --- a/product/src/gui/plugin/ConstCurves/CConstCurves.h +++ b/product/src/gui/plugin/ConstCurves/CConstCurves.h @@ -1,57 +1,57 @@ -#ifndef CCONSTCURVES_H -#define CCONSTCURVES_H - -#include -#include -#include "CDbInterface.h" -#include "CCurveChartView.h" -#include "CMessageManage.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" - -namespace Ui { -class CConstCurves; -} - -enum NodeType -{ - LOCATION_TYPE = 10000, - DEV_TYPE, - TAG_TYPE -}; - -class CConstCurves : public QWidget -{ - Q_OBJECT - -public: - explicit CConstCurves(bool editMode, QVector ptrVec, QWidget *parent = 0); - ~CConstCurves(); - -private slots: - void slotDevItemChanged(QTreeWidgetItem *item, int column); - void slotDataChanged(const SReplyQueue& reply); - void on_m_readBtn_clicked(); - void ontime(); - -private: - void initialize(); - void initView(); - void initDevTree(); - void devItemChanged(QTreeWidgetItem *item); - void updateValue(QTreeWidgetItem *item, QList dotList, QList valueList); - void insertCurve(QTreeWidgetItem *item); - void sendMessage(const SReadQueue &sReadQueue); - -private: - Ui::CConstCurves *ui; - CSysInfoInterfacePtr m_sysInfo; - CDbInterface *m_dbInterface; - CMessageManage *m_messageMng; - QList m_queueList; - int m_nDomainID; - bool m_isReading; - int m_nTimerSec; - QString m_strDevName; -}; - -#endif // CCONSTCURVES_H +#ifndef CCONSTCURVES_H +#define CCONSTCURVES_H + +#include +#include +#include "CDbInterface.h" +#include "CCurveChartView.h" +#include "CMessageManage.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" + +namespace Ui { +class CConstCurves; +} + +enum NodeType +{ + LOCATION_TYPE = 10000, + DEV_TYPE, + TAG_TYPE +}; + +class CConstCurves : public QWidget +{ + Q_OBJECT + +public: + explicit CConstCurves(bool editMode, QVector ptrVec, QWidget *parent = 0); + ~CConstCurves(); + +private slots: + void slotDevItemChanged(QTreeWidgetItem *item, int column); + void slotDataChanged(const SReplyQueue& reply); + void on_m_readBtn_clicked(); + void ontime(); + +private: + void initialize(); + void initView(); + void initDevTree(); + void devItemChanged(QTreeWidgetItem *item); + void updateValue(QTreeWidgetItem *item, QList dotList, QList valueList); + void insertCurve(QTreeWidgetItem *item); + void sendMessage(const SReadQueue &sReadQueue); + +private: + Ui::CConstCurves *ui; + CSysInfoInterfacePtr m_sysInfo; + CDbInterface *m_dbInterface; + CMessageManage *m_messageMng; + QList m_queueList; + int m_nDomainID; + bool m_isReading; + int m_nTimerSec; + QString m_strDevName; +}; + +#endif // CCONSTCURVES_H diff --git a/product/src/gui/plugin/ConstCurves/CConstCurves.ui b/product/src/gui/plugin/ConstCurves/CConstCurves.ui index 5b1673fb..a8749b0c 100644 --- a/product/src/gui/plugin/ConstCurves/CConstCurves.ui +++ b/product/src/gui/plugin/ConstCurves/CConstCurves.ui @@ -1,127 +1,127 @@ - - - CConstCurves - - - - 0 - 0 - 787 - 535 - - - - CConstCurves - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - 3 - - - - - 1 - - - - - - - 2 - - - - - - - - 3 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 80 - 16777215 - - - - 查询 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 1 - - - - - - - - - - - - - - CCurveChartView - QWidget -
CCurveChartView.h
- 1 -
-
- - -
+ + + CConstCurves + + + + 0 + 0 + 787 + 535 + + + + CConstCurves + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + 3 + + + + + 1 + + + + + + + 2 + + + + + + + + 3 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 80 + 16777215 + + + + 查询 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 1 + + + + + + + + + + + + + + CCurveChartView + QWidget +
CCurveChartView.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/ConstCurves/CConstPluginWidget.cpp b/product/src/gui/plugin/ConstCurves/CConstPluginWidget.cpp index fb176373..859c9d64 100644 --- a/product/src/gui/plugin/ConstCurves/CConstPluginWidget.cpp +++ b/product/src/gui/plugin/ConstCurves/CConstPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CConstPluginWidget.h" -#include "CConstCurves.h" -#include - -CConstPluginWidget::CConstPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CConstPluginWidget::~CConstPluginWidget() -{ - -} - -bool CConstPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CConstCurves *pWidget = new CConstCurves(editMode, ptrVec, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CConstPluginWidget::release() -{ - -} +#include "CConstPluginWidget.h" +#include "CConstCurves.h" +#include + +CConstPluginWidget::CConstPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CConstPluginWidget::~CConstPluginWidget() +{ + +} + +bool CConstPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CConstCurves *pWidget = new CConstCurves(editMode, ptrVec, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CConstPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ConstCurves/CConstPluginWidget.h b/product/src/gui/plugin/ConstCurves/CConstPluginWidget.h index d4e5694e..9bd3267c 100644 --- a/product/src/gui/plugin/ConstCurves/CConstPluginWidget.h +++ b/product/src/gui/plugin/ConstCurves/CConstPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CCONSTPLUGINWIDGET_H -#define CCONSTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CConstPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CConstPluginWidget(QObject *parent = 0); - ~CConstPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CCONSTPLUGINWIDGET_H +#ifndef CCONSTPLUGINWIDGET_H +#define CCONSTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CConstPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CConstPluginWidget(QObject *parent = 0); + ~CConstPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CCONSTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/ConstCurves/CCurveChartView.cpp b/product/src/gui/plugin/ConstCurves/CCurveChartView.cpp index b819d04e..f2ccdadc 100644 --- a/product/src/gui/plugin/ConstCurves/CCurveChartView.cpp +++ b/product/src/gui/plugin/ConstCurves/CCurveChartView.cpp @@ -1,182 +1,182 @@ -#include "CCurveChartView.h" -#include - -CCurveChartView::CCurveChartView(QWidget *parent) - : QChartView(parent) -{ - initialize(); -} - -void CCurveChartView::initialize() -{ - m_pChart = new QChart(); - m_pChart->legend()->setVisible(true); - m_pChart->legend()->setAlignment(Qt::AlignTop); - m_pChart->setMargins(QMargins(0,0,0,0)); - m_pChart->setBackgroundRoundness(0); - - //< X Axis - m_axisX = new QValueAxis(); - m_axisX->setTickCount(11); - m_axisX->setGridLineVisible(true); - m_pChart->addAxis(m_axisX, Qt::AlignBottom); - setAxisXRange(0,1); - - //< Y Axis - m_axisY = new QValueAxis(); - m_axisY->setTickCount(5); - m_axisY->setGridLineVisible(true); - m_pChart->addAxis(m_axisY, Qt::AlignLeft); - setAxisYRange(0,1); - - setRenderHint(QPainter::Antialiasing); - setChart(m_pChart); - setStyleSheet("background-color:transparent"); - m_leftBottom.setX(0); - m_leftBottom.setY(1); - m_rightTop.setX(0); - m_rightTop.setY(1); -} - -void CCurveChartView::setAxisXRange(double min, double max) -{ - m_axisX->setRange(min, max); -} - -void CCurveChartView::setAxisYRange(double min, double max) -{ - m_axisY->setRange(min, max); -} - -void CCurveChartView::insertLineSeries(const QList &listPoint, const QString& name) -{ - QLineSeries *lineSeries = new QLineSeries(); - lineSeries->setName(name); - m_pChart->addSeries(lineSeries); - lineSeries->replace(listPoint); - lineSeries->attachAxis(m_axisX); - lineSeries->attachAxis(m_axisY); - - int cSize = m_pChart->series().size() % 16; - lineSeries->setColor(m_listColor.at(cSize)); - - updateAxisRange(listPoint); -} - -void CCurveChartView::clearSeries() -{ - QList seriesList = m_pChart->series(); - QList::const_iterator iter = seriesList.constBegin(); - while(iter != seriesList.constEnd()) - { - delete *iter; - ++iter; - } - m_leftBottom.setX(0); - m_leftBottom.setY(1); - m_rightTop.setX(0); - m_rightTop.setY(1); - setAxisXRange(0,1); - setAxisYRange(0,1); -} - -void CCurveChartView::setColorList(const QStringList &listColor) -{ - foreach (QString c, listColor) - { - c.replace("\r", ""); - m_listColor.append(QColor(c)); - } -} - -QColor CCurveChartView::plotBackgroundColor() -{ - return m_backGroundColor; -} - -void CCurveChartView::setPlotBackgroundColor(const QColor &color) -{ - m_backGroundColor = color; - - m_pChart->setBackgroundBrush(color); -} - -QColor CCurveChartView::plotTickColor() -{ - return m_tickColor; -} - -void CCurveChartView::setPlotTickColor(const QColor &color) -{ - m_tickColor = color; - - m_pChart->axisX()->setLabelsColor(color); - m_pChart->axisY()->setLabelsColor(color); -} - -QColor CCurveChartView::plotGridColor() -{ - return m_gridColor; -} - -void CCurveChartView::setPlotGridColor(const QColor &color) -{ - m_gridColor = color; - - m_pChart->axisX()->setGridLineColor(color); - m_pChart->axisY()->setGridLineColor(color); -} - -QColor CCurveChartView::plotLinePen() -{ - return m_linePen; -} - -void CCurveChartView::setPlotLinePen(const QColor &color) -{ - m_pChart->axisX()->setLinePen(color); - m_pChart->axisY()->setLinePen(color); -} - -QColor CCurveChartView::plotLegendColor() -{ - return m_legendColor; -} - -void CCurveChartView::setPlotLegendColor(const QColor &color) -{ - m_pChart->legend()->setLabelBrush(color); -} - -void CCurveChartView::updateAxisRange(const QList& listPoint) -{ - if(m_pChart->series().size() == 1) - { - m_leftBottom.setX(listPoint.at(0).x()); - m_leftBottom.setY(listPoint.at(0).y()); - m_rightTop.setX(listPoint.at(0).x()); - m_rightTop.setY(listPoint.at(0).y()); - } - - foreach (QPointF point, listPoint) { - if(point.x() < m_leftBottom.x()) - { - m_leftBottom.setX(point.x()); - } - else if(point.x() > m_rightTop.x()) - { - m_rightTop.setX(point.x()); - } - if(point.y() < m_leftBottom.y()) - { - m_leftBottom.setY(point.y()); - } - else if(point.y() > m_rightTop.y()) - { - m_rightTop.setY(point.y()); - } - } - m_axisX->setRange(m_leftBottom.x() - (m_rightTop.x()-m_leftBottom.x())/10., m_rightTop.x() + (m_rightTop.x()-m_leftBottom.x())/11.); - m_axisY->setRange(m_leftBottom.y(), m_rightTop.y() + (m_rightTop.y()-m_leftBottom.y())/5.); -} - +#include "CCurveChartView.h" +#include + +CCurveChartView::CCurveChartView(QWidget *parent) + : QChartView(parent) +{ + initialize(); +} + +void CCurveChartView::initialize() +{ + m_pChart = new QChart(); + m_pChart->legend()->setVisible(true); + m_pChart->legend()->setAlignment(Qt::AlignTop); + m_pChart->setMargins(QMargins(0,0,0,0)); + m_pChart->setBackgroundRoundness(0); + + //< X Axis + m_axisX = new QValueAxis(); + m_axisX->setTickCount(11); + m_axisX->setGridLineVisible(true); + m_pChart->addAxis(m_axisX, Qt::AlignBottom); + setAxisXRange(0,1); + + //< Y Axis + m_axisY = new QValueAxis(); + m_axisY->setTickCount(5); + m_axisY->setGridLineVisible(true); + m_pChart->addAxis(m_axisY, Qt::AlignLeft); + setAxisYRange(0,1); + + setRenderHint(QPainter::Antialiasing); + setChart(m_pChart); + setStyleSheet("background-color:transparent"); + m_leftBottom.setX(0); + m_leftBottom.setY(1); + m_rightTop.setX(0); + m_rightTop.setY(1); +} + +void CCurveChartView::setAxisXRange(double min, double max) +{ + m_axisX->setRange(min, max); +} + +void CCurveChartView::setAxisYRange(double min, double max) +{ + m_axisY->setRange(min, max); +} + +void CCurveChartView::insertLineSeries(const QList &listPoint, const QString& name) +{ + QLineSeries *lineSeries = new QLineSeries(); + lineSeries->setName(name); + m_pChart->addSeries(lineSeries); + lineSeries->replace(listPoint); + lineSeries->attachAxis(m_axisX); + lineSeries->attachAxis(m_axisY); + + int cSize = m_pChart->series().size() % 16; + lineSeries->setColor(m_listColor.at(cSize)); + + updateAxisRange(listPoint); +} + +void CCurveChartView::clearSeries() +{ + QList seriesList = m_pChart->series(); + QList::const_iterator iter = seriesList.constBegin(); + while(iter != seriesList.constEnd()) + { + delete *iter; + ++iter; + } + m_leftBottom.setX(0); + m_leftBottom.setY(1); + m_rightTop.setX(0); + m_rightTop.setY(1); + setAxisXRange(0,1); + setAxisYRange(0,1); +} + +void CCurveChartView::setColorList(const QStringList &listColor) +{ + foreach (QString c, listColor) + { + c.replace("\r", ""); + m_listColor.append(QColor(c)); + } +} + +QColor CCurveChartView::plotBackgroundColor() +{ + return m_backGroundColor; +} + +void CCurveChartView::setPlotBackgroundColor(const QColor &color) +{ + m_backGroundColor = color; + + m_pChart->setBackgroundBrush(color); +} + +QColor CCurveChartView::plotTickColor() +{ + return m_tickColor; +} + +void CCurveChartView::setPlotTickColor(const QColor &color) +{ + m_tickColor = color; + + m_pChart->axisX()->setLabelsColor(color); + m_pChart->axisY()->setLabelsColor(color); +} + +QColor CCurveChartView::plotGridColor() +{ + return m_gridColor; +} + +void CCurveChartView::setPlotGridColor(const QColor &color) +{ + m_gridColor = color; + + m_pChart->axisX()->setGridLineColor(color); + m_pChart->axisY()->setGridLineColor(color); +} + +QColor CCurveChartView::plotLinePen() +{ + return m_linePen; +} + +void CCurveChartView::setPlotLinePen(const QColor &color) +{ + m_pChart->axisX()->setLinePen(color); + m_pChart->axisY()->setLinePen(color); +} + +QColor CCurveChartView::plotLegendColor() +{ + return m_legendColor; +} + +void CCurveChartView::setPlotLegendColor(const QColor &color) +{ + m_pChart->legend()->setLabelBrush(color); +} + +void CCurveChartView::updateAxisRange(const QList& listPoint) +{ + if(m_pChart->series().size() == 1) + { + m_leftBottom.setX(listPoint.at(0).x()); + m_leftBottom.setY(listPoint.at(0).y()); + m_rightTop.setX(listPoint.at(0).x()); + m_rightTop.setY(listPoint.at(0).y()); + } + + foreach (QPointF point, listPoint) { + if(point.x() < m_leftBottom.x()) + { + m_leftBottom.setX(point.x()); + } + else if(point.x() > m_rightTop.x()) + { + m_rightTop.setX(point.x()); + } + if(point.y() < m_leftBottom.y()) + { + m_leftBottom.setY(point.y()); + } + else if(point.y() > m_rightTop.y()) + { + m_rightTop.setY(point.y()); + } + } + m_axisX->setRange(m_leftBottom.x() - (m_rightTop.x()-m_leftBottom.x())/10., m_rightTop.x() + (m_rightTop.x()-m_leftBottom.x())/11.); + m_axisY->setRange(m_leftBottom.y(), m_rightTop.y() + (m_rightTop.y()-m_leftBottom.y())/5.); +} + diff --git a/product/src/gui/plugin/ConstCurves/CCurveChartView.h b/product/src/gui/plugin/ConstCurves/CCurveChartView.h index 90581a76..a6b69749 100644 --- a/product/src/gui/plugin/ConstCurves/CCurveChartView.h +++ b/product/src/gui/plugin/ConstCurves/CCurveChartView.h @@ -1,68 +1,68 @@ -#ifndef CURVECHARTVIEW_H -#define CURVECHARTVIEW_H - -#include -#include -#include -#include - -QT_CHARTS_USE_NAMESPACE - -class CCurveChartView : public QChartView -{ - Q_OBJECT - Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) - Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) - Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) - Q_PROPERTY(QColor plotLinePen READ plotLinePen WRITE setPlotLinePen) - Q_PROPERTY(QColor plotLegendColor READ plotLegendColor WRITE setPlotLegendColor) - -public: - explicit CCurveChartView(QWidget *parent = Q_NULLPTR); - - void initialize(); - - void setAxisXRange(double min, double max); - - void setAxisYRange(double min, double max); - - void insertLineSeries(const QList &listPoint, const QString &name); - - void clearSeries(); - - void setColorList(const QStringList &listColor); - - //< 样式 - QColor plotBackgroundColor(); - void setPlotBackgroundColor(const QColor &color); - - QColor plotTickColor(); - void setPlotTickColor(const QColor &color); - - QColor plotGridColor(); - void setPlotGridColor(const QColor &color); - - QColor plotLinePen(); - void setPlotLinePen(const QColor &color); - - QColor plotLegendColor(); - void setPlotLegendColor(const QColor &color); - -private: - void updateAxisRange(const QList &listPoint); - -private: - QChart * m_pChart; - QList m_listColor; - QValueAxis * m_axisX; - QValueAxis * m_axisY; - QColor m_backGroundColor; - QColor m_tickColor; - QColor m_gridColor; - QColor m_linePen; - QColor m_legendColor; - QPointF m_leftBottom; - QPointF m_rightTop; -}; - -#endif // CCURVECHARTVIEW_H +#ifndef CURVECHARTVIEW_H +#define CURVECHARTVIEW_H + +#include +#include +#include +#include + +QT_CHARTS_USE_NAMESPACE + +class CCurveChartView : public QChartView +{ + Q_OBJECT + Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) + Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) + Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) + Q_PROPERTY(QColor plotLinePen READ plotLinePen WRITE setPlotLinePen) + Q_PROPERTY(QColor plotLegendColor READ plotLegendColor WRITE setPlotLegendColor) + +public: + explicit CCurveChartView(QWidget *parent = Q_NULLPTR); + + void initialize(); + + void setAxisXRange(double min, double max); + + void setAxisYRange(double min, double max); + + void insertLineSeries(const QList &listPoint, const QString &name); + + void clearSeries(); + + void setColorList(const QStringList &listColor); + + //< 样式 + QColor plotBackgroundColor(); + void setPlotBackgroundColor(const QColor &color); + + QColor plotTickColor(); + void setPlotTickColor(const QColor &color); + + QColor plotGridColor(); + void setPlotGridColor(const QColor &color); + + QColor plotLinePen(); + void setPlotLinePen(const QColor &color); + + QColor plotLegendColor(); + void setPlotLegendColor(const QColor &color); + +private: + void updateAxisRange(const QList &listPoint); + +private: + QChart * m_pChart; + QList m_listColor; + QValueAxis * m_axisX; + QValueAxis * m_axisY; + QColor m_backGroundColor; + QColor m_tickColor; + QColor m_gridColor; + QColor m_linePen; + QColor m_legendColor; + QPointF m_leftBottom; + QPointF m_rightTop; +}; + +#endif // CCURVECHARTVIEW_H diff --git a/product/src/gui/plugin/ConstCurves/CDbInterface.cpp b/product/src/gui/plugin/ConstCurves/CDbInterface.cpp index 58cdb893..0c134832 100644 --- a/product/src/gui/plugin/ConstCurves/CDbInterface.cpp +++ b/product/src/gui/plugin/ConstCurves/CDbInterface.cpp @@ -1,117 +1,117 @@ -#include "CDbInterface.h" - -using namespace kbd_dbms; - -CDbInterface::CDbInterface() - : m_pReadDb(NULL) -{ - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - - readFesConst(); -} - -CDbInterface::~CDbInterface() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; -} - -void CDbInterface::readLocationInfo(int domainID, QMap &locMap, QList &locOrder) -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QSqlQuery query; - QString sqlQuery = QString("select location_id,description from sys_model_location_info where domain_id = %1 order by location_no").arg(domainID); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - locMap.insert(query.value(0).toInt(), query.value(1).toString()); - locOrder.push_back(query.value(0).toInt()); - } -} - -QMap CDbInterface::readFesDevInfo(int locationID) -{ - if(!m_pReadDb->isOpen()) - { - return QMap(); - } - QMap map; - QSqlQuery query; - QString sqlQuery = QString("select tag_name,dev_id,dev_desc from fes_dev_info where location_id=%1").arg(locationID); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tagName = query.value(0).toString(); - int devID = query.value(1).toInt(); - QString devDesc = query.value(2).toString(); - - map.insert(tagName+","+QString::number(devID), devDesc); - } - return map; -} - -QList CDbInterface::queryFesConst(const QString &devTag) -{ - return m_fesConstMap.values(devTag); -} - -QString CDbInterface::queryDevTag(int devID, const QString& rtuTag) -{ - if(!m_pReadDb->isOpen()) - { - return QString(); - } - QString devTag; - QSqlQuery query; - QString sqlQuery = QString("select tag_name from fes_dev_info where dev_id = %1 and rtu_tag='%2'").arg(devID).arg(rtuTag); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - devTag = query.value(0).toString(); - } - return devTag; -} - -void CDbInterface::readFesConst() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - m_fesConstMap.clear(); - QSqlQuery query; - QString sqlQuery = QString("select tag_name,description,rtu_tag,dev_tag,seq_no,value_ratio,value_added,value_max,value_min,value_type from fes_const order by seq_no desc"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - SFesConst fesConst; - fesConst.tag_name = query.value(0).toString(); - fesConst.description = query.value(1).toString(); - fesConst.rtu_tag = query.value(2).toString(); - fesConst.dev_tag = query.value(3).toString(); - fesConst.seq_no = query.value(4).toInt(); - fesConst.value_ratio = query.value(5).toDouble(); - fesConst.value_added = query.value(6).toDouble(); - fesConst.value_max = query.value(7).toInt(); - fesConst.value_min = query.value(8).toInt(); - fesConst.value_type = query.value(9).toInt(); - - m_fesConstMap.insert(query.value(3).toString(), fesConst); - } -} +#include "CDbInterface.h" + +using namespace kbd_dbms; + +CDbInterface::CDbInterface() + : m_pReadDb(NULL) +{ + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + readFesConst(); +} + +CDbInterface::~CDbInterface() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; +} + +void CDbInterface::readLocationInfo(int domainID, QMap &locMap, QList &locOrder) +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QSqlQuery query; + QString sqlQuery = QString("select location_id,description from sys_model_location_info where domain_id = %1 order by location_no").arg(domainID); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + locMap.insert(query.value(0).toInt(), query.value(1).toString()); + locOrder.push_back(query.value(0).toInt()); + } +} + +QMap CDbInterface::readFesDevInfo(int locationID) +{ + if(!m_pReadDb->isOpen()) + { + return QMap(); + } + QMap map; + QSqlQuery query; + QString sqlQuery = QString("select tag_name,dev_id,dev_desc from fes_dev_info where location_id=%1").arg(locationID); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tagName = query.value(0).toString(); + int devID = query.value(1).toInt(); + QString devDesc = query.value(2).toString(); + + map.insert(tagName+","+QString::number(devID), devDesc); + } + return map; +} + +QList CDbInterface::queryFesConst(const QString &devTag) +{ + return m_fesConstMap.values(devTag); +} + +QString CDbInterface::queryDevTag(int devID, const QString& rtuTag) +{ + if(!m_pReadDb->isOpen()) + { + return QString(); + } + QString devTag; + QSqlQuery query; + QString sqlQuery = QString("select tag_name from fes_dev_info where dev_id = %1 and rtu_tag='%2'").arg(devID).arg(rtuTag); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + devTag = query.value(0).toString(); + } + return devTag; +} + +void CDbInterface::readFesConst() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_fesConstMap.clear(); + QSqlQuery query; + QString sqlQuery = QString("select tag_name,description,rtu_tag,dev_tag,seq_no,value_ratio,value_added,value_max,value_min,value_type from fes_const order by seq_no desc"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + SFesConst fesConst; + fesConst.tag_name = query.value(0).toString(); + fesConst.description = query.value(1).toString(); + fesConst.rtu_tag = query.value(2).toString(); + fesConst.dev_tag = query.value(3).toString(); + fesConst.seq_no = query.value(4).toInt(); + fesConst.value_ratio = query.value(5).toDouble(); + fesConst.value_added = query.value(6).toDouble(); + fesConst.value_max = query.value(7).toInt(); + fesConst.value_min = query.value(8).toInt(); + fesConst.value_type = query.value(9).toInt(); + + m_fesConstMap.insert(query.value(3).toString(), fesConst); + } +} diff --git a/product/src/gui/plugin/ConstCurves/CDbInterface.h b/product/src/gui/plugin/ConstCurves/CDbInterface.h index b6d9c182..6a3d2e4c 100644 --- a/product/src/gui/plugin/ConstCurves/CDbInterface.h +++ b/product/src/gui/plugin/ConstCurves/CDbInterface.h @@ -1,42 +1,42 @@ -#ifndef CDBDATAMANAGE_H -#define CDBDATAMANAGE_H - -#include -#include "dbms/db_api_ex/CDbApi.h" - -struct SFesConst -{ - QString tag_name; - QString description; - QString rtu_tag; - QString dev_tag; - int seq_no; - double value_ratio; - double value_added; - int value_max; - int value_min; - int value_type; -}; - -class CDbInterface -{ -public: - CDbInterface(); - ~CDbInterface(); - - void readLocationInfo(int domainID, QMap &locMap, QList &locOrder); //< locationID, locationDesc - QMap readFesDevInfo(int locationID); //< 'devTag,devID' devDesc - - QList queryFesConst(const QString& devTag); - QString queryDevTag(int devID, const QString &rtuTag); - -private: - void readFesConst(); - -private: - kbd_dbms::CDbApi * m_pReadDb; - QMultiMap m_fesConstMap; - -}; - -#endif // CDBDATAMANAGE_H +#ifndef CDBDATAMANAGE_H +#define CDBDATAMANAGE_H + +#include +#include "dbms/db_api_ex/CDbApi.h" + +struct SFesConst +{ + QString tag_name; + QString description; + QString rtu_tag; + QString dev_tag; + int seq_no; + double value_ratio; + double value_added; + int value_max; + int value_min; + int value_type; +}; + +class CDbInterface +{ +public: + CDbInterface(); + ~CDbInterface(); + + void readLocationInfo(int domainID, QMap &locMap, QList &locOrder); //< locationID, locationDesc + QMap readFesDevInfo(int locationID); //< 'devTag,devID' devDesc + + QList queryFesConst(const QString& devTag); + QString queryDevTag(int devID, const QString &rtuTag); + +private: + void readFesConst(); + +private: + kbd_dbms::CDbApi * m_pReadDb; + QMultiMap m_fesConstMap; + +}; + +#endif // CDBDATAMANAGE_H diff --git a/product/src/gui/plugin/ConstCurves/CMessageManage.cpp b/product/src/gui/plugin/ConstCurves/CMessageManage.cpp index 34ce9297..a5e2d83b 100644 --- a/product/src/gui/plugin/ConstCurves/CMessageManage.cpp +++ b/product/src/gui/plugin/ConstCurves/CMessageManage.cpp @@ -1,313 +1,313 @@ -#include "CMessageManage.h" -#include "pub_logger_api/logger.h" -#include -#include "CDbInterface.h" - -const int E_PSCADA_APPID = 4; -CMessageManage::CMessageManage(QObject *parent) - : QObject(parent) -{ - m_permMng = NULL; - m_sysInfo = NULL; - m_communicator = NULL; -// m_test = false; -// m_testNum = 50; - - init(); -} - -CMessageManage::~CMessageManage() -{ - if(m_timer) - { - m_timer->stop(); - delete m_timer; - } - m_timer = NULL; - - delSub(E_PSCADA_APPID, CH_OPT_TO_HMI_OPTCMD_UP); - closeMsg(); -} - -bool CMessageManage::sendMessage(const SReadQueue& queueList, int nDstDomainId) -{ - kbd_net::CMbMessage msg; - msg.setMsgType(MT_OPT_COMMON_DOWN); - msg.setSubject(E_PSCADA_APPID, CH_HMI_TO_OPT_OPTCMD_DOWN); - COptCustCtrlRequest cOptCustCtrlRequest; - SOptCustCtrlRequest sOptCustCtrlRequest; - sOptCustCtrlRequest.stHead = createReqHead(nDstDomainId); - sOptCustCtrlRequest.strKeyIdTag = QString("fes_const.%1.value").arg(queueList.tag_name).toStdString(); - sOptCustCtrlRequest.strRtuTag = queueList.rtu_tag.toStdString(); - sOptCustCtrlRequest.vecOptCustCtrlQueue = createCtrlQueue(queueList.dev_id); - - std::string content = cOptCustCtrlRequest.generate(sOptCustCtrlRequest); - msg.setData(content); - - if(!m_communicator->sendMsgToDomain(msg, nDstDomainId)) - { - return false; - } - - m_curRtu = sOptCustCtrlRequest.strRtuTag; - m_strHostName = sOptCustCtrlRequest.stHead.strHostName; - m_strInstName = sOptCustCtrlRequest.stHead.strInstName; - m_nOptTime = sOptCustCtrlRequest.stHead.nOptTime; - -// m_test = true; -// m_testDevId = queueList.dev_id; -// m_testRtuTag = queueList.rtu_tag; - return true; -} - -void CMessageManage::recvMessage() -{ -// test(); - kbd_net::CMbMessage msg; - if(m_communicator->recvMsg(msg, 50)) - { - if(msg.getMsgType() != MT_OPT_COMMON_UP) - { - return; - } - - COptCustCtrlReply cOptCustCtrlReply; - SOptCustCtrlReply sOptCustCtrlReply; - std::string str((const char*)msg.getDataPtr(), msg.getDataSize()); - cOptCustCtrlReply.parse(str, sOptCustCtrlReply); - - parseMsg(sOptCustCtrlReply); - } -} - -void CMessageManage::init() -{ - if(!createSysInfoInstance(m_sysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - } - - m_permMng = getPermMngInstance("base"); - if(m_permMng != NULL) - { - if(m_permMng->PermDllInit() != PERM_NORMAL) - { - LOGERROR("权限接口初始化失败!"); - } - } - - initMsg(); - if(!addSub(E_PSCADA_APPID, CH_OPT_TO_HMI_OPTCMD_UP)) - { - return; - } - - m_timer = new QTimer(this); - connect(m_timer, SIGNAL(timeout()), this, SLOT(recvMessage())); - m_timer->start(500); -} - -void CMessageManage::initMsg() -{ - if(m_communicator == NULL) - { - m_communicator = new kbd_net::CMbCommunicator(); - } -} - -void CMessageManage::closeMsg() -{ - if(m_communicator != NULL) - { - delete m_communicator; - } - m_communicator = NULL; -} - -bool CMessageManage::addSub(int appID, int channel) -{ - if(m_communicator) - { - return m_communicator->addSub(appID, channel); - } - else - { - return false; - } -} - -bool CMessageManage::delSub(int appID, int channel) -{ - if(m_communicator) - { - return m_communicator->delSub(appID, channel); - } - else - { - return false; - } -} - -SOptReqHead CMessageManage::createReqHead(int nDstDomainId) -{ - SOptReqHead head; - SNodeInfo nodeInfo; - int userID; - int usergID; - int level; - int loginSec; - std::string instanceName; - - m_sysInfo->getLocalNodeInfo(nodeInfo); - if(m_permMng) - { - m_permMng->CurUser(userID, usergID, level, loginSec, instanceName); - } - - head.strSrcTag = "hmi"; - head.nSrcDomainID = nodeInfo.nDomainId; - head.nDstDomainID = nDstDomainId; - head.nAppID = E_PSCADA_APPID; - head.strHostName = nodeInfo.strName; - head.strInstName = instanceName; - head.strCommName = m_communicator->getName(); - head.nUserID = userID; - head.nUserGroupID = usergID; - head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - - return head; -} - -std::vector CMessageManage::createCtrlQueue(int devID) -{ - std::vector queueVec; - SOptCustCtrlQueue typeQueue; - typeQueue.strKeyName = "cmd_type"; - typeQueue.strKeyValue = "const_value_read"; - SOptCustCtrlQueue devQueue; - devQueue.strKeyName = "dev_id"; - devQueue.strKeyValue = QString::number(devID).toStdString(); - queueVec.push_back(typeQueue); - queueVec.push_back(devQueue); - return queueVec; -} - -void CMessageManage::parseMsg(const SOptCustCtrlReply& sOptCustCtrlReply) -{ - if(!checkMsg(sOptCustCtrlReply.stHead.strHostName, sOptCustCtrlReply.stHead.strInstName, sOptCustCtrlReply.stHead.nOptTime)) - { - return; - } - - SReplyQueue sReplyQueue; - sReplyQueue.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - sReplyQueue.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "cmd_type" - && iter->strKeyValue != "const_value_read") - { - break; - } - if(iter->strKeyName == "dev_id") - { - sReplyQueue.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - sReplyQueue.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - sReplyQueue.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - else if(iter->strKeyName == "cur_value") - { - sReplyQueue.valueList.append(QString::fromStdString(iter->strKeyValue).toDouble()); - } - ++iter; - } - sReplyQueue.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(sReplyQueue); -} - -bool CMessageManage::checkMsg(std::string strHostName, std::string strInstName, int nOptTime) -{ - if(m_strHostName != strHostName) - { - return false; - } - if(m_strInstName != strInstName) - { - return false; - } - if(m_nOptTime != nOptTime) - { - return false; - } - return true; -} - -void CMessageManage::test() -{ -// if(m_test) -// { -// CDbInterface interface; -// QString dev_tag = interface.queryDevTag(m_testDevId, m_testRtuTag); -// QList constList = interface.queryFesConst(dev_tag); -// SOptCustCtrlReply sOptCustCtrlReply; - -// SOptReplyHead sHead; -// sHead.strSrcTag = "hmi"; -// sHead.nDomainID = 1; -// sHead.nDstDomainID = 1; -// sHead.nAppID = E_PSCADA_APPID; -// sHead.strHostName = m_strHostName; -// sHead.strInstName = m_strInstName; -// sHead.strKeyIdTag = ""; -// sHead.nIsSuccess = 1; -// sHead.strResultStr = "读取失败"; -// sHead.nOptTime = m_nOptTime; - -// std::vector queueVec; - -// SOptCustCtrlQueue queue; -// queue.strKeyName = "cmd_type"; -// queue.strKeyValue = "const_value_read"; -// queueVec.push_back(queue); - -// SOptCustCtrlQueue queue1; -// queue1.strKeyName = "dev_id"; -// queue1.strKeyValue = QString::number(m_testDevId).toStdString(); -// queueVec.push_back(queue1); - -// SOptCustCtrlQueue queue2; -// queue2.strKeyName = "cur_group"; -// queue2.strKeyValue = "1"; -// queueVec.push_back(queue2); - -// foreach (SFesConst fesConst, constList) { -// if(fesConst.value_type == 5) -// { -// continue; -// } -// SOptCustCtrlQueue que; -// que.strKeyName = "dot_no"; -// que.strKeyValue = QString::number(fesConst.seq_no).toStdString(); -// queueVec.push_back(que); - -// SOptCustCtrlQueue que1; -// que1.strKeyName = "cur_value"; -// que1.strKeyValue = QString::number(m_testNum).toStdString(); -// queueVec.push_back(que1); -// m_testNum+=10; -// } -// sOptCustCtrlReply.stHead = sHead; -// sOptCustCtrlReply.vecOptCustCtrlQueue = queueVec; - -// m_test = false; -// parseMsg(sOptCustCtrlReply); -// } -} - +#include "CMessageManage.h" +#include "pub_logger_api/logger.h" +#include +#include "CDbInterface.h" + +const int E_PSCADA_APPID = 4; +CMessageManage::CMessageManage(QObject *parent) + : QObject(parent) +{ + m_permMng = NULL; + m_sysInfo = NULL; + m_communicator = NULL; +// m_test = false; +// m_testNum = 50; + + init(); +} + +CMessageManage::~CMessageManage() +{ + if(m_timer) + { + m_timer->stop(); + delete m_timer; + } + m_timer = NULL; + + delSub(E_PSCADA_APPID, CH_OPT_TO_HMI_OPTCMD_UP); + closeMsg(); +} + +bool CMessageManage::sendMessage(const SReadQueue& queueList, int nDstDomainId) +{ + kbd_net::CMbMessage msg; + msg.setMsgType(MT_OPT_COMMON_DOWN); + msg.setSubject(E_PSCADA_APPID, CH_HMI_TO_OPT_OPTCMD_DOWN); + COptCustCtrlRequest cOptCustCtrlRequest; + SOptCustCtrlRequest sOptCustCtrlRequest; + sOptCustCtrlRequest.stHead = createReqHead(nDstDomainId); + sOptCustCtrlRequest.strKeyIdTag = QString("fes_const.%1.value").arg(queueList.tag_name).toStdString(); + sOptCustCtrlRequest.strRtuTag = queueList.rtu_tag.toStdString(); + sOptCustCtrlRequest.vecOptCustCtrlQueue = createCtrlQueue(queueList.dev_id); + + std::string content = cOptCustCtrlRequest.generate(sOptCustCtrlRequest); + msg.setData(content); + + if(!m_communicator->sendMsgToDomain(msg, nDstDomainId)) + { + return false; + } + + m_curRtu = sOptCustCtrlRequest.strRtuTag; + m_strHostName = sOptCustCtrlRequest.stHead.strHostName; + m_strInstName = sOptCustCtrlRequest.stHead.strInstName; + m_nOptTime = sOptCustCtrlRequest.stHead.nOptTime; + +// m_test = true; +// m_testDevId = queueList.dev_id; +// m_testRtuTag = queueList.rtu_tag; + return true; +} + +void CMessageManage::recvMessage() +{ +// test(); + kbd_net::CMbMessage msg; + if(m_communicator->recvMsg(msg, 50)) + { + if(msg.getMsgType() != MT_OPT_COMMON_UP) + { + return; + } + + COptCustCtrlReply cOptCustCtrlReply; + SOptCustCtrlReply sOptCustCtrlReply; + std::string str((const char*)msg.getDataPtr(), msg.getDataSize()); + cOptCustCtrlReply.parse(str, sOptCustCtrlReply); + + parseMsg(sOptCustCtrlReply); + } +} + +void CMessageManage::init() +{ + if(!createSysInfoInstance(m_sysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + + m_permMng = getPermMngInstance("base"); + if(m_permMng != NULL) + { + if(m_permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + } + } + + initMsg(); + if(!addSub(E_PSCADA_APPID, CH_OPT_TO_HMI_OPTCMD_UP)) + { + return; + } + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_timer->start(500); +} + +void CMessageManage::initMsg() +{ + if(m_communicator == NULL) + { + m_communicator = new kbd_net::CMbCommunicator(); + } +} + +void CMessageManage::closeMsg() +{ + if(m_communicator != NULL) + { + delete m_communicator; + } + m_communicator = NULL; +} + +bool CMessageManage::addSub(int appID, int channel) +{ + if(m_communicator) + { + return m_communicator->addSub(appID, channel); + } + else + { + return false; + } +} + +bool CMessageManage::delSub(int appID, int channel) +{ + if(m_communicator) + { + return m_communicator->delSub(appID, channel); + } + else + { + return false; + } +} + +SOptReqHead CMessageManage::createReqHead(int nDstDomainId) +{ + SOptReqHead head; + SNodeInfo nodeInfo; + int userID; + int usergID; + int level; + int loginSec; + std::string instanceName; + + m_sysInfo->getLocalNodeInfo(nodeInfo); + if(m_permMng) + { + m_permMng->CurUser(userID, usergID, level, loginSec, instanceName); + } + + head.strSrcTag = "hmi"; + head.nSrcDomainID = nodeInfo.nDomainId; + head.nDstDomainID = nDstDomainId; + head.nAppID = E_PSCADA_APPID; + head.strHostName = nodeInfo.strName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = userID; + head.nUserGroupID = usergID; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + return head; +} + +std::vector CMessageManage::createCtrlQueue(int devID) +{ + std::vector queueVec; + SOptCustCtrlQueue typeQueue; + typeQueue.strKeyName = "cmd_type"; + typeQueue.strKeyValue = "const_value_read"; + SOptCustCtrlQueue devQueue; + devQueue.strKeyName = "dev_id"; + devQueue.strKeyValue = QString::number(devID).toStdString(); + queueVec.push_back(typeQueue); + queueVec.push_back(devQueue); + return queueVec; +} + +void CMessageManage::parseMsg(const SOptCustCtrlReply& sOptCustCtrlReply) +{ + if(!checkMsg(sOptCustCtrlReply.stHead.strHostName, sOptCustCtrlReply.stHead.strInstName, sOptCustCtrlReply.stHead.nOptTime)) + { + return; + } + + SReplyQueue sReplyQueue; + sReplyQueue.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + sReplyQueue.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "cmd_type" + && iter->strKeyValue != "const_value_read") + { + break; + } + if(iter->strKeyName == "dev_id") + { + sReplyQueue.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + sReplyQueue.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + sReplyQueue.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + else if(iter->strKeyName == "cur_value") + { + sReplyQueue.valueList.append(QString::fromStdString(iter->strKeyValue).toDouble()); + } + ++iter; + } + sReplyQueue.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(sReplyQueue); +} + +bool CMessageManage::checkMsg(std::string strHostName, std::string strInstName, int nOptTime) +{ + if(m_strHostName != strHostName) + { + return false; + } + if(m_strInstName != strInstName) + { + return false; + } + if(m_nOptTime != nOptTime) + { + return false; + } + return true; +} + +void CMessageManage::test() +{ +// if(m_test) +// { +// CDbInterface interface; +// QString dev_tag = interface.queryDevTag(m_testDevId, m_testRtuTag); +// QList constList = interface.queryFesConst(dev_tag); +// SOptCustCtrlReply sOptCustCtrlReply; + +// SOptReplyHead sHead; +// sHead.strSrcTag = "hmi"; +// sHead.nDomainID = 1; +// sHead.nDstDomainID = 1; +// sHead.nAppID = E_PSCADA_APPID; +// sHead.strHostName = m_strHostName; +// sHead.strInstName = m_strInstName; +// sHead.strKeyIdTag = ""; +// sHead.nIsSuccess = 1; +// sHead.strResultStr = "读取失败"; +// sHead.nOptTime = m_nOptTime; + +// std::vector queueVec; + +// SOptCustCtrlQueue queue; +// queue.strKeyName = "cmd_type"; +// queue.strKeyValue = "const_value_read"; +// queueVec.push_back(queue); + +// SOptCustCtrlQueue queue1; +// queue1.strKeyName = "dev_id"; +// queue1.strKeyValue = QString::number(m_testDevId).toStdString(); +// queueVec.push_back(queue1); + +// SOptCustCtrlQueue queue2; +// queue2.strKeyName = "cur_group"; +// queue2.strKeyValue = "1"; +// queueVec.push_back(queue2); + +// foreach (SFesConst fesConst, constList) { +// if(fesConst.value_type == 5) +// { +// continue; +// } +// SOptCustCtrlQueue que; +// que.strKeyName = "dot_no"; +// que.strKeyValue = QString::number(fesConst.seq_no).toStdString(); +// queueVec.push_back(que); + +// SOptCustCtrlQueue que1; +// que1.strKeyName = "cur_value"; +// que1.strKeyValue = QString::number(m_testNum).toStdString(); +// queueVec.push_back(que1); +// m_testNum+=10; +// } +// sOptCustCtrlReply.stHead = sHead; +// sOptCustCtrlReply.vecOptCustCtrlQueue = queueVec; + +// m_test = false; +// parseMsg(sOptCustCtrlReply); +// } +} + diff --git a/product/src/gui/plugin/ConstCurves/CMessageManage.h b/product/src/gui/plugin/ConstCurves/CMessageManage.h index c5815160..bd99137a 100644 --- a/product/src/gui/plugin/ConstCurves/CMessageManage.h +++ b/product/src/gui/plugin/ConstCurves/CMessageManage.h @@ -1,79 +1,79 @@ -#ifndef CMESSAGEMANAGE_H -#define CMESSAGEMANAGE_H - -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" -#include "service/operate_server_api/JsonMessageStruct.h" -#include "service/operate_server_api/JsonOptCommand.h" -#include "common/MessageChannel.h" -#include -#include - -struct SReadQueue -{ - QString tag_name; - QString rtu_tag; - int dev_id; - QString dev_name; -}; - -struct SReplyQueue -{ - QString rtu_tag; - int isSuccess; - QString resultStr; - int dev_id; - int cur_group; - QList dotList; - QList valueList; -}; - -using namespace kbd_public; -using namespace kbd_service; -class CMessageManage : public QObject -{ - Q_OBJECT -public: - CMessageManage(QObject *parent = 0); - ~CMessageManage(); - - bool sendMessage(const SReadQueue &queueList, int nDstDomainId); - -signals: - void dataChanged(const SReplyQueue& reply); - -private slots: - void recvMessage(); - -private: - void init(); - void initMsg(); - void closeMsg(); - bool addSub(int appID, int channel); - bool delSub(int appID, int channel); - SOptReqHead createReqHead(int nDstDomainId); - std::vector createCtrlQueue(int devID); - void parseMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - bool checkMsg(std::string strHostName, std::string strInstName, int nOptTime); - - void test(); - -private: - kbd_net::CMbCommunicator *m_communicator; - CSysInfoInterfacePtr m_sysInfo; - CPermMngApiPtr m_permMng; - QTimer *m_timer; - std::string m_curRtu; - std::string m_strHostName; - std::string m_strInstName; - int m_nOptTime; - -// bool m_test; -// int m_testDevId; -// QString m_testRtuTag; -// int m_testNum; -}; - -#endif // CMESSAGEMANAGE_H +#ifndef CMESSAGEMANAGE_H +#define CMESSAGEMANAGE_H + +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "common/MessageChannel.h" +#include +#include + +struct SReadQueue +{ + QString tag_name; + QString rtu_tag; + int dev_id; + QString dev_name; +}; + +struct SReplyQueue +{ + QString rtu_tag; + int isSuccess; + QString resultStr; + int dev_id; + int cur_group; + QList dotList; + QList valueList; +}; + +using namespace kbd_public; +using namespace kbd_service; +class CMessageManage : public QObject +{ + Q_OBJECT +public: + CMessageManage(QObject *parent = 0); + ~CMessageManage(); + + bool sendMessage(const SReadQueue &queueList, int nDstDomainId); + +signals: + void dataChanged(const SReplyQueue& reply); + +private slots: + void recvMessage(); + +private: + void init(); + void initMsg(); + void closeMsg(); + bool addSub(int appID, int channel); + bool delSub(int appID, int channel); + SOptReqHead createReqHead(int nDstDomainId); + std::vector createCtrlQueue(int devID); + void parseMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + bool checkMsg(std::string strHostName, std::string strInstName, int nOptTime); + + void test(); + +private: + kbd_net::CMbCommunicator *m_communicator; + CSysInfoInterfacePtr m_sysInfo; + CPermMngApiPtr m_permMng; + QTimer *m_timer; + std::string m_curRtu; + std::string m_strHostName; + std::string m_strInstName; + int m_nOptTime; + +// bool m_test; +// int m_testDevId; +// QString m_testRtuTag; +// int m_testNum; +}; + +#endif // CMESSAGEMANAGE_H diff --git a/product/src/gui/plugin/ConstCurves/ConstCurves.pro b/product/src/gui/plugin/ConstCurves/ConstCurves.pro index cc4fa900..c5afd940 100644 --- a/product/src/gui/plugin/ConstCurves/ConstCurves.pro +++ b/product/src/gui/plugin/ConstCurves/ConstCurves.pro @@ -1,70 +1,70 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-10-14T17:31:40 -# -#------------------------------------------------- - -QT += core gui charts sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = ConstCurves -TEMPLATE = lib - -CONFIG += plugin -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CConstCurves.cpp \ - CCurveChartView.cpp \ - CDbInterface.cpp \ - CMessageManage.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - CConstPluginWidget.cpp -# main.cpp - -HEADERS += \ - CConstCurves.h \ - CCurveChartView.h \ - CDbInterface.h \ - CMessageManage.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - CConstPluginWidget.h - -FORMS += \ - CConstCurves.ui - -LIBS += -lprotobuf \ - -ldb_base_api \ - -ldb_api_ex \ - -lnet_msg_bus_api \ - -lpub_sysinfo_api \ - -lperm_mng_api \ - -llog4cplus \ - -lpub_logger_api \ - -ldp_chg_data_api \ - -lpub_utility_api - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -RESOURCES += \ - colorconfig.qrc +#------------------------------------------------- +# +# Project created by QtCreator 2019-10-14T17:31:40 +# +#------------------------------------------------- + +QT += core gui charts sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ConstCurves +TEMPLATE = lib + +CONFIG += plugin +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CConstCurves.cpp \ + CCurveChartView.cpp \ + CDbInterface.cpp \ + CMessageManage.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + CConstPluginWidget.cpp +# main.cpp + +HEADERS += \ + CConstCurves.h \ + CCurveChartView.h \ + CDbInterface.h \ + CMessageManage.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + CConstPluginWidget.h + +FORMS += \ + CConstCurves.ui + +LIBS += -lprotobuf \ + -ldb_base_api \ + -ldb_api_ex \ + -lnet_msg_bus_api \ + -lpub_sysinfo_api \ + -lperm_mng_api \ + -llog4cplus \ + -lpub_logger_api \ + -ldp_chg_data_api \ + -lpub_utility_api + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +RESOURCES += \ + colorconfig.qrc diff --git a/product/src/gui/plugin/ConstCurves/colorconfig.qrc b/product/src/gui/plugin/ConstCurves/colorconfig.qrc index 71723dc6..85edbbb1 100644 --- a/product/src/gui/plugin/ConstCurves/colorconfig.qrc +++ b/product/src/gui/plugin/ConstCurves/colorconfig.qrc @@ -1,5 +1,5 @@ - - - resource/color.cfg - - + + + resource/color.cfg + + diff --git a/product/src/gui/plugin/ConstCurves/main.cpp b/product/src/gui/plugin/ConstCurves/main.cpp index ad6b5f14..a01ad988 100644 --- a/product/src/gui/plugin/ConstCurves/main.cpp +++ b/product/src/gui/plugin/ConstCurves/main.cpp @@ -1,45 +1,45 @@ -#include "CConstCurves.h" -#include -#include "pub_logger_api/logger.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("1", "1", 3, 12*60*60, "hmi") != 0) - { - return -1; - } - - kbd_service::CDpcdaForApp::initGlobalThread(); - - { - LOGINFO("===========================ConstCurves==========================="); - QApplication app(argc, argv); - - QVector ptrVec; - CConstCurves w(false, ptrVec); - w.show(); - - app.exec(); - } - - kbd_service::CDpcdaForApp::releaseGlobalThread(); - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include "CConstCurves.h" +#include +#include "pub_logger_api/logger.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("1", "1", 3, 12*60*60, "hmi") != 0) + { + return -1; + } + + kbd_service::CDpcdaForApp::initGlobalThread(); + + { + LOGINFO("===========================ConstCurves==========================="); + QApplication app(argc, argv); + + QVector ptrVec; + CConstCurves w(false, ptrVec); + w.show(); + + app.exec(); + } + + kbd_service::CDpcdaForApp::releaseGlobalThread(); + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/ConstCurves/resource/color.cfg b/product/src/gui/plugin/ConstCurves/resource/color.cfg index e6e13a32..f5f10d54 100644 --- a/product/src/gui/plugin/ConstCurves/resource/color.cfg +++ b/product/src/gui/plugin/ConstCurves/resource/color.cfg @@ -1,16 +1,16 @@ -#EF3829 -#EFD752 -#6BA2D6 -#DEAECE -#EF968C -#18A28C -#8C3C39 -#63498C -#6B4531 -#EFDFDE -#BD6DA5 -#C6D729 -#103852 -#B5B2B5 -#CEAA9C +#EF3829 +#EFD752 +#6BA2D6 +#DEAECE +#EF968C +#18A28C +#8C3C39 +#63498C +#6B4531 +#EFDFDE +#BD6DA5 +#C6D729 +#103852 +#B5B2B5 +#CEAA9C #F7EFEF \ No newline at end of file diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptCommon.h b/product/src/gui/plugin/DataOptWidget/CDataOptCommon.h index 30974fa6..4932f87a 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptCommon.h +++ b/product/src/gui/plugin/DataOptWidget/CDataOptCommon.h @@ -1,69 +1,69 @@ -#ifndef CDATAOPTCOMMON_H -#define CDATAOPTCOMMON_H - -#include - -#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") - -enum enTreeColumn{ - COL_TAGNAME = 0, - COL_LOCATION, - COL_DEVICE, - COL_TYPE, - COL_OPTTIME, - COL_SUBSYSTEM, - COL_SETVALUE, - COL_STATETEXT, - COL_HOSTNAME, - COL_USERNAME, - COL_USERGROUP, - COL_KEYIDTAG, - COL_TABLE -}; - -enum enTreeNodeType{ - TYPE_DEVGROUP, - TYPE_POINT -}; - -struct STOptTagInfo -{ - QString keyIdTag; - int tagType; - qint64 optTime; - int locationId; - int subSystem; - double setValue; - QString stateText; - QString hostName; - QString userName; - QString userGroup; - - QString tagName; - QString devName; - QString table; -}; - -struct STTagInfo -{ - QString tagName; - QString desc; - QString devName; - QString devDesc; - QString devgName; - int region; - -}; - -struct STLocationInfo -{ - int id; - QString desc; - int domainId; - STLocationInfo(){ - id= -1; - domainId = -1; - } -}; - -#endif // CDATAOPTCOMMON_H +#ifndef CDATAOPTCOMMON_H +#define CDATAOPTCOMMON_H + +#include + +#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") + +enum enTreeColumn{ + COL_TAGNAME = 0, + COL_LOCATION, + COL_DEVICE, + COL_TYPE, + COL_OPTTIME, + COL_SUBSYSTEM, + COL_SETVALUE, + COL_STATETEXT, + COL_HOSTNAME, + COL_USERNAME, + COL_USERGROUP, + COL_KEYIDTAG, + COL_TABLE +}; + +enum enTreeNodeType{ + TYPE_DEVGROUP, + TYPE_POINT +}; + +struct STOptTagInfo +{ + QString keyIdTag; + int tagType; + qint64 optTime; + int locationId; + int subSystem; + double setValue; + QString stateText; + QString hostName; + QString userName; + QString userGroup; + + QString tagName; + QString devName; + QString table; +}; + +struct STTagInfo +{ + QString tagName; + QString desc; + QString devName; + QString devDesc; + QString devgName; + int region; + +}; + +struct STLocationInfo +{ + int id; + QString desc; + int domainId; + STLocationInfo(){ + id= -1; + domainId = -1; + } +}; + +#endif // CDATAOPTCOMMON_H diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.cpp b/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.cpp index f3082092..72c3f0c8 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.cpp +++ b/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.cpp @@ -1,32 +1,32 @@ -#include "CDataOptPluginWidget.h" -#include "CDataOptWidget.h" -CDataOptPluginWidget::CDataOptPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CDataOptPluginWidget::~CDataOptPluginWidget() -{ - -} - -bool CDataOptPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CDataOptWidget *pWidget = new CDataOptWidget(editMode, parent); - - if(ptrVec.size()>0) - { - pWidget->setTagType(3); - }else - { - pWidget->setTagType(0); - } - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CDataOptPluginWidget::release() -{ - -} +#include "CDataOptPluginWidget.h" +#include "CDataOptWidget.h" +CDataOptPluginWidget::CDataOptPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CDataOptPluginWidget::~CDataOptPluginWidget() +{ + +} + +bool CDataOptPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CDataOptWidget *pWidget = new CDataOptWidget(editMode, parent); + + if(ptrVec.size()>0) + { + pWidget->setTagType(3); + }else + { + pWidget->setTagType(0); + } + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CDataOptPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.h b/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.h index af8981cf..ff07c06a 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.h +++ b/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CDATAOPTPLUGINWIDGET_H -#define CDATAOPTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CDataOptPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CDataOptPluginWidget(QObject *parent = 0); - - ~CDataOptPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); - -}; - -#endif // CDATAOPTPLUGINWIDGET_H +#ifndef CDATAOPTPLUGINWIDGET_H +#define CDATAOPTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CDataOptPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CDataOptPluginWidget(QObject *parent = 0); + + ~CDataOptPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); + +}; + +#endif // CDATAOPTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptWidget.cpp b/product/src/gui/plugin/DataOptWidget/CDataOptWidget.cpp index 96c47c71..7a3f7efe 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptWidget.cpp +++ b/product/src/gui/plugin/DataOptWidget/CDataOptWidget.cpp @@ -1,778 +1,778 @@ -#include "CDataOptWidget.h" -#include "ui_CDataOptWidget.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include -#include -#include "Common.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" -#include "pub_sysinfo_api/SysInfoApi.h" -using namespace kbd_dbms; -using namespace kbd_public; -using namespace kbd_service; - -CDataOptWidget::CDataOptWidget(bool editMode, QWidget *parent) - : QWidget(parent), - ui(new Ui::CDataOptWidget), - m_pReadDb(Q_NULLPTR), - m_communicator(Q_NULLPTR), - m_pThread(Q_NULLPTR), - m_pWork(Q_NULLPTR), - m_editMode(editMode), - m_domainId(-1), - m_appId(-1) -{ - ui->setupUi(this); - - qRegisterMetaType >("QList"); - initStyleSheet(); - - if(!m_editMode) - { - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - - if(m_pThread == Q_NULLPTR) - { - m_pThread = new QThread(); - } - if(m_pWork == Q_NULLPTR) - { - m_pWork = new CDataOptWork(); - } - m_pWork->moveToThread(m_pThread); - connect(m_pThread,&QThread::finished,m_pWork,&QObject::deleteLater); - connect(this,&CDataOptWidget::sigSearch,m_pWork,&CDataOptWork::slotSearch,Qt::QueuedConnection); - connect(m_pWork,&CDataOptWork::sigShowMess,this,&CDataOptWidget::slotShowMess,Qt::QueuedConnection); - connect(m_pWork,&CDataOptWork::sigBrush,this,&CDataOptWidget::slotBrush,Qt::QueuedConnection); - connect(ui->pBrush,&QPushButton::clicked,this,&CDataOptWidget::search); - connect(ui->pCancelSetValue,&QPushButton::clicked,this,&CDataOptWidget::cancelSetValue); - initialize(); - m_pThread->start(); - search(); - } -} - -CDataOptWidget::~CDataOptWidget() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = Q_NULLPTR; - - if(m_pThread) - { - m_pThread->exit(); - m_pThread->wait(); - delete m_pThread; - } - m_pThread = Q_NULLPTR; - - delete ui; -} - -void CDataOptWidget::setTagType(int actual) -{ - if(m_editMode) - { - return ; - } - if(actual <= 0) - { - ui->cType->blockSignals(true); - ui->cType->clear(); - ui->cType->addItem(tr("全部"),-1); - QMap::iterator pos = m_typeMap.begin(); - while (pos != m_typeMap.end()) { - ui->cType->addItem(pos.value(),pos.key()); - pos++; - } - ui->cType->blockSignals(false); - }else - { - ui->cType->blockSignals(true); - ui->cType->clear(); - ui->cType->addItem(m_typeMap.value(actual),actual); - ui->cType->blockSignals(false); - - ui->label_2->setHidden(true); - ui->cType->setHidden(true); - ui->treeWidget->setColumnHidden(COL_TYPE,true); - ui->treeWidget->setColumnHidden(COL_SETVALUE,true); - } - search(); -} - -void CDataOptWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - -// strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; -// QFile qssfile2(QString::fromStdString(strFullPath)); -// qssfile2.open(QFile::ReadOnly); -// if (qssfile2.isOpen()) -// { -// qss += QLatin1String(qssfile2.readAll()); -// qssfile2.close(); -// } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CDataOptWidget::initialize() -{ - if(!createSysInfoInstance(m_pSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - } - initMsg(); - initData(); - initView(); - initConn(); -} - -void CDataOptWidget::initData() -{ - loadLoc(); - - loadSub(); - - loadDevG(); - - loadTagType();//dict_menu_info -} - -void CDataOptWidget::initView() -{ - ui->cLocation->blockSignals(true); - ui->cSub->blockSignals(true); - ui->cType->blockSignals(true); - ui->cLocation->clear(); - foreach (const int &locId, m_locOrder) { - ui->cLocation->addItem(m_locMap.value(locId).desc, locId); - } - - ui->cSub->clear(); - QMap::iterator itor = m_subMap.begin(); - while (itor != m_subMap.end()) { - ui->cSub->addItem(itor.value(),itor.key()); - itor++; - } - - ui->cType->clear(); - QMap::iterator pos = m_typeMap.begin(); - while (pos != m_typeMap.end()) { - ui->cType->addItem(pos.value(),pos.key()); - pos++; - } - ui->cLocation->blockSignals(false); - ui->cSub->blockSignals(false); - ui->cType->blockSignals(false); - - setDefaultWidth(); - setColumnHidden(COL_SUBSYSTEM,true); - setColumnHidden(COL_STATETEXT,true); - setColumnHidden(COL_USERGROUP,true); - setColumnHidden(COL_KEYIDTAG,true); - setColumnHidden(COL_TABLE,true); - ui->treeWidget->setSortingEnabled(true); - ui->treeWidget->sortByColumn(COL_OPTTIME, Qt::DescendingOrder); -} - -void CDataOptWidget::initConn() -{ - connect(ui->cLocation,&QComboBox::currentTextChanged,this,&CDataOptWidget::filter); - connect(ui->cSub,&QComboBox::currentTextChanged,this,&CDataOptWidget::filter); - connect(ui->cType,&QComboBox::currentTextChanged,this,&CDataOptWidget::filter); -} - -void CDataOptWidget::loadLoc() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION,DOMAIN_ID from sys_model_location_info order by LOCATION_NO"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - STLocationInfo loc; - loc.id = query.value(0).toInt(); - loc.desc = query.value(1).toString(); - loc.domainId = query.value(2).toInt(); - m_locMap.insert(loc.id, loc); - m_locOrder.push_back(loc.id); - } -} - -void CDataOptWidget::loadSub() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select SUB_SYSTEM_ID,DESCRIPTION from sys_model_sub_system_info where SUB_SYSTEM_ID > 3"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - int id = query.value(0).toInt(); - QString desc = query.value(1).toString(); - m_subMap.insert(id, desc); - } -} - -void CDataOptWidget::loadDevG() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - m_devgMap.insert(tag, desc); - } -} - -void CDataOptWidget::loadTagType() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select ACTUAL_VALUE,DISPLAY_VALUE from dict_menu_info where menu_name = '标签类型'"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - int actual = query.value(0).toInt(); - QString display = query.value(1).toString(); - m_typeMap.insert(actual, display); - } -} - -void CDataOptWidget::updateTree(const QList &dataList) -{ - ui->treeWidget->clear(); - ui->treeWidget->setSortingEnabled(false); - QList typeList = m_typeMap.keys(); - QMap devGroupMap; //< 设备组所在节点 - for(int index(0);indexgetTagInfoByPointTagName(dataList[index].tagName); - - //< 找到设备组所在树节点 - QTreeWidgetItem * parent = Q_NULLPTR; - QMap::iterator iter = devGroupMap.find(tagInfo.devgName); - if(iter == devGroupMap.end()) - { - QTreeWidgetItem * devgItem = new QTreeWidgetItem; - devgItem->setText(COL_TAGNAME, m_devgMap.value(tagInfo.devgName,tr("未知"))); - devgItem->setData(COL_TAGNAME, Qt::UserRole, tagInfo.devgName); - devgItem->setData(COL_TAGNAME, Qt::UserRole+1, TYPE_DEVGROUP); - devgItem->setText(COL_OPTTIME, QDateTime::fromMSecsSinceEpoch(dataList[index].optTime).toString("yyyy-MM-dd hh:mm:ss")); - devgItem->setData(COL_OPTTIME, Qt::UserRole, dataList[index].optTime); //< 用于排序 - ui->treeWidget->addTopLevelItem(devgItem); - devGroupMap.insert(tagInfo.devgName, devgItem); - parent = devgItem; - } - else - { - if(dataList[index].optTime > iter.value()->data(COL_OPTTIME, Qt::UserRole).toInt()) - { - iter.value()->setData(COL_OPTTIME, Qt::UserRole, dataList[index].optTime); - iter.value()->setText(COL_OPTTIME, QDateTime::fromMSecsSinceEpoch(dataList[index].optTime).toString("yyyy-MM-dd hh:mm:ss")); - } - parent = iter.value(); - } - - QTreeWidgetItem *item = new QTreeWidgetItem(parent); - item->setText(COL_TAGNAME, tagInfo.desc); - item->setData(COL_TAGNAME, Qt::UserRole, tagInfo.tagName); - item->setData(COL_TAGNAME, Qt::UserRole+1, TYPE_POINT); - - item->setText(COL_LOCATION, m_locMap.value(dataList[index].locationId).desc); - item->setData(COL_LOCATION, Qt::UserRole, dataList[index].locationId); - - item->setText(COL_DEVICE, tagInfo.devDesc); - item->setData(COL_DEVICE, Qt::UserRole, tagInfo.devName); - - item->setText(COL_TYPE, m_typeMap.value(dataList[index].tagType, tr("未知"))); - item->setData(COL_TYPE, Qt::UserRole, dataList[index].tagType); - - item->setText(COL_OPTTIME, QDateTime::fromMSecsSinceEpoch(dataList[index].optTime).toString("yyyy-MM-dd hh:mm:ss")); - item->setData(COL_OPTTIME, Qt::UserRole, dataList[index].optTime); - - item->setText(COL_SUBSYSTEM, m_subMap.value(dataList[index].subSystem,tr("未知"))); - item->setData(COL_SUBSYSTEM, Qt::UserRole, dataList[index].subSystem); - - item->setText(COL_SETVALUE, QString::number(dataList[index].setValue)); - item->setData(COL_SETVALUE, Qt::UserRole, dataList[index].setValue); - - item->setText(COL_STATETEXT, dataList[index].stateText); - item->setData(COL_STATETEXT, Qt::UserRole, dataList[index].stateText); - - item->setText(COL_HOSTNAME, dataList[index].hostName); - item->setData(COL_HOSTNAME, Qt::UserRole, dataList[index].hostName); - - item->setText(COL_USERNAME, dataList[index].userName); - item->setData(COL_USERNAME, Qt::UserRole, dataList[index].userName); - - item->setText(COL_USERGROUP, dataList[index].userGroup); - item->setData(COL_USERGROUP, Qt::UserRole, dataList[index].userGroup); - - item->setText(COL_KEYIDTAG, dataList[index].keyIdTag); - item->setData(COL_KEYIDTAG, Qt::UserRole, dataList[index].keyIdTag); - - item->setText(COL_TABLE, dataList[index].table); - item->setData(COL_TABLE, Qt::UserRole,dataList[index].table); - } - filter(""); - ui->treeWidget->setSortingEnabled(true); -} - -void CDataOptWidget::updateCount() -{ - int showRowCount = 0; - for(int nIndex(0); nIndex< ui->treeWidget->topLevelItemCount(); nIndex++) - { - QTreeWidgetItem *item = ui->treeWidget->topLevelItem(nIndex); - for(int nChildIndex(0); nChildIndexchildCount(); nChildIndex++) - { - if(!item->child(nChildIndex)->isHidden()) - { - showRowCount++; - } - } - } - ui->lCount->setNum(showRowCount); -} - -bool CDataOptWidget::permCheck(int location, int region) -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - QString mess; - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - int userId; - if(PERM_NORMAL != permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - userId = -1; - mess = QString(tr("获取当前登录用户失败!")); - slotShowMess(mess); - return false; - } - std::vector vecRegionOptId; - QList regList; - QList locList; - std::vector vecLocationOptId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) - { - - std::vector ::iterator region = vecRegionOptId.begin(); - while (region != vecRegionOptId.end()) - { - regList.append(*region++); - } - - std::vector ::iterator location = vecLocationOptId.begin(); - while (location != vecLocationOptId.end()) - { - locList.append(*location++); - } - } - if(locList.contains(location) && regList.contains(region)) - { - return true; - }else - { - mess = QString(tr("无操作权限!")); - slotShowMess(mess); - return false; - } - } - mess = QString(tr("初始化权限失败!")); - slotShowMess(mess); - return false; -} - -void CDataOptWidget::initMsg() -{ - if(m_communicator == Q_NULLPTR) - { - m_communicator = new kbd_net::CMbCommunicator(); - } -} - -int CDataOptWidget::createReqHead(SOptReqHead &head) -{ - SNodeInfo nodeInfo; - int userID = -1; - int usergID = -1; - int level; - int loginSec; - std::string instanceName; - - CSysInfoInterfacePtr sysInfo; - if(createSysInfoInstance(sysInfo) == false) - { - LOGERROR("创建系统信息访问库实例失败!"); - return kbdFailed; - } - else - { - sysInfo->getLocalNodeInfo(nodeInfo); - } - - CPermMngApiPtr permMng = getPermMngInstance("base"); - if(permMng != NULL) - { - if(permMng->PermDllInit() != PERM_NORMAL) - { - LOGERROR("权限接口初始化失败!"); - return kbdFailed; - }else - { - if(PERM_NORMAL != permMng->CurUser(userID, usergID, level, loginSec, instanceName)) - { - userID = -1; - return kbdFailed; - } - } - } - head.strSrcTag = "dataOptWidget"; - head.nSrcDomainID = nodeInfo.nDomainId; - head.nDstDomainID = m_domainId; - head.nAppID = m_appId; - head.strHostName = nodeInfo.strName; - head.strInstName = instanceName; - head.strCommName = m_communicator->getName(); - head.nUserID = userID; - head.nUserGroupID = usergID; - head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - - return kbdSuccess; -} - -void CDataOptWidget::filter(const QString &text) -{ - Q_UNUSED(text) - int nLocId = ui->cLocation->currentData().toInt(); - int nSubId = ui->cSub->currentData().toInt(); - int nTypeId = ui->cType->currentData().toInt(); - - for(int nTopIndex(0); nTopIndextreeWidget->topLevelItemCount(); nTopIndex++) - { - bool isAllHide = true; - QTreeWidgetItem * parent = ui->treeWidget->topLevelItem(nTopIndex); - for(int nChildIndex(0); nChildIndexchildCount(); nChildIndex++) - { - if(nLocId != parent->child(nChildIndex)->data(COL_LOCATION, Qt::UserRole).toInt()) - { - parent->child(nChildIndex)->setHidden(true); - } - else if(nSubId != parent->child(nChildIndex)->data(COL_SUBSYSTEM, Qt::UserRole).toInt()) - { - parent->child(nChildIndex)->setHidden(true); - } - else if(nTypeId != -1 && nTypeId != parent->child(nChildIndex)->data(COL_TYPE, Qt::UserRole).toInt()) - { - parent->child(nChildIndex)->setHidden(true); - } - else - { - parent->child(nChildIndex)->setHidden(false); - isAllHide = false; - } - } - if(isAllHide) - { - parent->setHidden(true); - } - else - { - parent->setHidden(false); - } - } - ui->treeWidget->expandAll(); - updateCount(); -} - -void CDataOptWidget::slotShowMess(const QString &mess) -{ - QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); -} - -void CDataOptWidget::slotBrush(const QList &optTagInfoList) -{ - updateTree(optTagInfoList); - updateCount(); -} - -void CDataOptWidget::setColumnHidden(int column, bool hide) -{ - ui->treeWidget->setColumnHidden(column, hide); -} - -void CDataOptWidget::setColumnWidth(int column, int width) -{ - ui->treeWidget->setColumnWidth(column,width); -} - -void CDataOptWidget::setRowHeight(int height) -{ - ui->treeWidget->header()->setDefaultSectionSize(height); -} - -void CDataOptWidget::setDefaultWidth() -{ - setColumnWidth(COL_TAGNAME,200); - setColumnWidth(COL_LOCATION,200); - setColumnWidth(COL_DEVICE,200); - setColumnWidth(COL_TYPE,150); - setColumnWidth(COL_OPTTIME,200); - setColumnWidth(COL_SETVALUE,100); - setColumnWidth(COL_HOSTNAME,150); - setColumnWidth(COL_USERNAME,150); -} - -void CDataOptWidget::cancelSetValue() -{ - QString mess = QString(tr("当前未选中任何项!")); - QList list = ui->treeWidget->selectedItems(); - if (list.size() <= 0) - { - slotShowMess(mess); - return; - } - - struct itemData - { - QString tagName; - QString tagDesc; - int tagType; - inline bool operator==(const itemData &other) const - { - if(tagName != other.tagName) - { - return false; - } - return tagType == other.tagType; - } - }; - - QList itemDataList = {}; - - QList::iterator iter= list.begin(); - for(; iter!=list.end(); ++iter) - { - QTreeWidgetItem *item = *iter; - int type = item->data(COL_TAGNAME, Qt::UserRole+1).toInt(); - if(type == TYPE_DEVGROUP) - { - for(int n=0; nchildCount(); n++) - { - if(item->child(n)->isHidden()) - { - continue; - } - itemData sItemData; - sItemData.tagName = item->child(n)->data(COL_TAGNAME, Qt::UserRole).toString(); - sItemData.tagDesc = item->child(n)->text(COL_TAGNAME); - sItemData.tagType = item->child(n)->data(COL_TYPE, Qt::UserRole).toInt(); - if(itemDataList.isEmpty()) - { - itemDataList.append(sItemData); - } - else if(std::find(itemDataList.begin(), itemDataList.end(), sItemData) == itemDataList.end()) - { - itemDataList.append(sItemData); - } - else - { - LOGINFO("取消置数: 重复[%s %d]", sItemData.tagName.toStdString().c_str(), sItemData.tagType); - } - } - } - else if(type == TYPE_POINT) - { - itemData sItemData; - sItemData.tagName = item->data(COL_TAGNAME, Qt::UserRole).toString(); - sItemData.tagDesc = item->text(COL_TAGNAME); - sItemData.tagType = item->data(COL_TYPE, Qt::UserRole).toInt(); - if(itemDataList.isEmpty()) - { - itemDataList.append(sItemData); - } - else if(std::find(itemDataList.begin(), itemDataList.end(), sItemData) == itemDataList.end()) - { - itemDataList.append(sItemData); - } - else - { - LOGINFO("取消置数: 重复[%s %d]", sItemData.tagName.toStdString().c_str(), sItemData.tagType); - } - } - else - { - LOGERROR("取消置数: 未知树节点类型[%d]", type); - } - } - - LOGINFO("取消置数: [%d]", itemDataList.length()); - for(int nIndex(0); nIndexgetOptTagInfoByTagAndType(tagName,tagType,info) !=kbdSuccess ) - { - slotShowMess(tr("获取标签操作信息有误,%1").arg(desc)); - return false; - } - STTagInfo tagInfo; - if(m_pWork->getTagInfoByTag(tagName,tagInfo) !=kbdSuccess ) - { - slotShowMess(tr("获取标签信息有误,%1").arg(desc)); - return false; - } - if(!permCheck(info.locationId,tagInfo.region)) - { - return false; - } - removeOptTagInfo(info); - - return true; -} - -void CDataOptWidget::removeOptTagInfo(const STOptTagInfo &info) -{ - kbd_net::CMbMessage msg; - msg.setMsgType(MT_OPT_COMMON_DOWN); - msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); - SOptTagSet sOptTagSet; - SOptTagQueue optTagQueue; - COptTagSet cOptTagSet; - - if(createReqHead(sOptTagSet.stHead)!= kbdSuccess) - { - return ; - } - optTagQueue.strKeyIdTag = info.keyIdTag.toStdString(); - optTagQueue.nIsSet = 0;// 0:取消;1:设置; - optTagQueue.fSetValue = info.setValue; - optTagQueue.strStateText = info.stateText.toStdString(); - optTagQueue.bIsPointQuery = 1; - optTagQueue.nLocationId = info.locationId; - optTagQueue.nSubSystem = info.subSystem; - - sOptTagSet.vecTagQueue.push_back(optTagQueue); - std::string content = cOptTagSet.generate(sOptTagSet); - int type = info.tagType; - if(type == 1) - { - msg.setMsgType(MT_OPT_TAG_VALUE_SET); - }else if(type == 2) - { - msg.setMsgType(MT_OPT_PINHIBIT_REF); - }else if(type == 3) - { - msg.setMsgType(MT_OPT_PINHIBIT_ALARM); - }else - { - msg.setMsgType(MT_OPT_PINHIBIT_CTRL); - } - msg.setData(content); - if(!m_communicator->sendMsgToDomain(msg, m_domainId)) - { - QString mess = QString(tr("下发取消命令失败")); - slotShowMess(mess); - }else - { - removeItemOptTagInfo(info); - m_pWork->removeOneOptTagInfo(info); - updateCount(); - } -} - -void CDataOptWidget::removeItemOptTagInfo(const STOptTagInfo &info) -{ - for(int nTopIndex(0); nTopIndextreeWidget->topLevelItemCount(); nTopIndex++) - { - QTreeWidgetItem * parent = ui->treeWidget->topLevelItem(nTopIndex); - for(int nChildIndex(0); nChildIndexchildCount(); nChildIndex++) - { - QString tagName = parent->child(nChildIndex)->data(COL_TAGNAME, Qt::UserRole).toString(); - int tagType = parent->child(nChildIndex)->data(COL_TYPE, Qt::UserRole).toInt(); - if(info.tagName == tagName && info.tagType == tagType) - { - parent->takeChild(nChildIndex--); - break; - } - } - if(parent->childCount() == 0) - { - ui->treeWidget->takeTopLevelItem(nTopIndex--); - } - } -} - -void CDataOptWidget::search() -{ - m_domainId = m_locMap.value(ui->cLocation->currentData().toInt()).domainId; - - if(m_pSysInfo != Q_NULLPTR) - { - SAppInfo stAppInfo; - m_pSysInfo->getAppInfoBySubsystemId(ui->cSub->currentData().toInt(),stAppInfo); - m_appId = stAppInfo.nId; - emit sigSearch(m_domainId,m_appId); - } -} - +#include "CDataOptWidget.h" +#include "ui_CDataOptWidget.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include +#include +#include "Common.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" +#include "pub_sysinfo_api/SysInfoApi.h" +using namespace kbd_dbms; +using namespace kbd_public; +using namespace kbd_service; + +CDataOptWidget::CDataOptWidget(bool editMode, QWidget *parent) + : QWidget(parent), + ui(new Ui::CDataOptWidget), + m_pReadDb(Q_NULLPTR), + m_communicator(Q_NULLPTR), + m_pThread(Q_NULLPTR), + m_pWork(Q_NULLPTR), + m_editMode(editMode), + m_domainId(-1), + m_appId(-1) +{ + ui->setupUi(this); + + qRegisterMetaType >("QList"); + initStyleSheet(); + + if(!m_editMode) + { + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + if(m_pThread == Q_NULLPTR) + { + m_pThread = new QThread(); + } + if(m_pWork == Q_NULLPTR) + { + m_pWork = new CDataOptWork(); + } + m_pWork->moveToThread(m_pThread); + connect(m_pThread,&QThread::finished,m_pWork,&QObject::deleteLater); + connect(this,&CDataOptWidget::sigSearch,m_pWork,&CDataOptWork::slotSearch,Qt::QueuedConnection); + connect(m_pWork,&CDataOptWork::sigShowMess,this,&CDataOptWidget::slotShowMess,Qt::QueuedConnection); + connect(m_pWork,&CDataOptWork::sigBrush,this,&CDataOptWidget::slotBrush,Qt::QueuedConnection); + connect(ui->pBrush,&QPushButton::clicked,this,&CDataOptWidget::search); + connect(ui->pCancelSetValue,&QPushButton::clicked,this,&CDataOptWidget::cancelSetValue); + initialize(); + m_pThread->start(); + search(); + } +} + +CDataOptWidget::~CDataOptWidget() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = Q_NULLPTR; + + if(m_pThread) + { + m_pThread->exit(); + m_pThread->wait(); + delete m_pThread; + } + m_pThread = Q_NULLPTR; + + delete ui; +} + +void CDataOptWidget::setTagType(int actual) +{ + if(m_editMode) + { + return ; + } + if(actual <= 0) + { + ui->cType->blockSignals(true); + ui->cType->clear(); + ui->cType->addItem(tr("全部"),-1); + QMap::iterator pos = m_typeMap.begin(); + while (pos != m_typeMap.end()) { + ui->cType->addItem(pos.value(),pos.key()); + pos++; + } + ui->cType->blockSignals(false); + }else + { + ui->cType->blockSignals(true); + ui->cType->clear(); + ui->cType->addItem(m_typeMap.value(actual),actual); + ui->cType->blockSignals(false); + + ui->label_2->setHidden(true); + ui->cType->setHidden(true); + ui->treeWidget->setColumnHidden(COL_TYPE,true); + ui->treeWidget->setColumnHidden(COL_SETVALUE,true); + } + search(); +} + +void CDataOptWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + +// strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; +// QFile qssfile2(QString::fromStdString(strFullPath)); +// qssfile2.open(QFile::ReadOnly); +// if (qssfile2.isOpen()) +// { +// qss += QLatin1String(qssfile2.readAll()); +// qssfile2.close(); +// } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CDataOptWidget::initialize() +{ + if(!createSysInfoInstance(m_pSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + initMsg(); + initData(); + initView(); + initConn(); +} + +void CDataOptWidget::initData() +{ + loadLoc(); + + loadSub(); + + loadDevG(); + + loadTagType();//dict_menu_info +} + +void CDataOptWidget::initView() +{ + ui->cLocation->blockSignals(true); + ui->cSub->blockSignals(true); + ui->cType->blockSignals(true); + ui->cLocation->clear(); + foreach (const int &locId, m_locOrder) { + ui->cLocation->addItem(m_locMap.value(locId).desc, locId); + } + + ui->cSub->clear(); + QMap::iterator itor = m_subMap.begin(); + while (itor != m_subMap.end()) { + ui->cSub->addItem(itor.value(),itor.key()); + itor++; + } + + ui->cType->clear(); + QMap::iterator pos = m_typeMap.begin(); + while (pos != m_typeMap.end()) { + ui->cType->addItem(pos.value(),pos.key()); + pos++; + } + ui->cLocation->blockSignals(false); + ui->cSub->blockSignals(false); + ui->cType->blockSignals(false); + + setDefaultWidth(); + setColumnHidden(COL_SUBSYSTEM,true); + setColumnHidden(COL_STATETEXT,true); + setColumnHidden(COL_USERGROUP,true); + setColumnHidden(COL_KEYIDTAG,true); + setColumnHidden(COL_TABLE,true); + ui->treeWidget->setSortingEnabled(true); + ui->treeWidget->sortByColumn(COL_OPTTIME, Qt::DescendingOrder); +} + +void CDataOptWidget::initConn() +{ + connect(ui->cLocation,&QComboBox::currentTextChanged,this,&CDataOptWidget::filter); + connect(ui->cSub,&QComboBox::currentTextChanged,this,&CDataOptWidget::filter); + connect(ui->cType,&QComboBox::currentTextChanged,this,&CDataOptWidget::filter); +} + +void CDataOptWidget::loadLoc() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION,DOMAIN_ID from sys_model_location_info order by LOCATION_NO"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + STLocationInfo loc; + loc.id = query.value(0).toInt(); + loc.desc = query.value(1).toString(); + loc.domainId = query.value(2).toInt(); + m_locMap.insert(loc.id, loc); + m_locOrder.push_back(loc.id); + } +} + +void CDataOptWidget::loadSub() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select SUB_SYSTEM_ID,DESCRIPTION from sys_model_sub_system_info where SUB_SYSTEM_ID > 3"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString desc = query.value(1).toString(); + m_subMap.insert(id, desc); + } +} + +void CDataOptWidget::loadDevG() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + m_devgMap.insert(tag, desc); + } +} + +void CDataOptWidget::loadTagType() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select ACTUAL_VALUE,DISPLAY_VALUE from dict_menu_info where menu_name = '标签类型'"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int actual = query.value(0).toInt(); + QString display = query.value(1).toString(); + m_typeMap.insert(actual, display); + } +} + +void CDataOptWidget::updateTree(const QList &dataList) +{ + ui->treeWidget->clear(); + ui->treeWidget->setSortingEnabled(false); + QList typeList = m_typeMap.keys(); + QMap devGroupMap; //< 设备组所在节点 + for(int index(0);indexgetTagInfoByPointTagName(dataList[index].tagName); + + //< 找到设备组所在树节点 + QTreeWidgetItem * parent = Q_NULLPTR; + QMap::iterator iter = devGroupMap.find(tagInfo.devgName); + if(iter == devGroupMap.end()) + { + QTreeWidgetItem * devgItem = new QTreeWidgetItem; + devgItem->setText(COL_TAGNAME, m_devgMap.value(tagInfo.devgName,tr("未知"))); + devgItem->setData(COL_TAGNAME, Qt::UserRole, tagInfo.devgName); + devgItem->setData(COL_TAGNAME, Qt::UserRole+1, TYPE_DEVGROUP); + devgItem->setText(COL_OPTTIME, QDateTime::fromMSecsSinceEpoch(dataList[index].optTime).toString("yyyy-MM-dd hh:mm:ss")); + devgItem->setData(COL_OPTTIME, Qt::UserRole, dataList[index].optTime); //< 用于排序 + ui->treeWidget->addTopLevelItem(devgItem); + devGroupMap.insert(tagInfo.devgName, devgItem); + parent = devgItem; + } + else + { + if(dataList[index].optTime > iter.value()->data(COL_OPTTIME, Qt::UserRole).toInt()) + { + iter.value()->setData(COL_OPTTIME, Qt::UserRole, dataList[index].optTime); + iter.value()->setText(COL_OPTTIME, QDateTime::fromMSecsSinceEpoch(dataList[index].optTime).toString("yyyy-MM-dd hh:mm:ss")); + } + parent = iter.value(); + } + + QTreeWidgetItem *item = new QTreeWidgetItem(parent); + item->setText(COL_TAGNAME, tagInfo.desc); + item->setData(COL_TAGNAME, Qt::UserRole, tagInfo.tagName); + item->setData(COL_TAGNAME, Qt::UserRole+1, TYPE_POINT); + + item->setText(COL_LOCATION, m_locMap.value(dataList[index].locationId).desc); + item->setData(COL_LOCATION, Qt::UserRole, dataList[index].locationId); + + item->setText(COL_DEVICE, tagInfo.devDesc); + item->setData(COL_DEVICE, Qt::UserRole, tagInfo.devName); + + item->setText(COL_TYPE, m_typeMap.value(dataList[index].tagType, tr("未知"))); + item->setData(COL_TYPE, Qt::UserRole, dataList[index].tagType); + + item->setText(COL_OPTTIME, QDateTime::fromMSecsSinceEpoch(dataList[index].optTime).toString("yyyy-MM-dd hh:mm:ss")); + item->setData(COL_OPTTIME, Qt::UserRole, dataList[index].optTime); + + item->setText(COL_SUBSYSTEM, m_subMap.value(dataList[index].subSystem,tr("未知"))); + item->setData(COL_SUBSYSTEM, Qt::UserRole, dataList[index].subSystem); + + item->setText(COL_SETVALUE, QString::number(dataList[index].setValue)); + item->setData(COL_SETVALUE, Qt::UserRole, dataList[index].setValue); + + item->setText(COL_STATETEXT, dataList[index].stateText); + item->setData(COL_STATETEXT, Qt::UserRole, dataList[index].stateText); + + item->setText(COL_HOSTNAME, dataList[index].hostName); + item->setData(COL_HOSTNAME, Qt::UserRole, dataList[index].hostName); + + item->setText(COL_USERNAME, dataList[index].userName); + item->setData(COL_USERNAME, Qt::UserRole, dataList[index].userName); + + item->setText(COL_USERGROUP, dataList[index].userGroup); + item->setData(COL_USERGROUP, Qt::UserRole, dataList[index].userGroup); + + item->setText(COL_KEYIDTAG, dataList[index].keyIdTag); + item->setData(COL_KEYIDTAG, Qt::UserRole, dataList[index].keyIdTag); + + item->setText(COL_TABLE, dataList[index].table); + item->setData(COL_TABLE, Qt::UserRole,dataList[index].table); + } + filter(""); + ui->treeWidget->setSortingEnabled(true); +} + +void CDataOptWidget::updateCount() +{ + int showRowCount = 0; + for(int nIndex(0); nIndex< ui->treeWidget->topLevelItemCount(); nIndex++) + { + QTreeWidgetItem *item = ui->treeWidget->topLevelItem(nIndex); + for(int nChildIndex(0); nChildIndexchildCount(); nChildIndex++) + { + if(!item->child(nChildIndex)->isHidden()) + { + showRowCount++; + } + } + } + ui->lCount->setNum(showRowCount); +} + +bool CDataOptWidget::permCheck(int location, int region) +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + QString mess; + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + int userId; + if(PERM_NORMAL != permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + userId = -1; + mess = QString(tr("获取当前登录用户失败!")); + slotShowMess(mess); + return false; + } + std::vector vecRegionOptId; + QList regList; + QList locList; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) + { + + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + regList.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + locList.append(*location++); + } + } + if(locList.contains(location) && regList.contains(region)) + { + return true; + }else + { + mess = QString(tr("无操作权限!")); + slotShowMess(mess); + return false; + } + } + mess = QString(tr("初始化权限失败!")); + slotShowMess(mess); + return false; +} + +void CDataOptWidget::initMsg() +{ + if(m_communicator == Q_NULLPTR) + { + m_communicator = new kbd_net::CMbCommunicator(); + } +} + +int CDataOptWidget::createReqHead(SOptReqHead &head) +{ + SNodeInfo nodeInfo; + int userID = -1; + int usergID = -1; + int level; + int loginSec; + std::string instanceName; + + CSysInfoInterfacePtr sysInfo; + if(createSysInfoInstance(sysInfo) == false) + { + LOGERROR("创建系统信息访问库实例失败!"); + return kbdFailed; + } + else + { + sysInfo->getLocalNodeInfo(nodeInfo); + } + + CPermMngApiPtr permMng = getPermMngInstance("base"); + if(permMng != NULL) + { + if(permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + return kbdFailed; + }else + { + if(PERM_NORMAL != permMng->CurUser(userID, usergID, level, loginSec, instanceName)) + { + userID = -1; + return kbdFailed; + } + } + } + head.strSrcTag = "dataOptWidget"; + head.nSrcDomainID = nodeInfo.nDomainId; + head.nDstDomainID = m_domainId; + head.nAppID = m_appId; + head.strHostName = nodeInfo.strName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = userID; + head.nUserGroupID = usergID; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + return kbdSuccess; +} + +void CDataOptWidget::filter(const QString &text) +{ + Q_UNUSED(text) + int nLocId = ui->cLocation->currentData().toInt(); + int nSubId = ui->cSub->currentData().toInt(); + int nTypeId = ui->cType->currentData().toInt(); + + for(int nTopIndex(0); nTopIndextreeWidget->topLevelItemCount(); nTopIndex++) + { + bool isAllHide = true; + QTreeWidgetItem * parent = ui->treeWidget->topLevelItem(nTopIndex); + for(int nChildIndex(0); nChildIndexchildCount(); nChildIndex++) + { + if(nLocId != parent->child(nChildIndex)->data(COL_LOCATION, Qt::UserRole).toInt()) + { + parent->child(nChildIndex)->setHidden(true); + } + else if(nSubId != parent->child(nChildIndex)->data(COL_SUBSYSTEM, Qt::UserRole).toInt()) + { + parent->child(nChildIndex)->setHidden(true); + } + else if(nTypeId != -1 && nTypeId != parent->child(nChildIndex)->data(COL_TYPE, Qt::UserRole).toInt()) + { + parent->child(nChildIndex)->setHidden(true); + } + else + { + parent->child(nChildIndex)->setHidden(false); + isAllHide = false; + } + } + if(isAllHide) + { + parent->setHidden(true); + } + else + { + parent->setHidden(false); + } + } + ui->treeWidget->expandAll(); + updateCount(); +} + +void CDataOptWidget::slotShowMess(const QString &mess) +{ + QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); +} + +void CDataOptWidget::slotBrush(const QList &optTagInfoList) +{ + updateTree(optTagInfoList); + updateCount(); +} + +void CDataOptWidget::setColumnHidden(int column, bool hide) +{ + ui->treeWidget->setColumnHidden(column, hide); +} + +void CDataOptWidget::setColumnWidth(int column, int width) +{ + ui->treeWidget->setColumnWidth(column,width); +} + +void CDataOptWidget::setRowHeight(int height) +{ + ui->treeWidget->header()->setDefaultSectionSize(height); +} + +void CDataOptWidget::setDefaultWidth() +{ + setColumnWidth(COL_TAGNAME,200); + setColumnWidth(COL_LOCATION,200); + setColumnWidth(COL_DEVICE,200); + setColumnWidth(COL_TYPE,150); + setColumnWidth(COL_OPTTIME,200); + setColumnWidth(COL_SETVALUE,100); + setColumnWidth(COL_HOSTNAME,150); + setColumnWidth(COL_USERNAME,150); +} + +void CDataOptWidget::cancelSetValue() +{ + QString mess = QString(tr("当前未选中任何项!")); + QList list = ui->treeWidget->selectedItems(); + if (list.size() <= 0) + { + slotShowMess(mess); + return; + } + + struct itemData + { + QString tagName; + QString tagDesc; + int tagType; + inline bool operator==(const itemData &other) const + { + if(tagName != other.tagName) + { + return false; + } + return tagType == other.tagType; + } + }; + + QList itemDataList = {}; + + QList::iterator iter= list.begin(); + for(; iter!=list.end(); ++iter) + { + QTreeWidgetItem *item = *iter; + int type = item->data(COL_TAGNAME, Qt::UserRole+1).toInt(); + if(type == TYPE_DEVGROUP) + { + for(int n=0; nchildCount(); n++) + { + if(item->child(n)->isHidden()) + { + continue; + } + itemData sItemData; + sItemData.tagName = item->child(n)->data(COL_TAGNAME, Qt::UserRole).toString(); + sItemData.tagDesc = item->child(n)->text(COL_TAGNAME); + sItemData.tagType = item->child(n)->data(COL_TYPE, Qt::UserRole).toInt(); + if(itemDataList.isEmpty()) + { + itemDataList.append(sItemData); + } + else if(std::find(itemDataList.begin(), itemDataList.end(), sItemData) == itemDataList.end()) + { + itemDataList.append(sItemData); + } + else + { + LOGINFO("取消置数: 重复[%s %d]", sItemData.tagName.toStdString().c_str(), sItemData.tagType); + } + } + } + else if(type == TYPE_POINT) + { + itemData sItemData; + sItemData.tagName = item->data(COL_TAGNAME, Qt::UserRole).toString(); + sItemData.tagDesc = item->text(COL_TAGNAME); + sItemData.tagType = item->data(COL_TYPE, Qt::UserRole).toInt(); + if(itemDataList.isEmpty()) + { + itemDataList.append(sItemData); + } + else if(std::find(itemDataList.begin(), itemDataList.end(), sItemData) == itemDataList.end()) + { + itemDataList.append(sItemData); + } + else + { + LOGINFO("取消置数: 重复[%s %d]", sItemData.tagName.toStdString().c_str(), sItemData.tagType); + } + } + else + { + LOGERROR("取消置数: 未知树节点类型[%d]", type); + } + } + + LOGINFO("取消置数: [%d]", itemDataList.length()); + for(int nIndex(0); nIndexgetOptTagInfoByTagAndType(tagName,tagType,info) !=kbdSuccess ) + { + slotShowMess(tr("获取标签操作信息有误,%1").arg(desc)); + return false; + } + STTagInfo tagInfo; + if(m_pWork->getTagInfoByTag(tagName,tagInfo) !=kbdSuccess ) + { + slotShowMess(tr("获取标签信息有误,%1").arg(desc)); + return false; + } + if(!permCheck(info.locationId,tagInfo.region)) + { + return false; + } + removeOptTagInfo(info); + + return true; +} + +void CDataOptWidget::removeOptTagInfo(const STOptTagInfo &info) +{ + kbd_net::CMbMessage msg; + msg.setMsgType(MT_OPT_COMMON_DOWN); + msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); + SOptTagSet sOptTagSet; + SOptTagQueue optTagQueue; + COptTagSet cOptTagSet; + + if(createReqHead(sOptTagSet.stHead)!= kbdSuccess) + { + return ; + } + optTagQueue.strKeyIdTag = info.keyIdTag.toStdString(); + optTagQueue.nIsSet = 0;// 0:取消;1:设置; + optTagQueue.fSetValue = info.setValue; + optTagQueue.strStateText = info.stateText.toStdString(); + optTagQueue.bIsPointQuery = 1; + optTagQueue.nLocationId = info.locationId; + optTagQueue.nSubSystem = info.subSystem; + + sOptTagSet.vecTagQueue.push_back(optTagQueue); + std::string content = cOptTagSet.generate(sOptTagSet); + int type = info.tagType; + if(type == 1) + { + msg.setMsgType(MT_OPT_TAG_VALUE_SET); + }else if(type == 2) + { + msg.setMsgType(MT_OPT_PINHIBIT_REF); + }else if(type == 3) + { + msg.setMsgType(MT_OPT_PINHIBIT_ALARM); + }else + { + msg.setMsgType(MT_OPT_PINHIBIT_CTRL); + } + msg.setData(content); + if(!m_communicator->sendMsgToDomain(msg, m_domainId)) + { + QString mess = QString(tr("下发取消命令失败")); + slotShowMess(mess); + }else + { + removeItemOptTagInfo(info); + m_pWork->removeOneOptTagInfo(info); + updateCount(); + } +} + +void CDataOptWidget::removeItemOptTagInfo(const STOptTagInfo &info) +{ + for(int nTopIndex(0); nTopIndextreeWidget->topLevelItemCount(); nTopIndex++) + { + QTreeWidgetItem * parent = ui->treeWidget->topLevelItem(nTopIndex); + for(int nChildIndex(0); nChildIndexchildCount(); nChildIndex++) + { + QString tagName = parent->child(nChildIndex)->data(COL_TAGNAME, Qt::UserRole).toString(); + int tagType = parent->child(nChildIndex)->data(COL_TYPE, Qt::UserRole).toInt(); + if(info.tagName == tagName && info.tagType == tagType) + { + parent->takeChild(nChildIndex--); + break; + } + } + if(parent->childCount() == 0) + { + ui->treeWidget->takeTopLevelItem(nTopIndex--); + } + } +} + +void CDataOptWidget::search() +{ + m_domainId = m_locMap.value(ui->cLocation->currentData().toInt()).domainId; + + if(m_pSysInfo != Q_NULLPTR) + { + SAppInfo stAppInfo; + m_pSysInfo->getAppInfoBySubsystemId(ui->cSub->currentData().toInt(),stAppInfo); + m_appId = stAppInfo.nId; + emit sigSearch(m_domainId,m_appId); + } +} + diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptWidget.h b/product/src/gui/plugin/DataOptWidget/CDataOptWidget.h index ee0542c9..a39fc380 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptWidget.h +++ b/product/src/gui/plugin/DataOptWidget/CDataOptWidget.h @@ -1,113 +1,113 @@ -#ifndef CDATAOPTWIDGET_H -#define CDATAOPTWIDGET_H - -#include -#include -#include "dbms/db_api_ex/CDbApi.h" -#include -#include "CDataOptCommon.h" -#include -#include "CDataOptWork.h" - -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "service/operate_server_api/JsonMessageStruct.h" -#include "service/operate_server_api/JsonOptCommand.h" -#include "common/MessageChannel.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" - -QT_BEGIN_NAMESPACE -namespace Ui { class CDataOptWidget; } -QT_END_NAMESPACE - -class CDataOptWidget : public QWidget -{ - Q_OBJECT - -public: - CDataOptWidget(bool editMode,QWidget *parent = nullptr); - ~CDataOptWidget(); - -private: - void initStyleSheet(); - - void initialize(); - - void initData(); - - void initView(); - - void initConn(); - - void loadLoc(); - - void loadSub(); - - void loadDevG(); - - void loadTagType(); - - void updateTree(const QList &dataList); - - void updateCount(); - - bool permCheck(int location ,int region); - - void initMsg(); - - int createReqHead(SOptReqHead &head); - - -public slots: - - void setTagType(int actual = 0); - - void filter(const QString &text); - - void slotShowMess(const QString &mess); - - void slotBrush(const QList & optTagInfoList); - - void setColumnHidden(int column,bool hide); - - void setColumnWidth(int column,int width); - - void setRowHeight(int height); - - void setDefaultWidth(); - - void cancelSetValue(); - bool cancelItemSetValue(const QString &desc,const QString& tagName,int tagType); - - void removeOptTagInfo(const STOptTagInfo &info); - - void removeItemOptTagInfo(const STOptTagInfo &info); - - void search(); - -signals: - void sigSearch(int domainId ,int appid); - -private: - Ui::CDataOptWidget *ui; - - kbd_dbms::CDbApi * m_pReadDb; - - kbd_net::CMbCommunicator *m_communicator; - kbd_public::CSysInfoInterfacePtr m_pSysInfo; - QMap m_locMap; - QList m_locOrder; - QMap m_subMap; - QMap m_devgMap; - QMap m_typeMap; - - QThread *m_pThread; - CDataOptWork *m_pWork; - - bool m_editMode; - int m_domainId; - int m_appId; - -}; -#endif // CDATAOPTWIDGET_H +#ifndef CDATAOPTWIDGET_H +#define CDATAOPTWIDGET_H + +#include +#include +#include "dbms/db_api_ex/CDbApi.h" +#include +#include "CDataOptCommon.h" +#include +#include "CDataOptWork.h" + +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "common/MessageChannel.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class CDataOptWidget; } +QT_END_NAMESPACE + +class CDataOptWidget : public QWidget +{ + Q_OBJECT + +public: + CDataOptWidget(bool editMode,QWidget *parent = nullptr); + ~CDataOptWidget(); + +private: + void initStyleSheet(); + + void initialize(); + + void initData(); + + void initView(); + + void initConn(); + + void loadLoc(); + + void loadSub(); + + void loadDevG(); + + void loadTagType(); + + void updateTree(const QList &dataList); + + void updateCount(); + + bool permCheck(int location ,int region); + + void initMsg(); + + int createReqHead(SOptReqHead &head); + + +public slots: + + void setTagType(int actual = 0); + + void filter(const QString &text); + + void slotShowMess(const QString &mess); + + void slotBrush(const QList & optTagInfoList); + + void setColumnHidden(int column,bool hide); + + void setColumnWidth(int column,int width); + + void setRowHeight(int height); + + void setDefaultWidth(); + + void cancelSetValue(); + bool cancelItemSetValue(const QString &desc,const QString& tagName,int tagType); + + void removeOptTagInfo(const STOptTagInfo &info); + + void removeItemOptTagInfo(const STOptTagInfo &info); + + void search(); + +signals: + void sigSearch(int domainId ,int appid); + +private: + Ui::CDataOptWidget *ui; + + kbd_dbms::CDbApi * m_pReadDb; + + kbd_net::CMbCommunicator *m_communicator; + kbd_public::CSysInfoInterfacePtr m_pSysInfo; + QMap m_locMap; + QList m_locOrder; + QMap m_subMap; + QMap m_devgMap; + QMap m_typeMap; + + QThread *m_pThread; + CDataOptWork *m_pWork; + + bool m_editMode; + int m_domainId; + int m_appId; + +}; +#endif // CDATAOPTWIDGET_H diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptWidget.ui b/product/src/gui/plugin/DataOptWidget/CDataOptWidget.ui index a44a0e7f..91e83e15 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptWidget.ui +++ b/product/src/gui/plugin/DataOptWidget/CDataOptWidget.ui @@ -1,213 +1,213 @@ - - - CDataOptWidget - - - - 0 - 0 - 800 - 600 - - - - CDataOptWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 位置: - - - - - - - - - - 专业 - - - - - - - - - - 标签类型: - - - - - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 总数 - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 刷新 - - - - - - - 取消设置 - - - - - - - - - QAbstractItemView::ExtendedSelection - - - - 设备组/点 - - - - - 位置 - - - - - 设备 - - - - - 标签类型 - - - - - 操作时间 - - - - - 专业 - - - - - 设置值 - - - - - 状态文本 - - - - - 主机 - - - - - 操作员 - - - - - 用户组 - - - - - 点标签 - - - - - 表名 - - - - - - - - - - - - + + + CDataOptWidget + + + + 0 + 0 + 800 + 600 + + + + CDataOptWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 位置: + + + + + + + + + + 专业 + + + + + + + + + + 标签类型: + + + + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 总数 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 刷新 + + + + + + + 取消设置 + + + + + + + + + QAbstractItemView::ExtendedSelection + + + + 设备组/点 + + + + + 位置 + + + + + 设备 + + + + + 标签类型 + + + + + 操作时间 + + + + + 专业 + + + + + 设置值 + + + + + 状态文本 + + + + + 主机 + + + + + 操作员 + + + + + 用户组 + + + + + 点标签 + + + + + 表名 + + + + + + + + + + + + diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptWork.cpp b/product/src/gui/plugin/DataOptWidget/CDataOptWork.cpp index e034b28f..391350cc 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptWork.cpp +++ b/product/src/gui/plugin/DataOptWidget/CDataOptWork.cpp @@ -1,244 +1,244 @@ -#include "CDataOptWork.h" -#include "Common.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_dbms; -CDataOptWork::CDataOptWork(QObject *parent) : QObject(parent) -{ - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); -} - -STTagInfo CDataOptWork::getTagInfoByPointTagName(const QString &tagName) -{ - STTagInfo tagInfo; - return m_TagInfoMap.value(tagName,tagInfo); -} - -int CDataOptWork::getOptTagInfoByTagAndType(const QString &tag, int type,STOptTagInfo &info) -{ - for(int index(0);index vecColumn = {"key_id_tag","tag_type","opt_time","location_id","sub_system","set_value","state_text","host_name","user_name","user_group"}; - - - bRet = m_objRdbNetApi.queryTotal("opt_tag_info",vecColumn,objRdbRet); - if(!bRet || objRdbRet.msgrecord_size() < 0) - { - emit sigShowMess(QString("读取人工置数信息表失败,请检查网络或主数据库服务器连接是否异常!%1").arg(QString::fromStdString(m_objRdbNetApi.getErr()))); - return false; - } - - for(int i=0;i > tableTagMap = getKeyIdTagMap(); - readKeyIdTagDescListByMap(tableTagMap); -} - -QMap > CDataOptWork::getKeyIdTagMap() -{ - QMap > tableTagListMap; - for(int index(0);index >::iterator it = tableTagListMap.find(m_optTagInfoList[index].table); - if(it != tableTagListMap.end()) - { - it.value().append(m_optTagInfoList[index].tagName); - }else - { - QList list; - list.append(m_optTagInfoList[index].tagName); - tableTagListMap[m_optTagInfoList[index].table] = list; - } - } - return tableTagListMap; -} - -void CDataOptWork::readKeyIdTagDescListByMap(const QMap > &tableTagMap) -{ - m_TagInfoMap.clear(); - QMap >::const_iterator it = tableTagMap.begin(); - while (it != tableTagMap.constEnd()) { - readKeyIdTagDescListByTable(it.key(),it.value()); - it++; - } -} - -void CDataOptWork::readKeyIdTagDescListByTable(const QString &table, const QList tagList) -{ - if(!m_pReadDb->isOpen()) - { - return ; - - } - QString cond =QString(); - - if(tagList.isEmpty()) - { - return ; - } - for(int index(0);indexexecute(sql,query); - while(query.next()) - { - STTagInfo info; - info.tagName = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devName = query.value(2).toString(); - info.devDesc = query.value(3).toString(); - info.devgName = query.value(4).toString(); - info.region = query.value(5).toInt(); - m_TagInfoMap[info.tagName] = info; - } -} - -QString CDataOptWork::getTagNameByKeyIdTag(const QString &keyIdTag) -{ - QStringList temp = keyIdTag.split("."); - QString tagName = QString(); - if(temp.length() < 3) - { - return tagName; - } - tagName = temp.at(1); - for(int index(2);indexopen(); +} + +STTagInfo CDataOptWork::getTagInfoByPointTagName(const QString &tagName) +{ + STTagInfo tagInfo; + return m_TagInfoMap.value(tagName,tagInfo); +} + +int CDataOptWork::getOptTagInfoByTagAndType(const QString &tag, int type,STOptTagInfo &info) +{ + for(int index(0);index vecColumn = {"key_id_tag","tag_type","opt_time","location_id","sub_system","set_value","state_text","host_name","user_name","user_group"}; + + + bRet = m_objRdbNetApi.queryTotal("opt_tag_info",vecColumn,objRdbRet); + if(!bRet || objRdbRet.msgrecord_size() < 0) + { + emit sigShowMess(QString("读取人工置数信息表失败,请检查网络或主数据库服务器连接是否异常!%1").arg(QString::fromStdString(m_objRdbNetApi.getErr()))); + return false; + } + + for(int i=0;i > tableTagMap = getKeyIdTagMap(); + readKeyIdTagDescListByMap(tableTagMap); +} + +QMap > CDataOptWork::getKeyIdTagMap() +{ + QMap > tableTagListMap; + for(int index(0);index >::iterator it = tableTagListMap.find(m_optTagInfoList[index].table); + if(it != tableTagListMap.end()) + { + it.value().append(m_optTagInfoList[index].tagName); + }else + { + QList list; + list.append(m_optTagInfoList[index].tagName); + tableTagListMap[m_optTagInfoList[index].table] = list; + } + } + return tableTagListMap; +} + +void CDataOptWork::readKeyIdTagDescListByMap(const QMap > &tableTagMap) +{ + m_TagInfoMap.clear(); + QMap >::const_iterator it = tableTagMap.begin(); + while (it != tableTagMap.constEnd()) { + readKeyIdTagDescListByTable(it.key(),it.value()); + it++; + } +} + +void CDataOptWork::readKeyIdTagDescListByTable(const QString &table, const QList tagList) +{ + if(!m_pReadDb->isOpen()) + { + return ; + + } + QString cond =QString(); + + if(tagList.isEmpty()) + { + return ; + } + for(int index(0);indexexecute(sql,query); + while(query.next()) + { + STTagInfo info; + info.tagName = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devName = query.value(2).toString(); + info.devDesc = query.value(3).toString(); + info.devgName = query.value(4).toString(); + info.region = query.value(5).toInt(); + m_TagInfoMap[info.tagName] = info; + } +} + +QString CDataOptWork::getTagNameByKeyIdTag(const QString &keyIdTag) +{ + QStringList temp = keyIdTag.split("."); + QString tagName = QString(); + if(temp.length() < 3) + { + return tagName; + } + tagName = temp.at(1); + for(int index(2);index -#include "dbms/db_api_ex/CDbApi.h" -#include "rdb_net_api/CRdbNetApi.h" -#include "CDataOptCommon.h" -#include - -class CDataOptWork : public QObject -{ - Q_OBJECT -public: - explicit CDataOptWork(QObject *parent = nullptr); - - STTagInfo getTagInfoByPointTagName(const QString &tagName); - - int getOptTagInfoByTagAndType(const QString &tag, int type, STOptTagInfo &info); - - int getTagInfoByTag(const QString &tag,STTagInfo &info); - - void removeOneOptTagInfo(const STOptTagInfo &info); - -public slots: - - void slotSearch(int domainId,int appid); - -signals: - void sigShowMess(const QString &mess); - - void sigBrush(const QList &optTagInfoList); - -private: - bool readTagInfo(); - - bool readKeyIdTagDesc(); - - void readKeyIdTagDescByTagList(); - - QMap > getKeyIdTagMap(); - - void readKeyIdTagDescListByMap(const QMap > &tableTagMap); - - void readKeyIdTagDescListByTable(const QString &table,const QList tagList); - - QString getTagNameByKeyIdTag(const QString &keyIdTag); - - QString getDeviceNameByKeyIdTag(const QString &keyIdTag); - - QString getTableNameByKeyIdTag(const QString &keyIdTag); - -private: - - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbNetApi m_objRdbNetApi; //< 网络查询对象 - - QList m_optTagInfoList; - QMap m_TagInfoMap; -}; - -#endif // CDATAOPTWORK_H +#ifndef CDATAOPTWORK_H +#define CDATAOPTWORK_H + +#include +#include "dbms/db_api_ex/CDbApi.h" +#include "rdb_net_api/CRdbNetApi.h" +#include "CDataOptCommon.h" +#include + +class CDataOptWork : public QObject +{ + Q_OBJECT +public: + explicit CDataOptWork(QObject *parent = nullptr); + + STTagInfo getTagInfoByPointTagName(const QString &tagName); + + int getOptTagInfoByTagAndType(const QString &tag, int type, STOptTagInfo &info); + + int getTagInfoByTag(const QString &tag,STTagInfo &info); + + void removeOneOptTagInfo(const STOptTagInfo &info); + +public slots: + + void slotSearch(int domainId,int appid); + +signals: + void sigShowMess(const QString &mess); + + void sigBrush(const QList &optTagInfoList); + +private: + bool readTagInfo(); + + bool readKeyIdTagDesc(); + + void readKeyIdTagDescByTagList(); + + QMap > getKeyIdTagMap(); + + void readKeyIdTagDescListByMap(const QMap > &tableTagMap); + + void readKeyIdTagDescListByTable(const QString &table,const QList tagList); + + QString getTagNameByKeyIdTag(const QString &keyIdTag); + + QString getDeviceNameByKeyIdTag(const QString &keyIdTag); + + QString getTableNameByKeyIdTag(const QString &keyIdTag); + +private: + + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbNetApi m_objRdbNetApi; //< 网络查询对象 + + QList m_optTagInfoList; + QMap m_TagInfoMap; +}; + +#endif // CDATAOPTWORK_H diff --git a/product/src/gui/plugin/DataOptWidget/DataOptWidget.pro b/product/src/gui/plugin/DataOptWidget/DataOptWidget.pro index 027236d6..7afe741a 100644 --- a/product/src/gui/plugin/DataOptWidget/DataOptWidget.pro +++ b/product/src/gui/plugin/DataOptWidget/DataOptWidget.pro @@ -1,62 +1,62 @@ -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib - -TARGET = DataOptWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any Qt feature that has been marked deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if it uses deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - CDataOptPluginWidget.cpp \ - CDataOptWork.cpp \ -# main.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - CDataOptWidget.cpp - -HEADERS += \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - CDataOptCommon.h \ - CDataOptPluginWidget.h \ - CDataOptWidget.h \ - CDataOptWork.h - -FORMS += \ - CDataOptWidget.ui - -LIBS += \ - -lprotobuf \ - -ldb_base_api \ - -ldb_api_ex \ - -lnet_msg_bus_api \ - -lpub_sysinfo_api \ - -lperm_mng_api \ - -llog4cplus \ - -lpub_logger_api \ - -ldp_chg_data_api \ - -lrdb_api \ - -lrdb_net_api \ - -lpub_utility_api \ - -lsys_login_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib + +TARGET = DataOptWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + CDataOptPluginWidget.cpp \ + CDataOptWork.cpp \ +# main.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + CDataOptWidget.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CDataOptCommon.h \ + CDataOptPluginWidget.h \ + CDataOptWidget.h \ + CDataOptWork.h + +FORMS += \ + CDataOptWidget.ui + +LIBS += \ + -lprotobuf \ + -ldb_base_api \ + -ldb_api_ex \ + -lnet_msg_bus_api \ + -lpub_sysinfo_api \ + -lperm_mng_api \ + -llog4cplus \ + -lpub_logger_api \ + -ldp_chg_data_api \ + -lrdb_api \ + -lrdb_net_api \ + -lpub_utility_api \ + -lsys_login_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/DataOptWidget/main.cpp b/product/src/gui/plugin/DataOptWidget/main.cpp index 8ddcbd8a..1e1e5b2d 100644 --- a/product/src/gui/plugin/DataOptWidget/main.cpp +++ b/product/src/gui/plugin/DataOptWidget/main.cpp @@ -1,37 +1,37 @@ - -#include - -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "CDataOptWidget.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - kbd_public::StartLogSystem("HMI", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - { - CDataOptWidget w(false,NULL); - w.setTagType(0); - w.show(); - a.exec(); - } - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} + +#include + +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "CDataOptWidget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + kbd_public::StartLogSystem("HMI", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + { + CDataOptWidget w(false,NULL); + w.setTagType(0); + w.show(); + a.exec(); + } + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/DevHisDataWidget/CDbInterface.cpp b/product/src/gui/plugin/DevHisDataWidget/CDbInterface.cpp index 92f1a4ea..95af14eb 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDbInterface.cpp +++ b/product/src/gui/plugin/DevHisDataWidget/CDbInterface.cpp @@ -1,178 +1,178 @@ -#include "CDbInterface.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "public/pub_logger_api/logger.h" - -using namespace kbd_dbms; - -CDbInterface::CDbInterface() - : m_pReadDb(NULL), - m_rtdbAccess(NULL) -{ - initialize(); - - loadDictStateText(); - loadDictMenuInfo(); -} - -CDbInterface::~CDbInterface() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; -} - -void CDbInterface::initialize() -{ - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - if(!m_pReadDb->open()) - { - LOGERROR("打开数据库连接失败! %s", m_pReadDb->getLastErrorString().toStdString().c_str()); - } - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - nCurDomain = CN_InvalidDomainId; - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - } - else - { - spSysInfo->getLocalNodeInfo(stNodeInfo); - nCurDomain = stNodeInfo.nDomainId; - } -} - -void CDbInterface::loadDictStateText() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - m_dictText.clear(); - QSqlQuery query; - QString sqlSequenceQuery = QString("select state_text_name, actual_value, display_value from dict_state_text_info"); - m_pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - m_dictText[query.value(0).toString()].insert(query.value(1).toInt(), query.value(2).toString()); - } -} - -void CDbInterface::loadDictMenuInfo() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - m_dictMenu.clear(); - QSqlQuery query; - QString sqlSequenceQuery = QString("select menu_macro_name,actual_value from dict_menu_info where menu_macro_name='%1' or menu_macro_name='%2'") - .arg(MENU_STATE_AI_INVALID).arg(MENU_STATE_DI_INVALID); - m_pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - m_dictMenu.insert(query.value(0).toString(), query.value(1).toInt()); - } -} - -void CDbInterface::readLocationInfo(QMap &locMap, QList &locOrder) -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QSqlQuery query; - QString sqlSequenceQuery = QString("select location_id, tag_name, description from sys_model_location_info where domain_id = %1 order by location_no").arg(nCurDomain); - m_pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - locMap.insert(query.value(0).toInt(), QString("%1,%2").arg(query.value(1).toString()).arg(query.value(2).toString())); - locOrder.push_back(query.value(0).toInt()); - } -} - -QMap CDbInterface::readDevTypeInfo() -{ - if(!m_pReadDb->isOpen()) - { - return QMap(); - } - QMap map; - QSqlQuery query; - QString sqlSequenceQuery = QString("select dev_type_id, description from dev_type_def"); - m_pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - map.insert(query.value(0).toInt(), query.value(1).toString()); - } - return map; -} - -QMap CDbInterface::readDevInfo(int devType, int location) -{ - if(!m_pReadDb->isOpen()) - { - return QMap(); - } - QMap map; - QSqlQuery query; - QString sqlSequenceQuery = QString("select tag_name, description from dev_info where dev_type = %1 and location_id = %2").arg(devType).arg(location); - m_pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - map.insert(query.value(0).toString(), query.value(1).toString()); - } - return map; -} - -QString CDbInterface::readStateText(const QString &tag) -{ - QString ret; - if(m_rtdbAccess->open("pscada", "digital")) - { - CONDINFO condition; - memcpy(condition.name, "tag_name", strlen("tag_name")); - condition.logicalop = ATTRCOND_OR; - condition.relationop = ATTRCOND_EQU; - condition.conditionval = tag.toStdString(); - - CRdbQueryResult result; - std::vector columns; - columns.push_back("state_text_name"); - if(m_rtdbAccess->select(condition, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType text; - result.getColumnValue(nIndex, 0, text); - ret = QString::fromStdString(text.toStdString()); - } - } - } - - m_rtdbAccess->close(); - return ret; -} - -QString CDbInterface::queryDisplayValue(const QString &text, int actual) -{ - return m_dictText.value(text).value(actual); -} - -int CDbInterface::queryStateActualValue(const QString ¯o) -{ - return m_dictMenu.value(macro, 0); -} - +#include "CDbInterface.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "public/pub_logger_api/logger.h" + +using namespace kbd_dbms; + +CDbInterface::CDbInterface() + : m_pReadDb(NULL), + m_rtdbAccess(NULL) +{ + initialize(); + + loadDictStateText(); + loadDictMenuInfo(); +} + +CDbInterface::~CDbInterface() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; +} + +void CDbInterface::initialize() +{ + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + LOGERROR("打开数据库连接失败! %s", m_pReadDb->getLastErrorString().toStdString().c_str()); + } + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + nCurDomain = CN_InvalidDomainId; + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + else + { + spSysInfo->getLocalNodeInfo(stNodeInfo); + nCurDomain = stNodeInfo.nDomainId; + } +} + +void CDbInterface::loadDictStateText() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_dictText.clear(); + QSqlQuery query; + QString sqlSequenceQuery = QString("select state_text_name, actual_value, display_value from dict_state_text_info"); + m_pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + m_dictText[query.value(0).toString()].insert(query.value(1).toInt(), query.value(2).toString()); + } +} + +void CDbInterface::loadDictMenuInfo() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_dictMenu.clear(); + QSqlQuery query; + QString sqlSequenceQuery = QString("select menu_macro_name,actual_value from dict_menu_info where menu_macro_name='%1' or menu_macro_name='%2'") + .arg(MENU_STATE_AI_INVALID).arg(MENU_STATE_DI_INVALID); + m_pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + m_dictMenu.insert(query.value(0).toString(), query.value(1).toInt()); + } +} + +void CDbInterface::readLocationInfo(QMap &locMap, QList &locOrder) +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QSqlQuery query; + QString sqlSequenceQuery = QString("select location_id, tag_name, description from sys_model_location_info where domain_id = %1 order by location_no").arg(nCurDomain); + m_pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + locMap.insert(query.value(0).toInt(), QString("%1,%2").arg(query.value(1).toString()).arg(query.value(2).toString())); + locOrder.push_back(query.value(0).toInt()); + } +} + +QMap CDbInterface::readDevTypeInfo() +{ + if(!m_pReadDb->isOpen()) + { + return QMap(); + } + QMap map; + QSqlQuery query; + QString sqlSequenceQuery = QString("select dev_type_id, description from dev_type_def"); + m_pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + map.insert(query.value(0).toInt(), query.value(1).toString()); + } + return map; +} + +QMap CDbInterface::readDevInfo(int devType, int location) +{ + if(!m_pReadDb->isOpen()) + { + return QMap(); + } + QMap map; + QSqlQuery query; + QString sqlSequenceQuery = QString("select tag_name, description from dev_info where dev_type = %1 and location_id = %2").arg(devType).arg(location); + m_pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + map.insert(query.value(0).toString(), query.value(1).toString()); + } + return map; +} + +QString CDbInterface::readStateText(const QString &tag) +{ + QString ret; + if(m_rtdbAccess->open("pscada", "digital")) + { + CONDINFO condition; + memcpy(condition.name, "tag_name", strlen("tag_name")); + condition.logicalop = ATTRCOND_OR; + condition.relationop = ATTRCOND_EQU; + condition.conditionval = tag.toStdString(); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("state_text_name"); + if(m_rtdbAccess->select(condition, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType text; + result.getColumnValue(nIndex, 0, text); + ret = QString::fromStdString(text.toStdString()); + } + } + } + + m_rtdbAccess->close(); + return ret; +} + +QString CDbInterface::queryDisplayValue(const QString &text, int actual) +{ + return m_dictText.value(text).value(actual); +} + +int CDbInterface::queryStateActualValue(const QString ¯o) +{ + return m_dictMenu.value(macro, 0); +} + diff --git a/product/src/gui/plugin/DevHisDataWidget/CDbInterface.h b/product/src/gui/plugin/DevHisDataWidget/CDbInterface.h index dd543f15..3f3a3303 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDbInterface.h +++ b/product/src/gui/plugin/DevHisDataWidget/CDbInterface.h @@ -1,40 +1,40 @@ -#ifndef CDBINTERFACE_H -#define CDBINTERFACE_H - -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/db_api_ex/CDbApi.h" - -//< 状态字定义 -#define MENU_STATE_DI_INVALID ("MENU_STATE_DI_INVALID") //< 数字量无效 -#define MENU_STATE_AI_INVALID ("MENU_STATE_AI_INVALID") //< 模拟量无效 - -class CDbInterface -{ -public: - CDbInterface(); - ~CDbInterface(); - - void readLocationInfo(QMap &locMap, QList &locOrder); //Map(id,tag_name description) - QMap readDevTypeInfo(); - QMap readDevInfo(int devType, int location); - QString readStateText(const QString& tag); - - QString queryDisplayValue(const QString& text, int actual); - int queryStateActualValue(const QString& macro); - -private: - void initialize(); - - void loadDictStateText(); - void loadDictMenuInfo(); - -private: - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccess * m_rtdbAccess; - int nCurDomain; - QMap > m_dictText; //< state_text_name actual_value,display_value - QMap m_dictMenu; //< menu_macro_name,actual_value - -}; - -#endif // CDBINTERFACE_H +#ifndef CDBINTERFACE_H +#define CDBINTERFACE_H + +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" + +//< 状态字定义 +#define MENU_STATE_DI_INVALID ("MENU_STATE_DI_INVALID") //< 数字量无效 +#define MENU_STATE_AI_INVALID ("MENU_STATE_AI_INVALID") //< 模拟量无效 + +class CDbInterface +{ +public: + CDbInterface(); + ~CDbInterface(); + + void readLocationInfo(QMap &locMap, QList &locOrder); //Map(id,tag_name description) + QMap readDevTypeInfo(); + QMap readDevInfo(int devType, int location); + QString readStateText(const QString& tag); + + QString queryDisplayValue(const QString& text, int actual); + int queryStateActualValue(const QString& macro); + +private: + void initialize(); + + void loadDictStateText(); + void loadDictMenuInfo(); + +private: + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccess * m_rtdbAccess; + int nCurDomain; + QMap > m_dictText; //< state_text_name actual_value,display_value + QMap m_dictMenu; //< menu_macro_name,actual_value + +}; + +#endif // CDBINTERFACE_H diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.cpp b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.cpp index ec2952d9..313fd8c3 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.cpp +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CDevHisDataPluginWidget.h" -#include "CDevHisDataWidget.h" -#include - -CDevHisDataPluginWidget::CDevHisDataPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CDevHisDataPluginWidget::~CDevHisDataPluginWidget() -{ - -} - -bool CDevHisDataPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CDevHisDataWidget *pWidget = new CDevHisDataWidget(editMode, ptrVec, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CDevHisDataPluginWidget::release() -{ - -} +#include "CDevHisDataPluginWidget.h" +#include "CDevHisDataWidget.h" +#include + +CDevHisDataPluginWidget::CDevHisDataPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CDevHisDataPluginWidget::~CDevHisDataPluginWidget() +{ + +} + +bool CDevHisDataPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CDevHisDataWidget *pWidget = new CDevHisDataWidget(editMode, ptrVec, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CDevHisDataPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.h b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.h index a524005b..2e970cb5 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.h +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CDEVHISDATAPLUGINWIDGET_H -#define CDEVHISDATAPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CDevHisDataPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CDevHisDataPluginWidget(QObject *parent = 0); - ~CDevHisDataPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CDEVHISDATAPLUGINWIDGET_H +#ifndef CDEVHISDATAPLUGINWIDGET_H +#define CDEVHISDATAPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CDevHisDataPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CDevHisDataPluginWidget(QObject *parent = 0); + ~CDevHisDataPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CDEVHISDATAPLUGINWIDGET_H diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.cpp b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.cpp index 4d8f3ee6..294c4697 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.cpp +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.cpp @@ -1,542 +1,542 @@ -#include "CDevHisDataWidget.h" -#include "ui_CDevHisDataWidget.h" -#include "CTableViewPrinter.h" -#include "model_excel/xlsx/xlsxdocument.h" -#include -#include -#include -#include -#include -#include "pub_utility_api/FileStyle.h" - -CDevHisDataWidget::CDevHisDataWidget(bool editMode, QVector ptrVec, QWidget *parent) : - QWidget(parent), - ui(new Ui::CDevHisDataWidget), - m_dbInterface(Q_NULLPTR), - m_pHisEventThread(Q_NULLPTR), - m_hisDataManage(Q_NULLPTR), - m_devHisModel(Q_NULLPTR), - m_editModel(editMode) -{ - Q_UNUSED(ptrVec); - ui->setupUi(this); - - QString style = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile file1(QString::fromStdString(strFullPath)); - if (file1.open(QIODevice::ReadOnly)) - { - QTextStream styleStream(&file1); - style += styleStream.readAll(); - //setStyleSheet(style); - } - file1.close(); - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("deviceHisData.qss") ; - QFile file2(QString::fromStdString(strFullPath)); - if (file2.open(QIODevice::ReadOnly)) - { - QTextStream styleStream(&file2); - style+= styleStream.readAll(); - //setStyleSheet(style); - } - file2.close(); - - if(!style.isEmpty()) - { - setStyleSheet(style); - } - initView(); - - if(!m_editModel) - { - qRegisterMetaType*>("std::vector*"); - qRegisterMetaType("EnComputeMethod"); - qRegisterMetaType("EnFillMethod"); - qRegisterMetaType *>*>("std::vector *>*"); - qRegisterMetaType("int64_t"); - - initData(); - - QTimer::singleShot(10, this, SLOT(updateTableColumnWidth())); - } -} - -CDevHisDataWidget::~CDevHisDataWidget() -{ - if(m_pHisEventThread) - { - m_pHisEventThread->quit(); - m_pHisEventThread->wait(); - } - m_pHisEventThread = Q_NULLPTR; - - if(m_dbInterface) - { - delete m_dbInterface; - } - m_dbInterface = NULL; - - if(m_hisDataManage) - { - delete m_hisDataManage; - } - m_hisDataManage = NULL; - - delete ui; -} - -int CDevHisDataWidget::currentLocationId() -{ - return ui->m_locationComb->currentData().toString().section(",", 0, 0).toInt(); -} - -QString CDevHisDataWidget::currentLocationTag() -{ - return ui->m_locationComb->currentData().toString().section(",", 1, 1); -} - -QString CDevHisDataWidget::currentLocation() -{ - return ui->m_locationComb->currentText(); -} - -int CDevHisDataWidget::currentDevType() -{ - return ui->m_devTypeComb->currentData().toInt(); -} - -QString CDevHisDataWidget::currentDevTag() -{ - return ui->m_devComb->currentData().toString(); -} - -QString CDevHisDataWidget::currentDevice() -{ - return ui->m_devComb->currentText(); -} - -qint64 CDevHisDataWidget::currentStartTime() -{ - return ui->m_startTime->dateTime().toMSecsSinceEpoch(); -} - -qint64 CDevHisDataWidget::currentEndTime() -{ - return ui->m_endTime->dateTime().toMSecsSinceEpoch(); -} - -QString CDevHisDataWidget::hexTo26(int number) -{ - int p = 26; //进制 - int c = 0; //取余后的数字 - QString temp; - - while (true) { - c = number % p; - number = number / p; - if(number != 0) - { - temp.prepend(QString(QChar(0x41 + c))); - } - else - { - temp.prepend(QString(QChar(0x41 + c))); - break; - } - number--; - } - - return temp; -} - -void CDevHisDataWidget::initView() -{ - ui->m_printBtn->setVisible(false); - - ui->m_tableView->horizontalHeader()->setStretchLastSection(true); - ui->m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->m_tableView->verticalHeader()->setVisible(false); - - QDateTime dateTime = QDateTime::currentDateTime(); - QTime time = dateTime.time(); - time.setHMS(time.hour(), time.minute(), 0, 0); - dateTime.setTime(time); - ui->m_startTime->setDateTime(dateTime); - - time.setHMS(time.hour(), time.minute(), 59, 999); - dateTime.setTime(time); - ui->m_endTime->setDateTime(dateTime); -} - -void CDevHisDataWidget::initData() -{ - kbd_dbms::initTsdbApi(); - - m_dbInterface = new CDbInterface(); - m_hisDataManage = new CHisDataManage(Q_NULLPTR, m_dbInterface); - m_pHisEventThread = new QThread(); - m_hisDataManage->moveToThread(m_pHisEventThread); - connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); - connect(this, SIGNAL(sigReadHistoryPolymericData(std::vector*,int64_t,int64_t,int,EnComputeMethod,EnFillMethod)) - , m_hisDataManage, SLOT(queryHistoryPolymericData(std::vector*,int64_t,int64_t,int,EnComputeMethod,EnFillMethod))); - connect(m_hisDataManage, SIGNAL(sigHistoryPolymericData(std::vector*,std::vector*>*)) - , this, SLOT(updateHisPolymericData(std::vector*,std::vector*>*))); - m_pHisEventThread->start(); - - readDevManageXml(); - m_devHisModel = new CDevHisTableModel(ui->m_tableView); - ui->m_tableView->setModel(m_devHisModel); - - QMap locationMap; - QList locOrder; - m_dbInterface->readLocationInfo(locationMap, locOrder); - foreach (const int &locId, locOrder) { - QString value = locationMap.value(locId); - QString desc = value.section(",", 1, 1); - QString tag = value.section(",", 0, 0); - ui->m_locationComb->addItem(desc, QString("%1,%2").arg(locId).arg(tag)); - } - - QMap devTypeMap = m_dbInterface->readDevTypeInfo(); - QMap::const_iterator devTypeIter = devTypeMap.constBegin(); - for(; devTypeIter != devTypeMap.constEnd(); ++devTypeIter) - { - ui->m_devTypeComb->addItem(devTypeIter.value(), devTypeIter.key()); - } -} - -void CDevHisDataWidget::updateTableColumnWidth() -{ - int nWidth = ui->m_tableView->width(); - int nColmn = m_devHisModel->columnCount(); - for(int nIndex = 0; nIndex < nColmn; ++nIndex) - { - ui->m_tableView->setColumnWidth(nIndex, (nWidth/nColmn) - 2); - } -} - -void CDevHisDataWidget::readDevManageXml() -{ - QDomDocument document; - QDir dir(QCoreApplication::applicationDirPath()); - dir.cdUp(); - dir.cdUp(); - dir.cd(QString("data%1model").arg(QDir::separator())); - QFile file(QString("%1%2devManage.xml").arg(dir.path()).arg(QDir::separator())); - if (!file.open(QIODevice::ReadOnly)) - { - return; - } - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - QDomElement root = document.documentElement(); - if(!root.isNull()) - { - QDomNodeList nodeList = root.elementsByTagName("devType"); - for(int nodeIndex(0); nodeIndex < nodeList.size(); nodeIndex++) - { - QDomElement elem = nodeList.at(nodeIndex).toElement(); - if(!elem.isNull()) - { - QList vecDev; - int devType = elem.attribute("id").toInt(); - QDomNodeList itemList = elem.elementsByTagName("item"); - for(int itemIndex(0); itemIndex < itemList.size(); itemIndex++) - { - QDomNode node = itemList.at(itemIndex); - QDomElement element = node.toElement(); - if(!element.isNull()) - { - SDevManage dev; - dev.tag_name = element.attribute("tag"); - dev.description = element.attribute("description"); - dev.pointType = EnMeasPiontType(element.attribute("pointType").toInt()); - vecDev.append(dev); - } - } - m_devManageMap.insert(devType, vecDev); - } - } - } -} - -double CDevHisDataWidget::getValue(const VarMeasPiontVal &pointVal) -{ - double value = qSqrt(-1.); - if (typeid(boost::int32_t) == pointVal.type()) - { - value = (double)boost::get(pointVal); - } - else if (typeid(boost::float64_t) == pointVal.type()) - { - value = (double)boost::get(pointVal); - } - return value; -} - -QString CDevHisDataWidget::getDispValue(const SMeasPointKey &measPointKey, const VarMeasPiontVal &pointVal) -{ - if(measPointKey.m_enType == MPT_DI) - { - return m_dbInterface->queryDisplayValue(m_digTextMap.value(QString::fromLocal8Bit(measPointKey.m_pszTagName)), getValue(pointVal)); - } - - return QString::number(getValue(pointVal)); -} - -QList CDevHisDataWidget::getValueInitList(int size) -{ - QList list; - for(int nIndex = 0; nIndex < size; ++nIndex) - { - list.append("");//QString::number(qSqrt(-1.))); - } - return list; -} - -QList CDevHisDataWidget::getPointDescList() -{ - QList list; - QList::const_iterator iter = m_devManageMap.value(currentDevType()).constBegin(); - for(; iter != m_devManageMap.value(currentDevType()).constEnd(); ++iter) - { - list.append(iter->description); - } - return list; -} - -void CDevHisDataWidget::setEnable(bool enable) -{ - ui->m_locationComb->setEnabled(enable); - ui->m_devTypeComb->setEnabled(enable); - ui->m_devComb->setEnabled(enable); - ui->m_startTime->setEnabled(enable); - ui->m_endTime->setEnabled(enable); - ui->m_searchBtn->setEnabled(enable); -} - -void CDevHisDataWidget::on_m_locationComb_currentIndexChanged(int index) -{ - Q_UNUSED(index); - m_devHisModel->clear(); - - ui->m_devComb->clear(); - QMap devMap = m_dbInterface->readDevInfo(currentDevType(), currentLocationId()); - QMap::const_iterator iter = devMap.constBegin(); - for(; iter != devMap.constEnd(); ++iter) - { - ui->m_devComb->addItem(iter.value(), iter.key()); - } -} - -void CDevHisDataWidget::on_m_devTypeComb_currentIndexChanged(int index) -{ - on_m_locationComb_currentIndexChanged(index); //index无效 - - m_devHisModel->setHeader(getPointDescList()); - - updateTableColumnWidth(); -} - -void CDevHisDataWidget::on_m_devComb_currentIndexChanged(int index) -{ - Q_UNUSED(index); - m_digTextMap.clear(); - QList list = m_devManageMap.value(currentDevType()); - for(int nIndex = 0; nIndex < list.length(); ++nIndex) - { - if(list.at(nIndex).pointType == MPT_DI) - { - QString tag = currentDevTag() + "." + list.at(nIndex).tag_name; - m_digTextMap.insert(tag, m_dbInterface->readStateText(tag)); - } - } - - m_nanList.clear(); - m_nanList.append(getValueInitList(list.length())); -} - -void CDevHisDataWidget::on_m_startTime_dateTimeChanged(const QDateTime &dateTime) -{ - if(dateTime > ui->m_endTime->dateTime()) - { - ui->m_endTime->setDateTime(dateTime); - } -} - -void CDevHisDataWidget::on_m_endTime_dateTimeChanged(const QDateTime &dateTime) -{ - QDateTime dt = QDateTime::currentDateTime(); - if(dateTime > dt) - { - ui->m_endTime->setDateTime(dt); - } - if(dateTime < ui->m_startTime->dateTime()) - { - ui->m_startTime->setDateTime(dateTime); - } -} - -void CDevHisDataWidget::on_m_searchBtn_clicked() -{ - std::vector *vecMpKey = new std::vector(); - - QString devTag = currentDevTag(); - foreach (SDevManage dev, m_devManageMap.value(currentDevType())) { - SMeasPointKey key; - std::string tmp = QString("%1.%2").arg(devTag).arg(dev.tag_name).toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = dev.pointType; - vecMpKey->push_back(key); - } - - setEnable(false); - emit sigReadHistoryPolymericData(vecMpKey, currentStartTime(), currentEndTime(), 1 * 60 * 1000, CM_LAST, FM_PREVIOUS); -} - -void CDevHisDataWidget::on_m_clearBtn_clicked() -{ - m_devHisModel->clear(); -} - -void CDevHisDataWidget::on_m_excelBtn_clicked() -{ - QString filePath = QFileDialog::getSaveFileName(this, tr("保存"), "", "*.xlsx"); - if(filePath.isEmpty()) - return; - - QXlsx::Document xlsx; - - for(int col = 0; col < m_devHisModel->columnCount(); col++) - { - xlsx.write(hexTo26(col)+"1", m_devHisModel->headerData(col, Qt::Horizontal, Qt::DisplayRole)); - xlsx.setColumnWidth(col+1, (ui->m_tableView->columnWidth(col))/7); - } - - for(int row = 0; row < m_devHisModel->rowCount(); row++) - { - for(int col = 0; col < m_devHisModel->columnCount(); col++) - { - QModelIndex index = m_devHisModel->index(row, col); - xlsx.write(hexTo26(col)+QString::number(row+2), m_devHisModel->data(index)); - } - } - - if(xlsx.saveAs(filePath)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } -} - -void CDevHisDataWidget::on_m_pdfBtn_clicked() -{ - QString filePath = QFileDialog::getSaveFileName(this, tr("保存"), "", "*.pdf"); - if(filePath.isEmpty()) - return; - - QTableView view(ui->m_tableView); - view.setModel(ui->m_tableView->model()); - - QPrinter printer; - printer.setPageSize(QPagedPaintDevice::A4); - printer.setPageOrientation(QPageLayout::Landscape); - printer.setOutputFileName(filePath); - printer.setOutputFormat(QPrinter::PdfFormat); - - CTableViewPrinter viewPrinter(&view); - if(viewPrinter.print(&printer)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } -} - -void CDevHisDataWidget::on_m_printBtn_clicked() -{ -} - -void CDevHisDataWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult) -{ -// qDebug() << "updateHisOriginalData begin: " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); - - QMap map; - for(int nIndex = 0; nIndex < (int)vecResult->size(); ++nIndex) - { - std::vector::iterator iter = vecResult->at(nIndex)->begin(); - for(; iter != vecResult->at(nIndex)->end(); ++iter) - { - if(iter->m_nTime < currentStartTime() || iter->m_nTime > currentEndTime()) - { - continue; - } - - if(map.contains(iter->m_nTime)) - { - map[iter->m_nTime].valueList.replace(nIndex, getDispValue(vecMpKey->at(nIndex), iter->m_varValue)); - } - else - { - SHisData hisData; - hisData.location = currentLocation(); - hisData.device = currentDevice(); - hisData.valueList.append(m_nanList); - hisData.valueList.replace(nIndex, getDispValue(vecMpKey->at(nIndex), iter->m_varValue)); - map.insert(iter->m_nTime, hisData); - } - } - } - - m_devHisModel->update(map); - -// qDebug() << "updateHisOriginalData end1: " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); - - //< 释放结果集 - std::vector *>::iterator res = vecResult->begin(); - while(vecResult->end() != res) - { - delete (*res); - ++res; - } - vecResult->clear(); - delete vecResult; - - //< 释放测点信息 - std::vector::iterator key = vecMpKey->begin(); - while(vecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - } - vecMpKey->clear(); - delete vecMpKey; - - setEnable(true); - -// qDebug() << "updateHisOriginalData end2: " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); -} - -void CDevHisDataWidget::resizeEvent(QResizeEvent *event) -{ - if(!m_editModel) - { - updateTableColumnWidth(); - } - QWidget::resizeEvent(event); -} - +#include "CDevHisDataWidget.h" +#include "ui_CDevHisDataWidget.h" +#include "CTableViewPrinter.h" +#include "model_excel/xlsx/xlsxdocument.h" +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + +CDevHisDataWidget::CDevHisDataWidget(bool editMode, QVector ptrVec, QWidget *parent) : + QWidget(parent), + ui(new Ui::CDevHisDataWidget), + m_dbInterface(Q_NULLPTR), + m_pHisEventThread(Q_NULLPTR), + m_hisDataManage(Q_NULLPTR), + m_devHisModel(Q_NULLPTR), + m_editModel(editMode) +{ + Q_UNUSED(ptrVec); + ui->setupUi(this); + + QString style = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile file1(QString::fromStdString(strFullPath)); + if (file1.open(QIODevice::ReadOnly)) + { + QTextStream styleStream(&file1); + style += styleStream.readAll(); + //setStyleSheet(style); + } + file1.close(); + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("deviceHisData.qss") ; + QFile file2(QString::fromStdString(strFullPath)); + if (file2.open(QIODevice::ReadOnly)) + { + QTextStream styleStream(&file2); + style+= styleStream.readAll(); + //setStyleSheet(style); + } + file2.close(); + + if(!style.isEmpty()) + { + setStyleSheet(style); + } + initView(); + + if(!m_editModel) + { + qRegisterMetaType*>("std::vector*"); + qRegisterMetaType("EnComputeMethod"); + qRegisterMetaType("EnFillMethod"); + qRegisterMetaType *>*>("std::vector *>*"); + qRegisterMetaType("int64_t"); + + initData(); + + QTimer::singleShot(10, this, SLOT(updateTableColumnWidth())); + } +} + +CDevHisDataWidget::~CDevHisDataWidget() +{ + if(m_pHisEventThread) + { + m_pHisEventThread->quit(); + m_pHisEventThread->wait(); + } + m_pHisEventThread = Q_NULLPTR; + + if(m_dbInterface) + { + delete m_dbInterface; + } + m_dbInterface = NULL; + + if(m_hisDataManage) + { + delete m_hisDataManage; + } + m_hisDataManage = NULL; + + delete ui; +} + +int CDevHisDataWidget::currentLocationId() +{ + return ui->m_locationComb->currentData().toString().section(",", 0, 0).toInt(); +} + +QString CDevHisDataWidget::currentLocationTag() +{ + return ui->m_locationComb->currentData().toString().section(",", 1, 1); +} + +QString CDevHisDataWidget::currentLocation() +{ + return ui->m_locationComb->currentText(); +} + +int CDevHisDataWidget::currentDevType() +{ + return ui->m_devTypeComb->currentData().toInt(); +} + +QString CDevHisDataWidget::currentDevTag() +{ + return ui->m_devComb->currentData().toString(); +} + +QString CDevHisDataWidget::currentDevice() +{ + return ui->m_devComb->currentText(); +} + +qint64 CDevHisDataWidget::currentStartTime() +{ + return ui->m_startTime->dateTime().toMSecsSinceEpoch(); +} + +qint64 CDevHisDataWidget::currentEndTime() +{ + return ui->m_endTime->dateTime().toMSecsSinceEpoch(); +} + +QString CDevHisDataWidget::hexTo26(int number) +{ + int p = 26; //进制 + int c = 0; //取余后的数字 + QString temp; + + while (true) { + c = number % p; + number = number / p; + if(number != 0) + { + temp.prepend(QString(QChar(0x41 + c))); + } + else + { + temp.prepend(QString(QChar(0x41 + c))); + break; + } + number--; + } + + return temp; +} + +void CDevHisDataWidget::initView() +{ + ui->m_printBtn->setVisible(false); + + ui->m_tableView->horizontalHeader()->setStretchLastSection(true); + ui->m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->m_tableView->verticalHeader()->setVisible(false); + + QDateTime dateTime = QDateTime::currentDateTime(); + QTime time = dateTime.time(); + time.setHMS(time.hour(), time.minute(), 0, 0); + dateTime.setTime(time); + ui->m_startTime->setDateTime(dateTime); + + time.setHMS(time.hour(), time.minute(), 59, 999); + dateTime.setTime(time); + ui->m_endTime->setDateTime(dateTime); +} + +void CDevHisDataWidget::initData() +{ + kbd_dbms::initTsdbApi(); + + m_dbInterface = new CDbInterface(); + m_hisDataManage = new CHisDataManage(Q_NULLPTR, m_dbInterface); + m_pHisEventThread = new QThread(); + m_hisDataManage->moveToThread(m_pHisEventThread); + connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); + connect(this, SIGNAL(sigReadHistoryPolymericData(std::vector*,int64_t,int64_t,int,EnComputeMethod,EnFillMethod)) + , m_hisDataManage, SLOT(queryHistoryPolymericData(std::vector*,int64_t,int64_t,int,EnComputeMethod,EnFillMethod))); + connect(m_hisDataManage, SIGNAL(sigHistoryPolymericData(std::vector*,std::vector*>*)) + , this, SLOT(updateHisPolymericData(std::vector*,std::vector*>*))); + m_pHisEventThread->start(); + + readDevManageXml(); + m_devHisModel = new CDevHisTableModel(ui->m_tableView); + ui->m_tableView->setModel(m_devHisModel); + + QMap locationMap; + QList locOrder; + m_dbInterface->readLocationInfo(locationMap, locOrder); + foreach (const int &locId, locOrder) { + QString value = locationMap.value(locId); + QString desc = value.section(",", 1, 1); + QString tag = value.section(",", 0, 0); + ui->m_locationComb->addItem(desc, QString("%1,%2").arg(locId).arg(tag)); + } + + QMap devTypeMap = m_dbInterface->readDevTypeInfo(); + QMap::const_iterator devTypeIter = devTypeMap.constBegin(); + for(; devTypeIter != devTypeMap.constEnd(); ++devTypeIter) + { + ui->m_devTypeComb->addItem(devTypeIter.value(), devTypeIter.key()); + } +} + +void CDevHisDataWidget::updateTableColumnWidth() +{ + int nWidth = ui->m_tableView->width(); + int nColmn = m_devHisModel->columnCount(); + for(int nIndex = 0; nIndex < nColmn; ++nIndex) + { + ui->m_tableView->setColumnWidth(nIndex, (nWidth/nColmn) - 2); + } +} + +void CDevHisDataWidget::readDevManageXml() +{ + QDomDocument document; + QDir dir(QCoreApplication::applicationDirPath()); + dir.cdUp(); + dir.cdUp(); + dir.cd(QString("data%1model").arg(QDir::separator())); + QFile file(QString("%1%2devManage.xml").arg(dir.path()).arg(QDir::separator())); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(!root.isNull()) + { + QDomNodeList nodeList = root.elementsByTagName("devType"); + for(int nodeIndex(0); nodeIndex < nodeList.size(); nodeIndex++) + { + QDomElement elem = nodeList.at(nodeIndex).toElement(); + if(!elem.isNull()) + { + QList vecDev; + int devType = elem.attribute("id").toInt(); + QDomNodeList itemList = elem.elementsByTagName("item"); + for(int itemIndex(0); itemIndex < itemList.size(); itemIndex++) + { + QDomNode node = itemList.at(itemIndex); + QDomElement element = node.toElement(); + if(!element.isNull()) + { + SDevManage dev; + dev.tag_name = element.attribute("tag"); + dev.description = element.attribute("description"); + dev.pointType = EnMeasPiontType(element.attribute("pointType").toInt()); + vecDev.append(dev); + } + } + m_devManageMap.insert(devType, vecDev); + } + } + } +} + +double CDevHisDataWidget::getValue(const VarMeasPiontVal &pointVal) +{ + double value = qSqrt(-1.); + if (typeid(boost::int32_t) == pointVal.type()) + { + value = (double)boost::get(pointVal); + } + else if (typeid(boost::float64_t) == pointVal.type()) + { + value = (double)boost::get(pointVal); + } + return value; +} + +QString CDevHisDataWidget::getDispValue(const SMeasPointKey &measPointKey, const VarMeasPiontVal &pointVal) +{ + if(measPointKey.m_enType == MPT_DI) + { + return m_dbInterface->queryDisplayValue(m_digTextMap.value(QString::fromLocal8Bit(measPointKey.m_pszTagName)), getValue(pointVal)); + } + + return QString::number(getValue(pointVal)); +} + +QList CDevHisDataWidget::getValueInitList(int size) +{ + QList list; + for(int nIndex = 0; nIndex < size; ++nIndex) + { + list.append("");//QString::number(qSqrt(-1.))); + } + return list; +} + +QList CDevHisDataWidget::getPointDescList() +{ + QList list; + QList::const_iterator iter = m_devManageMap.value(currentDevType()).constBegin(); + for(; iter != m_devManageMap.value(currentDevType()).constEnd(); ++iter) + { + list.append(iter->description); + } + return list; +} + +void CDevHisDataWidget::setEnable(bool enable) +{ + ui->m_locationComb->setEnabled(enable); + ui->m_devTypeComb->setEnabled(enable); + ui->m_devComb->setEnabled(enable); + ui->m_startTime->setEnabled(enable); + ui->m_endTime->setEnabled(enable); + ui->m_searchBtn->setEnabled(enable); +} + +void CDevHisDataWidget::on_m_locationComb_currentIndexChanged(int index) +{ + Q_UNUSED(index); + m_devHisModel->clear(); + + ui->m_devComb->clear(); + QMap devMap = m_dbInterface->readDevInfo(currentDevType(), currentLocationId()); + QMap::const_iterator iter = devMap.constBegin(); + for(; iter != devMap.constEnd(); ++iter) + { + ui->m_devComb->addItem(iter.value(), iter.key()); + } +} + +void CDevHisDataWidget::on_m_devTypeComb_currentIndexChanged(int index) +{ + on_m_locationComb_currentIndexChanged(index); //index无效 + + m_devHisModel->setHeader(getPointDescList()); + + updateTableColumnWidth(); +} + +void CDevHisDataWidget::on_m_devComb_currentIndexChanged(int index) +{ + Q_UNUSED(index); + m_digTextMap.clear(); + QList list = m_devManageMap.value(currentDevType()); + for(int nIndex = 0; nIndex < list.length(); ++nIndex) + { + if(list.at(nIndex).pointType == MPT_DI) + { + QString tag = currentDevTag() + "." + list.at(nIndex).tag_name; + m_digTextMap.insert(tag, m_dbInterface->readStateText(tag)); + } + } + + m_nanList.clear(); + m_nanList.append(getValueInitList(list.length())); +} + +void CDevHisDataWidget::on_m_startTime_dateTimeChanged(const QDateTime &dateTime) +{ + if(dateTime > ui->m_endTime->dateTime()) + { + ui->m_endTime->setDateTime(dateTime); + } +} + +void CDevHisDataWidget::on_m_endTime_dateTimeChanged(const QDateTime &dateTime) +{ + QDateTime dt = QDateTime::currentDateTime(); + if(dateTime > dt) + { + ui->m_endTime->setDateTime(dt); + } + if(dateTime < ui->m_startTime->dateTime()) + { + ui->m_startTime->setDateTime(dateTime); + } +} + +void CDevHisDataWidget::on_m_searchBtn_clicked() +{ + std::vector *vecMpKey = new std::vector(); + + QString devTag = currentDevTag(); + foreach (SDevManage dev, m_devManageMap.value(currentDevType())) { + SMeasPointKey key; + std::string tmp = QString("%1.%2").arg(devTag).arg(dev.tag_name).toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = dev.pointType; + vecMpKey->push_back(key); + } + + setEnable(false); + emit sigReadHistoryPolymericData(vecMpKey, currentStartTime(), currentEndTime(), 1 * 60 * 1000, CM_LAST, FM_PREVIOUS); +} + +void CDevHisDataWidget::on_m_clearBtn_clicked() +{ + m_devHisModel->clear(); +} + +void CDevHisDataWidget::on_m_excelBtn_clicked() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("保存"), "", "*.xlsx"); + if(filePath.isEmpty()) + return; + + QXlsx::Document xlsx; + + for(int col = 0; col < m_devHisModel->columnCount(); col++) + { + xlsx.write(hexTo26(col)+"1", m_devHisModel->headerData(col, Qt::Horizontal, Qt::DisplayRole)); + xlsx.setColumnWidth(col+1, (ui->m_tableView->columnWidth(col))/7); + } + + for(int row = 0; row < m_devHisModel->rowCount(); row++) + { + for(int col = 0; col < m_devHisModel->columnCount(); col++) + { + QModelIndex index = m_devHisModel->index(row, col); + xlsx.write(hexTo26(col)+QString::number(row+2), m_devHisModel->data(index)); + } + } + + if(xlsx.saveAs(filePath)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } +} + +void CDevHisDataWidget::on_m_pdfBtn_clicked() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("保存"), "", "*.pdf"); + if(filePath.isEmpty()) + return; + + QTableView view(ui->m_tableView); + view.setModel(ui->m_tableView->model()); + + QPrinter printer; + printer.setPageSize(QPagedPaintDevice::A4); + printer.setPageOrientation(QPageLayout::Landscape); + printer.setOutputFileName(filePath); + printer.setOutputFormat(QPrinter::PdfFormat); + + CTableViewPrinter viewPrinter(&view); + if(viewPrinter.print(&printer)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } +} + +void CDevHisDataWidget::on_m_printBtn_clicked() +{ +} + +void CDevHisDataWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult) +{ +// qDebug() << "updateHisOriginalData begin: " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); + + QMap map; + for(int nIndex = 0; nIndex < (int)vecResult->size(); ++nIndex) + { + std::vector::iterator iter = vecResult->at(nIndex)->begin(); + for(; iter != vecResult->at(nIndex)->end(); ++iter) + { + if(iter->m_nTime < currentStartTime() || iter->m_nTime > currentEndTime()) + { + continue; + } + + if(map.contains(iter->m_nTime)) + { + map[iter->m_nTime].valueList.replace(nIndex, getDispValue(vecMpKey->at(nIndex), iter->m_varValue)); + } + else + { + SHisData hisData; + hisData.location = currentLocation(); + hisData.device = currentDevice(); + hisData.valueList.append(m_nanList); + hisData.valueList.replace(nIndex, getDispValue(vecMpKey->at(nIndex), iter->m_varValue)); + map.insert(iter->m_nTime, hisData); + } + } + } + + m_devHisModel->update(map); + +// qDebug() << "updateHisOriginalData end1: " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); + + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(vecResult->end() != res) + { + delete (*res); + ++res; + } + vecResult->clear(); + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; + + setEnable(true); + +// qDebug() << "updateHisOriginalData end2: " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); +} + +void CDevHisDataWidget::resizeEvent(QResizeEvent *event) +{ + if(!m_editModel) + { + updateTableColumnWidth(); + } + QWidget::resizeEvent(event); +} + diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.h b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.h index 3cef71f6..db56f48b 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.h +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.h @@ -1,83 +1,83 @@ -#ifndef CDEVHISDATAWIDGET_H -#define CDEVHISDATAWIDGET_H - -#include -#include "CDbInterface.h" -#include "CHisDataManage.h" -#include "CDevHisTableModel.h" - -namespace Ui { -class CDevHisDataWidget; -} - -struct SDevManage -{ - QString tag_name; - QString description; - kbd_dbms::EnMeasPiontType pointType; //< MPT_AI ,MPT_DI ,MPT_MIX ,MPT_ACC -}; - -class CDevHisDataWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CDevHisDataWidget(bool editMode, QVector ptrVec, QWidget *parent = 0); - ~CDevHisDataWidget(); - - int currentLocationId(); - QString currentLocationTag(); - QString currentLocation(); - int currentDevType(); - QString currentDevTag(); - QString currentDevice(); - qint64 currentStartTime(); - qint64 currentEndTime(); - - QString hexTo26(int number); - -signals: - void sigReadHistoryPolymericData(std::vector *vecMpKey, int64_t nTimeBegin, int64_t nTimeEnd, int nGroupByMs, EnComputeMethod method, EnFillMethod fill); - -private slots: - void on_m_locationComb_currentIndexChanged(int index); - void on_m_devTypeComb_currentIndexChanged(int index); - void on_m_devComb_currentIndexChanged(int index); - void on_m_startTime_dateTimeChanged(const QDateTime &dateTime); - void on_m_endTime_dateTimeChanged(const QDateTime &dateTime); - void on_m_searchBtn_clicked(); - void on_m_clearBtn_clicked(); - void on_m_excelBtn_clicked(); - void on_m_pdfBtn_clicked(); - void on_m_printBtn_clicked(); - void updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult); - void updateTableColumnWidth(); - -protected: - void resizeEvent(QResizeEvent *event); - -private: - void initView(); - void initData(); - - void readDevManageXml(); - double getValue(const VarMeasPiontVal &pointVal); - QString getDispValue(const SMeasPointKey& measPointKey, const VarMeasPiontVal &pointVal); - QList getValueInitList(int size); - QList getPointDescList(); - - void setEnable(bool enable); - -private: - Ui::CDevHisDataWidget *ui; - CDbInterface *m_dbInterface; - QThread *m_pHisEventThread; - CHisDataManage *m_hisDataManage; - CDevHisTableModel *m_devHisModel; - bool m_editModel; - QMap> m_devManageMap; - QMap m_digTextMap; //< tag_name,state_text_name - QList m_nanList; -}; - -#endif // CDEVHISDATAWIDGET_H +#ifndef CDEVHISDATAWIDGET_H +#define CDEVHISDATAWIDGET_H + +#include +#include "CDbInterface.h" +#include "CHisDataManage.h" +#include "CDevHisTableModel.h" + +namespace Ui { +class CDevHisDataWidget; +} + +struct SDevManage +{ + QString tag_name; + QString description; + kbd_dbms::EnMeasPiontType pointType; //< MPT_AI ,MPT_DI ,MPT_MIX ,MPT_ACC +}; + +class CDevHisDataWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CDevHisDataWidget(bool editMode, QVector ptrVec, QWidget *parent = 0); + ~CDevHisDataWidget(); + + int currentLocationId(); + QString currentLocationTag(); + QString currentLocation(); + int currentDevType(); + QString currentDevTag(); + QString currentDevice(); + qint64 currentStartTime(); + qint64 currentEndTime(); + + QString hexTo26(int number); + +signals: + void sigReadHistoryPolymericData(std::vector *vecMpKey, int64_t nTimeBegin, int64_t nTimeEnd, int nGroupByMs, EnComputeMethod method, EnFillMethod fill); + +private slots: + void on_m_locationComb_currentIndexChanged(int index); + void on_m_devTypeComb_currentIndexChanged(int index); + void on_m_devComb_currentIndexChanged(int index); + void on_m_startTime_dateTimeChanged(const QDateTime &dateTime); + void on_m_endTime_dateTimeChanged(const QDateTime &dateTime); + void on_m_searchBtn_clicked(); + void on_m_clearBtn_clicked(); + void on_m_excelBtn_clicked(); + void on_m_pdfBtn_clicked(); + void on_m_printBtn_clicked(); + void updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult); + void updateTableColumnWidth(); + +protected: + void resizeEvent(QResizeEvent *event); + +private: + void initView(); + void initData(); + + void readDevManageXml(); + double getValue(const VarMeasPiontVal &pointVal); + QString getDispValue(const SMeasPointKey& measPointKey, const VarMeasPiontVal &pointVal); + QList getValueInitList(int size); + QList getPointDescList(); + + void setEnable(bool enable); + +private: + Ui::CDevHisDataWidget *ui; + CDbInterface *m_dbInterface; + QThread *m_pHisEventThread; + CHisDataManage *m_hisDataManage; + CDevHisTableModel *m_devHisModel; + bool m_editModel; + QMap> m_devManageMap; + QMap m_digTextMap; //< tag_name,state_text_name + QList m_nanList; +}; + +#endif // CDEVHISDATAWIDGET_H diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.ui b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.ui index a9ecdb49..5aaa28de 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.ui +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataWidget.ui @@ -1,398 +1,398 @@ - - - CDevHisDataWidget - - - - 0 - 0 - 802 - 520 - - - - CDevHisDataWidget - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - 16777215 - 60 - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 0 - - - 3 - - - 0 - - - 0 - - - 3 - - - 0 - - - - - 3 - - - 3 - - - 3 - - - 0 - - - 0 - - - - - - 80 - 0 - - - - - 60 - 16777215 - - - - 区域: - - - - - - - - 120 - 0 - - - - - - - - - 80 - 0 - - - - - 60 - 16777215 - - - - 开始时间: - - - - - - - - 120 - 0 - - - - - 2219 - 12 - 31 - - - - - 1970 - 1 - 1 - - - - yyyy-MM-dd HH:mm - - - true - - - - - - - - - 3 - - - 3 - - - - - - 80 - 0 - - - - - 60 - 16777215 - - - - 设备类型: - - - - - - - - 120 - 0 - - - - - - - - - 80 - 0 - - - - - 60 - 16777215 - - - - 结束时间: - - - - - - - - 120 - 0 - - - - - 2219 - 12 - 31 - - - - - 1970 - 1 - 1 - - - - yyyy-MM-dd HH:mm - - - true - - - - - - - - - 3 - - - - - - 80 - 0 - - - - - 60 - 16777215 - - - - 设备名称: - - - - - - - - 120 - 0 - - - - - - - - Qt::Horizontal - - - - 88 - 20 - - - - - - - - 查询 - - - - - - - - - Qt::Horizontal - - - - 217 - 48 - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - - - Excel - - - - - - - Pdf - - - - - - - 打印 - - - - - - - Qt::Horizontal - - - - 188 - 20 - - - - - - - - 清除 - - - - - - - - - - - - + + + CDevHisDataWidget + + + + 0 + 0 + 802 + 520 + + + + CDevHisDataWidget + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + 16777215 + 60 + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + 0 + + + 3 + + + 0 + + + 0 + + + 3 + + + 0 + + + + + 3 + + + 3 + + + 3 + + + 0 + + + 0 + + + + + + 80 + 0 + + + + + 60 + 16777215 + + + + 区域: + + + + + + + + 120 + 0 + + + + + + + + + 80 + 0 + + + + + 60 + 16777215 + + + + 开始时间: + + + + + + + + 120 + 0 + + + + + 2219 + 12 + 31 + + + + + 1970 + 1 + 1 + + + + yyyy-MM-dd HH:mm + + + true + + + + + + + + + 3 + + + 3 + + + + + + 80 + 0 + + + + + 60 + 16777215 + + + + 设备类型: + + + + + + + + 120 + 0 + + + + + + + + + 80 + 0 + + + + + 60 + 16777215 + + + + 结束时间: + + + + + + + + 120 + 0 + + + + + 2219 + 12 + 31 + + + + + 1970 + 1 + 1 + + + + yyyy-MM-dd HH:mm + + + true + + + + + + + + + 3 + + + + + + 80 + 0 + + + + + 60 + 16777215 + + + + 设备名称: + + + + + + + + 120 + 0 + + + + + + + + Qt::Horizontal + + + + 88 + 20 + + + + + + + + 查询 + + + + + + + + + Qt::Horizontal + + + + 217 + 48 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + Excel + + + + + + + Pdf + + + + + + + 打印 + + + + + + + Qt::Horizontal + + + + 188 + 20 + + + + + + + + 清除 + + + + + + + + + + + + diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisTableModel.cpp b/product/src/gui/plugin/DevHisDataWidget/CDevHisTableModel.cpp index a1cee1ac..5fa2f027 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisTableModel.cpp +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisTableModel.cpp @@ -1,126 +1,126 @@ -#include "CDevHisTableModel.h" -#include - -CDevHisTableModel::CDevHisTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ -} - -void CDevHisTableModel::setHeader(const QList &headList) -{ - beginResetModel(); - m_header.clear(); - m_header << tr("日期/时间") << tr("设备名称") << tr("所属区域"); - m_header << headList; - endResetModel(); -} - -void CDevHisTableModel::update(const QMap &dataMap) -{ - beginResetModel(); - m_keyList.clear(); - m_valueList.clear(); - m_keyList = dataMap.keys(); - m_valueList = dataMap.values(); -// qDebug() << dataMap.size(); - endResetModel(); -} - -void CDevHisTableModel::clear() -{ - beginResetModel(); - m_keyList.clear(); - m_valueList.clear(); - endResetModel(); -} - -QVariant CDevHisTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_header.at(section); - } - } - return QVariant(); -} - -int CDevHisTableModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_keyList.size(); -} - -int CDevHisTableModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.count(); -} - -QVariant CDevHisTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.row() > m_keyList.size()) - return QVariant(); - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - - if(Qt::DisplayRole != role) - { - return QVariant(); - } - -// qDebug() << "data: " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); - if(index.column() > 2) - { - const QList &data = m_valueList.at(index.row()).valueList; - if(index.column() - 3 >= 0 && - index.column() - 3 < data.length()) - { - return data.at(index.column() - 3); - } - } - - switch (index.column()) - { - case 0: - { - return QDateTime::fromMSecsSinceEpoch(m_keyList.at(index.row())).toString("yyyy-MM-dd hh:mm"); - } - break; - case 1: - { - return m_valueList.at(index.row()).device; - } - break; - case 2: - { - return m_valueList.at(index.row()).location; - } - break; - default: - break; - } - - return QVariant(); -} - -bool CDevHisTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_UNUSED(value); - Q_UNUSED(role); - - if(!index.isValid()) - { - return false; - } - - return true; -} +#include "CDevHisTableModel.h" +#include + +CDevHisTableModel::CDevHisTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ +} + +void CDevHisTableModel::setHeader(const QList &headList) +{ + beginResetModel(); + m_header.clear(); + m_header << tr("日期/时间") << tr("设备名称") << tr("所属区域"); + m_header << headList; + endResetModel(); +} + +void CDevHisTableModel::update(const QMap &dataMap) +{ + beginResetModel(); + m_keyList.clear(); + m_valueList.clear(); + m_keyList = dataMap.keys(); + m_valueList = dataMap.values(); +// qDebug() << dataMap.size(); + endResetModel(); +} + +void CDevHisTableModel::clear() +{ + beginResetModel(); + m_keyList.clear(); + m_valueList.clear(); + endResetModel(); +} + +QVariant CDevHisTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); +} + +int CDevHisTableModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_keyList.size(); +} + +int CDevHisTableModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.count(); +} + +QVariant CDevHisTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() > m_keyList.size()) + return QVariant(); + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + +// qDebug() << "data: " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); + if(index.column() > 2) + { + const QList &data = m_valueList.at(index.row()).valueList; + if(index.column() - 3 >= 0 && + index.column() - 3 < data.length()) + { + return data.at(index.column() - 3); + } + } + + switch (index.column()) + { + case 0: + { + return QDateTime::fromMSecsSinceEpoch(m_keyList.at(index.row())).toString("yyyy-MM-dd hh:mm"); + } + break; + case 1: + { + return m_valueList.at(index.row()).device; + } + break; + case 2: + { + return m_valueList.at(index.row()).location; + } + break; + default: + break; + } + + return QVariant(); +} + +bool CDevHisTableModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(value); + Q_UNUSED(role); + + if(!index.isValid()) + { + return false; + } + + return true; +} diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisTableModel.h b/product/src/gui/plugin/DevHisDataWidget/CDevHisTableModel.h index 8ced1ed9..6a6d9ed5 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisTableModel.h +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisTableModel.h @@ -1,41 +1,41 @@ -#ifndef CDEVHISTABLEMODEL_H -#define CDEVHISTABLEMODEL_H - -#include -#include - -struct SHisData -{ - QString location; - QString device; - QList valueList; -}; - -class CDevHisTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CDevHisTableModel(QObject *parent = nullptr); - - void setHeader(const QList& headList); - - void update(const QMap& dataMap); - - void clear(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - -private: - QStringList m_header; - QList m_keyList; - QList m_valueList; -}; - -#endif // CDEVHISTABLEMODEL_H +#ifndef CDEVHISTABLEMODEL_H +#define CDEVHISTABLEMODEL_H + +#include +#include + +struct SHisData +{ + QString location; + QString device; + QList valueList; +}; + +class CDevHisTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CDevHisTableModel(QObject *parent = nullptr); + + void setHeader(const QList& headList); + + void update(const QMap& dataMap); + + void clear(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + +private: + QStringList m_header; + QList m_keyList; + QList m_valueList; +}; + +#endif // CDEVHISTABLEMODEL_H diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisTableView.cpp b/product/src/gui/plugin/DevHisDataWidget/CDevHisTableView.cpp index ddfd3926..5e0944b6 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisTableView.cpp +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisTableView.cpp @@ -1,7 +1,7 @@ -#include "CDevHisTableView.h" - -CDevHisTableView::CDevHisTableView(QWidget *parent) - :QTableView(parent) -{ - -} +#include "CDevHisTableView.h" + +CDevHisTableView::CDevHisTableView(QWidget *parent) + :QTableView(parent) +{ + +} diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisTableView.h b/product/src/gui/plugin/DevHisDataWidget/CDevHisTableView.h index f4dd02ed..c029885c 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisTableView.h +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisTableView.h @@ -1,14 +1,14 @@ -#ifndef CDEVHISTABLEVIEW_H -#define CDEVHISTABLEVIEW_H - -#include - -class CDevHisTableView : public QTableView -{ - Q_OBJECT -public: - CDevHisTableView(QWidget *parent = Q_NULLPTR); - -}; - -#endif // CDEVHISTABLEVIEW_H +#ifndef CDEVHISTABLEVIEW_H +#define CDEVHISTABLEVIEW_H + +#include + +class CDevHisTableView : public QTableView +{ + Q_OBJECT +public: + CDevHisTableView(QWidget *parent = Q_NULLPTR); + +}; + +#endif // CDEVHISTABLEVIEW_H diff --git a/product/src/gui/plugin/DevHisDataWidget/CHisDataManage.cpp b/product/src/gui/plugin/DevHisDataWidget/CHisDataManage.cpp index 6d1e0191..5f685d48 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CHisDataManage.cpp +++ b/product/src/gui/plugin/DevHisDataWidget/CHisDataManage.cpp @@ -1,114 +1,114 @@ -#include "CHisDataManage.h" -#include "public/pub_logger_api/logger.h" - -#define SAMPLE_CYC_MIN 5 //MIN - -CHisDataManage::CHisDataManage(QObject *parent, CDbInterface *dbInterface) - : QObject(parent), - m_dbInterface(dbInterface), - m_tsdbConnPtr((CTsdbConn*)nullptr) -{ -} - -CHisDataManage::~CHisDataManage() -{ - m_tsdbConnPtr = boost::shared_ptr(Q_NULLPTR); - releaseTsdbApi(); - if(m_dbInterface) - { - m_dbInterface = NULL; - } -} - -bool CHisDataManage::getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr) -{ - if(m_tsdbConnPtr != NULL) - { - if(m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - } - else - { - m_tsdbConnPtr = getOneUseableConn(true); - if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - else - { - m_tsdbConnPtr = getOneUseableConn(false); - if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - } - } - return false; -} - -void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, int64_t nTimeBegin, int64_t nTimeEnd, int nGroupByMs, EnComputeMethod method, EnFillMethod fill) -{ - int64_t nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; - std::vector *> *vecResult = new std::vector *>(); - - CTsdbConnPtr tsdbConnPtr; - if(getValidTsdbConnPtr(tsdbConnPtr)) - { - std::vector vecNotHaveStatus; - for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) - { - QString strMeasType; - switch (vecMpKey->at(nIndex).m_enType) - { - case MPT_AI: //< 模拟量 - { - strMeasType = MENU_STATE_AI_INVALID; - break; - } - case MPT_DI: //< 数字量 - { - strMeasType = MENU_STATE_DI_INVALID; - break; - } - case MPT_MIX: //< 混合量 - { - break; - } - case MPT_ACC: //< 累计(电度)量 - { - break; - } - default: - return; - } - - int nInvalidValue = 0x01; - if(m_dbInterface->queryStateActualValue(strMeasType)) - { - nInvalidValue <<= m_dbInterface->queryStateActualValue(strMeasType); - vecNotHaveStatus.push_back(nInvalidValue); - } - else - { - vecNotHaveStatus.push_back(0); - } - vecResult->push_back(new std::vector()); - } - - if(!getHisValue(*tsdbConnPtr, 10000, *vecMpKey, nTimeBegin - nIntervalSecs, nTimeEnd + nIntervalSecs, NULL, &vecNotHaveStatus, NULL, NULL, NULL, method, nGroupByMs, fill, *vecResult)) - { - LOGINFO("DevHisDataWidget CHisDataManage::queryHistoryOriginalData: 查询超时!"); - } - } - else - { - LOGINFO("DevHisDataWidget CHisDataManage::queryHistoryOriginalData: 未获取到有效的TSDB连接!"); - } - - emit sigHistoryPolymericData(vecMpKey, vecResult); -} +#include "CHisDataManage.h" +#include "public/pub_logger_api/logger.h" + +#define SAMPLE_CYC_MIN 5 //MIN + +CHisDataManage::CHisDataManage(QObject *parent, CDbInterface *dbInterface) + : QObject(parent), + m_dbInterface(dbInterface), + m_tsdbConnPtr((CTsdbConn*)nullptr) +{ +} + +CHisDataManage::~CHisDataManage() +{ + m_tsdbConnPtr = boost::shared_ptr(Q_NULLPTR); + releaseTsdbApi(); + if(m_dbInterface) + { + m_dbInterface = NULL; + } +} + +bool CHisDataManage::getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr) +{ + if(m_tsdbConnPtr != NULL) + { + if(m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + else + { + m_tsdbConnPtr = getOneUseableConn(true); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + else + { + m_tsdbConnPtr = getOneUseableConn(false); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + } + return false; +} + +void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, int64_t nTimeBegin, int64_t nTimeEnd, int nGroupByMs, EnComputeMethod method, EnFillMethod fill) +{ + int64_t nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + std::vector *> *vecResult = new std::vector *>(); + + CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + std::vector vecNotHaveStatus; + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + QString strMeasType; + switch (vecMpKey->at(nIndex).m_enType) + { + case MPT_AI: //< 模拟量 + { + strMeasType = MENU_STATE_AI_INVALID; + break; + } + case MPT_DI: //< 数字量 + { + strMeasType = MENU_STATE_DI_INVALID; + break; + } + case MPT_MIX: //< 混合量 + { + break; + } + case MPT_ACC: //< 累计(电度)量 + { + break; + } + default: + return; + } + + int nInvalidValue = 0x01; + if(m_dbInterface->queryStateActualValue(strMeasType)) + { + nInvalidValue <<= m_dbInterface->queryStateActualValue(strMeasType); + vecNotHaveStatus.push_back(nInvalidValue); + } + else + { + vecNotHaveStatus.push_back(0); + } + vecResult->push_back(new std::vector()); + } + + if(!getHisValue(*tsdbConnPtr, 10000, *vecMpKey, nTimeBegin - nIntervalSecs, nTimeEnd + nIntervalSecs, NULL, &vecNotHaveStatus, NULL, NULL, NULL, method, nGroupByMs, fill, *vecResult)) + { + LOGINFO("DevHisDataWidget CHisDataManage::queryHistoryOriginalData: 查询超时!"); + } + } + else + { + LOGINFO("DevHisDataWidget CHisDataManage::queryHistoryOriginalData: 未获取到有效的TSDB连接!"); + } + + emit sigHistoryPolymericData(vecMpKey, vecResult); +} diff --git a/product/src/gui/plugin/DevHisDataWidget/CHisDataManage.h b/product/src/gui/plugin/DevHisDataWidget/CHisDataManage.h index f813c20f..c3ed0534 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CHisDataManage.h +++ b/product/src/gui/plugin/DevHisDataWidget/CHisDataManage.h @@ -1,34 +1,34 @@ -#ifndef CHISDATAMANAGE_H -#define CHISDATAMANAGE_H - -#include -#include -#include "tsdb_api/TsdbApi.h" -#include "db_his_query_api/DbHisQueryBase.h" -#include "db_his_query_api/DbHisQueryApi.h" -#include "CDbInterface.h" - -using namespace kbd_dbms; -class CHisDataManage : public QObject -{ - Q_OBJECT -public: - explicit CHisDataManage(QObject *parent = nullptr, CDbInterface* dbInterface = nullptr); - ~CHisDataManage(); - -public slots: - void queryHistoryPolymericData(std::vector *vecMpKey, int64_t nTimeBegin, int64_t nTimeEnd, int nGroupByMs, EnComputeMethod method, EnFillMethod fill); - -signals: - void sigHistoryPolymericData(std::vector *vecMpKey, - std::vector *> *vecResult); - -private: - bool getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr); - -private: - CDbInterface *m_dbInterface; - kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; -}; - -#endif // CHISDATAMANAGE_H +#ifndef CHISDATAMANAGE_H +#define CHISDATAMANAGE_H + +#include +#include +#include "tsdb_api/TsdbApi.h" +#include "db_his_query_api/DbHisQueryBase.h" +#include "db_his_query_api/DbHisQueryApi.h" +#include "CDbInterface.h" + +using namespace kbd_dbms; +class CHisDataManage : public QObject +{ + Q_OBJECT +public: + explicit CHisDataManage(QObject *parent = nullptr, CDbInterface* dbInterface = nullptr); + ~CHisDataManage(); + +public slots: + void queryHistoryPolymericData(std::vector *vecMpKey, int64_t nTimeBegin, int64_t nTimeEnd, int nGroupByMs, EnComputeMethod method, EnFillMethod fill); + +signals: + void sigHistoryPolymericData(std::vector *vecMpKey, + std::vector *> *vecResult); + +private: + bool getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr); + +private: + CDbInterface *m_dbInterface; + kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; +}; + +#endif // CHISDATAMANAGE_H diff --git a/product/src/gui/plugin/DevHisDataWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/DevHisDataWidget/CTableViewPrinter.cpp index bedfa772..6da493f1 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/DevHisDataWidget/CTableViewPrinter.cpp @@ -1,128 +1,128 @@ -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include - -CTableViewPrinter::CTableViewPrinter(QTableView *view) - : m_pView(view) -{ - m_pModel = view->model(); -} - -bool CTableViewPrinter::print(QPrinter * printer) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - - qreal marginHorizontal = 20; - qreal marginVertical = 20; - - QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); - printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); - - int length = 0; - horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); - for(int nSection(3); nSection < horizontalHeader->count(); nSection++) - { - length += horizontalHeader->sectionSize(nSection); - } - horizontalHeader->resizeSection(0, (horizontalHeader->width() - length)/3); - horizontalHeader->resizeSection(1, (horizontalHeader->width() - length)/3); - horizontalHeader->resizeSection(2, (horizontalHeader->width() - length)/3); - - QPainter painter(printer); - if(!painter.isActive()) - { - return false; - } - - renderHeader(painter); - - int offset = 0; - int currentPage = 0; - int horizontalHeaderHeight = horizontalHeader->height(); - for(int row(0); row < m_pModel->rowCount(); row++) - { - if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) - { - horizontalHeaderHeight = 0; - } - - if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) - { - printer->newPage(); - currentPage++; - offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - } - - for(int column(0); column < m_pModel->columnCount(); column++) - { - int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - int rowHeight = m_pView->rowHeight(row); - int columnWidth = m_pView->columnWidth(column); - - //< draw item - QStyleOptionViewItem opt; - opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); - painter.save(); - painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); - painter.restore(); - - //< Vertical Line - if(column == 0) - { - QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - //< Horizontal Line - int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; - QPoint left(verticalHeader->width(), rowPosition); - QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); - drawGridLine(&painter, left, right); - - } - return true; -} - -void CTableViewPrinter::renderHeader(QPainter &painter) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - for(int column(0); column < horizontalHeader->count(); column++) - { - painter.save(); - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); - painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); - painter.restore(); - } - int columnPosition = horizontalHeader->width() + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); -} - -void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) -{ - painter->save(); - QStyleOptionViewItem opt; - const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); - const QColor gridColor = static_cast(gridHint); - painter->setPen(gridColor); - painter->drawLine(p1, p2); - painter->restore(); -} +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include + +CTableViewPrinter::CTableViewPrinter(QTableView *view) + : m_pView(view) +{ + m_pModel = view->model(); +} + +bool CTableViewPrinter::print(QPrinter * printer) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); + printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + + int length = 0; + horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); + for(int nSection(3); nSection < horizontalHeader->count(); nSection++) + { + length += horizontalHeader->sectionSize(nSection); + } + horizontalHeader->resizeSection(0, (horizontalHeader->width() - length)/3); + horizontalHeader->resizeSection(1, (horizontalHeader->width() - length)/3); + horizontalHeader->resizeSection(2, (horizontalHeader->width() - length)/3); + + QPainter painter(printer); + if(!painter.isActive()) + { + return false; + } + + renderHeader(painter); + + int offset = 0; + int currentPage = 0; + int horizontalHeaderHeight = horizontalHeader->height(); + for(int row(0); row < m_pModel->rowCount(); row++) + { + if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) + { + horizontalHeaderHeight = 0; + } + + if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) + { + printer->newPage(); + currentPage++; + offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + } + + for(int column(0); column < m_pModel->columnCount(); column++) + { + int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + int rowHeight = m_pView->rowHeight(row); + int columnWidth = m_pView->columnWidth(column); + + //< draw item + QStyleOptionViewItem opt; + opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); + painter.save(); + painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); + painter.restore(); + + //< Vertical Line + if(column == 0) + { + QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + //< Horizontal Line + int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; + QPoint left(verticalHeader->width(), rowPosition); + QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); + drawGridLine(&painter, left, right); + + } + return true; +} + +void CTableViewPrinter::renderHeader(QPainter &painter) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + for(int column(0); column < horizontalHeader->count(); column++) + { + painter.save(); + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); + painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); + painter.restore(); + } + int columnPosition = horizontalHeader->width() + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); +} + +void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + QStyleOptionViewItem opt; + const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); + const QColor gridColor = static_cast(gridHint); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} diff --git a/product/src/gui/plugin/DevHisDataWidget/CTableViewPrinter.h b/product/src/gui/plugin/DevHisDataWidget/CTableViewPrinter.h index 66c17c5a..0a80e9fb 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/DevHisDataWidget/CTableViewPrinter.h @@ -1,24 +1,24 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H - -class QPointF; -class QPainter; -class QPrinter; -class QTableView; -class QAbstractItemModel; - -class CTableViewPrinter -{ -public: - explicit CTableViewPrinter(QTableView * view); - - bool print(QPrinter *printer); - void renderHeader(QPainter &painter); - void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); - -private: - QTableView * m_pView; - QAbstractItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H + +class QPointF; +class QPainter; +class QPrinter; +class QTableView; +class QAbstractItemModel; + +class CTableViewPrinter +{ +public: + explicit CTableViewPrinter(QTableView * view); + + bool print(QPrinter *printer); + void renderHeader(QPainter &painter); + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + +private: + QTableView * m_pView; + QAbstractItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/DevHisDataWidget/DevHisDataWidget.pro b/product/src/gui/plugin/DevHisDataWidget/DevHisDataWidget.pro index 98a20694..bbaeb76c 100644 --- a/product/src/gui/plugin/DevHisDataWidget/DevHisDataWidget.pro +++ b/product/src/gui/plugin/DevHisDataWidget/DevHisDataWidget.pro @@ -1,65 +1,65 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-11-08T11:21:39 -# -#------------------------------------------------- - -QT += core gui sql xml printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = DevHisDataWidget -TEMPLATE = lib - -CONFIG += plugin -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - CDevHisDataWidget.cpp \ - CDbInterface.cpp \ - CHisDataManage.cpp \ - CDevHisTableModel.cpp \ - CTableViewPrinter.cpp \ - CDevHisDataPluginWidget.cpp - -HEADERS += \ - CDevHisDataWidget.h \ - CDbInterface.h \ - CHisDataManage.h \ - CDevHisTableModel.h \ - CTableViewPrinter.h \ - CDevHisDataPluginWidget.h - -FORMS += \ - CDevHisDataWidget.ui - -LIBS += \ - -ldb_base_api \ - -ldb_api_ex \ - -lrdb_api \ - -lpub_sysinfo_api \ - -lpub_logger_api \ - -llog4cplus \ - -ltsdb_api \ - -ldb_his_query_api \ - -lmodel_excel \ - -lpub_utility_api - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2019-11-08T11:21:39 +# +#------------------------------------------------- + +QT += core gui sql xml printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = DevHisDataWidget +TEMPLATE = lib + +CONFIG += plugin +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + CDevHisDataWidget.cpp \ + CDbInterface.cpp \ + CHisDataManage.cpp \ + CDevHisTableModel.cpp \ + CTableViewPrinter.cpp \ + CDevHisDataPluginWidget.cpp + +HEADERS += \ + CDevHisDataWidget.h \ + CDbInterface.h \ + CHisDataManage.h \ + CDevHisTableModel.h \ + CTableViewPrinter.h \ + CDevHisDataPluginWidget.h + +FORMS += \ + CDevHisDataWidget.ui + +LIBS += \ + -ldb_base_api \ + -ldb_api_ex \ + -lrdb_api \ + -lpub_sysinfo_api \ + -lpub_logger_api \ + -llog4cplus \ + -ltsdb_api \ + -ldb_his_query_api \ + -lmodel_excel \ + -lpub_utility_api + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/DevHisDataWidget/main.cpp b/product/src/gui/plugin/DevHisDataWidget/main.cpp index 71d470b7..6e696473 100644 --- a/product/src/gui/plugin/DevHisDataWidget/main.cpp +++ b/product/src/gui/plugin/DevHisDataWidget/main.cpp @@ -1,44 +1,44 @@ -#include -#include "CDevHisDataWidget.h" -#include "pub_logger_api/logger.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - kbd_service::CDpcdaForApp::initGlobalThread(); - - { - LOGINFO("=========================== CDevHisDataWidget ==========================="); - QApplication app(argc, argv); - - CDevHisDataWidget w; - w.show(); - - app.exec(); - } - - kbd_service::CDpcdaForApp::releaseGlobalThread(); - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include +#include "CDevHisDataWidget.h" +#include "pub_logger_api/logger.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + kbd_service::CDpcdaForApp::initGlobalThread(); + + { + LOGINFO("=========================== CDevHisDataWidget ==========================="); + QApplication app(argc, argv); + + CDevHisDataWidget w; + w.show(); + + app.exec(); + } + + kbd_service::CDpcdaForApp::releaseGlobalThread(); + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/DevRealDataWidget/CDbInterface.cpp b/product/src/gui/plugin/DevRealDataWidget/CDbInterface.cpp index 2ef18a89..2321ed8a 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDbInterface.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CDbInterface.cpp @@ -1,598 +1,598 @@ -#include "CDbInterface.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_dbms; -using namespace kbd_public; - -CDbInterface *CDbInterface::m_pInstance = NULL; - -CDbInterface::CDbInterface() -{ - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - readUnitInfo(); - readDiStatus(); - readAiStatus(); - loadRTLocation(); - loadDeviceInfo(); -} - -CDbInterface *CDbInterface::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CDbInterface(); - } - return m_pInstance; -} - -void CDbInterface::destory() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - m_mapUnit.clear(); - m_mapAiStatus.clear(); - m_mapDiStatus.clear(); - m_pInstance = NULL; - delete this; -} - -QMap CDbInterface::locationInfo() -{ - return m_locationInfo; -} - -QString CDbInterface::getLocationDesc(const int &locId) -{ - return m_locationInfo.value(locId); -} - -QList CDbInterface::getLocationOrder() -{ - return m_locOrder; -} - -bool CDbInterface::queryDevGroupInfoList(const int &nLocId, const int &nSubId, QList > &devgList) -{ - if(nLocId == CN_InvalidLocationId) - { - return false; - } - QSqlQuery query; - QString sqlSequenceQuery; - if(nSubId == CN_InvalidSubsystemId) - { - //< 所有专业 - sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1 order by dev_group_no asc; ") - .arg(nLocId); - } - else - { - sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1 and sub_system = %2 order by dev_group_no asc; ") - .arg(nLocId).arg(nSubId); - } - if(!m_pReadDb->execute(sqlSequenceQuery, query)) - { - LOGINFO("查找位置[%d],专业[%d]下的设备组失败!",nLocId,nSubId); - return false; - } - while(query.next()) - { - QPair pair; - pair.first = query.value(0).toString(); - pair.second = query.value(1).toString(); - devgList.append(pair); - } - return true; -} - -QMap CDbInterface::deviceInfo(const QString &devGroupName) -{ - return m_devGDevInfoMap.value(devGroupName, QMap()); -} - -QList CDbInterface::deviceInfoByDevg(const QString &devGroupName) -{ - return m_devGDevInfoMap.value(devGroupName, QMap()).keys(); -} - -QMap CDbInterface::readDevGroupDesc(const QStringList &tagList) -{ - QMap map; - if(tagList.isEmpty()) - { - return map; - } - if(!m_pReadDb->isOpen()) - { - return map; - } - QSqlQuery query; - QString str = tagList.join("','"); - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group where TAG_NAME in ('%1')").arg(str); - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - - map.insert(tag, desc); - } - return map; -} - -QMap > CDbInterface::readPointInfo(const QStringList &strDev, const QStringList &listTableName) -{ - if(strDev.isEmpty()) - { - return QMap>(); - } - - QMap> map; - for(int nIndex=0; nIndex ret = readPointInfo(strDev, tableName); - if(!ret.isEmpty()) - { - map.insert(tableName, ret); - } - } - return map; -} - -QMap CDbInterface::readPointInfo(const QStringList &strDev, const QString &strTableName) -{ - if(strDev.isEmpty()) - { - return QMap(); - } - if(!m_pReadDb->isOpen()) - { - return QMap(); - } - - QMap map; - QSqlQuery query; - QString addQuery; - for(int nIndex = 0; nIndex < strDev.length(); ++nIndex) - { - addQuery += "'" + strDev[nIndex] + "'"; - if(nIndex != strDev.length() - 1) - { - addQuery += ","; - } - } - - QString add = QString(); - if(strTableName == "analog" || strTableName == "accuml") - { - add = ",t1.UNIT_ID"; - } - else if(strTableName == "digital" || strTableName == "mix") - { - add = ",t1.STATE_TEXT_NAME"; - } - QString sqlQuery = QString("select t1.TAG_NAME,t1.DESCRIPTION,t1.SEQ_NO,t2.DESCRIPTION%1,t1.REGION_ID,t1.LOCATION_ID,t1.SUB_SYSTEM from %2 as t1 left join dev_info as t2 on t1.DEVICE = t2.TAG_NAME where t1.DEVICE in (%3)").arg(add).arg(strTableName).arg(addQuery); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - int seq = query.value(2).toInt(); - QString dev = query.value(3).toString(); - int region = query.value(5).toInt(); - int location = query.value(6).toInt(); - int subSystem = query.value(7).toInt(); - QString value; - if(strTableName == "analog" || strTableName == "accuml") - { - QString unitName = getUnitName(query.value(4).toInt()); - QString unit = QString(); - if(unitName != " ") - unit = " (" + unitName + ")"; - - value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg(unit).arg(region).arg(location).arg(subSystem); - } - else if(strTableName == "digital" || strTableName == "mix") - { - QString stateTextName = query.value(4).toString(); - value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg(stateTextName).arg(region).arg(location).arg(subSystem); - } - else - { - value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg("").arg(region).arg(location).arg(subSystem); - } - - map.insert(tag, value); - } - return map; -} - -QString CDbInterface::getUnitName(int unitId) -{ - QMap::const_iterator iter = m_mapUnit.find(unitId); - if(iter != m_mapUnit.constEnd()) - { - return iter.value(); - } - return " "; -} - -QString CDbInterface::getStateTextNameByValue(const QString &textName, int value) -{ - QString ret = QString::number(value); - if(m_rtdbAccess->open("base", "dict_state_text_info")) - { - CONDINFO condition1; - memcpy(condition1.name, "state_text_name", strlen("state_text_name")); - condition1.logicalop = ATTRCOND_AND; - condition1.relationop = ATTRCOND_EQU; - condition1.conditionval = textName.toStdString().c_str(); - - CONDINFO condition2; - memcpy(condition2.name, "actual_value", strlen("actual_value")); - condition2.logicalop = ATTRCOND_AND; - condition2.relationop = ATTRCOND_EQU; - condition2.conditionval = value; - - std::vector vecCondInfo; - vecCondInfo.push_back(condition1); - vecCondInfo.push_back(condition2); - - CRdbQueryResult result; - std::vector columns; - columns.push_back("display_value"); - if(m_rtdbAccess->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - ret = QString::fromStdString(value.toStdString()); - } - } - m_rtdbAccess->close(); - } - return ret; -} - -bool CDbInterface::getStateTextList(const QString &textName, QMap& textMap) -{ - if (m_rtdbAccess->open("base", "dict_state_text_info")) - { - CONDINFO condition1; - memcpy(condition1.name, "state_text_name", strlen("state_text_name")); - condition1.logicalop = ATTRCOND_AND; - condition1.relationop = ATTRCOND_EQU; - condition1.conditionval = textName.toStdString().c_str(); - - std::vector vecCondInfo; - vecCondInfo.push_back(condition1); - - CRdbQueryResult result; - std::vector columns; - columns.push_back("state_text_name"); - columns.push_back("actual_value"); - columns.push_back("display_value"); - - if (m_rtdbAccess->select(vecCondInfo, result, columns)) - { - for (int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 1, value); - int realValue = value.toInt(); - result.getColumnValue(nIndex, 2, value); - QString display_value = QString::fromStdString(value.toStdString()); - textMap[realValue] = display_value; - } - } - else { - return false; - } - m_rtdbAccess->close(); - } - return true; -} - -QString CDbInterface::getStatusStr(int status, int table) -{ - QString ret = QString(); - int num = 0; - int temp = status; - while(temp != 0) - { - if((temp % 2) == 1) - { - if(table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) - ret += getAiStatusStr(num); - else if(table == EN_DIGITAL) - ret += getDiStatusStr(num); - ret += " "; - } - temp /= 2; - num += 1; - } - return ret; -} - -QString CDbInterface::getPointDesc(int point_type) -{ - QString ret = QString::number(point_type); - switch (point_type) { - case EN_ANALOG: - { - ret = QObject::tr("模拟量"); - break; - } - case EN_DIGITAL: - { - ret = QObject::tr("数字量"); - break; - } - case EN_ACCUML: - { - ret = QObject::tr("累积量"); - break; - } - case EN_MIX: - { - ret = QObject::tr("混合量"); - break; - } - default: - break; - } - return ret; -} - -bool CDbInterface::isAlarmEnable(int status, int table) -{ - - if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) - { - return isBitEnable(status, 21); - } - - else if (table == EN_DIGITAL) - { - return isBitEnable(status, 13); - } - return false; -} - -bool CDbInterface::isCtrlEnable(int status, int table) -{ - if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) - { - return isBitEnable(status, 22); - } - - else if (table == EN_DIGITAL) - { - return isBitEnable(status, 14); - } - return false; -} - -bool CDbInterface::isRefreshEnable(int status, int table) -{ - if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) - { - return isBitEnable(status, 20); - } - - else if (table == EN_DIGITAL) - { - return isBitEnable(status, 12); - } - return false; -} - -bool CDbInterface::isSetValueEnable(int status, int table) -{ - if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) - { - return isBitEnable(status, 10); - } - - else if (table == EN_DIGITAL) - { - return isBitEnable(status, 11); - } - return false; -} - -bool CDbInterface::isBitEnable(int status, int checkNum) -{ - return (status >> (checkNum)) & 0x01 == 0x01; -} - -QString CDbInterface::getDiStatusStr(int status) -{ - QMap::const_iterator iter = m_mapDiStatus.find(status); - if(iter != m_mapDiStatus.constEnd()) - { - return iter.value(); - } - return " "; -} - -QString CDbInterface::getAiStatusStr(int status) -{ - QMap::const_iterator iter = m_mapAiStatus.find(status); - if(iter != m_mapAiStatus.constEnd()) - { - return iter.value(); - } - return " "; -} - -void CDbInterface::loadRTLocation() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return; - } - int level; - std::vector vecLocationId; - std::vector vecPermPic; - if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) - { - LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); - return; - } - - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - QPair id_value; - id_value.first = "location_id"; - id_value.second = "description"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back(id_value.first); - columns.push_back(id_value.second); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - m_locationInfo.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - - std::vector ::const_iterator it = vecLocationId.cbegin(); - while (it != vecLocationId.cend()) - { - if(key.toInt() == *it) - { - m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); - m_locOrder.push_back(key.toInt()); - } - ++it; - } - } - } - } - m_rtdbAccess->close(); -} - -void CDbInterface::loadDeviceInfo() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,GROUP_TAG_NAME from dev_info"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - QString devg = query.value(2).toString(); - QMap >::iterator iter = m_devGDevInfoMap.find(devg); - if(iter != m_devGDevInfoMap.end()) - { - m_devGDevInfoMap[devg].insert(tag,desc); - }else - { - QMap devMap; - devMap.insert(tag,desc); - m_devGDevInfoMap[devg] = devMap; - } - } -} - -void CDbInterface::readUnitInfo() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - m_mapUnit.clear(); - QSqlQuery query; - QString sqlQuery = QString("select UNIT_ID,UNIT_NAME from dict_unit_info"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - int id = query.value(0).toInt(); - QString name = query.value(1).toString(); - - m_mapUnit.insert(id, name); - } -} - -void CDbInterface::readDiStatus() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - m_mapDiStatus.clear(); - QSqlQuery query; - QString sqlQuery = QString("select ACTUAL_VALUE,DISPLAY_VALUE from dict_menu_info where MENU_NAME='%1'").arg(DI_STATUS_MENU_NAME); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - int id = query.value(0).toInt(); - QString name = query.value(1).toString(); - - m_mapDiStatus.insert(id, name); - } -} - -void CDbInterface::readAiStatus() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - m_mapAiStatus.clear(); - QSqlQuery query; - QString sqlQuery = QString("select ACTUAL_VALUE,DISPLAY_VALUE from dict_menu_info where MENU_NAME='%1'").arg(AI_STATUS_MENU_NAME); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - int id = query.value(0).toInt(); - QString name = query.value(1).toString(); - - m_mapAiStatus.insert(id, name); - } -} - +#include "CDbInterface.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" + +using namespace kbd_dbms; +using namespace kbd_public; + +CDbInterface *CDbInterface::m_pInstance = NULL; + +CDbInterface::CDbInterface() +{ + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + readUnitInfo(); + readDiStatus(); + readAiStatus(); + loadRTLocation(); + loadDeviceInfo(); +} + +CDbInterface *CDbInterface::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDbInterface(); + } + return m_pInstance; +} + +void CDbInterface::destory() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_mapUnit.clear(); + m_mapAiStatus.clear(); + m_mapDiStatus.clear(); + m_pInstance = NULL; + delete this; +} + +QMap CDbInterface::locationInfo() +{ + return m_locationInfo; +} + +QString CDbInterface::getLocationDesc(const int &locId) +{ + return m_locationInfo.value(locId); +} + +QList CDbInterface::getLocationOrder() +{ + return m_locOrder; +} + +bool CDbInterface::queryDevGroupInfoList(const int &nLocId, const int &nSubId, QList > &devgList) +{ + if(nLocId == CN_InvalidLocationId) + { + return false; + } + QSqlQuery query; + QString sqlSequenceQuery; + if(nSubId == CN_InvalidSubsystemId) + { + //< 所有专业 + sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1 order by dev_group_no asc; ") + .arg(nLocId); + } + else + { + sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1 and sub_system = %2 order by dev_group_no asc; ") + .arg(nLocId).arg(nSubId); + } + if(!m_pReadDb->execute(sqlSequenceQuery, query)) + { + LOGINFO("查找位置[%d],专业[%d]下的设备组失败!",nLocId,nSubId); + return false; + } + while(query.next()) + { + QPair pair; + pair.first = query.value(0).toString(); + pair.second = query.value(1).toString(); + devgList.append(pair); + } + return true; +} + +QMap CDbInterface::deviceInfo(const QString &devGroupName) +{ + return m_devGDevInfoMap.value(devGroupName, QMap()); +} + +QList CDbInterface::deviceInfoByDevg(const QString &devGroupName) +{ + return m_devGDevInfoMap.value(devGroupName, QMap()).keys(); +} + +QMap CDbInterface::readDevGroupDesc(const QStringList &tagList) +{ + QMap map; + if(tagList.isEmpty()) + { + return map; + } + if(!m_pReadDb->isOpen()) + { + return map; + } + QSqlQuery query; + QString str = tagList.join("','"); + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group where TAG_NAME in ('%1')").arg(str); + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + + map.insert(tag, desc); + } + return map; +} + +QMap > CDbInterface::readPointInfo(const QStringList &strDev, const QStringList &listTableName) +{ + if(strDev.isEmpty()) + { + return QMap>(); + } + + QMap> map; + for(int nIndex=0; nIndex ret = readPointInfo(strDev, tableName); + if(!ret.isEmpty()) + { + map.insert(tableName, ret); + } + } + return map; +} + +QMap CDbInterface::readPointInfo(const QStringList &strDev, const QString &strTableName) +{ + if(strDev.isEmpty()) + { + return QMap(); + } + if(!m_pReadDb->isOpen()) + { + return QMap(); + } + + QMap map; + QSqlQuery query; + QString addQuery; + for(int nIndex = 0; nIndex < strDev.length(); ++nIndex) + { + addQuery += "'" + strDev[nIndex] + "'"; + if(nIndex != strDev.length() - 1) + { + addQuery += ","; + } + } + + QString add = QString(); + if(strTableName == "analog" || strTableName == "accuml") + { + add = ",t1.UNIT_ID"; + } + else if(strTableName == "digital" || strTableName == "mix") + { + add = ",t1.STATE_TEXT_NAME"; + } + QString sqlQuery = QString("select t1.TAG_NAME,t1.DESCRIPTION,t1.SEQ_NO,t2.DESCRIPTION%1,t1.REGION_ID,t1.LOCATION_ID,t1.SUB_SYSTEM from %2 as t1 left join dev_info as t2 on t1.DEVICE = t2.TAG_NAME where t1.DEVICE in (%3)").arg(add).arg(strTableName).arg(addQuery); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + int seq = query.value(2).toInt(); + QString dev = query.value(3).toString(); + int region = query.value(5).toInt(); + int location = query.value(6).toInt(); + int subSystem = query.value(7).toInt(); + QString value; + if(strTableName == "analog" || strTableName == "accuml") + { + QString unitName = getUnitName(query.value(4).toInt()); + QString unit = QString(); + if(unitName != " ") + unit = " (" + unitName + ")"; + + value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg(unit).arg(region).arg(location).arg(subSystem); + } + else if(strTableName == "digital" || strTableName == "mix") + { + QString stateTextName = query.value(4).toString(); + value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg(stateTextName).arg(region).arg(location).arg(subSystem); + } + else + { + value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg("").arg(region).arg(location).arg(subSystem); + } + + map.insert(tag, value); + } + return map; +} + +QString CDbInterface::getUnitName(int unitId) +{ + QMap::const_iterator iter = m_mapUnit.find(unitId); + if(iter != m_mapUnit.constEnd()) + { + return iter.value(); + } + return " "; +} + +QString CDbInterface::getStateTextNameByValue(const QString &textName, int value) +{ + QString ret = QString::number(value); + if(m_rtdbAccess->open("base", "dict_state_text_info")) + { + CONDINFO condition1; + memcpy(condition1.name, "state_text_name", strlen("state_text_name")); + condition1.logicalop = ATTRCOND_AND; + condition1.relationop = ATTRCOND_EQU; + condition1.conditionval = textName.toStdString().c_str(); + + CONDINFO condition2; + memcpy(condition2.name, "actual_value", strlen("actual_value")); + condition2.logicalop = ATTRCOND_AND; + condition2.relationop = ATTRCOND_EQU; + condition2.conditionval = value; + + std::vector vecCondInfo; + vecCondInfo.push_back(condition1); + vecCondInfo.push_back(condition2); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("display_value"); + if(m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + ret = QString::fromStdString(value.toStdString()); + } + } + m_rtdbAccess->close(); + } + return ret; +} + +bool CDbInterface::getStateTextList(const QString &textName, QMap& textMap) +{ + if (m_rtdbAccess->open("base", "dict_state_text_info")) + { + CONDINFO condition1; + memcpy(condition1.name, "state_text_name", strlen("state_text_name")); + condition1.logicalop = ATTRCOND_AND; + condition1.relationop = ATTRCOND_EQU; + condition1.conditionval = textName.toStdString().c_str(); + + std::vector vecCondInfo; + vecCondInfo.push_back(condition1); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("state_text_name"); + columns.push_back("actual_value"); + columns.push_back("display_value"); + + if (m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for (int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 1, value); + int realValue = value.toInt(); + result.getColumnValue(nIndex, 2, value); + QString display_value = QString::fromStdString(value.toStdString()); + textMap[realValue] = display_value; + } + } + else { + return false; + } + m_rtdbAccess->close(); + } + return true; +} + +QString CDbInterface::getStatusStr(int status, int table) +{ + QString ret = QString(); + int num = 0; + int temp = status; + while(temp != 0) + { + if((temp % 2) == 1) + { + if(table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + ret += getAiStatusStr(num); + else if(table == EN_DIGITAL) + ret += getDiStatusStr(num); + ret += " "; + } + temp /= 2; + num += 1; + } + return ret; +} + +QString CDbInterface::getPointDesc(int point_type) +{ + QString ret = QString::number(point_type); + switch (point_type) { + case EN_ANALOG: + { + ret = QObject::tr("模拟量"); + break; + } + case EN_DIGITAL: + { + ret = QObject::tr("数字量"); + break; + } + case EN_ACCUML: + { + ret = QObject::tr("累积量"); + break; + } + case EN_MIX: + { + ret = QObject::tr("混合量"); + break; + } + default: + break; + } + return ret; +} + +bool CDbInterface::isAlarmEnable(int status, int table) +{ + + if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + { + return isBitEnable(status, 21); + } + + else if (table == EN_DIGITAL) + { + return isBitEnable(status, 13); + } + return false; +} + +bool CDbInterface::isCtrlEnable(int status, int table) +{ + if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + { + return isBitEnable(status, 22); + } + + else if (table == EN_DIGITAL) + { + return isBitEnable(status, 14); + } + return false; +} + +bool CDbInterface::isRefreshEnable(int status, int table) +{ + if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + { + return isBitEnable(status, 20); + } + + else if (table == EN_DIGITAL) + { + return isBitEnable(status, 12); + } + return false; +} + +bool CDbInterface::isSetValueEnable(int status, int table) +{ + if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + { + return isBitEnable(status, 10); + } + + else if (table == EN_DIGITAL) + { + return isBitEnable(status, 11); + } + return false; +} + +bool CDbInterface::isBitEnable(int status, int checkNum) +{ + return (status >> (checkNum)) & 0x01 == 0x01; +} + +QString CDbInterface::getDiStatusStr(int status) +{ + QMap::const_iterator iter = m_mapDiStatus.find(status); + if(iter != m_mapDiStatus.constEnd()) + { + return iter.value(); + } + return " "; +} + +QString CDbInterface::getAiStatusStr(int status) +{ + QMap::const_iterator iter = m_mapAiStatus.find(status); + if(iter != m_mapAiStatus.constEnd()) + { + return iter.value(); + } + return " "; +} + +void CDbInterface::loadRTLocation() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + int level; + std::vector vecLocationId; + std::vector vecPermPic; + if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) + { + LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); + return; + } + + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + QPair id_value; + id_value.first = "location_id"; + id_value.second = "description"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back(id_value.first); + columns.push_back(id_value.second); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + m_locationInfo.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + std::vector ::const_iterator it = vecLocationId.cbegin(); + while (it != vecLocationId.cend()) + { + if(key.toInt() == *it) + { + m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); + m_locOrder.push_back(key.toInt()); + } + ++it; + } + } + } + } + m_rtdbAccess->close(); +} + +void CDbInterface::loadDeviceInfo() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,GROUP_TAG_NAME from dev_info"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + QString devg = query.value(2).toString(); + QMap >::iterator iter = m_devGDevInfoMap.find(devg); + if(iter != m_devGDevInfoMap.end()) + { + m_devGDevInfoMap[devg].insert(tag,desc); + }else + { + QMap devMap; + devMap.insert(tag,desc); + m_devGDevInfoMap[devg] = devMap; + } + } +} + +void CDbInterface::readUnitInfo() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_mapUnit.clear(); + QSqlQuery query; + QString sqlQuery = QString("select UNIT_ID,UNIT_NAME from dict_unit_info"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + + m_mapUnit.insert(id, name); + } +} + +void CDbInterface::readDiStatus() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_mapDiStatus.clear(); + QSqlQuery query; + QString sqlQuery = QString("select ACTUAL_VALUE,DISPLAY_VALUE from dict_menu_info where MENU_NAME='%1'").arg(DI_STATUS_MENU_NAME); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + + m_mapDiStatus.insert(id, name); + } +} + +void CDbInterface::readAiStatus() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_mapAiStatus.clear(); + QSqlQuery query; + QString sqlQuery = QString("select ACTUAL_VALUE,DISPLAY_VALUE from dict_menu_info where MENU_NAME='%1'").arg(AI_STATUS_MENU_NAME); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + + m_mapAiStatus.insert(id, name); + } +} + diff --git a/product/src/gui/plugin/DevRealDataWidget/CDbInterface.h b/product/src/gui/plugin/DevRealDataWidget/CDbInterface.h index 6b3a9342..cde8eda8 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDbInterface.h +++ b/product/src/gui/plugin/DevRealDataWidget/CDbInterface.h @@ -1,78 +1,78 @@ -#ifndef CDBINTERFACE_H -#define CDBINTERFACE_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/db_api_ex/CDbApi.h" - -#define DI_STATUS_MENU_NAME ("数字量状态") -#define AI_STATUS_MENU_NAME ("模拟量状态") - -enum EPointType -{ - EN_ANALOG, - EN_DIGITAL, - EN_ACCUML, - EN_MIX, - EN_ALL -}; - -class CDbInterface -{ -public: - static CDbInterface * instance(); - void destory(); - - QMap locationInfo(); - QString getLocationDesc(const int &locId); - QList getLocationOrder(); - bool queryDevGroupInfoList(const int& nLocId, const int &nSubId, QList> &devgList); - - QMap deviceInfo(const QString &devGroupName); - - QList deviceInfoByDevg(const QString &devGroupName); - - QMap readDevGroupDesc(const QStringList &tagList); - QMap> readPointInfo(const QStringList &strDev, const QStringList &listTableName); - QMap readPointInfo(const QStringList& strDev, const QString& strTableName); - - QString getUnitName(int unitId); - QString getStateTextNameByValue(const QString &textName, int value); - bool getStateTextList(const QString &textName,QMap& textMap); - QString getStatusStr(int status, int table); - QString getPointDesc(int point_type); - - bool isAlarmEnable(int status, int table); - bool isCtrlEnable(int status, int table); - bool isRefreshEnable(int status, int table); - bool isSetValueEnable(int status, int table); - bool isBitEnable(int status, int checkNum); -private: - CDbInterface(); - - void readUnitInfo(); - void readDiStatus(); - void readAiStatus(); - - QString getDiStatusStr(int status); - QString getAiStatusStr(int status); - - void loadRTLocation(); - void loadDeviceInfo(); - -private: - static CDbInterface * m_pInstance; - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccess * m_rtdbAccess; - QMap m_mapUnit; - QMap m_mapDiStatus; - QMap m_mapAiStatus; - - QMap m_locationInfo; //< LocationID-LocationDesc - QList m_locOrder; - - QMap m_devgInfoMap; - QMap > m_devGDevInfoMap; -}; - -#endif // CDBINTERFACE_H +#ifndef CDBINTERFACE_H +#define CDBINTERFACE_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" + +#define DI_STATUS_MENU_NAME ("数字量状态") +#define AI_STATUS_MENU_NAME ("模拟量状态") + +enum EPointType +{ + EN_ANALOG, + EN_DIGITAL, + EN_ACCUML, + EN_MIX, + EN_ALL +}; + +class CDbInterface +{ +public: + static CDbInterface * instance(); + void destory(); + + QMap locationInfo(); + QString getLocationDesc(const int &locId); + QList getLocationOrder(); + bool queryDevGroupInfoList(const int& nLocId, const int &nSubId, QList> &devgList); + + QMap deviceInfo(const QString &devGroupName); + + QList deviceInfoByDevg(const QString &devGroupName); + + QMap readDevGroupDesc(const QStringList &tagList); + QMap> readPointInfo(const QStringList &strDev, const QStringList &listTableName); + QMap readPointInfo(const QStringList& strDev, const QString& strTableName); + + QString getUnitName(int unitId); + QString getStateTextNameByValue(const QString &textName, int value); + bool getStateTextList(const QString &textName,QMap& textMap); + QString getStatusStr(int status, int table); + QString getPointDesc(int point_type); + + bool isAlarmEnable(int status, int table); + bool isCtrlEnable(int status, int table); + bool isRefreshEnable(int status, int table); + bool isSetValueEnable(int status, int table); + bool isBitEnable(int status, int checkNum); +private: + CDbInterface(); + + void readUnitInfo(); + void readDiStatus(); + void readAiStatus(); + + QString getDiStatusStr(int status); + QString getAiStatusStr(int status); + + void loadRTLocation(); + void loadDeviceInfo(); + +private: + static CDbInterface * m_pInstance; + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccess * m_rtdbAccess; + QMap m_mapUnit; + QMap m_mapDiStatus; + QMap m_mapAiStatus; + + QMap m_locationInfo; //< LocationID-LocationDesc + QList m_locOrder; + + QMap m_devgInfoMap; + QMap > m_devGDevInfoMap; +}; + +#endif // CDBINTERFACE_H diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.cpp b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.cpp index 66e0467a..a6695567 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CDevRealDataPluginWidget.h" -#include "CDevRealDataWidget.h" -#include - -CDevRealDataPluginWidget::CDevRealDataPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CDevRealDataPluginWidget::~CDevRealDataPluginWidget() -{ - -} - -bool CDevRealDataPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CDevRealDataWidget *pWidget = new CDevRealDataWidget(editMode, ptrVec, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CDevRealDataPluginWidget::release() -{ - -} +#include "CDevRealDataPluginWidget.h" +#include "CDevRealDataWidget.h" +#include + +CDevRealDataPluginWidget::CDevRealDataPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CDevRealDataPluginWidget::~CDevRealDataPluginWidget() +{ + +} + +bool CDevRealDataPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CDevRealDataWidget *pWidget = new CDevRealDataWidget(editMode, ptrVec, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CDevRealDataPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.h b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.h index 7d2b258d..0b47ddd5 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.h +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CDEVREALDATAPLUGINWIDGET_H -#define CDEVREALDATAPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CDevRealDataPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CDevRealDataPluginWidget(QObject *parent = 0); - ~CDevRealDataPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CDEVREALDATAPLUGINWIDGET_H +#ifndef CDEVREALDATAPLUGINWIDGET_H +#define CDEVREALDATAPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CDevRealDataPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CDevRealDataPluginWidget(QObject *parent = 0); + ~CDevRealDataPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CDEVREALDATAPLUGINWIDGET_H diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.cpp b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.cpp index aeb14688..d507c45d 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.cpp @@ -1,1211 +1,1211 @@ -#include "CDevRealDataWidget.h" -#include "ui_CDevRealDataWidget.h" -#include -#include "pub_utility_api/FileStyle.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" -#include -#include -#include "SetValueInputDialog.h" - -using namespace kbd_dbms; -using namespace kbd_public; -using namespace kbd_service; -CDevRealDataWidget::CDevRealDataWidget(bool editMode, QVector ptrVec, QWidget *parent) : - QWidget(parent), - ui(new Ui::CDevRealDataWidget), - m_pDpcdaForApp(NULL), - m_realDataCollect(NULL), - m_pCollectThread(NULL), - m_realModel(NULL), - m_communicator(NULL), - m_isShowSub(false) -{ - Q_UNUSED(ptrVec); - ui->setupUi(this); - - initStyleSheet(); - ui->splitter->setSizes(QList()<<220<<1200); - - ui->frame_5->setVisible(false); - - if(!editMode) - { - qRegisterMetaType>>("QMap>"); - qRegisterMetaType>>("QMap>"); - qRegisterMetaType>>("QMap>"); - - if(!kbd_public::createSysInfoInstance(m_sysInfoPtr)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return; - } - initMsg(); - readNodeInfo(); - initialize(); - } -} - -CDevRealDataWidget::~CDevRealDataWidget() -{ - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - delete m_pDpcdaForApp; - } - m_pDpcdaForApp = NULL; - - if(m_realDataCollect) - { - emit releaseCollectThread(); - } - m_realDataCollect = NULL; - - if(m_pCollectThread) - { - m_pCollectThread->quit(); - m_pCollectThread->wait(); - } - m_pCollectThread = NULL; - - CDbInterface::instance()->destory(); - - if(m_realModel) - { - delete m_realModel; - } - m_realModel = NULL; - - delete ui; -} - -void CDevRealDataWidget::initMsg() -{ - if(m_communicator == NULL) - { - m_communicator = new kbd_net::CMbCommunicator(); - } -} - -QString CDevRealDataWidget::curDevGroup() -{ - return ui->m_devGroupComb->currentData().toString(); -} - -QString CDevRealDataWidget::curPointTable() -{ - QString ret = ""; - if(ui->m_typeCb->currentIndex() == 1) - { - ret = "analog"; - } - else if(ui->m_typeCb->currentIndex() == 2) - { - ret = "digital"; - } - else if(ui->m_typeCb->currentIndex() == 3) - { - ret = "accuml"; - } - else if(ui->m_typeCb->currentIndex() == 4) - { - ret = "mix"; - } - else - { - ret = "analog,digital,accuml,mix"; - } - return ret; -} - -void CDevRealDataWidget::setTableColumnHidden(int column, bool hide) -{ - ui->m_tableView->setColumnHidden(column, hide); -} - -void CDevRealDataWidget::setTableColumnWidth(int column, int width) -{ - ui->m_tableView->setColumnWidth(column, width); -} - -void CDevRealDataWidget::resetDeviceGroup(const QStringList &tagList) -{ - ui->widget->setHidden(true); - ui->frame_5->setVisible(true); - ui->m_devGroupComb->blockSignals(true); - ui->m_devGroupComb->clear(); - - QMap devGroup = CDbInterface::instance()->readDevGroupDesc(tagList); - if(devGroup.isEmpty()) - { - return; - } - QMap::const_iterator iter = devGroup.constBegin(); - for(; iter != devGroup.constEnd(); ++iter) - { - ui->m_devGroupComb->addItem(iter.value(), iter.key()); - } - - ui->m_devGroupComb->blockSignals(false); - emit ui->m_devGroupComb->currentIndexChanged(0); -} - -void CDevRealDataWidget::setShowSubSystem(bool isShow) -{ - m_isShowSub = isShow; - ui->label_4->setVisible(m_isShowSub); - ui->m_subCb->setVisible(m_isShowSub); -} - -void CDevRealDataWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - qssfile1.close(); - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("deviceRealData.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - qssfile2.close(); - - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CDevRealDataWidget::initialize() -{ - ui->m_subCb->setView(new QListView()); - ui->m_locCb->setView(new QListView()); - ui->m_devGroupComb->setView(new QListView()); - ui->m_typeCb->setView(new QListView()); - ui->m_typeCb->setEnabled(true); - - //< 初始化专业 - //< 默认不区分专业 - ui->label_4->setVisible(m_isShowSub); - ui->m_subCb->setVisible(m_isShowSub); - ui->m_subCb->addItem(tr("所有"),CN_InvalidSubsystemId); - std::vector vecSubsystemInfo; - m_sysInfoPtr->getAllSubsystemInfo(vecSubsystemInfo); - std::vector::iterator subIter = vecSubsystemInfo.begin(); - for(; subIter!=vecSubsystemInfo.end(); ++subIter) - { - SSubsystemInfo& info = *subIter; - if(info.nId < 4) - { - continue; - } - ui->m_subCb->addItem(QString::fromStdString(info.strDesc),info.nId); - } - - //< 初始化位置 - std::vector vecLocationInfo; - m_sysInfoPtr->getAllLocationInfo(vecLocationInfo); - std::vector::iterator locIter = vecLocationInfo.begin(); - for(; locIter!=vecLocationInfo.end(); ++locIter) - { - SLocationInfo& info = *locIter; - ui->m_locCb->addItem(QString::fromStdString(info.strDesc),info.nId); - } - - //< 初始化订阅线程 - m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); - m_realDataCollect = new CRealDataCollect; - m_pCollectThread = new QThread(this); - m_realDataCollect->moveToThread(m_pCollectThread); - connect(m_pCollectThread, &QThread::finished, m_pCollectThread, &QThread::deleteLater); - connect(this, &CDevRealDataWidget::releaseCollectThread, m_realDataCollect, &CRealDataCollect::release, Qt::BlockingQueuedConnection); - connect(m_realDataCollect, &CRealDataCollect::signal_updateAi, this, &CDevRealDataWidget::slotUpdateAi); - connect(m_realDataCollect, &CRealDataCollect::signal_updateDi, this, &CDevRealDataWidget::slotUpdateDi); - connect(m_realDataCollect, &CRealDataCollect::signal_updatePi, this, &CDevRealDataWidget::slotUpdatePi); - connect(m_realDataCollect, &CRealDataCollect::signal_updateMi, this, &CDevRealDataWidget::slotUpdateMi); - m_pCollectThread->start(); - - //< 初始化表格模型 - m_realModel = new CRealTableModel(this); - ui->m_tableView->setModel(m_realModel); - ui->m_tableView->horizontalHeader()->setStretchLastSection(true); - connect(ui->m_tableView->selectionModel(), - SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), - this, - SLOT(slotCurRowChanged(const QModelIndex &, const QModelIndex &))); - - connect(m_realModel, - SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), - this, - SLOT(slotDataChanged(const QModelIndex &, const QModelIndex &))); - - ui->treeWidget->setColumnCount(1); - setTableColumnWidth(0,300); - setTableColumnWidth(2,300); - connect(ui->m_subCb, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTreeWidget())); - connect(ui->m_locCb, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTreeWidget())); - connect(ui->m_devGroupComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDeviceUpdate())); - connect(ui->m_typeCb, SIGNAL(currentIndexChanged(int)), this, SLOT(brush())); - connect(ui->mSearchLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotDevSearchLineChanged(const QString&))); - connect(ui->m_filterBtn, SIGNAL(clicked()), this, SLOT(slotFilter())); - connect(ui->m_filterEdit, SIGNAL(returnPressed()), this, SLOT(slotFilter())); - connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CDevRealDataWidget::treeItemClicked); - - updateTreeWidget(); - - //< 初始化标签设置按钮 - bool isRefreshEnable = false; - bool isAlarmEnable = false; - bool isCtrlEnable = false; - bool isSetValueEnable = false; - ui->ctrlDiableBtn->setHidden(isCtrlEnable); - ui->ctrlEnableBtn->setHidden(!isCtrlEnable); - ui->refreshDisableBtn->setHidden(isRefreshEnable); - ui->refreshEnableBtn->setHidden(!isRefreshEnable); - ui->alarmDiableBtn->setHidden(isAlarmEnable); - ui->alarmEnableBtn->setHidden(!isAlarmEnable); - ui->setValueEnableBtn->setHidden(isSetValueEnable); - ui->setValueDisableBtn->setHidden(!isSetValueEnable); - connect(ui->refreshEnableBtn, SIGNAL(clicked()), this, SLOT(slotEnableRefreshBtnClick())); - connect(ui->alarmEnableBtn, SIGNAL(clicked()), this, SLOT(slotEnableAlarmBtnClick())); - connect(ui->setValueEnableBtn, SIGNAL(clicked()), this, SLOT(slotEnableSetValueBtnClick())); - connect(ui->ctrlEnableBtn, SIGNAL(clicked()), this, SLOT(slotEnableCtrBtnClick())); - connect(ui->refreshDisableBtn, SIGNAL(clicked()), this, SLOT(slotDisableRefreshBtnClick())); - connect(ui->alarmDiableBtn, SIGNAL(clicked()), this, SLOT(slotDisableAlarmBtnClick())); - connect(ui->setValueDisableBtn, SIGNAL(clicked()), this, SLOT(slotDisableSetValueBtnClick())); - connect(ui->ctrlDiableBtn, SIGNAL(clicked()), this, SLOT(slotDisableCtrlBtnClick())); -} - -void CDevRealDataWidget::updateTreeWidget() -{ - ui->mSearchLineEdit->clear(); - cleanTreeWidget(); - int nLocId = ui->m_locCb->currentData().toInt(); - int nSubId = ui->m_subCb->currentData().toInt(); - QList> devgList; - if(!CDbInterface::instance()->queryDevGroupInfoList(nLocId,nSubId,devgList)) - { - slotShowMess(tr("查询设备组信息失败!")); - return; - } - for(int nIndex(0);nIndexsetText(0,devgList.at(nIndex).second); - devgItem->setData(0,Qt::UserRole,(int)EN_TREE_DEVG);//类型 - devgItem->setData(0,Qt::UserRole+1,devgList.at(nIndex).first);//值 - ui->treeWidget->addTopLevelItem(devgItem); - - QMap devInfo = CDbInterface::instance()->deviceInfo(devgList.at(nIndex).first); - QMap::iterator pos = devInfo.begin(); - while (pos != devInfo.end()) { - QTreeWidgetItem *devItem = new QTreeWidgetItem(); - devItem->setText(0,pos.value()); - devItem->setData(0,Qt::UserRole,(int)EN_TREE_DEV);//类型 - devItem->setData(0,Qt::UserRole+1,pos.key());//值 - devgItem->addChild(devItem); - pos++; - } - } - if(ui->treeWidget->topLevelItem(0)) - { - emit ui->treeWidget->itemClicked(ui->treeWidget->topLevelItem(0), 0); - } -} - -void CDevRealDataWidget::cleanTreeWidget() -{ - for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) - { - ui->treeWidget->takeTopLevelItem(index); - } - treeItemClicked(Q_NULLPTR,0); -} - -int CDevRealDataWidget::tableNameToEnum(const QString &tableName) -{ - if(tableName == "analog") - { - return EN_ANALOG; - } - else if(tableName == "digital") - { - return EN_DIGITAL; - } - else if(tableName == "accuml") - { - return EN_ACCUML; - } - else if(tableName == "mix") - { - return EN_MIX; - } - else - { - return -1; - } -} - -QList CDevRealDataWidget::getDevByDevg(const QString &devg) -{ - return CDbInterface::instance()->deviceInfoByDevg(devg); -} - -bool CDevRealDataWidget::setValueTagInfo(bool isEnable) -{ - QItemSelectionModel* selModel = ui->m_tableView->selectionModel(); - QModelIndexList indexList = selModel->selectedRows(); - if (indexList.count() <= 0) - { - slotShowMess(tr("请至少选择一项!")); - return false; - } - - QString titleStr = ""; - - CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); - foreach(QModelIndex index, indexList) - { - int location = model->data(model->index(index.row(), 0), Qt::UserRole + 8).toInt(); - int region = model->data(model->index(index.row(), 0), Qt::UserRole + 7).toInt(); - - QString desc = model->data(model->index(index.row(), 0), Qt::DisplayRole).toString(); - QString retStr = checkPerm(location, region); - if (!retStr.isEmpty()) - { - QString meg = QString(tr("行“%1”,%2")).arg(desc).arg(retStr); - slotShowMess(meg); - return false; - } - if(titleStr.isEmpty()) - titleStr = desc; - } - - if(indexList.count() > 1) - { - titleStr = QString(tr("“%1”等,共(%2)项")).arg(titleStr).arg(indexList.count()); - } - - int firstRow = indexList.at(0).row(); - double value = 0; - if (isEnable) - { - if (!getSetValue(titleStr,firstRow, value)) - { - return false; - } - } - - foreach(QModelIndex index, indexList) { - int row = index.row(); - - STOptTagInfo info; - info.tagName = ""; - info.setValue = value; - info.nIsSet = isEnable?1:0;// 0:取消;1:设置; - info.optType = MT_OPT_TAG_VALUE_SET; - info.tagName = model->data(model->index(row, 0), Qt::UserRole + 2).toString(); - info.keyIdTag = model->data(model->index(row, 0), Qt::UserRole + 1).toString(); - info.subSystem = model->data(model->index(row, 0), Qt::UserRole + 9).toInt(); - info.locationId = model->data(model->index(row, 0), Qt::UserRole + 8).toInt(); - - if (!OptTagInfo(info)) - { - return false; - } - } - return true; -} - -bool CDevRealDataWidget::setRefreshTagInfo(bool isEnable) -{ - QItemSelectionModel* selModel = ui->m_tableView->selectionModel(); - QModelIndexList indexList = selModel->selectedRows(); - if (indexList.count() <= 0) - { - slotShowMess(tr("请至少选择一项!")); - return false; - } - - CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); - foreach(QModelIndex index, indexList) - { - int location = model->data(model->index(index.row(), 0), Qt::UserRole + 8).toInt(); - int region = model->data(model->index(index.row(), 0), Qt::UserRole + 7).toInt(); - - QString desc = model->data(model->index(index.row(), 0), Qt::DisplayRole).toString(); - QString retStr = checkPerm(location, region); - if (!retStr.isEmpty()) - { - QString meg = QString(tr("“%1”,%2")).arg(desc).arg(retStr); - slotShowMess(meg); - return false; - } - } - - foreach(QModelIndex index, indexList) { - int row = index.row(); - - STOptTagInfo info; - info.tagName = ""; - info.setValue = 0; - info.nIsSet = isEnable ? 1 : 0;// 0:取消;1:设置; - info.optType = MT_OPT_PINHIBIT_REF; - - info.tagName = model->data(model->index(row, 0), Qt::UserRole + 2).toString(); - info.keyIdTag = model->data(model->index(row, 0), Qt::UserRole + 1).toString(); - info.subSystem = model->data(model->index(row, 0), Qt::UserRole + 9).toInt(); - info.locationId = model->data(model->index(row, 0), Qt::UserRole + 8).toInt(); - - - if (!OptTagInfo(info)) - { - return false; - } - } - return true; -} - -bool CDevRealDataWidget::setAlarmTagInfo(bool isEnable) -{ - QItemSelectionModel* selModel = ui->m_tableView->selectionModel(); - QModelIndexList indexList = selModel->selectedRows(); - if (indexList.count() <= 0) - { - slotShowMess(tr("请至少选择一项!")); - return false; - } - - CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); - foreach(QModelIndex index, indexList) - { - int location = model->data(model->index(index.row(), 0), Qt::UserRole + 8).toInt(); - int region = model->data(model->index(index.row(), 0), Qt::UserRole + 7).toInt(); - - QString desc = model->data(model->index(index.row(), 0), Qt::DisplayRole).toString(); - QString retStr = checkPerm(location, region); - if (!retStr.isEmpty()) - { - QString meg = QString(tr("“%1”,%2")).arg(desc).arg(retStr); - slotShowMess(meg); - return false; - } - } - - foreach(QModelIndex index, indexList) { - int row = index.row(); - - STOptTagInfo info; - info.tagName = ""; - info.setValue = 0; - info.nIsSet = isEnable ? 1 : 0;// 0:取消;1:设置; - info.optType = MT_OPT_PINHIBIT_ALARM; - info.tagName = model->data(model->index(row, 0), Qt::UserRole + 2).toString(); - info.keyIdTag = model->data(model->index(row, 0), Qt::UserRole + 1).toString(); - info.subSystem = model->data(model->index(row, 0), Qt::UserRole + 9).toInt(); - info.locationId = model->data(model->index(row, 0), Qt::UserRole + 8).toInt(); - - - if (!OptTagInfo(info)) - { - return false; - } - } - return true; -} - -bool CDevRealDataWidget::setCtrTagInfo(bool isEnable) -{ - QItemSelectionModel* selModel = ui->m_tableView->selectionModel(); - QModelIndexList indexList = selModel->selectedRows(); - if (indexList.count() <= 0) - { - slotShowMess(tr("请至少选择一项!")); - return false; - } - - CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); - foreach(QModelIndex index, indexList) - { - int location = model->data(model->index(index.row(), 0), Qt::UserRole + 8).toInt(); - int region = model->data(model->index(index.row(), 0), Qt::UserRole + 7).toInt(); - - QString desc = model->data(model->index(index.row(), 0), Qt::DisplayRole).toString(); - QString retStr = checkPerm(location, region); - if (!retStr.isEmpty()) - { - QString meg = QString(tr("“%1”,%2")).arg(desc).arg(retStr); - slotShowMess(meg); - return false; - } - } - - foreach(QModelIndex index, indexList) { - int row = index.row(); - - STOptTagInfo info; - info.tagName = ""; - info.setValue = 0; - info.nIsSet = isEnable ? 1 : 0;// 0:取消;1:设置; - info.optType = MT_OPT_PINHIBIT_CTRL; - info.tagName = model->data(model->index(row, 0), Qt::UserRole + 2).toString(); - info.keyIdTag = model->data(model->index(row, 0), Qt::UserRole + 1).toString(); - info.subSystem = model->data(model->index(row, 0), Qt::UserRole + 9).toInt(); - info.locationId = model->data(model->index(row, 0), Qt::UserRole + 8).toInt(); - - if (!OptTagInfo(info)) - { - return false; - } - } - return true; -} - -bool CDevRealDataWidget::getSetValue(const QString& title,int row, double& value) -{ - QAbstractItemModel* model = ui->m_tableView->model(); - - int dotType = model->data(model->index(row, 0), Qt::UserRole + 6).toInt(); - - if (dotType == EN_ANALOG || dotType == EN_ACCUML || dotType == EN_MIX) - { - double deaultValue = model->data(model->index(row, 3)).toInt(); - - SetValueInputDialog *dlg = new SetValueInputDialog(this); - dlg->setTitileLabel(title); - dlg->initView(dotType, deaultValue); - if (dlg->exec() == QDialog::Accepted) - { - value = dlg->getValue(); - delete dlg; - return true; - } - - delete dlg; - return false; - } - else if (dotType == EN_DIGITAL) - { - //CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value_di); - /* int defaultValue = model->data(model->index(row, 3)).toInt(); - bool isOk; - int retVaule = QInputDialog::getInt(NULL, - "人工置数", - "请输入置数值", - defaultValue,0 ,4,1, &isOk); - - value = retVaule;*/ - int defaultValue = model->data(model->index(row,0), Qt::UserRole + 3).toInt(); - QString stateText = model->data(model->index(row,0), Qt::UserRole + 4).toString(); - SetValueInputDialog *dlg = new SetValueInputDialog(this); - dlg->setTitileLabel(title); - dlg->setDiText(stateText); - dlg->initView(dotType, defaultValue); - if (dlg->exec() == QDialog::Accepted) - { - value = dlg->getValue(); - delete dlg; - return true; - } - - delete dlg; - return false; - } - - return false; -} - -void CDevRealDataWidget::slotCurRowChanged(const QModelIndex ¤t, const QModelIndex &previous) -{ - Q_UNUSED(previous) - bool isRefreshEnable = true; - bool isAlarmEnable = true; - bool isCtrlEnable = true; - bool isSetValueEnable = true; - - int curRow = current.row();//indexList.at(0).row(); - - QAbstractItemModel* model = ui->m_tableView->model(); - int status = model->data(model->index(curRow, 0), Qt::UserRole + 5).toInt(); - int pointType = model->data(model->index(curRow, 0), Qt::UserRole + 6).toInt(); - isRefreshEnable = CDbInterface::instance()->isRefreshEnable(status, pointType); - isAlarmEnable = CDbInterface::instance()->isAlarmEnable(status, pointType); - isCtrlEnable = CDbInterface::instance()->isCtrlEnable(status, pointType); - isSetValueEnable = CDbInterface::instance()->isSetValueEnable(status, pointType); - - ui->ctrlDiableBtn->setHidden(isCtrlEnable); - ui->ctrlEnableBtn->setHidden(!isCtrlEnable); - ui->refreshDisableBtn->setHidden(isRefreshEnable); - ui->refreshEnableBtn->setHidden(!isRefreshEnable); - ui->alarmDiableBtn->setHidden(isAlarmEnable); - ui->alarmEnableBtn->setHidden(!isAlarmEnable); - ui->setValueEnableBtn->setHidden(isSetValueEnable); - ui->setValueDisableBtn->setHidden(!isSetValueEnable); -} - -void CDevRealDataWidget::slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - Q_UNUSED(bottomRight) - Q_UNUSED(topLeft) - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); -} - -void CDevRealDataWidget::slotDeviceUpdate() -{ - m_devg = curDevGroup(); - m_devList.clear(); - m_devList = getDevByDevg(m_devg); - brush(); -} - -void CDevRealDataWidget::slotDevSearchLineChanged(const QString &text) -{ - QTreeWidgetItemIterator it( ui->treeWidget); - while (*it) { - ui->treeWidget->setItemHidden(*it,false); - ++it; - } - - searchTextItem(text,NULL); -} - -bool CDevRealDataWidget::searchTextItem(const QString& text,QTreeWidgetItem *item) -{ - bool isFinded = false; - if(item) - { - if(isItemFindText(text,item)) - { - isFinded = true; - return isFinded; - } - - int clildCount = item->childCount(); - for(int i=0; ichild(i); - if(searchTextItem(text,clild)) - { - isFinded = true; - } - } - - if(!isFinded) - { - ui->treeWidget->setItemHidden(item,true); - } - } - else - { - int clildCount = ui->treeWidget->topLevelItemCount(); - for(int i=0; itreeWidget->topLevelItem(i); - if(searchTextItem(text,clild)) - { - isFinded = true; - } - } - } - - - return isFinded; -} - -bool CDevRealDataWidget::isItemFindText(const QString &text, QTreeWidgetItem *item) -{ - if(text.isEmpty()) - { - return true; - } - - QString desc = item->text(0); - QString value = item->data(0,Qt::UserRole+1).toString(); - if(desc.contains(text) || value.contains(text)) - { - return true; - } - - return false; -} - -void CDevRealDataWidget::slotUpdateAi(QMap > aiMap) -{ - QMap >::iterator iter = aiMap.begin(); - for(; iter != aiMap.end(); iter++) - { - SortKey sortKey; - sortKey.tag_name = iter.key(); - sortKey.point_type = EN_ANALOG; - - QMap>::const_iterator sIter = m_aiMap.find(iter.key()); - if(sIter == m_aiMap.end()) - { - continue; - } - sortKey.seq_no = sIter.value().first; - sortKey.device = sIter.value().second; - - QMap::const_iterator dIter = m_realData.find(sortKey); - if(dIter == m_realData.end()) - { - continue; - } - - if(m_realData[sortKey].point_type == EN_ANALOG) - { - m_realData[sortKey].value_ai = iter.value().first; - m_realData[sortKey].status = iter.value().second; - m_realData[sortKey].isInit = true; - } - } - QList dataList = m_realData.values(); - m_realModel->updateRealValue(dataList); -} - -void CDevRealDataWidget::slotUpdateDi(QMap > diMap) -{ - QMap >::iterator iter = diMap.begin(); - for(; iter != diMap.end(); iter++) - { - SortKey sortKey; - sortKey.tag_name = iter.key(); - sortKey.point_type = EN_DIGITAL; - - QMap>::const_iterator sIter = m_diMap.find(iter.key()); - if(sIter == m_diMap.end()) - { - continue; - } - sortKey.seq_no = sIter.value().first; - sortKey.device = sIter.value().second; - - QMap::const_iterator dIter = m_realData.find(sortKey); - if(dIter == m_realData.end()) - { - continue; - } - - if(m_realData[sortKey].point_type == EN_DIGITAL) - { - m_realData[sortKey].value_di = iter.value().first; - m_realData[sortKey].status = iter.value().second; - m_realData[sortKey].isInit = true; - } - } - QList dataList = m_realData.values(); - m_realModel->updateRealValue(dataList); -} - -void CDevRealDataWidget::slotUpdatePi(QMap > piMap) -{ - QMap >::iterator iter = piMap.begin(); - for(; iter != piMap.end(); iter++) - { - SortKey sortKey; - sortKey.tag_name = iter.key(); - sortKey.point_type = EN_ACCUML; - - QMap>::const_iterator sIter = m_piMap.find(iter.key()); - if(sIter == m_piMap.end()) - { - continue; - } - sortKey.seq_no = sIter.value().first; - sortKey.device = sIter.value().second; - - QMap::const_iterator dIter = m_realData.find(sortKey); - if(dIter == m_realData.end()) - { - continue; - } - - if(m_realData[sortKey].point_type == EN_ACCUML) - { - m_realData[sortKey].value_pi = iter.value().first; - m_realData[sortKey].status = iter.value().second; - m_realData[sortKey].isInit = true; - } - } - QList dataList = m_realData.values(); - m_realModel->updateRealValue(dataList); -} - -void CDevRealDataWidget::slotUpdateMi(QMap > miMap) -{ - QMap >::iterator iter = miMap.begin(); - for(; iter != miMap.end(); iter++) - { - SortKey sortKey; - sortKey.tag_name = iter.key(); - sortKey.point_type = EN_MIX; - - QMap>::const_iterator sIter = m_miMap.find(iter.key()); - if(sIter == m_miMap.end()) - { - continue; - } - sortKey.seq_no = sIter.value().first; - sortKey.device = sIter.value().second; - - QMap::const_iterator dIter = m_realData.find(sortKey); - if(dIter == m_realData.end()) - { - continue; - } - - if(m_realData[sortKey].point_type == EN_MIX) - { - m_realData[sortKey].value_mi = iter.value().first; - m_realData[sortKey].status = iter.value().second; - m_realData[sortKey].isInit = true; - } - } - QList dataList = m_realData.values(); - m_realModel->updateRealValue(dataList); -} - -void CDevRealDataWidget::slotFilter() -{ - QString filterName = ui->m_filterEdit->text(); - for (int nIndex = 0; nIndex < m_realModel->rowCount(); nIndex++) - { - QString str = m_realModel->data(m_realModel->index(nIndex, 0), Qt::DisplayRole).toString(); - if (filterName.isEmpty() || str.contains(filterName, Qt::CaseInsensitive)) - { - ui->m_tableView->setRowHidden(nIndex, false); - } - else - { - ui->m_tableView->setRowHidden(nIndex,true); - } - } -} - -void CDevRealDataWidget::treeItemClicked(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - if(item == Q_NULLPTR) - { - m_devList.clear(); - brush(); - return; - } - if(item->data(0,Qt::UserRole).toInt() == EN_TREE_LOC) - { - return ; - }else if(item->data(0,Qt::UserRole).toInt() == EN_TREE_SUB) - { - return ; - }else if(item->data(0,Qt::UserRole).toInt() == EN_TREE_DEVG) - { - QString devg =item->data(0,Qt::UserRole+1).toString(); - m_devg = devg; - m_devList = getDevByDevg(devg); - }else if(item->data(0,Qt::UserRole).toInt() == EN_TREE_DEV) - { - m_devList.clear(); - QString dev =item->data(0,Qt::UserRole+1).toString(); - m_devList.append(dev); - } - brush(); -} - -void CDevRealDataWidget::brush() -{ - m_realData.clear(); - m_aiMap.clear(); - m_diMap.clear(); - m_piMap.clear(); - m_miMap.clear(); - m_pDpcdaForApp->unsubscribeAll(); -// LOGINFO("DEVREAL slotPointTableUpdate --unsubscribeAll()"); - - QMap> pointMap = CDbInterface::instance()->readPointInfo(m_devList, curPointTable().split(",", QString::SkipEmptyParts)); - QMap>::const_iterator fIter = pointMap.constBegin(); - for(; fIter != pointMap.constEnd(); ++fIter) - { - QMap point = fIter.value(); - QMap::const_iterator iter = point.constBegin(); - for(; iter != point.constEnd(); ++iter) - { - int subSystem = iter.value().section(",", 6, 6).toInt(); - - SRealData sRealData; - sRealData.tag_name = iter.key(); - sRealData.description = iter.value().section(",", 0, 0); - sRealData.point_type = tableNameToEnum(fIter.key()); - sRealData.device = iter.value().section(",", 1, 1); - sRealData.isInit = false; - if(sRealData.point_type == EN_ANALOG || sRealData.point_type == EN_ACCUML) - sRealData.unit = iter.value().section(",", 3, 3); - else if(sRealData.point_type == EN_DIGITAL || sRealData.point_type == EN_MIX) - sRealData.stateTextName = iter.value().section(",", 3, 3); - - sRealData.region = iter.value().section(",", 4, 4).toInt(); - sRealData.location = iter.value().section(",", 5, 5).toInt(); - sRealData.subSystem= subSystem; - - if (sRealData.point_type == EN_ANALOG) - { - sRealData.tableName = "analog"; - m_aiMap[iter.key()] = qMakePair(iter.value().section(",", 2, 2).toInt(), - iter.value().section(",", 1, 1)); - } - else if (sRealData.point_type == EN_ACCUML) - { - sRealData.tableName = "accuml"; - m_piMap[iter.key()] = qMakePair(iter.value().section(",", 2, 2).toInt(), - iter.value().section(",", 1, 1)); - } - else if (sRealData.point_type == EN_DIGITAL) - { - sRealData.tableName = "digital"; - m_diMap[iter.key()] = qMakePair(iter.value().section(",", 2, 2).toInt(), - iter.value().section(",", 1, 1)); - } - else if (sRealData.point_type == EN_MIX) - { - sRealData.tableName = "mix"; - m_miMap[iter.key()] = qMakePair(iter.value().section(",", 2, 2).toInt(), - iter.value().section(",", 1, 1)); - } - - sRealData.keyIdTag = QString("%1.%2.value").arg(sRealData.tableName).arg(sRealData.tag_name); - - SortKey sortKey; - sortKey.tag_name = iter.key(); - sortKey.point_type = tableNameToEnum(fIter.key()); - sortKey.seq_no = iter.value().section(",", 2, 2).toInt(); - sortKey.device = iter.value().section(",", 1, 1); - m_realData.insert(sortKey, sRealData); - m_pDpcdaForApp->subscribe(fIter.key().toStdString(), iter.key().toStdString(), "value"); - m_pDpcdaForApp->subscribe(fIter.key().toStdString(), iter.key().toStdString(), "status"); - // LOGINFO("DEVREAL subscribe value,status tag_name: %s", iter.key().toStdString().c_str()); - } - } - m_realModel->updateRealData(m_realData.values()); - emit ui->m_filterBtn->click(); -} - -void CDevRealDataWidget::slotEnableRefreshBtnClick() -{ - if (setRefreshTagInfo(false)) - { - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); - } -} - -void CDevRealDataWidget::slotEnableAlarmBtnClick() -{ - if (setAlarmTagInfo(false)) - { - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); - } - -} - -void CDevRealDataWidget::slotEnableSetValueBtnClick() -{ - if (setValueTagInfo(true)) - { - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); - } -} - -void CDevRealDataWidget::slotEnableCtrBtnClick() -{ - if (setCtrTagInfo(false)) - { - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); - } -} - -void CDevRealDataWidget::slotDisableRefreshBtnClick() -{ - if (setRefreshTagInfo(true)) - { - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); - } -} - -void CDevRealDataWidget::slotDisableAlarmBtnClick() -{ - if (setAlarmTagInfo(true)) - { - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); - } -} - -void CDevRealDataWidget::slotDisableSetValueBtnClick() -{ - if (setValueTagInfo(false)) - { - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); - } -} - -void CDevRealDataWidget::slotDisableCtrlBtnClick() -{ - if (setCtrTagInfo(true)) - { - QModelIndex index = ui->m_tableView->currentIndex(); - slotCurRowChanged(index, index); - } -} - -bool CDevRealDataWidget::OptTagInfo(const STOptTagInfo &info) -{ - kbd_net::CMbMessage msg; - msg.setMsgType(MT_OPT_COMMON_DOWN); - msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); - SOptTagSet sOptTagSet; - SOptTagQueue optTagQueue; - COptTagSet cOptTagSet; - - if(!createReqHead(sOptTagSet.stHead, info)) - { - return false; - } - - optTagQueue.strKeyIdTag = info.keyIdTag.toStdString(); - optTagQueue.nIsSet = info.nIsSet;// 0:取消;1:设置; - optTagQueue.fSetValue = info.setValue; - optTagQueue.strStateText = info.stateText.toStdString(); - optTagQueue.bIsPointQuery = 1; - optTagQueue.nLocationId = info.locationId; - optTagQueue.nSubSystem = info.subSystem; - - sOptTagSet.vecTagQueue.push_back(optTagQueue); - std::string content = cOptTagSet.generate(sOptTagSet); - - msg.setMsgType(info.optType); - - msg.setData(content); - if (!m_communicator->sendMsgToDomain(msg, sOptTagSet.stHead.nDstDomainID)) - { - QString mess = QString(tr("下发取消命令失败")); - slotShowMess(mess); - - return false; - } - - return true; -} - -void CDevRealDataWidget::slotShowMess(const QString &mess) -{ - QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); -} - -QString CDevRealDataWidget::checkPerm(int location, int region) -{ - int level; - int loginSec; - CPermMngApiPtr permMng = getPermMngInstance("base"); - if(permMng != NULL) - { - if(permMng->PermDllInit() != PERM_NORMAL) - { - return tr("获取登录信息失败!"); - }else - { - std::string instanceName = "DevRealDataWidget"; - if(PERM_NORMAL != permMng->CurUser(m_curUserId, m_curUsergId, level, loginSec, instanceName)) - { - m_curUserId = -1; - return tr("获取登录账户失败!"); - } - SSpeFuncDef speFunc; - speFunc.location_id = location; - speFunc.region_id = region; - speFunc.func_define = OPT_FUNC_SPE_OPT_OVERRIDE; - if (permMng->PermCheck(PERM_SPE_FUNC_DEF, &speFunc) == PERM_PERMIT) - return ""; - else - { - QString mess = QString(tr("无标签操作权限!")); - return mess; - } - - /* std::vector vecRegionOptId; - QList regList; - QList locList; - std::vector vecLocationOptId; - if(PERM_NORMAL == permMng->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) - { - - std::vector ::iterator region = vecRegionOptId.begin(); - while (region != vecRegionOptId.end()) - { - regList.append(*region++); - } - - std::vector ::iterator location = vecLocationOptId.begin(); - while (location != vecLocationOptId.end()) - { - locList.append(*location++); - } - } - if(locList.contains(location) && regList.contains(region)) - { - return ""; - }else - { - QString mess = QString(tr("无标签操作权限!")); - return mess; - }*/ - } - } - - return tr("获取登录信息失败!"); -} - -void CDevRealDataWidget::readNodeInfo() -{ - if(m_sysInfoPtr->getLocalNodeInfo(m_nodeInfo) == kbdFailed) - { - LOGERROR("获取本机节点信息失败!"); - } -} - -bool CDevRealDataWidget::createReqHead(SOptReqHead &head, const STOptTagInfo &info) -{ - SAppInfo stAppInfo; - if(kbdSuccess != m_sysInfoPtr->getAppInfoBySubsystemId(info.subSystem, stAppInfo)) - { - return false; - } - std::string instanceName = "devRealDataWidget"; - SNodeInfo& nodeInfo = m_nodeInfo; - head.strSrcTag = "DecRealDataWidget"; - head.nSrcDomainID = nodeInfo.nDomainId; - head.nDstDomainID = nodeInfo.nDomainId; - head.nAppID = stAppInfo.nId; - head.strHostName = nodeInfo.strName; - head.strInstName = instanceName; - head.strCommName = m_communicator->getName(); - head.nUserID = m_curUserId; - head.nUserGroupID = m_curUsergId; - head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - return true; -} +#include "CDevRealDataWidget.h" +#include "ui_CDevRealDataWidget.h" +#include +#include "pub_utility_api/FileStyle.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" +#include +#include +#include "SetValueInputDialog.h" + +using namespace kbd_dbms; +using namespace kbd_public; +using namespace kbd_service; +CDevRealDataWidget::CDevRealDataWidget(bool editMode, QVector ptrVec, QWidget *parent) : + QWidget(parent), + ui(new Ui::CDevRealDataWidget), + m_pDpcdaForApp(NULL), + m_realDataCollect(NULL), + m_pCollectThread(NULL), + m_realModel(NULL), + m_communicator(NULL), + m_isShowSub(false) +{ + Q_UNUSED(ptrVec); + ui->setupUi(this); + + initStyleSheet(); + ui->splitter->setSizes(QList()<<220<<1200); + + ui->frame_5->setVisible(false); + + if(!editMode) + { + qRegisterMetaType>>("QMap>"); + qRegisterMetaType>>("QMap>"); + qRegisterMetaType>>("QMap>"); + + if(!kbd_public::createSysInfoInstance(m_sysInfoPtr)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + initMsg(); + readNodeInfo(); + initialize(); + } +} + +CDevRealDataWidget::~CDevRealDataWidget() +{ + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = NULL; + + if(m_realDataCollect) + { + emit releaseCollectThread(); + } + m_realDataCollect = NULL; + + if(m_pCollectThread) + { + m_pCollectThread->quit(); + m_pCollectThread->wait(); + } + m_pCollectThread = NULL; + + CDbInterface::instance()->destory(); + + if(m_realModel) + { + delete m_realModel; + } + m_realModel = NULL; + + delete ui; +} + +void CDevRealDataWidget::initMsg() +{ + if(m_communicator == NULL) + { + m_communicator = new kbd_net::CMbCommunicator(); + } +} + +QString CDevRealDataWidget::curDevGroup() +{ + return ui->m_devGroupComb->currentData().toString(); +} + +QString CDevRealDataWidget::curPointTable() +{ + QString ret = ""; + if(ui->m_typeCb->currentIndex() == 1) + { + ret = "analog"; + } + else if(ui->m_typeCb->currentIndex() == 2) + { + ret = "digital"; + } + else if(ui->m_typeCb->currentIndex() == 3) + { + ret = "accuml"; + } + else if(ui->m_typeCb->currentIndex() == 4) + { + ret = "mix"; + } + else + { + ret = "analog,digital,accuml,mix"; + } + return ret; +} + +void CDevRealDataWidget::setTableColumnHidden(int column, bool hide) +{ + ui->m_tableView->setColumnHidden(column, hide); +} + +void CDevRealDataWidget::setTableColumnWidth(int column, int width) +{ + ui->m_tableView->setColumnWidth(column, width); +} + +void CDevRealDataWidget::resetDeviceGroup(const QStringList &tagList) +{ + ui->widget->setHidden(true); + ui->frame_5->setVisible(true); + ui->m_devGroupComb->blockSignals(true); + ui->m_devGroupComb->clear(); + + QMap devGroup = CDbInterface::instance()->readDevGroupDesc(tagList); + if(devGroup.isEmpty()) + { + return; + } + QMap::const_iterator iter = devGroup.constBegin(); + for(; iter != devGroup.constEnd(); ++iter) + { + ui->m_devGroupComb->addItem(iter.value(), iter.key()); + } + + ui->m_devGroupComb->blockSignals(false); + emit ui->m_devGroupComb->currentIndexChanged(0); +} + +void CDevRealDataWidget::setShowSubSystem(bool isShow) +{ + m_isShowSub = isShow; + ui->label_4->setVisible(m_isShowSub); + ui->m_subCb->setVisible(m_isShowSub); +} + +void CDevRealDataWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + qssfile1.close(); + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("deviceRealData.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + qssfile2.close(); + + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CDevRealDataWidget::initialize() +{ + ui->m_subCb->setView(new QListView()); + ui->m_locCb->setView(new QListView()); + ui->m_devGroupComb->setView(new QListView()); + ui->m_typeCb->setView(new QListView()); + ui->m_typeCb->setEnabled(true); + + //< 初始化专业 + //< 默认不区分专业 + ui->label_4->setVisible(m_isShowSub); + ui->m_subCb->setVisible(m_isShowSub); + ui->m_subCb->addItem(tr("所有"),CN_InvalidSubsystemId); + std::vector vecSubsystemInfo; + m_sysInfoPtr->getAllSubsystemInfo(vecSubsystemInfo); + std::vector::iterator subIter = vecSubsystemInfo.begin(); + for(; subIter!=vecSubsystemInfo.end(); ++subIter) + { + SSubsystemInfo& info = *subIter; + if(info.nId < 4) + { + continue; + } + ui->m_subCb->addItem(QString::fromStdString(info.strDesc),info.nId); + } + + //< 初始化位置 + std::vector vecLocationInfo; + m_sysInfoPtr->getAllLocationInfo(vecLocationInfo); + std::vector::iterator locIter = vecLocationInfo.begin(); + for(; locIter!=vecLocationInfo.end(); ++locIter) + { + SLocationInfo& info = *locIter; + ui->m_locCb->addItem(QString::fromStdString(info.strDesc),info.nId); + } + + //< 初始化订阅线程 + m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); + m_realDataCollect = new CRealDataCollect; + m_pCollectThread = new QThread(this); + m_realDataCollect->moveToThread(m_pCollectThread); + connect(m_pCollectThread, &QThread::finished, m_pCollectThread, &QThread::deleteLater); + connect(this, &CDevRealDataWidget::releaseCollectThread, m_realDataCollect, &CRealDataCollect::release, Qt::BlockingQueuedConnection); + connect(m_realDataCollect, &CRealDataCollect::signal_updateAi, this, &CDevRealDataWidget::slotUpdateAi); + connect(m_realDataCollect, &CRealDataCollect::signal_updateDi, this, &CDevRealDataWidget::slotUpdateDi); + connect(m_realDataCollect, &CRealDataCollect::signal_updatePi, this, &CDevRealDataWidget::slotUpdatePi); + connect(m_realDataCollect, &CRealDataCollect::signal_updateMi, this, &CDevRealDataWidget::slotUpdateMi); + m_pCollectThread->start(); + + //< 初始化表格模型 + m_realModel = new CRealTableModel(this); + ui->m_tableView->setModel(m_realModel); + ui->m_tableView->horizontalHeader()->setStretchLastSection(true); + connect(ui->m_tableView->selectionModel(), + SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), + this, + SLOT(slotCurRowChanged(const QModelIndex &, const QModelIndex &))); + + connect(m_realModel, + SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, + SLOT(slotDataChanged(const QModelIndex &, const QModelIndex &))); + + ui->treeWidget->setColumnCount(1); + setTableColumnWidth(0,300); + setTableColumnWidth(2,300); + connect(ui->m_subCb, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTreeWidget())); + connect(ui->m_locCb, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTreeWidget())); + connect(ui->m_devGroupComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDeviceUpdate())); + connect(ui->m_typeCb, SIGNAL(currentIndexChanged(int)), this, SLOT(brush())); + connect(ui->mSearchLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotDevSearchLineChanged(const QString&))); + connect(ui->m_filterBtn, SIGNAL(clicked()), this, SLOT(slotFilter())); + connect(ui->m_filterEdit, SIGNAL(returnPressed()), this, SLOT(slotFilter())); + connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CDevRealDataWidget::treeItemClicked); + + updateTreeWidget(); + + //< 初始化标签设置按钮 + bool isRefreshEnable = false; + bool isAlarmEnable = false; + bool isCtrlEnable = false; + bool isSetValueEnable = false; + ui->ctrlDiableBtn->setHidden(isCtrlEnable); + ui->ctrlEnableBtn->setHidden(!isCtrlEnable); + ui->refreshDisableBtn->setHidden(isRefreshEnable); + ui->refreshEnableBtn->setHidden(!isRefreshEnable); + ui->alarmDiableBtn->setHidden(isAlarmEnable); + ui->alarmEnableBtn->setHidden(!isAlarmEnable); + ui->setValueEnableBtn->setHidden(isSetValueEnable); + ui->setValueDisableBtn->setHidden(!isSetValueEnable); + connect(ui->refreshEnableBtn, SIGNAL(clicked()), this, SLOT(slotEnableRefreshBtnClick())); + connect(ui->alarmEnableBtn, SIGNAL(clicked()), this, SLOT(slotEnableAlarmBtnClick())); + connect(ui->setValueEnableBtn, SIGNAL(clicked()), this, SLOT(slotEnableSetValueBtnClick())); + connect(ui->ctrlEnableBtn, SIGNAL(clicked()), this, SLOT(slotEnableCtrBtnClick())); + connect(ui->refreshDisableBtn, SIGNAL(clicked()), this, SLOT(slotDisableRefreshBtnClick())); + connect(ui->alarmDiableBtn, SIGNAL(clicked()), this, SLOT(slotDisableAlarmBtnClick())); + connect(ui->setValueDisableBtn, SIGNAL(clicked()), this, SLOT(slotDisableSetValueBtnClick())); + connect(ui->ctrlDiableBtn, SIGNAL(clicked()), this, SLOT(slotDisableCtrlBtnClick())); +} + +void CDevRealDataWidget::updateTreeWidget() +{ + ui->mSearchLineEdit->clear(); + cleanTreeWidget(); + int nLocId = ui->m_locCb->currentData().toInt(); + int nSubId = ui->m_subCb->currentData().toInt(); + QList> devgList; + if(!CDbInterface::instance()->queryDevGroupInfoList(nLocId,nSubId,devgList)) + { + slotShowMess(tr("查询设备组信息失败!")); + return; + } + for(int nIndex(0);nIndexsetText(0,devgList.at(nIndex).second); + devgItem->setData(0,Qt::UserRole,(int)EN_TREE_DEVG);//类型 + devgItem->setData(0,Qt::UserRole+1,devgList.at(nIndex).first);//值 + ui->treeWidget->addTopLevelItem(devgItem); + + QMap devInfo = CDbInterface::instance()->deviceInfo(devgList.at(nIndex).first); + QMap::iterator pos = devInfo.begin(); + while (pos != devInfo.end()) { + QTreeWidgetItem *devItem = new QTreeWidgetItem(); + devItem->setText(0,pos.value()); + devItem->setData(0,Qt::UserRole,(int)EN_TREE_DEV);//类型 + devItem->setData(0,Qt::UserRole+1,pos.key());//值 + devgItem->addChild(devItem); + pos++; + } + } + if(ui->treeWidget->topLevelItem(0)) + { + emit ui->treeWidget->itemClicked(ui->treeWidget->topLevelItem(0), 0); + } +} + +void CDevRealDataWidget::cleanTreeWidget() +{ + for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) + { + ui->treeWidget->takeTopLevelItem(index); + } + treeItemClicked(Q_NULLPTR,0); +} + +int CDevRealDataWidget::tableNameToEnum(const QString &tableName) +{ + if(tableName == "analog") + { + return EN_ANALOG; + } + else if(tableName == "digital") + { + return EN_DIGITAL; + } + else if(tableName == "accuml") + { + return EN_ACCUML; + } + else if(tableName == "mix") + { + return EN_MIX; + } + else + { + return -1; + } +} + +QList CDevRealDataWidget::getDevByDevg(const QString &devg) +{ + return CDbInterface::instance()->deviceInfoByDevg(devg); +} + +bool CDevRealDataWidget::setValueTagInfo(bool isEnable) +{ + QItemSelectionModel* selModel = ui->m_tableView->selectionModel(); + QModelIndexList indexList = selModel->selectedRows(); + if (indexList.count() <= 0) + { + slotShowMess(tr("请至少选择一项!")); + return false; + } + + QString titleStr = ""; + + CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); + foreach(QModelIndex index, indexList) + { + int location = model->data(model->index(index.row(), 0), Qt::UserRole + 8).toInt(); + int region = model->data(model->index(index.row(), 0), Qt::UserRole + 7).toInt(); + + QString desc = model->data(model->index(index.row(), 0), Qt::DisplayRole).toString(); + QString retStr = checkPerm(location, region); + if (!retStr.isEmpty()) + { + QString meg = QString(tr("行“%1”,%2")).arg(desc).arg(retStr); + slotShowMess(meg); + return false; + } + if(titleStr.isEmpty()) + titleStr = desc; + } + + if(indexList.count() > 1) + { + titleStr = QString(tr("“%1”等,共(%2)项")).arg(titleStr).arg(indexList.count()); + } + + int firstRow = indexList.at(0).row(); + double value = 0; + if (isEnable) + { + if (!getSetValue(titleStr,firstRow, value)) + { + return false; + } + } + + foreach(QModelIndex index, indexList) { + int row = index.row(); + + STOptTagInfo info; + info.tagName = ""; + info.setValue = value; + info.nIsSet = isEnable?1:0;// 0:取消;1:设置; + info.optType = MT_OPT_TAG_VALUE_SET; + info.tagName = model->data(model->index(row, 0), Qt::UserRole + 2).toString(); + info.keyIdTag = model->data(model->index(row, 0), Qt::UserRole + 1).toString(); + info.subSystem = model->data(model->index(row, 0), Qt::UserRole + 9).toInt(); + info.locationId = model->data(model->index(row, 0), Qt::UserRole + 8).toInt(); + + if (!OptTagInfo(info)) + { + return false; + } + } + return true; +} + +bool CDevRealDataWidget::setRefreshTagInfo(bool isEnable) +{ + QItemSelectionModel* selModel = ui->m_tableView->selectionModel(); + QModelIndexList indexList = selModel->selectedRows(); + if (indexList.count() <= 0) + { + slotShowMess(tr("请至少选择一项!")); + return false; + } + + CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); + foreach(QModelIndex index, indexList) + { + int location = model->data(model->index(index.row(), 0), Qt::UserRole + 8).toInt(); + int region = model->data(model->index(index.row(), 0), Qt::UserRole + 7).toInt(); + + QString desc = model->data(model->index(index.row(), 0), Qt::DisplayRole).toString(); + QString retStr = checkPerm(location, region); + if (!retStr.isEmpty()) + { + QString meg = QString(tr("“%1”,%2")).arg(desc).arg(retStr); + slotShowMess(meg); + return false; + } + } + + foreach(QModelIndex index, indexList) { + int row = index.row(); + + STOptTagInfo info; + info.tagName = ""; + info.setValue = 0; + info.nIsSet = isEnable ? 1 : 0;// 0:取消;1:设置; + info.optType = MT_OPT_PINHIBIT_REF; + + info.tagName = model->data(model->index(row, 0), Qt::UserRole + 2).toString(); + info.keyIdTag = model->data(model->index(row, 0), Qt::UserRole + 1).toString(); + info.subSystem = model->data(model->index(row, 0), Qt::UserRole + 9).toInt(); + info.locationId = model->data(model->index(row, 0), Qt::UserRole + 8).toInt(); + + + if (!OptTagInfo(info)) + { + return false; + } + } + return true; +} + +bool CDevRealDataWidget::setAlarmTagInfo(bool isEnable) +{ + QItemSelectionModel* selModel = ui->m_tableView->selectionModel(); + QModelIndexList indexList = selModel->selectedRows(); + if (indexList.count() <= 0) + { + slotShowMess(tr("请至少选择一项!")); + return false; + } + + CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); + foreach(QModelIndex index, indexList) + { + int location = model->data(model->index(index.row(), 0), Qt::UserRole + 8).toInt(); + int region = model->data(model->index(index.row(), 0), Qt::UserRole + 7).toInt(); + + QString desc = model->data(model->index(index.row(), 0), Qt::DisplayRole).toString(); + QString retStr = checkPerm(location, region); + if (!retStr.isEmpty()) + { + QString meg = QString(tr("“%1”,%2")).arg(desc).arg(retStr); + slotShowMess(meg); + return false; + } + } + + foreach(QModelIndex index, indexList) { + int row = index.row(); + + STOptTagInfo info; + info.tagName = ""; + info.setValue = 0; + info.nIsSet = isEnable ? 1 : 0;// 0:取消;1:设置; + info.optType = MT_OPT_PINHIBIT_ALARM; + info.tagName = model->data(model->index(row, 0), Qt::UserRole + 2).toString(); + info.keyIdTag = model->data(model->index(row, 0), Qt::UserRole + 1).toString(); + info.subSystem = model->data(model->index(row, 0), Qt::UserRole + 9).toInt(); + info.locationId = model->data(model->index(row, 0), Qt::UserRole + 8).toInt(); + + + if (!OptTagInfo(info)) + { + return false; + } + } + return true; +} + +bool CDevRealDataWidget::setCtrTagInfo(bool isEnable) +{ + QItemSelectionModel* selModel = ui->m_tableView->selectionModel(); + QModelIndexList indexList = selModel->selectedRows(); + if (indexList.count() <= 0) + { + slotShowMess(tr("请至少选择一项!")); + return false; + } + + CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); + foreach(QModelIndex index, indexList) + { + int location = model->data(model->index(index.row(), 0), Qt::UserRole + 8).toInt(); + int region = model->data(model->index(index.row(), 0), Qt::UserRole + 7).toInt(); + + QString desc = model->data(model->index(index.row(), 0), Qt::DisplayRole).toString(); + QString retStr = checkPerm(location, region); + if (!retStr.isEmpty()) + { + QString meg = QString(tr("“%1”,%2")).arg(desc).arg(retStr); + slotShowMess(meg); + return false; + } + } + + foreach(QModelIndex index, indexList) { + int row = index.row(); + + STOptTagInfo info; + info.tagName = ""; + info.setValue = 0; + info.nIsSet = isEnable ? 1 : 0;// 0:取消;1:设置; + info.optType = MT_OPT_PINHIBIT_CTRL; + info.tagName = model->data(model->index(row, 0), Qt::UserRole + 2).toString(); + info.keyIdTag = model->data(model->index(row, 0), Qt::UserRole + 1).toString(); + info.subSystem = model->data(model->index(row, 0), Qt::UserRole + 9).toInt(); + info.locationId = model->data(model->index(row, 0), Qt::UserRole + 8).toInt(); + + if (!OptTagInfo(info)) + { + return false; + } + } + return true; +} + +bool CDevRealDataWidget::getSetValue(const QString& title,int row, double& value) +{ + QAbstractItemModel* model = ui->m_tableView->model(); + + int dotType = model->data(model->index(row, 0), Qt::UserRole + 6).toInt(); + + if (dotType == EN_ANALOG || dotType == EN_ACCUML || dotType == EN_MIX) + { + double deaultValue = model->data(model->index(row, 3)).toInt(); + + SetValueInputDialog *dlg = new SetValueInputDialog(this); + dlg->setTitileLabel(title); + dlg->initView(dotType, deaultValue); + if (dlg->exec() == QDialog::Accepted) + { + value = dlg->getValue(); + delete dlg; + return true; + } + + delete dlg; + return false; + } + else if (dotType == EN_DIGITAL) + { + //CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value_di); + /* int defaultValue = model->data(model->index(row, 3)).toInt(); + bool isOk; + int retVaule = QInputDialog::getInt(NULL, + "人工置数", + "请输入置数值", + defaultValue,0 ,4,1, &isOk); + + value = retVaule;*/ + int defaultValue = model->data(model->index(row,0), Qt::UserRole + 3).toInt(); + QString stateText = model->data(model->index(row,0), Qt::UserRole + 4).toString(); + SetValueInputDialog *dlg = new SetValueInputDialog(this); + dlg->setTitileLabel(title); + dlg->setDiText(stateText); + dlg->initView(dotType, defaultValue); + if (dlg->exec() == QDialog::Accepted) + { + value = dlg->getValue(); + delete dlg; + return true; + } + + delete dlg; + return false; + } + + return false; +} + +void CDevRealDataWidget::slotCurRowChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_UNUSED(previous) + bool isRefreshEnable = true; + bool isAlarmEnable = true; + bool isCtrlEnable = true; + bool isSetValueEnable = true; + + int curRow = current.row();//indexList.at(0).row(); + + QAbstractItemModel* model = ui->m_tableView->model(); + int status = model->data(model->index(curRow, 0), Qt::UserRole + 5).toInt(); + int pointType = model->data(model->index(curRow, 0), Qt::UserRole + 6).toInt(); + isRefreshEnable = CDbInterface::instance()->isRefreshEnable(status, pointType); + isAlarmEnable = CDbInterface::instance()->isAlarmEnable(status, pointType); + isCtrlEnable = CDbInterface::instance()->isCtrlEnable(status, pointType); + isSetValueEnable = CDbInterface::instance()->isSetValueEnable(status, pointType); + + ui->ctrlDiableBtn->setHidden(isCtrlEnable); + ui->ctrlEnableBtn->setHidden(!isCtrlEnable); + ui->refreshDisableBtn->setHidden(isRefreshEnable); + ui->refreshEnableBtn->setHidden(!isRefreshEnable); + ui->alarmDiableBtn->setHidden(isAlarmEnable); + ui->alarmEnableBtn->setHidden(!isAlarmEnable); + ui->setValueEnableBtn->setHidden(isSetValueEnable); + ui->setValueDisableBtn->setHidden(!isSetValueEnable); +} + +void CDevRealDataWidget::slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + Q_UNUSED(bottomRight) + Q_UNUSED(topLeft) + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); +} + +void CDevRealDataWidget::slotDeviceUpdate() +{ + m_devg = curDevGroup(); + m_devList.clear(); + m_devList = getDevByDevg(m_devg); + brush(); +} + +void CDevRealDataWidget::slotDevSearchLineChanged(const QString &text) +{ + QTreeWidgetItemIterator it( ui->treeWidget); + while (*it) { + ui->treeWidget->setItemHidden(*it,false); + ++it; + } + + searchTextItem(text,NULL); +} + +bool CDevRealDataWidget::searchTextItem(const QString& text,QTreeWidgetItem *item) +{ + bool isFinded = false; + if(item) + { + if(isItemFindText(text,item)) + { + isFinded = true; + return isFinded; + } + + int clildCount = item->childCount(); + for(int i=0; ichild(i); + if(searchTextItem(text,clild)) + { + isFinded = true; + } + } + + if(!isFinded) + { + ui->treeWidget->setItemHidden(item,true); + } + } + else + { + int clildCount = ui->treeWidget->topLevelItemCount(); + for(int i=0; itreeWidget->topLevelItem(i); + if(searchTextItem(text,clild)) + { + isFinded = true; + } + } + } + + + return isFinded; +} + +bool CDevRealDataWidget::isItemFindText(const QString &text, QTreeWidgetItem *item) +{ + if(text.isEmpty()) + { + return true; + } + + QString desc = item->text(0); + QString value = item->data(0,Qt::UserRole+1).toString(); + if(desc.contains(text) || value.contains(text)) + { + return true; + } + + return false; +} + +void CDevRealDataWidget::slotUpdateAi(QMap > aiMap) +{ + QMap >::iterator iter = aiMap.begin(); + for(; iter != aiMap.end(); iter++) + { + SortKey sortKey; + sortKey.tag_name = iter.key(); + sortKey.point_type = EN_ANALOG; + + QMap>::const_iterator sIter = m_aiMap.find(iter.key()); + if(sIter == m_aiMap.end()) + { + continue; + } + sortKey.seq_no = sIter.value().first; + sortKey.device = sIter.value().second; + + QMap::const_iterator dIter = m_realData.find(sortKey); + if(dIter == m_realData.end()) + { + continue; + } + + if(m_realData[sortKey].point_type == EN_ANALOG) + { + m_realData[sortKey].value_ai = iter.value().first; + m_realData[sortKey].status = iter.value().second; + m_realData[sortKey].isInit = true; + } + } + QList dataList = m_realData.values(); + m_realModel->updateRealValue(dataList); +} + +void CDevRealDataWidget::slotUpdateDi(QMap > diMap) +{ + QMap >::iterator iter = diMap.begin(); + for(; iter != diMap.end(); iter++) + { + SortKey sortKey; + sortKey.tag_name = iter.key(); + sortKey.point_type = EN_DIGITAL; + + QMap>::const_iterator sIter = m_diMap.find(iter.key()); + if(sIter == m_diMap.end()) + { + continue; + } + sortKey.seq_no = sIter.value().first; + sortKey.device = sIter.value().second; + + QMap::const_iterator dIter = m_realData.find(sortKey); + if(dIter == m_realData.end()) + { + continue; + } + + if(m_realData[sortKey].point_type == EN_DIGITAL) + { + m_realData[sortKey].value_di = iter.value().first; + m_realData[sortKey].status = iter.value().second; + m_realData[sortKey].isInit = true; + } + } + QList dataList = m_realData.values(); + m_realModel->updateRealValue(dataList); +} + +void CDevRealDataWidget::slotUpdatePi(QMap > piMap) +{ + QMap >::iterator iter = piMap.begin(); + for(; iter != piMap.end(); iter++) + { + SortKey sortKey; + sortKey.tag_name = iter.key(); + sortKey.point_type = EN_ACCUML; + + QMap>::const_iterator sIter = m_piMap.find(iter.key()); + if(sIter == m_piMap.end()) + { + continue; + } + sortKey.seq_no = sIter.value().first; + sortKey.device = sIter.value().second; + + QMap::const_iterator dIter = m_realData.find(sortKey); + if(dIter == m_realData.end()) + { + continue; + } + + if(m_realData[sortKey].point_type == EN_ACCUML) + { + m_realData[sortKey].value_pi = iter.value().first; + m_realData[sortKey].status = iter.value().second; + m_realData[sortKey].isInit = true; + } + } + QList dataList = m_realData.values(); + m_realModel->updateRealValue(dataList); +} + +void CDevRealDataWidget::slotUpdateMi(QMap > miMap) +{ + QMap >::iterator iter = miMap.begin(); + for(; iter != miMap.end(); iter++) + { + SortKey sortKey; + sortKey.tag_name = iter.key(); + sortKey.point_type = EN_MIX; + + QMap>::const_iterator sIter = m_miMap.find(iter.key()); + if(sIter == m_miMap.end()) + { + continue; + } + sortKey.seq_no = sIter.value().first; + sortKey.device = sIter.value().second; + + QMap::const_iterator dIter = m_realData.find(sortKey); + if(dIter == m_realData.end()) + { + continue; + } + + if(m_realData[sortKey].point_type == EN_MIX) + { + m_realData[sortKey].value_mi = iter.value().first; + m_realData[sortKey].status = iter.value().second; + m_realData[sortKey].isInit = true; + } + } + QList dataList = m_realData.values(); + m_realModel->updateRealValue(dataList); +} + +void CDevRealDataWidget::slotFilter() +{ + QString filterName = ui->m_filterEdit->text(); + for (int nIndex = 0; nIndex < m_realModel->rowCount(); nIndex++) + { + QString str = m_realModel->data(m_realModel->index(nIndex, 0), Qt::DisplayRole).toString(); + if (filterName.isEmpty() || str.contains(filterName, Qt::CaseInsensitive)) + { + ui->m_tableView->setRowHidden(nIndex, false); + } + else + { + ui->m_tableView->setRowHidden(nIndex,true); + } + } +} + +void CDevRealDataWidget::treeItemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + if(item == Q_NULLPTR) + { + m_devList.clear(); + brush(); + return; + } + if(item->data(0,Qt::UserRole).toInt() == EN_TREE_LOC) + { + return ; + }else if(item->data(0,Qt::UserRole).toInt() == EN_TREE_SUB) + { + return ; + }else if(item->data(0,Qt::UserRole).toInt() == EN_TREE_DEVG) + { + QString devg =item->data(0,Qt::UserRole+1).toString(); + m_devg = devg; + m_devList = getDevByDevg(devg); + }else if(item->data(0,Qt::UserRole).toInt() == EN_TREE_DEV) + { + m_devList.clear(); + QString dev =item->data(0,Qt::UserRole+1).toString(); + m_devList.append(dev); + } + brush(); +} + +void CDevRealDataWidget::brush() +{ + m_realData.clear(); + m_aiMap.clear(); + m_diMap.clear(); + m_piMap.clear(); + m_miMap.clear(); + m_pDpcdaForApp->unsubscribeAll(); +// LOGINFO("DEVREAL slotPointTableUpdate --unsubscribeAll()"); + + QMap> pointMap = CDbInterface::instance()->readPointInfo(m_devList, curPointTable().split(",", QString::SkipEmptyParts)); + QMap>::const_iterator fIter = pointMap.constBegin(); + for(; fIter != pointMap.constEnd(); ++fIter) + { + QMap point = fIter.value(); + QMap::const_iterator iter = point.constBegin(); + for(; iter != point.constEnd(); ++iter) + { + int subSystem = iter.value().section(",", 6, 6).toInt(); + + SRealData sRealData; + sRealData.tag_name = iter.key(); + sRealData.description = iter.value().section(",", 0, 0); + sRealData.point_type = tableNameToEnum(fIter.key()); + sRealData.device = iter.value().section(",", 1, 1); + sRealData.isInit = false; + if(sRealData.point_type == EN_ANALOG || sRealData.point_type == EN_ACCUML) + sRealData.unit = iter.value().section(",", 3, 3); + else if(sRealData.point_type == EN_DIGITAL || sRealData.point_type == EN_MIX) + sRealData.stateTextName = iter.value().section(",", 3, 3); + + sRealData.region = iter.value().section(",", 4, 4).toInt(); + sRealData.location = iter.value().section(",", 5, 5).toInt(); + sRealData.subSystem= subSystem; + + if (sRealData.point_type == EN_ANALOG) + { + sRealData.tableName = "analog"; + m_aiMap[iter.key()] = qMakePair(iter.value().section(",", 2, 2).toInt(), + iter.value().section(",", 1, 1)); + } + else if (sRealData.point_type == EN_ACCUML) + { + sRealData.tableName = "accuml"; + m_piMap[iter.key()] = qMakePair(iter.value().section(",", 2, 2).toInt(), + iter.value().section(",", 1, 1)); + } + else if (sRealData.point_type == EN_DIGITAL) + { + sRealData.tableName = "digital"; + m_diMap[iter.key()] = qMakePair(iter.value().section(",", 2, 2).toInt(), + iter.value().section(",", 1, 1)); + } + else if (sRealData.point_type == EN_MIX) + { + sRealData.tableName = "mix"; + m_miMap[iter.key()] = qMakePair(iter.value().section(",", 2, 2).toInt(), + iter.value().section(",", 1, 1)); + } + + sRealData.keyIdTag = QString("%1.%2.value").arg(sRealData.tableName).arg(sRealData.tag_name); + + SortKey sortKey; + sortKey.tag_name = iter.key(); + sortKey.point_type = tableNameToEnum(fIter.key()); + sortKey.seq_no = iter.value().section(",", 2, 2).toInt(); + sortKey.device = iter.value().section(",", 1, 1); + m_realData.insert(sortKey, sRealData); + m_pDpcdaForApp->subscribe(fIter.key().toStdString(), iter.key().toStdString(), "value"); + m_pDpcdaForApp->subscribe(fIter.key().toStdString(), iter.key().toStdString(), "status"); + // LOGINFO("DEVREAL subscribe value,status tag_name: %s", iter.key().toStdString().c_str()); + } + } + m_realModel->updateRealData(m_realData.values()); + emit ui->m_filterBtn->click(); +} + +void CDevRealDataWidget::slotEnableRefreshBtnClick() +{ + if (setRefreshTagInfo(false)) + { + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); + } +} + +void CDevRealDataWidget::slotEnableAlarmBtnClick() +{ + if (setAlarmTagInfo(false)) + { + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); + } + +} + +void CDevRealDataWidget::slotEnableSetValueBtnClick() +{ + if (setValueTagInfo(true)) + { + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); + } +} + +void CDevRealDataWidget::slotEnableCtrBtnClick() +{ + if (setCtrTagInfo(false)) + { + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); + } +} + +void CDevRealDataWidget::slotDisableRefreshBtnClick() +{ + if (setRefreshTagInfo(true)) + { + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); + } +} + +void CDevRealDataWidget::slotDisableAlarmBtnClick() +{ + if (setAlarmTagInfo(true)) + { + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); + } +} + +void CDevRealDataWidget::slotDisableSetValueBtnClick() +{ + if (setValueTagInfo(false)) + { + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); + } +} + +void CDevRealDataWidget::slotDisableCtrlBtnClick() +{ + if (setCtrTagInfo(true)) + { + QModelIndex index = ui->m_tableView->currentIndex(); + slotCurRowChanged(index, index); + } +} + +bool CDevRealDataWidget::OptTagInfo(const STOptTagInfo &info) +{ + kbd_net::CMbMessage msg; + msg.setMsgType(MT_OPT_COMMON_DOWN); + msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); + SOptTagSet sOptTagSet; + SOptTagQueue optTagQueue; + COptTagSet cOptTagSet; + + if(!createReqHead(sOptTagSet.stHead, info)) + { + return false; + } + + optTagQueue.strKeyIdTag = info.keyIdTag.toStdString(); + optTagQueue.nIsSet = info.nIsSet;// 0:取消;1:设置; + optTagQueue.fSetValue = info.setValue; + optTagQueue.strStateText = info.stateText.toStdString(); + optTagQueue.bIsPointQuery = 1; + optTagQueue.nLocationId = info.locationId; + optTagQueue.nSubSystem = info.subSystem; + + sOptTagSet.vecTagQueue.push_back(optTagQueue); + std::string content = cOptTagSet.generate(sOptTagSet); + + msg.setMsgType(info.optType); + + msg.setData(content); + if (!m_communicator->sendMsgToDomain(msg, sOptTagSet.stHead.nDstDomainID)) + { + QString mess = QString(tr("下发取消命令失败")); + slotShowMess(mess); + + return false; + } + + return true; +} + +void CDevRealDataWidget::slotShowMess(const QString &mess) +{ + QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); +} + +QString CDevRealDataWidget::checkPerm(int location, int region) +{ + int level; + int loginSec; + CPermMngApiPtr permMng = getPermMngInstance("base"); + if(permMng != NULL) + { + if(permMng->PermDllInit() != PERM_NORMAL) + { + return tr("获取登录信息失败!"); + }else + { + std::string instanceName = "DevRealDataWidget"; + if(PERM_NORMAL != permMng->CurUser(m_curUserId, m_curUsergId, level, loginSec, instanceName)) + { + m_curUserId = -1; + return tr("获取登录账户失败!"); + } + SSpeFuncDef speFunc; + speFunc.location_id = location; + speFunc.region_id = region; + speFunc.func_define = OPT_FUNC_SPE_OPT_OVERRIDE; + if (permMng->PermCheck(PERM_SPE_FUNC_DEF, &speFunc) == PERM_PERMIT) + return ""; + else + { + QString mess = QString(tr("无标签操作权限!")); + return mess; + } + + /* std::vector vecRegionOptId; + QList regList; + QList locList; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMng->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) + { + + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + regList.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + locList.append(*location++); + } + } + if(locList.contains(location) && regList.contains(region)) + { + return ""; + }else + { + QString mess = QString(tr("无标签操作权限!")); + return mess; + }*/ + } + } + + return tr("获取登录信息失败!"); +} + +void CDevRealDataWidget::readNodeInfo() +{ + if(m_sysInfoPtr->getLocalNodeInfo(m_nodeInfo) == kbdFailed) + { + LOGERROR("获取本机节点信息失败!"); + } +} + +bool CDevRealDataWidget::createReqHead(SOptReqHead &head, const STOptTagInfo &info) +{ + SAppInfo stAppInfo; + if(kbdSuccess != m_sysInfoPtr->getAppInfoBySubsystemId(info.subSystem, stAppInfo)) + { + return false; + } + std::string instanceName = "devRealDataWidget"; + SNodeInfo& nodeInfo = m_nodeInfo; + head.strSrcTag = "DecRealDataWidget"; + head.nSrcDomainID = nodeInfo.nDomainId; + head.nDstDomainID = nodeInfo.nDomainId; + head.nAppID = stAppInfo.nId; + head.strHostName = nodeInfo.strName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = m_curUserId; + head.nUserGroupID = m_curUsergId; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + return true; +} diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.h b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.h index 7c6d18b2..9ce55d54 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.h +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.h @@ -1,129 +1,129 @@ -#ifndef CDEVREALDATAWIDGET_H -#define CDEVREALDATAWIDGET_H - -#include -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "CDbInterface.h" -#include "CRealTableModel.h" -#include "CRealDataCollect.h" -#include -#include "pub_sysinfo_api/SysInfoApi.h" -#include "service/operate_server_api/JsonMessageStruct.h" -#include "service/operate_server_api/JsonOptCommand.h" -#include "DevRealDataCommon.h" - -namespace Ui { -class CDevRealDataWidget; -} - -enum EN_TREE_TYPE -{ - EN_TREE_LOC = 1001, - EN_TREE_SUB = 1002, - EN_TREE_DEVG = 1003, - EN_TREE_DEV = 1004 -}; - -class CDevRealDataWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CDevRealDataWidget(bool editMode, QVector ptrVec, QWidget *parent = 0); - ~CDevRealDataWidget(); - - QString curDevGroup(); - QString curPointTable(); - QString curDeviceStr(); - - void initMsg(); - -signals: - void releaseCollectThread(); - -public slots: - void setTableColumnHidden(int column, bool hide); - void setTableColumnWidth(int column, int width); - void resetDeviceGroup(const QStringList& tagList); - void setShowSubSystem(bool isShow); - -private: - void initStyleSheet(); - void initialize(); - - void cleanTreeWidget(); - int tableNameToEnum(const QString& tableName); - - QList getDevByDevg(const QString &devg); - - bool setValueTagInfo(bool isEnable); - bool setRefreshTagInfo(bool isEnable); - bool setAlarmTagInfo(bool isEnable); - bool setCtrTagInfo(bool isEnable); - bool getSetValue(const QString& title,int row, double& value); - bool OptTagInfo(const STOptTagInfo &info); - bool createReqHead(SOptReqHead &head, const STOptTagInfo &info); - - void slotShowMess(const QString &mess); - - QString checkPerm(int location, int region); - - void readNodeInfo(); - - bool searchTextItem(const QString& text,QTreeWidgetItem *item); - bool isItemFindText(const QString& text,QTreeWidgetItem *item); -private slots: - void slotCurRowChanged(const QModelIndex ¤t, const QModelIndex &previous); - void slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - void slotDeviceUpdate(); - void slotDevSearchLineChanged(const QString& text); - //void slotPointTableUpdate(); - - void slotUpdateAi(QMap> aiMap); - void slotUpdateDi(QMap> diMap); - void slotUpdatePi(QMap> piMap); - void slotUpdateMi(QMap> miMap); - - void slotFilter(); - - void treeItemClicked(QTreeWidgetItem *item, int column); - - void updateTreeWidget(); - void brush(); - - void slotEnableRefreshBtnClick();//禁止刷新 - void slotEnableAlarmBtnClick();//禁止告警 - void slotEnableSetValueBtnClick();//人工置数 - void slotEnableCtrBtnClick();//禁止控制 - - void slotDisableRefreshBtnClick();//禁止刷新 - void slotDisableAlarmBtnClick();//禁止告警 - void slotDisableSetValueBtnClick();//人工置数 - void slotDisableCtrlBtnClick();//禁止控制 -private: - Ui::CDevRealDataWidget *ui; - kbd_service::CDpcdaForApp *m_pDpcdaForApp; - CRealDataCollect *m_realDataCollect; - QThread *m_pCollectThread; - CRealTableModel *m_realModel; - QMap m_realData; - - QString m_devg;//search - QList m_devList; //search - - kbd_net::CMbCommunicator *m_communicator; - - int m_curUserId; - int m_curUsergId; - - kbd_public::CSysInfoInterfacePtr m_sysInfoPtr; - kbd_public::SNodeInfo m_nodeInfo; - - QMap> m_aiMap; //模拟量序号和设备标签 - QMap> m_diMap; //数字量序号和设备标签 - QMap> m_piMap; //累积量序号和设备标签 - QMap> m_miMap; //混合量序号和设备标签 - bool m_isShowSub; -}; - -#endif // CDEVREALDATAWIDGET_H +#ifndef CDEVREALDATAWIDGET_H +#define CDEVREALDATAWIDGET_H + +#include +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "CDbInterface.h" +#include "CRealTableModel.h" +#include "CRealDataCollect.h" +#include +#include "pub_sysinfo_api/SysInfoApi.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "DevRealDataCommon.h" + +namespace Ui { +class CDevRealDataWidget; +} + +enum EN_TREE_TYPE +{ + EN_TREE_LOC = 1001, + EN_TREE_SUB = 1002, + EN_TREE_DEVG = 1003, + EN_TREE_DEV = 1004 +}; + +class CDevRealDataWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CDevRealDataWidget(bool editMode, QVector ptrVec, QWidget *parent = 0); + ~CDevRealDataWidget(); + + QString curDevGroup(); + QString curPointTable(); + QString curDeviceStr(); + + void initMsg(); + +signals: + void releaseCollectThread(); + +public slots: + void setTableColumnHidden(int column, bool hide); + void setTableColumnWidth(int column, int width); + void resetDeviceGroup(const QStringList& tagList); + void setShowSubSystem(bool isShow); + +private: + void initStyleSheet(); + void initialize(); + + void cleanTreeWidget(); + int tableNameToEnum(const QString& tableName); + + QList getDevByDevg(const QString &devg); + + bool setValueTagInfo(bool isEnable); + bool setRefreshTagInfo(bool isEnable); + bool setAlarmTagInfo(bool isEnable); + bool setCtrTagInfo(bool isEnable); + bool getSetValue(const QString& title,int row, double& value); + bool OptTagInfo(const STOptTagInfo &info); + bool createReqHead(SOptReqHead &head, const STOptTagInfo &info); + + void slotShowMess(const QString &mess); + + QString checkPerm(int location, int region); + + void readNodeInfo(); + + bool searchTextItem(const QString& text,QTreeWidgetItem *item); + bool isItemFindText(const QString& text,QTreeWidgetItem *item); +private slots: + void slotCurRowChanged(const QModelIndex ¤t, const QModelIndex &previous); + void slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void slotDeviceUpdate(); + void slotDevSearchLineChanged(const QString& text); + //void slotPointTableUpdate(); + + void slotUpdateAi(QMap> aiMap); + void slotUpdateDi(QMap> diMap); + void slotUpdatePi(QMap> piMap); + void slotUpdateMi(QMap> miMap); + + void slotFilter(); + + void treeItemClicked(QTreeWidgetItem *item, int column); + + void updateTreeWidget(); + void brush(); + + void slotEnableRefreshBtnClick();//禁止刷新 + void slotEnableAlarmBtnClick();//禁止告警 + void slotEnableSetValueBtnClick();//人工置数 + void slotEnableCtrBtnClick();//禁止控制 + + void slotDisableRefreshBtnClick();//禁止刷新 + void slotDisableAlarmBtnClick();//禁止告警 + void slotDisableSetValueBtnClick();//人工置数 + void slotDisableCtrlBtnClick();//禁止控制 +private: + Ui::CDevRealDataWidget *ui; + kbd_service::CDpcdaForApp *m_pDpcdaForApp; + CRealDataCollect *m_realDataCollect; + QThread *m_pCollectThread; + CRealTableModel *m_realModel; + QMap m_realData; + + QString m_devg;//search + QList m_devList; //search + + kbd_net::CMbCommunicator *m_communicator; + + int m_curUserId; + int m_curUsergId; + + kbd_public::CSysInfoInterfacePtr m_sysInfoPtr; + kbd_public::SNodeInfo m_nodeInfo; + + QMap> m_aiMap; //模拟量序号和设备标签 + QMap> m_diMap; //数字量序号和设备标签 + QMap> m_piMap; //累积量序号和设备标签 + QMap> m_miMap; //混合量序号和设备标签 + bool m_isShowSub; +}; + +#endif // CDEVREALDATAWIDGET_H diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.ui b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.ui index 6fbfec24..32d57653 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.ui +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.ui @@ -1,436 +1,436 @@ - - - CDevRealDataWidget - - - - 0 - 0 - 1192 - 484 - - - - CDevRealDataWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - - - Qt::Horizontal - - - - - 300 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - 位置 - - - - - - - 专业 - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 关键字查询 - - - false - - - - - - - false - - - - 1 - - - - - - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 禁止控制 - - - - - - - 恢复控制 - - - - - - - 禁止刷新 - - - - - - - 恢复刷新 - - - - - - - 禁止告警 - - - - - - - 恢复告警 - - - - - - - 人工置数 - - - - - - - 取消置数 - - - - - - - - - QAbstractItemView::SelectRows - - - - - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 80 - 16777215 - - - - 设备组 - - - Qt::AlignCenter - - - - - - - - - - - - - 点类型 - - - - - - - - 全部 - - - - - 模拟量 - - - - - 数字量 - - - - - 累积量 - - - - - 混合量 - - - - - - - - - 50 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 200 - 16777215 - - - - 关键字查询 - - - - - - - 查询 - - - - - - - - - - - - - - - - - - - - - - CTableView - QTableView -
CTableView.h
-
-
- - -
+ + + CDevRealDataWidget + + + + 0 + 0 + 1192 + 484 + + + + CDevRealDataWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + + + Qt::Horizontal + + + + + 300 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + 位置 + + + + + + + 专业 + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 关键字查询 + + + false + + + + + + + false + + + + 1 + + + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 禁止控制 + + + + + + + 恢复控制 + + + + + + + 禁止刷新 + + + + + + + 恢复刷新 + + + + + + + 禁止告警 + + + + + + + 恢复告警 + + + + + + + 人工置数 + + + + + + + 取消置数 + + + + + + + + + QAbstractItemView::SelectRows + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 80 + 16777215 + + + + 设备组 + + + Qt::AlignCenter + + + + + + + + + + + + + 点类型 + + + + + + + + 全部 + + + + + 模拟量 + + + + + 数字量 + + + + + 累积量 + + + + + 混合量 + + + + + + + + + 50 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 200 + 16777215 + + + + 关键字查询 + + + + + + + 查询 + + + + + + + + + + + + + + + + + + + + + + CTableView + QTableView +
CTableView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.cpp b/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.cpp index fa4ef04c..f5f42068 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.cpp @@ -1,223 +1,223 @@ -#include "CRealDataCollect.h" -#include - -CRealDataCollect::CRealDataCollect(QObject *parent) - : QObject(parent), - m_pMbComm(NULL), - m_pTimer(NULL), - m_nTimeCount(0) -{ - initMsg(); - if(!addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE)) - { - return; - } - - m_pTimer = new QTimer(this); - connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); - m_pTimer->start(100); -} - -CRealDataCollect::~CRealDataCollect() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - closeMsg(); -} - -void CRealDataCollect::release() -{ - delete this; -} - -void CRealDataCollect::initMsg() -{ - if(m_pMbComm == NULL) - { - m_pMbComm = new kbd_net::CMbCommunicator("DevRealDataWidget"); - } -} - -void CRealDataCollect::closeMsg() -{ - if(m_pMbComm != NULL) - { - delete m_pMbComm; - } - m_pMbComm = NULL; -} - -bool CRealDataCollect::addSub(int appID, int channel) -{ - if(m_pMbComm) - { - return m_pMbComm->addSub(appID, channel); - } - else - { - return false; - } -} - -bool CRealDataCollect::delSub(int appID, int channel) -{ - if(m_pMbComm) - { - return m_pMbComm->delSub(appID, channel); - } - else - { - return false; - } -} - -void CRealDataCollect::recvMessage() -{ - m_nTimeCount = (m_nTimeCount + 1) % 36000; - - if(m_nTimeCount % 10 == 0) - { - processChangeData(); - } - - try - { - kbd_net::CMbMessage objMsg; - for(int i = 0; i < 6; i++) - { - if(m_pMbComm->recvMsg(objMsg, 0)) - { - if(objMsg.isValid()) - { - if(objMsg.getChannelID() == CH_SCADA_TO_HMI_DATA_CHANGE - && objMsg.getMsgType() == kbd_idlfile::MT_DP_CHANGE_DATA) - { - parserMsg(objMsg); - } - } - } - } - } - catch(...) - { - - } -} - -void CRealDataCollect::processChangeData() -{ - if(!m_aiMap.isEmpty()) - { - emit signal_updateAi(m_aiMap); - m_aiMap.clear(); - } - - if(!m_diMap.isEmpty()) - { - emit signal_updateDi(m_diMap); - m_diMap.clear(); - } - - if(!m_piMap.isEmpty()) - { - emit signal_updatePi(m_piMap); - m_piMap.clear(); - } - - if(!m_miMap.isEmpty()) - { - emit signal_updateMi(m_miMap); - m_miMap.clear(); - } -} - -int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) -{ - kbd_idlfile::SRealTimeDataPkg changeDataPackage; - try - { - changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); - int aiSize = changeDataPackage.stairtd_size(); - if(aiSize > 0) - { - kbd_idlfile::SAiRealTimeData aiStru; - QString tagName; - float value; - uint status; - for(int i = 0; i < aiSize;++i) - { - aiStru = changeDataPackage.stairtd(i); - tagName = QString::fromStdString(aiStru.strtagname()); - value = aiStru.fvalue(); - status = aiStru.ustatus(); -// emit signal_updateAi(tagName, value, status); - m_aiMap[tagName] = qMakePair(value, status); - } - } - - int diSize = changeDataPackage.stdirtd_size(); - if(diSize > 0) - { - kbd_idlfile::SDiRealTimeData diStu; - QString tagName; - int value; - uint status; - for(int i = 0; i < diSize; ++i) - { - diStu = changeDataPackage.stdirtd(i); - tagName = QString::fromStdString(diStu.strtagname()); - value = diStu.nvalue(); - status = diStu.ustatus(); -// emit signal_updateDi(tagName, value, status); - m_diMap[tagName] = qMakePair(value, status); - } - } - - int piSize = changeDataPackage.stpirtd_size(); - if(piSize > 0) - { - kbd_idlfile::SPiRealTimeData piStu; - QString tagName; - double value; - uint status; - for(int i = 0 ; i < piSize; ++i) - { - piStu = changeDataPackage.stpirtd(i); - tagName = QString::fromStdString(piStu.strtagname()); - value = piStu.dvalue(); - status = piStu.ustatus(); -// emit signal_updatePi(tagName, value, status); - m_piMap[tagName] = qMakePair(value, status); - } - } - - int miSize = changeDataPackage.stmirtd_size(); - if(miSize > 0) - { - kbd_idlfile::SMiRealTimeData miStu; - QString tagName; - int value; - uint status; - for(int i = 0 ; i < miSize ; ++i) - { - miStu = changeDataPackage.stmirtd(i); - tagName = QString::fromStdString(miStu.strtagname()); - value = miStu.nvalue(); - status = miStu.ustatus(); -// emit signal_updateMi(tagName, value, status); - m_miMap[tagName] = qMakePair(value, status); - } - } - } - catch(...) - { - return 0; - } - return 1; -} +#include "CRealDataCollect.h" +#include + +CRealDataCollect::CRealDataCollect(QObject *parent) + : QObject(parent), + m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0) +{ + initMsg(); + if(!addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE)) + { + return; + } + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CRealDataCollect::~CRealDataCollect() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + closeMsg(); +} + +void CRealDataCollect::release() +{ + delete this; +} + +void CRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new kbd_net::CMbCommunicator("DevRealDataWidget"); + } +} + +void CRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +bool CRealDataCollect::addSub(int appID, int channel) +{ + if(m_pMbComm) + { + return m_pMbComm->addSub(appID, channel); + } + else + { + return false; + } +} + +bool CRealDataCollect::delSub(int appID, int channel) +{ + if(m_pMbComm) + { + return m_pMbComm->delSub(appID, channel); + } + else + { + return false; + } +} + +void CRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { + processChangeData(); + } + + try + { + kbd_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getChannelID() == CH_SCADA_TO_HMI_DATA_CHANGE + && objMsg.getMsgType() == kbd_idlfile::MT_DP_CHANGE_DATA) + { + parserMsg(objMsg); + } + } + } + } + } + catch(...) + { + + } +} + +void CRealDataCollect::processChangeData() +{ + if(!m_aiMap.isEmpty()) + { + emit signal_updateAi(m_aiMap); + m_aiMap.clear(); + } + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + + if(!m_piMap.isEmpty()) + { + emit signal_updatePi(m_piMap); + m_piMap.clear(); + } + + if(!m_miMap.isEmpty()) + { + emit signal_updateMi(m_miMap); + m_miMap.clear(); + } +} + +int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) +{ + kbd_idlfile::SRealTimeDataPkg changeDataPackage; + try + { + changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); + int aiSize = changeDataPackage.stairtd_size(); + if(aiSize > 0) + { + kbd_idlfile::SAiRealTimeData aiStru; + QString tagName; + float value; + uint status; + for(int i = 0; i < aiSize;++i) + { + aiStru = changeDataPackage.stairtd(i); + tagName = QString::fromStdString(aiStru.strtagname()); + value = aiStru.fvalue(); + status = aiStru.ustatus(); +// emit signal_updateAi(tagName, value, status); + m_aiMap[tagName] = qMakePair(value, status); + } + } + + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + kbd_idlfile::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); +// emit signal_updateDi(tagName, value, status); + m_diMap[tagName] = qMakePair(value, status); + } + } + + int piSize = changeDataPackage.stpirtd_size(); + if(piSize > 0) + { + kbd_idlfile::SPiRealTimeData piStu; + QString tagName; + double value; + uint status; + for(int i = 0 ; i < piSize; ++i) + { + piStu = changeDataPackage.stpirtd(i); + tagName = QString::fromStdString(piStu.strtagname()); + value = piStu.dvalue(); + status = piStu.ustatus(); +// emit signal_updatePi(tagName, value, status); + m_piMap[tagName] = qMakePair(value, status); + } + } + + int miSize = changeDataPackage.stmirtd_size(); + if(miSize > 0) + { + kbd_idlfile::SMiRealTimeData miStu; + QString tagName; + int value; + uint status; + for(int i = 0 ; i < miSize ; ++i) + { + miStu = changeDataPackage.stmirtd(i); + tagName = QString::fromStdString(miStu.strtagname()); + value = miStu.nvalue(); + status = miStu.ustatus(); +// emit signal_updateMi(tagName, value, status); + m_miMap[tagName] = qMakePair(value, status); + } + } + } + catch(...) + { + return 0; + } + return 1; +} diff --git a/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.h b/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.h index 789760c4..a6724d94 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.h +++ b/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.h @@ -1,49 +1,49 @@ -#ifndef CREALDATACOLLECT_H -#define CREALDATACOLLECT_H - -#include -#include -#include "net_msg_bus_api/CMbCommunicator.h" -#include "MessageChannel.h" -#include "DataProcMessage.pb.h" - -class QTimer; -class CRealDataCollect : public QObject -{ - Q_OBJECT -public: - explicit CRealDataCollect(QObject * parent = 0); - ~CRealDataCollect(); - -public slots: - void release(); - -private: - void initMsg(); - void closeMsg(); - bool addSub(int appID, int channel); - bool delSub(int appID, int channel); - - int parserMsg(const kbd_net::CMbMessage &); - -private slots: - void recvMessage(); - void processChangeData(); - -signals: - void signal_updateAi(QMap> aiMap); - void signal_updateDi(QMap> diMap); - void signal_updatePi(QMap> piMap); - void signal_updateMi(QMap> miMap); - -private: - kbd_net::CMbCommunicator *m_pMbComm; - QTimer * m_pTimer; - int m_nTimeCount; - QMap> m_aiMap; - QMap> m_diMap; - QMap> m_piMap; - QMap> m_miMap; -}; - -#endif // CREALDATACOLLECT_H +#ifndef CREALDATACOLLECT_H +#define CREALDATACOLLECT_H + +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" + +class QTimer; +class CRealDataCollect : public QObject +{ + Q_OBJECT +public: + explicit CRealDataCollect(QObject * parent = 0); + ~CRealDataCollect(); + +public slots: + void release(); + +private: + void initMsg(); + void closeMsg(); + bool addSub(int appID, int channel); + bool delSub(int appID, int channel); + + int parserMsg(const kbd_net::CMbMessage &); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateAi(QMap> aiMap); + void signal_updateDi(QMap> diMap); + void signal_updatePi(QMap> piMap); + void signal_updateMi(QMap> miMap); + +private: + kbd_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + QMap> m_aiMap; + QMap> m_diMap; + QMap> m_piMap; + QMap> m_miMap; +}; + +#endif // CREALDATACOLLECT_H diff --git a/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.cpp b/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.cpp index f36707d6..1bbc02f2 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.cpp @@ -1,180 +1,180 @@ -#include "CRealTableModel.h" - -CRealTableModel::CRealTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header << tr("测点") << tr("点类型") << tr("设备") << tr("值") << tr("状态"); - -} - -void CRealTableModel::updateRealData(const QList &dataList) -{ - beginResetModel(); - m_listRealData = dataList; - endResetModel(); -} - -void CRealTableModel::updateRealValue(QList &dataList) -{ - m_listRealData.swap(dataList); - update(); -} - -void CRealTableModel::update() -{ - QModelIndex topLeft = createIndex(0, 3); - QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); - emit dataChanged(topLeft, bottomRight); -} - -QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(role == Qt::DisplayRole) - { - if(orientation == Qt::Horizontal) - { - return m_header.at(section); - } - } - return QVariant(); -} - -int CRealTableModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_listRealData.size(); -} - -int CRealTableModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.size(); -} - -QVariant CRealTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if(role == Qt::TextAlignmentRole) - { - return Qt::AlignCenter; - } - - if(role == Qt::TextColorRole) - { - //判断是否告警未复归 如果复归则把值颜色修改为红色否则返回QVariant(); - if(m_listRealData.at(index.row()).isInit && index.column() == 3 && m_listRealData.at(index.row()).point_type == EN_DIGITAL) - { - int status = m_listRealData.at(index.row()).status; - if((status & 1024) == 1024) - { - return QVariant(QBrush(QColor(255,0,0))); - } - } - return QVariant(); - } - if (index.column() == 0) - { - if (role == Qt::UserRole + 1) - { - return m_listRealData.at(index.row()).keyIdTag; - } - else if (role == Qt::UserRole + 2) - { - return m_listRealData.at(index.row()).tag_name; - } - else if (role == Qt::UserRole + 3) - { - return m_listRealData.at(index.row()).tableName; - } - else if (role == Qt::UserRole + 4) - { - return m_listRealData.at(index.row()).stateTextName; - } - else if (role == Qt::UserRole + 5) - { - return m_listRealData.at(index.row()).status; - } - else if (role == Qt::UserRole + 6) - { - return m_listRealData.at(index.row()).point_type; - } - else if (role == Qt::UserRole + 7) - { - return m_listRealData.at(index.row()).region; - } - else if (role == Qt::UserRole + 8) - { - return m_listRealData.at(index.row()).location; - } - else if (role == Qt::UserRole + 9) - { - return m_listRealData.at(index.row()).subSystem; - } - } - - if(role != Qt::DisplayRole) - { - return QVariant(); - } - - switch (index.column()) { - case 0: - { - return m_listRealData.at(index.row()).description + m_listRealData.at(index.row()).unit; - break; - } - case 1: - { - return CDbInterface::instance()->getPointDesc(m_listRealData.at(index.row()).point_type); - break; - } - case 2: - { - return m_listRealData.at(index.row()).device; - break; - } - case 3: - { - if(m_listRealData.at(index.row()).isInit == false) - { - return ""; - } - if(m_listRealData.at(index.row()).point_type == EN_ANALOG) - { - return QString::number(m_listRealData.at(index.row()).value_ai, 'f', 2); - } - else if(m_listRealData.at(index.row()).point_type == EN_DIGITAL) - { - return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value_di); - } - else if(m_listRealData.at(index.row()).point_type == EN_ACCUML) - { - return QString::number(m_listRealData.at(index.row()).value_pi, 'f', 2); - } - else if(m_listRealData.at(index.row()).point_type == EN_MIX) - { - return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value_mi); - } - break; - } - case 4: - { - if(m_listRealData.at(index.row()).isInit == false) - { - return ""; - } - return CDbInterface::instance()->getStatusStr(m_listRealData.at(index.row()).status, m_listRealData.at(index.row()).point_type); - break; - } - default: - break; - } - - return QVariant(); -} +#include "CRealTableModel.h" + +CRealTableModel::CRealTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header << tr("测点") << tr("点类型") << tr("设备") << tr("值") << tr("状态"); + +} + +void CRealTableModel::updateRealData(const QList &dataList) +{ + beginResetModel(); + m_listRealData = dataList; + endResetModel(); +} + +void CRealTableModel::updateRealValue(QList &dataList) +{ + m_listRealData.swap(dataList); + update(); +} + +void CRealTableModel::update() +{ + QModelIndex topLeft = createIndex(0, 3); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); + emit dataChanged(topLeft, bottomRight); +} + +QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(role == Qt::DisplayRole) + { + if(orientation == Qt::Horizontal) + { + return m_header.at(section); + } + } + return QVariant(); +} + +int CRealTableModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_listRealData.size(); +} + +int CRealTableModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.size(); +} + +QVariant CRealTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if(role == Qt::TextAlignmentRole) + { + return Qt::AlignCenter; + } + + if(role == Qt::TextColorRole) + { + //判断是否告警未复归 如果复归则把值颜色修改为红色否则返回QVariant(); + if(m_listRealData.at(index.row()).isInit && index.column() == 3 && m_listRealData.at(index.row()).point_type == EN_DIGITAL) + { + int status = m_listRealData.at(index.row()).status; + if((status & 1024) == 1024) + { + return QVariant(QBrush(QColor(255,0,0))); + } + } + return QVariant(); + } + if (index.column() == 0) + { + if (role == Qt::UserRole + 1) + { + return m_listRealData.at(index.row()).keyIdTag; + } + else if (role == Qt::UserRole + 2) + { + return m_listRealData.at(index.row()).tag_name; + } + else if (role == Qt::UserRole + 3) + { + return m_listRealData.at(index.row()).tableName; + } + else if (role == Qt::UserRole + 4) + { + return m_listRealData.at(index.row()).stateTextName; + } + else if (role == Qt::UserRole + 5) + { + return m_listRealData.at(index.row()).status; + } + else if (role == Qt::UserRole + 6) + { + return m_listRealData.at(index.row()).point_type; + } + else if (role == Qt::UserRole + 7) + { + return m_listRealData.at(index.row()).region; + } + else if (role == Qt::UserRole + 8) + { + return m_listRealData.at(index.row()).location; + } + else if (role == Qt::UserRole + 9) + { + return m_listRealData.at(index.row()).subSystem; + } + } + + if(role != Qt::DisplayRole) + { + return QVariant(); + } + + switch (index.column()) { + case 0: + { + return m_listRealData.at(index.row()).description + m_listRealData.at(index.row()).unit; + break; + } + case 1: + { + return CDbInterface::instance()->getPointDesc(m_listRealData.at(index.row()).point_type); + break; + } + case 2: + { + return m_listRealData.at(index.row()).device; + break; + } + case 3: + { + if(m_listRealData.at(index.row()).isInit == false) + { + return ""; + } + if(m_listRealData.at(index.row()).point_type == EN_ANALOG) + { + return QString::number(m_listRealData.at(index.row()).value_ai, 'f', 2); + } + else if(m_listRealData.at(index.row()).point_type == EN_DIGITAL) + { + return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value_di); + } + else if(m_listRealData.at(index.row()).point_type == EN_ACCUML) + { + return QString::number(m_listRealData.at(index.row()).value_pi, 'f', 2); + } + else if(m_listRealData.at(index.row()).point_type == EN_MIX) + { + return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value_mi); + } + break; + } + case 4: + { + if(m_listRealData.at(index.row()).isInit == false) + { + return ""; + } + return CDbInterface::instance()->getStatusStr(m_listRealData.at(index.row()).status, m_listRealData.at(index.row()).point_type); + break; + } + default: + break; + } + + return QVariant(); +} diff --git a/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.h b/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.h index fbefda9d..0b76c451 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.h +++ b/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.h @@ -1,90 +1,90 @@ -#ifndef CREALTABLEMODEL_H -#define CREALTABLEMODEL_H - -#include -#include "CDbInterface.h" - -struct SortKey -{ - QString tag_name; - int seq_no; - int point_type; - QString device; - - inline bool operator==(const SortKey &other) const - { - if(point_type != other.point_type) - { - return false; - } - return tag_name == other.tag_name; - } - - inline bool operator<(const SortKey &other) const - { - if(point_type != other.point_type) - { - return point_type < other.point_type; - } - if(device.compare(other.device) != 0) - { - return device < other.device; - } - if(seq_no != other.seq_no) - { - return seq_no < other.seq_no; - } - if(tag_name.compare(other.tag_name) != 0) - { - return tag_name < other.tag_name; - } - return point_type < other.point_type;; - } -}; -struct SRealData -{ - QString keyIdTag; - QString tableName; - QString tag_name; - QString description; - int point_type; - QString device; - float value_ai; - int value_di; - double value_pi; - int value_mi; - uint status; - QString unit; - QString stateTextName; - bool isInit; - int region; - int location; - int subSystem; -}; - -class CRealTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CRealTableModel(QObject *parent = nullptr); - - void updateRealData(const QList &dataList); - - void updateRealValue(QList &dataList); - - void update(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: - QStringList m_header; - QList m_listRealData; -}; - -#endif // CREALTABLEMODEL_H +#ifndef CREALTABLEMODEL_H +#define CREALTABLEMODEL_H + +#include +#include "CDbInterface.h" + +struct SortKey +{ + QString tag_name; + int seq_no; + int point_type; + QString device; + + inline bool operator==(const SortKey &other) const + { + if(point_type != other.point_type) + { + return false; + } + return tag_name == other.tag_name; + } + + inline bool operator<(const SortKey &other) const + { + if(point_type != other.point_type) + { + return point_type < other.point_type; + } + if(device.compare(other.device) != 0) + { + return device < other.device; + } + if(seq_no != other.seq_no) + { + return seq_no < other.seq_no; + } + if(tag_name.compare(other.tag_name) != 0) + { + return tag_name < other.tag_name; + } + return point_type < other.point_type;; + } +}; +struct SRealData +{ + QString keyIdTag; + QString tableName; + QString tag_name; + QString description; + int point_type; + QString device; + float value_ai; + int value_di; + double value_pi; + int value_mi; + uint status; + QString unit; + QString stateTextName; + bool isInit; + int region; + int location; + int subSystem; +}; + +class CRealTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CRealTableModel(QObject *parent = nullptr); + + void updateRealData(const QList &dataList); + + void updateRealValue(QList &dataList); + + void update(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QStringList m_header; + QList m_listRealData; +}; + +#endif // CREALTABLEMODEL_H diff --git a/product/src/gui/plugin/DevRealDataWidget/CTableView.cpp b/product/src/gui/plugin/DevRealDataWidget/CTableView.cpp index 5102d89d..5a5658ac 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CTableView.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CTableView.cpp @@ -1,32 +1,32 @@ -#include "CTableView.h" -#include - -CTableView::CTableView(QWidget *parent) - : QTableView(parent) -{ - -} - -int CTableView::tableColumnWidth() -{ - return m_nTableColWidth; -} - -void CTableView::setTableColumnWidth(const int &nWidth) -{ - m_nTableColWidth = nWidth; - - horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); -} - -int CTableView::tableRowHeight() -{ - return m_nTableRowHeight; -} - -void CTableView::setTableRowHeight(const int &nHeight) -{ - m_nTableRowHeight = nHeight; - - verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); -} +#include "CTableView.h" +#include + +CTableView::CTableView(QWidget *parent) + : QTableView(parent) +{ + +} + +int CTableView::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CTableView::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CTableView::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CTableView::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} diff --git a/product/src/gui/plugin/DevRealDataWidget/CTableView.h b/product/src/gui/plugin/DevRealDataWidget/CTableView.h index 8b457048..6335001f 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CTableView.h +++ b/product/src/gui/plugin/DevRealDataWidget/CTableView.h @@ -1,26 +1,26 @@ -#ifndef CTABLEVIEW_H -#define CTABLEVIEW_H - -#include - -class CTableView : public QTableView -{ - Q_OBJECT - Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) - Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) - -public: - CTableView(QWidget *parent = Q_NULLPTR); - - int tableColumnWidth(); - void setTableColumnWidth(const int &nWidth); - - int tableRowHeight(); - void setTableRowHeight(const int &nHeight); - -private: - int m_nTableColWidth; - int m_nTableRowHeight; -}; - -#endif // CTABLEVIEW_H +#ifndef CTABLEVIEW_H +#define CTABLEVIEW_H + +#include + +class CTableView : public QTableView +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + CTableView(QWidget *parent = Q_NULLPTR); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + +private: + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +#endif // CTABLEVIEW_H diff --git a/product/src/gui/plugin/DevRealDataWidget/DevRealDataCommon.h b/product/src/gui/plugin/DevRealDataWidget/DevRealDataCommon.h index da9bf813..8488048c 100644 --- a/product/src/gui/plugin/DevRealDataWidget/DevRealDataCommon.h +++ b/product/src/gui/plugin/DevRealDataWidget/DevRealDataCommon.h @@ -1,49 +1,49 @@ -#ifndef CDEVREALDATACOMMON_H -#define CDEVREALDATACOMMON_H - -#include - -#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") - -struct STOptTagInfo -{ - QString keyIdTag; - int optType; - qint64 optTime; - int locationId; - int subSystem; - double setValue; - int nIsSet; - QString stateText; - QString hostName; - QString userName; - QString userGroup; - - QString tagName; - QString devName; - QString table; -}; - -struct STTagInfo -{ - QString tagName; - QString desc; - QString devName; - QString devDesc; - QString devgName; - int region; - -}; - -struct STLocationInfo -{ - int id; - QString desc; - int domainId; - STLocationInfo() { - id = -1; - domainId = -1; - } -}; - -#endif // CDEVREALDATACOMMON_H +#ifndef CDEVREALDATACOMMON_H +#define CDEVREALDATACOMMON_H + +#include + +#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") + +struct STOptTagInfo +{ + QString keyIdTag; + int optType; + qint64 optTime; + int locationId; + int subSystem; + double setValue; + int nIsSet; + QString stateText; + QString hostName; + QString userName; + QString userGroup; + + QString tagName; + QString devName; + QString table; +}; + +struct STTagInfo +{ + QString tagName; + QString desc; + QString devName; + QString devDesc; + QString devgName; + int region; + +}; + +struct STLocationInfo +{ + int id; + QString desc; + int domainId; + STLocationInfo() { + id = -1; + domainId = -1; + } +}; + +#endif // CDEVREALDATACOMMON_H diff --git a/product/src/gui/plugin/DevRealDataWidget/DevRealDataWidget.pro b/product/src/gui/plugin/DevRealDataWidget/DevRealDataWidget.pro index 22933dc7..633226a7 100644 --- a/product/src/gui/plugin/DevRealDataWidget/DevRealDataWidget.pro +++ b/product/src/gui/plugin/DevRealDataWidget/DevRealDataWidget.pro @@ -1,76 +1,76 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-02-21T11:06:51 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = DevRealDataWidget -TEMPLATE = lib - - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - CDevRealDataWidget.cpp \ - CRealDataCollect.cpp \ - CDbInterface.cpp \ - CRealTableModel.cpp \ - main.cpp \ - CDevRealDataPluginWidget.cpp \ - SetValueInputDialog.cpp \ - CTableView.cpp - -HEADERS += \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - CDevRealDataWidget.h \ - CRealDataCollect.h \ - CDbInterface.h \ - CRealTableModel.h \ - CDevRealDataPluginWidget.h \ - DevRealDataCommon.h \ - SetValueInputDialog.h \ - CTableView.h - -FORMS += \ - CDevRealDataWidget.ui \ - SetValueInputDialog.ui - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lprotobuf \ - -lnet_msg_bus_api \ - -ldb_base_api \ - -ldb_api_ex \ - -lpub_sysinfo_api \ - -ldp_chg_data_api \ - -lrdb_api \ - -lrdb_net_api \ - -lpub_utility_api \ - -lperm_mng_api - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2020-02-21T11:06:51 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = DevRealDataWidget +TEMPLATE = lib + + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + CDevRealDataWidget.cpp \ + CRealDataCollect.cpp \ + CDbInterface.cpp \ + CRealTableModel.cpp \ + main.cpp \ + CDevRealDataPluginWidget.cpp \ + SetValueInputDialog.cpp \ + CTableView.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CDevRealDataWidget.h \ + CRealDataCollect.h \ + CDbInterface.h \ + CRealTableModel.h \ + CDevRealDataPluginWidget.h \ + DevRealDataCommon.h \ + SetValueInputDialog.h \ + CTableView.h + +FORMS += \ + CDevRealDataWidget.ui \ + SetValueInputDialog.ui + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lprotobuf \ + -lnet_msg_bus_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lpub_sysinfo_api \ + -ldp_chg_data_api \ + -lrdb_api \ + -lrdb_net_api \ + -lpub_utility_api \ + -lperm_mng_api + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.cpp b/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.cpp index 766dbd64..c5490730 100644 --- a/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.cpp @@ -1,69 +1,69 @@ -#include "SetValueInputDialog.h" -#include "ui_SetValueInputDialog.h" -#include "CDbInterface.h" -#include - -SetValueInputDialog::SetValueInputDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::SetValueInputDialog) -{ - ui->setupUi(this); - setWindowTitle(tr("人工置数")); - connect(ui->okBtn, SIGNAL(clicked()), this, SLOT(accept())); - connect(ui->cannelBtn, SIGNAL(clicked()), this, SLOT(reject())); -} - -SetValueInputDialog::~SetValueInputDialog() -{ - delete ui; -} - -void SetValueInputDialog::setTitileLabel(const QString &title) -{ - ui->mTitileLabel->setText(title); -} - -void SetValueInputDialog::setDiText(const QString& text) -{ - mDiStatusText.clear(); - CDbInterface::instance()->getStateTextList(text, mDiStatusText); - - ui->comboBox->clear(); - QMap::iterator iter = mDiStatusText.begin(); - for (; iter !=mDiStatusText.end(); ++iter) - { - ui->comboBox->addItem(iter.value(), iter.key()); - } - // ui->comboBox->add -} - -void SetValueInputDialog::initView(int dotType, double defaultValue) -{ - mDotValue = dotType; - if (dotType == EN_ANALOG || dotType == EN_ACCUML || dotType == EN_MIX) - { - ui->stackedWidget->setCurrentIndex(0); - ui->lineEdit->setText(QString::number(defaultValue)); - } - else if (dotType == EN_DIGITAL) - { - ui->stackedWidget->setCurrentIndex(1); - - } - -} - -double SetValueInputDialog::getValue() -{ - double value = 0; - QStackedWidget* sw = ui->stackedWidget; - if (sw->currentIndex() == 0) - { - value = ui->lineEdit->text().toDouble(); - } - else - { - value = ui->comboBox->currentData().toDouble(); - } - return value; -} +#include "SetValueInputDialog.h" +#include "ui_SetValueInputDialog.h" +#include "CDbInterface.h" +#include + +SetValueInputDialog::SetValueInputDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SetValueInputDialog) +{ + ui->setupUi(this); + setWindowTitle(tr("人工置数")); + connect(ui->okBtn, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->cannelBtn, SIGNAL(clicked()), this, SLOT(reject())); +} + +SetValueInputDialog::~SetValueInputDialog() +{ + delete ui; +} + +void SetValueInputDialog::setTitileLabel(const QString &title) +{ + ui->mTitileLabel->setText(title); +} + +void SetValueInputDialog::setDiText(const QString& text) +{ + mDiStatusText.clear(); + CDbInterface::instance()->getStateTextList(text, mDiStatusText); + + ui->comboBox->clear(); + QMap::iterator iter = mDiStatusText.begin(); + for (; iter !=mDiStatusText.end(); ++iter) + { + ui->comboBox->addItem(iter.value(), iter.key()); + } + // ui->comboBox->add +} + +void SetValueInputDialog::initView(int dotType, double defaultValue) +{ + mDotValue = dotType; + if (dotType == EN_ANALOG || dotType == EN_ACCUML || dotType == EN_MIX) + { + ui->stackedWidget->setCurrentIndex(0); + ui->lineEdit->setText(QString::number(defaultValue)); + } + else if (dotType == EN_DIGITAL) + { + ui->stackedWidget->setCurrentIndex(1); + + } + +} + +double SetValueInputDialog::getValue() +{ + double value = 0; + QStackedWidget* sw = ui->stackedWidget; + if (sw->currentIndex() == 0) + { + value = ui->lineEdit->text().toDouble(); + } + else + { + value = ui->comboBox->currentData().toDouble(); + } + return value; +} diff --git a/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.h b/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.h index 54d82f4b..bbef4c33 100644 --- a/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.h +++ b/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.h @@ -1,33 +1,33 @@ -#ifndef SETVALUEINPUTDIALOG_H -#define SETVALUEINPUTDIALOG_H - -#include -#include - -namespace Ui { -class SetValueInputDialog; -} - -class SetValueInputDialog : public QDialog -{ - Q_OBJECT - -public: - explicit SetValueInputDialog(QWidget *parent = 0); - ~SetValueInputDialog(); - - void setTitileLabel(const QString& title); - void setDiText(const QString& text); - void initView(int dotType,double defaultValue); - - double getValue(); - - -private: - Ui::SetValueInputDialog *ui; - int mDotValue; - QMap mDiStatusText; - -}; - -#endif // SETVALUEINPUTDIALOG_H +#ifndef SETVALUEINPUTDIALOG_H +#define SETVALUEINPUTDIALOG_H + +#include +#include + +namespace Ui { +class SetValueInputDialog; +} + +class SetValueInputDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SetValueInputDialog(QWidget *parent = 0); + ~SetValueInputDialog(); + + void setTitileLabel(const QString& title); + void setDiText(const QString& text); + void initView(int dotType,double defaultValue); + + double getValue(); + + +private: + Ui::SetValueInputDialog *ui; + int mDotValue; + QMap mDiStatusText; + +}; + +#endif // SETVALUEINPUTDIALOG_H diff --git a/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.ui b/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.ui index 7745af9d..0009f23f 100644 --- a/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.ui +++ b/product/src/gui/plugin/DevRealDataWidget/SetValueInputDialog.ui @@ -1,175 +1,175 @@ - - - SetValueInputDialog - - - - 0 - 0 - 246 - 145 - - - - Dialog - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确定 - - - - - - - 取消 - - - - - - - - - 1 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 设置值 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 设置值 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - + + + SetValueInputDialog + + + + 0 + 0 + 246 + 145 + + + + Dialog + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确定 + + + + + + + 取消 + + + + + + + + + 1 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 设置值 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 设置值 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/product/src/gui/plugin/DevRealDataWidget/main.cpp b/product/src/gui/plugin/DevRealDataWidget/main.cpp index 16e62ae6..e2cdcd24 100644 --- a/product/src/gui/plugin/DevRealDataWidget/main.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/main.cpp @@ -1,41 +1,41 @@ -#include "CDevRealDataWidget.h" -#include -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - kbd_service::CDpcdaForApp::initGlobalThread(); - - { - QVector ptrVec; - QApplication a(argc, argv); - CDevRealDataWidget w(false, ptrVec); - w.show(); - - a.exec(); - } - - kbd_service::CDpcdaForApp::releaseGlobalThread(); - - kbd_net::releaseMsgBus(); - - return 0; -} +#include "CDevRealDataWidget.h" +#include +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + kbd_service::CDpcdaForApp::initGlobalThread(); + + { + QVector ptrVec; + QApplication a(argc, argv); + CDevRealDataWidget w(false, ptrVec); + w.show(); + + a.exec(); + } + + kbd_service::CDpcdaForApp::releaseGlobalThread(); + + kbd_net::releaseMsgBus(); + + return 0; +} diff --git a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointCommon.h b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointCommon.h index 33d12eaf..c6107d40 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointCommon.h +++ b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointCommon.h @@ -1,30 +1,30 @@ -#ifndef CDEVSPEPOINTCOMMON_H -#define CDEVSPEPOINTCOMMON_H - -#include - -enum EN_Type -{ - TYPE_DESC = 0, - TYPE_POINT -}; - -struct ST_RealData -{ - QString tag_name; - QString description; - QString table_name; - double value; - uint status; - QString stateTextName; - bool isInit; - char type; - ST_RealData(){ - value = 0.0; - status = 0; - isInit = false; - type = 1; - } -}; - -#endif // CDEVSPEPOINTCOMMON_H +#ifndef CDEVSPEPOINTCOMMON_H +#define CDEVSPEPOINTCOMMON_H + +#include + +enum EN_Type +{ + TYPE_DESC = 0, + TYPE_POINT +}; + +struct ST_RealData +{ + QString tag_name; + QString description; + QString table_name; + double value; + uint status; + QString stateTextName; + bool isInit; + char type; + ST_RealData(){ + value = 0.0; + status = 0; + isInit = false; + type = 1; + } +}; + +#endif // CDEVSPEPOINTCOMMON_H diff --git a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.cpp b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.cpp index 67c1bcd2..c46c00a1 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.cpp +++ b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CDevSpePointPluginWidget.h" -#include "CDevSpePointWidget.h" - -CDevSpePointPluginWidget::CDevSpePointPluginWidget() -{ - -} - -CDevSpePointPluginWidget::~CDevSpePointPluginWidget() -{ - -} - -bool CDevSpePointPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CDevSpePointWidget *pWidget = new CDevSpePointWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CDevSpePointPluginWidget::release() -{ - -} +#include "CDevSpePointPluginWidget.h" +#include "CDevSpePointWidget.h" + +CDevSpePointPluginWidget::CDevSpePointPluginWidget() +{ + +} + +CDevSpePointPluginWidget::~CDevSpePointPluginWidget() +{ + +} + +bool CDevSpePointPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CDevSpePointWidget *pWidget = new CDevSpePointWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CDevSpePointPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.h b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.h index b130ff92..568eebe5 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.h +++ b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CDEVSPEPOINTPLUGINWIDGET_H -#define CDEVSPEPOINTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CDevSpePointPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CDevSpePointPluginWidget(); - ~CDevSpePointPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CDEVSPEPOINTPLUGINWIDGET_H +#ifndef CDEVSPEPOINTPLUGINWIDGET_H +#define CDEVSPEPOINTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CDevSpePointPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CDevSpePointPluginWidget(); + ~CDevSpePointPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CDEVSPEPOINTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.cpp b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.cpp index e5de3afe..a6aba3f2 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.cpp +++ b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.cpp @@ -1,1099 +1,1099 @@ -#include "CDevSpePointWidget.h" -#include "public/pub_utility_api/FileStyle.h" -#include "CRealDataCollect.h" -#include "CRealTableModel.h" -#include -#include -#include -#include - -CDevSpePointWidget::CDevSpePointWidget(QWidget *parent, bool isEditMode) - : QWidget(parent), - m_pDpcdaForApp(Q_NULLPTR), - m_pTableView(Q_NULLPTR), - m_pTableModel(Q_NULLPTR), - m_isEditMode(isEditMode) -{ - initialize(); -} - -CDevSpePointWidget::~CDevSpePointWidget() -{ - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - delete m_pDpcdaForApp; - } - m_pDpcdaForApp = NULL; -} - -void CDevSpePointWidget::setCornerName(const QString &name) -{ - int columnSize = m_columnNameList.size(); - int columnTagSize = m_columnTagList.size(); - if(columnSize == columnTagSize) - { - m_columnNameList.push_front(name); - } - else if(columnSize == (columnTagSize + 1)) - { - m_columnNameList[0] = name; - } - m_pTableModel->setHeader(m_columnNameList); -} - -void CDevSpePointWidget::showNameType(int labelType) -{ - deviceOrGroupShowType = labelType; -} - -QString CDevSpePointWidget::addRow(const QString &pointTag) -{ - if(pointTag.isEmpty()) - { - return tr("测点标签为空!"); - } - - kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); - if(!objReader.open()) - { - return tr("数据库连接打开失败!"); - } - - - QStringList pointList = pointTag.split(","); - QString error = QString(); - int i=0; - - if(deviceOrGroupShowType == 0) //行标题默认模式-->0 - { - foreach (QString point, pointList) - { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4];//occ.PDBD22_PDGKC1 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - //< 添加第一列数据(设备描述) - QString deviceName = queryDeviceDesc(device, objReader); - if(deviceName.isEmpty()) - { - error += tr("查询设备描述失败!\n"); - continue; - } - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - } - - } - else if(deviceOrGroupShowType == 1) //行标题按设备组显示-->1(每行参数取该组全部设备存在的第一个值) - { - foreach (QString point, pointList) - { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - - //< 检查是否重复添加 - QString device =list[3] + "." + list[4].split("_")[0]; //S12.6102 - qDebug() << "deviceOrGroupShowType(1) device: " << device; - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - - //< 添加第一列数据(设备描述) - QString deviceName = queryGetGroupDescription(device, objReader); //设备组名,如:6102柜17变1#变压器 - - if(deviceName.isEmpty()) - { - error += tr("查询设备描述失败!\n"); - continue; - } - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; //000.S12.6102 - qDebug() << "deviceOrGroupShowType(1) device(1): " << device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - qDebug() << "deviceOrGroupShowType(1) m_columnTagList.isEmpty()"; - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - qDebug() << "realData-->" << realData.tag_name << realData.table_name; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - } - } - else if(deviceOrGroupShowType == 2) //行标题按设备名显示-->2 - { - foreach (QString point, pointList) - { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4].split("_")[0]; //kxg.KXG1Meter1 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - - //< 添加第一列数据(设备描述) - QString valueType = list[5]; - device = queryGetDevInfoTagName(valueType, device, objReader); - - kbd_dbms::CDbApi descriptionReader(DB_CONN_MODEL_READ); - if(!descriptionReader.open()) - { - return tr("数据库连接打开失败!"); - } - QString deviceName = queryGetDevInfoDescription(device, descriptionReader); - - - if(deviceName.isEmpty()) - { - error += tr("查询设备描述失败!\n"); - continue; - } - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - } - } - else if(deviceOrGroupShowType == 3) //行标题按设备组名显示,取该组第一个设备和它的值 - { - foreach (QString point, pointList) - { - QStringList list = point.split("."); - //< 检查标签是否合法 - if(list.length() != 7) - { - error += ("测点标签不合法!\n"); - continue; - } - - //< 检查是否重复添加 - QString device = list[3] + "." + list[4].split("_")[0]; - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - - //< 添加第一列数据(设备描述) - QString deviceName = queryGetGroupDescription(device, objReader); - if(deviceName.isEmpty()) - { - error += tr("查询设备描述失败!\n"); - continue; - } - device = list[3] + "." + list[4]; - device = QString("%1").arg(i++, 3, 10, QChar('0')) + "." + device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - qDebug() << "realData-->" << realData.tag_name << realData.table_name; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - - } - } - - m_pTableModel->updateRealData(m_dataMap); - // m_pTableModel->sort(1,Qt::AscendingOrder); - return error; -} - -QString CDevSpePointWidget::addRowName(const QString &pointTag, const QString &DevName) -{ - if(pointTag.isEmpty()) - { - return tr("测点标签为空!"); - } - QStringList pointList = pointTag.split(","); - QStringList DevNameList = DevName.split(","); - - if(pointList.count() != DevNameList.count()) - { - //转化为字符串 - QString str = QString("%1:%2").arg(pointList.count(), 2, 10, QLatin1Char('0')).arg(DevNameList.count(), 2, 10, QLatin1Char('0')); - return str; - } - - kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); - if(!objReader.open()) - { - return tr("数据库连接打开失败!"); - } - - QString error = QString(); - int i=0; - - if(deviceOrGroupShowType == 0) //行标题默认模式-->0 - { - foreach (QString point, pointList) - { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4]; //occ.PDBD22_PDGKC1 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - //< 添加第一列数据(设备描述) - QString deviceName = DevNameList[i];//queryDeviceDesc(device, objReader); - - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - } - } - else if(deviceOrGroupShowType == 1 || deviceOrGroupShowType == 3) //行标题按设备组显示-->1(每行参数取该组全部设备存在的第一个值) - { - foreach (QString point, pointList) - { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4].split("_")[0]; //S12.6102 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - //< 添加第一列数据(设备描述) - QString deviceName = DevNameList[i]; - device = queryGetGroupDescription(device, objReader); - - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - } - } - else if(deviceOrGroupShowType == 2) //行标题按设备名显示-->2 - { - foreach (QString point, pointList) - { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4].split("_")[0]; //kxg.KXG1Meter1 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - - //< 添加第一列数据(设备描述) - QString valueType = list[5]; - device = queryGetDevInfoTagName(valueType, device, objReader); - - kbd_dbms::CDbApi descriptionReader(DB_CONN_MODEL_READ); - if(!descriptionReader.open()) - { - return tr("数据库连接打开失败!"); - } - QString deviceName = queryGetDevInfoDescription(device, descriptionReader); - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - } - - } - - m_pTableModel->updateRealData(m_dataMap); - // m_pTableModel->sort(1,Qt::AscendingOrder); - return error; -} - -QString CDevSpePointWidget::addColumn(const QString &title, const QString &pointTag) -{ - if(pointTag.isEmpty()) - { - return tr("测点标签为空!"); - } - kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); - if(!objReader.open()) - { - return tr("数据库连接打开失败!"); - } - QStringList titleList = title.split(","); - QStringList pointList = pointTag.split(","); - if(titleList.size() != pointList.size()) - { - return tr("传入参数个数不一致!"); - } - QString error = QString(); - - - if(deviceOrGroupShowType == 0 || deviceOrGroupShowType == 2) - { - for(int i(0); i < pointList.length(); i++) - { - //< 检查标签是否合法 - QStringList list = QString(pointList[i]).split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 添加列头 - QString table = list[2]; - QString tag = list[5]; - m_columnTagList.append(qMakePair(tag, table)); - m_columnNameList.append(titleList[i]); - m_pTableModel->setHeader(m_columnNameList); - //< 添加点标签列数据 - QStringList devList = m_dataMap.keys(); - if(devList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex(tag, table)); //VA、analog - m_columnNameList.append(titleList[i]); //列标题栏 - m_pTableModel->setHeader(m_columnNameList); - - - //< 添加点标签列数据 - QStringList devList = m_dataMap.keys(); - //000.S12.6102", "001.S12.6342", "002.S12.6343", "003.S12.6344", "004.S12.6345", "005.S12.6346", "006.S12.6111 - - if(devList.isEmpty()) - { - continue; - } - - int groupNum = 0; - for(int nIndex(0); nIndex(tag, table)); - m_columnNameList.append(titleList[i]); - m_pTableModel->setHeader(m_columnNameList); - //< 添加点标签列数据 - QStringList devList = m_dataMap.keys(); - if(devList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndexupdateRealData(m_dataMap); - return error; -} - -void CDevSpePointWidget::subscribe() -{ - qDebug() << "subscribe start!"; - if(m_pDpcdaForApp == Q_NULLPTR) - { - return; - } - m_pDpcdaForApp->unsubscribeAll(); - - QMap>::const_iterator iter = m_dataMap.cbegin(); - for(; iter != m_dataMap.cend(); iter++) - { - const QList &list = iter.value(); - foreach (const ST_RealData &data, list) { - qDebug() << "subscribe data-->" << data.table_name << data.tag_name; - if(data.type != TYPE_POINT) - { - continue; - } - if(data.tag_name.isEmpty() || data.table_name.isEmpty()) - { - continue; - } - m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), "value"); - m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), "status"); - qDebug() << "subscribe-->" << data.table_name << data.tag_name; - } - } -} - -void CDevSpePointWidget::unsubscribeAll() -{ - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - } -} - -void CDevSpePointWidget::setRowHeight(int height) -{ - for(int nIndex(0); nIndexrowCount(); nIndex++) - { - m_pTableView->setRowHeight(nIndex, height); - } -} - -void CDevSpePointWidget::setColumnWidth(int column, int width) -{ - for(int nIndex(0); nIndexrowCount(); nIndex++) - { - m_pTableView->setColumnWidth(column, width); - } -} - -void CDevSpePointWidget::setValidString(const QString &text) -{ - if(m_pTableModel) - { - m_pTableModel->setValidString(text); - } -} - -void CDevSpePointWidget::setColumnStateText(int column, const QString &stateText) -{ - QStringList list = stateText.split(","); - if((list.length() % 2) != 0) - { - return; - } - QMap map; - double key; - QString value; - for(int n = 0; n < list.length(); ++n) - { - key = QString(list[n++]).toDouble(); - value = list[n]; - map[key] = value; - } - - m_pTableModel->addColStateTextMap(column, map); -} - -void CDevSpePointWidget::slotUpdateAi(const QMap > &aiMap) -{ - QMap >::const_iterator iter = aiMap.constBegin(); - for(; iter != aiMap.constEnd(); iter++) - { - QMap>::iterator dIter = m_dataMap.begin(); - for(; dIter != m_dataMap.end(); dIter++) - { - QList &dataList = dIter.value(); - for(int nIndex(0); nIndexupdateRealValue(m_dataMap); -} - -void CDevSpePointWidget::slotUpdateDi(const QMap > &diMap) -{ - QMap >::const_iterator iter = diMap.constBegin(); - for(; iter != diMap.constEnd(); iter++) - { - QMap>::iterator dIter = m_dataMap.begin(); - for(; dIter != m_dataMap.end(); dIter++) - { - QList &dataList = dIter.value(); - for(int nIndex(0); nIndexupdateRealValue(m_dataMap); -} - -void CDevSpePointWidget::slotUpdatePi(const QMap > &piMap) -{ - QMap >::const_iterator iter = piMap.constBegin(); - for(; iter != piMap.constEnd(); iter++) - { - QMap>::iterator dIter = m_dataMap.begin(); - for(; dIter != m_dataMap.end(); dIter++) - { - QList &dataList = dIter.value(); - for(int nIndex(0); nIndexupdateRealValue(m_dataMap); -} - -void CDevSpePointWidget::slotUpdateMi(const QMap > &miMap) -{ - QMap >::const_iterator iter = miMap.constBegin(); - for(; iter != miMap.constEnd(); iter++) - { - QMap>::iterator dIter = m_dataMap.begin(); - for(; dIter != m_dataMap.end(); dIter++) - { - QList &dataList = dIter.value(); - for(int nIndex(0); nIndexupdateRealValue(m_dataMap); -} - -void CDevSpePointWidget::initialize() -{ - m_pTableView = new QTableView; - m_pTableView->horizontalHeader()->setStretchLastSection(true); - m_pTableView->setSelectionMode(QAbstractItemView::NoSelection); - m_pTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); - m_pTableView->setAlternatingRowColors(true); - m_pTableModel = new CRealTableModel; - m_pTableView->setModel(m_pTableModel); - QGridLayout *layout = new QGridLayout; - layout->addWidget(m_pTableView); - layout->setMargin(0); - setLayout(layout); - - if(m_isEditMode) - { - return; - } - initStyle(); - - qRegisterMetaType>>("QMap>"); - qRegisterMetaType>>("QMap>"); - qRegisterMetaType>>("QMap>"); - - m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); - - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateAi, this, &CDevSpePointWidget::slotUpdateAi); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CDevSpePointWidget::slotUpdateDi); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateMi, this, &CDevSpePointWidget::slotUpdateMi); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updatePi, this, &CDevSpePointWidget::slotUpdatePi); -} - -void CDevSpePointWidget::initStyle() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss"); - qDebug() << "strFullPath-->" << QString::fromStdString(strFullPath); - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qDebug() << "load public.qss"; - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - qssfile1.close(); - - std::string style = kbd_public::CFileStyle::getPathOfStyleFile("devSpePoint.qss") ; - qDebug() << "Style Path-->" << QString::fromStdString(style); - QFile file(QString::fromStdString(style)); - file.open(QFile::ReadOnly); - if (file.isOpen()) - { - setStyleSheet(QLatin1String(file.readAll())); - file.close(); - qDebug() << "load devSpePoint.qss"; - } -} - -QString CDevSpePointWidget::queryDeviceDesc(const QString &devTag, kbd_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QList listColName; - listColName.append("DESCRIPTION"); - kbd_dbms::CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_value = devTag; - objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; - - QSqlQuery objQuery; - if(objReader.select("dev_info", listColName, objCondition, objQuery)) - { - while(objQuery.next()) - { - return objQuery.value(0).toString(); - } - } - return QString(); -} - -QString CDevSpePointWidget::queryDigitalStateText(const QString &point, kbd_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - QList listColName; - listColName.append("STATE_TEXT_NAME"); - kbd_dbms::CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_value = point; - objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; - - QSqlQuery objQuery; - if(objReader.select("digital", listColName, objCondition, objQuery)) - { - while(objQuery.next()) - { - return objQuery.value(0).toString(); - } - } - return QString(); -} - -//获取设备组名,仅deviceOrGroupType==1时使用 -QString CDevSpePointWidget::queryGetGroupDescription(const QString &tagName, kbd_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QList listColName; - listColName.append("DESCRIPTION"); //需要取的值 - kbd_dbms::CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; //比较的组名 - objCondition.m_value = tagName; // 比较的值 - objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; // 比较条件 - objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; // 两个比较条件之间的关系 - - QSqlQuery objQuery; - if(objReader.select("dev_group", listColName, objCondition, objQuery)) - { - while(objQuery.next()) - { - return objQuery.value(0).toString(); - } - } - return QString(); -} - -//获取设备组里第1个存在的列标题值的设备名,仅deviceOrGroupType==1时使用 -QString CDevSpePointWidget::queryGetCollumnDevInfoTagName(const QString &measureType, const QString &valueType, const QString &groupName, kbd_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QString mysqlExecute; - mysqlExecute = QString("SELECT %1.TAG_NAME FROM %2 JOIN dev_info ON dev_info.TAG_NAME = %3.DEVICE WHERE dev_info.GROUP_TAG_NAME = '%4'") - .arg(measureType).arg(measureType).arg(measureType).arg(groupName); - QSqlQuery objQuery; - if(objReader.execute(mysqlExecute, objQuery)) - { - qDebug() << "queryGetCollumnDevInfoTagName"; - while(objQuery.next()) - { - qDebug() << "queryGetCollumnDevInfoTagName-->" << objQuery.value(0).toString(); - if(objQuery.value(0).toString().contains(valueType)) - { - return objQuery.value(0).toString(); - } - } - } - return QString(); -} - -//以第1个存在VA值的设备名为列标题时,仅deviceOrGroupType==2时使用 -QString CDevSpePointWidget::queryGetDevInfoTagName(const QString &valueType, const QString &groupTagName, kbd_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QString mysqlExecute; - mysqlExecute = QString("SELECT analog.TAG_NAME FROM analog JOIN dev_info ON analog.DEVICE = dev_info.TAG_NAME WHERE dev_info.GROUP_TAG_NAME = '%1'").arg(groupTagName); - QSqlQuery objQuery; - if(objReader.execute(mysqlExecute, objQuery)) - { - while(objQuery.next()) - { - qDebug() << "queryGetGroupDescription-->" << objQuery.value(0).toString(); - if(objQuery.value(0).toString().contains(valueType)) - { - return objQuery.value(0).toString().replace("." + valueType, ""); - } - } - } - return QString(); -} - -//获取某组设备里的设备名,仅deviceOrGroupType==2时使用 -QString CDevSpePointWidget::queryGetDevInfoDescription(const QString &deviceTagName, kbd_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QList listColName; - listColName.append("DESCRIPTION"); //是objCondition.m_value的组名 - kbd_dbms::CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; //比较的字段名 - objCondition.m_value = deviceTagName; //比较的值 - objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; //比较条件 - objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; //两个比较条件之间的关系 - - QSqlQuery objQuery; - if(objReader.select("dev_info", listColName, objCondition, objQuery)) - { - while(objQuery.next()) - { - return objQuery.value(0).toString(); - } - } - return QString(); -} +#include "CDevSpePointWidget.h" +#include "public/pub_utility_api/FileStyle.h" +#include "CRealDataCollect.h" +#include "CRealTableModel.h" +#include +#include +#include +#include + +CDevSpePointWidget::CDevSpePointWidget(QWidget *parent, bool isEditMode) + : QWidget(parent), + m_pDpcdaForApp(Q_NULLPTR), + m_pTableView(Q_NULLPTR), + m_pTableModel(Q_NULLPTR), + m_isEditMode(isEditMode) +{ + initialize(); +} + +CDevSpePointWidget::~CDevSpePointWidget() +{ + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = NULL; +} + +void CDevSpePointWidget::setCornerName(const QString &name) +{ + int columnSize = m_columnNameList.size(); + int columnTagSize = m_columnTagList.size(); + if(columnSize == columnTagSize) + { + m_columnNameList.push_front(name); + } + else if(columnSize == (columnTagSize + 1)) + { + m_columnNameList[0] = name; + } + m_pTableModel->setHeader(m_columnNameList); +} + +void CDevSpePointWidget::showNameType(int labelType) +{ + deviceOrGroupShowType = labelType; +} + +QString CDevSpePointWidget::addRow(const QString &pointTag) +{ + if(pointTag.isEmpty()) + { + return tr("测点标签为空!"); + } + + kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); + if(!objReader.open()) + { + return tr("数据库连接打开失败!"); + } + + + QStringList pointList = pointTag.split(","); + QString error = QString(); + int i=0; + + if(deviceOrGroupShowType == 0) //行标题默认模式-->0 + { + foreach (QString point, pointList) + { + //< 检查标签是否合法 + QStringList list = point.split("."); + if(list.length() != 7) + { + error += tr("测点标签不合法!\n"); + continue; + } + //< 检查是否重复添加 + QString device =list[3] + "." + list[4];//occ.PDBD22_PDGKC1 + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) + { + error += tr("重复添加!\n"); + continue; + } + //< 添加第一列数据(设备描述) + QString deviceName = queryDeviceDesc(device, objReader); + if(deviceName.isEmpty()) + { + error += tr("查询设备描述失败!\n"); + continue; + } + + //添加排序 + device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) + { + continue; + } + + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") + { + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); + } + m_dataMap[device].append(realData); + } + } + + } + else if(deviceOrGroupShowType == 1) //行标题按设备组显示-->1(每行参数取该组全部设备存在的第一个值) + { + foreach (QString point, pointList) + { + //< 检查标签是否合法 + QStringList list = point.split("."); + if(list.length() != 7) + { + error += tr("测点标签不合法!\n"); + continue; + } + + //< 检查是否重复添加 + QString device =list[3] + "." + list[4].split("_")[0]; //S12.6102 + qDebug() << "deviceOrGroupShowType(1) device: " << device; + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) + { + error += tr("重复添加!\n"); + continue; + } + + //< 添加第一列数据(设备描述) + QString deviceName = queryGetGroupDescription(device, objReader); //设备组名,如:6102柜17变1#变压器 + + if(deviceName.isEmpty()) + { + error += tr("查询设备描述失败!\n"); + continue; + } + + //添加排序 + device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; //000.S12.6102 + qDebug() << "deviceOrGroupShowType(1) device(1): " << device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) + { + continue; + } + + qDebug() << "deviceOrGroupShowType(1) m_columnTagList.isEmpty()"; + + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + qDebug() << "realData-->" << realData.tag_name << realData.table_name; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") + { + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); + } + m_dataMap[device].append(realData); + } + } + } + else if(deviceOrGroupShowType == 2) //行标题按设备名显示-->2 + { + foreach (QString point, pointList) + { + //< 检查标签是否合法 + QStringList list = point.split("."); + if(list.length() != 7) + { + error += tr("测点标签不合法!\n"); + continue; + } + //< 检查是否重复添加 + QString device =list[3] + "." + list[4].split("_")[0]; //kxg.KXG1Meter1 + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) + { + error += tr("重复添加!\n"); + continue; + } + + //< 添加第一列数据(设备描述) + QString valueType = list[5]; + device = queryGetDevInfoTagName(valueType, device, objReader); + + kbd_dbms::CDbApi descriptionReader(DB_CONN_MODEL_READ); + if(!descriptionReader.open()) + { + return tr("数据库连接打开失败!"); + } + QString deviceName = queryGetDevInfoDescription(device, descriptionReader); + + + if(deviceName.isEmpty()) + { + error += tr("查询设备描述失败!\n"); + continue; + } + + //添加排序 + device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) + { + continue; + } + + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") + { + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); + } + m_dataMap[device].append(realData); + } + } + } + else if(deviceOrGroupShowType == 3) //行标题按设备组名显示,取该组第一个设备和它的值 + { + foreach (QString point, pointList) + { + QStringList list = point.split("."); + //< 检查标签是否合法 + if(list.length() != 7) + { + error += ("测点标签不合法!\n"); + continue; + } + + //< 检查是否重复添加 + QString device = list[3] + "." + list[4].split("_")[0]; + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) + { + error += tr("重复添加!\n"); + continue; + } + + //< 添加第一列数据(设备描述) + QString deviceName = queryGetGroupDescription(device, objReader); + if(deviceName.isEmpty()) + { + error += tr("查询设备描述失败!\n"); + continue; + } + device = list[3] + "." + list[4]; + device = QString("%1").arg(i++, 3, 10, QChar('0')) + "." + device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) + { + continue; + } + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + qDebug() << "realData-->" << realData.tag_name << realData.table_name; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") + { + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); + } + m_dataMap[device].append(realData); + } + + } + } + + m_pTableModel->updateRealData(m_dataMap); + // m_pTableModel->sort(1,Qt::AscendingOrder); + return error; +} + +QString CDevSpePointWidget::addRowName(const QString &pointTag, const QString &DevName) +{ + if(pointTag.isEmpty()) + { + return tr("测点标签为空!"); + } + QStringList pointList = pointTag.split(","); + QStringList DevNameList = DevName.split(","); + + if(pointList.count() != DevNameList.count()) + { + //转化为字符串 + QString str = QString("%1:%2").arg(pointList.count(), 2, 10, QLatin1Char('0')).arg(DevNameList.count(), 2, 10, QLatin1Char('0')); + return str; + } + + kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); + if(!objReader.open()) + { + return tr("数据库连接打开失败!"); + } + + QString error = QString(); + int i=0; + + if(deviceOrGroupShowType == 0) //行标题默认模式-->0 + { + foreach (QString point, pointList) + { + //< 检查标签是否合法 + QStringList list = point.split("."); + if(list.length() != 7) + { + error += tr("测点标签不合法!\n"); + continue; + } + //< 检查是否重复添加 + QString device =list[3] + "." + list[4]; //occ.PDBD22_PDGKC1 + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) + { + error += tr("重复添加!\n"); + continue; + } + //< 添加第一列数据(设备描述) + QString deviceName = DevNameList[i];//queryDeviceDesc(device, objReader); + + + //添加排序 + device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) + { + continue; + } + + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") + { + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); + } + m_dataMap[device].append(realData); + } + } + } + else if(deviceOrGroupShowType == 1 || deviceOrGroupShowType == 3) //行标题按设备组显示-->1(每行参数取该组全部设备存在的第一个值) + { + foreach (QString point, pointList) + { + //< 检查标签是否合法 + QStringList list = point.split("."); + if(list.length() != 7) + { + error += tr("测点标签不合法!\n"); + continue; + } + //< 检查是否重复添加 + QString device =list[3] + "." + list[4].split("_")[0]; //S12.6102 + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) + { + error += tr("重复添加!\n"); + continue; + } + //< 添加第一列数据(设备描述) + QString deviceName = DevNameList[i]; + device = queryGetGroupDescription(device, objReader); + + + //添加排序 + device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) + { + continue; + } + + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") + { + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); + } + m_dataMap[device].append(realData); + } + } + } + else if(deviceOrGroupShowType == 2) //行标题按设备名显示-->2 + { + foreach (QString point, pointList) + { + //< 检查标签是否合法 + QStringList list = point.split("."); + if(list.length() != 7) + { + error += tr("测点标签不合法!\n"); + continue; + } + //< 检查是否重复添加 + QString device =list[3] + "." + list[4].split("_")[0]; //kxg.KXG1Meter1 + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) + { + error += tr("重复添加!\n"); + continue; + } + + //< 添加第一列数据(设备描述) + QString valueType = list[5]; + device = queryGetDevInfoTagName(valueType, device, objReader); + + kbd_dbms::CDbApi descriptionReader(DB_CONN_MODEL_READ); + if(!descriptionReader.open()) + { + return tr("数据库连接打开失败!"); + } + QString deviceName = queryGetDevInfoDescription(device, descriptionReader); + + //添加排序 + device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) + { + continue; + } + + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") + { + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); + } + m_dataMap[device].append(realData); + } + } + + } + + m_pTableModel->updateRealData(m_dataMap); + // m_pTableModel->sort(1,Qt::AscendingOrder); + return error; +} + +QString CDevSpePointWidget::addColumn(const QString &title, const QString &pointTag) +{ + if(pointTag.isEmpty()) + { + return tr("测点标签为空!"); + } + kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); + if(!objReader.open()) + { + return tr("数据库连接打开失败!"); + } + QStringList titleList = title.split(","); + QStringList pointList = pointTag.split(","); + if(titleList.size() != pointList.size()) + { + return tr("传入参数个数不一致!"); + } + QString error = QString(); + + + if(deviceOrGroupShowType == 0 || deviceOrGroupShowType == 2) + { + for(int i(0); i < pointList.length(); i++) + { + //< 检查标签是否合法 + QStringList list = QString(pointList[i]).split("."); + if(list.length() != 7) + { + error += tr("测点标签不合法!\n"); + continue; + } + //< 添加列头 + QString table = list[2]; + QString tag = list[5]; + m_columnTagList.append(qMakePair(tag, table)); + m_columnNameList.append(titleList[i]); + m_pTableModel->setHeader(m_columnNameList); + //< 添加点标签列数据 + QStringList devList = m_dataMap.keys(); + if(devList.isEmpty()) + { + continue; + } + + for(int nIndex(0); nIndex(tag, table)); //VA、analog + m_columnNameList.append(titleList[i]); //列标题栏 + m_pTableModel->setHeader(m_columnNameList); + + + //< 添加点标签列数据 + QStringList devList = m_dataMap.keys(); + //000.S12.6102", "001.S12.6342", "002.S12.6343", "003.S12.6344", "004.S12.6345", "005.S12.6346", "006.S12.6111 + + if(devList.isEmpty()) + { + continue; + } + + int groupNum = 0; + for(int nIndex(0); nIndex(tag, table)); + m_columnNameList.append(titleList[i]); + m_pTableModel->setHeader(m_columnNameList); + //< 添加点标签列数据 + QStringList devList = m_dataMap.keys(); + if(devList.isEmpty()) + { + continue; + } + + for(int nIndex(0); nIndexupdateRealData(m_dataMap); + return error; +} + +void CDevSpePointWidget::subscribe() +{ + qDebug() << "subscribe start!"; + if(m_pDpcdaForApp == Q_NULLPTR) + { + return; + } + m_pDpcdaForApp->unsubscribeAll(); + + QMap>::const_iterator iter = m_dataMap.cbegin(); + for(; iter != m_dataMap.cend(); iter++) + { + const QList &list = iter.value(); + foreach (const ST_RealData &data, list) { + qDebug() << "subscribe data-->" << data.table_name << data.tag_name; + if(data.type != TYPE_POINT) + { + continue; + } + if(data.tag_name.isEmpty() || data.table_name.isEmpty()) + { + continue; + } + m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), "value"); + m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), "status"); + qDebug() << "subscribe-->" << data.table_name << data.tag_name; + } + } +} + +void CDevSpePointWidget::unsubscribeAll() +{ + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + } +} + +void CDevSpePointWidget::setRowHeight(int height) +{ + for(int nIndex(0); nIndexrowCount(); nIndex++) + { + m_pTableView->setRowHeight(nIndex, height); + } +} + +void CDevSpePointWidget::setColumnWidth(int column, int width) +{ + for(int nIndex(0); nIndexrowCount(); nIndex++) + { + m_pTableView->setColumnWidth(column, width); + } +} + +void CDevSpePointWidget::setValidString(const QString &text) +{ + if(m_pTableModel) + { + m_pTableModel->setValidString(text); + } +} + +void CDevSpePointWidget::setColumnStateText(int column, const QString &stateText) +{ + QStringList list = stateText.split(","); + if((list.length() % 2) != 0) + { + return; + } + QMap map; + double key; + QString value; + for(int n = 0; n < list.length(); ++n) + { + key = QString(list[n++]).toDouble(); + value = list[n]; + map[key] = value; + } + + m_pTableModel->addColStateTextMap(column, map); +} + +void CDevSpePointWidget::slotUpdateAi(const QMap > &aiMap) +{ + QMap >::const_iterator iter = aiMap.constBegin(); + for(; iter != aiMap.constEnd(); iter++) + { + QMap>::iterator dIter = m_dataMap.begin(); + for(; dIter != m_dataMap.end(); dIter++) + { + QList &dataList = dIter.value(); + for(int nIndex(0); nIndexupdateRealValue(m_dataMap); +} + +void CDevSpePointWidget::slotUpdateDi(const QMap > &diMap) +{ + QMap >::const_iterator iter = diMap.constBegin(); + for(; iter != diMap.constEnd(); iter++) + { + QMap>::iterator dIter = m_dataMap.begin(); + for(; dIter != m_dataMap.end(); dIter++) + { + QList &dataList = dIter.value(); + for(int nIndex(0); nIndexupdateRealValue(m_dataMap); +} + +void CDevSpePointWidget::slotUpdatePi(const QMap > &piMap) +{ + QMap >::const_iterator iter = piMap.constBegin(); + for(; iter != piMap.constEnd(); iter++) + { + QMap>::iterator dIter = m_dataMap.begin(); + for(; dIter != m_dataMap.end(); dIter++) + { + QList &dataList = dIter.value(); + for(int nIndex(0); nIndexupdateRealValue(m_dataMap); +} + +void CDevSpePointWidget::slotUpdateMi(const QMap > &miMap) +{ + QMap >::const_iterator iter = miMap.constBegin(); + for(; iter != miMap.constEnd(); iter++) + { + QMap>::iterator dIter = m_dataMap.begin(); + for(; dIter != m_dataMap.end(); dIter++) + { + QList &dataList = dIter.value(); + for(int nIndex(0); nIndexupdateRealValue(m_dataMap); +} + +void CDevSpePointWidget::initialize() +{ + m_pTableView = new QTableView; + m_pTableView->horizontalHeader()->setStretchLastSection(true); + m_pTableView->setSelectionMode(QAbstractItemView::NoSelection); + m_pTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_pTableView->setAlternatingRowColors(true); + m_pTableModel = new CRealTableModel; + m_pTableView->setModel(m_pTableModel); + QGridLayout *layout = new QGridLayout; + layout->addWidget(m_pTableView); + layout->setMargin(0); + setLayout(layout); + + if(m_isEditMode) + { + return; + } + initStyle(); + + qRegisterMetaType>>("QMap>"); + qRegisterMetaType>>("QMap>"); + qRegisterMetaType>>("QMap>"); + + m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); + + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateAi, this, &CDevSpePointWidget::slotUpdateAi); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CDevSpePointWidget::slotUpdateDi); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateMi, this, &CDevSpePointWidget::slotUpdateMi); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updatePi, this, &CDevSpePointWidget::slotUpdatePi); +} + +void CDevSpePointWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss"); + qDebug() << "strFullPath-->" << QString::fromStdString(strFullPath); + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qDebug() << "load public.qss"; + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + qssfile1.close(); + + std::string style = kbd_public::CFileStyle::getPathOfStyleFile("devSpePoint.qss") ; + qDebug() << "Style Path-->" << QString::fromStdString(style); + QFile file(QString::fromStdString(style)); + file.open(QFile::ReadOnly); + if (file.isOpen()) + { + setStyleSheet(QLatin1String(file.readAll())); + file.close(); + qDebug() << "load devSpePoint.qss"; + } +} + +QString CDevSpePointWidget::queryDeviceDesc(const QString &devTag, kbd_dbms::CDbApi &objReader) const +{ + if(!objReader.isOpen()) + { + return QString(); + } + + QList listColName; + listColName.append("DESCRIPTION"); + kbd_dbms::CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_value = devTag; + objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; + + QSqlQuery objQuery; + if(objReader.select("dev_info", listColName, objCondition, objQuery)) + { + while(objQuery.next()) + { + return objQuery.value(0).toString(); + } + } + return QString(); +} + +QString CDevSpePointWidget::queryDigitalStateText(const QString &point, kbd_dbms::CDbApi &objReader) const +{ + if(!objReader.isOpen()) + { + return QString(); + } + QList listColName; + listColName.append("STATE_TEXT_NAME"); + kbd_dbms::CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_value = point; + objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; + + QSqlQuery objQuery; + if(objReader.select("digital", listColName, objCondition, objQuery)) + { + while(objQuery.next()) + { + return objQuery.value(0).toString(); + } + } + return QString(); +} + +//获取设备组名,仅deviceOrGroupType==1时使用 +QString CDevSpePointWidget::queryGetGroupDescription(const QString &tagName, kbd_dbms::CDbApi &objReader) const +{ + if(!objReader.isOpen()) + { + return QString(); + } + + QList listColName; + listColName.append("DESCRIPTION"); //需要取的值 + kbd_dbms::CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; //比较的组名 + objCondition.m_value = tagName; // 比较的值 + objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; // 比较条件 + objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; // 两个比较条件之间的关系 + + QSqlQuery objQuery; + if(objReader.select("dev_group", listColName, objCondition, objQuery)) + { + while(objQuery.next()) + { + return objQuery.value(0).toString(); + } + } + return QString(); +} + +//获取设备组里第1个存在的列标题值的设备名,仅deviceOrGroupType==1时使用 +QString CDevSpePointWidget::queryGetCollumnDevInfoTagName(const QString &measureType, const QString &valueType, const QString &groupName, kbd_dbms::CDbApi &objReader) const +{ + if(!objReader.isOpen()) + { + return QString(); + } + + QString mysqlExecute; + mysqlExecute = QString("SELECT %1.TAG_NAME FROM %2 JOIN dev_info ON dev_info.TAG_NAME = %3.DEVICE WHERE dev_info.GROUP_TAG_NAME = '%4'") + .arg(measureType).arg(measureType).arg(measureType).arg(groupName); + QSqlQuery objQuery; + if(objReader.execute(mysqlExecute, objQuery)) + { + qDebug() << "queryGetCollumnDevInfoTagName"; + while(objQuery.next()) + { + qDebug() << "queryGetCollumnDevInfoTagName-->" << objQuery.value(0).toString(); + if(objQuery.value(0).toString().contains(valueType)) + { + return objQuery.value(0).toString(); + } + } + } + return QString(); +} + +//以第1个存在VA值的设备名为列标题时,仅deviceOrGroupType==2时使用 +QString CDevSpePointWidget::queryGetDevInfoTagName(const QString &valueType, const QString &groupTagName, kbd_dbms::CDbApi &objReader) const +{ + if(!objReader.isOpen()) + { + return QString(); + } + + QString mysqlExecute; + mysqlExecute = QString("SELECT analog.TAG_NAME FROM analog JOIN dev_info ON analog.DEVICE = dev_info.TAG_NAME WHERE dev_info.GROUP_TAG_NAME = '%1'").arg(groupTagName); + QSqlQuery objQuery; + if(objReader.execute(mysqlExecute, objQuery)) + { + while(objQuery.next()) + { + qDebug() << "queryGetGroupDescription-->" << objQuery.value(0).toString(); + if(objQuery.value(0).toString().contains(valueType)) + { + return objQuery.value(0).toString().replace("." + valueType, ""); + } + } + } + return QString(); +} + +//获取某组设备里的设备名,仅deviceOrGroupType==2时使用 +QString CDevSpePointWidget::queryGetDevInfoDescription(const QString &deviceTagName, kbd_dbms::CDbApi &objReader) const +{ + if(!objReader.isOpen()) + { + return QString(); + } + + QList listColName; + listColName.append("DESCRIPTION"); //是objCondition.m_value的组名 + kbd_dbms::CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; //比较的字段名 + objCondition.m_value = deviceTagName; //比较的值 + objCondition.m_eCompare = kbd_dbms::CDbCondition::COMPARE_EQ; //比较条件 + objCondition.m_eLogic = kbd_dbms::CDbCondition::LOGIC_AND; //两个比较条件之间的关系 + + QSqlQuery objQuery; + if(objReader.select("dev_info", listColName, objCondition, objQuery)) + { + while(objQuery.next()) + { + return objQuery.value(0).toString(); + } + } + return QString(); +} diff --git a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.h b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.h index 415f6a94..ca96033d 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.h +++ b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.h @@ -1,127 +1,127 @@ -#ifndef CDEVSPEPOINTWIDGET_H -#define CDEVSPEPOINTWIDGET_H - -#include -#include "CDevSpePointCommon.h" -#include "db_api_ex/CDbApi.h" -#include "dp_chg_data_api/CDpcdaForApp.h" - -class QTableView; -class CRealTableModel; -class CDevSpePointWidget : public QWidget -{ - Q_OBJECT - -public: - CDevSpePointWidget(QWidget *parent = 0, bool isEditMode = true); - ~CDevSpePointWidget(); - -public slots: - /** - * @brief setCornerName 设置第一列名称 - * @param name 名称 - */ - void setCornerName(const QString &name); - - /** - * @brief addRow 添加行 - * @param pointTag 测点标签(以","分隔) 用于获取设备 station1.PSCADA.analog.station1.G03_jgxh.IA.value - * @return 错误描述 - */ - QString addRow(const QString &pointTag); - - /** - * @brief addRow 添加行 - * @param pointTag 测点标签(以","分隔) 用于获取设备 station1.PSCADA.analog.station1.G03_jgxh.IA.value - * @param DevName 设备名称(以","分隔) 用于设置显示设备名称 - * @return 错误描述 - */ - QString addRowName(const QString &pointTag,const QString &DevName); - - /** - * @brief addColumn 添加列 - * @param title 列头(以","分隔) - * @param pointTag 测点标签(以","分隔) 用于获取测点表名和后缀 station1.PSCADA.analog.station1.G03_jgxh.IA.value - * @return 错误描述 - */ - QString addColumn(const QString &title, const QString &pointTag); - - /** - * @brief subscribe 订阅变化数据(需最后调用) - */ - void subscribe(); - - /** - * @brief unsubscribeAll 取消所有订阅 - */ - void unsubscribeAll(); - - /** - * @brief setRowHeight 设置行高 - * @param rowHeight 行高 - */ - void setRowHeight(int height); - - /** - * @brief setColumnWidth 设置列宽 - * @param column 列号 - * @param width 列宽 - */ - void setColumnWidth(int column, int width); - - /** - * @brief setValidString 设置无效值显示文本,为空时显示值 - * @param text - */ - void setValidString(const QString &text); - - /** - * @brief setColumnStateText 设置某列的显示状态文本 - * @param column 列号 - * @param stateText 0,正常,1,休眠,2,关机,3,故障 - */ - void setColumnStateText(int column, const QString &stateText); - - /** - * @brief 设置支路和电量行标题显示模式 - * @param labelType - * 行标题默认模式-->0 - * 行标题按设备组名显示-->1(每行数据取该组全部设备存在的第一个值) - * 行标题按设备名显示-->2(取该组设备中第一个存在VA值的设备及它的其它项数据) - * 行标题按设备组名显示-->3(取该组第一个设备和它的值) - */ - void showNameType(int labelType); - -private slots: - void slotUpdateAi(const QMap>& aiMap); - void slotUpdateDi(const QMap>& diMap); - void slotUpdatePi(const QMap>& piMap); - void slotUpdateMi(const QMap>& miMap); - -private: - void initialize(); - void initStyle(); - - QString queryDeviceDesc(const QString &devTag, kbd_dbms::CDbApi &objReader) const; - QString queryDigitalStateText(const QString &point, kbd_dbms::CDbApi &objReader) const; - QString queryGetGroupDescription(const QString &tagName, kbd_dbms::CDbApi &objReader) const; - QString queryGetCollumnDevInfoTagName(const QString &measureType, const QString &valueType, - const QString &groupTagName, kbd_dbms::CDbApi &objReader) const; - QString queryGetDevInfoTagName(const QString &valueType, const QString &groupTagName, kbd_dbms::CDbApi &objReader) const; - QString queryGetAnalogTagName(const QString &valueType, const QString &deviceName, kbd_dbms::CDbApi &objReader) const; - QString queryGetDevInfoDescription(const QString &deviceTagName, kbd_dbms::CDbApi &objReader) const; - -private: - kbd_service::CDpcdaForApp *m_pDpcdaForApp; - QTableView * m_pTableView; - CRealTableModel * m_pTableModel; - bool m_isEditMode; - - QList< QPair > m_columnTagList; //< 标签名,表名 - QStringList m_columnNameList; - QMap> m_dataMap; - - int deviceOrGroupShowType = 0; //列标题显示模式 -}; - -#endif // CDEVSPEPOINTWIDGET_H +#ifndef CDEVSPEPOINTWIDGET_H +#define CDEVSPEPOINTWIDGET_H + +#include +#include "CDevSpePointCommon.h" +#include "db_api_ex/CDbApi.h" +#include "dp_chg_data_api/CDpcdaForApp.h" + +class QTableView; +class CRealTableModel; +class CDevSpePointWidget : public QWidget +{ + Q_OBJECT + +public: + CDevSpePointWidget(QWidget *parent = 0, bool isEditMode = true); + ~CDevSpePointWidget(); + +public slots: + /** + * @brief setCornerName 设置第一列名称 + * @param name 名称 + */ + void setCornerName(const QString &name); + + /** + * @brief addRow 添加行 + * @param pointTag 测点标签(以","分隔) 用于获取设备 station1.PSCADA.analog.station1.G03_jgxh.IA.value + * @return 错误描述 + */ + QString addRow(const QString &pointTag); + + /** + * @brief addRow 添加行 + * @param pointTag 测点标签(以","分隔) 用于获取设备 station1.PSCADA.analog.station1.G03_jgxh.IA.value + * @param DevName 设备名称(以","分隔) 用于设置显示设备名称 + * @return 错误描述 + */ + QString addRowName(const QString &pointTag,const QString &DevName); + + /** + * @brief addColumn 添加列 + * @param title 列头(以","分隔) + * @param pointTag 测点标签(以","分隔) 用于获取测点表名和后缀 station1.PSCADA.analog.station1.G03_jgxh.IA.value + * @return 错误描述 + */ + QString addColumn(const QString &title, const QString &pointTag); + + /** + * @brief subscribe 订阅变化数据(需最后调用) + */ + void subscribe(); + + /** + * @brief unsubscribeAll 取消所有订阅 + */ + void unsubscribeAll(); + + /** + * @brief setRowHeight 设置行高 + * @param rowHeight 行高 + */ + void setRowHeight(int height); + + /** + * @brief setColumnWidth 设置列宽 + * @param column 列号 + * @param width 列宽 + */ + void setColumnWidth(int column, int width); + + /** + * @brief setValidString 设置无效值显示文本,为空时显示值 + * @param text + */ + void setValidString(const QString &text); + + /** + * @brief setColumnStateText 设置某列的显示状态文本 + * @param column 列号 + * @param stateText 0,正常,1,休眠,2,关机,3,故障 + */ + void setColumnStateText(int column, const QString &stateText); + + /** + * @brief 设置支路和电量行标题显示模式 + * @param labelType + * 行标题默认模式-->0 + * 行标题按设备组名显示-->1(每行数据取该组全部设备存在的第一个值) + * 行标题按设备名显示-->2(取该组设备中第一个存在VA值的设备及它的其它项数据) + * 行标题按设备组名显示-->3(取该组第一个设备和它的值) + */ + void showNameType(int labelType); + +private slots: + void slotUpdateAi(const QMap>& aiMap); + void slotUpdateDi(const QMap>& diMap); + void slotUpdatePi(const QMap>& piMap); + void slotUpdateMi(const QMap>& miMap); + +private: + void initialize(); + void initStyle(); + + QString queryDeviceDesc(const QString &devTag, kbd_dbms::CDbApi &objReader) const; + QString queryDigitalStateText(const QString &point, kbd_dbms::CDbApi &objReader) const; + QString queryGetGroupDescription(const QString &tagName, kbd_dbms::CDbApi &objReader) const; + QString queryGetCollumnDevInfoTagName(const QString &measureType, const QString &valueType, + const QString &groupTagName, kbd_dbms::CDbApi &objReader) const; + QString queryGetDevInfoTagName(const QString &valueType, const QString &groupTagName, kbd_dbms::CDbApi &objReader) const; + QString queryGetAnalogTagName(const QString &valueType, const QString &deviceName, kbd_dbms::CDbApi &objReader) const; + QString queryGetDevInfoDescription(const QString &deviceTagName, kbd_dbms::CDbApi &objReader) const; + +private: + kbd_service::CDpcdaForApp *m_pDpcdaForApp; + QTableView * m_pTableView; + CRealTableModel * m_pTableModel; + bool m_isEditMode; + + QList< QPair > m_columnTagList; //< 标签名,表名 + QStringList m_columnNameList; + QMap> m_dataMap; + + int deviceOrGroupShowType = 0; //列标题显示模式 +}; + +#endif // CDEVSPEPOINTWIDGET_H diff --git a/product/src/gui/plugin/DevSpePointWidget/CRealDataCollect.cpp b/product/src/gui/plugin/DevSpePointWidget/CRealDataCollect.cpp index f345cc49..d8c82787 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CRealDataCollect.cpp +++ b/product/src/gui/plugin/DevSpePointWidget/CRealDataCollect.cpp @@ -1,240 +1,240 @@ -#include "CRealDataCollect.h" -#include - -CRealDataCollect* CRealDataCollect::m_pInstance = NULL; - -CRealDataCollect::CRealDataCollect() - : m_pMbComm(NULL), - m_pTimer(NULL), - m_nTimeCount(0) -{ - initMsg(); - if(!addSub()) - { - return; - } - - m_pTimer = new QTimer(this); - connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); - m_pTimer->start(100); -} - -CRealDataCollect *CRealDataCollect::instance() -{ - if(m_pInstance == NULL) - { - m_pInstance = new CRealDataCollect(); - } - return m_pInstance; -} - -void CRealDataCollect::release() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - delSub(); - closeMsg(); - m_pInstance = NULL; - delete this; -} - -void CRealDataCollect::initMsg() -{ - if(m_pMbComm == NULL) - { - m_pMbComm = new kbd_net::CMbCommunicator("DevSpePointWidget"); - } -} - -void CRealDataCollect::closeMsg() -{ - if(m_pMbComm != NULL) - { - delete m_pMbComm; - } - m_pMbComm = NULL; -} - -void CRealDataCollect::clearMsg() -{ - if(m_pMbComm) - { - kbd_net::CMbMessage objMsg; - while(m_pMbComm->recvMsg(objMsg, 0)) - {} - } -} - -bool CRealDataCollect::addSub() -{ - if(m_pMbComm) - { - return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else - { - return false; - } -} - -bool CRealDataCollect::delSub() -{ - if(m_pMbComm) - { - return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else - { - return false; - } -} - -void CRealDataCollect::recvMessage() -{ - m_nTimeCount = (m_nTimeCount + 1) % 36000; - - if(m_nTimeCount % 10 == 0) - { - processChangeData(); - } - - try - { - kbd_net::CMbMessage objMsg; - for(int i = 0; i < 6; i++) - { - if(m_pMbComm->recvMsg(objMsg, 0)) - { - if(objMsg.isValid()) - { - if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) - { - continue; - } - if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) - { - continue; - } - parserMsg(objMsg); - } - } - } - } - catch(...) - { - - } -} - -void CRealDataCollect::processChangeData() -{ - if(!m_aiMap.isEmpty()) - { - emit signal_updateAi(m_aiMap); - m_aiMap.clear(); - } - - if(!m_diMap.isEmpty()) - { - emit signal_updateDi(m_diMap); - m_diMap.clear(); - } - - if(!m_piMap.isEmpty()) - { - emit signal_updatePi(m_piMap); - m_piMap.clear(); - } - - if(!m_miMap.isEmpty()) - { - emit signal_updateMi(m_miMap); - m_miMap.clear(); - } -} - -int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) -{ - kbd_idlfile::SRealTimeDataPkg changeDataPackage; - try - { - changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); - int aiSize = changeDataPackage.stairtd_size(); - if(aiSize > 0) - { - kbd_idlfile::SAiRealTimeData aiStru; - QString tagName; - float value; - uint status; - for(int i = 0; i < aiSize;++i) - { - aiStru = changeDataPackage.stairtd(i); - tagName = QString::fromStdString(aiStru.strtagname()); - value = aiStru.fvalue(); - status = aiStru.ustatus(); - m_aiMap[tagName] = qMakePair(value, status); - } - } - - int diSize = changeDataPackage.stdirtd_size(); - if(diSize > 0) - { - kbd_idlfile::SDiRealTimeData diStu; - QString tagName; - int value; - uint status; - for(int i = 0; i < diSize; ++i) - { - diStu = changeDataPackage.stdirtd(i); - tagName = QString::fromStdString(diStu.strtagname()); - value = diStu.nvalue(); - status = diStu.ustatus(); - m_diMap[tagName] = qMakePair(value, status); - } - } - - int piSize = changeDataPackage.stpirtd_size(); - if(piSize > 0) - { - kbd_idlfile::SPiRealTimeData piStu; - QString tagName; - double value; - uint status; - for(int i = 0 ; i < piSize; ++i) - { - piStu = changeDataPackage.stpirtd(i); - tagName = QString::fromStdString(piStu.strtagname()); - value = piStu.dvalue(); - status = piStu.ustatus(); - m_piMap[tagName] = qMakePair(value, status); - } - } - - int miSize = changeDataPackage.stmirtd_size(); - if(miSize > 0) - { - kbd_idlfile::SMiRealTimeData miStu; - QString tagName; - int value; - uint status; - for(int i = 0 ; i < miSize ; ++i) - { - miStu = changeDataPackage.stmirtd(i); - tagName = QString::fromStdString(miStu.strtagname()); - value = miStu.nvalue(); - status = miStu.ustatus(); - m_miMap[tagName] = qMakePair(value, status); - } - } - } - catch(...) - { - return 0; - } - return 1; -} +#include "CRealDataCollect.h" +#include + +CRealDataCollect* CRealDataCollect::m_pInstance = NULL; + +CRealDataCollect::CRealDataCollect() + : m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0) +{ + initMsg(); + if(!addSub()) + { + return; + } + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CRealDataCollect *CRealDataCollect::instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CRealDataCollect(); + } + return m_pInstance; +} + +void CRealDataCollect::release() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(); + closeMsg(); + m_pInstance = NULL; + delete this; +} + +void CRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new kbd_net::CMbCommunicator("DevSpePointWidget"); + } +} + +void CRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +void CRealDataCollect::clearMsg() +{ + if(m_pMbComm) + { + kbd_net::CMbMessage objMsg; + while(m_pMbComm->recvMsg(objMsg, 0)) + {} + } +} + +bool CRealDataCollect::addSub() +{ + if(m_pMbComm) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +bool CRealDataCollect::delSub() +{ + if(m_pMbComm) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +void CRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { + processChangeData(); + } + + try + { + kbd_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) + { + continue; + } + if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) + { + continue; + } + parserMsg(objMsg); + } + } + } + } + catch(...) + { + + } +} + +void CRealDataCollect::processChangeData() +{ + if(!m_aiMap.isEmpty()) + { + emit signal_updateAi(m_aiMap); + m_aiMap.clear(); + } + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + + if(!m_piMap.isEmpty()) + { + emit signal_updatePi(m_piMap); + m_piMap.clear(); + } + + if(!m_miMap.isEmpty()) + { + emit signal_updateMi(m_miMap); + m_miMap.clear(); + } +} + +int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) +{ + kbd_idlfile::SRealTimeDataPkg changeDataPackage; + try + { + changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); + int aiSize = changeDataPackage.stairtd_size(); + if(aiSize > 0) + { + kbd_idlfile::SAiRealTimeData aiStru; + QString tagName; + float value; + uint status; + for(int i = 0; i < aiSize;++i) + { + aiStru = changeDataPackage.stairtd(i); + tagName = QString::fromStdString(aiStru.strtagname()); + value = aiStru.fvalue(); + status = aiStru.ustatus(); + m_aiMap[tagName] = qMakePair(value, status); + } + } + + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + kbd_idlfile::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); + m_diMap[tagName] = qMakePair(value, status); + } + } + + int piSize = changeDataPackage.stpirtd_size(); + if(piSize > 0) + { + kbd_idlfile::SPiRealTimeData piStu; + QString tagName; + double value; + uint status; + for(int i = 0 ; i < piSize; ++i) + { + piStu = changeDataPackage.stpirtd(i); + tagName = QString::fromStdString(piStu.strtagname()); + value = piStu.dvalue(); + status = piStu.ustatus(); + m_piMap[tagName] = qMakePair(value, status); + } + } + + int miSize = changeDataPackage.stmirtd_size(); + if(miSize > 0) + { + kbd_idlfile::SMiRealTimeData miStu; + QString tagName; + int value; + uint status; + for(int i = 0 ; i < miSize ; ++i) + { + miStu = changeDataPackage.stmirtd(i); + tagName = QString::fromStdString(miStu.strtagname()); + value = miStu.nvalue(); + status = miStu.ustatus(); + m_miMap[tagName] = qMakePair(value, status); + } + } + } + catch(...) + { + return 0; + } + return 1; +} diff --git a/product/src/gui/plugin/DevSpePointWidget/CRealDataCollect.h b/product/src/gui/plugin/DevSpePointWidget/CRealDataCollect.h index d7e6e567..43d497b3 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CRealDataCollect.h +++ b/product/src/gui/plugin/DevSpePointWidget/CRealDataCollect.h @@ -1,52 +1,52 @@ -#ifndef CREALDATACOLLECT_H -#define CREALDATACOLLECT_H - -#include -#include -#include "net_msg_bus_api/CMbCommunicator.h" -#include "MessageChannel.h" -#include "DataProcMessage.pb.h" - -class QTimer; -class CRealDataCollect : public QObject -{ - Q_OBJECT -public: - static CRealDataCollect * instance(); - - void release(); - -private: - CRealDataCollect(); - - void initMsg(); - void closeMsg(); - void clearMsg(); - bool addSub(); - bool delSub(); - - int parserMsg(const kbd_net::CMbMessage &); - -private slots: - void recvMessage(); - void processChangeData(); - -signals: - void signal_updateAi(QMap> aiMap); - void signal_updateDi(QMap> diMap); - void signal_updatePi(QMap> piMap); - void signal_updateMi(QMap> miMap); - -private: - kbd_net::CMbCommunicator *m_pMbComm; - QTimer * m_pTimer; - int m_nTimeCount; - QMap> m_aiMap; - QMap> m_diMap; - QMap> m_piMap; - QMap> m_miMap; - - static CRealDataCollect * m_pInstance; -}; - -#endif // CREALDATACOLLECT_H +#ifndef CREALDATACOLLECT_H +#define CREALDATACOLLECT_H + +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" + +class QTimer; +class CRealDataCollect : public QObject +{ + Q_OBJECT +public: + static CRealDataCollect * instance(); + + void release(); + +private: + CRealDataCollect(); + + void initMsg(); + void closeMsg(); + void clearMsg(); + bool addSub(); + bool delSub(); + + int parserMsg(const kbd_net::CMbMessage &); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateAi(QMap> aiMap); + void signal_updateDi(QMap> diMap); + void signal_updatePi(QMap> piMap); + void signal_updateMi(QMap> miMap); + +private: + kbd_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + QMap> m_aiMap; + QMap> m_diMap; + QMap> m_piMap; + QMap> m_miMap; + + static CRealDataCollect * m_pInstance; +}; + +#endif // CREALDATACOLLECT_H diff --git a/product/src/gui/plugin/DevSpePointWidget/CRealTableModel.cpp b/product/src/gui/plugin/DevSpePointWidget/CRealTableModel.cpp index e403fc17..abfa4e6a 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CRealTableModel.cpp +++ b/product/src/gui/plugin/DevSpePointWidget/CRealTableModel.cpp @@ -1,181 +1,181 @@ -#include "CRealTableModel.h" -#include "dbms/rdb_api/CRdbAccess.h" -#include - -CRealTableModel::CRealTableModel(QObject *parent) - : QAbstractTableModel(parent), - m_strValidText("") -{ - -} - -void CRealTableModel::addColStateTextMap(int column, const QMap &map) -{ - if(map.isEmpty()) - { - return; - } - m_colStateTextMap[column] = map; -} - -void CRealTableModel::setValidString(const QString &text) -{ - m_strValidText = text; -} - -void CRealTableModel::setHeader(const QStringList &header) -{ - m_headerList = header; -} - -void CRealTableModel::updateRealData(const QMap > &dataMap) -{ - beginResetModel(); - m_dataMap = dataMap; - endResetModel(); -} - -void CRealTableModel::updateRealValue(QMap > dataMap) -{ - m_dataMap.swap(dataMap); - update(); -} - -void CRealTableModel::update() -{ - QModelIndex topLeft = createIndex(0, 1); - QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); - emit dataChanged(topLeft, bottomRight); -} - -QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(role == Qt::DisplayRole) - { - if(orientation == Qt::Horizontal) - { - return m_headerList.value(section, ""); - } - } - return QVariant(); -} - -int CRealTableModel::rowCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_dataMap.size(); -} - -int CRealTableModel::columnCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_headerList.size(); -} - -QVariant CRealTableModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid()) - return QVariant(); - - if(role == Qt::TextAlignmentRole) - { - return Qt::AlignCenter; - } - - if(role != Qt::DisplayRole && role != Qt::TextColorRole) - { - return QVariant(); - } - - QMap>::const_iterator rowIter = m_dataMap.begin() + index.row(); - const ST_RealData &data = rowIter.value().at(index.column()); - if(role == Qt::TextColorRole) - { - //判断是否告警未复归 如果复归则把值颜色修改为红色否则返回QVariant(); - if(data.isInit && data.type == TYPE_POINT) - { - if((data.status & 1024) == 1024) - { - return QVariant(QBrush(QColor(255,0,0))); - } - } - return QVariant(); - } - else if(role == Qt::DisplayRole) - { - if(data.type == TYPE_DESC) - { - return data.description; - } - if(data.isInit == false) - { - return QVariant(); - } - if(!m_strValidText.isEmpty()) - { - if((data.status & 4) == 4) - { - return m_strValidText; - } - } - QMap >::const_iterator iter = m_colStateTextMap.find(index.column()); - if(iter != m_colStateTextMap.end()) - { - return iter.value().value(data.value, QString::number(data.value, 'f', 2)); - } - if(data.table_name == "digital") - { - return getStateTextNameByValue(data.stateTextName, data.value); - } - else - { - // return data.value; - return QString::number(data.value, 'f', 2); - } - } - - return QVariant(); -} - -QString CRealTableModel::getStateTextNameByValue(const QString &textName, const int &value) const -{ - kbd_dbms::CRdbAccess objRtdbAccss; - QString ret = QString::number(value); - if(objRtdbAccss.open("base", "dict_state_text_info")) - { - kbd_dbms::CONDINFO condition1; - memcpy(condition1.name, "state_text_name", strlen("state_text_name")); - condition1.logicalop = ATTRCOND_AND; - condition1.relationop = ATTRCOND_EQU; - condition1.conditionval = textName.toStdString().c_str(); - - kbd_dbms::CONDINFO condition2; - memcpy(condition2.name, "actual_value", strlen("actual_value")); - condition2.logicalop = ATTRCOND_AND; - condition2.relationop = ATTRCOND_EQU; - condition2.conditionval = value; - - std::vector vecCondInfo; - vecCondInfo.push_back(condition1); - vecCondInfo.push_back(condition2); - - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("display_value"); - if(objRtdbAccss.select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, value); - ret = QString::fromStdString(value.toStdString()); - } - } - objRtdbAccss.close(); - } - return ret; -} +#include "CRealTableModel.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include + +CRealTableModel::CRealTableModel(QObject *parent) + : QAbstractTableModel(parent), + m_strValidText("") +{ + +} + +void CRealTableModel::addColStateTextMap(int column, const QMap &map) +{ + if(map.isEmpty()) + { + return; + } + m_colStateTextMap[column] = map; +} + +void CRealTableModel::setValidString(const QString &text) +{ + m_strValidText = text; +} + +void CRealTableModel::setHeader(const QStringList &header) +{ + m_headerList = header; +} + +void CRealTableModel::updateRealData(const QMap > &dataMap) +{ + beginResetModel(); + m_dataMap = dataMap; + endResetModel(); +} + +void CRealTableModel::updateRealValue(QMap > dataMap) +{ + m_dataMap.swap(dataMap); + update(); +} + +void CRealTableModel::update() +{ + QModelIndex topLeft = createIndex(0, 1); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); + emit dataChanged(topLeft, bottomRight); +} + +QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(role == Qt::DisplayRole) + { + if(orientation == Qt::Horizontal) + { + return m_headerList.value(section, ""); + } + } + return QVariant(); +} + +int CRealTableModel::rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_dataMap.size(); +} + +int CRealTableModel::columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_headerList.size(); +} + +QVariant CRealTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(role == Qt::TextAlignmentRole) + { + return Qt::AlignCenter; + } + + if(role != Qt::DisplayRole && role != Qt::TextColorRole) + { + return QVariant(); + } + + QMap>::const_iterator rowIter = m_dataMap.begin() + index.row(); + const ST_RealData &data = rowIter.value().at(index.column()); + if(role == Qt::TextColorRole) + { + //判断是否告警未复归 如果复归则把值颜色修改为红色否则返回QVariant(); + if(data.isInit && data.type == TYPE_POINT) + { + if((data.status & 1024) == 1024) + { + return QVariant(QBrush(QColor(255,0,0))); + } + } + return QVariant(); + } + else if(role == Qt::DisplayRole) + { + if(data.type == TYPE_DESC) + { + return data.description; + } + if(data.isInit == false) + { + return QVariant(); + } + if(!m_strValidText.isEmpty()) + { + if((data.status & 4) == 4) + { + return m_strValidText; + } + } + QMap >::const_iterator iter = m_colStateTextMap.find(index.column()); + if(iter != m_colStateTextMap.end()) + { + return iter.value().value(data.value, QString::number(data.value, 'f', 2)); + } + if(data.table_name == "digital") + { + return getStateTextNameByValue(data.stateTextName, data.value); + } + else + { + // return data.value; + return QString::number(data.value, 'f', 2); + } + } + + return QVariant(); +} + +QString CRealTableModel::getStateTextNameByValue(const QString &textName, const int &value) const +{ + kbd_dbms::CRdbAccess objRtdbAccss; + QString ret = QString::number(value); + if(objRtdbAccss.open("base", "dict_state_text_info")) + { + kbd_dbms::CONDINFO condition1; + memcpy(condition1.name, "state_text_name", strlen("state_text_name")); + condition1.logicalop = ATTRCOND_AND; + condition1.relationop = ATTRCOND_EQU; + condition1.conditionval = textName.toStdString().c_str(); + + kbd_dbms::CONDINFO condition2; + memcpy(condition2.name, "actual_value", strlen("actual_value")); + condition2.logicalop = ATTRCOND_AND; + condition2.relationop = ATTRCOND_EQU; + condition2.conditionval = value; + + std::vector vecCondInfo; + vecCondInfo.push_back(condition1); + vecCondInfo.push_back(condition2); + + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("display_value"); + if(objRtdbAccss.select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, value); + ret = QString::fromStdString(value.toStdString()); + } + } + objRtdbAccss.close(); + } + return ret; +} diff --git a/product/src/gui/plugin/DevSpePointWidget/CRealTableModel.h b/product/src/gui/plugin/DevSpePointWidget/CRealTableModel.h index 25b3d883..b59e4384 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CRealTableModel.h +++ b/product/src/gui/plugin/DevSpePointWidget/CRealTableModel.h @@ -1,42 +1,42 @@ -#ifndef CREALTABLEMODEL_H -#define CREALTABLEMODEL_H - -#include -#include "CDevSpePointCommon.h" - -class CRealTableModel : public QAbstractTableModel -{ -public: - explicit CRealTableModel(QObject *parent = nullptr); - - void addColStateTextMap(int column, const QMap &map); - - void setValidString(const QString &text); - - void setHeader(const QStringList &header); - - void updateRealData(const QMap> &dataMap); - - void updateRealValue(QMap > dataMap); - - void update(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: - QString getStateTextNameByValue(const QString &textName, const int &value) const; - -private: - QStringList m_headerList; - - QMap> m_dataMap; - QString m_strValidText; - QMap > m_colStateTextMap; -}; - -#endif // CREALTABLEMODEL_H +#ifndef CREALTABLEMODEL_H +#define CREALTABLEMODEL_H + +#include +#include "CDevSpePointCommon.h" + +class CRealTableModel : public QAbstractTableModel +{ +public: + explicit CRealTableModel(QObject *parent = nullptr); + + void addColStateTextMap(int column, const QMap &map); + + void setValidString(const QString &text); + + void setHeader(const QStringList &header); + + void updateRealData(const QMap> &dataMap); + + void updateRealValue(QMap > dataMap); + + void update(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QString getStateTextNameByValue(const QString &textName, const int &value) const; + +private: + QStringList m_headerList; + + QMap> m_dataMap; + QString m_strValidText; + QMap > m_colStateTextMap; +}; + +#endif // CREALTABLEMODEL_H diff --git a/product/src/gui/plugin/DevSpePointWidget/DevSpePointWidget.pro b/product/src/gui/plugin/DevSpePointWidget/DevSpePointWidget.pro index fbfca683..c9056aef 100644 --- a/product/src/gui/plugin/DevSpePointWidget/DevSpePointWidget.pro +++ b/product/src/gui/plugin/DevSpePointWidget/DevSpePointWidget.pro @@ -1,61 +1,61 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-12-10T10:45:31 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = DevSpePointWidget -TEMPLATE = lib - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CDevSpePointWidget.cpp \ - CRealTableModel.cpp \ - CRealDataCollect.cpp \ - CDevSpePointPluginWidget.cpp - -HEADERS += \ - CDevSpePointWidget.h \ - CDevSpePointCommon.h \ - CRealTableModel.h \ - CRealDataCollect.h \ - CDevSpePointPluginWidget.h - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lrdb_api \ - -ldb_base_api \ - -ldb_api_ex \ - -lprotobuf \ - -lnet_msg_bus_api \ - -ldp_chg_data_api \ - -lpub_utility_api - - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -FORMS += +#------------------------------------------------- +# +# Project created by QtCreator 2021-12-10T10:45:31 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = DevSpePointWidget +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CDevSpePointWidget.cpp \ + CRealTableModel.cpp \ + CRealDataCollect.cpp \ + CDevSpePointPluginWidget.cpp + +HEADERS += \ + CDevSpePointWidget.h \ + CDevSpePointCommon.h \ + CRealTableModel.h \ + CRealDataCollect.h \ + CDevSpePointPluginWidget.h + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lrdb_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lprotobuf \ + -lnet_msg_bus_api \ + -ldp_chg_data_api \ + -lpub_utility_api + + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +FORMS += diff --git a/product/src/gui/plugin/DevSpePointWidget/main.cpp b/product/src/gui/plugin/DevSpePointWidget/main.cpp index fc366f98..f5cd8f70 100644 --- a/product/src/gui/plugin/DevSpePointWidget/main.cpp +++ b/product/src/gui/plugin/DevSpePointWidget/main.cpp @@ -1,11 +1,11 @@ -#include "CDevSpePointWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - DevSpePointWidget w; - w.show(); - - return a.exec(); -} +#include "CDevSpePointWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + DevSpePointWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocComManage.h b/product/src/gui/plugin/DocumentManageWidget/CDocComManage.h index 26de73ba..a54eb1aa 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocComManage.h +++ b/product/src/gui/plugin/DocumentManageWidget/CDocComManage.h @@ -1,32 +1,32 @@ -#ifndef CDOCPATHMANAGE_H -#define CDOCPATHMANAGE_H - -#include - -#include "public/pub_utility_api/FileUtil.h" - -#include "perm_mng_api/PermMngApi.h" - -static QString getRootPath() -{ - std::string strCurModuleDir = kbd_public::CFileUtil::getCurModuleDir(); - strCurModuleDir += "../../data/PcpmsDocManage"; - return QString::fromStdString(strCurModuleDir); -} - -static bool checkDeletePerm() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - return false; - } - std::string tmpStr = "FUNC_NOM_OM"; - if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) - { - return false; - } - return true; -} - -#endif // CDOCPATHMANAGE_H +#ifndef CDOCPATHMANAGE_H +#define CDOCPATHMANAGE_H + +#include + +#include "public/pub_utility_api/FileUtil.h" + +#include "perm_mng_api/PermMngApi.h" + +static QString getRootPath() +{ + std::string strCurModuleDir = kbd_public::CFileUtil::getCurModuleDir(); + strCurModuleDir += "../../data/PcpmsDocManage"; + return QString::fromStdString(strCurModuleDir); +} + +static bool checkDeletePerm() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + return false; + } + std::string tmpStr = "FUNC_NOM_OM"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + return false; + } + return true; +} + +#endif // CDOCPATHMANAGE_H diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.cpp b/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.cpp index 00bcd287..dd6226a3 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.cpp @@ -1,26 +1,26 @@ -#include "CDocumentManagePlugin.h" -#include "CDocumentManageWidget.h" - -CDocumentManagePlugin::CDocumentManagePlugin(QObject *parent) -{ - -} - -CDocumentManagePlugin::~CDocumentManagePlugin() -{ - -} - -bool CDocumentManagePlugin::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CDocumentManageWidget *pWidget = new CDocumentManageWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *workTicketWidget = (IPluginWidget *)pWidget; - return true; -} - -void CDocumentManagePlugin::release() -{ - -} +#include "CDocumentManagePlugin.h" +#include "CDocumentManageWidget.h" + +CDocumentManagePlugin::CDocumentManagePlugin(QObject *parent) +{ + +} + +CDocumentManagePlugin::~CDocumentManagePlugin() +{ + +} + +bool CDocumentManagePlugin::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CDocumentManageWidget *pWidget = new CDocumentManageWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *workTicketWidget = (IPluginWidget *)pWidget; + return true; +} + +void CDocumentManagePlugin::release() +{ + +} diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.h b/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.h index f927f566..7989fb48 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.h +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.h @@ -1,21 +1,21 @@ -#ifndef CDOCUMENTMANAGEPLUGIN_H -#define CDOCUMENTMANAGEPLUGIN_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CDocumentManagePlugin : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CDocumentManagePlugin(QObject *parent = 0); - ~CDocumentManagePlugin(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec); - void release(); -}; - -#endif // CDOCUMENTMANAGEPLUGIN_H +#ifndef CDOCUMENTMANAGEPLUGIN_H +#define CDOCUMENTMANAGEPLUGIN_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CDocumentManagePlugin : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CDocumentManagePlugin(QObject *parent = 0); + ~CDocumentManagePlugin(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec); + void release(); +}; + +#endif // CDOCUMENTMANAGEPLUGIN_H diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.cpp b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.cpp index 1f0021b6..1780db62 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.cpp @@ -1,67 +1,67 @@ -#include "CDocumentManageWidget.h" -#include "ui_CDocumentManageWidget.h" -#include "pub_utility_api/FileStyle.h" -#include - -CDocumentManageWidget::CDocumentManageWidget(QWidget *parent, bool isEditMode) : - QWidget(parent), - ui(new Ui::CDocumentManageWidget) -{ - ui->setupUi(this); - - ui->splitter->setStretchFactor(0, 1); - ui->splitter->setStretchFactor(1, 2); - - if(!isEditMode) - { - initStyle(); - connect(ui->m_treeWidget, &CFileFolderTree::fileItemClicked, ui->m_tableWidget, &CFileTableWidget::resetView); - connect(ui->m_add, &QPushButton::clicked, ui->m_treeWidget, &CFileFolderTree::slotAdd); - connect(ui->m_modify, &QPushButton::clicked, ui->m_treeWidget, &CFileFolderTree::slotModify); - connect(ui->m_delete_2, &QPushButton::clicked, ui->m_treeWidget, &CFileFolderTree::slotDelete); - connect(ui->m_upload, &QPushButton::clicked, ui->m_tableWidget, &CFileTableWidget::slotUpload); - connect(ui->m_load, &QPushButton::clicked, ui->m_tableWidget, &CFileTableWidget::slotLoad); - connect(ui->m_delete, &QPushButton::clicked, ui->m_tableWidget, &CFileTableWidget::slotDelete); - connect(ui->m_open, &QPushButton::clicked, ui->m_tableWidget, &CFileTableWidget::slotOpen); - connect(ui->m_search, &QPushButton::clicked, this, &CDocumentManageWidget::slotSearch); - connect(ui->m_tableFilterEdit, &QLineEdit::textChanged, this, &CDocumentManageWidget::slotSearch); - } -} - -CDocumentManageWidget::~CDocumentManageWidget() -{ - delete ui; -} - -void CDocumentManageWidget::initStyle() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("documentManage.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CDocumentManageWidget::slotSearch() -{ - QString text = ui->m_tableFilterEdit->text(); - - ui->m_tableWidget->filter(text); -} +#include "CDocumentManageWidget.h" +#include "ui_CDocumentManageWidget.h" +#include "pub_utility_api/FileStyle.h" +#include + +CDocumentManageWidget::CDocumentManageWidget(QWidget *parent, bool isEditMode) : + QWidget(parent), + ui(new Ui::CDocumentManageWidget) +{ + ui->setupUi(this); + + ui->splitter->setStretchFactor(0, 1); + ui->splitter->setStretchFactor(1, 2); + + if(!isEditMode) + { + initStyle(); + connect(ui->m_treeWidget, &CFileFolderTree::fileItemClicked, ui->m_tableWidget, &CFileTableWidget::resetView); + connect(ui->m_add, &QPushButton::clicked, ui->m_treeWidget, &CFileFolderTree::slotAdd); + connect(ui->m_modify, &QPushButton::clicked, ui->m_treeWidget, &CFileFolderTree::slotModify); + connect(ui->m_delete_2, &QPushButton::clicked, ui->m_treeWidget, &CFileFolderTree::slotDelete); + connect(ui->m_upload, &QPushButton::clicked, ui->m_tableWidget, &CFileTableWidget::slotUpload); + connect(ui->m_load, &QPushButton::clicked, ui->m_tableWidget, &CFileTableWidget::slotLoad); + connect(ui->m_delete, &QPushButton::clicked, ui->m_tableWidget, &CFileTableWidget::slotDelete); + connect(ui->m_open, &QPushButton::clicked, ui->m_tableWidget, &CFileTableWidget::slotOpen); + connect(ui->m_search, &QPushButton::clicked, this, &CDocumentManageWidget::slotSearch); + connect(ui->m_tableFilterEdit, &QLineEdit::textChanged, this, &CDocumentManageWidget::slotSearch); + } +} + +CDocumentManageWidget::~CDocumentManageWidget() +{ + delete ui; +} + +void CDocumentManageWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("documentManage.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CDocumentManageWidget::slotSearch() +{ + QString text = ui->m_tableFilterEdit->text(); + + ui->m_tableWidget->filter(text); +} diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.h b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.h index af478188..f864ad1e 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.h +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.h @@ -1,28 +1,28 @@ -#ifndef CDOCUMENTMANAGEWIDGET_H -#define CDOCUMENTMANAGEWIDGET_H - -#include - -namespace Ui { -class CDocumentManageWidget; -} - -class CDocumentManageWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CDocumentManageWidget(QWidget *parent = 0, bool isEditMode = true); - ~CDocumentManageWidget(); - -private: - void initStyle(); - -private slots: - void slotSearch(); - -private: - Ui::CDocumentManageWidget *ui; -}; - -#endif // CDOCUMENTMANAGEWIDGET_H +#ifndef CDOCUMENTMANAGEWIDGET_H +#define CDOCUMENTMANAGEWIDGET_H + +#include + +namespace Ui { +class CDocumentManageWidget; +} + +class CDocumentManageWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CDocumentManageWidget(QWidget *parent = 0, bool isEditMode = true); + ~CDocumentManageWidget(); + +private: + void initStyle(); + +private slots: + void slotSearch(); + +private: + Ui::CDocumentManageWidget *ui; +}; + +#endif // CDOCUMENTMANAGEWIDGET_H diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.ui b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.ui index 7bf5cbdb..c9a41eb1 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.ui +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.ui @@ -1,146 +1,146 @@ - - - CDocumentManageWidget - - - - 0 - 0 - 1160 - 660 - - - - 文档管理 - - - - - - Qt::Horizontal - - - - - - - 添加 - - - - - - - 修改 - - - - - - - 删除 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 下载 - - - - - - - 上传 - - - - - - - 删除 - - - - - - - 查询 - - - - - - - Qt::Horizontal - - - - 68 - 20 - - - - - - - - 输入文档名称查询 - - - - - - - - - - 打开 - - - - - - - - - - - - - CFileFolderTree - QWidget -
CFileFolderTree.h
- 1 -
- - CFileTableWidget - QWidget -
CFileTableWidget.h
- 1 -
-
- - -
+ + + CDocumentManageWidget + + + + 0 + 0 + 1160 + 660 + + + + 文档管理 + + + + + + Qt::Horizontal + + + + + + + 添加 + + + + + + + 修改 + + + + + + + 删除 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 下载 + + + + + + + 上传 + + + + + + + 删除 + + + + + + + 查询 + + + + + + + Qt::Horizontal + + + + 68 + 20 + + + + + + + + 输入文档名称查询 + + + + + + + + + + 打开 + + + + + + + + + + + + + CFileFolderTree + QWidget +
CFileFolderTree.h
+ 1 +
+ + CFileTableWidget + QWidget +
CFileTableWidget.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.cpp b/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.cpp index 2a658518..1f86c43f 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.cpp @@ -1,294 +1,294 @@ -#include "CFileFolderTree.h" -#include "CDocComManage.h" -#include "CInputDialog.h" -#include -#include -#include -#include - -CFileFolderTree::CFileFolderTree(QWidget *parent) - : QTreeWidget(parent) -{ - initialize(); -} - -QString CFileFolderTree::getCurrentPath() -{ - if(currentItem()) - { - return currentItem()->data(0, Qt::UserRole).toString(); - } - return QString(); -} - -void CFileFolderTree::initialize() -{ - setColumnCount(1); - setHeaderHidden(true); - connect(this, &CFileFolderTree::itemClicked, this, &CFileFolderTree::slotItemClicked); - - QString curModuleDir = getRootPath(); - QDir dir; - bool isExists = dir.exists(curModuleDir); - if(!isExists) - { - dir.mkdir(curModuleDir); - } - dir.setPath(curModuleDir); - makeTree(dir, Q_NULLPTR); - expandAll(); -} - -void CFileFolderTree::makeTree(const QDir &dir, QTreeWidgetItem *parent) -{ - QStringList entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - - foreach (QString entry, entryList) { - QDir tmpDir; - tmpDir.setPath(dir.path()); - tmpDir.cd(entry); - QTreeWidgetItem * item = new QTreeWidgetItem; - item->setText(0, entry); - item->setData(0, Qt::UserRole, tmpDir.path()); - if(parent) - { - parent->addChild(item); - } - else - { - addTopLevelItem(item); - } - makeTree(tmpDir, item); - } -} - -bool CFileFolderTree::getInputFolderName(const QString &title, QString &folderName) -{ - bool ok = true; - QString name = folderName; - QRegExp nameExp("[\\d|\\w|\u4e00-\u9fa5]+"); - CInputDialog * dialog; - while(ok) - { - dialog = new CInputDialog(this); - dialog->setTitle(title); - dialog->setWindowFlag(Qt::WindowStaysOnTopHint, true); - dialog->resize(300,100); - int nameId = dialog->addOneInput(tr("名称:"), name); - if(dialog->exec() == QDialog::Accepted) - { - name = dialog->getInputText(nameId); - if(!nameExp.exactMatch(name)) - { - QMessageBox::information(this, tr("提示"), tr("非法的命名")); - continue; - } - else - { - folderName = name; - break; - } - } - else - { - ok = false; - } - } - delete dialog; - return ok; -} - -bool CFileFolderTree::rmdir(const QDir &dir) -{ - QStringList fileList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); - foreach (QString file, fileList) { - QDir tmpDir(dir); - tmpDir.remove(file); - } - - QStringList dirList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - foreach (QString entry, dirList) { - QDir tmpDir(dir); - tmpDir.cd(entry); - rmdir(tmpDir); - } - - return dir.rmdir(dir.path()); -} - -void CFileFolderTree::slotAdd() -{ - if(!checkDeletePerm()) - { - QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); - return; - } - QString name; - if(!getInputFolderName(tr("添加目录"), name)) - { - return; - } - - QString curModuleDir; - if(currentItem()) - { - curModuleDir = currentItem()->data(0, Qt::UserRole).toString() + QDir::separator() + name; - } - else - { - curModuleDir = getRootPath() + QDir::separator() + name; - } - - QDir dir; - if(dir.exists(curModuleDir)) - { - QMessageBox::information(this, tr("提示"), tr("目录已存在")); - return; - } - - bool isSuccess = dir.mkdir(curModuleDir); - if(!isSuccess) - { - QMessageBox::information(this, tr("提示"), tr("添加目录失败")); - } - else - { - QTreeWidgetItem * item = new QTreeWidgetItem; - item->setText(0, name); - item->setData(0, Qt::UserRole, curModuleDir); - if(currentItem()) - { - currentItem()->addChild(item); - expandItem(currentItem()); - } - else - { - addTopLevelItem(item); - } - } -} - -void CFileFolderTree::slotModify() -{ - if(!checkDeletePerm()) - { - QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); - return; - } - if(currentItem() == Q_NULLPTR) - { - QMessageBox::information(this, tr("提示"), tr("请选择要修改的目录")); - return; - } - QString oldName = currentItem()->text(0); - QString newName = oldName; - if(!getInputFolderName(tr("修改目录名称"), newName)) - { - return; - } - if(oldName == newName) - { - return; - } - - QString oldModuleDir = currentItem()->data(0, Qt::UserRole).toString(); - QDir dir(oldModuleDir); - dir.cdUp(); - QString newModuleDir = dir.path() + QDir::separator() + newName; - if(dir.exists(newModuleDir)) - { - QMessageBox::information(this, tr("提示"), tr("目录已存在")); - return; - } - - bool isSuccess = dir.rename(oldName, newName); - if(!isSuccess) - { - QMessageBox::information(this, tr("提示"), tr("修改目录名称失败")); - } - else - { - currentItem()->setText(0, newName); - currentItem()->setData(0, Qt::UserRole, newModuleDir); - } -} - -void CFileFolderTree::slotDelete() -{ - if(!checkDeletePerm()) - { - QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); - return; - } - if(currentItem() == Q_NULLPTR) - { - QMessageBox::information(this, tr("提示"), tr("请选择要删除的目录")); - return; - } - if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("确认删除?"))) - { - return; - } - - QString curModuleDir = currentItem()->data(0, Qt::UserRole).toString(); - bool isSuccess = rmdir(curModuleDir); - if(!isSuccess) - { - QMessageBox::information(this, tr("提示"), tr("删除目录失败")); - } - else - { - QTreeWidgetItem * parent = currentItem()->parent(); - if(parent == Q_NULLPTR) - { - takeTopLevelItem(indexOfTopLevelItem(currentItem())); - } - else - { - parent->takeChild(parent->indexOfChild(currentItem())); - } - if(currentItem()) - { - emit itemClicked(currentItem(), 0); - } - } -} - -void CFileFolderTree::slotItemClicked(QTreeWidgetItem *item, int column) -{ - emit fileItemClicked( item->data(column, Qt::UserRole).toString() ); -} - -void CFileFolderTree::contextMenuEvent(QContextMenuEvent *event) -{ - QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); - if(Q_NULLPTR != pItem) - { - QMenu menu; - menu.addAction(tr("添加"), [=](){ slotAdd(); }); - menu.addAction(tr("修改"), [=](){ slotModify(); }); - menu.addAction(tr("删除"), [=](){ slotDelete(); }); - menu.exec(event->globalPos()); - } - else - { - QMenu menu; - menu.addAction(tr("添加"), [=](){ slotAdd(); }); - menu.exec(event->globalPos()); - } -} - -void CFileFolderTree::mousePressEvent(QMouseEvent *event) -{ - QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); - if(Q_NULLPTR == pItem) - { - clearSelection(); - setCurrentItem(Q_NULLPTR); - emit fileItemClicked(""); - } - else - { - return QTreeWidget::mousePressEvent(event); - } -} +#include "CFileFolderTree.h" +#include "CDocComManage.h" +#include "CInputDialog.h" +#include +#include +#include +#include + +CFileFolderTree::CFileFolderTree(QWidget *parent) + : QTreeWidget(parent) +{ + initialize(); +} + +QString CFileFolderTree::getCurrentPath() +{ + if(currentItem()) + { + return currentItem()->data(0, Qt::UserRole).toString(); + } + return QString(); +} + +void CFileFolderTree::initialize() +{ + setColumnCount(1); + setHeaderHidden(true); + connect(this, &CFileFolderTree::itemClicked, this, &CFileFolderTree::slotItemClicked); + + QString curModuleDir = getRootPath(); + QDir dir; + bool isExists = dir.exists(curModuleDir); + if(!isExists) + { + dir.mkdir(curModuleDir); + } + dir.setPath(curModuleDir); + makeTree(dir, Q_NULLPTR); + expandAll(); +} + +void CFileFolderTree::makeTree(const QDir &dir, QTreeWidgetItem *parent) +{ + QStringList entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + + foreach (QString entry, entryList) { + QDir tmpDir; + tmpDir.setPath(dir.path()); + tmpDir.cd(entry); + QTreeWidgetItem * item = new QTreeWidgetItem; + item->setText(0, entry); + item->setData(0, Qt::UserRole, tmpDir.path()); + if(parent) + { + parent->addChild(item); + } + else + { + addTopLevelItem(item); + } + makeTree(tmpDir, item); + } +} + +bool CFileFolderTree::getInputFolderName(const QString &title, QString &folderName) +{ + bool ok = true; + QString name = folderName; + QRegExp nameExp("[\\d|\\w|\u4e00-\u9fa5]+"); + CInputDialog * dialog; + while(ok) + { + dialog = new CInputDialog(this); + dialog->setTitle(title); + dialog->setWindowFlag(Qt::WindowStaysOnTopHint, true); + dialog->resize(300,100); + int nameId = dialog->addOneInput(tr("名称:"), name); + if(dialog->exec() == QDialog::Accepted) + { + name = dialog->getInputText(nameId); + if(!nameExp.exactMatch(name)) + { + QMessageBox::information(this, tr("提示"), tr("非法的命名")); + continue; + } + else + { + folderName = name; + break; + } + } + else + { + ok = false; + } + } + delete dialog; + return ok; +} + +bool CFileFolderTree::rmdir(const QDir &dir) +{ + QStringList fileList = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); + foreach (QString file, fileList) { + QDir tmpDir(dir); + tmpDir.remove(file); + } + + QStringList dirList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + foreach (QString entry, dirList) { + QDir tmpDir(dir); + tmpDir.cd(entry); + rmdir(tmpDir); + } + + return dir.rmdir(dir.path()); +} + +void CFileFolderTree::slotAdd() +{ + if(!checkDeletePerm()) + { + QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); + return; + } + QString name; + if(!getInputFolderName(tr("添加目录"), name)) + { + return; + } + + QString curModuleDir; + if(currentItem()) + { + curModuleDir = currentItem()->data(0, Qt::UserRole).toString() + QDir::separator() + name; + } + else + { + curModuleDir = getRootPath() + QDir::separator() + name; + } + + QDir dir; + if(dir.exists(curModuleDir)) + { + QMessageBox::information(this, tr("提示"), tr("目录已存在")); + return; + } + + bool isSuccess = dir.mkdir(curModuleDir); + if(!isSuccess) + { + QMessageBox::information(this, tr("提示"), tr("添加目录失败")); + } + else + { + QTreeWidgetItem * item = new QTreeWidgetItem; + item->setText(0, name); + item->setData(0, Qt::UserRole, curModuleDir); + if(currentItem()) + { + currentItem()->addChild(item); + expandItem(currentItem()); + } + else + { + addTopLevelItem(item); + } + } +} + +void CFileFolderTree::slotModify() +{ + if(!checkDeletePerm()) + { + QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); + return; + } + if(currentItem() == Q_NULLPTR) + { + QMessageBox::information(this, tr("提示"), tr("请选择要修改的目录")); + return; + } + QString oldName = currentItem()->text(0); + QString newName = oldName; + if(!getInputFolderName(tr("修改目录名称"), newName)) + { + return; + } + if(oldName == newName) + { + return; + } + + QString oldModuleDir = currentItem()->data(0, Qt::UserRole).toString(); + QDir dir(oldModuleDir); + dir.cdUp(); + QString newModuleDir = dir.path() + QDir::separator() + newName; + if(dir.exists(newModuleDir)) + { + QMessageBox::information(this, tr("提示"), tr("目录已存在")); + return; + } + + bool isSuccess = dir.rename(oldName, newName); + if(!isSuccess) + { + QMessageBox::information(this, tr("提示"), tr("修改目录名称失败")); + } + else + { + currentItem()->setText(0, newName); + currentItem()->setData(0, Qt::UserRole, newModuleDir); + } +} + +void CFileFolderTree::slotDelete() +{ + if(!checkDeletePerm()) + { + QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); + return; + } + if(currentItem() == Q_NULLPTR) + { + QMessageBox::information(this, tr("提示"), tr("请选择要删除的目录")); + return; + } + if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("确认删除?"))) + { + return; + } + + QString curModuleDir = currentItem()->data(0, Qt::UserRole).toString(); + bool isSuccess = rmdir(curModuleDir); + if(!isSuccess) + { + QMessageBox::information(this, tr("提示"), tr("删除目录失败")); + } + else + { + QTreeWidgetItem * parent = currentItem()->parent(); + if(parent == Q_NULLPTR) + { + takeTopLevelItem(indexOfTopLevelItem(currentItem())); + } + else + { + parent->takeChild(parent->indexOfChild(currentItem())); + } + if(currentItem()) + { + emit itemClicked(currentItem(), 0); + } + } +} + +void CFileFolderTree::slotItemClicked(QTreeWidgetItem *item, int column) +{ + emit fileItemClicked( item->data(column, Qt::UserRole).toString() ); +} + +void CFileFolderTree::contextMenuEvent(QContextMenuEvent *event) +{ + QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if(Q_NULLPTR != pItem) + { + QMenu menu; + menu.addAction(tr("添加"), [=](){ slotAdd(); }); + menu.addAction(tr("修改"), [=](){ slotModify(); }); + menu.addAction(tr("删除"), [=](){ slotDelete(); }); + menu.exec(event->globalPos()); + } + else + { + QMenu menu; + menu.addAction(tr("添加"), [=](){ slotAdd(); }); + menu.exec(event->globalPos()); + } +} + +void CFileFolderTree::mousePressEvent(QMouseEvent *event) +{ + QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if(Q_NULLPTR == pItem) + { + clearSelection(); + setCurrentItem(Q_NULLPTR); + emit fileItemClicked(""); + } + else + { + return QTreeWidget::mousePressEvent(event); + } +} diff --git a/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.h b/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.h index 0223043b..89ab6ccc 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.h +++ b/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.h @@ -1,38 +1,38 @@ -#ifndef CFILEFOLDERTREE_H -#define CFILEFOLDERTREE_H - -#include - -class QDir; -class CFileFolderTree : public QTreeWidget -{ - Q_OBJECT -public: - CFileFolderTree(QWidget *parent = Q_NULLPTR); - - QString getCurrentPath(); - -signals: - void fileItemClicked(const QString &path); - -private: - void initialize(); - void makeTree(const QDir &dir, QTreeWidgetItem * parent); - bool getInputFolderName(const QString &title, QString &folderName); - bool rmdir(const QDir &dir); - -public slots: - void slotAdd(); - void slotModify(); - void slotDelete(); - -private slots: - void slotItemClicked(QTreeWidgetItem *item, int column); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - void mousePressEvent(QMouseEvent *event); - -}; - -#endif // CFILEFOLDERTREE_H +#ifndef CFILEFOLDERTREE_H +#define CFILEFOLDERTREE_H + +#include + +class QDir; +class CFileFolderTree : public QTreeWidget +{ + Q_OBJECT +public: + CFileFolderTree(QWidget *parent = Q_NULLPTR); + + QString getCurrentPath(); + +signals: + void fileItemClicked(const QString &path); + +private: + void initialize(); + void makeTree(const QDir &dir, QTreeWidgetItem * parent); + bool getInputFolderName(const QString &title, QString &folderName); + bool rmdir(const QDir &dir); + +public slots: + void slotAdd(); + void slotModify(); + void slotDelete(); + +private slots: + void slotItemClicked(QTreeWidgetItem *item, int column); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + void mousePressEvent(QMouseEvent *event); + +}; + +#endif // CFILEFOLDERTREE_H diff --git a/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.cpp b/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.cpp index 3ac76339..54d47399 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.cpp @@ -1,314 +1,314 @@ -#include "CFileTableWidget.h" -#include "CDocComManage.h" -#include -#include -#include -#include -#include -#include -#include - -CFileTableWidget::CFileTableWidget(QWidget *parent) - : QTableWidget(parent) -{ - initialize(); -} - -void CFileTableWidget::filter(const QString &docName) -{ - m_filterText = docName; - - int row = rowCount(); - for(int nIndex(0); nIndex < row; nIndex++) - { - if(docName.isEmpty()) - { - setRowHidden(nIndex, false); - continue; - } - if(item(nIndex, COLUMN_NAME)->text().contains(docName)) - { - setRowHidden(nIndex, false); - } - else - { - setRowHidden(nIndex, true); - } - } -} - -void CFileTableWidget::resetView(const QString &path) -{ - m_rootPath = path; - clearContents(); - setRowCount(0); - - if(m_rootPath.isEmpty()) - { - return; - } - makeTable(m_rootPath); - filter(m_filterText); -} - -void CFileTableWidget::slotUpload() -{ - if(!checkDeletePerm()) - { - QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); - return; - } - if(m_rootPath.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("请选择上传目录")); - return; - } - - QStringList fileList = QFileDialog::getOpenFileNames(this, tr("上传文档")); - if(fileList.isEmpty()) - { - return; - } - - QDir dir(m_rootPath); - QString error; - bool successTip = false; - foreach (QString file, fileList) { - QFileInfo sourceFile(file); - QString dstFile = dir.path() + QDir::separator() + sourceFile.fileName(); - if(dir.exists(sourceFile.fileName())) - { - if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("文档已存在: %1,是否替换?").arg(sourceFile.fileName()))) - { - continue; - } - if(false == QFile::remove(dstFile)) - { - error += QString("%1\n").arg(sourceFile.fileName()); - continue; - } - } - if(false == QFile::copy(file, dstFile)) - { - error += QString("%1\n").arg(sourceFile.fileName()); - } - else - { - successTip = true; - } - } - if(!error.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("%1 上传失败").arg(error)); - } - else - { - if(successTip) - { - QMessageBox::information(this, tr("提示"), tr("上传成功")); - } - } - resetView(m_rootPath); -} - -void CFileTableWidget::slotLoad() -{ - QModelIndexList indexList = selectionModel()->selectedRows(); - if(indexList.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("请选择文档")); - return; - } - - QString loadPath = QFileDialog::getExistingDirectory(this, tr("请选择下载路径")); - if(loadPath.isEmpty()) - { - return; - } - - QString error; - bool successTip = false; - foreach (QModelIndex index, indexList) { - int row = index.row(); - QString sourcePath = getRootPath() + QDir::separator() + item(row, 3)->text() + QDir::separator() + item(row, 1)->text(); - QString dstPath = loadPath + QDir::separator() + item(row, 1)->text(); - QDir dstDir(loadPath); - if(dstDir.exists(item(row, 1)->text())) - { - if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("文档已存在: %1,是否替换?").arg(item(row, 1)->text()))) - { - continue; - } - if(false == QFile::remove(dstPath)) - { - error += QString("%1\n").arg(item(row, 1)->text()); - continue; - } - } - bool isSuccess = QFile::copy(sourcePath, dstPath); - if(!isSuccess) - { - error += QString("%1\n").arg(item(row, 1)->text()); - } - else - { - successTip = true; - } - } - if(!error.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("%1 下载失败").arg(error)); - } - else - { - if(successTip) - { - QMessageBox::information(this, tr("提示"), tr("下载成功")); - } - } -} - -void CFileTableWidget::slotDelete() -{ - if(!checkDeletePerm()) - { - QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); - return; - } - QModelIndexList indexList = selectionModel()->selectedRows(); - if(indexList.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("请选择文档")); - return; - } - if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("确认删除?"))) - { - return; - } - QDir dir; - foreach (QModelIndex index, indexList) { - int row = index.row(); - QString filePath = getRootPath() + QDir::separator() + item(row, 3)->text() + QDir::separator() + item(row, 1)->text(); - bool isSuccess = dir.remove(filePath); - if(!isSuccess) - { - QMessageBox::information(this, tr("提示"), tr("删除 %1 失败").arg(item(row, 1)->text())); - continue; - } - } - resetView(m_rootPath); -} - -void CFileTableWidget::slotOpen() -{ - QModelIndexList indexList = selectionModel()->selectedRows(); - if(indexList.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("请选择文档")); - return; - } - QModelIndex index = indexList[0]; - int row = index.row(); - QString filePath = getRootPath() + QDir::separator() + item(row, 3)->text() + QDir::separator() + item(row, 1)->text(); - - QFile file(filePath); - if(!file.exists()) - { - QMessageBox::information(this, tr("提示"), tr("文档不存在")); - return; - } - if(false == QDesktopServices::openUrl(QUrl::fromLocalFile(filePath))) - { - QMessageBox::information(this, tr("提示"), tr("打开文档失败")); - } -} - -int CFileTableWidget::tableColumnWidth() -{ - return m_nTableColWidth; -} - -void CFileTableWidget::setTableColumnWidth(const int &nWidth) -{ - m_nTableColWidth = nWidth; - - horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); -} - -int CFileTableWidget::tableRowHeight() -{ - return m_nTableRowHeight; -} - -void CFileTableWidget::setTableRowHeight(const int &nHeight) -{ - m_nTableRowHeight = nHeight; - - verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); -} - -void CFileTableWidget::initialize() -{ - setColumnCount(4); - setColumnWidth(COLUMN_SEQ, 50); - setColumnWidth(COLUMN_NAME, 350); - setColumnWidth(COLUMN_DATE, 190); - setHorizontalHeaderLabels(QStringList() << tr("序号") << tr("文档名称") << tr("文档修改时间") << tr("文档路径")); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setEditTriggers(QAbstractItemView::NoEditTriggers); - horizontalHeader()->setStretchLastSection(true); - setAlternatingRowColors(true); - verticalHeader()->setHidden(true); -} - -void CFileTableWidget::makeTable(const QString &path) -{ - QDir dir(path); - QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Time); - foreach (QFileInfo fileInfo, fileInfoList) { - int row = rowCount(); - insertRow(row); - - QTableWidgetItem * seqItem = new QTableWidgetItem(); - seqItem->setText(QString::number(row + 1)); - seqItem->setTextAlignment(Qt::AlignCenter); - setItem(row, COLUMN_SEQ, seqItem); - - QTableWidgetItem * nameItem = new QTableWidgetItem; - nameItem->setText(fileInfo.fileName()); - nameItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); - setItem(row, COLUMN_NAME, nameItem); - - QTableWidgetItem * dateItem = new QTableWidgetItem; - dateItem->setText(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss")); - dateItem->setTextAlignment(Qt::AlignCenter); - setItem(row, COLUMN_DATE, dateItem); - - QTableWidgetItem * pathItem = new QTableWidgetItem; - QDir tmpRootDir(getRootPath()); - QDir tmpFileDir(fileInfo.filePath()); - tmpFileDir.cdUp(); - pathItem->setText(tmpRootDir.relativeFilePath(tmpFileDir.path())); - pathItem->setTextAlignment(Qt::AlignCenter); - setItem(row, COLUMN_PATH, pathItem); - } - - QStringList entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time); - foreach (QString entry, entryList) { - makeTable(path + QDir::separator() + entry); - } -} - -void CFileTableWidget::mousePressEvent(QMouseEvent *event) -{ - QModelIndex modelIndex = indexAt(event->pos()); - if(-1 == modelIndex.row()) - { - clearSelection(); - } - else - { - } - return QTableWidget::mousePressEvent(event); -} +#include "CFileTableWidget.h" +#include "CDocComManage.h" +#include +#include +#include +#include +#include +#include +#include + +CFileTableWidget::CFileTableWidget(QWidget *parent) + : QTableWidget(parent) +{ + initialize(); +} + +void CFileTableWidget::filter(const QString &docName) +{ + m_filterText = docName; + + int row = rowCount(); + for(int nIndex(0); nIndex < row; nIndex++) + { + if(docName.isEmpty()) + { + setRowHidden(nIndex, false); + continue; + } + if(item(nIndex, COLUMN_NAME)->text().contains(docName)) + { + setRowHidden(nIndex, false); + } + else + { + setRowHidden(nIndex, true); + } + } +} + +void CFileTableWidget::resetView(const QString &path) +{ + m_rootPath = path; + clearContents(); + setRowCount(0); + + if(m_rootPath.isEmpty()) + { + return; + } + makeTable(m_rootPath); + filter(m_filterText); +} + +void CFileTableWidget::slotUpload() +{ + if(!checkDeletePerm()) + { + QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); + return; + } + if(m_rootPath.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("请选择上传目录")); + return; + } + + QStringList fileList = QFileDialog::getOpenFileNames(this, tr("上传文档")); + if(fileList.isEmpty()) + { + return; + } + + QDir dir(m_rootPath); + QString error; + bool successTip = false; + foreach (QString file, fileList) { + QFileInfo sourceFile(file); + QString dstFile = dir.path() + QDir::separator() + sourceFile.fileName(); + if(dir.exists(sourceFile.fileName())) + { + if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("文档已存在: %1,是否替换?").arg(sourceFile.fileName()))) + { + continue; + } + if(false == QFile::remove(dstFile)) + { + error += QString("%1\n").arg(sourceFile.fileName()); + continue; + } + } + if(false == QFile::copy(file, dstFile)) + { + error += QString("%1\n").arg(sourceFile.fileName()); + } + else + { + successTip = true; + } + } + if(!error.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("%1 上传失败").arg(error)); + } + else + { + if(successTip) + { + QMessageBox::information(this, tr("提示"), tr("上传成功")); + } + } + resetView(m_rootPath); +} + +void CFileTableWidget::slotLoad() +{ + QModelIndexList indexList = selectionModel()->selectedRows(); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("请选择文档")); + return; + } + + QString loadPath = QFileDialog::getExistingDirectory(this, tr("请选择下载路径")); + if(loadPath.isEmpty()) + { + return; + } + + QString error; + bool successTip = false; + foreach (QModelIndex index, indexList) { + int row = index.row(); + QString sourcePath = getRootPath() + QDir::separator() + item(row, 3)->text() + QDir::separator() + item(row, 1)->text(); + QString dstPath = loadPath + QDir::separator() + item(row, 1)->text(); + QDir dstDir(loadPath); + if(dstDir.exists(item(row, 1)->text())) + { + if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("文档已存在: %1,是否替换?").arg(item(row, 1)->text()))) + { + continue; + } + if(false == QFile::remove(dstPath)) + { + error += QString("%1\n").arg(item(row, 1)->text()); + continue; + } + } + bool isSuccess = QFile::copy(sourcePath, dstPath); + if(!isSuccess) + { + error += QString("%1\n").arg(item(row, 1)->text()); + } + else + { + successTip = true; + } + } + if(!error.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("%1 下载失败").arg(error)); + } + else + { + if(successTip) + { + QMessageBox::information(this, tr("提示"), tr("下载成功")); + } + } +} + +void CFileTableWidget::slotDelete() +{ + if(!checkDeletePerm()) + { + QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); + return; + } + QModelIndexList indexList = selectionModel()->selectedRows(); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("请选择文档")); + return; + } + if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("确认删除?"))) + { + return; + } + QDir dir; + foreach (QModelIndex index, indexList) { + int row = index.row(); + QString filePath = getRootPath() + QDir::separator() + item(row, 3)->text() + QDir::separator() + item(row, 1)->text(); + bool isSuccess = dir.remove(filePath); + if(!isSuccess) + { + QMessageBox::information(this, tr("提示"), tr("删除 %1 失败").arg(item(row, 1)->text())); + continue; + } + } + resetView(m_rootPath); +} + +void CFileTableWidget::slotOpen() +{ + QModelIndexList indexList = selectionModel()->selectedRows(); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("请选择文档")); + return; + } + QModelIndex index = indexList[0]; + int row = index.row(); + QString filePath = getRootPath() + QDir::separator() + item(row, 3)->text() + QDir::separator() + item(row, 1)->text(); + + QFile file(filePath); + if(!file.exists()) + { + QMessageBox::information(this, tr("提示"), tr("文档不存在")); + return; + } + if(false == QDesktopServices::openUrl(QUrl::fromLocalFile(filePath))) + { + QMessageBox::information(this, tr("提示"), tr("打开文档失败")); + } +} + +int CFileTableWidget::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CFileTableWidget::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CFileTableWidget::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CFileTableWidget::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} + +void CFileTableWidget::initialize() +{ + setColumnCount(4); + setColumnWidth(COLUMN_SEQ, 50); + setColumnWidth(COLUMN_NAME, 350); + setColumnWidth(COLUMN_DATE, 190); + setHorizontalHeaderLabels(QStringList() << tr("序号") << tr("文档名称") << tr("文档修改时间") << tr("文档路径")); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setEditTriggers(QAbstractItemView::NoEditTriggers); + horizontalHeader()->setStretchLastSection(true); + setAlternatingRowColors(true); + verticalHeader()->setHidden(true); +} + +void CFileTableWidget::makeTable(const QString &path) +{ + QDir dir(path); + QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Time); + foreach (QFileInfo fileInfo, fileInfoList) { + int row = rowCount(); + insertRow(row); + + QTableWidgetItem * seqItem = new QTableWidgetItem(); + seqItem->setText(QString::number(row + 1)); + seqItem->setTextAlignment(Qt::AlignCenter); + setItem(row, COLUMN_SEQ, seqItem); + + QTableWidgetItem * nameItem = new QTableWidgetItem; + nameItem->setText(fileInfo.fileName()); + nameItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); + setItem(row, COLUMN_NAME, nameItem); + + QTableWidgetItem * dateItem = new QTableWidgetItem; + dateItem->setText(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss")); + dateItem->setTextAlignment(Qt::AlignCenter); + setItem(row, COLUMN_DATE, dateItem); + + QTableWidgetItem * pathItem = new QTableWidgetItem; + QDir tmpRootDir(getRootPath()); + QDir tmpFileDir(fileInfo.filePath()); + tmpFileDir.cdUp(); + pathItem->setText(tmpRootDir.relativeFilePath(tmpFileDir.path())); + pathItem->setTextAlignment(Qt::AlignCenter); + setItem(row, COLUMN_PATH, pathItem); + } + + QStringList entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time); + foreach (QString entry, entryList) { + makeTable(path + QDir::separator() + entry); + } +} + +void CFileTableWidget::mousePressEvent(QMouseEvent *event) +{ + QModelIndex modelIndex = indexAt(event->pos()); + if(-1 == modelIndex.row()) + { + clearSelection(); + } + else + { + } + return QTableWidget::mousePressEvent(event); +} diff --git a/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.h b/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.h index c38333ca..112a50c1 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.h +++ b/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.h @@ -1,54 +1,54 @@ -#ifndef CFILETABLEWIDGET_H -#define CFILETABLEWIDGET_H - -#include - -class CFileTableWidget : public QTableWidget -{ - Q_OBJECT - Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) - Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) - -public: - enum EN_COLUMN - { - COLUMN_SEQ = 0, - COLUMN_NAME, - COLUMN_DATE, - COLUMN_PATH - }; - CFileTableWidget(QWidget *parent = Q_NULLPTR); - - void filter(const QString &docName); - -public slots: - void resetView(const QString &path); - - void slotUpload(); - void slotLoad(); - void slotDelete(); - void slotOpen(); - - int tableColumnWidth(); - void setTableColumnWidth(const int &nWidth); - - int tableRowHeight(); - void setTableRowHeight(const int &nHeight); - - -private: - void initialize(); - void makeTable(const QString &path); - -protected: - void mousePressEvent(QMouseEvent *event); - -private: - QString m_rootPath; - QString m_filterText; - - int m_nTableColWidth; - int m_nTableRowHeight; -}; - -#endif // CFILETABLEWIDGET_H +#ifndef CFILETABLEWIDGET_H +#define CFILETABLEWIDGET_H + +#include + +class CFileTableWidget : public QTableWidget +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + enum EN_COLUMN + { + COLUMN_SEQ = 0, + COLUMN_NAME, + COLUMN_DATE, + COLUMN_PATH + }; + CFileTableWidget(QWidget *parent = Q_NULLPTR); + + void filter(const QString &docName); + +public slots: + void resetView(const QString &path); + + void slotUpload(); + void slotLoad(); + void slotDelete(); + void slotOpen(); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + + +private: + void initialize(); + void makeTable(const QString &path); + +protected: + void mousePressEvent(QMouseEvent *event); + +private: + QString m_rootPath; + QString m_filterText; + + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +#endif // CFILETABLEWIDGET_H diff --git a/product/src/gui/plugin/DocumentManageWidget/CInputDialog.cpp b/product/src/gui/plugin/DocumentManageWidget/CInputDialog.cpp index 1b38829f..21caaf03 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CInputDialog.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CInputDialog.cpp @@ -1,64 +1,64 @@ -#include "CInputDialog.h" -#include -#include -#include -#include - -CInputDialog::CInputDialog(QWidget *parent) - : QDialog(parent), - m_nInputId(0) -{ - QVBoxLayout * layout = new QVBoxLayout(this); - QDialogButtonBox * buttonBox = new QDialogButtonBox( - QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - layout->addWidget(buttonBox); - layout->setMargin(3); - layout->setSpacing(3); - setLayout(layout); - connect(buttonBox, &QDialogButtonBox::accepted, [=]{accept();}); - connect(buttonBox, &QDialogButtonBox::rejected, [=]{reject();}); -} - -CInputDialog::~CInputDialog() -{ - m_inputMap.clear(); -} - -void CInputDialog::setTitle(const QString &title) -{ - setWindowTitle(title); -} - -int CInputDialog::addOneInput(const QString &text, const QString &value) -{ - QVBoxLayout *gLayout = dynamic_cast(this->layout()); - if(gLayout) - { - QVBoxLayout * layout = new QVBoxLayout; - QLabel * label = new QLabel(text); - QLineEdit * edit = new QLineEdit(value); - layout->addWidget(label); - layout->addWidget(edit); - layout->setMargin(3); - layout->setSpacing(3); - QDialogButtonBox * b = findChild(); - gLayout->insertLayout(gLayout->indexOf(b), layout); - m_inputMap.insert(m_nInputId, edit); - return m_nInputId++; - } - return -1; -} - -QString CInputDialog::getInputText(int nInputId) -{ - if(nInputId < 0) - { - return QString(); - } - QLineEdit *lineEdit = m_inputMap.value(nInputId); - if(lineEdit) - { - return lineEdit->text(); - } - return QString(); -} +#include "CInputDialog.h" +#include +#include +#include +#include + +CInputDialog::CInputDialog(QWidget *parent) + : QDialog(parent), + m_nInputId(0) +{ + QVBoxLayout * layout = new QVBoxLayout(this); + QDialogButtonBox * buttonBox = new QDialogButtonBox( + QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + layout->addWidget(buttonBox); + layout->setMargin(3); + layout->setSpacing(3); + setLayout(layout); + connect(buttonBox, &QDialogButtonBox::accepted, [=]{accept();}); + connect(buttonBox, &QDialogButtonBox::rejected, [=]{reject();}); +} + +CInputDialog::~CInputDialog() +{ + m_inputMap.clear(); +} + +void CInputDialog::setTitle(const QString &title) +{ + setWindowTitle(title); +} + +int CInputDialog::addOneInput(const QString &text, const QString &value) +{ + QVBoxLayout *gLayout = dynamic_cast(this->layout()); + if(gLayout) + { + QVBoxLayout * layout = new QVBoxLayout; + QLabel * label = new QLabel(text); + QLineEdit * edit = new QLineEdit(value); + layout->addWidget(label); + layout->addWidget(edit); + layout->setMargin(3); + layout->setSpacing(3); + QDialogButtonBox * b = findChild(); + gLayout->insertLayout(gLayout->indexOf(b), layout); + m_inputMap.insert(m_nInputId, edit); + return m_nInputId++; + } + return -1; +} + +QString CInputDialog::getInputText(int nInputId) +{ + if(nInputId < 0) + { + return QString(); + } + QLineEdit *lineEdit = m_inputMap.value(nInputId); + if(lineEdit) + { + return lineEdit->text(); + } + return QString(); +} diff --git a/product/src/gui/plugin/DocumentManageWidget/CInputDialog.h b/product/src/gui/plugin/DocumentManageWidget/CInputDialog.h index 8c177a21..1a9f1544 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CInputDialog.h +++ b/product/src/gui/plugin/DocumentManageWidget/CInputDialog.h @@ -1,28 +1,28 @@ -#ifndef CINPUTDIALOG_H -#define CINPUTDIALOG_H - -#include -#include -#include - -class QLineEdit; -class CInputDialog : public QDialog -{ - Q_OBJECT -public: - CInputDialog(QWidget *parent = Q_NULLPTR); - ~CInputDialog(); - - void setTitle(const QString &title); - - int addOneInput(const QString &text, const QString &value); - - QString getInputText(int nInputId); - -private: - int m_nInputId; - QMap m_inputMap; - -}; - -#endif // CINPUTDIALOG_H +#ifndef CINPUTDIALOG_H +#define CINPUTDIALOG_H + +#include +#include +#include + +class QLineEdit; +class CInputDialog : public QDialog +{ + Q_OBJECT +public: + CInputDialog(QWidget *parent = Q_NULLPTR); + ~CInputDialog(); + + void setTitle(const QString &title); + + int addOneInput(const QString &text, const QString &value); + + QString getInputText(int nInputId); + +private: + int m_nInputId; + QMap m_inputMap; + +}; + +#endif // CINPUTDIALOG_H diff --git a/product/src/gui/plugin/DocumentManageWidget/DocumentManageWidget.pro b/product/src/gui/plugin/DocumentManageWidget/DocumentManageWidget.pro index 5d499fe9..36344f9f 100644 --- a/product/src/gui/plugin/DocumentManageWidget/DocumentManageWidget.pro +++ b/product/src/gui/plugin/DocumentManageWidget/DocumentManageWidget.pro @@ -1,53 +1,53 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-12-14T16:25:26 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = DocumentManageWidget -TEMPLATE = lib - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CDocumentManageWidget.cpp \ - CFileFolderTree.cpp \ - CInputDialog.cpp \ - CFileTableWidget.cpp \ - CDocumentManagePlugin.cpp - -HEADERS += \ - CDocumentManageWidget.h \ - CFileFolderTree.h \ - CInputDialog.h \ - CFileTableWidget.h \ - CDocComManage.h \ - CDocumentManagePlugin.h - -FORMS += \ - CDocumentManageWidget.ui - -LIBS += \ - -lpub_utility_api \ - -lperm_mng_api - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-12-14T16:25:26 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = DocumentManageWidget +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CDocumentManageWidget.cpp \ + CFileFolderTree.cpp \ + CInputDialog.cpp \ + CFileTableWidget.cpp \ + CDocumentManagePlugin.cpp + +HEADERS += \ + CDocumentManageWidget.h \ + CFileFolderTree.h \ + CInputDialog.h \ + CFileTableWidget.h \ + CDocComManage.h \ + CDocumentManagePlugin.h + +FORMS += \ + CDocumentManageWidget.ui + +LIBS += \ + -lpub_utility_api \ + -lperm_mng_api + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/DocumentManageWidget/main.cpp b/product/src/gui/plugin/DocumentManageWidget/main.cpp index 3750dd8e..a6c31bbc 100644 --- a/product/src/gui/plugin/DocumentManageWidget/main.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/main.cpp @@ -1,11 +1,11 @@ -#include "CDocumentManageWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CDocumentManageWidget w(NULL,false); - w.show(); - - return a.exec(); -} +#include "CDocumentManageWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CDocumentManageWidget w(NULL,false); + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/EventWidget/CAccidentReviewDialog.cpp b/product/src/gui/plugin/EventWidget/CAccidentReviewDialog.cpp index f0b59bb7..493f740a 100644 --- a/product/src/gui/plugin/EventWidget/CAccidentReviewDialog.cpp +++ b/product/src/gui/plugin/EventWidget/CAccidentReviewDialog.cpp @@ -1,289 +1,289 @@ -#include "CAccidentReviewDialog.h" -#include "public/pub_utility_api/FileUtil.h" -#include "public/pub_logger_api/logger.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -CAccidentReviewDialog::CAccidentReviewDialog(const QString &path, QWidget *parent) - : QDialog(parent) -{ - resize(350,450); - getFilterNames(path); - initView(); - initTree(); -} - -CAccidentReviewDialog::~CAccidentReviewDialog() -{ - -} - -QString CAccidentReviewDialog::getCurrentGraph() -{ - if(m_treeWidget->currentItem()) - { - return m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); - } - return QString(); -} - -void CAccidentReviewDialog::initView() -{ - setWindowTitle(tr("事故追忆")); - m_treeWidget = new QTreeWidget(this); - m_treeWidget->headerItem()->setHidden(true); - - QSpacerItem * spacer = new QSpacerItem(10, 0, QSizePolicy::Preferred); - m_confirmBtn = new QPushButton(tr("确认"), this); - m_cancelBtn = new QPushButton(tr("取消"), this); - connect(m_confirmBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotConfirm); - connect(m_cancelBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotCancel); - - QGridLayout * layout = new QGridLayout(); - layout->addWidget(m_treeWidget, 0, 0, 1, 3); - layout->addItem(spacer, 1, 0); - layout->addWidget(m_confirmBtn, 1, 1); - layout->addWidget(m_cancelBtn, 1, 2); - setLayout(layout); -} - -void CAccidentReviewDialog::initTree() -{ - QMap>> m_mapNav; - readNavJson(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) - + QString("../../data/model/NavigationWidget.json"), m_mapNav); - QList> nodeList = m_mapNav.value(-1); - for(int nIndex=0; nIndexaddTopLevelItem(item); - - addChildLevelItem(item, nodeList[nIndex], m_mapNav); - } - treeFilter(); - m_treeWidget->expandAll(); -} - -void CAccidentReviewDialog::getFilterNames(const QString &path) -{ - QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) - + QString("../../data/pic/"); - m_fileNameList = getAllFile(filePath, filePath, path); -} - -QStringList CAccidentReviewDialog::getAllFile(const QString &path, const QString &relativePath, const QString &filter) -{ - QDir dir(path); - QDir relativeDir(relativePath); - QStringList allFile; - - QString fileName; - QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoSymLinks); - for(QFileInfo &file : fileList) - { - fileName = relativeDir.relativeFilePath(file.filePath()); - if(fileName.contains(filter)) - { - allFile.append(fileName); - } - } - - QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - for(QFileInfo &folder : folderList) - { - allFile.append(getAllFile(folder.absoluteFilePath(), relativePath, filter)); - } - - return allFile; -} - -void CAccidentReviewDialog::treeFilter() -{ - bool topShow,childShow,leafShow; - int nTopCount = m_treeWidget->topLevelItemCount(); - for(int nTopIndex(0); nTopIndextopLevelItem(nTopIndex); - topShow = m_fileNameList.contains(topItem->data(0, Qt::UserRole).toString()); - - int nChildCount = topItem->childCount(); - for(int nChildIndex(0); nChildIndexchild(nChildIndex); - childShow = m_fileNameList.contains(childItem->data(0, Qt::UserRole).toString()); - - int nLeafCount = childItem->childCount(); - for(int nLeafIndex(0); nLeafIndexchild(nLeafIndex); - leafShow = m_fileNameList.contains(leafItem->data(0, Qt::UserRole).toString()); - leafItem->setHidden(!leafShow); - if(leafShow) - { - childShow = true; - } - } - childItem->setHidden(!childShow); - if(childShow) - { - topShow = true; - } - } - topItem->setHidden(!topShow); - } -} - -void CAccidentReviewDialog::slotConfirm() -{ - if(m_treeWidget->currentItem() == NULL) - { - QMessageBox::information(this, tr("提示"), tr("请选择一张画面!"), QMessageBox::Ok); - return; - } - QString data = m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); - if(data.isEmpty() || !m_fileNameList.contains(data)) - { - QMessageBox::information(this, tr("提示"), tr("请选择其他画面!"), QMessageBox::Ok); - return; - } - accept(); -} - -void CAccidentReviewDialog::slotCancel() -{ - reject(); -} - -void CAccidentReviewDialog::addChildLevelItem(QTreeWidgetItem *item, const QPair &node, - const QMap > > &navMap) -{ - const QList > childList = navMap.value(node.first); - for(int nIndex=0; nIndexaddChild(childItem); - - addChildLevelItem(childItem, childList[nIndex], navMap); - } -} - -QTreeWidgetItem *CAccidentReviewDialog::getAddLevelItem(const ST_NODE &st_node) -{ - if(st_node.used == Disable) - { - return NULL; - } - - QTreeWidgetItem * childItem = new QTreeWidgetItem(); - childItem->setData(0, Qt::DisplayRole, st_node.name); - childItem->setData(0, Qt::UserRole, st_node.data); - return childItem; -} - -void CAccidentReviewDialog::readNavJson(const QString &path, QMap > > &map) -{ - QFile file(path); - QByteArray readJson; - if(file.open(QIODevice::ReadOnly)) - { - readJson = file.readAll(); - file.close(); - } - QJsonParseError readError; - QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); - if(readError.error != QJsonParseError::NoError) - { - LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); - return; - } - QJsonObject root = readJsonResponse.object(); - if(root.contains("items")) - { - QJsonArray itemArray = root.value("items").toArray(); - int nItemNumber = 0; - for(int nIndex(0); nIndex< itemArray.size(); nIndex++) - { - ST_NODE st_Node_Top; - QJsonObject topLevelObject = itemArray[nIndex].toObject(); - makeStButton(st_Node_Top, topLevelObject); - QPair topMap; - int nTopNumber = nItemNumber; - topMap.first = nItemNumber++; - topMap.second = st_Node_Top; - - QJsonArray childArray = topLevelObject.value("items").toArray(); - for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) - { - ST_NODE st_Node_Child; - QJsonObject childLevelObject = childArray[nChildIndex].toObject(); - makeStButton(st_Node_Child, childLevelObject); - QPair childMap; - int nChildNumber = nItemNumber; - childMap.first = nItemNumber++; - childMap.second = st_Node_Child; - - QJsonArray leafArray = childLevelObject.value("items").toArray(); - for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) - { - ST_NODE st_Node_Leaf; - QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); - makeStButton(st_Node_Leaf, leafLevelObject); - QPair leafMap; - leafMap.first = nItemNumber++; - leafMap.second = st_Node_Leaf; - map[nChildNumber].append(leafMap); - } - map[nTopNumber].append(childMap); - } - map[-1].append(topMap); - } - } -} - -void CAccidentReviewDialog::makeStButton(ST_NODE &st_Node, const QJsonObject &object) -{ - if(!object.value("name").isUndefined()) - { - st_Node.name = object.value("name").toString(); - } - if(!object.value("icon").isUndefined()) - { - st_Node.icon = object.value("icon").toString(); - } - if(!object.value("data").isUndefined()) - { - st_Node.data = object.value("data").toString(); - } - if(!object.value("opt").isUndefined()) - { - st_Node.type = object.value("opt").toInt(); - } - if(!object.value("used").isUndefined()) - { - st_Node.used = object.value("used").toInt(); - } - if(!object.value("web").isUndefined()) - { - st_Node.web = object.value("web").toInt(); - } - if(!object.value("webData").isUndefined()) - { - st_Node.webData = object.value("webData").toString(); - } -} +#include "CAccidentReviewDialog.h" +#include "public/pub_utility_api/FileUtil.h" +#include "public/pub_logger_api/logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CAccidentReviewDialog::CAccidentReviewDialog(const QString &path, QWidget *parent) + : QDialog(parent) +{ + resize(350,450); + getFilterNames(path); + initView(); + initTree(); +} + +CAccidentReviewDialog::~CAccidentReviewDialog() +{ + +} + +QString CAccidentReviewDialog::getCurrentGraph() +{ + if(m_treeWidget->currentItem()) + { + return m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); + } + return QString(); +} + +void CAccidentReviewDialog::initView() +{ + setWindowTitle(tr("事故追忆")); + m_treeWidget = new QTreeWidget(this); + m_treeWidget->headerItem()->setHidden(true); + + QSpacerItem * spacer = new QSpacerItem(10, 0, QSizePolicy::Preferred); + m_confirmBtn = new QPushButton(tr("确认"), this); + m_cancelBtn = new QPushButton(tr("取消"), this); + connect(m_confirmBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotConfirm); + connect(m_cancelBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotCancel); + + QGridLayout * layout = new QGridLayout(); + layout->addWidget(m_treeWidget, 0, 0, 1, 3); + layout->addItem(spacer, 1, 0); + layout->addWidget(m_confirmBtn, 1, 1); + layout->addWidget(m_cancelBtn, 1, 2); + setLayout(layout); +} + +void CAccidentReviewDialog::initTree() +{ + QMap>> m_mapNav; + readNavJson(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + + QString("../../data/model/NavigationWidget.json"), m_mapNav); + QList> nodeList = m_mapNav.value(-1); + for(int nIndex=0; nIndexaddTopLevelItem(item); + + addChildLevelItem(item, nodeList[nIndex], m_mapNav); + } + treeFilter(); + m_treeWidget->expandAll(); +} + +void CAccidentReviewDialog::getFilterNames(const QString &path) +{ + QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + + QString("../../data/pic/"); + m_fileNameList = getAllFile(filePath, filePath, path); +} + +QStringList CAccidentReviewDialog::getAllFile(const QString &path, const QString &relativePath, const QString &filter) +{ + QDir dir(path); + QDir relativeDir(relativePath); + QStringList allFile; + + QString fileName; + QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoSymLinks); + for(QFileInfo &file : fileList) + { + fileName = relativeDir.relativeFilePath(file.filePath()); + if(fileName.contains(filter)) + { + allFile.append(fileName); + } + } + + QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for(QFileInfo &folder : folderList) + { + allFile.append(getAllFile(folder.absoluteFilePath(), relativePath, filter)); + } + + return allFile; +} + +void CAccidentReviewDialog::treeFilter() +{ + bool topShow,childShow,leafShow; + int nTopCount = m_treeWidget->topLevelItemCount(); + for(int nTopIndex(0); nTopIndextopLevelItem(nTopIndex); + topShow = m_fileNameList.contains(topItem->data(0, Qt::UserRole).toString()); + + int nChildCount = topItem->childCount(); + for(int nChildIndex(0); nChildIndexchild(nChildIndex); + childShow = m_fileNameList.contains(childItem->data(0, Qt::UserRole).toString()); + + int nLeafCount = childItem->childCount(); + for(int nLeafIndex(0); nLeafIndexchild(nLeafIndex); + leafShow = m_fileNameList.contains(leafItem->data(0, Qt::UserRole).toString()); + leafItem->setHidden(!leafShow); + if(leafShow) + { + childShow = true; + } + } + childItem->setHidden(!childShow); + if(childShow) + { + topShow = true; + } + } + topItem->setHidden(!topShow); + } +} + +void CAccidentReviewDialog::slotConfirm() +{ + if(m_treeWidget->currentItem() == NULL) + { + QMessageBox::information(this, tr("提示"), tr("请选择一张画面!"), QMessageBox::Ok); + return; + } + QString data = m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); + if(data.isEmpty() || !m_fileNameList.contains(data)) + { + QMessageBox::information(this, tr("提示"), tr("请选择其他画面!"), QMessageBox::Ok); + return; + } + accept(); +} + +void CAccidentReviewDialog::slotCancel() +{ + reject(); +} + +void CAccidentReviewDialog::addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap) +{ + const QList > childList = navMap.value(node.first); + for(int nIndex=0; nIndexaddChild(childItem); + + addChildLevelItem(childItem, childList[nIndex], navMap); + } +} + +QTreeWidgetItem *CAccidentReviewDialog::getAddLevelItem(const ST_NODE &st_node) +{ + if(st_node.used == Disable) + { + return NULL; + } + + QTreeWidgetItem * childItem = new QTreeWidgetItem(); + childItem->setData(0, Qt::DisplayRole, st_node.name); + childItem->setData(0, Qt::UserRole, st_node.data); + return childItem; +} + +void CAccidentReviewDialog::readNavJson(const QString &path, QMap > > &map) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + if(root.contains("items")) + { + QJsonArray itemArray = root.value("items").toArray(); + int nItemNumber = 0; + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + ST_NODE st_Node_Top; + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + makeStButton(st_Node_Top, topLevelObject); + QPair topMap; + int nTopNumber = nItemNumber; + topMap.first = nItemNumber++; + topMap.second = st_Node_Top; + + QJsonArray childArray = topLevelObject.value("items").toArray(); + for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) + { + ST_NODE st_Node_Child; + QJsonObject childLevelObject = childArray[nChildIndex].toObject(); + makeStButton(st_Node_Child, childLevelObject); + QPair childMap; + int nChildNumber = nItemNumber; + childMap.first = nItemNumber++; + childMap.second = st_Node_Child; + + QJsonArray leafArray = childLevelObject.value("items").toArray(); + for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) + { + ST_NODE st_Node_Leaf; + QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); + makeStButton(st_Node_Leaf, leafLevelObject); + QPair leafMap; + leafMap.first = nItemNumber++; + leafMap.second = st_Node_Leaf; + map[nChildNumber].append(leafMap); + } + map[nTopNumber].append(childMap); + } + map[-1].append(topMap); + } + } +} + +void CAccidentReviewDialog::makeStButton(ST_NODE &st_Node, const QJsonObject &object) +{ + if(!object.value("name").isUndefined()) + { + st_Node.name = object.value("name").toString(); + } + if(!object.value("icon").isUndefined()) + { + st_Node.icon = object.value("icon").toString(); + } + if(!object.value("data").isUndefined()) + { + st_Node.data = object.value("data").toString(); + } + if(!object.value("opt").isUndefined()) + { + st_Node.type = object.value("opt").toInt(); + } + if(!object.value("used").isUndefined()) + { + st_Node.used = object.value("used").toInt(); + } + if(!object.value("web").isUndefined()) + { + st_Node.web = object.value("web").toInt(); + } + if(!object.value("webData").isUndefined()) + { + st_Node.webData = object.value("webData").toString(); + } +} diff --git a/product/src/gui/plugin/EventWidget/CAccidentReviewDialog.h b/product/src/gui/plugin/EventWidget/CAccidentReviewDialog.h index a2d69b28..080fb279 100644 --- a/product/src/gui/plugin/EventWidget/CAccidentReviewDialog.h +++ b/product/src/gui/plugin/EventWidget/CAccidentReviewDialog.h @@ -1,56 +1,56 @@ -#ifndef CACCIDENTREVIEWDIALOG_H -#define CACCIDENTREVIEWDIALOG_H - -#include -#include -#include - -struct ST_NODE -{ - QString name; - int used; - int type; - QString icon; - int web; - QString data; - QString webData; -}; - -class QTreeWidget; -class QTreeWidgetItem; -class CAccidentReviewDialog : public QDialog -{ - Q_OBJECT -public: - enum Node_Enable{Enable = 1,Disable = 2}; - CAccidentReviewDialog(const QString &path, QWidget *parent = Q_NULLPTR); - ~CAccidentReviewDialog(); - - QString getCurrentGraph(); - -private slots: - void slotConfirm(); - void slotCancel(); - -private: - void initView(); - void initTree(); - void getFilterNames(const QString &path); - QStringList getAllFile(const QString &path, const QString &relativePath, - const QString &filter); - void treeFilter(); - - void addChildLevelItem(QTreeWidgetItem *item, const QPair &node, - const QMap > > &navMap); - QTreeWidgetItem* getAddLevelItem(const ST_NODE& st_node); - void readNavJson(const QString &path, QMap>>& map); - void makeStButton(ST_NODE &st_Node, const QJsonObject &object); - -private: - QTreeWidget * m_treeWidget; - QPushButton * m_confirmBtn; - QPushButton * m_cancelBtn; - QStringList m_fileNameList; -}; - -#endif // CACCIDENTREVIEWDIALOG_H +#ifndef CACCIDENTREVIEWDIALOG_H +#define CACCIDENTREVIEWDIALOG_H + +#include +#include +#include + +struct ST_NODE +{ + QString name; + int used; + int type; + QString icon; + int web; + QString data; + QString webData; +}; + +class QTreeWidget; +class QTreeWidgetItem; +class CAccidentReviewDialog : public QDialog +{ + Q_OBJECT +public: + enum Node_Enable{Enable = 1,Disable = 2}; + CAccidentReviewDialog(const QString &path, QWidget *parent = Q_NULLPTR); + ~CAccidentReviewDialog(); + + QString getCurrentGraph(); + +private slots: + void slotConfirm(); + void slotCancel(); + +private: + void initView(); + void initTree(); + void getFilterNames(const QString &path); + QStringList getAllFile(const QString &path, const QString &relativePath, + const QString &filter); + void treeFilter(); + + void addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap); + QTreeWidgetItem* getAddLevelItem(const ST_NODE& st_node); + void readNavJson(const QString &path, QMap>>& map); + void makeStButton(ST_NODE &st_Node, const QJsonObject &object); + +private: + QTreeWidget * m_treeWidget; + QPushButton * m_confirmBtn; + QPushButton * m_cancelBtn; + QStringList m_fileNameList; +}; + +#endif // CACCIDENTREVIEWDIALOG_H diff --git a/product/src/gui/plugin/EventWidget/CEventDataCollect.cpp b/product/src/gui/plugin/EventWidget/CEventDataCollect.cpp index 46c53931..e646fc7b 100644 --- a/product/src/gui/plugin/EventWidget/CEventDataCollect.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDataCollect.cpp @@ -1,787 +1,787 @@ -#include "CEventDataCollect.h" -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" -#include "CEventMsgManage.h" - -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" -#include "Common.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CharUtil.h" -using namespace std; -using namespace kbd_public; -CEventDataCollect * CEventDataCollect::m_pInstance = NULL; - -CEventDataCollect * CEventDataCollect::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CEventDataCollect(); - } - return m_pInstance; -} - -CEventDataCollect::CEventDataCollect() - : m_pTimer(NULL) -{ - msgMutex = new QMutex(); - - m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); - m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_pTimer = new QTimer(); - m_pTimer->setInterval(1000); - connect(m_pTimer, &QTimer::timeout, this, &CEventDataCollect::slotUpdateEvent); - - initialize(); -} - -int CEventDataCollect::queryPriorityOrder(int &id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); - kbd_dbms::CVarType value; - m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); - return value.toInt(); -} - -CEventDataCollect::~CEventDataCollect() -{ - if(m_pTimer != NULL) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - suspendThread(); - - m_priorityOrderMap.clear(); - m_priorityDescriptionMap.clear(); - m_locationDescriptionMap.clear(); - m_regionInfoDescriptionMap.clear(); - m_alarmTypeDescriptionMap.clear(); - m_deviceTypeDescriptionMap.clear(); - m_subSystemDescriptionMap.clear(); - m_locationOrderList.clear(); - - delete msgMutex; - delete m_rtdbAccess; - m_pInstance = NULL; -} - -bool CEventDataCollect::initialize() -{ - m_pTimer->start(); - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - kbd_public::SNodeInfo stNodeInfo; - spSysInfo->getLocalNodeInfo(stNodeInfo); - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); - m_nLocationID = stNodeInfo.nLocationId; - } - loadEventConfig(); - return resumeThread(); -} - -void CEventDataCollect::release() -{ - m_pTimer->stop(); - suspendThread(true); - m_priorityOrderMap.clear(); - m_priorityDescriptionMap.clear(); - m_locationDescriptionMap.clear(); - m_regionInfoDescriptionMap.clear(); - m_alarmTypeDescriptionMap.clear(); - m_deviceTypeDescriptionMap.clear(); - m_subSystemDescriptionMap.clear(); - m_areaInfoMap.clear(); - m_areaLocMap.clear(); - m_locationOrderList.clear(); - - CEventMsgManage::instance()->clearRTMsg(); -} - -void CEventDataCollect::loadEventConfig() -{ - loadPermInfo(); - loadPriorityDescription(); - loadLocationDescription(); - loadRegionInfoDescription(); - loadAlarmTypeDescription(); - loadDeviceTypeDescription(); - loadAlarmStatusDescription(); - loadEventShowStatusDescription(); - loadEventOtherStatusDescription(); - loadUserName(); - loadDeviceGroupDescription(); - loadSubSystemDescription(); -} - -int CEventDataCollect::priorityId(const QString &description) -{ - return m_priorityDescriptionMap.key(description, -1); -} - -int CEventDataCollect::locationId(const QString &description) -{ - return m_locationDescriptionMap.key(description, -1); -} - -int CEventDataCollect::regionId(const QString &description) -{ - return m_regionInfoDescriptionMap.key(description, -1); -} - -int CEventDataCollect::alarmTypeId(const QString &description) -{ - return m_alarmTypeDescriptionMap.key(description, -1); -} - -int CEventDataCollect::eventStatusId(const QString &description) -{ - return m_eventShowStatusMap.key(description, -1); -} - -int CEventDataCollect::deviceTypeId(const QString &description) -{ - return m_deviceTypeDescriptionMap.key(description, -1); -} - -QString CEventDataCollect::priorityDescription(const int &id) -{ - return m_priorityDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::locationDescription(const int &id) -{ - return m_locationDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::regionDescription(const int &id) -{ - return m_regionInfoDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::alarmTypeDescription(const int &id) -{ - return m_alarmTypeDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::deviceTypeDescription(const int &id) -{ - return m_deviceTypeDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::deviceGroupDescription(const QString &id) -{ - return m_deviceGroupDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::alarmStatusDescription(const int &id) -{ - return m_alarmStatusMap.value(id, QString()); -} - -QString CEventDataCollect::userNameDescription(const int &id) -{ - return m_userNameMap.value(id, QString()); -} - -QString CEventDataCollect::eventShowStatusDescription(const int &id) -{ - return m_eventShowStatusMap.value(id, QString()); -} - -QString CEventDataCollect::subSystemDescription(const int &id) -{ - return m_subSystemDescriptionMap.value(id, QString()); -} - -QList CEventDataCollect::priorityList() -{ - return m_priorityDescriptionMap.keys(); -} - -QList CEventDataCollect::locationList() -{ - return m_listPermLocationId; -} - -QList CEventDataCollect::regionList() -{ - return m_listPermRegionId; -} - -QList CEventDataCollect::alarmTypeList() -{ - return m_alarmTypeDescriptionMap.keys(); -} - -QList CEventDataCollect::alarmStatusList() -{ - return m_eventShowStatusMap.keys(); -} - -QList CEventDataCollect::alarmOtherList() -{ - return m_eventOtherStatusMap.keys(); -} - -QMap CEventDataCollect::areaInfoMap() -{ - return m_areaInfoMap; -} - -QMap > CEventDataCollect::areaLocMap() -{ - return m_areaLocMap; -} - -QList CEventDataCollect::locationOrderList() -{ - return m_locationOrderList; -} - -QList CEventDataCollect::getDevGroupTagList() -{ - return m_deviceGroupDescriptionMap.keys(); -} - -void CEventDataCollect::loadPermInfo() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecRegionId; - std::vector vecLocationId; - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - m_listPermLocationId.append(*location++); - } - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - m_listPermRegionId.append(*region++); - } - } - } -} - -void CEventDataCollect::loadPriorityDescription() -{ - m_priorityDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "alarm_level_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("priority_id"); - columns.push_back("priority_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CEventDataCollect::loadSubSystemDescription() -{ - m_subSystemDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "sys_model_sub_system_info")) - { - LOGERROR("open sys_model_sub_system_info success"); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("sub_system_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - LOGERROR("select columns success"); - LOGERROR(QString::number( result.getRecordCount()).toStdString().c_str()); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_subSystemDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - - } - } - } -} - -void CEventDataCollect::loadLocationDescription() -{ - m_areaInfoMap.clear(); - m_areaLocMap.clear(); - if(m_rtdbAccess->open("base", "sys_model_location_info")) - { - m_locationDescriptionMap.clear(); - m_locationOrderList.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("location_id"); - columns.push_back("tag_name"); - columns.push_back("description"); - columns.push_back("location_type"); - columns.push_back("plocation_id"); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType area_id; - kbd_dbms::CVarType tag_name; - kbd_dbms::CVarType description; - kbd_dbms::CVarType area_type; - kbd_dbms::CVarType parea_id; - result.getColumnValue(nIndex, 0, area_id); - result.getColumnValue(nIndex, 1, tag_name); - result.getColumnValue(nIndex, 2, description); - result.getColumnValue(nIndex, 3, area_type); - result.getColumnValue(nIndex, 4, parea_id); - SAreaInfo info; - info.nId =area_id.toInt(); - info.stTag =QString::fromStdString(tag_name.toStdString()); - info.stDes =QString::fromStdString(description.toStdString()); - if(area_type.toInt() != (int)E_LOCATION_NODE) - { - info.eType = E_LOCATION_AREA; - }else - { - info.eType = E_LOCATION_NODE; - } - info.nPareaId =parea_id.toInt(); - m_areaInfoMap[info.nId] = info; - if(m_listPermLocationId.contains(info.nId)) - { - m_locationOrderList.push_back(info.nId); - m_locationDescriptionMap[info.nId] = info.stDes; - } - } - } - } - QMap::iterator it= m_areaInfoMap.begin(); - while (it != m_areaInfoMap.end()) { - if(m_listPermLocationId.contains(it.key())) - { - if(it.value().eType == (int)E_LOCATION_NODE) - { - QMap >::iterator pos = m_areaLocMap.find(it.value().nPareaId); - if(pos == m_areaLocMap.end()) - { - QVector locVec; - locVec.append(it.value().nId); - m_areaLocMap.insert(it.value().nPareaId,locVec); - }else - { - QVector &locVec = pos.value(); - locVec.append(it.value().nId); - } - }else - { - QMap >::iterator pos = m_areaLocMap.find(it.key()); - if(pos == m_areaLocMap.end()) - { - QVector locVec; - locVec.append(it.value().nId); - m_areaLocMap.insert(it.key(),locVec); - }else - { - QVector &locVec = pos.value(); - locVec.append(it.value().nId); - } - } - - } - it++; - } -} - -void CEventDataCollect::loadRegionInfoDescription() -{ - m_regionInfoDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "region_info")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("region_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - if(m_listPermRegionId.contains(key.toInt())) - { - m_regionInfoDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - } -} - -void CEventDataCollect::loadAlarmTypeDescription() -{ - m_alarmTypeDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "alarm_type_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("type_id"); - columns.push_back("type_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CEventDataCollect::loadDeviceTypeDescription() -{ - m_deviceTypeDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "dev_type_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("dev_type_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CEventDataCollect::loadAlarmStatusDescription() -{ - m_alarmStatusMap.clear(); - if(m_rtdbAccess->open("base", "alarm_status_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("status_value"); - columns.push_back("display_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmStatusMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CEventDataCollect::loadUserName() -{ - m_userNameMap.clear(); - if(m_rtdbAccess->open("base", "rm_user_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("perm_id"); - columns.push_back("perm_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_userNameMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CEventDataCollect::loadEventShowStatusDescription() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - if(StringToInt(strKey) != OTHERSTATUS) - { - m_eventShowStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; - }else - { - m_eventShowStatusMap[StringToInt(strKey)] = tr("其他"); - } - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -void CEventDataCollect::loadEventOtherStatusDescription() -{ - m_eventOtherStatusMap.clear(); - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - m_eventOtherStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -void CEventDataCollect::loadDeviceGroupDescription() -{ - if(m_rtdbAccess->open("base", "dev_group")) - { - m_deviceGroupDescriptionMap.clear(); - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("tag_name"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); - } - } - } -} - -QMap CEventDataCollect::priorityDescriptionMap() -{ - return m_priorityDescriptionMap; -} - -QMap CEventDataCollect::locationDescriptionMap() -{ - return m_locationDescriptionMap; -} - -QMap CEventDataCollect::regionInfoDescriptionMap() -{ - return m_regionInfoDescriptionMap; -} - -QMap CEventDataCollect::alarmTypeDescriptionMap() -{ - return m_alarmTypeDescriptionMap; -} - -QMap CEventDataCollect::deviceTypeDescriptionMap() -{ - return m_deviceTypeDescriptionMap; -} - -QMap CEventDataCollect::alarmStatusMap() -{ - return m_alarmStatusMap; -} - -QMap CEventDataCollect::userNameMap() -{ - return m_userNameMap; -} - -QMap CEventDataCollect::eventShowStatusDescriptionMap() -{ - return m_eventShowStatusMap; -} - -QMap CEventDataCollect::eventOtherStatusDescriptionMap() -{ - return m_eventOtherStatusMap; -} - -void CEventDataCollect::slotUpdateEvent() -{ - //loadEventConfig(); - - QMutexLocker locker(msgMutex); - - if(!m_listEventCache.isEmpty()) - { - emit sigMsgArrived(m_listEventCache); - m_listEventCache.clear(); - } - emit sigDevTreeUpdate(); -} - -void CEventDataCollect::handleAllEvtMsg(int nDomainID, kbd_idlfile::SEvtCltAddEvt &objAllEvt) -{ - QMutexLocker locker(msgMutex); - LOGINFO("-------------------------handleAllEvtMsg-------------------------"); - CEventMsgManage::instance()->removeEventMsgByDomainID(nDomainID); - removeCache(nDomainID); - for(int nAddMsgIndex(0); nAddMsgIndex < objAllEvt.evt_info_size(); nAddMsgIndex++) - { - kbd_idlfile::SEvtInfoToEvtClt msg = objAllEvt.evt_info(nAddMsgIndex); - EventMsgPtr event(new CEventMsgInfo()); - event->initialize(msg); - event->priorityOrder = queryPriorityOrder(event->priority); - if(!m_listPermLocationId.contains(event->location_id)) - { - continue; - } - if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) - { - continue; - } - CEventMsgManage::instance()->addEventMsg(event); - } - emit sigMsgRefresh(); - emit sigEventStateChanged(); - emit sigDevTreeUpdate(); -} - -void CEventDataCollect::handleAddEvtMsg(kbd_idlfile::SEvtCltAddEvt &objAddEvt) -{ - QMutexLocker locker(msgMutex); - LOGINFO("-------------------------handleAddEvtMsg-------------------------"); - for(int nAddMsgIndex(0); nAddMsgIndex < objAddEvt.evt_info_size(); nAddMsgIndex++) - { - kbd_idlfile::SEvtInfoToEvtClt msg = objAddEvt.evt_info(nAddMsgIndex); - EventMsgPtr event(new CEventMsgInfo()); - event->initialize(msg); - event->priorityOrder = queryPriorityOrder(event->priority); - if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) - { - continue; - } - CEventMsgManage::instance()->addEventMsg(event); - m_listEventCache.append(event); - } - emit sigEventStateChanged(); -} - -void CEventDataCollect::handleLinkWave2EvtMsg(kbd_idlfile::SAlmCltLinkWave2Alm &objWave2Evt) -{ - QMutexLocker locker(msgMutex); - QList uuidList; - LOGINFO("-------------------------handleAddEvtMsg-------------------------"); - QString waveFile = QString::fromStdString(objWave2Evt.wave_file()); - for(int nAddMsgIndex(0); nAddMsgIndex < objWave2Evt.uuid_base64_size(); nAddMsgIndex++) - { - QString uuid = QString::fromStdString(objWave2Evt.uuid_base64(nAddMsgIndex)); - uuidList.append(uuid); - } - CEventMsgManage::instance()->linkWave2EvtMsg(uuidList,waveFile); -} - -void CEventDataCollect::handleClearRTEvent() -{ - QMutexLocker locker(msgMutex); - CEventMsgManage::instance()->clearRTMsg(); - emit sigMsgRefresh(); - emit sigEventStateChanged(); -} - -void CEventDataCollect::removeCache(int nDomain) -{ - QList::iterator it = m_listEventCache.begin(); - while (it != m_listEventCache.end()) - { - if(nDomain == (*it)->domain_id) - { - it = m_listEventCache.erase(it); - continue; - } - it++; - } -} +#include "CEventDataCollect.h" +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "CEventMsgManage.h" + +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +using namespace std; +using namespace kbd_public; +CEventDataCollect * CEventDataCollect::m_pInstance = NULL; + +CEventDataCollect * CEventDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CEventDataCollect(); + } + return m_pInstance; +} + +CEventDataCollect::CEventDataCollect() + : m_pTimer(NULL) +{ + msgMutex = new QMutex(); + + m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_pTimer = new QTimer(); + m_pTimer->setInterval(1000); + connect(m_pTimer, &QTimer::timeout, this, &CEventDataCollect::slotUpdateEvent); + + initialize(); +} + +int CEventDataCollect::queryPriorityOrder(int &id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + kbd_dbms::CVarType value; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +CEventDataCollect::~CEventDataCollect() +{ + if(m_pTimer != NULL) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + suspendThread(); + + m_priorityOrderMap.clear(); + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionInfoDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + m_deviceTypeDescriptionMap.clear(); + m_subSystemDescriptionMap.clear(); + m_locationOrderList.clear(); + + delete msgMutex; + delete m_rtdbAccess; + m_pInstance = NULL; +} + +bool CEventDataCollect::initialize() +{ + m_pTimer->start(); + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + kbd_public::SNodeInfo stNodeInfo; + spSysInfo->getLocalNodeInfo(stNodeInfo); + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); + m_nLocationID = stNodeInfo.nLocationId; + } + loadEventConfig(); + return resumeThread(); +} + +void CEventDataCollect::release() +{ + m_pTimer->stop(); + suspendThread(true); + m_priorityOrderMap.clear(); + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionInfoDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + m_deviceTypeDescriptionMap.clear(); + m_subSystemDescriptionMap.clear(); + m_areaInfoMap.clear(); + m_areaLocMap.clear(); + m_locationOrderList.clear(); + + CEventMsgManage::instance()->clearRTMsg(); +} + +void CEventDataCollect::loadEventConfig() +{ + loadPermInfo(); + loadPriorityDescription(); + loadLocationDescription(); + loadRegionInfoDescription(); + loadAlarmTypeDescription(); + loadDeviceTypeDescription(); + loadAlarmStatusDescription(); + loadEventShowStatusDescription(); + loadEventOtherStatusDescription(); + loadUserName(); + loadDeviceGroupDescription(); + loadSubSystemDescription(); +} + +int CEventDataCollect::priorityId(const QString &description) +{ + return m_priorityDescriptionMap.key(description, -1); +} + +int CEventDataCollect::locationId(const QString &description) +{ + return m_locationDescriptionMap.key(description, -1); +} + +int CEventDataCollect::regionId(const QString &description) +{ + return m_regionInfoDescriptionMap.key(description, -1); +} + +int CEventDataCollect::alarmTypeId(const QString &description) +{ + return m_alarmTypeDescriptionMap.key(description, -1); +} + +int CEventDataCollect::eventStatusId(const QString &description) +{ + return m_eventShowStatusMap.key(description, -1); +} + +int CEventDataCollect::deviceTypeId(const QString &description) +{ + return m_deviceTypeDescriptionMap.key(description, -1); +} + +QString CEventDataCollect::priorityDescription(const int &id) +{ + return m_priorityDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::locationDescription(const int &id) +{ + return m_locationDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::regionDescription(const int &id) +{ + return m_regionInfoDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::alarmTypeDescription(const int &id) +{ + return m_alarmTypeDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::deviceTypeDescription(const int &id) +{ + return m_deviceTypeDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::deviceGroupDescription(const QString &id) +{ + return m_deviceGroupDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::alarmStatusDescription(const int &id) +{ + return m_alarmStatusMap.value(id, QString()); +} + +QString CEventDataCollect::userNameDescription(const int &id) +{ + return m_userNameMap.value(id, QString()); +} + +QString CEventDataCollect::eventShowStatusDescription(const int &id) +{ + return m_eventShowStatusMap.value(id, QString()); +} + +QString CEventDataCollect::subSystemDescription(const int &id) +{ + return m_subSystemDescriptionMap.value(id, QString()); +} + +QList CEventDataCollect::priorityList() +{ + return m_priorityDescriptionMap.keys(); +} + +QList CEventDataCollect::locationList() +{ + return m_listPermLocationId; +} + +QList CEventDataCollect::regionList() +{ + return m_listPermRegionId; +} + +QList CEventDataCollect::alarmTypeList() +{ + return m_alarmTypeDescriptionMap.keys(); +} + +QList CEventDataCollect::alarmStatusList() +{ + return m_eventShowStatusMap.keys(); +} + +QList CEventDataCollect::alarmOtherList() +{ + return m_eventOtherStatusMap.keys(); +} + +QMap CEventDataCollect::areaInfoMap() +{ + return m_areaInfoMap; +} + +QMap > CEventDataCollect::areaLocMap() +{ + return m_areaLocMap; +} + +QList CEventDataCollect::locationOrderList() +{ + return m_locationOrderList; +} + +QList CEventDataCollect::getDevGroupTagList() +{ + return m_deviceGroupDescriptionMap.keys(); +} + +void CEventDataCollect::loadPermInfo() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecRegionId; + std::vector vecLocationId; + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listPermLocationId.append(*location++); + } + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listPermRegionId.append(*region++); + } + } + } +} + +void CEventDataCollect::loadPriorityDescription() +{ + m_priorityDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "alarm_level_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("priority_id"); + columns.push_back("priority_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadSubSystemDescription() +{ + m_subSystemDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "sys_model_sub_system_info")) + { + LOGERROR("open sys_model_sub_system_info success"); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("sub_system_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + LOGERROR("select columns success"); + LOGERROR(QString::number( result.getRecordCount()).toStdString().c_str()); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_subSystemDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + + } + } + } +} + +void CEventDataCollect::loadLocationDescription() +{ + m_areaInfoMap.clear(); + m_areaLocMap.clear(); + if(m_rtdbAccess->open("base", "sys_model_location_info")) + { + m_locationDescriptionMap.clear(); + m_locationOrderList.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("tag_name"); + columns.push_back("description"); + columns.push_back("location_type"); + columns.push_back("plocation_id"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType area_id; + kbd_dbms::CVarType tag_name; + kbd_dbms::CVarType description; + kbd_dbms::CVarType area_type; + kbd_dbms::CVarType parea_id; + result.getColumnValue(nIndex, 0, area_id); + result.getColumnValue(nIndex, 1, tag_name); + result.getColumnValue(nIndex, 2, description); + result.getColumnValue(nIndex, 3, area_type); + result.getColumnValue(nIndex, 4, parea_id); + SAreaInfo info; + info.nId =area_id.toInt(); + info.stTag =QString::fromStdString(tag_name.toStdString()); + info.stDes =QString::fromStdString(description.toStdString()); + if(area_type.toInt() != (int)E_LOCATION_NODE) + { + info.eType = E_LOCATION_AREA; + }else + { + info.eType = E_LOCATION_NODE; + } + info.nPareaId =parea_id.toInt(); + m_areaInfoMap[info.nId] = info; + if(m_listPermLocationId.contains(info.nId)) + { + m_locationOrderList.push_back(info.nId); + m_locationDescriptionMap[info.nId] = info.stDes; + } + } + } + } + QMap::iterator it= m_areaInfoMap.begin(); + while (it != m_areaInfoMap.end()) { + if(m_listPermLocationId.contains(it.key())) + { + if(it.value().eType == (int)E_LOCATION_NODE) + { + QMap >::iterator pos = m_areaLocMap.find(it.value().nPareaId); + if(pos == m_areaLocMap.end()) + { + QVector locVec; + locVec.append(it.value().nId); + m_areaLocMap.insert(it.value().nPareaId,locVec); + }else + { + QVector &locVec = pos.value(); + locVec.append(it.value().nId); + } + }else + { + QMap >::iterator pos = m_areaLocMap.find(it.key()); + if(pos == m_areaLocMap.end()) + { + QVector locVec; + locVec.append(it.value().nId); + m_areaLocMap.insert(it.key(),locVec); + }else + { + QVector &locVec = pos.value(); + locVec.append(it.value().nId); + } + } + + } + it++; + } +} + +void CEventDataCollect::loadRegionInfoDescription() +{ + m_regionInfoDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "region_info")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("region_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + if(m_listPermRegionId.contains(key.toInt())) + { + m_regionInfoDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + } +} + +void CEventDataCollect::loadAlarmTypeDescription() +{ + m_alarmTypeDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "alarm_type_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("type_id"); + columns.push_back("type_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadDeviceTypeDescription() +{ + m_deviceTypeDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "dev_type_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("dev_type_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadAlarmStatusDescription() +{ + m_alarmStatusMap.clear(); + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("status_value"); + columns.push_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadUserName() +{ + m_userNameMap.clear(); + if(m_rtdbAccess->open("base", "rm_user_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_id"); + columns.push_back("perm_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_userNameMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadEventShowStatusDescription() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + if(StringToInt(strKey) != OTHERSTATUS) + { + m_eventShowStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; + }else + { + m_eventShowStatusMap[StringToInt(strKey)] = tr("其他"); + } + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CEventDataCollect::loadEventOtherStatusDescription() +{ + m_eventOtherStatusMap.clear(); + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + m_eventOtherStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CEventDataCollect::loadDeviceGroupDescription() +{ + if(m_rtdbAccess->open("base", "dev_group")) + { + m_deviceGroupDescriptionMap.clear(); + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("tag_name"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); + } + } + } +} + +QMap CEventDataCollect::priorityDescriptionMap() +{ + return m_priorityDescriptionMap; +} + +QMap CEventDataCollect::locationDescriptionMap() +{ + return m_locationDescriptionMap; +} + +QMap CEventDataCollect::regionInfoDescriptionMap() +{ + return m_regionInfoDescriptionMap; +} + +QMap CEventDataCollect::alarmTypeDescriptionMap() +{ + return m_alarmTypeDescriptionMap; +} + +QMap CEventDataCollect::deviceTypeDescriptionMap() +{ + return m_deviceTypeDescriptionMap; +} + +QMap CEventDataCollect::alarmStatusMap() +{ + return m_alarmStatusMap; +} + +QMap CEventDataCollect::userNameMap() +{ + return m_userNameMap; +} + +QMap CEventDataCollect::eventShowStatusDescriptionMap() +{ + return m_eventShowStatusMap; +} + +QMap CEventDataCollect::eventOtherStatusDescriptionMap() +{ + return m_eventOtherStatusMap; +} + +void CEventDataCollect::slotUpdateEvent() +{ + //loadEventConfig(); + + QMutexLocker locker(msgMutex); + + if(!m_listEventCache.isEmpty()) + { + emit sigMsgArrived(m_listEventCache); + m_listEventCache.clear(); + } + emit sigDevTreeUpdate(); +} + +void CEventDataCollect::handleAllEvtMsg(int nDomainID, kbd_idlfile::SEvtCltAddEvt &objAllEvt) +{ + QMutexLocker locker(msgMutex); + LOGINFO("-------------------------handleAllEvtMsg-------------------------"); + CEventMsgManage::instance()->removeEventMsgByDomainID(nDomainID); + removeCache(nDomainID); + for(int nAddMsgIndex(0); nAddMsgIndex < objAllEvt.evt_info_size(); nAddMsgIndex++) + { + kbd_idlfile::SEvtInfoToEvtClt msg = objAllEvt.evt_info(nAddMsgIndex); + EventMsgPtr event(new CEventMsgInfo()); + event->initialize(msg); + event->priorityOrder = queryPriorityOrder(event->priority); + if(!m_listPermLocationId.contains(event->location_id)) + { + continue; + } + if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) + { + continue; + } + CEventMsgManage::instance()->addEventMsg(event); + } + emit sigMsgRefresh(); + emit sigEventStateChanged(); + emit sigDevTreeUpdate(); +} + +void CEventDataCollect::handleAddEvtMsg(kbd_idlfile::SEvtCltAddEvt &objAddEvt) +{ + QMutexLocker locker(msgMutex); + LOGINFO("-------------------------handleAddEvtMsg-------------------------"); + for(int nAddMsgIndex(0); nAddMsgIndex < objAddEvt.evt_info_size(); nAddMsgIndex++) + { + kbd_idlfile::SEvtInfoToEvtClt msg = objAddEvt.evt_info(nAddMsgIndex); + EventMsgPtr event(new CEventMsgInfo()); + event->initialize(msg); + event->priorityOrder = queryPriorityOrder(event->priority); + if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) + { + continue; + } + CEventMsgManage::instance()->addEventMsg(event); + m_listEventCache.append(event); + } + emit sigEventStateChanged(); +} + +void CEventDataCollect::handleLinkWave2EvtMsg(kbd_idlfile::SAlmCltLinkWave2Alm &objWave2Evt) +{ + QMutexLocker locker(msgMutex); + QList uuidList; + LOGINFO("-------------------------handleAddEvtMsg-------------------------"); + QString waveFile = QString::fromStdString(objWave2Evt.wave_file()); + for(int nAddMsgIndex(0); nAddMsgIndex < objWave2Evt.uuid_base64_size(); nAddMsgIndex++) + { + QString uuid = QString::fromStdString(objWave2Evt.uuid_base64(nAddMsgIndex)); + uuidList.append(uuid); + } + CEventMsgManage::instance()->linkWave2EvtMsg(uuidList,waveFile); +} + +void CEventDataCollect::handleClearRTEvent() +{ + QMutexLocker locker(msgMutex); + CEventMsgManage::instance()->clearRTMsg(); + emit sigMsgRefresh(); + emit sigEventStateChanged(); +} + +void CEventDataCollect::removeCache(int nDomain) +{ + QList::iterator it = m_listEventCache.begin(); + while (it != m_listEventCache.end()) + { + if(nDomain == (*it)->domain_id) + { + it = m_listEventCache.erase(it); + continue; + } + it++; + } +} diff --git a/product/src/gui/plugin/EventWidget/CEventDataCollect.h b/product/src/gui/plugin/EventWidget/CEventDataCollect.h index 8d32d24b..95ec9b8e 100644 --- a/product/src/gui/plugin/EventWidget/CEventDataCollect.h +++ b/product/src/gui/plugin/EventWidget/CEventDataCollect.h @@ -1,154 +1,154 @@ -#ifndef CEventDataCollect_H -#define CEventDataCollect_H - -#include -#include -#include -#include "AlarmMessage.pb.h" -#include "CEventMsgInfo.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "dbms/rdb_api/CRdbAccess.h" -#include -#include - -#define FUNC_SPE_EVENT_VIEW ("FUNC_SPE_EVENT_VIEW") - -const int OTHERSTATUS = 9999; -class CEventDataCollect : public QObject, public kbd_service::CAlmApiForEvtClt -{ - Q_OBJECT -public: - static CEventDataCollect * instance(); - - virtual ~CEventDataCollect(); - - bool initialize(); - - void release(); - - void loadEventConfig(); - int priorityId(const QString &description); - int locationId(const QString &description); - int regionId(const QString &description); - int alarmTypeId(const QString &description); - int eventStatusId(const QString &description); - int deviceTypeId(const QString &description); - - QString priorityDescription(const int & id); - QString locationDescription(const int & id); - QString regionDescription(const int & id); - QString alarmTypeDescription(const int & id); - QString deviceTypeDescription(const int & id); - QString deviceGroupDescription(const QString &id); - QString alarmStatusDescription(const int & id); - QString userNameDescription(const int & id); - QString subSystemDescription(const int &id); - QString eventShowStatusDescription(const int & id); - - QList priorityList(); - QList locationList(); - QList regionList(); - QList alarmTypeList(); - QList alarmStatusList(); - QList alarmOtherList(); - QMap areaInfoMap(); - QMap > areaLocMap(); - QList locationOrderList(); - QList getDevGroupTagList(); - - QMap priorityDescriptionMap(); - QMap locationDescriptionMap(); - QMap regionInfoDescriptionMap(); - QMap alarmTypeDescriptionMap(); - QMap deviceTypeDescriptionMap(); - QMap alarmStatusMap(); - QMap userNameMap(); - - QMap eventShowStatusDescriptionMap(); - QMap eventOtherStatusDescriptionMap(); - - virtual void handleAllEvtMsg(int nDomainID, kbd_idlfile::SEvtCltAddEvt &objAllEvt); - - virtual void handleAddEvtMsg(kbd_idlfile::SEvtCltAddEvt &objAddEvt); - - virtual void handleLinkWave2EvtMsg( kbd_idlfile::SAlmCltLinkWave2Alm &objWave2Evt); - - void handleClearRTEvent(); - -signals: - /** - * @brief sigMsgRefresh 在handleAllAlmMsg时触发,通知model重新拉取报警消息 - */ - void sigMsgRefresh(); - - /** - * @brief sigMsgArrived 在handleAddAlmMsg时触发,通知model新报警消息到达 - */ - void sigMsgArrived(QList listEvents); - - /** - * @brief sigEventStateChanged 事件数量或状态改变时触发。 - */ - void sigEventStateChanged(); - - /** - * @brief sigDevTreeUpdate 通知设备树更新设备组事件数 - */ - void sigDevTreeUpdate(); - -public slots: - //void queryHistoryEvent(const QStringList &tables, QList typeFilter, const QString &condition); - void slotUpdateEvent(); - -private: - CEventDataCollect(); - int queryPriorityOrder(int &id); - void removeCache(int nDomain); - - void loadPermInfo(); - void loadPriorityDescription(); - void loadLocationDescription(); - void loadRegionInfoDescription(); - void loadAlarmTypeDescription(); - void loadDeviceTypeDescription(); - void loadAlarmStatusDescription(); - void loadUserName(); - void loadSubSystemDescription(); - void loadEventShowStatusDescription(); - void loadEventOtherStatusDescription(); - - void loadDeviceGroupDescription(); - -private: - QMutex * msgMutex; - QTimer * m_pTimer; - int m_nLocationID; - QList m_listEventCache; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; - QList m_listPermLocationId; - QList m_listPermRegionId; - QMap m_priorityOrderMap; - QMap m_priorityDescriptionMap; - QMap m_locationDescriptionMap; - QMap m_regionInfoDescriptionMap; - QMap m_alarmTypeDescriptionMap; - QMap m_deviceTypeDescriptionMap; - QMap m_subSystemDescriptionMap; - QMap m_alarmStatusMap; - QMap m_userNameMap; - QMap m_DescriptionMap; - static CEventDataCollect * m_pInstance; - - QMap m_eventShowStatusMap; // - QMap m_eventOtherStatusMap; //其他报警状态 - - - QMap m_areaInfoMap; //区域信息 - QMap > m_areaLocMap; //区域映射 - - QList m_locationOrderList; //< location_id: 按location_no排序 - QMap m_deviceGroupDescriptionMap; -}; - -#endif // CEventDataCollect_H +#ifndef CEventDataCollect_H +#define CEventDataCollect_H + +#include +#include +#include +#include "AlarmMessage.pb.h" +#include "CEventMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include +#include + +#define FUNC_SPE_EVENT_VIEW ("FUNC_SPE_EVENT_VIEW") + +const int OTHERSTATUS = 9999; +class CEventDataCollect : public QObject, public kbd_service::CAlmApiForEvtClt +{ + Q_OBJECT +public: + static CEventDataCollect * instance(); + + virtual ~CEventDataCollect(); + + bool initialize(); + + void release(); + + void loadEventConfig(); + int priorityId(const QString &description); + int locationId(const QString &description); + int regionId(const QString &description); + int alarmTypeId(const QString &description); + int eventStatusId(const QString &description); + int deviceTypeId(const QString &description); + + QString priorityDescription(const int & id); + QString locationDescription(const int & id); + QString regionDescription(const int & id); + QString alarmTypeDescription(const int & id); + QString deviceTypeDescription(const int & id); + QString deviceGroupDescription(const QString &id); + QString alarmStatusDescription(const int & id); + QString userNameDescription(const int & id); + QString subSystemDescription(const int &id); + QString eventShowStatusDescription(const int & id); + + QList priorityList(); + QList locationList(); + QList regionList(); + QList alarmTypeList(); + QList alarmStatusList(); + QList alarmOtherList(); + QMap areaInfoMap(); + QMap > areaLocMap(); + QList locationOrderList(); + QList getDevGroupTagList(); + + QMap priorityDescriptionMap(); + QMap locationDescriptionMap(); + QMap regionInfoDescriptionMap(); + QMap alarmTypeDescriptionMap(); + QMap deviceTypeDescriptionMap(); + QMap alarmStatusMap(); + QMap userNameMap(); + + QMap eventShowStatusDescriptionMap(); + QMap eventOtherStatusDescriptionMap(); + + virtual void handleAllEvtMsg(int nDomainID, kbd_idlfile::SEvtCltAddEvt &objAllEvt); + + virtual void handleAddEvtMsg(kbd_idlfile::SEvtCltAddEvt &objAddEvt); + + virtual void handleLinkWave2EvtMsg( kbd_idlfile::SAlmCltLinkWave2Alm &objWave2Evt); + + void handleClearRTEvent(); + +signals: + /** + * @brief sigMsgRefresh 在handleAllAlmMsg时触发,通知model重新拉取报警消息 + */ + void sigMsgRefresh(); + + /** + * @brief sigMsgArrived 在handleAddAlmMsg时触发,通知model新报警消息到达 + */ + void sigMsgArrived(QList listEvents); + + /** + * @brief sigEventStateChanged 事件数量或状态改变时触发。 + */ + void sigEventStateChanged(); + + /** + * @brief sigDevTreeUpdate 通知设备树更新设备组事件数 + */ + void sigDevTreeUpdate(); + +public slots: + //void queryHistoryEvent(const QStringList &tables, QList typeFilter, const QString &condition); + void slotUpdateEvent(); + +private: + CEventDataCollect(); + int queryPriorityOrder(int &id); + void removeCache(int nDomain); + + void loadPermInfo(); + void loadPriorityDescription(); + void loadLocationDescription(); + void loadRegionInfoDescription(); + void loadAlarmTypeDescription(); + void loadDeviceTypeDescription(); + void loadAlarmStatusDescription(); + void loadUserName(); + void loadSubSystemDescription(); + void loadEventShowStatusDescription(); + void loadEventOtherStatusDescription(); + + void loadDeviceGroupDescription(); + +private: + QMutex * msgMutex; + QTimer * m_pTimer; + int m_nLocationID; + QList m_listEventCache; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + QList m_listPermLocationId; + QList m_listPermRegionId; + QMap m_priorityOrderMap; + QMap m_priorityDescriptionMap; + QMap m_locationDescriptionMap; + QMap m_regionInfoDescriptionMap; + QMap m_alarmTypeDescriptionMap; + QMap m_deviceTypeDescriptionMap; + QMap m_subSystemDescriptionMap; + QMap m_alarmStatusMap; + QMap m_userNameMap; + QMap m_DescriptionMap; + static CEventDataCollect * m_pInstance; + + QMap m_eventShowStatusMap; // + QMap m_eventOtherStatusMap; //其他报警状态 + + + QMap m_areaInfoMap; //区域信息 + QMap > m_areaLocMap; //区域映射 + + QList m_locationOrderList; //< location_id: 按location_no排序 + QMap m_deviceGroupDescriptionMap; +}; + +#endif // CEventDataCollect_H diff --git a/product/src/gui/plugin/EventWidget/CEventDelegate.cpp b/product/src/gui/plugin/EventWidget/CEventDelegate.cpp index 528f388f..afb4456f 100644 --- a/product/src/gui/plugin/EventWidget/CEventDelegate.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDelegate.cpp @@ -1,306 +1,306 @@ -#include "CEventDelegate.h" -#include -#include -#include -#include "CEventMsgInfo.h" -#include "CEventItemModel.h" -#include "CEventHistoryModel.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/FileStyle.h" -#include "pub_logger_api/logger.h" -#include -#include -#include -CEventDelegate::CEventDelegate(QObject *parent) - : QStyledItemDelegate(parent), - m_pModel(Q_NULLPTR), - m_pHisModel(Q_NULLPTR), - m_selectIsEmpty(false), - m_enableWave(true) -{ - loadColorConfig(); -} - -void CEventDelegate::setEnableWave(bool isNeed) -{ - m_enableWave = isNeed; -} - -void CEventDelegate::setEventModel(CEventItemModel *model) -{ - m_pHisModel = NULL; - m_pModel = model; -} - -void CEventDelegate::setHisEventModel(CEventHistoryModel *model) -{ - m_pModel = NULL; - m_pHisModel = model; -} - -void CEventDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - if(!index.isValid()) - { - return; - } - QColor fillColor; - QColor penColor; - bool select = option.state & QStyle::State_Selected; - - //< Common - if(m_pModel != NULL) - { - EventMsgPtr info = m_pModel->getAlarmInfo(index); - - if(info != Q_NULLPTR) - { - painter->save(); - if(AS_ALARM_RTN == info->alm_style) - { - if(select) - { - fillColor = m_selectBackgroundColor; - if(m_selectIsEmpty) - { - penColor = m_activeTextMap[info->priorityOrder]; - }else - { - penColor = m_selectTextColor; - } - } - else - { - penColor = m_resumeTextMap[info->priorityOrder]; - fillColor = m_backgroundMap[info->priorityOrder]; - } - }else - { - if(select) - { - fillColor = m_selectBackgroundColor; - if(m_selectIsEmpty) - { - penColor = m_activeTextMap[info->priorityOrder]; - }else - { - penColor = m_selectTextColor; - } - } - else - { - penColor = m_activeTextMap[info->priorityOrder]; - fillColor = m_backgroundMap[info->priorityOrder]; - } - } - - painter->setPen(penColor); - painter->fillRect(option.rect, fillColor); - if(m_enableWave && REAL_BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); - std::string style = kbd_public::CFileStyle::getCurStyle(); - QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(file); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); - painter->restore(); - } - }else if(m_pHisModel != NULL) - { - EventMsgPtr info = m_pHisModel->getAlarmInfo(index); - - if(info != Q_NULLPTR) - { - painter->save(); - if(AS_ALARM_RTN == info->alm_style) - { - if(select) - { - fillColor = m_selectBackgroundColor; - if(m_selectIsEmpty) - { - penColor = m_activeTextMap[info->priorityOrder]; - }else - { - penColor = m_selectTextColor; - } - } - else - { - penColor = m_resumeTextMap[info->priorityOrder]; - fillColor = m_backgroundMap[info->priorityOrder]; - } - }else - { - if(select) - { - fillColor = m_selectBackgroundColor; - if(m_selectIsEmpty) - { - penColor = m_activeTextMap[info->priorityOrder]; - }else - { - penColor = m_selectTextColor; - } - } - else - { - penColor = m_activeTextMap[info->priorityOrder]; - fillColor = m_backgroundMap[info->priorityOrder]; - } - } - painter->setPen(penColor); - painter->fillRect(option.rect, fillColor); - if(m_enableWave && HIS_BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); - std::string style = kbd_public::CFileStyle::getCurStyle(); - QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(file); - button.features = QStyleOptionButton::Flat; - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - painter->drawText(option.rect, m_pHisModel->data(index, Qt::TextAlignmentRole).toInt(), m_pHisModel->data(index).toString()); - painter->restore(); - } - } -} - -bool CEventDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - if(!index.isValid()) - { - return false; - } - if(m_pModel != NULL) - { - if(index.column() != REAL_BUTTON_COLUMN) - { - return false; - } - EventMsgPtr info = m_pModel->getAlarmInfo(index); - QMouseEvent *mouseEvent = static_cast(event); - if(info && m_enableWave && !info->wave_file.isEmpty()) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - QString wave = info->wave_file; - wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); - LOGINFO("录波文件为:%s",wave.toStdString().c_str()); - - const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( - std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); - if(strProc.empty()) - LOGERROR("未找到可执行文件WaveAnalyze"); - else - QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); - } - } - } - }else - { - if(index.column() != HIS_BUTTON_COLUMN) - { - return false; - } - EventMsgPtr info = m_pHisModel->getAlarmInfo(index); - QMouseEvent *mouseEvent = static_cast(event); - if(info && m_enableWave && !info->wave_file.isEmpty()) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); - QRect rect = button.rect; - if(rect.contains(mouseEvent->pos())) - { - QString wave = info->wave_file; - wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); - LOGINFO("录波文件为:%s",wave.toStdString().c_str()); - - const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( - std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); - if(strProc.empty()) - LOGERROR("未找到可执行文件WaveAnalyze"); - else - QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); - } - } - } - } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} -void CEventDelegate::loadColorConfig() -{ - QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); - QDomDocument document; - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly)) - { - LOGINFO("loadColorConfig Failed!"); - return; - } - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - QDomElement element = document.documentElement(); - QDomNode node = element.firstChild(); - while(!node.isNull()) - { - QDomElement attr = node.toElement(); - if(!attr.isNull()) - { - if(QString("Level") == attr.tagName()) - { - int priority = attr.attribute("priority").toInt(); - m_backgroundMap[priority] = QColor(attr.attribute("background_color")); - m_alternatingMap[priority] = QColor(attr.attribute("alternating_color")); - m_confirmMap[priority] = QColor(attr.attribute("confirm_color")); - - m_activeTextMap[priority] = QColor(attr.attribute("active_text_color")); - m_confirmTextMap[priority] = QColor(attr.attribute("confirm_text_color")); - m_resumeTextMap[priority] = QColor(attr.attribute("resume_text_color")); - } - else if(QString("Select") == attr.tagName()) - { - m_selectBackgroundColor = QColor(attr.attribute("background_color")); - if(attr.attribute("text_color").isEmpty()) - { - m_selectIsEmpty = true; - }else - { - m_selectTextColor = QColor(attr.attribute("text_color")); - } - } - } - node = node.nextSibling(); - } -} +#include "CEventDelegate.h" +#include +#include +#include +#include "CEventMsgInfo.h" +#include "CEventItemModel.h" +#include "CEventHistoryModel.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +CEventDelegate::CEventDelegate(QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(Q_NULLPTR), + m_pHisModel(Q_NULLPTR), + m_selectIsEmpty(false), + m_enableWave(true) +{ + loadColorConfig(); +} + +void CEventDelegate::setEnableWave(bool isNeed) +{ + m_enableWave = isNeed; +} + +void CEventDelegate::setEventModel(CEventItemModel *model) +{ + m_pHisModel = NULL; + m_pModel = model; +} + +void CEventDelegate::setHisEventModel(CEventHistoryModel *model) +{ + m_pModel = NULL; + m_pHisModel = model; +} + +void CEventDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + QColor fillColor; + QColor penColor; + bool select = option.state & QStyle::State_Selected; + + //< Common + if(m_pModel != NULL) + { + EventMsgPtr info = m_pModel->getAlarmInfo(index); + + if(info != Q_NULLPTR) + { + painter->save(); + if(AS_ALARM_RTN == info->alm_style) + { + if(select) + { + fillColor = m_selectBackgroundColor; + if(m_selectIsEmpty) + { + penColor = m_activeTextMap[info->priorityOrder]; + }else + { + penColor = m_selectTextColor; + } + } + else + { + penColor = m_resumeTextMap[info->priorityOrder]; + fillColor = m_backgroundMap[info->priorityOrder]; + } + }else + { + if(select) + { + fillColor = m_selectBackgroundColor; + if(m_selectIsEmpty) + { + penColor = m_activeTextMap[info->priorityOrder]; + }else + { + penColor = m_selectTextColor; + } + } + else + { + penColor = m_activeTextMap[info->priorityOrder]; + fillColor = m_backgroundMap[info->priorityOrder]; + } + } + + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + if(m_enableWave && REAL_BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); + std::string style = kbd_public::CFileStyle::getCurStyle(); + QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + } + }else if(m_pHisModel != NULL) + { + EventMsgPtr info = m_pHisModel->getAlarmInfo(index); + + if(info != Q_NULLPTR) + { + painter->save(); + if(AS_ALARM_RTN == info->alm_style) + { + if(select) + { + fillColor = m_selectBackgroundColor; + if(m_selectIsEmpty) + { + penColor = m_activeTextMap[info->priorityOrder]; + }else + { + penColor = m_selectTextColor; + } + } + else + { + penColor = m_resumeTextMap[info->priorityOrder]; + fillColor = m_backgroundMap[info->priorityOrder]; + } + }else + { + if(select) + { + fillColor = m_selectBackgroundColor; + if(m_selectIsEmpty) + { + penColor = m_activeTextMap[info->priorityOrder]; + }else + { + penColor = m_selectTextColor; + } + } + else + { + penColor = m_activeTextMap[info->priorityOrder]; + fillColor = m_backgroundMap[info->priorityOrder]; + } + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + if(m_enableWave && HIS_BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); + std::string style = kbd_public::CFileStyle::getCurStyle(); + QString file = kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + painter->drawText(option.rect, m_pHisModel->data(index, Qt::TextAlignmentRole).toInt(), m_pHisModel->data(index).toString()); + painter->restore(); + } + } +} + +bool CEventDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(m_pModel != NULL) + { + if(index.column() != REAL_BUTTON_COLUMN) + { + return false; + } + EventMsgPtr info = m_pModel->getAlarmInfo(index); + QMouseEvent *mouseEvent = static_cast(event); + if(info && m_enableWave && !info->wave_file.isEmpty()) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString wave = info->wave_file; + wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); + LOGINFO("录波文件为:%s",wave.toStdString().c_str()); + + const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); + } + } + } + }else + { + if(index.column() != HIS_BUTTON_COLUMN) + { + return false; + } + EventMsgPtr info = m_pHisModel->getAlarmInfo(index); + QMouseEvent *mouseEvent = static_cast(event); + if(info && m_enableWave && !info->wave_file.isEmpty()) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString wave = info->wave_file; + wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); + LOGINFO("录波文件为:%s",wave.toStdString().c_str()); + + const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); + } + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} +void CEventDelegate::loadColorConfig() +{ + QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); + QDomDocument document; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + { + LOGINFO("loadColorConfig Failed!"); + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement element = document.documentElement(); + QDomNode node = element.firstChild(); + while(!node.isNull()) + { + QDomElement attr = node.toElement(); + if(!attr.isNull()) + { + if(QString("Level") == attr.tagName()) + { + int priority = attr.attribute("priority").toInt(); + m_backgroundMap[priority] = QColor(attr.attribute("background_color")); + m_alternatingMap[priority] = QColor(attr.attribute("alternating_color")); + m_confirmMap[priority] = QColor(attr.attribute("confirm_color")); + + m_activeTextMap[priority] = QColor(attr.attribute("active_text_color")); + m_confirmTextMap[priority] = QColor(attr.attribute("confirm_text_color")); + m_resumeTextMap[priority] = QColor(attr.attribute("resume_text_color")); + } + else if(QString("Select") == attr.tagName()) + { + m_selectBackgroundColor = QColor(attr.attribute("background_color")); + if(attr.attribute("text_color").isEmpty()) + { + m_selectIsEmpty = true; + }else + { + m_selectTextColor = QColor(attr.attribute("text_color")); + } + } + } + node = node.nextSibling(); + } +} diff --git a/product/src/gui/plugin/EventWidget/CEventDelegate.h b/product/src/gui/plugin/EventWidget/CEventDelegate.h index 4246b621..9bfff454 100644 --- a/product/src/gui/plugin/EventWidget/CEventDelegate.h +++ b/product/src/gui/plugin/EventWidget/CEventDelegate.h @@ -1,50 +1,50 @@ -#ifndef CEVENTDELEGATE_H -#define CEVENTDELEGATE_H - -#include -class CEventItemModel; -class CEventHistoryModel; - -class CEventDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CEventDelegate(QObject *parent = 0); - - void setEnableWave(bool isNeed); - - void setEventModel(CEventItemModel *model); - void setHisEventModel(CEventHistoryModel *model); - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; -private: - void loadColorConfig(); -private: - CEventItemModel *m_pModel; - CEventHistoryModel *m_pHisModel; - //< background color - QMap m_backgroundMap; - QMap m_alternatingMap; - QMap m_confirmMap; - - //< text color - QMap m_activeTextMap; - QMap m_confirmTextMap; - QMap m_resumeTextMap; - - //< select color - QColor m_selectBackgroundColor; - QColor m_selectTextColor; - - //< no item - QColor m_emptyBackgroundColor; - QColor m_emptyTipColor; - QString m_emptyTip; - - bool m_selectIsEmpty; - - bool m_enableWave; -}; - -#endif // CEVENTDELEGATE_H +#ifndef CEVENTDELEGATE_H +#define CEVENTDELEGATE_H + +#include +class CEventItemModel; +class CEventHistoryModel; + +class CEventDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CEventDelegate(QObject *parent = 0); + + void setEnableWave(bool isNeed); + + void setEventModel(CEventItemModel *model); + void setHisEventModel(CEventHistoryModel *model); + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; +private: + void loadColorConfig(); +private: + CEventItemModel *m_pModel; + CEventHistoryModel *m_pHisModel; + //< background color + QMap m_backgroundMap; + QMap m_alternatingMap; + QMap m_confirmMap; + + //< text color + QMap m_activeTextMap; + QMap m_confirmTextMap; + QMap m_resumeTextMap; + + //< select color + QColor m_selectBackgroundColor; + QColor m_selectTextColor; + + //< no item + QColor m_emptyBackgroundColor; + QColor m_emptyTipColor; + QString m_emptyTip; + + bool m_selectIsEmpty; + + bool m_enableWave; +}; + +#endif // CEVENTDELEGATE_H diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.cpp b/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.cpp index b827384a..35ab017f 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.cpp @@ -1,99 +1,99 @@ -#include "CEventDeviceTreeItem.h" - -CEventDeviceTreeItem::CEventDeviceTreeItem(const QString &data, CEventDeviceTreeItem *parent) - : m_tag(QString()), - m_parentItem(parent) -{ - if(m_parentItem) - { - m_parentItem->m_childItems.append(this); - } - - m_data = data; - m_checkState = Qt::Checked; -} - -CEventDeviceTreeItem::~CEventDeviceTreeItem() -{ - qDeleteAll(m_childItems); - m_childItems.clear(); -} - -CEventDeviceTreeItem *CEventDeviceTreeItem::child(int row) -{ - return m_childItems.value(row); -} - -CEventDeviceTreeItem *CEventDeviceTreeItem::parentItem() -{ - return m_parentItem; -} - -int CEventDeviceTreeItem::row() const -{ - if (m_parentItem) - { - return m_parentItem->m_childItems.indexOf(const_cast(this)); - } - - return 0; -} - -int CEventDeviceTreeItem::childCount() const -{ - return m_childItems.count(); -} - -int CEventDeviceTreeItem::columnCount() const -{ - return 1; -} - -QVariant CEventDeviceTreeItem::data(Qt::ItemDataRole role) const -{ - if(Qt::DisplayRole == role) - { - return m_data; - } - else if(Qt::UserRole == role) - { - return m_tag; - } - else if(Qt::CheckStateRole == role) - { - return m_checkState; - } - return QVariant(); -} - -bool CEventDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) -{ - if(Qt::DisplayRole == role) - { - m_data = value.toString(); - return true; - } - else if(Qt::UserRole == role) - { - m_tag = value.toString(); - return true; - } - else if(Qt::CheckStateRole == role) - { - m_checkState = (Qt::CheckState)value.toInt(); - return true; - } - return false; -} - -bool CEventDeviceTreeItem::removeChildren(int position, int count, int columns) -{ - Q_UNUSED(columns) - if (position < 0 || position + count > m_childItems.size()) - return false; - - for (int row = 0; row < count; ++row) - delete m_childItems.takeAt(position); - - return true; -} +#include "CEventDeviceTreeItem.h" + +CEventDeviceTreeItem::CEventDeviceTreeItem(const QString &data, CEventDeviceTreeItem *parent) + : m_tag(QString()), + m_parentItem(parent) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } + + m_data = data; + m_checkState = Qt::Checked; +} + +CEventDeviceTreeItem::~CEventDeviceTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +CEventDeviceTreeItem *CEventDeviceTreeItem::child(int row) +{ + return m_childItems.value(row); +} + +CEventDeviceTreeItem *CEventDeviceTreeItem::parentItem() +{ + return m_parentItem; +} + +int CEventDeviceTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CEventDeviceTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CEventDeviceTreeItem::columnCount() const +{ + return 1; +} + +QVariant CEventDeviceTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::UserRole == role) + { + return m_tag; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } + return QVariant(); +} + +bool CEventDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::UserRole == role) + { + m_tag = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + return false; +} + +bool CEventDeviceTreeItem::removeChildren(int position, int count, int columns) +{ + Q_UNUSED(columns) + if (position < 0 || position + count > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) + delete m_childItems.takeAt(position); + + return true; +} diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.h b/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.h index bb0bcab5..a2e68a9f 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.h +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.h @@ -1,83 +1,83 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CEVENTDEVICETREEITEM_H -#define CEVENTDEVICETREEITEM_H - -#include -#include - -class CEventDeviceTreeItem -{ -public: - explicit CEventDeviceTreeItem(const QString &data = QString(), CEventDeviceTreeItem *parentItem = Q_NULLPTR); - ~CEventDeviceTreeItem(); - - CEventDeviceTreeItem *child(int row); - CEventDeviceTreeItem *parentItem(); - - int row() const; - - int childCount() const; - int columnCount() const; - - QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; - bool setData(const QVariant &value, Qt::ItemDataRole role); - bool removeChildren(int position, int count, int columns); -private: - QString m_data; - QString m_tag; - Qt::CheckState m_checkState; - - QList m_childItems; - CEventDeviceTreeItem *m_parentItem; -}; - -#endif // CEVENTDEVICETREEITEM_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CEVENTDEVICETREEITEM_H +#define CEVENTDEVICETREEITEM_H + +#include +#include + +class CEventDeviceTreeItem +{ +public: + explicit CEventDeviceTreeItem(const QString &data = QString(), CEventDeviceTreeItem *parentItem = Q_NULLPTR); + ~CEventDeviceTreeItem(); + + CEventDeviceTreeItem *child(int row); + CEventDeviceTreeItem *parentItem(); + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + bool removeChildren(int position, int count, int columns); +private: + QString m_data; + QString m_tag; + Qt::CheckState m_checkState; + + QList m_childItems; + CEventDeviceTreeItem *m_parentItem; +}; + +#endif // CEVENTDEVICETREEITEM_H diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.cpp b/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.cpp index 41898cce..7a8192d4 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.cpp @@ -1,263 +1,263 @@ -#include "CEventDeviceTreeItem.h" -#include "CEventDeviceTreeModel.h" -#include "CEventMsgManage.h" -#include "CEventDataCollect.h" - -CEventDeviceTreeModel::CEventDeviceTreeModel(QObject *parent) - : QAbstractItemModel(parent) -{ - rootItem = new CEventDeviceTreeItem(); -} - -CEventDeviceTreeModel::~CEventDeviceTreeModel() -{ - m_devTagIndex.clear(); - m_devNameIndex.clear(); - delete rootItem; -} - -void CEventDeviceTreeModel::setupModelData(const QMap > > locationInfos, const QList &locationList) -{ - for(int nLocIndex(0); nLocIndexlocationDescription(locationList[nLocIndex]); - CEventDeviceTreeItem * location = new CEventDeviceTreeItem(locDesc, rootItem); - const QVector > vec = locationInfos.value(locationList[nLocIndex]); - for(int nDevIndex(0); nDevIndex < vec.size(); ++nDevIndex) - { - CEventDeviceTreeItem * device = new CEventDeviceTreeItem(vec.at(nDevIndex).second, location); - device->setData(vec.at(nDevIndex).first, Qt::UserRole); - QModelIndex modelIndex = createIndex(nDevIndex, 0, device); - m_devTagIndex.insert(vec.at(nDevIndex).first, modelIndex); - m_devNameIndex.insert(locDesc + "." + vec.at(nDevIndex).second, modelIndex); - } - } -} - -const HashIndex &CEventDeviceTreeModel::indexTagList() const -{ - return m_devTagIndex; -} - -const HashIndex &CEventDeviceTreeModel::indexNameList() const -{ - return m_devNameIndex; -} - -QModelIndex CEventDeviceTreeModel::indexOfDeviceTag(const QString &tag) -{ - return m_devTagIndex.value(tag, QModelIndex()); -} - -QModelIndex CEventDeviceTreeModel::indexOfDeviceName(const QString &name) -{ - return m_devNameIndex.value(name, QModelIndex()); -} - -QVariant CEventDeviceTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(section) - Q_UNUSED(orientation) - Q_UNUSED(role) - return QVariant(); -} - -QModelIndex CEventDeviceTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!hasIndex(row, column, parent)) - { - return QModelIndex(); - } - - CEventDeviceTreeItem *parentItem; - - if (!parent.isValid()) - { - parentItem = rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - CEventDeviceTreeItem *childItem = parentItem->child(row); - if (childItem) - { - return createIndex(row, column, childItem); - } - else - { - return QModelIndex(); - } -} - -QModelIndex CEventDeviceTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - CEventDeviceTreeItem *childItem = static_cast(index.internalPointer()); - - CEventDeviceTreeItem *parentItem = childItem->parentItem(); - if (parentItem == rootItem) - { - return QModelIndex(); - } - - return createIndex(parentItem->row(), 0, parentItem); -} - -int CEventDeviceTreeModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - { - return 0; - } - - CEventDeviceTreeItem *parentItem; - if (!parent.isValid()) - { - parentItem = rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - return parentItem->childCount(); -} - -int CEventDeviceTreeModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return static_cast(parent.internalPointer())->columnCount(); - } - else - { - return rootItem->columnCount(); - } -} - - -QVariant CEventDeviceTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.column()) - { - return QVariant(); - } - - CEventDeviceTreeItem *item = static_cast(index.internalPointer()); - if (Qt::DisplayRole == role) - { - const QString &deviceGroup = item->data(Qt::UserRole).toString(); - if(deviceGroup.isEmpty()) - { - return item->data(Qt::DisplayRole).toString(); - } - return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(m_eventDeviceGroupStatistical.value(deviceGroup,0)); - } - else if(Qt::CheckStateRole == role && QModelIndex() != index.parent()) - { - return item->data(Qt::CheckStateRole); - } - - return QVariant(); -} - -bool CEventDeviceTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid() || index.column()) - { - return false; - } - if(Qt::CheckStateRole == role) - { - emit itemCheckStateChanged(static_cast(index.internalPointer())->data(Qt::UserRole).toString(), value.toBool()); - } - return static_cast(index.internalPointer())->setData(value, (Qt::ItemDataRole)role); -} - -Qt::ItemFlags CEventDeviceTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - if(!index.column()) - { - return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; - } - - return QAbstractItemModel::flags(index); -} - -void CEventDeviceTreeModel::setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state) -{ - if(!index.isValid()) - { - return; - } - CEventDeviceTreeItem * pItem = static_cast(index.internalPointer()); - if(pItem) - { - int nChildCount = pItem->childCount(); - for( int nIndex(0); nIndex < nChildCount; nIndex++) - { - pItem->child(nIndex)->setData(state, Qt::CheckStateRole); - emit itemCheckStateChanged(pItem->child(nIndex)->data(Qt::UserRole).toString(), state); - } - } -} - -void CEventDeviceTreeModel::setAllDeviceCheckState(const Qt::CheckState &state) -{ - HashIndex::const_iterator iter = m_devTagIndex.constBegin(); - while (iter != m_devTagIndex.constEnd()) - { - CEventDeviceTreeItem * pItem = static_cast(iter.value().internalPointer()); - if(pItem) - { - pItem->setData(state, Qt::CheckStateRole); - emit itemCheckStateChanged(pItem->data(Qt::UserRole).toString(), state); - } - ++iter; - } -} - -void CEventDeviceTreeModel::removeData() -{ - m_eventDeviceGroupStatistical.clear(); - QModelIndex modelindex = QModelIndex(); - if(rootItem->childCount()>0) - { - beginRemoveRows(modelindex, 0, rootItem->childCount()-1); - rootItem->removeChildren(0, rootItem->childCount(), rootItem->columnCount()); - endRemoveRows(); - } -} - -QHash CEventDeviceTreeModel::getDeviceStatisticalInfo() -{ - return m_eventDeviceGroupStatistical; -} - -void CEventDeviceTreeModel::slotDevTreeUpdate() -{ - m_eventDeviceGroupStatistical.clear(); - m_eventDeviceGroupStatistical = CEventMsgManage::instance()->getDevGStatisticalInfo(); -} - -void CEventDeviceTreeModel::slotHisDevTreeUpdate(QList eventList) -{ - m_eventDeviceGroupStatistical.clear(); - - QList::const_iterator iter = eventList.constBegin(); - for(; iter != eventList.constEnd(); iter++) - { - m_eventDeviceGroupStatistical[(*iter)->dev_group_tag] += 1; - } -} +#include "CEventDeviceTreeItem.h" +#include "CEventDeviceTreeModel.h" +#include "CEventMsgManage.h" +#include "CEventDataCollect.h" + +CEventDeviceTreeModel::CEventDeviceTreeModel(QObject *parent) + : QAbstractItemModel(parent) +{ + rootItem = new CEventDeviceTreeItem(); +} + +CEventDeviceTreeModel::~CEventDeviceTreeModel() +{ + m_devTagIndex.clear(); + m_devNameIndex.clear(); + delete rootItem; +} + +void CEventDeviceTreeModel::setupModelData(const QMap > > locationInfos, const QList &locationList) +{ + for(int nLocIndex(0); nLocIndexlocationDescription(locationList[nLocIndex]); + CEventDeviceTreeItem * location = new CEventDeviceTreeItem(locDesc, rootItem); + const QVector > vec = locationInfos.value(locationList[nLocIndex]); + for(int nDevIndex(0); nDevIndex < vec.size(); ++nDevIndex) + { + CEventDeviceTreeItem * device = new CEventDeviceTreeItem(vec.at(nDevIndex).second, location); + device->setData(vec.at(nDevIndex).first, Qt::UserRole); + QModelIndex modelIndex = createIndex(nDevIndex, 0, device); + m_devTagIndex.insert(vec.at(nDevIndex).first, modelIndex); + m_devNameIndex.insert(locDesc + "." + vec.at(nDevIndex).second, modelIndex); + } + } +} + +const HashIndex &CEventDeviceTreeModel::indexTagList() const +{ + return m_devTagIndex; +} + +const HashIndex &CEventDeviceTreeModel::indexNameList() const +{ + return m_devNameIndex; +} + +QModelIndex CEventDeviceTreeModel::indexOfDeviceTag(const QString &tag) +{ + return m_devTagIndex.value(tag, QModelIndex()); +} + +QModelIndex CEventDeviceTreeModel::indexOfDeviceName(const QString &name) +{ + return m_devNameIndex.value(name, QModelIndex()); +} + +QVariant CEventDeviceTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CEventDeviceTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + CEventDeviceTreeItem *parentItem; + + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + CEventDeviceTreeItem *childItem = parentItem->child(row); + if (childItem) + { + return createIndex(row, column, childItem); + } + else + { + return QModelIndex(); + } +} + +QModelIndex CEventDeviceTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CEventDeviceTreeItem *childItem = static_cast(index.internalPointer()); + + CEventDeviceTreeItem *parentItem = childItem->parentItem(); + if (parentItem == rootItem) + { + return QModelIndex(); + } + + return createIndex(parentItem->row(), 0, parentItem); +} + +int CEventDeviceTreeModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + { + return 0; + } + + CEventDeviceTreeItem *parentItem; + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +int CEventDeviceTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return static_cast(parent.internalPointer())->columnCount(); + } + else + { + return rootItem->columnCount(); + } +} + + +QVariant CEventDeviceTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.column()) + { + return QVariant(); + } + + CEventDeviceTreeItem *item = static_cast(index.internalPointer()); + if (Qt::DisplayRole == role) + { + const QString &deviceGroup = item->data(Qt::UserRole).toString(); + if(deviceGroup.isEmpty()) + { + return item->data(Qt::DisplayRole).toString(); + } + return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(m_eventDeviceGroupStatistical.value(deviceGroup,0)); + } + else if(Qt::CheckStateRole == role && QModelIndex() != index.parent()) + { + return item->data(Qt::CheckStateRole); + } + + return QVariant(); +} + +bool CEventDeviceTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.column()) + { + return false; + } + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(static_cast(index.internalPointer())->data(Qt::UserRole).toString(), value.toBool()); + } + return static_cast(index.internalPointer())->setData(value, (Qt::ItemDataRole)role); +} + +Qt::ItemFlags CEventDeviceTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + if(!index.column()) + { + return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; + } + + return QAbstractItemModel::flags(index); +} + +void CEventDeviceTreeModel::setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + CEventDeviceTreeItem * pItem = static_cast(index.internalPointer()); + if(pItem) + { + int nChildCount = pItem->childCount(); + for( int nIndex(0); nIndex < nChildCount; nIndex++) + { + pItem->child(nIndex)->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->child(nIndex)->data(Qt::UserRole).toString(), state); + } + } +} + +void CEventDeviceTreeModel::setAllDeviceCheckState(const Qt::CheckState &state) +{ + HashIndex::const_iterator iter = m_devTagIndex.constBegin(); + while (iter != m_devTagIndex.constEnd()) + { + CEventDeviceTreeItem * pItem = static_cast(iter.value().internalPointer()); + if(pItem) + { + pItem->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::UserRole).toString(), state); + } + ++iter; + } +} + +void CEventDeviceTreeModel::removeData() +{ + m_eventDeviceGroupStatistical.clear(); + QModelIndex modelindex = QModelIndex(); + if(rootItem->childCount()>0) + { + beginRemoveRows(modelindex, 0, rootItem->childCount()-1); + rootItem->removeChildren(0, rootItem->childCount(), rootItem->columnCount()); + endRemoveRows(); + } +} + +QHash CEventDeviceTreeModel::getDeviceStatisticalInfo() +{ + return m_eventDeviceGroupStatistical; +} + +void CEventDeviceTreeModel::slotDevTreeUpdate() +{ + m_eventDeviceGroupStatistical.clear(); + m_eventDeviceGroupStatistical = CEventMsgManage::instance()->getDevGStatisticalInfo(); +} + +void CEventDeviceTreeModel::slotHisDevTreeUpdate(QList eventList) +{ + m_eventDeviceGroupStatistical.clear(); + + QList::const_iterator iter = eventList.constBegin(); + for(; iter != eventList.constEnd(); iter++) + { + m_eventDeviceGroupStatistical[(*iter)->dev_group_tag] += 1; + } +} diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.h b/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.h index 6f00e356..2aa55aa3 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.h +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.h @@ -1,127 +1,127 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CEVENTDEVICETREEMODEL_H -#define CEVENTDEVICETREEMODEL_H - -#include -#include -#include -#include -#include "CEventMsgInfo.h" - -typedef QHash< QString, QModelIndex > HashIndex; //< Device - -class CEventDeviceTreeItem; - -class CEventDeviceTreeModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - explicit CEventDeviceTreeModel(QObject *parent = 0); - ~CEventDeviceTreeModel(); - - //< @param locationInfos [ locationDesc[ devTag, devDesc ] ] - void setupModelData(const QMap > > locationInfos, const QList &locationList); - - const HashIndex &indexTagList() const; - - const HashIndex &indexNameList() const; - - QModelIndex indexOfDeviceTag(const QString &tag); - - QModelIndex indexOfDeviceName(const QString &name); - - QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - void setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state); - - void setAllDeviceCheckState(const Qt::CheckState &state); - - void removeData(); - - QHash getDeviceStatisticalInfo(); - -signals: - void itemCheckStateChanged(const QString &device, const bool &checked); - -public slots: - /** - * @brief slotDevTreeUpdate 实时事件 - */ - void slotDevTreeUpdate(); - - /** - * @brief slotDevTreeUpdate 历史事件 - * @param eventList - */ - void slotHisDevTreeUpdate(QList eventList); - -private: - CEventDeviceTreeItem *rootItem; - HashIndex m_devTagIndex; - HashIndex m_devNameIndex; - QHash m_eventDeviceGroupStatistical; //<设备组告警数量统计 -}; - -#endif // CEVENTDEVICETREEMODEL_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CEVENTDEVICETREEMODEL_H +#define CEVENTDEVICETREEMODEL_H + +#include +#include +#include +#include +#include "CEventMsgInfo.h" + +typedef QHash< QString, QModelIndex > HashIndex; //< Device + +class CEventDeviceTreeItem; + +class CEventDeviceTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CEventDeviceTreeModel(QObject *parent = 0); + ~CEventDeviceTreeModel(); + + //< @param locationInfos [ locationDesc[ devTag, devDesc ] ] + void setupModelData(const QMap > > locationInfos, const QList &locationList); + + const HashIndex &indexTagList() const; + + const HashIndex &indexNameList() const; + + QModelIndex indexOfDeviceTag(const QString &tag); + + QModelIndex indexOfDeviceName(const QString &name); + + QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void setAllDeviceCheckState(const Qt::CheckState &state); + + void removeData(); + + QHash getDeviceStatisticalInfo(); + +signals: + void itemCheckStateChanged(const QString &device, const bool &checked); + +public slots: + /** + * @brief slotDevTreeUpdate 实时事件 + */ + void slotDevTreeUpdate(); + + /** + * @brief slotDevTreeUpdate 历史事件 + * @param eventList + */ + void slotHisDevTreeUpdate(QList eventList); + +private: + CEventDeviceTreeItem *rootItem; + HashIndex m_devTagIndex; + HashIndex m_devNameIndex; + QHash m_eventDeviceGroupStatistical; //<设备组告警数量统计 +}; + +#endif // CEVENTDEVICETREEMODEL_H diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.cpp b/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.cpp index 5d9f2d1a..8abecb17 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.cpp @@ -1,7 +1,7 @@ -#include "CEventDeviceTreeView.h" - -CEventDeviceTreeView::CEventDeviceTreeView(QWidget *parent) - : QTreeView(parent) -{ - -} +#include "CEventDeviceTreeView.h" + +CEventDeviceTreeView::CEventDeviceTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.h b/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.h index 69d2f565..009bab75 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.h +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.h @@ -1,14 +1,14 @@ -#ifndef CEVENTDEVICETREEVIEW_H -#define CEVENTDEVICETREEVIEW_H - -#include - -class CEventDeviceTreeView : public QTreeView -{ - Q_OBJECT -public: - CEventDeviceTreeView(QWidget *parent = Q_NULLPTR); - -}; - -#endif // CEVENTDEVICETREEVIEW_H +#ifndef CEVENTDEVICETREEVIEW_H +#define CEVENTDEVICETREEVIEW_H + +#include + +class CEventDeviceTreeView : public QTreeView +{ + Q_OBJECT +public: + CEventDeviceTreeView(QWidget *parent = Q_NULLPTR); + +}; + +#endif // CEVENTDEVICETREEVIEW_H diff --git a/product/src/gui/plugin/EventWidget/CEventFilterDialog.cpp b/product/src/gui/plugin/EventWidget/CEventFilterDialog.cpp index daec8c4c..e6b339f9 100644 --- a/product/src/gui/plugin/EventWidget/CEventFilterDialog.cpp +++ b/product/src/gui/plugin/EventWidget/CEventFilterDialog.cpp @@ -1,806 +1,806 @@ -#include "CEventFilterDialog.h" -#include "ui_CEventFilterDialog.h" -#include "CEventDataCollect.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include - -int CEventFilterDialog::windowMinWidth() -{ - return m_nMinWidth; -} - -void CEventFilterDialog::setWindowMinWidth(int nWidth) -{ - m_nMinWidth = nWidth; - setMinimumWidth(m_nMinWidth); -} - -int CEventFilterDialog::windowMinHeigth() -{ - return m_nMinHeight; -} - -void CEventFilterDialog::setWindowMinHeigth(int nHeight) -{ - m_nMinHeight = nHeight; - setMinimumHeight(m_nMinHeight); -} - -CEventFilterDialog::CEventFilterDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CEventFilterDialog), - m_rtdbAccess(Q_NULLPTR), - m_nMinHeight(421), - m_nMinWidth(570) -{ - ui->setupUi(this); - setObjectName("event_dialog"); - ui->subSystem->setView(new QListView()); - ui->deviceType->setView(new QListView()); -} - -CEventFilterDialog::~CEventFilterDialog() -{ - if(m_rtdbAccess) - { - delete m_rtdbAccess; - } - m_rtdbAccess = Q_NULLPTR; - delete ui; -} - -void CEventFilterDialog::initialize(E_ALARM_VIEW view) -{ - m_view=view; - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - ui->level->setSelectionMode(QAbstractItemView::MultiSelection); - //ui->location->setSelectionMode(QAbstractItemView::MultiSelection); - ui->region->setSelectionMode(QAbstractItemView::MultiSelection); - ui->type->setSelectionMode(QAbstractItemView::MultiSelection); - - QList priorityList = CEventDataCollect::instance()->priorityList(); - foreach (int priority, priorityList) - { - ui->level->addItem(CEventDataCollect::instance()->priorityDescription(priority)); - } - -// QList locationList = CEventDataCollect::instance()->locationList(); - -// foreach (int location, locationList) -// { -// ui->location->addItem(CEventDataCollect::instance()->locationDescription(location)); -// } - m_areaInfoMap = CEventDataCollect::instance()->areaInfoMap(); - m_areaLocMap = CEventDataCollect::instance()->areaLocMap(); - ui->area->clear(); - ui->area->setColumnCount(1); - bool isArea = false; - QMap >::iterator it = m_areaLocMap.begin(); - while (it != m_areaLocMap.end()) { - if(it.key()<=0) - { - QVector locVec = it.value(); - for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); - firstItem->setData(0,Qt::UserRole,locVec.at(index)); - firstItem->setData(0,Qt::UserRole+1,it.key()); - firstItem->setCheckState(0,Qt::Unchecked); - firstItem->setToolTip(0,getDescByAreaId(locVec.at(index))); - ui->area->addTopLevelItem(firstItem); - } - }else - { - QTreeWidgetItem *firstItem = new QTreeWidgetItem(); - firstItem->setText(0,getDescByAreaId(it.key())); - firstItem->setData(0,Qt::UserRole,it.key()); - firstItem->setData(0,Qt::UserRole+1,-1); - firstItem->setCheckState(0,Qt::Unchecked); - firstItem->setToolTip(0,getDescByAreaId(it.key())); - QVector locVec = it.value(); - for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); - secondItem->setData(0,Qt::UserRole,locVec.at(index)); - secondItem->setData(0,Qt::UserRole+1,it.key()); - secondItem->setCheckState(0,Qt::Unchecked); - secondItem->setToolTip(0,getDescByAreaId(locVec.at(index))); - firstItem->addChild(secondItem); - } - ui->area->addTopLevelItem(firstItem); - isArea = true; - } - - it++; - } - //< 无区域配置时不缩进,尽可能展示完全 - if(!isArea) - { - ui->area->setIndentation(0); - } - QList regionList = CEventDataCollect::instance()->regionList(); - foreach (int region, regionList) - { - ui->region->addItem(CEventDataCollect::instance()->regionDescription(region)); - } - - QList alarmStatusList = CEventDataCollect::instance()->alarmStatusList(); - foreach (int alarmStatus, alarmStatusList) - { - ui->type->addItem(CEventDataCollect::instance()->eventShowStatusDescription(alarmStatus)); - } - - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - std::vector vecSubsystemInfo; - spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); - foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) - { - if(info.nId <= CN_AppId_COMAPP) - { - continue; - } - ui->subSystem->addItem(QString::fromStdString(info.strDesc)); - } - } - - ui->subSystem->setCurrentIndex(-1); - - connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); - connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); - connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); - connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); - connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); - connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); - connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); - connect(ui->area, &QTreeWidget::itemChanged, this, &CEventFilterDialog::slot_updateCheckLocationState); - connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); - connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); - connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); - connect(ui->checkType, SIGNAL(pressed()), this, SLOT(slot_checkTypePressed())); - connect(ui->checkType, SIGNAL(stateChanged(int)), this, SLOT(slot_typeSelectChange(int))); - connect(ui->type, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckTypeState())); - connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); - ui->subSystem->setCurrentIndex(0); -} - -void CEventFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) -{ - ui->levelFilter->setChecked(isLevelFilterEnable); -} - -void CEventFilterDialog::setLevelFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->level->count(); nIndex++) - { - int nLevelID = CEventDataCollect::instance()->priorityId(ui->level->item(nIndex)->text()); - if(filter.contains(nLevelID)) - { - ui->level->item(nIndex)->setSelected(true); - } - else - { - ui->level->item(nIndex)->setSelected(false); - } - } -} - -void CEventFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) -{ - ui->locationFilter->setChecked(isLocationFilterEnable); -} - -void CEventFilterDialog::setLocationFilter(const QList &filter) -{ - if(filter.isEmpty()) - { - return; - } - ui->area->blockSignals(true); - int count = ui->area->topLevelItemCount(); - for(int index(0);indexarea->topLevelItem(index); - int areaId = firstItem->data(0,Qt::UserRole).toInt(); - if(filter.contains(areaId)) - { - firstItem->setCheckState(0,Qt::Checked); - } - int childCount = firstItem->childCount(); - - for(int locIndex(0);locIndex child(locIndex); - int locId = secondItem->data(0,Qt::UserRole).toInt(); - if(filter.contains(locId)) - { - secondItem->setCheckState(0,Qt::Checked); - } - } - } - int selectNum = 0; - int allNum = 0; - for(int index(0);indexarea->topLevelItem(index); - if(firstItem->checkState(0) == Qt::Checked) - { - selectNum += 1; - } - int childNum = firstItem->childCount(); - for(int secIndex(0);secIndexchild(secIndex); - allNum++; - if(secondItem->checkState(0) == Qt::Checked) - { - selectNum += 1; - } - } - } - - if(selectNum == 0) - { - ui->checkLocation->setCheckState(Qt::Unchecked); - }else if(selectNum == allNum) - { - ui->checkLocation->setCheckState(Qt::Checked); - }else - { - ui->checkLocation->setCheckState(Qt::PartiallyChecked); - } - ui->area->blockSignals(false); -} - -void CEventFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) -{ - ui->regionFilter->setChecked(isRegionFilterEnable); -} - -void CEventFilterDialog::setRegionFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->region->count(); nIndex++) - { - int nRegionID = CEventDataCollect::instance()->regionId(ui->region->item(nIndex)->text()); - if(filter.contains(nRegionID)) - { - ui->region->item(nIndex)->setSelected(true); - } - else - { - ui->region->item(nIndex)->setSelected(false); - } - } -} - -void CEventFilterDialog::setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable) -{ - ui->alarmTypeFilter->setChecked(isAlarmTypeEnable); -} - -void CEventFilterDialog::setAlarmTypeFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->type->count(); nIndex++) - { - int nAlarmTypeID = CEventDataCollect::instance()->eventStatusId(ui->type->item(nIndex)->text()); - if(filter.contains(nAlarmTypeID)) - { - ui->type->item(nIndex)->setSelected(true); - } - else - { - ui->type->item(nIndex)->setSelected(false); - } - } -} - -void CEventFilterDialog::setDeviceFilterEnable(const bool &filter) -{ - ui->deviceFilterEnable->setChecked(filter); -} - -void CEventFilterDialog::setSubSystem(const QString &subSystem) -{ - if(ui->deviceFilterEnable->isChecked()) - { - ui->subSystem->setCurrentText(subSystem); - } -} - -void CEventFilterDialog::setDeviceType(const QString &deviceType) -{ - if(ui->deviceFilterEnable->isChecked()) - { - ui->deviceType->setCurrentText(deviceType); - } -} - -void CEventFilterDialog::setTimeFilterEnable(const bool &filter) -{ - ui->timeFilterEnable->setChecked(filter); -} - -void CEventFilterDialog::setStartTimeFilter(const QDateTime &filter) -{ - if(ui->timeFilterEnable->isChecked()) - { - ui->startTime->setDateTime(filter); - } - else - { - QDateTime dataTime(QDateTime::currentDateTime()); - dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().minute(),0,0)); - ui->startTime->setDateTime(dataTime); - } -} - -void CEventFilterDialog::setEndTimeFilter(const QDateTime &filter) -{ - if(ui->timeFilterEnable->isChecked()) - { - ui->endTime->setDateTime(filter); - } - else - { - QDateTime dataTime(QDateTime::currentDateTime()); - dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().minute(),59,999)); - ui->endTime->setDateTime(QDateTime::currentDateTime()); - } -} - - -void CEventFilterDialog::setkeyWordFilterEnable(const bool &filter) -{ - ui->keywordFilterEnable->setChecked(filter); -} - -void CEventFilterDialog::setkeyWordFilteContent(const QString &content) -{ - if(ui->keywordFilterEnable->isChecked()) - { - ui->keyWord->setText(content); - } -} - -void CEventFilterDialog::setReturnFilterEnable(bool &filter) -{ - ui->returnFilterEnable->setChecked(filter); -} - -void CEventFilterDialog::setReturnFilter(bool &filter) -{ - if(filter) - { - ui->hasReturn->setChecked(true); - } - else - { - ui->notReturn->setChecked(true); - } -} - -void CEventFilterDialog::slot_updateFilter() -{ - bool isTimeFilter = ui->timeFilterEnable->isChecked(); - QDateTime startTime = QDateTime(); - QDateTime endTime = QDateTime(); - if(isTimeFilter) - { - startTime = ui->startTime->dateTime(); - endTime = ui->endTime->dateTime(); - } - if(startTime.toMSecsSinceEpoch() > endTime.toMSecsSinceEpoch()) - { - QMessageBox::information( 0, tr("提示"), tr("开始时间不能大于结束时间!")); - return; - } - if(m_view == E_ALARM_HIS_EVENT ) - { - if(!isTimeFilter) - { - QMessageBox::information( 0, tr("提示"), tr("历史事件过滤必须选择时间!")); - return; - } - - if((endTime.toMSecsSinceEpoch()-startTime.toMSecsSinceEpoch())/1000/3600/24 >= 90 ) - { - QMessageBox::information( 0, tr("提示"), tr("时间间隔不得超过90天!")); - return; - } - } - bool isLevelFilter = ui->levelFilter->isChecked(); - QList listLevel; - foreach (QListWidgetItem *item, ui->level->selectedItems()) - { - listLevel << CEventDataCollect::instance()->priorityId(item->text()); - } - - bool isLocationFilter = ui->locationFilter->isChecked(); - QList listLocation; -// foreach (QListWidgetItem *item, ui->location->selectedItems()) -// { -// listLocation << CEventDataCollect::instance()->locationId(item->text()); -// } - int count = ui->area->topLevelItemCount(); - for(int index(0);indexarea->topLevelItem(index); - if(firstItem->checkState(0) == Qt::Checked) - { - listLocation.append(firstItem->data(0,Qt::UserRole).toInt()); - } - int locCount = firstItem->childCount(); - for(int locIndex(0);locIndexchild(locIndex); - if(secondItem->checkState(0) == Qt::Checked) - { - listLocation.append(secondItem->data(0,Qt::UserRole).toInt()); - } - } - } - - bool isRegionFilter = ui->regionFilter->isChecked(); - QList listRegion; - foreach (QListWidgetItem *item, ui->region->selectedItems()) - { - listRegion << CEventDataCollect::instance()->regionId(item->text()); - } - - bool isAlarmTypeFilter = ui->alarmTypeFilter->isChecked(); - QList listAlarmType; - foreach (QListWidgetItem *item, ui->type->selectedItems()) - { - listAlarmType << CEventDataCollect::instance()->eventStatusId(item->text()); - } - - bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); - QString subSystem = ui->subSystem->currentText(); - QString deviceType = ui->deviceType->currentText(); - - bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); - QString strKeyWord =ui->keyWord->text(); - - - bool isReturnFilter = ui->returnFilterEnable->isChecked(); - bool isReturn = ui->hasReturn->isChecked(); - emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, - isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime,isReturnFilter, isReturn); - accept(); -} - -//Level -void CEventFilterDialog::slot_checkLevelPressed() -{ - if( Qt::Unchecked == ui->checkLevel->checkState()) - { - ui->checkLevel->setTristate(false); - } -} - -void CEventFilterDialog::slot_levelSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->level->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->level->selectAll(); - } -} - -void CEventFilterDialog::slot_updateCheckLevelState() -{ - if( ui->level->count() == ui->level->selectedItems().count() ) - { - if( Qt::Checked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->level->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Location -void CEventFilterDialog::slot_checkLocationPressed() -{ - if( Qt::Unchecked == ui->checkLocation->checkState()) - { - ui->checkLocation->setTristate(false); - } -} - -void CEventFilterDialog::slot_locationSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - clearTreeSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - allTreeSelection(); - } -} - -void CEventFilterDialog::slot_updateCheckLocationState(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - ui->area->blockSignals(true); - if(item->parent() == NULL) //父节点 - { - childItemSelection(item); - }else if(item->childCount()<= 0) //子节点 - { - //parentItemSelection(item); - } - - int selectNum = 0; - int count = ui->area->topLevelItemCount(); - int allNum = 0; - for(int index(0);indexarea->topLevelItem(index); - if(firstItem->checkState(0) == Qt::Checked) - { - selectNum += 1; - } - int childNum = firstItem->childCount(); - for(int secIndex(0);secIndexchild(secIndex); - allNum++; - if(secondItem->checkState(0) == Qt::Checked) - { - selectNum += 1; - } - } - } - - if(selectNum == 0) - { - ui->checkLocation->setCheckState(Qt::Unchecked); - }else if(selectNum == allNum) - { - ui->checkLocation->setCheckState(Qt::Checked); - }else - { - ui->checkLocation->setCheckState(Qt::PartiallyChecked); - } - - - ui->area->blockSignals(false); -} - -//Region -void CEventFilterDialog::slot_checkRegionPressed() -{ - if( Qt::Unchecked == ui->checkRegion->checkState()) - { - ui->checkRegion->setTristate(false); - } -} - -void CEventFilterDialog::slot_regionSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->region->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->region->selectAll(); - } -} - -void CEventFilterDialog::slot_updateCheckRegionState() -{ - if( ui->region->count() == ui->region->selectedItems().count() ) - { - if( Qt::Checked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->region->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Type -void CEventFilterDialog::slot_checkTypePressed() -{ - if( Qt::Unchecked == ui->checkType->checkState()) - { - ui->checkType->setTristate(false); - } -} - -void CEventFilterDialog::slot_typeSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->type->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->type->selectAll(); - } -} - -void CEventFilterDialog::slot_updateCheckTypeState() -{ - if( ui->type->count() == ui->type->selectedItems().count() ) - { - if( Qt::Checked != ui->checkType->checkState() ) - { - ui->checkType->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->type->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkType->checkState() ) - { - ui->checkType->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkType->checkState() ) - { - ui->checkType->setCheckState(Qt::PartiallyChecked); - } - } -} - -void CEventFilterDialog::slot_updateDevice(const QString &subSystem) -{ - int nSubSystemId = -1; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - std::vector vecSubsystemInfo; - spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); - foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) - { - if(subSystem.toStdString() == info.strDesc) - { - nSubSystemId = info.nId; - } - } - } - - ui->deviceType->clear(); - QList values; - - if(nSubSystemId != -1) - { - kbd_dbms::CVarType subSystemId = nSubSystemId; - if(m_rtdbAccess->open("base", "dev_type_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CONDINFO condition; - condition.relationop = ATTRCOND_EQU; - memcpy(condition.name, "sub_system",strlen("sub_system")); - condition.conditionval = subSystemId; - std::vector columns; - columns.push_back("description"); - - kbd_dbms::CRdbQueryResult result; - if(m_rtdbAccess->select(condition, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, value); - values.append(value); - } - } - } - } - foreach (kbd_dbms::CVarType value, values) - { - ui->deviceType->addItem(value.c_str()); - } -} - -QString CEventFilterDialog::getDescByAreaId(int areaId) -{ - SAreaInfo info; - return m_areaInfoMap.value(areaId,info).stDes; -} - -void CEventFilterDialog::clearTreeSelection() -{ - int count = ui->area->topLevelItemCount(); - for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Unchecked); - slot_updateCheckLocationState(ui->area->topLevelItem(index),0); - } -} - -void CEventFilterDialog::childItemSelection(QTreeWidgetItem *item) -{ - Qt::CheckState status = item->checkState(0); - - int count = item->childCount(); - for(int index(0);indexchild(index)->setCheckState(0,status); - } -} - -void CEventFilterDialog::parentItemSelection(QTreeWidgetItem *item) -{ - QTreeWidgetItem *parent = item->parent(); - int count = parent->childCount(); - int checkNum = 0; - for(int index(0);indexchild(index)->checkState(0) == Qt::Checked) - { - checkNum += 1; - } - } - if(checkNum == count) - { - parent->setCheckState(0,Qt::Checked); - }else if(checkNum == 0) - { - parent->setCheckState(0,Qt::Unchecked); - }else - { - parent->setCheckState(0,Qt::PartiallyChecked); - } -} - -void CEventFilterDialog::allTreeSelection() -{ - int count = ui->area->topLevelItemCount(); - for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Checked); - slot_updateCheckLocationState(ui->area->topLevelItem(index),0); - } -} +#include "CEventFilterDialog.h" +#include "ui_CEventFilterDialog.h" +#include "CEventDataCollect.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include + +int CEventFilterDialog::windowMinWidth() +{ + return m_nMinWidth; +} + +void CEventFilterDialog::setWindowMinWidth(int nWidth) +{ + m_nMinWidth = nWidth; + setMinimumWidth(m_nMinWidth); +} + +int CEventFilterDialog::windowMinHeigth() +{ + return m_nMinHeight; +} + +void CEventFilterDialog::setWindowMinHeigth(int nHeight) +{ + m_nMinHeight = nHeight; + setMinimumHeight(m_nMinHeight); +} + +CEventFilterDialog::CEventFilterDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CEventFilterDialog), + m_rtdbAccess(Q_NULLPTR), + m_nMinHeight(421), + m_nMinWidth(570) +{ + ui->setupUi(this); + setObjectName("event_dialog"); + ui->subSystem->setView(new QListView()); + ui->deviceType->setView(new QListView()); +} + +CEventFilterDialog::~CEventFilterDialog() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + delete ui; +} + +void CEventFilterDialog::initialize(E_ALARM_VIEW view) +{ + m_view=view; + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + ui->level->setSelectionMode(QAbstractItemView::MultiSelection); + //ui->location->setSelectionMode(QAbstractItemView::MultiSelection); + ui->region->setSelectionMode(QAbstractItemView::MultiSelection); + ui->type->setSelectionMode(QAbstractItemView::MultiSelection); + + QList priorityList = CEventDataCollect::instance()->priorityList(); + foreach (int priority, priorityList) + { + ui->level->addItem(CEventDataCollect::instance()->priorityDescription(priority)); + } + +// QList locationList = CEventDataCollect::instance()->locationList(); + +// foreach (int location, locationList) +// { +// ui->location->addItem(CEventDataCollect::instance()->locationDescription(location)); +// } + m_areaInfoMap = CEventDataCollect::instance()->areaInfoMap(); + m_areaLocMap = CEventDataCollect::instance()->areaLocMap(); + ui->area->clear(); + ui->area->setColumnCount(1); + bool isArea = false; + QMap >::iterator it = m_areaLocMap.begin(); + while (it != m_areaLocMap.end()) { + if(it.key()<=0) + { + QVector locVec = it.value(); + for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); + firstItem->setData(0,Qt::UserRole,locVec.at(index)); + firstItem->setData(0,Qt::UserRole+1,it.key()); + firstItem->setCheckState(0,Qt::Unchecked); + firstItem->setToolTip(0,getDescByAreaId(locVec.at(index))); + ui->area->addTopLevelItem(firstItem); + } + }else + { + QTreeWidgetItem *firstItem = new QTreeWidgetItem(); + firstItem->setText(0,getDescByAreaId(it.key())); + firstItem->setData(0,Qt::UserRole,it.key()); + firstItem->setData(0,Qt::UserRole+1,-1); + firstItem->setCheckState(0,Qt::Unchecked); + firstItem->setToolTip(0,getDescByAreaId(it.key())); + QVector locVec = it.value(); + for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); + secondItem->setData(0,Qt::UserRole,locVec.at(index)); + secondItem->setData(0,Qt::UserRole+1,it.key()); + secondItem->setCheckState(0,Qt::Unchecked); + secondItem->setToolTip(0,getDescByAreaId(locVec.at(index))); + firstItem->addChild(secondItem); + } + ui->area->addTopLevelItem(firstItem); + isArea = true; + } + + it++; + } + //< 无区域配置时不缩进,尽可能展示完全 + if(!isArea) + { + ui->area->setIndentation(0); + } + QList regionList = CEventDataCollect::instance()->regionList(); + foreach (int region, regionList) + { + ui->region->addItem(CEventDataCollect::instance()->regionDescription(region)); + } + + QList alarmStatusList = CEventDataCollect::instance()->alarmStatusList(); + foreach (int alarmStatus, alarmStatusList) + { + ui->type->addItem(CEventDataCollect::instance()->eventShowStatusDescription(alarmStatus)); + } + + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(info.nId <= CN_AppId_COMAPP) + { + continue; + } + ui->subSystem->addItem(QString::fromStdString(info.strDesc)); + } + } + + ui->subSystem->setCurrentIndex(-1); + + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); + connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); + connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); + connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); + connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); + connect(ui->area, &QTreeWidget::itemChanged, this, &CEventFilterDialog::slot_updateCheckLocationState); + connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); + connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); + connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); + connect(ui->checkType, SIGNAL(pressed()), this, SLOT(slot_checkTypePressed())); + connect(ui->checkType, SIGNAL(stateChanged(int)), this, SLOT(slot_typeSelectChange(int))); + connect(ui->type, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckTypeState())); + connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); + ui->subSystem->setCurrentIndex(0); +} + +void CEventFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) +{ + ui->levelFilter->setChecked(isLevelFilterEnable); +} + +void CEventFilterDialog::setLevelFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->level->count(); nIndex++) + { + int nLevelID = CEventDataCollect::instance()->priorityId(ui->level->item(nIndex)->text()); + if(filter.contains(nLevelID)) + { + ui->level->item(nIndex)->setSelected(true); + } + else + { + ui->level->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) +{ + ui->locationFilter->setChecked(isLocationFilterEnable); +} + +void CEventFilterDialog::setLocationFilter(const QList &filter) +{ + if(filter.isEmpty()) + { + return; + } + ui->area->blockSignals(true); + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index); + int areaId = firstItem->data(0,Qt::UserRole).toInt(); + if(filter.contains(areaId)) + { + firstItem->setCheckState(0,Qt::Checked); + } + int childCount = firstItem->childCount(); + + for(int locIndex(0);locIndex child(locIndex); + int locId = secondItem->data(0,Qt::UserRole).toInt(); + if(filter.contains(locId)) + { + secondItem->setCheckState(0,Qt::Checked); + } + } + } + int selectNum = 0; + int allNum = 0; + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + int childNum = firstItem->childCount(); + for(int secIndex(0);secIndexchild(secIndex); + allNum++; + if(secondItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + } + } + + if(selectNum == 0) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + }else if(selectNum == allNum) + { + ui->checkLocation->setCheckState(Qt::Checked); + }else + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + ui->area->blockSignals(false); +} + +void CEventFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) +{ + ui->regionFilter->setChecked(isRegionFilterEnable); +} + +void CEventFilterDialog::setRegionFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->region->count(); nIndex++) + { + int nRegionID = CEventDataCollect::instance()->regionId(ui->region->item(nIndex)->text()); + if(filter.contains(nRegionID)) + { + ui->region->item(nIndex)->setSelected(true); + } + else + { + ui->region->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable) +{ + ui->alarmTypeFilter->setChecked(isAlarmTypeEnable); +} + +void CEventFilterDialog::setAlarmTypeFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->type->count(); nIndex++) + { + int nAlarmTypeID = CEventDataCollect::instance()->eventStatusId(ui->type->item(nIndex)->text()); + if(filter.contains(nAlarmTypeID)) + { + ui->type->item(nIndex)->setSelected(true); + } + else + { + ui->type->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setDeviceFilterEnable(const bool &filter) +{ + ui->deviceFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setSubSystem(const QString &subSystem) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->subSystem->setCurrentText(subSystem); + } +} + +void CEventFilterDialog::setDeviceType(const QString &deviceType) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->deviceType->setCurrentText(deviceType); + } +} + +void CEventFilterDialog::setTimeFilterEnable(const bool &filter) +{ + ui->timeFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setStartTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->startTime->setDateTime(filter); + } + else + { + QDateTime dataTime(QDateTime::currentDateTime()); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().minute(),0,0)); + ui->startTime->setDateTime(dataTime); + } +} + +void CEventFilterDialog::setEndTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->endTime->setDateTime(filter); + } + else + { + QDateTime dataTime(QDateTime::currentDateTime()); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().minute(),59,999)); + ui->endTime->setDateTime(QDateTime::currentDateTime()); + } +} + + +void CEventFilterDialog::setkeyWordFilterEnable(const bool &filter) +{ + ui->keywordFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setkeyWordFilteContent(const QString &content) +{ + if(ui->keywordFilterEnable->isChecked()) + { + ui->keyWord->setText(content); + } +} + +void CEventFilterDialog::setReturnFilterEnable(bool &filter) +{ + ui->returnFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setReturnFilter(bool &filter) +{ + if(filter) + { + ui->hasReturn->setChecked(true); + } + else + { + ui->notReturn->setChecked(true); + } +} + +void CEventFilterDialog::slot_updateFilter() +{ + bool isTimeFilter = ui->timeFilterEnable->isChecked(); + QDateTime startTime = QDateTime(); + QDateTime endTime = QDateTime(); + if(isTimeFilter) + { + startTime = ui->startTime->dateTime(); + endTime = ui->endTime->dateTime(); + } + if(startTime.toMSecsSinceEpoch() > endTime.toMSecsSinceEpoch()) + { + QMessageBox::information( 0, tr("提示"), tr("开始时间不能大于结束时间!")); + return; + } + if(m_view == E_ALARM_HIS_EVENT ) + { + if(!isTimeFilter) + { + QMessageBox::information( 0, tr("提示"), tr("历史事件过滤必须选择时间!")); + return; + } + + if((endTime.toMSecsSinceEpoch()-startTime.toMSecsSinceEpoch())/1000/3600/24 >= 90 ) + { + QMessageBox::information( 0, tr("提示"), tr("时间间隔不得超过90天!")); + return; + } + } + bool isLevelFilter = ui->levelFilter->isChecked(); + QList listLevel; + foreach (QListWidgetItem *item, ui->level->selectedItems()) + { + listLevel << CEventDataCollect::instance()->priorityId(item->text()); + } + + bool isLocationFilter = ui->locationFilter->isChecked(); + QList listLocation; +// foreach (QListWidgetItem *item, ui->location->selectedItems()) +// { +// listLocation << CEventDataCollect::instance()->locationId(item->text()); +// } + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + listLocation.append(firstItem->data(0,Qt::UserRole).toInt()); + } + int locCount = firstItem->childCount(); + for(int locIndex(0);locIndexchild(locIndex); + if(secondItem->checkState(0) == Qt::Checked) + { + listLocation.append(secondItem->data(0,Qt::UserRole).toInt()); + } + } + } + + bool isRegionFilter = ui->regionFilter->isChecked(); + QList listRegion; + foreach (QListWidgetItem *item, ui->region->selectedItems()) + { + listRegion << CEventDataCollect::instance()->regionId(item->text()); + } + + bool isAlarmTypeFilter = ui->alarmTypeFilter->isChecked(); + QList listAlarmType; + foreach (QListWidgetItem *item, ui->type->selectedItems()) + { + listAlarmType << CEventDataCollect::instance()->eventStatusId(item->text()); + } + + bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); + QString subSystem = ui->subSystem->currentText(); + QString deviceType = ui->deviceType->currentText(); + + bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); + QString strKeyWord =ui->keyWord->text(); + + + bool isReturnFilter = ui->returnFilterEnable->isChecked(); + bool isReturn = ui->hasReturn->isChecked(); + emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, + isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime,isReturnFilter, isReturn); + accept(); +} + +//Level +void CEventFilterDialog::slot_checkLevelPressed() +{ + if( Qt::Unchecked == ui->checkLevel->checkState()) + { + ui->checkLevel->setTristate(false); + } +} + +void CEventFilterDialog::slot_levelSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->level->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->level->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckLevelState() +{ + if( ui->level->count() == ui->level->selectedItems().count() ) + { + if( Qt::Checked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->level->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Location +void CEventFilterDialog::slot_checkLocationPressed() +{ + if( Qt::Unchecked == ui->checkLocation->checkState()) + { + ui->checkLocation->setTristate(false); + } +} + +void CEventFilterDialog::slot_locationSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + clearTreeSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + allTreeSelection(); + } +} + +void CEventFilterDialog::slot_updateCheckLocationState(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + ui->area->blockSignals(true); + if(item->parent() == NULL) //父节点 + { + childItemSelection(item); + }else if(item->childCount()<= 0) //子节点 + { + //parentItemSelection(item); + } + + int selectNum = 0; + int count = ui->area->topLevelItemCount(); + int allNum = 0; + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + int childNum = firstItem->childCount(); + for(int secIndex(0);secIndexchild(secIndex); + allNum++; + if(secondItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + } + } + + if(selectNum == 0) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + }else if(selectNum == allNum) + { + ui->checkLocation->setCheckState(Qt::Checked); + }else + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + + + ui->area->blockSignals(false); +} + +//Region +void CEventFilterDialog::slot_checkRegionPressed() +{ + if( Qt::Unchecked == ui->checkRegion->checkState()) + { + ui->checkRegion->setTristate(false); + } +} + +void CEventFilterDialog::slot_regionSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->region->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->region->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckRegionState() +{ + if( ui->region->count() == ui->region->selectedItems().count() ) + { + if( Qt::Checked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->region->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Type +void CEventFilterDialog::slot_checkTypePressed() +{ + if( Qt::Unchecked == ui->checkType->checkState()) + { + ui->checkType->setTristate(false); + } +} + +void CEventFilterDialog::slot_typeSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->type->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->type->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckTypeState() +{ + if( ui->type->count() == ui->type->selectedItems().count() ) + { + if( Qt::Checked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->type->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::PartiallyChecked); + } + } +} + +void CEventFilterDialog::slot_updateDevice(const QString &subSystem) +{ + int nSubSystemId = -1; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(subSystem.toStdString() == info.strDesc) + { + nSubSystemId = info.nId; + } + } + } + + ui->deviceType->clear(); + QList values; + + if(nSubSystemId != -1) + { + kbd_dbms::CVarType subSystemId = nSubSystemId; + if(m_rtdbAccess->open("base", "dev_type_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CONDINFO condition; + condition.relationop = ATTRCOND_EQU; + memcpy(condition.name, "sub_system",strlen("sub_system")); + condition.conditionval = subSystemId; + std::vector columns; + columns.push_back("description"); + + kbd_dbms::CRdbQueryResult result; + if(m_rtdbAccess->select(condition, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, value); + values.append(value); + } + } + } + } + foreach (kbd_dbms::CVarType value, values) + { + ui->deviceType->addItem(value.c_str()); + } +} + +QString CEventFilterDialog::getDescByAreaId(int areaId) +{ + SAreaInfo info; + return m_areaInfoMap.value(areaId,info).stDes; +} + +void CEventFilterDialog::clearTreeSelection() +{ + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Unchecked); + slot_updateCheckLocationState(ui->area->topLevelItem(index),0); + } +} + +void CEventFilterDialog::childItemSelection(QTreeWidgetItem *item) +{ + Qt::CheckState status = item->checkState(0); + + int count = item->childCount(); + for(int index(0);indexchild(index)->setCheckState(0,status); + } +} + +void CEventFilterDialog::parentItemSelection(QTreeWidgetItem *item) +{ + QTreeWidgetItem *parent = item->parent(); + int count = parent->childCount(); + int checkNum = 0; + for(int index(0);indexchild(index)->checkState(0) == Qt::Checked) + { + checkNum += 1; + } + } + if(checkNum == count) + { + parent->setCheckState(0,Qt::Checked); + }else if(checkNum == 0) + { + parent->setCheckState(0,Qt::Unchecked); + }else + { + parent->setCheckState(0,Qt::PartiallyChecked); + } +} + +void CEventFilterDialog::allTreeSelection() +{ + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Checked); + slot_updateCheckLocationState(ui->area->topLevelItem(index),0); + } +} diff --git a/product/src/gui/plugin/EventWidget/CEventFilterDialog.h b/product/src/gui/plugin/EventWidget/CEventFilterDialog.h index d51fb7c7..c8a90beb 100644 --- a/product/src/gui/plugin/EventWidget/CEventFilterDialog.h +++ b/product/src/gui/plugin/EventWidget/CEventFilterDialog.h @@ -1,105 +1,105 @@ -#ifndef CEVENTFILTERDIALOG_H -#define CEVENTFILTERDIALOG_H - -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "CEventMsgInfo.h" -#include -#include -#include - -namespace Ui { -class CEventFilterDialog; -} - -class CEventFilterDialog : public QDialog -{ - Q_OBJECT - Q_PROPERTY(int windowMinWidth READ windowMinWidth WRITE setWindowMinWidth) - Q_PROPERTY(int windowMinHeigth READ windowMinHeigth WRITE setWindowMinHeigth) - -public slots: - int windowMinWidth(); - void setWindowMinWidth(int nWidth); - int windowMinHeigth(); - void setWindowMinHeigth(int nHeight); - -public: - explicit CEventFilterDialog(QWidget *parent = 0); - ~CEventFilterDialog(); - - void initialize(E_ALARM_VIEW view); - - void setLevelFilterEnable(const bool &isLevelFilterEnable); - void setLevelFilter(const QList &filter); - void setLocationFilterEnable(const bool &isLocationFilterEnable); - void setLocationFilter(const QList &filter); - void setRegionFilterEnable(const bool &isRegionFilterEnable); - void setRegionFilter(const QList &filter); - void setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable); - void setAlarmTypeFilter(const QList &filter); - void setDeviceFilterEnable(const bool &filter); - void setSubSystem(const QString &subSystem); - void setDeviceType(const QString &deviceType); - void setTimeFilterEnable(const bool &filter); - void setStartTimeFilter(const QDateTime &filter); - void setEndTimeFilter(const QDateTime &filter); - void setkeyWordFilterEnable(const bool &filter); - void setkeyWordFilteContent(const QString &content); - void setReturnFilterEnable(bool &filter); - void setReturnFilter(bool &filter); -signals: - /** - * @brief sig_updateFilter - * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm - */ - void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool); - -private slots: - void slot_updateFilter(); - - //Level - void slot_checkLevelPressed(); - void slot_levelSelectChange(const int &state); - void slot_updateCheckLevelState(); - - //Station - void slot_checkLocationPressed(); - void slot_locationSelectChange(const int &state); - void slot_updateCheckLocationState(QTreeWidgetItem *item, int column); - - //Region - void slot_checkRegionPressed(); - void slot_regionSelectChange(const int &state); - void slot_updateCheckRegionState(); - - //AlarmType - void slot_checkTypePressed(); - void slot_typeSelectChange(const int &state); - void slot_updateCheckTypeState(); - - //DeviceType - void slot_updateDevice(const QString &subSystem); - -private: - QString getDescByAreaId(int areaId); - void clearTreeSelection(); - void childItemSelection(QTreeWidgetItem *item); - void parentItemSelection(QTreeWidgetItem *item); - void allTreeSelection(); - -private: - Ui::CEventFilterDialog *ui; - kbd_dbms::CRdbAccess * m_rtdbAccess; - - QMap m_areaInfoMap; //区域信息 - - QMap > m_areaLocMap; //区域映射 - E_ALARM_VIEW m_view; - - int m_nMinWidth; - int m_nMinHeight; -}; - -#endif // CEVENTFILTERDIALOG_H +#ifndef CEVENTFILTERDIALOG_H +#define CEVENTFILTERDIALOG_H + +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "CEventMsgInfo.h" +#include +#include +#include + +namespace Ui { +class CEventFilterDialog; +} + +class CEventFilterDialog : public QDialog +{ + Q_OBJECT + Q_PROPERTY(int windowMinWidth READ windowMinWidth WRITE setWindowMinWidth) + Q_PROPERTY(int windowMinHeigth READ windowMinHeigth WRITE setWindowMinHeigth) + +public slots: + int windowMinWidth(); + void setWindowMinWidth(int nWidth); + int windowMinHeigth(); + void setWindowMinHeigth(int nHeight); + +public: + explicit CEventFilterDialog(QWidget *parent = 0); + ~CEventFilterDialog(); + + void initialize(E_ALARM_VIEW view); + + void setLevelFilterEnable(const bool &isLevelFilterEnable); + void setLevelFilter(const QList &filter); + void setLocationFilterEnable(const bool &isLocationFilterEnable); + void setLocationFilter(const QList &filter); + void setRegionFilterEnable(const bool &isRegionFilterEnable); + void setRegionFilter(const QList &filter); + void setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable); + void setAlarmTypeFilter(const QList &filter); + void setDeviceFilterEnable(const bool &filter); + void setSubSystem(const QString &subSystem); + void setDeviceType(const QString &deviceType); + void setTimeFilterEnable(const bool &filter); + void setStartTimeFilter(const QDateTime &filter); + void setEndTimeFilter(const QDateTime &filter); + void setkeyWordFilterEnable(const bool &filter); + void setkeyWordFilteContent(const QString &content); + void setReturnFilterEnable(bool &filter); + void setReturnFilter(bool &filter); +signals: + /** + * @brief sig_updateFilter + * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm + */ + void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool); + +private slots: + void slot_updateFilter(); + + //Level + void slot_checkLevelPressed(); + void slot_levelSelectChange(const int &state); + void slot_updateCheckLevelState(); + + //Station + void slot_checkLocationPressed(); + void slot_locationSelectChange(const int &state); + void slot_updateCheckLocationState(QTreeWidgetItem *item, int column); + + //Region + void slot_checkRegionPressed(); + void slot_regionSelectChange(const int &state); + void slot_updateCheckRegionState(); + + //AlarmType + void slot_checkTypePressed(); + void slot_typeSelectChange(const int &state); + void slot_updateCheckTypeState(); + + //DeviceType + void slot_updateDevice(const QString &subSystem); + +private: + QString getDescByAreaId(int areaId); + void clearTreeSelection(); + void childItemSelection(QTreeWidgetItem *item); + void parentItemSelection(QTreeWidgetItem *item); + void allTreeSelection(); + +private: + Ui::CEventFilterDialog *ui; + kbd_dbms::CRdbAccess * m_rtdbAccess; + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 + E_ALARM_VIEW m_view; + + int m_nMinWidth; + int m_nMinHeight; +}; + +#endif // CEVENTFILTERDIALOG_H diff --git a/product/src/gui/plugin/EventWidget/CEventFilterDialog.ui b/product/src/gui/plugin/EventWidget/CEventFilterDialog.ui index 4f6210f3..ce477fac 100644 --- a/product/src/gui/plugin/EventWidget/CEventFilterDialog.ui +++ b/product/src/gui/plugin/EventWidget/CEventFilterDialog.ui @@ -1,402 +1,402 @@ - - - CEventFilterDialog - - - - 0 - 0 - 570 - 421 - - - - - 530 - 0 - - - - - 16777215 - 16777215 - - - - 过滤 - - - - - - 时间 - - - true - - - false - - - - - - - - 开始时间 - - - - - - - - 2018 - 1 - 1 - - - - - 0 - 0 - 0 - 2000 - 1 - 1 - - - - - 2050 - 12 - 31 - - - - QDateTimeEdit::YearSection - - - yyyy/MM/dd hh:mm - - - - - - - - - - - 结束时间 - - - - - - - false - - - - 2018 - 1 - 1 - - - - - 0 - 0 - 0 - 2000 - 1 - 1 - - - - - 2050 - 12 - 31 - - - - yyyy/MM/dd hh:mm - - - false - - - - - - - - - - - - - - 优先级 - - - true - - - - - - 全选 - - - true - - - true - - - - - - - - - - - - - 位置 - - - true - - - - - - 全选 - - - true - - - - - - - QAbstractItemView::NoSelection - - - false - - - - 1 - - - - - - - - - - - 责任区 - - - true - - - - - - 全选 - - - true - - - - - - - - - - - - - 事件状态 - - - true - - - - - - 全选 - - - true - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 281 - 20 - - - - - - - - 确定 - - - - - - - 取消 - - - - - - - - - - - 设备类型 - - - true - - - false - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - - - - 事件内容关键字 - - - true - - - false - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - 复归 - - - true - - - false - - - - - - - 0 - 0 - - - - 已复归 - - - - - - - - 0 - 0 - - - - 未复归 - - - - - - - - - - - - - + + + CEventFilterDialog + + + + 0 + 0 + 570 + 421 + + + + + 530 + 0 + + + + + 16777215 + 16777215 + + + + 过滤 + + + + + + 时间 + + + true + + + false + + + + + + + + 开始时间 + + + + + + + + 2018 + 1 + 1 + + + + + 0 + 0 + 0 + 2000 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + QDateTimeEdit::YearSection + + + yyyy/MM/dd hh:mm + + + + + + + + + + + 结束时间 + + + + + + + false + + + + 2018 + 1 + 1 + + + + + 0 + 0 + 0 + 2000 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + yyyy/MM/dd hh:mm + + + false + + + + + + + + + + + + + + 优先级 + + + true + + + + + + 全选 + + + true + + + true + + + + + + + + + + + + + 位置 + + + true + + + + + + 全选 + + + true + + + + + + + QAbstractItemView::NoSelection + + + false + + + + 1 + + + + + + + + + + + 责任区 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + + 事件状态 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 281 + 20 + + + + + + + + 确定 + + + + + + + 取消 + + + + + + + + + + + 设备类型 + + + true + + + false + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + + + 事件内容关键字 + + + true + + + false + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + 复归 + + + true + + + false + + + + + + + 0 + 0 + + + + 已复归 + + + + + + + + 0 + 0 + + + + 未复归 + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/EventWidget/CEventForm.cpp b/product/src/gui/plugin/EventWidget/CEventForm.cpp index f83ef742..abafed2c 100644 --- a/product/src/gui/plugin/EventWidget/CEventForm.cpp +++ b/product/src/gui/plugin/EventWidget/CEventForm.cpp @@ -1,1591 +1,1591 @@ -#include "CEventForm.h" -#include "ui_CEventForm.h" -#include "CEventMsgInfo.h" -#include -#include "CEventItemModel.h" -#include "CEventHistoryModel.h" -#include "CEventFilterDialog.h" -#include "CEventMsgManage.h" -#include "CEventDataCollect.h" -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CEventDelegate.h" -#include "pub_utility_api/FileStyle.h" -#include -#include "pub_logger_api/logger.h" -#include "CAccidentReviewDialog.h" -#include "CEventDeviceTreeModel.h" -#include "CEventDeviceTreeItem.h" - -CEventForm::CEventForm(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CEventForm), - m_pRealDelegate(NULL), - m_pHistoryDelegate(NULL), - m_pRealTimeModel(NULL), - m_pHistoryModel(NULL), - m_pDeviceModel(NULL), - m_pDeviceHisModel(NULL), - m_isEditMode(editMode), - m_thread(NULL), - m_hisSearch(NULL), - m_enableWave(false), - m_isNeedAccidentReview(true), - m_buttonGroup(Q_NULLPTR), - m_ncurIndex(0), - m_strAccidenPath(QString()) -{ - qRegisterMetaType("CEventMsgInfo"); - qRegisterMetaType("EventMsgPtr"); - qRegisterMetaType >("SetEventMsgPtr"); - qRegisterMetaType("ST_FILTER"); - - ui->setupUi(this); - initilize(); - if(!m_isEditMode) - { - m_hisSearch = new QThread(); - m_hisWork = new CEventHisThread(); - m_hisWork->moveToThread(m_hisSearch); - connect(m_hisSearch,&QThread::started,m_hisWork,&CEventHisThread::init,Qt::QueuedConnection); - connect(m_hisSearch,&QThread::finished,m_hisWork,&CEventHisThread::deleteLater,Qt::QueuedConnection); - m_buttonGroup = new QButtonGroup; - m_buttonGroup->setExclusive(true); - m_buttonGroup->addButton(ui->realEventButton,0); - m_buttonGroup->addButton(ui->hisEventButton,1); - connect(m_buttonGroup,SIGNAL(buttonClicked(int)),this,SLOT(updateStack(int))); - m_hisSearch->start(); - initModel(); - updateStack(0); - - //< 放到构造函数中(打开两个窗口,关闭其中一个有问题) -// CEventDataCollect::instance()->initialize(); - - initFilter(); - - connect(CEventDataCollect::instance(), SIGNAL(sigEventStateChanged()), this, SLOT(slotRTEventStateChanged()), Qt::QueuedConnection); - connect(ui->clear, &QPushButton::clicked, this, &CEventForm::slotClearRTEvent); - connect(ui->closeBtn, &QPushButton::clicked, this, &CEventForm::closeBtnClicked); - } - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("event.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - { - //< 初始化实时设备树搜索框 - QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->treeView->header()); - m_pRealSearchEdit = new QLineEdit(ui->treeView->header()); - m_pRealSearchEdit->setObjectName("realSearchEdit"); - m_pRealSearchEdit->setTextMargins(0, 0, 21, 0); - m_pRealSearchEdit->setPlaceholderText(tr("按设备组关键字搜索")); - pHBoxLayout->addWidget(m_pRealSearchEdit); - pHBoxLayout->setContentsMargins(2,0,2,0); - pHBoxLayout->setSpacing(0); - ui->treeView->header()->setLayout(pHBoxLayout); - ui->treeView->header()->setObjectName("realDeviceHeader"); - m_pRealSearchButton = new QPushButton(this); - m_pRealSearchButton->setObjectName("realSearchButton"); - m_pRealSearchButton->setText(""); - m_pRealSearchButton->setMaximumSize(21, 22); - m_pRealSearchButton->setCursor(QCursor(Qt::ArrowCursor)); - QHBoxLayout * pSearchLayout = new QHBoxLayout(); - pSearchLayout->setContentsMargins(1, 1, 1, 1); - pSearchLayout->addStretch(); - pSearchLayout->addWidget(m_pRealSearchButton); - m_pRealSearchEdit->setLayout(pSearchLayout); - connect(m_pRealSearchEdit, &QLineEdit::returnPressed, this, &CEventForm::searchRealDeviceName); - connect(m_pRealSearchButton, &QPushButton::clicked, this, &CEventForm::searchRealDeviceName); - } - { - //< 初始化历史设备树搜索框 - QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->treeView_2->header()); - m_pHistorySearchEdit = new QLineEdit(ui->treeView_2->header()); - m_pHistorySearchEdit->setObjectName("hisSearchEdit"); - m_pHistorySearchEdit->setTextMargins(0, 0, 21, 0); - m_pHistorySearchEdit->setPlaceholderText(tr("按设备组关键字搜索")); - pHBoxLayout->addWidget(m_pHistorySearchEdit); - pHBoxLayout->setContentsMargins(2,0,2,0); - pHBoxLayout->setSpacing(0); - ui->treeView_2->header()->setLayout(pHBoxLayout); - ui->treeView_2->header()->setObjectName("hisDeviceHeader"); - m_pHistorySearchButton = new QPushButton(this); - m_pHistorySearchButton->setObjectName("hisSearchButton"); - m_pHistorySearchButton->setText(""); - m_pHistorySearchButton->setMaximumSize(21, 22); - m_pHistorySearchButton->setCursor(QCursor(Qt::ArrowCursor)); - QHBoxLayout * pSearchLayout = new QHBoxLayout(); - pSearchLayout->setContentsMargins(1, 1, 1, 1); - pSearchLayout->addStretch(); - pSearchLayout->addWidget(m_pHistorySearchButton); - m_pHistorySearchEdit->setLayout(pSearchLayout); - connect(m_pHistorySearchEdit, &QLineEdit::returnPressed, this, &CEventForm::searchHistoryDeviceName); - connect(m_pHistorySearchButton, &QPushButton::clicked, this, &CEventForm::searchHistoryDeviceName); - } - - m_timeIcon = new QPushButton(this); - m_myCalendar = new CMyCalendar(this); - QWidgetAction *widgetAction=new QWidgetAction(this); - m_timeMenu = new QMenu(this); - widgetAction->setDefaultWidget(m_myCalendar); - m_timeMenu->addAction(widgetAction); - m_timeIcon->setObjectName("iconButton"); - m_timeIcon->setText(""); - m_timeIcon->setMaximumSize(21, 22); - m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); - QHBoxLayout * pTimeLayout = new QHBoxLayout(); - pTimeLayout->setContentsMargins(1, 1, 1, 1); - pTimeLayout->addStretch(); - pTimeLayout->addWidget(m_timeIcon); - ui->lineEdit->setLayout(pTimeLayout); - connect(m_timeIcon,&QPushButton::clicked,this,&CEventForm::myCalendarShow); - connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CEventForm::myCalendarHide); - connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CEventForm::cancleTimeFilter); - ui->lineEdit->setText(tr("请选择时间")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit->setObjectName("iconLineEdit"); - ui->splitter->setStretchFactor(0,1); - ui->splitter->setStretchFactor(1,6); - ui->splitter_2->setStretchFactor(0,1); - ui->splitter_2->setStretchFactor(1,6); - - m_excelPrinter = new CExcelPrinter(); - m_thread = new QThread(); - m_excelPrinter->moveToThread(m_thread); - connect(m_thread,&QThread::started,m_excelPrinter,&CExcelPrinter::initialize); - connect(m_thread,&QThread::finished,m_excelPrinter,&CExcelPrinter::deleteLater); - connect(this,&CEventForm::printExcel,m_excelPrinter,&CExcelPrinter::printerByModel); - connect(this,&CEventForm::printExcelHis,m_excelPrinter,&CExcelPrinter::printerHisByModel); - connect(m_excelPrinter,&CExcelPrinter::sigShowResult,this,&CEventForm::slotShowResult); - m_thread->start(); - -} - -CEventForm::~CEventForm() -{ - CEventDataCollect::instance()->release(); - if(m_pRealTimeModel) - { - delete m_pRealTimeModel; - } - m_pRealTimeModel = Q_NULLPTR; - - if(m_pHistoryModel) - { - delete m_pHistoryModel; - } - m_pHistoryModel = Q_NULLPTR; - if(m_pRealDelegate) - { - delete m_pRealDelegate; - } - m_pRealDelegate = Q_NULLPTR; - if(m_pHistoryDelegate) - { - delete m_pHistoryDelegate; - } - m_pHistoryDelegate = Q_NULLPTR; - if(m_excelPrinter) - { - delete m_excelPrinter; - } - m_excelPrinter = Q_NULLPTR; - if(m_thread) - { - m_thread->quit(); - m_thread->wait(); - } - if(m_hisSearch) - { - m_hisSearch->quit(); - m_hisSearch->wait(); - } - - delete CEventDataCollect::instance(); - delete CEventMsgManage::instance(); - delete ui; - - qDebug() << "~CEventForm()"; -} - -void CEventForm::initilize() -{ - //< lingdaoyaoqiu - { - QSettings columFlags1("KBD_HMI", "eventReal config"); - if(!columFlags1.contains(QString("eventReal/colum_0"))) - { - columFlags1.setValue(QString("eventReal/colum_0"), false); //< 时间 - columFlags1.setValue(QString("eventReal/colum_1"), false); //< 优先级 - columFlags1.setValue(QString("eventReal/colum_2"), false); //< 位置 - columFlags1.setValue(QString("eventReal/colum_3"), true); //< 责任区 - columFlags1.setValue(QString("eventReal/colum_4"), true); //< 事件类型 - columFlags1.setValue(QString("eventReal/colum_5"), false); //< 事件状态 - columFlags1.setValue(QString("eventReal/colum_6"), false); //< 复归状态 - } - } - { - QSettings columFlags2("KBD_HMI", "eventHis config"); - if(!columFlags2.contains(QString("eventHis/colum_0"))) - { - // tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("复归状态")<< tr("专业")<< tr("设备组")<< tr("确认人")<< tr("确认时间")<< tr("点标签")<< tr("事件内容") ; - - columFlags2.setValue(QString("eventHis/colum_0"), false); //< 时间 - columFlags2.setValue(QString("eventHis/colum_1"), false); //< 优先级 - columFlags2.setValue(QString("eventHis/colum_2"), false); //< 位置 - columFlags2.setValue(QString("eventHis/colum_3"), true); //< 责任区 - columFlags2.setValue(QString("eventHis/colum_4"), true); //< 事件类型 - columFlags2.setValue(QString("eventHis/colum_5"), false); //< 事件状态 - columFlags2.setValue(QString("eventHis/colum_6"), false); //< 复归状态 - columFlags2.setValue(QString("eventHis/colum_7"), true); // - columFlags2.setValue(QString("eventHis/colum_8"), true); // - columFlags2.setValue(QString("eventHis/colum_9"), true); // - columFlags2.setValue(QString("eventHis/colum_10"),true); // - columFlags2.setValue(QString("eventHis/colum_11"),true); // - columFlags2.setValue(QString("eventHis/colum_12"),true); // - } - } - m_pListWidget1 = new CMyListWidget(this); - m_pListWidget2 = new CMyListWidget(this); - m_pListWidget3 = new CMyListWidget(this); - m_pLineEdit1 = new QLineEdit(this); - m_pLineEdit2 = new QLineEdit(this); - m_pLineEdit3 = new QLineEdit(this); - - ui->comboBox->setModel(m_pListWidget1->model()); - ui->comboBox->setView(m_pListWidget1); - ui->comboBox->setLineEdit(m_pLineEdit1); - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - m_pLineEdit1->setReadOnly(true); - connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 - ui->comboBox_2->setModel(m_pListWidget2->model()); - ui->comboBox_2->setView(m_pListWidget2); - ui->comboBox_2->setLineEdit(m_pLineEdit2); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - m_pLineEdit2->setReadOnly(true); - connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); - ui->comboBox_3->setModel(m_pListWidget3->model()); - ui->comboBox_3->setView(m_pListWidget3); - ui->comboBox_3->setLineEdit(m_pLineEdit3); - m_strText3 = tr("请选择告警状态"); - m_pLineEdit3->setText(tr("请选择告警状态")); - m_pLineEdit3->setReadOnly(true); - connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); -} - -void CEventForm::initModel() -{ - initHisModel(); - initRealModel(); - loadDeviceGroupFilterWidget(); -} - -void CEventForm::initHisModel() -{ - if(m_pHistoryDelegate == NULL) - { - m_pHistoryDelegate = new CEventDelegate(ui->eventView_2); - } - ui->eventView_2->setItemDelegate(m_pHistoryDelegate); - ui->eventView_2->setSortingEnabled(false); - if(NULL == m_pHistoryModel) - { - m_pHistoryModel = new CEventHistoryModel(this); - - connect(m_pHistoryModel, &CEventHistoryModel::sigPermInvalid, this, &CEventForm::slotPermInvalid,Qt::QueuedConnection); - connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventRequesting, this, &CEventForm::slotUpdateHISTipsRequesting,Qt::QueuedConnection); - if(m_hisSearch != NULL) - { - connect(m_pHistoryModel, &CEventHistoryModel::requestHistory, m_hisWork,&CEventHisThread::doWork,Qt::QueuedConnection); - connect(m_hisWork, &CEventHisThread::sigUpdateHisEvent, m_pHistoryModel, &CEventHistoryModel::updateEvents, Qt::QueuedConnection); - } - connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventSizeChanged, this, &CEventForm::slotUpdateHISTips,Qt::QueuedConnection); - connect(m_pHistoryModel, &CEventHistoryModel::sigHISRecordOutOfRangeTips, this, &CEventForm::slotHISRecordOutOfRangeTips,Qt::QueuedConnection); - connect(m_pHistoryModel, &CEventHistoryModel::sigOutOfRangeTips, this, &CEventForm::slotHisOutOfRangeTips,Qt::QueuedConnection); - - } - ui->eventView_2->setModel(m_pHistoryModel); - m_pHistoryDelegate->setHisEventModel(m_pHistoryModel); - ui->eventView_2->setColumnWidth(8, 250); - QSettings columFlags2("KBD_HMI", "eventHis config"); - for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount() - 1; nColumnIndex++) - { - bool visible = columFlags2.value(QString("eventHis/colum_%1").arg(nColumnIndex)).toBool(); - ui->eventView_2->setColumnHidden(nColumnIndex, visible); - } - ui->eventView_2->setColumnHidden(m_pHistoryModel->columnCount() - 1, false); - ui->eventView_2->setColumnWidth(0, 250); - ui->eventView_2->setColumnWidth(1, 150); - ui->eventView_2->setColumnWidth(2, 150); - ui->eventView_2->setColumnWidth(3, 150); - ui->eventView_2->setColumnWidth(4, 150); - ui->eventView_2->setColumnWidth(5, 150); - ui->eventView_2->setColumnWidth(6, 150); - ui->eventView_2->setColumnWidth(7, 150); - ui->eventView_2->setColumnWidth(8, 150); - ui->eventView_2->setColumnWidth(9, 150); - ui->eventView_2->setColumnWidth(10, 150); - ui->eventView_2->setColumnWidth(11, 250); - ui->eventView_2->setColumnWidth(12, 350); - slotUpdateHISTips(); - - if(m_pDeviceHisModel == NULL) - { - m_pDeviceHisModel = new CEventDeviceTreeModel(this); - ui->treeView_2->setModel(m_pDeviceHisModel); - - connect(m_pDeviceHisModel, &CEventDeviceTreeModel::itemCheckStateChanged, this, &CEventForm::hisDeviceGroupFilterChanged); - if(m_hisSearch != NULL) - { - connect(m_hisWork, &CEventHisThread::sigUpdateHisEvent, this, &CEventForm::updateHisDeviceGroupHiddenState, Qt::QueuedConnection); - } - } -} - -void CEventForm::initRealModel() -{ - if(m_pRealDelegate == NULL) - { - m_pRealDelegate = new CEventDelegate(this); - ui->eventView->setItemDelegate(m_pRealDelegate); - } - ui->eventView->setSortingEnabled(true); - if(NULL == m_pRealTimeModel) - { - m_pRealTimeModel = new CEventItemModel(this); - connect(ui->eventView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pRealTimeModel, SLOT(sortColumn(int,Qt::SortOrder))); - ui->eventView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); - } - ui->eventView->setModel(m_pRealTimeModel); - m_pRealDelegate->setEventModel(m_pRealTimeModel); - QSettings columFlags1("KBD_HMI", "eventReal config"); - for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount() - 1; nColumnIndex++) - { - bool visible = columFlags1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool(); - ui->eventView->setColumnHidden(nColumnIndex, visible); - } - ui->eventView->setColumnHidden(m_pRealTimeModel->columnCount() - 1, false); - ui->eventView->setColumnWidth(0, 250); - ui->eventView->setColumnWidth(1, 150); - ui->eventView->setColumnWidth(2, 150); - ui->eventView->setColumnWidth(3, 150); - ui->eventView->setColumnWidth(4, 150); - ui->eventView->setColumnWidth(5, 150); - slotUpdateRTTips(); - - if(m_pDeviceModel == NULL) - { - m_pDeviceModel = new CEventDeviceTreeModel(this); - ui->treeView->setModel(m_pDeviceModel); - - connect(m_pDeviceModel, &CEventDeviceTreeModel::itemCheckStateChanged, this, &CEventForm::deviceGroupFilterChanged); - connect(CEventDataCollect::instance(),&CEventDataCollect::sigDevTreeUpdate,m_pDeviceModel,&CEventDeviceTreeModel::slotDevTreeUpdate); - connect(CEventDataCollect::instance(),&CEventDataCollect::sigDevTreeUpdate,this,&CEventForm::updateDeviceGroupHiddenState); - } -} - -void CEventForm::login() -{ - if(!m_isEditMode) - { - CEventDataCollect::instance()->release(); - if(m_pRealTimeModel) - { - m_pRealTimeModel->initialize(); - } - if(m_pHistoryModel) - { - m_pHistoryModel->initialize(); - } - if(m_pRealDelegate == NULL) - { - m_pRealDelegate = new CEventDelegate(ui->eventView); - m_pRealDelegate->setEventModel(m_pRealTimeModel); - } - if(m_pHistoryDelegate == NULL) - { - m_pHistoryDelegate = new CEventDelegate(ui->eventView_2); - m_pHistoryDelegate->setHisEventModel(m_pHistoryModel); - } - CEventDataCollect::instance()->initialize(); - initFilter(); - if(ui->hisEventButton->isChecked()) - { - m_pHistoryModel->loadEventHistoryData(); - slotUpdateHISTips(); - } - } -} - -void CEventForm::logout() -{ - if(!m_isEditMode) - { - CEventDataCollect::instance()->release(); - } -} - -void CEventForm::slotShowResult(QString result) -{ - Q_UNUSED(result); - QMessageBox::information( 0, tr("提示"), tr("导出成功")); -} - -void CEventForm::setHiddenLocation(bool hide) -{ - ui->label_2->setHidden(hide); - ui->comboBox_2->setHidden(hide); -} - -void CEventForm::setHiddenTime(bool hide) -{ - ui->label_4->setHidden(hide); - ui->lineEdit->setHidden(hide); -} - -void CEventForm::setHiddenStatus(bool hide) -{ - ui->label_3->setHidden(hide); - ui->comboBox_3->setHidden(hide); -} - -void CEventForm::setHiddenPriority(bool hide) -{ - ui->label->setHidden(hide); - ui->comboBox->setHidden(hide); -} - -void CEventForm::setHiddenCloseButton(bool hide) -{ - ui->closeBtn->setHidden(hide); -} - -void CEventForm::setRowHeight(int height) -{ - if(ui->eventView != Q_NULLPTR) - { - ui->eventView->setDefaultRowHeight(height); - } - if(ui->eventView_2 != Q_NULLPTR) - { - ui->eventView_2->setDefaultRowHeight(height); - } -} - -void CEventForm::setColumnWidth(const int &column, const int &width) -{ - if(column<0 ||column >=9) - { - return ; - } - - if(column < 7) - { - if(ui->eventView != Q_NULLPTR) - { - ui->eventView->setColumnWidth(column, width); - } - if(ui->eventView_2 != Q_NULLPTR) - { - ui->eventView_2->setColumnWidth(column, width); - } - }else if(column >= 7) - { - if(ui->eventView_2 != Q_NULLPTR) - { - ui->eventView_2->setColumnWidth(column, width); - } - } -} - -void CEventForm::setColumnVisible(const int &column, const bool &visible) -{ - if(ui->eventView != Q_NULLPTR) - { - ui->eventView->setColumnHidden(column, !visible); - } -} - -void CEventForm::setHisColumnWidth(const int &column, const int &width) -{ - if(ui->eventView_2 != Q_NULLPTR) - { - ui->eventView_2->setColumnWidth(column, width); - } -} - -void CEventForm::setHisColumnVisible(const int &column, const bool &visible) -{ - if(ui->eventView_2 != Q_NULLPTR) - { - ui->eventView_2->setColumnHidden(column, !visible); - } -} - -void CEventForm::setEnableAccidentReview(bool isNeed) -{ - m_isNeedAccidentReview = isNeed; -} - -void CEventForm::setEnableWave(bool isNeed) -{ - if(m_pRealDelegate) - { - m_pRealDelegate->setEnableWave(isNeed); - } - if(m_pHistoryDelegate) - { - m_pHistoryDelegate->setEnableWave(isNeed); - } -} - -void CEventForm::setAccidentReviewPath(const QString &path) -{ - m_strAccidenPath = path; -} - -void CEventForm::initFilter() -{ - m_pListWidget1->clear(); - m_pListWidget2->clear(); - m_pListWidget3->clear(); - QMap priority = CEventDataCollect::instance()->priorityDescriptionMap(); - QMap alarmStatus = CEventDataCollect::instance()->eventShowStatusDescriptionMap(); - for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); - pItem->setData(Qt::UserRole, it1.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it1.value()); - m_pListWidget1->addItem(pItem); - m_pListWidget1->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); - } - QList locOrder = CEventDataCollect::instance()->locationOrderList(); - foreach (const int &locId, locOrder) { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); - pItem->setData(Qt::UserRole, locId); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(CEventDataCollect::instance()->locationDescription(locId)); - m_pListWidget2->addItem(pItem); - m_pListWidget2->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); - } - for(QMap::iterator it3 = alarmStatus.begin();it3 != alarmStatus.end();++it3) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); - pItem->setData(Qt::UserRole, it3.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it3.value()); - m_pListWidget3->addItem(pItem); - m_pListWidget3->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); - } - if(m_pDeviceModel) - { - m_pDeviceModel->setAllDeviceCheckState(Qt::Checked); - } - if(m_pDeviceHisModel) - { - m_pDeviceHisModel->setAllDeviceCheckState(Qt::Checked); - } -} - -void CEventForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) -{ - if(isLevelFilter == true && listLevel.size() > 0) - { - QString strText(""); - for (int i = 0; i < ui->comboBox->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listLevel.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText1 = strText; - m_pLineEdit1->setText(strText); - }else - { - for (int i = 0; i < ui->comboBox->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - } -} - -void CEventForm::setLocationComboBox(bool &isLocationFilter, QList &listLocation) -{ - if(isLocationFilter == true && listLocation.size() > 0) - { - QString strText(""); - for (int i = 0; i < ui->comboBox_2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listLocation.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText2 = strText; - m_pLineEdit2->setText(strText); - }else - { - for (int i = 0; i < ui->comboBox_2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - } -} - -void CEventForm::setEventStatusComboBox(bool &isEventStatusFilter, QList &listEventStatus) -{ - if(isEventStatusFilter == true && listEventStatus.size() > 0) - { - QString strText(""); - for (int i = 0; i < ui->comboBox_3->count(); ++i) - { - - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listEventStatus.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText3 = strText; - m_pLineEdit3->setText(strText); - }else - { - for (int i = 0; i < ui->comboBox_3->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText3 = tr("请选择事件状态"); - m_pLineEdit3->setText(tr("请选择事件状态")); - } -} - -void CEventForm::setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) -{ - if(isTimeFilter == true) - { - ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); - }else - { - ui->lineEdit->setText(tr("请选择时间")); - } -} - -void CEventForm::slotClearRTEvent() -{ - CEventDataCollect::instance()->handleClearRTEvent(); -} - -void CEventForm::deviceGroupFilterChanged(const QString &device, const bool &checked) -{ - if(checked) - { - if(m_pRealTimeModel) - { - m_pRealTimeModel->addDeviceGroupFilter(device); - } - } - else - { - if(m_pRealTimeModel) - { - m_pRealTimeModel->removeDeviceGroupFilter(device); - } - } -} - -void CEventForm::hisDeviceGroupFilterChanged(const QString &device, const bool &checked) -{ - if(checked) - { - if(m_pHistoryModel) - { - m_pHistoryModel->addDeviceGroupFilter(device); - m_pHistoryModel->updateShowEvents(); - } - } - else - { - if(m_pHistoryModel) - { - m_pHistoryModel->removeDeviceGroupFilter(device); - m_pHistoryModel->updateShowEvents(); - } - } -} - -void CEventForm::updateFilter() -{ - CEventFilterDialog filterDlg(this); - bool isLevelFilter; - QList levelFilter; - bool isLocationFilter; - QList locationFilter; - bool isRegionFilter; - QList regionFilter; - bool isAlarmTypeFilter; - QList typeFilter; - bool deviceTypeFilter; - QString subSystem; - QString deviceType; - bool keywordFilter; - QString keyword; - bool isTimeFilterEnable; - QDateTime startTime; - QDateTime endTime; - bool isReturnFilterEnable; - bool isReturn; - if(ui->realEventButton->isChecked()) - { - m_pRealTimeModel->getFilter(isLevelFilter, levelFilter, - isLocationFilter, locationFilter, - isRegionFilter, regionFilter, - isAlarmTypeFilter, typeFilter, - deviceTypeFilter, subSystem, deviceType, - keywordFilter, keyword, - isTimeFilterEnable, startTime, endTime,isReturnFilterEnable,isReturn); - filterDlg.initialize(E_ALARM_REAL_EVENT); - } - else if(ui->hisEventButton->isChecked()) - { - m_pHistoryModel->getFilter(isLevelFilter, levelFilter, - isLocationFilter, locationFilter, - isRegionFilter, regionFilter, - isAlarmTypeFilter, typeFilter, - deviceTypeFilter, subSystem, deviceType, - keywordFilter, keyword, - isTimeFilterEnable, startTime, endTime,isReturnFilterEnable,isReturn); - filterDlg.initialize(E_ALARM_HIS_EVENT); - } - - filterDlg.setLevelFilterEnable(isLevelFilter); - filterDlg.setLevelFilter(levelFilter); - filterDlg.setLocationFilterEnable(isLocationFilter); - filterDlg.setLocationFilter(locationFilter); - filterDlg.setRegionFilterEnable(isRegionFilter); - filterDlg.setRegionFilter(regionFilter); - filterDlg.setAlarmTypeFilterEnable(isAlarmTypeFilter); - filterDlg.setAlarmTypeFilter(typeFilter); - filterDlg.setDeviceFilterEnable(deviceTypeFilter); - filterDlg.setSubSystem(subSystem); - filterDlg.setDeviceType(deviceType); - filterDlg.setkeyWordFilterEnable(keywordFilter); - filterDlg.setkeyWordFilteContent(keyword); - filterDlg.setTimeFilterEnable(isTimeFilterEnable); - filterDlg.setStartTimeFilter(startTime); - filterDlg.setEndTimeFilter(endTime); - filterDlg.setReturnFilterEnable(isReturnFilterEnable);; - filterDlg.setReturnFilter(isReturn); - connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool)), - this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool))); - filterDlg.exec(); -} - -void CEventForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventStatusFilter, QList listEventStatus, - bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isReturnFilter, bool isReturn) -{ - if(ui->realEventButton->isChecked()) - { - m_pRealTimeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventStatusFilter, listEventStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime,isReturnFilter,isReturn); - setLevelComboBox(isLevelFilter,listLevel); - setLocationComboBox(isLocationFilter,listLocation); - setEventStatusComboBox(isEventStatusFilter,listEventStatus); - setEventTimeLineEdit(isTimeFilter, startTime, endTime); - slotUpdateRTTips(); - } - else if(ui->hisEventButton->isChecked()) - { - m_pHistoryModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventStatusFilter, listEventStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime,isReturnFilter,isReturn); - setLevelComboBox(isLevelFilter,listLevel); - setLocationComboBox(isLocationFilter,listLocation); - setEventStatusComboBox(isEventStatusFilter,listEventStatus); - setEventTimeLineEdit(isTimeFilter, startTime, endTime); - m_pHistoryModel->loadEventHistoryData(); - } -} - -void CEventForm::slotRTEventStateChanged() -{ - if(dynamic_cast(ui->eventView->model())) - { - slotUpdateRTTips(); - } -} - -void CEventForm::slotUpdateRTTips() -{ - ui->typeLabel->setText(tr("实时事件总数:")); - if(m_pRealTimeModel) - { - ui->eventCount->setText(QString::number(CEventMsgManage::instance()->getListEventCount())); - } -} - -void CEventForm::slotUpdateHISTipsRequesting() -{ - ui->typeLabel_2->setText(tr("正在查询历史事件...")); - ui->eventCount_2->setText(""); - ui->label_his_tip->setText(""); -} - -void CEventForm::slotPermInvalid() -{ - QMessageBox::critical(this, tr("错误"), tr("当前用户不具备事件浏览权限"), QMessageBox::Ok); -} - -void CEventForm::slotUpdateHISTips() -{ - ui->typeLabel_2->setText(tr("历史事件数量:")); - if(m_pHistoryModel) - { - int count = m_pHistoryModel->rowCount(); - ui->eventCount_2->setText(QString::number(count)); - if(count >= LIMIT_HIS_RECORD) - { - ui->label_his_tip->setText(tr("历史事件数量超出10000条,超出部分不显示")); - }else - { - ui->label_his_tip->setText(""); - } - - } -} - -void CEventForm::slotHISRecordOutOfRangeTips(QStringList stDescList) -{ - QString stMess = ""; - for( int index(0);index!=stDescList.size() ; ++index ) - { - stMess += stDescList.at(index); - if(index != stDescList.size()-1) - stMess += "/"; - } - if(stDescList.size() != 0) - { - QMessageBox::information(this, tr("提示"), - QString(tr("历史事件数量超出%1条,未予显示!")).arg(LIMIT_HIS_RECORD), - QMessageBox::Ok); - } -} - -void CEventForm::slotHisOutOfRangeTips() -{ - QMessageBox::information(this, tr("提示"), - QString(tr("历史事件数量超出%1条,未予显示!")).arg(LIMIT_HIS_RECORD), - QMessageBox::Ok); -} - -void CEventForm::print() -{ - QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"*.xlsx");//获取保存路径*.xls - if(!fileName.isEmpty()) - { - if(ui->realEventButton->isChecked()) - { - if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) - fileName = fileName + ".xlsx"; - emit printExcel(m_pRealTimeModel,fileName); - }else if(ui->hisEventButton->isChecked()) - { - if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) - fileName = fileName + ".xlsx"; - emit printExcelHis(m_pHistoryModel,fileName); - } - } -} - -void CEventForm::stateChanged1(int state) -{ - Q_UNUSED(state); - QString strText(""); - m_priorityList.clear(); - int nCount = m_pListWidget1->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_priorityList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText1 = strText; - m_pLineEdit1->setText(strText); - } - else - { - m_pLineEdit1->clear(); - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - } - bool isCheck = false; - if(ui->realEventButton->isChecked()) - { - if(m_priorityList.size() == 0) - { - m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); - }else - { - isCheck = true; - m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); - } - } - else if(ui->hisEventButton->isChecked()) - { - if(m_priorityList.size() == 0) - { - m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); - }else - { - isCheck = true; - m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); - } - m_pHistoryModel->loadEventHistoryData(); - } -} - -void CEventForm::stateChanged2(int state) -{ - Q_UNUSED(state); - QString strText(""); - m_locationList.clear(); - int nCount = m_pListWidget2->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_locationList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText2 = strText; - m_pLineEdit2->setText(strText); - } - else - { - m_pLineEdit2->clear(); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - } - bool isCheck = false; - if(ui->realEventButton->isChecked()) - { - if(m_locationList.size() == 0) - { - m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); - }else - { - isCheck = true; - m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); - } - } - else if(ui->hisEventButton->isChecked()) - { - if(m_locationList.size() == 0) - { - m_pHistoryModel->setLocationFilter(isCheck,m_locationList); - }else - { - isCheck = true; - m_pHistoryModel->setLocationFilter(isCheck,m_locationList); - } - m_pHistoryModel->loadEventHistoryData(); - } -} - -void CEventForm::stateChanged3(int state) -{ - Q_UNUSED(state); - QString strText(""); - m_eventStatusList.clear(); - bool other = false; - int nCount = m_pListWidget3->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - if(nData == OTHERSTATUS) - { - other = true; - } - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_eventStatusList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText3 = strText; - m_pLineEdit3->setText(strText); - } - else - { - m_pLineEdit3->clear(); - m_strText3 = tr("请选择事件状态"); - m_pLineEdit3->setText(tr("请选择事件状态")); - } - bool isCheck = false; - if(ui->realEventButton->isChecked()) - { - if(m_eventStatusList.size() == 0) - { - m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventStatusList,other); - }else - { - isCheck = true; - m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventStatusList,other); - } - } - else if(ui->hisEventButton->isChecked()) - { - if(m_eventStatusList.size() == 0) - { - m_pHistoryModel->setEventTypeFilter(isCheck,m_eventStatusList,other); - }else - { - isCheck = true; - m_pHistoryModel->setEventTypeFilter(isCheck,m_eventStatusList,other); - } - m_pHistoryModel->loadEventHistoryData(); - } -} - -void CEventForm::textChanged1(const QString &text) -{ - Q_UNUSED(text); - m_pLineEdit1->setText(m_strText1); -} - -void CEventForm::textChanged2(const QString &text) -{ - Q_UNUSED(text); - m_pLineEdit2->setText(m_strText2); -} - -void CEventForm::textChanged3(const QString &text) -{ - Q_UNUSED(text); - m_pLineEdit3->setText(m_strText3); -} - -void CEventForm::myCalendarHide(QDate startTime, QDate endTime) -{ - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); - //开始过滤 - bool isCheck = false; - if(ui->realEventButton->isChecked()) - { - isCheck = true; - m_pRealTimeModel->setEventTimeFilter(isCheck,startTime,endTime); - }else if(ui->hisEventButton->isChecked()) - { - isCheck = true; - m_pHistoryModel->setEventTimeFilter(isCheck,startTime,endTime); - m_pHistoryModel->loadEventHistoryData(); - } - m_timeMenu->hide(); -} - -void CEventForm::myCalendarShow() -{ - QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); - if(ui->realEventButton->isChecked()) - { - m_myCalendar->setView(E_ALARM_REAL_EVENT); - }else if(ui->hisEventButton->isChecked()) - { - m_myCalendar->setView(E_ALARM_HIS_EVENT); - } - - m_timeMenu->move(point); - m_timeMenu->show(); -} - -void CEventForm::cancleTimeFilter() -{ - ui->lineEdit->setText(tr("请选择时间")); - //取消过滤 - bool isCheck = false; - if(ui->realEventButton->isChecked()) - { - m_pRealTimeModel->setEventTimeFilter(isCheck); - }else if(ui->hisEventButton->isChecked()) - { - m_pHistoryModel->setEventTimeFilter(isCheck); - m_pHistoryModel->loadEventHistoryData(); - } - m_timeMenu->hide(); -} - -void CEventForm::searchRealDeviceName() -{ - QItemSelection selection; - QString content = m_pRealSearchEdit->text(); - ui->treeView->selectionModel()->select(selection, QItemSelectionModel::Clear); - if(content.isEmpty()) - { - return; - } - const QHash< QString, QModelIndex > &indexNameList = m_pDeviceModel->indexNameList(); - QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); - while (iter != indexNameList.constEnd()) - { - if(ui->treeView->isRowHidden(iter.value().row(), iter.value().parent())) - { - iter++; - continue; - } - if(iter.key().section(".", 1).contains(content, Qt::CaseInsensitive)) - { - selection.append(QItemSelectionRange(iter.value(), iter.value())); - selection.append(QItemSelectionRange(iter.value().parent(), iter.value().parent())); - } - iter++; - } - ui->treeView->selectionModel()->select(selection, QItemSelectionModel::Select); -} - -void CEventForm::searchHistoryDeviceName() -{ - QItemSelection selection; - QString content = m_pHistorySearchEdit->text(); - ui->treeView_2->selectionModel()->select(selection, QItemSelectionModel::Clear); - if(content.isEmpty()) - { - return; - } - const QHash< QString, QModelIndex > &indexNameList = m_pDeviceHisModel->indexNameList(); - QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); - while (iter != indexNameList.constEnd()) - { - if(ui->treeView_2->isRowHidden(iter.value().row(), iter.value().parent())) - { - iter++; - continue; - } - if(iter.key().section(".", 1).contains(content, Qt::CaseInsensitive)) - { - selection.append(QItemSelectionRange(iter.value(), iter.value())); - selection.append(QItemSelectionRange(iter.value().parent(), iter.value().parent())); - } - iter++; - } - ui->treeView_2->selectionModel()->select(selection, QItemSelectionModel::Select); -} - -void CEventForm::contextMenuEvent(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - if(ui->realEventButton->isChecked()) - { - contextMenuRealEvent(event); - }else if(ui->hisEventButton->isChecked()) - { - contextMenuHisEvent(event); - } -} - -void CEventForm::contextMenuRealEvent(QContextMenuEvent *event) -{ - if(event->pos().x() < ui->eventView->pos().x()) - { - return; - } - QRect headerRect = ui->eventView->horizontalHeader()->rect(); - headerRect.moveTopLeft(ui->eventView->mapTo(this, QPoint())); - if(headerRect.contains(event->pos())) - { - QMenu columnMenu(this); - for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount()-1; nColumnIndex++) - { - QAction * action = columnMenu.addAction(m_pRealTimeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); - action->setCheckable(true); - action->setChecked(!ui->eventView->isColumnHidden(nColumnIndex)); - - connect(action, &QAction::triggered, [=](){ - - ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags1("KBD_HMI", "eventReal config"); - columFlags1.setValue(QString("eventReal/colum_%1").arg(nColumnIndex), !action->isChecked()); - }); - } - columnMenu.exec(QCursor::pos()); - }else - { - QModelIndex index_ = ui->eventView->indexAt(ui->eventView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index_.isValid()) - { - return; - } - QMenu menu(this); - QModelIndex index = ui->eventView->currentIndex(); - if(!index.isValid()) - { - return ; - } - QModelIndexList indexLists = ui->eventView->selectionModel()->selectedIndexes(); - - //判断右键位置是否在选中区 - if(!indexLists.contains(index)) - { - ui->eventView->clearSelection(); - ui->eventView->setCurrentIndex(index); - } - - if(m_isNeedAccidentReview) - { - QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); - connect(accidentReviewAction,&QAction::triggered,[=](){ - rightAccidentReviewReal(); - }); - } - menu.exec(QCursor::pos()); - } -} - -void CEventForm::contextMenuHisEvent(QContextMenuEvent *event) -{ - if(event->pos().x() < ui->eventView_2->pos().x()) - { - return; - } - QRect headerRect = ui->eventView_2->horizontalHeader()->rect(); - headerRect.moveTopLeft(ui->eventView_2->mapTo(this, QPoint())); - if(headerRect.contains(event->pos())) - { - QMenu columnMenu(this); - for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount()-1; nColumnIndex++) - { - QAction * action = columnMenu.addAction(m_pHistoryModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); - action->setCheckable(true); - action->setChecked(!ui->eventView_2->isColumnHidden(nColumnIndex)); - connect(action, &QAction::triggered, [=](){ - ui->eventView_2->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags2("KBD_HMI", "eventHis config"); - columFlags2.setValue(QString("eventHis/colum_%1").arg(nColumnIndex), !action->isChecked()); - }); - } - columnMenu.exec(QCursor::pos()); - }else - { - QModelIndex index_ = ui->eventView_2->indexAt(ui->eventView_2->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index_.isValid()) - { - return; - } - QMenu menu(this); - QModelIndex index = ui->eventView_2->currentIndex(); - if(!index.isValid()) - { - return ; - } - QModelIndexList indexLists = ui->eventView_2->selectionModel()->selectedIndexes(); - - //判断右键位置是否在选中区 - if(!indexLists.contains(index)) - { - ui->eventView_2->clearSelection(); - ui->eventView_2->setCurrentIndex(index); - } - - if(m_isNeedAccidentReview) - { - QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); - connect(accidentReviewAction,&QAction::triggered,[=](){ - rightAccidentReviewHis(); - }); - } - menu.exec(QCursor::pos()); - } -} - -void CEventForm::loadDeviceGroupFilterWidget() -{ - if(!m_pDeviceModel && !m_pDeviceHisModel) - { - return; - } - - kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); - if(!objReader.open()) - { - LOGERROR("load deviceGroup info error, database open failed, %s", objReader.getLastErrorString().toStdString().c_str()); - return; - } - - QMap< int, QVector< QPair< QString, QString > > > locationInfos; - - QList locationList = CEventDataCollect::instance()->locationOrderList(); - for(int nIndex(0); nIndex > dev; - - QSqlQuery query; - QString sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1;").arg(locationList[nIndex]); - if(objReader.execute(sqlSequenceQuery, query)) - { - while(query.next()) - { - dev.append(qMakePair(query.value(0).toString(), query.value(1).toString())); - } - locationInfos.insert(locationList[nIndex], dev); - }else - { - LOGERROR("load device info error, dbInterface execute failed!"); - } - } - if(m_pDeviceModel) - { - m_pDeviceModel->removeData(); - m_pDeviceModel->setupModelData(locationInfos,locationList); - updateDeviceGroupHiddenState(); - ui->treeView->expandAll(); - } - if(m_pDeviceHisModel) - { - m_pDeviceHisModel->removeData(); - m_pDeviceHisModel->setupModelData(locationInfos,locationList); - updateHisDeviceGroupHiddenState(QList()); - ui->treeView_2->expandAll(); - } -} - -void CEventForm::updateDeviceGroupHiddenState() -{ - QHash listDeviceStatisticalInfo = m_pDeviceModel->getDeviceStatisticalInfo(); - for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) - { - QModelIndex topLevelIndex = m_pDeviceModel->index(nTopLevelRow, 0); - for(int nChildRow(0); nChildRow < m_pDeviceModel->rowCount(topLevelIndex); nChildRow++) - { - CEventDeviceTreeItem *item = static_cast(m_pDeviceModel->index(nChildRow, 0, topLevelIndex).internalPointer()); - ui->treeView->setRowHidden(nChildRow, topLevelIndex, !listDeviceStatisticalInfo.value(item->data(Qt::UserRole).toString(), 0)); - } - } -} - -void CEventForm::updateHisDeviceGroupHiddenState(QList eventList) -{ - m_pDeviceHisModel->slotHisDevTreeUpdate(eventList); - - QHash listDeviceStatisticalInfo = m_pDeviceHisModel->getDeviceStatisticalInfo(); - for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceHisModel->rowCount(); nTopLevelRow++) - { - QModelIndex topLevelIndex = m_pDeviceHisModel->index(nTopLevelRow, 0); - for(int nChildRow(0); nChildRow < m_pDeviceHisModel->rowCount(topLevelIndex); nChildRow++) - { - CEventDeviceTreeItem *item = static_cast(m_pDeviceHisModel->index(nChildRow, 0, topLevelIndex).internalPointer()); - ui->treeView_2->setRowHidden(nChildRow, topLevelIndex, !listDeviceStatisticalInfo.value(item->data(Qt::UserRole).toString(), 0)); - } - } -} - -void CEventForm::updateStack(int index) -{ - if(m_ncurIndex == index) - { - return ; - } - if(index==0) - { - bool isLevelFilterEnable = false; - QList priorityFilterList; - m_pRealTimeModel->getPriorityFilter(isLevelFilterEnable,priorityFilterList); - - bool isLocationFilterEnable = false; - QList locationFilterList; - m_pRealTimeModel->getLocationFilter(isLocationFilterEnable,locationFilterList); - - bool isStatusFilterEnable = false; - QList statusFilterList; - m_pRealTimeModel->getEventStatusFilter(isStatusFilterEnable,statusFilterList); - - bool timeFilterEnable = false; - QDateTime startTime; - QDateTime endTime; - m_pRealTimeModel->getEventTimeFilter(timeFilterEnable,startTime,endTime); - - setLevelComboBox(isLevelFilterEnable,priorityFilterList); - setLocationComboBox(isLocationFilterEnable,locationFilterList); - setEventStatusComboBox(isStatusFilterEnable,statusFilterList); - setEventTimeLineEdit(timeFilterEnable, startTime, endTime); - ui->clear->setEnabled(true); - m_ncurIndex = index; - ui->eventStackWidget->setCurrentIndex(0); - }else if(index == 1) - { - bool isLevelFilterEnable = false; - QList priorityFilterList; - m_pHistoryModel->getPriorityFilter(isLevelFilterEnable,priorityFilterList); - - bool isLocationFilterEnable = false; - QList locationFilterList; - m_pHistoryModel->getLocationFilter(isLocationFilterEnable,locationFilterList); - - bool isStatusFilterEnable = false; - QList statusFilterList; - m_pHistoryModel->getEventStatusFilter(isStatusFilterEnable,statusFilterList); - - setLevelComboBox(isLevelFilterEnable,priorityFilterList); - setLocationComboBox(isLocationFilterEnable,locationFilterList); - setEventStatusComboBox(isStatusFilterEnable,statusFilterList); - QDate startData = QDate::currentDate().addDays(-6); - QDate endData = QDate::currentDate(); - bool check = true; - m_pHistoryModel->setEventTimeFilter(check,startData,endData); - ui->lineEdit->setText(startData.toString("yyyy-MM-dd")+"~"+endData.toString("yyyy-MM-dd")); - m_pHistoryModel->loadEventHistoryData(); - ui->clear->setEnabled(false); - m_ncurIndex = index; - ui->eventStackWidget->setCurrentIndex(1); - } -} - -void CEventForm::rightAccidentReviewReal() -{ - QModelIndex index = ui->eventView->currentIndex(); - if(!index.isValid()) - { - return ; - } - QList listInfo = m_pRealTimeModel->getListEventInfo(); - EventMsgPtr info = listInfo.at(index.row()); - if(info != NULL) - { - CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); - if(dialog->exec() == QDialog::Accepted) - { - emit openAccidentReviewDialog(info->time_stamp-30000,30000*2,dialog->getCurrentGraph()); - } - delete dialog; - dialog = NULL; - } -} - -void CEventForm::rightAccidentReviewHis() -{ - QModelIndex index = ui->eventView_2->currentIndex(); - if(!index.isValid()) - { - return ; - } - QList listInfo = m_pHistoryModel->getListEventInfo(); - EventMsgPtr info = listInfo.at(index.row()); - if(info != NULL) - { - CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); - if(dialog->exec() == QDialog::Accepted) - { - emit openAccidentReviewDialog(info->time_stamp-30000,30000*2,dialog->getCurrentGraph()); - } - delete dialog; - dialog = NULL; - } -} +#include "CEventForm.h" +#include "ui_CEventForm.h" +#include "CEventMsgInfo.h" +#include +#include "CEventItemModel.h" +#include "CEventHistoryModel.h" +#include "CEventFilterDialog.h" +#include "CEventMsgManage.h" +#include "CEventDataCollect.h" +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CEventDelegate.h" +#include "pub_utility_api/FileStyle.h" +#include +#include "pub_logger_api/logger.h" +#include "CAccidentReviewDialog.h" +#include "CEventDeviceTreeModel.h" +#include "CEventDeviceTreeItem.h" + +CEventForm::CEventForm(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CEventForm), + m_pRealDelegate(NULL), + m_pHistoryDelegate(NULL), + m_pRealTimeModel(NULL), + m_pHistoryModel(NULL), + m_pDeviceModel(NULL), + m_pDeviceHisModel(NULL), + m_isEditMode(editMode), + m_thread(NULL), + m_hisSearch(NULL), + m_enableWave(false), + m_isNeedAccidentReview(true), + m_buttonGroup(Q_NULLPTR), + m_ncurIndex(0), + m_strAccidenPath(QString()) +{ + qRegisterMetaType("CEventMsgInfo"); + qRegisterMetaType("EventMsgPtr"); + qRegisterMetaType >("SetEventMsgPtr"); + qRegisterMetaType("ST_FILTER"); + + ui->setupUi(this); + initilize(); + if(!m_isEditMode) + { + m_hisSearch = new QThread(); + m_hisWork = new CEventHisThread(); + m_hisWork->moveToThread(m_hisSearch); + connect(m_hisSearch,&QThread::started,m_hisWork,&CEventHisThread::init,Qt::QueuedConnection); + connect(m_hisSearch,&QThread::finished,m_hisWork,&CEventHisThread::deleteLater,Qt::QueuedConnection); + m_buttonGroup = new QButtonGroup; + m_buttonGroup->setExclusive(true); + m_buttonGroup->addButton(ui->realEventButton,0); + m_buttonGroup->addButton(ui->hisEventButton,1); + connect(m_buttonGroup,SIGNAL(buttonClicked(int)),this,SLOT(updateStack(int))); + m_hisSearch->start(); + initModel(); + updateStack(0); + + //< 放到构造函数中(打开两个窗口,关闭其中一个有问题) +// CEventDataCollect::instance()->initialize(); + + initFilter(); + + connect(CEventDataCollect::instance(), SIGNAL(sigEventStateChanged()), this, SLOT(slotRTEventStateChanged()), Qt::QueuedConnection); + connect(ui->clear, &QPushButton::clicked, this, &CEventForm::slotClearRTEvent); + connect(ui->closeBtn, &QPushButton::clicked, this, &CEventForm::closeBtnClicked); + } + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("event.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + { + //< 初始化实时设备树搜索框 + QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->treeView->header()); + m_pRealSearchEdit = new QLineEdit(ui->treeView->header()); + m_pRealSearchEdit->setObjectName("realSearchEdit"); + m_pRealSearchEdit->setTextMargins(0, 0, 21, 0); + m_pRealSearchEdit->setPlaceholderText(tr("按设备组关键字搜索")); + pHBoxLayout->addWidget(m_pRealSearchEdit); + pHBoxLayout->setContentsMargins(2,0,2,0); + pHBoxLayout->setSpacing(0); + ui->treeView->header()->setLayout(pHBoxLayout); + ui->treeView->header()->setObjectName("realDeviceHeader"); + m_pRealSearchButton = new QPushButton(this); + m_pRealSearchButton->setObjectName("realSearchButton"); + m_pRealSearchButton->setText(""); + m_pRealSearchButton->setMaximumSize(21, 22); + m_pRealSearchButton->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pSearchLayout = new QHBoxLayout(); + pSearchLayout->setContentsMargins(1, 1, 1, 1); + pSearchLayout->addStretch(); + pSearchLayout->addWidget(m_pRealSearchButton); + m_pRealSearchEdit->setLayout(pSearchLayout); + connect(m_pRealSearchEdit, &QLineEdit::returnPressed, this, &CEventForm::searchRealDeviceName); + connect(m_pRealSearchButton, &QPushButton::clicked, this, &CEventForm::searchRealDeviceName); + } + { + //< 初始化历史设备树搜索框 + QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->treeView_2->header()); + m_pHistorySearchEdit = new QLineEdit(ui->treeView_2->header()); + m_pHistorySearchEdit->setObjectName("hisSearchEdit"); + m_pHistorySearchEdit->setTextMargins(0, 0, 21, 0); + m_pHistorySearchEdit->setPlaceholderText(tr("按设备组关键字搜索")); + pHBoxLayout->addWidget(m_pHistorySearchEdit); + pHBoxLayout->setContentsMargins(2,0,2,0); + pHBoxLayout->setSpacing(0); + ui->treeView_2->header()->setLayout(pHBoxLayout); + ui->treeView_2->header()->setObjectName("hisDeviceHeader"); + m_pHistorySearchButton = new QPushButton(this); + m_pHistorySearchButton->setObjectName("hisSearchButton"); + m_pHistorySearchButton->setText(""); + m_pHistorySearchButton->setMaximumSize(21, 22); + m_pHistorySearchButton->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pSearchLayout = new QHBoxLayout(); + pSearchLayout->setContentsMargins(1, 1, 1, 1); + pSearchLayout->addStretch(); + pSearchLayout->addWidget(m_pHistorySearchButton); + m_pHistorySearchEdit->setLayout(pSearchLayout); + connect(m_pHistorySearchEdit, &QLineEdit::returnPressed, this, &CEventForm::searchHistoryDeviceName); + connect(m_pHistorySearchButton, &QPushButton::clicked, this, &CEventForm::searchHistoryDeviceName); + } + + m_timeIcon = new QPushButton(this); + m_myCalendar = new CMyCalendar(this); + QWidgetAction *widgetAction=new QWidgetAction(this); + m_timeMenu = new QMenu(this); + widgetAction->setDefaultWidget(m_myCalendar); + m_timeMenu->addAction(widgetAction); + m_timeIcon->setObjectName("iconButton"); + m_timeIcon->setText(""); + m_timeIcon->setMaximumSize(21, 22); + m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_timeIcon); + ui->lineEdit->setLayout(pTimeLayout); + connect(m_timeIcon,&QPushButton::clicked,this,&CEventForm::myCalendarShow); + connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CEventForm::myCalendarHide); + connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CEventForm::cancleTimeFilter); + ui->lineEdit->setText(tr("请选择时间")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit->setObjectName("iconLineEdit"); + ui->splitter->setStretchFactor(0,1); + ui->splitter->setStretchFactor(1,6); + ui->splitter_2->setStretchFactor(0,1); + ui->splitter_2->setStretchFactor(1,6); + + m_excelPrinter = new CExcelPrinter(); + m_thread = new QThread(); + m_excelPrinter->moveToThread(m_thread); + connect(m_thread,&QThread::started,m_excelPrinter,&CExcelPrinter::initialize); + connect(m_thread,&QThread::finished,m_excelPrinter,&CExcelPrinter::deleteLater); + connect(this,&CEventForm::printExcel,m_excelPrinter,&CExcelPrinter::printerByModel); + connect(this,&CEventForm::printExcelHis,m_excelPrinter,&CExcelPrinter::printerHisByModel); + connect(m_excelPrinter,&CExcelPrinter::sigShowResult,this,&CEventForm::slotShowResult); + m_thread->start(); + +} + +CEventForm::~CEventForm() +{ + CEventDataCollect::instance()->release(); + if(m_pRealTimeModel) + { + delete m_pRealTimeModel; + } + m_pRealTimeModel = Q_NULLPTR; + + if(m_pHistoryModel) + { + delete m_pHistoryModel; + } + m_pHistoryModel = Q_NULLPTR; + if(m_pRealDelegate) + { + delete m_pRealDelegate; + } + m_pRealDelegate = Q_NULLPTR; + if(m_pHistoryDelegate) + { + delete m_pHistoryDelegate; + } + m_pHistoryDelegate = Q_NULLPTR; + if(m_excelPrinter) + { + delete m_excelPrinter; + } + m_excelPrinter = Q_NULLPTR; + if(m_thread) + { + m_thread->quit(); + m_thread->wait(); + } + if(m_hisSearch) + { + m_hisSearch->quit(); + m_hisSearch->wait(); + } + + delete CEventDataCollect::instance(); + delete CEventMsgManage::instance(); + delete ui; + + qDebug() << "~CEventForm()"; +} + +void CEventForm::initilize() +{ + //< lingdaoyaoqiu + { + QSettings columFlags1("KBD_HMI", "eventReal config"); + if(!columFlags1.contains(QString("eventReal/colum_0"))) + { + columFlags1.setValue(QString("eventReal/colum_0"), false); //< 时间 + columFlags1.setValue(QString("eventReal/colum_1"), false); //< 优先级 + columFlags1.setValue(QString("eventReal/colum_2"), false); //< 位置 + columFlags1.setValue(QString("eventReal/colum_3"), true); //< 责任区 + columFlags1.setValue(QString("eventReal/colum_4"), true); //< 事件类型 + columFlags1.setValue(QString("eventReal/colum_5"), false); //< 事件状态 + columFlags1.setValue(QString("eventReal/colum_6"), false); //< 复归状态 + } + } + { + QSettings columFlags2("KBD_HMI", "eventHis config"); + if(!columFlags2.contains(QString("eventHis/colum_0"))) + { + // tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("复归状态")<< tr("专业")<< tr("设备组")<< tr("确认人")<< tr("确认时间")<< tr("点标签")<< tr("事件内容") ; + + columFlags2.setValue(QString("eventHis/colum_0"), false); //< 时间 + columFlags2.setValue(QString("eventHis/colum_1"), false); //< 优先级 + columFlags2.setValue(QString("eventHis/colum_2"), false); //< 位置 + columFlags2.setValue(QString("eventHis/colum_3"), true); //< 责任区 + columFlags2.setValue(QString("eventHis/colum_4"), true); //< 事件类型 + columFlags2.setValue(QString("eventHis/colum_5"), false); //< 事件状态 + columFlags2.setValue(QString("eventHis/colum_6"), false); //< 复归状态 + columFlags2.setValue(QString("eventHis/colum_7"), true); // + columFlags2.setValue(QString("eventHis/colum_8"), true); // + columFlags2.setValue(QString("eventHis/colum_9"), true); // + columFlags2.setValue(QString("eventHis/colum_10"),true); // + columFlags2.setValue(QString("eventHis/colum_11"),true); // + columFlags2.setValue(QString("eventHis/colum_12"),true); // + } + } + m_pListWidget1 = new CMyListWidget(this); + m_pListWidget2 = new CMyListWidget(this); + m_pListWidget3 = new CMyListWidget(this); + m_pLineEdit1 = new QLineEdit(this); + m_pLineEdit2 = new QLineEdit(this); + m_pLineEdit3 = new QLineEdit(this); + + ui->comboBox->setModel(m_pListWidget1->model()); + ui->comboBox->setView(m_pListWidget1); + ui->comboBox->setLineEdit(m_pLineEdit1); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + m_pLineEdit1->setReadOnly(true); + connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 + ui->comboBox_2->setModel(m_pListWidget2->model()); + ui->comboBox_2->setView(m_pListWidget2); + ui->comboBox_2->setLineEdit(m_pLineEdit2); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + m_pLineEdit2->setReadOnly(true); + connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); + ui->comboBox_3->setModel(m_pListWidget3->model()); + ui->comboBox_3->setView(m_pListWidget3); + ui->comboBox_3->setLineEdit(m_pLineEdit3); + m_strText3 = tr("请选择告警状态"); + m_pLineEdit3->setText(tr("请选择告警状态")); + m_pLineEdit3->setReadOnly(true); + connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); +} + +void CEventForm::initModel() +{ + initHisModel(); + initRealModel(); + loadDeviceGroupFilterWidget(); +} + +void CEventForm::initHisModel() +{ + if(m_pHistoryDelegate == NULL) + { + m_pHistoryDelegate = new CEventDelegate(ui->eventView_2); + } + ui->eventView_2->setItemDelegate(m_pHistoryDelegate); + ui->eventView_2->setSortingEnabled(false); + if(NULL == m_pHistoryModel) + { + m_pHistoryModel = new CEventHistoryModel(this); + + connect(m_pHistoryModel, &CEventHistoryModel::sigPermInvalid, this, &CEventForm::slotPermInvalid,Qt::QueuedConnection); + connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventRequesting, this, &CEventForm::slotUpdateHISTipsRequesting,Qt::QueuedConnection); + if(m_hisSearch != NULL) + { + connect(m_pHistoryModel, &CEventHistoryModel::requestHistory, m_hisWork,&CEventHisThread::doWork,Qt::QueuedConnection); + connect(m_hisWork, &CEventHisThread::sigUpdateHisEvent, m_pHistoryModel, &CEventHistoryModel::updateEvents, Qt::QueuedConnection); + } + connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventSizeChanged, this, &CEventForm::slotUpdateHISTips,Qt::QueuedConnection); + connect(m_pHistoryModel, &CEventHistoryModel::sigHISRecordOutOfRangeTips, this, &CEventForm::slotHISRecordOutOfRangeTips,Qt::QueuedConnection); + connect(m_pHistoryModel, &CEventHistoryModel::sigOutOfRangeTips, this, &CEventForm::slotHisOutOfRangeTips,Qt::QueuedConnection); + + } + ui->eventView_2->setModel(m_pHistoryModel); + m_pHistoryDelegate->setHisEventModel(m_pHistoryModel); + ui->eventView_2->setColumnWidth(8, 250); + QSettings columFlags2("KBD_HMI", "eventHis config"); + for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount() - 1; nColumnIndex++) + { + bool visible = columFlags2.value(QString("eventHis/colum_%1").arg(nColumnIndex)).toBool(); + ui->eventView_2->setColumnHidden(nColumnIndex, visible); + } + ui->eventView_2->setColumnHidden(m_pHistoryModel->columnCount() - 1, false); + ui->eventView_2->setColumnWidth(0, 250); + ui->eventView_2->setColumnWidth(1, 150); + ui->eventView_2->setColumnWidth(2, 150); + ui->eventView_2->setColumnWidth(3, 150); + ui->eventView_2->setColumnWidth(4, 150); + ui->eventView_2->setColumnWidth(5, 150); + ui->eventView_2->setColumnWidth(6, 150); + ui->eventView_2->setColumnWidth(7, 150); + ui->eventView_2->setColumnWidth(8, 150); + ui->eventView_2->setColumnWidth(9, 150); + ui->eventView_2->setColumnWidth(10, 150); + ui->eventView_2->setColumnWidth(11, 250); + ui->eventView_2->setColumnWidth(12, 350); + slotUpdateHISTips(); + + if(m_pDeviceHisModel == NULL) + { + m_pDeviceHisModel = new CEventDeviceTreeModel(this); + ui->treeView_2->setModel(m_pDeviceHisModel); + + connect(m_pDeviceHisModel, &CEventDeviceTreeModel::itemCheckStateChanged, this, &CEventForm::hisDeviceGroupFilterChanged); + if(m_hisSearch != NULL) + { + connect(m_hisWork, &CEventHisThread::sigUpdateHisEvent, this, &CEventForm::updateHisDeviceGroupHiddenState, Qt::QueuedConnection); + } + } +} + +void CEventForm::initRealModel() +{ + if(m_pRealDelegate == NULL) + { + m_pRealDelegate = new CEventDelegate(this); + ui->eventView->setItemDelegate(m_pRealDelegate); + } + ui->eventView->setSortingEnabled(true); + if(NULL == m_pRealTimeModel) + { + m_pRealTimeModel = new CEventItemModel(this); + connect(ui->eventView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pRealTimeModel, SLOT(sortColumn(int,Qt::SortOrder))); + ui->eventView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + } + ui->eventView->setModel(m_pRealTimeModel); + m_pRealDelegate->setEventModel(m_pRealTimeModel); + QSettings columFlags1("KBD_HMI", "eventReal config"); + for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount() - 1; nColumnIndex++) + { + bool visible = columFlags1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool(); + ui->eventView->setColumnHidden(nColumnIndex, visible); + } + ui->eventView->setColumnHidden(m_pRealTimeModel->columnCount() - 1, false); + ui->eventView->setColumnWidth(0, 250); + ui->eventView->setColumnWidth(1, 150); + ui->eventView->setColumnWidth(2, 150); + ui->eventView->setColumnWidth(3, 150); + ui->eventView->setColumnWidth(4, 150); + ui->eventView->setColumnWidth(5, 150); + slotUpdateRTTips(); + + if(m_pDeviceModel == NULL) + { + m_pDeviceModel = new CEventDeviceTreeModel(this); + ui->treeView->setModel(m_pDeviceModel); + + connect(m_pDeviceModel, &CEventDeviceTreeModel::itemCheckStateChanged, this, &CEventForm::deviceGroupFilterChanged); + connect(CEventDataCollect::instance(),&CEventDataCollect::sigDevTreeUpdate,m_pDeviceModel,&CEventDeviceTreeModel::slotDevTreeUpdate); + connect(CEventDataCollect::instance(),&CEventDataCollect::sigDevTreeUpdate,this,&CEventForm::updateDeviceGroupHiddenState); + } +} + +void CEventForm::login() +{ + if(!m_isEditMode) + { + CEventDataCollect::instance()->release(); + if(m_pRealTimeModel) + { + m_pRealTimeModel->initialize(); + } + if(m_pHistoryModel) + { + m_pHistoryModel->initialize(); + } + if(m_pRealDelegate == NULL) + { + m_pRealDelegate = new CEventDelegate(ui->eventView); + m_pRealDelegate->setEventModel(m_pRealTimeModel); + } + if(m_pHistoryDelegate == NULL) + { + m_pHistoryDelegate = new CEventDelegate(ui->eventView_2); + m_pHistoryDelegate->setHisEventModel(m_pHistoryModel); + } + CEventDataCollect::instance()->initialize(); + initFilter(); + if(ui->hisEventButton->isChecked()) + { + m_pHistoryModel->loadEventHistoryData(); + slotUpdateHISTips(); + } + } +} + +void CEventForm::logout() +{ + if(!m_isEditMode) + { + CEventDataCollect::instance()->release(); + } +} + +void CEventForm::slotShowResult(QString result) +{ + Q_UNUSED(result); + QMessageBox::information( 0, tr("提示"), tr("导出成功")); +} + +void CEventForm::setHiddenLocation(bool hide) +{ + ui->label_2->setHidden(hide); + ui->comboBox_2->setHidden(hide); +} + +void CEventForm::setHiddenTime(bool hide) +{ + ui->label_4->setHidden(hide); + ui->lineEdit->setHidden(hide); +} + +void CEventForm::setHiddenStatus(bool hide) +{ + ui->label_3->setHidden(hide); + ui->comboBox_3->setHidden(hide); +} + +void CEventForm::setHiddenPriority(bool hide) +{ + ui->label->setHidden(hide); + ui->comboBox->setHidden(hide); +} + +void CEventForm::setHiddenCloseButton(bool hide) +{ + ui->closeBtn->setHidden(hide); +} + +void CEventForm::setRowHeight(int height) +{ + if(ui->eventView != Q_NULLPTR) + { + ui->eventView->setDefaultRowHeight(height); + } + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setDefaultRowHeight(height); + } +} + +void CEventForm::setColumnWidth(const int &column, const int &width) +{ + if(column<0 ||column >=9) + { + return ; + } + + if(column < 7) + { + if(ui->eventView != Q_NULLPTR) + { + ui->eventView->setColumnWidth(column, width); + } + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setColumnWidth(column, width); + } + }else if(column >= 7) + { + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setColumnWidth(column, width); + } + } +} + +void CEventForm::setColumnVisible(const int &column, const bool &visible) +{ + if(ui->eventView != Q_NULLPTR) + { + ui->eventView->setColumnHidden(column, !visible); + } +} + +void CEventForm::setHisColumnWidth(const int &column, const int &width) +{ + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setColumnWidth(column, width); + } +} + +void CEventForm::setHisColumnVisible(const int &column, const bool &visible) +{ + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setColumnHidden(column, !visible); + } +} + +void CEventForm::setEnableAccidentReview(bool isNeed) +{ + m_isNeedAccidentReview = isNeed; +} + +void CEventForm::setEnableWave(bool isNeed) +{ + if(m_pRealDelegate) + { + m_pRealDelegate->setEnableWave(isNeed); + } + if(m_pHistoryDelegate) + { + m_pHistoryDelegate->setEnableWave(isNeed); + } +} + +void CEventForm::setAccidentReviewPath(const QString &path) +{ + m_strAccidenPath = path; +} + +void CEventForm::initFilter() +{ + m_pListWidget1->clear(); + m_pListWidget2->clear(); + m_pListWidget3->clear(); + QMap priority = CEventDataCollect::instance()->priorityDescriptionMap(); + QMap alarmStatus = CEventDataCollect::instance()->eventShowStatusDescriptionMap(); + for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); + pItem->setData(Qt::UserRole, it1.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it1.value()); + m_pListWidget1->addItem(pItem); + m_pListWidget1->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); + } + QList locOrder = CEventDataCollect::instance()->locationOrderList(); + foreach (const int &locId, locOrder) { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); + pItem->setData(Qt::UserRole, locId); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(CEventDataCollect::instance()->locationDescription(locId)); + m_pListWidget2->addItem(pItem); + m_pListWidget2->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); + } + for(QMap::iterator it3 = alarmStatus.begin();it3 != alarmStatus.end();++it3) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); + pItem->setData(Qt::UserRole, it3.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it3.value()); + m_pListWidget3->addItem(pItem); + m_pListWidget3->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); + } + if(m_pDeviceModel) + { + m_pDeviceModel->setAllDeviceCheckState(Qt::Checked); + } + if(m_pDeviceHisModel) + { + m_pDeviceHisModel->setAllDeviceCheckState(Qt::Checked); + } +} + +void CEventForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) +{ + if(isLevelFilter == true && listLevel.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLevel.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText1 = strText; + m_pLineEdit1->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } +} + +void CEventForm::setLocationComboBox(bool &isLocationFilter, QList &listLocation) +{ + if(isLocationFilter == true && listLocation.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox_2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLocation.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText2 = strText; + m_pLineEdit2->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox_2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } +} + +void CEventForm::setEventStatusComboBox(bool &isEventStatusFilter, QList &listEventStatus) +{ + if(isEventStatusFilter == true && listEventStatus.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox_3->count(); ++i) + { + + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listEventStatus.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText3 = strText; + m_pLineEdit3->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox_3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText3 = tr("请选择事件状态"); + m_pLineEdit3->setText(tr("请选择事件状态")); + } +} + +void CEventForm::setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) +{ + if(isTimeFilter == true) + { + ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); + }else + { + ui->lineEdit->setText(tr("请选择时间")); + } +} + +void CEventForm::slotClearRTEvent() +{ + CEventDataCollect::instance()->handleClearRTEvent(); +} + +void CEventForm::deviceGroupFilterChanged(const QString &device, const bool &checked) +{ + if(checked) + { + if(m_pRealTimeModel) + { + m_pRealTimeModel->addDeviceGroupFilter(device); + } + } + else + { + if(m_pRealTimeModel) + { + m_pRealTimeModel->removeDeviceGroupFilter(device); + } + } +} + +void CEventForm::hisDeviceGroupFilterChanged(const QString &device, const bool &checked) +{ + if(checked) + { + if(m_pHistoryModel) + { + m_pHistoryModel->addDeviceGroupFilter(device); + m_pHistoryModel->updateShowEvents(); + } + } + else + { + if(m_pHistoryModel) + { + m_pHistoryModel->removeDeviceGroupFilter(device); + m_pHistoryModel->updateShowEvents(); + } + } +} + +void CEventForm::updateFilter() +{ + CEventFilterDialog filterDlg(this); + bool isLevelFilter; + QList levelFilter; + bool isLocationFilter; + QList locationFilter; + bool isRegionFilter; + QList regionFilter; + bool isAlarmTypeFilter; + QList typeFilter; + bool deviceTypeFilter; + QString subSystem; + QString deviceType; + bool keywordFilter; + QString keyword; + bool isTimeFilterEnable; + QDateTime startTime; + QDateTime endTime; + bool isReturnFilterEnable; + bool isReturn; + if(ui->realEventButton->isChecked()) + { + m_pRealTimeModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmTypeFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime,isReturnFilterEnable,isReturn); + filterDlg.initialize(E_ALARM_REAL_EVENT); + } + else if(ui->hisEventButton->isChecked()) + { + m_pHistoryModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmTypeFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime,isReturnFilterEnable,isReturn); + filterDlg.initialize(E_ALARM_HIS_EVENT); + } + + filterDlg.setLevelFilterEnable(isLevelFilter); + filterDlg.setLevelFilter(levelFilter); + filterDlg.setLocationFilterEnable(isLocationFilter); + filterDlg.setLocationFilter(locationFilter); + filterDlg.setRegionFilterEnable(isRegionFilter); + filterDlg.setRegionFilter(regionFilter); + filterDlg.setAlarmTypeFilterEnable(isAlarmTypeFilter); + filterDlg.setAlarmTypeFilter(typeFilter); + filterDlg.setDeviceFilterEnable(deviceTypeFilter); + filterDlg.setSubSystem(subSystem); + filterDlg.setDeviceType(deviceType); + filterDlg.setkeyWordFilterEnable(keywordFilter); + filterDlg.setkeyWordFilteContent(keyword); + filterDlg.setTimeFilterEnable(isTimeFilterEnable); + filterDlg.setStartTimeFilter(startTime); + filterDlg.setEndTimeFilter(endTime); + filterDlg.setReturnFilterEnable(isReturnFilterEnable);; + filterDlg.setReturnFilter(isReturn); + connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool)), + this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool))); + filterDlg.exec(); +} + +void CEventForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventStatusFilter, QList listEventStatus, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isReturnFilter, bool isReturn) +{ + if(ui->realEventButton->isChecked()) + { + m_pRealTimeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventStatusFilter, listEventStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime,isReturnFilter,isReturn); + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setEventStatusComboBox(isEventStatusFilter,listEventStatus); + setEventTimeLineEdit(isTimeFilter, startTime, endTime); + slotUpdateRTTips(); + } + else if(ui->hisEventButton->isChecked()) + { + m_pHistoryModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventStatusFilter, listEventStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime,isReturnFilter,isReturn); + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setEventStatusComboBox(isEventStatusFilter,listEventStatus); + setEventTimeLineEdit(isTimeFilter, startTime, endTime); + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::slotRTEventStateChanged() +{ + if(dynamic_cast(ui->eventView->model())) + { + slotUpdateRTTips(); + } +} + +void CEventForm::slotUpdateRTTips() +{ + ui->typeLabel->setText(tr("实时事件总数:")); + if(m_pRealTimeModel) + { + ui->eventCount->setText(QString::number(CEventMsgManage::instance()->getListEventCount())); + } +} + +void CEventForm::slotUpdateHISTipsRequesting() +{ + ui->typeLabel_2->setText(tr("正在查询历史事件...")); + ui->eventCount_2->setText(""); + ui->label_his_tip->setText(""); +} + +void CEventForm::slotPermInvalid() +{ + QMessageBox::critical(this, tr("错误"), tr("当前用户不具备事件浏览权限"), QMessageBox::Ok); +} + +void CEventForm::slotUpdateHISTips() +{ + ui->typeLabel_2->setText(tr("历史事件数量:")); + if(m_pHistoryModel) + { + int count = m_pHistoryModel->rowCount(); + ui->eventCount_2->setText(QString::number(count)); + if(count >= LIMIT_HIS_RECORD) + { + ui->label_his_tip->setText(tr("历史事件数量超出10000条,超出部分不显示")); + }else + { + ui->label_his_tip->setText(""); + } + + } +} + +void CEventForm::slotHISRecordOutOfRangeTips(QStringList stDescList) +{ + QString stMess = ""; + for( int index(0);index!=stDescList.size() ; ++index ) + { + stMess += stDescList.at(index); + if(index != stDescList.size()-1) + stMess += "/"; + } + if(stDescList.size() != 0) + { + QMessageBox::information(this, tr("提示"), + QString(tr("历史事件数量超出%1条,未予显示!")).arg(LIMIT_HIS_RECORD), + QMessageBox::Ok); + } +} + +void CEventForm::slotHisOutOfRangeTips() +{ + QMessageBox::information(this, tr("提示"), + QString(tr("历史事件数量超出%1条,未予显示!")).arg(LIMIT_HIS_RECORD), + QMessageBox::Ok); +} + +void CEventForm::print() +{ + QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"*.xlsx");//获取保存路径*.xls + if(!fileName.isEmpty()) + { + if(ui->realEventButton->isChecked()) + { + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + fileName = fileName + ".xlsx"; + emit printExcel(m_pRealTimeModel,fileName); + }else if(ui->hisEventButton->isChecked()) + { + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + fileName = fileName + ".xlsx"; + emit printExcelHis(m_pHistoryModel,fileName); + } + } +} + +void CEventForm::stateChanged1(int state) +{ + Q_UNUSED(state); + QString strText(""); + m_priorityList.clear(); + int nCount = m_pListWidget1->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_priorityList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText1 = strText; + m_pLineEdit1->setText(strText); + } + else + { + m_pLineEdit1->clear(); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + if(m_priorityList.size() == 0) + { + m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); + }else + { + isCheck = true; + m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); + } + } + else if(ui->hisEventButton->isChecked()) + { + if(m_priorityList.size() == 0) + { + m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); + }else + { + isCheck = true; + m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::stateChanged2(int state) +{ + Q_UNUSED(state); + QString strText(""); + m_locationList.clear(); + int nCount = m_pListWidget2->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_locationList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText2 = strText; + m_pLineEdit2->setText(strText); + } + else + { + m_pLineEdit2->clear(); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + if(m_locationList.size() == 0) + { + m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); + }else + { + isCheck = true; + m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); + } + } + else if(ui->hisEventButton->isChecked()) + { + if(m_locationList.size() == 0) + { + m_pHistoryModel->setLocationFilter(isCheck,m_locationList); + }else + { + isCheck = true; + m_pHistoryModel->setLocationFilter(isCheck,m_locationList); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::stateChanged3(int state) +{ + Q_UNUSED(state); + QString strText(""); + m_eventStatusList.clear(); + bool other = false; + int nCount = m_pListWidget3->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + if(nData == OTHERSTATUS) + { + other = true; + } + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_eventStatusList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText3 = strText; + m_pLineEdit3->setText(strText); + } + else + { + m_pLineEdit3->clear(); + m_strText3 = tr("请选择事件状态"); + m_pLineEdit3->setText(tr("请选择事件状态")); + } + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + if(m_eventStatusList.size() == 0) + { + m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventStatusList,other); + }else + { + isCheck = true; + m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventStatusList,other); + } + } + else if(ui->hisEventButton->isChecked()) + { + if(m_eventStatusList.size() == 0) + { + m_pHistoryModel->setEventTypeFilter(isCheck,m_eventStatusList,other); + }else + { + isCheck = true; + m_pHistoryModel->setEventTypeFilter(isCheck,m_eventStatusList,other); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::textChanged1(const QString &text) +{ + Q_UNUSED(text); + m_pLineEdit1->setText(m_strText1); +} + +void CEventForm::textChanged2(const QString &text) +{ + Q_UNUSED(text); + m_pLineEdit2->setText(m_strText2); +} + +void CEventForm::textChanged3(const QString &text) +{ + Q_UNUSED(text); + m_pLineEdit3->setText(m_strText3); +} + +void CEventForm::myCalendarHide(QDate startTime, QDate endTime) +{ + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); + //开始过滤 + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + isCheck = true; + m_pRealTimeModel->setEventTimeFilter(isCheck,startTime,endTime); + }else if(ui->hisEventButton->isChecked()) + { + isCheck = true; + m_pHistoryModel->setEventTimeFilter(isCheck,startTime,endTime); + m_pHistoryModel->loadEventHistoryData(); + } + m_timeMenu->hide(); +} + +void CEventForm::myCalendarShow() +{ + QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); + if(ui->realEventButton->isChecked()) + { + m_myCalendar->setView(E_ALARM_REAL_EVENT); + }else if(ui->hisEventButton->isChecked()) + { + m_myCalendar->setView(E_ALARM_HIS_EVENT); + } + + m_timeMenu->move(point); + m_timeMenu->show(); +} + +void CEventForm::cancleTimeFilter() +{ + ui->lineEdit->setText(tr("请选择时间")); + //取消过滤 + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + m_pRealTimeModel->setEventTimeFilter(isCheck); + }else if(ui->hisEventButton->isChecked()) + { + m_pHistoryModel->setEventTimeFilter(isCheck); + m_pHistoryModel->loadEventHistoryData(); + } + m_timeMenu->hide(); +} + +void CEventForm::searchRealDeviceName() +{ + QItemSelection selection; + QString content = m_pRealSearchEdit->text(); + ui->treeView->selectionModel()->select(selection, QItemSelectionModel::Clear); + if(content.isEmpty()) + { + return; + } + const QHash< QString, QModelIndex > &indexNameList = m_pDeviceModel->indexNameList(); + QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); + while (iter != indexNameList.constEnd()) + { + if(ui->treeView->isRowHidden(iter.value().row(), iter.value().parent())) + { + iter++; + continue; + } + if(iter.key().section(".", 1).contains(content, Qt::CaseInsensitive)) + { + selection.append(QItemSelectionRange(iter.value(), iter.value())); + selection.append(QItemSelectionRange(iter.value().parent(), iter.value().parent())); + } + iter++; + } + ui->treeView->selectionModel()->select(selection, QItemSelectionModel::Select); +} + +void CEventForm::searchHistoryDeviceName() +{ + QItemSelection selection; + QString content = m_pHistorySearchEdit->text(); + ui->treeView_2->selectionModel()->select(selection, QItemSelectionModel::Clear); + if(content.isEmpty()) + { + return; + } + const QHash< QString, QModelIndex > &indexNameList = m_pDeviceHisModel->indexNameList(); + QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); + while (iter != indexNameList.constEnd()) + { + if(ui->treeView_2->isRowHidden(iter.value().row(), iter.value().parent())) + { + iter++; + continue; + } + if(iter.key().section(".", 1).contains(content, Qt::CaseInsensitive)) + { + selection.append(QItemSelectionRange(iter.value(), iter.value())); + selection.append(QItemSelectionRange(iter.value().parent(), iter.value().parent())); + } + iter++; + } + ui->treeView_2->selectionModel()->select(selection, QItemSelectionModel::Select); +} + +void CEventForm::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(ui->realEventButton->isChecked()) + { + contextMenuRealEvent(event); + }else if(ui->hisEventButton->isChecked()) + { + contextMenuHisEvent(event); + } +} + +void CEventForm::contextMenuRealEvent(QContextMenuEvent *event) +{ + if(event->pos().x() < ui->eventView->pos().x()) + { + return; + } + QRect headerRect = ui->eventView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->eventView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pRealTimeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->eventView->isColumnHidden(nColumnIndex)); + + connect(action, &QAction::triggered, [=](){ + + ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags1("KBD_HMI", "eventReal config"); + columFlags1.setValue(QString("eventReal/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + columnMenu.exec(QCursor::pos()); + }else + { + QModelIndex index_ = ui->eventView->indexAt(ui->eventView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QMenu menu(this); + QModelIndex index = ui->eventView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QModelIndexList indexLists = ui->eventView->selectionModel()->selectedIndexes(); + + //判断右键位置是否在选中区 + if(!indexLists.contains(index)) + { + ui->eventView->clearSelection(); + ui->eventView->setCurrentIndex(index); + } + + if(m_isNeedAccidentReview) + { + QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); + connect(accidentReviewAction,&QAction::triggered,[=](){ + rightAccidentReviewReal(); + }); + } + menu.exec(QCursor::pos()); + } +} + +void CEventForm::contextMenuHisEvent(QContextMenuEvent *event) +{ + if(event->pos().x() < ui->eventView_2->pos().x()) + { + return; + } + QRect headerRect = ui->eventView_2->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->eventView_2->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pHistoryModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->eventView_2->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->eventView_2->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags2("KBD_HMI", "eventHis config"); + columFlags2.setValue(QString("eventHis/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + columnMenu.exec(QCursor::pos()); + }else + { + QModelIndex index_ = ui->eventView_2->indexAt(ui->eventView_2->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QMenu menu(this); + QModelIndex index = ui->eventView_2->currentIndex(); + if(!index.isValid()) + { + return ; + } + QModelIndexList indexLists = ui->eventView_2->selectionModel()->selectedIndexes(); + + //判断右键位置是否在选中区 + if(!indexLists.contains(index)) + { + ui->eventView_2->clearSelection(); + ui->eventView_2->setCurrentIndex(index); + } + + if(m_isNeedAccidentReview) + { + QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); + connect(accidentReviewAction,&QAction::triggered,[=](){ + rightAccidentReviewHis(); + }); + } + menu.exec(QCursor::pos()); + } +} + +void CEventForm::loadDeviceGroupFilterWidget() +{ + if(!m_pDeviceModel && !m_pDeviceHisModel) + { + return; + } + + kbd_dbms::CDbApi objReader(DB_CONN_MODEL_READ); + if(!objReader.open()) + { + LOGERROR("load deviceGroup info error, database open failed, %s", objReader.getLastErrorString().toStdString().c_str()); + return; + } + + QMap< int, QVector< QPair< QString, QString > > > locationInfos; + + QList locationList = CEventDataCollect::instance()->locationOrderList(); + for(int nIndex(0); nIndex > dev; + + QSqlQuery query; + QString sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1;").arg(locationList[nIndex]); + if(objReader.execute(sqlSequenceQuery, query)) + { + while(query.next()) + { + dev.append(qMakePair(query.value(0).toString(), query.value(1).toString())); + } + locationInfos.insert(locationList[nIndex], dev); + }else + { + LOGERROR("load device info error, dbInterface execute failed!"); + } + } + if(m_pDeviceModel) + { + m_pDeviceModel->removeData(); + m_pDeviceModel->setupModelData(locationInfos,locationList); + updateDeviceGroupHiddenState(); + ui->treeView->expandAll(); + } + if(m_pDeviceHisModel) + { + m_pDeviceHisModel->removeData(); + m_pDeviceHisModel->setupModelData(locationInfos,locationList); + updateHisDeviceGroupHiddenState(QList()); + ui->treeView_2->expandAll(); + } +} + +void CEventForm::updateDeviceGroupHiddenState() +{ + QHash listDeviceStatisticalInfo = m_pDeviceModel->getDeviceStatisticalInfo(); + for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) + { + QModelIndex topLevelIndex = m_pDeviceModel->index(nTopLevelRow, 0); + for(int nChildRow(0); nChildRow < m_pDeviceModel->rowCount(topLevelIndex); nChildRow++) + { + CEventDeviceTreeItem *item = static_cast(m_pDeviceModel->index(nChildRow, 0, topLevelIndex).internalPointer()); + ui->treeView->setRowHidden(nChildRow, topLevelIndex, !listDeviceStatisticalInfo.value(item->data(Qt::UserRole).toString(), 0)); + } + } +} + +void CEventForm::updateHisDeviceGroupHiddenState(QList eventList) +{ + m_pDeviceHisModel->slotHisDevTreeUpdate(eventList); + + QHash listDeviceStatisticalInfo = m_pDeviceHisModel->getDeviceStatisticalInfo(); + for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceHisModel->rowCount(); nTopLevelRow++) + { + QModelIndex topLevelIndex = m_pDeviceHisModel->index(nTopLevelRow, 0); + for(int nChildRow(0); nChildRow < m_pDeviceHisModel->rowCount(topLevelIndex); nChildRow++) + { + CEventDeviceTreeItem *item = static_cast(m_pDeviceHisModel->index(nChildRow, 0, topLevelIndex).internalPointer()); + ui->treeView_2->setRowHidden(nChildRow, topLevelIndex, !listDeviceStatisticalInfo.value(item->data(Qt::UserRole).toString(), 0)); + } + } +} + +void CEventForm::updateStack(int index) +{ + if(m_ncurIndex == index) + { + return ; + } + if(index==0) + { + bool isLevelFilterEnable = false; + QList priorityFilterList; + m_pRealTimeModel->getPriorityFilter(isLevelFilterEnable,priorityFilterList); + + bool isLocationFilterEnable = false; + QList locationFilterList; + m_pRealTimeModel->getLocationFilter(isLocationFilterEnable,locationFilterList); + + bool isStatusFilterEnable = false; + QList statusFilterList; + m_pRealTimeModel->getEventStatusFilter(isStatusFilterEnable,statusFilterList); + + bool timeFilterEnable = false; + QDateTime startTime; + QDateTime endTime; + m_pRealTimeModel->getEventTimeFilter(timeFilterEnable,startTime,endTime); + + setLevelComboBox(isLevelFilterEnable,priorityFilterList); + setLocationComboBox(isLocationFilterEnable,locationFilterList); + setEventStatusComboBox(isStatusFilterEnable,statusFilterList); + setEventTimeLineEdit(timeFilterEnable, startTime, endTime); + ui->clear->setEnabled(true); + m_ncurIndex = index; + ui->eventStackWidget->setCurrentIndex(0); + }else if(index == 1) + { + bool isLevelFilterEnable = false; + QList priorityFilterList; + m_pHistoryModel->getPriorityFilter(isLevelFilterEnable,priorityFilterList); + + bool isLocationFilterEnable = false; + QList locationFilterList; + m_pHistoryModel->getLocationFilter(isLocationFilterEnable,locationFilterList); + + bool isStatusFilterEnable = false; + QList statusFilterList; + m_pHistoryModel->getEventStatusFilter(isStatusFilterEnable,statusFilterList); + + setLevelComboBox(isLevelFilterEnable,priorityFilterList); + setLocationComboBox(isLocationFilterEnable,locationFilterList); + setEventStatusComboBox(isStatusFilterEnable,statusFilterList); + QDate startData = QDate::currentDate().addDays(-6); + QDate endData = QDate::currentDate(); + bool check = true; + m_pHistoryModel->setEventTimeFilter(check,startData,endData); + ui->lineEdit->setText(startData.toString("yyyy-MM-dd")+"~"+endData.toString("yyyy-MM-dd")); + m_pHistoryModel->loadEventHistoryData(); + ui->clear->setEnabled(false); + m_ncurIndex = index; + ui->eventStackWidget->setCurrentIndex(1); + } +} + +void CEventForm::rightAccidentReviewReal() +{ + QModelIndex index = ui->eventView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pRealTimeModel->getListEventInfo(); + EventMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReviewDialog(info->time_stamp-30000,30000*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } +} + +void CEventForm::rightAccidentReviewHis() +{ + QModelIndex index = ui->eventView_2->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pHistoryModel->getListEventInfo(); + EventMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReviewDialog(info->time_stamp-30000,30000*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } +} diff --git a/product/src/gui/plugin/EventWidget/CEventForm.h b/product/src/gui/plugin/EventWidget/CEventForm.h index dbad6994..c5b32c59 100644 --- a/product/src/gui/plugin/EventWidget/CEventForm.h +++ b/product/src/gui/plugin/EventWidget/CEventForm.h @@ -1,169 +1,169 @@ -#ifndef CEventForm_H -#define CEventForm_H - -#include -#include -#include -#include -#include -#include "CMyCalendar.h" -#include "CExcelPrinter.h" -#include "CEventHisThread.h" -namespace Ui { -class CEventForm; -} - -class CEventDelegate; -class CEventItemModel; -class CEventHistoryModel; -class QAbstractTableModel; -class CEventDeviceTreeModel; - -typedef QList QModelIndexList; - -class CEventForm : public QWidget -{ - Q_OBJECT - -public: - explicit CEventForm(QWidget *parent, bool editMode); - ~CEventForm(); - void initilize(); - - void initModel(); - - void initHisModel(); - - void initRealModel(); - -signals: - void closeBtnClicked(); - void printExcel(CEventItemModel *model,QString fileName); - void printExcelHis(CEventHistoryModel *model,QString fileName); - - void openAccidentReviewDialog(quint64 starTime,quint64 keepTime,QString graph = QString()); -public slots: - void login(); - - void logout(); - - void slotShowResult(QString result); - - void setHiddenLocation(bool hide); - void setHiddenTime(bool hide); - void setHiddenStatus(bool hide); - void setHiddenPriority(bool hide); - void setHiddenCloseButton(bool hide); - void setRowHeight(int height); - void setColumnWidth(const int &column, const int &width); - void setColumnVisible(const int &column, const bool &visible = true); - void setHisColumnWidth(const int &column, const int &width); - void setHisColumnVisible(const int &column, const bool &visible = true); - void setEnableAccidentReview(bool isNeed = true); - void setEnableWave(bool isNeed); - - //< pic子路径 - void setAccidentReviewPath(const QString& path); -public: - void initFilter(); - void setLevelComboBox(bool &isLevelFilter,QList &listLevel); - void setLocationComboBox(bool &isLocationFilter,QList &listLocation); - void setEventStatusComboBox(bool &isEventStatusFilter,QList &listEventStatus); - void setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); - -protected slots: - void slotClearRTEvent(); - void deviceGroupFilterChanged(const QString &device, const bool &checked); - void hisDeviceGroupFilterChanged(const QString &device, const bool &checked); - void updateFilter(); - void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventStatusFilter, QList listEventStatus, - bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, - QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime,bool isReturnFilter,bool isReturn); - void slotRTEventStateChanged(); - void slotUpdateRTTips(); //< 更新实时数据文本提示 - //< 更新历史数据文本提示 - void slotUpdateHISTipsRequesting(); - void slotPermInvalid(); - void slotUpdateHISTips(); - void slotHISRecordOutOfRangeTips(QStringList stDescList); - void slotHisOutOfRangeTips(); - void print(); - void stateChanged1(int state); - void stateChanged2(int state); - void stateChanged3(int state); - void textChanged1(const QString &text); - void textChanged2(const QString &text); - void textChanged3(const QString &text); - - void myCalendarHide(QDate startTime, QDate endTime); - void myCalendarShow(); - void cancleTimeFilter(); - - void searchRealDeviceName(); - void searchHistoryDeviceName(); -protected: - void contextMenuEvent(QContextMenuEvent *event); - - void contextMenuRealEvent(QContextMenuEvent *event); - - void contextMenuHisEvent(QContextMenuEvent *event); - - void loadDeviceGroupFilterWidget(); - -private slots: - void updateDeviceGroupHiddenState(); - void updateHisDeviceGroupHiddenState(QList eventList); - - void updateStack(int index); -private: - void rightAccidentReviewReal(); - void rightAccidentReviewHis(); -private: - Ui::CEventForm *ui; - CEventDelegate *m_pRealDelegate; - CEventDelegate *m_pHistoryDelegate; - CEventItemModel * m_pRealTimeModel; - CEventHistoryModel * m_pHistoryModel; - CEventDeviceTreeModel * m_pDeviceModel; - CEventDeviceTreeModel * m_pDeviceHisModel; - int m_nIsModel; - bool m_isEditMode; - - QLineEdit *m_pRealSearchEdit; - QPushButton *m_pRealSearchButton; - QLineEdit *m_pHistorySearchEdit; - QPushButton *m_pHistorySearchButton; - QListWidget *m_pListWidget1; - QListWidget *m_pListWidget2; - QListWidget *m_pListWidget3; - - QLineEdit *m_pLineEdit1; - QLineEdit *m_pLineEdit2; - QLineEdit *m_pLineEdit3; - QList m_priorityList; - QList m_locationList; - QList m_eventStatusList; - QString m_strText1; - QString m_strText2; - QString m_strText3; - - QPushButton *m_timeIcon; - - CMyCalendar * m_myCalendar; - QMenu *m_timeMenu; - - QThread *m_thread; //打印线程 - CExcelPrinter * m_excelPrinter; - - QThread *m_hisSearch; - CEventHisThread *m_hisWork; - - bool m_enableWave; - bool m_isNeedAccidentReview; - - QButtonGroup *m_buttonGroup; - int m_ncurIndex; - QString m_strAccidenPath; -}; - -#endif // CEventForm_H +#ifndef CEventForm_H +#define CEventForm_H + +#include +#include +#include +#include +#include +#include "CMyCalendar.h" +#include "CExcelPrinter.h" +#include "CEventHisThread.h" +namespace Ui { +class CEventForm; +} + +class CEventDelegate; +class CEventItemModel; +class CEventHistoryModel; +class QAbstractTableModel; +class CEventDeviceTreeModel; + +typedef QList QModelIndexList; + +class CEventForm : public QWidget +{ + Q_OBJECT + +public: + explicit CEventForm(QWidget *parent, bool editMode); + ~CEventForm(); + void initilize(); + + void initModel(); + + void initHisModel(); + + void initRealModel(); + +signals: + void closeBtnClicked(); + void printExcel(CEventItemModel *model,QString fileName); + void printExcelHis(CEventHistoryModel *model,QString fileName); + + void openAccidentReviewDialog(quint64 starTime,quint64 keepTime,QString graph = QString()); +public slots: + void login(); + + void logout(); + + void slotShowResult(QString result); + + void setHiddenLocation(bool hide); + void setHiddenTime(bool hide); + void setHiddenStatus(bool hide); + void setHiddenPriority(bool hide); + void setHiddenCloseButton(bool hide); + void setRowHeight(int height); + void setColumnWidth(const int &column, const int &width); + void setColumnVisible(const int &column, const bool &visible = true); + void setHisColumnWidth(const int &column, const int &width); + void setHisColumnVisible(const int &column, const bool &visible = true); + void setEnableAccidentReview(bool isNeed = true); + void setEnableWave(bool isNeed); + + //< pic子路径 + void setAccidentReviewPath(const QString& path); +public: + void initFilter(); + void setLevelComboBox(bool &isLevelFilter,QList &listLevel); + void setLocationComboBox(bool &isLocationFilter,QList &listLocation); + void setEventStatusComboBox(bool &isEventStatusFilter,QList &listEventStatus); + void setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); + +protected slots: + void slotClearRTEvent(); + void deviceGroupFilterChanged(const QString &device, const bool &checked); + void hisDeviceGroupFilterChanged(const QString &device, const bool &checked); + void updateFilter(); + void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventStatusFilter, QList listEventStatus, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, + QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime,bool isReturnFilter,bool isReturn); + void slotRTEventStateChanged(); + void slotUpdateRTTips(); //< 更新实时数据文本提示 + //< 更新历史数据文本提示 + void slotUpdateHISTipsRequesting(); + void slotPermInvalid(); + void slotUpdateHISTips(); + void slotHISRecordOutOfRangeTips(QStringList stDescList); + void slotHisOutOfRangeTips(); + void print(); + void stateChanged1(int state); + void stateChanged2(int state); + void stateChanged3(int state); + void textChanged1(const QString &text); + void textChanged2(const QString &text); + void textChanged3(const QString &text); + + void myCalendarHide(QDate startTime, QDate endTime); + void myCalendarShow(); + void cancleTimeFilter(); + + void searchRealDeviceName(); + void searchHistoryDeviceName(); +protected: + void contextMenuEvent(QContextMenuEvent *event); + + void contextMenuRealEvent(QContextMenuEvent *event); + + void contextMenuHisEvent(QContextMenuEvent *event); + + void loadDeviceGroupFilterWidget(); + +private slots: + void updateDeviceGroupHiddenState(); + void updateHisDeviceGroupHiddenState(QList eventList); + + void updateStack(int index); +private: + void rightAccidentReviewReal(); + void rightAccidentReviewHis(); +private: + Ui::CEventForm *ui; + CEventDelegate *m_pRealDelegate; + CEventDelegate *m_pHistoryDelegate; + CEventItemModel * m_pRealTimeModel; + CEventHistoryModel * m_pHistoryModel; + CEventDeviceTreeModel * m_pDeviceModel; + CEventDeviceTreeModel * m_pDeviceHisModel; + int m_nIsModel; + bool m_isEditMode; + + QLineEdit *m_pRealSearchEdit; + QPushButton *m_pRealSearchButton; + QLineEdit *m_pHistorySearchEdit; + QPushButton *m_pHistorySearchButton; + QListWidget *m_pListWidget1; + QListWidget *m_pListWidget2; + QListWidget *m_pListWidget3; + + QLineEdit *m_pLineEdit1; + QLineEdit *m_pLineEdit2; + QLineEdit *m_pLineEdit3; + QList m_priorityList; + QList m_locationList; + QList m_eventStatusList; + QString m_strText1; + QString m_strText2; + QString m_strText3; + + QPushButton *m_timeIcon; + + CMyCalendar * m_myCalendar; + QMenu *m_timeMenu; + + QThread *m_thread; //打印线程 + CExcelPrinter * m_excelPrinter; + + QThread *m_hisSearch; + CEventHisThread *m_hisWork; + + bool m_enableWave; + bool m_isNeedAccidentReview; + + QButtonGroup *m_buttonGroup; + int m_ncurIndex; + QString m_strAccidenPath; +}; + +#endif // CEventForm_H diff --git a/product/src/gui/plugin/EventWidget/CEventForm.ui b/product/src/gui/plugin/EventWidget/CEventForm.ui index e5b0bade..fdd997b3 100644 --- a/product/src/gui/plugin/EventWidget/CEventForm.ui +++ b/product/src/gui/plugin/EventWidget/CEventForm.ui @@ -1,714 +1,714 @@ - - - CEventForm - - - - 0 - 0 - 1343 - 654 - - - - 事件 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - 0 - - - - 9 - - - 9 - - - 9 - - - 9 - - - 0 - - - - - 0 - - - 0 - - - 0 - - - - - - 0 - 32 - - - - 实时事件 - - - true - - - true - - - - - - - - 0 - 32 - - - - 历史事件 - - - true - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 6 - - - 5 - - - 5 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 优先级: - - - - - - - - 125 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 位置: - - - - - - - - 125 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 事件状态: - - - - - - - - 137 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 时间: - - - - - - - - 0 - 0 - - - - - 200 - 26 - - - - - 200 - 26 - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - - 45 - 26 - - - - 清空 - - - - - - - - 45 - 26 - - - - 过滤 - - - - - - - - 45 - 26 - - - - 导出 - - - - - - - - 45 - 26 - - - - 关闭 - - - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 9 - - - 9 - - - 9 - - - 9 - - - 0 - - - - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 300 - 0 - - - - Qt::Horizontal - - - - - 210 - 0 - - - - - - - 600 - 300 - - - - QFrame::Sunken - - - false - - - false - - - - - - - - - - - 0 - 0 - - - - 实时事件总数: - - - Qt::AutoText - - - false - - - - - - - - 30 - 0 - - - - 0 - - - - - - - - - Qt::Horizontal - - - - 493 - 20 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 300 - 0 - - - - Qt::Horizontal - - - - - 210 - 0 - - - - - - - 600 - 300 - - - - QFrame::Sunken - - - false - - - false - - - - - - - - - - - 30 - 0 - - - - 0 - - - - - - - - 0 - 0 - - - - 历史事件总数: - - - Qt::AutoText - - - false - - - - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - - - Qt::Horizontal - - - - 935 - 20 - - - - - - - - - - - - - - - - - - - CEventView - QTableView -
CEventView.h
-
- - CEventDeviceTreeView - QTreeView -
CEventDeviceTreeView.h
-
-
- - - - filter - clicked() - CEventForm - updateFilter() - - - 650 - 25 - - - 599 - 0 - - - - - print - clicked() - CEventForm - print() - - - 722 - 21 - - - 743 - 21 - - - - - - updateFilter() - print() - -
+ + + CEventForm + + + + 0 + 0 + 1343 + 654 + + + + 事件 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 0 + + + + 9 + + + 9 + + + 9 + + + 9 + + + 0 + + + + + 0 + + + 0 + + + 0 + + + + + + 0 + 32 + + + + 实时事件 + + + true + + + true + + + + + + + + 0 + 32 + + + + 历史事件 + + + true + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + 5 + + + 5 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 优先级: + + + + + + + + 125 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 位置: + + + + + + + + 125 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 事件状态: + + + + + + + + 137 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 时间: + + + + + + + + 0 + 0 + + + + + 200 + 26 + + + + + 200 + 26 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + 45 + 26 + + + + 清空 + + + + + + + + 45 + 26 + + + + 过滤 + + + + + + + + 45 + 26 + + + + 导出 + + + + + + + + 45 + 26 + + + + 关闭 + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 9 + + + 9 + + + 9 + + + 9 + + + 0 + + + + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 300 + 0 + + + + Qt::Horizontal + + + + + 210 + 0 + + + + + + + 600 + 300 + + + + QFrame::Sunken + + + false + + + false + + + + + + + + + + + 0 + 0 + + + + 实时事件总数: + + + Qt::AutoText + + + false + + + + + + + + 30 + 0 + + + + 0 + + + + + + + + + Qt::Horizontal + + + + 493 + 20 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 300 + 0 + + + + Qt::Horizontal + + + + + 210 + 0 + + + + + + + 600 + 300 + + + + QFrame::Sunken + + + false + + + false + + + + + + + + + + + 30 + 0 + + + + 0 + + + + + + + + 0 + 0 + + + + 历史事件总数: + + + Qt::AutoText + + + false + + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + + 935 + 20 + + + + + + + + + + + + + + + + + + + CEventView + QTableView +
CEventView.h
+
+ + CEventDeviceTreeView + QTreeView +
CEventDeviceTreeView.h
+
+
+ + + + filter + clicked() + CEventForm + updateFilter() + + + 650 + 25 + + + 599 + 0 + + + + + print + clicked() + CEventForm + print() + + + 722 + 21 + + + 743 + 21 + + + + + + updateFilter() + print() + +
diff --git a/product/src/gui/plugin/EventWidget/CEventHisThread.cpp b/product/src/gui/plugin/EventWidget/CEventHisThread.cpp index 7712a58a..2a5b2dce 100644 --- a/product/src/gui/plugin/EventWidget/CEventHisThread.cpp +++ b/product/src/gui/plugin/EventWidget/CEventHisThread.cpp @@ -1,689 +1,689 @@ -#include "CEventHisThread.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" -#include -#include "CEventDataCollect.h" -#include "perm_mng_api/PermMngApi.h" - -using namespace std; - -CEventHisThread::CEventHisThread(QObject *parent) : QObject(parent), - m_pReadDb(Q_NULLPTR), m_rtdbPriorityOrderAccess(nullptr) -{ -} - -CEventHisThread::~CEventHisThread() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; -} - -void CEventHisThread::init() -{ - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); - if(!m_pReadDb->open()) - { - LOGERROR("打开数据库失败,error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); - } - - m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); - m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); -} - -int CEventHisThread::queryPriorityOrder(int &id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); - kbd_dbms::CVarType value; - m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); - return value.toInt(); -} - -void CEventHisThread::condition(QList &showEventList, QList &listEvents) -{ - QList::iterator it = listEvents.begin(); - int count = 0; - while (it != listEvents.end()) { - if(conditionFilter(*it)) - { - showEventList.append(*it); - count++; - } - - if(count == LIMIT_HIS_RECORD) - { - break; - } - it++; - } -} - -bool CEventHisThread::conditionFilter(const EventMsgPtr info) -{ - if(m_stFilter.isLevelFilterEnable && !m_stFilter.levelFilter.contains(info->priority)) - { - return false; - } - // if(m_stFilter.isLocationFilterEnable && !m_stFilter.locationFilter.contains(info->location_id)) - // { - // return false; - // } - - // if(m_stFilter.isRegionFilterEnable) - // { - // if(!m_stFilter.regionFilter.contains(info->region_id)) - // { - // return false; - // } - // } - // else - // { - // if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 - // { - // return false; - // } - // } - //事件状态过滤 -// if(m_stFilter.isStatusFilterEnable && !m_stFilter.statusFilter.contains(info->alm_status)) -// { -// return false; -// } -// if(m_stFilter.isDeviceTypeFileter) -// { -// if(CEventDataCollect::instance()->deviceTypeId(m_stFilter.deviceType) != info->dev_type) -// { -// return false; -// } -// } -// if(m_stFilter.isKeywordEnable) -// { -// if(!info->content.contains(m_stFilter.keyword)) -// { -// return false; -// } -// } - //不再需要时间过滤 - if(m_stFilter.isReturnFilterEnable) - { - if(m_stFilter.isReturn) - { - if(info->alm_style != AS_ALARM_RTN ) - { - return false; - } - } - else - { - if(info->alm_style != AS_ALARM) - { - return false; - } - } - } - - return true; -} - -QString CEventHisThread::buildCondition() -{ - QString conditionFilter; - //< 内容 - QString content = buildConditionPartContent(); - if(!content.isEmpty()) - { - conditionFilter += content; - } - - //< 等级 - QString priority = buildConditionPartPriority(); - if(!conditionFilter.isEmpty() && !priority.isEmpty()) - { - conditionFilter += " AND "; - } - if(!priority.isEmpty()) - { - conditionFilter += priority; - } - //< 告警状态 - QString status = buildConditionPartStatus(); - if(!conditionFilter.isEmpty() && !status.isEmpty()) - { - conditionFilter += " AND "; - } - if(!status.isEmpty()) - { - conditionFilter += status; - } - - - //< 设备类型 - QString device_type = buildConditionPartDeviceType(); - if(!conditionFilter.isEmpty() && !device_type.isEmpty()) - { - conditionFilter += " AND "; - } - if(!device_type.isEmpty()) - { - conditionFilter += device_type; - } - - return conditionFilter; -} - -QString CEventHisThread::buildLocAndRegion() -{ - QString conditionFilter = QString(); - //< 车站 - - QString location_id = buildConditionPartLocation(); - if(location_id.isEmpty()) - { - return QString(); - }else - { - conditionFilter += location_id; - } - - //< 责任区 - QString region_id = buildConditionPartRegion(); - if(region_id.isEmpty()) - { - return QString(); - }else - { - conditionFilter += " AND "; - conditionFilter +=region_id; - } - return conditionFilter; -} - -QString CEventHisThread::buildConditionPartPriority() -{ - if(m_stFilter.isLevelFilterEnable) - { - QString strFilter; - for(int nIndex = 0; nIndex < m_stFilter.levelFilter.size(); nIndex++) - { - strFilter.append(QString::number(m_stFilter.levelFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); - } - return strFilter; - } - return QString(); -} - -QString CEventHisThread::buildConditionPartStatus() -{ - if(m_stFilter.isStatusFilterEnable) - { - QString strFilter; - for(int nIndex = 0; nIndex < m_stFilter.statusFilter.size(); nIndex++) - { - strFilter.append(QString::number(m_stFilter.statusFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("alm_status").arg(strFilter); - } - return strFilter; - } - return QString(); -} - -QString CEventHisThread::buildConditionPartLocation() -{ - QList locationFilter; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecLocationId; - std::vector vecRegionId; - if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - if(m_stFilter.isLocationFilterEnable) - { - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - if(m_stFilter.locationFilter.contains(*location)) - { - locationFilter.append(*location); - } - location++; - } - } - else - { - locationFilter = QVector::fromStdVector(vecLocationId).toList(); - } - } - else - { - LOGERROR("获取当前用户事件权限失败!"); - return QString(); - } - } - - QString strFilter; - for(int nIndex = 0; nIndex < locationFilter.size(); nIndex++) - { - strFilter.append(QString::number(locationFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); - } - return strFilter; -} - -QString CEventHisThread::buildConditionPartRegion() -{ - QList regionFilter; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecLocationId; - std::vector vecRegionId; - if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - if(m_stFilter.isRegionFilterEnable) - { - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - if(m_stFilter.regionFilter.contains(*region)) - { - regionFilter.append(*region); - } - region++; - } - } - else - { - regionFilter = QVector::fromStdVector(vecRegionId).toList(); - } - } - else - { - LOGERROR("获取当前用户事件权限失败!"); - return QString(); - } - } - - - QString strFilter; - for(int nIndex = 0; nIndex < regionFilter.size(); nIndex++) - { - strFilter.append(QString::number(regionFilter.at(nIndex)) + ", "); - } - strFilter.append(QString::number(0) + ", ");//防止责任区为空 - strFilter.append(QString::number(-1) + ", ");//防止责任区为空 - - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); - return strFilter; -} - -QString CEventHisThread::buildConditionPartDeviceType() -{ - if(m_stFilter.isDeviceTypeFileter) - { - return QString("(%1 = %2)").arg("dev_type").arg(CEventDataCollect::instance()->deviceTypeId(m_stFilter.deviceType)); - } - return QString(); -} - -QString CEventHisThread::buildConditionPartContent() -{ - if(m_stFilter.isKeywordEnable && !m_stFilter.keyword.isEmpty()) - { - QString strFilter = QString("(%1 like '%" ).arg("content") + m_stFilter.keyword + QString("%')"); - return strFilter; - } - return QString(); -} - -void CEventHisThread::doWork(ST_FILTER stFilter) -{ - m_stFilter = stFilter; - if(m_stFilter.isReturnFilterEnable) - { - doReturnFilterEnable(); - }else - { - doReturnFilterDisenable(); - } - -// if(m_stFilter.isReturnFilterEnable) -// { - - -// }else -// { -// sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file from his_event"); -// sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); - -// QString locAndRegionFilter = buildLocAndRegion(); -// if(locAndRegionFilter.isEmpty()) -// { -// emit sigUpdateHisEvent(showEventList); -// LOGERROR("doWork()无所属车站或责任区,停止查询!"); -// return ; -// } -// sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); - -// QString conditionFilter = buildCondition(); -// if(!conditionFilter.isEmpty()) -// { -// sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); -// } -// sql = QString("%1 order by time_stamp desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); -// } - -// LOGDEBUG("his sql:%s",sql.toStdString().c_str()); -// if(m_pReadDb->isOpen()) -// { -// QSqlQuery query; -// try -// { -// m_pReadDb->execute(sql,query); -// } -// catch(...) -// { -// qDebug() << "Query Error!"; -// } -// if(m_stFilter.isReturnFilterEnable) -// { -// QMap exitTagMap; -// if(query.isActive()) -// { -// while(query.next()) -// { -// EventMsgPtr info(new CEventMsgInfo); -// info->time_stamp = query.value(0).toULongLong(); -// info->priority = query.value(1).toInt(); -// info->location_id = query.value(2).toInt(); -// info->region_id = query.value(3).toInt(); -// info->content = query.value(4).toString(); -// info->alm_type = query.value(5).toInt(); -// info->alm_status = query.value(6).toInt(); -// int logic = query.value(7).toInt(); -// if(logic == 0) -// { -// info->alm_style = AS_ALARM; -// }else if(logic ==1) -// { -// info->alm_style = AS_ALARM_RTN; -// }else -// { -// info->alm_style = AS_EVENT_ONLY; -// } -// info->dev_type = query.value(8).toInt(); -// info->cfm_user = query.value(9).toUInt(); -// info->cfm_time = query.value(10).toULongLong(); -// info->key_id_tag = query.value(11).toString(); -// info->priorityOrder = queryPriorityOrder(info->priority); -// info->wave_file = query.value(12).toString(); -// if(exitTagMap.find(info->key_id_tag) == exitTagMap.end()) -// { -// historyEventList.append(info); -// exitTagMap[info->key_id_tag] = true; -// } -// } -// } -// exitTagMap.clear(); -// }else -// { -// if(query.isActive()) -// { -// while(query.next()) -// { -// EventMsgPtr info(new CEventMsgInfo); -// info->time_stamp = query.value(0).toULongLong(); -// info->priority = query.value(1).toInt(); -// info->location_id = query.value(2).toInt(); -// info->region_id = query.value(3).toInt(); -// info->content = query.value(4).toString(); -// info->alm_type = query.value(5).toInt(); -// info->alm_status = query.value(6).toInt(); -// int logic = query.value(7).toInt(); -// if(logic == 0) -// { -// info->alm_style = AS_ALARM; -// }else if(logic ==1) -// { -// info->alm_style = AS_ALARM_RTN; -// }else -// { -// info->alm_style = AS_EVENT_ONLY; -// } -// info->dev_type = query.value(8).toInt(); -// info->cfm_user = query.value(9).toUInt(); -// info->cfm_time = query.value(10).toULongLong(); -// info->key_id_tag = query.value(11).toString(); -// info->priorityOrder = queryPriorityOrder(info->priority); -// info->wave_file = query.value(12).toString(); -// historyEventList.append(info); -// } -// } -// } -// } - -// if(m_stFilter.isReturnFilterEnable) -// { -// condition(showEventList,historyEventList); -// }else -// { -// showEventList.swap(historyEventList); -// } -// emit sigUpdateHisEvent(showEventList); -} - -void CEventHisThread::doReturnFilterEnable() -{ - QList historyEventList;//查询到的所有 - QString sql; - QList showEventList; - qint64 startStamp = m_stFilter.startTime.toMSecsSinceEpoch(); - qint64 endStamp = m_stFilter.endTime.toMSecsSinceEpoch(); - - sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag,SUB_SYSTEM from his_event"); - - - //先查询标签和时间 然后根据时间和标签再次查询 - sql = QString("select max(time_stamp),key_id_tag from his_event"); - sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); - QString locAndRegionFilter = buildLocAndRegion(); - if(locAndRegionFilter.isEmpty()) - { - emit sigUpdateHisEvent(showEventList); - LOGERROR("doWork()无所属车站或责任区,停止查询!"); - return ; - } - sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); - QString conditionFilter = buildCondition(); - if(!conditionFilter.isEmpty()) - { - sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); - } - sql = QString("%1 group by key_id_tag order by max(time_stamp) desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); - - LOGDEBUG("his sql:%s",sql.toStdString().c_str()); - - QList keyList; - if(m_pReadDb->isOpen()) - { - QSqlQuery query; - try - { - m_pReadDb->execute(sql,query); - } - catch(...) - { - qDebug() << "Query Error!"; - } - - if(query.isActive()) - { - while(query.next()) - { - STimeKeyIdTag keyInfo; - keyInfo.time_stamp = query.value(0).toULongLong(); - keyInfo.key_id_tag = query.value(1).toString(); - if(!keyInfo.key_id_tag.isEmpty()) - { - keyList.append(keyInfo); - } - } - } - } - if(keyList.isEmpty()) - { - emit sigUpdateHisEvent(showEventList); - return ; - } - //第2次查询结果 - QString sqlBase = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag,SUB_SYSTEM from his_event"); - int counter = 0; - QString cond = QString(); - for(int index(0);index historyEventList;//查询到的所有 - QString sql; - QList showEventList; - qint64 startStamp = m_stFilter.startTime.toMSecsSinceEpoch(); - qint64 endStamp = m_stFilter.endTime.toMSecsSinceEpoch(); - - sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag,SUB_SYSTEM from his_event"); - sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); - - QString locAndRegionFilter = buildLocAndRegion(); - if(locAndRegionFilter.isEmpty()) - { - emit sigUpdateHisEvent(showEventList); - LOGERROR("doWork()无所属车站或责任区,停止查询!"); - return ; - } - sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); - - QString conditionFilter = buildCondition(); - if(!conditionFilter.isEmpty()) - { - sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); - } - sql = QString("%1 order by time_stamp desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); - - LOGDEBUG("his sql:%s",sql.toStdString().c_str()); - if(m_pReadDb->isOpen()) - { - QSqlQuery query; - try - { - m_pReadDb->execute(sql,query); - } - catch(...) - { - qDebug() << "Query Error!"; - } - search(sql,historyEventList); - } - - emit sigUpdateHisEvent(historyEventList); -} - -void CEventHisThread::search(const QString &sql, QList &eventList) -{ - if(m_pReadDb->isOpen()) - { - QSqlQuery query; - try - { - m_pReadDb->execute(sql,query); - } - catch(...) - { - qDebug() << "Query Error!"; - } - - if(query.isActive()) - { - while(query.next()) - { - EventMsgPtr info(new CEventMsgInfo); - info->time_stamp = query.value(0).toULongLong(); - info->priority = query.value(1).toInt(); - info->location_id = query.value(2).toInt(); - info->region_id = query.value(3).toInt(); - info->content = query.value(4).toString(); - info->alm_type = query.value(5).toInt(); - info->alm_status = query.value(6).toInt(); - int logic = query.value(7).toInt(); - if(logic == 0) - { - info->alm_style = AS_ALARM; - }else if(logic ==1) - { - info->alm_style = AS_ALARM_RTN; - }else - { - info->alm_style = AS_EVENT_ONLY; - } - info->dev_type = query.value(8).toInt(); - info->cfm_user = query.value(9).toUInt(); - info->cfm_time = query.value(10).toULongLong(); - info->key_id_tag = query.value(11).toString(); - info->priorityOrder = queryPriorityOrder(info->priority); - info->wave_file = query.value(12).toString(); - info->dev_group_tag = query.value(13).toString(); - info->sub_system = query.value(14).toInt(); - - - eventList.append(info); - } - } - } -} +#include "CEventHisThread.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include +#include "CEventDataCollect.h" +#include "perm_mng_api/PermMngApi.h" + +using namespace std; + +CEventHisThread::CEventHisThread(QObject *parent) : QObject(parent), + m_pReadDb(Q_NULLPTR), m_rtdbPriorityOrderAccess(nullptr) +{ +} + +CEventHisThread::~CEventHisThread() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; +} + +void CEventHisThread::init() +{ + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); + if(!m_pReadDb->open()) + { + LOGERROR("打开数据库失败,error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); + } + + m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); +} + +int CEventHisThread::queryPriorityOrder(int &id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + kbd_dbms::CVarType value; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +void CEventHisThread::condition(QList &showEventList, QList &listEvents) +{ + QList::iterator it = listEvents.begin(); + int count = 0; + while (it != listEvents.end()) { + if(conditionFilter(*it)) + { + showEventList.append(*it); + count++; + } + + if(count == LIMIT_HIS_RECORD) + { + break; + } + it++; + } +} + +bool CEventHisThread::conditionFilter(const EventMsgPtr info) +{ + if(m_stFilter.isLevelFilterEnable && !m_stFilter.levelFilter.contains(info->priority)) + { + return false; + } + // if(m_stFilter.isLocationFilterEnable && !m_stFilter.locationFilter.contains(info->location_id)) + // { + // return false; + // } + + // if(m_stFilter.isRegionFilterEnable) + // { + // if(!m_stFilter.regionFilter.contains(info->region_id)) + // { + // return false; + // } + // } + // else + // { + // if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 + // { + // return false; + // } + // } + //事件状态过滤 +// if(m_stFilter.isStatusFilterEnable && !m_stFilter.statusFilter.contains(info->alm_status)) +// { +// return false; +// } +// if(m_stFilter.isDeviceTypeFileter) +// { +// if(CEventDataCollect::instance()->deviceTypeId(m_stFilter.deviceType) != info->dev_type) +// { +// return false; +// } +// } +// if(m_stFilter.isKeywordEnable) +// { +// if(!info->content.contains(m_stFilter.keyword)) +// { +// return false; +// } +// } + //不再需要时间过滤 + if(m_stFilter.isReturnFilterEnable) + { + if(m_stFilter.isReturn) + { + if(info->alm_style != AS_ALARM_RTN ) + { + return false; + } + } + else + { + if(info->alm_style != AS_ALARM) + { + return false; + } + } + } + + return true; +} + +QString CEventHisThread::buildCondition() +{ + QString conditionFilter; + //< 内容 + QString content = buildConditionPartContent(); + if(!content.isEmpty()) + { + conditionFilter += content; + } + + //< 等级 + QString priority = buildConditionPartPriority(); + if(!conditionFilter.isEmpty() && !priority.isEmpty()) + { + conditionFilter += " AND "; + } + if(!priority.isEmpty()) + { + conditionFilter += priority; + } + //< 告警状态 + QString status = buildConditionPartStatus(); + if(!conditionFilter.isEmpty() && !status.isEmpty()) + { + conditionFilter += " AND "; + } + if(!status.isEmpty()) + { + conditionFilter += status; + } + + + //< 设备类型 + QString device_type = buildConditionPartDeviceType(); + if(!conditionFilter.isEmpty() && !device_type.isEmpty()) + { + conditionFilter += " AND "; + } + if(!device_type.isEmpty()) + { + conditionFilter += device_type; + } + + return conditionFilter; +} + +QString CEventHisThread::buildLocAndRegion() +{ + QString conditionFilter = QString(); + //< 车站 + + QString location_id = buildConditionPartLocation(); + if(location_id.isEmpty()) + { + return QString(); + }else + { + conditionFilter += location_id; + } + + //< 责任区 + QString region_id = buildConditionPartRegion(); + if(region_id.isEmpty()) + { + return QString(); + }else + { + conditionFilter += " AND "; + conditionFilter +=region_id; + } + return conditionFilter; +} + +QString CEventHisThread::buildConditionPartPriority() +{ + if(m_stFilter.isLevelFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_stFilter.levelFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_stFilter.levelFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHisThread::buildConditionPartStatus() +{ + if(m_stFilter.isStatusFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_stFilter.statusFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_stFilter.statusFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("alm_status").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHisThread::buildConditionPartLocation() +{ + QList locationFilter; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_stFilter.isLocationFilterEnable) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + if(m_stFilter.locationFilter.contains(*location)) + { + locationFilter.append(*location); + } + location++; + } + } + else + { + locationFilter = QVector::fromStdVector(vecLocationId).toList(); + } + } + else + { + LOGERROR("获取当前用户事件权限失败!"); + return QString(); + } + } + + QString strFilter; + for(int nIndex = 0; nIndex < locationFilter.size(); nIndex++) + { + strFilter.append(QString::number(locationFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); + } + return strFilter; +} + +QString CEventHisThread::buildConditionPartRegion() +{ + QList regionFilter; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_stFilter.isRegionFilterEnable) + { + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + if(m_stFilter.regionFilter.contains(*region)) + { + regionFilter.append(*region); + } + region++; + } + } + else + { + regionFilter = QVector::fromStdVector(vecRegionId).toList(); + } + } + else + { + LOGERROR("获取当前用户事件权限失败!"); + return QString(); + } + } + + + QString strFilter; + for(int nIndex = 0; nIndex < regionFilter.size(); nIndex++) + { + strFilter.append(QString::number(regionFilter.at(nIndex)) + ", "); + } + strFilter.append(QString::number(0) + ", ");//防止责任区为空 + strFilter.append(QString::number(-1) + ", ");//防止责任区为空 + + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); + return strFilter; +} + +QString CEventHisThread::buildConditionPartDeviceType() +{ + if(m_stFilter.isDeviceTypeFileter) + { + return QString("(%1 = %2)").arg("dev_type").arg(CEventDataCollect::instance()->deviceTypeId(m_stFilter.deviceType)); + } + return QString(); +} + +QString CEventHisThread::buildConditionPartContent() +{ + if(m_stFilter.isKeywordEnable && !m_stFilter.keyword.isEmpty()) + { + QString strFilter = QString("(%1 like '%" ).arg("content") + m_stFilter.keyword + QString("%')"); + return strFilter; + } + return QString(); +} + +void CEventHisThread::doWork(ST_FILTER stFilter) +{ + m_stFilter = stFilter; + if(m_stFilter.isReturnFilterEnable) + { + doReturnFilterEnable(); + }else + { + doReturnFilterDisenable(); + } + +// if(m_stFilter.isReturnFilterEnable) +// { + + +// }else +// { +// sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file from his_event"); +// sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); + +// QString locAndRegionFilter = buildLocAndRegion(); +// if(locAndRegionFilter.isEmpty()) +// { +// emit sigUpdateHisEvent(showEventList); +// LOGERROR("doWork()无所属车站或责任区,停止查询!"); +// return ; +// } +// sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); + +// QString conditionFilter = buildCondition(); +// if(!conditionFilter.isEmpty()) +// { +// sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); +// } +// sql = QString("%1 order by time_stamp desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); +// } + +// LOGDEBUG("his sql:%s",sql.toStdString().c_str()); +// if(m_pReadDb->isOpen()) +// { +// QSqlQuery query; +// try +// { +// m_pReadDb->execute(sql,query); +// } +// catch(...) +// { +// qDebug() << "Query Error!"; +// } +// if(m_stFilter.isReturnFilterEnable) +// { +// QMap exitTagMap; +// if(query.isActive()) +// { +// while(query.next()) +// { +// EventMsgPtr info(new CEventMsgInfo); +// info->time_stamp = query.value(0).toULongLong(); +// info->priority = query.value(1).toInt(); +// info->location_id = query.value(2).toInt(); +// info->region_id = query.value(3).toInt(); +// info->content = query.value(4).toString(); +// info->alm_type = query.value(5).toInt(); +// info->alm_status = query.value(6).toInt(); +// int logic = query.value(7).toInt(); +// if(logic == 0) +// { +// info->alm_style = AS_ALARM; +// }else if(logic ==1) +// { +// info->alm_style = AS_ALARM_RTN; +// }else +// { +// info->alm_style = AS_EVENT_ONLY; +// } +// info->dev_type = query.value(8).toInt(); +// info->cfm_user = query.value(9).toUInt(); +// info->cfm_time = query.value(10).toULongLong(); +// info->key_id_tag = query.value(11).toString(); +// info->priorityOrder = queryPriorityOrder(info->priority); +// info->wave_file = query.value(12).toString(); +// if(exitTagMap.find(info->key_id_tag) == exitTagMap.end()) +// { +// historyEventList.append(info); +// exitTagMap[info->key_id_tag] = true; +// } +// } +// } +// exitTagMap.clear(); +// }else +// { +// if(query.isActive()) +// { +// while(query.next()) +// { +// EventMsgPtr info(new CEventMsgInfo); +// info->time_stamp = query.value(0).toULongLong(); +// info->priority = query.value(1).toInt(); +// info->location_id = query.value(2).toInt(); +// info->region_id = query.value(3).toInt(); +// info->content = query.value(4).toString(); +// info->alm_type = query.value(5).toInt(); +// info->alm_status = query.value(6).toInt(); +// int logic = query.value(7).toInt(); +// if(logic == 0) +// { +// info->alm_style = AS_ALARM; +// }else if(logic ==1) +// { +// info->alm_style = AS_ALARM_RTN; +// }else +// { +// info->alm_style = AS_EVENT_ONLY; +// } +// info->dev_type = query.value(8).toInt(); +// info->cfm_user = query.value(9).toUInt(); +// info->cfm_time = query.value(10).toULongLong(); +// info->key_id_tag = query.value(11).toString(); +// info->priorityOrder = queryPriorityOrder(info->priority); +// info->wave_file = query.value(12).toString(); +// historyEventList.append(info); +// } +// } +// } +// } + +// if(m_stFilter.isReturnFilterEnable) +// { +// condition(showEventList,historyEventList); +// }else +// { +// showEventList.swap(historyEventList); +// } +// emit sigUpdateHisEvent(showEventList); +} + +void CEventHisThread::doReturnFilterEnable() +{ + QList historyEventList;//查询到的所有 + QString sql; + QList showEventList; + qint64 startStamp = m_stFilter.startTime.toMSecsSinceEpoch(); + qint64 endStamp = m_stFilter.endTime.toMSecsSinceEpoch(); + + sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag,SUB_SYSTEM from his_event"); + + + //先查询标签和时间 然后根据时间和标签再次查询 + sql = QString("select max(time_stamp),key_id_tag from his_event"); + sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); + QString locAndRegionFilter = buildLocAndRegion(); + if(locAndRegionFilter.isEmpty()) + { + emit sigUpdateHisEvent(showEventList); + LOGERROR("doWork()无所属车站或责任区,停止查询!"); + return ; + } + sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); + QString conditionFilter = buildCondition(); + if(!conditionFilter.isEmpty()) + { + sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); + } + sql = QString("%1 group by key_id_tag order by max(time_stamp) desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); + + LOGDEBUG("his sql:%s",sql.toStdString().c_str()); + + QList keyList; + if(m_pReadDb->isOpen()) + { + QSqlQuery query; + try + { + m_pReadDb->execute(sql,query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + + if(query.isActive()) + { + while(query.next()) + { + STimeKeyIdTag keyInfo; + keyInfo.time_stamp = query.value(0).toULongLong(); + keyInfo.key_id_tag = query.value(1).toString(); + if(!keyInfo.key_id_tag.isEmpty()) + { + keyList.append(keyInfo); + } + } + } + } + if(keyList.isEmpty()) + { + emit sigUpdateHisEvent(showEventList); + return ; + } + //第2次查询结果 + QString sqlBase = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag,SUB_SYSTEM from his_event"); + int counter = 0; + QString cond = QString(); + for(int index(0);index historyEventList;//查询到的所有 + QString sql; + QList showEventList; + qint64 startStamp = m_stFilter.startTime.toMSecsSinceEpoch(); + qint64 endStamp = m_stFilter.endTime.toMSecsSinceEpoch(); + + sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag,SUB_SYSTEM from his_event"); + sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); + + QString locAndRegionFilter = buildLocAndRegion(); + if(locAndRegionFilter.isEmpty()) + { + emit sigUpdateHisEvent(showEventList); + LOGERROR("doWork()无所属车站或责任区,停止查询!"); + return ; + } + sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); + + QString conditionFilter = buildCondition(); + if(!conditionFilter.isEmpty()) + { + sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); + } + sql = QString("%1 order by time_stamp desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); + + LOGDEBUG("his sql:%s",sql.toStdString().c_str()); + if(m_pReadDb->isOpen()) + { + QSqlQuery query; + try + { + m_pReadDb->execute(sql,query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + search(sql,historyEventList); + } + + emit sigUpdateHisEvent(historyEventList); +} + +void CEventHisThread::search(const QString &sql, QList &eventList) +{ + if(m_pReadDb->isOpen()) + { + QSqlQuery query; + try + { + m_pReadDb->execute(sql,query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + + if(query.isActive()) + { + while(query.next()) + { + EventMsgPtr info(new CEventMsgInfo); + info->time_stamp = query.value(0).toULongLong(); + info->priority = query.value(1).toInt(); + info->location_id = query.value(2).toInt(); + info->region_id = query.value(3).toInt(); + info->content = query.value(4).toString(); + info->alm_type = query.value(5).toInt(); + info->alm_status = query.value(6).toInt(); + int logic = query.value(7).toInt(); + if(logic == 0) + { + info->alm_style = AS_ALARM; + }else if(logic ==1) + { + info->alm_style = AS_ALARM_RTN; + }else + { + info->alm_style = AS_EVENT_ONLY; + } + info->dev_type = query.value(8).toInt(); + info->cfm_user = query.value(9).toUInt(); + info->cfm_time = query.value(10).toULongLong(); + info->key_id_tag = query.value(11).toString(); + info->priorityOrder = queryPriorityOrder(info->priority); + info->wave_file = query.value(12).toString(); + info->dev_group_tag = query.value(13).toString(); + info->sub_system = query.value(14).toInt(); + + + eventList.append(info); + } + } + } +} diff --git a/product/src/gui/plugin/EventWidget/CEventHisThread.h b/product/src/gui/plugin/EventWidget/CEventHisThread.h index fdbd92fc..44324983 100644 --- a/product/src/gui/plugin/EventWidget/CEventHisThread.h +++ b/product/src/gui/plugin/EventWidget/CEventHisThread.h @@ -1,50 +1,50 @@ -#ifndef CEVENTHISTHREAD_H -#define CEVENTHISTHREAD_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "CEventMsgInfo.h" -#include "db_api_ex/CDbApi.h" -#include - -class CEventHisThread : public QObject -{ - Q_OBJECT -public: - explicit CEventHisThread(QObject *parent = nullptr); - ~CEventHisThread(); - void init(); -private: - int queryPriorityOrder(int &id); - - void condition(QList &showEventList,QList &listEvents); - bool conditionFilter(const EventMsgPtr info); - - QString buildCondition(); - QString buildLocAndRegion(); - QString buildConditionPartPriority(); - QString buildConditionPartStatus(); - QString buildConditionPartLocation(); - QString buildConditionPartRegion(); - QString buildConditionPartDeviceType(); - QString buildConditionPartContent(); - -public slots: - void doWork(ST_FILTER stFilter); - - void doReturnFilterEnable(); - - void doReturnFilterDisenable(); - - void search(const QString &sql, QList &eventList); - -signals: - void sigUpdateHisEvent(QList eventSet); - -private: - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; - ST_FILTER m_stFilter; -}; - -#endif // CEVENTHISTHREAD_H +#ifndef CEVENTHISTHREAD_H +#define CEVENTHISTHREAD_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "CEventMsgInfo.h" +#include "db_api_ex/CDbApi.h" +#include + +class CEventHisThread : public QObject +{ + Q_OBJECT +public: + explicit CEventHisThread(QObject *parent = nullptr); + ~CEventHisThread(); + void init(); +private: + int queryPriorityOrder(int &id); + + void condition(QList &showEventList,QList &listEvents); + bool conditionFilter(const EventMsgPtr info); + + QString buildCondition(); + QString buildLocAndRegion(); + QString buildConditionPartPriority(); + QString buildConditionPartStatus(); + QString buildConditionPartLocation(); + QString buildConditionPartRegion(); + QString buildConditionPartDeviceType(); + QString buildConditionPartContent(); + +public slots: + void doWork(ST_FILTER stFilter); + + void doReturnFilterEnable(); + + void doReturnFilterDisenable(); + + void search(const QString &sql, QList &eventList); + +signals: + void sigUpdateHisEvent(QList eventSet); + +private: + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + ST_FILTER m_stFilter; +}; + +#endif // CEVENTHISTHREAD_H diff --git a/product/src/gui/plugin/EventWidget/CEventHistoryModel.cpp b/product/src/gui/plugin/EventWidget/CEventHistoryModel.cpp index 8c0e6cac..f1e69a77 100644 --- a/product/src/gui/plugin/EventWidget/CEventHistoryModel.cpp +++ b/product/src/gui/plugin/EventWidget/CEventHistoryModel.cpp @@ -1,981 +1,981 @@ -#include "CEventHistoryModel.h" -#include "CEventMsgInfo.h" -#include -#include -#include -#include "CEventDataCollect.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" -#include "perm_mng_api/PermMngApi.h" -#include "service/alarm_server_api/AlarmCommonDef.h" -#include "CEventMsgManage.h" -///////////////////////////////////////////////////////////////////////////// - -typedef QPair > PAIRLISTALARMINFO; - -CEventHistoryModel::CEventHistoryModel(QObject *parent) - :QAbstractTableModel(parent), - m_sortKey(E_SORT_TIME), - m_order(Qt::DescendingOrder) -{ - header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("复归状态")<< tr("专业")<< tr("设备组")<< tr("确认人")<< tr("确认时间")<< tr("点标签")<< tr("事件内容") ; - initialize(); -} - -CEventHistoryModel::~CEventHistoryModel() -{ - m_listShowEventInfo.clear(); - m_listAllEventInfo.clear(); -} - -void CEventHistoryModel::initialize() -{ - beginResetModel(); - m_listShowEventInfo.clear(); - m_listAllEventInfo.clear(); - endResetModel(); - initFilter(); -} - -void CEventHistoryModel::initFilter() -{ - m_isLevelFilterEnable = false; - m_levelFilter.clear(); - m_isLocationFilterEnable = false; - m_locationFilter.clear(); - m_isRegionFilterEnable = false; - m_regionFilter.clear(); - m_isStatusFilterEnable = false; - m_statusFilter.clear(); - m_statusFilter2.clear(); - m_isDeviceTypeFileter = false; - m_subSystem = QString(); - m_deviceType = QString(); - m_isKeywordEnable = false; - m_keyword = QString(); - m_timeFilterEnable = false; - - m_isReturnFilterEnable = false; - m_isReturn = false; - addDeviceGroupFilter(); - - // m_isLevelFilterEnable = false; - // m_levelFilter = CEventDataCollect::instance()->priorityList(); - // m_isLocationFilterEnable = false; - // m_locationFilter = CEventDataCollect::instance()->locationList(); - // m_isRegionFilterEnable = false; - // m_regionFilter = CEventDataCollect::instance()->regionList(); - // m_isTypeFilterEnable = false; - // m_typeFilter = CEventDataCollect::instance()->alarmTypeList(); - // setFilter(m_isLevelFilterEnable, m_levelFilter, m_isLocationFilterEnable, m_locationFilter, m_isRegionFilterEnable, m_regionFilter, m_isTypeFilterEnable, m_typeFilter); -} - -void CEventHistoryModel::loadEventHistoryData() -{ - //< 权限判断 - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecLocationId; - std::vector vecRegionId; - if( PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - emit sigPermInvalid(); - return; - } - } - - //< 报警类型 - QStringList listHistoryEventTableName; - listHistoryEventTableName.append("his_event"); - emit sigHisEventRequesting(); - - ST_FILTER stFilter; - setStFilter(stFilter); - emit requestHistory(stFilter); -} - -QString CEventHistoryModel::bulidCondition() -{ - QString conditionFilter; - - //< 内容 - QString content = bulidConditionPartContent(); - if(!content.isEmpty()) - { - conditionFilter += content; - } - - //< 等级 - QString priority = bulidConditionPartPriority(); - if(!conditionFilter.isEmpty() && !priority.isEmpty()) - { - conditionFilter += " AND "; - } - if(!priority.isEmpty()) - { - conditionFilter += priority; - } - //< 告警状态 - QString status = bulidConditionPartStatus(); - if(!conditionFilter.isEmpty() && !status.isEmpty()) - { - conditionFilter += " AND "; - } - if(!status.isEmpty()) - { - conditionFilter += status; - } - //< 复归状态 - QString returnStatus = buildConditionParaReturnStatus(); - if(!conditionFilter.isEmpty() && !returnStatus.isEmpty()) - { - conditionFilter += " AND "; - } - if(!returnStatus.isEmpty()) - { - conditionFilter += returnStatus; - } - //LOGDEBUG("bulidConditionPartStatus():[%s]",status.toStdString().c_str()); - //< 车站 - - // kbd_public::SNodeInfo stNodeInfo; - // kbd_public::SLocationInfo stLocationInfo; - // kbd_public::CSysInfoInterfacePtr spSysInfo; - // if (kbd_public::createSysInfoInstance(spSysInfo)) - // { - // spSysInfo->getLocalNodeInfo(stNodeInfo); - // spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); - // } - // else - // { - // LOGERROR("历史事件-无法获取位置信息...") - - // } - // bool bIsCenter = stLocationInfo.bIsCenter; - // int nLocationId = stNodeInfo.nLocationId; - - // QString location_id; - // if(bIsCenter) - // { - // location_id = bulidConditionPartInteger(m_isLocationFilterEnable, "location_id", m_locationFilter); - // } - // else - // { - // QList location; - // location.append(nLocationId); - // location_id = bulidConditionPartInteger(true, "location_id", location); - // } - QString location_id = bulidConditionPartLocation(); - if(!conditionFilter.isEmpty() && !location_id.isEmpty()) - { - conditionFilter += " AND "; - } - if(!location_id.isEmpty()) - { - conditionFilter += location_id; - } - - //< 责任区 - QString region_id = bulidConditionPartRegion(); - if(!conditionFilter.isEmpty() && !region_id.isEmpty()) - { - conditionFilter += " AND "; - } - if(!region_id.isEmpty()) - { - conditionFilter += region_id; - } - - //< 设备类型 - QString device_type = bulidConditionPartDeviceType(); - if(!conditionFilter.isEmpty() && !device_type.isEmpty()) - { - conditionFilter += " AND "; - } - if(!device_type.isEmpty()) - { - conditionFilter += device_type; - } - - //< 时标 - QString time_stamp = bulidConditionPartDateTime(); - if(!conditionFilter.isEmpty() && !time_stamp.isEmpty()) - { - conditionFilter += " AND "; - } - if(!time_stamp.isEmpty()) - { - conditionFilter += time_stamp; - } - - return conditionFilter; -} - -QString CEventHistoryModel::bulidConditionPartPriority() -{ - if(m_isLevelFilterEnable) - { - QString strFilter; - for(int nIndex = 0; nIndex < m_levelFilter.size(); nIndex++) - { - strFilter.append(QString::number(m_levelFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); - } - return strFilter; - } - return QString(); -} - -QString CEventHistoryModel::bulidConditionPartStatus() -{ - if(m_isStatusFilterEnable) - { - QString strFilter; - for(int nIndex = 0; nIndex < m_statusFilter.size(); nIndex++) - { - strFilter.append(QString::number(m_statusFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("alm_status").arg(strFilter); - } - return strFilter; - } - return QString(); -} - -QString CEventHistoryModel::buildConditionParaReturnStatus() -{ - if(m_isReturnFilterEnable) - { - QString strFilter; - if(m_isReturn) - { - strFilter = QString("%1 = %2").arg("alm_style").arg(1);//返回状态 返回确认状态 返回删除状态 返回确认删除状态 - }else - { - strFilter = QString("%1 = %2").arg("alm_style").arg(0); - } - return strFilter; - } - return QString(); -} - -QString CEventHistoryModel::bulidConditionPartLocation() -{ - QList locationFilter; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecLocationId; - std::vector vecRegionId; - if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - if(m_isLocationFilterEnable) - { - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - if(m_locationFilter.contains(*location)) - { - locationFilter.append(*location); - } - location++; - } - } - else - { - locationFilter = QVector::fromStdVector(vecLocationId).toList(); - } - } - else - { - return QString(); - } - } - - QString strFilter; - for(int nIndex = 0; nIndex < locationFilter.size(); nIndex++) - { - strFilter.append(QString::number(locationFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); - }else - { - strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); - } - return strFilter; -} - -QString CEventHistoryModel::bulidConditionPartRegion() -{ - QList regionFilter; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecLocationId; - std::vector vecRegionId; - if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - if(m_isRegionFilterEnable) - { - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - if(m_regionFilter.contains(*region)) - { - regionFilter.append(*region); - } - region++; - } - } - else - { - regionFilter = QVector::fromStdVector(vecRegionId).toList(); - } - } - else - { - return QString(); - } - } - - - QString strFilter; - for(int nIndex = 0; nIndex < regionFilter.size(); nIndex++) - { - strFilter.append(QString::number(regionFilter.at(nIndex)) + ", "); - } - strFilter.append(QString::number(0) + ", ");//防止责任区为空 - strFilter.append(QString::number(-1) + ", ");//防止责任区为空 - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); - }else - { - strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); - } - return strFilter; -} - -QString CEventHistoryModel::bulidConditionPartDeviceType() -{ - if(m_isDeviceTypeFileter) - { - return QString("(%1 = %2)").arg("dev_type").arg(CEventDataCollect::instance()->deviceTypeId(m_deviceType)); - } - return QString(); -} - -QString CEventHistoryModel::bulidConditionPartContent() -{ - if(m_isKeywordEnable && !m_keyword.isEmpty()) - { - QString strFilter = QString("(%1 like '%" ).arg("content") + m_keyword + QString("%')"); - return strFilter; - } - return QString(); -} - -QString CEventHistoryModel::bulidConditionPartDateTime() -{ - if(m_timeFilterEnable) - { - qint64 start_timeStamp = m_startTime.toMSecsSinceEpoch(); - qint64 end_timeStamp = m_endTime.toMSecsSinceEpoch(); - QString strFilter = QString("(%1 between %2 AND %3)").arg("time_stamp").arg(start_timeStamp).arg(end_timeStamp); - return strFilter; - } - return QString(); -} - -EventMsgPtr CEventHistoryModel::getAlarmInfo(const QModelIndex &index) const -{ - if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) - { - return NULL; - } - - return m_listShowEventInfo.at(index.row()); -} - -QVariant CEventHistoryModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(header.at(section)); - } - return QVariant(); -} - -QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - else if(Qt::DisplayRole == role) - { - - switch ( index.column() ) - { - case 0 : - { - return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - case 1 : - { - return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); - } - case 2 : - { - return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); - } - case 3 : - { - return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); - } - case 4 : - { - return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); - } - case 5 : - { - return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); - } - case 6 : - { - if(m_listShowEventInfo.at(index.row())->alm_style == AS_ALARM) //未复归 - { - return tr("未复归"); - } - else if(m_listShowEventInfo.at(index.row())->alm_style == AS_ALARM_RTN) //已复归 - { - return tr("已复归"); - }else{ - return QString("-"); - } - } - - case 7 : - { - return CEventDataCollect::instance()->subSystemDescription(m_listShowEventInfo.at(index.row())->sub_system); - - - } - case 8 : - { - QString dev_group_name = CEventDataCollect::instance()->deviceGroupDescription(m_listShowEventInfo.at(index.row())->dev_group_tag); - if(dev_group_name.isEmpty()) - { - return QString("-"); - }else - { - return dev_group_name; - } - - - } - case 9 : - { - - QString userName = CEventDataCollect::instance()->userNameDescription(m_listShowEventInfo.at(index.row())->cfm_user); - if(userName.isEmpty()) - { - return QString("-"); - }else - { - return userName; - } - } - case 10 : - { - - if(m_listShowEventInfo.at(index.row())->cfm_time == 0) - { - return QString("-"); - }else - { - return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->cfm_time).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - } - case 11 : - { - if(m_listShowEventInfo.at(index.row())->key_id_tag =="") - { - return QString("-"); - }else - { - return m_listShowEventInfo.at(index.row())->key_id_tag; - } - } case 12 : - { - - return m_listShowEventInfo.at(index.row())->content; - - } - - default: - return QVariant(); - } - } - return QVariant(); -} - -int CEventHistoryModel::columnCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - - return header.count(); -} - -int CEventHistoryModel::rowCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - return m_listShowEventInfo.count(); -} - -Qt::ItemFlags CEventHistoryModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CEventHistoryModel::sort() -{ - QMap mapAlarmInfo; - //<分 - for(int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) - { - EventMsgPtr temp = m_listShowEventInfo.at(nIndex); - mapAlarmInfo[nIndex / 1000].second.append(temp); - } - - //<快速排序 - for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) - { - qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); - } - - //<治 - PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; - for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) - { - //<归并 - tempListAlarmInfo.first = 0; - mapAlarmInfo[nPairIndex].first = 0; - while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) - { - if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) - { - tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - } - tempListAlarmInfo.first += 1; - } - } - m_listShowEventInfo = tempListAlarmInfo.second; -} - -void CEventHistoryModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CEventHistoryModel::partitionAscendingOrder(QList &list, int start, int last) -{ - EventMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftlessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CEventHistoryModel::partitionDescendingOrder(QList &list, int start, int last) -{ - EventMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -void CEventHistoryModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, - const bool &isKeywordFilterEnable, const QString &keyword, - const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, const bool &isReturnFilterEnable, const bool &isReturn) -{ - m_isLevelFilterEnable = isLevelFilterEnable; - m_levelFilter = levelFilter; - m_isLocationFilterEnable = isStationFilterEnable; - m_locationFilter = stationFilter; - m_isRegionFilterEnable = isRegionFilterEnable; - m_regionFilter = regionFilter; - m_isStatusFilterEnable = isTypeFilterEnable; - m_statusFilter = typeFilter; - m_statusFilter2 = typeFilter; - m_isReturnFilterEnable = isReturnFilterEnable; - m_isReturn = isReturn; - if(typeFilter.contains(OTHERSTATUS)) - { - QMap alarmOtherMap = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); - QMap::iterator it = alarmOtherMap.begin(); - for(;it != alarmOtherMap.end(); ++it) - { - m_statusFilter.append(it.key()); - } - } - m_isDeviceTypeFileter = isDeviceTypeFilter; - m_subSystem = subSystem; - m_deviceType = deviceType; - m_isKeywordEnable = isKeywordFilterEnable; - m_keyword = keyword; - m_timeFilterEnable = timeFilterEnable; - m_startTime = startTime; - m_endTime = endTime; -} - -void CEventHistoryModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, - bool &returnFilterEnable,bool &isReturn) -{ - isLevelFilterEnable = m_isLevelFilterEnable; - levelFilter = m_levelFilter; - isLocationFilterEnable = m_isLocationFilterEnable; - locationFilter = m_locationFilter; - isRegionFilterEnable = m_isRegionFilterEnable; - regionFilter = m_regionFilter; - isTypeFilterEnable = m_isStatusFilterEnable; - alarmTypeFilter = m_statusFilter2; - subSystem = m_subSystem; - deviceTypeFilter = m_isDeviceTypeFileter; - deviceType = m_deviceType; - keywordFilterEnable = m_isKeywordEnable; - keyword = m_keyword; - timeFilterEnable = m_timeFilterEnable; - startTime = m_startTime; - endTime = m_endTime; - returnFilterEnable = m_isReturnFilterEnable; - isReturn = m_isReturn; -} - -bool CEventHistoryModel::conditionFilter(EventMsgPtr info) -{ - if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) - { - return false; - } - if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) - { - return false; - } - - if(m_isRegionFilterEnable) - { - if(!m_regionFilter.contains(info->region_id)) - { - return false; - } - } - else - { - if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 - { - return false; - } - } - //事件状态过滤 - if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) - { - return false; - } - if(m_isDeviceTypeFileter) - { - if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) - { - return false; - } - } - if(m_isKeywordEnable) - { - if(!info->content.contains(m_keyword)) - { - return false; - } - } - if(m_timeFilterEnable) - { - if(m_startTime.toMSecsSinceEpoch() >= (qint64)info->time_stamp) - { - return false; - } - if(m_endTime.toMSecsSinceEpoch() <= (qint64)info->time_stamp) - { - return false; - } - } - if(m_isReturnFilterEnable) - { - if(m_isReturn) - { - if(info->alm_style != AS_ALARM_RTN ) - { - return false; - } - } - else - { - if(info->alm_style != AS_ALARM) - { - return false; - } - } - } - - return true; -} - -void CEventHistoryModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - m_isLevelFilterEnable = isCheck; - m_levelFilter = priorityFilter; -} - -void CEventHistoryModel::setLocationFilter(bool &isCheck, QList &locationFilter) -{ - m_isLocationFilterEnable = isCheck; - m_locationFilter = locationFilter; -} - -void CEventHistoryModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other) -{ - m_isStatusFilterEnable = isCheck; - m_statusFilter = eventTypeFilter; - m_statusFilter2 = eventTypeFilter; - if(other == true) - { - QMap otherEventStatus = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); - QMap::iterator it = otherEventStatus.begin(); - for(;it != otherEventStatus.end(); ++it) - { - m_statusFilter.append(it.key()); - } - } -} - -void CEventHistoryModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) -{ - m_timeFilterEnable = isCheck; - if(isCheck) - { - QTime time_1(0,0,0); - QTime time_2(23,59,59); - m_startTime.setDate(startTime); - m_startTime.setTime(time_1); - m_endTime.setDate(endTime); - m_endTime.setTime(time_2); - } -} - -void CEventHistoryModel::setEventTimeFilter(bool &isCheck) -{ - m_timeFilterEnable = isCheck; -} - -void CEventHistoryModel::getPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - isCheck = m_isLevelFilterEnable; - priorityFilter = m_levelFilter; -} - -void CEventHistoryModel::getLocationFilter(bool &isCheck, QList &locationFilter) -{ - isCheck = m_isLocationFilterEnable; - locationFilter = m_locationFilter; -} - -void CEventHistoryModel::getEventStatusFilter(bool &isCheck, QList &eventStatusFilter) -{ - isCheck = m_isStatusFilterEnable; - eventStatusFilter = m_statusFilter2; -} - -QList CEventHistoryModel::getListEventInfo() -{ - return m_listShowEventInfo; -} - -void CEventHistoryModel::addDeviceGroupFilter() -{ - for(QString group : CEventDataCollect::instance()->getDevGroupTagList()) - { - m_deviceGroupFilter.insert(group); - } -} - -void CEventHistoryModel::removeDeviceGroupFilter() -{ - m_deviceGroupFilter.clear(); -} - -void CEventHistoryModel::addDeviceGroupFilter(const QString &device) -{ - QString deviceG = device; - QStringList devGList = deviceG.split(","); - foreach (QString devG, devGList) { - m_deviceGroupFilter.insert(devG); - } -} - -void CEventHistoryModel::removeDeviceGroupFilter(const QString &device) -{ - m_deviceGroupFilter.remove(device); -} - -void CEventHistoryModel::updateEvents(QList eventList) -{ - m_listAllEventInfo = eventList; - - updateShowEvents(); -} - -void CEventHistoryModel::updateShowEvents() -{ - beginResetModel(); - m_listShowEventInfo.clear(); - QList::iterator it = m_listAllEventInfo.begin(); - while (it != m_listAllEventInfo.end()) { - //< 设备组 - if((*it)->dev_group_tag.isEmpty() || m_deviceGroupFilter.contains((*it)->dev_group_tag)) - { - m_listShowEventInfo.append(*it); - } - it++; - } - endResetModel(); - emit sigHisEventSizeChanged(); -} - -void CEventHistoryModel::setStFilter(ST_FILTER &stFilter) -{ - stFilter.isLevelFilterEnable = m_isLevelFilterEnable; - stFilter.levelFilter = m_levelFilter; - stFilter.isLocationFilterEnable = m_isLocationFilterEnable; - stFilter.locationFilter = m_locationFilter; - stFilter.isRegionFilterEnable = m_isRegionFilterEnable; - stFilter.regionFilter = m_regionFilter; - stFilter.isStatusFilterEnable = m_isStatusFilterEnable; - stFilter.statusFilter = m_statusFilter; - stFilter.statusFilter2 = m_statusFilter2; - stFilter.isDeviceTypeFileter = m_isDeviceTypeFileter; - - stFilter.subSystem = m_subSystem; - stFilter.deviceType = m_deviceType; - stFilter.isKeywordEnable = m_isKeywordEnable; - stFilter.keyword = m_keyword; - stFilter.timeFilterEnable = m_timeFilterEnable; - stFilter.startTime = m_startTime; - stFilter.endTime = m_endTime; - - stFilter.isReturnFilterEnable = m_isReturnFilterEnable; - stFilter.isReturn = m_isReturn; - -} +#include "CEventHistoryModel.h" +#include "CEventMsgInfo.h" +#include +#include +#include +#include "CEventDataCollect.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include "perm_mng_api/PermMngApi.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include "CEventMsgManage.h" +///////////////////////////////////////////////////////////////////////////// + +typedef QPair > PAIRLISTALARMINFO; + +CEventHistoryModel::CEventHistoryModel(QObject *parent) + :QAbstractTableModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::DescendingOrder) +{ + header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("复归状态")<< tr("专业")<< tr("设备组")<< tr("确认人")<< tr("确认时间")<< tr("点标签")<< tr("事件内容") ; + initialize(); +} + +CEventHistoryModel::~CEventHistoryModel() +{ + m_listShowEventInfo.clear(); + m_listAllEventInfo.clear(); +} + +void CEventHistoryModel::initialize() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + m_listAllEventInfo.clear(); + endResetModel(); + initFilter(); +} + +void CEventHistoryModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_levelFilter.clear(); + m_isLocationFilterEnable = false; + m_locationFilter.clear(); + m_isRegionFilterEnable = false; + m_regionFilter.clear(); + m_isStatusFilterEnable = false; + m_statusFilter.clear(); + m_statusFilter2.clear(); + m_isDeviceTypeFileter = false; + m_subSystem = QString(); + m_deviceType = QString(); + m_isKeywordEnable = false; + m_keyword = QString(); + m_timeFilterEnable = false; + + m_isReturnFilterEnable = false; + m_isReturn = false; + addDeviceGroupFilter(); + + // m_isLevelFilterEnable = false; + // m_levelFilter = CEventDataCollect::instance()->priorityList(); + // m_isLocationFilterEnable = false; + // m_locationFilter = CEventDataCollect::instance()->locationList(); + // m_isRegionFilterEnable = false; + // m_regionFilter = CEventDataCollect::instance()->regionList(); + // m_isTypeFilterEnable = false; + // m_typeFilter = CEventDataCollect::instance()->alarmTypeList(); + // setFilter(m_isLevelFilterEnable, m_levelFilter, m_isLocationFilterEnable, m_locationFilter, m_isRegionFilterEnable, m_regionFilter, m_isTypeFilterEnable, m_typeFilter); +} + +void CEventHistoryModel::loadEventHistoryData() +{ + //< 权限判断 + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if( PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + emit sigPermInvalid(); + return; + } + } + + //< 报警类型 + QStringList listHistoryEventTableName; + listHistoryEventTableName.append("his_event"); + emit sigHisEventRequesting(); + + ST_FILTER stFilter; + setStFilter(stFilter); + emit requestHistory(stFilter); +} + +QString CEventHistoryModel::bulidCondition() +{ + QString conditionFilter; + + //< 内容 + QString content = bulidConditionPartContent(); + if(!content.isEmpty()) + { + conditionFilter += content; + } + + //< 等级 + QString priority = bulidConditionPartPriority(); + if(!conditionFilter.isEmpty() && !priority.isEmpty()) + { + conditionFilter += " AND "; + } + if(!priority.isEmpty()) + { + conditionFilter += priority; + } + //< 告警状态 + QString status = bulidConditionPartStatus(); + if(!conditionFilter.isEmpty() && !status.isEmpty()) + { + conditionFilter += " AND "; + } + if(!status.isEmpty()) + { + conditionFilter += status; + } + //< 复归状态 + QString returnStatus = buildConditionParaReturnStatus(); + if(!conditionFilter.isEmpty() && !returnStatus.isEmpty()) + { + conditionFilter += " AND "; + } + if(!returnStatus.isEmpty()) + { + conditionFilter += returnStatus; + } + //LOGDEBUG("bulidConditionPartStatus():[%s]",status.toStdString().c_str()); + //< 车站 + + // kbd_public::SNodeInfo stNodeInfo; + // kbd_public::SLocationInfo stLocationInfo; + // kbd_public::CSysInfoInterfacePtr spSysInfo; + // if (kbd_public::createSysInfoInstance(spSysInfo)) + // { + // spSysInfo->getLocalNodeInfo(stNodeInfo); + // spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); + // } + // else + // { + // LOGERROR("历史事件-无法获取位置信息...") + + // } + // bool bIsCenter = stLocationInfo.bIsCenter; + // int nLocationId = stNodeInfo.nLocationId; + + // QString location_id; + // if(bIsCenter) + // { + // location_id = bulidConditionPartInteger(m_isLocationFilterEnable, "location_id", m_locationFilter); + // } + // else + // { + // QList location; + // location.append(nLocationId); + // location_id = bulidConditionPartInteger(true, "location_id", location); + // } + QString location_id = bulidConditionPartLocation(); + if(!conditionFilter.isEmpty() && !location_id.isEmpty()) + { + conditionFilter += " AND "; + } + if(!location_id.isEmpty()) + { + conditionFilter += location_id; + } + + //< 责任区 + QString region_id = bulidConditionPartRegion(); + if(!conditionFilter.isEmpty() && !region_id.isEmpty()) + { + conditionFilter += " AND "; + } + if(!region_id.isEmpty()) + { + conditionFilter += region_id; + } + + //< 设备类型 + QString device_type = bulidConditionPartDeviceType(); + if(!conditionFilter.isEmpty() && !device_type.isEmpty()) + { + conditionFilter += " AND "; + } + if(!device_type.isEmpty()) + { + conditionFilter += device_type; + } + + //< 时标 + QString time_stamp = bulidConditionPartDateTime(); + if(!conditionFilter.isEmpty() && !time_stamp.isEmpty()) + { + conditionFilter += " AND "; + } + if(!time_stamp.isEmpty()) + { + conditionFilter += time_stamp; + } + + return conditionFilter; +} + +QString CEventHistoryModel::bulidConditionPartPriority() +{ + if(m_isLevelFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_levelFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_levelFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartStatus() +{ + if(m_isStatusFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_statusFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_statusFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("alm_status").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::buildConditionParaReturnStatus() +{ + if(m_isReturnFilterEnable) + { + QString strFilter; + if(m_isReturn) + { + strFilter = QString("%1 = %2").arg("alm_style").arg(1);//返回状态 返回确认状态 返回删除状态 返回确认删除状态 + }else + { + strFilter = QString("%1 = %2").arg("alm_style").arg(0); + } + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartLocation() +{ + QList locationFilter; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_isLocationFilterEnable) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + if(m_locationFilter.contains(*location)) + { + locationFilter.append(*location); + } + location++; + } + } + else + { + locationFilter = QVector::fromStdVector(vecLocationId).toList(); + } + } + else + { + return QString(); + } + } + + QString strFilter; + for(int nIndex = 0; nIndex < locationFilter.size(); nIndex++) + { + strFilter.append(QString::number(locationFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); + }else + { + strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); + } + return strFilter; +} + +QString CEventHistoryModel::bulidConditionPartRegion() +{ + QList regionFilter; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_isRegionFilterEnable) + { + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + if(m_regionFilter.contains(*region)) + { + regionFilter.append(*region); + } + region++; + } + } + else + { + regionFilter = QVector::fromStdVector(vecRegionId).toList(); + } + } + else + { + return QString(); + } + } + + + QString strFilter; + for(int nIndex = 0; nIndex < regionFilter.size(); nIndex++) + { + strFilter.append(QString::number(regionFilter.at(nIndex)) + ", "); + } + strFilter.append(QString::number(0) + ", ");//防止责任区为空 + strFilter.append(QString::number(-1) + ", ");//防止责任区为空 + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); + }else + { + strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); + } + return strFilter; +} + +QString CEventHistoryModel::bulidConditionPartDeviceType() +{ + if(m_isDeviceTypeFileter) + { + return QString("(%1 = %2)").arg("dev_type").arg(CEventDataCollect::instance()->deviceTypeId(m_deviceType)); + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartContent() +{ + if(m_isKeywordEnable && !m_keyword.isEmpty()) + { + QString strFilter = QString("(%1 like '%" ).arg("content") + m_keyword + QString("%')"); + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartDateTime() +{ + if(m_timeFilterEnable) + { + qint64 start_timeStamp = m_startTime.toMSecsSinceEpoch(); + qint64 end_timeStamp = m_endTime.toMSecsSinceEpoch(); + QString strFilter = QString("(%1 between %2 AND %3)").arg("time_stamp").arg(start_timeStamp).arg(end_timeStamp); + return strFilter; + } + return QString(); +} + +EventMsgPtr CEventHistoryModel::getAlarmInfo(const QModelIndex &index) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return NULL; + } + + return m_listShowEventInfo.at(index.row()); +} + +QVariant CEventHistoryModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(header.at(section)); + } + return QVariant(); +} + +QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + else if(Qt::DisplayRole == role) + { + + switch ( index.column() ) + { + case 0 : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case 1 : + { + return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); + } + case 2 : + { + return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); + } + case 3 : + { + return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); + } + case 4 : + { + return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); + } + case 5 : + { + return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); + } + case 6 : + { + if(m_listShowEventInfo.at(index.row())->alm_style == AS_ALARM) //未复归 + { + return tr("未复归"); + } + else if(m_listShowEventInfo.at(index.row())->alm_style == AS_ALARM_RTN) //已复归 + { + return tr("已复归"); + }else{ + return QString("-"); + } + } + + case 7 : + { + return CEventDataCollect::instance()->subSystemDescription(m_listShowEventInfo.at(index.row())->sub_system); + + + } + case 8 : + { + QString dev_group_name = CEventDataCollect::instance()->deviceGroupDescription(m_listShowEventInfo.at(index.row())->dev_group_tag); + if(dev_group_name.isEmpty()) + { + return QString("-"); + }else + { + return dev_group_name; + } + + + } + case 9 : + { + + QString userName = CEventDataCollect::instance()->userNameDescription(m_listShowEventInfo.at(index.row())->cfm_user); + if(userName.isEmpty()) + { + return QString("-"); + }else + { + return userName; + } + } + case 10 : + { + + if(m_listShowEventInfo.at(index.row())->cfm_time == 0) + { + return QString("-"); + }else + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->cfm_time).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + } + case 11 : + { + if(m_listShowEventInfo.at(index.row())->key_id_tag =="") + { + return QString("-"); + }else + { + return m_listShowEventInfo.at(index.row())->key_id_tag; + } + } case 12 : + { + + return m_listShowEventInfo.at(index.row())->content; + + } + + default: + return QVariant(); + } + } + return QVariant(); +} + +int CEventHistoryModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return header.count(); +} + +int CEventHistoryModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + return m_listShowEventInfo.count(); +} + +Qt::ItemFlags CEventHistoryModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CEventHistoryModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr temp = m_listShowEventInfo.at(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(temp); + } + + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + + //<治 + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + m_listShowEventInfo = tempListAlarmInfo.second; +} + +void CEventHistoryModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CEventHistoryModel::partitionAscendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CEventHistoryModel::partitionDescendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CEventHistoryModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, const bool &isReturnFilterEnable, const bool &isReturn) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isStatusFilterEnable = isTypeFilterEnable; + m_statusFilter = typeFilter; + m_statusFilter2 = typeFilter; + m_isReturnFilterEnable = isReturnFilterEnable; + m_isReturn = isReturn; + if(typeFilter.contains(OTHERSTATUS)) + { + QMap alarmOtherMap = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); + QMap::iterator it = alarmOtherMap.begin(); + for(;it != alarmOtherMap.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyword = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; +} + +void CEventHistoryModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &returnFilterEnable,bool &isReturn) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isTypeFilterEnable = m_isStatusFilterEnable; + alarmTypeFilter = m_statusFilter2; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyword; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; + returnFilterEnable = m_isReturnFilterEnable; + isReturn = m_isReturn; +} + +bool CEventHistoryModel::conditionFilter(EventMsgPtr info) +{ + if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) + { + return false; + } + if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) + { + return false; + } + + if(m_isRegionFilterEnable) + { + if(!m_regionFilter.contains(info->region_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 + { + return false; + } + } + //事件状态过滤 + if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) + { + return false; + } + if(m_isDeviceTypeFileter) + { + if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) + { + return false; + } + } + if(m_isKeywordEnable) + { + if(!info->content.contains(m_keyword)) + { + return false; + } + } + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() >= (qint64)info->time_stamp) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() <= (qint64)info->time_stamp) + { + return false; + } + } + if(m_isReturnFilterEnable) + { + if(m_isReturn) + { + if(info->alm_style != AS_ALARM_RTN ) + { + return false; + } + } + else + { + if(info->alm_style != AS_ALARM) + { + return false; + } + } + } + + return true; +} + +void CEventHistoryModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; +} + +void CEventHistoryModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; +} + +void CEventHistoryModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other) +{ + m_isStatusFilterEnable = isCheck; + m_statusFilter = eventTypeFilter; + m_statusFilter2 = eventTypeFilter; + if(other == true) + { + QMap otherEventStatus = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); + QMap::iterator it = otherEventStatus.begin(); + for(;it != otherEventStatus.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } +} + +void CEventHistoryModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } +} + +void CEventHistoryModel::setEventTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; +} + +void CEventHistoryModel::getPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + isCheck = m_isLevelFilterEnable; + priorityFilter = m_levelFilter; +} + +void CEventHistoryModel::getLocationFilter(bool &isCheck, QList &locationFilter) +{ + isCheck = m_isLocationFilterEnable; + locationFilter = m_locationFilter; +} + +void CEventHistoryModel::getEventStatusFilter(bool &isCheck, QList &eventStatusFilter) +{ + isCheck = m_isStatusFilterEnable; + eventStatusFilter = m_statusFilter2; +} + +QList CEventHistoryModel::getListEventInfo() +{ + return m_listShowEventInfo; +} + +void CEventHistoryModel::addDeviceGroupFilter() +{ + for(QString group : CEventDataCollect::instance()->getDevGroupTagList()) + { + m_deviceGroupFilter.insert(group); + } +} + +void CEventHistoryModel::removeDeviceGroupFilter() +{ + m_deviceGroupFilter.clear(); +} + +void CEventHistoryModel::addDeviceGroupFilter(const QString &device) +{ + QString deviceG = device; + QStringList devGList = deviceG.split(","); + foreach (QString devG, devGList) { + m_deviceGroupFilter.insert(devG); + } +} + +void CEventHistoryModel::removeDeviceGroupFilter(const QString &device) +{ + m_deviceGroupFilter.remove(device); +} + +void CEventHistoryModel::updateEvents(QList eventList) +{ + m_listAllEventInfo = eventList; + + updateShowEvents(); +} + +void CEventHistoryModel::updateShowEvents() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + QList::iterator it = m_listAllEventInfo.begin(); + while (it != m_listAllEventInfo.end()) { + //< 设备组 + if((*it)->dev_group_tag.isEmpty() || m_deviceGroupFilter.contains((*it)->dev_group_tag)) + { + m_listShowEventInfo.append(*it); + } + it++; + } + endResetModel(); + emit sigHisEventSizeChanged(); +} + +void CEventHistoryModel::setStFilter(ST_FILTER &stFilter) +{ + stFilter.isLevelFilterEnable = m_isLevelFilterEnable; + stFilter.levelFilter = m_levelFilter; + stFilter.isLocationFilterEnable = m_isLocationFilterEnable; + stFilter.locationFilter = m_locationFilter; + stFilter.isRegionFilterEnable = m_isRegionFilterEnable; + stFilter.regionFilter = m_regionFilter; + stFilter.isStatusFilterEnable = m_isStatusFilterEnable; + stFilter.statusFilter = m_statusFilter; + stFilter.statusFilter2 = m_statusFilter2; + stFilter.isDeviceTypeFileter = m_isDeviceTypeFileter; + + stFilter.subSystem = m_subSystem; + stFilter.deviceType = m_deviceType; + stFilter.isKeywordEnable = m_isKeywordEnable; + stFilter.keyword = m_keyword; + stFilter.timeFilterEnable = m_timeFilterEnable; + stFilter.startTime = m_startTime; + stFilter.endTime = m_endTime; + + stFilter.isReturnFilterEnable = m_isReturnFilterEnable; + stFilter.isReturn = m_isReturn; + +} diff --git a/product/src/gui/plugin/EventWidget/CEventHistoryModel.h b/product/src/gui/plugin/EventWidget/CEventHistoryModel.h index ee48164d..314a1f29 100644 --- a/product/src/gui/plugin/EventWidget/CEventHistoryModel.h +++ b/product/src/gui/plugin/EventWidget/CEventHistoryModel.h @@ -1,148 +1,148 @@ -#ifndef CEVENTHISTORYMODEL_H -#define CEVENTHISTORYMODEL_H - -#include -#include -#include -#include "CEventMsgInfo.h" -#include "CEventDataCollect.h" - -#define Row_Full (15000) -#define MAX_HIS_ROWCOUNT (10000) - -class CEventMsgInfo; - -class CEventHistoryModel : public QAbstractTableModel -{ - Q_OBJECT -public: - CEventHistoryModel(QObject *parent = Q_NULLPTR); - ~CEventHistoryModel(); - - void initialize(); - void initFilter(); - - void loadEventHistoryData(); - - QString bulidCondition(); - QString bulidConditionPartPriority(); - QString bulidConditionPartStatus(); - QString buildConditionParaReturnStatus(); - QString bulidConditionPartLocation(); - QString bulidConditionPartRegion(); - QString bulidConditionPartDeviceType(); - QString bulidConditionPartContent(); - QString bulidConditionPartDateTime(); - - EventMsgPtr getAlarmInfo(const QModelIndex &index) const; - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual int columnCount(const QModelIndex &index = QModelIndex()) const; - virtual int rowCount(const QModelIndex &index = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - void sort(); - void qucikSort(QList &list, int start, int last); - int partitionAscendingOrder(QList &list, int start, int last); - int partitionDescendingOrder(QList &list, int start, int last); - /** - * 设置模型数据过滤条件,过滤显示数据 - */ - void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), - const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), - const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), - const QDateTime &endTime = QDateTime(),const bool &isReturnFilterEnable = false, const bool &isReturn = false); - - /** - * 获取模型数据过滤条件,用于初始化过滤对话框 - */ - void getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, bool &returnFilterEnable, bool &isReturn); - - bool conditionFilter(EventMsgPtr info); - - void setPriorityFilter(bool &isCheck, QList &priorityFilter); - void setLocationFilter(bool &isCheck, QList &locationFilter); - void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other); - void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); - void setEventTimeFilter(bool &isCheck); - - void getPriorityFilter(bool &isCheck,QList &priorityFilter); - - void getLocationFilter(bool &isCheck,QList &locationFilter); - - void getEventStatusFilter(bool &isCheck, QList &eventStatusFilter); - - QList getListEventInfo(); - - void addDeviceGroupFilter(); - void removeDeviceGroupFilter(); - void addDeviceGroupFilter(const QString &device); - void removeDeviceGroupFilter(const QString &device); -signals: - //void requestHistoryEvents(const QStringList &listHistoryEventTableName,QList typeFilter, const QString &conditionFilter); - void requestHistoryEvents(const QStringList &listHistoryEventTableName, const QString &conditionFilter); - void sigPermInvalid(); - void sigHisEventRequesting(); - void sigHisEventSizeChanged(); - void sigHISRecordOutOfRangeTips(QStringList stDescList); - void sigOutOfRangeTips(); - - void requestHistory(ST_FILTER stFilter); - -public slots: - void updateEvents(QList eventList); - void updateShowEvents(); - -private: - - void setStFilter(ST_FILTER &stFilter); - -private: - QStringList header; - QList m_listShowEventInfo; - QList m_listAllEventInfo; - QList m_listPermLocationId; - QList m_listPermRegionId; - - E_ALARM_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - - //Filter - bool m_isLevelFilterEnable; //是否按报警级别过滤 - QList m_levelFilter; //报警级别过滤 - bool m_isLocationFilterEnable; //是否按车站过滤 - QList m_locationFilter; //车站过滤 - bool m_isRegionFilterEnable; //是否按责任区过滤 - QList m_regionFilter; //责任区过滤 - bool m_isStatusFilterEnable; //是否按报警类型过滤 - QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) - QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) - bool m_isDeviceTypeFileter; //设备类型过滤 - QString m_subSystem; //子系统 - QString m_deviceType; //设备类型 - bool m_isKeywordEnable; //关键字过滤 - QString m_keyword; //关键字 - bool m_timeFilterEnable; //是否根据时间过滤 - QDateTime m_startTime; //起始时间 - QDateTime m_endTime; //终止时间 - - bool m_isReturnFilterEnable; //是否根据复归状态过滤 - bool m_isReturn; - - QMap m_areaInfoMap; //区域信息 - - QMap > m_areaLocMap; //区域映射 - QSet m_deviceGroupFilter; //<设备组过滤 -}; - -#endif // CEVENTHISTORYMODEL_H +#ifndef CEVENTHISTORYMODEL_H +#define CEVENTHISTORYMODEL_H + +#include +#include +#include +#include "CEventMsgInfo.h" +#include "CEventDataCollect.h" + +#define Row_Full (15000) +#define MAX_HIS_ROWCOUNT (10000) + +class CEventMsgInfo; + +class CEventHistoryModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CEventHistoryModel(QObject *parent = Q_NULLPTR); + ~CEventHistoryModel(); + + void initialize(); + void initFilter(); + + void loadEventHistoryData(); + + QString bulidCondition(); + QString bulidConditionPartPriority(); + QString bulidConditionPartStatus(); + QString buildConditionParaReturnStatus(); + QString bulidConditionPartLocation(); + QString bulidConditionPartRegion(); + QString bulidConditionPartDeviceType(); + QString bulidConditionPartContent(); + QString bulidConditionPartDateTime(); + + EventMsgPtr getAlarmInfo(const QModelIndex &index) const; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + void sort(); + void qucikSort(QList &list, int start, int last); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(),const bool &isReturnFilterEnable = false, const bool &isReturn = false); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, bool &returnFilterEnable, bool &isReturn); + + bool conditionFilter(EventMsgPtr info); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other); + void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); + void setEventTimeFilter(bool &isCheck); + + void getPriorityFilter(bool &isCheck,QList &priorityFilter); + + void getLocationFilter(bool &isCheck,QList &locationFilter); + + void getEventStatusFilter(bool &isCheck, QList &eventStatusFilter); + + QList getListEventInfo(); + + void addDeviceGroupFilter(); + void removeDeviceGroupFilter(); + void addDeviceGroupFilter(const QString &device); + void removeDeviceGroupFilter(const QString &device); +signals: + //void requestHistoryEvents(const QStringList &listHistoryEventTableName,QList typeFilter, const QString &conditionFilter); + void requestHistoryEvents(const QStringList &listHistoryEventTableName, const QString &conditionFilter); + void sigPermInvalid(); + void sigHisEventRequesting(); + void sigHisEventSizeChanged(); + void sigHISRecordOutOfRangeTips(QStringList stDescList); + void sigOutOfRangeTips(); + + void requestHistory(ST_FILTER stFilter); + +public slots: + void updateEvents(QList eventList); + void updateShowEvents(); + +private: + + void setStFilter(ST_FILTER &stFilter); + +private: + QStringList header; + QList m_listShowEventInfo; + QList m_listAllEventInfo; + QList m_listPermLocationId; + QList m_listPermRegionId; + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + //Filter + bool m_isLevelFilterEnable; //是否按报警级别过滤 + QList m_levelFilter; //报警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isStatusFilterEnable; //是否按报警类型过滤 + QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) + QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyword; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + + bool m_isReturnFilterEnable; //是否根据复归状态过滤 + bool m_isReturn; + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 + QSet m_deviceGroupFilter; //<设备组过滤 +}; + +#endif // CEVENTHISTORYMODEL_H diff --git a/product/src/gui/plugin/EventWidget/CEventItemModel.cpp b/product/src/gui/plugin/EventWidget/CEventItemModel.cpp index 1da8ded2..3ac070fe 100644 --- a/product/src/gui/plugin/EventWidget/CEventItemModel.cpp +++ b/product/src/gui/plugin/EventWidget/CEventItemModel.cpp @@ -1,759 +1,759 @@ -#include "CEventItemModel.h" -#include "CEventMsgInfo.h" -#include -#include -#include -#include -#include "CEventDataCollect.h" -#include "service/alarm_server_api/AlarmCommonDef.h" -#include "CEventMsgManage.h" -#include "pub_logger_api/logger.h" - -///////////////////////////////////////////////////////////////////////////// - -typedef QPair > PAIRLISTALARMINFO; - -CEventItemModel::CEventItemModel(QObject *parent) - :QAbstractTableModel(parent), - m_sortKey(E_SORT_TIME), - m_order(Qt::AscendingOrder) -{ - header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型") << tr("事件状态") << tr("复归状态") << tr("事件内容"); - initialize(); - connect(CEventDataCollect::instance(), SIGNAL(sigMsgRefresh()), - this, SLOT(slotMsgRefresh()), Qt::QueuedConnection); - - connect(CEventDataCollect::instance(), SIGNAL(sigMsgArrived(QList)), - this, SLOT(slotMsgArrived(QList))); -} - -CEventItemModel::~CEventItemModel() -{ - m_listShowEventInfo.clear(); -} - -void CEventItemModel::initialize() -{ - beginResetModel(); - m_listShowEventInfo.clear(); - endResetModel(); - - initFilterAndReloadData(); -} - -void CEventItemModel::initFilter() -{ - m_isLevelFilterEnable = false; - m_levelFilter.clear(); - m_isLocationFilterEnable = false; - m_locationFilter.clear(); - m_isRegionFilterEnable = false; - m_regionFilter.clear(); - m_isStatusFilterEnable = false; - m_statusFilter.clear(); - m_statusFilter2.clear(); - m_isDeviceTypeFileter = false; - m_subSystem = QString(); - m_deviceType = QString(); - m_isKeywordEnable = false; - m_keyword = QString(); - m_timeFilterEnable = false; - m_isReturnFilterEnable = false; - m_isReturn = false; - addDeviceGroupFilter(); -} - -void CEventItemModel::initFilterAndReloadData() -{ - initFilter(); - slotMsgRefresh(); -} - -EventMsgPtr CEventItemModel::getAlarmInfo(const QModelIndex &index) const -{ - if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) - { - return NULL; - } - - return m_listShowEventInfo.at(index.row()); -} - -const QList CEventItemModel::getListShowAlarmInfo() const -{ - return m_listShowEventInfo; -} - -void CEventItemModel::insertAlarmMsg(EventMsgPtr info) -{ - int nInsertRowIndex = -1; - if (Qt::AscendingOrder == m_order) - { - for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) - { - EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); - if (!msg->lessThan(info, m_sortKey)) - { - nInsertRowIndex = nIndex; - break; - } - } - } - else - { - for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) - { - EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); - if (!msg->moreThan(info, m_sortKey)) - { - nInsertRowIndex = nIndex; - break; - } - } - } - if (-1 == nInsertRowIndex) - { - nInsertRowIndex = m_listShowEventInfo.count(); - } - - - beginInsertRows(QModelIndex(), nInsertRowIndex, nInsertRowIndex); - m_listShowEventInfo.insert(nInsertRowIndex, info); - endInsertRows(); - - return; -} - -QVariant CEventItemModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(header.at(section)); - } - return QVariant(); -} - -QVariant CEventItemModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == (int)E_SORT_CONTENT) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - } - else if(Qt::DisplayRole == role) - { - switch (index.column()) - { - case E_SORT_TIME : - { - return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp, Qt::LocalTime).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - case E_SORT_PRIORITY : - { - return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); - } - case E_SORT_LOCATION : - { - return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); - } - case E_SORT_REGION : - { - return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); - } - case E_SORT_TYPE : - { - return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); - } - case E_SORT_STATUS : - { - return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); - } - case E_SORT_STYLE : - { - if(AS_ALARM == m_listShowEventInfo.at(index.row())->alm_style) //未复归 - { - return tr("未复归"); - } - else if(AS_ALARM_RTN == m_listShowEventInfo.at(index.row())->alm_style ) //已复归 - { - return tr("已复归"); - }else{ - return QString("-"); - } - } - case E_SORT_CONTENT : - { - return m_listShowEventInfo.at(index.row())->content; - } - default: - return QVariant(); - } - } - return QVariant(); -} - -int CEventItemModel::columnCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - - return header.count(); -} - -int CEventItemModel::rowCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - return m_listShowEventInfo.count(); -} - -Qt::ItemFlags CEventItemModel::flags(const QModelIndex &index) const -{ - // return Qt::NoItemFlags; - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CEventItemModel::sortColumn(int column, Qt::SortOrder order) -{ - if(order == Qt::AscendingOrder) - { - m_order = Qt::DescendingOrder; - } - else - { - m_order = Qt::AscendingOrder; - } - - if(column ==E_SORT_PRIORITY) - { - if(order == Qt::AscendingOrder) - { - m_order = Qt::AscendingOrder; - } - else - { - m_order = Qt::DescendingOrder; - } - } - - - m_sortKey = (E_ALARM_SORTKEY)column; - - beginResetModel(); - sort(); - endResetModel(); -} - -//<归并排序 -void CEventItemModel::sort() -{ - QMap mapAlarmInfo; - //<分 - for(int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) - { - EventMsgPtr temp = m_listShowEventInfo.at(nIndex); - mapAlarmInfo[nIndex / 1000].second.append(temp); - } - - //<快速排序 - for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) - { - qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); - } - - //<治 - PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; - for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) - { - //<归并 - tempListAlarmInfo.first = 0; - mapAlarmInfo[nPairIndex].first = 0; - while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) - { - if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) - { - tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - } - tempListAlarmInfo.first += 1; - } - } - m_listShowEventInfo = tempListAlarmInfo.second; -} - - -void CEventItemModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CEventItemModel::partitionAscendingOrder(QList &list, int start, int last) -{ - EventMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftlessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CEventItemModel::partitionDescendingOrder(QList &list, int start, int last) -{ - EventMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -void CEventItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, - const bool &isKeywordFilterEnable, const QString &keyword, - const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime,const bool &isReturnFilterEnable,const bool &isReturn) -{ - m_isLevelFilterEnable = isLevelFilterEnable; - m_levelFilter = levelFilter; - m_isLocationFilterEnable = isStationFilterEnable; - m_locationFilter = stationFilter; - m_isRegionFilterEnable = isRegionFilterEnable; - m_regionFilter = regionFilter; - m_isStatusFilterEnable = isTypeFilterEnable; - m_statusFilter = typeFilter; - m_statusFilter2 = typeFilter; - if(typeFilter.contains(OTHERSTATUS)) - { - QMap alarmOtherMap = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); - QMap::iterator it = alarmOtherMap.begin(); - for(;it != alarmOtherMap.end(); ++it) - { - m_statusFilter.append(it.key()); - } - } - m_isDeviceTypeFileter = isDeviceTypeFilter; - m_subSystem = subSystem; - m_deviceType = deviceType; - m_isKeywordEnable = isKeywordFilterEnable; - m_keyword = keyword; - m_timeFilterEnable = timeFilterEnable; - m_startTime = startTime; - m_endTime = endTime; - m_isReturnFilterEnable = isReturnFilterEnable; - m_isReturn = isReturn; - slotMsgRefresh(); -} - -void CEventItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, - bool &returnFilterEnable,bool &isReturn) -{ - isLevelFilterEnable = m_isLevelFilterEnable; - levelFilter = m_levelFilter; - isLocationFilterEnable = m_isLocationFilterEnable; - locationFilter = m_locationFilter; - isRegionFilterEnable = m_isRegionFilterEnable; - regionFilter = m_regionFilter; - isTypeFilterEnable = m_isStatusFilterEnable; - alarmTypeFilter = m_statusFilter2; - subSystem = m_subSystem; - deviceTypeFilter = m_isDeviceTypeFileter; - deviceType = m_deviceType; - keywordFilterEnable = m_isKeywordEnable; - keyword = m_keyword; - timeFilterEnable = m_timeFilterEnable; - startTime = m_startTime; - endTime = m_endTime; - returnFilterEnable = m_isReturnFilterEnable; - isReturn = m_isReturn; -} - -bool CEventItemModel::conditionFilter(EventMsgPtr info) -{ - //< 等级 - if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) - { - return false; - } - - //< 车站 - if(m_isLocationFilterEnable) - { - if(!m_locationFilter.contains(info->location_id)) - { - return false; - } - } - else - { - if(!CEventDataCollect::instance()->locationList().contains(info->location_id)) - { - return false; - } - } - - //< 责任区 - if(m_isRegionFilterEnable) - { - if(!m_regionFilter.contains(info->region_id)) - { - return false; - } - } - else - { - if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 - { - return false; - } - } - - //< 状态 - if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) - { - return false; - } - - //< 设备类型 - if(m_isDeviceTypeFileter) - { - if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) - { - return false; - } - } - - //< 设备组 - if(!info->dev_group_tag.isEmpty() && !m_deviceGroupFilter.contains(info->dev_group_tag)) - { - return false; - } - - //< 关键字 - if(m_isKeywordEnable) - { - if(!info->content.contains(m_keyword)) - { - return false; - } - } - - //< 时间 - if(m_timeFilterEnable) - { - if((quint64)m_startTime.toMSecsSinceEpoch() >= info->time_stamp) - { - return false; - } - if((quint64)m_endTime.toMSecsSinceEpoch() <= info->time_stamp) - { - return false; - } - } - if(m_isReturnFilterEnable) - { - if(m_isReturn) - { - if(info->alm_style != AS_ALARM_RTN) - { - return false; - } - } - else - { - if(info->alm_style != AS_ALARM ) - { - return false; - } - } - } - return true; -} - -void CEventItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - m_isLevelFilterEnable = isCheck; - m_levelFilter = priorityFilter; - - slotMsgRefresh(); -} - -void CEventItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) -{ - m_isLocationFilterEnable = isCheck; - m_locationFilter = locationFilter; - - slotMsgRefresh(); -} - -void CEventItemModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other) -{ - m_isStatusFilterEnable = isCheck; - m_statusFilter = eventTypeFilter; - m_statusFilter2 = eventTypeFilter; - if(other == true) - { - QMap otherEventStatus = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); - QMap::iterator it = otherEventStatus.begin(); - for(;it != otherEventStatus.end(); ++it) - { - m_statusFilter.append(it.key()); - } - } - slotMsgRefresh(); -} - -void CEventItemModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) -{ - m_timeFilterEnable = isCheck; - if(isCheck) - { - QTime time_1(0,0,0); - QTime time_2(23,59,59); - m_startTime.setDate(startTime); - m_startTime.setTime(time_1); - m_endTime.setDate(endTime); - m_endTime.setTime(time_2); - } - slotMsgRefresh(); -} - -void CEventItemModel::setEventTimeFilter(bool &isCheck) -{ - m_timeFilterEnable = isCheck; - slotMsgRefresh(); -} - -void CEventItemModel::getPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - isCheck = m_isLevelFilterEnable; - priorityFilter = m_levelFilter; -} - -void CEventItemModel::getLocationFilter(bool &isCheck, QList &locationFilter) -{ - isCheck = m_isLocationFilterEnable; - locationFilter = m_locationFilter; -} - -void CEventItemModel::getEventStatusFilter(bool &isCheck, QList &eventStatusFilter) -{ - isCheck = m_isStatusFilterEnable; - eventStatusFilter = m_statusFilter2; -} - -void CEventItemModel::getEventTimeFilter(bool &isCheck, QDateTime &startTime, QDateTime &endTime) -{ - isCheck = m_timeFilterEnable; - startTime = m_startTime; - endTime = m_endTime; -} - -QList CEventItemModel::getListEventInfo() -{ - return m_listShowEventInfo; -} - -void CEventItemModel::addDeviceGroupFilter() -{ - for(QString group : CEventDataCollect::instance()->getDevGroupTagList()) - { - m_deviceGroupFilter.insert(group); - } -} - -void CEventItemModel::removeDeviceGroupFilter() -{ - m_deviceGroupFilter.clear(); -} - -void CEventItemModel::addDeviceGroupFilter(const QString &device) -{ - QString deviceG = device; - QStringList devGList = deviceG.split(","); - foreach (QString devG, devGList) { - m_deviceGroupFilter.insert(devG); - } - slotMsgRefresh(); -} - -void CEventItemModel::removeDeviceGroupFilter(const QString &device) -{ - m_deviceGroupFilter.remove(device); - slotMsgRefresh(); -} - -void CEventItemModel::slotMsgRefresh() -{ - //需要先过滤 - m_listAllEventInfo = CEventMsgManage::instance()->getListEventInfo(); - //根据复归过滤 - QList listFilterInfo; - firstFilterByReturn(listFilterInfo); - m_listAllEventInfo.clear(); - beginResetModel(); - m_listShowEventInfo.clear(); - QList::iterator it = listFilterInfo.begin(); - while (it != listFilterInfo.end()) { - if(conditionFilter(*it)) - { - m_listShowEventInfo.append(*it); - } - it++; - } - sort(); - endResetModel(); -} - -void CEventItemModel::slotMsgArrived(QList listEvents) -{ - if(m_isReturnFilterEnable) - { - slotMsgRefresh(); - }else - { - QList::iterator itPos = listEvents.begin(); - while(itPos != listEvents.end()) - { - if(conditionFilter(*itPos)) - { - insertAlarmMsg(*itPos); - } - itPos++; - } - } - - for(int nIndex = m_listShowEventInfo.size() - 1; nIndex >= 0; --nIndex) - { - if(m_listShowEventInfo.at(nIndex)->deleted) - { - beginRemoveRows(QModelIndex(), nIndex, nIndex); - m_listShowEventInfo.removeAt(nIndex); - endRemoveRows(); - } - } -} - -void CEventItemModel::firstFilterByReturn(QList &filterList) -{ - if(!m_isReturnFilterEnable) - { - filterList = m_listAllEventInfo; - return; - } - - QHash filerHash; - - QList::iterator it = m_listAllEventInfo.begin(); - while (it != m_listAllEventInfo.end()) { - if((*it)->key_id_tag.isEmpty()) - { - it++; - continue; - } - //< 动作和复归 - if((*it)->alm_style == AS_ALARM || (*it)->alm_style == AS_ALARM_RTN) - { - EventMsgPtr ptr = filerHash.value((*it)->key_id_tag,NULL); - if(ptr != NULL) - { - if((*it)->time_stamp >ptr->time_stamp) - { - filerHash[(*it)->key_id_tag] = (*it); - } - }else - { - filerHash[(*it)->key_id_tag] = (*it); - } - } - it++; - } - QHash::iterator pos = filerHash.begin(); - while (pos != filerHash.end()) { - filterList.append(pos.value()); - pos++; - } -} +#include "CEventItemModel.h" +#include "CEventMsgInfo.h" +#include +#include +#include +#include +#include "CEventDataCollect.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include "CEventMsgManage.h" +#include "pub_logger_api/logger.h" + +///////////////////////////////////////////////////////////////////////////// + +typedef QPair > PAIRLISTALARMINFO; + +CEventItemModel::CEventItemModel(QObject *parent) + :QAbstractTableModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::AscendingOrder) +{ + header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型") << tr("事件状态") << tr("复归状态") << tr("事件内容"); + initialize(); + connect(CEventDataCollect::instance(), SIGNAL(sigMsgRefresh()), + this, SLOT(slotMsgRefresh()), Qt::QueuedConnection); + + connect(CEventDataCollect::instance(), SIGNAL(sigMsgArrived(QList)), + this, SLOT(slotMsgArrived(QList))); +} + +CEventItemModel::~CEventItemModel() +{ + m_listShowEventInfo.clear(); +} + +void CEventItemModel::initialize() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + endResetModel(); + + initFilterAndReloadData(); +} + +void CEventItemModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_levelFilter.clear(); + m_isLocationFilterEnable = false; + m_locationFilter.clear(); + m_isRegionFilterEnable = false; + m_regionFilter.clear(); + m_isStatusFilterEnable = false; + m_statusFilter.clear(); + m_statusFilter2.clear(); + m_isDeviceTypeFileter = false; + m_subSystem = QString(); + m_deviceType = QString(); + m_isKeywordEnable = false; + m_keyword = QString(); + m_timeFilterEnable = false; + m_isReturnFilterEnable = false; + m_isReturn = false; + addDeviceGroupFilter(); +} + +void CEventItemModel::initFilterAndReloadData() +{ + initFilter(); + slotMsgRefresh(); +} + +EventMsgPtr CEventItemModel::getAlarmInfo(const QModelIndex &index) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return NULL; + } + + return m_listShowEventInfo.at(index.row()); +} + +const QList CEventItemModel::getListShowAlarmInfo() const +{ + return m_listShowEventInfo; +} + +void CEventItemModel::insertAlarmMsg(EventMsgPtr info) +{ + int nInsertRowIndex = -1; + if (Qt::AscendingOrder == m_order) + { + for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); + if (!msg->lessThan(info, m_sortKey)) + { + nInsertRowIndex = nIndex; + break; + } + } + } + else + { + for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); + if (!msg->moreThan(info, m_sortKey)) + { + nInsertRowIndex = nIndex; + break; + } + } + } + if (-1 == nInsertRowIndex) + { + nInsertRowIndex = m_listShowEventInfo.count(); + } + + + beginInsertRows(QModelIndex(), nInsertRowIndex, nInsertRowIndex); + m_listShowEventInfo.insert(nInsertRowIndex, info); + endInsertRows(); + + return; +} + +QVariant CEventItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(header.at(section)); + } + return QVariant(); +} + +QVariant CEventItemModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == (int)E_SORT_CONTENT) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + } + else if(Qt::DisplayRole == role) + { + switch (index.column()) + { + case E_SORT_TIME : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp, Qt::LocalTime).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case E_SORT_PRIORITY : + { + return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); + } + case E_SORT_LOCATION : + { + return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); + } + case E_SORT_REGION : + { + return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); + } + case E_SORT_TYPE : + { + return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); + } + case E_SORT_STATUS : + { + return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); + } + case E_SORT_STYLE : + { + if(AS_ALARM == m_listShowEventInfo.at(index.row())->alm_style) //未复归 + { + return tr("未复归"); + } + else if(AS_ALARM_RTN == m_listShowEventInfo.at(index.row())->alm_style ) //已复归 + { + return tr("已复归"); + }else{ + return QString("-"); + } + } + case E_SORT_CONTENT : + { + return m_listShowEventInfo.at(index.row())->content; + } + default: + return QVariant(); + } + } + return QVariant(); +} + +int CEventItemModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return header.count(); +} + +int CEventItemModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + return m_listShowEventInfo.count(); +} + +Qt::ItemFlags CEventItemModel::flags(const QModelIndex &index) const +{ + // return Qt::NoItemFlags; + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CEventItemModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + + if(column ==E_SORT_PRIORITY) + { + if(order == Qt::AscendingOrder) + { + m_order = Qt::AscendingOrder; + } + else + { + m_order = Qt::DescendingOrder; + } + } + + + m_sortKey = (E_ALARM_SORTKEY)column; + + beginResetModel(); + sort(); + endResetModel(); +} + +//<归并排序 +void CEventItemModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr temp = m_listShowEventInfo.at(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(temp); + } + + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + + //<治 + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + m_listShowEventInfo = tempListAlarmInfo.second; +} + + +void CEventItemModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CEventItemModel::partitionAscendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CEventItemModel::partitionDescendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CEventItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime,const bool &isReturnFilterEnable,const bool &isReturn) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isStatusFilterEnable = isTypeFilterEnable; + m_statusFilter = typeFilter; + m_statusFilter2 = typeFilter; + if(typeFilter.contains(OTHERSTATUS)) + { + QMap alarmOtherMap = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); + QMap::iterator it = alarmOtherMap.begin(); + for(;it != alarmOtherMap.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyword = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + m_isReturnFilterEnable = isReturnFilterEnable; + m_isReturn = isReturn; + slotMsgRefresh(); +} + +void CEventItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &returnFilterEnable,bool &isReturn) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isTypeFilterEnable = m_isStatusFilterEnable; + alarmTypeFilter = m_statusFilter2; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyword; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; + returnFilterEnable = m_isReturnFilterEnable; + isReturn = m_isReturn; +} + +bool CEventItemModel::conditionFilter(EventMsgPtr info) +{ + //< 等级 + if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) + { + return false; + } + + //< 车站 + if(m_isLocationFilterEnable) + { + if(!m_locationFilter.contains(info->location_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->locationList().contains(info->location_id)) + { + return false; + } + } + + //< 责任区 + if(m_isRegionFilterEnable) + { + if(!m_regionFilter.contains(info->region_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 + { + return false; + } + } + + //< 状态 + if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { + if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) + { + return false; + } + } + + //< 设备组 + if(!info->dev_group_tag.isEmpty() && !m_deviceGroupFilter.contains(info->dev_group_tag)) + { + return false; + } + + //< 关键字 + if(m_isKeywordEnable) + { + if(!info->content.contains(m_keyword)) + { + return false; + } + } + + //< 时间 + if(m_timeFilterEnable) + { + if((quint64)m_startTime.toMSecsSinceEpoch() >= info->time_stamp) + { + return false; + } + if((quint64)m_endTime.toMSecsSinceEpoch() <= info->time_stamp) + { + return false; + } + } + if(m_isReturnFilterEnable) + { + if(m_isReturn) + { + if(info->alm_style != AS_ALARM_RTN) + { + return false; + } + } + else + { + if(info->alm_style != AS_ALARM ) + { + return false; + } + } + } + return true; +} + +void CEventItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + + slotMsgRefresh(); +} + +void CEventItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + + slotMsgRefresh(); +} + +void CEventItemModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other) +{ + m_isStatusFilterEnable = isCheck; + m_statusFilter = eventTypeFilter; + m_statusFilter2 = eventTypeFilter; + if(other == true) + { + QMap otherEventStatus = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); + QMap::iterator it = otherEventStatus.begin(); + for(;it != otherEventStatus.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + slotMsgRefresh(); +} + +void CEventItemModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + slotMsgRefresh(); +} + +void CEventItemModel::setEventTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + slotMsgRefresh(); +} + +void CEventItemModel::getPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + isCheck = m_isLevelFilterEnable; + priorityFilter = m_levelFilter; +} + +void CEventItemModel::getLocationFilter(bool &isCheck, QList &locationFilter) +{ + isCheck = m_isLocationFilterEnable; + locationFilter = m_locationFilter; +} + +void CEventItemModel::getEventStatusFilter(bool &isCheck, QList &eventStatusFilter) +{ + isCheck = m_isStatusFilterEnable; + eventStatusFilter = m_statusFilter2; +} + +void CEventItemModel::getEventTimeFilter(bool &isCheck, QDateTime &startTime, QDateTime &endTime) +{ + isCheck = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; +} + +QList CEventItemModel::getListEventInfo() +{ + return m_listShowEventInfo; +} + +void CEventItemModel::addDeviceGroupFilter() +{ + for(QString group : CEventDataCollect::instance()->getDevGroupTagList()) + { + m_deviceGroupFilter.insert(group); + } +} + +void CEventItemModel::removeDeviceGroupFilter() +{ + m_deviceGroupFilter.clear(); +} + +void CEventItemModel::addDeviceGroupFilter(const QString &device) +{ + QString deviceG = device; + QStringList devGList = deviceG.split(","); + foreach (QString devG, devGList) { + m_deviceGroupFilter.insert(devG); + } + slotMsgRefresh(); +} + +void CEventItemModel::removeDeviceGroupFilter(const QString &device) +{ + m_deviceGroupFilter.remove(device); + slotMsgRefresh(); +} + +void CEventItemModel::slotMsgRefresh() +{ + //需要先过滤 + m_listAllEventInfo = CEventMsgManage::instance()->getListEventInfo(); + //根据复归过滤 + QList listFilterInfo; + firstFilterByReturn(listFilterInfo); + m_listAllEventInfo.clear(); + beginResetModel(); + m_listShowEventInfo.clear(); + QList::iterator it = listFilterInfo.begin(); + while (it != listFilterInfo.end()) { + if(conditionFilter(*it)) + { + m_listShowEventInfo.append(*it); + } + it++; + } + sort(); + endResetModel(); +} + +void CEventItemModel::slotMsgArrived(QList listEvents) +{ + if(m_isReturnFilterEnable) + { + slotMsgRefresh(); + }else + { + QList::iterator itPos = listEvents.begin(); + while(itPos != listEvents.end()) + { + if(conditionFilter(*itPos)) + { + insertAlarmMsg(*itPos); + } + itPos++; + } + } + + for(int nIndex = m_listShowEventInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowEventInfo.at(nIndex)->deleted) + { + beginRemoveRows(QModelIndex(), nIndex, nIndex); + m_listShowEventInfo.removeAt(nIndex); + endRemoveRows(); + } + } +} + +void CEventItemModel::firstFilterByReturn(QList &filterList) +{ + if(!m_isReturnFilterEnable) + { + filterList = m_listAllEventInfo; + return; + } + + QHash filerHash; + + QList::iterator it = m_listAllEventInfo.begin(); + while (it != m_listAllEventInfo.end()) { + if((*it)->key_id_tag.isEmpty()) + { + it++; + continue; + } + //< 动作和复归 + if((*it)->alm_style == AS_ALARM || (*it)->alm_style == AS_ALARM_RTN) + { + EventMsgPtr ptr = filerHash.value((*it)->key_id_tag,NULL); + if(ptr != NULL) + { + if((*it)->time_stamp >ptr->time_stamp) + { + filerHash[(*it)->key_id_tag] = (*it); + } + }else + { + filerHash[(*it)->key_id_tag] = (*it); + } + } + it++; + } + QHash::iterator pos = filerHash.begin(); + while (pos != filerHash.end()) { + filterList.append(pos.value()); + pos++; + } +} diff --git a/product/src/gui/plugin/EventWidget/CEventItemModel.h b/product/src/gui/plugin/EventWidget/CEventItemModel.h index dd89ddb5..0c7d378a 100644 --- a/product/src/gui/plugin/EventWidget/CEventItemModel.h +++ b/product/src/gui/plugin/EventWidget/CEventItemModel.h @@ -1,150 +1,150 @@ -#ifndef CEVENTITEMMODEL_H -#define CEVENTITEMMODEL_H - -#include -#include -#include -#include -#include "CEventMsgInfo.h" -#include "CEventDataCollect.h" - -#define Row_Full (15000) - -class CEventMsgInfo; -class QTimer; - -class CEventItemModel : public QAbstractTableModel -{ - Q_OBJECT -public: - CEventItemModel(QObject *parent = Q_NULLPTR); - ~CEventItemModel(); - - void initialize(); - void initFilter(); - - void initFilterAndReloadData(); - - EventMsgPtr getAlarmInfo(const QModelIndex &index) const; - - const QList getListShowAlarmInfo() const; - - /** - * @brief insertAlarmMsg 数采通知模型报警到达 - * @param info - */ - void insertAlarmMsg(EventMsgPtr info); - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual int columnCount(const QModelIndex &index = QModelIndex()) const; - virtual int rowCount(const QModelIndex &index = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - void sort(); - void qucikSort(QList &listAlarmInfo, int left, int right); - int partitionAscendingOrder(QList &list, int start, int last); - int partitionDescendingOrder(QList &list, int start, int last); - - /** - * 设置模型数据过滤条件,过滤显示数据 - */ - void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), - const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), - const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), - const QDateTime &endTime = QDateTime(),const bool &isReturnFilterEnable = false,const bool &isReturn = false); - - /** - * 获取模型数据过滤条件,用于初始化过滤对话框 - */ - void getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, - bool &returnFilterEnable,bool &isReturn); - - bool conditionFilter(EventMsgPtr info); - - void setPriorityFilter(bool &isCheck, QList &priorityFilter); - void setLocationFilter(bool &isCheck, QList &locationFilter); - void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other); - void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); - void setEventTimeFilter(bool &isCheck); - - void getPriorityFilter(bool &isCheck,QList &priorityFilter); - - void getLocationFilter(bool &isCheck,QList &locationFilter); - - void getEventStatusFilter(bool &isCheck, QList &eventStatusFilter); - - void getEventTimeFilter(bool &isCheck,QDateTime &startTime, QDateTime &endTime); - - QList getListEventInfo(); - - void addDeviceGroupFilter(); - void removeDeviceGroupFilter(); - void addDeviceGroupFilter(const QString &device); - void removeDeviceGroupFilter(const QString &device); -signals: - void sigRowChanged(); - -public slots: - void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); - -private slots: - /** - * @brief slotMsgRefresh 更新model,重新拉取数据 - */ - void slotMsgRefresh(); - - /** - * @brief slotMsgArrived 报警消息到达 - * @param info - */ - void slotMsgArrived(QList listEvents); -private: - void firstFilterByReturn(QList &filterSet); - -private: - QStringList header; - QList m_listShowEventInfo; - QList m_listAllEventInfo; - - E_ALARM_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - - //Filter - bool m_isLevelFilterEnable; //是否按报警级别过滤 - QList m_levelFilter; //报警级别过滤 - bool m_isLocationFilterEnable; //是否按车站过滤 - QList m_locationFilter; //车站过滤 - bool m_isRegionFilterEnable; //是否按责任区过滤 - QList m_regionFilter; //责任区过滤 - bool m_isStatusFilterEnable; //是否按事件状态过滤 - QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) - QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) - bool m_isDeviceTypeFileter; //设备类型过滤 - QString m_subSystem; //子系统 - QString m_deviceType; //设备类型 - bool m_isKeywordEnable; //关键字过滤 - QString m_keyword; //关键字 - bool m_timeFilterEnable; //是否根据时间过滤 - QDateTime m_startTime; //起始时间 - QDateTime m_endTime; //终止时间 - - bool m_isReturnFilterEnable; //是否根据复归状态过滤 - bool m_isReturn; - - QMap m_areaInfoMap; //区域信息 - - QMap > m_areaLocMap; //区域映射 - QSet m_deviceGroupFilter; //<设备组过滤 -}; - -#endif // CEVENTITEMMODEL_H +#ifndef CEVENTITEMMODEL_H +#define CEVENTITEMMODEL_H + +#include +#include +#include +#include +#include "CEventMsgInfo.h" +#include "CEventDataCollect.h" + +#define Row_Full (15000) + +class CEventMsgInfo; +class QTimer; + +class CEventItemModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CEventItemModel(QObject *parent = Q_NULLPTR); + ~CEventItemModel(); + + void initialize(); + void initFilter(); + + void initFilterAndReloadData(); + + EventMsgPtr getAlarmInfo(const QModelIndex &index) const; + + const QList getListShowAlarmInfo() const; + + /** + * @brief insertAlarmMsg 数采通知模型报警到达 + * @param info + */ + void insertAlarmMsg(EventMsgPtr info); + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + void sort(); + void qucikSort(QList &listAlarmInfo, int left, int right); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(),const bool &isReturnFilterEnable = false,const bool &isReturn = false); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &returnFilterEnable,bool &isReturn); + + bool conditionFilter(EventMsgPtr info); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other); + void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); + void setEventTimeFilter(bool &isCheck); + + void getPriorityFilter(bool &isCheck,QList &priorityFilter); + + void getLocationFilter(bool &isCheck,QList &locationFilter); + + void getEventStatusFilter(bool &isCheck, QList &eventStatusFilter); + + void getEventTimeFilter(bool &isCheck,QDateTime &startTime, QDateTime &endTime); + + QList getListEventInfo(); + + void addDeviceGroupFilter(); + void removeDeviceGroupFilter(); + void addDeviceGroupFilter(const QString &device); + void removeDeviceGroupFilter(const QString &device); +signals: + void sigRowChanged(); + +public slots: + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + +private slots: + /** + * @brief slotMsgRefresh 更新model,重新拉取数据 + */ + void slotMsgRefresh(); + + /** + * @brief slotMsgArrived 报警消息到达 + * @param info + */ + void slotMsgArrived(QList listEvents); +private: + void firstFilterByReturn(QList &filterSet); + +private: + QStringList header; + QList m_listShowEventInfo; + QList m_listAllEventInfo; + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + //Filter + bool m_isLevelFilterEnable; //是否按报警级别过滤 + QList m_levelFilter; //报警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isStatusFilterEnable; //是否按事件状态过滤 + QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) + QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyword; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + + bool m_isReturnFilterEnable; //是否根据复归状态过滤 + bool m_isReturn; + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 + QSet m_deviceGroupFilter; //<设备组过滤 +}; + +#endif // CEVENTITEMMODEL_H diff --git a/product/src/gui/plugin/EventWidget/CEventMsgInfo.cpp b/product/src/gui/plugin/EventWidget/CEventMsgInfo.cpp index ea0d9787..7eb106ec 100644 --- a/product/src/gui/plugin/EventWidget/CEventMsgInfo.cpp +++ b/product/src/gui/plugin/EventWidget/CEventMsgInfo.cpp @@ -1,457 +1,457 @@ -#include "CEventMsgInfo.h" -#include -#include "CEventDataCollect.h" -#include - -CEventMsgInfo::CEventMsgInfo(): alm_status(0), cfm_user(0), cfm_time(0) -{ - alm_type = -1; - alm_style = AS_EVENT_ONLY; - time_stamp = 1000; - domain_id = -1; - location_id = -1; - app_id = -1; - content = QString(""); - priority = -1; - dev_type = -1; - region_id = -1; - sub_system = -1; - key_id_tag = QString(); - uuid_base64 = QString(); - priorityOrder = -1; - deleted = false; - filterDelete = false; - wave_file = QString(); - dev_group_tag = QString(); - dev_group_tag = QString(); -} - -CEventMsgInfo::CEventMsgInfo(const CEventMsgInfo &other): alm_status(0), cfm_user(0), cfm_time(0), priorityOrder(0) -{ - alm_type = other.alm_type; - alm_style = other.alm_style; - time_stamp = other.time_stamp; - domain_id = other.domain_id; - location_id = other.location_id; - app_id = other.app_id; - content = other.content; - priority = other.priority; - dev_type = other.dev_type; - key_id_tag = other.key_id_tag; - uuid_base64 = other.uuid_base64; - region_id = other.region_id; - deleted = other.deleted; - filterDelete = other.filterDelete; - wave_file = other.wave_file; - dev_group_tag = other.dev_group_tag; - dev_group_tag = other.dev_group_tag; -} - -void CEventMsgInfo::initialize(const kbd_idlfile::SEvtInfoToEvtClt &eventInfo) -{ - alm_type = eventInfo.alm_type(); - E_ALARM_LOGICSTATE logic = (E_ALARM_LOGICSTATE)eventInfo.logic_state(); - if(logic == E_ALS_ALARM || logic == E_ALS_ALARM_CFM || - logic == E_ALS_ALARM_DEL || logic == E_ALS_ALARM_CFM_DEL) - { - alm_style = AS_ALARM; - }else if(logic == E_ALS_RETURN || logic == E_ALS_RETURN_CFM || - logic == E_ALS_RETURN_DEL || logic == E_ALS_RETURN_CFM_DEL) - { - alm_style = AS_ALARM_RTN; - }else{ - alm_style = AS_EVENT_ONLY; - } - time_stamp = eventInfo.time_stamp(); - alm_status = eventInfo.alm_status(); - domain_id = eventInfo.domain_id(); - location_id = eventInfo.location_id(); - app_id = eventInfo.app_id(); - content = QString::fromStdString(eventInfo.content()); - priority = eventInfo.priority(); - dev_type = eventInfo.dev_type(); - key_id_tag = QString::fromStdString(eventInfo.key_id_tag()); - uuid_base64 = QString::fromStdString(eventInfo.uuid_base64()); - if(eventInfo.has_region_id() && eventInfo.region_id() > 0) - { - region_id = eventInfo.region_id(); - } - else - { - region_id = -1; - } - wave_file = QString::fromStdString(eventInfo.wave_file()); - if(eventInfo.has_dev_group_tag()) - { - dev_group_tag = QString::fromStdString(eventInfo.dev_group_tag()); - } -} - -bool CEventMsgInfo::lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) - { - case E_SORT_PRIORITY: - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - else if(priorityOrder > info->priorityOrder) - { - return false; - } - else if(priorityOrder == info->priorityOrder) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TIME: - { - if(time_stamp < info->time_stamp) - { - return true; - } - if(time_stamp > info->time_stamp) - { - return false; - } - else if(time_stamp == info->time_stamp) - { - if(priorityOrder <= info->priorityOrder) - { - return true; - } - return false; - } - break; - } - case E_SORT_LOCATION: - { - if(location_id < info->location_id) - { - return true; - } - else if(location_id > info->location_id) - { - return false; - } - else if(location_id == info->location_id) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_REGION: - { - if(region_id < info->region_id) - { - return true; - } - else if(region_id > info->region_id) - { - return false; - } - else if(region_id == info->region_id) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TYPE: - { - if(alm_type < info->alm_type) - { - return true; - } - else if(alm_type > info->alm_type) - { - return false; - } - else if(alm_type == info->alm_type) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_STATUS: - { - if(alm_status < info->alm_status) - { - return true; - } - else if(alm_status > info->alm_status) - { - return false; - } - else if(alm_status == info->alm_status) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_STYLE: - { - if(alm_style alm_style) - { - return true; - } - else if(alm_style >info->alm_style) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_CONTENT: - { - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else if(content == info->content) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - default: - break; - } - return false; -} - -bool CEventMsgInfo::moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) - { - case E_SORT_PRIORITY: - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - else if(priorityOrder < info->priorityOrder) - { - return false; - } - else if(priorityOrder == info->priorityOrder) - { - if(time_stamp >= info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_TIME: - { - if(time_stamp > info->time_stamp) - { - return true; - } - if(time_stamp < info->time_stamp) - { - return false; - } - else if(time_stamp == info->time_stamp) - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - return false; - } - break; - } - case E_SORT_LOCATION: - { - if(location_id > info->location_id) - { - return true; - } - else if(location_id < info->location_id) - { - return false; - } - else if(location_id == info->location_id) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_REGION: - { - if(region_id > info->region_id) - { - return true; - } - else if(region_id < info->region_id) - { - return false; - } - else if(region_id == info->region_id) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TYPE: - { - if(alm_type > info->alm_type) - { - return true; - } - else if(alm_type < info->alm_type) - { - return false; - } - else if(alm_type == info->alm_type) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_STATUS: - { - if(alm_status > info->alm_status) - { - return true; - } - else if(alm_status < info->alm_status) - { - return false; - } - else if(alm_status == info->alm_status) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_STYLE: - { - if(alm_style alm_style) - { - return false; - } - else if(alm_style >info->alm_style) - { - return true; - } - else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_CONTENT: - { - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content > info->content) - { - return true; - } - else if(content < info->content) - { - return false; - } - else if(content == info->content) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - default: - break; - } - return false; -} - -bool CEventMsgInfo::operator==(const EventMsgPtr &target) -{ - return uuid_base64 == target->uuid_base64; -} +#include "CEventMsgInfo.h" +#include +#include "CEventDataCollect.h" +#include + +CEventMsgInfo::CEventMsgInfo(): alm_status(0), cfm_user(0), cfm_time(0) +{ + alm_type = -1; + alm_style = AS_EVENT_ONLY; + time_stamp = 1000; + domain_id = -1; + location_id = -1; + app_id = -1; + content = QString(""); + priority = -1; + dev_type = -1; + region_id = -1; + sub_system = -1; + key_id_tag = QString(); + uuid_base64 = QString(); + priorityOrder = -1; + deleted = false; + filterDelete = false; + wave_file = QString(); + dev_group_tag = QString(); + dev_group_tag = QString(); +} + +CEventMsgInfo::CEventMsgInfo(const CEventMsgInfo &other): alm_status(0), cfm_user(0), cfm_time(0), priorityOrder(0) +{ + alm_type = other.alm_type; + alm_style = other.alm_style; + time_stamp = other.time_stamp; + domain_id = other.domain_id; + location_id = other.location_id; + app_id = other.app_id; + content = other.content; + priority = other.priority; + dev_type = other.dev_type; + key_id_tag = other.key_id_tag; + uuid_base64 = other.uuid_base64; + region_id = other.region_id; + deleted = other.deleted; + filterDelete = other.filterDelete; + wave_file = other.wave_file; + dev_group_tag = other.dev_group_tag; + dev_group_tag = other.dev_group_tag; +} + +void CEventMsgInfo::initialize(const kbd_idlfile::SEvtInfoToEvtClt &eventInfo) +{ + alm_type = eventInfo.alm_type(); + E_ALARM_LOGICSTATE logic = (E_ALARM_LOGICSTATE)eventInfo.logic_state(); + if(logic == E_ALS_ALARM || logic == E_ALS_ALARM_CFM || + logic == E_ALS_ALARM_DEL || logic == E_ALS_ALARM_CFM_DEL) + { + alm_style = AS_ALARM; + }else if(logic == E_ALS_RETURN || logic == E_ALS_RETURN_CFM || + logic == E_ALS_RETURN_DEL || logic == E_ALS_RETURN_CFM_DEL) + { + alm_style = AS_ALARM_RTN; + }else{ + alm_style = AS_EVENT_ONLY; + } + time_stamp = eventInfo.time_stamp(); + alm_status = eventInfo.alm_status(); + domain_id = eventInfo.domain_id(); + location_id = eventInfo.location_id(); + app_id = eventInfo.app_id(); + content = QString::fromStdString(eventInfo.content()); + priority = eventInfo.priority(); + dev_type = eventInfo.dev_type(); + key_id_tag = QString::fromStdString(eventInfo.key_id_tag()); + uuid_base64 = QString::fromStdString(eventInfo.uuid_base64()); + if(eventInfo.has_region_id() && eventInfo.region_id() > 0) + { + region_id = eventInfo.region_id(); + } + else + { + region_id = -1; + } + wave_file = QString::fromStdString(eventInfo.wave_file()); + if(eventInfo.has_dev_group_tag()) + { + dev_group_tag = QString::fromStdString(eventInfo.dev_group_tag()); + } +} + +bool CEventMsgInfo::lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + else if(priorityOrder > info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp < info->time_stamp) + { + return true; + } + if(time_stamp > info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder <= info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id < info->location_id) + { + return true; + } + else if(location_id > info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id < info->region_id) + { + return true; + } + else if(region_id > info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type < info->alm_type) + { + return true; + } + else if(alm_type > info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STATUS: + { + if(alm_status < info->alm_status) + { + return true; + } + else if(alm_status > info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STYLE: + { + if(alm_style alm_style) + { + return true; + } + else if(alm_style >info->alm_style) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} + +bool CEventMsgInfo::moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + else if(priorityOrder < info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp >= info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp > info->time_stamp) + { + return true; + } + if(time_stamp < info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id > info->location_id) + { + return true; + } + else if(location_id < info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id > info->region_id) + { + return true; + } + else if(region_id < info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type > info->alm_type) + { + return true; + } + else if(alm_type < info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STATUS: + { + if(alm_status > info->alm_status) + { + return true; + } + else if(alm_status < info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STYLE: + { + if(alm_style alm_style) + { + return false; + } + else if(alm_style >info->alm_style) + { + return true; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} + +bool CEventMsgInfo::operator==(const EventMsgPtr &target) +{ + return uuid_base64 == target->uuid_base64; +} diff --git a/product/src/gui/plugin/EventWidget/CEventMsgInfo.h b/product/src/gui/plugin/EventWidget/CEventMsgInfo.h index fb8b5c3f..0732ba52 100644 --- a/product/src/gui/plugin/EventWidget/CEventMsgInfo.h +++ b/product/src/gui/plugin/EventWidget/CEventMsgInfo.h @@ -1,170 +1,170 @@ -#ifndef ALARMMSGINFO_H -#define ALARMMSGINFO_H - -#include -#include -#include -#include "alarm_server_api/CAlmApiForEvtClt.h" -#include "common/DataType.h" -#include - -#define LIMIT_HIS_RECORD 10000 -#define REAL_BUTTON_COLUMN 7 //按钮所在列 -#define HIS_BUTTON_COLUMN 9 //按钮所在列 -//排序 -enum E_ALARM_VIEW -{ - E_ALARM_REAL_EVENT = 0, - E_ALARM_HIS_EVENT =1 -}; -enum E_ALARM_SORTKEY -{ - E_SORT_TIME = 0, //时间戳 - E_SORT_PRIORITY, //优先级 - E_SORT_LOCATION, //车站 - E_SORT_REGION, //责任区 - E_SORT_TYPE, //事件类型 - E_SORT_STATUS, //事件状态 - E_SORT_STYLE, //复归状态 - E_SORT_CONTENT //告警内容 -}; - -enum E_ALARM_STYLE -{ - AS_ALARM = 0, // 告警动作 - AS_ALARM_RTN = 1, // 告警恢复 - AS_EVENT_ONLY = 2, // 仅产生事件 - AS_DO_NOTHING = 3, // 无 -}; -// 报警状态 -enum E_ALARM_LOGICSTATE -{ - E_ALS_ALARM = 0, // 报警状态 - E_ALS_ALARM_CFM=1, // 报警确认状态 - E_ALS_RETURN=2, // 报警返回状态 - E_ALS_RETURN_CFM=3, // 报警返回确认状态 - ALS_EVT_ONLY = 4, // 仅事件 - - //在原始告警窗删除后,可能还需要在智能告警窗展示 - E_ALS_ALARM_DEL = 20, // 告警状态,且在原始告警窗已删除,可能是达到数量上限而删除 - E_ALS_ALARM_CFM_DEL =21, // 告警确认状态,且在原始告警窗已删除 - E_ALS_RETURN_DEL=22, // 告警返回状态,且在原始告警窗已删除,可能是达到数量上限而删除 - E_ALS_RETURN_CFM_DEL=23, // 告警返回确认状态,且在原始告警窗已删除 - E_ALS_BAD = 100 -}; - -enum E_LOCATION_TYPE -{ - E_LOCATION_NODE = 0, - E_LOCATION_AREA -}; - -struct STimeKeyIdTag -{ - quint64 time_stamp; - QString key_id_tag; -}; - -struct SAreaInfo -{ - int nId; - QString stTag; - QString stDes; - E_LOCATION_TYPE eType; - int nPareaId; - SAreaInfo() { - nId = -1; - stTag = QString(); - stDes = QString(); - eType = E_LOCATION_NODE; - nPareaId = -1; - } -}; -struct ST_FILTER -{ - - bool isLevelFilterEnable; - QList levelFilter; //报警级别过滤 - bool isLocationFilterEnable; //是否按车站过滤 - QList locationFilter; //车站过滤 - bool isRegionFilterEnable; //是否按责任区过滤 - QList regionFilter; //责任区过滤 - bool isStatusFilterEnable; //是否按报警类型过滤 - QList statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) - QList statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) - bool isDeviceTypeFileter; //设备类型过滤 - QString subSystem; //子系统 - QString deviceType; //设备类型 - bool isKeywordEnable; //关键字过滤 - QString keyword; //关键字 - bool timeFilterEnable; //是否根据时间过滤 - QDateTime startTime; //起始时间 - QDateTime endTime; //终止时间 - - bool isReturnFilterEnable; //是否根据复归状态过滤 - bool isReturn; - ST_FILTER() { - isLevelFilterEnable = false; - isLocationFilterEnable = false; - isRegionFilterEnable = false; - - isStatusFilterEnable = false; - - isDeviceTypeFileter = false; - subSystem = QString(); - deviceType = QString(); - isKeywordEnable = false; - keyword = QString(); - timeFilterEnable = false; - QDateTime dataTime(QDateTime::currentDateTime()); - dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),0,0)); - startTime = dataTime; - dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),59,999)); - endTime = dataTime; - - isReturnFilterEnable =false; - isReturn = false; - } -}; -class CEventMsgInfo; -typedef QSharedPointer EventMsgPtr; - -class CEventMsgInfo -{ -public: - CEventMsgInfo(); - CEventMsgInfo(const CEventMsgInfo &other); - void initialize(const kbd_idlfile::SEvtInfoToEvtClt &eventInfo); - bool lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool operator==(const EventMsgPtr &target); - qint32 alm_type; //报警类型 - E_ALARM_STYLE alm_style; //< 告警类型 - quint64 time_stamp; //时标(RFC1305、POSIX时标标准) - qint32 domain_id; //域ID - qint32 location_id; //位置ID - qint32 app_id; //应用号 - QString content; //报警内容 - qint32 priority; //报警优先级id - qint32 dev_type; //设备类型ID - qint32 region_id; //责任区ID - bool deleted; //实时事件删除标志 - bool filterDelete; //过滤删除 - QString uuid_base64; //< uuid 主键 - QString key_id_tag; //< 测点ID - int32 alm_status; //事件状态 - uint cfm_user; //确认人 - uint64 cfm_time; //确认时间 - QString dev_group_tag; //< 设备组 - qint32 sub_system; //专业号 -//Extend - qint32 priorityOrder; - - QString wave_file; -}; - - -Q_DECLARE_METATYPE(CEventMsgInfo) -Q_DECLARE_METATYPE(EventMsgPtr) - -#endif // ALARMMSGINFO_H +#ifndef ALARMMSGINFO_H +#define ALARMMSGINFO_H + +#include +#include +#include +#include "alarm_server_api/CAlmApiForEvtClt.h" +#include "common/DataType.h" +#include + +#define LIMIT_HIS_RECORD 10000 +#define REAL_BUTTON_COLUMN 7 //按钮所在列 +#define HIS_BUTTON_COLUMN 9 //按钮所在列 +//排序 +enum E_ALARM_VIEW +{ + E_ALARM_REAL_EVENT = 0, + E_ALARM_HIS_EVENT =1 +}; +enum E_ALARM_SORTKEY +{ + E_SORT_TIME = 0, //时间戳 + E_SORT_PRIORITY, //优先级 + E_SORT_LOCATION, //车站 + E_SORT_REGION, //责任区 + E_SORT_TYPE, //事件类型 + E_SORT_STATUS, //事件状态 + E_SORT_STYLE, //复归状态 + E_SORT_CONTENT //告警内容 +}; + +enum E_ALARM_STYLE +{ + AS_ALARM = 0, // 告警动作 + AS_ALARM_RTN = 1, // 告警恢复 + AS_EVENT_ONLY = 2, // 仅产生事件 + AS_DO_NOTHING = 3, // 无 +}; +// 报警状态 +enum E_ALARM_LOGICSTATE +{ + E_ALS_ALARM = 0, // 报警状态 + E_ALS_ALARM_CFM=1, // 报警确认状态 + E_ALS_RETURN=2, // 报警返回状态 + E_ALS_RETURN_CFM=3, // 报警返回确认状态 + ALS_EVT_ONLY = 4, // 仅事件 + + //在原始告警窗删除后,可能还需要在智能告警窗展示 + E_ALS_ALARM_DEL = 20, // 告警状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_ALARM_CFM_DEL =21, // 告警确认状态,且在原始告警窗已删除 + E_ALS_RETURN_DEL=22, // 告警返回状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_RETURN_CFM_DEL=23, // 告警返回确认状态,且在原始告警窗已删除 + E_ALS_BAD = 100 +}; + +enum E_LOCATION_TYPE +{ + E_LOCATION_NODE = 0, + E_LOCATION_AREA +}; + +struct STimeKeyIdTag +{ + quint64 time_stamp; + QString key_id_tag; +}; + +struct SAreaInfo +{ + int nId; + QString stTag; + QString stDes; + E_LOCATION_TYPE eType; + int nPareaId; + SAreaInfo() { + nId = -1; + stTag = QString(); + stDes = QString(); + eType = E_LOCATION_NODE; + nPareaId = -1; + } +}; +struct ST_FILTER +{ + + bool isLevelFilterEnable; + QList levelFilter; //报警级别过滤 + bool isLocationFilterEnable; //是否按车站过滤 + QList locationFilter; //车站过滤 + bool isRegionFilterEnable; //是否按责任区过滤 + QList regionFilter; //责任区过滤 + bool isStatusFilterEnable; //是否按报警类型过滤 + QList statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) + QList statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) + bool isDeviceTypeFileter; //设备类型过滤 + QString subSystem; //子系统 + QString deviceType; //设备类型 + bool isKeywordEnable; //关键字过滤 + QString keyword; //关键字 + bool timeFilterEnable; //是否根据时间过滤 + QDateTime startTime; //起始时间 + QDateTime endTime; //终止时间 + + bool isReturnFilterEnable; //是否根据复归状态过滤 + bool isReturn; + ST_FILTER() { + isLevelFilterEnable = false; + isLocationFilterEnable = false; + isRegionFilterEnable = false; + + isStatusFilterEnable = false; + + isDeviceTypeFileter = false; + subSystem = QString(); + deviceType = QString(); + isKeywordEnable = false; + keyword = QString(); + timeFilterEnable = false; + QDateTime dataTime(QDateTime::currentDateTime()); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),0,0)); + startTime = dataTime; + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),59,999)); + endTime = dataTime; + + isReturnFilterEnable =false; + isReturn = false; + } +}; +class CEventMsgInfo; +typedef QSharedPointer EventMsgPtr; + +class CEventMsgInfo +{ +public: + CEventMsgInfo(); + CEventMsgInfo(const CEventMsgInfo &other); + void initialize(const kbd_idlfile::SEvtInfoToEvtClt &eventInfo); + bool lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool operator==(const EventMsgPtr &target); + qint32 alm_type; //报警类型 + E_ALARM_STYLE alm_style; //< 告警类型 + quint64 time_stamp; //时标(RFC1305、POSIX时标标准) + qint32 domain_id; //域ID + qint32 location_id; //位置ID + qint32 app_id; //应用号 + QString content; //报警内容 + qint32 priority; //报警优先级id + qint32 dev_type; //设备类型ID + qint32 region_id; //责任区ID + bool deleted; //实时事件删除标志 + bool filterDelete; //过滤删除 + QString uuid_base64; //< uuid 主键 + QString key_id_tag; //< 测点ID + int32 alm_status; //事件状态 + uint cfm_user; //确认人 + uint64 cfm_time; //确认时间 + QString dev_group_tag; //< 设备组 + qint32 sub_system; //专业号 +//Extend + qint32 priorityOrder; + + QString wave_file; +}; + + +Q_DECLARE_METATYPE(CEventMsgInfo) +Q_DECLARE_METATYPE(EventMsgPtr) + +#endif // ALARMMSGINFO_H diff --git a/product/src/gui/plugin/EventWidget/CEventMsgManage.cpp b/product/src/gui/plugin/EventWidget/CEventMsgManage.cpp index 5eb03b58..0f38ee17 100644 --- a/product/src/gui/plugin/EventWidget/CEventMsgManage.cpp +++ b/product/src/gui/plugin/EventWidget/CEventMsgManage.cpp @@ -1,155 +1,155 @@ -#include "CEventMsgManage.h" -#include -#include -CEventMsgManage * CEventMsgManage::m_pInstance = Q_NULLPTR; - -CEventMsgManage *CEventMsgManage::instance() -{ - if(m_pInstance == Q_NULLPTR) - { - m_pInstance = new CEventMsgManage(); - } - return m_pInstance; -} - - -CEventMsgManage::CEventMsgManage() - : QObject() -{ - mutex = new QMutex(); -} - -CEventMsgManage::~CEventMsgManage() -{ - m_listEventInfo.clear(); - m_eventDeviceGroupStatistical.clear(); - delete mutex; - m_pInstance = Q_NULLPTR; -} - -QList CEventMsgManage::getListEventInfo() -{ - QMutexLocker locker(mutex); - return m_listEventInfo; -} - -int CEventMsgManage::getListEventCount() -{ - if(m_listEventInfo.isEmpty()) - { - return 0; - } - - return m_listEventInfo.count(); -} - -void CEventMsgManage::addEventMsg(const EventMsgPtr msg) -{ - QMutexLocker locker(mutex); - if(!m_listEventInfo.isEmpty()) - { - bool inserted = false; - QList::iterator iter = m_listEventInfo.begin(); - while (iter != m_listEventInfo.end()) - { - if(msg->time_stamp >= (*iter)->time_stamp) - { - m_listEventInfo.insert(iter, msg); - inserted = true; - break; - } - iter++; - } - if (!inserted) - { - m_listEventInfo.append(msg); - } - } - else - { - m_listEventInfo.append(msg); - } - if(m_listEventInfo.size() > 10000) - { - EventMsgPtr info = m_listEventInfo.takeLast(); - info->deleted = true; - } - else - { - devDevGTotEvtAddStats(msg); - } -} - -void CEventMsgManage::linkWave2EvtMsg(const QList &uuidList, const QString &waveFile) -{ - QMutexLocker locker(mutex); - for(int index(0);index::iterator it = m_listEventInfo.begin(); - while (it != m_listEventInfo.end()) { - if((*it)->uuid_base64 == uuidList.at(index)) - { - (*it)->wave_file = waveFile; - break; - } - it++; - } - } -} - -void CEventMsgManage::removeEventMsgByDomainID(const int domainId) -{ - QMutexLocker locker(mutex); - QList::iterator it = m_listEventInfo.begin(); - while (it != m_listEventInfo.end()) - { - if(domainId == (*it)->domain_id) - { - it = m_listEventInfo.erase(it); - continue; - } - it++; - } -} - -void CEventMsgManage::clearRTMsg() -{ - QMutexLocker locker(mutex); - m_listEventInfo.clear(); - m_eventDeviceGroupStatistical.clear(); -} - -QHash CEventMsgManage::getDevGStatisticalInfo() -{ - QMutexLocker locker(mutex); - - return m_eventDeviceGroupStatistical; -} - -int CEventMsgManage::deviceGroupAlarmStatistical(const QString &deviceGroup) -{ - QMutexLocker locker(mutex); - - if(deviceGroup.isEmpty()) - { - return 0; - } - - return m_eventDeviceGroupStatistical.value(deviceGroup, 0); -} - -void CEventMsgManage::devDevGTotEvtAddStats(const EventMsgPtr &msg) -{ - int dgCount = m_eventDeviceGroupStatistical.value(msg->dev_group_tag,0); - - ++dgCount; - - if(dgCount <= 0) - { - m_eventDeviceGroupStatistical.remove(msg->dev_group_tag); - } - else - { - m_eventDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); - } -} +#include "CEventMsgManage.h" +#include +#include +CEventMsgManage * CEventMsgManage::m_pInstance = Q_NULLPTR; + +CEventMsgManage *CEventMsgManage::instance() +{ + if(m_pInstance == Q_NULLPTR) + { + m_pInstance = new CEventMsgManage(); + } + return m_pInstance; +} + + +CEventMsgManage::CEventMsgManage() + : QObject() +{ + mutex = new QMutex(); +} + +CEventMsgManage::~CEventMsgManage() +{ + m_listEventInfo.clear(); + m_eventDeviceGroupStatistical.clear(); + delete mutex; + m_pInstance = Q_NULLPTR; +} + +QList CEventMsgManage::getListEventInfo() +{ + QMutexLocker locker(mutex); + return m_listEventInfo; +} + +int CEventMsgManage::getListEventCount() +{ + if(m_listEventInfo.isEmpty()) + { + return 0; + } + + return m_listEventInfo.count(); +} + +void CEventMsgManage::addEventMsg(const EventMsgPtr msg) +{ + QMutexLocker locker(mutex); + if(!m_listEventInfo.isEmpty()) + { + bool inserted = false; + QList::iterator iter = m_listEventInfo.begin(); + while (iter != m_listEventInfo.end()) + { + if(msg->time_stamp >= (*iter)->time_stamp) + { + m_listEventInfo.insert(iter, msg); + inserted = true; + break; + } + iter++; + } + if (!inserted) + { + m_listEventInfo.append(msg); + } + } + else + { + m_listEventInfo.append(msg); + } + if(m_listEventInfo.size() > 10000) + { + EventMsgPtr info = m_listEventInfo.takeLast(); + info->deleted = true; + } + else + { + devDevGTotEvtAddStats(msg); + } +} + +void CEventMsgManage::linkWave2EvtMsg(const QList &uuidList, const QString &waveFile) +{ + QMutexLocker locker(mutex); + for(int index(0);index::iterator it = m_listEventInfo.begin(); + while (it != m_listEventInfo.end()) { + if((*it)->uuid_base64 == uuidList.at(index)) + { + (*it)->wave_file = waveFile; + break; + } + it++; + } + } +} + +void CEventMsgManage::removeEventMsgByDomainID(const int domainId) +{ + QMutexLocker locker(mutex); + QList::iterator it = m_listEventInfo.begin(); + while (it != m_listEventInfo.end()) + { + if(domainId == (*it)->domain_id) + { + it = m_listEventInfo.erase(it); + continue; + } + it++; + } +} + +void CEventMsgManage::clearRTMsg() +{ + QMutexLocker locker(mutex); + m_listEventInfo.clear(); + m_eventDeviceGroupStatistical.clear(); +} + +QHash CEventMsgManage::getDevGStatisticalInfo() +{ + QMutexLocker locker(mutex); + + return m_eventDeviceGroupStatistical; +} + +int CEventMsgManage::deviceGroupAlarmStatistical(const QString &deviceGroup) +{ + QMutexLocker locker(mutex); + + if(deviceGroup.isEmpty()) + { + return 0; + } + + return m_eventDeviceGroupStatistical.value(deviceGroup, 0); +} + +void CEventMsgManage::devDevGTotEvtAddStats(const EventMsgPtr &msg) +{ + int dgCount = m_eventDeviceGroupStatistical.value(msg->dev_group_tag,0); + + ++dgCount; + + if(dgCount <= 0) + { + m_eventDeviceGroupStatistical.remove(msg->dev_group_tag); + } + else + { + m_eventDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); + } +} diff --git a/product/src/gui/plugin/EventWidget/CEventMsgManage.h b/product/src/gui/plugin/EventWidget/CEventMsgManage.h index 5bf2ef6f..f895457e 100644 --- a/product/src/gui/plugin/EventWidget/CEventMsgManage.h +++ b/product/src/gui/plugin/EventWidget/CEventMsgManage.h @@ -1,46 +1,46 @@ -#ifndef CEventMsgManage_H -#define CEventMsgManage_H - -#include -#include "CEventMsgInfo.h" - -class QMutex; - -class CEventMsgManage : public QObject -{ - Q_OBJECT -public: - static CEventMsgManage * instance(); - - ~CEventMsgManage(); - - QList getListEventInfo(); - - int getListEventCount(); - - void addEventMsg(const EventMsgPtr msg); - - void linkWave2EvtMsg(const QList &uuidList,const QString &waveFile); - - void removeEventMsgByDomainID(const int domainId); - - void clearRTMsg(); - - QHash getDevGStatisticalInfo(); - - int deviceGroupAlarmStatistical(const QString &deviceGroup); - -private: - CEventMsgManage(); - - void devDevGTotEvtAddStats(const EventMsgPtr &msg); - -private: - QMutex * mutex; - QList m_listEventInfo; - QList m_historyEventInfo; - QHash m_eventDeviceGroupStatistical; //<设备组事件数量统计 - static CEventMsgManage * m_pInstance; -}; - -#endif // CEventMsgManage_H +#ifndef CEventMsgManage_H +#define CEventMsgManage_H + +#include +#include "CEventMsgInfo.h" + +class QMutex; + +class CEventMsgManage : public QObject +{ + Q_OBJECT +public: + static CEventMsgManage * instance(); + + ~CEventMsgManage(); + + QList getListEventInfo(); + + int getListEventCount(); + + void addEventMsg(const EventMsgPtr msg); + + void linkWave2EvtMsg(const QList &uuidList,const QString &waveFile); + + void removeEventMsgByDomainID(const int domainId); + + void clearRTMsg(); + + QHash getDevGStatisticalInfo(); + + int deviceGroupAlarmStatistical(const QString &deviceGroup); + +private: + CEventMsgManage(); + + void devDevGTotEvtAddStats(const EventMsgPtr &msg); + +private: + QMutex * mutex; + QList m_listEventInfo; + QList m_historyEventInfo; + QHash m_eventDeviceGroupStatistical; //<设备组事件数量统计 + static CEventMsgManage * m_pInstance; +}; + +#endif // CEventMsgManage_H diff --git a/product/src/gui/plugin/EventWidget/CEventPluginWidget.cpp b/product/src/gui/plugin/EventWidget/CEventPluginWidget.cpp index 87c8d18a..adf0cc20 100644 --- a/product/src/gui/plugin/EventWidget/CEventPluginWidget.cpp +++ b/product/src/gui/plugin/EventWidget/CEventPluginWidget.cpp @@ -1,26 +1,26 @@ -#include -#include "CEventPluginWidget.h" -#include "CEventForm.h" - -CEventPluginWidget::CEventPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CEventPluginWidget::~CEventPluginWidget() -{ - -} - -bool CEventPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec); - CEventForm *pWidget = new CEventForm(parent, editMode); - *widget = (QWidget *)pWidget; - *eventWidget = (IPluginWidget *)pWidget; - return true; -} - -void CEventPluginWidget::release() -{ -} +#include +#include "CEventPluginWidget.h" +#include "CEventForm.h" + +CEventPluginWidget::CEventPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CEventPluginWidget::~CEventPluginWidget() +{ + +} + +bool CEventPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec); + CEventForm *pWidget = new CEventForm(parent, editMode); + *widget = (QWidget *)pWidget; + *eventWidget = (IPluginWidget *)pWidget; + return true; +} + +void CEventPluginWidget::release() +{ +} diff --git a/product/src/gui/plugin/EventWidget/CEventPluginWidget.h b/product/src/gui/plugin/EventWidget/CEventPluginWidget.h index e32fb0a4..1e530db5 100644 --- a/product/src/gui/plugin/EventWidget/CEventPluginWidget.h +++ b/product/src/gui/plugin/EventWidget/CEventPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CEVENTPLUGINWIDGET_H -#define CEVENTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CEventPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CEventPluginWidget(QObject *parent = 0); - ~CEventPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec); - void release(); -}; - -#endif //CEVENTPLUGINWIDGET_H - +#ifndef CEVENTPLUGINWIDGET_H +#define CEVENTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CEventPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CEventPluginWidget(QObject *parent = 0); + ~CEventPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec); + void release(); +}; + +#endif //CEVENTPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/EventWidget/CEventView.cpp b/product/src/gui/plugin/EventWidget/CEventView.cpp index 0939d022..86fd5ad3 100644 --- a/product/src/gui/plugin/EventWidget/CEventView.cpp +++ b/product/src/gui/plugin/EventWidget/CEventView.cpp @@ -1,36 +1,36 @@ -#include -#include "CEventView.h" - -CEventView::CEventView(QWidget *parent) - :QTableView(parent) -{ - setSortingEnabled(true); - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - setSelectionBehavior(QAbstractItemView::SelectRows); - //setSelectionMode(QAbstractItemView::MultiSelection); -} - -QModelIndexList CEventView::selectedItems() const -{ - QModelIndexList indexList; - foreach(QModelIndex index, selectedIndexes()) - { - if(index.column() == 0) - { - indexList.append(index); - } - } - return indexList; -} - -void CEventView::setDefaultRowHeight(int height) -{ - verticalHeader()->setDefaultSectionSize(height); -} - -void CEventView::selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected) -{ - QTableView::selectionChanged(selected, deSelected); - emit sig_selectionChanged(selectedIndexes()); -} +#include +#include "CEventView.h" + +CEventView::CEventView(QWidget *parent) + :QTableView(parent) +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + setSelectionBehavior(QAbstractItemView::SelectRows); + //setSelectionMode(QAbstractItemView::MultiSelection); +} + +QModelIndexList CEventView::selectedItems() const +{ + QModelIndexList indexList; + foreach(QModelIndex index, selectedIndexes()) + { + if(index.column() == 0) + { + indexList.append(index); + } + } + return indexList; +} + +void CEventView::setDefaultRowHeight(int height) +{ + verticalHeader()->setDefaultSectionSize(height); +} + +void CEventView::selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected) +{ + QTableView::selectionChanged(selected, deSelected); + emit sig_selectionChanged(selectedIndexes()); +} diff --git a/product/src/gui/plugin/EventWidget/CEventView.h b/product/src/gui/plugin/EventWidget/CEventView.h index e5e4846f..5a251886 100644 --- a/product/src/gui/plugin/EventWidget/CEventView.h +++ b/product/src/gui/plugin/EventWidget/CEventView.h @@ -1,22 +1,22 @@ -#ifndef CEventView_H -#define CEventView_H - -#include - -class CEventView : public QTableView -{ - Q_OBJECT -public: - CEventView(QWidget *parent = Q_NULLPTR); - - QModelIndexList selectedItems() const; - - void setDefaultRowHeight(int height); -signals: - void sig_selectionChanged(const QModelIndexList &list); - -protected slots: - virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected); -}; - -#endif // ALARMVIEW_H +#ifndef CEventView_H +#define CEventView_H + +#include + +class CEventView : public QTableView +{ + Q_OBJECT +public: + CEventView(QWidget *parent = Q_NULLPTR); + + QModelIndexList selectedItems() const; + + void setDefaultRowHeight(int height); +signals: + void sig_selectionChanged(const QModelIndexList &list); + +protected slots: + virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected); +}; + +#endif // ALARMVIEW_H diff --git a/product/src/gui/plugin/EventWidget/CExcelPrinter.cpp b/product/src/gui/plugin/EventWidget/CExcelPrinter.cpp index 3c74ebea..53b4f8b4 100644 --- a/product/src/gui/plugin/EventWidget/CExcelPrinter.cpp +++ b/product/src/gui/plugin/EventWidget/CExcelPrinter.cpp @@ -1,65 +1,65 @@ -#include "CExcelPrinter.h" -CExcelPrinter::CExcelPrinter(QObject *parent) : QObject(parent) -{ - -} - -void CExcelPrinter::initialize() -{ - -} - -void CExcelPrinter::printerByModel(CEventItemModel *model, const QString fileName) -{ - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "实时事件" ); - int rowcount=model->rowCount(); - int colcount=model->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - // 写内容 - for ( int i=0; idata(model->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText ); - } - } - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - // 提示导出路径 - QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); - emit sigShowResult(result); -} - -void CExcelPrinter::printerHisByModel(CEventHistoryModel *model, const QString fileName) -{ - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "历史事件" ); - // 写横向表头 - int rowcount=model->rowCount(); - int colcount=model->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - // 写内容 - for ( int i=0; idata(model->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText ); - } - } - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - // 提示导出路径 - QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); - emit sigShowResult(result); -} +#include "CExcelPrinter.h" +CExcelPrinter::CExcelPrinter(QObject *parent) : QObject(parent) +{ + +} + +void CExcelPrinter::initialize() +{ + +} + +void CExcelPrinter::printerByModel(CEventItemModel *model, const QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "实时事件" ); + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString()); + } + // 写内容 + for ( int i=0; idata(model->index(i, j)).toString(); + xlsx.write( i+2, j+1, sText ); + } + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + // 提示导出路径 + QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); + emit sigShowResult(result); +} + +void CExcelPrinter::printerHisByModel(CEventHistoryModel *model, const QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "历史事件" ); + // 写横向表头 + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString()); + } + // 写内容 + for ( int i=0; idata(model->index(i, j)).toString(); + xlsx.write( i+2, j+1, sText ); + } + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + // 提示导出路径 + QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); + emit sigShowResult(result); +} diff --git a/product/src/gui/plugin/EventWidget/CExcelPrinter.h b/product/src/gui/plugin/EventWidget/CExcelPrinter.h index dc552b07..b3cdfeeb 100644 --- a/product/src/gui/plugin/EventWidget/CExcelPrinter.h +++ b/product/src/gui/plugin/EventWidget/CExcelPrinter.h @@ -1,21 +1,21 @@ -#ifndef CEXCELPRINTER_H -#define CEXCELPRINTER_H - -#include -#include -#include -#include "model_excel/xlsx/xlsxdocument.h" -class CExcelPrinter : public QObject -{ - Q_OBJECT -public: - explicit CExcelPrinter(QObject *parent = nullptr); - void initialize(); -signals: - void sigShowResult(QString result); -public slots: - void printerByModel(CEventItemModel *model,const QString fileName); - void printerHisByModel(CEventHistoryModel *model,const QString fileName); -}; - -#endif // CEXCELPRINTER_H +#ifndef CEXCELPRINTER_H +#define CEXCELPRINTER_H + +#include +#include +#include +#include "model_excel/xlsx/xlsxdocument.h" +class CExcelPrinter : public QObject +{ + Q_OBJECT +public: + explicit CExcelPrinter(QObject *parent = nullptr); + void initialize(); +signals: + void sigShowResult(QString result); +public slots: + void printerByModel(CEventItemModel *model,const QString fileName); + void printerHisByModel(CEventHistoryModel *model,const QString fileName); +}; + +#endif // CEXCELPRINTER_H diff --git a/product/src/gui/plugin/EventWidget/CMyCalendar.cpp b/product/src/gui/plugin/EventWidget/CMyCalendar.cpp index a136d524..e5f6ea98 100644 --- a/product/src/gui/plugin/EventWidget/CMyCalendar.cpp +++ b/product/src/gui/plugin/EventWidget/CMyCalendar.cpp @@ -1,93 +1,93 @@ -#include "CMyCalendar.h" -#include "ui_CMyCalendar.h" -#include -#include -#include - -CMyCalendar::CMyCalendar(QWidget *parent) : - QWidget(parent), - ui(new Ui::CMyCalendar) -{ - ui->setupUi(this); - connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); - connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); - connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); - m_startTime = QDate::currentDate(); - m_endTime = QDate::currentDate(); - ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); - ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit_2->setReadOnly(true); -} - -CMyCalendar::~CMyCalendar() -{ - delete ui; -} - -void CMyCalendar::setView(E_ALARM_VIEW view) -{ - m_view = view; - if(m_view == E_ALARM_HIS_EVENT) - { - ui->pushButton->setEnabled(false); - }else - { - ui->pushButton->setEnabled(true); - } -} - -void CMyCalendar::keyPressEvent(QKeyEvent *event) -{ - if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) - { - return ; - } - QWidget::keyPressEvent(event); -} - -void CMyCalendar::slot_endTime(QDate date) -{ - ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); - m_endTime = date; - if(m_startTime.isNull() ) - { - return; - } - if(m_endTime < m_startTime) - { - return ; - } - if(m_view == E_ALARM_HIS_EVENT) - { - QTime time_1(0,0,0); - QTime time_2(23,59,59); - QDateTime startTime; - QDateTime endTime; - startTime.setDate(m_startTime); - startTime.setTime(time_1); - - endTime.setDate(m_endTime); - endTime.setTime(time_2); - if((endTime.toMSecsSinceEpoch()-startTime.toMSecsSinceEpoch())/1000/3600/24 >= 90 ) - { - return; - } - } - emit sig_endTimeClick(m_startTime,m_endTime); -} - -void CMyCalendar::slot_startTime(QDate date) -{ - m_startTime = date; - ui->lineEdit->setText(date.toString("yyyy-MM-dd")); -} - -void CMyCalendar::slot_cancle() -{ - if(m_view == E_ALARM_HIS_EVENT) - { - return; - } - emit sig_cancle(); -} +#include "CMyCalendar.h" +#include "ui_CMyCalendar.h" +#include +#include +#include + +CMyCalendar::CMyCalendar(QWidget *parent) : + QWidget(parent), + ui(new Ui::CMyCalendar) +{ + ui->setupUi(this); + connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); + connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); + connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); + m_startTime = QDate::currentDate(); + m_endTime = QDate::currentDate(); + ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); + ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit_2->setReadOnly(true); +} + +CMyCalendar::~CMyCalendar() +{ + delete ui; +} + +void CMyCalendar::setView(E_ALARM_VIEW view) +{ + m_view = view; + if(m_view == E_ALARM_HIS_EVENT) + { + ui->pushButton->setEnabled(false); + }else + { + ui->pushButton->setEnabled(true); + } +} + +void CMyCalendar::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + { + return ; + } + QWidget::keyPressEvent(event); +} + +void CMyCalendar::slot_endTime(QDate date) +{ + ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); + m_endTime = date; + if(m_startTime.isNull() ) + { + return; + } + if(m_endTime < m_startTime) + { + return ; + } + if(m_view == E_ALARM_HIS_EVENT) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + QDateTime startTime; + QDateTime endTime; + startTime.setDate(m_startTime); + startTime.setTime(time_1); + + endTime.setDate(m_endTime); + endTime.setTime(time_2); + if((endTime.toMSecsSinceEpoch()-startTime.toMSecsSinceEpoch())/1000/3600/24 >= 90 ) + { + return; + } + } + emit sig_endTimeClick(m_startTime,m_endTime); +} + +void CMyCalendar::slot_startTime(QDate date) +{ + m_startTime = date; + ui->lineEdit->setText(date.toString("yyyy-MM-dd")); +} + +void CMyCalendar::slot_cancle() +{ + if(m_view == E_ALARM_HIS_EVENT) + { + return; + } + emit sig_cancle(); +} diff --git a/product/src/gui/plugin/EventWidget/CMyCalendar.h b/product/src/gui/plugin/EventWidget/CMyCalendar.h index 359703a7..cfce4691 100644 --- a/product/src/gui/plugin/EventWidget/CMyCalendar.h +++ b/product/src/gui/plugin/EventWidget/CMyCalendar.h @@ -1,38 +1,38 @@ -#ifndef CMYCALENDAR_H -#define CMYCALENDAR_H - -#include -#include -#include -#include "CEventMsgInfo.h" - -namespace Ui { -class CMyCalendar; -} - -class CMyCalendar : public QWidget -{ - Q_OBJECT -signals: - void sig_endTimeClick(QDate startDate,QDate endDate); - void sig_startTimeClick(QDate date); - void sig_cancle(); -public: - explicit CMyCalendar(QWidget *parent = 0); - ~CMyCalendar(); - void setView(E_ALARM_VIEW view); -protected: - void keyPressEvent(QKeyEvent *event); - -public slots: - void slot_endTime(QDate date); - void slot_startTime(QDate date); - void slot_cancle(); -private: - Ui::CMyCalendar *ui; - QDate m_startTime; - QDate m_endTime; - E_ALARM_VIEW m_view; -}; - -#endif // CMYCALENDAR_H +#ifndef CMYCALENDAR_H +#define CMYCALENDAR_H + +#include +#include +#include +#include "CEventMsgInfo.h" + +namespace Ui { +class CMyCalendar; +} + +class CMyCalendar : public QWidget +{ + Q_OBJECT +signals: + void sig_endTimeClick(QDate startDate,QDate endDate); + void sig_startTimeClick(QDate date); + void sig_cancle(); +public: + explicit CMyCalendar(QWidget *parent = 0); + ~CMyCalendar(); + void setView(E_ALARM_VIEW view); +protected: + void keyPressEvent(QKeyEvent *event); + +public slots: + void slot_endTime(QDate date); + void slot_startTime(QDate date); + void slot_cancle(); +private: + Ui::CMyCalendar *ui; + QDate m_startTime; + QDate m_endTime; + E_ALARM_VIEW m_view; +}; + +#endif // CMYCALENDAR_H diff --git a/product/src/gui/plugin/EventWidget/CMyCalendar.ui b/product/src/gui/plugin/EventWidget/CMyCalendar.ui index 3cfb549d..98fb3b2c 100644 --- a/product/src/gui/plugin/EventWidget/CMyCalendar.ui +++ b/product/src/gui/plugin/EventWidget/CMyCalendar.ui @@ -1,119 +1,119 @@ - - - CMyCalendar - - - - 0 - 0 - 538 - 264 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 20 - 0 - - - - - - - Qt::AlignCenter - - - - - - - - - - 取消 - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - + + + CMyCalendar + + + + 0 + 0 + 538 + 264 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 20 + 0 + + + + + + + Qt::AlignCenter + + + + + + + + + + 取消 + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/EventWidget/CMyCheckBox.cpp b/product/src/gui/plugin/EventWidget/CMyCheckBox.cpp index f9a083e1..46f563eb 100644 --- a/product/src/gui/plugin/EventWidget/CMyCheckBox.cpp +++ b/product/src/gui/plugin/EventWidget/CMyCheckBox.cpp @@ -1,22 +1,22 @@ -#include "CMyCheckBox.h" -#include - -CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) - :QCheckBox(text,parent) -{ - -} - -CMyCheckBox::CMyCheckBox(QWidget *parent) - :QCheckBox(parent) -{ - -} - -void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) -{ - Q_UNUSED(e); - setChecked(!isChecked()); - emit clicked(isChecked()); - -} +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e); + setChecked(!isChecked()); + emit clicked(isChecked()); + +} diff --git a/product/src/gui/plugin/EventWidget/CMyCheckBox.h b/product/src/gui/plugin/EventWidget/CMyCheckBox.h index 36947db5..bdba8dbc 100644 --- a/product/src/gui/plugin/EventWidget/CMyCheckBox.h +++ b/product/src/gui/plugin/EventWidget/CMyCheckBox.h @@ -1,16 +1,16 @@ -#ifndef MYCHECKBOX_H -#define MYCHECKBOX_H - -#include - -class CMyCheckBox : public QCheckBox -{ -public: - CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); - CMyCheckBox(QWidget *parent = Q_NULLPTR); - -protected: - void mouseReleaseEvent(QMouseEvent *e); -}; - -#endif // MYCHECKBOX_H +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/EventWidget/CMyListWidget.cpp b/product/src/gui/plugin/EventWidget/CMyListWidget.cpp index 3b542202..ded92615 100644 --- a/product/src/gui/plugin/EventWidget/CMyListWidget.cpp +++ b/product/src/gui/plugin/EventWidget/CMyListWidget.cpp @@ -1,12 +1,12 @@ -#include "CMyListWidget.h" - -CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) -{ - -} - -void CMyListWidget::showEvent(QShowEvent *event) -{ - this->updateGeometries(); - QListWidget::showEvent(event); -} +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/EventWidget/CMyListWidget.h b/product/src/gui/plugin/EventWidget/CMyListWidget.h index 9fc4491f..3e92461e 100644 --- a/product/src/gui/plugin/EventWidget/CMyListWidget.h +++ b/product/src/gui/plugin/EventWidget/CMyListWidget.h @@ -1,15 +1,15 @@ -#ifndef CMYLISTWIDGET_H -#define CMYLISTWIDGET_H - -#include - -class CMyListWidget : public QListWidget -{ -public: - explicit CMyListWidget(QWidget *parent = 0); - -protected: - void showEvent(QShowEvent *event); -}; - -#endif // CMYLISTWIDGET_H +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/EventWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/EventWidget/CTableViewPrinter.cpp index 6702252f..afbf955c 100644 --- a/product/src/gui/plugin/EventWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/EventWidget/CTableViewPrinter.cpp @@ -1,122 +1,122 @@ -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include - -CTableViewPrinter::CTableViewPrinter(QTableView *view) - : m_pView(view) -{ - m_pModel = view->model(); -} - -void CTableViewPrinter::print(QPrinter * printer) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - - qreal marginHorizontal = 20; - qreal marginVertical = 20; - - QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); - printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); - - int length = 0; - horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); - for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) - { - length += horizontalHeader->sectionSize(nSection); - } - horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); - - QPainter painter(printer); - - renderHeader(painter); - - int offset = 0; - int currentPage = 0; - int horizontalHeaderHeight = horizontalHeader->height(); - for(int row(0); row < m_pModel->rowCount(); row++) - { - if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) - { - horizontalHeaderHeight = 0; - } - - - if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) - { - printer->newPage(); - currentPage++; - offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - } - - for(int column(0); column < m_pModel->columnCount(); column++) - { - int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - int rowHeight = m_pView->rowHeight(row); - int columnWidth = m_pView->columnWidth(column); - - //< draw item - QStyleOptionViewItem opt; - opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); - painter.save(); - painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); - painter.restore(); - - //< Vertical Line - if(column == 0) - { - QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - //< Horizontal Line - int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; - QPoint left(verticalHeader->width(), rowPosition); - QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); - drawGridLine(&painter, left, right); - - } -} - -void CTableViewPrinter::renderHeader(QPainter &painter) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - for(int column(0); column < horizontalHeader->count(); column++) - { - painter.save(); - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); - painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); - painter.restore(); - } - int columnPosition = horizontalHeader->width() + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); -} - -void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) -{ - painter->save(); - QStyleOptionViewItem opt; - const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); - const QColor gridColor = static_cast(gridHint); - painter->setPen(gridColor); - painter->drawLine(p1, p2); - painter->restore(); -} +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include + +CTableViewPrinter::CTableViewPrinter(QTableView *view) + : m_pView(view) +{ + m_pModel = view->model(); +} + +void CTableViewPrinter::print(QPrinter * printer) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); + printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + + int length = 0; + horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); + for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) + { + length += horizontalHeader->sectionSize(nSection); + } + horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); + + QPainter painter(printer); + + renderHeader(painter); + + int offset = 0; + int currentPage = 0; + int horizontalHeaderHeight = horizontalHeader->height(); + for(int row(0); row < m_pModel->rowCount(); row++) + { + if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) + { + horizontalHeaderHeight = 0; + } + + + if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) + { + printer->newPage(); + currentPage++; + offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + } + + for(int column(0); column < m_pModel->columnCount(); column++) + { + int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + int rowHeight = m_pView->rowHeight(row); + int columnWidth = m_pView->columnWidth(column); + + //< draw item + QStyleOptionViewItem opt; + opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); + painter.save(); + painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); + painter.restore(); + + //< Vertical Line + if(column == 0) + { + QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + //< Horizontal Line + int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; + QPoint left(verticalHeader->width(), rowPosition); + QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); + drawGridLine(&painter, left, right); + + } +} + +void CTableViewPrinter::renderHeader(QPainter &painter) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + for(int column(0); column < horizontalHeader->count(); column++) + { + painter.save(); + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); + painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); + painter.restore(); + } + int columnPosition = horizontalHeader->width() + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); +} + +void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + QStyleOptionViewItem opt; + const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); + const QColor gridColor = static_cast(gridHint); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} diff --git a/product/src/gui/plugin/EventWidget/CTableViewPrinter.h b/product/src/gui/plugin/EventWidget/CTableViewPrinter.h index 4faf41ed..839198f2 100644 --- a/product/src/gui/plugin/EventWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/EventWidget/CTableViewPrinter.h @@ -1,24 +1,24 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H - -class QPointF; -class QPainter; -class QPrinter; -class QTableView; -class QAbstractItemModel; - -class CTableViewPrinter -{ -public: - explicit CTableViewPrinter(QTableView * view); - - void print(QPrinter *printer); - void renderHeader(QPainter &painter); - void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); - -private: - QTableView * m_pView; - QAbstractItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H + +class QPointF; +class QPainter; +class QPrinter; +class QTableView; +class QAbstractItemModel; + +class CTableViewPrinter +{ +public: + explicit CTableViewPrinter(QTableView * view); + + void print(QPrinter *printer); + void renderHeader(QPainter &painter); + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + +private: + QTableView * m_pView; + QAbstractItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/EventWidget/EventWidget.pro b/product/src/gui/plugin/EventWidget/EventWidget.pro index d816901d..73034e63 100644 --- a/product/src/gui/plugin/EventWidget/EventWidget.pro +++ b/product/src/gui/plugin/EventWidget/EventWidget.pro @@ -1,71 +1,71 @@ -QT += core sql xml printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = EventWidget - -CONFIG += plugin - -HEADERS = \ - CEventMsgInfo.h \ - CEventDataCollect.h \ - CEventView.h \ - CEventMsgManage.h \ - CEventItemModel.h \ - CEventHistoryModel.h \ - CEventFilterDialog.h \ - CEventForm.h \ - CEventPluginWidget.h \ - CTableViewPrinter.h \ - CMyListWidget.h \ - CMyCalendar.h \ - CMyCheckBox.h \ - CExcelPrinter.h \ - CEventDelegate.h \ - CEventHisThread.h \ - CAccidentReviewDialog.h \ - CEventDeviceTreeItem.h \ - CEventDeviceTreeModel.h \ - CEventDeviceTreeView.h - -SOURCES = \ - CEventMsgInfo.cpp \ - CEventDataCollect.cpp \ - CEventView.cpp \ - CEventMsgManage.cpp \ - CEventItemModel.cpp \ - CEventHistoryModel.cpp \ - CEventFilterDialog.cpp \ - CEventForm.cpp \ - CEventPluginWidget.cpp \ - CTableViewPrinter.cpp \ - CMyListWidget.cpp \ - CMyCalendar.cpp \ - CMyCheckBox.cpp \ - CExcelPrinter.cpp \ - CEventDelegate.cpp \ - CEventHisThread.cpp \ - CAccidentReviewDialog.cpp \ - CEventDeviceTreeItem.cpp \ - CEventDeviceTreeModel.cpp \ - CEventDeviceTreeView.cpp - -FORMS += \ - CEventFilterDialog.ui \ - CEventForm.ui \ - CMyCalendar.ui - -LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -LIBS += -lpub_sysinfo_api -lnet_msg_bus_api -lalarm_server_api -lmodel_excel - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - - +QT += core sql xml printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = EventWidget + +CONFIG += plugin + +HEADERS = \ + CEventMsgInfo.h \ + CEventDataCollect.h \ + CEventView.h \ + CEventMsgManage.h \ + CEventItemModel.h \ + CEventHistoryModel.h \ + CEventFilterDialog.h \ + CEventForm.h \ + CEventPluginWidget.h \ + CTableViewPrinter.h \ + CMyListWidget.h \ + CMyCalendar.h \ + CMyCheckBox.h \ + CExcelPrinter.h \ + CEventDelegate.h \ + CEventHisThread.h \ + CAccidentReviewDialog.h \ + CEventDeviceTreeItem.h \ + CEventDeviceTreeModel.h \ + CEventDeviceTreeView.h + +SOURCES = \ + CEventMsgInfo.cpp \ + CEventDataCollect.cpp \ + CEventView.cpp \ + CEventMsgManage.cpp \ + CEventItemModel.cpp \ + CEventHistoryModel.cpp \ + CEventFilterDialog.cpp \ + CEventForm.cpp \ + CEventPluginWidget.cpp \ + CTableViewPrinter.cpp \ + CMyListWidget.cpp \ + CMyCalendar.cpp \ + CMyCheckBox.cpp \ + CExcelPrinter.cpp \ + CEventDelegate.cpp \ + CEventHisThread.cpp \ + CAccidentReviewDialog.cpp \ + CEventDeviceTreeItem.cpp \ + CEventDeviceTreeModel.cpp \ + CEventDeviceTreeView.cpp + +FORMS += \ + CEventFilterDialog.ui \ + CEventForm.ui \ + CMyCalendar.ui + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api +LIBS += -lpub_sysinfo_api -lnet_msg_bus_api -lalarm_server_api -lmodel_excel + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + + diff --git a/product/src/gui/plugin/EventWidget/main.cpp b/product/src/gui/plugin/EventWidget/main.cpp index 90943c1a..006b335d 100644 --- a/product/src/gui/plugin/EventWidget/main.cpp +++ b/product/src/gui/plugin/EventWidget/main.cpp @@ -1,42 +1,42 @@ -#include -//#include "CEventPlugin.h" -#include "CEventForm.h" -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "CEventDataCollect.h" -#include "perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - - - //<初始化消息总线 - //kbd_public::StartLogSystem(NULL, "HMI", "Alarm_Client"); - kbd_public::StartLogSystem(NULL, "HMI"); - kbd_net::initMsgBus("Event_Client", "1", true); - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - permMngPtr->PermDllInit(); - if(permMngPtr->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) - { - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return -1; - } - // CEventPlugin p; - { - QApplication app(argc, argv); - CEventForm n(NULL,false); - n.show(); - - app.exec(); - } - - - - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include +//#include "CEventPlugin.h" +#include "CEventForm.h" +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "CEventDataCollect.h" +#include "perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + + + //<初始化消息总线 + //kbd_public::StartLogSystem(NULL, "HMI", "Alarm_Client"); + kbd_public::StartLogSystem(NULL, "HMI"); + kbd_net::initMsgBus("Event_Client", "1", true); + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + permMngPtr->PermDllInit(); + if(permMngPtr->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + { + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return -1; + } + // CEventPlugin p; + { + QApplication app(argc, argv); + CEventForm n(NULL,false); + n.show(); + + app.exec(); + } + + + + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordCommon.h b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordCommon.h index a42d3aeb..35f5e9f7 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordCommon.h +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordCommon.h @@ -1,6 +1,6 @@ -#ifndef CFAULTRECALLRECORDCOMMON_H -#define CFAULTRECALLRECORDCOMMON_H - -#include - -#endif // CFAULTRECALLRECORDCOMMON_H +#ifndef CFAULTRECALLRECORDCOMMON_H +#define CFAULTRECALLRECORDCOMMON_H + +#include + +#endif // CFAULTRECALLRECORDCOMMON_H diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.cpp b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.cpp index 320d8acf..6d2ada56 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.cpp +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.cpp @@ -1,24 +1,24 @@ -#include "CFaultRecallRecordPluginWidget.h" -#include "CFaultRecallRecordWidget.h" -CFaultRecallRecordPluginWidget::CFaultRecallRecordPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CFaultRecallRecordPluginWidget::~CFaultRecallRecordPluginWidget() -{ - -} - -bool CFaultRecallRecordPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CFaultRecallRecordWidget *pWidget = new CFaultRecallRecordWidget(editMode, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CFaultRecallRecordPluginWidget::release() -{ - -} +#include "CFaultRecallRecordPluginWidget.h" +#include "CFaultRecallRecordWidget.h" +CFaultRecallRecordPluginWidget::CFaultRecallRecordPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CFaultRecallRecordPluginWidget::~CFaultRecallRecordPluginWidget() +{ + +} + +bool CFaultRecallRecordPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CFaultRecallRecordWidget *pWidget = new CFaultRecallRecordWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CFaultRecallRecordPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.h b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.h index f6092b3e..e0458f40 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.h +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CFAULTRECALLRECORDPLUGINWIDGET_H -#define CFAULTRECALLRECORDPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CFaultRecallRecordPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CFaultRecallRecordPluginWidget(QObject *parent = 0); - - ~CFaultRecallRecordPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); - -}; - -#endif // CFAULTRECALLRECORDPLUGINWIDGET_H +#ifndef CFAULTRECALLRECORDPLUGINWIDGET_H +#define CFAULTRECALLRECORDPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CFaultRecallRecordPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CFaultRecallRecordPluginWidget(QObject *parent = 0); + + ~CFaultRecallRecordPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); + +}; + +#endif // CFAULTRECALLRECORDPLUGINWIDGET_H diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.cpp b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.cpp index da7209a8..5945c07e 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.cpp +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.cpp @@ -1,485 +1,485 @@ -#include "CFaultRecallRecordWidget.h" -#include "ui_CFaultRecallRecordWidget.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include -#include -#include "Common.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "dbms/db_api_ex/CDbApi.h" - -using namespace kbd_dbms; -using namespace kbd_public; -using namespace kbd_service; - -CFaultRecallRecordWidget::CFaultRecallRecordWidget(bool editMode, QWidget *parent) - : QWidget(parent), - ui(new Ui::CFaultRecallRecordWidget), - m_editMode(editMode) -{ - ui->setupUi(this); - - initStyleSheet(); - initView(); - if(!m_editMode) - { - connect(ui->playBtn,&QPushButton::clicked,this,&CFaultRecallRecordWidget::slotPlayBtn); - connect(ui->delBtn,&QPushButton::clicked,this,&CFaultRecallRecordWidget::slotDelBtn); - connect(ui->clearBtn,&QPushButton::clicked,this,&CFaultRecallRecordWidget::slotClearBtn); - connect(ui->refreshBtn,&QPushButton::clicked,this,&CFaultRecallRecordWidget::slotRefreshBtn); - connect(ui->m_treeWidget,&QTreeWidget::itemDoubleClicked,this,&CFaultRecallRecordWidget::slotItemDoubleClicked); - connect(ui->startTimeEdit,&QDateTimeEdit::dateTimeChanged,this,&CFaultRecallRecordWidget::slot_updateTable); - connect(ui->endTimeEdit,&QDateTimeEdit::dateTimeChanged,this,&CFaultRecallRecordWidget::slot_updateTable); - connect(ui->locationCkb, SIGNAL(currentIndexChanged(int)),this,SLOT(slot_updateTable())); - initViewData(); - - } -} - -CFaultRecallRecordWidget::~CFaultRecallRecordWidget() -{ - delete ui; -} - - -void CFaultRecallRecordWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - -// strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; -// QFile qssfile2(QString::fromStdString(strFullPath)); -// qssfile2.open(QFile::ReadOnly); -// if (qssfile2.isOpen()) -// { -// qss += QLatin1String(qssfile2.readAll()); -// qssfile2.close(); -// } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CFaultRecallRecordWidget::initView() -{ - ui->m_treeWidget->setColumnWidth(0,500); - ui->m_treeWidget->setColumnWidth(1,300); - ui->m_treeWidget->setColumnWidth(2,300); - ui->m_treeWidget->setColumnWidth(3,300); - ui->m_treeWidget->setColumnHidden(4,true); -} - -void CFaultRecallRecordWidget::refeshTree(kbd_dbms::CDbApi* dbifs) -{ - mItemDataVec.clear(); - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID,SUB_SYSTEM,NAME,TIME_BEGING,TIME_END,REPLAY_FIRST_PIC from fault_recall_record order by TIME_BEGING limit 10000"); - - dbifs->execute(sqlQuery, query); - - while(query.next()) - { - SItemData itemData; - itemData.locationId = query.value(0).toInt(); - itemData.subSystem = query.value(1).toInt(); - itemData.name = query.value(2).toString(); - itemData.startTime = query.value(3).toLongLong(); - itemData.endTime = query.value(4).toLongLong(); - itemData.pic = query.value(5).toString(); - mItemDataVec.push_back(itemData); - } - - slot_updateTable(); -} - -bool CFaultRecallRecordWidget::checkUserPerm() -{ - CPermMngApiPtr pPermMng = getPermMngInstance("BASE"); - if (pPermMng == NULL) - { - LOGERROR("CFaultRecallRecordWidget::checkUserPerm(), getPermMngInstance error"); - return false; - }; - - std::string tmp = "FUNC_NOM_DUTY"; - if ( pPermMng->PermCheck(PERM_NOM_FUNC_DEF,&tmp) == PERM_PERMIT ) - return true; - - return false; -} - -bool CFaultRecallRecordWidget::initViewData() -{ - initDateTimeEdit(); - - kbd_dbms::CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); - if(! pReadDb->open()) - { - delete pReadDb; - pReadDb = NULL; - return false; - } - - readLocationArray(pReadDb); - refeshTree(pReadDb); - - pReadDb->close(); - delete pReadDb; - pReadDb = NULL; - - return true; -} - -void CFaultRecallRecordWidget::readLocationArray(kbd_dbms::CDbApi* dbifs) -{ - ui->locationCkb->clear(); - - ui->locationCkb->addItem(tr("全部"),QVariant(-1)); - - QSqlQuery query; - QString sqlQuery = QString("SELECT location_id,description FROM sys_model_location_info order by location_no"); - - dbifs->execute(sqlQuery, query); - - while(query.next()) - { - int locationId = query.value(0).toInt(); - QString locationDesc = query.value(1).toString(); - - ui->locationCkb->addItem(locationDesc,QVariant(locationId)); - } -} - -void CFaultRecallRecordWidget::initDateTimeEdit() -{ - QDateTime now = QDateTime::currentDateTime(); - QDateTime startTime = now.addDays(-1); - QDateTime endTime = now.addDays(1); - ui->startTimeEdit->setDateTime(startTime); - ui->endTimeEdit->setDateTime(endTime); -} - -QString CFaultRecallRecordWidget::getLocationDesc(int locationId) -{ - int index = ui->locationCkb->findData(locationId); - if(index >= 0) - { - return ui->locationCkb->itemText(index); - } - - return QString::number(locationId); -} - - - -void CFaultRecallRecordWidget::slotShowMess(const QString &mess) -{ - QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); -} - -void CFaultRecallRecordWidget::slotPlayBtn() -{ - // 暂时不判断判断用户权限,没有单独的模拟操作权限 -// if ( checkUserPerm() == false ) -// { -// QMessageBox::critical( 0, "错误", "用户权限验证失败" ); -// return; -// } - QString fileStr; - QString descStr; - QList list = ui->m_treeWidget->selectedItems(); - if(list.count() < 1) - { - slotShowMess(tr("请选择一项记录!")); - return; - } - QTreeWidgetItem* item = list.at(0); - fileStr = item->text(4); - descStr = item->text(0); - - qint64 startTime = item->data(2,Qt::UserRole+1).toLongLong(); - qint64 endTime = item->data(3,Qt::UserRole+1).toLongLong(); - - - QString msgStr = QString(tr("确定开始播放“%1”?").arg(descStr)); - int ret = QMessageBox::question(this, tr("提示"),msgStr); - if(ret == QMessageBox::Yes) - { - emit sigPlay(fileStr,startTime,endTime); - } - -} - -void CFaultRecallRecordWidget::slotDelBtn() -{ - - QList list = ui->m_treeWidget->selectedItems(); - if(list.count() < 1) - { - slotShowMess(tr("请选择删除项!")); - return; - } - - - - QTreeWidgetItem* item = list.at(0); - - int locationId = item->data(1,Qt::UserRole+1).toInt(); - QString name = item->text(0); - qint64 startTime = item->data(2,Qt::UserRole+1).toLongLong(); - qint64 endTime = item->data(3,Qt::UserRole+1).toLongLong(); - - - QString msgStr = QString(tr("确定删除记录“%1”?").arg(name)); - int ret = QMessageBox::question(this, tr("提示"),msgStr); - if(ret != QMessageBox::Yes) - { - return; - } - - kbd_dbms::CDbApi * pWriteDb = new CDbApi(DB_CONN_MODEL_WRITE); - if(! pWriteDb->open()) - { - slotShowMess(tr("打开数据库失败。")); - return; - } - - QList listCondition; - CDbCondition cd1; - cd1.m_sColName = "LOCATION_ID"; - cd1.m_eLogic = CDbCondition::LOGIC_AND; - cd1.m_eCompare = CDbCondition::COMPARE_EQ; - cd1.m_value = locationId; - listCondition.push_back(cd1); - - CDbCondition cd2; - cd2.m_sColName = "NAME"; - cd2.m_eLogic = CDbCondition::LOGIC_AND; - cd2.m_eCompare = CDbCondition::COMPARE_EQ; - cd2.m_value = name; - listCondition.push_back(cd2); - - CDbCondition cd3; - cd3.m_sColName = "TIME_BEGING"; - cd3.m_eLogic = CDbCondition::LOGIC_AND; - cd3.m_eCompare = CDbCondition::COMPARE_EQ; - cd3.m_value = startTime; - listCondition.push_back(cd3); - - CDbCondition cd4; - cd4.m_sColName = "TIME_END"; - cd4.m_eLogic = CDbCondition::LOGIC_AND; - cd4.m_eCompare = CDbCondition::COMPARE_EQ; - cd4.m_value = endTime; - listCondition.push_back(cd4); - - - ret = pWriteDb->deleteRow("fault_recall_record", listCondition); - - - pWriteDb->close(); - delete pWriteDb; - pWriteDb = NULL; - - if(ret) - { - delete item; - item = NULL; - slotRefreshBtn(); - } - else - { - slotShowMess(tr("删除“%1”失败!").arg(name)); - } -} - -void CFaultRecallRecordWidget::slotClearBtn() -{ - QString msgStr = QString(tr("确定清空所有记录?")); - int ret = QMessageBox::question(this, tr("提示"),msgStr); - if(ret != QMessageBox::Yes) - { - return; - } - - kbd_dbms::CDbApi * pWriteDb = new CDbApi(DB_CONN_MODEL_WRITE); - if(! pWriteDb->open()) - { - slotShowMess(tr("打开数据库失败。")); - return; - } - - ret = pWriteDb->deleteRow("fault_recall_record"); - - - pWriteDb->close(); - delete pWriteDb; - pWriteDb = NULL; - - if(ret) - { - ui->m_treeWidget->clear(); - slotRefreshBtn(); - } - else - { - slotShowMess(tr("清空失败!")); - } -} - -void CFaultRecallRecordWidget::slotRefreshBtn() -{ - kbd_dbms::CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); - if(! pReadDb->open()) - { - delete pReadDb; - pReadDb = NULL; - slotShowMess(tr("打开数据库失败。")); - return; - } - - refeshTree(pReadDb); - - pReadDb->close(); - delete pReadDb; - pReadDb = NULL; - -} - -void CFaultRecallRecordWidget::slot_updateTable() -{ - ui->m_treeWidget->clear(); - int filterLocation = ui->locationCkb->currentData().toInt(); - qint64 filterStartTime = ui->startTimeEdit->dateTime().toMSecsSinceEpoch(); - qint64 filterEndTime = ui->endTimeEdit->dateTime().toMSecsSinceEpoch(); - - QVector::iterator iter = mItemDataVec.begin(); - for(; iter!=mItemDataVec.end(); ++iter) - { - SItemData& itemData = *iter; - - if(filterLocation != -1 && filterLocation != itemData.locationId) - { - continue; - } - - if(filterStartTime > itemData.startTime) - { - continue; - } - - if(filterEndTime < itemData.endTime) - { - continue; - } - - QTreeWidgetItem* item = new QTreeWidgetItem(ui->m_treeWidget); - - item->setText(0,itemData.name); - - item->setText(1,getLocationDesc(itemData.locationId)); - item->setData(1,Qt::UserRole+1,itemData.locationId); - item->setData(1,Qt::UserRole+2,itemData.subSystem); - - - item->setText(2,QDateTime::fromMSecsSinceEpoch(itemData.startTime).toString("yyyy-MM-dd hh:mm:ss")); - item->setData(2,Qt::UserRole+1,itemData.startTime); - - item->setText(3,QDateTime::fromMSecsSinceEpoch(itemData.endTime).toString("yyyy-MM-dd hh:mm:ss")); - item->setData(3,Qt::UserRole+1,itemData.endTime); - - item->setText(4,itemData.pic); - - item->setTextAlignment(0,Qt::AlignCenter); - item->setTextAlignment(1,Qt::AlignCenter); - item->setTextAlignment(2,Qt::AlignCenter); - item->setTextAlignment(3,Qt::AlignCenter); - item->setTextAlignment(4,Qt::AlignCenter); - } -} - -QString CFaultRecallRecordWidget::curPic() -{ - QList list = ui->m_treeWidget->selectedItems(); - if(list.count() < 1) - { - return ""; - } - QTreeWidgetItem* item = list.at(0); - - QString pic = item->text(4); - return pic; -} - -qint64 CFaultRecallRecordWidget::curStartTime() -{ - QList list = ui->m_treeWidget->selectedItems(); - if(list.count() < 1) - { - return 0; - } - QTreeWidgetItem* item = list.at(0); - - qint64 startTime = item->data(2,Qt::UserRole+1).toLongLong(); - return startTime; -} - -qint64 CFaultRecallRecordWidget::curEndTime() -{ - QList list = ui->m_treeWidget->selectedItems(); - if(list.count() < 1) - { - return 0; - } - QTreeWidgetItem* item = list.at(0); - - qint64 endTime = item->data(3,Qt::UserRole+1).toLongLong(); - return endTime; -} - -QString CFaultRecallRecordWidget::curName() -{ - QList list = ui->m_treeWidget->selectedItems(); - if(list.count() < 1) - { - return ""; - } - QTreeWidgetItem* item = list.at(0); - - QString name = item->text(1); - return name; -} - -void CFaultRecallRecordWidget::setRecordStatus(int status) -{ - bool isEnabled = status != 1; - this->setEnabled(isEnabled); -} - -void CFaultRecallRecordWidget::slotItemDoubleClicked(QTreeWidgetItem *item, int cl) -{ - slotPlayBtn(); -} - -void CFaultRecallRecordWidget::setColumnHidden(int column, bool hide) -{ - ui->m_treeWidget->setColumnHidden(column,hide); -} - -void CFaultRecallRecordWidget::setColumnWidth(int column, int width) -{ - ui->m_treeWidget->setColumnWidth(column,width); -} - - +#include "CFaultRecallRecordWidget.h" +#include "ui_CFaultRecallRecordWidget.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include +#include +#include "Common.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "dbms/db_api_ex/CDbApi.h" + +using namespace kbd_dbms; +using namespace kbd_public; +using namespace kbd_service; + +CFaultRecallRecordWidget::CFaultRecallRecordWidget(bool editMode, QWidget *parent) + : QWidget(parent), + ui(new Ui::CFaultRecallRecordWidget), + m_editMode(editMode) +{ + ui->setupUi(this); + + initStyleSheet(); + initView(); + if(!m_editMode) + { + connect(ui->playBtn,&QPushButton::clicked,this,&CFaultRecallRecordWidget::slotPlayBtn); + connect(ui->delBtn,&QPushButton::clicked,this,&CFaultRecallRecordWidget::slotDelBtn); + connect(ui->clearBtn,&QPushButton::clicked,this,&CFaultRecallRecordWidget::slotClearBtn); + connect(ui->refreshBtn,&QPushButton::clicked,this,&CFaultRecallRecordWidget::slotRefreshBtn); + connect(ui->m_treeWidget,&QTreeWidget::itemDoubleClicked,this,&CFaultRecallRecordWidget::slotItemDoubleClicked); + connect(ui->startTimeEdit,&QDateTimeEdit::dateTimeChanged,this,&CFaultRecallRecordWidget::slot_updateTable); + connect(ui->endTimeEdit,&QDateTimeEdit::dateTimeChanged,this,&CFaultRecallRecordWidget::slot_updateTable); + connect(ui->locationCkb, SIGNAL(currentIndexChanged(int)),this,SLOT(slot_updateTable())); + initViewData(); + + } +} + +CFaultRecallRecordWidget::~CFaultRecallRecordWidget() +{ + delete ui; +} + + +void CFaultRecallRecordWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + +// strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; +// QFile qssfile2(QString::fromStdString(strFullPath)); +// qssfile2.open(QFile::ReadOnly); +// if (qssfile2.isOpen()) +// { +// qss += QLatin1String(qssfile2.readAll()); +// qssfile2.close(); +// } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CFaultRecallRecordWidget::initView() +{ + ui->m_treeWidget->setColumnWidth(0,500); + ui->m_treeWidget->setColumnWidth(1,300); + ui->m_treeWidget->setColumnWidth(2,300); + ui->m_treeWidget->setColumnWidth(3,300); + ui->m_treeWidget->setColumnHidden(4,true); +} + +void CFaultRecallRecordWidget::refeshTree(kbd_dbms::CDbApi* dbifs) +{ + mItemDataVec.clear(); + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID,SUB_SYSTEM,NAME,TIME_BEGING,TIME_END,REPLAY_FIRST_PIC from fault_recall_record order by TIME_BEGING limit 10000"); + + dbifs->execute(sqlQuery, query); + + while(query.next()) + { + SItemData itemData; + itemData.locationId = query.value(0).toInt(); + itemData.subSystem = query.value(1).toInt(); + itemData.name = query.value(2).toString(); + itemData.startTime = query.value(3).toLongLong(); + itemData.endTime = query.value(4).toLongLong(); + itemData.pic = query.value(5).toString(); + mItemDataVec.push_back(itemData); + } + + slot_updateTable(); +} + +bool CFaultRecallRecordWidget::checkUserPerm() +{ + CPermMngApiPtr pPermMng = getPermMngInstance("BASE"); + if (pPermMng == NULL) + { + LOGERROR("CFaultRecallRecordWidget::checkUserPerm(), getPermMngInstance error"); + return false; + }; + + std::string tmp = "FUNC_NOM_DUTY"; + if ( pPermMng->PermCheck(PERM_NOM_FUNC_DEF,&tmp) == PERM_PERMIT ) + return true; + + return false; +} + +bool CFaultRecallRecordWidget::initViewData() +{ + initDateTimeEdit(); + + kbd_dbms::CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(! pReadDb->open()) + { + delete pReadDb; + pReadDb = NULL; + return false; + } + + readLocationArray(pReadDb); + refeshTree(pReadDb); + + pReadDb->close(); + delete pReadDb; + pReadDb = NULL; + + return true; +} + +void CFaultRecallRecordWidget::readLocationArray(kbd_dbms::CDbApi* dbifs) +{ + ui->locationCkb->clear(); + + ui->locationCkb->addItem(tr("全部"),QVariant(-1)); + + QSqlQuery query; + QString sqlQuery = QString("SELECT location_id,description FROM sys_model_location_info order by location_no"); + + dbifs->execute(sqlQuery, query); + + while(query.next()) + { + int locationId = query.value(0).toInt(); + QString locationDesc = query.value(1).toString(); + + ui->locationCkb->addItem(locationDesc,QVariant(locationId)); + } +} + +void CFaultRecallRecordWidget::initDateTimeEdit() +{ + QDateTime now = QDateTime::currentDateTime(); + QDateTime startTime = now.addDays(-1); + QDateTime endTime = now.addDays(1); + ui->startTimeEdit->setDateTime(startTime); + ui->endTimeEdit->setDateTime(endTime); +} + +QString CFaultRecallRecordWidget::getLocationDesc(int locationId) +{ + int index = ui->locationCkb->findData(locationId); + if(index >= 0) + { + return ui->locationCkb->itemText(index); + } + + return QString::number(locationId); +} + + + +void CFaultRecallRecordWidget::slotShowMess(const QString &mess) +{ + QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); +} + +void CFaultRecallRecordWidget::slotPlayBtn() +{ + // 暂时不判断判断用户权限,没有单独的模拟操作权限 +// if ( checkUserPerm() == false ) +// { +// QMessageBox::critical( 0, "错误", "用户权限验证失败" ); +// return; +// } + QString fileStr; + QString descStr; + QList list = ui->m_treeWidget->selectedItems(); + if(list.count() < 1) + { + slotShowMess(tr("请选择一项记录!")); + return; + } + QTreeWidgetItem* item = list.at(0); + fileStr = item->text(4); + descStr = item->text(0); + + qint64 startTime = item->data(2,Qt::UserRole+1).toLongLong(); + qint64 endTime = item->data(3,Qt::UserRole+1).toLongLong(); + + + QString msgStr = QString(tr("确定开始播放“%1”?").arg(descStr)); + int ret = QMessageBox::question(this, tr("提示"),msgStr); + if(ret == QMessageBox::Yes) + { + emit sigPlay(fileStr,startTime,endTime); + } + +} + +void CFaultRecallRecordWidget::slotDelBtn() +{ + + QList list = ui->m_treeWidget->selectedItems(); + if(list.count() < 1) + { + slotShowMess(tr("请选择删除项!")); + return; + } + + + + QTreeWidgetItem* item = list.at(0); + + int locationId = item->data(1,Qt::UserRole+1).toInt(); + QString name = item->text(0); + qint64 startTime = item->data(2,Qt::UserRole+1).toLongLong(); + qint64 endTime = item->data(3,Qt::UserRole+1).toLongLong(); + + + QString msgStr = QString(tr("确定删除记录“%1”?").arg(name)); + int ret = QMessageBox::question(this, tr("提示"),msgStr); + if(ret != QMessageBox::Yes) + { + return; + } + + kbd_dbms::CDbApi * pWriteDb = new CDbApi(DB_CONN_MODEL_WRITE); + if(! pWriteDb->open()) + { + slotShowMess(tr("打开数据库失败。")); + return; + } + + QList listCondition; + CDbCondition cd1; + cd1.m_sColName = "LOCATION_ID"; + cd1.m_eLogic = CDbCondition::LOGIC_AND; + cd1.m_eCompare = CDbCondition::COMPARE_EQ; + cd1.m_value = locationId; + listCondition.push_back(cd1); + + CDbCondition cd2; + cd2.m_sColName = "NAME"; + cd2.m_eLogic = CDbCondition::LOGIC_AND; + cd2.m_eCompare = CDbCondition::COMPARE_EQ; + cd2.m_value = name; + listCondition.push_back(cd2); + + CDbCondition cd3; + cd3.m_sColName = "TIME_BEGING"; + cd3.m_eLogic = CDbCondition::LOGIC_AND; + cd3.m_eCompare = CDbCondition::COMPARE_EQ; + cd3.m_value = startTime; + listCondition.push_back(cd3); + + CDbCondition cd4; + cd4.m_sColName = "TIME_END"; + cd4.m_eLogic = CDbCondition::LOGIC_AND; + cd4.m_eCompare = CDbCondition::COMPARE_EQ; + cd4.m_value = endTime; + listCondition.push_back(cd4); + + + ret = pWriteDb->deleteRow("fault_recall_record", listCondition); + + + pWriteDb->close(); + delete pWriteDb; + pWriteDb = NULL; + + if(ret) + { + delete item; + item = NULL; + slotRefreshBtn(); + } + else + { + slotShowMess(tr("删除“%1”失败!").arg(name)); + } +} + +void CFaultRecallRecordWidget::slotClearBtn() +{ + QString msgStr = QString(tr("确定清空所有记录?")); + int ret = QMessageBox::question(this, tr("提示"),msgStr); + if(ret != QMessageBox::Yes) + { + return; + } + + kbd_dbms::CDbApi * pWriteDb = new CDbApi(DB_CONN_MODEL_WRITE); + if(! pWriteDb->open()) + { + slotShowMess(tr("打开数据库失败。")); + return; + } + + ret = pWriteDb->deleteRow("fault_recall_record"); + + + pWriteDb->close(); + delete pWriteDb; + pWriteDb = NULL; + + if(ret) + { + ui->m_treeWidget->clear(); + slotRefreshBtn(); + } + else + { + slotShowMess(tr("清空失败!")); + } +} + +void CFaultRecallRecordWidget::slotRefreshBtn() +{ + kbd_dbms::CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(! pReadDb->open()) + { + delete pReadDb; + pReadDb = NULL; + slotShowMess(tr("打开数据库失败。")); + return; + } + + refeshTree(pReadDb); + + pReadDb->close(); + delete pReadDb; + pReadDb = NULL; + +} + +void CFaultRecallRecordWidget::slot_updateTable() +{ + ui->m_treeWidget->clear(); + int filterLocation = ui->locationCkb->currentData().toInt(); + qint64 filterStartTime = ui->startTimeEdit->dateTime().toMSecsSinceEpoch(); + qint64 filterEndTime = ui->endTimeEdit->dateTime().toMSecsSinceEpoch(); + + QVector::iterator iter = mItemDataVec.begin(); + for(; iter!=mItemDataVec.end(); ++iter) + { + SItemData& itemData = *iter; + + if(filterLocation != -1 && filterLocation != itemData.locationId) + { + continue; + } + + if(filterStartTime > itemData.startTime) + { + continue; + } + + if(filterEndTime < itemData.endTime) + { + continue; + } + + QTreeWidgetItem* item = new QTreeWidgetItem(ui->m_treeWidget); + + item->setText(0,itemData.name); + + item->setText(1,getLocationDesc(itemData.locationId)); + item->setData(1,Qt::UserRole+1,itemData.locationId); + item->setData(1,Qt::UserRole+2,itemData.subSystem); + + + item->setText(2,QDateTime::fromMSecsSinceEpoch(itemData.startTime).toString("yyyy-MM-dd hh:mm:ss")); + item->setData(2,Qt::UserRole+1,itemData.startTime); + + item->setText(3,QDateTime::fromMSecsSinceEpoch(itemData.endTime).toString("yyyy-MM-dd hh:mm:ss")); + item->setData(3,Qt::UserRole+1,itemData.endTime); + + item->setText(4,itemData.pic); + + item->setTextAlignment(0,Qt::AlignCenter); + item->setTextAlignment(1,Qt::AlignCenter); + item->setTextAlignment(2,Qt::AlignCenter); + item->setTextAlignment(3,Qt::AlignCenter); + item->setTextAlignment(4,Qt::AlignCenter); + } +} + +QString CFaultRecallRecordWidget::curPic() +{ + QList list = ui->m_treeWidget->selectedItems(); + if(list.count() < 1) + { + return ""; + } + QTreeWidgetItem* item = list.at(0); + + QString pic = item->text(4); + return pic; +} + +qint64 CFaultRecallRecordWidget::curStartTime() +{ + QList list = ui->m_treeWidget->selectedItems(); + if(list.count() < 1) + { + return 0; + } + QTreeWidgetItem* item = list.at(0); + + qint64 startTime = item->data(2,Qt::UserRole+1).toLongLong(); + return startTime; +} + +qint64 CFaultRecallRecordWidget::curEndTime() +{ + QList list = ui->m_treeWidget->selectedItems(); + if(list.count() < 1) + { + return 0; + } + QTreeWidgetItem* item = list.at(0); + + qint64 endTime = item->data(3,Qt::UserRole+1).toLongLong(); + return endTime; +} + +QString CFaultRecallRecordWidget::curName() +{ + QList list = ui->m_treeWidget->selectedItems(); + if(list.count() < 1) + { + return ""; + } + QTreeWidgetItem* item = list.at(0); + + QString name = item->text(1); + return name; +} + +void CFaultRecallRecordWidget::setRecordStatus(int status) +{ + bool isEnabled = status != 1; + this->setEnabled(isEnabled); +} + +void CFaultRecallRecordWidget::slotItemDoubleClicked(QTreeWidgetItem *item, int cl) +{ + slotPlayBtn(); +} + +void CFaultRecallRecordWidget::setColumnHidden(int column, bool hide) +{ + ui->m_treeWidget->setColumnHidden(column,hide); +} + +void CFaultRecallRecordWidget::setColumnWidth(int column, int width) +{ + ui->m_treeWidget->setColumnWidth(column,width); +} + + diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.h b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.h index 8da78b30..31d19995 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.h +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.h @@ -1,80 +1,80 @@ -#ifndef CFAULTRECALLRECORDWIDGET_H -#define CFAULTRECALLRECORDWIDGET_H - -#include -#include -#include -#include "CFaultRecallRecordCommon.h" -#include - -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" -#include -#include "dbms/db_api_ex/CDbApi.h" - -QT_BEGIN_NAMESPACE -namespace Ui { class CFaultRecallRecordWidget; } -QT_END_NAMESPACE - -struct SItemData -{ - int locationId; - int subSystem; - QString name; - qint64 startTime; - qint64 endTime; - QString pic; -}; - -class CFaultRecallRecordWidget : public QWidget -{ - Q_OBJECT - -public: - CFaultRecallRecordWidget(bool editMode,QWidget *parent = nullptr); - ~CFaultRecallRecordWidget(); - -private: - void initStyleSheet(); - void initView(); - void refeshTree(kbd_dbms::CDbApi* dbifs); - bool checkUserPerm(); - - bool initViewData(); - void readLocationArray( kbd_dbms::CDbApi* dbifs); - void initDateTimeEdit(); - - QString getLocationDesc(int locationId); - -public slots: - void slotShowMess(const QString &mess); - - void slotPlayBtn(); - void slotDelBtn(); - void slotClearBtn(); - void slotRefreshBtn(); - void slot_updateTable(); - QString curPic(); - qint64 curStartTime(); - qint64 curEndTime(); - QString curName(); - void setRecordStatus(int status); - - void slotItemDoubleClicked(QTreeWidgetItem *item, int cl); - - void setColumnHidden(int column,bool hide); - void setColumnWidth(int column,int width); - -signals: - void sigPlay(const QString& file,qint64 startTime, qint64 endTime); - -private: - Ui::CFaultRecallRecordWidget *ui; - - bool m_editMode; - - QVector mItemDataVec; - - -}; -#endif // CFAULTRECALLRECORDWIDGET_H +#ifndef CFAULTRECALLRECORDWIDGET_H +#define CFAULTRECALLRECORDWIDGET_H + +#include +#include +#include +#include "CFaultRecallRecordCommon.h" +#include + +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include +#include "dbms/db_api_ex/CDbApi.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class CFaultRecallRecordWidget; } +QT_END_NAMESPACE + +struct SItemData +{ + int locationId; + int subSystem; + QString name; + qint64 startTime; + qint64 endTime; + QString pic; +}; + +class CFaultRecallRecordWidget : public QWidget +{ + Q_OBJECT + +public: + CFaultRecallRecordWidget(bool editMode,QWidget *parent = nullptr); + ~CFaultRecallRecordWidget(); + +private: + void initStyleSheet(); + void initView(); + void refeshTree(kbd_dbms::CDbApi* dbifs); + bool checkUserPerm(); + + bool initViewData(); + void readLocationArray( kbd_dbms::CDbApi* dbifs); + void initDateTimeEdit(); + + QString getLocationDesc(int locationId); + +public slots: + void slotShowMess(const QString &mess); + + void slotPlayBtn(); + void slotDelBtn(); + void slotClearBtn(); + void slotRefreshBtn(); + void slot_updateTable(); + QString curPic(); + qint64 curStartTime(); + qint64 curEndTime(); + QString curName(); + void setRecordStatus(int status); + + void slotItemDoubleClicked(QTreeWidgetItem *item, int cl); + + void setColumnHidden(int column,bool hide); + void setColumnWidth(int column,int width); + +signals: + void sigPlay(const QString& file,qint64 startTime, qint64 endTime); + +private: + Ui::CFaultRecallRecordWidget *ui; + + bool m_editMode; + + QVector mItemDataVec; + + +}; +#endif // CFAULTRECALLRECORDWIDGET_H diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.ui b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.ui index af071b9f..ad318896 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.ui +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.ui @@ -1,190 +1,190 @@ - - - CFaultRecallRecordWidget - - - - 0 - 0 - 800 - 600 - - - - CFaultRecallRecordWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 位置 - - - - - - - - - - 开始时间 - - - - - - - - - - 结束时间 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - - 名称 - - - AlignCenter - - - - - 位置 - - - AlignCenter - - - - - 开始时间 - - - AlignCenter - - - - - 结束时间 - - - AlignCenter - - - - - 画面 - - - AlignCenter - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 刷新 - - - - - - - 清空 - - - - - - - 删除 - - - - - - - 播放 - - - - - - - - - - - - - + + + CFaultRecallRecordWidget + + + + 0 + 0 + 800 + 600 + + + + CFaultRecallRecordWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 位置 + + + + + + + + + + 开始时间 + + + + + + + + + + 结束时间 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + 名称 + + + AlignCenter + + + + + 位置 + + + AlignCenter + + + + + 开始时间 + + + AlignCenter + + + + + 结束时间 + + + AlignCenter + + + + + 画面 + + + AlignCenter + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 刷新 + + + + + + + 清空 + + + + + + + 删除 + + + + + + + 播放 + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/FaultRecallRecordWidget.pro b/product/src/gui/plugin/FaultRecallRecordWidget/FaultRecallRecordWidget.pro index 5fcff7cc..3175dd6f 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/FaultRecallRecordWidget.pro +++ b/product/src/gui/plugin/FaultRecallRecordWidget/FaultRecallRecordWidget.pro @@ -1,51 +1,51 @@ -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib - -TARGET = FaultRecallRecordWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any Qt feature that has been marked deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if it uses deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - CFaultRecallRecordPluginWidget.cpp \ -# main.cpp \ - CFaultRecallRecordWidget.cpp - -HEADERS += \ - CFaultRecallRecordCommon.h \ - CFaultRecallRecordPluginWidget.h \ - CFaultRecallRecordWidget.h - -FORMS += \ - CFaultRecallRecordWidget.ui - -LIBS += \ - -llog4cplus \ - -ldb_base_api \ - -ldb_api_ex \ - -lpub_logger_api \ - -lpub_utility_api \ - -lperm_mng_api \ - -lsys_login_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib + +TARGET = FaultRecallRecordWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + CFaultRecallRecordPluginWidget.cpp \ +# main.cpp \ + CFaultRecallRecordWidget.cpp + +HEADERS += \ + CFaultRecallRecordCommon.h \ + CFaultRecallRecordPluginWidget.h \ + CFaultRecallRecordWidget.h + +FORMS += \ + CFaultRecallRecordWidget.ui + +LIBS += \ + -llog4cplus \ + -ldb_base_api \ + -ldb_api_ex \ + -lpub_logger_api \ + -lpub_utility_api \ + -lperm_mng_api \ + -lsys_login_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/main.cpp b/product/src/gui/plugin/FaultRecallRecordWidget/main.cpp index 6fb06be2..b3f7cff6 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/main.cpp +++ b/product/src/gui/plugin/FaultRecallRecordWidget/main.cpp @@ -1,36 +1,36 @@ - -#include - -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "CFaultRecallRecordWidget.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); -// kbd_public::StartLogSystem("HMI", "hmi"); -// if (!(kbd_net::initMsgBus("HMI", "HMI"))) -// { -// return -1; -// } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - { - CFaultRecallRecordWidget w(false,NULL); - w.show(); - a.exec(); - } - //<释放消息总线 -// kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} + +#include + +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "CFaultRecallRecordWidget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); +// kbd_public::StartLogSystem("HMI", "hmi"); +// if (!(kbd_net::initMsgBus("HMI", "HMI"))) +// { +// return -1; +// } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + { + CFaultRecallRecordWidget w(false,NULL); + w.show(); + a.exec(); + } + //<释放消息总线 +// kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordModel.cpp b/product/src/gui/plugin/FaultRecordWidget/FaultRecordModel.cpp index eb2507a9..b2dfded0 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordModel.cpp +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordModel.cpp @@ -1,73 +1,73 @@ -#include "FaultRecordModel.h" -#include -FaultRecordModel::FaultRecordModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header <time).toString("yyyy-MM-dd hh:mm:ss"); - case 1: - return m_data.at(index.row())->locationName; - case 2: - return m_data.at(index.row())->devName; - case 3: - return m_data.at(index.row())->fileName; - default: - break; - } - } - return QVariant(); -} - -void FaultRecordModel::setDataPtr(QList listPtr) -{ - beginResetModel(); - m_data = listPtr; - endResetModel(); -} +#include "FaultRecordModel.h" +#include +FaultRecordModel::FaultRecordModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header <time).toString("yyyy-MM-dd hh:mm:ss"); + case 1: + return m_data.at(index.row())->locationName; + case 2: + return m_data.at(index.row())->devName; + case 3: + return m_data.at(index.row())->fileName; + default: + break; + } + } + return QVariant(); +} + +void FaultRecordModel::setDataPtr(QList listPtr) +{ + beginResetModel(); + m_data = listPtr; + endResetModel(); +} diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordModel.h b/product/src/gui/plugin/FaultRecordWidget/FaultRecordModel.h index be8a7881..84b12cf6 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordModel.h +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordModel.h @@ -1,27 +1,27 @@ -#ifndef FAULTRECORDMODEL_H -#define FAULTRECORDMODEL_H - -#include -#include -class FaultRecordModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit FaultRecordModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - void setDataPtr(QList listPtr); -private: - QStringList m_header; - QList m_data; -}; - -#endif // FAULTRECORDMODEL_H +#ifndef FAULTRECORDMODEL_H +#define FAULTRECORDMODEL_H + +#include +#include +class FaultRecordModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit FaultRecordModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + void setDataPtr(QList listPtr); +private: + QStringList m_header; + QList m_data; +}; + +#endif // FAULTRECORDMODEL_H diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.cpp b/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.cpp index 6bc22913..de85bf83 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.cpp +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "FaultRecordPluginWidget.h" -#include "FaultRecordWidget.h" -#include -#include "StructDefine.h" -FaultRecordPluginWidget::FaultRecordPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -FaultRecordPluginWidget::~FaultRecordPluginWidget() -{ - -} - -bool FaultRecordPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec) -{ - FaultRecordWidget *pWidget = new FaultRecordWidget(editMode,parent); - pWidget->initialize((int)E_Fault_Window); - *widget = (QWidget *)pWidget; - *pluginWidget = (IPluginWidget *)pWidget; - return true; -} - -void FaultRecordPluginWidget::release() -{ - -} +#include "FaultRecordPluginWidget.h" +#include "FaultRecordWidget.h" +#include +#include "StructDefine.h" +FaultRecordPluginWidget::FaultRecordPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +FaultRecordPluginWidget::~FaultRecordPluginWidget() +{ + +} + +bool FaultRecordPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec) +{ + FaultRecordWidget *pWidget = new FaultRecordWidget(editMode,parent); + pWidget->initialize((int)E_Fault_Window); + *widget = (QWidget *)pWidget; + *pluginWidget = (IPluginWidget *)pWidget; + return true; +} + +void FaultRecordPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.h b/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.h index d790a295..72a6ef98 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.h +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef FAULTRECORDPLUGINWIDGET_H -#define FAULTRECORDPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class FaultRecordPluginWidget : public QObject , public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - FaultRecordPluginWidget(QObject *parent = nullptr); - ~FaultRecordPluginWidget(); - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec); - void release(); -signals: - -public slots: -}; - -#endif // FAULTRECORDPLUGINWIDGET_H +#ifndef FAULTRECORDPLUGINWIDGET_H +#define FAULTRECORDPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class FaultRecordPluginWidget : public QObject , public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + FaultRecordPluginWidget(QObject *parent = nullptr); + ~FaultRecordPluginWidget(); + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec); + void release(); +signals: + +public slots: +}; + +#endif // FAULTRECORDPLUGINWIDGET_H diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.cpp b/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.cpp index 411137be..2d045b97 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.cpp +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.cpp @@ -1,708 +1,708 @@ -#include "FaultRecordWidget.h" -#include "ui_FaultRecordWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/FileStyle.h" -#include "db_api_ex/CDbApi.h" - - -using namespace kbd_dbms; -bool timeCompare(const SFaultRecordInfoPtr p1, const SFaultRecordInfoPtr p2) -{ - return p1->time > p2->time; -} - -FaultRecordWidget::FaultRecordWidget(bool editMode, QWidget *parent) : - QWidget(parent), - m_path(QString()), - m_mode(E_Fault_Window), - m_edit(editMode), - m_deleteOptPerm(false), - ui(new Ui::FaultRecordWidget) -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("faultRecord.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - ui->setupUi(this); - QDir dir(QCoreApplication::applicationDirPath()); - dir.cd("../../data/rec"); - m_path = dir.path(); - loadConfig(); - initUi(); - if(!m_edit) - { - connect(ui->brush,&QPushButton::clicked,this,&FaultRecordWidget::brush); - connect(ui->allClear,&QPushButton::clicked,this,&FaultRecordWidget::allClear); - connect(ui->clear,&QPushButton::clicked,this,&FaultRecordWidget::clear); - connect(ui->open,&QPushButton::clicked,this,&FaultRecordWidget::open); - connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&FaultRecordWidget::treeItemClicked); - } -} - -FaultRecordWidget::~FaultRecordWidget() -{ - cleanTreeWidget(); - m_locDescList.clear(); - m_devDescList.clear(); - delete ui; -} - -void FaultRecordWidget::initialize(int mode) -{ - m_location.clear(); - m_devList.clear(); - - if((E_Fault_Mode)mode == E_Fault_Window) - { - //ui->widget->heightForWidth(60); - }else - { - //ui->widget->heightForWidth(20); - ui->tableView->setColumnHidden(1,true); - ui->tableView->setColumnHidden(2,true); - ui->allClear->setHidden(true); - ui->clear->setHidden(true); - //ui->title->setHidden(true); - ui->widget_5->setHidden(true); - } -} - -void FaultRecordWidget::setLocationAndDev(QString location, QStringList devList) -{ - m_location = location; - m_devList =devList; - if(m_devList.isEmpty()) - { - m_devList = m_locDevMap.value(m_location,m_devList); - } - brush(); -} - -void FaultRecordWidget::setColumnWidth(const int &column, const int &width) -{ - ui->tableView->setColumnWidth(column,width); -} - -void FaultRecordWidget::setColumnVisible(const int &column, const bool &visible) -{ - ui->tableView->setColumnHidden(column,!visible); -} - -void FaultRecordWidget::treeItemClicked(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - if(item == Q_NULLPTR) - { - return ; - } - if(item->data(0,Qt::UserRole).toInt() == EN_TREE_ITEM_LOC) - { - QString loc = item->text(0); - if(loc.isEmpty()) - { - return ; - } - m_location = loc; - m_devList.clear(); - m_devList = m_locDevMap.value(m_location,m_devList); - }else - { - QString loc = item->data(0,Qt::UserRole+1).toString(); - QString dev = item->text(0); - if(loc.isEmpty()) - { - return ; - } - m_location = loc; - m_devList.clear(); - m_devList.append(dev); - } - - brush(); -} - -void FaultRecordWidget::initUi() -{ - ui->splitter->setSizes(QList()<<220<<1200); - initTreeWidget(); - - initTimeUi(); - initModelUi(); - - connect(ui->startTime,&QDateEdit::dateTimeChanged,this,&FaultRecordWidget::brushByTime); - connect(ui->endTime,&QDateEdit::dateTimeChanged,this,&FaultRecordWidget::brushByTime); -} - -void FaultRecordWidget::loadConfig() -{ - loadLocationDesc(); - loadDevDesc(); - loadLocation(); - loadDev(); -} - -void FaultRecordWidget::loadLocationDesc() -{ - m_locDescList.clear(); - CDbApi *readApi = new CDbApi(DB_CONN_MODEL_READ); - if(readApi != Q_NULLPTR && readApi->open()) - { - QString sql = QString("select description from %1 order by location_no").arg("sys_model_location_info"); - QSqlQuery objQuery; - if(readApi->execute(sql,objQuery)) - { - while (objQuery.next()) { - QString name = objQuery.value(0).toString().trimmed(); - m_locDescList.append(name); - } - } - }else - { - LOGERROR("查询车站描述失败"); - } - if(readApi != Q_NULLPTR) - { - delete readApi; - } - readApi =Q_NULLPTR; - -} - -void FaultRecordWidget::loadDevDesc() -{ - m_devDescList.clear(); - CDbApi *readApi = new CDbApi(DB_CONN_MODEL_READ); - if(readApi != Q_NULLPTR && readApi->open()) - { - QString sql = QString("select dev_desc from %1").arg("fes_dev_info"); - QSqlQuery objQuery; - if(readApi->execute(sql,objQuery)) - { - while (objQuery.next()) { - - QString name = objQuery.value(0).toString().trimmed(); - m_devDescList.append(name); - } - } - }else - { - LOGERROR("查询前置设备描述失败"); - } - if(readApi != Q_NULLPTR) - { - delete readApi; - } - readApi =Q_NULLPTR; -} - -void FaultRecordWidget::loadLocation() -{ - m_locationList.clear(); - QDir dir(m_path); - QFileInfoList folder_list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - - for(int i = 0; i != folder_list.size(); i++) - { - if(m_locDescList.contains(folder_list.at(i).baseName())) - { - m_locationList.append(folder_list.at(i).baseName()); - } - } -} - -void FaultRecordWidget::loadDev() -{ - m_locDevMap.clear(); - for(int index(0);index >::iterator it = m_locDevMap.find(m_locationList.at(index)); - if(it == m_locDevMap.end()) - { - QList devList; - devList.append(folder_list.at(i).baseName()); - m_locDevMap[m_locationList.at(index)] = devList; - }else - { - QList &devList = it.value(); - devList.append(folder_list.at(i).baseName()); - } - } - } -} - -void FaultRecordWidget::initTreeWidget() -{ - cleanTreeWidget(); - ui->treeWidget->setColumnCount(1); - for(int index(0);indexsetText(0,m_locationList.at(index)); - item->setData(0,Qt::UserRole,(int)EN_TREE_ITEM_LOC); - item->setData(0,Qt::UserRole+1,QString()); - - ui->treeWidget->addTopLevelItem(item); - item->setExpanded(true); - QMap >::iterator it =m_locDevMap.find(m_locationList.at(index)); - if(it != m_locDevMap.end()) - { - QList &devList = it.value(); - for(int devIndex(0);devIndexsetText(0,devList.at(devIndex)); - devitem->setData(0,Qt::UserRole,(int)EN_TREE_ITEM_DEV); - devitem->setData(0,Qt::UserRole+1,m_locationList.at(index)); - item->addChild(devitem); - } - } - } -} - -void FaultRecordWidget::cleanTreeWidget() -{ - for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) - { - QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); - for(int devIndex(item->childCount()-1);devIndex >= 0; devIndex--) - { - QTreeWidgetItem *devitem = item->child(devIndex); - item->removeChild(devitem); - delete devitem; - devitem = Q_NULLPTR; - } - ui->treeWidget->removeItemWidget(item,0); - delete item; - item = Q_NULLPTR; - } -} - -void FaultRecordWidget::initTimeUi() -{ -// ui->startTime->setCalendarPopup(true); -// ui->endTime->setCalendarPopup(true); - ui->startTime->setDisplayFormat("yyyy/MM/dd"); - ui->endTime->setDisplayFormat("yyyy/MM/dd"); - ui->endTime->setDate(QDate::currentDate()); - ui->startTime->setDate(QDate::currentDate().addDays(-7)); -} - -void FaultRecordWidget::initModelUi() -{ - m_model = new FaultRecordModel; - ui->tableView->setModel(m_model); - ui->tableView->setAlternatingRowColors(true); - ui->tableView->horizontalHeader()->setStretchLastSection(true); - ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - ui->tableView->verticalHeader()->setMaximumSectionSize(30); - ui->tableView->verticalHeader()->setMinimumSectionSize(30); - connect(ui->tableView,&QTableView::doubleClicked,this,&FaultRecordWidget::open); - ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); - ui->tableView->setColumnWidth(0,200); - ui->tableView->setColumnWidth(1,200); - ui->tableView->setColumnWidth(2,200); -} - -void FaultRecordWidget::updateDeleteOperatePerm() -{ - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - m_nodeName = stNodeInfo.strName; - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(PERM_NORMAL != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - m_userId = -1; - LOGERROR("用户ID获取失败!"); - return; - } - std::string str = "FUNC_NOM_FAULTRECORD_DEL"; - if(PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF,&str)) - { - m_deleteOptPerm = false; - LOGERROR("无故障录波删除权限!"); - }else - { - m_deleteOptPerm = true; - } - } -} - -void FaultRecordWidget::brush() -{ - m_dataList.clear(); - m_model->setDataPtr(m_dataList); - if(check() && collectData()) - { - qSort(m_dataList.begin(),m_dataList.end(),timeCompare); - m_model->setDataPtr(m_dataList); - } -} - -void FaultRecordWidget::brushByTime(const QDateTime &dateTime) -{ - Q_UNUSED(dateTime); - m_dataList.clear(); - m_model->setDataPtr(m_dataList); - if(check() && collectData()) - { - qSort(m_dataList.begin(),m_dataList.end(),timeCompare); - m_model->setDataPtr(m_dataList); - } -} - -void FaultRecordWidget::allClear() -{ - updateDeleteOperatePerm(); - if(m_deleteOptPerm == false) - { - QMessageBox::critical( 0, tr("提示"), tr("当前用户不具有删除权限") ); - return ; - } - if(m_dataList.size() <= 0) - { - return ; - } - for(int index(0);indexfilePath; - deleteData(name); - } - brush(); -} - -void FaultRecordWidget::clear() -{ - updateDeleteOperatePerm(); - if(m_deleteOptPerm == false) - { - QMessageBox::critical( 0, tr("提示"), tr("当前用户不具有删除权限") ); - return ; - } - int nRow = ui->tableView->currentIndex().row(); - if ( nRow < 0 || nRow >= m_dataList.count() ) - { - QMessageBox::critical( 0, tr("提示"), tr("当前未选中任何项") ); - return; - } - QString name = m_dataList.at(nRow)->filePath; - deleteData(name); - brush(); -} - -void FaultRecordWidget::open() -{ - int nRow = ui->tableView->currentIndex().row(); - if ( nRow < 0 || nRow >= m_dataList.count() ) - { - QMessageBox::critical( 0, tr("提示"), tr("当前未选中任何项") ); - return; - } - QString path = m_dataList.at(nRow)->filePath; - path = QString("%1%2%3").arg("\"").arg(path).arg("\""); - LOGINFO("录波文件为:%s",path.toStdString().c_str()); - - const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( - std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); - if(strProc.empty()) - LOGERROR("未找到可执行文件WaveAnalyze"); - else - QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(path)); -} - -bool FaultRecordWidget::check() -{ - QDate startDate = ui->startTime->date(); - QDate endDate = ui->endTime->date(); - QTime time_1(0,0,0); - QTime time_2(23,59,59); - m_startTime.setDate(startDate); - m_startTime.setTime(time_1); - m_endTime.setDate(endDate); - m_endTime.setTime(time_2); - if(m_location.isEmpty()) - { - return false; - } - if(m_devList.isEmpty()) - { - return false; - } - if(m_startTime.toSecsSinceEpoch() >m_endTime.toSecsSinceEpoch()) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - QString text = tr("开始时间不能大于结束时间!"); - msgBox->setWindowTitle(tr("提示")); - msgBox->setText(text); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return false; - } - return true; -} - -bool FaultRecordWidget::collectData() -{ - QDir dir(m_path); - dir.cd(m_location); - if(!dir.exists()) - { - QMessageBox::warning(this, tr("提示"), tr("不存在%1位置!").arg(m_location), QMessageBox::Ok); - return false; - } - - for(int index(0);index time || time > m_endTime.toSecsSinceEpoch() ) - { - continue; - } - SFaultRecordInfoPtr infoPtr(new SFaultRecordInfo()); - infoPtr->devName = dev; - infoPtr->locationName = location; - infoPtr->fileName = fileName; - infoPtr->filePath = file_list.at(i).absoluteFilePath(); - infoPtr->time = time; - m_dataList.append(infoPtr); - LOGDEBUG("makeData()end:"); - } -} - -bool FaultRecordWidget::makeTime(QString &file, qint64 &time) -{ - QStringList fileList = file.split(","); - if(fileList.size() != 2) - { - return false; - } - QString fileFirst = fileList.at(0); - QStringList ymdList = fileFirst.split("/"); - if(ymdList.size() != 3) - { - return false; - } - QString year = ymdList.at(2); - QString mouth = ymdList.at(1); - QString day = ymdList.at(0); - - QString fileSecond = fileList.at(1); - QStringList hmszList = fileSecond.split("."); - if(hmszList.size() != 2) - { - return false; - } - QString fileThird = hmszList.at(0); - - QStringList hmsList = fileThird.split(":"); - if(hmsList.size() != 3) - { - return false; - } - QString hour = hmsList.at(0); - QString min = hmsList.at(1); - QString sec = hmsList.at(2); - - QString timeDate = QString(); - timeDate += year; - timeDate += "-"; - timeDate += mouth; - timeDate += "-"; - timeDate += day; - timeDate += " "; - timeDate += hour; - timeDate += ":"; - timeDate += min; - timeDate += ":"; - timeDate += sec; - QDateTime dateTime; - time = dateTime.fromString(timeDate,"yyyy-MM-dd hh:mm:ss").toSecsSinceEpoch(); - return true; -} - -bool FaultRecordWidget::getTime(QString file, qint64 &time) -{ - QFile fl(file); - QString str; - QByteArray array; - if(fl.exists()) - { - if(fl.open(QFile::ReadOnly | QFile::Text)) - { - int i = 0; - int j = 0; - int k = 0; - while (!fl.atEnd()) { - array = fl.readLine(); - i++; - if(i == 2) - { - QString row=QString::fromStdString(array.toStdString()).split(",").at(0); - j = row.toInt(); - - j += 4; - } - if(j != 0 && i== j ) - { - QString row = QString::fromStdString(array.toStdString()); - k = row.toInt(); - if(k == 0)//特殊处理为0的情况 - { - k=1; - } - k += i; - k += 1; - } - if(k != 0 && k == i) - { - str = QString::fromStdString(array.toStdString()); - break; - } - } - if(i == k) - { - return makeTime(str,time); - } - } - } - return false; -} - -void FaultRecordWidget::deleteData(QString file) -{ - QString suf = file.section(".", -1); - file.remove(file.length()-4,4); - bool isUpper = false; - if(suf.compare(SUFFIXCFG, Qt::CaseSensitive) != 0) - { - isUpper = true; - } - - QString cfg = isUpper ? file + "." + SUFFIXCFG.toUpper() : file + "." + SUFFIXCFG; - QString cfgPath = cfg; - QString xdCfg = QString("../../data/rec%1").arg(cfg.remove(0,m_path.size())); - LOGINFO("删除文件:[%s]",cfgPath.toStdString().c_str()); - LOGINFO("删除文件:[%s]",xdCfg.toStdString().c_str()); - QFile cfgTemp(cfgPath); - cfgTemp.remove(); - m_fileApi.commitLocalFileDel(xdCfg.toStdString()); - - QString cnf = isUpper ? file + "." + SUFFIXCNF.toUpper() : file + "." + SUFFIXCNF; - QString cnfPath = cnf; - QString xdCnf = QString("../../data/rec%1").arg(cnf.remove(0,m_path.size())); - LOGINFO("删除文件:[%s]",cnfPath.toStdString().c_str()); - LOGINFO("删除文件:[%s]",xdCnf.toStdString().c_str()); - QFile cnfTemp(cnfPath); - cnfTemp.remove(); - m_fileApi.commitLocalFileDel(xdCnf.toStdString()); - - QString dat = isUpper ? file + "." + SUFFIXDAT.toUpper() : file + "." + SUFFIXDAT; - QString datPath = dat; - QString xdDat = QString("../../data/rec%1").arg(dat.remove(0,m_path.size())); - LOGINFO("删除文件:[%s]",datPath.toStdString().c_str()); - LOGINFO("删除文件:[%s]",xdDat.toStdString().c_str()); - QFile datTemp(datPath); - datTemp.remove(); - m_fileApi.commitLocalFileDel(xdDat.toStdString()); -} - +#include "FaultRecordWidget.h" +#include "ui_FaultRecordWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include "db_api_ex/CDbApi.h" + + +using namespace kbd_dbms; +bool timeCompare(const SFaultRecordInfoPtr p1, const SFaultRecordInfoPtr p2) +{ + return p1->time > p2->time; +} + +FaultRecordWidget::FaultRecordWidget(bool editMode, QWidget *parent) : + QWidget(parent), + m_path(QString()), + m_mode(E_Fault_Window), + m_edit(editMode), + m_deleteOptPerm(false), + ui(new Ui::FaultRecordWidget) +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("faultRecord.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + ui->setupUi(this); + QDir dir(QCoreApplication::applicationDirPath()); + dir.cd("../../data/rec"); + m_path = dir.path(); + loadConfig(); + initUi(); + if(!m_edit) + { + connect(ui->brush,&QPushButton::clicked,this,&FaultRecordWidget::brush); + connect(ui->allClear,&QPushButton::clicked,this,&FaultRecordWidget::allClear); + connect(ui->clear,&QPushButton::clicked,this,&FaultRecordWidget::clear); + connect(ui->open,&QPushButton::clicked,this,&FaultRecordWidget::open); + connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&FaultRecordWidget::treeItemClicked); + } +} + +FaultRecordWidget::~FaultRecordWidget() +{ + cleanTreeWidget(); + m_locDescList.clear(); + m_devDescList.clear(); + delete ui; +} + +void FaultRecordWidget::initialize(int mode) +{ + m_location.clear(); + m_devList.clear(); + + if((E_Fault_Mode)mode == E_Fault_Window) + { + //ui->widget->heightForWidth(60); + }else + { + //ui->widget->heightForWidth(20); + ui->tableView->setColumnHidden(1,true); + ui->tableView->setColumnHidden(2,true); + ui->allClear->setHidden(true); + ui->clear->setHidden(true); + //ui->title->setHidden(true); + ui->widget_5->setHidden(true); + } +} + +void FaultRecordWidget::setLocationAndDev(QString location, QStringList devList) +{ + m_location = location; + m_devList =devList; + if(m_devList.isEmpty()) + { + m_devList = m_locDevMap.value(m_location,m_devList); + } + brush(); +} + +void FaultRecordWidget::setColumnWidth(const int &column, const int &width) +{ + ui->tableView->setColumnWidth(column,width); +} + +void FaultRecordWidget::setColumnVisible(const int &column, const bool &visible) +{ + ui->tableView->setColumnHidden(column,!visible); +} + +void FaultRecordWidget::treeItemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + if(item == Q_NULLPTR) + { + return ; + } + if(item->data(0,Qt::UserRole).toInt() == EN_TREE_ITEM_LOC) + { + QString loc = item->text(0); + if(loc.isEmpty()) + { + return ; + } + m_location = loc; + m_devList.clear(); + m_devList = m_locDevMap.value(m_location,m_devList); + }else + { + QString loc = item->data(0,Qt::UserRole+1).toString(); + QString dev = item->text(0); + if(loc.isEmpty()) + { + return ; + } + m_location = loc; + m_devList.clear(); + m_devList.append(dev); + } + + brush(); +} + +void FaultRecordWidget::initUi() +{ + ui->splitter->setSizes(QList()<<220<<1200); + initTreeWidget(); + + initTimeUi(); + initModelUi(); + + connect(ui->startTime,&QDateEdit::dateTimeChanged,this,&FaultRecordWidget::brushByTime); + connect(ui->endTime,&QDateEdit::dateTimeChanged,this,&FaultRecordWidget::brushByTime); +} + +void FaultRecordWidget::loadConfig() +{ + loadLocationDesc(); + loadDevDesc(); + loadLocation(); + loadDev(); +} + +void FaultRecordWidget::loadLocationDesc() +{ + m_locDescList.clear(); + CDbApi *readApi = new CDbApi(DB_CONN_MODEL_READ); + if(readApi != Q_NULLPTR && readApi->open()) + { + QString sql = QString("select description from %1 order by location_no").arg("sys_model_location_info"); + QSqlQuery objQuery; + if(readApi->execute(sql,objQuery)) + { + while (objQuery.next()) { + QString name = objQuery.value(0).toString().trimmed(); + m_locDescList.append(name); + } + } + }else + { + LOGERROR("查询车站描述失败"); + } + if(readApi != Q_NULLPTR) + { + delete readApi; + } + readApi =Q_NULLPTR; + +} + +void FaultRecordWidget::loadDevDesc() +{ + m_devDescList.clear(); + CDbApi *readApi = new CDbApi(DB_CONN_MODEL_READ); + if(readApi != Q_NULLPTR && readApi->open()) + { + QString sql = QString("select dev_desc from %1").arg("fes_dev_info"); + QSqlQuery objQuery; + if(readApi->execute(sql,objQuery)) + { + while (objQuery.next()) { + + QString name = objQuery.value(0).toString().trimmed(); + m_devDescList.append(name); + } + } + }else + { + LOGERROR("查询前置设备描述失败"); + } + if(readApi != Q_NULLPTR) + { + delete readApi; + } + readApi =Q_NULLPTR; +} + +void FaultRecordWidget::loadLocation() +{ + m_locationList.clear(); + QDir dir(m_path); + QFileInfoList folder_list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + + for(int i = 0; i != folder_list.size(); i++) + { + if(m_locDescList.contains(folder_list.at(i).baseName())) + { + m_locationList.append(folder_list.at(i).baseName()); + } + } +} + +void FaultRecordWidget::loadDev() +{ + m_locDevMap.clear(); + for(int index(0);index >::iterator it = m_locDevMap.find(m_locationList.at(index)); + if(it == m_locDevMap.end()) + { + QList devList; + devList.append(folder_list.at(i).baseName()); + m_locDevMap[m_locationList.at(index)] = devList; + }else + { + QList &devList = it.value(); + devList.append(folder_list.at(i).baseName()); + } + } + } +} + +void FaultRecordWidget::initTreeWidget() +{ + cleanTreeWidget(); + ui->treeWidget->setColumnCount(1); + for(int index(0);indexsetText(0,m_locationList.at(index)); + item->setData(0,Qt::UserRole,(int)EN_TREE_ITEM_LOC); + item->setData(0,Qt::UserRole+1,QString()); + + ui->treeWidget->addTopLevelItem(item); + item->setExpanded(true); + QMap >::iterator it =m_locDevMap.find(m_locationList.at(index)); + if(it != m_locDevMap.end()) + { + QList &devList = it.value(); + for(int devIndex(0);devIndexsetText(0,devList.at(devIndex)); + devitem->setData(0,Qt::UserRole,(int)EN_TREE_ITEM_DEV); + devitem->setData(0,Qt::UserRole+1,m_locationList.at(index)); + item->addChild(devitem); + } + } + } +} + +void FaultRecordWidget::cleanTreeWidget() +{ + for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) + { + QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); + for(int devIndex(item->childCount()-1);devIndex >= 0; devIndex--) + { + QTreeWidgetItem *devitem = item->child(devIndex); + item->removeChild(devitem); + delete devitem; + devitem = Q_NULLPTR; + } + ui->treeWidget->removeItemWidget(item,0); + delete item; + item = Q_NULLPTR; + } +} + +void FaultRecordWidget::initTimeUi() +{ +// ui->startTime->setCalendarPopup(true); +// ui->endTime->setCalendarPopup(true); + ui->startTime->setDisplayFormat("yyyy/MM/dd"); + ui->endTime->setDisplayFormat("yyyy/MM/dd"); + ui->endTime->setDate(QDate::currentDate()); + ui->startTime->setDate(QDate::currentDate().addDays(-7)); +} + +void FaultRecordWidget::initModelUi() +{ + m_model = new FaultRecordModel; + ui->tableView->setModel(m_model); + ui->tableView->setAlternatingRowColors(true); + ui->tableView->horizontalHeader()->setStretchLastSection(true); + ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + ui->tableView->verticalHeader()->setMaximumSectionSize(30); + ui->tableView->verticalHeader()->setMinimumSectionSize(30); + connect(ui->tableView,&QTableView::doubleClicked,this,&FaultRecordWidget::open); + ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); + ui->tableView->setColumnWidth(0,200); + ui->tableView->setColumnWidth(1,200); + ui->tableView->setColumnWidth(2,200); +} + +void FaultRecordWidget::updateDeleteOperatePerm() +{ + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + m_nodeName = stNodeInfo.strName; + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(PERM_NORMAL != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + m_userId = -1; + LOGERROR("用户ID获取失败!"); + return; + } + std::string str = "FUNC_NOM_FAULTRECORD_DEL"; + if(PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF,&str)) + { + m_deleteOptPerm = false; + LOGERROR("无故障录波删除权限!"); + }else + { + m_deleteOptPerm = true; + } + } +} + +void FaultRecordWidget::brush() +{ + m_dataList.clear(); + m_model->setDataPtr(m_dataList); + if(check() && collectData()) + { + qSort(m_dataList.begin(),m_dataList.end(),timeCompare); + m_model->setDataPtr(m_dataList); + } +} + +void FaultRecordWidget::brushByTime(const QDateTime &dateTime) +{ + Q_UNUSED(dateTime); + m_dataList.clear(); + m_model->setDataPtr(m_dataList); + if(check() && collectData()) + { + qSort(m_dataList.begin(),m_dataList.end(),timeCompare); + m_model->setDataPtr(m_dataList); + } +} + +void FaultRecordWidget::allClear() +{ + updateDeleteOperatePerm(); + if(m_deleteOptPerm == false) + { + QMessageBox::critical( 0, tr("提示"), tr("当前用户不具有删除权限") ); + return ; + } + if(m_dataList.size() <= 0) + { + return ; + } + for(int index(0);indexfilePath; + deleteData(name); + } + brush(); +} + +void FaultRecordWidget::clear() +{ + updateDeleteOperatePerm(); + if(m_deleteOptPerm == false) + { + QMessageBox::critical( 0, tr("提示"), tr("当前用户不具有删除权限") ); + return ; + } + int nRow = ui->tableView->currentIndex().row(); + if ( nRow < 0 || nRow >= m_dataList.count() ) + { + QMessageBox::critical( 0, tr("提示"), tr("当前未选中任何项") ); + return; + } + QString name = m_dataList.at(nRow)->filePath; + deleteData(name); + brush(); +} + +void FaultRecordWidget::open() +{ + int nRow = ui->tableView->currentIndex().row(); + if ( nRow < 0 || nRow >= m_dataList.count() ) + { + QMessageBox::critical( 0, tr("提示"), tr("当前未选中任何项") ); + return; + } + QString path = m_dataList.at(nRow)->filePath; + path = QString("%1%2%3").arg("\"").arg(path).arg("\""); + LOGINFO("录波文件为:%s",path.toStdString().c_str()); + + const std::string strProc = std::move(kbd_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + kbd_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(path)); +} + +bool FaultRecordWidget::check() +{ + QDate startDate = ui->startTime->date(); + QDate endDate = ui->endTime->date(); + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startDate); + m_startTime.setTime(time_1); + m_endTime.setDate(endDate); + m_endTime.setTime(time_2); + if(m_location.isEmpty()) + { + return false; + } + if(m_devList.isEmpty()) + { + return false; + } + if(m_startTime.toSecsSinceEpoch() >m_endTime.toSecsSinceEpoch()) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + QString text = tr("开始时间不能大于结束时间!"); + msgBox->setWindowTitle(tr("提示")); + msgBox->setText(text); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return false; + } + return true; +} + +bool FaultRecordWidget::collectData() +{ + QDir dir(m_path); + dir.cd(m_location); + if(!dir.exists()) + { + QMessageBox::warning(this, tr("提示"), tr("不存在%1位置!").arg(m_location), QMessageBox::Ok); + return false; + } + + for(int index(0);index time || time > m_endTime.toSecsSinceEpoch() ) + { + continue; + } + SFaultRecordInfoPtr infoPtr(new SFaultRecordInfo()); + infoPtr->devName = dev; + infoPtr->locationName = location; + infoPtr->fileName = fileName; + infoPtr->filePath = file_list.at(i).absoluteFilePath(); + infoPtr->time = time; + m_dataList.append(infoPtr); + LOGDEBUG("makeData()end:"); + } +} + +bool FaultRecordWidget::makeTime(QString &file, qint64 &time) +{ + QStringList fileList = file.split(","); + if(fileList.size() != 2) + { + return false; + } + QString fileFirst = fileList.at(0); + QStringList ymdList = fileFirst.split("/"); + if(ymdList.size() != 3) + { + return false; + } + QString year = ymdList.at(2); + QString mouth = ymdList.at(1); + QString day = ymdList.at(0); + + QString fileSecond = fileList.at(1); + QStringList hmszList = fileSecond.split("."); + if(hmszList.size() != 2) + { + return false; + } + QString fileThird = hmszList.at(0); + + QStringList hmsList = fileThird.split(":"); + if(hmsList.size() != 3) + { + return false; + } + QString hour = hmsList.at(0); + QString min = hmsList.at(1); + QString sec = hmsList.at(2); + + QString timeDate = QString(); + timeDate += year; + timeDate += "-"; + timeDate += mouth; + timeDate += "-"; + timeDate += day; + timeDate += " "; + timeDate += hour; + timeDate += ":"; + timeDate += min; + timeDate += ":"; + timeDate += sec; + QDateTime dateTime; + time = dateTime.fromString(timeDate,"yyyy-MM-dd hh:mm:ss").toSecsSinceEpoch(); + return true; +} + +bool FaultRecordWidget::getTime(QString file, qint64 &time) +{ + QFile fl(file); + QString str; + QByteArray array; + if(fl.exists()) + { + if(fl.open(QFile::ReadOnly | QFile::Text)) + { + int i = 0; + int j = 0; + int k = 0; + while (!fl.atEnd()) { + array = fl.readLine(); + i++; + if(i == 2) + { + QString row=QString::fromStdString(array.toStdString()).split(",").at(0); + j = row.toInt(); + + j += 4; + } + if(j != 0 && i== j ) + { + QString row = QString::fromStdString(array.toStdString()); + k = row.toInt(); + if(k == 0)//特殊处理为0的情况 + { + k=1; + } + k += i; + k += 1; + } + if(k != 0 && k == i) + { + str = QString::fromStdString(array.toStdString()); + break; + } + } + if(i == k) + { + return makeTime(str,time); + } + } + } + return false; +} + +void FaultRecordWidget::deleteData(QString file) +{ + QString suf = file.section(".", -1); + file.remove(file.length()-4,4); + bool isUpper = false; + if(suf.compare(SUFFIXCFG, Qt::CaseSensitive) != 0) + { + isUpper = true; + } + + QString cfg = isUpper ? file + "." + SUFFIXCFG.toUpper() : file + "." + SUFFIXCFG; + QString cfgPath = cfg; + QString xdCfg = QString("../../data/rec%1").arg(cfg.remove(0,m_path.size())); + LOGINFO("删除文件:[%s]",cfgPath.toStdString().c_str()); + LOGINFO("删除文件:[%s]",xdCfg.toStdString().c_str()); + QFile cfgTemp(cfgPath); + cfgTemp.remove(); + m_fileApi.commitLocalFileDel(xdCfg.toStdString()); + + QString cnf = isUpper ? file + "." + SUFFIXCNF.toUpper() : file + "." + SUFFIXCNF; + QString cnfPath = cnf; + QString xdCnf = QString("../../data/rec%1").arg(cnf.remove(0,m_path.size())); + LOGINFO("删除文件:[%s]",cnfPath.toStdString().c_str()); + LOGINFO("删除文件:[%s]",xdCnf.toStdString().c_str()); + QFile cnfTemp(cnfPath); + cnfTemp.remove(); + m_fileApi.commitLocalFileDel(xdCnf.toStdString()); + + QString dat = isUpper ? file + "." + SUFFIXDAT.toUpper() : file + "." + SUFFIXDAT; + QString datPath = dat; + QString xdDat = QString("../../data/rec%1").arg(dat.remove(0,m_path.size())); + LOGINFO("删除文件:[%s]",datPath.toStdString().c_str()); + LOGINFO("删除文件:[%s]",xdDat.toStdString().c_str()); + QFile datTemp(datPath); + datTemp.remove(); + m_fileApi.commitLocalFileDel(xdDat.toStdString()); +} + diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.h b/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.h index 220e2889..7975bb7d 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.h +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.h @@ -1,103 +1,103 @@ -#ifndef FAULTRECORDWIDGET_H -#define FAULTRECORDWIDGET_H - -#include -#include -#include -#include -#include "FaultRecordModel.h" -#include "StructDefine.h" -#include -#include "sys_file_sync_api/FilesyncApi.h" -#include - -namespace Ui { -class FaultRecordWidget; -} - -enum EN_TREE_ITEM_TYPE -{ - EN_TREE_ITEM_LOC = 1001, - EN_TREE_ITEM_DEV = 1002 -}; -class FaultRecordWidget : public QWidget -{ - Q_OBJECT - -public: - explicit FaultRecordWidget(bool editMode, QWidget *parent = 0); - ~FaultRecordWidget(); - - void initUi(); - void loadConfig(); - - void loadLocationDesc(); - void loadDevDesc(); - void loadLocation(); - void loadDev(); - - void initTreeWidget(); - void cleanTreeWidget(); - - void initTimeUi(); - - void initModelUi(); - - void updateDeleteOperatePerm(); //更新删除权限 -public slots: - - void initialize(int mode); - void setLocationAndDev(QString location, QStringList devList); - void setColumnWidth(const int &column, const int &width); - void setColumnVisible(const int &column, const bool &visible); - - void treeItemClicked(QTreeWidgetItem *item, int column); - -private slots: - - void brush(); - void brushByTime(const QDateTime &dateTime); - void allClear(); - void clear(); - void open(); -private: - - bool check(); - - bool collectData(); - - void makeData(const QFileInfoList &file_list,const QString &location,const QString &dev); - /** - * @brief makeTime 求日期 - * @param file 文件名(不含后缀) - * @return 1970至此时间的秒数 - */ - bool makeTime(QString &file, qint64 &time); - - bool getTime(QString file,qint64 &time); - void deleteData(QString file); -private: - Ui::FaultRecordWidget *ui; - - QList m_locationList; - QMap > m_locDevMap; - QString m_path; - QList m_dataList; - FaultRecordModel *m_model; - - QString m_location; - QStringList m_devList; - QDateTime m_startTime; - QDateTime m_endTime; - - bool m_deleteOptPerm; - int m_userId; - std::string m_nodeName; - E_Fault_Mode m_mode; - bool m_edit; - kbd_sys::FilesyncApi m_fileApi; - QList m_locDescList; - QList m_devDescList; -}; - -#endif // FAULTRECORDWIDGET_H +#ifndef FAULTRECORDWIDGET_H +#define FAULTRECORDWIDGET_H + +#include +#include +#include +#include +#include "FaultRecordModel.h" +#include "StructDefine.h" +#include +#include "sys_file_sync_api/FilesyncApi.h" +#include + +namespace Ui { +class FaultRecordWidget; +} + +enum EN_TREE_ITEM_TYPE +{ + EN_TREE_ITEM_LOC = 1001, + EN_TREE_ITEM_DEV = 1002 +}; +class FaultRecordWidget : public QWidget +{ + Q_OBJECT + +public: + explicit FaultRecordWidget(bool editMode, QWidget *parent = 0); + ~FaultRecordWidget(); + + void initUi(); + void loadConfig(); + + void loadLocationDesc(); + void loadDevDesc(); + void loadLocation(); + void loadDev(); + + void initTreeWidget(); + void cleanTreeWidget(); + + void initTimeUi(); + + void initModelUi(); + + void updateDeleteOperatePerm(); //更新删除权限 +public slots: + + void initialize(int mode); + void setLocationAndDev(QString location, QStringList devList); + void setColumnWidth(const int &column, const int &width); + void setColumnVisible(const int &column, const bool &visible); + + void treeItemClicked(QTreeWidgetItem *item, int column); + +private slots: + + void brush(); + void brushByTime(const QDateTime &dateTime); + void allClear(); + void clear(); + void open(); +private: + + bool check(); + + bool collectData(); + + void makeData(const QFileInfoList &file_list,const QString &location,const QString &dev); + /** + * @brief makeTime 求日期 + * @param file 文件名(不含后缀) + * @return 1970至此时间的秒数 + */ + bool makeTime(QString &file, qint64 &time); + + bool getTime(QString file,qint64 &time); + void deleteData(QString file); +private: + Ui::FaultRecordWidget *ui; + + QList m_locationList; + QMap > m_locDevMap; + QString m_path; + QList m_dataList; + FaultRecordModel *m_model; + + QString m_location; + QStringList m_devList; + QDateTime m_startTime; + QDateTime m_endTime; + + bool m_deleteOptPerm; + int m_userId; + std::string m_nodeName; + E_Fault_Mode m_mode; + bool m_edit; + kbd_sys::FilesyncApi m_fileApi; + QList m_locDescList; + QList m_devDescList; +}; + +#endif // FAULTRECORDWIDGET_H diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.pro b/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.pro index 6505b0f0..2cb9217f 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.pro +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.pro @@ -1,52 +1,52 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-04-29T16:13:54 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = faultRecordWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - #main.cpp \ - FaultRecordWidget.cpp \ - FaultRecordModel.cpp \ - FaultRecordPluginWidget.cpp - -HEADERS += \ - FaultRecordWidget.h \ - FaultRecordModel.h \ - StructDefine.h \ - FaultRecordPluginWidget.h - -FORMS += \ - FaultRecordWidget.ui - -LIBS += -llog4cplus -lboost_system -lboost_filesystem -lprotobuf -lpub_logger_api -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api -ldb_base_api -lsys_file_sync_api -ldb_api_ex - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2020-04-29T16:13:54 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = faultRecordWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + #main.cpp \ + FaultRecordWidget.cpp \ + FaultRecordModel.cpp \ + FaultRecordPluginWidget.cpp + +HEADERS += \ + FaultRecordWidget.h \ + FaultRecordModel.h \ + StructDefine.h \ + FaultRecordPluginWidget.h + +FORMS += \ + FaultRecordWidget.ui + +LIBS += -llog4cplus -lboost_system -lboost_filesystem -lprotobuf -lpub_logger_api -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api -ldb_base_api -lsys_file_sync_api -ldb_api_ex + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.ui b/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.ui index f6d1f8f8..099e7858 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.ui +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordWidget.ui @@ -1,251 +1,251 @@ - - - FaultRecordWidget - - - - 0 - 0 - 1320 - 577 - - - - FaultRecordWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - 位置/设备 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 26 - - - - - - - - 开始时间 - - - - - - - 结束时间 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 26 - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 26 - - - - 刷新 - - - - - - - - 0 - 26 - - - - 全部删除 - - - - - - - - 0 - 26 - - - - 删除 - - - - - - - - 0 - 26 - - - - 打开 - - - - - - - - - - - - - - - + + + FaultRecordWidget + + + + 0 + 0 + 1320 + 577 + + + + FaultRecordWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 位置/设备 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 26 + + + + + + + + 开始时间 + + + + + + + 结束时间 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 26 + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + 0 + 26 + + + + 刷新 + + + + + + + + 0 + 26 + + + + 全部删除 + + + + + + + + 0 + 26 + + + + 删除 + + + + + + + + 0 + 26 + + + + 打开 + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/FaultRecordWidget/StructDefine.h b/product/src/gui/plugin/FaultRecordWidget/StructDefine.h index 8c300734..813346d4 100644 --- a/product/src/gui/plugin/FaultRecordWidget/StructDefine.h +++ b/product/src/gui/plugin/FaultRecordWidget/StructDefine.h @@ -1,34 +1,34 @@ -#ifndef STRUCTDEFINE_H -#define STRUCTDEFINE_H -#include -#include - -const QString SUFFIXCFG = "cfg"; //后缀为cfg -const QString SUFFIXCNF = "cnf"; -const QString SUFFIXDAT = "dat"; - -enum E_Fault_Mode -{ - E_Fault_Pop = 0, - E_Fault_Window -}; - -struct SFaultRecordInfo -{ - qint64 time; - QString locationName; - QString devName; - QString fileName; - QString filePath; - SFaultRecordInfo() - { - time = 0; - locationName = QString(); - devName = QString(); - fileName = QString(); - filePath = QString(); - } -}; - -typedef QSharedPointer SFaultRecordInfoPtr; -#endif // STRUCTDEFINE_H +#ifndef STRUCTDEFINE_H +#define STRUCTDEFINE_H +#include +#include + +const QString SUFFIXCFG = "cfg"; //后缀为cfg +const QString SUFFIXCNF = "cnf"; +const QString SUFFIXDAT = "dat"; + +enum E_Fault_Mode +{ + E_Fault_Pop = 0, + E_Fault_Window +}; + +struct SFaultRecordInfo +{ + qint64 time; + QString locationName; + QString devName; + QString fileName; + QString filePath; + SFaultRecordInfo() + { + time = 0; + locationName = QString(); + devName = QString(); + fileName = QString(); + filePath = QString(); + } +}; + +typedef QSharedPointer SFaultRecordInfoPtr; +#endif // STRUCTDEFINE_H diff --git a/product/src/gui/plugin/FaultRecordWidget/main.cpp b/product/src/gui/plugin/FaultRecordWidget/main.cpp index 802594d3..9aee6e5f 100644 --- a/product/src/gui/plugin/FaultRecordWidget/main.cpp +++ b/product/src/gui/plugin/FaultRecordWidget/main.cpp @@ -1,11 +1,11 @@ -#include "FaultRecordWidget.h" -#include -#include "pub_logger_api/logger.h" -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - FaultRecordWidget w(false,0); - w.show(); - - return a.exec(); -} +#include "FaultRecordWidget.h" +#include +#include "pub_logger_api/logger.h" +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + FaultRecordWidget w(false,0); + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.cpp b/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.cpp index 7064b4b0..cda97848 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.cpp +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.cpp @@ -1,29 +1,29 @@ -#include -#include "FbdEditorPluginWidget.h" -#include "FbdEditorWidget.h" - -CFbdEditorPluginWidget::CFbdEditorPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CFbdEditorPluginWidget::~CFbdEditorPluginWidget() -{ - -} - -bool CFbdEditorPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - - FbdEditorWidget *pWidget = new FbdEditorWidget(editMode, parent); - *widget = (QWidget *)pWidget; - *alarmWidget = (IPluginWidget *)pWidget; - - return true; -} - -void CFbdEditorPluginWidget::release() -{ - -} +#include +#include "FbdEditorPluginWidget.h" +#include "FbdEditorWidget.h" + +CFbdEditorPluginWidget::CFbdEditorPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CFbdEditorPluginWidget::~CFbdEditorPluginWidget() +{ + +} + +bool CFbdEditorPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + + FbdEditorWidget *pWidget = new FbdEditorWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + + return true; +} + +void CFbdEditorPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.h b/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.h index 323d2949..9c9ab34f 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.h +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef FBDEDITORPLUGINWIDGET_H -#define FBDEDITORPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CFbdEditorPluginWidget: public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CFbdEditorPluginWidget(QObject *parent = 0); - ~CFbdEditorPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); - void release(); -}; - -#endif // FBDEDITORPLUGINWIDGET +#ifndef FBDEDITORPLUGINWIDGET_H +#define FBDEDITORPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CFbdEditorPluginWidget: public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CFbdEditorPluginWidget(QObject *parent = 0); + ~CFbdEditorPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif // FBDEDITORPLUGINWIDGET diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.cpp b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.cpp index 814d2735..ce6a5519 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.cpp +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.cpp @@ -1,61 +1,61 @@ -#include "FbdEditorWidget.h" -#include "fbd_designer/fbd_editor/CFBDMainWindow.h" -#include "fbd_designer/fbd_editor/CFBDMainWindow_global.h" -#include - -FbdEditorWidget::FbdEditorWidget(bool editMode, QWidget *parent) : - QWidget(parent), - m_ptrWindow(Q_NULLPTR) -{ - if(editMode) - { - QLabel *label = new QLabel(this); - label->setPixmap(QPixmap(":/editMode.png")); - label->setScaledContents(true); - QGridLayout *layout = new QGridLayout(this); - layout->addWidget(label); - layout->setMargin(0); - setLayout(layout); - } - else - { - m_ptrWindow = new CFBDMainWindow(parent); - QGridLayout *layout = new QGridLayout(this); - layout->addWidget(m_ptrWindow); - layout->setMargin(0); - setLayout(layout); - } -} - -FbdEditorWidget::~FbdEditorWidget() -{ - if(m_ptrWindow) - { - delete m_ptrWindow; - } - m_ptrWindow = NULL; -} - -void FbdEditorWidget::slotHideMenu(bool bHide) -{ - if(m_ptrWindow) - { - m_ptrWindow->slotHideMenu(bHide); - } -} - -void FbdEditorWidget::slotInit(QString sBussinessTypeName, QString sDefaultDiagramName) -{ - if(m_ptrWindow) - { - m_ptrWindow->slotInit(sBussinessTypeName, sDefaultDiagramName); - } -} - -void FbdEditorWidget::slotSetEditPermission(bool bEnable) -{ - if(m_ptrWindow) - { - m_ptrWindow->slotSetEditPermission(bEnable); - } -} +#include "FbdEditorWidget.h" +#include "fbd_designer/fbd_editor/CFBDMainWindow.h" +#include "fbd_designer/fbd_editor/CFBDMainWindow_global.h" +#include + +FbdEditorWidget::FbdEditorWidget(bool editMode, QWidget *parent) : + QWidget(parent), + m_ptrWindow(Q_NULLPTR) +{ + if(editMode) + { + QLabel *label = new QLabel(this); + label->setPixmap(QPixmap(":/editMode.png")); + label->setScaledContents(true); + QGridLayout *layout = new QGridLayout(this); + layout->addWidget(label); + layout->setMargin(0); + setLayout(layout); + } + else + { + m_ptrWindow = new CFBDMainWindow(parent); + QGridLayout *layout = new QGridLayout(this); + layout->addWidget(m_ptrWindow); + layout->setMargin(0); + setLayout(layout); + } +} + +FbdEditorWidget::~FbdEditorWidget() +{ + if(m_ptrWindow) + { + delete m_ptrWindow; + } + m_ptrWindow = NULL; +} + +void FbdEditorWidget::slotHideMenu(bool bHide) +{ + if(m_ptrWindow) + { + m_ptrWindow->slotHideMenu(bHide); + } +} + +void FbdEditorWidget::slotInit(QString sBussinessTypeName, QString sDefaultDiagramName) +{ + if(m_ptrWindow) + { + m_ptrWindow->slotInit(sBussinessTypeName, sDefaultDiagramName); + } +} + +void FbdEditorWidget::slotSetEditPermission(bool bEnable) +{ + if(m_ptrWindow) + { + m_ptrWindow->slotSetEditPermission(bEnable); + } +} diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.h b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.h index 956749c4..d8f9215f 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.h +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.h @@ -1,24 +1,24 @@ -#ifndef FBDEDITORWIDGET_H -#define FBDEDITORWIDGET_H - -#include - -class CFBDMainWindow; -class FbdEditorWidget : public QWidget -{ - Q_OBJECT - -public: - explicit FbdEditorWidget(bool editMode, QWidget *parent = 0); - ~FbdEditorWidget(); - -public slots: - void slotHideMenu(bool bHide); - void slotInit(QString sBussinessTypeName="", QString sDefaultDiagramName=""); - void slotSetEditPermission(bool bEnable); - -private: - CFBDMainWindow *m_ptrWindow; -}; - -#endif // FBDEDITORWIDGET_H +#ifndef FBDEDITORWIDGET_H +#define FBDEDITORWIDGET_H + +#include + +class CFBDMainWindow; +class FbdEditorWidget : public QWidget +{ + Q_OBJECT + +public: + explicit FbdEditorWidget(bool editMode, QWidget *parent = 0); + ~FbdEditorWidget(); + +public slots: + void slotHideMenu(bool bHide); + void slotInit(QString sBussinessTypeName="", QString sDefaultDiagramName=""); + void slotSetEditPermission(bool bEnable); + +private: + CFBDMainWindow *m_ptrWindow; +}; + +#endif // FBDEDITORWIDGET_H diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.pro b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.pro index 1d9420f3..44dbb0bd 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.pro +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.pro @@ -1,46 +1,46 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-08-27T16:30:15 -# -#------------------------------------------------- - -QT += core gui widgets xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = FbdEditorWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - FbdEditorPluginWidget.cpp \ - FbdEditorWidget.cpp - -HEADERS += \ - FbdEditorPluginWidget.h \ - FbdEditorWidget.h - -LIBS += -lfbd_editor - -exists($$PWD/../../../common.pri) { - include($$PWD/../../../common.pri) -}else { - error("FATAL error: connot find common.pri") -} - -RESOURCES += \ - resource.qrc - +#------------------------------------------------- +# +# Project created by QtCreator 2020-08-27T16:30:15 +# +#------------------------------------------------- + +QT += core gui widgets xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = FbdEditorWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + FbdEditorPluginWidget.cpp \ + FbdEditorWidget.cpp + +HEADERS += \ + FbdEditorPluginWidget.h \ + FbdEditorWidget.h + +LIBS += -lfbd_editor + +exists($$PWD/../../../common.pri) { + include($$PWD/../../../common.pri) +}else { + error("FATAL error: connot find common.pri") +} + +RESOURCES += \ + resource.qrc + diff --git a/product/src/gui/plugin/FbdEditorWidget/resource.qrc b/product/src/gui/plugin/FbdEditorWidget/resource.qrc index da184419..c0b74269 100644 --- a/product/src/gui/plugin/FbdEditorWidget/resource.qrc +++ b/product/src/gui/plugin/FbdEditorWidget/resource.qrc @@ -1,5 +1,5 @@ - - - editMode.png - - + + + editMode.png + + diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelCommon.h b/product/src/gui/plugin/HangPanelWidget/CHangPanelCommon.h index 742cb4d1..00768a2d 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelCommon.h +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelCommon.h @@ -1,49 +1,49 @@ -#ifndef CDATAOPTCOMMON_H -#define CDATAOPTCOMMON_H - -#include - -#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") - -struct SHangPanelInfo -{ - QString keyIdTag; - int tokenId; - qint64 optTime; - int locationId; - int subSystem; - QString device; - QString hostName; - QString userName; - QString userGroup; - QString note; - - QString tagName; - QString devName; - QString table; - -}; - -struct SDeviceInfo -{ - QString tagName; - QString desc; - QString devName; - QString devDesc; - QString devgName; - int region; - -}; - -struct STLocationInfo -{ - int id; - QString desc; - int domainId; - STLocationInfo(){ - id= -1; - domainId = -1; - } -}; - -#endif // CDATAOPTCOMMON_H +#ifndef CDATAOPTCOMMON_H +#define CDATAOPTCOMMON_H + +#include + +#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") + +struct SHangPanelInfo +{ + QString keyIdTag; + int tokenId; + qint64 optTime; + int locationId; + int subSystem; + QString device; + QString hostName; + QString userName; + QString userGroup; + QString note; + + QString tagName; + QString devName; + QString table; + +}; + +struct SDeviceInfo +{ + QString tagName; + QString desc; + QString devName; + QString devDesc; + QString devgName; + int region; + +}; + +struct STLocationInfo +{ + int id; + QString desc; + int domainId; + STLocationInfo(){ + id= -1; + domainId = -1; + } +}; + +#endif // CDATAOPTCOMMON_H diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.cpp b/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.cpp index 03aacc7c..ec5c86ab 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.cpp +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.cpp @@ -1,34 +1,34 @@ -#include "CHangPanelPluginWidget.h" -#include "CHangPanelWidget.h" - -CHangPanelPluginWidget::CHangPanelPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CHangPanelPluginWidget::~CHangPanelPluginWidget() -{ - -} - -bool CHangPanelPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CHangPanelWidget *pWidget = new CHangPanelWidget(editMode, parent); - - if(ptrVec.size()>0) - { - pWidget->setTagType(3); - } - else - { - pWidget->setTagType(0); - } - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CHangPanelPluginWidget::release() -{ - -} +#include "CHangPanelPluginWidget.h" +#include "CHangPanelWidget.h" + +CHangPanelPluginWidget::CHangPanelPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CHangPanelPluginWidget::~CHangPanelPluginWidget() +{ + +} + +bool CHangPanelPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CHangPanelWidget *pWidget = new CHangPanelWidget(editMode, parent); + + if(ptrVec.size()>0) + { + pWidget->setTagType(3); + } + else + { + pWidget->setTagType(0); + } + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CHangPanelPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.h b/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.h index 0d0e9d97..3889afcd 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.h +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CHangPanelPluginWidget_H -#define CHangPanelPluginWidget_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CHangPanelPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CHangPanelPluginWidget(QObject *parent = 0); - - ~CHangPanelPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); - -}; - -#endif // CHangPanelPluginWidget_H +#ifndef CHangPanelPluginWidget_H +#define CHangPanelPluginWidget_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CHangPanelPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CHangPanelPluginWidget(QObject *parent = 0); + + ~CHangPanelPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); + +}; + +#endif // CHangPanelPluginWidget_H diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.cpp b/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.cpp index 15c15343..9757551f 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.cpp +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.cpp @@ -1,672 +1,672 @@ -#include "CHangPanelWidget.h" -#include "ui_CHangPanelWidget.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include -#include -#include "Common.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" -#include "pub_sysinfo_api/SysInfoApi.h" - -using namespace kbd_dbms; -using namespace kbd_public; -using namespace kbd_service; - -CHangPanelWidget::CHangPanelWidget(bool editMode, QWidget *parent) - : QWidget(parent), - ui(new Ui::CHangPanelWidget), - m_pReadDb(Q_NULLPTR), - m_communicator(Q_NULLPTR), - m_pThread(Q_NULLPTR), - m_pWork(Q_NULLPTR), - m_editMode(editMode) -{ - ui->setupUi(this); - - qRegisterMetaType >("QList"); - m_domainId = -1; - m_appId = -1; - initStyleSheet(); - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - if(!m_editMode) - { - if(m_pThread == Q_NULLPTR) - { - m_pThread = new QThread(); - } - if(m_pWork == Q_NULLPTR) - { - m_pWork = new CHangPanelWork(); - } - m_pWork->moveToThread(m_pThread); - connect(m_pThread,&QThread::finished,m_pWork,&QObject::deleteLater); - connect(this,&CHangPanelWidget::sigSearch,m_pWork,&CHangPanelWork::slotSearch,Qt::QueuedConnection); - connect(m_pWork,&CHangPanelWork::sigShowMess,this,&CHangPanelWidget::slotShowMess,Qt::QueuedConnection); - connect(m_pWork,&CHangPanelWork::sigBrush,this,&CHangPanelWidget::slotBrush,Qt::QueuedConnection); - connect(ui->pBrush,&QPushButton::clicked,this,&CHangPanelWidget::brush); - connect(ui->pCancelSetValue,&QPushButton::clicked,this,&CHangPanelWidget::cancelHangePanel); - initialize(); - m_pThread->start(); - QString text =QString(); - search(text); - } -} - -CHangPanelWidget::~CHangPanelWidget() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = Q_NULLPTR; - if(m_pThread) - { - m_pThread->exit(); - m_pThread->wait(); - delete m_pThread; - } - m_pThread = Q_NULLPTR; - - delete ui; -} - -void CHangPanelWidget::setTagType(int actual) -{ - if(m_editMode) - { - return ; - } - if(actual <= 0) - { - }else - { - } - QString text =QString(); - search(text); -} - -void CHangPanelWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CHangPanelWidget::initialize() -{ - if(!createSysInfoInstance(m_pSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - } - initMsg(); - initData(); - initView(); - initConn(); -} - -void CHangPanelWidget::initData() -{ - //4.获取位置 - loadLoc(); - - loadSub();//sys_model_sub_system_info - - loadDevG();//dev_group - - loadDev();//dev_info - - loadHangType();//dict_menu_info -} - -void CHangPanelWidget::initView() -{ - ui->cLocation->blockSignals(true); - ui->cSub->blockSignals(true); - ui->cLocation->clear(); - - foreach (const int &locId, m_locOrder) { - ui->cLocation->addItem(m_locMap.value(locId).desc,locId); - } - - ui->cSub->clear(); - QMap::iterator itor = m_subMap.begin(); - - while (itor != m_subMap.end()) { - ui->cSub->addItem(itor.value(),itor.key()); - itor++; - } - - ui->cSub->blockSignals(false); - ui->cLocation->blockSignals(false); - setDefaultWidth(); - setColumnHidden(9,true); - setColumnHidden(10,true); - - ui->tableWidget->setSortingEnabled(true); - ui->tableWidget->sortByColumn(4, Qt::DescendingOrder); -} - -void CHangPanelWidget::initConn() -{ - connect(ui->cLocation,&QComboBox::currentTextChanged,this,&CHangPanelWidget::search); - connect(ui->cSub,&QComboBox::currentTextChanged,this,&CHangPanelWidget::search); -} - -void CHangPanelWidget::loadLoc() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - - QStringList listColName ; - listColName <<"LOCATION_ID"<<"DESCRIPTION"<<"DOMAIN_ID" ; - QList listOrderBy; - listOrderBy << CDbOrder("location_no"); - - - if(false == m_pReadDb->select("sys_model_location_info",listColName, listOrderBy, query)) return ; - - while(query.next()) - { - STLocationInfo loc; - loc.id = query.value(0).toInt(); - loc.desc = query.value(1).toString(); - loc.domainId = query.value(2).toInt(); - m_locMap.insert(loc.id, loc); - m_locOrder.push_back(loc.id); - } -} - -void CHangPanelWidget::loadSub() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select SUB_SYSTEM_ID,DESCRIPTION from sys_model_sub_system_info where SUB_SYSTEM_ID > 3"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - int id = query.value(0).toInt(); - QString desc = query.value(1).toString(); - m_subMap.insert(id, desc); - } -} - -void CHangPanelWidget::loadDevG() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - - QStringList listColName ; - listColName <<"TAG_NAME"<<"DESCRIPTION" ; - - if(false == m_pReadDb->select("dev_group",listColName, query)) return ; - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - m_devgMap.insert(tag, desc); - } -} - -void CHangPanelWidget::loadDev() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - - QStringList listColName ; - listColName <<"TAG_NAME"<<"DESCRIPTION" ; - - if(false == m_pReadDb->select("dev_info",listColName, query)) return ; - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - m_devMap.insert(tag, desc); - } - return; -} - -void CHangPanelWidget::loadHangType() -{ - if(!m_pReadDb->isOpen()) - { - return ; - } - QSqlQuery query; - - QStringList listColName ; - listColName <<"TOKEN_ID"<<"DESCRIPTION"<<"TOKEN_PROP"; - - if(false == m_pReadDb->select ("opt_token_define",listColName,query)) return; - - while(query.next()) - { - int nTokenId = query.value(0).toInt(); - QString sDesc = query.value(1).toString(); - int nTokenProp = query.value(2).toInt(); - m_typeMap.insert(nTokenId, sDesc); - } - return; -} - -void CHangPanelWidget::updateTable(const QList &dataList) -{ - ui->tableWidget->setSortingEnabled(false); - ui->tableWidget->setRowCount(0); - int locId = ui->cLocation->currentData().toInt(); - QList typeList; - - for(int index(0);indextableWidget->rowCount(); - ui->tableWidget->insertRow(row); - - QTableWidgetItem *item = new QTableWidgetItem();//厂站 - item->setText(m_locMap.value(dataList[index].locationId).desc); - item->setData(Qt::UserRole,dataList[index].locationId); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,0,item); - - item = new QTableWidgetItem();//设备组 - SDeviceInfo tagInfo = m_pWork->getTagInfoByPointTagName(dataList[index].tagName); - item->setText(m_devgMap.value(tagInfo.devgName,tr("未知"))); - item->setData(Qt::UserRole,tagInfo.devgName); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,1,item); - - item = new QTableWidgetItem(); //设备描述 - item->setText(tagInfo.devDesc); - item->setData(Qt::UserRole,tagInfo.devName); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,2,item); - - item = new QTableWidgetItem();//挂牌类型 - item->setText(m_typeMap.value(dataList[index].tokenId,tr("未知"))); - item->setData(Qt::UserRole,dataList[index].tokenId); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,3,item); - - item = new QTableWidgetItem(); //操作时间 - item->setText(QDateTime::fromMSecsSinceEpoch(dataList[index].optTime).toString("yyyy-MM-dd hh:mm:ss")); - item->setData(Qt::UserRole,dataList[index].optTime); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,4,item); - - item = new QTableWidgetItem(); //专业 - item->setText(m_subMap.value(dataList[index].subSystem,tr("未知"))); - item->setData(Qt::UserRole,dataList[index].subSystem); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,5,item); - - item = new QTableWidgetItem();//操作主机 - item->setText(dataList[index].hostName); - item->setData(Qt::UserRole,dataList[index].hostName); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,6,item); - - item = new QTableWidgetItem();//操作人 - item->setText(dataList[index].userName); - item->setData(Qt::UserRole,dataList[index].userName); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,7,item); - - item = new QTableWidgetItem();//操作人组 - item->setText(dataList[index].userGroup); - item->setData(Qt::UserRole,dataList[index].userGroup); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,8,item); - - item = new QTableWidgetItem();//备注 - item->setText(dataList[index].note); - item->setData(Qt::UserRole,dataList[index].note); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,9,item); - - - item = new QTableWidgetItem();//标签KEY - item->setText(dataList[index].keyIdTag); - item->setData(Qt::UserRole,dataList[index].tagName); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(row,10,item); - - } - ui->tableWidget->setSortingEnabled(true); -} - -void CHangPanelWidget::updateCount() -{ - ui->lCount->setNum(ui->tableWidget->rowCount()); -} - -bool CHangPanelWidget::permCheck(int location, int region) -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - QString mess; - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - int userId; - if(PERM_NORMAL != permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - userId = -1; - return false; - } - std::vector vecRegionOptId; - QList regList; - QList locList; - std::vector vecLocationOptId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) - { - - std::vector ::iterator region = vecRegionOptId.begin(); - while (region != vecRegionOptId.end()) - { - regList.append(*region++); - } - - std::vector ::iterator location = vecLocationOptId.begin(); - while (location != vecLocationOptId.end()) - { - locList.append(*location++); - } - } - if(locList.contains(location) && regList.contains(region)) - { - return true; - }else - { - mess = QString(tr("无取消挂牌操作权限!")); - slotShowMess(mess); - return false; - } - } - mess = QString(tr("初始化权限失败!")); - slotShowMess(mess); - return false; -} - -void CHangPanelWidget::initMsg() -{ - if(m_communicator == Q_NULLPTR) - { - m_communicator = new kbd_net::CMbCommunicator(); - } -} - -int CHangPanelWidget::createReqHead(SOptReqHead &head) -{ - SNodeInfo nodeInfo; - int userID = -1; - int usergID = -1; - int level; - int loginSec; - std::string instanceName; - - CSysInfoInterfacePtr sysInfo; - if(createSysInfoInstance(sysInfo) == false) - { - LOGERROR("创建系统信息访问库实例失败!"); - return kbdFailed; - } - else - { - sysInfo->getLocalNodeInfo(nodeInfo); - } - - CPermMngApiPtr permMng = getPermMngInstance("base"); - if(permMng != NULL) - { - if(permMng->PermDllInit() != PERM_NORMAL) - { - LOGERROR("权限接口初始化失败!"); - return kbdFailed; - }else - { - if(PERM_NORMAL != permMng->CurUser(userID, usergID, level, loginSec, instanceName)) - { - userID = -1; - return kbdFailed; - } - } - } - head.strSrcTag = "HangPanelWidget"; - head.nSrcDomainID = nodeInfo.nDomainId; - head.nDstDomainID = m_domainId; - head.nAppID = m_appId; - head.strHostName = nodeInfo.strName; - head.strInstName = instanceName; - head.strCommName = m_communicator->getName(); - head.nUserID = userID; - head.nUserGroupID = usergID; - head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - - return kbdSuccess; -} - -void CHangPanelWidget::filter(const QString &content) -{ - Q_UNUSED(content); - int locId = ui->cLocation->currentData().toInt(); - int row = ui->tableWidget->rowCount(); - for(int index(0);indextableWidget->item(index,0)->data(Qt::UserRole).toInt(); - int type = ui->tableWidget->item(index,4)->data(Qt::UserRole).toInt(); - } -} - -void CHangPanelWidget::slotShowMess(const QString &mess) -{ - QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); -} - -void CHangPanelWidget::slotBrush(const QList &optTagInfoList) -{ - updateTable(optTagInfoList); - updateCount(); -} - -void CHangPanelWidget::setColumnHidden(int column, bool hide) -{ - ui->tableWidget->setColumnHidden(column,hide); -} - -void CHangPanelWidget::setColumnWidth(int column, int width) -{ - ui->tableWidget->setColumnWidth(column,width); -} - -void CHangPanelWidget::setRowHeight(int height) -{ - ui->tableWidget->horizontalHeader()->setDefaultSectionSize(height); -} - -void CHangPanelWidget::setDefaultWidth() -{ - ui->tableWidget->setColumnWidth(0,150); - ui->tableWidget->setColumnWidth(1,180); - ui->tableWidget->setColumnWidth(2,180); - ui->tableWidget->setColumnWidth(3,150); - ui->tableWidget->setColumnWidth(4,150); - ui->tableWidget->setColumnWidth(5,150); - ui->tableWidget->setColumnWidth(6,150); - ui->tableWidget->setColumnWidth(7,150); - ui->tableWidget->setColumnWidth(8,100); - ui->tableWidget->setColumnWidth(9,200); - ui->tableWidget->setColumnWidth(10,0); -} - -void CHangPanelWidget::cancelHangePanel() -{ - QString mess = QString(tr("请选择一项挂牌信息!"));; - QList list = ui->tableWidget->selectedItems(); - if (list.size() <= 0) - { - slotShowMess(mess); - return; - } - int row = ui->tableWidget->currentRow(); - QString tagName= ui->tableWidget->item(row,10)->data(Qt::UserRole).toString(); //标签 - QString descName= ui->tableWidget->item(row,10)->text(); //标签 - int tagType = ui->tableWidget->item(row,3)->data(Qt::UserRole).toInt(); //挂牌类型 - - struct itemData - { - QString tagName; - QString tagDesc; - int tagType; - }; - - QMap itemDataMap; - - QList::iterator iter= list.begin(); - for(; iter!=list.end(); ++iter) - { - QTableWidgetItem* item = *iter; - - int row = item->row(); - itemDataMap[row].tagName = ui->tableWidget->item(row,10)->data(Qt::UserRole).toString(); - itemDataMap[row].tagDesc = ui->tableWidget->item(row,2)->text(); - itemDataMap[row].tagType = ui->tableWidget->item(row,3)->data(Qt::UserRole).toInt(); - } - - - QMap::iterator itemDataIter = itemDataMap.begin(); - for(; itemDataIter!= itemDataMap.end(); ++itemDataIter) - { - itemData& data = itemDataIter.value(); - if(!cancelItemHangePanel(data.tagDesc,data.tagName,data.tagType)) - { - break; - } - } - -} - -bool CHangPanelWidget::cancelItemHangePanel(const QString &desc, const QString &tagName, int tagType) -{ - SHangPanelInfo info; - if(m_pWork->getHangInfoByTagAndType(tagName,tagType,info) !=kbdSuccess ) //得到挂牌信息 - { - slotShowMess(tr("获取标签挂牌信息有误,%1").arg(desc)); - return false; - } - SDeviceInfo tagInfo; - if(m_pWork->getHangeInfoByTag(tagName,tagInfo) !=kbdSuccess ) //挂牌设备信息 - { - slotShowMess(tr("获取标签挂牌信息有误,%1").arg(desc)); - return false; - } - if(!permCheck(info.locationId,tagInfo.region)) - { - return false; - } - removeHangInfo(info); - return true; -} - -void CHangPanelWidget::removeHangInfo(const SHangPanelInfo &info) -{ - kbd_net::CMbMessage msg; - msg.setMsgType(MT_OPT_COMMON_DOWN); - msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); - STokenSet sOptHangSet; - STokenQueue optHangQueue; - CTokenSet cTokenSet; - - if(createReqHead(sOptHangSet.stHead)!= kbdSuccess){ return ; } - - optHangQueue.strKeyIdTag = info.keyIdTag.toStdString(); - optHangQueue.nTokenId = info.tokenId ;// 0:取消;1:设置; - optHangQueue.nLocationId = info.locationId; - optHangQueue.nSubSystem = info.subSystem; - - sOptHangSet.vecTokenQueue.push_back(optHangQueue); - std::string content = cTokenSet.generate(sOptHangSet); - msg.setMsgType(MT_OPT_TOKEN_DELETE); - - msg.setData(content); - if(!m_communicator->sendMsgToDomain(msg, m_domainId)) - { - QString mess = QString(tr("下发取消挂牌命令失败")); - slotShowMess(mess); - } - else - { - removeItemHangInfo(info); - m_pWork->removeHangInfo(info); - updateCount(); - } - return ; -} - -void CHangPanelWidget::removeItemHangInfo(const SHangPanelInfo &info) -{ - int rowCount = ui->tableWidget->rowCount(); - for(int i=0; itableWidget->item(i,10)->data(Qt::UserRole).toString(); - int tagType = ui->tableWidget->item(i,3)->data(Qt::UserRole).toInt(); - if(tagName == info.tagName && info.tokenId ==tagType ) - { - ui->tableWidget->removeRow(i); - break; - } - } -} - -void CHangPanelWidget::search(const QString &content) -{ - Q_UNUSED(content); - m_domainId = m_locMap.value(ui->cLocation->currentData().toInt()).domainId; - - if(m_pSysInfo != Q_NULLPTR) - { - SAppInfo stAppInfo; - m_pSysInfo->getAppInfoBySubsystemId(ui->cSub->currentData().toInt(),stAppInfo); //ZZL - m_appId = stAppInfo.nId; - emit sigSearch(m_domainId,m_appId); - } -} - -void CHangPanelWidget::brush() -{ - QString text =QString(); - search(text); -} - +#include "CHangPanelWidget.h" +#include "ui_CHangPanelWidget.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include +#include +#include "Common.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" +#include "pub_sysinfo_api/SysInfoApi.h" + +using namespace kbd_dbms; +using namespace kbd_public; +using namespace kbd_service; + +CHangPanelWidget::CHangPanelWidget(bool editMode, QWidget *parent) + : QWidget(parent), + ui(new Ui::CHangPanelWidget), + m_pReadDb(Q_NULLPTR), + m_communicator(Q_NULLPTR), + m_pThread(Q_NULLPTR), + m_pWork(Q_NULLPTR), + m_editMode(editMode) +{ + ui->setupUi(this); + + qRegisterMetaType >("QList"); + m_domainId = -1; + m_appId = -1; + initStyleSheet(); + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + if(!m_editMode) + { + if(m_pThread == Q_NULLPTR) + { + m_pThread = new QThread(); + } + if(m_pWork == Q_NULLPTR) + { + m_pWork = new CHangPanelWork(); + } + m_pWork->moveToThread(m_pThread); + connect(m_pThread,&QThread::finished,m_pWork,&QObject::deleteLater); + connect(this,&CHangPanelWidget::sigSearch,m_pWork,&CHangPanelWork::slotSearch,Qt::QueuedConnection); + connect(m_pWork,&CHangPanelWork::sigShowMess,this,&CHangPanelWidget::slotShowMess,Qt::QueuedConnection); + connect(m_pWork,&CHangPanelWork::sigBrush,this,&CHangPanelWidget::slotBrush,Qt::QueuedConnection); + connect(ui->pBrush,&QPushButton::clicked,this,&CHangPanelWidget::brush); + connect(ui->pCancelSetValue,&QPushButton::clicked,this,&CHangPanelWidget::cancelHangePanel); + initialize(); + m_pThread->start(); + QString text =QString(); + search(text); + } +} + +CHangPanelWidget::~CHangPanelWidget() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = Q_NULLPTR; + if(m_pThread) + { + m_pThread->exit(); + m_pThread->wait(); + delete m_pThread; + } + m_pThread = Q_NULLPTR; + + delete ui; +} + +void CHangPanelWidget::setTagType(int actual) +{ + if(m_editMode) + { + return ; + } + if(actual <= 0) + { + }else + { + } + QString text =QString(); + search(text); +} + +void CHangPanelWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CHangPanelWidget::initialize() +{ + if(!createSysInfoInstance(m_pSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + initMsg(); + initData(); + initView(); + initConn(); +} + +void CHangPanelWidget::initData() +{ + //4.获取位置 + loadLoc(); + + loadSub();//sys_model_sub_system_info + + loadDevG();//dev_group + + loadDev();//dev_info + + loadHangType();//dict_menu_info +} + +void CHangPanelWidget::initView() +{ + ui->cLocation->blockSignals(true); + ui->cSub->blockSignals(true); + ui->cLocation->clear(); + + foreach (const int &locId, m_locOrder) { + ui->cLocation->addItem(m_locMap.value(locId).desc,locId); + } + + ui->cSub->clear(); + QMap::iterator itor = m_subMap.begin(); + + while (itor != m_subMap.end()) { + ui->cSub->addItem(itor.value(),itor.key()); + itor++; + } + + ui->cSub->blockSignals(false); + ui->cLocation->blockSignals(false); + setDefaultWidth(); + setColumnHidden(9,true); + setColumnHidden(10,true); + + ui->tableWidget->setSortingEnabled(true); + ui->tableWidget->sortByColumn(4, Qt::DescendingOrder); +} + +void CHangPanelWidget::initConn() +{ + connect(ui->cLocation,&QComboBox::currentTextChanged,this,&CHangPanelWidget::search); + connect(ui->cSub,&QComboBox::currentTextChanged,this,&CHangPanelWidget::search); +} + +void CHangPanelWidget::loadLoc() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + + QStringList listColName ; + listColName <<"LOCATION_ID"<<"DESCRIPTION"<<"DOMAIN_ID" ; + QList listOrderBy; + listOrderBy << CDbOrder("location_no"); + + + if(false == m_pReadDb->select("sys_model_location_info",listColName, listOrderBy, query)) return ; + + while(query.next()) + { + STLocationInfo loc; + loc.id = query.value(0).toInt(); + loc.desc = query.value(1).toString(); + loc.domainId = query.value(2).toInt(); + m_locMap.insert(loc.id, loc); + m_locOrder.push_back(loc.id); + } +} + +void CHangPanelWidget::loadSub() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select SUB_SYSTEM_ID,DESCRIPTION from sys_model_sub_system_info where SUB_SYSTEM_ID > 3"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString desc = query.value(1).toString(); + m_subMap.insert(id, desc); + } +} + +void CHangPanelWidget::loadDevG() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + + QStringList listColName ; + listColName <<"TAG_NAME"<<"DESCRIPTION" ; + + if(false == m_pReadDb->select("dev_group",listColName, query)) return ; + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + m_devgMap.insert(tag, desc); + } +} + +void CHangPanelWidget::loadDev() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + + QStringList listColName ; + listColName <<"TAG_NAME"<<"DESCRIPTION" ; + + if(false == m_pReadDb->select("dev_info",listColName, query)) return ; + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + m_devMap.insert(tag, desc); + } + return; +} + +void CHangPanelWidget::loadHangType() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + + QStringList listColName ; + listColName <<"TOKEN_ID"<<"DESCRIPTION"<<"TOKEN_PROP"; + + if(false == m_pReadDb->select ("opt_token_define",listColName,query)) return; + + while(query.next()) + { + int nTokenId = query.value(0).toInt(); + QString sDesc = query.value(1).toString(); + int nTokenProp = query.value(2).toInt(); + m_typeMap.insert(nTokenId, sDesc); + } + return; +} + +void CHangPanelWidget::updateTable(const QList &dataList) +{ + ui->tableWidget->setSortingEnabled(false); + ui->tableWidget->setRowCount(0); + int locId = ui->cLocation->currentData().toInt(); + QList typeList; + + for(int index(0);indextableWidget->rowCount(); + ui->tableWidget->insertRow(row); + + QTableWidgetItem *item = new QTableWidgetItem();//厂站 + item->setText(m_locMap.value(dataList[index].locationId).desc); + item->setData(Qt::UserRole,dataList[index].locationId); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,0,item); + + item = new QTableWidgetItem();//设备组 + SDeviceInfo tagInfo = m_pWork->getTagInfoByPointTagName(dataList[index].tagName); + item->setText(m_devgMap.value(tagInfo.devgName,tr("未知"))); + item->setData(Qt::UserRole,tagInfo.devgName); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,1,item); + + item = new QTableWidgetItem(); //设备描述 + item->setText(tagInfo.devDesc); + item->setData(Qt::UserRole,tagInfo.devName); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,2,item); + + item = new QTableWidgetItem();//挂牌类型 + item->setText(m_typeMap.value(dataList[index].tokenId,tr("未知"))); + item->setData(Qt::UserRole,dataList[index].tokenId); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,3,item); + + item = new QTableWidgetItem(); //操作时间 + item->setText(QDateTime::fromMSecsSinceEpoch(dataList[index].optTime).toString("yyyy-MM-dd hh:mm:ss")); + item->setData(Qt::UserRole,dataList[index].optTime); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,4,item); + + item = new QTableWidgetItem(); //专业 + item->setText(m_subMap.value(dataList[index].subSystem,tr("未知"))); + item->setData(Qt::UserRole,dataList[index].subSystem); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,5,item); + + item = new QTableWidgetItem();//操作主机 + item->setText(dataList[index].hostName); + item->setData(Qt::UserRole,dataList[index].hostName); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,6,item); + + item = new QTableWidgetItem();//操作人 + item->setText(dataList[index].userName); + item->setData(Qt::UserRole,dataList[index].userName); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,7,item); + + item = new QTableWidgetItem();//操作人组 + item->setText(dataList[index].userGroup); + item->setData(Qt::UserRole,dataList[index].userGroup); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,8,item); + + item = new QTableWidgetItem();//备注 + item->setText(dataList[index].note); + item->setData(Qt::UserRole,dataList[index].note); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,9,item); + + + item = new QTableWidgetItem();//标签KEY + item->setText(dataList[index].keyIdTag); + item->setData(Qt::UserRole,dataList[index].tagName); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(row,10,item); + + } + ui->tableWidget->setSortingEnabled(true); +} + +void CHangPanelWidget::updateCount() +{ + ui->lCount->setNum(ui->tableWidget->rowCount()); +} + +bool CHangPanelWidget::permCheck(int location, int region) +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + QString mess; + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + int userId; + if(PERM_NORMAL != permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + userId = -1; + return false; + } + std::vector vecRegionOptId; + QList regList; + QList locList; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) + { + + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + regList.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + locList.append(*location++); + } + } + if(locList.contains(location) && regList.contains(region)) + { + return true; + }else + { + mess = QString(tr("无取消挂牌操作权限!")); + slotShowMess(mess); + return false; + } + } + mess = QString(tr("初始化权限失败!")); + slotShowMess(mess); + return false; +} + +void CHangPanelWidget::initMsg() +{ + if(m_communicator == Q_NULLPTR) + { + m_communicator = new kbd_net::CMbCommunicator(); + } +} + +int CHangPanelWidget::createReqHead(SOptReqHead &head) +{ + SNodeInfo nodeInfo; + int userID = -1; + int usergID = -1; + int level; + int loginSec; + std::string instanceName; + + CSysInfoInterfacePtr sysInfo; + if(createSysInfoInstance(sysInfo) == false) + { + LOGERROR("创建系统信息访问库实例失败!"); + return kbdFailed; + } + else + { + sysInfo->getLocalNodeInfo(nodeInfo); + } + + CPermMngApiPtr permMng = getPermMngInstance("base"); + if(permMng != NULL) + { + if(permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + return kbdFailed; + }else + { + if(PERM_NORMAL != permMng->CurUser(userID, usergID, level, loginSec, instanceName)) + { + userID = -1; + return kbdFailed; + } + } + } + head.strSrcTag = "HangPanelWidget"; + head.nSrcDomainID = nodeInfo.nDomainId; + head.nDstDomainID = m_domainId; + head.nAppID = m_appId; + head.strHostName = nodeInfo.strName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = userID; + head.nUserGroupID = usergID; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + return kbdSuccess; +} + +void CHangPanelWidget::filter(const QString &content) +{ + Q_UNUSED(content); + int locId = ui->cLocation->currentData().toInt(); + int row = ui->tableWidget->rowCount(); + for(int index(0);indextableWidget->item(index,0)->data(Qt::UserRole).toInt(); + int type = ui->tableWidget->item(index,4)->data(Qt::UserRole).toInt(); + } +} + +void CHangPanelWidget::slotShowMess(const QString &mess) +{ + QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); +} + +void CHangPanelWidget::slotBrush(const QList &optTagInfoList) +{ + updateTable(optTagInfoList); + updateCount(); +} + +void CHangPanelWidget::setColumnHidden(int column, bool hide) +{ + ui->tableWidget->setColumnHidden(column,hide); +} + +void CHangPanelWidget::setColumnWidth(int column, int width) +{ + ui->tableWidget->setColumnWidth(column,width); +} + +void CHangPanelWidget::setRowHeight(int height) +{ + ui->tableWidget->horizontalHeader()->setDefaultSectionSize(height); +} + +void CHangPanelWidget::setDefaultWidth() +{ + ui->tableWidget->setColumnWidth(0,150); + ui->tableWidget->setColumnWidth(1,180); + ui->tableWidget->setColumnWidth(2,180); + ui->tableWidget->setColumnWidth(3,150); + ui->tableWidget->setColumnWidth(4,150); + ui->tableWidget->setColumnWidth(5,150); + ui->tableWidget->setColumnWidth(6,150); + ui->tableWidget->setColumnWidth(7,150); + ui->tableWidget->setColumnWidth(8,100); + ui->tableWidget->setColumnWidth(9,200); + ui->tableWidget->setColumnWidth(10,0); +} + +void CHangPanelWidget::cancelHangePanel() +{ + QString mess = QString(tr("请选择一项挂牌信息!"));; + QList list = ui->tableWidget->selectedItems(); + if (list.size() <= 0) + { + slotShowMess(mess); + return; + } + int row = ui->tableWidget->currentRow(); + QString tagName= ui->tableWidget->item(row,10)->data(Qt::UserRole).toString(); //标签 + QString descName= ui->tableWidget->item(row,10)->text(); //标签 + int tagType = ui->tableWidget->item(row,3)->data(Qt::UserRole).toInt(); //挂牌类型 + + struct itemData + { + QString tagName; + QString tagDesc; + int tagType; + }; + + QMap itemDataMap; + + QList::iterator iter= list.begin(); + for(; iter!=list.end(); ++iter) + { + QTableWidgetItem* item = *iter; + + int row = item->row(); + itemDataMap[row].tagName = ui->tableWidget->item(row,10)->data(Qt::UserRole).toString(); + itemDataMap[row].tagDesc = ui->tableWidget->item(row,2)->text(); + itemDataMap[row].tagType = ui->tableWidget->item(row,3)->data(Qt::UserRole).toInt(); + } + + + QMap::iterator itemDataIter = itemDataMap.begin(); + for(; itemDataIter!= itemDataMap.end(); ++itemDataIter) + { + itemData& data = itemDataIter.value(); + if(!cancelItemHangePanel(data.tagDesc,data.tagName,data.tagType)) + { + break; + } + } + +} + +bool CHangPanelWidget::cancelItemHangePanel(const QString &desc, const QString &tagName, int tagType) +{ + SHangPanelInfo info; + if(m_pWork->getHangInfoByTagAndType(tagName,tagType,info) !=kbdSuccess ) //得到挂牌信息 + { + slotShowMess(tr("获取标签挂牌信息有误,%1").arg(desc)); + return false; + } + SDeviceInfo tagInfo; + if(m_pWork->getHangeInfoByTag(tagName,tagInfo) !=kbdSuccess ) //挂牌设备信息 + { + slotShowMess(tr("获取标签挂牌信息有误,%1").arg(desc)); + return false; + } + if(!permCheck(info.locationId,tagInfo.region)) + { + return false; + } + removeHangInfo(info); + return true; +} + +void CHangPanelWidget::removeHangInfo(const SHangPanelInfo &info) +{ + kbd_net::CMbMessage msg; + msg.setMsgType(MT_OPT_COMMON_DOWN); + msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); + STokenSet sOptHangSet; + STokenQueue optHangQueue; + CTokenSet cTokenSet; + + if(createReqHead(sOptHangSet.stHead)!= kbdSuccess){ return ; } + + optHangQueue.strKeyIdTag = info.keyIdTag.toStdString(); + optHangQueue.nTokenId = info.tokenId ;// 0:取消;1:设置; + optHangQueue.nLocationId = info.locationId; + optHangQueue.nSubSystem = info.subSystem; + + sOptHangSet.vecTokenQueue.push_back(optHangQueue); + std::string content = cTokenSet.generate(sOptHangSet); + msg.setMsgType(MT_OPT_TOKEN_DELETE); + + msg.setData(content); + if(!m_communicator->sendMsgToDomain(msg, m_domainId)) + { + QString mess = QString(tr("下发取消挂牌命令失败")); + slotShowMess(mess); + } + else + { + removeItemHangInfo(info); + m_pWork->removeHangInfo(info); + updateCount(); + } + return ; +} + +void CHangPanelWidget::removeItemHangInfo(const SHangPanelInfo &info) +{ + int rowCount = ui->tableWidget->rowCount(); + for(int i=0; itableWidget->item(i,10)->data(Qt::UserRole).toString(); + int tagType = ui->tableWidget->item(i,3)->data(Qt::UserRole).toInt(); + if(tagName == info.tagName && info.tokenId ==tagType ) + { + ui->tableWidget->removeRow(i); + break; + } + } +} + +void CHangPanelWidget::search(const QString &content) +{ + Q_UNUSED(content); + m_domainId = m_locMap.value(ui->cLocation->currentData().toInt()).domainId; + + if(m_pSysInfo != Q_NULLPTR) + { + SAppInfo stAppInfo; + m_pSysInfo->getAppInfoBySubsystemId(ui->cSub->currentData().toInt(),stAppInfo); //ZZL + m_appId = stAppInfo.nId; + emit sigSearch(m_domainId,m_appId); + } +} + +void CHangPanelWidget::brush() +{ + QString text =QString(); + search(text); +} + diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.h b/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.h index af8ab89b..a0358c55 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.h +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.h @@ -1,116 +1,116 @@ -#ifndef CHangPanelWidget_H -#define CHangPanelWidget_H - -#include -#include -#include "dbms/db_api_ex/CDbApi.h" -#include -#include "CHangPanelCommon.h" -#include -#include "CHangPanelWork.h" - -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "service/operate_server_api/JsonMessageStruct.h" -#include "service/operate_server_api/JsonOptCommand.h" -#include "common/MessageChannel.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" - -QT_BEGIN_NAMESPACE -namespace Ui { class CHangPanelWidget; } -QT_END_NAMESPACE - -class CHangPanelWidget : public QWidget -{ - Q_OBJECT - -public: - CHangPanelWidget(bool editMode,QWidget *parent = nullptr); - ~CHangPanelWidget(); - -private: - void initStyleSheet(); - - void initialize(); - - void initData(); - - void initView(); - - void initConn(); - - void loadLoc(); - - void loadSub(); - - void loadDevG(); - - void loadDev(); - - void loadHangType(); - - void updateTable(const QList &dataList); - - void updateCount(); - - bool permCheck(int location ,int region); - - void initMsg(); - - int createReqHead(SOptReqHead &head); - - -public slots: - - void setTagType(int actual = 0); - - void filter(const QString & content); - - void slotShowMess(const QString &mess); - - void slotBrush(const QList & optTagInfoList); - - void setColumnHidden(int column,bool hide); - - void setColumnWidth(int column,int width); - - void setRowHeight(int height); - - void setDefaultWidth(); - - void cancelHangePanel(); - bool cancelItemHangePanel(const QString &desc,const QString &tagName, int tagType); - - void removeHangInfo(const SHangPanelInfo &info); - void removeItemHangInfo(const SHangPanelInfo &info); - void search(const QString & content); - - void brush(); - -signals: - void sigSearch(int domainId ,int appid); - -private: - Ui::CHangPanelWidget *ui; - - kbd_dbms::CDbApi * m_pReadDb; - - kbd_net::CMbCommunicator *m_communicator; - kbd_public::CSysInfoInterfacePtr m_pSysInfo; - QMap m_locMap; - QList m_locOrder; - QMap m_subMap; - QMap m_devgMap; - QMap m_devMap; - QMap m_typeMap; - - QThread *m_pThread; - CHangPanelWork *m_pWork; - - bool m_editMode; - int m_domainId; - int m_appId; - -}; -#endif // CHangPanelWidget_H +#ifndef CHangPanelWidget_H +#define CHangPanelWidget_H + +#include +#include +#include "dbms/db_api_ex/CDbApi.h" +#include +#include "CHangPanelCommon.h" +#include +#include "CHangPanelWork.h" + +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "common/MessageChannel.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class CHangPanelWidget; } +QT_END_NAMESPACE + +class CHangPanelWidget : public QWidget +{ + Q_OBJECT + +public: + CHangPanelWidget(bool editMode,QWidget *parent = nullptr); + ~CHangPanelWidget(); + +private: + void initStyleSheet(); + + void initialize(); + + void initData(); + + void initView(); + + void initConn(); + + void loadLoc(); + + void loadSub(); + + void loadDevG(); + + void loadDev(); + + void loadHangType(); + + void updateTable(const QList &dataList); + + void updateCount(); + + bool permCheck(int location ,int region); + + void initMsg(); + + int createReqHead(SOptReqHead &head); + + +public slots: + + void setTagType(int actual = 0); + + void filter(const QString & content); + + void slotShowMess(const QString &mess); + + void slotBrush(const QList & optTagInfoList); + + void setColumnHidden(int column,bool hide); + + void setColumnWidth(int column,int width); + + void setRowHeight(int height); + + void setDefaultWidth(); + + void cancelHangePanel(); + bool cancelItemHangePanel(const QString &desc,const QString &tagName, int tagType); + + void removeHangInfo(const SHangPanelInfo &info); + void removeItemHangInfo(const SHangPanelInfo &info); + void search(const QString & content); + + void brush(); + +signals: + void sigSearch(int domainId ,int appid); + +private: + Ui::CHangPanelWidget *ui; + + kbd_dbms::CDbApi * m_pReadDb; + + kbd_net::CMbCommunicator *m_communicator; + kbd_public::CSysInfoInterfacePtr m_pSysInfo; + QMap m_locMap; + QList m_locOrder; + QMap m_subMap; + QMap m_devgMap; + QMap m_devMap; + QMap m_typeMap; + + QThread *m_pThread; + CHangPanelWork *m_pWork; + + bool m_editMode; + int m_domainId; + int m_appId; + +}; +#endif // CHangPanelWidget_H diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.ui b/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.ui index 2907e3de..7ac44e9b 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.ui +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.ui @@ -1,209 +1,209 @@ - - - CHangPanelWidget - - - - 0 - 0 - 800 - 600 - - - - CHangPanelWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 位置: - - - - - - - - 100 - 0 - - - - - - - - 专业: - - - - - - - - 100 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - - 位置 - - - - - 设备组 - - - - - 设备名称 - - - - - 挂牌类型 - - - - - 挂牌时间 - - - - - 专业 - - - - - 操作主机 - - - - - 操作人 - - - - - 操作人组 - - - - - 备注信息 - - - - - 标签名 - - - - - - - - - - 总数 - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 刷新 - - - - - - - 取消挂牌 - - - - - - - - - - - - - + + + CHangPanelWidget + + + + 0 + 0 + 800 + 600 + + + + CHangPanelWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 位置: + + + + + + + + 100 + 0 + + + + + + + + 专业: + + + + + + + + 100 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + + 位置 + + + + + 设备组 + + + + + 设备名称 + + + + + 挂牌类型 + + + + + 挂牌时间 + + + + + 专业 + + + + + 操作主机 + + + + + 操作人 + + + + + 操作人组 + + + + + 备注信息 + + + + + 标签名 + + + + + + + + + + 总数 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 刷新 + + + + + + + 取消挂牌 + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelWork.cpp b/product/src/gui/plugin/HangPanelWidget/CHangPanelWork.cpp index a4833f0d..494ec6fa 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelWork.cpp +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelWork.cpp @@ -1,245 +1,245 @@ -#include "CHangPanelWork.h" -#include "Common.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_dbms; -CHangPanelWork::CHangPanelWork(QObject *parent) : QObject(parent) -{ - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); -} - -SDeviceInfo CHangPanelWork::getTagInfoByPointTagName(const QString &tagName) -{ - SDeviceInfo deviceInfo; - return m_mapDeviceInfo.value(tagName,deviceInfo); -} - -int CHangPanelWork::getHangInfoByTagAndType(const QString &tag, int type,SHangPanelInfo &info) -{ - for(int index(0);index vecColumn = {"key_id_tag","token_id","opt_time","location_id","sub_system","device","host_name","user_name","user_group","note"}; - - bRet = m_objRdbNetApi.queryTotal("opt_token_info",vecColumn,objRdbRet); - if(!bRet || objRdbRet.msgrecord_size() < 0) - { - emit sigShowMess(QString("读挂牌信息表失败,请检查网络或主数据库服务器连接是否异常!%1").arg(QString::fromStdString(m_objRdbNetApi.getErr()))); - return false; - } - - for(int i=0;i > tableTagMap = getKeyIdTagMap(); - readKeyIdTagDescListByMap(tableTagMap); -} - -QMap > CHangPanelWork::getKeyIdTagMap() -{ - QMap > tableTagListMap; - for(int index(0);index >::iterator it = tableTagListMap.find(m_listHangPanel[index].table); - if(it != tableTagListMap.end()) - { - it.value().append(m_listHangPanel[index].tagName); - }else - { - QList list; - list.append(m_listHangPanel[index].tagName); - tableTagListMap[m_listHangPanel[index].table] = list; - } - } - return tableTagListMap; -} - -void CHangPanelWork::readKeyIdTagDescListByMap(const QMap > &tableTagMap) -{ - m_mapDeviceInfo.clear(); - QMap >::const_iterator it = tableTagMap.begin(); - while (it != tableTagMap.constEnd()) { - readKeyIdTagDescListByTable(it.key(),it.value()); - it++; - } -} - -void CHangPanelWork::readKeyIdTagDescListByTable(const QString &table, const QList tagList) -{ - if(!m_pReadDb->isOpen()) - { - return ; - - } - QString cond =QString(); - - if(tagList.isEmpty()) - { - return ; - } - for(int index(0);indexexecute(sql,query); - while(query.next()) - { - SDeviceInfo info; - info.tagName = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devName = query.value(2).toString(); - info.devDesc = query.value(3).toString(); - info.devgName = query.value(4).toString(); - info.region = query.value(5).toInt(); - m_mapDeviceInfo[info.tagName] = info; - } -} - -QString CHangPanelWork::getTagNameByKeyIdTag(const QString &keyIdTag) -{ - QStringList temp = keyIdTag.split("."); - QString tagName = QString(); - if(temp.length() < 3) - { - return tagName; - } - tagName = temp.at(1); - for(int index(2);indexopen(); +} + +SDeviceInfo CHangPanelWork::getTagInfoByPointTagName(const QString &tagName) +{ + SDeviceInfo deviceInfo; + return m_mapDeviceInfo.value(tagName,deviceInfo); +} + +int CHangPanelWork::getHangInfoByTagAndType(const QString &tag, int type,SHangPanelInfo &info) +{ + for(int index(0);index vecColumn = {"key_id_tag","token_id","opt_time","location_id","sub_system","device","host_name","user_name","user_group","note"}; + + bRet = m_objRdbNetApi.queryTotal("opt_token_info",vecColumn,objRdbRet); + if(!bRet || objRdbRet.msgrecord_size() < 0) + { + emit sigShowMess(QString("读挂牌信息表失败,请检查网络或主数据库服务器连接是否异常!%1").arg(QString::fromStdString(m_objRdbNetApi.getErr()))); + return false; + } + + for(int i=0;i > tableTagMap = getKeyIdTagMap(); + readKeyIdTagDescListByMap(tableTagMap); +} + +QMap > CHangPanelWork::getKeyIdTagMap() +{ + QMap > tableTagListMap; + for(int index(0);index >::iterator it = tableTagListMap.find(m_listHangPanel[index].table); + if(it != tableTagListMap.end()) + { + it.value().append(m_listHangPanel[index].tagName); + }else + { + QList list; + list.append(m_listHangPanel[index].tagName); + tableTagListMap[m_listHangPanel[index].table] = list; + } + } + return tableTagListMap; +} + +void CHangPanelWork::readKeyIdTagDescListByMap(const QMap > &tableTagMap) +{ + m_mapDeviceInfo.clear(); + QMap >::const_iterator it = tableTagMap.begin(); + while (it != tableTagMap.constEnd()) { + readKeyIdTagDescListByTable(it.key(),it.value()); + it++; + } +} + +void CHangPanelWork::readKeyIdTagDescListByTable(const QString &table, const QList tagList) +{ + if(!m_pReadDb->isOpen()) + { + return ; + + } + QString cond =QString(); + + if(tagList.isEmpty()) + { + return ; + } + for(int index(0);indexexecute(sql,query); + while(query.next()) + { + SDeviceInfo info; + info.tagName = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devName = query.value(2).toString(); + info.devDesc = query.value(3).toString(); + info.devgName = query.value(4).toString(); + info.region = query.value(5).toInt(); + m_mapDeviceInfo[info.tagName] = info; + } +} + +QString CHangPanelWork::getTagNameByKeyIdTag(const QString &keyIdTag) +{ + QStringList temp = keyIdTag.split("."); + QString tagName = QString(); + if(temp.length() < 3) + { + return tagName; + } + tagName = temp.at(1); + for(int index(2);index -#include "dbms/db_api_ex/CDbApi.h" -#include "rdb_net_api/CRdbNetApi.h" -#include "CHangPanelCommon.h" -#include - -class CHangPanelWork : public QObject -{ - Q_OBJECT -public: - explicit CHangPanelWork(QObject *parent = nullptr); - - SDeviceInfo getTagInfoByPointTagName(const QString &tagName); - - int getHangInfoByTagAndType(const QString &tag, int type, SHangPanelInfo &info); - - int getHangeInfoByTag(const QString &tag,SDeviceInfo &info); - - void removeHangInfo(const SHangPanelInfo &info); - -public slots: - - void slotSearch(int domainId,int appid); - -signals: - void sigShowMess(const QString &mess); - - void sigBrush(const QList &optTagInfoList); - -private: - bool readHangPanelInfo(); - - bool readKeyIdTagDesc(); - - void readKeyIdTagDescByTagList(); - - QMap > getKeyIdTagMap(); - - void readKeyIdTagDescListByMap(const QMap > &tableTagMap); - - void readKeyIdTagDescListByTable(const QString &table,const QList tagList); - - QString getTagNameByKeyIdTag(const QString &keyIdTag); - - QString getDeviceNameByKeyIdTag(const QString &keyIdTag); - - QString getTableNameByKeyIdTag(const QString &keyIdTag); - -private: - - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbNetApi m_objRdbNetApi; //< 网络查询对象 - - QList m_listHangPanel; - QMap m_mapDeviceInfo; -}; - -#endif // CHangPanelWork_H +#ifndef CHangPanelWork_H +#define CHangPanelWork_H + +#include +#include "dbms/db_api_ex/CDbApi.h" +#include "rdb_net_api/CRdbNetApi.h" +#include "CHangPanelCommon.h" +#include + +class CHangPanelWork : public QObject +{ + Q_OBJECT +public: + explicit CHangPanelWork(QObject *parent = nullptr); + + SDeviceInfo getTagInfoByPointTagName(const QString &tagName); + + int getHangInfoByTagAndType(const QString &tag, int type, SHangPanelInfo &info); + + int getHangeInfoByTag(const QString &tag,SDeviceInfo &info); + + void removeHangInfo(const SHangPanelInfo &info); + +public slots: + + void slotSearch(int domainId,int appid); + +signals: + void sigShowMess(const QString &mess); + + void sigBrush(const QList &optTagInfoList); + +private: + bool readHangPanelInfo(); + + bool readKeyIdTagDesc(); + + void readKeyIdTagDescByTagList(); + + QMap > getKeyIdTagMap(); + + void readKeyIdTagDescListByMap(const QMap > &tableTagMap); + + void readKeyIdTagDescListByTable(const QString &table,const QList tagList); + + QString getTagNameByKeyIdTag(const QString &keyIdTag); + + QString getDeviceNameByKeyIdTag(const QString &keyIdTag); + + QString getTableNameByKeyIdTag(const QString &keyIdTag); + +private: + + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbNetApi m_objRdbNetApi; //< 网络查询对象 + + QList m_listHangPanel; + QMap m_mapDeviceInfo; +}; + +#endif // CHangPanelWork_H diff --git a/product/src/gui/plugin/HangPanelWidget/HangPanelWidget.pro b/product/src/gui/plugin/HangPanelWidget/HangPanelWidget.pro index 934355cc..7819c270 100644 --- a/product/src/gui/plugin/HangPanelWidget/HangPanelWidget.pro +++ b/product/src/gui/plugin/HangPanelWidget/HangPanelWidget.pro @@ -1,62 +1,62 @@ -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib - -TARGET = HangPanelWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any Qt feature that has been marked deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if it uses deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ -# main.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - CHangPanelWidget.cpp \ - CHangPanelWork.cpp \ - CHangPanelPluginWidget.cpp - -HEADERS += \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - CHangPanelWork.h \ - CHangPanelWidget.h \ - CHangPanelPluginWidget.h \ - CHangPanelCommon.h - -FORMS += \ - CHangPanelWidget.ui - -LIBS += \ - -lprotobuf \ - -ldb_base_api \ - -ldb_api_ex \ - -lnet_msg_bus_api \ - -lpub_sysinfo_api \ - -lperm_mng_api \ - -llog4cplus \ - -lpub_logger_api \ - #-ldp_chg_data_api \ - -lrdb_api \ - -lrdb_net_api \ - -lpub_utility_api \ - -lsys_login_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib + +TARGET = HangPanelWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ +# main.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + CHangPanelWidget.cpp \ + CHangPanelWork.cpp \ + CHangPanelPluginWidget.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CHangPanelWork.h \ + CHangPanelWidget.h \ + CHangPanelPluginWidget.h \ + CHangPanelCommon.h + +FORMS += \ + CHangPanelWidget.ui + +LIBS += \ + -lprotobuf \ + -ldb_base_api \ + -ldb_api_ex \ + -lnet_msg_bus_api \ + -lpub_sysinfo_api \ + -lperm_mng_api \ + -llog4cplus \ + -lpub_logger_api \ + #-ldp_chg_data_api \ + -lrdb_api \ + -lrdb_net_api \ + -lpub_utility_api \ + -lsys_login_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/HangPanelWidget/main.cpp b/product/src/gui/plugin/HangPanelWidget/main.cpp index 1792a498..b17f898f 100644 --- a/product/src/gui/plugin/HangPanelWidget/main.cpp +++ b/product/src/gui/plugin/HangPanelWidget/main.cpp @@ -1,37 +1,37 @@ - -#include - -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "CHangPanelWidget.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - kbd_public::StartLogSystem("HMI", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) - { - //return -1; - } - - { - CHangPanelWidget w(false,NULL); - w.setTagType(0); - w.show(); - a.exec(); - } - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} + +#include + +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "CHangPanelWidget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + kbd_public::StartLogSystem("HMI", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) + { + //return -1; + } + + { + CHangPanelWidget w(false,NULL); + w.setTagType(0); + w.show(); + a.exec(); + } + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/HmiRollWidget/CGroupManageDialog.cpp b/product/src/gui/plugin/HmiRollWidget/CGroupManageDialog.cpp index 78a62702..12816a98 100644 --- a/product/src/gui/plugin/HmiRollWidget/CGroupManageDialog.cpp +++ b/product/src/gui/plugin/HmiRollWidget/CGroupManageDialog.cpp @@ -1,239 +1,239 @@ -#include "CGroupManageDialog.h" -#include -#include -#include -#include -#include -#include -#include -#include - -CGroupManageDialog::CGroupManageDialog(QWidget *parent) - : QDialog(parent) -{ - initWidget(); - resize(300,300); -} - -CGroupManageDialog::~CGroupManageDialog() -{ - -} - -void CGroupManageDialog::setGroup(const QStringList &Group) -{ - m_TableWidget->blockSignals(true); - m_TableWidget->clearContents(); - m_TableWidget->setRowCount(0); - int row = 0; - foreach (QString temp, Group) { - m_TableWidget->insertRow(row); - QTableWidgetItem *item = new QTableWidgetItem(temp); - item->setData(Qt::UserRole, Item_Normal); - item->setData(Qt::UserRole+1, temp); - item->setTextAlignment(Qt::AlignCenter); - m_TableWidget->setItem(row, 0, item); - row += 1; - } - m_TableWidget->blockSignals(false); -} - -QStringList CGroupManageDialog::getGroup() -{ - return m_GroupList; -} - -QStringList CGroupManageDialog::getNormalGroup() -{ - QStringList resultList; - for(int nIndex=0; nIndexrowCount(); nIndex++) - { - Item_Type type = (Item_Type)m_TableWidget->item(nIndex, 0)->data(Qt::UserRole).toInt(); - if(type != Item_Normal) - { - continue; - } - QString text = m_TableWidget->item(nIndex, 0)->text(); - resultList.append(text); - } - return resultList; -} - -QStringList CGroupManageDialog::getNewGroup() -{ - QStringList resultList; - for(int nIndex=0; nIndexrowCount(); nIndex++) - { - Item_Type type = (Item_Type)m_TableWidget->item(nIndex, 0)->data(Qt::UserRole).toInt(); - if(type != Item_New) - { - continue; - } - QString text = m_TableWidget->item(nIndex, 0)->text(); - resultList.append(text); - } - return resultList; -} - -QMap CGroupManageDialog::getModifyGroup() -{ - QMap resultMap; - for(int nIndex=0; nIndexrowCount(); nIndex++) - { - Item_Type type = (Item_Type)m_TableWidget->item(nIndex, 0)->data(Qt::UserRole).toInt(); - if(type != Item_Modify) - { - continue; - } - QString now = m_TableWidget->item(nIndex, 0)->text(); - QString before = m_TableWidget->item(nIndex, 0)->data(Qt::UserRole+1).toString(); - resultMap.insert(now, before); - } - return resultMap; -} - -void CGroupManageDialog::initWidget() -{ - setWindowTitle(tr("轮询组配置")); - - QPushButton * Add = new QPushButton(tr("新增"), this); - connect(Add, &QPushButton::clicked, this, &CGroupManageDialog::slotAddGroup); - - QPushButton * Del = new QPushButton(tr("删除"), this); - connect(Del, &QPushButton::clicked, this, &CGroupManageDialog::slotDelGroup); - - QPushButton * Save = new QPushButton(tr("保存"), this); - connect(Save, &QPushButton::clicked, this, &CGroupManageDialog::slotSaveGroup); - - m_TableWidget = new QTableWidget(this); - m_TableWidget->setColumnCount(1); - m_TableWidget->setHorizontalHeaderLabels(QStringList() << tr("轮询组")); - m_TableWidget->setSelectionMode(QAbstractItemView::SingleSelection); - m_TableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - m_TableWidget->horizontalHeader()->setStretchLastSection(true); - connect(m_TableWidget, &QTableWidget::itemChanged, this, &CGroupManageDialog::slotItemChanged); -// CTableDelegate *delegate = new CTableDelegate(this); -// m_TableWidget->setItemDelegate(delegate); - - QHBoxLayout * hLayout = new QHBoxLayout(); - hLayout->addWidget(Add); - hLayout->addWidget(Del); - QSpacerItem * spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding); - hLayout->addSpacerItem(spacer); - - QHBoxLayout * sLayout = new QHBoxLayout(); - QSpacerItem * item1 = new QSpacerItem(0, 0, QSizePolicy::Expanding); - QSpacerItem * item2 = new QSpacerItem(0, 0, QSizePolicy::Expanding); - sLayout->addSpacerItem(item1); - sLayout->addWidget(Save); - sLayout->addSpacerItem(item2); - - QVBoxLayout * vLayout = new QVBoxLayout(this); - vLayout->addLayout(hLayout); - vLayout->addWidget(m_TableWidget); - vLayout->addLayout(sLayout); - setLayout(vLayout); -} - -void CGroupManageDialog::showInfo(const QString &info) -{ - QMessageBox::information(this, tr("提示"), info, QMessageBox::Ok); -} - -void CGroupManageDialog::slotAddGroup() -{ - int addRow = m_TableWidget->rowCount(); - m_TableWidget->insertRow(addRow); - QTableWidgetItem *item = new QTableWidgetItem(""); - item->setData(Qt::UserRole, Item_New); - item->setTextAlignment(Qt::AlignCenter); - m_TableWidget->setItem(addRow, 0, item); -} - -void CGroupManageDialog::slotDelGroup() -{ - int delRow = m_TableWidget->currentRow(); - if(delRow >= 0) - { - m_TableWidget->removeRow(delRow); - } -} - -void CGroupManageDialog::slotSaveGroup() -{ - m_GroupList.clear(); - for(int nIndex=0; nIndexrowCount(); nIndex++) - { - QString text = m_TableWidget->item(nIndex, 0)->text(); - if(text.isEmpty()) - { - showInfo(tr("轮询组不能为空!")); - return; - } - QRegExp exp("^([A-Za-z]|[0-9]|\\w)+$"); - if(!exp.exactMatch(text)) - { - showInfo(tr("轮询组不能有特殊符号!")); - return; - } - if(m_GroupList.indexOf(text) != -1) - { - showInfo(tr("轮询组不能重复!")); - return; - } - m_GroupList.append(text); - } - accept(); -} - -void CGroupManageDialog::slotItemChanged(QTableWidgetItem *item) -{ - if(!item) - { - return; - } - - if(Item_New == item->data(Qt::UserRole)) - { - return; - } - - item->setData(Qt::UserRole, Item_Modify); -} - -void CGroupManageDialog::contextMenuEvent(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - QMenu menu; - QAction *Add = menu.addAction(tr("新增")); - connect(Add, &QAction::triggered, this, &CGroupManageDialog::slotAddGroup); - QAction *Del = menu.addAction(tr("删除")); - connect(Del, &QAction::triggered, this, &CGroupManageDialog::slotDelGroup); - menu.exec(event->globalPos()); -} - - -CTableDelegate::CTableDelegate(QObject *parent) - : QStyledItemDelegate(parent) -{ - -} - -QWidget *CTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - if(Item_New != index.data(Qt::UserRole).toInt()) - { - return NULL; - } - return QStyledItemDelegate::createEditor(parent, option, index); -} - -void CTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - return QStyledItemDelegate::setEditorData(editor, index); -} - -void CTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - return QStyledItemDelegate::setModelData(editor, model, index); -} +#include "CGroupManageDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include + +CGroupManageDialog::CGroupManageDialog(QWidget *parent) + : QDialog(parent) +{ + initWidget(); + resize(300,300); +} + +CGroupManageDialog::~CGroupManageDialog() +{ + +} + +void CGroupManageDialog::setGroup(const QStringList &Group) +{ + m_TableWidget->blockSignals(true); + m_TableWidget->clearContents(); + m_TableWidget->setRowCount(0); + int row = 0; + foreach (QString temp, Group) { + m_TableWidget->insertRow(row); + QTableWidgetItem *item = new QTableWidgetItem(temp); + item->setData(Qt::UserRole, Item_Normal); + item->setData(Qt::UserRole+1, temp); + item->setTextAlignment(Qt::AlignCenter); + m_TableWidget->setItem(row, 0, item); + row += 1; + } + m_TableWidget->blockSignals(false); +} + +QStringList CGroupManageDialog::getGroup() +{ + return m_GroupList; +} + +QStringList CGroupManageDialog::getNormalGroup() +{ + QStringList resultList; + for(int nIndex=0; nIndexrowCount(); nIndex++) + { + Item_Type type = (Item_Type)m_TableWidget->item(nIndex, 0)->data(Qt::UserRole).toInt(); + if(type != Item_Normal) + { + continue; + } + QString text = m_TableWidget->item(nIndex, 0)->text(); + resultList.append(text); + } + return resultList; +} + +QStringList CGroupManageDialog::getNewGroup() +{ + QStringList resultList; + for(int nIndex=0; nIndexrowCount(); nIndex++) + { + Item_Type type = (Item_Type)m_TableWidget->item(nIndex, 0)->data(Qt::UserRole).toInt(); + if(type != Item_New) + { + continue; + } + QString text = m_TableWidget->item(nIndex, 0)->text(); + resultList.append(text); + } + return resultList; +} + +QMap CGroupManageDialog::getModifyGroup() +{ + QMap resultMap; + for(int nIndex=0; nIndexrowCount(); nIndex++) + { + Item_Type type = (Item_Type)m_TableWidget->item(nIndex, 0)->data(Qt::UserRole).toInt(); + if(type != Item_Modify) + { + continue; + } + QString now = m_TableWidget->item(nIndex, 0)->text(); + QString before = m_TableWidget->item(nIndex, 0)->data(Qt::UserRole+1).toString(); + resultMap.insert(now, before); + } + return resultMap; +} + +void CGroupManageDialog::initWidget() +{ + setWindowTitle(tr("轮询组配置")); + + QPushButton * Add = new QPushButton(tr("新增"), this); + connect(Add, &QPushButton::clicked, this, &CGroupManageDialog::slotAddGroup); + + QPushButton * Del = new QPushButton(tr("删除"), this); + connect(Del, &QPushButton::clicked, this, &CGroupManageDialog::slotDelGroup); + + QPushButton * Save = new QPushButton(tr("保存"), this); + connect(Save, &QPushButton::clicked, this, &CGroupManageDialog::slotSaveGroup); + + m_TableWidget = new QTableWidget(this); + m_TableWidget->setColumnCount(1); + m_TableWidget->setHorizontalHeaderLabels(QStringList() << tr("轮询组")); + m_TableWidget->setSelectionMode(QAbstractItemView::SingleSelection); + m_TableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + m_TableWidget->horizontalHeader()->setStretchLastSection(true); + connect(m_TableWidget, &QTableWidget::itemChanged, this, &CGroupManageDialog::slotItemChanged); +// CTableDelegate *delegate = new CTableDelegate(this); +// m_TableWidget->setItemDelegate(delegate); + + QHBoxLayout * hLayout = new QHBoxLayout(); + hLayout->addWidget(Add); + hLayout->addWidget(Del); + QSpacerItem * spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding); + hLayout->addSpacerItem(spacer); + + QHBoxLayout * sLayout = new QHBoxLayout(); + QSpacerItem * item1 = new QSpacerItem(0, 0, QSizePolicy::Expanding); + QSpacerItem * item2 = new QSpacerItem(0, 0, QSizePolicy::Expanding); + sLayout->addSpacerItem(item1); + sLayout->addWidget(Save); + sLayout->addSpacerItem(item2); + + QVBoxLayout * vLayout = new QVBoxLayout(this); + vLayout->addLayout(hLayout); + vLayout->addWidget(m_TableWidget); + vLayout->addLayout(sLayout); + setLayout(vLayout); +} + +void CGroupManageDialog::showInfo(const QString &info) +{ + QMessageBox::information(this, tr("提示"), info, QMessageBox::Ok); +} + +void CGroupManageDialog::slotAddGroup() +{ + int addRow = m_TableWidget->rowCount(); + m_TableWidget->insertRow(addRow); + QTableWidgetItem *item = new QTableWidgetItem(""); + item->setData(Qt::UserRole, Item_New); + item->setTextAlignment(Qt::AlignCenter); + m_TableWidget->setItem(addRow, 0, item); +} + +void CGroupManageDialog::slotDelGroup() +{ + int delRow = m_TableWidget->currentRow(); + if(delRow >= 0) + { + m_TableWidget->removeRow(delRow); + } +} + +void CGroupManageDialog::slotSaveGroup() +{ + m_GroupList.clear(); + for(int nIndex=0; nIndexrowCount(); nIndex++) + { + QString text = m_TableWidget->item(nIndex, 0)->text(); + if(text.isEmpty()) + { + showInfo(tr("轮询组不能为空!")); + return; + } + QRegExp exp("^([A-Za-z]|[0-9]|\\w)+$"); + if(!exp.exactMatch(text)) + { + showInfo(tr("轮询组不能有特殊符号!")); + return; + } + if(m_GroupList.indexOf(text) != -1) + { + showInfo(tr("轮询组不能重复!")); + return; + } + m_GroupList.append(text); + } + accept(); +} + +void CGroupManageDialog::slotItemChanged(QTableWidgetItem *item) +{ + if(!item) + { + return; + } + + if(Item_New == item->data(Qt::UserRole)) + { + return; + } + + item->setData(Qt::UserRole, Item_Modify); +} + +void CGroupManageDialog::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + QMenu menu; + QAction *Add = menu.addAction(tr("新增")); + connect(Add, &QAction::triggered, this, &CGroupManageDialog::slotAddGroup); + QAction *Del = menu.addAction(tr("删除")); + connect(Del, &QAction::triggered, this, &CGroupManageDialog::slotDelGroup); + menu.exec(event->globalPos()); +} + + +CTableDelegate::CTableDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ + +} + +QWidget *CTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(Item_New != index.data(Qt::UserRole).toInt()) + { + return NULL; + } + return QStyledItemDelegate::createEditor(parent, option, index); +} + +void CTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + return QStyledItemDelegate::setEditorData(editor, index); +} + +void CTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + return QStyledItemDelegate::setModelData(editor, model, index); +} diff --git a/product/src/gui/plugin/HmiRollWidget/CGroupManageDialog.h b/product/src/gui/plugin/HmiRollWidget/CGroupManageDialog.h index 80d3f1f9..df234eee 100644 --- a/product/src/gui/plugin/HmiRollWidget/CGroupManageDialog.h +++ b/product/src/gui/plugin/HmiRollWidget/CGroupManageDialog.h @@ -1,58 +1,58 @@ -#ifndef CGROUPMANAGEDIALOG_H -#define CGROUPMANAGEDIALOG_H - -#include -#include -#include -#include - -enum Item_Type{ - Item_Normal = 0, - Item_New, - Item_Modify, -}; - -class CGroupManageDialog : public QDialog -{ - Q_OBJECT -public: - CGroupManageDialog(QWidget *parent = 0); - ~CGroupManageDialog(); - - void setGroup(const QStringList &Group); - QStringList getGroup(); - QStringList getNormalGroup(); - QStringList getNewGroup(); - QMap getModifyGroup(); - -private: - void initWidget(); - void showInfo(const QString &info); - -private slots: - void slotAddGroup(); - void slotDelGroup(); - void slotSaveGroup(); - void slotItemChanged(QTableWidgetItem *item); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - -private: - QTableWidget * m_TableWidget; - QStringList m_GroupList; -}; - -class CTableDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CTableDelegate(QObject *parent = 0); - - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; - - void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE; -}; - -#endif // CGROUPMANAGEDIALOG_H +#ifndef CGROUPMANAGEDIALOG_H +#define CGROUPMANAGEDIALOG_H + +#include +#include +#include +#include + +enum Item_Type{ + Item_Normal = 0, + Item_New, + Item_Modify, +}; + +class CGroupManageDialog : public QDialog +{ + Q_OBJECT +public: + CGroupManageDialog(QWidget *parent = 0); + ~CGroupManageDialog(); + + void setGroup(const QStringList &Group); + QStringList getGroup(); + QStringList getNormalGroup(); + QStringList getNewGroup(); + QMap getModifyGroup(); + +private: + void initWidget(); + void showInfo(const QString &info); + +private slots: + void slotAddGroup(); + void slotDelGroup(); + void slotSaveGroup(); + void slotItemChanged(QTableWidgetItem *item); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +private: + QTableWidget * m_TableWidget; + QStringList m_GroupList; +}; + +class CTableDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CTableDelegate(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE; +}; + +#endif // CGROUPMANAGEDIALOG_H diff --git a/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.cpp b/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.cpp index 7a423e8b..d7a2bb25 100644 --- a/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.cpp +++ b/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.cpp @@ -1,26 +1,26 @@ -#include "CHmiRollPlugin.h" -#include "CHmiRollWidget.h" -#include - -CHmiRollPlugin::CHmiRollPlugin(QObject *parent) : QObject(parent) -{ - -} - -CHmiRollPlugin::~CHmiRollPlugin() -{ - -} - -bool CHmiRollPlugin::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CHmiRollWidget *pWidget = new CHmiRollWidget(editMode, ptrVec, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CHmiRollPlugin::release() -{ - -} +#include "CHmiRollPlugin.h" +#include "CHmiRollWidget.h" +#include + +CHmiRollPlugin::CHmiRollPlugin(QObject *parent) : QObject(parent) +{ + +} + +CHmiRollPlugin::~CHmiRollPlugin() +{ + +} + +bool CHmiRollPlugin::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CHmiRollWidget *pWidget = new CHmiRollWidget(editMode, ptrVec, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CHmiRollPlugin::release() +{ + +} diff --git a/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.h b/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.h index d9aaae1f..10538500 100644 --- a/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.h +++ b/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.h @@ -1,21 +1,21 @@ -#ifndef CHMIROLLPLUGIN_H -#define CHMIROLLPLUGIN_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CHmiRollPlugin : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CHmiRollPlugin(QObject *parent = 0); - ~CHmiRollPlugin(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CHMIROLLPLUGIN_H +#ifndef CHMIROLLPLUGIN_H +#define CHMIROLLPLUGIN_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CHmiRollPlugin : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CHmiRollPlugin(QObject *parent = 0); + ~CHmiRollPlugin(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CHMIROLLPLUGIN_H diff --git a/product/src/gui/plugin/HmiRollWidget/CHmiRollWidget.cpp b/product/src/gui/plugin/HmiRollWidget/CHmiRollWidget.cpp index 73a4bce0..7297c580 100644 --- a/product/src/gui/plugin/HmiRollWidget/CHmiRollWidget.cpp +++ b/product/src/gui/plugin/HmiRollWidget/CHmiRollWidget.cpp @@ -1,157 +1,157 @@ -#include "CHmiRollWidget.h" -#include "ConfigWidget.h" -#include "CRollSwitchWidget.h" -#include -#include -#include -#include -#include "CXmlOpt.h" -#include "pub_utility_api/FileStyle.h" - -CHmiRollWidget::CHmiRollWidget(bool editMode, QVector ptrVec, QWidget *parent) - : QWidget(parent), - m_rollSwitchWidget(Q_NULLPTR), - m_configWidget(Q_NULLPTR) -{ - Q_UNUSED(ptrVec) - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("hmiRoll.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - if(editMode){ - initialize(E_ConfigMode); - } -} - -CHmiRollWidget::~CHmiRollWidget() -{ - if(m_rollSwitchWidget) - { - delete m_rollSwitchWidget; - } - m_rollSwitchWidget = NULL; - - if(m_configWidget) - { - delete m_configWidget; - } - m_configWidget = NULL; -} - -void CHmiRollWidget::initialize(int mode) -{ - switch (mode) { - case E_AutoMode: - { - break; - } - case E_SwitchMode: - { - QGridLayout *layout = new QGridLayout(this); - QGridLayout *layout1 = new QGridLayout(this); - QFrame *frame = new QFrame(this); - m_rollSwitchWidget = new CRollSwitchWidget(this); - connect(m_rollSwitchWidget, &CRollSwitchWidget::sigAutoRoll, this, &CHmiRollWidget::sigAutoRoll); - connect(m_rollSwitchWidget, &CRollSwitchWidget::sigStartRoll, this, &CHmiRollWidget::sigStartRoll); - connect(m_rollSwitchWidget, &CRollSwitchWidget::sigStopRoll, this, &CHmiRollWidget::sigStopRoll); - connect(m_rollSwitchWidget, &CRollSwitchWidget::sigClose, this, &CHmiRollWidget::sigClose); - layout->addWidget(m_rollSwitchWidget); - frame->setLayout(layout); - layout1->addWidget(frame); - layout1->setContentsMargins(0,0,0,0); - setLayout(layout1); - this->setContentsMargins(0,0,0,0); - break; - } - case E_ConfigMode: - { - QGridLayout *layout = new QGridLayout(this); - QGridLayout *layout1 = new QGridLayout(this); - QFrame *frame = new QFrame(this); - m_configWidget = new ConfigWidget(this); - m_configWidget->setContentsMargins(0,0,0,0); - connect(m_configWidget, &ConfigWidget::sigSave, this, &CHmiRollWidget::sigSave); - layout->addWidget(m_configWidget); - layout->setContentsMargins(0,0,0,0); - frame->setLayout(layout); - layout1->addWidget(frame); - layout1->setContentsMargins(0,0,0,0); - setLayout(layout1); - this->setContentsMargins(0,0,0,0); - break; - } - default: - break; - } -} - -QVariantList CHmiRollWidget::readScreenRoll(int screen) -{ - QPair info; - bool ret = CXmlOpt::readScreenRoll(screen, info); - if(ret){ - QVariantList Group; - Group.append(info.first); - Group.append(QVariant::fromValue(info.second)); - return Group; - }else{ - return QVariantList(); - } -} - -QVariantList CHmiRollWidget::readGraphRoll(const QString &group) -{ - QList info; - bool ret = CXmlOpt::readGraphRoll(group, info); - if(ret){ - QVariantList list; - foreach (SGraph graph, info) { - if(graph.enable == 0) - { - continue; - } - list.append(graph.pic); - list.append(QVariant::fromValue(graph.interval)); - } - return list; - }else{ - return QVariantList(); - } -} - -void CHmiRollWidget::setRollInfo(bool isAuto, bool isStart, const QString &Group, int interval, int screen) -{ - if(m_rollSwitchWidget) - { - m_rollSwitchWidget->setRollInfo(isAuto, isStart, Group, interval, screen); - } -} - -void CHmiRollWidget::hmiSwitchOpt() -{ - if(m_configWidget) - { - m_configWidget->hmiSwitchOpt(); - } -} +#include "CHmiRollWidget.h" +#include "ConfigWidget.h" +#include "CRollSwitchWidget.h" +#include +#include +#include +#include +#include "CXmlOpt.h" +#include "pub_utility_api/FileStyle.h" + +CHmiRollWidget::CHmiRollWidget(bool editMode, QVector ptrVec, QWidget *parent) + : QWidget(parent), + m_rollSwitchWidget(Q_NULLPTR), + m_configWidget(Q_NULLPTR) +{ + Q_UNUSED(ptrVec) + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("hmiRoll.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + if(editMode){ + initialize(E_ConfigMode); + } +} + +CHmiRollWidget::~CHmiRollWidget() +{ + if(m_rollSwitchWidget) + { + delete m_rollSwitchWidget; + } + m_rollSwitchWidget = NULL; + + if(m_configWidget) + { + delete m_configWidget; + } + m_configWidget = NULL; +} + +void CHmiRollWidget::initialize(int mode) +{ + switch (mode) { + case E_AutoMode: + { + break; + } + case E_SwitchMode: + { + QGridLayout *layout = new QGridLayout(this); + QGridLayout *layout1 = new QGridLayout(this); + QFrame *frame = new QFrame(this); + m_rollSwitchWidget = new CRollSwitchWidget(this); + connect(m_rollSwitchWidget, &CRollSwitchWidget::sigAutoRoll, this, &CHmiRollWidget::sigAutoRoll); + connect(m_rollSwitchWidget, &CRollSwitchWidget::sigStartRoll, this, &CHmiRollWidget::sigStartRoll); + connect(m_rollSwitchWidget, &CRollSwitchWidget::sigStopRoll, this, &CHmiRollWidget::sigStopRoll); + connect(m_rollSwitchWidget, &CRollSwitchWidget::sigClose, this, &CHmiRollWidget::sigClose); + layout->addWidget(m_rollSwitchWidget); + frame->setLayout(layout); + layout1->addWidget(frame); + layout1->setContentsMargins(0,0,0,0); + setLayout(layout1); + this->setContentsMargins(0,0,0,0); + break; + } + case E_ConfigMode: + { + QGridLayout *layout = new QGridLayout(this); + QGridLayout *layout1 = new QGridLayout(this); + QFrame *frame = new QFrame(this); + m_configWidget = new ConfigWidget(this); + m_configWidget->setContentsMargins(0,0,0,0); + connect(m_configWidget, &ConfigWidget::sigSave, this, &CHmiRollWidget::sigSave); + layout->addWidget(m_configWidget); + layout->setContentsMargins(0,0,0,0); + frame->setLayout(layout); + layout1->addWidget(frame); + layout1->setContentsMargins(0,0,0,0); + setLayout(layout1); + this->setContentsMargins(0,0,0,0); + break; + } + default: + break; + } +} + +QVariantList CHmiRollWidget::readScreenRoll(int screen) +{ + QPair info; + bool ret = CXmlOpt::readScreenRoll(screen, info); + if(ret){ + QVariantList Group; + Group.append(info.first); + Group.append(QVariant::fromValue(info.second)); + return Group; + }else{ + return QVariantList(); + } +} + +QVariantList CHmiRollWidget::readGraphRoll(const QString &group) +{ + QList info; + bool ret = CXmlOpt::readGraphRoll(group, info); + if(ret){ + QVariantList list; + foreach (SGraph graph, info) { + if(graph.enable == 0) + { + continue; + } + list.append(graph.pic); + list.append(QVariant::fromValue(graph.interval)); + } + return list; + }else{ + return QVariantList(); + } +} + +void CHmiRollWidget::setRollInfo(bool isAuto, bool isStart, const QString &Group, int interval, int screen) +{ + if(m_rollSwitchWidget) + { + m_rollSwitchWidget->setRollInfo(isAuto, isStart, Group, interval, screen); + } +} + +void CHmiRollWidget::hmiSwitchOpt() +{ + if(m_configWidget) + { + m_configWidget->hmiSwitchOpt(); + } +} diff --git a/product/src/gui/plugin/HmiRollWidget/CHmiRollWidget.h b/product/src/gui/plugin/HmiRollWidget/CHmiRollWidget.h index b51f41d7..333343eb 100644 --- a/product/src/gui/plugin/HmiRollWidget/CHmiRollWidget.h +++ b/product/src/gui/plugin/HmiRollWidget/CHmiRollWidget.h @@ -1,45 +1,45 @@ -#ifndef CHMIROLLWIDGET_H -#define CHMIROLLWIDGET_H - -#include -#include -enum E_Mode{ - E_AutoMode = 0, - E_SwitchMode, - E_ConfigMode -}; - -class CRollSwitchWidget; -class ConfigWidget; -class CHmiRollWidget : public QWidget -{ - Q_OBJECT - -public: - CHmiRollWidget(bool editMode, QVector ptrVec, QWidget *parent = 0); - ~CHmiRollWidget(); - -signals: - void sigAutoRoll(bool Auto, const QString &Group, int delay); - void sigStartRoll(const QString &Group); - void sigStopRoll(); - void sigSave(const QString &modify, const QString &del); - void sigClose(); - -public slots: - void initialize(int mode); - - QVariantList readScreenRoll(int screen); - - QVariantList readGraphRoll(const QString &group); - - void setRollInfo(bool isAuto, bool isStart, const QString &Group, int interval, int screen); - - void hmiSwitchOpt(); - -private: - CRollSwitchWidget * m_rollSwitchWidget; - ConfigWidget * m_configWidget; -}; - -#endif // CHMIROLLWIDGET_H +#ifndef CHMIROLLWIDGET_H +#define CHMIROLLWIDGET_H + +#include +#include +enum E_Mode{ + E_AutoMode = 0, + E_SwitchMode, + E_ConfigMode +}; + +class CRollSwitchWidget; +class ConfigWidget; +class CHmiRollWidget : public QWidget +{ + Q_OBJECT + +public: + CHmiRollWidget(bool editMode, QVector ptrVec, QWidget *parent = 0); + ~CHmiRollWidget(); + +signals: + void sigAutoRoll(bool Auto, const QString &Group, int delay); + void sigStartRoll(const QString &Group); + void sigStopRoll(); + void sigSave(const QString &modify, const QString &del); + void sigClose(); + +public slots: + void initialize(int mode); + + QVariantList readScreenRoll(int screen); + + QVariantList readGraphRoll(const QString &group); + + void setRollInfo(bool isAuto, bool isStart, const QString &Group, int interval, int screen); + + void hmiSwitchOpt(); + +private: + CRollSwitchWidget * m_rollSwitchWidget; + ConfigWidget * m_configWidget; +}; + +#endif // CHMIROLLWIDGET_H diff --git a/product/src/gui/plugin/HmiRollWidget/CLineEditWithBtn.cpp b/product/src/gui/plugin/HmiRollWidget/CLineEditWithBtn.cpp index 490eb3d6..cc17f7f1 100644 --- a/product/src/gui/plugin/HmiRollWidget/CLineEditWithBtn.cpp +++ b/product/src/gui/plugin/HmiRollWidget/CLineEditWithBtn.cpp @@ -1,76 +1,76 @@ -#include "CLineEditWithBtn.h" -#include -#include -#include - -CLineEditWithBtn::CLineEditWithBtn(QWidget *parent) - :QWidget(parent) -{ - QHBoxLayout *layout = new QHBoxLayout(this); - m_edit = new QLineEdit(this); - m_edit->installEventFilter(this); - m_button = new QToolButton(this); - m_button->setText("..."); - m_button->setFixedSize(21,21); - layout->addWidget(m_edit); - layout->addWidget(m_button); - layout->setMargin(0); - layout->setSpacing(0); - this->setLayout(layout); - - connect(m_button, SIGNAL(clicked()), this, SLOT(getFilePath())); -} - -CLineEditWithBtn::~CLineEditWithBtn() -{ - -} - -QString CLineEditWithBtn::text() -{ - return m_edit->text(); -} - -void CLineEditWithBtn::setText(const QString &text) -{ - m_edit->setText(text); -} - -void CLineEditWithBtn::getFilePath() -{ - QFileDialog *dialog = new QFileDialog(this, tr("选择文件"), "../../data/pic", "*.glx"); -// dialog->setWindowFlag(Qt::WindowDoesNotAcceptFocus); - dialog->setOption(QFileDialog::DontUseNativeDialog); - dialog->setAttribute(Qt::WA_DeleteOnClose); - dialog->setReadOnly(true); - connect(dialog, SIGNAL(fileSelected(QString)), this, SLOT(setFilePath(QString))); - dialog->show(); -} - -void CLineEditWithBtn::setFilePath(const QString &name) -{ - if(name != QString()) - { - QDir dir("../../data/pic"); - - setText(dir.relativeFilePath(name)); - } -} - -bool CLineEditWithBtn::eventFilter(QObject *watched, QEvent *event) -{ - if(watched == m_edit) - { - if (event->type() == QEvent::FocusOut) - { - this->setFocus(); - return true; - } - else - { - return false; - } - } - - return QWidget::eventFilter(watched, event); -} +#include "CLineEditWithBtn.h" +#include +#include +#include + +CLineEditWithBtn::CLineEditWithBtn(QWidget *parent) + :QWidget(parent) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + m_edit = new QLineEdit(this); + m_edit->installEventFilter(this); + m_button = new QToolButton(this); + m_button->setText("..."); + m_button->setFixedSize(21,21); + layout->addWidget(m_edit); + layout->addWidget(m_button); + layout->setMargin(0); + layout->setSpacing(0); + this->setLayout(layout); + + connect(m_button, SIGNAL(clicked()), this, SLOT(getFilePath())); +} + +CLineEditWithBtn::~CLineEditWithBtn() +{ + +} + +QString CLineEditWithBtn::text() +{ + return m_edit->text(); +} + +void CLineEditWithBtn::setText(const QString &text) +{ + m_edit->setText(text); +} + +void CLineEditWithBtn::getFilePath() +{ + QFileDialog *dialog = new QFileDialog(this, tr("选择文件"), "../../data/pic", "*.glx"); +// dialog->setWindowFlag(Qt::WindowDoesNotAcceptFocus); + dialog->setOption(QFileDialog::DontUseNativeDialog); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setReadOnly(true); + connect(dialog, SIGNAL(fileSelected(QString)), this, SLOT(setFilePath(QString))); + dialog->show(); +} + +void CLineEditWithBtn::setFilePath(const QString &name) +{ + if(name != QString()) + { + QDir dir("../../data/pic"); + + setText(dir.relativeFilePath(name)); + } +} + +bool CLineEditWithBtn::eventFilter(QObject *watched, QEvent *event) +{ + if(watched == m_edit) + { + if (event->type() == QEvent::FocusOut) + { + this->setFocus(); + return true; + } + else + { + return false; + } + } + + return QWidget::eventFilter(watched, event); +} diff --git a/product/src/gui/plugin/HmiRollWidget/CLineEditWithBtn.h b/product/src/gui/plugin/HmiRollWidget/CLineEditWithBtn.h index d2dc8b93..e7608ca3 100644 --- a/product/src/gui/plugin/HmiRollWidget/CLineEditWithBtn.h +++ b/product/src/gui/plugin/HmiRollWidget/CLineEditWithBtn.h @@ -1,31 +1,31 @@ -#ifndef CLINEEDITWITHBTN_H -#define CLINEEDITWITHBTN_H - -#include -#include -#include -#include - -class CLineEditWithBtn : public QWidget -{ - Q_OBJECT -public: - CLineEditWithBtn(QWidget *parent = 0); - ~CLineEditWithBtn(); - - void setText(const QString &text); - QString text(); - -protected: - bool eventFilter(QObject *watched, QEvent *event); - -private slots: - void getFilePath(); - void setFilePath(const QString& name); - -private: - QLineEdit *m_edit; - QToolButton *m_button; -}; - -#endif // CLINEEDITWITHBTN_H +#ifndef CLINEEDITWITHBTN_H +#define CLINEEDITWITHBTN_H + +#include +#include +#include +#include + +class CLineEditWithBtn : public QWidget +{ + Q_OBJECT +public: + CLineEditWithBtn(QWidget *parent = 0); + ~CLineEditWithBtn(); + + void setText(const QString &text); + QString text(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private slots: + void getFilePath(); + void setFilePath(const QString& name); + +private: + QLineEdit *m_edit; + QToolButton *m_button; +}; + +#endif // CLINEEDITWITHBTN_H diff --git a/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.cpp b/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.cpp index ba5d3c95..8d8e858c 100644 --- a/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.cpp +++ b/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.cpp @@ -1,229 +1,229 @@ -#include "CRollSwitchWidget.h" -#include -#include -#include -#include - -CRollSwitchWidget::CRollSwitchWidget(QWidget *parent) - : QWidget(parent) -{ - initWidget(); - initGroup(); -} - -CRollSwitchWidget::~CRollSwitchWidget() -{ - m_GroupList.clear(); - m_hmiRollMap.clear(); - m_screenMap.clear(); - m_autoTimeMap.clear(); -} - -void CRollSwitchWidget::setRollInfo(bool isAuto, bool isStart, const QString &Group, int interval, int screen) -{ - m_nScreen = screen; - int index = m_GroupComb->findText(Group); - if(index >= 0){ - m_GroupComb->setCurrentIndex(index); - } - - if(isAuto){ - resetView(E_AUTO); - m_timeSpin->setValue(interval); - }else{ - if(isStart){ - resetView(E_START); - }else{ - resetView(E_STOP); - } - m_timeSpin->setValue(m_autoTimeMap.value(m_nScreen, 15)); - } -} - -void CRollSwitchWidget::initWidget() -{ - QLabel *label = new QLabel(tr("播放组"), this); - - m_GroupComb = new QComboBox(this); - m_GroupComb->setView(new QListView()); - m_GroupComb->setMinimumWidth(120); - connect(m_GroupComb, &QComboBox::currentTextChanged, this, &CRollSwitchWidget::slotGroupCombChange); - - m_TableWidget = new QTableWidget(this); - m_TableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - m_TableWidget->setColumnCount(2); - m_TableWidget->setHorizontalHeaderLabels(QStringList() << tr("画面文件名称") << tr("画面轮询间隔(s)")); - m_TableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - m_TableWidget->horizontalHeader()->setStretchLastSection(true); - m_TableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - - m_autoCheckBox = new QCheckBox(tr("自动轮询(设定的时间内,未检测到键鼠操作,自动轮询播放画面)"), this); - connect(m_autoCheckBox, &QCheckBox::clicked, this, &CRollSwitchWidget::slotAutoPlayClick); - - m_startBtn = new QPushButton(tr("开始"), this); - connect(m_startBtn, &QPushButton::clicked, this, &CRollSwitchWidget::slotStartClick); - - m_stopBtn = new QPushButton(tr("停止"), this); - connect(m_stopBtn, &QPushButton::clicked, this, &CRollSwitchWidget::slotStopClick); - m_stopBtn->setVisible(false); - - m_confirmBtn = new QPushButton(tr("关闭"), this); - connect(m_confirmBtn, &QPushButton::clicked, this, &CRollSwitchWidget::slotConfirmClick); - m_confirmBtn->setVisible(false); - - QLabel *label1 = new QLabel(tr("轮询时间(s)"), this); - label1->setObjectName("autoTime"); - m_timeSpin = new QSpinBox(this); - m_timeSpin->setMaximum(9999); - m_timeSpin->setMaximumWidth(80); //宽度调整 - m_timeSpin->setMinimum(15); - m_timeSpin->setValue(15); - - QHBoxLayout *hLayout = new QHBoxLayout(); - hLayout->addWidget(label); - hLayout->addWidget(m_GroupComb); - - hLayout->addWidget(m_startBtn); - hLayout->addWidget(m_stopBtn); - hLayout->addWidget(m_confirmBtn); - - QHBoxLayout *cLayout = new QHBoxLayout(); - cLayout->addWidget(m_autoCheckBox); - QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding); - cLayout->addSpacerItem(item); - cLayout->addWidget(label1); - cLayout->addWidget(m_timeSpin); - - QGridLayout *gLayout = new QGridLayout(this); - gLayout->addLayout(hLayout, 0, 0, 1, 1); - gLayout->addWidget(m_TableWidget, 1, 0, 1, 3); - gLayout->addLayout(cLayout, 2, 0, 1, 3); - - setLayout(gLayout); -} - -void CRollSwitchWidget::initGroup() -{ - m_GroupList.clear(); - m_hmiRollMap.clear(); - m_screenMap.clear(); - m_autoTimeMap.clear(); - m_GroupComb->clear(); - - CXmlOpt::readHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap); - foreach (QString group, m_GroupList) { - m_GroupComb->addItem(group); - } -} - -void CRollSwitchWidget::slotGroupCombChange(const QString &text) -{ - m_TableWidget->clearContents(); - m_TableWidget->setRowCount(0); - QList graphList = m_hmiRollMap.value(text); - int row = 0; - foreach (SGraph graph, graphList) { - if(graph.enable == 0) - continue; - m_TableWidget->insertRow(row); - QTableWidgetItem *picItem = new QTableWidgetItem(graph.pic); - QTableWidgetItem *intervalItem = new QTableWidgetItem(QString::number(graph.interval)); - picItem->setTextAlignment(Qt::AlignCenter); - intervalItem->setTextAlignment(Qt::AlignCenter); - m_TableWidget->setItem(row, 0, picItem); - m_TableWidget->setItem(row, 1, intervalItem); - row+=1; - } -} - -void CRollSwitchWidget::slotStartClick() -{ - emit sigStartRoll(m_GroupComb->currentText()); - resetView(E_START); -} - -//自动播放选中 -void CRollSwitchWidget::slotAutoPlayClick() -{ - if(m_autoCheckBox->isChecked()) - { - QPair pair; - pair.first = m_GroupComb->currentText(); - pair.second = m_timeSpin->value(); - m_screenMap.insert(m_nScreen, pair); - m_autoTimeMap[m_nScreen] = m_timeSpin->value(); - if(CXmlOpt::saveHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap)) - { - emit sigAutoRoll(true, m_GroupComb->currentText(), m_timeSpin->value()); - resetView(E_AUTO); - } - } - else - { - m_screenMap.remove(m_nScreen); - if(CXmlOpt::saveHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap)) - { - emit sigAutoRoll(false, m_GroupComb->currentText(), m_timeSpin->value()); - resetView(E_STOP); - } - } -} - - -void CRollSwitchWidget::slotStopClick() -{ - emit sigStopRoll(); - resetView(E_STOP); -} - -void CRollSwitchWidget::slotConfirmClick() -{ - emit sigClose(); -} - -void CRollSwitchWidget::resetView(EStatus status) -{ - switch (status) { - case E_AUTO: - { - m_autoCheckBox->setChecked(true); - m_autoCheckBox->setEnabled(true); - m_timeSpin->setEnabled(false); - m_GroupComb->setEnabled(false); - m_startBtn->setVisible(false); - m_startBtn->setEnabled(false); - m_stopBtn->setVisible(true); - m_stopBtn->setEnabled(false); - m_confirmBtn->setVisible(false); - break; - } - case E_START: - { - m_autoCheckBox->setChecked(false); - m_autoCheckBox->setEnabled(false); - m_timeSpin->setEnabled(false); - m_GroupComb->setEnabled(false); - m_startBtn->setVisible(false); - m_stopBtn->setVisible(true); - m_stopBtn->setEnabled(true); - m_confirmBtn->setVisible(false); - break; - } - case E_STOP: - { - m_autoCheckBox->setChecked(false); - m_autoCheckBox->setEnabled(true); - m_timeSpin->setEnabled(true); - m_GroupComb->setEnabled(true); - m_startBtn->setVisible(true); - m_startBtn->setEnabled(true); - m_stopBtn->setVisible(false); - m_stopBtn->setEnabled(false); - m_confirmBtn->setVisible(false); - break; - } - default: - break; - } -} - +#include "CRollSwitchWidget.h" +#include +#include +#include +#include + +CRollSwitchWidget::CRollSwitchWidget(QWidget *parent) + : QWidget(parent) +{ + initWidget(); + initGroup(); +} + +CRollSwitchWidget::~CRollSwitchWidget() +{ + m_GroupList.clear(); + m_hmiRollMap.clear(); + m_screenMap.clear(); + m_autoTimeMap.clear(); +} + +void CRollSwitchWidget::setRollInfo(bool isAuto, bool isStart, const QString &Group, int interval, int screen) +{ + m_nScreen = screen; + int index = m_GroupComb->findText(Group); + if(index >= 0){ + m_GroupComb->setCurrentIndex(index); + } + + if(isAuto){ + resetView(E_AUTO); + m_timeSpin->setValue(interval); + }else{ + if(isStart){ + resetView(E_START); + }else{ + resetView(E_STOP); + } + m_timeSpin->setValue(m_autoTimeMap.value(m_nScreen, 15)); + } +} + +void CRollSwitchWidget::initWidget() +{ + QLabel *label = new QLabel(tr("播放组"), this); + + m_GroupComb = new QComboBox(this); + m_GroupComb->setView(new QListView()); + m_GroupComb->setMinimumWidth(120); + connect(m_GroupComb, &QComboBox::currentTextChanged, this, &CRollSwitchWidget::slotGroupCombChange); + + m_TableWidget = new QTableWidget(this); + m_TableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + m_TableWidget->setColumnCount(2); + m_TableWidget->setHorizontalHeaderLabels(QStringList() << tr("画面文件名称") << tr("画面轮询间隔(s)")); + m_TableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + m_TableWidget->horizontalHeader()->setStretchLastSection(true); + m_TableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + + m_autoCheckBox = new QCheckBox(tr("自动轮询(设定的时间内,未检测到键鼠操作,自动轮询播放画面)"), this); + connect(m_autoCheckBox, &QCheckBox::clicked, this, &CRollSwitchWidget::slotAutoPlayClick); + + m_startBtn = new QPushButton(tr("开始"), this); + connect(m_startBtn, &QPushButton::clicked, this, &CRollSwitchWidget::slotStartClick); + + m_stopBtn = new QPushButton(tr("停止"), this); + connect(m_stopBtn, &QPushButton::clicked, this, &CRollSwitchWidget::slotStopClick); + m_stopBtn->setVisible(false); + + m_confirmBtn = new QPushButton(tr("关闭"), this); + connect(m_confirmBtn, &QPushButton::clicked, this, &CRollSwitchWidget::slotConfirmClick); + m_confirmBtn->setVisible(false); + + QLabel *label1 = new QLabel(tr("轮询时间(s)"), this); + label1->setObjectName("autoTime"); + m_timeSpin = new QSpinBox(this); + m_timeSpin->setMaximum(9999); + m_timeSpin->setMaximumWidth(80); //宽度调整 + m_timeSpin->setMinimum(15); + m_timeSpin->setValue(15); + + QHBoxLayout *hLayout = new QHBoxLayout(); + hLayout->addWidget(label); + hLayout->addWidget(m_GroupComb); + + hLayout->addWidget(m_startBtn); + hLayout->addWidget(m_stopBtn); + hLayout->addWidget(m_confirmBtn); + + QHBoxLayout *cLayout = new QHBoxLayout(); + cLayout->addWidget(m_autoCheckBox); + QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding); + cLayout->addSpacerItem(item); + cLayout->addWidget(label1); + cLayout->addWidget(m_timeSpin); + + QGridLayout *gLayout = new QGridLayout(this); + gLayout->addLayout(hLayout, 0, 0, 1, 1); + gLayout->addWidget(m_TableWidget, 1, 0, 1, 3); + gLayout->addLayout(cLayout, 2, 0, 1, 3); + + setLayout(gLayout); +} + +void CRollSwitchWidget::initGroup() +{ + m_GroupList.clear(); + m_hmiRollMap.clear(); + m_screenMap.clear(); + m_autoTimeMap.clear(); + m_GroupComb->clear(); + + CXmlOpt::readHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap); + foreach (QString group, m_GroupList) { + m_GroupComb->addItem(group); + } +} + +void CRollSwitchWidget::slotGroupCombChange(const QString &text) +{ + m_TableWidget->clearContents(); + m_TableWidget->setRowCount(0); + QList graphList = m_hmiRollMap.value(text); + int row = 0; + foreach (SGraph graph, graphList) { + if(graph.enable == 0) + continue; + m_TableWidget->insertRow(row); + QTableWidgetItem *picItem = new QTableWidgetItem(graph.pic); + QTableWidgetItem *intervalItem = new QTableWidgetItem(QString::number(graph.interval)); + picItem->setTextAlignment(Qt::AlignCenter); + intervalItem->setTextAlignment(Qt::AlignCenter); + m_TableWidget->setItem(row, 0, picItem); + m_TableWidget->setItem(row, 1, intervalItem); + row+=1; + } +} + +void CRollSwitchWidget::slotStartClick() +{ + emit sigStartRoll(m_GroupComb->currentText()); + resetView(E_START); +} + +//自动播放选中 +void CRollSwitchWidget::slotAutoPlayClick() +{ + if(m_autoCheckBox->isChecked()) + { + QPair pair; + pair.first = m_GroupComb->currentText(); + pair.second = m_timeSpin->value(); + m_screenMap.insert(m_nScreen, pair); + m_autoTimeMap[m_nScreen] = m_timeSpin->value(); + if(CXmlOpt::saveHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap)) + { + emit sigAutoRoll(true, m_GroupComb->currentText(), m_timeSpin->value()); + resetView(E_AUTO); + } + } + else + { + m_screenMap.remove(m_nScreen); + if(CXmlOpt::saveHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap)) + { + emit sigAutoRoll(false, m_GroupComb->currentText(), m_timeSpin->value()); + resetView(E_STOP); + } + } +} + + +void CRollSwitchWidget::slotStopClick() +{ + emit sigStopRoll(); + resetView(E_STOP); +} + +void CRollSwitchWidget::slotConfirmClick() +{ + emit sigClose(); +} + +void CRollSwitchWidget::resetView(EStatus status) +{ + switch (status) { + case E_AUTO: + { + m_autoCheckBox->setChecked(true); + m_autoCheckBox->setEnabled(true); + m_timeSpin->setEnabled(false); + m_GroupComb->setEnabled(false); + m_startBtn->setVisible(false); + m_startBtn->setEnabled(false); + m_stopBtn->setVisible(true); + m_stopBtn->setEnabled(false); + m_confirmBtn->setVisible(false); + break; + } + case E_START: + { + m_autoCheckBox->setChecked(false); + m_autoCheckBox->setEnabled(false); + m_timeSpin->setEnabled(false); + m_GroupComb->setEnabled(false); + m_startBtn->setVisible(false); + m_stopBtn->setVisible(true); + m_stopBtn->setEnabled(true); + m_confirmBtn->setVisible(false); + break; + } + case E_STOP: + { + m_autoCheckBox->setChecked(false); + m_autoCheckBox->setEnabled(true); + m_timeSpin->setEnabled(true); + m_GroupComb->setEnabled(true); + m_startBtn->setVisible(true); + m_startBtn->setEnabled(true); + m_stopBtn->setVisible(false); + m_stopBtn->setEnabled(false); + m_confirmBtn->setVisible(false); + break; + } + default: + break; + } +} + diff --git a/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.h b/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.h index 74f88d40..665f97bb 100644 --- a/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.h +++ b/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.h @@ -1,64 +1,64 @@ -#ifndef CROLLSWITCHWIDGET_H -#define CROLLSWITCHWIDGET_H - -#include -#include -#include -#include -#include -#include -#include "CXmlOpt.h" - -enum EStatus{ - E_AUTO, - E_START, - E_STOP -}; - -class CRollSwitchWidget : public QWidget -{ - Q_OBJECT -public: - explicit CRollSwitchWidget(QWidget *parent = nullptr); - ~CRollSwitchWidget(); - -signals: - void sigAutoRoll(bool Auto, const QString &Group, int delay); - void sigStartRoll(const QString &Group); - void sigStopRoll(); - void sigClose(); - -public slots: - void setRollInfo(bool isAuto, bool isStart, const QString &Group, int interval, int screen); - -private: - void initWidget(); - void initGroup(); - -private slots: - void slotGroupCombChange(const QString &text); - void slotAutoPlayClick(); - void slotStartClick(); - void slotStopClick(); - void slotConfirmClick(); - -private: - void resetView(EStatus status); - -private: - QComboBox *m_GroupComb; - QTableWidget *m_TableWidget; - QCheckBox *m_autoCheckBox; - QPushButton *m_startBtn; - QPushButton *m_stopBtn; - QPushButton *m_confirmBtn; - QSpinBox *m_timeSpin; - - int m_nScreen; - QStringList m_GroupList; - QMap > m_hmiRollMap; - QMap> m_screenMap; - QMap m_autoTimeMap; -}; - -#endif // CROLLSWITCHWIDGET_H +#ifndef CROLLSWITCHWIDGET_H +#define CROLLSWITCHWIDGET_H + +#include +#include +#include +#include +#include +#include +#include "CXmlOpt.h" + +enum EStatus{ + E_AUTO, + E_START, + E_STOP +}; + +class CRollSwitchWidget : public QWidget +{ + Q_OBJECT +public: + explicit CRollSwitchWidget(QWidget *parent = nullptr); + ~CRollSwitchWidget(); + +signals: + void sigAutoRoll(bool Auto, const QString &Group, int delay); + void sigStartRoll(const QString &Group); + void sigStopRoll(); + void sigClose(); + +public slots: + void setRollInfo(bool isAuto, bool isStart, const QString &Group, int interval, int screen); + +private: + void initWidget(); + void initGroup(); + +private slots: + void slotGroupCombChange(const QString &text); + void slotAutoPlayClick(); + void slotStartClick(); + void slotStopClick(); + void slotConfirmClick(); + +private: + void resetView(EStatus status); + +private: + QComboBox *m_GroupComb; + QTableWidget *m_TableWidget; + QCheckBox *m_autoCheckBox; + QPushButton *m_startBtn; + QPushButton *m_stopBtn; + QPushButton *m_confirmBtn; + QSpinBox *m_timeSpin; + + int m_nScreen; + QStringList m_GroupList; + QMap > m_hmiRollMap; + QMap> m_screenMap; + QMap m_autoTimeMap; +}; + +#endif // CROLLSWITCHWIDGET_H diff --git a/product/src/gui/plugin/HmiRollWidget/CTableDelegata.cpp b/product/src/gui/plugin/HmiRollWidget/CTableDelegata.cpp index 4b868d6d..2f9fd12e 100644 --- a/product/src/gui/plugin/HmiRollWidget/CTableDelegata.cpp +++ b/product/src/gui/plugin/HmiRollWidget/CTableDelegata.cpp @@ -1,87 +1,87 @@ -#include "CTableDelegata.h" -#include -#include -#include "CLineEditWithBtn.h" - -CTableDelegata::CTableDelegata(QObject *parent) - : QStyledItemDelegate(parent) -{ - -} - -QWidget *CTableDelegata::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - if(index.column() == 0) - { - return NULL; - } - else if(index.column() == 1) - { - CLineEditWithBtn *edit = new CLineEditWithBtn(parent); - return edit; - } - else if(index.column() == 2) - { - QComboBox *comb = new QComboBox(parent); - comb->addItem(tr("是"), 1); - comb->addItem(tr("否"), 0); - return comb; - } - else if(index.column() == 3) - { - QLineEdit *edit = new QLineEdit(parent); - edit->setValidator(new QIntValidator(1, 86400, parent)); - return edit; - } - return QStyledItemDelegate::createEditor(parent, option, index); -} - -void CTableDelegata::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - if(index.column() == 1) - { - CLineEditWithBtn *lineEdit = static_cast(editor); - lineEdit->setText(index.data().toString()); - } - else if(index.column() == 2) - { - QString text = index.data(Qt::DisplayRole).toString(); - QComboBox *box = static_cast(editor); - box->setCurrentIndex(box->findText(text)); - } - else if(index.column() == 3) - { - QString text = index.data(Qt::DisplayRole).toString(); - QLineEdit *edit = static_cast(editor); - edit->setText(text); - } - else - { - QStyledItemDelegate::setEditorData(editor, index); - } -} - -void CTableDelegata::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - if(index.column() == 1) - { - CLineEditWithBtn *lineEdit = static_cast(editor); - model->setData(index, lineEdit->text(), Qt::DisplayRole); - } - else if(index.column() == 2) - { - QComboBox *comb = static_cast(editor); - model->setData(index, comb->currentText(), Qt::DisplayRole); - model->setData(index, comb->currentData().toInt(), Qt::UserRole); - } - else if(index.column() == 3) - { - QLineEdit *edit = static_cast(editor); - model->setData(index, edit->text(), Qt::DisplayRole); - } - else - { - QStyledItemDelegate::setModelData(editor, model, index); - } -} - +#include "CTableDelegata.h" +#include +#include +#include "CLineEditWithBtn.h" + +CTableDelegata::CTableDelegata(QObject *parent) + : QStyledItemDelegate(parent) +{ + +} + +QWidget *CTableDelegata::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(index.column() == 0) + { + return NULL; + } + else if(index.column() == 1) + { + CLineEditWithBtn *edit = new CLineEditWithBtn(parent); + return edit; + } + else if(index.column() == 2) + { + QComboBox *comb = new QComboBox(parent); + comb->addItem(tr("是"), 1); + comb->addItem(tr("否"), 0); + return comb; + } + else if(index.column() == 3) + { + QLineEdit *edit = new QLineEdit(parent); + edit->setValidator(new QIntValidator(1, 86400, parent)); + return edit; + } + return QStyledItemDelegate::createEditor(parent, option, index); +} + +void CTableDelegata::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if(index.column() == 1) + { + CLineEditWithBtn *lineEdit = static_cast(editor); + lineEdit->setText(index.data().toString()); + } + else if(index.column() == 2) + { + QString text = index.data(Qt::DisplayRole).toString(); + QComboBox *box = static_cast(editor); + box->setCurrentIndex(box->findText(text)); + } + else if(index.column() == 3) + { + QString text = index.data(Qt::DisplayRole).toString(); + QLineEdit *edit = static_cast(editor); + edit->setText(text); + } + else + { + QStyledItemDelegate::setEditorData(editor, index); + } +} + +void CTableDelegata::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + if(index.column() == 1) + { + CLineEditWithBtn *lineEdit = static_cast(editor); + model->setData(index, lineEdit->text(), Qt::DisplayRole); + } + else if(index.column() == 2) + { + QComboBox *comb = static_cast(editor); + model->setData(index, comb->currentText(), Qt::DisplayRole); + model->setData(index, comb->currentData().toInt(), Qt::UserRole); + } + else if(index.column() == 3) + { + QLineEdit *edit = static_cast(editor); + model->setData(index, edit->text(), Qt::DisplayRole); + } + else + { + QStyledItemDelegate::setModelData(editor, model, index); + } +} + diff --git a/product/src/gui/plugin/HmiRollWidget/CTableDelegata.h b/product/src/gui/plugin/HmiRollWidget/CTableDelegata.h index 7f48fc5f..d7432e67 100644 --- a/product/src/gui/plugin/HmiRollWidget/CTableDelegata.h +++ b/product/src/gui/plugin/HmiRollWidget/CTableDelegata.h @@ -1,21 +1,21 @@ -#ifndef CTABLEDELEGATA_H -#define CTABLEDELEGATA_H - -#include -#include - -class CTableDelegata : public QStyledItemDelegate -{ - Q_OBJECT -public: - CTableDelegata(QObject *parent = 0); - - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const override; - - void setEditorData(QWidget *editor, const QModelIndex &index) const override; - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const override; -}; - -#endif // CTABLEDELEGATA_H +#ifndef CTABLEDELEGATA_H +#define CTABLEDELEGATA_H + +#include +#include + +class CTableDelegata : public QStyledItemDelegate +{ + Q_OBJECT +public: + CTableDelegata(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const override; +}; + +#endif // CTABLEDELEGATA_H diff --git a/product/src/gui/plugin/HmiRollWidget/CXmlOpt.cpp b/product/src/gui/plugin/HmiRollWidget/CXmlOpt.cpp index 4d9ef505..df8e9da1 100644 --- a/product/src/gui/plugin/HmiRollWidget/CXmlOpt.cpp +++ b/product/src/gui/plugin/HmiRollWidget/CXmlOpt.cpp @@ -1,224 +1,224 @@ -#include "CXmlOpt.h" -#include -#include - -CXmlOpt::CXmlOpt() -{ - -} - -bool CXmlOpt::readHmiRollXml(QStringList &GroupList, QMap > &GraphMap, - QMap > &ScreenMap, QMap &autoTimeMap) -{ - QDomDocument document; - if(!readXml(document)) - { - return false; - } - QDomElement root = document.documentElement(); - if(root.isNull()) - { - return false; - } - - readGroup(root, GroupList, GraphMap); - readScreen(root, ScreenMap); - readAutoTime(root, autoTimeMap); - - return true; -} - -bool CXmlOpt::saveHmiRollXml(const QStringList &GroupList, const QMap > &GraphMap, - const QMap > &ScreenMap, QMap &autoTimeMap) -{ - QFile file(HmiRollPath); - if(file.open(QIODevice::WriteOnly | QIODevice::Text)) - { - QDomDocument document; - - QString strHeader("version='1.0' encoding='utf-8'"); - document.appendChild(document.createProcessingInstruction("xml", strHeader)); - QDomElement root = document.createElement("Profile"); - foreach (QString Group, GroupList) { - QDomElement groupNode = document.createElement("Group"); - groupNode.setAttribute("name", Group); - foreach (SGraph sGraph, GraphMap.value(Group, QList())) { - QDomElement graph = document.createElement("Graph"); - graph.setAttribute("pic", sGraph.pic); - graph.setAttribute("enable", sGraph.enable); - graph.setAttribute("interval", sGraph.interval); - groupNode.appendChild(graph); - } - root.appendChild(groupNode); - } - QMap >::const_iterator sIter = ScreenMap.constBegin(); - for(; sIter != ScreenMap.constEnd(); sIter++) - { - QDomElement screenNode = document.createElement("Screen"); - screenNode.setAttribute("id", QString::number(sIter.key())); - screenNode.setAttribute("group", sIter.value().first); - screenNode.setAttribute("delay", QString::number(sIter.value().second)); - root.appendChild(screenNode); - } - QMap::const_iterator tIter = autoTimeMap.constBegin(); - for(; tIter != autoTimeMap.constEnd(); tIter++) - { - QDomElement timeNode = document.createElement("AutoTime"); - timeNode.setAttribute("id", QString::number(tIter.key())); - timeNode.setAttribute("time", QString::number(tIter.value())); - root.appendChild(timeNode); - } - document.appendChild(root); - - QTextStream content(&file); - document.save(content, 4); - - file.close(); - return true; - } - file.close(); - return false; -} - -bool CXmlOpt::readScreenRoll(int screen, QPair &info) -{ - QDomDocument document; - if(!readXml(document)) - { - return false; - } - QDomElement root = document.documentElement(); - if(root.isNull()) - { - return false; - } - QMap > ScreenMap; - readScreen(root, ScreenMap, screen); - if(ScreenMap.isEmpty()){ - return false; - }else{ - info = ScreenMap.value(screen, QPair()); - } - return true; -} - -bool CXmlOpt::readGraphRoll(const QString &group, QList &info) -{ - QDomDocument document; - if(!readXml(document)) - { - return false; - } - QDomElement root = document.documentElement(); - if(root.isNull()) - { - return false; - } - QMap > GraphMap; - QStringList GroupList; - readGroup(root, GroupList, GraphMap, group); - if(GraphMap.isEmpty()){ - return false; - }else{ - info = GraphMap.value(group, QList()); - } - return true; -} - -bool CXmlOpt::readXml(QDomDocument &doc) -{ - QFile file(HmiRollPath); - if (!file.open(QIODevice::ReadOnly)) - { - return false; - } - if (!doc.setContent(&file)) - { - file.close(); - return false; - } - file.close(); - return true; -} - -void CXmlOpt::readGroup(const QDomElement &root, QStringList &GroupList, QMap > &GraphMap, const QString &group) -{ - QDomNodeList groupList = root.elementsByTagName("Group"); - for(int groupIndex(0); groupIndex < groupList.size(); groupIndex++) - { - QDomNode groupNode = groupList.at(groupIndex); - if(groupNode.isNull()) - continue; - QDomElement groupElement = groupNode.toElement(); - if(groupElement.isNull()) - continue; - QString groupName = groupElement.attribute("name", QString()); - if(!group.isEmpty() && group != groupName) - continue; - - QDomNodeList graphList = groupElement.elementsByTagName("Graph"); - QList list; - for(int graphIndex(0); graphIndex < graphList.size(); graphIndex++) - { - QDomNode graphNode = graphList.at(graphIndex); - if(graphNode.isNull()) - continue; - QDomElement graphElement = graphNode.toElement(); - if(!graphElement.isNull()) - { - QString pic = graphElement.attribute("pic", QString()); - int enable = graphElement.attribute("enable", QString()).toInt(); - int interval = graphElement.attribute("interval", QString()).toInt(); - SGraph sGraph; - sGraph.pic = pic; - sGraph.enable = enable; - sGraph.interval = interval; - list.append(sGraph); - } - } - GroupList.append(groupName); - GraphMap.insert(groupName, list); - } -} - -void CXmlOpt::readScreen(const QDomElement &root, QMap > &ScreenMap, int screen) -{ - QDomNodeList screenList = root.elementsByTagName("Screen"); - for(int screenIndex(0); screenIndex < screenList.size(); screenIndex++) - { - QDomNode screenNode = screenList.at(screenIndex); - if(screenNode.isNull()) - continue; - QDomElement screenElement = screenNode.toElement(); - if(screenElement.isNull()) - continue; - int id = screenElement.attribute("id", QString()).toInt(); - if(screen>=0 && id != screen) - continue; - QString group = screenElement.attribute("group", QString()); - int delay = screenElement.attribute("delay", QString()).toInt(); - QPair pair; - pair.first = group; - pair.second = delay; - ScreenMap.insert(id, pair); - } -} - -void CXmlOpt::readAutoTime(const QDomElement &root, QMap &autoTimeMap, int screen) -{ - QDomNodeList screenList = root.elementsByTagName("AutoTime"); - for(int screenIndex(0); screenIndex < screenList.size(); screenIndex++) - { - QDomNode screenNode = screenList.at(screenIndex); - if(screenNode.isNull()) - continue; - QDomElement screenElement = screenNode.toElement(); - if(screenElement.isNull()) - continue; - int id = screenElement.attribute("id", QString()).toInt(); - if(screen>=0 && id != screen) - continue; - int time = screenElement.attribute("time", QString()).toInt(); - autoTimeMap.insert(id, time); - } -} +#include "CXmlOpt.h" +#include +#include + +CXmlOpt::CXmlOpt() +{ + +} + +bool CXmlOpt::readHmiRollXml(QStringList &GroupList, QMap > &GraphMap, + QMap > &ScreenMap, QMap &autoTimeMap) +{ + QDomDocument document; + if(!readXml(document)) + { + return false; + } + QDomElement root = document.documentElement(); + if(root.isNull()) + { + return false; + } + + readGroup(root, GroupList, GraphMap); + readScreen(root, ScreenMap); + readAutoTime(root, autoTimeMap); + + return true; +} + +bool CXmlOpt::saveHmiRollXml(const QStringList &GroupList, const QMap > &GraphMap, + const QMap > &ScreenMap, QMap &autoTimeMap) +{ + QFile file(HmiRollPath); + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QDomDocument document; + + QString strHeader("version='1.0' encoding='utf-8'"); + document.appendChild(document.createProcessingInstruction("xml", strHeader)); + QDomElement root = document.createElement("Profile"); + foreach (QString Group, GroupList) { + QDomElement groupNode = document.createElement("Group"); + groupNode.setAttribute("name", Group); + foreach (SGraph sGraph, GraphMap.value(Group, QList())) { + QDomElement graph = document.createElement("Graph"); + graph.setAttribute("pic", sGraph.pic); + graph.setAttribute("enable", sGraph.enable); + graph.setAttribute("interval", sGraph.interval); + groupNode.appendChild(graph); + } + root.appendChild(groupNode); + } + QMap >::const_iterator sIter = ScreenMap.constBegin(); + for(; sIter != ScreenMap.constEnd(); sIter++) + { + QDomElement screenNode = document.createElement("Screen"); + screenNode.setAttribute("id", QString::number(sIter.key())); + screenNode.setAttribute("group", sIter.value().first); + screenNode.setAttribute("delay", QString::number(sIter.value().second)); + root.appendChild(screenNode); + } + QMap::const_iterator tIter = autoTimeMap.constBegin(); + for(; tIter != autoTimeMap.constEnd(); tIter++) + { + QDomElement timeNode = document.createElement("AutoTime"); + timeNode.setAttribute("id", QString::number(tIter.key())); + timeNode.setAttribute("time", QString::number(tIter.value())); + root.appendChild(timeNode); + } + document.appendChild(root); + + QTextStream content(&file); + document.save(content, 4); + + file.close(); + return true; + } + file.close(); + return false; +} + +bool CXmlOpt::readScreenRoll(int screen, QPair &info) +{ + QDomDocument document; + if(!readXml(document)) + { + return false; + } + QDomElement root = document.documentElement(); + if(root.isNull()) + { + return false; + } + QMap > ScreenMap; + readScreen(root, ScreenMap, screen); + if(ScreenMap.isEmpty()){ + return false; + }else{ + info = ScreenMap.value(screen, QPair()); + } + return true; +} + +bool CXmlOpt::readGraphRoll(const QString &group, QList &info) +{ + QDomDocument document; + if(!readXml(document)) + { + return false; + } + QDomElement root = document.documentElement(); + if(root.isNull()) + { + return false; + } + QMap > GraphMap; + QStringList GroupList; + readGroup(root, GroupList, GraphMap, group); + if(GraphMap.isEmpty()){ + return false; + }else{ + info = GraphMap.value(group, QList()); + } + return true; +} + +bool CXmlOpt::readXml(QDomDocument &doc) +{ + QFile file(HmiRollPath); + if (!file.open(QIODevice::ReadOnly)) + { + return false; + } + if (!doc.setContent(&file)) + { + file.close(); + return false; + } + file.close(); + return true; +} + +void CXmlOpt::readGroup(const QDomElement &root, QStringList &GroupList, QMap > &GraphMap, const QString &group) +{ + QDomNodeList groupList = root.elementsByTagName("Group"); + for(int groupIndex(0); groupIndex < groupList.size(); groupIndex++) + { + QDomNode groupNode = groupList.at(groupIndex); + if(groupNode.isNull()) + continue; + QDomElement groupElement = groupNode.toElement(); + if(groupElement.isNull()) + continue; + QString groupName = groupElement.attribute("name", QString()); + if(!group.isEmpty() && group != groupName) + continue; + + QDomNodeList graphList = groupElement.elementsByTagName("Graph"); + QList list; + for(int graphIndex(0); graphIndex < graphList.size(); graphIndex++) + { + QDomNode graphNode = graphList.at(graphIndex); + if(graphNode.isNull()) + continue; + QDomElement graphElement = graphNode.toElement(); + if(!graphElement.isNull()) + { + QString pic = graphElement.attribute("pic", QString()); + int enable = graphElement.attribute("enable", QString()).toInt(); + int interval = graphElement.attribute("interval", QString()).toInt(); + SGraph sGraph; + sGraph.pic = pic; + sGraph.enable = enable; + sGraph.interval = interval; + list.append(sGraph); + } + } + GroupList.append(groupName); + GraphMap.insert(groupName, list); + } +} + +void CXmlOpt::readScreen(const QDomElement &root, QMap > &ScreenMap, int screen) +{ + QDomNodeList screenList = root.elementsByTagName("Screen"); + for(int screenIndex(0); screenIndex < screenList.size(); screenIndex++) + { + QDomNode screenNode = screenList.at(screenIndex); + if(screenNode.isNull()) + continue; + QDomElement screenElement = screenNode.toElement(); + if(screenElement.isNull()) + continue; + int id = screenElement.attribute("id", QString()).toInt(); + if(screen>=0 && id != screen) + continue; + QString group = screenElement.attribute("group", QString()); + int delay = screenElement.attribute("delay", QString()).toInt(); + QPair pair; + pair.first = group; + pair.second = delay; + ScreenMap.insert(id, pair); + } +} + +void CXmlOpt::readAutoTime(const QDomElement &root, QMap &autoTimeMap, int screen) +{ + QDomNodeList screenList = root.elementsByTagName("AutoTime"); + for(int screenIndex(0); screenIndex < screenList.size(); screenIndex++) + { + QDomNode screenNode = screenList.at(screenIndex); + if(screenNode.isNull()) + continue; + QDomElement screenElement = screenNode.toElement(); + if(screenElement.isNull()) + continue; + int id = screenElement.attribute("id", QString()).toInt(); + if(screen>=0 && id != screen) + continue; + int time = screenElement.attribute("time", QString()).toInt(); + autoTimeMap.insert(id, time); + } +} diff --git a/product/src/gui/plugin/HmiRollWidget/CXmlOpt.h b/product/src/gui/plugin/HmiRollWidget/CXmlOpt.h index b47d5fe6..5cd49b54 100644 --- a/product/src/gui/plugin/HmiRollWidget/CXmlOpt.h +++ b/product/src/gui/plugin/HmiRollWidget/CXmlOpt.h @@ -1,36 +1,36 @@ -#ifndef CXMLOPT_H -#define CXMLOPT_H - -#include -#include - -#define HmiRollPath "../../data/model/hmiRoll.xml" - -struct SGraph -{ - QString pic; - int enable; - int interval; -}; - -class CXmlOpt -{ -public: - CXmlOpt(); - - static bool readHmiRollXml(QStringList &GroupList, QMap> &GraphMap, - QMap>& ScreenMap, QMap &autoTimeMap); - static bool saveHmiRollXml(const QStringList &GroupList, const QMap> &GraphMap, - const QMap>& ScreenMap, QMap &autoTimeMap); - - static bool readScreenRoll(int screen, QPair &info); - static bool readGraphRoll(const QString &group, QList &info); - -private: - static bool readXml(QDomDocument &doc); - static void readGroup(const QDomElement &root, QStringList &GroupList, QMap > &GraphMap, const QString &group = QString()); - static void readScreen(const QDomElement &root, QMap>& ScreenMap, int screen = -1); - static void readAutoTime(const QDomElement &root, QMap &autoTimeMap, int screen = -1); -}; - -#endif // CXMLOPT_H +#ifndef CXMLOPT_H +#define CXMLOPT_H + +#include +#include + +#define HmiRollPath "../../data/model/hmiRoll.xml" + +struct SGraph +{ + QString pic; + int enable; + int interval; +}; + +class CXmlOpt +{ +public: + CXmlOpt(); + + static bool readHmiRollXml(QStringList &GroupList, QMap> &GraphMap, + QMap>& ScreenMap, QMap &autoTimeMap); + static bool saveHmiRollXml(const QStringList &GroupList, const QMap> &GraphMap, + const QMap>& ScreenMap, QMap &autoTimeMap); + + static bool readScreenRoll(int screen, QPair &info); + static bool readGraphRoll(const QString &group, QList &info); + +private: + static bool readXml(QDomDocument &doc); + static void readGroup(const QDomElement &root, QStringList &GroupList, QMap > &GraphMap, const QString &group = QString()); + static void readScreen(const QDomElement &root, QMap>& ScreenMap, int screen = -1); + static void readAutoTime(const QDomElement &root, QMap &autoTimeMap, int screen = -1); +}; + +#endif // CXMLOPT_H diff --git a/product/src/gui/plugin/HmiRollWidget/ConfigWidget.cpp b/product/src/gui/plugin/HmiRollWidget/ConfigWidget.cpp index 995d0682..18e16fbe 100644 --- a/product/src/gui/plugin/HmiRollWidget/ConfigWidget.cpp +++ b/product/src/gui/plugin/HmiRollWidget/ConfigWidget.cpp @@ -1,341 +1,341 @@ -#include "ConfigWidget.h" -#include -#include -#include -#include -#include "CGroupManageDialog.h" -#include -#include -#include -#include - -ConfigWidget::ConfigWidget(QWidget *parent) - : QWidget(parent) -{ - initWidget(); - initGroup(); -} - -ConfigWidget::~ConfigWidget() -{ - m_GroupList.clear(); - m_hmiRollMap.clear(); - m_screenMap.clear(); - m_autoTimeMap.clear(); -} - -void ConfigWidget::initWidget() -{ - m_GroupComb = new QComboBox(this); - m_GroupComb->setView(new QListView()); - connect(m_GroupComb, &QComboBox::currentTextChanged, this, &ConfigWidget::slotGroupCombChange); - m_GroupComb->setMinimumWidth(100); - - m_GroupManage = new QPushButton(tr("分组管理"), this); - connect(m_GroupManage, &QPushButton::clicked, this, &ConfigWidget::slotGroupManageClick); - - m_Add = new QPushButton(tr("新增"), this); - connect(m_Add, &QPushButton::clicked, this, &ConfigWidget::slotAddClick); - - m_Del = new QPushButton(tr("删除"), this); - connect(m_Del, &QPushButton::clicked, this, &ConfigWidget::slotDelClick); - - m_MoveUp = new QPushButton(tr("上移"), this); - connect(m_MoveUp, &QPushButton::clicked, this, &ConfigWidget::slotMoveUpClick); - - m_MoveDown = new QPushButton(tr("下移"), this); - connect(m_MoveDown, &QPushButton::clicked, this, &ConfigWidget::slotMoveDownClick); - - m_Save = new QPushButton(tr("保存"), this); - connect(m_Save, &QPushButton::clicked, this, &ConfigWidget::slotSaveClick); - - QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding); - - m_TableWidget = new QTableWidget(this); - m_TableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - m_TableWidget->setColumnCount(4); - m_TableWidget->setHorizontalHeaderLabels(QStringList() << tr("轮询组") << tr("画面文件名称") << tr("是否启用") << tr("画面轮询间隔(s)")); - m_TableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - m_TableWidget->horizontalHeader()->setStretchLastSection(true); - CTableDelegata *delegata = new CTableDelegata(this); - m_TableWidget->setItemDelegate(delegata); - - QHBoxLayout *hLayout = new QHBoxLayout(); - hLayout->addWidget(m_GroupComb); - hLayout->addWidget(m_GroupManage); - hLayout->addWidget(m_Add); - hLayout->addWidget(m_Del); - hLayout->addWidget(m_MoveUp); - hLayout->addWidget(m_MoveDown); - hLayout->addWidget(m_Save); - hLayout->addSpacerItem(spacer); - - QGridLayout *gridLayout = new QGridLayout(this); - gridLayout->addLayout(hLayout, 0, 0); - gridLayout->addWidget(m_TableWidget, 1, 0); - setLayout(gridLayout); -} - -void ConfigWidget::initGroup() -{ - m_GroupList.clear(); - m_hmiRollMap.clear(); - m_screenMap.clear(); - m_autoTimeMap.clear(); - m_GroupComb->clear(); - - CXmlOpt::readHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap); - foreach (QString group, m_GroupList) { - m_GroupComb->addItem(group); - } -} - -void ConfigWidget::hmiSwitchOpt() -{ - initGroup(); -} - -void ConfigWidget::slotGroupCombChange(const QString &text) -{ - m_TableWidget->clearContents(); - m_TableWidget->setRowCount(0); - QList graphList = m_hmiRollMap.value(text); - int row = 0; - foreach (SGraph graph, graphList) { - m_TableWidget->insertRow(row); - QTableWidgetItem *groupItem = new QTableWidgetItem(text); - QTableWidgetItem *picItem = new QTableWidgetItem(graph.pic); - QTableWidgetItem *enableItem = new QTableWidgetItem(getEnableDesc(graph.enable)); - enableItem->setData(Qt::UserRole, graph.enable); - QTableWidgetItem *intervalItem = new QTableWidgetItem(QString::number(graph.interval)); - groupItem->setTextAlignment(Qt::AlignCenter); - picItem->setTextAlignment(Qt::AlignCenter); - enableItem->setTextAlignment(Qt::AlignCenter); - intervalItem->setTextAlignment(Qt::AlignCenter); - m_TableWidget->setItem(row, 0, groupItem); - m_TableWidget->setItem(row, 1, picItem); - m_TableWidget->setItem(row, 2, enableItem); - m_TableWidget->setItem(row, 3, intervalItem); - row+=1; - } -} - -void ConfigWidget::slotGroupManageClick() -{ - CGroupManageDialog * dialog = new CGroupManageDialog(this); - dialog->setGroup(m_GroupList); - if(QDialog::Accepted == dialog->exec()) - { - QStringList normalGroupList = dialog->getNormalGroup(); - QStringList newGroupList = dialog->getNewGroup(); - QMap modifyGroupMap = dialog->getModifyGroup(); - QStringList modifyGroupList = modifyGroupMap.keys(); - QStringList changeList; - - //< 修改轮询组 - QMap > modifyTemp; - QMap> screenTemp; - foreach (QString modifyGroup, modifyGroupList) { - QString oldName = modifyGroupMap.value(modifyGroup, QString()); - changeList.append(oldName + "-" + modifyGroup); - QList Graph = m_hmiRollMap.value(oldName); - modifyTemp.insert(modifyGroup, Graph); - - QMap>::iterator iter = m_screenMap.begin(); - for(; iter != m_screenMap.end(); ) - { - if(iter.value().first == oldName){ - QPair temp; - temp.first = oldName; - temp.second = modifyGroup; - screenTemp.insert(iter.key(), temp); - } - iter++; - } - } - QMap >::const_iterator iter = modifyTemp.constBegin(); - for(; iter != modifyTemp.constEnd(); iter++) - { - m_hmiRollMap.insert(iter.key(), iter.value()); - } - QMap>::iterator screenIter = screenTemp.begin(); - for(; screenIter != screenTemp.end(); screenIter++) - { - QMap>::iterator iter = m_screenMap.find(screenIter.key()); - if(iter != m_screenMap.end() && iter.value().first == screenIter.value().first) - { - iter.value().first = screenIter.value().second; - } - } - - //< 新增轮询组 - foreach (QString newGroup, newGroupList) { - m_hmiRollMap.insert(newGroup, QList()); - } - - //< 删除轮询组 - QStringList nowGroupList = newGroupList + modifyGroupList + normalGroupList; - QStringList delGroupList; - foreach (QString Group, m_hmiRollMap.keys()) { - if(nowGroupList.indexOf(Group) == -1) - { - m_hmiRollMap.remove(Group); - QMap>::iterator iter = m_screenMap.begin(); - for(; iter != m_screenMap.end(); ) - { - if(iter.value().first == Group){ - iter = m_screenMap.erase(iter); - }else{ - iter++; - } - } - delGroupList.append(Group); - } - } - - m_GroupList = dialog->getGroup(); - CXmlOpt::saveHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap); - initGroup(); - - emit sigSave(changeList.join(","), delGroupList.join(",")); - } - - delete dialog; - dialog = NULL; -} - -void ConfigWidget::slotAddClick() -{ - if(m_GroupComb->currentText().isEmpty()) - return; - int addRow = m_TableWidget->rowCount(); - QList selectList = m_TableWidget->selectedRanges(); - if(!selectList.isEmpty()) - addRow = selectList.last().bottomRow() + 1; - m_TableWidget->insertRow(addRow); - QTableWidgetItem *groupItem = new QTableWidgetItem(m_GroupComb->currentText()); - QTableWidgetItem *picItem = new QTableWidgetItem(""); - QTableWidgetItem *enableItem = new QTableWidgetItem(getEnableDesc(1)); - enableItem->setData(Qt::UserRole, 1); - QTableWidgetItem *intervalItem = new QTableWidgetItem("10"); - groupItem->setTextAlignment(Qt::AlignCenter); - picItem->setTextAlignment(Qt::AlignCenter); - enableItem->setTextAlignment(Qt::AlignCenter); - intervalItem->setTextAlignment(Qt::AlignCenter); - m_TableWidget->setItem(addRow, 0, groupItem); - m_TableWidget->setItem(addRow, 1, picItem); - m_TableWidget->setItem(addRow, 2, enableItem); - m_TableWidget->setItem(addRow, 3, intervalItem); -} - -void ConfigWidget::slotDelClick() -{ - if(m_GroupComb->currentText().isEmpty()) - return; - QList selectList = m_TableWidget->selectedRanges(); - for(int nIndex=selectList.count()-1; nIndex>=0; nIndex--) - { - int bottomRow = selectList.at(nIndex).bottomRow(); - int topRow = selectList.at(nIndex).topRow(); - for(int row=bottomRow; row>=topRow; row--) - { - m_TableWidget->removeRow(row); - } - } -} - -void ConfigWidget::slotMoveUpClick() -{ - if(m_GroupComb->currentText().isEmpty()) - return; - QList selectList = m_TableWidget->selectedRanges(); - if(selectList.isEmpty() || selectList.first().topRow() == 0) - { - return; - } - - int insertRow = selectList.first().topRow() - 1; - m_TableWidget->insertRow(insertRow); - for(int col=0; colcolumnCount(); col++) - { - m_TableWidget->setItem(insertRow, col, m_TableWidget->takeItem(insertRow+2, col)); - } - m_TableWidget->removeRow(insertRow+2); - m_TableWidget->selectRow(insertRow); -} - -void ConfigWidget::slotMoveDownClick() -{ - if(m_GroupComb->currentText().isEmpty()) - return; - QList selectList = m_TableWidget->selectedRanges(); - if(selectList.isEmpty() || selectList.last().bottomRow() == m_TableWidget->rowCount()-1) - { - return; - } - - int insertRow = selectList.last().bottomRow() + 2; - m_TableWidget->insertRow(insertRow); - for(int col=0; colcolumnCount(); col++) - { - m_TableWidget->setItem(insertRow, col, m_TableWidget->takeItem(insertRow-2, col)); - } - m_TableWidget->removeRow(insertRow-2); - m_TableWidget->selectRow(insertRow-1); -} - -void ConfigWidget::slotSaveClick() -{ - if(m_GroupComb->currentText().isEmpty()) - return; - QList graphList; - for(int nIndex=0; nIndexrowCount(); nIndex++) - { - SGraph graph; - graph.pic = m_TableWidget->item(nIndex, 1)->text(); - if(graph.pic.isEmpty()){ - showInfo(tr("画面文件名称不能为空!")); - return; - } - graph.enable = m_TableWidget->item(nIndex, 2)->data(Qt::UserRole).toInt(); - graph.interval = m_TableWidget->item(nIndex, 3)->text().toInt(); - graphList.append(graph); - } - m_hmiRollMap[m_GroupComb->currentText()] = graphList; - bool success = CXmlOpt::saveHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap); - success ? showInfo(tr("保存成功")) : showInfo(tr("保存失败")); - emit sigSave("", ""); -} - -void ConfigWidget::contextMenuEvent(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - QMenu menu; - QAction *Add = menu.addAction(tr("新增")); - connect(Add, &QAction::triggered, this, &ConfigWidget::slotAddClick); - QAction *Del = menu.addAction(tr("删除")); - connect(Del, &QAction::triggered, this, &ConfigWidget::slotDelClick); - QAction *MoveUp = menu.addAction(tr("上移")); - connect(MoveUp, &QAction::triggered, this, &ConfigWidget::slotMoveUpClick); - QAction *MoveDown = menu.addAction(tr("下移")); - connect(MoveDown, &QAction::triggered, this, &ConfigWidget::slotMoveDownClick); - menu.exec(event->globalPos()); -} - -QString ConfigWidget::getEnableDesc(int enable) -{ - if(enable == 1) - { - return tr("是"); - } - else if(enable == 0) - { - return tr("否"); - } - return QString(); -} - -void ConfigWidget::showInfo(const QString &info) -{ - QMessageBox::information(this, tr("提示"), info, QMessageBox::Ok); -} +#include "ConfigWidget.h" +#include +#include +#include +#include +#include "CGroupManageDialog.h" +#include +#include +#include +#include + +ConfigWidget::ConfigWidget(QWidget *parent) + : QWidget(parent) +{ + initWidget(); + initGroup(); +} + +ConfigWidget::~ConfigWidget() +{ + m_GroupList.clear(); + m_hmiRollMap.clear(); + m_screenMap.clear(); + m_autoTimeMap.clear(); +} + +void ConfigWidget::initWidget() +{ + m_GroupComb = new QComboBox(this); + m_GroupComb->setView(new QListView()); + connect(m_GroupComb, &QComboBox::currentTextChanged, this, &ConfigWidget::slotGroupCombChange); + m_GroupComb->setMinimumWidth(100); + + m_GroupManage = new QPushButton(tr("分组管理"), this); + connect(m_GroupManage, &QPushButton::clicked, this, &ConfigWidget::slotGroupManageClick); + + m_Add = new QPushButton(tr("新增"), this); + connect(m_Add, &QPushButton::clicked, this, &ConfigWidget::slotAddClick); + + m_Del = new QPushButton(tr("删除"), this); + connect(m_Del, &QPushButton::clicked, this, &ConfigWidget::slotDelClick); + + m_MoveUp = new QPushButton(tr("上移"), this); + connect(m_MoveUp, &QPushButton::clicked, this, &ConfigWidget::slotMoveUpClick); + + m_MoveDown = new QPushButton(tr("下移"), this); + connect(m_MoveDown, &QPushButton::clicked, this, &ConfigWidget::slotMoveDownClick); + + m_Save = new QPushButton(tr("保存"), this); + connect(m_Save, &QPushButton::clicked, this, &ConfigWidget::slotSaveClick); + + QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding); + + m_TableWidget = new QTableWidget(this); + m_TableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + m_TableWidget->setColumnCount(4); + m_TableWidget->setHorizontalHeaderLabels(QStringList() << tr("轮询组") << tr("画面文件名称") << tr("是否启用") << tr("画面轮询间隔(s)")); + m_TableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + m_TableWidget->horizontalHeader()->setStretchLastSection(true); + CTableDelegata *delegata = new CTableDelegata(this); + m_TableWidget->setItemDelegate(delegata); + + QHBoxLayout *hLayout = new QHBoxLayout(); + hLayout->addWidget(m_GroupComb); + hLayout->addWidget(m_GroupManage); + hLayout->addWidget(m_Add); + hLayout->addWidget(m_Del); + hLayout->addWidget(m_MoveUp); + hLayout->addWidget(m_MoveDown); + hLayout->addWidget(m_Save); + hLayout->addSpacerItem(spacer); + + QGridLayout *gridLayout = new QGridLayout(this); + gridLayout->addLayout(hLayout, 0, 0); + gridLayout->addWidget(m_TableWidget, 1, 0); + setLayout(gridLayout); +} + +void ConfigWidget::initGroup() +{ + m_GroupList.clear(); + m_hmiRollMap.clear(); + m_screenMap.clear(); + m_autoTimeMap.clear(); + m_GroupComb->clear(); + + CXmlOpt::readHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap); + foreach (QString group, m_GroupList) { + m_GroupComb->addItem(group); + } +} + +void ConfigWidget::hmiSwitchOpt() +{ + initGroup(); +} + +void ConfigWidget::slotGroupCombChange(const QString &text) +{ + m_TableWidget->clearContents(); + m_TableWidget->setRowCount(0); + QList graphList = m_hmiRollMap.value(text); + int row = 0; + foreach (SGraph graph, graphList) { + m_TableWidget->insertRow(row); + QTableWidgetItem *groupItem = new QTableWidgetItem(text); + QTableWidgetItem *picItem = new QTableWidgetItem(graph.pic); + QTableWidgetItem *enableItem = new QTableWidgetItem(getEnableDesc(graph.enable)); + enableItem->setData(Qt::UserRole, graph.enable); + QTableWidgetItem *intervalItem = new QTableWidgetItem(QString::number(graph.interval)); + groupItem->setTextAlignment(Qt::AlignCenter); + picItem->setTextAlignment(Qt::AlignCenter); + enableItem->setTextAlignment(Qt::AlignCenter); + intervalItem->setTextAlignment(Qt::AlignCenter); + m_TableWidget->setItem(row, 0, groupItem); + m_TableWidget->setItem(row, 1, picItem); + m_TableWidget->setItem(row, 2, enableItem); + m_TableWidget->setItem(row, 3, intervalItem); + row+=1; + } +} + +void ConfigWidget::slotGroupManageClick() +{ + CGroupManageDialog * dialog = new CGroupManageDialog(this); + dialog->setGroup(m_GroupList); + if(QDialog::Accepted == dialog->exec()) + { + QStringList normalGroupList = dialog->getNormalGroup(); + QStringList newGroupList = dialog->getNewGroup(); + QMap modifyGroupMap = dialog->getModifyGroup(); + QStringList modifyGroupList = modifyGroupMap.keys(); + QStringList changeList; + + //< 修改轮询组 + QMap > modifyTemp; + QMap> screenTemp; + foreach (QString modifyGroup, modifyGroupList) { + QString oldName = modifyGroupMap.value(modifyGroup, QString()); + changeList.append(oldName + "-" + modifyGroup); + QList Graph = m_hmiRollMap.value(oldName); + modifyTemp.insert(modifyGroup, Graph); + + QMap>::iterator iter = m_screenMap.begin(); + for(; iter != m_screenMap.end(); ) + { + if(iter.value().first == oldName){ + QPair temp; + temp.first = oldName; + temp.second = modifyGroup; + screenTemp.insert(iter.key(), temp); + } + iter++; + } + } + QMap >::const_iterator iter = modifyTemp.constBegin(); + for(; iter != modifyTemp.constEnd(); iter++) + { + m_hmiRollMap.insert(iter.key(), iter.value()); + } + QMap>::iterator screenIter = screenTemp.begin(); + for(; screenIter != screenTemp.end(); screenIter++) + { + QMap>::iterator iter = m_screenMap.find(screenIter.key()); + if(iter != m_screenMap.end() && iter.value().first == screenIter.value().first) + { + iter.value().first = screenIter.value().second; + } + } + + //< 新增轮询组 + foreach (QString newGroup, newGroupList) { + m_hmiRollMap.insert(newGroup, QList()); + } + + //< 删除轮询组 + QStringList nowGroupList = newGroupList + modifyGroupList + normalGroupList; + QStringList delGroupList; + foreach (QString Group, m_hmiRollMap.keys()) { + if(nowGroupList.indexOf(Group) == -1) + { + m_hmiRollMap.remove(Group); + QMap>::iterator iter = m_screenMap.begin(); + for(; iter != m_screenMap.end(); ) + { + if(iter.value().first == Group){ + iter = m_screenMap.erase(iter); + }else{ + iter++; + } + } + delGroupList.append(Group); + } + } + + m_GroupList = dialog->getGroup(); + CXmlOpt::saveHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap); + initGroup(); + + emit sigSave(changeList.join(","), delGroupList.join(",")); + } + + delete dialog; + dialog = NULL; +} + +void ConfigWidget::slotAddClick() +{ + if(m_GroupComb->currentText().isEmpty()) + return; + int addRow = m_TableWidget->rowCount(); + QList selectList = m_TableWidget->selectedRanges(); + if(!selectList.isEmpty()) + addRow = selectList.last().bottomRow() + 1; + m_TableWidget->insertRow(addRow); + QTableWidgetItem *groupItem = new QTableWidgetItem(m_GroupComb->currentText()); + QTableWidgetItem *picItem = new QTableWidgetItem(""); + QTableWidgetItem *enableItem = new QTableWidgetItem(getEnableDesc(1)); + enableItem->setData(Qt::UserRole, 1); + QTableWidgetItem *intervalItem = new QTableWidgetItem("10"); + groupItem->setTextAlignment(Qt::AlignCenter); + picItem->setTextAlignment(Qt::AlignCenter); + enableItem->setTextAlignment(Qt::AlignCenter); + intervalItem->setTextAlignment(Qt::AlignCenter); + m_TableWidget->setItem(addRow, 0, groupItem); + m_TableWidget->setItem(addRow, 1, picItem); + m_TableWidget->setItem(addRow, 2, enableItem); + m_TableWidget->setItem(addRow, 3, intervalItem); +} + +void ConfigWidget::slotDelClick() +{ + if(m_GroupComb->currentText().isEmpty()) + return; + QList selectList = m_TableWidget->selectedRanges(); + for(int nIndex=selectList.count()-1; nIndex>=0; nIndex--) + { + int bottomRow = selectList.at(nIndex).bottomRow(); + int topRow = selectList.at(nIndex).topRow(); + for(int row=bottomRow; row>=topRow; row--) + { + m_TableWidget->removeRow(row); + } + } +} + +void ConfigWidget::slotMoveUpClick() +{ + if(m_GroupComb->currentText().isEmpty()) + return; + QList selectList = m_TableWidget->selectedRanges(); + if(selectList.isEmpty() || selectList.first().topRow() == 0) + { + return; + } + + int insertRow = selectList.first().topRow() - 1; + m_TableWidget->insertRow(insertRow); + for(int col=0; colcolumnCount(); col++) + { + m_TableWidget->setItem(insertRow, col, m_TableWidget->takeItem(insertRow+2, col)); + } + m_TableWidget->removeRow(insertRow+2); + m_TableWidget->selectRow(insertRow); +} + +void ConfigWidget::slotMoveDownClick() +{ + if(m_GroupComb->currentText().isEmpty()) + return; + QList selectList = m_TableWidget->selectedRanges(); + if(selectList.isEmpty() || selectList.last().bottomRow() == m_TableWidget->rowCount()-1) + { + return; + } + + int insertRow = selectList.last().bottomRow() + 2; + m_TableWidget->insertRow(insertRow); + for(int col=0; colcolumnCount(); col++) + { + m_TableWidget->setItem(insertRow, col, m_TableWidget->takeItem(insertRow-2, col)); + } + m_TableWidget->removeRow(insertRow-2); + m_TableWidget->selectRow(insertRow-1); +} + +void ConfigWidget::slotSaveClick() +{ + if(m_GroupComb->currentText().isEmpty()) + return; + QList graphList; + for(int nIndex=0; nIndexrowCount(); nIndex++) + { + SGraph graph; + graph.pic = m_TableWidget->item(nIndex, 1)->text(); + if(graph.pic.isEmpty()){ + showInfo(tr("画面文件名称不能为空!")); + return; + } + graph.enable = m_TableWidget->item(nIndex, 2)->data(Qt::UserRole).toInt(); + graph.interval = m_TableWidget->item(nIndex, 3)->text().toInt(); + graphList.append(graph); + } + m_hmiRollMap[m_GroupComb->currentText()] = graphList; + bool success = CXmlOpt::saveHmiRollXml(m_GroupList, m_hmiRollMap, m_screenMap, m_autoTimeMap); + success ? showInfo(tr("保存成功")) : showInfo(tr("保存失败")); + emit sigSave("", ""); +} + +void ConfigWidget::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + QMenu menu; + QAction *Add = menu.addAction(tr("新增")); + connect(Add, &QAction::triggered, this, &ConfigWidget::slotAddClick); + QAction *Del = menu.addAction(tr("删除")); + connect(Del, &QAction::triggered, this, &ConfigWidget::slotDelClick); + QAction *MoveUp = menu.addAction(tr("上移")); + connect(MoveUp, &QAction::triggered, this, &ConfigWidget::slotMoveUpClick); + QAction *MoveDown = menu.addAction(tr("下移")); + connect(MoveDown, &QAction::triggered, this, &ConfigWidget::slotMoveDownClick); + menu.exec(event->globalPos()); +} + +QString ConfigWidget::getEnableDesc(int enable) +{ + if(enable == 1) + { + return tr("是"); + } + else if(enable == 0) + { + return tr("否"); + } + return QString(); +} + +void ConfigWidget::showInfo(const QString &info) +{ + QMessageBox::information(this, tr("提示"), info, QMessageBox::Ok); +} diff --git a/product/src/gui/plugin/HmiRollWidget/ConfigWidget.h b/product/src/gui/plugin/HmiRollWidget/ConfigWidget.h index b6ea197c..3af8dfe1 100644 --- a/product/src/gui/plugin/HmiRollWidget/ConfigWidget.h +++ b/product/src/gui/plugin/HmiRollWidget/ConfigWidget.h @@ -1,58 +1,58 @@ -#ifndef CONFIGWIDGET_H -#define CONFIGWIDGET_H - -#include -#include -#include -#include -#include - -class ConfigWidget : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = nullptr); - ~ConfigWidget(); - -signals: - void sigSave(const QString &modify, const QString &del); - -private: - void initWidget(); - void initGroup(); - -public slots: - void hmiSwitchOpt(); - -private slots: - void slotGroupCombChange(const QString &text); - void slotGroupManageClick(); - void slotAddClick(); - void slotDelClick(); - void slotMoveUpClick(); - void slotMoveDownClick(); - void slotSaveClick(); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - -private: - QString getEnableDesc(int enable); - void showInfo(const QString &info); - -private: - QComboBox * m_GroupComb; - QPushButton * m_GroupManage; - QPushButton * m_Add; - QPushButton * m_Del; - QPushButton * m_MoveUp; - QPushButton * m_MoveDown; - QPushButton * m_Save; - QTableWidget *m_TableWidget; - QStringList m_GroupList; - QMap > m_hmiRollMap; - QMap> m_screenMap; - QMap m_autoTimeMap; -}; - -#endif // CONFIGWIDGET_H +#ifndef CONFIGWIDGET_H +#define CONFIGWIDGET_H + +#include +#include +#include +#include +#include + +class ConfigWidget : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = nullptr); + ~ConfigWidget(); + +signals: + void sigSave(const QString &modify, const QString &del); + +private: + void initWidget(); + void initGroup(); + +public slots: + void hmiSwitchOpt(); + +private slots: + void slotGroupCombChange(const QString &text); + void slotGroupManageClick(); + void slotAddClick(); + void slotDelClick(); + void slotMoveUpClick(); + void slotMoveDownClick(); + void slotSaveClick(); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +private: + QString getEnableDesc(int enable); + void showInfo(const QString &info); + +private: + QComboBox * m_GroupComb; + QPushButton * m_GroupManage; + QPushButton * m_Add; + QPushButton * m_Del; + QPushButton * m_MoveUp; + QPushButton * m_MoveDown; + QPushButton * m_Save; + QTableWidget *m_TableWidget; + QStringList m_GroupList; + QMap > m_hmiRollMap; + QMap> m_screenMap; + QMap m_autoTimeMap; +}; + +#endif // CONFIGWIDGET_H diff --git a/product/src/gui/plugin/HmiRollWidget/HmiRollWidget.pro b/product/src/gui/plugin/HmiRollWidget/HmiRollWidget.pro index 3d3fe74a..4686237b 100644 --- a/product/src/gui/plugin/HmiRollWidget/HmiRollWidget.pro +++ b/product/src/gui/plugin/HmiRollWidget/HmiRollWidget.pro @@ -1,57 +1,57 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-11-25T08:28:23 -# -#------------------------------------------------- - -QT += core gui xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = HmiRollWidget -TEMPLATE = lib - -CONFIG += plugin -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ -# main.cpp \ - CHmiRollWidget.cpp \ - CLineEditWithBtn.cpp \ - ConfigWidget.cpp \ - CXmlOpt.cpp \ - CTableDelegata.cpp \ - CGroupManageDialog.cpp \ - CRollSwitchWidget.cpp \ - CHmiRollPlugin.cpp - -HEADERS += \ - CHmiRollWidget.h \ - CLineEditWithBtn.h \ - ConfigWidget.h \ - CXmlOpt.h \ - CTableDelegata.h \ - CGroupManageDialog.h \ - CRollSwitchWidget.h \ - CHmiRollPlugin.h - -LIBS += \ - -lpub_utility_api - - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2020-11-25T08:28:23 +# +#------------------------------------------------- + +QT += core gui xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = HmiRollWidget +TEMPLATE = lib + +CONFIG += plugin +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ +# main.cpp \ + CHmiRollWidget.cpp \ + CLineEditWithBtn.cpp \ + ConfigWidget.cpp \ + CXmlOpt.cpp \ + CTableDelegata.cpp \ + CGroupManageDialog.cpp \ + CRollSwitchWidget.cpp \ + CHmiRollPlugin.cpp + +HEADERS += \ + CHmiRollWidget.h \ + CLineEditWithBtn.h \ + ConfigWidget.h \ + CXmlOpt.h \ + CTableDelegata.h \ + CGroupManageDialog.h \ + CRollSwitchWidget.h \ + CHmiRollPlugin.h + +LIBS += \ + -lpub_utility_api + + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/HmiRollWidget/main.cpp b/product/src/gui/plugin/HmiRollWidget/main.cpp index 55c03143..19829895 100644 --- a/product/src/gui/plugin/HmiRollWidget/main.cpp +++ b/product/src/gui/plugin/HmiRollWidget/main.cpp @@ -1,15 +1,15 @@ -#include "CHmiRollWidget.h" -#include -#include - -int main(int argc, char *argv[]) -{ - QTextCodec *codec = QTextCodec::codecForName("UTF-8"); - QTextCodec::setCodecForLocale(codec); - - QApplication a(argc, argv); - CHmiRollWidget w; - w.show(); - - return a.exec(); -} +#include "CHmiRollWidget.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + QTextCodec::setCodecForLocale(codec); + + QApplication a(argc, argv); + CHmiRollWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.cpp b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.cpp index a1742926..c4a4703a 100644 --- a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.cpp +++ b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CBrowserPluginWidget.h" -#include "CBrowserWidget.h" - -CBrowserPluginWidget::CBrowserPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CBrowserPluginWidget::~CBrowserPluginWidget() -{ - -} - -bool CBrowserPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CBrowserWidget *pWidget = new CBrowserWidget(parent,editMode); - *widget = (QWidget *)pWidget; - *reportWidget = (IPluginWidget *)pWidget; - return true; -} - -void CBrowserPluginWidget::release() -{ - -} +#include +#include "CBrowserPluginWidget.h" +#include "CBrowserWidget.h" + +CBrowserPluginWidget::CBrowserPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CBrowserPluginWidget::~CBrowserPluginWidget() +{ + +} + +bool CBrowserPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CBrowserWidget *pWidget = new CBrowserWidget(parent,editMode); + *widget = (QWidget *)pWidget; + *reportWidget = (IPluginWidget *)pWidget; + return true; +} + +void CBrowserPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.h b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.h index 267ba0f6..4fd2cc2d 100644 --- a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.h +++ b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CBROWSERPLUGINWIDGET_H -#define CBROWSERPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CBrowserPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CBrowserPluginWidget(QObject *parent = 0); - ~CBrowserPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); - void release(); -}; - -#endif // CBROWSERPLUGINWIDGET_H +#ifndef CBROWSERPLUGINWIDGET_H +#define CBROWSERPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CBrowserPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CBrowserPluginWidget(QObject *parent = 0); + ~CBrowserPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); + void release(); +}; + +#endif // CBROWSERPLUGINWIDGET_H diff --git a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserWidget.cpp b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserWidget.cpp index bb56782d..7061f792 100644 --- a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserWidget.cpp +++ b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserWidget.cpp @@ -1,273 +1,273 @@ -#include "CBrowserWidget.h" -#include "pub_logger_api/logger.h" -#include - -CBrowserWidget::CBrowserWidget(QWidget *parent, bool editMode) - : QWidget(parent) -{ - m_pView = NULL; - m_rtdbAccess = NULL; - if(editMode) - { - QLabel *label = new QLabel(this); - label->setPixmap(QPixmap(":/report")); - label->setScaledContents(true); - QGridLayout *lay = new QGridLayout(this); - lay->addWidget(label); - this->setLayout(lay); - } - else - { - init(); - } -} - -CBrowserWidget::~CBrowserWidget() -{ - if(m_pView) - { - QWebEngineProfile * engineProfile = m_pView->page()->profile(); - engineProfile->clearHttpCache(); - QWebEngineCookieStore *cookie = engineProfile->cookieStore(); - cookie->deleteAllCookies(); - delete m_pView; - } - m_pView = NULL; - - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; -} - -void CBrowserWidget::init() -{ - QNetworkProxyFactory::setUseSystemConfiguration(false); - QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); - QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_pView = new QWebEngineView(this); - m_pView->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); - m_pView->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); - m_pView->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); - connect(m_pView, &QWebEngineView::loadFinished, this, &CBrowserWidget::slotLoadFinish); - - QGridLayout * layout = new QGridLayout(this); - layout->addWidget(m_pView); - layout->setMargin(0); - this->setLayout(layout); - - m_isHTML = false; - m_addrNum = 0; - initSysInfo(); -} - -void CBrowserWidget::initSysInfo() -{ - if (createSysInfoInstance(m_sysInfoPtr)) - { - SNodeInfo LocalNode,ServerNode1,ServerNode2; - m_sysInfoPtr->getLocalNodeInfo(LocalNode); //获取当前节点信息 - int DomainId=LocalNode.nDomainId; //获取当前节点所属域ID - SAppInfo AppInfo; - m_sysInfoPtr->getAppInfoByName("COMAPP", AppInfo); - int AppId = AppInfo.nId; - SAppDeploy AppDeploy; - m_sysInfoPtr->getAppDeployById(DomainId,AppId,AppDeploy); //获取当前域公共应用部署信息 - std::string ServerNodeName1 = AppDeploy.strNode1; //获取当前域公共应用部署的第一个节点名 - m_sysInfoPtr->getNodeInfoByName(ServerNodeName1,ServerNode1); //获取公共应用部署的节点信息 - m_ServerAddr[0] = ServerNode1.strNic1Addr; //获取公共应用部署的节点IP地址 - m_ServerNode[0] = ServerNodeName1; - if(AppDeploy.strNode2 != "") - { - std::string ServerNodeName2 = AppDeploy.strNode2; - m_sysInfoPtr->getNodeInfoByName(ServerNodeName2,ServerNode2); - m_ServerAddr[1] = ServerNode2.strNic1Addr; - m_ServerNode[1] = ServerNodeName2; - } - setNicAddr(AppId); - } -} - -void CBrowserWidget::setNicAddr(int appId) -{ - std::string ipAddr1 = ""; - std::string ipAddr2 = ""; - std::string node1 = ""; - std::string node2 = ""; - std::vector> vector = getRunRedundancyInfoByAppid(appId); - for(size_t i=0; i vec = vector.at(i); - std::string node_name = vec.at(0).toStdString(); - int is_active = vec.at(1).toInt(); - int is_master = vec.at(2).toInt(); - int is_slave = vec.at(3).toInt(); - std::string ip1 = vec.at(4).toStdString(); - int ip1_active = vec.at(5).toInt(); - std::string ip2 = vec.at(6).toStdString(); - int ip2_active = vec.at(7).toInt(); - - if(is_active != 1) - { - continue; - } - if(is_master == 1) - { - node1 = node_name; - if(ip1_active == 1) - ipAddr1 = ip1; - else if(ip2_active == 1) - ipAddr1 = ip2; - } - else if(is_slave == 1) - { - node2 = node_name; - if(ip1_active == 1) - ipAddr2 = ip1; - else if(ip2_active == 1) - ipAddr2 = ip2; - } - } - if(ipAddr1 == "" && ipAddr2 == "") - {} - else if(ipAddr1 == "") - { - std::string temp = getAnotherIp(node2); - m_ServerAddr[0] = temp; - m_ServerAddr[1] = ipAddr2; - } - else if(ipAddr2 == "") - { - std::string temp = getAnotherIp(node1); - m_ServerAddr[0] = ipAddr1; - m_ServerAddr[1] = temp; - } - else - { - m_ServerAddr[0] = ipAddr1; - m_ServerAddr[1] = ipAddr2; - } -} - -std::string CBrowserWidget::getAnotherIp(const std::string &node) -{ - std::string ret = ""; - if(node == m_ServerNode[0]) - { - ret = m_ServerAddr[1]; - } - else - { - ret = m_ServerAddr[0]; - } - return ret; -} - -std::vector> CBrowserWidget::getRunRedundancyInfoByAppid(int appId) -{ - std::vector> vector; - if(m_rtdbAccess->open("base", "sys_run_redundancy_info")) - { - kbd_dbms::CONDINFO condition; - memcpy(condition.name, "app_id", strlen("app_id")); - condition.logicalop = ATTRCOND_AND; - condition.relationop = ATTRCOND_EQU; - condition.conditionval = appId; - - std::vector vecCondInfo; - vecCondInfo.push_back(condition); - - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("node_name"); - columns.push_back("is_active"); - columns.push_back("is_master"); - columns.push_back("is_slave"); - columns.push_back("ip1"); - columns.push_back("ip1_active"); - columns.push_back("ip2"); - columns.push_back("ip2_active"); - - if(m_rtdbAccess->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - std::vector temp; - kbd_dbms::CVarType node_name; - kbd_dbms::CVarType is_active; - kbd_dbms::CVarType is_master; - kbd_dbms::CVarType is_slave; - kbd_dbms::CVarType ip1; - kbd_dbms::CVarType ip1_active; - kbd_dbms::CVarType ip2; - kbd_dbms::CVarType ip2_active; - result.getColumnValue(nIndex, 0, node_name); - result.getColumnValue(nIndex, 1, is_active); - result.getColumnValue(nIndex, 2, is_master); - result.getColumnValue(nIndex, 3, is_slave); - result.getColumnValue(nIndex, 4, ip1); - result.getColumnValue(nIndex, 5, ip1_active); - result.getColumnValue(nIndex, 6, ip2); - result.getColumnValue(nIndex, 7, ip2_active); - temp.push_back(node_name); - temp.push_back(is_active); - temp.push_back(is_master); - temp.push_back(is_slave); - temp.push_back(ip1); - temp.push_back(ip1_active); - temp.push_back(ip2); - temp.push_back(ip2_active); - vector.push_back(temp); - } - } - m_rtdbAccess->close(); - } - return vector; -} - -void CBrowserWidget::loadHtml(const QString &url) -{ - if(url == QString()) - { - return; - } - m_isHTML = true; - QUrl html(url); - LOGINFO("loadPage url: %s", url.toStdString().c_str()); - m_pView->load(html); -} - -void CBrowserWidget::loadPage(const QString &url) -{ - if(url == QString()) - { - return; - } - m_isHTML = true; - QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum]) + url; - QUrl html(urlstr); - LOGINFO("loadPage url: %s", urlstr.toStdString().c_str()); - m_pView->load(html); -} - -void CBrowserWidget::slotLoadFinish(bool ok) -{ - if(m_isHTML) - { - if (!ok) - { - LOGINFO("slotLoadFinish fail!"); - std::string path = kbd_public::CFileUtil::getCurModuleDir(); - m_pView->load(QUrl::fromLocalFile(QString::fromStdString(path)+"../../data/report/FAIL_PAGE.html")); - } - else - { - LOGINFO("slotLoadFinish success!"); - } - } - m_isHTML = false; -} - +#include "CBrowserWidget.h" +#include "pub_logger_api/logger.h" +#include + +CBrowserWidget::CBrowserWidget(QWidget *parent, bool editMode) + : QWidget(parent) +{ + m_pView = NULL; + m_rtdbAccess = NULL; + if(editMode) + { + QLabel *label = new QLabel(this); + label->setPixmap(QPixmap(":/report")); + label->setScaledContents(true); + QGridLayout *lay = new QGridLayout(this); + lay->addWidget(label); + this->setLayout(lay); + } + else + { + init(); + } +} + +CBrowserWidget::~CBrowserWidget() +{ + if(m_pView) + { + QWebEngineProfile * engineProfile = m_pView->page()->profile(); + engineProfile->clearHttpCache(); + QWebEngineCookieStore *cookie = engineProfile->cookieStore(); + cookie->deleteAllCookies(); + delete m_pView; + } + m_pView = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; +} + +void CBrowserWidget::init() +{ + QNetworkProxyFactory::setUseSystemConfiguration(false); + QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_pView = new QWebEngineView(this); + m_pView->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); + m_pView->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); + m_pView->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); + connect(m_pView, &QWebEngineView::loadFinished, this, &CBrowserWidget::slotLoadFinish); + + QGridLayout * layout = new QGridLayout(this); + layout->addWidget(m_pView); + layout->setMargin(0); + this->setLayout(layout); + + m_isHTML = false; + m_addrNum = 0; + initSysInfo(); +} + +void CBrowserWidget::initSysInfo() +{ + if (createSysInfoInstance(m_sysInfoPtr)) + { + SNodeInfo LocalNode,ServerNode1,ServerNode2; + m_sysInfoPtr->getLocalNodeInfo(LocalNode); //获取当前节点信息 + int DomainId=LocalNode.nDomainId; //获取当前节点所属域ID + SAppInfo AppInfo; + m_sysInfoPtr->getAppInfoByName("COMAPP", AppInfo); + int AppId = AppInfo.nId; + SAppDeploy AppDeploy; + m_sysInfoPtr->getAppDeployById(DomainId,AppId,AppDeploy); //获取当前域公共应用部署信息 + std::string ServerNodeName1 = AppDeploy.strNode1; //获取当前域公共应用部署的第一个节点名 + m_sysInfoPtr->getNodeInfoByName(ServerNodeName1,ServerNode1); //获取公共应用部署的节点信息 + m_ServerAddr[0] = ServerNode1.strNic1Addr; //获取公共应用部署的节点IP地址 + m_ServerNode[0] = ServerNodeName1; + if(AppDeploy.strNode2 != "") + { + std::string ServerNodeName2 = AppDeploy.strNode2; + m_sysInfoPtr->getNodeInfoByName(ServerNodeName2,ServerNode2); + m_ServerAddr[1] = ServerNode2.strNic1Addr; + m_ServerNode[1] = ServerNodeName2; + } + setNicAddr(AppId); + } +} + +void CBrowserWidget::setNicAddr(int appId) +{ + std::string ipAddr1 = ""; + std::string ipAddr2 = ""; + std::string node1 = ""; + std::string node2 = ""; + std::vector> vector = getRunRedundancyInfoByAppid(appId); + for(size_t i=0; i vec = vector.at(i); + std::string node_name = vec.at(0).toStdString(); + int is_active = vec.at(1).toInt(); + int is_master = vec.at(2).toInt(); + int is_slave = vec.at(3).toInt(); + std::string ip1 = vec.at(4).toStdString(); + int ip1_active = vec.at(5).toInt(); + std::string ip2 = vec.at(6).toStdString(); + int ip2_active = vec.at(7).toInt(); + + if(is_active != 1) + { + continue; + } + if(is_master == 1) + { + node1 = node_name; + if(ip1_active == 1) + ipAddr1 = ip1; + else if(ip2_active == 1) + ipAddr1 = ip2; + } + else if(is_slave == 1) + { + node2 = node_name; + if(ip1_active == 1) + ipAddr2 = ip1; + else if(ip2_active == 1) + ipAddr2 = ip2; + } + } + if(ipAddr1 == "" && ipAddr2 == "") + {} + else if(ipAddr1 == "") + { + std::string temp = getAnotherIp(node2); + m_ServerAddr[0] = temp; + m_ServerAddr[1] = ipAddr2; + } + else if(ipAddr2 == "") + { + std::string temp = getAnotherIp(node1); + m_ServerAddr[0] = ipAddr1; + m_ServerAddr[1] = temp; + } + else + { + m_ServerAddr[0] = ipAddr1; + m_ServerAddr[1] = ipAddr2; + } +} + +std::string CBrowserWidget::getAnotherIp(const std::string &node) +{ + std::string ret = ""; + if(node == m_ServerNode[0]) + { + ret = m_ServerAddr[1]; + } + else + { + ret = m_ServerAddr[0]; + } + return ret; +} + +std::vector> CBrowserWidget::getRunRedundancyInfoByAppid(int appId) +{ + std::vector> vector; + if(m_rtdbAccess->open("base", "sys_run_redundancy_info")) + { + kbd_dbms::CONDINFO condition; + memcpy(condition.name, "app_id", strlen("app_id")); + condition.logicalop = ATTRCOND_AND; + condition.relationop = ATTRCOND_EQU; + condition.conditionval = appId; + + std::vector vecCondInfo; + vecCondInfo.push_back(condition); + + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("node_name"); + columns.push_back("is_active"); + columns.push_back("is_master"); + columns.push_back("is_slave"); + columns.push_back("ip1"); + columns.push_back("ip1_active"); + columns.push_back("ip2"); + columns.push_back("ip2_active"); + + if(m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + std::vector temp; + kbd_dbms::CVarType node_name; + kbd_dbms::CVarType is_active; + kbd_dbms::CVarType is_master; + kbd_dbms::CVarType is_slave; + kbd_dbms::CVarType ip1; + kbd_dbms::CVarType ip1_active; + kbd_dbms::CVarType ip2; + kbd_dbms::CVarType ip2_active; + result.getColumnValue(nIndex, 0, node_name); + result.getColumnValue(nIndex, 1, is_active); + result.getColumnValue(nIndex, 2, is_master); + result.getColumnValue(nIndex, 3, is_slave); + result.getColumnValue(nIndex, 4, ip1); + result.getColumnValue(nIndex, 5, ip1_active); + result.getColumnValue(nIndex, 6, ip2); + result.getColumnValue(nIndex, 7, ip2_active); + temp.push_back(node_name); + temp.push_back(is_active); + temp.push_back(is_master); + temp.push_back(is_slave); + temp.push_back(ip1); + temp.push_back(ip1_active); + temp.push_back(ip2); + temp.push_back(ip2_active); + vector.push_back(temp); + } + } + m_rtdbAccess->close(); + } + return vector; +} + +void CBrowserWidget::loadHtml(const QString &url) +{ + if(url == QString()) + { + return; + } + m_isHTML = true; + QUrl html(url); + LOGINFO("loadPage url: %s", url.toStdString().c_str()); + m_pView->load(html); +} + +void CBrowserWidget::loadPage(const QString &url) +{ + if(url == QString()) + { + return; + } + m_isHTML = true; + QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum]) + url; + QUrl html(urlstr); + LOGINFO("loadPage url: %s", urlstr.toStdString().c_str()); + m_pView->load(html); +} + +void CBrowserWidget::slotLoadFinish(bool ok) +{ + if(m_isHTML) + { + if (!ok) + { + LOGINFO("slotLoadFinish fail!"); + std::string path = kbd_public::CFileUtil::getCurModuleDir(); + m_pView->load(QUrl::fromLocalFile(QString::fromStdString(path)+"../../data/report/FAIL_PAGE.html")); + } + else + { + LOGINFO("slotLoadFinish success!"); + } + } + m_isHTML = false; +} + diff --git a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserWidget.h b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserWidget.h index 9bd6697f..f3704830 100644 --- a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserWidget.h +++ b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserWidget.h @@ -1,52 +1,52 @@ -#ifndef CBROWSERWIDGET_H -#define CBROWSERWIDGET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" - -using namespace kbd_public; -class CBrowserWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CBrowserWidget(QWidget *parent, bool editMode); - ~CBrowserWidget(); - -public slots: - void loadHtml(const QString &url = QString()); - void loadPage(const QString &url = QString()); - -private: - void init(); - void initSysInfo(); - void setNicAddr(int appId); - std::string getAnotherIp(const std::string &node); - std::vector > getRunRedundancyInfoByAppid(int appId); - void slotLoadFinish(bool ok); - -private: - QWebEngineView *m_pView; - kbd_dbms::CRdbAccess * m_rtdbAccess; - CSysInfoInterfacePtr m_sysInfoPtr; - std::string m_ServerNode[2]; - std::string m_ServerAddr[2]; - bool m_isHTML; - int m_addrNum; -}; - - - - -#endif // CBROWSERWIDGET_H +#ifndef CBROWSERWIDGET_H +#define CBROWSERWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" + +using namespace kbd_public; +class CBrowserWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CBrowserWidget(QWidget *parent, bool editMode); + ~CBrowserWidget(); + +public slots: + void loadHtml(const QString &url = QString()); + void loadPage(const QString &url = QString()); + +private: + void init(); + void initSysInfo(); + void setNicAddr(int appId); + std::string getAnotherIp(const std::string &node); + std::vector > getRunRedundancyInfoByAppid(int appId); + void slotLoadFinish(bool ok); + +private: + QWebEngineView *m_pView; + kbd_dbms::CRdbAccess * m_rtdbAccess; + CSysInfoInterfacePtr m_sysInfoPtr; + std::string m_ServerNode[2]; + std::string m_ServerAddr[2]; + bool m_isHTML; + int m_addrNum; +}; + + + + +#endif // CBROWSERWIDGET_H diff --git a/product/src/gui/plugin/HtmlBrowserWidget/HtmlBrowserWidget.pro b/product/src/gui/plugin/HtmlBrowserWidget/HtmlBrowserWidget.pro index 254697aa..8b9d856a 100644 --- a/product/src/gui/plugin/HtmlBrowserWidget/HtmlBrowserWidget.pro +++ b/product/src/gui/plugin/HtmlBrowserWidget/HtmlBrowserWidget.pro @@ -1,52 +1,52 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-11-13T14:55:16 -# -#------------------------------------------------- - -QT += core gui webenginewidgets - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = HtmlBrowser -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CBrowserWidget.cpp \ - CBrowserPluginWidget.cpp - -HEADERS += \ - CBrowserWidget.h \ - CBrowserPluginWidget.h - -RESOURCES += \ - resource.qrc - -LIBS += \ - -lpub_sysinfo_api \ - -lpub_utility_api \ - -lrdb_api \ - -llog4cplus \ - -lpub_logger_api \ - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2018-11-13T14:55:16 +# +#------------------------------------------------- + +QT += core gui webenginewidgets + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = HtmlBrowser +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CBrowserWidget.cpp \ + CBrowserPluginWidget.cpp + +HEADERS += \ + CBrowserWidget.h \ + CBrowserPluginWidget.h + +RESOURCES += \ + resource.qrc + +LIBS += \ + -lpub_sysinfo_api \ + -lpub_utility_api \ + -lrdb_api \ + -llog4cplus \ + -lpub_logger_api \ + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/HtmlBrowserWidget/resource.qrc b/product/src/gui/plugin/HtmlBrowserWidget/resource.qrc index 81d727c0..361a3f26 100644 --- a/product/src/gui/plugin/HtmlBrowserWidget/resource.qrc +++ b/product/src/gui/plugin/HtmlBrowserWidget/resource.qrc @@ -1,5 +1,5 @@ - - - report.png - - + + + report.png + + diff --git a/product/src/gui/plugin/ISCSAlarmWidget/AlarmWidget.pro b/product/src/gui/plugin/ISCSAlarmWidget/AlarmWidget.pro index 54e1cedd..f5d21883 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/AlarmWidget.pro +++ b/product/src/gui/plugin/ISCSAlarmWidget/AlarmWidget.pro @@ -1,97 +1,97 @@ -QT += core sql xml multimedia printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = ISCSAlarmWidget - -CONFIG += plugin - -HEADERS = \ - CAlarmItemModel.h \ - CAlarmView.h \ - CAlarmDelegate.h \ - CAlarmForm.h \ - CAlarmFilterDialog.h \ - CAlarmWidget.h \ - CAlarmDataCollect.h \ - CAlarmMsgInfo.h \ - CAlarmPlugin.h \ - CAlarmMsgManage.h \ - CAlarmPluginWidget.h \ - CAlarmMediaPlayer.h \ - CTableViewPrinter.h \ - CAlarmInhibitDialog.h \ - CAlarmDeviceTreeItem.h \ - CAlarmDeviceTreeModel.h \ - CAlarmDeviceTreeView.h \ - CAlarmCommon.h \ - CMyListWidget.h \ - CMyCalendar.h \ - CMyCheckBox.h \ - CAiAlarmTreeView.h \ - CAiAlarmMsgInfo.h \ - CAiAlarmDataCollect.h \ - CAiAlarmTreeItem.h \ - CAiAlarmTreeModel.h \ - CAiAlarmDelegate.h \ - CDisposalPlanDialog.h \ - CTreeViewPrinter.h \ - CPdfPrinter.h - -SOURCES = \ - CAlarmItemModel.cpp \ - CAlarmView.cpp \ - CAlarmDelegate.cpp \ - CAlarmForm.cpp \ - CAlarmFilterDialog.cpp \ - CAlarmWidget.cpp \ - CAlarmDataCollect.cpp \ - CAlarmMsgInfo.cpp \ - CAlarmPlugin.cpp \ - CAlarmMsgManage.cpp \ - CAlarmPluginWidget.cpp \ - CAlarmMediaPlayer.cpp \ - CTableViewPrinter.cpp \ - CAlarmInhibitDialog.cpp \ - CAlarmDeviceTreeModel.cpp \ - CAlarmDeviceTreeItem.cpp \ - CAlarmDeviceTreeView.cpp \ - CMyListWidget.cpp \ - CMyCalendar.cpp \ - CMyCheckBox.cpp \ - CAiAlarmTreeView.cpp \ - CAiAlarmMsgInfo.cpp \ - CAiAlarmDataCollect.cpp \ - CAiAlarmTreeItem.cpp \ - CAiAlarmTreeModel.cpp \ - CAiAlarmDelegate.cpp \ - CDisposalPlanDialog.cpp \ - CTreeViewPrinter.cpp \ - CPdfPrinter.cpp - -FORMS += \ - CAlarmFilterDialog.ui \ - CAlarmForm.ui \ - CAlarmInhibitDialog.ui \ - CMyCalendar.ui \ - CDisposalPlanDialog.ui - - -LIBS += -llog4cplus -lboost_system -lboost_filesystem -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api -ldb_sysinfo_api -LIBS += -lnet_msg_bus_api -lalarm_server_api -lintelli_alm_api -lmodel_excel - -win32{ - # CAlarmMediaPlayer.cpp 检测声卡的代码使用 - LIBS += -lole32 -} - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +QT += core sql xml multimedia printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = ISCSAlarmWidget + +CONFIG += plugin + +HEADERS = \ + CAlarmItemModel.h \ + CAlarmView.h \ + CAlarmDelegate.h \ + CAlarmForm.h \ + CAlarmFilterDialog.h \ + CAlarmWidget.h \ + CAlarmDataCollect.h \ + CAlarmMsgInfo.h \ + CAlarmPlugin.h \ + CAlarmMsgManage.h \ + CAlarmPluginWidget.h \ + CAlarmMediaPlayer.h \ + CTableViewPrinter.h \ + CAlarmInhibitDialog.h \ + CAlarmDeviceTreeItem.h \ + CAlarmDeviceTreeModel.h \ + CAlarmDeviceTreeView.h \ + CAlarmCommon.h \ + CMyListWidget.h \ + CMyCalendar.h \ + CMyCheckBox.h \ + CAiAlarmTreeView.h \ + CAiAlarmMsgInfo.h \ + CAiAlarmDataCollect.h \ + CAiAlarmTreeItem.h \ + CAiAlarmTreeModel.h \ + CAiAlarmDelegate.h \ + CDisposalPlanDialog.h \ + CTreeViewPrinter.h \ + CPdfPrinter.h + +SOURCES = \ + CAlarmItemModel.cpp \ + CAlarmView.cpp \ + CAlarmDelegate.cpp \ + CAlarmForm.cpp \ + CAlarmFilterDialog.cpp \ + CAlarmWidget.cpp \ + CAlarmDataCollect.cpp \ + CAlarmMsgInfo.cpp \ + CAlarmPlugin.cpp \ + CAlarmMsgManage.cpp \ + CAlarmPluginWidget.cpp \ + CAlarmMediaPlayer.cpp \ + CTableViewPrinter.cpp \ + CAlarmInhibitDialog.cpp \ + CAlarmDeviceTreeModel.cpp \ + CAlarmDeviceTreeItem.cpp \ + CAlarmDeviceTreeView.cpp \ + CMyListWidget.cpp \ + CMyCalendar.cpp \ + CMyCheckBox.cpp \ + CAiAlarmTreeView.cpp \ + CAiAlarmMsgInfo.cpp \ + CAiAlarmDataCollect.cpp \ + CAiAlarmTreeItem.cpp \ + CAiAlarmTreeModel.cpp \ + CAiAlarmDelegate.cpp \ + CDisposalPlanDialog.cpp \ + CTreeViewPrinter.cpp \ + CPdfPrinter.cpp + +FORMS += \ + CAlarmFilterDialog.ui \ + CAlarmForm.ui \ + CAlarmInhibitDialog.ui \ + CMyCalendar.ui \ + CDisposalPlanDialog.ui + + +LIBS += -llog4cplus -lboost_system -lboost_filesystem -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api -ldb_sysinfo_api +LIBS += -lnet_msg_bus_api -lalarm_server_api -lintelli_alm_api -lmodel_excel + +win32{ + # CAlarmMediaPlayer.cpp 检测声卡的代码使用 + LIBS += -lole32 +} + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDataCollect.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDataCollect.cpp index 5dcc2066..51bb94f9 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDataCollect.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDataCollect.cpp @@ -1,224 +1,224 @@ -#include "CAiAlarmDataCollect.h" -#include "pub_logger_api/logger.h" -#include "CAlarmMsgManage.h" -#include -#include "CAlarmDataCollect.h" -using namespace kbd_service; -CAiAlarmDataCollect * CAiAlarmDataCollect::m_pInstance = NULL; -CAiAlarmDataCollect::CAiAlarmDataCollect() - : CIntelliAlmApi4Clt(), - m_bFaultRecallState(false), - m_pAlternateTimer(Q_NULLPTR) -{ - m_rtdbMutex = new QMutex(); - m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); - m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); -} - -CAiAlarmDataCollect::~CAiAlarmDataCollect() -{ - LOGDEBUG("CAiAlarmDataCollect::~CAiAlarmDataCollect()"); - qDebug() << "~CAiAlarmDataCollect()"; -} - -CAiAlarmDataCollect *CAiAlarmDataCollect::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CAiAlarmDataCollect(); - } - return m_pInstance; -} - -void CAiAlarmDataCollect::initialize() -{ - CAlarmDataCollect::instance()->initialize(); - resumeThread(); - if(!m_pAlternateTimer) - { - m_pAlternateTimer = new QTimer(); - m_pAlternateTimer->setInterval(2000); - connect(m_pAlternateTimer, &QTimer::timeout, this, &CAiAlarmDataCollect::slotAiAlarmStateChanged); - connect(this, &CAiAlarmDataCollect::sigTimerShot, this, &CAiAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); - } - emit sigTimerShot(true); -} - -void CAiAlarmDataCollect::release() -{ - emit sigTimerShot(false); - suspendThread(true); - QMutexLocker locker(m_rtdbMutex); - CAlarmDataCollect::instance()->release(); - emit sigMsgRefresh(); -} - -bool CAiAlarmDataCollect::isFaultRecallState() -{ - return m_bFaultRecallState; -} - -bool CAiAlarmDataCollect::requestDelAlm(kbd_idlfile::SIntelliAlmDel &objDelAlm) -{ - LOGDEBUG("请求删除!"); - return kbd_service::CIntelliAlmApi4Clt::requestDelAlm(objDelAlm); -} - -bool CAiAlarmDataCollect::requestSeprAlm(kbd_idlfile::SIntelliAlmSepr &objSeprAlm) -{ - LOGDEBUG("请求分离!"); - return kbd_service::CIntelliAlmApi4Clt::requestSeprAlm(objSeprAlm); -} - -bool CAiAlarmDataCollect::requestMergeAlm(kbd_idlfile::SIntelliAlmMerge &objMergeAlm) -{ - LOGDEBUG("请求合并!"); - return kbd_service::CIntelliAlmApi4Clt::requestMergeAlm(objMergeAlm); -} - -void CAiAlarmDataCollect::handleAllAlmMsg(int nDomainId, kbd_idlfile::SIntelliAlmAdd &objAllAlm) -{ - LOGINFO("========== AiAlarmDataCollect handleAllAlmMsg =========="); - - //< 清空该域缓存 - QMutexLocker locker(m_rtdbMutex); - CAlarmMsgManage::instance()->removeAiAlarmMsgByDomainID(nDomainId); - //构建告警 - int nAlarmCount = objAllAlm.alm_info_size(); - for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) - { - kbd_idlfile::SIntelliAlmInfo msg = objAllAlm.alm_info(nAddMsgIndex); - AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); - alm->initialize(msg); - alm->priorityOrder = queryPriorityOrder(alm->priority); - CAlarmMsgManage::instance()->addAiAllAlarmMsg(alm);//添加全部完成后,通知model重新拉取数据 - } - LOGDEBUG("AiAlarmDataCollect COUNT:[%d]",nAlarmCount); - emit sigMsgRefresh(); -} - -void CAiAlarmDataCollect::handleAddAlmMsg(kbd_idlfile::SIntelliAlmAdd &objAddAlm) -{ - LOGINFO("========== AiAlarmDataCollect handleAddAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - //构建告警 - int nAlarmCount = objAddAlm.alm_info_size(); - for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) - { - kbd_idlfile::SIntelliAlmInfo msg = objAddAlm.alm_info(nAddMsgIndex); - AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); - alm->initialize(msg); - alm->priorityOrder = queryPriorityOrder(alm->priority); - CAlarmMsgManage::instance()->addAiAlarmMsg(alm); //单独添加的时候,来一条通知一次model添加 - } - LOGDEBUG("AiAlarmDataCollect handleAddAlmMsg():count[%d]",nAlarmCount); -} - -void CAiAlarmDataCollect::handleDelAlmMsg(kbd_idlfile::SIntelliAlmDel &objDelAlm) -{ - LOGINFO("========== AiAlarmDataCollect handleDelAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - //构建告警 - int nAlarmCount = objDelAlm.uuid_base64_size(); - for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) - { - QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); - CAlarmMsgManage::instance()->delAiAlarmMsg(uuid); - } -} - -void CAiAlarmDataCollect::handleBrokenAlmMsg(kbd_idlfile::SIntelliAlmBroken &objBrokenAlm) -{ - //先保证能够编译通过 - LOGINFO("========== AiAlarmDataCollect handleBrokenAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - int nAlarmCount = objBrokenAlm.uuid_base64_size(); - for(int nBrokenMsgIndex(0); nBrokenMsgIndex < nAlarmCount; nBrokenMsgIndex++) - { - QString uuid = QString::fromStdString(objBrokenAlm.uuid_base64(nBrokenMsgIndex)); - CAlarmMsgManage::instance()->brokenAiAlarmMsg(uuid); - } -} - -void CAiAlarmDataCollect::handleReleaseAlmMsg(kbd_idlfile::SIntelliAlmRelease &objReleaseAlm) -{ - //先保证能够编译通过 - LOGINFO("========== AiAlarmDataCollect handleReleaseAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - int nAlarmCount = objReleaseAlm.uuid_base64_size(); - for(int nReleaseMsgIndex(0); nReleaseMsgIndex < nAlarmCount; nReleaseMsgIndex++) - { - QString uuid = QString::fromStdString(objReleaseAlm.uuid_base64(nReleaseMsgIndex)); - CAlarmMsgManage::instance()->releaseAiAlarmMsg(uuid); - } - LOGDEBUG("AiAlarmDataCollect handleReleaseAlmMsg():count[%d]--uuid[%s]",nAlarmCount,objReleaseAlm.uuid_base64(0).c_str()); - -} - -void CAiAlarmDataCollect::destory(bool *exit) -{ - m_pAlternateTimer->blockSignals(true); - suspendThread(); - { - QMutexLocker locker(m_rtdbMutex); - if(Q_NULLPTR != m_pAlternateTimer) - { - m_pAlternateTimer->stop(); - m_pAlternateTimer->deleteLater(); - } - m_pAlternateTimer = Q_NULLPTR; - } - delete m_rtdbMutex; - delete m_rtdbPriorityOrderAccess; - m_pInstance = NULL; - delete this; - - *exit = true; -} - -void CAiAlarmDataCollect::slotTimerShot(const bool start) -{ - if(m_pAlternateTimer) - { - if(start) - { - m_pAlternateTimer->start(); - } - else - { - m_pAlternateTimer->stop(); - } - } -} - -void CAiAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) -{ - m_bFaultRecallState = bFaultRecallState; - release(); - emit sigMsgRefresh(); - CAlarmDataCollect::instance()->slotSwitchFaultRecallState(m_bFaultRecallState); - m_pInstance->reinit(m_bFaultRecallState); - - initialize(); - emit sigAlarmOperateEnable(!m_bFaultRecallState); -} - -int CAiAlarmDataCollect::queryPriorityOrder(int &id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); - kbd_dbms::CVarType value = -1000; - m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); - return value.toInt(); -} - -void CAiAlarmDataCollect::slotAiAlarmStateChanged() -{ - QMutexLocker locker(m_rtdbMutex); - CAlarmMsgManage::instance()->dealDelayAi(); - if(CAlarmMsgManage::instance()->needUpdateAi()) - { - CAlarmMsgManage::instance()->updateAiInfo(); - emit sigMsgRefresh(); - } - emit sigUpdateAlarmView(); -} +#include "CAiAlarmDataCollect.h" +#include "pub_logger_api/logger.h" +#include "CAlarmMsgManage.h" +#include +#include "CAlarmDataCollect.h" +using namespace kbd_service; +CAiAlarmDataCollect * CAiAlarmDataCollect::m_pInstance = NULL; +CAiAlarmDataCollect::CAiAlarmDataCollect() + : CIntelliAlmApi4Clt(), + m_bFaultRecallState(false), + m_pAlternateTimer(Q_NULLPTR) +{ + m_rtdbMutex = new QMutex(); + m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); +} + +CAiAlarmDataCollect::~CAiAlarmDataCollect() +{ + LOGDEBUG("CAiAlarmDataCollect::~CAiAlarmDataCollect()"); + qDebug() << "~CAiAlarmDataCollect()"; +} + +CAiAlarmDataCollect *CAiAlarmDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAiAlarmDataCollect(); + } + return m_pInstance; +} + +void CAiAlarmDataCollect::initialize() +{ + CAlarmDataCollect::instance()->initialize(); + resumeThread(); + if(!m_pAlternateTimer) + { + m_pAlternateTimer = new QTimer(); + m_pAlternateTimer->setInterval(2000); + connect(m_pAlternateTimer, &QTimer::timeout, this, &CAiAlarmDataCollect::slotAiAlarmStateChanged); + connect(this, &CAiAlarmDataCollect::sigTimerShot, this, &CAiAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); + } + emit sigTimerShot(true); +} + +void CAiAlarmDataCollect::release() +{ + emit sigTimerShot(false); + suspendThread(true); + QMutexLocker locker(m_rtdbMutex); + CAlarmDataCollect::instance()->release(); + emit sigMsgRefresh(); +} + +bool CAiAlarmDataCollect::isFaultRecallState() +{ + return m_bFaultRecallState; +} + +bool CAiAlarmDataCollect::requestDelAlm(kbd_idlfile::SIntelliAlmDel &objDelAlm) +{ + LOGDEBUG("请求删除!"); + return kbd_service::CIntelliAlmApi4Clt::requestDelAlm(objDelAlm); +} + +bool CAiAlarmDataCollect::requestSeprAlm(kbd_idlfile::SIntelliAlmSepr &objSeprAlm) +{ + LOGDEBUG("请求分离!"); + return kbd_service::CIntelliAlmApi4Clt::requestSeprAlm(objSeprAlm); +} + +bool CAiAlarmDataCollect::requestMergeAlm(kbd_idlfile::SIntelliAlmMerge &objMergeAlm) +{ + LOGDEBUG("请求合并!"); + return kbd_service::CIntelliAlmApi4Clt::requestMergeAlm(objMergeAlm); +} + +void CAiAlarmDataCollect::handleAllAlmMsg(int nDomainId, kbd_idlfile::SIntelliAlmAdd &objAllAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleAllAlmMsg =========="); + + //< 清空该域缓存 + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->removeAiAlarmMsgByDomainID(nDomainId); + //构建告警 + int nAlarmCount = objAllAlm.alm_info_size(); + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + kbd_idlfile::SIntelliAlmInfo msg = objAllAlm.alm_info(nAddMsgIndex); + AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + CAlarmMsgManage::instance()->addAiAllAlarmMsg(alm);//添加全部完成后,通知model重新拉取数据 + } + LOGDEBUG("AiAlarmDataCollect COUNT:[%d]",nAlarmCount); + emit sigMsgRefresh(); +} + +void CAiAlarmDataCollect::handleAddAlmMsg(kbd_idlfile::SIntelliAlmAdd &objAddAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleAddAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //构建告警 + int nAlarmCount = objAddAlm.alm_info_size(); + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + kbd_idlfile::SIntelliAlmInfo msg = objAddAlm.alm_info(nAddMsgIndex); + AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + CAlarmMsgManage::instance()->addAiAlarmMsg(alm); //单独添加的时候,来一条通知一次model添加 + } + LOGDEBUG("AiAlarmDataCollect handleAddAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::handleDelAlmMsg(kbd_idlfile::SIntelliAlmDel &objDelAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleDelAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //构建告警 + int nAlarmCount = objDelAlm.uuid_base64_size(); + for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) + { + QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); + CAlarmMsgManage::instance()->delAiAlarmMsg(uuid); + } +} + +void CAiAlarmDataCollect::handleBrokenAlmMsg(kbd_idlfile::SIntelliAlmBroken &objBrokenAlm) +{ + //先保证能够编译通过 + LOGINFO("========== AiAlarmDataCollect handleBrokenAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objBrokenAlm.uuid_base64_size(); + for(int nBrokenMsgIndex(0); nBrokenMsgIndex < nAlarmCount; nBrokenMsgIndex++) + { + QString uuid = QString::fromStdString(objBrokenAlm.uuid_base64(nBrokenMsgIndex)); + CAlarmMsgManage::instance()->brokenAiAlarmMsg(uuid); + } +} + +void CAiAlarmDataCollect::handleReleaseAlmMsg(kbd_idlfile::SIntelliAlmRelease &objReleaseAlm) +{ + //先保证能够编译通过 + LOGINFO("========== AiAlarmDataCollect handleReleaseAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objReleaseAlm.uuid_base64_size(); + for(int nReleaseMsgIndex(0); nReleaseMsgIndex < nAlarmCount; nReleaseMsgIndex++) + { + QString uuid = QString::fromStdString(objReleaseAlm.uuid_base64(nReleaseMsgIndex)); + CAlarmMsgManage::instance()->releaseAiAlarmMsg(uuid); + } + LOGDEBUG("AiAlarmDataCollect handleReleaseAlmMsg():count[%d]--uuid[%s]",nAlarmCount,objReleaseAlm.uuid_base64(0).c_str()); + +} + +void CAiAlarmDataCollect::destory(bool *exit) +{ + m_pAlternateTimer->blockSignals(true); + suspendThread(); + { + QMutexLocker locker(m_rtdbMutex); + if(Q_NULLPTR != m_pAlternateTimer) + { + m_pAlternateTimer->stop(); + m_pAlternateTimer->deleteLater(); + } + m_pAlternateTimer = Q_NULLPTR; + } + delete m_rtdbMutex; + delete m_rtdbPriorityOrderAccess; + m_pInstance = NULL; + delete this; + + *exit = true; +} + +void CAiAlarmDataCollect::slotTimerShot(const bool start) +{ + if(m_pAlternateTimer) + { + if(start) + { + m_pAlternateTimer->start(); + } + else + { + m_pAlternateTimer->stop(); + } + } +} + +void CAiAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) +{ + m_bFaultRecallState = bFaultRecallState; + release(); + emit sigMsgRefresh(); + CAlarmDataCollect::instance()->slotSwitchFaultRecallState(m_bFaultRecallState); + m_pInstance->reinit(m_bFaultRecallState); + + initialize(); + emit sigAlarmOperateEnable(!m_bFaultRecallState); +} + +int CAiAlarmDataCollect::queryPriorityOrder(int &id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + kbd_dbms::CVarType value = -1000; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +void CAiAlarmDataCollect::slotAiAlarmStateChanged() +{ + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->dealDelayAi(); + if(CAlarmMsgManage::instance()->needUpdateAi()) + { + CAlarmMsgManage::instance()->updateAiInfo(); + emit sigMsgRefresh(); + } + emit sigUpdateAlarmView(); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDataCollect.h b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDataCollect.h index 3594c46b..2ccd046d 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDataCollect.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDataCollect.h @@ -1,78 +1,78 @@ -#ifndef CAIALARMDATACOLLECT_H -#define CAIALARMDATACOLLECT_H - -#include -#include -#include -#include -#include -#include "IntelliAlmMsg.pb.h" -#include "CAiAlarmMsgInfo.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "dbms/rdb_api/CRdbAccess.h" - -class CAiAlarmDataCollect : public QObject, public kbd_service::CIntelliAlmApi4Clt -{ - Q_OBJECT -public: - static CAiAlarmDataCollect *instance(); - - virtual ~CAiAlarmDataCollect(); - - void initialize(); - - void release(); - - bool isFaultRecallState(); - - virtual bool requestDelAlm(kbd_idlfile::SIntelliAlmDel &objDelAlm); - - virtual bool requestSeprAlm(kbd_idlfile::SIntelliAlmSepr &objSeprAlm); - - virtual bool requestMergeAlm(kbd_idlfile::SIntelliAlmMerge &objMergeAlm); - - virtual void handleAllAlmMsg(int nDomainId,kbd_idlfile::SIntelliAlmAdd &objAllAlm); - - virtual void handleAddAlmMsg(kbd_idlfile::SIntelliAlmAdd &objAddAlm); - - virtual void handleDelAlmMsg(kbd_idlfile::SIntelliAlmDel &objDelAlm); - - virtual void handleBrokenAlmMsg(kbd_idlfile::SIntelliAlmBroken &objBrokenAlm); - - virtual void handleReleaseAlmMsg(kbd_idlfile::SIntelliAlmRelease &objReleaseAlm); -signals: - //< 启停定时器 - void sigTimerShot(const bool bStop); - - //< 定时更新,通知model刷新界面 - void sigUpdateAlarmView(); - - //< 通知所有告警插件禁用/使能告警操作 - void sigAlarmOperateEnable(const bool &bEnable); - - //< 通知model重新拉取告警消息 - void sigMsgRefresh(); - - -public slots: - void destory(bool *exit); - - void slotTimerShot(const bool start); - - void slotSwitchFaultRecallState(bool bFaultRecallState); - -private: - CAiAlarmDataCollect(); - - int queryPriorityOrder(int &id); -private slots: - void slotAiAlarmStateChanged(); -private: - bool m_bFaultRecallState; - QMutex *m_rtdbMutex; - QTimer * m_pAlternateTimer; - kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; - static CAiAlarmDataCollect * m_pInstance; -}; - -#endif // CAIALARMDATACOLLECT_H +#ifndef CAIALARMDATACOLLECT_H +#define CAIALARMDATACOLLECT_H + +#include +#include +#include +#include +#include +#include "IntelliAlmMsg.pb.h" +#include "CAiAlarmMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" + +class CAiAlarmDataCollect : public QObject, public kbd_service::CIntelliAlmApi4Clt +{ + Q_OBJECT +public: + static CAiAlarmDataCollect *instance(); + + virtual ~CAiAlarmDataCollect(); + + void initialize(); + + void release(); + + bool isFaultRecallState(); + + virtual bool requestDelAlm(kbd_idlfile::SIntelliAlmDel &objDelAlm); + + virtual bool requestSeprAlm(kbd_idlfile::SIntelliAlmSepr &objSeprAlm); + + virtual bool requestMergeAlm(kbd_idlfile::SIntelliAlmMerge &objMergeAlm); + + virtual void handleAllAlmMsg(int nDomainId,kbd_idlfile::SIntelliAlmAdd &objAllAlm); + + virtual void handleAddAlmMsg(kbd_idlfile::SIntelliAlmAdd &objAddAlm); + + virtual void handleDelAlmMsg(kbd_idlfile::SIntelliAlmDel &objDelAlm); + + virtual void handleBrokenAlmMsg(kbd_idlfile::SIntelliAlmBroken &objBrokenAlm); + + virtual void handleReleaseAlmMsg(kbd_idlfile::SIntelliAlmRelease &objReleaseAlm); +signals: + //< 启停定时器 + void sigTimerShot(const bool bStop); + + //< 定时更新,通知model刷新界面 + void sigUpdateAlarmView(); + + //< 通知所有告警插件禁用/使能告警操作 + void sigAlarmOperateEnable(const bool &bEnable); + + //< 通知model重新拉取告警消息 + void sigMsgRefresh(); + + +public slots: + void destory(bool *exit); + + void slotTimerShot(const bool start); + + void slotSwitchFaultRecallState(bool bFaultRecallState); + +private: + CAiAlarmDataCollect(); + + int queryPriorityOrder(int &id); +private slots: + void slotAiAlarmStateChanged(); +private: + bool m_bFaultRecallState; + QMutex *m_rtdbMutex; + QTimer * m_pAlternateTimer; + kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + static CAiAlarmDataCollect * m_pInstance; +}; + +#endif // CAIALARMDATACOLLECT_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDelegate.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDelegate.cpp index b4f53fe2..a9d2e7a2 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDelegate.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDelegate.cpp @@ -1,231 +1,231 @@ -#include "CAiAlarmDelegate.h" -#include -#include "pub_utility_api/FileUtil.h" -#include "pub_logger_api/logger.h" -#include -#include -#include -#include -CAiAlarmDelegate::CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent) - : QStyledItemDelegate(parent), - m_pModel(model) -{ - loadColorConfig(); -} - -void CAiAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - if(!index.isValid()) - { - return; - } - CAiAlarmTreeItem *item = m_pModel->getItem(index); - - bool select = option.state & QStyle::State_Selected; - QColor fillColor; - QColor penColor; - if(item->isAi()) - { - AiAlarmMsgPtr aiptr = NULL; - if(item->getAiPtr(aiptr) && aiptr != NULL) - { - painter->save(); - - if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aiptr->uuid_base64)) //包含的原始告警没有全部被确认 - { - if(select) - { - fillColor = m_selectBackgroundColor; - penColor = m_selectTextColor; - } - else - { - penColor = m_activeTextMap[aiptr->priorityOrder]; - fillColor = m_backgroundMap[aiptr->priorityOrder]; - } - }else //此条智能告警可以删除(置灰) - { - if(select) - { - fillColor = m_selectBackgroundColor; - } - else - { - fillColor = m_confirmMap.value(aiptr->priorityOrder, Qt::red); - } - penColor = m_confirmTextMap.value(aiptr->priorityOrder, Qt::white); - } - painter->setPen(penColor); - painter->fillRect(option.rect, fillColor); - if( VIDEO_COLUMN == index.column() && aiptr->m_needVideoAlm) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video.png").c_str()); - - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - - painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); - painter->restore(); - }else - { - return ; - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) && ptr != NULL) - { - painter->save(); - if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_RETURN - || ptr->logic_state == E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_RETURN_DEL)//未确认 - { - if(select) - { - fillColor = m_selectBackgroundColor; - penColor = m_selectTextColor; - } - else - { - penColor = m_activeTextMap[ptr->priorityOrder]; - fillColor = m_backgroundMap[ptr->priorityOrder]; - } - }else - { - if(select) - { - fillColor = m_selectBackgroundColor; - } - else - { - fillColor = m_confirmMap.value(ptr->priorityOrder, Qt::white); - } - penColor = m_confirmTextMap.value(ptr->priorityOrder, Qt::red); - } - painter->setPen(penColor); - painter->fillRect(option.rect, fillColor); - - if( VIDEO_COLUMN == index.column() && ptr->m_needVideoAlm) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video.png").c_str()); - - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); - painter->restore(); - }else - { - return ; - } - } -} - -bool CAiAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - if(!index.isValid()) - { - return false; - } - if(index.column() != VIDEO_COLUMN) - { - return false; - } - QMouseEvent *mouseEvent = static_cast(event); - CAiAlarmTreeItem *item = m_pModel->getItem(index); - if(item->isAi()) - { - return false; - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) && ptr != NULL && ptr->m_needVideoAlm) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); - QRect rect = button.rect; - QString pointTag = ptr->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - if(rect.contains(mouseEvent->pos())) - { - QString pointTag = ptr->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); - } - } - } - } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} - -void CAiAlarmDelegate::loadColorConfig() -{ - QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); - QDomDocument document; - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly)) - { - LOGERROR("loadColorConfig Failed!"); - return; - } - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - bool isFlash = false; - QDomElement element = document.documentElement(); - QDomNode node = element.firstChild(); - while(!node.isNull()) - { - QDomElement attr = node.toElement(); - if(!attr.isNull()) - { - if(QString("Flash") == attr.tagName()) - { - isFlash = (bool)attr.attribute("alternate").toInt(); - } - else if(QString("Level") == attr.tagName()) - { - int priority = attr.attribute("priority").toInt(); - m_backgroundMap[priority] = QColor(attr.attribute("background_color")); - m_alternatingMap[priority] = QColor(attr.attribute("alternating_color")); - m_confirmMap[priority] = QColor(attr.attribute("confirm_color")); - - m_activeTextMap[priority] = QColor(attr.attribute("active_text_color")); - m_confirmTextMap[priority] = QColor(attr.attribute("confirm_text_color")); - } - else if(QString("Select") == attr.tagName()) - { - m_selectBackgroundColor = QColor(attr.attribute("background_color")); - m_selectTextColor = QColor(attr.attribute("text_color")); - } - else if(QString("NoItem") == attr.tagName()) - { - m_emptyBackgroundColor = QColor(attr.attribute("background_color")); - m_emptyTipColor = QColor(attr.attribute("tips_color")); - m_emptyTip = tr("当前无告警!"); - } - } - node = node.nextSibling(); - } -} +#include "CAiAlarmDelegate.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include +CAiAlarmDelegate::CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(model) +{ + loadColorConfig(); +} + +void CAiAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + CAiAlarmTreeItem *item = m_pModel->getItem(index); + + bool select = option.state & QStyle::State_Selected; + QColor fillColor; + QColor penColor; + if(item->isAi()) + { + AiAlarmMsgPtr aiptr = NULL; + if(item->getAiPtr(aiptr) && aiptr != NULL) + { + painter->save(); + + if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aiptr->uuid_base64)) //包含的原始告警没有全部被确认 + { + if(select) + { + fillColor = m_selectBackgroundColor; + penColor = m_selectTextColor; + } + else + { + penColor = m_activeTextMap[aiptr->priorityOrder]; + fillColor = m_backgroundMap[aiptr->priorityOrder]; + } + }else //此条智能告警可以删除(置灰) + { + if(select) + { + fillColor = m_selectBackgroundColor; + } + else + { + fillColor = m_confirmMap.value(aiptr->priorityOrder, Qt::red); + } + penColor = m_confirmTextMap.value(aiptr->priorityOrder, Qt::white); + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + if( VIDEO_COLUMN == index.column() && aiptr->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video.png").c_str()); + + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + }else + { + return ; + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + painter->save(); + if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_RETURN + || ptr->logic_state == E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_RETURN_DEL)//未确认 + { + if(select) + { + fillColor = m_selectBackgroundColor; + penColor = m_selectTextColor; + } + else + { + penColor = m_activeTextMap[ptr->priorityOrder]; + fillColor = m_backgroundMap[ptr->priorityOrder]; + } + }else + { + if(select) + { + fillColor = m_selectBackgroundColor; + } + else + { + fillColor = m_confirmMap.value(ptr->priorityOrder, Qt::white); + } + penColor = m_confirmTextMap.value(ptr->priorityOrder, Qt::red); + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + + if( VIDEO_COLUMN == index.column() && ptr->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video.png").c_str()); + + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + }else + { + return ; + } + } +} + +bool CAiAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(index.column() != VIDEO_COLUMN) + { + return false; + } + QMouseEvent *mouseEvent = static_cast(event); + CAiAlarmTreeItem *item = m_pModel->getItem(index); + if(item->isAi()) + { + return false; + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL && ptr->m_needVideoAlm) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + if(rect.contains(mouseEvent->pos())) + { + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); + } + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +void CAiAlarmDelegate::loadColorConfig() +{ + QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); + QDomDocument document; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + { + LOGERROR("loadColorConfig Failed!"); + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + bool isFlash = false; + QDomElement element = document.documentElement(); + QDomNode node = element.firstChild(); + while(!node.isNull()) + { + QDomElement attr = node.toElement(); + if(!attr.isNull()) + { + if(QString("Flash") == attr.tagName()) + { + isFlash = (bool)attr.attribute("alternate").toInt(); + } + else if(QString("Level") == attr.tagName()) + { + int priority = attr.attribute("priority").toInt(); + m_backgroundMap[priority] = QColor(attr.attribute("background_color")); + m_alternatingMap[priority] = QColor(attr.attribute("alternating_color")); + m_confirmMap[priority] = QColor(attr.attribute("confirm_color")); + + m_activeTextMap[priority] = QColor(attr.attribute("active_text_color")); + m_confirmTextMap[priority] = QColor(attr.attribute("confirm_text_color")); + } + else if(QString("Select") == attr.tagName()) + { + m_selectBackgroundColor = QColor(attr.attribute("background_color")); + m_selectTextColor = QColor(attr.attribute("text_color")); + } + else if(QString("NoItem") == attr.tagName()) + { + m_emptyBackgroundColor = QColor(attr.attribute("background_color")); + m_emptyTipColor = QColor(attr.attribute("tips_color")); + m_emptyTip = tr("当前无告警!"); + } + } + node = node.nextSibling(); + } +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDelegate.h b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDelegate.h index 8f48f875..95a15eed 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDelegate.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmDelegate.h @@ -1,40 +1,40 @@ -#ifndef CAIALARMDELEGATE_H -#define CAIALARMDELEGATE_H - -#include -#include -#include "CAiAlarmTreeModel.h" -class CAiAlarmDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent = 0); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); -signals: - void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); -private: - void loadColorConfig(); -private: - CAiAlarmTreeModel *m_pModel; - //< background color - QMap m_backgroundMap; - QMap m_alternatingMap; - QMap m_confirmMap; - - //< text color - QMap m_activeTextMap; - QMap m_confirmTextMap; - - //< select color - QColor m_selectBackgroundColor; - QColor m_selectTextColor; - - //< no item - QColor m_emptyBackgroundColor; - QColor m_emptyTipColor; - QString m_emptyTip; -}; - -#endif // CAIALARMDELEGATE_H +#ifndef CAIALARMDELEGATE_H +#define CAIALARMDELEGATE_H + +#include +#include +#include "CAiAlarmTreeModel.h" +class CAiAlarmDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent = 0); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); +signals: + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); +private: + void loadColorConfig(); +private: + CAiAlarmTreeModel *m_pModel; + //< background color + QMap m_backgroundMap; + QMap m_alternatingMap; + QMap m_confirmMap; + + //< text color + QMap m_activeTextMap; + QMap m_confirmTextMap; + + //< select color + QColor m_selectBackgroundColor; + QColor m_selectTextColor; + + //< no item + QColor m_emptyBackgroundColor; + QColor m_emptyTipColor; + QString m_emptyTip; +}; + +#endif // CAIALARMDELEGATE_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmMsgInfo.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmMsgInfo.cpp index 21731feb..1b6f4b16 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmMsgInfo.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmMsgInfo.cpp @@ -1,439 +1,439 @@ -#include "CAiAlarmMsgInfo.h" -#include -#include "CAlarmDataCollect.h" -#include - -CAiAlarmMsgInfo::CAiAlarmMsgInfo() -{ - logic_state = E_AiALM_IALS_NORMAL; - domain_id = -1; - priority = -1; - time_stamp = 1000; - - uuid_base64 = QString(); - content = QString(); - disposal_plan = QString(); - raw_alm_uuid.clear(); - - priorityOrder = -1; - deleteFlag = false; - brokenFlag = false; - releaseFlag = false; - m_needVideoAlm =false; -} - -CAiAlarmMsgInfo::CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other) -{ - logic_state = other.logic_state; - domain_id = other.domain_id; - time_stamp = other.time_stamp; - - uuid_base64 = other.uuid_base64; - content = other.content; - disposal_plan = other.disposal_plan; - raw_alm_uuid = other.raw_alm_uuid; - - priorityOrder = other.priorityOrder; - deleteFlag = other.deleteFlag; - brokenFlag = other.brokenFlag; - releaseFlag = other.releaseFlag; - m_needVideoAlm = other.m_needVideoAlm; -} - -void CAiAlarmMsgInfo::initialize(const kbd_idlfile::SIntelliAlmInfo &alarmInfo) -{ - - logic_state = (E_AiALARM_LOGICSTATE)alarmInfo.logic_state(); - domain_id = alarmInfo.domain_id(); - priority = alarmInfo.priority(); - time_stamp = alarmInfo.time_stamp(); - - uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); - content = QString::fromStdString(alarmInfo.content()); - disposal_plan = QString::fromStdString(alarmInfo.disposal_plan()); - raw_alm_uuid.clear(); //< 关联的原始告警uuid - for(int x(0); x < alarmInfo.raw_alm_uuid_size(); x++) - { - raw_alm_uuid.append(QString::fromStdString(alarmInfo.raw_alm_uuid(x))); - } - - priorityOrder = -1; - if(logic_state == E_AIALM_IALS_DELETED) - { - deleteFlag = true; - }else - { - deleteFlag = false; - } - if(logic_state == E_AIALM_IALS_BROKEN) - { - brokenFlag = true; - }else - { - brokenFlag = false; - } - releaseFlag = false; - m_needVideoAlm =false; -} - -bool CAiAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priority > info->priority) - { - return true; - }else if(priority < info->priority) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp < info->time_stamp) - { - return true; - }else if(time_stamp > info->time_stamp) - { - return false; - }else - { - if(priority > info->priority) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return false; - break; - case E_SORT_REGION: - return false; - break; - case E_SORT_TYPE: - return false; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return false; - case E_SORT_ALM_STATE: - return false; - break; - default: - break; - } - return false; -} - -bool CAiAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priority < info->priority) - { - return true; - }else if(priority > info->priority) - { - return false; - }else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp > info->time_stamp) - { - return true; - }else if(time_stamp < info->time_stamp) - { - return false; - }else - { - if(priority < info->priority) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return true; - break; - case E_SORT_REGION: - return true; - break; - case E_SORT_TYPE: - return true; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content < info->content) - { - return false; - } - else if(content > info->content) - { - return true; - } - else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return true; - break; - case E_SORT_ALM_STATE: - return true; - break; - default: - break; - } - return false; -} -//< 智能告警-前者小[不包含的字段进行比较排序] -bool CAiAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priority > info->priority) - { - return true; - }else if(priority < info->priority) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp < info->time_stamp) - { - return true; - }else if(time_stamp > info->time_stamp) - { - return false; - }else - { - if(priority > info->priority) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return true; - break; - case E_SORT_REGION: - return true; - break; - case E_SORT_TYPE: - return true; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return true; - case E_SORT_ALM_STATE: - return true; - break; - default: - break; - } - return false; -} - -bool CAiAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priority < info->priority) - { - return true; - }else if(priority > info->priority) - { - return false; - }else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp > info->time_stamp) - { - return true; - }else if(time_stamp < info->time_stamp) - { - return false; - }else - { - if(priority < info->priority) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return false; - break; - case E_SORT_REGION: - return false; - break; - case E_SORT_TYPE: - return false; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content < info->content) - { - return false; - } - else if(content > info->content) - { - return true; - } - else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return false; - break; - case E_SORT_ALM_STATE: - return false; - break; - default: - break; - } - return false; -} - -bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target) -{ - if(source.uuid_base64 == target.uuid_base64) - { - return true; - } - return false; -// //替换式告警且车站、测点ID相同 -// if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) -// { -// return true; -// } -// //流水账告警且时标、告警内容相同 -// else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) -// { -// return true; -// } -// return false; -} +#include "CAiAlarmMsgInfo.h" +#include +#include "CAlarmDataCollect.h" +#include + +CAiAlarmMsgInfo::CAiAlarmMsgInfo() +{ + logic_state = E_AiALM_IALS_NORMAL; + domain_id = -1; + priority = -1; + time_stamp = 1000; + + uuid_base64 = QString(); + content = QString(); + disposal_plan = QString(); + raw_alm_uuid.clear(); + + priorityOrder = -1; + deleteFlag = false; + brokenFlag = false; + releaseFlag = false; + m_needVideoAlm =false; +} + +CAiAlarmMsgInfo::CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other) +{ + logic_state = other.logic_state; + domain_id = other.domain_id; + time_stamp = other.time_stamp; + + uuid_base64 = other.uuid_base64; + content = other.content; + disposal_plan = other.disposal_plan; + raw_alm_uuid = other.raw_alm_uuid; + + priorityOrder = other.priorityOrder; + deleteFlag = other.deleteFlag; + brokenFlag = other.brokenFlag; + releaseFlag = other.releaseFlag; + m_needVideoAlm = other.m_needVideoAlm; +} + +void CAiAlarmMsgInfo::initialize(const kbd_idlfile::SIntelliAlmInfo &alarmInfo) +{ + + logic_state = (E_AiALARM_LOGICSTATE)alarmInfo.logic_state(); + domain_id = alarmInfo.domain_id(); + priority = alarmInfo.priority(); + time_stamp = alarmInfo.time_stamp(); + + uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); + content = QString::fromStdString(alarmInfo.content()); + disposal_plan = QString::fromStdString(alarmInfo.disposal_plan()); + raw_alm_uuid.clear(); //< 关联的原始告警uuid + for(int x(0); x < alarmInfo.raw_alm_uuid_size(); x++) + { + raw_alm_uuid.append(QString::fromStdString(alarmInfo.raw_alm_uuid(x))); + } + + priorityOrder = -1; + if(logic_state == E_AIALM_IALS_DELETED) + { + deleteFlag = true; + }else + { + deleteFlag = false; + } + if(logic_state == E_AIALM_IALS_BROKEN) + { + brokenFlag = true; + }else + { + brokenFlag = false; + } + releaseFlag = false; + m_needVideoAlm =false; +} + +bool CAiAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priority > info->priority) + { + return true; + }else if(priority < info->priority) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priority > info->priority) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return false; + case E_SORT_ALM_STATE: + return false; + break; + default: + break; + } + return false; +} + +bool CAiAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priority < info->priority) + { + return true; + }else if(priority > info->priority) + { + return false; + }else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priority < info->priority) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content > info->content) + { + return true; + } + else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return true; + break; + case E_SORT_ALM_STATE: + return true; + break; + default: + break; + } + return false; +} +//< 智能告警-前者小[不包含的字段进行比较排序] +bool CAiAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priority > info->priority) + { + return true; + }else if(priority < info->priority) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priority > info->priority) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return true; + case E_SORT_ALM_STATE: + return true; + break; + default: + break; + } + return false; +} + +bool CAiAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priority < info->priority) + { + return true; + }else if(priority > info->priority) + { + return false; + }else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priority < info->priority) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content > info->content) + { + return true; + } + else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return false; + break; + case E_SORT_ALM_STATE: + return false; + break; + default: + break; + } + return false; +} + +bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target) +{ + if(source.uuid_base64 == target.uuid_base64) + { + return true; + } + return false; +// //替换式告警且车站、测点ID相同 +// if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) +// { +// return true; +// } +// //流水账告警且时标、告警内容相同 +// else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) +// { +// return true; +// } +// return false; +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmMsgInfo.h b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmMsgInfo.h index fa4de22d..ac504bae 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmMsgInfo.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmMsgInfo.h @@ -1,54 +1,54 @@ -#ifndef CAIALARMMSGINFO_H -#define CAIALARMMSGINFO_H - - -#include -#include -#include -#include "intelli_alm_api/CIntelliAlmApi4Clt.h" -#include -#include -#include - -enum E_AiALARM_LOGICSTATE -{ - E_AiALM_IALS_NORMAL = 1, //正常 - E_AIALM_IALS_DELETED = 2, //已删除 - E_AIALM_IALS_BROKEN = 3, //不完整的 -}; -class CAiAlarmMsgInfo -{ -public: - CAiAlarmMsgInfo(); - CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other); - void initialize(const kbd_idlfile::SIntelliAlmInfo &alarmInfo); - - //< [优先级越小表示越大]-智能告警窗调用 - bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - E_AiALARM_LOGICSTATE logic_state; //< 状态 - qint32 domain_id; //< 域ID - qint32 priority; //< 告警优先级id - quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) - QString uuid_base64; //< uuid 主键 - QString content; //< 告警内容 - QString disposal_plan; //< 处置预案 - QVector raw_alm_uuid; //< 关联的原始告警uuid - //< Extend - qint32 priorityOrder; //< 优先级 - bool deleteFlag; //< 是否被删除 - bool brokenFlag; //< 是否不完整 - bool releaseFlag; //< 是否被释放 - bool m_needVideoAlm; -}; - -bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target); - -Q_DECLARE_METATYPE(CAiAlarmMsgInfo) -Q_DECLARE_METATYPE(AiAlarmMsgPtr) - -#endif // CAIALARMMSGINFO_H +#ifndef CAIALARMMSGINFO_H +#define CAIALARMMSGINFO_H + + +#include +#include +#include +#include "intelli_alm_api/CIntelliAlmApi4Clt.h" +#include +#include +#include + +enum E_AiALARM_LOGICSTATE +{ + E_AiALM_IALS_NORMAL = 1, //正常 + E_AIALM_IALS_DELETED = 2, //已删除 + E_AIALM_IALS_BROKEN = 3, //不完整的 +}; +class CAiAlarmMsgInfo +{ +public: + CAiAlarmMsgInfo(); + CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other); + void initialize(const kbd_idlfile::SIntelliAlmInfo &alarmInfo); + + //< [优先级越小表示越大]-智能告警窗调用 + bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + E_AiALARM_LOGICSTATE logic_state; //< 状态 + qint32 domain_id; //< 域ID + qint32 priority; //< 告警优先级id + quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) + QString uuid_base64; //< uuid 主键 + QString content; //< 告警内容 + QString disposal_plan; //< 处置预案 + QVector raw_alm_uuid; //< 关联的原始告警uuid + //< Extend + qint32 priorityOrder; //< 优先级 + bool deleteFlag; //< 是否被删除 + bool brokenFlag; //< 是否不完整 + bool releaseFlag; //< 是否被释放 + bool m_needVideoAlm; +}; + +bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target); + +Q_DECLARE_METATYPE(CAiAlarmMsgInfo) +Q_DECLARE_METATYPE(AiAlarmMsgPtr) + +#endif // CAIALARMMSGINFO_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeItem.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeItem.cpp index e9fd0392..c6787dc8 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeItem.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeItem.cpp @@ -1,396 +1,396 @@ -#include "CAiAlarmTreeItem.h" -#include "CAiAlarmMsgInfo.h" -#include "CAlarmMsgInfo.h" -#include "CAlarmCommon.h" -#include "pub_logger_api/logger.h" - -CAiAlarmTreeItem::CAiAlarmTreeItem(const QVector &data, CAiAlarmTreeItem *parent) - : m_parent(parent), - m_aialarmPtr(NULL), - m_alarmPtr(NULL), - m_data(data), - m_bIsAi(false), - m_uuid(QString()) - // m_checkState(Qt::Unchecked) -{ - -} - -CAiAlarmTreeItem::~CAiAlarmTreeItem() -{ - qDeleteAll(m_child); - m_child.clear(); -} - -CAiAlarmTreeItem *CAiAlarmTreeItem::child(int row) -{ - return m_child.at(row); -} - -CAiAlarmTreeItem *CAiAlarmTreeItem::parent() -{ - return m_parent; -} - -int CAiAlarmTreeItem::childCount() const -{ - return m_child.count(); -} - -int CAiAlarmTreeItem::columnCount() const -{ - return m_data.count(); -} - -int CAiAlarmTreeItem::childNumber() const -{ - if(m_parent) - { - return m_parent->m_child.indexOf(const_cast(this)); - } - return 0; -} - -QVariant CAiAlarmTreeItem::data(int column, int role) -{ - if(E_DisplayRole == role) - { - if(m_bIsAi == true) - { - return aigetDataByColumn(column); - }else - { - return getDataByColumn(column); - } - } - else - { - return QVariant(); - } -} - -bool CAiAlarmTreeItem::setData(int column, const QVariant &value, int role) -{ - Q_UNUSED(role) - Q_UNUSED(value) - if (column < 0 || column >= m_data.size()) - return false; -// if(E_IfAiFlag == role) -// { -// m_bIsAi = value.toBool(); -// return true; -// } -// else if(E_UserRole == role) -// { -// m_uuid = value.toString(); -// return true; -// } -// else if(E_DisplayRole == role) -// { -// m_data[column] = value; -// return true; -// } - return true; -} - -bool CAiAlarmTreeItem::setPtr(AlarmMsgPtr ptr) -{ - m_alarmPtr = ptr; - m_bIsAi = false; - m_uuid = ptr->uuid_base64; - return true; -} - -bool CAiAlarmTreeItem::setAiPtr(AiAlarmMsgPtr aiPtr) -{ - m_aialarmPtr = aiPtr; - m_bIsAi = true; - m_uuid = aiPtr->uuid_base64; - return true; -} - -bool CAiAlarmTreeItem::insertChildren(int position, int count, int columns) -{ - if (position < 0 || position > m_child.size()) - return false; - - for (int row = 0; row < count; ++row) { - QVector data(columns); - CAiAlarmTreeItem *item = new CAiAlarmTreeItem(data, this); - m_child.insert(position, item); - } - - return true; -} - -bool CAiAlarmTreeItem::removeChildren(int position, int count, int columns) -{ - Q_UNUSED(columns) - if (position < 0 || position + count > m_child.size()) - return false; - - for (int row = 0; row < count; ++row) - delete m_child.takeAt(position); - - return true; -} - -bool CAiAlarmTreeItem::isAi() -{ - return m_bIsAi; -} - -AlarmMsgPtr CAiAlarmTreeItem::ptr() -{ - if(m_alarmPtr == NULL) - return NULL; - else - return m_alarmPtr; -} - -bool CAiAlarmTreeItem::getPtr(AlarmMsgPtr &ptr) -{ - if(!m_bIsAi &&m_alarmPtr != NULL) - { - ptr = m_alarmPtr; - return true; - } - else - { - ptr = NULL; - return false; - } -} - -bool CAiAlarmTreeItem::getAiPtr(AiAlarmMsgPtr &aiPtr) -{ - if(m_bIsAi &&m_aialarmPtr != NULL) - { - aiPtr = m_aialarmPtr; - return true; - } - else - { - aiPtr = NULL; - return false; - } -} - -QList CAiAlarmTreeItem::getChildAlarmPtr() -{ - QList ptrList; - foreach (CAiAlarmTreeItem* item, m_child) { - if(item->ptr() != NULL) - { - ptrList.append(item->ptr()); - } - } - return ptrList; -} - -int CAiAlarmTreeItem::index(const QString uuid) -{ - for(int index(0);indexm_uuid == uuid) - { - return index; - } - } - return -1; -} - -bool CAiAlarmTreeItem::lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) -{ - AiAlarmMsgPtr aiptr = NULL; - AlarmMsgPtr ptr= NULL; - if(m_bIsAi) - { - if(info->isAi()) - { - if(info->getAiPtr(aiptr) && aiptr != NULL) - return m_aialarmPtr->ailessThan(aiptr,sortkey); - }else - { - if(info->getPtr(ptr) && ptr != NULL) - return m_aialarmPtr->ailessThan(ptr,sortkey); - } - - }else - { - if(info->isAi()) - { - if(info->getAiPtr(aiptr) && aiptr != NULL) - return m_alarmPtr->ailessThan(aiptr,sortkey); - }else - { - if(info->getPtr(ptr) && ptr != NULL) - return m_alarmPtr->ailessThan(ptr,sortkey); - } - } - LOGERROR("lessThan():比较大小出错!"); - return false; -} - -bool CAiAlarmTreeItem::moreThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) -{ - AiAlarmMsgPtr aiptr = NULL; - AlarmMsgPtr ptr= NULL; - if(m_bIsAi) - { - if(info->isAi()) - { - if(info->getAiPtr(aiptr) && aiptr != NULL) - return m_aialarmPtr->aimoreThan(aiptr,sortkey); - }else - { - if(info->getPtr(ptr) && ptr != NULL) - return m_aialarmPtr->aimoreThan(ptr,sortkey); - } - }else - { - if(info->isAi()) - { - if(info->getAiPtr(aiptr) && aiptr != NULL) - return m_alarmPtr->aimoreThan(aiptr,sortkey); - }else - { - if(info->getPtr(ptr) && ptr != NULL) - return m_alarmPtr->aimoreThan(ptr,sortkey); - } - } - LOGERROR("moreThan():比较大小出错!"); - return false; -} - -QList CAiAlarmTreeItem::getChild() -{ - return m_child; -} - -void CAiAlarmTreeItem::setChild(QList itemList) -{ - m_child.clear(); - m_child = itemList; -} - -QList CAiAlarmTreeItem::getChildItemList() -{ - return m_child; -} - -QVector CAiAlarmTreeItem::getContent() -{ - QVector vec; - if(m_bIsAi) - { - for(int index(0);indextime_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); - vec.append(CAlarmMsgManage::instance()->queryPriorityDesc(m_alarmPtr->priority)); - vec.append(CAlarmMsgManage::instance()->queryLocationDesc(m_alarmPtr->location_id)); - vec.append(CAlarmMsgManage::instance()->queryRegionDesc(m_alarmPtr->region_id)); - vec.append(CAlarmMsgManage::instance()->queryAlarmTypeDesc(m_alarmPtr->alm_type)); - vec.append(CAlarmMsgManage::instance()->queryAlarmStatusDesc(m_alarmPtr->alm_status)); - if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_RETURN == m_alarmPtr->logic_state - || E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_DEL == m_alarmPtr->logic_state) //< 未确认 - { - vec.append(QObject::tr("未确认")); - } - else - { - vec.append(QObject::tr("已确认")); - } - vec.append(""); - vec.append(m_alarmPtr->content); - } - return vec; -} - -QVariant CAiAlarmTreeItem::aigetDataByColumn(int column) -{ - if(m_aialarmPtr != NULL) - { - switch (column) { - case TIME: - m_data[0] = QDateTime::fromMSecsSinceEpoch(m_aialarmPtr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); - return m_data[0]; - case PRIORITY: - m_data[1] = CAlarmMsgManage::instance()->queryPriorityDesc(m_aialarmPtr->priority); - return m_data[1]; - case LOCATION: - m_data[2] = CAlarmMsgManage::instance()->queryLocationDesc(m_aialarmPtr->uuid_base64); - return m_data[2]; - case REGION: - m_data[3] ="-"; - return m_data[3]; - case TYPE: - m_data[4] ="-"; - return "-"; - case STATUS: - m_data[5] ="-"; - return "-"; - case CONFIRM: - m_data[6] =CAlarmMsgManage::instance()->queryConfirm(m_aialarmPtr->uuid_base64); - return m_data[6]; - - case CONTENT: - m_data[7] = m_aialarmPtr->content; - return m_data[7]; - default: - break; - } - } - return QVariant(); -} - -QVariant CAiAlarmTreeItem::getDataByColumn(int column) -{ - if(m_alarmPtr != NULL) - { - switch (column) { - case TIME: - m_data[0] = QDateTime::fromMSecsSinceEpoch(m_alarmPtr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); - return m_data[0]; - case PRIORITY: - m_data[1] = CAlarmMsgManage::instance()->queryPriorityDesc(m_alarmPtr->priority); - return m_data[1]; - case LOCATION: - m_data[2] = CAlarmMsgManage::instance()->queryLocationDesc(m_alarmPtr->location_id); - return m_data[2]; - case REGION: - m_data[3] = CAlarmMsgManage::instance()->queryRegionDesc(m_alarmPtr->region_id); - return m_data[3]; - case TYPE: - m_data[4] = CAlarmMsgManage::instance()->queryAlarmTypeDesc(m_alarmPtr->alm_type); - return m_data[4]; - case STATUS: - m_data[5] = CAlarmMsgManage::instance()->queryAlarmStatusDesc(m_alarmPtr->alm_status); - return m_data[5]; - case CONFIRM: - if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_RETURN == m_alarmPtr->logic_state - || E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_DEL == m_alarmPtr->logic_state) //< 未确认 - { - m_data[6] = QObject::tr("未确认"); - return m_data[6]; - } - else - { - m_data[6] = QObject::tr("已确认"); - return m_data[6]; - } - case CONTENT: - m_data[7] = m_alarmPtr->content; - return m_data[7]; - default: - break; - } - } - return QVariant(); -} +#include "CAiAlarmTreeItem.h" +#include "CAiAlarmMsgInfo.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmCommon.h" +#include "pub_logger_api/logger.h" + +CAiAlarmTreeItem::CAiAlarmTreeItem(const QVector &data, CAiAlarmTreeItem *parent) + : m_parent(parent), + m_aialarmPtr(NULL), + m_alarmPtr(NULL), + m_data(data), + m_bIsAi(false), + m_uuid(QString()) + // m_checkState(Qt::Unchecked) +{ + +} + +CAiAlarmTreeItem::~CAiAlarmTreeItem() +{ + qDeleteAll(m_child); + m_child.clear(); +} + +CAiAlarmTreeItem *CAiAlarmTreeItem::child(int row) +{ + return m_child.at(row); +} + +CAiAlarmTreeItem *CAiAlarmTreeItem::parent() +{ + return m_parent; +} + +int CAiAlarmTreeItem::childCount() const +{ + return m_child.count(); +} + +int CAiAlarmTreeItem::columnCount() const +{ + return m_data.count(); +} + +int CAiAlarmTreeItem::childNumber() const +{ + if(m_parent) + { + return m_parent->m_child.indexOf(const_cast(this)); + } + return 0; +} + +QVariant CAiAlarmTreeItem::data(int column, int role) +{ + if(E_DisplayRole == role) + { + if(m_bIsAi == true) + { + return aigetDataByColumn(column); + }else + { + return getDataByColumn(column); + } + } + else + { + return QVariant(); + } +} + +bool CAiAlarmTreeItem::setData(int column, const QVariant &value, int role) +{ + Q_UNUSED(role) + Q_UNUSED(value) + if (column < 0 || column >= m_data.size()) + return false; +// if(E_IfAiFlag == role) +// { +// m_bIsAi = value.toBool(); +// return true; +// } +// else if(E_UserRole == role) +// { +// m_uuid = value.toString(); +// return true; +// } +// else if(E_DisplayRole == role) +// { +// m_data[column] = value; +// return true; +// } + return true; +} + +bool CAiAlarmTreeItem::setPtr(AlarmMsgPtr ptr) +{ + m_alarmPtr = ptr; + m_bIsAi = false; + m_uuid = ptr->uuid_base64; + return true; +} + +bool CAiAlarmTreeItem::setAiPtr(AiAlarmMsgPtr aiPtr) +{ + m_aialarmPtr = aiPtr; + m_bIsAi = true; + m_uuid = aiPtr->uuid_base64; + return true; +} + +bool CAiAlarmTreeItem::insertChildren(int position, int count, int columns) +{ + if (position < 0 || position > m_child.size()) + return false; + + for (int row = 0; row < count; ++row) { + QVector data(columns); + CAiAlarmTreeItem *item = new CAiAlarmTreeItem(data, this); + m_child.insert(position, item); + } + + return true; +} + +bool CAiAlarmTreeItem::removeChildren(int position, int count, int columns) +{ + Q_UNUSED(columns) + if (position < 0 || position + count > m_child.size()) + return false; + + for (int row = 0; row < count; ++row) + delete m_child.takeAt(position); + + return true; +} + +bool CAiAlarmTreeItem::isAi() +{ + return m_bIsAi; +} + +AlarmMsgPtr CAiAlarmTreeItem::ptr() +{ + if(m_alarmPtr == NULL) + return NULL; + else + return m_alarmPtr; +} + +bool CAiAlarmTreeItem::getPtr(AlarmMsgPtr &ptr) +{ + if(!m_bIsAi &&m_alarmPtr != NULL) + { + ptr = m_alarmPtr; + return true; + } + else + { + ptr = NULL; + return false; + } +} + +bool CAiAlarmTreeItem::getAiPtr(AiAlarmMsgPtr &aiPtr) +{ + if(m_bIsAi &&m_aialarmPtr != NULL) + { + aiPtr = m_aialarmPtr; + return true; + } + else + { + aiPtr = NULL; + return false; + } +} + +QList CAiAlarmTreeItem::getChildAlarmPtr() +{ + QList ptrList; + foreach (CAiAlarmTreeItem* item, m_child) { + if(item->ptr() != NULL) + { + ptrList.append(item->ptr()); + } + } + return ptrList; +} + +int CAiAlarmTreeItem::index(const QString uuid) +{ + for(int index(0);indexm_uuid == uuid) + { + return index; + } + } + return -1; +} + +bool CAiAlarmTreeItem::lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) +{ + AiAlarmMsgPtr aiptr = NULL; + AlarmMsgPtr ptr= NULL; + if(m_bIsAi) + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_aialarmPtr->ailessThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_aialarmPtr->ailessThan(ptr,sortkey); + } + + }else + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_alarmPtr->ailessThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_alarmPtr->ailessThan(ptr,sortkey); + } + } + LOGERROR("lessThan():比较大小出错!"); + return false; +} + +bool CAiAlarmTreeItem::moreThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) +{ + AiAlarmMsgPtr aiptr = NULL; + AlarmMsgPtr ptr= NULL; + if(m_bIsAi) + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_aialarmPtr->aimoreThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_aialarmPtr->aimoreThan(ptr,sortkey); + } + }else + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_alarmPtr->aimoreThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_alarmPtr->aimoreThan(ptr,sortkey); + } + } + LOGERROR("moreThan():比较大小出错!"); + return false; +} + +QList CAiAlarmTreeItem::getChild() +{ + return m_child; +} + +void CAiAlarmTreeItem::setChild(QList itemList) +{ + m_child.clear(); + m_child = itemList; +} + +QList CAiAlarmTreeItem::getChildItemList() +{ + return m_child; +} + +QVector CAiAlarmTreeItem::getContent() +{ + QVector vec; + if(m_bIsAi) + { + for(int index(0);indextime_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); + vec.append(CAlarmMsgManage::instance()->queryPriorityDesc(m_alarmPtr->priority)); + vec.append(CAlarmMsgManage::instance()->queryLocationDesc(m_alarmPtr->location_id)); + vec.append(CAlarmMsgManage::instance()->queryRegionDesc(m_alarmPtr->region_id)); + vec.append(CAlarmMsgManage::instance()->queryAlarmTypeDesc(m_alarmPtr->alm_type)); + vec.append(CAlarmMsgManage::instance()->queryAlarmStatusDesc(m_alarmPtr->alm_status)); + if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_RETURN == m_alarmPtr->logic_state + || E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_DEL == m_alarmPtr->logic_state) //< 未确认 + { + vec.append(QObject::tr("未确认")); + } + else + { + vec.append(QObject::tr("已确认")); + } + vec.append(""); + vec.append(m_alarmPtr->content); + } + return vec; +} + +QVariant CAiAlarmTreeItem::aigetDataByColumn(int column) +{ + if(m_aialarmPtr != NULL) + { + switch (column) { + case TIME: + m_data[0] = QDateTime::fromMSecsSinceEpoch(m_aialarmPtr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + return m_data[0]; + case PRIORITY: + m_data[1] = CAlarmMsgManage::instance()->queryPriorityDesc(m_aialarmPtr->priority); + return m_data[1]; + case LOCATION: + m_data[2] = CAlarmMsgManage::instance()->queryLocationDesc(m_aialarmPtr->uuid_base64); + return m_data[2]; + case REGION: + m_data[3] ="-"; + return m_data[3]; + case TYPE: + m_data[4] ="-"; + return "-"; + case STATUS: + m_data[5] ="-"; + return "-"; + case CONFIRM: + m_data[6] =CAlarmMsgManage::instance()->queryConfirm(m_aialarmPtr->uuid_base64); + return m_data[6]; + + case CONTENT: + m_data[7] = m_aialarmPtr->content; + return m_data[7]; + default: + break; + } + } + return QVariant(); +} + +QVariant CAiAlarmTreeItem::getDataByColumn(int column) +{ + if(m_alarmPtr != NULL) + { + switch (column) { + case TIME: + m_data[0] = QDateTime::fromMSecsSinceEpoch(m_alarmPtr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + return m_data[0]; + case PRIORITY: + m_data[1] = CAlarmMsgManage::instance()->queryPriorityDesc(m_alarmPtr->priority); + return m_data[1]; + case LOCATION: + m_data[2] = CAlarmMsgManage::instance()->queryLocationDesc(m_alarmPtr->location_id); + return m_data[2]; + case REGION: + m_data[3] = CAlarmMsgManage::instance()->queryRegionDesc(m_alarmPtr->region_id); + return m_data[3]; + case TYPE: + m_data[4] = CAlarmMsgManage::instance()->queryAlarmTypeDesc(m_alarmPtr->alm_type); + return m_data[4]; + case STATUS: + m_data[5] = CAlarmMsgManage::instance()->queryAlarmStatusDesc(m_alarmPtr->alm_status); + return m_data[5]; + case CONFIRM: + if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_RETURN == m_alarmPtr->logic_state + || E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_DEL == m_alarmPtr->logic_state) //< 未确认 + { + m_data[6] = QObject::tr("未确认"); + return m_data[6]; + } + else + { + m_data[6] = QObject::tr("已确认"); + return m_data[6]; + } + case CONTENT: + m_data[7] = m_alarmPtr->content; + return m_data[7]; + default: + break; + } + } + return QVariant(); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeItem.h b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeItem.h index 7cc18879..ae826783 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeItem.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeItem.h @@ -1,79 +1,79 @@ -#ifndef CAIALARMTREEITEM_H -#define CAIALARMTREEITEM_H - -#include -#include -#include "CAlarmMsgManage.h" -enum E_ItemDataRole -{ - E_IfAiFlag =0x0101, //< 是否智能告警 - E_DisplayRole =0x0102, - E_UserRole = 0x0103, //< uuid - E_CheckStateRole = 0x0104 -}; -enum ColumnField -{ - TIME = 0, - PRIORITY, - LOCATION, - REGION, - TYPE, - STATUS, - CONFIRM, - CONTENT -}; -class CAiAlarmTreeItem -{ -public: - explicit CAiAlarmTreeItem(const QVector &data,CAiAlarmTreeItem *parent = Q_NULLPTR); - ~CAiAlarmTreeItem(); - - CAiAlarmTreeItem *child(int row); - CAiAlarmTreeItem *parent(); - - int childCount() const; - int columnCount() const; - //返回行数 - int childNumber() const; - QVariant data(int column,int role = E_DisplayRole); - bool setData(int column,const QVariant &value,int role); - bool setPtr(AlarmMsgPtr ptr); - bool setAiPtr(AiAlarmMsgPtr aiPtr); - bool insertChildren(int position, int count, int columns); - bool removeChildren(int position, int count, int columns); - bool isAi(); - - //若确定是原始告警可以直接使用 - AlarmMsgPtr ptr(); - bool getPtr(AlarmMsgPtr &ptr); - bool getAiPtr(AiAlarmMsgPtr &aiPtr); - QList getChildAlarmPtr(); - - int index(const QString uuid); - - bool lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool moreThan(CAiAlarmTreeItem* info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - QList getChild(); - void setChild(QList itemList); - - QList getChildItemList(); - - QVector getContent(); -private: - QVariant aigetDataByColumn(int column); - QVariant getDataByColumn(int column); -private: - QString m_uuid; - bool m_bIsAi; - QList m_child; - CAiAlarmTreeItem *m_parent; - - QVector m_data; - AlarmMsgPtr m_alarmPtr; - AiAlarmMsgPtr m_aialarmPtr; - - //Qt::CheckState m_checkState; -}; - -#endif // CAIALARMTREEITEM_H +#ifndef CAIALARMTREEITEM_H +#define CAIALARMTREEITEM_H + +#include +#include +#include "CAlarmMsgManage.h" +enum E_ItemDataRole +{ + E_IfAiFlag =0x0101, //< 是否智能告警 + E_DisplayRole =0x0102, + E_UserRole = 0x0103, //< uuid + E_CheckStateRole = 0x0104 +}; +enum ColumnField +{ + TIME = 0, + PRIORITY, + LOCATION, + REGION, + TYPE, + STATUS, + CONFIRM, + CONTENT +}; +class CAiAlarmTreeItem +{ +public: + explicit CAiAlarmTreeItem(const QVector &data,CAiAlarmTreeItem *parent = Q_NULLPTR); + ~CAiAlarmTreeItem(); + + CAiAlarmTreeItem *child(int row); + CAiAlarmTreeItem *parent(); + + int childCount() const; + int columnCount() const; + //返回行数 + int childNumber() const; + QVariant data(int column,int role = E_DisplayRole); + bool setData(int column,const QVariant &value,int role); + bool setPtr(AlarmMsgPtr ptr); + bool setAiPtr(AiAlarmMsgPtr aiPtr); + bool insertChildren(int position, int count, int columns); + bool removeChildren(int position, int count, int columns); + bool isAi(); + + //若确定是原始告警可以直接使用 + AlarmMsgPtr ptr(); + bool getPtr(AlarmMsgPtr &ptr); + bool getAiPtr(AiAlarmMsgPtr &aiPtr); + QList getChildAlarmPtr(); + + int index(const QString uuid); + + bool lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(CAiAlarmTreeItem* info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + QList getChild(); + void setChild(QList itemList); + + QList getChildItemList(); + + QVector getContent(); +private: + QVariant aigetDataByColumn(int column); + QVariant getDataByColumn(int column); +private: + QString m_uuid; + bool m_bIsAi; + QList m_child; + CAiAlarmTreeItem *m_parent; + + QVector m_data; + AlarmMsgPtr m_alarmPtr; + AiAlarmMsgPtr m_aialarmPtr; + + //Qt::CheckState m_checkState; +}; + +#endif // CAIALARMTREEITEM_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeModel.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeModel.cpp index 9b5f880a..979633aa 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeModel.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeModel.cpp @@ -1,959 +1,959 @@ -#include "CAiAlarmTreeModel.h" -#include "CAlarmMsgManage.h" -#include "CAiAlarmDataCollect.h" -#include "CAlarmDataCollect.h" -#include "pub_logger_api/logger.h" -CAiAlarmTreeModel::CAiAlarmTreeModel(QObject *parent) - : QAbstractItemModel(parent), - m_nShowNum(0), - m_nShowAiNum(0) -{ - m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") << tr("确认状态")<< tr("告警内容"); - m_root = new CAiAlarmTreeItem(m_header,Q_NULLPTR); - m_listHorAlignmentFlags.clear(); - for (int nIndex(0); nIndex < m_header.size(); nIndex++) - { - m_listHorAlignmentFlags.append(Qt::AlignHCenter); - } - m_sortKey = E_SORT_PRIORITY; - m_order = Qt::DescendingOrder; - initFilter(); - connect(CAlarmMsgManage::instance(), SIGNAL(sigMsgArrivedToAi(QList)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgAdd,this,&CAiAlarmTreeModel::slotAiMsgAdd,Qt::QueuedConnection); - - connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgRemove,this,&CAiAlarmTreeModel::slotAiMsgRemove,Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigMsgRemove,this,&CAiAlarmTreeModel::slotMsgRemove,Qt::QueuedConnection); - - connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); - connect(CAiAlarmDataCollect::instance(),&CAiAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); - - slotMsgRefresh(); -} - -CAiAlarmTreeModel::~CAiAlarmTreeModel() -{ - m_listHorAlignmentFlags.clear(); - m_header.clear(); -} - -QVariant CAiAlarmTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(m_header.at(section)); - } - return QVariant(); -} - -QModelIndex CAiAlarmTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!hasIndex(row, column, parent)) - { - return QModelIndex(); - } - - CAiAlarmTreeItem *parentItem; - - if (!parent.isValid()) - { - parentItem = m_root; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - CAiAlarmTreeItem *childItem = parentItem->child(row); - if (childItem) - { - return createIndex(row, column, childItem); - } - else - { - return QModelIndex(); - } -} - -QModelIndex CAiAlarmTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - CAiAlarmTreeItem *childItem = static_cast(index.internalPointer()); - - CAiAlarmTreeItem *parentItem = childItem->parent(); - if (parentItem == m_root) - { - return QModelIndex(); - } - - return createIndex(parentItem->childNumber(), 0, parentItem); -} - -int CAiAlarmTreeModel::rowCount(const QModelIndex &parent) const -{ -// if (parent.column() > 0) -// { -// return 0; -// } - - CAiAlarmTreeItem *parentItem; - if (!parent.isValid()) - { - parentItem = m_root; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - return parentItem->childCount(); - - // CAiAlarmTreeItem *parentItem; - // if (parent.isValid()) - // { - // parentItem = static_cast(parent.internalPointer()); - // } - // else - // { - // parentItem = m_root; - // } - - // return parentItem->childCount(); -} - -int CAiAlarmTreeModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return static_cast(parent.internalPointer())->columnCount(); - } - else - { - return m_root->columnCount(); - } -} - -QVariant CAiAlarmTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - { - return QVariant(); - } - if(Qt::TextAlignmentRole == role) - { - if(index.column() == 7) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); - } - - }else if (Qt::DisplayRole == role) - { - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - return item->data(index.column(),E_DisplayRole); - } - return QVariant(); -} - -bool CAiAlarmTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_UNUSED(value); - Q_UNUSED(role); - if (!index.isValid() || index.column()) - { - return false; - } - return true; -} - -bool CAiAlarmTreeModel::insertRows(int row, int count, const QModelIndex &parent) -{ - bool success; - CAiAlarmTreeItem *parentItem = getItem(parent); - beginInsertRows(parent, row, row + count - 1); - success = parentItem->insertChildren(row, count, m_root->columnCount()); - endInsertRows(); - return success; -} - -bool CAiAlarmTreeModel::removeRows(int row, int count, const QModelIndex &parent) -{ - bool success; - CAiAlarmTreeItem *parentItem = getItem(parent); - beginRemoveRows(parent, row, row + count - 1); - success = parentItem->removeChildren(row, count, m_root->columnCount()); - endRemoveRows(); - return success; -} - -void CAiAlarmTreeModel::setModel() -{ - setModelData(m_root); -} - -//添加智能告警 -void CAiAlarmTreeModel::slotAiMsgAdd(const AiAlarmMsgPtr aimsg) -{ - if(aimsg->deleteFlag == true ||aimsg->brokenFlag == true) - { - return ; - } - if(conditionAiFilter(aimsg)) - { - m_nShowNum += aimsg->raw_alm_uuid.size(); - m_nShowAiNum++; - insertAlarmMsg(aimsg); - } -} - -void CAiAlarmTreeModel::slotAiMsgRemove(const QString uuid) -{ - int x= m_root->index(uuid); - if(x != -1) - { - m_nShowNum -= m_root->child(x)->childCount(); - m_nShowAiNum--; - beginRemoveRows(QModelIndex(), 0, m_root->childCount()-1); - m_root->removeChildren(x, 1, m_root->columnCount()); - endRemoveRows(); - } -} - -void CAiAlarmTreeModel::slotMsgRefresh() -{ - if(m_root->childCount() > 0) - { - beginRemoveRows(QModelIndex(), 0, m_root->childCount()-1); - m_root->removeChildren(0, m_root->childCount(), m_root->columnCount()); - endRemoveRows(); - } - m_nShowNum = 0; - m_nShowAiNum = 0; - setModel(); -} - -void CAiAlarmTreeModel::sortColumn(int column, Qt::SortOrder order) -{ - if(order == Qt::AscendingOrder) - { - m_order = Qt::DescendingOrder; - } - else - { - m_order = Qt::AscendingOrder; - } - - switch ((ColumnField)column) - { - case TIME: - { - m_sortKey = E_SORT_TIME; - break; - } - case PRIORITY: - { - m_sortKey = E_SORT_PRIORITY; - break; - } - case LOCATION: - { - m_sortKey = E_SORT_LOCATION; - break; - } - case REGION: - { - m_sortKey = E_SORT_REGION; - break; - } - case TYPE: - { - m_sortKey = E_SORT_TYPE; - break; - } - case STATUS: - { - m_sortKey = E_SORT_ALM_STATE; - break; - } - case CONFIRM: - { - m_sortKey = E_SORT_LOGICSTATE; - break; - } - case CONTENT: - { - m_sortKey = E_SORT_CONTENT; - break; - } - default: - break; - } - - beginResetModel(); - sort(); - endResetModel(); -} - -void CAiAlarmTreeModel::slotMsgRemove(const QVector deluuid) -{ - - for(int index(0);indexindex(deluuid.at(index)); - if(x != -1) - { - m_nShowNum--; - beginRemoveRows(QModelIndex(),x,x); - m_root->removeChildren(x, 1, m_root->columnCount()); - endRemoveRows(); - } - } -} - -void CAiAlarmTreeModel::setModelData(CAiAlarmTreeItem *parent) -{ - QList listAlarm; - QList listaiAlarm; - listAlarm.clear(); - listaiAlarm.clear(); - int columnCount = m_root->columnCount(); - CAlarmMsgManage::instance()->getAlarmInfo(listAlarm,listaiAlarm); - foreach (AlarmMsgPtr almPtr, listAlarm) { - if(almPtr->deleteFlag == true) - { - continue; - } - if(conditionFilter(almPtr)) - { - m_nShowNum++; - parent->insertChildren(parent->childCount(), 1, columnCount); - parent->child(parent->childCount() - 1)->setPtr(almPtr); - } - } - foreach (AiAlarmMsgPtr aialmPtr, listaiAlarm) { - if(aialmPtr->deleteFlag == true || aialmPtr->brokenFlag == true) - { - continue; - } - if(conditionAiFilter(aialmPtr)) - { - m_root->insertChildren(m_root->childCount(), 1, columnCount); - m_nShowAiNum++; - m_root->child(m_root->childCount() - 1)->setAiPtr(aialmPtr); - int num = aialmPtr->raw_alm_uuid.count(); - QVector uuidVec = aialmPtr->raw_alm_uuid; - int childCount = m_root->childCount(); - CAiAlarmTreeItem *item = m_root->child(childCount- 1); - for(int index(0);index < num; index++) - { - m_nShowNum++; - AlarmMsgPtr ptr = CAlarmMsgManage::instance()->getAlarmPtrByuuid(uuidVec.at(index)); - item->insertChildren(item->childCount(),1,columnCount); - item->child(item->childCount() - 1)->setPtr(ptr); - } - } - } - beginResetModel(); - sort(); - endResetModel(); -} - -void CAiAlarmTreeModel::sort() -{ - QMap mapAlarmInfo; - //<分 - for(int nIndex(0); nIndex < m_root->childCount(); nIndex++) - { - CAiAlarmTreeItem *item = m_root->child(nIndex); - mapAlarmInfo[nIndex / 1000].second.append(item); - } - //<快速排序 - for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) - { - qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); - } - PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; - for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) - { - //<归并 - tempListAlarmInfo.first = 0; - mapAlarmInfo[nPairIndex].first = 0; - while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) - { - if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) - { - tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - } - tempListAlarmInfo.first += 1; - } - } - QList itemList = tempListAlarmInfo.second; - for(int index(0);indexisAi()) - { - QList item = itemList.at(index)->getChild(); - qucikSort(item, 0, item.count() - 1); - itemList.at(index)->setChild(item); - } - } - m_root->setChild(tempListAlarmInfo.second); -} - -void CAiAlarmTreeModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CAiAlarmTreeModel::partitionAscendingOrder(QList &list, int start, int last) -{ - CAiAlarmTreeItem * info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(left < right && list[left]->lessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CAiAlarmTreeModel::partitionDescendingOrder(QList &list, int start, int last) -{ - CAiAlarmTreeItem * info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CAiAlarmTreeModel::calcLeft(const AiAlarmMsgPtr &info) -{ - int mid = -1; - int left = 0; - int right = m_root->childCount() - 1; - while(left <= right) - { - mid = (left + right) / 2; - - if (Qt::AscendingOrder == m_order) - { - CAiAlarmTreeItem *item =m_root->child(mid); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) &&ptr != NULL) - { - if(info->ailessThan(ptr, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) &&ptr != NULL) - { - if(info->ailessThan(ptr, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - } - else - { - CAiAlarmTreeItem *item =m_root->child(mid); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) &&ptr != NULL) - { - if(ptr->ailessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) &&ptr != NULL) - { - if(ptr->ailessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - } - } - return left; -} - -int CAiAlarmTreeModel::calcLeft(const AlarmMsgPtr &info) -{ - int mid = -1; - int left = 0; - int right = m_root->childCount() - 1; - while(left <= right) - { - mid = (left + right) / 2; - - if (Qt::AscendingOrder == m_order) - { - CAiAlarmTreeItem *item =m_root->child(mid); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) && ptr != NULL) - { - if(info->ailessThan(ptr, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) && ptr != NULL) - { - if(info->ailessThan(ptr, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - } - else - { - CAiAlarmTreeItem *item =m_root->child(mid); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr) && ptr != NULL) - { - if(ptr->ailessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr) && ptr != NULL) - { - if(ptr->ailessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - } - } - return left; -} - -CAiAlarmTreeItem *CAiAlarmTreeModel::getItem(const QModelIndex &index) const -{ - if (index.isValid()) { - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - if (item) - return item; - } - return m_root; -} - -CAiAlarmTreeItem *CAiAlarmTreeModel::getItem() const -{ - return m_root; -} - -void CAiAlarmTreeModel::initFilter() -{ - m_isLevelFilterEnable = false; - m_isLocationFilterEnable = false; - m_isRegionFilterEnable = false; - m_isTypeFilterEnable = false; - m_isDeviceTypeFileter = false; - m_isKeywordEnable = false; - m_timeFilterEnable = false; - m_confirmFilterEnable = false; -} - -void CAiAlarmTreeModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, const bool &isStationFilterEnable, const QList &stationFilter, const bool &isRegionFilterEnable, const QList ®ionFilter, const bool &isTypeFilterEnable, const QList &typeFilter, const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, const bool &isKeywordFilterEnable, const QString &keyword, const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, const bool &confirmFilterEnable, const bool &isConfirm) -{ - m_isLevelFilterEnable = isLevelFilterEnable; - m_levelFilter = levelFilter; - m_isLocationFilterEnable = isStationFilterEnable; - m_locationFilter = stationFilter; - m_isRegionFilterEnable = isRegionFilterEnable; - m_regionFilter = regionFilter; - m_isTypeFilterEnable = isTypeFilterEnable; - m_typeFilter = typeFilter; - m_isDeviceTypeFileter = isDeviceTypeFilter; - m_subSystem = subSystem; - m_deviceType = deviceType; - m_isKeywordEnable = isKeywordFilterEnable; - m_keyowrd = keyword; - m_timeFilterEnable = timeFilterEnable; - m_startTime = startTime; - m_endTime = endTime; - m_confirmFilterEnable = confirmFilterEnable; - m_isConfirm = isConfirm; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::addDeviceGroupFilter(const QString &deviceGroup) -{ - m_deviceGroupFilter.insert(deviceGroup); - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::removeDeviceGroupFilter(const QString &deviceGroup) -{ - m_deviceGroupFilter.remove(deviceGroup); - slotMsgRefresh(); -} - -bool CAiAlarmTreeModel::conditionFilter(const AlarmMsgPtr ptr) -{ - //判断是否被禁止 - if(CAlarmMsgManage::instance()->isInhibit(ptr->key_id_tag)) - { - return false; - } - //(满足所有条件就展示) - //< 车站 - if(m_isLocationFilterEnable && !m_locationFilter.contains(ptr->location_id)) - { - return false; - } - - //< 等级 - if(m_isLevelFilterEnable && !m_levelFilter.contains(ptr->priority)) - { - return false; - } - - //< 责任区 - if(m_isRegionFilterEnable && !m_regionFilter.contains(ptr->region_id)) - { - return false; - } - - //< 类型 - if(m_isTypeFilterEnable && !m_typeFilter.contains(ptr->alm_type)) - { - return false; - } - - //< 设备类型 - if(m_isDeviceTypeFileter) - { - int dev_type = CAlarmMsgManage::instance()->queryDevTypeByDesc(m_deviceType); - if(dev_type != ptr->dev_type) - { - return false; - } - } - - //< 设备组 - if(m_deviceGroupFilter.contains(ptr->dev_group_tag)) - { - return false; - } - - //< 关键字 - if(m_isKeywordEnable && !ptr->content.contains(m_keyowrd)) - { - return false; - } - - //< 时间 - if(m_timeFilterEnable) - { - if(m_startTime.toMSecsSinceEpoch() >= (qint64)(ptr->time_stamp)) - { - return false; - } - if(m_endTime.toMSecsSinceEpoch() <= (qint64)(ptr->time_stamp)) - { - return false; - } - } - - //< 是否已确认 - if(m_confirmFilterEnable) - { - if(m_isConfirm) - { - if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_RETURN || - ptr->logic_state ==E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_RETURN_DEL) - { - return false; - } - } - else - { - if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM || - ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL) - { - return false; - } - } - } - return true; -} - -bool CAiAlarmTreeModel::conditionAiFilter(const AiAlarmMsgPtr ptr) -{ - //(满足一个条件就展示) - int num = ptr->raw_alm_uuid.size(); - for(int index(0);index < num;index++) - { - AlarmMsgPtr almptr = CAlarmMsgManage::instance()->getAlarmPtrByuuid(ptr->raw_alm_uuid.at(index)); - if(conditionFilter(almptr)) - { - return true; - } - } - return false; -} - -void CAiAlarmTreeModel::sortAlm(QList &almList) -{ - if(almList.size() >0 ) - { - if(Qt::AscendingOrder == m_order) - { - for(int i = 0 ;ilessThan(almList[j+1],m_sortKey)){ - AlarmMsgPtr temp=almList[j]; - almList[j]=almList[j+1]; - almList[j+1]=temp; - } - } - } - } - else if(Qt::DescendingOrder == m_order) - { - for(int i = 0 ;imoreThan(almList[j+1],m_sortKey)){ - AlarmMsgPtr temp=almList[j]; - almList[j]=almList[j+1]; - almList[j+1]=temp; - } - } - } - } - } -} - -void CAiAlarmTreeModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - m_isLevelFilterEnable = isCheck; - m_levelFilter = priorityFilter; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::setLocationFilter(bool &isCheck, QList &locationFilter) -{ - m_isLocationFilterEnable = isCheck; - m_locationFilter = locationFilter; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter) -{ - m_isTypeFilterEnable = isCheck; - m_typeFilter = alarmTypeFilter; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) -{ - m_timeFilterEnable = isCheck; - if(isCheck) - { - QTime time_1(0,0,0); - QTime time_2(23,59,59); - m_startTime.setDate(startTime); - m_startTime.setTime(time_1); - m_endTime.setDate(endTime); - m_endTime.setTime(time_2); - } - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck) -{ - m_timeFilterEnable = isCheck; - slotMsgRefresh(); -} - -void CAiAlarmTreeModel::insertAlarmMsg(const AlarmMsgPtr &info) -{ - int left =calcLeft(info); - beginInsertRows(QModelIndex(), left, left); - m_root->insertChildren(left,1,m_root->columnCount()); - m_root->child(left)->setPtr(info); - endInsertRows(); -} - -void CAiAlarmTreeModel::insertAlarmMsg(const AiAlarmMsgPtr info) -{ - int left = calcLeft(info); - beginInsertRows(QModelIndex(), left, left); - m_root->insertChildren(left,1,m_root->columnCount()); - m_root->child(left)->setAiPtr(info); - endInsertRows(); - - int num = info->raw_alm_uuid.count(); - QVector uuidVec = info->raw_alm_uuid; - CAiAlarmTreeItem *item = m_root->child(left); - QList almList; - for(int index(0);index < num; index++) - { - AlarmMsgPtr ptr = CAlarmMsgManage::instance()->getAlarmPtrByuuid(uuidVec.at(index)); - if(ptr == NULL) - continue; - almList.append(ptr); - } - sortAlm(almList); - int almNum = almList.size()-1; - for(int num(almNum);num>=0;num--) - { - QModelIndex modelindex = createIndex(almNum-num, 0, item); - beginInsertRows(modelindex, 0, 0); - item->insertChildren(almNum-num,1,m_root->columnCount()); - item->child(almNum-num)->setPtr(almList.at(num)); - endInsertRows(); - } -} - -int CAiAlarmTreeModel::getShowNum() -{ - return m_nShowNum; -} - -int CAiAlarmTreeModel::getShowAi() -{ - return m_nShowAiNum; -} - -void CAiAlarmTreeModel::slotMsgArrived(QList listMsg) -{ - QList::const_iterator it = listMsg.constBegin(); - while (it != listMsg.constEnd()) - { - if((*it)->deleteFlag != true) - { - if(conditionFilter(*it)) - { - m_nShowNum++; - insertAlarmMsg(*it); - } - } - ++it; - } -} +#include "CAiAlarmTreeModel.h" +#include "CAlarmMsgManage.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmDataCollect.h" +#include "pub_logger_api/logger.h" +CAiAlarmTreeModel::CAiAlarmTreeModel(QObject *parent) + : QAbstractItemModel(parent), + m_nShowNum(0), + m_nShowAiNum(0) +{ + m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") << tr("确认状态")<< tr("告警内容"); + m_root = new CAiAlarmTreeItem(m_header,Q_NULLPTR); + m_listHorAlignmentFlags.clear(); + for (int nIndex(0); nIndex < m_header.size(); nIndex++) + { + m_listHorAlignmentFlags.append(Qt::AlignHCenter); + } + m_sortKey = E_SORT_PRIORITY; + m_order = Qt::DescendingOrder; + initFilter(); + connect(CAlarmMsgManage::instance(), SIGNAL(sigMsgArrivedToAi(QList)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgAdd,this,&CAiAlarmTreeModel::slotAiMsgAdd,Qt::QueuedConnection); + + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgRemove,this,&CAiAlarmTreeModel::slotAiMsgRemove,Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigMsgRemove,this,&CAiAlarmTreeModel::slotMsgRemove,Qt::QueuedConnection); + + connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); + connect(CAiAlarmDataCollect::instance(),&CAiAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); + + slotMsgRefresh(); +} + +CAiAlarmTreeModel::~CAiAlarmTreeModel() +{ + m_listHorAlignmentFlags.clear(); + m_header.clear(); +} + +QVariant CAiAlarmTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +QModelIndex CAiAlarmTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + CAiAlarmTreeItem *parentItem; + + if (!parent.isValid()) + { + parentItem = m_root; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + CAiAlarmTreeItem *childItem = parentItem->child(row); + if (childItem) + { + return createIndex(row, column, childItem); + } + else + { + return QModelIndex(); + } +} + +QModelIndex CAiAlarmTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CAiAlarmTreeItem *childItem = static_cast(index.internalPointer()); + + CAiAlarmTreeItem *parentItem = childItem->parent(); + if (parentItem == m_root) + { + return QModelIndex(); + } + + return createIndex(parentItem->childNumber(), 0, parentItem); +} + +int CAiAlarmTreeModel::rowCount(const QModelIndex &parent) const +{ +// if (parent.column() > 0) +// { +// return 0; +// } + + CAiAlarmTreeItem *parentItem; + if (!parent.isValid()) + { + parentItem = m_root; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); + + // CAiAlarmTreeItem *parentItem; + // if (parent.isValid()) + // { + // parentItem = static_cast(parent.internalPointer()); + // } + // else + // { + // parentItem = m_root; + // } + + // return parentItem->childCount(); +} + +int CAiAlarmTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return static_cast(parent.internalPointer())->columnCount(); + } + else + { + return m_root->columnCount(); + } +} + +QVariant CAiAlarmTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + if(Qt::TextAlignmentRole == role) + { + if(index.column() == 7) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + } + + }else if (Qt::DisplayRole == role) + { + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + return item->data(index.column(),E_DisplayRole); + } + return QVariant(); +} + +bool CAiAlarmTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(value); + Q_UNUSED(role); + if (!index.isValid() || index.column()) + { + return false; + } + return true; +} + +bool CAiAlarmTreeModel::insertRows(int row, int count, const QModelIndex &parent) +{ + bool success; + CAiAlarmTreeItem *parentItem = getItem(parent); + beginInsertRows(parent, row, row + count - 1); + success = parentItem->insertChildren(row, count, m_root->columnCount()); + endInsertRows(); + return success; +} + +bool CAiAlarmTreeModel::removeRows(int row, int count, const QModelIndex &parent) +{ + bool success; + CAiAlarmTreeItem *parentItem = getItem(parent); + beginRemoveRows(parent, row, row + count - 1); + success = parentItem->removeChildren(row, count, m_root->columnCount()); + endRemoveRows(); + return success; +} + +void CAiAlarmTreeModel::setModel() +{ + setModelData(m_root); +} + +//添加智能告警 +void CAiAlarmTreeModel::slotAiMsgAdd(const AiAlarmMsgPtr aimsg) +{ + if(aimsg->deleteFlag == true ||aimsg->brokenFlag == true) + { + return ; + } + if(conditionAiFilter(aimsg)) + { + m_nShowNum += aimsg->raw_alm_uuid.size(); + m_nShowAiNum++; + insertAlarmMsg(aimsg); + } +} + +void CAiAlarmTreeModel::slotAiMsgRemove(const QString uuid) +{ + int x= m_root->index(uuid); + if(x != -1) + { + m_nShowNum -= m_root->child(x)->childCount(); + m_nShowAiNum--; + beginRemoveRows(QModelIndex(), 0, m_root->childCount()-1); + m_root->removeChildren(x, 1, m_root->columnCount()); + endRemoveRows(); + } +} + +void CAiAlarmTreeModel::slotMsgRefresh() +{ + if(m_root->childCount() > 0) + { + beginRemoveRows(QModelIndex(), 0, m_root->childCount()-1); + m_root->removeChildren(0, m_root->childCount(), m_root->columnCount()); + endRemoveRows(); + } + m_nShowNum = 0; + m_nShowAiNum = 0; + setModel(); +} + +void CAiAlarmTreeModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + + switch ((ColumnField)column) + { + case TIME: + { + m_sortKey = E_SORT_TIME; + break; + } + case PRIORITY: + { + m_sortKey = E_SORT_PRIORITY; + break; + } + case LOCATION: + { + m_sortKey = E_SORT_LOCATION; + break; + } + case REGION: + { + m_sortKey = E_SORT_REGION; + break; + } + case TYPE: + { + m_sortKey = E_SORT_TYPE; + break; + } + case STATUS: + { + m_sortKey = E_SORT_ALM_STATE; + break; + } + case CONFIRM: + { + m_sortKey = E_SORT_LOGICSTATE; + break; + } + case CONTENT: + { + m_sortKey = E_SORT_CONTENT; + break; + } + default: + break; + } + + beginResetModel(); + sort(); + endResetModel(); +} + +void CAiAlarmTreeModel::slotMsgRemove(const QVector deluuid) +{ + + for(int index(0);indexindex(deluuid.at(index)); + if(x != -1) + { + m_nShowNum--; + beginRemoveRows(QModelIndex(),x,x); + m_root->removeChildren(x, 1, m_root->columnCount()); + endRemoveRows(); + } + } +} + +void CAiAlarmTreeModel::setModelData(CAiAlarmTreeItem *parent) +{ + QList listAlarm; + QList listaiAlarm; + listAlarm.clear(); + listaiAlarm.clear(); + int columnCount = m_root->columnCount(); + CAlarmMsgManage::instance()->getAlarmInfo(listAlarm,listaiAlarm); + foreach (AlarmMsgPtr almPtr, listAlarm) { + if(almPtr->deleteFlag == true) + { + continue; + } + if(conditionFilter(almPtr)) + { + m_nShowNum++; + parent->insertChildren(parent->childCount(), 1, columnCount); + parent->child(parent->childCount() - 1)->setPtr(almPtr); + } + } + foreach (AiAlarmMsgPtr aialmPtr, listaiAlarm) { + if(aialmPtr->deleteFlag == true || aialmPtr->brokenFlag == true) + { + continue; + } + if(conditionAiFilter(aialmPtr)) + { + m_root->insertChildren(m_root->childCount(), 1, columnCount); + m_nShowAiNum++; + m_root->child(m_root->childCount() - 1)->setAiPtr(aialmPtr); + int num = aialmPtr->raw_alm_uuid.count(); + QVector uuidVec = aialmPtr->raw_alm_uuid; + int childCount = m_root->childCount(); + CAiAlarmTreeItem *item = m_root->child(childCount- 1); + for(int index(0);index < num; index++) + { + m_nShowNum++; + AlarmMsgPtr ptr = CAlarmMsgManage::instance()->getAlarmPtrByuuid(uuidVec.at(index)); + item->insertChildren(item->childCount(),1,columnCount); + item->child(item->childCount() - 1)->setPtr(ptr); + } + } + } + beginResetModel(); + sort(); + endResetModel(); +} + +void CAiAlarmTreeModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_root->childCount(); nIndex++) + { + CAiAlarmTreeItem *item = m_root->child(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(item); + } + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + QList itemList = tempListAlarmInfo.second; + for(int index(0);indexisAi()) + { + QList item = itemList.at(index)->getChild(); + qucikSort(item, 0, item.count() - 1); + itemList.at(index)->setChild(item); + } + } + m_root->setChild(tempListAlarmInfo.second); +} + +void CAiAlarmTreeModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CAiAlarmTreeModel::partitionAscendingOrder(QList &list, int start, int last) +{ + CAiAlarmTreeItem * info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(left < right && list[left]->lessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAiAlarmTreeModel::partitionDescendingOrder(QList &list, int start, int last) +{ + CAiAlarmTreeItem * info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAiAlarmTreeModel::calcLeft(const AiAlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_root->childCount() - 1; + while(left <= right) + { + mid = (left + right) / 2; + + if (Qt::AscendingOrder == m_order) + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) &&ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) &&ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + else + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) &&ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) &&ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + } + return left; +} + +int CAiAlarmTreeModel::calcLeft(const AlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_root->childCount() - 1; + while(left <= right) + { + mid = (left + right) / 2; + + if (Qt::AscendingOrder == m_order) + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) && ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + else + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) && ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + } + return left; +} + +CAiAlarmTreeItem *CAiAlarmTreeModel::getItem(const QModelIndex &index) const +{ + if (index.isValid()) { + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if (item) + return item; + } + return m_root; +} + +CAiAlarmTreeItem *CAiAlarmTreeModel::getItem() const +{ + return m_root; +} + +void CAiAlarmTreeModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_isLocationFilterEnable = false; + m_isRegionFilterEnable = false; + m_isTypeFilterEnable = false; + m_isDeviceTypeFileter = false; + m_isKeywordEnable = false; + m_timeFilterEnable = false; + m_confirmFilterEnable = false; +} + +void CAiAlarmTreeModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, const bool &isStationFilterEnable, const QList &stationFilter, const bool &isRegionFilterEnable, const QList ®ionFilter, const bool &isTypeFilterEnable, const QList &typeFilter, const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, const bool &isKeywordFilterEnable, const QString &keyword, const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, const bool &confirmFilterEnable, const bool &isConfirm) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isTypeFilterEnable = isTypeFilterEnable; + m_typeFilter = typeFilter; + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyowrd = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + m_confirmFilterEnable = confirmFilterEnable; + m_isConfirm = isConfirm; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::addDeviceGroupFilter(const QString &deviceGroup) +{ + m_deviceGroupFilter.insert(deviceGroup); + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::removeDeviceGroupFilter(const QString &deviceGroup) +{ + m_deviceGroupFilter.remove(deviceGroup); + slotMsgRefresh(); +} + +bool CAiAlarmTreeModel::conditionFilter(const AlarmMsgPtr ptr) +{ + //判断是否被禁止 + if(CAlarmMsgManage::instance()->isInhibit(ptr->key_id_tag)) + { + return false; + } + //(满足所有条件就展示) + //< 车站 + if(m_isLocationFilterEnable && !m_locationFilter.contains(ptr->location_id)) + { + return false; + } + + //< 等级 + if(m_isLevelFilterEnable && !m_levelFilter.contains(ptr->priority)) + { + return false; + } + + //< 责任区 + if(m_isRegionFilterEnable && !m_regionFilter.contains(ptr->region_id)) + { + return false; + } + + //< 类型 + if(m_isTypeFilterEnable && !m_typeFilter.contains(ptr->alm_type)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { + int dev_type = CAlarmMsgManage::instance()->queryDevTypeByDesc(m_deviceType); + if(dev_type != ptr->dev_type) + { + return false; + } + } + + //< 设备组 + if(m_deviceGroupFilter.contains(ptr->dev_group_tag)) + { + return false; + } + + //< 关键字 + if(m_isKeywordEnable && !ptr->content.contains(m_keyowrd)) + { + return false; + } + + //< 时间 + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() >= (qint64)(ptr->time_stamp)) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() <= (qint64)(ptr->time_stamp)) + { + return false; + } + } + + //< 是否已确认 + if(m_confirmFilterEnable) + { + if(m_isConfirm) + { + if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_RETURN || + ptr->logic_state ==E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_RETURN_DEL) + { + return false; + } + } + else + { + if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM || + ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL) + { + return false; + } + } + } + return true; +} + +bool CAiAlarmTreeModel::conditionAiFilter(const AiAlarmMsgPtr ptr) +{ + //(满足一个条件就展示) + int num = ptr->raw_alm_uuid.size(); + for(int index(0);index < num;index++) + { + AlarmMsgPtr almptr = CAlarmMsgManage::instance()->getAlarmPtrByuuid(ptr->raw_alm_uuid.at(index)); + if(conditionFilter(almptr)) + { + return true; + } + } + return false; +} + +void CAiAlarmTreeModel::sortAlm(QList &almList) +{ + if(almList.size() >0 ) + { + if(Qt::AscendingOrder == m_order) + { + for(int i = 0 ;ilessThan(almList[j+1],m_sortKey)){ + AlarmMsgPtr temp=almList[j]; + almList[j]=almList[j+1]; + almList[j+1]=temp; + } + } + } + } + else if(Qt::DescendingOrder == m_order) + { + for(int i = 0 ;imoreThan(almList[j+1],m_sortKey)){ + AlarmMsgPtr temp=almList[j]; + almList[j]=almList[j+1]; + almList[j+1]=temp; + } + } + } + } + } +} + +void CAiAlarmTreeModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter) +{ + m_isTypeFilterEnable = isCheck; + m_typeFilter = alarmTypeFilter; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::insertAlarmMsg(const AlarmMsgPtr &info) +{ + int left =calcLeft(info); + beginInsertRows(QModelIndex(), left, left); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setPtr(info); + endInsertRows(); +} + +void CAiAlarmTreeModel::insertAlarmMsg(const AiAlarmMsgPtr info) +{ + int left = calcLeft(info); + beginInsertRows(QModelIndex(), left, left); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setAiPtr(info); + endInsertRows(); + + int num = info->raw_alm_uuid.count(); + QVector uuidVec = info->raw_alm_uuid; + CAiAlarmTreeItem *item = m_root->child(left); + QList almList; + for(int index(0);index < num; index++) + { + AlarmMsgPtr ptr = CAlarmMsgManage::instance()->getAlarmPtrByuuid(uuidVec.at(index)); + if(ptr == NULL) + continue; + almList.append(ptr); + } + sortAlm(almList); + int almNum = almList.size()-1; + for(int num(almNum);num>=0;num--) + { + QModelIndex modelindex = createIndex(almNum-num, 0, item); + beginInsertRows(modelindex, 0, 0); + item->insertChildren(almNum-num,1,m_root->columnCount()); + item->child(almNum-num)->setPtr(almList.at(num)); + endInsertRows(); + } +} + +int CAiAlarmTreeModel::getShowNum() +{ + return m_nShowNum; +} + +int CAiAlarmTreeModel::getShowAi() +{ + return m_nShowAiNum; +} + +void CAiAlarmTreeModel::slotMsgArrived(QList listMsg) +{ + QList::const_iterator it = listMsg.constBegin(); + while (it != listMsg.constEnd()) + { + if((*it)->deleteFlag != true) + { + if(conditionFilter(*it)) + { + m_nShowNum++; + insertAlarmMsg(*it); + } + } + ++it; + } +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeModel.h b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeModel.h index a194bbc6..b4b5c324 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeModel.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeModel.h @@ -1,148 +1,148 @@ -#ifndef CAIALARMTREEMODEL_H -#define CAIALARMTREEMODEL_H - -#include -#include -#include - -typedef QPair > PAIRLISTALARMINFO; -class CAiAlarmTreeModel : public QAbstractItemModel -{ - Q_OBJECT -public: - explicit CAiAlarmTreeModel(QObject *parent = nullptr); - ~CAiAlarmTreeModel(); - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role); - // Add data: - bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - - // Remove data: - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - - void setModel(); - - CAiAlarmTreeItem *getItem(const QModelIndex &index) const; - - CAiAlarmTreeItem *getItem() const; - - void initFilter(); - - void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), - const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), - const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), - const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false); - - void addDeviceGroupFilter(const QString &deviceGroup); - - void removeDeviceGroupFilter(const QString &deviceGroup); - - void filter(); - - bool conditionFilter(const AlarmMsgPtr ptr); - - bool conditionAiFilter(const AiAlarmMsgPtr ptr); - - void sortAlm(QList &almList); -public: - void setPriorityFilter(bool &isCheck, QList &priorityFilter); - void setLocationFilter(bool &isCheck, QList &locationFilter); - void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter); - void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); - void setAlarmTimeFilter(bool &isCheck); - - void insertAlarmMsg(const AlarmMsgPtr &info); - - void insertAlarmMsg(const AiAlarmMsgPtr info); - - int getShowNum(); - - int getShowAi(); -public slots: - - void slotMsgArrived(QList listMsg); - - void slotAiMsgAdd(const AiAlarmMsgPtr aimsg); - - void slotAiMsgRemove(const QString uuid); - - void slotMsgRefresh(); - - void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); - - void slotMsgRemove(const QVector deluuid); -private: - void setModelData(CAiAlarmTreeItem *parent); - - void sort(); - - void qucikSort(QList &list, int start, int last); - - int partitionAscendingOrder(QList &list, int start, int last); - int partitionDescendingOrder(QList &list, int start, int last); - - int calcLeft(const AiAlarmMsgPtr &info); - int calcLeft(const AlarmMsgPtr &info); - -private: - - CAiAlarmTreeItem *m_root; - QVector m_header; - QList m_listHorAlignmentFlags; //< 水平对齐方式 - - //< Filter - bool m_isLevelFilterEnable; //是否按告警级别过滤 - QList m_levelFilter; //告警级别过滤 - bool m_isLocationFilterEnable; //是否按车站过滤 - QList m_locationFilter; //车站过滤 - bool m_isRegionFilterEnable; //是否按责任区过滤 - QList m_regionFilter; //责任区过滤 - - bool m_isTypeFilterEnable; //是否按告警类型过滤 - QList m_typeFilter; //告警类型过滤 - -// bool m_isStatusFilterEnable; //是否按告警状态过滤 -// QList m_statusFilter; //告警状态过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) -// QList m_statusFilter2; //告警状态过滤(显示在过滤窗中的告警状态) - bool m_isDeviceTypeFileter; //设备类型过滤 - QString m_subSystem; //子系统 - QString m_deviceType; //设备类型 - bool m_isKeywordEnable; //关键字过滤 - QString m_keyowrd; //关键字 - bool m_timeFilterEnable; //是否根据时间过滤 - QDateTime m_startTime; //起始时间 - QDateTime m_endTime; //终止时间 - bool m_confirmFilterEnable; //是否根据状态确认过滤 - bool m_isConfirm; //状态是否确认 - - QSet m_deviceFilter; //< 设备过滤 - QSet m_pointFilter; //标签过滤 - QSet m_deviceGroupFilter; //<设备组过滤 - -// QList m_alarm; //< 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗)(两个线程共同维护) -// QList m_aiinfos; //< 有权限已过滤的智能告警 - - E_ALARM_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - - int m_nShowNum; - int m_nShowAiNum; - -}; - -#endif // CAIALARMTREEMODEL_H +#ifndef CAIALARMTREEMODEL_H +#define CAIALARMTREEMODEL_H + +#include +#include +#include + +typedef QPair > PAIRLISTALARMINFO; +class CAiAlarmTreeModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit CAiAlarmTreeModel(QObject *parent = nullptr); + ~CAiAlarmTreeModel(); + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role); + // Add data: + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + // Remove data: + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + void setModel(); + + CAiAlarmTreeItem *getItem(const QModelIndex &index) const; + + CAiAlarmTreeItem *getItem() const; + + void initFilter(); + + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false); + + void addDeviceGroupFilter(const QString &deviceGroup); + + void removeDeviceGroupFilter(const QString &deviceGroup); + + void filter(); + + bool conditionFilter(const AlarmMsgPtr ptr); + + bool conditionAiFilter(const AiAlarmMsgPtr ptr); + + void sortAlm(QList &almList); +public: + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter); + void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); + void setAlarmTimeFilter(bool &isCheck); + + void insertAlarmMsg(const AlarmMsgPtr &info); + + void insertAlarmMsg(const AiAlarmMsgPtr info); + + int getShowNum(); + + int getShowAi(); +public slots: + + void slotMsgArrived(QList listMsg); + + void slotAiMsgAdd(const AiAlarmMsgPtr aimsg); + + void slotAiMsgRemove(const QString uuid); + + void slotMsgRefresh(); + + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + + void slotMsgRemove(const QVector deluuid); +private: + void setModelData(CAiAlarmTreeItem *parent); + + void sort(); + + void qucikSort(QList &list, int start, int last); + + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + + int calcLeft(const AiAlarmMsgPtr &info); + int calcLeft(const AlarmMsgPtr &info); + +private: + + CAiAlarmTreeItem *m_root; + QVector m_header; + QList m_listHorAlignmentFlags; //< 水平对齐方式 + + //< Filter + bool m_isLevelFilterEnable; //是否按告警级别过滤 + QList m_levelFilter; //告警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + + bool m_isTypeFilterEnable; //是否按告警类型过滤 + QList m_typeFilter; //告警类型过滤 + +// bool m_isStatusFilterEnable; //是否按告警状态过滤 +// QList m_statusFilter; //告警状态过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) +// QList m_statusFilter2; //告警状态过滤(显示在过滤窗中的告警状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyowrd; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + bool m_confirmFilterEnable; //是否根据状态确认过滤 + bool m_isConfirm; //状态是否确认 + + QSet m_deviceFilter; //< 设备过滤 + QSet m_pointFilter; //标签过滤 + QSet m_deviceGroupFilter; //<设备组过滤 + +// QList m_alarm; //< 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗)(两个线程共同维护) +// QList m_aiinfos; //< 有权限已过滤的智能告警 + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + int m_nShowNum; + int m_nShowAiNum; + +}; + +#endif // CAIALARMTREEMODEL_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeView.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeView.cpp index 40e1f640..cd92927f 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeView.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeView.cpp @@ -1,20 +1,20 @@ -#include "CAiAlarmTreeView.h" -#include -#include -CAiAlarmTreeView::CAiAlarmTreeView(QWidget *parent) - :QTreeView(parent) -{ -} - -void CAiAlarmTreeView::initialize() -{ - - setSortingEnabled(true); - setAlternatingRowColors(true); - header()->setDefaultAlignment(Qt::AlignCenter); - header()->setStretchLastSection(true); - header()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::MultiSelection); - setHorizontalScrollMode(ScrollPerPixel); -} +#include "CAiAlarmTreeView.h" +#include +#include +CAiAlarmTreeView::CAiAlarmTreeView(QWidget *parent) + :QTreeView(parent) +{ +} + +void CAiAlarmTreeView::initialize() +{ + + setSortingEnabled(true); + setAlternatingRowColors(true); + header()->setDefaultAlignment(Qt::AlignCenter); + header()->setStretchLastSection(true); + header()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::MultiSelection); + setHorizontalScrollMode(ScrollPerPixel); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeView.h b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeView.h index 001ef81a..e4af5631 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeView.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAiAlarmTreeView.h @@ -1,15 +1,15 @@ -#ifndef CAIALARMTREEVIEW_H -#define CAIALARMTREEVIEW_H - -#include - -class CAiAlarmTreeView : public QTreeView -{ - Q_OBJECT -public: - CAiAlarmTreeView(QWidget *parent = Q_NULLPTR); - - void initialize(); -}; - -#endif // CAIALARMTREEVIEW_H +#ifndef CAIALARMTREEVIEW_H +#define CAIALARMTREEVIEW_H + +#include + +class CAiAlarmTreeView : public QTreeView +{ + Q_OBJECT +public: + CAiAlarmTreeView(QWidget *parent = Q_NULLPTR); + + void initialize(); +}; + +#endif // CAIALARMTREEVIEW_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmCommon.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmCommon.h index 560afcc7..ea992d9d 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmCommon.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmCommon.h @@ -1,48 +1,48 @@ -#ifndef CALARMCOMMON_H -#define CALARMCOMMON_H - -#include -class CAlarmMsgInfo; -class CAiAlarmMsgInfo; - -typedef QSharedPointer AlarmMsgPtr; -typedef QSharedPointer AiAlarmMsgPtr; -#define FUNC_ALM_ACT_VIDEO_ALM ("ALM_ACT_VIDEO_ALM") -#define FUNC_ALM_ACT_ROBOT_LINK ("ALM_ACT_ROBOT_LINK") -#define FUNC_ALM_ACT_SHORT_MSG ("ALM_ACT_SHORT_MSG") -const QString fun_ia_edit = "FUNC_NOM_IA_EDIT"; //智能告警编辑权限 -#define VIDEO_TIME 30*1000 - -#define VIDEO_COLUMN 7 //视频按钮所在列 -//窗口 -enum E_Alarm_Mode -{ - E_Alarm_Dock, - E_Alarm_Window, - E_Alarm_Pop -}; - -//排序 -enum E_ALARM_SORTKEY -{ - E_SORT_VIDEO =0, - E_SORT_PRIORITY, //< 优先级 - E_SORT_TIME, //< 时间戳 - E_SORT_LOCATION, //< 车站 - E_SORT_REGION, //< 责任区 - E_SORT_TYPE, //< 告警类型 - E_SORT_CONTENT, //< 告警内容 - E_SORT_LOGICSTATE, //< 逻辑状态 - E_SORT_ALM_STATE //< 告警状态 -}; -struct SAiConfirm -{ - int nConfirm; - int nTotal; - SAiConfirm() { - nConfirm = 0; - nTotal = 0; - } -}; - -#endif // CALARMCOMMON_H +#ifndef CALARMCOMMON_H +#define CALARMCOMMON_H + +#include +class CAlarmMsgInfo; +class CAiAlarmMsgInfo; + +typedef QSharedPointer AlarmMsgPtr; +typedef QSharedPointer AiAlarmMsgPtr; +#define FUNC_ALM_ACT_VIDEO_ALM ("ALM_ACT_VIDEO_ALM") +#define FUNC_ALM_ACT_ROBOT_LINK ("ALM_ACT_ROBOT_LINK") +#define FUNC_ALM_ACT_SHORT_MSG ("ALM_ACT_SHORT_MSG") +const QString fun_ia_edit = "FUNC_NOM_IA_EDIT"; //智能告警编辑权限 +#define VIDEO_TIME 30*1000 + +#define VIDEO_COLUMN 7 //视频按钮所在列 +//窗口 +enum E_Alarm_Mode +{ + E_Alarm_Dock, + E_Alarm_Window, + E_Alarm_Pop +}; + +//排序 +enum E_ALARM_SORTKEY +{ + E_SORT_VIDEO =0, + E_SORT_PRIORITY, //< 优先级 + E_SORT_TIME, //< 时间戳 + E_SORT_LOCATION, //< 车站 + E_SORT_REGION, //< 责任区 + E_SORT_TYPE, //< 告警类型 + E_SORT_CONTENT, //< 告警内容 + E_SORT_LOGICSTATE, //< 逻辑状态 + E_SORT_ALM_STATE //< 告警状态 +}; +struct SAiConfirm +{ + int nConfirm; + int nTotal; + SAiConfirm() { + nConfirm = 0; + nTotal = 0; + } +}; + +#endif // CALARMCOMMON_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDataCollect.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDataCollect.cpp index f48588d4..184d391b 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDataCollect.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDataCollect.cpp @@ -1,350 +1,350 @@ -#include "CAlarmDataCollect.h" -#include -#include "pub_logger_api/logger.h" -#include "CAlarmMsgManage.h" -#include -#include "CAiAlarmDataCollect.h" -#include "dbms/db_sysinfo_api/CDbSysInfo.h" - -using namespace kbd_service; -using namespace kbd_dbms; -CAlarmDataCollect * CAlarmDataCollect::m_pInstance = NULL; - -CAlarmDataCollect::CAlarmDataCollect() - : CAlmApiForAlmClt(), - m_referenceCount(0), - m_bFaultRecallState(false), - m_pAlternateTimer(Q_NULLPTR), - m_bIsNeedUpdate(false), - m_bIsNeedRemove(false) -{ - m_rtdbMutex = new QMutex(); - m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); - m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); - - m_rtdbAlmLvlDefTab = new kbd_dbms::CRdbAccess(); - m_rtdbAlmLvlDefTab->open("base","alarm_level_define"); - - m_rtdbAlmActDefTab = new kbd_dbms::CRdbAccess(); - m_rtdbAlmActDefTab->open("base","alarm_action_define"); -} - -CAlarmDataCollect::~CAlarmDataCollect() -{ - LOGINFO("CAlarmDataCollect::~CAlarmDataCollect()"); - qDebug() << "~CAlarmDataCollect()"; -} - -void CAlarmDataCollect::refrence() -{ - m_referenceCount++; -} - -CAlarmDataCollect *CAlarmDataCollect::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CAlarmDataCollect(); - } - return m_pInstance; -} - -void CAlarmDataCollect::initialize() -{ - CAlarmMsgManage::instance()->initialize(); - resumeThread(); - if(!m_pAlternateTimer) - { - m_pAlternateTimer = new QTimer(); - m_pAlternateTimer->setInterval(1000); - connect(m_pAlternateTimer, &QTimer::timeout, this, &CAlarmDataCollect::slotAlarmStateChanged); - connect(this, &CAlarmDataCollect::sigTimerShot, this, &CAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); - } - emit sigTimerShot(true); -} - -void CAlarmDataCollect::release() -{ - emit sigTimerShot(false); - suspendThread(true); - QMutexLocker locker(m_rtdbMutex); - m_bIsNeedUpdate = false; - m_bIsNeedRemove = false; - CAlarmMsgManage::instance()->release(); - emit sigAlarmStateChanged(0, 0); - emit sigMsgRefresh(); -} - - -int CAlarmDataCollect::getRefrenceCount() -{ - return m_referenceCount; -} - -bool CAlarmDataCollect::isFaultRecallState() -{ - return m_bFaultRecallState; -} - -void CAlarmDataCollect::destory(bool *pExit) -{ - LOGINFO("退出时:CAlarmDataCollect::destory()打开窗口的个数m_referenceCount:[%d]",m_referenceCount); - if(--m_referenceCount > 0) - { - return; - } - bool exit =false; - CAiAlarmDataCollect::instance()->destory(&exit); - m_pAlternateTimer->blockSignals(true); - //< 退出数据采集线程 - while(!exit) - { - QThread::msleep(10); - } - m_pAlternateTimer->blockSignals(true); - suspendThread(); - { - QMutexLocker locker(m_rtdbMutex); - if(Q_NULLPTR != m_pAlternateTimer) - { - m_pAlternateTimer->stop(); - m_pAlternateTimer->deleteLater(); - } - m_pAlternateTimer = Q_NULLPTR; - m_bIsNeedUpdate = false; - m_bIsNeedRemove = false; - } - CAlarmMsgManage::instance()->destory(); - delete m_rtdbMutex; - delete m_rtdbPriorityOrderAccess; - m_pInstance = NULL; - delete this; - - *pExit = true; -} - -void CAlarmDataCollect::slotTimerShot(const bool start) -{ - if(m_pAlternateTimer) - { - if(start) - { - m_pAlternateTimer->start(); - } - else - { - m_pAlternateTimer->stop(); - } - } -} - -void CAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) -{ - m_bFaultRecallState = bFaultRecallState; - emit sigMsgRefresh(); - - m_pInstance->reinit(m_bFaultRecallState); -} - -bool CAlarmDataCollect::requestCfmAlm(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm) -{ - return kbd_service::CAlmApiForAlmClt::requestCfmAlm(objCfmAlm); -} - -bool CAlarmDataCollect::requestDelAlm(kbd_idlfile::SAlmCltDelAlm &objDelAlm) -{ - return kbd_service::CAlmApiForAlmClt::requestDelAlm(objDelAlm); -} - -void CAlarmDataCollect::handleAllAlmMsg(int domainId, kbd_idlfile::SAlmCltAddAlm &objAllAlm) -{ - loadAlmAct(); - loadAlmLel(); - if(!m_referenceCount) - { - return; - } - LOGINFO("========== AlarmDataCollect handleAllAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - //< 清空该域缓存 - CAlarmMsgManage::instance()->removeAlarmMsgByDomainID(domainId); - - //< 构建告警 - int nAlarmCount = objAllAlm.alm_info_size(); - for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) - { - kbd_idlfile::SAlmInfoToAlmClt msg = objAllAlm.alm_info(nAddMsgIndex); - AlarmMsgPtr alm(new CAlarmMsgInfo()); - alm->initialize(msg); - alm->priorityOrder = queryPriorityOrder(alm->priority); - //是否需要视频告警 - int priority = m_levelMap.value(alm->priority); - if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (priority>>(m_actMap.value(FUNC_ALM_ACT_VIDEO_ALM,1)-1) & 0x01)) - { - alm->m_needVideoAlm = true; - }else - { - alm->m_needVideoAlm = false; - } - CAlarmMsgManage::instance()->addAlarmMsg(alm); - } - CAlarmMsgManage::instance()->updateAiInfo(); - emit sigMsgRefresh(); - LOGDEBUG("handleAllAlmMsg END[%d] ",nAlarmCount); -} - -void CAlarmDataCollect::handleAddAlmMsg(kbd_idlfile::SAlmCltAddAlm &objAddAlm) -{ - loadAlmAct(); - loadAlmLel(); - if(!m_referenceCount) - { - return; - } - LOGINFO("========== AlarmDataCollect handleAddAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - //< 构建告警 - int nAlarmCount = objAddAlm.alm_info_size(); - for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) - { - kbd_idlfile::SAlmInfoToAlmClt msg = objAddAlm.alm_info(nAddMsgIndex); - AlarmMsgPtr alm(new CAlarmMsgInfo()); - alm->initialize(msg); - alm->priorityOrder = queryPriorityOrder(alm->priority); - //是否需要视频告警 - int priority = m_levelMap.value(alm->priority); - if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (priority>>(m_actMap.value(FUNC_ALM_ACT_VIDEO_ALM,1)-1) & 0x01)) - { - alm->m_needVideoAlm = true; - }else - { - alm->m_needVideoAlm = false; - } - //CAlarmMsgManage::instance()->addAlarmMsg(alm); - CAlarmMsgManage::instance()->addAlarmToAllInfo(alm); - CAlarmMsgManage::instance()->updateMsgAction(alm); - CAlarmMsgManage::instance()->addAlarmCacheMsg(alm); - } -} - -void CAlarmDataCollect::handleCfmAlmMsg(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm) -{ - if(!m_referenceCount) - { - return; - } - LOGINFO("========== AlarmDataCollect handleCfmAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - int nAlarmCount = objCfmAlm.uuid_base64_size(); - for(int nCfmMsgIndex(0); nCfmMsgIndex < nAlarmCount; nCfmMsgIndex++) - { - QString uuid = QString::fromStdString(objCfmAlm.uuid_base64(nCfmMsgIndex)); - CAlarmMsgManage::instance()->confirmAlarmMsg(uuid); - } - m_bIsNeedUpdate = true; -} - -void CAlarmDataCollect::handleDelAlmMsg(kbd_idlfile::SAlmCltDelAlm &objDelAlm) -{ - if(!m_referenceCount) - { - return; - } - - LOGINFO("========== AlarmDataCollect handleDelAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - int nAlarmCount = objDelAlm.uuid_base64_size(); - for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) - { - QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); - CAlarmMsgManage::instance()->removeAlarmMsg(uuid); - } - m_bIsNeedRemove = true; -} - -void CAlarmDataCollect::handleReleaseAlmMsg(kbd_idlfile::SAlmCltReleaseAlm &objRelAlm) -{ - if(!m_referenceCount) - { - return; - } - LOGINFO("========== AlarmDataCollect handleReleaseAlmMsg =========="); - QMutexLocker locker(m_rtdbMutex); - int nAlarmCount = objRelAlm.uuid_base64_size(); - for(int nRelMsgIndex(0); nRelMsgIndex < nAlarmCount; nRelMsgIndex++) - { - QString uuid = QString::fromStdString(objRelAlm.uuid_base64(nRelMsgIndex)); - CAlarmMsgManage::instance()->releaseAlarmMsg(uuid); - } -} - -void CAlarmDataCollect::slotAlarmStateChanged() -{ - QMutexLocker locker(m_rtdbMutex); - CAlarmMsgManage::instance()->msgArrived(); - if(m_bIsNeedUpdate) - { - emit sigMsgConfirm(); - m_bIsNeedUpdate = false; - } - - if(m_bIsNeedRemove) - { - emit sigMsgRemove(); - m_bIsNeedRemove = false; - } - int total = CAlarmMsgManage::instance()->getAlarmTotalSize(); - int unConfirm = CAlarmMsgManage::instance()->getUnConfirmSize(); - emit sigAlarmStateChanged(total, unConfirm); - emit sigUpdateAlarmView(); -} - -int CAlarmDataCollect::queryPriorityOrder(int &id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); - kbd_dbms::CVarType value = -1000; - m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); - return value.toInt(); -} - -void CAlarmDataCollect::loadAlmAct() -{ - CRdbQueryResult oResult; - m_actMap.clear(); - if(m_rtdbAlmActDefTab->select(oResult)) - { - CVarType actDef; - CVarType actId; - for(int index(0);indexselect(oResult)) - { - CVarType priorityId; - CVarType almAction; - for(int index(0);index +#include "pub_logger_api/logger.h" +#include "CAlarmMsgManage.h" +#include +#include "CAiAlarmDataCollect.h" +#include "dbms/db_sysinfo_api/CDbSysInfo.h" + +using namespace kbd_service; +using namespace kbd_dbms; +CAlarmDataCollect * CAlarmDataCollect::m_pInstance = NULL; + +CAlarmDataCollect::CAlarmDataCollect() + : CAlmApiForAlmClt(), + m_referenceCount(0), + m_bFaultRecallState(false), + m_pAlternateTimer(Q_NULLPTR), + m_bIsNeedUpdate(false), + m_bIsNeedRemove(false) +{ + m_rtdbMutex = new QMutex(); + m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); + + m_rtdbAlmLvlDefTab = new kbd_dbms::CRdbAccess(); + m_rtdbAlmLvlDefTab->open("base","alarm_level_define"); + + m_rtdbAlmActDefTab = new kbd_dbms::CRdbAccess(); + m_rtdbAlmActDefTab->open("base","alarm_action_define"); +} + +CAlarmDataCollect::~CAlarmDataCollect() +{ + LOGINFO("CAlarmDataCollect::~CAlarmDataCollect()"); + qDebug() << "~CAlarmDataCollect()"; +} + +void CAlarmDataCollect::refrence() +{ + m_referenceCount++; +} + +CAlarmDataCollect *CAlarmDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAlarmDataCollect(); + } + return m_pInstance; +} + +void CAlarmDataCollect::initialize() +{ + CAlarmMsgManage::instance()->initialize(); + resumeThread(); + if(!m_pAlternateTimer) + { + m_pAlternateTimer = new QTimer(); + m_pAlternateTimer->setInterval(1000); + connect(m_pAlternateTimer, &QTimer::timeout, this, &CAlarmDataCollect::slotAlarmStateChanged); + connect(this, &CAlarmDataCollect::sigTimerShot, this, &CAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); + } + emit sigTimerShot(true); +} + +void CAlarmDataCollect::release() +{ + emit sigTimerShot(false); + suspendThread(true); + QMutexLocker locker(m_rtdbMutex); + m_bIsNeedUpdate = false; + m_bIsNeedRemove = false; + CAlarmMsgManage::instance()->release(); + emit sigAlarmStateChanged(0, 0); + emit sigMsgRefresh(); +} + + +int CAlarmDataCollect::getRefrenceCount() +{ + return m_referenceCount; +} + +bool CAlarmDataCollect::isFaultRecallState() +{ + return m_bFaultRecallState; +} + +void CAlarmDataCollect::destory(bool *pExit) +{ + LOGINFO("退出时:CAlarmDataCollect::destory()打开窗口的个数m_referenceCount:[%d]",m_referenceCount); + if(--m_referenceCount > 0) + { + return; + } + bool exit =false; + CAiAlarmDataCollect::instance()->destory(&exit); + m_pAlternateTimer->blockSignals(true); + //< 退出数据采集线程 + while(!exit) + { + QThread::msleep(10); + } + m_pAlternateTimer->blockSignals(true); + suspendThread(); + { + QMutexLocker locker(m_rtdbMutex); + if(Q_NULLPTR != m_pAlternateTimer) + { + m_pAlternateTimer->stop(); + m_pAlternateTimer->deleteLater(); + } + m_pAlternateTimer = Q_NULLPTR; + m_bIsNeedUpdate = false; + m_bIsNeedRemove = false; + } + CAlarmMsgManage::instance()->destory(); + delete m_rtdbMutex; + delete m_rtdbPriorityOrderAccess; + m_pInstance = NULL; + delete this; + + *pExit = true; +} + +void CAlarmDataCollect::slotTimerShot(const bool start) +{ + if(m_pAlternateTimer) + { + if(start) + { + m_pAlternateTimer->start(); + } + else + { + m_pAlternateTimer->stop(); + } + } +} + +void CAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) +{ + m_bFaultRecallState = bFaultRecallState; + emit sigMsgRefresh(); + + m_pInstance->reinit(m_bFaultRecallState); +} + +bool CAlarmDataCollect::requestCfmAlm(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm) +{ + return kbd_service::CAlmApiForAlmClt::requestCfmAlm(objCfmAlm); +} + +bool CAlarmDataCollect::requestDelAlm(kbd_idlfile::SAlmCltDelAlm &objDelAlm) +{ + return kbd_service::CAlmApiForAlmClt::requestDelAlm(objDelAlm); +} + +void CAlarmDataCollect::handleAllAlmMsg(int domainId, kbd_idlfile::SAlmCltAddAlm &objAllAlm) +{ + loadAlmAct(); + loadAlmLel(); + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleAllAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //< 清空该域缓存 + CAlarmMsgManage::instance()->removeAlarmMsgByDomainID(domainId); + + //< 构建告警 + int nAlarmCount = objAllAlm.alm_info_size(); + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + kbd_idlfile::SAlmInfoToAlmClt msg = objAllAlm.alm_info(nAddMsgIndex); + AlarmMsgPtr alm(new CAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + //是否需要视频告警 + int priority = m_levelMap.value(alm->priority); + if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (priority>>(m_actMap.value(FUNC_ALM_ACT_VIDEO_ALM,1)-1) & 0x01)) + { + alm->m_needVideoAlm = true; + }else + { + alm->m_needVideoAlm = false; + } + CAlarmMsgManage::instance()->addAlarmMsg(alm); + } + CAlarmMsgManage::instance()->updateAiInfo(); + emit sigMsgRefresh(); + LOGDEBUG("handleAllAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleAddAlmMsg(kbd_idlfile::SAlmCltAddAlm &objAddAlm) +{ + loadAlmAct(); + loadAlmLel(); + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleAddAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //< 构建告警 + int nAlarmCount = objAddAlm.alm_info_size(); + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + kbd_idlfile::SAlmInfoToAlmClt msg = objAddAlm.alm_info(nAddMsgIndex); + AlarmMsgPtr alm(new CAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + //是否需要视频告警 + int priority = m_levelMap.value(alm->priority); + if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (priority>>(m_actMap.value(FUNC_ALM_ACT_VIDEO_ALM,1)-1) & 0x01)) + { + alm->m_needVideoAlm = true; + }else + { + alm->m_needVideoAlm = false; + } + //CAlarmMsgManage::instance()->addAlarmMsg(alm); + CAlarmMsgManage::instance()->addAlarmToAllInfo(alm); + CAlarmMsgManage::instance()->updateMsgAction(alm); + CAlarmMsgManage::instance()->addAlarmCacheMsg(alm); + } +} + +void CAlarmDataCollect::handleCfmAlmMsg(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleCfmAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objCfmAlm.uuid_base64_size(); + for(int nCfmMsgIndex(0); nCfmMsgIndex < nAlarmCount; nCfmMsgIndex++) + { + QString uuid = QString::fromStdString(objCfmAlm.uuid_base64(nCfmMsgIndex)); + CAlarmMsgManage::instance()->confirmAlarmMsg(uuid); + } + m_bIsNeedUpdate = true; +} + +void CAlarmDataCollect::handleDelAlmMsg(kbd_idlfile::SAlmCltDelAlm &objDelAlm) +{ + if(!m_referenceCount) + { + return; + } + + LOGINFO("========== AlarmDataCollect handleDelAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objDelAlm.uuid_base64_size(); + for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) + { + QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); + CAlarmMsgManage::instance()->removeAlarmMsg(uuid); + } + m_bIsNeedRemove = true; +} + +void CAlarmDataCollect::handleReleaseAlmMsg(kbd_idlfile::SAlmCltReleaseAlm &objRelAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleReleaseAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objRelAlm.uuid_base64_size(); + for(int nRelMsgIndex(0); nRelMsgIndex < nAlarmCount; nRelMsgIndex++) + { + QString uuid = QString::fromStdString(objRelAlm.uuid_base64(nRelMsgIndex)); + CAlarmMsgManage::instance()->releaseAlarmMsg(uuid); + } +} + +void CAlarmDataCollect::slotAlarmStateChanged() +{ + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->msgArrived(); + if(m_bIsNeedUpdate) + { + emit sigMsgConfirm(); + m_bIsNeedUpdate = false; + } + + if(m_bIsNeedRemove) + { + emit sigMsgRemove(); + m_bIsNeedRemove = false; + } + int total = CAlarmMsgManage::instance()->getAlarmTotalSize(); + int unConfirm = CAlarmMsgManage::instance()->getUnConfirmSize(); + emit sigAlarmStateChanged(total, unConfirm); + emit sigUpdateAlarmView(); +} + +int CAlarmDataCollect::queryPriorityOrder(int &id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + kbd_dbms::CVarType value = -1000; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +void CAlarmDataCollect::loadAlmAct() +{ + CRdbQueryResult oResult; + m_actMap.clear(); + if(m_rtdbAlmActDefTab->select(oResult)) + { + CVarType actDef; + CVarType actId; + for(int index(0);indexselect(oResult)) + { + CVarType priorityId; + CVarType almAction; + for(int index(0);index -#include -#include -#include -#include -#include "AlarmMessage.pb.h" -#include "CAlarmMsgInfo.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "dbms/rdb_api/CRdbAccess.h" - -class CAlarmDataCollect : public QObject, public kbd_service::CAlmApiForAlmClt -{ - Q_OBJECT -public: - static CAlarmDataCollect *instance(); - - virtual ~CAlarmDataCollect(); - - void initialize(); - - void refrence(); - - void release(); - - int getRefrenceCount(); - - bool isFaultRecallState(); - - virtual bool requestCfmAlm(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm); - - virtual bool requestDelAlm(kbd_idlfile::SAlmCltDelAlm &objDelAlm); - - virtual void handleAllAlmMsg(int domainId, kbd_idlfile::SAlmCltAddAlm &objAllAlm); - - virtual void handleAddAlmMsg(kbd_idlfile::SAlmCltAddAlm &objAddAlm); - - virtual void handleCfmAlmMsg(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm); - - virtual void handleDelAlmMsg(kbd_idlfile::SAlmCltDelAlm &objDelAlm); - - virtual void handleReleaseAlmMsg(kbd_idlfile::SAlmCltReleaseAlm &objDelAlm); - -signals: - //< 启停定时器 - void sigTimerShot(const bool bStop); - - //< 定时更新,通知model刷新界面 - void sigUpdateAlarmView(); - - //< 通知所有告警插件禁用/使能告警操作 - void sigAlarmOperateEnable(const bool &bEnable); - - //< 通知model重新拉取告警消息 - void sigMsgRefresh(); - - //< 通知model告警消息到达 - //void sigMsgArrived(); - - //< 通知model告警消息确认 - void sigMsgConfirm(); - - //< 通知model告警消息删除 - void sigMsgRemove(); - - //< 告警数量或状态改变时触发。 - void sigAlarmStateChanged(int total, int unConfirm); - -public slots: - void destory(bool *pExit); - - void slotTimerShot(const bool start); - - void slotSwitchFaultRecallState(bool bFaultRecallState); - -private: - CAlarmDataCollect(); - - int queryPriorityOrder(int &id); - void loadAlmAct();//加载告警动作 - void loadAlmLel();//加载告警等级 - -private slots: - void slotAlarmStateChanged(); - -private: - int m_referenceCount; - bool m_bFaultRecallState; //是否处于事故追忆 - QMutex * m_rtdbMutex; - QTimer * m_pAlternateTimer; - kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; - kbd_dbms::CRdbAccess * m_rtdbAlmLvlDefTab; // 告警等级定义表 - kbd_dbms::CRdbAccess * m_rtdbAlmActDefTab; // 告警动作定义表 - bool m_bIsNeedUpdate; //< 是否消息确认(每秒更新) - bool m_bIsNeedRemove; //< 是否需要删除(每秒更新) - bool m_bIsNeedRelease; //< 是否需要释放(每秒更新)- - static CAlarmDataCollect * m_pInstance; - - QMap m_levelMap; //<告警等级,告警动作> - QMap m_actMap; //<告警动作宏,告警动作id> -}; - -#endif // CALARMDATACOLLECT_H +#ifndef CALARMDATACOLLECT_H +#define CALARMDATACOLLECT_H + +#include +#include +#include +#include +#include +#include "AlarmMessage.pb.h" +#include "CAlarmMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" + +class CAlarmDataCollect : public QObject, public kbd_service::CAlmApiForAlmClt +{ + Q_OBJECT +public: + static CAlarmDataCollect *instance(); + + virtual ~CAlarmDataCollect(); + + void initialize(); + + void refrence(); + + void release(); + + int getRefrenceCount(); + + bool isFaultRecallState(); + + virtual bool requestCfmAlm(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm); + + virtual bool requestDelAlm(kbd_idlfile::SAlmCltDelAlm &objDelAlm); + + virtual void handleAllAlmMsg(int domainId, kbd_idlfile::SAlmCltAddAlm &objAllAlm); + + virtual void handleAddAlmMsg(kbd_idlfile::SAlmCltAddAlm &objAddAlm); + + virtual void handleCfmAlmMsg(kbd_idlfile::SAlmCltCfmAlm &objCfmAlm); + + virtual void handleDelAlmMsg(kbd_idlfile::SAlmCltDelAlm &objDelAlm); + + virtual void handleReleaseAlmMsg(kbd_idlfile::SAlmCltReleaseAlm &objDelAlm); + +signals: + //< 启停定时器 + void sigTimerShot(const bool bStop); + + //< 定时更新,通知model刷新界面 + void sigUpdateAlarmView(); + + //< 通知所有告警插件禁用/使能告警操作 + void sigAlarmOperateEnable(const bool &bEnable); + + //< 通知model重新拉取告警消息 + void sigMsgRefresh(); + + //< 通知model告警消息到达 + //void sigMsgArrived(); + + //< 通知model告警消息确认 + void sigMsgConfirm(); + + //< 通知model告警消息删除 + void sigMsgRemove(); + + //< 告警数量或状态改变时触发。 + void sigAlarmStateChanged(int total, int unConfirm); + +public slots: + void destory(bool *pExit); + + void slotTimerShot(const bool start); + + void slotSwitchFaultRecallState(bool bFaultRecallState); + +private: + CAlarmDataCollect(); + + int queryPriorityOrder(int &id); + void loadAlmAct();//加载告警动作 + void loadAlmLel();//加载告警等级 + +private slots: + void slotAlarmStateChanged(); + +private: + int m_referenceCount; + bool m_bFaultRecallState; //是否处于事故追忆 + QMutex * m_rtdbMutex; + QTimer * m_pAlternateTimer; + kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + kbd_dbms::CRdbAccess * m_rtdbAlmLvlDefTab; // 告警等级定义表 + kbd_dbms::CRdbAccess * m_rtdbAlmActDefTab; // 告警动作定义表 + bool m_bIsNeedUpdate; //< 是否消息确认(每秒更新) + bool m_bIsNeedRemove; //< 是否需要删除(每秒更新) + bool m_bIsNeedRelease; //< 是否需要释放(每秒更新)- + static CAlarmDataCollect * m_pInstance; + + QMap m_levelMap; //<告警等级,告警动作> + QMap m_actMap; //<告警动作宏,告警动作id> +}; + +#endif // CALARMDATACOLLECT_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDelegate.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDelegate.cpp index a1b71048..df19ef5c 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDelegate.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDelegate.cpp @@ -1,210 +1,210 @@ -#include -#include -#include -#include "CAlarmDelegate.h" -#include "CAlarmMsgInfo.h" -#include "CAlarmItemModel.h" -#include "pub_utility_api/FileUtil.h" -#include -#include -#include "pub_logger_api/logger.h" - -CAlarmDelegate::CAlarmDelegate(CAlarmItemModel * model, QObject *parent) - : QStyledItemDelegate(parent), - m_pModel(model), - m_isFlash(false) -{ - loadColorConfig(); -} - -void CAlarmDelegate::loadColorConfig() -{ - QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); - QDomDocument document; - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly)) - { - LOGERROR("loadColorConfig Failed!"); - return; - } - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - bool isFlash = false; - QDomElement element = document.documentElement(); - QDomNode node = element.firstChild(); - while(!node.isNull()) - { - QDomElement attr = node.toElement(); - if(!attr.isNull()) - { - if(QString("Flash") == attr.tagName()) - { - isFlash = (bool)attr.attribute("alternate").toInt(); - } - else if(QString("Level") == attr.tagName()) - { - int priority = attr.attribute("priority").toInt(); - m_backgroundMap[priority] = QColor(attr.attribute("background_color")); - m_alternatingMap[priority] = QColor(attr.attribute("alternating_color")); - m_confirmMap[priority] = QColor(attr.attribute("confirm_color")); - - m_activeTextMap[priority] = QColor(attr.attribute("active_text_color")); - m_confirmTextMap[priority] = QColor(attr.attribute("confirm_text_color")); - } - else if(QString("Select") == attr.tagName()) - { - m_selectBackgroundColor = QColor(attr.attribute("background_color")); - m_selectTextColor = QColor(attr.attribute("text_color")); - } - else if(QString("NoItem") == attr.tagName()) - { - m_emptyBackgroundColor = QColor(attr.attribute("background_color")); - m_emptyTipColor = QColor(attr.attribute("tips_color")); - m_emptyTip = tr("当前无告警!"); - } - } - node = node.nextSibling(); - } - - if(E_Alarm_Pop == m_pModel->getAlarmMode()) - { - m_isFlash = false; - } - else if(E_Alarm_Dock == m_pModel->getAlarmMode()) - { - m_isFlash = true; - } - else if(E_Alarm_Window == m_pModel->getAlarmMode()) - { - m_isFlash = isFlash; - } -} - -void CAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - if(!index.isValid()) - { - return; - } - QColor fillColor; - QColor penColor; - bool select = option.state & QStyle::State_Selected; - //< Dock Empty - if(E_Alarm_Dock == m_pModel->getAlarmMode() && 0 == m_pModel->getShowAlarmCount()) - { - painter->fillRect(option.rect, m_emptyBackgroundColor); - if(CAlarmItemModel::CONTENT == index.column() && parent()) - { - QRect rt = option.rect; - QWidget * parentWidget = dynamic_cast(parent()); - if(parentWidget) - { - rt.setLeft(0); - rt.setWidth(parentWidget->width()); - painter->save(); - painter->setPen(m_emptyTipColor); - painter->drawText(rt, Qt::AlignHCenter | Qt::AlignVCenter, m_emptyTip); - painter->restore(); - } - } - return; - } - - //< Common - AlarmMsgPtr info = m_pModel->getAlarmInfo(index); - - - if(info != Q_NULLPTR) - { - painter->save(); - - if(E_ALS_ALARM == info->logic_state || E_ALS_RETURN == info->logic_state) //< 未确认 - { - if(select) - { - fillColor = m_selectBackgroundColor; - penColor = m_selectTextColor; - } - else - { - if(m_isFlash && m_pModel->alternate()) - { - penColor = m_alternatingMap.value(info->priorityOrder, Qt::white); - } - else - { - penColor = m_activeTextMap[info->priorityOrder]; - } - fillColor = m_backgroundMap[info->priorityOrder]; - } - } - else - { - if(select) - { - fillColor = m_selectBackgroundColor; - } - else - { - fillColor = m_confirmMap.value(info->priorityOrder, Qt::white); - } - penColor = m_confirmTextMap.value(info->priorityOrder, Qt::red); - } - painter->setPen(penColor); - painter->fillRect(option.rect, fillColor); - if( VIDEO_COLUMN == index.column() && info->m_needVideoAlm) - { - painter->save(); - QStyleOptionButton button; - button.state |= QStyle::State_Enabled; - button.rect = option.rect; - - button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); - button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); - button.icon = QIcon(kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video.png").c_str()); - - QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); - painter->restore(); - } - painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); - painter->restore(); - } -} - -bool CAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - if(!index.isValid()) - { - return false; - } - if(index.column() != VIDEO_COLUMN) - { - return false; - } - AlarmMsgPtr info = m_pModel->getAlarmInfo(index); - QMouseEvent *mouseEvent = static_cast(event); - if(info &&info->m_needVideoAlm) - { - if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) - { - QStyleOptionButton button; - button.rect = option.rect; - button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); - QRect rect = button.rect; - QString pointTag = info->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - if(rect.contains(mouseEvent->pos())) - { - QString pointTag = info->key_id_tag; - pointTag.remove(pointTag.length()-6,6); - emit openVideo(info->domain_id,info->app_id,pointTag,info->time_stamp-VIDEO_TIME,info->time_stamp+VIDEO_TIME); - } - } - } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} +#include +#include +#include +#include "CAlarmDelegate.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "pub_utility_api/FileUtil.h" +#include +#include +#include "pub_logger_api/logger.h" + +CAlarmDelegate::CAlarmDelegate(CAlarmItemModel * model, QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(model), + m_isFlash(false) +{ + loadColorConfig(); +} + +void CAlarmDelegate::loadColorConfig() +{ + QString filePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); + QDomDocument document; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + { + LOGERROR("loadColorConfig Failed!"); + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + bool isFlash = false; + QDomElement element = document.documentElement(); + QDomNode node = element.firstChild(); + while(!node.isNull()) + { + QDomElement attr = node.toElement(); + if(!attr.isNull()) + { + if(QString("Flash") == attr.tagName()) + { + isFlash = (bool)attr.attribute("alternate").toInt(); + } + else if(QString("Level") == attr.tagName()) + { + int priority = attr.attribute("priority").toInt(); + m_backgroundMap[priority] = QColor(attr.attribute("background_color")); + m_alternatingMap[priority] = QColor(attr.attribute("alternating_color")); + m_confirmMap[priority] = QColor(attr.attribute("confirm_color")); + + m_activeTextMap[priority] = QColor(attr.attribute("active_text_color")); + m_confirmTextMap[priority] = QColor(attr.attribute("confirm_text_color")); + } + else if(QString("Select") == attr.tagName()) + { + m_selectBackgroundColor = QColor(attr.attribute("background_color")); + m_selectTextColor = QColor(attr.attribute("text_color")); + } + else if(QString("NoItem") == attr.tagName()) + { + m_emptyBackgroundColor = QColor(attr.attribute("background_color")); + m_emptyTipColor = QColor(attr.attribute("tips_color")); + m_emptyTip = tr("当前无告警!"); + } + } + node = node.nextSibling(); + } + + if(E_Alarm_Pop == m_pModel->getAlarmMode()) + { + m_isFlash = false; + } + else if(E_Alarm_Dock == m_pModel->getAlarmMode()) + { + m_isFlash = true; + } + else if(E_Alarm_Window == m_pModel->getAlarmMode()) + { + m_isFlash = isFlash; + } +} + +void CAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + QColor fillColor; + QColor penColor; + bool select = option.state & QStyle::State_Selected; + //< Dock Empty + if(E_Alarm_Dock == m_pModel->getAlarmMode() && 0 == m_pModel->getShowAlarmCount()) + { + painter->fillRect(option.rect, m_emptyBackgroundColor); + if(CAlarmItemModel::CONTENT == index.column() && parent()) + { + QRect rt = option.rect; + QWidget * parentWidget = dynamic_cast(parent()); + if(parentWidget) + { + rt.setLeft(0); + rt.setWidth(parentWidget->width()); + painter->save(); + painter->setPen(m_emptyTipColor); + painter->drawText(rt, Qt::AlignHCenter | Qt::AlignVCenter, m_emptyTip); + painter->restore(); + } + } + return; + } + + //< Common + AlarmMsgPtr info = m_pModel->getAlarmInfo(index); + + + if(info != Q_NULLPTR) + { + painter->save(); + + if(E_ALS_ALARM == info->logic_state || E_ALS_RETURN == info->logic_state) //< 未确认 + { + if(select) + { + fillColor = m_selectBackgroundColor; + penColor = m_selectTextColor; + } + else + { + if(m_isFlash && m_pModel->alternate()) + { + penColor = m_alternatingMap.value(info->priorityOrder, Qt::white); + } + else + { + penColor = m_activeTextMap[info->priorityOrder]; + } + fillColor = m_backgroundMap[info->priorityOrder]; + } + } + else + { + if(select) + { + fillColor = m_selectBackgroundColor; + } + else + { + fillColor = m_confirmMap.value(info->priorityOrder, Qt::white); + } + penColor = m_confirmTextMap.value(info->priorityOrder, Qt::red); + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + if( VIDEO_COLUMN == index.column() && info->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(kbd_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video.png").c_str()); + + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + } +} + +bool CAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(index.column() != VIDEO_COLUMN) + { + return false; + } + AlarmMsgPtr info = m_pModel->getAlarmInfo(index); + QMouseEvent *mouseEvent = static_cast(event); + if(info &&info->m_needVideoAlm) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + QString pointTag = info->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + if(rect.contains(mouseEvent->pos())) + { + QString pointTag = info->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(info->domain_id,info->app_id,pointTag,info->time_stamp-VIDEO_TIME,info->time_stamp+VIDEO_TIME); + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDelegate.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDelegate.h index 11d811b3..7427c474 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDelegate.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDelegate.h @@ -1,44 +1,44 @@ -#ifndef CALARMDELEGATE_H -#define CALARMDELEGATE_H - -#include -class CAlarmItemModel; - -class CAlarmDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CAlarmDelegate(CAlarmItemModel *model, QObject *parent = 0); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; - -signals: - void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); -private: - void loadColorConfig(); - -private: - CAlarmItemModel * m_pModel; - bool m_isFlash; - //< background color - QMap m_backgroundMap; - QMap m_alternatingMap; - QMap m_confirmMap; - - //< text color - QMap m_activeTextMap; - QMap m_confirmTextMap; - - //< select color - QColor m_selectBackgroundColor; - QColor m_selectTextColor; - - //< no item - QColor m_emptyBackgroundColor; - QColor m_emptyTipColor; - QString m_emptyTip; -}; - -#endif +#ifndef CALARMDELEGATE_H +#define CALARMDELEGATE_H + +#include +class CAlarmItemModel; + +class CAlarmDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CAlarmDelegate(CAlarmItemModel *model, QObject *parent = 0); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; + +signals: + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); +private: + void loadColorConfig(); + +private: + CAlarmItemModel * m_pModel; + bool m_isFlash; + //< background color + QMap m_backgroundMap; + QMap m_alternatingMap; + QMap m_confirmMap; + + //< text color + QMap m_activeTextMap; + QMap m_confirmTextMap; + + //< select color + QColor m_selectBackgroundColor; + QColor m_selectTextColor; + + //< no item + QColor m_emptyBackgroundColor; + QColor m_emptyTipColor; + QString m_emptyTip; +}; + +#endif diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeItem.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeItem.cpp index ab7fff6f..9aaa1f82 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeItem.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeItem.cpp @@ -1,89 +1,89 @@ -#include -#include "CAlarmDeviceTreeItem.h" -#include "pub_logger_api/logger.h" - -CAlarmDeviceTreeItem::CAlarmDeviceTreeItem(const QString &data, CAlarmDeviceTreeItem *parent) - : m_parentItem(parent), - m_tag(QString()) -{ - if(m_parentItem) - { - m_parentItem->m_childItems.append(this); - } - - m_data = data; - m_checkState = Qt::Checked; -} - -CAlarmDeviceTreeItem::~CAlarmDeviceTreeItem() -{ - qDeleteAll(m_childItems); - m_childItems.clear(); -} - -CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::child(int row) -{ - return m_childItems.value(row); -} - -CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::parentItem() -{ - return m_parentItem; -} - -int CAlarmDeviceTreeItem::row() const -{ - if (m_parentItem) - { - return m_parentItem->m_childItems.indexOf(const_cast(this)); - } - - return 0; -} - -int CAlarmDeviceTreeItem::childCount() const -{ - return m_childItems.count(); -} - -int CAlarmDeviceTreeItem::columnCount() const -{ - return 1; -} - -QVariant CAlarmDeviceTreeItem::data(Qt::ItemDataRole role) const -{ - if(Qt::DisplayRole == role) - { - return m_data; - } - else if(Qt::UserRole == role) - { - return m_tag; - } - else if(Qt::CheckStateRole == role) - { - return m_checkState; - } - return QVariant(); -} - -bool CAlarmDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) -{ - if(Qt::DisplayRole == role) - { - m_data = value.toString(); - return true; - } - else if(Qt::UserRole == role) - { - m_tag = value.toString(); - return true; - } - else if(Qt::CheckStateRole == role) - { - m_checkState = (Qt::CheckState)value.toInt(); - return true; - } - return false; -} +#include +#include "CAlarmDeviceTreeItem.h" +#include "pub_logger_api/logger.h" + +CAlarmDeviceTreeItem::CAlarmDeviceTreeItem(const QString &data, CAlarmDeviceTreeItem *parent) + : m_parentItem(parent), + m_tag(QString()) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } + + m_data = data; + m_checkState = Qt::Checked; +} + +CAlarmDeviceTreeItem::~CAlarmDeviceTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::child(int row) +{ + return m_childItems.value(row); +} + +CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::parentItem() +{ + return m_parentItem; +} + +int CAlarmDeviceTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CAlarmDeviceTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CAlarmDeviceTreeItem::columnCount() const +{ + return 1; +} + +QVariant CAlarmDeviceTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::UserRole == role) + { + return m_tag; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } + return QVariant(); +} + +bool CAlarmDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::UserRole == role) + { + m_tag = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + return false; +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeItem.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeItem.h index 1cbfad0c..e97e5406 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeItem.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeItem.h @@ -1,83 +1,83 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CALARMDEVICETREEITEM_H -#define CALARMDEVICETREEITEM_H - -#include -#include - -class CAlarmDeviceTreeItem -{ -public: - explicit CAlarmDeviceTreeItem(const QString &data = QString(), CAlarmDeviceTreeItem *parentItem = Q_NULLPTR); - ~CAlarmDeviceTreeItem(); - - CAlarmDeviceTreeItem *child(int row); - CAlarmDeviceTreeItem *parentItem(); - - int row() const; - - int childCount() const; - int columnCount() const; - - QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; - bool setData(const QVariant &value, Qt::ItemDataRole role); - -private: - QString m_data; - QString m_tag; - Qt::CheckState m_checkState; - - QList m_childItems; - CAlarmDeviceTreeItem *m_parentItem; -}; - -#endif // CALARMDEVICETREEITEM_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CALARMDEVICETREEITEM_H +#define CALARMDEVICETREEITEM_H + +#include +#include + +class CAlarmDeviceTreeItem +{ +public: + explicit CAlarmDeviceTreeItem(const QString &data = QString(), CAlarmDeviceTreeItem *parentItem = Q_NULLPTR); + ~CAlarmDeviceTreeItem(); + + CAlarmDeviceTreeItem *child(int row); + CAlarmDeviceTreeItem *parentItem(); + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + +private: + QString m_data; + QString m_tag; + Qt::CheckState m_checkState; + + QList m_childItems; + CAlarmDeviceTreeItem *m_parentItem; +}; + +#endif // CALARMDEVICETREEITEM_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeModel.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeModel.cpp index d89e51ac..294d8d52 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeModel.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeModel.cpp @@ -1,232 +1,232 @@ -#include "CAlarmDeviceTreeItem.h" -#include "CAlarmDeviceTreeModel.h" -#include "CAlarmMsgManage.h" -#include -#include "pub_logger_api/logger.h" - -CAlarmDeviceTreeModel::CAlarmDeviceTreeModel(QObject *parent) - : QAbstractItemModel(parent) -{ - rootItem = new CAlarmDeviceTreeItem(); -} - -CAlarmDeviceTreeModel::~CAlarmDeviceTreeModel() -{ - m_devTagIndex.clear(); - m_devNameIndex.clear(); - delete rootItem; -} - -void CAlarmDeviceTreeModel::setupModelData(const QMap< int, QVector< QPair< QString, QString > > > &locationInfos,QMap &locationMap) -{ - QMap< int, QVector< QPair< QString, QString > > >::const_iterator iter = locationInfos.constBegin(); - - while (iter != locationInfos.constEnd()) - { - CAlarmDeviceTreeItem * location = new CAlarmDeviceTreeItem(locationMap.value(iter.key()), rootItem); - QVector< QPair< QString, QString> > vec = iter.value(); - for(int nIndex(0); nIndex < vec.size(); ++nIndex) - { - CAlarmDeviceTreeItem * device = new CAlarmDeviceTreeItem(vec.at(nIndex).second, location); - device->setData(vec.at(nIndex).first, Qt::UserRole); - QModelIndex modelIndex = createIndex(nIndex , 0, device); - m_devTagIndex.insert(vec.at(nIndex).first, modelIndex); - m_devNameIndex.insert(locationMap.value(iter.key()) + "." + vec.at(nIndex).second, modelIndex); - } - iter++; - } -} - -const HashIndex &CAlarmDeviceTreeModel::indexTagList() const -{ - return m_devTagIndex; -} - -const HashIndex &CAlarmDeviceTreeModel::indexNameList() const -{ - return m_devNameIndex; -} - -QModelIndex CAlarmDeviceTreeModel::indexOfDeviceTag(const QString &tag) -{ - return m_devTagIndex.value(tag, QModelIndex()); -} - -QModelIndex CAlarmDeviceTreeModel::indexOfDeviceName(const QString &name) -{ - return m_devNameIndex.value(name, QModelIndex()); -} - -QVariant CAlarmDeviceTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(section) - Q_UNUSED(orientation) - Q_UNUSED(role) - return QVariant(); -} - -QModelIndex CAlarmDeviceTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!hasIndex(row, column, parent)) - { - return QModelIndex(); - } - - CAlarmDeviceTreeItem *parentItem; - - if (!parent.isValid()) - { - parentItem = rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - CAlarmDeviceTreeItem *childItem = parentItem->child(row); - if (childItem) - { - return createIndex(row, column, childItem); - } - else - { - return QModelIndex(); - } -} - -QModelIndex CAlarmDeviceTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - CAlarmDeviceTreeItem *childItem = static_cast(index.internalPointer()); - - CAlarmDeviceTreeItem *parentItem = childItem->parentItem(); - if (parentItem == rootItem) - { - return QModelIndex(); - } - - return createIndex(parentItem->row(), 0, parentItem); -} - -int CAlarmDeviceTreeModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - { - return 0; - } - - CAlarmDeviceTreeItem *parentItem; - if (!parent.isValid()) - { - parentItem = rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - return parentItem->childCount(); -} - -int CAlarmDeviceTreeModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return static_cast(parent.internalPointer())->columnCount(); - } - else - { - return rootItem->columnCount(); - } -} - - -QVariant CAlarmDeviceTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.column()) - { - return QVariant(); - } - - CAlarmDeviceTreeItem *item = static_cast(index.internalPointer()); - if (Qt::DisplayRole == role) - { - const QString &deviceGroup = item->data(Qt::UserRole).toString(); - if(deviceGroup.isEmpty()) - { - return item->data(Qt::DisplayRole).toString(); - } - return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(CAlarmMsgManage::instance()->deviceGroupAlarmStatistical(deviceGroup)); - } - else if(Qt::CheckStateRole == role && QModelIndex() != index.parent()) - { - return item->data(Qt::CheckStateRole); - } - - return QVariant(); -} - -bool CAlarmDeviceTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid() || index.column()) - { - return false; - } - if(Qt::CheckStateRole == role) - { - emit itemCheckStateChanged(static_cast(index.internalPointer())->data(Qt::UserRole).toString(), value.toBool()); - } - return static_cast(index.internalPointer())->setData(value, (Qt::ItemDataRole)role); -} - -Qt::ItemFlags CAlarmDeviceTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - if(!index.column()) - { - return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; - } - - return QAbstractItemModel::flags(index); -} - -void CAlarmDeviceTreeModel::setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state) -{ - if(!index.isValid()) - { - return; - } - CAlarmDeviceTreeItem * pItem = static_cast(index.internalPointer()); - if(pItem) - { - int nChildCount = pItem->childCount(); - for( int nIndex(0); nIndex < nChildCount; nIndex++) - { - pItem->child(nIndex)->setData(state, Qt::CheckStateRole); - emit itemCheckStateChanged(pItem->child(nIndex)->data(Qt::UserRole).toString(), state); - } - } -} - -void CAlarmDeviceTreeModel::setAllDeviceCheckState(const Qt::CheckState &state) -{ - HashIndex::const_iterator iter = m_devTagIndex.constBegin(); - while (iter != m_devTagIndex.constEnd()) - { - CAlarmDeviceTreeItem * pItem = static_cast(iter.value().internalPointer()); - if(pItem) - { - pItem->setData(state, Qt::CheckStateRole); - emit itemCheckStateChanged(pItem->data(Qt::UserRole).toString(), state); - } - ++iter; - } -} +#include "CAlarmDeviceTreeItem.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmMsgManage.h" +#include +#include "pub_logger_api/logger.h" + +CAlarmDeviceTreeModel::CAlarmDeviceTreeModel(QObject *parent) + : QAbstractItemModel(parent) +{ + rootItem = new CAlarmDeviceTreeItem(); +} + +CAlarmDeviceTreeModel::~CAlarmDeviceTreeModel() +{ + m_devTagIndex.clear(); + m_devNameIndex.clear(); + delete rootItem; +} + +void CAlarmDeviceTreeModel::setupModelData(const QMap< int, QVector< QPair< QString, QString > > > &locationInfos,QMap &locationMap) +{ + QMap< int, QVector< QPair< QString, QString > > >::const_iterator iter = locationInfos.constBegin(); + + while (iter != locationInfos.constEnd()) + { + CAlarmDeviceTreeItem * location = new CAlarmDeviceTreeItem(locationMap.value(iter.key()), rootItem); + QVector< QPair< QString, QString> > vec = iter.value(); + for(int nIndex(0); nIndex < vec.size(); ++nIndex) + { + CAlarmDeviceTreeItem * device = new CAlarmDeviceTreeItem(vec.at(nIndex).second, location); + device->setData(vec.at(nIndex).first, Qt::UserRole); + QModelIndex modelIndex = createIndex(nIndex , 0, device); + m_devTagIndex.insert(vec.at(nIndex).first, modelIndex); + m_devNameIndex.insert(locationMap.value(iter.key()) + "." + vec.at(nIndex).second, modelIndex); + } + iter++; + } +} + +const HashIndex &CAlarmDeviceTreeModel::indexTagList() const +{ + return m_devTagIndex; +} + +const HashIndex &CAlarmDeviceTreeModel::indexNameList() const +{ + return m_devNameIndex; +} + +QModelIndex CAlarmDeviceTreeModel::indexOfDeviceTag(const QString &tag) +{ + return m_devTagIndex.value(tag, QModelIndex()); +} + +QModelIndex CAlarmDeviceTreeModel::indexOfDeviceName(const QString &name) +{ + return m_devNameIndex.value(name, QModelIndex()); +} + +QVariant CAlarmDeviceTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CAlarmDeviceTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + CAlarmDeviceTreeItem *parentItem; + + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + CAlarmDeviceTreeItem *childItem = parentItem->child(row); + if (childItem) + { + return createIndex(row, column, childItem); + } + else + { + return QModelIndex(); + } +} + +QModelIndex CAlarmDeviceTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CAlarmDeviceTreeItem *childItem = static_cast(index.internalPointer()); + + CAlarmDeviceTreeItem *parentItem = childItem->parentItem(); + if (parentItem == rootItem) + { + return QModelIndex(); + } + + return createIndex(parentItem->row(), 0, parentItem); +} + +int CAlarmDeviceTreeModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + { + return 0; + } + + CAlarmDeviceTreeItem *parentItem; + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +int CAlarmDeviceTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return static_cast(parent.internalPointer())->columnCount(); + } + else + { + return rootItem->columnCount(); + } +} + + +QVariant CAlarmDeviceTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.column()) + { + return QVariant(); + } + + CAlarmDeviceTreeItem *item = static_cast(index.internalPointer()); + if (Qt::DisplayRole == role) + { + const QString &deviceGroup = item->data(Qt::UserRole).toString(); + if(deviceGroup.isEmpty()) + { + return item->data(Qt::DisplayRole).toString(); + } + return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(CAlarmMsgManage::instance()->deviceGroupAlarmStatistical(deviceGroup)); + } + else if(Qt::CheckStateRole == role && QModelIndex() != index.parent()) + { + return item->data(Qt::CheckStateRole); + } + + return QVariant(); +} + +bool CAlarmDeviceTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.column()) + { + return false; + } + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(static_cast(index.internalPointer())->data(Qt::UserRole).toString(), value.toBool()); + } + return static_cast(index.internalPointer())->setData(value, (Qt::ItemDataRole)role); +} + +Qt::ItemFlags CAlarmDeviceTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + if(!index.column()) + { + return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; + } + + return QAbstractItemModel::flags(index); +} + +void CAlarmDeviceTreeModel::setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + CAlarmDeviceTreeItem * pItem = static_cast(index.internalPointer()); + if(pItem) + { + int nChildCount = pItem->childCount(); + for( int nIndex(0); nIndex < nChildCount; nIndex++) + { + pItem->child(nIndex)->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->child(nIndex)->data(Qt::UserRole).toString(), state); + } + } +} + +void CAlarmDeviceTreeModel::setAllDeviceCheckState(const Qt::CheckState &state) +{ + HashIndex::const_iterator iter = m_devTagIndex.constBegin(); + while (iter != m_devTagIndex.constEnd()) + { + CAlarmDeviceTreeItem * pItem = static_cast(iter.value().internalPointer()); + if(pItem) + { + pItem->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::UserRole).toString(), state); + } + ++iter; + } +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeModel.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeModel.h index 49136c1d..df258f0e 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeModel.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeModel.h @@ -1,111 +1,111 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CALARMDEVICETREEMODEL_H -#define CALARMDEVICETREEMODEL_H - -#include -#include -#include -#include - - -typedef QHash< QString, QModelIndex > HashIndex; //< Device - -class CAlarmDeviceTreeItem; - -class CAlarmDeviceTreeModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - explicit CAlarmDeviceTreeModel(QObject *parent = 0); - ~CAlarmDeviceTreeModel(); - - //< @param locationInfos [ locationDesc[ devTag, devDesc ] ] - void setupModelData(const QMap > > &locationInfos, QMap &locationMap); - - const HashIndex &indexTagList() const; - - const HashIndex &indexNameList() const; - - QModelIndex indexOfDeviceTag(const QString &tag); - - QModelIndex indexOfDeviceName(const QString &name); - - QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - void setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state); - - void setAllDeviceCheckState(const Qt::CheckState &state); - -signals: - void itemCheckStateChanged(const QString &device, const bool &checked); - -private: - CAlarmDeviceTreeItem *rootItem; - HashIndex m_devTagIndex; - HashIndex m_devNameIndex; - HashIndex m_devGroupIndex; -}; - -#endif // CALARMDEVICETREEMODEL_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CALARMDEVICETREEMODEL_H +#define CALARMDEVICETREEMODEL_H + +#include +#include +#include +#include + + +typedef QHash< QString, QModelIndex > HashIndex; //< Device + +class CAlarmDeviceTreeItem; + +class CAlarmDeviceTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CAlarmDeviceTreeModel(QObject *parent = 0); + ~CAlarmDeviceTreeModel(); + + //< @param locationInfos [ locationDesc[ devTag, devDesc ] ] + void setupModelData(const QMap > > &locationInfos, QMap &locationMap); + + const HashIndex &indexTagList() const; + + const HashIndex &indexNameList() const; + + QModelIndex indexOfDeviceTag(const QString &tag); + + QModelIndex indexOfDeviceName(const QString &name); + + QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void setAllDeviceCheckState(const Qt::CheckState &state); + +signals: + void itemCheckStateChanged(const QString &device, const bool &checked); + +private: + CAlarmDeviceTreeItem *rootItem; + HashIndex m_devTagIndex; + HashIndex m_devNameIndex; + HashIndex m_devGroupIndex; +}; + +#endif // CALARMDEVICETREEMODEL_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeView.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeView.cpp index 997cad22..abd57560 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeView.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeView.cpp @@ -1,33 +1,33 @@ -#include "CAlarmDeviceTreeView.h" -#include "CAlarmDeviceTreeModel.h" -#include "CAlarmDeviceTreeItem.h" -#include -#include - -CAlarmDeviceTreeView::CAlarmDeviceTreeView(QWidget *parent) - : QTreeView(parent) -{ - -} - -//void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) -//{ -// CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); -// if(Q_NULLPTR != pModel) -// { -// QMenu menu; -// CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); -// if (Q_NULLPTR == pItem) -// { -// menu.addAction(tr("全选"), [=](){ pModel->setAllDeviceCheckState(Qt::Checked); }); -// menu.addAction(tr("清空"), [=](){ pModel->setAllDeviceCheckState(Qt::Unchecked); }); -// } -// else if (Q_NULLPTR != pItem && pItem->childCount() > 0) -// { -// menu.addAction(tr("选择"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Checked); }); -// menu.addAction(tr("清除"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Unchecked); }); -// } -// menu.exec(event->globalPos()); -// } -// return; -//} +#include "CAlarmDeviceTreeView.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmDeviceTreeItem.h" +#include +#include + +CAlarmDeviceTreeView::CAlarmDeviceTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} + +//void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) +//{ +// CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); +// if(Q_NULLPTR != pModel) +// { +// QMenu menu; +// CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); +// if (Q_NULLPTR == pItem) +// { +// menu.addAction(tr("全选"), [=](){ pModel->setAllDeviceCheckState(Qt::Checked); }); +// menu.addAction(tr("清空"), [=](){ pModel->setAllDeviceCheckState(Qt::Unchecked); }); +// } +// else if (Q_NULLPTR != pItem && pItem->childCount() > 0) +// { +// menu.addAction(tr("选择"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Checked); }); +// menu.addAction(tr("清除"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Unchecked); }); +// } +// menu.exec(event->globalPos()); +// } +// return; +//} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeView.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeView.h index b2c21691..b0d5d21e 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeView.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmDeviceTreeView.h @@ -1,16 +1,16 @@ -#ifndef CALARMDEVICETREEVIEW_H -#define CALARMDEVICETREEVIEW_H - -#include - -class CAlarmDeviceTreeView : public QTreeView -{ - Q_OBJECT -public: - CAlarmDeviceTreeView(QWidget *parent = Q_NULLPTR); - -protected: -// void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // CALARMDEVICETREEVIEW_H +#ifndef CALARMDEVICETREEVIEW_H +#define CALARMDEVICETREEVIEW_H + +#include + +class CAlarmDeviceTreeView : public QTreeView +{ + Q_OBJECT +public: + CAlarmDeviceTreeView(QWidget *parent = Q_NULLPTR); + +protected: +// void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // CALARMDEVICETREEVIEW_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.cpp index e5a3a929..865ba207 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.cpp @@ -1,606 +1,606 @@ -#include "CAlarmFilterDialog.h" -#include "ui_CAlarmFilterDialog.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" -#include -#include -#include -#include -#include "pub_utility_api/FileStyle.h" - -CAlarmFilterDialog::CAlarmFilterDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CAlarmFilterDialog), - m_rtdbAccess(Q_NULLPTR) -{ - ui->setupUi(this); - setObjectName("alarm_dialog"); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - ui->subSystem->setView(new QListView()); - ui->deviceType->setView(new QListView()); - //setStyleSheet("background-image:url(:/resource/back.png);"); -} - -CAlarmFilterDialog::~CAlarmFilterDialog() -{ - if(m_rtdbAccess) - { - delete m_rtdbAccess; - } - m_rtdbAccess = Q_NULLPTR; - delete ui; -} - -void CAlarmFilterDialog::initialize() -{ - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - ui->level->setSelectionMode(QAbstractItemView::MultiSelection); - ui->location->setSelectionMode(QAbstractItemView::MultiSelection); - ui->region->setSelectionMode(QAbstractItemView::MultiSelection); - ui->type->setSelectionMode(QAbstractItemView::MultiSelection); - - foreach (QString value, m_priorityMap) - { - ui->level->addItem(value); - } - - foreach (QString value, m_locationMap) - { - ui->location->addItem(value); - } - - foreach (QString value, m_regionMap) - { - ui->region->addItem(value); - } - - foreach (QString value, m_alarmTypeMap) - { - ui->type->addItem(value); - } - - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - std::vector vecSubsystemInfo; - spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); - foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) - { - if(info.nId <= CN_AppId_COMAPP) - { - continue; - } - ui->subSystem->addItem(QString::fromStdString(info.strDesc)); - } - } - - ui->subSystem->setCurrentIndex(-1); - - connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); - connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); - connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); - connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); - connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); - connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); - connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); - connect(ui->location, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLocationState())); - connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); - connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); - connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); - connect(ui->checkStatus, SIGNAL(pressed()), this, SLOT(slot_checkTypePressed())); - connect(ui->checkStatus, SIGNAL(stateChanged(int)), this, SLOT(slot_typeSelectChange(int))); - connect(ui->type, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckTypeState())); - connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); - if(ui->subSystem->count() > 0) - { - ui->subSystem->setCurrentIndex(0); - } -} - -void CAlarmFilterDialog::setPriorityDescription(QMap priorityMap) -{ - m_priorityMap = priorityMap; -} - -void CAlarmFilterDialog::setLocationDescription(QMap locationMap) -{ - m_locationMap = locationMap; -} - -void CAlarmFilterDialog::setRegionDescription(QMap regionMap) -{ - m_regionMap = regionMap; -} - -//void CAlarmFilterDialog::setAlarmStatusDescription(QMap statusMap) -//{ -// m_alarmStatusMap = statusMap; -//} - -void CAlarmFilterDialog::setAlarmTypeDescription(QMap typeMap) -{ - m_alarmTypeMap = typeMap; -} - -void CAlarmFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) -{ - ui->levelFilter->setChecked(isLevelFilterEnable); -} - -void CAlarmFilterDialog::setLevelFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->level->count(); nIndex++) - { - int nLevelID = m_priorityMap.key(ui->level->item(nIndex)->text()); - if(filter.contains(nLevelID)) - { - ui->level->item(nIndex)->setSelected(true); - } - else - { - ui->level->item(nIndex)->setSelected(false); - } - } -} - -void CAlarmFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) -{ - ui->locationFilter->setChecked(isLocationFilterEnable); -} - -void CAlarmFilterDialog::setLocationFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->location->count(); nIndex++) - { - int nLocationID = m_locationMap.key(ui->location->item(nIndex)->text()); - if(filter.contains(nLocationID)) - { - ui->location->item(nIndex)->setSelected(true); - } - else - { - ui->location->item(nIndex)->setSelected(false); - } - } -} - -void CAlarmFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) -{ - ui->regionFilter->setChecked(isRegionFilterEnable); -} - -void CAlarmFilterDialog::setRegionFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->region->count(); nIndex++) - { - int nRegionID = m_regionMap.key(ui->region->item(nIndex)->text()); - if(filter.contains(nRegionID)) - { - ui->region->item(nIndex)->setSelected(true); - } - else - { - ui->region->item(nIndex)->setSelected(false); - } - } -} - -void CAlarmFilterDialog::setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable) -{ - ui->alarmTypeFilter->setChecked(isAlarmTypeEnable); -} - -void CAlarmFilterDialog::setAlarmTypeFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->type->count(); nIndex++) - { - int nAlarmTypeID = m_alarmTypeMap.key(ui->type->item(nIndex)->text()); - if(filter.contains(nAlarmTypeID)) - { - ui->type->item(nIndex)->setSelected(true); - } - else - { - ui->type->item(nIndex)->setSelected(false); - } - } -} - -void CAlarmFilterDialog::setDeviceFilterEnable(const bool &filter) -{ - ui->deviceFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setSubSystem(const QString &subSystem) -{ - if(ui->deviceFilterEnable->isChecked()) - { - ui->subSystem->setCurrentText(subSystem); - } -} - -void CAlarmFilterDialog::setDeviceType(const QString &deviceType) -{ - if(ui->deviceFilterEnable->isChecked()) - { - ui->deviceType->setCurrentText(deviceType); - } -} - -void CAlarmFilterDialog::setTimeFilterEnable(const bool &filter) -{ - ui->timeFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setStartTimeFilter(const QDateTime &filter) -{ - if(ui->timeFilterEnable->isChecked()) - { - ui->startTime->setDateTime(filter); - } - else - { - ui->startTime->setDateTime(QDateTime::currentDateTime()); - } -} - -void CAlarmFilterDialog::setEndTimeFilter(const QDateTime &filter) -{ - if(ui->timeFilterEnable->isChecked()) - { - ui->endTime->setDateTime(filter); - } - else - { - ui->endTime->setDateTime(QDateTime::currentDateTime()); - } -} - -void CAlarmFilterDialog::setStateFilterEnable(const bool &filter) -{ - ui->stateFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setStateFilter(const bool &filter) -{ - if(filter) - { - ui->confirm->setChecked(true); - } - else - { - ui->unConfirm->setChecked(true); - } -} - -void CAlarmFilterDialog::setkeyWordFilterEnable(const bool &filter) -{ - ui->keywordFilterEnable->setChecked(filter); -} - -void CAlarmFilterDialog::setkeyWordFilteContent(const QString &content) -{ - if(ui->keywordFilterEnable->isChecked()) - { - ui->keyWord->setText(content); - } -} - -void CAlarmFilterDialog::slot_updateFilter() -{ - bool isLevelFilter = ui->levelFilter->isChecked(); - QList listLevel; - foreach (QListWidgetItem *item, ui->level->selectedItems()) - { - listLevel << m_priorityMap.key(item->text()); - } - - bool isLocationFilter = ui->locationFilter->isChecked(); - QList listLocation; - foreach (QListWidgetItem *item, ui->location->selectedItems()) - { - listLocation << m_locationMap.key(item->text()); - } - - bool isRegionFilter = ui->regionFilter->isChecked(); - QList listRegion; - foreach (QListWidgetItem *item, ui->region->selectedItems()) - { - listRegion << m_regionMap.key(item->text()); - } - - bool isAlarmTypeFilter = ui->alarmTypeFilter->isChecked(); - QList listAlarmType; - foreach (QListWidgetItem *item, ui->type->selectedItems()) - { - listAlarmType << m_alarmTypeMap.key(item->text()); - } - - bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); - QString subSystem = ui->subSystem->currentText(); - QString deviceType = ui->deviceType->currentText(); - - bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); - QString strKeyWord =ui->keyWord->text(); - - bool isTimeFilter = ui->timeFilterEnable->isChecked(); - QDateTime startTime = QDateTime(); - QDateTime endTime = QDateTime(); - if(isTimeFilter) - { - startTime = ui->startTime->dateTime(); - endTime = ui->endTime->dateTime(); - } - - bool isConfirmFilter = ui->stateFilterEnable->isChecked(); - bool confirm = ui->confirm->isChecked(); - - emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, - isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime, isConfirmFilter, confirm); - accept(); -} - -//Level -void CAlarmFilterDialog::slot_checkLevelPressed() -{ - if( Qt::Unchecked == ui->checkLevel->checkState()) - { - ui->checkLevel->setTristate(false); - } -} - -void CAlarmFilterDialog::slot_levelSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->level->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->level->selectAll(); - } -} - -void CAlarmFilterDialog::slot_updateCheckLevelState() -{ - if( ui->level->count() == ui->level->selectedItems().count() ) - { - if( Qt::Checked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->level->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Location -void CAlarmFilterDialog::slot_checkLocationPressed() -{ - if( Qt::Unchecked == ui->checkLocation->checkState()) - { - ui->checkLocation->setTristate(false); - } -} - -void CAlarmFilterDialog::slot_locationSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->location->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->location->selectAll(); - } -} - -void CAlarmFilterDialog::slot_updateCheckLocationState() -{ - if( ui->location->count() == ui->location->selectedItems().count() ) - { - if( Qt::Checked != ui->checkLocation->checkState() ) - { - ui->checkLocation->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->location->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkLocation->checkState() ) - { - ui->checkLocation->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkLocation->checkState() ) - { - ui->checkLocation->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Region -void CAlarmFilterDialog::slot_checkRegionPressed() -{ - if( Qt::Unchecked == ui->checkRegion->checkState()) - { - ui->checkRegion->setTristate(false); - } -} - -void CAlarmFilterDialog::slot_regionSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->region->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->region->selectAll(); - } -} - -void CAlarmFilterDialog::slot_updateCheckRegionState() -{ - if( ui->region->count() == ui->region->selectedItems().count() ) - { - if( Qt::Checked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->region->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Type -void CAlarmFilterDialog::slot_checkTypePressed() -{ - if( Qt::Unchecked == ui->checkStatus->checkState()) - { - ui->checkStatus->setTristate(false); - } -} - -void CAlarmFilterDialog::slot_typeSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->type->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->type->selectAll(); - } -} - -void CAlarmFilterDialog::slot_updateCheckTypeState() -{ - if( ui->type->count() == ui->type->selectedItems().count() ) - { - if( Qt::Checked != ui->checkStatus->checkState() ) - { - ui->checkStatus->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->type->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkStatus->checkState() ) - { - ui->checkStatus->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkStatus->checkState() ) - { - ui->checkStatus->setCheckState(Qt::PartiallyChecked); - } - } -} - -void CAlarmFilterDialog::slot_updateDevice(const QString &subSystem) -{ - int nSubSystemId = -1; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - std::vector vecSubsystemInfo; - spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); - foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) - { - if(subSystem.toStdString() == info.strDesc) - { - nSubSystemId = info.nId; - } - } - } - - ui->deviceType->clear(); - - QList values; - - if(nSubSystemId != -1) - { - kbd_dbms::CVarType subSystemId = nSubSystemId; - if(m_rtdbAccess->open("base", "dev_type_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CONDINFO condition; - condition.relationop = ATTRCOND_EQU; - memcpy(condition.name, "sub_system", strlen("sub_system")); - condition.conditionval = subSystemId; - std::vector columns; - columns.push_back("description"); - - kbd_dbms::CRdbQueryResult result; - if(m_rtdbAccess->select(condition, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, value); - values.append(value); - } - } - } - } - foreach (kbd_dbms::CVarType value, values) - { - ui->deviceType->addItem(value.c_str()); - } -} +#include "CAlarmFilterDialog.h" +#include "ui_CAlarmFilterDialog.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + +CAlarmFilterDialog::CAlarmFilterDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmFilterDialog), + m_rtdbAccess(Q_NULLPTR) +{ + ui->setupUi(this); + setObjectName("alarm_dialog"); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + ui->subSystem->setView(new QListView()); + ui->deviceType->setView(new QListView()); + //setStyleSheet("background-image:url(:/resource/back.png);"); +} + +CAlarmFilterDialog::~CAlarmFilterDialog() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + delete ui; +} + +void CAlarmFilterDialog::initialize() +{ + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + ui->level->setSelectionMode(QAbstractItemView::MultiSelection); + ui->location->setSelectionMode(QAbstractItemView::MultiSelection); + ui->region->setSelectionMode(QAbstractItemView::MultiSelection); + ui->type->setSelectionMode(QAbstractItemView::MultiSelection); + + foreach (QString value, m_priorityMap) + { + ui->level->addItem(value); + } + + foreach (QString value, m_locationMap) + { + ui->location->addItem(value); + } + + foreach (QString value, m_regionMap) + { + ui->region->addItem(value); + } + + foreach (QString value, m_alarmTypeMap) + { + ui->type->addItem(value); + } + + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(info.nId <= CN_AppId_COMAPP) + { + continue; + } + ui->subSystem->addItem(QString::fromStdString(info.strDesc)); + } + } + + ui->subSystem->setCurrentIndex(-1); + + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); + connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); + connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); + connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); + connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); + connect(ui->location, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLocationState())); + connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); + connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); + connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); + connect(ui->checkStatus, SIGNAL(pressed()), this, SLOT(slot_checkTypePressed())); + connect(ui->checkStatus, SIGNAL(stateChanged(int)), this, SLOT(slot_typeSelectChange(int))); + connect(ui->type, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckTypeState())); + connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); + if(ui->subSystem->count() > 0) + { + ui->subSystem->setCurrentIndex(0); + } +} + +void CAlarmFilterDialog::setPriorityDescription(QMap priorityMap) +{ + m_priorityMap = priorityMap; +} + +void CAlarmFilterDialog::setLocationDescription(QMap locationMap) +{ + m_locationMap = locationMap; +} + +void CAlarmFilterDialog::setRegionDescription(QMap regionMap) +{ + m_regionMap = regionMap; +} + +//void CAlarmFilterDialog::setAlarmStatusDescription(QMap statusMap) +//{ +// m_alarmStatusMap = statusMap; +//} + +void CAlarmFilterDialog::setAlarmTypeDescription(QMap typeMap) +{ + m_alarmTypeMap = typeMap; +} + +void CAlarmFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) +{ + ui->levelFilter->setChecked(isLevelFilterEnable); +} + +void CAlarmFilterDialog::setLevelFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->level->count(); nIndex++) + { + int nLevelID = m_priorityMap.key(ui->level->item(nIndex)->text()); + if(filter.contains(nLevelID)) + { + ui->level->item(nIndex)->setSelected(true); + } + else + { + ui->level->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) +{ + ui->locationFilter->setChecked(isLocationFilterEnable); +} + +void CAlarmFilterDialog::setLocationFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->location->count(); nIndex++) + { + int nLocationID = m_locationMap.key(ui->location->item(nIndex)->text()); + if(filter.contains(nLocationID)) + { + ui->location->item(nIndex)->setSelected(true); + } + else + { + ui->location->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) +{ + ui->regionFilter->setChecked(isRegionFilterEnable); +} + +void CAlarmFilterDialog::setRegionFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->region->count(); nIndex++) + { + int nRegionID = m_regionMap.key(ui->region->item(nIndex)->text()); + if(filter.contains(nRegionID)) + { + ui->region->item(nIndex)->setSelected(true); + } + else + { + ui->region->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable) +{ + ui->alarmTypeFilter->setChecked(isAlarmTypeEnable); +} + +void CAlarmFilterDialog::setAlarmTypeFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->type->count(); nIndex++) + { + int nAlarmTypeID = m_alarmTypeMap.key(ui->type->item(nIndex)->text()); + if(filter.contains(nAlarmTypeID)) + { + ui->type->item(nIndex)->setSelected(true); + } + else + { + ui->type->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setDeviceFilterEnable(const bool &filter) +{ + ui->deviceFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setSubSystem(const QString &subSystem) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->subSystem->setCurrentText(subSystem); + } +} + +void CAlarmFilterDialog::setDeviceType(const QString &deviceType) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->deviceType->setCurrentText(deviceType); + } +} + +void CAlarmFilterDialog::setTimeFilterEnable(const bool &filter) +{ + ui->timeFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setStartTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->startTime->setDateTime(filter); + } + else + { + ui->startTime->setDateTime(QDateTime::currentDateTime()); + } +} + +void CAlarmFilterDialog::setEndTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->endTime->setDateTime(filter); + } + else + { + ui->endTime->setDateTime(QDateTime::currentDateTime()); + } +} + +void CAlarmFilterDialog::setStateFilterEnable(const bool &filter) +{ + ui->stateFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setStateFilter(const bool &filter) +{ + if(filter) + { + ui->confirm->setChecked(true); + } + else + { + ui->unConfirm->setChecked(true); + } +} + +void CAlarmFilterDialog::setkeyWordFilterEnable(const bool &filter) +{ + ui->keywordFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setkeyWordFilteContent(const QString &content) +{ + if(ui->keywordFilterEnable->isChecked()) + { + ui->keyWord->setText(content); + } +} + +void CAlarmFilterDialog::slot_updateFilter() +{ + bool isLevelFilter = ui->levelFilter->isChecked(); + QList listLevel; + foreach (QListWidgetItem *item, ui->level->selectedItems()) + { + listLevel << m_priorityMap.key(item->text()); + } + + bool isLocationFilter = ui->locationFilter->isChecked(); + QList listLocation; + foreach (QListWidgetItem *item, ui->location->selectedItems()) + { + listLocation << m_locationMap.key(item->text()); + } + + bool isRegionFilter = ui->regionFilter->isChecked(); + QList listRegion; + foreach (QListWidgetItem *item, ui->region->selectedItems()) + { + listRegion << m_regionMap.key(item->text()); + } + + bool isAlarmTypeFilter = ui->alarmTypeFilter->isChecked(); + QList listAlarmType; + foreach (QListWidgetItem *item, ui->type->selectedItems()) + { + listAlarmType << m_alarmTypeMap.key(item->text()); + } + + bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); + QString subSystem = ui->subSystem->currentText(); + QString deviceType = ui->deviceType->currentText(); + + bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); + QString strKeyWord =ui->keyWord->text(); + + bool isTimeFilter = ui->timeFilterEnable->isChecked(); + QDateTime startTime = QDateTime(); + QDateTime endTime = QDateTime(); + if(isTimeFilter) + { + startTime = ui->startTime->dateTime(); + endTime = ui->endTime->dateTime(); + } + + bool isConfirmFilter = ui->stateFilterEnable->isChecked(); + bool confirm = ui->confirm->isChecked(); + + emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, + isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime, isConfirmFilter, confirm); + accept(); +} + +//Level +void CAlarmFilterDialog::slot_checkLevelPressed() +{ + if( Qt::Unchecked == ui->checkLevel->checkState()) + { + ui->checkLevel->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_levelSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->level->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->level->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckLevelState() +{ + if( ui->level->count() == ui->level->selectedItems().count() ) + { + if( Qt::Checked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->level->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Location +void CAlarmFilterDialog::slot_checkLocationPressed() +{ + if( Qt::Unchecked == ui->checkLocation->checkState()) + { + ui->checkLocation->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_locationSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->location->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->location->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckLocationState() +{ + if( ui->location->count() == ui->location->selectedItems().count() ) + { + if( Qt::Checked != ui->checkLocation->checkState() ) + { + ui->checkLocation->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->location->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkLocation->checkState() ) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkLocation->checkState() ) + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Region +void CAlarmFilterDialog::slot_checkRegionPressed() +{ + if( Qt::Unchecked == ui->checkRegion->checkState()) + { + ui->checkRegion->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_regionSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->region->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->region->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckRegionState() +{ + if( ui->region->count() == ui->region->selectedItems().count() ) + { + if( Qt::Checked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->region->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Type +void CAlarmFilterDialog::slot_checkTypePressed() +{ + if( Qt::Unchecked == ui->checkStatus->checkState()) + { + ui->checkStatus->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_typeSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->type->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->type->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckTypeState() +{ + if( ui->type->count() == ui->type->selectedItems().count() ) + { + if( Qt::Checked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->type->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::PartiallyChecked); + } + } +} + +void CAlarmFilterDialog::slot_updateDevice(const QString &subSystem) +{ + int nSubSystemId = -1; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(subSystem.toStdString() == info.strDesc) + { + nSubSystemId = info.nId; + } + } + } + + ui->deviceType->clear(); + + QList values; + + if(nSubSystemId != -1) + { + kbd_dbms::CVarType subSystemId = nSubSystemId; + if(m_rtdbAccess->open("base", "dev_type_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CONDINFO condition; + condition.relationop = ATTRCOND_EQU; + memcpy(condition.name, "sub_system", strlen("sub_system")); + condition.conditionval = subSystemId; + std::vector columns; + columns.push_back("description"); + + kbd_dbms::CRdbQueryResult result; + if(m_rtdbAccess->select(condition, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, value); + values.append(value); + } + } + } + } + foreach (kbd_dbms::CVarType value, values) + { + ui->deviceType->addItem(value.c_str()); + } +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.h index e9676577..e9c54713 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.h @@ -1,110 +1,110 @@ -#ifndef CALARMFILTERDIALOG_H -#define CALARMFILTERDIALOG_H - -#include -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" - -namespace Ui { -class CAlarmFilterDialog; -} - -class CAlarmFilterDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CAlarmFilterDialog(QWidget *parent = 0); - ~CAlarmFilterDialog(); - - void initialize(); - - void setPriorityDescription(QMap priorityMap); - void setLocationDescription(QMap locationMap); - void setRegionDescription(QMap regionMap); -// /** -// * @brief setAlarmStatusDescription 在过滤窗中新增告警状态代替过去的告警类型 -// * @param statusMap -// */ -// void setAlarmStatusDescription(QMap statusMap); - void setAlarmTypeDescription(QMap typeMap); - void setLevelFilterEnable(const bool &isLevelFilterEnable); - void setLevelFilter(const QList &filter); - void setLocationFilterEnable(const bool &isLocationFilterEnable); - void setLocationFilter(const QList &filter); - void setRegionFilterEnable(const bool &isRegionFilterEnable); - void setRegionFilter(const QList &filter); -// /** -// * @brief setAlarmTypeFilterEnable 过滤窗新增告警状态代替告警类型 -// * @param isAlarmTypeEnable -// */ -// void setAlarmStatusFilterEnable(const bool &isAlarmStatusEnable); -// /** -// * @brief setAlarmStatusFilter 过滤窗新增告警状态代替告警类型 -// * @param filter -// */ -// void setAlarmStatusFilter(const QList &filter); - - void setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable); - - void setAlarmTypeFilter(const QList &filter); - - void setDeviceFilterEnable(const bool &filter); - void setSubSystem(const QString &subSystem); - void setDeviceType(const QString &deviceType); - void setTimeFilterEnable(const bool &filter); - void setStartTimeFilter(const QDateTime &filter); - void setEndTimeFilter(const QDateTime &filter); - void setStateFilterEnable(const bool &filter); - void setStateFilter(const bool &filter); - void setkeyWordFilterEnable(const bool &filter); - void setkeyWordFilteContent(const QString &content); -signals: - /** - * @brief sig_updateFilter - * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm - */ - void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool); - -private slots: - void slot_updateFilter(); - - //Level - void slot_checkLevelPressed(); - void slot_levelSelectChange(const int &state); - void slot_updateCheckLevelState(); - - //Station - void slot_checkLocationPressed(); - void slot_locationSelectChange(const int &state); - void slot_updateCheckLocationState(); - - //Region - void slot_checkRegionPressed(); - void slot_regionSelectChange(const int &state); - void slot_updateCheckRegionState(); - - //AlarmType - void slot_checkTypePressed(); - void slot_typeSelectChange(const int &state); - void slot_updateCheckTypeState(); - - //DeviceType - void slot_updateDevice(const QString &subSystem); - -private: - Ui::CAlarmFilterDialog *ui; - - kbd_dbms::CRdbAccess * m_rtdbAccess; - QMap m_priorityMap; - QMap m_locationMap; - QMap m_regionMap; - QMap m_alarmTypeMap; - /** - * @brief m_alarmStatusMap 过滤窗新增告警状态代替告警类型 - */ - QMap m_alarmStatusMap; -}; - -#endif // ALARMFILTERDIALOG_H +#ifndef CALARMFILTERDIALOG_H +#define CALARMFILTERDIALOG_H + +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" + +namespace Ui { +class CAlarmFilterDialog; +} + +class CAlarmFilterDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmFilterDialog(QWidget *parent = 0); + ~CAlarmFilterDialog(); + + void initialize(); + + void setPriorityDescription(QMap priorityMap); + void setLocationDescription(QMap locationMap); + void setRegionDescription(QMap regionMap); +// /** +// * @brief setAlarmStatusDescription 在过滤窗中新增告警状态代替过去的告警类型 +// * @param statusMap +// */ +// void setAlarmStatusDescription(QMap statusMap); + void setAlarmTypeDescription(QMap typeMap); + void setLevelFilterEnable(const bool &isLevelFilterEnable); + void setLevelFilter(const QList &filter); + void setLocationFilterEnable(const bool &isLocationFilterEnable); + void setLocationFilter(const QList &filter); + void setRegionFilterEnable(const bool &isRegionFilterEnable); + void setRegionFilter(const QList &filter); +// /** +// * @brief setAlarmTypeFilterEnable 过滤窗新增告警状态代替告警类型 +// * @param isAlarmTypeEnable +// */ +// void setAlarmStatusFilterEnable(const bool &isAlarmStatusEnable); +// /** +// * @brief setAlarmStatusFilter 过滤窗新增告警状态代替告警类型 +// * @param filter +// */ +// void setAlarmStatusFilter(const QList &filter); + + void setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable); + + void setAlarmTypeFilter(const QList &filter); + + void setDeviceFilterEnable(const bool &filter); + void setSubSystem(const QString &subSystem); + void setDeviceType(const QString &deviceType); + void setTimeFilterEnable(const bool &filter); + void setStartTimeFilter(const QDateTime &filter); + void setEndTimeFilter(const QDateTime &filter); + void setStateFilterEnable(const bool &filter); + void setStateFilter(const bool &filter); + void setkeyWordFilterEnable(const bool &filter); + void setkeyWordFilteContent(const QString &content); +signals: + /** + * @brief sig_updateFilter + * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm + */ + void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool); + +private slots: + void slot_updateFilter(); + + //Level + void slot_checkLevelPressed(); + void slot_levelSelectChange(const int &state); + void slot_updateCheckLevelState(); + + //Station + void slot_checkLocationPressed(); + void slot_locationSelectChange(const int &state); + void slot_updateCheckLocationState(); + + //Region + void slot_checkRegionPressed(); + void slot_regionSelectChange(const int &state); + void slot_updateCheckRegionState(); + + //AlarmType + void slot_checkTypePressed(); + void slot_typeSelectChange(const int &state); + void slot_updateCheckTypeState(); + + //DeviceType + void slot_updateDevice(const QString &subSystem); + +private: + Ui::CAlarmFilterDialog *ui; + + kbd_dbms::CRdbAccess * m_rtdbAccess; + QMap m_priorityMap; + QMap m_locationMap; + QMap m_regionMap; + QMap m_alarmTypeMap; + /** + * @brief m_alarmStatusMap 过滤窗新增告警状态代替告警类型 + */ + QMap m_alarmStatusMap; +}; + +#endif // ALARMFILTERDIALOG_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.ui b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.ui index 8c7fa193..45b85361 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.ui +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmFilterDialog.ui @@ -1,378 +1,378 @@ - - - CAlarmFilterDialog - - - - 0 - 0 - 530 - 429 - - - - - 530 - 0 - - - - - 530 - 16777215 - - - - 过滤 - - - - - - - - 优先级 - - - true - - - - - - 全选 - - - true - - - true - - - - - - - - - - - - - 位置 - - - true - - - - - - 全选 - - - true - - - - - - - - - - - - - 责任区 - - - true - - - - - - 全选 - - - true - - - - - - - - - - - - - 告警类型 - - - true - - - - - - 全选 - - - true - - - - - - - - - - - - - - - - - - - 设备类型 - - - true - - - false - - - - - - - - - - - - - - - - - - - - - - - 时间 - - - true - - - false - - - - - - - - 开始时间 - - - - - - - - 0 - 0 - 0 - 2018 - 1 - 1 - - - - - 2018 - 1 - 1 - - - - - 23 - 59 - 59 - 2050 - 12 - 31 - - - - - 2050 - 12 - 31 - - - - - 2000 - 1 - 1 - - - - yyyy/MM/dd hh:mm - - - - - - - - - - - 结束时间 - - - - - - - - 2018 - 1 - 1 - - - - - 2050 - 12 - 31 - - - - - 2000 - 1 - 1 - - - - yyyy/MM/dd hh:mm - - - - - - - - - - - - - - - - 告警内容关键字 - - - true - - - false - - - - - - - - - - - - 状态 - - - false - - - true - - - false - - - - - - 已确认 - - - true - - - - - - - 未确认 - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 281 - 20 - - - - - - - - 确定 - - - - - - - 取消 - - - - - - - - - - + + + CAlarmFilterDialog + + + + 0 + 0 + 530 + 429 + + + + + 530 + 0 + + + + + 530 + 16777215 + + + + 过滤 + + + + + + + + 优先级 + + + true + + + + + + 全选 + + + true + + + true + + + + + + + + + + + + + 位置 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + + 责任区 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + + 告警类型 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + + + + + + + + 设备类型 + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + 时间 + + + true + + + false + + + + + + + + 开始时间 + + + + + + + + 0 + 0 + 0 + 2018 + 1 + 1 + + + + + 2018 + 1 + 1 + + + + + 23 + 59 + 59 + 2050 + 12 + 31 + + + + + 2050 + 12 + 31 + + + + + 2000 + 1 + 1 + + + + yyyy/MM/dd hh:mm + + + + + + + + + + + 结束时间 + + + + + + + + 2018 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + + 2000 + 1 + 1 + + + + yyyy/MM/dd hh:mm + + + + + + + + + + + + + + + + 告警内容关键字 + + + true + + + false + + + + + + + + + + + + 状态 + + + false + + + true + + + false + + + + + + 已确认 + + + true + + + + + + + 未确认 + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 281 + 20 + + + + + + + + 确定 + + + + + + + 取消 + + + + + + + + + + diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.cpp index 51572970..02e7b3c6 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.cpp @@ -1,2013 +1,2013 @@ -#include "CAlarmForm.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ui_CAlarmForm.h" -#include "CAlarmDelegate.h" -#include "CAiAlarmDelegate.h" -#include "CAlarmItemModel.h" -#include "CAlarmFilterDialog.h" -#include "CAlarmMsgManage.h" -#include "CTableViewPrinter.h" -#include "CAlarmDataCollect.h" -#include "CAiAlarmDataCollect.h" -#include "CAlarmInhibitDialog.h" -#include "CAlarmDeviceTreeModel.h" -#include "CAlarmDeviceTreeItem.h" -#include "CAiAlarmTreeItem.h" -#include "CAiAlarmTreeModel.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "dbms/db_sysinfo_api/CDbSysInfo.h" -#include -#include -#include "CMyListWidget.h" -#include "CMyCheckBox.h" -#include "CDisposalPlanDialog.h" -#include "CTreeViewPrinter.h" -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileUtil.h" -#include -CAlarmForm::CAlarmForm(QWidget *parent) : - QWidget(parent), - m_pModel(Q_NULLPTR), - m_treeModel(Q_NULLPTR), - m_delegate(Q_NULLPTR), - m_aiDelegate(Q_NULLPTR), - m_aiOptPerm(true), - m_enableAi(false), - ui(new Ui::CAlarmForm) -{ - qRegisterMetaType("QItemSelection"); - qRegisterMetaType< QList > >("QList >"); - qRegisterMetaType >("QVector"); - qRegisterMetaType >("QVector"); - qRegisterMetaType >("QVector"); - ui->setupUi(this); - ui->alarmView->setObjectName("alarmView"); - ui->splitter->setStretchFactor(0,1); - ui->splitter->setStretchFactor(1,6); - - QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->deviceView->header()); - m_pSearchTextEdit = new QLineEdit(ui->deviceView->header()); - m_pSearchTextEdit->setObjectName("searchTextEdit"); - m_pSearchTextEdit->setTextMargins(0, 0, 21, 0); - pHBoxLayout->addWidget(m_pSearchTextEdit); - pHBoxLayout->setContentsMargins(2,0,2,0); - pHBoxLayout->setSpacing(0); - ui->deviceView->header()->setLayout(pHBoxLayout); - ui->deviceView->header()->setFixedHeight(36); - - m_pSearchButton = new QPushButton(this); - m_pSearchButton->setObjectName("searchButton"); - m_pSearchButton->setText(""); - m_pSearchButton->setMaximumSize(21, 22); - m_pSearchButton->setCursor(QCursor(Qt::ArrowCursor)); - - QHBoxLayout * pSearchLayout = new QHBoxLayout(); - pSearchLayout->setContentsMargins(1, 1, 1, 1); - pSearchLayout->addStretch(); - pSearchLayout->addWidget(m_pSearchButton); - m_pSearchTextEdit->setLayout(pSearchLayout); - - connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CAlarmForm::searchDeviceName); - connect(m_pSearchButton, &QPushButton::clicked, this, &CAlarmForm::searchDeviceName); - //initialize(); - m_pListWidget1 = new CMyListWidget(this); - m_pListWidget2 = new CMyListWidget(this); - m_pListWidget3 = new CMyListWidget(this); - m_pLineEdit1 = new QLineEdit(this); - m_pLineEdit2 = new QLineEdit(this); - m_pLineEdit3 = new QLineEdit(this); - m_timeIcon = new QPushButton(this); - //时间过滤 - m_myCalendar = new CMyCalendar(this); - QWidgetAction *widgetAction=new QWidgetAction(this); - m_timeMenu = new QMenu(this); - widgetAction->setDefaultWidget(m_myCalendar); - m_timeMenu->addAction(widgetAction); - m_timeIcon->setObjectName("iconButton"); - m_timeIcon->setText(""); - m_timeIcon->setMaximumSize(21, 22); - m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); - QHBoxLayout * pTimeLayout = new QHBoxLayout(); - pTimeLayout->setContentsMargins(1, 1, 1, 1); - pTimeLayout->addStretch(); - pTimeLayout->addWidget(m_timeIcon); - ui->lineEdit->setLayout(pTimeLayout); - connect(m_timeIcon,&QPushButton::clicked,this,&CAlarmForm::myCalendarShow); - connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CAlarmForm::myCalendarHide); - connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CAlarmForm::cancleTimeFilter); - ui->lineEdit->setText(tr("请选择时间")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit->setObjectName("iconLineEdit"); - - m_pdfPrinter = new CPdfPrinter(); - m_thread = new QThread(); - m_pdfPrinter->moveToThread(m_thread); - connect(m_thread,&QThread::started,m_pdfPrinter,&CPdfPrinter::initialize); - connect(m_thread,&QThread::finished,m_pdfPrinter,&CPdfPrinter::deleteLater); - connect(this,&CAlarmForm::printExcel,m_pdfPrinter,&CPdfPrinter::printerByModel); - connect(this,&CAlarmForm::printExcelAlm,m_pdfPrinter,&CPdfPrinter::printerAlmByModel); - connect(m_pdfPrinter,&CPdfPrinter::printResult,this,&CAlarmForm::printMess); - m_thread->start(); -} - -CAlarmForm::~CAlarmForm() -{ - removeInhibitAlarm(m_listInhibitAlarm); - if(m_delegate) - { - delete m_delegate; - } - m_delegate = Q_NULLPTR; - - if(m_aiDelegate) - { - delete m_aiDelegate; - } - m_aiDelegate = Q_NULLPTR; - delete m_pdfPrinter; - m_thread->quit(); - m_thread->wait(); - delete ui; - LOGDEBUG("CAlarmForm::~CAlarmForm()"); - qDebug() << "~CAlarmForm()"; -} - -void CAlarmForm::initialize() -{ - m_pDeviceModel = new CAlarmDeviceTreeModel(this); - ui->deviceView->setModel(m_pDeviceModel); - connect(ui->checkBox,SIGNAL(stateChanged(int)),this,SLOT(slot_changePage(int))); - connect(ui->filter, SIGNAL(clicked()), this, SLOT(updateFilter())); - connect(ui->remove, SIGNAL(clicked()), this, SLOT(slot_removeAlarm())); - connect(ui->confirm, SIGNAL(clicked()), this, SLOT(slot_confirmAlarm())); - - connect(ui->inhibit, SIGNAL(clicked()), this, SLOT(slot_showInhibitAlarm())); - - connect(ui->print, SIGNAL(clicked()), this, SLOT(print())); - connect(ui->closeBtn, &QPushButton::clicked, this, &CAlarmForm::closeBtnClicked); - updateAlarmOperatePerm(); - - //< lingdaoyaoqiu - { - QSettings columFlags("KBD_HMI", "alarm config"); - if(!columFlags.contains(QString("alarm/colum_0"))) - { - columFlags.setValue(QString("alarm/colum_0"), false); //< 时间 - columFlags.setValue(QString("alarm/colum_1"), false); //< 优先级 - columFlags.setValue(QString("alarm/colum_2"), false); //< 位置 - columFlags.setValue(QString("alarm/colum_3"), true); //< 责任区 - columFlags.setValue(QString("alarm/colum_4"), true); //< 告警类型 - columFlags.setValue(QString("alarm/colum_5"), false); //< 告警状态 - columFlags.setValue(QString("alarm/colum_6"), false); //< 确认状态 - columFlags.setValue(QString("alarm/colum_7"), false); //< - } - } - loadConfig(); - ui->checkBox->setChecked(m_enableAi); -} - -void CAlarmForm::loadConfig() -{ - QFile file(kbd_public::CFileUtil::getPathOfCfgFile("intelli_alm_cfg.xml",CN_DIR_PLATFORM).c_str()); - if (!file.open(QFile::ReadWrite)) - { - LOGERROR("打开智能告警配置文件失败,默认不启动"); - return; - } - - QDomDocument doc; - if (!doc.setContent(&file)) - { - file.close(); - LOGERROR("加载智能告警配置文件失败,默认不启动"); - return; - } - file.close(); - - QDomElement root = doc.documentElement(); //返回根节点 root - QDomNode node = root.firstChild(); //获得第一个子节点 - - while (!node.isNull()) //如果节点不空 - { - QDomElement element = node.toElement(); - if(element.tagName() == "intelli_alm_srv") - { - if(element.attribute("enable") == "true") - { - m_enableAi =true; - }else - { - m_enableAi =false; - } - break; - } - node = node.nextSibling(); - } -} - -void CAlarmForm::updateAlarmOperatePerm() -{ - m_listRegionId.clear(); - m_listLocationId.clear(); - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - m_nodeName = stNodeInfo.strName; - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(PERM_NORMAL != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - m_userId = -1; - LOGERROR("用户ID获取失败!"); - return; - } - std::vector vecRegionId; - std::vector vecLocationId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionId, vecLocationId)) - { - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - m_listRegionId.append(*region++); - } - - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - m_listLocationId.append(*location++); - } - } - std::string str = "FUNC_NOM_IA_EDIT"; - if(PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF,&str)) - { - m_aiOptPerm = false; - LOGERROR("无智能告警编辑权限"); - }else - { - m_aiOptPerm = true; - } - } -} - -void CAlarmForm::setAlarmOperateEnable(const bool &bEnable) -{ - ui->confirm->setEnabled(bEnable); - ui->remove->setEnabled(bEnable); -} - -void CAlarmForm::setColumnWidth(const int &column, const int &width) -{ - if(ui->alarmView != Q_NULLPTR) - { - ui->alarmView->setColumnWidth(column, width); - } -} - -void CAlarmForm::initFilter() -{ - QMap priority = m_pModel->priorityDescriptionMap(); - QMap location = m_pModel->locationDescriptionMap(); - QMap alarmType = m_pModel->alarmTypeDescriptionMap(); - for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); - pItem->setData(Qt::UserRole, it1.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it1.value()); - m_pListWidget1->addItem(pItem); - m_pListWidget1->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); - } - ui->comboBox->setModel(m_pListWidget1->model()); - ui->comboBox->setView(m_pListWidget1); - ui->comboBox->setLineEdit(m_pLineEdit1); - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - m_pLineEdit1->setReadOnly(true); - connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 - for(QMap::iterator it2 = location.begin();it2 != location.end();++it2) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); - pItem->setData(Qt::UserRole, it2.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it2.value()); - m_pListWidget2->addItem(pItem); - m_pListWidget2->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); - } - ui->comboBox_2->setModel(m_pListWidget2->model()); - ui->comboBox_2->setView(m_pListWidget2); - ui->comboBox_2->setLineEdit(m_pLineEdit2); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - m_pLineEdit2->setReadOnly(true); - connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); - for(QMap::iterator it3 = alarmType.begin();it3 != alarmType.end();++it3) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); - pItem->setData(Qt::UserRole, it3.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it3.value()); - m_pListWidget3->addItem(pItem); - m_pListWidget3->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); - } - ui->comboBox_3->setModel(m_pListWidget3->model()); - ui->comboBox_3->setView(m_pListWidget3); - ui->comboBox_3->setLineEdit(m_pLineEdit3); - m_strText3 = tr("请选择告警类型"); - m_pLineEdit3->setText(tr("请选择告警类型")); - m_pLineEdit3->setReadOnly(true); - connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); -} - -void CAlarmForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) -{ - if(isLevelFilter == true && listLevel.size() > 0) - { - QString strText(""); - for (int i = 0; i < m_pListWidget1->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listLevel.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText1 = strText; - m_pLineEdit1->setText(strText); - }else - { - for (int i = 0; i < m_pListWidget1->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - } -} - -void CAlarmForm::setLocationComboBox(bool &isLocationFilter,QList &listLocation) -{ - if(isLocationFilter == true && listLocation.size() > 0) - { - QString strText(""); - for (int i = 0; i < m_pListWidget2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listLocation.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText2 = strText; - m_pLineEdit2->setText(strText); - }else - { - for (int i = 0; i < m_pListWidget2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - } -} - -void CAlarmForm::setAlarmTypeComboBox(bool &isAlarmTypeFilter, QList &listAlarmType) -{ - if(isAlarmTypeFilter == true && listAlarmType.size() > 0) - { - QString strText(""); - for (int i = 0; i < m_pListWidget3->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listAlarmType.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText3 = strText; - m_pLineEdit3->setText(strText); - }else - { - for (int i = 0; i < m_pListWidget3->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText3 = tr("请选择告警类型"); - m_pLineEdit3->setText(tr("请选择告警类型")); - } -} - -void CAlarmForm::setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) -{ - if(isTimeFilter == true) - { - ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); - }else - { - ui->lineEdit->setText(tr("请选择时间")); - } -} - -void CAlarmForm::setAlarmModel(CAlarmItemModel *model) -{ - m_pModel = model; - m_delegate = new CAlarmDelegate(m_pModel, ui->alarmView); - connect(m_delegate,&CAlarmDelegate::openVideo,CAlarmMsgManage::instance(),&CAlarmMsgManage::openVideoDialog,Qt::QueuedConnection); - ui->alarmView->initialize(); - ui->alarmView->setItemDelegate(m_delegate); - ui->alarmView->setModel(m_pModel); - - //< 性能损耗 - //connect(ui->alarmView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(slot_selectionChanged()), Qt::QueuedConnection); - connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); - ui->confirm->setEnabled(true); - ui->remove->setEnabled(true); - - - //原始告警窗 - - ui->alarmView->setColumnWidth(0, 230); - ui->alarmView->setColumnWidth(1, 120); - ui->alarmView->setColumnWidth(2, 150); - ui->alarmView->setColumnWidth(5, 150); - ui->alarmView->setColumnWidth(6, 120); - - ui->alarmView->horizontalHeader()->setSortIndicator(1, Qt::AscendingOrder); - QSettings columFlags("KBD_HMI", "alarm config"); - for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount(); nColumnIndex++) - { - bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); - ui->alarmView->setColumnHidden(nColumnIndex, visible); - } - // ui->stackedWidget->setCurrentIndex(0); - ui->checkBox->setHidden(true); - //智能告警窗 - if(m_enableAi) - { - ui->aiAlarmTreeView->initialize(); - m_treeModel = new CAiAlarmTreeModel(this); - m_aiDelegate = new CAiAlarmDelegate(m_treeModel,ui->aiAlarmTreeView); - ui->aiAlarmTreeView->setItemDelegate(m_aiDelegate); - ui->aiAlarmTreeView->setModel(m_treeModel); - connect(m_aiDelegate,&CAiAlarmDelegate::openVideo,CAlarmMsgManage::instance(),&CAlarmMsgManage::openVideoDialog,Qt::QueuedConnection); - connect(ui->aiAlarmTreeView->header(),&QHeaderView::sortIndicatorChanged, m_treeModel,&CAiAlarmTreeModel::sortColumn); - connect(ui->aiAlarmTreeView,&CAiAlarmTreeView::doubleClicked, this,&CAlarmForm::aiAlmDoubleClicked); - - ui->aiAlarmTreeView->setColumnWidth(0, 230); - ui->aiAlarmTreeView->setColumnWidth(1, 120); - ui->aiAlarmTreeView->setColumnWidth(2, 150); - ui->aiAlarmTreeView->setColumnWidth(5, 150); - ui->aiAlarmTreeView->setColumnWidth(6, 120); - - - ui->aiAlarmTreeView->header()->setSortIndicator(1, Qt::AscendingOrder); - for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount(); nColumnIndex++) - { - bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); - ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, visible); - } - // ui->stackedWidget->setCurrentIndex(1); - ui->checkBox->setHidden(false); - } - - - loadDeviceGroupFilterWidget(); - if(m_pDeviceModel) - { - connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); - } - initFilter(); -} - -void CAlarmForm::updateView() -{ - m_pModel->updateAlternate(); - updateDeviceGroupHiddenState(); - ui->alarmView->viewport()->update(); - if(m_enableAi) - { - ui->aiAlarmTreeView->viewport()->update(); - } - updateRowTips(); -} - -void CAlarmForm::updateFilter() -{ - bool isLevelFilter; - QList levelFilter; - bool isLocationFilter; - QList locationFilter; - bool isRegionFilter; - QList regionFilter; - bool isAlarmTypeFilter; //告警状态过滤 - QList typeFilter; - bool deviceTypeFilter; - QString subSystem; - QString deviceType; - bool keywordFilter; - QString keyword; - bool isTimeFilterEnable; - QDateTime startTime; - QDateTime endTime; - bool isStateFilterEnable; - bool isConfirm; - - CAlarmFilterDialog filterDlg; - filterDlg.setPriorityDescription(m_pModel->priorityDescriptionMap()); - filterDlg.setLocationDescription(m_pModel->locationDescriptionMap()); - filterDlg.setRegionDescription(m_pModel->regionDescriptionMap()); - filterDlg.setAlarmTypeDescription(m_pModel->alarmTypeDescriptionMap()); - m_pModel->getFilter(isLevelFilter, levelFilter, - isLocationFilter, locationFilter, - isRegionFilter, regionFilter, - isAlarmTypeFilter, typeFilter, - deviceTypeFilter, subSystem, deviceType, - keywordFilter, keyword, - isTimeFilterEnable, startTime, endTime, - isStateFilterEnable, isConfirm); - filterDlg.initialize(); - filterDlg.setLevelFilterEnable(isLevelFilter); - filterDlg.setLevelFilter(levelFilter); - filterDlg.setLocationFilterEnable(isLocationFilter); - filterDlg.setLocationFilter(locationFilter); - filterDlg.setRegionFilterEnable(isRegionFilter); - filterDlg.setRegionFilter(regionFilter); - filterDlg.setAlarmTypeFilterEnable(isAlarmTypeFilter); - filterDlg.setAlarmTypeFilter(typeFilter); - filterDlg.setDeviceFilterEnable(deviceTypeFilter); - filterDlg.setSubSystem(subSystem); - filterDlg.setDeviceType(deviceType); - filterDlg.setkeyWordFilterEnable(keywordFilter); - filterDlg.setkeyWordFilteContent(keyword); - filterDlg.setTimeFilterEnable(isTimeFilterEnable); - filterDlg.setStartTimeFilter(startTime); - filterDlg.setEndTimeFilter(endTime); - filterDlg.setStateFilterEnable(isStateFilterEnable); - filterDlg.setStateFilter(isConfirm); - connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool)), - this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool))); - filterDlg.exec(); -} - -void CAlarmForm::deviceGroupFilterChanged(const QString &device, const bool &checked) -{ - if(checked) - { - m_pModel->removeDeviceGroupFilter(device); - if(m_enableAi) - { - m_treeModel->removeDeviceGroupFilter(device); - } - } - else - { - m_pModel->addDeviceGroupFilter(device); - if(m_enableAi) - { - m_treeModel->addDeviceGroupFilter(device); - } - } -} - -void CAlarmForm::slot_changePage(int i) -{ - Q_UNUSED(i) - if(!ui->checkBox->isChecked()) - { - ui->stackedWidget->setCurrentIndex(0); - }else - { - ui->stackedWidget->setCurrentIndex(1); - } -} - -void CAlarmForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmType, - bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm) -{ - m_pModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm); - if(m_enableAi) - { - m_treeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm); - } - - //设置下拉框的值 - setLevelComboBox(isLevelFilter,listLevel); - setLocationComboBox(isLocationFilter,listLocation); - setAlarmTypeComboBox(isAlarmTypeFilter,listAlarmType); - setAlarmTimeLineEdit(isTimeFilter, startTime, endTime); -} - -void CAlarmForm::slot_removeAlarm() -{ - updateAlarmOperatePerm(); - if(!ui->checkBox->isChecked()) - { - removeAlarm0(); - }else - { - removeAlarm1(); - } -} - -void CAlarmForm::slot_confirmAlarm() -{ - updateAlarmOperatePerm(); - if(!ui->checkBox->isChecked()) - { - confirmAlarm0(); - }else - { - confirmAlarm1(); - } -} - -void CAlarmForm::slot_showInhibitAlarm() -{ - CAlarmInhibitDialog dlg; - dlg.setPriorityDescriptionMap(m_pModel->priorityDescriptionMap()); - dlg.setLocationDescriptionMap(m_pModel->locationDescriptionMap()); - dlg.setRegionDescriptionMap(m_pModel->regionDescriptionMap()); - dlg.setAlarmTypeDescriptionMap(m_pModel->alarmTypeDescriptionMap()); - dlg.setDeviceTypeDescriptionMap(m_pModel->deviceTypeDescriptionMap()); - dlg.setInhibitAlarmList(m_listInhibitAlarm); - connect(&dlg, &CAlarmInhibitDialog::removeInhibitAlarmList, this, &CAlarmForm::removeInhibitAlarm); - dlg.exec(); - -} - -void CAlarmForm::removeInhibitAlarm(QList alarmList) -{ - foreach (AlarmMsgPtr alm, alarmList) - { - m_listInhibitAlarm.removeAll(alm); - CAlarmMsgManage::instance()->removeInhibitTag(alm->key_id_tag); - } -} - -void CAlarmForm::searchDeviceName() -{ - QItemSelection selection; - QString content = m_pSearchTextEdit->text(); - ui->deviceView->selectionModel()->select(selection, QItemSelectionModel::Clear); - if(content.isEmpty()) - { - return; - } - const QHash< QString, QModelIndex > &indexNameList = m_pDeviceModel->indexNameList(); - QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); - while (iter != indexNameList.constEnd()) - { - qDebug()<deviceView->selectionModel()->select(selection, QItemSelectionModel::Select); -} - -void CAlarmForm::updateRowTips() -{ - if(!ui->checkBox->isChecked()) - { - if(m_pModel) - { - ui->showRow->setText(QString::number(m_pModel->rowCount())); - int nNumber = m_pModel->filterCount(); - if(nNumber<0) nNumber = 0 ; - ui->filterRow->setText(QString::number(nNumber)); - } - } - else - { - if(m_treeModel) - { - int showNum = m_treeModel->getShowNum(); - int showAiNum = m_treeModel->getShowAi(); - int showTotal = CAlarmMsgManage::instance()->getAlmTotal(); - ui->showRow->setText(QString("%1/%2").arg(showNum).arg(showAiNum)); - int nNumber = showTotal - showNum; - if(nNumber<0) nNumber = 0 ; - ui->filterRow->setText(QString::number(nNumber)); - } - } -} - -void CAlarmForm::print() -{ - //QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); - QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xlsx)");//获取保存路径*.xls - if(!ui->checkBox->isChecked()) - { - print0(fileName); - }else - { - print1(fileName); - } -} - -void CAlarmForm::stateChanged1(int state) -{ - Q_UNUSED(state) - QString strText(""); - m_priorityList.clear(); - int nCount = m_pListWidget1->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_priorityList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText1 = strText; - m_pLineEdit1->setText(strText); - } - else - { - m_pLineEdit1->clear(); - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - } - bool isCheck = false; - if(m_priorityList.size() > 0) - { - isCheck = true; - } - m_pModel->setPriorityFilter(isCheck,m_priorityList); - if(m_enableAi) - { - m_treeModel->setPriorityFilter(isCheck,m_priorityList); - } -} - -void CAlarmForm::stateChanged2(int state) -{ - Q_UNUSED(state) - QString strText(""); - m_locationList.clear(); - int nCount = m_pListWidget2->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_locationList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText2 = strText; - m_pLineEdit2->setText(strText); - } - else - { - m_pLineEdit2->clear(); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - } - bool isCheck = false; - if(m_locationList.size() > 0) - { - isCheck = true; - } - m_pModel->setLocationFilter(isCheck,m_locationList); - if(m_enableAi) - { - m_treeModel->setLocationFilter(isCheck,m_locationList); - } -} - -void CAlarmForm::stateChanged3(int state) -{ - Q_UNUSED(state) - QString strText(""); - m_alarmTypeList.clear(); - bool other = false; - int nCount = m_pListWidget3->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - if(nData == 0) - { - other = true; - } - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_alarmTypeList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText3 = strText; - m_pLineEdit3->setText(strText); - } - else - { - m_pLineEdit3->clear(); - m_strText3 = tr("请选择告警类型"); - m_pLineEdit3->setText(tr("请选择告警类型")); - } - bool isCheck = false; - if(m_alarmTypeList.size() > 0) - { - isCheck = true; - } - m_pModel->setAlarmTypeFilter(isCheck,m_alarmTypeList); - if(m_enableAi) - { - m_treeModel->setAlarmTypeFilter(isCheck,m_alarmTypeList); - } -} - -void CAlarmForm::textChanged1(const QString &text) -{ - Q_UNUSED(text) - m_pLineEdit1->setText(m_strText1); -} - -void CAlarmForm::textChanged2(const QString &text) -{ - Q_UNUSED(text) - m_pLineEdit2->setText(m_strText2); -} - -void CAlarmForm::textChanged3(const QString &text) -{ - Q_UNUSED(text) - m_pLineEdit3->setText(m_strText3); -} - -void CAlarmForm::myCalendarHide(QDate startTime,QDate endTime) -{ - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); - //开始过滤 - bool isCheck = true; - m_pModel->setAlarmTimeFilter(isCheck,startTime,endTime); - if(m_enableAi) - { - m_treeModel->setAlarmTimeFilter(isCheck,startTime,endTime); - } - m_timeMenu->hide(); -} - -void CAlarmForm::myCalendarShow() -{ - QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); - m_timeMenu->move(point); - m_timeMenu->show(); -} - -void CAlarmForm::cancleTimeFilter() -{ - ui->lineEdit->setText(tr("请选择时间")); - //取消过滤 - bool isCheck = false; - m_pModel->setAlarmTimeFilter(isCheck); - if(m_enableAi) - { - m_treeModel->setAlarmTimeFilter(isCheck); - } - m_timeMenu->hide(); -} - -void CAlarmForm::aiAlmDoubleClicked(const QModelIndex &index) -{ - if(m_treeModel == NULL) - { - return ; - } - if(!index.isValid()) - { - return ; - } - CAiAlarmTreeItem *item =static_cast(index.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr aiPtr; - if(item->getAiPtr(aiPtr)) - { - CDisposalPlanDialog dialog(aiPtr); - dialog.exec(); - }else - { - LOGERROR("aiAlmDoubleClicked():标识符错误!"); - } - } -} - -void CAlarmForm::printMess(QString fileName) -{ - QMessageBox::information( 0, tr("提示"), tr("导出成功")); -} - -void CAlarmForm::contextMenuEvent(QContextMenuEvent *event) -{ - updateAlarmOperatePerm(); - if(ui->stackedWidget->currentIndex() == 0) - { - contextMenuStack0Event(event); - }else if(ui->stackedWidget->currentIndex() == 1) - { - contextMenuStack1Event(event); - } -} - -void CAlarmForm::contextMenuStack0Event(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - if(!m_pModel) - { - return; - } - if(event->pos().x() < ui->alarmView->pos().x()) - { - return; - } - QRect headerRect = ui->alarmView->horizontalHeader()->rect(); - headerRect.moveTopLeft(ui->alarmView->mapTo(this, QPoint())); - if(headerRect.contains(event->pos())) - { - QMenu columnMenu(this); - - for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount()-1; nColumnIndex++) - { - QAction * action = columnMenu.addAction(m_pModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); - action->setCheckable(true); - action->setChecked(!ui->alarmView->isColumnHidden(nColumnIndex)); - connect(action, &QAction::triggered, [=](){ - ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); - ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags("KBD_HMI", "alarm config"); - columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); - }); - } - columnMenu.exec(QCursor::pos()); - } - else - { - QModelIndex index = ui->alarmView->indexAt(ui->alarmView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index.isValid()) - { - return; - } - AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); - ui->alarmView->clearSelection(); - ui->alarmView->selectRow(index.row()); - QMenu menu(this); - QAction * selectAction = menu.addAction(tr("全选")); - connect(selectAction, &QAction::triggered, [=](){ui->alarmView->selectAll();}); - - QAction * InhibitAction = menu.addAction(tr("禁止告警")); - connect(InhibitAction, &QAction::triggered, [=](){ - bool isContains = false; - foreach (AlarmMsgPtr alarm, m_listInhibitAlarm) - { - if(alarm->key_id_tag == alm->key_id_tag) - { - isContains = true; - break; - } - } - if(isContains) - { - QMessageBox::warning(this, tr("警告"), tr("当前测点告警已禁止,无需重复禁止!"), QMessageBox::Ok); - } - else - { - m_listInhibitAlarm.append(alm); - CAlarmMsgManage::instance()->addInhibitTag(alm->key_id_tag); - } - }); - menu.exec(QCursor::pos()); - } -} - -void CAlarmForm::contextMenuStack1Event(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - if(!m_treeModel) - { - return; - } - if(event->pos().x() < ui->aiAlarmTreeView->pos().x()) - { - return; - } - QRect headerRect = ui->aiAlarmTreeView->header()->rect(); - headerRect.moveTopLeft(ui->aiAlarmTreeView->mapTo(this, QPoint())); - if(headerRect.contains(event->pos())) - { - QMenu columnMenu(this); - - for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount()-1; nColumnIndex++) - { - QAction * action = columnMenu.addAction(m_treeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); - action->setCheckable(true); - action->setChecked(!ui->aiAlarmTreeView->isColumnHidden(nColumnIndex)); - connect(action, &QAction::triggered, [=](){ - ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); - ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags("KBD_HMI", "alarm config"); - columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); - }); - } - columnMenu.exec(QCursor::pos()); - }else - { - QMenu menu(this); - QModelIndex index_ = ui->aiAlarmTreeView->indexAt(ui->aiAlarmTreeView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index_.isValid()) - { - return; - } - QModelIndex index = ui->aiAlarmTreeView->currentIndex(); - if(!index.isValid()) - { - return ; - } - QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); - QModelIndexList indexLists = ui->aiAlarmTreeView->selectionModel()->selectedIndexes(); - QList aimsgList; - QList msgList; - - foreach (QModelIndex modelIndex, indexList) - { - if(!modelIndex.isValid()) - { - continue; - } - CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - aimsgList.append(ptr); - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - msgList.append(ptr); - } - } - } - //判断右键位置是否在选中区 - if(indexLists.contains(index)) - { - QAction * mergeAction = menu.addAction(tr("合并")); - connect(mergeAction,&QAction::triggered,[=](){ - QMap pkgMap; - QList listPtr; - listPtr.clear(); - int permSkip = -1; - if(aimsgList.size() > 0) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含智能告警,无法合并!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; - } - - for(int alarmIndex(0);alarmIndex < msgList.size();alarmIndex++) - { - if(msgList.at(alarmIndex) != NULL) - { - //判断此原始告警是否已经被聚类 - if(CAlarmMsgManage::instance()->isBelongAi(msgList.at(alarmIndex)->uuid_base64)) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含已经聚类的原始告警,无法合并!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; - } - //判断权限 - if(!m_aiOptPerm) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户无此条原始告警合并权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - permSkip = 1; - continue; - } - else - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - }else - { - listPtr.append(msgList.at(alarmIndex)); - } - } - } - //过滤后等于0直接返回 - if(listPtr.size() <= 0) - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return ; - } - for(int x(0);xdomain_id; - QMap::iterator it = pkgMap.find(domain_id); - if( it == pkgMap.end()) - { - kbd_idlfile::SIntelliAlmMerge *pkg =new kbd_idlfile::SIntelliAlmMerge(); - pkg->set_domain_id(domain_id); - pkgMap[domain_id] = pkg; - } - pkgMap.value(domain_id)->add_raw_alm_uuid(listPtr.at(x)->uuid_base64.toStdString()); - } - if(pkgMap.size() != 1) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含不同域的原始告警,无法合并!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - qDeleteAll(pkgMap); - pkgMap.clear(); - return ; - } - foreach (kbd_idlfile::SIntelliAlmMerge * pkg, pkgMap) - { - CAiAlarmDataCollect::instance()->requestMergeAlm(*pkg); - } - qDeleteAll(pkgMap); - pkgMap.clear(); - ui->aiAlarmTreeView->setFocus(); - }); - QAction * seprAction = menu.addAction(tr("分离")); - connect(seprAction,&QAction::triggered,[=](){ - if(aimsgList.size() != 0) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含智能告警,无法分离!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; - } - if(msgList.size() <= 0) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("无原始告警,无法分离!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; - } - QString aiuuid = ""; - if(!CAlarmMsgManage::instance()->getAiuuid(msgList.at(0)->uuid_base64,aiuuid)) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; - } - //权限过滤 - if(!m_aiOptPerm) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("无此条智能告警的编辑权限!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; - } - //遍历所有原始告警 - for(int index(1);indexgetAiuuid(msgList.at(index)->uuid_base64,uuid)) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; - } - if(uuid != aiuuid) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含不同智能告警下的原始告警,无法分离!")); - QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - return ; - } - } - //拼包 - int domain_id = msgList.at(0)->domain_id; - kbd_idlfile::SIntelliAlmSepr *pkg = new kbd_idlfile::SIntelliAlmSepr(); - pkg->set_domain_id(domain_id); - for(int index(0);indexadd_raw_alm_uuid(msgList.at(index)->uuid_base64.toStdString()); - } - //发送 - CAiAlarmDataCollect::instance()->requestSeprAlm(*pkg); - pkg = NULL; - delete pkg; - }); - }else - { - ui->aiAlarmTreeView->clearSelection(); - ui->aiAlarmTreeView->setCurrentIndex(index); - } - QAction * selectAction = menu.addAction(tr("全选")); - connect(selectAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->selectAll();}); - QAction * cancleAction = menu.addAction(tr("全不选")); - connect(cancleAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->clearSelection();}); - - menu.exec(QCursor::pos()); - } -} - -void CAlarmForm::loadDeviceGroupFilterWidget() -{ - if(!m_pModel) - { - return; - } - QMap< int, QVector< QPair< QString, QString > > > locationInfos; - QMap locationMap = m_pModel->locationDescriptionMap(); - kbd_dbms::CDbApi *m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - if(m_pReadDb->open()) - { - QMap::const_iterator iter = locationMap.constBegin(); - while (iter != locationMap.constEnd()) - { - QVector< QPair< QString, QString > > dev; - - QSqlQuery query; - QString sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1;").arg(iter.key()); - if(false == m_pReadDb->execute(sqlSequenceQuery, query)) - { - LOGINFO("load device info error, dbInterface execute failed!") - } - - while(query.next()) - { - dev.append(qMakePair(query.value(0).toString(), query.value(1).toString())); - } - locationInfos.insert(iter.key(), dev); - iter++; - } - } - else - { - LOGINFO("load deviceGroup info error, database open failed!") - } - m_pReadDb->close(); - delete m_pReadDb; - m_pReadDb = NULL; - m_pDeviceModel->setupModelData(locationInfos,locationMap); - updateDeviceGroupHiddenState(); -} - -void CAlarmForm::updateDeviceGroupHiddenState() -{ - QHash listDeviceStatisticalInfo = CAlarmMsgManage::instance()->getDeviceStatisticalInfo(); - for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) - { - QModelIndex topLevelIndex = m_pDeviceModel->index(nTopLevelRow, 0); - for(int nChildRow(0); nChildRow < m_pDeviceModel->rowCount(topLevelIndex); nChildRow++) - { - CAlarmDeviceTreeItem *item = static_cast(m_pDeviceModel->index(nChildRow, 0, topLevelIndex).internalPointer()); - ui->deviceView->setRowHidden(nChildRow, topLevelIndex, !listDeviceStatisticalInfo.value(item->data(Qt::UserRole).toString(), 0)); - } - } -} - -void CAlarmForm::print0(const QString &fileName) -{ - if(!fileName.isEmpty()) - { -// QVector columnHidden; -// QVector columnWidth; -// QTableView view(ui->alarmView); -// view.setModel(m_pModel); -// for(int nIndex(0); nIndex < m_pModel->columnCount(); nIndex++) -// { -// if(ui->alarmView->isColumnHidden(nIndex)) -// { -// columnHidden.append(true); -// }else -// { -// columnHidden.append(false); -// } -// columnWidth.append(ui->alarmView->columnWidth(nIndex)); -// } - emit printExcelAlm(m_pModel,fileName); - } -} - -void CAlarmForm::print1(const QString &fileName) -{ - if(!fileName.isEmpty()) - { -// QVector columnHidden; -// QVector columnWidth; -// for(int nIndex(0); nIndex < m_treeModel->columnCount(); nIndex++) -// { -// if(ui->aiAlarmTreeView->isColumnHidden(nIndex)) -// { -// columnHidden.append(true); -// }else -// { -// columnHidden.append(false); -// } -// columnWidth.append(ui->aiAlarmTreeView->columnWidth(nIndex)); -// } - emit printExcel(m_treeModel,fileName); - } -} - -void CAlarmForm::removeAlarm0() -{ - QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList listInfo = m_pModel->getListShowAlarmInfo(); - //声明告警删除package - QMap pkgMap; //Domain-DelPkg; - int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 - int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 - foreach (QModelIndex index, modelIndexList) - { - AlarmMsgPtr info = listInfo.at(index.row()); - //< 权限过滤 - - if(!m_listLocationId.contains(info->location_id) || (!m_listRegionId.contains(info->region_id) && info->region_id != -1)) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - permSkip = 1; - continue; - } - else - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - - //删除条件 - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) - { - if(1 != unConfirmSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含未确认告警!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - unConfirmSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - unConfirmSkip = 1; - continue; - } - else - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - - //构建告警删除package - QMap::iterator it = pkgMap.find(info->domain_id); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); - pkg->set_domain_id(info->domain_id); - pkgMap[info->domain_id] = pkg; - LOGINFO("Bulid Alarm Remove MSG: %s", info->key_id_tag.toStdString().c_str()); - } - pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); - } - - //请求删除 - foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) - { - if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) - { - LOGDEBUG("请求删除原始告警失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - ui->alarmView->setFocus(); -} - -void CAlarmForm::removeAlarm1() -{ - QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList aimsgList; //选中的智能告警 - QList msgList; //选中的原始告警 - //声明智能告警删除package - QMap aipkgMap; //Domain-DelPkg; ai - QMap pkgMap; //Domain-DelPkg; alarm - int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 - int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 - foreach (QModelIndex index, modelIndexList) - { - if(!index.isValid()) - { - continue; - } - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - aimsgList.append(ptr); - } - }else - { - //忽略选中的原始告警 - if(item->parent() == m_treeModel->getItem()) - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - msgList.append(ptr); - } - } - } - } - if(aimsgList.size() <= 0 && msgList.size() <= 0) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何智能告警和未聚类的原始告警!"), QMessageBox::Ok); - return; - } - //处理原始告警 - for(int alarm(0);alarmlocation_id) || (!m_listRegionId.contains(info->region_id) && info->region_id != -1)) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - permSkip = 1; - continue; - } - else - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - //删除条件 - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) - { - if(1 != unConfirmSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含未确认告警!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - unConfirmSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - unConfirmSkip = 1; - continue; - } - else - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - //构建告警删除package - QMap::iterator it = pkgMap.find(info->domain_id); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); - pkg->set_domain_id(info->domain_id); - pkgMap[info->domain_id] = pkg; - LOGINFO("Bulid Alarm Remove MSG: %s", info->key_id_tag.toStdString().c_str()); - } - pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); - } - //处理智能告警 - for(int aialarm(0);aialarmsetObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - permSkip = 1; - continue; - } - else - { - qDeleteAll(aipkgMap); - aipkgMap.clear(); - return; - } - } - else - { - continue; - } - } - if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aimsgList.at(aialarm)->uuid_base64)) - { - if(1 != unConfirmSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("包含未确认原始告警告警!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - unConfirmSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - unConfirmSkip = 1; - continue; - } - else - { - qDeleteAll(aipkgMap); - aipkgMap.clear(); - return; - } - } - else - { - continue; - } - } - int domain_id = aimsgList.at(aialarm)->domain_id; - QString aiuuid = aimsgList.at(aialarm)->uuid_base64; - QMap::iterator it = aipkgMap.find(domain_id); - if(it == aipkgMap.end()) - { - kbd_idlfile::SIntelliAlmDel * pkg = new kbd_idlfile::SIntelliAlmDel(); - pkg->set_domain_id(domain_id); - aipkgMap[domain_id] = pkg; - } - aipkgMap.value(domain_id)->add_uuid_base64(aiuuid.toStdString()); - } - //请求删除 - foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) - { - if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) - { - LOGDEBUG("请求删除原始告警失败!"); - } - } - qDeleteAll(pkgMap); - pkgMap.clear(); - //请求删除 - foreach (kbd_idlfile::SIntelliAlmDel * pkg, aipkgMap) - { - CAiAlarmDataCollect::instance()->requestDelAlm(*pkg); - } - qDeleteAll(aipkgMap); - aipkgMap.clear(); - ui->aiAlarmTreeView->setFocus(); -} - -void CAlarmForm::confirmAlarm0() -{ - QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList listInfo = m_pModel->getListShowAlarmInfo(); - if(listInfo.isEmpty()) - { - return; - } - - //构建告警确认package - QMap pkgMap; //Domain-DelPkg; - - int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 - foreach (QModelIndex index, modelIndexList) - { - AlarmMsgPtr info = listInfo.at(index.row()); - - //< 权限过滤 - if(!m_listLocationId.contains(info->location_id) || (!m_listRegionId.contains(info->region_id) && info->region_id != -1)) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - permSkip = 1; - continue; - } - else - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - - //告警状态 - if(E_ALS_ALARM == info->logic_state || E_ALS_RETURN == info->logic_state) - { - QString key = QString::number(info->domain_id); - QMap::iterator it = pkgMap.find(key); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); - pkg->set_node_name(m_nodeName); - pkg->set_user_id(m_userId); - pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); - pkg->set_domain_id(info->domain_id); - pkg->set_app_id(info->app_id); - pkg->set_alm_type(info->alm_type); - pkgMap[key] = pkg; - LOGINFO("Bulid Alarm Confirm MSG: %s", key.toStdString().c_str()); - } - - pkgMap.value(key)->add_key_id_tag(info->key_id_tag.toStdString()); - pkgMap.value(key)->add_time_stamp(info->time_stamp); - pkgMap.value(key)->add_uuid_base64(info->uuid_base64.toStdString()); - } - } - - //请求确认 - foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) - { - CAlarmDataCollect::instance()->requestCfmAlm(*pkg); - } - qDeleteAll(pkgMap); - pkgMap.clear(); - ui->alarmView->setFocus(); -} - -void CAlarmForm::confirmAlarm1() -{ - QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); - if(modelIndexList.isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); - return; - } - QList aimsgList; //选中的智能告警 - QList msgList; //选中的原始告警 - QList uuidList; - //构建告警确认package - QMap pkgMap; //Domain-DelPkg; - int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 - foreach (QModelIndex index, modelIndexList) - { - if(!index.isValid()) - { - continue; - } - CAiAlarmTreeItem *item = static_cast(index.internalPointer()); - if(item->isAi()) - { - AiAlarmMsgPtr ptr = NULL; - if(item->getAiPtr(ptr)) - { - aimsgList.append(ptr); - QList listPtr = item->getChildAlarmPtr(); - for(int x(0);xuuid_base64)) - { - msgList.append(listPtr.at(x)); - uuidList.append(listPtr.at(x)->uuid_base64); - } - } - } - }else - { - AlarmMsgPtr ptr = NULL; - if(item->getPtr(ptr)) - { - msgList.append(ptr); - uuidList.append(ptr->uuid_base64); - } - } - } - for(int alarmNum(0);alarmNumlocation_id) || (!m_listRegionId.contains(msgList.at(alarmNum)->region_id) && msgList.at(alarmNum)->region_id != -1)) - { - if(1 != permSkip) - { - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setObjectName("msgbox"); - msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox->setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox->addButton(tr("取消"), QMessageBox::RejectRole); - msgBox->setDefaultButton(skip); - msgBox->exec(); - if (msgBox->clickedButton() == skip) - { - permSkip = 0; - continue; - } - else if (msgBox->clickedButton() == skipAll) - { - permSkip = 1; - continue; - } - else - { - qDeleteAll(pkgMap); - pkgMap.clear(); - return; - } - } - else - { - continue; - } - } - if(E_ALS_ALARM == msgList.at(alarmNum)->logic_state || E_ALS_RETURN == msgList.at(alarmNum)->logic_state || - E_ALS_ALARM_DEL == msgList.at(alarmNum)->logic_state || E_ALS_RETURN_DEL == msgList.at(alarmNum)->logic_state) - { - QString key = QString(msgList.at(alarmNum)->domain_id); - QMap::iterator it= pkgMap.find(key); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); - pkg->set_node_name(m_nodeName); - pkg->set_user_id(m_userId); - pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); - pkg->set_domain_id(msgList.at(alarmNum)->domain_id); - pkg->set_app_id(msgList.at(alarmNum)->app_id); - pkg->set_alm_type(msgList.at(alarmNum)->alm_type); - pkgMap[key] = pkg; - } - pkgMap.value(key)->add_key_id_tag(msgList.at(alarmNum)->key_id_tag.toStdString()); - pkgMap.value(key)->add_time_stamp(msgList.at(alarmNum)->time_stamp); - pkgMap.value(key)->add_uuid_base64(msgList.at(alarmNum)->uuid_base64.toStdString()); - } - } - foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) - { - CAlarmDataCollect::instance()->requestCfmAlm(*pkg); - } - qDeleteAll(pkgMap); - pkgMap.clear(); - ui->aiAlarmTreeView->setFocus(); -} +#include "CAlarmForm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ui_CAlarmForm.h" +#include "CAlarmDelegate.h" +#include "CAiAlarmDelegate.h" +#include "CAlarmItemModel.h" +#include "CAlarmFilterDialog.h" +#include "CAlarmMsgManage.h" +#include "CTableViewPrinter.h" +#include "CAlarmDataCollect.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmInhibitDialog.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmDeviceTreeItem.h" +#include "CAiAlarmTreeItem.h" +#include "CAiAlarmTreeModel.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "dbms/db_sysinfo_api/CDbSysInfo.h" +#include +#include +#include "CMyListWidget.h" +#include "CMyCheckBox.h" +#include "CDisposalPlanDialog.h" +#include "CTreeViewPrinter.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileUtil.h" +#include +CAlarmForm::CAlarmForm(QWidget *parent) : + QWidget(parent), + m_pModel(Q_NULLPTR), + m_treeModel(Q_NULLPTR), + m_delegate(Q_NULLPTR), + m_aiDelegate(Q_NULLPTR), + m_aiOptPerm(true), + m_enableAi(false), + ui(new Ui::CAlarmForm) +{ + qRegisterMetaType("QItemSelection"); + qRegisterMetaType< QList > >("QList >"); + qRegisterMetaType >("QVector"); + qRegisterMetaType >("QVector"); + qRegisterMetaType >("QVector"); + ui->setupUi(this); + ui->alarmView->setObjectName("alarmView"); + ui->splitter->setStretchFactor(0,1); + ui->splitter->setStretchFactor(1,6); + + QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->deviceView->header()); + m_pSearchTextEdit = new QLineEdit(ui->deviceView->header()); + m_pSearchTextEdit->setObjectName("searchTextEdit"); + m_pSearchTextEdit->setTextMargins(0, 0, 21, 0); + pHBoxLayout->addWidget(m_pSearchTextEdit); + pHBoxLayout->setContentsMargins(2,0,2,0); + pHBoxLayout->setSpacing(0); + ui->deviceView->header()->setLayout(pHBoxLayout); + ui->deviceView->header()->setFixedHeight(36); + + m_pSearchButton = new QPushButton(this); + m_pSearchButton->setObjectName("searchButton"); + m_pSearchButton->setText(""); + m_pSearchButton->setMaximumSize(21, 22); + m_pSearchButton->setCursor(QCursor(Qt::ArrowCursor)); + + QHBoxLayout * pSearchLayout = new QHBoxLayout(); + pSearchLayout->setContentsMargins(1, 1, 1, 1); + pSearchLayout->addStretch(); + pSearchLayout->addWidget(m_pSearchButton); + m_pSearchTextEdit->setLayout(pSearchLayout); + + connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CAlarmForm::searchDeviceName); + connect(m_pSearchButton, &QPushButton::clicked, this, &CAlarmForm::searchDeviceName); + //initialize(); + m_pListWidget1 = new CMyListWidget(this); + m_pListWidget2 = new CMyListWidget(this); + m_pListWidget3 = new CMyListWidget(this); + m_pLineEdit1 = new QLineEdit(this); + m_pLineEdit2 = new QLineEdit(this); + m_pLineEdit3 = new QLineEdit(this); + m_timeIcon = new QPushButton(this); + //时间过滤 + m_myCalendar = new CMyCalendar(this); + QWidgetAction *widgetAction=new QWidgetAction(this); + m_timeMenu = new QMenu(this); + widgetAction->setDefaultWidget(m_myCalendar); + m_timeMenu->addAction(widgetAction); + m_timeIcon->setObjectName("iconButton"); + m_timeIcon->setText(""); + m_timeIcon->setMaximumSize(21, 22); + m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_timeIcon); + ui->lineEdit->setLayout(pTimeLayout); + connect(m_timeIcon,&QPushButton::clicked,this,&CAlarmForm::myCalendarShow); + connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CAlarmForm::myCalendarHide); + connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CAlarmForm::cancleTimeFilter); + ui->lineEdit->setText(tr("请选择时间")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit->setObjectName("iconLineEdit"); + + m_pdfPrinter = new CPdfPrinter(); + m_thread = new QThread(); + m_pdfPrinter->moveToThread(m_thread); + connect(m_thread,&QThread::started,m_pdfPrinter,&CPdfPrinter::initialize); + connect(m_thread,&QThread::finished,m_pdfPrinter,&CPdfPrinter::deleteLater); + connect(this,&CAlarmForm::printExcel,m_pdfPrinter,&CPdfPrinter::printerByModel); + connect(this,&CAlarmForm::printExcelAlm,m_pdfPrinter,&CPdfPrinter::printerAlmByModel); + connect(m_pdfPrinter,&CPdfPrinter::printResult,this,&CAlarmForm::printMess); + m_thread->start(); +} + +CAlarmForm::~CAlarmForm() +{ + removeInhibitAlarm(m_listInhibitAlarm); + if(m_delegate) + { + delete m_delegate; + } + m_delegate = Q_NULLPTR; + + if(m_aiDelegate) + { + delete m_aiDelegate; + } + m_aiDelegate = Q_NULLPTR; + delete m_pdfPrinter; + m_thread->quit(); + m_thread->wait(); + delete ui; + LOGDEBUG("CAlarmForm::~CAlarmForm()"); + qDebug() << "~CAlarmForm()"; +} + +void CAlarmForm::initialize() +{ + m_pDeviceModel = new CAlarmDeviceTreeModel(this); + ui->deviceView->setModel(m_pDeviceModel); + connect(ui->checkBox,SIGNAL(stateChanged(int)),this,SLOT(slot_changePage(int))); + connect(ui->filter, SIGNAL(clicked()), this, SLOT(updateFilter())); + connect(ui->remove, SIGNAL(clicked()), this, SLOT(slot_removeAlarm())); + connect(ui->confirm, SIGNAL(clicked()), this, SLOT(slot_confirmAlarm())); + + connect(ui->inhibit, SIGNAL(clicked()), this, SLOT(slot_showInhibitAlarm())); + + connect(ui->print, SIGNAL(clicked()), this, SLOT(print())); + connect(ui->closeBtn, &QPushButton::clicked, this, &CAlarmForm::closeBtnClicked); + updateAlarmOperatePerm(); + + //< lingdaoyaoqiu + { + QSettings columFlags("KBD_HMI", "alarm config"); + if(!columFlags.contains(QString("alarm/colum_0"))) + { + columFlags.setValue(QString("alarm/colum_0"), false); //< 时间 + columFlags.setValue(QString("alarm/colum_1"), false); //< 优先级 + columFlags.setValue(QString("alarm/colum_2"), false); //< 位置 + columFlags.setValue(QString("alarm/colum_3"), true); //< 责任区 + columFlags.setValue(QString("alarm/colum_4"), true); //< 告警类型 + columFlags.setValue(QString("alarm/colum_5"), false); //< 告警状态 + columFlags.setValue(QString("alarm/colum_6"), false); //< 确认状态 + columFlags.setValue(QString("alarm/colum_7"), false); //< + } + } + loadConfig(); + ui->checkBox->setChecked(m_enableAi); +} + +void CAlarmForm::loadConfig() +{ + QFile file(kbd_public::CFileUtil::getPathOfCfgFile("intelli_alm_cfg.xml",CN_DIR_PLATFORM).c_str()); + if (!file.open(QFile::ReadWrite)) + { + LOGERROR("打开智能告警配置文件失败,默认不启动"); + return; + } + + QDomDocument doc; + if (!doc.setContent(&file)) + { + file.close(); + LOGERROR("加载智能告警配置文件失败,默认不启动"); + return; + } + file.close(); + + QDomElement root = doc.documentElement(); //返回根节点 root + QDomNode node = root.firstChild(); //获得第一个子节点 + + while (!node.isNull()) //如果节点不空 + { + QDomElement element = node.toElement(); + if(element.tagName() == "intelli_alm_srv") + { + if(element.attribute("enable") == "true") + { + m_enableAi =true; + }else + { + m_enableAi =false; + } + break; + } + node = node.nextSibling(); + } +} + +void CAlarmForm::updateAlarmOperatePerm() +{ + m_listRegionId.clear(); + m_listLocationId.clear(); + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + m_nodeName = stNodeInfo.strName; + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(PERM_NORMAL != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + m_userId = -1; + LOGERROR("用户ID获取失败!"); + return; + } + std::vector vecRegionId; + std::vector vecLocationId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionId, vecLocationId)) + { + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listRegionId.append(*region++); + } + + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listLocationId.append(*location++); + } + } + std::string str = "FUNC_NOM_IA_EDIT"; + if(PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF,&str)) + { + m_aiOptPerm = false; + LOGERROR("无智能告警编辑权限"); + }else + { + m_aiOptPerm = true; + } + } +} + +void CAlarmForm::setAlarmOperateEnable(const bool &bEnable) +{ + ui->confirm->setEnabled(bEnable); + ui->remove->setEnabled(bEnable); +} + +void CAlarmForm::setColumnWidth(const int &column, const int &width) +{ + if(ui->alarmView != Q_NULLPTR) + { + ui->alarmView->setColumnWidth(column, width); + } +} + +void CAlarmForm::initFilter() +{ + QMap priority = m_pModel->priorityDescriptionMap(); + QMap location = m_pModel->locationDescriptionMap(); + QMap alarmType = m_pModel->alarmTypeDescriptionMap(); + for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); + pItem->setData(Qt::UserRole, it1.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it1.value()); + m_pListWidget1->addItem(pItem); + m_pListWidget1->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); + } + ui->comboBox->setModel(m_pListWidget1->model()); + ui->comboBox->setView(m_pListWidget1); + ui->comboBox->setLineEdit(m_pLineEdit1); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + m_pLineEdit1->setReadOnly(true); + connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 + for(QMap::iterator it2 = location.begin();it2 != location.end();++it2) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); + pItem->setData(Qt::UserRole, it2.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it2.value()); + m_pListWidget2->addItem(pItem); + m_pListWidget2->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); + } + ui->comboBox_2->setModel(m_pListWidget2->model()); + ui->comboBox_2->setView(m_pListWidget2); + ui->comboBox_2->setLineEdit(m_pLineEdit2); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + m_pLineEdit2->setReadOnly(true); + connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); + for(QMap::iterator it3 = alarmType.begin();it3 != alarmType.end();++it3) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); + pItem->setData(Qt::UserRole, it3.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it3.value()); + m_pListWidget3->addItem(pItem); + m_pListWidget3->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); + } + ui->comboBox_3->setModel(m_pListWidget3->model()); + ui->comboBox_3->setView(m_pListWidget3); + ui->comboBox_3->setLineEdit(m_pLineEdit3); + m_strText3 = tr("请选择告警类型"); + m_pLineEdit3->setText(tr("请选择告警类型")); + m_pLineEdit3->setReadOnly(true); + connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); +} + +void CAlarmForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) +{ + if(isLevelFilter == true && listLevel.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget1->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLevel.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText1 = strText; + m_pLineEdit1->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget1->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } +} + +void CAlarmForm::setLocationComboBox(bool &isLocationFilter,QList &listLocation) +{ + if(isLocationFilter == true && listLocation.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLocation.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText2 = strText; + m_pLineEdit2->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } +} + +void CAlarmForm::setAlarmTypeComboBox(bool &isAlarmTypeFilter, QList &listAlarmType) +{ + if(isAlarmTypeFilter == true && listAlarmType.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listAlarmType.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText3 = strText; + m_pLineEdit3->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText3 = tr("请选择告警类型"); + m_pLineEdit3->setText(tr("请选择告警类型")); + } +} + +void CAlarmForm::setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) +{ + if(isTimeFilter == true) + { + ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); + }else + { + ui->lineEdit->setText(tr("请选择时间")); + } +} + +void CAlarmForm::setAlarmModel(CAlarmItemModel *model) +{ + m_pModel = model; + m_delegate = new CAlarmDelegate(m_pModel, ui->alarmView); + connect(m_delegate,&CAlarmDelegate::openVideo,CAlarmMsgManage::instance(),&CAlarmMsgManage::openVideoDialog,Qt::QueuedConnection); + ui->alarmView->initialize(); + ui->alarmView->setItemDelegate(m_delegate); + ui->alarmView->setModel(m_pModel); + + //< 性能损耗 + //connect(ui->alarmView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(slot_selectionChanged()), Qt::QueuedConnection); + connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); + ui->confirm->setEnabled(true); + ui->remove->setEnabled(true); + + + //原始告警窗 + + ui->alarmView->setColumnWidth(0, 230); + ui->alarmView->setColumnWidth(1, 120); + ui->alarmView->setColumnWidth(2, 150); + ui->alarmView->setColumnWidth(5, 150); + ui->alarmView->setColumnWidth(6, 120); + + ui->alarmView->horizontalHeader()->setSortIndicator(1, Qt::AscendingOrder); + QSettings columFlags("KBD_HMI", "alarm config"); + for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount(); nColumnIndex++) + { + bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); + ui->alarmView->setColumnHidden(nColumnIndex, visible); + } + // ui->stackedWidget->setCurrentIndex(0); + ui->checkBox->setHidden(true); + //智能告警窗 + if(m_enableAi) + { + ui->aiAlarmTreeView->initialize(); + m_treeModel = new CAiAlarmTreeModel(this); + m_aiDelegate = new CAiAlarmDelegate(m_treeModel,ui->aiAlarmTreeView); + ui->aiAlarmTreeView->setItemDelegate(m_aiDelegate); + ui->aiAlarmTreeView->setModel(m_treeModel); + connect(m_aiDelegate,&CAiAlarmDelegate::openVideo,CAlarmMsgManage::instance(),&CAlarmMsgManage::openVideoDialog,Qt::QueuedConnection); + connect(ui->aiAlarmTreeView->header(),&QHeaderView::sortIndicatorChanged, m_treeModel,&CAiAlarmTreeModel::sortColumn); + connect(ui->aiAlarmTreeView,&CAiAlarmTreeView::doubleClicked, this,&CAlarmForm::aiAlmDoubleClicked); + + ui->aiAlarmTreeView->setColumnWidth(0, 230); + ui->aiAlarmTreeView->setColumnWidth(1, 120); + ui->aiAlarmTreeView->setColumnWidth(2, 150); + ui->aiAlarmTreeView->setColumnWidth(5, 150); + ui->aiAlarmTreeView->setColumnWidth(6, 120); + + + ui->aiAlarmTreeView->header()->setSortIndicator(1, Qt::AscendingOrder); + for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount(); nColumnIndex++) + { + bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, visible); + } + // ui->stackedWidget->setCurrentIndex(1); + ui->checkBox->setHidden(false); + } + + + loadDeviceGroupFilterWidget(); + if(m_pDeviceModel) + { + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); + } + initFilter(); +} + +void CAlarmForm::updateView() +{ + m_pModel->updateAlternate(); + updateDeviceGroupHiddenState(); + ui->alarmView->viewport()->update(); + if(m_enableAi) + { + ui->aiAlarmTreeView->viewport()->update(); + } + updateRowTips(); +} + +void CAlarmForm::updateFilter() +{ + bool isLevelFilter; + QList levelFilter; + bool isLocationFilter; + QList locationFilter; + bool isRegionFilter; + QList regionFilter; + bool isAlarmTypeFilter; //告警状态过滤 + QList typeFilter; + bool deviceTypeFilter; + QString subSystem; + QString deviceType; + bool keywordFilter; + QString keyword; + bool isTimeFilterEnable; + QDateTime startTime; + QDateTime endTime; + bool isStateFilterEnable; + bool isConfirm; + + CAlarmFilterDialog filterDlg; + filterDlg.setPriorityDescription(m_pModel->priorityDescriptionMap()); + filterDlg.setLocationDescription(m_pModel->locationDescriptionMap()); + filterDlg.setRegionDescription(m_pModel->regionDescriptionMap()); + filterDlg.setAlarmTypeDescription(m_pModel->alarmTypeDescriptionMap()); + m_pModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmTypeFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime, + isStateFilterEnable, isConfirm); + filterDlg.initialize(); + filterDlg.setLevelFilterEnable(isLevelFilter); + filterDlg.setLevelFilter(levelFilter); + filterDlg.setLocationFilterEnable(isLocationFilter); + filterDlg.setLocationFilter(locationFilter); + filterDlg.setRegionFilterEnable(isRegionFilter); + filterDlg.setRegionFilter(regionFilter); + filterDlg.setAlarmTypeFilterEnable(isAlarmTypeFilter); + filterDlg.setAlarmTypeFilter(typeFilter); + filterDlg.setDeviceFilterEnable(deviceTypeFilter); + filterDlg.setSubSystem(subSystem); + filterDlg.setDeviceType(deviceType); + filterDlg.setkeyWordFilterEnable(keywordFilter); + filterDlg.setkeyWordFilteContent(keyword); + filterDlg.setTimeFilterEnable(isTimeFilterEnable); + filterDlg.setStartTimeFilter(startTime); + filterDlg.setEndTimeFilter(endTime); + filterDlg.setStateFilterEnable(isStateFilterEnable); + filterDlg.setStateFilter(isConfirm); + connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool)), + this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool))); + filterDlg.exec(); +} + +void CAlarmForm::deviceGroupFilterChanged(const QString &device, const bool &checked) +{ + if(checked) + { + m_pModel->removeDeviceGroupFilter(device); + if(m_enableAi) + { + m_treeModel->removeDeviceGroupFilter(device); + } + } + else + { + m_pModel->addDeviceGroupFilter(device); + if(m_enableAi) + { + m_treeModel->addDeviceGroupFilter(device); + } + } +} + +void CAlarmForm::slot_changePage(int i) +{ + Q_UNUSED(i) + if(!ui->checkBox->isChecked()) + { + ui->stackedWidget->setCurrentIndex(0); + }else + { + ui->stackedWidget->setCurrentIndex(1); + } +} + +void CAlarmForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmType, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm) +{ + m_pModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm); + if(m_enableAi) + { + m_treeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm); + } + + //设置下拉框的值 + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setAlarmTypeComboBox(isAlarmTypeFilter,listAlarmType); + setAlarmTimeLineEdit(isTimeFilter, startTime, endTime); +} + +void CAlarmForm::slot_removeAlarm() +{ + updateAlarmOperatePerm(); + if(!ui->checkBox->isChecked()) + { + removeAlarm0(); + }else + { + removeAlarm1(); + } +} + +void CAlarmForm::slot_confirmAlarm() +{ + updateAlarmOperatePerm(); + if(!ui->checkBox->isChecked()) + { + confirmAlarm0(); + }else + { + confirmAlarm1(); + } +} + +void CAlarmForm::slot_showInhibitAlarm() +{ + CAlarmInhibitDialog dlg; + dlg.setPriorityDescriptionMap(m_pModel->priorityDescriptionMap()); + dlg.setLocationDescriptionMap(m_pModel->locationDescriptionMap()); + dlg.setRegionDescriptionMap(m_pModel->regionDescriptionMap()); + dlg.setAlarmTypeDescriptionMap(m_pModel->alarmTypeDescriptionMap()); + dlg.setDeviceTypeDescriptionMap(m_pModel->deviceTypeDescriptionMap()); + dlg.setInhibitAlarmList(m_listInhibitAlarm); + connect(&dlg, &CAlarmInhibitDialog::removeInhibitAlarmList, this, &CAlarmForm::removeInhibitAlarm); + dlg.exec(); + +} + +void CAlarmForm::removeInhibitAlarm(QList alarmList) +{ + foreach (AlarmMsgPtr alm, alarmList) + { + m_listInhibitAlarm.removeAll(alm); + CAlarmMsgManage::instance()->removeInhibitTag(alm->key_id_tag); + } +} + +void CAlarmForm::searchDeviceName() +{ + QItemSelection selection; + QString content = m_pSearchTextEdit->text(); + ui->deviceView->selectionModel()->select(selection, QItemSelectionModel::Clear); + if(content.isEmpty()) + { + return; + } + const QHash< QString, QModelIndex > &indexNameList = m_pDeviceModel->indexNameList(); + QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); + while (iter != indexNameList.constEnd()) + { + qDebug()<deviceView->selectionModel()->select(selection, QItemSelectionModel::Select); +} + +void CAlarmForm::updateRowTips() +{ + if(!ui->checkBox->isChecked()) + { + if(m_pModel) + { + ui->showRow->setText(QString::number(m_pModel->rowCount())); + int nNumber = m_pModel->filterCount(); + if(nNumber<0) nNumber = 0 ; + ui->filterRow->setText(QString::number(nNumber)); + } + } + else + { + if(m_treeModel) + { + int showNum = m_treeModel->getShowNum(); + int showAiNum = m_treeModel->getShowAi(); + int showTotal = CAlarmMsgManage::instance()->getAlmTotal(); + ui->showRow->setText(QString("%1/%2").arg(showNum).arg(showAiNum)); + int nNumber = showTotal - showNum; + if(nNumber<0) nNumber = 0 ; + ui->filterRow->setText(QString::number(nNumber)); + } + } +} + +void CAlarmForm::print() +{ + //QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); + QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xlsx)");//获取保存路径*.xls + if(!ui->checkBox->isChecked()) + { + print0(fileName); + }else + { + print1(fileName); + } +} + +void CAlarmForm::stateChanged1(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_priorityList.clear(); + int nCount = m_pListWidget1->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_priorityList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText1 = strText; + m_pLineEdit1->setText(strText); + } + else + { + m_pLineEdit1->clear(); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } + bool isCheck = false; + if(m_priorityList.size() > 0) + { + isCheck = true; + } + m_pModel->setPriorityFilter(isCheck,m_priorityList); + if(m_enableAi) + { + m_treeModel->setPriorityFilter(isCheck,m_priorityList); + } +} + +void CAlarmForm::stateChanged2(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_locationList.clear(); + int nCount = m_pListWidget2->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_locationList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText2 = strText; + m_pLineEdit2->setText(strText); + } + else + { + m_pLineEdit2->clear(); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } + bool isCheck = false; + if(m_locationList.size() > 0) + { + isCheck = true; + } + m_pModel->setLocationFilter(isCheck,m_locationList); + if(m_enableAi) + { + m_treeModel->setLocationFilter(isCheck,m_locationList); + } +} + +void CAlarmForm::stateChanged3(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_alarmTypeList.clear(); + bool other = false; + int nCount = m_pListWidget3->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + if(nData == 0) + { + other = true; + } + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_alarmTypeList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText3 = strText; + m_pLineEdit3->setText(strText); + } + else + { + m_pLineEdit3->clear(); + m_strText3 = tr("请选择告警类型"); + m_pLineEdit3->setText(tr("请选择告警类型")); + } + bool isCheck = false; + if(m_alarmTypeList.size() > 0) + { + isCheck = true; + } + m_pModel->setAlarmTypeFilter(isCheck,m_alarmTypeList); + if(m_enableAi) + { + m_treeModel->setAlarmTypeFilter(isCheck,m_alarmTypeList); + } +} + +void CAlarmForm::textChanged1(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit1->setText(m_strText1); +} + +void CAlarmForm::textChanged2(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit2->setText(m_strText2); +} + +void CAlarmForm::textChanged3(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit3->setText(m_strText3); +} + +void CAlarmForm::myCalendarHide(QDate startTime,QDate endTime) +{ + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); + //开始过滤 + bool isCheck = true; + m_pModel->setAlarmTimeFilter(isCheck,startTime,endTime); + if(m_enableAi) + { + m_treeModel->setAlarmTimeFilter(isCheck,startTime,endTime); + } + m_timeMenu->hide(); +} + +void CAlarmForm::myCalendarShow() +{ + QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); + m_timeMenu->move(point); + m_timeMenu->show(); +} + +void CAlarmForm::cancleTimeFilter() +{ + ui->lineEdit->setText(tr("请选择时间")); + //取消过滤 + bool isCheck = false; + m_pModel->setAlarmTimeFilter(isCheck); + if(m_enableAi) + { + m_treeModel->setAlarmTimeFilter(isCheck); + } + m_timeMenu->hide(); +} + +void CAlarmForm::aiAlmDoubleClicked(const QModelIndex &index) +{ + if(m_treeModel == NULL) + { + return ; + } + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item =static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr aiPtr; + if(item->getAiPtr(aiPtr)) + { + CDisposalPlanDialog dialog(aiPtr); + dialog.exec(); + }else + { + LOGERROR("aiAlmDoubleClicked():标识符错误!"); + } + } +} + +void CAlarmForm::printMess(QString fileName) +{ + QMessageBox::information( 0, tr("提示"), tr("导出成功")); +} + +void CAlarmForm::contextMenuEvent(QContextMenuEvent *event) +{ + updateAlarmOperatePerm(); + if(ui->stackedWidget->currentIndex() == 0) + { + contextMenuStack0Event(event); + }else if(ui->stackedWidget->currentIndex() == 1) + { + contextMenuStack1Event(event); + } +} + +void CAlarmForm::contextMenuStack0Event(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(!m_pModel) + { + return; + } + if(event->pos().x() < ui->alarmView->pos().x()) + { + return; + } + QRect headerRect = ui->alarmView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->alarmView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + + for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->alarmView->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags("KBD_HMI", "alarm config"); + columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + columnMenu.exec(QCursor::pos()); + } + else + { + QModelIndex index = ui->alarmView->indexAt(ui->alarmView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index.isValid()) + { + return; + } + AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); + ui->alarmView->clearSelection(); + ui->alarmView->selectRow(index.row()); + QMenu menu(this); + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction, &QAction::triggered, [=](){ui->alarmView->selectAll();}); + + QAction * InhibitAction = menu.addAction(tr("禁止告警")); + connect(InhibitAction, &QAction::triggered, [=](){ + bool isContains = false; + foreach (AlarmMsgPtr alarm, m_listInhibitAlarm) + { + if(alarm->key_id_tag == alm->key_id_tag) + { + isContains = true; + break; + } + } + if(isContains) + { + QMessageBox::warning(this, tr("警告"), tr("当前测点告警已禁止,无需重复禁止!"), QMessageBox::Ok); + } + else + { + m_listInhibitAlarm.append(alm); + CAlarmMsgManage::instance()->addInhibitTag(alm->key_id_tag); + } + }); + menu.exec(QCursor::pos()); + } +} + +void CAlarmForm::contextMenuStack1Event(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(!m_treeModel) + { + return; + } + if(event->pos().x() < ui->aiAlarmTreeView->pos().x()) + { + return; + } + QRect headerRect = ui->aiAlarmTreeView->header()->rect(); + headerRect.moveTopLeft(ui->aiAlarmTreeView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + + for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_treeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->aiAlarmTreeView->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags("KBD_HMI", "alarm config"); + columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + columnMenu.exec(QCursor::pos()); + }else + { + QMenu menu(this); + QModelIndex index_ = ui->aiAlarmTreeView->indexAt(ui->aiAlarmTreeView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + QModelIndexList indexLists = ui->aiAlarmTreeView->selectionModel()->selectedIndexes(); + QList aimsgList; + QList msgList; + + foreach (QModelIndex modelIndex, indexList) + { + if(!modelIndex.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + } + } + } + //判断右键位置是否在选中区 + if(indexLists.contains(index)) + { + QAction * mergeAction = menu.addAction(tr("合并")); + connect(mergeAction,&QAction::triggered,[=](){ + QMap pkgMap; + QList listPtr; + listPtr.clear(); + int permSkip = -1; + if(aimsgList.size() > 0) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含智能告警,无法合并!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; + } + + for(int alarmIndex(0);alarmIndex < msgList.size();alarmIndex++) + { + if(msgList.at(alarmIndex) != NULL) + { + //判断此原始告警是否已经被聚类 + if(CAlarmMsgManage::instance()->isBelongAi(msgList.at(alarmIndex)->uuid_base64)) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含已经聚类的原始告警,无法合并!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; + } + //判断权限 + if(!m_aiOptPerm) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户无此条原始告警合并权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + permSkip = 1; + continue; + } + else + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + }else + { + listPtr.append(msgList.at(alarmIndex)); + } + } + } + //过滤后等于0直接返回 + if(listPtr.size() <= 0) + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return ; + } + for(int x(0);xdomain_id; + QMap::iterator it = pkgMap.find(domain_id); + if( it == pkgMap.end()) + { + kbd_idlfile::SIntelliAlmMerge *pkg =new kbd_idlfile::SIntelliAlmMerge(); + pkg->set_domain_id(domain_id); + pkgMap[domain_id] = pkg; + } + pkgMap.value(domain_id)->add_raw_alm_uuid(listPtr.at(x)->uuid_base64.toStdString()); + } + if(pkgMap.size() != 1) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含不同域的原始告警,无法合并!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + qDeleteAll(pkgMap); + pkgMap.clear(); + return ; + } + foreach (kbd_idlfile::SIntelliAlmMerge * pkg, pkgMap) + { + CAiAlarmDataCollect::instance()->requestMergeAlm(*pkg); + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); + }); + QAction * seprAction = menu.addAction(tr("分离")); + connect(seprAction,&QAction::triggered,[=](){ + if(aimsgList.size() != 0) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含智能告警,无法分离!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; + } + if(msgList.size() <= 0) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("无原始告警,无法分离!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; + } + QString aiuuid = ""; + if(!CAlarmMsgManage::instance()->getAiuuid(msgList.at(0)->uuid_base64,aiuuid)) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; + } + //权限过滤 + if(!m_aiOptPerm) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("无此条智能告警的编辑权限!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; + } + //遍历所有原始告警 + for(int index(1);indexgetAiuuid(msgList.at(index)->uuid_base64,uuid)) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; + } + if(uuid != aiuuid) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含不同智能告警下的原始告警,无法分离!")); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; + } + } + //拼包 + int domain_id = msgList.at(0)->domain_id; + kbd_idlfile::SIntelliAlmSepr *pkg = new kbd_idlfile::SIntelliAlmSepr(); + pkg->set_domain_id(domain_id); + for(int index(0);indexadd_raw_alm_uuid(msgList.at(index)->uuid_base64.toStdString()); + } + //发送 + CAiAlarmDataCollect::instance()->requestSeprAlm(*pkg); + pkg = NULL; + delete pkg; + }); + }else + { + ui->aiAlarmTreeView->clearSelection(); + ui->aiAlarmTreeView->setCurrentIndex(index); + } + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->selectAll();}); + QAction * cancleAction = menu.addAction(tr("全不选")); + connect(cancleAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->clearSelection();}); + + menu.exec(QCursor::pos()); + } +} + +void CAlarmForm::loadDeviceGroupFilterWidget() +{ + if(!m_pModel) + { + return; + } + QMap< int, QVector< QPair< QString, QString > > > locationInfos; + QMap locationMap = m_pModel->locationDescriptionMap(); + kbd_dbms::CDbApi *m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + if(m_pReadDb->open()) + { + QMap::const_iterator iter = locationMap.constBegin(); + while (iter != locationMap.constEnd()) + { + QVector< QPair< QString, QString > > dev; + + QSqlQuery query; + QString sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1;").arg(iter.key()); + if(false == m_pReadDb->execute(sqlSequenceQuery, query)) + { + LOGINFO("load device info error, dbInterface execute failed!") + } + + while(query.next()) + { + dev.append(qMakePair(query.value(0).toString(), query.value(1).toString())); + } + locationInfos.insert(iter.key(), dev); + iter++; + } + } + else + { + LOGINFO("load deviceGroup info error, database open failed!") + } + m_pReadDb->close(); + delete m_pReadDb; + m_pReadDb = NULL; + m_pDeviceModel->setupModelData(locationInfos,locationMap); + updateDeviceGroupHiddenState(); +} + +void CAlarmForm::updateDeviceGroupHiddenState() +{ + QHash listDeviceStatisticalInfo = CAlarmMsgManage::instance()->getDeviceStatisticalInfo(); + for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) + { + QModelIndex topLevelIndex = m_pDeviceModel->index(nTopLevelRow, 0); + for(int nChildRow(0); nChildRow < m_pDeviceModel->rowCount(topLevelIndex); nChildRow++) + { + CAlarmDeviceTreeItem *item = static_cast(m_pDeviceModel->index(nChildRow, 0, topLevelIndex).internalPointer()); + ui->deviceView->setRowHidden(nChildRow, topLevelIndex, !listDeviceStatisticalInfo.value(item->data(Qt::UserRole).toString(), 0)); + } + } +} + +void CAlarmForm::print0(const QString &fileName) +{ + if(!fileName.isEmpty()) + { +// QVector columnHidden; +// QVector columnWidth; +// QTableView view(ui->alarmView); +// view.setModel(m_pModel); +// for(int nIndex(0); nIndex < m_pModel->columnCount(); nIndex++) +// { +// if(ui->alarmView->isColumnHidden(nIndex)) +// { +// columnHidden.append(true); +// }else +// { +// columnHidden.append(false); +// } +// columnWidth.append(ui->alarmView->columnWidth(nIndex)); +// } + emit printExcelAlm(m_pModel,fileName); + } +} + +void CAlarmForm::print1(const QString &fileName) +{ + if(!fileName.isEmpty()) + { +// QVector columnHidden; +// QVector columnWidth; +// for(int nIndex(0); nIndex < m_treeModel->columnCount(); nIndex++) +// { +// if(ui->aiAlarmTreeView->isColumnHidden(nIndex)) +// { +// columnHidden.append(true); +// }else +// { +// columnHidden.append(false); +// } +// columnWidth.append(ui->aiAlarmTreeView->columnWidth(nIndex)); +// } + emit printExcel(m_treeModel,fileName); + } +} + +void CAlarmForm::removeAlarm0() +{ + QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + //声明告警删除package + QMap pkgMap; //Domain-DelPkg; + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 + foreach (QModelIndex index, modelIndexList) + { + AlarmMsgPtr info = listInfo.at(index.row()); + //< 权限过滤 + + if(!m_listLocationId.contains(info->location_id) || (!m_listRegionId.contains(info->region_id) && info->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + permSkip = 1; + continue; + } + else + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + //删除条件 + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + unConfirmSkip = 1; + continue; + } + else + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + //构建告警删除package + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + LOGINFO("Bulid Alarm Remove MSG: %s", info->key_id_tag.toStdString().c_str()); + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + + //请求删除 + foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) + { + LOGDEBUG("请求删除原始告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->alarmView->setFocus(); +} + +void CAlarmForm::removeAlarm1() +{ + QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList aimsgList; //选中的智能告警 + QList msgList; //选中的原始告警 + //声明智能告警删除package + QMap aipkgMap; //Domain-DelPkg; ai + QMap pkgMap; //Domain-DelPkg; alarm + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 + foreach (QModelIndex index, modelIndexList) + { + if(!index.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + } + }else + { + //忽略选中的原始告警 + if(item->parent() == m_treeModel->getItem()) + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + } + } + } + } + if(aimsgList.size() <= 0 && msgList.size() <= 0) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何智能告警和未聚类的原始告警!"), QMessageBox::Ok); + return; + } + //处理原始告警 + for(int alarm(0);alarmlocation_id) || (!m_listRegionId.contains(info->region_id) && info->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + permSkip = 1; + continue; + } + else + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + //删除条件 + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + unConfirmSkip = 1; + continue; + } + else + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + //构建告警删除package + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + LOGINFO("Bulid Alarm Remove MSG: %s", info->key_id_tag.toStdString().c_str()); + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + //处理智能告警 + for(int aialarm(0);aialarmsetObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + permSkip = 1; + continue; + } + else + { + qDeleteAll(aipkgMap); + aipkgMap.clear(); + return; + } + } + else + { + continue; + } + } + if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aimsgList.at(aialarm)->uuid_base64)) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认原始告警告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + unConfirmSkip = 1; + continue; + } + else + { + qDeleteAll(aipkgMap); + aipkgMap.clear(); + return; + } + } + else + { + continue; + } + } + int domain_id = aimsgList.at(aialarm)->domain_id; + QString aiuuid = aimsgList.at(aialarm)->uuid_base64; + QMap::iterator it = aipkgMap.find(domain_id); + if(it == aipkgMap.end()) + { + kbd_idlfile::SIntelliAlmDel * pkg = new kbd_idlfile::SIntelliAlmDel(); + pkg->set_domain_id(domain_id); + aipkgMap[domain_id] = pkg; + } + aipkgMap.value(domain_id)->add_uuid_base64(aiuuid.toStdString()); + } + //请求删除 + foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) + { + LOGDEBUG("请求删除原始告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + //请求删除 + foreach (kbd_idlfile::SIntelliAlmDel * pkg, aipkgMap) + { + CAiAlarmDataCollect::instance()->requestDelAlm(*pkg); + } + qDeleteAll(aipkgMap); + aipkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); +} + +void CAlarmForm::confirmAlarm0() +{ + QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + if(listInfo.isEmpty()) + { + return; + } + + //构建告警确认package + QMap pkgMap; //Domain-DelPkg; + + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + foreach (QModelIndex index, modelIndexList) + { + AlarmMsgPtr info = listInfo.at(index.row()); + + //< 权限过滤 + if(!m_listLocationId.contains(info->location_id) || (!m_listRegionId.contains(info->region_id) && info->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + permSkip = 1; + continue; + } + else + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + //告警状态 + if(E_ALS_ALARM == info->logic_state || E_ALS_RETURN == info->logic_state) + { + QString key = QString::number(info->domain_id); + QMap::iterator it = pkgMap.find(key); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(info->domain_id); + pkg->set_app_id(info->app_id); + pkg->set_alm_type(info->alm_type); + pkgMap[key] = pkg; + LOGINFO("Bulid Alarm Confirm MSG: %s", key.toStdString().c_str()); + } + + pkgMap.value(key)->add_key_id_tag(info->key_id_tag.toStdString()); + pkgMap.value(key)->add_time_stamp(info->time_stamp); + pkgMap.value(key)->add_uuid_base64(info->uuid_base64.toStdString()); + } + } + + //请求确认 + foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) + { + CAlarmDataCollect::instance()->requestCfmAlm(*pkg); + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->alarmView->setFocus(); +} + +void CAlarmForm::confirmAlarm1() +{ + QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList aimsgList; //选中的智能告警 + QList msgList; //选中的原始告警 + QList uuidList; + //构建告警确认package + QMap pkgMap; //Domain-DelPkg; + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + foreach (QModelIndex index, modelIndexList) + { + if(!index.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + QList listPtr = item->getChildAlarmPtr(); + for(int x(0);xuuid_base64)) + { + msgList.append(listPtr.at(x)); + uuidList.append(listPtr.at(x)->uuid_base64); + } + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + uuidList.append(ptr->uuid_base64); + } + } + } + for(int alarmNum(0);alarmNumlocation_id) || (!m_listRegionId.contains(msgList.at(alarmNum)->region_id) && msgList.at(alarmNum)->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + permSkip = 1; + continue; + } + else + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + if(E_ALS_ALARM == msgList.at(alarmNum)->logic_state || E_ALS_RETURN == msgList.at(alarmNum)->logic_state || + E_ALS_ALARM_DEL == msgList.at(alarmNum)->logic_state || E_ALS_RETURN_DEL == msgList.at(alarmNum)->logic_state) + { + QString key = QString(msgList.at(alarmNum)->domain_id); + QMap::iterator it= pkgMap.find(key); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(msgList.at(alarmNum)->domain_id); + pkg->set_app_id(msgList.at(alarmNum)->app_id); + pkg->set_alm_type(msgList.at(alarmNum)->alm_type); + pkgMap[key] = pkg; + } + pkgMap.value(key)->add_key_id_tag(msgList.at(alarmNum)->key_id_tag.toStdString()); + pkgMap.value(key)->add_time_stamp(msgList.at(alarmNum)->time_stamp); + pkgMap.value(key)->add_uuid_base64(msgList.at(alarmNum)->uuid_base64.toStdString()); + } + } + foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) + { + CAlarmDataCollect::instance()->requestCfmAlm(*pkg); + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.h index 419e59c3..e7941a70 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.h @@ -1,160 +1,160 @@ -#ifndef CALARMFORM_H -#define CALARMFORM_H - -#include -#include -#include -#include "CAlarmMsgInfo.h" -#include "CAiAlarmMsgInfo.h" -#include -#include -#include "CMyCalendar.h" -#include -#include -#include -#include -#include -namespace Ui { -class CAlarmForm; -} - -class QLineEdit; -class QPushButton; -class QTreeWidgetItem; -class CAlarmItemModel; -class CAlarmDelegate; -class CAiAlarmDelegate; -class CAlarmDeviceTreeModel; -class CAiAlarmTreeModel; -typedef QList QModelIndexList; - - -class CAlarmForm : public QWidget -{ - Q_OBJECT - -public: - explicit CAlarmForm(QWidget *parent = 0); - ~CAlarmForm(); - - void initialize(); - - void loadConfig(); - void setAlarmModel(CAlarmItemModel * model); - void updateView(); - void updateAlarmOperatePerm(); //更新原始告警权限和智能告警操作权限 - - void setAlarmOperateEnable(const bool &bEnable); - - void setColumnWidth(const int &column, const int &width); -public: - void initFilter(); - void setLevelComboBox(bool &isLevelFilter,QList &listLevel); - void setLocationComboBox(bool &isLocationFilter,QList &listLocation); - void setAlarmTypeComboBox(bool &isAlarmTypeFilter,QList &listAlarmType); - void setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); -signals: - void sigAudioCuesEnable(bool bEnable); - - void closeBtnClicked(); - - void printer(QVector header,QList > data,QString fileName,QVector columnHidden,QVector columnWidth); - void printExcel(CAiAlarmTreeModel * model,const QString fileName); - void printExcelAlm(CAlarmItemModel * model,const QString fileName); -protected slots: - void updateFilter(); - void deviceGroupFilterChanged(const QString &device, const bool &checked); - void slot_changePage(int i); - void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmType, - bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, - QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm); - - void slot_removeAlarm(); - void slot_confirmAlarm(); - - void slot_showInhibitAlarm(); - void removeInhibitAlarm(QList alarmList); - - void searchDeviceName(); - - void updateRowTips(); - - void print(); - void stateChanged1(int state); - void stateChanged2(int state); - void stateChanged3(int state); - void textChanged1(const QString &text); - void textChanged2(const QString &text); - void textChanged3(const QString &text); - void myCalendarHide(QDate startTime, QDate endTime); - void myCalendarShow(); - void cancleTimeFilter(); - - void aiAlmDoubleClicked(const QModelIndex &index); - - void printMess(QString fileName); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - - void contextMenuStack0Event(QContextMenuEvent *event); - - void contextMenuStack1Event(QContextMenuEvent *event); - - void loadDeviceGroupFilterWidget(); - - void updateDeviceGroupHiddenState(); -private: - //原始告警窗点击打印(打印原始告警) - void print0(const QString &fileName); - //智能告警窗点击打印(打印智能和原始告警) - void print1(const QString &fileName); - //原始告警窗点击删除(删除原始告警) - void removeAlarm0(); - //智能告警窗点击删除(删除智能告警) - void removeAlarm1(); - //原始告警窗点击确认(确认原始告警) - void confirmAlarm0(); - //智能告警窗点击确认(确认原始告警) - void confirmAlarm1(); -private: - QLineEdit * m_pSearchTextEdit; - QPushButton * m_pSearchButton; - QList m_listRegionId; - QList m_listLocationId; - bool m_aiOptPerm; //智能告警操作权限 - - CAlarmItemModel * m_pModel; - CAlarmDelegate * m_delegate; - CAiAlarmDelegate * m_aiDelegate; - CAlarmDeviceTreeModel * m_pDeviceModel; - CAiAlarmTreeModel *m_treeModel; - int m_userId; - std::string m_nodeName; - QList m_listInhibitAlarm; - - QListWidget *m_pListWidget1; - QListWidget *m_pListWidget2; - QListWidget *m_pListWidget3; - - QLineEdit *m_pLineEdit1; - QLineEdit *m_pLineEdit2; - QLineEdit *m_pLineEdit3; - QList m_priorityList; - QList m_locationList; - QList m_alarmTypeList; - QString m_strText1; - QString m_strText2; - QString m_strText3; - Ui::CAlarmForm *ui; - QPushButton *m_timeIcon; - - CMyCalendar * m_myCalendar; - QMenu *m_timeMenu; - - QThread *m_thread; //打印线程 - CPdfPrinter *m_pdfPrinter; - bool m_enableAi; -}; - -#endif // ALARMFORM_H +#ifndef CALARMFORM_H +#define CALARMFORM_H + +#include +#include +#include +#include "CAlarmMsgInfo.h" +#include "CAiAlarmMsgInfo.h" +#include +#include +#include "CMyCalendar.h" +#include +#include +#include +#include +#include +namespace Ui { +class CAlarmForm; +} + +class QLineEdit; +class QPushButton; +class QTreeWidgetItem; +class CAlarmItemModel; +class CAlarmDelegate; +class CAiAlarmDelegate; +class CAlarmDeviceTreeModel; +class CAiAlarmTreeModel; +typedef QList QModelIndexList; + + +class CAlarmForm : public QWidget +{ + Q_OBJECT + +public: + explicit CAlarmForm(QWidget *parent = 0); + ~CAlarmForm(); + + void initialize(); + + void loadConfig(); + void setAlarmModel(CAlarmItemModel * model); + void updateView(); + void updateAlarmOperatePerm(); //更新原始告警权限和智能告警操作权限 + + void setAlarmOperateEnable(const bool &bEnable); + + void setColumnWidth(const int &column, const int &width); +public: + void initFilter(); + void setLevelComboBox(bool &isLevelFilter,QList &listLevel); + void setLocationComboBox(bool &isLocationFilter,QList &listLocation); + void setAlarmTypeComboBox(bool &isAlarmTypeFilter,QList &listAlarmType); + void setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); +signals: + void sigAudioCuesEnable(bool bEnable); + + void closeBtnClicked(); + + void printer(QVector header,QList > data,QString fileName,QVector columnHidden,QVector columnWidth); + void printExcel(CAiAlarmTreeModel * model,const QString fileName); + void printExcelAlm(CAlarmItemModel * model,const QString fileName); +protected slots: + void updateFilter(); + void deviceGroupFilterChanged(const QString &device, const bool &checked); + void slot_changePage(int i); + void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmType, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, + QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm); + + void slot_removeAlarm(); + void slot_confirmAlarm(); + + void slot_showInhibitAlarm(); + void removeInhibitAlarm(QList alarmList); + + void searchDeviceName(); + + void updateRowTips(); + + void print(); + void stateChanged1(int state); + void stateChanged2(int state); + void stateChanged3(int state); + void textChanged1(const QString &text); + void textChanged2(const QString &text); + void textChanged3(const QString &text); + void myCalendarHide(QDate startTime, QDate endTime); + void myCalendarShow(); + void cancleTimeFilter(); + + void aiAlmDoubleClicked(const QModelIndex &index); + + void printMess(QString fileName); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + + void contextMenuStack0Event(QContextMenuEvent *event); + + void contextMenuStack1Event(QContextMenuEvent *event); + + void loadDeviceGroupFilterWidget(); + + void updateDeviceGroupHiddenState(); +private: + //原始告警窗点击打印(打印原始告警) + void print0(const QString &fileName); + //智能告警窗点击打印(打印智能和原始告警) + void print1(const QString &fileName); + //原始告警窗点击删除(删除原始告警) + void removeAlarm0(); + //智能告警窗点击删除(删除智能告警) + void removeAlarm1(); + //原始告警窗点击确认(确认原始告警) + void confirmAlarm0(); + //智能告警窗点击确认(确认原始告警) + void confirmAlarm1(); +private: + QLineEdit * m_pSearchTextEdit; + QPushButton * m_pSearchButton; + QList m_listRegionId; + QList m_listLocationId; + bool m_aiOptPerm; //智能告警操作权限 + + CAlarmItemModel * m_pModel; + CAlarmDelegate * m_delegate; + CAiAlarmDelegate * m_aiDelegate; + CAlarmDeviceTreeModel * m_pDeviceModel; + CAiAlarmTreeModel *m_treeModel; + int m_userId; + std::string m_nodeName; + QList m_listInhibitAlarm; + + QListWidget *m_pListWidget1; + QListWidget *m_pListWidget2; + QListWidget *m_pListWidget3; + + QLineEdit *m_pLineEdit1; + QLineEdit *m_pLineEdit2; + QLineEdit *m_pLineEdit3; + QList m_priorityList; + QList m_locationList; + QList m_alarmTypeList; + QString m_strText1; + QString m_strText2; + QString m_strText3; + Ui::CAlarmForm *ui; + QPushButton *m_timeIcon; + + CMyCalendar * m_myCalendar; + QMenu *m_timeMenu; + + QThread *m_thread; //打印线程 + CPdfPrinter *m_pdfPrinter; + bool m_enableAi; +}; + +#endif // ALARMFORM_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.ui b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.ui index 8212614e..b9801bc3 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.ui +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.ui @@ -1,540 +1,540 @@ - - - CAlarmForm - - - - 0 - 0 - 1316 - 631 - - - - Form - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - QFrame::Sunken - - - 0 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 6 - - - 2 - - - - - Qt::Horizontal - - - - 0 - 20 - - - - - - - - - 132 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 位置: - - - - - - - - 170 - 0 - - - - - 16777215 - 26 - - - - - - - - - 111 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 时间: - - - - - - - - 80 - 26 - - - - - 16777215 - 26 - - - - 智能告警 - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 告警类型: - - - - - - - false - - - - 45 - 26 - - - - - - - 确认 - - - - - - - - 80 - 0 - - - - - 100 - 26 - - - - 禁止告警列表 - - - - - - - - 113 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 优先级: - - - - - - - 0 - - - 2 - - - 3 - - - - - - 55 - 0 - - - - 0 - - - - - - - 过滤告警数量: - - - - - - - 当前显示数量: - - - - - - - - 55 - 0 - - - - 0 - - - - - - - - - false - - - - 45 - 26 - - - - 删除 - - - - - - - - 45 - 26 - - - - 关闭 - - - - - - - - 0 - 0 - - - - - 45 - 0 - - - - - 45 - 26 - - - - 导出 - - - - - - - - 0 - 0 - - - - - 45 - 0 - - - - - 45 - 26 - - - - 过滤 - - - - - - - - - - 300 - 0 - - - - Qt::Horizontal - - - 0 - - - - - 210 - 0 - - - - false - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 600 - 0 - - - - QFrame::Sunken - - - false - - - false - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QAbstractItemView::ScrollPerPixel - - - - - - - - - - - - - - - - CAlarmView - QTableView -
CAlarmView.h
-
- - CAlarmDeviceTreeView - QTreeView -
CAlarmDeviceTreeView.h
-
- - CAiAlarmTreeView - QTreeView -
CAiAlarmTreeView.h
-
-
- - - - updateFilter() - -
+ + + CAlarmForm + + + + 0 + 0 + 1316 + 631 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Sunken + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + 2 + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + + 132 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 位置: + + + + + + + + 170 + 0 + + + + + 16777215 + 26 + + + + + + + + + 111 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 时间: + + + + + + + + 80 + 26 + + + + + 16777215 + 26 + + + + 智能告警 + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 告警类型: + + + + + + + false + + + + 45 + 26 + + + + + + + 确认 + + + + + + + + 80 + 0 + + + + + 100 + 26 + + + + 禁止告警列表 + + + + + + + + 113 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 优先级: + + + + + + + 0 + + + 2 + + + 3 + + + + + + 55 + 0 + + + + 0 + + + + + + + 过滤告警数量: + + + + + + + 当前显示数量: + + + + + + + + 55 + 0 + + + + 0 + + + + + + + + + false + + + + 45 + 26 + + + + 删除 + + + + + + + + 45 + 26 + + + + 关闭 + + + + + + + + 0 + 0 + + + + + 45 + 0 + + + + + 45 + 26 + + + + 导出 + + + + + + + + 0 + 0 + + + + + 45 + 0 + + + + + 45 + 26 + + + + 过滤 + + + + + + + + + + 300 + 0 + + + + Qt::Horizontal + + + 0 + + + + + 210 + 0 + + + + false + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 600 + 0 + + + + QFrame::Sunken + + + false + + + false + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QAbstractItemView::ScrollPerPixel + + + + + + + + + + + + + + + + CAlarmView + QTableView +
CAlarmView.h
+
+ + CAlarmDeviceTreeView + QTreeView +
CAlarmDeviceTreeView.h
+
+ + CAiAlarmTreeView + QTreeView +
CAiAlarmTreeView.h
+
+
+ + + + updateFilter() + +
diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.cpp index 012e5bdb..ff8ece89 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.cpp @@ -1,165 +1,165 @@ -#include "CAlarmInhibitDialog.h" -#include "ui_CAlarmInhibitDialog.h" -#include -#include -#include -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" - -CAlarmInhibitDialog::CAlarmInhibitDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CAlarmInhibitDialog) -{ - ui->setupUi(this); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - connect(ui->ok, &QPushButton::clicked, this, &CAlarmInhibitDialog::onRemoveInhibit); - connect(ui->cancle, &QPushButton::clicked, [=](){ - reject(); - }); -} - -CAlarmInhibitDialog::~CAlarmInhibitDialog() -{ - delete ui; -} - -void CAlarmInhibitDialog::setPriorityDescriptionMap(const QMap priorityDescriptionMap) -{ - m_priorityDescriptionMap = priorityDescriptionMap; -} - -void CAlarmInhibitDialog::setLocationDescriptionMap(const QMap locationDescriptionMap) -{ - m_locationDescriptionMap = locationDescriptionMap; -} - -void CAlarmInhibitDialog::setRegionDescriptionMap(const QMap regionDescriptionMap) -{ - m_regionDescriptionMap = regionDescriptionMap; -} - -void CAlarmInhibitDialog::setAlarmTypeDescriptionMap(const QMap alarmTypeDescriptionMap) -{ - m_alarmTypeDescriptionMap = alarmTypeDescriptionMap; -} - -void CAlarmInhibitDialog::setDeviceTypeDescriptionMap(const QMap deviceTypeDescriptionMap) -{ - m_deviceTypeDescriptionMap= deviceTypeDescriptionMap; -} - -void CAlarmInhibitDialog::setInhibitAlarmList(const QList &alarmList) -{ - m_inhibitAlarmList = alarmList; - ui->tableWidget->setRowCount(m_inhibitAlarmList.size()); - ui->tableWidget->setColumnCount(7); - for(int nRow(0); nRow < m_inhibitAlarmList.size(); nRow++) - { - QTableWidgetItem *item; - QString time_stamp = QDateTime::fromMSecsSinceEpoch(m_inhibitAlarmList.at(nRow)->time_stamp).toString("yyyy-MM-dd hh:mm:ss"); - item = new QTableWidgetItem(time_stamp); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 0, item); - - QString priority = m_priorityDescriptionMap.value(m_inhibitAlarmList.at(nRow)->priority); - item = new QTableWidgetItem(priority); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 1, item); - - QString location = m_locationDescriptionMap.value(m_inhibitAlarmList.at(nRow)->location_id); - item = new QTableWidgetItem(location); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 2, item); - - QString region = m_regionDescriptionMap.value(m_inhibitAlarmList.at(nRow)->region_id); - item = new QTableWidgetItem(region); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 3, item); - - QString type = m_alarmTypeDescriptionMap.value(m_inhibitAlarmList.at(nRow)->alm_type); - item = new QTableWidgetItem(type); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 4, item); - - QString state; - if(E_ALS_ALARM == m_inhibitAlarmList.at(nRow)->logic_state || E_ALS_RETURN == m_inhibitAlarmList.at(nRow)->logic_state) //< 未确认 - { - state = tr("未确认"); - } - else - { - state = tr("已确认"); - } - item = new QTableWidgetItem(state); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 5, item); - - item = new QTableWidgetItem(m_inhibitAlarmList.at(nRow)->content); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(nRow, 6, item); - } - - ui->tableWidget->setColumnWidth(0, 230); - ui->tableWidget->setColumnWidth(1, 100); - ui->tableWidget->setColumnWidth(2, 150); - ui->tableWidget->setColumnWidth(3, 150); - ui->tableWidget->setColumnWidth(4, 120); - ui->tableWidget->setColumnWidth(5, 80); - -} - -void CAlarmInhibitDialog::onRemoveInhibit() -{ - QModelIndexList indexList = ui->tableWidget->selectionModel()->selectedRows(0); - if(indexList.isEmpty()) - { - QMessageBox::information(this, tr("警告"), tr("请选择取消禁止告警所在的行!"), QMessageBox::Ok); - return; - } - std::sort(indexList.begin(), indexList.end()); - QList removedInhibitAlarmList; - for(int nRow(indexList.size() - 1); nRow >= 0; nRow--) - { - removedInhibitAlarmList.append(m_inhibitAlarmList.takeAt(indexList.at(nRow).row())); - ui->tableWidget->removeRow(indexList.at(nRow).row()); - } - emit removeInhibitAlarmList(removedInhibitAlarmList); -} - -void CAlarmInhibitDialog::contextMenuEvent(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - QMenu menu; - QAction * InhibitAction = menu.addAction(tr("取消禁止告警")); - connect(InhibitAction, &QAction::triggered,this,&CAlarmInhibitDialog::onRemoveInhibit); - setUpdatesEnabled(false); - menu.exec(QCursor::pos()); - setUpdatesEnabled(true); -} +#include "CAlarmInhibitDialog.h" +#include "ui_CAlarmInhibitDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" + +CAlarmInhibitDialog::CAlarmInhibitDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmInhibitDialog) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + connect(ui->ok, &QPushButton::clicked, this, &CAlarmInhibitDialog::onRemoveInhibit); + connect(ui->cancle, &QPushButton::clicked, [=](){ + reject(); + }); +} + +CAlarmInhibitDialog::~CAlarmInhibitDialog() +{ + delete ui; +} + +void CAlarmInhibitDialog::setPriorityDescriptionMap(const QMap priorityDescriptionMap) +{ + m_priorityDescriptionMap = priorityDescriptionMap; +} + +void CAlarmInhibitDialog::setLocationDescriptionMap(const QMap locationDescriptionMap) +{ + m_locationDescriptionMap = locationDescriptionMap; +} + +void CAlarmInhibitDialog::setRegionDescriptionMap(const QMap regionDescriptionMap) +{ + m_regionDescriptionMap = regionDescriptionMap; +} + +void CAlarmInhibitDialog::setAlarmTypeDescriptionMap(const QMap alarmTypeDescriptionMap) +{ + m_alarmTypeDescriptionMap = alarmTypeDescriptionMap; +} + +void CAlarmInhibitDialog::setDeviceTypeDescriptionMap(const QMap deviceTypeDescriptionMap) +{ + m_deviceTypeDescriptionMap= deviceTypeDescriptionMap; +} + +void CAlarmInhibitDialog::setInhibitAlarmList(const QList &alarmList) +{ + m_inhibitAlarmList = alarmList; + ui->tableWidget->setRowCount(m_inhibitAlarmList.size()); + ui->tableWidget->setColumnCount(7); + for(int nRow(0); nRow < m_inhibitAlarmList.size(); nRow++) + { + QTableWidgetItem *item; + QString time_stamp = QDateTime::fromMSecsSinceEpoch(m_inhibitAlarmList.at(nRow)->time_stamp).toString("yyyy-MM-dd hh:mm:ss"); + item = new QTableWidgetItem(time_stamp); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 0, item); + + QString priority = m_priorityDescriptionMap.value(m_inhibitAlarmList.at(nRow)->priority); + item = new QTableWidgetItem(priority); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 1, item); + + QString location = m_locationDescriptionMap.value(m_inhibitAlarmList.at(nRow)->location_id); + item = new QTableWidgetItem(location); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 2, item); + + QString region = m_regionDescriptionMap.value(m_inhibitAlarmList.at(nRow)->region_id); + item = new QTableWidgetItem(region); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 3, item); + + QString type = m_alarmTypeDescriptionMap.value(m_inhibitAlarmList.at(nRow)->alm_type); + item = new QTableWidgetItem(type); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 4, item); + + QString state; + if(E_ALS_ALARM == m_inhibitAlarmList.at(nRow)->logic_state || E_ALS_RETURN == m_inhibitAlarmList.at(nRow)->logic_state) //< 未确认 + { + state = tr("未确认"); + } + else + { + state = tr("已确认"); + } + item = new QTableWidgetItem(state); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 5, item); + + item = new QTableWidgetItem(m_inhibitAlarmList.at(nRow)->content); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 6, item); + } + + ui->tableWidget->setColumnWidth(0, 230); + ui->tableWidget->setColumnWidth(1, 100); + ui->tableWidget->setColumnWidth(2, 150); + ui->tableWidget->setColumnWidth(3, 150); + ui->tableWidget->setColumnWidth(4, 120); + ui->tableWidget->setColumnWidth(5, 80); + +} + +void CAlarmInhibitDialog::onRemoveInhibit() +{ + QModelIndexList indexList = ui->tableWidget->selectionModel()->selectedRows(0); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("警告"), tr("请选择取消禁止告警所在的行!"), QMessageBox::Ok); + return; + } + std::sort(indexList.begin(), indexList.end()); + QList removedInhibitAlarmList; + for(int nRow(indexList.size() - 1); nRow >= 0; nRow--) + { + removedInhibitAlarmList.append(m_inhibitAlarmList.takeAt(indexList.at(nRow).row())); + ui->tableWidget->removeRow(indexList.at(nRow).row()); + } + emit removeInhibitAlarmList(removedInhibitAlarmList); +} + +void CAlarmInhibitDialog::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + QMenu menu; + QAction * InhibitAction = menu.addAction(tr("取消禁止告警")); + connect(InhibitAction, &QAction::triggered,this,&CAlarmInhibitDialog::onRemoveInhibit); + setUpdatesEnabled(false); + menu.exec(QCursor::pos()); + setUpdatesEnabled(true); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.h index 9e7f909e..f6371f5f 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.h @@ -1,48 +1,48 @@ -#ifndef CALARMINHIBITDIALOG_H -#define CALARMINHIBITDIALOG_H - -#include -#include -#include "CAlarmMsgInfo.h" - -namespace Ui { -class CAlarmInhibitDialog; -} - -class CAlarmInhibitDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CAlarmInhibitDialog(QWidget *parent = 0); - ~CAlarmInhibitDialog(); - - void setPriorityDescriptionMap(const QMap priorityDescriptionMap); - void setLocationDescriptionMap(const QMap locationDescriptionMap); - void setRegionDescriptionMap(const QMap regionDescriptionMap); - void setAlarmTypeDescriptionMap(const QMap alarmTypeDescriptionMap); - void setDeviceTypeDescriptionMap(const QMap deviceTypeDescriptionMap); - - void setInhibitAlarmList(const QList &alarmList); - -signals: - void removeInhibitAlarmList(QList alarmList); - -protected slots: - void onRemoveInhibit(); -protected: - void contextMenuEvent(QContextMenuEvent *event); - -private: - Ui::CAlarmInhibitDialog *ui; - - QMap m_priorityDescriptionMap; - QMap m_locationDescriptionMap; - QMap m_regionDescriptionMap; - QMap m_alarmTypeDescriptionMap; - QMap m_deviceTypeDescriptionMap; - - QList m_inhibitAlarmList; -}; - -#endif // CALARMINHIBITDIALOG_H +#ifndef CALARMINHIBITDIALOG_H +#define CALARMINHIBITDIALOG_H + +#include +#include +#include "CAlarmMsgInfo.h" + +namespace Ui { +class CAlarmInhibitDialog; +} + +class CAlarmInhibitDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmInhibitDialog(QWidget *parent = 0); + ~CAlarmInhibitDialog(); + + void setPriorityDescriptionMap(const QMap priorityDescriptionMap); + void setLocationDescriptionMap(const QMap locationDescriptionMap); + void setRegionDescriptionMap(const QMap regionDescriptionMap); + void setAlarmTypeDescriptionMap(const QMap alarmTypeDescriptionMap); + void setDeviceTypeDescriptionMap(const QMap deviceTypeDescriptionMap); + + void setInhibitAlarmList(const QList &alarmList); + +signals: + void removeInhibitAlarmList(QList alarmList); + +protected slots: + void onRemoveInhibit(); +protected: + void contextMenuEvent(QContextMenuEvent *event); + +private: + Ui::CAlarmInhibitDialog *ui; + + QMap m_priorityDescriptionMap; + QMap m_locationDescriptionMap; + QMap m_regionDescriptionMap; + QMap m_alarmTypeDescriptionMap; + QMap m_deviceTypeDescriptionMap; + + QList m_inhibitAlarmList; +}; + +#endif // CALARMINHIBITDIALOG_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.ui b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.ui index 52f0bb8a..efeec9c6 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.ui +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmInhibitDialog.ui @@ -1,114 +1,114 @@ - - - CAlarmInhibitDialog - - - - 0 - 0 - 1094 - 433 - - - - 禁止报警列表 - - - - 3 - - - 3 - - - 3 - - - 6 - - - 3 - - - 6 - - - - - 关闭 - - - - - - - 取消禁止告警 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QAbstractItemView::MultiSelection - - - QAbstractItemView::SelectRows - - - true - - - - 时间 - - - - - 优先级 - - - - - 位置 - - - - - 责任区 - - - - - 告警类型 - - - - - 确认状态 - - - - - 告警内容 - - - - - - - - - + + + CAlarmInhibitDialog + + + + 0 + 0 + 1094 + 433 + + + + 禁止报警列表 + + + + 3 + + + 3 + + + 3 + + + 6 + + + 3 + + + 6 + + + + + 关闭 + + + + + + + 取消禁止告警 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QAbstractItemView::MultiSelection + + + QAbstractItemView::SelectRows + + + true + + + + 时间 + + + + + 优先级 + + + + + 位置 + + + + + 责任区 + + + + + 告警类型 + + + + + 确认状态 + + + + + 告警内容 + + + + + + + + + diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmItemModel.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmItemModel.cpp index 37926445..52f3ac95 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmItemModel.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmItemModel.cpp @@ -1,1154 +1,1154 @@ -#include "CAlarmItemModel.h" -#include "CAlarmMsgInfo.h" -#include -#include -#include -#include -#include "CAlarmDataCollect.h" -#include "CAlarmMsgManage.h" -#include "perm_mng_api/PermMngApi.h" -#include -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" -#include "Common.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CharUtil.h" -#include "pub_logger_api/logger.h" - -///////////////////////////////////////////////////////////////////////////// - -using namespace kbd_public; -using namespace std; -const int DOCK_ROW_COUNT = 3; -const int MAX_ROW_COUNT = 15000; - -typedef QPair > PAIRLISTALARMINFO; - -CAlarmItemModel::CAlarmItemModel(E_Alarm_Mode mode, QObject *parent) - :QAbstractTableModel(parent), - m_mode(mode), - m_sortKey(E_SORT_PRIORITY), - m_order(Qt::DescendingOrder), - m_rtdbAccess(Q_NULLPTR) -{ - m_nTotalSize = 0; - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_alternateFlag = true; - m_header <)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); - connect(CAlarmDataCollect::instance(), SIGNAL(sigAlarmStateChanged(int, int)), this, SLOT(slotAlarmStateChanged(int, int)), Qt::QueuedConnection); - if(E_Alarm_Dock == m_mode) - { - connect(CAlarmDataCollect::instance(), SIGNAL(sigMsgConfirm()), this, SLOT(slotMsgConfirm()), Qt::QueuedConnection); - } - connect(CAlarmDataCollect::instance(), SIGNAL(sigMsgRemove()), this, SLOT(slotMsgRemove()), Qt::QueuedConnection); -} - -CAlarmItemModel::~CAlarmItemModel() -{ - m_priorityDescriptionMap.clear(); - m_locationDescriptionMap.clear(); - m_regionDescriptionMap.clear(); - m_alarmTypeDescriptionMap.clear(); - - m_listShowAlarmInfo.clear(); - - if(m_rtdbAccess) - { - delete m_rtdbAccess; - } - m_rtdbAccess = Q_NULLPTR; - -} - -void CAlarmItemModel::initialize() -{ - LOGDEBUG("CAlarmItemModel::initialize():model:[%d]",m_mode); - m_listHorAlignmentFlags.clear(); - for (int nIndex(0); nIndex < m_header.size(); nIndex++) - { - m_listHorAlignmentFlags.append(Qt::AlignHCenter); - } - loadPermInfo(); - loadAlarmInfoConfig(); - initFilter(); - - slotMsgRefresh(); -} - -void CAlarmItemModel::initFilter() -{ - m_isLevelFilterEnable = false; - m_isLocationFilterEnable = false; - m_isRegionFilterEnable = false; - m_isTypeFilterEnable = false; - m_isDeviceTypeFileter = false; - m_isKeywordEnable = false; - m_timeFilterEnable = false; - m_confirmFilterEnable = false; - - // m_isLevelFilterEnable = false; - // m_levelFilter = m_priorityDescriptionMap.keys(); - // m_isLocationFilterEnable = false; - // m_locationFilter = m_locationDescriptionMap.keys(); - // m_isRegionFilterEnable = false; - // m_regionFilter = m_regionDescriptionMap.keys(); - // m_isTypeFilterEnable = false; - // m_typeFilter = m_alarmTypeDescriptionMap.keys(); - - // setFilter(m_isLevelFilterEnable, m_levelFilter, m_isLocationFilterEnable, m_locationFilter, m_isRegionFilterEnable, m_regionFilter, m_isTypeFilterEnable, m_typeFilter); -} - -void CAlarmItemModel::loadAlarmInfoConfig() -{ - loadPriorityDescription(); - loadLocationDescription(); - loadRegionDescription(); - loadAlarmTypeDescription(); - loadAlarmStatusDescription(); - loadDeviceTypeDescription(); - loadDeviceGroupDescription(); - loadAlarmShowStatusDescription(); - loadAlarmOtherStatusDescription(); -} - -E_Alarm_Mode CAlarmItemModel::getAlarmMode() const -{ - return m_mode; -} - -int CAlarmItemModel::getShowAlarmCount() const -{ - return m_listShowAlarmInfo.size(); -} - -AlarmMsgPtr CAlarmItemModel::getAlarmInfo(const QModelIndex &index) -{ - if(index.row() < m_listShowAlarmInfo.size()) - { - return m_listShowAlarmInfo.at(index.row()); - } - return AlarmMsgPtr(Q_NULLPTR); -} - -const QList CAlarmItemModel::getListShowAlarmInfo() const -{ - return m_listShowAlarmInfo; -} - -void CAlarmItemModel::setColumnAlign(const int &column, const int &alignFlag) -{ - Qt::AlignmentFlag flag = Qt::AlignHCenter; - if(Qt::AlignLeft == (Qt::AlignmentFlag)alignFlag || Qt::AlignRight == (Qt::AlignmentFlag)alignFlag) - { - flag = (Qt::AlignmentFlag)alignFlag; - } - m_listHorAlignmentFlags.replace(column, flag); -} - -void CAlarmItemModel::insertAlarmMsg(const AlarmMsgPtr &info) -{ - int mid = -1; - int left = 0; - int right = m_listShowAlarmInfo.size() - 1; - while(left <= right) - { - mid = (left + right) / 2; - if (Qt::AscendingOrder == m_order) - { - if(info->lessThan(m_listShowAlarmInfo[mid], m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - else - { - if(m_listShowAlarmInfo[mid]->lessThan(info, m_sortKey)) - { - right = mid - 1; - } - else - { - left = mid + 1; - } - } - } - - if (E_Alarm_Dock == m_mode) - { - beginResetModel(); - m_listShowAlarmInfo.insert(left, info); - endResetModel(); - } - else - { - beginInsertRows(QModelIndex(), left, left); - m_listShowAlarmInfo.insert(left, info); - endInsertRows(); - } -} - -bool CAlarmItemModel::alternate() const -{ - return m_alternateFlag; -} - -int CAlarmItemModel::filterCount() -{ - if (0 == m_nTotalSize) - { - return 0; - } - int nCount = m_nTotalSize - m_listShowAlarmInfo.size(); - if( nCount< 0) - { - return 0; - }else - { - return nCount; - } -} - -QVariant CAlarmItemModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(m_header.at(section)); - } - return QVariant(); -} - -QVariant CAlarmItemModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid() || index.row() >= m_listShowAlarmInfo.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == 7) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); - } - - } - else if(Qt::DisplayRole == role) - { - switch ( index.column() ) - { - case TIME : - { - return QDateTime::fromMSecsSinceEpoch(m_listShowAlarmInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - case PRIORITY : - { - return m_priorityDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->priority, tr("未知优先级:") + QString::number(m_listShowAlarmInfo.at(index.row())->priority)); - } - case LOCATION : - { - return m_locationDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->location_id, tr("未知位置:") + QString::number(m_listShowAlarmInfo.at(index.row())->location_id)); - } - case REGION : - { - return m_regionDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->region_id, tr("未知责任区:") + QString::number(m_listShowAlarmInfo.at(index.row())->region_id)); - } - case TYPE : - { - return m_alarmTypeDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->alm_type, tr("未知告警类型:") + QString::number(m_listShowAlarmInfo.at(index.row())->alm_type)); - } - case STATUS : - { - return m_alarmStatusDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->alm_status, tr("未知告警状态:") + QString::number(m_listShowAlarmInfo.at(index.row())->alm_status)); - } - case CONFIRM : - { - if(E_ALS_ALARM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN == m_listShowAlarmInfo.at(index.row())->logic_state) //< 未确认 - { - return tr("未确认"); - } - else - { - return tr("已确认"); - } - } - case CONTENT : - { - return m_listShowAlarmInfo.at(index.row())->content; - } - default: - break; - } - } - return QVariant(); -} - -int CAlarmItemModel::columnCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - - return m_header.count(); -} - -int CAlarmItemModel::rowCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - - if(E_Alarm_Dock == m_mode) - { - return DOCK_ROW_COUNT; - } - else - { - return m_listShowAlarmInfo.count(); - } -} - -Qt::ItemFlags CAlarmItemModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CAlarmItemModel::sortColumn(int column, Qt::SortOrder order) -{ - if(order == Qt::AscendingOrder) - { - m_order = Qt::DescendingOrder; - } - else - { - m_order = Qt::AscendingOrder; - } - - switch ((ColumnField)column) - { - case TIME: - { - m_sortKey = E_SORT_TIME; - break; - } - case PRIORITY: - { - m_sortKey = E_SORT_PRIORITY; - break; - } - case LOCATION: - { - m_sortKey = E_SORT_LOCATION; - break; - } - case REGION: - { - m_sortKey = E_SORT_REGION; - break; - } - case TYPE: - { - m_sortKey = E_SORT_TYPE; - break; - } - case STATUS: - { - m_sortKey = E_SORT_ALM_STATE; - break; - } - case CONFIRM: - { - m_sortKey = E_SORT_LOGICSTATE; - break; - } - case CONTENT: - { - m_sortKey = E_SORT_CONTENT; - break; - } - default: - break; - } - sort(); - beginResetModel(); - endResetModel(); -} - -//<归并排序 -void CAlarmItemModel::sort() -{ - QMap mapAlarmInfo; - //<分 - for(int nIndex(0); nIndex < m_listShowAlarmInfo.count(); nIndex++) - { - AlarmMsgPtr temp = m_listShowAlarmInfo.at(nIndex); - mapAlarmInfo[nIndex / 1000].second.append(temp); - } - - //<快速排序 - for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) - { - qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); - } - - PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; - for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) - { - //<归并 - tempListAlarmInfo.first = 0; - mapAlarmInfo[nPairIndex].first = 0; - while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) - { - if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) - { - tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - } - tempListAlarmInfo.first += 1; - } - } - m_listShowAlarmInfo = tempListAlarmInfo.second; -} - - -void CAlarmItemModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CAlarmItemModel::partitionAscendingOrder(QList &list, int start, int last) -{ - AlarmMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftlessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CAlarmItemModel::partitionDescendingOrder(QList &list, int start, int last) -{ - AlarmMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -void CAlarmItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - m_isLevelFilterEnable = isCheck; - m_levelFilter = priorityFilter; - slotMsgRefresh(); -} - -void CAlarmItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) -{ - m_isLocationFilterEnable = isCheck; - m_locationFilter = locationFilter; - slotMsgRefresh(); -} - -void CAlarmItemModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter) -{ - m_isTypeFilterEnable = isCheck; - m_typeFilter = alarmTypeFilter; - slotMsgRefresh(); -} - -void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) -{ - m_timeFilterEnable = isCheck; - if(isCheck) - { - QTime time_1(0,0,0); - QTime time_2(23,59,59); - m_startTime.setDate(startTime); - m_startTime.setTime(time_1); - m_endTime.setDate(endTime); - m_endTime.setTime(time_2); - } - slotMsgRefresh(); -} - -void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck) -{ - m_timeFilterEnable = isCheck; - slotMsgRefresh(); -} - -void CAlarmItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, - const bool &isKeywordFilterEnable, const QString &keyword, - const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, - const bool &confirmFilterEnable, const bool &isConfirm) -{ - m_isLevelFilterEnable = isLevelFilterEnable; - m_levelFilter = levelFilter; - m_isLocationFilterEnable = isStationFilterEnable; - m_locationFilter = stationFilter; - m_isRegionFilterEnable = isRegionFilterEnable; - m_regionFilter = regionFilter; - m_isTypeFilterEnable = isTypeFilterEnable; - m_typeFilter = typeFilter; - m_isDeviceTypeFileter = isDeviceTypeFilter; - m_subSystem = subSystem; - m_deviceType = deviceType; - m_isKeywordEnable = isKeywordFilterEnable; - m_keyowrd = keyword; - m_timeFilterEnable = timeFilterEnable; - m_startTime = startTime; - m_endTime = endTime; - m_confirmFilterEnable = confirmFilterEnable; - m_isConfirm = isConfirm; - - slotMsgRefresh(); -} - -void CAlarmItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, - bool &confirmFilterEnable, bool &isConfirm) -{ - isLevelFilterEnable = m_isLevelFilterEnable; - levelFilter = m_levelFilter; - isLocationFilterEnable = m_isLocationFilterEnable; - locationFilter = m_locationFilter; - isRegionFilterEnable = m_isRegionFilterEnable; - regionFilter = m_regionFilter; - isTypeFilterEnable = m_isTypeFilterEnable; - alarmTypeFilter = m_typeFilter; - subSystem = m_subSystem; - deviceTypeFilter = m_isDeviceTypeFileter; - deviceType = m_deviceType; - keywordFilterEnable = m_isKeywordEnable; - keyword = m_keyowrd; - timeFilterEnable = m_timeFilterEnable; - startTime = m_startTime; - endTime = m_endTime; - confirmFilterEnable = m_confirmFilterEnable; - isConfirm = m_isConfirm; -} - -void CAlarmItemModel::addDeviceFilter(const QString &device) -{ - m_deviceFilter.insert(device); - slotMsgRefresh(); -} - -void CAlarmItemModel::removeDeviceFilter(const QString &device) -{ - m_deviceFilter.remove(device); - slotMsgRefresh(); -} - -void CAlarmItemModel::addPointTagFilter(const QList &pointList) -{ - for(int i =0;ipriority)) - { - return false; - } - - //< 车站 - if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) - { - return false; - } - //< 责任区 - if(m_isRegionFilterEnable && !m_regionFilter.contains(info->region_id)) - { - return false; - } - - //< 类型 - if(m_isTypeFilterEnable && !m_typeFilter.contains(info->alm_type)) - { - return false; - } - - //< 设备类型 - if(m_isDeviceTypeFileter) - { - if(m_deviceTypeDescriptionMap.key(m_deviceType) != info->dev_type) - { - return false; - } - } - - //< 点-设备或设备组 - if(E_Alarm_Pop == m_mode) - { - //点标签过滤 - if(info->device.isEmpty() || !m_deviceGroupFilter.contains(info->dev_group_tag)) - { - return false; - } - } - else if(m_deviceGroupFilter.contains(info->dev_group_tag)) - { - return false; - } - - - //< 关键字 - if(m_isKeywordEnable && !info->content.contains(m_keyowrd)) - { - return false; - } - - //< 时间 - if(m_timeFilterEnable) - { - if(m_startTime.toMSecsSinceEpoch() >= (qint64)(info->time_stamp)) - { - return false; - } - if(m_endTime.toMSecsSinceEpoch() <= (qint64)(info->time_stamp)) - { - return false; - } - } - - //< 是否已确认 - if(m_confirmFilterEnable) - { - if(m_isConfirm) - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) - { - return false; - } - } - else - { - if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM) - { - return false; - } - } - } - - return true; -} - -void CAlarmItemModel::updateAlternate() -{ - m_alternateFlag = !m_alternateFlag; -// if(m_alternateFlag) -// { -// loadPermInfo(); -// loadAlarmInfoConfig(); -// } -} - -QMap CAlarmItemModel::priorityDescriptionMap() -{ - return m_priorityDescriptionMap; -} - -QMap CAlarmItemModel::locationDescriptionMap() -{ - return m_locationDescriptionMap; -} - -QMap CAlarmItemModel::regionDescriptionMap() -{ - return m_regionDescriptionMap; -} - -QMap CAlarmItemModel::alarmTypeDescriptionMap() -{ - return m_alarmTypeDescriptionMap; -} - -QMap CAlarmItemModel::alarmStatusDescriptionMap() -{ - return m_alarmStatusDescriptionMap; -} - -QMap CAlarmItemModel::deviceTypeDescriptionMap() -{ - return m_deviceTypeDescriptionMap; -} - -QMap CAlarmItemModel::deviceGroupDescriptionMap() -{ - return m_deviceGroupDescriptionMap; -} - -QMap CAlarmItemModel::alarmShowStatusDescriptionMap() -{ - return m_alarmShowStatusDescriptionMap; -} - -void CAlarmItemModel::slotMsgRefresh() -{ - beginResetModel(); - m_listShowAlarmInfo.clear(); - QList listAlarmInfo = CAlarmMsgManage::instance()->getListAlarmInfo(); - foreach (AlarmMsgPtr info, listAlarmInfo) - { - if(conditionFilter(info)) - { - m_listShowAlarmInfo.append(info); - } - } - sort(); - endResetModel(); - slotMsgConfirm(); -} - -void CAlarmItemModel::slotMsgArrived(QList listMsg) -{ - //处理新告警消息 - QList::const_iterator it = listMsg.constBegin(); - while (it != listMsg.constEnd()) - { - if(conditionFilter(*it)) - { - insertAlarmMsg(*it); - } - ++it; - } -} - -void CAlarmItemModel::slotMsgConfirm() -{ - if (E_Alarm_Dock == m_mode) - { - beginResetModel(); - for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) - { - E_ALARM_LOGICSTATE state = m_listShowAlarmInfo.at(nIndex)->logic_state; - if(state == E_ALS_ALARM_CFM || state == E_ALS_RETURN_CFM) - { - m_listShowAlarmInfo.removeAt(nIndex); - } - } - endResetModel(); - } -} - -void CAlarmItemModel::slotMsgRemove() -{ - if (E_Alarm_Dock == m_mode) - { - beginResetModel(); - for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) - { - if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) - { - m_listShowAlarmInfo.removeAt(nIndex); - } - } - endResetModel(); - } - else - { - for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) - { - if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) - { - beginRemoveRows(QModelIndex(), nIndex, nIndex); - m_listShowAlarmInfo.removeAt(nIndex); - endRemoveRows(); - } - } - } -} - -void CAlarmItemModel::slotAlarmStateChanged(int total, int unConfirm) -{ - Q_UNUSED(unConfirm) - m_nTotalSize = total; -} - -/********************************RTDB Query Access Begin****************************/ -void CAlarmItemModel::loadPermInfo() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecRegionId; - std::vector vecLocationId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_VIEW, vecRegionId, vecLocationId)) - { - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - m_listPermLocationId.append(*location++); - } - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - m_listPermRegionId.append(*region++); - } - } - } -} - -void CAlarmItemModel::loadPriorityDescription() -{ - if(m_rtdbAccess->open("base", "alarm_level_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("priority_id"); - columns.push_back("priority_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmItemModel::loadLocationDescription() -{ - if(m_rtdbAccess->open("base", "sys_model_location_info")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("location_id"); - columns.push_back("description"); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - if(m_listPermLocationId.contains(key.toInt())) - { - m_locationDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - } -} - -void CAlarmItemModel::loadRegionDescription() -{ - if(m_rtdbAccess->open("base", "region_info")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("region_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - if(m_listPermRegionId.contains(key.toInt())) - { - m_regionDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - } - m_regionDescriptionMap[-1] = QString(); -} - -void CAlarmItemModel::loadAlarmTypeDescription() -{ - if(m_rtdbAccess->open("base", "alarm_type_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("type_id"); - columns.push_back("type_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmItemModel::loadAlarmStatusDescription() -{ - if(m_rtdbAccess->open("base", "alarm_status_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("status_value"); - columns.push_back("display_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmStatusDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - -} - -void CAlarmItemModel::loadDeviceTypeDescription() -{ - if(m_rtdbAccess->open("base", "dev_type_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("dev_type_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmItemModel::loadDeviceGroupDescription() -{ - if(m_rtdbAccess->open("base", "dev_group")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("tag_name"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmItemModel::loadAlarmShowStatusDescription() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - if(StringToInt(strKey) != 0) - { - m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; - }else - { - m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = tr("其他"); - } - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -void CAlarmItemModel::loadAlarmOtherStatusDescription() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - m_alarmOtherStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} +#include "CAlarmItemModel.h" +#include "CAlarmMsgInfo.h" +#include +#include +#include +#include +#include "CAlarmDataCollect.h" +#include "CAlarmMsgManage.h" +#include "perm_mng_api/PermMngApi.h" +#include +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_logger_api/logger.h" + +///////////////////////////////////////////////////////////////////////////// + +using namespace kbd_public; +using namespace std; +const int DOCK_ROW_COUNT = 3; +const int MAX_ROW_COUNT = 15000; + +typedef QPair > PAIRLISTALARMINFO; + +CAlarmItemModel::CAlarmItemModel(E_Alarm_Mode mode, QObject *parent) + :QAbstractTableModel(parent), + m_mode(mode), + m_sortKey(E_SORT_PRIORITY), + m_order(Qt::DescendingOrder), + m_rtdbAccess(Q_NULLPTR) +{ + m_nTotalSize = 0; + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_alternateFlag = true; + m_header <)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); + connect(CAlarmDataCollect::instance(), SIGNAL(sigAlarmStateChanged(int, int)), this, SLOT(slotAlarmStateChanged(int, int)), Qt::QueuedConnection); + if(E_Alarm_Dock == m_mode) + { + connect(CAlarmDataCollect::instance(), SIGNAL(sigMsgConfirm()), this, SLOT(slotMsgConfirm()), Qt::QueuedConnection); + } + connect(CAlarmDataCollect::instance(), SIGNAL(sigMsgRemove()), this, SLOT(slotMsgRemove()), Qt::QueuedConnection); +} + +CAlarmItemModel::~CAlarmItemModel() +{ + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + + m_listShowAlarmInfo.clear(); + + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + +} + +void CAlarmItemModel::initialize() +{ + LOGDEBUG("CAlarmItemModel::initialize():model:[%d]",m_mode); + m_listHorAlignmentFlags.clear(); + for (int nIndex(0); nIndex < m_header.size(); nIndex++) + { + m_listHorAlignmentFlags.append(Qt::AlignHCenter); + } + loadPermInfo(); + loadAlarmInfoConfig(); + initFilter(); + + slotMsgRefresh(); +} + +void CAlarmItemModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_isLocationFilterEnable = false; + m_isRegionFilterEnable = false; + m_isTypeFilterEnable = false; + m_isDeviceTypeFileter = false; + m_isKeywordEnable = false; + m_timeFilterEnable = false; + m_confirmFilterEnable = false; + + // m_isLevelFilterEnable = false; + // m_levelFilter = m_priorityDescriptionMap.keys(); + // m_isLocationFilterEnable = false; + // m_locationFilter = m_locationDescriptionMap.keys(); + // m_isRegionFilterEnable = false; + // m_regionFilter = m_regionDescriptionMap.keys(); + // m_isTypeFilterEnable = false; + // m_typeFilter = m_alarmTypeDescriptionMap.keys(); + + // setFilter(m_isLevelFilterEnable, m_levelFilter, m_isLocationFilterEnable, m_locationFilter, m_isRegionFilterEnable, m_regionFilter, m_isTypeFilterEnable, m_typeFilter); +} + +void CAlarmItemModel::loadAlarmInfoConfig() +{ + loadPriorityDescription(); + loadLocationDescription(); + loadRegionDescription(); + loadAlarmTypeDescription(); + loadAlarmStatusDescription(); + loadDeviceTypeDescription(); + loadDeviceGroupDescription(); + loadAlarmShowStatusDescription(); + loadAlarmOtherStatusDescription(); +} + +E_Alarm_Mode CAlarmItemModel::getAlarmMode() const +{ + return m_mode; +} + +int CAlarmItemModel::getShowAlarmCount() const +{ + return m_listShowAlarmInfo.size(); +} + +AlarmMsgPtr CAlarmItemModel::getAlarmInfo(const QModelIndex &index) +{ + if(index.row() < m_listShowAlarmInfo.size()) + { + return m_listShowAlarmInfo.at(index.row()); + } + return AlarmMsgPtr(Q_NULLPTR); +} + +const QList CAlarmItemModel::getListShowAlarmInfo() const +{ + return m_listShowAlarmInfo; +} + +void CAlarmItemModel::setColumnAlign(const int &column, const int &alignFlag) +{ + Qt::AlignmentFlag flag = Qt::AlignHCenter; + if(Qt::AlignLeft == (Qt::AlignmentFlag)alignFlag || Qt::AlignRight == (Qt::AlignmentFlag)alignFlag) + { + flag = (Qt::AlignmentFlag)alignFlag; + } + m_listHorAlignmentFlags.replace(column, flag); +} + +void CAlarmItemModel::insertAlarmMsg(const AlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_listShowAlarmInfo.size() - 1; + while(left <= right) + { + mid = (left + right) / 2; + if (Qt::AscendingOrder == m_order) + { + if(info->lessThan(m_listShowAlarmInfo[mid], m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + else + { + if(m_listShowAlarmInfo[mid]->lessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + + if (E_Alarm_Dock == m_mode) + { + beginResetModel(); + m_listShowAlarmInfo.insert(left, info); + endResetModel(); + } + else + { + beginInsertRows(QModelIndex(), left, left); + m_listShowAlarmInfo.insert(left, info); + endInsertRows(); + } +} + +bool CAlarmItemModel::alternate() const +{ + return m_alternateFlag; +} + +int CAlarmItemModel::filterCount() +{ + if (0 == m_nTotalSize) + { + return 0; + } + int nCount = m_nTotalSize - m_listShowAlarmInfo.size(); + if( nCount< 0) + { + return 0; + }else + { + return nCount; + } +} + +QVariant CAlarmItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +QVariant CAlarmItemModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowAlarmInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == 7) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + } + + } + else if(Qt::DisplayRole == role) + { + switch ( index.column() ) + { + case TIME : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowAlarmInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case PRIORITY : + { + return m_priorityDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->priority, tr("未知优先级:") + QString::number(m_listShowAlarmInfo.at(index.row())->priority)); + } + case LOCATION : + { + return m_locationDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->location_id, tr("未知位置:") + QString::number(m_listShowAlarmInfo.at(index.row())->location_id)); + } + case REGION : + { + return m_regionDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->region_id, tr("未知责任区:") + QString::number(m_listShowAlarmInfo.at(index.row())->region_id)); + } + case TYPE : + { + return m_alarmTypeDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->alm_type, tr("未知告警类型:") + QString::number(m_listShowAlarmInfo.at(index.row())->alm_type)); + } + case STATUS : + { + return m_alarmStatusDescriptionMap.value(m_listShowAlarmInfo.at(index.row())->alm_status, tr("未知告警状态:") + QString::number(m_listShowAlarmInfo.at(index.row())->alm_status)); + } + case CONFIRM : + { + if(E_ALS_ALARM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN == m_listShowAlarmInfo.at(index.row())->logic_state) //< 未确认 + { + return tr("未确认"); + } + else + { + return tr("已确认"); + } + } + case CONTENT : + { + return m_listShowAlarmInfo.at(index.row())->content; + } + default: + break; + } + } + return QVariant(); +} + +int CAlarmItemModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return m_header.count(); +} + +int CAlarmItemModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + if(E_Alarm_Dock == m_mode) + { + return DOCK_ROW_COUNT; + } + else + { + return m_listShowAlarmInfo.count(); + } +} + +Qt::ItemFlags CAlarmItemModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CAlarmItemModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + + switch ((ColumnField)column) + { + case TIME: + { + m_sortKey = E_SORT_TIME; + break; + } + case PRIORITY: + { + m_sortKey = E_SORT_PRIORITY; + break; + } + case LOCATION: + { + m_sortKey = E_SORT_LOCATION; + break; + } + case REGION: + { + m_sortKey = E_SORT_REGION; + break; + } + case TYPE: + { + m_sortKey = E_SORT_TYPE; + break; + } + case STATUS: + { + m_sortKey = E_SORT_ALM_STATE; + break; + } + case CONFIRM: + { + m_sortKey = E_SORT_LOGICSTATE; + break; + } + case CONTENT: + { + m_sortKey = E_SORT_CONTENT; + break; + } + default: + break; + } + sort(); + beginResetModel(); + endResetModel(); +} + +//<归并排序 +void CAlarmItemModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_listShowAlarmInfo.count(); nIndex++) + { + AlarmMsgPtr temp = m_listShowAlarmInfo.at(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(temp); + } + + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + m_listShowAlarmInfo = tempListAlarmInfo.second; +} + + +void CAlarmItemModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CAlarmItemModel::partitionAscendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAlarmItemModel::partitionDescendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CAlarmItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + slotMsgRefresh(); +} + +void CAlarmItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter) +{ + m_isTypeFilterEnable = isCheck; + m_typeFilter = alarmTypeFilter; + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + slotMsgRefresh(); +} + +void CAlarmItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, + const bool &confirmFilterEnable, const bool &isConfirm) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isTypeFilterEnable = isTypeFilterEnable; + m_typeFilter = typeFilter; + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyowrd = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + m_confirmFilterEnable = confirmFilterEnable; + m_isConfirm = isConfirm; + + slotMsgRefresh(); +} + +void CAlarmItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &confirmFilterEnable, bool &isConfirm) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isTypeFilterEnable = m_isTypeFilterEnable; + alarmTypeFilter = m_typeFilter; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyowrd; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; + confirmFilterEnable = m_confirmFilterEnable; + isConfirm = m_isConfirm; +} + +void CAlarmItemModel::addDeviceFilter(const QString &device) +{ + m_deviceFilter.insert(device); + slotMsgRefresh(); +} + +void CAlarmItemModel::removeDeviceFilter(const QString &device) +{ + m_deviceFilter.remove(device); + slotMsgRefresh(); +} + +void CAlarmItemModel::addPointTagFilter(const QList &pointList) +{ + for(int i =0;ipriority)) + { + return false; + } + + //< 车站 + if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) + { + return false; + } + //< 责任区 + if(m_isRegionFilterEnable && !m_regionFilter.contains(info->region_id)) + { + return false; + } + + //< 类型 + if(m_isTypeFilterEnable && !m_typeFilter.contains(info->alm_type)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { + if(m_deviceTypeDescriptionMap.key(m_deviceType) != info->dev_type) + { + return false; + } + } + + //< 点-设备或设备组 + if(E_Alarm_Pop == m_mode) + { + //点标签过滤 + if(info->device.isEmpty() || !m_deviceGroupFilter.contains(info->dev_group_tag)) + { + return false; + } + } + else if(m_deviceGroupFilter.contains(info->dev_group_tag)) + { + return false; + } + + + //< 关键字 + if(m_isKeywordEnable && !info->content.contains(m_keyowrd)) + { + return false; + } + + //< 时间 + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() >= (qint64)(info->time_stamp)) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() <= (qint64)(info->time_stamp)) + { + return false; + } + } + + //< 是否已确认 + if(m_confirmFilterEnable) + { + if(m_isConfirm) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + return false; + } + } + else + { + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM) + { + return false; + } + } + } + + return true; +} + +void CAlarmItemModel::updateAlternate() +{ + m_alternateFlag = !m_alternateFlag; +// if(m_alternateFlag) +// { +// loadPermInfo(); +// loadAlarmInfoConfig(); +// } +} + +QMap CAlarmItemModel::priorityDescriptionMap() +{ + return m_priorityDescriptionMap; +} + +QMap CAlarmItemModel::locationDescriptionMap() +{ + return m_locationDescriptionMap; +} + +QMap CAlarmItemModel::regionDescriptionMap() +{ + return m_regionDescriptionMap; +} + +QMap CAlarmItemModel::alarmTypeDescriptionMap() +{ + return m_alarmTypeDescriptionMap; +} + +QMap CAlarmItemModel::alarmStatusDescriptionMap() +{ + return m_alarmStatusDescriptionMap; +} + +QMap CAlarmItemModel::deviceTypeDescriptionMap() +{ + return m_deviceTypeDescriptionMap; +} + +QMap CAlarmItemModel::deviceGroupDescriptionMap() +{ + return m_deviceGroupDescriptionMap; +} + +QMap CAlarmItemModel::alarmShowStatusDescriptionMap() +{ + return m_alarmShowStatusDescriptionMap; +} + +void CAlarmItemModel::slotMsgRefresh() +{ + beginResetModel(); + m_listShowAlarmInfo.clear(); + QList listAlarmInfo = CAlarmMsgManage::instance()->getListAlarmInfo(); + foreach (AlarmMsgPtr info, listAlarmInfo) + { + if(conditionFilter(info)) + { + m_listShowAlarmInfo.append(info); + } + } + sort(); + endResetModel(); + slotMsgConfirm(); +} + +void CAlarmItemModel::slotMsgArrived(QList listMsg) +{ + //处理新告警消息 + QList::const_iterator it = listMsg.constBegin(); + while (it != listMsg.constEnd()) + { + if(conditionFilter(*it)) + { + insertAlarmMsg(*it); + } + ++it; + } +} + +void CAlarmItemModel::slotMsgConfirm() +{ + if (E_Alarm_Dock == m_mode) + { + beginResetModel(); + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + E_ALARM_LOGICSTATE state = m_listShowAlarmInfo.at(nIndex)->logic_state; + if(state == E_ALS_ALARM_CFM || state == E_ALS_RETURN_CFM) + { + m_listShowAlarmInfo.removeAt(nIndex); + } + } + endResetModel(); + } +} + +void CAlarmItemModel::slotMsgRemove() +{ + if (E_Alarm_Dock == m_mode) + { + beginResetModel(); + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) + { + m_listShowAlarmInfo.removeAt(nIndex); + } + } + endResetModel(); + } + else + { + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) + { + beginRemoveRows(QModelIndex(), nIndex, nIndex); + m_listShowAlarmInfo.removeAt(nIndex); + endRemoveRows(); + } + } + } +} + +void CAlarmItemModel::slotAlarmStateChanged(int total, int unConfirm) +{ + Q_UNUSED(unConfirm) + m_nTotalSize = total; +} + +/********************************RTDB Query Access Begin****************************/ +void CAlarmItemModel::loadPermInfo() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecRegionId; + std::vector vecLocationId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_VIEW, vecRegionId, vecLocationId)) + { + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listPermLocationId.append(*location++); + } + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listPermRegionId.append(*region++); + } + } + } +} + +void CAlarmItemModel::loadPriorityDescription() +{ + if(m_rtdbAccess->open("base", "alarm_level_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("priority_id"); + columns.push_back("priority_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmItemModel::loadLocationDescription() +{ + if(m_rtdbAccess->open("base", "sys_model_location_info")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("description"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + if(m_listPermLocationId.contains(key.toInt())) + { + m_locationDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + } +} + +void CAlarmItemModel::loadRegionDescription() +{ + if(m_rtdbAccess->open("base", "region_info")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("region_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + if(m_listPermRegionId.contains(key.toInt())) + { + m_regionDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + } + m_regionDescriptionMap[-1] = QString(); +} + +void CAlarmItemModel::loadAlarmTypeDescription() +{ + if(m_rtdbAccess->open("base", "alarm_type_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("type_id"); + columns.push_back("type_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmItemModel::loadAlarmStatusDescription() +{ + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("status_value"); + columns.push_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + +} + +void CAlarmItemModel::loadDeviceTypeDescription() +{ + if(m_rtdbAccess->open("base", "dev_type_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("dev_type_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmItemModel::loadDeviceGroupDescription() +{ + if(m_rtdbAccess->open("base", "dev_group")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("tag_name"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmItemModel::loadAlarmShowStatusDescription() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + if(StringToInt(strKey) != 0) + { + m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; + }else + { + m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = tr("其他"); + } + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CAlarmItemModel::loadAlarmOtherStatusDescription() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + m_alarmOtherStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmItemModel.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmItemModel.h index 76d9fdbd..01de61ba 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmItemModel.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmItemModel.h @@ -1,230 +1,230 @@ -#ifndef CALARMITEMMODEL_H -#define CALARMITEMMODEL_H - -#include -#include -#include -#include -#include "CAlarmMsgInfo.h" -#include "dbms/rdb_api/CRdbAccess.h" -#include "CAlarmCommon.h" -extern const int DOCK_ROW_COUNT; -extern const int MAX_ROW_COUNT; - - - -class CAlarmView; -class CAlarmMsgInfo; - -class CAlarmItemModel : public QAbstractTableModel -{ - Q_OBJECT -public: - - enum ColumnField - { - TIME = 0, - PRIORITY, - LOCATION, - REGION, - TYPE, - STATUS, - CONFIRM, - CONTENT - }; - - CAlarmItemModel(E_Alarm_Mode mode, QObject *parent = Q_NULLPTR); - ~CAlarmItemModel(); - - void initialize(); - - void initFilter(); - - void loadAlarmInfoConfig(); - - E_Alarm_Mode getAlarmMode() const; - - int getShowAlarmCount() const; - - AlarmMsgPtr getAlarmInfo(const QModelIndex &index); - - const QList getListShowAlarmInfo() const; - - - void setColumnAlign(const int &column, const int &alignFlag); - - /** - * @brief insertAlarmMsg 数采通知模型告警到达 - * @param info - */ - void insertAlarmMsg(const AlarmMsgPtr &info); - - /** - * @brief alternate 闪烁状态切换 - * @return - */ - bool alternate() const; - - int filterCount(); - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual int columnCount(const QModelIndex &index = QModelIndex()) const; - virtual int rowCount(const QModelIndex &index = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - - void sort(); - void qucikSort(QList &listAlarmInfo, int left, int right); - int partitionAscendingOrder(QList &list, int start, int last); - int partitionDescendingOrder(QList &list, int start, int last); - - void setPriorityFilter(bool &isCheck, QList &priorityFilter); - void setLocationFilter(bool &isCheck, QList &locationFilter); - void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter); - void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); - void setAlarmTimeFilter(bool &isCheck); - /** - * 设置模型数据过滤条件,过滤显示数据 - */ - void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), - const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), - const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), - const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false); - - /** - * 获取模型数据过滤条件,用于初始化过滤对话框 - */ - void getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isStatusFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, - bool &confirmFilterEnable, bool &isConfirm); - - - void addDeviceFilter(const QString &device); - void removeDeviceFilter(const QString &device); - - void addPointTagFilter(const QList &pointList); - void addDeviceGroupFilter(); - void removeDeviceGroupFilter(); - void addDeviceGroupFilter(const QString &device); - void removeDeviceGroupFilter(const QString &device); - - bool conditionFilter(const AlarmMsgPtr &info); - - void updateAlternate(); - - QMap priorityDescriptionMap(); - QMap locationDescriptionMap(); - QMap regionDescriptionMap(); - QMap alarmTypeDescriptionMap(); - QMap alarmStatusDescriptionMap(); - QMap deviceTypeDescriptionMap(); - QMap deviceGroupDescriptionMap(); - - QMap alarmShowStatusDescriptionMap(); - QMap alarmOtherStatusDescriptionMap(); - -public slots: - void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); - - /** - * @brief slotMsgRefresh 更新model,重新拉取数据 - */ - void slotMsgRefresh(); - -private slots: - /** - * @brief slotMsgArrived 告警消息到达 - * @param info - */ - void slotMsgArrived(QList listMsg); - - /** - * @brief slotMsgConfirm 告警消息确认 - */ - void slotMsgConfirm(); - - /** - * @brief slotMsgArrived 告警消息删除 - */ - void slotMsgRemove(); - - void slotAlarmStateChanged(int total, int unConfirm); - -private: - void loadPermInfo(); - void loadPriorityDescription(); - void loadLocationDescription(); - void loadRegionDescription(); - void loadAlarmTypeDescription(); - void loadAlarmStatusDescription(); - void loadDeviceTypeDescription(); - void loadDeviceGroupDescription(); - - void loadAlarmShowStatusDescription(); - void loadAlarmOtherStatusDescription(); - -private: - E_Alarm_Mode m_mode; - QStringList m_header; - QList m_listShowAlarmInfo; - bool m_alternateFlag; //闪烁颜色切换 - E_ALARM_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - - int m_nTotalSize; - - QList m_listHorAlignmentFlags; //< 水平对齐方式 - - QList m_listPermLocationId; - QList m_listPermRegionId; - - kbd_dbms::CRdbAccess * m_rtdbAccess; - QMap m_priorityDescriptionMap; - QMap m_locationDescriptionMap; - QMap m_regionDescriptionMap; - QMap m_alarmTypeDescriptionMap; - QMap m_alarmStatusDescriptionMap; - QMap m_deviceTypeDescriptionMap; - QMap m_deviceGroupDescriptionMap; - - QMap m_alarmShowStatusDescriptionMap; - QMap m_alarmOtherStatusDescriptionMap; - //< Filter - bool m_isLevelFilterEnable; //是否按告警级别过滤 - QList m_levelFilter; //告警级别过滤 - bool m_isLocationFilterEnable; //是否按车站过滤 - QList m_locationFilter; //车站过滤 - bool m_isRegionFilterEnable; //是否按责任区过滤 - QList m_regionFilter; //责任区过滤 - bool m_isTypeFilterEnable; //是否按告警类型过滤 - QList m_typeFilter; -// bool m_isStatusFilterEnable; //是否按告警状态过滤 -// QList m_statusFilter; //告警状态过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) -// QList m_statusFilter2; //告警状态过滤(显示在过滤窗中的告警状态) - bool m_isDeviceTypeFileter; //设备类型过滤 - QString m_subSystem; //子系统 - QString m_deviceType; //设备类型 - bool m_isKeywordEnable; //关键字过滤 - QString m_keyowrd; //关键字 - bool m_timeFilterEnable; //是否根据时间过滤 - QDateTime m_startTime; //起始时间 - QDateTime m_endTime; //终止时间 - bool m_confirmFilterEnable; //是否根据状态确认过滤 - bool m_isConfirm; //状态是否确认 - - QSet m_deviceFilter; //< 设备过滤 - QSet m_pointFilter; //标签过滤 - QSet m_deviceGroupFilter; //<设备组过滤 - -}; - -#endif // ALARMITEMMODEL_H +#ifndef CALARMITEMMODEL_H +#define CALARMITEMMODEL_H + +#include +#include +#include +#include +#include "CAlarmMsgInfo.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include "CAlarmCommon.h" +extern const int DOCK_ROW_COUNT; +extern const int MAX_ROW_COUNT; + + + +class CAlarmView; +class CAlarmMsgInfo; + +class CAlarmItemModel : public QAbstractTableModel +{ + Q_OBJECT +public: + + enum ColumnField + { + TIME = 0, + PRIORITY, + LOCATION, + REGION, + TYPE, + STATUS, + CONFIRM, + CONTENT + }; + + CAlarmItemModel(E_Alarm_Mode mode, QObject *parent = Q_NULLPTR); + ~CAlarmItemModel(); + + void initialize(); + + void initFilter(); + + void loadAlarmInfoConfig(); + + E_Alarm_Mode getAlarmMode() const; + + int getShowAlarmCount() const; + + AlarmMsgPtr getAlarmInfo(const QModelIndex &index); + + const QList getListShowAlarmInfo() const; + + + void setColumnAlign(const int &column, const int &alignFlag); + + /** + * @brief insertAlarmMsg 数采通知模型告警到达 + * @param info + */ + void insertAlarmMsg(const AlarmMsgPtr &info); + + /** + * @brief alternate 闪烁状态切换 + * @return + */ + bool alternate() const; + + int filterCount(); + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + void sort(); + void qucikSort(QList &listAlarmInfo, int left, int right); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter); + void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); + void setAlarmTimeFilter(bool &isCheck); + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isStatusFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &confirmFilterEnable, bool &isConfirm); + + + void addDeviceFilter(const QString &device); + void removeDeviceFilter(const QString &device); + + void addPointTagFilter(const QList &pointList); + void addDeviceGroupFilter(); + void removeDeviceGroupFilter(); + void addDeviceGroupFilter(const QString &device); + void removeDeviceGroupFilter(const QString &device); + + bool conditionFilter(const AlarmMsgPtr &info); + + void updateAlternate(); + + QMap priorityDescriptionMap(); + QMap locationDescriptionMap(); + QMap regionDescriptionMap(); + QMap alarmTypeDescriptionMap(); + QMap alarmStatusDescriptionMap(); + QMap deviceTypeDescriptionMap(); + QMap deviceGroupDescriptionMap(); + + QMap alarmShowStatusDescriptionMap(); + QMap alarmOtherStatusDescriptionMap(); + +public slots: + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + + /** + * @brief slotMsgRefresh 更新model,重新拉取数据 + */ + void slotMsgRefresh(); + +private slots: + /** + * @brief slotMsgArrived 告警消息到达 + * @param info + */ + void slotMsgArrived(QList listMsg); + + /** + * @brief slotMsgConfirm 告警消息确认 + */ + void slotMsgConfirm(); + + /** + * @brief slotMsgArrived 告警消息删除 + */ + void slotMsgRemove(); + + void slotAlarmStateChanged(int total, int unConfirm); + +private: + void loadPermInfo(); + void loadPriorityDescription(); + void loadLocationDescription(); + void loadRegionDescription(); + void loadAlarmTypeDescription(); + void loadAlarmStatusDescription(); + void loadDeviceTypeDescription(); + void loadDeviceGroupDescription(); + + void loadAlarmShowStatusDescription(); + void loadAlarmOtherStatusDescription(); + +private: + E_Alarm_Mode m_mode; + QStringList m_header; + QList m_listShowAlarmInfo; + bool m_alternateFlag; //闪烁颜色切换 + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + int m_nTotalSize; + + QList m_listHorAlignmentFlags; //< 水平对齐方式 + + QList m_listPermLocationId; + QList m_listPermRegionId; + + kbd_dbms::CRdbAccess * m_rtdbAccess; + QMap m_priorityDescriptionMap; + QMap m_locationDescriptionMap; + QMap m_regionDescriptionMap; + QMap m_alarmTypeDescriptionMap; + QMap m_alarmStatusDescriptionMap; + QMap m_deviceTypeDescriptionMap; + QMap m_deviceGroupDescriptionMap; + + QMap m_alarmShowStatusDescriptionMap; + QMap m_alarmOtherStatusDescriptionMap; + //< Filter + bool m_isLevelFilterEnable; //是否按告警级别过滤 + QList m_levelFilter; //告警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isTypeFilterEnable; //是否按告警类型过滤 + QList m_typeFilter; +// bool m_isStatusFilterEnable; //是否按告警状态过滤 +// QList m_statusFilter; //告警状态过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) +// QList m_statusFilter2; //告警状态过滤(显示在过滤窗中的告警状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyowrd; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + bool m_confirmFilterEnable; //是否根据状态确认过滤 + bool m_isConfirm; //状态是否确认 + + QSet m_deviceFilter; //< 设备过滤 + QSet m_pointFilter; //标签过滤 + QSet m_deviceGroupFilter; //<设备组过滤 + +}; + +#endif // ALARMITEMMODEL_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMediaPlayer.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMediaPlayer.cpp index 1274d1db..eedceb1e 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMediaPlayer.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMediaPlayer.cpp @@ -1,331 +1,331 @@ - -#ifdef OS_WINDOWS -//< 为了检测可用声卡 -#include -#include -#endif - -#include -#include -#include -#include -#include "CAlarmMediaPlayer.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_logger_api/logger.h" -#include "pub_utility_api/I18N.h" - -const int MAX_AUDIO_COUNT = 100; - -using namespace kbd_public; -CAlarmMediaPlayer *CAlarmMediaPlayer::instance() -{ - static CAlarmMediaPlayer player; - return &player; -} - -CAlarmMediaPlayer::CAlarmMediaPlayer() - :m_bHaveValidAudioDev(false),m_pMediaPlayer(Q_NULLPTR),m_pTimerCheckAudioDev(Q_NULLPTR) -{ - QDir dir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); - dir.cdUp(); - dir.cdUp(); - dir.cd("data"); - - dir.cd("sound"); - m_strMediaPath = dir.absolutePath() + QDir::separator(); - - m_pTimerCheckAudioDev = new QTimer(); - m_pTimerCheckAudioDev->setInterval(5000); - connect(m_pTimerCheckAudioDev, SIGNAL(timeout()), this, SLOT(checkAudioDev()),Qt::QueuedConnection); - checkAudioDev(); - m_pTimerCheckAudioDev->start(); - - //< 需在checkAudioDev()之后调用 - initPlayer(); -} - -CAlarmMediaPlayer::~CAlarmMediaPlayer() -{ - m_listAlarmAudio.clear(); - if(Q_NULLPTR != m_pTimerCheckAudioDev) - { - m_pTimerCheckAudioDev->stop(); - m_pTimerCheckAudioDev->deleteLater(); - } - m_pTimerCheckAudioDev = NULL; - if(Q_NULLPTR != m_pMediaPlayer) - { - if(QMediaPlayer::StoppedState != m_pMediaPlayer->state()) - { - m_pMediaPlayer->stop(); - } - delete m_pMediaPlayer; - } - m_pMediaPlayer = Q_NULLPTR; -} - -void CAlarmMediaPlayer::initPlayer() -{ - if(Q_NULLPTR != m_pMediaPlayer) - return; - - m_pMediaPlayer = new QMediaPlayer(this); - connect(m_pMediaPlayer, &QMediaPlayer::stateChanged, this, &CAlarmMediaPlayer::playerStateChanged,Qt::QueuedConnection); - connect(m_pMediaPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(printError(QMediaPlayer::Error)),Qt::QueuedConnection); - - QMediaPlaylist *pPlayList = new QMediaPlaylist(this); - pPlayList->setPlaybackMode(QMediaPlaylist::Sequential); - pPlayList->clear(); - m_pMediaPlayer->setPlaylist(pPlayList); -} - -void CAlarmMediaPlayer::setVolumeEnable(bool bEnable) -{ - if(bEnable) - { - m_pMediaPlayer->setVolume(100); - } - else - { - m_pMediaPlayer->setVolume(0); - } -} - -void CAlarmMediaPlayer::release() -{ - LOGINFO("CAlarmMediaPlayer::release()"); - m_listAlarmAudio.clear(); - m_pMediaPlayer->stop(); -} - -void CAlarmMediaPlayer::insertAudioCues(const AlarmMsgPtr &info, const QStringList &strAudioFileNames) -{ - if(m_listAlarmAudio.count() >= MAX_AUDIO_COUNT) - { - m_listAlarmAudio.removeLast(); - } - //< 按优先级升序插入队列 - bool insertResult = false; - if(!m_listAlarmAudio.isEmpty()) - { - for(int nIndex(m_listAlarmAudio.size() - 1); nIndex >= 0; --nIndex) - { - if(info->priorityOrder > m_listAlarmAudio[nIndex].first->priorityOrder) - { - m_listAlarmAudio.insert(nIndex + 1, qMakePair(info, strAudioFileNames)); - insertResult = true; - break; - } - } - } - - if(!insertResult) - { - if(m_listAlarmAudio.isEmpty()) - { - LOGINFO("insertAudioCues():队列为空时,添加声音"); - m_listAlarmAudio.append(qMakePair(info, strAudioFileNames)); - updateAudioCuesPlayer(); - } - else - { - if(info->priorityOrder < m_listAlarmAudio.first().first->priorityOrder) - { - //< 同优先级不打断正在播放的语音, 高优先级则打断 - m_listAlarmAudio.prepend(qMakePair(info, strAudioFileNames)); - m_pMediaPlayer->stop(); - } - else - { - m_listAlarmAudio.prepend(qMakePair(info, strAudioFileNames)); - } - } - } -} - -void CAlarmMediaPlayer::removeAudioCues(const AlarmMsgPtr &info) -{ - if(m_listAlarmAudio.isEmpty()) - { - return; - } - if(info->uuid_base64 == m_listAlarmAudio.first().first->uuid_base64) - { - m_listAlarmAudio.removeFirst(); - m_pMediaPlayer->stop(); - } - else - { - QList::iterator it = m_listAlarmAudio.begin(); - while (it != m_listAlarmAudio.end()) - { - if(info->uuid_base64 == it->first->uuid_base64) - { - m_listAlarmAudio.erase(it); - break; - } - ++it; - } - } -} - -void CAlarmMediaPlayer::playerStateChanged(QMediaPlayer::State state) -{ - if(state == QMediaPlayer::StoppedState) - { - LOGDEBUG("playerStateChanged()状态发生变化时执行updateAudioCuesPlayer():状态为QMediaPlayer::StoppedState"); - updateAudioCuesPlayer(); - }else - { - LOGDEBUG("playerStateChanged()状态发生变化,但不为停止状态,[%d]",state); - } -} - -void CAlarmMediaPlayer::updateAudioCuesPlayer() -{ - if(!m_bHaveValidAudioDev || !m_pMediaPlayer || m_listAlarmAudio.isEmpty() || m_pMediaPlayer->state() != QMediaPlayer::StoppedState) - { - qDebug() << "updateAudioCuesPlayer() return"; - LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesPlayer(),return"); - return; - } - LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesPlayer(),继续往下执行"); - QStringList strAudioFileNames; - QList::iterator it = m_listAlarmAudio.begin(); - while (it != m_listAlarmAudio.end()) { - if(it->first->deleteFlag || it->first->releaseFlag) - { - it = m_listAlarmAudio.erase(it); - }else - { - strAudioFileNames = it->second; - if(strAudioFileNames.isEmpty()) - { - it = m_listAlarmAudio.erase(it); - }else - { - break; - } - } - } - m_pMediaPlayer->playlist()->clear(); - foreach (QString fileName, strAudioFileNames) - { - if(!fileName.isEmpty()) - { - fileName = m_strMediaPath + fileName; - if(QFile::exists(fileName)) - { - m_pMediaPlayer->playlist()->addMedia(QUrl::fromLocalFile(fileName)); - } - } - } - - if(!m_pMediaPlayer->playlist()->isEmpty()) - { - m_pMediaPlayer->play(); - }else - { - LOGINFO("CAlarmMediaPlayer::updateAudioCuesPlayer(),播放列表为空"); - } -} - -void CAlarmMediaPlayer::printError(QMediaPlayer::Error error) -{ - LOGERROR("QMediaPlayer error == %d , errorString : %s",error,m_pMediaPlayer->errorString().toStdString().c_str()); - //qDebug("QMediaPlayer error == %d , errorString : %s",error,m_pMediaPlayer->errorString().toStdString().c_str()); -} - -void CAlarmMediaPlayer::checkAudioDev() -{ - //< 周期性检测音频设备有效性,因为: - //< 1、声卡是可以热拔插的,比如USB声卡 - //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 - - bool bHaveValidDev = false; - - //< 注意:在win系统,qt5.9.9以及5.12.9上测试,下面使用QAudioDeviceInfo检测的方法,本身会导致内存上涨 - { - // //< 测试结果:无论windows audio服务是否启动,defaultOutputDevice看上去都是对的,所以,不能用这个判断是否有效 - - // QList listDev(QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)); - - // //< 不能仅仅检测列表是否为空,还需要检测有效性 - // //< 当有声卡硬件,但是Windows Audio服务未启动时,设备列表不为空,但如果播放依然可能导致内存上涨问题 - // foreach (QAudioDeviceInfo objDev, listDev) - // { - // //< 当Window Audio服务未启动时,无法获取有效的格式信息,以此判断 - // if(objDev.preferredFormat().isValid()) - // { - // bHaveValidDev = true; - // break; - // } - // } - } - - //< 不得已,使用win系统原生API条件编译 -#ifdef OS_WINDOWS - { - //< 获取系统默认主设备的音量,如果成功则至少说明: - //< 1、有声卡; 2、Windows Audio服务正常 - - CoInitialize(NULL); - IMMDeviceEnumerator *pDevEnumerator = NULL; - CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDevEnumerator); - - if(NULL != pDevEnumerator) - { - IMMDevice *pDefaultDev = NULL; - pDevEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDefaultDev); - - pDevEnumerator->Release(); - pDevEnumerator = NULL; - - if(NULL != pDefaultDev) - { - IAudioEndpointVolume *pEndpointVol = NULL; - pDefaultDev->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&pEndpointVol); - - pDefaultDev->Release(); - pDefaultDev = NULL; - - if(NULL != pEndpointVol) - { - float fVol; - const HRESULT nResult = pEndpointVol->GetMasterVolumeLevelScalar(&fVol); - if(S_OK == nResult) - bHaveValidDev = true; - - pEndpointVol->Release(); - pEndpointVol = NULL; - } - } - } - - CoUninitialize(); - } -#else - //< 在Linux系统下测试,即使没有声卡也未见问题,暂时不做检测 - bHaveValidDev = true; -#endif - - if(m_bHaveValidAudioDev && !bHaveValidDev) - { - LOGERROR("No valid audio output device !"); - m_bHaveValidAudioDev = false; - m_pMediaPlayer->stop(); - } - else if(!m_bHaveValidAudioDev && bHaveValidDev) - { - LOGINFO("Valid audio output device detected !"); - - //< 不重新构造可能不能正常播放 - delete m_pMediaPlayer; - m_pMediaPlayer = Q_NULLPTR; - m_bHaveValidAudioDev = true; - initPlayer(); - updateAudioCuesPlayer(); - } - - //qDebug() << "m_bHaveValidAudioDev = " << m_bHaveValidAudioDev; -} + +#ifdef OS_WINDOWS +//< 为了检测可用声卡 +#include +#include +#endif + +#include +#include +#include +#include +#include "CAlarmMediaPlayer.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/I18N.h" + +const int MAX_AUDIO_COUNT = 100; + +using namespace kbd_public; +CAlarmMediaPlayer *CAlarmMediaPlayer::instance() +{ + static CAlarmMediaPlayer player; + return &player; +} + +CAlarmMediaPlayer::CAlarmMediaPlayer() + :m_bHaveValidAudioDev(false),m_pMediaPlayer(Q_NULLPTR),m_pTimerCheckAudioDev(Q_NULLPTR) +{ + QDir dir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + + dir.cd("sound"); + m_strMediaPath = dir.absolutePath() + QDir::separator(); + + m_pTimerCheckAudioDev = new QTimer(); + m_pTimerCheckAudioDev->setInterval(5000); + connect(m_pTimerCheckAudioDev, SIGNAL(timeout()), this, SLOT(checkAudioDev()),Qt::QueuedConnection); + checkAudioDev(); + m_pTimerCheckAudioDev->start(); + + //< 需在checkAudioDev()之后调用 + initPlayer(); +} + +CAlarmMediaPlayer::~CAlarmMediaPlayer() +{ + m_listAlarmAudio.clear(); + if(Q_NULLPTR != m_pTimerCheckAudioDev) + { + m_pTimerCheckAudioDev->stop(); + m_pTimerCheckAudioDev->deleteLater(); + } + m_pTimerCheckAudioDev = NULL; + if(Q_NULLPTR != m_pMediaPlayer) + { + if(QMediaPlayer::StoppedState != m_pMediaPlayer->state()) + { + m_pMediaPlayer->stop(); + } + delete m_pMediaPlayer; + } + m_pMediaPlayer = Q_NULLPTR; +} + +void CAlarmMediaPlayer::initPlayer() +{ + if(Q_NULLPTR != m_pMediaPlayer) + return; + + m_pMediaPlayer = new QMediaPlayer(this); + connect(m_pMediaPlayer, &QMediaPlayer::stateChanged, this, &CAlarmMediaPlayer::playerStateChanged,Qt::QueuedConnection); + connect(m_pMediaPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(printError(QMediaPlayer::Error)),Qt::QueuedConnection); + + QMediaPlaylist *pPlayList = new QMediaPlaylist(this); + pPlayList->setPlaybackMode(QMediaPlaylist::Sequential); + pPlayList->clear(); + m_pMediaPlayer->setPlaylist(pPlayList); +} + +void CAlarmMediaPlayer::setVolumeEnable(bool bEnable) +{ + if(bEnable) + { + m_pMediaPlayer->setVolume(100); + } + else + { + m_pMediaPlayer->setVolume(0); + } +} + +void CAlarmMediaPlayer::release() +{ + LOGINFO("CAlarmMediaPlayer::release()"); + m_listAlarmAudio.clear(); + m_pMediaPlayer->stop(); +} + +void CAlarmMediaPlayer::insertAudioCues(const AlarmMsgPtr &info, const QStringList &strAudioFileNames) +{ + if(m_listAlarmAudio.count() >= MAX_AUDIO_COUNT) + { + m_listAlarmAudio.removeLast(); + } + //< 按优先级升序插入队列 + bool insertResult = false; + if(!m_listAlarmAudio.isEmpty()) + { + for(int nIndex(m_listAlarmAudio.size() - 1); nIndex >= 0; --nIndex) + { + if(info->priorityOrder > m_listAlarmAudio[nIndex].first->priorityOrder) + { + m_listAlarmAudio.insert(nIndex + 1, qMakePair(info, strAudioFileNames)); + insertResult = true; + break; + } + } + } + + if(!insertResult) + { + if(m_listAlarmAudio.isEmpty()) + { + LOGINFO("insertAudioCues():队列为空时,添加声音"); + m_listAlarmAudio.append(qMakePair(info, strAudioFileNames)); + updateAudioCuesPlayer(); + } + else + { + if(info->priorityOrder < m_listAlarmAudio.first().first->priorityOrder) + { + //< 同优先级不打断正在播放的语音, 高优先级则打断 + m_listAlarmAudio.prepend(qMakePair(info, strAudioFileNames)); + m_pMediaPlayer->stop(); + } + else + { + m_listAlarmAudio.prepend(qMakePair(info, strAudioFileNames)); + } + } + } +} + +void CAlarmMediaPlayer::removeAudioCues(const AlarmMsgPtr &info) +{ + if(m_listAlarmAudio.isEmpty()) + { + return; + } + if(info->uuid_base64 == m_listAlarmAudio.first().first->uuid_base64) + { + m_listAlarmAudio.removeFirst(); + m_pMediaPlayer->stop(); + } + else + { + QList::iterator it = m_listAlarmAudio.begin(); + while (it != m_listAlarmAudio.end()) + { + if(info->uuid_base64 == it->first->uuid_base64) + { + m_listAlarmAudio.erase(it); + break; + } + ++it; + } + } +} + +void CAlarmMediaPlayer::playerStateChanged(QMediaPlayer::State state) +{ + if(state == QMediaPlayer::StoppedState) + { + LOGDEBUG("playerStateChanged()状态发生变化时执行updateAudioCuesPlayer():状态为QMediaPlayer::StoppedState"); + updateAudioCuesPlayer(); + }else + { + LOGDEBUG("playerStateChanged()状态发生变化,但不为停止状态,[%d]",state); + } +} + +void CAlarmMediaPlayer::updateAudioCuesPlayer() +{ + if(!m_bHaveValidAudioDev || !m_pMediaPlayer || m_listAlarmAudio.isEmpty() || m_pMediaPlayer->state() != QMediaPlayer::StoppedState) + { + qDebug() << "updateAudioCuesPlayer() return"; + LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesPlayer(),return"); + return; + } + LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesPlayer(),继续往下执行"); + QStringList strAudioFileNames; + QList::iterator it = m_listAlarmAudio.begin(); + while (it != m_listAlarmAudio.end()) { + if(it->first->deleteFlag || it->first->releaseFlag) + { + it = m_listAlarmAudio.erase(it); + }else + { + strAudioFileNames = it->second; + if(strAudioFileNames.isEmpty()) + { + it = m_listAlarmAudio.erase(it); + }else + { + break; + } + } + } + m_pMediaPlayer->playlist()->clear(); + foreach (QString fileName, strAudioFileNames) + { + if(!fileName.isEmpty()) + { + fileName = m_strMediaPath + fileName; + if(QFile::exists(fileName)) + { + m_pMediaPlayer->playlist()->addMedia(QUrl::fromLocalFile(fileName)); + } + } + } + + if(!m_pMediaPlayer->playlist()->isEmpty()) + { + m_pMediaPlayer->play(); + }else + { + LOGINFO("CAlarmMediaPlayer::updateAudioCuesPlayer(),播放列表为空"); + } +} + +void CAlarmMediaPlayer::printError(QMediaPlayer::Error error) +{ + LOGERROR("QMediaPlayer error == %d , errorString : %s",error,m_pMediaPlayer->errorString().toStdString().c_str()); + //qDebug("QMediaPlayer error == %d , errorString : %s",error,m_pMediaPlayer->errorString().toStdString().c_str()); +} + +void CAlarmMediaPlayer::checkAudioDev() +{ + //< 周期性检测音频设备有效性,因为: + //< 1、声卡是可以热拔插的,比如USB声卡 + //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 + + bool bHaveValidDev = false; + + //< 注意:在win系统,qt5.9.9以及5.12.9上测试,下面使用QAudioDeviceInfo检测的方法,本身会导致内存上涨 + { + // //< 测试结果:无论windows audio服务是否启动,defaultOutputDevice看上去都是对的,所以,不能用这个判断是否有效 + + // QList listDev(QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)); + + // //< 不能仅仅检测列表是否为空,还需要检测有效性 + // //< 当有声卡硬件,但是Windows Audio服务未启动时,设备列表不为空,但如果播放依然可能导致内存上涨问题 + // foreach (QAudioDeviceInfo objDev, listDev) + // { + // //< 当Window Audio服务未启动时,无法获取有效的格式信息,以此判断 + // if(objDev.preferredFormat().isValid()) + // { + // bHaveValidDev = true; + // break; + // } + // } + } + + //< 不得已,使用win系统原生API条件编译 +#ifdef OS_WINDOWS + { + //< 获取系统默认主设备的音量,如果成功则至少说明: + //< 1、有声卡; 2、Windows Audio服务正常 + + CoInitialize(NULL); + IMMDeviceEnumerator *pDevEnumerator = NULL; + CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDevEnumerator); + + if(NULL != pDevEnumerator) + { + IMMDevice *pDefaultDev = NULL; + pDevEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDefaultDev); + + pDevEnumerator->Release(); + pDevEnumerator = NULL; + + if(NULL != pDefaultDev) + { + IAudioEndpointVolume *pEndpointVol = NULL; + pDefaultDev->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&pEndpointVol); + + pDefaultDev->Release(); + pDefaultDev = NULL; + + if(NULL != pEndpointVol) + { + float fVol; + const HRESULT nResult = pEndpointVol->GetMasterVolumeLevelScalar(&fVol); + if(S_OK == nResult) + bHaveValidDev = true; + + pEndpointVol->Release(); + pEndpointVol = NULL; + } + } + } + + CoUninitialize(); + } +#else + //< 在Linux系统下测试,即使没有声卡也未见问题,暂时不做检测 + bHaveValidDev = true; +#endif + + if(m_bHaveValidAudioDev && !bHaveValidDev) + { + LOGERROR("No valid audio output device !"); + m_bHaveValidAudioDev = false; + m_pMediaPlayer->stop(); + } + else if(!m_bHaveValidAudioDev && bHaveValidDev) + { + LOGINFO("Valid audio output device detected !"); + + //< 不重新构造可能不能正常播放 + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + m_bHaveValidAudioDev = true; + initPlayer(); + updateAudioCuesPlayer(); + } + + //qDebug() << "m_bHaveValidAudioDev = " << m_bHaveValidAudioDev; +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMediaPlayer.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMediaPlayer.h index 8213d77c..52cc2746 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMediaPlayer.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMediaPlayer.h @@ -1,78 +1,78 @@ -#ifndef CALARMMEDIAPLAYER_H -#define CALARMMEDIAPLAYER_H - -#include -#include -#include -#include -#include "CAlarmMsgInfo.h" - -//< 告警语音最大条数 -//extern const int MAX_AUDIO_COUNT; - -typedef QPair AlarmAudioPair; - -class CAlarmMediaPlayer : public QObject -{ - Q_OBJECT -public: - static CAlarmMediaPlayer * instance(); - ~CAlarmMediaPlayer(); - - /** - * @brief slotAudioCuesEnable 静音使能 - * @param bEnable - */ - void setVolumeEnable(bool bEnable); - - void release(); - -public slots: - /** - * @brief insertAudioCues 插入声音告警 - */ - void insertAudioCues(const AlarmMsgPtr &info, const QStringList &strAudioFileNames); - - /** - * @brief removeAudioCues 移除声音告警 - * @param info - */ - void removeAudioCues(const AlarmMsgPtr &info); - -private: - CAlarmMediaPlayer(); - /** - * @brief updateAudioCuesPlayer 更新播放文件 - */ - void updateAudioCuesPlayer(); - - void initPlayer(); - -private slots: - /** - * @brief playerStateChanged 播放器状态变化 - */ - void playerStateChanged(QMediaPlayer::State state); - - void printError(QMediaPlayer::Error error); - - void checkAudioDev(); - -private: - //< 机器有有效的音频输出设备 - //< 如果没有输出设备,会导致内存上涨,在Windows Server 2016上实测如此 - bool m_bHaveValidAudioDev; - - QString m_strMediaPath; - QMediaPlayer *m_pMediaPlayer; - - //< 周期性检测音频设备有效性,因为: - //< 1、声卡是可以热拔插的,比如USB声卡 - //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 - QTimer *m_pTimerCheckAudioDev; - - QList m_listAlarmAudio; //告警语音 - -}; - -#endif // CALARMMEDIAPLAYER_H +#ifndef CALARMMEDIAPLAYER_H +#define CALARMMEDIAPLAYER_H + +#include +#include +#include +#include +#include "CAlarmMsgInfo.h" + +//< 告警语音最大条数 +//extern const int MAX_AUDIO_COUNT; + +typedef QPair AlarmAudioPair; + +class CAlarmMediaPlayer : public QObject +{ + Q_OBJECT +public: + static CAlarmMediaPlayer * instance(); + ~CAlarmMediaPlayer(); + + /** + * @brief slotAudioCuesEnable 静音使能 + * @param bEnable + */ + void setVolumeEnable(bool bEnable); + + void release(); + +public slots: + /** + * @brief insertAudioCues 插入声音告警 + */ + void insertAudioCues(const AlarmMsgPtr &info, const QStringList &strAudioFileNames); + + /** + * @brief removeAudioCues 移除声音告警 + * @param info + */ + void removeAudioCues(const AlarmMsgPtr &info); + +private: + CAlarmMediaPlayer(); + /** + * @brief updateAudioCuesPlayer 更新播放文件 + */ + void updateAudioCuesPlayer(); + + void initPlayer(); + +private slots: + /** + * @brief playerStateChanged 播放器状态变化 + */ + void playerStateChanged(QMediaPlayer::State state); + + void printError(QMediaPlayer::Error error); + + void checkAudioDev(); + +private: + //< 机器有有效的音频输出设备 + //< 如果没有输出设备,会导致内存上涨,在Windows Server 2016上实测如此 + bool m_bHaveValidAudioDev; + + QString m_strMediaPath; + QMediaPlayer *m_pMediaPlayer; + + //< 周期性检测音频设备有效性,因为: + //< 1、声卡是可以热拔插的,比如USB声卡 + //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 + QTimer *m_pTimerCheckAudioDev; + + QList m_listAlarmAudio; //告警语音 + +}; + +#endif // CALARMMEDIAPLAYER_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgInfo.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgInfo.cpp index b33867c5..3f817705 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgInfo.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgInfo.cpp @@ -1,1000 +1,1000 @@ -#include "CAlarmMsgInfo.h" -#include -#include "CAlarmDataCollect.h" -#include -#include "CAiAlarmMsgInfo.h" -#include "pub_logger_api/logger.h" - -using namespace std; -CAlarmMsgInfo::CAlarmMsgInfo() -{ - alm_type = -1; - alm_status = -1; - logic_state = E_ALS_ALARM; - time_stamp = 1000; - domain_id = -1; - - location_id = -1; - app_id = -1; - uuid_base64 = QString(); - content = QString(); - priority = -1; - - if_water_alm = -1; - sound_file = QStringList(); - dev_type = -1; - region_id = -1; - dev_group_tag =QString(); - - key_id_tag = QString(); - graph_name = QString(); - priorityOrder = -1; - deleteFlag = false; - releaseFlag = false; - device = QString(); - m_needVideoAlm = false; - m_camera = QString(); - m_preset = QString(); -} - -CAlarmMsgInfo::CAlarmMsgInfo(const CAlarmMsgInfo &other) -{ - alm_type = other.alm_type; - alm_status = other.alm_status; - logic_state = other.logic_state; - time_stamp = other.time_stamp; - domain_id = other.domain_id; - - location_id = other.location_id; - app_id = other.app_id; - uuid_base64 = other.uuid_base64; - content = other.content; - priority = other.priority; - - priorityOrder = other.priorityOrder; - if_water_alm = other.if_water_alm; - sound_file = other.sound_file; - dev_type = other.dev_type; - region_id = other.region_id; - - dev_group_tag =other.dev_group_tag; - key_id_tag = other.key_id_tag; - graph_name = other.graph_name; - deleteFlag = other.deleteFlag; - releaseFlag = other.releaseFlag; - device = other.device; - m_needVideoAlm = other.m_needVideoAlm; - m_camera = other.m_camera; - m_preset = other.m_preset; - -} - -void CAlarmMsgInfo::initialize(const kbd_idlfile::SAlmInfoToAlmClt &alarmInfo) -{ - alm_type = alarmInfo.alm_type(); - alm_status = alarmInfo.alm_status(); - logic_state = (E_ALARM_LOGICSTATE)alarmInfo.logic_state(); - time_stamp = alarmInfo.time_stamp(); - domain_id = alarmInfo.domain_id(); - - location_id = alarmInfo.location_id(); - app_id = alarmInfo.app_id(); - - uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); - - - content = QString::fromStdString(alarmInfo.content()); - priority = alarmInfo.priority(); - - if_water_alm = alarmInfo.if_water_alm(); - sound_file.clear(); - for(int nIndex(0); nIndex < alarmInfo.sound_file_size(); nIndex++) - { - sound_file << QString::fromStdString(alarmInfo.sound_file(nIndex)); - } - - dev_type = alarmInfo.dev_type(); - if(alarmInfo.has_region_id() && alarmInfo.region_id() > 0) - { - region_id = alarmInfo.region_id(); - } - else - { - region_id = -1; - } - - if(alarmInfo.has_dev_group_tag()) - { - dev_group_tag = QString::fromStdString(alarmInfo.dev_group_tag()); - } - - if(alarmInfo.has_key_id_tag()) - { - key_id_tag = QString::fromStdString(alarmInfo.key_id_tag()); - QStringList tagList = key_id_tag.split("."); - if(tagList.size() == 5) - { - device = tagList.at(1) + "." + tagList.at(2); - } - } - - if(alarmInfo.has_graph_name()) - { - graph_name = QString::fromStdString(alarmInfo.graph_name()); - } - if(logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_ALARM_CFM_DEL || - logic_state == E_ALS_RETURN_DEL || logic_state == E_ALS_RETURN_CFM_DEL) - { - deleteFlag = true; - }else - { - deleteFlag = false; - } - releaseFlag = false; - m_camera = QString::fromStdString(alarmInfo.camera_tag()); - m_preset = QString::fromStdString(alarmInfo.camera_preset()); -} - -bool CAlarmMsgInfo::lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) - { - case E_SORT_PRIORITY: - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - else if(priorityOrder < info->priorityOrder) - { - return false; - } - else if(priorityOrder == info->priorityOrder) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_TIME: - { - if(time_stamp < info->time_stamp) - { - return true; - } - if(time_stamp > info->time_stamp) - { - return false; - } - else if(time_stamp == info->time_stamp) - { - if(priorityOrder > info->priorityOrder) - { - return false; - } - return true; - } - break; - } - case E_SORT_LOCATION: - { - if(location_id < info->location_id) - { - return true; - } - else if(location_id > info->location_id) - { - return false; - } - else if(location_id == info->location_id) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_REGION: - { - if(region_id < info->region_id) - { - return true; - } - else if(region_id > info->region_id) - { - return false; - } - else if(region_id == info->region_id) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_TYPE: - { - if(alm_type < info->alm_type) - { - return true; - } - else if(alm_type > info->alm_type) - { - return false; - } - else if(alm_type == info->alm_type) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_LOGICSTATE: - { - if((logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN) && (info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM)) - { - return true; - } - else if((info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) && (logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM)) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_ALM_STATE: - { - if(alm_status < info->alm_status) - { - return true; - } - else if(alm_status > info->alm_status) - { - return false; - } - else if(alm_status == info->alm_status) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_CONTENT: - { - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else if(content == info->content) - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - } - default: - break; - } - return false; -} - -bool CAlarmMsgInfo::moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) - { - case E_SORT_PRIORITY: - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - else if(priorityOrder > info->priorityOrder) - { - return false; - } - else if(priorityOrder == info->priorityOrder) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TIME: - { - if(time_stamp > info->time_stamp) - { - return true; - } - if(time_stamp < info->time_stamp) - { - return false; - } - else if(time_stamp == info->time_stamp) - { - if(priorityOrder < info->priorityOrder) - { - return false; - } - return true; - } - break; - } - case E_SORT_LOCATION: - { - if(location_id > info->location_id) - { - return true; - } - else if(location_id < info->location_id) - { - return false; - } - else if(location_id == info->location_id) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_REGION: - { - if(region_id > info->region_id) - { - return true; - } - else if(region_id < info->region_id) - { - return false; - } - else if(region_id == info->region_id) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TYPE: - { - if(alm_type > info->alm_type) - { - return true; - } - else if(alm_type < info->alm_type) - { - return false; - } - else if(alm_type == info->alm_type) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_LOGICSTATE: - { - if((logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN) && (info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM)) - { - return false; - } - else if((info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) && (logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM)) - { - return true; - } - else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_ALM_STATE: - { - if(alm_status > info->alm_status) - { - return true; - } - else if(alm_status < info->alm_status) - { - return false; - } - else if(alm_status == info->alm_status) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_CONTENT: - { - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content > info->content) - { - return true; - } - else if(content < info->content) - { - return false; - } - else if(content == info->content) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - default: - break; - } - return false; -} - -bool CAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priority > info->priority) - { - return true; - }else if(priority < info->priority) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp < info->time_stamp) - { - return true; - }else if(time_stamp > info->time_stamp) - { - return false; - }else - { - if(priority > info->priority) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - if(location_id < info->location_id) - { - return true; - }else if(location_id > info->location_id) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_REGION: - if(region_id < info->region_id) - { - return true; - }else if(region_id > info->region_id) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - - break; - case E_SORT_TYPE: - if(alm_type < info->alm_type) - { - return true; - }else if(alm_type > info->alm_type) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - if((logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)&&( - info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL)) - { - return true; - }else if((info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL)&&( - logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL)) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_ALM_STATE: - if(alm_status < info->alm_status) - { - return true; - }else if(alm_status > info->alm_status) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - default: - break; - } - return false; -} -//< 优先级小的大于优先级大的、时间大的大于时间小的、车站id大的大于车站id小的、责任区id大的大于责任区id小的、告警类型大的大于告警类型小的、 -//< 告警内容都为空,则前者小于后者、告警内容为空的小于告警内容不为空的、告警未确认的大于告警已确认的、告警状态大的大于告警状态小的 -bool CAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priority < info->priority) - { - return true; - }else if(priority > info->priority) - { - return false; - }else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp > info->time_stamp) - { - return true; - }else if(time_stamp < info->time_stamp) - { - return false; - }else - { - if(priority < info->priority) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - if(location_id > info->location_id) - { - return true; - }else if(location_id < info->location_id) - { - return false; - }else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_REGION: - if(region_id > info->region_id) - { - return true; - }else if(region_id < info->region_id) - { - return false; - }else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - - break; - case E_SORT_TYPE: - if(alm_type > info->alm_type) - { - return true; - }else if(alm_type < info->alm_type) - { - return false; - }else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content > info->content) - { - return true; - } - else if(content < info->content) - { - return false; - } - else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - if((logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)&&( - info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL)) - { - return false; - }else if((info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL)&&( - logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL)) - { - return true; - }else - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - case E_SORT_ALM_STATE: - if(alm_status > info->alm_status) - { - return true; - }else if(alm_status < info->alm_status) - { - return false; - }else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - default: - break; - } - return false; -} - -bool CAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priority > info->priority) - { - return true; - }else if(priority < info->priority) - { - return false; - }else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp < info->time_stamp) - { - return true; - }else if(time_stamp > info->time_stamp) - { - return false; - }else - { - if(priority > info->priority) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return true; - break; - case E_SORT_REGION: - return true; - break; - case E_SORT_TYPE: - return true; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else - { - if(time_stamp < info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return true; - case E_SORT_ALM_STATE: - return true; - break; - default: - break; - } - return false; -} - -bool CAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_PRIORITY: - if(priority < info->priority) - { - return true; - }else if(priority > info->priority) - { - return false; - }else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_TIME: - if(time_stamp > info->time_stamp) - { - return true; - }else if(time_stamp < info->time_stamp) - { - return false; - }else - { - if(priority < info->priority) - { - return true; - } - return false; - } - break; - case E_SORT_LOCATION: - return false; - break; - case E_SORT_REGION: - return false; - break; - case E_SORT_TYPE: - return false; - break; - case E_SORT_CONTENT: - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content > info->content) - { - return true; - } - else if(content < info->content) - { - return false; - } - else - { - if(time_stamp > info->time_stamp) - { - return true; - } - return false; - } - break; - case E_SORT_LOGICSTATE: - return false; - break; - case E_SORT_ALM_STATE: - return false; - break; - default: - break; - } - return false; -} - -bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target) -{ - if(source.uuid_base64 == target.uuid_base64) - { - return true; - } - return false; -// //替换式告警且车站、测点ID相同 -// if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) -// { -// return true; -// } -// //流水账告警且时标、告警内容相同 -// else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) -// { -// return true; -// } -// return false; -} +#include "CAlarmMsgInfo.h" +#include +#include "CAlarmDataCollect.h" +#include +#include "CAiAlarmMsgInfo.h" +#include "pub_logger_api/logger.h" + +using namespace std; +CAlarmMsgInfo::CAlarmMsgInfo() +{ + alm_type = -1; + alm_status = -1; + logic_state = E_ALS_ALARM; + time_stamp = 1000; + domain_id = -1; + + location_id = -1; + app_id = -1; + uuid_base64 = QString(); + content = QString(); + priority = -1; + + if_water_alm = -1; + sound_file = QStringList(); + dev_type = -1; + region_id = -1; + dev_group_tag =QString(); + + key_id_tag = QString(); + graph_name = QString(); + priorityOrder = -1; + deleteFlag = false; + releaseFlag = false; + device = QString(); + m_needVideoAlm = false; + m_camera = QString(); + m_preset = QString(); +} + +CAlarmMsgInfo::CAlarmMsgInfo(const CAlarmMsgInfo &other) +{ + alm_type = other.alm_type; + alm_status = other.alm_status; + logic_state = other.logic_state; + time_stamp = other.time_stamp; + domain_id = other.domain_id; + + location_id = other.location_id; + app_id = other.app_id; + uuid_base64 = other.uuid_base64; + content = other.content; + priority = other.priority; + + priorityOrder = other.priorityOrder; + if_water_alm = other.if_water_alm; + sound_file = other.sound_file; + dev_type = other.dev_type; + region_id = other.region_id; + + dev_group_tag =other.dev_group_tag; + key_id_tag = other.key_id_tag; + graph_name = other.graph_name; + deleteFlag = other.deleteFlag; + releaseFlag = other.releaseFlag; + device = other.device; + m_needVideoAlm = other.m_needVideoAlm; + m_camera = other.m_camera; + m_preset = other.m_preset; + +} + +void CAlarmMsgInfo::initialize(const kbd_idlfile::SAlmInfoToAlmClt &alarmInfo) +{ + alm_type = alarmInfo.alm_type(); + alm_status = alarmInfo.alm_status(); + logic_state = (E_ALARM_LOGICSTATE)alarmInfo.logic_state(); + time_stamp = alarmInfo.time_stamp(); + domain_id = alarmInfo.domain_id(); + + location_id = alarmInfo.location_id(); + app_id = alarmInfo.app_id(); + + uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); + + + content = QString::fromStdString(alarmInfo.content()); + priority = alarmInfo.priority(); + + if_water_alm = alarmInfo.if_water_alm(); + sound_file.clear(); + for(int nIndex(0); nIndex < alarmInfo.sound_file_size(); nIndex++) + { + sound_file << QString::fromStdString(alarmInfo.sound_file(nIndex)); + } + + dev_type = alarmInfo.dev_type(); + if(alarmInfo.has_region_id() && alarmInfo.region_id() > 0) + { + region_id = alarmInfo.region_id(); + } + else + { + region_id = -1; + } + + if(alarmInfo.has_dev_group_tag()) + { + dev_group_tag = QString::fromStdString(alarmInfo.dev_group_tag()); + } + + if(alarmInfo.has_key_id_tag()) + { + key_id_tag = QString::fromStdString(alarmInfo.key_id_tag()); + QStringList tagList = key_id_tag.split("."); + if(tagList.size() == 5) + { + device = tagList.at(1) + "." + tagList.at(2); + } + } + + if(alarmInfo.has_graph_name()) + { + graph_name = QString::fromStdString(alarmInfo.graph_name()); + } + if(logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_ALARM_CFM_DEL || + logic_state == E_ALS_RETURN_DEL || logic_state == E_ALS_RETURN_CFM_DEL) + { + deleteFlag = true; + }else + { + deleteFlag = false; + } + releaseFlag = false; + m_camera = QString::fromStdString(alarmInfo.camera_tag()); + m_preset = QString::fromStdString(alarmInfo.camera_preset()); +} + +bool CAlarmMsgInfo::lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + else if(priorityOrder < info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp < info->time_stamp) + { + return true; + } + if(time_stamp > info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder > info->priorityOrder) + { + return false; + } + return true; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id < info->location_id) + { + return true; + } + else if(location_id > info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_REGION: + { + if(region_id < info->region_id) + { + return true; + } + else if(region_id > info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type < info->alm_type) + { + return true; + } + else if(alm_type > info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOGICSTATE: + { + if((logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN) && (info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM)) + { + return true; + } + else if((info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) && (logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM)) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_ALM_STATE: + { + if(alm_status < info->alm_status) + { + return true; + } + else if(alm_status > info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + else if(priorityOrder > info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp > info->time_stamp) + { + return true; + } + if(time_stamp < info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder < info->priorityOrder) + { + return false; + } + return true; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id > info->location_id) + { + return true; + } + else if(location_id < info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id > info->region_id) + { + return true; + } + else if(region_id < info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type > info->alm_type) + { + return true; + } + else if(alm_type < info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_LOGICSTATE: + { + if((logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN) && (info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM)) + { + return false; + } + else if((info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) && (logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM)) + { + return true; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_ALM_STATE: + { + if(alm_status > info->alm_status) + { + return true; + } + else if(alm_status < info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priority > info->priority) + { + return true; + }else if(priority < info->priority) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priority > info->priority) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + if(location_id < info->location_id) + { + return true; + }else if(location_id > info->location_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_REGION: + if(region_id < info->region_id) + { + return true; + }else if(region_id > info->region_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + + break; + case E_SORT_TYPE: + if(alm_type < info->alm_type) + { + return true; + }else if(alm_type > info->alm_type) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + if((logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)&&( + info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL)) + { + return true; + }else if((info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL)&&( + logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL)) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_ALM_STATE: + if(alm_status < info->alm_status) + { + return true; + }else if(alm_status > info->alm_status) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + default: + break; + } + return false; +} +//< 优先级小的大于优先级大的、时间大的大于时间小的、车站id大的大于车站id小的、责任区id大的大于责任区id小的、告警类型大的大于告警类型小的、 +//< 告警内容都为空,则前者小于后者、告警内容为空的小于告警内容不为空的、告警未确认的大于告警已确认的、告警状态大的大于告警状态小的 +bool CAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priority < info->priority) + { + return true; + }else if(priority > info->priority) + { + return false; + }else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priority < info->priority) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + if(location_id > info->location_id) + { + return true; + }else if(location_id < info->location_id) + { + return false; + }else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_REGION: + if(region_id > info->region_id) + { + return true; + }else if(region_id < info->region_id) + { + return false; + }else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + + break; + case E_SORT_TYPE: + if(alm_type > info->alm_type) + { + return true; + }else if(alm_type < info->alm_type) + { + return false; + }else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + if((logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)&&( + info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL)) + { + return false; + }else if((info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL)&&( + logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL)) + { + return true; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_ALM_STATE: + if(alm_status > info->alm_status) + { + return true; + }else if(alm_status < info->alm_status) + { + return false; + }else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priority > info->priority) + { + return true; + }else if(priority < info->priority) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priority > info->priority) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return true; + case E_SORT_ALM_STATE: + return true; + break; + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priority < info->priority) + { + return true; + }else if(priority > info->priority) + { + return false; + }else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priority < info->priority) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else + { + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return false; + break; + case E_SORT_ALM_STATE: + return false; + break; + default: + break; + } + return false; +} + +bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target) +{ + if(source.uuid_base64 == target.uuid_base64) + { + return true; + } + return false; +// //替换式告警且车站、测点ID相同 +// if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) +// { +// return true; +// } +// //流水账告警且时标、告警内容相同 +// else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) +// { +// return true; +// } +// return false; +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgInfo.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgInfo.h index 7f9adf59..2f9a69db 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgInfo.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgInfo.h @@ -1,81 +1,81 @@ -#ifndef ALARMMSGINFO_H -#define ALARMMSGINFO_H - -#include -#include -#include -#include "alarm_server_api/CAlmApiForAlmClt.h" -#include "CAlarmCommon.h" -//< 告警操作 权限定义 -#define FUNC_SPE_ALARM_OPERATE ("FUNC_SPE_ALARM_OPERATE") - -// 逻辑状态 -enum E_ALARM_LOGICSTATE -{ - E_ALS_ALARM = 0, // 告警状态 - E_ALS_ALARM_CFM =1, // 告警确认状态 - E_ALS_RETURN=2, // 告警返回状态 - E_ALS_RETURN_CFM=3, // 告警返回确认状态 - - //在原始告警窗删除后,可能还需要在智能告警窗展示 - E_ALS_ALARM_DEL = 20, // 告警状态,且在原始告警窗已删除,可能是达到数量上限而删除 - E_ALS_ALARM_CFM_DEL =21, // 告警确认状态,且在原始告警窗已删除 - E_ALS_RETURN_DEL=22, // 告警返回状态,且在原始告警窗已删除,可能是达到数量上限而删除 - E_ALS_RETURN_CFM_DEL=23, // 告警返回确认状态,且在原始告警窗已删除 -}; - -class CAlarmMsgInfo -{ -public: - CAlarmMsgInfo(); - CAlarmMsgInfo(const CAlarmMsgInfo &other); - void initialize(const kbd_idlfile::SAlmInfoToAlmClt &alarmInfo); - int getCameraInfoByTag(const QString &tag); - - //< [优先级越小表示越大]-原始告警窗调用 - bool lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - //< [优先级越小表示越大]-智能告警窗调用 - bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - qint32 alm_type; //< 告警类型 - int alm_status; //< 告警状态 - E_ALARM_LOGICSTATE logic_state; //< 逻辑状态 - quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) - qint32 domain_id; //< 域ID - qint32 location_id; //< 位置ID - qint32 app_id; //< 应用号 - qint32 priority; //< 告警优先级id - qint32 if_water_alm; //< 是否流水账告警(0 替换式告警,1 流水账告警) - QString uuid_base64; //< uuid 主键 - QString content; //< 告警内容 - QStringList sound_file; //< 语音文件名 - //可选 - qint32 sub_system; //< 专业 - qint32 dev_type; //< 设备类型ID - qint32 region_id; //< 责任区ID - QString dev_group_tag; //< 设备组 - QString key_id_tag; //< 测点ID - QString graph_name; //< 告警关联画面名称 - - //< Extend - qint32 priorityOrder; //< 优先级 - QString device; //< 设备 (保留) - bool deleteFlag; //< 是否被删除 - bool releaseFlag; //< 释放标志 - bool m_needVideoAlm; //< 是否需要视频告警 - QString m_camera; - QString m_preset; - -}; - -bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target); - -Q_DECLARE_METATYPE(CAlarmMsgInfo) -Q_DECLARE_METATYPE(AlarmMsgPtr) - -#endif // ALARMMSGINFO_H +#ifndef ALARMMSGINFO_H +#define ALARMMSGINFO_H + +#include +#include +#include +#include "alarm_server_api/CAlmApiForAlmClt.h" +#include "CAlarmCommon.h" +//< 告警操作 权限定义 +#define FUNC_SPE_ALARM_OPERATE ("FUNC_SPE_ALARM_OPERATE") + +// 逻辑状态 +enum E_ALARM_LOGICSTATE +{ + E_ALS_ALARM = 0, // 告警状态 + E_ALS_ALARM_CFM =1, // 告警确认状态 + E_ALS_RETURN=2, // 告警返回状态 + E_ALS_RETURN_CFM=3, // 告警返回确认状态 + + //在原始告警窗删除后,可能还需要在智能告警窗展示 + E_ALS_ALARM_DEL = 20, // 告警状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_ALARM_CFM_DEL =21, // 告警确认状态,且在原始告警窗已删除 + E_ALS_RETURN_DEL=22, // 告警返回状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_RETURN_CFM_DEL=23, // 告警返回确认状态,且在原始告警窗已删除 +}; + +class CAlarmMsgInfo +{ +public: + CAlarmMsgInfo(); + CAlarmMsgInfo(const CAlarmMsgInfo &other); + void initialize(const kbd_idlfile::SAlmInfoToAlmClt &alarmInfo); + int getCameraInfoByTag(const QString &tag); + + //< [优先级越小表示越大]-原始告警窗调用 + bool lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + //< [优先级越小表示越大]-智能告警窗调用 + bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + qint32 alm_type; //< 告警类型 + int alm_status; //< 告警状态 + E_ALARM_LOGICSTATE logic_state; //< 逻辑状态 + quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) + qint32 domain_id; //< 域ID + qint32 location_id; //< 位置ID + qint32 app_id; //< 应用号 + qint32 priority; //< 告警优先级id + qint32 if_water_alm; //< 是否流水账告警(0 替换式告警,1 流水账告警) + QString uuid_base64; //< uuid 主键 + QString content; //< 告警内容 + QStringList sound_file; //< 语音文件名 + //可选 + qint32 sub_system; //< 专业 + qint32 dev_type; //< 设备类型ID + qint32 region_id; //< 责任区ID + QString dev_group_tag; //< 设备组 + QString key_id_tag; //< 测点ID + QString graph_name; //< 告警关联画面名称 + + //< Extend + qint32 priorityOrder; //< 优先级 + QString device; //< 设备 (保留) + bool deleteFlag; //< 是否被删除 + bool releaseFlag; //< 释放标志 + bool m_needVideoAlm; //< 是否需要视频告警 + QString m_camera; + QString m_preset; + +}; + +bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target); + +Q_DECLARE_METATYPE(CAlarmMsgInfo) +Q_DECLARE_METATYPE(AlarmMsgPtr) + +#endif // ALARMMSGINFO_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgManage.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgManage.cpp index 8ebf9f4d..11f1ee08 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgManage.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgManage.cpp @@ -1,1728 +1,1728 @@ -#include "CAlarmMsgManage.h" -#include -#include -#include -#include -#include "CAlarmDataCollect.h" -#include "service/alarm_server_api/AlarmCommonDef.h" -#include -#include "dbms/db_sysinfo_api/CDbSysInfo.h" -#include "perm_mng_api/PermMngApi.h" - -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" -#include "Common.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CharUtil.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_public; -using namespace std; - -CAlarmMsgManage *CAlarmMsgManage::pInstance = NULL; -CAlarmMsgManage *CAlarmMsgManage::instance() -{ - if(pInstance == NULL) - { - pInstance = new CAlarmMsgManage(); - } - return pInstance; -} - -CAlarmMsgManage::CAlarmMsgManage() - : QObject(), - m_nNDelComAlarmCount(0), - m_nDelNComAlarmCount(0), - m_nAlmTotal(0), - m_nAlmNum(0), - m_bIsError(false) -{ - mutex = new QMutex(); - m_infos.clear(); - m_alarmDeviceStatistical.clear(); - m_alarmDeviceGroupStatistical.clear(); - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - m_listMsgAddCache.clear(); - m_inhibitFilter.clear(); - m_aiinfos.clear(); - m_aicount.clear(); - m_alarm.clear(); - m_idToid.clear(); - m_aitolocation.clear(); - //根据需求 - m_all.clear(); - m_aiall.clear(); - - m_priorityDescriptionMap.clear(); - m_locationDescriptionMap.clear(); - m_regionDescriptionMap.clear(); - m_alarmTypeDescriptionMap.clear(); - m_alarmStatusDescriptionMap.clear(); - m_rtdbAlarmActionAccess = new kbd_dbms::CRdbAccess(); - m_rtdbAlarmActionAccess->open("base", "alarm_level_define"); - - m_rtdbLocationDescriptionAccess = new kbd_dbms::CRdbAccess(); - m_rtdbLocationDescriptionAccess->open("base", "sys_model_location_info"); - - m_rtdbAppDescriptionAccess = new kbd_dbms::CRdbAccess(); - m_rtdbAppDescriptionAccess->open("base", "sys_model_app_info"); - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - m_dbInterface = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - - loadPermInfo(); -} - -void CAlarmMsgManage::refreshCache() -{ - QMutexLocker locker(mutex); - m_listMsgAddCache.clear(); -} - -bool CAlarmMsgManage::isInhibit(const QString &tag_name) -{ - if(m_inhibitFilter.contains(tag_name)) - { - return true; - } - return false; -} - -void CAlarmMsgManage::addInhibitTag(const QString &tag) -{ - m_inhibitFilter.append(tag); -} - -void CAlarmMsgManage::removeInhibitTag(const QString &tag) -{ - m_inhibitFilter.removeAll(tag); -} - -QMap CAlarmMsgManage::getDevAlarm(const QString &device) -{ - QMutexLocker locker(mutex); - QMap alarm; - alarm.clear(); - return m_alarmDevPriority.value(device,alarm); -} - -QMap > CAlarmMsgManage::getDevGroupPriorityDevNum(const QString &deviceGroup) -{ - QMutexLocker locker(mutex); - QMap > alarm; - alarm.clear(); - - return m_alarmDGPDev.value(deviceGroup,alarm); -} - -QHash > CAlarmMsgManage::getLocAlmInfo() -{ - QMutexLocker locker(mutex); - return m_alarmLPAlm; -} - -void CAlarmMsgManage::updataDevGroupByDev(QString devGroup, QString device) -{ - QHash >::iterator it = m_alarmDevPriority.find(device); - int devMaxPriority =-1;//最高优先级 - if(it != m_alarmDevPriority.end()) - { - QMap::iterator itor= it.value().begin(); - - for(;itor!= it.value().end();itor++) - { - if(itor.value()>0) - { - devMaxPriority = itor.key(); - break; - } - } - } - QHash > >::iterator pos = m_alarmDGPDev.find(devGroup); - if(pos != m_alarmDGPDev.end()) - { - QMap > &priorityMap = pos.value(); - QMap >::iterator itor = priorityMap.begin(); - - while (itor != priorityMap.end()) { - QList &list = itor.value(); - if(list.contains(device)) - { - list.removeOne(device); - } - itor++; - } - if(devMaxPriority == -1) - return ; - itor =priorityMap.find(devMaxPriority); - if(itor != priorityMap.end()) - { - QList &devList = itor.value(); - if(!devList.contains(device)) - { - devList.append(device); - } - }else - { - QList list; - list.append(device); - priorityMap.insert(devMaxPriority,list); - } - }else - { - QList list; - list.append(device); - QMap > priorityMap; - priorityMap.insert(devMaxPriority,list); - m_alarmDGPDev.insert(devGroup,priorityMap); - } -} - -void CAlarmMsgManage::openVideoDialog(int domainId, int appId, QString tag, quint64 startTime, quint64 endTime) -{ - emit openVideo(domainId,appId,tag,startTime,endTime); -} - -void CAlarmMsgManage::removeAiAlarmMsgByDomainID(const int &domainId) -{ - QMutexLocker locker(mutex); - /* 清除全缓存 - */ - QHash::iterator pos = m_aiall.begin(); - while (pos != m_aiall.end()) { - if(domainId == (*pos)->domain_id) - { - pos = m_aiall.erase(pos); - continue; - } - pos++; - } - /* 清除有权限和未禁止的缓存 - */ - QHash::iterator it = m_aiinfos.begin(); - while (it != m_aiinfos.end()) - { - if(domainId == (*it)->domain_id) - { - eraseaicount((*it)->uuid_base64); - eraseidtoid((*it)->uuid_base64); - eraseidtolocation((*it)->uuid_base64); - it = m_aiinfos.erase(it); - continue; - } - it++; - } -} -// 添加时不需要通知模型,反正所有数据接收完成之后会全部刷新一下 -void CAlarmMsgManage::addAiAllAlarmMsg(AiAlarmMsgPtr &msg) -{ - QMutexLocker locker(mutex); - m_aiall.insert(msg->uuid_base64,msg); - QVector uuidVec = msg->raw_alm_uuid; - if(!isHaveAlm(uuidVec)) - { - m_delaydeal.append(msg); //延后处理 - return ; - } - if(checkLookPerm(uuidVec)) - { - addidtoid(uuidVec,msg->uuid_base64); - addaicount(uuidVec,msg->uuid_base64); - addaitolocation(uuidVec,msg->uuid_base64); - msg->m_needVideoAlm = initaivideo(uuidVec); - QVector deluuidVec; - updatealarm(uuidVec,deluuidVec); - if(msg->deleteFlag != true && msg->brokenFlag != true) - { - m_nAlmTotal += msg->raw_alm_uuid.size(); - } - m_aiinfos.insert(msg->uuid_base64,msg); - } -} - -void CAlarmMsgManage::addAiAlarmMsg(AiAlarmMsgPtr &msg) -{ - QMutexLocker locker(mutex); - m_aiall.insert(msg->uuid_base64,msg); - QVector uuidVec = msg->raw_alm_uuid; - if(!isHaveAlm(uuidVec)) - { - m_delaydeal.append(msg); //延后处理 - return ; - } - if(checkLookPerm(uuidVec)) - { - addidtoid(uuidVec,msg->uuid_base64); - addaicount(uuidVec,msg->uuid_base64); - addaitolocation(uuidVec,msg->uuid_base64); - msg->m_needVideoAlm = initaivideo(uuidVec); - QVector deluuidVec; - updatealarm(uuidVec,deluuidVec); - emit sigMsgRemove(deluuidVec); - if(msg->deleteFlag != true && msg->brokenFlag != true) - { - m_nAlmTotal += msg->raw_alm_uuid.size(); - } - m_aiinfos.insert(msg->uuid_base64,msg); - emit sigAiMsgAdd(msg); - } -} -//删除智能告警 -void CAlarmMsgManage::delAiAlarmMsg(QString &aiuuid) -{ - QMutexLocker locker(mutex); - //先修改此智能告警状态 - QHash::iterator pos = m_aiall.find(aiuuid); - if(pos != m_aiall.end()) - { - pos.value()->deleteFlag = true; - } - //删除智能告警窗上对应的智能告警 - QHash::iterator it = m_aiinfos.find(aiuuid); - if(it != m_aiinfos.end()) - { - if(it.value()->brokenFlag != true) - { - m_nAlmTotal -= it.value()->raw_alm_uuid.size(); - } - it.value()->deleteFlag = true; - emit sigAiMsgRemove(aiuuid); - } -} -//收到不完整的智能告警则删除 -void CAlarmMsgManage::brokenAiAlarmMsg(QString &aiuuid) -{ - QMutexLocker locker(mutex); - QHash::iterator pos = m_aiall.find(aiuuid); - if(pos != m_aiall.end()) - { - pos.value()->brokenFlag = true; - } - QHash::iterator it = m_aiinfos.find(aiuuid); - if(it != m_aiinfos.end()) - { - if(it.value()->deleteFlag != true) - { - m_nAlmTotal -= it.value()->raw_alm_uuid.size(); - } - it.value()->brokenFlag = true; - - emit sigAiMsgRemove(aiuuid); - } -} - -//释放智能告警(两种情况,1.删除后正常释放,2.请求分离后服务端会要求直接释放此条智能告警,这时,则需要把此条智能告警下关联的原始告警根据过滤后显示在智能告警窗的一级节点上) -void CAlarmMsgManage::releaseAiAlarmMsg(QString &aiuuid) -{ - QMutexLocker locker(mutex); - QHash::iterator pos = m_aiall.find(aiuuid); - if(pos != m_aiall.end()) - { - m_aiall.erase(pos); - } - QHash::iterator it = m_aiinfos.find(aiuuid); - if(it != m_aiinfos.end()) - { - if((*it)->brokenFlag != true && (*it)->deleteFlag != true) - { - m_nAlmTotal -= it.value()->raw_alm_uuid.size(); - } - QList m_listMsg; - QList uuidList = getalmuuidByAiuuid(aiuuid); - for(int index(0);indexdeleteFlag == true) - { - continue; - } - - if(!m_listPermLocationId.contains(almPtr->location_id) || (!m_listPermRegionId.contains(almPtr->region_id) && almPtr->region_id != -1)) - { - continue; - } - m_alarm.insert(almPtr->uuid_base64,almPtr); - if(!m_inhibitFilter.isEmpty() && m_inhibitFilter.contains(almPtr->key_id_tag)) - { - continue; - } - m_listMsg.append(almPtr); - } - eraseaicount(aiuuid); - eraseidtoid(aiuuid); - eraseidtolocation(aiuuid); - m_aiinfos.erase(it); - emit sigAiMsgRemove(aiuuid); - if(m_listMsg.size() > 0) - { - emit sigMsgArrivedToAi(m_listMsg); - } - } -} - -bool CAlarmMsgManage::getAiuuid(QString &uuid, QString &aiuuid) -{ - QMutexLocker locker(mutex); - - aiuuid = m_idToid.value(uuid,""); - if(aiuuid.isEmpty()) - { - return false; - } - return true; -} - -QMap CAlarmMsgManage::getAlarmOtherStatus() -{ - return m_alarmOtherStatusDescriptionMap; -} - -bool CAlarmMsgManage::isBelongAi(const QString &uuid) -{ - QMutexLocker locker(mutex); - if(m_idToid.value(uuid,"").isEmpty()) - { - return false; - } - return false; -} - -void CAlarmMsgManage::eraseaicount(QString &aiuuid) -{ - QHash::iterator it = m_aicount.begin(); - while (it != m_aicount.end()) { - if(aiuuid == it.key()) - { - it = m_aicount.erase(it); - continue; - } - it++; - } -} - -void CAlarmMsgManage::eraseidtoid(QString &aiuuid) -{ - QHash::iterator it = m_idToid.begin(); - while (it != m_idToid.end()) { - if(aiuuid == it.value()) - { - it = m_idToid.erase(it); - continue; - } - it++; - } -} - -void CAlarmMsgManage::eraseidtolocation(QString &aiuuid) -{ - QHash >::iterator it = m_aitolocation.begin(); - while (it != m_aitolocation.end()) { - if(aiuuid == it.key()) - { - it = m_aitolocation.erase(it); - continue; - } - it++; - } -} - -bool CAlarmMsgManage::isHaveAlm(QVector &uuidVec) -{ - - for(int x(0);x < uuidVec.count(); x++) - { - QHash::iterator it = m_all.find(uuidVec.at(x)); - if(it == m_all.end()) - { - return false; - } - } - return true; -} - -bool CAlarmMsgManage::checkLookPerm(QVector &uuidVec) -{ - for(int x(0);x < uuidVec.count(); x++) - { - AlarmMsgPtr ptr = m_all.value(uuidVec.at(x),NULL); - if(ptr == NULL) - { - LOGERROR("checkLookPerm---------------空指针"); - return false; - }else - { - qint32 location_id = ptr->location_id; - qint32 region_id = ptr->region_id; - if(m_listPermLocationId.contains(location_id) && (m_listPermRegionId.contains(region_id) || region_id == -1)) - { - return true; - } - } - - } - return false; -} - -void CAlarmMsgManage::addidtoid(QVector &uuidVec, QString &aiuuid) -{ - for(int x(0);x < uuidVec.count();x++) - { - m_idToid.insert(uuidVec.value(x),aiuuid); - } -} - -void CAlarmMsgManage::addaicount(QVector &uuidVec, QString &aiuuid) -{ - int confirm = 0; - for(int x(0);x < uuidVec.count();x++) - { - QString uuid = uuidVec.value(x) ; - if(getConfirmByuuid(uuid)) - { - confirm++; - } - } - SAiConfirm aiConfirm; - aiConfirm.nConfirm = confirm; - aiConfirm.nTotal = uuidVec.count(); - m_aicount.insert(aiuuid,aiConfirm); -} - -void CAlarmMsgManage::addaitolocation(QVector &uuidVec, QString &aiuuid) -{ - QHash >::iterator it =m_aitolocation.find(aiuuid); - if(it != m_aitolocation.end()) - { - m_aitolocation.erase(it); - } - QList locationList; - for(int x(0);x < uuidVec.count();x++) - { - int location = -1; - QString uuid = uuidVec.value(x) ; - if(getLocationByuuid(uuid,location)&&!locationList.contains(location)) - { - locationList.append(location); - } - } - m_aitolocation.insert(aiuuid,locationList); -} - -bool CAlarmMsgManage::initaivideo(QVector &uuidVec) -{ - bool flag = false; - for(int x(0);x < uuidVec.count();x++) - { - QString uuid = uuidVec.value(x) ; - if(getVideoFlagByuuid(uuid,flag) && flag) - { - return flag; - } - } - return flag; -} - -bool CAlarmMsgManage::getLocationByuuid(QString &uuid, int &location) -{ - AlarmMsgPtr ptr = m_all.value(uuid,NULL); - if(ptr != NULL) - { - location = ptr->location_id; - return true; - }else - { - //需要打标记 - m_bIsError = true; - LOGERROR("getConfirmByuuid():未查询到uuid =[%s]的原始告警信息",uuid.toStdString().c_str()); - } - return false; -} - -bool CAlarmMsgManage::getVideoFlagByuuid(QString &uuid, bool &flag) -{ - AlarmMsgPtr ptr = m_all.value(uuid,NULL); - if(ptr != NULL) - { - flag = ptr->m_needVideoAlm; - return true; - }else - { - //需要打标记 - m_bIsError = true; - LOGERROR("getConfirmByuuid():未查询到uuid =[%s]的原始告警信息",uuid.toStdString().c_str()); - } - return false; -} - -bool CAlarmMsgManage::getConfirmByuuid(QString &uuid) -{ - AlarmMsgPtr ptr = m_all.value(uuid,NULL); - if(ptr != NULL) - { - if(ptr->logic_state != E_ALS_ALARM_CFM &&ptr->logic_state != E_ALS_RETURN_CFM && - ptr->logic_state != E_ALS_ALARM_CFM_DEL &&ptr->logic_state != E_ALS_RETURN_CFM_DEL) - { - return false; - } - else - { - return true; - } - }else - { - //需要重新拉数据 - m_bIsError = true; - LOGERROR("getConfirmByuuid():未查询到uuid =[%s]的原始告警信息",uuid.toStdString().c_str()); - } - return false; -} - -//<添加智能告警时,需要删除此条智能告警下还存在一级节点上的原始告警 -void CAlarmMsgManage::updatealarm(QVector &uuidVec,QVector &deluuidVec) -{ - deluuidVec.clear(); - for(int index(0);index::iterator it =m_alarm.find(uuidVec.at(index)); - if(it != m_alarm.end()) - { - m_alarm.remove(uuidVec.at(index)); - deluuidVec.append(uuidVec.at(index)); - } - } -} - -void CAlarmMsgManage::loadAlarmInfoConfig() -{ - loadPriorityDescription(); - loadLocationDescription(); - loadRegionDescription(); - loadAlarmTypeDescription(); - loadAlarmStatusDescription(); - loadDeviceTypeDescription(); - loadDeviceGroupDescription(); - loadAlarmShowStatusDescription(); - loadAlarmOtherStatusDescription(); -} - -void CAlarmMsgManage::loadPriorityDescription() -{ - if(m_rtdbAccess->open("base", "alarm_level_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("priority_id"); - columns.push_back("priority_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmMsgManage::loadLocationDescription() -{ - if(m_rtdbAccess->open("base", "sys_model_location_info")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("location_id"); - columns.push_back("description"); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); -// if(m_listPermLocationId.contains(key.toInt())) -// { - m_locationDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); -// } - } - } - } -} - -void CAlarmMsgManage::loadRegionDescription() -{ - if(m_rtdbAccess->open("base", "region_info")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("region_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); -// if(m_listPermRegionId.contains(key.toInt())) -// { - m_regionDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); -// } - } - } - } - m_regionDescriptionMap[-1] = QString(); -} - -void CAlarmMsgManage::loadAlarmTypeDescription() -{ - if(m_rtdbAccess->open("base", "alarm_type_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("type_id"); - columns.push_back("type_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmMsgManage::loadAlarmStatusDescription() -{ - if(m_rtdbAccess->open("base", "alarm_status_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("status_value"); - columns.push_back("display_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmStatusDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmMsgManage::loadDeviceTypeDescription() -{ - if(m_rtdbAccess->open("base", "dev_type_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("dev_type_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmMsgManage::loadDeviceGroupDescription() -{ - if(m_rtdbAccess->open("base", "dev_group")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("tag_name"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); - } - } - } -} - -void CAlarmMsgManage::loadAlarmShowStatusDescription() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - if(StringToInt(strKey) != 0) - { - m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; - }else - { - m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = tr("其他"); - } - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -void CAlarmMsgManage::loadAlarmOtherStatusDescription() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - m_alarmOtherStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -void CAlarmMsgManage::almStats(const AlarmMsgPtr &msg, int addOrSub) -{ - if(addOrSub == 1) - { - almAddStats(msg); - }else - { - almSubStats(msg); - } -} - -void CAlarmMsgManage::almAddStats(const AlarmMsgPtr &msg) -{ - devDevGTotAlmAddStats(msg); - devDevGAddStats(msg); - locAddStats(msg); -} - -void CAlarmMsgManage::almSubStats(const AlarmMsgPtr &msg) -{ - devDevGTotAlmSubStats(msg); - devDevGSubStats(msg); - locSubStats(msg); -} - -void CAlarmMsgManage::devDevGTotAlmAddStats(const AlarmMsgPtr &msg) -{ - - int dCount = m_alarmDeviceStatistical.value(msg->device, 0);//设备告警数量 - int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 - - ++dgCount; // +1 - ++dCount; // +1 - - if(dCount <= 0) - { - m_alarmDeviceStatistical.remove(msg->device); - } - else - { - m_alarmDeviceStatistical.insert(msg->device, dCount); - } - if(dgCount <= 0) - { - m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); - } - else - { - m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); - } -} - -void CAlarmMsgManage::devDevGTotAlmSubStats(const AlarmMsgPtr &msg) -{ - int dCount = m_alarmDeviceStatistical.value(msg->device, 0); //设备告警数量 - int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 - - --dgCount; - --dCount; - - if(dCount <= 0) - { - m_alarmDeviceStatistical.remove(msg->device); - } - else - { - m_alarmDeviceStatistical.insert(msg->device, dCount); - } - if(dgCount < 0) - { - m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); - } - else - { - m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); - } -} - -void CAlarmMsgManage::devDevGAddStats(const AlarmMsgPtr &msg) -{ - QHash >::iterator posit = m_alarmDevPriority.find(msg->device); - if(posit != m_alarmDevPriority.end()) - { - QMap &priority = posit.value(); - QMap::iterator itor =priority.find(msg->priority); - if(itor != priority.end()) - itor.value()++; - else - priority.insert(msg->priority,1); - }else - { - QMap priority; - priority.insert(msg->priority,1); - m_alarmDevPriority.insert(msg->device,priority); - } - updataDevGroupByDev(msg->dev_group_tag,msg->device); -} - -void CAlarmMsgManage::devDevGSubStats(const AlarmMsgPtr &msg) -{ - QHash >::iterator posit = m_alarmDevPriority.find(msg->device); - if(posit != m_alarmDevPriority.end()) - { - QMap &priority = posit.value(); - QMap::iterator itor =priority.find(msg->priority); - if(itor != priority.end()) - itor.value()--; - } - updataDevGroupByDev(msg->dev_group_tag,msg->device); -} - -void CAlarmMsgManage::locAddStats(const AlarmMsgPtr &msg) -{ - QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); - if(posit != m_alarmLPAlm.end()) - { - QMap &priority = posit.value(); - QMap::iterator itor =priority.find(msg->priority); - if(itor != priority.end()) - itor.value()++; - else - priority.insert(msg->priority,1); - }else - { - QMap priority; - priority.insert(msg->priority,1); - m_alarmLPAlm.insert(msg->location_id,priority); - } -} - -void CAlarmMsgManage::locSubStats(const AlarmMsgPtr &msg) -{ - QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); - if(posit != m_alarmLPAlm.end()) - { - QMap &priority = posit.value(); - QMap::iterator itor =priority.find(msg->priority); - if(itor != priority.end()) - { - itor.value()--; - } - } -} - -QString CAlarmMsgManage::queryPriorityDesc(int id) -{ - return m_priorityDescriptionMap.value(id,QString()); -} - -QString CAlarmMsgManage::queryLocationDesc(int id) -{ - return m_locationDescriptionMap.value(id,QString()); -} - -QString CAlarmMsgManage::queryRegionDesc(int id) -{ - return m_regionDescriptionMap.value(id,QString()); -} - -QString CAlarmMsgManage::queryAlarmTypeDesc(int id) -{ - return m_alarmTypeDescriptionMap.value(id,QString()); -} - -QString CAlarmMsgManage::queryAlarmStatusDesc(int id) -{ - return m_alarmStatusDescriptionMap.value(id,QString()); -} - -int CAlarmMsgManage::queryDevTypeByDesc(QString &desc) -{ - return m_deviceTypeDescriptionMap.key(desc); -} - -QString CAlarmMsgManage::queryLocationDesc(QString &aiuuid) -{ - QMutexLocker locker(mutex); - QString desc = QString(); - QList listLocationId = m_aitolocation.value(aiuuid); - for(int index(0);index &listAlarm, QList &listaiAlarm) -{ - QMutexLocker locker(mutex); - listAlarm = m_alarm.values(); - listaiAlarm = m_aiinfos.values(); -} - -AlarmMsgPtr CAlarmMsgManage::getAlarmPtrByuuid(const QString uuid) -{ - QMutexLocker locker(mutex); - return m_all.value(uuid,NULL); -} - -bool CAlarmMsgManage::ifhaveNotConfirmAlmByuuid(QString &aiuuid) -{ - QMutexLocker locker(mutex); - SAiConfirm confirm; - SAiConfirm aiConfirm= m_aicount.value(aiuuid,confirm); - if(aiConfirm.nConfirm == aiConfirm.nTotal) - { - return false; - } - return true; -} - -void CAlarmMsgManage::updateAiInfo() -{ - QMutexLocker locker(mutex); - m_aicount.clear(); - m_idToid.clear(); - m_aitolocation.clear(); - QHash::iterator it = m_aiinfos.begin(); - while (it != m_aiinfos.end()) { - QVector uuidVec = (*it)->raw_alm_uuid; - addidtoid(uuidVec,(*it)->uuid_base64); - addaicount(uuidVec,(*it)->uuid_base64); - addaitolocation(uuidVec,(*it)->uuid_base64); - ++it; - } - // 更新后重置标识符 - m_bIsError = false; -} - -bool CAlarmMsgManage::needUpdateAi() -{ - QMutexLocker locker(mutex); - return m_bIsError; -} - -QList CAlarmMsgManage::getalmuuidByAiuuid(const QString &aiuuid) -{ - QList uuidList; - QHash::iterator it = m_idToid.begin(); - while(it != m_idToid.end()) { - if(it.value() == aiuuid) - { - uuidList.append(it.key()); - } - it++; - } - return uuidList; -} - -int CAlarmMsgManage::getAlmTotal() -{ - QMutexLocker locker(mutex); - return m_nAlmTotal + m_alarm.size(); -} - -CAlarmMsgManage::~CAlarmMsgManage() -{ - delete m_dbInterface; - LOGDEBUG("CAlarmMsgManage::~CAlarmMsgManage()"); -} - -void CAlarmMsgManage::destory() -{ - { - QMutexLocker locker(mutex); - m_infos.clear(); - m_all.clear(); - m_alarmDeviceStatistical.clear(); - m_alarmDeviceGroupStatistical.clear(); - delete m_rtdbAlarmActionAccess; - delete m_rtdbLocationDescriptionAccess; - delete m_rtdbAppDescriptionAccess; - if(m_rtdbAccess) - { - delete m_rtdbAccess; - } - m_rtdbAccess = Q_NULLPTR; - } - delete mutex; - pInstance = NULL; - - deleteLater(); -} - -void CAlarmMsgManage::initialize() -{ - release(); -} - -void CAlarmMsgManage::release() -{ - QMutexLocker locker(mutex); - m_infos.clear(); - m_alarmDeviceStatistical.clear(); - m_alarmDeviceGroupStatistical.clear(); - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - m_listMsgAddCache.clear(); - m_inhibitFilter.clear(); - m_aiinfos.clear(); - m_aicount.clear(); - m_alarm.clear(); - m_idToid.clear(); - m_aitolocation.clear(); - //根据需求 - m_all.clear(); - m_aiall.clear(); - m_priorityDescriptionMap.clear(); - m_locationDescriptionMap.clear(); - m_regionDescriptionMap.clear(); - m_alarmTypeDescriptionMap.clear(); - m_alarmStatusDescriptionMap.clear(); - loadPermInfo(); - loadAlarmInfoConfig(); - m_nNDelComAlarmCount = 0; - m_nDelNComAlarmCount = 0; - m_nAlmNum = 0; - m_nAlmTotal = 0; -} - -QList CAlarmMsgManage::getListAlarmInfo() -{ - //不需要清空1秒缓存 - QMutexLocker locker(mutex); - return m_infos.values(); -} - -QHash CAlarmMsgManage::getDeviceStatisticalInfo() -{ - QMutexLocker locker(mutex); - - return m_alarmDeviceGroupStatistical; -} - -int CAlarmMsgManage::deviceGroupAlarmStatistical(const QString &deviceGroup) -{ - if(deviceGroup.isEmpty()) - { - return 0; - } - - return m_alarmDeviceGroupStatistical.value(deviceGroup, 0); -} - -int CAlarmMsgManage::getAlarmTotalSize() -{ - QMutexLocker locker(mutex); - return m_infos.size(); -} - -int CAlarmMsgManage::getUnConfirmSize() -{ - return m_nNDelComAlarmCount; -} - -void CAlarmMsgManage::addAlarmMsg(const AlarmMsgPtr &msg) -{ - QMutexLocker locker(mutex); - m_all.insert(msg->uuid_base64,msg); - if(!m_inhibitFilter.isEmpty() && m_inhibitFilter.contains(msg->key_id_tag)) - { - return ; - } - if(!m_listPermLocationId.contains(msg->location_id) || (!m_listPermRegionId.contains(msg->region_id) && msg->region_id != -1)) - { - return ; - } - if(msg->deleteFlag == true) //已经删除的不会保存到中 - { - return ; - } - - AlarmMsgPtr oldMsg = m_infos.value(msg->uuid_base64, AlarmMsgPtr(NULL)); - if(!oldMsg.isNull()) - { - LOGERROR("CAlarmMsgManage::addAlarmMsg():告警uuid[%s]重复!",msg->uuid_base64.toStdString().c_str()); - } - - if(E_ALS_ALARM == msg->logic_state || E_ALS_RETURN == msg->logic_state )//未确认数量(界面显示未确认) - { - ++m_nNDelComAlarmCount; - } - m_infos.insert(msg->uuid_base64, msg); - //更新告警统计 - almStats(msg,1); - //更新未聚类但是需要展示的原始告警 - QHash::iterator it = m_idToid.find(msg->uuid_base64); - if(it == m_idToid.end()) - { - m_alarm.insert(msg->uuid_base64,msg); - } -} - -void CAlarmMsgManage::addAlarmToAllInfo(const AlarmMsgPtr &msg) -{ - QMutexLocker locker(mutex); - m_all.insert(msg->uuid_base64,msg); -} - -void CAlarmMsgManage::addAlarmCacheMsg(const AlarmMsgPtr &msg) -{ - QMutexLocker locker(mutex); - if(!m_inhibitFilter.isEmpty() && m_inhibitFilter.contains(msg->key_id_tag)) - { - return ; - } - if(!m_listPermLocationId.contains(msg->location_id) || (!m_listPermRegionId.contains(msg->region_id) && msg->region_id != -1)) - { - return ; - } - if(msg->deleteFlag == true) - { - return ; - } - m_listMsgAddCache.append(msg); -} - -void CAlarmMsgManage::confirmAlarmMsg(QString &uuid) -{ - QMutexLocker locker(mutex); - - AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); - if(!oldMsg.isNull()) - { - stopSounds(oldMsg); - if(E_ALS_ALARM == oldMsg->logic_state) - { - oldMsg->logic_state = E_ALS_ALARM_CFM; - --m_nNDelComAlarmCount; - } - else if(E_ALS_RETURN == oldMsg->logic_state) - { - oldMsg->logic_state = E_ALS_RETURN_CFM; - --m_nNDelComAlarmCount; - } - }else - { - AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); - if(!oldMsg_.isNull()) - { - if(E_ALS_ALARM == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_ALARM_CFM; - } - else if(E_ALS_RETURN == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_RETURN_CFM; - } - else if(E_ALS_ALARM_DEL == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; - } - else if(E_ALS_RETURN_DEL == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; - } - } - } - //确认告警时更新告警确认数量 - QHash::iterator it = m_idToid.find(uuid); - if(it != m_idToid.end()) - { - QString aiuuid = m_idToid.value(uuid); - SAiConfirm confirm = m_aicount.value(aiuuid); - confirm.nConfirm++; - m_aicount.insert(aiuuid,confirm); - } -} - -void CAlarmMsgManage::removeAlarmMsg(QString &uuid) -{ - QMutexLocker locker(mutex); - AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); - if(!oldMsg.isNull()) - { - if(E_ALS_ALARM == oldMsg->logic_state) - { - --m_nNDelComAlarmCount; - oldMsg->logic_state = E_ALS_ALARM_DEL; - } - else if(E_ALS_ALARM_CFM == oldMsg->logic_state) - { - oldMsg->logic_state = E_ALS_ALARM_CFM_DEL; - } - else if(E_ALS_RETURN == oldMsg->logic_state) - { - --m_nNDelComAlarmCount; - oldMsg->logic_state = E_ALS_RETURN_DEL; - } - else if(E_ALS_RETURN_CFM == oldMsg->logic_state) - { - oldMsg->logic_state = E_ALS_RETURN_CFM_DEL; - } - - oldMsg->deleteFlag = true; - almStats(oldMsg,0); - m_infos.remove(uuid); - }else - { - AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); - if(!oldMsg_.isNull()) - { - if(E_ALS_ALARM == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_ALARM_DEL; - } - else if(E_ALS_ALARM_CFM == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; - } - else if(E_ALS_RETURN == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_RETURN_DEL; - } - else if(E_ALS_RETURN_CFM == oldMsg_->logic_state) - { - oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; - } - oldMsg_->deleteFlag = true; - } - } - //原始告警删除某条时,智能告警需要删除一级节点上的此条原始告警 - QVector deluuidVec; - deluuidVec.push_back(uuid); - emit sigMsgRemove(deluuidVec); - //从m_alarm中删除未聚类但有删除标志的告警 - QHash::iterator it = m_alarm.find(uuid); - if(it != m_alarm.end()) - { - m_alarm.erase(it); - } -} - -void CAlarmMsgManage::releaseAlarmMsg(QString &uuid) -{ - QMutexLocker locker(mutex); - AlarmMsgPtr oldMsg = m_all.value(uuid, NULL); - if(!oldMsg.isNull()) - { - m_all.remove(uuid); - } -} - -void CAlarmMsgManage::removeAlarmMsgByDomainID(const int &domainId) -{ - QMutexLocker locker(mutex); - /* 清除全缓存 - */ - QHash::iterator pos = m_all.begin(); - while (pos != m_all.end()) { - if(domainId == (*pos)->domain_id) - { - pos = m_all.erase(pos); - continue; - } - pos++; - } - /* 清除有权限和未禁止的缓存 - */ - QHash::iterator it = m_infos.begin(); - while (it != m_infos.end()) - { - if(domainId == (*it)->domain_id) - { - if(E_ALS_ALARM == (*it)->logic_state || E_ALS_RETURN == (*it)->logic_state) - { - --m_nNDelComAlarmCount; - } - else if(E_ALS_ALARM_DEL == (*it)->logic_state || E_ALS_RETURN_DEL == (*it)->logic_state) - { - --m_nDelNComAlarmCount; - } - stopSounds(it.value()); - almStats((*it),0); - it = m_infos.erase(it); - continue; - } - it++; - } - //清空告警缓存(每秒更新) - QList::iterator itpos =m_listMsgAddCache.begin(); - while (itpos != m_listMsgAddCache.end()) { - if((*itpos)->domain_id == domainId) - { - itpos =m_listMsgAddCache.erase(itpos); - continue; - } - itpos++; - } - - //清空 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗) - QHash::iterator itor = m_alarm.begin(); - while(itor != m_alarm.end()) - { - if(domainId == (*itor)->domain_id) - { - itor = m_alarm.erase(itor); - continue; - } - itor++; - } -} - -void CAlarmMsgManage::updateMsgAction(const AlarmMsgPtr &info) -{ - if(!m_inhibitFilter.isEmpty() && m_inhibitFilter.contains(info->key_id_tag)) - { - return ; - } - if(!m_listPermLocationId.contains(info->location_id) || (!m_listPermRegionId.contains(info->region_id) && info->region_id != -1)) - { - return ; - } - if(info->logic_state == E_ALS_ALARM) - { - int alarmAction = queryAlarmAction(info->priority); - if(ALM_ACT_PUSH_PIC == (alarmAction & ALM_ACT_PUSH_PIC) && !info->graph_name.isEmpty()) - { - //第1位,推画面 - QString alarmInfo; - //< 等级 - alarmInfo.append(QString::number(info->priorityOrder) + QString(",")); - //< 时间 - alarmInfo.append(QDateTime::fromMSecsSinceEpoch(info->time_stamp).toString("yyyy-MM-dd hh:mm:ss") + QString(",")); - //< 车站 - alarmInfo.append(queryLocationDescription(info->location_id) + QString(",")); - //< 应用 - alarmInfo.append(queryAppDescription(info->app_id) + QString(",")); - //< 内容 - alarmInfo.append(info->content + QString(",")); - //< 画面名称 - alarmInfo.append(info->graph_name); - - pushGraphics(alarmInfo); - } - if(ALM_ACT_PRINT == (alarmAction & ALM_ACT_PRINT)) - { - //第2位,打印 - print(); - } - if(ALM_ACT_SHORT_MSG == (alarmAction & ALM_ACT_SHORT_MSG)) - { - //第3位,短消息 - shortMessage(); - } - if(ALM_ACT_SOUND == (alarmAction & ALM_ACT_SOUND)) - { - //第4位,声音告警 - if(!info->sound_file.isEmpty()) - { - sounds(info, info->sound_file); - } - } - if(ALM_ACT_PA == (alarmAction & ALM_ACT_PA)) - { - //第5位,广播告警 - paNotify(); - } - - } -} - -void CAlarmMsgManage::pushGraphics(const QString &info) -{ - emit sigAlarmPushGraph(info); -} - -void CAlarmMsgManage::print() -{ - -} - -void CAlarmMsgManage::shortMessage() -{ - -} - -void CAlarmMsgManage::sounds(const AlarmMsgPtr info, const QStringList soundFileNames) -{ - //播放告警音频 - if(!soundFileNames.isEmpty()) - { - emit sigInsertAudioCues(info, soundFileNames); - } -} - -void CAlarmMsgManage::stopSounds(const AlarmMsgPtr info) -{ - emit sigStopAudioCues(info); -} - -void CAlarmMsgManage::paNotify() -{ - -} - -bool CAlarmMsgManage::isBindMediaPlayer() -{ - return isSignalConnected(QMetaMethod::fromSignal(&CAlarmMsgManage::sigInsertAudioCues)); -} - -void CAlarmMsgManage::msgArrived() -{ - QMutexLocker locker(mutex); - QList m_ailistMsg; //需要在智能告警窗展示 - QList m_listMsg; //需要在智能告警窗展示 - m_listMsg.clear(); - for(int num(0);numkey_id_tag)) - { - continue ; - } - if(!m_listPermLocationId.contains(m_listMsgAddCache.at(num)->location_id) || (!m_listPermRegionId.contains(m_listMsgAddCache.at(num)->region_id) && m_listMsgAddCache.at(num)->region_id != -1)) - { - continue ; - } - if(m_listMsgAddCache.at(num)->deleteFlag == true) - { - continue ; - } - AlarmMsgPtr oldMsg = m_infos.value(m_listMsgAddCache.at(num)->uuid_base64, AlarmMsgPtr(NULL)); - if(!oldMsg.isNull()) - { - LOGERROR("CAlarmMsgManage::addAlarmMsg():告警uuid[%s]重复!",m_listMsgAddCache.at(num)->uuid_base64.toStdString().c_str()); - } - - if(E_ALS_ALARM == m_listMsgAddCache.at(num)->logic_state || E_ALS_RETURN == m_listMsgAddCache.at(num)->logic_state )//未删除未确认数量(界面显示未确认) - { - ++m_nNDelComAlarmCount; - } - m_infos.insert(m_listMsgAddCache.at(num)->uuid_base64, m_listMsgAddCache.at(num)); - m_listMsg.append(m_listMsgAddCache.at(num)); - //更新告警数量 - almStats(m_listMsgAddCache.at(num),1); - //更新未聚类但是需要展示的原始告警 - QHash::iterator it = m_idToid.find(m_listMsgAddCache.at(num)->uuid_base64); - if(it == m_idToid.end()) - { - m_alarm.insert(m_listMsgAddCache.at(num)->uuid_base64,m_listMsgAddCache.at(num)); - m_ailistMsg.append(m_listMsgAddCache.at(num)); - } - } - m_listMsgAddCache.clear(); - if(m_listMsg.size()>0) - { - emit sigMsgArrived(m_listMsg); - m_listMsg.clear(); - } - if(m_ailistMsg.size()>0) - { - emit sigMsgArrivedToAi(m_ailistMsg); - m_ailistMsg.clear(); - } -} - -void CAlarmMsgManage::dealDelayAi() -{ - QMutexLocker locker(mutex); - QList delaydeal = m_delaydeal; - m_delaydeal.clear(); - if(delaydeal.size() > 0) - { - for(int index(0);indexuuid_base64) == m_aiall.end()) - { - LOGERROR("dealDelayAi():延迟处理ai,如果在全部缓存中没有找到说明服务发送智能告警顺序出错!"); - continue; - } - QVector uuidVec = delaydeal.at(index)->raw_alm_uuid; - if(!isHaveAlm(uuidVec)) - { - m_delaydeal.append(delaydeal.at(index)); //延后处理 - continue; - } - if(checkLookPerm(uuidVec)) - { - addidtoid(uuidVec,delaydeal.at(index)->uuid_base64); - addaicount(uuidVec,delaydeal.at(index)->uuid_base64); - addaitolocation(uuidVec,delaydeal.at(index)->uuid_base64); - QVector deluuidVec; - updatealarm(uuidVec,deluuidVec); - emit sigMsgRemove(deluuidVec); - if(delaydeal.at(index)->deleteFlag != true && delaydeal.at(index)->brokenFlag != true) - { - m_nAlmTotal += delaydeal.at(index)->raw_alm_uuid.size(); - } - m_aiinfos.insert(delaydeal.at(index)->uuid_base64,delaydeal.at(index)); - emit sigAiMsgAdd(delaydeal.at(index)); - } - } - } -} - -QList CAlarmMsgManage::findMsgsByKeyIdTag(const QString &key_id_tag) -{ - QMutexLocker locker(mutex); - QList listMsg; - QList allMsgs = m_infos.values(); - QList::const_iterator iter = allMsgs.constBegin(); - while(iter != allMsgs.constEnd()) - { - if(QString::compare((*iter)->key_id_tag, key_id_tag)) - { - listMsg.append(*iter); - } - iter++; - } - return listMsg; -} - -int CAlarmMsgManage::queryAlarmAction(const int &priority) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbAlarmActionAccess); - kbd_dbms::CVarType value; - m_rtdbAlarmActionAccess->getColumnValueByKey((void*)&priority, "alarm_actions",value); - return value.toInt(); -} - -QString CAlarmMsgManage::queryLocationDescription(int id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbLocationDescriptionAccess); - kbd_dbms::CVarType value; - m_rtdbLocationDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); - return value.c_str(); -} - -QString CAlarmMsgManage::queryAppDescription(int id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbAppDescriptionAccess); - kbd_dbms::CVarType value; - m_rtdbAppDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); - return value.c_str(); -} - -void CAlarmMsgManage::loadPermInfo() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecRegionId; - std::vector vecLocationId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_VIEW, vecRegionId, vecLocationId)) - { - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - m_listPermLocationId.append(*location++); - } - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - m_listPermRegionId.append(*region++); - } - } - } -} +#include "CAlarmMsgManage.h" +#include +#include +#include +#include +#include "CAlarmDataCollect.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include +#include "dbms/db_sysinfo_api/CDbSysInfo.h" +#include "perm_mng_api/PermMngApi.h" + +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_logger_api/logger.h" + +using namespace kbd_public; +using namespace std; + +CAlarmMsgManage *CAlarmMsgManage::pInstance = NULL; +CAlarmMsgManage *CAlarmMsgManage::instance() +{ + if(pInstance == NULL) + { + pInstance = new CAlarmMsgManage(); + } + return pInstance; +} + +CAlarmMsgManage::CAlarmMsgManage() + : QObject(), + m_nNDelComAlarmCount(0), + m_nDelNComAlarmCount(0), + m_nAlmTotal(0), + m_nAlmNum(0), + m_bIsError(false) +{ + mutex = new QMutex(); + m_infos.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + m_listMsgAddCache.clear(); + m_inhibitFilter.clear(); + m_aiinfos.clear(); + m_aicount.clear(); + m_alarm.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + //根据需求 + m_all.clear(); + m_aiall.clear(); + + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + m_alarmStatusDescriptionMap.clear(); + m_rtdbAlarmActionAccess = new kbd_dbms::CRdbAccess(); + m_rtdbAlarmActionAccess->open("base", "alarm_level_define"); + + m_rtdbLocationDescriptionAccess = new kbd_dbms::CRdbAccess(); + m_rtdbLocationDescriptionAccess->open("base", "sys_model_location_info"); + + m_rtdbAppDescriptionAccess = new kbd_dbms::CRdbAccess(); + m_rtdbAppDescriptionAccess->open("base", "sys_model_app_info"); + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + m_dbInterface = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + + loadPermInfo(); +} + +void CAlarmMsgManage::refreshCache() +{ + QMutexLocker locker(mutex); + m_listMsgAddCache.clear(); +} + +bool CAlarmMsgManage::isInhibit(const QString &tag_name) +{ + if(m_inhibitFilter.contains(tag_name)) + { + return true; + } + return false; +} + +void CAlarmMsgManage::addInhibitTag(const QString &tag) +{ + m_inhibitFilter.append(tag); +} + +void CAlarmMsgManage::removeInhibitTag(const QString &tag) +{ + m_inhibitFilter.removeAll(tag); +} + +QMap CAlarmMsgManage::getDevAlarm(const QString &device) +{ + QMutexLocker locker(mutex); + QMap alarm; + alarm.clear(); + return m_alarmDevPriority.value(device,alarm); +} + +QMap > CAlarmMsgManage::getDevGroupPriorityDevNum(const QString &deviceGroup) +{ + QMutexLocker locker(mutex); + QMap > alarm; + alarm.clear(); + + return m_alarmDGPDev.value(deviceGroup,alarm); +} + +QHash > CAlarmMsgManage::getLocAlmInfo() +{ + QMutexLocker locker(mutex); + return m_alarmLPAlm; +} + +void CAlarmMsgManage::updataDevGroupByDev(QString devGroup, QString device) +{ + QHash >::iterator it = m_alarmDevPriority.find(device); + int devMaxPriority =-1;//最高优先级 + if(it != m_alarmDevPriority.end()) + { + QMap::iterator itor= it.value().begin(); + + for(;itor!= it.value().end();itor++) + { + if(itor.value()>0) + { + devMaxPriority = itor.key(); + break; + } + } + } + QHash > >::iterator pos = m_alarmDGPDev.find(devGroup); + if(pos != m_alarmDGPDev.end()) + { + QMap > &priorityMap = pos.value(); + QMap >::iterator itor = priorityMap.begin(); + + while (itor != priorityMap.end()) { + QList &list = itor.value(); + if(list.contains(device)) + { + list.removeOne(device); + } + itor++; + } + if(devMaxPriority == -1) + return ; + itor =priorityMap.find(devMaxPriority); + if(itor != priorityMap.end()) + { + QList &devList = itor.value(); + if(!devList.contains(device)) + { + devList.append(device); + } + }else + { + QList list; + list.append(device); + priorityMap.insert(devMaxPriority,list); + } + }else + { + QList list; + list.append(device); + QMap > priorityMap; + priorityMap.insert(devMaxPriority,list); + m_alarmDGPDev.insert(devGroup,priorityMap); + } +} + +void CAlarmMsgManage::openVideoDialog(int domainId, int appId, QString tag, quint64 startTime, quint64 endTime) +{ + emit openVideo(domainId,appId,tag,startTime,endTime); +} + +void CAlarmMsgManage::removeAiAlarmMsgByDomainID(const int &domainId) +{ + QMutexLocker locker(mutex); + /* 清除全缓存 + */ + QHash::iterator pos = m_aiall.begin(); + while (pos != m_aiall.end()) { + if(domainId == (*pos)->domain_id) + { + pos = m_aiall.erase(pos); + continue; + } + pos++; + } + /* 清除有权限和未禁止的缓存 + */ + QHash::iterator it = m_aiinfos.begin(); + while (it != m_aiinfos.end()) + { + if(domainId == (*it)->domain_id) + { + eraseaicount((*it)->uuid_base64); + eraseidtoid((*it)->uuid_base64); + eraseidtolocation((*it)->uuid_base64); + it = m_aiinfos.erase(it); + continue; + } + it++; + } +} +// 添加时不需要通知模型,反正所有数据接收完成之后会全部刷新一下 +void CAlarmMsgManage::addAiAllAlarmMsg(AiAlarmMsgPtr &msg) +{ + QMutexLocker locker(mutex); + m_aiall.insert(msg->uuid_base64,msg); + QVector uuidVec = msg->raw_alm_uuid; + if(!isHaveAlm(uuidVec)) + { + m_delaydeal.append(msg); //延后处理 + return ; + } + if(checkLookPerm(uuidVec)) + { + addidtoid(uuidVec,msg->uuid_base64); + addaicount(uuidVec,msg->uuid_base64); + addaitolocation(uuidVec,msg->uuid_base64); + msg->m_needVideoAlm = initaivideo(uuidVec); + QVector deluuidVec; + updatealarm(uuidVec,deluuidVec); + if(msg->deleteFlag != true && msg->brokenFlag != true) + { + m_nAlmTotal += msg->raw_alm_uuid.size(); + } + m_aiinfos.insert(msg->uuid_base64,msg); + } +} + +void CAlarmMsgManage::addAiAlarmMsg(AiAlarmMsgPtr &msg) +{ + QMutexLocker locker(mutex); + m_aiall.insert(msg->uuid_base64,msg); + QVector uuidVec = msg->raw_alm_uuid; + if(!isHaveAlm(uuidVec)) + { + m_delaydeal.append(msg); //延后处理 + return ; + } + if(checkLookPerm(uuidVec)) + { + addidtoid(uuidVec,msg->uuid_base64); + addaicount(uuidVec,msg->uuid_base64); + addaitolocation(uuidVec,msg->uuid_base64); + msg->m_needVideoAlm = initaivideo(uuidVec); + QVector deluuidVec; + updatealarm(uuidVec,deluuidVec); + emit sigMsgRemove(deluuidVec); + if(msg->deleteFlag != true && msg->brokenFlag != true) + { + m_nAlmTotal += msg->raw_alm_uuid.size(); + } + m_aiinfos.insert(msg->uuid_base64,msg); + emit sigAiMsgAdd(msg); + } +} +//删除智能告警 +void CAlarmMsgManage::delAiAlarmMsg(QString &aiuuid) +{ + QMutexLocker locker(mutex); + //先修改此智能告警状态 + QHash::iterator pos = m_aiall.find(aiuuid); + if(pos != m_aiall.end()) + { + pos.value()->deleteFlag = true; + } + //删除智能告警窗上对应的智能告警 + QHash::iterator it = m_aiinfos.find(aiuuid); + if(it != m_aiinfos.end()) + { + if(it.value()->brokenFlag != true) + { + m_nAlmTotal -= it.value()->raw_alm_uuid.size(); + } + it.value()->deleteFlag = true; + emit sigAiMsgRemove(aiuuid); + } +} +//收到不完整的智能告警则删除 +void CAlarmMsgManage::brokenAiAlarmMsg(QString &aiuuid) +{ + QMutexLocker locker(mutex); + QHash::iterator pos = m_aiall.find(aiuuid); + if(pos != m_aiall.end()) + { + pos.value()->brokenFlag = true; + } + QHash::iterator it = m_aiinfos.find(aiuuid); + if(it != m_aiinfos.end()) + { + if(it.value()->deleteFlag != true) + { + m_nAlmTotal -= it.value()->raw_alm_uuid.size(); + } + it.value()->brokenFlag = true; + + emit sigAiMsgRemove(aiuuid); + } +} + +//释放智能告警(两种情况,1.删除后正常释放,2.请求分离后服务端会要求直接释放此条智能告警,这时,则需要把此条智能告警下关联的原始告警根据过滤后显示在智能告警窗的一级节点上) +void CAlarmMsgManage::releaseAiAlarmMsg(QString &aiuuid) +{ + QMutexLocker locker(mutex); + QHash::iterator pos = m_aiall.find(aiuuid); + if(pos != m_aiall.end()) + { + m_aiall.erase(pos); + } + QHash::iterator it = m_aiinfos.find(aiuuid); + if(it != m_aiinfos.end()) + { + if((*it)->brokenFlag != true && (*it)->deleteFlag != true) + { + m_nAlmTotal -= it.value()->raw_alm_uuid.size(); + } + QList m_listMsg; + QList uuidList = getalmuuidByAiuuid(aiuuid); + for(int index(0);indexdeleteFlag == true) + { + continue; + } + + if(!m_listPermLocationId.contains(almPtr->location_id) || (!m_listPermRegionId.contains(almPtr->region_id) && almPtr->region_id != -1)) + { + continue; + } + m_alarm.insert(almPtr->uuid_base64,almPtr); + if(!m_inhibitFilter.isEmpty() && m_inhibitFilter.contains(almPtr->key_id_tag)) + { + continue; + } + m_listMsg.append(almPtr); + } + eraseaicount(aiuuid); + eraseidtoid(aiuuid); + eraseidtolocation(aiuuid); + m_aiinfos.erase(it); + emit sigAiMsgRemove(aiuuid); + if(m_listMsg.size() > 0) + { + emit sigMsgArrivedToAi(m_listMsg); + } + } +} + +bool CAlarmMsgManage::getAiuuid(QString &uuid, QString &aiuuid) +{ + QMutexLocker locker(mutex); + + aiuuid = m_idToid.value(uuid,""); + if(aiuuid.isEmpty()) + { + return false; + } + return true; +} + +QMap CAlarmMsgManage::getAlarmOtherStatus() +{ + return m_alarmOtherStatusDescriptionMap; +} + +bool CAlarmMsgManage::isBelongAi(const QString &uuid) +{ + QMutexLocker locker(mutex); + if(m_idToid.value(uuid,"").isEmpty()) + { + return false; + } + return false; +} + +void CAlarmMsgManage::eraseaicount(QString &aiuuid) +{ + QHash::iterator it = m_aicount.begin(); + while (it != m_aicount.end()) { + if(aiuuid == it.key()) + { + it = m_aicount.erase(it); + continue; + } + it++; + } +} + +void CAlarmMsgManage::eraseidtoid(QString &aiuuid) +{ + QHash::iterator it = m_idToid.begin(); + while (it != m_idToid.end()) { + if(aiuuid == it.value()) + { + it = m_idToid.erase(it); + continue; + } + it++; + } +} + +void CAlarmMsgManage::eraseidtolocation(QString &aiuuid) +{ + QHash >::iterator it = m_aitolocation.begin(); + while (it != m_aitolocation.end()) { + if(aiuuid == it.key()) + { + it = m_aitolocation.erase(it); + continue; + } + it++; + } +} + +bool CAlarmMsgManage::isHaveAlm(QVector &uuidVec) +{ + + for(int x(0);x < uuidVec.count(); x++) + { + QHash::iterator it = m_all.find(uuidVec.at(x)); + if(it == m_all.end()) + { + return false; + } + } + return true; +} + +bool CAlarmMsgManage::checkLookPerm(QVector &uuidVec) +{ + for(int x(0);x < uuidVec.count(); x++) + { + AlarmMsgPtr ptr = m_all.value(uuidVec.at(x),NULL); + if(ptr == NULL) + { + LOGERROR("checkLookPerm---------------空指针"); + return false; + }else + { + qint32 location_id = ptr->location_id; + qint32 region_id = ptr->region_id; + if(m_listPermLocationId.contains(location_id) && (m_listPermRegionId.contains(region_id) || region_id == -1)) + { + return true; + } + } + + } + return false; +} + +void CAlarmMsgManage::addidtoid(QVector &uuidVec, QString &aiuuid) +{ + for(int x(0);x < uuidVec.count();x++) + { + m_idToid.insert(uuidVec.value(x),aiuuid); + } +} + +void CAlarmMsgManage::addaicount(QVector &uuidVec, QString &aiuuid) +{ + int confirm = 0; + for(int x(0);x < uuidVec.count();x++) + { + QString uuid = uuidVec.value(x) ; + if(getConfirmByuuid(uuid)) + { + confirm++; + } + } + SAiConfirm aiConfirm; + aiConfirm.nConfirm = confirm; + aiConfirm.nTotal = uuidVec.count(); + m_aicount.insert(aiuuid,aiConfirm); +} + +void CAlarmMsgManage::addaitolocation(QVector &uuidVec, QString &aiuuid) +{ + QHash >::iterator it =m_aitolocation.find(aiuuid); + if(it != m_aitolocation.end()) + { + m_aitolocation.erase(it); + } + QList locationList; + for(int x(0);x < uuidVec.count();x++) + { + int location = -1; + QString uuid = uuidVec.value(x) ; + if(getLocationByuuid(uuid,location)&&!locationList.contains(location)) + { + locationList.append(location); + } + } + m_aitolocation.insert(aiuuid,locationList); +} + +bool CAlarmMsgManage::initaivideo(QVector &uuidVec) +{ + bool flag = false; + for(int x(0);x < uuidVec.count();x++) + { + QString uuid = uuidVec.value(x) ; + if(getVideoFlagByuuid(uuid,flag) && flag) + { + return flag; + } + } + return flag; +} + +bool CAlarmMsgManage::getLocationByuuid(QString &uuid, int &location) +{ + AlarmMsgPtr ptr = m_all.value(uuid,NULL); + if(ptr != NULL) + { + location = ptr->location_id; + return true; + }else + { + //需要打标记 + m_bIsError = true; + LOGERROR("getConfirmByuuid():未查询到uuid =[%s]的原始告警信息",uuid.toStdString().c_str()); + } + return false; +} + +bool CAlarmMsgManage::getVideoFlagByuuid(QString &uuid, bool &flag) +{ + AlarmMsgPtr ptr = m_all.value(uuid,NULL); + if(ptr != NULL) + { + flag = ptr->m_needVideoAlm; + return true; + }else + { + //需要打标记 + m_bIsError = true; + LOGERROR("getConfirmByuuid():未查询到uuid =[%s]的原始告警信息",uuid.toStdString().c_str()); + } + return false; +} + +bool CAlarmMsgManage::getConfirmByuuid(QString &uuid) +{ + AlarmMsgPtr ptr = m_all.value(uuid,NULL); + if(ptr != NULL) + { + if(ptr->logic_state != E_ALS_ALARM_CFM &&ptr->logic_state != E_ALS_RETURN_CFM && + ptr->logic_state != E_ALS_ALARM_CFM_DEL &&ptr->logic_state != E_ALS_RETURN_CFM_DEL) + { + return false; + } + else + { + return true; + } + }else + { + //需要重新拉数据 + m_bIsError = true; + LOGERROR("getConfirmByuuid():未查询到uuid =[%s]的原始告警信息",uuid.toStdString().c_str()); + } + return false; +} + +//<添加智能告警时,需要删除此条智能告警下还存在一级节点上的原始告警 +void CAlarmMsgManage::updatealarm(QVector &uuidVec,QVector &deluuidVec) +{ + deluuidVec.clear(); + for(int index(0);index::iterator it =m_alarm.find(uuidVec.at(index)); + if(it != m_alarm.end()) + { + m_alarm.remove(uuidVec.at(index)); + deluuidVec.append(uuidVec.at(index)); + } + } +} + +void CAlarmMsgManage::loadAlarmInfoConfig() +{ + loadPriorityDescription(); + loadLocationDescription(); + loadRegionDescription(); + loadAlarmTypeDescription(); + loadAlarmStatusDescription(); + loadDeviceTypeDescription(); + loadDeviceGroupDescription(); + loadAlarmShowStatusDescription(); + loadAlarmOtherStatusDescription(); +} + +void CAlarmMsgManage::loadPriorityDescription() +{ + if(m_rtdbAccess->open("base", "alarm_level_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("priority_id"); + columns.push_back("priority_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmMsgManage::loadLocationDescription() +{ + if(m_rtdbAccess->open("base", "sys_model_location_info")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("description"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); +// if(m_listPermLocationId.contains(key.toInt())) +// { + m_locationDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); +// } + } + } + } +} + +void CAlarmMsgManage::loadRegionDescription() +{ + if(m_rtdbAccess->open("base", "region_info")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("region_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); +// if(m_listPermRegionId.contains(key.toInt())) +// { + m_regionDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); +// } + } + } + } + m_regionDescriptionMap[-1] = QString(); +} + +void CAlarmMsgManage::loadAlarmTypeDescription() +{ + if(m_rtdbAccess->open("base", "alarm_type_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("type_id"); + columns.push_back("type_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmMsgManage::loadAlarmStatusDescription() +{ + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("status_value"); + columns.push_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmMsgManage::loadDeviceTypeDescription() +{ + if(m_rtdbAccess->open("base", "dev_type_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("dev_type_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmMsgManage::loadDeviceGroupDescription() +{ + if(m_rtdbAccess->open("base", "dev_group")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("tag_name"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmMsgManage::loadAlarmShowStatusDescription() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + if(StringToInt(strKey) != 0) + { + m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; + }else + { + m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = tr("其他"); + } + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CAlarmMsgManage::loadAlarmOtherStatusDescription() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + m_alarmOtherStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CAlarmMsgManage::almStats(const AlarmMsgPtr &msg, int addOrSub) +{ + if(addOrSub == 1) + { + almAddStats(msg); + }else + { + almSubStats(msg); + } +} + +void CAlarmMsgManage::almAddStats(const AlarmMsgPtr &msg) +{ + devDevGTotAlmAddStats(msg); + devDevGAddStats(msg); + locAddStats(msg); +} + +void CAlarmMsgManage::almSubStats(const AlarmMsgPtr &msg) +{ + devDevGTotAlmSubStats(msg); + devDevGSubStats(msg); + locSubStats(msg); +} + +void CAlarmMsgManage::devDevGTotAlmAddStats(const AlarmMsgPtr &msg) +{ + + int dCount = m_alarmDeviceStatistical.value(msg->device, 0);//设备告警数量 + int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 + + ++dgCount; // +1 + ++dCount; // +1 + + if(dCount <= 0) + { + m_alarmDeviceStatistical.remove(msg->device); + } + else + { + m_alarmDeviceStatistical.insert(msg->device, dCount); + } + if(dgCount <= 0) + { + m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); + } + else + { + m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); + } +} + +void CAlarmMsgManage::devDevGTotAlmSubStats(const AlarmMsgPtr &msg) +{ + int dCount = m_alarmDeviceStatistical.value(msg->device, 0); //设备告警数量 + int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 + + --dgCount; + --dCount; + + if(dCount <= 0) + { + m_alarmDeviceStatistical.remove(msg->device); + } + else + { + m_alarmDeviceStatistical.insert(msg->device, dCount); + } + if(dgCount < 0) + { + m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); + } + else + { + m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); + } +} + +void CAlarmMsgManage::devDevGAddStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit = m_alarmDevPriority.find(msg->device); + if(posit != m_alarmDevPriority.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()++; + else + priority.insert(msg->priority,1); + }else + { + QMap priority; + priority.insert(msg->priority,1); + m_alarmDevPriority.insert(msg->device,priority); + } + updataDevGroupByDev(msg->dev_group_tag,msg->device); +} + +void CAlarmMsgManage::devDevGSubStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit = m_alarmDevPriority.find(msg->device); + if(posit != m_alarmDevPriority.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()--; + } + updataDevGroupByDev(msg->dev_group_tag,msg->device); +} + +void CAlarmMsgManage::locAddStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); + if(posit != m_alarmLPAlm.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()++; + else + priority.insert(msg->priority,1); + }else + { + QMap priority; + priority.insert(msg->priority,1); + m_alarmLPAlm.insert(msg->location_id,priority); + } +} + +void CAlarmMsgManage::locSubStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); + if(posit != m_alarmLPAlm.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + { + itor.value()--; + } + } +} + +QString CAlarmMsgManage::queryPriorityDesc(int id) +{ + return m_priorityDescriptionMap.value(id,QString()); +} + +QString CAlarmMsgManage::queryLocationDesc(int id) +{ + return m_locationDescriptionMap.value(id,QString()); +} + +QString CAlarmMsgManage::queryRegionDesc(int id) +{ + return m_regionDescriptionMap.value(id,QString()); +} + +QString CAlarmMsgManage::queryAlarmTypeDesc(int id) +{ + return m_alarmTypeDescriptionMap.value(id,QString()); +} + +QString CAlarmMsgManage::queryAlarmStatusDesc(int id) +{ + return m_alarmStatusDescriptionMap.value(id,QString()); +} + +int CAlarmMsgManage::queryDevTypeByDesc(QString &desc) +{ + return m_deviceTypeDescriptionMap.key(desc); +} + +QString CAlarmMsgManage::queryLocationDesc(QString &aiuuid) +{ + QMutexLocker locker(mutex); + QString desc = QString(); + QList listLocationId = m_aitolocation.value(aiuuid); + for(int index(0);index &listAlarm, QList &listaiAlarm) +{ + QMutexLocker locker(mutex); + listAlarm = m_alarm.values(); + listaiAlarm = m_aiinfos.values(); +} + +AlarmMsgPtr CAlarmMsgManage::getAlarmPtrByuuid(const QString uuid) +{ + QMutexLocker locker(mutex); + return m_all.value(uuid,NULL); +} + +bool CAlarmMsgManage::ifhaveNotConfirmAlmByuuid(QString &aiuuid) +{ + QMutexLocker locker(mutex); + SAiConfirm confirm; + SAiConfirm aiConfirm= m_aicount.value(aiuuid,confirm); + if(aiConfirm.nConfirm == aiConfirm.nTotal) + { + return false; + } + return true; +} + +void CAlarmMsgManage::updateAiInfo() +{ + QMutexLocker locker(mutex); + m_aicount.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + QHash::iterator it = m_aiinfos.begin(); + while (it != m_aiinfos.end()) { + QVector uuidVec = (*it)->raw_alm_uuid; + addidtoid(uuidVec,(*it)->uuid_base64); + addaicount(uuidVec,(*it)->uuid_base64); + addaitolocation(uuidVec,(*it)->uuid_base64); + ++it; + } + // 更新后重置标识符 + m_bIsError = false; +} + +bool CAlarmMsgManage::needUpdateAi() +{ + QMutexLocker locker(mutex); + return m_bIsError; +} + +QList CAlarmMsgManage::getalmuuidByAiuuid(const QString &aiuuid) +{ + QList uuidList; + QHash::iterator it = m_idToid.begin(); + while(it != m_idToid.end()) { + if(it.value() == aiuuid) + { + uuidList.append(it.key()); + } + it++; + } + return uuidList; +} + +int CAlarmMsgManage::getAlmTotal() +{ + QMutexLocker locker(mutex); + return m_nAlmTotal + m_alarm.size(); +} + +CAlarmMsgManage::~CAlarmMsgManage() +{ + delete m_dbInterface; + LOGDEBUG("CAlarmMsgManage::~CAlarmMsgManage()"); +} + +void CAlarmMsgManage::destory() +{ + { + QMutexLocker locker(mutex); + m_infos.clear(); + m_all.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + delete m_rtdbAlarmActionAccess; + delete m_rtdbLocationDescriptionAccess; + delete m_rtdbAppDescriptionAccess; + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + } + delete mutex; + pInstance = NULL; + + deleteLater(); +} + +void CAlarmMsgManage::initialize() +{ + release(); +} + +void CAlarmMsgManage::release() +{ + QMutexLocker locker(mutex); + m_infos.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + m_listMsgAddCache.clear(); + m_inhibitFilter.clear(); + m_aiinfos.clear(); + m_aicount.clear(); + m_alarm.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + //根据需求 + m_all.clear(); + m_aiall.clear(); + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + m_alarmStatusDescriptionMap.clear(); + loadPermInfo(); + loadAlarmInfoConfig(); + m_nNDelComAlarmCount = 0; + m_nDelNComAlarmCount = 0; + m_nAlmNum = 0; + m_nAlmTotal = 0; +} + +QList CAlarmMsgManage::getListAlarmInfo() +{ + //不需要清空1秒缓存 + QMutexLocker locker(mutex); + return m_infos.values(); +} + +QHash CAlarmMsgManage::getDeviceStatisticalInfo() +{ + QMutexLocker locker(mutex); + + return m_alarmDeviceGroupStatistical; +} + +int CAlarmMsgManage::deviceGroupAlarmStatistical(const QString &deviceGroup) +{ + if(deviceGroup.isEmpty()) + { + return 0; + } + + return m_alarmDeviceGroupStatistical.value(deviceGroup, 0); +} + +int CAlarmMsgManage::getAlarmTotalSize() +{ + QMutexLocker locker(mutex); + return m_infos.size(); +} + +int CAlarmMsgManage::getUnConfirmSize() +{ + return m_nNDelComAlarmCount; +} + +void CAlarmMsgManage::addAlarmMsg(const AlarmMsgPtr &msg) +{ + QMutexLocker locker(mutex); + m_all.insert(msg->uuid_base64,msg); + if(!m_inhibitFilter.isEmpty() && m_inhibitFilter.contains(msg->key_id_tag)) + { + return ; + } + if(!m_listPermLocationId.contains(msg->location_id) || (!m_listPermRegionId.contains(msg->region_id) && msg->region_id != -1)) + { + return ; + } + if(msg->deleteFlag == true) //已经删除的不会保存到中 + { + return ; + } + + AlarmMsgPtr oldMsg = m_infos.value(msg->uuid_base64, AlarmMsgPtr(NULL)); + if(!oldMsg.isNull()) + { + LOGERROR("CAlarmMsgManage::addAlarmMsg():告警uuid[%s]重复!",msg->uuid_base64.toStdString().c_str()); + } + + if(E_ALS_ALARM == msg->logic_state || E_ALS_RETURN == msg->logic_state )//未确认数量(界面显示未确认) + { + ++m_nNDelComAlarmCount; + } + m_infos.insert(msg->uuid_base64, msg); + //更新告警统计 + almStats(msg,1); + //更新未聚类但是需要展示的原始告警 + QHash::iterator it = m_idToid.find(msg->uuid_base64); + if(it == m_idToid.end()) + { + m_alarm.insert(msg->uuid_base64,msg); + } +} + +void CAlarmMsgManage::addAlarmToAllInfo(const AlarmMsgPtr &msg) +{ + QMutexLocker locker(mutex); + m_all.insert(msg->uuid_base64,msg); +} + +void CAlarmMsgManage::addAlarmCacheMsg(const AlarmMsgPtr &msg) +{ + QMutexLocker locker(mutex); + if(!m_inhibitFilter.isEmpty() && m_inhibitFilter.contains(msg->key_id_tag)) + { + return ; + } + if(!m_listPermLocationId.contains(msg->location_id) || (!m_listPermRegionId.contains(msg->region_id) && msg->region_id != -1)) + { + return ; + } + if(msg->deleteFlag == true) + { + return ; + } + m_listMsgAddCache.append(msg); +} + +void CAlarmMsgManage::confirmAlarmMsg(QString &uuid) +{ + QMutexLocker locker(mutex); + + AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); + if(!oldMsg.isNull()) + { + stopSounds(oldMsg); + if(E_ALS_ALARM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_ALARM_CFM; + --m_nNDelComAlarmCount; + } + else if(E_ALS_RETURN == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_RETURN_CFM; + --m_nNDelComAlarmCount; + } + }else + { + AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); + if(!oldMsg_.isNull()) + { + if(E_ALS_ALARM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM; + } + else if(E_ALS_RETURN == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM; + } + else if(E_ALS_ALARM_DEL == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN_DEL == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; + } + } + } + //确认告警时更新告警确认数量 + QHash::iterator it = m_idToid.find(uuid); + if(it != m_idToid.end()) + { + QString aiuuid = m_idToid.value(uuid); + SAiConfirm confirm = m_aicount.value(aiuuid); + confirm.nConfirm++; + m_aicount.insert(aiuuid,confirm); + } +} + +void CAlarmMsgManage::removeAlarmMsg(QString &uuid) +{ + QMutexLocker locker(mutex); + AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); + if(!oldMsg.isNull()) + { + if(E_ALS_ALARM == oldMsg->logic_state) + { + --m_nNDelComAlarmCount; + oldMsg->logic_state = E_ALS_ALARM_DEL; + } + else if(E_ALS_ALARM_CFM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN == oldMsg->logic_state) + { + --m_nNDelComAlarmCount; + oldMsg->logic_state = E_ALS_RETURN_DEL; + } + else if(E_ALS_RETURN_CFM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_RETURN_CFM_DEL; + } + + oldMsg->deleteFlag = true; + almStats(oldMsg,0); + m_infos.remove(uuid); + }else + { + AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); + if(!oldMsg_.isNull()) + { + if(E_ALS_ALARM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_DEL; + } + else if(E_ALS_ALARM_CFM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_DEL; + } + else if(E_ALS_RETURN_CFM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; + } + oldMsg_->deleteFlag = true; + } + } + //原始告警删除某条时,智能告警需要删除一级节点上的此条原始告警 + QVector deluuidVec; + deluuidVec.push_back(uuid); + emit sigMsgRemove(deluuidVec); + //从m_alarm中删除未聚类但有删除标志的告警 + QHash::iterator it = m_alarm.find(uuid); + if(it != m_alarm.end()) + { + m_alarm.erase(it); + } +} + +void CAlarmMsgManage::releaseAlarmMsg(QString &uuid) +{ + QMutexLocker locker(mutex); + AlarmMsgPtr oldMsg = m_all.value(uuid, NULL); + if(!oldMsg.isNull()) + { + m_all.remove(uuid); + } +} + +void CAlarmMsgManage::removeAlarmMsgByDomainID(const int &domainId) +{ + QMutexLocker locker(mutex); + /* 清除全缓存 + */ + QHash::iterator pos = m_all.begin(); + while (pos != m_all.end()) { + if(domainId == (*pos)->domain_id) + { + pos = m_all.erase(pos); + continue; + } + pos++; + } + /* 清除有权限和未禁止的缓存 + */ + QHash::iterator it = m_infos.begin(); + while (it != m_infos.end()) + { + if(domainId == (*it)->domain_id) + { + if(E_ALS_ALARM == (*it)->logic_state || E_ALS_RETURN == (*it)->logic_state) + { + --m_nNDelComAlarmCount; + } + else if(E_ALS_ALARM_DEL == (*it)->logic_state || E_ALS_RETURN_DEL == (*it)->logic_state) + { + --m_nDelNComAlarmCount; + } + stopSounds(it.value()); + almStats((*it),0); + it = m_infos.erase(it); + continue; + } + it++; + } + //清空告警缓存(每秒更新) + QList::iterator itpos =m_listMsgAddCache.begin(); + while (itpos != m_listMsgAddCache.end()) { + if((*itpos)->domain_id == domainId) + { + itpos =m_listMsgAddCache.erase(itpos); + continue; + } + itpos++; + } + + //清空 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗) + QHash::iterator itor = m_alarm.begin(); + while(itor != m_alarm.end()) + { + if(domainId == (*itor)->domain_id) + { + itor = m_alarm.erase(itor); + continue; + } + itor++; + } +} + +void CAlarmMsgManage::updateMsgAction(const AlarmMsgPtr &info) +{ + if(!m_inhibitFilter.isEmpty() && m_inhibitFilter.contains(info->key_id_tag)) + { + return ; + } + if(!m_listPermLocationId.contains(info->location_id) || (!m_listPermRegionId.contains(info->region_id) && info->region_id != -1)) + { + return ; + } + if(info->logic_state == E_ALS_ALARM) + { + int alarmAction = queryAlarmAction(info->priority); + if(ALM_ACT_PUSH_PIC == (alarmAction & ALM_ACT_PUSH_PIC) && !info->graph_name.isEmpty()) + { + //第1位,推画面 + QString alarmInfo; + //< 等级 + alarmInfo.append(QString::number(info->priorityOrder) + QString(",")); + //< 时间 + alarmInfo.append(QDateTime::fromMSecsSinceEpoch(info->time_stamp).toString("yyyy-MM-dd hh:mm:ss") + QString(",")); + //< 车站 + alarmInfo.append(queryLocationDescription(info->location_id) + QString(",")); + //< 应用 + alarmInfo.append(queryAppDescription(info->app_id) + QString(",")); + //< 内容 + alarmInfo.append(info->content + QString(",")); + //< 画面名称 + alarmInfo.append(info->graph_name); + + pushGraphics(alarmInfo); + } + if(ALM_ACT_PRINT == (alarmAction & ALM_ACT_PRINT)) + { + //第2位,打印 + print(); + } + if(ALM_ACT_SHORT_MSG == (alarmAction & ALM_ACT_SHORT_MSG)) + { + //第3位,短消息 + shortMessage(); + } + if(ALM_ACT_SOUND == (alarmAction & ALM_ACT_SOUND)) + { + //第4位,声音告警 + if(!info->sound_file.isEmpty()) + { + sounds(info, info->sound_file); + } + } + if(ALM_ACT_PA == (alarmAction & ALM_ACT_PA)) + { + //第5位,广播告警 + paNotify(); + } + + } +} + +void CAlarmMsgManage::pushGraphics(const QString &info) +{ + emit sigAlarmPushGraph(info); +} + +void CAlarmMsgManage::print() +{ + +} + +void CAlarmMsgManage::shortMessage() +{ + +} + +void CAlarmMsgManage::sounds(const AlarmMsgPtr info, const QStringList soundFileNames) +{ + //播放告警音频 + if(!soundFileNames.isEmpty()) + { + emit sigInsertAudioCues(info, soundFileNames); + } +} + +void CAlarmMsgManage::stopSounds(const AlarmMsgPtr info) +{ + emit sigStopAudioCues(info); +} + +void CAlarmMsgManage::paNotify() +{ + +} + +bool CAlarmMsgManage::isBindMediaPlayer() +{ + return isSignalConnected(QMetaMethod::fromSignal(&CAlarmMsgManage::sigInsertAudioCues)); +} + +void CAlarmMsgManage::msgArrived() +{ + QMutexLocker locker(mutex); + QList m_ailistMsg; //需要在智能告警窗展示 + QList m_listMsg; //需要在智能告警窗展示 + m_listMsg.clear(); + for(int num(0);numkey_id_tag)) + { + continue ; + } + if(!m_listPermLocationId.contains(m_listMsgAddCache.at(num)->location_id) || (!m_listPermRegionId.contains(m_listMsgAddCache.at(num)->region_id) && m_listMsgAddCache.at(num)->region_id != -1)) + { + continue ; + } + if(m_listMsgAddCache.at(num)->deleteFlag == true) + { + continue ; + } + AlarmMsgPtr oldMsg = m_infos.value(m_listMsgAddCache.at(num)->uuid_base64, AlarmMsgPtr(NULL)); + if(!oldMsg.isNull()) + { + LOGERROR("CAlarmMsgManage::addAlarmMsg():告警uuid[%s]重复!",m_listMsgAddCache.at(num)->uuid_base64.toStdString().c_str()); + } + + if(E_ALS_ALARM == m_listMsgAddCache.at(num)->logic_state || E_ALS_RETURN == m_listMsgAddCache.at(num)->logic_state )//未删除未确认数量(界面显示未确认) + { + ++m_nNDelComAlarmCount; + } + m_infos.insert(m_listMsgAddCache.at(num)->uuid_base64, m_listMsgAddCache.at(num)); + m_listMsg.append(m_listMsgAddCache.at(num)); + //更新告警数量 + almStats(m_listMsgAddCache.at(num),1); + //更新未聚类但是需要展示的原始告警 + QHash::iterator it = m_idToid.find(m_listMsgAddCache.at(num)->uuid_base64); + if(it == m_idToid.end()) + { + m_alarm.insert(m_listMsgAddCache.at(num)->uuid_base64,m_listMsgAddCache.at(num)); + m_ailistMsg.append(m_listMsgAddCache.at(num)); + } + } + m_listMsgAddCache.clear(); + if(m_listMsg.size()>0) + { + emit sigMsgArrived(m_listMsg); + m_listMsg.clear(); + } + if(m_ailistMsg.size()>0) + { + emit sigMsgArrivedToAi(m_ailistMsg); + m_ailistMsg.clear(); + } +} + +void CAlarmMsgManage::dealDelayAi() +{ + QMutexLocker locker(mutex); + QList delaydeal = m_delaydeal; + m_delaydeal.clear(); + if(delaydeal.size() > 0) + { + for(int index(0);indexuuid_base64) == m_aiall.end()) + { + LOGERROR("dealDelayAi():延迟处理ai,如果在全部缓存中没有找到说明服务发送智能告警顺序出错!"); + continue; + } + QVector uuidVec = delaydeal.at(index)->raw_alm_uuid; + if(!isHaveAlm(uuidVec)) + { + m_delaydeal.append(delaydeal.at(index)); //延后处理 + continue; + } + if(checkLookPerm(uuidVec)) + { + addidtoid(uuidVec,delaydeal.at(index)->uuid_base64); + addaicount(uuidVec,delaydeal.at(index)->uuid_base64); + addaitolocation(uuidVec,delaydeal.at(index)->uuid_base64); + QVector deluuidVec; + updatealarm(uuidVec,deluuidVec); + emit sigMsgRemove(deluuidVec); + if(delaydeal.at(index)->deleteFlag != true && delaydeal.at(index)->brokenFlag != true) + { + m_nAlmTotal += delaydeal.at(index)->raw_alm_uuid.size(); + } + m_aiinfos.insert(delaydeal.at(index)->uuid_base64,delaydeal.at(index)); + emit sigAiMsgAdd(delaydeal.at(index)); + } + } + } +} + +QList CAlarmMsgManage::findMsgsByKeyIdTag(const QString &key_id_tag) +{ + QMutexLocker locker(mutex); + QList listMsg; + QList allMsgs = m_infos.values(); + QList::const_iterator iter = allMsgs.constBegin(); + while(iter != allMsgs.constEnd()) + { + if(QString::compare((*iter)->key_id_tag, key_id_tag)) + { + listMsg.append(*iter); + } + iter++; + } + return listMsg; +} + +int CAlarmMsgManage::queryAlarmAction(const int &priority) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbAlarmActionAccess); + kbd_dbms::CVarType value; + m_rtdbAlarmActionAccess->getColumnValueByKey((void*)&priority, "alarm_actions",value); + return value.toInt(); +} + +QString CAlarmMsgManage::queryLocationDescription(int id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbLocationDescriptionAccess); + kbd_dbms::CVarType value; + m_rtdbLocationDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); + return value.c_str(); +} + +QString CAlarmMsgManage::queryAppDescription(int id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbAppDescriptionAccess); + kbd_dbms::CVarType value; + m_rtdbAppDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); + return value.c_str(); +} + +void CAlarmMsgManage::loadPermInfo() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecRegionId; + std::vector vecLocationId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_VIEW, vecRegionId, vecLocationId)) + { + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listPermLocationId.append(*location++); + } + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listPermRegionId.append(*region++); + } + } + } +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgManage.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgManage.h index 5fe02dd0..a1ae0842 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgManage.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmMsgManage.h @@ -1,475 +1,475 @@ -#ifndef CALARMMSGMANAGE_H -#define CALARMMSGMANAGE_H - -#include -#include -#include "CAlarmMsgInfo.h" -#include "CAiAlarmMsgInfo.h" -#include "dbms/rdb_api/CRdbAccess.h" -#include "CAlarmCommon.h" -#include "db_api_ex/CDbApi.h" - -#define FUNC_SPE_ALARM_VIEW ("FUNC_SPE_ALARM_VIEW") -class QMutex; -class CAlarmItemModel; -class CAlarmMsgManage : public QObject -{ - Q_OBJECT -public: - static CAlarmMsgManage * instance(); - - ~CAlarmMsgManage(); - - //void loadDevGroupMap(); - - void destory(); - - void initialize(); - - void release(); - - QList getListAlarmInfo(); - - QHash getDeviceStatisticalInfo(); - - int deviceGroupAlarmStatistical(const QString &deviceGroup); - - int getAlarmTotalSize(); - - int getUnConfirmSize(); - - void addAlarmMsg(const AlarmMsgPtr &msg); - - void addAlarmToAllInfo(const AlarmMsgPtr &msg); - - void addAlarmCacheMsg(const AlarmMsgPtr &msg); - - void confirmAlarmMsg(QString &uuid); - - void removeAlarmMsg(QString &uuid); - - void releaseAlarmMsg(QString &uuid); - - void removeAlarmMsgByDomainID(const int &domainId); - - void updateMsgAction(const AlarmMsgPtr &info); - - //< 告警动作 - void pushGraphics(const QString &info); - void print(); - void shortMessage(); - void sounds(const AlarmMsgPtr info, const QStringList soundFileNames); - void stopSounds(const AlarmMsgPtr info); - void paNotify(); - - bool isBindMediaPlayer(); - void msgArrived(); - void dealDelayAi(); - QList findMsgsByKeyIdTag(const QString &key_id_tag); - //QHash m_alarmDeviceDeviceGroup; //<设备,设备组 - - void addInhibitTag(const QString &tag); - void removeInhibitTag(const QString &tag); - QMap getDevAlarm(const QString &device); - - QMap >getDevGroupPriorityDevNum(const QString &deviceGroup); - - QHash > getLocAlmInfo(); - void updataDevGroupByDev(QString devGroup, QString device); -signals: - void sigInsertAudioCues(const AlarmMsgPtr &info, const QStringList &soundFileNames); - void sigStopAudioCues(const AlarmMsgPtr &info); - void sigAlarmPushGraph(const QString &alarmInfo); - void sigAlarmReplaced(); - void sigMsgArrived(QList listMsg); //只通知表格模型 - /** - * @brief sigMsgArrivedToAi 通知树模型未聚类的原始告警到达 - * @param listMsg - */ - void sigMsgArrivedToAi(QList listMsg); //只通知树模型 - - void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); - -public slots: - void openVideoDialog(int domainId, int appId, QString tag, quint64 startTime, quint64 endTime); - -private: - CAlarmMsgManage(); - int queryAlarmAction(const int &priority); - QString queryLocationDescription(int id); - QString queryAppDescription(int id); - - void loadPermInfo(); - - void refreshCache(); - -public: - bool isInhibit(const QString &tag_name); - /** - * @brief removeAiAlarmMsgByDomainID 移除此域所有智能告警,并清除,维护相关结构 - * @param domainId 域id - */ - void removeAiAlarmMsgByDomainID(const int &domainId); - /** - * @brief addAiAllAlarmMsg 全数据时调用,不会通知模型,全部接收完会自动通知模型刷新(重新装载数据) - * @param msg 智能告警指针 - */ - void addAiAllAlarmMsg(AiAlarmMsgPtr &msg); - /** - * @brief addAiAlarmMsg 非全数据时调用,会通知模型添加智能告警,删除相关原始告警 - * @param msg 智能告警指针 - */ - void addAiAlarmMsg(AiAlarmMsgPtr &msg); - /** - * @brief delAiAlarmMsg 根据智能告警uuid删除智能告警 - * @param aiuuid 智能告警uuid - */ - void delAiAlarmMsg(QString &aiuuid); - /** - * @brief brokenAiAlarmMsg 处理不完整的智能告警 - * @param aiuuid - */ - void brokenAiAlarmMsg(QString &aiuuid); - /** - * @brief releaseAiAlarmMsg 根据智能告警uuid释放智能告警 - * @param aiuuid 智能告警uuid - */ - void releaseAiAlarmMsg(QString &aiuuid); - /** - * @brief getAiuuid 根据原始告警uuid获取智能告警uuid - * @param uuid 原始告警uuid - * @param aiuuid 智能告警uuid - * @return 成功返回true,失败返回false - */ - bool getAiuuid(QString &uuid,QString &aiuuid); - /** - * @brief getAlarmOtherStatus 获取其他告警状态集合 - * @return 其他告警状态集合 - */ - QMap getAlarmOtherStatus(); - /** - * @brief isBelongAi 是否属于某个智能告警(已经被某个智能告警聚类) - * @param uuid 原始告警uuid - * @return true-已经被聚类 false-还未被聚类 - */ - bool isBelongAi(const QString &uuid); -private: - /** - * @brief eraseaicount 删除key为aiuuid的键值对 (<智能告警id,SAiConfirm>) - * @param aiuuid 智能告警uuid - */ - void eraseaicount(QString &aiuuid); - /** - * @brief eraseidtoid 删除值为aiuuid的所有键值对(<原始告警id,智能告警id>) - * @param aiuuid 智能告警uuid - */ - void eraseidtoid(QString &aiuuid); - /** - * @brief eraseidtolocation 删除key为aiuuid的键值对 (<智能告警id,与此条智能告警相关的所有位置id>) - * @param aiuuid 智能告警uuid - */ - void eraseidtolocation(QString &aiuuid); - /** - * @brief isHaveAlm 查询m_all中是否包含uuidVec中的告警(确保智能告警下的原始告警一定存在) - * @param uuidVec - * @return - */ - bool isHaveAlm(QVector &uuidVec); - /** - * @brief checkLookPerm 检查当前登陆用户是否具有此条智能告警的权限(若可以看到其中任意一条,则具有权限) - * @param uuidVec 智能告警下原始告警uuid集合 - * @return 有权限返回 true 否则返回false - */ - bool checkLookPerm(QVector &uuidVec); - /** - * @brief addidtoid 添加原始告警uuid和智能告警uuid的映射 - * @param uuidVec 原始告警uuid集合 - * @param aiuuid 智能告警uuid - */ - void addidtoid(QVector &uuidVec,QString &aiuuid); - /** - * @brief addaicount 添加智能告警下原始告警的已确认和总数 - * @param uuidVec 原始告警uuid集合 - * @param aiuuid 智能告警uuid - */ - void addaicount(QVector &uuidVec,QString &aiuuid); - /** - * @brief addaitolocation 添加智能告警uuid和与此告警相关位置的id - * @param uuidVec 原始告警uuid集合 - * @param aiuuid 智能告警uuid - */ - void addaitolocation(QVector &uuidVec,QString &aiuuid); - /** - * @brief initaivideo 初始化智能告警下原始告警的视频标识 - * @param uuidVec 原始告警uuid集合 - * @param aiuuid 智能告警uuid - * @return 具有返回true,否则返回false - */ - bool initaivideo(QVector &uuidVec); - /** - * @brief getLocationByuuid 根据原始告警uuid获取位置id - * @param uuid 原始告警uuid - * @param location 位置 - * @return 成功返回true,否则返回false - */ - bool getLocationByuuid(QString &uuid, int &location); - /** - * @brief getVideoFlagByuuid 根据原始告警uuid获取是否具有视频标识 - * @param uuid - * @param flag 标识 - * @return - */ - bool getVideoFlagByuuid(QString &uuid,bool &flag); - /** - * @brief getConfirmByuuid 根据原始告警uuid获取是否被确认 - * @param uuid 原始告警uuid - * @return true-确认,false-未确认 - */ - bool getConfirmByuuid(QString &uuid); - /** - * @brief updatealarm 更新需要展示在智能告警窗上未聚类的原始告警 - * @param uuidVec 某条智能告警下的所有原始告警的uuid - * @param deluuidVec 需要被删除的一级节点上的未聚类的原始告警uuid - */ - void updatealarm(QVector &uuidVec, QVector &deluuidVec); - /** - * @brief loadAlarmInfoConfig 加载告警配置信息 - */ - void loadAlarmInfoConfig(); - /** - * @brief loadPriorityDescription 加载优先级描述 - */ - void loadPriorityDescription(); - /** - * @brief loadLocationDescription 加载位置描述 - */ - void loadLocationDescription(); - /** - * @brief loadRegionDescription 加载责任区描述 - */ - void loadRegionDescription(); - /** - * @brief loadAlarmTypeDescription 加载告警类型 - */ - void loadAlarmTypeDescription(); - /** - * @brief loadAlarmStatusDescription 加载告警状态描述 - */ - void loadAlarmStatusDescription(); - /** - * @brief loadDeviceTypeDescription 加载设备类型描述 - */ - void loadDeviceTypeDescription(); - /** - * @brief loadDeviceGroupDescription 加载设备组描述 - */ - void loadDeviceGroupDescription(); - /** - * @brief loadAlarmShowStatusDescription 加载需要显示在告警窗下拉框中的告警状态描述 - */ - void loadAlarmShowStatusDescription(); - /** - * @brief loadAlarmOtherStatusDescription 加载其他告警状态描述 - */ - void loadAlarmOtherStatusDescription(); - /** - * @brief almStats 告警统计 - * @param msg 告警指针 - * @param addOrSub 1--add 0--sub(1添加,0删除) - */ - void almStats(const AlarmMsgPtr &msg,int addOrSub); - /** - * @brief almAddStats 告警添加统计 - * @param msg 告警指针 - */ - void almAddStats(const AlarmMsgPtr &msg); - /** - * @brief almSubStats 告警删除统计 - * @param msg 告警指针 - */ - void almSubStats(const AlarmMsgPtr &msg); - /** - * @brief devDevGTotAlmAddStats 设备设备组按优先级添加统计 - * @param msg 告警指针 - */ - void devDevGTotAlmAddStats(const AlarmMsgPtr &msg); - /** - * @brief devDevGTotAlmSubStats 设备设备组按优先级删除统计 - * @param msg 告警指针 - */ - void devDevGTotAlmSubStats(const AlarmMsgPtr &msg); - void devDevGAddStats(const AlarmMsgPtr &msg); - void devDevGSubStats(const AlarmMsgPtr &msg); - void locAddStats(const AlarmMsgPtr &msg); - void locSubStats(const AlarmMsgPtr &msg); -signals: - /** - * @brief sigAiMsgRemove 通知智能告警模型删除智能告警 - * @param aiuuid 智能告警uuid - */ - void sigAiMsgRemove(const QString aiuuid); - /** - * @brief sigAiMsgAdd 通知智能告警模型添加某条智能告警 - * @param aimsg 智能告警指针 - */ - void sigAiMsgAdd(const AiAlarmMsgPtr aimsg); - /** - * @brief sigMsgRemove 通知智能告警模型删除一级节点上的原始告警 - * @param deluuid 需要删除的原始告警uuid的集合 - */ - void sigMsgRemove(const QVector deluuid); -public: - /** - * @brief queryPriorityDesc 根据id查询优先级描述 - * @param id 优先级id - * @return 优先级描述 - */ - QString queryPriorityDesc(int id); - /** - * @brief queryLocationDesc 根据位置id查询位置描述 - * @param id 位置id - * @return 位置描述 - */ - QString queryLocationDesc(int id); - /** - * @brief queryLocationDesc 根据智能告警uuid查询位置描述(可能包含多个位置) - * @param aiuuid 智能告警uuid - * @return 位置描述 - */ - QString queryLocationDesc(QString &aiuuid); - /** - * @brief queryRegionDesc 根据责任区id查询责任区描述 - * @param id 责任区id - * @return 责任区描述 - */ - QString queryRegionDesc(int id); - /** - * @brief queryAlarmTypeDesc 根据告警类型id查询告警类型描述 - * @param id 告警类型id - * @return 告警类型描述 - */ - QString queryAlarmTypeDesc(int id); - /** - * @brief queryAlarmStatusDesc 根据告警状态id查询告警状态描述 - * @param id 告警状态id - * @return 告警状态描述 - */ - QString queryAlarmStatusDesc(int id); - /** - * @brief queryDevTypeByDesc 根据设备类型描述查询设备类型id - * @param desc 设备描述 - * @return 设备id - */ - int queryDevTypeByDesc(QString &desc); - /** - * @brief queryConfirm 根据智能告警uuid查询确认数和总数 - * @param aiuuid 智能告警uuid - * @return 确认数/总数(ex:20/30) - */ - QString queryConfirm(const QString &aiuuid); - /** - * @brief queryAiTotal 根据智能告警uuid 查询原始告警条数 - * @param aiuuid 智能告警uuid - * @return 原始告警条数 - */ - int queryAiTotal(const QString &aiuuid); - /** - * @brief getAlarmInfo 获取所有有权限的原始告警和智能告警 (接口:给智能告警模型使用) - * @param listAlarm 原始告警指针集合 - * @param listaiAlarm 智能告警指针集合 - */ - void getAlarmInfo(QList &listAlarm,QList &listaiAlarm); - /** - * @brief getAlarmPtrByuuid 根据原始告警uuid获取原始告警指针 - * @param uuid 原始告警uuid - * @return 原始告警指针 - */ - AlarmMsgPtr getAlarmPtrByuuid(const QString uuid); - /** - * @brief ifhaveNotConfirmAlmByuuid 根据智能告警uuid查询是否还有未确认的原始告警 - * @param aiuuid 智能告警uuid - * @return 如果包含未确认原始告警返回true,否则返回false - */ - bool ifhaveNotConfirmAlmByuuid(QString &aiuuid); - /** - * @brief getAiLocationList 根据智能告警uuid获取有关的位置集合 - * @param aiuuid 智能告警uuid - * @return 与之有关的位置集合 - */ - QList getAiLocationList(QString &aiuuid); - /** - * @brief updateAiInfo 原始告警重传后需要更新智能告警下的原始告警指针以及相关信息 - */ - void updateAiInfo(); - /** - * @brief needUpdateAi 判断是否出错需要重传(一般情况下不会出错,但是当网络出现间断性故障,告警服务会断点续传,无法保证原始告警和智能告警的先后顺序,导致智能告警在前,原始告警在后, - * 智能告警无法查找到原始告警,特需要标识去判断是否发生故障,若故障则重置模型,重新关联数据。) - * @return true-出错需要重传,false-正确无需重传 - */ - bool needUpdateAi(); - /** - * @brief getalmuuidByAiuuid 根据智能告警uuid获取相关原始告警uuid - * @param aiuuid 智能告警uuid - * @return 原始告警uuidList - */ - QList getalmuuidByAiuuid(const QString &aiuuid); - /** - * @brief getAlmTotal 获取智能告警窗显示原始告警总数 - * @return 数量 - */ - int getAlmTotal(); -private: - QMutex * mutex; - kbd_dbms::CRdbAccess * m_rtdbAlarmActionAccess; - kbd_dbms::CRdbAccess * m_rtdbLocationDescriptionAccess; - kbd_dbms::CRdbAccess * m_rtdbAppDescriptionAccess; - //kbd_dbms::CRdbAccess * m_rtdbDeviceAccess; - kbd_dbms::CDbApi * m_dbInterface; - int m_nNDelComAlarmCount; //< 未删除未确认数量 N--not Del--delete Com--confirm - int m_nDelNComAlarmCount; //< 已删除未确认数量 - QHash m_infos; - QHash m_all; - static CAlarmMsgManage * pInstance; - - - QList m_listPermLocationId; //< 原始告警车站权限 - QList m_listPermRegionId; //< 原始告警责任区权限 - //缓存从collect调整到mng - QList m_listMsgAddCache; //< 告警缓存(每秒更新) - QStringList m_inhibitFilter; //< 告警抑制[界面] - - //智能告警新加 - QHash m_alarm; //< 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗)(两个线程共同维护) - QHash m_aiinfos; //< 有权限的智能告警 - QHash m_aiall; //< 所有智能告警 - - QHash m_aicount; //< <智能告警uuid,已确认数/总数 > - QHash m_idToid; //< <原始告警uuid,智能告警uuid > 用于确认原始告警之后便于更新智能告警中的已确认总数 - - QHash > m_aitolocation;//< <智能告警uuid,包含的原始告警车站id> - - QHash m_alarmDeviceStatistical; //< 设备告警数量统计 - QHash m_alarmDeviceGroupStatistical; //<设备组告警数量统计 - QHash > m_alarmDevPriority; //< 设备告警等级数量统计 - QHash > > m_alarmDGPDev; //< <设备组,<告警等级,设备> > - QHash > m_alarmLPAlm; //< <车站id,<告警等级,告警数量> > - - kbd_dbms::CRdbAccess * m_rtdbAccess; - QMap m_priorityDescriptionMap; - QMap m_locationDescriptionMap; - QMap m_regionDescriptionMap; - QMap m_alarmTypeDescriptionMap; - QMap m_alarmStatusDescriptionMap; - QMap m_deviceTypeDescriptionMap; - QMap m_deviceGroupDescriptionMap; - QMap m_alarmShowStatusDescriptionMap; - QMap m_alarmOtherStatusDescriptionMap; - bool m_bIsError; //数据异常,或者智能告警来临时,没有找到相关联的原始告警则需要重新拉取数据 - - QList m_delaydeal; //延迟处理的智能告警 - - int m_nAlmNum; //智能告警窗原始告警个数 - int m_nAlmTotal; //智能告警窗原始告警总数 -}; - -#endif // CALARMMSGMANAGE_H +#ifndef CALARMMSGMANAGE_H +#define CALARMMSGMANAGE_H + +#include +#include +#include "CAlarmMsgInfo.h" +#include "CAiAlarmMsgInfo.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include "CAlarmCommon.h" +#include "db_api_ex/CDbApi.h" + +#define FUNC_SPE_ALARM_VIEW ("FUNC_SPE_ALARM_VIEW") +class QMutex; +class CAlarmItemModel; +class CAlarmMsgManage : public QObject +{ + Q_OBJECT +public: + static CAlarmMsgManage * instance(); + + ~CAlarmMsgManage(); + + //void loadDevGroupMap(); + + void destory(); + + void initialize(); + + void release(); + + QList getListAlarmInfo(); + + QHash getDeviceStatisticalInfo(); + + int deviceGroupAlarmStatistical(const QString &deviceGroup); + + int getAlarmTotalSize(); + + int getUnConfirmSize(); + + void addAlarmMsg(const AlarmMsgPtr &msg); + + void addAlarmToAllInfo(const AlarmMsgPtr &msg); + + void addAlarmCacheMsg(const AlarmMsgPtr &msg); + + void confirmAlarmMsg(QString &uuid); + + void removeAlarmMsg(QString &uuid); + + void releaseAlarmMsg(QString &uuid); + + void removeAlarmMsgByDomainID(const int &domainId); + + void updateMsgAction(const AlarmMsgPtr &info); + + //< 告警动作 + void pushGraphics(const QString &info); + void print(); + void shortMessage(); + void sounds(const AlarmMsgPtr info, const QStringList soundFileNames); + void stopSounds(const AlarmMsgPtr info); + void paNotify(); + + bool isBindMediaPlayer(); + void msgArrived(); + void dealDelayAi(); + QList findMsgsByKeyIdTag(const QString &key_id_tag); + //QHash m_alarmDeviceDeviceGroup; //<设备,设备组 + + void addInhibitTag(const QString &tag); + void removeInhibitTag(const QString &tag); + QMap getDevAlarm(const QString &device); + + QMap >getDevGroupPriorityDevNum(const QString &deviceGroup); + + QHash > getLocAlmInfo(); + void updataDevGroupByDev(QString devGroup, QString device); +signals: + void sigInsertAudioCues(const AlarmMsgPtr &info, const QStringList &soundFileNames); + void sigStopAudioCues(const AlarmMsgPtr &info); + void sigAlarmPushGraph(const QString &alarmInfo); + void sigAlarmReplaced(); + void sigMsgArrived(QList listMsg); //只通知表格模型 + /** + * @brief sigMsgArrivedToAi 通知树模型未聚类的原始告警到达 + * @param listMsg + */ + void sigMsgArrivedToAi(QList listMsg); //只通知树模型 + + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + +public slots: + void openVideoDialog(int domainId, int appId, QString tag, quint64 startTime, quint64 endTime); + +private: + CAlarmMsgManage(); + int queryAlarmAction(const int &priority); + QString queryLocationDescription(int id); + QString queryAppDescription(int id); + + void loadPermInfo(); + + void refreshCache(); + +public: + bool isInhibit(const QString &tag_name); + /** + * @brief removeAiAlarmMsgByDomainID 移除此域所有智能告警,并清除,维护相关结构 + * @param domainId 域id + */ + void removeAiAlarmMsgByDomainID(const int &domainId); + /** + * @brief addAiAllAlarmMsg 全数据时调用,不会通知模型,全部接收完会自动通知模型刷新(重新装载数据) + * @param msg 智能告警指针 + */ + void addAiAllAlarmMsg(AiAlarmMsgPtr &msg); + /** + * @brief addAiAlarmMsg 非全数据时调用,会通知模型添加智能告警,删除相关原始告警 + * @param msg 智能告警指针 + */ + void addAiAlarmMsg(AiAlarmMsgPtr &msg); + /** + * @brief delAiAlarmMsg 根据智能告警uuid删除智能告警 + * @param aiuuid 智能告警uuid + */ + void delAiAlarmMsg(QString &aiuuid); + /** + * @brief brokenAiAlarmMsg 处理不完整的智能告警 + * @param aiuuid + */ + void brokenAiAlarmMsg(QString &aiuuid); + /** + * @brief releaseAiAlarmMsg 根据智能告警uuid释放智能告警 + * @param aiuuid 智能告警uuid + */ + void releaseAiAlarmMsg(QString &aiuuid); + /** + * @brief getAiuuid 根据原始告警uuid获取智能告警uuid + * @param uuid 原始告警uuid + * @param aiuuid 智能告警uuid + * @return 成功返回true,失败返回false + */ + bool getAiuuid(QString &uuid,QString &aiuuid); + /** + * @brief getAlarmOtherStatus 获取其他告警状态集合 + * @return 其他告警状态集合 + */ + QMap getAlarmOtherStatus(); + /** + * @brief isBelongAi 是否属于某个智能告警(已经被某个智能告警聚类) + * @param uuid 原始告警uuid + * @return true-已经被聚类 false-还未被聚类 + */ + bool isBelongAi(const QString &uuid); +private: + /** + * @brief eraseaicount 删除key为aiuuid的键值对 (<智能告警id,SAiConfirm>) + * @param aiuuid 智能告警uuid + */ + void eraseaicount(QString &aiuuid); + /** + * @brief eraseidtoid 删除值为aiuuid的所有键值对(<原始告警id,智能告警id>) + * @param aiuuid 智能告警uuid + */ + void eraseidtoid(QString &aiuuid); + /** + * @brief eraseidtolocation 删除key为aiuuid的键值对 (<智能告警id,与此条智能告警相关的所有位置id>) + * @param aiuuid 智能告警uuid + */ + void eraseidtolocation(QString &aiuuid); + /** + * @brief isHaveAlm 查询m_all中是否包含uuidVec中的告警(确保智能告警下的原始告警一定存在) + * @param uuidVec + * @return + */ + bool isHaveAlm(QVector &uuidVec); + /** + * @brief checkLookPerm 检查当前登陆用户是否具有此条智能告警的权限(若可以看到其中任意一条,则具有权限) + * @param uuidVec 智能告警下原始告警uuid集合 + * @return 有权限返回 true 否则返回false + */ + bool checkLookPerm(QVector &uuidVec); + /** + * @brief addidtoid 添加原始告警uuid和智能告警uuid的映射 + * @param uuidVec 原始告警uuid集合 + * @param aiuuid 智能告警uuid + */ + void addidtoid(QVector &uuidVec,QString &aiuuid); + /** + * @brief addaicount 添加智能告警下原始告警的已确认和总数 + * @param uuidVec 原始告警uuid集合 + * @param aiuuid 智能告警uuid + */ + void addaicount(QVector &uuidVec,QString &aiuuid); + /** + * @brief addaitolocation 添加智能告警uuid和与此告警相关位置的id + * @param uuidVec 原始告警uuid集合 + * @param aiuuid 智能告警uuid + */ + void addaitolocation(QVector &uuidVec,QString &aiuuid); + /** + * @brief initaivideo 初始化智能告警下原始告警的视频标识 + * @param uuidVec 原始告警uuid集合 + * @param aiuuid 智能告警uuid + * @return 具有返回true,否则返回false + */ + bool initaivideo(QVector &uuidVec); + /** + * @brief getLocationByuuid 根据原始告警uuid获取位置id + * @param uuid 原始告警uuid + * @param location 位置 + * @return 成功返回true,否则返回false + */ + bool getLocationByuuid(QString &uuid, int &location); + /** + * @brief getVideoFlagByuuid 根据原始告警uuid获取是否具有视频标识 + * @param uuid + * @param flag 标识 + * @return + */ + bool getVideoFlagByuuid(QString &uuid,bool &flag); + /** + * @brief getConfirmByuuid 根据原始告警uuid获取是否被确认 + * @param uuid 原始告警uuid + * @return true-确认,false-未确认 + */ + bool getConfirmByuuid(QString &uuid); + /** + * @brief updatealarm 更新需要展示在智能告警窗上未聚类的原始告警 + * @param uuidVec 某条智能告警下的所有原始告警的uuid + * @param deluuidVec 需要被删除的一级节点上的未聚类的原始告警uuid + */ + void updatealarm(QVector &uuidVec, QVector &deluuidVec); + /** + * @brief loadAlarmInfoConfig 加载告警配置信息 + */ + void loadAlarmInfoConfig(); + /** + * @brief loadPriorityDescription 加载优先级描述 + */ + void loadPriorityDescription(); + /** + * @brief loadLocationDescription 加载位置描述 + */ + void loadLocationDescription(); + /** + * @brief loadRegionDescription 加载责任区描述 + */ + void loadRegionDescription(); + /** + * @brief loadAlarmTypeDescription 加载告警类型 + */ + void loadAlarmTypeDescription(); + /** + * @brief loadAlarmStatusDescription 加载告警状态描述 + */ + void loadAlarmStatusDescription(); + /** + * @brief loadDeviceTypeDescription 加载设备类型描述 + */ + void loadDeviceTypeDescription(); + /** + * @brief loadDeviceGroupDescription 加载设备组描述 + */ + void loadDeviceGroupDescription(); + /** + * @brief loadAlarmShowStatusDescription 加载需要显示在告警窗下拉框中的告警状态描述 + */ + void loadAlarmShowStatusDescription(); + /** + * @brief loadAlarmOtherStatusDescription 加载其他告警状态描述 + */ + void loadAlarmOtherStatusDescription(); + /** + * @brief almStats 告警统计 + * @param msg 告警指针 + * @param addOrSub 1--add 0--sub(1添加,0删除) + */ + void almStats(const AlarmMsgPtr &msg,int addOrSub); + /** + * @brief almAddStats 告警添加统计 + * @param msg 告警指针 + */ + void almAddStats(const AlarmMsgPtr &msg); + /** + * @brief almSubStats 告警删除统计 + * @param msg 告警指针 + */ + void almSubStats(const AlarmMsgPtr &msg); + /** + * @brief devDevGTotAlmAddStats 设备设备组按优先级添加统计 + * @param msg 告警指针 + */ + void devDevGTotAlmAddStats(const AlarmMsgPtr &msg); + /** + * @brief devDevGTotAlmSubStats 设备设备组按优先级删除统计 + * @param msg 告警指针 + */ + void devDevGTotAlmSubStats(const AlarmMsgPtr &msg); + void devDevGAddStats(const AlarmMsgPtr &msg); + void devDevGSubStats(const AlarmMsgPtr &msg); + void locAddStats(const AlarmMsgPtr &msg); + void locSubStats(const AlarmMsgPtr &msg); +signals: + /** + * @brief sigAiMsgRemove 通知智能告警模型删除智能告警 + * @param aiuuid 智能告警uuid + */ + void sigAiMsgRemove(const QString aiuuid); + /** + * @brief sigAiMsgAdd 通知智能告警模型添加某条智能告警 + * @param aimsg 智能告警指针 + */ + void sigAiMsgAdd(const AiAlarmMsgPtr aimsg); + /** + * @brief sigMsgRemove 通知智能告警模型删除一级节点上的原始告警 + * @param deluuid 需要删除的原始告警uuid的集合 + */ + void sigMsgRemove(const QVector deluuid); +public: + /** + * @brief queryPriorityDesc 根据id查询优先级描述 + * @param id 优先级id + * @return 优先级描述 + */ + QString queryPriorityDesc(int id); + /** + * @brief queryLocationDesc 根据位置id查询位置描述 + * @param id 位置id + * @return 位置描述 + */ + QString queryLocationDesc(int id); + /** + * @brief queryLocationDesc 根据智能告警uuid查询位置描述(可能包含多个位置) + * @param aiuuid 智能告警uuid + * @return 位置描述 + */ + QString queryLocationDesc(QString &aiuuid); + /** + * @brief queryRegionDesc 根据责任区id查询责任区描述 + * @param id 责任区id + * @return 责任区描述 + */ + QString queryRegionDesc(int id); + /** + * @brief queryAlarmTypeDesc 根据告警类型id查询告警类型描述 + * @param id 告警类型id + * @return 告警类型描述 + */ + QString queryAlarmTypeDesc(int id); + /** + * @brief queryAlarmStatusDesc 根据告警状态id查询告警状态描述 + * @param id 告警状态id + * @return 告警状态描述 + */ + QString queryAlarmStatusDesc(int id); + /** + * @brief queryDevTypeByDesc 根据设备类型描述查询设备类型id + * @param desc 设备描述 + * @return 设备id + */ + int queryDevTypeByDesc(QString &desc); + /** + * @brief queryConfirm 根据智能告警uuid查询确认数和总数 + * @param aiuuid 智能告警uuid + * @return 确认数/总数(ex:20/30) + */ + QString queryConfirm(const QString &aiuuid); + /** + * @brief queryAiTotal 根据智能告警uuid 查询原始告警条数 + * @param aiuuid 智能告警uuid + * @return 原始告警条数 + */ + int queryAiTotal(const QString &aiuuid); + /** + * @brief getAlarmInfo 获取所有有权限的原始告警和智能告警 (接口:给智能告警模型使用) + * @param listAlarm 原始告警指针集合 + * @param listaiAlarm 智能告警指针集合 + */ + void getAlarmInfo(QList &listAlarm,QList &listaiAlarm); + /** + * @brief getAlarmPtrByuuid 根据原始告警uuid获取原始告警指针 + * @param uuid 原始告警uuid + * @return 原始告警指针 + */ + AlarmMsgPtr getAlarmPtrByuuid(const QString uuid); + /** + * @brief ifhaveNotConfirmAlmByuuid 根据智能告警uuid查询是否还有未确认的原始告警 + * @param aiuuid 智能告警uuid + * @return 如果包含未确认原始告警返回true,否则返回false + */ + bool ifhaveNotConfirmAlmByuuid(QString &aiuuid); + /** + * @brief getAiLocationList 根据智能告警uuid获取有关的位置集合 + * @param aiuuid 智能告警uuid + * @return 与之有关的位置集合 + */ + QList getAiLocationList(QString &aiuuid); + /** + * @brief updateAiInfo 原始告警重传后需要更新智能告警下的原始告警指针以及相关信息 + */ + void updateAiInfo(); + /** + * @brief needUpdateAi 判断是否出错需要重传(一般情况下不会出错,但是当网络出现间断性故障,告警服务会断点续传,无法保证原始告警和智能告警的先后顺序,导致智能告警在前,原始告警在后, + * 智能告警无法查找到原始告警,特需要标识去判断是否发生故障,若故障则重置模型,重新关联数据。) + * @return true-出错需要重传,false-正确无需重传 + */ + bool needUpdateAi(); + /** + * @brief getalmuuidByAiuuid 根据智能告警uuid获取相关原始告警uuid + * @param aiuuid 智能告警uuid + * @return 原始告警uuidList + */ + QList getalmuuidByAiuuid(const QString &aiuuid); + /** + * @brief getAlmTotal 获取智能告警窗显示原始告警总数 + * @return 数量 + */ + int getAlmTotal(); +private: + QMutex * mutex; + kbd_dbms::CRdbAccess * m_rtdbAlarmActionAccess; + kbd_dbms::CRdbAccess * m_rtdbLocationDescriptionAccess; + kbd_dbms::CRdbAccess * m_rtdbAppDescriptionAccess; + //kbd_dbms::CRdbAccess * m_rtdbDeviceAccess; + kbd_dbms::CDbApi * m_dbInterface; + int m_nNDelComAlarmCount; //< 未删除未确认数量 N--not Del--delete Com--confirm + int m_nDelNComAlarmCount; //< 已删除未确认数量 + QHash m_infos; + QHash m_all; + static CAlarmMsgManage * pInstance; + + + QList m_listPermLocationId; //< 原始告警车站权限 + QList m_listPermRegionId; //< 原始告警责任区权限 + //缓存从collect调整到mng + QList m_listMsgAddCache; //< 告警缓存(每秒更新) + QStringList m_inhibitFilter; //< 告警抑制[界面] + + //智能告警新加 + QHash m_alarm; //< 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗)(两个线程共同维护) + QHash m_aiinfos; //< 有权限的智能告警 + QHash m_aiall; //< 所有智能告警 + + QHash m_aicount; //< <智能告警uuid,已确认数/总数 > + QHash m_idToid; //< <原始告警uuid,智能告警uuid > 用于确认原始告警之后便于更新智能告警中的已确认总数 + + QHash > m_aitolocation;//< <智能告警uuid,包含的原始告警车站id> + + QHash m_alarmDeviceStatistical; //< 设备告警数量统计 + QHash m_alarmDeviceGroupStatistical; //<设备组告警数量统计 + QHash > m_alarmDevPriority; //< 设备告警等级数量统计 + QHash > > m_alarmDGPDev; //< <设备组,<告警等级,设备> > + QHash > m_alarmLPAlm; //< <车站id,<告警等级,告警数量> > + + kbd_dbms::CRdbAccess * m_rtdbAccess; + QMap m_priorityDescriptionMap; + QMap m_locationDescriptionMap; + QMap m_regionDescriptionMap; + QMap m_alarmTypeDescriptionMap; + QMap m_alarmStatusDescriptionMap; + QMap m_deviceTypeDescriptionMap; + QMap m_deviceGroupDescriptionMap; + QMap m_alarmShowStatusDescriptionMap; + QMap m_alarmOtherStatusDescriptionMap; + bool m_bIsError; //数据异常,或者智能告警来临时,没有找到相关联的原始告警则需要重新拉取数据 + + QList m_delaydeal; //延迟处理的智能告警 + + int m_nAlmNum; //智能告警窗原始告警个数 + int m_nAlmTotal; //智能告警窗原始告警总数 +}; + +#endif // CALARMMSGMANAGE_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.cpp index fdb3bb40..da760e08 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.cpp @@ -1,913 +1,913 @@ -#include "CAlarmPlugin.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "CAlarmView.h" -#include "CAlarmForm.h" -#include "CAlarmWidget.h" -#include "CAlarmItemModel.h" -#include "CAlarmDelegate.h" -#include "CAiAlarmDataCollect.h" -#include "CAlarmDataCollect.h" -#include "CAlarmMsgManage.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" - -QThread * CAlarmPlugin::m_pDataCollectThread = NULL; -CAlarmPlugin::CAlarmPlugin(QWidget *parent, bool editMode) - : QWidget(parent), - m_mode(E_Alarm_Window), - m_bIsEditMode(editMode), - m_alarmForm(Q_NULLPTR), - m_alarmWidget(Q_NULLPTR), - m_alarmView(Q_NULLPTR), - m_pModel(Q_NULLPTR) -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - qRegisterMetaType< CAlarmMsgInfo >("CAlarmMsgInfo"); - qRegisterMetaType< AlarmMsgPtr >("AlarmMsgPtr"); - qRegisterMetaType< QList >("ListAlarmMsgPtr"); - - if(!m_bIsEditMode) - { - if(!m_pDataCollectThread) - { - m_pDataCollectThread = new QThread(); - CAlarmDataCollect::instance()->moveToThread(m_pDataCollectThread); - CAlarmMsgManage::instance()->moveToThread(m_pDataCollectThread); - CAiAlarmDataCollect::instance()->moveToThread(m_pDataCollectThread); - connect(m_pDataCollectThread, &QThread::started, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::initialize, Qt::QueuedConnection); - connect(m_pDataCollectThread, &QThread::finished, m_pDataCollectThread, &QThread::deleteLater, Qt::QueuedConnection); - } - connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigAlarmStateChanged, this, &CAlarmPlugin::recvAlarmNumChanged, Qt::QueuedConnection); - connect(this, &CAlarmPlugin::sigSwitchFaultRecallState, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::slotSwitchFaultRecallState, Qt::QueuedConnection); - CAlarmDataCollect::instance()->refrence(); - //由原始告警采集线程去退出智能告警线程和清理资源 - connect(this, &CAlarmPlugin::alarmExit, CAlarmDataCollect::instance(), &CAlarmDataCollect::destory, Qt::BlockingQueuedConnection); - connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigUpdateAlarmView, this, &CAlarmPlugin::slotUpdateAlarmView, Qt::QueuedConnection); - connect(CAiAlarmDataCollect::instance(),&CAiAlarmDataCollect::sigUpdateAlarmView,this,&CAlarmPlugin::slotUpdateAiAlarmView,Qt::QueuedConnection); - connect(CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::sigAlarmOperateEnable, this, &CAlarmPlugin::slotUpdateAlarmOperateEnable, Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::openVideo,this,&CAlarmPlugin::openVideoDialog,Qt::QueuedConnection); - } -} - -CAlarmPlugin::~CAlarmPlugin() -{ - if(!m_bIsEditMode) - { - bool pExit = false; - int referenceCount = CAlarmDataCollect::instance()->getRefrenceCount(); - emit alarmExit(&pExit); - if(1 == referenceCount) - { - //< 退出数据采集线程 - while(!pExit) - { - QThread::msleep(10); - } - - //< 退出托管线程 - if(m_pDataCollectThread) - { - m_pDataCollectThread->exit(); - while (!m_pDataCollectThread->isFinished()) - { - QThread::msleep(10); - } - delete m_pDataCollectThread; - m_pDataCollectThread = Q_NULLPTR; - } - } - } - reset(); - LOGDEBUG("CAlarmPlugin::~CAlarmPlugin()"); - qDebug() << "~CAlarmPlugin()"; -} - -void CAlarmPlugin::initialize(int mode) -{ - if(E_Alarm_Dock != mode && E_Alarm_Window != mode && E_Alarm_Pop != mode) - { - return; - } - reset(); - - updateAlarmOperatePerm(); - - m_mode = (E_Alarm_Mode)mode; - - //初始界面:视图、模型 - QHBoxLayout * layout = new QHBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->setMargin(0); - if (E_Alarm_Window == mode) - { - m_alarmForm = new CAlarmForm(); - if(!m_bIsEditMode) - { - m_alarmForm->initialize(); - m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); - m_alarmForm->setAlarmModel(m_pModel); - connect(m_alarmForm, &CAlarmForm::closeBtnClicked, this, &CAlarmPlugin::closeBtnClicked, Qt::QueuedConnection); - } - else - { - m_alarmForm->setEnabled(false); - } - layout->addWidget(m_alarmForm); - } - else if (E_Alarm_Dock == mode) - { - m_alarmWidget = new CAlarmWidget(); - if(!m_bIsEditMode) - { - m_alarmWidget->initialize(); - m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); - m_alarmWidget->setAlarmModel(m_pModel); - if(!m_pDataCollectThread->isRunning()) - { - m_pDataCollectThread->start(); - } - connect(m_alarmWidget, &CAlarmWidget::alarmWidgetDoubleClicked, this, &CAlarmPlugin::alarmDockDoubleClicked, Qt::QueuedConnection);// dock 双击 - if(!CAlarmMsgManage::instance()->isBindMediaPlayer())//判断信号是否被连接 - { - connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigInsertAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::insertAudioCues, Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigStopAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::removeAudioCues, Qt::QueuedConnection); - connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigAlarmPushGraph, this, &CAlarmPlugin::alarmPush, Qt::QueuedConnection); - } - } - else - { - m_alarmWidget->initializeEdit(); - m_alarmWidget->setEnabled(false); - } - layout->addWidget(m_alarmWidget); - } - else if (E_Alarm_Pop == mode) - { - m_alarmView = new CAlarmView(this); - if(!m_bIsEditMode) - { - m_alarmView->initialize(); - m_alarmView->horizontalHeader()->setSortIndicatorShown(false); - m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); - m_alarmView->setModel(m_pModel); - CAlarmDelegate * pDelegate = new CAlarmDelegate(m_pModel, this); - m_alarmView->setItemDelegate(pDelegate); - } - else - { - m_alarmView->setEnabled(false); - } - layout->addWidget(m_alarmView); - } - setLayout(layout); - slotUpdateAlarmOperateEnable(!CAiAlarmDataCollect::instance()->isFaultRecallState()); -} - -void CAlarmPlugin::login() -{ - if(!m_bIsEditMode) - { - LOGDEBUG("CAlarmPlugin::login():"); - if(m_pModel == NULL) - { - LOGERROR("登陆出错,空指针!"); - return ; - } - updateAlarmOperatePerm(); - CAiAlarmDataCollect::instance()->release(); - CAlarmMediaPlayer::instance()->release(); - m_pModel->initialize(); - CAiAlarmDataCollect::instance()->initialize(); - } -} - -void CAlarmPlugin::logout() -{ - if(!m_bIsEditMode) - { - updateAlarmOperatePerm(); - CAiAlarmDataCollect::instance()->release(); - CAlarmMediaPlayer::instance()->release(); - } -} - -void CAlarmPlugin::switchFaultRecallState(bool bFaultRecallState) -{ - if(!m_bIsEditMode) - { - updateAlarmOperatePerm(); - CAlarmMediaPlayer::instance()->release(); - emit sigSwitchFaultRecallState(bFaultRecallState); - } -} - -int CAlarmPlugin::confirmAlarm(const QString &key_id_tag) -{ - QList listMsg = CAlarmMsgManage::instance()->findMsgsByKeyIdTag(key_id_tag); - return confirmAlarm(listMsg); -} - -int CAlarmPlugin::confirmAlarm(const QList &msgs) -{ - if(msgs.isEmpty()) - { - return -1; - } - - if(m_vecRegionId.empty() || m_vecLocationId.empty()) - { - return -1; - } - //< 可能有部分告警没有确认权限 - QMap pkgMap; //Domain-DelPkg; - for(int nIndex(0); nIndex < msgs.size(); nIndex++) - { - AlarmMsgPtr info = msgs.at(nIndex); - - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionId.begin(); - while (region != m_vecRegionId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationId.begin(); - while (location != m_vecLocationId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - QMap::iterator it = pkgMap.find(info->domain_id); - if(it == pkgMap.end()) - { - kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); - pkg->set_node_name(m_currentNodeName); - pkg->set_user_id(m_currentUsrId); - pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); - pkg->set_domain_id(info->domain_id); - pkg->set_app_id(info->app_id); - pkg->set_alm_type(info->alm_type); - pkgMap[info->domain_id] = pkg; - LOGINFO("Bulid Alarm Confirm MSG: %d", info->domain_id); - } - pkgMap.value(info->domain_id)->add_time_stamp(info->time_stamp); - pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); - pkgMap.value(info->domain_id)->add_key_id_tag(info->key_id_tag.toStdString()); - } - } - //请求确认 - foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) - { - CAlarmDataCollect::instance()->requestCfmAlm(*pkg); - } - qDeleteAll(pkgMap); - pkgMap.clear(); - return 0; -} - -int CAlarmPlugin::removeAlarm(const QList &msgs) -{ - if(msgs.isEmpty()) - { - return -1; - } - - if(m_vecRegionId.empty() || m_vecLocationId.empty()) - { - return -1; - } - //< 可能有部分告警没有删除权限 - QMap pkgMap; - for(int nIndex(0); nIndex < msgs.size(); nIndex++) - { - AlarmMsgPtr info = msgs.at(nIndex); - - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionId.begin(); - while (region != m_vecRegionId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationId.begin(); - while (location != m_vecLocationId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - QMap::iterator it = pkgMap.find(info->domain_id); - if( it == pkgMap.end()) - { - kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); - pkg->set_domain_id(info->domain_id); - pkgMap[info->domain_id] = pkg; - } - pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); - } - } - //请求删除 - foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) - { - CAlarmDataCollect::instance()->requestDelAlm(*pkg); - } - qDeleteAll(pkgMap); - pkgMap.clear(); - return 0; -} - - -void CAlarmPlugin::setVolumeEnable(bool bEnable) -{ - CAlarmMediaPlayer::instance()->setVolumeEnable(bEnable); -} - -void CAlarmPlugin::recvAlarmNumChanged(const int &total, const int &unConfirm) -{ - emit alarmNumChanged(total, unConfirm); -} - -void CAlarmPlugin::setColumnAlign(const int &column, const int &alignFlag) -{ - if(m_bIsEditMode) - { - return; - } - if(!m_pModel) - { - return; - } - m_pModel->setColumnAlign(column, alignFlag); -} - -void CAlarmPlugin::setDockRowHeight(const int &height) -{ - if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->setRowHeight(height); - } -} - -void CAlarmPlugin::setDockColumnVisible(const int &column, const bool &visbile) -{ - if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->setDockColumnVisible(column, visbile); - } -} - -QStringList CAlarmPlugin::getDevAlmInfo(const QString device) -{ - QMap alarm = CAlarmMsgManage::instance()->getDevAlarm(device); - QStringList result; - result.clear(); - QMap::iterator it= alarm.begin(); - while (it!= alarm.end()) { - QString alarmNum= QString("%1_%2").arg(it.key()).arg(it.value()); - result.append(alarmNum); - it++; - } - return result; -} - -QStringList CAlarmPlugin::getDevGroupAlmInfo(const QString deviceGroup) -{ - QMap > listMap = CAlarmMsgManage::instance()->getDevGroupPriorityDevNum(deviceGroup); - QStringList result; - result.clear(); - QMap >::iterator it =listMap.begin(); - for(;it != listMap.end();it++) - { - //优先级_设备数量 - QString priDev= QString("%1_%2").arg(it.key()).arg(it.value().size()); - result.append(priDev); - } - return result; -} - -QStringList CAlarmPlugin::getLocAlmInfo() -{ - QHash > locAlm = CAlarmMsgManage::instance()->getLocAlmInfo(); - QStringList list; - list.clear(); - QHash >::iterator it = locAlm.begin(); - while (it != locAlm.end()) { - QMap &priAlmNum =it.value(); - QMap::iterator pos = priAlmNum.begin(); - while (pos != priAlmNum.end()) { - QString priAlm = QString("%1_%2_%3").arg(it.key()).arg(pos.key()).arg(pos.value()); - list.append(priAlm); - pos++; - } - it++; - } - return list; -} - - -void CAlarmPlugin::setDevice(const QString &device) -{ - if(m_bIsEditMode || E_Alarm_Pop != m_mode) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - m_pModel->addDeviceFilter(device); -} - -void CAlarmPlugin::setDeviceGroup(const QString &deviceGroup) -{ - if(m_bIsEditMode || E_Alarm_Pop != m_mode) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - if(deviceGroup.isEmpty()) - { - m_pModel->addDeviceGroupFilter(); - }else - { - m_pModel->addDeviceGroupFilter(deviceGroup); - } - -} - -void CAlarmPlugin::setPointTag(const QString &pointList) -{ - if(m_bIsEditMode || E_Alarm_Pop != m_mode) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - QStringList s= pointList.split(","); - QList pointTagList; - for(int i = 0;iaddPointTagFilter(pointTagList); -} - -void CAlarmPlugin::setColumnVisible(const int &column, const bool &visible) -{ - if(m_bIsEditMode || E_Alarm_Pop != m_mode) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - m_alarmView->setColumnHidden(column, !visible); -} - -void CAlarmPlugin::confirmFirstAlarm(int index) -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Dock != m_mode || bFaultRecallState) - { - return; - } - if(!m_pModel) - { - return; - } - m_alarmWidget->confirmAlarm(index); -} - -void CAlarmPlugin::setColumnWidth(const int &column, const int &width) -{ - if(m_bIsEditMode) - { - return; - } - if(E_Alarm_Window == m_mode) - { - if(!m_alarmForm) - { - return; - } - m_alarmForm->setColumnWidth(column, width); - } - else if(E_Alarm_Dock == m_mode) - { - if(!m_alarmWidget) - { - return; - } - m_alarmWidget->setColumnWidth(column, width); - } - else if(E_Alarm_Pop == m_mode) - { - if(!m_alarmView || !m_pModel) - { - return; - } - m_alarmView->setColumnWidth(column, width); - } -} - -int CAlarmPlugin::currentSelectCount() -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) - { - return 0; - } - if(!m_alarmView || !m_pModel) - { - return 0; - } - QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(); - return listModelIndex.size(); -} - -void CAlarmPlugin::confirmCurrentAlarm() -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(0); - - QList msgs; - foreach (QModelIndex index, listModelIndex) - { - msgs.append(m_pModel->getAlarmInfo(index)); - } - confirmAlarm(msgs); - m_alarmView->clearSelection(); -} - -void CAlarmPlugin::confirmAllAlarm() -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - - bool permSkip = false; - QList msgs; - for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) - { - AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionId.begin(); - while (region != m_vecRegionId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationId.begin(); - while (location != m_vecLocationId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - msgs.append(info); - } - else - { - if(permSkip) - { - continue; - } - else - { - if(1 != permSkip) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox.setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox.addButton(tr("取消"), QMessageBox::RejectRole); - msgBox.setDefaultButton(skip); - msgBox.exec(); - if (msgBox.clickedButton() == skip) - { - continue; - } - else if (msgBox.clickedButton() == skipAll) - { - permSkip = true; - continue; - } - else - { - return; - } - } - } - } - } - confirmAlarm(msgs); - m_alarmView->clearSelection(); -} - -void CAlarmPlugin::removeAllAlarm() -{ - bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); - if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) - { - return; - } - if(!m_alarmView || !m_pModel) - { - return; - } - - bool permSkip = false; - bool unConfirmSkip = false; - QList msgs; - for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) - { - AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); - bool regionEnable = false; - bool locationEnable = false; - std::vector ::iterator region = m_vecRegionId.begin(); - while (region != m_vecRegionId.end()) - { - if(info->region_id == (*region++)) - { - regionEnable = true; - } - } - - std::vector ::iterator location = m_vecLocationId.begin(); - while (location != m_vecLocationId.end()) - { - if(info->location_id == (*location++)) - { - locationEnable = true; - } - } - if(regionEnable && locationEnable) - { - if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) - { - if(!unConfirmSkip) - { - QMessageBox msgBox; - msgBox.setText(tr("包含未确认告警!")); - msgBox.setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox.addButton(tr("取消"), QMessageBox::RejectRole); - msgBox.setDefaultButton(skip); - msgBox.exec(); - if (msgBox.clickedButton() == skip) - { - continue; - } - else if (msgBox.clickedButton() == skipAll) - { - unConfirmSkip = true; - continue; - } - else - { - return; - } - } - else - { - continue; - } - } - else - { - msgs.append(info); - } - } - else - { - if(permSkip) - { - continue; - } - else - { - if(1 != permSkip) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); - msgBox.setInformativeText(tr("是否跳过该项?")); - QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); - QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); - msgBox.addButton(tr("取消"), QMessageBox::RejectRole); - msgBox.setDefaultButton(skip); - msgBox.exec(); - if (msgBox.clickedButton() == skip) - { - continue; - } - else if (msgBox.clickedButton() == skipAll) - { - permSkip = true; - continue; - } - else - { - return; - } - } - } - } - } - removeAlarm(msgs); - m_alarmView->clearSelection(); -} - -void CAlarmPlugin::slotUpdateAlarmView() -{ - if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) - { - m_alarmWidget->updateView(); - } - else if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->updateView(); - } - else if(E_Alarm_Pop == m_mode && m_alarmView != Q_NULLPTR) - { - m_alarmView->viewport()->update(); - } -} - -void CAlarmPlugin::slotUpdateAiAlarmView() -{ - if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) - { - m_alarmForm->updateView(); - } - -} - -void CAlarmPlugin::slotUpdateAlarmOperateEnable(const bool &bEnable) -{ - if(!m_bIsEditMode) - { - if (E_Alarm_Window == m_mode) - { - m_alarmForm->setAlarmOperateEnable(bEnable); - - } - else if (E_Alarm_Dock == m_mode) - { - m_alarmWidget->setAlarmOperateEnable(bEnable); - - } - else if (E_Alarm_Pop == m_mode) - { - //< 禁用确认、删除接口, 见E_Alarm_Pop模式接口 - } - } -} - -void CAlarmPlugin::reset() -{ - if(Q_NULLPTR != m_pModel) - { - m_pModel->disconnect(); - delete m_pModel; - } - m_pModel = Q_NULLPTR; - - if(Q_NULLPTR != m_alarmForm) - { - delete m_alarmForm; - } - m_alarmForm = Q_NULLPTR; - - if(Q_NULLPTR != m_alarmWidget) - { - delete m_alarmWidget; - } - m_alarmWidget = Q_NULLPTR; - - if(Q_NULLPTR != m_alarmView) - { - delete m_alarmView; - } - m_alarmView = Q_NULLPTR; - - QLayout * lyt = layout(); - if(Q_NULLPTR != lyt) - { - delete lyt; - } -} - -void CAlarmPlugin::updateAlarmOperatePerm() -{ - m_currentUsrId = -1; - m_currentNodeName = ""; - m_vecRegionId.clear(); - m_vecLocationId.clear(); - - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!") - return; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - - m_currentNodeName = stNodeInfo.strName; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(0 != permMngPtr->CurUser(m_currentUsrId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - LOGERROR("用户ID获取失败!") - return; - } - if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, m_vecRegionId, m_vecLocationId)) - { - LOGERROR("用户不具备告警操作权限!") - return; - } - } -} +#include "CAlarmPlugin.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmView.h" +#include "CAlarmForm.h" +#include "CAlarmWidget.h" +#include "CAlarmItemModel.h" +#include "CAlarmDelegate.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmDataCollect.h" +#include "CAlarmMsgManage.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" + +QThread * CAlarmPlugin::m_pDataCollectThread = NULL; +CAlarmPlugin::CAlarmPlugin(QWidget *parent, bool editMode) + : QWidget(parent), + m_mode(E_Alarm_Window), + m_bIsEditMode(editMode), + m_alarmForm(Q_NULLPTR), + m_alarmWidget(Q_NULLPTR), + m_alarmView(Q_NULLPTR), + m_pModel(Q_NULLPTR) +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + qRegisterMetaType< CAlarmMsgInfo >("CAlarmMsgInfo"); + qRegisterMetaType< AlarmMsgPtr >("AlarmMsgPtr"); + qRegisterMetaType< QList >("ListAlarmMsgPtr"); + + if(!m_bIsEditMode) + { + if(!m_pDataCollectThread) + { + m_pDataCollectThread = new QThread(); + CAlarmDataCollect::instance()->moveToThread(m_pDataCollectThread); + CAlarmMsgManage::instance()->moveToThread(m_pDataCollectThread); + CAiAlarmDataCollect::instance()->moveToThread(m_pDataCollectThread); + connect(m_pDataCollectThread, &QThread::started, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::initialize, Qt::QueuedConnection); + connect(m_pDataCollectThread, &QThread::finished, m_pDataCollectThread, &QThread::deleteLater, Qt::QueuedConnection); + } + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigAlarmStateChanged, this, &CAlarmPlugin::recvAlarmNumChanged, Qt::QueuedConnection); + connect(this, &CAlarmPlugin::sigSwitchFaultRecallState, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::slotSwitchFaultRecallState, Qt::QueuedConnection); + CAlarmDataCollect::instance()->refrence(); + //由原始告警采集线程去退出智能告警线程和清理资源 + connect(this, &CAlarmPlugin::alarmExit, CAlarmDataCollect::instance(), &CAlarmDataCollect::destory, Qt::BlockingQueuedConnection); + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigUpdateAlarmView, this, &CAlarmPlugin::slotUpdateAlarmView, Qt::QueuedConnection); + connect(CAiAlarmDataCollect::instance(),&CAiAlarmDataCollect::sigUpdateAlarmView,this,&CAlarmPlugin::slotUpdateAiAlarmView,Qt::QueuedConnection); + connect(CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::sigAlarmOperateEnable, this, &CAlarmPlugin::slotUpdateAlarmOperateEnable, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::openVideo,this,&CAlarmPlugin::openVideoDialog,Qt::QueuedConnection); + } +} + +CAlarmPlugin::~CAlarmPlugin() +{ + if(!m_bIsEditMode) + { + bool pExit = false; + int referenceCount = CAlarmDataCollect::instance()->getRefrenceCount(); + emit alarmExit(&pExit); + if(1 == referenceCount) + { + //< 退出数据采集线程 + while(!pExit) + { + QThread::msleep(10); + } + + //< 退出托管线程 + if(m_pDataCollectThread) + { + m_pDataCollectThread->exit(); + while (!m_pDataCollectThread->isFinished()) + { + QThread::msleep(10); + } + delete m_pDataCollectThread; + m_pDataCollectThread = Q_NULLPTR; + } + } + } + reset(); + LOGDEBUG("CAlarmPlugin::~CAlarmPlugin()"); + qDebug() << "~CAlarmPlugin()"; +} + +void CAlarmPlugin::initialize(int mode) +{ + if(E_Alarm_Dock != mode && E_Alarm_Window != mode && E_Alarm_Pop != mode) + { + return; + } + reset(); + + updateAlarmOperatePerm(); + + m_mode = (E_Alarm_Mode)mode; + + //初始界面:视图、模型 + QHBoxLayout * layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setMargin(0); + if (E_Alarm_Window == mode) + { + m_alarmForm = new CAlarmForm(); + if(!m_bIsEditMode) + { + m_alarmForm->initialize(); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + m_alarmForm->setAlarmModel(m_pModel); + connect(m_alarmForm, &CAlarmForm::closeBtnClicked, this, &CAlarmPlugin::closeBtnClicked, Qt::QueuedConnection); + } + else + { + m_alarmForm->setEnabled(false); + } + layout->addWidget(m_alarmForm); + } + else if (E_Alarm_Dock == mode) + { + m_alarmWidget = new CAlarmWidget(); + if(!m_bIsEditMode) + { + m_alarmWidget->initialize(); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + m_alarmWidget->setAlarmModel(m_pModel); + if(!m_pDataCollectThread->isRunning()) + { + m_pDataCollectThread->start(); + } + connect(m_alarmWidget, &CAlarmWidget::alarmWidgetDoubleClicked, this, &CAlarmPlugin::alarmDockDoubleClicked, Qt::QueuedConnection);// dock 双击 + if(!CAlarmMsgManage::instance()->isBindMediaPlayer())//判断信号是否被连接 + { + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigInsertAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::insertAudioCues, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigStopAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::removeAudioCues, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigAlarmPushGraph, this, &CAlarmPlugin::alarmPush, Qt::QueuedConnection); + } + } + else + { + m_alarmWidget->initializeEdit(); + m_alarmWidget->setEnabled(false); + } + layout->addWidget(m_alarmWidget); + } + else if (E_Alarm_Pop == mode) + { + m_alarmView = new CAlarmView(this); + if(!m_bIsEditMode) + { + m_alarmView->initialize(); + m_alarmView->horizontalHeader()->setSortIndicatorShown(false); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + m_alarmView->setModel(m_pModel); + CAlarmDelegate * pDelegate = new CAlarmDelegate(m_pModel, this); + m_alarmView->setItemDelegate(pDelegate); + } + else + { + m_alarmView->setEnabled(false); + } + layout->addWidget(m_alarmView); + } + setLayout(layout); + slotUpdateAlarmOperateEnable(!CAiAlarmDataCollect::instance()->isFaultRecallState()); +} + +void CAlarmPlugin::login() +{ + if(!m_bIsEditMode) + { + LOGDEBUG("CAlarmPlugin::login():"); + if(m_pModel == NULL) + { + LOGERROR("登陆出错,空指针!"); + return ; + } + updateAlarmOperatePerm(); + CAiAlarmDataCollect::instance()->release(); + CAlarmMediaPlayer::instance()->release(); + m_pModel->initialize(); + CAiAlarmDataCollect::instance()->initialize(); + } +} + +void CAlarmPlugin::logout() +{ + if(!m_bIsEditMode) + { + updateAlarmOperatePerm(); + CAiAlarmDataCollect::instance()->release(); + CAlarmMediaPlayer::instance()->release(); + } +} + +void CAlarmPlugin::switchFaultRecallState(bool bFaultRecallState) +{ + if(!m_bIsEditMode) + { + updateAlarmOperatePerm(); + CAlarmMediaPlayer::instance()->release(); + emit sigSwitchFaultRecallState(bFaultRecallState); + } +} + +int CAlarmPlugin::confirmAlarm(const QString &key_id_tag) +{ + QList listMsg = CAlarmMsgManage::instance()->findMsgsByKeyIdTag(key_id_tag); + return confirmAlarm(listMsg); +} + +int CAlarmPlugin::confirmAlarm(const QList &msgs) +{ + if(msgs.isEmpty()) + { + return -1; + } + + if(m_vecRegionId.empty() || m_vecLocationId.empty()) + { + return -1; + } + //< 可能有部分告警没有确认权限 + QMap pkgMap; //Domain-DelPkg; + for(int nIndex(0); nIndex < msgs.size(); nIndex++) + { + AlarmMsgPtr info = msgs.at(nIndex); + + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionId.begin(); + while (region != m_vecRegionId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationId.begin(); + while (location != m_vecLocationId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); + pkg->set_node_name(m_currentNodeName); + pkg->set_user_id(m_currentUsrId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(info->domain_id); + pkg->set_app_id(info->app_id); + pkg->set_alm_type(info->alm_type); + pkgMap[info->domain_id] = pkg; + LOGINFO("Bulid Alarm Confirm MSG: %d", info->domain_id); + } + pkgMap.value(info->domain_id)->add_time_stamp(info->time_stamp); + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + pkgMap.value(info->domain_id)->add_key_id_tag(info->key_id_tag.toStdString()); + } + } + //请求确认 + foreach (kbd_idlfile::SAlmCltCfmAlm * pkg, pkgMap) + { + CAlarmDataCollect::instance()->requestCfmAlm(*pkg); + } + qDeleteAll(pkgMap); + pkgMap.clear(); + return 0; +} + +int CAlarmPlugin::removeAlarm(const QList &msgs) +{ + if(msgs.isEmpty()) + { + return -1; + } + + if(m_vecRegionId.empty() || m_vecLocationId.empty()) + { + return -1; + } + //< 可能有部分告警没有删除权限 + QMap pkgMap; + for(int nIndex(0); nIndex < msgs.size(); nIndex++) + { + AlarmMsgPtr info = msgs.at(nIndex); + + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionId.begin(); + while (region != m_vecRegionId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationId.begin(); + while (location != m_vecLocationId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + QMap::iterator it = pkgMap.find(info->domain_id); + if( it == pkgMap.end()) + { + kbd_idlfile::SAlmCltDelAlm * pkg = new kbd_idlfile::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + } + //请求删除 + foreach (kbd_idlfile::SAlmCltDelAlm * pkg, pkgMap) + { + CAlarmDataCollect::instance()->requestDelAlm(*pkg); + } + qDeleteAll(pkgMap); + pkgMap.clear(); + return 0; +} + + +void CAlarmPlugin::setVolumeEnable(bool bEnable) +{ + CAlarmMediaPlayer::instance()->setVolumeEnable(bEnable); +} + +void CAlarmPlugin::recvAlarmNumChanged(const int &total, const int &unConfirm) +{ + emit alarmNumChanged(total, unConfirm); +} + +void CAlarmPlugin::setColumnAlign(const int &column, const int &alignFlag) +{ + if(m_bIsEditMode) + { + return; + } + if(!m_pModel) + { + return; + } + m_pModel->setColumnAlign(column, alignFlag); +} + +void CAlarmPlugin::setDockRowHeight(const int &height) +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setRowHeight(height); + } +} + +void CAlarmPlugin::setDockColumnVisible(const int &column, const bool &visbile) +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setDockColumnVisible(column, visbile); + } +} + +QStringList CAlarmPlugin::getDevAlmInfo(const QString device) +{ + QMap alarm = CAlarmMsgManage::instance()->getDevAlarm(device); + QStringList result; + result.clear(); + QMap::iterator it= alarm.begin(); + while (it!= alarm.end()) { + QString alarmNum= QString("%1_%2").arg(it.key()).arg(it.value()); + result.append(alarmNum); + it++; + } + return result; +} + +QStringList CAlarmPlugin::getDevGroupAlmInfo(const QString deviceGroup) +{ + QMap > listMap = CAlarmMsgManage::instance()->getDevGroupPriorityDevNum(deviceGroup); + QStringList result; + result.clear(); + QMap >::iterator it =listMap.begin(); + for(;it != listMap.end();it++) + { + //优先级_设备数量 + QString priDev= QString("%1_%2").arg(it.key()).arg(it.value().size()); + result.append(priDev); + } + return result; +} + +QStringList CAlarmPlugin::getLocAlmInfo() +{ + QHash > locAlm = CAlarmMsgManage::instance()->getLocAlmInfo(); + QStringList list; + list.clear(); + QHash >::iterator it = locAlm.begin(); + while (it != locAlm.end()) { + QMap &priAlmNum =it.value(); + QMap::iterator pos = priAlmNum.begin(); + while (pos != priAlmNum.end()) { + QString priAlm = QString("%1_%2_%3").arg(it.key()).arg(pos.key()).arg(pos.value()); + list.append(priAlm); + pos++; + } + it++; + } + return list; +} + + +void CAlarmPlugin::setDevice(const QString &device) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + m_pModel->addDeviceFilter(device); +} + +void CAlarmPlugin::setDeviceGroup(const QString &deviceGroup) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + if(deviceGroup.isEmpty()) + { + m_pModel->addDeviceGroupFilter(); + }else + { + m_pModel->addDeviceGroupFilter(deviceGroup); + } + +} + +void CAlarmPlugin::setPointTag(const QString &pointList) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + QStringList s= pointList.split(","); + QList pointTagList; + for(int i = 0;iaddPointTagFilter(pointTagList); +} + +void CAlarmPlugin::setColumnVisible(const int &column, const bool &visible) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + m_alarmView->setColumnHidden(column, !visible); +} + +void CAlarmPlugin::confirmFirstAlarm(int index) +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Dock != m_mode || bFaultRecallState) + { + return; + } + if(!m_pModel) + { + return; + } + m_alarmWidget->confirmAlarm(index); +} + +void CAlarmPlugin::setColumnWidth(const int &column, const int &width) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode) + { + if(!m_alarmForm) + { + return; + } + m_alarmForm->setColumnWidth(column, width); + } + else if(E_Alarm_Dock == m_mode) + { + if(!m_alarmWidget) + { + return; + } + m_alarmWidget->setColumnWidth(column, width); + } + else if(E_Alarm_Pop == m_mode) + { + if(!m_alarmView || !m_pModel) + { + return; + } + m_alarmView->setColumnWidth(column, width); + } +} + +int CAlarmPlugin::currentSelectCount() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return 0; + } + if(!m_alarmView || !m_pModel) + { + return 0; + } + QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(); + return listModelIndex.size(); +} + +void CAlarmPlugin::confirmCurrentAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(0); + + QList msgs; + foreach (QModelIndex index, listModelIndex) + { + msgs.append(m_pModel->getAlarmInfo(index)); + } + confirmAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::confirmAllAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + + bool permSkip = false; + QList msgs; + for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) + { + AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionId.begin(); + while (region != m_vecRegionId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationId.begin(); + while (location != m_vecLocationId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + msgs.append(info); + } + else + { + if(permSkip) + { + continue; + } + else + { + if(1 != permSkip) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + permSkip = true; + continue; + } + else + { + return; + } + } + } + } + } + confirmAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::removeAllAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + + bool permSkip = false; + bool unConfirmSkip = false; + QList msgs; + for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) + { + AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionId.begin(); + while (region != m_vecRegionId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationId.begin(); + while (location != m_vecLocationId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(!unConfirmSkip) + { + QMessageBox msgBox; + msgBox.setText(tr("包含未确认告警!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + unConfirmSkip = true; + continue; + } + else + { + return; + } + } + else + { + continue; + } + } + else + { + msgs.append(info); + } + } + else + { + if(permSkip) + { + continue; + } + else + { + if(1 != permSkip) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + permSkip = true; + continue; + } + else + { + return; + } + } + } + } + } + removeAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::slotUpdateAlarmView() +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->updateView(); + } + else if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->updateView(); + } + else if(E_Alarm_Pop == m_mode && m_alarmView != Q_NULLPTR) + { + m_alarmView->viewport()->update(); + } +} + +void CAlarmPlugin::slotUpdateAiAlarmView() +{ + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->updateView(); + } + +} + +void CAlarmPlugin::slotUpdateAlarmOperateEnable(const bool &bEnable) +{ + if(!m_bIsEditMode) + { + if (E_Alarm_Window == m_mode) + { + m_alarmForm->setAlarmOperateEnable(bEnable); + + } + else if (E_Alarm_Dock == m_mode) + { + m_alarmWidget->setAlarmOperateEnable(bEnable); + + } + else if (E_Alarm_Pop == m_mode) + { + //< 禁用确认、删除接口, 见E_Alarm_Pop模式接口 + } + } +} + +void CAlarmPlugin::reset() +{ + if(Q_NULLPTR != m_pModel) + { + m_pModel->disconnect(); + delete m_pModel; + } + m_pModel = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmForm) + { + delete m_alarmForm; + } + m_alarmForm = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmWidget) + { + delete m_alarmWidget; + } + m_alarmWidget = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmView) + { + delete m_alarmView; + } + m_alarmView = Q_NULLPTR; + + QLayout * lyt = layout(); + if(Q_NULLPTR != lyt) + { + delete lyt; + } +} + +void CAlarmPlugin::updateAlarmOperatePerm() +{ + m_currentUsrId = -1; + m_currentNodeName = ""; + m_vecRegionId.clear(); + m_vecLocationId.clear(); + + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!") + return; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + + m_currentNodeName = stNodeInfo.strName; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(0 != permMngPtr->CurUser(m_currentUsrId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + LOGERROR("用户ID获取失败!") + return; + } + if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, m_vecRegionId, m_vecLocationId)) + { + LOGERROR("用户不具备告警操作权限!") + return; + } + } +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.h index 1151d2de..f15eccc4 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.h @@ -1,165 +1,165 @@ -#ifndef CALARMPLUGIN_H -#define CALARMPLUGIN_H - -#include -#include "CAlarmMsgInfo.h" -#include "CAlarmItemModel.h" -#include "CAlarmMediaPlayer.h" - -class CAlarmView; -class CAlarmForm; -class CAlarmWidget; -class CAlarmItemModel; - -class CAlarmPlugin : public QWidget -{ - Q_OBJECT -public: - CAlarmPlugin(QWidget *parent, bool editMode = false); - ~CAlarmPlugin(); -public slots: - void initialize(int mode); - - void login(); - - void logout(); - - void switchFaultRecallState(bool bFaultRecallState); - - /** - * @brief confirmAlarm 告警停闪 - * @param key_id_tag 测点名 - * @return [0: 发送成功] [-1:未找到] [1: 不具备权限] - */ - int confirmAlarm(const QString &key_id_tag); - - int confirmAlarm(const QList &msgs); - - int removeAlarm(const QList &msgs); - - /** - * @brief setAudioVolumeEnable 音量使能 - */ - void setVolumeEnable(bool bEnable); - - /** - * @brief recvAlarmNumChanged 告警数量变化 - */ - void recvAlarmNumChanged(const int &total, const int &unConfirm); - - /** - * @brief setColumnWidth 设置列宽 - * @param column - * @param width - */ - void setColumnWidth(const int &column, const int &width); - - //< alignFlag: 1-AlignLeft; 2-AlignRight; other-AlignHCenter - void setColumnAlign(const int &column, const int &alignFlag); - - /****************以下接口仅针对E_Alarm_Dock模式[底部告警栏]有效********************/ - - void confirmFirstAlarm(int index= 0); - - void setDockRowHeight(const int &height); - - void setDockColumnVisible(const int &column, const bool &visbile = true); - - /***************************************************************************/ - - //添加查询设备告警数量和设备组告警数量的接口 - - QStringList getDevAlmInfo(const QString device); - - /** - * @brief getDevGroupPriorityDevNum 获取设备组下每个告警等级的设备数量 - * @param deviceGroup 设备组 - * @return 返回字符串 ex:deviceGroup1_23,deviceGroup2_22,deviceGroup3_0, [deviceGroup:设备组标签] - */ - QStringList getDevGroupAlmInfo(const QString deviceGroup); - /** - * @brief getLocAlmInfo 获取车站告警数量(优先级分组) - * @return - */ - QStringList getLocAlmInfo(); - /****************以下接口仅针对E_Alarm_Pop模式[设备对话框]有效********************/ - - void setDevice(const QString &device); - void setDeviceGroup(const QString &deviceGroup); - void setPointTag(const QString &pointList); - void setColumnVisible(const int &column, const bool &visible); - - int currentSelectCount(); - - void confirmCurrentAlarm(); - - void confirmAllAlarm(); - - void removeAllAlarm(); - - /***************************************************************************/ - -signals: - - /** - * @brief alarmNumChanged 告警数量变化 - */ - void alarmNumChanged(const int &total, const int &unConfirm); //脚本更新数量 - - /** - * @brief alarmPush 告警推图 - */ - void alarmPush(const QString &info); - - void alarmExit(bool * pExit); - - void sigSwitchFaultRecallState(bool bFaultRecallState); - - /** - * @brief alarmDockDoubleClicked 告警窗[Dock] 双击信号 - */ - void alarmDockDoubleClicked(); - - /** - * @brief closeBtnClicked 告警窗[Window] 关闭按钮点击信号 - */ - void closeBtnClicked(); - - void openVideoDialog(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); - -private slots: - - /** - * @brief slotUpdateAlarmView 更新视图 - */ - void slotUpdateAlarmView(); - void slotUpdateAiAlarmView(); - - /** - * @brief slotUpdateAlarmOperateEnable 更新界面告警操作接口 - * @param bEnable - */ - void slotUpdateAlarmOperateEnable(const bool &bEnable); - -private: - void reset(); - - void updateAlarmOperatePerm(); - -private: - E_Alarm_Mode m_mode; - bool m_bIsEditMode; - CAlarmForm * m_alarmForm; - CAlarmWidget * m_alarmWidget; - CAlarmView * m_alarmView; - CAlarmItemModel * m_pModel; - - int m_currentUsrId; - std::string m_currentNodeName; - std::vector m_vecRegionId; - std::vector m_vecLocationId; - //static int m_number; - static QThread * m_pDataCollectThread; -}; - -#endif // CALARMPLUGIN_H +#ifndef CALARMPLUGIN_H +#define CALARMPLUGIN_H + +#include +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "CAlarmMediaPlayer.h" + +class CAlarmView; +class CAlarmForm; +class CAlarmWidget; +class CAlarmItemModel; + +class CAlarmPlugin : public QWidget +{ + Q_OBJECT +public: + CAlarmPlugin(QWidget *parent, bool editMode = false); + ~CAlarmPlugin(); +public slots: + void initialize(int mode); + + void login(); + + void logout(); + + void switchFaultRecallState(bool bFaultRecallState); + + /** + * @brief confirmAlarm 告警停闪 + * @param key_id_tag 测点名 + * @return [0: 发送成功] [-1:未找到] [1: 不具备权限] + */ + int confirmAlarm(const QString &key_id_tag); + + int confirmAlarm(const QList &msgs); + + int removeAlarm(const QList &msgs); + + /** + * @brief setAudioVolumeEnable 音量使能 + */ + void setVolumeEnable(bool bEnable); + + /** + * @brief recvAlarmNumChanged 告警数量变化 + */ + void recvAlarmNumChanged(const int &total, const int &unConfirm); + + /** + * @brief setColumnWidth 设置列宽 + * @param column + * @param width + */ + void setColumnWidth(const int &column, const int &width); + + //< alignFlag: 1-AlignLeft; 2-AlignRight; other-AlignHCenter + void setColumnAlign(const int &column, const int &alignFlag); + + /****************以下接口仅针对E_Alarm_Dock模式[底部告警栏]有效********************/ + + void confirmFirstAlarm(int index= 0); + + void setDockRowHeight(const int &height); + + void setDockColumnVisible(const int &column, const bool &visbile = true); + + /***************************************************************************/ + + //添加查询设备告警数量和设备组告警数量的接口 + + QStringList getDevAlmInfo(const QString device); + + /** + * @brief getDevGroupPriorityDevNum 获取设备组下每个告警等级的设备数量 + * @param deviceGroup 设备组 + * @return 返回字符串 ex:deviceGroup1_23,deviceGroup2_22,deviceGroup3_0, [deviceGroup:设备组标签] + */ + QStringList getDevGroupAlmInfo(const QString deviceGroup); + /** + * @brief getLocAlmInfo 获取车站告警数量(优先级分组) + * @return + */ + QStringList getLocAlmInfo(); + /****************以下接口仅针对E_Alarm_Pop模式[设备对话框]有效********************/ + + void setDevice(const QString &device); + void setDeviceGroup(const QString &deviceGroup); + void setPointTag(const QString &pointList); + void setColumnVisible(const int &column, const bool &visible); + + int currentSelectCount(); + + void confirmCurrentAlarm(); + + void confirmAllAlarm(); + + void removeAllAlarm(); + + /***************************************************************************/ + +signals: + + /** + * @brief alarmNumChanged 告警数量变化 + */ + void alarmNumChanged(const int &total, const int &unConfirm); //脚本更新数量 + + /** + * @brief alarmPush 告警推图 + */ + void alarmPush(const QString &info); + + void alarmExit(bool * pExit); + + void sigSwitchFaultRecallState(bool bFaultRecallState); + + /** + * @brief alarmDockDoubleClicked 告警窗[Dock] 双击信号 + */ + void alarmDockDoubleClicked(); + + /** + * @brief closeBtnClicked 告警窗[Window] 关闭按钮点击信号 + */ + void closeBtnClicked(); + + void openVideoDialog(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + +private slots: + + /** + * @brief slotUpdateAlarmView 更新视图 + */ + void slotUpdateAlarmView(); + void slotUpdateAiAlarmView(); + + /** + * @brief slotUpdateAlarmOperateEnable 更新界面告警操作接口 + * @param bEnable + */ + void slotUpdateAlarmOperateEnable(const bool &bEnable); + +private: + void reset(); + + void updateAlarmOperatePerm(); + +private: + E_Alarm_Mode m_mode; + bool m_bIsEditMode; + CAlarmForm * m_alarmForm; + CAlarmWidget * m_alarmWidget; + CAlarmView * m_alarmView; + CAlarmItemModel * m_pModel; + + int m_currentUsrId; + std::string m_currentNodeName; + std::vector m_vecRegionId; + std::vector m_vecLocationId; + //static int m_number; + static QThread * m_pDataCollectThread; +}; + +#endif // CALARMPLUGIN_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.cpp index 481755c9..5337d7e3 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.cpp @@ -1,29 +1,29 @@ -#include -#include "CAlarmPluginWidget.h" -#include "CAlarmPlugin.h" -#include "pub_logger_api/logger.h" - -CAlarmPluginWidget::CAlarmPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CAlarmPluginWidget::~CAlarmPluginWidget() -{ - -} - -bool CAlarmPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CAlarmPlugin *pWidget = new CAlarmPlugin(parent, editMode); - pWidget->initialize((int)E_Alarm_Dock); - *widget = (QWidget *)pWidget; - *alarmWidget = (IPluginWidget *)pWidget; - return true; -} - -void CAlarmPluginWidget::release() -{ - -} +#include +#include "CAlarmPluginWidget.h" +#include "CAlarmPlugin.h" +#include "pub_logger_api/logger.h" + +CAlarmPluginWidget::CAlarmPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CAlarmPluginWidget::~CAlarmPluginWidget() +{ + +} + +bool CAlarmPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CAlarmPlugin *pWidget = new CAlarmPlugin(parent, editMode); + pWidget->initialize((int)E_Alarm_Dock); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + return true; +} + +void CAlarmPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.h index e68fdfa9..5c706ea9 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CALARMPLUGINWIDGET_H -#define CALARMPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CAlarmPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CAlarmPluginWidget(QObject *parent = 0); - ~CAlarmPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); - void release(); -}; - -#endif //CALARMPLUGINWIDGET_H - +#ifndef CALARMPLUGINWIDGET_H +#define CALARMPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CAlarmPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CAlarmPluginWidget(QObject *parent = 0); + ~CAlarmPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif //CALARMPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmView.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmView.cpp index e93eb122..d24f5892 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmView.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmView.cpp @@ -1,27 +1,27 @@ -#include -#include -#include "CAlarmView.h" -#include - -CAlarmView::CAlarmView(QWidget *parent) - : QTableView(parent) -{ - -} - -void CAlarmView::initialize() -{ - setSortingEnabled(true); - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::MultiSelection); - setHorizontalScrollMode(ScrollPerPixel); -} - -void CAlarmView::mouseDoubleClickEvent(QMouseEvent *event) -{ - emit alarmViewDoubleClicked(); - QTableView::mouseDoubleClickEvent(event); -} +#include +#include +#include "CAlarmView.h" +#include + +CAlarmView::CAlarmView(QWidget *parent) + : QTableView(parent) +{ + +} + +void CAlarmView::initialize() +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::MultiSelection); + setHorizontalScrollMode(ScrollPerPixel); +} + +void CAlarmView::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit alarmViewDoubleClicked(); + QTableView::mouseDoubleClickEvent(event); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmView.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmView.h index 92534311..468ae17d 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmView.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmView.h @@ -1,22 +1,22 @@ -#ifndef CALARMVIEW_H -#define CALARMVIEW_H - -#include - -class CAlarmView : public QTableView -{ - Q_OBJECT -public: - CAlarmView(QWidget *parent = Q_NULLPTR); - - void initialize(); - -signals: - void alarmViewDoubleClicked(); - -protected: - void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - -}; - -#endif // ALARMVIEW_H +#ifndef CALARMVIEW_H +#define CALARMVIEW_H + +#include + +class CAlarmView : public QTableView +{ + Q_OBJECT +public: + CAlarmView(QWidget *parent = Q_NULLPTR); + + void initialize(); + +signals: + void alarmViewDoubleClicked(); + +protected: + void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +}; + +#endif // ALARMVIEW_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmWidget.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmWidget.cpp index 0575e330..0da30a4f 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmWidget.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmWidget.cpp @@ -1,381 +1,381 @@ -#include "CAlarmWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include "CAlarmForm.h" -#include "CAlarmView.h" -#include "CAlarmMsgInfo.h" -#include "CAlarmItemModel.h" -#include "CAlarmDataCollect.h" -#include "CAlarmDelegate.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include -#include -#include "pub_logger_api/logger.h" - -CAlarmWidget::CAlarmWidget(QWidget *parent) - : QWidget(parent), - m_pView(Q_NULLPTR), - m_pModel(Q_NULLPTR), - m_delegate(Q_NULLPTR), - m_pConfirmButtonRow0(Q_NULLPTR), - m_pConfirmButtonRow1(Q_NULLPTR), - m_pConfirmButtonRow2(Q_NULLPTR) -{ - //initialize(); -} - -CAlarmWidget::~CAlarmWidget() -{ - if(Q_NULLPTR != m_delegate) - { - delete m_delegate; - } - m_delegate = Q_NULLPTR; - qDebug() << "~CAlarmWidget()"; -} - -void CAlarmWidget::setAlarmModel(CAlarmItemModel *pModel) -{ - if(!pModel) - { - return; - } - m_pModel = pModel; - m_pView->setModel(m_pModel); - - if(!m_delegate) - { - m_delegate = new CAlarmDelegate(m_pModel, this); - m_pView->setItemDelegate(m_delegate); - } - - connect(m_pConfirmButtonRow0, SIGNAL(clicked()), this, SLOT(slotConfirmRow0())); - connect(m_pConfirmButtonRow1, SIGNAL(clicked()), this, SLOT(slotConfirmRow1())); - connect(m_pConfirmButtonRow2, SIGNAL(clicked()), this, SLOT(slotConfirmRow2())); - - - m_pView->setColumnHidden(0, false); - m_pView->setColumnHidden(1, false); - m_pView->setColumnHidden(2, false); - m_pView->setColumnHidden(3, true); - m_pView->setColumnHidden(4, true); - m_pView->setColumnHidden(5, false); - m_pView->setColumnHidden(6, false); - m_pView->setColumnHidden(7, false); - - - m_pView->setColumnWidth(0, 230); - m_pView->setColumnWidth(1, 120); - m_pView->setColumnWidth(2, 150); - m_pView->setColumnWidth(5, 150); - m_pView->setColumnWidth(6, 120); - - updateRowHeight(); -} - -void CAlarmWidget::setRowHeight(const int &height) -{ - if(m_pView) - { - m_pView->setRowHeight(0, height); - m_pView->setRowHeight(1, height); - m_pView->setRowHeight(2, height); - updateRowHeight(); - } -} - -void CAlarmWidget::setDockColumnVisible(const int &column, const bool &visbile) -{ - if(m_pView) - { - m_pView->setColumnHidden(column, !visbile); - } -} - -void CAlarmWidget::updateRowHeight() -{ - int nHeight = m_pView->rowHeight(0); - m_pConfirmButtonRow0->setMinimumHeight(nHeight); - m_pConfirmButtonRow1->setMinimumHeight(nHeight); - m_pConfirmButtonRow2->setMinimumHeight(nHeight); - setFixedHeight(nHeight * 3 + 1); -} - -void CAlarmWidget::updateView() -{ - if(m_pView != Q_NULLPTR) - { - m_pView->setShowGrid(m_pModel->getShowAlarmCount()); - m_pModel->updateAlternate(); - m_pView->viewport()->update(); - } -} - -void CAlarmWidget::setAlarmOperateEnable(const bool &bEnable) -{ - m_pConfirmButtonRow0->setEnabled(bEnable); - m_pConfirmButtonRow1->setEnabled(bEnable); - m_pConfirmButtonRow2->setEnabled(bEnable); -} - -void CAlarmWidget::setColumnWidth(const int &column, const int &width) -{ - if(m_pView != Q_NULLPTR) - { - m_pView->setColumnWidth(column, width); - } -} - -void CAlarmWidget::initialize() -{ - QHBoxLayout * pLayout = new QHBoxLayout(this); - pLayout->setMargin(0); - setLayout(pLayout); - - m_pView = new CAlarmView(this); - m_pView->setAlternatingRowColors(true); - m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_pView->setSelectionMode(QAbstractItemView::NoSelection); - m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_pView->horizontalHeader()->setStretchLastSection(true); - m_pView->horizontalHeader()->setVisible(false); - - m_pView->verticalHeader()->setVisible(false); - m_pView->setColumnWidth(0, 150); - pLayout->addWidget(m_pView); - QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); - m_pConfirmButtonRow0 = new QPushButton(tr("确认")); - m_pConfirmButtonRow1 = new QPushButton(tr("确认")); - m_pConfirmButtonRow2 = new QPushButton(tr("确认")); - int nHeight = 23; - m_pConfirmButtonRow0->setMinimumHeight(nHeight); - m_pConfirmButtonRow1->setMinimumHeight(nHeight); - m_pConfirmButtonRow2->setMinimumHeight(nHeight); - setMinimumHeight(nHeight * 3); - - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); - - pConfirmBtnLayout->addStretch(); - pLayout->addLayout(pConfirmBtnLayout); - layout()->setSpacing(0); - - updateAlarmOperatePerm(); - - m_pConfirmButtonRow0->setVisible(false); - m_pConfirmButtonRow1->setVisible(false); - m_pConfirmButtonRow2->setVisible(false); - connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); -} - -void CAlarmWidget::initializeEdit() -{ - QHBoxLayout * pLayout = new QHBoxLayout(this); - pLayout->setMargin(0); - setLayout(pLayout); - //m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") << tr("确认状态") << tr("告警内容"); - QStandardItemModel *model = new QStandardItemModel(); - model->setItem(0,0,new QStandardItem("2020-01-01 12:59:59.999")); - model->setItem(0,1,new QStandardItem("高")); - model->setItem(0,2,new QStandardItem("XX位置")); - model->setItem(0,3,new QStandardItem("-")); - model->setItem(0,4,new QStandardItem("系统信息")); - model->setItem(0,5,new QStandardItem("通道异常")); - model->setItem(0,6,new QStandardItem("未确认")); - model->setItem(0,7,new QStandardItem("通道:chanX,通道状态:通讯中断!")); - model->item(0,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,1)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,2)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,3)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,4)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,5)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,6)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - model->item(0,7)->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); - m_pView = new CAlarmView(this); - m_pView->setAlternatingRowColors(true); - m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_pView->setSelectionMode(QAbstractItemView::NoSelection); - m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_pView->horizontalHeader()->setStretchLastSection(true); - m_pView->horizontalHeader()->setVisible(false); - m_pView->verticalHeader()->setVisible(false); - - //m_pView->setColumnWidth(0, 150); - pLayout->addWidget(m_pView); - QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); - m_pConfirmButtonRow0 = new QPushButton(tr("确认")); - m_pConfirmButtonRow1 = new QPushButton(tr("确认")); - m_pConfirmButtonRow2 = new QPushButton(tr("确认")); - int nHeight = 23; - m_pConfirmButtonRow0->setMinimumHeight(nHeight); - m_pConfirmButtonRow1->setMinimumHeight(nHeight); - m_pConfirmButtonRow2->setMinimumHeight(nHeight); - setMinimumHeight(nHeight * 3); - - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); - pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); - - pConfirmBtnLayout->addStretch(); - pLayout->addLayout(pConfirmBtnLayout); - layout()->setSpacing(0); - - updateAlarmOperatePerm(); - - m_pConfirmButtonRow0->setVisible(false); - m_pConfirmButtonRow1->setVisible(false); - m_pConfirmButtonRow2->setVisible(false); - - - m_pView->setModel(model); - m_pView->setColumnHidden(0, false); - m_pView->setColumnHidden(1, false); - m_pView->setColumnHidden(2, false); - m_pView->setColumnHidden(3, true); - m_pView->setColumnHidden(4, true); - m_pView->setColumnHidden(5, false); - m_pView->setColumnHidden(6, false); - m_pView->setColumnHidden(7, false); - - - m_pView->setColumnWidth(0, 230); - m_pView->setColumnWidth(1, 120); - m_pView->setColumnWidth(2, 150); - m_pView->setColumnWidth(5, 150); - m_pView->setColumnWidth(6, 120); - - m_pView->setRowHeight(0,50); - - //connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); -} - -void CAlarmWidget::closeEvent(QCloseEvent *event) -{ - Q_UNUSED(event) - if(Q_NULLPTR != m_pConfirmButtonRow0) - { - delete m_pConfirmButtonRow0; - m_pConfirmButtonRow0 = Q_NULLPTR; - } - if(Q_NULLPTR != m_pConfirmButtonRow1) - { - delete m_pConfirmButtonRow1; - m_pConfirmButtonRow1 = Q_NULLPTR; - } - if(Q_NULLPTR != m_pConfirmButtonRow2) - { - delete m_pConfirmButtonRow2; - m_pConfirmButtonRow2 = Q_NULLPTR; - } - QWidget::closeEvent(event); -} - -void CAlarmWidget::confirmAlarm(const int &row) -{ - //构建告警确认package - if(row >= m_pModel->getListShowAlarmInfo().count()) - { - return; - } - AlarmMsgPtr info = m_pModel->getListShowAlarmInfo().at(row); - - updateAlarmOperatePerm(); - if(!m_listLocationId.contains(info->location_id)) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警所在位置的操作权限!")); - msgBox.exec(); - return; - } - if(!m_listRegionId.contains(info->region_id) && info->region_id != -1) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备该告警所在责任区的操作权限!")); - msgBox.exec(); - return; - } - - kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); - pkg->set_node_name(m_nodeName); - pkg->set_user_id(m_userId); - pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); - pkg->set_domain_id(info->domain_id); - pkg->set_app_id(info->app_id); - pkg->set_alm_type(info->alm_type); - pkg->add_key_id_tag(info->key_id_tag.toStdString()); - pkg->add_time_stamp(info->time_stamp); - pkg->add_uuid_base64(info->uuid_base64.toStdString()); - //请求确认 - CAlarmDataCollect::instance()->requestCfmAlm(*pkg); - - delete pkg; -} - -bool CAlarmWidget::updateAlarmOperatePerm() -{ - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return false; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - m_nodeName = stNodeInfo.strName; - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(0 != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - m_userId = -1; - LOGERROR("用户ID获取失败!"); - return false; - } - std::vector vecRegionId; - std::vector vecLocationId; - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionId, vecLocationId)) - { - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - m_listRegionId.append(*region++); - } - - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - m_listLocationId.append(*location++); - } - } - return true; - } - return false; -} - -void CAlarmWidget::slotConfirmRow0() -{ - confirmAlarm(0); -} - -void CAlarmWidget::slotConfirmRow1() -{ - confirmAlarm(1); -} - -void CAlarmWidget::slotConfirmRow2() -{ - confirmAlarm(2); -} +#include "CAlarmWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmForm.h" +#include "CAlarmView.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "CAlarmDataCollect.h" +#include "CAlarmDelegate.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include +#include "pub_logger_api/logger.h" + +CAlarmWidget::CAlarmWidget(QWidget *parent) + : QWidget(parent), + m_pView(Q_NULLPTR), + m_pModel(Q_NULLPTR), + m_delegate(Q_NULLPTR), + m_pConfirmButtonRow0(Q_NULLPTR), + m_pConfirmButtonRow1(Q_NULLPTR), + m_pConfirmButtonRow2(Q_NULLPTR) +{ + //initialize(); +} + +CAlarmWidget::~CAlarmWidget() +{ + if(Q_NULLPTR != m_delegate) + { + delete m_delegate; + } + m_delegate = Q_NULLPTR; + qDebug() << "~CAlarmWidget()"; +} + +void CAlarmWidget::setAlarmModel(CAlarmItemModel *pModel) +{ + if(!pModel) + { + return; + } + m_pModel = pModel; + m_pView->setModel(m_pModel); + + if(!m_delegate) + { + m_delegate = new CAlarmDelegate(m_pModel, this); + m_pView->setItemDelegate(m_delegate); + } + + connect(m_pConfirmButtonRow0, SIGNAL(clicked()), this, SLOT(slotConfirmRow0())); + connect(m_pConfirmButtonRow1, SIGNAL(clicked()), this, SLOT(slotConfirmRow1())); + connect(m_pConfirmButtonRow2, SIGNAL(clicked()), this, SLOT(slotConfirmRow2())); + + + m_pView->setColumnHidden(0, false); + m_pView->setColumnHidden(1, false); + m_pView->setColumnHidden(2, false); + m_pView->setColumnHidden(3, true); + m_pView->setColumnHidden(4, true); + m_pView->setColumnHidden(5, false); + m_pView->setColumnHidden(6, false); + m_pView->setColumnHidden(7, false); + + + m_pView->setColumnWidth(0, 230); + m_pView->setColumnWidth(1, 120); + m_pView->setColumnWidth(2, 150); + m_pView->setColumnWidth(5, 150); + m_pView->setColumnWidth(6, 120); + + updateRowHeight(); +} + +void CAlarmWidget::setRowHeight(const int &height) +{ + if(m_pView) + { + m_pView->setRowHeight(0, height); + m_pView->setRowHeight(1, height); + m_pView->setRowHeight(2, height); + updateRowHeight(); + } +} + +void CAlarmWidget::setDockColumnVisible(const int &column, const bool &visbile) +{ + if(m_pView) + { + m_pView->setColumnHidden(column, !visbile); + } +} + +void CAlarmWidget::updateRowHeight() +{ + int nHeight = m_pView->rowHeight(0); + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setFixedHeight(nHeight * 3 + 1); +} + +void CAlarmWidget::updateView() +{ + if(m_pView != Q_NULLPTR) + { + m_pView->setShowGrid(m_pModel->getShowAlarmCount()); + m_pModel->updateAlternate(); + m_pView->viewport()->update(); + } +} + +void CAlarmWidget::setAlarmOperateEnable(const bool &bEnable) +{ + m_pConfirmButtonRow0->setEnabled(bEnable); + m_pConfirmButtonRow1->setEnabled(bEnable); + m_pConfirmButtonRow2->setEnabled(bEnable); +} + +void CAlarmWidget::setColumnWidth(const int &column, const int &width) +{ + if(m_pView != Q_NULLPTR) + { + m_pView->setColumnWidth(column, width); + } +} + +void CAlarmWidget::initialize() +{ + QHBoxLayout * pLayout = new QHBoxLayout(this); + pLayout->setMargin(0); + setLayout(pLayout); + + m_pView = new CAlarmView(this); + m_pView->setAlternatingRowColors(true); + m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pView->setSelectionMode(QAbstractItemView::NoSelection); + m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_pView->horizontalHeader()->setStretchLastSection(true); + m_pView->horizontalHeader()->setVisible(false); + + m_pView->verticalHeader()->setVisible(false); + m_pView->setColumnWidth(0, 150); + pLayout->addWidget(m_pView); + QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); + m_pConfirmButtonRow0 = new QPushButton(tr("确认")); + m_pConfirmButtonRow1 = new QPushButton(tr("确认")); + m_pConfirmButtonRow2 = new QPushButton(tr("确认")); + int nHeight = 23; + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setMinimumHeight(nHeight * 3); + + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); + + pConfirmBtnLayout->addStretch(); + pLayout->addLayout(pConfirmBtnLayout); + layout()->setSpacing(0); + + updateAlarmOperatePerm(); + + m_pConfirmButtonRow0->setVisible(false); + m_pConfirmButtonRow1->setVisible(false); + m_pConfirmButtonRow2->setVisible(false); + connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); +} + +void CAlarmWidget::initializeEdit() +{ + QHBoxLayout * pLayout = new QHBoxLayout(this); + pLayout->setMargin(0); + setLayout(pLayout); + //m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") << tr("确认状态") << tr("告警内容"); + QStandardItemModel *model = new QStandardItemModel(); + model->setItem(0,0,new QStandardItem("2020-01-01 12:59:59.999")); + model->setItem(0,1,new QStandardItem("高")); + model->setItem(0,2,new QStandardItem("XX位置")); + model->setItem(0,3,new QStandardItem("-")); + model->setItem(0,4,new QStandardItem("系统信息")); + model->setItem(0,5,new QStandardItem("通道异常")); + model->setItem(0,6,new QStandardItem("未确认")); + model->setItem(0,7,new QStandardItem("通道:chanX,通道状态:通讯中断!")); + model->item(0,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,1)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,2)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,3)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,4)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,5)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,6)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,7)->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); + m_pView = new CAlarmView(this); + m_pView->setAlternatingRowColors(true); + m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pView->setSelectionMode(QAbstractItemView::NoSelection); + m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_pView->horizontalHeader()->setStretchLastSection(true); + m_pView->horizontalHeader()->setVisible(false); + m_pView->verticalHeader()->setVisible(false); + + //m_pView->setColumnWidth(0, 150); + pLayout->addWidget(m_pView); + QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); + m_pConfirmButtonRow0 = new QPushButton(tr("确认")); + m_pConfirmButtonRow1 = new QPushButton(tr("确认")); + m_pConfirmButtonRow2 = new QPushButton(tr("确认")); + int nHeight = 23; + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setMinimumHeight(nHeight * 3); + + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); + + pConfirmBtnLayout->addStretch(); + pLayout->addLayout(pConfirmBtnLayout); + layout()->setSpacing(0); + + updateAlarmOperatePerm(); + + m_pConfirmButtonRow0->setVisible(false); + m_pConfirmButtonRow1->setVisible(false); + m_pConfirmButtonRow2->setVisible(false); + + + m_pView->setModel(model); + m_pView->setColumnHidden(0, false); + m_pView->setColumnHidden(1, false); + m_pView->setColumnHidden(2, false); + m_pView->setColumnHidden(3, true); + m_pView->setColumnHidden(4, true); + m_pView->setColumnHidden(5, false); + m_pView->setColumnHidden(6, false); + m_pView->setColumnHidden(7, false); + + + m_pView->setColumnWidth(0, 230); + m_pView->setColumnWidth(1, 120); + m_pView->setColumnWidth(2, 150); + m_pView->setColumnWidth(5, 150); + m_pView->setColumnWidth(6, 120); + + m_pView->setRowHeight(0,50); + + //connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); +} + +void CAlarmWidget::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event) + if(Q_NULLPTR != m_pConfirmButtonRow0) + { + delete m_pConfirmButtonRow0; + m_pConfirmButtonRow0 = Q_NULLPTR; + } + if(Q_NULLPTR != m_pConfirmButtonRow1) + { + delete m_pConfirmButtonRow1; + m_pConfirmButtonRow1 = Q_NULLPTR; + } + if(Q_NULLPTR != m_pConfirmButtonRow2) + { + delete m_pConfirmButtonRow2; + m_pConfirmButtonRow2 = Q_NULLPTR; + } + QWidget::closeEvent(event); +} + +void CAlarmWidget::confirmAlarm(const int &row) +{ + //构建告警确认package + if(row >= m_pModel->getListShowAlarmInfo().count()) + { + return; + } + AlarmMsgPtr info = m_pModel->getListShowAlarmInfo().at(row); + + updateAlarmOperatePerm(); + if(!m_listLocationId.contains(info->location_id)) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警所在位置的操作权限!")); + msgBox.exec(); + return; + } + if(!m_listRegionId.contains(info->region_id) && info->region_id != -1) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警所在责任区的操作权限!")); + msgBox.exec(); + return; + } + + kbd_idlfile::SAlmCltCfmAlm * pkg = new kbd_idlfile::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(info->domain_id); + pkg->set_app_id(info->app_id); + pkg->set_alm_type(info->alm_type); + pkg->add_key_id_tag(info->key_id_tag.toStdString()); + pkg->add_time_stamp(info->time_stamp); + pkg->add_uuid_base64(info->uuid_base64.toStdString()); + //请求确认 + CAlarmDataCollect::instance()->requestCfmAlm(*pkg); + + delete pkg; +} + +bool CAlarmWidget::updateAlarmOperatePerm() +{ + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + m_nodeName = stNodeInfo.strName; + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(0 != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + m_userId = -1; + LOGERROR("用户ID获取失败!"); + return false; + } + std::vector vecRegionId; + std::vector vecLocationId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionId, vecLocationId)) + { + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listRegionId.append(*region++); + } + + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listLocationId.append(*location++); + } + } + return true; + } + return false; +} + +void CAlarmWidget::slotConfirmRow0() +{ + confirmAlarm(0); +} + +void CAlarmWidget::slotConfirmRow1() +{ + confirmAlarm(1); +} + +void CAlarmWidget::slotConfirmRow2() +{ + confirmAlarm(2); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmWidget.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmWidget.h index f6b138af..7edd2f35 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmWidget.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmWidget.h @@ -1,65 +1,65 @@ -#ifndef CALARMWINDOW_H -#define CALARMWINDOW_H - -#include - -class QPushButton; -class QMouseEvent; -class CAlarmView; -class CAlarmDelegate; -class CAlarmItemModel; - -class CAlarmWidget : public QWidget -{ - Q_OBJECT -public: - explicit CAlarmWidget(QWidget *parent = nullptr); - ~CAlarmWidget(); - - void setAlarmModel(CAlarmItemModel * pModel); - - void setRowHeight(const int &height); - - void setDockColumnVisible(const int &column, const bool &visbile); - - void updateRowHeight(); - - void updateView(); - - void setAlarmOperateEnable(const bool &bEnable); - - void setColumnWidth(const int &column, const int &width); - - void confirmAlarm(const int &row); - -signals: - void alarmWidgetDoubleClicked(); - -protected: - void closeEvent(QCloseEvent *event); - - bool updateAlarmOperatePerm(); - -public slots: - void initialize(); - - void initializeEdit(); - void slotConfirmRow0(); - void slotConfirmRow1(); - void slotConfirmRow2(); - - -private: - CAlarmView * m_pView; - CAlarmItemModel * m_pModel; - CAlarmDelegate * m_delegate; - int m_userId; - std::string m_nodeName; - QList m_listRegionId; - QList m_listLocationId; - QPushButton * m_pConfirmButtonRow0; - QPushButton * m_pConfirmButtonRow1; - QPushButton * m_pConfirmButtonRow2; -}; - -#endif // ALARMWINDOW_H +#ifndef CALARMWINDOW_H +#define CALARMWINDOW_H + +#include + +class QPushButton; +class QMouseEvent; +class CAlarmView; +class CAlarmDelegate; +class CAlarmItemModel; + +class CAlarmWidget : public QWidget +{ + Q_OBJECT +public: + explicit CAlarmWidget(QWidget *parent = nullptr); + ~CAlarmWidget(); + + void setAlarmModel(CAlarmItemModel * pModel); + + void setRowHeight(const int &height); + + void setDockColumnVisible(const int &column, const bool &visbile); + + void updateRowHeight(); + + void updateView(); + + void setAlarmOperateEnable(const bool &bEnable); + + void setColumnWidth(const int &column, const int &width); + + void confirmAlarm(const int &row); + +signals: + void alarmWidgetDoubleClicked(); + +protected: + void closeEvent(QCloseEvent *event); + + bool updateAlarmOperatePerm(); + +public slots: + void initialize(); + + void initializeEdit(); + void slotConfirmRow0(); + void slotConfirmRow1(); + void slotConfirmRow2(); + + +private: + CAlarmView * m_pView; + CAlarmItemModel * m_pModel; + CAlarmDelegate * m_delegate; + int m_userId; + std::string m_nodeName; + QList m_listRegionId; + QList m_listLocationId; + QPushButton * m_pConfirmButtonRow0; + QPushButton * m_pConfirmButtonRow1; + QPushButton * m_pConfirmButtonRow2; +}; + +#endif // ALARMWINDOW_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.cpp index 4438ebd7..415eb4bf 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.cpp @@ -1,28 +1,28 @@ -#include "CDisposalPlanDialog.h" -#include "ui_CDisposalPlanDialog.h" -#include "CAiAlarmMsgInfo.h" -#include -CDisposalPlanDialog::CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr, QWidget *parent) : - QDialog(parent), - m_aiptr(aiptr), - ui(new Ui::CDisposalPlanDialog) -{ - ui->setupUi(this); - setWindowTitle(tr("处置预案")); - Qt::WindowFlags flags=Qt::Dialog; - flags |=Qt::WindowCloseButtonHint; - setWindowFlags(flags); - - ui->time->setReadOnly(true); - ui->content->setReadOnly(true); - ui->displan->setReadOnly(true); - - ui->time->setText(QDateTime::fromMSecsSinceEpoch(m_aiptr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); - ui->content->setText(m_aiptr->content); - ui->displan->setText(m_aiptr->disposal_plan); -} - -CDisposalPlanDialog::~CDisposalPlanDialog() -{ - delete ui; -} +#include "CDisposalPlanDialog.h" +#include "ui_CDisposalPlanDialog.h" +#include "CAiAlarmMsgInfo.h" +#include +CDisposalPlanDialog::CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr, QWidget *parent) : + QDialog(parent), + m_aiptr(aiptr), + ui(new Ui::CDisposalPlanDialog) +{ + ui->setupUi(this); + setWindowTitle(tr("处置预案")); + Qt::WindowFlags flags=Qt::Dialog; + flags |=Qt::WindowCloseButtonHint; + setWindowFlags(flags); + + ui->time->setReadOnly(true); + ui->content->setReadOnly(true); + ui->displan->setReadOnly(true); + + ui->time->setText(QDateTime::fromMSecsSinceEpoch(m_aiptr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); + ui->content->setText(m_aiptr->content); + ui->displan->setText(m_aiptr->disposal_plan); +} + +CDisposalPlanDialog::~CDisposalPlanDialog() +{ + delete ui; +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.h b/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.h index 802ea751..3dccca2c 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.h @@ -1,23 +1,23 @@ -#ifndef CDISPOSALPLANDIALOG_H -#define CDISPOSALPLANDIALOG_H - -#include -#include "CAlarmCommon.h" -namespace Ui { -class CDisposalPlanDialog; -} - -class CDisposalPlanDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr,QWidget *parent = 0); - ~CDisposalPlanDialog(); - -private: - Ui::CDisposalPlanDialog *ui; - AiAlarmMsgPtr m_aiptr; -}; - -#endif // CDISPOSALPLANDIALOG_H +#ifndef CDISPOSALPLANDIALOG_H +#define CDISPOSALPLANDIALOG_H + +#include +#include "CAlarmCommon.h" +namespace Ui { +class CDisposalPlanDialog; +} + +class CDisposalPlanDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr,QWidget *parent = 0); + ~CDisposalPlanDialog(); + +private: + Ui::CDisposalPlanDialog *ui; + AiAlarmMsgPtr m_aiptr; +}; + +#endif // CDISPOSALPLANDIALOG_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.ui b/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.ui index 78722a83..7273d80c 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.ui +++ b/product/src/gui/plugin/ISCSAlarmWidget/CDisposalPlanDialog.ui @@ -1,140 +1,140 @@ - - - CDisposalPlanDialog - - - - 0 - 0 - 391 - 389 - - - - Dialog - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - Qt::Vertical - - - - - - - 告警时间: - - - - - - - - - - - - 0 - 12 - - - - - 16777215 - 12 - - - - 告警内容: - - - - - - 0 - 50 - - - - - - - 0 - 12 - - - - - 16777215 - 12 - - - - 处置预案: - - - - - - 0 - 50 - - - - - - - - - - - - - - - - + + + CDisposalPlanDialog + + + + 0 + 0 + 391 + 389 + + + + Dialog + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Vertical + + + + + + + 告警时间: + + + + + + + + + + + + 0 + 12 + + + + + 16777215 + 12 + + + + 告警内容: + + + + + + 0 + 50 + + + + + + + 0 + 12 + + + + + 16777215 + 12 + + + + 处置预案: + + + + + + 0 + 50 + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.cpp index cfc6822e..9dca56ae 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.cpp @@ -1,57 +1,57 @@ -#include "CMyCalendar.h" -#include "ui_CMyCalendar.h" -#include -#include -#include -CMyCalendar::CMyCalendar(QWidget *parent) : - QWidget(parent), - ui(new Ui::CMyCalendar) -{ - ui->setupUi(this); - connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); - connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); - connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); - m_startTime = QDate::currentDate(); - m_endTime = QDate::currentDate(); - ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); - ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit_2->setReadOnly(true); -} - -CMyCalendar::~CMyCalendar() -{ - delete ui; -} - -void CMyCalendar::keyPressEvent(QKeyEvent *event) -{ - if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) - { - return ; - } - QWidget::keyPressEvent(event); -} - -void CMyCalendar::slot_endTime(QDate date) -{ - ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); - m_endTime = date; - if(m_startTime.isNull() || m_endTime < m_startTime) - { - //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); - return; - } - emit sig_endTimeClick(m_startTime,m_endTime); -} - -void CMyCalendar::slot_startTime(QDate date) -{ - m_startTime = date; - ui->lineEdit->setText(date.toString("yyyy-MM-dd")); -} - -void CMyCalendar::slot_cancle() -{ - emit sig_cancle(); -} +#include "CMyCalendar.h" +#include "ui_CMyCalendar.h" +#include +#include +#include +CMyCalendar::CMyCalendar(QWidget *parent) : + QWidget(parent), + ui(new Ui::CMyCalendar) +{ + ui->setupUi(this); + connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); + connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); + connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); + m_startTime = QDate::currentDate(); + m_endTime = QDate::currentDate(); + ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); + ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit_2->setReadOnly(true); +} + +CMyCalendar::~CMyCalendar() +{ + delete ui; +} + +void CMyCalendar::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) + { + return ; + } + QWidget::keyPressEvent(event); +} + +void CMyCalendar::slot_endTime(QDate date) +{ + ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); + m_endTime = date; + if(m_startTime.isNull() || m_endTime < m_startTime) + { + //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); + return; + } + emit sig_endTimeClick(m_startTime,m_endTime); +} + +void CMyCalendar::slot_startTime(QDate date) +{ + m_startTime = date; + ui->lineEdit->setText(date.toString("yyyy-MM-dd")); +} + +void CMyCalendar::slot_cancle() +{ + emit sig_cancle(); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.h b/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.h index 2b103611..339fb73c 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.h @@ -1,34 +1,34 @@ -#ifndef CMYCALENDAR_H -#define CMYCALENDAR_H - -#include -#include - -namespace Ui { -class CMyCalendar; -} - -class CMyCalendar : public QWidget -{ - Q_OBJECT -signals: - void sig_endTimeClick(QDate startDate,QDate endDate); - void sig_startTimeClick(QDate date); - void sig_cancle(); -public: - explicit CMyCalendar(QWidget *parent = 0); - ~CMyCalendar(); -protected: - virtual void keyPressEvent(QKeyEvent *event); - -public slots: - void slot_endTime(QDate date); - void slot_startTime(QDate date); - void slot_cancle(); -private: - Ui::CMyCalendar *ui; - QDate m_startTime; - QDate m_endTime; -}; - -#endif // CMYCALENDAR_H +#ifndef CMYCALENDAR_H +#define CMYCALENDAR_H + +#include +#include + +namespace Ui { +class CMyCalendar; +} + +class CMyCalendar : public QWidget +{ + Q_OBJECT +signals: + void sig_endTimeClick(QDate startDate,QDate endDate); + void sig_startTimeClick(QDate date); + void sig_cancle(); +public: + explicit CMyCalendar(QWidget *parent = 0); + ~CMyCalendar(); +protected: + virtual void keyPressEvent(QKeyEvent *event); + +public slots: + void slot_endTime(QDate date); + void slot_startTime(QDate date); + void slot_cancle(); +private: + Ui::CMyCalendar *ui; + QDate m_startTime; + QDate m_endTime; +}; + +#endif // CMYCALENDAR_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.ui b/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.ui index 8df14ac2..9610c481 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.ui +++ b/product/src/gui/plugin/ISCSAlarmWidget/CMyCalendar.ui @@ -1,140 +1,140 @@ - - - CMyCalendar - - - - 0 - 0 - 538 - 270 - - - - Form - - - 1.000000000000000 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - 0 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - 0 - - - - - - - - - 20 - 0 - - - - - 20 - 16777215 - - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - false - - - 0 - - - - - - Qt::AlignCenter - - - - - - - - - - 取消 - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - + + + CMyCalendar + + + + 0 + 0 + 538 + 270 + + + + Form + + + 1.000000000000000 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + + + + + + + + + 20 + 0 + + + + + 20 + 16777215 + + + + Qt::NoContextMenu + + + Qt::LeftToRight + + + false + + + 0 + + + + + + Qt::AlignCenter + + + + + + + + + + 取消 + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CMyCheckBox.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CMyCheckBox.cpp index 9bc0eddb..b2bc5d95 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CMyCheckBox.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CMyCheckBox.cpp @@ -1,21 +1,21 @@ -#include "CMyCheckBox.h" -#include - -CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) - :QCheckBox(text,parent) -{ - -} - -CMyCheckBox::CMyCheckBox(QWidget *parent) - :QCheckBox(parent) -{ - -} - -void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) -{ - setChecked(!isChecked()); - emit clicked(isChecked()); - -} +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + setChecked(!isChecked()); + emit clicked(isChecked()); + +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CMyCheckBox.h b/product/src/gui/plugin/ISCSAlarmWidget/CMyCheckBox.h index 36947db5..bdba8dbc 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CMyCheckBox.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CMyCheckBox.h @@ -1,16 +1,16 @@ -#ifndef MYCHECKBOX_H -#define MYCHECKBOX_H - -#include - -class CMyCheckBox : public QCheckBox -{ -public: - CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); - CMyCheckBox(QWidget *parent = Q_NULLPTR); - -protected: - void mouseReleaseEvent(QMouseEvent *e); -}; - -#endif // MYCHECKBOX_H +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CMyListWidget.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CMyListWidget.cpp index 3b542202..ded92615 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CMyListWidget.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CMyListWidget.cpp @@ -1,12 +1,12 @@ -#include "CMyListWidget.h" - -CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) -{ - -} - -void CMyListWidget::showEvent(QShowEvent *event) -{ - this->updateGeometries(); - QListWidget::showEvent(event); -} +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CMyListWidget.h b/product/src/gui/plugin/ISCSAlarmWidget/CMyListWidget.h index 9fc4491f..3e92461e 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CMyListWidget.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CMyListWidget.h @@ -1,15 +1,15 @@ -#ifndef CMYLISTWIDGET_H -#define CMYLISTWIDGET_H - -#include - -class CMyListWidget : public QListWidget -{ -public: - explicit CMyListWidget(QWidget *parent = 0); - -protected: - void showEvent(QShowEvent *event); -}; - -#endif // CMYLISTWIDGET_H +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CPdfPrinter.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CPdfPrinter.cpp index 93f54b5a..587c9959 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CPdfPrinter.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CPdfPrinter.cpp @@ -1,217 +1,217 @@ -#include "CPdfPrinter.h" -#include -#include -#include -#include -#include -#include - -CPdfPrinter::CPdfPrinter(QObject *parent) : QObject(parent) -{ - m_print.setPageSize(QPagedPaintDevice::A4); - m_print.setPageOrientation(QPageLayout::Landscape); - m_print.setOutputFormat(QPrinter::PdfFormat); - m_headHeight = 30; -} - -void CPdfPrinter::initialize() -{ - -} - -void CPdfPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) -{ - painter->save(); - const QColor gridColor = static_cast(Qt::black); - painter->setPen(gridColor); - painter->drawLine(p1, p2); - painter->restore(); -} - -void CPdfPrinter::renderHeader(QPainter &painter, const QVector &header) -{ - int columnPosition = 0; - for(int column(0); column < m_columnWidth.size(); column++) - { - if(m_columnHidden.at(column) != true) - { - painter.save(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, m_headHeight); - drawGridLine(&painter, top, bottom); - QRect rect = QRect(columnPosition, 0, m_columnWidth.at(column) , m_headHeight); - painter.drawText(rect, header.at(column), QTextOption(Qt::AlignCenter)); - painter.restore(); - columnPosition += m_columnWidth.at(column); - } - } - columnPosition = m_width; - QPoint top(m_width, 0); - QPoint bottom(m_width, m_headHeight); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(0, 0.5), QPoint(m_width + 0, 0.5)); - drawGridLine(&painter, QPoint(0, 0.5 + m_headHeight), QPoint(m_width + 0, 0.5 + m_headHeight)); -} - -void CPdfPrinter::printerByModel(CAiAlarmTreeModel *treeModel, const QString fileName) -{ - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "智能告警" ); - // 写横向表头 - QXlsx::Format formatheader; - formatheader.setFontBold(true); - formatheader.setFontColor(Qt::black); - - QXlsx::Format formatAi; - formatAi.setFontBold(true); - formatAi.setFontColor(Qt::red); - - QXlsx::Format formatMergedAlm; - formatMergedAlm.setFontBold(false); - formatMergedAlm.setFontColor(Qt::darkGreen); - QXlsx::Format formatAlm; - formatAlm.setFontBold(false); - formatAlm.setFontColor(Qt::darkYellow); - int colcount = treeModel->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString(),formatheader); - } - - // 写内容 - int rowNum = 1; - CAiAlarmTreeItem *item = treeModel->getItem(); - QList itemList = item->getChildItemList(); - for(int index(0);indexisAi()) - { - for(int j(0);jdata(j).toString(); - xlsx.write( rowNum +1, j+1, sText,formatAi ); - } - rowNum++; - QList itemList_ =itemList.at(index)->getChildItemList(); - for(int indexAlm(0);indexAlmdata(i).toString(); - xlsx.write( rowNum +1, i+1, sText,formatMergedAlm ); - } - rowNum++; - } - }else - { - for(int j(0);jdata(j).toString(); - xlsx.write( rowNum +1, j+1, sText,formatAlm ); - } - rowNum++; - } - } - - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - - // 提示导出路径 - emit printResult(sExcelFileName); -} - -void CPdfPrinter::printerAlmByModel(CAlarmItemModel *model, const QString fileName) -{ - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "原始告警" ); - // 写横向表头 - int rowcount=model->rowCount(); - int colcount=model->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - - // 写内容 - for ( int i=0; idata(model->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText); - } - } - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - - // 提示导出路径 - //QMessageBox::information( 0, tr("提示"), tr("导出完成\n文件为:")+sExcelFileName); - emit printResult(sExcelFileName); -} - -void CPdfPrinter::printer(QVector header, QList > data, QString fileName, QVector columnHidden, QVector columnWidth) -{ - qreal marginHorizontal = 20; - qreal marginVertical = 20; - - QRectF pageRect = m_print.pageRect().adjusted(0, 0, -marginHorizontal, -marginVertical); - m_print.setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); - m_print.setOutputFileName(fileName); - m_height = pageRect.height(); - m_width = pageRect.width(); - int length = 0; - for(int nSection(0); nSection < columnWidth.size() - 1; nSection++) - { - length += columnWidth.at(nSection); - } - columnWidth[columnWidth.size() - 1] = m_width -length; - - m_columnHidden = columnHidden; - m_columnWidth = columnWidth; - - int currentPage = 0; - //每页数据个数 - int numOfPage = m_height/m_headHeight-1; - - QPainter painter(&m_print); - for(int index(0);index(Qt::red); - painter.setPen(gridColor); - painter.drawText(rect, data.at(index).at(column), QTextOption(Qt::AlignCenter)); - painter.restore(); - columnPosition += columnWidth.at(column); - } - columnPosition =m_width; - QPoint top(columnPosition, m_headHeight*(index%numOfPage+1)); - QPoint bottom(columnPosition, m_headHeight*(index%numOfPage+2)); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(0, 0.5 + m_headHeight*(index%numOfPage+2)), QPoint(m_width + 0, 0.5 + m_headHeight*(index%numOfPage+2))); - } - for(int index(0);index +#include +#include +#include +#include +#include + +CPdfPrinter::CPdfPrinter(QObject *parent) : QObject(parent) +{ + m_print.setPageSize(QPagedPaintDevice::A4); + m_print.setPageOrientation(QPageLayout::Landscape); + m_print.setOutputFormat(QPrinter::PdfFormat); + m_headHeight = 30; +} + +void CPdfPrinter::initialize() +{ + +} + +void CPdfPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + const QColor gridColor = static_cast(Qt::black); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} + +void CPdfPrinter::renderHeader(QPainter &painter, const QVector &header) +{ + int columnPosition = 0; + for(int column(0); column < m_columnWidth.size(); column++) + { + if(m_columnHidden.at(column) != true) + { + painter.save(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, m_headHeight); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, m_columnWidth.at(column) , m_headHeight); + painter.drawText(rect, header.at(column), QTextOption(Qt::AlignCenter)); + painter.restore(); + columnPosition += m_columnWidth.at(column); + } + } + columnPosition = m_width; + QPoint top(m_width, 0); + QPoint bottom(m_width, m_headHeight); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(0, 0.5), QPoint(m_width + 0, 0.5)); + drawGridLine(&painter, QPoint(0, 0.5 + m_headHeight), QPoint(m_width + 0, 0.5 + m_headHeight)); +} + +void CPdfPrinter::printerByModel(CAiAlarmTreeModel *treeModel, const QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "智能告警" ); + // 写横向表头 + QXlsx::Format formatheader; + formatheader.setFontBold(true); + formatheader.setFontColor(Qt::black); + + QXlsx::Format formatAi; + formatAi.setFontBold(true); + formatAi.setFontColor(Qt::red); + + QXlsx::Format formatMergedAlm; + formatMergedAlm.setFontBold(false); + formatMergedAlm.setFontColor(Qt::darkGreen); + QXlsx::Format formatAlm; + formatAlm.setFontBold(false); + formatAlm.setFontColor(Qt::darkYellow); + int colcount = treeModel->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString(),formatheader); + } + + // 写内容 + int rowNum = 1; + CAiAlarmTreeItem *item = treeModel->getItem(); + QList itemList = item->getChildItemList(); + for(int index(0);indexisAi()) + { + for(int j(0);jdata(j).toString(); + xlsx.write( rowNum +1, j+1, sText,formatAi ); + } + rowNum++; + QList itemList_ =itemList.at(index)->getChildItemList(); + for(int indexAlm(0);indexAlmdata(i).toString(); + xlsx.write( rowNum +1, i+1, sText,formatMergedAlm ); + } + rowNum++; + } + }else + { + for(int j(0);jdata(j).toString(); + xlsx.write( rowNum +1, j+1, sText,formatAlm ); + } + rowNum++; + } + } + + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + + // 提示导出路径 + emit printResult(sExcelFileName); +} + +void CPdfPrinter::printerAlmByModel(CAlarmItemModel *model, const QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "原始告警" ); + // 写横向表头 + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString()); + } + + // 写内容 + for ( int i=0; idata(model->index(i, j)).toString(); + xlsx.write( i+2, j+1, sText); + } + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + + // 提示导出路径 + //QMessageBox::information( 0, tr("提示"), tr("导出完成\n文件为:")+sExcelFileName); + emit printResult(sExcelFileName); +} + +void CPdfPrinter::printer(QVector header, QList > data, QString fileName, QVector columnHidden, QVector columnWidth) +{ + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = m_print.pageRect().adjusted(0, 0, -marginHorizontal, -marginVertical); + m_print.setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + m_print.setOutputFileName(fileName); + m_height = pageRect.height(); + m_width = pageRect.width(); + int length = 0; + for(int nSection(0); nSection < columnWidth.size() - 1; nSection++) + { + length += columnWidth.at(nSection); + } + columnWidth[columnWidth.size() - 1] = m_width -length; + + m_columnHidden = columnHidden; + m_columnWidth = columnWidth; + + int currentPage = 0; + //每页数据个数 + int numOfPage = m_height/m_headHeight-1; + + QPainter painter(&m_print); + for(int index(0);index(Qt::red); + painter.setPen(gridColor); + painter.drawText(rect, data.at(index).at(column), QTextOption(Qt::AlignCenter)); + painter.restore(); + columnPosition += columnWidth.at(column); + } + columnPosition =m_width; + QPoint top(columnPosition, m_headHeight*(index%numOfPage+1)); + QPoint bottom(columnPosition, m_headHeight*(index%numOfPage+2)); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(0, 0.5 + m_headHeight*(index%numOfPage+2)), QPoint(m_width + 0, 0.5 + m_headHeight*(index%numOfPage+2))); + } + for(int index(0);index -#include -#include -#include -#include -#include -#include "model_excel/xlsx/xlsxdocument.h" -#include "model_excel/xlsx/xlsxformat.h" -class QPainter; -class CPdfPrinter : public QObject -{ - Q_OBJECT -public: - explicit CPdfPrinter(QObject *parent = nullptr); - - void initialize(); - - void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); - - void renderHeader(QPainter &painter, const QVector &header); -signals: - void printResult(QString fileName); -public slots: - void printer(QVector header, QList > data, QString fileName, QVector columnHidden, QVector columnWidth); - void printerByModel(CAiAlarmTreeModel *treeModel,const QString fileName); - void printerAlmByModel(CAlarmItemModel *model,const QString fileName); -private: - QString m_fileName; - QPrinter m_print; - QVector m_columnHidden; - QVector m_columnWidth; - int m_headHeight; - int m_height; - int m_width; -}; -#endif // CPDFPRINTER_H +/** +* @file AlarmWidget 之前是做pdf打印,因需求修改,现在改为excel ,但是类名不变,维护请注意 +* @brief +* @author jxd +* @date 2020-01-08 +*/ +#ifndef CPDFPRINTER_H +#define CPDFPRINTER_H + +#include +#include +#include +#include +#include +#include +#include "model_excel/xlsx/xlsxdocument.h" +#include "model_excel/xlsx/xlsxformat.h" +class QPainter; +class CPdfPrinter : public QObject +{ + Q_OBJECT +public: + explicit CPdfPrinter(QObject *parent = nullptr); + + void initialize(); + + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + + void renderHeader(QPainter &painter, const QVector &header); +signals: + void printResult(QString fileName); +public slots: + void printer(QVector header, QList > data, QString fileName, QVector columnHidden, QVector columnWidth); + void printerByModel(CAiAlarmTreeModel *treeModel,const QString fileName); + void printerAlmByModel(CAlarmItemModel *model,const QString fileName); +private: + QString m_fileName; + QPrinter m_print; + QVector m_columnHidden; + QVector m_columnWidth; + int m_headHeight; + int m_height; + int m_width; +}; +#endif // CPDFPRINTER_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CTableViewPrinter.cpp index 5170b555..0163ba9a 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CTableViewPrinter.cpp @@ -1,54 +1,54 @@ -#include "CTableViewPrinter.h" -#include "CAlarmCommon.h" -#include "CAlarmMsgManage.h" -CTableViewPrinter::CTableViewPrinter(CAlarmItemModel *model): - m_pModel(model) -{ - -} - -QVector CTableViewPrinter::getHead() -{ - int columnCount = m_pModel->columnCount(); - QVector header; - for(int index(0);index headerData(index,Qt::Horizontal).toString()); - } - return header; -} - -QList > CTableViewPrinter::getData() -{ - QList > data; - QList list = m_pModel->getListShowAlarmInfo(); - for(int index(0);index content; - //1.时间 - content.append(QDateTime::fromMSecsSinceEpoch(list.at(index)->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); - //2.优先级 - content.append(CAlarmMsgManage::instance()->queryPriorityDesc(list.at(index)->priority)); - //3.位置 - content.append(CAlarmMsgManage::instance()->queryLocationDesc(list.at(index)->location_id)); - //4.责任区 - content.append(CAlarmMsgManage::instance()->queryRegionDesc(list.at(index)->region_id)); - //5.类型 - content.append(CAlarmMsgManage::instance()->queryAlarmTypeDesc(list.at(index)->alm_type)); - //6.状态 - content.append(CAlarmMsgManage::instance()->queryAlarmStatusDesc(list.at(index)->alm_status)); - //7.确认状态 - if(list.at(index)->logic_state == E_ALS_ALARM || list.at(index)->logic_state == E_ALS_RETURN) - { - content.append(QObject::tr("未确认")); - }else - { - content.append(QObject::tr("已确认")); - } - //8.内容 - content.append(list.at(index)->content); - data.append(content); - } - return data; -} - +#include "CTableViewPrinter.h" +#include "CAlarmCommon.h" +#include "CAlarmMsgManage.h" +CTableViewPrinter::CTableViewPrinter(CAlarmItemModel *model): + m_pModel(model) +{ + +} + +QVector CTableViewPrinter::getHead() +{ + int columnCount = m_pModel->columnCount(); + QVector header; + for(int index(0);index headerData(index,Qt::Horizontal).toString()); + } + return header; +} + +QList > CTableViewPrinter::getData() +{ + QList > data; + QList list = m_pModel->getListShowAlarmInfo(); + for(int index(0);index content; + //1.时间 + content.append(QDateTime::fromMSecsSinceEpoch(list.at(index)->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); + //2.优先级 + content.append(CAlarmMsgManage::instance()->queryPriorityDesc(list.at(index)->priority)); + //3.位置 + content.append(CAlarmMsgManage::instance()->queryLocationDesc(list.at(index)->location_id)); + //4.责任区 + content.append(CAlarmMsgManage::instance()->queryRegionDesc(list.at(index)->region_id)); + //5.类型 + content.append(CAlarmMsgManage::instance()->queryAlarmTypeDesc(list.at(index)->alm_type)); + //6.状态 + content.append(CAlarmMsgManage::instance()->queryAlarmStatusDesc(list.at(index)->alm_status)); + //7.确认状态 + if(list.at(index)->logic_state == E_ALS_ALARM || list.at(index)->logic_state == E_ALS_RETURN) + { + content.append(QObject::tr("未确认")); + }else + { + content.append(QObject::tr("已确认")); + } + //8.内容 + content.append(list.at(index)->content); + data.append(content); + } + return data; +} + diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CTableViewPrinter.h b/product/src/gui/plugin/ISCSAlarmWidget/CTableViewPrinter.h index d464b6d8..b911e7a8 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CTableViewPrinter.h @@ -1,15 +1,15 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H -#include "CAlarmItemModel.h" -class QVariant; -class CTableViewPrinter -{ -public: - CTableViewPrinter(CAlarmItemModel *model); - QVector getHead(); - QList > getData(); -private: - CAlarmItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H +#include "CAlarmItemModel.h" +class QVariant; +class CTableViewPrinter +{ +public: + CTableViewPrinter(CAlarmItemModel *model); + QVector getHead(); + QList > getData(); +private: + CAlarmItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CTreeViewPrinter.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CTreeViewPrinter.cpp index fbcbdf1d..673ee6af 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CTreeViewPrinter.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CTreeViewPrinter.cpp @@ -1,42 +1,42 @@ -#include "CTreeViewPrinter.h" -#include "CAiAlarmTreeItem.h" -CTreeViewPrinter::CTreeViewPrinter(CAiAlarmTreeModel *model): - m_pModel(model) -{ - -} - -QVector CTreeViewPrinter::getHead() -{ - int columnCount = m_pModel->columnCount(); - QVector header; - for(int index(0);index headerData(index,Qt::Horizontal).toString()); - } - return header; -} - -QList > CTreeViewPrinter::getData() -{ - QList > data; - CAiAlarmTreeItem *item = ((CAiAlarmTreeModel*)m_pModel)->getItem(); - QList itemList = item->getChildItemList(); - for(int index(0);index content; - content = itemList.at(index)->getContent(); - data.append(content); - if(itemList.at(index)->isAi()) - { - QList itemlist = itemList.at(index)->getChildItemList(); - for(int dex(0);dex almInfo; - almInfo = itemlist.at(dex)->getContent(); - data.append(almInfo); - } - } - } - return data; -} +#include "CTreeViewPrinter.h" +#include "CAiAlarmTreeItem.h" +CTreeViewPrinter::CTreeViewPrinter(CAiAlarmTreeModel *model): + m_pModel(model) +{ + +} + +QVector CTreeViewPrinter::getHead() +{ + int columnCount = m_pModel->columnCount(); + QVector header; + for(int index(0);index headerData(index,Qt::Horizontal).toString()); + } + return header; +} + +QList > CTreeViewPrinter::getData() +{ + QList > data; + CAiAlarmTreeItem *item = ((CAiAlarmTreeModel*)m_pModel)->getItem(); + QList itemList = item->getChildItemList(); + for(int index(0);index content; + content = itemList.at(index)->getContent(); + data.append(content); + if(itemList.at(index)->isAi()) + { + QList itemlist = itemList.at(index)->getChildItemList(); + for(int dex(0);dex almInfo; + almInfo = itemlist.at(dex)->getContent(); + data.append(almInfo); + } + } + } + return data; +} diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CTreeViewPrinter.h b/product/src/gui/plugin/ISCSAlarmWidget/CTreeViewPrinter.h index ff13552a..a28a4498 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CTreeViewPrinter.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CTreeViewPrinter.h @@ -1,15 +1,15 @@ -#ifndef CTREEVIEWPRINTER_H -#define CTREEVIEWPRINTER_H -#include "CAiAlarmTreeModel.h" -class QVariant; -class CTreeViewPrinter -{ -public: - CTreeViewPrinter(CAiAlarmTreeModel *model); - QVector getHead(); - QList > getData(); -private: - CAiAlarmTreeModel * m_pModel; -}; - -#endif // CTREEVIEWPRINTER_H +#ifndef CTREEVIEWPRINTER_H +#define CTREEVIEWPRINTER_H +#include "CAiAlarmTreeModel.h" +class QVariant; +class CTreeViewPrinter +{ +public: + CTreeViewPrinter(CAiAlarmTreeModel *model); + QVector getHead(); + QList > getData(); +private: + CAiAlarmTreeModel * m_pModel; +}; + +#endif // CTREEVIEWPRINTER_H diff --git a/product/src/gui/plugin/ISCSAlarmWidget/main.cpp b/product/src/gui/plugin/ISCSAlarmWidget/main.cpp index 5802d8e3..90f7977e 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/main.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/main.cpp @@ -1,43 +1,43 @@ -#include -#include "CAlarmPlugin.h" -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - //<初始化消息总线 - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("2", "2", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - { - CAlarmPlugin n(NULL, false); - n.initialize(E_Alarm_Window); - - n.show(); - app.exec(); - } - - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} - +#include +#include "CAlarmPlugin.h" +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + //<初始化消息总线 + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("2", "2", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + { + CAlarmPlugin n(NULL, false); + n.initialize(E_Alarm_Window); + + n.show(); + app.exec(); + } + + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} + diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventDataCollect.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventDataCollect.cpp index 994183d8..2f2b3119 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventDataCollect.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventDataCollect.cpp @@ -1,781 +1,781 @@ -#include "CEventDataCollect.h" -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "dbms/db_sysinfo_api/CDbSysInfo.h" -#include "perm_mng_api/PermMngApi.h" -#include "CEventMsgManage.h" - -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" -#include "Common.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CharUtil.h" -using namespace std; -using namespace kbd_public; -CEventDataCollect * CEventDataCollect::m_pInstance = NULL; - -CEventDataCollect * CEventDataCollect::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CEventDataCollect(); - } - return m_pInstance; -} - -CEventDataCollect::CEventDataCollect() - : m_pTimer(NULL) -{ - msgMutex = new QMutex(); - - m_dbHisReadApi = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); - m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); - - m_pTimer = new QTimer(); - m_pTimer->setInterval(1000); - connect(m_pTimer, &QTimer::timeout, this, &CEventDataCollect::slotUpdateEvent); - -} - -CEventDataCollect::~CEventDataCollect() -{ - if(m_pTimer != NULL) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - suspendThread(); - - m_priorityOrderMap.clear(); - m_priorityDescriptionMap.clear(); - m_locationDescriptionMap.clear(); - m_regionInfoDescriptionMap.clear(); - m_alarmTypeDescriptionMap.clear(); - m_deviceTypeDescriptionMap.clear(); - m_subSystemDescriptionMap.clear(); - - delete msgMutex; - delete m_rtdbAccess; - delete m_rtdbPriorityOrderAccess; - m_dbHisReadApi->close(); - delete m_dbHisReadApi; - m_pInstance = NULL; - qDebug() << "~CEventDataCollect()"; -} - -bool CEventDataCollect::initialize() -{ - m_pTimer->start(); - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - kbd_public::SNodeInfo stNodeInfo; - spSysInfo->getLocalNodeInfo(stNodeInfo); - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); - m_nLocationID = stNodeInfo.nLocationId; - } - loadEventConfig(); - return resumeThread(); -} - -void CEventDataCollect::release() -{ - m_pTimer->stop(); - suspendThread(true); - m_priorityOrderMap.clear(); - m_priorityDescriptionMap.clear(); - m_locationDescriptionMap.clear(); - m_regionInfoDescriptionMap.clear(); - m_alarmTypeDescriptionMap.clear(); - m_deviceTypeDescriptionMap.clear(); - m_subSystemDescriptionMap.clear(); - - CEventMsgManage::instance()->clearRTMsg(); -} - -void CEventDataCollect::loadEventConfig() -{ - loadPermInfo(); - priorityDescriptionMap(); - locationDescriptionMap(); - regionInfoDescriptionMap(); - alarmTypeDescriptionMap(); - deviceTypeDescriptionMap(); - alarmStatusMap(); - userNameMap(); -} - -int CEventDataCollect::priorityId(const QString &description) -{ - return m_priorityDescriptionMap.key(description, -1); -} - -int CEventDataCollect::locationId(const QString &description) -{ - return m_locationDescriptionMap.key(description, -1); -} - -int CEventDataCollect::regionId(const QString &description) -{ - return m_regionInfoDescriptionMap.key(description, -1); -} - -int CEventDataCollect::alarmTypeId(const QString &description) -{ - return m_alarmTypeDescriptionMap.key(description, -1); -} - -int CEventDataCollect::eventStatusId(const QString &description) -{ - return m_eventShowStatusMap.key(description, -1); -} - -int CEventDataCollect::deviceTypeId(const QString &description) -{ - return m_deviceTypeDescriptionMap.key(description, -1); -} - -QString CEventDataCollect::priorityDescription(const int &id) -{ - return m_priorityDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::locationDescription(const int &id) -{ - return m_locationDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::regionDescription(const int &id) -{ - return m_regionInfoDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::alarmTypeDescription(const int &id) -{ - return m_alarmTypeDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::deviceTypeDescription(const int &id) -{ - return m_deviceTypeDescriptionMap.value(id, QString()); -} - -QString CEventDataCollect::alarmStatusDescription(const int &id) -{ - return m_alarmStatusMap.value(id, QString()); -} - -QString CEventDataCollect::userNameDescription(const int &id) -{ - return m_userNameMap.value(id, QString()); -} - -QString CEventDataCollect::eventShowStatusDescription(const int &id) -{ - return m_eventShowStatusMap.value(id, QString()); -} - -QList CEventDataCollect::priorityList() -{ - return m_priorityDescriptionMap.keys(); -} - -QList CEventDataCollect::locationList() -{ - return m_listPermLocationId; -} - -QList CEventDataCollect::regionList() -{ - return m_listPermRegionId; -} - -QList CEventDataCollect::alarmTypeList() -{ - return m_alarmTypeDescriptionMap.keys(); -} - -QList CEventDataCollect::alarmStatusList() -{ - return m_eventShowStatusMap.keys(); -} - -QList CEventDataCollect::alarmOtherList() -{ - return m_eventOtherStatusMap.keys(); -} - -void CEventDataCollect::loadPermInfo() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecRegionId; - std::vector vecLocationId; - m_listPermLocationId.clear(); - m_listPermRegionId.clear(); - if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - m_listPermLocationId.append(*location++); - } - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - m_listPermRegionId.append(*region++); - } - } - } -} - -QMap CEventDataCollect::priorityDescriptionMap() -{ - m_priorityDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "alarm_level_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("priority_id"); - columns.push_back("priority_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - return m_priorityDescriptionMap; -} - -QMap CEventDataCollect::locationDescriptionMap() -{ - m_locationDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "sys_model_location_info")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("location_id"); - columns.push_back("description"); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - if(m_listPermLocationId.contains(key.toInt())) - { - m_locationDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - } - return m_locationDescriptionMap; -} - -QMap CEventDataCollect::regionInfoDescriptionMap() -{ - m_regionInfoDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "region_info")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("region_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - if(m_listPermRegionId.contains(key.toInt())) - { - m_regionInfoDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - } - return m_regionInfoDescriptionMap; -} - -QMap CEventDataCollect::alarmTypeDescriptionMap() -{ - m_alarmTypeDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "alarm_type_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("type_id"); - columns.push_back("type_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - return m_alarmTypeDescriptionMap; -} - - -QMap CEventDataCollect::deviceTypeDescriptionMap() -{ - m_deviceTypeDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "dev_type_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("dev_type_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - return m_deviceTypeDescriptionMap; -} - -QMap CEventDataCollect::alarmStatusMap() -{ - m_alarmStatusMap.clear(); - if(m_rtdbAccess->open("base", "alarm_status_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("status_value"); - columns.push_back("display_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmStatusMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - return m_alarmStatusMap; -} - -QMap CEventDataCollect::userNameMap() -{ - m_userNameMap.clear(); - if(m_rtdbAccess->open("base", "rm_user_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("perm_id"); - columns.push_back("perm_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_userNameMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - return m_userNameMap; -} - -QMap CEventDataCollect::eventShowStatusDescriptionMap() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - if(StringToInt(strKey) != OTHERSTATUS) - { - m_eventShowStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; - }else - { - m_eventShowStatusMap[StringToInt(strKey)] = tr("其他"); - } - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } - return m_eventShowStatusMap; -} - -QMap CEventDataCollect::eventOtherStatusDescriptionMap() -{ - m_eventOtherStatusMap.clear(); - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - //string strValue = pParamIter->second.get(".value"); - m_eventOtherStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } - return m_eventOtherStatusMap; -} - -//void CEventDataCollect::queryHistoryEvent(const QStringList &tables,QList typeFilter, const QString &condition) -//{ -// QList listHistoryEvent; -// if(tables.isEmpty()) -// { -// return; -// } -// bool res = m_dbInterface->open(); -// QStringList stDescList; -// stDescList.clear(); -// if(res) -// { -// QString sqlSequenceQuery; -// try -// { -// for(int nTableIndex(0); nTableIndex < tables.size(); nTableIndex++) -// { -// sqlSequenceQuery = QString("select " -// "time_stamp, " -// "priority," -// "location_id," -// "region_id," -// "content," -// "alm_type," -// "alm_status," -// "domain_id," -// "app_id," -// "dev_type," -// "confirm_user_id," -// "confirm_time " -// "from %1").arg(tables.at(nTableIndex)); -// if(!condition.isEmpty()) -// { -// sqlSequenceQuery = QString("%1 where %2").arg(sqlSequenceQuery).arg(condition); -// } - -// sqlSequenceQuery = QString("%1 order by time_stamp desc limit %2;").arg(sqlSequenceQuery).arg(LIMIT_HIS_RECORD); -// QSqlQuery query; -// try -// { -// m_dbInterface->execute(sqlSequenceQuery, query); -// } -// catch(...) -// { -// qDebug() << "Query Error!"; -// } -// if(query.isActive()) -// { -// int count = 0; -// int nIndex = 0; -// while(query.next()) -// { -// EventMsgPtr info(new CEventMsgInfo); -// info->time_stamp = query.value(0).toULongLong(); -// info->priority = query.value(1).toInt(); -// info->location_id = query.value(2).toInt(); -// info->region_id = query.value(3).toInt(); -// info->content = query.value(4).toString(); -// info->alm_type = query.value(5).toInt(); -// info->alm_status = query.value(6).toInt(); -// info->domain_id = query.value(7).toInt(); -// info->app_id = query.value(8).toInt(); -// info->dev_type = query.value(9).toInt(); -// info->cfm_user = query.value(10).toUInt(); -// info->cfm_time = query.value(11).toULongLong(); -// if(nTableIndex) -// { -// bool isInsertSuccess = false; -// while (nIndex < listHistoryEvent.size()) -// { -// if(info->time_stamp >= listHistoryEvent.at(nIndex)->time_stamp) -// { -// listHistoryEvent.insert(nIndex, info); -// isInsertSuccess = true; -// break; -// } -// ++nIndex; -// } -// if(!isInsertSuccess) -// { -// listHistoryEvent.append(info); -// } -// } -// else -// { -// listHistoryEvent.append(info); -// } -// ++count; -// } -// if(count >= LIMIT_HIS_RECORD) -// { -// stDescList.append(m_alarmTypeDescriptionMap.value(typeFilter.at(nTableIndex))); -// } -// } - -// } -// } -// catch(std::exception e) -// { -// qDebug() << "QueryHistoryEvent Exception!"; -// } -// } - -// m_dbInterface->close(); -// emit sigUpdateHistoryEvent(listHistoryEvent, stDescList); -//} - -void CEventDataCollect::slotUpdateEvent() -{ -// loadEventConfig(); - - QMutexLocker locker(msgMutex); - emit sigMsgArrived(m_listEventCache); - m_listEventCache.clear(); -} - -void CEventDataCollect::handleAllEvtMsg(int nDomainID, kbd_idlfile::SEvtCltAddEvt &objAllEvt) -{ - QMutexLocker locker(msgMutex); - CEventMsgManage::instance()->removeEventMsgByDomainID(nDomainID); - for(int nAddMsgIndex(0); nAddMsgIndex < objAllEvt.evt_info_size(); nAddMsgIndex++) - { - kbd_idlfile::SEvtInfoToEvtClt msg = objAllEvt.evt_info(nAddMsgIndex); - EventMsgPtr event(new CEventMsgInfo()); - event->initialize(msg); - event->priorityOrder = queryPriorityOrder(event->priority); - if(!m_listPermLocationId.contains(event->location_id)) - { - continue; - } - if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) - { - continue; - } - CEventMsgManage::instance()->addEventMsg(event); - } - emit sigMsgRefresh(); - emit sigEventStateChanged(); -} - -void CEventDataCollect::handleAddEvtMsg(kbd_idlfile::SEvtCltAddEvt &objAddEvt) -{ - QMutexLocker locker(msgMutex); - for(int nAddMsgIndex(0); nAddMsgIndex < objAddEvt.evt_info_size(); nAddMsgIndex++) - { - kbd_idlfile::SEvtInfoToEvtClt msg = objAddEvt.evt_info(nAddMsgIndex); - EventMsgPtr event(new CEventMsgInfo()); - event->initialize(msg); - event->priorityOrder = queryPriorityOrder(event->priority); - if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) - { - continue; - } - CEventMsgManage::instance()->addEventMsg(event); - m_listEventCache.append(event); - } - emit sigEventStateChanged(); -} - -void CEventDataCollect::handleClearRTEvent() -{ - QMutexLocker locker(msgMutex); - CEventMsgManage::instance()->clearRTMsg(); - emit sigMsgRefresh(); - emit sigEventStateChanged(); -} - -void CEventDataCollect::queryHistoryEvent(const QStringList &tables, const QString &condition) -{ - QList listHistoryEvent; - if(tables.isEmpty()) - { - return; - } - bool res = m_dbHisReadApi->open(); - QStringList stDescList; - stDescList.clear(); - if(res) - { - QString sqlSequenceQuery; - try - { - for(int nTableIndex(0); nTableIndex < tables.size(); nTableIndex++) - { - sqlSequenceQuery = QString("select " - "time_stamp, " - "priority," - "location_id," - "region_id," - "content," - "alm_type," - "alm_status," - "dev_type," - "confirm_user_id," - "confirm_time " - "from %1").arg(tables.at(nTableIndex)); - if(!condition.isEmpty()) - { - sqlSequenceQuery = QString("%1 where %2 ").arg(sqlSequenceQuery).arg(condition); - } - - sqlSequenceQuery = QString("%1 order by time_stamp desc limit %2 ;").arg(sqlSequenceQuery).arg(LIMIT_HIS_RECORD); - LOGINFO("%s",sqlSequenceQuery.toStdString().c_str()); - QSqlQuery query; - try - { - m_dbHisReadApi->execute(sqlSequenceQuery, query); - } - catch(...) - { - qDebug() << "Query Error!"; - } - if(query.isActive()) - { - int count = 0; - int nIndex = 0; - while(query.next()) - { - EventMsgPtr info(new CEventMsgInfo); - info->time_stamp = query.value(0).toULongLong(); - info->priority = query.value(1).toInt(); - info->location_id = query.value(2).toInt(); - info->region_id = query.value(3).toInt(); - info->content = query.value(4).toString(); - info->alm_type = query.value(5).toInt(); - info->alm_status = query.value(6).toInt(); - info->dev_type = query.value(7).toInt(); - info->cfm_user = query.value(8).toUInt(); - info->cfm_time = query.value(9).toULongLong(); - if(nTableIndex) - { - bool isInsertSuccess = false; - while (nIndex < listHistoryEvent.size()) - { - if(info->time_stamp >= listHistoryEvent.at(nIndex)->time_stamp) - { - listHistoryEvent.insert(nIndex, info); - isInsertSuccess = true; - break; - } - ++nIndex; - } - if(!isInsertSuccess) - { - listHistoryEvent.append(info); - } - } - else - { - listHistoryEvent.append(info); - } - ++count; - } - if(count >= LIMIT_HIS_RECORD) - { - //stDescList.append(m_alarmTypeDescriptionMap.value(nTableIndex)); - } - } - - } - } - catch(std::exception e) - { - qDebug() << "QueryHistoryEvent Exception!"; - } - } - - m_dbHisReadApi->close(); - emit sigUpdateHistoryEvent(listHistoryEvent, stDescList); -} - -int CEventDataCollect::queryPriorityOrder(int &id) -{ - kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); - kbd_dbms::CVarType value; - m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); - return value.toInt(); -} +#include "CEventDataCollect.h" +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "dbms/db_sysinfo_api/CDbSysInfo.h" +#include "perm_mng_api/PermMngApi.h" +#include "CEventMsgManage.h" + +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +using namespace std; +using namespace kbd_public; +CEventDataCollect * CEventDataCollect::m_pInstance = NULL; + +CEventDataCollect * CEventDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CEventDataCollect(); + } + return m_pInstance; +} + +CEventDataCollect::CEventDataCollect() + : m_pTimer(NULL) +{ + msgMutex = new QMutex(); + + m_dbHisReadApi = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + m_rtdbPriorityOrderAccess = new kbd_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); + + m_pTimer = new QTimer(); + m_pTimer->setInterval(1000); + connect(m_pTimer, &QTimer::timeout, this, &CEventDataCollect::slotUpdateEvent); + +} + +CEventDataCollect::~CEventDataCollect() +{ + if(m_pTimer != NULL) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + suspendThread(); + + m_priorityOrderMap.clear(); + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionInfoDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + m_deviceTypeDescriptionMap.clear(); + m_subSystemDescriptionMap.clear(); + + delete msgMutex; + delete m_rtdbAccess; + delete m_rtdbPriorityOrderAccess; + m_dbHisReadApi->close(); + delete m_dbHisReadApi; + m_pInstance = NULL; + qDebug() << "~CEventDataCollect()"; +} + +bool CEventDataCollect::initialize() +{ + m_pTimer->start(); + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + kbd_public::SNodeInfo stNodeInfo; + spSysInfo->getLocalNodeInfo(stNodeInfo); + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); + m_nLocationID = stNodeInfo.nLocationId; + } + loadEventConfig(); + return resumeThread(); +} + +void CEventDataCollect::release() +{ + m_pTimer->stop(); + suspendThread(true); + m_priorityOrderMap.clear(); + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionInfoDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + m_deviceTypeDescriptionMap.clear(); + m_subSystemDescriptionMap.clear(); + + CEventMsgManage::instance()->clearRTMsg(); +} + +void CEventDataCollect::loadEventConfig() +{ + loadPermInfo(); + priorityDescriptionMap(); + locationDescriptionMap(); + regionInfoDescriptionMap(); + alarmTypeDescriptionMap(); + deviceTypeDescriptionMap(); + alarmStatusMap(); + userNameMap(); +} + +int CEventDataCollect::priorityId(const QString &description) +{ + return m_priorityDescriptionMap.key(description, -1); +} + +int CEventDataCollect::locationId(const QString &description) +{ + return m_locationDescriptionMap.key(description, -1); +} + +int CEventDataCollect::regionId(const QString &description) +{ + return m_regionInfoDescriptionMap.key(description, -1); +} + +int CEventDataCollect::alarmTypeId(const QString &description) +{ + return m_alarmTypeDescriptionMap.key(description, -1); +} + +int CEventDataCollect::eventStatusId(const QString &description) +{ + return m_eventShowStatusMap.key(description, -1); +} + +int CEventDataCollect::deviceTypeId(const QString &description) +{ + return m_deviceTypeDescriptionMap.key(description, -1); +} + +QString CEventDataCollect::priorityDescription(const int &id) +{ + return m_priorityDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::locationDescription(const int &id) +{ + return m_locationDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::regionDescription(const int &id) +{ + return m_regionInfoDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::alarmTypeDescription(const int &id) +{ + return m_alarmTypeDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::deviceTypeDescription(const int &id) +{ + return m_deviceTypeDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::alarmStatusDescription(const int &id) +{ + return m_alarmStatusMap.value(id, QString()); +} + +QString CEventDataCollect::userNameDescription(const int &id) +{ + return m_userNameMap.value(id, QString()); +} + +QString CEventDataCollect::eventShowStatusDescription(const int &id) +{ + return m_eventShowStatusMap.value(id, QString()); +} + +QList CEventDataCollect::priorityList() +{ + return m_priorityDescriptionMap.keys(); +} + +QList CEventDataCollect::locationList() +{ + return m_listPermLocationId; +} + +QList CEventDataCollect::regionList() +{ + return m_listPermRegionId; +} + +QList CEventDataCollect::alarmTypeList() +{ + return m_alarmTypeDescriptionMap.keys(); +} + +QList CEventDataCollect::alarmStatusList() +{ + return m_eventShowStatusMap.keys(); +} + +QList CEventDataCollect::alarmOtherList() +{ + return m_eventOtherStatusMap.keys(); +} + +void CEventDataCollect::loadPermInfo() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecRegionId; + std::vector vecLocationId; + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listPermLocationId.append(*location++); + } + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listPermRegionId.append(*region++); + } + } + } +} + +QMap CEventDataCollect::priorityDescriptionMap() +{ + m_priorityDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "alarm_level_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("priority_id"); + columns.push_back("priority_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + return m_priorityDescriptionMap; +} + +QMap CEventDataCollect::locationDescriptionMap() +{ + m_locationDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "sys_model_location_info")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("description"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + if(m_listPermLocationId.contains(key.toInt())) + { + m_locationDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + } + return m_locationDescriptionMap; +} + +QMap CEventDataCollect::regionInfoDescriptionMap() +{ + m_regionInfoDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "region_info")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("region_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + if(m_listPermRegionId.contains(key.toInt())) + { + m_regionInfoDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + } + return m_regionInfoDescriptionMap; +} + +QMap CEventDataCollect::alarmTypeDescriptionMap() +{ + m_alarmTypeDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "alarm_type_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("type_id"); + columns.push_back("type_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + return m_alarmTypeDescriptionMap; +} + + +QMap CEventDataCollect::deviceTypeDescriptionMap() +{ + m_deviceTypeDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "dev_type_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("dev_type_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + return m_deviceTypeDescriptionMap; +} + +QMap CEventDataCollect::alarmStatusMap() +{ + m_alarmStatusMap.clear(); + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("status_value"); + columns.push_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + return m_alarmStatusMap; +} + +QMap CEventDataCollect::userNameMap() +{ + m_userNameMap.clear(); + if(m_rtdbAccess->open("base", "rm_user_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_id"); + columns.push_back("perm_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_userNameMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + return m_userNameMap; +} + +QMap CEventDataCollect::eventShowStatusDescriptionMap() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + if(StringToInt(strKey) != OTHERSTATUS) + { + m_eventShowStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; + }else + { + m_eventShowStatusMap[StringToInt(strKey)] = tr("其他"); + } + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } + return m_eventShowStatusMap; +} + +QMap CEventDataCollect::eventOtherStatusDescriptionMap() +{ + m_eventOtherStatusMap.clear(); + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + m_eventOtherStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } + return m_eventOtherStatusMap; +} + +//void CEventDataCollect::queryHistoryEvent(const QStringList &tables,QList typeFilter, const QString &condition) +//{ +// QList listHistoryEvent; +// if(tables.isEmpty()) +// { +// return; +// } +// bool res = m_dbInterface->open(); +// QStringList stDescList; +// stDescList.clear(); +// if(res) +// { +// QString sqlSequenceQuery; +// try +// { +// for(int nTableIndex(0); nTableIndex < tables.size(); nTableIndex++) +// { +// sqlSequenceQuery = QString("select " +// "time_stamp, " +// "priority," +// "location_id," +// "region_id," +// "content," +// "alm_type," +// "alm_status," +// "domain_id," +// "app_id," +// "dev_type," +// "confirm_user_id," +// "confirm_time " +// "from %1").arg(tables.at(nTableIndex)); +// if(!condition.isEmpty()) +// { +// sqlSequenceQuery = QString("%1 where %2").arg(sqlSequenceQuery).arg(condition); +// } + +// sqlSequenceQuery = QString("%1 order by time_stamp desc limit %2;").arg(sqlSequenceQuery).arg(LIMIT_HIS_RECORD); +// QSqlQuery query; +// try +// { +// m_dbInterface->execute(sqlSequenceQuery, query); +// } +// catch(...) +// { +// qDebug() << "Query Error!"; +// } +// if(query.isActive()) +// { +// int count = 0; +// int nIndex = 0; +// while(query.next()) +// { +// EventMsgPtr info(new CEventMsgInfo); +// info->time_stamp = query.value(0).toULongLong(); +// info->priority = query.value(1).toInt(); +// info->location_id = query.value(2).toInt(); +// info->region_id = query.value(3).toInt(); +// info->content = query.value(4).toString(); +// info->alm_type = query.value(5).toInt(); +// info->alm_status = query.value(6).toInt(); +// info->domain_id = query.value(7).toInt(); +// info->app_id = query.value(8).toInt(); +// info->dev_type = query.value(9).toInt(); +// info->cfm_user = query.value(10).toUInt(); +// info->cfm_time = query.value(11).toULongLong(); +// if(nTableIndex) +// { +// bool isInsertSuccess = false; +// while (nIndex < listHistoryEvent.size()) +// { +// if(info->time_stamp >= listHistoryEvent.at(nIndex)->time_stamp) +// { +// listHistoryEvent.insert(nIndex, info); +// isInsertSuccess = true; +// break; +// } +// ++nIndex; +// } +// if(!isInsertSuccess) +// { +// listHistoryEvent.append(info); +// } +// } +// else +// { +// listHistoryEvent.append(info); +// } +// ++count; +// } +// if(count >= LIMIT_HIS_RECORD) +// { +// stDescList.append(m_alarmTypeDescriptionMap.value(typeFilter.at(nTableIndex))); +// } +// } + +// } +// } +// catch(std::exception e) +// { +// qDebug() << "QueryHistoryEvent Exception!"; +// } +// } + +// m_dbInterface->close(); +// emit sigUpdateHistoryEvent(listHistoryEvent, stDescList); +//} + +void CEventDataCollect::slotUpdateEvent() +{ +// loadEventConfig(); + + QMutexLocker locker(msgMutex); + emit sigMsgArrived(m_listEventCache); + m_listEventCache.clear(); +} + +void CEventDataCollect::handleAllEvtMsg(int nDomainID, kbd_idlfile::SEvtCltAddEvt &objAllEvt) +{ + QMutexLocker locker(msgMutex); + CEventMsgManage::instance()->removeEventMsgByDomainID(nDomainID); + for(int nAddMsgIndex(0); nAddMsgIndex < objAllEvt.evt_info_size(); nAddMsgIndex++) + { + kbd_idlfile::SEvtInfoToEvtClt msg = objAllEvt.evt_info(nAddMsgIndex); + EventMsgPtr event(new CEventMsgInfo()); + event->initialize(msg); + event->priorityOrder = queryPriorityOrder(event->priority); + if(!m_listPermLocationId.contains(event->location_id)) + { + continue; + } + if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) + { + continue; + } + CEventMsgManage::instance()->addEventMsg(event); + } + emit sigMsgRefresh(); + emit sigEventStateChanged(); +} + +void CEventDataCollect::handleAddEvtMsg(kbd_idlfile::SEvtCltAddEvt &objAddEvt) +{ + QMutexLocker locker(msgMutex); + for(int nAddMsgIndex(0); nAddMsgIndex < objAddEvt.evt_info_size(); nAddMsgIndex++) + { + kbd_idlfile::SEvtInfoToEvtClt msg = objAddEvt.evt_info(nAddMsgIndex); + EventMsgPtr event(new CEventMsgInfo()); + event->initialize(msg); + event->priorityOrder = queryPriorityOrder(event->priority); + if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) + { + continue; + } + CEventMsgManage::instance()->addEventMsg(event); + m_listEventCache.append(event); + } + emit sigEventStateChanged(); +} + +void CEventDataCollect::handleClearRTEvent() +{ + QMutexLocker locker(msgMutex); + CEventMsgManage::instance()->clearRTMsg(); + emit sigMsgRefresh(); + emit sigEventStateChanged(); +} + +void CEventDataCollect::queryHistoryEvent(const QStringList &tables, const QString &condition) +{ + QList listHistoryEvent; + if(tables.isEmpty()) + { + return; + } + bool res = m_dbHisReadApi->open(); + QStringList stDescList; + stDescList.clear(); + if(res) + { + QString sqlSequenceQuery; + try + { + for(int nTableIndex(0); nTableIndex < tables.size(); nTableIndex++) + { + sqlSequenceQuery = QString("select " + "time_stamp, " + "priority," + "location_id," + "region_id," + "content," + "alm_type," + "alm_status," + "dev_type," + "confirm_user_id," + "confirm_time " + "from %1").arg(tables.at(nTableIndex)); + if(!condition.isEmpty()) + { + sqlSequenceQuery = QString("%1 where %2 ").arg(sqlSequenceQuery).arg(condition); + } + + sqlSequenceQuery = QString("%1 order by time_stamp desc limit %2 ;").arg(sqlSequenceQuery).arg(LIMIT_HIS_RECORD); + LOGINFO("%s",sqlSequenceQuery.toStdString().c_str()); + QSqlQuery query; + try + { + m_dbHisReadApi->execute(sqlSequenceQuery, query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + if(query.isActive()) + { + int count = 0; + int nIndex = 0; + while(query.next()) + { + EventMsgPtr info(new CEventMsgInfo); + info->time_stamp = query.value(0).toULongLong(); + info->priority = query.value(1).toInt(); + info->location_id = query.value(2).toInt(); + info->region_id = query.value(3).toInt(); + info->content = query.value(4).toString(); + info->alm_type = query.value(5).toInt(); + info->alm_status = query.value(6).toInt(); + info->dev_type = query.value(7).toInt(); + info->cfm_user = query.value(8).toUInt(); + info->cfm_time = query.value(9).toULongLong(); + if(nTableIndex) + { + bool isInsertSuccess = false; + while (nIndex < listHistoryEvent.size()) + { + if(info->time_stamp >= listHistoryEvent.at(nIndex)->time_stamp) + { + listHistoryEvent.insert(nIndex, info); + isInsertSuccess = true; + break; + } + ++nIndex; + } + if(!isInsertSuccess) + { + listHistoryEvent.append(info); + } + } + else + { + listHistoryEvent.append(info); + } + ++count; + } + if(count >= LIMIT_HIS_RECORD) + { + //stDescList.append(m_alarmTypeDescriptionMap.value(nTableIndex)); + } + } + + } + } + catch(std::exception e) + { + qDebug() << "QueryHistoryEvent Exception!"; + } + } + + m_dbHisReadApi->close(); + emit sigUpdateHistoryEvent(listHistoryEvent, stDescList); +} + +int CEventDataCollect::queryPriorityOrder(int &id) +{ + kbd_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + kbd_dbms::CVarType value; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventDataCollect.h b/product/src/gui/plugin/ISCSEventWidget/CEventDataCollect.h index fe884f06..9f8cf868 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventDataCollect.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventDataCollect.h @@ -1,122 +1,122 @@ -#ifndef CEventDataCollect_H -#define CEventDataCollect_H - -#include -#include -#include -#include "AlarmMessage.pb.h" -#include "CEventMsgInfo.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "dbms/rdb_api/CRdbAccess.h" -#include "db_api_ex/CDbApi.h" - -#define FUNC_SPE_EVENT_VIEW ("FUNC_SPE_EVENT_VIEW") -#define LIMIT_HIS_RECORD 10000 -const int OTHERSTATUS = 9999; -class CEventDataCollect : public QObject, public kbd_service::CAlmApiForEvtClt -{ - Q_OBJECT -public: - static CEventDataCollect * instance(); - - virtual ~CEventDataCollect(); - - bool initialize(); - - void release(); - - void loadEventConfig(); - int priorityId(const QString &description); - int locationId(const QString &description); - int regionId(const QString &description); - int alarmTypeId(const QString &description); - int eventStatusId(const QString &description); - int deviceTypeId(const QString &description); - - QString priorityDescription(const int & id); - QString locationDescription(const int & id); - QString regionDescription(const int & id); - QString alarmTypeDescription(const int & id); - QString deviceTypeDescription(const int & id); - QString alarmStatusDescription(const int & id); - QString userNameDescription(const int & id); - - QString eventShowStatusDescription(const int & id); - - QList priorityList(); - QList locationList(); - QList regionList(); - QList alarmTypeList(); - QList alarmStatusList(); - QList alarmOtherList(); - void loadPermInfo(); - QMap priorityDescriptionMap(); - QMap locationDescriptionMap(); - QMap regionInfoDescriptionMap(); - QMap alarmTypeDescriptionMap(); - QMap deviceTypeDescriptionMap(); - QMap alarmStatusMap(); - QMap userNameMap(); - - QMap eventShowStatusDescriptionMap(); - QMap eventOtherStatusDescriptionMap(); - - virtual void handleAllEvtMsg(int nDomainID, kbd_idlfile::SEvtCltAddEvt &objAllEvt); - - virtual void handleAddEvtMsg(kbd_idlfile::SEvtCltAddEvt &objAddEvt); - - void handleClearRTEvent(); - -signals: - /** - * @brief sigMsgRefresh 在handleAllAlmMsg时触发,通知model重新拉取报警消息 - */ - void sigMsgRefresh(); - - /** - * @brief sigMsgArrived 在handleAddAlmMsg时触发,通知model新报警消息到达 - */ - void sigMsgArrived(QList listEvents); - - /** - * @brief sigEventStateChanged 事件数量或状态改变时触发。 - */ - void sigEventStateChanged(); - - void sigUpdateHistoryEvent(QList listEvents, QStringList stDescList); - -public slots: - //void queryHistoryEvent(const QStringList &tables, QList typeFilter, const QString &condition); - void queryHistoryEvent(const QStringList &tables, const QString &condition); - void slotUpdateEvent(); - -private: - CEventDataCollect(); - int queryPriorityOrder(int &id); - -private: - QMutex * msgMutex; - QTimer * m_pTimer; - int m_nLocationID; - QList m_listEventCache; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; - kbd_dbms::CDbApi * m_dbHisReadApi; - QList m_listPermLocationId; - QList m_listPermRegionId; - QMap m_priorityOrderMap; - QMap m_priorityDescriptionMap; - QMap m_locationDescriptionMap; - QMap m_regionInfoDescriptionMap; - QMap m_alarmTypeDescriptionMap; - QMap m_deviceTypeDescriptionMap; - QMap m_subSystemDescriptionMap; - QMap m_alarmStatusMap; - QMap m_userNameMap; - static CEventDataCollect * m_pInstance; - - QMap m_eventShowStatusMap; // - QMap m_eventOtherStatusMap; //其他报警状态 -}; - -#endif // CEventDataCollect_H +#ifndef CEventDataCollect_H +#define CEventDataCollect_H + +#include +#include +#include +#include "AlarmMessage.pb.h" +#include "CEventMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include "db_api_ex/CDbApi.h" + +#define FUNC_SPE_EVENT_VIEW ("FUNC_SPE_EVENT_VIEW") +#define LIMIT_HIS_RECORD 10000 +const int OTHERSTATUS = 9999; +class CEventDataCollect : public QObject, public kbd_service::CAlmApiForEvtClt +{ + Q_OBJECT +public: + static CEventDataCollect * instance(); + + virtual ~CEventDataCollect(); + + bool initialize(); + + void release(); + + void loadEventConfig(); + int priorityId(const QString &description); + int locationId(const QString &description); + int regionId(const QString &description); + int alarmTypeId(const QString &description); + int eventStatusId(const QString &description); + int deviceTypeId(const QString &description); + + QString priorityDescription(const int & id); + QString locationDescription(const int & id); + QString regionDescription(const int & id); + QString alarmTypeDescription(const int & id); + QString deviceTypeDescription(const int & id); + QString alarmStatusDescription(const int & id); + QString userNameDescription(const int & id); + + QString eventShowStatusDescription(const int & id); + + QList priorityList(); + QList locationList(); + QList regionList(); + QList alarmTypeList(); + QList alarmStatusList(); + QList alarmOtherList(); + void loadPermInfo(); + QMap priorityDescriptionMap(); + QMap locationDescriptionMap(); + QMap regionInfoDescriptionMap(); + QMap alarmTypeDescriptionMap(); + QMap deviceTypeDescriptionMap(); + QMap alarmStatusMap(); + QMap userNameMap(); + + QMap eventShowStatusDescriptionMap(); + QMap eventOtherStatusDescriptionMap(); + + virtual void handleAllEvtMsg(int nDomainID, kbd_idlfile::SEvtCltAddEvt &objAllEvt); + + virtual void handleAddEvtMsg(kbd_idlfile::SEvtCltAddEvt &objAddEvt); + + void handleClearRTEvent(); + +signals: + /** + * @brief sigMsgRefresh 在handleAllAlmMsg时触发,通知model重新拉取报警消息 + */ + void sigMsgRefresh(); + + /** + * @brief sigMsgArrived 在handleAddAlmMsg时触发,通知model新报警消息到达 + */ + void sigMsgArrived(QList listEvents); + + /** + * @brief sigEventStateChanged 事件数量或状态改变时触发。 + */ + void sigEventStateChanged(); + + void sigUpdateHistoryEvent(QList listEvents, QStringList stDescList); + +public slots: + //void queryHistoryEvent(const QStringList &tables, QList typeFilter, const QString &condition); + void queryHistoryEvent(const QStringList &tables, const QString &condition); + void slotUpdateEvent(); + +private: + CEventDataCollect(); + int queryPriorityOrder(int &id); + +private: + QMutex * msgMutex; + QTimer * m_pTimer; + int m_nLocationID; + QList m_listEventCache; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + kbd_dbms::CDbApi * m_dbHisReadApi; + QList m_listPermLocationId; + QList m_listPermRegionId; + QMap m_priorityOrderMap; + QMap m_priorityDescriptionMap; + QMap m_locationDescriptionMap; + QMap m_regionInfoDescriptionMap; + QMap m_alarmTypeDescriptionMap; + QMap m_deviceTypeDescriptionMap; + QMap m_subSystemDescriptionMap; + QMap m_alarmStatusMap; + QMap m_userNameMap; + static CEventDataCollect * m_pInstance; + + QMap m_eventShowStatusMap; // + QMap m_eventOtherStatusMap; //其他报警状态 +}; + +#endif // CEventDataCollect_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.cpp index b1428eb8..b788745e 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.cpp @@ -1,531 +1,531 @@ -#include "CEventFilterDialog.h" -#include "ui_CEventFilterDialog.h" -#include "CEventDataCollect.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" - -CEventFilterDialog::CEventFilterDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CEventFilterDialog), - m_rtdbAccess(Q_NULLPTR) -{ - ui->setupUi(this); - setObjectName("event_dialog"); - ui->subSystem->setView(new QListView()); - ui->deviceType->setView(new QListView()); - initialize(); -} - -CEventFilterDialog::~CEventFilterDialog() -{ - if(m_rtdbAccess) - { - delete m_rtdbAccess; - } - m_rtdbAccess = Q_NULLPTR; - delete ui; -} - -void CEventFilterDialog::initialize() -{ - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - ui->level->setSelectionMode(QAbstractItemView::MultiSelection); - ui->location->setSelectionMode(QAbstractItemView::MultiSelection); - ui->region->setSelectionMode(QAbstractItemView::MultiSelection); - ui->type->setSelectionMode(QAbstractItemView::MultiSelection); - - QList priorityList = CEventDataCollect::instance()->priorityList(); - foreach (int priority, priorityList) - { - ui->level->addItem(CEventDataCollect::instance()->priorityDescription(priority)); - } - - QList locationList = CEventDataCollect::instance()->locationList(); - foreach (int location, locationList) - { - ui->location->addItem(CEventDataCollect::instance()->locationDescription(location)); - } - - QList regionList = CEventDataCollect::instance()->regionList(); - foreach (int region, regionList) - { - ui->region->addItem(CEventDataCollect::instance()->regionDescription(region)); - } - - QList alarmTypeList = CEventDataCollect::instance()->alarmTypeList(); - foreach (int alarmType, alarmTypeList) - { - ui->type->addItem(CEventDataCollect::instance()->alarmTypeDescription(alarmType)); - } - - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - std::vector vecSubsystemInfo; - spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); - foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) - { - if(info.nId <= CN_AppId_COMAPP) - { - continue; - } - ui->subSystem->addItem(QString::fromStdString(info.strDesc)); - } - } - - ui->subSystem->setCurrentIndex(-1); - - connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); - connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); - connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); - connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); - connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); - connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); - connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); - connect(ui->location, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLocationState())); - connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); - connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); - connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); - connect(ui->checkType, SIGNAL(pressed()), this, SLOT(slot_checkTypePressed())); - connect(ui->checkType, SIGNAL(stateChanged(int)), this, SLOT(slot_typeSelectChange(int))); - connect(ui->type, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckTypeState())); - connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); - ui->subSystem->setCurrentIndex(0); -} - -void CEventFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) -{ - ui->levelFilter->setChecked(isLevelFilterEnable); -} - -void CEventFilterDialog::setLevelFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->level->count(); nIndex++) - { - int nLevelID = CEventDataCollect::instance()->priorityId(ui->level->item(nIndex)->text()); - if(filter.contains(nLevelID)) - { - ui->level->item(nIndex)->setSelected(true); - } - else - { - ui->level->item(nIndex)->setSelected(false); - } - } -} - -void CEventFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) -{ - ui->locationFilter->setChecked(isLocationFilterEnable); -} - -void CEventFilterDialog::setLocationFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->location->count(); nIndex++) - { - int nLocationID = CEventDataCollect::instance()->locationId(ui->location->item(nIndex)->text()); - if(filter.contains(nLocationID)) - { - ui->location->item(nIndex)->setSelected(true); - } - else - { - ui->location->item(nIndex)->setSelected(false); - } - } -} - -void CEventFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) -{ - ui->regionFilter->setChecked(isRegionFilterEnable); -} - -void CEventFilterDialog::setRegionFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->region->count(); nIndex++) - { - int nRegionID = CEventDataCollect::instance()->regionId(ui->region->item(nIndex)->text()); - if(filter.contains(nRegionID)) - { - ui->region->item(nIndex)->setSelected(true); - } - else - { - ui->region->item(nIndex)->setSelected(false); - } - } -} - -void CEventFilterDialog::setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable) -{ - ui->alarmTypeFilter->setChecked(isAlarmTypeEnable); -} - -void CEventFilterDialog::setAlarmTypeFilter(const QList &filter) -{ - for(int nIndex(0); nIndex < ui->type->count(); nIndex++) - { - int nAlarmTypeID = CEventDataCollect::instance()->alarmTypeId(ui->type->item(nIndex)->text()); - if(filter.contains(nAlarmTypeID)) - { - ui->type->item(nIndex)->setSelected(true); - } - else - { - ui->type->item(nIndex)->setSelected(false); - } - } -} - -void CEventFilterDialog::setDeviceFilterEnable(const bool &filter) -{ - ui->deviceFilterEnable->setChecked(filter); -} - -void CEventFilterDialog::setSubSystem(const QString &subSystem) -{ - if(ui->deviceFilterEnable->isChecked()) - { - ui->subSystem->setCurrentText(subSystem); - } -} - -void CEventFilterDialog::setDeviceType(const QString &deviceType) -{ - if(ui->deviceFilterEnable->isChecked()) - { - ui->deviceType->setCurrentText(deviceType); - } -} - -void CEventFilterDialog::setTimeFilterEnable(const bool &filter) -{ - ui->timeFilterEnable->setChecked(filter); -} - -void CEventFilterDialog::setStartTimeFilter(const QDateTime &filter) -{ - if(ui->timeFilterEnable->isChecked()) - { - ui->startTime->setDateTime(filter); - } - else - { - ui->startTime->setDateTime(QDateTime::currentDateTime()); - } -} - -void CEventFilterDialog::setEndTimeFilter(const QDateTime &filter) -{ - if(ui->timeFilterEnable->isChecked()) - { - ui->endTime->setDateTime(filter); - } - else - { - ui->endTime->setDateTime(QDateTime::currentDateTime()); - } -} - - -void CEventFilterDialog::setkeyWordFilterEnable(const bool &filter) -{ - ui->keywordFilterEnable->setChecked(filter); -} - -void CEventFilterDialog::setkeyWordFilteContent(const QString &content) -{ - if(ui->keywordFilterEnable->isChecked()) - { - ui->keyWord->setText(content); - } -} - -void CEventFilterDialog::slot_updateFilter() -{ - bool isLevelFilter = ui->levelFilter->isChecked(); - QList listLevel; - foreach (QListWidgetItem *item, ui->level->selectedItems()) - { - listLevel << CEventDataCollect::instance()->priorityId(item->text()); - } - - bool isLocationFilter = ui->locationFilter->isChecked(); - QList listLocation; - foreach (QListWidgetItem *item, ui->location->selectedItems()) - { - listLocation << CEventDataCollect::instance()->locationId(item->text()); - } - - bool isRegionFilter = ui->regionFilter->isChecked(); - QList listRegion; - foreach (QListWidgetItem *item, ui->region->selectedItems()) - { - listRegion << CEventDataCollect::instance()->regionId(item->text()); - } - - bool isAlarmTypeFilter = ui->alarmTypeFilter->isChecked(); - QList listAlarmType; - foreach (QListWidgetItem *item, ui->type->selectedItems()) - { - listAlarmType << CEventDataCollect::instance()->alarmTypeId(item->text()); - } - - bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); - QString subSystem = ui->subSystem->currentText(); - QString deviceType = ui->deviceType->currentText(); - - bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); - QString strKeyWord =ui->keyWord->text(); - - bool isTimeFilter = ui->timeFilterEnable->isChecked(); - QDateTime startTime = QDateTime(); - QDateTime endTime = QDateTime(); - if(isTimeFilter) - { - startTime = ui->startTime->dateTime(); - endTime = ui->endTime->dateTime(); - } - - emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, - isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime); - accept(); -} - -//Level -void CEventFilterDialog::slot_checkLevelPressed() -{ - if( Qt::Unchecked == ui->checkLevel->checkState()) - { - ui->checkLevel->setTristate(false); - } -} - -void CEventFilterDialog::slot_levelSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->level->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->level->selectAll(); - } -} - -void CEventFilterDialog::slot_updateCheckLevelState() -{ - if( ui->level->count() == ui->level->selectedItems().count() ) - { - if( Qt::Checked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->level->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) - { - ui->checkLevel->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Location -void CEventFilterDialog::slot_checkLocationPressed() -{ - if( Qt::Unchecked == ui->checkLocation->checkState()) - { - ui->checkLocation->setTristate(false); - } -} - -void CEventFilterDialog::slot_locationSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->location->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->location->selectAll(); - } -} - -void CEventFilterDialog::slot_updateCheckLocationState() -{ - if( ui->location->count() == ui->location->selectedItems().count() ) - { - if( Qt::Checked != ui->checkLocation->checkState() ) - { - ui->checkLocation->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->location->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkLocation->checkState() ) - { - ui->checkLocation->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkLocation->checkState() ) - { - ui->checkLocation->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Region -void CEventFilterDialog::slot_checkRegionPressed() -{ - if( Qt::Unchecked == ui->checkRegion->checkState()) - { - ui->checkRegion->setTristate(false); - } -} - -void CEventFilterDialog::slot_regionSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->region->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->region->selectAll(); - } -} - -void CEventFilterDialog::slot_updateCheckRegionState() -{ - if( ui->region->count() == ui->region->selectedItems().count() ) - { - if( Qt::Checked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->region->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) - { - ui->checkRegion->setCheckState(Qt::PartiallyChecked); - } - } -} - -//Type -void CEventFilterDialog::slot_checkTypePressed() -{ - if( Qt::Unchecked == ui->checkType->checkState()) - { - ui->checkType->setTristate(false); - } -} - -void CEventFilterDialog::slot_typeSelectChange(const int &state) -{ - if( Qt::Unchecked == (Qt::CheckState)state ) - { - ui->type->clearSelection(); - } - else if( Qt::Checked == (Qt::CheckState)state) - { - ui->type->selectAll(); - } -} - -void CEventFilterDialog::slot_updateCheckTypeState() -{ - if( ui->type->count() == ui->type->selectedItems().count() ) - { - if( Qt::Checked != ui->checkType->checkState() ) - { - ui->checkType->setCheckState(Qt::Checked); - } - - } - else if( 0 == ui->type->selectedItems().count() ) - { - if( Qt::Unchecked != ui->checkType->checkState() ) - { - ui->checkType->setCheckState(Qt::Unchecked); - } - } - else - { - if( Qt::PartiallyChecked != ui->checkType->checkState() ) - { - ui->checkType->setCheckState(Qt::PartiallyChecked); - } - } -} - -void CEventFilterDialog::slot_updateDevice(const QString &subSystem) -{ - int nSubSystemId = -1; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - std::vector vecSubsystemInfo; - spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); - foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) - { - if(subSystem.toStdString() == info.strDesc) - { - nSubSystemId = info.nId; - } - } - } - - ui->deviceType->clear(); - QList values; - - if(nSubSystemId != -1) - { - kbd_dbms::CVarType subSystemId = nSubSystemId; - if(m_rtdbAccess->open("base", "dev_type_def")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CONDINFO condition; - condition.relationop = ATTRCOND_EQU; - memcpy(condition.name, "sub_system", strlen("sub_system")); - condition.conditionval = subSystemId; - std::vector columns; - columns.push_back("description"); - - kbd_dbms::CRdbQueryResult result; - if(m_rtdbAccess->select(condition, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, value); - values.append(value); - } - } - } - } - foreach (kbd_dbms::CVarType value, values) - { - ui->deviceType->addItem(value.c_str()); - } -} +#include "CEventFilterDialog.h" +#include "ui_CEventFilterDialog.h" +#include "CEventDataCollect.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" + +CEventFilterDialog::CEventFilterDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CEventFilterDialog), + m_rtdbAccess(Q_NULLPTR) +{ + ui->setupUi(this); + setObjectName("event_dialog"); + ui->subSystem->setView(new QListView()); + ui->deviceType->setView(new QListView()); + initialize(); +} + +CEventFilterDialog::~CEventFilterDialog() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + delete ui; +} + +void CEventFilterDialog::initialize() +{ + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + ui->level->setSelectionMode(QAbstractItemView::MultiSelection); + ui->location->setSelectionMode(QAbstractItemView::MultiSelection); + ui->region->setSelectionMode(QAbstractItemView::MultiSelection); + ui->type->setSelectionMode(QAbstractItemView::MultiSelection); + + QList priorityList = CEventDataCollect::instance()->priorityList(); + foreach (int priority, priorityList) + { + ui->level->addItem(CEventDataCollect::instance()->priorityDescription(priority)); + } + + QList locationList = CEventDataCollect::instance()->locationList(); + foreach (int location, locationList) + { + ui->location->addItem(CEventDataCollect::instance()->locationDescription(location)); + } + + QList regionList = CEventDataCollect::instance()->regionList(); + foreach (int region, regionList) + { + ui->region->addItem(CEventDataCollect::instance()->regionDescription(region)); + } + + QList alarmTypeList = CEventDataCollect::instance()->alarmTypeList(); + foreach (int alarmType, alarmTypeList) + { + ui->type->addItem(CEventDataCollect::instance()->alarmTypeDescription(alarmType)); + } + + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(info.nId <= CN_AppId_COMAPP) + { + continue; + } + ui->subSystem->addItem(QString::fromStdString(info.strDesc)); + } + } + + ui->subSystem->setCurrentIndex(-1); + + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); + connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); + connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); + connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); + connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); + connect(ui->location, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLocationState())); + connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); + connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); + connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); + connect(ui->checkType, SIGNAL(pressed()), this, SLOT(slot_checkTypePressed())); + connect(ui->checkType, SIGNAL(stateChanged(int)), this, SLOT(slot_typeSelectChange(int))); + connect(ui->type, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckTypeState())); + connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); + ui->subSystem->setCurrentIndex(0); +} + +void CEventFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) +{ + ui->levelFilter->setChecked(isLevelFilterEnable); +} + +void CEventFilterDialog::setLevelFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->level->count(); nIndex++) + { + int nLevelID = CEventDataCollect::instance()->priorityId(ui->level->item(nIndex)->text()); + if(filter.contains(nLevelID)) + { + ui->level->item(nIndex)->setSelected(true); + } + else + { + ui->level->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) +{ + ui->locationFilter->setChecked(isLocationFilterEnable); +} + +void CEventFilterDialog::setLocationFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->location->count(); nIndex++) + { + int nLocationID = CEventDataCollect::instance()->locationId(ui->location->item(nIndex)->text()); + if(filter.contains(nLocationID)) + { + ui->location->item(nIndex)->setSelected(true); + } + else + { + ui->location->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) +{ + ui->regionFilter->setChecked(isRegionFilterEnable); +} + +void CEventFilterDialog::setRegionFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->region->count(); nIndex++) + { + int nRegionID = CEventDataCollect::instance()->regionId(ui->region->item(nIndex)->text()); + if(filter.contains(nRegionID)) + { + ui->region->item(nIndex)->setSelected(true); + } + else + { + ui->region->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable) +{ + ui->alarmTypeFilter->setChecked(isAlarmTypeEnable); +} + +void CEventFilterDialog::setAlarmTypeFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->type->count(); nIndex++) + { + int nAlarmTypeID = CEventDataCollect::instance()->alarmTypeId(ui->type->item(nIndex)->text()); + if(filter.contains(nAlarmTypeID)) + { + ui->type->item(nIndex)->setSelected(true); + } + else + { + ui->type->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setDeviceFilterEnable(const bool &filter) +{ + ui->deviceFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setSubSystem(const QString &subSystem) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->subSystem->setCurrentText(subSystem); + } +} + +void CEventFilterDialog::setDeviceType(const QString &deviceType) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->deviceType->setCurrentText(deviceType); + } +} + +void CEventFilterDialog::setTimeFilterEnable(const bool &filter) +{ + ui->timeFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setStartTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->startTime->setDateTime(filter); + } + else + { + ui->startTime->setDateTime(QDateTime::currentDateTime()); + } +} + +void CEventFilterDialog::setEndTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->endTime->setDateTime(filter); + } + else + { + ui->endTime->setDateTime(QDateTime::currentDateTime()); + } +} + + +void CEventFilterDialog::setkeyWordFilterEnable(const bool &filter) +{ + ui->keywordFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setkeyWordFilteContent(const QString &content) +{ + if(ui->keywordFilterEnable->isChecked()) + { + ui->keyWord->setText(content); + } +} + +void CEventFilterDialog::slot_updateFilter() +{ + bool isLevelFilter = ui->levelFilter->isChecked(); + QList listLevel; + foreach (QListWidgetItem *item, ui->level->selectedItems()) + { + listLevel << CEventDataCollect::instance()->priorityId(item->text()); + } + + bool isLocationFilter = ui->locationFilter->isChecked(); + QList listLocation; + foreach (QListWidgetItem *item, ui->location->selectedItems()) + { + listLocation << CEventDataCollect::instance()->locationId(item->text()); + } + + bool isRegionFilter = ui->regionFilter->isChecked(); + QList listRegion; + foreach (QListWidgetItem *item, ui->region->selectedItems()) + { + listRegion << CEventDataCollect::instance()->regionId(item->text()); + } + + bool isAlarmTypeFilter = ui->alarmTypeFilter->isChecked(); + QList listAlarmType; + foreach (QListWidgetItem *item, ui->type->selectedItems()) + { + listAlarmType << CEventDataCollect::instance()->alarmTypeId(item->text()); + } + + bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); + QString subSystem = ui->subSystem->currentText(); + QString deviceType = ui->deviceType->currentText(); + + bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); + QString strKeyWord =ui->keyWord->text(); + + bool isTimeFilter = ui->timeFilterEnable->isChecked(); + QDateTime startTime = QDateTime(); + QDateTime endTime = QDateTime(); + if(isTimeFilter) + { + startTime = ui->startTime->dateTime(); + endTime = ui->endTime->dateTime(); + } + + emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, + isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime); + accept(); +} + +//Level +void CEventFilterDialog::slot_checkLevelPressed() +{ + if( Qt::Unchecked == ui->checkLevel->checkState()) + { + ui->checkLevel->setTristate(false); + } +} + +void CEventFilterDialog::slot_levelSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->level->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->level->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckLevelState() +{ + if( ui->level->count() == ui->level->selectedItems().count() ) + { + if( Qt::Checked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->level->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Location +void CEventFilterDialog::slot_checkLocationPressed() +{ + if( Qt::Unchecked == ui->checkLocation->checkState()) + { + ui->checkLocation->setTristate(false); + } +} + +void CEventFilterDialog::slot_locationSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->location->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->location->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckLocationState() +{ + if( ui->location->count() == ui->location->selectedItems().count() ) + { + if( Qt::Checked != ui->checkLocation->checkState() ) + { + ui->checkLocation->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->location->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkLocation->checkState() ) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkLocation->checkState() ) + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Region +void CEventFilterDialog::slot_checkRegionPressed() +{ + if( Qt::Unchecked == ui->checkRegion->checkState()) + { + ui->checkRegion->setTristate(false); + } +} + +void CEventFilterDialog::slot_regionSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->region->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->region->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckRegionState() +{ + if( ui->region->count() == ui->region->selectedItems().count() ) + { + if( Qt::Checked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->region->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Type +void CEventFilterDialog::slot_checkTypePressed() +{ + if( Qt::Unchecked == ui->checkType->checkState()) + { + ui->checkType->setTristate(false); + } +} + +void CEventFilterDialog::slot_typeSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->type->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->type->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckTypeState() +{ + if( ui->type->count() == ui->type->selectedItems().count() ) + { + if( Qt::Checked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->type->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::PartiallyChecked); + } + } +} + +void CEventFilterDialog::slot_updateDevice(const QString &subSystem) +{ + int nSubSystemId = -1; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (kbd_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(subSystem.toStdString() == info.strDesc) + { + nSubSystemId = info.nId; + } + } + } + + ui->deviceType->clear(); + QList values; + + if(nSubSystemId != -1) + { + kbd_dbms::CVarType subSystemId = nSubSystemId; + if(m_rtdbAccess->open("base", "dev_type_def")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CONDINFO condition; + condition.relationop = ATTRCOND_EQU; + memcpy(condition.name, "sub_system", strlen("sub_system")); + condition.conditionval = subSystemId; + std::vector columns; + columns.push_back("description"); + + kbd_dbms::CRdbQueryResult result; + if(m_rtdbAccess->select(condition, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, value); + values.append(value); + } + } + } + } + foreach (kbd_dbms::CVarType value, values) + { + ui->deviceType->addItem(value.c_str()); + } +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.h b/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.h index 76efab02..5e3919dc 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.h @@ -1,76 +1,76 @@ -#ifndef CEVENTFILTERDIALOG_H -#define CEVENTFILTERDIALOG_H - -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" - -namespace Ui { -class CEventFilterDialog; -} - -class CEventFilterDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CEventFilterDialog(QWidget *parent = 0); - ~CEventFilterDialog(); - - void initialize(); - - void setLevelFilterEnable(const bool &isLevelFilterEnable); - void setLevelFilter(const QList &filter); - void setLocationFilterEnable(const bool &isLocationFilterEnable); - void setLocationFilter(const QList &filter); - void setRegionFilterEnable(const bool &isRegionFilterEnable); - void setRegionFilter(const QList &filter); - void setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable); - void setAlarmTypeFilter(const QList &filter); - void setDeviceFilterEnable(const bool &filter); - void setSubSystem(const QString &subSystem); - void setDeviceType(const QString &deviceType); - void setTimeFilterEnable(const bool &filter); - void setStartTimeFilter(const QDateTime &filter); - void setEndTimeFilter(const QDateTime &filter); - void setkeyWordFilterEnable(const bool &filter); - void setkeyWordFilteContent(const QString &content); -signals: - /** - * @brief sig_updateFilter - * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm - */ - void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime); - -private slots: - void slot_updateFilter(); - - //Level - void slot_checkLevelPressed(); - void slot_levelSelectChange(const int &state); - void slot_updateCheckLevelState(); - - //Station - void slot_checkLocationPressed(); - void slot_locationSelectChange(const int &state); - void slot_updateCheckLocationState(); - - //Region - void slot_checkRegionPressed(); - void slot_regionSelectChange(const int &state); - void slot_updateCheckRegionState(); - - //AlarmType - void slot_checkTypePressed(); - void slot_typeSelectChange(const int &state); - void slot_updateCheckTypeState(); - - //DeviceType - void slot_updateDevice(const QString &subSystem); - -private: - Ui::CEventFilterDialog *ui; - kbd_dbms::CRdbAccess * m_rtdbAccess; -}; - -#endif // CEVENTFILTERDIALOG_H +#ifndef CEVENTFILTERDIALOG_H +#define CEVENTFILTERDIALOG_H + +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" + +namespace Ui { +class CEventFilterDialog; +} + +class CEventFilterDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CEventFilterDialog(QWidget *parent = 0); + ~CEventFilterDialog(); + + void initialize(); + + void setLevelFilterEnable(const bool &isLevelFilterEnable); + void setLevelFilter(const QList &filter); + void setLocationFilterEnable(const bool &isLocationFilterEnable); + void setLocationFilter(const QList &filter); + void setRegionFilterEnable(const bool &isRegionFilterEnable); + void setRegionFilter(const QList &filter); + void setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable); + void setAlarmTypeFilter(const QList &filter); + void setDeviceFilterEnable(const bool &filter); + void setSubSystem(const QString &subSystem); + void setDeviceType(const QString &deviceType); + void setTimeFilterEnable(const bool &filter); + void setStartTimeFilter(const QDateTime &filter); + void setEndTimeFilter(const QDateTime &filter); + void setkeyWordFilterEnable(const bool &filter); + void setkeyWordFilteContent(const QString &content); +signals: + /** + * @brief sig_updateFilter + * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm + */ + void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime); + +private slots: + void slot_updateFilter(); + + //Level + void slot_checkLevelPressed(); + void slot_levelSelectChange(const int &state); + void slot_updateCheckLevelState(); + + //Station + void slot_checkLocationPressed(); + void slot_locationSelectChange(const int &state); + void slot_updateCheckLocationState(); + + //Region + void slot_checkRegionPressed(); + void slot_regionSelectChange(const int &state); + void slot_updateCheckRegionState(); + + //AlarmType + void slot_checkTypePressed(); + void slot_typeSelectChange(const int &state); + void slot_updateCheckTypeState(); + + //DeviceType + void slot_updateDevice(const QString &subSystem); + +private: + Ui::CEventFilterDialog *ui; + kbd_dbms::CRdbAccess * m_rtdbAccess; +}; + +#endif // CEVENTFILTERDIALOG_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.ui b/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.ui index 07356625..ed33bf49 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.ui +++ b/product/src/gui/plugin/ISCSEventWidget/CEventFilterDialog.ui @@ -1,326 +1,326 @@ - - - CEventFilterDialog - - - - 0 - 0 - 530 - 429 - - - - - 530 - 0 - - - - - 530 - 16777215 - - - - 过滤 - - - - - - - - 优先级 - - - true - - - - - - 全选 - - - true - - - true - - - - - - - - - - - - - 位置 - - - true - - - - - - 全选 - - - true - - - - - - - - - - - - - 责任区 - - - true - - - - - - 全选 - - - true - - - - - - - - - - - - - 事件类型 - - - true - - - - - - 全选 - - - true - - - - - - - - - - - - - - - - - - - 设备类型 - - - true - - - false - - - - - - - - - - - - - - - 事件内容关键字 - - - true - - - false - - - - - - - - - - - - - - 时间 - - - true - - - false - - - - - - - - 开始时间 - - - - - - - - 2018 - 1 - 1 - - - - - 0 - 0 - 0 - 2000 - 1 - 1 - - - - - 2050 - 12 - 31 - - - - QDateTimeEdit::YearSection - - - yyyy/MM/dd hh:mm - - - - - - - - - - - 结束时间 - - - - - - - false - - - - 2018 - 1 - 1 - - - - - 0 - 0 - 0 - 2000 - 1 - 1 - - - - - 2050 - 12 - 31 - - - - yyyy/MM/dd hh:mm - - - false - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 281 - 20 - - - - - - - - 确定 - - - - - - - 取消 - - - - - - - - - - + + + CEventFilterDialog + + + + 0 + 0 + 530 + 429 + + + + + 530 + 0 + + + + + 530 + 16777215 + + + + 过滤 + + + + + + + + 优先级 + + + true + + + + + + 全选 + + + true + + + true + + + + + + + + + + + + + 位置 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + + 责任区 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + + 事件类型 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + + + + + + + + 设备类型 + + + true + + + false + + + + + + + + + + + + + + + 事件内容关键字 + + + true + + + false + + + + + + + + + + + + + + 时间 + + + true + + + false + + + + + + + + 开始时间 + + + + + + + + 2018 + 1 + 1 + + + + + 0 + 0 + 0 + 2000 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + QDateTimeEdit::YearSection + + + yyyy/MM/dd hh:mm + + + + + + + + + + + 结束时间 + + + + + + + false + + + + 2018 + 1 + 1 + + + + + 0 + 0 + 0 + 2000 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + yyyy/MM/dd hh:mm + + + false + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 281 + 20 + + + + + + + + 确定 + + + + + + + 取消 + + + + + + + + + + diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventForm.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventForm.cpp index 988f6a06..cf3f002a 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventForm.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventForm.cpp @@ -1,964 +1,964 @@ -#include "CEventForm.h" -#include "ui_CEventForm.h" -#include "CEventMsgInfo.h" -#include -#include "CEventItemModel.h" -#include "CEventHistoryModel.h" -#include "CEventFilterDialog.h" -#include "CEventMsgManage.h" -#include "CEventDataCollect.h" -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pub_utility_api/FileStyle.h" - -CEventForm::CEventForm(QWidget *parent, bool editMode) : - QWidget(parent), - m_pRealTimeModel(NULL), - m_pHistoryModel(NULL), - m_isEditMode(editMode), - ui(new Ui::CEventForm) -{ - qRegisterMetaType("CEventMsgInfo"); - qRegisterMetaType("EventMsgPtr"); - - ui->setupUi(this); - m_pListWidget1 = new CMyListWidget(this); - m_pListWidget2 = new CMyListWidget(this); - m_pListWidget3 = new CMyListWidget(this); - m_pLineEdit1 = new QLineEdit(this); - m_pLineEdit2 = new QLineEdit(this); - m_pLineEdit3 = new QLineEdit(this); - initilize(); - if(!m_isEditMode) - { - connect(ui->eventType, &QPushButton::clicked, this, &CEventForm::slotUpdateModel); - CEventDataCollect::instance()->initialize(); - - initFilter(); - slotUpdateModel(); - connect(CEventDataCollect::instance(), SIGNAL(sigEventStateChanged()), this, SLOT(slotRTEventStateChanged()), Qt::QueuedConnection); - connect(ui->clear, &QPushButton::clicked, this, &CEventForm::slotClearRTEvent); - connect(ui->closeBtn, &QPushButton::clicked, this, &CEventForm::closeBtnClicked); - ui->eventView->setColumnWidth(0, 250); - ui->eventView->setColumnWidth(1, 150); - ui->eventView->setColumnWidth(2, 150); - ui->eventView->setColumnWidth(3, 150); - ui->eventView->setColumnWidth(4, 150); - ui->eventView->setColumnWidth(5, 150); - } - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("event.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - m_timeIcon = new QPushButton(this); - m_myCalendar = new CMyCalendar(this); - QWidgetAction *widgetAction=new QWidgetAction(this); - m_timeMenu = new QMenu(this); - widgetAction->setDefaultWidget(m_myCalendar); - m_timeMenu->addAction(widgetAction); - m_timeIcon->setObjectName("iconButton"); - m_timeIcon->setText(""); - m_timeIcon->setMaximumSize(21, 22); - m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); - QHBoxLayout * pTimeLayout = new QHBoxLayout(); - pTimeLayout->setContentsMargins(1, 1, 1, 1); - pTimeLayout->addStretch(); - pTimeLayout->addWidget(m_timeIcon); - ui->lineEdit->setLayout(pTimeLayout); - connect(m_timeIcon,&QPushButton::clicked,this,&CEventForm::myCalendarShow); - connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CEventForm::myCalendarHide); - connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CEventForm::cancleTimeFilter); - ui->lineEdit->setText(tr("请选择时间")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit->setObjectName("iconLineEdit"); - - m_excelPrinter = new CExcelPrinter(); - m_thread = new QThread(); - m_excelPrinter->moveToThread(m_thread); - connect(m_thread,&QThread::started,m_excelPrinter,&CExcelPrinter::initialize); - connect(m_thread,&QThread::finished,m_excelPrinter,&CExcelPrinter::deleteLater); - connect(this,&CEventForm::printExcel,m_excelPrinter,&CExcelPrinter::printerByModel); - connect(this,&CEventForm::printExcelHis,m_excelPrinter,&CExcelPrinter::printerHisByModel); - connect(m_excelPrinter,&CExcelPrinter::sigShowResult,this,&CEventForm::slotShowResult); - m_thread->start(); -} - -CEventForm::~CEventForm() -{ - if(m_pRealTimeModel) - { - delete m_pRealTimeModel; - } - m_pRealTimeModel = Q_NULLPTR; - - if(m_pHistoryModel) - { - delete m_pHistoryModel; - } - m_pHistoryModel = Q_NULLPTR; - - delete m_excelPrinter; - m_thread->quit(); - m_thread->wait(); - delete CEventDataCollect::instance(); - delete CEventMsgManage::instance(); - delete ui; - - qDebug() << "~CEventForm()"; -} - -void CEventForm::initilize() -{ - //< lingdaoyaoqiu - { - QSettings columFlags1("KBD_HMI", "eventReal config"); - if(!columFlags1.contains(QString("eventReal/colum_0"))) - { - columFlags1.setValue(QString("eventReal/colum_0"), false); //< 时间 - columFlags1.setValue(QString("eventReal/colum_1"), false); //< 优先级 - columFlags1.setValue(QString("eventReal/colum_2"), false); //< 位置 - columFlags1.setValue(QString("eventReal/colum_3"), true); //< 责任区 - columFlags1.setValue(QString("eventReal/colum_4"), true); //< 事件类型 - columFlags1.setValue(QString("eventReal/colum_5"), false); //< 事件状态 - columFlags1.setValue(QString("eventReal/colum_6"), false); //< 事件内容 - } - } - { - QSettings columFlags2("KBD_HMI", "eventHis config"); - if(!columFlags2.contains(QString("eventHis/colum_0"))) - { - columFlags2.setValue(QString("eventHis/colum_0"), false); //< 时间 - columFlags2.setValue(QString("eventHis/colum_1"), false); //< 优先级 - columFlags2.setValue(QString("eventHis/colum_2"), false); //< 位置 - columFlags2.setValue(QString("eventHis/colum_3"), true); //< 责任区 - columFlags2.setValue(QString("eventHis/colum_4"), true); //< 事件类型 - columFlags2.setValue(QString("eventHis/colum_5"), false); //< 事件状态 - columFlags2.setValue(QString("eventHis/colum_6"), true); //< 确认人 - columFlags2.setValue(QString("eventHis/colum_7"), true); //< 确认时间 - columFlags2.setValue(QString("eventHis/colum_8"), false); //< 事件内容 - } - } - ui->comboBox->setModel(m_pListWidget1->model()); - ui->comboBox->setView(m_pListWidget1); - ui->comboBox->setLineEdit(m_pLineEdit1); - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - m_pLineEdit1->setReadOnly(true); - connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 - ui->comboBox_2->setModel(m_pListWidget2->model()); - ui->comboBox_2->setView(m_pListWidget2); - ui->comboBox_2->setLineEdit(m_pLineEdit2); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - m_pLineEdit2->setReadOnly(true); - connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); - ui->comboBox_3->setModel(m_pListWidget3->model()); - ui->comboBox_3->setView(m_pListWidget3); - ui->comboBox_3->setLineEdit(m_pLineEdit3); - m_strText3 = tr("请选择告警类型"); - m_pLineEdit3->setText(tr("请选择告警类型")); - m_pLineEdit3->setReadOnly(true); - connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); -} - -void CEventForm::login() -{ - if(!m_isEditMode) - { - CEventDataCollect::instance()->release(); - if(m_pRealTimeModel) - { - m_pRealTimeModel->initialize(); - } - if(m_pHistoryModel) - { - m_pHistoryModel->initialize(); - } - CEventDataCollect::instance()->initialize(); - initFilter(); - if(dynamic_cast(ui->eventView->model())) - { - m_pHistoryModel->loadEventHistoryData(); - setFilterWndInit(); - slotUpdateHISTips(); - } - } -} - -void CEventForm::logout() -{ - if(!m_isEditMode) - { - CEventDataCollect::instance()->release(); - } -} - -void CEventForm::slotShowResult(QString result) -{ - QMessageBox::information( 0, tr("提示"), tr("导出成功")); -} - -void CEventForm::initFilter() -{ - m_pListWidget1->clear(); - m_pListWidget2->clear(); - m_pListWidget3->clear(); - QMap priority = CEventDataCollect::instance()->priorityDescriptionMap(); - QMap location = CEventDataCollect::instance()->locationDescriptionMap(); - QMap alarmType = CEventDataCollect::instance()->alarmTypeDescriptionMap(); - for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); - pItem->setData(Qt::UserRole, it1.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it1.value()); - m_pListWidget1->addItem(pItem); - m_pListWidget1->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); - } - for(QMap::iterator it2 = location.begin();it2 != location.end();++it2) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); - pItem->setData(Qt::UserRole, it2.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it2.value()); - m_pListWidget2->addItem(pItem); - m_pListWidget2->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); - } - for(QMap::iterator it3 = alarmType.begin();it3 != alarmType.end();++it3) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); - pItem->setData(Qt::UserRole, it3.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it3.value()); - m_pListWidget3->addItem(pItem); - m_pListWidget3->setItemWidget(pItem, pCheckBox); - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); - } -} - -void CEventForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) -{ - if(isLevelFilter == true && listLevel.size() > 0) - { - QString strText(""); - for (int i = 0; i < ui->comboBox->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listLevel.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText1 = strText; - m_pLineEdit1->setText(strText); - }else - { - for (int i = 0; i < ui->comboBox->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - } -} - -void CEventForm::setLocationComboBox(bool &isLocationFilter, QList &listLocation) -{ - if(isLocationFilter == true && listLocation.size() > 0) - { - QString strText(""); - for (int i = 0; i < ui->comboBox_2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listLocation.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText2 = strText; - m_pLineEdit2->setText(strText); - }else - { - for (int i = 0; i < ui->comboBox_2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - } -} - -void CEventForm::setEventTypeComboBox(bool &isEventTypeFilter, QList &listEventType) -{ - if(isEventTypeFilter == true && listEventType.size() > 0) - { - QString strText(""); - for (int i = 0; i < ui->comboBox_3->count(); ++i) - { - - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - int nData = pItem->data(Qt::UserRole).toInt(); - if(listEventType.contains(nData)) - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(true); - strText.append(pCheckBox->text()).append(" "); - pCheckBox->blockSignals(false); - }else - { - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - } - m_strText3 = strText; - m_pLineEdit3->setText(strText); - }else - { - for (int i = 0; i < ui->comboBox_3->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText3 = tr("请选择事件状态"); - m_pLineEdit3->setText(tr("请选择事件状态")); - } -} - -void CEventForm::setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) -{ - if(isTimeFilter == true) - { - ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); - }else - { - ui->lineEdit->setText(tr("请选择时间")); - } -} -//切换实时事件和历史事件的时候,会把过滤条件置空 -void CEventForm::setFilterWndInit() -{ - - if(dynamic_cast(ui->eventView->model())) - { - m_priorityList.clear(); - m_locationList.clear(); - m_eventTypeList.clear(); - bool isCheck =false; - m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); - m_pHistoryModel->setLocationFilter(isCheck,m_locationList); - m_pHistoryModel->setEventTypeFilter(isCheck,m_eventTypeList); - }else - { - m_priorityList.clear(); - m_locationList.clear(); - m_eventTypeList.clear(); - bool isCheck =false; - m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); - m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); - m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventTypeList); - } - for (int i = 0; i < ui->comboBox_3->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - for (int i = 0; i < ui->comboBox->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - for (int i = 0; i < ui->comboBox_2->count(); ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - pCheckBox->blockSignals(true); - pCheckBox->setChecked(false); - pCheckBox->blockSignals(false); - } - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - m_strText3 = tr("请选择事件类型"); - m_pLineEdit3->setText(tr("请选择事件类型")); - ui->lineEdit->setText(tr("请选择时间")); -} - -void CEventForm::slotClearRTEvent() -{ - CEventDataCollect::instance()->handleClearRTEvent(); -} - -void CEventForm::slotUpdateModel() -{ - if(dynamic_cast(ui->eventView->model())) - { - ui->eventView->setSortingEnabled(false); - ui->clear->setVisible(false); - ui->eventType->setText(tr("实时事件")); - ui->filter->setText(tr("过滤")); - m_nIsModel = 0;//历史事件 - if(NULL == m_pHistoryModel) - { - m_pHistoryModel = new CEventHistoryModel(this); - - connect(m_pHistoryModel, &CEventHistoryModel::sigPermInvalid, this, &CEventForm::slotPermInvalid); - connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventRequesting, this, &CEventForm::slotUpdateHISTipsRequesting); - connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventSizeChanged, this, &CEventForm::slotUpdateHISTips); - connect(m_pHistoryModel, &CEventHistoryModel::sigHISRecordOutOfRangeTips, this, &CEventForm::slotHISRecordOutOfRangeTips); - } - ui->eventView->setModel(m_pHistoryModel); - QSettings columFlags2("KBD_HMI", "eventHis config"); - for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount(); nColumnIndex++) - { - bool visible = columFlags2.value(QString("eventHis/colum_%1").arg(nColumnIndex)).toBool(); - ui->eventView->setColumnHidden(nColumnIndex, visible); - } - - m_pHistoryModel->loadEventHistoryData(); - setFilterWndInit(); - slotUpdateHISTips(); - } - else - { - ui->eventView->setSortingEnabled(true); - ui->clear->setVisible(true); - ui->eventType->setText(tr("历史事件")); - ui->filter->setText(tr("过滤")); - m_nIsModel = 1;//实时事件 - if(NULL == m_pRealTimeModel) - { - m_pRealTimeModel = new CEventItemModel(this); - connect(ui->eventView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pRealTimeModel, SLOT(sortColumn(int,Qt::SortOrder))); - ui->eventView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); - } - ui->eventView->setModel(m_pRealTimeModel); - QSettings columFlags1("KBD_HMI", "eventReal config"); - for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount(); nColumnIndex++) - { - bool visible = columFlags1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool(); - ui->eventView->setColumnHidden(nColumnIndex, visible); - - } - setFilterWndInit(); - slotUpdateRTTips(); - } -} - -void CEventForm::updateFilter() -{ - CEventFilterDialog filterDlg(this); - - bool isLevelFilter; - QList levelFilter; - bool isLocationFilter; - QList locationFilter; - bool isRegionFilter; - QList regionFilter; - bool isAlarmTypeFilter; - QList typeFilter; - bool deviceTypeFilter; - QString subSystem; - QString deviceType; - bool keywordFilter; - QString keyword; - bool isTimeFilterEnable; - QDateTime startTime; - QDateTime endTime; - if(dynamic_cast(ui->eventView->model())) - { - m_pRealTimeModel->getFilter(isLevelFilter, levelFilter, - isLocationFilter, locationFilter, - isRegionFilter, regionFilter, - isAlarmTypeFilter, typeFilter, - deviceTypeFilter, subSystem, deviceType, - keywordFilter, keyword, - isTimeFilterEnable, startTime, endTime); - } - else if(dynamic_cast(ui->eventView->model())) - { - m_pHistoryModel->getFilter(isLevelFilter, levelFilter, - isLocationFilter, locationFilter, - isRegionFilter, regionFilter, - isAlarmTypeFilter, typeFilter, - deviceTypeFilter, subSystem, deviceType, - keywordFilter, keyword, - isTimeFilterEnable, startTime, endTime); - } - - filterDlg.setLevelFilterEnable(isLevelFilter); - filterDlg.setLevelFilter(levelFilter); - filterDlg.setLocationFilterEnable(isLocationFilter); - filterDlg.setLocationFilter(locationFilter); - filterDlg.setRegionFilterEnable(isRegionFilter); - filterDlg.setRegionFilter(regionFilter); - filterDlg.setAlarmTypeFilterEnable(isAlarmTypeFilter); - filterDlg.setAlarmTypeFilter(typeFilter); - filterDlg.setDeviceFilterEnable(deviceTypeFilter); - filterDlg.setSubSystem(subSystem); - filterDlg.setDeviceType(deviceType); - filterDlg.setkeyWordFilterEnable(keywordFilter); - filterDlg.setkeyWordFilteContent(keyword); - filterDlg.setTimeFilterEnable(isTimeFilterEnable); - filterDlg.setStartTimeFilter(startTime); - filterDlg.setEndTimeFilter(endTime); - connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime)), - this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime))); - filterDlg.exec(); -} - -void CEventForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventTypeFilter, QList listEventType, - bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime) -{ - if(dynamic_cast(ui->eventView->model())) - { - m_pRealTimeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventTypeFilter, listEventType, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime); - setLevelComboBox(isLevelFilter,listLevel); - setLocationComboBox(isLocationFilter,listLocation); - setEventTypeComboBox(isEventTypeFilter,listEventType); - setEventTimeLineEdit(isTimeFilter, startTime, endTime); - slotUpdateRTTips(); - } - else if(dynamic_cast(ui->eventView->model())) - { - m_pHistoryModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventTypeFilter, listEventType, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime); - setLevelComboBox(isLevelFilter,listLevel); - setLocationComboBox(isLocationFilter,listLocation); - setEventTypeComboBox(isEventTypeFilter,listEventType); - setEventTimeLineEdit(isTimeFilter, startTime, endTime); - m_pHistoryModel->loadEventHistoryData(); - } -} - -void CEventForm::slotRTEventStateChanged() -{ - if(dynamic_cast(ui->eventView->model())) - { - slotUpdateRTTips(); - } -} - -void CEventForm::slotUpdateRTTips() -{ - ui->typeLabel->setText(tr("实时事件总数: ")); - if(m_pRealTimeModel) - { - ui->eventCount->setText(QString::number(CEventMsgManage::instance()->getListEventCount())); - } -} - -void CEventForm::slotUpdateHISTipsRequesting() -{ - ui->typeLabel->setText(QString("正在查询历史事件...")); - ui->eventCount->setText(""); -} - -void CEventForm::slotPermInvalid() -{ - QMessageBox::critical(this, tr("错误"), tr("当前用户不具备事件浏览权限"), QMessageBox::Ok); -} - -void CEventForm::slotUpdateHISTips() -{ - ui->typeLabel->setText(tr("历史事件数量: ")); - if(m_pHistoryModel) - { - ui->eventCount->setText(QString::number(m_pHistoryModel->rowCount())); - } -} - -void CEventForm::slotHISRecordOutOfRangeTips(QStringList stDescList) -{ - QString stMess = ""; - for( int index(0);index!=stDescList.size() ; ++index ) - { - stMess += stDescList.at(index); - if(index != stDescList.size()-1) - stMess += "/"; - } - if(stDescList.size() != 0) - { - QMessageBox::information(this, tr("提示"), - QString(tr("%1 历史事件数量超出%2条,未予显示!")).arg(stMess).arg(LIMIT_HIS_RECORD), - QMessageBox::Ok); - } -} - -void CEventForm::print() -{ - //QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); - QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xlsx)");//获取保存路径*.xls - if(!fileName.isEmpty()) - { -// QTableView view(ui->eventView); -// view.setModel(ui->eventView->model()); -// for(int nIndex(0); nIndex < ui->eventView->model()->columnCount(); nIndex++) -// { -// view.setColumnHidden(nIndex, ui->eventView->isColumnHidden(nIndex)); -// view.setColumnWidth(nIndex, ui->eventView->columnWidth(nIndex)); -// } - -// QPrinter printer; -// printer.setPageSize(QPagedPaintDevice::A4); -// printer.setPageOrientation(QPageLayout::Landscape); -// printer.setOutputFileName(fileName); -// printer.setOutputFormat(QPrinter::PdfFormat); - -// CTableViewPrinter viewPrinter(&view); -// viewPrinter.print(&printer); - - if(dynamic_cast(ui->eventView->model())) - { - emit printExcelHis(m_pHistoryModel,fileName); - }else - { - emit printExcel(m_pRealTimeModel,fileName); - } - } -} - -void CEventForm::stateChanged1(int state) -{ - QString strText(""); - m_priorityList.clear(); - int nCount = m_pListWidget1->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget1->item(i); - QWidget *pWidget = m_pListWidget1->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_priorityList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText1 = strText; - m_pLineEdit1->setText(strText); - } - else - { - m_pLineEdit1->clear(); - m_strText1 = tr("请选择优先级"); - m_pLineEdit1->setText(tr("请选择优先级")); - } - bool isCheck = false; - if(dynamic_cast(ui->eventView->model())) - { - if(m_priorityList.size() == 0) - { - m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); - }else - { - isCheck = true; - m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); - } - } - else if(dynamic_cast(ui->eventView->model())) - { - if(m_priorityList.size() == 0) - { - m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); - }else - { - isCheck = true; - m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); - } - m_pHistoryModel->loadEventHistoryData(); - } -} - -void CEventForm::stateChanged2(int state) -{ - QString strText(""); - m_locationList.clear(); - int nCount = m_pListWidget2->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget2->item(i); - QWidget *pWidget = m_pListWidget2->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_locationList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText2 = strText; - m_pLineEdit2->setText(strText); - } - else - { - m_pLineEdit2->clear(); - m_strText2 = tr("请选择位置"); - m_pLineEdit2->setText(tr("请选择位置")); - } - bool isCheck = false; - if(dynamic_cast(ui->eventView->model())) - { - if(m_locationList.size() == 0) - { - m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); - }else - { - isCheck = true; - m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); - } - } - else if(dynamic_cast(ui->eventView->model())) - { - if(m_locationList.size() == 0) - { - m_pHistoryModel->setLocationFilter(isCheck,m_locationList); - }else - { - isCheck = true; - m_pHistoryModel->setLocationFilter(isCheck,m_locationList); - } - m_pHistoryModel->loadEventHistoryData(); - } -} - -void CEventForm::stateChanged3(int state) -{ - QString strText(""); - m_eventTypeList.clear(); - int nCount = m_pListWidget3->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget3->item(i); - QWidget *pWidget = m_pListWidget3->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_eventTypeList.append(nData); - } - } - if (!strText.isEmpty()) - { - m_strText3 = strText; - m_pLineEdit3->setText(strText); - } - else - { - m_pLineEdit3->clear(); - m_strText3 = tr("请选择事件类型"); - m_pLineEdit3->setText(tr("请选择事件类型")); - } - bool isCheck = false; - if(dynamic_cast(ui->eventView->model())) - { - if(m_eventTypeList.size() == 0) - { - m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventTypeList); - }else - { - isCheck = true; - m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventTypeList); - } - } - else if(dynamic_cast(ui->eventView->model())) - { - if(m_eventTypeList.size() == 0) - { - m_pHistoryModel->setEventTypeFilter(isCheck,m_eventTypeList); - }else - { - isCheck = true; - m_pHistoryModel->setEventTypeFilter(isCheck,m_eventTypeList); - } - m_pHistoryModel->loadEventHistoryData(); - } -} - -void CEventForm::textChanged1(const QString &text) -{ - m_pLineEdit1->setText(m_strText1); -} - -void CEventForm::textChanged2(const QString &text) -{ - m_pLineEdit2->setText(m_strText2); -} - -void CEventForm::textChanged3(const QString &text) -{ - m_pLineEdit3->setText(m_strText3); -} - -void CEventForm::myCalendarHide(QDate startTime, QDate endTime) -{ - ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); - //开始过滤 - bool isCheck = false; - if(dynamic_cast(ui->eventView->model())) - { - isCheck = true; - m_pRealTimeModel->setEventTimeFilter(isCheck,startTime,endTime); - }else if(dynamic_cast(ui->eventView->model())) - { - isCheck = true; - m_pHistoryModel->setEventTimeFilter(isCheck,startTime,endTime); - m_pHistoryModel->loadEventHistoryData(); - } - m_timeMenu->hide(); -} - -void CEventForm::myCalendarShow() -{ - QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); - m_timeMenu->move(point); - m_timeMenu->show(); -} - -void CEventForm::cancleTimeFilter() -{ - ui->lineEdit->setText(tr("请选择时间")); - //取消过滤 - bool isCheck = false; - if(dynamic_cast(ui->eventView->model())) - { - m_pRealTimeModel->setEventTimeFilter(isCheck); - }else if(dynamic_cast(ui->eventView->model())) - { - m_pHistoryModel->setEventTimeFilter(isCheck); - m_pHistoryModel->loadEventHistoryData(); - } - m_timeMenu->hide(); -} - -void CEventForm::contextMenuEvent(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - if(event->pos().x() < ui->eventView->pos().x()) - { - return; - } - QRect headerRect = ui->eventView->horizontalHeader()->rect(); - headerRect.moveTopLeft(ui->eventView->mapTo(this, QPoint())); - if(headerRect.contains(event->pos())) - { - QMenu columnMenu(this); - if(m_nIsModel == 1) - { - for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount()-1; nColumnIndex++) - { - QAction * action = columnMenu.addAction(m_pRealTimeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); - action->setCheckable(true); - QSettings columFlags1_1("KBD_HMI", "eventReal config"); - action->setChecked(!columFlags1_1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool()); - - connect(action, &QAction::triggered, [=](){ - - ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags1("KBD_HMI", "eventReal config"); - columFlags1.setValue(QString("eventReal/colum_%1").arg(nColumnIndex), !action->isChecked()); - }); - } - }else - { - for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount()-1; nColumnIndex++) - { - QAction * action = columnMenu.addAction(m_pHistoryModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); - action->setCheckable(true); - action->setChecked(!ui->eventView->isColumnHidden(nColumnIndex)); - connect(action, &QAction::triggered, [=](){ - ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags2("KBD_HMI", "eventHis config"); - columFlags2.setValue(QString("eventHis/colum_%1").arg(nColumnIndex), !action->isChecked()); - }); - } - } - columnMenu.exec(QCursor::pos()); - } -} +#include "CEventForm.h" +#include "ui_CEventForm.h" +#include "CEventMsgInfo.h" +#include +#include "CEventItemModel.h" +#include "CEventHistoryModel.h" +#include "CEventFilterDialog.h" +#include "CEventMsgManage.h" +#include "CEventDataCollect.h" +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + +CEventForm::CEventForm(QWidget *parent, bool editMode) : + QWidget(parent), + m_pRealTimeModel(NULL), + m_pHistoryModel(NULL), + m_isEditMode(editMode), + ui(new Ui::CEventForm) +{ + qRegisterMetaType("CEventMsgInfo"); + qRegisterMetaType("EventMsgPtr"); + + ui->setupUi(this); + m_pListWidget1 = new CMyListWidget(this); + m_pListWidget2 = new CMyListWidget(this); + m_pListWidget3 = new CMyListWidget(this); + m_pLineEdit1 = new QLineEdit(this); + m_pLineEdit2 = new QLineEdit(this); + m_pLineEdit3 = new QLineEdit(this); + initilize(); + if(!m_isEditMode) + { + connect(ui->eventType, &QPushButton::clicked, this, &CEventForm::slotUpdateModel); + CEventDataCollect::instance()->initialize(); + + initFilter(); + slotUpdateModel(); + connect(CEventDataCollect::instance(), SIGNAL(sigEventStateChanged()), this, SLOT(slotRTEventStateChanged()), Qt::QueuedConnection); + connect(ui->clear, &QPushButton::clicked, this, &CEventForm::slotClearRTEvent); + connect(ui->closeBtn, &QPushButton::clicked, this, &CEventForm::closeBtnClicked); + ui->eventView->setColumnWidth(0, 250); + ui->eventView->setColumnWidth(1, 150); + ui->eventView->setColumnWidth(2, 150); + ui->eventView->setColumnWidth(3, 150); + ui->eventView->setColumnWidth(4, 150); + ui->eventView->setColumnWidth(5, 150); + } + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("event.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + m_timeIcon = new QPushButton(this); + m_myCalendar = new CMyCalendar(this); + QWidgetAction *widgetAction=new QWidgetAction(this); + m_timeMenu = new QMenu(this); + widgetAction->setDefaultWidget(m_myCalendar); + m_timeMenu->addAction(widgetAction); + m_timeIcon->setObjectName("iconButton"); + m_timeIcon->setText(""); + m_timeIcon->setMaximumSize(21, 22); + m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_timeIcon); + ui->lineEdit->setLayout(pTimeLayout); + connect(m_timeIcon,&QPushButton::clicked,this,&CEventForm::myCalendarShow); + connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CEventForm::myCalendarHide); + connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CEventForm::cancleTimeFilter); + ui->lineEdit->setText(tr("请选择时间")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit->setObjectName("iconLineEdit"); + + m_excelPrinter = new CExcelPrinter(); + m_thread = new QThread(); + m_excelPrinter->moveToThread(m_thread); + connect(m_thread,&QThread::started,m_excelPrinter,&CExcelPrinter::initialize); + connect(m_thread,&QThread::finished,m_excelPrinter,&CExcelPrinter::deleteLater); + connect(this,&CEventForm::printExcel,m_excelPrinter,&CExcelPrinter::printerByModel); + connect(this,&CEventForm::printExcelHis,m_excelPrinter,&CExcelPrinter::printerHisByModel); + connect(m_excelPrinter,&CExcelPrinter::sigShowResult,this,&CEventForm::slotShowResult); + m_thread->start(); +} + +CEventForm::~CEventForm() +{ + if(m_pRealTimeModel) + { + delete m_pRealTimeModel; + } + m_pRealTimeModel = Q_NULLPTR; + + if(m_pHistoryModel) + { + delete m_pHistoryModel; + } + m_pHistoryModel = Q_NULLPTR; + + delete m_excelPrinter; + m_thread->quit(); + m_thread->wait(); + delete CEventDataCollect::instance(); + delete CEventMsgManage::instance(); + delete ui; + + qDebug() << "~CEventForm()"; +} + +void CEventForm::initilize() +{ + //< lingdaoyaoqiu + { + QSettings columFlags1("KBD_HMI", "eventReal config"); + if(!columFlags1.contains(QString("eventReal/colum_0"))) + { + columFlags1.setValue(QString("eventReal/colum_0"), false); //< 时间 + columFlags1.setValue(QString("eventReal/colum_1"), false); //< 优先级 + columFlags1.setValue(QString("eventReal/colum_2"), false); //< 位置 + columFlags1.setValue(QString("eventReal/colum_3"), true); //< 责任区 + columFlags1.setValue(QString("eventReal/colum_4"), true); //< 事件类型 + columFlags1.setValue(QString("eventReal/colum_5"), false); //< 事件状态 + columFlags1.setValue(QString("eventReal/colum_6"), false); //< 事件内容 + } + } + { + QSettings columFlags2("KBD_HMI", "eventHis config"); + if(!columFlags2.contains(QString("eventHis/colum_0"))) + { + columFlags2.setValue(QString("eventHis/colum_0"), false); //< 时间 + columFlags2.setValue(QString("eventHis/colum_1"), false); //< 优先级 + columFlags2.setValue(QString("eventHis/colum_2"), false); //< 位置 + columFlags2.setValue(QString("eventHis/colum_3"), true); //< 责任区 + columFlags2.setValue(QString("eventHis/colum_4"), true); //< 事件类型 + columFlags2.setValue(QString("eventHis/colum_5"), false); //< 事件状态 + columFlags2.setValue(QString("eventHis/colum_6"), true); //< 确认人 + columFlags2.setValue(QString("eventHis/colum_7"), true); //< 确认时间 + columFlags2.setValue(QString("eventHis/colum_8"), false); //< 事件内容 + } + } + ui->comboBox->setModel(m_pListWidget1->model()); + ui->comboBox->setView(m_pListWidget1); + ui->comboBox->setLineEdit(m_pLineEdit1); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + m_pLineEdit1->setReadOnly(true); + connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 + ui->comboBox_2->setModel(m_pListWidget2->model()); + ui->comboBox_2->setView(m_pListWidget2); + ui->comboBox_2->setLineEdit(m_pLineEdit2); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + m_pLineEdit2->setReadOnly(true); + connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); + ui->comboBox_3->setModel(m_pListWidget3->model()); + ui->comboBox_3->setView(m_pListWidget3); + ui->comboBox_3->setLineEdit(m_pLineEdit3); + m_strText3 = tr("请选择告警类型"); + m_pLineEdit3->setText(tr("请选择告警类型")); + m_pLineEdit3->setReadOnly(true); + connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); +} + +void CEventForm::login() +{ + if(!m_isEditMode) + { + CEventDataCollect::instance()->release(); + if(m_pRealTimeModel) + { + m_pRealTimeModel->initialize(); + } + if(m_pHistoryModel) + { + m_pHistoryModel->initialize(); + } + CEventDataCollect::instance()->initialize(); + initFilter(); + if(dynamic_cast(ui->eventView->model())) + { + m_pHistoryModel->loadEventHistoryData(); + setFilterWndInit(); + slotUpdateHISTips(); + } + } +} + +void CEventForm::logout() +{ + if(!m_isEditMode) + { + CEventDataCollect::instance()->release(); + } +} + +void CEventForm::slotShowResult(QString result) +{ + QMessageBox::information( 0, tr("提示"), tr("导出成功")); +} + +void CEventForm::initFilter() +{ + m_pListWidget1->clear(); + m_pListWidget2->clear(); + m_pListWidget3->clear(); + QMap priority = CEventDataCollect::instance()->priorityDescriptionMap(); + QMap location = CEventDataCollect::instance()->locationDescriptionMap(); + QMap alarmType = CEventDataCollect::instance()->alarmTypeDescriptionMap(); + for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); + pItem->setData(Qt::UserRole, it1.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it1.value()); + m_pListWidget1->addItem(pItem); + m_pListWidget1->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); + } + for(QMap::iterator it2 = location.begin();it2 != location.end();++it2) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); + pItem->setData(Qt::UserRole, it2.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it2.value()); + m_pListWidget2->addItem(pItem); + m_pListWidget2->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); + } + for(QMap::iterator it3 = alarmType.begin();it3 != alarmType.end();++it3) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); + pItem->setData(Qt::UserRole, it3.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it3.value()); + m_pListWidget3->addItem(pItem); + m_pListWidget3->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); + } +} + +void CEventForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) +{ + if(isLevelFilter == true && listLevel.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLevel.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText1 = strText; + m_pLineEdit1->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } +} + +void CEventForm::setLocationComboBox(bool &isLocationFilter, QList &listLocation) +{ + if(isLocationFilter == true && listLocation.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox_2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLocation.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText2 = strText; + m_pLineEdit2->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox_2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } +} + +void CEventForm::setEventTypeComboBox(bool &isEventTypeFilter, QList &listEventType) +{ + if(isEventTypeFilter == true && listEventType.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox_3->count(); ++i) + { + + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listEventType.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText3 = strText; + m_pLineEdit3->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox_3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText3 = tr("请选择事件状态"); + m_pLineEdit3->setText(tr("请选择事件状态")); + } +} + +void CEventForm::setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) +{ + if(isTimeFilter == true) + { + ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); + }else + { + ui->lineEdit->setText(tr("请选择时间")); + } +} +//切换实时事件和历史事件的时候,会把过滤条件置空 +void CEventForm::setFilterWndInit() +{ + + if(dynamic_cast(ui->eventView->model())) + { + m_priorityList.clear(); + m_locationList.clear(); + m_eventTypeList.clear(); + bool isCheck =false; + m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); + m_pHistoryModel->setLocationFilter(isCheck,m_locationList); + m_pHistoryModel->setEventTypeFilter(isCheck,m_eventTypeList); + }else + { + m_priorityList.clear(); + m_locationList.clear(); + m_eventTypeList.clear(); + bool isCheck =false; + m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); + m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); + m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventTypeList); + } + for (int i = 0; i < ui->comboBox_3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + for (int i = 0; i < ui->comboBox->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + for (int i = 0; i < ui->comboBox_2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + m_strText3 = tr("请选择事件类型"); + m_pLineEdit3->setText(tr("请选择事件类型")); + ui->lineEdit->setText(tr("请选择时间")); +} + +void CEventForm::slotClearRTEvent() +{ + CEventDataCollect::instance()->handleClearRTEvent(); +} + +void CEventForm::slotUpdateModel() +{ + if(dynamic_cast(ui->eventView->model())) + { + ui->eventView->setSortingEnabled(false); + ui->clear->setVisible(false); + ui->eventType->setText(tr("实时事件")); + ui->filter->setText(tr("过滤")); + m_nIsModel = 0;//历史事件 + if(NULL == m_pHistoryModel) + { + m_pHistoryModel = new CEventHistoryModel(this); + + connect(m_pHistoryModel, &CEventHistoryModel::sigPermInvalid, this, &CEventForm::slotPermInvalid); + connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventRequesting, this, &CEventForm::slotUpdateHISTipsRequesting); + connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventSizeChanged, this, &CEventForm::slotUpdateHISTips); + connect(m_pHistoryModel, &CEventHistoryModel::sigHISRecordOutOfRangeTips, this, &CEventForm::slotHISRecordOutOfRangeTips); + } + ui->eventView->setModel(m_pHistoryModel); + QSettings columFlags2("KBD_HMI", "eventHis config"); + for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount(); nColumnIndex++) + { + bool visible = columFlags2.value(QString("eventHis/colum_%1").arg(nColumnIndex)).toBool(); + ui->eventView->setColumnHidden(nColumnIndex, visible); + } + + m_pHistoryModel->loadEventHistoryData(); + setFilterWndInit(); + slotUpdateHISTips(); + } + else + { + ui->eventView->setSortingEnabled(true); + ui->clear->setVisible(true); + ui->eventType->setText(tr("历史事件")); + ui->filter->setText(tr("过滤")); + m_nIsModel = 1;//实时事件 + if(NULL == m_pRealTimeModel) + { + m_pRealTimeModel = new CEventItemModel(this); + connect(ui->eventView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pRealTimeModel, SLOT(sortColumn(int,Qt::SortOrder))); + ui->eventView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + } + ui->eventView->setModel(m_pRealTimeModel); + QSettings columFlags1("KBD_HMI", "eventReal config"); + for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount(); nColumnIndex++) + { + bool visible = columFlags1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool(); + ui->eventView->setColumnHidden(nColumnIndex, visible); + + } + setFilterWndInit(); + slotUpdateRTTips(); + } +} + +void CEventForm::updateFilter() +{ + CEventFilterDialog filterDlg(this); + + bool isLevelFilter; + QList levelFilter; + bool isLocationFilter; + QList locationFilter; + bool isRegionFilter; + QList regionFilter; + bool isAlarmTypeFilter; + QList typeFilter; + bool deviceTypeFilter; + QString subSystem; + QString deviceType; + bool keywordFilter; + QString keyword; + bool isTimeFilterEnable; + QDateTime startTime; + QDateTime endTime; + if(dynamic_cast(ui->eventView->model())) + { + m_pRealTimeModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmTypeFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime); + } + else if(dynamic_cast(ui->eventView->model())) + { + m_pHistoryModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmTypeFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime); + } + + filterDlg.setLevelFilterEnable(isLevelFilter); + filterDlg.setLevelFilter(levelFilter); + filterDlg.setLocationFilterEnable(isLocationFilter); + filterDlg.setLocationFilter(locationFilter); + filterDlg.setRegionFilterEnable(isRegionFilter); + filterDlg.setRegionFilter(regionFilter); + filterDlg.setAlarmTypeFilterEnable(isAlarmTypeFilter); + filterDlg.setAlarmTypeFilter(typeFilter); + filterDlg.setDeviceFilterEnable(deviceTypeFilter); + filterDlg.setSubSystem(subSystem); + filterDlg.setDeviceType(deviceType); + filterDlg.setkeyWordFilterEnable(keywordFilter); + filterDlg.setkeyWordFilteContent(keyword); + filterDlg.setTimeFilterEnable(isTimeFilterEnable); + filterDlg.setStartTimeFilter(startTime); + filterDlg.setEndTimeFilter(endTime); + connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime)), + this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime))); + filterDlg.exec(); +} + +void CEventForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventTypeFilter, QList listEventType, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime) +{ + if(dynamic_cast(ui->eventView->model())) + { + m_pRealTimeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventTypeFilter, listEventType, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime); + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setEventTypeComboBox(isEventTypeFilter,listEventType); + setEventTimeLineEdit(isTimeFilter, startTime, endTime); + slotUpdateRTTips(); + } + else if(dynamic_cast(ui->eventView->model())) + { + m_pHistoryModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventTypeFilter, listEventType, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime); + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setEventTypeComboBox(isEventTypeFilter,listEventType); + setEventTimeLineEdit(isTimeFilter, startTime, endTime); + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::slotRTEventStateChanged() +{ + if(dynamic_cast(ui->eventView->model())) + { + slotUpdateRTTips(); + } +} + +void CEventForm::slotUpdateRTTips() +{ + ui->typeLabel->setText(tr("实时事件总数: ")); + if(m_pRealTimeModel) + { + ui->eventCount->setText(QString::number(CEventMsgManage::instance()->getListEventCount())); + } +} + +void CEventForm::slotUpdateHISTipsRequesting() +{ + ui->typeLabel->setText(QString("正在查询历史事件...")); + ui->eventCount->setText(""); +} + +void CEventForm::slotPermInvalid() +{ + QMessageBox::critical(this, tr("错误"), tr("当前用户不具备事件浏览权限"), QMessageBox::Ok); +} + +void CEventForm::slotUpdateHISTips() +{ + ui->typeLabel->setText(tr("历史事件数量: ")); + if(m_pHistoryModel) + { + ui->eventCount->setText(QString::number(m_pHistoryModel->rowCount())); + } +} + +void CEventForm::slotHISRecordOutOfRangeTips(QStringList stDescList) +{ + QString stMess = ""; + for( int index(0);index!=stDescList.size() ; ++index ) + { + stMess += stDescList.at(index); + if(index != stDescList.size()-1) + stMess += "/"; + } + if(stDescList.size() != 0) + { + QMessageBox::information(this, tr("提示"), + QString(tr("%1 历史事件数量超出%2条,未予显示!")).arg(stMess).arg(LIMIT_HIS_RECORD), + QMessageBox::Ok); + } +} + +void CEventForm::print() +{ + //QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); + QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xlsx)");//获取保存路径*.xls + if(!fileName.isEmpty()) + { +// QTableView view(ui->eventView); +// view.setModel(ui->eventView->model()); +// for(int nIndex(0); nIndex < ui->eventView->model()->columnCount(); nIndex++) +// { +// view.setColumnHidden(nIndex, ui->eventView->isColumnHidden(nIndex)); +// view.setColumnWidth(nIndex, ui->eventView->columnWidth(nIndex)); +// } + +// QPrinter printer; +// printer.setPageSize(QPagedPaintDevice::A4); +// printer.setPageOrientation(QPageLayout::Landscape); +// printer.setOutputFileName(fileName); +// printer.setOutputFormat(QPrinter::PdfFormat); + +// CTableViewPrinter viewPrinter(&view); +// viewPrinter.print(&printer); + + if(dynamic_cast(ui->eventView->model())) + { + emit printExcelHis(m_pHistoryModel,fileName); + }else + { + emit printExcel(m_pRealTimeModel,fileName); + } + } +} + +void CEventForm::stateChanged1(int state) +{ + QString strText(""); + m_priorityList.clear(); + int nCount = m_pListWidget1->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_priorityList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText1 = strText; + m_pLineEdit1->setText(strText); + } + else + { + m_pLineEdit1->clear(); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } + bool isCheck = false; + if(dynamic_cast(ui->eventView->model())) + { + if(m_priorityList.size() == 0) + { + m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); + }else + { + isCheck = true; + m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); + } + } + else if(dynamic_cast(ui->eventView->model())) + { + if(m_priorityList.size() == 0) + { + m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); + }else + { + isCheck = true; + m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::stateChanged2(int state) +{ + QString strText(""); + m_locationList.clear(); + int nCount = m_pListWidget2->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_locationList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText2 = strText; + m_pLineEdit2->setText(strText); + } + else + { + m_pLineEdit2->clear(); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } + bool isCheck = false; + if(dynamic_cast(ui->eventView->model())) + { + if(m_locationList.size() == 0) + { + m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); + }else + { + isCheck = true; + m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); + } + } + else if(dynamic_cast(ui->eventView->model())) + { + if(m_locationList.size() == 0) + { + m_pHistoryModel->setLocationFilter(isCheck,m_locationList); + }else + { + isCheck = true; + m_pHistoryModel->setLocationFilter(isCheck,m_locationList); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::stateChanged3(int state) +{ + QString strText(""); + m_eventTypeList.clear(); + int nCount = m_pListWidget3->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_eventTypeList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText3 = strText; + m_pLineEdit3->setText(strText); + } + else + { + m_pLineEdit3->clear(); + m_strText3 = tr("请选择事件类型"); + m_pLineEdit3->setText(tr("请选择事件类型")); + } + bool isCheck = false; + if(dynamic_cast(ui->eventView->model())) + { + if(m_eventTypeList.size() == 0) + { + m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventTypeList); + }else + { + isCheck = true; + m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventTypeList); + } + } + else if(dynamic_cast(ui->eventView->model())) + { + if(m_eventTypeList.size() == 0) + { + m_pHistoryModel->setEventTypeFilter(isCheck,m_eventTypeList); + }else + { + isCheck = true; + m_pHistoryModel->setEventTypeFilter(isCheck,m_eventTypeList); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::textChanged1(const QString &text) +{ + m_pLineEdit1->setText(m_strText1); +} + +void CEventForm::textChanged2(const QString &text) +{ + m_pLineEdit2->setText(m_strText2); +} + +void CEventForm::textChanged3(const QString &text) +{ + m_pLineEdit3->setText(m_strText3); +} + +void CEventForm::myCalendarHide(QDate startTime, QDate endTime) +{ + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); + //开始过滤 + bool isCheck = false; + if(dynamic_cast(ui->eventView->model())) + { + isCheck = true; + m_pRealTimeModel->setEventTimeFilter(isCheck,startTime,endTime); + }else if(dynamic_cast(ui->eventView->model())) + { + isCheck = true; + m_pHistoryModel->setEventTimeFilter(isCheck,startTime,endTime); + m_pHistoryModel->loadEventHistoryData(); + } + m_timeMenu->hide(); +} + +void CEventForm::myCalendarShow() +{ + QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); + m_timeMenu->move(point); + m_timeMenu->show(); +} + +void CEventForm::cancleTimeFilter() +{ + ui->lineEdit->setText(tr("请选择时间")); + //取消过滤 + bool isCheck = false; + if(dynamic_cast(ui->eventView->model())) + { + m_pRealTimeModel->setEventTimeFilter(isCheck); + }else if(dynamic_cast(ui->eventView->model())) + { + m_pHistoryModel->setEventTimeFilter(isCheck); + m_pHistoryModel->loadEventHistoryData(); + } + m_timeMenu->hide(); +} + +void CEventForm::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(event->pos().x() < ui->eventView->pos().x()) + { + return; + } + QRect headerRect = ui->eventView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->eventView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + if(m_nIsModel == 1) + { + for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pRealTimeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + QSettings columFlags1_1("KBD_HMI", "eventReal config"); + action->setChecked(!columFlags1_1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool()); + + connect(action, &QAction::triggered, [=](){ + + ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags1("KBD_HMI", "eventReal config"); + columFlags1.setValue(QString("eventReal/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + }else + { + for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pHistoryModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->eventView->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags2("KBD_HMI", "eventHis config"); + columFlags2.setValue(QString("eventHis/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + } + columnMenu.exec(QCursor::pos()); + } +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventForm.h b/product/src/gui/plugin/ISCSEventWidget/CEventForm.h index a3d63587..fc8bed39 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventForm.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventForm.h @@ -1,107 +1,107 @@ -#ifndef CEventForm_H -#define CEventForm_H - -#include -#include -#include -#include -#include -#include "CMyCalendar.h" -#include "CExcelPrinter.h" -namespace Ui { -class CEventForm; -} - -class CEventDelegate; -class CEventItemModel; -class CEventHistoryModel; -class QAbstractTableModel; - -typedef QList QModelIndexList; - -class CEventForm : public QWidget -{ - Q_OBJECT - -public: - explicit CEventForm(QWidget *parent, bool editMode); - ~CEventForm(); - void initilize(); - -signals: - void closeBtnClicked(); - void printExcel(CEventItemModel *model,QString fileName); - void printExcelHis(CEventHistoryModel *model,QString fileName); -public slots: - void login(); - - void logout(); - - void slotShowResult(QString result); - - -public: - void initFilter(); - void setLevelComboBox(bool &isLevelFilter,QList &listLevel); - void setLocationComboBox(bool &isLocationFilter,QList &listLocation); - void setEventTypeComboBox(bool &isEventTypeFilter,QList &listEventType); - void setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); - void setFilterWndInit(); -protected slots: - void slotClearRTEvent(); - void slotUpdateModel(); - void updateFilter(); - void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventTypeFilter, QList listEventType, - bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, - QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime); - void slotRTEventStateChanged(); - void slotUpdateRTTips(); //< 更新实时数据文本提示 - //< 更新历史数据文本提示 - void slotUpdateHISTipsRequesting(); - void slotPermInvalid(); - void slotUpdateHISTips(); - void slotHISRecordOutOfRangeTips(QStringList stDescList); - void print(); - void stateChanged1(int state); - void stateChanged2(int state); - void stateChanged3(int state); - void textChanged1(const QString &text); - void textChanged2(const QString &text); - void textChanged3(const QString &text); - - void myCalendarHide(QDate startTime, QDate endTime); - void myCalendarShow(); - void cancleTimeFilter(); -protected: - void contextMenuEvent(QContextMenuEvent *event); -private: - Ui::CEventForm *ui; - CEventItemModel * m_pRealTimeModel; - CEventHistoryModel * m_pHistoryModel; - int m_nIsModel; - bool m_isEditMode; - - QListWidget *m_pListWidget1; - QListWidget *m_pListWidget2; - QListWidget *m_pListWidget3; - - QLineEdit *m_pLineEdit1; - QLineEdit *m_pLineEdit2; - QLineEdit *m_pLineEdit3; - QList m_priorityList; - QList m_locationList; - QList m_eventTypeList; - QString m_strText1; - QString m_strText2; - QString m_strText3; - - QPushButton *m_timeIcon; - - CMyCalendar * m_myCalendar; - QMenu *m_timeMenu; - - QThread *m_thread; //打印线程 - CExcelPrinter * m_excelPrinter; -}; - -#endif // CEventForm_H +#ifndef CEventForm_H +#define CEventForm_H + +#include +#include +#include +#include +#include +#include "CMyCalendar.h" +#include "CExcelPrinter.h" +namespace Ui { +class CEventForm; +} + +class CEventDelegate; +class CEventItemModel; +class CEventHistoryModel; +class QAbstractTableModel; + +typedef QList QModelIndexList; + +class CEventForm : public QWidget +{ + Q_OBJECT + +public: + explicit CEventForm(QWidget *parent, bool editMode); + ~CEventForm(); + void initilize(); + +signals: + void closeBtnClicked(); + void printExcel(CEventItemModel *model,QString fileName); + void printExcelHis(CEventHistoryModel *model,QString fileName); +public slots: + void login(); + + void logout(); + + void slotShowResult(QString result); + + +public: + void initFilter(); + void setLevelComboBox(bool &isLevelFilter,QList &listLevel); + void setLocationComboBox(bool &isLocationFilter,QList &listLocation); + void setEventTypeComboBox(bool &isEventTypeFilter,QList &listEventType); + void setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); + void setFilterWndInit(); +protected slots: + void slotClearRTEvent(); + void slotUpdateModel(); + void updateFilter(); + void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventTypeFilter, QList listEventType, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, + QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime); + void slotRTEventStateChanged(); + void slotUpdateRTTips(); //< 更新实时数据文本提示 + //< 更新历史数据文本提示 + void slotUpdateHISTipsRequesting(); + void slotPermInvalid(); + void slotUpdateHISTips(); + void slotHISRecordOutOfRangeTips(QStringList stDescList); + void print(); + void stateChanged1(int state); + void stateChanged2(int state); + void stateChanged3(int state); + void textChanged1(const QString &text); + void textChanged2(const QString &text); + void textChanged3(const QString &text); + + void myCalendarHide(QDate startTime, QDate endTime); + void myCalendarShow(); + void cancleTimeFilter(); +protected: + void contextMenuEvent(QContextMenuEvent *event); +private: + Ui::CEventForm *ui; + CEventItemModel * m_pRealTimeModel; + CEventHistoryModel * m_pHistoryModel; + int m_nIsModel; + bool m_isEditMode; + + QListWidget *m_pListWidget1; + QListWidget *m_pListWidget2; + QListWidget *m_pListWidget3; + + QLineEdit *m_pLineEdit1; + QLineEdit *m_pLineEdit2; + QLineEdit *m_pLineEdit3; + QList m_priorityList; + QList m_locationList; + QList m_eventTypeList; + QString m_strText1; + QString m_strText2; + QString m_strText3; + + QPushButton *m_timeIcon; + + CMyCalendar * m_myCalendar; + QMenu *m_timeMenu; + + QThread *m_thread; //打印线程 + CExcelPrinter * m_excelPrinter; +}; + +#endif // CEventForm_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventForm.ui b/product/src/gui/plugin/ISCSEventWidget/CEventForm.ui index 3fc28452..f4ed71b1 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventForm.ui +++ b/product/src/gui/plugin/ISCSEventWidget/CEventForm.ui @@ -1,422 +1,422 @@ - - - CEventForm - - - - 0 - 0 - 1080 - 515 - - - - 事件 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - 0 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - 4 - - - 0 - - - 4 - - - 6 - - - 2 - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 位置: - - - - - - - - 130 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 时间: - - - - - - - Qt::Horizontal - - - - 682 - 20 - - - - - - - - - 45 - 26 - - - - 过滤 - - - - - - - - 45 - 26 - - - - 清空 - - - - - - - - 45 - 26 - - - - 导出 - - - - - - - - 110 - 0 - - - - - 16777215 - 26 - - - - - - - - - 110 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 优先级: - - - - - - - - 45 - 26 - - - - 关闭 - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 事件类型: - - - - - - - - 170 - 0 - - - - - 16777215 - 26 - - - - - - - - - - - 600 - 300 - - - - QFrame::Sunken - - - false - - - false - - - - - - - - - - - - 0 - 0 - - - - 事件总数: - - - Qt::AutoText - - - false - - - - - - - - 30 - 0 - - - - 0 - - - - - - - - - Qt::Horizontal - - - - 438 - 20 - - - - - - - - - 100 - 0 - - - - - - - - - - - - - - - - - CEventView - QTableView -
CEventView.h
-
-
- - - - filter - clicked() - CEventForm - updateFilter() - - - 650 - 25 - - - 599 - 0 - - - - - print - clicked() - CEventForm - print() - - - 722 - 21 - - - 743 - 21 - - - - - - updateFilter() - print() - -
+ + + CEventForm + + + + 0 + 0 + 1080 + 515 + + + + 事件 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 4 + + + 0 + + + 4 + + + 6 + + + 2 + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 位置: + + + + + + + + 130 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 时间: + + + + + + + Qt::Horizontal + + + + 682 + 20 + + + + + + + + + 45 + 26 + + + + 过滤 + + + + + + + + 45 + 26 + + + + 清空 + + + + + + + + 45 + 26 + + + + 导出 + + + + + + + + 110 + 0 + + + + + 16777215 + 26 + + + + + + + + + 110 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 优先级: + + + + + + + + 45 + 26 + + + + 关闭 + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 事件类型: + + + + + + + + 170 + 0 + + + + + 16777215 + 26 + + + + + + + + + + + 600 + 300 + + + + QFrame::Sunken + + + false + + + false + + + + + + + + + + + + 0 + 0 + + + + 事件总数: + + + Qt::AutoText + + + false + + + + + + + + 30 + 0 + + + + 0 + + + + + + + + + Qt::Horizontal + + + + 438 + 20 + + + + + + + + + 100 + 0 + + + + + + + + + + + + + + + + + CEventView + QTableView +
CEventView.h
+
+
+ + + + filter + clicked() + CEventForm + updateFilter() + + + 650 + 25 + + + 599 + 0 + + + + + print + clicked() + CEventForm + print() + + + 722 + 21 + + + 743 + 21 + + + + + + updateFilter() + print() + +
diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventHistoryModel.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventHistoryModel.cpp index aaf60341..9c0c69d9 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventHistoryModel.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventHistoryModel.cpp @@ -1,641 +1,641 @@ -#include "CEventHistoryModel.h" -#include "CEventMsgInfo.h" -#include -#include -#include -#include "CEventDataCollect.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" -#include "perm_mng_api/PermMngApi.h" -#include "service/alarm_server_api/AlarmCommonDef.h" -#include "CEventMsgManage.h" -///////////////////////////////////////////////////////////////////////////// - -typedef QPair > PAIRLISTALARMINFO; - -CEventHistoryModel::CEventHistoryModel(QObject *parent) - :QAbstractTableModel(parent), - m_sortKey(E_SORT_PRIORITY), - m_order(Qt::AscendingOrder) -{ - header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("确认人")<< tr("确认时间") << tr("事件内容"); - connect(this, &CEventHistoryModel::requestHistoryEvents, CEventDataCollect::instance(), &CEventDataCollect::queryHistoryEvent, Qt::QueuedConnection); - connect(CEventDataCollect::instance(), &CEventDataCollect::sigUpdateHistoryEvent, this, &CEventHistoryModel::updateListEvents, Qt::QueuedConnection); - initialize(); -} - -CEventHistoryModel::~CEventHistoryModel() -{ - m_listShowEventInfo.clear(); -} - -void CEventHistoryModel::initialize() -{ - beginResetModel(); - m_listShowEventInfo.clear(); - endResetModel(); - initFilter(); -} - -void CEventHistoryModel::initFilter() -{ - m_isLevelFilterEnable = false; - m_isLocationFilterEnable = false; - m_isRegionFilterEnable = false; - m_isTypeFilterEnable = false; - m_isDeviceTypeFileter = false; - m_isKeywordEnable = false; - m_timeFilterEnable = false; - - // m_isLevelFilterEnable = false; - // m_levelFilter = CEventDataCollect::instance()->priorityList(); - // m_isLocationFilterEnable = false; - // m_locationFilter = CEventDataCollect::instance()->locationList(); - // m_isRegionFilterEnable = false; - // m_regionFilter = CEventDataCollect::instance()->regionList(); - // m_isTypeFilterEnable = false; - // m_typeFilter = CEventDataCollect::instance()->alarmTypeList(); - // setFilter(m_isLevelFilterEnable, m_levelFilter, m_isLocationFilterEnable, m_locationFilter, m_isRegionFilterEnable, m_regionFilter, m_isTypeFilterEnable, m_typeFilter); -} - -void CEventHistoryModel::loadEventHistoryData() -{ - //< 权限判断 - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecLocationId; - std::vector vecRegionId; - if( PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - emit sigPermInvalid(); - return; - } - } - - //< 报警类型 - QStringList listHistoryEventTableName; - listHistoryEventTableName.append("his_event"); - emit sigHisEventRequesting(); - QString strCondition = bulidCondition(); - LOGDEBUG("%s",strCondition.toStdString().c_str()); - emit requestHistoryEvents(listHistoryEventTableName, strCondition); -} - -QString CEventHistoryModel::bulidCondition() -{ - QString conditionFilter; - - //< 内容 - QString content = bulidConditionPartContent(); - if(!content.isEmpty()) - { - conditionFilter += content; - } - - //< 等级 - QString priority = bulidConditionPartPriority(); - if(!conditionFilter.isEmpty() && !priority.isEmpty()) - { - conditionFilter += " AND "; - } - if(!priority.isEmpty()) - { - conditionFilter += priority; - } - //< 类型 - QString status = bulidConditionPartType(); - if(!conditionFilter.isEmpty() && !status.isEmpty()) - { - conditionFilter += " AND "; - } - if(!status.isEmpty()) - { - conditionFilter += status; - } - LOGDEBUG("bulidConditionPartStatus():[%s]",status.toStdString().c_str()); - //< 车站 - - // kbd_public::SNodeInfo stNodeInfo; - // kbd_public::SLocationInfo stLocationInfo; - // kbd_public::CSysInfoInterfacePtr spSysInfo; - // if (kbd_public::createSysInfoInstance(spSysInfo)) - // { - // spSysInfo->getLocalNodeInfo(stNodeInfo); - // spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); - // } - // else - // { - // LOGERROR("历史事件-无法获取位置信息...") - - // } - // bool bIsCenter = stLocationInfo.bIsCenter; - // int nLocationId = stNodeInfo.nLocationId; - - // QString location_id; - // if(bIsCenter) - // { - // location_id = bulidConditionPartInteger(m_isLocationFilterEnable, "location_id", m_locationFilter); - // } - // else - // { - // QList location; - // location.append(nLocationId); - // location_id = bulidConditionPartInteger(true, "location_id", location); - // } - QString location_id = bulidConditionPartLocation(); - if(!conditionFilter.isEmpty() && !location_id.isEmpty()) - { - conditionFilter += " AND "; - } - if(!location_id.isEmpty()) - { - conditionFilter += location_id; - } - - //< 责任区 - QString region_id = bulidConditionPartRegion(); - if(!conditionFilter.isEmpty() && !region_id.isEmpty()) - { - conditionFilter += " AND "; - } - if(!region_id.isEmpty()) - { - conditionFilter += region_id; - } - - //< 设备类型 - QString device_type = bulidConditionPartDeviceType(); - if(!conditionFilter.isEmpty() && !device_type.isEmpty()) - { - conditionFilter += " AND "; - } - if(!device_type.isEmpty()) - { - conditionFilter += device_type; - } - - //< 时标 - QString time_stamp = bulidConditionPartDateTime(); - if(!conditionFilter.isEmpty() && !time_stamp.isEmpty()) - { - conditionFilter += " AND "; - } - if(!time_stamp.isEmpty()) - { - conditionFilter += time_stamp; - } - - return conditionFilter; -} - -QString CEventHistoryModel::bulidConditionPartPriority() -{ - if(m_isLevelFilterEnable) - { - QString strFilter; - for(int nIndex = 0; nIndex < m_levelFilter.size(); nIndex++) - { - strFilter.append(QString::number(m_levelFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); - } - return strFilter; - } - return QString(); -} - -QString CEventHistoryModel::bulidConditionPartType() -{ - if(m_isTypeFilterEnable) - { - QString strFilter; - for(int nIndex = 0; nIndex < m_typeFilter.size(); nIndex++) - { - strFilter.append(QString::number(m_typeFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("alm_type").arg(strFilter); - } - return strFilter; - } - return QString(); -} - -QString CEventHistoryModel::bulidConditionPartLocation() -{ - QList locationFilter; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecLocationId; - std::vector vecRegionId; - if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - if(m_isLocationFilterEnable) - { - std::vector ::iterator location = vecLocationId.begin(); - while (location != vecLocationId.end()) - { - if(m_locationFilter.contains(*location)) - { - locationFilter.append(*location); - } - location++; - } - } - else - { - locationFilter = QVector::fromStdVector(vecLocationId).toList(); - } - } - else - { - return QString(); - } - } - - QString strFilter; - for(int nIndex = 0; nIndex < locationFilter.size(); nIndex++) - { - strFilter.append(QString::number(locationFilter.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); - }else - { - strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); - } - return strFilter; -} - -QString CEventHistoryModel::bulidConditionPartRegion() -{ - QList regionFilter; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::vector vecLocationId; - std::vector vecRegionId; - if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) - { - if(m_isRegionFilterEnable) - { - std::vector ::iterator region = vecRegionId.begin(); - while (region != vecRegionId.end()) - { - if(m_regionFilter.contains(*region)) - { - regionFilter.append(*region); - } - region++; - } - } - else - { - regionFilter = QVector::fromStdVector(vecRegionId).toList(); - } - } - else - { - return QString(); - } - } - - - QString strFilter; - for(int nIndex = 0; nIndex < regionFilter.size(); nIndex++) - { - strFilter.append(QString::number(regionFilter.at(nIndex)) + ", "); - } - strFilter.append(QString::number(0) + ", ");//防止责任区为空 - strFilter.append(QString::number(-1) + ", ");//防止责任区为空 - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); - }else - { - strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); - } - return strFilter; -} - -QString CEventHistoryModel::bulidConditionPartDeviceType() -{ - if(m_isDeviceTypeFileter) - { - return QString("(%1 = %2)").arg("dev_type").arg(CEventDataCollect::instance()->deviceTypeId(m_deviceType)); - } - return QString(); -} - -QString CEventHistoryModel::bulidConditionPartContent() -{ - if(m_isKeywordEnable && !m_keyword.isEmpty()) - { - QString strFilter = QString("(%1 like '%" ).arg("content") + m_keyword + QString("%')"); - return strFilter; - } - return QString(); -} - -QString CEventHistoryModel::bulidConditionPartDateTime() -{ - if(m_timeFilterEnable) - { - qint64 start_timeStamp = m_startTime.toMSecsSinceEpoch(); - qint64 end_timeStamp = m_endTime.toMSecsSinceEpoch(); - QString strFilter = QString("(%1 between %2 AND %3)").arg("time_stamp").arg(start_timeStamp).arg(end_timeStamp); - return strFilter; - } - return QString(); -} - -EventMsgPtr CEventHistoryModel::getAlarmInfo(const QModelIndex &index) const -{ - if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) - { - return NULL; - } - - return m_listShowEventInfo.at(index.row()); -} - -QVariant CEventHistoryModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(header.at(section)); - } - return QVariant(); -} - -QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == 8) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - } - else if(Qt::DisplayRole == role) - { - - switch ( index.column() ) - { - case 0 : - { - return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - case 1 : - { - return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); - } - case 2 : - { - return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); - } - case 3 : - { - return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); - } - case 4 : - { - return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); - } - case 5 : - { - return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); - } - case 6 : - { - return CEventDataCollect::instance()->userNameDescription(m_listShowEventInfo.at(index.row())->cfm_user); - } - case 7 : - { - if(m_listShowEventInfo.at(index.row())->cfm_time == 0) - { - return tr(""); - }else - { - return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->cfm_time).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - } - case 8 : - { - return m_listShowEventInfo.at(index.row())->content; - } - default: - return QVariant(); - } - } - return QVariant(); -} - -int CEventHistoryModel::columnCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - - return header.count(); -} - -int CEventHistoryModel::rowCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - return m_listShowEventInfo.count(); -} - -Qt::ItemFlags CEventHistoryModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CEventHistoryModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, - const bool &isKeywordFilterEnable, const QString &keyword, - const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime) -{ - m_isLevelFilterEnable = isLevelFilterEnable; - m_levelFilter = levelFilter; - m_isLocationFilterEnable = isStationFilterEnable; - m_locationFilter = stationFilter; - m_isRegionFilterEnable = isRegionFilterEnable; - m_regionFilter = regionFilter; - m_isTypeFilterEnable = isTypeFilterEnable; - m_typeFilter = typeFilter; - m_isDeviceTypeFileter = isDeviceTypeFilter; - m_subSystem = subSystem; - m_deviceType = deviceType; - m_isKeywordEnable = isKeywordFilterEnable; - m_keyword = keyword; - m_timeFilterEnable = timeFilterEnable; - m_startTime = startTime; - m_endTime = endTime; -} - -void CEventHistoryModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime) -{ - isLevelFilterEnable = m_isLevelFilterEnable; - levelFilter = m_levelFilter; - isLocationFilterEnable = m_isLocationFilterEnable; - locationFilter = m_locationFilter; - isRegionFilterEnable = m_isRegionFilterEnable; - regionFilter = m_regionFilter; - isTypeFilterEnable = m_isTypeFilterEnable; - alarmTypeFilter = m_typeFilter; - subSystem = m_subSystem; - deviceTypeFilter = m_isDeviceTypeFileter; - deviceType = m_deviceType; - keywordFilterEnable = m_isKeywordEnable; - keyword = m_keyword; - timeFilterEnable = m_timeFilterEnable; - startTime = m_startTime; - endTime = m_endTime; -} - -bool CEventHistoryModel::conditionFilter(EventMsgPtr info) -{ - if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) - { - return false; - } - if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) - { - return false; - } - - if(m_isRegionFilterEnable) - { - if(!m_regionFilter.contains(info->region_id)) - { - return false; - } - } - else - { - if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 - { - return false; - } - } - //事件状态过滤 - if(m_isTypeFilterEnable && !m_typeFilter.contains(info->alm_type)) - { - return false; - } - if(m_isDeviceTypeFileter) - { - if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) - { - return false; - } - } - if(m_isKeywordEnable) - { - if(!info->content.contains(m_keyword)) - { - return false; - } - } - if(m_timeFilterEnable) - { - if(m_startTime.toMSecsSinceEpoch() >= (qint64)info->time_stamp) - { - return false; - } - if(m_endTime.toMSecsSinceEpoch() <= (qint64)info->time_stamp) - { - return false; - } - } - return true; -} - -void CEventHistoryModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - m_isLevelFilterEnable = isCheck; - m_levelFilter = priorityFilter; -} - -void CEventHistoryModel::setLocationFilter(bool &isCheck, QList &locationFilter) -{ - m_isLocationFilterEnable = isCheck; - m_locationFilter = locationFilter; -} - -void CEventHistoryModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter) -{ - m_isTypeFilterEnable = isCheck; - m_typeFilter = eventTypeFilter; -} - -void CEventHistoryModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) -{ - m_timeFilterEnable = isCheck; - if(isCheck) - { - QTime time_1(0,0,0); - QTime time_2(23,59,59); - m_startTime.setDate(startTime); - m_startTime.setTime(time_1); - m_endTime.setDate(endTime); - m_endTime.setTime(time_2); - } -} - -void CEventHistoryModel::setEventTimeFilter(bool &isCheck) -{ - m_timeFilterEnable = isCheck; -} - -void CEventHistoryModel::updateListEvents(const QList &listEvents, QStringList stDescList) -{ - beginResetModel(); - m_listShowEventInfo.clear(); - m_listShowEventInfo = listEvents; - endResetModel(); - emit sigHisEventSizeChanged(); - emit sigHISRecordOutOfRangeTips(stDescList); -} +#include "CEventHistoryModel.h" +#include "CEventMsgInfo.h" +#include +#include +#include +#include "CEventDataCollect.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include "perm_mng_api/PermMngApi.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include "CEventMsgManage.h" +///////////////////////////////////////////////////////////////////////////// + +typedef QPair > PAIRLISTALARMINFO; + +CEventHistoryModel::CEventHistoryModel(QObject *parent) + :QAbstractTableModel(parent), + m_sortKey(E_SORT_PRIORITY), + m_order(Qt::AscendingOrder) +{ + header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("确认人")<< tr("确认时间") << tr("事件内容"); + connect(this, &CEventHistoryModel::requestHistoryEvents, CEventDataCollect::instance(), &CEventDataCollect::queryHistoryEvent, Qt::QueuedConnection); + connect(CEventDataCollect::instance(), &CEventDataCollect::sigUpdateHistoryEvent, this, &CEventHistoryModel::updateListEvents, Qt::QueuedConnection); + initialize(); +} + +CEventHistoryModel::~CEventHistoryModel() +{ + m_listShowEventInfo.clear(); +} + +void CEventHistoryModel::initialize() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + endResetModel(); + initFilter(); +} + +void CEventHistoryModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_isLocationFilterEnable = false; + m_isRegionFilterEnable = false; + m_isTypeFilterEnable = false; + m_isDeviceTypeFileter = false; + m_isKeywordEnable = false; + m_timeFilterEnable = false; + + // m_isLevelFilterEnable = false; + // m_levelFilter = CEventDataCollect::instance()->priorityList(); + // m_isLocationFilterEnable = false; + // m_locationFilter = CEventDataCollect::instance()->locationList(); + // m_isRegionFilterEnable = false; + // m_regionFilter = CEventDataCollect::instance()->regionList(); + // m_isTypeFilterEnable = false; + // m_typeFilter = CEventDataCollect::instance()->alarmTypeList(); + // setFilter(m_isLevelFilterEnable, m_levelFilter, m_isLocationFilterEnable, m_locationFilter, m_isRegionFilterEnable, m_regionFilter, m_isTypeFilterEnable, m_typeFilter); +} + +void CEventHistoryModel::loadEventHistoryData() +{ + //< 权限判断 + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if( PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + emit sigPermInvalid(); + return; + } + } + + //< 报警类型 + QStringList listHistoryEventTableName; + listHistoryEventTableName.append("his_event"); + emit sigHisEventRequesting(); + QString strCondition = bulidCondition(); + LOGDEBUG("%s",strCondition.toStdString().c_str()); + emit requestHistoryEvents(listHistoryEventTableName, strCondition); +} + +QString CEventHistoryModel::bulidCondition() +{ + QString conditionFilter; + + //< 内容 + QString content = bulidConditionPartContent(); + if(!content.isEmpty()) + { + conditionFilter += content; + } + + //< 等级 + QString priority = bulidConditionPartPriority(); + if(!conditionFilter.isEmpty() && !priority.isEmpty()) + { + conditionFilter += " AND "; + } + if(!priority.isEmpty()) + { + conditionFilter += priority; + } + //< 类型 + QString status = bulidConditionPartType(); + if(!conditionFilter.isEmpty() && !status.isEmpty()) + { + conditionFilter += " AND "; + } + if(!status.isEmpty()) + { + conditionFilter += status; + } + LOGDEBUG("bulidConditionPartStatus():[%s]",status.toStdString().c_str()); + //< 车站 + + // kbd_public::SNodeInfo stNodeInfo; + // kbd_public::SLocationInfo stLocationInfo; + // kbd_public::CSysInfoInterfacePtr spSysInfo; + // if (kbd_public::createSysInfoInstance(spSysInfo)) + // { + // spSysInfo->getLocalNodeInfo(stNodeInfo); + // spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); + // } + // else + // { + // LOGERROR("历史事件-无法获取位置信息...") + + // } + // bool bIsCenter = stLocationInfo.bIsCenter; + // int nLocationId = stNodeInfo.nLocationId; + + // QString location_id; + // if(bIsCenter) + // { + // location_id = bulidConditionPartInteger(m_isLocationFilterEnable, "location_id", m_locationFilter); + // } + // else + // { + // QList location; + // location.append(nLocationId); + // location_id = bulidConditionPartInteger(true, "location_id", location); + // } + QString location_id = bulidConditionPartLocation(); + if(!conditionFilter.isEmpty() && !location_id.isEmpty()) + { + conditionFilter += " AND "; + } + if(!location_id.isEmpty()) + { + conditionFilter += location_id; + } + + //< 责任区 + QString region_id = bulidConditionPartRegion(); + if(!conditionFilter.isEmpty() && !region_id.isEmpty()) + { + conditionFilter += " AND "; + } + if(!region_id.isEmpty()) + { + conditionFilter += region_id; + } + + //< 设备类型 + QString device_type = bulidConditionPartDeviceType(); + if(!conditionFilter.isEmpty() && !device_type.isEmpty()) + { + conditionFilter += " AND "; + } + if(!device_type.isEmpty()) + { + conditionFilter += device_type; + } + + //< 时标 + QString time_stamp = bulidConditionPartDateTime(); + if(!conditionFilter.isEmpty() && !time_stamp.isEmpty()) + { + conditionFilter += " AND "; + } + if(!time_stamp.isEmpty()) + { + conditionFilter += time_stamp; + } + + return conditionFilter; +} + +QString CEventHistoryModel::bulidConditionPartPriority() +{ + if(m_isLevelFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_levelFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_levelFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartType() +{ + if(m_isTypeFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_typeFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_typeFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("alm_type").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartLocation() +{ + QList locationFilter; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_isLocationFilterEnable) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + if(m_locationFilter.contains(*location)) + { + locationFilter.append(*location); + } + location++; + } + } + else + { + locationFilter = QVector::fromStdVector(vecLocationId).toList(); + } + } + else + { + return QString(); + } + } + + QString strFilter; + for(int nIndex = 0; nIndex < locationFilter.size(); nIndex++) + { + strFilter.append(QString::number(locationFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); + }else + { + strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); + } + return strFilter; +} + +QString CEventHistoryModel::bulidConditionPartRegion() +{ + QList regionFilter; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_isRegionFilterEnable) + { + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + if(m_regionFilter.contains(*region)) + { + regionFilter.append(*region); + } + region++; + } + } + else + { + regionFilter = QVector::fromStdVector(vecRegionId).toList(); + } + } + else + { + return QString(); + } + } + + + QString strFilter; + for(int nIndex = 0; nIndex < regionFilter.size(); nIndex++) + { + strFilter.append(QString::number(regionFilter.at(nIndex)) + ", "); + } + strFilter.append(QString::number(0) + ", ");//防止责任区为空 + strFilter.append(QString::number(-1) + ", ");//防止责任区为空 + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); + }else + { + strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); + } + return strFilter; +} + +QString CEventHistoryModel::bulidConditionPartDeviceType() +{ + if(m_isDeviceTypeFileter) + { + return QString("(%1 = %2)").arg("dev_type").arg(CEventDataCollect::instance()->deviceTypeId(m_deviceType)); + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartContent() +{ + if(m_isKeywordEnable && !m_keyword.isEmpty()) + { + QString strFilter = QString("(%1 like '%" ).arg("content") + m_keyword + QString("%')"); + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartDateTime() +{ + if(m_timeFilterEnable) + { + qint64 start_timeStamp = m_startTime.toMSecsSinceEpoch(); + qint64 end_timeStamp = m_endTime.toMSecsSinceEpoch(); + QString strFilter = QString("(%1 between %2 AND %3)").arg("time_stamp").arg(start_timeStamp).arg(end_timeStamp); + return strFilter; + } + return QString(); +} + +EventMsgPtr CEventHistoryModel::getAlarmInfo(const QModelIndex &index) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return NULL; + } + + return m_listShowEventInfo.at(index.row()); +} + +QVariant CEventHistoryModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(header.at(section)); + } + return QVariant(); +} + +QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == 8) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + } + else if(Qt::DisplayRole == role) + { + + switch ( index.column() ) + { + case 0 : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case 1 : + { + return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); + } + case 2 : + { + return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); + } + case 3 : + { + return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); + } + case 4 : + { + return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); + } + case 5 : + { + return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); + } + case 6 : + { + return CEventDataCollect::instance()->userNameDescription(m_listShowEventInfo.at(index.row())->cfm_user); + } + case 7 : + { + if(m_listShowEventInfo.at(index.row())->cfm_time == 0) + { + return tr(""); + }else + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->cfm_time).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + } + case 8 : + { + return m_listShowEventInfo.at(index.row())->content; + } + default: + return QVariant(); + } + } + return QVariant(); +} + +int CEventHistoryModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return header.count(); +} + +int CEventHistoryModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + return m_listShowEventInfo.count(); +} + +Qt::ItemFlags CEventHistoryModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CEventHistoryModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isTypeFilterEnable = isTypeFilterEnable; + m_typeFilter = typeFilter; + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyword = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; +} + +void CEventHistoryModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isTypeFilterEnable = m_isTypeFilterEnable; + alarmTypeFilter = m_typeFilter; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyword; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; +} + +bool CEventHistoryModel::conditionFilter(EventMsgPtr info) +{ + if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) + { + return false; + } + if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) + { + return false; + } + + if(m_isRegionFilterEnable) + { + if(!m_regionFilter.contains(info->region_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 + { + return false; + } + } + //事件状态过滤 + if(m_isTypeFilterEnable && !m_typeFilter.contains(info->alm_type)) + { + return false; + } + if(m_isDeviceTypeFileter) + { + if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) + { + return false; + } + } + if(m_isKeywordEnable) + { + if(!info->content.contains(m_keyword)) + { + return false; + } + } + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() >= (qint64)info->time_stamp) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() <= (qint64)info->time_stamp) + { + return false; + } + } + return true; +} + +void CEventHistoryModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; +} + +void CEventHistoryModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; +} + +void CEventHistoryModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter) +{ + m_isTypeFilterEnable = isCheck; + m_typeFilter = eventTypeFilter; +} + +void CEventHistoryModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } +} + +void CEventHistoryModel::setEventTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; +} + +void CEventHistoryModel::updateListEvents(const QList &listEvents, QStringList stDescList) +{ + beginResetModel(); + m_listShowEventInfo.clear(); + m_listShowEventInfo = listEvents; + endResetModel(); + emit sigHisEventSizeChanged(); + emit sigHISRecordOutOfRangeTips(stDescList); +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventHistoryModel.h b/product/src/gui/plugin/ISCSEventWidget/CEventHistoryModel.h index e7151b44..726e5776 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventHistoryModel.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventHistoryModel.h @@ -1,116 +1,116 @@ -#ifndef CEVENTHISTORYMODEL_H -#define CEVENTHISTORYMODEL_H - -#include -#include "CEventMsgInfo.h" -#include "CEventDataCollect.h" -#include - -#define Row_Full (15000) -#define MAX_HIS_ROWCOUNT (10000) - -class CEventMsgInfo; - -class CEventHistoryModel : public QAbstractTableModel -{ - Q_OBJECT -public: - CEventHistoryModel(QObject *parent = Q_NULLPTR); - ~CEventHistoryModel(); - - void initialize(); - void initFilter(); - - void loadEventHistoryData(); - - QString bulidCondition(); - QString bulidConditionPartPriority(); - QString bulidConditionPartType(); - QString bulidConditionPartLocation(); - QString bulidConditionPartRegion(); - QString bulidConditionPartDeviceType(); - QString bulidConditionPartContent(); - QString bulidConditionPartDateTime(); - - EventMsgPtr getAlarmInfo(const QModelIndex &index) const; - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual int columnCount(const QModelIndex &index = QModelIndex()) const; - virtual int rowCount(const QModelIndex &index = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - - /** - * 设置模型数据过滤条件,过滤显示数据 - */ - void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), - const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), - const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), - const QDateTime &endTime = QDateTime()); - - /** - * 获取模型数据过滤条件,用于初始化过滤对话框 - */ - void getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime); - - bool conditionFilter(EventMsgPtr info); - - void setPriorityFilter(bool &isCheck, QList &priorityFilter); - void setLocationFilter(bool &isCheck, QList &locationFilter); - void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter); - void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); - void setEventTimeFilter(bool &isCheck); -signals: - //void requestHistoryEvents(const QStringList &listHistoryEventTableName,QList typeFilter, const QString &conditionFilter); - void requestHistoryEvents(const QStringList &listHistoryEventTableName, const QString &conditionFilter); - void sigPermInvalid(); - void sigHisEventRequesting(); - void sigHisEventSizeChanged(); - void sigHISRecordOutOfRangeTips(QStringList stDescList); - -public slots: - void updateListEvents(const QList &listEvents, QStringList stDescList); - -private: - QStringList header; - QList m_listShowEventInfo; - - QList m_listPermLocationId; - QList m_listPermRegionId; - - E_ALARM_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - - //Filter - bool m_isLevelFilterEnable; //是否按报警级别过滤 - QList m_levelFilter; //报警级别过滤 - bool m_isLocationFilterEnable; //是否按车站过滤 - QList m_locationFilter; //车站过滤 - bool m_isRegionFilterEnable; //是否按责任区过滤 - QList m_regionFilter; //责任区过滤 - bool m_isTypeFilterEnable; - QList m_typeFilter; -// bool m_isStatusFilterEnable; //是否按报警类型过滤 -// QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) -// QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) - bool m_isDeviceTypeFileter; //设备类型过滤 - QString m_subSystem; //子系统 - QString m_deviceType; //设备类型 - bool m_isKeywordEnable; //关键字过滤 - QString m_keyword; //关键字 - bool m_timeFilterEnable; //是否根据时间过滤 - QDateTime m_startTime; //起始时间 - QDateTime m_endTime; //终止时间 -}; - -#endif // CEVENTHISTORYMODEL_H +#ifndef CEVENTHISTORYMODEL_H +#define CEVENTHISTORYMODEL_H + +#include +#include "CEventMsgInfo.h" +#include "CEventDataCollect.h" +#include + +#define Row_Full (15000) +#define MAX_HIS_ROWCOUNT (10000) + +class CEventMsgInfo; + +class CEventHistoryModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CEventHistoryModel(QObject *parent = Q_NULLPTR); + ~CEventHistoryModel(); + + void initialize(); + void initFilter(); + + void loadEventHistoryData(); + + QString bulidCondition(); + QString bulidConditionPartPriority(); + QString bulidConditionPartType(); + QString bulidConditionPartLocation(); + QString bulidConditionPartRegion(); + QString bulidConditionPartDeviceType(); + QString bulidConditionPartContent(); + QString bulidConditionPartDateTime(); + + EventMsgPtr getAlarmInfo(const QModelIndex &index) const; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime()); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime); + + bool conditionFilter(EventMsgPtr info); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter); + void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); + void setEventTimeFilter(bool &isCheck); +signals: + //void requestHistoryEvents(const QStringList &listHistoryEventTableName,QList typeFilter, const QString &conditionFilter); + void requestHistoryEvents(const QStringList &listHistoryEventTableName, const QString &conditionFilter); + void sigPermInvalid(); + void sigHisEventRequesting(); + void sigHisEventSizeChanged(); + void sigHISRecordOutOfRangeTips(QStringList stDescList); + +public slots: + void updateListEvents(const QList &listEvents, QStringList stDescList); + +private: + QStringList header; + QList m_listShowEventInfo; + + QList m_listPermLocationId; + QList m_listPermRegionId; + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + //Filter + bool m_isLevelFilterEnable; //是否按报警级别过滤 + QList m_levelFilter; //报警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isTypeFilterEnable; + QList m_typeFilter; +// bool m_isStatusFilterEnable; //是否按报警类型过滤 +// QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) +// QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyword; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 +}; + +#endif // CEVENTHISTORYMODEL_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventItemModel.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventItemModel.cpp index 9a8d04eb..bbd8dfd0 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventItemModel.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventItemModel.cpp @@ -1,651 +1,651 @@ -#include "CEventItemModel.h" -#include "CEventMsgInfo.h" -#include -#include -#include -#include -#include "CEventDataCollect.h" -#include "service/alarm_server_api/AlarmCommonDef.h" -#include "CEventMsgManage.h" -///////////////////////////////////////////////////////////////////////////// - -typedef QPair > PAIRLISTALARMINFO; - -CEventItemModel::CEventItemModel(QObject *parent) - :QAbstractTableModel(parent), - m_sortKey(E_SORT_TIME), - m_order(Qt::AscendingOrder) -{ - header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型") << tr("事件状态") << tr("事件内容"); - initialize(); - connect(CEventDataCollect::instance(), SIGNAL(sigMsgRefresh()), - this, SLOT(slotMsgRefresh()), Qt::QueuedConnection); - - connect(CEventDataCollect::instance(), SIGNAL(sigMsgArrived(QList)), - this, SLOT(slotMsgArrived(QList))); -} - -CEventItemModel::~CEventItemModel() -{ - m_listShowEventInfo.clear(); -} - -void CEventItemModel::initialize() -{ - beginResetModel(); - m_listShowEventInfo.clear(); - endResetModel(); - - initFilter(); -} - -void CEventItemModel::initFilter() -{ - m_isLevelFilterEnable = false; - m_isLocationFilterEnable = false; - m_isRegionFilterEnable = false; - m_isTypeFilterEnable = false; - m_isDeviceTypeFileter = false; - m_isKeywordEnable = false; - m_timeFilterEnable = false; -} - -EventMsgPtr CEventItemModel::getAlarmInfo(const QModelIndex &index) const -{ - if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) - { - return NULL; - } - - return m_listShowEventInfo.at(index.row()); -} - -const QList CEventItemModel::getListShowAlarmInfo() const -{ - return m_listShowEventInfo; -} - -void CEventItemModel::insertAlarmMsg(EventMsgPtr info) -{ - int nInsertRowIndex = -1; - if (Qt::AscendingOrder == m_order) - { - for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) - { - EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); - if (!msg->lessThan(info, m_sortKey)) - { - nInsertRowIndex = nIndex; - break; - } - } - } - else - { - for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) - { - EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); - if (!msg->moreThan(info, m_sortKey)) - { - nInsertRowIndex = nIndex; - break; - } - } - } - if (-1 == nInsertRowIndex) - { - nInsertRowIndex = m_listShowEventInfo.count(); - } - - - beginInsertRows(QModelIndex(), nInsertRowIndex, nInsertRowIndex); - m_listShowEventInfo.insert(nInsertRowIndex, info); - endInsertRows(); - - return; -} - -QVariant CEventItemModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(header.at(section)); - } - return QVariant(); -} - -QVariant CEventItemModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == 6) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - }else - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - } - else if(Qt::DisplayRole == role) - { - switch (index.column()) - { - case 0 : - { - return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp, Qt::LocalTime).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - case 1 : - { - return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); - } - case 2 : - { - return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); - } - case 3 : - { - return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); - } - case 4 : - { - return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); - } - case 5 : - { - return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); - } - case 6 : - { - return m_listShowEventInfo.at(index.row())->content; - } - default: - return QVariant(); - } - } - return QVariant(); -} - -int CEventItemModel::columnCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - - return header.count(); -} - -int CEventItemModel::rowCount(const QModelIndex &index) const -{ - if (index.isValid()) - { - return 0; - } - return m_listShowEventInfo.count(); -} - -Qt::ItemFlags CEventItemModel::flags(const QModelIndex &index) const -{ - // return Qt::NoItemFlags; - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -void CEventItemModel::sortColumn(int column, Qt::SortOrder order) -{ - if(order == Qt::AscendingOrder) - { - m_order = Qt::DescendingOrder; - } - else - { - m_order = Qt::AscendingOrder; - } - switch (column) - { - case 0: - { - m_sortKey = E_SORT_TIME; - break; - } - case 1: - { - m_sortKey = E_SORT_PRIORITY; - break; - } - case 2: - { - m_sortKey = E_SORT_LOCATION; - break; - } - case 3: - { - m_sortKey = E_SORT_REGION; - break; - } - case 4: - { - m_sortKey = E_SORT_TYPE; - break; - } - case 5: - { - m_sortKey = E_SORT_STATUS; - break; - } - case 6: - { - m_sortKey = E_SORT_CONTENT; - break; - } - default: - break; - } - sort(); - beginResetModel(); - endResetModel(); -} - -//<归并排序 -void CEventItemModel::sort() -{ - QMap mapAlarmInfo; - //<分 - for(int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) - { - EventMsgPtr temp = m_listShowEventInfo.at(nIndex); - mapAlarmInfo[nIndex / 1000].second.append(temp); - } - - //<快速排序 - for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) - { - qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); - } - - //<治 - PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; - for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) - { - //<归并 - tempListAlarmInfo.first = 0; - mapAlarmInfo[nPairIndex].first = 0; - while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) - { - if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) - { - tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) - { - tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); - mapAlarmInfo[nPairIndex].first += 1; - } - } - } - tempListAlarmInfo.first += 1; - } - } - m_listShowEventInfo = tempListAlarmInfo.second; -} - - -void CEventItemModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CEventItemModel::partitionAscendingOrder(QList &list, int start, int last) -{ - EventMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftlessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CEventItemModel::partitionDescendingOrder(QList &list, int start, int last) -{ - EventMsgPtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -void CEventItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, - const bool &isKeywordFilterEnable, const QString &keyword, - const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime) -{ - m_isLevelFilterEnable = isLevelFilterEnable; - m_levelFilter = levelFilter; - m_isLocationFilterEnable = isStationFilterEnable; - m_locationFilter = stationFilter; - m_isRegionFilterEnable = isRegionFilterEnable; - m_regionFilter = regionFilter; - m_isTypeFilterEnable = isTypeFilterEnable; - m_typeFilter = typeFilter; - m_isDeviceTypeFileter = isDeviceTypeFilter; - m_subSystem = subSystem; - m_deviceType = deviceType; - m_isKeywordEnable = isKeywordFilterEnable; - m_keyowrd = keyword; - m_timeFilterEnable = timeFilterEnable; - m_startTime = startTime; - m_endTime = endTime; - - beginResetModel(); - m_listShowEventInfo.clear(); - foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) - { - if (conditionFilter(info)) - { - m_listShowEventInfo.append(info); - } - } - sort(); - endResetModel(); -} - -void CEventItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime) -{ - isLevelFilterEnable = m_isLevelFilterEnable; - levelFilter = m_levelFilter; - isLocationFilterEnable = m_isLocationFilterEnable; - locationFilter = m_locationFilter; - isRegionFilterEnable = m_isRegionFilterEnable; - regionFilter = m_regionFilter; - isTypeFilterEnable = m_isTypeFilterEnable; - alarmTypeFilter = m_typeFilter; - subSystem = m_subSystem; - deviceTypeFilter = m_isDeviceTypeFileter; - deviceType = m_deviceType; - keywordFilterEnable = m_isKeywordEnable; - keyword = m_keyowrd; - timeFilterEnable = m_timeFilterEnable; - startTime = m_startTime; - endTime = m_endTime; -} - -bool CEventItemModel::conditionFilter(EventMsgPtr info) -{ - //< 等级 - if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) - { - return false; - } - - //< 车站 - if(m_isLocationFilterEnable) - { - if(!m_locationFilter.contains(info->location_id)) - { - return false; - } - } - else - { - if(!CEventDataCollect::instance()->locationList().contains(info->location_id)) - { - return false; - } - } - - //< 责任区 - if(m_isRegionFilterEnable) - { - if(!m_regionFilter.contains(info->region_id)) - { - return false; - } - } - else - { - if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 - { - return false; - } - } - - //< 状态 - if(m_isTypeFilterEnable && !m_typeFilter.contains(info->alm_type)) - { - return false; - } - - //< 设备类型 - if(m_isDeviceTypeFileter) - { - if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) - { - return false; - } - } - //< 关键字 - if(m_isKeywordEnable) - { - if(!info->content.contains(m_keyowrd)) - { - return false; - } - } - - //< 时间 - if(m_timeFilterEnable) - { - if(m_startTime.toMSecsSinceEpoch() >= info->time_stamp) - { - return false; - } - if(m_endTime.toMSecsSinceEpoch() <= info->time_stamp) - { - return false; - } - } - return true; -} - -void CEventItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) -{ - m_isLevelFilterEnable = isCheck; - m_levelFilter = priorityFilter; - - beginResetModel(); - m_listShowEventInfo.clear(); - foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) - { - if (conditionFilter(info)) - { - m_listShowEventInfo.append(info); - } - } - sort(); - endResetModel(); -} - -void CEventItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) -{ - m_isLocationFilterEnable = isCheck; - m_locationFilter = locationFilter; - - beginResetModel(); - m_listShowEventInfo.clear(); - foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) - { - if (conditionFilter(info)) - { - m_listShowEventInfo.append(info); - } - } - sort(); - endResetModel(); -} - -void CEventItemModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter) -{ - m_isTypeFilterEnable = isCheck; - m_typeFilter = eventTypeFilter; - beginResetModel(); - m_listShowEventInfo.clear(); - foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) - { - if (conditionFilter(info)) - { - m_listShowEventInfo.append(info); - } - } - sort(); - endResetModel(); -} - -void CEventItemModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) -{ - m_timeFilterEnable = isCheck; - if(isCheck) - { - QTime time_1(0,0,0); - QTime time_2(23,59,59); - m_startTime.setDate(startTime); - m_startTime.setTime(time_1); - m_endTime.setDate(endTime); - m_endTime.setTime(time_2); - } - beginResetModel(); - m_listShowEventInfo.clear(); - foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) - { - if (conditionFilter(info)) - { - m_listShowEventInfo.append(info); - } - } - sort(); - endResetModel(); -} - -void CEventItemModel::setEventTimeFilter(bool &isCheck) -{ - m_timeFilterEnable = isCheck; - beginResetModel(); - m_listShowEventInfo.clear(); - foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) - { - if (conditionFilter(info)) - { - m_listShowEventInfo.append(info); - } - } - sort(); - endResetModel(); -} - -void CEventItemModel::slotMsgRefresh() -{ - beginResetModel(); - m_listShowEventInfo.clear(); - foreach (EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) - { - if(conditionFilter(info)) - { - m_listShowEventInfo.append(info); - } - } - sort(); - endResetModel(); -} - -void CEventItemModel::slotMsgArrived(QList listEvents) -{ - foreach (EventMsgPtr info, listEvents) - { - if(!conditionFilter(info)) - { - return; - } - // 更新Model - insertAlarmMsg(info); - } - - //< 删除项 - for(int nIndex = m_listShowEventInfo.size() - 1; nIndex >= 0; --nIndex) - { - if(m_listShowEventInfo.at(nIndex)->deleted) - { - beginRemoveRows(QModelIndex(), nIndex, nIndex); - m_listShowEventInfo.removeAt(nIndex); - endRemoveRows(); - } - } -} +#include "CEventItemModel.h" +#include "CEventMsgInfo.h" +#include +#include +#include +#include +#include "CEventDataCollect.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include "CEventMsgManage.h" +///////////////////////////////////////////////////////////////////////////// + +typedef QPair > PAIRLISTALARMINFO; + +CEventItemModel::CEventItemModel(QObject *parent) + :QAbstractTableModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::AscendingOrder) +{ + header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型") << tr("事件状态") << tr("事件内容"); + initialize(); + connect(CEventDataCollect::instance(), SIGNAL(sigMsgRefresh()), + this, SLOT(slotMsgRefresh()), Qt::QueuedConnection); + + connect(CEventDataCollect::instance(), SIGNAL(sigMsgArrived(QList)), + this, SLOT(slotMsgArrived(QList))); +} + +CEventItemModel::~CEventItemModel() +{ + m_listShowEventInfo.clear(); +} + +void CEventItemModel::initialize() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + endResetModel(); + + initFilter(); +} + +void CEventItemModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_isLocationFilterEnable = false; + m_isRegionFilterEnable = false; + m_isTypeFilterEnable = false; + m_isDeviceTypeFileter = false; + m_isKeywordEnable = false; + m_timeFilterEnable = false; +} + +EventMsgPtr CEventItemModel::getAlarmInfo(const QModelIndex &index) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return NULL; + } + + return m_listShowEventInfo.at(index.row()); +} + +const QList CEventItemModel::getListShowAlarmInfo() const +{ + return m_listShowEventInfo; +} + +void CEventItemModel::insertAlarmMsg(EventMsgPtr info) +{ + int nInsertRowIndex = -1; + if (Qt::AscendingOrder == m_order) + { + for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); + if (!msg->lessThan(info, m_sortKey)) + { + nInsertRowIndex = nIndex; + break; + } + } + } + else + { + for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); + if (!msg->moreThan(info, m_sortKey)) + { + nInsertRowIndex = nIndex; + break; + } + } + } + if (-1 == nInsertRowIndex) + { + nInsertRowIndex = m_listShowEventInfo.count(); + } + + + beginInsertRows(QModelIndex(), nInsertRowIndex, nInsertRowIndex); + m_listShowEventInfo.insert(nInsertRowIndex, info); + endInsertRows(); + + return; +} + +QVariant CEventItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(header.at(section)); + } + return QVariant(); +} + +QVariant CEventItemModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == 6) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + } + else if(Qt::DisplayRole == role) + { + switch (index.column()) + { + case 0 : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp, Qt::LocalTime).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case 1 : + { + return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); + } + case 2 : + { + return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); + } + case 3 : + { + return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); + } + case 4 : + { + return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); + } + case 5 : + { + return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); + } + case 6 : + { + return m_listShowEventInfo.at(index.row())->content; + } + default: + return QVariant(); + } + } + return QVariant(); +} + +int CEventItemModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return header.count(); +} + +int CEventItemModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + return m_listShowEventInfo.count(); +} + +Qt::ItemFlags CEventItemModel::flags(const QModelIndex &index) const +{ + // return Qt::NoItemFlags; + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CEventItemModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + switch (column) + { + case 0: + { + m_sortKey = E_SORT_TIME; + break; + } + case 1: + { + m_sortKey = E_SORT_PRIORITY; + break; + } + case 2: + { + m_sortKey = E_SORT_LOCATION; + break; + } + case 3: + { + m_sortKey = E_SORT_REGION; + break; + } + case 4: + { + m_sortKey = E_SORT_TYPE; + break; + } + case 5: + { + m_sortKey = E_SORT_STATUS; + break; + } + case 6: + { + m_sortKey = E_SORT_CONTENT; + break; + } + default: + break; + } + sort(); + beginResetModel(); + endResetModel(); +} + +//<归并排序 +void CEventItemModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr temp = m_listShowEventInfo.at(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(temp); + } + + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + + //<治 + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + m_listShowEventInfo = tempListAlarmInfo.second; +} + + +void CEventItemModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CEventItemModel::partitionAscendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CEventItemModel::partitionDescendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CEventItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isTypeFilterEnable = isTypeFilterEnable; + m_typeFilter = typeFilter; + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyowrd = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + + beginResetModel(); + m_listShowEventInfo.clear(); + foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) + { + if (conditionFilter(info)) + { + m_listShowEventInfo.append(info); + } + } + sort(); + endResetModel(); +} + +void CEventItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isTypeFilterEnable = m_isTypeFilterEnable; + alarmTypeFilter = m_typeFilter; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyowrd; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; +} + +bool CEventItemModel::conditionFilter(EventMsgPtr info) +{ + //< 等级 + if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) + { + return false; + } + + //< 车站 + if(m_isLocationFilterEnable) + { + if(!m_locationFilter.contains(info->location_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->locationList().contains(info->location_id)) + { + return false; + } + } + + //< 责任区 + if(m_isRegionFilterEnable) + { + if(!m_regionFilter.contains(info->region_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 + { + return false; + } + } + + //< 状态 + if(m_isTypeFilterEnable && !m_typeFilter.contains(info->alm_type)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { + if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) + { + return false; + } + } + //< 关键字 + if(m_isKeywordEnable) + { + if(!info->content.contains(m_keyowrd)) + { + return false; + } + } + + //< 时间 + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() >= info->time_stamp) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() <= info->time_stamp) + { + return false; + } + } + return true; +} + +void CEventItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + + beginResetModel(); + m_listShowEventInfo.clear(); + foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) + { + if (conditionFilter(info)) + { + m_listShowEventInfo.append(info); + } + } + sort(); + endResetModel(); +} + +void CEventItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + + beginResetModel(); + m_listShowEventInfo.clear(); + foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) + { + if (conditionFilter(info)) + { + m_listShowEventInfo.append(info); + } + } + sort(); + endResetModel(); +} + +void CEventItemModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter) +{ + m_isTypeFilterEnable = isCheck; + m_typeFilter = eventTypeFilter; + beginResetModel(); + m_listShowEventInfo.clear(); + foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) + { + if (conditionFilter(info)) + { + m_listShowEventInfo.append(info); + } + } + sort(); + endResetModel(); +} + +void CEventItemModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + beginResetModel(); + m_listShowEventInfo.clear(); + foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) + { + if (conditionFilter(info)) + { + m_listShowEventInfo.append(info); + } + } + sort(); + endResetModel(); +} + +void CEventItemModel::setEventTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + beginResetModel(); + m_listShowEventInfo.clear(); + foreach(EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) + { + if (conditionFilter(info)) + { + m_listShowEventInfo.append(info); + } + } + sort(); + endResetModel(); +} + +void CEventItemModel::slotMsgRefresh() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + foreach (EventMsgPtr info, CEventMsgManage::instance()->getListEventInfo()) + { + if(conditionFilter(info)) + { + m_listShowEventInfo.append(info); + } + } + sort(); + endResetModel(); +} + +void CEventItemModel::slotMsgArrived(QList listEvents) +{ + foreach (EventMsgPtr info, listEvents) + { + if(!conditionFilter(info)) + { + return; + } + // 更新Model + insertAlarmMsg(info); + } + + //< 删除项 + for(int nIndex = m_listShowEventInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowEventInfo.at(nIndex)->deleted) + { + beginRemoveRows(QModelIndex(), nIndex, nIndex); + m_listShowEventInfo.removeAt(nIndex); + endRemoveRows(); + } + } +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventItemModel.h b/product/src/gui/plugin/ISCSEventWidget/CEventItemModel.h index dafe3e38..b8ff2ce3 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventItemModel.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventItemModel.h @@ -1,123 +1,123 @@ -#ifndef CEVENTITEMMODEL_H -#define CEVENTITEMMODEL_H - -#include -#include -#include "CEventMsgInfo.h" -#include "CEventDataCollect.h" -#include - -#define Row_Full (15000) - -class CEventMsgInfo; -class QTimer; - -class CEventItemModel : public QAbstractTableModel -{ - Q_OBJECT -public: - CEventItemModel(QObject *parent = Q_NULLPTR); - ~CEventItemModel(); - - void initialize(); - void initFilter(); - - EventMsgPtr getAlarmInfo(const QModelIndex &index) const; - - const QList getListShowAlarmInfo() const; - - /** - * @brief insertAlarmMsg 数采通知模型报警到达 - * @param info - */ - void insertAlarmMsg(EventMsgPtr info); - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual int columnCount(const QModelIndex &index = QModelIndex()) const; - virtual int rowCount(const QModelIndex &index = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - void sort(); - void qucikSort(QList &listAlarmInfo, int left, int right); - int partitionAscendingOrder(QList &list, int start, int last); - int partitionDescendingOrder(QList &list, int start, int last); - - /** - * 设置模型数据过滤条件,过滤显示数据 - */ - void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, - const bool &isStationFilterEnable, const QList &stationFilter, - const bool &isRegionFilterEnable, const QList ®ionFilter, - const bool &isTypeFilterEnable, const QList &typeFilter, - const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), - const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), - const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), - const QDateTime &endTime = QDateTime()); - - /** - * 获取模型数据过滤条件,用于初始化过滤对话框 - */ - void getFilter(bool &isLevelFilterEnable, QList &levelFilter, - bool &isLocationFilterEnable, QList &locationFilter, - bool &isRegionFilterEnable, QList ®ionFilter, - bool &isTypeFilterEnable, QList &alarmTypeFilter, - bool &deviceTypeFilter, QString &subSystem, QString &deviceType, - bool &keywordFilterEnable, QString &keyword, - bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime); - - bool conditionFilter(EventMsgPtr info); - - void setPriorityFilter(bool &isCheck, QList &priorityFilter); - void setLocationFilter(bool &isCheck, QList &locationFilter); - void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter); - void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); - void setEventTimeFilter(bool &isCheck); -signals: - void sigRowChanged(); - -public slots: - void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); - -private slots: - /** - * @brief slotMsgRefresh 更新model,重新拉取数据 - */ - void slotMsgRefresh(); - - /** - * @brief slotMsgArrived 报警消息到达 - * @param info - */ - void slotMsgArrived(QList listEvents); - -private: - QStringList header; - QList m_listShowEventInfo; - - E_ALARM_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - - //Filter - bool m_isLevelFilterEnable; //是否按报警级别过滤 - QList m_levelFilter; //报警级别过滤 - bool m_isLocationFilterEnable; //是否按车站过滤 - QList m_locationFilter; //车站过滤 - bool m_isRegionFilterEnable; //是否按责任区过滤 - QList m_regionFilter; //责任区过滤 - - bool m_isTypeFilterEnable; - QList m_typeFilter; -// bool m_isStatusFilterEnable; //是否按事件状态过滤 -// QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) -// QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) - bool m_isDeviceTypeFileter; //设备类型过滤 - QString m_subSystem; //子系统 - QString m_deviceType; //设备类型 - bool m_isKeywordEnable; //关键字过滤 - QString m_keyowrd; //关键字 - bool m_timeFilterEnable; //是否根据时间过滤 - QDateTime m_startTime; //起始时间 - QDateTime m_endTime; //终止时间 -}; - -#endif // CEVENTITEMMODEL_H +#ifndef CEVENTITEMMODEL_H +#define CEVENTITEMMODEL_H + +#include +#include +#include "CEventMsgInfo.h" +#include "CEventDataCollect.h" +#include + +#define Row_Full (15000) + +class CEventMsgInfo; +class QTimer; + +class CEventItemModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CEventItemModel(QObject *parent = Q_NULLPTR); + ~CEventItemModel(); + + void initialize(); + void initFilter(); + + EventMsgPtr getAlarmInfo(const QModelIndex &index) const; + + const QList getListShowAlarmInfo() const; + + /** + * @brief insertAlarmMsg 数采通知模型报警到达 + * @param info + */ + void insertAlarmMsg(EventMsgPtr info); + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + void sort(); + void qucikSort(QList &listAlarmInfo, int left, int right); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime()); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime); + + bool conditionFilter(EventMsgPtr info); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter); + void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); + void setEventTimeFilter(bool &isCheck); +signals: + void sigRowChanged(); + +public slots: + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + +private slots: + /** + * @brief slotMsgRefresh 更新model,重新拉取数据 + */ + void slotMsgRefresh(); + + /** + * @brief slotMsgArrived 报警消息到达 + * @param info + */ + void slotMsgArrived(QList listEvents); + +private: + QStringList header; + QList m_listShowEventInfo; + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + //Filter + bool m_isLevelFilterEnable; //是否按报警级别过滤 + QList m_levelFilter; //报警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + + bool m_isTypeFilterEnable; + QList m_typeFilter; +// bool m_isStatusFilterEnable; //是否按事件状态过滤 +// QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) +// QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyowrd; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 +}; + +#endif // CEVENTITEMMODEL_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventMsgInfo.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventMsgInfo.cpp index 2e8bc608..e47bcca5 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventMsgInfo.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventMsgInfo.cpp @@ -1,378 +1,378 @@ -#include "CEventMsgInfo.h" -#include -#include "CEventDataCollect.h" -#include - -CEventMsgInfo::CEventMsgInfo() -{ - alm_type = -1; - time_stamp = 1000; - domain_id = -1; - location_id = -1; - app_id = -1; - content = QString(""); - priority = -1; - dev_type = -1; - region_id = -1; - priorityOrder = -1; - deleted = false; -} - -CEventMsgInfo::CEventMsgInfo(const CEventMsgInfo &other) -{ - alm_type = other.alm_type; - time_stamp = other.time_stamp; - domain_id = other.domain_id; - location_id = other.location_id; - app_id = other.app_id; - content = other.content; - priority = other.priority; - dev_type = other.dev_type; - region_id = other.region_id; - deleted = other.deleted; -} - -void CEventMsgInfo::initialize(const kbd_idlfile::SEvtInfoToEvtClt &eventInfo) -{ - alm_type = eventInfo.alm_type(); - time_stamp = eventInfo.time_stamp(); - alm_status = eventInfo.alm_status(); - domain_id = eventInfo.domain_id(); - location_id = eventInfo.location_id(); - app_id = eventInfo.app_id(); - content = QString::fromStdString(eventInfo.content()); - priority = eventInfo.priority(); - dev_type = eventInfo.dev_type(); - if(eventInfo.has_region_id() && eventInfo.region_id() > 0) - { - region_id = eventInfo.region_id(); - } - else - { - region_id = -1; - } -} - -bool CEventMsgInfo::lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) - { - case E_SORT_PRIORITY: - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - else if(priorityOrder > info->priorityOrder) - { - return false; - } - else if(priorityOrder == info->priorityOrder) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TIME: - { - if(time_stamp < info->time_stamp) - { - return true; - } - if(time_stamp > info->time_stamp) - { - return false; - } - else if(time_stamp == info->time_stamp) - { - if(priorityOrder <= info->priorityOrder) - { - return true; - } - return false; - } - break; - } - case E_SORT_LOCATION: - { - if(location_id < info->location_id) - { - return true; - } - else if(location_id > info->location_id) - { - return false; - } - else if(location_id == info->location_id) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_REGION: - { - if(region_id < info->region_id) - { - return true; - } - else if(region_id > info->region_id) - { - return false; - } - else if(region_id == info->region_id) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TYPE: - { - if(alm_type < info->alm_type) - { - return true; - } - else if(alm_type > info->alm_type) - { - return false; - } - else if(alm_type == info->alm_type) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_STATUS: - { - if(alm_status < info->alm_status) - { - return true; - } - else if(alm_status > info->alm_status) - { - return false; - } - else if(alm_status == info->alm_status) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_CONTENT: - { - if(content.isEmpty() && info->content.isEmpty()) - { - return false; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return true; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return false; - } - else if(content < info->content) - { - return true; - } - else if(content > info->content) - { - return false; - } - else if(content == info->content) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - default: - break; - } - return false; -} - -bool CEventMsgInfo::moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) -{ - switch (sortkey) - { - case E_SORT_PRIORITY: - { - if(priorityOrder > info->priorityOrder) - { - return true; - } - else if(priorityOrder < info->priorityOrder) - { - return false; - } - else if(priorityOrder == info->priorityOrder) - { - if(time_stamp >= info->time_stamp) - { - return true; - } - return false; - } - break; - } - case E_SORT_TIME: - { - if(time_stamp > info->time_stamp) - { - return true; - } - if(time_stamp < info->time_stamp) - { - return false; - } - else if(time_stamp == info->time_stamp) - { - if(priorityOrder < info->priorityOrder) - { - return true; - } - return false; - } - break; - } - case E_SORT_LOCATION: - { - if(location_id > info->location_id) - { - return true; - } - else if(location_id < info->location_id) - { - return false; - } - else if(location_id == info->location_id) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_REGION: - { - if(region_id > info->region_id) - { - return true; - } - else if(region_id < info->region_id) - { - return false; - } - else if(region_id == info->region_id) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_TYPE: - { - if(alm_type > info->alm_type) - { - return true; - } - else if(alm_type < info->alm_type) - { - return false; - } - else if(alm_type == info->alm_type) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_STATUS: - { - if(alm_status > info->alm_status) - { - return true; - } - else if(alm_status < info->alm_status) - { - return false; - } - else if(alm_status == info->alm_status) - { - if(time_stamp <= info->time_stamp) - { - return false; - } - return true; - } - break; - } - case E_SORT_CONTENT: - { - if(content.isEmpty() && info->content.isEmpty()) - { - return true; - } - else if(content.isEmpty() && (!info->content.isEmpty())) - { - return false; - } - else if((!content.isEmpty()) && info->content.isEmpty()) - { - return true; - } - else if(content > info->content) - { - return true; - } - else if(content < info->content) - { - return false; - } - else if(content == info->content) - { - if(time_stamp < info->time_stamp) - { - return false; - } - return true; - } - break; - } - default: - break; - } - return false; -} +#include "CEventMsgInfo.h" +#include +#include "CEventDataCollect.h" +#include + +CEventMsgInfo::CEventMsgInfo() +{ + alm_type = -1; + time_stamp = 1000; + domain_id = -1; + location_id = -1; + app_id = -1; + content = QString(""); + priority = -1; + dev_type = -1; + region_id = -1; + priorityOrder = -1; + deleted = false; +} + +CEventMsgInfo::CEventMsgInfo(const CEventMsgInfo &other) +{ + alm_type = other.alm_type; + time_stamp = other.time_stamp; + domain_id = other.domain_id; + location_id = other.location_id; + app_id = other.app_id; + content = other.content; + priority = other.priority; + dev_type = other.dev_type; + region_id = other.region_id; + deleted = other.deleted; +} + +void CEventMsgInfo::initialize(const kbd_idlfile::SEvtInfoToEvtClt &eventInfo) +{ + alm_type = eventInfo.alm_type(); + time_stamp = eventInfo.time_stamp(); + alm_status = eventInfo.alm_status(); + domain_id = eventInfo.domain_id(); + location_id = eventInfo.location_id(); + app_id = eventInfo.app_id(); + content = QString::fromStdString(eventInfo.content()); + priority = eventInfo.priority(); + dev_type = eventInfo.dev_type(); + if(eventInfo.has_region_id() && eventInfo.region_id() > 0) + { + region_id = eventInfo.region_id(); + } + else + { + region_id = -1; + } +} + +bool CEventMsgInfo::lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + else if(priorityOrder > info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp < info->time_stamp) + { + return true; + } + if(time_stamp > info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder <= info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id < info->location_id) + { + return true; + } + else if(location_id > info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id < info->region_id) + { + return true; + } + else if(region_id > info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type < info->alm_type) + { + return true; + } + else if(alm_type > info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STATUS: + { + if(alm_status < info->alm_status) + { + return true; + } + else if(alm_status > info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} + +bool CEventMsgInfo::moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + else if(priorityOrder < info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp >= info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp > info->time_stamp) + { + return true; + } + if(time_stamp < info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id > info->location_id) + { + return true; + } + else if(location_id < info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id > info->region_id) + { + return true; + } + else if(region_id < info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type > info->alm_type) + { + return true; + } + else if(alm_type < info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STATUS: + { + if(alm_status > info->alm_status) + { + return true; + } + else if(alm_status < info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventMsgInfo.h b/product/src/gui/plugin/ISCSEventWidget/CEventMsgInfo.h index 5e1b6a98..6743107f 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventMsgInfo.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventMsgInfo.h @@ -1,62 +1,62 @@ -#ifndef ALARMMSGINFO_H -#define ALARMMSGINFO_H - -#include -#include -#include -#include "alarm_server_api/CAlmApiForEvtClt.h" -#include "common/DataType.h" -//排序 -enum E_ALARM_SORTKEY -{ - E_SORT_PRIORITY = 0, //优先级 - E_SORT_TIME, //时间戳 - E_SORT_LOCATION, //车站 - E_SORT_REGION, //责任区 - E_SORT_TYPE, //事件状态 - E_SORT_STATUS, //事件类型 - E_SORT_CONTENT //报警内容 -}; - -// 报警状态 -enum E_ALARM_LOGICSTATE -{ - E_ALS_ALARM = 0, // 报警状态 - E_ALS_ALARM_CFM, // 报警确认状态 - E_ALS_RETURN, // 报警返回状态 - E_ALS_RETURN_CFM, // 报警返回确认状态 -}; -class CEventMsgInfo; -typedef QSharedPointer EventMsgPtr; - -class CEventMsgInfo -{ -public: - CEventMsgInfo(); - CEventMsgInfo(const CEventMsgInfo &other); - void initialize(const kbd_idlfile::SEvtInfoToEvtClt &eventInfo); - bool lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - bool moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); - - qint32 alm_type; //报警类型 - quint64 time_stamp; //时标(RFC1305、POSIX时标标准) - qint32 domain_id; //域ID - qint32 location_id; //位置ID - qint32 app_id; //应用号 - QString content; //报警内容 - qint32 priority; //报警优先级id - qint32 dev_type; //设备类型ID - qint32 region_id; //责任区ID - bool deleted; //实时事件删除标志 - - int32 alm_status; //事件状态 - uint cfm_user; //确认人 - uint64 cfm_time; //确认时间 -//Extend - qint32 priorityOrder; -}; - -Q_DECLARE_METATYPE(CEventMsgInfo) -Q_DECLARE_METATYPE(EventMsgPtr) - -#endif // ALARMMSGINFO_H +#ifndef ALARMMSGINFO_H +#define ALARMMSGINFO_H + +#include +#include +#include +#include "alarm_server_api/CAlmApiForEvtClt.h" +#include "common/DataType.h" +//排序 +enum E_ALARM_SORTKEY +{ + E_SORT_PRIORITY = 0, //优先级 + E_SORT_TIME, //时间戳 + E_SORT_LOCATION, //车站 + E_SORT_REGION, //责任区 + E_SORT_TYPE, //事件状态 + E_SORT_STATUS, //事件类型 + E_SORT_CONTENT //报警内容 +}; + +// 报警状态 +enum E_ALARM_LOGICSTATE +{ + E_ALS_ALARM = 0, // 报警状态 + E_ALS_ALARM_CFM, // 报警确认状态 + E_ALS_RETURN, // 报警返回状态 + E_ALS_RETURN_CFM, // 报警返回确认状态 +}; +class CEventMsgInfo; +typedef QSharedPointer EventMsgPtr; + +class CEventMsgInfo +{ +public: + CEventMsgInfo(); + CEventMsgInfo(const CEventMsgInfo &other); + void initialize(const kbd_idlfile::SEvtInfoToEvtClt &eventInfo); + bool lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + qint32 alm_type; //报警类型 + quint64 time_stamp; //时标(RFC1305、POSIX时标标准) + qint32 domain_id; //域ID + qint32 location_id; //位置ID + qint32 app_id; //应用号 + QString content; //报警内容 + qint32 priority; //报警优先级id + qint32 dev_type; //设备类型ID + qint32 region_id; //责任区ID + bool deleted; //实时事件删除标志 + + int32 alm_status; //事件状态 + uint cfm_user; //确认人 + uint64 cfm_time; //确认时间 +//Extend + qint32 priorityOrder; +}; + +Q_DECLARE_METATYPE(CEventMsgInfo) +Q_DECLARE_METATYPE(EventMsgPtr) + +#endif // ALARMMSGINFO_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventMsgManage.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventMsgManage.cpp index e726afab..1c9fdaff 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventMsgManage.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventMsgManage.cpp @@ -1,97 +1,97 @@ -#include "CEventMsgManage.h" -#include -#include -CEventMsgManage * CEventMsgManage::m_pInstance = Q_NULLPTR; - -CEventMsgManage *CEventMsgManage::instance() -{ - if(m_pInstance == Q_NULLPTR) - { - m_pInstance = new CEventMsgManage(); - } - return m_pInstance; -} - - -CEventMsgManage::CEventMsgManage() - : QObject() -{ - mutex = new QMutex(); -} - -CEventMsgManage::~CEventMsgManage() -{ - m_listEventInfo.clear(); - delete mutex; - m_pInstance = Q_NULLPTR; -} - -QList CEventMsgManage::getListEventInfo() -{ - QMutexLocker locker(mutex); - return m_listEventInfo; -} - -int CEventMsgManage::getListEventCount() -{ - if(m_listEventInfo.isEmpty()) - { - return 0; - } - - return m_listEventInfo.count(); -} - -void CEventMsgManage::addEventMsg(const EventMsgPtr msg) -{ - QMutexLocker locker(mutex); - if(!m_listEventInfo.isEmpty()) - { - bool inserted = false; - QList::iterator iter = m_listEventInfo.begin(); - while (iter != m_listEventInfo.end()) - { - if(msg->time_stamp >= (*iter)->time_stamp) - { - m_listEventInfo.insert(iter, msg); - inserted = true; - break; - } - iter++; - } - if (!inserted) - { - m_listEventInfo.append(msg); - } - } - else - { - m_listEventInfo.append(msg); - } - if(m_listEventInfo.size() > 10000) - { - m_listEventInfo.takeLast()->deleted = true; - } -} - -void CEventMsgManage::removeEventMsgByDomainID(const int domainId) -{ - QMutexLocker locker(mutex); - QList::iterator it = m_listEventInfo.begin(); - while (it != m_listEventInfo.end()) - { - if(domainId == (*it)->domain_id) - { - it = m_listEventInfo.erase(it); - continue; - } - it++; - } -} - -void CEventMsgManage::clearRTMsg() -{ - QMutexLocker locker(mutex); - m_listEventInfo.clear(); -} - +#include "CEventMsgManage.h" +#include +#include +CEventMsgManage * CEventMsgManage::m_pInstance = Q_NULLPTR; + +CEventMsgManage *CEventMsgManage::instance() +{ + if(m_pInstance == Q_NULLPTR) + { + m_pInstance = new CEventMsgManage(); + } + return m_pInstance; +} + + +CEventMsgManage::CEventMsgManage() + : QObject() +{ + mutex = new QMutex(); +} + +CEventMsgManage::~CEventMsgManage() +{ + m_listEventInfo.clear(); + delete mutex; + m_pInstance = Q_NULLPTR; +} + +QList CEventMsgManage::getListEventInfo() +{ + QMutexLocker locker(mutex); + return m_listEventInfo; +} + +int CEventMsgManage::getListEventCount() +{ + if(m_listEventInfo.isEmpty()) + { + return 0; + } + + return m_listEventInfo.count(); +} + +void CEventMsgManage::addEventMsg(const EventMsgPtr msg) +{ + QMutexLocker locker(mutex); + if(!m_listEventInfo.isEmpty()) + { + bool inserted = false; + QList::iterator iter = m_listEventInfo.begin(); + while (iter != m_listEventInfo.end()) + { + if(msg->time_stamp >= (*iter)->time_stamp) + { + m_listEventInfo.insert(iter, msg); + inserted = true; + break; + } + iter++; + } + if (!inserted) + { + m_listEventInfo.append(msg); + } + } + else + { + m_listEventInfo.append(msg); + } + if(m_listEventInfo.size() > 10000) + { + m_listEventInfo.takeLast()->deleted = true; + } +} + +void CEventMsgManage::removeEventMsgByDomainID(const int domainId) +{ + QMutexLocker locker(mutex); + QList::iterator it = m_listEventInfo.begin(); + while (it != m_listEventInfo.end()) + { + if(domainId == (*it)->domain_id) + { + it = m_listEventInfo.erase(it); + continue; + } + it++; + } +} + +void CEventMsgManage::clearRTMsg() +{ + QMutexLocker locker(mutex); + m_listEventInfo.clear(); +} + diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventMsgManage.h b/product/src/gui/plugin/ISCSEventWidget/CEventMsgManage.h index 741a3185..f0150ab8 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventMsgManage.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventMsgManage.h @@ -1,37 +1,37 @@ -#ifndef CEventMsgManage_H -#define CEventMsgManage_H - -#include -#include "CEventMsgInfo.h" - -class QMutex; - -class CEventMsgManage : public QObject -{ - Q_OBJECT -public: - static CEventMsgManage * instance(); - - ~CEventMsgManage(); - - QList getListEventInfo(); - - int getListEventCount(); - - void addEventMsg(const EventMsgPtr msg); - - void removeEventMsgByDomainID(const int domainId); - - void clearRTMsg(); - -private: - CEventMsgManage(); - -private: - QMutex * mutex; - QList m_listEventInfo; - QList m_historyEventInfo; - static CEventMsgManage * m_pInstance; -}; - -#endif // CEventMsgManage_H +#ifndef CEventMsgManage_H +#define CEventMsgManage_H + +#include +#include "CEventMsgInfo.h" + +class QMutex; + +class CEventMsgManage : public QObject +{ + Q_OBJECT +public: + static CEventMsgManage * instance(); + + ~CEventMsgManage(); + + QList getListEventInfo(); + + int getListEventCount(); + + void addEventMsg(const EventMsgPtr msg); + + void removeEventMsgByDomainID(const int domainId); + + void clearRTMsg(); + +private: + CEventMsgManage(); + +private: + QMutex * mutex; + QList m_listEventInfo; + QList m_historyEventInfo; + static CEventMsgManage * m_pInstance; +}; + +#endif // CEventMsgManage_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.cpp index 79486eb7..eeddeec3 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.cpp @@ -1,25 +1,25 @@ -#include -#include "CEventPluginWidget.h" -#include "CEventForm.h" - -CEventPluginWidget::CEventPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CEventPluginWidget::~CEventPluginWidget() -{ - -} - -bool CEventPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec) -{ - CEventForm *pWidget = new CEventForm(parent, editMode); - *widget = (QWidget *)pWidget; - *eventWidget = (IPluginWidget *)pWidget; - return true; -} - -void CEventPluginWidget::release() -{ -} +#include +#include "CEventPluginWidget.h" +#include "CEventForm.h" + +CEventPluginWidget::CEventPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CEventPluginWidget::~CEventPluginWidget() +{ + +} + +bool CEventPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec) +{ + CEventForm *pWidget = new CEventForm(parent, editMode); + *widget = (QWidget *)pWidget; + *eventWidget = (IPluginWidget *)pWidget; + return true; +} + +void CEventPluginWidget::release() +{ +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.h b/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.h index e32fb0a4..1e530db5 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CEVENTPLUGINWIDGET_H -#define CEVENTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CEventPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CEventPluginWidget(QObject *parent = 0); - ~CEventPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec); - void release(); -}; - -#endif //CEVENTPLUGINWIDGET_H - +#ifndef CEVENTPLUGINWIDGET_H +#define CEVENTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CEventPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CEventPluginWidget(QObject *parent = 0); + ~CEventPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec); + void release(); +}; + +#endif //CEVENTPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventView.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventView.cpp index 83e566af..ea528e77 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventView.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventView.cpp @@ -1,31 +1,31 @@ -#include -#include "CEventView.h" - -CEventView::CEventView(QWidget *parent) - :QTableView(parent) -{ - setSortingEnabled(true); - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::MultiSelection); -} - -QModelIndexList CEventView::selectedItems() const -{ - QModelIndexList indexList; - foreach(QModelIndex index, selectedIndexes()) - { - if(index.column() == 0) - { - indexList.append(index); - } - } - return indexList; -} - -void CEventView::selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected) -{ - QTableView::selectionChanged(selected, deSelected); - emit sig_selectionChanged(selectedIndexes()); -} +#include +#include "CEventView.h" + +CEventView::CEventView(QWidget *parent) + :QTableView(parent) +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::MultiSelection); +} + +QModelIndexList CEventView::selectedItems() const +{ + QModelIndexList indexList; + foreach(QModelIndex index, selectedIndexes()) + { + if(index.column() == 0) + { + indexList.append(index); + } + } + return indexList; +} + +void CEventView::selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected) +{ + QTableView::selectionChanged(selected, deSelected); + emit sig_selectionChanged(selectedIndexes()); +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventView.h b/product/src/gui/plugin/ISCSEventWidget/CEventView.h index 360fc3e5..de3f7226 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventView.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventView.h @@ -1,21 +1,21 @@ -#ifndef CEventView_H -#define CEventView_H - -#include - -class CEventView : public QTableView -{ - Q_OBJECT -public: - CEventView(QWidget *parent = Q_NULLPTR); - - QModelIndexList selectedItems() const; - -signals: - void sig_selectionChanged(const QModelIndexList &list); - -protected slots: - virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected); -}; - -#endif // ALARMVIEW_H +#ifndef CEventView_H +#define CEventView_H + +#include + +class CEventView : public QTableView +{ + Q_OBJECT +public: + CEventView(QWidget *parent = Q_NULLPTR); + + QModelIndexList selectedItems() const; + +signals: + void sig_selectionChanged(const QModelIndexList &list); + +protected slots: + virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected); +}; + +#endif // ALARMVIEW_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CExcelPrinter.cpp b/product/src/gui/plugin/ISCSEventWidget/CExcelPrinter.cpp index 3c74ebea..53b4f8b4 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CExcelPrinter.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CExcelPrinter.cpp @@ -1,65 +1,65 @@ -#include "CExcelPrinter.h" -CExcelPrinter::CExcelPrinter(QObject *parent) : QObject(parent) -{ - -} - -void CExcelPrinter::initialize() -{ - -} - -void CExcelPrinter::printerByModel(CEventItemModel *model, const QString fileName) -{ - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "实时事件" ); - int rowcount=model->rowCount(); - int colcount=model->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - // 写内容 - for ( int i=0; idata(model->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText ); - } - } - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - // 提示导出路径 - QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); - emit sigShowResult(result); -} - -void CExcelPrinter::printerHisByModel(CEventHistoryModel *model, const QString fileName) -{ - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "历史事件" ); - // 写横向表头 - int rowcount=model->rowCount(); - int colcount=model->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - // 写内容 - for ( int i=0; idata(model->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText ); - } - } - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - // 提示导出路径 - QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); - emit sigShowResult(result); -} +#include "CExcelPrinter.h" +CExcelPrinter::CExcelPrinter(QObject *parent) : QObject(parent) +{ + +} + +void CExcelPrinter::initialize() +{ + +} + +void CExcelPrinter::printerByModel(CEventItemModel *model, const QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "实时事件" ); + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString()); + } + // 写内容 + for ( int i=0; idata(model->index(i, j)).toString(); + xlsx.write( i+2, j+1, sText ); + } + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + // 提示导出路径 + QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); + emit sigShowResult(result); +} + +void CExcelPrinter::printerHisByModel(CEventHistoryModel *model, const QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "历史事件" ); + // 写横向表头 + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString()); + } + // 写内容 + for ( int i=0; idata(model->index(i, j)).toString(); + xlsx.write( i+2, j+1, sText ); + } + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + // 提示导出路径 + QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); + emit sigShowResult(result); +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CExcelPrinter.h b/product/src/gui/plugin/ISCSEventWidget/CExcelPrinter.h index dc552b07..b3cdfeeb 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CExcelPrinter.h +++ b/product/src/gui/plugin/ISCSEventWidget/CExcelPrinter.h @@ -1,21 +1,21 @@ -#ifndef CEXCELPRINTER_H -#define CEXCELPRINTER_H - -#include -#include -#include -#include "model_excel/xlsx/xlsxdocument.h" -class CExcelPrinter : public QObject -{ - Q_OBJECT -public: - explicit CExcelPrinter(QObject *parent = nullptr); - void initialize(); -signals: - void sigShowResult(QString result); -public slots: - void printerByModel(CEventItemModel *model,const QString fileName); - void printerHisByModel(CEventHistoryModel *model,const QString fileName); -}; - -#endif // CEXCELPRINTER_H +#ifndef CEXCELPRINTER_H +#define CEXCELPRINTER_H + +#include +#include +#include +#include "model_excel/xlsx/xlsxdocument.h" +class CExcelPrinter : public QObject +{ + Q_OBJECT +public: + explicit CExcelPrinter(QObject *parent = nullptr); + void initialize(); +signals: + void sigShowResult(QString result); +public slots: + void printerByModel(CEventItemModel *model,const QString fileName); + void printerHisByModel(CEventHistoryModel *model,const QString fileName); +}; + +#endif // CEXCELPRINTER_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.cpp b/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.cpp index 965f5bcd..0482e2e0 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.cpp @@ -1,56 +1,56 @@ -#include "CMyCalendar.h" -#include "ui_CMyCalendar.h" -#include -#include -CMyCalendar::CMyCalendar(QWidget *parent) : - QWidget(parent), - ui(new Ui::CMyCalendar) -{ - ui->setupUi(this); - connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); - connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); - connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); - m_startTime = QDate::currentDate(); - m_endTime = QDate::currentDate(); - ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); - ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit_2->setReadOnly(true); -} - -CMyCalendar::~CMyCalendar() -{ - delete ui; -} - -void CMyCalendar::keyPressEvent(QKeyEvent *event) -{ - if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) - { - return ; - } - QWidget::keyPressEvent(event); -} - -void CMyCalendar::slot_endTime(QDate date) -{ - ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); - m_endTime = date; - if(m_startTime.isNull() || m_endTime < m_startTime) - { - //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); - return; - } - emit sig_endTimeClick(m_startTime,m_endTime); -} - -void CMyCalendar::slot_startTime(QDate date) -{ - m_startTime = date; - ui->lineEdit->setText(date.toString("yyyy-MM-dd")); -} - -void CMyCalendar::slot_cancle() -{ - emit sig_cancle(); -} +#include "CMyCalendar.h" +#include "ui_CMyCalendar.h" +#include +#include +CMyCalendar::CMyCalendar(QWidget *parent) : + QWidget(parent), + ui(new Ui::CMyCalendar) +{ + ui->setupUi(this); + connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); + connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); + connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); + m_startTime = QDate::currentDate(); + m_endTime = QDate::currentDate(); + ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); + ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit_2->setReadOnly(true); +} + +CMyCalendar::~CMyCalendar() +{ + delete ui; +} + +void CMyCalendar::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + { + return ; + } + QWidget::keyPressEvent(event); +} + +void CMyCalendar::slot_endTime(QDate date) +{ + ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); + m_endTime = date; + if(m_startTime.isNull() || m_endTime < m_startTime) + { + //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); + return; + } + emit sig_endTimeClick(m_startTime,m_endTime); +} + +void CMyCalendar::slot_startTime(QDate date) +{ + m_startTime = date; + ui->lineEdit->setText(date.toString("yyyy-MM-dd")); +} + +void CMyCalendar::slot_cancle() +{ + emit sig_cancle(); +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.h b/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.h index 4952b3b8..db92a26b 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.h +++ b/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.h @@ -1,35 +1,35 @@ -#ifndef CMYCALENDAR_H -#define CMYCALENDAR_H - -#include -#include -#include -namespace Ui { -class CMyCalendar; -} - -class CMyCalendar : public QWidget -{ - Q_OBJECT -signals: - void sig_endTimeClick(QDate startDate,QDate endDate); - void sig_startTimeClick(QDate date); - void sig_cancle(); -public: - explicit CMyCalendar(QWidget *parent = 0); - ~CMyCalendar(); - -protected: - void keyPressEvent(QKeyEvent *event); - -public slots: - void slot_endTime(QDate date); - void slot_startTime(QDate date); - void slot_cancle(); -private: - Ui::CMyCalendar *ui; - QDate m_startTime; - QDate m_endTime; -}; - -#endif // CMYCALENDAR_H +#ifndef CMYCALENDAR_H +#define CMYCALENDAR_H + +#include +#include +#include +namespace Ui { +class CMyCalendar; +} + +class CMyCalendar : public QWidget +{ + Q_OBJECT +signals: + void sig_endTimeClick(QDate startDate,QDate endDate); + void sig_startTimeClick(QDate date); + void sig_cancle(); +public: + explicit CMyCalendar(QWidget *parent = 0); + ~CMyCalendar(); + +protected: + void keyPressEvent(QKeyEvent *event); + +public slots: + void slot_endTime(QDate date); + void slot_startTime(QDate date); + void slot_cancle(); +private: + Ui::CMyCalendar *ui; + QDate m_startTime; + QDate m_endTime; +}; + +#endif // CMYCALENDAR_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.ui b/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.ui index 3cfb549d..98fb3b2c 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.ui +++ b/product/src/gui/plugin/ISCSEventWidget/CMyCalendar.ui @@ -1,119 +1,119 @@ - - - CMyCalendar - - - - 0 - 0 - 538 - 264 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 20 - 0 - - - - - - - Qt::AlignCenter - - - - - - - - - - 取消 - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - + + + CMyCalendar + + + + 0 + 0 + 538 + 264 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 20 + 0 + + + + + + + Qt::AlignCenter + + + + + + + + + + 取消 + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ISCSEventWidget/CMyCheckBox.cpp b/product/src/gui/plugin/ISCSEventWidget/CMyCheckBox.cpp index 9bc0eddb..b2bc5d95 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CMyCheckBox.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CMyCheckBox.cpp @@ -1,21 +1,21 @@ -#include "CMyCheckBox.h" -#include - -CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) - :QCheckBox(text,parent) -{ - -} - -CMyCheckBox::CMyCheckBox(QWidget *parent) - :QCheckBox(parent) -{ - -} - -void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) -{ - setChecked(!isChecked()); - emit clicked(isChecked()); - -} +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + setChecked(!isChecked()); + emit clicked(isChecked()); + +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CMyCheckBox.h b/product/src/gui/plugin/ISCSEventWidget/CMyCheckBox.h index 36947db5..bdba8dbc 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CMyCheckBox.h +++ b/product/src/gui/plugin/ISCSEventWidget/CMyCheckBox.h @@ -1,16 +1,16 @@ -#ifndef MYCHECKBOX_H -#define MYCHECKBOX_H - -#include - -class CMyCheckBox : public QCheckBox -{ -public: - CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); - CMyCheckBox(QWidget *parent = Q_NULLPTR); - -protected: - void mouseReleaseEvent(QMouseEvent *e); -}; - -#endif // MYCHECKBOX_H +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CMyListWidget.cpp b/product/src/gui/plugin/ISCSEventWidget/CMyListWidget.cpp index 3b542202..ded92615 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CMyListWidget.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CMyListWidget.cpp @@ -1,12 +1,12 @@ -#include "CMyListWidget.h" - -CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) -{ - -} - -void CMyListWidget::showEvent(QShowEvent *event) -{ - this->updateGeometries(); - QListWidget::showEvent(event); -} +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CMyListWidget.h b/product/src/gui/plugin/ISCSEventWidget/CMyListWidget.h index 9fc4491f..3e92461e 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CMyListWidget.h +++ b/product/src/gui/plugin/ISCSEventWidget/CMyListWidget.h @@ -1,15 +1,15 @@ -#ifndef CMYLISTWIDGET_H -#define CMYLISTWIDGET_H - -#include - -class CMyListWidget : public QListWidget -{ -public: - explicit CMyListWidget(QWidget *parent = 0); - -protected: - void showEvent(QShowEvent *event); -}; - -#endif // CMYLISTWIDGET_H +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/ISCSEventWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/ISCSEventWidget/CTableViewPrinter.cpp index 6702252f..afbf955c 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CTableViewPrinter.cpp @@ -1,122 +1,122 @@ -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include - -CTableViewPrinter::CTableViewPrinter(QTableView *view) - : m_pView(view) -{ - m_pModel = view->model(); -} - -void CTableViewPrinter::print(QPrinter * printer) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - - qreal marginHorizontal = 20; - qreal marginVertical = 20; - - QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); - printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); - - int length = 0; - horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); - for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) - { - length += horizontalHeader->sectionSize(nSection); - } - horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); - - QPainter painter(printer); - - renderHeader(painter); - - int offset = 0; - int currentPage = 0; - int horizontalHeaderHeight = horizontalHeader->height(); - for(int row(0); row < m_pModel->rowCount(); row++) - { - if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) - { - horizontalHeaderHeight = 0; - } - - - if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) - { - printer->newPage(); - currentPage++; - offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - } - - for(int column(0); column < m_pModel->columnCount(); column++) - { - int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - int rowHeight = m_pView->rowHeight(row); - int columnWidth = m_pView->columnWidth(column); - - //< draw item - QStyleOptionViewItem opt; - opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); - painter.save(); - painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); - painter.restore(); - - //< Vertical Line - if(column == 0) - { - QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - //< Horizontal Line - int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; - QPoint left(verticalHeader->width(), rowPosition); - QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); - drawGridLine(&painter, left, right); - - } -} - -void CTableViewPrinter::renderHeader(QPainter &painter) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - for(int column(0); column < horizontalHeader->count(); column++) - { - painter.save(); - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); - painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); - painter.restore(); - } - int columnPosition = horizontalHeader->width() + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); -} - -void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) -{ - painter->save(); - QStyleOptionViewItem opt; - const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); - const QColor gridColor = static_cast(gridHint); - painter->setPen(gridColor); - painter->drawLine(p1, p2); - painter->restore(); -} +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include + +CTableViewPrinter::CTableViewPrinter(QTableView *view) + : m_pView(view) +{ + m_pModel = view->model(); +} + +void CTableViewPrinter::print(QPrinter * printer) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); + printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + + int length = 0; + horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); + for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) + { + length += horizontalHeader->sectionSize(nSection); + } + horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); + + QPainter painter(printer); + + renderHeader(painter); + + int offset = 0; + int currentPage = 0; + int horizontalHeaderHeight = horizontalHeader->height(); + for(int row(0); row < m_pModel->rowCount(); row++) + { + if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) + { + horizontalHeaderHeight = 0; + } + + + if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) + { + printer->newPage(); + currentPage++; + offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + } + + for(int column(0); column < m_pModel->columnCount(); column++) + { + int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + int rowHeight = m_pView->rowHeight(row); + int columnWidth = m_pView->columnWidth(column); + + //< draw item + QStyleOptionViewItem opt; + opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); + painter.save(); + painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); + painter.restore(); + + //< Vertical Line + if(column == 0) + { + QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + //< Horizontal Line + int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; + QPoint left(verticalHeader->width(), rowPosition); + QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); + drawGridLine(&painter, left, right); + + } +} + +void CTableViewPrinter::renderHeader(QPainter &painter) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + for(int column(0); column < horizontalHeader->count(); column++) + { + painter.save(); + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); + painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); + painter.restore(); + } + int columnPosition = horizontalHeader->width() + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); +} + +void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + QStyleOptionViewItem opt; + const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); + const QColor gridColor = static_cast(gridHint); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} diff --git a/product/src/gui/plugin/ISCSEventWidget/CTableViewPrinter.h b/product/src/gui/plugin/ISCSEventWidget/CTableViewPrinter.h index 4faf41ed..839198f2 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/ISCSEventWidget/CTableViewPrinter.h @@ -1,24 +1,24 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H - -class QPointF; -class QPainter; -class QPrinter; -class QTableView; -class QAbstractItemModel; - -class CTableViewPrinter -{ -public: - explicit CTableViewPrinter(QTableView * view); - - void print(QPrinter *printer); - void renderHeader(QPainter &painter); - void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); - -private: - QTableView * m_pView; - QAbstractItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H + +class QPointF; +class QPainter; +class QPrinter; +class QTableView; +class QAbstractItemModel; + +class CTableViewPrinter +{ +public: + explicit CTableViewPrinter(QTableView * view); + + void print(QPrinter *printer); + void renderHeader(QPainter &painter); + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + +private: + QTableView * m_pView; + QAbstractItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/ISCSEventWidget/EventWidget.pro b/product/src/gui/plugin/ISCSEventWidget/EventWidget.pro index e0cfe41e..496c73c8 100644 --- a/product/src/gui/plugin/ISCSEventWidget/EventWidget.pro +++ b/product/src/gui/plugin/ISCSEventWidget/EventWidget.pro @@ -1,61 +1,61 @@ -QT += core sql xml printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = ISCSEventWidget - -CONFIG += plugin - -HEADERS = \ - CEventMsgInfo.h \ - CEventDataCollect.h \ - CEventView.h \ - CEventMsgManage.h \ - CEventItemModel.h \ - CEventHistoryModel.h \ - CEventFilterDialog.h \ - CEventForm.h \ - CEventPluginWidget.h \ - CTableViewPrinter.h \ - CMyListWidget.h \ - CMyCalendar.h \ - CMyCheckBox.h \ - CExcelPrinter.h - -SOURCES = \ - CEventMsgInfo.cpp \ - CEventDataCollect.cpp \ - CEventView.cpp \ - CEventMsgManage.cpp \ - CEventItemModel.cpp \ - CEventHistoryModel.cpp \ - CEventFilterDialog.cpp \ - CEventForm.cpp \ - CEventPluginWidget.cpp \ - CTableViewPrinter.cpp \ - CMyListWidget.cpp \ - CMyCalendar.cpp \ - CMyCheckBox.cpp \ - CExcelPrinter.cpp - -FORMS += \ - CEventFilterDialog.ui \ - CEventForm.ui \ - CMyCalendar.ui - -RESOURCES += \ - resource.qrc - -LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -ldb_sysinfo_api -lpub_sysinfo_api -lnet_msg_bus_api -lalarm_server_api -lmodel_excel - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - - +QT += core sql xml printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = ISCSEventWidget + +CONFIG += plugin + +HEADERS = \ + CEventMsgInfo.h \ + CEventDataCollect.h \ + CEventView.h \ + CEventMsgManage.h \ + CEventItemModel.h \ + CEventHistoryModel.h \ + CEventFilterDialog.h \ + CEventForm.h \ + CEventPluginWidget.h \ + CTableViewPrinter.h \ + CMyListWidget.h \ + CMyCalendar.h \ + CMyCheckBox.h \ + CExcelPrinter.h + +SOURCES = \ + CEventMsgInfo.cpp \ + CEventDataCollect.cpp \ + CEventView.cpp \ + CEventMsgManage.cpp \ + CEventItemModel.cpp \ + CEventHistoryModel.cpp \ + CEventFilterDialog.cpp \ + CEventForm.cpp \ + CEventPluginWidget.cpp \ + CTableViewPrinter.cpp \ + CMyListWidget.cpp \ + CMyCalendar.cpp \ + CMyCheckBox.cpp \ + CExcelPrinter.cpp + +FORMS += \ + CEventFilterDialog.ui \ + CEventForm.ui \ + CMyCalendar.ui + +RESOURCES += \ + resource.qrc + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -ldb_sysinfo_api -lpub_sysinfo_api -lnet_msg_bus_api -lalarm_server_api -lmodel_excel + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + + diff --git a/product/src/gui/plugin/ISCSEventWidget/main.cpp b/product/src/gui/plugin/ISCSEventWidget/main.cpp index 84138c0a..41afc697 100644 --- a/product/src/gui/plugin/ISCSEventWidget/main.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/main.cpp @@ -1,42 +1,42 @@ -#include -//#include "CEventPlugin.h" -#include "CEventForm.h" -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "CEventDataCollect.h" -#include "perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - - - //<初始化消息总线 - //kbd_public::StartLogSystem(NULL, "HMI", "Alarm_Client"); - kbd_public::StartLogSystem(NULL, "HMI"); - kbd_net::initMsgBus("Alarm_Client", "1", true); - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - permMngPtr->PermDllInit(); - if(permMngPtr->SysLogin("2", "2", 1, 12*60*60, "hmi") != 0) - { - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return -1; - } - // CEventPlugin p; - { - QApplication app(argc, argv); - CEventForm n(NULL,false); - n.show(); - - app.exec(); - } - - - - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include +//#include "CEventPlugin.h" +#include "CEventForm.h" +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "CEventDataCollect.h" +#include "perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + + + //<初始化消息总线 + //kbd_public::StartLogSystem(NULL, "HMI", "Alarm_Client"); + kbd_public::StartLogSystem(NULL, "HMI"); + kbd_net::initMsgBus("Alarm_Client", "1", true); + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + permMngPtr->PermDllInit(); + if(permMngPtr->SysLogin("2", "2", 1, 12*60*60, "hmi") != 0) + { + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return -1; + } + // CEventPlugin p; + { + QApplication app(argc, argv); + CEventForm n(NULL,false); + n.show(); + + app.exec(); + } + + + + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/ISCSEventWidget/resource.qrc b/product/src/gui/plugin/ISCSEventWidget/resource.qrc index 3fd215d0..7646d2b3 100644 --- a/product/src/gui/plugin/ISCSEventWidget/resource.qrc +++ b/product/src/gui/plugin/ISCSEventWidget/resource.qrc @@ -1 +1 @@ - + diff --git a/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendModel.cpp b/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendModel.cpp index c5c3ccc3..b9606cee 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendModel.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendModel.cpp @@ -1,537 +1,537 @@ -#include "CCurveLegendModel.h" -#include "CTrendGraph.h" -#include -#include -#include -#include -#include -#include - -ColorWidget::ColorWidget(QWidget *parent) - : QWidget(parent) -{ - setStyleSheet(""); -} - -ColorWidget::~ColorWidget() -{ -} - -void ColorWidget::setColor(const QColor &color) -{ - this->m_color = color; - emit colorChanged(); -} - -QColor ColorWidget::color() const -{ - return m_color; -} - -void ColorWidget::updateCurrentColor() -{ - QColorDialog dlg(this); - dlg.setOption(QColorDialog::DontUseNativeDialog); - dlg.setWindowFlag(Qt::FramelessWindowHint); - dlg.setCurrentColor(m_color); - dlg.exec(); - if(dlg.selectedColor().isValid()) - { - setColor(dlg.selectedColor()); - } -} - -void ColorWidget::paintEvent(QPaintEvent *event) -{ - QPainter p(this); - p.setPen(Qt::white); - p.setBrush(m_color); - p.drawRect(rect().adjusted(1, 1, -2, -2)); - QWidget::paintEvent(event); -} - -void ColorWidget::mousePressEvent(QMouseEvent *event) -{ - QWidget::mousePressEvent(event); - updateCurrentColor(); -} - - -CCurveLegnedDelegate::CCurveLegnedDelegate(QObject *parent) - : QStyledItemDelegate(parent) -{ - -} - -void CCurveLegnedDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QStyleOptionViewItem viewOption(option); - initStyleOption(&viewOption, index); - if (option.state.testFlag(QStyle::State_HasFocus)) - { - viewOption.state = viewOption.state ^ QStyle::State_HasFocus; - } - QStyledItemDelegate::paint(painter, viewOption, index); - - if(!index.isValid() || !const_cast(index.model())) - { - return; - } - CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); - if(!model) - { - return; - } - - if(CCurveLegendModel::COLOR == index.column()) - { - painter->save(); - painter->fillRect(option.rect.adjusted(2, 2,-2, -2), QBrush(Qt::white)); - painter->fillRect(option.rect.adjusted(2, 2,-2, -2), QBrush(model->data(index).value())); - painter->restore(); - } -} - -QWidget *CCurveLegnedDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(option) - if(!index.isValid() || !const_cast(index.model())) - { - return Q_NULLPTR; - } - CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); - if(!model) - { - return Q_NULLPTR; - } - - if(CCurveLegendModel::COLOR == index.column()) - { - ColorWidget * colorWidget = new ColorWidget(parent); - connect(colorWidget, &ColorWidget::colorChanged, this, &CCurveLegnedDelegate::slotColorChangde); - return colorWidget; - } - if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) - { - QDoubleSpinBox * spinBox = new QDoubleSpinBox(parent); - return spinBox; - } - - return Q_NULLPTR; -} - -void CCurveLegnedDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - if(!index.isValid() || Q_NULLPTR == editor) - { - return; - } - - CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); - if(!model) - { - return; - } - - if(CCurveLegendModel::COLOR == index.column()) - { - ColorWidget * colorWidget = dynamic_cast(editor); - if(colorWidget) - { - colorWidget->setColor(model->data(index).value()); - } - return; - } - if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) - { - QDoubleSpinBox * spinBox = dynamic_cast(editor); - if(spinBox) - { - spinBox->setValue(model->data(index).toDouble()); - spinBox->setSingleStep(1.); - spinBox->setMaximum(10000); - spinBox->setMinimum(-10000); - } - return; - } - return; -} - -void CCurveLegnedDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - if(!index.isValid() || !const_cast(index.model())) - { - return; - } - if(!model) - { - return; - } - - if(dynamic_cast(editor)) - { - model->setData(index, dynamic_cast(editor)->value()); - return; - } - else if(dynamic_cast(editor)) - { - model->setData(index, dynamic_cast(editor)->color()); - return; - } - -} - -bool CCurveLegnedDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ -// if(index.column() == 0 && event->type() == QEvent::MouseButtonPress) -// { -// QMouseEvent *mouseEvent = static_cast(event); -// if(mouseEvent->button() == Qt::LeftButton && option.rect.contains(mouseEvent->pos())) -// { -// if(const_cast(index.model())) -// { -// CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); -// if(!model) -// { -// return QStyledItemDelegate::editorEvent(event, model, option, index); -// } -// } -// } -// } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} - -void CCurveLegnedDelegate::slotColorChangde() -{ - QWidget * pWidget = dynamic_cast(sender()); - if(pWidget) - { - emit commitData(pWidget); - emit closeEditor(pWidget); - } -} - -CCurveLegendModel::CCurveLegendModel(QObject *parent) - : QAbstractTableModel(parent), - m_graph(Q_NULLPTR) -{ - m_header << tr("名称") << tr("颜色") << tr("值") << tr("最大值") << tr("最大值时间") << tr("最小值") << tr("最小值时间") << tr("平均值") << tr("单位") << tr("Y轴缩放系数") << tr("Y轴偏移系数"); -} - -void CCurveLegendModel::setMode(const CCurveLegendModel::LengedMode &mode) -{ - m_lengedMode = mode; - update(); -} - -void CCurveLegendModel::setTrendGraph(CTrendGraph *graph) -{ - if(nullptr == graph) - { - return; - } - beginResetModel(); - m_graph = graph; - endResetModel(); -} - -void CCurveLegendModel::setTrendCurrentValues(QList list) -{ - m_currentValue.swap(list); - update(); -} - -void CCurveLegendModel::update() -{ - QModelIndex topLeft = createIndex(0, VALUE); - QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); - emit dataChanged(topLeft, bottomRight); -} - -void CCurveLegendModel::clear() -{ - beginResetModel(); - m_graph = Q_NULLPTR; - endResetModel(); -} - -QVariant CCurveLegendModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_header.at(section); - } - } - return QVariant(); -} - -int CCurveLegendModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid() || Q_NULLPTR == m_graph) - return 0; - - return m_graph->curves().count(); -} - -int CCurveLegendModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid() || Q_NULLPTR == m_graph) - return 0; - - return m_header.count(); -} - -QVariant CCurveLegendModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid() || Q_NULLPTR == m_graph) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == NAME) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - } - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - - if(Qt::CheckStateRole == role && NAME == index.column()) - { - if(m_graph->curves().at(index.row()).visible) - { - return Qt::Checked; - } - else - { - return Qt::Unchecked; - } - } - - if(Qt::DisplayRole != role) - { - return QVariant(); - } - - Curve curve = m_graph->curves().at(index.row()); - switch (index.column()) - { - case NAME: - { - return curve.desc; - } - break; - case COLOR: - { - return curve.color; - } - break; - case VALUE: - { - if(qIsNaN(m_currentValue.value(index.row()))) - { - return QString("NaN"); - } - else - { - return m_currentValue.value(index.row()); - } - } - break; - case MAX: - { - if(LENGED_RT_MODE == m_lengedMode) - { - if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMax) < _EPSILON_) - { - return QString("--"); - } - return curve.rtMax; - } - else - { - if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.hisMax) < _EPSILON_) - { - return QString("--"); - } - return curve.hisMax; - } - } - break; - case MAXTIME: - { - if(LENGED_RT_MODE == m_lengedMode) - { - if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMaxTime) < _EPSILON_) - { - return QString("--"); - } - return QDateTime::fromMSecsSinceEpoch(curve.rtMaxTime).toString("hh:mm:ss"); - } - else - { - if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.hisMaxTime) < _EPSILON_) - { - return QString("--"); - } - return QDateTime::fromMSecsSinceEpoch(curve.hisMaxTime).toString("yyyy-MM-dd hh:mm:ss"); - } - } - break; - case MIN: - { - if(LENGED_RT_MODE == m_lengedMode) - { - if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.rtMin) < _EPSILON_) - { - return QString("--"); - } - return curve.rtMin; - } - else - { - if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.hisMin) < _EPSILON_) - { - return QString("--"); - } - return curve.hisMin; - } - } - break; - case MINTIME: - { - if(LENGED_RT_MODE == m_lengedMode) - { - if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.rtMinTime) < _EPSILON_) - { - return QString("--"); - } - return QDateTime::fromMSecsSinceEpoch(curve.rtMinTime).toString("hh:mm:ss"); - } - else - { - if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.hisMinTime) < _EPSILON_) - { - return QString("--"); - } - return QDateTime::fromMSecsSinceEpoch(curve.hisMinTime).toString("yyyy-MM-dd hh:mm:ss"); - } - } - break; - case AVE: - { - - if(LENGED_RT_MODE == m_lengedMode) - { - if("analog" != curve.type || qAbs((-DBL_MAX) - curve.rtAverage) < _EPSILON_ || qIsNaN(curve.rtAverage)) - { - return QString("--"); - } - return curve.rtAverage; - } - else - { - if("analog" != curve.type || qAbs((-DBL_MAX) - curve.hisAverage) < _EPSILON_ || qIsNaN(curve.hisAverage)) - { - return QString("--"); - } - return curve.hisAverage; - } - } - break; - case UNIT: - { - if(curve.unit.isEmpty()) - { - return QString("--"); - } - return curve.unit; - } - break; - case FACTOR: - { - return curve.factor; - } - break; - case OFFSET: - { - return curve.offset; - } - break; - default: - break; - } - - return QVariant(); -} - -bool CCurveLegendModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if(!index.isValid()) - { - return false; - } - - if(Qt::CheckStateRole == role && NAME == index.column()) - { - m_graph->setCurveVisible(index.row(), value.toBool()); - emit graphVisibleChanged(); - return true; - } - if(Qt::EditRole != role) - { - return false; - } - - if(COLOR == index.column()) - { - m_graph->setCurveColor(index.row(), value.value()); - } - if(FACTOR == index.column()) - { - m_graph->setCurveFactor(index.row(), value.toDouble()); - } - else if(OFFSET == index.column()) - { - m_graph->setCurveOffset(index.row(), value.toDouble()); - } - emit graphPropertyChanged(); - - QModelIndex topLeft = createIndex(0, 0); - QModelIndex bottomright = createIndex(rowCount() - 1, columnCount() - 1); - emit dataChanged(topLeft, bottomright); - - return true; -} - -Qt::ItemFlags CCurveLegendModel::flags(const QModelIndex &index) const -{ - if(!index.isValid()) - { - return Qt::NoItemFlags; - } - - Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - if(COLOR == index.column() || FACTOR == index.column() || OFFSET == index.column()) - { - itemFlags |= Qt::ItemIsEditable; - } - else if(NAME == index.column()) - { - itemFlags |= Qt::ItemIsUserCheckable; - } - - return itemFlags; -} - -void CCurveLegendModel::setChildrenCheckState(const Qt::CheckState &state) -{ - for(int nChildIndex(0); nChildIndex < rowCount(); nChildIndex++) - { - m_graph->setCurveVisible(nChildIndex, state); - } - emit graphVisibleChanged(); -} +#include "CCurveLegendModel.h" +#include "CTrendGraph.h" +#include +#include +#include +#include +#include +#include + +ColorWidget::ColorWidget(QWidget *parent) + : QWidget(parent) +{ + setStyleSheet(""); +} + +ColorWidget::~ColorWidget() +{ +} + +void ColorWidget::setColor(const QColor &color) +{ + this->m_color = color; + emit colorChanged(); +} + +QColor ColorWidget::color() const +{ + return m_color; +} + +void ColorWidget::updateCurrentColor() +{ + QColorDialog dlg(this); + dlg.setOption(QColorDialog::DontUseNativeDialog); + dlg.setWindowFlag(Qt::FramelessWindowHint); + dlg.setCurrentColor(m_color); + dlg.exec(); + if(dlg.selectedColor().isValid()) + { + setColor(dlg.selectedColor()); + } +} + +void ColorWidget::paintEvent(QPaintEvent *event) +{ + QPainter p(this); + p.setPen(Qt::white); + p.setBrush(m_color); + p.drawRect(rect().adjusted(1, 1, -2, -2)); + QWidget::paintEvent(event); +} + +void ColorWidget::mousePressEvent(QMouseEvent *event) +{ + QWidget::mousePressEvent(event); + updateCurrentColor(); +} + + +CCurveLegnedDelegate::CCurveLegnedDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ + +} + +void CCurveLegnedDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem viewOption(option); + initStyleOption(&viewOption, index); + if (option.state.testFlag(QStyle::State_HasFocus)) + { + viewOption.state = viewOption.state ^ QStyle::State_HasFocus; + } + QStyledItemDelegate::paint(painter, viewOption, index); + + if(!index.isValid() || !const_cast(index.model())) + { + return; + } + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + painter->save(); + painter->fillRect(option.rect.adjusted(2, 2,-2, -2), QBrush(Qt::white)); + painter->fillRect(option.rect.adjusted(2, 2,-2, -2), QBrush(model->data(index).value())); + painter->restore(); + } +} + +QWidget *CCurveLegnedDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid() || !const_cast(index.model())) + { + return Q_NULLPTR; + } + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return Q_NULLPTR; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + ColorWidget * colorWidget = new ColorWidget(parent); + connect(colorWidget, &ColorWidget::colorChanged, this, &CCurveLegnedDelegate::slotColorChangde); + return colorWidget; + } + if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) + { + QDoubleSpinBox * spinBox = new QDoubleSpinBox(parent); + return spinBox; + } + + return Q_NULLPTR; +} + +void CCurveLegnedDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if(!index.isValid() || Q_NULLPTR == editor) + { + return; + } + + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + ColorWidget * colorWidget = dynamic_cast(editor); + if(colorWidget) + { + colorWidget->setColor(model->data(index).value()); + } + return; + } + if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) + { + QDoubleSpinBox * spinBox = dynamic_cast(editor); + if(spinBox) + { + spinBox->setValue(model->data(index).toDouble()); + spinBox->setSingleStep(1.); + spinBox->setMaximum(10000); + spinBox->setMinimum(-10000); + } + return; + } + return; +} + +void CCurveLegnedDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + if(!index.isValid() || !const_cast(index.model())) + { + return; + } + if(!model) + { + return; + } + + if(dynamic_cast(editor)) + { + model->setData(index, dynamic_cast(editor)->value()); + return; + } + else if(dynamic_cast(editor)) + { + model->setData(index, dynamic_cast(editor)->color()); + return; + } + +} + +bool CCurveLegnedDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ +// if(index.column() == 0 && event->type() == QEvent::MouseButtonPress) +// { +// QMouseEvent *mouseEvent = static_cast(event); +// if(mouseEvent->button() == Qt::LeftButton && option.rect.contains(mouseEvent->pos())) +// { +// if(const_cast(index.model())) +// { +// CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); +// if(!model) +// { +// return QStyledItemDelegate::editorEvent(event, model, option, index); +// } +// } +// } +// } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +void CCurveLegnedDelegate::slotColorChangde() +{ + QWidget * pWidget = dynamic_cast(sender()); + if(pWidget) + { + emit commitData(pWidget); + emit closeEditor(pWidget); + } +} + +CCurveLegendModel::CCurveLegendModel(QObject *parent) + : QAbstractTableModel(parent), + m_graph(Q_NULLPTR) +{ + m_header << tr("名称") << tr("颜色") << tr("值") << tr("最大值") << tr("最大值时间") << tr("最小值") << tr("最小值时间") << tr("平均值") << tr("单位") << tr("Y轴缩放系数") << tr("Y轴偏移系数"); +} + +void CCurveLegendModel::setMode(const CCurveLegendModel::LengedMode &mode) +{ + m_lengedMode = mode; + update(); +} + +void CCurveLegendModel::setTrendGraph(CTrendGraph *graph) +{ + if(nullptr == graph) + { + return; + } + beginResetModel(); + m_graph = graph; + endResetModel(); +} + +void CCurveLegendModel::setTrendCurrentValues(QList list) +{ + m_currentValue.swap(list); + update(); +} + +void CCurveLegendModel::update() +{ + QModelIndex topLeft = createIndex(0, VALUE); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); + emit dataChanged(topLeft, bottomRight); +} + +void CCurveLegendModel::clear() +{ + beginResetModel(); + m_graph = Q_NULLPTR; + endResetModel(); +} + +QVariant CCurveLegendModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); +} + +int CCurveLegendModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid() || Q_NULLPTR == m_graph) + return 0; + + return m_graph->curves().count(); +} + +int CCurveLegendModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid() || Q_NULLPTR == m_graph) + return 0; + + return m_header.count(); +} + +QVariant CCurveLegendModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || Q_NULLPTR == m_graph) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == NAME) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + } + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + if(Qt::CheckStateRole == role && NAME == index.column()) + { + if(m_graph->curves().at(index.row()).visible) + { + return Qt::Checked; + } + else + { + return Qt::Unchecked; + } + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + Curve curve = m_graph->curves().at(index.row()); + switch (index.column()) + { + case NAME: + { + return curve.desc; + } + break; + case COLOR: + { + return curve.color; + } + break; + case VALUE: + { + if(qIsNaN(m_currentValue.value(index.row()))) + { + return QString("NaN"); + } + else + { + return m_currentValue.value(index.row()); + } + } + break; + case MAX: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMax) < _EPSILON_) + { + return QString("--"); + } + return curve.rtMax; + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.hisMax) < _EPSILON_) + { + return QString("--"); + } + return curve.hisMax; + } + } + break; + case MAXTIME: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMaxTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.rtMaxTime).toString("hh:mm:ss"); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.hisMaxTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.hisMaxTime).toString("yyyy-MM-dd hh:mm:ss"); + } + } + break; + case MIN: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.rtMin) < _EPSILON_) + { + return QString("--"); + } + return curve.rtMin; + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.hisMin) < _EPSILON_) + { + return QString("--"); + } + return curve.hisMin; + } + } + break; + case MINTIME: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.rtMinTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.rtMinTime).toString("hh:mm:ss"); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.hisMinTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.hisMinTime).toString("yyyy-MM-dd hh:mm:ss"); + } + } + break; + case AVE: + { + + if(LENGED_RT_MODE == m_lengedMode) + { + if("analog" != curve.type || qAbs((-DBL_MAX) - curve.rtAverage) < _EPSILON_ || qIsNaN(curve.rtAverage)) + { + return QString("--"); + } + return curve.rtAverage; + } + else + { + if("analog" != curve.type || qAbs((-DBL_MAX) - curve.hisAverage) < _EPSILON_ || qIsNaN(curve.hisAverage)) + { + return QString("--"); + } + return curve.hisAverage; + } + } + break; + case UNIT: + { + if(curve.unit.isEmpty()) + { + return QString("--"); + } + return curve.unit; + } + break; + case FACTOR: + { + return curve.factor; + } + break; + case OFFSET: + { + return curve.offset; + } + break; + default: + break; + } + + return QVariant(); +} + +bool CCurveLegendModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid()) + { + return false; + } + + if(Qt::CheckStateRole == role && NAME == index.column()) + { + m_graph->setCurveVisible(index.row(), value.toBool()); + emit graphVisibleChanged(); + return true; + } + if(Qt::EditRole != role) + { + return false; + } + + if(COLOR == index.column()) + { + m_graph->setCurveColor(index.row(), value.value()); + } + if(FACTOR == index.column()) + { + m_graph->setCurveFactor(index.row(), value.toDouble()); + } + else if(OFFSET == index.column()) + { + m_graph->setCurveOffset(index.row(), value.toDouble()); + } + emit graphPropertyChanged(); + + QModelIndex topLeft = createIndex(0, 0); + QModelIndex bottomright = createIndex(rowCount() - 1, columnCount() - 1); + emit dataChanged(topLeft, bottomright); + + return true; +} + +Qt::ItemFlags CCurveLegendModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + { + return Qt::NoItemFlags; + } + + Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + if(COLOR == index.column() || FACTOR == index.column() || OFFSET == index.column()) + { + itemFlags |= Qt::ItemIsEditable; + } + else if(NAME == index.column()) + { + itemFlags |= Qt::ItemIsUserCheckable; + } + + return itemFlags; +} + +void CCurveLegendModel::setChildrenCheckState(const Qt::CheckState &state) +{ + for(int nChildIndex(0); nChildIndex < rowCount(); nChildIndex++) + { + m_graph->setCurveVisible(nChildIndex, state); + } + emit graphVisibleChanged(); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendModel.h b/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendModel.h index abfe6f48..f55fa7d0 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendModel.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendModel.h @@ -1,117 +1,117 @@ -#ifndef CCURVELEGENDMODEL_H -#define CCURVELEGENDMODEL_H - -#include -#include -#include - - -class CTrendGraph; - -class ColorWidget : public QWidget -{ - Q_OBJECT -public: - explicit ColorWidget(QWidget *parent=Q_NULLPTR); - ~ColorWidget(); - - void setColor(const QColor &color); - QColor color() const; - - void updateCurrentColor(); - -signals: - void colorChanged(); - -protected: - void paintEvent(QPaintEvent * event); - void mousePressEvent(QMouseEvent *event); - -private: - QColor m_color; -}; - -class CCurveLegnedDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CCurveLegnedDelegate(QObject *parent = nullptr); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - - QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; - - void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; - - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; - -protected: - bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); - -private slots: - void slotColorChangde(); -}; - -class CCurveLegendModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - enum LengedMode - { - LENGED_RT_MODE = 0, - LENGED_HIS_MODE - }; - - enum ColumnField - { - NAME = 0, - COLOR, - VALUE, - MAX, - MAXTIME, - MIN, - MINTIME, - AVE, - UNIT, - FACTOR, - OFFSET - }; - - - explicit CCurveLegendModel(QObject *parent = nullptr); - - void setMode(const LengedMode &mode); - - void setTrendGraph(CTrendGraph * graph); - - void setTrendCurrentValues(QList list); - - void update(); - - void clear(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - - Qt::ItemFlags flags(const QModelIndex &index) const; - - void setChildrenCheckState(const Qt::CheckState &state); - -signals: - void graphVisibleChanged(); - void graphPropertyChanged(); - -private: - LengedMode m_lengedMode; - QStringList m_header; - CTrendGraph * m_graph; - QList m_currentValue; -}; - -#endif // CCURVELEGENDMODEL_H +#ifndef CCURVELEGENDMODEL_H +#define CCURVELEGENDMODEL_H + +#include +#include +#include + + +class CTrendGraph; + +class ColorWidget : public QWidget +{ + Q_OBJECT +public: + explicit ColorWidget(QWidget *parent=Q_NULLPTR); + ~ColorWidget(); + + void setColor(const QColor &color); + QColor color() const; + + void updateCurrentColor(); + +signals: + void colorChanged(); + +protected: + void paintEvent(QPaintEvent * event); + void mousePressEvent(QMouseEvent *event); + +private: + QColor m_color; +}; + +class CCurveLegnedDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CCurveLegnedDelegate(QObject *parent = nullptr); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + +protected: + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); + +private slots: + void slotColorChangde(); +}; + +class CCurveLegendModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + enum LengedMode + { + LENGED_RT_MODE = 0, + LENGED_HIS_MODE + }; + + enum ColumnField + { + NAME = 0, + COLOR, + VALUE, + MAX, + MAXTIME, + MIN, + MINTIME, + AVE, + UNIT, + FACTOR, + OFFSET + }; + + + explicit CCurveLegendModel(QObject *parent = nullptr); + + void setMode(const LengedMode &mode); + + void setTrendGraph(CTrendGraph * graph); + + void setTrendCurrentValues(QList list); + + void update(); + + void clear(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const; + + void setChildrenCheckState(const Qt::CheckState &state); + +signals: + void graphVisibleChanged(); + void graphPropertyChanged(); + +private: + LengedMode m_lengedMode; + QStringList m_header; + CTrendGraph * m_graph; + QList m_currentValue; +}; + +#endif // CCURVELEGENDMODEL_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendView.cpp b/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendView.cpp index 7a67e18f..4df730f2 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendView.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendView.cpp @@ -1,22 +1,22 @@ -#include "CCurveLegendView.h" -#include "CCurveLegendModel.h" -#include -#include - -CCurveLegendView::CCurveLegendView(QWidget *parent) - : QTableView(parent) -{ - -} - -void CCurveLegendView::contextMenuEvent(QContextMenuEvent *event) -{ - CCurveLegendModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR != pModel) - { - QMenu menu; - menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(Qt::Unchecked); }); - menu.exec(event->globalPos()); - } - return; -} +#include "CCurveLegendView.h" +#include "CCurveLegendModel.h" +#include +#include + +CCurveLegendView::CCurveLegendView(QWidget *parent) + : QTableView(parent) +{ + +} + +void CCurveLegendView::contextMenuEvent(QContextMenuEvent *event) +{ + CCurveLegendModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QMenu menu; + menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(Qt::Unchecked); }); + menu.exec(event->globalPos()); + } + return; +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendView.h b/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendView.h index ba3f55f8..b73453c2 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendView.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CCurveLegendView.h @@ -1,16 +1,16 @@ -#ifndef CCURVELEGENDVIEW_H -#define CCURVELEGENDVIEW_H - -#include - -class CCurveLegendView : public QTableView -{ - Q_OBJECT -public: - CCurveLegendView(QWidget *parent = Q_NULLPTR); - -protected: - void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // CCURVELEGENDVIEW_H +#ifndef CCURVELEGENDVIEW_H +#define CCURVELEGENDVIEW_H + +#include + +class CCurveLegendView : public QTableView +{ + Q_OBJECT +public: + CCurveLegendView(QWidget *parent = Q_NULLPTR); + +protected: + void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // CCURVELEGENDVIEW_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CHisDataManage.cpp b/product/src/gui/plugin/ISCSTrendCurves/CHisDataManage.cpp index 23c32dfc..6ed7a392 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CHisDataManage.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CHisDataManage.cpp @@ -1,225 +1,225 @@ -#include "CHisDataManage.h" -#include "db_his_query_api/DbHisQueryApi.h" -#include "sample_server_api/SampleDefine.h" -#include "CTrendInfoManage.h" -#include "pub_logger_api/logger.h" -using namespace kbd_dbms; - -CHisDataManage::CHisDataManage(QObject *parent) - : QObject(parent), - m_TsdbExcuting(false), - m_bHasPendingCommand(false), - m_tsdbConnPtr((CTsdbConn*)nullptr) -{ - -} - -CHisDataManage::~CHisDataManage() -{ - QMutexLocker locker(&m_mutex); - m_tsdbConnPtr = boost::shared_ptr(Q_NULLPTR); - releaseTsdbApi(); - foreach (TsdbCommand cmd, m_listCommand) - { - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; - } - m_listCommand.clear(); -} - -bool CHisDataManage::isTsdbExuting() -{ - QMutexLocker locker(&m_mutex); - return m_TsdbExcuting; -} - -void CHisDataManage::postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, double lower, double upper, int nGroupByMinute, EnComputeMethod method) -{ - QMutexLocker locker(&m_mutex); - m_bHasPendingCommand = true; - TsdbCommand cmd; - cmd.type = type; - cmd.pVecMpKey = vecMpKey; - cmd.lower = lower; - cmd.upper = upper; - cmd.nGroupByMinute = nGroupByMinute; - cmd.method = method; - m_listCommand.push_back(cmd); -} - -void CHisDataManage::release() -{ - delete this; -} - -bool CHisDataManage::getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr) -{ - //< 不使用getOneUseableConn()返回的正式库测试 - // ptr.reset(new kbd_dbms::CTsdbConn("127.0.0.1", -1, "iscs6000", "", "")); - // return true; - if(m_tsdbConnPtr != NULL) - { - if(m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - } - else - { - m_tsdbConnPtr = getOneUseableConn(true); - if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - else - { - m_tsdbConnPtr = getOneUseableConn(false); - if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - } - } - return false; -} - -void CHisDataManage::checkTsdbCommandQueue() -{ - if(m_bHasPendingCommand) - { - m_bHasPendingCommand = false; - TsdbCommand cmd; - { - QMutexLocker locker(&m_mutex); - if(!m_listCommand.isEmpty()) - { - cmd = m_listCommand.takeLast(); - } - } - if(E_ORIGINAL == cmd.type) - { - queryHistoryOriginalData(cmd.pVecMpKey, cmd.lower, cmd.upper); - } - else if(E_POLYMERIC == cmd.type) - { - queryHistoryPolymericData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.nGroupByMinute, cmd.method); - } - } - else - { - foreach (TsdbCommand cmd, m_listCommand) - { - std::vector::iterator it = cmd.pVecMpKey->begin(); - while(it != cmd.pVecMpKey->end()) - { - free( (char*)it->m_pszTagName ); - ++it; - } - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; - } - m_listCommand.clear(); - } -} - -void CHisDataManage::queryHistoryOriginalData(std::vector *vecMpKey, double lower, double upper, E_Data_Type type) -{ - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - - double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; - std::vector *> *vecResult = new std::vector *>(); - - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - if(getValidTsdbConnPtr(tsdbConnPtr)) - { - for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) - { - vecResult->push_back(new std::vector()); - } - if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, - NULL,NULL,kbd_dbms::CM_NULL,0,kbd_dbms::FM_NULL_METHOD,*vecResult)) - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 查询超时!"); - } - } - else - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 未获取到有效的TSDB连接!"); - } - - emit sigupdateHisOriginalData(vecMpKey, vecResult, type); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); -} - -void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, double lower, double upper, int nGroupByMinute, EnComputeMethod method) -{ - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - - double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; - std::vector *> *vecResult = new std::vector *>(); - - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - if(getValidTsdbConnPtr(tsdbConnPtr)) - { - std::vector vecNotHaveStatus; - for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) - { - vecNotHaveStatus.push_back(0); - - vecResult->push_back(new std::vector()); - } - - if(!getHisValue(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, - NULL, &vecNotHaveStatus, NULL, NULL, NULL, method, nGroupByMinute * 60 * 1000, FM_NULL_METHOD, *vecResult)) - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!"); - } - } - else - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); - - } - - emit sigHistoryPolymericData(vecMpKey, vecResult, nGroupByMinute); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); -} - -void CHisDataManage::queryHistoryEvents(std::vector *vecMpKey, double lower, double upper, std::vector *> *vecResult, const QString &tag) -{ - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - - if(getValidTsdbConnPtr(tsdbConnPtr)) - { - if(!getHisEventPoint(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, *vecResult)) - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!"); - } - } - else - { - - LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); - } - emit sigHistoryEvent(vecMpKey, vecResult, tag); - -} +#include "CHisDataManage.h" +#include "db_his_query_api/DbHisQueryApi.h" +#include "sample_server_api/SampleDefine.h" +#include "CTrendInfoManage.h" +#include "pub_logger_api/logger.h" +using namespace kbd_dbms; + +CHisDataManage::CHisDataManage(QObject *parent) + : QObject(parent), + m_TsdbExcuting(false), + m_bHasPendingCommand(false), + m_tsdbConnPtr((CTsdbConn*)nullptr) +{ + +} + +CHisDataManage::~CHisDataManage() +{ + QMutexLocker locker(&m_mutex); + m_tsdbConnPtr = boost::shared_ptr(Q_NULLPTR); + releaseTsdbApi(); + foreach (TsdbCommand cmd, m_listCommand) + { + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + m_listCommand.clear(); +} + +bool CHisDataManage::isTsdbExuting() +{ + QMutexLocker locker(&m_mutex); + return m_TsdbExcuting; +} + +void CHisDataManage::postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, double lower, double upper, int nGroupByMinute, EnComputeMethod method) +{ + QMutexLocker locker(&m_mutex); + m_bHasPendingCommand = true; + TsdbCommand cmd; + cmd.type = type; + cmd.pVecMpKey = vecMpKey; + cmd.lower = lower; + cmd.upper = upper; + cmd.nGroupByMinute = nGroupByMinute; + cmd.method = method; + m_listCommand.push_back(cmd); +} + +void CHisDataManage::release() +{ + delete this; +} + +bool CHisDataManage::getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr) +{ + //< 不使用getOneUseableConn()返回的正式库测试 + // ptr.reset(new kbd_dbms::CTsdbConn("127.0.0.1", -1, "iscs6000", "", "")); + // return true; + if(m_tsdbConnPtr != NULL) + { + if(m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + else + { + m_tsdbConnPtr = getOneUseableConn(true); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + else + { + m_tsdbConnPtr = getOneUseableConn(false); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + } + return false; +} + +void CHisDataManage::checkTsdbCommandQueue() +{ + if(m_bHasPendingCommand) + { + m_bHasPendingCommand = false; + TsdbCommand cmd; + { + QMutexLocker locker(&m_mutex); + if(!m_listCommand.isEmpty()) + { + cmd = m_listCommand.takeLast(); + } + } + if(E_ORIGINAL == cmd.type) + { + queryHistoryOriginalData(cmd.pVecMpKey, cmd.lower, cmd.upper); + } + else if(E_POLYMERIC == cmd.type) + { + queryHistoryPolymericData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.nGroupByMinute, cmd.method); + } + } + else + { + foreach (TsdbCommand cmd, m_listCommand) + { + std::vector::iterator it = cmd.pVecMpKey->begin(); + while(it != cmd.pVecMpKey->end()) + { + free( (char*)it->m_pszTagName ); + ++it; + } + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + m_listCommand.clear(); + } +} + +void CHisDataManage::queryHistoryOriginalData(std::vector *vecMpKey, double lower, double upper, E_Data_Type type) +{ + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = true; + } + + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + std::vector *> *vecResult = new std::vector *>(); + + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, + NULL,NULL,kbd_dbms::CM_NULL,0,kbd_dbms::FM_NULL_METHOD,*vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 查询超时!"); + } + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 未获取到有效的TSDB连接!"); + } + + emit sigupdateHisOriginalData(vecMpKey, vecResult, type); + + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = false; + } + checkTsdbCommandQueue(); +} + +void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, double lower, double upper, int nGroupByMinute, EnComputeMethod method) +{ + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = true; + } + + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + std::vector *> *vecResult = new std::vector *>(); + + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + std::vector vecNotHaveStatus; + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecNotHaveStatus.push_back(0); + + vecResult->push_back(new std::vector()); + } + + if(!getHisValue(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, + NULL, &vecNotHaveStatus, NULL, NULL, NULL, method, nGroupByMinute * 60 * 1000, FM_NULL_METHOD, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!"); + } + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); + + } + + emit sigHistoryPolymericData(vecMpKey, vecResult, nGroupByMinute); + + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = false; + } + checkTsdbCommandQueue(); +} + +void CHisDataManage::queryHistoryEvents(std::vector *vecMpKey, double lower, double upper, std::vector *> *vecResult, const QString &tag) +{ + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + if(!getHisEventPoint(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!"); + } + } + else + { + + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); + } + emit sigHistoryEvent(vecMpKey, vecResult, tag); + +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CHisDataManage.h b/product/src/gui/plugin/ISCSTrendCurves/CHisDataManage.h index ad28387b..d8fe5858 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CHisDataManage.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CHisDataManage.h @@ -1,110 +1,110 @@ -#ifndef CHISDATAMANAGE_H -#define CHISDATAMANAGE_H - -#include -#include -#include "CTrendGraph.h" -#include "plot/qcustomplot.h" -#include "tsdb_api/TsdbApi.h" -#include "db_his_query_api/DbHisQueryBase.h" - -enum E_Data_Type -{ - E_REALTIME, - E_HISTORY -}; - -enum E_His_Type -{ - E_Invalid = -1, - E_ORIGINAL, - E_POLYMERIC -}; - -struct MeasurementPoint -{ - kbd_dbms::EnMeasPiontType type; //< 测点类型 - const QString strTagName; //< 测点TAG名 -}; - -struct TsdbCommand -{ - TsdbCommand() - { - type = E_Invalid; - pVecMpKey = nullptr; - lower = -1.; - upper = -1.; - nGroupByMinute = -1; - method = kbd_dbms::CM_NULL; - } - E_His_Type type; - std::vector * pVecMpKey; - double lower; - double upper; - int nGroupByMinute; - kbd_dbms::EnComputeMethod method; -}; - -class CHisDataManage : public QObject -{ - Q_OBJECT -public: - explicit CHisDataManage(QObject *parent = nullptr); - ~CHisDataManage(); - - bool isTsdbExuting(); - -signals: - void sigupdateHisOriginalData(std::vector *vecMpKey, - std::vector *> *vecResult, - E_Data_Type type = E_HISTORY); - - void sigHistoryPolymericData(std::vector *vecMpKey, - std::vector *> *vecResult, - int nGroupByMinute); - - void sigHistoryEvent(std::vector *vecMpKey, - std::vector *> *vecResult, - const QString &tag); - -public slots: - void release(); - - void postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, - double lower, double upper, - int nGroupByMinute = -1, - kbd_dbms::EnComputeMethod method = kbd_dbms::CM_NULL); - - void queryHistoryOriginalData(std::vector *vecMpKey, - double lower, double upper, - E_Data_Type type = E_HISTORY); - - void queryHistoryPolymericData(std::vector *vecMpKey, - double lower, double upper, - int nGroupByMinute, - kbd_dbms::EnComputeMethod method); - - void queryHistoryEvents(std::vector *vecMpKey, - double lower, double upper, - std::vector *> *vecResult, - const QString &tag); - -protected: - bool getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr); - void checkTsdbCommandQueue(); - -private: - bool m_TsdbExcuting; - bool m_bHasPendingCommand; - kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; - - QList m_listCommand; - QMutex m_mutex; -}; - - -template -inline bool compareVarPoint(const T &a, const T &b) { return a.m_nTime < b.m_nTime; } - -#endif // CHISDATAMANAGE_H +#ifndef CHISDATAMANAGE_H +#define CHISDATAMANAGE_H + +#include +#include +#include "CTrendGraph.h" +#include "plot/qcustomplot.h" +#include "tsdb_api/TsdbApi.h" +#include "db_his_query_api/DbHisQueryBase.h" + +enum E_Data_Type +{ + E_REALTIME, + E_HISTORY +}; + +enum E_His_Type +{ + E_Invalid = -1, + E_ORIGINAL, + E_POLYMERIC +}; + +struct MeasurementPoint +{ + kbd_dbms::EnMeasPiontType type; //< 测点类型 + const QString strTagName; //< 测点TAG名 +}; + +struct TsdbCommand +{ + TsdbCommand() + { + type = E_Invalid; + pVecMpKey = nullptr; + lower = -1.; + upper = -1.; + nGroupByMinute = -1; + method = kbd_dbms::CM_NULL; + } + E_His_Type type; + std::vector * pVecMpKey; + double lower; + double upper; + int nGroupByMinute; + kbd_dbms::EnComputeMethod method; +}; + +class CHisDataManage : public QObject +{ + Q_OBJECT +public: + explicit CHisDataManage(QObject *parent = nullptr); + ~CHisDataManage(); + + bool isTsdbExuting(); + +signals: + void sigupdateHisOriginalData(std::vector *vecMpKey, + std::vector *> *vecResult, + E_Data_Type type = E_HISTORY); + + void sigHistoryPolymericData(std::vector *vecMpKey, + std::vector *> *vecResult, + int nGroupByMinute); + + void sigHistoryEvent(std::vector *vecMpKey, + std::vector *> *vecResult, + const QString &tag); + +public slots: + void release(); + + void postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, + double lower, double upper, + int nGroupByMinute = -1, + kbd_dbms::EnComputeMethod method = kbd_dbms::CM_NULL); + + void queryHistoryOriginalData(std::vector *vecMpKey, + double lower, double upper, + E_Data_Type type = E_HISTORY); + + void queryHistoryPolymericData(std::vector *vecMpKey, + double lower, double upper, + int nGroupByMinute, + kbd_dbms::EnComputeMethod method); + + void queryHistoryEvents(std::vector *vecMpKey, + double lower, double upper, + std::vector *> *vecResult, + const QString &tag); + +protected: + bool getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr); + void checkTsdbCommandQueue(); + +private: + bool m_TsdbExcuting; + bool m_bHasPendingCommand; + kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; + + QList m_listCommand; + QMutex m_mutex; +}; + + +template +inline bool compareVarPoint(const T &a, const T &b) { return a.m_nTime < b.m_nTime; } + +#endif // CHISDATAMANAGE_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CHisEventManage.cpp b/product/src/gui/plugin/ISCSTrendCurves/CHisEventManage.cpp index 2b4434cb..17c67c04 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CHisEventManage.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CHisEventManage.cpp @@ -1,79 +1,79 @@ -#include "CHisEventManage.h" -#include "service/alarm_server_api/AlarmCommonDef.h" - -CHisEventManage::CHisEventManage(QObject *parent) - : QObject(parent), - m_pReadDb(Q_NULLPTR) -{ - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); - m_pReadDb->open(); -} - -CHisEventManage::~CHisEventManage() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = Q_NULLPTR; -} - -void CHisEventManage::release() -{ - delete this; -} - -void CHisEventManage::queryHisEvent(const QString &tag, const qint64 &time, const QMap &timeTag) -{ - if(!m_pReadDb->isOpen()) - { - return; - } - - QString str; - QList timeList = timeTag.keys(); - for(int nIndex=0; nIndex tagSet = timeTag.values().toSet(); - QString sqlSequenceQuery = QString("select time_stamp,content,key_id_tag from HIS_EVENT where time_stamp in (%1)").arg(str); - QSqlQuery query; - try - { - m_pReadDb->execute(sqlSequenceQuery, query); - } - catch(...) - { - qDebug() << "Query Error!"; - } - if(query.isActive()) - { - QStringList contents; - while(query.next()) - { - QString tag = query.value(2).toString().section(".", 1, -2); - if(tagSet.find(tag) != tagSet.end()) - { - contents << QDateTime::fromMSecsSinceEpoch(query.value(0).toDouble()).toString("MM-dd hh:mm:ss zzz ") + query.value(1).toString(); - } - } - - if(contents.isEmpty()) - { - contents << tr("未查询到该设备相关事件!"); - } - - emit updateHisEvent(tag, time, contents); - } -} +#include "CHisEventManage.h" +#include "service/alarm_server_api/AlarmCommonDef.h" + +CHisEventManage::CHisEventManage(QObject *parent) + : QObject(parent), + m_pReadDb(Q_NULLPTR) +{ + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); + m_pReadDb->open(); +} + +CHisEventManage::~CHisEventManage() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = Q_NULLPTR; +} + +void CHisEventManage::release() +{ + delete this; +} + +void CHisEventManage::queryHisEvent(const QString &tag, const qint64 &time, const QMap &timeTag) +{ + if(!m_pReadDb->isOpen()) + { + return; + } + + QString str; + QList timeList = timeTag.keys(); + for(int nIndex=0; nIndex tagSet = timeTag.values().toSet(); + QString sqlSequenceQuery = QString("select time_stamp,content,key_id_tag from HIS_EVENT where time_stamp in (%1)").arg(str); + QSqlQuery query; + try + { + m_pReadDb->execute(sqlSequenceQuery, query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + if(query.isActive()) + { + QStringList contents; + while(query.next()) + { + QString tag = query.value(2).toString().section(".", 1, -2); + if(tagSet.find(tag) != tagSet.end()) + { + contents << QDateTime::fromMSecsSinceEpoch(query.value(0).toDouble()).toString("MM-dd hh:mm:ss zzz ") + query.value(1).toString(); + } + } + + if(contents.isEmpty()) + { + contents << tr("未查询到该设备相关事件!"); + } + + emit updateHisEvent(tag, time, contents); + } +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CHisEventManage.h b/product/src/gui/plugin/ISCSTrendCurves/CHisEventManage.h index 7bd51fe8..c585950e 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CHisEventManage.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CHisEventManage.h @@ -1,25 +1,25 @@ -#ifndef CHISEVENTMANAGE_H -#define CHISEVENTMANAGE_H - -#include "db_api_ex/CDbApi.h" - -class CHisEventManage : public QObject -{ - Q_OBJECT -public: - CHisEventManage(QObject *parent = Q_NULLPTR); - - ~CHisEventManage(); - - void release(); - - void queryHisEvent(const QString &tag, const qint64 &time, const QMap& timeTag); - -signals: - void updateHisEvent(const QString &tag, const qint64 &time, QStringList contents); - -private: - kbd_dbms::CDbApi * m_pReadDb; -}; - -#endif // CHISEVENTMANAGE_H +#ifndef CHISEVENTMANAGE_H +#define CHISEVENTMANAGE_H + +#include "db_api_ex/CDbApi.h" + +class CHisEventManage : public QObject +{ + Q_OBJECT +public: + CHisEventManage(QObject *parent = Q_NULLPTR); + + ~CHisEventManage(); + + void release(); + + void queryHisEvent(const QString &tag, const qint64 &time, const QMap& timeTag); + +signals: + void updateHisEvent(const QString &tag, const qint64 &time, QStringList contents); + +private: + kbd_dbms::CDbApi * m_pReadDb; +}; + +#endif // CHISEVENTMANAGE_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.cpp b/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.cpp index aa5273e8..ab43378b 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.cpp @@ -1,2160 +1,2160 @@ -#include "CPlotWidget.h" -#include "ui_CPlotWidget.h" -#include "CCurveLegendModel.h" -#include "CHisEventManage.h" -#include "CTrendInfoManage.h" -#include "CRealTimeDataCollect.h" -#include "sample_server_api/SampleDefine.h" -#include "pub_logger_api/logger.h" -#include "./widgets/CEditCollectWidget.h" -#include "./widgets/CToolTip.h" - -using namespace kbd_dbms; - -CPlotWidget::CPlotWidget(QWidget *parent) : - QWidget(parent), - ui(new Ui::CPlotWidget), - m_type(E_Trend_Invalid), - m_bHisAdaption(false), - m_TrendTypeButton(Q_NULLPTR), - m_pLengedModel(Q_NULLPTR), - m_pTimer(Q_NULLPTR), - m_pTrendGraph(Q_NULLPTR), - m_pDpcdaForApp(Q_NULLPTR), - m_rtDataCollect(Q_NULLPTR), - m_pHisDataThread(Q_NULLPTR), - m_pHisDataManage(Q_NULLPTR), - m_pHisEventThread(Q_NULLPTR), - m_pHisEventManage(Q_NULLPTR), - m_isWindowMode(true) -{ - ui->setupUi(this); - setContentsMargins(1, 1, 1, 1); - qRegisterMetaType< E_Data_Type >("E_Data_Type"); - qRegisterMetaType< kbd_dbms::EnComputeMethod >("kbd_dbms::EnComputeMethod"); - qRegisterMetaType< std::vector >("std::vector"); - qRegisterMetaType< std::vector *> >("std::vector *>"); -} - -CPlotWidget::~CPlotWidget() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = Q_NULLPTR; - - if(m_pHisEventManage) - { - emit releaseHisEventThread(); - m_pHisEventManage = Q_NULLPTR; - } - - if(m_pHisEventThread) - { - m_pHisEventThread->quit(); - m_pHisEventThread->wait(); - } - m_pHisEventThread = Q_NULLPTR; - - if(m_pHisDataManage) - { - emit releaseHisEventThread(); - m_pHisDataManage = Q_NULLPTR; - } - if(m_pHisDataThread) - { - m_pHisDataThread->quit(); - m_pHisDataThread->wait(); - } - m_pHisDataThread = Q_NULLPTR; - - if(m_pTrendGraph) - { - delete m_pTrendGraph; - } - m_pTrendGraph = Q_NULLPTR; - - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - delete m_pDpcdaForApp; - } - m_pDpcdaForApp = Q_NULLPTR; - - if(m_rtDataCollect->isRunning()) - { - m_rtDataCollect->disconnect(this); - m_rtDataCollect->requestInterruption(); - m_rtDataCollect->wait(); - } - m_rtDataCollect = Q_NULLPTR; - delete ui; -} - -/************************************************************************ - * - * 1、初始化界面 - * 2、初始化实时数据采集 - * - ************************************************************************/ -void CPlotWidget::initialize() -{ - initTsdbApi(); - m_pTrendGraph = new CTrendGraph(); - m_rtRange = 10 * 60 * 1000; //< second - - //< GroupButton - m_TrendTypeButton = new QButtonGroup(this); - m_TrendTypeButton->addButton(ui->realTime, E_Trend_RealTime); - m_TrendTypeButton->addButton(ui->sec, E_Trend_His_Minute); - m_TrendTypeButton->addButton(ui->day, E_Trend_His_Day); - m_TrendTypeButton->addButton(ui->week, E_Trend_His_Week); - m_TrendTypeButton->addButton(ui->month, E_Trend_His_Month); - m_TrendTypeButton->addButton(ui->quarter, E_Trend_His_Quarter); - m_TrendTypeButton->addButton(ui->year, E_Trend_His_Year); - connect(m_TrendTypeButton, SIGNAL(buttonClicked(int)), this, SLOT(updateTrendShowMode(int))); -// QList listButton = m_TrendTypeButton->buttons(); -// foreach (QAbstractButton * button, listButton) -// { -// CTabButton * tabButton = dynamic_cast(button); -// if(tabButton && tabButton != ui->realTime) -// { -// tabButton->setShowCalendarEnable(true); -// connect(tabButton, &CTabButton::dataChanged, this, &CPlotWidget::updateTrendRange); -// } -// } - connect(ui->prePage, &QPushButton::clicked, this, &CPlotWidget::prePage); - connect(ui->nextPage, &QPushButton::clicked, this, &CPlotWidget::nextPage); - connect(ui->date, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotDateTimeChanged); - ui->date->setCalendarPopup(true); - ui->date->setDateTime(QDateTime::currentDateTime()); - - //< initPlot - ui->plot->setEnabled(true); - ui->plot->setSymbolPos(QPoint(width() / 2, 0)); - ui->plot->setNoAntialiasingOnDrag(true); - ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //<水平拖拽 - ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //<水平缩放 - ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); - QSharedPointer ticker(new QCPAxisTickerDateTime()); - ui->plot->xAxis->setTicker(ticker); - ui->plot->yAxis->setRange(-1, 1); - ui->plot->yAxis->scaleRange(1.02); - ui->plot->yAxis2->setVisible(true); - ui->plot->xAxis->setScaleType(QCPAxis::stLinear); - m_ptrPlotTricker = ui->plot->yAxis->ticker(); - connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->yAxis2, SLOT(setRange(QCPRange))); - connect(ui->plot->xAxis, SIGNAL(rangeChanged(const QCPRange &,const QCPRange &)), this, SLOT(plotAxisRangeChanged(const QCPRange &,const QCPRange &))); - connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeDraged, this, &CPlotWidget::updateCurves); - connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeScaled, this, &CPlotWidget::updateCurves); - connect(ui->plot, &QCustomPlot::symbolPosChanged, this, &CPlotWidget::updateLengedValue); - - //< initTitle - m_trendTitle = new QCPItemText(ui->plot); - m_trendTitle->setObjectName("m_trendTitle"); - m_trendTitle->setPositionAlignment(Qt::AlignCenter); - m_trendTitle->position->setType(QCPItemPosition::ptAxisRectRatio); - m_trendTitle->position->setCoords(0.03, 0.01); - m_trendTitle->setColor(QColor(255,255,255)); - m_trendTitle->setFont(QFont("Microsoft YaHei", 10)); - m_trendTitle->setText("实时趋势"); - m_trendTitle->setVisible(false); - - //< initTableView - m_pLengedModel = new CCurveLegendModel(ui->lengedView); - ui->lengedView->setModel(m_pLengedModel); - ui->lengedView->setItemDelegate(new CCurveLegnedDelegate(ui->lengedView)); - ui->lengedView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked); - ui->lengedView->verticalHeader()->setVisible(false); - ui->lengedView->setAlternatingRowColors(true); - ui->lengedView->horizontalHeader()->setStretchLastSection(true); - ui->lengedView->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->lengedView->setSelectionMode(QAbstractItemView::SingleSelection); - ui->lengedView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->lengedView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); - - connect(m_pLengedModel, &CCurveLegendModel::graphVisibleChanged, this, &CPlotWidget::graphVisibleChanged); - connect(m_pLengedModel, &CCurveLegendModel::graphPropertyChanged, this, &CPlotWidget::graphPropertyChanged); - connect(ui->lengedView, &QTableView::clicked, this, &CPlotWidget::updateGraphSelection); - - ui->plotExport->setVisible(false); - ui->adaptFrame->setVisible(false); - ui->clear->setEnabled(false); - ui->collectCurve->setVisible(false); - connect(ui->adapt, &QCheckBox::toggled, this, &CPlotWidget::updateAdaptState); - connect(ui->collectCurve, &QPushButton::clicked, this, &CPlotWidget::addCollect); - connect(ui->plotPrint, &QPushButton::clicked, this, &CPlotWidget::print); - connect(ui->clear, &QPushButton::clicked, this, &CPlotWidget::clear); - if(Q_NULLPTR == m_pTimer) - { - m_pTimer = new QTimer(this); - m_pTimer->setInterval(1000); - connect(m_pTimer, &QTimer::timeout, this, &CPlotWidget::realTimeElapsed); - } - - m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); - m_rtDataCollect = new CRealTimeDataCollect(this); - connect(m_rtDataCollect, &CRealTimeDataCollect::finished, m_rtDataCollect, &CRealTimeDataCollect::deleteLater); - connect(m_rtDataCollect, &CRealTimeDataCollect::realTimeTrendDataArrived, this, &CPlotWidget::recvRealTimeTrendData, Qt::QueuedConnection); - m_rtDataCollect->start(); - - m_pHisDataManage = new CHisDataManage(); - m_pHisDataThread = new QThread(this); - m_pHisDataManage->moveToThread(m_pHisDataThread); - connect(m_pHisDataThread, &QThread::finished, m_pHisDataThread, &QObject::deleteLater); - connect(this, &CPlotWidget::releaseHisDataThread, m_pHisDataManage, &CHisDataManage::release, Qt::BlockingQueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryOriginalData, m_pHisDataManage, &CHisDataManage::queryHistoryOriginalData, Qt::QueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryPolymericData, m_pHisDataManage, &CHisDataManage::queryHistoryPolymericData, Qt::QueuedConnection); - connect(m_pHisDataManage, &CHisDataManage::sigupdateHisOriginalData, this, &CPlotWidget::updateHisOriginalData, Qt::QueuedConnection); - connect(m_pHisDataManage, &CHisDataManage::sigHistoryPolymericData, this, &CPlotWidget::updateHisPolymericData, Qt::QueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryEvent, m_pHisDataManage, &CHisDataManage::queryHistoryEvents, Qt::QueuedConnection); - connect(m_pHisDataManage, &CHisDataManage::sigHistoryEvent, this, &CPlotWidget::updatePhaseTracer, Qt::QueuedConnection); - - m_pHisDataThread->start(); - - m_pHisEventManage = new CHisEventManage(); - m_pHisEventThread = new QThread(this); - m_pHisEventManage->moveToThread(m_pHisEventThread); - connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); - connect(this, &CPlotWidget::releaseHisEventThread, m_pHisEventManage, &CHisEventManage::release, Qt::BlockingQueuedConnection); - connect(m_pHisEventManage, &CHisEventManage::updateHisEvent, this, &CPlotWidget::updateGraphEvent ,Qt::QueuedConnection); - m_pHisEventThread->start(); - - connect(ui->scaleSlider, &QSlider::valueChanged, this, &CPlotWidget::rescaleYAxisRange); - - QMetaObject::invokeMethod(ui->realTime, "click"); -} - -void CPlotWidget::resizeEvent(QResizeEvent *event) -{ - QSize size = parentWidget()->size(); - if(ui->titleFrame->isVisible()) - { - size.setHeight(size.height() - (ui->titleFrame->height() + ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + 15)); - } - else - { - size.setHeight(size.height() - (ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + 15)); - } - ui->plot->resize(size); - ui->plot->replot(); - - updateLengedColumnWidth(); - QWidget::resizeEvent(event); -} - -void CPlotWidget::updateLengedColumnWidth() -{ - int nLengedWidth = ui->lengedView->width(); - ui->lengedView->setColumnWidth(CCurveLegendModel::NAME, nLengedWidth / 12. * 3); - ui->lengedView->setColumnWidth(CCurveLegendModel::COLOR, nLengedWidth / 12.); - ui->lengedView->setColumnWidth(CCurveLegendModel::VALUE, nLengedWidth / 12.); - ui->lengedView->setColumnWidth(CCurveLegendModel::MAX, nLengedWidth / 12.); - ui->lengedView->setColumnWidth(CCurveLegendModel::MAXTIME, nLengedWidth / 12. * 1.5); - ui->lengedView->setColumnWidth(CCurveLegendModel::MIN, nLengedWidth / 12.); - ui->lengedView->setColumnWidth(CCurveLegendModel::MINTIME, nLengedWidth / 12. * 1.5); - ui->lengedView->setColumnWidth(CCurveLegendModel::AVE, nLengedWidth / 12.); - ui->lengedView->setColumnWidth(CCurveLegendModel::UNIT, nLengedWidth / 12.); - // ui->lengedView->setColumnWidth(CCurveLegendModel::FACTOR, nLengedWidth / 12.); - // ui->lengedView->setColumnWidth(CCurveLegendModel::OFFSET, nLengedWidth / 12.); -} - -void CPlotWidget::updateCurveSelectionColor(QCPGraph *graph) -{ - if(!graph) - { - return; - } - QPen selectedPen = graph->selectionDecorator()->pen(); - selectedPen.setWidth(1); - QColor color; - QColor graphColor = graph->pen().color(); - int r = graphColor.red() > 225 ? graphColor.red() - 30 : graphColor.red() + 30; - int g = graphColor.green() > 225 ? graphColor.green() - 30 : graphColor.green() + 30; - int b = graphColor.blue() > 225 ? graphColor.blue() - 30 : graphColor.blue() + 30; - color.setRgb(r, g, b); - selectedPen.setColor(color); - graph->selectionDecorator()->setPen(selectedPen); -} - -E_Trend_Type CPlotWidget::getRangeType(const QCPRange &range) -{ - if(range.size() <= 0) - { - return E_Trend_Invalid; - } - - QDateTime upper = QDateTime::fromMSecsSinceEpoch(range.upper); - - if(range.lower >= upper.addSecs(-10).toMSecsSinceEpoch()) - { - return E_Trend_RealTime; - } - else if(range.lower >= upper.addSecs(-600).toMSecsSinceEpoch()) - { - return E_Trend_His_Minute; - } - else if(range.lower >= upper.addSecs(-3600).toMSecsSinceEpoch()) - { - return E_Trend_His_Hour; - } - else if(range.lower >= upper.addDays(-1).toMSecsSinceEpoch()) - { - return E_Trend_His_Day; - } - else if(range.lower >= upper.addDays(-7).toMSecsSinceEpoch()) - { - return E_Trend_His_Week; - } - else if(range.lower >= upper.addMonths(-1).toMSecsSinceEpoch()) - { - return E_Trend_His_Month; - } - else if(range.lower >= upper.addMonths(-3).toMSecsSinceEpoch()) - { - return E_Trend_His_Quarter; - } - else if(range.lower >= upper.addYears(-1).toMSecsSinceEpoch()) - { - return E_Trend_His_Year; - } - - return E_Trend_His_Year; -} - -int CPlotWidget::currentGroupByMinute() -{ - int nGroupByMinute = 0; - switch (m_type) - { - case E_Trend_RealTime: - { - //< Error - } - break; - case E_Trend_His_Minute: - { - //< Error - } - break; - case E_Trend_His_Hour: - { - //< Error - } - break; - case E_Trend_His_Day: - { - nGroupByMinute = 1; - } - break; - case E_Trend_His_Week: - { - nGroupByMinute = 7; - } - break; - case E_Trend_His_Month: - { - nGroupByMinute = 30; - } - break; - case E_Trend_His_Quarter: - { - nGroupByMinute = 90; - } - break; - case E_Trend_His_Year: - { - nGroupByMinute = 365; - } - break; - default: - break; - } - return nGroupByMinute; -} - -/************************************************************************ - * - * 接口 - * - ************************************************************************/ -void CPlotWidget::setTitle(const QString &title) -{ - ui->title->setText(title); -} - -void CPlotWidget::setTitleVisible(bool visible) -{ - ui->titleFrame->setVisible(visible); -} - -void CPlotWidget::setTickCount(const int &count) -{ - QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); - ticker->setTickCount(count); -} - -void CPlotWidget::insertTag(const QString &tag) -{ -// static int nTagIndex = 0; -// if(nTagIndex > 63) -// { -// nTagIndex = 0; -// } - int graphSize = m_pTrendGraph->curves().size() % 16; - - Curve curve; - curve.tag = tag; - curve.color = m_listColor.at(graphSize); //m_listColor.at((nTagIndex++) % m_listColor.size()); - insertCurve(curve); -} - -void CPlotWidget::insertTag(const QStringList &listTag) -{ - m_pTrendGraph->clear(); - foreach (QString tag, listTag) - { - insertTag(tag); - } -} - -void CPlotWidget::removeTag(const QString &tag) -{ - int nIndex = m_pTrendGraph->removeCurve(tag); - if(nIndex != -1) - { - if(ui->plot->graph(nIndex)->selected()) - { - ui->plot->clearItems(); - m_listTracer.clear(); - } - ui->plot->removeGraph(nIndex); - } - - m_pLengedModel->setTrendGraph(m_pTrendGraph); - updateLengedColumnWidth(); - if(!m_pTrendGraph->curves().size()) - { - ui->plot->yAxis->setRange(QCPRange(-1, 1)); - - if(m_isWindowMode) - { - ui->collectCurve->setVisible(false); - } - ui->clear->setEnabled(false); - } - ui->plot->replot(); -} - -void CPlotWidget::setDisplayTime(const int &trendType, const double &dateTime) -{ - QAbstractButton* Button = m_TrendTypeButton->button(trendType); - if(Button) - { - QMetaObject::invokeMethod(Button, "click"); - - QDateTime nDateTime = QDateTime::fromMSecsSinceEpoch(dateTime); - ui->date->setDateTime(nDateTime); - } -} - -void CPlotWidget::setTagVisible(const QString &tag, const bool &visible) -{ - int nIndex = m_pTrendGraph->index(tag); - if(nIndex != -1) - { - m_pLengedModel->setData(m_pLengedModel->index(nIndex, 0), visible, Qt::CheckStateRole); - ui->plot->replot(); - } -} - -void CPlotWidget::setClearVisible(bool visible) -{ - if(visible) - { - ui->clear->show(); - } - else - { - ui->clear->hide(); - } -} - -void CPlotWidget::insertCurve(Curve curve) -{ - if(ui->plot->graphCount() >= 64) - { - QMessageBox::warning(this, tr("错误"), tr("当前趋势曲线已达最大支持数量[64]!"), QMessageBox::Ok); - emit updateTagCheckState(curve.tag, false); - return; - } - - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - if(curve.tag == ui->plot->graph(nIndex)->name()) - { - LOGINFO("趋势曲线[%s]已存在", curve.tag.toStdString().c_str()); - return; - } - } - - curve.type = CTrendInfoManage::instance()->getTagType(curve.tag); - curve.unit = CTrendInfoManage::instance()->getTagUnit(curve.tag); - if(curve.type.isEmpty()) - { - LOGINFO("趋势曲线[%s]类型不存在", curve.tag.toStdString().c_str()); - return; - } - - curve.desc = CTrendInfoManage::instance()->getTagDescription(curve.tag); - if(curve.desc.isEmpty()) - { - LOGINFO("趋势曲线[%s]描述不存在", curve.tag.toStdString().c_str()); - return; - } - - - m_pDpcdaForApp->subscribe(curve.type.toStdString(), curve.tag.toStdString(), "value"); - - //< 添加曲线 - m_pTrendGraph->addCurve(curve); - QCPGraph * graph = ui->plot->addGraph(); - graph->setName(curve.tag); - graph->setDesc(curve.desc); - graph->setPen(curve.color); - updateCurveSelectionColor(graph); - -// connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); - - //< 方波 - QString type = CTrendInfoManage::instance()->getTagType(curve.tag); - if(type == "digital" || type == "mix") - { - graph->setLineStyle(QCPGraph::lsStepLeft); - } - - //< 查询最新十分钟数据 -// double upper = QDateTime::currentMSecsSinceEpoch(); -// double lower = upper - (10 * 60 * 1000); -// SMeasPointKey key; -// std::string tmp = curve.tag.toStdString(); -// char * tag = (char*)malloc(tmp.size() + 1); -// memset(tag, 0, tmp.size() + 1); -// memcpy(tag, tmp.c_str(), tmp.size()); -// key.m_pszTagName = tag; -// key.m_enType = getMeasType(curve.type); -// std::vector * vecMpKey = new std::vector(); -// vecMpKey->push_back(key); -// emit sigQueryHistoryOriginalData(vecMpKey, lower, upper, E_REALTIME); - updateCurves(); - - m_pLengedModel->setTrendGraph(m_pTrendGraph); - updateLengedColumnWidth(); - if(m_type == E_Trend_RealTime && m_isWindowMode) - { - setLegendCurveTransformColumnVisible(true); - } - ui->clear->setEnabled(true); - - if(m_isWindowMode) - { - ui->collectCurve->setVisible(false); - emit updateTagCheckState(curve.tag, true); - } - else - { - setLegendCurveTransformColumnVisible(true); - } - -} - -void CPlotWidget::clear(bool clearTitle) -{ - if(!m_pTrendGraph->curves().size()) - { - ui->clear->setEnabled(false); - } - m_pTrendGraph->clear(); - m_pLengedModel->clear(); - m_pLengedModel->update(); - - ui->plot->yAxis->setRange(QCPRange(-1, 1)); - ui->plot->clearItems(clearTitle); - ui->plot->clearGraphs(); - ui->plot->replot(); - setTitle(tr("趋势图")); - if(m_isWindowMode) - { - ui->collectCurve->setVisible(false); - } - emit clearCurve(); -} - -void CPlotWidget::setWindowMode(const bool &isWindowMode) -{ - m_isWindowMode = isWindowMode; -} - -void CPlotWidget::setColorList(const QStringList &listColor) -{ - foreach (QString c, listColor) - { - c.replace("\r", ""); - m_listColor.append(QColor(c)); - } -} - -/****************************** 图表颜色 **************************************/ -QColor CPlotWidget::plotBackgroundColor() -{ - return m_plotBackgroundColor; -} - -void CPlotWidget::setPlotBackgroundColor(const QColor &color) -{ - m_plotBackgroundColor = color; - - ui->plot->setBackground(m_plotBackgroundColor); -} - -QPixmap CPlotWidget::plotBackImage() -{ - return m_plotBackImage; -} - -void CPlotWidget::setPlotBackImage(const QPixmap &pm) -{ - m_plotBackImage = pm; - - ui->plot->setBackgroundScaled(false); - ui->plot->setBackground(pm); -} - -QColor CPlotWidget::plotTickColor() -{ - return m_plotTickColor; -} - -void CPlotWidget::setPlotTickColor(const QColor &color) -{ - m_plotTickColor = color; - - ui->plot->xAxis->setTickLabelColor(color); - ui->plot->yAxis->setTickLabelColor(color); - ui->plot->yAxis2->setTickLabelColor(color); -} - -QColor CPlotWidget::plotGridColor() -{ - return m_plotGridColor; -} - -void CPlotWidget::setPlotGridColor(const QColor &color) -{ - m_plotGridColor = color; - - ui->plot->xAxis->grid()->setPen(color); - ui->plot->yAxis->grid()->setPen(color); - - ui->plot->xAxis->grid()->setSubGridPen(color); - ui->plot->yAxis->grid()->setSubGridPen(color); -} - -QColor CPlotWidget::plotZeroLineColor() -{ - return m_plotZeroLineColor; -} - -void CPlotWidget::setPlotZeroLineColor(const QColor &color) -{ - m_plotZeroLineColor = color; - - ui->plot->xAxis->grid()->setZeroLinePen(QPen(color)); - ui->plot->yAxis->grid()->setZeroLinePen(QPen(color)); -} - -QColor CPlotWidget::plotTickPen() -{ - return m_plotTickPen; -} - -void CPlotWidget::setPlotTickPen(const QColor &color) -{ - m_plotTickPen = color; - - ui->plot->xAxis->setBasePen(color); - ui->plot->yAxis->setBasePen(color); - ui->plot->yAxis2->setBasePen(color); - ui->plot->xAxis->setTickPen(color); - ui->plot->yAxis->setTickPen(color); - ui->plot->yAxis2->setTickPen(color); - ui->plot->xAxis->setSubTickPen(color); - ui->plot->yAxis->setSubTickPen(color); - ui->plot->yAxis2->setSubTickPen(color); -} -/*****************************************************************************/ - - -void CPlotWidget::realTimeElapsed() -{ - //< 刷新X轴 - const QCPRange &range = ui->plot->xAxis->range(); - double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); - double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); - ui->plot->xAxis->setRange(upper, range.size(), Qt::AlignRight); - - QList listVal; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - m_pTrendGraph->updateRTCurveStatisticsInfo(graph->name()); - QVector * pCPGraphData = graph->data()->data(); - - if(pCPGraphData->isEmpty()) - { - listVal.append(qSqrt(-1.)); - } - else - { - - listVal.append(pCPGraphData->last().value); - - //< set virtual point value - if(limit == pCPGraphData->last().key) - { - pCPGraphData->last().value = (*(pCPGraphData->end() - 2)).value; - } - } - } - m_pLengedModel->setTrendCurrentValues(listVal); - rescaleYAxisRange(); - ui->plot->replot(); -} - -void CPlotWidget::recvRealTimeTrendData(const QString &tagName, QVariant value) -{ - //< LOGINFO("Recv RealTime Trend Data-[Tag Name: %s, value: %f] ", tagName.toStdString().c_str(), value.toDouble()); - double key = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); - m_pTrendGraph->pushCurveRTDataValue(tagName, key, value.toDouble()); - - if(E_Trend_RealTime != m_type) - { - return; - } - - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - if(graph->name() == tagName) - { - QVector * pCPGraphData = graph->data()->data(); - - if(!pCPGraphData->isEmpty() && qAbs(((*(pCPGraphData->end() - 2)).value - value.toDouble())) < _EPSILON_) - { - return; - } - graph->addData(key, value.toDouble()); - if( pCPGraphData->first().key < ( key - (20 * 60 * 1000) ) ) - { - graph->data()->removeBefore( key - (20 * 60 * 1000) ); - } - return; - } - } -} - -void CPlotWidget::plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange) -{ - Q_UNUSED(oldRange); - QDateTime upper = QDateTime::fromMSecsSinceEpoch(newRange.upper); - double midValue = (newRange.upper + newRange.lower) / 2; - - if(m_type == E_Trend_RealTime) - { - m_rtRange = newRange.size(); - if(m_rtRange > 10 * 60 * 1000) - { - m_rtRange = 10 * 60 * 1000; - } - else if(m_rtRange < 10 * 1000) - { - m_rtRange = 10 * 1000; - } - - double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); - ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); - return; - } - else if(m_type == E_Trend_His_Minute || m_type == E_Trend_His_Day || m_type == E_Trend_His_Week || m_type == E_Trend_His_Month || m_type == E_Trend_His_Quarter || m_type == E_Trend_His_Year) - { - QPair dateTime = getFatureDataTime(m_type, ui->date->dateTime()); - double range = newRange.size() > (dateTime.second - dateTime.first)?(dateTime.second - dateTime.first):newRange.size(); - if(newRange.lower < dateTime.first) - { - ui->plot->xAxis->setRange(dateTime.first, range, Qt::AlignLeft); - return; - } - else if(newRange.upper > dateTime.second) - { - ui->plot->xAxis->setRange(dateTime.second, range, Qt::AlignRight); - return; - } - } -// else if(m_type == E_Trend_His_Year) -// { -// if(newRange.size() > newRange.upper - upper.addYears(-1).toMSecsSinceEpoch()) -// { -// ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addYears(-1).toMSecsSinceEpoch(), Qt::AlignCenter); -// return; -// } -// } - - QList listToolTip= findChildren(); - foreach (CToolTip * pToolTip, listToolTip) - { - pToolTip->close(); - } - - if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) - { - updateYAxisTicker(); - } - - E_Trend_Type rangeType = getRangeType(newRange); - if(m_type == rangeType) - { - return; - } - - if(m_type == E_Trend_His_Minute) - { - if(rangeType == E_Trend_RealTime) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-10).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Hour) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Day) - { - if(rangeType == E_Trend_His_Minute) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Week) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Week) - { - if(rangeType == E_Trend_His_Day) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Month) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Month) - { - if(rangeType == E_Trend_His_Week) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Quarter) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Quarter) - { - if(rangeType == E_Trend_His_Month) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Year) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Year) - { - if(rangeType == E_Trend_His_Quarter) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - -// if(rangeType != E_Trend_Invalid && rangeType != E_Trend_His_Minute && rangeType != E_Trend_His_Hour) -// { -// m_TrendTypeButton->button((int)rangeType)->setChecked(true); -// } -// updateTrendShowMode(rangeType, false); -} - -void CPlotWidget::updateTrendShowMode(int nIndex, bool updateXAxisRange) -{ - updateGraphTitle(nIndex); - - m_type = (E_Trend_Type)nIndex; - if(Q_NULLPTR != m_pTimer && m_pTimer->isActive()) - { - m_pTimer->stop(); - } - m_pLengedModel->setMode(CCurveLegendModel::LENGED_HIS_MODE); - if(m_isWindowMode) - { - setLegendCurveTransformColumnVisible(false); - } - //< default setting - ui->prePage->setEnabled(true); - ui->nextPage->setEnabled(true); - ui->date->setEnabled(true); - ui->plot->axisRect()->setScaleRight(false); - ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //< 水平拖拽 - ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //< 水平缩放 - ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); - ui->plot->xAxis->setScaleType(QCPAxis::stLinear); - - updateAxisFormat(updateXAxisRange); - - if (m_type == E_Trend_RealTime || m_type == E_Trend_Invalid) - { - ui->prePage->setVisible(false); - ui->nextPage->setVisible(false); - ui->date->setVisible(false); - } - else - { - ui->prePage->setVisible(true); - ui->nextPage->setVisible(true); - ui->date->setVisible(true); - ui->date->setDateTime(QDateTime::currentDateTime()); - } - - if(updateXAxisRange) - { - updateCurves(); - } -} - -void CPlotWidget::updateGraphTitle(int nIndex) -{ - m_type = (E_Trend_Type)nIndex; - - if(m_type == E_Trend_RealTime) - { - m_trendTitle->setText("实时趋势"); - } - else if(m_type == E_Trend_His_Minute) - { - m_trendTitle->setText("秒趋势"); - } - else if(m_type == E_Trend_His_Day) - { - m_trendTitle->setText("日趋势"); - } - else if(m_type == E_Trend_His_Week) - { - m_trendTitle->setText("周趋势"); - } - else if(m_type == E_Trend_His_Month) - { - m_trendTitle->setText("月趋势"); - } - else if(m_type == E_Trend_His_Quarter) - { - m_trendTitle->setText("季度趋势"); - } - else if(m_type == E_Trend_His_Year) - { - m_trendTitle->setText("年趋势"); - } -} - -void CPlotWidget::updateCurves() -{ - if(E_Trend_RealTime == m_type) - { - ui->adaptFrame->setVisible(false); - updateRealTimeCurveRecord(); - rescaleYAxisRange(); - ui->plot->replot(); - } - else - { - ui->adaptFrame->setVisible(true); - updateHistoryCurveRecord(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper); - } -} - -void CPlotWidget::updateRealTimeCurveRecord() -{ - if(Q_NULLPTR == m_pTrendGraph) - { - return; - } - double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - //< 清空数据 - QSharedPointer container(new QCPGraphDataContainer()); - - const QVector< QPair > &values = m_pTrendGraph->curve(graph->name()).values; - QVector< QPair >::const_iterator it = values.constBegin(); - double preValue = -1; - while (it != values.constEnd()) - { - //< LOGINFO("Update RealTime Trend Data-----------------[Time: %f, value: %f] ", it->first, it->second); - if(qAbs((it->second)-preValue) < _EPSILON_) - { - ++it; - continue; - } - container->add(QCPGraphData(it->first, it->second)); - preValue = it->second; - ++it; - } - - //< virtual point - if(container->data()->size() > 0) - { - container->add(QCPGraphData(limit, container->data()->last().value)); - } - else - { - container->add(QCPGraphData(limit, qSqrt(-1.))); - } - graph->setData(container); - } -} - -void CPlotWidget::updateHistoryCurveRecord(double lower, double upper) -{ - if(!ui->plot->graphCount()) - { - return; - } - std::vector * vecMpKey = new std::vector(); - for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) - { - const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); - SMeasPointKey key; - std::string tmp = curve.tag.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(curve.type); - vecMpKey->push_back(key); - } - - if(!m_pHisDataManage->isTsdbExuting()) - { - if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) - { - emit sigQueryHistoryOriginalData(vecMpKey, lower, upper); - } - else - { - emit sigQueryHistoryPolymericData(vecMpKey, lower, upper, currentGroupByMinute(), kbd_dbms::CM_FIRST); - } - } - else - { - if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) - { - m_pHisDataManage->postTsdbCommandQueue(E_ORIGINAL, vecMpKey, lower, upper); - } - else - { - m_pHisDataManage->postTsdbCommandQueue(E_POLYMERIC, vecMpKey, lower, upper, currentGroupByMinute(), kbd_dbms::CM_FIRST); - } - } -} - -void CPlotWidget::updateHisOriginalData(std::vector *vecMpKey, std::vector *> *vecResult, E_Data_Type type) -{ - std::vector< QSharedPointer > vecRange; - std::vector< QSharedPointer > vecContainer; - - updateHisData(vecResult, vecRange, vecContainer); - - if(E_REALTIME == type) - { - for(size_t nIndex(0); nIndex < vecContainer.size(); ++nIndex) - { - QCPGraphDataContainer::iterator it = vecContainer.at(nIndex)->begin(); - while(it != vecContainer.at(nIndex)->end()) - { - m_pTrendGraph->pushCurveRTDataValue(vecMpKey->at(nIndex).m_pszTagName, it->key, it->value); - ++it; - } - } - updateCurves(); - } - else if(E_HISTORY == type) - { - updateHistoryGraph(vecMpKey, vecContainer, vecRange); - } - - //< 释放结果集 - std::vector *>::iterator res = vecResult->begin(); - while(vecResult->end() != res) - { - delete (*res); - ++res; - } - vecResult->clear(); - delete vecResult; - - //< 释放测点信息 - std::vector::iterator key = vecMpKey->begin(); - while(vecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - - } - vecMpKey->clear(); - delete vecMpKey; -} - -void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, int nGroupByMinute) -{ - std::vector< QSharedPointer > vecRange; - std::vector< QSharedPointer > vecContainer; - - if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) - { - updateHisData(vecResult, vecRange, vecContainer, nGroupByMinute); - - updateHistoryGraph(vecMpKey, vecContainer, vecRange); - } - - //< 释放结果集 - std::vector *>::iterator res = vecResult->begin(); - while(vecResult->end() != res) - { - delete (*res); - ++res; - } - vecResult->clear(); - delete vecResult; - - //< 释放测点信息 - std::vector::iterator key = vecMpKey->begin(); - while(vecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - } - vecMpKey->clear(); - delete vecMpKey; -} - -void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange) -{ - double lower = ui->plot->xAxis->range().lower; - double upper = ui->plot->xAxis->range().upper; - - for(int nIndex(0); nIndex < (int)(vecContainer.size()); ++nIndex) - { - if(nIndex > ui->plot->graphCount()-1) - { - continue; - } - QCPGraph * graph = ui->plot->graph(nIndex); - { - if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) - { - continue; - } - } - - int count = 0; //< accuml size - double offset = 0.; - double factor = 1.; - double accuml = 0.; - - - Curve curve = m_pTrendGraph->curve(graph->name()); - if(m_bHisAdaption) - { - factor = 100. / (vecRange.at(nIndex)->max - vecRange.at(nIndex)->min); - offset = -factor * vecRange.at(nIndex)->min; - m_pTrendGraph->setCurveGraphFactor(nIndex, factor); - m_pTrendGraph->setCurveGraphOffset(nIndex, offset); - } - else - { - factor = curve.factor; - offset = curve.offset; - } - - //< 此设计考虑自定义缩放【已实现,暂未开放】扩展 - double max = -DBL_MAX; - double min = DBL_MAX; - double maxTime = -DBL_MAX; - double minTime = DBL_MAX; - double average = qSqrt(-1.); - QCPGraphDataContainer::iterator iter = vecContainer.at(nIndex)->begin(); - while(iter != vecContainer.at(nIndex)->end()) - { - if(qIsNaN(iter->value)) - { - ++iter; - continue; - } - - //< 统计值 - if(iter->key >= lower && iter->key <= upper) - { - ++count; - if(iter->value > max) - { - max = iter->value; - maxTime = iter->key; - } - if(iter->value < min) - { - min = iter->value; - minTime = iter->key; - } - - accuml += iter->value; - } - - //< 缩放数据 - if(m_bHisAdaption) - { - iter->value *= factor; - iter->value += offset; - } - ++iter; - } - if(!vecContainer.at(nIndex)->isEmpty()) - { - if(count) - { - average = accuml / count; - } - } - m_pTrendGraph->setCurveHisDataValue(graph->name(), max, min, maxTime, minTime, average, accuml, *vecRange.at(nIndex)); - graph->data()->clear(); - graph->setData(vecContainer.at(nIndex)); - } - updateLengedValue(ui->plot->xAxis->pixelToCoord(ui->plot->symbolPos().x())); - rescaleYAxisRange(); - QList listSelectGraph = ui->plot->selectedGraphs(); - if(!listSelectGraph.isEmpty()) - { -// updateSelectGraph(listSelectGraph.first()->name()); - } - else - { - ui->plot->replot(); - } -} - -void CPlotWidget::updateSelectGraph(const QString &graphName) -{ - Curve curve = m_pTrendGraph->curve(graphName); - QCPGraph * graph = NULL; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - if(graphName == ui->plot->graph(nIndex)->name()) - { - graph = ui->plot->graph(nIndex); - } - } - if(graph == NULL || E_Trend_Invalid == m_type || E_Trend_RealTime == m_type || !curve.visible) - { - ui->plot->replot(); - return; - } - - QString device = curve.tag.section(".", 0, 1); - QString deviceGroup = CTrendInfoManage::instance()->queryDeviceGroup(device); - if(deviceGroup.isEmpty()) - { - ui->plot->replot(QCustomPlot::rpQueuedReplot); - return; - } - - QStringList tagList = CTrendInfoManage::instance()->queryTagListDevGroup(deviceGroup); - if(tagList.isEmpty()) - { - ui->plot->replot(QCustomPlot::rpQueuedReplot); - return; - } - - std::vector * vecMpKey = new std::vector(); - std::vector *> *vecResult = new std::vector *>(); - foreach (QString tagName, tagList) { - SMeasPointKey key; - std::string tmp = tagName.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(CTrendInfoManage::instance()->getTagType(tagName)); - vecMpKey->push_back(key); - - std::vector *vecEvtPoint = new std::vector(); - vecResult->push_back(vecEvtPoint); - } - - emit sigQueryHistoryEvent(vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, vecResult, curve.tag); - ui->plot->replot(QCustomPlot::rpQueuedReplot); -} - -void CPlotWidget::updatePhaseTracer(std::vector *vecMpKey, std::vector *> *vecResult, const QString &tag) -{ - ui->plot->clearItems(); - m_listTracer.clear(); - QCPGraph * graph = NULL; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - if(tag == ui->plot->graph(nIndex)->name()) - { - graph = ui->plot->graph(nIndex); - break; - } - } - if(NULL != graph) - { - QMultiMap< double, QStringList > map; - for(size_t tagIndex(0); tagIndex < vecResult->size(); tagIndex++) - { - std::vector *evetVector = vecResult->at(tagIndex); - std::vector::iterator iter = evetVector->begin(); - for(; iter != evetVector->end(); iter++) - { - QStringList list; - list.append(vecMpKey->at(tagIndex).m_pszTagName); - list.append(QString::number(iter->m_nAlmType)); - map.insert(iter->m_nTime, list); - } - } - - QPointF prePt(-1000., -1000.); - //< 1min 显示所有事件 - - bool bMinRange = ui->plot->xAxis->range().size() > 60; - QMultiMap< double, QStringList >::iterator rIter = map.begin(); - QMap hidePoint; - for(; rIter != map.end(); rIter++) - { - double key = rIter.key(); - if(bMinRange) - { - double curX = ui->plot->xAxis->coordToPixel(key); - if(qIsNaN(graph->value(key))) - { - continue; - } - double curY = ui->plot->yAxis->coordToPixel(graph->value(key)); - QPointF pt = QPointF(curX, curY) - prePt; - if(pt.manhattanLength() < 12) - { - hidePoint.insert(key, rIter.value()[0]); - continue; - } - prePt = QPointF(curX, curY); - } - QStringList value = rIter.value(); - QCPItemTracer *phaseTracer = new QCPItemTracer(ui->plot, key, QString(value[1]).toInt(), QPen(Qt::red), QBrush(Qt::red)); - phaseTracer->setGraphKey(key); - phaseTracer->setGraph(graph); - phaseTracer->addHidePoint(key, value[0]); - if(m_listTracer.length() > 0) - m_listTracer.last()->setHidePoint(hidePoint); - m_listTracer.append(phaseTracer); - connect(phaseTracer, &QCPItemTracer::itemTracerHoverd, m_pHisEventManage, &CHisEventManage::queryHisEvent, Qt::QueuedConnection); - hidePoint.clear(); - hidePoint.insert(key, value[0]); - } - } - - - //< 释放结果集 - std::vector *>::iterator res = vecResult->begin(); - while(res != vecResult->end()) - { - delete (*res); - ++res; - } - delete vecResult; - - //< 释放测点信息 - std::vector::iterator key = vecMpKey->begin(); - while(vecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - } - vecMpKey->clear(); - delete vecMpKey; - - ui->plot->replot(); -} - -void CPlotWidget::updateGraphEvent(const QString &tag, const qint64 &time, QStringList contents) -{ - foreach (QCPItemTracer *phaseTracer, m_listTracer) - { - if(phaseTracer->timeStamp() == time && phaseTracer->graph()->name() == tag) - { - phaseTracer->setInfo(contents); - phaseTracer->showTips(); - } - } -} - -void CPlotWidget::updateTrendRange(const QDate &date) -{ - CTabButton * button = dynamic_cast(sender()); - if(button && button != ui->realTime) - { - button->setChecked(true); - ui->plot->xAxis->blockSignals(true); - updateTrendShowMode(m_TrendTypeButton->id(button)); - const QCPRange &range = ui->plot->xAxis->range(); - double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime(date.addDays(1))); - ui->plot->xAxis->setRange(upper, range.size(), Qt::AlignRight); - ui->plot->xAxis->blockSignals(false); - updateCurves(); - } -} - -void CPlotWidget::updateAxisFormat(bool updateXAxisRange) -{ - QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); - double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); - switch (m_type) - { - case E_Trend_RealTime: - { - //< 10 min - ui->prePage->setEnabled(false); - ui->nextPage->setEnabled(false); - ui->date->setEnabled(false); - ui->plot->setInteractions(QCP::iRangeZoom | QCP::iSelectPlottables); - ui->plot->axisRect()->setScaleRight(true); - ticker->setDateTimeFormat("hh:mm:ss"); - ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); - if(Q_NULLPTR != m_pTimer) - { - m_pTimer->start(); - } - if(m_isWindowMode) - { - ticker->setTickCount(11); - setLegendCurveTransformColumnVisible(true); - } - else - { - ticker->setTickCount(6); - } - - m_pLengedModel->setMode(CCurveLegendModel::LENGED_RT_MODE); - ui->plot->yAxis->setTicker(m_ptrPlotTricker); - ui->plot->yAxis2->setTicker(m_ptrPlotTricker); - } - break; - case E_Trend_His_Minute: - { - if(m_isWindowMode) - { - ticker->setTickCount(12); - } - else - { - ticker->setTickCount(6); - } - ticker->setDateTimeFormat("hh:mm:ss"); - ui->date->setFixedWidth(120); - ui->date->setDisplayFormat("yyyy-MM-dd hh:mm"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Minute); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Hour: - { - if(m_isWindowMode) - { - ticker->setTickCount(11); - } - else - { - ticker->setTickCount(6); - } - ticker->setDateTimeFormat("hh:mm:ss"); - } - break; - case E_Trend_His_Day: - { - if(m_isWindowMode) - { - ticker->setTickCount(12); - } - else - { - ticker->setTickCount(6); - } - ticker->setDateTimeFormat("hh:mm:ss"); - ui->date->setFixedWidth(85); - ui->date->setDisplayFormat("yyyy-MM-dd"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Day); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Week: - { - if(m_isWindowMode) - { - ticker->setTickCount(8); - } - else - { - ticker->setTickCount(6); - } - ticker->setDateTimeFormat("MM-dd hh:mm ddd"); - ui->date->setFixedWidth(85); - ui->date->setDisplayFormat("yyyy-MM-dd"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Week); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Month: - { - if(m_isWindowMode) - { - ticker->setTickCount(11); - } - else - { - ticker->setTickCount(10); - } - ticker->setDateTimeFormat("MM-dd hh"); - ui->date->setFixedWidth(65); - ui->date->setDisplayFormat("yyyy-MM"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Month); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Quarter: - { - if(m_isWindowMode) - { - ticker->setTickCount(10); - } - else - { - ticker->setTickCount(10); - } - ticker->setDateTimeFormat("MM-dd hh"); - ui->date->setFixedWidth(65); - ui->date->setDisplayFormat("yyyy-MM"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Quarter); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Year: - { - if(m_isWindowMode) - { - ticker->setTickCount(13); - } - else - { - ticker->setTickCount(10); - } - ticker->setDateTimeFormat("yyyy-MM-dd"); - ui->date->setFixedWidth(50); - ui->date->setDisplayFormat("yyyy"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Year); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - default: - break; - } -} - -QPair CPlotWidget::getFatureDataTime(E_Trend_Type type, QDateTime curTime) -{ - QDateTime low; - QDateTime up; - QPair range; - if(curTime == QDateTime()) - { - low = QDateTime::currentDateTime(); - up = QDateTime::currentDateTime(); - } - else - { - low = curTime; - up = curTime; - } - - switch (type) { - case E_Trend_His_Day: - { - break; - } - case E_Trend_His_Minute: - { - int minute = up.time().minute(); - up.setTime(QTime(up.time().hour(), (minute/10)*10+9, 59, 999)); - low.setTime(QTime(low.time().hour(), (minute/10)*10)); - range.first = low.toMSecsSinceEpoch(); - range.second = up.toMSecsSinceEpoch(); - return range; - } - case E_Trend_His_Week: - { - up = up.addDays(7-low.date().dayOfWeek()); - low = low.addDays(-low.date().dayOfWeek()+1); - break; - } - case E_Trend_His_Month: - { - up.setDate(QDate(low.date().year(), low.date().month(), low.date().daysInMonth())); - low.setDate(QDate(low.date().year(), low.date().month(), 1)); - break; - } - case E_Trend_His_Quarter: - { - QString month = QString::number(low.date().month()); - if(QString("1,2,3").split(",").indexOf(month) != -1) - { - up.setDate(QDate(low.date().year(), 3, 31)); - low.setDate(QDate(low.date().year(), 1, 1)); - } - else if(QString("4,5,6").split(",").indexOf(month) != -1) - { - up.setDate(QDate(low.date().year(), 6, 30)); - low.setDate(QDate(low.date().year(), 4, 1)); - } - else if(QString("7,8,9").split(",").indexOf(month) != -1) - { - up.setDate(QDate(low.date().year(), 9, 30)); - low.setDate(QDate(low.date().year(), 7, 1)); - } - else if(QString("10,11,12").split(",").indexOf(month) != -1) - { - up.setDate(QDate(low.date().year(), 12, 31)); - low.setDate(QDate(low.date().year(), 10, 1)); - } - break; - } - case E_Trend_His_Year: - { - up.setDate(QDate(low.date().year(), 12, 31)); - low.setDate(QDate(low.date().year(), 1, 1)); - break; - } - default: - break; - } - low.setTime(QTime(0,0,0)); - up.setTime(QTime(23,59,59)); - range.first = low.toMSecsSinceEpoch(); - range.second = up.toMSecsSinceEpoch(); - return range; -} - -void CPlotWidget::updateAdaptState(bool isAdapt) -{ - m_bHisAdaption = isAdapt; - if(m_isWindowMode) - { - setLegendCurveTransformColumnVisible(isAdapt); - } - updateCurves(); - - updateYAxisTicker(); -} - -void CPlotWidget::addCollect() -{ - CEditCollectWidget * pCollectWidget = new CEditCollectWidget(this); - pCollectWidget->show(); - QPoint pt = ui->collectCurve->mapToGlobal(QPoint()); - pt.setX(pt.x() - pCollectWidget->width() + ui->collectCurve->width()); - pt.setY(pt.y() + ui->collectCurve->height() ); - pCollectWidget->move(pt); - connect(pCollectWidget, &CEditCollectWidget::acceptedInput, this, [=](){ - if(!pCollectWidget->text().isEmpty()) - { - emit collectGraph(pCollectWidget->text(), *m_pTrendGraph); - } - else - { - QMessageBox::warning(this, tr("错误"), tr("趋势名称不允许为空!"), - QMessageBox::Ok); - } - pCollectWidget->close(); - delete pCollectWidget; - }); -} - -void CPlotWidget::print() -{ - QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), "/home.jpg", tr("(*.jpg)"), - Q_NULLPTR, QFileDialog::DontUseNativeDialog); - - if(strFileName.isEmpty()) - { - return; - } - ui->plot->legend->setVisible(true); - m_trendTitle->setVisible(true); - ui->plot->replot(QCustomPlot::rpImmediateRefresh); - ui->plot->saveJpg(strFileName, 1600, 800); - ui->plot->legend->setVisible(false); - m_trendTitle->setVisible(false); -} - -void CPlotWidget::prePage() -{ - QDateTime dateTime = ui->date->dateTime(); - switch(m_type) - { - case E_Trend_His_Minute: - { - ui->date->setDateTime(dateTime.addSecs(-600)); - break; - } - case E_Trend_His_Hour: - case E_Trend_His_Day: - { - ui->date->setDateTime(dateTime.addDays(-1)); - break; - } - case E_Trend_His_Week: - { - ui->date->setDateTime(dateTime.addDays(-7)); - break; - } - case E_Trend_His_Month: - { - ui->date->setDateTime(dateTime.addMonths(-1)); - break; - } - case E_Trend_His_Quarter: - { - ui->date->setDateTime(dateTime.addMonths(-3)); - break; - } - case E_Trend_His_Year: - { - ui->date->setDateTime(dateTime.addYears(-1)); - break; - } - default: - return; - } - - QPair range = getFatureDataTime(m_type, ui->date->dateTime()); - ui->plot->xAxis->setRange(range.first, range.second); - updateCurves(); -} - -void CPlotWidget::nextPage() -{ - QDateTime dateTime = ui->date->dateTime(); - switch(m_type) - { - case E_Trend_His_Minute: - { - ui->date->setDateTime(dateTime.addSecs(600)); - break; - } - case E_Trend_His_Hour: - case E_Trend_His_Day: - { - ui->date->setDateTime(dateTime.addDays(1)); - break; - } - case E_Trend_His_Week: - { - ui->date->setDateTime(dateTime.addDays(7)); - break; - } - case E_Trend_His_Month: - { - ui->date->setDateTime(dateTime.addMonths(1)); - break; - } - case E_Trend_His_Quarter: - { - ui->date->setDateTime(dateTime.addMonths(3)); - break; - } - case E_Trend_His_Year: - { - ui->date->setDateTime(dateTime.addYears(1)); - break; - } - default: - return; - } - - QPair range = getFatureDataTime(m_type, ui->date->dateTime()); - ui->plot->xAxis->setRange(range.first, range.second); - updateCurves(); -} - -void CPlotWidget::graphVisibleChanged() -{ - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - Curve curve = m_pTrendGraph->curve(graph->name()); - graph->setVisible(curve.visible); - if(!curve.visible) - { - graph->removeFromLegend(ui->plot->legend); - } - else - { - graph->addToLegend(ui->plot->legend); - } - - if(graph->selected() && !curve.visible) - { - ui->plot->clearItems(); - m_listTracer.clear(); - } - } - rescaleYAxisRange(); - ui->plot->replot(); -} - -void CPlotWidget::graphPropertyChanged() -{ - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - Curve curve = m_pTrendGraph->curve(graph->name()); - graph->setPen(curve.color); - updateCurveSelectionColor(graph); - } - ui->lengedView->setCurrentIndex(ui->lengedView->model()->index(ui->lengedView->currentIndex().row(), 0)); - updateCurves(); -} - -void CPlotWidget::updateLengedValue(const double &dateTime) -{ - QList listVal; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - double graphValue = graph->value(dateTime); - Curve curve = m_pTrendGraph->curve(graph->name()); - double value = graphValue; - - if(m_bHisAdaption) - { - value = (graphValue - curve.graphOffset) / curve.graphFactor; - } - listVal.append(value); - } - m_pLengedModel->setTrendCurrentValues(listVal); -} - -void CPlotWidget::graphSelectionChanged(bool select) -{ - ui->plot->clearItems(); - m_listTracer.clear(); - ui->lengedView->selectionModel()->clear(); - updateYAxisTicker(); - - QCPGraph * graph = dynamic_cast(sender()); - if(Q_NULLPTR != graph && select) - { - ui->lengedView->selectRow(m_pTrendGraph->index(graph->name())); - updateSelectGraph(graph->name()); - } - ui->plot->replot(QCustomPlot::rpQueuedRefresh); -} - -void CPlotWidget::updateGraphSelection() -{ - ui->plot->blockSignals(true); - ui->plot->clearItems(); - ui->plot->deselectAll(); - ui->plot->blockSignals(false); - int index = ui->lengedView->currentIndex().row(); - QCPGraph * graph = ui->plot->graph(index); - if(graph) - { - QCPDataSelection selection(QCPDataRange(0, 1)); - graph->setSelection(selection); - } - ui->plot->replot(); -} - -void CPlotWidget::updateYAxisTicker() -{ - QList graphs = ui->plot->selectedGraphs(); - if(graphs.isEmpty()) - { - if(m_bHisAdaption) - { - QSharedPointer ticker(new QCPAxisTickerText); - for(int nIndex(0); nIndex <= 100; nIndex+= 20) - { - ticker->addTick(nIndex, " "); - } - ui->plot->yAxis->setTicker(ticker); - ui->plot->yAxis2->setTicker(ticker); - ui->plot->replot(QCustomPlot::rpQueuedRefresh); - return; - } - } - else - { - if(m_bHisAdaption) - { - QSharedPointer ticker(new QCPAxisTickerText); - Curve curve = m_pTrendGraph->curve(graphs.first()->name()); - QString strUnit = QString(); - if(!curve.unit.isEmpty()) - { - strUnit = QString("\n%1").arg(curve.unit); - } - double min = curve.hisPlotRange.min; - double max = curve.hisPlotRange.max; - double range = max - min; - min -= range * ui->scaleSlider->value() / 5.; - max += range * ui->scaleSlider->value() / 5.; - QList ticks = regulate(min, max, 11); - if(!ticks.isEmpty()) - { - double range = curve.hisPlotRange.max - curve.hisPlotRange.min; - for(int nIndex(0); nIndex < ticks.size(); nIndex += 2) - { - ticker->addTick((ticks.at(nIndex) - curve.hisPlotRange.min) / range * 100, QString::number((ticks.at(nIndex)), 'f', 1) + strUnit); - } - ui->plot->yAxis->setTicker(ticker); - ui->plot->yAxis2->setTicker(ticker); - } - ui->plot->replot(QCustomPlot::rpQueuedRefresh); - return; - } - } - ui->plot->yAxis->setTicker(m_ptrPlotTricker); - ui->plot->yAxis2->setTicker(m_ptrPlotTricker); - ui->plot->replot(QCustomPlot::rpQueuedRefresh); -} - -EnMeasPiontType CPlotWidget::getMeasType(const QString &type) -{ - if ("analog" == type) - { - return MPT_AI; //< 模拟量 - } - else if ("digital" == type) - { - return MPT_DI; //< 数字量 - } - else if ("mix" == type) - { - return MPT_MIX; //< 混合量 - } - else if ("accuml" == type) - { - return MPT_ACC; //< 累计(电度)量 - } - return MPT_AI; //< INVALID -} - -void CPlotWidget::setLegendCurveTransformColumnVisible(const bool &visible) -{ - Q_UNUSED(visible) - ui->lengedView->setColumnHidden(CCurveLegendModel::FACTOR, true); - ui->lengedView->setColumnHidden(CCurveLegendModel::OFFSET, true); -} - -QList CPlotWidget::regulate(double min, double max, int tickCount) -{ - QList ticks; - if (tickCount < 1 || max < min) - { - return ticks; - } - - double delta = max - min; - if (delta < 1.0) - { - max += (1.0 - delta) / 2.0; - min -= (1.0 - delta) / 2.0; - } - delta = max - min; - - int exp = (int)(log(delta) / log(10.0)) - 2; - double multiplier = pow(10, exp); - const double solutions[] = { 1, 2, 2.5, 5, 10, 20, 25, 50, 100, 200, 250, 500 }; - - int nIndex = 0; - for (; nIndex < (int)(sizeof(solutions) / sizeof(double)); ++nIndex) - { - double multiCal = multiplier * solutions[nIndex]; - if (((int)(delta / multiCal) + 1) <= tickCount) - { - break; - } - } - - double interval = multiplier * solutions[nIndex]; - - double startPoint = ((int)ceil(min / interval) - 1) * interval; - for (int axisIndex = 0; startPoint + interval*axisIndex <= max; axisIndex++) - { - ticks.append(startPoint + interval*axisIndex); - } - return ticks; -} - -void CPlotWidget::rescaleYAxisRange() -{ - ui->plot->yAxis->setRange(-1, 1); - ui->plot->yAxis->rescale(true); - ui->plot->yAxis->scaleRange(ui->scaleSlider->value() / 5. + 1.20); - if(m_bHisAdaption) - { - updateYAxisTicker(); - } - else - { - ui->plot->replot(); - } -} - -template -void CPlotWidget::updateHisData(std::vector*> *vecResult, std::vector > &vecRange, std::vector< QSharedPointer > &vecContainer, int nGroupByMinute) -{ - int nMaxIntervalSecs = (SAMPLE_CYC_MIN + nGroupByMinute) * 60 * 1000; - typename std::vector *>::const_iterator it = vecResult->begin(); - while(it != vecResult->end()) - { - QSharedPointer range(new Range()); - QSharedPointer container(new QCPGraphDataContainer()); - vecRange.push_back(range); - vecContainer.push_back(container); - - //< Valid Check - std::vector<_Tp> * vecPoint = *it; - if(vecPoint->empty()) - { - ++it; - continue; - } - - //< Graph Bound - _Tp left; - left.m_nTime = ui->plot->xAxis->range().lower; - typename std::vector<_Tp>::const_iterator varHisLeft = std::upper_bound((*vecPoint).begin(), (*vecPoint).end(), left, compareVarPoint<_Tp>); - if(varHisLeft != (*vecPoint).begin() && varHisLeft != (*vecPoint).end()) - { - --varHisLeft; - } - - _Tp right; - right.m_nTime = ui->plot->xAxis->range().upper; - typename std::vector<_Tp>::const_iterator varHisRight = std::lower_bound((*vecPoint).begin(), (*vecPoint).end(), right, compareVarPoint<_Tp>); - if(varHisRight == (*vecPoint).end()) - { - varHisRight = (*vecPoint).end() - 1; - } - ++varHisRight; - - //< Prepare Work(used: record Interval) - qint64 lastTimeStamp = -1; - - //< Handle Data - typename std::vector<_Tp>::const_iterator pt = varHisLeft; - while(pt != varHisRight) - { - double value = qSqrt(-1.); - if (typeid(boost::int32_t) == pt->m_varValue.type()) - { - value = (double)boost::get(pt->m_varValue); - } - else if (typeid(boost::float64_t) == pt->m_varValue.type()) - { - value = (double)boost::get(pt->m_varValue); - } - - if(value > range->max) - { - range->max = value; - } - if(value < range->min) - { - range->min = value; - } - - qint64 timeStamp = pt->m_nTime; - if(lastTimeStamp > 0 && lastTimeStamp + nMaxIntervalSecs < timeStamp) - { - container->add(QCPGraphData(lastTimeStamp, qSqrt(-1.))); - } - container->add(QCPGraphData(timeStamp, value)); - lastTimeStamp = timeStamp; - ++pt; - } - ++it; - } -} - -template -bool CPlotWidget::checkStatus(const _Tp &var, const int &nInvalid) -{ - Q_UNUSED(var); - Q_UNUSED(nInvalid); - return true; -} - -template -bool CPlotWidget::checkStatus(const SVarHisSamplePoint &var, const int &nInvalid) -{ - return nInvalid == (var.m_nStatus & nInvalid); -} - -void CPlotWidget::slotDateTimeChanged(const QDateTime &dateTime) -{ - QPair range = getFatureDataTime(m_type, dateTime); - ui->plot->xAxis->setRange(range.first, range.second); - - updateCurves(); -} +#include "CPlotWidget.h" +#include "ui_CPlotWidget.h" +#include "CCurveLegendModel.h" +#include "CHisEventManage.h" +#include "CTrendInfoManage.h" +#include "CRealTimeDataCollect.h" +#include "sample_server_api/SampleDefine.h" +#include "pub_logger_api/logger.h" +#include "./widgets/CEditCollectWidget.h" +#include "./widgets/CToolTip.h" + +using namespace kbd_dbms; + +CPlotWidget::CPlotWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::CPlotWidget), + m_type(E_Trend_Invalid), + m_bHisAdaption(false), + m_TrendTypeButton(Q_NULLPTR), + m_pLengedModel(Q_NULLPTR), + m_pTimer(Q_NULLPTR), + m_pTrendGraph(Q_NULLPTR), + m_pDpcdaForApp(Q_NULLPTR), + m_rtDataCollect(Q_NULLPTR), + m_pHisDataThread(Q_NULLPTR), + m_pHisDataManage(Q_NULLPTR), + m_pHisEventThread(Q_NULLPTR), + m_pHisEventManage(Q_NULLPTR), + m_isWindowMode(true) +{ + ui->setupUi(this); + setContentsMargins(1, 1, 1, 1); + qRegisterMetaType< E_Data_Type >("E_Data_Type"); + qRegisterMetaType< kbd_dbms::EnComputeMethod >("kbd_dbms::EnComputeMethod"); + qRegisterMetaType< std::vector >("std::vector"); + qRegisterMetaType< std::vector *> >("std::vector *>"); +} + +CPlotWidget::~CPlotWidget() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = Q_NULLPTR; + + if(m_pHisEventManage) + { + emit releaseHisEventThread(); + m_pHisEventManage = Q_NULLPTR; + } + + if(m_pHisEventThread) + { + m_pHisEventThread->quit(); + m_pHisEventThread->wait(); + } + m_pHisEventThread = Q_NULLPTR; + + if(m_pHisDataManage) + { + emit releaseHisEventThread(); + m_pHisDataManage = Q_NULLPTR; + } + if(m_pHisDataThread) + { + m_pHisDataThread->quit(); + m_pHisDataThread->wait(); + } + m_pHisDataThread = Q_NULLPTR; + + if(m_pTrendGraph) + { + delete m_pTrendGraph; + } + m_pTrendGraph = Q_NULLPTR; + + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = Q_NULLPTR; + + if(m_rtDataCollect->isRunning()) + { + m_rtDataCollect->disconnect(this); + m_rtDataCollect->requestInterruption(); + m_rtDataCollect->wait(); + } + m_rtDataCollect = Q_NULLPTR; + delete ui; +} + +/************************************************************************ + * + * 1、初始化界面 + * 2、初始化实时数据采集 + * + ************************************************************************/ +void CPlotWidget::initialize() +{ + initTsdbApi(); + m_pTrendGraph = new CTrendGraph(); + m_rtRange = 10 * 60 * 1000; //< second + + //< GroupButton + m_TrendTypeButton = new QButtonGroup(this); + m_TrendTypeButton->addButton(ui->realTime, E_Trend_RealTime); + m_TrendTypeButton->addButton(ui->sec, E_Trend_His_Minute); + m_TrendTypeButton->addButton(ui->day, E_Trend_His_Day); + m_TrendTypeButton->addButton(ui->week, E_Trend_His_Week); + m_TrendTypeButton->addButton(ui->month, E_Trend_His_Month); + m_TrendTypeButton->addButton(ui->quarter, E_Trend_His_Quarter); + m_TrendTypeButton->addButton(ui->year, E_Trend_His_Year); + connect(m_TrendTypeButton, SIGNAL(buttonClicked(int)), this, SLOT(updateTrendShowMode(int))); +// QList listButton = m_TrendTypeButton->buttons(); +// foreach (QAbstractButton * button, listButton) +// { +// CTabButton * tabButton = dynamic_cast(button); +// if(tabButton && tabButton != ui->realTime) +// { +// tabButton->setShowCalendarEnable(true); +// connect(tabButton, &CTabButton::dataChanged, this, &CPlotWidget::updateTrendRange); +// } +// } + connect(ui->prePage, &QPushButton::clicked, this, &CPlotWidget::prePage); + connect(ui->nextPage, &QPushButton::clicked, this, &CPlotWidget::nextPage); + connect(ui->date, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotDateTimeChanged); + ui->date->setCalendarPopup(true); + ui->date->setDateTime(QDateTime::currentDateTime()); + + //< initPlot + ui->plot->setEnabled(true); + ui->plot->setSymbolPos(QPoint(width() / 2, 0)); + ui->plot->setNoAntialiasingOnDrag(true); + ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //<水平拖拽 + ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //<水平缩放 + ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); + QSharedPointer ticker(new QCPAxisTickerDateTime()); + ui->plot->xAxis->setTicker(ticker); + ui->plot->yAxis->setRange(-1, 1); + ui->plot->yAxis->scaleRange(1.02); + ui->plot->yAxis2->setVisible(true); + ui->plot->xAxis->setScaleType(QCPAxis::stLinear); + m_ptrPlotTricker = ui->plot->yAxis->ticker(); + connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->yAxis2, SLOT(setRange(QCPRange))); + connect(ui->plot->xAxis, SIGNAL(rangeChanged(const QCPRange &,const QCPRange &)), this, SLOT(plotAxisRangeChanged(const QCPRange &,const QCPRange &))); + connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeDraged, this, &CPlotWidget::updateCurves); + connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeScaled, this, &CPlotWidget::updateCurves); + connect(ui->plot, &QCustomPlot::symbolPosChanged, this, &CPlotWidget::updateLengedValue); + + //< initTitle + m_trendTitle = new QCPItemText(ui->plot); + m_trendTitle->setObjectName("m_trendTitle"); + m_trendTitle->setPositionAlignment(Qt::AlignCenter); + m_trendTitle->position->setType(QCPItemPosition::ptAxisRectRatio); + m_trendTitle->position->setCoords(0.03, 0.01); + m_trendTitle->setColor(QColor(255,255,255)); + m_trendTitle->setFont(QFont("Microsoft YaHei", 10)); + m_trendTitle->setText("实时趋势"); + m_trendTitle->setVisible(false); + + //< initTableView + m_pLengedModel = new CCurveLegendModel(ui->lengedView); + ui->lengedView->setModel(m_pLengedModel); + ui->lengedView->setItemDelegate(new CCurveLegnedDelegate(ui->lengedView)); + ui->lengedView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked); + ui->lengedView->verticalHeader()->setVisible(false); + ui->lengedView->setAlternatingRowColors(true); + ui->lengedView->horizontalHeader()->setStretchLastSection(true); + ui->lengedView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->lengedView->setSelectionMode(QAbstractItemView::SingleSelection); + ui->lengedView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->lengedView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + + connect(m_pLengedModel, &CCurveLegendModel::graphVisibleChanged, this, &CPlotWidget::graphVisibleChanged); + connect(m_pLengedModel, &CCurveLegendModel::graphPropertyChanged, this, &CPlotWidget::graphPropertyChanged); + connect(ui->lengedView, &QTableView::clicked, this, &CPlotWidget::updateGraphSelection); + + ui->plotExport->setVisible(false); + ui->adaptFrame->setVisible(false); + ui->clear->setEnabled(false); + ui->collectCurve->setVisible(false); + connect(ui->adapt, &QCheckBox::toggled, this, &CPlotWidget::updateAdaptState); + connect(ui->collectCurve, &QPushButton::clicked, this, &CPlotWidget::addCollect); + connect(ui->plotPrint, &QPushButton::clicked, this, &CPlotWidget::print); + connect(ui->clear, &QPushButton::clicked, this, &CPlotWidget::clear); + if(Q_NULLPTR == m_pTimer) + { + m_pTimer = new QTimer(this); + m_pTimer->setInterval(1000); + connect(m_pTimer, &QTimer::timeout, this, &CPlotWidget::realTimeElapsed); + } + + m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); + m_rtDataCollect = new CRealTimeDataCollect(this); + connect(m_rtDataCollect, &CRealTimeDataCollect::finished, m_rtDataCollect, &CRealTimeDataCollect::deleteLater); + connect(m_rtDataCollect, &CRealTimeDataCollect::realTimeTrendDataArrived, this, &CPlotWidget::recvRealTimeTrendData, Qt::QueuedConnection); + m_rtDataCollect->start(); + + m_pHisDataManage = new CHisDataManage(); + m_pHisDataThread = new QThread(this); + m_pHisDataManage->moveToThread(m_pHisDataThread); + connect(m_pHisDataThread, &QThread::finished, m_pHisDataThread, &QObject::deleteLater); + connect(this, &CPlotWidget::releaseHisDataThread, m_pHisDataManage, &CHisDataManage::release, Qt::BlockingQueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryOriginalData, m_pHisDataManage, &CHisDataManage::queryHistoryOriginalData, Qt::QueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryPolymericData, m_pHisDataManage, &CHisDataManage::queryHistoryPolymericData, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigupdateHisOriginalData, this, &CPlotWidget::updateHisOriginalData, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHistoryPolymericData, this, &CPlotWidget::updateHisPolymericData, Qt::QueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryEvent, m_pHisDataManage, &CHisDataManage::queryHistoryEvents, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHistoryEvent, this, &CPlotWidget::updatePhaseTracer, Qt::QueuedConnection); + + m_pHisDataThread->start(); + + m_pHisEventManage = new CHisEventManage(); + m_pHisEventThread = new QThread(this); + m_pHisEventManage->moveToThread(m_pHisEventThread); + connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); + connect(this, &CPlotWidget::releaseHisEventThread, m_pHisEventManage, &CHisEventManage::release, Qt::BlockingQueuedConnection); + connect(m_pHisEventManage, &CHisEventManage::updateHisEvent, this, &CPlotWidget::updateGraphEvent ,Qt::QueuedConnection); + m_pHisEventThread->start(); + + connect(ui->scaleSlider, &QSlider::valueChanged, this, &CPlotWidget::rescaleYAxisRange); + + QMetaObject::invokeMethod(ui->realTime, "click"); +} + +void CPlotWidget::resizeEvent(QResizeEvent *event) +{ + QSize size = parentWidget()->size(); + if(ui->titleFrame->isVisible()) + { + size.setHeight(size.height() - (ui->titleFrame->height() + ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + 15)); + } + else + { + size.setHeight(size.height() - (ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + 15)); + } + ui->plot->resize(size); + ui->plot->replot(); + + updateLengedColumnWidth(); + QWidget::resizeEvent(event); +} + +void CPlotWidget::updateLengedColumnWidth() +{ + int nLengedWidth = ui->lengedView->width(); + ui->lengedView->setColumnWidth(CCurveLegendModel::NAME, nLengedWidth / 12. * 3); + ui->lengedView->setColumnWidth(CCurveLegendModel::COLOR, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::VALUE, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MAX, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MAXTIME, nLengedWidth / 12. * 1.5); + ui->lengedView->setColumnWidth(CCurveLegendModel::MIN, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MINTIME, nLengedWidth / 12. * 1.5); + ui->lengedView->setColumnWidth(CCurveLegendModel::AVE, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::UNIT, nLengedWidth / 12.); + // ui->lengedView->setColumnWidth(CCurveLegendModel::FACTOR, nLengedWidth / 12.); + // ui->lengedView->setColumnWidth(CCurveLegendModel::OFFSET, nLengedWidth / 12.); +} + +void CPlotWidget::updateCurveSelectionColor(QCPGraph *graph) +{ + if(!graph) + { + return; + } + QPen selectedPen = graph->selectionDecorator()->pen(); + selectedPen.setWidth(1); + QColor color; + QColor graphColor = graph->pen().color(); + int r = graphColor.red() > 225 ? graphColor.red() - 30 : graphColor.red() + 30; + int g = graphColor.green() > 225 ? graphColor.green() - 30 : graphColor.green() + 30; + int b = graphColor.blue() > 225 ? graphColor.blue() - 30 : graphColor.blue() + 30; + color.setRgb(r, g, b); + selectedPen.setColor(color); + graph->selectionDecorator()->setPen(selectedPen); +} + +E_Trend_Type CPlotWidget::getRangeType(const QCPRange &range) +{ + if(range.size() <= 0) + { + return E_Trend_Invalid; + } + + QDateTime upper = QDateTime::fromMSecsSinceEpoch(range.upper); + + if(range.lower >= upper.addSecs(-10).toMSecsSinceEpoch()) + { + return E_Trend_RealTime; + } + else if(range.lower >= upper.addSecs(-600).toMSecsSinceEpoch()) + { + return E_Trend_His_Minute; + } + else if(range.lower >= upper.addSecs(-3600).toMSecsSinceEpoch()) + { + return E_Trend_His_Hour; + } + else if(range.lower >= upper.addDays(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Day; + } + else if(range.lower >= upper.addDays(-7).toMSecsSinceEpoch()) + { + return E_Trend_His_Week; + } + else if(range.lower >= upper.addMonths(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Month; + } + else if(range.lower >= upper.addMonths(-3).toMSecsSinceEpoch()) + { + return E_Trend_His_Quarter; + } + else if(range.lower >= upper.addYears(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Year; + } + + return E_Trend_His_Year; +} + +int CPlotWidget::currentGroupByMinute() +{ + int nGroupByMinute = 0; + switch (m_type) + { + case E_Trend_RealTime: + { + //< Error + } + break; + case E_Trend_His_Minute: + { + //< Error + } + break; + case E_Trend_His_Hour: + { + //< Error + } + break; + case E_Trend_His_Day: + { + nGroupByMinute = 1; + } + break; + case E_Trend_His_Week: + { + nGroupByMinute = 7; + } + break; + case E_Trend_His_Month: + { + nGroupByMinute = 30; + } + break; + case E_Trend_His_Quarter: + { + nGroupByMinute = 90; + } + break; + case E_Trend_His_Year: + { + nGroupByMinute = 365; + } + break; + default: + break; + } + return nGroupByMinute; +} + +/************************************************************************ + * + * 接口 + * + ************************************************************************/ +void CPlotWidget::setTitle(const QString &title) +{ + ui->title->setText(title); +} + +void CPlotWidget::setTitleVisible(bool visible) +{ + ui->titleFrame->setVisible(visible); +} + +void CPlotWidget::setTickCount(const int &count) +{ + QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); + ticker->setTickCount(count); +} + +void CPlotWidget::insertTag(const QString &tag) +{ +// static int nTagIndex = 0; +// if(nTagIndex > 63) +// { +// nTagIndex = 0; +// } + int graphSize = m_pTrendGraph->curves().size() % 16; + + Curve curve; + curve.tag = tag; + curve.color = m_listColor.at(graphSize); //m_listColor.at((nTagIndex++) % m_listColor.size()); + insertCurve(curve); +} + +void CPlotWidget::insertTag(const QStringList &listTag) +{ + m_pTrendGraph->clear(); + foreach (QString tag, listTag) + { + insertTag(tag); + } +} + +void CPlotWidget::removeTag(const QString &tag) +{ + int nIndex = m_pTrendGraph->removeCurve(tag); + if(nIndex != -1) + { + if(ui->plot->graph(nIndex)->selected()) + { + ui->plot->clearItems(); + m_listTracer.clear(); + } + ui->plot->removeGraph(nIndex); + } + + m_pLengedModel->setTrendGraph(m_pTrendGraph); + updateLengedColumnWidth(); + if(!m_pTrendGraph->curves().size()) + { + ui->plot->yAxis->setRange(QCPRange(-1, 1)); + + if(m_isWindowMode) + { + ui->collectCurve->setVisible(false); + } + ui->clear->setEnabled(false); + } + ui->plot->replot(); +} + +void CPlotWidget::setDisplayTime(const int &trendType, const double &dateTime) +{ + QAbstractButton* Button = m_TrendTypeButton->button(trendType); + if(Button) + { + QMetaObject::invokeMethod(Button, "click"); + + QDateTime nDateTime = QDateTime::fromMSecsSinceEpoch(dateTime); + ui->date->setDateTime(nDateTime); + } +} + +void CPlotWidget::setTagVisible(const QString &tag, const bool &visible) +{ + int nIndex = m_pTrendGraph->index(tag); + if(nIndex != -1) + { + m_pLengedModel->setData(m_pLengedModel->index(nIndex, 0), visible, Qt::CheckStateRole); + ui->plot->replot(); + } +} + +void CPlotWidget::setClearVisible(bool visible) +{ + if(visible) + { + ui->clear->show(); + } + else + { + ui->clear->hide(); + } +} + +void CPlotWidget::insertCurve(Curve curve) +{ + if(ui->plot->graphCount() >= 64) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势曲线已达最大支持数量[64]!"), QMessageBox::Ok); + emit updateTagCheckState(curve.tag, false); + return; + } + + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(curve.tag == ui->plot->graph(nIndex)->name()) + { + LOGINFO("趋势曲线[%s]已存在", curve.tag.toStdString().c_str()); + return; + } + } + + curve.type = CTrendInfoManage::instance()->getTagType(curve.tag); + curve.unit = CTrendInfoManage::instance()->getTagUnit(curve.tag); + if(curve.type.isEmpty()) + { + LOGINFO("趋势曲线[%s]类型不存在", curve.tag.toStdString().c_str()); + return; + } + + curve.desc = CTrendInfoManage::instance()->getTagDescription(curve.tag); + if(curve.desc.isEmpty()) + { + LOGINFO("趋势曲线[%s]描述不存在", curve.tag.toStdString().c_str()); + return; + } + + + m_pDpcdaForApp->subscribe(curve.type.toStdString(), curve.tag.toStdString(), "value"); + + //< 添加曲线 + m_pTrendGraph->addCurve(curve); + QCPGraph * graph = ui->plot->addGraph(); + graph->setName(curve.tag); + graph->setDesc(curve.desc); + graph->setPen(curve.color); + updateCurveSelectionColor(graph); + +// connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); + + //< 方波 + QString type = CTrendInfoManage::instance()->getTagType(curve.tag); + if(type == "digital" || type == "mix") + { + graph->setLineStyle(QCPGraph::lsStepLeft); + } + + //< 查询最新十分钟数据 +// double upper = QDateTime::currentMSecsSinceEpoch(); +// double lower = upper - (10 * 60 * 1000); +// SMeasPointKey key; +// std::string tmp = curve.tag.toStdString(); +// char * tag = (char*)malloc(tmp.size() + 1); +// memset(tag, 0, tmp.size() + 1); +// memcpy(tag, tmp.c_str(), tmp.size()); +// key.m_pszTagName = tag; +// key.m_enType = getMeasType(curve.type); +// std::vector * vecMpKey = new std::vector(); +// vecMpKey->push_back(key); +// emit sigQueryHistoryOriginalData(vecMpKey, lower, upper, E_REALTIME); + updateCurves(); + + m_pLengedModel->setTrendGraph(m_pTrendGraph); + updateLengedColumnWidth(); + if(m_type == E_Trend_RealTime && m_isWindowMode) + { + setLegendCurveTransformColumnVisible(true); + } + ui->clear->setEnabled(true); + + if(m_isWindowMode) + { + ui->collectCurve->setVisible(false); + emit updateTagCheckState(curve.tag, true); + } + else + { + setLegendCurveTransformColumnVisible(true); + } + +} + +void CPlotWidget::clear(bool clearTitle) +{ + if(!m_pTrendGraph->curves().size()) + { + ui->clear->setEnabled(false); + } + m_pTrendGraph->clear(); + m_pLengedModel->clear(); + m_pLengedModel->update(); + + ui->plot->yAxis->setRange(QCPRange(-1, 1)); + ui->plot->clearItems(clearTitle); + ui->plot->clearGraphs(); + ui->plot->replot(); + setTitle(tr("趋势图")); + if(m_isWindowMode) + { + ui->collectCurve->setVisible(false); + } + emit clearCurve(); +} + +void CPlotWidget::setWindowMode(const bool &isWindowMode) +{ + m_isWindowMode = isWindowMode; +} + +void CPlotWidget::setColorList(const QStringList &listColor) +{ + foreach (QString c, listColor) + { + c.replace("\r", ""); + m_listColor.append(QColor(c)); + } +} + +/****************************** 图表颜色 **************************************/ +QColor CPlotWidget::plotBackgroundColor() +{ + return m_plotBackgroundColor; +} + +void CPlotWidget::setPlotBackgroundColor(const QColor &color) +{ + m_plotBackgroundColor = color; + + ui->plot->setBackground(m_plotBackgroundColor); +} + +QPixmap CPlotWidget::plotBackImage() +{ + return m_plotBackImage; +} + +void CPlotWidget::setPlotBackImage(const QPixmap &pm) +{ + m_plotBackImage = pm; + + ui->plot->setBackgroundScaled(false); + ui->plot->setBackground(pm); +} + +QColor CPlotWidget::plotTickColor() +{ + return m_plotTickColor; +} + +void CPlotWidget::setPlotTickColor(const QColor &color) +{ + m_plotTickColor = color; + + ui->plot->xAxis->setTickLabelColor(color); + ui->plot->yAxis->setTickLabelColor(color); + ui->plot->yAxis2->setTickLabelColor(color); +} + +QColor CPlotWidget::plotGridColor() +{ + return m_plotGridColor; +} + +void CPlotWidget::setPlotGridColor(const QColor &color) +{ + m_plotGridColor = color; + + ui->plot->xAxis->grid()->setPen(color); + ui->plot->yAxis->grid()->setPen(color); + + ui->plot->xAxis->grid()->setSubGridPen(color); + ui->plot->yAxis->grid()->setSubGridPen(color); +} + +QColor CPlotWidget::plotZeroLineColor() +{ + return m_plotZeroLineColor; +} + +void CPlotWidget::setPlotZeroLineColor(const QColor &color) +{ + m_plotZeroLineColor = color; + + ui->plot->xAxis->grid()->setZeroLinePen(QPen(color)); + ui->plot->yAxis->grid()->setZeroLinePen(QPen(color)); +} + +QColor CPlotWidget::plotTickPen() +{ + return m_plotTickPen; +} + +void CPlotWidget::setPlotTickPen(const QColor &color) +{ + m_plotTickPen = color; + + ui->plot->xAxis->setBasePen(color); + ui->plot->yAxis->setBasePen(color); + ui->plot->yAxis2->setBasePen(color); + ui->plot->xAxis->setTickPen(color); + ui->plot->yAxis->setTickPen(color); + ui->plot->yAxis2->setTickPen(color); + ui->plot->xAxis->setSubTickPen(color); + ui->plot->yAxis->setSubTickPen(color); + ui->plot->yAxis2->setSubTickPen(color); +} +/*****************************************************************************/ + + +void CPlotWidget::realTimeElapsed() +{ + //< 刷新X轴 + const QCPRange &range = ui->plot->xAxis->range(); + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); + ui->plot->xAxis->setRange(upper, range.size(), Qt::AlignRight); + + QList listVal; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + m_pTrendGraph->updateRTCurveStatisticsInfo(graph->name()); + QVector * pCPGraphData = graph->data()->data(); + + if(pCPGraphData->isEmpty()) + { + listVal.append(qSqrt(-1.)); + } + else + { + + listVal.append(pCPGraphData->last().value); + + //< set virtual point value + if(limit == pCPGraphData->last().key) + { + pCPGraphData->last().value = (*(pCPGraphData->end() - 2)).value; + } + } + } + m_pLengedModel->setTrendCurrentValues(listVal); + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::recvRealTimeTrendData(const QString &tagName, QVariant value) +{ + //< LOGINFO("Recv RealTime Trend Data-[Tag Name: %s, value: %f] ", tagName.toStdString().c_str(), value.toDouble()); + double key = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + m_pTrendGraph->pushCurveRTDataValue(tagName, key, value.toDouble()); + + if(E_Trend_RealTime != m_type) + { + return; + } + + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + if(graph->name() == tagName) + { + QVector * pCPGraphData = graph->data()->data(); + + if(!pCPGraphData->isEmpty() && qAbs(((*(pCPGraphData->end() - 2)).value - value.toDouble())) < _EPSILON_) + { + return; + } + graph->addData(key, value.toDouble()); + if( pCPGraphData->first().key < ( key - (20 * 60 * 1000) ) ) + { + graph->data()->removeBefore( key - (20 * 60 * 1000) ); + } + return; + } + } +} + +void CPlotWidget::plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange) +{ + Q_UNUSED(oldRange); + QDateTime upper = QDateTime::fromMSecsSinceEpoch(newRange.upper); + double midValue = (newRange.upper + newRange.lower) / 2; + + if(m_type == E_Trend_RealTime) + { + m_rtRange = newRange.size(); + if(m_rtRange > 10 * 60 * 1000) + { + m_rtRange = 10 * 60 * 1000; + } + else if(m_rtRange < 10 * 1000) + { + m_rtRange = 10 * 1000; + } + + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); + return; + } + else if(m_type == E_Trend_His_Minute || m_type == E_Trend_His_Day || m_type == E_Trend_His_Week || m_type == E_Trend_His_Month || m_type == E_Trend_His_Quarter || m_type == E_Trend_His_Year) + { + QPair dateTime = getFatureDataTime(m_type, ui->date->dateTime()); + double range = newRange.size() > (dateTime.second - dateTime.first)?(dateTime.second - dateTime.first):newRange.size(); + if(newRange.lower < dateTime.first) + { + ui->plot->xAxis->setRange(dateTime.first, range, Qt::AlignLeft); + return; + } + else if(newRange.upper > dateTime.second) + { + ui->plot->xAxis->setRange(dateTime.second, range, Qt::AlignRight); + return; + } + } +// else if(m_type == E_Trend_His_Year) +// { +// if(newRange.size() > newRange.upper - upper.addYears(-1).toMSecsSinceEpoch()) +// { +// ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addYears(-1).toMSecsSinceEpoch(), Qt::AlignCenter); +// return; +// } +// } + + QList listToolTip= findChildren(); + foreach (CToolTip * pToolTip, listToolTip) + { + pToolTip->close(); + } + + if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) + { + updateYAxisTicker(); + } + + E_Trend_Type rangeType = getRangeType(newRange); + if(m_type == rangeType) + { + return; + } + + if(m_type == E_Trend_His_Minute) + { + if(rangeType == E_Trend_RealTime) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-10).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Hour) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Day) + { + if(rangeType == E_Trend_His_Minute) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Week) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Week) + { + if(rangeType == E_Trend_His_Day) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Month) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Month) + { + if(rangeType == E_Trend_His_Week) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Quarter) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Quarter) + { + if(rangeType == E_Trend_His_Month) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Year) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Year) + { + if(rangeType == E_Trend_His_Quarter) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + +// if(rangeType != E_Trend_Invalid && rangeType != E_Trend_His_Minute && rangeType != E_Trend_His_Hour) +// { +// m_TrendTypeButton->button((int)rangeType)->setChecked(true); +// } +// updateTrendShowMode(rangeType, false); +} + +void CPlotWidget::updateTrendShowMode(int nIndex, bool updateXAxisRange) +{ + updateGraphTitle(nIndex); + + m_type = (E_Trend_Type)nIndex; + if(Q_NULLPTR != m_pTimer && m_pTimer->isActive()) + { + m_pTimer->stop(); + } + m_pLengedModel->setMode(CCurveLegendModel::LENGED_HIS_MODE); + if(m_isWindowMode) + { + setLegendCurveTransformColumnVisible(false); + } + //< default setting + ui->prePage->setEnabled(true); + ui->nextPage->setEnabled(true); + ui->date->setEnabled(true); + ui->plot->axisRect()->setScaleRight(false); + ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //< 水平拖拽 + ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //< 水平缩放 + ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); + ui->plot->xAxis->setScaleType(QCPAxis::stLinear); + + updateAxisFormat(updateXAxisRange); + + if (m_type == E_Trend_RealTime || m_type == E_Trend_Invalid) + { + ui->prePage->setVisible(false); + ui->nextPage->setVisible(false); + ui->date->setVisible(false); + } + else + { + ui->prePage->setVisible(true); + ui->nextPage->setVisible(true); + ui->date->setVisible(true); + ui->date->setDateTime(QDateTime::currentDateTime()); + } + + if(updateXAxisRange) + { + updateCurves(); + } +} + +void CPlotWidget::updateGraphTitle(int nIndex) +{ + m_type = (E_Trend_Type)nIndex; + + if(m_type == E_Trend_RealTime) + { + m_trendTitle->setText("实时趋势"); + } + else if(m_type == E_Trend_His_Minute) + { + m_trendTitle->setText("秒趋势"); + } + else if(m_type == E_Trend_His_Day) + { + m_trendTitle->setText("日趋势"); + } + else if(m_type == E_Trend_His_Week) + { + m_trendTitle->setText("周趋势"); + } + else if(m_type == E_Trend_His_Month) + { + m_trendTitle->setText("月趋势"); + } + else if(m_type == E_Trend_His_Quarter) + { + m_trendTitle->setText("季度趋势"); + } + else if(m_type == E_Trend_His_Year) + { + m_trendTitle->setText("年趋势"); + } +} + +void CPlotWidget::updateCurves() +{ + if(E_Trend_RealTime == m_type) + { + ui->adaptFrame->setVisible(false); + updateRealTimeCurveRecord(); + rescaleYAxisRange(); + ui->plot->replot(); + } + else + { + ui->adaptFrame->setVisible(true); + updateHistoryCurveRecord(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper); + } +} + +void CPlotWidget::updateRealTimeCurveRecord() +{ + if(Q_NULLPTR == m_pTrendGraph) + { + return; + } + double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + //< 清空数据 + QSharedPointer container(new QCPGraphDataContainer()); + + const QVector< QPair > &values = m_pTrendGraph->curve(graph->name()).values; + QVector< QPair >::const_iterator it = values.constBegin(); + double preValue = -1; + while (it != values.constEnd()) + { + //< LOGINFO("Update RealTime Trend Data-----------------[Time: %f, value: %f] ", it->first, it->second); + if(qAbs((it->second)-preValue) < _EPSILON_) + { + ++it; + continue; + } + container->add(QCPGraphData(it->first, it->second)); + preValue = it->second; + ++it; + } + + //< virtual point + if(container->data()->size() > 0) + { + container->add(QCPGraphData(limit, container->data()->last().value)); + } + else + { + container->add(QCPGraphData(limit, qSqrt(-1.))); + } + graph->setData(container); + } +} + +void CPlotWidget::updateHistoryCurveRecord(double lower, double upper) +{ + if(!ui->plot->graphCount()) + { + return; + } + std::vector * vecMpKey = new std::vector(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) + { + const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); + SMeasPointKey key; + std::string tmp = curve.tag.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(curve.type); + vecMpKey->push_back(key); + } + + if(!m_pHisDataManage->isTsdbExuting()) + { + if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) + { + emit sigQueryHistoryOriginalData(vecMpKey, lower, upper); + } + else + { + emit sigQueryHistoryPolymericData(vecMpKey, lower, upper, currentGroupByMinute(), kbd_dbms::CM_FIRST); + } + } + else + { + if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) + { + m_pHisDataManage->postTsdbCommandQueue(E_ORIGINAL, vecMpKey, lower, upper); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(E_POLYMERIC, vecMpKey, lower, upper, currentGroupByMinute(), kbd_dbms::CM_FIRST); + } + } +} + +void CPlotWidget::updateHisOriginalData(std::vector *vecMpKey, std::vector *> *vecResult, E_Data_Type type) +{ + std::vector< QSharedPointer > vecRange; + std::vector< QSharedPointer > vecContainer; + + updateHisData(vecResult, vecRange, vecContainer); + + if(E_REALTIME == type) + { + for(size_t nIndex(0); nIndex < vecContainer.size(); ++nIndex) + { + QCPGraphDataContainer::iterator it = vecContainer.at(nIndex)->begin(); + while(it != vecContainer.at(nIndex)->end()) + { + m_pTrendGraph->pushCurveRTDataValue(vecMpKey->at(nIndex).m_pszTagName, it->key, it->value); + ++it; + } + } + updateCurves(); + } + else if(E_HISTORY == type) + { + updateHistoryGraph(vecMpKey, vecContainer, vecRange); + } + + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(vecResult->end() != res) + { + delete (*res); + ++res; + } + vecResult->clear(); + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + + } + vecMpKey->clear(); + delete vecMpKey; +} + +void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, int nGroupByMinute) +{ + std::vector< QSharedPointer > vecRange; + std::vector< QSharedPointer > vecContainer; + + if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) + { + updateHisData(vecResult, vecRange, vecContainer, nGroupByMinute); + + updateHistoryGraph(vecMpKey, vecContainer, vecRange); + } + + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(vecResult->end() != res) + { + delete (*res); + ++res; + } + vecResult->clear(); + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; +} + +void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange) +{ + double lower = ui->plot->xAxis->range().lower; + double upper = ui->plot->xAxis->range().upper; + + for(int nIndex(0); nIndex < (int)(vecContainer.size()); ++nIndex) + { + if(nIndex > ui->plot->graphCount()-1) + { + continue; + } + QCPGraph * graph = ui->plot->graph(nIndex); + { + if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) + { + continue; + } + } + + int count = 0; //< accuml size + double offset = 0.; + double factor = 1.; + double accuml = 0.; + + + Curve curve = m_pTrendGraph->curve(graph->name()); + if(m_bHisAdaption) + { + factor = 100. / (vecRange.at(nIndex)->max - vecRange.at(nIndex)->min); + offset = -factor * vecRange.at(nIndex)->min; + m_pTrendGraph->setCurveGraphFactor(nIndex, factor); + m_pTrendGraph->setCurveGraphOffset(nIndex, offset); + } + else + { + factor = curve.factor; + offset = curve.offset; + } + + //< 此设计考虑自定义缩放【已实现,暂未开放】扩展 + double max = -DBL_MAX; + double min = DBL_MAX; + double maxTime = -DBL_MAX; + double minTime = DBL_MAX; + double average = qSqrt(-1.); + QCPGraphDataContainer::iterator iter = vecContainer.at(nIndex)->begin(); + while(iter != vecContainer.at(nIndex)->end()) + { + if(qIsNaN(iter->value)) + { + ++iter; + continue; + } + + //< 统计值 + if(iter->key >= lower && iter->key <= upper) + { + ++count; + if(iter->value > max) + { + max = iter->value; + maxTime = iter->key; + } + if(iter->value < min) + { + min = iter->value; + minTime = iter->key; + } + + accuml += iter->value; + } + + //< 缩放数据 + if(m_bHisAdaption) + { + iter->value *= factor; + iter->value += offset; + } + ++iter; + } + if(!vecContainer.at(nIndex)->isEmpty()) + { + if(count) + { + average = accuml / count; + } + } + m_pTrendGraph->setCurveHisDataValue(graph->name(), max, min, maxTime, minTime, average, accuml, *vecRange.at(nIndex)); + graph->data()->clear(); + graph->setData(vecContainer.at(nIndex)); + } + updateLengedValue(ui->plot->xAxis->pixelToCoord(ui->plot->symbolPos().x())); + rescaleYAxisRange(); + QList listSelectGraph = ui->plot->selectedGraphs(); + if(!listSelectGraph.isEmpty()) + { +// updateSelectGraph(listSelectGraph.first()->name()); + } + else + { + ui->plot->replot(); + } +} + +void CPlotWidget::updateSelectGraph(const QString &graphName) +{ + Curve curve = m_pTrendGraph->curve(graphName); + QCPGraph * graph = NULL; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(graphName == ui->plot->graph(nIndex)->name()) + { + graph = ui->plot->graph(nIndex); + } + } + if(graph == NULL || E_Trend_Invalid == m_type || E_Trend_RealTime == m_type || !curve.visible) + { + ui->plot->replot(); + return; + } + + QString device = curve.tag.section(".", 0, 1); + QString deviceGroup = CTrendInfoManage::instance()->queryDeviceGroup(device); + if(deviceGroup.isEmpty()) + { + ui->plot->replot(QCustomPlot::rpQueuedReplot); + return; + } + + QStringList tagList = CTrendInfoManage::instance()->queryTagListDevGroup(deviceGroup); + if(tagList.isEmpty()) + { + ui->plot->replot(QCustomPlot::rpQueuedReplot); + return; + } + + std::vector * vecMpKey = new std::vector(); + std::vector *> *vecResult = new std::vector *>(); + foreach (QString tagName, tagList) { + SMeasPointKey key; + std::string tmp = tagName.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(CTrendInfoManage::instance()->getTagType(tagName)); + vecMpKey->push_back(key); + + std::vector *vecEvtPoint = new std::vector(); + vecResult->push_back(vecEvtPoint); + } + + emit sigQueryHistoryEvent(vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, vecResult, curve.tag); + ui->plot->replot(QCustomPlot::rpQueuedReplot); +} + +void CPlotWidget::updatePhaseTracer(std::vector *vecMpKey, std::vector *> *vecResult, const QString &tag) +{ + ui->plot->clearItems(); + m_listTracer.clear(); + QCPGraph * graph = NULL; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(tag == ui->plot->graph(nIndex)->name()) + { + graph = ui->plot->graph(nIndex); + break; + } + } + if(NULL != graph) + { + QMultiMap< double, QStringList > map; + for(size_t tagIndex(0); tagIndex < vecResult->size(); tagIndex++) + { + std::vector *evetVector = vecResult->at(tagIndex); + std::vector::iterator iter = evetVector->begin(); + for(; iter != evetVector->end(); iter++) + { + QStringList list; + list.append(vecMpKey->at(tagIndex).m_pszTagName); + list.append(QString::number(iter->m_nAlmType)); + map.insert(iter->m_nTime, list); + } + } + + QPointF prePt(-1000., -1000.); + //< 1min 显示所有事件 + + bool bMinRange = ui->plot->xAxis->range().size() > 60; + QMultiMap< double, QStringList >::iterator rIter = map.begin(); + QMap hidePoint; + for(; rIter != map.end(); rIter++) + { + double key = rIter.key(); + if(bMinRange) + { + double curX = ui->plot->xAxis->coordToPixel(key); + if(qIsNaN(graph->value(key))) + { + continue; + } + double curY = ui->plot->yAxis->coordToPixel(graph->value(key)); + QPointF pt = QPointF(curX, curY) - prePt; + if(pt.manhattanLength() < 12) + { + hidePoint.insert(key, rIter.value()[0]); + continue; + } + prePt = QPointF(curX, curY); + } + QStringList value = rIter.value(); + QCPItemTracer *phaseTracer = new QCPItemTracer(ui->plot, key, QString(value[1]).toInt(), QPen(Qt::red), QBrush(Qt::red)); + phaseTracer->setGraphKey(key); + phaseTracer->setGraph(graph); + phaseTracer->addHidePoint(key, value[0]); + if(m_listTracer.length() > 0) + m_listTracer.last()->setHidePoint(hidePoint); + m_listTracer.append(phaseTracer); + connect(phaseTracer, &QCPItemTracer::itemTracerHoverd, m_pHisEventManage, &CHisEventManage::queryHisEvent, Qt::QueuedConnection); + hidePoint.clear(); + hidePoint.insert(key, value[0]); + } + } + + + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(res != vecResult->end()) + { + delete (*res); + ++res; + } + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; + + ui->plot->replot(); +} + +void CPlotWidget::updateGraphEvent(const QString &tag, const qint64 &time, QStringList contents) +{ + foreach (QCPItemTracer *phaseTracer, m_listTracer) + { + if(phaseTracer->timeStamp() == time && phaseTracer->graph()->name() == tag) + { + phaseTracer->setInfo(contents); + phaseTracer->showTips(); + } + } +} + +void CPlotWidget::updateTrendRange(const QDate &date) +{ + CTabButton * button = dynamic_cast(sender()); + if(button && button != ui->realTime) + { + button->setChecked(true); + ui->plot->xAxis->blockSignals(true); + updateTrendShowMode(m_TrendTypeButton->id(button)); + const QCPRange &range = ui->plot->xAxis->range(); + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime(date.addDays(1))); + ui->plot->xAxis->setRange(upper, range.size(), Qt::AlignRight); + ui->plot->xAxis->blockSignals(false); + updateCurves(); + } +} + +void CPlotWidget::updateAxisFormat(bool updateXAxisRange) +{ + QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + switch (m_type) + { + case E_Trend_RealTime: + { + //< 10 min + ui->prePage->setEnabled(false); + ui->nextPage->setEnabled(false); + ui->date->setEnabled(false); + ui->plot->setInteractions(QCP::iRangeZoom | QCP::iSelectPlottables); + ui->plot->axisRect()->setScaleRight(true); + ticker->setDateTimeFormat("hh:mm:ss"); + ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); + if(Q_NULLPTR != m_pTimer) + { + m_pTimer->start(); + } + if(m_isWindowMode) + { + ticker->setTickCount(11); + setLegendCurveTransformColumnVisible(true); + } + else + { + ticker->setTickCount(6); + } + + m_pLengedModel->setMode(CCurveLegendModel::LENGED_RT_MODE); + ui->plot->yAxis->setTicker(m_ptrPlotTricker); + ui->plot->yAxis2->setTicker(m_ptrPlotTricker); + } + break; + case E_Trend_His_Minute: + { + if(m_isWindowMode) + { + ticker->setTickCount(12); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + ui->date->setFixedWidth(120); + ui->date->setDisplayFormat("yyyy-MM-dd hh:mm"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Minute); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Hour: + { + if(m_isWindowMode) + { + ticker->setTickCount(11); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + } + break; + case E_Trend_His_Day: + { + if(m_isWindowMode) + { + ticker->setTickCount(12); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + ui->date->setFixedWidth(85); + ui->date->setDisplayFormat("yyyy-MM-dd"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Day); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Week: + { + if(m_isWindowMode) + { + ticker->setTickCount(8); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("MM-dd hh:mm ddd"); + ui->date->setFixedWidth(85); + ui->date->setDisplayFormat("yyyy-MM-dd"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Week); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Month: + { + if(m_isWindowMode) + { + ticker->setTickCount(11); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("MM-dd hh"); + ui->date->setFixedWidth(65); + ui->date->setDisplayFormat("yyyy-MM"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Month); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Quarter: + { + if(m_isWindowMode) + { + ticker->setTickCount(10); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("MM-dd hh"); + ui->date->setFixedWidth(65); + ui->date->setDisplayFormat("yyyy-MM"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Quarter); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Year: + { + if(m_isWindowMode) + { + ticker->setTickCount(13); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("yyyy-MM-dd"); + ui->date->setFixedWidth(50); + ui->date->setDisplayFormat("yyyy"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Year); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + default: + break; + } +} + +QPair CPlotWidget::getFatureDataTime(E_Trend_Type type, QDateTime curTime) +{ + QDateTime low; + QDateTime up; + QPair range; + if(curTime == QDateTime()) + { + low = QDateTime::currentDateTime(); + up = QDateTime::currentDateTime(); + } + else + { + low = curTime; + up = curTime; + } + + switch (type) { + case E_Trend_His_Day: + { + break; + } + case E_Trend_His_Minute: + { + int minute = up.time().minute(); + up.setTime(QTime(up.time().hour(), (minute/10)*10+9, 59, 999)); + low.setTime(QTime(low.time().hour(), (minute/10)*10)); + range.first = low.toMSecsSinceEpoch(); + range.second = up.toMSecsSinceEpoch(); + return range; + } + case E_Trend_His_Week: + { + up = up.addDays(7-low.date().dayOfWeek()); + low = low.addDays(-low.date().dayOfWeek()+1); + break; + } + case E_Trend_His_Month: + { + up.setDate(QDate(low.date().year(), low.date().month(), low.date().daysInMonth())); + low.setDate(QDate(low.date().year(), low.date().month(), 1)); + break; + } + case E_Trend_His_Quarter: + { + QString month = QString::number(low.date().month()); + if(QString("1,2,3").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 3, 31)); + low.setDate(QDate(low.date().year(), 1, 1)); + } + else if(QString("4,5,6").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 6, 30)); + low.setDate(QDate(low.date().year(), 4, 1)); + } + else if(QString("7,8,9").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 9, 30)); + low.setDate(QDate(low.date().year(), 7, 1)); + } + else if(QString("10,11,12").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 12, 31)); + low.setDate(QDate(low.date().year(), 10, 1)); + } + break; + } + case E_Trend_His_Year: + { + up.setDate(QDate(low.date().year(), 12, 31)); + low.setDate(QDate(low.date().year(), 1, 1)); + break; + } + default: + break; + } + low.setTime(QTime(0,0,0)); + up.setTime(QTime(23,59,59)); + range.first = low.toMSecsSinceEpoch(); + range.second = up.toMSecsSinceEpoch(); + return range; +} + +void CPlotWidget::updateAdaptState(bool isAdapt) +{ + m_bHisAdaption = isAdapt; + if(m_isWindowMode) + { + setLegendCurveTransformColumnVisible(isAdapt); + } + updateCurves(); + + updateYAxisTicker(); +} + +void CPlotWidget::addCollect() +{ + CEditCollectWidget * pCollectWidget = new CEditCollectWidget(this); + pCollectWidget->show(); + QPoint pt = ui->collectCurve->mapToGlobal(QPoint()); + pt.setX(pt.x() - pCollectWidget->width() + ui->collectCurve->width()); + pt.setY(pt.y() + ui->collectCurve->height() ); + pCollectWidget->move(pt); + connect(pCollectWidget, &CEditCollectWidget::acceptedInput, this, [=](){ + if(!pCollectWidget->text().isEmpty()) + { + emit collectGraph(pCollectWidget->text(), *m_pTrendGraph); + } + else + { + QMessageBox::warning(this, tr("错误"), tr("趋势名称不允许为空!"), + QMessageBox::Ok); + } + pCollectWidget->close(); + delete pCollectWidget; + }); +} + +void CPlotWidget::print() +{ + QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), "/home.jpg", tr("(*.jpg)"), + Q_NULLPTR, QFileDialog::DontUseNativeDialog); + + if(strFileName.isEmpty()) + { + return; + } + ui->plot->legend->setVisible(true); + m_trendTitle->setVisible(true); + ui->plot->replot(QCustomPlot::rpImmediateRefresh); + ui->plot->saveJpg(strFileName, 1600, 800); + ui->plot->legend->setVisible(false); + m_trendTitle->setVisible(false); +} + +void CPlotWidget::prePage() +{ + QDateTime dateTime = ui->date->dateTime(); + switch(m_type) + { + case E_Trend_His_Minute: + { + ui->date->setDateTime(dateTime.addSecs(-600)); + break; + } + case E_Trend_His_Hour: + case E_Trend_His_Day: + { + ui->date->setDateTime(dateTime.addDays(-1)); + break; + } + case E_Trend_His_Week: + { + ui->date->setDateTime(dateTime.addDays(-7)); + break; + } + case E_Trend_His_Month: + { + ui->date->setDateTime(dateTime.addMonths(-1)); + break; + } + case E_Trend_His_Quarter: + { + ui->date->setDateTime(dateTime.addMonths(-3)); + break; + } + case E_Trend_His_Year: + { + ui->date->setDateTime(dateTime.addYears(-1)); + break; + } + default: + return; + } + + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + ui->plot->xAxis->setRange(range.first, range.second); + updateCurves(); +} + +void CPlotWidget::nextPage() +{ + QDateTime dateTime = ui->date->dateTime(); + switch(m_type) + { + case E_Trend_His_Minute: + { + ui->date->setDateTime(dateTime.addSecs(600)); + break; + } + case E_Trend_His_Hour: + case E_Trend_His_Day: + { + ui->date->setDateTime(dateTime.addDays(1)); + break; + } + case E_Trend_His_Week: + { + ui->date->setDateTime(dateTime.addDays(7)); + break; + } + case E_Trend_His_Month: + { + ui->date->setDateTime(dateTime.addMonths(1)); + break; + } + case E_Trend_His_Quarter: + { + ui->date->setDateTime(dateTime.addMonths(3)); + break; + } + case E_Trend_His_Year: + { + ui->date->setDateTime(dateTime.addYears(1)); + break; + } + default: + return; + } + + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + ui->plot->xAxis->setRange(range.first, range.second); + updateCurves(); +} + +void CPlotWidget::graphVisibleChanged() +{ + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + Curve curve = m_pTrendGraph->curve(graph->name()); + graph->setVisible(curve.visible); + if(!curve.visible) + { + graph->removeFromLegend(ui->plot->legend); + } + else + { + graph->addToLegend(ui->plot->legend); + } + + if(graph->selected() && !curve.visible) + { + ui->plot->clearItems(); + m_listTracer.clear(); + } + } + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::graphPropertyChanged() +{ + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + Curve curve = m_pTrendGraph->curve(graph->name()); + graph->setPen(curve.color); + updateCurveSelectionColor(graph); + } + ui->lengedView->setCurrentIndex(ui->lengedView->model()->index(ui->lengedView->currentIndex().row(), 0)); + updateCurves(); +} + +void CPlotWidget::updateLengedValue(const double &dateTime) +{ + QList listVal; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + double graphValue = graph->value(dateTime); + Curve curve = m_pTrendGraph->curve(graph->name()); + double value = graphValue; + + if(m_bHisAdaption) + { + value = (graphValue - curve.graphOffset) / curve.graphFactor; + } + listVal.append(value); + } + m_pLengedModel->setTrendCurrentValues(listVal); +} + +void CPlotWidget::graphSelectionChanged(bool select) +{ + ui->plot->clearItems(); + m_listTracer.clear(); + ui->lengedView->selectionModel()->clear(); + updateYAxisTicker(); + + QCPGraph * graph = dynamic_cast(sender()); + if(Q_NULLPTR != graph && select) + { + ui->lengedView->selectRow(m_pTrendGraph->index(graph->name())); + updateSelectGraph(graph->name()); + } + ui->plot->replot(QCustomPlot::rpQueuedRefresh); +} + +void CPlotWidget::updateGraphSelection() +{ + ui->plot->blockSignals(true); + ui->plot->clearItems(); + ui->plot->deselectAll(); + ui->plot->blockSignals(false); + int index = ui->lengedView->currentIndex().row(); + QCPGraph * graph = ui->plot->graph(index); + if(graph) + { + QCPDataSelection selection(QCPDataRange(0, 1)); + graph->setSelection(selection); + } + ui->plot->replot(); +} + +void CPlotWidget::updateYAxisTicker() +{ + QList graphs = ui->plot->selectedGraphs(); + if(graphs.isEmpty()) + { + if(m_bHisAdaption) + { + QSharedPointer ticker(new QCPAxisTickerText); + for(int nIndex(0); nIndex <= 100; nIndex+= 20) + { + ticker->addTick(nIndex, " "); + } + ui->plot->yAxis->setTicker(ticker); + ui->plot->yAxis2->setTicker(ticker); + ui->plot->replot(QCustomPlot::rpQueuedRefresh); + return; + } + } + else + { + if(m_bHisAdaption) + { + QSharedPointer ticker(new QCPAxisTickerText); + Curve curve = m_pTrendGraph->curve(graphs.first()->name()); + QString strUnit = QString(); + if(!curve.unit.isEmpty()) + { + strUnit = QString("\n%1").arg(curve.unit); + } + double min = curve.hisPlotRange.min; + double max = curve.hisPlotRange.max; + double range = max - min; + min -= range * ui->scaleSlider->value() / 5.; + max += range * ui->scaleSlider->value() / 5.; + QList ticks = regulate(min, max, 11); + if(!ticks.isEmpty()) + { + double range = curve.hisPlotRange.max - curve.hisPlotRange.min; + for(int nIndex(0); nIndex < ticks.size(); nIndex += 2) + { + ticker->addTick((ticks.at(nIndex) - curve.hisPlotRange.min) / range * 100, QString::number((ticks.at(nIndex)), 'f', 1) + strUnit); + } + ui->plot->yAxis->setTicker(ticker); + ui->plot->yAxis2->setTicker(ticker); + } + ui->plot->replot(QCustomPlot::rpQueuedRefresh); + return; + } + } + ui->plot->yAxis->setTicker(m_ptrPlotTricker); + ui->plot->yAxis2->setTicker(m_ptrPlotTricker); + ui->plot->replot(QCustomPlot::rpQueuedRefresh); +} + +EnMeasPiontType CPlotWidget::getMeasType(const QString &type) +{ + if ("analog" == type) + { + return MPT_AI; //< 模拟量 + } + else if ("digital" == type) + { + return MPT_DI; //< 数字量 + } + else if ("mix" == type) + { + return MPT_MIX; //< 混合量 + } + else if ("accuml" == type) + { + return MPT_ACC; //< 累计(电度)量 + } + return MPT_AI; //< INVALID +} + +void CPlotWidget::setLegendCurveTransformColumnVisible(const bool &visible) +{ + Q_UNUSED(visible) + ui->lengedView->setColumnHidden(CCurveLegendModel::FACTOR, true); + ui->lengedView->setColumnHidden(CCurveLegendModel::OFFSET, true); +} + +QList CPlotWidget::regulate(double min, double max, int tickCount) +{ + QList ticks; + if (tickCount < 1 || max < min) + { + return ticks; + } + + double delta = max - min; + if (delta < 1.0) + { + max += (1.0 - delta) / 2.0; + min -= (1.0 - delta) / 2.0; + } + delta = max - min; + + int exp = (int)(log(delta) / log(10.0)) - 2; + double multiplier = pow(10, exp); + const double solutions[] = { 1, 2, 2.5, 5, 10, 20, 25, 50, 100, 200, 250, 500 }; + + int nIndex = 0; + for (; nIndex < (int)(sizeof(solutions) / sizeof(double)); ++nIndex) + { + double multiCal = multiplier * solutions[nIndex]; + if (((int)(delta / multiCal) + 1) <= tickCount) + { + break; + } + } + + double interval = multiplier * solutions[nIndex]; + + double startPoint = ((int)ceil(min / interval) - 1) * interval; + for (int axisIndex = 0; startPoint + interval*axisIndex <= max; axisIndex++) + { + ticks.append(startPoint + interval*axisIndex); + } + return ticks; +} + +void CPlotWidget::rescaleYAxisRange() +{ + ui->plot->yAxis->setRange(-1, 1); + ui->plot->yAxis->rescale(true); + ui->plot->yAxis->scaleRange(ui->scaleSlider->value() / 5. + 1.20); + if(m_bHisAdaption) + { + updateYAxisTicker(); + } + else + { + ui->plot->replot(); + } +} + +template +void CPlotWidget::updateHisData(std::vector*> *vecResult, std::vector > &vecRange, std::vector< QSharedPointer > &vecContainer, int nGroupByMinute) +{ + int nMaxIntervalSecs = (SAMPLE_CYC_MIN + nGroupByMinute) * 60 * 1000; + typename std::vector *>::const_iterator it = vecResult->begin(); + while(it != vecResult->end()) + { + QSharedPointer range(new Range()); + QSharedPointer container(new QCPGraphDataContainer()); + vecRange.push_back(range); + vecContainer.push_back(container); + + //< Valid Check + std::vector<_Tp> * vecPoint = *it; + if(vecPoint->empty()) + { + ++it; + continue; + } + + //< Graph Bound + _Tp left; + left.m_nTime = ui->plot->xAxis->range().lower; + typename std::vector<_Tp>::const_iterator varHisLeft = std::upper_bound((*vecPoint).begin(), (*vecPoint).end(), left, compareVarPoint<_Tp>); + if(varHisLeft != (*vecPoint).begin() && varHisLeft != (*vecPoint).end()) + { + --varHisLeft; + } + + _Tp right; + right.m_nTime = ui->plot->xAxis->range().upper; + typename std::vector<_Tp>::const_iterator varHisRight = std::lower_bound((*vecPoint).begin(), (*vecPoint).end(), right, compareVarPoint<_Tp>); + if(varHisRight == (*vecPoint).end()) + { + varHisRight = (*vecPoint).end() - 1; + } + ++varHisRight; + + //< Prepare Work(used: record Interval) + qint64 lastTimeStamp = -1; + + //< Handle Data + typename std::vector<_Tp>::const_iterator pt = varHisLeft; + while(pt != varHisRight) + { + double value = qSqrt(-1.); + if (typeid(boost::int32_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + else if (typeid(boost::float64_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + + if(value > range->max) + { + range->max = value; + } + if(value < range->min) + { + range->min = value; + } + + qint64 timeStamp = pt->m_nTime; + if(lastTimeStamp > 0 && lastTimeStamp + nMaxIntervalSecs < timeStamp) + { + container->add(QCPGraphData(lastTimeStamp, qSqrt(-1.))); + } + container->add(QCPGraphData(timeStamp, value)); + lastTimeStamp = timeStamp; + ++pt; + } + ++it; + } +} + +template +bool CPlotWidget::checkStatus(const _Tp &var, const int &nInvalid) +{ + Q_UNUSED(var); + Q_UNUSED(nInvalid); + return true; +} + +template +bool CPlotWidget::checkStatus(const SVarHisSamplePoint &var, const int &nInvalid) +{ + return nInvalid == (var.m_nStatus & nInvalid); +} + +void CPlotWidget::slotDateTimeChanged(const QDateTime &dateTime) +{ + QPair range = getFatureDataTime(m_type, dateTime); + ui->plot->xAxis->setRange(range.first, range.second); + + updateCurves(); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.h b/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.h index 5661929a..e5af78c2 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.h @@ -1,233 +1,233 @@ -#ifndef CPLOTWIDGET_H -#define CPLOTWIDGET_H - -#include -#include "CTrendGraph.h" -#include "CHisDataManage.h" -#include "plot/qcustomplot.h" -#include "dbms/tsdb_api/TsdbApi.h" -#include "dbms/tsdb_api/CTsdbConn.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "dbms/db_his_query_api/DbHisQueryApi.h" - -namespace Ui { -class CPlotWidget; -} - -class QTimer; -class QCustomPlot; -class QCPItemText; -class QCPItemTracer; -class QAbstractButton; -class CHisDataManage; -class CHisEventManage; -class CCurveLegendModel; -class CRealTimeDataCollect; - -enum E_Trend_Type -{ - E_Trend_Invalid = 0, - E_Trend_RealTime = 1, - E_Trend_His_Minute = 2, - E_Trend_His_Hour = 3, - E_Trend_His_Day = 4, - E_Trend_His_Week = 5, - E_Trend_His_Month = 6, - E_Trend_His_Quarter = 7, - E_Trend_His_Year = 8 -}; - -class CPlotWidget : public QWidget -{ - Q_OBJECT - Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) - Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) - Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) - Q_PROPERTY(QColor plotZeroLineColor READ plotZeroLineColor WRITE setPlotZeroLineColor) - Q_PROPERTY(QColor plotTickPen READ plotTickPen WRITE setPlotTickPen) - Q_PROPERTY(QPixmap plotBackImage READ plotBackImage WRITE setPlotBackImage) - -public: - explicit CPlotWidget(QWidget *parent = 0); - ~CPlotWidget(); - - void initialize(); - - void setTitle(const QString &title); - - void setTitleVisible(bool visible); - - void setTickCount(const int &count); - - void insertTag(const QString &tag); - - void insertTag(const QStringList &listTag); - - void removeTag(const QString &tag); - - void setDisplayTime(const int &trendType, const double &dateTime); - - void setTagVisible(const QString &tag, const bool &visible); - - void setClearVisible(bool visible); - - void insertCurve(Curve curve); - - void clear(bool clearTitle = false); - - void setWindowMode(const bool &isWindowMode); - - void setColorList(const QStringList &listColor); - - QColor plotBackgroundColor(); - void setPlotBackgroundColor(const QColor &color); - - QPixmap plotBackImage(); - void setPlotBackImage(const QPixmap &pm); - - QColor plotTickColor(); - void setPlotTickColor(const QColor &color); - - QColor plotGridColor(); - void setPlotGridColor(const QColor &color); - - QColor plotZeroLineColor(); - void setPlotZeroLineColor(const QColor &color); - - QColor plotTickPen(); - void setPlotTickPen(const QColor &color); - -signals: - void clearCurve(); - void queryHisEvent(const QString &tag, const int &type, const qint64 &time); - void collectGraph(const QString &title, const CTrendGraph &graph); - void updateTagCheckState(const QString &tag, const bool &outOfRange); - void releaseHisDataThread(); - void releaseHisEventThread(); - - void sigQueryHistoryOriginalData(std::vector *vecMpKey, - double lower, double upper, - E_Data_Type type = E_HISTORY); - - void sigQueryHistoryPolymericData(std::vector *vecMpKey, - double lower, double upper, int nGroupByMinute, kbd_dbms::EnComputeMethod method); - - void sigQueryHistoryEvent(std::vector *vecMpKey, - double lower, double upper, - std::vector *> *vecResult, - const QString &tag); - -protected: - void resizeEvent(QResizeEvent *event); - void updateLengedColumnWidth(); - void updateCurveSelectionColor(QCPGraph * graph); - -private slots: - void realTimeElapsed(); - - void recvRealTimeTrendData(const QString &tagName, QVariant value); - - void plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange); - - void updateTrendShowMode(int nIndex, bool updateXAxisRange = true); - - void updateCurves(); - - void updateRealTimeCurveRecord(); - - void updateHistoryCurveRecord(double lower, double upper); - - void updateHisOriginalData(std::vector *vecMpKey, - std::vector *> *vecResult, - E_Data_Type type = E_HISTORY); - - void updateHisPolymericData(std::vector *vecMpKey, - std::vector *> *vecResult, - int nGroupByMinute); - - void updateHistoryGraph(std::vector *vecMpKey, - std::vector< QSharedPointer > &vecContainer, - std::vector< QSharedPointer > &vecRange); - - void updateSelectGraph(const QString &graphName); - - void updatePhaseTracer(std::vector *vecMpKey, - std::vector *> *vecResult, - const QString &tag); - void updateGraphEvent(const QString &tag, const qint64 &time, QStringList contents); - - void updateTrendRange(const QDate &date); - void updateAxisFormat(bool updateXAxisRange); - QPair getFatureDataTime(E_Trend_Type type, QDateTime curTime = QDateTime()); - void updateAdaptState(bool isAdapt); - void addCollect(); - void print(); - void prePage(); - void nextPage(); - - void graphVisibleChanged(); - void graphPropertyChanged(); - void updateLengedValue(const double &dateTime); - void graphSelectionChanged(bool select); - void updateGraphSelection(); - void updateYAxisTicker(); - - void slotDateTimeChanged(const QDateTime &dateTime); - -private: - kbd_dbms::EnMeasPiontType getMeasType(const QString &type); - - E_Trend_Type getRangeType(const QCPRange &range); - - void updateGraphTitle(int nIndex); - - int currentGroupByMinute(); - - void setLegendCurveTransformColumnVisible(const bool &visible); - - QList regulate(double min, double max, int tickCount); - - void rescaleYAxisRange(); - - template - void updateHisData(std::vector*> *vecResult, - std::vector< QSharedPointer > &vecRange, - std::vector< QSharedPointer > &vecContainer, - int nGroupByMinute = 0); - - template - bool checkStatus(const _Tp &var, const int &nInvalid); - - template - bool checkStatus(const kbd_dbms::SVarHisSamplePoint &var, const int &nInvalid); - -private: - Ui::CPlotWidget *ui; - E_Trend_Type m_type; - bool m_bHisAdaption; - QButtonGroup * m_TrendTypeButton; - CCurveLegendModel * m_pLengedModel; - QTimer * m_pTimer; - CTrendGraph * m_pTrendGraph; - QCPItemText * m_trendTitle; - double m_rtRange; - kbd_service::CDpcdaForApp * m_pDpcdaForApp; - CRealTimeDataCollect * m_rtDataCollect; - QSharedPointer m_ptrPlotTricker; - QThread * m_pHisDataThread; - CHisDataManage * m_pHisDataManage; - QThread * m_pHisEventThread; - CHisEventManage * m_pHisEventManage; - bool m_isWindowMode; - - QPixmap m_plotBackImage; - QColor m_plotBackgroundColor; - QColor m_plotTickColor; - QColor m_plotGridColor; - QColor m_plotZeroLineColor; - QColor m_plotTickPen; - QList m_listTracer; - QList m_listColor; -}; - -#endif // CPLOTWIDGET_H +#ifndef CPLOTWIDGET_H +#define CPLOTWIDGET_H + +#include +#include "CTrendGraph.h" +#include "CHisDataManage.h" +#include "plot/qcustomplot.h" +#include "dbms/tsdb_api/TsdbApi.h" +#include "dbms/tsdb_api/CTsdbConn.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "dbms/db_his_query_api/DbHisQueryApi.h" + +namespace Ui { +class CPlotWidget; +} + +class QTimer; +class QCustomPlot; +class QCPItemText; +class QCPItemTracer; +class QAbstractButton; +class CHisDataManage; +class CHisEventManage; +class CCurveLegendModel; +class CRealTimeDataCollect; + +enum E_Trend_Type +{ + E_Trend_Invalid = 0, + E_Trend_RealTime = 1, + E_Trend_His_Minute = 2, + E_Trend_His_Hour = 3, + E_Trend_His_Day = 4, + E_Trend_His_Week = 5, + E_Trend_His_Month = 6, + E_Trend_His_Quarter = 7, + E_Trend_His_Year = 8 +}; + +class CPlotWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) + Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) + Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) + Q_PROPERTY(QColor plotZeroLineColor READ plotZeroLineColor WRITE setPlotZeroLineColor) + Q_PROPERTY(QColor plotTickPen READ plotTickPen WRITE setPlotTickPen) + Q_PROPERTY(QPixmap plotBackImage READ plotBackImage WRITE setPlotBackImage) + +public: + explicit CPlotWidget(QWidget *parent = 0); + ~CPlotWidget(); + + void initialize(); + + void setTitle(const QString &title); + + void setTitleVisible(bool visible); + + void setTickCount(const int &count); + + void insertTag(const QString &tag); + + void insertTag(const QStringList &listTag); + + void removeTag(const QString &tag); + + void setDisplayTime(const int &trendType, const double &dateTime); + + void setTagVisible(const QString &tag, const bool &visible); + + void setClearVisible(bool visible); + + void insertCurve(Curve curve); + + void clear(bool clearTitle = false); + + void setWindowMode(const bool &isWindowMode); + + void setColorList(const QStringList &listColor); + + QColor plotBackgroundColor(); + void setPlotBackgroundColor(const QColor &color); + + QPixmap plotBackImage(); + void setPlotBackImage(const QPixmap &pm); + + QColor plotTickColor(); + void setPlotTickColor(const QColor &color); + + QColor plotGridColor(); + void setPlotGridColor(const QColor &color); + + QColor plotZeroLineColor(); + void setPlotZeroLineColor(const QColor &color); + + QColor plotTickPen(); + void setPlotTickPen(const QColor &color); + +signals: + void clearCurve(); + void queryHisEvent(const QString &tag, const int &type, const qint64 &time); + void collectGraph(const QString &title, const CTrendGraph &graph); + void updateTagCheckState(const QString &tag, const bool &outOfRange); + void releaseHisDataThread(); + void releaseHisEventThread(); + + void sigQueryHistoryOriginalData(std::vector *vecMpKey, + double lower, double upper, + E_Data_Type type = E_HISTORY); + + void sigQueryHistoryPolymericData(std::vector *vecMpKey, + double lower, double upper, int nGroupByMinute, kbd_dbms::EnComputeMethod method); + + void sigQueryHistoryEvent(std::vector *vecMpKey, + double lower, double upper, + std::vector *> *vecResult, + const QString &tag); + +protected: + void resizeEvent(QResizeEvent *event); + void updateLengedColumnWidth(); + void updateCurveSelectionColor(QCPGraph * graph); + +private slots: + void realTimeElapsed(); + + void recvRealTimeTrendData(const QString &tagName, QVariant value); + + void plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + + void updateTrendShowMode(int nIndex, bool updateXAxisRange = true); + + void updateCurves(); + + void updateRealTimeCurveRecord(); + + void updateHistoryCurveRecord(double lower, double upper); + + void updateHisOriginalData(std::vector *vecMpKey, + std::vector *> *vecResult, + E_Data_Type type = E_HISTORY); + + void updateHisPolymericData(std::vector *vecMpKey, + std::vector *> *vecResult, + int nGroupByMinute); + + void updateHistoryGraph(std::vector *vecMpKey, + std::vector< QSharedPointer > &vecContainer, + std::vector< QSharedPointer > &vecRange); + + void updateSelectGraph(const QString &graphName); + + void updatePhaseTracer(std::vector *vecMpKey, + std::vector *> *vecResult, + const QString &tag); + void updateGraphEvent(const QString &tag, const qint64 &time, QStringList contents); + + void updateTrendRange(const QDate &date); + void updateAxisFormat(bool updateXAxisRange); + QPair getFatureDataTime(E_Trend_Type type, QDateTime curTime = QDateTime()); + void updateAdaptState(bool isAdapt); + void addCollect(); + void print(); + void prePage(); + void nextPage(); + + void graphVisibleChanged(); + void graphPropertyChanged(); + void updateLengedValue(const double &dateTime); + void graphSelectionChanged(bool select); + void updateGraphSelection(); + void updateYAxisTicker(); + + void slotDateTimeChanged(const QDateTime &dateTime); + +private: + kbd_dbms::EnMeasPiontType getMeasType(const QString &type); + + E_Trend_Type getRangeType(const QCPRange &range); + + void updateGraphTitle(int nIndex); + + int currentGroupByMinute(); + + void setLegendCurveTransformColumnVisible(const bool &visible); + + QList regulate(double min, double max, int tickCount); + + void rescaleYAxisRange(); + + template + void updateHisData(std::vector*> *vecResult, + std::vector< QSharedPointer > &vecRange, + std::vector< QSharedPointer > &vecContainer, + int nGroupByMinute = 0); + + template + bool checkStatus(const _Tp &var, const int &nInvalid); + + template + bool checkStatus(const kbd_dbms::SVarHisSamplePoint &var, const int &nInvalid); + +private: + Ui::CPlotWidget *ui; + E_Trend_Type m_type; + bool m_bHisAdaption; + QButtonGroup * m_TrendTypeButton; + CCurveLegendModel * m_pLengedModel; + QTimer * m_pTimer; + CTrendGraph * m_pTrendGraph; + QCPItemText * m_trendTitle; + double m_rtRange; + kbd_service::CDpcdaForApp * m_pDpcdaForApp; + CRealTimeDataCollect * m_rtDataCollect; + QSharedPointer m_ptrPlotTricker; + QThread * m_pHisDataThread; + CHisDataManage * m_pHisDataManage; + QThread * m_pHisEventThread; + CHisEventManage * m_pHisEventManage; + bool m_isWindowMode; + + QPixmap m_plotBackImage; + QColor m_plotBackgroundColor; + QColor m_plotTickColor; + QColor m_plotGridColor; + QColor m_plotZeroLineColor; + QColor m_plotTickPen; + QList m_listTracer; + QList m_listColor; +}; + +#endif // CPLOTWIDGET_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.ui b/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.ui index dff3f5f6..430b468c 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.ui +++ b/product/src/gui/plugin/ISCSTrendCurves/CPlotWidget.ui @@ -1,620 +1,620 @@ - - - CPlotWidget - - - - 0 - 0 - 937 - 558 - - - - Form - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - - false - - - - 480 - 240 - - - - - - - - - 20 - 0 - - - - - 20 - 16777215 - - - - - - - Qt::Vertical - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 18 - - - 0 - - - 3 - - - 0 - - - - - 0 - - - 0 - - - 5 - - - 5 - - - 5 - - - 0 - - - - - - 52 - 30 - - - - - 52 - 16777215 - - - - - - - - - - - - 52 - 30 - - - - - 52 - 16777215 - - - - - - - - - - - - 52 - 30 - - - - - 52 - 16777215 - - - - 实时 - - - - - - - - 52 - 30 - - - - - 52 - 16777215 - - - - - - - - - - - - 52 - 30 - - - - - 52 - 16777215 - - - - - - - - - - - - 52 - 30 - - - - - 52 - 16777215 - - - - - - - - - - - - 52 - 30 - - - - - 52 - 16777215 - - - - - - - - - - - - - 收藏 - - - - - - - - 72 - 26 - - - - - 16777215 - 26 - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 3 - - - 0 - - - 3 - - - 0 - - - 2 - - - 3 - - - - - - 0 - 0 - - - - - 42 - 24 - - - - 对比 - - - true - - - - - - - - - - 导出 - - - - - - - Qt::Horizontal - - - - 304 - 20 - - - - - - - - 打印 - - - - - - - - - - - 0 - 35 - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 359 - 20 - - - - - - - - Qt::Horizontal - - - - 359 - 20 - - - - - - - - - Microsoft YaHei - 20 - 50 - false - - - - - - - 趋势图 - - - - - - - - - - - - - 0 - 32 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 2 - - - 0 - - - 2 - - - 6 - - - 0 - - - - - 下一页 - - - - - - - Qt::Horizontal - - - - 50 - 20 - - - - - - - - false - - - 清空 - - - - - - - 上一页 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 23 - 59 - 59 - 2036 - 12 - 31 - - - - - 0 - 0 - 0 - 1970 - 1 - 1 - - - - yyyy/MM/dd HH:mm - - - - - - - - 58 - 0 - - - - - 58 - 16777215 - - - - border:none; -background:transparent; - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - - - 16777215 - 150 - - - - false - - - false - - - - - - - - QCustomPlot - QWidget -
./plot/qcustomplot.h
- 1 -
- - CTabButton - QPushButton -
./widgets/CTabButton.h
-
- - CCurveLegendView - QTableView -
CCurveLegendView.h
-
-
- - -
+ + + CPlotWidget + + + + 0 + 0 + 937 + 558 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + + + false + + + + 480 + 240 + + + + + + + + + 20 + 0 + + + + + 20 + 16777215 + + + + + + + Qt::Vertical + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 18 + + + 0 + + + 3 + + + 0 + + + + + 0 + + + 0 + + + 5 + + + 5 + + + 5 + + + 0 + + + + + + 52 + 30 + + + + + 52 + 16777215 + + + + + + + + + + + + 52 + 30 + + + + + 52 + 16777215 + + + + + + + + + + + + 52 + 30 + + + + + 52 + 16777215 + + + + 实时 + + + + + + + + 52 + 30 + + + + + 52 + 16777215 + + + + + + + + + + + + 52 + 30 + + + + + 52 + 16777215 + + + + + + + + + + + + 52 + 30 + + + + + 52 + 16777215 + + + + + + + + + + + + 52 + 30 + + + + + 52 + 16777215 + + + + + + + + + + + + + 收藏 + + + + + + + + 72 + 26 + + + + + 16777215 + 26 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 3 + + + 0 + + + 3 + + + 0 + + + 2 + + + 3 + + + + + + 0 + 0 + + + + + 42 + 24 + + + + 对比 + + + true + + + + + + + + + + 导出 + + + + + + + Qt::Horizontal + + + + 304 + 20 + + + + + + + + 打印 + + + + + + + + + + + 0 + 35 + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 359 + 20 + + + + + + + + Qt::Horizontal + + + + 359 + 20 + + + + + + + + + Microsoft YaHei + 20 + 50 + false + + + + + + + 趋势图 + + + + + + + + + + + + + 0 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 2 + + + 0 + + + 2 + + + 6 + + + 0 + + + + + 下一页 + + + + + + + Qt::Horizontal + + + + 50 + 20 + + + + + + + + false + + + 清空 + + + + + + + 上一页 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 23 + 59 + 59 + 2036 + 12 + 31 + + + + + 0 + 0 + 0 + 1970 + 1 + 1 + + + + yyyy/MM/dd HH:mm + + + + + + + + 58 + 0 + + + + + 58 + 16777215 + + + + border:none; +background:transparent; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + 16777215 + 150 + + + + false + + + false + + + + + + + + QCustomPlot + QWidget +
./plot/qcustomplot.h
+ 1 +
+ + CTabButton + QPushButton +
./widgets/CTabButton.h
+
+ + CCurveLegendView + QTableView +
CCurveLegendView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/ISCSTrendCurves/CRealTimeDataCollect.cpp b/product/src/gui/plugin/ISCSTrendCurves/CRealTimeDataCollect.cpp index 13efd81f..b8a90a08 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CRealTimeDataCollect.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CRealTimeDataCollect.cpp @@ -1,98 +1,98 @@ -#include "CRealTimeDataCollect.h" -#include "MessageChannel.h" -#include "DataProcMessage.pb.h" -#include "pub_logger_api/logger.h" -#include "CTrendInfoManage.h" -#include - -using namespace kbd_net; -using namespace kbd_public; -using namespace kbd_idlfile; - -CRealTimeDataCollect::CRealTimeDataCollect(QObject *parent) - : QThread(parent) -{ - -} - -CRealTimeDataCollect::~CRealTimeDataCollect() -{ - -} - -void CRealTimeDataCollect::run() -{ - kbd_public::CSysInfoInterfacePtr sysInfo; - kbd_public::createSysInfoInstance(sysInfo); - - // 初始化通讯器 - CMbCommunicator * pCommunicator = new CMbCommunicator(); - pCommunicator->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - while(!isInterruptionRequested()) - { - kbd_net::CMbMessage msg; - if (pCommunicator && pCommunicator->recvMsg(msg, 100) && !isInterruptionRequested()) - { - parseTrendDataMessage(msg); - } - } - if (pCommunicator != NULL) - { - pCommunicator->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - delete pCommunicator; - } - pCommunicator = NULL; -} - -void CRealTimeDataCollect::parseTrendDataMessage(const CMbMessage &msg) -{ - int msgType = msg.getMsgType(); - if(MT_DP_CHANGE_DATA == msgType) - { - kbd_idlfile::SRealTimeDataPkg chgDataPkg; - try - { - chgDataPkg.ParseFromArray(msg.getDataPtr(), (int)msg.getDataSize()); - int aiSize = chgDataPkg.stairtd_size(); - for(int i = 0;i < aiSize; i++) - { - const kbd_idlfile::SAiRealTimeData &aiStru = chgDataPkg.stairtd(i); - msgNotify(aiStru.strtagname(), aiStru.fvalue()); - } - - int diSize = chgDataPkg.stdirtd_size(); - for(int i = 0;i < diSize; i++) - { - const kbd_idlfile::SDiRealTimeData &diStru = chgDataPkg.stdirtd(i); - msgNotify(diStru.strtagname(), diStru.nvalue()); - } - - int piSize = chgDataPkg.stpirtd_size(); - for(int i = 0;i < piSize; i++) - { - const kbd_idlfile::SPiRealTimeData &piStru = chgDataPkg.stpirtd(i); - msgNotify(piStru.strtagname(), (qint64)piStru.dvalue()); - } - - int miSize = chgDataPkg.stmirtd_size(); - for(int i = 0;i < miSize; i++) - { - const kbd_idlfile::SMiRealTimeData &miStru = chgDataPkg.stmirtd(i); - msgNotify(miStru.strtagname(), miStru.nvalue()); - } - } - catch (...) - { - LOGERROR("TrendPlugin ParseTrendDataMessage ! MsgType: %d", msgType); - } - } -} - -void CRealTimeDataCollect::msgNotify(const std::string &strTagName, const QVariant &value) -{ - if((!isInterruptionRequested())) - { - emit realTimeTrendDataArrived(QString::fromStdString(strTagName), value); - } -} - +#include "CRealTimeDataCollect.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" +#include "pub_logger_api/logger.h" +#include "CTrendInfoManage.h" +#include + +using namespace kbd_net; +using namespace kbd_public; +using namespace kbd_idlfile; + +CRealTimeDataCollect::CRealTimeDataCollect(QObject *parent) + : QThread(parent) +{ + +} + +CRealTimeDataCollect::~CRealTimeDataCollect() +{ + +} + +void CRealTimeDataCollect::run() +{ + kbd_public::CSysInfoInterfacePtr sysInfo; + kbd_public::createSysInfoInstance(sysInfo); + + // 初始化通讯器 + CMbCommunicator * pCommunicator = new CMbCommunicator(); + pCommunicator->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + while(!isInterruptionRequested()) + { + kbd_net::CMbMessage msg; + if (pCommunicator && pCommunicator->recvMsg(msg, 100) && !isInterruptionRequested()) + { + parseTrendDataMessage(msg); + } + } + if (pCommunicator != NULL) + { + pCommunicator->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + delete pCommunicator; + } + pCommunicator = NULL; +} + +void CRealTimeDataCollect::parseTrendDataMessage(const CMbMessage &msg) +{ + int msgType = msg.getMsgType(); + if(MT_DP_CHANGE_DATA == msgType) + { + kbd_idlfile::SRealTimeDataPkg chgDataPkg; + try + { + chgDataPkg.ParseFromArray(msg.getDataPtr(), (int)msg.getDataSize()); + int aiSize = chgDataPkg.stairtd_size(); + for(int i = 0;i < aiSize; i++) + { + const kbd_idlfile::SAiRealTimeData &aiStru = chgDataPkg.stairtd(i); + msgNotify(aiStru.strtagname(), aiStru.fvalue()); + } + + int diSize = chgDataPkg.stdirtd_size(); + for(int i = 0;i < diSize; i++) + { + const kbd_idlfile::SDiRealTimeData &diStru = chgDataPkg.stdirtd(i); + msgNotify(diStru.strtagname(), diStru.nvalue()); + } + + int piSize = chgDataPkg.stpirtd_size(); + for(int i = 0;i < piSize; i++) + { + const kbd_idlfile::SPiRealTimeData &piStru = chgDataPkg.stpirtd(i); + msgNotify(piStru.strtagname(), (qint64)piStru.dvalue()); + } + + int miSize = chgDataPkg.stmirtd_size(); + for(int i = 0;i < miSize; i++) + { + const kbd_idlfile::SMiRealTimeData &miStru = chgDataPkg.stmirtd(i); + msgNotify(miStru.strtagname(), miStru.nvalue()); + } + } + catch (...) + { + LOGERROR("TrendPlugin ParseTrendDataMessage ! MsgType: %d", msgType); + } + } +} + +void CRealTimeDataCollect::msgNotify(const std::string &strTagName, const QVariant &value) +{ + if((!isInterruptionRequested())) + { + emit realTimeTrendDataArrived(QString::fromStdString(strTagName), value); + } +} + diff --git a/product/src/gui/plugin/ISCSTrendCurves/CRealTimeDataCollect.h b/product/src/gui/plugin/ISCSTrendCurves/CRealTimeDataCollect.h index b2a2492e..6dd3f6cb 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CRealTimeDataCollect.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CRealTimeDataCollect.h @@ -1,45 +1,45 @@ -#ifndef CREALTIMEDATACOLLECT_H -#define CREALTIMEDATACOLLECT_H - -#include -#include -#include -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "../../include/net/net_msg_bus_api/CMbMessage.h" -#include "../../include/public/pub_sysinfo_api/SysInfoApi.h" - -struct ChgDataStru -{ - QVariant value; - unsigned int status; -}; - -class CRealTimeDataCollect : public QThread -{ - Q_OBJECT - -public: - CRealTimeDataCollect(QObject *parent = Q_NULLPTR); - ~CRealTimeDataCollect(); - -signals: - void realTimeTrendDataArrived(const QString &tagName, QVariant value); - -protected: - /** - * 消息接收线程 - * @brief run - */ - void run(); - -private: - /** - * @brief parseTrendDataMessage 解析实时数据 - * @param msg - */ - void parseTrendDataMessage(const kbd_net::CMbMessage &msg); - - void msgNotify(const std::string &strTagName, const QVariant &value); -}; - -#endif // CREALTIMEDATACOLLECT_H +#ifndef CREALTIMEDATACOLLECT_H +#define CREALTIMEDATACOLLECT_H + +#include +#include +#include +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "../../include/net/net_msg_bus_api/CMbMessage.h" +#include "../../include/public/pub_sysinfo_api/SysInfoApi.h" + +struct ChgDataStru +{ + QVariant value; + unsigned int status; +}; + +class CRealTimeDataCollect : public QThread +{ + Q_OBJECT + +public: + CRealTimeDataCollect(QObject *parent = Q_NULLPTR); + ~CRealTimeDataCollect(); + +signals: + void realTimeTrendDataArrived(const QString &tagName, QVariant value); + +protected: + /** + * 消息接收线程 + * @brief run + */ + void run(); + +private: + /** + * @brief parseTrendDataMessage 解析实时数据 + * @param msg + */ + void parseTrendDataMessage(const kbd_net::CMbMessage &msg); + + void msgNotify(const std::string &strTagName, const QVariant &value); +}; + +#endif // CREALTIMEDATACOLLECT_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.cpp index e5aebae4..45802ba8 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.cpp @@ -1,158 +1,158 @@ -#include -#include "CTrendEditDialog.h" -#include "ui_CTrendEditDialog.h" -#include "CTrendEditModel.h" -#include "GraphTool/Retriever/CRetriever.h" -#include "pub_utility_api/FileUtil.h" - -using namespace kbd_dbms; - -CTrendEditDialog::CTrendEditDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CTrendEditDialog), - m_graph(nullptr) -// m_pRretriever(nullptr) -{ - ui->setupUi(this); - ui->m_retrieverWidget->setWindowFlags(Qt::Widget); - //setWindowModality(Qt::WindowModal); - initialize(); - connect(ui->addCurve, SIGNAL(clicked()), this, SLOT(slot_addCureve())); - connect(ui->removeCurve, SIGNAL(clicked()), this, SLOT(slot_removeCureve())); - connect(ui->clearCurve, SIGNAL(clicked()), this, SLOT(slot_clearCureve())); - connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateTrend())); - connect(ui->cancle, SIGNAL(clicked()), this, SLOT(close())); -} - -CTrendEditDialog::~CTrendEditDialog() -{ -// if(m_pRretriever != NULL) -// { -// delete m_pRretriever; -// } -// m_pRretriever = NULL; - delete ui; -} - -void CTrendEditDialog::initialize() -{ - - initTrendView(); - -// m_pRretriever = new CRetriever(this); -} - -void CTrendEditDialog::initTrendView() -{ - m_model = new CTrendEditModel(this); - ui->trendView->setModel(m_model); - ui->trendView->horizontalHeader()->setStretchLastSection(true); - CTrendDelegate * delegate = new CTrendDelegate(this); - ui->trendView->setItemDelegate(delegate); - ui->trendView->setAlternatingRowColors(true); - ui->trendView->horizontalHeader()->setStretchLastSection(true); - ui->trendView->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->trendView->setSelectionMode(QAbstractItemView::SingleSelection); - - connect(ui->m_retrieverWidget, &CRetriever::itemTagTriggered, ui->trendView, &CTrendEditView::appendTagName); -} - -void CTrendEditDialog::showEvent(QShowEvent *event) -{ - QDialog::showEvent(event); - updateTrendViewColumnWidth(); -} - -void CTrendEditDialog::resizeEvent(QResizeEvent *event) -{ - QDialog::resizeEvent(event); - updateTrendViewColumnWidth(); -} - - -void CTrendEditDialog::updateTrendViewColumnWidth() -{ - int nTrendViewWidth = ui->trendView->width(); - ui->trendView->setColumnWidth(0, nTrendViewWidth / 3 * 2); -} - - -void CTrendEditDialog::setTrendGraph(CTrendGraph *graph) -{ - if( Q_NULLPTR == graph ) - { - return; - } - m_graph = graph; - m_model->setTrendCurves(m_graph->curves()); -} - -CTrendGraph *CTrendEditDialog::trendGraph() const -{ - return m_graph; -} - -void CTrendEditDialog::setValidLocation(QStringList &list) -{ - ui->m_retrieverWidget->setValidLocation(list); -} - -void CTrendEditDialog::setValidSubsystm(QStringList &list) -{ - ui->m_retrieverWidget->setValidProfession(list); -} - -void CTrendEditDialog::slot_updateTrend() -{ - if(m_model->rowCount() == 0) - { - QMessageBox::warning(this, tr("警告"), tr("测点数量不允许为空!")); - return; - } - - for(int nIndex(0); nIndex < m_model->rowCount(); ++nIndex) - { - if(m_model->curves().at(nIndex).tag == "") - { - QMessageBox::warning(this, tr("警告"), tr("测点名称不允许存在空值!")); - return; - } - } - if(nullptr == m_graph) - { - m_graph = new CTrendGraph(); - } - m_graph->setCurves(m_model->curves()); - accept(); -} - -void CTrendEditDialog::slot_addCureve() -{ - m_model->addTrendCurve(); -} - -void CTrendEditDialog::slot_removeCureve() -{ - if(!ui->trendView->currentIndex().isValid()) - { - QMessageBox::information(this, tr("提示"), tr("当前未选中行!")); - return; - } - m_model->removeTrendCurve(ui->trendView->currentIndex().row()); -} - -void CTrendEditDialog::slot_clearCureve() -{ - m_model->clearTrendCurves(); -} - -//void CTrendEditDialog::slot_showRetriever() -//{ -// if(nullptr == m_pRretriever) -// { -// m_pRretriever = new CRetriever(this); -// } -// m_pRretriever->show(); -//} - - +#include +#include "CTrendEditDialog.h" +#include "ui_CTrendEditDialog.h" +#include "CTrendEditModel.h" +#include "GraphTool/Retriever/CRetriever.h" +#include "pub_utility_api/FileUtil.h" + +using namespace kbd_dbms; + +CTrendEditDialog::CTrendEditDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CTrendEditDialog), + m_graph(nullptr) +// m_pRretriever(nullptr) +{ + ui->setupUi(this); + ui->m_retrieverWidget->setWindowFlags(Qt::Widget); + //setWindowModality(Qt::WindowModal); + initialize(); + connect(ui->addCurve, SIGNAL(clicked()), this, SLOT(slot_addCureve())); + connect(ui->removeCurve, SIGNAL(clicked()), this, SLOT(slot_removeCureve())); + connect(ui->clearCurve, SIGNAL(clicked()), this, SLOT(slot_clearCureve())); + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateTrend())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(close())); +} + +CTrendEditDialog::~CTrendEditDialog() +{ +// if(m_pRretriever != NULL) +// { +// delete m_pRretriever; +// } +// m_pRretriever = NULL; + delete ui; +} + +void CTrendEditDialog::initialize() +{ + + initTrendView(); + +// m_pRretriever = new CRetriever(this); +} + +void CTrendEditDialog::initTrendView() +{ + m_model = new CTrendEditModel(this); + ui->trendView->setModel(m_model); + ui->trendView->horizontalHeader()->setStretchLastSection(true); + CTrendDelegate * delegate = new CTrendDelegate(this); + ui->trendView->setItemDelegate(delegate); + ui->trendView->setAlternatingRowColors(true); + ui->trendView->horizontalHeader()->setStretchLastSection(true); + ui->trendView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->trendView->setSelectionMode(QAbstractItemView::SingleSelection); + + connect(ui->m_retrieverWidget, &CRetriever::itemTagTriggered, ui->trendView, &CTrendEditView::appendTagName); +} + +void CTrendEditDialog::showEvent(QShowEvent *event) +{ + QDialog::showEvent(event); + updateTrendViewColumnWidth(); +} + +void CTrendEditDialog::resizeEvent(QResizeEvent *event) +{ + QDialog::resizeEvent(event); + updateTrendViewColumnWidth(); +} + + +void CTrendEditDialog::updateTrendViewColumnWidth() +{ + int nTrendViewWidth = ui->trendView->width(); + ui->trendView->setColumnWidth(0, nTrendViewWidth / 3 * 2); +} + + +void CTrendEditDialog::setTrendGraph(CTrendGraph *graph) +{ + if( Q_NULLPTR == graph ) + { + return; + } + m_graph = graph; + m_model->setTrendCurves(m_graph->curves()); +} + +CTrendGraph *CTrendEditDialog::trendGraph() const +{ + return m_graph; +} + +void CTrendEditDialog::setValidLocation(QStringList &list) +{ + ui->m_retrieverWidget->setValidLocation(list); +} + +void CTrendEditDialog::setValidSubsystm(QStringList &list) +{ + ui->m_retrieverWidget->setValidProfession(list); +} + +void CTrendEditDialog::slot_updateTrend() +{ + if(m_model->rowCount() == 0) + { + QMessageBox::warning(this, tr("警告"), tr("测点数量不允许为空!")); + return; + } + + for(int nIndex(0); nIndex < m_model->rowCount(); ++nIndex) + { + if(m_model->curves().at(nIndex).tag == "") + { + QMessageBox::warning(this, tr("警告"), tr("测点名称不允许存在空值!")); + return; + } + } + if(nullptr == m_graph) + { + m_graph = new CTrendGraph(); + } + m_graph->setCurves(m_model->curves()); + accept(); +} + +void CTrendEditDialog::slot_addCureve() +{ + m_model->addTrendCurve(); +} + +void CTrendEditDialog::slot_removeCureve() +{ + if(!ui->trendView->currentIndex().isValid()) + { + QMessageBox::information(this, tr("提示"), tr("当前未选中行!")); + return; + } + m_model->removeTrendCurve(ui->trendView->currentIndex().row()); +} + +void CTrendEditDialog::slot_clearCureve() +{ + m_model->clearTrendCurves(); +} + +//void CTrendEditDialog::slot_showRetriever() +//{ +// if(nullptr == m_pRretriever) +// { +// m_pRretriever = new CRetriever(this); +// } +// m_pRretriever->show(); +//} + + diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.h index cab2c9f3..03c4f5ec 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.h @@ -1,52 +1,52 @@ -#ifndef CTRENDEDITDIALOG_H -#define CTRENDEDITDIALOG_H - -#include -#include "CTrendGraph.h" - -namespace Ui { -class CTrendEditDialog; -} - -class CRetriever; -class CTrendEditModel; - -class CTrendEditDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CTrendEditDialog(QWidget *parent = 0); - ~CTrendEditDialog(); - - void initialize(); - void initTrendView(); - - void setTrendGraph(CTrendGraph * data); - CTrendGraph * trendGraph() const; - - void setValidLocation(QStringList& list); - void setValidSubsystm(QStringList& list); - -protected: - void showEvent(QShowEvent *event); - void resizeEvent(QResizeEvent *event); - -protected slots: - void slot_updateTrend(); - void slot_addCureve(); - void slot_removeCureve(); - void slot_clearCureve(); -// void slot_showRetriever(); - -private: - void updateTrendViewColumnWidth(); - -private: - Ui::CTrendEditDialog *ui; - CTrendGraph * m_graph; - CTrendEditModel * m_model; -// CRetriever * m_pRretriever; -}; - -#endif // CTRENDEDITDIALOG_H +#ifndef CTRENDEDITDIALOG_H +#define CTRENDEDITDIALOG_H + +#include +#include "CTrendGraph.h" + +namespace Ui { +class CTrendEditDialog; +} + +class CRetriever; +class CTrendEditModel; + +class CTrendEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CTrendEditDialog(QWidget *parent = 0); + ~CTrendEditDialog(); + + void initialize(); + void initTrendView(); + + void setTrendGraph(CTrendGraph * data); + CTrendGraph * trendGraph() const; + + void setValidLocation(QStringList& list); + void setValidSubsystm(QStringList& list); + +protected: + void showEvent(QShowEvent *event); + void resizeEvent(QResizeEvent *event); + +protected slots: + void slot_updateTrend(); + void slot_addCureve(); + void slot_removeCureve(); + void slot_clearCureve(); +// void slot_showRetriever(); + +private: + void updateTrendViewColumnWidth(); + +private: + Ui::CTrendEditDialog *ui; + CTrendGraph * m_graph; + CTrendEditModel * m_model; +// CRetriever * m_pRretriever; +}; + +#endif // CTRENDEDITDIALOG_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.ui b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.ui index 30b390a9..16901664 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.ui +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditDialog.ui @@ -1,193 +1,193 @@ - - - CTrendEditDialog - - - - 0 - 0 - 1047 - 566 - - - - 趋势编辑 - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 取消 - - - - - - - 确定 - - - - - - - Qt::Horizontal - - - - 500 - 20 - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - - - QFrame::NoFrame - - - QFrame::Sunken - - - 1 - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 3 - - - - - 2 - - - 0 - - - - - 添加 - - - - - - - 删除 - - - - - - - 清空 - - - - - - - Qt::Horizontal - - - - 408 - 20 - - - - - - - - - - - - - - - - - - - - - - CTrendEditView - QTableView -
CTrendEditView.h
-
- - CRetriever - QWidget -
GraphTool/Retriever/CRetriever.h
- 1 -
-
- - - - onAddCureve() - -
+ + + CTrendEditDialog + + + + 0 + 0 + 1047 + 566 + + + + 趋势编辑 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 取消 + + + + + + + 确定 + + + + + + + Qt::Horizontal + + + + 500 + 20 + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + QFrame::NoFrame + + + QFrame::Sunken + + + 1 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 3 + + + + + 2 + + + 0 + + + + + 添加 + + + + + + + 删除 + + + + + + + 清空 + + + + + + + Qt::Horizontal + + + + 408 + 20 + + + + + + + + + + + + + + + + + + + + + + CTrendEditView + QTableView +
CTrendEditView.h
+
+ + CRetriever + QWidget +
GraphTool/Retriever/CRetriever.h
+ 1 +
+
+ + + + onAddCureve() + +
diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditModel.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditModel.cpp index 89645842..51147b41 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditModel.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditModel.cpp @@ -1,288 +1,288 @@ -#include -#include -#include -#include "CTrendGraph.h" -#include "CTrendEditModel.h" - -CTrendDelegate::CTrendDelegate(QObject *parent) - : QStyledItemDelegate(parent) -{ - -} - -QWidget *CTrendDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(option) - if(!index.isValid() || !const_cast(index.model())) - { - return parent; - } - CTrendEditModel * model = dynamic_cast(const_cast(index.model())); - if(!model) - { - return parent; - } - if( 1 == index.column() ) - { - CColorLabel * label = new CColorLabel(parent); - label->setColor(model->color(index)); - return label; - } - else if( 2 == index.column() ) - { - QSpinBox * spin = new QSpinBox(parent); - spin->setMinimum(1); - spin->setMaximum(10); - spin->setSingleStep(1); - return spin; - } - return Q_NULLPTR; -} - -void CTrendDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QStyledItemDelegate::paint(painter, option, index); - if (!index.isValid()) - { - return; - } - if (!const_cast(index.model())) - { - return; - } - CTrendEditModel * model = dynamic_cast(const_cast(index.model())); - if (!model) - { - return; - } - if (1 == index.column()) - { - painter->save(); - painter->fillRect(option.rect.adjusted(2,1,-2,-1), model->color(index)); - painter->restore(); - } -} - -void CTrendDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - if (!index.isValid() || !const_cast(index.model())) - { - return; - } - - CTrendEditModel * model = dynamic_cast(const_cast(index.model())); - if (!model) - { - return; - } - if (1 == index.column()) - { - CColorLabel * label = dynamic_cast(editor); - if(label) - { - label->setColor(model->color(index)); - } - } - else - { - QStyledItemDelegate::setEditorData(editor, index); - } - -} - -void CTrendDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - if(!index.isValid() || !const_cast(index.model())) - { - return; - } - CTrendEditModel * dataModel = dynamic_cast(model); - if(!dataModel) - { - return; - } - - if( 1 == index.column() ) - { - CColorLabel * label = dynamic_cast(editor); - if(label) - { - dataModel->setData(index, label->color()); - } - } - else - { - QStyledItemDelegate::setModelData(editor, model, index); - } - -} - -void CTrendDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(index) - editor->setGeometry(option.rect.adjusted(3,3,-3,-3)); -} - -CTrendEditModel::CTrendEditModel(QObject *parent) - :QAbstractTableModel(parent) -{ - m_header << tr("测点名称") << tr("颜色"); -} - -CTrendEditModel::~CTrendEditModel() -{ - m_listCurve.clear(); -} - -void CTrendEditModel::addTrendCurve() -{ - beginResetModel(); - Curve curve; - curve.tag = QString(""); - curve.desc = QString(""); - curve.color = QColor(qrand() % 255, qrand() % 255, qrand() % 255); - m_listCurve.append(curve); - endResetModel(); -} - -void CTrendEditModel::removeTrendCurve(const int & row) -{ - beginResetModel(); - m_listCurve.removeAt(row); - endResetModel(); -} - -void CTrendEditModel::clearTrendCurves() -{ - beginResetModel(); - m_listCurve.clear(); - endResetModel(); -} - -void CTrendEditModel::setTrendCurves(QList curves) -{ - beginResetModel(); - m_listCurve = curves; - endResetModel(); -} - -QList CTrendEditModel::curves() -{ - return m_listCurve; -} - -QColor CTrendEditModel::color(const QModelIndex &index) const -{ - if(index.isValid() && 1 == index.column() ) - { - return m_listCurve.at(index.row()).color; - } - return QColor(); -} - -QVariant CTrendEditModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_header.at(section); - } - } - return QVariant(); - -} - -QVariant CTrendEditModel::data(const QModelIndex &index, int role) const -{ - if(Qt::DisplayRole != role || !index.isValid()) - { - return QVariant(); - } - Curve curve = m_listCurve.at(index.row()); - switch (index.column()) - { - case 0: - { - return QString("%1").arg(curve.tag); - } - case 1: - { - return curve.color; - } - default: - break; - } - return QVariant(); -} - -bool CTrendEditModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_UNUSED(role) - if(!index.isValid()) - { - return false; - } - switch (index.column()) - { - case 0: - { - QStringList list = value.toString().split("."); - m_listCurve[index.row()].tag = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); - m_listCurve[index.row()].type = list.at(2); - break; - } - case 1: - { - m_listCurve[index.row()].color = value.value(); - break; - } - default: - break; - } - emit dataChanged(index, index); - return true; -} - -int CTrendEditModel::columnCount(const QModelIndex &index) const -{ - if (index.isValid()) - return 0; - return m_header.size(); -} - -int CTrendEditModel::rowCount(const QModelIndex &index) const -{ - if (index.isValid()) - return 0; - return m_listCurve.count(); -} - -Qt::ItemFlags CTrendEditModel::flags(const QModelIndex &index) const -{ - if(!index.isValid()) - { - return Qt::NoItemFlags; - } - return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; -} - -QString CTrendEditModel::checkAppendData(const QString &tag) -{ - QStringList list = tag.split("."); - QString tagName = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); - QString type = list.at(2); - if(type != "analog") - { - return tr("只能添加模拟量!"); - } - - foreach (Curve curve, m_listCurve) { - if(curve.tag == tagName) - { - return tr("该测点已存在!"); - } - } - return ""; -} - +#include +#include +#include +#include "CTrendGraph.h" +#include "CTrendEditModel.h" + +CTrendDelegate::CTrendDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ + +} + +QWidget *CTrendDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid() || !const_cast(index.model())) + { + return parent; + } + CTrendEditModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return parent; + } + if( 1 == index.column() ) + { + CColorLabel * label = new CColorLabel(parent); + label->setColor(model->color(index)); + return label; + } + else if( 2 == index.column() ) + { + QSpinBox * spin = new QSpinBox(parent); + spin->setMinimum(1); + spin->setMaximum(10); + spin->setSingleStep(1); + return spin; + } + return Q_NULLPTR; +} + +void CTrendDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter, option, index); + if (!index.isValid()) + { + return; + } + if (!const_cast(index.model())) + { + return; + } + CTrendEditModel * model = dynamic_cast(const_cast(index.model())); + if (!model) + { + return; + } + if (1 == index.column()) + { + painter->save(); + painter->fillRect(option.rect.adjusted(2,1,-2,-1), model->color(index)); + painter->restore(); + } +} + +void CTrendDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if (!index.isValid() || !const_cast(index.model())) + { + return; + } + + CTrendEditModel * model = dynamic_cast(const_cast(index.model())); + if (!model) + { + return; + } + if (1 == index.column()) + { + CColorLabel * label = dynamic_cast(editor); + if(label) + { + label->setColor(model->color(index)); + } + } + else + { + QStyledItemDelegate::setEditorData(editor, index); + } + +} + +void CTrendDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + if(!index.isValid() || !const_cast(index.model())) + { + return; + } + CTrendEditModel * dataModel = dynamic_cast(model); + if(!dataModel) + { + return; + } + + if( 1 == index.column() ) + { + CColorLabel * label = dynamic_cast(editor); + if(label) + { + dataModel->setData(index, label->color()); + } + } + else + { + QStyledItemDelegate::setModelData(editor, model, index); + } + +} + +void CTrendDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect.adjusted(3,3,-3,-3)); +} + +CTrendEditModel::CTrendEditModel(QObject *parent) + :QAbstractTableModel(parent) +{ + m_header << tr("测点名称") << tr("颜色"); +} + +CTrendEditModel::~CTrendEditModel() +{ + m_listCurve.clear(); +} + +void CTrendEditModel::addTrendCurve() +{ + beginResetModel(); + Curve curve; + curve.tag = QString(""); + curve.desc = QString(""); + curve.color = QColor(qrand() % 255, qrand() % 255, qrand() % 255); + m_listCurve.append(curve); + endResetModel(); +} + +void CTrendEditModel::removeTrendCurve(const int & row) +{ + beginResetModel(); + m_listCurve.removeAt(row); + endResetModel(); +} + +void CTrendEditModel::clearTrendCurves() +{ + beginResetModel(); + m_listCurve.clear(); + endResetModel(); +} + +void CTrendEditModel::setTrendCurves(QList curves) +{ + beginResetModel(); + m_listCurve = curves; + endResetModel(); +} + +QList CTrendEditModel::curves() +{ + return m_listCurve; +} + +QColor CTrendEditModel::color(const QModelIndex &index) const +{ + if(index.isValid() && 1 == index.column() ) + { + return m_listCurve.at(index.row()).color; + } + return QColor(); +} + +QVariant CTrendEditModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); + +} + +QVariant CTrendEditModel::data(const QModelIndex &index, int role) const +{ + if(Qt::DisplayRole != role || !index.isValid()) + { + return QVariant(); + } + Curve curve = m_listCurve.at(index.row()); + switch (index.column()) + { + case 0: + { + return QString("%1").arg(curve.tag); + } + case 1: + { + return curve.color; + } + default: + break; + } + return QVariant(); +} + +bool CTrendEditModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(role) + if(!index.isValid()) + { + return false; + } + switch (index.column()) + { + case 0: + { + QStringList list = value.toString().split("."); + m_listCurve[index.row()].tag = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); + m_listCurve[index.row()].type = list.at(2); + break; + } + case 1: + { + m_listCurve[index.row()].color = value.value(); + break; + } + default: + break; + } + emit dataChanged(index, index); + return true; +} + +int CTrendEditModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + return 0; + return m_header.size(); +} + +int CTrendEditModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + return 0; + return m_listCurve.count(); +} + +Qt::ItemFlags CTrendEditModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + { + return Qt::NoItemFlags; + } + return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; +} + +QString CTrendEditModel::checkAppendData(const QString &tag) +{ + QStringList list = tag.split("."); + QString tagName = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); + QString type = list.at(2); + if(type != "analog") + { + return tr("只能添加模拟量!"); + } + + foreach (Curve curve, m_listCurve) { + if(curve.tag == tagName) + { + return tr("该测点已存在!"); + } + } + return ""; +} + diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditModel.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditModel.h index e19ff160..6b0ffd1b 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditModel.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditModel.h @@ -1,93 +1,93 @@ -#ifndef CTRENDEDITMODEL_H -#define CTRENDEDITMODEL_H - -/***************************************** -/ * - * 趋势曲线设置视图模型 - * - * ***************************************/ - -#include -#include -#include -#include -#include -#include -#include "CTrendGraph.h" - -//Delegate Label -class CColorLabel : public QLabel -{ - Q_OBJECT -public: - CColorLabel(QWidget * parent = Q_NULLPTR) : QLabel(parent){} - - void setColor(const QColor &color) { m_color = color; } - QColor color() const { return m_color; } - -protected: - virtual void mousePressEvent(QMouseEvent *event) - { - QLabel::mousePressEvent(event); - QColor color = QColorDialog::getColor(m_color, this, tr("颜色选择"), QColorDialog::DontUseNativeDialog); - if(color.isValid()) - { - m_color = color; - } - } - - virtual void paintEvent(QPaintEvent * event) - { - QPainter p(this); - p.fillRect(rect(), QBrush(m_color)); - QLabel::paintEvent(event); - } - -private: - QColor m_color; -}; - -class CTrendDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CTrendDelegate(QObject *parent = 0); - - virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - virtual void setEditorData(QWidget *editor, const QModelIndex &index) const; - virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; - void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; -}; - -class CTrendEditModel : public QAbstractTableModel -{ - Q_OBJECT -public: - CTrendEditModel(QObject *parent = Q_NULLPTR); - ~CTrendEditModel(); - - void addTrendCurve(); - void removeTrendCurve(const int &row); - void clearTrendCurves(); - - void setTrendCurves(QList curves); - QList curves(); - - QColor color(const QModelIndex &index) const; - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual int columnCount(const QModelIndex &index = QModelIndex()) const; - virtual int rowCount(const QModelIndex &index = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - - QString checkAppendData(const QString& tag); - -private: - QStringList m_header; - QList m_listCurve; -}; - -#endif // CTRENDEDITMODEL_H +#ifndef CTRENDEDITMODEL_H +#define CTRENDEDITMODEL_H + +/***************************************** +/ * + * 趋势曲线设置视图模型 + * + * ***************************************/ + +#include +#include +#include +#include +#include +#include +#include "CTrendGraph.h" + +//Delegate Label +class CColorLabel : public QLabel +{ + Q_OBJECT +public: + CColorLabel(QWidget * parent = Q_NULLPTR) : QLabel(parent){} + + void setColor(const QColor &color) { m_color = color; } + QColor color() const { return m_color; } + +protected: + virtual void mousePressEvent(QMouseEvent *event) + { + QLabel::mousePressEvent(event); + QColor color = QColorDialog::getColor(m_color, this, tr("颜色选择"), QColorDialog::DontUseNativeDialog); + if(color.isValid()) + { + m_color = color; + } + } + + virtual void paintEvent(QPaintEvent * event) + { + QPainter p(this); + p.fillRect(rect(), QBrush(m_color)); + QLabel::paintEvent(event); + } + +private: + QColor m_color; +}; + +class CTrendDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CTrendDelegate(QObject *parent = 0); + + virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual void setEditorData(QWidget *editor, const QModelIndex &index) const; + virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +class CTrendEditModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CTrendEditModel(QObject *parent = Q_NULLPTR); + ~CTrendEditModel(); + + void addTrendCurve(); + void removeTrendCurve(const int &row); + void clearTrendCurves(); + + void setTrendCurves(QList curves); + QList curves(); + + QColor color(const QModelIndex &index) const; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + QString checkAppendData(const QString& tag); + +private: + QStringList m_header; + QList m_listCurve; +}; + +#endif // CTRENDEDITMODEL_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditView.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditView.cpp index 8ee9ef11..bb823955 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditView.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditView.cpp @@ -1,97 +1,97 @@ -#include "CTrendEditView.h" -#include -#include -#include -#include -#include -#include -#include "CTrendEditModel.h" - -CTrendEditView::CTrendEditView(QWidget *parent) - : QTableView(parent) -{ - setAcceptDrops(true); - setDropIndicatorShown(true); - setDragEnabled(true); - setDragDropMode(QAbstractItemView::DragDrop); - setSelectionMode(QAbstractItemView::ExtendedSelection); -} - -void CTrendEditView::appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti) -{ - Q_UNUSED(strTagDesc); - if(dynamic_cast(model())) - { - CTrendEditModel * curveDataModel = dynamic_cast(model()); - - QString ret = curveDataModel->checkAppendData(strTagName); - if(ret != "") - { - QMessageBox::warning(this, tr("提示"), ret); - return; - } - - if(!isMulti) - { - if(currentIndex() == QModelIndex()) - { - QMessageBox::warning(this, tr("提示"), tr("请选中一行!")); - return; - } - - curveDataModel->setData(currentIndex().sibling(currentIndex().row(), 0), strTagName); - } - else - { - curveDataModel->addTrendCurve(); - curveDataModel->setData(model()->sibling(model()->rowCount()-1, 0, currentIndex()), strTagName); - } - } -} - -void CTrendEditView::dragEnterEvent(QDragEnterEvent *event) -{ - if (event->mimeData()->hasText()) - { - event->acceptProposedAction(); - event->setDropAction(Qt::CopyAction); - } - else - { - event->setAccepted(false); - } -} - -void CTrendEditView::dragMoveEvent(QDragMoveEvent *event) -{ - if (event->mimeData()->hasText()) - { - event->acceptProposedAction(); - event->setDropAction(Qt::CopyAction); - } - else - { - event->setAccepted(false); - } -} - -void CTrendEditView::dropEvent(QDropEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasText()) - { - QString content = mimeData->text(); - if(dynamic_cast(model())) - { - CTrendEditModel * curveDataModel = dynamic_cast(model()); - QPoint pt = mapFromGlobal(QCursor::pos()); - pt.setY(pt.y() - horizontalHeader()->height()); - QModelIndex index = indexAt(pt); - if(!curveDataModel->setData(index.sibling(index.row(), 0), content)) - { - QMessageBox::warning(this, tr("警告"), tr("该测点已存在!")); - } - } - } - event->accept(); -} +#include "CTrendEditView.h" +#include +#include +#include +#include +#include +#include +#include "CTrendEditModel.h" + +CTrendEditView::CTrendEditView(QWidget *parent) + : QTableView(parent) +{ + setAcceptDrops(true); + setDropIndicatorShown(true); + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DragDrop); + setSelectionMode(QAbstractItemView::ExtendedSelection); +} + +void CTrendEditView::appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti) +{ + Q_UNUSED(strTagDesc); + if(dynamic_cast(model())) + { + CTrendEditModel * curveDataModel = dynamic_cast(model()); + + QString ret = curveDataModel->checkAppendData(strTagName); + if(ret != "") + { + QMessageBox::warning(this, tr("提示"), ret); + return; + } + + if(!isMulti) + { + if(currentIndex() == QModelIndex()) + { + QMessageBox::warning(this, tr("提示"), tr("请选中一行!")); + return; + } + + curveDataModel->setData(currentIndex().sibling(currentIndex().row(), 0), strTagName); + } + else + { + curveDataModel->addTrendCurve(); + curveDataModel->setData(model()->sibling(model()->rowCount()-1, 0, currentIndex()), strTagName); + } + } +} + +void CTrendEditView::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + event->setDropAction(Qt::CopyAction); + } + else + { + event->setAccepted(false); + } +} + +void CTrendEditView::dragMoveEvent(QDragMoveEvent *event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + event->setDropAction(Qt::CopyAction); + } + else + { + event->setAccepted(false); + } +} + +void CTrendEditView::dropEvent(QDropEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + if (mimeData->hasText()) + { + QString content = mimeData->text(); + if(dynamic_cast(model())) + { + CTrendEditModel * curveDataModel = dynamic_cast(model()); + QPoint pt = mapFromGlobal(QCursor::pos()); + pt.setY(pt.y() - horizontalHeader()->height()); + QModelIndex index = indexAt(pt); + if(!curveDataModel->setData(index.sibling(index.row(), 0), content)) + { + QMessageBox::warning(this, tr("警告"), tr("该测点已存在!")); + } + } + } + event->accept(); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditView.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditView.h index 1ecfdf93..5245c626 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendEditView.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendEditView.h @@ -1,21 +1,21 @@ -#ifndef CTRENDEDITVIEW_H -#define CTRENDEDITVIEW_H - -#include - -class CTrendEditView : public QTableView -{ - Q_OBJECT -public: - CTrendEditView(QWidget *parent = Q_NULLPTR); - -public slots: - void appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti); - -protected: - void dragEnterEvent(QDragEnterEvent *event); - void dragMoveEvent(QDragMoveEvent *event); - void dropEvent(QDropEvent *event); -}; - -#endif // CTRENDEDITVIEW_H +#ifndef CTRENDEDITVIEW_H +#define CTRENDEDITVIEW_H + +#include + +class CTrendEditView : public QTableView +{ + Q_OBJECT +public: + CTrendEditView(QWidget *parent = Q_NULLPTR); + +public slots: + void appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); +}; + +#endif // CTRENDEDITVIEW_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendFavTreeWidget.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendFavTreeWidget.cpp index c80144f6..e182f771 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendFavTreeWidget.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendFavTreeWidget.cpp @@ -1,527 +1,527 @@ -#include "CTrendFavTreeWidget.h" -#include "CTrendEditDialog.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "perm_mng_api/PermMngApi.h" -#include "pub_utility_api/FileUtil.h" -#include "widgets/CTrendAddWidget.h" -#include "CTrendInfoManage.h" - -CTrendFavTreeWidget::CTrendFavTreeWidget(QWidget *parent) - : QTreeWidget(parent) -{ - setColumnCount(1); - setHeaderLabel(tr("趋势管理")); - setSelectionMode(QAbstractItemView::SingleSelection); - setEditTriggers(EditKeyPressed); - connect(this, &CTrendFavTreeWidget::doubleClicked, this, &CTrendFavTreeWidget::slotShowTrendGraph); - connect(this, &CTrendFavTreeWidget::itemChanged, this, &CTrendFavTreeWidget::slotItemChanged); - setObjectName("CTrendFavTreeWidget"); - loadTrendGraph(); - setEditTriggers(NoEditTriggers); -} - -CTrendFavTreeWidget::~CTrendFavTreeWidget() -{ - savaTrendGraph(); - qDeleteAll(m_trendGraphMap); - m_trendGraphMap.clear(); -} - -void CTrendFavTreeWidget::collectGraph(const QString &title, const CTrendGraph &graph) -{ - for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) - { - if(topLevelItem(nIndex)->text(0) == title ) - { - QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); - return; - } - } - - QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << title, Item_GRAPH_Type); - item->setFlags(item->flags() | Qt::ItemIsEditable); - addTopLevelItem(item); - CTrendGraph * tmp = new CTrendGraph(); - tmp->setCurves(graph.curves()); - m_trendGraphMap.insert(item, tmp); - savaTrendGraph(); -} - - -void CTrendFavTreeWidget::contextMenuEvent(QContextMenuEvent *event) -{ -// bool bIsEditable = false; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL) - { - return; - } - - permMngPtr->PermDllInit(); - std::string tmp = FUNC_NOM_TREND_EDIT; - if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) - { -// bIsEditable = true; - } - else - { - return; - } - - QMenu menu; - QTreeWidgetItem * item = itemAt(event->pos()); - - if(!item) - { - QAction * newAction = new QAction(tr("添加趋势"), &menu); - menu.addAction(newAction); - connect(newAction, SIGNAL(triggered()), this, SLOT(slotNewTrendEdit())); - } - else - { - if(Item_LOCATION_Type == item->type()) - { - QAction * newAction = new QAction(tr("添加趋势"), &menu); - menu.addAction(newAction); - connect(newAction, SIGNAL(triggered()), this, SLOT(slotNewTrendEdit())); - } - else if(Item_GRAPH_Type == item->type()) - { - QAction * showAction = new QAction(tr("显示"), &menu); - menu.addAction(showAction); - connect(showAction, SIGNAL(triggered()), this, SLOT(slotShowTrendGraph())); - - QAction * editAction = new QAction(tr("编辑"), &menu); - menu.addAction(editAction); - connect(editAction, SIGNAL(triggered()), this, SLOT(slotEditTrendEdit())); - - QAction * renameAction = new QAction(tr("重命名"), &menu); - menu.addAction(renameAction); - connect(renameAction, &QAction::triggered, this, [&]() { - m_strEditItemContent = item->text(0); - editItem(item);}); - } - QAction * deleteAction = new QAction(tr("删除"), &menu); - menu.addAction(deleteAction); - connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotRemoveTrendEdit())); - } - - menu.exec(event->globalPos()); -} - -void CTrendFavTreeWidget::slotNewTrendEdit() -{ - CTrendAddWidget *widget = new CTrendAddWidget(this); - widget->show(); - connect(widget, &CTrendAddWidget::acceptedInput, this, [=](){ - if(widget->text() == QString()) - { - QMessageBox::warning(this, tr("错误"), tr("趋势名称不允许为空!"), - QMessageBox::Ok); - } - else if(!isTrendNameValid(widget->text())) - { - QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); - } - else - { - slotAddTrend(widget->locationId(), widget->subSysteId(), widget->text()); - widget->close(); - delete widget; - } - }); -} - -void CTrendFavTreeWidget::slotShowTrendGraph() -{ - if(m_trendGraphMap.contains(currentItem())) - { - emit showTrendGraph(m_trendGraphMap.value(currentItem()), currentItem()->text(0)); - } -} - -void CTrendFavTreeWidget::slotEditTrendEdit() -{ - CTrendEditDialog *dlg = new CTrendEditDialog(this); - - if(m_trendGraphMap.contains(currentItem())) - { - dlg->setTrendGraph(m_trendGraphMap.value(currentItem())); - dlg->setValidLocation(QStringList() << currentItem()->parent()->parent()->text(0)); - dlg->setValidSubsystm(QStringList() << currentItem()->parent()->text(0)); - } - if(QDialog::Accepted !=dlg->exec()) - { - return; - } - - CTrendGraph * graph = dlg->trendGraph(); - delete dlg; - dlg = NULL; - - m_trendGraphMap.insert(currentItem(), graph); - savaTrendGraph(); -} - -void CTrendFavTreeWidget::slotRemoveTrendEdit() -{ - if(Item_LOCATION_Type == currentItem()->type()) - { - takeTopLevelItem(currentIndex().row()); - } - else - { - currentItem()->parent()->takeChild(currentIndex().row()); - } - savaTrendGraph(); -} - -void CTrendFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column) - QString content = item->text(0); - for(int locationIndex(0); locationIndex < topLevelItemCount(); locationIndex++) - { - QTreeWidgetItem *locationItem = topLevelItem(locationIndex); - for(int subIndex(0); subIndex < locationItem->childCount(); subIndex++) - { - QTreeWidgetItem *subItem = locationItem->child(subIndex); - for(int nIndex(0); nIndex < subItem->childCount(); nIndex++) - { - QTreeWidgetItem *temp = subItem->child(nIndex); - if( temp != item && temp->text(0) == content ) - { - QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); - item->setText(0, m_strEditItemContent); - return; - } - } - } - } - savaTrendGraph(); -} - -void CTrendFavTreeWidget::slotAddTrend(int locationId, int subSystemId, QString name) -{ - int insert = false; - int location = -1; - QList curves; - CTrendGraph * graph = new CTrendGraph(); - graph->setCurves(curves); - for(int locationIndex(0); locationIndex < topLevelItemCount(); locationIndex++) - { - QTreeWidgetItem * locationItem = topLevelItem(locationIndex); - int temp = locationItem->data(0, Qt::UserRole).toInt(); - if(temp < locationId) - continue; - else if(temp > locationId) - { - QTreeWidgetItem *lItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getLocationDesc(locationId), Item_LOCATION_Type); - QTreeWidgetItem *sItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getSubSystemDesc(subSystemId), Item_SUBSYSTEM_Type); - QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); - lItem->setData(0, Qt::UserRole, locationId); - sItem->setData(0, Qt::UserRole, subSystemId); - sItem->addChild(tItem); - lItem->addChild(sItem); - insertTopLevelItem(locationIndex, lItem); - m_trendGraphMap.insert(tItem, graph); - insert = true; - break; - } - - location = locationIndex; - int subCount = locationItem->childCount(); - for(int subIndex(0); subIndex < subCount; subIndex++) - { - QTreeWidgetItem * subItem = locationItem->child(subIndex); - int temp = subItem->data(0, Qt::UserRole).toInt(); - if(temp < subSystemId) - continue; - else if(temp > subSystemId) - { - QTreeWidgetItem *sItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getSubSystemDesc(subSystemId), Item_SUBSYSTEM_Type); - QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); - sItem->setData(0, Qt::UserRole, subSystemId); - sItem->addChild(tItem); - locationItem->insertChild(subIndex, sItem); - m_trendGraphMap.insert(tItem, graph); - insert = true; - break; - } - QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); - tItem->setFlags(tItem->flags() | Qt::ItemIsEditable); - subItem->addChild(tItem); - m_trendGraphMap.insert(tItem, graph); - insert = true; - break; - } - break; - } - if(!insert) - { - QTreeWidgetItem *lItem = topLevelItem(location); - if(!lItem) - { - lItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getLocationDesc(locationId), Item_LOCATION_Type); - lItem->setData(0, Qt::UserRole, locationId); - } - QTreeWidgetItem *sItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getSubSystemDesc(subSystemId), Item_SUBSYSTEM_Type); - QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); - sItem->setData(0, Qt::UserRole, subSystemId); - sItem->addChild(tItem); - lItem->addChild(sItem); - m_trendGraphMap.insert(tItem, graph); - if(location == -1) - addTopLevelItem(lItem); - } - savaTrendGraph(); -} - -void CTrendFavTreeWidget::slotImport() -{ - QString filePath = QFileDialog::getOpenFileName(this, tr("选择趋势收藏文件"), QString(), "*.xml"); - if(filePath.isEmpty()) - { - return; - } - loadTrendGraph(filePath); - savaTrendGraph(); -} - -void CTrendFavTreeWidget::slotExport() -{ - QString filePath = QFileDialog::getSaveFileName(this, tr("保存趋势收藏文件"), QString(), "*.xml"); - if(filePath.isEmpty()) - { - return; - } - - QList selectItem = selectedItems(); - if(selectItem.isEmpty()) - { - return; - } -} - -bool CTrendFavTreeWidget::isTrendNameValid(const QString &name) -{ - for(int locationIndex(0); locationIndex < topLevelItemCount(); locationIndex++) - { - QTreeWidgetItem *locationItem = topLevelItem(locationIndex); - for(int subIndex(0); subIndex < locationItem->childCount(); subIndex++) - { - QTreeWidgetItem *subItem = locationItem->child(subIndex); - for(int nIndex(0); nIndex < subItem->childCount(); nIndex++) - { - QTreeWidgetItem *temp = subItem->child(nIndex); - if(temp->text(0) == name ) - { - return false; - } - } - } - } - return true; -} - -QString CTrendFavTreeWidget::getNewValidTitle() -{ - QString title = QString("自定义趋势_"); - QStringList listItemText; - for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) - { - listItemText << topLevelItem(nIndex)->text(0); - } - int serial = 0; - while(listItemText.contains(title + QString::number(serial))) - { - serial++; - } - return title + QString::number(serial); -} - -void CTrendFavTreeWidget::loadTrendGraph(const QString &filePath) -{ - QDomDocument document; - QString strFileName; - if(filePath.isEmpty()) - { - strFileName = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); - } - else - { - strFileName = filePath; - } - QFile file(strFileName); - if (!file.open(QIODevice::ReadOnly)) - { - return; - } - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - QDomElement root = document.documentElement(); - if(!root.isNull()) - { - QDomNodeList locationNodeList = root.elementsByTagName("location"); - for(int locationIndex(0); locationIndex < locationNodeList.size(); locationIndex++) - { - QDomNode locationNode = locationNodeList.at(locationIndex); - if(locationNode.isNull()) - continue; - QDomElement locationElement = locationNode.toElement(); - if(locationElement.isNull()) - continue; - QString locationId = locationElement.attribute("id", "-1"); - QString locationDesc = CTrendInfoManage::instance()->getLocationDesc(locationId.toInt()); - QTreeWidgetItem * locationItem = new QTreeWidgetItem(QStringList() << locationDesc, Item_LOCATION_Type); - locationItem->setData(0, Qt::UserRole, locationId); - - QDomNodeList subSysNodeList = locationElement.elementsByTagName("subSystem"); - for(int subSysIndex(0); subSysIndex < subSysNodeList.size(); subSysIndex++) - { - QDomNode subSysNode = subSysNodeList.at(subSysIndex); - if(subSysNode.isNull()) - continue; - QDomElement subSysElement = subSysNode.toElement(); - if(subSysElement.isNull()) - continue; - QString subSysId = subSysElement.attribute("id", "-1"); - QString subSysDesc = CTrendInfoManage::instance()->getSubSystemDesc(subSysId.toInt()); - QTreeWidgetItem * subSysItem = new QTreeWidgetItem(locationItem, QStringList() << subSysDesc, Item_SUBSYSTEM_Type); - subSysItem->setData(0, Qt::UserRole, subSysId); - - QDomNodeList graphNodeList = subSysElement.elementsByTagName("graph"); - for(int graphIndex(0); graphIndex < graphNodeList.size(); graphIndex++) - { - QDomNode graphNode = graphNodeList.at(graphIndex); - if(graphNode.isNull()) - continue; - QDomElement graphElement = graphNode.toElement(); - if(graphElement.isNull()) - continue; - QString name = graphElement.attribute("name", QString()); - QTreeWidgetItem * graphItem = new QTreeWidgetItem(subSysItem, QStringList() << name, Item_GRAPH_Type); - graphItem->setFlags(graphItem->flags() | Qt::ItemIsEditable); - - QList curves; - QDomNodeList curveNodeList = graphElement.elementsByTagName("curve"); - for(int nCurveIndex(0); nCurveIndex < curveNodeList.size(); nCurveIndex++) - { - QDomNode curveNode = curveNodeList.at(nCurveIndex); - QDomElement curveElement = curveNode.toElement(); - if(curveElement.isNull()) - continue; - QDomNodeList itemList = curveElement.elementsByTagName("item"); - for(int itemIndex(0); itemIndex < itemList.size(); itemIndex++) - { - QDomNode itemNode = itemList.at(itemIndex); - if(itemNode.isNull()) - continue; - while(!itemNode.isNull()) - { - QDomElement item = itemNode.toElement(); - if(!item.isNull()) - { - Curve curve; - curve.tag = item.attribute("tag"); - curve.color = QColor(item.attribute("color").toUInt() & 0x00ffffff); - curves.append(curve); - } - itemNode = curveNode.nextSibling(); - } - } - } - CTrendGraph * graph = new CTrendGraph(); - graph->setCurves(curves); - m_trendGraphMap.insert(graphItem, graph); - } - } - addTopLevelItem(locationItem); - } - } -} - -void CTrendFavTreeWidget::savaTrendGraph(const QString &filePath) -{ - QFile file; - if(!filePath.isEmpty()) - { - file.setFileName(filePath); - } - else - { - QString strTrendDir = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model"); - QDir dir; - if(!dir.exists(strTrendDir)) - { - dir.mkdir(strTrendDir); - } - QString strTrendFile = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); - file.setFileName(strTrendFile); - } - - if(file.open(QIODevice::WriteOnly | QIODevice::Text)) - { - QDomDocument document; - - QString strHeader("version='1.0' encoding='utf-8'"); - document.appendChild(document.createProcessingInstruction("xml", strHeader)); - QDomElement root = document.createElement("Profile"); - for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) - { - QTreeWidgetItem * locationItem = topLevelItem(nIndex); - QDomElement locationNode = document.createElement("location"); - locationNode.setAttribute("id", locationItem->data(0, Qt::UserRole).toString()); - int subSysCount = locationItem->childCount(); - for(int nSubSysIndex(0); nSubSysIndex < subSysCount; nSubSysIndex++) - { - QTreeWidgetItem * subSysItem = locationItem->child(nSubSysIndex); - QDomElement subSysNode = document.createElement("subSystem"); - subSysNode.setAttribute("id", subSysItem->data(0, Qt::UserRole).toString()); - int graphCount = subSysItem->childCount(); - for(int nGraphIndex(0); nGraphIndex < graphCount; nGraphIndex++) - { - QTreeWidgetItem * item = subSysItem->child(nGraphIndex); - QDomElement graphNode = document.createElement("graph"); - graphNode.setAttribute("name", item->text(0)); - - QDomElement curveNode = document.createElement("curve"); - if(m_trendGraphMap.contains(item)) - { - const QList listCurve = m_trendGraphMap.value(item)->curves(); - for(int nCurveIndex(0); nCurveIndex < listCurve.size(); nCurveIndex++) - { - Curve curve = listCurve.at(nCurveIndex); - QDomElement item = document.createElement("item"); - item.setAttribute("tag", curve.tag); - item.setAttribute("color", curve.color.rgb()); - curveNode.appendChild(item); - } - graphNode.appendChild(curveNode); - } - subSysNode.appendChild(graphNode); - } - locationNode.appendChild(subSysNode); - } - root.appendChild(locationNode); - } - document.appendChild(root); - - QTextStream content(&file); - document.save(content, 4); - } - file.close(); -} +#include "CTrendFavTreeWidget.h" +#include "CTrendEditDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "perm_mng_api/PermMngApi.h" +#include "pub_utility_api/FileUtil.h" +#include "widgets/CTrendAddWidget.h" +#include "CTrendInfoManage.h" + +CTrendFavTreeWidget::CTrendFavTreeWidget(QWidget *parent) + : QTreeWidget(parent) +{ + setColumnCount(1); + setHeaderLabel(tr("趋势管理")); + setSelectionMode(QAbstractItemView::SingleSelection); + setEditTriggers(EditKeyPressed); + connect(this, &CTrendFavTreeWidget::doubleClicked, this, &CTrendFavTreeWidget::slotShowTrendGraph); + connect(this, &CTrendFavTreeWidget::itemChanged, this, &CTrendFavTreeWidget::slotItemChanged); + setObjectName("CTrendFavTreeWidget"); + loadTrendGraph(); + setEditTriggers(NoEditTriggers); +} + +CTrendFavTreeWidget::~CTrendFavTreeWidget() +{ + savaTrendGraph(); + qDeleteAll(m_trendGraphMap); + m_trendGraphMap.clear(); +} + +void CTrendFavTreeWidget::collectGraph(const QString &title, const CTrendGraph &graph) +{ + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->text(0) == title ) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + return; + } + } + + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << title, Item_GRAPH_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + CTrendGraph * tmp = new CTrendGraph(); + tmp->setCurves(graph.curves()); + m_trendGraphMap.insert(item, tmp); + savaTrendGraph(); +} + + +void CTrendFavTreeWidget::contextMenuEvent(QContextMenuEvent *event) +{ +// bool bIsEditable = false; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL) + { + return; + } + + permMngPtr->PermDllInit(); + std::string tmp = FUNC_NOM_TREND_EDIT; + if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) + { +// bIsEditable = true; + } + else + { + return; + } + + QMenu menu; + QTreeWidgetItem * item = itemAt(event->pos()); + + if(!item) + { + QAction * newAction = new QAction(tr("添加趋势"), &menu); + menu.addAction(newAction); + connect(newAction, SIGNAL(triggered()), this, SLOT(slotNewTrendEdit())); + } + else + { + if(Item_LOCATION_Type == item->type()) + { + QAction * newAction = new QAction(tr("添加趋势"), &menu); + menu.addAction(newAction); + connect(newAction, SIGNAL(triggered()), this, SLOT(slotNewTrendEdit())); + } + else if(Item_GRAPH_Type == item->type()) + { + QAction * showAction = new QAction(tr("显示"), &menu); + menu.addAction(showAction); + connect(showAction, SIGNAL(triggered()), this, SLOT(slotShowTrendGraph())); + + QAction * editAction = new QAction(tr("编辑"), &menu); + menu.addAction(editAction); + connect(editAction, SIGNAL(triggered()), this, SLOT(slotEditTrendEdit())); + + QAction * renameAction = new QAction(tr("重命名"), &menu); + menu.addAction(renameAction); + connect(renameAction, &QAction::triggered, this, [&]() { + m_strEditItemContent = item->text(0); + editItem(item);}); + } + QAction * deleteAction = new QAction(tr("删除"), &menu); + menu.addAction(deleteAction); + connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotRemoveTrendEdit())); + } + + menu.exec(event->globalPos()); +} + +void CTrendFavTreeWidget::slotNewTrendEdit() +{ + CTrendAddWidget *widget = new CTrendAddWidget(this); + widget->show(); + connect(widget, &CTrendAddWidget::acceptedInput, this, [=](){ + if(widget->text() == QString()) + { + QMessageBox::warning(this, tr("错误"), tr("趋势名称不允许为空!"), + QMessageBox::Ok); + } + else if(!isTrendNameValid(widget->text())) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + } + else + { + slotAddTrend(widget->locationId(), widget->subSysteId(), widget->text()); + widget->close(); + delete widget; + } + }); +} + +void CTrendFavTreeWidget::slotShowTrendGraph() +{ + if(m_trendGraphMap.contains(currentItem())) + { + emit showTrendGraph(m_trendGraphMap.value(currentItem()), currentItem()->text(0)); + } +} + +void CTrendFavTreeWidget::slotEditTrendEdit() +{ + CTrendEditDialog *dlg = new CTrendEditDialog(this); + + if(m_trendGraphMap.contains(currentItem())) + { + dlg->setTrendGraph(m_trendGraphMap.value(currentItem())); + dlg->setValidLocation(QStringList() << currentItem()->parent()->parent()->text(0)); + dlg->setValidSubsystm(QStringList() << currentItem()->parent()->text(0)); + } + if(QDialog::Accepted !=dlg->exec()) + { + return; + } + + CTrendGraph * graph = dlg->trendGraph(); + delete dlg; + dlg = NULL; + + m_trendGraphMap.insert(currentItem(), graph); + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotRemoveTrendEdit() +{ + if(Item_LOCATION_Type == currentItem()->type()) + { + takeTopLevelItem(currentIndex().row()); + } + else + { + currentItem()->parent()->takeChild(currentIndex().row()); + } + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column) + QString content = item->text(0); + for(int locationIndex(0); locationIndex < topLevelItemCount(); locationIndex++) + { + QTreeWidgetItem *locationItem = topLevelItem(locationIndex); + for(int subIndex(0); subIndex < locationItem->childCount(); subIndex++) + { + QTreeWidgetItem *subItem = locationItem->child(subIndex); + for(int nIndex(0); nIndex < subItem->childCount(); nIndex++) + { + QTreeWidgetItem *temp = subItem->child(nIndex); + if( temp != item && temp->text(0) == content ) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + item->setText(0, m_strEditItemContent); + return; + } + } + } + } + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotAddTrend(int locationId, int subSystemId, QString name) +{ + int insert = false; + int location = -1; + QList curves; + CTrendGraph * graph = new CTrendGraph(); + graph->setCurves(curves); + for(int locationIndex(0); locationIndex < topLevelItemCount(); locationIndex++) + { + QTreeWidgetItem * locationItem = topLevelItem(locationIndex); + int temp = locationItem->data(0, Qt::UserRole).toInt(); + if(temp < locationId) + continue; + else if(temp > locationId) + { + QTreeWidgetItem *lItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getLocationDesc(locationId), Item_LOCATION_Type); + QTreeWidgetItem *sItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getSubSystemDesc(subSystemId), Item_SUBSYSTEM_Type); + QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); + lItem->setData(0, Qt::UserRole, locationId); + sItem->setData(0, Qt::UserRole, subSystemId); + sItem->addChild(tItem); + lItem->addChild(sItem); + insertTopLevelItem(locationIndex, lItem); + m_trendGraphMap.insert(tItem, graph); + insert = true; + break; + } + + location = locationIndex; + int subCount = locationItem->childCount(); + for(int subIndex(0); subIndex < subCount; subIndex++) + { + QTreeWidgetItem * subItem = locationItem->child(subIndex); + int temp = subItem->data(0, Qt::UserRole).toInt(); + if(temp < subSystemId) + continue; + else if(temp > subSystemId) + { + QTreeWidgetItem *sItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getSubSystemDesc(subSystemId), Item_SUBSYSTEM_Type); + QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); + sItem->setData(0, Qt::UserRole, subSystemId); + sItem->addChild(tItem); + locationItem->insertChild(subIndex, sItem); + m_trendGraphMap.insert(tItem, graph); + insert = true; + break; + } + QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); + tItem->setFlags(tItem->flags() | Qt::ItemIsEditable); + subItem->addChild(tItem); + m_trendGraphMap.insert(tItem, graph); + insert = true; + break; + } + break; + } + if(!insert) + { + QTreeWidgetItem *lItem = topLevelItem(location); + if(!lItem) + { + lItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getLocationDesc(locationId), Item_LOCATION_Type); + lItem->setData(0, Qt::UserRole, locationId); + } + QTreeWidgetItem *sItem = new QTreeWidgetItem(QStringList() << CTrendInfoManage::instance()->getSubSystemDesc(subSystemId), Item_SUBSYSTEM_Type); + QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); + sItem->setData(0, Qt::UserRole, subSystemId); + sItem->addChild(tItem); + lItem->addChild(sItem); + m_trendGraphMap.insert(tItem, graph); + if(location == -1) + addTopLevelItem(lItem); + } + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotImport() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("选择趋势收藏文件"), QString(), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + loadTrendGraph(filePath); + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotExport() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("保存趋势收藏文件"), QString(), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + + QList selectItem = selectedItems(); + if(selectItem.isEmpty()) + { + return; + } +} + +bool CTrendFavTreeWidget::isTrendNameValid(const QString &name) +{ + for(int locationIndex(0); locationIndex < topLevelItemCount(); locationIndex++) + { + QTreeWidgetItem *locationItem = topLevelItem(locationIndex); + for(int subIndex(0); subIndex < locationItem->childCount(); subIndex++) + { + QTreeWidgetItem *subItem = locationItem->child(subIndex); + for(int nIndex(0); nIndex < subItem->childCount(); nIndex++) + { + QTreeWidgetItem *temp = subItem->child(nIndex); + if(temp->text(0) == name ) + { + return false; + } + } + } + } + return true; +} + +QString CTrendFavTreeWidget::getNewValidTitle() +{ + QString title = QString("自定义趋势_"); + QStringList listItemText; + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + listItemText << topLevelItem(nIndex)->text(0); + } + int serial = 0; + while(listItemText.contains(title + QString::number(serial))) + { + serial++; + } + return title + QString::number(serial); +} + +void CTrendFavTreeWidget::loadTrendGraph(const QString &filePath) +{ + QDomDocument document; + QString strFileName; + if(filePath.isEmpty()) + { + strFileName = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); + } + else + { + strFileName = filePath; + } + QFile file(strFileName); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(!root.isNull()) + { + QDomNodeList locationNodeList = root.elementsByTagName("location"); + for(int locationIndex(0); locationIndex < locationNodeList.size(); locationIndex++) + { + QDomNode locationNode = locationNodeList.at(locationIndex); + if(locationNode.isNull()) + continue; + QDomElement locationElement = locationNode.toElement(); + if(locationElement.isNull()) + continue; + QString locationId = locationElement.attribute("id", "-1"); + QString locationDesc = CTrendInfoManage::instance()->getLocationDesc(locationId.toInt()); + QTreeWidgetItem * locationItem = new QTreeWidgetItem(QStringList() << locationDesc, Item_LOCATION_Type); + locationItem->setData(0, Qt::UserRole, locationId); + + QDomNodeList subSysNodeList = locationElement.elementsByTagName("subSystem"); + for(int subSysIndex(0); subSysIndex < subSysNodeList.size(); subSysIndex++) + { + QDomNode subSysNode = subSysNodeList.at(subSysIndex); + if(subSysNode.isNull()) + continue; + QDomElement subSysElement = subSysNode.toElement(); + if(subSysElement.isNull()) + continue; + QString subSysId = subSysElement.attribute("id", "-1"); + QString subSysDesc = CTrendInfoManage::instance()->getSubSystemDesc(subSysId.toInt()); + QTreeWidgetItem * subSysItem = new QTreeWidgetItem(locationItem, QStringList() << subSysDesc, Item_SUBSYSTEM_Type); + subSysItem->setData(0, Qt::UserRole, subSysId); + + QDomNodeList graphNodeList = subSysElement.elementsByTagName("graph"); + for(int graphIndex(0); graphIndex < graphNodeList.size(); graphIndex++) + { + QDomNode graphNode = graphNodeList.at(graphIndex); + if(graphNode.isNull()) + continue; + QDomElement graphElement = graphNode.toElement(); + if(graphElement.isNull()) + continue; + QString name = graphElement.attribute("name", QString()); + QTreeWidgetItem * graphItem = new QTreeWidgetItem(subSysItem, QStringList() << name, Item_GRAPH_Type); + graphItem->setFlags(graphItem->flags() | Qt::ItemIsEditable); + + QList curves; + QDomNodeList curveNodeList = graphElement.elementsByTagName("curve"); + for(int nCurveIndex(0); nCurveIndex < curveNodeList.size(); nCurveIndex++) + { + QDomNode curveNode = curveNodeList.at(nCurveIndex); + QDomElement curveElement = curveNode.toElement(); + if(curveElement.isNull()) + continue; + QDomNodeList itemList = curveElement.elementsByTagName("item"); + for(int itemIndex(0); itemIndex < itemList.size(); itemIndex++) + { + QDomNode itemNode = itemList.at(itemIndex); + if(itemNode.isNull()) + continue; + while(!itemNode.isNull()) + { + QDomElement item = itemNode.toElement(); + if(!item.isNull()) + { + Curve curve; + curve.tag = item.attribute("tag"); + curve.color = QColor(item.attribute("color").toUInt() & 0x00ffffff); + curves.append(curve); + } + itemNode = curveNode.nextSibling(); + } + } + } + CTrendGraph * graph = new CTrendGraph(); + graph->setCurves(curves); + m_trendGraphMap.insert(graphItem, graph); + } + } + addTopLevelItem(locationItem); + } + } +} + +void CTrendFavTreeWidget::savaTrendGraph(const QString &filePath) +{ + QFile file; + if(!filePath.isEmpty()) + { + file.setFileName(filePath); + } + else + { + QString strTrendDir = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model"); + QDir dir; + if(!dir.exists(strTrendDir)) + { + dir.mkdir(strTrendDir); + } + QString strTrendFile = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); + file.setFileName(strTrendFile); + } + + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QDomDocument document; + + QString strHeader("version='1.0' encoding='utf-8'"); + document.appendChild(document.createProcessingInstruction("xml", strHeader)); + QDomElement root = document.createElement("Profile"); + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + QTreeWidgetItem * locationItem = topLevelItem(nIndex); + QDomElement locationNode = document.createElement("location"); + locationNode.setAttribute("id", locationItem->data(0, Qt::UserRole).toString()); + int subSysCount = locationItem->childCount(); + for(int nSubSysIndex(0); nSubSysIndex < subSysCount; nSubSysIndex++) + { + QTreeWidgetItem * subSysItem = locationItem->child(nSubSysIndex); + QDomElement subSysNode = document.createElement("subSystem"); + subSysNode.setAttribute("id", subSysItem->data(0, Qt::UserRole).toString()); + int graphCount = subSysItem->childCount(); + for(int nGraphIndex(0); nGraphIndex < graphCount; nGraphIndex++) + { + QTreeWidgetItem * item = subSysItem->child(nGraphIndex); + QDomElement graphNode = document.createElement("graph"); + graphNode.setAttribute("name", item->text(0)); + + QDomElement curveNode = document.createElement("curve"); + if(m_trendGraphMap.contains(item)) + { + const QList listCurve = m_trendGraphMap.value(item)->curves(); + for(int nCurveIndex(0); nCurveIndex < listCurve.size(); nCurveIndex++) + { + Curve curve = listCurve.at(nCurveIndex); + QDomElement item = document.createElement("item"); + item.setAttribute("tag", curve.tag); + item.setAttribute("color", curve.color.rgb()); + curveNode.appendChild(item); + } + graphNode.appendChild(curveNode); + } + subSysNode.appendChild(graphNode); + } + locationNode.appendChild(subSysNode); + } + root.appendChild(locationNode); + } + document.appendChild(root); + + QTextStream content(&file); + document.save(content, 4); + } + file.close(); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendFavTreeWidget.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendFavTreeWidget.h index a63b9228..a71cbf33 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendFavTreeWidget.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendFavTreeWidget.h @@ -1,53 +1,53 @@ -#ifndef CTRENDFAVTREEWIDGET_H -#define CTRENDFAVTREEWIDGET_H - -#include - -enum E_Tree_ItemType -{ - Item_LOCATION_Type = QTreeWidgetItem::UserType + 1, - Item_SUBSYSTEM_Type, - Item_GRAPH_Type, - Item_TAG_Type, -}; - -class CTrendGraph; - -class CTrendFavTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - explicit CTrendFavTreeWidget(QWidget *parent = nullptr); - ~CTrendFavTreeWidget(); - -signals: - void showTrendGraph(CTrendGraph * graph, QString name); - -public slots: - void collectGraph(const QString &title, const CTrendGraph &graph); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - -protected slots: - void slotNewTrendEdit(); - void slotShowTrendGraph(); - void slotEditTrendEdit(); - void slotRemoveTrendEdit(); - void slotItemChanged(QTreeWidgetItem *item, int column); - void slotAddTrend(int locationId, int subSystemId, QString name); - void slotImport(); - void slotExport(); - -private: - bool isTrendNameValid(const QString& name); - QString getNewValidTitle(); - void loadTrendGraph(const QString& filePath = QString()); - void savaTrendGraph(const QString& filePath = QString()); - -private: - QMap m_trendGraphMap; - QString m_strEditItemContent; -}; - -#endif // CTRENDFAVTREEWIDGET_H +#ifndef CTRENDFAVTREEWIDGET_H +#define CTRENDFAVTREEWIDGET_H + +#include + +enum E_Tree_ItemType +{ + Item_LOCATION_Type = QTreeWidgetItem::UserType + 1, + Item_SUBSYSTEM_Type, + Item_GRAPH_Type, + Item_TAG_Type, +}; + +class CTrendGraph; + +class CTrendFavTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + explicit CTrendFavTreeWidget(QWidget *parent = nullptr); + ~CTrendFavTreeWidget(); + +signals: + void showTrendGraph(CTrendGraph * graph, QString name); + +public slots: + void collectGraph(const QString &title, const CTrendGraph &graph); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +protected slots: + void slotNewTrendEdit(); + void slotShowTrendGraph(); + void slotEditTrendEdit(); + void slotRemoveTrendEdit(); + void slotItemChanged(QTreeWidgetItem *item, int column); + void slotAddTrend(int locationId, int subSystemId, QString name); + void slotImport(); + void slotExport(); + +private: + bool isTrendNameValid(const QString& name); + QString getNewValidTitle(); + void loadTrendGraph(const QString& filePath = QString()); + void savaTrendGraph(const QString& filePath = QString()); + +private: + QMap m_trendGraphMap; + QString m_strEditItemContent; +}; + +#endif // CTRENDFAVTREEWIDGET_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendGraph.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendGraph.cpp index 32d88d73..d1fe4867 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendGraph.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendGraph.cpp @@ -1,183 +1,183 @@ -#include "CTrendGraph.h" -#include -#include "plot/qcustomplot.h" - -const double _EPSILON_ = 1e-5; - -CTrendGraph::CTrendGraph() -{ - -} - -CTrendGraph::~CTrendGraph() -{ - clear(); -} - -const QList CTrendGraph::curves() const -{ - return m_listCurve; -} - -void CTrendGraph::setCurves(QList listCurve) -{ - m_listCurve.swap(listCurve); -} - -const Curve &CTrendGraph::curve(const QString &tag) const -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - return m_listCurve.at(nIndex); - } - } - Q_ASSERT_X(false, "CTrendGraph::curve", "curve is not exists"); - -} - -int CTrendGraph::index(const QString &tag) const -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - return nIndex; - } - } - return -1; -} - -void CTrendGraph::clear() -{ - m_listCurve.clear(); -} - -void CTrendGraph::addCurve(const Curve &curve) -{ - m_listCurve.append(curve); -} - -int CTrendGraph::removeCurve(const QString &tag) -{ - for(int nIndex(m_listCurve.size() - 1); nIndex >= 0; nIndex--) - { - if(m_listCurve.at(nIndex).tag == tag) - { - m_listCurve.removeAt(nIndex); - return nIndex; - } - } - return -1; -} - -void CTrendGraph::setCurveVisible(const int &nIndex, const bool &visible) -{ - m_listCurve[nIndex].visible = visible; -} - -void CTrendGraph::setCurveColor(const int &nIndex, const QColor &color) -{ - m_listCurve[nIndex].color = color; -} - -void CTrendGraph::setCurveFactor(const int &nIndex, const double &factor) -{ - m_listCurve[nIndex].factor = factor; -} - -void CTrendGraph::setCurveOffset(const int &nIndex, const double &offset) -{ - m_listCurve[nIndex].offset = offset; -} - -void CTrendGraph::setCurveGraphFactor(const int &nIndex, const double &factor) -{ - m_listCurve[nIndex].graphFactor = factor; -} - -void CTrendGraph::setCurveGraphOffset(const int &nIndex, const double &offset) -{ - m_listCurve[nIndex].graphOffset = offset; -} - -void CTrendGraph::setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range) -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - m_listCurve[nIndex].hisMax = max; - m_listCurve[nIndex].hisMin = min; - m_listCurve[nIndex].hisAverage = average; - m_listCurve[nIndex].hisAccuml = accuml; - m_listCurve[nIndex].hisPlotRange = range; - m_listCurve[nIndex].hisMaxTime = maxTime; - m_listCurve[nIndex].hisMinTime = minTime; - } - } -} - -void CTrendGraph::pushCurveRTDataValue(const QString &tag, const double &key, const double &value) -{ - //< 保留20min实时数据 - int nIndex = m_listCurve.indexOf(tag); - if (-1 == nIndex || qIsNaN(value)) - { - return; - } - - Curve &curve = m_listCurve[nIndex]; - curve.values.append(qMakePair(key, value)); - QVector< QPair > &values = curve.values; - if (values.first().first < (key - (20 * 60 * 1000))) - { - values.removeFirst(); - } -} - -void CTrendGraph::updateRTCurveStatisticsInfo(const QString &strTagName) -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == strTagName) - { - updateRTCurveStatisticsInfo(m_listCurve[nIndex]); - return; - } - } -} - -void CTrendGraph::updateRTCurveStatisticsInfo(Curve &curve) -{ - //< 计算10min内实时数据最大值、最小值、累计值、平均值 - qreal rtMax = -DBL_MAX; - qreal rtMin = DBL_MAX; - qreal rtMaxTime = -DBL_MAX; - qreal rtMinTime = DBL_MAX; - qreal rtAccuml = 0; - int nIndex = curve.values.size(); - double validKey = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()) - (10 * 60 * 1000); - while (--nIndex >= 0 && curve.values.at(nIndex).first >= validKey) - { - if (curve.values.at(nIndex).second <= rtMin) - { - rtMin = curve.values.at(nIndex).second; - rtMinTime = curve.values.at(nIndex).first; - } - if(curve.values.at(nIndex).second >= rtMax) - { - rtMax = curve.values.at(nIndex).second; - rtMaxTime = curve.values.at(nIndex).first; - } - rtAccuml += curve.values.at(nIndex).second; - } - - curve.rtMin = rtMin; - curve.rtMax = rtMax; - curve.rtMinTime = rtMinTime; - curve.rtMaxTime = rtMaxTime; - curve.rtAccuml = rtAccuml; - curve.rtAverage = rtAccuml / (curve.values.size() - (nIndex + 1)); -} +#include "CTrendGraph.h" +#include +#include "plot/qcustomplot.h" + +const double _EPSILON_ = 1e-5; + +CTrendGraph::CTrendGraph() +{ + +} + +CTrendGraph::~CTrendGraph() +{ + clear(); +} + +const QList CTrendGraph::curves() const +{ + return m_listCurve; +} + +void CTrendGraph::setCurves(QList listCurve) +{ + m_listCurve.swap(listCurve); +} + +const Curve &CTrendGraph::curve(const QString &tag) const +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + return m_listCurve.at(nIndex); + } + } + Q_ASSERT_X(false, "CTrendGraph::curve", "curve is not exists"); + +} + +int CTrendGraph::index(const QString &tag) const +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + return nIndex; + } + } + return -1; +} + +void CTrendGraph::clear() +{ + m_listCurve.clear(); +} + +void CTrendGraph::addCurve(const Curve &curve) +{ + m_listCurve.append(curve); +} + +int CTrendGraph::removeCurve(const QString &tag) +{ + for(int nIndex(m_listCurve.size() - 1); nIndex >= 0; nIndex--) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve.removeAt(nIndex); + return nIndex; + } + } + return -1; +} + +void CTrendGraph::setCurveVisible(const int &nIndex, const bool &visible) +{ + m_listCurve[nIndex].visible = visible; +} + +void CTrendGraph::setCurveColor(const int &nIndex, const QColor &color) +{ + m_listCurve[nIndex].color = color; +} + +void CTrendGraph::setCurveFactor(const int &nIndex, const double &factor) +{ + m_listCurve[nIndex].factor = factor; +} + +void CTrendGraph::setCurveOffset(const int &nIndex, const double &offset) +{ + m_listCurve[nIndex].offset = offset; +} + +void CTrendGraph::setCurveGraphFactor(const int &nIndex, const double &factor) +{ + m_listCurve[nIndex].graphFactor = factor; +} + +void CTrendGraph::setCurveGraphOffset(const int &nIndex, const double &offset) +{ + m_listCurve[nIndex].graphOffset = offset; +} + +void CTrendGraph::setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve[nIndex].hisMax = max; + m_listCurve[nIndex].hisMin = min; + m_listCurve[nIndex].hisAverage = average; + m_listCurve[nIndex].hisAccuml = accuml; + m_listCurve[nIndex].hisPlotRange = range; + m_listCurve[nIndex].hisMaxTime = maxTime; + m_listCurve[nIndex].hisMinTime = minTime; + } + } +} + +void CTrendGraph::pushCurveRTDataValue(const QString &tag, const double &key, const double &value) +{ + //< 保留20min实时数据 + int nIndex = m_listCurve.indexOf(tag); + if (-1 == nIndex || qIsNaN(value)) + { + return; + } + + Curve &curve = m_listCurve[nIndex]; + curve.values.append(qMakePair(key, value)); + QVector< QPair > &values = curve.values; + if (values.first().first < (key - (20 * 60 * 1000))) + { + values.removeFirst(); + } +} + +void CTrendGraph::updateRTCurveStatisticsInfo(const QString &strTagName) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == strTagName) + { + updateRTCurveStatisticsInfo(m_listCurve[nIndex]); + return; + } + } +} + +void CTrendGraph::updateRTCurveStatisticsInfo(Curve &curve) +{ + //< 计算10min内实时数据最大值、最小值、累计值、平均值 + qreal rtMax = -DBL_MAX; + qreal rtMin = DBL_MAX; + qreal rtMaxTime = -DBL_MAX; + qreal rtMinTime = DBL_MAX; + qreal rtAccuml = 0; + int nIndex = curve.values.size(); + double validKey = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()) - (10 * 60 * 1000); + while (--nIndex >= 0 && curve.values.at(nIndex).first >= validKey) + { + if (curve.values.at(nIndex).second <= rtMin) + { + rtMin = curve.values.at(nIndex).second; + rtMinTime = curve.values.at(nIndex).first; + } + if(curve.values.at(nIndex).second >= rtMax) + { + rtMax = curve.values.at(nIndex).second; + rtMaxTime = curve.values.at(nIndex).first; + } + rtAccuml += curve.values.at(nIndex).second; + } + + curve.rtMin = rtMin; + curve.rtMax = rtMax; + curve.rtMinTime = rtMinTime; + curve.rtMaxTime = rtMaxTime; + curve.rtAccuml = rtAccuml; + curve.rtAverage = rtAccuml / (curve.values.size() - (nIndex + 1)); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendGraph.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendGraph.h index daec3db6..629d8d2b 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendGraph.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendGraph.h @@ -1,136 +1,136 @@ -#ifndef CTRENDGRAPH_H -#define CTRENDGRAPH_H - -#include -#include -#include -#include -#include -#include - -/******************************趋势图形************************** - * 此类包含趋势静态配置属性 - **************************************************************/ -extern const double _EPSILON_; - -struct Range -{ - Range() - : min(DBL_MAX), - max(-DBL_MAX) - {} - - Range(double _min, double _max) - : min(_min), - max(_max) - {} - double min; - double max; -}; - -struct Curve -{ - Curve(const QString &strTagName = QString()) - : visible(true), - rtMax(-DBL_MAX), - rtMin(DBL_MAX), - rtAverage(-DBL_MAX), - rtAccuml(0), - hisMax(-DBL_MAX), - hisMin(DBL_MAX), - hisAverage(-DBL_MAX), - hisAccuml(0), - graphFactor(1.), - graphOffset(0.), - factor(1.), - offset(0.), - rtMaxTime(-DBL_MAX), - rtMinTime(DBL_MAX), - hisMaxTime(-DBL_MAX), - hisMinTime(DBL_MAX), - tag(strTagName), - desc(QString()), - type(QString()), - unit(QString()), - color(QColor()){} - - inline bool operator==(const Curve &curve) const - { - return tag == curve.tag; - } - - inline bool operator==(const QString &strTagName) const - { - return tag == strTagName; - } - - bool visible; - double rtMax; - double rtMin; - double rtAverage; - double rtAccuml; - double hisMax; - double hisMin; - double hisAverage; - double hisAccuml; - double graphFactor; - double graphOffset; - double factor; - double offset; - double rtMaxTime; - double rtMinTime; - double hisMaxTime; - double hisMinTime; - - Range hisPlotRange; //< hisPlotRange > Range(hisMin, hisMax) [趋势对比计算刻度] - - QString tag; - QString desc; - QString type; - QString unit; - QColor color; - - QVector< QPair > values; -}; - -class CTrendGraph -{ -public: - CTrendGraph(); - - ~CTrendGraph(); - - const QList curves() const; - void setCurves(QList listCurve); - - const Curve &curve(const QString &tag) const; - int index(const QString &tag) const; - - void clear(); - - void addCurve(const Curve &curve); - int removeCurve(const QString &tag); - - void setCurveVisible(const int &nIndex, const bool &visible); - - void setCurveColor(const int &nIndex, const QColor &color); - void setCurveFactor(const int &nIndex, const double &factor); - void setCurveOffset(const int &nIndex, const double &offset); - - void setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range); - void pushCurveRTDataValue(const QString &tag, const double &key, const double &value); - - void setCurveGraphFactor(const int &nIndex, const double &factor); - void setCurveGraphOffset(const int &nIndex, const double &offset); - - //< 更新实时曲线统计信息 - void updateRTCurveStatisticsInfo(const QString &strTagName); - void updateRTCurveStatisticsInfo(Curve &curve); - -private: - QList m_listCurve; -}; - -#endif // CTRENDGRAPH_H - - +#ifndef CTRENDGRAPH_H +#define CTRENDGRAPH_H + +#include +#include +#include +#include +#include +#include + +/******************************趋势图形************************** + * 此类包含趋势静态配置属性 + **************************************************************/ +extern const double _EPSILON_; + +struct Range +{ + Range() + : min(DBL_MAX), + max(-DBL_MAX) + {} + + Range(double _min, double _max) + : min(_min), + max(_max) + {} + double min; + double max; +}; + +struct Curve +{ + Curve(const QString &strTagName = QString()) + : visible(true), + rtMax(-DBL_MAX), + rtMin(DBL_MAX), + rtAverage(-DBL_MAX), + rtAccuml(0), + hisMax(-DBL_MAX), + hisMin(DBL_MAX), + hisAverage(-DBL_MAX), + hisAccuml(0), + graphFactor(1.), + graphOffset(0.), + factor(1.), + offset(0.), + rtMaxTime(-DBL_MAX), + rtMinTime(DBL_MAX), + hisMaxTime(-DBL_MAX), + hisMinTime(DBL_MAX), + tag(strTagName), + desc(QString()), + type(QString()), + unit(QString()), + color(QColor()){} + + inline bool operator==(const Curve &curve) const + { + return tag == curve.tag; + } + + inline bool operator==(const QString &strTagName) const + { + return tag == strTagName; + } + + bool visible; + double rtMax; + double rtMin; + double rtAverage; + double rtAccuml; + double hisMax; + double hisMin; + double hisAverage; + double hisAccuml; + double graphFactor; + double graphOffset; + double factor; + double offset; + double rtMaxTime; + double rtMinTime; + double hisMaxTime; + double hisMinTime; + + Range hisPlotRange; //< hisPlotRange > Range(hisMin, hisMax) [趋势对比计算刻度] + + QString tag; + QString desc; + QString type; + QString unit; + QColor color; + + QVector< QPair > values; +}; + +class CTrendGraph +{ +public: + CTrendGraph(); + + ~CTrendGraph(); + + const QList curves() const; + void setCurves(QList listCurve); + + const Curve &curve(const QString &tag) const; + int index(const QString &tag) const; + + void clear(); + + void addCurve(const Curve &curve); + int removeCurve(const QString &tag); + + void setCurveVisible(const int &nIndex, const bool &visible); + + void setCurveColor(const int &nIndex, const QColor &color); + void setCurveFactor(const int &nIndex, const double &factor); + void setCurveOffset(const int &nIndex, const double &offset); + + void setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range); + void pushCurveRTDataValue(const QString &tag, const double &key, const double &value); + + void setCurveGraphFactor(const int &nIndex, const double &factor); + void setCurveGraphOffset(const int &nIndex, const double &offset); + + //< 更新实时曲线统计信息 + void updateRTCurveStatisticsInfo(const QString &strTagName); + void updateRTCurveStatisticsInfo(Curve &curve); + +private: + QList m_listCurve; +}; + +#endif // CTRENDGRAPH_H + + diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendInfoManage.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendInfoManage.cpp index 955ffbc8..65eb12f9 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendInfoManage.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendInfoManage.cpp @@ -1,491 +1,491 @@ -#include "CTrendInfoManage.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_dbms; - -CTrendInfoManage *CTrendInfoManage::m_pInstance = NULL; - -CTrendInfoManage *CTrendInfoManage::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CTrendInfoManage(); - } - return m_pInstance; -} - -CTrendInfoManage::CTrendInfoManage() -{ - //< 关系库 - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - if(!m_pReadDb->open()) - { - LOGERROR("打开数据库连接失败! %s", m_pReadDb->getLastErrorString().toStdString().c_str()); - } - - //< 实时库 - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - m_listTagInfo.reserve(5000); - - loadUnit(); - loadRTLocation(); - loadRTSubsystem(); - loadDevGroupInfo(); - loadDeviceInfo(); - loadTagInfo(); - loadStateDefine(); -} - -void CTrendInfoManage::destory() -{ - if(m_pReadDb != NULL) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - m_listTagUnit.clear(); - m_locationInfo.clear(); - m_subSystemInfo.clear(); - m_devGroupInfo.clear(); - m_devLocation.clear(); - m_deviceInfo.clear(); - m_listTagInfo.clear(); - m_listTagName.clear(); - m_pInstance = NULL; - delete this; -} - -QMap CTrendInfoManage::locationInfo() -{ - return m_locationInfo; -} - -QMap CTrendInfoManage::subSystemInfo() -{ - return m_subSystemInfo; -} - -QMap CTrendInfoManage::devGroupInfo(const int &location) -{ - return m_devGroupInfo.value(location, QMap()); -} - -QMap CTrendInfoManage::deviceInfo(const QString &devGroupName) -{ - return m_deviceInfo.value(devGroupName, QMap()); -} - -QStringList CTrendInfoManage::queryTagListDevGroup(const QString &devGroup) -{ - QStringList tagList = QStringList(); - QMap devMap = m_deviceInfo.value(devGroup); - if(devMap.isEmpty()) - { - return tagList; - } - QStringList deviceList = devMap.keys(); - foreach (QString device, deviceList) { - tagList.append(m_listTagName.value(device, QStringList())); - } - return tagList; -} - -QStringList CTrendInfoManage::queryTagList(const QString &device) -{ - QStringList result = m_listTagName.value(device, QStringList()); - for(int nIndex = 0; nIndex < result.length(); ++nIndex) - { - if(getTagType(result.at(nIndex)) == "digital") - { - result.removeAt(nIndex); - nIndex--; - } - } - return result; -} - -QString CTrendInfoManage::queryDeviceGroup(const QString &device) -{ - QMap >::const_iterator iter = m_deviceInfo.begin(); - for(; iter != m_deviceInfo.end(); ++iter) - { - QStringList deviceList = iter.value().keys(); - if(deviceList.indexOf(device) != -1) - { - return iter.key(); - } - } - return QString(); -} - -QString CTrendInfoManage::getTagDescription(const QString &tag) -{ - QStringList values = m_listTagInfo.value(tag, QStringList()); - if(values.isEmpty()) - { - return QString(); - } - return values.at(0); -} - -QString CTrendInfoManage::getTagType(const QString &tag) -{ - QStringList values = m_listTagInfo.value(tag, QStringList()); - if(values.isEmpty()) - { - return QString(); - } - return values.at(1); -} - -QString CTrendInfoManage::getTagUnit(const QString &tag) -{ - QStringList values = m_listTagInfo.value(tag, QStringList()); - if(values.isEmpty()) - { - return QString(); - } - return values.at(2); -} - -QString CTrendInfoManage::getLocationDesc(int id) -{ - return m_locationInfo.value(id, QString()); -} - -QString CTrendInfoManage::getSubSystemDesc(int id) -{ - return m_subSystemInfo.value(id, QString()); -} - -bool CTrendInfoManage::checkTrendEditPerm() -{ - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return false; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - if(0 == permMngPtr->PermDllInit()) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - std::string strTendEdit = "FUNC_NOM_TREND_EDIT"; - if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &strTendEdit)) - { - return true; - } - } - return false; -} - -int CTrendInfoManage::getStateActualValue(const QString &state) -{ - if(state.isEmpty()) - { - return 0; - } - return m_menuState.value(state); -} - -void CTrendInfoManage::reloadData() -{ - m_devGroupInfo.clear(); - m_devLocation.clear(); - m_deviceInfo.clear(); - m_listTagInfo.clear(); - m_listTagName.clear(); - - loadDevGroupInfo(); - loadDeviceInfo(); - loadTagInfo(); -} - -void CTrendInfoManage::loadRTLocation() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return; - } - int level; - std::vector vecLocationId; - std::vector vecPermPic; - if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) - { - LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); - return; - } - - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - QPair id_value; - id_value.first = "location_id"; - id_value.second = "description"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back(id_value.first); - columns.push_back(id_value.second); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - m_locationInfo.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - - std::vector ::const_iterator it = vecLocationId.cbegin(); - while (it != vecLocationId.cend()) - { - if(key.toInt() == *it) - { - m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); - } - ++it; - } - } - } - } -} - -void CTrendInfoManage::loadRTSubsystem() -{ - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_sub_system_info"; - QPair id_value; - id_value.first = "sub_system_id"; - id_value.second = "description"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back(id_value.first); - columns.push_back(id_value.second); - - if(m_rtdbAccess->select(result, columns)) - { - m_subSystemInfo.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_subSystemInfo[key.toInt()] = QString::fromStdString(value.toStdString()); - } - m_subSystemInfo.remove(1); - m_subSystemInfo.remove(2); - m_subSystemInfo.remove(3); - } - } -} - -void CTrendInfoManage::loadDevGroupInfo() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QSqlQuery query; - - QString strLoctionFilter; - if(!m_locationInfo.keys().isEmpty()) - { - QStringList listLocation; - foreach (int nLocationID, m_locationInfo.keys()) - { - listLocation.append(QString::number(nLocationID)); - } - strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); - } - QString sqlSequenceQuery = QString("select tag_name, description, location_id from dev_group"); - if(!strLoctionFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" where %1;").arg(strLoctionFilter)); - } - m_pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - m_devGroupInfo[query.value(2).toInt()].insert(query.value(0).toString(), query.value(1).toString()); - } - return; -} - -void CTrendInfoManage::loadDeviceInfo() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QSqlQuery query; - - QString strLoctionFilter; - QList > listDevGroup = m_devGroupInfo.values(); - if(!listDevGroup.isEmpty()) - { - QStringList listLocation; - for(int i=0; iexecute(sqlSequenceQuery, query); - while(query.next()) - { - m_deviceInfo[query.value(2).toString()].insert(query.value(0).toString(), query.value(1).toString()); - m_devLocation[query.value(3).toInt()].insert(query.value(0).toString(), query.value(1).toString()); - } - return; -} - -void CTrendInfoManage::loadTagInfo() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QSqlQuery query; - QStringList listType; - listType.append(QString("analog")); - listType.append(QString("digital")); - listType.append(QString("accuml")); - // listType.append(QString("mix")); - QString strDeviceFilter; - if(!m_deviceInfo.isEmpty()) - { - QStringList listDevice; - QMap >::const_iterator iter = m_deviceInfo.constBegin(); - while (iter != m_deviceInfo.constEnd()) - { - listDevice.append(iter.value().keys()); - ++iter; - } - strDeviceFilter = "'" + listDevice.join("', '") + "'"; - strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); - } - - for(int nIndex(0); nIndex < listType.size(); nIndex++) - { - QString strUnitField = QString(); - if(QString("analog") == listType.at(nIndex)) - { - strUnitField = QString(", t1.unit_id "); - } - QString sqlSequenceQuery = - QString("SELECT t2.group_tag_name, t1.tag_name, t1.description, t1.device, t1.location_id %1 \ -FROM %2 as t1 left join dev_info as t2 on t1.device = t2.tag_name").arg(strUnitField).arg(listType.at(nIndex)); - if(!strDeviceFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" WHERE %1;").arg(strDeviceFilter)); - } - - m_pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - const QString group = query.value(0).toString(); - const QString tagName = query.value(1).toString(); - const QString tagDesc = query.value(2).toString(); - const QString device = query.value(3).toString(); - int location = query.value(4).toInt(); - const QString strDescription = m_locationInfo.value(location) + "." + m_devGroupInfo[location].value(group) + "." + m_devLocation[location].value(device) + "." + tagDesc; - m_listTagName[device].append(tagName); - QString strUnitDesc = QString(); - if(query.value(5).isValid()) - { - strUnitDesc = m_listTagUnit.value(query.value(5).toInt(), QString()); - } - m_listTagInfo.insert(tagName, QStringList() << strDescription << listType.at(nIndex) << strUnitDesc); - } - } - return; -} - -void CTrendInfoManage::loadUnit() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QSqlQuery query; - QString sqlSequenceQuery = QString("select unit_id, unit_name from dict_unit_info"); - m_pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - m_listTagUnit.insert(query.value(0).toInt(), query.value(1).toString()); - } - return; -} - -void CTrendInfoManage::loadStateDefine() -{ - if(m_rtdbAccess->open("base", "dict_menu_info")) - { - CONDINFO conditionAI; - memcpy(conditionAI.name, "menu_macro_name", strlen("menu_macro_name")); - conditionAI.logicalop = ATTRCOND_OR; - conditionAI.relationop = ATTRCOND_EQU; - conditionAI.conditionval = MENU_STATE_AI_INVALID; - - CONDINFO conditionDI; - memcpy(conditionDI.name, "menu_macro_name", strlen("menu_macro_name")); - conditionDI.logicalop = ATTRCOND_OR; - conditionDI.relationop = ATTRCOND_EQU; - conditionDI.conditionval = MENU_STATE_DI_INVALID; - - std::vector vecCondInfo; - vecCondInfo.push_back(conditionAI); - vecCondInfo.push_back(conditionDI); - - CRdbQueryResult result; - std::vector columns; - columns.push_back("menu_macro_name"); - columns.push_back("actual_value"); - if(m_rtdbAccess->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType name; - CVarType value; - result.getColumnValue(nIndex, 0, name); - result.getColumnValue(nIndex, 1, value); - m_menuState.insert(QString::fromStdString(name.toStdString()), value.toInt()); - } - } - } - - m_rtdbAccess->close(); -} - +#include "CTrendInfoManage.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" + +using namespace kbd_dbms; + +CTrendInfoManage *CTrendInfoManage::m_pInstance = NULL; + +CTrendInfoManage *CTrendInfoManage::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CTrendInfoManage(); + } + return m_pInstance; +} + +CTrendInfoManage::CTrendInfoManage() +{ + //< 关系库 + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + LOGERROR("打开数据库连接失败! %s", m_pReadDb->getLastErrorString().toStdString().c_str()); + } + + //< 实时库 + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + m_listTagInfo.reserve(5000); + + loadUnit(); + loadRTLocation(); + loadRTSubsystem(); + loadDevGroupInfo(); + loadDeviceInfo(); + loadTagInfo(); + loadStateDefine(); +} + +void CTrendInfoManage::destory() +{ + if(m_pReadDb != NULL) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_listTagUnit.clear(); + m_locationInfo.clear(); + m_subSystemInfo.clear(); + m_devGroupInfo.clear(); + m_devLocation.clear(); + m_deviceInfo.clear(); + m_listTagInfo.clear(); + m_listTagName.clear(); + m_pInstance = NULL; + delete this; +} + +QMap CTrendInfoManage::locationInfo() +{ + return m_locationInfo; +} + +QMap CTrendInfoManage::subSystemInfo() +{ + return m_subSystemInfo; +} + +QMap CTrendInfoManage::devGroupInfo(const int &location) +{ + return m_devGroupInfo.value(location, QMap()); +} + +QMap CTrendInfoManage::deviceInfo(const QString &devGroupName) +{ + return m_deviceInfo.value(devGroupName, QMap()); +} + +QStringList CTrendInfoManage::queryTagListDevGroup(const QString &devGroup) +{ + QStringList tagList = QStringList(); + QMap devMap = m_deviceInfo.value(devGroup); + if(devMap.isEmpty()) + { + return tagList; + } + QStringList deviceList = devMap.keys(); + foreach (QString device, deviceList) { + tagList.append(m_listTagName.value(device, QStringList())); + } + return tagList; +} + +QStringList CTrendInfoManage::queryTagList(const QString &device) +{ + QStringList result = m_listTagName.value(device, QStringList()); + for(int nIndex = 0; nIndex < result.length(); ++nIndex) + { + if(getTagType(result.at(nIndex)) == "digital") + { + result.removeAt(nIndex); + nIndex--; + } + } + return result; +} + +QString CTrendInfoManage::queryDeviceGroup(const QString &device) +{ + QMap >::const_iterator iter = m_deviceInfo.begin(); + for(; iter != m_deviceInfo.end(); ++iter) + { + QStringList deviceList = iter.value().keys(); + if(deviceList.indexOf(device) != -1) + { + return iter.key(); + } + } + return QString(); +} + +QString CTrendInfoManage::getTagDescription(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(0); +} + +QString CTrendInfoManage::getTagType(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(1); +} + +QString CTrendInfoManage::getTagUnit(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(2); +} + +QString CTrendInfoManage::getLocationDesc(int id) +{ + return m_locationInfo.value(id, QString()); +} + +QString CTrendInfoManage::getSubSystemDesc(int id) +{ + return m_subSystemInfo.value(id, QString()); +} + +bool CTrendInfoManage::checkTrendEditPerm() +{ + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + if(0 == permMngPtr->PermDllInit()) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string strTendEdit = "FUNC_NOM_TREND_EDIT"; + if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &strTendEdit)) + { + return true; + } + } + return false; +} + +int CTrendInfoManage::getStateActualValue(const QString &state) +{ + if(state.isEmpty()) + { + return 0; + } + return m_menuState.value(state); +} + +void CTrendInfoManage::reloadData() +{ + m_devGroupInfo.clear(); + m_devLocation.clear(); + m_deviceInfo.clear(); + m_listTagInfo.clear(); + m_listTagName.clear(); + + loadDevGroupInfo(); + loadDeviceInfo(); + loadTagInfo(); +} + +void CTrendInfoManage::loadRTLocation() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + int level; + std::vector vecLocationId; + std::vector vecPermPic; + if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) + { + LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); + return; + } + + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + QPair id_value; + id_value.first = "location_id"; + id_value.second = "description"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back(id_value.first); + columns.push_back(id_value.second); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + m_locationInfo.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + std::vector ::const_iterator it = vecLocationId.cbegin(); + while (it != vecLocationId.cend()) + { + if(key.toInt() == *it) + { + m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); + } + ++it; + } + } + } + } +} + +void CTrendInfoManage::loadRTSubsystem() +{ + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_sub_system_info"; + QPair id_value; + id_value.first = "sub_system_id"; + id_value.second = "description"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back(id_value.first); + columns.push_back(id_value.second); + + if(m_rtdbAccess->select(result, columns)) + { + m_subSystemInfo.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_subSystemInfo[key.toInt()] = QString::fromStdString(value.toStdString()); + } + m_subSystemInfo.remove(1); + m_subSystemInfo.remove(2); + m_subSystemInfo.remove(3); + } + } +} + +void CTrendInfoManage::loadDevGroupInfo() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QSqlQuery query; + + QString strLoctionFilter; + if(!m_locationInfo.keys().isEmpty()) + { + QStringList listLocation; + foreach (int nLocationID, m_locationInfo.keys()) + { + listLocation.append(QString::number(nLocationID)); + } + strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); + } + QString sqlSequenceQuery = QString("select tag_name, description, location_id from dev_group"); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" where %1;").arg(strLoctionFilter)); + } + m_pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + m_devGroupInfo[query.value(2).toInt()].insert(query.value(0).toString(), query.value(1).toString()); + } + return; +} + +void CTrendInfoManage::loadDeviceInfo() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QSqlQuery query; + + QString strLoctionFilter; + QList > listDevGroup = m_devGroupInfo.values(); + if(!listDevGroup.isEmpty()) + { + QStringList listLocation; + for(int i=0; iexecute(sqlSequenceQuery, query); + while(query.next()) + { + m_deviceInfo[query.value(2).toString()].insert(query.value(0).toString(), query.value(1).toString()); + m_devLocation[query.value(3).toInt()].insert(query.value(0).toString(), query.value(1).toString()); + } + return; +} + +void CTrendInfoManage::loadTagInfo() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QSqlQuery query; + QStringList listType; + listType.append(QString("analog")); + listType.append(QString("digital")); + listType.append(QString("accuml")); + // listType.append(QString("mix")); + QString strDeviceFilter; + if(!m_deviceInfo.isEmpty()) + { + QStringList listDevice; + QMap >::const_iterator iter = m_deviceInfo.constBegin(); + while (iter != m_deviceInfo.constEnd()) + { + listDevice.append(iter.value().keys()); + ++iter; + } + strDeviceFilter = "'" + listDevice.join("', '") + "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); + } + + for(int nIndex(0); nIndex < listType.size(); nIndex++) + { + QString strUnitField = QString(); + if(QString("analog") == listType.at(nIndex)) + { + strUnitField = QString(", t1.unit_id "); + } + QString sqlSequenceQuery = + QString("SELECT t2.group_tag_name, t1.tag_name, t1.description, t1.device, t1.location_id %1 \ +FROM %2 as t1 left join dev_info as t2 on t1.device = t2.tag_name").arg(strUnitField).arg(listType.at(nIndex)); + if(!strDeviceFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" WHERE %1;").arg(strDeviceFilter)); + } + + m_pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + const QString group = query.value(0).toString(); + const QString tagName = query.value(1).toString(); + const QString tagDesc = query.value(2).toString(); + const QString device = query.value(3).toString(); + int location = query.value(4).toInt(); + const QString strDescription = m_locationInfo.value(location) + "." + m_devGroupInfo[location].value(group) + "." + m_devLocation[location].value(device) + "." + tagDesc; + m_listTagName[device].append(tagName); + QString strUnitDesc = QString(); + if(query.value(5).isValid()) + { + strUnitDesc = m_listTagUnit.value(query.value(5).toInt(), QString()); + } + m_listTagInfo.insert(tagName, QStringList() << strDescription << listType.at(nIndex) << strUnitDesc); + } + } + return; +} + +void CTrendInfoManage::loadUnit() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QSqlQuery query; + QString sqlSequenceQuery = QString("select unit_id, unit_name from dict_unit_info"); + m_pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + m_listTagUnit.insert(query.value(0).toInt(), query.value(1).toString()); + } + return; +} + +void CTrendInfoManage::loadStateDefine() +{ + if(m_rtdbAccess->open("base", "dict_menu_info")) + { + CONDINFO conditionAI; + memcpy(conditionAI.name, "menu_macro_name", strlen("menu_macro_name")); + conditionAI.logicalop = ATTRCOND_OR; + conditionAI.relationop = ATTRCOND_EQU; + conditionAI.conditionval = MENU_STATE_AI_INVALID; + + CONDINFO conditionDI; + memcpy(conditionDI.name, "menu_macro_name", strlen("menu_macro_name")); + conditionDI.logicalop = ATTRCOND_OR; + conditionDI.relationop = ATTRCOND_EQU; + conditionDI.conditionval = MENU_STATE_DI_INVALID; + + std::vector vecCondInfo; + vecCondInfo.push_back(conditionAI); + vecCondInfo.push_back(conditionDI); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("menu_macro_name"); + columns.push_back("actual_value"); + if(m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType name; + CVarType value; + result.getColumnValue(nIndex, 0, name); + result.getColumnValue(nIndex, 1, value); + m_menuState.insert(QString::fromStdString(name.toStdString()), value.toInt()); + } + } + } + + m_rtdbAccess->close(); +} + diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendInfoManage.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendInfoManage.h index 8e261438..e05a3ecd 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendInfoManage.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendInfoManage.h @@ -1,80 +1,80 @@ -#ifndef CTRENDINFOMANAGE_H -#define CTRENDINFOMANAGE_H - -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/db_api_ex/CDbApi.h" - -#define FUNC_NOM_TREND_EDIT "FUNC_NOM_TREND_EDIT" - -//< 状态字定义 -#define MENU_STATE_DI_INVALID ("MENU_STATE_DI_INVALID") //< 数字量无效 -#define MENU_STATE_AI_INVALID ("MENU_STATE_AI_INVALID") //< 模拟量无效 - -class CTrendInfoManage -{ -public: - static CTrendInfoManage * instance(); - - void destory(); - - QMap locationInfo(); - - QMap subSystemInfo(); - - QMap devGroupInfo(const int& location); //新增设备组 - - QMap deviceInfo(const QString &devGroupName); //新增设备组时修改 - - QStringList queryTagListDevGroup(const QString &devGroup); - - QStringList queryTagList(const QString &device); - - QString queryDeviceGroup(const QString &device); - - QString getTagDescription(const QString &tag); - - QString getTagType(const QString &tag); - - QString getTagUnit(const QString &tag); - - QString getLocationDesc(int id); - - QString getSubSystemDesc(int id); - - bool checkTrendEditPerm(); - - int getStateActualValue(const QString &state); - - void reloadData(); - -private: - CTrendInfoManage(); - - void loadRTLocation(); - void loadRTSubsystem(); - void loadDevGroupInfo(); //新增设备组 - void loadDeviceInfo(); //新增设备组时修改 - void loadTagInfo(); - void loadUnit(); - void loadStateDefine(); - -private: - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccess * m_rtdbAccess; - QMap m_subSystemInfo; - QMap m_locationInfo; //< LocationID-LocationDesc - QMap > m_devGroupInfo; //< LocationID- 新增设备组 - QMap > m_devLocation; //< LocationID- 新增设备组 - QMap > m_deviceInfo; //< DevGroupName- 新增设备组时修改 - QMap m_listTagName; //< DeviceName-list - - QHash m_listTagInfo; //< TagName-TagInfo - QMap m_listTagUnit; - QMap m_menuState; - static CTrendInfoManage * m_pInstance; - -}; - -#endif // CTRENDINFOMANAGE_H +#ifndef CTRENDINFOMANAGE_H +#define CTRENDINFOMANAGE_H + +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" + +#define FUNC_NOM_TREND_EDIT "FUNC_NOM_TREND_EDIT" + +//< 状态字定义 +#define MENU_STATE_DI_INVALID ("MENU_STATE_DI_INVALID") //< 数字量无效 +#define MENU_STATE_AI_INVALID ("MENU_STATE_AI_INVALID") //< 模拟量无效 + +class CTrendInfoManage +{ +public: + static CTrendInfoManage * instance(); + + void destory(); + + QMap locationInfo(); + + QMap subSystemInfo(); + + QMap devGroupInfo(const int& location); //新增设备组 + + QMap deviceInfo(const QString &devGroupName); //新增设备组时修改 + + QStringList queryTagListDevGroup(const QString &devGroup); + + QStringList queryTagList(const QString &device); + + QString queryDeviceGroup(const QString &device); + + QString getTagDescription(const QString &tag); + + QString getTagType(const QString &tag); + + QString getTagUnit(const QString &tag); + + QString getLocationDesc(int id); + + QString getSubSystemDesc(int id); + + bool checkTrendEditPerm(); + + int getStateActualValue(const QString &state); + + void reloadData(); + +private: + CTrendInfoManage(); + + void loadRTLocation(); + void loadRTSubsystem(); + void loadDevGroupInfo(); //新增设备组 + void loadDeviceInfo(); //新增设备组时修改 + void loadTagInfo(); + void loadUnit(); + void loadStateDefine(); + +private: + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccess * m_rtdbAccess; + QMap m_subSystemInfo; + QMap m_locationInfo; //< LocationID-LocationDesc + QMap > m_devGroupInfo; //< LocationID- 新增设备组 + QMap > m_devLocation; //< LocationID- 新增设备组 + QMap > m_deviceInfo; //< DevGroupName- 新增设备组时修改 + QMap m_listTagName; //< DeviceName-list + + QHash m_listTagInfo; //< TagName-TagInfo + QMap m_listTagUnit; + QMap m_menuState; + static CTrendInfoManage * m_pInstance; + +}; + +#endif // CTRENDINFOMANAGE_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.cpp index b009975b..b857fe30 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CTrendPluginWidget.h" -#include "CTrendWindow.h" - -CTrendPluginWidget::CTrendPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CTrendPluginWidget::~CTrendPluginWidget() -{ - -} - -bool CTrendPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CTrendWindow *pWidget = new CTrendWindow(editMode, ptrVec, parent); - pWidget->initialize(E_Trend_Window); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CTrendPluginWidget::release() -{ - -} +#include +#include "CTrendPluginWidget.h" +#include "CTrendWindow.h" + +CTrendPluginWidget::CTrendPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CTrendPluginWidget::~CTrendPluginWidget() +{ + +} + +bool CTrendPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CTrendWindow *pWidget = new CTrendWindow(editMode, ptrVec, parent); + pWidget->initialize(E_Trend_Window); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CTrendPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.h index f469158c..620317a8 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CTRENDPLUGINWIDGET_H -#define CTRENDPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CTrendPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CTrendPluginWidget(QObject *parent = 0); - ~CTrendPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif //CTRENDPLUGINWIDGET_H - +#ifndef CTRENDPLUGINWIDGET_H +#define CTRENDPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CTrendPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CTrendPluginWidget(QObject *parent = 0); + ~CTrendPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif //CTRENDPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeItem.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeItem.cpp index 7b41fa9e..a4946827 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeItem.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeItem.cpp @@ -1,114 +1,114 @@ -#include -#include "CTrendTreeItem.h" - -CTrendTreeItem::CTrendTreeItem(int type) - : m_parentItem(Q_NULLPTR), - m_data(QString()), - m_tag(QString()), - m_type(type), - m_checkState(Qt::Unchecked) -{ - -} - -CTrendTreeItem::CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type) - : m_parentItem(parent), - m_data(data), - m_tag(QString()), - m_type(type), - m_checkState(Qt::Unchecked) -{ - if(m_parentItem) - { - m_parentItem->m_childItems.append(this); - } -} - -CTrendTreeItem::~CTrendTreeItem() -{ - qDeleteAll(m_childItems); - m_childItems.clear(); -} - -int CTrendTreeItem::type() const -{ - return m_type; -} - -int CTrendTreeItem::indexOfChild(const CTrendTreeItem *item) const -{ - for(int nIndex(0); nIndex < m_childItems.size(); ++nIndex) - { - if(item == m_childItems[nIndex]) - { - return nIndex; - } - } - return -1; -} - -CTrendTreeItem *CTrendTreeItem::child(int row) const -{ - return m_childItems.value(row); -} - -CTrendTreeItem *CTrendTreeItem::parent() const -{ - return m_parentItem; -} - -int CTrendTreeItem::row() const -{ - if (m_parentItem) - { - return m_parentItem->m_childItems.indexOf(const_cast(this)); - } - - return 0; -} - -int CTrendTreeItem::childCount() const -{ - return m_childItems.count(); -} - -int CTrendTreeItem::columnCount() const -{ - return 1; -} - -QVariant CTrendTreeItem::data(Qt::ItemDataRole role) const -{ - if(Qt::DisplayRole == role) - { - return m_data; - } - else if(Qt::UserRole == role) - { - return m_tag; - } - else if(Qt::CheckStateRole == role) - { - return m_checkState; - } -} - -bool CTrendTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) -{ - if(Qt::DisplayRole == role) - { - m_data = value.toString(); - return true; - } - else if(Qt::UserRole == role) - { - m_tag = value.toString(); - return true; - } - else if(Qt::CheckStateRole == role) - { - m_checkState = (Qt::CheckState)value.toInt(); - return true; - } - return false; -} +#include +#include "CTrendTreeItem.h" + +CTrendTreeItem::CTrendTreeItem(int type) + : m_parentItem(Q_NULLPTR), + m_data(QString()), + m_tag(QString()), + m_type(type), + m_checkState(Qt::Unchecked) +{ + +} + +CTrendTreeItem::CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type) + : m_parentItem(parent), + m_data(data), + m_tag(QString()), + m_type(type), + m_checkState(Qt::Unchecked) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } +} + +CTrendTreeItem::~CTrendTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +int CTrendTreeItem::type() const +{ + return m_type; +} + +int CTrendTreeItem::indexOfChild(const CTrendTreeItem *item) const +{ + for(int nIndex(0); nIndex < m_childItems.size(); ++nIndex) + { + if(item == m_childItems[nIndex]) + { + return nIndex; + } + } + return -1; +} + +CTrendTreeItem *CTrendTreeItem::child(int row) const +{ + return m_childItems.value(row); +} + +CTrendTreeItem *CTrendTreeItem::parent() const +{ + return m_parentItem; +} + +int CTrendTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CTrendTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CTrendTreeItem::columnCount() const +{ + return 1; +} + +QVariant CTrendTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::UserRole == role) + { + return m_tag; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } +} + +bool CTrendTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::UserRole == role) + { + m_tag = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + return false; +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeItem.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeItem.h index 4c9fb606..b172400a 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeItem.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeItem.h @@ -1,98 +1,98 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CTRENDTREEITEM_H -#define CTRENDTREEITEM_H - -#include -#include - -enum NodeType -{ - ROOT_TYPE = 10000, - LOCATION_TYPE, - DEV_TYPE, - TAG_TYPE -}; - -class CTrendTreeItem -{ -public: - CTrendTreeItem(int type); - CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type); - ~CTrendTreeItem(); - - int type() const; - - int indexOfChild(const CTrendTreeItem * item) const; - - CTrendTreeItem *child(int row) const; - CTrendTreeItem *parent() const; - - int row() const; - - int childCount() const; - int columnCount() const; - - QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; - bool setData(const QVariant &value, Qt::ItemDataRole role); - -private: - CTrendTreeItem *m_parentItem; - QString m_data; - QString m_tag; - int m_type; - Qt::CheckState m_checkState; - - QList m_childItems; - -}; - -#endif // CTRENDTREEITEM_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CTRENDTREEITEM_H +#define CTRENDTREEITEM_H + +#include +#include + +enum NodeType +{ + ROOT_TYPE = 10000, + LOCATION_TYPE, + DEV_TYPE, + TAG_TYPE +}; + +class CTrendTreeItem +{ +public: + CTrendTreeItem(int type); + CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type); + ~CTrendTreeItem(); + + int type() const; + + int indexOfChild(const CTrendTreeItem * item) const; + + CTrendTreeItem *child(int row) const; + CTrendTreeItem *parent() const; + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + +private: + CTrendTreeItem *m_parentItem; + QString m_data; + QString m_tag; + int m_type; + Qt::CheckState m_checkState; + + QList m_childItems; + +}; + +#endif // CTRENDTREEITEM_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeModel.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeModel.cpp index c3240216..4f478563 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeModel.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeModel.cpp @@ -1,407 +1,407 @@ -#include "CTrendTreeModel.h" -#include "CTrendInfoManage.h" -#include - -const int ItemTagRole = Qt::UserRole + 1; - -CTrendTreeModel::CTrendTreeModel(QObject *parent, QTreeView *view) - : QAbstractItemModel(parent), - m_pView(view), - m_rootItem(Q_NULLPTR) -{ - QTimer::singleShot(300, this, [=](){initTrendTagInfo();}); -} - -CTrendTreeModel::~CTrendTreeModel() -{ - if(Q_NULLPTR != m_rootItem) - { - delete m_rootItem; - } - m_rootItem = Q_NULLPTR; -} - - -void CTrendTreeModel::initTrendTagInfo() -{ - beginResetModel(); - - if(Q_NULLPTR != m_rootItem) - { - delete m_rootItem; - } - m_rootItem = new QTreeWidgetItem(ROOT_TYPE); - - //< load location - QMap locationInfo = CTrendInfoManage::instance()->locationInfo(); - QMap::const_iterator iter_location = locationInfo.constBegin(); - while (iter_location != locationInfo.constEnd()) - { - //< load deviceGroup - QMap devGroupInfo = CTrendInfoManage::instance()->devGroupInfo(iter_location.key()); - if(devGroupInfo.isEmpty()) - { - ++iter_location; - continue; - } - QTreeWidgetItem * locationItem = new QTreeWidgetItem(m_rootItem, QStringList() << iter_location.value(), LOCATION_TYPE); - locationItem->setData(0, ItemTagRole, iter_location.key()); - QMap::const_iterator iter_devGroup = devGroupInfo.constBegin(); - while (iter_devGroup != devGroupInfo.constEnd()) - { - //< load device - QMap devInfo = CTrendInfoManage::instance()->deviceInfo(iter_devGroup.key()); - if(devInfo.isEmpty()) - { - ++iter_devGroup; - continue; - } - QMap::const_iterator iter_device = devInfo.constBegin(); - while (iter_device != devInfo.constEnd()) - { - //< load tag - QStringList listTagName = CTrendInfoManage::instance()->queryTagList(iter_device.key()); - if(listTagName.isEmpty()) - { - ++iter_device; - continue; - } - QTreeWidgetItem * devGroupItem = new QTreeWidgetItem(locationItem, QStringList() << iter_devGroup.value(), DEV_GROUP_TYPE); - devGroupItem->setData(0, ItemTagRole, iter_devGroup.key()); - QTreeWidgetItem * devItem = new QTreeWidgetItem(devGroupItem, QStringList() << iter_device.value(), DEV_TYPE); - devItem->setData(0, ItemTagRole, iter_device.key()); - QStringList::const_iterator iter_tag = listTagName.constBegin(); - while (iter_tag != listTagName.constEnd()) - { - QTreeWidgetItem * tagItem = new QTreeWidgetItem(devItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); - tagItem->setData(0, ItemTagRole, *iter_tag); - tagItem->setToolTip(0, *iter_tag); - ++iter_tag; - } - ++iter_device; - } - - ++iter_devGroup; - } - - ++iter_location; - } - - endResetModel(); -} - -void CTrendTreeModel::clearTrendTagInfo() -{ - CTrendInfoManage::instance()->destory(); - beginResetModel(); - if(Q_NULLPTR != m_rootItem) - { - delete m_rootItem; - } - m_rootItem = Q_NULLPTR; - endResetModel(); -} - -QVariant CTrendTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(section) - Q_UNUSED(orientation) - Q_UNUSED(role) - return QVariant(); -} - -QModelIndex CTrendTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) - { - return QModelIndex(); - } - - QTreeWidgetItem * parentItem; - if(!parent.isValid()) - { - parentItem = m_rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - if(parentItem) - { - QTreeWidgetItem *childItem = parentItem->child(row); - if(childItem) - { - return createIndex(row,0,childItem); - } - } - - return QModelIndex(); -} - -QModelIndex CTrendTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - QTreeWidgetItem *childItem = static_cast(index.internalPointer()); - if (!childItem) - { - return QModelIndex(); - } - - QTreeWidgetItem *parentItem = childItem->parent(); - - if (parentItem == m_rootItem) - { - return QModelIndex(); - } - - int row = parentItem->parent()->indexOfChild(parentItem); - return createIndex(row, 0, parentItem); -} - -int CTrendTreeModel::rowCount(const QModelIndex &parent) const -{ - if(!parent.isValid()) - { - if (NULL != m_rootItem) - { - return m_rootItem->childCount(); - } - else - { - return 0; - } - } - else - { - QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); - } -} - -int CTrendTreeModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return 1; -} - -QVariant CTrendTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item) - { - if(TAG_TYPE == item->type() && Qt::CheckStateRole == role && 0 == index.column()) - { - return item->checkState(index.column()); - } - return item->data(index.column(), role); - } - return QVariant(); -} - -bool CTrendTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - - if(!index.isValid()) - { - return false; - } - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item) - { - if(Qt::CheckStateRole == role) - { - emit itemCheckStateChanged(item->data(0, ItemTagRole).toString(), value.toInt()); - } - item->setData(index.column(), role, value); - } - - return true; -} - -Qt::ItemFlags CTrendTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item && TAG_TYPE == item->type()) - { - return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; - } - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} - -void CTrendTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state) -{ - if(!index.isValid()) - { - return; - } - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(!item) - { - return; - } - if(DEV_TYPE == item->type()) - { - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - setData(index.child(nChildIndex, 0), state, Qt::CheckStateRole); - } - } -} - -void CTrendTreeModel::updateNodeVisualState(const QString &content, QItemSelection &selection) -{ - for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) - { - QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); - bool hit = traverNode(content, topLevelIndex, selection); - m_pView->setRowHidden(topLevelIndex.row(), topLevelIndex.parent(), !hit); - } -} - -bool CTrendTreeModel::traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection) -{ - if(!index.isValid()) - { - return false; - } - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(!item) - { - return false; - } - - bool isContains = false; - if(content.isEmpty()) - { - isContains = true; - } - else - { - isContains = item->text(index.column()).contains(content); - if(isContains) - { - selection.append(QItemSelectionRange(index)); - } - } - - if(TAG_TYPE == item->type()) - { - m_pView->setRowHidden(index.row(), index.parent(), !isContains); - return isContains; - } - - bool hasHit = false; - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - if(traverNode(content, index.child(nChildIndex, 0), selection)) - { - hasHit = true; - } - } - - if(DEV_TYPE == item->type()) - { - if(isContains) - { - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - m_pView->setRowHidden(nChildIndex, index, false); - } - } - m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); - } - - if(DEV_GROUP_TYPE == item->type()) - { - if(isContains) - { - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - m_pView->setRowHidden(nChildIndex, index, false); - for(int n(0); n < item->child(nChildIndex)->childCount(); n++) - { - m_pView->setRowHidden(n, createIndex(n, 0, item->child(nChildIndex)), false); - } - } - } - m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); - } - - return hasHit | isContains; -} - -void CTrendTreeModel::clearCheckState() -{ - if(!m_rootItem) - { - return; - } - blockSignals(true); - for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) - { - QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); - updateChildCheckState(topLevelIndex, Qt::Unchecked); - } - blockSignals(false); - m_pView->update(); -} - -void CTrendTreeModel::updateTagCheckState(const QString &tag, const bool &checked) -{ - for(int nLocationRow(0); nLocationRow < m_rootItem->childCount(); nLocationRow++) - { - QTreeWidgetItem * locationItem = m_rootItem->child(nLocationRow); - for(int nDeviceGroupRow(0); nDeviceGroupRow < locationItem->childCount(); nDeviceGroupRow++) - { - QTreeWidgetItem * deviceGroupItem = locationItem->child(nDeviceGroupRow); - for(int nDeviceRow(0); nDeviceRow < deviceGroupItem->childCount(); nDeviceRow++) - { - QTreeWidgetItem * deviceItem = deviceGroupItem->child(nDeviceRow); - for(int nTagRow(0); nTagRow < deviceItem->childCount(); nTagRow++) - { - QTreeWidgetItem * tagItem = deviceItem->child(nTagRow); - if(tag == tagItem->data(0, ItemTagRole).toString()) - { - tagItem->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); - return; - } - } - } - } - } -} - -void CTrendTreeModel::updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state) -{ - if(!index.isValid()) - { - return; - } - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(!item) - { - return; - } - if(TAG_TYPE == item->type()) - { - item->setCheckState(0, state); - } - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - updateChildCheckState(index.child(nChildIndex, 0), state); - } -} +#include "CTrendTreeModel.h" +#include "CTrendInfoManage.h" +#include + +const int ItemTagRole = Qt::UserRole + 1; + +CTrendTreeModel::CTrendTreeModel(QObject *parent, QTreeView *view) + : QAbstractItemModel(parent), + m_pView(view), + m_rootItem(Q_NULLPTR) +{ + QTimer::singleShot(300, this, [=](){initTrendTagInfo();}); +} + +CTrendTreeModel::~CTrendTreeModel() +{ + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = Q_NULLPTR; +} + + +void CTrendTreeModel::initTrendTagInfo() +{ + beginResetModel(); + + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = new QTreeWidgetItem(ROOT_TYPE); + + //< load location + QMap locationInfo = CTrendInfoManage::instance()->locationInfo(); + QMap::const_iterator iter_location = locationInfo.constBegin(); + while (iter_location != locationInfo.constEnd()) + { + //< load deviceGroup + QMap devGroupInfo = CTrendInfoManage::instance()->devGroupInfo(iter_location.key()); + if(devGroupInfo.isEmpty()) + { + ++iter_location; + continue; + } + QTreeWidgetItem * locationItem = new QTreeWidgetItem(m_rootItem, QStringList() << iter_location.value(), LOCATION_TYPE); + locationItem->setData(0, ItemTagRole, iter_location.key()); + QMap::const_iterator iter_devGroup = devGroupInfo.constBegin(); + while (iter_devGroup != devGroupInfo.constEnd()) + { + //< load device + QMap devInfo = CTrendInfoManage::instance()->deviceInfo(iter_devGroup.key()); + if(devInfo.isEmpty()) + { + ++iter_devGroup; + continue; + } + QMap::const_iterator iter_device = devInfo.constBegin(); + while (iter_device != devInfo.constEnd()) + { + //< load tag + QStringList listTagName = CTrendInfoManage::instance()->queryTagList(iter_device.key()); + if(listTagName.isEmpty()) + { + ++iter_device; + continue; + } + QTreeWidgetItem * devGroupItem = new QTreeWidgetItem(locationItem, QStringList() << iter_devGroup.value(), DEV_GROUP_TYPE); + devGroupItem->setData(0, ItemTagRole, iter_devGroup.key()); + QTreeWidgetItem * devItem = new QTreeWidgetItem(devGroupItem, QStringList() << iter_device.value(), DEV_TYPE); + devItem->setData(0, ItemTagRole, iter_device.key()); + QStringList::const_iterator iter_tag = listTagName.constBegin(); + while (iter_tag != listTagName.constEnd()) + { + QTreeWidgetItem * tagItem = new QTreeWidgetItem(devItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); + tagItem->setData(0, ItemTagRole, *iter_tag); + tagItem->setToolTip(0, *iter_tag); + ++iter_tag; + } + ++iter_device; + } + + ++iter_devGroup; + } + + ++iter_location; + } + + endResetModel(); +} + +void CTrendTreeModel::clearTrendTagInfo() +{ + CTrendInfoManage::instance()->destory(); + beginResetModel(); + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = Q_NULLPTR; + endResetModel(); +} + +QVariant CTrendTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CTrendTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) + { + return QModelIndex(); + } + + QTreeWidgetItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + QTreeWidgetItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,0,childItem); + } + } + + return QModelIndex(); +} + +QModelIndex CTrendTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + QTreeWidgetItem *childItem = static_cast(index.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + QTreeWidgetItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + { + return QModelIndex(); + } + + int row = parentItem->parent()->indexOfChild(parentItem); + return createIndex(row, 0, parentItem); +} + +int CTrendTreeModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (NULL != m_rootItem) + { + return m_rootItem->childCount(); + } + else + { + return 0; + } + } + else + { + QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int CTrendTreeModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant CTrendTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(TAG_TYPE == item->type() && Qt::CheckStateRole == role && 0 == index.column()) + { + return item->checkState(index.column()); + } + return item->data(index.column(), role); + } + return QVariant(); +} + +bool CTrendTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + + if(!index.isValid()) + { + return false; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(item->data(0, ItemTagRole).toString(), value.toInt()); + } + item->setData(index.column(), role, value); + } + + return true; +} + +Qt::ItemFlags CTrendTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item && TAG_TYPE == item->type()) + { + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +void CTrendTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } + if(DEV_TYPE == item->type()) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + setData(index.child(nChildIndex, 0), state, Qt::CheckStateRole); + } + } +} + +void CTrendTreeModel::updateNodeVisualState(const QString &content, QItemSelection &selection) +{ + for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) + { + QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); + bool hit = traverNode(content, topLevelIndex, selection); + m_pView->setRowHidden(topLevelIndex.row(), topLevelIndex.parent(), !hit); + } +} + +bool CTrendTreeModel::traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection) +{ + if(!index.isValid()) + { + return false; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return false; + } + + bool isContains = false; + if(content.isEmpty()) + { + isContains = true; + } + else + { + isContains = item->text(index.column()).contains(content); + if(isContains) + { + selection.append(QItemSelectionRange(index)); + } + } + + if(TAG_TYPE == item->type()) + { + m_pView->setRowHidden(index.row(), index.parent(), !isContains); + return isContains; + } + + bool hasHit = false; + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + if(traverNode(content, index.child(nChildIndex, 0), selection)) + { + hasHit = true; + } + } + + if(DEV_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + if(DEV_GROUP_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + for(int n(0); n < item->child(nChildIndex)->childCount(); n++) + { + m_pView->setRowHidden(n, createIndex(n, 0, item->child(nChildIndex)), false); + } + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + return hasHit | isContains; +} + +void CTrendTreeModel::clearCheckState() +{ + if(!m_rootItem) + { + return; + } + blockSignals(true); + for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) + { + QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); + updateChildCheckState(topLevelIndex, Qt::Unchecked); + } + blockSignals(false); + m_pView->update(); +} + +void CTrendTreeModel::updateTagCheckState(const QString &tag, const bool &checked) +{ + for(int nLocationRow(0); nLocationRow < m_rootItem->childCount(); nLocationRow++) + { + QTreeWidgetItem * locationItem = m_rootItem->child(nLocationRow); + for(int nDeviceGroupRow(0); nDeviceGroupRow < locationItem->childCount(); nDeviceGroupRow++) + { + QTreeWidgetItem * deviceGroupItem = locationItem->child(nDeviceGroupRow); + for(int nDeviceRow(0); nDeviceRow < deviceGroupItem->childCount(); nDeviceRow++) + { + QTreeWidgetItem * deviceItem = deviceGroupItem->child(nDeviceRow); + for(int nTagRow(0); nTagRow < deviceItem->childCount(); nTagRow++) + { + QTreeWidgetItem * tagItem = deviceItem->child(nTagRow); + if(tag == tagItem->data(0, ItemTagRole).toString()) + { + tagItem->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); + return; + } + } + } + } + } +} + +void CTrendTreeModel::updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } + if(TAG_TYPE == item->type()) + { + item->setCheckState(0, state); + } + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + updateChildCheckState(index.child(nChildIndex, 0), state); + } +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeModel.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeModel.h index 08d82f69..6240ebe1 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeModel.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeModel.h @@ -1,66 +1,66 @@ -#ifndef CTRENDTREEMODEL_H -#define CTRENDTREEMODEL_H - -#include -#include - -enum NodeType -{ - ROOT_TYPE = 10000, - LOCATION_TYPE, - DEV_GROUP_TYPE, - DEV_TYPE, - TAG_TYPE -}; - -extern const int ItemTagRole; - -class CTrendTreeModel : public QAbstractItemModel -{ - Q_OBJECT -public: - CTrendTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR); - - ~CTrendTreeModel(); - - void initTrendTagInfo(); - - void clearTrendTagInfo(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - void setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state); - - void updateNodeVisualState(const QString &content, QItemSelection &selection); - -signals: - void itemCheckStateChanged(const QString &strTagName, const int &checkedState); - -public slots: - void clearCheckState(); - void updateTagCheckState(const QString &tag, const bool &checked); - -protected: - bool traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection); - - void updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state); - -private: - QTreeView * m_pView; - QStringList m_header; - QTreeWidgetItem * m_rootItem; -}; - -#endif // CTRENDTREEMODEL_H +#ifndef CTRENDTREEMODEL_H +#define CTRENDTREEMODEL_H + +#include +#include + +enum NodeType +{ + ROOT_TYPE = 10000, + LOCATION_TYPE, + DEV_GROUP_TYPE, + DEV_TYPE, + TAG_TYPE +}; + +extern const int ItemTagRole; + +class CTrendTreeModel : public QAbstractItemModel +{ + Q_OBJECT +public: + CTrendTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR); + + ~CTrendTreeModel(); + + void initTrendTagInfo(); + + void clearTrendTagInfo(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void updateNodeVisualState(const QString &content, QItemSelection &selection); + +signals: + void itemCheckStateChanged(const QString &strTagName, const int &checkedState); + +public slots: + void clearCheckState(); + void updateTagCheckState(const QString &tag, const bool &checked); + +protected: + bool traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection); + + void updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state); + +private: + QTreeView * m_pView; + QStringList m_header; + QTreeWidgetItem * m_rootItem; +}; + +#endif // CTRENDTREEMODEL_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeView.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeView.cpp index f87fe2ba..73ed6ee8 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeView.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeView.cpp @@ -1,59 +1,59 @@ -#include "CTrendTreeView.h" -#include "CTrendTreeModel.h" -#include -#include -#include - -CTrendTreeView::CTrendTreeView(QWidget *parent) - : QTreeView(parent) -{ - -} - -void CTrendTreeView::contextMenuEvent(QContextMenuEvent *event) -{ - CTrendTreeModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR != pModel) - { - QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); - if(Q_NULLPTR != pItem) - { - if(DEV_TYPE == pItem->type()) - { - QMenu menu; - menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); - menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Unchecked); }); - menu.exec(event->globalPos()); - } - } - } - return; -} - -void CTrendTreeView::mouseDoubleClickEvent(QMouseEvent *event) -{ - CTrendTreeModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR != pModel) - { - QModelIndex index = indexAt(event->pos()); - QTreeWidgetItem * pItem = static_cast(index.internalPointer()); - if(Q_NULLPTR != pItem) - { - if(TAG_TYPE == pItem->type()) - { - Qt::CheckState state = pItem->data(0, Qt::CheckStateRole).value(); - if (Qt::Checked == state) - { - state = Qt::Unchecked; - } - else - { - state = Qt::Checked; - } - pModel->setData(index, state, Qt::CheckStateRole); - update(); - } - } - } - return QTreeView::mouseDoubleClickEvent(event); -} +#include "CTrendTreeView.h" +#include "CTrendTreeModel.h" +#include +#include +#include + +CTrendTreeView::CTrendTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} + +void CTrendTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CTrendTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if(Q_NULLPTR != pItem) + { + if(DEV_TYPE == pItem->type()) + { + QMenu menu; + menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); + menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Unchecked); }); + menu.exec(event->globalPos()); + } + } + } + return; +} + +void CTrendTreeView::mouseDoubleClickEvent(QMouseEvent *event) +{ + CTrendTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QModelIndex index = indexAt(event->pos()); + QTreeWidgetItem * pItem = static_cast(index.internalPointer()); + if(Q_NULLPTR != pItem) + { + if(TAG_TYPE == pItem->type()) + { + Qt::CheckState state = pItem->data(0, Qt::CheckStateRole).value(); + if (Qt::Checked == state) + { + state = Qt::Unchecked; + } + else + { + state = Qt::Checked; + } + pModel->setData(index, state, Qt::CheckStateRole); + update(); + } + } + } + return QTreeView::mouseDoubleClickEvent(event); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeView.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeView.h index c3e3e4c3..2fb82d37 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeView.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendTreeView.h @@ -1,17 +1,17 @@ -#ifndef CTRENDTREEVIEW_H -#define CTRENDTREEVIEW_H - -#include - -class CTrendTreeView : public QTreeView -{ - Q_OBJECT -public: - CTrendTreeView(QWidget *parent = Q_NULLPTR); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - void mouseDoubleClickEvent(QMouseEvent *event); -}; - -#endif // CTRENDTREEVIEW_H +#ifndef CTRENDTREEVIEW_H +#define CTRENDTREEVIEW_H + +#include + +class CTrendTreeView : public QTreeView +{ + Q_OBJECT +public: + CTrendTreeView(QWidget *parent = Q_NULLPTR); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); +}; + +#endif // CTRENDTREEVIEW_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendWindow.cpp b/product/src/gui/plugin/ISCSTrendCurves/CTrendWindow.cpp index 70ddbf7b..48688c87 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendWindow.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendWindow.cpp @@ -1,363 +1,363 @@ -#include "CTrendWindow.h" -#include -#include -#include -#include -#include -#include -#include "CPlotWidget.h" -#include -#include -#include "CTrendTreeView.h" -#include "CTrendTreeModel.h" -#include "CTrendInfoManage.h" -#include "CTrendFavTreeWidget.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/FileStyle.h" - -CTrendWindow::CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent) - : QWidget(parent), - m_isEditMode(editMode), -// m_pTagWidget(Q_NULLPTR), - m_plotWidget(Q_NULLPTR), - m_pTagTreeView(Q_NULLPTR), - m_pTrendTreeModel(Q_NULLPTR), -// m_pSearchButton(Q_NULLPTR), -// m_pSearchTextEdit(Q_NULLPTR), - m_pSplitter(Q_NULLPTR), - m_pFavoritesTreeWidget(Q_NULLPTR) -{ - Q_UNUSED(ptrVec) - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("trendCurves.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -CTrendWindow::~CTrendWindow() -{ - CTrendInfoManage::instance()->destory(); -} - -void CTrendWindow::initialize(const int &mode) -{ - if(m_isEditMode) - { - initWindow(); - return; - } - - clearChildren(); - if(E_Trend_Window == (E_Trend_Mode)mode) - { - initWindow(); - } - else if(E_Trend_Widget == (E_Trend_Mode)mode) - { - initWidget(); - } - - if(m_plotWidget) - { - QString strColorConfig; - QFile colorFile("://resource/color.cfg"); - if (colorFile.open(QIODevice::ReadOnly)) - { - QTextStream colorStream(&colorFile); - strColorConfig= colorStream.readAll(); - } - QStringList listColor = strColorConfig.split("\n"); - m_plotWidget->setColorList(listColor); - } - -} - -void CTrendWindow::setTitle(const QString &title) -{ - if(m_plotWidget) - { - m_plotWidget->setTitle(title); - } -} - -void CTrendWindow::setTitleVisible(bool visible) -{ - if(m_plotWidget) - { - m_plotWidget->setTitleVisible(visible); - } -} - -void CTrendWindow::setTickCount(const int &count) -{ - if(m_plotWidget) - { - m_plotWidget->setTickCount(count); - } -} - -void CTrendWindow::insertTag(const QString &tag) -{ - if(m_plotWidget) - { - m_plotWidget->insertTag(tag); - } -} - -void CTrendWindow::insertTag(const QStringList &listTag) -{ - if(m_plotWidget) - { - m_plotWidget->insertTag(listTag); - } -} - -void CTrendWindow::removeTag(const QString &tag) -{ - if(m_plotWidget) - { - m_plotWidget->removeTag(tag); - } -} - -void CTrendWindow::setDisplayTime(const int &trendType, const double &dateTime) -{ - if(m_plotWidget) - { - m_plotWidget->setDisplayTime(trendType, dateTime); - } -} - -void CTrendWindow::setTagVisible(const QString &tag, const bool &visible) -{ - if(m_plotWidget) - { - m_plotWidget->setTagVisible(tag, visible); - } -} - -void CTrendWindow::clearTag() -{ - if(m_plotWidget) - { - m_plotWidget->clear(); - } -} - -void CTrendWindow::setClearVisible(bool visible) -{ - if(m_plotWidget) - { - m_plotWidget->setClearVisible(visible); - } -} - -void CTrendWindow::initWindow() -{ -// m_pTagWidget = new QTabWidget(this); -// m_pTagWidget->setTabPosition(QTabWidget::North); - m_pTagTreeView = new CTrendTreeView(this); - m_pTagTreeView->setVisible(false); - m_pTrendTreeModel = new CTrendTreeModel(this, m_pTagTreeView); - m_pTagTreeView->setModel(m_pTrendTreeModel); -// m_pTagTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); -// m_pTagTreeView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); - -// m_pTagTreeView->header()->setObjectName("devHeader"); -// QGridLayout * pHBoxLayout = new QGridLayout(m_pTagTreeView->header()); -// m_pSearchTextEdit = new QLineEdit(m_pTagTreeView->header()); -// m_pSearchTextEdit->setObjectName("searchTextEdit"); -// m_pSearchButton = new QPushButton(m_pTagTreeView->header()); -// m_pSearchButton->setObjectName("searchButton"); - -// connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CTrendWindow::FindTagName); -// connect(m_pSearchButton, &QPushButton::clicked, this, &CTrendWindow::FindTagName); -// pHBoxLayout->addWidget(m_pSearchTextEdit, 0, 0); -// pHBoxLayout->addWidget(m_pSearchButton, 0, 1); -// pHBoxLayout->setContentsMargins(5,0,5,0); -// pHBoxLayout->setSpacing(0); -// m_pTagTreeView->header()->setLayout(pHBoxLayout); -// m_pTagWidget->addTab(m_pTagTreeView, tr("设备/点")); - m_pFavoritesTreeWidget = new CTrendFavTreeWidget(this); - m_pFavoritesTreeWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); -// m_pTagWidget->addTab(m_pFavoritesTreeWidget, tr("收藏夹")); -// m_pTagWidget->setContentsMargins(1,1,1,1); -// m_pTagWidget->setCurrentIndex(1); - m_plotWidget = new CPlotWidget(this); - m_plotWidget->initialize(); - m_pSplitter = new QSplitter(this); -// m_pSplitter->addWidget(m_pFavoritesTreeWidget); - m_pSplitter->addWidget(m_pFavoritesTreeWidget); - m_pSplitter->addWidget(m_plotWidget); - m_pSplitter->setStretchFactor(0, 1); - m_pSplitter->setStretchFactor(1, 2); - m_pSplitter->setContentsMargins(6, 6, 6, 6); - m_pSplitter->setHandleWidth(10); - QHBoxLayout * layout = new QHBoxLayout(this); - layout->addWidget(m_pSplitter); - layout->setContentsMargins(0, 0, 0, 0); - setLayout(layout); - connect(m_plotWidget, &CPlotWidget::clearCurve, m_pTrendTreeModel, &CTrendTreeModel::clearCheckState); - connect(m_plotWidget, &CPlotWidget::collectGraph, m_pFavoritesTreeWidget, &CTrendFavTreeWidget::collectGraph); - connect(m_plotWidget, &CPlotWidget::updateTagCheckState, m_pTrendTreeModel, &CTrendTreeModel::updateTagCheckState, Qt::QueuedConnection); - connect(m_pTrendTreeModel, &CTrendTreeModel::itemCheckStateChanged, this, &CTrendWindow::itemCheckStateChanged); - connect(m_pFavoritesTreeWidget, &CTrendFavTreeWidget::showTrendGraph, this, &CTrendWindow::showTrendGraph); -} - -void CTrendWindow::initWidget() -{ - m_plotWidget = new CPlotWidget(this); - m_plotWidget->initialize(); - m_plotWidget->setTickCount(5); - m_plotWidget->setWindowMode(false); - QHBoxLayout * layout = new QHBoxLayout(this); - layout->addWidget(m_plotWidget); - layout->setMargin(3); - setLayout(layout); -} - -void CTrendWindow::clearChildren() -{ -// if(m_pSearchButton) -// { -// delete m_pSearchButton; -// } -// m_pSearchButton = Q_NULLPTR; - -// if(m_pSearchTextEdit) -// { -// delete m_pSearchTextEdit; -// } -// m_pSearchTextEdit = Q_NULLPTR; - - if(m_pTagTreeView) - { - delete m_pTagTreeView; - } - m_pTagTreeView = Q_NULLPTR; - -// if(m_pTagWidget) -// { -// delete m_pTagWidget; -// } -// m_pTagWidget = Q_NULLPTR; - - if(m_plotWidget) - { - delete m_plotWidget; - } - m_plotWidget = Q_NULLPTR; - - if(m_pTrendTreeModel) - { - delete m_pTrendTreeModel; - } - m_pTrendTreeModel = Q_NULLPTR; - - if(m_pSplitter) - { - delete m_pSplitter; - } - m_pSplitter = Q_NULLPTR; - - if(m_pFavoritesTreeWidget) - { - delete m_pFavoritesTreeWidget; - } - m_pFavoritesTreeWidget = Q_NULLPTR; - - if(layout()) - { - delete layout(); - } -} - -void CTrendWindow::login() -{ - if(m_pTrendTreeModel) - { - m_pTrendTreeModel->initTrendTagInfo(); - } -} - -void CTrendWindow::logout() -{ - if(m_pTrendTreeModel) - { - m_pTrendTreeModel->clearTrendTagInfo(); - } - - if(m_plotWidget) - { - m_plotWidget->clear(true); - } -} - -void CTrendWindow::itemCheckStateChanged(const QString &strTagName, const int &checkedState) -{ - if(Qt::Checked == (Qt::CheckState)checkedState) - { - m_plotWidget->insertTag(strTagName); - } - else if(Qt::Unchecked == (Qt::CheckState)checkedState) - { - m_plotWidget->removeTag(strTagName); - } -} - -void CTrendWindow::updateTrendName(const QString &title) -{ - m_plotWidget->setTitle(title); -} - -void CTrendWindow::showTrendGraph(CTrendGraph *graph, const QString &name) -{ - m_plotWidget->clear(); - if(!name.isEmpty()) - { - updateTrendName(name); - } - foreach (Curve curve, graph->curves()) - { - m_plotWidget->insertCurve(curve); - } -} - -void CTrendWindow::FindTagName() -{ -// QString content = m_pSearchTextEdit->text(); -// m_pTagTreeView->collapseAll(); -// m_pTagTreeView->selectionModel()->clear(); -// QItemSelection selection; -// m_pTrendTreeModel->updateNodeVisualState(content, selection); -// m_pTagTreeView->selectionModel()->select(selection, QItemSelectionModel::Select); - -// if(content.isEmpty()) -// { -// m_pTagTreeView->collapseAll(); -// } -// else -// { -// m_pTagTreeView->expandAll(); -// } -} +#include "CTrendWindow.h" +#include +#include +#include +#include +#include +#include +#include "CPlotWidget.h" +#include +#include +#include "CTrendTreeView.h" +#include "CTrendTreeModel.h" +#include "CTrendInfoManage.h" +#include "CTrendFavTreeWidget.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" + +CTrendWindow::CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent) + : QWidget(parent), + m_isEditMode(editMode), +// m_pTagWidget(Q_NULLPTR), + m_plotWidget(Q_NULLPTR), + m_pTagTreeView(Q_NULLPTR), + m_pTrendTreeModel(Q_NULLPTR), +// m_pSearchButton(Q_NULLPTR), +// m_pSearchTextEdit(Q_NULLPTR), + m_pSplitter(Q_NULLPTR), + m_pFavoritesTreeWidget(Q_NULLPTR) +{ + Q_UNUSED(ptrVec) + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("trendCurves.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +CTrendWindow::~CTrendWindow() +{ + CTrendInfoManage::instance()->destory(); +} + +void CTrendWindow::initialize(const int &mode) +{ + if(m_isEditMode) + { + initWindow(); + return; + } + + clearChildren(); + if(E_Trend_Window == (E_Trend_Mode)mode) + { + initWindow(); + } + else if(E_Trend_Widget == (E_Trend_Mode)mode) + { + initWidget(); + } + + if(m_plotWidget) + { + QString strColorConfig; + QFile colorFile("://resource/color.cfg"); + if (colorFile.open(QIODevice::ReadOnly)) + { + QTextStream colorStream(&colorFile); + strColorConfig= colorStream.readAll(); + } + QStringList listColor = strColorConfig.split("\n"); + m_plotWidget->setColorList(listColor); + } + +} + +void CTrendWindow::setTitle(const QString &title) +{ + if(m_plotWidget) + { + m_plotWidget->setTitle(title); + } +} + +void CTrendWindow::setTitleVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setTitleVisible(visible); + } +} + +void CTrendWindow::setTickCount(const int &count) +{ + if(m_plotWidget) + { + m_plotWidget->setTickCount(count); + } +} + +void CTrendWindow::insertTag(const QString &tag) +{ + if(m_plotWidget) + { + m_plotWidget->insertTag(tag); + } +} + +void CTrendWindow::insertTag(const QStringList &listTag) +{ + if(m_plotWidget) + { + m_plotWidget->insertTag(listTag); + } +} + +void CTrendWindow::removeTag(const QString &tag) +{ + if(m_plotWidget) + { + m_plotWidget->removeTag(tag); + } +} + +void CTrendWindow::setDisplayTime(const int &trendType, const double &dateTime) +{ + if(m_plotWidget) + { + m_plotWidget->setDisplayTime(trendType, dateTime); + } +} + +void CTrendWindow::setTagVisible(const QString &tag, const bool &visible) +{ + if(m_plotWidget) + { + m_plotWidget->setTagVisible(tag, visible); + } +} + +void CTrendWindow::clearTag() +{ + if(m_plotWidget) + { + m_plotWidget->clear(); + } +} + +void CTrendWindow::setClearVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setClearVisible(visible); + } +} + +void CTrendWindow::initWindow() +{ +// m_pTagWidget = new QTabWidget(this); +// m_pTagWidget->setTabPosition(QTabWidget::North); + m_pTagTreeView = new CTrendTreeView(this); + m_pTagTreeView->setVisible(false); + m_pTrendTreeModel = new CTrendTreeModel(this, m_pTagTreeView); + m_pTagTreeView->setModel(m_pTrendTreeModel); +// m_pTagTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); +// m_pTagTreeView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + +// m_pTagTreeView->header()->setObjectName("devHeader"); +// QGridLayout * pHBoxLayout = new QGridLayout(m_pTagTreeView->header()); +// m_pSearchTextEdit = new QLineEdit(m_pTagTreeView->header()); +// m_pSearchTextEdit->setObjectName("searchTextEdit"); +// m_pSearchButton = new QPushButton(m_pTagTreeView->header()); +// m_pSearchButton->setObjectName("searchButton"); + +// connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CTrendWindow::FindTagName); +// connect(m_pSearchButton, &QPushButton::clicked, this, &CTrendWindow::FindTagName); +// pHBoxLayout->addWidget(m_pSearchTextEdit, 0, 0); +// pHBoxLayout->addWidget(m_pSearchButton, 0, 1); +// pHBoxLayout->setContentsMargins(5,0,5,0); +// pHBoxLayout->setSpacing(0); +// m_pTagTreeView->header()->setLayout(pHBoxLayout); +// m_pTagWidget->addTab(m_pTagTreeView, tr("设备/点")); + m_pFavoritesTreeWidget = new CTrendFavTreeWidget(this); + m_pFavoritesTreeWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); +// m_pTagWidget->addTab(m_pFavoritesTreeWidget, tr("收藏夹")); +// m_pTagWidget->setContentsMargins(1,1,1,1); +// m_pTagWidget->setCurrentIndex(1); + m_plotWidget = new CPlotWidget(this); + m_plotWidget->initialize(); + m_pSplitter = new QSplitter(this); +// m_pSplitter->addWidget(m_pFavoritesTreeWidget); + m_pSplitter->addWidget(m_pFavoritesTreeWidget); + m_pSplitter->addWidget(m_plotWidget); + m_pSplitter->setStretchFactor(0, 1); + m_pSplitter->setStretchFactor(1, 2); + m_pSplitter->setContentsMargins(6, 6, 6, 6); + m_pSplitter->setHandleWidth(10); + QHBoxLayout * layout = new QHBoxLayout(this); + layout->addWidget(m_pSplitter); + layout->setContentsMargins(0, 0, 0, 0); + setLayout(layout); + connect(m_plotWidget, &CPlotWidget::clearCurve, m_pTrendTreeModel, &CTrendTreeModel::clearCheckState); + connect(m_plotWidget, &CPlotWidget::collectGraph, m_pFavoritesTreeWidget, &CTrendFavTreeWidget::collectGraph); + connect(m_plotWidget, &CPlotWidget::updateTagCheckState, m_pTrendTreeModel, &CTrendTreeModel::updateTagCheckState, Qt::QueuedConnection); + connect(m_pTrendTreeModel, &CTrendTreeModel::itemCheckStateChanged, this, &CTrendWindow::itemCheckStateChanged); + connect(m_pFavoritesTreeWidget, &CTrendFavTreeWidget::showTrendGraph, this, &CTrendWindow::showTrendGraph); +} + +void CTrendWindow::initWidget() +{ + m_plotWidget = new CPlotWidget(this); + m_plotWidget->initialize(); + m_plotWidget->setTickCount(5); + m_plotWidget->setWindowMode(false); + QHBoxLayout * layout = new QHBoxLayout(this); + layout->addWidget(m_plotWidget); + layout->setMargin(3); + setLayout(layout); +} + +void CTrendWindow::clearChildren() +{ +// if(m_pSearchButton) +// { +// delete m_pSearchButton; +// } +// m_pSearchButton = Q_NULLPTR; + +// if(m_pSearchTextEdit) +// { +// delete m_pSearchTextEdit; +// } +// m_pSearchTextEdit = Q_NULLPTR; + + if(m_pTagTreeView) + { + delete m_pTagTreeView; + } + m_pTagTreeView = Q_NULLPTR; + +// if(m_pTagWidget) +// { +// delete m_pTagWidget; +// } +// m_pTagWidget = Q_NULLPTR; + + if(m_plotWidget) + { + delete m_plotWidget; + } + m_plotWidget = Q_NULLPTR; + + if(m_pTrendTreeModel) + { + delete m_pTrendTreeModel; + } + m_pTrendTreeModel = Q_NULLPTR; + + if(m_pSplitter) + { + delete m_pSplitter; + } + m_pSplitter = Q_NULLPTR; + + if(m_pFavoritesTreeWidget) + { + delete m_pFavoritesTreeWidget; + } + m_pFavoritesTreeWidget = Q_NULLPTR; + + if(layout()) + { + delete layout(); + } +} + +void CTrendWindow::login() +{ + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->initTrendTagInfo(); + } +} + +void CTrendWindow::logout() +{ + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->clearTrendTagInfo(); + } + + if(m_plotWidget) + { + m_plotWidget->clear(true); + } +} + +void CTrendWindow::itemCheckStateChanged(const QString &strTagName, const int &checkedState) +{ + if(Qt::Checked == (Qt::CheckState)checkedState) + { + m_plotWidget->insertTag(strTagName); + } + else if(Qt::Unchecked == (Qt::CheckState)checkedState) + { + m_plotWidget->removeTag(strTagName); + } +} + +void CTrendWindow::updateTrendName(const QString &title) +{ + m_plotWidget->setTitle(title); +} + +void CTrendWindow::showTrendGraph(CTrendGraph *graph, const QString &name) +{ + m_plotWidget->clear(); + if(!name.isEmpty()) + { + updateTrendName(name); + } + foreach (Curve curve, graph->curves()) + { + m_plotWidget->insertCurve(curve); + } +} + +void CTrendWindow::FindTagName() +{ +// QString content = m_pSearchTextEdit->text(); +// m_pTagTreeView->collapseAll(); +// m_pTagTreeView->selectionModel()->clear(); +// QItemSelection selection; +// m_pTrendTreeModel->updateNodeVisualState(content, selection); +// m_pTagTreeView->selectionModel()->select(selection, QItemSelectionModel::Select); + +// if(content.isEmpty()) +// { +// m_pTagTreeView->collapseAll(); +// } +// else +// { +// m_pTagTreeView->expandAll(); +// } +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendWindow.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendWindow.h index de84f980..829daa0b 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendWindow.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendWindow.h @@ -1,74 +1,74 @@ -#ifndef CTRENDWINDOW_H -#define CTRENDWINDOW_H - -#include - -class QSplitter; -class QTreeView; -class QLineEdit; -class QTabWidget; -class CPlotWidget; -class CTrendGraph; -class QComboBox; -class QPushButton; -class CTrendTreeView; -class CTrendTreeModel; -class CTrendFavTreeWidget; - -enum E_Trend_Mode -{ - E_Trend_Window = 0, - E_Trend_Widget = 1 -}; - -class CTrendWindow : public QWidget -{ - Q_OBJECT -public: - explicit CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent = 0); - ~CTrendWindow(); - -public slots: - void initialize(const int &mode); - - void setTitle(const QString &title); - void setTitleVisible(bool visible); - void setTickCount(const int &count); - - void insertTag(const QString &tag); - void insertTag(const QStringList &listTag); - void removeTag(const QString &tag); - void setDisplayTime(const int &trendType, const double &dateTime); - void setTagVisible(const QString &tag, const bool &visible = false); - void clearTag(); - - void setClearVisible(bool visible); - - void login(); - void logout(); - -protected: - void initWindow(); - void initWidget(); - - void clearChildren(); - - void itemCheckStateChanged(const QString &strTagName, const int &checkedState); - void updateTrendName(const QString &title); - void showTrendGraph(CTrendGraph * graph, const QString &name = QString()); - void FindTagName(); - -private: - bool m_isEditMode; - CPlotWidget * m_plotWidget; - CTrendTreeView * m_pTagTreeView; - CTrendTreeModel * m_pTrendTreeModel; - QSplitter * m_pSplitter; - CTrendFavTreeWidget * m_pFavoritesTreeWidget; - -// QTabWidget * m_pTagWidget; -// QPushButton * m_pSearchButton; -// QLineEdit * m_pSearchTextEdit; -}; - -#endif // CTRENDWINDOW_H +#ifndef CTRENDWINDOW_H +#define CTRENDWINDOW_H + +#include + +class QSplitter; +class QTreeView; +class QLineEdit; +class QTabWidget; +class CPlotWidget; +class CTrendGraph; +class QComboBox; +class QPushButton; +class CTrendTreeView; +class CTrendTreeModel; +class CTrendFavTreeWidget; + +enum E_Trend_Mode +{ + E_Trend_Window = 0, + E_Trend_Widget = 1 +}; + +class CTrendWindow : public QWidget +{ + Q_OBJECT +public: + explicit CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent = 0); + ~CTrendWindow(); + +public slots: + void initialize(const int &mode); + + void setTitle(const QString &title); + void setTitleVisible(bool visible); + void setTickCount(const int &count); + + void insertTag(const QString &tag); + void insertTag(const QStringList &listTag); + void removeTag(const QString &tag); + void setDisplayTime(const int &trendType, const double &dateTime); + void setTagVisible(const QString &tag, const bool &visible = false); + void clearTag(); + + void setClearVisible(bool visible); + + void login(); + void logout(); + +protected: + void initWindow(); + void initWidget(); + + void clearChildren(); + + void itemCheckStateChanged(const QString &strTagName, const int &checkedState); + void updateTrendName(const QString &title); + void showTrendGraph(CTrendGraph * graph, const QString &name = QString()); + void FindTagName(); + +private: + bool m_isEditMode; + CPlotWidget * m_plotWidget; + CTrendTreeView * m_pTagTreeView; + CTrendTreeModel * m_pTrendTreeModel; + QSplitter * m_pSplitter; + CTrendFavTreeWidget * m_pFavoritesTreeWidget; + +// QTabWidget * m_pTagWidget; +// QPushButton * m_pSearchButton; +// QLineEdit * m_pSearchTextEdit; +}; + +#endif // CTRENDWINDOW_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/TrendCurves.pro b/product/src/gui/plugin/ISCSTrendCurves/TrendCurves.pro index 83a9a610..d9326c9e 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/TrendCurves.pro +++ b/product/src/gui/plugin/ISCSTrendCurves/TrendCurves.pro @@ -1,87 +1,87 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-11-09T10:35:55 -# -#------------------------------------------------- - - -QT += core gui widgets sql xml printsupport - -TARGET = ISCSTrendCurves -TEMPLATE = lib - -CONFIG += plugin - -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/plot/qcustomplot.cpp \ - $$PWD/widgets/CTabButton.cpp \ - $$PWD/widgets/CToolTip.cpp \ - $$PWD/widgets/CEditCollectWidget.cpp \ - CTrendWindow.cpp \ - CTrendGraph.cpp \ - CPlotWidget.cpp \ - CCurveLegendModel.cpp \ - CTrendTreeModel.cpp \ - CTrendInfoManage.cpp \ - CRealTimeDataCollect.cpp \ - CHisEventManage.cpp \ - CTrendFavTreeWidget.cpp \ - CTrendEditDialog.cpp \ - CTrendEditView.cpp \ - CTrendEditModel.cpp \ - CTrendPluginWidget.cpp \ - widgets/CCalendarWidget.cpp \ - CTrendTreeView.cpp \ - CHisDataManage.cpp \ - CCurveLegendView.cpp \ - widgets/CTrendAddWidget.cpp -# main.cpp - -HEADERS += \ - $$PWD/plot/qcustomplot.h \ - $$PWD/widgets/CTabButton.h \ - $$PWD/widgets/CToolTip.h \ - $$PWD/widgets/CEditCollectWidget.h \ - CTrendWindow.h \ - CTrendGraph.h \ - CPlotWidget.h \ - CCurveLegendModel.h \ - CTrendTreeModel.h \ - CTrendInfoManage.h \ - CRealTimeDataCollect.h \ - CHisEventManage.h \ - CTrendFavTreeWidget.h \ - CTrendEditDialog.h \ - CTrendEditView.h \ - CTrendEditModel.h \ - CTrendPluginWidget.h \ - widgets/CCalendarWidget.h \ - CTrendTreeView.h \ - CHisDataManage.h \ - CCurveLegendView.h \ - widgets/CTrendAddWidget.h - -FORMS += \ - CPlotWidget.ui \ - CTrendEditDialog.ui - -RESOURCES += \ - style.qrc - -LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -LIBS += -lpub_utility_api -lpub_sysinfo_api -LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api -ldb_his_query_api -LIBS += -lnet_msg_bus_api -lperm_mng_api -ldp_chg_data_api -lRetriever - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - - +#------------------------------------------------- +# +# Project created by QtCreator 2018-11-09T10:35:55 +# +#------------------------------------------------- + + +QT += core gui widgets sql xml printsupport + +TARGET = ISCSTrendCurves +TEMPLATE = lib + +CONFIG += plugin + +INCLUDEPATH += $$PWD + +SOURCES += \ + $$PWD/plot/qcustomplot.cpp \ + $$PWD/widgets/CTabButton.cpp \ + $$PWD/widgets/CToolTip.cpp \ + $$PWD/widgets/CEditCollectWidget.cpp \ + CTrendWindow.cpp \ + CTrendGraph.cpp \ + CPlotWidget.cpp \ + CCurveLegendModel.cpp \ + CTrendTreeModel.cpp \ + CTrendInfoManage.cpp \ + CRealTimeDataCollect.cpp \ + CHisEventManage.cpp \ + CTrendFavTreeWidget.cpp \ + CTrendEditDialog.cpp \ + CTrendEditView.cpp \ + CTrendEditModel.cpp \ + CTrendPluginWidget.cpp \ + widgets/CCalendarWidget.cpp \ + CTrendTreeView.cpp \ + CHisDataManage.cpp \ + CCurveLegendView.cpp \ + widgets/CTrendAddWidget.cpp +# main.cpp + +HEADERS += \ + $$PWD/plot/qcustomplot.h \ + $$PWD/widgets/CTabButton.h \ + $$PWD/widgets/CToolTip.h \ + $$PWD/widgets/CEditCollectWidget.h \ + CTrendWindow.h \ + CTrendGraph.h \ + CPlotWidget.h \ + CCurveLegendModel.h \ + CTrendTreeModel.h \ + CTrendInfoManage.h \ + CRealTimeDataCollect.h \ + CHisEventManage.h \ + CTrendFavTreeWidget.h \ + CTrendEditDialog.h \ + CTrendEditView.h \ + CTrendEditModel.h \ + CTrendPluginWidget.h \ + widgets/CCalendarWidget.h \ + CTrendTreeView.h \ + CHisDataManage.h \ + CCurveLegendView.h \ + widgets/CTrendAddWidget.h + +FORMS += \ + CPlotWidget.ui \ + CTrendEditDialog.ui + +RESOURCES += \ + style.qrc + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api +LIBS += -lpub_utility_api -lpub_sysinfo_api +LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api -ldb_his_query_api +LIBS += -lnet_msg_bus_api -lperm_mng_api -ldp_chg_data_api -lRetriever + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + + diff --git a/product/src/gui/plugin/ISCSTrendCurves/main.cpp b/product/src/gui/plugin/ISCSTrendCurves/main.cpp index 37f03d68..789f8667 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/main.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/main.cpp @@ -1,46 +1,46 @@ -#include -#include "CTrendWindow.h" -#include "pub_logger_api/logger.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - kbd_service::CDpcdaForApp::initGlobalThread(); - - { - LOGINFO("===========================Trend Curve==========================="); - QApplication app(argc, argv); - - QVector ptrVec; - CTrendWindow w(false, ptrVec); - w.initialize(E_Trend_Window); - w.show(); - - app.exec(); - } - - kbd_service::CDpcdaForApp::releaseGlobalThread(); - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include +#include "CTrendWindow.h" +#include "pub_logger_api/logger.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + kbd_service::CDpcdaForApp::initGlobalThread(); + + { + LOGINFO("===========================Trend Curve==========================="); + QApplication app(argc, argv); + + QVector ptrVec; + CTrendWindow w(false, ptrVec); + w.initialize(E_Trend_Window); + w.show(); + + app.exec(); + } + + kbd_service::CDpcdaForApp::releaseGlobalThread(); + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/plot/qcustomplot.cpp b/product/src/gui/plugin/ISCSTrendCurves/plot/qcustomplot.cpp index d12165a0..fd0cd606 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/plot/qcustomplot.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/plot/qcustomplot.cpp @@ -1,30417 +1,30417 @@ -/*************************************************************************** -** ** -** QCustomPlot, an easy to use, modern plotting widget for Qt ** -** Copyright (C) 2011-2017 Emanuel Eichhammer ** -** ** -** This program is free software: you can redistribute it and/or modify ** -** it under the terms of the GNU General Public License as published by ** -** the Free Software Foundation, either version 3 of the License, or ** -** (at your option) any later version. ** -** ** -** This program is distributed in the hope that it will be useful, ** -** but WITHOUT ANY WARRANTY; without even the implied warranty of ** -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** -** GNU General Public License for more details. ** -** ** -** You should have received a copy of the GNU General Public License ** -** along with this program. If not, see http://www.gnu.org/licenses/. ** -** ** -**************************************************************************** -** Author: Emanuel Eichhammer ** -** Website/Contact: http://www.qcustomplot.com/ ** -** Date: 04.09.17 ** -** Version: 2.0.0 ** -****************************************************************************/ - -#include "qcustomplot.h" -#include "../widgets/CToolTip.h" - -/* including file 'src/vector2d.cpp', size 7340 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPVector2D -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPVector2D - \brief Represents two doubles as a mathematical 2D vector - - This class acts as a replacement for QVector2D with the advantage of double precision instead of - single, and some convenience methods tailored for the QCustomPlot library. -*/ - -/* start documentation of inline functions */ - -/*! \fn void QCPVector2D::setX(double x) - - Sets the x coordinate of this vector to \a x. - - \see setY -*/ - -/*! \fn void QCPVector2D::setY(double y) - - Sets the y coordinate of this vector to \a y. - - \see setX -*/ - -/*! \fn double QCPVector2D::length() const - - Returns the length of this vector. - - \see lengthSquared -*/ - -/*! \fn double QCPVector2D::lengthSquared() const - - Returns the squared length of this vector. In some situations, e.g. when just trying to find the - shortest vector of a group, this is faster than calculating \ref length, because it avoids - calculation of a square root. - - \see length -*/ - -/*! \fn QPoint QCPVector2D::toPoint() const - - Returns a QPoint which has the x and y coordinates of this vector, truncating any floating point - information. - - \see toPointF -*/ - -/*! \fn QPointF QCPVector2D::toPointF() const - - Returns a QPointF which has the x and y coordinates of this vector. - - \see toPoint -*/ - -/*! \fn bool QCPVector2D::isNull() const - - Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y - coordinates, i.e. if both are binary equal to 0. -*/ - -/*! \fn QCPVector2D QCPVector2D::perpendicular() const - - Returns a vector perpendicular to this vector, with the same length. -*/ - -/*! \fn double QCPVector2D::dot() const - - Returns the dot/scalar product of this vector with the specified vector \a vec. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a QCPVector2D object and initializes the x and y coordinates to 0. -*/ -QCPVector2D::QCPVector2D() : - mX(0), - mY(0) -{ -} - -/*! - Creates a QCPVector2D object and initializes the \a x and \a y coordinates with the specified - values. -*/ -QCPVector2D::QCPVector2D(double x, double y) : - mX(x), - mY(y) -{ -} - -/*! - Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of - the specified \a point. -*/ -QCPVector2D::QCPVector2D(const QPoint &point) : - mX(point.x()), - mY(point.y()) -{ -} - -/*! - Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of - the specified \a point. -*/ -QCPVector2D::QCPVector2D(const QPointF &point) : - mX(point.x()), - mY(point.y()) -{ -} - -/*! - Normalizes this vector. After this operation, the length of the vector is equal to 1. - - \see normalized, length, lengthSquared -*/ -void QCPVector2D::normalize() -{ - double len = length(); - mX /= len; - mY /= len; -} - -/*! - Returns a normalized version of this vector. The length of the returned vector is equal to 1. - - \see normalize, length, lengthSquared -*/ -QCPVector2D QCPVector2D::normalized() const -{ - QCPVector2D result(mX, mY); - result.normalize(); - return result; -} - -/*! \overload - - Returns the squared shortest distance of this vector (interpreted as a point) to the finite line - segment given by \a start and \a end. - - \see distanceToStraightLine -*/ -double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const -{ - QCPVector2D v(end-start); - double vLengthSqr = v.lengthSquared(); - if (!qFuzzyIsNull(vLengthSqr)) - { - double mu = v.dot(*this-start)/vLengthSqr; - if (mu < 0) - return (*this-start).lengthSquared(); - else if (mu > 1) - return (*this-end).lengthSquared(); - else - return ((start + mu*v)-*this).lengthSquared(); - } else - return (*this-start).lengthSquared(); -} - -/*! \overload - - Returns the squared shortest distance of this vector (interpreted as a point) to the finite line - segment given by \a line. - - \see distanceToStraightLine -*/ -double QCPVector2D::distanceSquaredToLine(const QLineF &line) const -{ - return distanceSquaredToLine(QCPVector2D(line.p1()), QCPVector2D(line.p2())); -} - -/*! - Returns the shortest distance of this vector (interpreted as a point) to the infinite straight - line given by a \a base point and a \a direction vector. - - \see distanceSquaredToLine -*/ -double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const -{ - return qAbs((*this-base).dot(direction.perpendicular()))/direction.length(); -} - -/*! - Scales this vector by the given \a factor, i.e. the x and y components are multiplied by \a - factor. -*/ -QCPVector2D &QCPVector2D::operator*=(double factor) -{ - mX *= factor; - mY *= factor; - return *this; -} - -/*! - Scales this vector by the given \a divisor, i.e. the x and y components are divided by \a - divisor. -*/ -QCPVector2D &QCPVector2D::operator/=(double divisor) -{ - mX /= divisor; - mY /= divisor; - return *this; -} - -/*! - Adds the given \a vector to this vector component-wise. -*/ -QCPVector2D &QCPVector2D::operator+=(const QCPVector2D &vector) -{ - mX += vector.mX; - mY += vector.mY; - return *this; -} - -/*! - subtracts the given \a vector from this vector component-wise. -*/ -QCPVector2D &QCPVector2D::operator-=(const QCPVector2D &vector) -{ - mX -= vector.mX; - mY -= vector.mY; - return *this; -} -/* end of 'src/vector2d.cpp' */ - - -/* including file 'src/painter.cpp', size 8670 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPainter -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPainter - \brief QPainter subclass used internally - - This QPainter subclass is used to provide some extended functionality e.g. for tweaking position - consistency between antialiased and non-antialiased painting. Further it provides workarounds - for QPainter quirks. - - \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and - restore. So while it is possible to pass a QCPPainter instance to a function that expects a - QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because - it will call the base class implementations of the functions actually hidden by QCPPainter). -*/ - -/*! - Creates a new QCPPainter instance and sets default values -*/ -QCPPainter::QCPPainter() : - QPainter(), - mModes(pmDefault), - mIsAntialiasing(false) -{ - // don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and - // a call to begin() will follow -} - -/*! - Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just - like the analogous QPainter constructor, begins painting on \a device immediately. - - Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. -*/ -QCPPainter::QCPPainter(QPaintDevice *device) : - QPainter(device), - mModes(pmDefault), - mIsAntialiasing(false) -{ -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. - if (isActive()) - setRenderHint(QPainter::NonCosmeticDefaultPen); -#endif -} - -/*! - Sets the pen of the painter and applies certain fixes to it, depending on the mode of this - QCPPainter. - - \note this function hides the non-virtual base class implementation. -*/ -void QCPPainter::setPen(const QPen &pen) -{ - QPainter::setPen(pen); - if (mModes.testFlag(pmNonCosmetic)) - makeNonCosmetic(); -} - -/*! \overload - - Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of - this QCPPainter. - - \note this function hides the non-virtual base class implementation. -*/ -void QCPPainter::setPen(const QColor &color) -{ - QPainter::setPen(color); - if (mModes.testFlag(pmNonCosmetic)) - makeNonCosmetic(); -} - -/*! \overload - - Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of - this QCPPainter. - - \note this function hides the non-virtual base class implementation. -*/ -void QCPPainter::setPen(Qt::PenStyle penStyle) -{ - QPainter::setPen(penStyle); - if (mModes.testFlag(pmNonCosmetic)) - makeNonCosmetic(); -} - -/*! \overload - - Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when - antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to - integer coordinates and then passes it to the original drawLine. - - \note this function hides the non-virtual base class implementation. -*/ -void QCPPainter::drawLine(const QLineF &line) -{ - if (mIsAntialiasing || mModes.testFlag(pmVectorized)) - QPainter::drawLine(line); - else - QPainter::drawLine(line.toLine()); -} - -/*! - Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint - with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between - antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for - AA/Non-AA painting). -*/ -void QCPPainter::setAntialiasing(bool enabled) -{ - setRenderHint(QPainter::Antialiasing, enabled); - if (mIsAntialiasing != enabled) - { - mIsAntialiasing = enabled; - if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs - { - if (mIsAntialiasing) - translate(0.5, 0.5); - else - translate(-0.5, -0.5); - } - } -} - -/*! - Sets the mode of the painter. This controls whether the painter shall adjust its - fixes/workarounds optimized for certain output devices. -*/ -void QCPPainter::setModes(QCPPainter::PainterModes modes) -{ - mModes = modes; -} - -/*! - Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a - device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, - all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that - behaviour. - - The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets - the render hint as appropriate. - - \note this function hides the non-virtual base class implementation. -*/ -bool QCPPainter::begin(QPaintDevice *device) -{ - bool result = QPainter::begin(device); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. - if (result) - setRenderHint(QPainter::NonCosmeticDefaultPen); -#endif - return result; -} - -/*! \overload - - Sets the mode of the painter. This controls whether the painter shall adjust its - fixes/workarounds optimized for certain output devices. -*/ -void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) -{ - if (!enabled && mModes.testFlag(mode)) - mModes &= ~mode; - else if (enabled && !mModes.testFlag(mode)) - mModes |= mode; -} - -/*! - Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to - QPainter, the save/restore functions are reimplemented to also save/restore those members. - - \note this function hides the non-virtual base class implementation. - - \see restore -*/ -void QCPPainter::save() -{ - mAntialiasingStack.push(mIsAntialiasing); - QPainter::save(); -} - -/*! - Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to - QPainter, the save/restore functions are reimplemented to also save/restore those members. - - \note this function hides the non-virtual base class implementation. - - \see save -*/ -void QCPPainter::restore() -{ - if (!mAntialiasingStack.isEmpty()) - mIsAntialiasing = mAntialiasingStack.pop(); - else - qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; - QPainter::restore(); -} - -/*! - Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen - overrides when the \ref pmNonCosmetic mode is set. -*/ -void QCPPainter::makeNonCosmetic() -{ - if (qFuzzyIsNull(pen().widthF())) - { - QPen p = pen(); - p.setWidth(1); - QPainter::setPen(p); - } -} -/* end of 'src/painter.cpp' */ - - -/* including file 'src/paintbuffer.cpp', size 18502 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractPaintBuffer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractPaintBuffer - \brief The abstract base class for paint buffers, which define the rendering backend - - This abstract base class defines the basic interface that a paint buffer needs to provide in - order to be usable by QCustomPlot. - - A paint buffer manages both a surface to draw onto, and the matching paint device. The size of - the surface can be changed via \ref setSize. External classes (\ref QCustomPlot and \ref - QCPLayer) request a painter via \ref startPainting and then perform the draw calls. Once the - painting is complete, \ref donePainting is called, so the paint buffer implementation can do - clean up if necessary. Before rendering a frame, each paint buffer is usually filled with a color - using \ref clear (usually the color is \c Qt::transparent), to remove the contents of the - previous frame. - - The simplest paint buffer implementation is \ref QCPPaintBufferPixmap which allows regular - software rendering via the raster engine. Hardware accelerated rendering via pixel buffers and - frame buffer objects is provided by \ref QCPPaintBufferGlPbuffer and \ref QCPPaintBufferGlFbo. - They are used automatically if \ref QCustomPlot::setOpenGl is enabled. -*/ - -/* start documentation of pure virtual functions */ - -/*! \fn virtual QCPPainter *QCPAbstractPaintBuffer::startPainting() = 0 - - Returns a \ref QCPPainter which is ready to draw to this buffer. The ownership and thus the - responsibility to delete the painter after the painting operations are complete is given to the - caller of this method. - - Once you are done using the painter, delete the painter and call \ref donePainting. - - While a painter generated with this method is active, you must not call \ref setSize, \ref - setDevicePixelRatio or \ref clear. - - This method may return 0, if a painter couldn't be activated on the buffer. This usually - indicates a problem with the respective painting backend. -*/ - -/*! \fn virtual void QCPAbstractPaintBuffer::draw(QCPPainter *painter) const = 0 - - Draws the contents of this buffer with the provided \a painter. This is the method that is used - to finally join all paint buffers and draw them onto the screen. -*/ - -/*! \fn virtual void QCPAbstractPaintBuffer::clear(const QColor &color) = 0 - - Fills the entire buffer with the provided \a color. To have an empty transparent buffer, use the - named color \c Qt::transparent. - - This method must not be called if there is currently a painter (acquired with \ref startPainting) - active. -*/ - -/*! \fn virtual void QCPAbstractPaintBuffer::reallocateBuffer() = 0 - - Reallocates the internal buffer with the currently configured size (\ref setSize) and device - pixel ratio, if applicable (\ref setDevicePixelRatio). It is called as soon as any of those - properties are changed on this paint buffer. - - \note Subclasses of \ref QCPAbstractPaintBuffer must call their reimplementation of this method - in their constructor, to perform the first allocation (this can not be done by the base class - because calling pure virtual methods in base class constructors is not possible). -*/ - -/* end documentation of pure virtual functions */ -/* start documentation of inline functions */ - -/*! \fn virtual void QCPAbstractPaintBuffer::donePainting() - - If you have acquired a \ref QCPPainter to paint onto this paint buffer via \ref startPainting, - call this method as soon as you are done with the painting operations and have deleted the - painter. - - paint buffer subclasses may use this method to perform any type of cleanup that is necessary. The - default implementation does nothing. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a paint buffer and initializes it with the provided \a size and \a devicePixelRatio. - - Subclasses must call their \ref reallocateBuffer implementation in their respective constructors. -*/ -QCPAbstractPaintBuffer::QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio) : - mSize(size), - mDevicePixelRatio(devicePixelRatio), - mInvalidated(true) -{ -} - -QCPAbstractPaintBuffer::~QCPAbstractPaintBuffer() -{ -} - -/*! - Sets the paint buffer size. - - The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained - by \ref startPainting are invalidated and must not be used after calling this method. - - If \a size is already the current buffer size, this method does nothing. -*/ -void QCPAbstractPaintBuffer::setSize(const QSize &size) -{ - if (mSize != size) - { - mSize = size; - reallocateBuffer(); - } -} - -/*! - Sets the invalidated flag to \a invalidated. - - This mechanism is used internally in conjunction with isolated replotting of \ref QCPLayer - instances (in \ref QCPLayer::lmBuffered mode). If \ref QCPLayer::replot is called on a buffered - layer, i.e. an isolated repaint of only that layer (and its dedicated paint buffer) is requested, - QCustomPlot will decide depending on the invalidated flags of other paint buffers whether it also - replots them, instead of only the layer on which the replot was called. - - The invalidated flag is set to true when \ref QCPLayer association has changed, i.e. if layers - were added or removed from this buffer, or if they were reordered. It is set to false as soon as - all associated \ref QCPLayer instances are drawn onto the buffer. - - Under normal circumstances, it is not necessary to manually call this method. -*/ -void QCPAbstractPaintBuffer::setInvalidated(bool invalidated) -{ - mInvalidated = invalidated; -} - -/*! - Sets the the device pixel ratio to \a ratio. This is useful to render on high-DPI output devices. - The ratio is automatically set to the device pixel ratio used by the parent QCustomPlot instance. - - The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained - by \ref startPainting are invalidated and must not be used after calling this method. - - \note This method is only available for Qt versions 5.4 and higher. -*/ -void QCPAbstractPaintBuffer::setDevicePixelRatio(double ratio) -{ - if (!qFuzzyCompare(ratio, mDevicePixelRatio)) - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mDevicePixelRatio = ratio; - reallocateBuffer(); -#else - qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; - mDevicePixelRatio = 1.0; -#endif - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPaintBufferPixmap -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPaintBufferPixmap - \brief A paint buffer based on QPixmap, using software raster rendering - - This paint buffer is the default and fall-back paint buffer which uses software rendering and - QPixmap as internal buffer. It is used if \ref QCustomPlot::setOpenGl is false. -*/ - -/*! - Creates a pixmap paint buffer instancen with the specified \a size and \a devicePixelRatio, if - applicable. -*/ -QCPPaintBufferPixmap::QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio) : - QCPAbstractPaintBuffer(size, devicePixelRatio) -{ - QCPPaintBufferPixmap::reallocateBuffer(); -} - -QCPPaintBufferPixmap::~QCPPaintBufferPixmap() -{ -} - -/* inherits documentation from base class */ -QCPPainter *QCPPaintBufferPixmap::startPainting() -{ - QCPPainter *result = new QCPPainter(&mBuffer); - result->setRenderHint(QPainter::HighQualityAntialiasing); - return result; -} - -/* inherits documentation from base class */ -void QCPPaintBufferPixmap::draw(QCPPainter *painter) const -{ - if (painter && painter->isActive()) - painter->drawPixmap(0, 0, mBuffer); - else - qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; -} - -/* inherits documentation from base class */ -void QCPPaintBufferPixmap::clear(const QColor &color) -{ - mBuffer.fill(color); -} - -/* inherits documentation from base class */ -void QCPPaintBufferPixmap::reallocateBuffer() -{ - setInvalidated(); - if (!qFuzzyCompare(1.0, mDevicePixelRatio)) - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mBuffer = QPixmap(mSize*mDevicePixelRatio); - mBuffer.setDevicePixelRatio(mDevicePixelRatio); -#else - qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; - mDevicePixelRatio = 1.0; - mBuffer = QPixmap(mSize); -#endif - } else - { - mBuffer = QPixmap(mSize); - } -} - - -#ifdef QCP_OPENGL_PBUFFER -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPaintBufferGlPbuffer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPaintBufferGlPbuffer - \brief A paint buffer based on OpenGL pixel buffers, using hardware accelerated rendering - - This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot - rendering. It is based on OpenGL pixel buffers (pbuffer) and is used in Qt versions before 5.0. - (See \ref QCPPaintBufferGlFbo used in newer Qt versions.) - - The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are - supported by the system. -*/ - -/*! - Creates a \ref QCPPaintBufferGlPbuffer instance with the specified \a size and \a - devicePixelRatio, if applicable. - - The parameter \a multisamples defines how many samples are used per pixel. Higher values thus - result in higher quality antialiasing. If the specified \a multisamples value exceeds the - capability of the graphics hardware, the highest supported multisampling is used. -*/ -QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples) : - QCPAbstractPaintBuffer(size, devicePixelRatio), - mGlPBuffer(0), - mMultisamples(qMax(0, multisamples)) -{ - QCPPaintBufferGlPbuffer::reallocateBuffer(); -} - -QCPPaintBufferGlPbuffer::~QCPPaintBufferGlPbuffer() -{ - if (mGlPBuffer) - delete mGlPBuffer; -} - -/* inherits documentation from base class */ -QCPPainter *QCPPaintBufferGlPbuffer::startPainting() -{ - if (!mGlPBuffer->isValid()) - { - qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; - return 0; - } - - QCPPainter *result = new QCPPainter(mGlPBuffer); - result->setRenderHint(QPainter::HighQualityAntialiasing); - return result; -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlPbuffer::draw(QCPPainter *painter) const -{ - if (!painter || !painter->isActive()) - { - qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; - return; - } - if (!mGlPBuffer->isValid()) - { - qDebug() << Q_FUNC_INFO << "OpenGL pbuffer isn't valid, reallocateBuffer was not called?"; - return; - } - painter->drawImage(0, 0, mGlPBuffer->toImage()); -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlPbuffer::clear(const QColor &color) -{ - if (mGlPBuffer->isValid()) - { - mGlPBuffer->makeCurrent(); - glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - mGlPBuffer->doneCurrent(); - } else - qDebug() << Q_FUNC_INFO << "OpenGL pbuffer invalid or context not current"; -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlPbuffer::reallocateBuffer() -{ - if (mGlPBuffer) - delete mGlPBuffer; - - QGLFormat format; - format.setAlpha(true); - format.setSamples(mMultisamples); - mGlPBuffer = new QGLPixelBuffer(mSize, format); -} -#endif // QCP_OPENGL_PBUFFER - - -#ifdef QCP_OPENGL_FBO -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPaintBufferGlFbo -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPaintBufferGlFbo - \brief A paint buffer based on OpenGL frame buffers objects, using hardware accelerated rendering - - This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot - rendering. It is based on OpenGL frame buffer objects (fbo) and is used in Qt versions 5.0 and - higher. (See \ref QCPPaintBufferGlPbuffer used in older Qt versions.) - - The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are - supported by the system. -*/ - -/*! - Creates a \ref QCPPaintBufferGlFbo instance with the specified \a size and \a devicePixelRatio, - if applicable. - - All frame buffer objects shall share one OpenGL context and paint device, which need to be set up - externally and passed via \a glContext and \a glPaintDevice. The set-up is done in \ref - QCustomPlot::setupOpenGl and the context and paint device are managed by the parent QCustomPlot - instance. -*/ -QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice) : - QCPAbstractPaintBuffer(size, devicePixelRatio), - mGlContext(glContext), - mGlPaintDevice(glPaintDevice), - mGlFrameBuffer(0) -{ - QCPPaintBufferGlFbo::reallocateBuffer(); -} - -QCPPaintBufferGlFbo::~QCPPaintBufferGlFbo() -{ - if (mGlFrameBuffer) - delete mGlFrameBuffer; -} - -/* inherits documentation from base class */ -QCPPainter *QCPPaintBufferGlFbo::startPainting() -{ - if (mGlPaintDevice.isNull()) - { - qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; - return 0; - } - if (!mGlFrameBuffer) - { - qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; - return 0; - } - - if (QOpenGLContext::currentContext() != mGlContext.data()) - mGlContext.data()->makeCurrent(mGlContext.data()->surface()); - mGlFrameBuffer->bind(); - QCPPainter *result = new QCPPainter(mGlPaintDevice.data()); - result->setRenderHint(QPainter::HighQualityAntialiasing); - return result; -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlFbo::donePainting() -{ - if (mGlFrameBuffer && mGlFrameBuffer->isBound()) - mGlFrameBuffer->release(); - else - qDebug() << Q_FUNC_INFO << "Either OpenGL frame buffer not valid or was not bound"; -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlFbo::draw(QCPPainter *painter) const -{ - if (!painter || !painter->isActive()) - { - qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; - return; - } - if (!mGlFrameBuffer) - { - qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; - return; - } - painter->drawImage(0, 0, mGlFrameBuffer->toImage()); -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlFbo::clear(const QColor &color) -{ - if (mGlContext.isNull()) - { - qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; - return; - } - if (!mGlFrameBuffer) - { - qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; - return; - } - - if (QOpenGLContext::currentContext() != mGlContext.data()) - mGlContext.data()->makeCurrent(mGlContext.data()->surface()); - mGlFrameBuffer->bind(); - glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - mGlFrameBuffer->release(); -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlFbo::reallocateBuffer() -{ - // release and delete possibly existing framebuffer: - if (mGlFrameBuffer) - { - if (mGlFrameBuffer->isBound()) - mGlFrameBuffer->release(); - delete mGlFrameBuffer; - mGlFrameBuffer = 0; - } - - if (mGlContext.isNull()) - { - qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; - return; - } - if (mGlPaintDevice.isNull()) - { - qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; - return; - } - - // create new fbo with appropriate size: - mGlContext.data()->makeCurrent(mGlContext.data()->surface()); - QOpenGLFramebufferObjectFormat frameBufferFormat; - frameBufferFormat.setSamples(mGlContext.data()->format().samples()); - frameBufferFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - mGlFrameBuffer = new QOpenGLFramebufferObject(mSize*mDevicePixelRatio, frameBufferFormat); - if (mGlPaintDevice.data()->size() != mSize*mDevicePixelRatio) - mGlPaintDevice.data()->setSize(mSize*mDevicePixelRatio); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mGlPaintDevice.data()->setDevicePixelRatio(mDevicePixelRatio); -#endif -} -#endif // QCP_OPENGL_FBO -/* end of 'src/paintbuffer.cpp' */ - - -/* including file 'src/layer.cpp', size 37064 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayer - \brief A layer that may contain objects, to control the rendering order - - The Layering system of QCustomPlot is the mechanism to control the rendering order of the - elements inside the plot. - - It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of - one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, - QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers - bottom to top and successively draws the layerables of the layers into the paint buffer(s). - - A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base - class from which almost all visible objects derive, like axes, grids, graphs, items, etc. - - \section qcplayer-defaultlayers Default layers - - Initially, QCustomPlot has six layers: "background", "grid", "main", "axes", "legend" and - "overlay" (in that order). On top is the "overlay" layer, which only contains the QCustomPlot's - selection rect (\ref QCustomPlot::selectionRect). The next two layers "axes" and "legend" contain - the default axes and legend, so they will be drawn above plottables. In the middle, there is the - "main" layer. It is initially empty and set as the current layer (see - QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. are created on this - layer by default. Then comes the "grid" layer which contains the QCPGrid instances (which belong - tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background shall be drawn behind - everything else, thus the default QCPAxisRect instance is placed on the "background" layer. Of - course, the layer affiliation of the individual objects can be changed as required (\ref - QCPLayerable::setLayer). - - \section qcplayer-ordering Controlling the rendering order via layers - - Controlling the ordering of layerables in the plot is easy: Create a new layer in the position - you want the layerable to be in, e.g. above "main", with \ref QCustomPlot::addLayer. Then set the - current layer with \ref QCustomPlot::setCurrentLayer to that new layer and finally create the - objects normally. They will be placed on the new layer automatically, due to the current layer - setting. Alternatively you could have also ignored the current layer setting and just moved the - objects with \ref QCPLayerable::setLayer to the desired layer after creating them. - - It is also possible to move whole layers. For example, If you want the grid to be shown in front - of all plottables/items on the "main" layer, just move it above "main" with - QCustomPlot::moveLayer. - - The rendering order within one layer is simply by order of creation or insertion. The item - created last (or added last to the layer), is drawn on top of all other objects on that layer. - - When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below - the deleted layer, see QCustomPlot::removeLayer. - - \section qcplayer-buffering Replotting only a specific layer - - If the layer mode (\ref setMode) is set to \ref lmBuffered, you can replot only this specific - layer by calling \ref replot. In certain situations this can provide better replot performance, - compared with a full replot of all layers. Upon creation of a new layer, the layer mode is - initialized to \ref lmLogical. The only layer that is set to \ref lmBuffered in a new \ref - QCustomPlot instance is the "overlay" layer, containing the selection rect. -*/ - -/* start documentation of inline functions */ - -/*! \fn QList QCPLayer::children() const - - Returns a list of all layerables on this layer. The order corresponds to the rendering order: - layerables with higher indices are drawn above layerables with lower indices. -*/ - -/*! \fn int QCPLayer::index() const - - Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be - accessed via \ref QCustomPlot::layer. - - Layers with higher indices will be drawn above layers with lower indices. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPLayer instance. - - Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. - - \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. - This check is only performed by \ref QCustomPlot::addLayer. -*/ -QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : - QObject(parentPlot), - mParentPlot(parentPlot), - mName(layerName), - mIndex(-1), // will be set to a proper value by the QCustomPlot layer creation function - mVisible(true), - mMode(lmLogical) -{ - // Note: no need to make sure layerName is unique, because layer - // management is done with QCustomPlot functions. -} - -QCPLayer::~QCPLayer() -{ - // If child layerables are still on this layer, detach them, so they don't try to reach back to this - // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted - // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to - // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) - - while (!mChildren.isEmpty()) - mChildren.last()->setLayer(0); // removes itself from mChildren via removeChild() - - if (mParentPlot->currentLayer() == this) - qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand."; -} - -/*! - Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this - layer will be invisible. - - This function doesn't change the visibility property of the layerables (\ref - QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the - visibility of the parent layer into account. -*/ -void QCPLayer::setVisible(bool visible) -{ - mVisible = visible; -} - -/*! - Sets the rendering mode of this layer. - - If \a mode is set to \ref lmBuffered for a layer, it will be given a dedicated paint buffer by - the parent QCustomPlot instance. This means it may be replotted individually by calling \ref - QCPLayer::replot, without needing to replot all other layers. - - Layers which are set to \ref lmLogical (the default) are used only to define the rendering order - and can't be replotted individually. - - Note that each layer which is set to \ref lmBuffered requires additional paint buffers for the - layers below, above and for the layer itself. This increases the memory consumption and - (slightly) decreases the repainting speed because multiple paint buffers need to be joined. So - you should carefully choose which layers benefit from having their own paint buffer. A typical - example would be a layer which contains certain layerables (e.g. items) that need to be changed - and thus replotted regularly, while all other layerables on other layers stay static. By default, - only the topmost layer called "overlay" is in mode \ref lmBuffered, and contains the selection - rect. - - \see replot -*/ -void QCPLayer::setMode(QCPLayer::LayerMode mode) -{ - if (mMode != mode) - { - mMode = mode; - if (!mPaintBuffer.isNull()) - mPaintBuffer.data()->setInvalidated(); - } -} - -/*! \internal - - Draws the contents of this layer with the provided \a painter. - - \see replot, drawToPaintBuffer -*/ -void QCPLayer::draw(QCPPainter *painter) -{ - foreach (QCPLayerable *child, mChildren) - { - if (child->realVisibility()) - { - painter->save(); - painter->setClipRect(child->clipRect().translated(0, -1)); - child->applyDefaultAntialiasingHint(painter); - child->draw(painter); - painter->restore(); - } - } -} - -/*! \internal - - Draws the contents of this layer into the paint buffer which is associated with this layer. The - association is established by the parent QCustomPlot, which manages all paint buffers (see \ref - QCustomPlot::setupPaintBuffers). - - \see draw -*/ -void QCPLayer::drawToPaintBuffer() -{ - if (!mPaintBuffer.isNull()) - { - if (QCPPainter *painter = mPaintBuffer.data()->startPainting()) - { - if (painter->isActive()) - draw(painter); - else - qDebug() << Q_FUNC_INFO << "paint buffer returned inactive painter"; - delete painter; - mPaintBuffer.data()->donePainting(); - } else - qDebug() << Q_FUNC_INFO << "paint buffer returned zero painter"; - } else - qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; -} - -/*! - If the layer mode (\ref setMode) is set to \ref lmBuffered, this method allows replotting only - the layerables on this specific layer, without the need to replot all other layers (as a call to - \ref QCustomPlot::replot would do). - - If the layer mode is \ref lmLogical however, this method simply calls \ref QCustomPlot::replot on - the parent QCustomPlot instance. - - QCustomPlot also makes sure to replot all layers instead of only this one, if the layer ordering - has changed since the last full replot and the other paint buffers were thus invalidated. - - \see draw -*/ -void QCPLayer::replot() -{ - if (mMode == lmBuffered && !mParentPlot->hasInvalidatedPaintBuffers()) - { - if (!mPaintBuffer.isNull()) - { - mPaintBuffer.data()->clear(Qt::transparent); - drawToPaintBuffer(); - mPaintBuffer.data()->setInvalidated(false); - mParentPlot->update(); - } else - qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; - } else if (mMode == lmLogical) - mParentPlot->replot(); -} - -/*! \internal - - Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will - be prepended to the list, i.e. be drawn beneath the other layerables already in the list. - - This function does not change the \a mLayer member of \a layerable to this layer. (Use - QCPLayerable::setLayer to change the layer of an object, not this function.) - - \see removeChild -*/ -void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) -{ - if (!mChildren.contains(layerable)) - { - if (prepend) - mChildren.prepend(layerable); - else - mChildren.append(layerable); - if (!mPaintBuffer.isNull()) - mPaintBuffer.data()->setInvalidated(); - } else - qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); -} - -/*! \internal - - Removes the \a layerable from the list of this layer. - - This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer - to change the layer of an object, not this function.) - - \see addChild -*/ -void QCPLayer::removeChild(QCPLayerable *layerable) -{ - if (mChildren.removeOne(layerable)) - { - if (!mPaintBuffer.isNull()) - mPaintBuffer.data()->setInvalidated(); - } else - qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayerable -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayerable - \brief Base class for all drawable objects - - This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid - etc. - - Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking - the layers accordingly. - - For details about the layering mechanism, see the QCPLayer documentation. -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPLayerable *QCPLayerable::parentLayerable() const - - Returns the parent layerable of this layerable. The parent layerable is used to provide - visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables - only get drawn if their parent layerables are visible, too. - - Note that a parent layerable is not necessarily also the QObject parent for memory management. - Further, a layerable doesn't always have a parent layerable, so this function may return 0. - - A parent layerable is set implicitly when placed inside layout elements and doesn't need to be - set manually by the user. -*/ - -/* end documentation of inline functions */ -/* start documentation of pure virtual functions */ - -/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 - \internal - - This function applies the default antialiasing setting to the specified \a painter, using the - function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when - \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing - setting may be specified individually, this function should set the antialiasing state of the - most prominent entity. In this case however, the \ref draw function usually calls the specialized - versions of this function before drawing each entity, effectively overriding the setting of the - default antialiasing hint. - - First example: QCPGraph has multiple entities that have an antialiasing setting: The graph - line, fills and scatters. Those can be configured via QCPGraph::setAntialiased, - QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only - the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's - antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and - QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw - calls the respective specialized applyAntialiasingHint function. - - Second example: QCPItemLine consists only of a line so there is only one antialiasing - setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by - all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the - respective layerable subclass.) Consequently it only has the normal - QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to - care about setting any antialiasing states, because the default antialiasing hint is already set - on the painter when the \ref draw function is called, and that's the state it wants to draw the - line with. -*/ - -/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 - \internal - - This function draws the layerable with the specified \a painter. It is only called by - QCustomPlot, if the layerable is visible (\ref setVisible). - - Before this function is called, the painter's antialiasing state is set via \ref - applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was - set to \ref clipRect. -*/ - -/* end documentation of pure virtual functions */ -/* start documentation of signals */ - -/*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); - - This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to - a different layer. - - \see setLayer -*/ - -/* end documentation of signals */ - -/*! - Creates a new QCPLayerable instance. - - Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the - derived classes. - - If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a - targetLayer is an empty string, it places itself on the current layer of the plot (see \ref - QCustomPlot::setCurrentLayer). - - It is possible to provide 0 as \a plot. In that case, you should assign a parent plot at a later - time with \ref initializeParentPlot. - - The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable - parents are mainly used to control visibility in a hierarchy of layerables. This means a - layerable is only drawn, if all its ancestor layerables are also visible. Note that \a - parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a - plot does. It is not uncommon to set the QObject-parent to something else in the constructors of - QCPLayerable subclasses, to guarantee a working destruction hierarchy. -*/ -QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) : - QObject(plot), - mVisible(true), - mParentPlot(plot), - mParentLayerable(parentLayerable), - mLayer(0), - mAntialiased(true) -{ - if (mParentPlot) - { - if (targetLayer.isEmpty()) - setLayer(mParentPlot->currentLayer()); - else if (!setLayer(targetLayer)) - qDebug() << Q_FUNC_INFO << "setting QCPlayerable initial layer to" << targetLayer << "failed."; - } -} - -QCPLayerable::~QCPLayerable() -{ - if (mLayer) - { - mLayer->removeChild(this); - mLayer = 0; - } -} - -/*! - Sets the visibility of this layerable object. If an object is not visible, it will not be drawn - on the QCustomPlot surface, and user interaction with it (e.g. click and selection) is not - possible. -*/ -void QCPLayerable::setVisible(bool on) -{ - mVisible = on; -} - -/*! - Sets the \a layer of this layerable object. The object will be placed on top of the other objects - already on \a layer. - - If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or - interact/receive events). - - Returns true if the layer of this layerable was successfully changed to \a layer. -*/ -bool QCPLayerable::setLayer(QCPLayer *layer) -{ - return moveToLayer(layer, false); -} - -/*! \overload - Sets the layer of this layerable object by name - - Returns true on success, i.e. if \a layerName is a valid layer name. -*/ -bool QCPLayerable::setLayer(const QString &layerName) -{ - if (!mParentPlot) - { - qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; - return false; - } - if (QCPLayer *layer = mParentPlot->layer(layerName)) - { - return setLayer(layer); - } else - { - qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; - return false; - } -} - -/*! - Sets whether this object will be drawn antialiased or not. - - Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and - QCustomPlot::setNotAntialiasedElements. -*/ -void QCPLayerable::setAntialiased(bool enabled) -{ - mAntialiased = enabled; -} - -/*! - Returns whether this layerable is visible, taking the visibility of the layerable parent and the - visibility of this layerable's layer into account. This is the method that is consulted to decide - whether a layerable shall be drawn or not. - - If this layerable has a direct layerable parent (usually set via hierarchies implemented in - subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this - layerable has its visibility set to true and the parent layerable's \ref realVisibility returns - true. -*/ -bool QCPLayerable::realVisibility() const -{ - return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility()); -} - -/*! - This function is used to decide whether a click hits a layerable object or not. - - \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the - shortest pixel distance of this point to the object. If the object is either invisible or the - distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the - object is not selectable, -1.0 is returned, too. - - If the object is represented not by single lines but by an area like a \ref QCPItemText or the - bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In - these cases this function thus returns a constant value greater zero but still below the parent - plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). - - Providing a constant value for area objects allows selecting line objects even when they are - obscured by such area objects, by clicking close to the lines (i.e. closer than - 0.99*selectionTolerance). - - The actual setting of the selection state is not done by this function. This is handled by the - parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified - via the \ref selectEvent/\ref deselectEvent methods. - - \a details is an optional output parameter. Every layerable subclass may place any information - in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot - decides on the basis of this selectTest call, that the object was successfully selected. The - subsequent call to \ref selectEvent will carry the \a details. This is useful for multi-part - objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked - is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be - placed in \a details. So in the subsequent \ref selectEvent, the decision which part was - selected doesn't have to be done a second time for a single selection operation. - - You may pass 0 as \a details to indicate that you are not interested in those selection details. - - \see selectEvent, deselectEvent, mousePressEvent, wheelEvent, QCustomPlot::setInteractions -*/ -double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(pos) - Q_UNUSED(onlySelectable) - Q_UNUSED(details) - return -1.0; -} - -/*! \internal - - Sets the parent plot of this layerable. Use this function once to set the parent plot if you have - passed 0 in the constructor. It can not be used to move a layerable from one QCustomPlot to - another one. - - Note that, unlike when passing a non-null parent plot in the constructor, this function does not - make \a parentPlot the QObject-parent of this layerable. If you want this, call - QObject::setParent(\a parentPlot) in addition to this function. - - Further, you will probably want to set a layer (\ref setLayer) after calling this function, to - make the layerable appear on the QCustomPlot. - - The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized - so they can react accordingly (e.g. also initialize the parent plot of child layerables, like - QCPLayout does). -*/ -void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) -{ - if (mParentPlot) - { - qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; - return; - } - - if (!parentPlot) - qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; - - mParentPlot = parentPlot; - parentPlotInitialized(mParentPlot); -} - -/*! \internal - - Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not - become the QObject-parent (for memory management) of this layerable. - - The parent layerable has influence on the return value of the \ref realVisibility method. Only - layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be - drawn. - - \see realVisibility -*/ -void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) -{ - mParentLayerable = parentLayerable; -} - -/*! \internal - - Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to - the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is - false, the object will be appended. - - Returns true on success, i.e. if \a layer is a valid layer. -*/ -bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) -{ - if (layer && !mParentPlot) - { - qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; - return false; - } - if (layer && layer->parentPlot() != mParentPlot) - { - qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; - return false; - } - - QCPLayer *oldLayer = mLayer; - if (mLayer) - mLayer->removeChild(this); - mLayer = layer; - if (mLayer) - mLayer->addChild(this, prepend); - if (mLayer != oldLayer) - emit layerChanged(mLayer); - return true; -} - -/*! \internal - - Sets the QCPainter::setAntialiasing state on the provided \a painter, depending on the \a - localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is - controlled via \a overrideElement. -*/ -void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const -{ - if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) - painter->setAntialiasing(false); - else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) - painter->setAntialiasing(true); - else - painter->setAntialiasing(localAntialiased); -} - -/*! \internal - - This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting - of a parent plot. This is the case when 0 was passed as parent plot in the constructor, and the - parent plot is set at a later time. - - For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any - QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level - element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To - propagate the parent plot to all the children of the hierarchy, the top level element then uses - this function to pass the parent plot on to its child elements. - - The default implementation does nothing. - - \see initializeParentPlot -*/ -void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) -{ - Q_UNUSED(parentPlot) -} - -/*! \internal - - Returns the selection category this layerable shall belong to. The selection category is used in - conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and - which aren't. - - Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref - QCP::iSelectOther. This is what the default implementation returns. - - \see QCustomPlot::setInteractions -*/ -QCP::Interaction QCPLayerable::selectionCategory() const -{ - return QCP::iSelectOther; -} - -/*! \internal - - Returns the clipping rectangle of this layerable object. By default, this is the viewport of the - parent QCustomPlot. Specific subclasses may reimplement this function to provide different - clipping rects. - - The returned clipping rect is set on the painter before the draw function of the respective - object is called. -*/ -QRect QCPLayerable::clipRect() const -{ - if (mParentPlot) - return mParentPlot->viewport(); - else - return QRect(); -} - -/*! \internal - - This event is called when the layerable shall be selected, as a consequence of a click by the - user. Subclasses should react to it by setting their selection state appropriately. The default - implementation does nothing. - - \a event is the mouse event that caused the selection. \a additive indicates, whether the user - was holding the multi-select-modifier while performing the selection (see \ref - QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled - (i.e. become selected when unselected and unselected when selected). - - Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. - returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). - The \a details data you output from \ref selectTest is fed back via \a details here. You may - use it to transport any kind of information from the selectTest to the possibly subsequent - selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable - that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need - to do the calculation again to find out which part was actually clicked. - - \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must - set the value either to true or false, depending on whether the selection state of this layerable - was actually changed. For layerables that only are selectable as a whole and not in parts, this - is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the - selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the - layerable was previously unselected and now is switched to the selected state. - - \see selectTest, deselectEvent -*/ -void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - Q_UNUSED(additive) - Q_UNUSED(details) - Q_UNUSED(selectionStateChanged) -} - -/*! \internal - - This event is called when the layerable shall be deselected, either as consequence of a user - interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by - unsetting their selection appropriately. - - just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must - return true or false when the selection state of this layerable has changed or not changed, - respectively. - - \see selectTest, selectEvent -*/ -void QCPLayerable::deselectEvent(bool *selectionStateChanged) -{ - Q_UNUSED(selectionStateChanged) -} - -/*! - This event gets called when the user presses a mouse button while the cursor is over the - layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref - selectTest. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). The parameter \a details contains layerable-specific details about the hit, which - were generated in the previous call to \ref selectTest. For example, One-dimensional plottables - like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as - \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c - SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). - - QCustomPlot uses an event propagation system that works the same as Qt's system. If your - layerable doesn't reimplement the \ref mousePressEvent or explicitly calls \c event->ignore() in - its reimplementation, the event will be propagated to the next layerable in the stacking order. - - Once a layerable has accepted the \ref mousePressEvent, it is considered the mouse grabber and - will receive all following calls to \ref mouseMoveEvent or \ref mouseReleaseEvent for this mouse - interaction (a "mouse interaction" in this context ends with the release). - - The default implementation does nothing except explicitly ignoring the event with \c - event->ignore(). - - \see mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent -*/ -void QCPLayerable::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - event->ignore(); -} - -/*! - This event gets called when the user moves the mouse while holding a mouse button, after this - layerable has become the mouse grabber by accepting the preceding \ref mousePressEvent. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). The parameter \a startPos indicates the position where the initial \ref - mousePressEvent occured, that started the mouse interaction. - - The default implementation does nothing. - - \see mousePressEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent -*/ -void QCPLayerable::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(startPos) - event->ignore(); -} - -/*! - This event gets called when the user releases the mouse button, after this layerable has become - the mouse grabber by accepting the preceding \ref mousePressEvent. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). The parameter \a startPos indicates the position where the initial \ref - mousePressEvent occured, that started the mouse interaction. - - The default implementation does nothing. - - \see mousePressEvent, mouseMoveEvent, mouseDoubleClickEvent, wheelEvent -*/ -void QCPLayerable::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(startPos) - event->ignore(); -} - -/*! - This event gets called when the user presses the mouse button a second time in a double-click, - while the cursor is over the layerable. Whether a cursor is over the layerable is decided by a - preceding call to \ref selectTest. - - The \ref mouseDoubleClickEvent is called instead of the second \ref mousePressEvent. So in the - case of a double-click, the event succession is - pressEvent – releaseEvent – doubleClickEvent – releaseEvent. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). The parameter \a details contains layerable-specific details about the hit, which - were generated in the previous call to \ref selectTest. For example, One-dimensional plottables - like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as - \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c - SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). - - Similarly to \ref mousePressEvent, once a layerable has accepted the \ref mouseDoubleClickEvent, - it is considered the mouse grabber and will receive all following calls to \ref mouseMoveEvent - and \ref mouseReleaseEvent for this mouse interaction (a "mouse interaction" in this context ends - with the release). - - The default implementation does nothing except explicitly ignoring the event with \c - event->ignore(). - - \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, wheelEvent -*/ -void QCPLayerable::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - event->ignore(); -} - -/*! - This event gets called when the user turns the mouse scroll wheel while the cursor is over the - layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref - selectTest. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). - - The \c event->delta() indicates how far the mouse wheel was turned, which is usually +/- 120 for - single rotation steps. However, if the mouse wheel is turned rapidly, multiple steps may - accumulate to one event, making \c event->delta() larger. On the other hand, if the wheel has - very smooth steps or none at all, the delta may be smaller. - - The default implementation does nothing. - - \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent -*/ -void QCPLayerable::wheelEvent(QWheelEvent *event) -{ - event->ignore(); -} -/* end of 'src/layer.cpp' */ - - -/* including file 'src/axis/range.cpp', size 12221 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPRange -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPRange - \brief Represents the range an axis is encompassing. - - contains a \a lower and \a upper double value and provides convenience input, output and - modification functions. - - \see QCPAxis::setRange -*/ - -/* start of documentation of inline functions */ - -/*! \fn double QCPRange::size() const - - Returns the size of the range, i.e. \a upper-\a lower -*/ - -/*! \fn double QCPRange::center() const - - Returns the center of the range, i.e. (\a upper+\a lower)*0.5 -*/ - -/*! \fn void QCPRange::normalize() - - Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values are - swapped. -*/ - -/*! \fn bool QCPRange::contains(double value) const - - Returns true when \a value lies within or exactly on the borders of the range. -*/ - -/*! \fn QCPRange &QCPRange::operator+=(const double& value) - - Adds \a value to both boundaries of the range. -*/ - -/*! \fn QCPRange &QCPRange::operator-=(const double& value) - - Subtracts \a value from both boundaries of the range. -*/ - -/*! \fn QCPRange &QCPRange::operator*=(const double& value) - - Multiplies both boundaries of the range by \a value. -*/ - -/*! \fn QCPRange &QCPRange::operator/=(const double& value) - - Divides both boundaries of the range by \a value. -*/ - -/* end of documentation of inline functions */ - -/*! - Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller - intervals would cause errors due to the 11-bit exponent of double precision numbers, - corresponding to a minimum magnitude of roughly 1e-308. - - \warning Do not use this constant to indicate "arbitrarily small" values in plotting logic (as - values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to - prevent axis ranges from obtaining underflowing ranges. - - \see validRange, maxRange -*/ -//const double QCPRange::minRange = 1e-280; -const double QCPRange::minRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(1970, 0, 0)); - -/*! - Maximum values (negative and positive) the range will accept in range-changing functions. - Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, - corresponding to a maximum magnitude of roughly 1e308. - - \warning Do not use this constant to indicate "arbitrarily large" values in plotting logic (as - values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to - prevent axis ranges from obtaining overflowing ranges. - - \see validRange, minRange -*/ -//const double QCPRange::maxRange = 1e250; -const double QCPRange::maxRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 12, 31)); - -/*! - Constructs a range with \a lower and \a upper set to zero. -*/ -QCPRange::QCPRange() : - lower(0), - upper(0) -{ -} - -/*! \overload - - Constructs a range with the specified \a lower and \a upper values. - - The resulting range will be normalized (see \ref normalize), so if \a lower is not numerically - smaller than \a upper, they will be swapped. -*/ -QCPRange::QCPRange(double lower, double upper) : - lower(lower), - upper(upper) -{ - normalize(); -} - -/*! \overload - - Expands this range such that \a otherRange is contained in the new range. It is assumed that both - this range and \a otherRange are normalized (see \ref normalize). - - If this range contains NaN as lower or upper bound, it will be replaced by the respective bound - of \a otherRange. - - If \a otherRange is already inside the current range, this function does nothing. - - \see expanded -*/ -void QCPRange::expand(const QCPRange &otherRange) -{ - if (lower > otherRange.lower || qIsNaN(lower)) - lower = otherRange.lower; - if (upper < otherRange.upper || qIsNaN(upper)) - upper = otherRange.upper; -} - -/*! \overload - - Expands this range such that \a includeCoord is contained in the new range. It is assumed that - this range is normalized (see \ref normalize). - - If this range contains NaN as lower or upper bound, the respective bound will be set to \a - includeCoord. - - If \a includeCoord is already inside the current range, this function does nothing. - - \see expand -*/ -void QCPRange::expand(double includeCoord) -{ - if (lower > includeCoord || qIsNaN(lower)) - lower = includeCoord; - if (upper < includeCoord || qIsNaN(upper)) - upper = includeCoord; -} - - -/*! \overload - - Returns an expanded range that contains this and \a otherRange. It is assumed that both this - range and \a otherRange are normalized (see \ref normalize). - - If this range contains NaN as lower or upper bound, the returned range's bound will be taken from - \a otherRange. - - \see expand -*/ -QCPRange QCPRange::expanded(const QCPRange &otherRange) const -{ - QCPRange result = *this; - result.expand(otherRange); - return result; -} - -/*! \overload - - Returns an expanded range that includes the specified \a includeCoord. It is assumed that this - range is normalized (see \ref normalize). - - If this range contains NaN as lower or upper bound, the returned range's bound will be set to \a - includeCoord. - - \see expand -*/ -QCPRange QCPRange::expanded(double includeCoord) const -{ - QCPRange result = *this; - result.expand(includeCoord); - return result; -} - -/*! - Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a - upperBound. If possible, the size of the current range is preserved in the process. - - If the range shall only be bounded at the lower side, you can set \a upperBound to \ref - QCPRange::maxRange. If it shall only be bounded at the upper side, set \a lowerBound to -\ref - QCPRange::maxRange. -*/ -QCPRange QCPRange::bounded(double lowerBound, double upperBound) const -{ - if (lowerBound > upperBound) - qSwap(lowerBound, upperBound); - - QCPRange result(lower, upper); - if (result.lower < lowerBound) - { - result.lower = lowerBound; - result.upper = lowerBound + size(); - if (result.upper > upperBound || qFuzzyCompare(size(), upperBound-lowerBound)) - result.upper = upperBound; - } else if (result.upper > upperBound) - { - result.upper = upperBound; - result.lower = upperBound - size(); - if (result.lower < lowerBound || qFuzzyCompare(size(), upperBound-lowerBound)) - result.lower = lowerBound; - } - - return result; -} - -/*! - Returns a sanitized version of the range. Sanitized means for logarithmic scales, that - the range won't span the positive and negative sign domain, i.e. contain zero. Further - \a lower will always be numerically smaller (or equal) to \a upper. - - If the original range does span positive and negative sign domains or contains zero, - the returned range will try to approximate the original range as good as possible. - If the positive interval of the original range is wider than the negative interval, the - returned range will only contain the positive interval, with lower bound set to \a rangeFac or - \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval - is wider than the positive interval, this time by changing the \a upper bound. -*/ -QCPRange QCPRange::sanitizedForLogScale() const -{ - double rangeFac = 1e-3; - QCPRange sanitizedRange(lower, upper); - sanitizedRange.normalize(); - // can't have range spanning negative and positive values in log plot, so change range to fix it - //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) - if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) - { - // case lower is 0 - if (rangeFac < sanitizedRange.upper*rangeFac) - sanitizedRange.lower = rangeFac; - else - sanitizedRange.lower = sanitizedRange.upper*rangeFac; - } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) - else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) - { - // case upper is 0 - if (-rangeFac > sanitizedRange.lower*rangeFac) - sanitizedRange.upper = -rangeFac; - else - sanitizedRange.upper = sanitizedRange.lower*rangeFac; - } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) - { - // find out whether negative or positive interval is wider to decide which sign domain will be chosen - if (-sanitizedRange.lower > sanitizedRange.upper) - { - // negative is wider, do same as in case upper is 0 - if (-rangeFac > sanitizedRange.lower*rangeFac) - sanitizedRange.upper = -rangeFac; - else - sanitizedRange.upper = sanitizedRange.lower*rangeFac; - } else - { - // positive is wider, do same as in case lower is 0 - if (rangeFac < sanitizedRange.upper*rangeFac) - sanitizedRange.lower = rangeFac; - else - sanitizedRange.lower = sanitizedRange.upper*rangeFac; - } - } - // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper minRange && - upper < maxRange && - qAbs(lower-upper) > 1 && - qAbs(lower-upper) < maxRange - minRange); - -// return (lower > -maxRange && -// upper < maxRange && -// qAbs(lower-upper) > minRange && -// qAbs(lower-upper) < maxRange && -// !(lower > 0 && qIsInf(upper/lower)) && -// !(upper < 0 && qIsInf(lower/upper))); -} - -/*! - \overload - Checks, whether the specified range is within valid bounds, which are defined - as QCPRange::maxRange and QCPRange::minRange. - A valid range means: - \li range bounds within -maxRange and maxRange - \li range size above minRange - \li range size below maxRange -*/ -bool QCPRange::validRange(const QCPRange &range) -{ - return validRange(range.lower, range.upper); -// return (range.lower > -maxRange && -// range.upper < maxRange && -// qAbs(range.lower-range.upper) > minRange && -// qAbs(range.lower-range.upper) < maxRange && -// !(range.lower > 0 && qIsInf(range.upper/range.lower)) && -// !(range.upper < 0 && qIsInf(range.lower/range.upper))); -} -/* end of 'src/axis/range.cpp' */ - - -/* including file 'src/selection.cpp', size 21906 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPDataRange -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPDataRange - \brief Describes a data range given by begin and end index - - QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index - of a contiguous set of data points. The end index points to the data point above the last data point that's part of - the data range, similarly to the nomenclature used in standard iterators. - - Data Ranges are not bound to a certain plottable, thus they can be freely exchanged, created and - modified. If a non-contiguous data set shall be described, the class \ref QCPDataSelection is - used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref - QCPDataSelection is thus used. - - Both \ref QCPDataRange and \ref QCPDataSelection offer convenience methods to work with them, - e.g. \ref bounded, \ref expanded, \ref intersects, \ref intersection, \ref adjusted, \ref - contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be - used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding - \ref QCPDataSelection. - - %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and - QCPDataRange. - - \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval - in floating point plot coordinates, e.g. the current axis range. -*/ - -/* start documentation of inline functions */ - -/*! \fn int QCPDataRange::size() const - - Returns the number of data points described by this data range. This is equal to the end index - minus the begin index. - - \see length -*/ - -/*! \fn int QCPDataRange::length() const - - Returns the number of data points described by this data range. Equivalent to \ref size. -*/ - -/*! \fn void QCPDataRange::setBegin(int begin) - - Sets the begin of this data range. The \a begin index points to the first data point that is part - of the data range. - - No checks or corrections are made to ensure the resulting range is valid (\ref isValid). - - \see setEnd -*/ - -/*! \fn void QCPDataRange::setEnd(int end) - - Sets the end of this data range. The \a end index points to the data point just above the last - data point that is part of the data range. - - No checks or corrections are made to ensure the resulting range is valid (\ref isValid). - - \see setBegin -*/ - -/*! \fn bool QCPDataRange::isValid() const - - Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and - an end index greater or equal to the begin index. - - \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods - (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's - methods. The invalid range is not inherently prevented in QCPDataRange, to allow temporary - invalid begin/end values while manipulating the range. An invalid range is not necessarily empty - (\ref isEmpty), since its \ref length can be negative and thus non-zero. -*/ - -/*! \fn bool QCPDataRange::isEmpty() const - - Returns whether this range is empty, i.e. whether its begin index equals its end index. - - \see size, length -*/ - -/*! \fn QCPDataRange QCPDataRange::adjusted(int changeBegin, int changeEnd) const - - Returns a data range where \a changeBegin and \a changeEnd were added to the begin and end - indices, respectively. -*/ - -/* end documentation of inline functions */ - -/*! - Creates an empty QCPDataRange, with begin and end set to 0. -*/ -QCPDataRange::QCPDataRange() : - mBegin(0), - mEnd(0) -{ -} - -/*! - Creates a QCPDataRange, initialized with the specified \a begin and \a end. - - No checks or corrections are made to ensure the resulting range is valid (\ref isValid). -*/ -QCPDataRange::QCPDataRange(int begin, int end) : - mBegin(begin), - mEnd(end) -{ -} - -/*! - Returns a data range that matches this data range, except that parts exceeding \a other are - excluded. - - This method is very similar to \ref intersection, with one distinction: If this range and the \a - other range share no intersection, the returned data range will be empty with begin and end set - to the respective boundary side of \a other, at which this range is residing. (\ref intersection - would just return a range with begin and end set to 0.) -*/ -QCPDataRange QCPDataRange::bounded(const QCPDataRange &other) const -{ - QCPDataRange result(intersection(other)); - if (result.isEmpty()) // no intersection, preserve respective bounding side of otherRange as both begin and end of return value - { - if (mEnd <= other.mBegin) - result = QCPDataRange(other.mBegin, other.mBegin); - else - result = QCPDataRange(other.mEnd, other.mEnd); - } - return result; -} - -/*! - Returns a data range that contains both this data range as well as \a other. -*/ -QCPDataRange QCPDataRange::expanded(const QCPDataRange &other) const -{ - return QCPDataRange(qMin(mBegin, other.mBegin), qMax(mEnd, other.mEnd)); -} - -/*! - Returns the data range which is contained in both this data range and \a other. - - This method is very similar to \ref bounded, with one distinction: If this range and the \a other - range share no intersection, the returned data range will be empty with begin and end set to 0. - (\ref bounded would return a range with begin and end set to one of the boundaries of \a other, - depending on which side this range is on.) - - \see QCPDataSelection::intersection -*/ -QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const -{ - QCPDataRange result(qMax(mBegin, other.mBegin), qMin(mEnd, other.mEnd)); - if (result.isValid()) - return result; - else - return QCPDataRange(); -} - -/*! - Returns whether this data range and \a other share common data points. - - \see intersection, contains -*/ -bool QCPDataRange::intersects(const QCPDataRange &other) const -{ - return !( (mBegin > other.mBegin && mBegin >= other.mEnd) || - (mEnd <= other.mBegin && mEnd < other.mEnd) ); -} - -/*! - Returns whether all data points described by this data range are also in \a other. - - \see intersects -*/ -bool QCPDataRange::contains(const QCPDataRange &other) const -{ - return mBegin <= other.mBegin && mEnd >= other.mEnd; -} - - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPDataSelection -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPDataSelection - \brief Describes a data set by holding multiple QCPDataRange instances - - QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly - disjoint) set of data selection. - - The data selection can be modified with addition and subtraction operators which take - QCPDataSelection and QCPDataRange instances, as well as methods such as \ref addDataRange and - \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc. - - The method \ref simplify is used to join directly adjacent or even overlapping QCPDataRange - instances. QCPDataSelection automatically simplifies when using the addition/subtraction - operators. The only case when \ref simplify is left to the user, is when calling \ref - addDataRange, with the parameter \a simplify explicitly set to false. This is useful if many data - ranges will be added to the selection successively and the overhead for simplifying after each - iteration shall be avoided. In this case, you should make sure to call \ref simplify after - completing the operation. - - Use \ref enforceType to bring the data selection into a state complying with the constraints for - selections defined in \ref QCP::SelectionType. - - %QCustomPlot's \ref dataselection "data selection mechanism" is based on QCPDataSelection and - QCPDataRange. - - \section qcpdataselection-iterating Iterating over a data selection - - As an example, the following code snippet calculates the average value of a graph's data - \ref QCPAbstractPlottable::selection "selection": - - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpdataselection-iterating-1 - -*/ - -/* start documentation of inline functions */ - -/*! \fn int QCPDataSelection::dataRangeCount() const - - Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref - dataRange via their index. - - \see dataRange, dataPointCount -*/ - -/*! \fn QList QCPDataSelection::dataRanges() const - - Returns all data ranges that make up the data selection. If the data selection is simplified (the - usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point - index. - - \see dataRange -*/ - -/*! \fn bool QCPDataSelection::isEmpty() const - - Returns true if there are no data ranges, and thus no data points, in this QCPDataSelection - instance. - - \see dataRangeCount -*/ - -/* end documentation of inline functions */ - -/*! - Creates an empty QCPDataSelection. -*/ -QCPDataSelection::QCPDataSelection() -{ -} - -/*! - Creates a QCPDataSelection containing the provided \a range. -*/ -QCPDataSelection::QCPDataSelection(const QCPDataRange &range) -{ - mDataRanges.append(range); -} - -/*! - Returns true if this selection is identical (contains the same data ranges with the same begin - and end indices) to \a other. - - Note that both data selections must be in simplified state (the usual state of the selection, see - \ref simplify) for this operator to return correct results. -*/ -bool QCPDataSelection::operator==(const QCPDataSelection &other) const -{ - if (mDataRanges.size() != other.mDataRanges.size()) - return false; - for (int i=0; i= other.end()) - break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this - - if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored - { - if (thisBegin >= other.begin()) // range leading segment is encompassed - { - if (thisEnd <= other.end()) // range fully encompassed, remove completely - { - mDataRanges.removeAt(i); - continue; - } else // only leading segment is encompassed, trim accordingly - mDataRanges[i].setBegin(other.end()); - } else // leading segment is not encompassed - { - if (thisEnd <= other.end()) // only trailing segment is encompassed, trim accordingly - { - mDataRanges[i].setEnd(other.begin()); - } else // other lies inside this range, so split range - { - mDataRanges[i].setEnd(other.begin()); - mDataRanges.insert(i+1, QCPDataRange(other.end(), thisEnd)); - break; // since data ranges are sorted (and don't overlap) after simplify() call, we're done here - } - } - } - ++i; - } - - return *this; -} - -/*! - Returns the total number of data points contained in all data ranges that make up this data - selection. -*/ -int QCPDataSelection::dataPointCount() const -{ - int result = 0; - for (int i=0; i= 0 && index < mDataRanges.size()) - { - return mDataRanges.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of range:" << index; - return QCPDataRange(); - } -} - -/*! - Returns a \ref QCPDataRange which spans the entire data selection, including possible - intermediate segments which are not part of the original data selection. -*/ -QCPDataRange QCPDataSelection::span() const -{ - if (isEmpty()) - return QCPDataRange(); - else - return QCPDataRange(mDataRanges.first().begin(), mDataRanges.last().end()); -} - -/*! - Adds the given \a dataRange to this data selection. This is equivalent to the += operator but - allows disabling immediate simplification by setting \a simplify to false. This can improve - performance if adding a very large amount of data ranges successively. In this case, make sure to - call \ref simplify manually, after the operation. -*/ -void QCPDataSelection::addDataRange(const QCPDataRange &dataRange, bool simplify) -{ - mDataRanges.append(dataRange); - if (simplify) - this->simplify(); -} - -/*! - Removes all data ranges. The data selection then contains no data points. - - \ref isEmpty -*/ -void QCPDataSelection::clear() -{ - mDataRanges.clear(); -} - -/*! - Sorts all data ranges by range begin index in ascending order, and then joins directly adjacent - or overlapping ranges. This can reduce the number of individual data ranges in the selection, and - prevents possible double-counting when iterating over the data points held by the data ranges. - - This method is automatically called when using the addition/subtraction operators. The only case - when \ref simplify is left to the user, is when calling \ref addDataRange, with the parameter \a - simplify explicitly set to false. -*/ -void QCPDataSelection::simplify() -{ - // remove any empty ranges: - for (int i=mDataRanges.size()-1; i>=0; --i) - { - if (mDataRanges.at(i).isEmpty()) - mDataRanges.removeAt(i); - } - if (mDataRanges.isEmpty()) - return; - - // sort ranges by starting value, ascending: - std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin); - - // join overlapping/contiguous ranges: - int i = 1; - while (i < mDataRanges.size()) - { - if (mDataRanges.at(i-1).end() >= mDataRanges.at(i).begin()) // range i overlaps/joins with i-1, so expand range i-1 appropriately and remove range i from list - { - mDataRanges[i-1].setEnd(qMax(mDataRanges.at(i-1).end(), mDataRanges.at(i).end())); - mDataRanges.removeAt(i); - } else - ++i; - } -} - -/*! - Makes sure this data selection conforms to the specified \a type selection type. Before the type - is enforced, \ref simplify is called. - - Depending on \a type, enforcing means adding new data points that were previously not part of the - selection, or removing data points from the selection. If the current selection already conforms - to \a type, the data selection is not changed. - - \see QCP::SelectionType -*/ -void QCPDataSelection::enforceType(QCP::SelectionType type) -{ - simplify(); - switch (type) - { - case QCP::stNone: - { - mDataRanges.clear(); - break; - } - case QCP::stWhole: - { - // whole selection isn't defined by data range, so don't change anything (is handled in plottable methods) - break; - } - case QCP::stSingleData: - { - // reduce all data ranges to the single first data point: - if (!mDataRanges.isEmpty()) - { - if (mDataRanges.size() > 1) - mDataRanges = QList() << mDataRanges.first(); - if (mDataRanges.first().length() > 1) - mDataRanges.first().setEnd(mDataRanges.first().begin()+1); - } - break; - } - case QCP::stDataRange: - { - mDataRanges = QList() << span(); - break; - } - case QCP::stMultipleDataRanges: - { - // this is the selection type that allows all concievable combinations of ranges, so do nothing - break; - } - } -} - -/*! - Returns true if the data selection \a other is contained entirely in this data selection, i.e. - all data point indices that are in \a other are also in this data selection. - - \see QCPDataRange::contains -*/ -bool QCPDataSelection::contains(const QCPDataSelection &other) const -{ - if (other.isEmpty()) return false; - - int otherIndex = 0; - int thisIndex = 0; - while (thisIndex < mDataRanges.size() && otherIndex < other.mDataRanges.size()) - { - if (mDataRanges.at(thisIndex).contains(other.mDataRanges.at(otherIndex))) - ++otherIndex; - else - ++thisIndex; - } - return thisIndex < mDataRanges.size(); // if thisIndex ran all the way to the end to find a containing range for the current otherIndex, other is not contained in this -} - -/*! - Returns a data selection containing the points which are both in this data selection and in the - data range \a other. - - A common use case is to limit an unknown data selection to the valid range of a data container, - using \ref QCPDataContainer::dataRange as \a other. One can then safely iterate over the returned - data selection without exceeding the data container's bounds. -*/ -QCPDataSelection QCPDataSelection::intersection(const QCPDataRange &other) const -{ - QCPDataSelection result; - for (int i=0; iorientation() == Qt::Horizontal) - return QCPRange(axis->pixelToCoord(mRect.left()), axis->pixelToCoord(mRect.left()+mRect.width())); - else - return QCPRange(axis->pixelToCoord(mRect.top()+mRect.height()), axis->pixelToCoord(mRect.top())); - } else - { - qDebug() << Q_FUNC_INFO << "called with axis zero"; - return QCPRange(); - } -} - -/*! - Sets the pen that will be used to draw the selection rect outline. - - \see setBrush -*/ -void QCPSelectionRect::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the brush that will be used to fill the selection rect. By default the selection rect is not - filled, i.e. \a brush is Qt::NoBrush. - - \see setPen -*/ -void QCPSelectionRect::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - If there is currently a selection interaction going on (\ref isActive), the interaction is - canceled. The selection rect will emit the \ref canceled signal. -*/ -void QCPSelectionRect::cancel() -{ - if (mActive) - { - mActive = false; - emit canceled(mRect, 0); - } -} - -/*! \internal - - This method is called by QCustomPlot to indicate that a selection rect interaction was initiated. - The default implementation sets the selection rect to active, initializes the selection rect - geometry and emits the \ref started signal. -*/ -void QCPSelectionRect::startSelection(QMouseEvent *event) -{ - mActive = true; - mRect = QRect(event->pos(), event->pos()); - emit started(event); -} - -/*! \internal - - This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs - to update its geometry. The default implementation updates the rect and emits the \ref changed - signal. -*/ -void QCPSelectionRect::moveSelection(QMouseEvent *event) -{ - mRect.setBottomRight(event->pos()); - emit changed(mRect, event); - layer()->replot(); -} - -/*! \internal - - This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has - finished by the user releasing the mouse button. The default implementation deactivates the - selection rect and emits the \ref accepted signal. -*/ -void QCPSelectionRect::endSelection(QMouseEvent *event) -{ - mRect.setBottomRight(event->pos()); - mActive = false; - emit accepted(mRect, event); -} - -/*! \internal - - This method is called by QCustomPlot when a key has been pressed by the user while the selection - rect interaction is active. The default implementation allows to \ref cancel the interaction by - hitting the escape key. -*/ -void QCPSelectionRect::keyPressEvent(QKeyEvent *event) -{ - if (event->key() == Qt::Key_Escape && mActive) - { - mActive = false; - emit canceled(mRect, event); - } -} - -/* inherits documentation from base class */ -void QCPSelectionRect::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); -} - -/*! \internal - - If the selection rect is active (\ref isActive), draws the selection rect defined by \a mRect. - - \seebaseclassmethod -*/ -void QCPSelectionRect::draw(QCPPainter *painter) -{ - if (mActive) - { - painter->setPen(mPen); - painter->setBrush(mBrush); - painter->drawRect(mRect); - } -} -/* end of 'src/selectionrect.cpp' */ - - -/* including file 'src/layout.cpp', size 79064 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPMarginGroup -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPMarginGroup - \brief A margin group allows synchronization of margin sides if working with multiple layout elements. - - QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that - they will all have the same size, based on the largest required margin in the group. - - \n - \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" - \n - - In certain situations it is desirable that margins at specific sides are synchronized across - layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will - provide a cleaner look to the user if the left and right margins of the two axis rects are of the - same size. The left axis of the top axis rect will then be at the same horizontal position as the - left axis of the lower axis rect, making them appear aligned. The same applies for the right - axes. This is what QCPMarginGroup makes possible. - - To add/remove a specific side of a layout element to/from a margin group, use the \ref - QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call - \ref clear, or just delete the margin group. - - \section QCPMarginGroup-example Example - - First create a margin group: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 - Then set this group on the layout element sides: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-2 - Here, we've used the first two axis rects of the plot and synchronized their left margins with - each other and their right margins with each other. -*/ - -/* start documentation of inline functions */ - -/*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const - - Returns a list of all layout elements that have their margin \a side associated with this margin - group. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPMarginGroup instance in \a parentPlot. -*/ -QCPMarginGroup::QCPMarginGroup(QCustomPlot *parentPlot) : - QObject(parentPlot), - mParentPlot(parentPlot) -{ - mChildren.insert(QCP::msLeft, QList()); - mChildren.insert(QCP::msRight, QList()); - mChildren.insert(QCP::msTop, QList()); - mChildren.insert(QCP::msBottom, QList()); -} - -QCPMarginGroup::~QCPMarginGroup() -{ - clear(); -} - -/*! - Returns whether this margin group is empty. If this function returns true, no layout elements use - this margin group to synchronize margin sides. -*/ -bool QCPMarginGroup::isEmpty() const -{ - QHashIterator > it(mChildren); - while (it.hasNext()) - { - it.next(); - if (!it.value().isEmpty()) - return false; - } - return true; -} - -/*! - Clears this margin group. The synchronization of the margin sides that use this margin group is - lifted and they will use their individual margin sizes again. -*/ -void QCPMarginGroup::clear() -{ - // make all children remove themselves from this margin group: - QHashIterator > it(mChildren); - while (it.hasNext()) - { - it.next(); - const QList elements = it.value(); - for (int i=elements.size()-1; i>=0; --i) - elements.at(i)->setMarginGroup(it.key(), 0); // removes itself from mChildren via removeChild - } -} - -/*! \internal - - Returns the synchronized common margin for \a side. This is the margin value that will be used by - the layout element on the respective side, if it is part of this margin group. - - The common margin is calculated by requesting the automatic margin (\ref - QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin - group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into - account, too.) -*/ -int QCPMarginGroup::commonMargin(QCP::MarginSide side) const -{ - // query all automatic margins of the layout elements in this margin group side and find maximum: - int result = 0; - const QList elements = mChildren.value(side); - for (int i=0; iautoMargins().testFlag(side)) - continue; - int m = qMax(elements.at(i)->calculateAutoMargin(side), QCP::getMarginValue(elements.at(i)->minimumMargins(), side)); - if (m > result) - result = m; - } - return result; -} - -/*! \internal - - Adds \a element to the internal list of child elements, for the margin \a side. - - This function does not modify the margin group property of \a element. -*/ -void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) -{ - if (!mChildren[side].contains(element)) - mChildren[side].append(element); - else - qDebug() << Q_FUNC_INFO << "element is already child of this margin group side" << reinterpret_cast(element); -} - -/*! \internal - - Removes \a element from the internal list of child elements, for the margin \a side. - - This function does not modify the margin group property of \a element. -*/ -void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) -{ - if (!mChildren[side].removeOne(element)) - qDebug() << Q_FUNC_INFO << "element is not child of this margin group side" << reinterpret_cast(element); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayoutElement -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayoutElement - \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". - - This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. - - A Layout element is a rectangular object which can be placed in layouts. It has an outer rect - (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference - between outer and inner rect is called its margin. The margin can either be set to automatic or - manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be - set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, - the layout element subclass will control the value itself (via \ref calculateAutoMargin). - - Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level - layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref - QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. - - Thus in QCustomPlot one can divide layout elements into two categories: The ones that are - invisible by themselves, because they don't draw anything. Their only purpose is to manage the - position and size of other layout elements. This category of layout elements usually use - QCPLayout as base class. Then there is the category of layout elements which actually draw - something. For example, QCPAxisRect, QCPLegend and QCPTextElement are of this category. This does - not necessarily mean that the latter category can't have child layout elements. QCPLegend for - instance, actually derives from QCPLayoutGrid and the individual legend items are child layout - elements in the grid layout. -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPLayout *QCPLayoutElement::layout() const - - Returns the parent layout of this layout element. -*/ - -/*! \fn QRect QCPLayoutElement::rect() const - - Returns the inner rect of this layout element. The inner rect is the outer rect (\ref outerRect, \ref - setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). - - In some cases, the area between outer and inner rect is left blank. In other cases the margin - area is used to display peripheral graphics while the main content is in the inner rect. This is - where automatic margin calculation becomes interesting because it allows the layout element to - adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect - draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if - \ref setAutoMargins is enabled) according to the space required by the labels of the axes. - - \see outerRect -*/ - -/*! \fn QRect QCPLayoutElement::outerRect() const - - Returns the outer rect of this layout element. The outer rect is the inner rect expanded by the - margins (\ref setMargins, \ref setAutoMargins). The outer rect is used (and set via \ref - setOuterRect) by the parent \ref QCPLayout to control the size of this layout element. - - \see rect -*/ - -/* end documentation of inline functions */ - -/*! - Creates an instance of QCPLayoutElement and sets default values. -*/ -QCPLayoutElement::QCPLayoutElement(QCustomPlot *parentPlot) : - QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout) - mParentLayout(0), - mMinimumSize(), - mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), - mSizeConstraintRect(scrInnerRect), - mRect(0, 0, 0, 0), - mOuterRect(0, 0, 0, 0), - mMargins(0, 0, 0, 0), - mMinimumMargins(0, 0, 0, 0), - mAutoMargins(QCP::msAll) -{ -} - -QCPLayoutElement::~QCPLayoutElement() -{ - setMarginGroup(QCP::msAll, 0); // unregister at margin groups, if there are any - // unregister at layout: - if (qobject_cast(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor - mParentLayout->take(this); -} - -/*! - Sets the outer rect of this layout element. If the layout element is inside a layout, the layout - sets the position and size of this layout element using this function. - - Calling this function externally has no effect, since the layout will overwrite any changes to - the outer rect upon the next replot. - - The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. - - \see rect -*/ -void QCPLayoutElement::setOuterRect(const QRect &rect) -{ - if (mOuterRect != rect) - { - mOuterRect = rect; - mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); - } -} - -/*! - Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all - sides, this function is used to manually set the margin on those sides. Sides that are still set - to be handled automatically are ignored and may have any value in \a margins. - - The margin is the distance between the outer rect (controlled by the parent layout via \ref - setOuterRect) and the inner \ref rect (which usually contains the main content of this layout - element). - - \see setAutoMargins -*/ -void QCPLayoutElement::setMargins(const QMargins &margins) -{ - if (mMargins != margins) - { - mMargins = margins; - mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); - } -} - -/*! - If \ref setAutoMargins is enabled on some or all margins, this function is used to provide - minimum values for those margins. - - The minimum values are not enforced on margin sides that were set to be under manual control via - \ref setAutoMargins. - - \see setAutoMargins -*/ -void QCPLayoutElement::setMinimumMargins(const QMargins &margins) -{ - if (mMinimumMargins != margins) - { - mMinimumMargins = margins; - } -} - -/*! - Sets on which sides the margin shall be calculated automatically. If a side is calculated - automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is - set to be controlled manually, the value may be specified with \ref setMargins. - - Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref - setMarginGroup), to synchronize (align) it with other layout elements in the plot. - - \see setMinimumMargins, setMargins, QCP::MarginSide -*/ -void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) -{ - mAutoMargins = sides; -} - -/*! - Sets the minimum size of this layout element. A parent layout tries to respect the \a size here - by changing row/column sizes in the layout accordingly. - - If the parent layout size is not sufficient to satisfy all minimum size constraints of its child - layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot - propagates the layout's size constraints to the outside by setting its own minimum QWidget size - accordingly, so violations of \a size should be exceptions. - - Whether this constraint applies to the inner or the outer rect can be specified with \ref - setSizeConstraintRect (see \ref rect and \ref outerRect). -*/ -void QCPLayoutElement::setMinimumSize(const QSize &size) -{ - if (mMinimumSize != size) - { - mMinimumSize = size; - if (mParentLayout) - mParentLayout->sizeConstraintsChanged(); - } -} - -/*! \overload - - Sets the minimum size of this layout element. - - Whether this constraint applies to the inner or the outer rect can be specified with \ref - setSizeConstraintRect (see \ref rect and \ref outerRect). -*/ -void QCPLayoutElement::setMinimumSize(int width, int height) -{ - setMinimumSize(QSize(width, height)); -} - -/*! - Sets the maximum size of this layout element. A parent layout tries to respect the \a size here - by changing row/column sizes in the layout accordingly. - - Whether this constraint applies to the inner or the outer rect can be specified with \ref - setSizeConstraintRect (see \ref rect and \ref outerRect). -*/ -void QCPLayoutElement::setMaximumSize(const QSize &size) -{ - if (mMaximumSize != size) - { - mMaximumSize = size; - if (mParentLayout) - mParentLayout->sizeConstraintsChanged(); - } -} - -/*! \overload - - Sets the maximum size of this layout element. - - Whether this constraint applies to the inner or the outer rect can be specified with \ref - setSizeConstraintRect (see \ref rect and \ref outerRect). -*/ -void QCPLayoutElement::setMaximumSize(int width, int height) -{ - setMaximumSize(QSize(width, height)); -} - -/*! - Sets to which rect of a layout element the size constraints apply. Size constraints can be set - via \ref setMinimumSize and \ref setMaximumSize. - - The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis - labels), whereas the inner rect (\ref rect) does not. - - \see setMinimumSize, setMaximumSize -*/ -void QCPLayoutElement::setSizeConstraintRect(SizeConstraintRect constraintRect) -{ - if (mSizeConstraintRect != constraintRect) - { - mSizeConstraintRect = constraintRect; - if (mParentLayout) - mParentLayout->sizeConstraintsChanged(); - } -} - -/*! - Sets the margin \a group of the specified margin \a sides. - - Margin groups allow synchronizing specified margins across layout elements, see the documentation - of \ref QCPMarginGroup. - - To unset the margin group of \a sides, set \a group to 0. - - Note that margin groups only work for margin sides that are set to automatic (\ref - setAutoMargins). - - \see QCP::MarginSide -*/ -void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) -{ - QVector sideVector; - if (sides.testFlag(QCP::msLeft)) sideVector.append(QCP::msLeft); - if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); - if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); - if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); - - for (int i=0; iremoveChild(side, this); - - if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there - { - mMarginGroups.remove(side); - } else // setting to a new group - { - mMarginGroups[side] = group; - group->addChild(side, this); - } - } - } -} - -/*! - Updates the layout element and sub-elements. This function is automatically called before every - replot by the parent layout element. It is called multiple times, once for every \ref - UpdatePhase. The phases are run through in the order of the enum values. For details about what - happens at the different phases, see the documentation of \ref UpdatePhase. - - Layout elements that have child elements should call the \ref update method of their child - elements, and pass the current \a phase unchanged. - - The default implementation executes the automatic margin mechanism in the \ref upMargins phase. - Subclasses should make sure to call the base class implementation. -*/ -void QCPLayoutElement::update(UpdatePhase phase) -{ - if (phase == upMargins) - { - if (mAutoMargins != QCP::msNone) - { - // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group: - QMargins newMargins = mMargins; - QList allMarginSides = QList() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom; - foreach (QCP::MarginSide side, allMarginSides) - { - if (mAutoMargins.testFlag(side)) // this side's margin shall be calculated automatically - { - if (mMarginGroups.contains(side)) - QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group - else - QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly - // apply minimum margin restrictions: - if (QCP::getMarginValue(newMargins, side) < QCP::getMarginValue(mMinimumMargins, side)) - QCP::setMarginValue(newMargins, side, QCP::getMarginValue(mMinimumMargins, side)); - } - } - setMargins(newMargins); - } - } -} - -/*! - Returns the suggested minimum size this layout element (the \ref outerRect) may be compressed to, - if no manual minimum size is set. - - if a minimum size (\ref setMinimumSize) was not set manually, parent layouts use the returned size - (usually indirectly through \ref QCPLayout::getFinalMinimumOuterSize) to determine the minimum - allowed size of this layout element. - - A manual minimum size is considered set if it is non-zero. - - The default implementation simply returns the sum of the horizontal margins for the width and the - sum of the vertical margins for the height. Reimplementations may use their detailed knowledge - about the layout element's content to provide size hints. -*/ -QSize QCPLayoutElement::minimumOuterSizeHint() const -{ - return QSize(mMargins.left()+mMargins.right(), mMargins.top()+mMargins.bottom()); -} - -/*! - Returns the suggested maximum size this layout element (the \ref outerRect) may be expanded to, - if no manual maximum size is set. - - if a maximum size (\ref setMaximumSize) was not set manually, parent layouts use the returned - size (usually indirectly through \ref QCPLayout::getFinalMaximumOuterSize) to determine the - maximum allowed size of this layout element. - - A manual maximum size is considered set if it is smaller than Qt's \c QWIDGETSIZE_MAX. - - The default implementation simply returns \c QWIDGETSIZE_MAX for both width and height, implying - no suggested maximum size. Reimplementations may use their detailed knowledge about the layout - element's content to provide size hints. -*/ -QSize QCPLayoutElement::maximumOuterSizeHint() const -{ - return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); -} - -/*! - Returns a list of all child elements in this layout element. If \a recursive is true, all - sub-child elements are included in the list, too. - - \warning There may be entries with value 0 in the returned list. (For example, QCPLayoutGrid may have - empty cells which yield 0 at the respective index.) -*/ -QList QCPLayoutElement::elements(bool recursive) const -{ - Q_UNUSED(recursive) - return QList(); -} - -/*! - Layout elements are sensitive to events inside their outer rect. If \a pos is within the outer - rect, this method returns a value corresponding to 0.99 times the parent plot's selection - tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is - true, -1.0 is returned. - - See \ref QCPLayerable::selectTest for a general explanation of this virtual method. - - QCPLayoutElement subclasses may reimplement this method to provide more specific selection test - behaviour. -*/ -double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - - if (onlySelectable) - return -1; - - if (QRectF(mOuterRect).contains(pos)) - { - if (mParentPlot) - return mParentPlot->selectionTolerance()*0.99; - else - { - qDebug() << Q_FUNC_INFO << "parent plot not defined"; - return -1; - } - } else - return -1; -} - -/*! \internal - - propagates the parent plot initialization to all child elements, by calling \ref - QCPLayerable::initializeParentPlot on them. -*/ -void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) -{ - foreach (QCPLayoutElement* el, elements(false)) - { - if (!el->parentPlot()) - el->initializeParentPlot(parentPlot); - } -} - -/*! \internal - - Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a - side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the - returned value will not be smaller than the specified minimum margin. - - The default implementation just returns the respective manual margin (\ref setMargins) or the - minimum margin, whichever is larger. -*/ -int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) -{ - return qMax(QCP::getMarginValue(mMargins, side), QCP::getMarginValue(mMinimumMargins, side)); -} - -/*! \internal - - This virtual method is called when this layout element was moved to a different QCPLayout, or - when this layout element has changed its logical position (e.g. row and/or column) within the - same QCPLayout. Subclasses may use this to react accordingly. - - Since this method is called after the completion of the move, you can access the new parent - layout via \ref layout(). - - The default implementation does nothing. -*/ -void QCPLayoutElement::layoutChanged() -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayout -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayout - \brief The abstract base class for layouts - - This is an abstract base class for layout elements whose main purpose is to define the position - and size of other child layout elements. In most cases, layouts don't draw anything themselves - (but there are exceptions to this, e.g. QCPLegend). - - QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. - - QCPLayout introduces a common interface for accessing and manipulating the child elements. Those - functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref - simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions - to this interface which are more specialized to the form of the layout. For example, \ref - QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid - more conveniently. - - Since this is an abstract base class, you can't instantiate it directly. Rather use one of its - subclasses like QCPLayoutGrid or QCPLayoutInset. - - For a general introduction to the layout system, see the dedicated documentation page \ref - thelayoutsystem "The Layout System". -*/ - -/* start documentation of pure virtual functions */ - -/*! \fn virtual int QCPLayout::elementCount() const = 0 - - Returns the number of elements/cells in the layout. - - \see elements, elementAt -*/ - -/*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 - - Returns the element in the cell with the given \a index. If \a index is invalid, returns 0. - - Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. - QCPLayoutGrid), so this function may return 0 in those cases. You may use this function to check - whether a cell is empty or not. - - \see elements, elementCount, takeAt -*/ - -/*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 - - Removes the element with the given \a index from the layout and returns it. - - If the \a index is invalid or the cell with that index is empty, returns 0. - - Note that some layouts don't remove the respective cell right away but leave an empty cell after - successful removal of the layout element. To collapse empty cells, use \ref simplify. - - \see elementAt, take -*/ - -/*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 - - Removes the specified \a element from the layout and returns true on success. - - If the \a element isn't in this layout, returns false. - - Note that some layouts don't remove the respective cell right away but leave an empty cell after - successful removal of the layout element. To collapse empty cells, use \ref simplify. - - \see takeAt -*/ - -/* end documentation of pure virtual functions */ - -/*! - Creates an instance of QCPLayout and sets default values. Note that since QCPLayout - is an abstract base class, it can't be instantiated directly. -*/ -QCPLayout::QCPLayout() -{ -} - -/*! - If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to - reposition and resize their cells. - - Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements". - - For details about this method and the update phases, see the documentation of \ref - QCPLayoutElement::update. -*/ -void QCPLayout::update(UpdatePhase phase) -{ - QCPLayoutElement::update(phase); - - // set child element rects according to layout: - if (phase == upLayout) - updateLayout(); - - // propagate update call to child elements: - const int elCount = elementCount(); - for (int i=0; iupdate(phase); - } -} - -/* inherits documentation from base class */ -QList QCPLayout::elements(bool recursive) const -{ - const int c = elementCount(); - QList result; -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - result.reserve(c); -#endif - for (int i=0; ielements(recursive); - } - } - return result; -} - -/*! - Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the - default implementation does nothing. - - Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit - simplification while QCPLayoutGrid does. -*/ -void QCPLayout::simplify() -{ -} - -/*! - Removes and deletes the element at the provided \a index. Returns true on success. If \a index is - invalid or points to an empty cell, returns false. - - This function internally uses \ref takeAt to remove the element from the layout and then deletes - the returned element. Note that some layouts don't remove the respective cell right away but leave an - empty cell after successful removal of the layout element. To collapse empty cells, use \ref - simplify. - - \see remove, takeAt -*/ -bool QCPLayout::removeAt(int index) -{ - if (QCPLayoutElement *el = takeAt(index)) - { - delete el; - return true; - } else - return false; -} - -/*! - Removes and deletes the provided \a element. Returns true on success. If \a element is not in the - layout, returns false. - - This function internally uses \ref takeAt to remove the element from the layout and then deletes - the element. Note that some layouts don't remove the respective cell right away but leave an - empty cell after successful removal of the layout element. To collapse empty cells, use \ref - simplify. - - \see removeAt, take -*/ -bool QCPLayout::remove(QCPLayoutElement *element) -{ - if (take(element)) - { - delete element; - return true; - } else - return false; -} - -/*! - Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure - all empty cells are collapsed. - - \see remove, removeAt -*/ -void QCPLayout::clear() -{ - for (int i=elementCount()-1; i>=0; --i) - { - if (elementAt(i)) - removeAt(i); - } - simplify(); -} - -/*! - Subclasses call this method to report changed (minimum/maximum) size constraints. - - If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref - sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of - QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, - it may update itself and resize cells accordingly. -*/ -void QCPLayout::sizeConstraintsChanged() const -{ - if (QWidget *w = qobject_cast(parent())) - w->updateGeometry(); - else if (QCPLayout *l = qobject_cast(parent())) - l->sizeConstraintsChanged(); -} - -/*! \internal - - Subclasses reimplement this method to update the position and sizes of the child elements/cells - via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. - - The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay - within that rect. - - \ref getSectionSizes may help with the reimplementation of this function. - - \see update -*/ -void QCPLayout::updateLayout() -{ -} - - -/*! \internal - - Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the - \ref QCPLayerable::parentLayerable and the QObject parent to this layout. - - Further, if \a el didn't previously have a parent plot, calls \ref - QCPLayerable::initializeParentPlot on \a el to set the paret plot. - - This method is used by subclass specific methods that add elements to the layout. Note that this - method only changes properties in \a el. The removal from the old layout and the insertion into - the new layout must be done additionally. -*/ -void QCPLayout::adoptElement(QCPLayoutElement *el) -{ - if (el) - { - el->mParentLayout = this; - el->setParentLayerable(this); - el->setParent(this); - if (!el->parentPlot()) - el->initializeParentPlot(mParentPlot); - el->layoutChanged(); - } else - qDebug() << Q_FUNC_INFO << "Null element passed"; -} - -/*! \internal - - Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout - and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent - QCustomPlot. - - This method is used by subclass specific methods that remove elements from the layout (e.g. \ref - take or \ref takeAt). Note that this method only changes properties in \a el. The removal from - the old layout must be done additionally. -*/ -void QCPLayout::releaseElement(QCPLayoutElement *el) -{ - if (el) - { - el->mParentLayout = 0; - el->setParentLayerable(0); - el->setParent(mParentPlot); - // Note: Don't initializeParentPlot(0) here, because layout element will stay in same parent plot - } else - qDebug() << Q_FUNC_INFO << "Null element passed"; -} - -/*! \internal - - This is a helper function for the implementation of \ref updateLayout in subclasses. - - It calculates the sizes of one-dimensional sections with provided constraints on maximum section - sizes, minimum section sizes, relative stretch factors and the final total size of all sections. - - The QVector entries refer to the sections. Thus all QVectors must have the same size. - - \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size - imposed, set all vector values to Qt's QWIDGETSIZE_MAX. - - \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size - imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than - \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, - not exceeding the allowed total size is taken to be more important than not going below minimum - section sizes.) - - \a stretchFactors give the relative proportions of the sections to each other. If all sections - shall be scaled equally, set all values equal. If the first section shall be double the size of - each individual other section, set the first number of \a stretchFactors to double the value of - the other individual values (e.g. {2, 1, 1, 1}). - - \a totalSize is the value that the final section sizes will add up to. Due to rounding, the - actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, - you could distribute the remaining difference on the sections. - - The return value is a QVector containing the section sizes. -*/ -QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const -{ - if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) - { - qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; - return QVector(); - } - if (stretchFactors.isEmpty()) - return QVector(); - int sectionCount = stretchFactors.size(); - QVector sectionSizes(sectionCount); - // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): - int minSizeSum = 0; - for (int i=0; i minimumLockedSections; - QList unfinishedSections; - for (int i=0; i result(sectionCount); - for (int i=0; iminimumOuterSizeHint(); - QSize minOuter = el->minimumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset minimum of 0) - if (minOuter.width() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) - minOuter.rwidth() += el->margins().left() + el->margins().right(); - if (minOuter.height() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) - minOuter.rheight() += el->margins().top() + el->margins().bottom(); - - return QSize(minOuter.width() > 0 ? minOuter.width() : minOuterHint.width(), - minOuter.height() > 0 ? minOuter.height() : minOuterHint.height());; -} - -/*! \internal - - This is a helper function for the implementation of subclasses. - - It returns the maximum size that should finally be used for the outer rect of the passed layout - element \a el. - - It takes into account whether a manual maximum size is set (\ref - QCPLayoutElement::setMaximumSize), which size constraint is set (\ref - QCPLayoutElement::setSizeConstraintRect), as well as the maximum size hint, if no manual maximum - size was set (\ref QCPLayoutElement::maximumOuterSizeHint). -*/ -QSize QCPLayout::getFinalMaximumOuterSize(const QCPLayoutElement *el) -{ - QSize maxOuterHint = el->maximumOuterSizeHint(); - QSize maxOuter = el->maximumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset maximum of QWIDGETSIZE_MAX) - if (maxOuter.width() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) - maxOuter.rwidth() += el->margins().left() + el->margins().right(); - if (maxOuter.height() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) - maxOuter.rheight() += el->margins().top() + el->margins().bottom(); - - return QSize(maxOuter.width() < QWIDGETSIZE_MAX ? maxOuter.width() : maxOuterHint.width(), - maxOuter.height() < QWIDGETSIZE_MAX ? maxOuter.height() : maxOuterHint.height()); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayoutGrid -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayoutGrid - \brief A layout that arranges child elements in a grid - - Elements are laid out in a grid with configurable stretch factors (\ref setColumnStretchFactor, - \ref setRowStretchFactor) and spacing (\ref setColumnSpacing, \ref setRowSpacing). - - Elements can be added to cells via \ref addElement. The grid is expanded if the specified row or - column doesn't exist yet. Whether a cell contains a valid layout element can be checked with \ref - hasElement, that element can be retrieved with \ref element. If rows and columns that only have - empty cells shall be removed, call \ref simplify. Removal of elements is either done by just - adding the element to a different layout or by using the QCPLayout interface \ref take or \ref - remove. - - If you use \ref addElement(QCPLayoutElement*) without explicit parameters for \a row and \a - column, the grid layout will choose the position according to the current \ref setFillOrder and - the wrapping (\ref setWrap). - - Row and column insertion can be performed with \ref insertRow and \ref insertColumn. -*/ - -/* start documentation of inline functions */ - -/*! \fn int QCPLayoutGrid::rowCount() const - - Returns the number of rows in the layout. - - \see columnCount -*/ - -/*! \fn int QCPLayoutGrid::columnCount() const - - Returns the number of columns in the layout. - - \see rowCount -*/ - -/* end documentation of inline functions */ - -/*! - Creates an instance of QCPLayoutGrid and sets default values. -*/ -QCPLayoutGrid::QCPLayoutGrid() : - mColumnSpacing(5), - mRowSpacing(5), - mWrap(0), - mFillOrder(foRowsFirst) -{ -} - -QCPLayoutGrid::~QCPLayoutGrid() -{ - // clear all child layout elements. This is important because only the specific layouts know how - // to handle removing elements (clear calls virtual removeAt method to do that). - clear(); -} - -/*! - Returns the element in the cell in \a row and \a column. - - Returns 0 if either the row/column is invalid or if the cell is empty. In those cases, a qDebug - message is printed. To check whether a cell exists and isn't empty, use \ref hasElement. - - \see addElement, hasElement -*/ -QCPLayoutElement *QCPLayoutGrid::element(int row, int column) const -{ - if (row >= 0 && row < mElements.size()) - { - if (column >= 0 && column < mElements.first().size()) - { - if (QCPLayoutElement *result = mElements.at(row).at(column)) - return result; - else - qDebug() << Q_FUNC_INFO << "Requested cell is empty. Row:" << row << "Column:" << column; - } else - qDebug() << Q_FUNC_INFO << "Invalid column. Row:" << row << "Column:" << column; - } else - qDebug() << Q_FUNC_INFO << "Invalid row. Row:" << row << "Column:" << column; - return 0; -} - - -/*! \overload - - Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it - is first removed from there. If \a row or \a column don't exist yet, the layout is expanded - accordingly. - - Returns true if the element was added successfully, i.e. if the cell at \a row and \a column - didn't already have an element. - - Use the overload of this method without explicit row/column index to place the element according - to the configured fill order and wrapping settings. - - \see element, hasElement, take, remove -*/ -bool QCPLayoutGrid::addElement(int row, int column, QCPLayoutElement *element) -{ - if (!hasElement(row, column)) - { - if (element && element->layout()) // remove from old layout first - element->layout()->take(element); - expandTo(row+1, column+1); - mElements[row][column] = element; - if (element) - adoptElement(element); - return true; - } else - qDebug() << Q_FUNC_INFO << "There is already an element in the specified row/column:" << row << column; - return false; -} - -/*! \overload - - Adds the \a element to the next empty cell according to the current fill order (\ref - setFillOrder) and wrapping (\ref setWrap). If \a element is already in a layout, it is first - removed from there. If necessary, the layout is expanded to hold the new element. - - Returns true if the element was added successfully. - - \see setFillOrder, setWrap, element, hasElement, take, remove -*/ -bool QCPLayoutGrid::addElement(QCPLayoutElement *element) -{ - int rowIndex = 0; - int colIndex = 0; - if (mFillOrder == foColumnsFirst) - { - while (hasElement(rowIndex, colIndex)) - { - ++colIndex; - if (colIndex >= mWrap && mWrap > 0) - { - colIndex = 0; - ++rowIndex; - } - } - } else - { - while (hasElement(rowIndex, colIndex)) - { - ++rowIndex; - if (rowIndex >= mWrap && mWrap > 0) - { - rowIndex = 0; - ++colIndex; - } - } - } - return addElement(rowIndex, colIndex, element); -} - -/*! - Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't - empty. - - \see element -*/ -bool QCPLayoutGrid::hasElement(int row, int column) -{ - if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) - return mElements.at(row).at(column); - else - return false; -} - -/*! - Sets the stretch \a factor of \a column. - - Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond - their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref - QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref - QCPLayoutElement::setSizeConstraintRect.) - - The default stretch factor of newly created rows/columns is 1. - - \see setColumnStretchFactors, setRowStretchFactor -*/ -void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) -{ - if (column >= 0 && column < columnCount()) - { - if (factor > 0) - mColumnStretchFactors[column] = factor; - else - qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; - } else - qDebug() << Q_FUNC_INFO << "Invalid column:" << column; -} - -/*! - Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. - - Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond - their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref - QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref - QCPLayoutElement::setSizeConstraintRect.) - - The default stretch factor of newly created rows/columns is 1. - - \see setColumnStretchFactor, setRowStretchFactors -*/ -void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) -{ - if (factors.size() == mColumnStretchFactors.size()) - { - mColumnStretchFactors = factors; - for (int i=0; i= 0 && row < rowCount()) - { - if (factor > 0) - mRowStretchFactors[row] = factor; - else - qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; - } else - qDebug() << Q_FUNC_INFO << "Invalid row:" << row; -} - -/*! - Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. - - Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond - their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref - QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref - QCPLayoutElement::setSizeConstraintRect.) - - The default stretch factor of newly created rows/columns is 1. - - \see setRowStretchFactor, setColumnStretchFactors -*/ -void QCPLayoutGrid::setRowStretchFactors(const QList &factors) -{ - if (factors.size() == mRowStretchFactors.size()) - { - mRowStretchFactors = factors; - for (int i=0; i tempElements; - if (rearrange) - { - tempElements.reserve(elCount); - for (int i=0; i()); - mRowStretchFactors.append(1); - } - // go through rows and expand columns as necessary: - int newColCount = qMax(columnCount(), newColumnCount); - for (int i=0; i rowCount()) - newIndex = rowCount(); - - mRowStretchFactors.insert(newIndex, 1); - QList newRow; - for (int col=0; col columnCount()) - newIndex = columnCount(); - - mColumnStretchFactors.insert(newIndex, 1); - for (int row=0; row= 0 && row < rowCount()) - { - if (column >= 0 && column < columnCount()) - { - switch (mFillOrder) - { - case foRowsFirst: return column*rowCount() + row; - case foColumnsFirst: return row*columnCount() + column; - } - } else - qDebug() << Q_FUNC_INFO << "row index out of bounds:" << row; - } else - qDebug() << Q_FUNC_INFO << "column index out of bounds:" << column; - return 0; -} - -/*! - Converts the linear index to row and column indices and writes the result to \a row and \a - column. - - The way the cells are indexed depends on \ref setFillOrder. If it is \ref foRowsFirst, the - indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices - increase top to bottom and then left to right. - - If there are no cells (i.e. column or row count is zero), sets \a row and \a column to -1. - - For the retrieved \a row and \a column to be valid, the passed \a index must be valid itself, - i.e. greater or equal to zero and smaller than the current \ref elementCount. - - \see rowColToIndex -*/ -void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const -{ - row = -1; - column = -1; - const int nCols = columnCount(); - const int nRows = rowCount(); - if (nCols == 0 || nRows == 0) - return; - if (index < 0 || index >= elementCount()) - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return; - } - - switch (mFillOrder) - { - case foRowsFirst: - { - column = index / nRows; - row = index % nRows; - break; - } - case foColumnsFirst: - { - row = index / nCols; - column = index % nCols; - break; - } - } -} - -/* inherits documentation from base class */ -void QCPLayoutGrid::updateLayout() -{ - QVector minColWidths, minRowHeights, maxColWidths, maxRowHeights; - getMinimumRowColSizes(&minColWidths, &minRowHeights); - getMaximumRowColSizes(&maxColWidths, &maxRowHeights); - - int totalRowSpacing = (rowCount()-1) * mRowSpacing; - int totalColSpacing = (columnCount()-1) * mColumnSpacing; - QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); - QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); - - // go through cells and set rects accordingly: - int yOffset = mRect.top(); - for (int row=0; row 0) - yOffset += rowHeights.at(row-1)+mRowSpacing; - int xOffset = mRect.left(); - for (int col=0; col 0) - xOffset += colWidths.at(col-1)+mColumnSpacing; - if (mElements.at(row).at(col)) - mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row))); - } - } -} - -/*! - \seebaseclassmethod - - Note that the association of the linear \a index to the row/column based cells depends on the - current setting of \ref setFillOrder. - - \see rowColToIndex -*/ -QCPLayoutElement *QCPLayoutGrid::elementAt(int index) const -{ - if (index >= 0 && index < elementCount()) - { - int row, col; - indexToRowCol(index, row, col); - return mElements.at(row).at(col); - } else - return 0; -} - -/*! - \seebaseclassmethod - - Note that the association of the linear \a index to the row/column based cells depends on the - current setting of \ref setFillOrder. - - \see rowColToIndex -*/ -QCPLayoutElement *QCPLayoutGrid::takeAt(int index) -{ - if (QCPLayoutElement *el = elementAt(index)) - { - releaseElement(el); - int row, col; - indexToRowCol(index, row, col); - mElements[row][col] = 0; - return el; - } else - { - qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; - return 0; - } -} - -/* inherits documentation from base class */ -bool QCPLayoutGrid::take(QCPLayoutElement *element) -{ - if (element) - { - for (int i=0; i QCPLayoutGrid::elements(bool recursive) const -{ - QList result; - const int elCount = elementCount(); -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - result.reserve(elCount); -#endif - for (int i=0; ielements(recursive); - } - } - return result; -} - -/*! - Simplifies the layout by collapsing rows and columns which only contain empty cells. -*/ -void QCPLayoutGrid::simplify() -{ - // remove rows with only empty cells: - for (int row=rowCount()-1; row>=0; --row) - { - bool hasElements = false; - for (int col=0; col=0; --col) - { - bool hasElements = false; - for (int row=0; row minColWidths, minRowHeights; - getMinimumRowColSizes(&minColWidths, &minRowHeights); - QSize result(0, 0); - for (int i=0; i maxColWidths, maxRowHeights; - getMaximumRowColSizes(&maxColWidths, &maxRowHeights); - - QSize result(0, 0); - for (int i=0; i QWIDGETSIZE_MAX) - result.setHeight(QWIDGETSIZE_MAX); - if (result.width() > QWIDGETSIZE_MAX) - result.setWidth(QWIDGETSIZE_MAX); - return result; -} - -/*! \internal - - Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights - respectively. - - The minimum height of a row is the largest minimum height of any element's outer rect in that - row. The minimum width of a column is the largest minimum width of any element's outer rect in - that column. - - This is a helper function for \ref updateLayout. - - \see getMaximumRowColSizes -*/ -void QCPLayoutGrid::getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const -{ - *minColWidths = QVector(columnCount(), 0); - *minRowHeights = QVector(rowCount(), 0); - for (int row=0; rowat(col) < minSize.width()) - (*minColWidths)[col] = minSize.width(); - if (minRowHeights->at(row) < minSize.height()) - (*minRowHeights)[row] = minSize.height(); - } - } - } -} - -/*! \internal - - Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights - respectively. - - The maximum height of a row is the smallest maximum height of any element's outer rect in that - row. The maximum width of a column is the smallest maximum width of any element's outer rect in - that column. - - This is a helper function for \ref updateLayout. - - \see getMinimumRowColSizes -*/ -void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const -{ - *maxColWidths = QVector(columnCount(), QWIDGETSIZE_MAX); - *maxRowHeights = QVector(rowCount(), QWIDGETSIZE_MAX); - for (int row=0; rowat(col) > maxSize.width()) - (*maxColWidths)[col] = maxSize.width(); - if (maxRowHeights->at(row) > maxSize.height()) - (*maxRowHeights)[row] = maxSize.height(); - } - } - } -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayoutInset -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPLayoutInset - \brief A layout that places child elements aligned to the border or arbitrarily positioned - - Elements are placed either aligned to the border or at arbitrary position in the area of the - layout. Which placement applies is controlled with the \ref InsetPlacement (\ref - setInsetPlacement). - - Elements are added via \ref addElement(QCPLayoutElement *element, Qt::Alignment alignment) or - addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset - placement will default to \ref ipBorderAligned and the element will be aligned according to the - \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at - arbitrary position and size, defined by \a rect. - - The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively. - - This is the layout that every QCPAxisRect has as \ref QCPAxisRect::insetLayout. -*/ - -/* start documentation of inline functions */ - -/*! \fn virtual void QCPLayoutInset::simplify() - - The QCPInsetLayout does not need simplification since it can never have empty cells due to its - linear index structure. This method does nothing. -*/ - -/* end documentation of inline functions */ - -/*! - Creates an instance of QCPLayoutInset and sets default values. -*/ -QCPLayoutInset::QCPLayoutInset() -{ -} - -QCPLayoutInset::~QCPLayoutInset() -{ - // clear all child layout elements. This is important because only the specific layouts know how - // to handle removing elements (clear calls virtual removeAt method to do that). - clear(); -} - -/*! - Returns the placement type of the element with the specified \a index. -*/ -QCPLayoutInset::InsetPlacement QCPLayoutInset::insetPlacement(int index) const -{ - if (elementAt(index)) - return mInsetPlacement.at(index); - else - { - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; - return ipFree; - } -} - -/*! - Returns the alignment of the element with the specified \a index. The alignment only has a - meaning, if the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned. -*/ -Qt::Alignment QCPLayoutInset::insetAlignment(int index) const -{ - if (elementAt(index)) - return mInsetAlignment.at(index); - else - { - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; - return 0; - } -} - -/*! - Returns the rect of the element with the specified \a index. The rect only has a - meaning, if the inset placement (\ref setInsetPlacement) is \ref ipFree. -*/ -QRectF QCPLayoutInset::insetRect(int index) const -{ - if (elementAt(index)) - return mInsetRect.at(index); - else - { - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; - return QRectF(); - } -} - -/*! - Sets the inset placement type of the element with the specified \a index to \a placement. - - \see InsetPlacement -*/ -void QCPLayoutInset::setInsetPlacement(int index, QCPLayoutInset::InsetPlacement placement) -{ - if (elementAt(index)) - mInsetPlacement[index] = placement; - else - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; -} - -/*! - If the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned, this function - is used to set the alignment of the element with the specified \a index to \a alignment. - - \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, - Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other - alignment flags will be ignored. -*/ -void QCPLayoutInset::setInsetAlignment(int index, Qt::Alignment alignment) -{ - if (elementAt(index)) - mInsetAlignment[index] = alignment; - else - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; -} - -/*! - If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the - position and size of the element with the specified \a index to \a rect. - - \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) - will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right - corner of the layout, with 35% width and height of the parent layout. - - Note that the minimum and maximum sizes of the embedded element (\ref - QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize) are enforced. -*/ -void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) -{ - if (elementAt(index)) - mInsetRect[index] = rect; - else - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; -} - -/* inherits documentation from base class */ -void QCPLayoutInset::updateLayout() -{ - for (int i=0; i finalMaxSize.width()) - insetRect.setWidth(finalMaxSize.width()); - if (insetRect.size().height() > finalMaxSize.height()) - insetRect.setHeight(finalMaxSize.height()); - } else if (mInsetPlacement.at(i) == ipBorderAligned) - { - insetRect.setSize(finalMinSize); - Qt::Alignment al = mInsetAlignment.at(i); - if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(rect().x()); - else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(rect().x()+rect().width()); - else insetRect.moveLeft(rect().x()+rect().width()*0.5-finalMinSize.width()*0.5); // default to Qt::AlignHCenter - if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(rect().y()); - else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(rect().y()+rect().height()); - else insetRect.moveTop(rect().y()+rect().height()*0.5-finalMinSize.height()*0.5); // default to Qt::AlignVCenter - } - mElements.at(i)->setOuterRect(insetRect); - } -} - -/* inherits documentation from base class */ -int QCPLayoutInset::elementCount() const -{ - return mElements.size(); -} - -/* inherits documentation from base class */ -QCPLayoutElement *QCPLayoutInset::elementAt(int index) const -{ - if (index >= 0 && index < mElements.size()) - return mElements.at(index); - else - return 0; -} - -/* inherits documentation from base class */ -QCPLayoutElement *QCPLayoutInset::takeAt(int index) -{ - if (QCPLayoutElement *el = elementAt(index)) - { - releaseElement(el); - mElements.removeAt(index); - mInsetPlacement.removeAt(index); - mInsetAlignment.removeAt(index); - mInsetRect.removeAt(index); - return el; - } else - { - qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; - return 0; - } -} - -/* inherits documentation from base class */ -bool QCPLayoutInset::take(QCPLayoutElement *element) -{ - if (element) - { - for (int i=0; irealVisibility() && mElements.at(i)->selectTest(pos, onlySelectable) >= 0) - return mParentPlot->selectionTolerance()*0.99; - } - return -1; -} - -/*! - Adds the specified \a element to the layout as an inset aligned at the border (\ref - setInsetAlignment is initialized with \ref ipBorderAligned). The alignment is set to \a - alignment. - - \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, - Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other - alignment flags will be ignored. - - \see addElement(QCPLayoutElement *element, const QRectF &rect) -*/ -void QCPLayoutInset::addElement(QCPLayoutElement *element, Qt::Alignment alignment) -{ - if (element) - { - if (element->layout()) // remove from old layout first - element->layout()->take(element); - mElements.append(element); - mInsetPlacement.append(ipBorderAligned); - mInsetAlignment.append(alignment); - mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4)); - adoptElement(element); - } else - qDebug() << Q_FUNC_INFO << "Can't add null element"; -} - -/*! - Adds the specified \a element to the layout as an inset with free positioning/sizing (\ref - setInsetAlignment is initialized with \ref ipFree). The position and size is set to \a - rect. - - \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) - will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right - corner of the layout, with 35% width and height of the parent layout. - - \see addElement(QCPLayoutElement *element, Qt::Alignment alignment) -*/ -void QCPLayoutInset::addElement(QCPLayoutElement *element, const QRectF &rect) -{ - if (element) - { - if (element->layout()) // remove from old layout first - element->layout()->take(element); - mElements.append(element); - mInsetPlacement.append(ipFree); - mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop); - mInsetRect.append(rect); - adoptElement(element); - } else - qDebug() << Q_FUNC_INFO << "Can't add null element"; -} -/* end of 'src/layout.cpp' */ - - -/* including file 'src/lineending.cpp', size 11536 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLineEnding -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLineEnding - \brief Handles the different ending decorations for line-like items - - \image html QCPLineEnding.png "The various ending styles currently supported" - - For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine - has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. - - The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can - be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of - the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. - For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite - directions, e.g. "outward". This can be changed by \ref setInverted, which would make the - respective arrow point inward. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify a - QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. - \snippet documentation/doc-code-snippets/mainwindow.cpp qcplineending-sethead -*/ - -/*! - Creates a QCPLineEnding instance with default values (style \ref esNone). -*/ -QCPLineEnding::QCPLineEnding() : - mStyle(esNone), - mWidth(8), - mLength(10), - mInverted(false) -{ -} - -/*! - Creates a QCPLineEnding instance with the specified values. -*/ -QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : - mStyle(style), - mWidth(width), - mLength(length), - mInverted(inverted) -{ -} - -/*! - Sets the style of the ending decoration. -*/ -void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) -{ - mStyle = style; -} - -/*! - Sets the width of the ending decoration, if the style supports it. On arrows, for example, the - width defines the size perpendicular to the arrow's pointing direction. - - \see setLength -*/ -void QCPLineEnding::setWidth(double width) -{ - mWidth = width; -} - -/*! - Sets the length of the ending decoration, if the style supports it. On arrows, for example, the - length defines the size in pointing direction. - - \see setWidth -*/ -void QCPLineEnding::setLength(double length) -{ - mLength = length; -} - -/*! - Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point - inward when \a inverted is set to true. - - Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or - discs, this doesn't make a difference. However, asymmetric styles like \ref esHalfBar are - affected by it, which can be used to control to which side the half bar points to. -*/ -void QCPLineEnding::setInverted(bool inverted) -{ - mInverted = inverted; -} - -/*! \internal - - Returns the maximum pixel radius the ending decoration might cover, starting from the position - the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). - - This is relevant for clipping. Only omit painting of the decoration when the position where the - decoration is supposed to be drawn is farther away from the clipping rect than the returned - distance. -*/ -double QCPLineEnding::boundingDistance() const -{ - switch (mStyle) - { - case esNone: - return 0; - - case esFlatArrow: - case esSpikeArrow: - case esLineArrow: - case esSkewedBar: - return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length - - case esDisc: - case esSquare: - case esDiamond: - case esBar: - case esHalfBar: - return mWidth*1.42; // items that only have a width -> width*sqrt(2) - - } - return 0; -} - -/*! - Starting from the origin of this line ending (which is style specific), returns the length - covered by the line ending symbol, in backward direction. - - For example, the \ref esSpikeArrow has a shorter real length than a \ref esFlatArrow, even if - both have the same \ref setLength value, because the spike arrow has an inward curved back, which - reduces the length along its center axis (the drawing origin for arrows is at the tip). - - This function is used for precise, style specific placement of line endings, for example in - QCPAxes. -*/ -double QCPLineEnding::realLength() const -{ - switch (mStyle) - { - case esNone: - case esLineArrow: - case esSkewedBar: - case esBar: - case esHalfBar: - return 0; - - case esFlatArrow: - return mLength; - - case esDisc: - case esSquare: - case esDiamond: - return mWidth*0.5; - - case esSpikeArrow: - return mLength*0.8; - } - return 0; -} - -/*! \internal - - Draws the line ending with the specified \a painter at the position \a pos. The direction of the - line ending is controlled with \a dir. -*/ -void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const -{ - if (mStyle == esNone) - return; - - QCPVector2D lengthVec = dir.normalized() * mLength*(mInverted ? -1 : 1); - if (lengthVec.isNull()) - lengthVec = QCPVector2D(1, 0); - QCPVector2D widthVec = dir.normalized().perpendicular() * mWidth*0.5*(mInverted ? -1 : 1); - - QPen penBackup = painter->pen(); - QBrush brushBackup = painter->brush(); - QPen miterPen = penBackup; - miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey - QBrush brush(painter->pen().color(), Qt::SolidPattern); - switch (mStyle) - { - case esNone: break; - case esFlatArrow: - { - QPointF points[3] = {pos.toPointF(), - (pos-lengthVec+widthVec).toPointF(), - (pos-lengthVec-widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->setBrush(brush); - painter->drawConvexPolygon(points, 3); - painter->setBrush(brushBackup); - painter->setPen(penBackup); - break; - } - case esSpikeArrow: - { - QPointF points[4] = {pos.toPointF(), - (pos-lengthVec+widthVec).toPointF(), - (pos-lengthVec*0.8).toPointF(), - (pos-lengthVec-widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->setBrush(brush); - painter->drawConvexPolygon(points, 4); - painter->setBrush(brushBackup); - painter->setPen(penBackup); - break; - } - case esLineArrow: - { - QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), - pos.toPointF(), - (pos-lengthVec-widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->drawPolyline(points, 3); - painter->setPen(penBackup); - break; - } - case esDisc: - { - painter->setBrush(brush); - painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); - painter->setBrush(brushBackup); - break; - } - case esSquare: - { - QCPVector2D widthVecPerp = widthVec.perpendicular(); - QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), - (pos-widthVecPerp-widthVec).toPointF(), - (pos+widthVecPerp-widthVec).toPointF(), - (pos+widthVecPerp+widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->setBrush(brush); - painter->drawConvexPolygon(points, 4); - painter->setBrush(brushBackup); - painter->setPen(penBackup); - break; - } - case esDiamond: - { - QCPVector2D widthVecPerp = widthVec.perpendicular(); - QPointF points[4] = {(pos-widthVecPerp).toPointF(), - (pos-widthVec).toPointF(), - (pos+widthVecPerp).toPointF(), - (pos+widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->setBrush(brush); - painter->drawConvexPolygon(points, 4); - painter->setBrush(brushBackup); - painter->setPen(penBackup); - break; - } - case esBar: - { - painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); - break; - } - case esHalfBar: - { - painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); - break; - } - case esSkewedBar: - { - if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic)) - { - // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line - painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)).toPointF(), - (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)).toPointF()); - } else - { - // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly - painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(), - (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF()); - } - break; - } - } -} - -/*! \internal - \overload - - Draws the line ending. The direction is controlled with the \a angle parameter in radians. -*/ -void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const -{ - draw(painter, pos, QCPVector2D(qCos(angle), qSin(angle))); -} -/* end of 'src/lineending.cpp' */ - - -/* including file 'src/axis/axisticker.cpp', size 18664 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTicker -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTicker - \brief The base class tick generator used by QCPAxis to create tick positions and tick labels - - Each QCPAxis has an internal QCPAxisTicker (or a subclass) in order to generate tick positions - and tick labels for the current axis range. The ticker of an axis can be set via \ref - QCPAxis::setTicker. Since that method takes a QSharedPointer, multiple - axes can share the same ticker instance. - - This base class generates normal tick coordinates and numeric labels for linear axes. It picks a - reasonable tick step (the separation between ticks) which results in readable tick labels. The - number of ticks that should be approximately generated can be set via \ref setTickCount. - Depending on the current tick step strategy (\ref setTickStepStrategy), the algorithm either - sacrifices readability to better match the specified tick count (\ref - QCPAxisTicker::tssMeetTickCount) or relaxes the tick count in favor of better tick steps (\ref - QCPAxisTicker::tssReadability), which is the default. - - The following more specialized axis ticker subclasses are available, see details in the - respective class documentation: - -
- - - - - - - -
QCPAxisTickerFixed\image html axisticker-fixed.png
QCPAxisTickerLog\image html axisticker-log.png
QCPAxisTickerPi\image html axisticker-pi.png
QCPAxisTickerText\image html axisticker-text.png
QCPAxisTickerDateTime\image html axisticker-datetime.png
QCPAxisTickerTime\image html axisticker-time.png - \image html axisticker-time2.png
-
- - \section axisticker-subclassing Creating own axis tickers - - Creating own axis tickers can be achieved very easily by sublassing QCPAxisTicker and - reimplementing some or all of the available virtual methods. - - In the simplest case you might wish to just generate different tick steps than the other tickers, - so you only reimplement the method \ref getTickStep. If you additionally want control over the - string that will be shown as tick label, reimplement \ref getTickLabel. - - If you wish to have complete control, you can generate the tick vectors and tick label vectors - yourself by reimplementing \ref createTickVector and \ref createLabelVector. The default - implementations use the previously mentioned virtual methods \ref getTickStep and \ref - getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case - of unequal tick steps, the method \ref getTickStep loses its usefulness and can be ignored. - - The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick - placement control is obtained by reimplementing \ref createSubTickVector. - - See the documentation of all these virtual methods in QCPAxisTicker for detailed information - about the parameters and expected return values. -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTicker::QCPAxisTicker() : - mTickStepStrategy(tssReadability), - mTickCount(5), - mTickOrigin(0) -{ -} - -QCPAxisTicker::~QCPAxisTicker() -{ - -} - -/*! - Sets which strategy the axis ticker follows when choosing the size of the tick step. For the - available strategies, see \ref TickStepStrategy. -*/ -void QCPAxisTicker::setTickStepStrategy(QCPAxisTicker::TickStepStrategy strategy) -{ - mTickStepStrategy = strategy; -} - -/*! - Sets how many ticks this ticker shall aim to generate across the axis range. Note that \a count - is not guaranteed to be matched exactly, as generating readable tick intervals may conflict with - the requested number of ticks. - - Whether the readability has priority over meeting the requested \a count can be specified with - \ref setTickStepStrategy. -*/ -void QCPAxisTicker::setTickCount(int count) -{ - if (count > 0) - mTickCount = count; - else - qDebug() << Q_FUNC_INFO << "tick count must be greater than zero:" << count; -} - -/*! - Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a - concept and doesn't need to be inside the currently visible axis range. - - By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick - step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be - {-4, 1, 6, 11, 16,...}. -*/ -void QCPAxisTicker::setTickOrigin(double origin) -{ - mTickOrigin = origin; -} - -/*! - This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks), - tick label strings (\a tickLabels) and sub tick coordinates (\a subTicks). - - The ticks are generated for the specified \a range. The generated labels typically follow the - specified \a locale, \a formatChar and number \a precision, however this might be different (or - even irrelevant) for certain QCPAxisTicker subclasses. - - The output parameter \a ticks is filled with the generated tick positions in axis coordinates. - The output parameters \a subTicks and \a tickLabels are optional (set them to 0 if not needed) - and are respectively filled with sub tick coordinates, and tick label strings belonging to \a - ticks by index. -*/ -void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels) -{ - // generate (major) ticks: - double tickStep = getTickStep(range); - ticks = createTickVector(tickStep, range); - trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more) - - // generate sub ticks between major ticks: - if (subTicks) - { - if (ticks.size() > 0) - { - *subTicks = createSubTickVector(getSubTickCount(tickStep), ticks); - trimTicks(range, *subTicks, false); - } else - *subTicks = QVector(); - } - - // finally trim also outliers (no further clipping happens in axis drawing): - trimTicks(range, ticks, false); - // generate labels for visible ticks if requested: - if (tickLabels) - *tickLabels = createLabelVector(ticks, locale, formatChar, precision); -} - -/*! \internal - - Takes the entire currently visible axis range and returns a sensible tick step in - order to provide readable tick labels as well as a reasonable number of tick counts (see \ref - setTickCount, \ref setTickStepStrategy). - - If a QCPAxisTicker subclass only wants a different tick step behaviour than the default - implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper - function. -*/ -double QCPAxisTicker::getTickStep(const QCPRange &range) -{ - double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - return cleanMantissa(exactStep); -} - -/*! \internal - - Takes the \a tickStep, i.e. the distance between two consecutive ticks, and returns - an appropriate number of sub ticks for that specific tick step. - - Note that a returned sub tick count of e.g. 4 will split each tick interval into 5 sections. -*/ -int QCPAxisTicker::getSubTickCount(double tickStep) -{ - int result = 1; // default to 1, if no proper value can be found - - // separate integer and fractional part of mantissa: - double epsilon = 0.01; - double intPartf; - int intPart; - double fracPart = modf(getMantissa(tickStep), &intPartf); - intPart = intPartf; - - // handle cases with (almost) integer mantissa: - if (fracPart < epsilon || 1.0-fracPart < epsilon) - { - if (1.0-fracPart < epsilon) - ++intPart; - switch (intPart) - { - case 1: result = 4; break; // 1.0 -> 0.2 substep - case 2: result = 3; break; // 2.0 -> 0.5 substep - case 3: result = 2; break; // 3.0 -> 1.0 substep - case 4: result = 3; break; // 4.0 -> 1.0 substep - case 5: result = 4; break; // 5.0 -> 1.0 substep - case 6: result = 2; break; // 6.0 -> 2.0 substep - case 7: result = 6; break; // 7.0 -> 1.0 substep - case 8: result = 3; break; // 8.0 -> 2.0 substep - case 9: result = 2; break; // 9.0 -> 3.0 substep - } - } else - { - // handle cases with significantly fractional mantissa: - if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa - { - switch (intPart) - { - case 1: result = 2; break; // 1.5 -> 0.5 substep - case 2: result = 4; break; // 2.5 -> 0.5 substep - case 3: result = 4; break; // 3.5 -> 0.7 substep - case 4: result = 2; break; // 4.5 -> 1.5 substep - case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with default getTickStep from here on) - case 6: result = 4; break; // 6.5 -> 1.3 substep - case 7: result = 2; break; // 7.5 -> 2.5 substep - case 8: result = 4; break; // 8.5 -> 1.7 substep - case 9: result = 4; break; // 9.5 -> 1.9 substep - } - } - // if mantissa fraction isn't 0.0 or 0.5, don't bother finding good sub tick marks, leave default - } - - return result; -} - -/*! \internal - - This method returns the tick label string as it should be printed under the \a tick coordinate. - If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a - precision. - - If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is - enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will - be formatted accordingly using multiplication symbol and superscript during rendering of the - label automatically. -*/ -QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) -{ - return locale.toString(tick, formatChar.toLatin1(), precision); -} - -/*! \internal - - Returns a vector containing all coordinates of sub ticks that should be drawn. It generates \a - subTickCount sub ticks between each tick pair given in \a ticks. - - If a QCPAxisTicker subclass needs maximal control over the generated sub ticks, it should - reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to - base its result on \a subTickCount or \a ticks. -*/ -QVector QCPAxisTicker::createSubTickVector(int subTickCount, const QVector &ticks) -{ - QVector result; - if (subTickCount <= 0 || ticks.size() < 2) - return result; - - result.reserve((ticks.size()-1)*subTickCount); - for (int i=1; i QCPAxisTicker::createTickVector(double tickStep, const QCPRange &range) -{ - QVector result; - // Generate tick positions according to tickStep: - qint64 firstStep = floor((range.lower-mTickOrigin)/tickStep); // do not use qFloor here, or we'll lose 64 bit precision - qint64 lastStep = ceil((range.upper-mTickOrigin)/tickStep); // do not use qCeil here, or we'll lose 64 bit precision - int tickcount = lastStep-firstStep+1; - if (tickcount < 0) tickcount = 0; - result.resize(tickcount); - for (int i=0; i QCPAxisTicker::createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision) -{ - QVector result; - result.reserve(ticks.size()); - for (int i=0; i &ticks, bool keepOneOutlier) const -{ - bool lowFound = false; - bool highFound = false; - int lowIndex = 0; - int highIndex = -1; - - for (int i=0; i < ticks.size(); ++i) - { - if (ticks.at(i) >= range.lower) - { - lowFound = true; - lowIndex = i; - break; - } - } - for (int i=ticks.size()-1; i >= 0; --i) - { - if (ticks.at(i) <= range.upper) - { - highFound = true; - highIndex = i; - break; - } - } - - if (highFound && lowFound) - { - int trimFront = qMax(0, lowIndex-(keepOneOutlier ? 1 : 0)); - int trimBack = qMax(0, ticks.size()-(keepOneOutlier ? 2 : 1)-highIndex); - if (trimFront > 0 || trimBack > 0) - ticks = ticks.mid(trimFront, ticks.size()-trimFront-trimBack); - } else // all ticks are either all below or all above the range - ticks.clear(); -} - -/*! \internal - - Returns the coordinate contained in \a candidates which is closest to the provided \a target. - - This method assumes \a candidates is not empty and sorted in ascending order. -*/ -double QCPAxisTicker::pickClosest(double target, const QVector &candidates) const -{ - if (candidates.size() == 1) - return candidates.first(); - QVector::const_iterator it = std::lower_bound(candidates.constBegin(), candidates.constEnd(), target); - if (it == candidates.constEnd()) - return *(it-1); - else if (it == candidates.constBegin()) - return *it; - else - return target-*(it-1) < *it-target ? *(it-1) : *it; -} - -/*! \internal - - Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also - returns the magnitude of \a input as a power of 10. - - For example, an input of 142.6 will return a mantissa of 1.426 and a magnitude of 100. -*/ -double QCPAxisTicker::getMantissa(double input, double *magnitude) const -{ - const double mag = qPow(10.0, qFloor(qLn(input)/qLn(10.0))); - if (magnitude) *magnitude = mag; - return input/mag; -} - -/*! \internal - - Returns a number that is close to \a input but has a clean, easier human readable mantissa. How - strongly the mantissa is altered, and thus how strong the result deviates from the original \a - input, depends on the current tick step strategy (see \ref setTickStepStrategy). -*/ -double QCPAxisTicker::cleanMantissa(double input) const -{ - double magnitude; - const double mantissa = getMantissa(input, &magnitude); - switch (mTickStepStrategy) - { - case tssReadability: - { - return pickClosest(mantissa, QVector() << 1.0 << 2.0 << 2.5 << 5.0 << 10.0)*magnitude; - } - case tssMeetTickCount: - { - // this gives effectively a mantissa of 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0 - if (mantissa <= 5.0) - return (int)(mantissa*2)/2.0*magnitude; // round digit after decimal point to 0.5 - else - return (int)(mantissa/2.0)*2.0*magnitude; // round to first digit in multiples of 2 - } - } - return input; -} -/* end of 'src/axis/axisticker.cpp' */ - - -/* including file 'src/axis/axistickerdatetime.cpp', size 14443 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerDateTime -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerDateTime - \brief Specialized axis ticker for calendar dates and times as axis ticks - - \image html axisticker-datetime.png - - This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The - plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00 - UTC). This is also used for example by QDateTime in the toTime_t()/setTime_t() methods - with a precision of one second. Since Qt 4.7, millisecond accuracy can be obtained from QDateTime - by using QDateTime::fromMSecsSinceEpoch()/1000.0. The static methods \ref dateTimeToKey - and \ref keyToDateTime conveniently perform this conversion achieving a precision of one - millisecond on all Qt versions. - - The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat. - If a different time spec (time zone) shall be used, see \ref setDateTimeSpec. - - This ticker produces unequal tick spacing in order to provide intuitive date and time-of-day - ticks. For example, if the axis range spans a few years such that there is one tick per year, - ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years, - will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in - the image above: even though the number of days varies month by month, this ticker generates - ticks on the same day of each month. - - If you would like to change the date/time that is used as a (mathematical) starting date for the - ticks, use the \ref setTickOrigin(const QDateTime &origin) method overload, which takes a - QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at - 9:45 of every year. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickerdatetime-creation - - \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and - milliseconds, and are not interested in the intricacies of real calendar dates with months and - (leap) years, have a look at QCPAxisTickerTime instead. -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerDateTime::QCPAxisTickerDateTime() : - mDateTimeFormat(QLatin1String("hh:mm:ss\ndd.MM.yy")), - mDateTimeSpec(Qt::LocalTime), - mDateStrategy(dsNone) -{ - setTickCount(4); -} - -/*! - Sets the format in which dates and times are displayed as tick labels. For details about the \a - format string, see the documentation of QDateTime::toString(). - - Newlines can be inserted with "\n". - - \see setDateTimeSpec -*/ -void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) -{ - mDateTimeFormat = format; -} - -/*! - Sets the time spec that is used for creating the tick labels from corresponding dates/times. - - The default value of QDateTime objects (and also QCPAxisTickerDateTime) is - Qt::LocalTime. However, if the date time values passed to QCustomPlot (e.g. in the form - of axis ranges or keys of a plottable) are given in the UTC spec, set \a spec to Qt::UTC - to get the correct axis labels. - - \see setDateTimeFormat -*/ -void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) -{ - mDateTimeSpec = spec; -} - -/*! - Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970, - 00:00 UTC). For the date time ticker it might be more intuitive to use the overload which - directly takes a QDateTime, see \ref setTickOrigin(const QDateTime &origin). - - This is useful to define the month/day/time recurring at greater tick interval steps. For - example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick - per year, the ticks will end up on 15. July at 9:45 of every year. -*/ -void QCPAxisTickerDateTime::setTickOrigin(double origin) -{ - QCPAxisTicker::setTickOrigin(origin); -} - -/*! - Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) as a QDateTime \a origin. - - This is useful to define the month/day/time recurring at greater tick interval steps. For - example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick - per year, the ticks will end up on 15. July at 9:45 of every year. -*/ -void QCPAxisTickerDateTime::setTickOrigin(const QDateTime &origin) -{ - setTickOrigin(dateTimeToKey(origin)); -} - -/*! \internal - - Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly, - monthly, bi-monthly, etc. - - Note that this tick step isn't used exactly when generating the tick vector in \ref - createTickVector, but only as a guiding value requiring some correction for each individual tick - interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day - in the month to the last day in the previous month from tick to tick, due to the non-uniform - length of months. The same problem arises with leap years. - - \seebaseclassmethod -*/ -double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) -{ - double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - - mDateStrategy = dsNone; - if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds - { - result = cleanMantissa(result); - } else if (result < 86400*30437.5*12) // below a year - { -// result = pickClosest(result, QVector() -// << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5*60 << 5*60 << 10*60 << 15*60 << 30*60 << 60*60 // second, minute, hour range -// << 3600*2 << 3600*3 << 3600*6 << 3600*12 << 3600*24 // hour to day range -// << 86400*2 << 86400*5 << 86400*7 << 86400*14 << 86400*30.4375 << 86400*30.4375*2 << 86400*30.4375*3 << 86400*30.4375*6 << 86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) - result = pickClosest(result, QVector() - << 1000 << 1000*2.5 << 1000*5 << 1000*10 << 1000*15 << 1000*30 << 1000*60 << 1000*2.5*60 << 1000*5*60 << 1000*10*60 << 1000*15*60 << 1000*30*60 << 1000*60*60 // second, minute, hour range - << 1000*3600*2 << 1000*3600*3 << 1000*3600*6 << 1000*3600*12 << 1000*3600*24 // hour to day range - << 1000*86400*2 << 1000*86400*5 << 1000*86400*7 << 1000*86400*14 << 1000*86400*30.4375 << 1000*86400*30.4375*2 << 1000*86400*30.4375*3 << 1000*86400*30.4375*6 << 1000*86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) - if (result > 86400*30437.5-1) // month tick intervals or larger - mDateStrategy = dsUniformDayInMonth; - else if (result > 3600*24*1000-1) // day tick intervals or larger - mDateStrategy = dsUniformTimeInDay; - } else // more than a year, go back to normal clean mantissa algorithm but in units of years - { - const double secondsPerYear = 86400*30437.5*12; // average including leap years - result = cleanMantissa(result/secondsPerYear)*secondsPerYear; - mDateStrategy = dsUniformDayInMonth; - } - return result; -} - -/*! \internal - - Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly, - monthly, bi-monthly, etc. - - \seebaseclassmethod -*/ -int QCPAxisTickerDateTime::getSubTickCount(double tickStep) -{ - int result = QCPAxisTicker::getSubTickCount(tickStep); - switch (qRound64(tickStep)) // hand chosen subticks for specific minute/hour/day/week/month range (as specified in getTickStep) - { - case 5*1000*60: result = 4; break; - case 10*1000*60: result = 1; break; - case 15*1000*60: result = 2; break; - case 30*1000*60: result = 1; break; - case 60*1000*60: result = 3; break; - case 3600*1000*2: result = 3; break; - case 3600*1000*3: result = 2; break; - case 3600*1000*6: result = 1; break; - case 3600*1000*12: result = 3; break; - case 3600*1000*24: result = 3; break; - case 86400*1000*2: result = 1; break; - case 86400*1000*5: result = 4; break; - case 86400*1000*7: result = 6; break; - case 86400*1000*14: result = 1; break; - case (qint64)(86400*1000*30.4375+0.5): result = 3; break; - case (qint64)(86400*1000*30.4375*2+0.5): result = 1; break; - case (qint64)(86400*1000*30.4375*3+0.5): result = 2; break; - case (qint64)(86400*1000*30.4375*6+0.5): result = 5; break; - case (qint64)(86400*1000*30.4375*12+0.5): result = 3; break; - } - return result; -} - -/*! \internal - - Generates a date/time tick label for tick coordinate \a tick, based on the currently set format - (\ref setDateTimeFormat) and time spec (\ref setDateTimeSpec). - - \seebaseclassmethod -*/ -QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) -{ - Q_UNUSED(precision) - Q_UNUSED(formatChar) - return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); -} - -/*! \internal - - Uses the passed \a tickStep as a guiding value and applies corrections in order to obtain - non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month. - - \seebaseclassmethod -*/ -QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) -{ - QVector result = QCPAxisTicker::createTickVector(tickStep, range); - if (!result.isEmpty()) - { - if (mDateStrategy == dsUniformTimeInDay) - { - QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible - QDateTime tickDateTime; - for (int i=0; i 15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day - tickDateTime = tickDateTime.addMonths(-1); - tickDateTime.setDate(QDate(tickDateTime.date().year(), tickDateTime.date().month(), thisUniformDay)); - result[i] = dateTimeToKey(tickDateTime); - } - } - } - return result; -} - -/*! - A convenience method which turns \a key (in seconds since Epoch 1. Jan 1970, 00:00 UTC) into a - QDateTime object. This can be used to turn axis coordinates to actual QDateTimes. - - The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it - works around the lack of a QDateTime::fromMSecsSinceEpoch in Qt 4.6) - - \see dateTimeToKey -*/ -QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) -{ - return QDateTime::fromMSecsSinceEpoch(key); -} - -/*! \overload - - A convenience method which turns a QDateTime object into a double value that corresponds to - seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by - QCPAxisTickerDateTime. - - The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it - works around the lack of a QDateTime::toMSecsSinceEpoch in Qt 4.6) - - \see keyToDateTime -*/ -double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime dateTime) -{ - return dateTime.toMSecsSinceEpoch(); -} - -/*! \overload - - A convenience method which turns a QDate object into a double value that corresponds to - seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by - QCPAxisTickerDateTime. - - \see keyToDateTime -*/ -double QCPAxisTickerDateTime::dateTimeToKey(const QDate date) -{ - return QDateTime(date).toMSecsSinceEpoch(); -} -/* end of 'src/axis/axistickerdatetime.cpp' */ - - -/* including file 'src/axis/axistickertime.cpp', size 11747 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerTime -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerTime - \brief Specialized axis ticker for time spans in units of milliseconds to days - - \image html axisticker-time.png - - This QCPAxisTicker subclass generates ticks that corresponds to time intervals. - - The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref - setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate - zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date - and time. - - The time can be displayed in milliseconds, seconds, minutes, hours and days. Depending on the - largest available unit in the format specified with \ref setTimeFormat, any time spans above will - be carried in that largest unit. So for example if the format string is "%m:%s" and a tick at - coordinate value 7815 (being 2 hours, 10 minutes and 15 seconds) is created, the resulting tick - label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour - unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis - zero will carry a leading minus sign. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation - - Here is an example of a time axis providing time information in days, hours and minutes. Due to - the axis range spanning a few days and the wanted tick count (\ref setTickCount), the ticker - decided to use tick steps of 12 hours: - - \image html axisticker-time2.png - - The format string for this example is - \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation-2 - - \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime - instead. -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerTime::QCPAxisTickerTime() : - mTimeFormat(QLatin1String("%h:%m:%s")), - mSmallestUnit(tuSeconds), - mBiggestUnit(tuHours) -{ - setTickCount(4); - mFieldWidth[tuMilliseconds] = 3; - mFieldWidth[tuSeconds] = 2; - mFieldWidth[tuMinutes] = 2; - mFieldWidth[tuHours] = 2; - mFieldWidth[tuDays] = 1; - - mFormatPattern[tuMilliseconds] = QLatin1String("%z"); - mFormatPattern[tuSeconds] = QLatin1String("%s"); - mFormatPattern[tuMinutes] = QLatin1String("%m"); - mFormatPattern[tuHours] = QLatin1String("%h"); - mFormatPattern[tuDays] = QLatin1String("%d"); -} - -/*! - Sets the format that will be used to display time in the tick labels. - - The available patterns are: - - %%z for milliseconds - - %%s for seconds - - %%m for minutes - - %%h for hours - - %%d for days - - The field width (zero padding) can be controlled for each unit with \ref setFieldWidth. - - The largest unit that appears in \a format will carry all the remaining time of a certain tick - coordinate, even if it overflows the natural limit of the unit. For example, if %%m is the - largest unit it might become larger than 59 in order to consume larger time values. If on the - other hand %%h is available, the minutes will wrap around to zero after 59 and the time will - carry to the hour digit. -*/ -void QCPAxisTickerTime::setTimeFormat(const QString &format) -{ - mTimeFormat = format; - - // determine smallest and biggest unit in format, to optimize unit replacement and allow biggest - // unit to consume remaining time of a tick value and grow beyond its modulo (e.g. min > 59) - mSmallestUnit = tuMilliseconds; - mBiggestUnit = tuMilliseconds; - bool hasSmallest = false; - for (int i = tuMilliseconds; i <= tuDays; ++i) - { - TimeUnit unit = static_cast(i); - if (mTimeFormat.contains(mFormatPattern.value(unit))) - { - if (!hasSmallest) - { - mSmallestUnit = unit; - hasSmallest = true; - } - mBiggestUnit = unit; - } - } -} - -/*! - Sets the field widh of the specified \a unit to be \a width digits, when displayed in the tick - label. If the number for the specific unit is shorter than \a width, it will be padded with an - according number of zeros to the left in order to reach the field width. - - \see setTimeFormat -*/ -void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int width) -{ - mFieldWidth[unit] = qMax(width, 1); -} - -/*! \internal - - Returns the tick step appropriate for time displays, depending on the provided \a range and the - smallest available time unit in the current format (\ref setTimeFormat). For example if the unit - of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes) - that require sub-minute precision to be displayed correctly. - - \seebaseclassmethod -*/ -double QCPAxisTickerTime::getTickStep(const QCPRange &range) -{ - double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - - if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds - { - if (mSmallestUnit == tuMilliseconds) - result = qMax(cleanMantissa(result), 0.001); // smallest tick step is 1 millisecond - else // have no milliseconds available in format, so stick with 1 second tickstep - result = 1.0; - } else if (result < 3600*24) // below a day - { - // the filling of availableSteps seems a bit contorted but it fills in a sorted fashion and thus saves a post-fill sorting run - QVector availableSteps; - // seconds range: - if (mSmallestUnit <= tuSeconds) - availableSteps << 1; - if (mSmallestUnit == tuMilliseconds) - availableSteps << 2.5; // only allow half second steps if milliseconds are there to display it - else if (mSmallestUnit == tuSeconds) - availableSteps << 2; - if (mSmallestUnit <= tuSeconds) - availableSteps << 5 << 10 << 15 << 30; - // minutes range: - if (mSmallestUnit <= tuMinutes) - availableSteps << 1*60; - if (mSmallestUnit <= tuSeconds) - availableSteps << 2.5*60; // only allow half minute steps if seconds are there to display it - else if (mSmallestUnit == tuMinutes) - availableSteps << 2*60; - if (mSmallestUnit <= tuMinutes) - availableSteps << 5*60 << 10*60 << 15*60 << 30*60; - // hours range: - if (mSmallestUnit <= tuHours) - availableSteps << 1*3600 << 2*3600 << 3*3600 << 6*3600 << 12*3600 << 24*3600; - // pick available step that is most appropriate to approximate ideal step: - result = pickClosest(result, availableSteps); - } else // more than a day, go back to normal clean mantissa algorithm but in units of days - { - const double secondsPerDay = 3600*24; - result = cleanMantissa(result/secondsPerDay)*secondsPerDay; - } - return result; -} - -/*! \internal - - Returns the sub tick count appropriate for the provided \a tickStep and time displays. - - \seebaseclassmethod -*/ -int QCPAxisTickerTime::getSubTickCount(double tickStep) -{ - int result = QCPAxisTicker::getSubTickCount(tickStep); - switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day range (as specified in getTickStep) - { - case 5*60: result = 4; break; - case 10*60: result = 1; break; - case 15*60: result = 2; break; - case 30*60: result = 1; break; - case 60*60: result = 3; break; - case 3600*2: result = 3; break; - case 3600*3: result = 2; break; - case 3600*6: result = 1; break; - case 3600*12: result = 3; break; - case 3600*24: result = 3; break; - } - return result; -} - -/*! \internal - - Returns the tick label corresponding to the provided \a tick and the configured format and field - widths (\ref setTimeFormat, \ref setFieldWidth). - - \seebaseclassmethod -*/ -QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) -{ - Q_UNUSED(precision) - Q_UNUSED(formatChar) - Q_UNUSED(locale) - bool negative = tick < 0; - if (negative) tick *= -1; - double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59) - double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time - - restValues[tuMilliseconds] = tick*1000; - values[tuMilliseconds] = modf(restValues[tuMilliseconds]/1000, &restValues[tuSeconds])*1000; - values[tuSeconds] = modf(restValues[tuSeconds]/60, &restValues[tuMinutes])*60; - values[tuMinutes] = modf(restValues[tuMinutes]/60, &restValues[tuHours])*60; - values[tuHours] = modf(restValues[tuHours]/24, &restValues[tuDays])*24; - // no need to set values[tuDays] because days are always a rest value (there is no higher unit so it consumes all remaining time) - - QString result = mTimeFormat; - for (int i = mSmallestUnit; i <= mBiggestUnit; ++i) - { - TimeUnit iUnit = static_cast(i); - replaceUnit(result, iUnit, qRound(iUnit == mBiggestUnit ? restValues[iUnit] : values[iUnit])); - } - if (negative) - result.prepend(QLatin1Char('-')); - return result; -} - -/*! \internal - - Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified - \a value, using the field width as specified with \ref setFieldWidth for the \a unit. -*/ -void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit unit, int value) const -{ - QString valueStr = QString::number(value); - while (valueStr.size() < mFieldWidth.value(unit)) - valueStr.prepend(QLatin1Char('0')); - - text.replace(mFormatPattern.value(unit), valueStr); -} -/* end of 'src/axis/axistickertime.cpp' */ - - -/* including file 'src/axis/axistickerfixed.cpp', size 5583 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerFixed -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerFixed - \brief Specialized axis ticker with a fixed tick step - - \image html axisticker-fixed.png - - This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It - is also possible to allow integer multiples and integer powers of the specified tick step with - \ref setScaleStrategy. - - A typical application of this ticker is to make an axis only display integers, by setting the - tick step of the ticker to 1.0 and the scale strategy to \ref ssMultiples. - - Another case is when a certain number has a special meaning and axis ticks should only appear at - multiples of that value. In this case you might also want to consider \ref QCPAxisTickerPi - because despite the name it is not limited to only pi symbols/values. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickerfixed-creation -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerFixed::QCPAxisTickerFixed() : - mTickStep(1.0), - mScaleStrategy(ssNone) -{ -} - -/*! - Sets the fixed tick interval to \a step. - - The axis ticker will only use this tick step when generating axis ticks. This might cause a very - high tick density and overlapping labels if the axis range is zoomed out. Using \ref - setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a - step. This will enable the ticker to reduce the number of ticks to a reasonable amount (see \ref - setTickCount). -*/ -void QCPAxisTickerFixed::setTickStep(double step) -{ - if (step > 0) - mTickStep = step; - else - qDebug() << Q_FUNC_INFO << "tick step must be greater than zero:" << step; -} - -/*! - Sets whether the specified tick step (\ref setTickStep) is absolutely fixed or whether - modifications may be applied to it before calculating the finally used tick step, such as - permitting multiples or powers. See \ref ScaleStrategy for details. - - The default strategy is \ref ssNone, which means the tick step is absolutely fixed. -*/ -void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy strategy) -{ - mScaleStrategy = strategy; -} - -/*! \internal - - Determines the actually used tick step from the specified tick step and scale strategy (\ref - setTickStep, \ref setScaleStrategy). - - This method either returns the specified tick step exactly, or, if the scale strategy is not \ref - ssNone, a modification of it to allow varying the number of ticks in the current axis range. - - \seebaseclassmethod -*/ -double QCPAxisTickerFixed::getTickStep(const QCPRange &range) -{ - switch (mScaleStrategy) - { - case ssNone: - { - return mTickStep; - } - case ssMultiples: - { - double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - if (exactStep < mTickStep) - return mTickStep; - else - return (qint64)(cleanMantissa(exactStep/mTickStep)+0.5)*mTickStep; - } - case ssPowers: - { - double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - return qPow(mTickStep, (int)(qLn(exactStep)/qLn(mTickStep)+0.5)); - } - } - return mTickStep; -} -/* end of 'src/axis/axistickerfixed.cpp' */ - - -/* including file 'src/axis/axistickertext.cpp', size 8653 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerText -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerText - \brief Specialized axis ticker which allows arbitrary labels at specified coordinates - - \image html axisticker-text.png - - This QCPAxisTicker subclass generates ticks which can be directly specified by the user as - coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a - time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks - and modify the tick/label data there. - - This is useful for cases where the axis represents categories rather than numerical values. - - If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on - the axis range), it is a sign that you should probably create an own ticker by subclassing - QCPAxisTicker, instead of using this one. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickertext-creation -*/ - -/* start of documentation of inline functions */ - -/*! \fn QMap &QCPAxisTickerText::ticks() - - Returns a non-const reference to the internal map which stores the tick coordinates and their - labels. - - You can access the map directly in order to add, remove or manipulate ticks, as an alternative to - using the methods provided by QCPAxisTickerText, such as \ref setTicks and \ref addTick. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerText::QCPAxisTickerText() : - mSubTickCount(0) -{ -} - -/*! \overload - - Sets the ticks that shall appear on the axis. The map key of \a ticks corresponds to the axis - coordinate, and the map value is the string that will appear as tick label. - - An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks - getter. - - \see addTicks, addTick, clear -*/ -void QCPAxisTickerText::setTicks(const QMap &ticks) -{ - mTicks = ticks; -} - -/*! \overload - - Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis - coordinates, and the entries of \a labels are the respective strings that will appear as tick - labels. - - \see addTicks, addTick, clear -*/ -void QCPAxisTickerText::setTicks(const QVector &positions, const QVector labels) -{ - clear(); - addTicks(positions, labels); -} - -/*! - Sets the number of sub ticks that shall appear between ticks. For QCPAxisTickerText, there is no - automatic sub tick count calculation. So if sub ticks are needed, they must be configured with this - method. -*/ -void QCPAxisTickerText::setSubTickCount(int subTicks) -{ - if (subTicks >= 0) - mSubTickCount = subTicks; - else - qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; -} - -/*! - Clears all ticks. - - An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks - getter. - - \see setTicks, addTicks, addTick -*/ -void QCPAxisTickerText::clear() -{ - mTicks.clear(); -} - -/*! - Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a - label. - - \see addTicks, setTicks, clear -*/ -void QCPAxisTickerText::addTick(double position, QString label) -{ - mTicks.insert(position, label); -} - -/*! \overload - - Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to - the axis coordinate, and the map value is the string that will appear as tick label. - - An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks - getter. - - \see addTick, setTicks, clear -*/ -void QCPAxisTickerText::addTicks(const QMap &ticks) -{ - mTicks.unite(ticks); -} - -/*! \overload - - Adds the provided ticks to the ones already existing. The entries of \a positions correspond to - the axis coordinates, and the entries of \a labels are the respective strings that will appear as - tick labels. - - An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks - getter. - - \see addTick, setTicks, clear -*/ -void QCPAxisTickerText::addTicks(const QVector &positions, const QVector &labels) -{ - if (positions.size() != labels.size()) - qDebug() << Q_FUNC_INFO << "passed unequal length vectors for positions and labels:" << positions.size() << labels.size(); - int n = qMin(positions.size(), labels.size()); - for (int i=0; i QCPAxisTickerText::createTickVector(double tickStep, const QCPRange &range) -{ - Q_UNUSED(tickStep) - QVector result; - if (mTicks.isEmpty()) - return result; - - QMap::const_iterator start = mTicks.lowerBound(range.lower); - QMap::const_iterator end = mTicks.upperBound(range.upper); - // this method should try to give one tick outside of range so proper subticks can be generated: - if (start != mTicks.constBegin()) --start; - if (end != mTicks.constEnd()) ++end; - for (QMap::const_iterator it = start; it != end; ++it) - result.append(it.key()); - - return result; -} -/* end of 'src/axis/axistickertext.cpp' */ - - -/* including file 'src/axis/axistickerpi.cpp', size 11170 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerPi -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerPi - \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi - - \image html axisticker-pi.png - - This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic - constant with a numerical value specified with \ref setPiValue and an appearance in the tick - labels specified with \ref setPiSymbol. - - Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the - tick label can be configured with \ref setFractionStyle. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickerpi-creation -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerPi::QCPAxisTickerPi() : - mPiSymbol(QLatin1String(" ")+QChar(0x03C0)), - mPiValue(M_PI), - mPeriodicity(0), - mFractionStyle(fsUnicodeFractions), - mPiTickStep(0) -{ - setTickCount(4); -} - -/*! - Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick - label. - - If a space shall appear between the number and the symbol, make sure the space is contained in \a - symbol. -*/ -void QCPAxisTickerPi::setPiSymbol(QString symbol) -{ - mPiSymbol = symbol; -} - -/*! - Sets the numerical value that the symbolic constant has. - - This will be used to place the appropriate fractions of the symbol at the respective axis - coordinates. -*/ -void QCPAxisTickerPi::setPiValue(double pi) -{ - mPiValue = pi; -} - -/*! - Sets whether the axis labels shall appear periodicly and if so, at which multiplicity of the - symbolic constant. - - To disable periodicity, set \a multiplesOfPi to zero. - - For example, an axis that identifies 0 with 2pi would set \a multiplesOfPi to two. -*/ -void QCPAxisTickerPi::setPeriodicity(int multiplesOfPi) -{ - mPeriodicity = qAbs(multiplesOfPi); -} - -/*! - Sets how the numerical/fractional part preceding the symbolic constant is displayed in tick - labels. See \ref FractionStyle for the various options. -*/ -void QCPAxisTickerPi::setFractionStyle(QCPAxisTickerPi::FractionStyle style) -{ - mFractionStyle = style; -} - -/*! \internal - - Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence - the numerical/fractional part preceding the symbolic constant is made to have a readable - mantissa. - - \seebaseclassmethod -*/ -double QCPAxisTickerPi::getTickStep(const QCPRange &range) -{ - mPiTickStep = range.size()/mPiValue/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - mPiTickStep = cleanMantissa(mPiTickStep); - return mPiTickStep*mPiValue; -} - -/*! \internal - - Returns the sub tick count, using the constant's value (\ref setPiValue) as base unit. In - consequence the sub ticks divide the numerical/fractional part preceding the symbolic constant - reasonably, and not the total tick coordinate. - - \seebaseclassmethod -*/ -int QCPAxisTickerPi::getSubTickCount(double tickStep) -{ - return QCPAxisTicker::getSubTickCount(tickStep/mPiValue); -} - -/*! \internal - - Returns the tick label as a fractional/numerical part and a symbolic string as suffix. The - formatting of the fraction is done according to the specified \ref setFractionStyle. The appended - symbol is specified with \ref setPiSymbol. - - \seebaseclassmethod -*/ -QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) -{ - double tickInPis = tick/mPiValue; - if (mPeriodicity > 0) - tickInPis = fmod(tickInPis, mPeriodicity); - - if (mFractionStyle != fsFloatingPoint && mPiTickStep > 0.09 && mPiTickStep < 50) - { - // simply construct fraction from decimal like 1.234 -> 1234/1000 and then simplify fraction, smaller digits are irrelevant due to mPiTickStep conditional above - int denominator = 1000; - int numerator = qRound(tickInPis*denominator); - simplifyFraction(numerator, denominator); - if (qAbs(numerator) == 1 && denominator == 1) - return (numerator < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); - else if (numerator == 0) - return QLatin1String("0"); - else - return fractionToString(numerator, denominator) + mPiSymbol; - } else - { - if (qFuzzyIsNull(tickInPis)) - return QLatin1String("0"); - else if (qFuzzyCompare(qAbs(tickInPis), 1.0)) - return (tickInPis < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); - else - return QCPAxisTicker::getTickLabel(tickInPis, locale, formatChar, precision) + mPiSymbol; - } -} - -/*! \internal - - Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure - the fraction is in irreducible form, i.e. numerator and denominator don't share any common - factors which could be cancelled. -*/ -void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const -{ - if (numerator == 0 || denominator == 0) - return; - - int num = numerator; - int denom = denominator; - while (denom != 0) // euclidean gcd algorithm - { - int oldDenom = denom; - denom = num % denom; - num = oldDenom; - } - // num is now gcd of numerator and denominator - numerator /= num; - denominator /= num; -} - -/*! \internal - - Takes the fraction given by \a numerator and \a denominator and returns a string representation. - The result depends on the configured fraction style (\ref setFractionStyle). - - This method is used to format the numerical/fractional part when generating tick labels. It - simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out - any integer parts of the fraction (e.g. "10/4" becomes "2 1/2"). -*/ -QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const -{ - if (denominator == 0) - { - qDebug() << Q_FUNC_INFO << "called with zero denominator"; - return QString(); - } - if (mFractionStyle == fsFloatingPoint) // should never be the case when calling this function - { - qDebug() << Q_FUNC_INFO << "shouldn't be called with fraction style fsDecimal"; - return QString::number(numerator/(double)denominator); // failsafe - } - int sign = numerator*denominator < 0 ? -1 : 1; - numerator = qAbs(numerator); - denominator = qAbs(denominator); - - if (denominator == 1) - { - return QString::number(sign*numerator); - } else - { - int integerPart = numerator/denominator; - int remainder = numerator%denominator; - if (remainder == 0) - { - return QString::number(sign*integerPart); - } else - { - if (mFractionStyle == fsAsciiFractions) - { - return QString(QLatin1String("%1%2%3/%4")) - .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) - .arg(integerPart > 0 ? QString::number(integerPart)+QLatin1String(" ") : QLatin1String("")) - .arg(remainder) - .arg(denominator); - } else if (mFractionStyle == fsUnicodeFractions) - { - return QString(QLatin1String("%1%2%3")) - .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) - .arg(integerPart > 0 ? QString::number(integerPart) : QLatin1String("")) - .arg(unicodeFraction(remainder, denominator)); - } - } - } - return QString(); -} - -/*! \internal - - Returns the unicode string representation of the fraction given by \a numerator and \a - denominator. This is the representation used in \ref fractionToString when the fraction style - (\ref setFractionStyle) is \ref fsUnicodeFractions. - - This method doesn't use the single-character common fractions but builds each fraction from a - superscript unicode number, the unicode fraction character, and a subscript unicode number. -*/ -QString QCPAxisTickerPi::unicodeFraction(int numerator, int denominator) const -{ - return unicodeSuperscript(numerator)+QChar(0x2044)+unicodeSubscript(denominator); -} - -/*! \internal - - Returns the unicode string representing \a number as superscript. This is used to build - unicode fractions in \ref unicodeFraction. -*/ -QString QCPAxisTickerPi::unicodeSuperscript(int number) const -{ - if (number == 0) - return QString(QChar(0x2070)); - - QString result; - while (number > 0) - { - const int digit = number%10; - switch (digit) - { - case 1: { result.prepend(QChar(0x00B9)); break; } - case 2: { result.prepend(QChar(0x00B2)); break; } - case 3: { result.prepend(QChar(0x00B3)); break; } - default: { result.prepend(QChar(0x2070+digit)); break; } - } - number /= 10; - } - return result; -} - -/*! \internal - - Returns the unicode string representing \a number as subscript. This is used to build unicode - fractions in \ref unicodeFraction. -*/ -QString QCPAxisTickerPi::unicodeSubscript(int number) const -{ - if (number == 0) - return QString(QChar(0x2080)); - - QString result; - while (number > 0) - { - result.prepend(QChar(0x2080+number%10)); - number /= 10; - } - return result; -} -/* end of 'src/axis/axistickerpi.cpp' */ - - -/* including file 'src/axis/axistickerlog.cpp', size 7106 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerLog -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerLog - \brief Specialized axis ticker suited for logarithmic axes - - \image html axisticker-log.png - - This QCPAxisTicker subclass generates ticks with unequal tick intervals suited for logarithmic - axis scales. The ticks are placed at powers of the specified log base (\ref setLogBase). - - Especially in the case of a log base equal to 10 (the default), it might be desirable to have - tick labels in the form of powers of ten without mantissa display. To achieve this, set the - number precision (\ref QCPAxis::setNumberPrecision) to zero and the number format (\ref - QCPAxis::setNumberFormat) to scientific (exponential) display with beautifully typeset decimal - powers, so a format string of "eb". This will result in the following axis tick labels: - - \image html axisticker-log-powers.png - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickerlog-creation -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerLog::QCPAxisTickerLog() : - mLogBase(10.0), - mSubTickCount(8), // generates 10 intervals - mLogBaseLnInv(1.0/qLn(mLogBase)) -{ -} - -/*! - Sets the logarithm base used for tick coordinate generation. The ticks will be placed at integer - powers of \a base. -*/ -void QCPAxisTickerLog::setLogBase(double base) -{ - if (base > 0) - { - mLogBase = base; - mLogBaseLnInv = 1.0/qLn(mLogBase); - } else - qDebug() << Q_FUNC_INFO << "log base has to be greater than zero:" << base; -} - -/*! - Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced - linearly to provide a better visual guide, so the sub tick density increases toward the higher - tick. - - Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in - the case of logarithm base 10 an intuitive sub tick spacing would be achieved with eight sub - ticks (the default). This means e.g. between the ticks 10 and 100 there will be eight ticks, - namely at 20, 30, 40, 50, 60, 70, 80 and 90. -*/ -void QCPAxisTickerLog::setSubTickCount(int subTicks) -{ - if (subTicks >= 0) - mSubTickCount = subTicks; - else - qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; -} - -/*! \internal - - Since logarithmic tick steps are necessarily different for each tick interval, this method does - nothing in the case of QCPAxisTickerLog - - \seebaseclassmethod -*/ -double QCPAxisTickerLog::getTickStep(const QCPRange &range) -{ - // Logarithmic axis ticker has unequal tick spacing, so doesn't need this method - Q_UNUSED(range) - return 1.0; -} - -/*! \internal - - Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no - automatic sub tick count calculation necessary. - - \seebaseclassmethod -*/ -int QCPAxisTickerLog::getSubTickCount(double tickStep) -{ - Q_UNUSED(tickStep) - return mSubTickCount; -} - -/*! \internal - - Creates ticks with a spacing given by the logarithm base and an increasing integer power in the - provided \a range. The step in which the power increases tick by tick is chosen in order to keep - the total number of ticks as close as possible to the tick count (\ref setTickCount). The - parameter \a tickStep is ignored for QCPAxisTickerLog - - \seebaseclassmethod -*/ -QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRange &range) -{ - Q_UNUSED(tickStep) - QVector result; - if (range.lower > 0 && range.upper > 0) // positive range - { - double exactPowerStep = qLn(range.upper/range.lower)*mLogBaseLnInv/(double)(mTickCount+1e-10); - double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); - double currentTick = qPow(newLogBase, qFloor(qLn(range.lower)/qLn(newLogBase))); - result.append(currentTick); - while (currentTick < range.upper && currentTick > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case - { - currentTick *= newLogBase; - result.append(currentTick); - } - } else if (range.lower < 0 && range.upper < 0) // negative range - { - double exactPowerStep = qLn(range.lower/range.upper)*mLogBaseLnInv/(double)(mTickCount+1e-10); - double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); - double currentTick = -qPow(newLogBase, qCeil(qLn(-range.lower)/qLn(newLogBase))); - result.append(currentTick); - while (currentTick < range.upper && currentTick < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case - { - currentTick /= newLogBase; - result.append(currentTick); - } - } else // invalid range for logarithmic scale, because lower and upper have different sign - { - qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << range.lower << ".." << range.upper; - } - - return result; -} -/* end of 'src/axis/axistickerlog.cpp' */ - - -/* including file 'src/axis/axis.cpp', size 99397 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPGrid -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPGrid - \brief Responsible for drawing the grid of a QCPAxis. - - This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the - grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref - QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. - - The axis and grid drawing was split into two classes to allow them to be placed on different - layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid - in the background and the axes in the foreground, and any plottables/items in between. This - described situation is the default setup, see the QCPLayer documentation. -*/ - -/*! - Creates a QCPGrid instance and sets default values. - - You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. -*/ -QCPGrid::QCPGrid(QCPAxis *parentAxis) : - QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), - mParentAxis(parentAxis) -{ - // warning: this is called in QCPAxis constructor, so parentAxis members should not be accessed/called - setParent(parentAxis); - setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); - setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); - setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); - setSubGridVisible(false); - setAntialiased(false); - setAntialiasedSubGrid(false); - setAntialiasedZeroLine(false); -} - -/*! - Sets whether grid lines at sub tick marks are drawn. - - \see setSubGridPen -*/ -void QCPGrid::setSubGridVisible(bool visible) -{ - mSubGridVisible = visible; -} - -/*! - Sets whether sub grid lines are drawn antialiased. -*/ -void QCPGrid::setAntialiasedSubGrid(bool enabled) -{ - mAntialiasedSubGrid = enabled; -} - -/*! - Sets whether zero lines are drawn antialiased. -*/ -void QCPGrid::setAntialiasedZeroLine(bool enabled) -{ - mAntialiasedZeroLine = enabled; -} - -/*! - Sets the pen with which (major) grid lines are drawn. -*/ -void QCPGrid::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen with which sub grid lines are drawn. -*/ -void QCPGrid::setSubGridPen(const QPen &pen) -{ - mSubGridPen = pen; -} - -/*! - Sets the pen with which zero lines are drawn. - - Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid - lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. -*/ -void QCPGrid::setZeroLinePen(const QPen &pen) -{ - mZeroLinePen = pen; -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing the major grid lines. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \see setAntialiased -*/ -void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); -} - -/*! \internal - - Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning - over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). -*/ -void QCPGrid::draw(QCPPainter *painter) -{ - if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - - if (mParentAxis->subTicks() && mSubGridVisible) - drawSubGridLines(painter); - drawGridLines(painter); -} - -/*! \internal - - Draws the main grid lines and possibly a zero line with the specified painter. - - This is a helper function called by \ref draw. -*/ -void QCPGrid::drawGridLines(QCPPainter *painter) const -{ - if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - - const int tickCount = mParentAxis->mTickVector.size(); - double t; // helper variable, result of coordinate-to-pixel transforms - if (mParentAxis->orientation() == Qt::Horizontal) - { - // draw zeroline: - int zeroLineIndex = -1; - if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) - { - applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); - painter->setPen(mZeroLinePen); - double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero - for (int i=0; imTickVector.at(i)) < epsilon) - { - zeroLineIndex = i; - t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x - painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); - break; - } - } - } - // draw grid lines: - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // x - painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); - } - } else - { - // draw zeroline: - int zeroLineIndex = -1; - if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) - { - applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); - painter->setPen(mZeroLinePen); - double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero - for (int i=0; imTickVector.at(i)) < epsilon) - { - zeroLineIndex = i; - t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y - painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); - break; - } - } - } - // draw grid lines: - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // y - painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); - } - } -} - -/*! \internal - - Draws the sub grid lines with the specified painter. - - This is a helper function called by \ref draw. -*/ -void QCPGrid::drawSubGridLines(QCPPainter *painter) const -{ - if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - - applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); - double t; // helper variable, result of coordinate-to-pixel transforms - painter->setPen(mSubGridPen); - if (mParentAxis->orientation() == Qt::Horizontal) - { - for (int i=0; imSubTickVector.size(); ++i) - { - t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // x - painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); - } - } else - { - for (int i=0; imSubTickVector.size(); ++i) - { - t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // y - painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); - } - } -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxis -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAxis - \brief Manages a single axis inside a QCustomPlot. - - Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via - QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and - QCustomPlot::yAxis2 (right). - - Axes are always part of an axis rect, see QCPAxisRect. - \image html AxisNamesOverview.png -
Naming convention of axis parts
- \n - - \image html AxisRectSpacingOverview.png -
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line - on the left represents the QCustomPlot widget border.
- - Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and - tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of - the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the - documentation of QCPAxisTicker. -*/ - -/* start of documentation of inline functions */ - -/*! \fn Qt::Orientation QCPAxis::orientation() const - - Returns the orientation of this axis. The axis orientation (horizontal or vertical) is deduced - from the axis type (left, top, right or bottom). - - \see orientation(AxisType type), pixelOrientation -*/ - -/*! \fn QCPGrid *QCPAxis::grid() const - - Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the - grid is displayed. -*/ - -/*! \fn static Qt::Orientation QCPAxis::orientation(AxisType type) - - Returns the orientation of the specified axis type - - \see orientation(), pixelOrientation -*/ - -/*! \fn int QCPAxis::pixelOrientation() const - - Returns which direction points towards higher coordinate values/keys, in pixel space. - - This method returns either 1 or -1. If it returns 1, then going in the positive direction along - the orientation of the axis in pixels corresponds to going from lower to higher axis coordinates. - On the other hand, if this method returns -1, going to smaller pixel values corresponds to going - from lower to higher axis coordinates. - - For example, this is useful to easily shift axis coordinates by a certain amount given in pixels, - without having to care about reversed or vertically aligned axes: - - \code - double newKey = keyAxis->pixelToCoord(keyAxis->coordToPixel(oldKey)+10*keyAxis->pixelOrientation()); - \endcode - - \a newKey will then contain a key that is ten pixels towards higher keys, starting from \a oldKey. -*/ - -/*! \fn QSharedPointer QCPAxis::ticker() const - - Returns a modifiable shared pointer to the currently installed axis ticker. The axis ticker is - responsible for generating the tick positions and tick labels of this axis. You can access the - \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count - (\ref QCPAxisTicker::setTickCount). - - You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see - the documentation there. A new axis ticker can be set with \ref setTicker. - - Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis - ticker simply by passing the same shared pointer to multiple axes. - - \see setTicker -*/ - -/* end of documentation of inline functions */ -/* start of documentation of signals */ - -/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) - - This signal is emitted when the range of this axis has changed. You can connect it to the \ref - setRange slot of another axis to communicate the new range to the other axis, in order for it to - be synchronized. - - You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. - This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper - range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following - slot would limit the x axis to ranges between 0 and 10: - \code - customPlot->xAxis->setRange(newRange.bounded(0, 10)) - \endcode -*/ - -/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) - \overload - - Additionally to the new range, this signal also provides the previous range held by the axis as - \a oldRange. -*/ - -/*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); - - This signal is emitted when the scale type changes, by calls to \ref setScaleType -*/ - -/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) - - This signal is emitted when the selection state of this axis has changed, either by user interaction - or by a direct call to \ref setSelectedParts. -*/ - -/*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); - - This signal is emitted when the selectability changes, by calls to \ref setSelectableParts -*/ - -/* end of documentation of signals */ - -/*! - Constructs an Axis instance of Type \a type for the axis rect \a parent. - - Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create - them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, - create them manually and then inject them also via \ref QCPAxisRect::addAxis. -*/ -QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : - QCPLayerable(parent->parentPlot(), QString(), parent), - // axis base: - mAxisType(type), - mAxisRect(parent), - mPadding(5), - mOrientation(orientation(type)), - mSelectableParts(spAxis | spTickLabels | spAxisLabel), - mSelectedParts(spNone), - mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - mSelectedBasePen(QPen(Qt::blue, 2)), - // axis label: - mLabel(), - mLabelFont(mParentPlot->font()), - mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), - mLabelColor(Qt::black), - mSelectedLabelColor(Qt::blue), - // tick labels: - mTickLabels(true), - mTickLabelFont(mParentPlot->font()), - mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), - mTickLabelColor(Qt::black), - mSelectedTickLabelColor(Qt::blue), - mNumberPrecision(6), - mNumberFormatChar('g'), - mNumberBeautifulPowers(true), - // ticks and subticks: - mTicks(true), - mSubTicks(true), - mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - mSelectedTickPen(QPen(Qt::blue, 2)), - mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - mSelectedSubTickPen(QPen(Qt::blue, 2)), - // scale and range: - mRange(0, 5), - mRangeReversed(false), - mScaleType(stLinear), - // internal members: - mGrid(new QCPGrid(this)), - mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())), - mTicker(new QCPAxisTicker), - mCachedMarginValid(false), - mCachedMargin(0) -{ - setParent(parent); - mGrid->setVisible(false); - setAntialiased(false); - setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again - - if (type == atTop) - { - setTickLabelPadding(3); - setLabelPadding(6); - } else if (type == atRight) - { - setTickLabelPadding(7); - setLabelPadding(12); - } else if (type == atBottom) - { - setTickLabelPadding(3); - setLabelPadding(3); - } else if (type == atLeft) - { - setTickLabelPadding(5); - setLabelPadding(10); - } -} - -QCPAxis::~QCPAxis() -{ - delete mAxisPainter; - delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order -} - -/* No documentation as it is a property getter */ -int QCPAxis::tickLabelPadding() const -{ - return mAxisPainter->tickLabelPadding; -} - -/* No documentation as it is a property getter */ -double QCPAxis::tickLabelRotation() const -{ - return mAxisPainter->tickLabelRotation; -} - -/* No documentation as it is a property getter */ -QCPAxis::LabelSide QCPAxis::tickLabelSide() const -{ - return mAxisPainter->tickLabelSide; -} - -/* No documentation as it is a property getter */ -QString QCPAxis::numberFormat() const -{ - QString result; - result.append(mNumberFormatChar); - if (mNumberBeautifulPowers) - { - result.append(QLatin1Char('b')); - if (mAxisPainter->numberMultiplyCross) - result.append(QLatin1Char('c')); - } - return result; -} - -/* No documentation as it is a property getter */ -int QCPAxis::tickLengthIn() const -{ - return mAxisPainter->tickLengthIn; -} - -/* No documentation as it is a property getter */ -int QCPAxis::tickLengthOut() const -{ - return mAxisPainter->tickLengthOut; -} - -/* No documentation as it is a property getter */ -int QCPAxis::subTickLengthIn() const -{ - return mAxisPainter->subTickLengthIn; -} - -/* No documentation as it is a property getter */ -int QCPAxis::subTickLengthOut() const -{ - return mAxisPainter->subTickLengthOut; -} - -/* No documentation as it is a property getter */ -int QCPAxis::labelPadding() const -{ - return mAxisPainter->labelPadding; -} - -/* No documentation as it is a property getter */ -int QCPAxis::offset() const -{ - return mAxisPainter->offset; -} - -/* No documentation as it is a property getter */ -QCPLineEnding QCPAxis::lowerEnding() const -{ - return mAxisPainter->lowerEnding; -} - -/* No documentation as it is a property getter */ -QCPLineEnding QCPAxis::upperEnding() const -{ - return mAxisPainter->upperEnding; -} - -/*! - Sets whether the axis uses a linear scale or a logarithmic scale. - - Note that this method controls the coordinate transformation. You will likely also want to use a - logarithmic tick spacing and labeling, which can be achieved by setting an instance of \ref - QCPAxisTickerLog via \ref setTicker. See the documentation of \ref QCPAxisTickerLog about the - details of logarithmic axis tick creation. - - \ref setNumberPrecision -*/ -void QCPAxis::setScaleType(QCPAxis::ScaleType type) -{ - if (mScaleType != type) - { - mScaleType = type; - if (mScaleType == stLogarithmic) - setRange(mRange.sanitizedForLogScale()); - mCachedMarginValid = false; - emit scaleTypeChanged(mScaleType); - } -} - -/*! - Sets the range of the axis. - - This slot may be connected with the \ref rangeChanged signal of another axis so this axis - is always synchronized with the other axis range, when it changes. - - To invert the direction of an axis, use \ref setRangeReversed. -*/ -void QCPAxis::setRange(const QCPRange &range) -{ - if (range.lower == mRange.lower && range.upper == mRange.upper) - return; - - if (!QCPRange::validRange(range)) return; - QCPRange oldRange = mRange; - if (mScaleType == stLogarithmic) - { - mRange = range.sanitizedForLogScale(); - } else - { - mRange = range.sanitizedForLinScale(); - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. - (When \ref QCustomPlot::setInteractions contains iSelectAxes.) - - However, even when \a selectable is set to a value not allowing the selection of a specific part, - it is still possible to set the selection of this part manually, by calling \ref setSelectedParts - directly. - - \see SelectablePart, setSelectedParts -*/ -void QCPAxis::setSelectableParts(const SelectableParts &selectable) -{ - if (mSelectableParts != selectable) - { - mSelectableParts = selectable; - emit selectableChanged(mSelectableParts); - } -} - -/*! - Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part - is selected, it uses a different pen/font. - - The entire selection mechanism for axes is handled automatically when \ref - QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you - wish to change the selection state manually. - - This function can change the selection state of a part, independent of the \ref setSelectableParts setting. - - emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - - \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, - setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor -*/ -void QCPAxis::setSelectedParts(const SelectableParts &selected) -{ - if (mSelectedParts != selected) - { - mSelectedParts = selected; - emit selectionChanged(mSelectedParts); - } -} - -/*! - \overload - - Sets the lower and upper bound of the axis range. - - To invert the direction of an axis, use \ref setRangeReversed. - - There is also a slot to set a range, see \ref setRange(const QCPRange &range). -*/ -void QCPAxis::setRange(double lower, double upper) -{ - if (lower == mRange.lower && upper == mRange.upper) - return; - - if (!QCPRange::validRange(lower, upper)) return; - QCPRange oldRange = mRange; - mRange.lower = lower; - mRange.upper = upper; - if (mScaleType == stLogarithmic) - { - mRange = mRange.sanitizedForLogScale(); - } else - { - mRange = mRange.sanitizedForLinScale(); - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - \overload - - Sets the range of the axis. - - The \a position coordinate indicates together with the \a alignment parameter, where the new - range will be positioned. \a size defines the size of the new axis range. \a alignment may be - Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, - or center of the range to be aligned with \a position. Any other values of \a alignment will - default to Qt::AlignCenter. -*/ -void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) -{ - if (alignment == Qt::AlignLeft) - setRange(position, position+size); - else if (alignment == Qt::AlignRight) - setRange(position-size, position); - else // alignment == Qt::AlignCenter - setRange(position-size/2.0, position+size/2.0); -} - -/*! - Sets the lower bound of the axis range. The upper bound is not changed. - \see setRange -*/ -void QCPAxis::setRangeLower(double lower) -{ - if (mRange.lower == lower) - return; - - QCPRange oldRange = mRange; - mRange.lower = lower; - if (mScaleType == stLogarithmic) - { - mRange = mRange.sanitizedForLogScale(); - } else - { - mRange = mRange.sanitizedForLinScale(); - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Sets the upper bound of the axis range. The lower bound is not changed. - \see setRange -*/ -void QCPAxis::setRangeUpper(double upper) -{ - if (mRange.upper == upper) - return; - - QCPRange oldRange = mRange; - mRange.upper = upper; - if (mScaleType == stLogarithmic) - { - mRange = mRange.sanitizedForLogScale(); - } else - { - mRange = mRange.sanitizedForLinScale(); - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal - axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the - direction of increasing values is inverted. - - Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part - of the \ref setRange interface will still reference the mathematically smaller number than the \a - upper part. -*/ -void QCPAxis::setRangeReversed(bool reversed) -{ - mRangeReversed = reversed; -} - -/*! - The axis ticker is responsible for generating the tick positions and tick labels. See the - documentation of QCPAxisTicker for details on how to work with axis tickers. - - You can change the tick positioning/labeling behaviour of this axis by setting a different - QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis - ticker, access it via \ref ticker. - - Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis - ticker simply by passing the same shared pointer to multiple axes. - - \see ticker -*/ -void QCPAxis::setTicker(QSharedPointer ticker) -{ - if (ticker) - mTicker = ticker; - else - qDebug() << Q_FUNC_INFO << "can not set 0 as axis ticker"; - // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector -} - -/*! - Sets whether tick marks are displayed. - - Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve - that, see \ref setTickLabels. - - \see setSubTicks -*/ -void QCPAxis::setTicks(bool show) -{ - if (mTicks != show) - { - mTicks = show; - mCachedMarginValid = false; - } -} - -/*! - Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. -*/ -void QCPAxis::setTickLabels(bool show) -{ - if (mTickLabels != show) - { - mTickLabels = show; - mCachedMarginValid = false; - if (!mTickLabels) - mTickVectorLabels.clear(); - } -} - -/*! - Sets the distance between the axis base line (including any outward ticks) and the tick labels. - \see setLabelPadding, setPadding -*/ -void QCPAxis::setTickLabelPadding(int padding) -{ - if (mAxisPainter->tickLabelPadding != padding) - { - mAxisPainter->tickLabelPadding = padding; - mCachedMarginValid = false; - } -} - -/*! - Sets the font of the tick labels. - - \see setTickLabels, setTickLabelColor -*/ -void QCPAxis::setTickLabelFont(const QFont &font) -{ - if (font != mTickLabelFont) - { - mTickLabelFont = font; - mCachedMarginValid = false; - } -} - -/*! - Sets the color of the tick labels. - - \see setTickLabels, setTickLabelFont -*/ -void QCPAxis::setTickLabelColor(const QColor &color) -{ - mTickLabelColor = color; -} - -/*! - Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, - the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values - from -90 to 90 degrees. - - If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For - other angles, the label is drawn with an offset such that it seems to point toward or away from - the tick mark. -*/ -void QCPAxis::setTickLabelRotation(double degrees) -{ - if (!qFuzzyIsNull(degrees-mAxisPainter->tickLabelRotation)) - { - mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0); - mCachedMarginValid = false; - } -} - -/*! - Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. - - The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels - to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels - appear on the inside are additionally clipped to the axis rect. -*/ -void QCPAxis::setTickLabelSide(LabelSide side) -{ - mAxisPainter->tickLabelSide = side; - mCachedMarginValid = false; -} - -/*! - Sets the number format for the numbers in tick labels. This \a formatCode is an extended version - of the format code used e.g. by QString::number() and QLocale::toString(). For reference about - that, see the "Argument Formats" section in the detailed description of the QString class. - - \a formatCode is a string of one, two or three characters. The first character is identical to - the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed - format, 'g'/'G' scientific or fixed, whichever is shorter. - - The second and third characters are optional and specific to QCustomPlot:\n - If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. - "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for - "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 - [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. - If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can - be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the - cross and 183 (0xB7) for the dot. - - Examples for \a formatCode: - \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, - normal scientific format is used - \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with - beautifully typeset decimal powers and a dot as multiplication sign - \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as - multiplication sign - \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal - powers. Format code will be reduced to 'f'. - \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format - code will not be changed. -*/ -void QCPAxis::setNumberFormat(const QString &formatCode) -{ - if (formatCode.isEmpty()) - { - qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; - return; - } - mCachedMarginValid = false; - - // interpret first char as number format char: - QString allowedFormatChars(QLatin1String("eEfgG")); - if (allowedFormatChars.contains(formatCode.at(0))) - { - mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); - } else - { - qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; - return; - } - if (formatCode.length() < 2) - { - mNumberBeautifulPowers = false; - mAxisPainter->numberMultiplyCross = false; - return; - } - - // interpret second char as indicator for beautiful decimal powers: - if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) - { - mNumberBeautifulPowers = true; - } else - { - qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; - return; - } - if (formatCode.length() < 3) - { - mAxisPainter->numberMultiplyCross = false; - return; - } - - // interpret third char as indicator for dot or cross multiplication symbol: - if (formatCode.at(2) == QLatin1Char('c')) - { - mAxisPainter->numberMultiplyCross = true; - } else if (formatCode.at(2) == QLatin1Char('d')) - { - mAxisPainter->numberMultiplyCross = false; - } else - { - qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; - return; - } -} - -/*! - Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) - for details. The effect of precisions are most notably for number Formats starting with 'e', see - \ref setNumberFormat -*/ -void QCPAxis::setNumberPrecision(int precision) -{ - if (mNumberPrecision != precision) - { - mNumberPrecision = precision; - mCachedMarginValid = false; - } -} - -/*! - Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the - plot and \a outside is the length they will reach outside the plot. If \a outside is greater than - zero, the tick labels and axis label will increase their distance to the axis accordingly, so - they won't collide with the ticks. - - \see setSubTickLength, setTickLengthIn, setTickLengthOut -*/ -void QCPAxis::setTickLength(int inside, int outside) -{ - setTickLengthIn(inside); - setTickLengthOut(outside); -} - -/*! - Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach - inside the plot. - - \see setTickLengthOut, setTickLength, setSubTickLength -*/ -void QCPAxis::setTickLengthIn(int inside) -{ - if (mAxisPainter->tickLengthIn != inside) - { - mAxisPainter->tickLengthIn = inside; - } -} - -/*! - Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach - outside the plot. If \a outside is greater than zero, the tick labels and axis label will - increase their distance to the axis accordingly, so they won't collide with the ticks. - - \see setTickLengthIn, setTickLength, setSubTickLength -*/ -void QCPAxis::setTickLengthOut(int outside) -{ - if (mAxisPainter->tickLengthOut != outside) - { - mAxisPainter->tickLengthOut = outside; - mCachedMarginValid = false; // only outside tick length can change margin - } -} - -/*! - Sets whether sub tick marks are displayed. - - Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) - - \see setTicks -*/ -void QCPAxis::setSubTicks(bool show) -{ - if (mSubTicks != show) - { - mSubTicks = show; - mCachedMarginValid = false; - } -} - -/*! - Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside - the plot and \a outside is the length they will reach outside the plot. If \a outside is greater - than zero, the tick labels and axis label will increase their distance to the axis accordingly, - so they won't collide with the ticks. - - \see setTickLength, setSubTickLengthIn, setSubTickLengthOut -*/ -void QCPAxis::setSubTickLength(int inside, int outside) -{ - setSubTickLengthIn(inside); - setSubTickLengthOut(outside); -} - -/*! - Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside - the plot. - - \see setSubTickLengthOut, setSubTickLength, setTickLength -*/ -void QCPAxis::setSubTickLengthIn(int inside) -{ - if (mAxisPainter->subTickLengthIn != inside) - { - mAxisPainter->subTickLengthIn = inside; - } -} - -/*! - Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach - outside the plot. If \a outside is greater than zero, the tick labels will increase their - distance to the axis accordingly, so they won't collide with the ticks. - - \see setSubTickLengthIn, setSubTickLength, setTickLength -*/ -void QCPAxis::setSubTickLengthOut(int outside) -{ - if (mAxisPainter->subTickLengthOut != outside) - { - mAxisPainter->subTickLengthOut = outside; - mCachedMarginValid = false; // only outside tick length can change margin - } -} - -/*! - Sets the pen, the axis base line is drawn with. - - \see setTickPen, setSubTickPen -*/ -void QCPAxis::setBasePen(const QPen &pen) -{ - mBasePen = pen; -} - -/*! - Sets the pen, tick marks will be drawn with. - - \see setTickLength, setBasePen -*/ -void QCPAxis::setTickPen(const QPen &pen) -{ - mTickPen = pen; -} - -/*! - Sets the pen, subtick marks will be drawn with. - - \see setSubTickCount, setSubTickLength, setBasePen -*/ -void QCPAxis::setSubTickPen(const QPen &pen) -{ - mSubTickPen = pen; -} - -/*! - Sets the font of the axis label. - - \see setLabelColor -*/ -void QCPAxis::setLabelFont(const QFont &font) -{ - if (mLabelFont != font) - { - mLabelFont = font; - mCachedMarginValid = false; - } -} - -/*! - Sets the color of the axis label. - - \see setLabelFont -*/ -void QCPAxis::setLabelColor(const QColor &color) -{ - mLabelColor = color; -} - -/*! - Sets the text of the axis label that will be shown below/above or next to the axis, depending on - its orientation. To disable axis labels, pass an empty string as \a str. -*/ -void QCPAxis::setLabel(const QString &str) -{ - if (mLabel != str) - { - mLabel = str; - mCachedMarginValid = false; - } -} - -/*! - Sets the distance between the tick labels and the axis label. - - \see setTickLabelPadding, setPadding -*/ -void QCPAxis::setLabelPadding(int padding) -{ - if (mAxisPainter->labelPadding != padding) - { - mAxisPainter->labelPadding = padding; - mCachedMarginValid = false; - } -} - -/*! - Sets the padding of the axis. - - When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, - that is left blank. - - The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. - - \see setLabelPadding, setTickLabelPadding -*/ -void QCPAxis::setPadding(int padding) -{ - if (mPadding != padding) - { - mPadding = padding; - mCachedMarginValid = false; - } -} - -/*! - Sets the offset the axis has to its axis rect side. - - If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, - only the offset of the inner most axis has meaning (even if it is set to be invisible). The - offset of the other, outer axes is controlled automatically, to place them at appropriate - positions. -*/ -void QCPAxis::setOffset(int offset) -{ - mAxisPainter->offset = offset; -} - -/*! - Sets the font that is used for tick labels when they are selected. - - \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedTickLabelFont(const QFont &font) -{ - if (font != mSelectedTickLabelFont) - { - mSelectedTickLabelFont = font; - // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts - } -} - -/*! - Sets the font that is used for the axis label when it is selected. - - \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedLabelFont(const QFont &font) -{ - mSelectedLabelFont = font; - // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts -} - -/*! - Sets the color that is used for tick labels when they are selected. - - \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedTickLabelColor(const QColor &color) -{ - if (color != mSelectedTickLabelColor) - { - mSelectedTickLabelColor = color; - } -} - -/*! - Sets the color that is used for the axis label when it is selected. - - \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedLabelColor(const QColor &color) -{ - mSelectedLabelColor = color; -} - -/*! - Sets the pen that is used to draw the axis base line when selected. - - \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedBasePen(const QPen &pen) -{ - mSelectedBasePen = pen; -} - -/*! - Sets the pen that is used to draw the (major) ticks when selected. - - \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedTickPen(const QPen &pen) -{ - mSelectedTickPen = pen; -} - -/*! - Sets the pen that is used to draw the subticks when selected. - - \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedSubTickPen(const QPen &pen) -{ - mSelectedSubTickPen = pen; -} - -/*! - Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available - styles. - - For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. - Note that this meaning does not change when the axis range is reversed with \ref - setRangeReversed. - - \see setUpperEnding -*/ -void QCPAxis::setLowerEnding(const QCPLineEnding &ending) -{ - mAxisPainter->lowerEnding = ending; -} - -/*! - Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available - styles. - - For horizontal axes, this method refers to the right ending, for vertical axes the top ending. - Note that this meaning does not change when the axis range is reversed with \ref - setRangeReversed. - - \see setLowerEnding -*/ -void QCPAxis::setUpperEnding(const QCPLineEnding &ending) -{ - mAxisPainter->upperEnding = ending; -} - -/*! - If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper - bounds of the range. The range is simply moved by \a diff. - - If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This - corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). -*/ -void QCPAxis::moveRange(double diff) -{ - QCPRange oldRange = mRange; - if (mScaleType == stLinear) - { - mRange.lower += diff; - mRange.upper += diff; - } else // mScaleType == stLogarithmic - { - mRange.lower *= diff; - mRange.upper *= diff; - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Scales the range of this axis by \a factor around the center of the current axis range. For - example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis - range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around - the center will have moved symmetrically closer). - - If you wish to scale around a different coordinate than the current axis range center, use the - overload \ref scaleRange(double factor, double center). -*/ -void QCPAxis::scaleRange(double factor) -{ - scaleRange(factor, range().center()); -} - -/*! \overload - - Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a - factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at - coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates - around 1.0 will have moved symmetrically closer to 1.0). - - \see scaleRange(double factor) -*/ -void QCPAxis::scaleRange(double factor, double center) -{ - QCPRange oldRange = mRange; - if (mScaleType == stLinear) - { - QCPRange newRange; - newRange.lower = (mRange.lower-center)*factor + center; - newRange.upper = (mRange.upper-center)*factor + center; - if (QCPRange::validRange(newRange)) - mRange = newRange.sanitizedForLinScale(); - } else // mScaleType == stLogarithmic - { - if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range - { - QCPRange newRange; - newRange.lower = qPow(mRange.lower/center, factor)*center; - newRange.upper = qPow(mRange.upper/center, factor)*center; - if (QCPRange::validRange(newRange)) - mRange = newRange.sanitizedForLogScale(); - } else - qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will - be done around the center of the current axis range. - - For example, if \a ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs - plotted with those axes will appear in a 1:1 aspect ratio, independent of the aspect ratio the - axis rect has. - - This is an operation that changes the range of this axis once, it doesn't fix the scale ratio - indefinitely. Note that calling this function in the constructor of the QCustomPlot's parent - won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent - will follow. -*/ -void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) -{ - int otherPixelSize, ownPixelSize; - - if (otherAxis->orientation() == Qt::Horizontal) - otherPixelSize = otherAxis->axisRect()->width(); - else - otherPixelSize = otherAxis->axisRect()->height(); - - if (orientation() == Qt::Horizontal) - ownPixelSize = axisRect()->width(); - else - ownPixelSize = axisRect()->height(); - - double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/(double)otherPixelSize; - setRange(range().center(), newRangeSize, Qt::AlignCenter); -} - -/*! - Changes the axis range such that all plottables associated with this axis are fully visible in - that dimension. - - \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes -*/ -void QCPAxis::rescale(bool onlyVisiblePlottables) -{ - QList p = plottables(); - QCPRange newRange; - bool haveRange = false; - for (int i=0; irealVisibility() && onlyVisiblePlottables) - continue; - QCPRange plottableRange; - bool currentFoundRange; - QCP::SignDomain signDomain = QCP::sdBoth; - if (mScaleType == stLogarithmic) - signDomain = (mRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); - if (p.at(i)->keyAxis() == this) - plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain); - else - plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain); - if (currentFoundRange) - { - if (!haveRange) - newRange = plottableRange; - else - newRange.expand(plottableRange); - haveRange = true; - } - } - if (haveRange) - { - if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable - { - double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason - if (mScaleType == stLinear) - { - newRange.lower = center-mRange.size()/2.0; - newRange.upper = center+mRange.size()/2.0; - } else // mScaleType == stLogarithmic - { - newRange.lower = center/qSqrt(mRange.upper/mRange.lower); - newRange.upper = center*qSqrt(mRange.upper/mRange.lower); - } - } - setRange(newRange); - } -} - -/*! - Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. -*/ -double QCPAxis::pixelToCoord(double value) const -{ - if (orientation() == Qt::Horizontal) - { - if (mScaleType == stLinear) - { - if (!mRangeReversed) - return (value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.lower; - else - return -(value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.upper; - } else // mScaleType == stLogarithmic - { - if (!mRangeReversed) - return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/(double)mAxisRect->width())*mRange.lower; - else - return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/(double)mAxisRect->width())*mRange.upper; - } - } else // orientation() == Qt::Vertical - { - if (mScaleType == stLinear) - { - if (!mRangeReversed) - return (mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.lower; - else - return -(mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.upper; - } else // mScaleType == stLogarithmic - { - if (!mRangeReversed) - return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/(double)mAxisRect->height())*mRange.lower; - else - return qPow(mRange.upper/mRange.lower, (value-mAxisRect->bottom())/(double)mAxisRect->height())*mRange.upper; - } - } -} - -/*! - Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. -*/ -double QCPAxis::coordToPixel(double value) const -{ - if (orientation() == Qt::Horizontal) - { - if (mScaleType == stLinear) - { - if (!mRangeReversed) - return (value-mRange.lower)/mRange.size()*mAxisRect->width()+mAxisRect->left(); - else - return (mRange.upper-value)/mRange.size()*mAxisRect->width()+mAxisRect->left(); - } else // mScaleType == stLogarithmic - { - if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range - return !mRangeReversed ? mAxisRect->right()+200 : mAxisRect->left()-200; - else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range - return !mRangeReversed ? mAxisRect->left()-200 : mAxisRect->right()+200; - else - { - if (!mRangeReversed) - return qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); - else - return qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); - } - } - } else // orientation() == Qt::Vertical - { - if (mScaleType == stLinear) - { - if (!mRangeReversed) - return mAxisRect->bottom()-(value-mRange.lower)/mRange.size()*mAxisRect->height(); - else - return mAxisRect->bottom()-(mRange.upper-value)/mRange.size()*mAxisRect->height(); - } else // mScaleType == stLogarithmic - { - if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range - return !mRangeReversed ? mAxisRect->top()-200 : mAxisRect->bottom()+200; - else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range - return !mRangeReversed ? mAxisRect->bottom()+200 : mAxisRect->top()-200; - else - { - if (!mRangeReversed) - return mAxisRect->bottom()-qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); - else - return mAxisRect->bottom()-qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); - } - } - } -} - -/*! - Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function - is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this - function does not change the current selection state of the axis. - - If the axis is not visible (\ref setVisible), this function always returns \ref spNone. - - \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions -*/ -QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const -{ - if (!mVisible) - return spNone; - - if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) - return spAxis; - else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) - return spTickLabels; - else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) - return spAxisLabel; - else - return spNone; -} - -/* inherits documentation from base class */ -double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if (!mParentPlot) return -1; - SelectablePart part = getPartAt(pos); - if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) - return -1; - - if (details) - details->setValue(part); - return mParentPlot->selectionTolerance()*0.99; -} - -/*! - Returns a list of all the plottables that have this axis as key or value axis. - - If you are only interested in plottables of type QCPGraph, see \ref graphs. - - \see graphs, items -*/ -QList QCPAxis::plottables() const -{ - QList result; - if (!mParentPlot) return result; - - for (int i=0; imPlottables.size(); ++i) - { - if (mParentPlot->mPlottables.at(i)->keyAxis() == this ||mParentPlot->mPlottables.at(i)->valueAxis() == this) - result.append(mParentPlot->mPlottables.at(i)); - } - return result; -} - -/*! - Returns a list of all the graphs that have this axis as key or value axis. - - \see plottables, items -*/ -QList QCPAxis::graphs() const -{ - QList result; - if (!mParentPlot) return result; - - for (int i=0; imGraphs.size(); ++i) - { - if (mParentPlot->mGraphs.at(i)->keyAxis() == this || mParentPlot->mGraphs.at(i)->valueAxis() == this) - result.append(mParentPlot->mGraphs.at(i)); - } - return result; -} - -/*! - Returns a list of all the items that are associated with this axis. An item is considered - associated with an axis if at least one of its positions uses the axis as key or value axis. - - \see plottables, graphs -*/ -QList QCPAxis::items() const -{ - QList result; - if (!mParentPlot) return result; - - for (int itemId=0; itemIdmItems.size(); ++itemId) - { - QList positions = mParentPlot->mItems.at(itemId)->positions(); - for (int posId=0; posIdkeyAxis() == this || positions.at(posId)->valueAxis() == this) - { - result.append(mParentPlot->mItems.at(itemId)); - break; - } - } - } - return result; -} - -/*! - Transforms a margin side to the logically corresponding axis type. (QCP::msLeft to - QCPAxis::atLeft, QCP::msRight to QCPAxis::atRight, etc.) -*/ -QCPAxis::AxisType QCPAxis::marginSideToAxisType(QCP::MarginSide side) -{ - switch (side) - { - case QCP::msLeft: return atLeft; - case QCP::msRight: return atRight; - case QCP::msTop: return atTop; - case QCP::msBottom: return atBottom; - default: break; - } - qDebug() << Q_FUNC_INFO << "Invalid margin side passed:" << (int)side; - return atLeft; -} - -/*! - Returns the axis type that describes the opposite axis of an axis with the specified \a type. -*/ -QCPAxis::AxisType QCPAxis::opposite(QCPAxis::AxisType type) -{ - switch (type) - { - case atLeft: return atRight; break; - case atRight: return atLeft; break; - case atBottom: return atTop; break; - case atTop: return atBottom; break; - default: qDebug() << Q_FUNC_INFO << "invalid axis type"; return atLeft; break; - } -} - -/* inherits documentation from base class */ -void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - SelectablePart part = details.value(); - if (mSelectableParts.testFlag(part)) - { - SelectableParts selBefore = mSelectedParts; - setSelectedParts(additive ? mSelectedParts^part : part); - if (selectionStateChanged) - *selectionStateChanged = mSelectedParts != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPAxis::deselectEvent(bool *selectionStateChanged) -{ - SelectableParts selBefore = mSelectedParts; - setSelectedParts(mSelectedParts & ~mSelectableParts); - if (selectionStateChanged) - *selectionStateChanged = mSelectedParts != selBefore; -} - -/*! \internal - - This mouse event reimplementation provides the functionality to let the user drag individual axes - exclusively, by startig the drag on top of the axis. - - For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect - must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis - (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref - QCPAxisRect::setRangeDragAxes) - - \seebaseclassmethod - - \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis - rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. -*/ -void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag) || - !mAxisRect->rangeDrag().testFlag(orientation()) || - !mAxisRect->rangeDragAxes(orientation()).contains(this)) - { - event->ignore(); - return; - } - - if (event->buttons() & Qt::LeftButton) - { - mDragging = true; - // initialize antialiasing backup in case we start dragging: - if (mParentPlot->noAntialiasingOnDrag()) - { - mAADragBackup = mParentPlot->antialiasedElements(); - mNotAADragBackup = mParentPlot->notAntialiasedElements(); - } - // Mouse range dragging interaction: - if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) - mDragStartRange = mRange; - } -} - -/*! \internal - - This mouse event reimplementation provides the functionality to let the user drag individual axes - exclusively, by startig the drag on top of the axis. - - \seebaseclassmethod - - \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis - rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. - - \see QCPAxis::mousePressEvent -*/ -void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - if (mDragging) - { - const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y(); - const double currentPixel = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y(); - if (mScaleType == QCPAxis::stLinear) - { - const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel); - setRange(mDragStartRange.lower+diff, mDragStartRange.upper+diff); - } else if (mScaleType == QCPAxis::stLogarithmic) - { - const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); - setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); - } - - if (mParentPlot->noAntialiasingOnDrag()) - mParentPlot->setNotAntialiasedElements(QCP::aeAll); - mParentPlot->replot(QCustomPlot::rpQueuedReplot); - } -} - -/*! \internal - - This mouse event reimplementation provides the functionality to let the user drag individual axes - exclusively, by startig the drag on top of the axis. - - \seebaseclassmethod - - \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis - rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. - - \see QCPAxis::mousePressEvent -*/ -void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(event) - Q_UNUSED(startPos) - mDragging = false; - if (mParentPlot->noAntialiasingOnDrag()) - { - mParentPlot->setAntialiasedElements(mAADragBackup); - mParentPlot->setNotAntialiasedElements(mNotAADragBackup); - } -} - -/*! \internal - - This mouse event reimplementation provides the functionality to let the user zoom individual axes - exclusively, by performing the wheel event on top of the axis. - - For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect - must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis - (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref - QCPAxisRect::setRangeZoomAxes) - - \seebaseclassmethod - - \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the - axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. -*/ -void QCPAxis::wheelEvent(QWheelEvent *event) -{ - // Mouse range zooming interaction: - if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom) || - !mAxisRect->rangeZoom().testFlag(orientation()) || - !mAxisRect->rangeZoomAxes(orientation()).contains(this)) - { - event->ignore(); - return; - } - - const double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually - const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps); - scaleRange(factor, pixelToCoord(orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y())); - mParentPlot->replot(); -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing axis lines. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \seebaseclassmethod - - \see setAntialiased -*/ -void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); -} - -/*! \internal - - Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. - - \seebaseclassmethod -*/ -void QCPAxis::draw(QCPPainter *painter) -{ - QVector subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter - QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter - QVector tickLabels; // the final vector passed to QCPAxisPainter - tickPositions.reserve(mTickVector.size()); - tickLabels.reserve(mTickVector.size()); - subTickPositions.reserve(mSubTickVector.size()); - - if (mTicks) - { - for (int i=0; itype = mAxisType; - mAxisPainter->basePen = getBasePen(); - mAxisPainter->labelFont = getLabelFont(); - mAxisPainter->labelColor = getLabelColor(); - mAxisPainter->label = mLabel; - mAxisPainter->substituteExponent = mNumberBeautifulPowers; - mAxisPainter->tickPen = getTickPen(); - mAxisPainter->subTickPen = getSubTickPen(); - mAxisPainter->tickLabelFont = getTickLabelFont(); - mAxisPainter->tickLabelColor = getTickLabelColor(); - mAxisPainter->axisRect = mAxisRect->rect(); - mAxisPainter->viewportRect = mParentPlot->viewport(); - mAxisPainter->abbreviateDecimalPowers = mScaleType == stLogarithmic; - mAxisPainter->reversedEndings = mRangeReversed; - mAxisPainter->tickPositions = tickPositions; - mAxisPainter->tickLabels = tickLabels; - mAxisPainter->subTickPositions = subTickPositions; - mAxisPainter->draw(painter); -} - -/*! \internal - - Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling - QCPAxisTicker::generate on the currently installed ticker. - - If a change in the label text/count is detected, the cached axis margin is invalidated to make - sure the next margin calculation recalculates the label sizes and returns an up-to-date value. -*/ -void QCPAxis::setupTickVectors() -{ - if (!mParentPlot) return; - if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; - - QVector oldLabels = mTickVectorLabels; - mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); - mCachedMarginValid &= mTickVectorLabels == oldLabels; // if labels have changed, margin might have changed, too -} - -/*! \internal - - Returns the pen that is used to draw the axis base line. Depending on the selection state, this - is either mSelectedBasePen or mBasePen. -*/ -QPen QCPAxis::getBasePen() const -{ - return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; -} - -/*! \internal - - Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this - is either mSelectedTickPen or mTickPen. -*/ -QPen QCPAxis::getTickPen() const -{ - return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; -} - -/*! \internal - - Returns the pen that is used to draw the subticks. Depending on the selection state, this - is either mSelectedSubTickPen or mSubTickPen. -*/ -QPen QCPAxis::getSubTickPen() const -{ - return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; -} - -/*! \internal - - Returns the font that is used to draw the tick labels. Depending on the selection state, this - is either mSelectedTickLabelFont or mTickLabelFont. -*/ -QFont QCPAxis::getTickLabelFont() const -{ - return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; -} - -/*! \internal - - Returns the font that is used to draw the axis label. Depending on the selection state, this - is either mSelectedLabelFont or mLabelFont. -*/ -QFont QCPAxis::getLabelFont() const -{ - return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; -} - -/*! \internal - - Returns the color that is used to draw the tick labels. Depending on the selection state, this - is either mSelectedTickLabelColor or mTickLabelColor. -*/ -QColor QCPAxis::getTickLabelColor() const -{ - return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; -} - -/*! \internal - - Returns the color that is used to draw the axis label. Depending on the selection state, this - is either mSelectedLabelColor or mLabelColor. -*/ -QColor QCPAxis::getLabelColor() const -{ - return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; -} - -/*! \internal - - Returns the appropriate outward margin for this axis. It is needed if \ref - QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref - atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom - margin and so forth. For the calculation, this function goes through similar steps as \ref draw, - so changing one function likely requires the modification of the other one as well. - - The margin consists of the outward tick length, tick label padding, tick label size, label - padding, label size, and padding. - - The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. - unchanged are very fast. -*/ -int QCPAxis::calculateMargin() -{ - if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis - return 0; - - if (mCachedMarginValid) - return mCachedMargin; - - // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels - int margin = 0; - - QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter - QVector tickLabels; // the final vector passed to QCPAxisPainter - tickPositions.reserve(mTickVector.size()); - tickLabels.reserve(mTickVector.size()); - - if (mTicks) - { - for (int i=0; itype = mAxisType; - mAxisPainter->labelFont = getLabelFont(); - mAxisPainter->label = mLabel; - mAxisPainter->tickLabelFont = mTickLabelFont; - mAxisPainter->axisRect = mAxisRect->rect(); - mAxisPainter->viewportRect = mParentPlot->viewport(); - mAxisPainter->tickPositions = tickPositions; - mAxisPainter->tickLabels = tickLabels; - margin += mAxisPainter->size(); - margin += mPadding; - - mCachedMargin = margin; - mCachedMarginValid = true; - return margin; -} - -/* inherits documentation from base class */ -QCP::Interaction QCPAxis::selectionCategory() const -{ - return QCP::iSelectAxes; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisPainterPrivate -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAxisPainterPrivate - - \internal - \brief (Private) - - This is a private class and not part of the public QCustomPlot interface. - - It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and - axis label. It also buffers the labels to reduce replot times. The parameters are configured by - directly accessing the public member variables. -*/ - -/*! - Constructs a QCPAxisPainterPrivate instance. Make sure to not create a new instance on every - redraw, to utilize the caching mechanisms. -*/ -QCPAxisPainterPrivate::QCPAxisPainterPrivate(QCustomPlot *parentPlot) : - type(QCPAxis::atLeft), - basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - lowerEnding(QCPLineEnding::esNone), - upperEnding(QCPLineEnding::esNone), - labelPadding(0), - tickLabelPadding(0), - tickLabelRotation(0), - tickLabelSide(QCPAxis::lsOutside), - substituteExponent(true), - numberMultiplyCross(false), - tickLengthIn(5), - tickLengthOut(0), - subTickLengthIn(2), - subTickLengthOut(0), - tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - offset(0), - abbreviateDecimalPowers(false), - reversedEndings(false), - mParentPlot(parentPlot), - mLabelCache(16) // cache at most 16 (tick) labels -{ -} - -QCPAxisPainterPrivate::~QCPAxisPainterPrivate() -{ -} - -/*! \internal - - Draws the axis with the specified \a painter. - - The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set - here, too. -*/ -void QCPAxisPainterPrivate::draw(QCPPainter *painter) -{ - QByteArray newHash = generateLabelParameterHash(); - if (newHash != mLabelParameterHash) - { - mLabelCache.clear(); - mLabelParameterHash = newHash; - } - - QPoint origin; - switch (type) - { - case QCPAxis::atLeft: origin = axisRect.bottomLeft() +QPoint(-offset, 0); break; - case QCPAxis::atRight: origin = axisRect.bottomRight()+QPoint(+offset, 0); break; - case QCPAxis::atTop: origin = axisRect.topLeft() +QPoint(0, -offset); break; - case QCPAxis::atBottom: origin = axisRect.bottomLeft() +QPoint(0, +offset); break; - } - - double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) - switch (type) - { - case QCPAxis::atTop: yCor = -1; break; - case QCPAxis::atRight: xCor = 1; break; - default: break; - } - int margin = 0; - // draw baseline: - QLineF baseLine; - painter->setPen(basePen); - if (QCPAxis::orientation(type) == Qt::Horizontal) - baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(axisRect.width()+xCor, yCor)); - else - baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -axisRect.height()+yCor)); - if (reversedEndings) - baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later - painter->drawLine(baseLine); - - // draw ticks: - if (!tickPositions.isEmpty()) - { - painter->setPen(tickPen); - int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis) - if (QCPAxis::orientation(type) == Qt::Horizontal) - { - for (int i=0; idrawLine(QLineF(tickPositions.at(i)+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPositions.at(i)+xCor, origin.y()+tickLengthIn*tickDir+yCor)); - } else - { - for (int i=0; idrawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPositions.at(i)+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPositions.at(i)+yCor)); - } - } - - // draw subticks: - if (!subTickPositions.isEmpty()) - { - painter->setPen(subTickPen); - // direction of ticks ("inward" is right for left axis and left for right axis) - int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; - if (QCPAxis::orientation(type) == Qt::Horizontal) - { - for (int i=0; idrawLine(QLineF(subTickPositions.at(i)+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPositions.at(i)+xCor, origin.y()+subTickLengthIn*tickDir+yCor)); - } else - { - for (int i=0; idrawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPositions.at(i)+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPositions.at(i)+yCor)); - } - } - margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); - - // draw axis base endings: - bool antialiasingBackup = painter->antialiasing(); - painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't - painter->setBrush(QBrush(basePen.color())); - QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); - if (lowerEnding.style() != QCPLineEnding::esNone) - lowerEnding.draw(painter, QCPVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector); - if (upperEnding.style() != QCPLineEnding::esNone) - upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); - painter->setAntialiasing(antialiasingBackup); - - // tick labels: - QRect oldClipRect; - if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect - { - oldClipRect = painter->clipRegion().boundingRect(); - painter->setClipRect(axisRect); - } - QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label - if (!tickLabels.isEmpty()) - { - if (tickLabelSide == QCPAxis::lsOutside) - margin += tickLabelPadding; - painter->setFont(tickLabelFont); - painter->setPen(QPen(tickLabelColor)); - const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size()); - int distanceToAxis = margin; - if (tickLabelSide == QCPAxis::lsInside) - distanceToAxis = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); - for (int i=0; isetClipRect(oldClipRect); - - // axis label: - QRect labelBounds; - if (!label.isEmpty()) - { - margin += labelPadding; - painter->setFont(labelFont); - painter->setPen(QPen(labelColor)); - labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, label); - if (type == QCPAxis::atLeft) - { - QTransform oldTransform = painter->transform(); - painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); - painter->rotate(-90); - painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); - painter->setTransform(oldTransform); - } - else if (type == QCPAxis::atRight) - { - QTransform oldTransform = painter->transform(); - painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-axisRect.height()); - painter->rotate(90); - painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); - painter->setTransform(oldTransform); - } - else if (type == QCPAxis::atTop) - painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); - else if (type == QCPAxis::atBottom) - painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); - } - - // set selection boxes: - int selectionTolerance = 0; - if (mParentPlot) - selectionTolerance = mParentPlot->selectionTolerance(); - else - qDebug() << Q_FUNC_INFO << "mParentPlot is null"; - int selAxisOutSize = qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance); - int selAxisInSize = selectionTolerance; - int selTickLabelSize; - int selTickLabelOffset; - if (tickLabelSide == QCPAxis::lsOutside) - { - selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); - selTickLabelOffset = qMax(tickLengthOut, subTickLengthOut)+tickLabelPadding; - } else - { - selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); - selTickLabelOffset = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); - } - int selLabelSize = labelBounds.height(); - int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding; - if (type == QCPAxis::atLeft) - { - mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom()); - mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom()); - mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom()); - } else if (type == QCPAxis::atRight) - { - mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom()); - mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom()); - mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom()); - } else if (type == QCPAxis::atTop) - { - mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize); - mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset); - mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset); - } else if (type == QCPAxis::atBottom) - { - mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize); - mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset); - mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset); - } - mAxisSelectionBox = mAxisSelectionBox.normalized(); - mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized(); - mLabelSelectionBox = mLabelSelectionBox.normalized(); - // draw hitboxes for debug purposes: - //painter->setBrush(Qt::NoBrush); - //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); -} - -/*! \internal - - Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone - direction) needed to fit the axis. -*/ -int QCPAxisPainterPrivate::size() const -{ - int result = 0; - - // get length of tick marks pointing outwards: - if (!tickPositions.isEmpty()) - result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); - - // calculate size of tick labels: - if (tickLabelSide == QCPAxis::lsOutside) - { - QSize tickLabelsSize(0, 0); - if (!tickLabels.isEmpty()) - { - for (int i=0; ibufferDevicePixelRatio())); - result.append(QByteArray::number(tickLabelRotation)); - result.append(QByteArray::number((int)tickLabelSide)); - result.append(QByteArray::number((int)substituteExponent)); - result.append(QByteArray::number((int)numberMultiplyCross)); - result.append(tickLabelColor.name().toLatin1()+QByteArray::number(tickLabelColor.alpha(), 16)); - result.append(tickLabelFont.toString().toLatin1()); - return result; -} - -/*! \internal - - Draws a single tick label with the provided \a painter, utilizing the internal label cache to - significantly speed up drawing of labels that were drawn in previous calls. The tick label is - always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in - pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence - for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), - at which the label should be drawn. - - In order to later draw the axis label in a place that doesn't overlap with the tick labels, the - largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref - drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a - tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently - holds. - - The label is drawn with the font and pen that are currently set on the \a painter. To draw - superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref - getTickLabelData). -*/ -void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize) -{ - // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! - if (text.isEmpty()) return; - QSize finalSize; - QPointF labelAnchor; - switch (type) - { - case QCPAxis::atLeft: labelAnchor = QPointF(axisRect.left()-distanceToAxis-offset, position); break; - case QCPAxis::atRight: labelAnchor = QPointF(axisRect.right()+distanceToAxis+offset, position); break; - case QCPAxis::atTop: labelAnchor = QPointF(position, axisRect.top()-distanceToAxis-offset); break; - case QCPAxis::atBottom: labelAnchor = QPointF(position, axisRect.bottom()+distanceToAxis+offset); break; - } - if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled - { - CachedLabel *cachedLabel = mLabelCache.take(text); // attempt to get label from cache - if (!cachedLabel) // no cached label existed, create it - { - cachedLabel = new CachedLabel; - TickLabelData labelData = getTickLabelData(painter->font(), text); - cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft(); - if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) - { - cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio()); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED -# ifdef QCP_DEVICEPIXELRATIO_FLOAT - cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF()); -# else - cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); -# endif -#endif - } else - cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); - cachedLabel->pixmap.fill(Qt::transparent); - QCPPainter cachePainter(&cachedLabel->pixmap); - cachePainter.setPen(painter->pen()); - drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData); - } - // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): - bool labelClippedByBorder = false; - if (tickLabelSide == QCPAxis::lsOutside) - { - if (QCPAxis::orientation(type) == Qt::Horizontal) - labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); - else - labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); - } - if (!labelClippedByBorder) - { - painter->drawPixmap(labelAnchor+cachedLabel->offset, cachedLabel->pixmap); - finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); - } - mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created - } else // label caching disabled, draw text directly on surface: - { - TickLabelData labelData = getTickLabelData(painter->font(), text); - QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData); - // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): - bool labelClippedByBorder = false; - if (tickLabelSide == QCPAxis::lsOutside) - { - if (QCPAxis::orientation(type) == Qt::Horizontal) - labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); - else - labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); - } - if (!labelClippedByBorder) - { - drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData); - finalSize = labelData.rotatedTotalBounds.size(); - } - } - - // expand passed tickLabelsSize if current tick label is larger: - if (finalSize.width() > tickLabelsSize->width()) - tickLabelsSize->setWidth(finalSize.width()); - if (finalSize.height() > tickLabelsSize->height()) - tickLabelsSize->setHeight(finalSize.height()); -} - -/*! \internal - - This is a \ref placeTickLabel helper function. - - Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a - y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to - directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when - QCP::phCacheLabels plotting hint is not set. -*/ -void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const -{ - // backup painter settings that we're about to change: - QTransform oldTransform = painter->transform(); - QFont oldFont = painter->font(); - - // transform painter to position/rotation: - painter->translate(x, y); - if (!qFuzzyIsNull(tickLabelRotation)) - painter->rotate(tickLabelRotation); - - // draw text: - if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used - { - painter->setFont(labelData.baseFont); - painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); - if (!labelData.suffixPart.isEmpty()) - painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart); - painter->setFont(labelData.expFont); - painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); - } else - { - painter->setFont(labelData.baseFont); - painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); - } - - // reset painter settings to what it was before: - painter->setTransform(oldTransform); - painter->setFont(oldFont); -} - -/*! \internal - - This is a \ref placeTickLabel helper function. - - Transforms the passed \a text and \a font to a tickLabelData structure that can then be further - processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and - exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. -*/ -QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const -{ - TickLabelData result; - - // determine whether beautiful decimal powers should be used - bool useBeautifulPowers = false; - int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart - int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart - if (substituteExponent) - { - ePos = text.indexOf(QLatin1Char('e')); - if (ePos > 0 && text.at(ePos-1).isDigit()) - { - eLast = ePos; - while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) - ++eLast; - if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power - useBeautifulPowers = true; - } - } - - // calculate text bounding rects and do string preparation for beautiful decimal powers: - result.baseFont = font; - if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line - result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding - if (useBeautifulPowers) - { - // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: - result.basePart = text.left(ePos); - result.suffixPart = text.mid(eLast+1); // also drawn normally but after exponent - // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: - if (abbreviateDecimalPowers && result.basePart == QLatin1String("1")) - result.basePart = QLatin1String("10"); - else - result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10"); - result.expPart = text.mid(ePos+1, eLast-ePos); - // clip "+" and leading zeros off expPart: - while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' - result.expPart.remove(1, 1); - if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) - result.expPart.remove(0, 1); - // prepare smaller font for exponent: - result.expFont = font; - if (result.expFont.pointSize() > 0) - result.expFont.setPointSize(result.expFont.pointSize()*0.75); - else - result.expFont.setPixelSize(result.expFont.pixelSize()*0.75); - // calculate bounding rects of base part(s), exponent part and total one: - result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); - result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); - if (!result.suffixPart.isEmpty()) - result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart); - result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA - } else // useBeautifulPowers == false - { - result.basePart = text; - result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); - } - result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler - - // calculate possibly different bounding rect after rotation: - result.rotatedTotalBounds = result.totalBounds; - if (!qFuzzyIsNull(tickLabelRotation)) - { - QTransform transform; - transform.rotate(tickLabelRotation); - result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); - } - - return result; -} - -/*! \internal - - This is a \ref placeTickLabel helper function. - - Calculates the offset at which the top left corner of the specified tick label shall be drawn. - The offset is relative to a point right next to the tick the label belongs to. - - This function is thus responsible for e.g. centering tick labels under ticks and positioning them - appropriately when they are rotated. -*/ -QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &labelData) const -{ - /* - calculate label offset from base point at tick (non-trivial, for best visual appearance): short - explanation for bottom axis: The anchor, i.e. the point in the label that is placed - horizontally under the corresponding tick is always on the label side that is closer to the - axis (e.g. the left side of the text when we're rotating clockwise). On that side, the height - is halved and the resulting point is defined the anchor. This way, a 90 degree rotated text - will be centered under the tick (i.e. displaced horizontally by half its height). At the same - time, a 45 degree rotated text will "point toward" its tick, as is typical for rotated tick - labels. - */ - bool doRotation = !qFuzzyIsNull(tickLabelRotation); - bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes. - double radians = tickLabelRotation/180.0*M_PI; - int x=0, y=0; - if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label - { - if (doRotation) - { - if (tickLabelRotation > 0) - { - x = -qCos(radians)*labelData.totalBounds.width(); - y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0; - } else - { - x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height(); - y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0; - } - } else - { - x = -labelData.totalBounds.width(); - y = -labelData.totalBounds.height()/2.0; - } - } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label - { - if (doRotation) - { - if (tickLabelRotation > 0) - { - x = +qSin(radians)*labelData.totalBounds.height(); - y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0; - } else - { - x = 0; - y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0; - } - } else - { - x = 0; - y = -labelData.totalBounds.height()/2.0; - } - } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label - { - if (doRotation) - { - if (tickLabelRotation > 0) - { - x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0; - y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height(); - } else - { - x = -qSin(-radians)*labelData.totalBounds.height()/2.0; - y = -qCos(-radians)*labelData.totalBounds.height(); - } - } else - { - x = -labelData.totalBounds.width()/2.0; - y = -labelData.totalBounds.height(); - } - } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label - { - if (doRotation) - { - if (tickLabelRotation > 0) - { - x = +qSin(radians)*labelData.totalBounds.height()/2.0; - y = 0; - } else - { - x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height()/2.0; - y = +qSin(-radians)*labelData.totalBounds.width(); - } - } else - { - x = -labelData.totalBounds.width()/2.0; - y = 0; - } - } - - return QPointF(x, y); -} - -/*! \internal - - Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label - to be drawn, depending on number format etc. Since only the largest tick label is wanted for the - margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a - smaller width/height. -*/ -void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const -{ - // note: this function must return the same tick label sizes as the placeTickLabel function. - QSize finalSize; - if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label - { - const CachedLabel *cachedLabel = mLabelCache.object(text); - finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); - } else // label caching disabled or no label with this text cached: - { - TickLabelData labelData = getTickLabelData(font, text); - finalSize = labelData.rotatedTotalBounds.size(); - } - - // expand passed tickLabelsSize if current tick label is larger: - if (finalSize.width() > tickLabelsSize->width()) - tickLabelsSize->setWidth(finalSize.width()); - if (finalSize.height() > tickLabelsSize->height()) - tickLabelsSize->setHeight(finalSize.height()); -} -/* end of 'src/axis/axis.cpp' */ - - -/* including file 'src/scatterstyle.cpp', size 17450 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPScatterStyle -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPScatterStyle - \brief Represents the visual appearance of scatter points - - This class holds information about shape, color and size of scatter points. In plottables like - QCPGraph it is used to store how scatter points shall be drawn. For example, \ref - QCPGraph::setScatterStyle takes a QCPScatterStyle instance. - - A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a - fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can - be controlled with \ref setSize. - - \section QCPScatterStyle-defining Specifying a scatter style - - You can set all these configurations either by calling the respective functions on an instance: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 - - Or you can use one of the various constructors that take different parameter combinations, making - it easy to specify a scatter style in a single call, like so: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 - - \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable - - There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref - QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref - isPenDefined will return false. It leads to scatter points that inherit the pen from the - plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line - color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes - it very convenient to set up typical scatter settings: - - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation - - Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works - because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly - into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) - constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref - ScatterShape, where actually a QCPScatterStyle is expected. - - \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps - - QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. - - For custom shapes, you can provide a QPainterPath with the desired shape to the \ref - setCustomPath function or call the constructor that takes a painter path. The scatter shape will - automatically be set to \ref ssCustom. - - For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the - constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. - Note that \ref setSize does not influence the appearance of the pixmap. -*/ - -/* start documentation of inline functions */ - -/*! \fn bool QCPScatterStyle::isNone() const - - Returns whether the scatter shape is \ref ssNone. - - \see setShape -*/ - -/*! \fn bool QCPScatterStyle::isPenDefined() const - - Returns whether a pen has been defined for this scatter style. - - The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those - are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen - is undefined, the pen of the respective plottable will be used for drawing scatters. - - If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call - \ref undefinePen. - - \see setPen -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. - - Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited - from the plottable that uses this scatter style. -*/ -QCPScatterStyle::QCPScatterStyle() : - mSize(6), - mShape(ssNone), - mPen(Qt::NoPen), - mBrush(Qt::NoBrush), - mPenDefined(false) -{ -} - -/*! - Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or - brush is defined. - - Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited - from the plottable that uses this scatter style. -*/ -QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) : - mSize(size), - mShape(shape), - mPen(Qt::NoPen), - mBrush(Qt::NoBrush), - mPenDefined(false) -{ -} - -/*! - Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, - and size to \a size. No brush is defined, i.e. the scatter point will not be filled. -*/ -QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) : - mSize(size), - mShape(shape), - mPen(QPen(color)), - mBrush(Qt::NoBrush), - mPenDefined(true) -{ -} - -/*! - Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, - the brush color to \a fill (with a solid pattern), and size to \a size. -*/ -QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) : - mSize(size), - mShape(shape), - mPen(QPen(color)), - mBrush(QBrush(fill)), - mPenDefined(true) -{ -} - -/*! - Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the - brush to \a brush, and size to \a size. - - \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen - and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n - QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n - doesn't necessarily lead C++ to use this constructor in some cases, but might mistake - Qt::NoPen for a QColor and use the - \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) - constructor instead (which will lead to an unexpected look of the scatter points). To prevent - this, be more explicit with the parameter types. For example, use QBrush(Qt::blue) - instead of just Qt::blue, to clearly point out to the compiler that this constructor is - wanted. -*/ -QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) : - mSize(size), - mShape(shape), - mPen(pen), - mBrush(brush), - mPenDefined(pen.style() != Qt::NoPen) -{ -} - -/*! - Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape - is set to \ref ssPixmap. -*/ -QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : - mSize(5), - mShape(ssPixmap), - mPen(Qt::NoPen), - mBrush(Qt::NoBrush), - mPixmap(pixmap), - mPenDefined(false) -{ -} - -/*! - Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The - scatter shape is set to \ref ssCustom. - - The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly - different meaning than for built-in scatter points: The custom path will be drawn scaled by a - factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its - original size by default. To for example double the size of the path, set \a size to 12. -*/ -QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) : - mSize(size), - mShape(ssCustom), - mPen(pen), - mBrush(brush), - mCustomPath(customPath), - mPenDefined(pen.style() != Qt::NoPen) -{ -} - -/*! - Copies the specified \a properties from the \a other scatter style to this scatter style. -*/ -void QCPScatterStyle::setFromOther(const QCPScatterStyle &other, ScatterProperties properties) -{ - if (properties.testFlag(spPen)) - { - setPen(other.pen()); - if (!other.isPenDefined()) - undefinePen(); - } - if (properties.testFlag(spBrush)) - setBrush(other.brush()); - if (properties.testFlag(spSize)) - setSize(other.size()); - if (properties.testFlag(spShape)) - { - setShape(other.shape()); - if (other.shape() == ssPixmap) - setPixmap(other.pixmap()); - else if (other.shape() == ssCustom) - setCustomPath(other.customPath()); - } -} - -/*! - Sets the size (pixel diameter) of the drawn scatter points to \a size. - - \see setShape -*/ -void QCPScatterStyle::setSize(double size) -{ - mSize = size; -} - -/*! - Sets the shape to \a shape. - - Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref - ssPixmap and \ref ssCustom, respectively. - - \see setSize -*/ -void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) -{ - mShape = shape; -} - -/*! - Sets the pen that will be used to draw scatter points to \a pen. - - If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after - a call to this function, even if \a pen is Qt::NoPen. If you have defined a pen - previously by calling this function and now wish to undefine the pen, call \ref undefinePen. - - \see setBrush -*/ -void QCPScatterStyle::setPen(const QPen &pen) -{ - mPenDefined = true; - mPen = pen; -} - -/*! - Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter - shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. - - \see setPen -*/ -void QCPScatterStyle::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the pixmap that will be drawn as scatter point to \a pixmap. - - Note that \ref setSize does not influence the appearance of the pixmap. - - The scatter shape is automatically set to \ref ssPixmap. -*/ -void QCPScatterStyle::setPixmap(const QPixmap &pixmap) -{ - setShape(ssPixmap); - mPixmap = pixmap; -} - -/*! - Sets the custom shape that will be drawn as scatter point to \a customPath. - - The scatter shape is automatically set to \ref ssCustom. -*/ -void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) -{ - setShape(ssCustom); - mCustomPath = customPath; -} - -/*! - Sets this scatter style to have an undefined pen (see \ref isPenDefined for what an undefined pen - implies). - - A call to \ref setPen will define a pen. -*/ -void QCPScatterStyle::undefinePen() -{ - mPenDefined = false; -} - -/*! - Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an - undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. - - This function is used by plottables (or any class that wants to draw scatters) just before a - number of scatters with this style shall be drawn with the \a painter. - - \see drawShape -*/ -void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const -{ - painter->setPen(mPenDefined ? mPen : defaultPen); - painter->setBrush(mBrush); -} - -/*! - Draws the scatter shape with \a painter at position \a pos. - - This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be - called before scatter points are drawn with \ref drawShape. - - \see applyTo -*/ -void QCPScatterStyle::drawShape(QCPPainter *painter, const QPointF &pos) const -{ - drawShape(painter, pos.x(), pos.y()); -} - -/*! \overload - Draws the scatter shape with \a painter at position \a x and \a y. -*/ -void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const -{ - double w = mSize/2.0; - switch (mShape) - { - case ssNone: break; - case ssDot: - { - painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y)); - break; - } - case ssCross: - { - painter->drawLine(QLineF(x-w, y-w, x+w, y+w)); - painter->drawLine(QLineF(x-w, y+w, x+w, y-w)); - break; - } - case ssPlus: - { - painter->drawLine(QLineF(x-w, y, x+w, y)); - painter->drawLine(QLineF( x, y+w, x, y-w)); - break; - } - case ssCircle: - { - painter->drawEllipse(QPointF(x , y), w, w); - break; - } - case ssDisc: - { - QBrush b = painter->brush(); - painter->setBrush(painter->pen().color()); - painter->drawEllipse(QPointF(x , y), w, w); - painter->setBrush(b); - break; - } - case ssSquare: - { - painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); - break; - } - case ssDiamond: - { - QPointF lineArray[4] = {QPointF(x-w, y), - QPointF( x, y-w), - QPointF(x+w, y), - QPointF( x, y+w)}; - painter->drawPolygon(lineArray, 4); - break; - } - case ssStar: - { - painter->drawLine(QLineF(x-w, y, x+w, y)); - painter->drawLine(QLineF( x, y+w, x, y-w)); - painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); - painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); - break; - } - case ssTriangle: - { - QPointF lineArray[3] = {QPointF(x-w, y+0.755*w), - QPointF(x+w, y+0.755*w), - QPointF( x, y-0.977*w)}; - painter->drawPolygon(lineArray, 3); - break; - } - case ssTriangleInverted: - { - QPointF lineArray[3] = {QPointF(x-w, y-0.755*w), - QPointF(x+w, y-0.755*w), - QPointF( x, y+0.977*w)}; - painter->drawPolygon(lineArray, 3); - break; - } - case ssCrossSquare: - { - painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); - painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); - painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); - break; - } - case ssPlusSquare: - { - painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); - painter->drawLine(QLineF(x-w, y, x+w*0.95, y)); - painter->drawLine(QLineF( x, y+w, x, y-w)); - break; - } - case ssCrossCircle: - { - painter->drawEllipse(QPointF(x, y), w, w); - painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670)); - painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707)); - break; - } - case ssPlusCircle: - { - painter->drawEllipse(QPointF(x, y), w, w); - painter->drawLine(QLineF(x-w, y, x+w, y)); - painter->drawLine(QLineF( x, y+w, x, y-w)); - break; - } - case ssPeace: - { - painter->drawEllipse(QPointF(x, y), w, w); - painter->drawLine(QLineF(x, y-w, x, y+w)); - painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); - painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); - break; - } - case ssPixmap: - { - const double widthHalf = mPixmap.width()*0.5; - const double heightHalf = mPixmap.height()*0.5; -#if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) - const QRectF clipRect = painter->clipRegion().boundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); -#else - const QRectF clipRect = painter->clipBoundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); -#endif - if (clipRect.contains(x, y)) - painter->drawPixmap(x-widthHalf, y-heightHalf, mPixmap); - break; - } - case ssCustom: - { - QTransform oldTransform = painter->transform(); - painter->translate(x, y); - painter->scale(mSize/6.0, mSize/6.0); - painter->drawPath(mCustomPath); - painter->setTransform(oldTransform); - break; - } - } -} -/* end of 'src/scatterstyle.cpp' */ - -//amalgamation: add datacontainer.cpp - -/* including file 'src/plottable.cpp', size 38845 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPSelectionDecorator -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPSelectionDecorator - \brief Controls how a plottable's data selection is drawn - - Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref - QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data. - - The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the - scatter style (\ref setScatterStyle) if the plottable draws scatters. Since a \ref - QCPScatterStyle is itself composed of different properties such as color shape and size, the - decorator allows specifying exactly which of those properties shall be used for the selected data - point, via \ref setUsedScatterProperties. - - A \ref QCPSelectionDecorator subclass instance can be passed to a plottable via \ref - QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance - of selected segments. - - Use \ref copyFrom to easily transfer the settings of one decorator to another one. This is - especially useful since plottables take ownership of the passed selection decorator, and thus the - same decorator instance can not be passed to multiple plottables. - - Selection decorators can also themselves perform drawing operations by reimplementing \ref - drawDecoration, which is called by the plottable's draw method. The base class \ref - QCPSelectionDecorator does not make use of this however. For example, \ref - QCPSelectionDecoratorBracket draws brackets around selected data segments. -*/ - -/*! - Creates a new QCPSelectionDecorator instance with default values -*/ -QCPSelectionDecorator::QCPSelectionDecorator() : - mPen(QColor(80, 80, 255), 2.5), - mBrush(Qt::NoBrush), - mScatterStyle(), - mUsedScatterProperties(QCPScatterStyle::spNone), - mPlottable(0) -{ -} - -QCPSelectionDecorator::~QCPSelectionDecorator() -{ -} - -/*! - Sets the pen that will be used by the parent plottable to draw selected data segments. -*/ -void QCPSelectionDecorator::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the brush that will be used by the parent plottable to draw selected data segments. -*/ -void QCPSelectionDecorator::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the scatter style that will be used by the parent plottable to draw scatters in selected - data segments. - - \a usedProperties specifies which parts of the passed \a scatterStyle will be used by the - plottable. The used properties can also be changed via \ref setUsedScatterProperties. -*/ -void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties) -{ - mScatterStyle = scatterStyle; - setUsedScatterProperties(usedProperties); -} - -/*! - Use this method to define which properties of the scatter style (set via \ref setScatterStyle) - will be used for selected data segments. All properties of the scatter style that are not - specified in \a properties will remain as specified in the plottable's original scatter style. - - \see QCPScatterStyle::ScatterProperty -*/ -void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties) -{ - mUsedScatterProperties = properties; -} - -/*! - Sets the pen of \a painter to the pen of this selection decorator. - - \see applyBrush, getFinalScatterStyle -*/ -void QCPSelectionDecorator::applyPen(QCPPainter *painter) const -{ - painter->setPen(mPen); -} - -/*! - Sets the brush of \a painter to the brush of this selection decorator. - - \see applyPen, getFinalScatterStyle -*/ -void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const -{ - painter->setBrush(mBrush); -} - -/*! - Returns the scatter style that the parent plottable shall use for selected scatter points. The - plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending - on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this - selecion decorator's scatter style (\ref setScatterStyle), and \a unselectedStyle. - - \see applyPen, applyBrush, setScatterStyle -*/ -QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const -{ - QCPScatterStyle result(unselectedStyle); - result.setFromOther(mScatterStyle, mUsedScatterProperties); - - // if style shall inherit pen from plottable (has no own pen defined), give it the selected - // plottable pen explicitly, so it doesn't use the unselected plottable pen when used in the - // plottable: - if (!result.isPenDefined()) - result.setPen(mPen); - - return result; -} - -/*! - Copies all properties (e.g. color, fill, scatter style) of the \a other selection decorator to - this selection decorator. -*/ -void QCPSelectionDecorator::copyFrom(const QCPSelectionDecorator *other) -{ - setPen(other->pen()); - setBrush(other->brush()); - setScatterStyle(other->scatterStyle(), other->usedScatterProperties()); -} - -/*! - This method is called by all plottables' draw methods to allow custom selection decorations to be - drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data - selection for which the decoration shall be drawn. - - The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so - this method does nothing. -*/ -void QCPSelectionDecorator::drawDecoration(QCPPainter *painter, QCPDataSelection selection) -{ - Q_UNUSED(painter) - Q_UNUSED(selection) -} - -/*! \internal - - This method is called as soon as a selection decorator is associated with a plottable, by a call - to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access - data points via the \ref QCPAbstractPlottable::interface1D interface). - - If the selection decorator was already added to a different plottable before, this method aborts - the registration and returns false. -*/ -bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottable) -{ - if (!mPlottable) - { - mPlottable = plottable; - return true; - } else - { - qDebug() << Q_FUNC_INFO << "This selection decorator is already registered with plottable:" << reinterpret_cast(mPlottable); - return false; - } -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractPlottable -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractPlottable - \brief The abstract base class for all data representing objects in a plot. - - It defines a very basic interface like name, pen, brush, visibility etc. Since this class is - abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to - create new ways of displaying data (see "Creating own plottables" below). Plottables that display - one-dimensional data (i.e. data points have a single key dimension and one or multiple values at - each key) are based off of the template subclass \ref QCPAbstractPlottable1D, see details - there. - - All further specifics are in the subclasses, for example: - \li A normal graph with possibly a line and/or scatter points \ref QCPGraph - (typically created with \ref QCustomPlot::addGraph) - \li A parametric curve: \ref QCPCurve - \li A bar chart: \ref QCPBars - \li A statistical box plot: \ref QCPStatisticalBox - \li A color encoded two-dimensional map: \ref QCPColorMap - \li An OHLC/Candlestick chart: \ref QCPFinancial - - \section plottables-subclassing Creating own plottables - - Subclassing directly from QCPAbstractPlottable is only recommended if you wish to display - two-dimensional data like \ref QCPColorMap, i.e. two logical key dimensions and one (or more) - data dimensions. If you want to display data with only one logical key dimension, you should - rather derive from \ref QCPAbstractPlottable1D. - - If subclassing QCPAbstractPlottable directly, these are the pure virtual functions you must - implement: - \li \ref selectTest - \li \ref draw - \li \ref drawLegendIcon - \li \ref getKeyRange - \li \ref getValueRange - - See the documentation of those functions for what they need to do. - - For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot - coordinates to pixel coordinates. This function is quite convenient, because it takes the - orientation of the key and value axes into account for you (x and y are swapped when the key axis - is vertical and the value axis horizontal). If you are worried about performance (i.e. you need - to translate many points in a loop like QCPGraph), you can directly use \ref - QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis - yourself. - - Here are some important members you inherit from QCPAbstractPlottable: - - - - - - - - - - - - - - - - - - - - - - - - - - -
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable - (e.g QCPGraph uses this pen for its graph lines and scatters)
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable - (e.g. QCPGraph uses this brush to control filling under the graph)
QPointer<\ref QCPAxis> \b mKeyAxis, \b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates - to pixels in either the key or value dimension. Make sure to check whether the pointer is null before using it. If one of - the axes is null, don't draw the plottable.
\ref QCPSelectionDecorator \b mSelectionDecoratorThe currently set selection decorator which specifies how selected data of the plottable shall be drawn and decorated. - When drawing your data, you must consult this decorator for the appropriate pen/brush before drawing unselected/selected data segments. - Finally, you should call its \ref QCPSelectionDecorator::drawDecoration method at the end of your \ref draw implementation.
\ref QCP::SelectionType \b mSelectableIn which composition, if at all, this plottable's data may be selected. Enforcing this setting on the data selection is done - by QCPAbstractPlottable automatically.
\ref QCPDataSelection \b mSelectionHolds the current selection state of the plottable's data, i.e. the selected data ranges (\ref QCPDataRange).
-*/ - -/* start of documentation of inline functions */ - -/*! \fn QCPSelectionDecorator *QCPAbstractPlottable::selectionDecorator() const - - Provides access to the selection decorator of this plottable. The selection decorator controls - how selected data ranges are drawn (e.g. their pen color and fill), see \ref - QCPSelectionDecorator for details. - - If you wish to use an own \ref QCPSelectionDecorator subclass, pass an instance of it to \ref - setSelectionDecorator. -*/ - -/*! \fn bool QCPAbstractPlottable::selected() const - - Returns true if there are any data points of the plottable currently selected. Use \ref selection - to retrieve the current \ref QCPDataSelection. -*/ - -/*! \fn QCPDataSelection QCPAbstractPlottable::selection() const - - Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on - this plottable. - - \see selected, setSelection, setSelectable -*/ - -/*! \fn virtual QCPPlottableInterface1D *QCPAbstractPlottable::interface1D() - - If this plottable is a one-dimensional plottable, i.e. it implements the \ref - QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case - of a \ref QCPColorMap) returns zero. - - You can use this method to gain read access to data coordinates while holding a pointer to the - abstract base class only. -*/ - -/* end of documentation of inline functions */ -/* start of documentation of pure virtual functions */ - -/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 - \internal - - called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation - of this plottable inside \a rect, next to the plottable name. - - The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't - appear outside the legend icon border. -*/ - -/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0 - - Returns the coordinate range that all data in this plottable span in the key axis dimension. For - logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref - QCP::sdPositive in order to restrict the returned range to that sign domain. E.g. when only - negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and all positive points - will be ignored for range calculation. For no restriction, just set \a inSignDomain to \ref - QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could - be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data). - - Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by - this function may have size zero (e.g. when there is only one data point). In this case \a - foundRange would return true, but the returned range is not a valid range in terms of \ref - QCPRange::validRange. - - \see rescaleAxes, getValueRange -*/ - -/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0 - - Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span - in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref - QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign - domain. E.g. when only negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and - all positive points will be ignored for range calculation. For no restriction, just set \a - inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates - whether a range could be found or not. If this is false, you shouldn't use the returned range - (e.g. no points in data). - - If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), - all data points are considered, without any restriction on the keys. - - Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by - this function may have size zero (e.g. when there is only one data point). In this case \a - foundRange would return true, but the returned range is not a valid range in terms of \ref - QCPRange::validRange. - - \see rescaleAxes, getKeyRange -*/ - -/* end of documentation of pure virtual functions */ -/* start of documentation of signals */ - -/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) - - This signal is emitted when the selection state of this plottable has changed, either by user - interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether - there are any points selected or not. - - \see selectionChanged(const QCPDataSelection &selection) -*/ - -/*! \fn void QCPAbstractPlottable::selectionChanged(const QCPDataSelection &selection) - - This signal is emitted when the selection state of this plottable has changed, either by user - interaction or by a direct call to \ref setSelection. The parameter \a selection holds the - currently selected data ranges. - - \see selectionChanged(bool selected) -*/ - -/*! \fn void QCPAbstractPlottable::selectableChanged(QCP::SelectionType selectable); - - This signal is emitted when the selectability of this plottable has changed. - - \see setSelectable -*/ - -/* end of documentation of signals */ - -/*! - Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as - its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance - and have perpendicular orientations. If either of these restrictions is violated, a corresponding - message is printed to the debug output (qDebug), the construction is not aborted, though. - - Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, - it can't be directly instantiated. - - You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. -*/ -QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()), - mName(), - mDesc(), - mAntialiasedFill(true), - mAntialiasedScatters(true), - mPen(Qt::black), - mBrush(Qt::NoBrush), - mKeyAxis(keyAxis), - mValueAxis(valueAxis), - mSelectable(QCP::stWhole), - mSelectionDecorator(0) -{ - if (keyAxis->parentPlot() != valueAxis->parentPlot()) - qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; - if (keyAxis->orientation() == valueAxis->orientation()) - qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; - - mParentPlot->registerPlottable(this); - setSelectionDecorator(new QCPSelectionDecorator); -} - -QCPAbstractPlottable::~QCPAbstractPlottable() -{ - if (mSelectionDecorator) - { - delete mSelectionDecorator; - mSelectionDecorator = 0; - } -} - -/*! - The name is the textual representation of this plottable as it is displayed in the legend - (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. -*/ -void QCPAbstractPlottable::setName(const QString &name) -{ - mName = name; -} - -void QCPAbstractPlottable::setDesc(const QString &desc) -{ - mDesc = desc; -} - -/*! - Sets whether fills of this plottable are drawn antialiased or not. - - Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. -*/ -void QCPAbstractPlottable::setAntialiasedFill(bool enabled) -{ - mAntialiasedFill = enabled; -} - -/*! - Sets whether the scatter symbols of this plottable are drawn antialiased or not. - - Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. -*/ -void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) -{ - mAntialiasedScatters = enabled; -} - -/*! - The pen is used to draw basic lines that make up the plottable representation in the - plot. - - For example, the \ref QCPGraph subclass draws its graph lines with this pen. - - \see setBrush -*/ -void QCPAbstractPlottable::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - The brush is used to draw basic fills of the plottable representation in the - plot. The Fill can be a color, gradient or texture, see the usage of QBrush. - - For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when - it's not set to Qt::NoBrush. - - \see setPen -*/ -void QCPAbstractPlottable::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal - to the plottable's value axis. This function performs no checks to make sure this is the case. - The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the - y-axis (QCustomPlot::yAxis) as value axis. - - Normally, the key and value axes are set in the constructor of the plottable (or \ref - QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). - - \see setValueAxis -*/ -void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) -{ - mKeyAxis = axis; -} - -/*! - The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is - orthogonal to the plottable's key axis. This function performs no checks to make sure this is the - case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and - the y-axis (QCustomPlot::yAxis) as value axis. - - Normally, the key and value axes are set in the constructor of the plottable (or \ref - QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). - - \see setKeyAxis -*/ -void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) -{ - mValueAxis = axis; -} - - -/*! - Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently - (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref - selectionDecorator). - - The entire selection mechanism for plottables is handled automatically when \ref - QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when - you wish to change the selection state programmatically. - - Using \ref setSelectable you can further specify for each plottable whether and to which - granularity it is selectable. If \a selection is not compatible with the current \ref - QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted - accordingly (see \ref QCPDataSelection::enforceType). - - emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - - \see setSelectable, selectTest -*/ -void QCPAbstractPlottable::setSelection(QCPDataSelection selection) -{ - selection.enforceType(mSelectable); - if (mSelection != selection) - { - mSelection = selection; - emit selectionChanged(selected()); - emit selectionChanged(mSelection); - } -} - -/*! - Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to - customize the visual representation of selected data ranges further than by using the default - QCPSelectionDecorator. - - The plottable takes ownership of the \a decorator. - - The currently set decorator can be accessed via \ref selectionDecorator. -*/ -void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorator) -{ - if (decorator) - { - if (decorator->registerWithPlottable(this)) - { - if (mSelectionDecorator) // delete old decorator if necessary - delete mSelectionDecorator; - mSelectionDecorator = decorator; - } - } else if (mSelectionDecorator) // just clear decorator - { - delete mSelectionDecorator; - mSelectionDecorator = 0; - } -} - -/*! - Sets whether and to which granularity this plottable can be selected. - - A selection can happen by clicking on the QCustomPlot surface (When \ref - QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect - (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by - calling \ref setSelection. - - \see setSelection, QCP::SelectionType -*/ -void QCPAbstractPlottable::setSelectable(QCP::SelectionType selectable) -{ - if (mSelectable != selectable) - { - mSelectable = selectable; - QCPDataSelection oldSelection = mSelection; - mSelection.enforceType(mSelectable); - emit selectableChanged(mSelectable); - if (mSelection != oldSelection) - { - emit selectionChanged(selected()); - emit selectionChanged(mSelection); - } - } -} - - -/*! - Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, - taking the orientations of the axes associated with this plottable into account (e.g. whether key - represents x or y). - - \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. - - \see pixelsToCoords, QCPAxis::coordToPixel -*/ -void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - if (keyAxis->orientation() == Qt::Horizontal) - { - x = keyAxis->coordToPixel(key); - y = valueAxis->coordToPixel(value); - } else - { - y = keyAxis->coordToPixel(key); - x = valueAxis->coordToPixel(value); - } -} - -/*! \overload - - Transforms the given \a key and \a value to pixel coordinates and returns them in a QPointF. -*/ -const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } - - if (keyAxis->orientation() == Qt::Horizontal) - return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); - else - return QPointF(valueAxis->coordToPixel(value), keyAxis->coordToPixel(key)); -} - -/*! - Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, - taking the orientations of the axes associated with this plottable into account (e.g. whether key - represents x or y). - - \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. - - \see coordsToPixels, QCPAxis::coordToPixel -*/ -void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - if (keyAxis->orientation() == Qt::Horizontal) - { - key = keyAxis->pixelToCoord(x); - value = valueAxis->pixelToCoord(y); - } else - { - key = keyAxis->pixelToCoord(y); - value = valueAxis->pixelToCoord(x); - } -} - -/*! \overload - - Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. -*/ -void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const -{ - pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); -} - -/*! - Rescales the key and value axes associated with this plottable to contain all displayed data, so - the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make - sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. - Instead it will stay in the current sign domain and ignore all parts of the plottable that lie - outside of that domain. - - \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show - multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has - \a onlyEnlarge set to false (the default), and all subsequent set to true. - - \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale -*/ -void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const -{ - rescaleKeyAxis(onlyEnlarge); - rescaleValueAxis(onlyEnlarge); -} - -/*! - Rescales the key axis of the plottable so the whole plottable is visible. - - See \ref rescaleAxes for detailed behaviour. -*/ -void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } - - QCP::SignDomain signDomain = QCP::sdBoth; - if (keyAxis->scaleType() == QCPAxis::stLogarithmic) - signDomain = (keyAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); - - bool foundRange; - QCPRange newRange = getKeyRange(foundRange, signDomain); - if (foundRange) - { - if (onlyEnlarge) - newRange.expand(keyAxis->range()); - if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable - { - double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason - if (keyAxis->scaleType() == QCPAxis::stLinear) - { - newRange.lower = center-keyAxis->range().size()/2.0; - newRange.upper = center+keyAxis->range().size()/2.0; - } else // scaleType() == stLogarithmic - { - newRange.lower = center/qSqrt(keyAxis->range().upper/keyAxis->range().lower); - newRange.upper = center*qSqrt(keyAxis->range().upper/keyAxis->range().lower); - } - } - keyAxis->setRange(newRange); - } -} - -/*! - Rescales the value axis of the plottable so the whole plottable is visible. If \a inKeyRange is - set to true, only the data points which are in the currently visible key axis range are - considered. - - Returns true if the axis was actually scaled. This might not be the case if this plottable has an - invalid range, e.g. because it has no data points. - - See \ref rescaleAxes for detailed behaviour. -*/ -void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - QCP::SignDomain signDomain = QCP::sdBoth; - if (valueAxis->scaleType() == QCPAxis::stLogarithmic) - signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); - - bool foundRange; - QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); - if (foundRange) - { - if (onlyEnlarge) - newRange.expand(valueAxis->range()); - if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable - { - double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason - if (valueAxis->scaleType() == QCPAxis::stLinear) - { - newRange.lower = center-valueAxis->range().size()/2.0; - newRange.upper = center+valueAxis->range().size()/2.0; - } else // scaleType() == stLogarithmic - { - newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); - newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); - } - } - valueAxis->setRange(newRange); - } -} - -/*! \overload - - Adds this plottable to the specified \a legend. - - Creates a QCPPlottableLegendItem which is inserted into the legend. Returns true on success, i.e. - when the legend exists and a legend item associated with this plottable isn't already in the - legend. - - If the plottable needs a more specialized representation in the legend, you can create a - corresponding subclass of \ref QCPPlottableLegendItem and add it to the legend manually instead - of calling this method. - - \see removeFromLegend, QCPLegend::addItem -*/ -bool QCPAbstractPlottable::addToLegend(QCPLegend *legend) -{ - if (!legend) - { - qDebug() << Q_FUNC_INFO << "passed legend is null"; - return false; - } - if (legend->parentPlot() != mParentPlot) - { - qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; - return false; - } - - if (!legend->hasItemWithPlottable(this)) - { - legend->addItem(new QCPPlottableLegendItem(legend, this)); - return true; - } else - return false; -} - -/*! \overload - - Adds this plottable to the legend of the parent QCustomPlot (\ref QCustomPlot::legend). - - \see removeFromLegend -*/ -bool QCPAbstractPlottable::addToLegend() -{ - if (!mParentPlot || !mParentPlot->legend) - return false; - else - return addToLegend(mParentPlot->legend); -} - -/*! \overload - - Removes the plottable from the specifed \a legend. This means the \ref QCPPlottableLegendItem - that is associated with this plottable is removed. - - Returns true on success, i.e. if the legend exists and a legend item associated with this - plottable was found and removed. - - \see addToLegend, QCPLegend::removeItem -*/ -bool QCPAbstractPlottable::removeFromLegend(QCPLegend *legend) const -{ - if (!legend) - { - qDebug() << Q_FUNC_INFO << "passed legend is null"; - return false; - } - - if (QCPPlottableLegendItem *lip = legend->itemWithPlottable(this)) - return legend->removeItem(lip); - else - return false; -} - -/*! \overload - - Removes the plottable from the legend of the parent QCustomPlot. - - \see addToLegend -*/ -bool QCPAbstractPlottable::removeFromLegend() const -{ - if (!mParentPlot || !mParentPlot->legend) - return false; - else - return removeFromLegend(mParentPlot->legend); -} - -/* inherits documentation from base class */ -QRect QCPAbstractPlottable::clipRect() const -{ - if (mKeyAxis && mValueAxis) - return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect(); - else - return QRect(); -} - -/* inherits documentation from base class */ -QCP::Interaction QCPAbstractPlottable::selectionCategory() const -{ - return QCP::iSelectPlottables; -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing plottable lines. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \seebaseclassmethod - - \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint -*/ -void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing plottable fills. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint -*/ -void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing plottable scatter points. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint -*/ -void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); -} - -/* inherits documentation from base class */ -void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - - if (mSelectable != QCP::stNone) - { - QCPDataSelection newSelection = details.value(); - QCPDataSelection selectionBefore = mSelection; - if (additive) - { - if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit - { - if (selected()) - setSelection(QCPDataSelection()); - else - setSelection(newSelection); - } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments - { - if (mSelection.contains(newSelection)) // if entire newSelection is already selected, toggle selection - setSelection(mSelection-newSelection); - else - setSelection(mSelection+newSelection); - } - } else - setSelection(newSelection); - if (selectionStateChanged) - *selectionStateChanged = mSelection != selectionBefore; - } -} - -/* inherits documentation from base class */ -void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) -{ - if (mSelectable != QCP::stNone) - { - QCPDataSelection selectionBefore = mSelection; - setSelection(QCPDataSelection()); - if (selectionStateChanged) - *selectionStateChanged = mSelection != selectionBefore; - } -} -/* end of 'src/plottable.cpp' */ - - -/* including file 'src/item.cpp', size 49269 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemAnchor -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemAnchor - \brief An anchor of an item to which positions can be attached to. - - An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't - control anything on its item, but provides a way to tie other items via their positions to the - anchor. - - For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. - Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can - attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by - calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the - QCPItemRect. This way the start of the line will now always follow the respective anchor location - on the rect item. - - Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an - anchor to other positions. - - To learn how to provide anchors in your own item subclasses, see the subclassing section of the - QCPAbstractItem documentation. -*/ - -/* start documentation of inline functions */ - -/*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() - - Returns 0 if this instance is merely a QCPItemAnchor, and a valid pointer of type QCPItemPosition* if - it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). - - This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids - dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with - gcc compiler). -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if - you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as - explained in the subclassing section of the QCPAbstractItem documentation. -*/ -QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId) : - mName(name), - mParentPlot(parentPlot), - mParentItem(parentItem), - mAnchorId(anchorId) -{ -} - -QCPItemAnchor::~QCPItemAnchor() -{ - // unregister as parent at children: - foreach (QCPItemPosition *child, mChildrenX.toList()) - { - if (child->parentAnchorX() == this) - child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX - } - foreach (QCPItemPosition *child, mChildrenY.toList()) - { - if (child->parentAnchorY() == this) - child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY - } -} - -/*! - Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. - - The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the - parent item, QCPItemAnchor is just an intermediary. -*/ -QPointF QCPItemAnchor::pixelPosition() const -{ - if (mParentItem) - { - if (mAnchorId > -1) - { - return mParentItem->anchorPixelPosition(mAnchorId); - } else - { - qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; - return QPointF(); - } - } else - { - qDebug() << Q_FUNC_INFO << "no parent item set"; - return QPointF(); - } -} - -/*! \internal - - Adds \a pos to the childX list of this anchor, which keeps track of which children use this - anchor as parent anchor for the respective coordinate. This is necessary to notify the children - prior to destruction of the anchor. - - Note that this function does not change the parent setting in \a pos. -*/ -void QCPItemAnchor::addChildX(QCPItemPosition *pos) -{ - if (!mChildrenX.contains(pos)) - mChildrenX.insert(pos); - else - qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); -} - -/*! \internal - - Removes \a pos from the childX list of this anchor. - - Note that this function does not change the parent setting in \a pos. -*/ -void QCPItemAnchor::removeChildX(QCPItemPosition *pos) -{ - if (!mChildrenX.remove(pos)) - qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); -} - -/*! \internal - - Adds \a pos to the childY list of this anchor, which keeps track of which children use this - anchor as parent anchor for the respective coordinate. This is necessary to notify the children - prior to destruction of the anchor. - - Note that this function does not change the parent setting in \a pos. -*/ -void QCPItemAnchor::addChildY(QCPItemPosition *pos) -{ - if (!mChildrenY.contains(pos)) - mChildrenY.insert(pos); - else - qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); -} - -/*! \internal - - Removes \a pos from the childY list of this anchor. - - Note that this function does not change the parent setting in \a pos. -*/ -void QCPItemAnchor::removeChildY(QCPItemPosition *pos) -{ - if (!mChildrenY.remove(pos)) - qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemPosition -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemPosition - \brief Manages the position of an item. - - Every item has at least one public QCPItemPosition member pointer which provides ways to position the - item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: - \a topLeft and \a bottomRight. - - QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type - defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel - coordinates, as plot coordinates of certain axes, etc. For more advanced plots it is also - possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref - setTypeY). This way an item could be positioned at a fixed pixel distance from the top in the Y - direction, while following a plot coordinate in the X direction. - - A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie - multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords) - are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0) - means directly ontop of the parent anchor. For example, You could attach the \a start position of - a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting point of the line - always be centered under the text label, no matter where the text is moved to. For more advanced - plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see - \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X - direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B - in Y. - - Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent - anchor for other positions. - - To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPosition. This - works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref - setPixelPosition transforms the coordinates appropriately, to make the position appear at the specified - pixel values. -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const - - Returns the current position type. - - If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the - type of the X coordinate. In that case rather use \a typeX() and \a typeY(). - - \see setType -*/ - -/*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const - - Returns the current parent anchor. - - If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), - this method returns the parent anchor of the Y coordinate. In that case rather use \a - parentAnchorX() and \a parentAnchorY(). - - \see setParentAnchor -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if - you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as - explained in the subclassing section of the QCPAbstractItem documentation. -*/ -QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name) : - QCPItemAnchor(parentPlot, parentItem, name), - mPositionTypeX(ptAbsolute), - mPositionTypeY(ptAbsolute), - mKey(0), - mValue(0), - mParentAnchorX(0), - mParentAnchorY(0) -{ -} - -QCPItemPosition::~QCPItemPosition() -{ - // unregister as parent at children: - // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then - // the setParentAnchor(0) call the correct QCPItemPosition::pixelPosition function instead of QCPItemAnchor::pixelPosition - foreach (QCPItemPosition *child, mChildrenX.toList()) - { - if (child->parentAnchorX() == this) - child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX - } - foreach (QCPItemPosition *child, mChildrenY.toList()) - { - if (child->parentAnchorY() == this) - child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY - } - // unregister as child in parent: - if (mParentAnchorX) - mParentAnchorX->removeChildX(this); - if (mParentAnchorY) - mParentAnchorY->removeChildY(this); -} - -/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ -QCPAxisRect *QCPItemPosition::axisRect() const -{ - return mAxisRect.data(); -} - -/*! - Sets the type of the position. The type defines how the coordinates passed to \ref setCoords - should be handled and how the QCPItemPosition should behave in the plot. - - The possible values for \a type can be separated in two main categories: - - \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords - and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. - By default, the QCustomPlot's x- and yAxis are used. - - \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This - corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref - ptAxisRectRatio. They differ only in the way the absolute position is described, see the - documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify - the axis rect with \ref setAxisRect. By default this is set to the main axis rect. - - Note that the position type \ref ptPlotCoords is only available (and sensible) when the position - has no parent anchor (\ref setParentAnchor). - - If the type is changed, the apparent pixel position on the plot is preserved. This means - the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. - - This method sets the type for both X and Y directions. It is also possible to set different types - for X and Y, see \ref setTypeX, \ref setTypeY. -*/ -void QCPItemPosition::setType(QCPItemPosition::PositionType type) -{ - setTypeX(type); - setTypeY(type); -} - -/*! - This method sets the position type of the X coordinate to \a type. - - For a detailed description of what a position type is, see the documentation of \ref setType. - - \see setType, setTypeY -*/ -void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) -{ - if (mPositionTypeX != type) - { - // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect - // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. - bool retainPixelPosition = true; - if ((mPositionTypeX == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) - retainPixelPosition = false; - if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) - retainPixelPosition = false; - - QPointF pixel; - if (retainPixelPosition) - pixel = pixelPosition(); - - mPositionTypeX = type; - - if (retainPixelPosition) - setPixelPosition(pixel); - } -} - -/*! - This method sets the position type of the Y coordinate to \a type. - - For a detailed description of what a position type is, see the documentation of \ref setType. - - \see setType, setTypeX -*/ -void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) -{ - if (mPositionTypeY != type) - { - // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect - // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. - bool retainPixelPosition = true; - if ((mPositionTypeY == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) - retainPixelPosition = false; - if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) - retainPixelPosition = false; - - QPointF pixel; - if (retainPixelPosition) - pixel = pixelPosition(); - - mPositionTypeY = type; - - if (retainPixelPosition) - setPixelPosition(pixel); - } -} - -/*! - Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now - follow any position changes of the anchor. The local coordinate system of positions with a parent - anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence - the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) - - if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved - during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position - will be exactly on top of the parent anchor. - - To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to 0. - - If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is - set to \ref ptAbsolute, to keep the position in a valid state. - - This method sets the parent anchor for both X and Y directions. It is also possible to set - different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. -*/ -bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) -{ - bool successX = setParentAnchorX(parentAnchor, keepPixelPosition); - bool successY = setParentAnchorY(parentAnchor, keepPixelPosition); - return successX && successY; -} - -/*! - This method sets the parent anchor of the X coordinate to \a parentAnchor. - - For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. - - \see setParentAnchor, setParentAnchorY -*/ -bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) -{ - // make sure self is not assigned as parent: - if (parentAnchor == this) - { - qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); - return false; - } - // make sure no recursive parent-child-relationships are created: - QCPItemAnchor *currentParent = parentAnchor; - while (currentParent) - { - if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) - { - // is a QCPItemPosition, might have further parent, so keep iterating - if (currentParentPos == this) - { - qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); - return false; - } - currentParent = currentParentPos->parentAnchorX(); - } else - { - // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the - // same, to prevent a position being child of an anchor which itself depends on the position, - // because they're both on the same item: - if (currentParent->mParentItem == mParentItem) - { - qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); - return false; - } - break; - } - } - - // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: - if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) - setTypeX(ptAbsolute); - - // save pixel position: - QPointF pixelP; - if (keepPixelPosition) - pixelP = pixelPosition(); - // unregister at current parent anchor: - if (mParentAnchorX) - mParentAnchorX->removeChildX(this); - // register at new parent anchor: - if (parentAnchor) - parentAnchor->addChildX(this); - mParentAnchorX = parentAnchor; - // restore pixel position under new parent: - if (keepPixelPosition) - setPixelPosition(pixelP); - else - setCoords(0, coords().y()); - return true; -} - -/*! - This method sets the parent anchor of the Y coordinate to \a parentAnchor. - - For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. - - \see setParentAnchor, setParentAnchorX -*/ -bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) -{ - // make sure self is not assigned as parent: - if (parentAnchor == this) - { - qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); - return false; - } - // make sure no recursive parent-child-relationships are created: - QCPItemAnchor *currentParent = parentAnchor; - while (currentParent) - { - if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) - { - // is a QCPItemPosition, might have further parent, so keep iterating - if (currentParentPos == this) - { - qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); - return false; - } - currentParent = currentParentPos->parentAnchorY(); - } else - { - // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the - // same, to prevent a position being child of an anchor which itself depends on the position, - // because they're both on the same item: - if (currentParent->mParentItem == mParentItem) - { - qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); - return false; - } - break; - } - } - - // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: - if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) - setTypeY(ptAbsolute); - - // save pixel position: - QPointF pixelP; - if (keepPixelPosition) - pixelP = pixelPosition(); - // unregister at current parent anchor: - if (mParentAnchorY) - mParentAnchorY->removeChildY(this); - // register at new parent anchor: - if (parentAnchor) - parentAnchor->addChildY(this); - mParentAnchorY = parentAnchor; - // restore pixel position under new parent: - if (keepPixelPosition) - setPixelPosition(pixelP); - else - setCoords(coords().x(), 0); - return true; -} - -/*! - Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type - (\ref setType, \ref setTypeX, \ref setTypeY). - - For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position - on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the - QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the - plot coordinate system defined by the axes set by \ref setAxes. By default those are the - QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available - coordinate types and their meaning. - - If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a - value must also be provided in the different coordinate systems. Here, the X type refers to \a - key, and the Y type refers to \a value. - - \see setPixelPosition -*/ -void QCPItemPosition::setCoords(double key, double value) -{ - mKey = key; - mValue = value; -} - -/*! \overload - - Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the - meaning of \a value of the \ref setCoords(double key, double value) method. -*/ -void QCPItemPosition::setCoords(const QPointF &pos) -{ - setCoords(pos.x(), pos.y()); -} - -/*! - Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It - includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). - - \see setPixelPosition -*/ -QPointF QCPItemPosition::pixelPosition() const -{ - QPointF result; - - // determine X: - switch (mPositionTypeX) - { - case ptAbsolute: - { - result.rx() = mKey; - if (mParentAnchorX) - result.rx() += mParentAnchorX->pixelPosition().x(); - break; - } - case ptViewportRatio: - { - result.rx() = mKey*mParentPlot->viewport().width(); - if (mParentAnchorX) - result.rx() += mParentAnchorX->pixelPosition().x(); - else - result.rx() += mParentPlot->viewport().left(); - break; - } - case ptAxisRectRatio: - { - if (mAxisRect) - { - result.rx() = mKey*mAxisRect.data()->width(); - if (mParentAnchorX) - result.rx() += mParentAnchorX->pixelPosition().x(); - else - result.rx() += mAxisRect.data()->left(); - } else - qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; - break; - } - case ptPlotCoords: - { - if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) - result.rx() = mKeyAxis.data()->coordToPixel(mKey); - else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) - result.rx() = mValueAxis.data()->coordToPixel(mValue); - else - qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; - break; - } - } - - // determine Y: - switch (mPositionTypeY) - { - case ptAbsolute: - { - result.ry() = mValue; - if (mParentAnchorY) - result.ry() += mParentAnchorY->pixelPosition().y(); - break; - } - case ptViewportRatio: - { - result.ry() = mValue*mParentPlot->viewport().height(); - if (mParentAnchorY) - result.ry() += mParentAnchorY->pixelPosition().y(); - else - result.ry() += mParentPlot->viewport().top(); - break; - } - case ptAxisRectRatio: - { - if (mAxisRect) - { - result.ry() = mValue*mAxisRect.data()->height(); - if (mParentAnchorY) - result.ry() += mParentAnchorY->pixelPosition().y(); - else - result.ry() += mAxisRect.data()->top(); - } else - qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; - break; - } - case ptPlotCoords: - { - if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) - result.ry() = mKeyAxis.data()->coordToPixel(mKey); - else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) - result.ry() = mValueAxis.data()->coordToPixel(mValue); - else - qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; - break; - } - } - - return result; -} - -/*! - When \ref setType is \ref ptPlotCoords, this function may be used to specify the axes the - coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and - yAxis of the QCustomPlot. -*/ -void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) -{ - mKeyAxis = keyAxis; - mValueAxis = valueAxis; -} - -/*! - When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the - coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of - the QCustomPlot. -*/ -void QCPItemPosition::setAxisRect(QCPAxisRect *axisRect) -{ - mAxisRect = axisRect; -} - -/*! - Sets the apparent pixel position. This works no matter what type (\ref setType) this - QCPItemPosition is or what parent-child situation it is in, as coordinates are transformed - appropriately, to make the position finally appear at the specified pixel values. - - Only if the type is \ref ptAbsolute and no parent anchor is set, this function's effect is - identical to that of \ref setCoords. - - \see pixelPosition, setCoords -*/ -void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) -{ - double x = pixelPosition.x(); - double y = pixelPosition.y(); - - switch (mPositionTypeX) - { - case ptAbsolute: - { - if (mParentAnchorX) - x -= mParentAnchorX->pixelPosition().x(); - break; - } - case ptViewportRatio: - { - if (mParentAnchorX) - x -= mParentAnchorX->pixelPosition().x(); - else - x -= mParentPlot->viewport().left(); - x /= (double)mParentPlot->viewport().width(); - break; - } - case ptAxisRectRatio: - { - if (mAxisRect) - { - if (mParentAnchorX) - x -= mParentAnchorX->pixelPosition().x(); - else - x -= mAxisRect.data()->left(); - x /= (double)mAxisRect.data()->width(); - } else - qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; - break; - } - case ptPlotCoords: - { - if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) - x = mKeyAxis.data()->pixelToCoord(x); - else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) - y = mValueAxis.data()->pixelToCoord(x); - else - qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; - break; - } - } - - switch (mPositionTypeY) - { - case ptAbsolute: - { - if (mParentAnchorY) - y -= mParentAnchorY->pixelPosition().y(); - break; - } - case ptViewportRatio: - { - if (mParentAnchorY) - y -= mParentAnchorY->pixelPosition().y(); - else - y -= mParentPlot->viewport().top(); - y /= (double)mParentPlot->viewport().height(); - break; - } - case ptAxisRectRatio: - { - if (mAxisRect) - { - if (mParentAnchorY) - y -= mParentAnchorY->pixelPosition().y(); - else - y -= mAxisRect.data()->top(); - y /= (double)mAxisRect.data()->height(); - } else - qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; - break; - } - case ptPlotCoords: - { - if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) - x = mKeyAxis.data()->pixelToCoord(y); - else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) - y = mValueAxis.data()->pixelToCoord(y); - else - qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; - break; - } - } - - setCoords(x, y); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractItem -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractItem - \brief The abstract base class for all items in a plot. - - In QCustomPlot, items are supplemental graphical elements that are neither plottables - (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus - plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each - specific item has at least one QCPItemPosition member which controls the positioning. Some items - are defined by more than one coordinate and thus have two or more QCPItemPosition members (For - example, QCPItemRect has \a topLeft and \a bottomRight). - - This abstract base class defines a very basic interface like visibility and clipping. Since this - class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass - yourself to create new items. - - The built-in items are: - - - - - - - - - - -
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
- - \section items-clipping Clipping - - Items are by default clipped to the main axis rect (they are only visible inside the axis rect). - To make an item visible outside that axis rect, disable clipping via \ref setClipToAxisRect - "setClipToAxisRect(false)". - - On the other hand if you want the item to be clipped to a different axis rect, specify it via - \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and - in principle is independent of the coordinate axes the item might be tied to via its position - members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping - also contains the axes used for the item positions. - - \section items-using Using items - - First you instantiate the item you want to use and add it to the plot: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 - by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just - set the plot coordinates where the line should start/end: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-2 - If we don't want the line to be positioned in plot coordinates but a different coordinate system, - e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-3 - Then we can set the coordinates, this time in pixels: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 - and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 - - For more advanced plots, it is even possible to set different types and parent anchors per X/Y - coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref - QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. - - \section items-subclassing Creating own items - - To create an own item, you implement a subclass of QCPAbstractItem. These are the pure - virtual functions, you must implement: - \li \ref selectTest - \li \ref draw - - See the documentation of those functions for what they need to do. - - \subsection items-positioning Allowing the item to be positioned - - As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall - have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add - a public member of type QCPItemPosition like so: - - \code QCPItemPosition * const myPosition;\endcode - - the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition - instance it points to, can be modified, of course). - The initialization of this pointer is made easy with the \ref createPosition function. Just assign - the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition - takes a string which is the name of the position, typically this is identical to the variable name. - For example, the constructor of QCPItemExample could look like this: - - \code - QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - myPosition(createPosition("myPosition")) - { - // other constructor code - } - \endcode - - \subsection items-drawing The draw function - - To give your item a visual representation, reimplement the \ref draw function and use the passed - QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the - position member(s) via \ref QCPItemPosition::pixelPosition. - - To optimize performance you should calculate a bounding rect first (don't forget to take the pen - width into account), check whether it intersects the \ref clipRect, and only draw the item at all - if this is the case. - - \subsection items-selection The selectTest function - - Your implementation of the \ref selectTest function may use the helpers \ref - QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the - selection test becomes significantly simpler for most items. See the documentation of \ref - selectTest for what the function parameters mean and what the function should return. - - \subsection anchors Providing anchors - - Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public - member, e.g. - - \code QCPItemAnchor * const bottom;\endcode - - and create it in the constructor with the \ref createAnchor function, assigning it a name and an - anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). - Since anchors can be placed anywhere, relative to the item's position(s), your item needs to - provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int - anchorId) function. - - In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel - position when anything attached to the anchor needs to know the coordinates. -*/ - -/* start of documentation of inline functions */ - -/*! \fn QList QCPAbstractItem::positions() const - - Returns all positions of the item in a list. - - \see anchors, position -*/ - -/*! \fn QList QCPAbstractItem::anchors() const - - Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always - also an anchor, the list will also contain the positions of this item. - - \see positions, anchor -*/ - -/* end of documentation of inline functions */ -/* start documentation of pure virtual functions */ - -/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 - \internal - - Draws this item with the provided \a painter. - - The cliprect of the provided painter is set to the rect returned by \ref clipRect before this - function is called. The clipRect depends on the clipping settings defined by \ref - setClipToAxisRect and \ref setClipAxisRect. -*/ - -/* end documentation of pure virtual functions */ -/* start documentation of signals */ - -/*! \fn void QCPAbstractItem::selectionChanged(bool selected) - This signal is emitted when the selection state of this item has changed, either by user interaction - or by a direct call to \ref setSelected. -*/ - -/* end documentation of signals */ - -/*! - Base class constructor which initializes base class members. -*/ -QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : - QCPLayerable(parentPlot), - mClipToAxisRect(false), - mSelectable(true), - mSelected(false) -{ - parentPlot->registerItem(this); - - QList rects = parentPlot->axisRects(); - if (rects.size() > 0) - { - setClipToAxisRect(true); - setClipAxisRect(rects.first()); - } -} - -QCPAbstractItem::~QCPAbstractItem() -{ - // don't delete mPositions because every position is also an anchor and thus in mAnchors - qDeleteAll(mAnchors); -} - -/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ -QCPAxisRect *QCPAbstractItem::clipAxisRect() const -{ - return mClipAxisRect.data(); -} - -/*! - Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the - entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. - - \see setClipAxisRect -*/ -void QCPAbstractItem::setClipToAxisRect(bool clip) -{ - mClipToAxisRect = clip; - if (mClipToAxisRect) - setParentLayerable(mClipAxisRect.data()); -} - -/*! - Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref - setClipToAxisRect is set to true. - - \see setClipToAxisRect -*/ -void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) -{ - mClipAxisRect = rect; - if (mClipToAxisRect) - setParentLayerable(mClipAxisRect.data()); -} - -/*! - Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. - (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) - - However, even when \a selectable was set to false, it is possible to set the selection manually, - by calling \ref setSelected. - - \see QCustomPlot::setInteractions, setSelected -*/ -void QCPAbstractItem::setSelectable(bool selectable) -{ - if (mSelectable != selectable) - { - mSelectable = selectable; - emit selectableChanged(mSelectable); - } -} - -/*! - Sets whether this item is selected or not. When selected, it might use a different visual - appearance (e.g. pen and brush), this depends on the specific item though. - - The entire selection mechanism for items is handled automatically when \ref - QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this - function when you wish to change the selection state manually. - - This function can change the selection state even when \ref setSelectable was set to false. - - emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - - \see setSelectable, selectTest -*/ -void QCPAbstractItem::setSelected(bool selected) -{ - if (mSelected != selected) - { - mSelected = selected; - emit selectionChanged(mSelected); - } -} - -/*! - Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by - that name, returns 0. - - This function provides an alternative way to access item positions. Normally, you access - positions direcly by their member pointers (which typically have the same variable name as \a - name). - - \see positions, anchor -*/ -QCPItemPosition *QCPAbstractItem::position(const QString &name) const -{ - for (int i=0; iname() == name) - return mPositions.at(i); - } - qDebug() << Q_FUNC_INFO << "position with name not found:" << name; - return 0; -} - -/*! - Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by - that name, returns 0. - - This function provides an alternative way to access item anchors. Normally, you access - anchors direcly by their member pointers (which typically have the same variable name as \a - name). - - \see anchors, position -*/ -QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const -{ - for (int i=0; iname() == name) - return mAnchors.at(i); - } - qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; - return 0; -} - -/*! - Returns whether this item has an anchor with the specified \a name. - - Note that you can check for positions with this function, too. This is because every position is - also an anchor (QCPItemPosition inherits from QCPItemAnchor). - - \see anchor, position -*/ -bool QCPAbstractItem::hasAnchor(const QString &name) const -{ - for (int i=0; iname() == name) - return true; - } - return false; -} - -/*! \internal - - Returns the rect the visual representation of this item is clipped to. This depends on the - current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. - - If the item is not clipped to an axis rect, QCustomPlot's viewport rect is returned. - - \see draw -*/ -QRect QCPAbstractItem::clipRect() const -{ - if (mClipToAxisRect && mClipAxisRect) - return mClipAxisRect.data()->rect(); - else - return mParentPlot->viewport(); -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing item lines. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \see setAntialiased -*/ -void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); -} - -/*! \internal - - A convenience function which returns the selectTest value for a specified \a rect and a specified - click position \a pos. \a filledRect defines whether a click inside the rect should also be - considered a hit or whether only the rect border is sensitive to hits. - - This function may be used to help with the implementation of the \ref selectTest function for - specific items. - - For example, if your item consists of four rects, call this function four times, once for each - rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four - returned values. -*/ -double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const -{ - double result = -1; - - // distance to border: - QList lines; - lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) - << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); - double minDistSqr = std::numeric_limits::max(); - for (int i=0; i mParentPlot->selectionTolerance()*0.99) - { - if (rect.contains(pos)) - result = mParentPlot->selectionTolerance()*0.99; - } - return result; -} - -/*! \internal - - Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in - item subclasses if they want to provide anchors (QCPItemAnchor). - - For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor - ids and returns the respective pixel points of the specified anchor. - - \see createAnchor -*/ -QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const -{ - qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified - \a name must be a unique string that is usually identical to the variable name of the position - member (This is needed to provide the name-based \ref position access to positions). - - Don't delete positions created by this function manually, as the item will take care of it. - - Use this function in the constructor (initialization list) of the specific item subclass to - create each position member. Don't create QCPItemPositions with \b new yourself, because they - won't be registered with the item properly. - - \see createAnchor -*/ -QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) -{ - if (hasAnchor(name)) - qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; - QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); - mPositions.append(newPosition); - mAnchors.append(newPosition); // every position is also an anchor - newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); - newPosition->setType(QCPItemPosition::ptPlotCoords); - if (mParentPlot->axisRect()) - newPosition->setAxisRect(mParentPlot->axisRect()); - newPosition->setCoords(0, 0); - return newPosition; -} - -/*! \internal - - Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified - \a name must be a unique string that is usually identical to the variable name of the anchor - member (This is needed to provide the name based \ref anchor access to anchors). - - The \a anchorId must be a number identifying the created anchor. It is recommended to create an - enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor - to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns - the correct pixel coordinates for the passed anchor id. - - Don't delete anchors created by this function manually, as the item will take care of it. - - Use this function in the constructor (initialization list) of the specific item subclass to - create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they - won't be registered with the item properly. - - \see createPosition -*/ -QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) -{ - if (hasAnchor(name)) - qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; - QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); - mAnchors.append(newAnchor); - return newAnchor; -} - -/* inherits documentation from base class */ -void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - Q_UNUSED(details) - if (mSelectable) - { - bool selBefore = mSelected; - setSelected(additive ? !mSelected : true); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPAbstractItem::deselectEvent(bool *selectionStateChanged) -{ - if (mSelectable) - { - bool selBefore = mSelected; - setSelected(false); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/* inherits documentation from base class */ -QCP::Interaction QCPAbstractItem::selectionCategory() const -{ - return QCP::iSelectItems; -} -/* end of 'src/item.cpp' */ - - -/* including file 'src/core.cpp', size 125037 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCustomPlot -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCustomPlot - - \brief The central class of the library. This is the QWidget which displays the plot and - interacts with the user. - - For tutorials on how to use QCustomPlot, see the website\n - http://www.qcustomplot.com/ -*/ - -/* start of documentation of inline functions */ - -/*! \fn QCPSelectionRect *QCustomPlot::selectionRect() const - - Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used - to handle and draw selection rect interactions (see \ref setSelectionRectMode). - - \see setSelectionRect -*/ - -/*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const - - Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just - one cell with the main QCPAxisRect inside. -*/ - -/* end of documentation of inline functions */ -/* start of documentation of signals */ - -/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse double click event. -*/ - -/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse press event. - - It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot - connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref - QCPAxisRect::setRangeDragAxes. -*/ - -/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse move event. - - It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot - connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref - QCPAxisRect::setRangeDragAxes. - - \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, - because the dragging starting point was saved the moment the mouse was pressed. Thus it only has - a meaning for the range drag axes that were set at that moment. If you want to change the drag - axes, consider doing this in the \ref mousePress signal instead. -*/ - -/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse release event. - - It is emitted before QCustomPlot handles any other mechanisms like object selection. So a - slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or - \ref QCPAbstractPlottable::setSelectable. -*/ - -/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse wheel event. - - It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot - connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref - QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. -*/ - -/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) - - This signal is emitted when a plottable is clicked. - - \a event is the mouse event that caused the click and \a plottable is the plottable that received - the click. The parameter \a dataIndex indicates the data point that was closest to the click - position. - - \see plottableDoubleClick -*/ - -/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) - - This signal is emitted when a plottable is double clicked. - - \a event is the mouse event that caused the click and \a plottable is the plottable that received - the click. The parameter \a dataIndex indicates the data point that was closest to the click - position. - - \see plottableClick -*/ - -/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) - - This signal is emitted when an item is clicked. - - \a event is the mouse event that caused the click and \a item is the item that received the - click. - - \see itemDoubleClick -*/ - -/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) - - This signal is emitted when an item is double clicked. - - \a event is the mouse event that caused the click and \a item is the item that received the - click. - - \see itemClick -*/ - -/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) - - This signal is emitted when an axis is clicked. - - \a event is the mouse event that caused the click, \a axis is the axis that received the click and - \a part indicates the part of the axis that was clicked. - - \see axisDoubleClick -*/ - -/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) - - This signal is emitted when an axis is double clicked. - - \a event is the mouse event that caused the click, \a axis is the axis that received the click and - \a part indicates the part of the axis that was clicked. - - \see axisClick -*/ - -/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) - - This signal is emitted when a legend (item) is clicked. - - \a event is the mouse event that caused the click, \a legend is the legend that received the - click and \a item is the legend item that received the click. If only the legend and no item is - clicked, \a item is 0. This happens for a click inside the legend padding or the space between - two items. - - \see legendDoubleClick -*/ - -/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) - - This signal is emitted when a legend (item) is double clicked. - - \a event is the mouse event that caused the click, \a legend is the legend that received the - click and \a item is the legend item that received the click. If only the legend and no item is - clicked, \a item is 0. This happens for a click inside the legend padding or the space between - two items. - - \see legendClick -*/ - -/*! \fn void QCustomPlot::selectionChangedByUser() - - This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by - clicking. It is not emitted when the selection state of an object has changed programmatically by - a direct call to setSelected()/setSelection() on an object or by calling \ref - deselectAll. - - In addition to this signal, selectable objects also provide individual signals, for example \ref - QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals - are emitted even if the selection state is changed programmatically. - - See the documentation of \ref setInteractions for details about the selection mechanism. - - \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends -*/ - -/*! \fn void QCustomPlot::beforeReplot() - - This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref - replot). - - It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them - replot synchronously, it won't cause an infinite recursion. - - \see replot, afterReplot -*/ - -/*! \fn void QCustomPlot::afterReplot() - - This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref - replot). - - It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them - replot synchronously, it won't cause an infinite recursion. - - \see replot, beforeReplot -*/ - -/* end of documentation of signals */ -/* start of documentation of public members */ - -/*! \var QCPAxis *QCustomPlot::xAxis - - A pointer to the primary x Axis (bottom) of the main axis rect of the plot. - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref - QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the - default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointers become 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/*! \var QCPAxis *QCustomPlot::yAxis - - A pointer to the primary y Axis (left) of the main axis rect of the plot. - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref - QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the - default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointers become 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/*! \var QCPAxis *QCustomPlot::xAxis2 - - A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are - invisible by default. Use QCPAxis::setVisible to change this (or use \ref - QCPAxisRect::setupFullAxesBox). - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref - QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the - default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointers become 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/*! \var QCPAxis *QCustomPlot::yAxis2 - - A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are - invisible by default. Use QCPAxis::setVisible to change this (or use \ref - QCPAxisRect::setupFullAxesBox). - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref - QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the - default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointers become 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/*! \var QCPLegend *QCustomPlot::legend - - A pointer to the default legend of the main axis rect. The legend is invisible by default. Use - QCPLegend::setVisible to change this. - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple legends to the plot, use the layout system interface to - access the new legend. For example, legends can be placed inside an axis rect's \ref - QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If - the default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointer becomes 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/* end of documentation of public members */ - -/*! - Constructs a QCustomPlot and sets reasonable default values. -*/ -QCustomPlot::QCustomPlot(QWidget *parent) : - QWidget(parent), - xAxis(0), - yAxis(0), - xAxis2(0), - yAxis2(0), - legend(0), - mBufferDevicePixelRatio(1.0), // will be adapted to primary screen below - mPlotLayout(0), - mAutoAddPlottableToLegend(true), - mAntialiasedElements(QCP::aeNone), - mNotAntialiasedElements(QCP::aeNone), - mInteractions(0), - mSelectionTolerance(8), - mNoAntialiasingOnDrag(false), - mBackgroundBrush(Qt::white, Qt::SolidPattern), - mBackgroundScaled(true), - mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), - mCurrentLayer(0), - mPlottingHints(QCP::phCacheLabels|QCP::phImmediateRefresh), - mMultiSelectModifier(Qt::ControlModifier), - mSelectionRectMode(QCP::srmNone), - mSelectionRect(0), - mOpenGl(false), - mSymbolPressed(false), - mMouseHasMoved(false), - mMouseEventLayerable(0), - mMouseSignalLayerable(0), - mReplotting(false), - mReplotQueued(false), - mOpenGlMultisamples(16), - mOpenGlAntialiasedElementsBackup(QCP::aeNone), - mOpenGlCacheLabelsBackup(true) -{ - setAttribute(Qt::WA_NoMousePropagation); - setAttribute(Qt::WA_OpaquePaintEvent); - setFocusPolicy(Qt::ClickFocus); - setMouseTracking(true); - QLocale currentLocale = locale(); - currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); - setLocale(currentLocale); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED -# ifdef QCP_DEVICEPIXELRATIO_FLOAT - setBufferDevicePixelRatio(QWidget::devicePixelRatioF()); -# else - setBufferDevicePixelRatio(QWidget::devicePixelRatio()); -# endif -#endif - - mOpenGlAntialiasedElementsBackup = mAntialiasedElements; - mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); - // create initial layers: - mLayers.append(new QCPLayer(this, QLatin1String("background"))); - mLayers.append(new QCPLayer(this, QLatin1String("grid"))); - mLayers.append(new QCPLayer(this, QLatin1String("main"))); - mLayers.append(new QCPLayer(this, QLatin1String("axes"))); - mLayers.append(new QCPLayer(this, QLatin1String("legend"))); - mLayers.append(new QCPLayer(this, QLatin1String("overlay"))); - updateLayerIndices(); - setCurrentLayer(QLatin1String("main")); - layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered); - - // create initial layout, axis rect and legend: - mPlotLayout = new QCPLayoutGrid; - mPlotLayout->initializeParentPlot(this); - mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry - mPlotLayout->setLayer(QLatin1String("main")); - QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true); - mPlotLayout->addElement(0, 0, defaultAxisRect); - xAxis = defaultAxisRect->axis(QCPAxis::atBottom); - yAxis = defaultAxisRect->axis(QCPAxis::atLeft); - xAxis2 = defaultAxisRect->axis(QCPAxis::atTop); - yAxis2 = defaultAxisRect->axis(QCPAxis::atRight); - legend = new QCPLegend; - legend->setVisible(false); - defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); - defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); - - defaultAxisRect->setLayer(QLatin1String("background")); - xAxis->setLayer(QLatin1String("axes")); - yAxis->setLayer(QLatin1String("axes")); - xAxis2->setLayer(QLatin1String("axes")); - yAxis2->setLayer(QLatin1String("axes")); - xAxis->grid()->setLayer(QLatin1String("grid")); - yAxis->grid()->setLayer(QLatin1String("grid")); - xAxis2->grid()->setLayer(QLatin1String("grid")); - yAxis2->grid()->setLayer(QLatin1String("grid")); - legend->setLayer(QLatin1String("legend")); - - // create selection rect instance: - mSelectionRect = new QCPSelectionRect(this); - mSelectionRect->setLayer(QLatin1String("overlay")); - - setViewport(rect()); // needs to be called after mPlotLayout has been created - - replot(rpQueuedReplot); -} - -QCustomPlot::~QCustomPlot() -{ - clearPlottables(); - clearItems(true); - - if (mPlotLayout) - { - delete mPlotLayout; - mPlotLayout = 0; - } - - mCurrentLayer = 0; - qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed - mLayers.clear(); -} - -void QCustomPlot::setSymbolPos(const QPoint pos) -{ - mSymbolPos = QPoint(pos.x(), 0); -} - -/*! - Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. - - This overrides the antialiasing settings for whole element groups, normally controlled with the - \a setAntialiasing function on the individual elements. If an element is neither specified in - \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on - each individual element instance is used. - - For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be - drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set - to. - - if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is - removed from there. - - \see setNotAntialiasedElements -*/ -void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) -{ - mAntialiasedElements = antialiasedElements; - - // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: - if ((mNotAntialiasedElements & mAntialiasedElements) != 0) - mNotAntialiasedElements |= ~mAntialiasedElements; -} - -/*! - Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. - - See \ref setAntialiasedElements for details. - - \see setNotAntialiasedElement -*/ -void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) -{ - if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) - mAntialiasedElements &= ~antialiasedElement; - else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) - mAntialiasedElements |= antialiasedElement; - - // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: - if ((mNotAntialiasedElements & mAntialiasedElements) != 0) - mNotAntialiasedElements |= ~mAntialiasedElements; -} - -/*! - Sets which elements are forcibly drawn not antialiased as an \a or combination of - QCP::AntialiasedElement. - - This overrides the antialiasing settings for whole element groups, normally controlled with the - \a setAntialiasing function on the individual elements. If an element is neither specified in - \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on - each individual element instance is used. - - For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be - drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set - to. - - if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is - removed from there. - - \see setAntialiasedElements -*/ -void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) -{ - mNotAntialiasedElements = notAntialiasedElements; - - // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: - if ((mNotAntialiasedElements & mAntialiasedElements) != 0) - mAntialiasedElements |= ~mNotAntialiasedElements; -} - -/*! - Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. - - See \ref setNotAntialiasedElements for details. - - \see setAntialiasedElement -*/ -void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) -{ - if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) - mNotAntialiasedElements &= ~notAntialiasedElement; - else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) - mNotAntialiasedElements |= notAntialiasedElement; - - // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: - if ((mNotAntialiasedElements & mAntialiasedElements) != 0) - mAntialiasedElements |= ~mNotAntialiasedElements; -} - -/*! - If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the - plottable to the legend (QCustomPlot::legend). - - \see addGraph, QCPLegend::addItem -*/ -void QCustomPlot::setAutoAddPlottableToLegend(bool on) -{ - mAutoAddPlottableToLegend = on; -} - -/*! - Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction - enums. There are the following types of interactions: - - Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the - respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. - For details how to control which axes the user may drag/zoom and in what orientations, see \ref - QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, - \ref QCPAxisRect::setRangeZoomAxes. - - Plottable data selection is controlled by \ref QCP::iSelectPlottables. If \ref - QCP::iSelectPlottables is set, the user may select plottables (graphs, curves, bars,...) and - their data by clicking on them or in their vicinity (\ref setSelectionTolerance). Whether the - user can actually select a plottable and its data can further be restricted with the \ref - QCPAbstractPlottable::setSelectable method on the specific plottable. For details, see the - special page about the \ref dataselection "data selection mechanism". To retrieve a list of all - currently selected plottables, call \ref selectedPlottables. If you're only interested in - QCPGraphs, you may use the convenience function \ref selectedGraphs. - - Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user - may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find - out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of - all currently selected items, call \ref selectedItems. - - Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user - may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick - labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for - each axis. To retrieve a list of all axes that currently contain selected parts, call \ref - selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). - - Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may - select the legend itself or individual items by clicking on them. What parts exactly are - selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the - legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To - find out which child items are selected, call \ref QCPLegend::selectedItems. - - All other selectable elements The selection of all other selectable objects (e.g. - QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the - user may select those objects by clicking on them. To find out which are currently selected, you - need to check their selected state explicitly. - - If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is - emitted. Each selectable object additionally emits an individual selectionChanged signal whenever - their selection state has changed, i.e. not only by user interaction. - - To allow multiple objects to be selected by holding the selection modifier (\ref - setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. - - \note In addition to the selection mechanism presented here, QCustomPlot always emits - corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and - \ref plottableDoubleClick for example. - - \see setInteraction, setSelectionTolerance -*/ -void QCustomPlot::setInteractions(const QCP::Interactions &interactions) -{ - mInteractions = interactions; -} - -/*! - Sets the single \a interaction of this QCustomPlot to \a enabled. - - For details about the interaction system, see \ref setInteractions. - - \see setInteractions -*/ -void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) -{ - if (!enabled && mInteractions.testFlag(interaction)) - mInteractions &= ~interaction; - else if (enabled && !mInteractions.testFlag(interaction)) - mInteractions |= interaction; -} - -/*! - Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or - not. - - If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a - potential selection when the minimum distance between the click position and the graph line is - smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks - directly inside the area and ignore this selection tolerance. In other words, it only has meaning - for parts of objects that are too thin to exactly hit with a click and thus need such a - tolerance. - - \see setInteractions, QCPLayerable::selectTest -*/ -void QCustomPlot::setSelectionTolerance(int pixels) -{ - mSelectionTolerance = pixels; -} - -/*! - Sets whether antialiasing is disabled for this QCustomPlot while the user is dragging axes - ranges. If many objects, especially plottables, are drawn antialiased, this greatly improves - performance during dragging. Thus it creates a more responsive user experience. As soon as the - user stops dragging, the last replot is done with normal antialiasing, to restore high image - quality. - - \see setAntialiasedElements, setNotAntialiasedElements -*/ -void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) -{ - mNoAntialiasingOnDrag = enabled; -} - -/*! - Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. - - \see setPlottingHint -*/ -void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) -{ - mPlottingHints = hints; -} - -/*! - Sets the specified plotting \a hint to \a enabled. - - \see setPlottingHints -*/ -void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) -{ - QCP::PlottingHints newHints = mPlottingHints; - if (!enabled) - newHints &= ~hint; - else - newHints |= hint; - - if (newHints != mPlottingHints) - setPlottingHints(newHints); -} - -/*! - Sets the keyboard modifier that will be recognized as multi-select-modifier. - - If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple - objects (or data points) by clicking on them one after the other while holding down \a modifier. - - By default the multi-select-modifier is set to Qt::ControlModifier. - - \see setInteractions -*/ -void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) -{ - mMultiSelectModifier = modifier; -} - -/*! - Sets how QCustomPlot processes mouse click-and-drag interactions by the user. - - If \a mode is \ref QCP::srmNone, the mouse drag is forwarded to the underlying objects. For - example, QCPAxisRect may process a mouse drag by dragging axis ranges, see \ref - QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref - selectionRect) becomes activated and allows e.g. rect zooming and data point selection. - - If you wish to provide your user both with axis range dragging and data selection/range zooming, - use this method to switch between the modes just before the interaction is processed, e.g. in - reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether - the user is holding a certain keyboard modifier, and then decide which \a mode shall be set. - - If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the - interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes - will keep the selection rect active. Upon completion of the interaction, the behaviour is as - defined by the currently set \a mode, not the mode that was set when the interaction started. - - \see setInteractions, setSelectionRect, QCPSelectionRect -*/ -void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) -{ - if (mSelectionRect) - { - if (mode == QCP::srmNone) - mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect - - // disconnect old connections: - if (mSelectionRectMode == QCP::srmSelect) - disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); - else if (mSelectionRectMode == QCP::srmZoom) - disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); - - // establish new ones: - if (mode == QCP::srmSelect) - connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); - else if (mode == QCP::srmZoom) - connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); - } - - mSelectionRectMode = mode; -} - -/*! - Sets the \ref QCPSelectionRect instance that QCustomPlot will use if \a mode is not \ref - QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of - the passed \a selectionRect. It can be accessed later via \ref selectionRect. - - This method is useful if you wish to replace the default QCPSelectionRect instance with an - instance of a QCPSelectionRect subclass, to introduce custom behaviour of the selection rect. - - \see setSelectionRectMode -*/ -void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) -{ - if (mSelectionRect) - delete mSelectionRect; - - mSelectionRect = selectionRect; - - if (mSelectionRect) - { - // establish connections with new selection rect: - if (mSelectionRectMode == QCP::srmSelect) - connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); - else if (mSelectionRectMode == QCP::srmZoom) - connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); - } -} - -/*! - \warning This is still an experimental feature and its performance depends on the system that it - runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering - might cause context conflicts on some systems. - - This method allows to enable OpenGL plot rendering, for increased plotting performance of - graphically demanding plots (thick lines, translucent fills, etc.). - - If \a enabled is set to true, QCustomPlot will try to initialize OpenGL and, if successful, - continue plotting with hardware acceleration. The parameter \a multisampling controls how many - samples will be used per pixel, it essentially controls the antialiasing quality. If \a - multisampling is set too high for the current graphics hardware, the maximum allowed value will - be used. - - You can test whether switching to OpenGL rendering was successful by checking whether the - according getter \a QCustomPlot::openGl() returns true. If the OpenGL initialization fails, - rendering continues with the regular software rasterizer, and an according qDebug output is - generated. - - If switching to OpenGL was successful, this method disables label caching (\ref setPlottingHint - "setPlottingHint(QCP::phCacheLabels, false)") and turns on QCustomPlot's antialiasing override - for all elements (\ref setAntialiasedElements "setAntialiasedElements(QCP::aeAll)"), leading to a - higher quality output. The antialiasing override allows for pixel-grid aligned drawing in the - OpenGL paint device. As stated before, in OpenGL rendering the actual antialiasing of the plot is - controlled with \a multisampling. If \a enabled is set to false, the antialiasing/label caching - settings are restored to what they were before OpenGL was enabled, if they weren't altered in the - meantime. - - \note OpenGL support is only enabled if QCustomPlot is compiled with the macro \c QCUSTOMPLOT_USE_OPENGL - defined. This define must be set before including the QCustomPlot header both during compilation - of the QCustomPlot library as well as when compiling your application. It is best to just include - the line DEFINES += QCUSTOMPLOT_USE_OPENGL in the respective qmake project files. - \note If you are using a Qt version before 5.0, you must also add the module "opengl" to your \c - QT variable in the qmake project files. For Qt versions 5.0 and higher, QCustomPlot switches to a - newer OpenGL interface which is already in the "gui" module. -*/ -void QCustomPlot::setOpenGl(bool enabled, int multisampling) -{ - mOpenGlMultisamples = qMax(0, multisampling); -#ifdef QCUSTOMPLOT_USE_OPENGL - mOpenGl = enabled; - if (mOpenGl) - { - if (setupOpenGl()) - { - // backup antialiasing override and labelcaching setting so we can restore upon disabling OpenGL - mOpenGlAntialiasedElementsBackup = mAntialiasedElements; - mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); - // set antialiasing override to antialias all (aligns gl pixel grid properly), and disable label caching (would use software rasterizer for pixmap caches): - setAntialiasedElements(QCP::aeAll); - setPlottingHint(QCP::phCacheLabels, false); - } else - { - qDebug() << Q_FUNC_INFO << "Failed to enable OpenGL, continuing plotting without hardware acceleration."; - mOpenGl = false; - } - } else - { - // restore antialiasing override and labelcaching to what it was before enabling OpenGL, if nobody changed it in the meantime: - if (mAntialiasedElements == QCP::aeAll) - setAntialiasedElements(mOpenGlAntialiasedElementsBackup); - if (!mPlottingHints.testFlag(QCP::phCacheLabels)) - setPlottingHint(QCP::phCacheLabels, mOpenGlCacheLabelsBackup); - freeOpenGl(); - } - // recreate all paint buffers: - mPaintBuffers.clear(); - setupPaintBuffers(); -#else - Q_UNUSED(enabled) - qDebug() << Q_FUNC_INFO << "QCustomPlot can't use OpenGL because QCUSTOMPLOT_USE_OPENGL was not defined during compilation (add 'DEFINES += QCUSTOMPLOT_USE_OPENGL' to your qmake .pro file)"; -#endif -} - -/*! - Sets the viewport of this QCustomPlot. Usually users of QCustomPlot don't need to change the - viewport manually. - - The viewport is the area in which the plot is drawn. All mechanisms, e.g. margin caluclation take - the viewport to be the outer border of the plot. The viewport normally is the rect() of the - QCustomPlot widget, i.e. a rect with top left (0, 0) and size of the QCustomPlot widget. - - Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically - an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger - and contains also the axes themselves, their tick numbers, their labels, or even additional axis - rects, color scales and other layout elements. - - This function is used to allow arbitrary size exports with \ref toPixmap, \ref savePng, \ref - savePdf, etc. by temporarily changing the viewport size. -*/ -void QCustomPlot::setViewport(const QRect &rect) -{ - mViewport = rect; - if (mPlotLayout) - mPlotLayout->setOuterRect(mViewport); -} - -/*! - Sets the device pixel ratio used by the paint buffers of this QCustomPlot instance. - - Normally, this doesn't need to be set manually, because it is initialized with the regular \a - QWidget::devicePixelRatio which is configured by Qt to fit the display device (e.g. 1 for normal - displays, 2 for High-DPI displays). - - Device pixel ratios are supported by Qt only for Qt versions since 5.4. If this method is called - when QCustomPlot is being used with older Qt versions, outputs an according qDebug message and - leaves the internal buffer device pixel ratio at 1.0. -*/ -void QCustomPlot::setBufferDevicePixelRatio(double ratio) -{ - if (!qFuzzyCompare(ratio, mBufferDevicePixelRatio)) - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mBufferDevicePixelRatio = ratio; - for (int i=0; isetDevicePixelRatio(mBufferDevicePixelRatio); - // Note: axis label cache has devicePixelRatio as part of cache hash, so no need to manually clear cache here -#else - qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; - mBufferDevicePixelRatio = 1.0; -#endif - } -} - -/*! - Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn - below all other objects in the plot. - - For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be - enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is - preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, - consider using the overloaded version of this function. - - If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will - first be filled with that brush, before drawing the background pixmap. This can be useful for - background pixmaps with translucent areas. - - \see setBackgroundScaled, setBackgroundScaledMode -*/ -void QCustomPlot::setBackground(const QPixmap &pm) -{ - mBackgroundPixmap = pm; - mScaledBackgroundPixmap = QPixmap(); -} - -/*! - Sets the background brush of the viewport (see \ref setViewport). - - Before drawing everything else, the background is filled with \a brush. If a background pixmap - was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport - before the background pixmap is drawn. This can be useful for background pixmaps with translucent - areas. - - Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be - useful for exporting to image formats which support transparency, e.g. \ref savePng. - - \see setBackgroundScaled, setBackgroundScaledMode -*/ -void QCustomPlot::setBackground(const QBrush &brush) -{ - mBackgroundBrush = brush; -} - -/*! \overload - - Allows setting the background pixmap of the viewport, whether it shall be scaled and how it - shall be scaled in one call. - - \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode -*/ -void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) -{ - mBackgroundPixmap = pm; - mScaledBackgroundPixmap = QPixmap(); - mBackgroundScaled = scaled; - mBackgroundScaledMode = mode; -} - -/*! - Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is - set to true, control whether and how the aspect ratio of the original pixmap is preserved with - \ref setBackgroundScaledMode. - - Note that the scaled version of the original pixmap is buffered, so there is no performance - penalty on replots. (Except when the viewport dimensions are changed continuously.) - - \see setBackground, setBackgroundScaledMode -*/ -void QCustomPlot::setBackgroundScaled(bool scaled) -{ - mBackgroundScaled = scaled; -} - -/*! - If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this - function to define whether and how the aspect ratio of the original pixmap is preserved. - - \see setBackground, setBackgroundScaled -*/ -void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) -{ - mBackgroundScaledMode = mode; -} - -/*! - Returns the plottable with \a index. If the index is invalid, returns 0. - - There is an overloaded version of this function with no parameter which returns the last added - plottable, see QCustomPlot::plottable() - - \see plottableCount -*/ -QCPAbstractPlottable *QCustomPlot::plottable(int index) -{ - if (index >= 0 && index < mPlottables.size()) - { - return mPlottables.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! \overload - - Returns the last plottable that was added to the plot. If there are no plottables in the plot, - returns 0. - - \see plottableCount -*/ -QCPAbstractPlottable *QCustomPlot::plottable() -{ - if (!mPlottables.isEmpty()) - { - return mPlottables.last(); - } else - return 0; -} - -/*! - Removes the specified plottable from the plot and deletes it. If necessary, the corresponding - legend item is also removed from the default legend (QCustomPlot::legend). - - Returns true on success. - - \see clearPlottables -*/ -bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) -{ - if (!mPlottables.contains(plottable)) - { - qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); - return false; - } - - // remove plottable from legend: - plottable->removeFromLegend(); - // special handling for QCPGraphs to maintain the simple graph interface: - if (QCPGraph *graph = qobject_cast(plottable)) - mGraphs.removeOne(graph); - // remove plottable: - delete plottable; - mPlottables.removeOne(plottable); - return true; -} - -/*! \overload - - Removes and deletes the plottable by its \a index. -*/ -bool QCustomPlot::removePlottable(int index) -{ - if (index >= 0 && index < mPlottables.size()) - return removePlottable(mPlottables[index]); - else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return false; - } -} - -/*! - Removes all plottables from the plot and deletes them. Corresponding legend items are also - removed from the default legend (QCustomPlot::legend). - - Returns the number of plottables removed. - - \see removePlottable -*/ -int QCustomPlot::clearPlottables() -{ - int c = mPlottables.size(); - for (int i=c-1; i >= 0; --i) - removePlottable(mPlottables[i]); - return c; -} - -/*! - Returns the number of currently existing plottables in the plot - - \see plottable -*/ -int QCustomPlot::plottableCount() const -{ - return mPlottables.size(); -} - -/*! - Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. - - There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. - - \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection -*/ -QList QCustomPlot::selectedPlottables() const -{ - QList result; - foreach (QCPAbstractPlottable *plottable, mPlottables) - { - if (plottable->selected()) - result.append(plottable); - } - return result; -} - -/*! - Returns the plottable at the pixel position \a pos. Plottables that only consist of single lines - (like graphs) have a tolerance band around them, see \ref setSelectionTolerance. If multiple - plottables come into consideration, the one closest to \a pos is returned. - - If \a onlySelectable is true, only plottables that are selectable - (QCPAbstractPlottable::setSelectable) are considered. - - If there is no plottable at \a pos, the return value is 0. - - \see itemAt, layoutElementAt -*/ -QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable) const -{ - QCPAbstractPlottable *resultPlottable = 0; - double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value - - foreach (QCPAbstractPlottable *plottable, mPlottables) - { - if (onlySelectable && !plottable->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPabstractPlottable::selectable - continue; - if ((plottable->keyAxis()->axisRect()->rect() & plottable->valueAxis()->axisRect()->rect()).contains(pos.toPoint())) // only consider clicks inside the rect that is spanned by the plottable's key/value axes - { - double currentDistance = plottable->selectTest(pos, false); - if (currentDistance >= 0 && currentDistance < resultDistance) - { - resultPlottable = plottable; - resultDistance = currentDistance; - } - } - } - - return resultPlottable; -} - -/*! - Returns whether this QCustomPlot instance contains the \a plottable. -*/ -bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const -{ - return mPlottables.contains(plottable); -} - -/*! - Returns the graph with \a index. If the index is invalid, returns 0. - - There is an overloaded version of this function with no parameter which returns the last created - graph, see QCustomPlot::graph() - - \see graphCount, addGraph -*/ -QCPGraph *QCustomPlot::graph(int index) const -{ - if (index >= 0 && index < mGraphs.size()) - { - return mGraphs.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! \overload - - Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, - returns 0. - - \see graphCount, addGraph -*/ -QCPGraph *QCustomPlot::graph() const -{ - if (!mGraphs.isEmpty()) - { - return mGraphs.last(); - } else - return 0; -} - -/*! - Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the - bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a - keyAxis and \a valueAxis must reside in this QCustomPlot. - - \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically - "y") for the graph. - - Returns a pointer to the newly created graph, or 0 if adding the graph failed. - - \see graph, graphCount, removeGraph, clearGraphs -*/ -QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) -{ - if (!keyAxis) keyAxis = xAxis; - if (!valueAxis) valueAxis = yAxis; - if (!keyAxis || !valueAxis) - { - qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)"; - return 0; - } - if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) - { - qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; - return 0; - } - - QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); - newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); - return newGraph; -} - -/*! - Removes the specified \a graph from the plot and deletes it. If necessary, the corresponding - legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in - the plot have a channel fill set towards the removed graph, the channel fill property of those - graphs is reset to zero (no channel fill). - - Returns true on success. - - \see clearGraphs -*/ -bool QCustomPlot::removeGraph(QCPGraph *graph) -{ - return removePlottable(graph); -} - -/*! \overload - - Removes and deletes the graph by its \a index. -*/ -bool QCustomPlot::removeGraph(int index) -{ - if (index >= 0 && index < mGraphs.size()) - return removeGraph(mGraphs[index]); - else - return false; -} - -/*! - Removes all graphs from the plot and deletes them. Corresponding legend items are also removed - from the default legend (QCustomPlot::legend). - - Returns the number of graphs removed. - - \see removeGraph -*/ -int QCustomPlot::clearGraphs() -{ - int c = mGraphs.size(); - for (int i=c-1; i >= 0; --i) - removeGraph(mGraphs[i]); - return c; -} - -/*! - Returns the number of currently existing graphs in the plot - - \see graph, addGraph -*/ -int QCustomPlot::graphCount() const -{ - return mGraphs.size(); -} - -/*! - Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. - - If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, - etc., use \ref selectedPlottables. - - \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection -*/ -QList QCustomPlot::selectedGraphs() const -{ - QList result; - foreach (QCPGraph *graph, mGraphs) - { - if (graph->selected()) - result.append(graph); - } - return result; -} - -/*! - Returns the item with \a index. If the index is invalid, returns 0. - - There is an overloaded version of this function with no parameter which returns the last added - item, see QCustomPlot::item() - - \see itemCount -*/ -QCPAbstractItem *QCustomPlot::item(int index) const -{ - if (index >= 0 && index < mItems.size()) - { - return mItems.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! \overload - - Returns the last item that was added to this plot. If there are no items in the plot, - returns 0. - - \see itemCount -*/ -QCPAbstractItem *QCustomPlot::item() const -{ - if (!mItems.isEmpty()) - { - return mItems.last(); - } else - return 0; -} - -/*! - Removes the specified item from the plot and deletes it. - - Returns true on success. - - \see clearItems -*/ -bool QCustomPlot::removeItem(QCPAbstractItem *item) -{ - if (mItems.contains(item)) - { - delete item; - mItems.removeOne(item); - return true; - } else - { - qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); - return false; - } -} - -/*! \overload - - Removes and deletes the item by its \a index. -*/ -bool QCustomPlot::removeItem(int index) -{ - if (index >= 0 && index < mItems.size()) - return removeItem(mItems[index]); - else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return false; - } -} - -/*! - Removes all items from the plot and deletes them. - - Returns the number of items removed. - - \see removeItem -*/ -int QCustomPlot::clearItems(bool clearTitle) -{ - int c = mItems.size(); - for (int i=c-1; i >= 0; --i) - { - if(mItems[i]->objectName() == "m_trendTitle") - { - if(!clearTitle) - { - continue; - } - } - removeItem(mItems[i]); - } - return c; -} - -/*! - Returns the number of currently existing items in the plot - - \see item -*/ -int QCustomPlot::itemCount() const -{ - return mItems.size(); -} - -/*! - Returns a list of the selected items. If no items are currently selected, the list is empty. - - \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected -*/ -QList QCustomPlot::selectedItems() const -{ - QList result; - foreach (QCPAbstractItem *item, mItems) - { - if (item->selected()) - result.append(item); - } - return result; -} - -/*! - Returns the item at the pixel position \a pos. Items that only consist of single lines (e.g. \ref - QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref - setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is - returned. - - If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are - considered. - - If there is no item at \a pos, the return value is 0. - - \see plottableAt, layoutElementAt -*/ -QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const -{ - QCPAbstractItem *resultItem = 0; - double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value - - foreach (QCPAbstractItem *item, mItems) - { - if (onlySelectable && !item->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable - continue; - if (!item->clipToAxisRect() || item->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it - { - double currentDistance = item->selectTest(pos, false); - if (currentDistance >= 0 && currentDistance < resultDistance) - { - resultItem = item; - resultDistance = currentDistance; - } - } - } - - return resultItem; -} - -/*! - Returns whether this QCustomPlot contains the \a item. - - \see item -*/ -bool QCustomPlot::hasItem(QCPAbstractItem *item) const -{ - return mItems.contains(item); -} - -/*! - Returns the layer with the specified \a name. If there is no layer with the specified name, 0 is - returned. - - Layer names are case-sensitive. - - \see addLayer, moveLayer, removeLayer -*/ -QCPLayer *QCustomPlot::layer(const QString &name) const -{ - foreach (QCPLayer *layer, mLayers) - { - if (layer->name() == name) - return layer; - } - return 0; -} - -/*! \overload - - Returns the layer by \a index. If the index is invalid, 0 is returned. - - \see addLayer, moveLayer, removeLayer -*/ -QCPLayer *QCustomPlot::layer(int index) const -{ - if (index >= 0 && index < mLayers.size()) - { - return mLayers.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! - Returns the layer that is set as current layer (see \ref setCurrentLayer). -*/ -QCPLayer *QCustomPlot::currentLayer() const -{ - return mCurrentLayer; -} - -/*! - Sets the layer with the specified \a name to be the current layer. All layerables (\ref - QCPLayerable), e.g. plottables and items, are created on the current layer. - - Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. - - Layer names are case-sensitive. - - \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer -*/ -bool QCustomPlot::setCurrentLayer(const QString &name) -{ - if (QCPLayer *newCurrentLayer = layer(name)) - { - return setCurrentLayer(newCurrentLayer); - } else - { - qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; - return false; - } -} - -/*! \overload - - Sets the provided \a layer to be the current layer. - - Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. - - \see addLayer, moveLayer, removeLayer -*/ -bool QCustomPlot::setCurrentLayer(QCPLayer *layer) -{ - if (!mLayers.contains(layer)) - { - qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); - return false; - } - - mCurrentLayer = layer; - return true; -} - -/*! - Returns the number of currently existing layers in the plot - - \see layer, addLayer -*/ -int QCustomPlot::layerCount() const -{ - return mLayers.size(); -} - -/*! - Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which - must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. - - Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a - valid layer inside this QCustomPlot. - - If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. - - For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. - - \see layer, moveLayer, removeLayer -*/ -bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) -{ - if (!otherLayer) - otherLayer = mLayers.last(); - if (!mLayers.contains(otherLayer)) - { - qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); - return false; - } - if (layer(name)) - { - qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; - return false; - } - - QCPLayer *newLayer = new QCPLayer(this, name); - mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); - updateLayerIndices(); - setupPaintBuffers(); // associates new layer with the appropriate paint buffer - return true; -} - -/*! - Removes the specified \a layer and returns true on success. - - All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below - \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both - cases, the total rendering order of all layerables in the QCustomPlot is preserved. - - If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom - layer) becomes the new current layer. - - It is not possible to remove the last layer of the plot. - - \see layer, addLayer, moveLayer -*/ -bool QCustomPlot::removeLayer(QCPLayer *layer) -{ - if (!mLayers.contains(layer)) - { - qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); - return false; - } - if (mLayers.size() < 2) - { - qDebug() << Q_FUNC_INFO << "can't remove last layer"; - return false; - } - - // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) - int removedIndex = layer->index(); - bool isFirstLayer = removedIndex==0; - QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); - QList children = layer->children(); - if (isFirstLayer) // prepend in reverse order (so order relative to each other stays the same) - { - for (int i=children.size()-1; i>=0; --i) - children.at(i)->moveToLayer(targetLayer, true); - } else // append normally - { - for (int i=0; imoveToLayer(targetLayer, false); - } - // if removed layer is current layer, change current layer to layer below/above: - if (layer == mCurrentLayer) - setCurrentLayer(targetLayer); - // invalidate the paint buffer that was responsible for this layer: - if (!layer->mPaintBuffer.isNull()) - layer->mPaintBuffer.data()->setInvalidated(); - // remove layer: - delete layer; - mLayers.removeOne(layer); - updateLayerIndices(); - return true; -} - -/*! - Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or - below is controlled with \a insertMode. - - Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the - QCustomPlot. - - \see layer, addLayer, moveLayer -*/ -bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) -{ - if (!mLayers.contains(layer)) - { - qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); - return false; - } - if (!mLayers.contains(otherLayer)) - { - qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); - return false; - } - - if (layer->index() > otherLayer->index()) - mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); - else if (layer->index() < otherLayer->index()) - mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); - - // invalidate the paint buffers that are responsible for the layers: - if (!layer->mPaintBuffer.isNull()) - layer->mPaintBuffer.data()->setInvalidated(); - if (!otherLayer->mPaintBuffer.isNull()) - otherLayer->mPaintBuffer.data()->setInvalidated(); - - updateLayerIndices(); - return true; -} - -/*! - Returns the number of axis rects in the plot. - - All axis rects can be accessed via QCustomPlot::axisRect(). - - Initially, only one axis rect exists in the plot. - - \see axisRect, axisRects -*/ -int QCustomPlot::axisRectCount() const -{ - return axisRects().size(); -} - -/*! - Returns the axis rect with \a index. - - Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were - added, all of them may be accessed with this function in a linear fashion (even when they are - nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). - - \see axisRectCount, axisRects -*/ -QCPAxisRect *QCustomPlot::axisRect(int index) const -{ - const QList rectList = axisRects(); - if (index >= 0 && index < rectList.size()) - { - return rectList.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "invalid axis rect index" << index; - return 0; - } -} - -/*! - Returns all axis rects in the plot. - - \see axisRectCount, axisRect -*/ -QList QCustomPlot::axisRects() const -{ - QList result; - QStack elementStack; - if (mPlotLayout) - elementStack.push(mPlotLayout); - - while (!elementStack.isEmpty()) - { - foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) - { - if (element) - { - elementStack.push(element); - if (QCPAxisRect *ar = qobject_cast(element)) - result.append(ar); - } - } - } - - return result; -} - -/*! - Returns the layout element at pixel position \a pos. If there is no element at that position, - returns 0. - - Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on - any of its parent elements is set to false, it will not be considered. - - \see itemAt, plottableAt -*/ -QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const -{ - QCPLayoutElement *currentElement = mPlotLayout; - bool searchSubElements = true; - while (searchSubElements && currentElement) - { - searchSubElements = false; - foreach (QCPLayoutElement *subElement, currentElement->elements(false)) - { - if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) - { - currentElement = subElement; - searchSubElements = true; - break; - } - } - } - return currentElement; -} - -/*! - Returns the layout element of type \ref QCPAxisRect at pixel position \a pos. This method ignores - other layout elements even if they are visually in front of the axis rect (e.g. a \ref - QCPLegend). If there is no axis rect at that position, returns 0. - - Only visible axis rects are used. If \ref QCPLayoutElement::setVisible on the axis rect itself or - on any of its parent elements is set to false, it will not be considered. - - \see layoutElementAt -*/ -QCPAxisRect *QCustomPlot::axisRectAt(const QPointF &pos) const -{ - QCPAxisRect *result = 0; - QCPLayoutElement *currentElement = mPlotLayout; - bool searchSubElements = true; - while (searchSubElements && currentElement) - { - searchSubElements = false; - foreach (QCPLayoutElement *subElement, currentElement->elements(false)) - { - if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) - { - currentElement = subElement; - searchSubElements = true; - if (QCPAxisRect *ar = qobject_cast(currentElement)) - result = ar; - break; - } - } - } - return result; -} - -/*! - Returns the axes that currently have selected parts, i.e. whose selection state is not \ref - QCPAxis::spNone. - - \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, - QCPAxis::setSelectableParts -*/ -QList QCustomPlot::selectedAxes() const -{ - QList result, allAxes; - foreach (QCPAxisRect *rect, axisRects()) - allAxes << rect->axes(); - - foreach (QCPAxis *axis, allAxes) - { - if (axis->selectedParts() != QCPAxis::spNone) - result.append(axis); - } - - return result; -} - -/*! - Returns the legends that currently have selected parts, i.e. whose selection state is not \ref - QCPLegend::spNone. - - \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, - QCPLegend::setSelectableParts, QCPLegend::selectedItems -*/ -QList QCustomPlot::selectedLegends() const -{ - QList result; - - QStack elementStack; - if (mPlotLayout) - elementStack.push(mPlotLayout); - - while (!elementStack.isEmpty()) - { - foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) - { - if (subElement) - { - elementStack.push(subElement); - if (QCPLegend *leg = qobject_cast(subElement)) - { - if (leg->selectedParts() != QCPLegend::spNone) - result.append(leg); - } - } - } - } - - return result; -} - -/*! - Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. - - Since calling this function is not a user interaction, this does not emit the \ref - selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the - objects were previously selected. - - \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends -*/ -void QCustomPlot::deselectAll() -{ - foreach (QCPLayer *layer, mLayers) - { - foreach (QCPLayerable *layerable, layer->children()) - layerable->deselectEvent(0); - } -} - -/*! - Causes a complete replot into the internal paint buffer(s). Finally, the widget surface is - refreshed with the new buffer contents. This is the method that must be called to make changes to - the plot, e.g. on the axis ranges or data points of graphs, visible. - - The parameter \a refreshPriority can be used to fine-tune the timing of the replot. For example - if your application calls \ref replot very quickly in succession (e.g. multiple independent - functions change some aspects of the plot and each wants to make sure the change gets replotted), - it is advisable to set \a refreshPriority to \ref QCustomPlot::rpQueuedReplot. This way, the - actual replotting is deferred to the next event loop iteration. Multiple successive calls of \ref - replot with this priority will only cause a single replot, avoiding redundant replots and - improving performance. - - Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the - QCustomPlot widget and user interactions (object selection and range dragging/zooming). - - Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref - afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two - signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite - recursion. - - If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to - replot only that specific layer via \ref QCPLayer::replot. See the documentation there for - details. -*/ -void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) -{ - if (refreshPriority == QCustomPlot::rpQueuedReplot) - { - if (!mReplotQueued) - { - mReplotQueued = true; - QTimer::singleShot(0, this, SLOT(replot())); - } - return; - } - - if (mReplotting) // incase signals loop back to replot slot - return; - mReplotting = true; - mReplotQueued = false; - emit beforeReplot(); - - updateLayout(); - // draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers: - setupPaintBuffers(); - foreach (QCPLayer *layer, mLayers) - layer->drawToPaintBuffer(); - for (int i=0; isetInvalidated(false); - - if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh) - repaint(); - else - update(); - - emit afterReplot(); - mReplotting = false; -} - -/*! - Rescales the axes such that all plottables (like graphs) in the plot are fully visible. - - if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true - (QCPLayerable::setVisible), will be used to rescale the axes. - - \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale -*/ -void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) -{ - QList allAxes; - foreach (QCPAxisRect *rect, axisRects()) - allAxes << rect->axes(); - - foreach (QCPAxis *axis, allAxes) - axis->rescale(onlyVisiblePlottables); -} - -/*! - Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale - of texts and lines will be derived from the specified \a width and \a height. This means, the - output will look like the normal on-screen output of a QCustomPlot widget with the corresponding - pixel width and height. If either \a width or \a height is zero, the exported image will have the - same dimensions as the QCustomPlot widget currently has. - - Setting \a exportPen to \ref QCP::epNoCosmetic allows to disable the use of cosmetic pens when - drawing to the PDF file. Cosmetic pens are pens with numerical width 0, which are always drawn as - a one pixel wide line, no matter what zoom factor is set in the PDF-Viewer. For more information - about cosmetic pens, see the QPainter and QPen documentation. - - The objects of the plot will appear in the current selection state. If you don't want any - selected objects to be painted in their selected look, deselect everything with \ref deselectAll - before calling this function. - - Returns true on success. - - \warning - \li If you plan on editing the exported PDF file with a vector graphics editor like Inkscape, it - is advised to set \a exportPen to \ref QCP::epNoCosmetic to avoid losing those cosmetic lines - (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). - \li If calling this function inside the constructor of the parent of the QCustomPlot widget - (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide - explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this - function uses the current width and height of the QCustomPlot widget. However, in Qt, these - aren't defined yet inside the constructor, so you would get an image that has strange - widths/heights. - - \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting - PDF file. - - \note On Android systems, this method does nothing and issues an according qDebug warning - message. This is also the case if for other reasons the define flag \c QT_NO_PRINTER is set. - - \see savePng, saveBmp, saveJpg, saveRastered -*/ -bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::ExportPen exportPen, const QString &pdfCreator, const QString &pdfTitle) -{ - bool success = false; -#ifdef QT_NO_PRINTER - Q_UNUSED(fileName) - Q_UNUSED(exportPen) - Q_UNUSED(width) - Q_UNUSED(height) - Q_UNUSED(pdfCreator) - Q_UNUSED(pdfTitle) - qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created."; -#else - int newWidth, newHeight; - if (width == 0 || height == 0) - { - newWidth = this->width(); - newHeight = this->height(); - } else - { - newWidth = width; - newHeight = height; - } - - QPrinter printer(QPrinter::ScreenResolution); - printer.setOutputFileName(fileName); - printer.setOutputFormat(QPrinter::PdfFormat); - printer.setColorMode(QPrinter::Color); - printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator); - printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle); - QRect oldViewport = viewport(); - setViewport(QRect(0, 0, newWidth, newHeight)); -#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) - printer.setFullPage(true); - printer.setPaperSize(viewport().size(), QPrinter::DevicePixel); -#else - QPageLayout pageLayout; - pageLayout.setMode(QPageLayout::FullPageMode); - pageLayout.setOrientation(QPageLayout::Portrait); - pageLayout.setMargins(QMarginsF(0, 0, 0, 0)); - pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch)); - printer.setPageLayout(pageLayout); -#endif - QCPPainter printpainter; - if (printpainter.begin(&printer)) - { - printpainter.setMode(QCPPainter::pmVectorized); - printpainter.setMode(QCPPainter::pmNoCaching); - printpainter.setMode(QCPPainter::pmNonCosmetic, exportPen==QCP::epNoCosmetic); - printpainter.setWindow(mViewport); - if (mBackgroundBrush.style() != Qt::NoBrush && - mBackgroundBrush.color() != Qt::white && - mBackgroundBrush.color() != Qt::transparent && - mBackgroundBrush.color().alpha() > 0) // draw pdf background color if not white/transparent - printpainter.fillRect(viewport(), mBackgroundBrush); - draw(&printpainter); - printpainter.end(); - success = true; - } - setViewport(oldViewport); -#endif // QT_NO_PRINTER - return success; -} - -/*! - Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width - and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the - current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. - are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale - parameter. - - For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an - image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, - texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full - 200*200 pixel resolution. - - If you use a high scaling factor, it is recommended to enable antialiasing for all elements by - temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows - QCustomPlot to place objects with sub-pixel accuracy. - - image compression can be controlled with the \a quality parameter which must be between 0 and 100 - or -1 to use the default setting. - - The \a resolution will be written to the image file header and has no direct consequence for the - quality or the pixel size. However, if opening the image with a tool which respects the metadata, - it will be able to scale the image to match either a given size in real units of length (inch, - centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is - given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected - resolution unit internally. - - Returns true on success. If this function fails, most likely the PNG format isn't supported by - the system, see Qt docs about QImageWriter::supportedImageFormats(). - - The objects of the plot will appear in the current selection state. If you don't want any selected - objects to be painted in their selected look, deselect everything with \ref deselectAll before calling - this function. - - If you want the PNG to have a transparent background, call \ref setBackground(const QBrush &brush) - with no brush (Qt::NoBrush) or a transparent color (Qt::transparent), before saving. - - \warning If calling this function inside the constructor of the parent of the QCustomPlot widget - (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide - explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this - function uses the current width and height of the QCustomPlot widget. However, in Qt, these - aren't defined yet inside the constructor, so you would get an image that has strange - widths/heights. - - \see savePdf, saveBmp, saveJpg, saveRastered -*/ -bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) -{ - return saveRastered(fileName, width, height, scale, "PNG", quality, resolution, resolutionUnit); -} - -/*! - Saves a JPEG image file to \a fileName on disc. The output plot will have the dimensions \a width - and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the - current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. - are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale - parameter. - - For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an - image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, - texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full - 200*200 pixel resolution. - - If you use a high scaling factor, it is recommended to enable antialiasing for all elements by - temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows - QCustomPlot to place objects with sub-pixel accuracy. - - image compression can be controlled with the \a quality parameter which must be between 0 and 100 - or -1 to use the default setting. - - The \a resolution will be written to the image file header and has no direct consequence for the - quality or the pixel size. However, if opening the image with a tool which respects the metadata, - it will be able to scale the image to match either a given size in real units of length (inch, - centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is - given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected - resolution unit internally. - - Returns true on success. If this function fails, most likely the JPEG format isn't supported by - the system, see Qt docs about QImageWriter::supportedImageFormats(). - - The objects of the plot will appear in the current selection state. If you don't want any selected - objects to be painted in their selected look, deselect everything with \ref deselectAll before calling - this function. - - \warning If calling this function inside the constructor of the parent of the QCustomPlot widget - (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide - explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this - function uses the current width and height of the QCustomPlot widget. However, in Qt, these - aren't defined yet inside the constructor, so you would get an image that has strange - widths/heights. - - \see savePdf, savePng, saveBmp, saveRastered -*/ -bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) -{ - return saveRastered(fileName, width, height, scale, "JPG", quality, resolution, resolutionUnit); -} - -/*! - Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width - and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the - current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. - are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale - parameter. - - For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an - image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, - texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full - 200*200 pixel resolution. - - If you use a high scaling factor, it is recommended to enable antialiasing for all elements by - temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows - QCustomPlot to place objects with sub-pixel accuracy. - - The \a resolution will be written to the image file header and has no direct consequence for the - quality or the pixel size. However, if opening the image with a tool which respects the metadata, - it will be able to scale the image to match either a given size in real units of length (inch, - centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is - given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected - resolution unit internally. - - Returns true on success. If this function fails, most likely the BMP format isn't supported by - the system, see Qt docs about QImageWriter::supportedImageFormats(). - - The objects of the plot will appear in the current selection state. If you don't want any selected - objects to be painted in their selected look, deselect everything with \ref deselectAll before calling - this function. - - \warning If calling this function inside the constructor of the parent of the QCustomPlot widget - (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide - explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this - function uses the current width and height of the QCustomPlot widget. However, in Qt, these - aren't defined yet inside the constructor, so you would get an image that has strange - widths/heights. - - \see savePdf, savePng, saveJpg, saveRastered -*/ -bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale, int resolution, QCP::ResolutionUnit resolutionUnit) -{ - return saveRastered(fileName, width, height, scale, "BMP", -1, resolution, resolutionUnit); -} - -/*! \internal - - Returns a minimum size hint that corresponds to the minimum size of the top level layout - (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum - size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. - This is especially important, when placed in a QLayout where other components try to take in as - much space as possible (e.g. QMdiArea). -*/ -QSize QCustomPlot::minimumSizeHint() const -{ - return mPlotLayout->minimumOuterSizeHint(); -} - -/*! \internal - - Returns a size hint that is the same as \ref minimumSizeHint. - -*/ -QSize QCustomPlot::sizeHint() const -{ - return mPlotLayout->minimumOuterSizeHint(); -} - -/*! \internal - - Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but - draws the internal buffer on the widget surface. -*/ -void QCustomPlot::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QCPPainter painter(this); - if (!painter.isActive()) - { - return; - } - painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem - if (mBackgroundBrush.style() != Qt::NoBrush) - painter.fillRect(mViewport, mBackgroundBrush); - drawBackground(&painter); - for (int bufferIndex = 0; bufferIndex < mPaintBuffers.size(); ++bufferIndex) - mPaintBuffers.at(bufferIndex)->draw(&painter); - - if(!axisRect()->isScaleRight()) - { - //< 横坐标有效值 - int x = mSymbolPos.x() >= yAxis->axisRect()->left() ? mSymbolPos.x() : yAxis->axisRect()->left(); - x = x <= yAxis->axisRect()->right() ? x : yAxis->axisRect()->right(); - //< 纵坐标 - int y = yAxis->axisRect()->top(); - - painter.save(); - painter.setPen(QColor(182, 194, 205)); - painter.setBrush(QColor(182, 194, 205)); - painter.setAntialiasing(true); - QPolygon polygon; - polygon.append(QPoint(x, y)); - polygon.append(QPoint(x + 3, y - 5)); - polygon.append(QPoint(x + 3, 0)); - polygon.append(QPoint(x - 3, 0)); - polygon.append(QPoint(x - 3, y - 5)); - painter.drawPolygon(polygon); - painter.drawLine(QPoint(x, y), QPoint(x, yAxis->axisRect()->bottom())); - painter.restore(); - } -} - -/*! \internal - - Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect - of mPlotLayout) is resized appropriately. Finally a \ref replot is performed. -*/ -void QCustomPlot::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event) - // resize and repaint the buffer: - setViewport(rect()); - replot(rpQueuedRefresh); // queued refresh is important here, to prevent painting issues in some contexts (e.g. MDI subwindow) -} - -/*! \internal - - Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then - determines the layerable under the cursor and forwards the event to it. Finally, emits the - specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref - axisDoubleClick, etc.). - - \see mousePressEvent, mouseReleaseEvent -*/ -void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) -{ - emit mouseDoubleClick(event); - mMouseHasMoved = false; - mMousePressPos = event->pos(); - - // determine layerable under the cursor (this event is called instead of the second press event in a double-click): - QList details; - QList candidates = layerableListAt(mMousePressPos, false, &details); - for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list - candidates.at(i)->mouseDoubleClickEvent(event, details.at(i)); - if (event->isAccepted()) - { - mMouseEventLayerable = candidates.at(i); - mMouseEventLayerableDetails = details.at(i); - break; - } - } - - // emit specialized object double click signals: - if (!candidates.isEmpty()) - { - if (QCPAbstractPlottable *ap = qobject_cast(candidates.first())) - { - int dataIndex = 0; - if (!details.first().value().isEmpty()) - dataIndex = details.first().value().dataRange().begin(); - emit plottableDoubleClick(ap, dataIndex, event); - } else if (QCPAxis *ax = qobject_cast(candidates.first())) - emit axisDoubleClick(ax, details.first().value(), event); - else if (QCPAbstractItem *ai = qobject_cast(candidates.first())) - emit itemDoubleClick(ai, event); - else if (QCPLegend *lg = qobject_cast(candidates.first())) - emit legendDoubleClick(lg, 0, event); - else if (QCPAbstractLegendItem *li = qobject_cast(candidates.first())) - emit legendDoubleClick(li->parentLegend(), li, event); - } - - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. -} - -/*! \internal - - Event handler for when a mouse button is pressed. Emits the mousePress signal. - - If the current \ref setSelectionRectMode is not \ref QCP::srmNone, passes the event to the - selection rect. Otherwise determines the layerable under the cursor and forwards the event to it. - - \see mouseMoveEvent, mouseReleaseEvent -*/ -void QCustomPlot::mousePressEvent(QMouseEvent *event) -{ - if(cursor().shape() == Qt::SizeHorCursor && event->button() == Qt::LeftButton) - { - mSymbolPos = event->pos(); - mSymbolPressed = true; - return; - } - - emit mousePress(event); - // save some state to tell in releaseEvent whether it was a click: - - - mMouseHasMoved = false; - mMousePressPos = event->pos(); - - if (mSelectionRect && mSelectionRectMode != QCP::srmNone) - { - if (mSelectionRectMode != QCP::srmZoom || qobject_cast(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect - mSelectionRect->startSelection(event); - } else - { - // no selection rect interaction, prepare for click signal emission and forward event to layerable under the cursor: - QList details; - QList candidates = layerableListAt(mMousePressPos, false, &details); - if (!candidates.isEmpty()) - { - mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always topmost hit layerable (signal emitted in release event) - mMouseSignalLayerableDetails = details.first(); - } - // forward event to topmost candidate which accepts the event: - for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events call ignore() on the event, in that case propagate to next candidate in list - candidates.at(i)->mousePressEvent(event, details.at(i)); - if (event->isAccepted()) - { - mMouseEventLayerable = candidates.at(i); - mMouseEventLayerableDetails = details.at(i); - break; - } - } - } - - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. - update(); -} - -/*! \internal - - Event handler for when the cursor is moved. Emits the \ref mouseMove signal. - - If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it - in order to update the rect geometry. - - Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the - layout element before), the mouseMoveEvent is forwarded to that element. - - \see mousePressEvent, mouseReleaseEvent -*/ -void QCustomPlot::mouseMoveEvent(QMouseEvent *event) -{ - //< time tip - if(!axisRect()->isScaleRight() && !mSymbolPressed && qAbs(mSymbolPos.x() - event->pos().x()) < 5) - { - if(event->pos().y() > yAxis->axisRect()->top()) - { - if(Qt::SizeHorCursor != cursor().shape()) - { - setCursor(QCursor(Qt::SizeHorCursor)); - } - } - static QString preTipsContent = QString(); - QString strTime = QDateTime::fromMSecsSinceEpoch(xAxis->pixelToCoord(mSymbolPos.x())).toString("yyyy-MM-dd hh:mm:ss zzz"); - if(preTipsContent == strTime && findChild("ToolTip")) - { - return; - } - preTipsContent = strTime; - QFontMetrics metrics(QToolTip::font()); - int pixelsWide = metrics.width(strTime); - int pixelsHigh = metrics.height(); - QPoint position = mapToGlobal(QPoint(event->pos().x() - (pixelsWide / 2), -(pixelsHigh / 2))); - CToolTip::popup(position, strTime, this); - return; - } - - if(mSymbolPressed && event->pos().x() >= yAxis->mAxisRect->left() &&event->pos().x() <= yAxis->mAxisRect->right()) - { - setCursor(QCursor(Qt::SizeHorCursor)); - mSymbolPos = event->pos(); - emit symbolPosChanged(xAxis->pixelToCoord(mSymbolPos.x())); - update(); - return; - } - setCursor(QCursor(Qt::ArrowCursor)); - - - emit mouseMove(event); - if (!mMouseHasMoved && (mMousePressPos-event->pos()).manhattanLength() > 3) - mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release - - if (mSelectionRect && mSelectionRect->isActive()) - mSelectionRect->moveSelection(event); - else if (mMouseEventLayerable) // call event of affected layerable: - mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos); - - //< Extra By ZH - QList details; - QList candidates = layerableListAt(event->pos(), false, &details); - for (int i = 0; i < candidates.size(); ++i) - { - if(dynamic_cast(candidates.at(i))) - { - event->accept(); - candidates.at(i)->mouseMoveEvent(event, mMousePressPos); - } - } - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. -} - -/*! \internal - - Event handler for when a mouse button is released. Emits the \ref mouseRelease signal. - - If the mouse was moved less than a certain threshold in any direction since the \ref - mousePressEvent, it is considered a click which causes the selection mechanism (if activated via - \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse - click signals are emitted (e.g. \ref plottableClick, \ref axisClick, etc.) - - If a layerable is the mouse capturer (a \ref mousePressEvent happened on top of the layerable - before), the \ref mouseReleaseEvent is forwarded to that element. - - \see mousePressEvent, mouseMoveEvent -*/ -void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) -{ - emit mouseRelease(event); - - mSymbolPressed = false; - if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click - { - if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here - mSelectionRect->cancel(); - if (event->button() == Qt::LeftButton) - processPointSelection(event); - - // emit specialized click signals of QCustomPlot instance: - if (QCPAbstractPlottable *ap = qobject_cast(mMouseSignalLayerable)) - { - int dataIndex = 0; - if (!mMouseSignalLayerableDetails.value().isEmpty()) - dataIndex = mMouseSignalLayerableDetails.value().dataRange().begin(); - emit plottableClick(ap, dataIndex, event); - } else if (QCPAxis *ax = qobject_cast(mMouseSignalLayerable)) - emit axisClick(ax, mMouseSignalLayerableDetails.value(), event); - else if (QCPAbstractItem *ai = qobject_cast(mMouseSignalLayerable)) - emit itemClick(ai, event); - else if (QCPLegend *lg = qobject_cast(mMouseSignalLayerable)) - emit legendClick(lg, 0, event); - else if (QCPAbstractLegendItem *li = qobject_cast(mMouseSignalLayerable)) - emit legendClick(li->parentLegend(), li, event); - mMouseSignalLayerable = 0; - } - - if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there - { - // finish selection rect, the appropriate action will be taken via signal-slot connection: - mSelectionRect->endSelection(event); - } else - { - // call event of affected layerable: - if (mMouseEventLayerable) - { - mMouseEventLayerable->mouseReleaseEvent(event, mMousePressPos); - mMouseEventLayerable = 0; - } - } - - if (noAntialiasingOnDrag()) - replot(rpQueuedReplot); - - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. -} - -/*! \internal - - Event handler for mouse wheel events. First, the \ref mouseWheel signal is emitted. Then - determines the affected layerable and forwards the event to it. -*/ -void QCustomPlot::wheelEvent(QWheelEvent *event) -{ - QRect rt = axisRect()->mRect; - if(event->pos().x() < rt.left() || event->pos().x() > rt.right() || event->pos().y() < rt.top() || event->pos().y() > rt.bottom()) - { - return; - } - - emit mouseWheel(event); - // forward event to layerable under cursor: - QList candidates = layerableListAt(event->pos(), false); - - - for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list - candidates.at(i)->wheelEvent(event); - if (event->isAccepted()) - break; - } - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. -} - -bool QCustomPlot::eventFilter(QObject *object, QEvent *event) -{ - QLabel * pLabel = dynamic_cast(object); - if (pLabel) - { - if(event->type() == QEvent::Wheel) - { - QWheelEvent * pWheelEvent = dynamic_cast(event); - QWheelEvent e(mapFromGlobal(pWheelEvent->globalPos()), - pWheelEvent->globalPos(), - pWheelEvent->pixelDelta(), - pWheelEvent->angleDelta(), - pWheelEvent->delta(), - pWheelEvent->orientation(), - pWheelEvent->buttons(), - pWheelEvent->modifiers()); - - wheelEvent(&e); - return true; - } - else if(event->type() == QEvent::MouseMove) - { - QMouseEvent *pMouseEvent = dynamic_cast(event); - QPoint pt = mapFromGlobal(pMouseEvent->globalPos()); - QMouseEvent e(pMouseEvent->type(), - pt, pt, - pMouseEvent->screenPos(), - pMouseEvent->button(), - pMouseEvent->buttons(), - pMouseEvent->modifiers(), - pMouseEvent->source()); - mouseMoveEvent(&e); - return true; - } - } - return QWidget::eventFilter(object, event); -} - -/*! \internal - - This function draws the entire plot, including background pixmap, with the specified \a painter. - It does not make use of the paint buffers like \ref replot, so this is the function typically - used by saving/exporting methods such as \ref savePdf or \ref toPainter. - - Note that it does not fill the background with the background brush (as the user may specify with - \ref setBackground(const QBrush &brush)), this is up to the respective functions calling this - method. -*/ -void QCustomPlot::draw(QCPPainter *painter) -{ - updateLayout(); - - // draw viewport background pixmap: - drawBackground(painter); - - // draw all layered objects (grid, axes, plottables, items, legend,...): - foreach (QCPLayer *layer, mLayers) - layer->draw(painter); - - /* Debug code to draw all layout element rects - foreach (QCPLayoutElement* el, findChildren()) - { - painter->setBrush(Qt::NoBrush); - painter->setPen(QPen(QColor(0, 0, 0, 100), 0, Qt::DashLine)); - painter->drawRect(el->rect()); - painter->setPen(QPen(QColor(255, 0, 0, 100), 0, Qt::DashLine)); - painter->drawRect(el->outerRect()); - } - */ -} - -/*! \internal - - Performs the layout update steps defined by \ref QCPLayoutElement::UpdatePhase, by calling \ref - QCPLayoutElement::update on the main plot layout. - - Here, the layout elements calculate their positions and margins, and prepare for the following - draw call. -*/ -void QCustomPlot::updateLayout() -{ - // run through layout phases: - mPlotLayout->update(QCPLayoutElement::upPreparation); - mPlotLayout->update(QCPLayoutElement::upMargins); - mPlotLayout->update(QCPLayoutElement::upLayout); -} - -/*! \internal - - Draws the viewport background pixmap of the plot. - - If a pixmap was provided via \ref setBackground, this function buffers the scaled version - depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside - the viewport with the provided \a painter. The scaled version is buffered in - mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when - the axis rect has changed in a way that requires a rescale of the background pixmap (this is - dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was - set. - - Note that this function does not draw a fill with the background brush - (\ref setBackground(const QBrush &brush)) beneath the pixmap. - - \see setBackground, setBackgroundScaled, setBackgroundScaledMode -*/ -void QCustomPlot::drawBackground(QCPPainter *painter) -{ - // Note: background color is handled in individual replot/save functions - - // draw background pixmap (on top of fill, if brush specified): - if (!mBackgroundPixmap.isNull()) - { - if (mBackgroundScaled) - { - // check whether mScaledBackground needs to be updated: - QSize scaledSize(mBackgroundPixmap.size()); - scaledSize.scale(mViewport.size(), mBackgroundScaledMode); - if (mScaledBackgroundPixmap.size() != scaledSize) - mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation); - painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect()); - } else - { - painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height())); - } - } -} - -/*! \internal - - Goes through the layers and makes sure this QCustomPlot instance holds the correct number of - paint buffers and that they have the correct configuration (size, pixel ratio, etc.). - Allocations, reallocations and deletions of paint buffers are performed as necessary. It also - associates the paint buffers with the layers, so they draw themselves into the right buffer when - \ref QCPLayer::drawToPaintBuffer is called. This means it associates adjacent \ref - QCPLayer::lmLogical layers to a mutual paint buffer and creates dedicated paint buffers for - layers in \ref QCPLayer::lmBuffered mode. - - This method uses \ref createPaintBuffer to create new paint buffers. - - After this method, the paint buffers are empty (filled with \c Qt::transparent) and invalidated - (so an attempt to replot only a single buffered layer causes a full replot). - - This method is called in every \ref replot call, prior to actually drawing the layers (into their - associated paint buffer). If the paint buffers don't need changing/reallocating, this method - basically leaves them alone and thus finishes very fast. -*/ -void QCustomPlot::setupPaintBuffers() -{ - int bufferIndex = 0; - if (mPaintBuffers.isEmpty()) - mPaintBuffers.append(QSharedPointer(createPaintBuffer())); - - for (int layerIndex = 0; layerIndex < mLayers.size(); ++layerIndex) - { - QCPLayer *layer = mLayers.at(layerIndex); - if (layer->mode() == QCPLayer::lmLogical) - { - layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); - } else if (layer->mode() == QCPLayer::lmBuffered) - { - ++bufferIndex; - if (bufferIndex >= mPaintBuffers.size()) - mPaintBuffers.append(QSharedPointer(createPaintBuffer())); - layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); - if (layerIndex < mLayers.size()-1 && mLayers.at(layerIndex+1)->mode() == QCPLayer::lmLogical) // not last layer, and next one is logical, so prepare another buffer for next layerables - { - ++bufferIndex; - if (bufferIndex >= mPaintBuffers.size()) - mPaintBuffers.append(QSharedPointer(createPaintBuffer())); - } - } - } - // remove unneeded buffers: - while (mPaintBuffers.size()-1 > bufferIndex) - mPaintBuffers.removeLast(); - // resize buffers to viewport size and clear contents: - for (int i=0; isetSize(viewport().size()); // won't do anything if already correct size - mPaintBuffers.at(i)->clear(Qt::transparent); - mPaintBuffers.at(i)->setInvalidated(); - } -} - -/*! \internal - - This method is used by \ref setupPaintBuffers when it needs to create new paint buffers. - - Depending on the current setting of \ref setOpenGl, and the current Qt version, different - backends (subclasses of \ref QCPAbstractPaintBuffer) are created, initialized with the proper - size and device pixel ratio, and returned. -*/ -QCPAbstractPaintBuffer *QCustomPlot::createPaintBuffer() -{ - if (mOpenGl) - { -#if defined(QCP_OPENGL_FBO) - return new QCPPaintBufferGlFbo(viewport().size(), mBufferDevicePixelRatio, mGlContext, mGlPaintDevice); -#elif defined(QCP_OPENGL_PBUFFER) - return new QCPPaintBufferGlPbuffer(viewport().size(), mBufferDevicePixelRatio, mOpenGlMultisamples); -#else - qDebug() << Q_FUNC_INFO << "OpenGL enabled even though no support for it compiled in, this shouldn't have happened. Falling back to pixmap paint buffer."; - return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); -#endif - } else - return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); -} - -/*! - This method returns whether any of the paint buffers held by this QCustomPlot instance are - invalidated. - - If any buffer is invalidated, a partial replot (\ref QCPLayer::replot) is not allowed and always - causes a full replot (\ref QCustomPlot::replot) of all layers. This is the case when for example - the layer order has changed, new layers were added, layers were removed, or layer modes were - changed (\ref QCPLayer::setMode). - - \see QCPAbstractPaintBuffer::setInvalidated -*/ -bool QCustomPlot::hasInvalidatedPaintBuffers() -{ - for (int i=0; iinvalidated()) - return true; - } - return false; -} - -/*! \internal - - When \ref setOpenGl is set to true, this method is used to initialize OpenGL (create a context, - surface, paint device). - - Returns true on success. - - If this method is successful, all paint buffers should be deleted and then reallocated by calling - \ref setupPaintBuffers, so the OpenGL-based paint buffer subclasses (\ref - QCPPaintBufferGlPbuffer, \ref QCPPaintBufferGlFbo) are used for subsequent replots. - - \see freeOpenGl -*/ -bool QCustomPlot::setupOpenGl() -{ -#ifdef QCP_OPENGL_FBO - freeOpenGl(); - QSurfaceFormat proposedSurfaceFormat; - proposedSurfaceFormat.setSamples(mOpenGlMultisamples); -#ifdef QCP_OPENGL_OFFSCREENSURFACE - QOffscreenSurface *surface = new QOffscreenSurface; -#else - QWindow *surface = new QWindow; - surface->setSurfaceType(QSurface::OpenGLSurface); -#endif - surface->setFormat(proposedSurfaceFormat); - surface->create(); - mGlSurface = QSharedPointer(surface); - mGlContext = QSharedPointer(new QOpenGLContext); - mGlContext->setFormat(mGlSurface->format()); - if (!mGlContext->create()) - { - qDebug() << Q_FUNC_INFO << "Failed to create OpenGL context"; - mGlContext.clear(); - mGlSurface.clear(); - return false; - } - if (!mGlContext->makeCurrent(mGlSurface.data())) // context needs to be current to create paint device - { - qDebug() << Q_FUNC_INFO << "Failed to make opengl context current"; - mGlContext.clear(); - mGlSurface.clear(); - return false; - } - if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) - { - qDebug() << Q_FUNC_INFO << "OpenGL of this system doesn't support frame buffer objects"; - mGlContext.clear(); - mGlSurface.clear(); - return false; - } - mGlPaintDevice = QSharedPointer(new QOpenGLPaintDevice); - return true; -#elif defined(QCP_OPENGL_PBUFFER) - return QGLFormat::hasOpenGL(); -#else - return false; -#endif -} - -/*! \internal - - When \ref setOpenGl is set to false, this method is used to deinitialize OpenGL (releases the - context and frees resources). - - After OpenGL is disabled, all paint buffers should be deleted and then reallocated by calling - \ref setupPaintBuffers, so the standard software rendering paint buffer subclass (\ref - QCPPaintBufferPixmap) is used for subsequent replots. - - \see setupOpenGl -*/ -void QCustomPlot::freeOpenGl() -{ -#ifdef QCP_OPENGL_FBO - mGlPaintDevice.clear(); - mGlContext.clear(); - mGlSurface.clear(); -#endif -} - -/*! \internal - - This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot - so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. -*/ -void QCustomPlot::axisRemoved(QCPAxis *axis) -{ - if (xAxis == axis) - xAxis = 0; - if (xAxis2 == axis) - xAxis2 = 0; - if (yAxis == axis) - yAxis = 0; - if (yAxis2 == axis) - yAxis2 = 0; - - // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers -} - -/*! \internal - - This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so - it may clear its QCustomPlot::legend member accordingly. -*/ -void QCustomPlot::legendRemoved(QCPLegend *legend) -{ - if (this->legend == legend) - this->legend = 0; -} - -/*! \internal - - This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref - setSelectionRectMode is set to \ref QCP::srmSelect. - - First, it determines which axis rect was the origin of the selection rect judging by the starting - point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be - precise) associated with that axis rect and finds the data points that are in \a rect. It does - this by querying their \ref QCPAbstractPlottable1D::selectTestRect method. - - Then, the actual selection is done by calling the plottables' \ref - QCPAbstractPlottable::selectEvent, placing the found selected data points in the \a details - parameter as QVariant(\ref QCPDataSelection). All plottables that weren't touched by \a - rect receive a \ref QCPAbstractPlottable::deselectEvent. - - \see processRectZoom -*/ -void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) -{ - bool selectionStateChanged = false; - - if (mInteractions.testFlag(QCP::iSelectPlottables)) - { - QMap > potentialSelections; // map key is number of selected data points, so we have selections sorted by size - QRectF rectF(rect.normalized()); - if (QCPAxisRect *affectedAxisRect = axisRectAt(rectF.topLeft())) - { - // determine plottables that were hit by the rect and thus are candidates for selection: - foreach (QCPAbstractPlottable *plottable, affectedAxisRect->plottables()) - { - if (QCPPlottableInterface1D *plottableInterface = plottable->interface1D()) - { - QCPDataSelection dataSel = plottableInterface->selectTestRect(rectF, true); - if (!dataSel.isEmpty()) - potentialSelections.insertMulti(dataSel.dataPointCount(), QPair(plottable, dataSel)); - } - } - - if (!mInteractions.testFlag(QCP::iMultiSelect)) - { - // only leave plottable with most selected points in map, since we will only select a single plottable: - if (!potentialSelections.isEmpty()) - { - QMap >::iterator it = potentialSelections.begin(); - while (it != potentialSelections.end()-1) // erase all except last element - it = potentialSelections.erase(it); - } - } - - bool additive = event->modifiers().testFlag(mMultiSelectModifier); - // deselect all other layerables if not additive selection: - if (!additive) - { - // emit deselection except to those plottables who will be selected afterwards: - foreach (QCPLayer *layer, mLayers) - { - foreach (QCPLayerable *layerable, layer->children()) - { - if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory())) - { - bool selChanged = false; - layerable->deselectEvent(&selChanged); - selectionStateChanged |= selChanged; - } - } - } - } - - // go through selections in reverse (largest selection first) and emit select events: - QMap >::const_iterator it = potentialSelections.constEnd(); - while (it != potentialSelections.constBegin()) - { - --it; - if (mInteractions.testFlag(it.value().first->selectionCategory())) - { - bool selChanged = false; - it.value().first->selectEvent(event, additive, QVariant::fromValue(it.value().second), &selChanged); - selectionStateChanged |= selChanged; - } - } - } - } - - if (selectionStateChanged) - { - emit selectionChangedByUser(); - replot(rpQueuedReplot); - } else if (mSelectionRect) - mSelectionRect->layer()->replot(); -} - -/*! \internal - - This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref - setSelectionRectMode is set to \ref QCP::srmZoom. - - It determines which axis rect was the origin of the selection rect judging by the starting point - of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the - provided \a rect (see \ref QCPAxisRect::zoom). - - \see processRectSelection -*/ -void QCustomPlot::processRectZoom(QRect rect, QMouseEvent *event) -{ - Q_UNUSED(event) - if (QCPAxisRect *axisRect = axisRectAt(rect.topLeft())) - { - QList affectedAxes = QList() << axisRect->rangeZoomAxes(Qt::Horizontal) << axisRect->rangeZoomAxes(Qt::Vertical); - affectedAxes.removeAll(static_cast(0)); - axisRect->zoom(QRectF(rect), affectedAxes); - } - replot(rpQueuedReplot); // always replot to make selection rect disappear -} - -/*! \internal - - This method is called when a simple left mouse click was detected on the QCustomPlot surface. - - It first determines the layerable that was hit by the click, and then calls its \ref - QCPLayerable::selectEvent. All other layerables receive a QCPLayerable::deselectEvent (unless the - multi-select modifier was pressed, see \ref setMultiSelectModifier). - - In this method the hit layerable is determined a second time using \ref layerableAt (after the - one in \ref mousePressEvent), because we want \a onlySelectable set to true this time. This - implies that the mouse event grabber (mMouseEventLayerable) may be a different one from the - clicked layerable determined here. For example, if a non-selectable layerable is in front of a - selectable layerable at the click position, the front layerable will receive mouse events but the - selectable one in the back will receive the \ref QCPLayerable::selectEvent. - - \see processRectSelection, QCPLayerable::selectTest -*/ -void QCustomPlot::processPointSelection(QMouseEvent *event) -{ - QVariant details; - QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details); - bool selectionStateChanged = false; - bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); - // deselect all other layerables if not additive selection: - if (!additive) - { - foreach (QCPLayer *layer, mLayers) - { - foreach (QCPLayerable *layerable, layer->children()) - { - if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory())) - { - bool selChanged = false; - layerable->deselectEvent(&selChanged); - selectionStateChanged |= selChanged; - } - } - } - } - if (clickedLayerable && mInteractions.testFlag(clickedLayerable->selectionCategory())) - { - // a layerable was actually clicked, call its selectEvent: - bool selChanged = false; - clickedLayerable->selectEvent(event, additive, details, &selChanged); - selectionStateChanged |= selChanged; - } - if (selectionStateChanged) - { - emit selectionChangedByUser(); - replot(rpQueuedReplot); - } -} - -/*! \internal - - Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend - is enabled, adds it to the legend (QCustomPlot::legend). QCustomPlot takes ownership of the - plottable. - - Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of - \a plottable is this QCustomPlot. - - This method is called automatically in the QCPAbstractPlottable base class constructor. -*/ -bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) -{ - if (mPlottables.contains(plottable)) - { - qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); - return false; - } - if (plottable->parentPlot() != this) - { - qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); - return false; - } - - mPlottables.append(plottable); - // possibly add plottable to legend: - if (mAutoAddPlottableToLegend) - plottable->addToLegend(); - if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) - plottable->setLayer(currentLayer()); - return true; -} - -/*! \internal - - In order to maintain the simplified graph interface of QCustomPlot, this method is called by the - QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true - on success, i.e. if \a graph is valid and wasn't already registered with this QCustomPlot. - - This graph specific registration happens in addition to the call to \ref registerPlottable by the - QCPAbstractPlottable base class. -*/ -bool QCustomPlot::registerGraph(QCPGraph *graph) -{ - if (!graph) - { - qDebug() << Q_FUNC_INFO << "passed graph is zero"; - return false; - } - if (mGraphs.contains(graph)) - { - qDebug() << Q_FUNC_INFO << "graph already registered with this QCustomPlot"; - return false; - } - - mGraphs.append(graph); - return true; -} - - -/*! \internal - - Registers the specified item with this QCustomPlot. QCustomPlot takes ownership of the item. - - Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a - item is this QCustomPlot. - - This method is called automatically in the QCPAbstractItem base class constructor. -*/ -bool QCustomPlot::registerItem(QCPAbstractItem *item) -{ - if (mItems.contains(item)) - { - qDebug() << Q_FUNC_INFO << "item already added to this QCustomPlot:" << reinterpret_cast(item); - return false; - } - if (item->parentPlot() != this) - { - qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast(item); - return false; - } - - mItems.append(item); - if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor) - item->setLayer(currentLayer()); - return true; -} - -/*! \internal - - Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called - after every operation that changes the layer indices, like layer removal, layer creation, layer - moving. -*/ -void QCustomPlot::updateLayerIndices() const -{ - for (int i=0; imIndex = i; -} - -/*! \internal - - Returns the top-most layerable at pixel position \a pos. If \a onlySelectable is set to true, - only those layerables that are selectable will be considered. (Layerable subclasses communicate - their selectability via the QCPLayerable::selectTest method, by returning -1.) - - \a selectionDetails is an output parameter that contains selection specifics of the affected - layerable. This is useful if the respective layerable shall be given a subsequent - QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains - information about which part of the layerable was hit, in multi-part layerables (e.g. - QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref - QCPDataSelection instance with the single data point which is closest to \a pos. - - \see layerableListAt, layoutElementAt, axisRectAt -*/ -QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const -{ - QList details; - QList candidates = layerableListAt(pos, onlySelectable, selectionDetails ? &details : 0); - if (selectionDetails && !details.isEmpty()) - *selectionDetails = details.first(); - if (!candidates.isEmpty()) - return candidates.first(); - else - return 0; -} - -/*! \internal - - Returns the layerables at pixel position \a pos. If \a onlySelectable is set to true, only those - layerables that are selectable will be considered. (Layerable subclasses communicate their - selectability via the QCPLayerable::selectTest method, by returning -1.) - - The returned list is sorted by the layerable/drawing order. If you only need to know the top-most - layerable, rather use \ref layerableAt. - - \a selectionDetails is an output parameter that contains selection specifics of the affected - layerable. This is useful if the respective layerable shall be given a subsequent - QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains - information about which part of the layerable was hit, in multi-part layerables (e.g. - QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref - QCPDataSelection instance with the single data point which is closest to \a pos. - - \see layerableAt, layoutElementAt, axisRectAt -*/ -QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails) const -{ - QList result; - for (int layerIndex=mLayers.size()-1; layerIndex>=0; --layerIndex) - { - const QList layerables = mLayers.at(layerIndex)->children(); - for (int i=layerables.size()-1; i>=0; --i) - { - if (!layerables.at(i)->realVisibility()) - continue; - QVariant details; - double dist = layerables.at(i)->selectTest(pos, onlySelectable, selectionDetails ? &details : 0); - if (dist >= 0 && dist < selectionTolerance()) - { - result.append(layerables.at(i)); - if (selectionDetails) - selectionDetails->append(details); - } - } - } - return result; -} - -/*! - Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is - sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead - to a full resolution file with width 200.) If the \a format supports compression, \a quality may - be between 0 and 100 to control it. - - Returns true on success. If this function fails, most likely the given \a format isn't supported - by the system, see Qt docs about QImageWriter::supportedImageFormats(). - - The \a resolution will be written to the image file header (if the file format supports this) and - has no direct consequence for the quality or the pixel size. However, if opening the image with a - tool which respects the metadata, it will be able to scale the image to match either a given size - in real units of length (inch, centimeters, etc.), or the target display DPI. You can specify in - which units \a resolution is given, by setting \a resolutionUnit. The \a resolution is converted - to the format's expected resolution unit internally. - - \see saveBmp, saveJpg, savePng, savePdf -*/ -bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) -{ - QImage buffer = toPixmap(width, height, scale).toImage(); - - int dotsPerMeter = 0; - switch (resolutionUnit) - { - case QCP::ruDotsPerMeter: dotsPerMeter = resolution; break; - case QCP::ruDotsPerCentimeter: dotsPerMeter = resolution*100; break; - case QCP::ruDotsPerInch: dotsPerMeter = resolution/0.0254; break; - } - buffer.setDotsPerMeterX(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools - buffer.setDotsPerMeterY(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools - if (!buffer.isNull()) - return buffer.save(fileName, format, quality); - else - return false; -} - -/*! - Renders the plot to a pixmap and returns it. - - The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and - scale 2.0 lead to a full resolution pixmap with width 200.) - - \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf -*/ -QPixmap QCustomPlot::toPixmap(int width, int height, double scale) -{ - // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too. - int newWidth, newHeight; - if (width == 0 || height == 0) - { - newWidth = this->width(); - newHeight = this->height(); - } else - { - newWidth = width; - newHeight = height; - } - int scaledWidth = qRound(scale*newWidth); - int scaledHeight = qRound(scale*newHeight); - - QPixmap result(scaledWidth, scaledHeight); - result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later - QCPPainter painter; - painter.begin(&result); - if (painter.isActive()) - { - QRect oldViewport = viewport(); - setViewport(QRect(0, 0, newWidth, newHeight)); - painter.setMode(QCPPainter::pmNoCaching); - if (!qFuzzyCompare(scale, 1.0)) - { - if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales - painter.setMode(QCPPainter::pmNonCosmetic); - painter.scale(scale, scale); - } - if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill - painter.fillRect(mViewport, mBackgroundBrush); - draw(&painter); - setViewport(oldViewport); - painter.end(); - } else // might happen if pixmap has width or height zero - { - qDebug() << Q_FUNC_INFO << "Couldn't activate painter on pixmap"; - return QPixmap(); - } - return result; -} - -/*! - Renders the plot using the passed \a painter. - - The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will - appear scaled accordingly. - - \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter - on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with - the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. - - \see toPixmap -*/ -void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) -{ - // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too. - int newWidth, newHeight; - if (width == 0 || height == 0) - { - newWidth = this->width(); - newHeight = this->height(); - } else - { - newWidth = width; - newHeight = height; - } - - if (painter->isActive()) - { - QRect oldViewport = viewport(); - setViewport(QRect(0, 0, newWidth, newHeight)); - painter->setMode(QCPPainter::pmNoCaching); - if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here - painter->fillRect(mViewport, mBackgroundBrush); - draw(painter); - setViewport(oldViewport); - } else - qDebug() << Q_FUNC_INFO << "Passed painter is not active"; -} -/* end of 'src/core.cpp' */ - -//amalgamation: add plottable1d.cpp - -/* including file 'src/colorgradient.cpp', size 24646 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPColorGradient -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPColorGradient - \brief Defines a color gradient for use with e.g. \ref QCPColorMap - - This class describes a color gradient which can be used to encode data with color. For example, - QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which - take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) - with a \a position from 0 to 1. In between these defined color positions, the - color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation. - - Alternatively, load one of the preset color gradients shown in the image below, with \ref - loadPreset, or by directly specifying the preset in the constructor. - - Apart from red, green and blue components, the gradient also interpolates the alpha values of the - configured color stops. This allows to display some portions of the data range as transparent in - the plot. - - \image html QCPColorGradient.png - - The \ref QCPColorGradient(GradientPreset preset) constructor allows directly converting a \ref - GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset - to all the \a setGradient methods, e.g.: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient - - The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the - color gradient shall be applied periodically (wrapping around) to data values that lie outside - the data range specified on the plottable instance can be controlled with \ref setPeriodic. -*/ - -/*! - Constructs a new, empty QCPColorGradient with no predefined color stops. You can add own color - stops with \ref setColorStopAt. - - The color level count is initialized to 350. -*/ -QCPColorGradient::QCPColorGradient() : - mLevelCount(350), - mColorInterpolation(ciRGB), - mPeriodic(false), - mColorBufferInvalidated(true) -{ - mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); -} - -/*! - Constructs a new QCPColorGradient initialized with the colors and color interpolation according - to \a preset. - - The color level count is initialized to 350. -*/ -QCPColorGradient::QCPColorGradient(GradientPreset preset) : - mLevelCount(350), - mColorInterpolation(ciRGB), - mPeriodic(false), - mColorBufferInvalidated(true) -{ - mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); - loadPreset(preset); -} - -/* undocumented operator */ -bool QCPColorGradient::operator==(const QCPColorGradient &other) const -{ - return ((other.mLevelCount == this->mLevelCount) && - (other.mColorInterpolation == this->mColorInterpolation) && - (other.mPeriodic == this->mPeriodic) && - (other.mColorStops == this->mColorStops)); -} - -/*! - Sets the number of discretization levels of the color gradient to \a n. The default is 350 which - is typically enough to create a smooth appearance. The minimum number of levels is 2. - - \image html QCPColorGradient-levelcount.png -*/ -void QCPColorGradient::setLevelCount(int n) -{ - if (n < 2) - { - qDebug() << Q_FUNC_INFO << "n must be greater or equal 2 but was" << n; - n = 2; - } - if (n != mLevelCount) - { - mLevelCount = n; - mColorBufferInvalidated = true; - } -} - -/*! - Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the - colors are the values of the passed QMap \a colorStops. In between these color stops, the color - is interpolated according to \ref setColorInterpolation. - - A more convenient way to create a custom gradient may be to clear all color stops with \ref - clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with - \ref setColorStopAt. - - \see clearColorStops -*/ -void QCPColorGradient::setColorStops(const QMap &colorStops) -{ - mColorStops = colorStops; - mColorBufferInvalidated = true; -} - -/*! - Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between - these color stops, the color is interpolated according to \ref setColorInterpolation. - - \see setColorStops, clearColorStops -*/ -void QCPColorGradient::setColorStopAt(double position, const QColor &color) -{ - mColorStops.insert(position, color); - mColorBufferInvalidated = true; -} - -/*! - Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be - interpolated linearly in RGB or in HSV color space. - - For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, - whereas in HSV space the intermediate color is yellow. -*/ -void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation) -{ - if (interpolation != mColorInterpolation) - { - mColorInterpolation = interpolation; - mColorBufferInvalidated = true; - } -} - -/*! - Sets whether data points that are outside the configured data range (e.g. \ref - QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether - they all have the same color, corresponding to the respective gradient boundary color. - - \image html QCPColorGradient-periodic.png - - As shown in the image above, gradients that have the same start and end color are especially - suitable for a periodic gradient mapping, since they produce smooth color transitions throughout - the color map. A preset that has this property is \ref gpHues. - - In practice, using periodic color gradients makes sense when the data corresponds to a periodic - dimension, such as an angle or a phase. If this is not the case, the color encoding might become - ambiguous, because multiple different data values are shown as the same color. -*/ -void QCPColorGradient::setPeriodic(bool enabled) -{ - mPeriodic = enabled; -} - -/*! \overload - - This method is used to quickly convert a \a data array to colors. The colors will be output in - the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this - function. The data range that shall be used for mapping the data value to the gradient is passed - in \a range. \a logarithmic indicates whether the data values shall be mapped to colors - logarithmically. - - if \a data actually contains 2D-data linearized via [row*columnCount + column], you can - set \a dataIndexFactor to columnCount to convert a column instead of a row of the data - array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data - is addressed data[i*dataIndexFactor]. - - Use the overloaded method to additionally provide alpha map data. - - The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied - with alpha (see QImage::Format_ARGB32_Premultiplied). -*/ -void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) -{ - // If you change something here, make sure to also adapt color() and the other colorize() overload - if (!data) - { - qDebug() << Q_FUNC_INFO << "null pointer given as data"; - return; - } - if (!scanLine) - { - qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; - return; - } - if (mColorBufferInvalidated) - updateColorBuffer(); - - if (!logarithmic) - { - const double posToIndexFactor = (mLevelCount-1)/range.size(); - if (mPeriodic) - { - for (int i=0; i= mLevelCount) - index = mLevelCount-1; - scanLine[i] = mColorBuffer.at(index); - } - } - } else // logarithmic == true - { - if (mPeriodic) - { - for (int i=0; i= mLevelCount) - index = mLevelCount-1; - scanLine[i] = mColorBuffer.at(index); - } - } - } -} - -/*! \overload - - Additionally to the other overload of \ref colorize, this method takes the array \a alpha, which - has the same size and structure as \a data and encodes the alpha information per data point. - - The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied - with alpha (see QImage::Format_ARGB32_Premultiplied). -*/ -void QCPColorGradient::colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) -{ - // If you change something here, make sure to also adapt color() and the other colorize() overload - if (!data) - { - qDebug() << Q_FUNC_INFO << "null pointer given as data"; - return; - } - if (!alpha) - { - qDebug() << Q_FUNC_INFO << "null pointer given as alpha"; - return; - } - if (!scanLine) - { - qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; - return; - } - if (mColorBufferInvalidated) - updateColorBuffer(); - - if (!logarithmic) - { - const double posToIndexFactor = (mLevelCount-1)/range.size(); - if (mPeriodic) - { - for (int i=0; i= mLevelCount) - index = mLevelCount-1; - if (alpha[dataIndexFactor*i] == 255) - { - scanLine[i] = mColorBuffer.at(index); - } else - { - const QRgb rgb = mColorBuffer.at(index); - const float alphaF = alpha[dataIndexFactor*i]/255.0f; - scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); - } - } - } - } else // logarithmic == true - { - if (mPeriodic) - { - for (int i=0; i= mLevelCount) - index = mLevelCount-1; - if (alpha[dataIndexFactor*i] == 255) - { - scanLine[i] = mColorBuffer.at(index); - } else - { - const QRgb rgb = mColorBuffer.at(index); - const float alphaF = alpha[dataIndexFactor*i]/255.0f; - scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); - } - } - } - } -} - -/*! \internal - - This method is used to colorize a single data value given in \a position, to colors. The data - range that shall be used for mapping the data value to the gradient is passed in \a range. \a - logarithmic indicates whether the data value shall be mapped to a color logarithmically. - - If an entire array of data values shall be converted, rather use \ref colorize, for better - performance. - - The returned QRgb has its r, g and b components premultiplied with alpha (see - QImage::Format_ARGB32_Premultiplied). -*/ -QRgb QCPColorGradient::color(double position, const QCPRange &range, bool logarithmic) -{ - // If you change something here, make sure to also adapt ::colorize() - if (mColorBufferInvalidated) - updateColorBuffer(); - int index = 0; - if (!logarithmic) - index = (position-range.lower)*(mLevelCount-1)/range.size(); - else - index = qLn(position/range.lower)/qLn(range.upper/range.lower)*(mLevelCount-1); - if (mPeriodic) - { - index = index % mLevelCount; - if (index < 0) - index += mLevelCount; - } else - { - if (index < 0) - index = 0; - else if (index >= mLevelCount) - index = mLevelCount-1; - } - return mColorBuffer.at(index); -} - -/*! - Clears the current color stops and loads the specified \a preset. A preset consists of predefined - color stops and the corresponding color interpolation method. - - The available presets are: - \image html QCPColorGradient.png -*/ -void QCPColorGradient::loadPreset(GradientPreset preset) -{ - clearColorStops(); - switch (preset) - { - case gpGrayscale: - setColorInterpolation(ciRGB); - setColorStopAt(0, Qt::black); - setColorStopAt(1, Qt::white); - break; - case gpHot: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(50, 0, 0)); - setColorStopAt(0.2, QColor(180, 10, 0)); - setColorStopAt(0.4, QColor(245, 50, 0)); - setColorStopAt(0.6, QColor(255, 150, 10)); - setColorStopAt(0.8, QColor(255, 255, 50)); - setColorStopAt(1, QColor(255, 255, 255)); - break; - case gpCold: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(0, 0, 50)); - setColorStopAt(0.2, QColor(0, 10, 180)); - setColorStopAt(0.4, QColor(0, 50, 245)); - setColorStopAt(0.6, QColor(10, 150, 255)); - setColorStopAt(0.8, QColor(50, 255, 255)); - setColorStopAt(1, QColor(255, 255, 255)); - break; - case gpNight: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(10, 20, 30)); - setColorStopAt(1, QColor(250, 255, 250)); - break; - case gpCandy: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(0, 0, 255)); - setColorStopAt(1, QColor(255, 250, 250)); - break; - case gpGeography: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(70, 170, 210)); - setColorStopAt(0.20, QColor(90, 160, 180)); - setColorStopAt(0.25, QColor(45, 130, 175)); - setColorStopAt(0.30, QColor(100, 140, 125)); - setColorStopAt(0.5, QColor(100, 140, 100)); - setColorStopAt(0.6, QColor(130, 145, 120)); - setColorStopAt(0.7, QColor(140, 130, 120)); - setColorStopAt(0.9, QColor(180, 190, 190)); - setColorStopAt(1, QColor(210, 210, 230)); - break; - case gpIon: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(50, 10, 10)); - setColorStopAt(0.45, QColor(0, 0, 255)); - setColorStopAt(0.8, QColor(0, 255, 255)); - setColorStopAt(1, QColor(0, 255, 0)); - break; - case gpThermal: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(0, 0, 50)); - setColorStopAt(0.15, QColor(20, 0, 120)); - setColorStopAt(0.33, QColor(200, 30, 140)); - setColorStopAt(0.6, QColor(255, 100, 0)); - setColorStopAt(0.85, QColor(255, 255, 40)); - setColorStopAt(1, QColor(255, 255, 255)); - break; - case gpPolar: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(50, 255, 255)); - setColorStopAt(0.18, QColor(10, 70, 255)); - setColorStopAt(0.28, QColor(10, 10, 190)); - setColorStopAt(0.5, QColor(0, 0, 0)); - setColorStopAt(0.72, QColor(190, 10, 10)); - setColorStopAt(0.82, QColor(255, 70, 10)); - setColorStopAt(1, QColor(255, 255, 50)); - break; - case gpSpectrum: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(50, 0, 50)); - setColorStopAt(0.15, QColor(0, 0, 255)); - setColorStopAt(0.35, QColor(0, 255, 255)); - setColorStopAt(0.6, QColor(255, 255, 0)); - setColorStopAt(0.75, QColor(255, 30, 0)); - setColorStopAt(1, QColor(50, 0, 0)); - break; - case gpJet: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(0, 0, 100)); - setColorStopAt(0.15, QColor(0, 50, 255)); - setColorStopAt(0.35, QColor(0, 255, 255)); - setColorStopAt(0.65, QColor(255, 255, 0)); - setColorStopAt(0.85, QColor(255, 30, 0)); - setColorStopAt(1, QColor(100, 0, 0)); - break; - case gpHues: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(255, 0, 0)); - setColorStopAt(1.0/3.0, QColor(0, 0, 255)); - setColorStopAt(2.0/3.0, QColor(0, 255, 0)); - setColorStopAt(1, QColor(255, 0, 0)); - break; - } -} - -/*! - Clears all color stops. - - \see setColorStops, setColorStopAt -*/ -void QCPColorGradient::clearColorStops() -{ - mColorStops.clear(); - mColorBufferInvalidated = true; -} - -/*! - Returns an inverted gradient. The inverted gradient has all properties as this \ref - QCPColorGradient, but the order of the color stops is inverted. - - \see setColorStops, setColorStopAt -*/ -QCPColorGradient QCPColorGradient::inverted() const -{ - QCPColorGradient result(*this); - result.clearColorStops(); - for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) - result.setColorStopAt(1.0-it.key(), it.value()); - return result; -} - -/*! \internal - - Returns true if the color gradient uses transparency, i.e. if any of the configured color stops - has an alpha value below 255. -*/ -bool QCPColorGradient::stopsUseAlpha() const -{ - for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) - { - if (it.value().alpha() < 255) - return true; - } - return false; -} - -/*! \internal - - Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly - convert positions to colors. This is where the interpolation between color stops is calculated. -*/ -void QCPColorGradient::updateColorBuffer() -{ - if (mColorBuffer.size() != mLevelCount) - mColorBuffer.resize(mLevelCount); - if (mColorStops.size() > 1) - { - double indexToPosFactor = 1.0/(double)(mLevelCount-1); - const bool useAlpha = stopsUseAlpha(); - for (int i=0; i::const_iterator it = mColorStops.lowerBound(position); - if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop - { - mColorBuffer[i] = (it-1).value().rgba(); - } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop - { - mColorBuffer[i] = it.value().rgba(); - } else // position is in between stops (or on an intermediate stop), interpolate color - { - QMap::const_iterator high = it; - QMap::const_iterator low = it-1; - double t = (position-low.key())/(high.key()-low.key()); // interpolation factor 0..1 - switch (mColorInterpolation) - { - case ciRGB: - { - if (useAlpha) - { - const int alpha = (1-t)*low.value().alpha() + t*high.value().alpha(); - const float alphaPremultiplier = alpha/255.0f; // since we use QImage::Format_ARGB32_Premultiplied - mColorBuffer[i] = qRgba(((1-t)*low.value().red() + t*high.value().red())*alphaPremultiplier, - ((1-t)*low.value().green() + t*high.value().green())*alphaPremultiplier, - ((1-t)*low.value().blue() + t*high.value().blue())*alphaPremultiplier, - alpha); - } else - { - mColorBuffer[i] = qRgb(((1-t)*low.value().red() + t*high.value().red()), - ((1-t)*low.value().green() + t*high.value().green()), - ((1-t)*low.value().blue() + t*high.value().blue())); - } - break; - } - case ciHSV: - { - QColor lowHsv = low.value().toHsv(); - QColor highHsv = high.value().toHsv(); - double hue = 0; - double hueDiff = highHsv.hueF()-lowHsv.hueF(); - if (hueDiff > 0.5) - hue = lowHsv.hueF() - t*(1.0-hueDiff); - else if (hueDiff < -0.5) - hue = lowHsv.hueF() + t*(1.0+hueDiff); - else - hue = lowHsv.hueF() + t*hueDiff; - if (hue < 0) hue += 1.0; - else if (hue >= 1.0) hue -= 1.0; - if (useAlpha) - { - const QRgb rgb = QColor::fromHsvF(hue, - (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), - (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); - const float alpha = (1-t)*lowHsv.alphaF() + t*highHsv.alphaF(); - mColorBuffer[i] = qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha); - } - else - { - mColorBuffer[i] = QColor::fromHsvF(hue, - (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), - (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); - } - break; - } - } - } - } - } else if (mColorStops.size() == 1) - { - const QRgb rgb = mColorStops.constBegin().value().rgb(); - const float alpha = mColorStops.constBegin().value().alphaF(); - mColorBuffer.fill(qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha)); - } else // mColorStops is empty, fill color buffer with black - { - mColorBuffer.fill(qRgb(0, 0, 0)); - } - mColorBufferInvalidated = false; -} -/* end of 'src/colorgradient.cpp' */ - - -/* including file 'src/selectiondecorator-bracket.cpp', size 12313 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPSelectionDecoratorBracket -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPSelectionDecoratorBracket - \brief A selection decorator which draws brackets around each selected data segment - - Additionally to the regular highlighting of selected segments via color, fill and scatter style, - this \ref QCPSelectionDecorator subclass draws markers at the begin and end of each selected data - segment of the plottable. - - The shape of the markers can be controlled with \ref setBracketStyle, \ref setBracketWidth and - \ref setBracketHeight. The color/fill can be controlled with \ref setBracketPen and \ref - setBracketBrush. - - To introduce custom bracket styles, it is only necessary to sublcass \ref - QCPSelectionDecoratorBracket and reimplement \ref drawBracket. The rest will be managed by the - base class. -*/ - -/*! - Creates a new QCPSelectionDecoratorBracket instance with default values. -*/ -QCPSelectionDecoratorBracket::QCPSelectionDecoratorBracket() : - mBracketPen(QPen(Qt::black)), - mBracketBrush(Qt::NoBrush), - mBracketWidth(5), - mBracketHeight(50), - mBracketStyle(bsSquareBracket), - mTangentToData(false), - mTangentAverage(2) -{ - -} - -QCPSelectionDecoratorBracket::~QCPSelectionDecoratorBracket() -{ -} - -/*! - Sets the pen that will be used to draw the brackets at the beginning and end of each selected - data segment. -*/ -void QCPSelectionDecoratorBracket::setBracketPen(const QPen &pen) -{ - mBracketPen = pen; -} - -/*! - Sets the brush that will be used to draw the brackets at the beginning and end of each selected - data segment. -*/ -void QCPSelectionDecoratorBracket::setBracketBrush(const QBrush &brush) -{ - mBracketBrush = brush; -} - -/*! - Sets the width of the drawn bracket. The width dimension is always parallel to the key axis of - the data, or the tangent direction of the current data slope, if \ref setTangentToData is - enabled. -*/ -void QCPSelectionDecoratorBracket::setBracketWidth(int width) -{ - mBracketWidth = width; -} - -/*! - Sets the height of the drawn bracket. The height dimension is always perpendicular to the key axis - of the data, or the tangent direction of the current data slope, if \ref setTangentToData is - enabled. -*/ -void QCPSelectionDecoratorBracket::setBracketHeight(int height) -{ - mBracketHeight = height; -} - -/*! - Sets the shape that the bracket/marker will have. - - \see setBracketWidth, setBracketHeight -*/ -void QCPSelectionDecoratorBracket::setBracketStyle(QCPSelectionDecoratorBracket::BracketStyle style) -{ - mBracketStyle = style; -} - -/*! - Sets whether the brackets will be rotated such that they align with the slope of the data at the - position that they appear in. - - For noisy data, it might be more visually appealing to average the slope over multiple data - points. This can be configured via \ref setTangentAverage. -*/ -void QCPSelectionDecoratorBracket::setTangentToData(bool enabled) -{ - mTangentToData = enabled; -} - -/*! - Controls over how many data points the slope shall be averaged, when brackets shall be aligned - with the data (if \ref setTangentToData is true). - - From the position of the bracket, \a pointCount points towards the selected data range will be - taken into account. The smallest value of \a pointCount is 1, which is effectively equivalent to - disabling \ref setTangentToData. -*/ -void QCPSelectionDecoratorBracket::setTangentAverage(int pointCount) -{ - mTangentAverage = pointCount; - if (mTangentAverage < 1) - mTangentAverage = 1; -} - -/*! - Draws the bracket shape with \a painter. The parameter \a direction is either -1 or 1 and - indicates whether the bracket shall point to the left or the right (i.e. is a closing or opening - bracket, respectively). - - The passed \a painter already contains all transformations that are necessary to position and - rotate the bracket appropriately. Painting operations can be performed as if drawing upright - brackets on flat data with horizontal key axis, with (0, 0) being the center of the bracket. - - If you wish to sublcass \ref QCPSelectionDecoratorBracket in order to provide custom bracket - shapes (see \ref QCPSelectionDecoratorBracket::bsUserStyle), this is the method you should - reimplement. -*/ -void QCPSelectionDecoratorBracket::drawBracket(QCPPainter *painter, int direction) const -{ - switch (mBracketStyle) - { - case bsSquareBracket: - { - painter->drawLine(QLineF(mBracketWidth*direction, -mBracketHeight*0.5, 0, -mBracketHeight*0.5)); - painter->drawLine(QLineF(mBracketWidth*direction, mBracketHeight*0.5, 0, mBracketHeight*0.5)); - painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); - break; - } - case bsHalfEllipse: - { - painter->drawArc(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight, -90*16, -180*16*direction); - break; - } - case bsEllipse: - { - painter->drawEllipse(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight); - break; - } - case bsPlus: - { - painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); - painter->drawLine(QLineF(-mBracketWidth*0.5, 0, mBracketWidth*0.5, 0)); - break; - } - default: - { - qDebug() << Q_FUNC_INFO << "unknown/custom bracket style can't be handeld by default implementation:" << static_cast(mBracketStyle); - break; - } - } -} - -/*! - Draws the bracket decoration on the data points at the begin and end of each selected data - segment given in \a seletion. - - It uses the method \ref drawBracket to actually draw the shapes. - - \seebaseclassmethod -*/ -void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSelection selection) -{ - if (!mPlottable || selection.isEmpty()) return; - - if (QCPPlottableInterface1D *interface1d = mPlottable->interface1D()) - { - foreach (const QCPDataRange &dataRange, selection.dataRanges()) - { - // determine position and (if tangent mode is enabled) angle of brackets: - int openBracketDir = (mPlottable->keyAxis() && !mPlottable->keyAxis()->rangeReversed()) ? 1 : -1; - int closeBracketDir = -openBracketDir; - QPointF openBracketPos = getPixelCoordinates(interface1d, dataRange.begin()); - QPointF closeBracketPos = getPixelCoordinates(interface1d, dataRange.end()-1); - double openBracketAngle = 0; - double closeBracketAngle = 0; - if (mTangentToData) - { - openBracketAngle = getTangentAngle(interface1d, dataRange.begin(), openBracketDir); - closeBracketAngle = getTangentAngle(interface1d, dataRange.end()-1, closeBracketDir); - } - // draw opening bracket: - QTransform oldTransform = painter->transform(); - painter->setPen(mBracketPen); - painter->setBrush(mBracketBrush); - painter->translate(openBracketPos); - painter->rotate(openBracketAngle/M_PI*180.0); - drawBracket(painter, openBracketDir); - painter->setTransform(oldTransform); - // draw closing bracket: - painter->setPen(mBracketPen); - painter->setBrush(mBracketBrush); - painter->translate(closeBracketPos); - painter->rotate(closeBracketAngle/M_PI*180.0); - drawBracket(painter, closeBracketDir); - painter->setTransform(oldTransform); - } - } -} - -/*! \internal - - If \ref setTangentToData is enabled, brackets need to be rotated according to the data slope. - This method returns the angle in radians by which a bracket at the given \a dataIndex must be - rotated. - - The parameter \a direction must be set to either -1 or 1, representing whether it is an opening - or closing bracket. Since for slope calculation multiple data points are required, this defines - the direction in which the algorithm walks, starting at \a dataIndex, to average those data - points. (see \ref setTangentToData and \ref setTangentAverage) - - \a interface1d is the interface to the plottable's data which is used to query data coordinates. -*/ -double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const -{ - if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->dataCount()) - return 0; - direction = direction < 0 ? -1 : 1; // enforce direction is either -1 or 1 - - // how many steps we can actually go from index in the given direction without exceeding data bounds: - int averageCount; - if (direction < 0) - averageCount = qMin(mTangentAverage, dataIndex); - else - averageCount = qMin(mTangentAverage, interface1d->dataCount()-1-dataIndex); - qDebug() << averageCount; - // calculate point average of averageCount points: - QVector points(averageCount); - QPointF pointsAverage; - int currentIndex = dataIndex; - for (int i=0; ikeyAxis(); - QCPAxis *valueAxis = mPlottable->valueAxis(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(0, 0); } - - if (keyAxis->orientation() == Qt::Horizontal) - return QPointF(keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))); - else - return QPointF(valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex)), keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex))); -} -/* end of 'src/selectiondecorator-bracket.cpp' */ - - -/* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47584 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisRect -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAxisRect - \brief Holds multiple axes and arranges them in a rectangular shape. - - This class represents an axis rect, a rectangular area that is bounded on all sides with an - arbitrary number of axes. - - Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the - layout system allows to have multiple axis rects, e.g. arranged in a grid layout - (QCustomPlot::plotLayout). - - By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be - accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. - If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be - invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref - addAxes. To remove an axis, use \ref removeAxis. - - The axis rect layerable itself only draws a background pixmap or color, if specified (\ref - setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an - explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be - placed on other layers, independently of the axis rect. - - Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref - insetLayout and can be used to have other layout elements (or even other layouts with multiple - elements) hovering inside the axis rect. - - If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The - behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel - is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable - via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are - only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref - QCP::iRangeZoom. - - \image html AxisRectSpacingOverview.png -
Overview of the spacings and paddings that define the geometry of an axis. The dashed - line on the far left indicates the viewport/widget border.
-*/ - -/* start documentation of inline functions */ - -/*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const - - Returns the inset layout of this axis rect. It can be used to place other layout elements (or - even layouts with multiple other elements) inside/on top of an axis rect. - - \see QCPLayoutInset -*/ - -/*! \fn int QCPAxisRect::left() const - - Returns the pixel position of the left border of this axis rect. Margins are not taken into - account here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::right() const - - Returns the pixel position of the right border of this axis rect. Margins are not taken into - account here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::top() const - - Returns the pixel position of the top border of this axis rect. Margins are not taken into - account here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::bottom() const - - Returns the pixel position of the bottom border of this axis rect. Margins are not taken into - account here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::width() const - - Returns the pixel width of this axis rect. Margins are not taken into account here, so the - returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::height() const - - Returns the pixel height of this axis rect. Margins are not taken into account here, so the - returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QSize QCPAxisRect::size() const - - Returns the pixel size of this axis rect. Margins are not taken into account here, so the - returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::topLeft() const - - Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, - so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::topRight() const - - Returns the top right corner of this axis rect in pixels. Margins are not taken into account - here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::bottomLeft() const - - Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account - here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::bottomRight() const - - Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account - here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::center() const - - Returns the center of this axis rect in pixels. Margins are not taken into account here, so the - returned value is with respect to the inner \ref rect. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a QCPAxisRect instance and sets default values. An axis is added for each of the four - sides, the top and right axes are set invisible initially. -*/ -QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : - QCPLayoutElement(parentPlot), - mBackgroundBrush(Qt::NoBrush), - mBackgroundScaled(true), - mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), - mInsetLayout(new QCPLayoutInset), - mRangeDrag(Qt::Horizontal|Qt::Vertical), - mRangeZoom(Qt::Horizontal|Qt::Vertical), - mRangeZoomFactorHorz(0.85), - mRangeZoomFactorVert(0.85), - mDragging(false), - mIsScaleRight(false) -{ - mInsetLayout->initializeParentPlot(mParentPlot); - mInsetLayout->setParentLayerable(this); - mInsetLayout->setParent(this); - - setMinimumSize(50, 50); - setMinimumMargins(QMargins(15, 15, 15, 15)); - mAxes.insert(QCPAxis::atLeft, QList()); - mAxes.insert(QCPAxis::atRight, QList()); - mAxes.insert(QCPAxis::atTop, QList()); - mAxes.insert(QCPAxis::atBottom, QList()); - - if (setupDefaultAxes) - { - QCPAxis *xAxis = addAxis(QCPAxis::atBottom); - QCPAxis *yAxis = addAxis(QCPAxis::atLeft); - QCPAxis *xAxis2 = addAxis(QCPAxis::atTop); - QCPAxis *yAxis2 = addAxis(QCPAxis::atRight); - setRangeDragAxes(xAxis, yAxis); - setRangeZoomAxes(xAxis, yAxis); - xAxis2->setVisible(false); - yAxis2->setVisible(false); - xAxis->grid()->setVisible(true); - yAxis->grid()->setVisible(true); - xAxis2->grid()->setVisible(false); - yAxis2->grid()->setVisible(false); - xAxis2->grid()->setZeroLinePen(Qt::NoPen); - yAxis2->grid()->setZeroLinePen(Qt::NoPen); - xAxis2->grid()->setVisible(false); - yAxis2->grid()->setVisible(false); - } -} - -QCPAxisRect::~QCPAxisRect() -{ - delete mInsetLayout; - mInsetLayout = 0; - - QList axesList = axes(); - for (int i=0; i ax(mAxes.value(type)); - if (index >= 0 && index < ax.size()) - { - return ax.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; - return 0; - } -} - -/*! - Returns all axes on the axis rect sides specified with \a types. - - \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of - multiple sides. - - \see axis -*/ -QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const -{ - QList result; - if (types.testFlag(QCPAxis::atLeft)) - result << mAxes.value(QCPAxis::atLeft); - if (types.testFlag(QCPAxis::atRight)) - result << mAxes.value(QCPAxis::atRight); - if (types.testFlag(QCPAxis::atTop)) - result << mAxes.value(QCPAxis::atTop); - if (types.testFlag(QCPAxis::atBottom)) - result << mAxes.value(QCPAxis::atBottom); - return result; -} - -/*! \overload - - Returns all axes of this axis rect. -*/ -QList QCPAxisRect::axes() const -{ - QList result; - QHashIterator > it(mAxes); - while (it.hasNext()) - { - it.next(); - result << it.value(); - } - return result; -} - -/*! - Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a - new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to - remove an axis, use \ref removeAxis instead of deleting it manually. - - You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was - previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership - of the axis, so you may not delete it afterwards. Further, the \a axis must have been created - with this axis rect as parent and with the same axis type as specified in \a type. If this is not - the case, a debug output is generated, the axis is not added, and the method returns 0. - - This method can not be used to move \a axis between axis rects. The same \a axis instance must - not be added multiple times to the same or different axis rects. - - If an axis rect side already contains one or more axes, the lower and upper endings of the new - axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref - QCPLineEnding::esHalfBar. - - \see addAxes, setupFullAxesBox -*/ -QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) -{ - QCPAxis *newAxis = axis; - if (!newAxis) - { - newAxis = new QCPAxis(this, type); - } else // user provided existing axis instance, do some sanity checks - { - if (newAxis->axisType() != type) - { - qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter"; - return 0; - } - if (newAxis->axisRect() != this) - { - qDebug() << Q_FUNC_INFO << "passed axis doesn't have this axis rect as parent axis rect"; - return 0; - } - if (axes().contains(newAxis)) - { - qDebug() << Q_FUNC_INFO << "passed axis is already owned by this axis rect"; - return 0; - } - } - if (mAxes[type].size() > 0) // multiple axes on one side, add half-bar axis ending to additional axes with offset - { - bool invert = (type == QCPAxis::atRight) || (type == QCPAxis::atBottom); - newAxis->setLowerEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, !invert)); - newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); - } - mAxes[type].append(newAxis); - - // reset convenience axis pointers on parent QCustomPlot if they are unset: - if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) - { - switch (type) - { - case QCPAxis::atBottom: { if (!mParentPlot->xAxis) mParentPlot->xAxis = newAxis; break; } - case QCPAxis::atLeft: { if (!mParentPlot->yAxis) mParentPlot->yAxis = newAxis; break; } - case QCPAxis::atTop: { if (!mParentPlot->xAxis2) mParentPlot->xAxis2 = newAxis; break; } - case QCPAxis::atRight: { if (!mParentPlot->yAxis2) mParentPlot->yAxis2 = newAxis; break; } - } - } - - return newAxis; -} - -/*! - Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an - or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. - - Returns a list of the added axes. - - \see addAxis, setupFullAxesBox -*/ -QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) -{ - QList result; - if (types.testFlag(QCPAxis::atLeft)) - result << addAxis(QCPAxis::atLeft); - if (types.testFlag(QCPAxis::atRight)) - result << addAxis(QCPAxis::atRight); - if (types.testFlag(QCPAxis::atTop)) - result << addAxis(QCPAxis::atTop); - if (types.testFlag(QCPAxis::atBottom)) - result << addAxis(QCPAxis::atBottom); - return result; -} - -/*! - Removes the specified \a axis from the axis rect and deletes it. - - Returns true on success, i.e. if \a axis was a valid axis in this axis rect. - - \see addAxis -*/ -bool QCPAxisRect::removeAxis(QCPAxis *axis) -{ - // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers: - QHashIterator > it(mAxes); - while (it.hasNext()) - { - it.next(); - if (it.value().contains(axis)) - { - if (it.value().first() == axis && it.value().size() > 1) // if removing first axis, transfer axis offset to the new first axis (which at this point is the second axis, if it exists) - it.value()[1]->setOffset(axis->offset()); - mAxes[it.key()].removeOne(axis); - if (qobject_cast(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot) - parentPlot()->axisRemoved(axis); - delete axis; - return true; - } - } - qDebug() << Q_FUNC_INFO << "Axis isn't in axis rect:" << reinterpret_cast(axis); - return false; -} - -/*! - Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. - - All axes of this axis rect will have their range zoomed accordingly. If you only wish to zoom - specific axes, use the overloaded version of this method. - - \see QCustomPlot::setSelectionRectMode -*/ -void QCPAxisRect::zoom(const QRectF &pixelRect) -{ - zoom(pixelRect, axes()); -} - -/*! \overload - - Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. - - Only the axes passed in \a affectedAxes will have their ranges zoomed accordingly. - - \see QCustomPlot::setSelectionRectMode -*/ -void QCPAxisRect::zoom(const QRectF &pixelRect, const QList &affectedAxes) -{ - foreach (QCPAxis *axis, affectedAxes) - { - if (!axis) - { - qDebug() << Q_FUNC_INFO << "a passed axis was zero"; - continue; - } - QCPRange pixelRange; - if (axis->orientation() == Qt::Horizontal) - pixelRange = QCPRange(pixelRect.left(), pixelRect.right()); - else - pixelRange = QCPRange(pixelRect.top(), pixelRect.bottom()); - axis->setRange(axis->pixelToCoord(pixelRange.lower), axis->pixelToCoord(pixelRange.upper)); - } -} - -/*! - Convenience function to create an axis on each side that doesn't have any axes yet and set their - visibility to true. Further, the top/right axes are assigned the following properties of the - bottom/left axes: - - \li range (\ref QCPAxis::setRange) - \li range reversed (\ref QCPAxis::setRangeReversed) - \li scale type (\ref QCPAxis::setScaleType) - \li tick visibility (\ref QCPAxis::setTicks) - \li number format (\ref QCPAxis::setNumberFormat) - \li number precision (\ref QCPAxis::setNumberPrecision) - \li tick count of ticker (\ref QCPAxisTicker::setTickCount) - \li tick origin of ticker (\ref QCPAxisTicker::setTickOrigin) - - Tick label visibility (\ref QCPAxis::setTickLabels) of the right and top axes are set to false. - - If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom - and left axes are connected to the \ref QCPAxis::setRange slots of the top and right axes. -*/ -void QCPAxisRect::setupFullAxesBox(bool connectRanges) -{ - QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; - if (axisCount(QCPAxis::atBottom) == 0) - xAxis = addAxis(QCPAxis::atBottom); - else - xAxis = axis(QCPAxis::atBottom); - - if (axisCount(QCPAxis::atLeft) == 0) - yAxis = addAxis(QCPAxis::atLeft); - else - yAxis = axis(QCPAxis::atLeft); - - if (axisCount(QCPAxis::atTop) == 0) - xAxis2 = addAxis(QCPAxis::atTop); - else - xAxis2 = axis(QCPAxis::atTop); - - if (axisCount(QCPAxis::atRight) == 0) - yAxis2 = addAxis(QCPAxis::atRight); - else - yAxis2 = axis(QCPAxis::atRight); - - xAxis->setVisible(true); - yAxis->setVisible(true); - xAxis2->setVisible(true); - yAxis2->setVisible(true); - xAxis2->setTickLabels(false); - yAxis2->setTickLabels(false); - - xAxis2->setRange(xAxis->range()); - xAxis2->setRangeReversed(xAxis->rangeReversed()); - xAxis2->setScaleType(xAxis->scaleType()); - xAxis2->setTicks(xAxis->ticks()); - xAxis2->setNumberFormat(xAxis->numberFormat()); - xAxis2->setNumberPrecision(xAxis->numberPrecision()); - xAxis2->ticker()->setTickCount(xAxis->ticker()->tickCount()); - xAxis2->ticker()->setTickOrigin(xAxis->ticker()->tickOrigin()); - - yAxis2->setRange(yAxis->range()); - yAxis2->setRangeReversed(yAxis->rangeReversed()); - yAxis2->setScaleType(yAxis->scaleType()); - yAxis2->setTicks(yAxis->ticks()); - yAxis2->setNumberFormat(yAxis->numberFormat()); - yAxis2->setNumberPrecision(yAxis->numberPrecision()); - yAxis2->ticker()->setTickCount(yAxis->ticker()->tickCount()); - yAxis2->ticker()->setTickOrigin(yAxis->ticker()->tickOrigin()); - - if (connectRanges) - { - connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); - connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); - } -} - -/*! - Returns a list of all the plottables that are associated with this axis rect. - - A plottable is considered associated with an axis rect if its key or value axis (or both) is in - this axis rect. - - \see graphs, items -*/ -QList QCPAxisRect::plottables() const -{ - // Note: don't append all QCPAxis::plottables() into a list, because we might get duplicate entries - QList result; - for (int i=0; imPlottables.size(); ++i) - { - if (mParentPlot->mPlottables.at(i)->keyAxis()->axisRect() == this || mParentPlot->mPlottables.at(i)->valueAxis()->axisRect() == this) - result.append(mParentPlot->mPlottables.at(i)); - } - return result; -} - -/*! - Returns a list of all the graphs that are associated with this axis rect. - - A graph is considered associated with an axis rect if its key or value axis (or both) is in - this axis rect. - - \see plottables, items -*/ -QList QCPAxisRect::graphs() const -{ - // Note: don't append all QCPAxis::graphs() into a list, because we might get duplicate entries - QList result; - for (int i=0; imGraphs.size(); ++i) - { - if (mParentPlot->mGraphs.at(i)->keyAxis()->axisRect() == this || mParentPlot->mGraphs.at(i)->valueAxis()->axisRect() == this) - result.append(mParentPlot->mGraphs.at(i)); - } - return result; -} - -/*! - Returns a list of all the items that are associated with this axis rect. - - An item is considered associated with an axis rect if any of its positions has key or value axis - set to an axis that is in this axis rect, or if any of its positions has \ref - QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref - QCPAbstractItem::setClipAxisRect) is set to this axis rect. - - \see plottables, graphs -*/ -QList QCPAxisRect::items() const -{ - // Note: don't just append all QCPAxis::items() into a list, because we might get duplicate entries - // and miss those items that have this axis rect as clipAxisRect. - QList result; - for (int itemId=0; itemIdmItems.size(); ++itemId) - { - if (mParentPlot->mItems.at(itemId)->clipAxisRect() == this) - { - result.append(mParentPlot->mItems.at(itemId)); - continue; - } - QList positions = mParentPlot->mItems.at(itemId)->positions(); - for (int posId=0; posIdaxisRect() == this || - positions.at(posId)->keyAxis()->axisRect() == this || - positions.at(posId)->valueAxis()->axisRect() == this) - { - result.append(mParentPlot->mItems.at(itemId)); - break; - } - } - } - return result; -} - -/*! - This method is called automatically upon replot and doesn't need to be called by users of - QCPAxisRect. - - Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), - and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its - QCPInsetLayout::update function. - - \seebaseclassmethod -*/ -void QCPAxisRect::update(UpdatePhase phase) -{ - QCPLayoutElement::update(phase); - - switch (phase) - { - case upPreparation: - { - QList allAxes = axes(); - for (int i=0; isetupTickVectors(); - break; - } - case upLayout: - { - mInsetLayout->setOuterRect(rect()); - break; - } - default: break; - } - - // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): - mInsetLayout->update(phase); -} - -/* inherits documentation from base class */ -QList QCPAxisRect::elements(bool recursive) const -{ - QList result; - if (mInsetLayout) - { - result << mInsetLayout; - if (recursive) - result << mInsetLayout->elements(recursive); - } - return result; -} - -/* inherits documentation from base class */ -void QCPAxisRect::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - painter->setAntialiasing(false); -} - -/* inherits documentation from base class */ -void QCPAxisRect::draw(QCPPainter *painter) -{ - drawBackground(painter); -} - -/*! - Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the - axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect - backgrounds are usually drawn below everything else. - - For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be - enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio - is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, - consider using the overloaded version of this function. - - Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref - setBackground(const QBrush &brush). - - \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) -*/ -void QCPAxisRect::setBackground(const QPixmap &pm) -{ - mBackgroundPixmap = pm; - mScaledBackgroundPixmap = QPixmap(); -} - -/*! \overload - - Sets \a brush as the background brush. The axis rect background will be filled with this brush. - Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds - are usually drawn below everything else. - - The brush will be drawn before (under) any background pixmap, which may be specified with \ref - setBackground(const QPixmap &pm). - - To disable drawing of a background brush, set \a brush to Qt::NoBrush. - - \see setBackground(const QPixmap &pm) -*/ -void QCPAxisRect::setBackground(const QBrush &brush) -{ - mBackgroundBrush = brush; -} - -/*! \overload - - Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it - shall be scaled in one call. - - \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode -*/ -void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) -{ - mBackgroundPixmap = pm; - mScaledBackgroundPixmap = QPixmap(); - mBackgroundScaled = scaled; - mBackgroundScaledMode = mode; -} - -/*! - Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled - is set to true, you may control whether and how the aspect ratio of the original pixmap is - preserved with \ref setBackgroundScaledMode. - - Note that the scaled version of the original pixmap is buffered, so there is no performance - penalty on replots. (Except when the axis rect dimensions are changed continuously.) - - \see setBackground, setBackgroundScaledMode -*/ -void QCPAxisRect::setBackgroundScaled(bool scaled) -{ - mBackgroundScaled = scaled; -} - -/*! - If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to - define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. - \see setBackground, setBackgroundScaled -*/ -void QCPAxisRect::setBackgroundScaledMode(Qt::AspectRatioMode mode) -{ - mBackgroundScaledMode = mode; -} - -/*! - Returns the range drag axis of the \a orientation provided. If multiple axes were set, returns - the first one (use \ref rangeDragAxes to retrieve a list with all set axes). - - \see setRangeDragAxes -*/ -QCPAxis *QCPAxisRect::rangeDragAxis(Qt::Orientation orientation) -{ - if (orientation == Qt::Horizontal) - return mRangeDragHorzAxis.isEmpty() ? 0 : mRangeDragHorzAxis.first().data(); - else - return mRangeDragVertAxis.isEmpty() ? 0 : mRangeDragVertAxis.first().data(); -} - -/*! - Returns the range zoom axis of the \a orientation provided. If multiple axes were set, returns - the first one (use \ref rangeZoomAxes to retrieve a list with all set axes). - - \see setRangeZoomAxes -*/ -QCPAxis *QCPAxisRect::rangeZoomAxis(Qt::Orientation orientation) -{ - if (orientation == Qt::Horizontal) - return mRangeZoomHorzAxis.isEmpty() ? 0 : mRangeZoomHorzAxis.first().data(); - else - return mRangeZoomVertAxis.isEmpty() ? 0 : mRangeZoomVertAxis.first().data(); -} - -/*! - Returns all range drag axes of the \a orientation provided. - - \see rangeZoomAxis, setRangeZoomAxes -*/ -QList QCPAxisRect::rangeDragAxes(Qt::Orientation orientation) -{ - QList result; - if (orientation == Qt::Horizontal) - { - for (int i=0; i QCPAxisRect::rangeZoomAxes(Qt::Orientation orientation) -{ - QList result; - if (orientation == Qt::Horizontal) - { - for (int i=0; iQt::Horizontal | - Qt::Vertical as \a orientations. - - In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions - contains \ref QCP::iRangeDrag to enable the range dragging interaction. - - \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag -*/ -void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) -{ - mRangeDrag = orientations; -} - -/*! - Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation - corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, - QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical - axis is the left axis (yAxis). - - To disable range zooming entirely, pass 0 as \a orientations or remove \ref QCP::iRangeZoom from \ref - QCustomPlot::setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | - Qt::Vertical as \a orientations. - - In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions - contains \ref QCP::iRangeZoom to enable the range zooming interaction. - - \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag -*/ -void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) -{ - mRangeZoom = orientations; -} - -/*! \overload - - Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on - the QCustomPlot widget. Pass 0 if no axis shall be dragged in the respective orientation. - - Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall - react to dragging interactions. - - \see setRangeZoomAxes -*/ -void QCPAxisRect::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) -{ - QList horz, vert; - if (horizontal) - horz.append(horizontal); - if (vertical) - vert.append(vertical); - setRangeDragAxes(horz, vert); -} - -/*! \overload - - This method allows to set up multiple axes to react to horizontal and vertical dragging. The drag - orientation that the respective axis will react to is deduced from its orientation (\ref - QCPAxis::orientation). - - In the unusual case that you wish to e.g. drag a vertically oriented axis with a horizontal drag - motion, use the overload taking two separate lists for horizontal and vertical dragging. -*/ -void QCPAxisRect::setRangeDragAxes(QList axes) -{ - QList horz, vert; - foreach (QCPAxis *ax, axes) - { - if (ax->orientation() == Qt::Horizontal) - horz.append(ax); - else - vert.append(ax); - } - setRangeDragAxes(horz, vert); -} - -/*! \overload - - This method allows to set multiple axes up to react to horizontal and vertical dragging, and - define specifically which axis reacts to which drag orientation (irrespective of the axis - orientation). -*/ -void QCPAxisRect::setRangeDragAxes(QList horizontal, QList vertical) -{ - mRangeDragHorzAxis.clear(); - foreach (QCPAxis *ax, horizontal) - { - QPointer axPointer(ax); - if (!axPointer.isNull()) - mRangeDragHorzAxis.append(axPointer); - else - qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); - } - mRangeDragVertAxis.clear(); - foreach (QCPAxis *ax, vertical) - { - QPointer axPointer(ax); - if (!axPointer.isNull()) - mRangeDragVertAxis.append(axPointer); - else - qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); - } -} - -/*! - Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on - the QCustomPlot widget. Pass 0 if no axis shall be zoomed in the respective orientation. - - The two axes can be zoomed with different strengths, when different factors are passed to \ref - setRangeZoomFactor(double horizontalFactor, double verticalFactor). - - Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall - react to zooming interactions. - - \see setRangeDragAxes -*/ -void QCPAxisRect::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) -{ - QList horz, vert; - if (horizontal) - horz.append(horizontal); - if (vertical) - vert.append(vertical); - setRangeZoomAxes(horz, vert); -} - -/*! \overload - - This method allows to set up multiple axes to react to horizontal and vertical range zooming. The - zoom orientation that the respective axis will react to is deduced from its orientation (\ref - QCPAxis::orientation). - - In the unusual case that you wish to e.g. zoom a vertically oriented axis with a horizontal zoom - interaction, use the overload taking two separate lists for horizontal and vertical zooming. -*/ -void QCPAxisRect::setRangeZoomAxes(QList axes) -{ - QList horz, vert; - foreach (QCPAxis *ax, axes) - { - if (ax->orientation() == Qt::Horizontal) - horz.append(ax); - else - vert.append(ax); - } - setRangeZoomAxes(horz, vert); -} - -/*! \overload - - This method allows to set multiple axes up to react to horizontal and vertical zooming, and - define specifically which axis reacts to which zoom orientation (irrespective of the axis - orientation). -*/ -void QCPAxisRect::setRangeZoomAxes(QList horizontal, QList vertical) -{ - mRangeZoomHorzAxis.clear(); - foreach (QCPAxis *ax, horizontal) - { - QPointer axPointer(ax); - if (!axPointer.isNull()) - mRangeZoomHorzAxis.append(axPointer); - else - qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); - } - mRangeZoomVertAxis.clear(); - foreach (QCPAxis *ax, vertical) - { - QPointer axPointer(ax); - if (!axPointer.isNull()) - mRangeZoomVertAxis.append(axPointer); - else - qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); - } -} - -/*! - Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with - \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to - let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal - and which is vertical, can be set with \ref setRangeZoomAxes. - - When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) - will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the - same scrolling direction will zoom out. -*/ -void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFactor) -{ - mRangeZoomFactorHorz = horizontalFactor; - mRangeZoomFactorVert = verticalFactor; -} - -/*! \overload - - Sets both the horizontal and vertical zoom \a factor. -*/ -void QCPAxisRect::setRangeZoomFactor(double factor) -{ - mRangeZoomFactorHorz = factor; - mRangeZoomFactorVert = factor; -} - -/*! \internal - - Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a - pixmap. - - If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an - according filling inside the axis rect with the provided \a painter. - - Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version - depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside - the axis rect with the provided \a painter. The scaled version is buffered in - mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when - the axis rect has changed in a way that requires a rescale of the background pixmap (this is - dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was - set. - - \see setBackground, setBackgroundScaled, setBackgroundScaledMode -*/ -void QCPAxisRect::drawBackground(QCPPainter *painter) -{ - // draw background fill: - if (mBackgroundBrush != Qt::NoBrush) - painter->fillRect(mRect, mBackgroundBrush); - - // draw background pixmap (on top of fill, if brush specified): - if (!mBackgroundPixmap.isNull()) - { - if (mBackgroundScaled) - { - // check whether mScaledBackground needs to be updated: - QSize scaledSize(mBackgroundPixmap.size()); - scaledSize.scale(mRect.size(), mBackgroundScaledMode); - if (mScaledBackgroundPixmap.size() != scaledSize) - mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); - painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); - } else - { - painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); - } - } -} - -/*! \internal - - This function makes sure multiple axes on the side specified with \a type don't collide, but are - distributed according to their respective space requirement (QCPAxis::calculateMargin). - - It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the - one with index zero. - - This function is called by \ref calculateAutoMargin. -*/ -void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) -{ - const QList axesList = mAxes.value(type); - if (axesList.isEmpty()) - return; - - bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false - for (int i=1; ioffset() + axesList.at(i-1)->calculateMargin(); - if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible) - { - if (!isFirstVisible) - offset += axesList.at(i)->tickLengthIn(); - isFirstVisible = false; - } - axesList.at(i)->setOffset(offset); - } -} - -/* inherits documentation from base class */ -int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) -{ - if (!mAutoMargins.testFlag(side)) - qDebug() << Q_FUNC_INFO << "Called with side that isn't specified as auto margin"; - - updateAxesOffset(QCPAxis::marginSideToAxisType(side)); - - // note: only need to look at the last (outer most) axis to determine the total margin, due to updateAxisOffset call - const QList axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); - if (axesList.size() > 0) - return axesList.last()->offset() + axesList.last()->calculateMargin(); - else - return 0; -} - -/*! \internal - - Reacts to a change in layout to potentially set the convenience axis pointers \ref - QCustomPlot::xAxis, \ref QCustomPlot::yAxis, etc. of the parent QCustomPlot to the respective - axes of this axis rect. This is only done if the respective convenience pointer is currently zero - and if there is no QCPAxisRect at position (0, 0) of the plot layout. - - This automation makes it simpler to replace the main axis rect with a newly created one, without - the need to manually reset the convenience pointers. -*/ -void QCPAxisRect::layoutChanged() -{ - if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) - { - if (axisCount(QCPAxis::atBottom) > 0 && !mParentPlot->xAxis) - mParentPlot->xAxis = axis(QCPAxis::atBottom); - if (axisCount(QCPAxis::atLeft) > 0 && !mParentPlot->yAxis) - mParentPlot->yAxis = axis(QCPAxis::atLeft); - if (axisCount(QCPAxis::atTop) > 0 && !mParentPlot->xAxis2) - mParentPlot->xAxis2 = axis(QCPAxis::atTop); - if (axisCount(QCPAxis::atRight) > 0 && !mParentPlot->yAxis2) - mParentPlot->yAxis2 = axis(QCPAxis::atRight); - } -} - -/*! \internal - - Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is - pressed, the range dragging interaction is initialized (the actual range manipulation happens in - the \ref mouseMoveEvent). - - The mDragging flag is set to true and some anchor points are set that are needed to determine the - distance the mouse was dragged in the mouse move/release events later. - - \see mouseMoveEvent, mouseReleaseEvent -*/ -void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - if (event->buttons() & Qt::LeftButton) - { - mDragging = true; - // initialize antialiasing backup in case we start dragging: - if (mParentPlot->noAntialiasingOnDrag()) - { - mAADragBackup = mParentPlot->antialiasedElements(); - mNotAADragBackup = mParentPlot->notAntialiasedElements(); - } - // Mouse range dragging interaction: - if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) - { - mDragStartHorzRange.clear(); - for (int i=0; irange()); - mDragStartVertRange.clear(); - for (int i=0; irange()); - } - } -} - -/*! \internal - - Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a - preceding \ref mousePressEvent, the range is moved accordingly. - - \see mousePressEvent, mouseReleaseEvent -*/ -void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(startPos) - // Mouse range dragging interaction: - if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) - { - - if (mRangeDrag.testFlag(Qt::Horizontal)) - { - for (int i=0; i= mDragStartHorzRange.size()) - break; - - //< Drag - if (ax->mScaleType == QCPAxis::stLinear) - { - double diff = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x()); - ax->setRange(mDragStartHorzRange.at(i).lower+diff, mDragStartHorzRange.at(i).upper+diff); - - if(diff != 0) - { - mIsDragMove = true; - } - } - //< Scale - else if (ax->mScaleType == QCPAxis::stLogarithmic) - { - double diff = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x()); - ax->setRange(mDragStartHorzRange.at(i).lower*diff, mDragStartHorzRange.at(i).upper*diff); - if(diff != 0) - { - mIsDragMove = true; - } - } - } - } - - if (mRangeDrag.testFlag(Qt::Vertical)) - { - for (int i=0; i= mDragStartVertRange.size()) - break; - if (ax->mScaleType == QCPAxis::stLinear) - { - double diff = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y()); - ax->setRange(mDragStartVertRange.at(i).lower+diff, mDragStartVertRange.at(i).upper+diff); - } else if (ax->mScaleType == QCPAxis::stLogarithmic) - { - double diff = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y()); - ax->setRange(mDragStartVertRange.at(i).lower*diff, mDragStartVertRange.at(i).upper*diff); - } - } - } - - if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot - { - if (mParentPlot->noAntialiasingOnDrag()) - mParentPlot->setNotAntialiasedElements(QCP::aeAll); - mParentPlot->replot(QCustomPlot::rpQueuedReplot); - } - - } -} - -/* inherits documentation from base class */ -void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(event) - Q_UNUSED(startPos) - - //< Note: update His Date - - if(mIsDragMove) - { - emit rangeDraged(); - mIsDragMove = false; - } - - mDragging = false; - if (mParentPlot->noAntialiasingOnDrag()) - { - mParentPlot->setAntialiasedElements(mAADragBackup); - mParentPlot->setNotAntialiasedElements(mNotAADragBackup); - } -} - -/*! \internal - - Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the - ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of - the scaling operation is the current cursor position inside the axis rect. The scaling factor is - dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural - zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. - - Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse - wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be - multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as - exponent of the range zoom factor. This takes care of the wheel direction automatically, by - inverting the factor, when the wheel step is negative (f^-1 = 1/f). -*/ -void QCPAxisRect::wheelEvent(QWheelEvent *event) -{ - // Mouse range zooming interaction: - if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) - { - if (mRangeZoom != 0) - { - double factor; - double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually - if (mRangeZoom.testFlag(Qt::Horizontal)) - { - factor = qPow(mRangeZoomFactorHorz, wheelSteps); - for (int i=0; iscaleRange(factor,mRangeZoomHorzAxis.at(i)->range().upper); - } - else - { - mRangeZoomHorzAxis.at(i)->scaleRange(factor, mRangeZoomHorzAxis.at(i)->pixelToCoord(event->pos().x())); - } - emit rangeScaled(); - } - } - } - if (mRangeZoom.testFlag(Qt::Vertical)) - { - factor = qPow(mRangeZoomFactorVert, wheelSteps); - for (int i=0; iscaleRange(factor, mRangeZoomVertAxis.at(i)->pixelToCoord(event->pos().y())); - } - } - mParentPlot->replot(); - } - } -} -/* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ - - -/* including file 'src/layoutelements/layoutelement-legend.cpp', size 31097 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractLegendItem -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractLegendItem - \brief The abstract base class for all entries in a QCPLegend. - - It defines a very basic interface for entries in a QCPLegend. For representing plottables in the - legend, the subclass \ref QCPPlottableLegendItem is more suitable. - - Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry - that's not even associated with a plottable). - - You must implement the following pure virtual functions: - \li \ref draw (from QCPLayerable) - - You inherit the following members you may use: - - - - - - - - -
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
-*/ - -/* start of documentation of signals */ - -/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) - - This signal is emitted when the selection state of this legend item has changed, either by user - interaction or by a direct call to \ref setSelected. -*/ - -/* end of documentation of signals */ - -/*! - Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not - cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. -*/ -QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : - QCPLayoutElement(parent->parentPlot()), - mParentLegend(parent), - mFont(parent->font()), - mTextColor(parent->textColor()), - mSelectedFont(parent->selectedFont()), - mSelectedTextColor(parent->selectedTextColor()), - mSelectable(true), - mSelected(false) -{ - setLayer(QLatin1String("legend")); - setMargins(QMargins(0, 0, 0, 0)); -} - -/*! - Sets the default font of this specific legend item to \a font. - - \see setTextColor, QCPLegend::setFont -*/ -void QCPAbstractLegendItem::setFont(const QFont &font) -{ - mFont = font; -} - -/*! - Sets the default text color of this specific legend item to \a color. - - \see setFont, QCPLegend::setTextColor -*/ -void QCPAbstractLegendItem::setTextColor(const QColor &color) -{ - mTextColor = color; -} - -/*! - When this legend item is selected, \a font is used to draw generic text, instead of the normal - font set with \ref setFont. - - \see setFont, QCPLegend::setSelectedFont -*/ -void QCPAbstractLegendItem::setSelectedFont(const QFont &font) -{ - mSelectedFont = font; -} - -/*! - When this legend item is selected, \a color is used to draw generic text, instead of the normal - color set with \ref setTextColor. - - \see setTextColor, QCPLegend::setSelectedTextColor -*/ -void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) -{ - mSelectedTextColor = color; -} - -/*! - Sets whether this specific legend item is selectable. - - \see setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAbstractLegendItem::setSelectable(bool selectable) -{ - if (mSelectable != selectable) - { - mSelectable = selectable; - emit selectableChanged(mSelectable); - } -} - -/*! - Sets whether this specific legend item is selected. - - It is possible to set the selection state of this item by calling this function directly, even if - setSelectable is set to false. - - \see setSelectableParts, QCustomPlot::setInteractions -*/ -void QCPAbstractLegendItem::setSelected(bool selected) -{ - if (mSelected != selected) - { - mSelected = selected; - emit selectionChanged(mSelected); - } -} - -/* inherits documentation from base class */ -double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (!mParentPlot) return -1; - if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) - return -1; - - if (mRect.contains(pos.toPoint())) - return mParentPlot->selectionTolerance()*0.99; - else - return -1; -} - -/* inherits documentation from base class */ -void QCPAbstractLegendItem::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeLegendItems); -} - -/* inherits documentation from base class */ -QRect QCPAbstractLegendItem::clipRect() const -{ - return mOuterRect; -} - -/* inherits documentation from base class */ -void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - Q_UNUSED(details) - if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) - { - bool selBefore = mSelected; - setSelected(additive ? !mSelected : true); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) -{ - if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) - { - bool selBefore = mSelected; - setSelected(false); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPlottableLegendItem -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPlottableLegendItem - \brief A legend item representing a plottable with an icon and the plottable name. - - This is the standard legend item for plottables. It displays an icon of the plottable next to the - plottable name. The icon is drawn by the respective plottable itself (\ref - QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. - For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the - middle. - - Legend items of this type are always associated with one plottable (retrievable via the - plottable() function and settable with the constructor). You may change the font of the plottable - name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref - QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. - - The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend - creates/removes legend items of this type. - - Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of - QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout - interface, QCPLegend has specialized functions for handling legend items conveniently, see the - documentation of \ref QCPLegend. -*/ - -/*! - Creates a new legend item associated with \a plottable. - - Once it's created, it can be added to the legend via \ref QCPLegend::addItem. - - A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref - QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. -*/ -QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : - QCPAbstractLegendItem(parent), - mPlottable(plottable) -{ - setAntialiased(false); -} - -/*! \internal - - Returns the pen that shall be used to draw the icon border, taking into account the selection - state of this item. -*/ -QPen QCPPlottableLegendItem::getIconBorderPen() const -{ - return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); -} - -/*! \internal - - Returns the text color that shall be used to draw text, taking into account the selection state - of this item. -*/ -QColor QCPPlottableLegendItem::getTextColor() const -{ - return mSelected ? mSelectedTextColor : mTextColor; -} - -/*! \internal - - Returns the font that shall be used to draw text, taking into account the selection state of this - item. -*/ -QFont QCPPlottableLegendItem::getFont() const -{ - return mSelected ? mSelectedFont : mFont; -} - -/*! \internal - - Draws the item with \a painter. The size and position of the drawn legend item is defined by the - parent layout (typically a \ref QCPLegend) and the \ref minimumOuterSizeHint and \ref - maximumOuterSizeHint of this legend item. -*/ -void QCPPlottableLegendItem::draw(QCPPainter *painter) -{ - if (!mPlottable) return; - painter->setFont(getFont()); - painter->setPen(QPen(getTextColor())); - QSizeF iconSize = mParentLegend->iconSize(); - QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); - QRectF iconRect(mRect.topLeft(), iconSize); - int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops - painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->desc()); - // draw icon: - painter->save(); - painter->setClipRect(iconRect, Qt::IntersectClip); - mPlottable->drawLegendIcon(painter, iconRect); - painter->restore(); - // draw icon border: - if (getIconBorderPen().style() != Qt::NoPen) - { - painter->setPen(getIconBorderPen()); - painter->setBrush(Qt::NoBrush); - int halfPen = qCeil(painter->pen().widthF()*0.5)+1; - painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped - painter->drawRect(iconRect); - } -} - -/*! \internal - - Calculates and returns the size of this item. This includes the icon, the text and the padding in - between. - - \seebaseclassmethod -*/ -QSize QCPPlottableLegendItem::minimumOuterSizeHint() const -{ - if (!mPlottable) return QSize(); - QSize result(0, 0); - QRect textRect; - QFontMetrics fontMetrics(getFont()); - QSize iconSize = mParentLegend->iconSize(); - textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); - result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); - result.setHeight(qMax(textRect.height(), iconSize.height())); - result.rwidth() += mMargins.left()+mMargins.right(); - result.rheight() += mMargins.top()+mMargins.bottom(); - return result; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLegend -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLegend - \brief Manages a legend inside a QCustomPlot. - - A legend is a small box somewhere in the plot which lists plottables with their name and icon. - - A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the - plottable, for which a legend item shall be created. In the case of the main legend (\ref - QCustomPlot::legend), simply adding plottables to the plot while \ref - QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding - legend items. The legend item associated with a certain plottable can be removed with \ref - QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and - manipulate legend items directly: \ref item, \ref itemWithPlottable, \ref itemCount, \ref - addItem, \ref removeItem, etc. - - Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref - QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement - "QCPLayoutElements" which are placed in the grid layout of the legend. \ref QCPLegend only adds - an interface specialized for handling child elements of type \ref QCPAbstractLegendItem, as - mentioned above. In principle, any other layout elements may also be added to a legend via the - normal \ref QCPLayoutGrid interface. See the special page about \link thelayoutsystem The Layout - System\endlink for examples on how to add other elements to the legend and move it outside the axis - rect. - - Use the methods \ref setFillOrder and \ref setWrap inherited from \ref QCPLayoutGrid to control - in which order (column first or row first) the legend is filled up when calling \ref addItem, and - at which column or row wrapping occurs. - - By default, every QCustomPlot has one legend (\ref QCustomPlot::legend) which is placed in the - inset layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another - position inside the axis rect, use the methods of the \ref QCPLayoutInset. To move the legend - outside of the axis rect, place it anywhere else with the \ref QCPLayout/\ref QCPLayoutElement - interface. -*/ - -/* start of documentation of signals */ - -/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); - - This signal is emitted when the selection state of this legend has changed. - - \see setSelectedParts, setSelectableParts -*/ - -/* end of documentation of signals */ - -/*! - Constructs a new QCPLegend instance with default values. - - Note that by default, QCustomPlot already contains a legend ready to be used as \ref - QCustomPlot::legend -*/ -QCPLegend::QCPLegend() -{ - setFillOrder(QCPLayoutGrid::foRowsFirst); - setWrap(0); - - setRowSpacing(3); - setColumnSpacing(8); - setMargins(QMargins(7, 5, 7, 4)); - setAntialiased(false); - setIconSize(32, 18); - - setIconTextPadding(7); - - setSelectableParts(spLegendBox | spItems); - setSelectedParts(spNone); - - setBorderPen(QPen(Qt::black, 0)); - setSelectedBorderPen(QPen(Qt::blue, 2)); - setIconBorderPen(Qt::NoPen); - setSelectedIconBorderPen(QPen(Qt::blue, 2)); - setBrush(Qt::white); - setSelectedBrush(Qt::white); - setTextColor(Qt::black); - setSelectedTextColor(Qt::blue); -} - -QCPLegend::~QCPLegend() -{ - clearItems(); - if (qobject_cast(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot) - mParentPlot->legendRemoved(this); -} - -/* no doc for getter, see setSelectedParts */ -QCPLegend::SelectableParts QCPLegend::selectedParts() const -{ - // check whether any legend elements selected, if yes, add spItems to return value - bool hasSelectedItems = false; - for (int i=0; iselected()) - { - hasSelectedItems = true; - break; - } - } - if (hasSelectedItems) - return mSelectedParts | spItems; - else - return mSelectedParts & ~spItems; -} - -/*! - Sets the pen, the border of the entire legend is drawn with. -*/ -void QCPLegend::setBorderPen(const QPen &pen) -{ - mBorderPen = pen; -} - -/*! - Sets the brush of the legend background. -*/ -void QCPLegend::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will - use this font by default. However, a different font can be specified on a per-item-basis by - accessing the specific legend item. - - This function will also set \a font on all already existing legend items. - - \see QCPAbstractLegendItem::setFont -*/ -void QCPLegend::setFont(const QFont &font) -{ - mFont = font; - for (int i=0; isetFont(mFont); - } -} - -/*! - Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) - will use this color by default. However, a different colors can be specified on a per-item-basis - by accessing the specific legend item. - - This function will also set \a color on all already existing legend items. - - \see QCPAbstractLegendItem::setTextColor -*/ -void QCPLegend::setTextColor(const QColor &color) -{ - mTextColor = color; - for (int i=0; isetTextColor(color); - } -} - -/*! - Sets the size of legend icons. Legend items that draw an icon (e.g. a visual - representation of the graph) will use this size by default. -*/ -void QCPLegend::setIconSize(const QSize &size) -{ - mIconSize = size; -} - -/*! \overload -*/ -void QCPLegend::setIconSize(int width, int height) -{ - mIconSize.setWidth(width); - mIconSize.setHeight(height); -} - -/*! - Sets the horizontal space in pixels between the legend icon and the text next to it. - Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the - name of the graph) will use this space by default. -*/ -void QCPLegend::setIconTextPadding(int padding) -{ - mIconTextPadding = padding; -} - -/*! - Sets the pen used to draw a border around each legend icon. Legend items that draw an - icon (e.g. a visual representation of the graph) will use this pen by default. - - If no border is wanted, set this to \a Qt::NoPen. -*/ -void QCPLegend::setIconBorderPen(const QPen &pen) -{ - mIconBorderPen = pen; -} - -/*! - Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. - (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) - - However, even when \a selectable is set to a value not allowing the selection of a specific part, - it is still possible to set the selection of this part manually, by calling \ref setSelectedParts - directly. - - \see SelectablePart, setSelectedParts -*/ -void QCPLegend::setSelectableParts(const SelectableParts &selectable) -{ - if (mSelectableParts != selectable) - { - mSelectableParts = selectable; - emit selectableChanged(mSelectableParts); - } -} - -/*! - Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part - is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected - doesn't contain \ref spItems, those items become deselected. - - The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions - contains iSelectLegend. You only need to call this function when you wish to change the selection - state manually. - - This function can change the selection state of a part even when \ref setSelectableParts was set to a - value that actually excludes the part. - - emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - - Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set - before, because there's no way to specify which exact items to newly select. Do this by calling - \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. - - \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, - setSelectedFont -*/ -void QCPLegend::setSelectedParts(const SelectableParts &selected) -{ - SelectableParts newSelected = selected; - mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed - - if (mSelectedParts != newSelected) - { - if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that) - { - qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function"; - newSelected &= ~spItems; - } - if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems)) // spItems flag was unset, so clear item selection - { - for (int i=0; isetSelected(false); - } - } - mSelectedParts = newSelected; - emit selectionChanged(mSelectedParts); - } -} - -/*! - When the legend box is selected, this pen is used to draw the border instead of the normal pen - set via \ref setBorderPen. - - \see setSelectedParts, setSelectableParts, setSelectedBrush -*/ -void QCPLegend::setSelectedBorderPen(const QPen &pen) -{ - mSelectedBorderPen = pen; -} - -/*! - Sets the pen legend items will use to draw their icon borders, when they are selected. - - \see setSelectedParts, setSelectableParts, setSelectedFont -*/ -void QCPLegend::setSelectedIconBorderPen(const QPen &pen) -{ - mSelectedIconBorderPen = pen; -} - -/*! - When the legend box is selected, this brush is used to draw the legend background instead of the normal brush - set via \ref setBrush. - - \see setSelectedParts, setSelectableParts, setSelectedBorderPen -*/ -void QCPLegend::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/*! - Sets the default font that is used by legend items when they are selected. - - This function will also set \a font on all already existing legend items. - - \see setFont, QCPAbstractLegendItem::setSelectedFont -*/ -void QCPLegend::setSelectedFont(const QFont &font) -{ - mSelectedFont = font; - for (int i=0; isetSelectedFont(font); - } -} - -/*! - Sets the default text color that is used by legend items when they are selected. - - This function will also set \a color on all already existing legend items. - - \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor -*/ -void QCPLegend::setSelectedTextColor(const QColor &color) -{ - mSelectedTextColor = color; - for (int i=0; isetSelectedTextColor(color); - } -} - -/*! - Returns the item with index \a i. - - Note that the linear index depends on the current fill order (\ref setFillOrder). - - \see itemCount, addItem, itemWithPlottable -*/ -QCPAbstractLegendItem *QCPLegend::item(int index) const -{ - return qobject_cast(elementAt(index)); -} - -/*! - Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). - If such an item isn't in the legend, returns 0. - - \see hasItemWithPlottable -*/ -QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const -{ - for (int i=0; i(item(i))) - { - if (pli->plottable() == plottable) - return pli; - } - } - return 0; -} - -/*! - Returns the number of items currently in the legend. - - Note that if empty cells are in the legend (e.g. by calling methods of the \ref QCPLayoutGrid - base class which allows creating empty cells), they are included in the returned count. - - \see item -*/ -int QCPLegend::itemCount() const -{ - return elementCount(); -} - -/*! - Returns whether the legend contains \a item. - - \see hasItemWithPlottable -*/ -bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const -{ - for (int i=0; iitem(i)) - return true; - } - return false; -} - -/*! - Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). - If such an item isn't in the legend, returns false. - - \see itemWithPlottable -*/ -bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const -{ - return itemWithPlottable(plottable); -} - -/*! - Adds \a item to the legend, if it's not present already. The element is arranged according to the - current fill order (\ref setFillOrder) and wrapping (\ref setWrap). - - Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. - - The legend takes ownership of the item. - - \see removeItem, item, hasItem -*/ -bool QCPLegend::addItem(QCPAbstractLegendItem *item) -{ - return addElement(item); -} - -/*! \overload - - Removes the item with the specified \a index from the legend and deletes it. - - After successful removal, the legend is reordered according to the current fill order (\ref - setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item - was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. - - Returns true, if successful. Unlike \ref QCPLayoutGrid::removeAt, this method only removes - elements derived from \ref QCPAbstractLegendItem. - - \see itemCount, clearItems -*/ -bool QCPLegend::removeItem(int index) -{ - if (QCPAbstractLegendItem *ali = item(index)) - { - bool success = remove(ali); - if (success) - setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering - return success; - } else - return false; -} - -/*! \overload - - Removes \a item from the legend and deletes it. - - After successful removal, the legend is reordered according to the current fill order (\ref - setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item - was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. - - Returns true, if successful. - - \see clearItems -*/ -bool QCPLegend::removeItem(QCPAbstractLegendItem *item) -{ - bool success = remove(item); - if (success) - setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering - return success; -} - -/*! - Removes all items from the legend. -*/ -void QCPLegend::clearItems() -{ - for (int i=itemCount()-1; i>=0; --i) - removeItem(i); -} - -/*! - Returns the legend items that are currently selected. If no items are selected, - the list is empty. - - \see QCPAbstractLegendItem::setSelected, setSelectable -*/ -QList QCPLegend::selectedItems() const -{ - QList result; - for (int i=0; iselected()) - result.append(ali); - } - } - return result; -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing main legend elements. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \seebaseclassmethod - - \see setAntialiased -*/ -void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); -} - -/*! \internal - - Returns the pen used to paint the border of the legend, taking into account the selection state - of the legend box. -*/ -QPen QCPLegend::getBorderPen() const -{ - return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; -} - -/*! \internal - - Returns the brush used to paint the background of the legend, taking into account the selection - state of the legend box. -*/ -QBrush QCPLegend::getBrush() const -{ - return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush; -} - -/*! \internal - - Draws the legend box with the provided \a painter. The individual legend items are layerables - themselves, thus are drawn independently. -*/ -void QCPLegend::draw(QCPPainter *painter) -{ - // draw background rect: - painter->setBrush(getBrush()); - painter->setPen(getBorderPen()); - painter->drawRect(mOuterRect); -} - -/* inherits documentation from base class */ -double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if (!mParentPlot) return -1; - if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) - return -1; - - if (mOuterRect.contains(pos.toPoint())) - { - if (details) details->setValue(spLegendBox); - return mParentPlot->selectionTolerance()*0.99; - } - return -1; -} - -/* inherits documentation from base class */ -void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - mSelectedParts = selectedParts(); // in case item selection has changed - if (details.value() == spLegendBox && mSelectableParts.testFlag(spLegendBox)) - { - SelectableParts selBefore = mSelectedParts; - setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent) - if (selectionStateChanged) - *selectionStateChanged = mSelectedParts != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPLegend::deselectEvent(bool *selectionStateChanged) -{ - mSelectedParts = selectedParts(); // in case item selection has changed - if (mSelectableParts.testFlag(spLegendBox)) - { - SelectableParts selBefore = mSelectedParts; - setSelectedParts(selectedParts() & ~spLegendBox); - if (selectionStateChanged) - *selectionStateChanged = mSelectedParts != selBefore; - } -} - -/* inherits documentation from base class */ -QCP::Interaction QCPLegend::selectionCategory() const -{ - return QCP::iSelectLegend; -} - -/* inherits documentation from base class */ -QCP::Interaction QCPAbstractLegendItem::selectionCategory() const -{ - return QCP::iSelectLegend; -} - -/* inherits documentation from base class */ -void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) -{ - if (parentPlot && !parentPlot->legend) - parentPlot->legend = this; -} -/* end of 'src/layoutelements/layoutelement-legend.cpp' */ - - -/* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12761 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPTextElement -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPTextElement - \brief A layout element displaying a text - - The text may be specified with \ref setText, the formatting can be controlled with \ref setFont, - \ref setTextColor, and \ref setTextFlags. - - A text element can be added as follows: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcptextelement-creation -*/ - -/* start documentation of signals */ - -/*! \fn void QCPTextElement::selectionChanged(bool selected) - - This signal is emitted when the selection state has changed to \a selected, either by user - interaction or by a direct call to \ref setSelected. - - \see setSelected, setSelectable -*/ - -/*! \fn void QCPTextElement::clicked(QMouseEvent *event) - - This signal is emitted when the text element is clicked. - - \see doubleClicked, selectTest -*/ - -/*! \fn void QCPTextElement::doubleClicked(QMouseEvent *event) - - This signal is emitted when the text element is double clicked. - - \see clicked, selectTest -*/ - -/* end documentation of signals */ - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref - setText). -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot) : - QCPLayoutElement(parentPlot), - mText(), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below - mTextColor(Qt::black), - mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - if (parentPlot) - { - mFont = parentPlot->font(); - mSelectedFont = parentPlot->font(); - } - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. - - The initial text is set to \a text. -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text) : - QCPLayoutElement(parentPlot), - mText(text), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below - mTextColor(Qt::black), - mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - if (parentPlot) - { - mFont = parentPlot->font(); - mSelectedFont = parentPlot->font(); - } - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. - - The initial text is set to \a text with \a pointSize. -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize) : - QCPLayoutElement(parentPlot), - mText(text), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below - mTextColor(Qt::black), - mSelectedFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - if (parentPlot) - { - mFont = parentPlot->font(); - mFont.setPointSizeF(pointSize); - mSelectedFont = parentPlot->font(); - mSelectedFont.setPointSizeF(pointSize); - } - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. - - The initial text is set to \a text with \a pointSize and the specified \a fontFamily. -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize) : - QCPLayoutElement(parentPlot), - mText(text), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(QFont(fontFamily, pointSize)), - mTextColor(Qt::black), - mSelectedFont(QFont(fontFamily, pointSize)), - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. - - The initial text is set to \a text with the specified \a font. -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font) : - QCPLayoutElement(parentPlot), - mText(text), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(font), - mTextColor(Qt::black), - mSelectedFont(font), - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! - Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". - - \see setFont, setTextColor, setTextFlags -*/ -void QCPTextElement::setText(const QString &text) -{ - mText = text; -} - -/*! - Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of - \c Qt::AlignmentFlag and \c Qt::TextFlag enums. - - Possible enums are: - - Qt::AlignLeft - - Qt::AlignRight - - Qt::AlignHCenter - - Qt::AlignJustify - - Qt::AlignTop - - Qt::AlignBottom - - Qt::AlignVCenter - - Qt::AlignCenter - - Qt::TextDontClip - - Qt::TextSingleLine - - Qt::TextExpandTabs - - Qt::TextShowMnemonic - - Qt::TextWordWrap - - Qt::TextIncludeTrailingSpaces -*/ -void QCPTextElement::setTextFlags(int flags) -{ - mTextFlags = flags; -} - -/*! - Sets the \a font of the text. - - \see setTextColor, setSelectedFont -*/ -void QCPTextElement::setFont(const QFont &font) -{ - mFont = font; -} - -/*! - Sets the \a color of the text. - - \see setFont, setSelectedTextColor -*/ -void QCPTextElement::setTextColor(const QColor &color) -{ - mTextColor = color; -} - -/*! - Sets the \a font of the text that will be used if the text element is selected (\ref setSelected). - - \see setFont -*/ -void QCPTextElement::setSelectedFont(const QFont &font) -{ - mSelectedFont = font; -} - -/*! - Sets the \a color of the text that will be used if the text element is selected (\ref setSelected). - - \see setTextColor -*/ -void QCPTextElement::setSelectedTextColor(const QColor &color) -{ - mSelectedTextColor = color; -} - -/*! - Sets whether the user may select this text element. - - Note that even when \a selectable is set to false, the selection state may be changed - programmatically via \ref setSelected. -*/ -void QCPTextElement::setSelectable(bool selectable) -{ - if (mSelectable != selectable) - { - mSelectable = selectable; - emit selectableChanged(mSelectable); - } -} - -/*! - Sets the selection state of this text element to \a selected. If the selection has changed, \ref - selectionChanged is emitted. - - Note that this function can change the selection state independently of the current \ref - setSelectable state. -*/ -void QCPTextElement::setSelected(bool selected) -{ - if (mSelected != selected) - { - mSelected = selected; - emit selectionChanged(mSelected); - } -} - -/* inherits documentation from base class */ -void QCPTextElement::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); -} - -/* inherits documentation from base class */ -void QCPTextElement::draw(QCPPainter *painter) -{ - painter->setFont(mainFont()); - painter->setPen(QPen(mainTextColor())); - painter->drawText(mRect, Qt::AlignCenter, mText, &mTextBoundingRect); -} - -/* inherits documentation from base class */ -QSize QCPTextElement::minimumOuterSizeHint() const -{ - QFontMetrics metrics(mFont); - QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); - result.rwidth() += mMargins.left()+mMargins.right(); - result.rheight() += mMargins.top()+mMargins.bottom(); - return result; -} - -/* inherits documentation from base class */ -QSize QCPTextElement::maximumOuterSizeHint() const -{ - QFontMetrics metrics(mFont); - QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); - result.setWidth(QWIDGETSIZE_MAX); - result.rheight() += mMargins.top()+mMargins.bottom(); - return result; -} - -/* inherits documentation from base class */ -void QCPTextElement::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - Q_UNUSED(details) - if (mSelectable) - { - bool selBefore = mSelected; - setSelected(additive ? !mSelected : true); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPTextElement::deselectEvent(bool *selectionStateChanged) -{ - if (mSelectable) - { - bool selBefore = mSelected; - setSelected(false); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/*! - Returns 0.99*selectionTolerance (see \ref QCustomPlot::setSelectionTolerance) when \a pos is - within the bounding box of the text element's text. Note that this bounding box is updated in the - draw call. - - If \a pos is outside the text's bounding box or if \a onlySelectable is true and this text - element is not selectable (\ref setSelectable), returns -1. - - \seebaseclassmethod -*/ -double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - if (mTextBoundingRect.contains(pos.toPoint())) - return mParentPlot->selectionTolerance()*0.99; - else - return -1; -} - -/*! - Accepts the mouse event in order to emit the according click signal in the \ref - mouseReleaseEvent. - - \seebaseclassmethod -*/ -void QCPTextElement::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - event->accept(); -} - -/*! - Emits the \ref clicked signal if the cursor hasn't moved by more than a few pixels since the \ref - mousePressEvent. - - \seebaseclassmethod -*/ -void QCPTextElement::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - if ((QPointF(event->pos())-startPos).manhattanLength() <= 3) - emit clicked(event); -} - -/*! - Emits the \ref doubleClicked signal. - - \seebaseclassmethod -*/ -void QCPTextElement::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - emit doubleClicked(event); -} - -/*! \internal - - Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to - true, else mFont is returned. -*/ -QFont QCPTextElement::mainFont() const -{ - return mSelected ? mSelectedFont : mFont; -} - -/*! \internal - - Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to - true, else mTextColor is returned. -*/ -QColor QCPTextElement::mainTextColor() const -{ - return mSelected ? mSelectedTextColor : mTextColor; -} -/* end of 'src/layoutelements/layoutelement-textelement.cpp' */ - - -/* including file 'src/layoutelements/layoutelement-colorscale.cpp', size 25770 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPColorScale -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPColorScale - \brief A color scale for use with color coding data such as QCPColorMap - - This layout element can be placed on the plot to correlate a color gradient with data values. It - is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". - - \image html QCPColorScale.png - - The color scale can be either horizontal or vertical, as shown in the image above. The - orientation and the side where the numbers appear is controlled with \ref setType. - - Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are - connected, they share their gradient, data range and data scale type (\ref setGradient, \ref - setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color - scale, to make them all synchronize these properties. - - To have finer control over the number display and axis behaviour, you can directly access the - \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if - you want to change the number of automatically generated ticks, call - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-tickcount - - Placing a color scale next to the main axis rect works like with any other layout element: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation - In this case we have placed it to the right of the default axis rect, so it wasn't necessary to - call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color - scale can be set with \ref setLabel. - - For optimum appearance (like in the image above), it may be desirable to line up the axis rect and - the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup - - Color scales are initialized with a non-zero minimum top and bottom margin (\ref - setMinimumMargins), because vertical color scales are most common and the minimum top/bottom - margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a - horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you - might want to also change the minimum margins accordingly, e.g. setMinimumMargins(QMargins(6, 0, 6, 0)). -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPAxis *QCPColorScale::axis() const - - Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the - appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its - interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref - setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref - QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on - the QCPColorScale or on its QCPAxis. - - If the type of the color scale is changed with \ref setType, the axis returned by this method - will change, too, to either the left, right, bottom or top axis, depending on which type was set. -*/ - -/* end documentation of signals */ -/* start documentation of signals */ - -/*! \fn void QCPColorScale::dataRangeChanged(const QCPRange &newRange); - - This signal is emitted when the data range changes. - - \see setDataRange -*/ - -/*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); - - This signal is emitted when the data scale type changes. - - \see setDataScaleType -*/ - -/*! \fn void QCPColorScale::gradientChanged(const QCPColorGradient &newGradient); - - This signal is emitted when the gradient changes. - - \see setGradient -*/ - -/* end documentation of signals */ - -/*! - Constructs a new QCPColorScale. -*/ -QCPColorScale::QCPColorScale(QCustomPlot *parentPlot) : - QCPLayoutElement(parentPlot), - mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight - mDataScaleType(QCPAxis::stLinear), - mBarWidth(20), - mAxisRect(new QCPColorScaleAxisRectPrivate(this)) -{ - setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used) - setType(QCPAxis::atRight); - setDataRange(QCPRange(0, 6)); -} - -QCPColorScale::~QCPColorScale() -{ - delete mAxisRect; -} - -/* undocumented getter */ -QString QCPColorScale::label() const -{ - if (!mColorAxis) - { - qDebug() << Q_FUNC_INFO << "internal color axis undefined"; - return QString(); - } - - return mColorAxis.data()->label(); -} - -/* undocumented getter */ -bool QCPColorScale::rangeDrag() const -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return false; - } - - return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && - mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && - mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); -} - -/* undocumented getter */ -bool QCPColorScale::rangeZoom() const -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return false; - } - - return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && - mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && - mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); -} - -/*! - Sets at which side of the color scale the axis is placed, and thus also its orientation. - - Note that after setting \a type to a different value, the axis returned by \ref axis() will - be a different one. The new axis will adopt the following properties from the previous axis: The - range, scale type, label and ticker (the latter will be shared and not copied). -*/ -void QCPColorScale::setType(QCPAxis::AxisType type) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - if (mType != type) - { - mType = type; - QCPRange rangeTransfer(0, 6); - QString labelTransfer; - QSharedPointer tickerTransfer; - // transfer/revert some settings on old axis if it exists: - bool doTransfer = (bool)mColorAxis; - if (doTransfer) - { - rangeTransfer = mColorAxis.data()->range(); - labelTransfer = mColorAxis.data()->label(); - tickerTransfer = mColorAxis.data()->ticker(); - mColorAxis.data()->setLabel(QString()); - disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); - disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); - } - QList allAxisTypes = QList() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop; - foreach (QCPAxis::AxisType atype, allAxisTypes) - { - mAxisRect.data()->axis(atype)->setTicks(atype == mType); - mAxisRect.data()->axis(atype)->setTickLabels(atype== mType); - } - // set new mColorAxis pointer: - mColorAxis = mAxisRect.data()->axis(mType); - // transfer settings to new axis: - if (doTransfer) - { - mColorAxis.data()->setRange(rangeTransfer); // range transfer necessary if axis changes from vertical to horizontal or vice versa (axes with same orientation are synchronized via signals) - mColorAxis.data()->setLabel(labelTransfer); - mColorAxis.data()->setTicker(tickerTransfer); - } - connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); - connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); - mAxisRect.data()->setRangeDragAxes(QList() << mColorAxis.data()); - } -} - -/*! - Sets the range spanned by the color gradient and that is shown by the axis in the color scale. - - It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is - also equivalent to directly accessing the \ref axis and setting its range with \ref - QCPAxis::setRange. - - \see setDataScaleType, setGradient, rescaleDataRange -*/ -void QCPColorScale::setDataRange(const QCPRange &dataRange) -{ - if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) - { - mDataRange = dataRange; - if (mColorAxis) - mColorAxis.data()->setRange(mDataRange); - emit dataRangeChanged(mDataRange); - } -} - -/*! - Sets the scale type of the color scale, i.e. whether values are linearly associated with colors - or logarithmically. - - It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is - also equivalent to directly accessing the \ref axis and setting its scale type with \ref - QCPAxis::setScaleType. - - \see setDataRange, setGradient -*/ -void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) -{ - if (mDataScaleType != scaleType) - { - mDataScaleType = scaleType; - if (mColorAxis) - mColorAxis.data()->setScaleType(mDataScaleType); - if (mDataScaleType == QCPAxis::stLogarithmic) - setDataRange(mDataRange.sanitizedForLogScale()); - emit dataScaleTypeChanged(mDataScaleType); - } -} - -/*! - Sets the color gradient that will be used to represent data values. - - It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. - - \see setDataRange, setDataScaleType -*/ -void QCPColorScale::setGradient(const QCPColorGradient &gradient) -{ - if (mGradient != gradient) - { - mGradient = gradient; - if (mAxisRect) - mAxisRect.data()->mGradientImageInvalidated = true; - emit gradientChanged(mGradient); - } -} - -/*! - Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on - the internal \ref axis. -*/ -void QCPColorScale::setLabel(const QString &str) -{ - if (!mColorAxis) - { - qDebug() << Q_FUNC_INFO << "internal color axis undefined"; - return; - } - - mColorAxis.data()->setLabel(str); -} - -/*! - Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed - will have. -*/ -void QCPColorScale::setBarWidth(int width) -{ - mBarWidth = width; -} - -/*! - Sets whether the user can drag the data range (\ref setDataRange). - - Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref - QCustomPlot::setInteractions) to allow range dragging. -*/ -void QCPColorScale::setRangeDrag(bool enabled) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - - if (enabled) - mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); - else - mAxisRect.data()->setRangeDrag(0); -} - -/*! - Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. - - Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref - QCustomPlot::setInteractions) to allow range dragging. -*/ -void QCPColorScale::setRangeZoom(bool enabled) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - - if (enabled) - mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); - else - mAxisRect.data()->setRangeZoom(0); -} - -/*! - Returns a list of all the color maps associated with this color scale. -*/ -QList QCPColorScale::colorMaps() const -{ - QList result; - for (int i=0; iplottableCount(); ++i) - { - if (QCPColorMap *cm = qobject_cast(mParentPlot->plottable(i))) - if (cm->colorScale() == this) - result.append(cm); - } - return result; -} - -/*! - Changes the data range such that all color maps associated with this color scale are fully mapped - to the gradient in the data dimension. - - \see setDataRange -*/ -void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) -{ - QList maps = colorMaps(); - QCPRange newRange; - bool haveRange = false; - QCP::SignDomain sign = QCP::sdBoth; - if (mDataScaleType == QCPAxis::stLogarithmic) - sign = (mDataRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); - for (int i=0; irealVisibility() && onlyVisibleMaps) - continue; - QCPRange mapRange; - if (maps.at(i)->colorScale() == this) - { - bool currentFoundRange = true; - mapRange = maps.at(i)->data()->dataBounds(); - if (sign == QCP::sdPositive) - { - if (mapRange.lower <= 0 && mapRange.upper > 0) - mapRange.lower = mapRange.upper*1e-3; - else if (mapRange.lower <= 0 && mapRange.upper <= 0) - currentFoundRange = false; - } else if (sign == QCP::sdNegative) - { - if (mapRange.upper >= 0 && mapRange.lower < 0) - mapRange.upper = mapRange.lower*1e-3; - else if (mapRange.upper >= 0 && mapRange.lower >= 0) - currentFoundRange = false; - } - if (currentFoundRange) - { - if (!haveRange) - newRange = mapRange; - else - newRange.expand(mapRange); - haveRange = true; - } - } - } - if (haveRange) - { - if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data - { - double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason - if (mDataScaleType == QCPAxis::stLinear) - { - newRange.lower = center-mDataRange.size()/2.0; - newRange.upper = center+mDataRange.size()/2.0; - } else // mScaleType == stLogarithmic - { - newRange.lower = center/qSqrt(mDataRange.upper/mDataRange.lower); - newRange.upper = center*qSqrt(mDataRange.upper/mDataRange.lower); - } - } - setDataRange(newRange); - } -} - -/* inherits documentation from base class */ -void QCPColorScale::update(UpdatePhase phase) -{ - QCPLayoutElement::update(phase); - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - - mAxisRect.data()->update(phase); - - switch (phase) - { - case upMargins: - { - if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) - { - setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); - setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); - } else - { - setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), QWIDGETSIZE_MAX); - setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), 0); - } - break; - } - case upLayout: - { - mAxisRect.data()->setOuterRect(rect()); - break; - } - default: break; - } -} - -/* inherits documentation from base class */ -void QCPColorScale::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - painter->setAntialiasing(false); -} - -/* inherits documentation from base class */ -void QCPColorScale::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - mAxisRect.data()->mousePressEvent(event, details); -} - -/* inherits documentation from base class */ -void QCPColorScale::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - mAxisRect.data()->mouseMoveEvent(event, startPos); -} - -/* inherits documentation from base class */ -void QCPColorScale::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - mAxisRect.data()->mouseReleaseEvent(event, startPos); -} - -/* inherits documentation from base class */ -void QCPColorScale::wheelEvent(QWheelEvent *event) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - mAxisRect.data()->wheelEvent(event); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPColorScaleAxisRectPrivate -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPColorScaleAxisRectPrivate - - \internal - \brief An axis rect subclass for use in a QCPColorScale - - This is a private class and not part of the public QCustomPlot interface. - - It provides the axis rect functionality for the QCPColorScale class. -*/ - - -/*! - Creates a new instance, as a child of \a parentColorScale. -*/ -QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale) : - QCPAxisRect(parentColorScale->parentPlot(), true), - mParentColorScale(parentColorScale), - mGradientImageInvalidated(true) -{ - setParentLayerable(parentColorScale); - setMinimumMargins(QMargins(0, 0, 0, 0)); - QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; - foreach (QCPAxis::AxisType type, allAxisTypes) - { - axis(type)->setVisible(true); - axis(type)->grid()->setVisible(false); - axis(type)->setPadding(0); - connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts))); - connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts))); - } - - connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange))); - connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange))); - connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange))); - connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))); - connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType))); - connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); - connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); - connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); - - // make layer transfers of color scale transfer to axis rect and axes - // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: - connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); - foreach (QCPAxis::AxisType type, allAxisTypes) - connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), axis(type), SLOT(setLayer(QCPLayer*))); -} - -/*! \internal - - Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws - it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. - - \seebaseclassmethod -*/ -void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) -{ - if (mGradientImageInvalidated) - updateGradientImage(); - - bool mirrorHorz = false; - bool mirrorVert = false; - if (mParentColorScale->mColorAxis) - { - mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); - mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); - } - - painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); - QCPAxisRect::draw(painter); -} - -/*! \internal - - Uses the current gradient of the parent \ref QCPColorScale (specified in the constructor) to - generate a gradient image. This gradient image will be used in the \ref draw method. -*/ -void QCPColorScaleAxisRectPrivate::updateGradientImage() -{ - if (rect().isEmpty()) - return; - - const QImage::Format format = QImage::Format_ARGB32_Premultiplied; - int n = mParentColorScale->mGradient.levelCount(); - int w, h; - QVector data(n); - for (int i=0; imType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop) - { - w = n; - h = rect().height(); - mGradientImage = QImage(w, h, format); - QVector pixels; - for (int y=0; y(mGradientImage.scanLine(y))); - mParentColorScale->mGradient.colorize(data.constData(), QCPRange(0, n-1), pixels.first(), n); - for (int y=1; y(mGradientImage.scanLine(y)); - const QRgb lineColor = mParentColorScale->mGradient.color(data[h-1-y], QCPRange(0, n-1)); - for (int x=0; x allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; - foreach (QCPAxis::AxisType type, allAxisTypes) - { - if (QCPAxis *senderAxis = qobject_cast(sender())) - if (senderAxis->axisType() == type) - continue; - - if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) - { - if (selectedParts.testFlag(QCPAxis::spAxis)) - axis(type)->setSelectedParts(axis(type)->selectedParts() | QCPAxis::spAxis); - else - axis(type)->setSelectedParts(axis(type)->selectedParts() & ~QCPAxis::spAxis); - } - } -} - -/*! \internal - - This slot is connected to the selectableChanged signals of the four axes in the constructor. It - synchronizes the selectability of the axes. -*/ -void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts) -{ - // synchronize axis base selectability: - QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; - foreach (QCPAxis::AxisType type, allAxisTypes) - { - if (QCPAxis *senderAxis = qobject_cast(sender())) - if (senderAxis->axisType() == type) - continue; - - if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) - { - if (selectableParts.testFlag(QCPAxis::spAxis)) - axis(type)->setSelectableParts(axis(type)->selectableParts() | QCPAxis::spAxis); - else - axis(type)->setSelectableParts(axis(type)->selectableParts() & ~QCPAxis::spAxis); - } - } -} -/* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ - - -/* including file 'src/plottables/plottable-graph.cpp', size 73960 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPGraphData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPGraphData - \brief Holds the data of one single data point for QCPGraph. - - The stored data is: - \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) - \li \a value: coordinate on the value axis of this data point (this is the \a mainValue) - - The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for - \ref QCPDataContainer with \ref QCPGraphData as the DataType template parameter. See the - documentation there for an explanation regarding the data type's generic methods. - - \see QCPGraphDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPGraphData::sortKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPGraphData QCPGraphData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey. All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPGraphData::sortKeyIsMainKey() - - Since the member \a key is both the data point key coordinate and the data ordering parameter, - this method returns true. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPGraphData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPGraphData::mainValue() const - - Returns the \a value member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPGraphData::valueRange() const - - Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a data point with key and value set to zero. -*/ -QCPGraphData::QCPGraphData() : - key(0), - value(0) -{ -} - -/*! - Constructs a data point with the specified \a key and \a value. -*/ -QCPGraphData::QCPGraphData(double key, double value) : - key(key), - value(value) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPGraph -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPGraph - \brief A plottable representing a graph in a plot. - - \image html QCPGraph.png - - Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be - accessed via QCustomPlot::graph. - - To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can - also access and modify the data via the \ref data method, which returns a pointer to the internal - \ref QCPGraphDataContainer. - - Graphs are used to display single-valued data. Single-valued means that there should only be one - data point per unique key coordinate. In other words, the graph can't have \a loops. If you do - want to plot non-single-valued curves, rather use the QCPCurve plottable. - - Gaps in the graph line can be created by adding data points with NaN as value - (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be - separated. - - \section qcpgraph-appearance Changing the appearance - - The appearance of the graph is mainly determined by the line style, scatter style, brush and pen - of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). - - \subsection filling Filling under or between graphs - - QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to - the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, - just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. - - By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill - between this graph and another one, call \ref setChannelFillGraph with the other graph as - parameter. - - \see QCustomPlot::addGraph, QCustomPlot::graph -*/ - -/* start of documentation of inline functions */ - -/*! \fn QSharedPointer QCPGraph::data() const - - Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may - use it to directly manipulate the data, which may be more convenient and faster than using the - regular \ref setData or \ref addData methods. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a - keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually - but use QCustomPlot::removePlottable() instead. - - To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. -*/ -QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis) -{ - // special handling for QCPGraphs to maintain the simple graph interface: - mParentPlot->registerGraph(this); - - setPen(QPen(Qt::blue, 0)); - setBrush(Qt::NoBrush); - - setLineStyle(lsLine); - setScatterSkip(0); - setChannelFillGraph(0); - setAdaptiveSampling(true); -} - -QCPGraph::~QCPGraph() -{ -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPGraphs may share the same data container safely. - Modifying the data in the container will then affect all graphs that share the container. Sharing - can be achieved by simply exchanging the data containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the graph's data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-2 - - \see addData -*/ -void QCPGraph::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Replaces the current data with the provided points in \a keys and \a values. The provided - vectors should have equal length. Else, the number of added points will be the size of the - smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData -*/ -void QCPGraph::setData(const QVector &keys, const QVector &values, bool alreadySorted) -{ - mDataContainer->clear(); - addData(keys, values, alreadySorted); -} - -/*! - Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to - \ref lsNone and \ref setScatterStyle to the desired scatter style. - - \see setScatterStyle -*/ -void QCPGraph::setLineStyle(LineStyle ls) -{ - mLineStyle = ls; -} - -/*! - Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points - are drawn (e.g. for line-only-plots with appropriate line style). - - \see QCPScatterStyle, setLineStyle -*/ -void QCPGraph::setScatterStyle(const QCPScatterStyle &style) -{ - mScatterStyle = style; -} - -/*! - If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of - scatter points are skipped/not drawn after every drawn scatter point. - - This can be used to make the data appear sparser while for example still having a smooth line, - and to improve performance for very high density plots. - - If \a skip is set to 0 (default), all scatter points are drawn. - - \see setScatterStyle -*/ -void QCPGraph::setScatterSkip(int skip) -{ - mScatterSkip = qMax(0, skip); -} - -/*! - Sets the target graph for filling the area between this graph and \a targetGraph with the current - brush (\ref setBrush). - - When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To - disable any filling, set the brush to Qt::NoBrush. - - \see setBrush -*/ -void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) -{ - // prevent setting channel target to this graph itself: - if (targetGraph == this) - { - qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; - mChannelFillGraph = 0; - return; - } - // prevent setting channel target to a graph not in the plot: - if (targetGraph && targetGraph->mParentPlot != mParentPlot) - { - qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; - mChannelFillGraph = 0; - return; - } - - mChannelFillGraph = targetGraph; -} - -/*! - Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive - sampling technique can drastically improve the replot performance for graphs with a larger number - of points (e.g. above 10,000), without notably changing the appearance of the graph. - - By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive - sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no - disadvantage in almost all cases. - - \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" - - As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are - reproduced reliably, as well as the overall shape of the data set. The replot time reduces - dramatically though. This allows QCustomPlot to display large amounts of data in realtime. - - \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" - - Care must be taken when using high-density scatter plots in combination with adaptive sampling. - The adaptive sampling algorithm treats scatter plots more carefully than line plots which still - gives a significant reduction of replot times, but not quite as much as for line plots. This is - because scatter plots inherently need more data points to be preserved in order to still resemble - the original, non-adaptive-sampling plot. As shown above, the results still aren't quite - identical, as banding occurs for the outer data points. This is in fact intentional, such that - the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, - depends on the point density, i.e. the number of points in the plot. - - For some situations with scatter plots it might thus be desirable to manually turn adaptive - sampling off. For example, when saving the plot to disk. This can be achieved by setting \a - enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled - back to true afterwards. -*/ -void QCPGraph::setAdaptiveSampling(bool enabled) -{ - mAdaptiveSampling = enabled; -} - -/*! \overload - - Adds the provided points in \a keys and \a values to the current data. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPGraph::addData(const QVector &keys, const QVector &values, bool alreadySorted) -{ - if (keys.size() != values.size()) - qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); - const int n = qMin(keys.size(), values.size()); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->key = keys[i]; - it->value = values[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - - Adds the provided data point as \a key and \a value to the current data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPGraph::addData(double key, double value) -{ - mDataContainer->add(QCPGraphData(key, value)); -} - -double QCPGraph::value(const double &key) -{ - QCPDataContainer::const_iterator lower = mDataContainer->findBegin(key, true); - if(lower == mDataContainer->constEnd()) - { - return qSqrt(-1.); - } - - if(lsStepLeft == mLineStyle) - { - return lower->value; - } - - QCPDataContainer::const_iterator upper = mDataContainer->findEnd(key, false); - if(upper == mDataContainer->constEnd()) - { - return qSqrt(-1.); - } - - if(upper->key == lower->key) - { - return lower->value; - } - - double rate = (upper->value - lower->value) / (upper->key - lower->key); - return rate * (key - lower->key) + lower->value; -} - -/* inherits documentation from base class */ -double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - double result = pointDistance(pos, closestDataPoint); - if (details) - { - int pointIndex = closestDataPoint-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return result; - } else - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPGraph::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - return mDataContainer->keyRange(foundRange, inSignDomain); -} - -/* inherits documentation from base class */ -QCPRange QCPGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); -} - -/* inherits documentation from base class */ -void QCPGraph::draw(QCPPainter *painter) -{ - if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; - if (mLineStyle == lsNone && mScatterStyle.isNone()) return; - - QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - // get line pixel points appropriate to line style: - QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) - getLines(&lines, lineDataRange); - - // check data validity if flag set: -#ifdef QCUSTOMPLOT_CHECK_DATA - QCPGraphDataContainer::const_iterator it; - for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) - { - if (QCP::isInvalidData(it->key, it->value)) - qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); - } -#endif - - // draw fill of graph: - if (isSelectedSegment && mSelectionDecorator) - mSelectionDecorator->applyBrush(painter); - else - painter->setBrush(mBrush); - painter->setPen(Qt::NoPen); - drawFill(painter, &lines); - - // draw line: - if (mLineStyle != lsNone) - { - if (isSelectedSegment && mSelectionDecorator) - mSelectionDecorator->applyPen(painter); - else - painter->setPen(mPen); - painter->setBrush(Qt::NoBrush); - if (mLineStyle == lsImpulse) - drawImpulsePlot(painter, lines); - else - drawLinePlot(painter, lines); // also step plots can be drawn as a line plot - } - - // draw scatters: - QCPScatterStyle finalScatterStyle = mScatterStyle; - if (isSelectedSegment && mSelectionDecorator) - finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); - if (!finalScatterStyle.isNone()) - { - getScatters(&scatters, allSegments.at(i)); - drawScatterPlot(painter, scatters, finalScatterStyle); - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - // draw fill: - if (mBrush.style() != Qt::NoBrush) - { - applyFillAntialiasingHint(painter); - painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); - } - // draw line vertically centered: - if (mLineStyle != lsNone) - { - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens - } - // draw scatter symbol: - if (!mScatterStyle.isNone()) - { - applyScattersAntialiasingHint(painter); - // scale scatter pixmap if it's too large to fit in legend icon rect: - if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) - { - QCPScatterStyle scaledStyle(mScatterStyle); - scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); - scaledStyle.applyTo(painter, mPen); - scaledStyle.drawShape(painter, QRectF(rect).center()); - } else - { - mScatterStyle.applyTo(painter, mPen); - mScatterStyle.drawShape(painter, QRectF(rect).center()); - } - } -} - -/*! \internal - - This method retrieves an optimized set of data points via \ref getOptimizedLineData, an branches - out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc. - according to the line style of the graph. - - \a lines will be filled with points in pixel coordinates, that can be drawn with the according - draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines - aren't necessarily the original data points. For example, step line styles require additional - points to form the steps when drawn. If the line style of the graph is \ref lsNone, the \a - lines vector will be empty. - - \a dataRange specifies the beginning and ending data indices that will be taken into account for - conversion. In this function, the specified range may exceed the total data bounds without harm: - a correspondingly trimmed data range will be used. This takes the burden off the user of this - function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref - getDataSegments. - - \see getScatters -*/ -void QCPGraph::getLines(QVector *lines, const QCPDataRange &dataRange) const -{ - if (!lines) return; - QCPGraphDataContainer::const_iterator begin, end; - getVisibleDataBounds(begin, end, dataRange); - if (begin == end) - { - lines->clear(); - return; - } - - QVector lineData; - if (mLineStyle != lsNone) - getOptimizedLineData(&lineData, begin, end); - - if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in lineData (significantly simplifies following processing) - std::reverse(lineData.begin(), lineData.end()); - - switch (mLineStyle) - { - case lsNone: lines->clear(); break; - case lsLine: *lines = dataToLines(lineData); break; - case lsStepLeft: *lines = dataToStepLeftLines(lineData); break; - case lsStepRight: *lines = dataToStepRightLines(lineData); break; - case lsStepCenter: *lines = dataToStepCenterLines(lineData); break; - case lsImpulse: *lines = dataToImpulseLines(lineData); break; - } -} - -/*! \internal - - This method retrieves an optimized set of data points via \ref getOptimizedScatterData and then - converts them to pixel coordinates. The resulting points are returned in \a scatters, and can be - passed to \ref drawScatterPlot. - - \a dataRange specifies the beginning and ending data indices that will be taken into account for - conversion. In this function, the specified range may exceed the total data bounds without harm: - a correspondingly trimmed data range will be used. This takes the burden off the user of this - function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref - getDataSegments. -*/ -void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataRange) const -{ - if (!scatters) return; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; } - - QCPGraphDataContainer::const_iterator begin, end; - getVisibleDataBounds(begin, end, dataRange); - if (begin == end) - { - scatters->clear(); - return; - } - - QVector data; - getOptimizedScatterData(&data, begin, end); - - if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in data (significantly simplifies following processing) - std::reverse(data.begin(), data.end()); - - scatters->resize(data.size()); - if (keyAxis->orientation() == Qt::Vertical) - { - for (int i=0; icoordToPixel(data.at(i).value)); - (*scatters)[i].setY(keyAxis->coordToPixel(data.at(i).key)); - } - } - } else - { - for (int i=0; icoordToPixel(data.at(i).key)); - (*scatters)[i].setY(valueAxis->coordToPixel(data.at(i).value)); - } - } - } -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsLine. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot -*/ -QVector QCPGraph::dataToLines(const QVector &data) const -{ - QVector result; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - - result.resize(data.size()); - - // transform data points to pixels: - if (keyAxis->orientation() == Qt::Vertical) - { - for (int i=0; icoordToPixel(data.at(i).value)); - result[i].setY(keyAxis->coordToPixel(data.at(i).key)); - } - } else // key axis is horizontal - { - for (int i=0; icoordToPixel(data.at(i).key)); - result[i].setY(valueAxis->coordToPixel(data.at(i).value)); - } - } - return result; -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsStepLeft. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot -*/ -QVector QCPGraph::dataToStepLeftLines(const QVector &data) const -{ - QVector result; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - - result.resize(data.size()*2); - - // calculate steps from data and transform to pixel coordinates: - if (keyAxis->orientation() == Qt::Vertical) - { - double lastValue = valueAxis->coordToPixel(data.first().value); - for (int i=0; icoordToPixel(data.at(i).key); - result[i*2+0].setX(lastValue); - result[i*2+0].setY(key); - lastValue = valueAxis->coordToPixel(data.at(i).value); - result[i*2+1].setX(lastValue); - result[i*2+1].setY(key); - } - } else // key axis is horizontal - { - double lastValue = valueAxis->coordToPixel(data.first().value); - for (int i=0; icoordToPixel(data.at(i).key); - result[i*2+0].setX(key); - result[i*2+0].setY(lastValue); - lastValue = valueAxis->coordToPixel(data.at(i).value); - result[i*2+1].setX(key); - result[i*2+1].setY(lastValue); - } - } - return result; -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsStepRight. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToLines, dataToStepLeftLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot -*/ -QVector QCPGraph::dataToStepRightLines(const QVector &data) const -{ - QVector result; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - - result.resize(data.size()*2); - - // calculate steps from data and transform to pixel coordinates: - if (keyAxis->orientation() == Qt::Vertical) - { - double lastKey = keyAxis->coordToPixel(data.first().key); - for (int i=0; icoordToPixel(data.at(i).value); - result[i*2+0].setX(value); - result[i*2+0].setY(lastKey); - lastKey = keyAxis->coordToPixel(data.at(i).key); - result[i*2+1].setX(value); - result[i*2+1].setY(lastKey); - } - } else // key axis is horizontal - { - double lastKey = keyAxis->coordToPixel(data.first().key); - for (int i=0; icoordToPixel(data.at(i).value); - result[i*2+0].setX(lastKey); - result[i*2+0].setY(value); - lastKey = keyAxis->coordToPixel(data.at(i).key); - result[i*2+1].setX(lastKey); - result[i*2+1].setY(value); - } - } - return result; -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsStepCenter. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToImpulseLines, getLines, drawLinePlot -*/ -QVector QCPGraph::dataToStepCenterLines(const QVector &data) const -{ - QVector result; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - - result.resize(data.size()*2); - - // calculate steps from data and transform to pixel coordinates: - if (keyAxis->orientation() == Qt::Vertical) - { - double lastKey = keyAxis->coordToPixel(data.first().key); - double lastValue = valueAxis->coordToPixel(data.first().value); - result[0].setX(lastValue); - result[0].setY(lastKey); - for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; - result[i*2-1].setX(lastValue); - result[i*2-1].setY(key); - lastValue = valueAxis->coordToPixel(data.at(i).value); - lastKey = keyAxis->coordToPixel(data.at(i).key); - result[i*2+0].setX(lastValue); - result[i*2+0].setY(key); - } - result[data.size()*2-1].setX(lastValue); - result[data.size()*2-1].setY(lastKey); - } else // key axis is horizontal - { - double lastKey = keyAxis->coordToPixel(data.first().key); - double lastValue = valueAxis->coordToPixel(data.first().value); - result[0].setX(lastKey); - result[0].setY(lastValue); - for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; - result[i*2-1].setX(key); - result[i*2-1].setY(lastValue); - lastValue = valueAxis->coordToPixel(data.at(i).value); - lastKey = keyAxis->coordToPixel(data.at(i).key); - result[i*2+0].setX(key); - result[i*2+0].setY(lastValue); - } - result[data.size()*2-1].setX(lastKey); - result[data.size()*2-1].setY(lastValue); - } - return result; -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsImpulse. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, getLines, drawImpulsePlot -*/ -QVector QCPGraph::dataToImpulseLines(const QVector &data) const -{ - QVector result; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } - - result.resize(data.size()*2); - - // transform data points to pixels: - if (keyAxis->orientation() == Qt::Vertical) - { - for (int i=0; icoordToPixel(data.at(i).key); - result[i*2+0].setX(valueAxis->coordToPixel(0)); - result[i*2+0].setY(key); - result[i*2+1].setX(valueAxis->coordToPixel(data.at(i).value)); - result[i*2+1].setY(key); - } - } else // key axis is horizontal - { - for (int i=0; icoordToPixel(data.at(i).key); - result[i*2+0].setX(key); - result[i*2+0].setY(valueAxis->coordToPixel(0)); - result[i*2+1].setX(key); - result[i*2+1].setY(valueAxis->coordToPixel(data.at(i).value)); - } - } - return result; -} - -/*! \internal - - Draws the fill of the graph using the specified \a painter, with the currently set brush. - - Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref - getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. - - In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), - this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to - operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN - segments of the two involved graphs, before passing the overlapping pairs to \ref - getChannelFillPolygon. - - Pass the points of this graph's line as \a lines, in pixel coordinates. - - \see drawLinePlot, drawImpulsePlot, drawScatterPlot -*/ -void QCPGraph::drawFill(QCPPainter *painter, QVector *lines) const -{ - if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot - if (painter->brush().style() == Qt::NoBrush || painter->brush().color().alpha() == 0) return; - - applyFillAntialiasingHint(painter); - QVector segments = getNonNanSegments(lines, keyAxis()->orientation()); - if (!mChannelFillGraph) - { - // draw base fill under graph, fill goes all the way to the zero-value-line: - for (int i=0; idrawPolygon(getFillPolygon(lines, segments.at(i))); - } else - { - // draw fill between this graph and mChannelFillGraph: - QVector otherLines; - mChannelFillGraph->getLines(&otherLines, QCPDataRange(0, mChannelFillGraph->dataCount())); - if (!otherLines.isEmpty()) - { - QVector otherSegments = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation()); - QVector > segmentPairs = getOverlappingSegments(segments, lines, otherSegments, &otherLines); - for (int i=0; idrawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first, &otherLines, segmentPairs.at(i).second)); - } - } -} - -/*! \internal - - Draws scatter symbols at every point passed in \a scatters, given in pixel coordinates. The - scatters will be drawn with \a painter and have the appearance as specified in \a style. - - \see drawLinePlot, drawImpulsePlot -*/ -void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const -{ - applyScattersAntialiasingHint(painter); - style.applyTo(painter, mPen); - for (int i=0; i &lines) const -{ - if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) - { - applyDefaultAntialiasingHint(painter); - drawPolyline(painter, lines); - } -} - -/*! \internal - - Draws impulses from the provided data, i.e. it connects all line pairs in \a lines, given in - pixel coordinates. The \a lines necessary for impulses are generated by \ref dataToImpulseLines - from the regular graph data points. - - \see drawLinePlot, drawScatterPlot -*/ -void QCPGraph::drawImpulsePlot(QCPPainter *painter, const QVector &lines) const -{ - if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) - { - applyDefaultAntialiasingHint(painter); - QPen oldPen = painter->pen(); - QPen newPen = painter->pen(); - newPen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line - painter->setPen(newPen); - painter->drawLines(lines); - painter->setPen(oldPen); - } -} - -/*! \internal - - Returns via \a lineData the data points that need to be visualized for this graph when plotting - graph lines, taking into consideration the currently visible axis ranges and, if \ref - setAdaptiveSampling is enabled, local point densities. The considered data can be restricted - further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref - getDataSegments). - - This method is used by \ref getLines to retrieve the basic working set of data. - - \see getOptimizedScatterData -*/ -void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const -{ - if (!lineData) return; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - if (begin == end) return; - - int dataCount = end-begin; - int maxCount = std::numeric_limits::max(); - if (mAdaptiveSampling) - { - double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); - if (2*keyPixelSpan+2 < (double)std::numeric_limits::max()) - maxCount = 2*keyPixelSpan+2; - } - - if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average - { - QCPGraphDataContainer::const_iterator it = begin; - double minValue = it->value; - double maxValue = it->value; - QCPGraphDataContainer::const_iterator currentIntervalFirstPoint = it; - int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction - int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey - double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); - double lastIntervalEndKey = currentIntervalStartKey; - double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates - bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) - int intervalDataCount = 1; - ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect - while (it != end) - { - if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary - { - if (it->value < minValue) - minValue = it->value; - else if (it->value > maxValue) - maxValue = it->value; - ++intervalDataCount; - } else // new pixel interval started - { - if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster - { - if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); - if (it->key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.8, (it-1)->value)); - } else - lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); - lastIntervalEndKey = (it-1)->key; - minValue = it->value; - maxValue = it->value; - currentIntervalFirstPoint = it; - currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); - if (keyEpsilonVariable) - keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); - intervalDataCount = 1; - } - ++it; - } - // handle last interval: - if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster - { - if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); - } else - lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); - - } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output - { - lineData->resize(dataCount); - std::copy(begin, end, lineData->begin()); - } -} - -/*! \internal - - Returns via \a scatterData the data points that need to be visualized for this graph when - plotting scatter points, taking into consideration the currently visible axis ranges and, if \ref - setAdaptiveSampling is enabled, local point densities. The considered data can be restricted - further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref - getDataSegments). - - This method is used by \ref getScatters to retrieve the basic working set of data. - - \see getOptimizedLineData -*/ -void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const -{ - if (!scatterData) return; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - const int scatterModulo = mScatterSkip+1; - const bool doScatterSkip = mScatterSkip > 0; - int beginIndex = begin-mDataContainer->constBegin(); - int endIndex = end-mDataContainer->constBegin(); - while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter - { - ++beginIndex; - ++begin; - } - if (begin == end) return; - int dataCount = end-begin; - int maxCount = std::numeric_limits::max(); - if (mAdaptiveSampling) - { - int keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); - maxCount = 2*keyPixelSpan+2; - } - - if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average - { - double valueMaxRange = valueAxis->range().upper; - double valueMinRange = valueAxis->range().lower; - QCPGraphDataContainer::const_iterator it = begin; - int itIndex = beginIndex; - double minValue = it->value; - double maxValue = it->value; - QCPGraphDataContainer::const_iterator minValueIt = it; - QCPGraphDataContainer::const_iterator maxValueIt = it; - QCPGraphDataContainer::const_iterator currentIntervalStart = it; - int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction - int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey - double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); - double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates - bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) - int intervalDataCount = 1; - // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) // make sure we didn't jump over end - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - // main loop over data points: - while (it != end) - { - if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary - { - if (it->value < minValue && it->value > valueMinRange && it->value < valueMaxRange) - { - minValue = it->value; - minValueIt = it; - } else if (it->value > maxValue && it->value > valueMinRange && it->value < valueMaxRange) - { - maxValue = it->value; - maxValueIt = it; - } - ++intervalDataCount; - } else // new pixel started - { - if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them - { - // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): - double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); - int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average - QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; - int c = 0; - while (intervalIt != it) - { - if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) - scatterData->append(*intervalIt); - ++c; - if (!doScatterSkip) - ++intervalIt; - else - intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here - } - } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) - scatterData->append(*currentIntervalStart); - minValue = it->value; - maxValue = it->value; - currentIntervalStart = it; - currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); - if (keyEpsilonVariable) - keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); - intervalDataCount = 1; - } - // advance to next data point: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) // make sure we didn't jump over end - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - } - // handle last interval: - if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them - { - // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): - double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); - int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average - QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; - int intervalItIndex = intervalIt-mDataContainer->constBegin(); - int c = 0; - while (intervalIt != it) - { - if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) - scatterData->append(*intervalIt); - ++c; - if (!doScatterSkip) - ++intervalIt; - else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison: - { - intervalItIndex += scatterModulo; - if (intervalItIndex < itIndex) - intervalIt += scatterModulo; - else - { - intervalIt = it; - intervalItIndex = itIndex; - } - } - } - } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) - scatterData->append(*currentIntervalStart); - - } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output - { - QCPGraphDataContainer::const_iterator it = begin; - int itIndex = beginIndex; - scatterData->reserve(dataCount); - while (it != end) - { - scatterData->append(*it); - // advance to next data point: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - } - } -} - -/*! - This method outputs the currently visible data range via \a begin and \a end. The returned range - will also never exceed \a rangeRestriction. - - This method takes into account that the drawing of data lines at the axis rect border always - requires the points just outside the visible axis range. So \a begin and \a end may actually - indicate a range that contains one additional data point to the left and right of the visible - axis range. -*/ -void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const -{ - if (rangeRestriction.isEmpty()) - { - end = mDataContainer->constEnd(); - begin = end; - } else - { - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - // get visible data range: - begin = mDataContainer->findBegin(keyAxis->range().lower); - end = mDataContainer->findEnd(keyAxis->range().upper); - // limit lower/upperEnd to rangeRestriction: - mDataContainer->limitIteratorsToDataRange(begin, end, rangeRestriction); // this also ensures rangeRestriction outside data bounds doesn't break anything - } -} - -/*! \internal - - This method goes through the passed points in \a lineData and returns a list of the segments - which don't contain NaN data points. - - \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check - for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c - Qt::Vertical, the \a x member is checked. - - \see getOverlappingSegments, drawFill -*/ -QVector QCPGraph::getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const -{ - QVector result; - const int n = lineData->size(); - - QCPDataRange currentSegment(-1, -1); - int i = 0; - - if (keyOrientation == Qt::Horizontal) - { - while (i < n) - { - while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point - ++i; - if (i == n) - break; - currentSegment.setBegin(i++); - while (i < n && !qIsNaN(lineData->at(i).y())) // seek next NaN data point or end of data - ++i; - currentSegment.setEnd(i++); - result.append(currentSegment); - } - } else // keyOrientation == Qt::Vertical - { - while (i < n) - { - while (i < n && qIsNaN(lineData->at(i).x())) // seek next non-NaN data point - ++i; - if (i == n) - break; - currentSegment.setBegin(i++); - while (i < n && !qIsNaN(lineData->at(i).x())) // seek next NaN data point or end of data - ++i; - currentSegment.setEnd(i++); - result.append(currentSegment); - } - } - return result; -} - -/*! \internal - - This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and - \a otherSegments, and their associated point data \a thisData and \a otherData. - - It returns all pairs of segments (the first from \a thisSegments, the second from \a - otherSegments), which overlap in plot coordinates. - - This method is useful in the case of a channel fill between two graphs, when only those non-NaN - segments which actually overlap in their key coordinate shall be considered for drawing a channel - fill polygon. - - It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and - that the segments don't overlap themselves. The same is assumed for the segments in \a - otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments. - - \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon -*/ -QVector > QCPGraph::getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const -{ - QVector > result; - if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() || otherSegments.isEmpty()) - return result; - - int thisIndex = 0; - int otherIndex = 0; - const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical; - while (thisIndex < thisSegments.size() && otherIndex < otherSegments.size()) - { - if (thisSegments.at(thisIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow - { - ++thisIndex; - continue; - } - if (otherSegments.at(otherIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow - { - ++otherIndex; - continue; - } - double thisLower, thisUpper, otherLower, otherUpper; - if (!verticalKey) - { - thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x(); - thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).x(); - otherLower = otherData->at(otherSegments.at(otherIndex).begin()).x(); - otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).x(); - } else - { - thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y(); - thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).y(); - otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y(); - otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).y(); - } - - int bPrecedence; - if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence)) - result.append(QPair(thisSegments.at(thisIndex), otherSegments.at(otherIndex))); - - if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with next otherSegment, keeping current thisSegment - ++otherIndex; - else // otherSegment reaches further than thisSegment, so continue with next thisSegment, keeping current otherSegment - ++thisIndex; - } - - return result; -} - -/*! \internal - - Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper) - have overlap. - - The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the - \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher - coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if - both segment's upper bounds are identical, 0 is returned as \a bPrecedence. - - It is assumed that the lower bounds always have smaller or equal values than the upper bounds. - - \see getOverlappingSegments -*/ -bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const -{ - bPrecedence = 0; - if (aLower > bUpper) - { - bPrecedence = -1; - return false; - } else if (bLower > aUpper) - { - bPrecedence = 1; - return false; - } else - { - if (aUpper > bUpper) - bPrecedence = -1; - else if (aUpper < bUpper) - bPrecedence = 1; - - return true; - } -} - -/*! \internal - - Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis. - The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates - is in positive or negative infinity. So this case is handled separately by just closing the fill - polygon on the axis which lies in the direction towards the zero value. - - \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether - the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or - y value of the returned point, respectively. -*/ -QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } - - QPointF result; - if (valueAxis->scaleType() == QCPAxis::stLinear) - { - if (keyAxis->orientation() == Qt::Horizontal) - { - result.setX(matchingDataPoint.x()); - result.setY(valueAxis->coordToPixel(0)); - } else // keyAxis->orientation() == Qt::Vertical - { - result.setX(valueAxis->coordToPixel(0)); - result.setY(matchingDataPoint.y()); - } - } else // valueAxis->mScaleType == QCPAxis::stLogarithmic - { - // In logarithmic scaling we can't just draw to value 0 so we just fill all the way - // to the axis which is in the direction towards 0 - if (keyAxis->orientation() == Qt::Vertical) - { - if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || - (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis - result.setX(keyAxis->axisRect()->right()); - else - result.setX(keyAxis->axisRect()->left()); - result.setY(matchingDataPoint.y()); - } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) - { - result.setX(matchingDataPoint.x()); - if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || - (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis - result.setY(keyAxis->axisRect()->top()); - else - result.setY(keyAxis->axisRect()->bottom()); - } - } - return result; -} - -/*! \internal - - Returns the polygon needed for drawing normal fills between this graph and the key axis. - - Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment - which shall be used for the fill. The collection of \a lineData points described by \a segment - must not contain NaN data points (see \ref getNonNanSegments). - - The returned fill polygon will be closed at the key axis (the zero-value line) for linear value - axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect - side (see \ref getFillBasePoint). - - For increased performance (due to implicit sharing), keep the returned QPolygonF const. - - \see drawFill, getNonNanSegments -*/ -const QPolygonF QCPGraph::getFillPolygon(const QVector *lineData, QCPDataRange segment) const -{ - if (segment.size() < 2) - return QPolygonF(); - QPolygonF result(segment.size()+2); - - result[0] = getFillBasePoint(lineData->at(segment.begin())); - std::copy(lineData->constBegin()+segment.begin(), lineData->constBegin()+segment.end(), result.begin()+1); - result[result.size()-1] = getFillBasePoint(lineData->at(segment.end()-1)); - - return result; -} - -/*! \internal - - Returns the polygon needed for drawing (partial) channel fills between this graph and the graph - specified by \ref setChannelFillGraph. - - The data points of this graph are passed as pixel coordinates via \a thisData, the data of the - other graph as \a otherData. The returned polygon will be calculated for the specified data - segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a - otherData, respectively. - - The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by - \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap - need to be processed here. - - For increased performance due to implicit sharing, keep the returned QPolygonF const. - - \see drawFill, getOverlappingSegments, getNonNanSegments -*/ -const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const -{ - if (!mChannelFillGraph) - return QPolygonF(); - - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } - if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } - - if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) - return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) - - if (thisData->isEmpty()) return QPolygonF(); - QVector thisSegmentData(thisSegment.size()); - QVector otherSegmentData(otherSegment.size()); - std::copy(thisData->constBegin()+thisSegment.begin(), thisData->constBegin()+thisSegment.end(), thisSegmentData.begin()); - std::copy(otherData->constBegin()+otherSegment.begin(), otherData->constBegin()+otherSegment.end(), otherSegmentData.begin()); - // pointers to be able to swap them, depending which data range needs cropping: - QVector *staticData = &thisSegmentData; - QVector *croppedData = &otherSegmentData; - - // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): - if (keyAxis->orientation() == Qt::Horizontal) - { - // x is key - // crop lower bound: - if (staticData->first().x() < croppedData->first().x()) // other one must be cropped - qSwap(staticData, croppedData); - const int lowBound = findIndexBelowX(croppedData, staticData->first().x()); - if (lowBound == -1) return QPolygonF(); // key ranges have no overlap - croppedData->remove(0, lowBound); - // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: - if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation - double slope; - if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x())) - slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); - else - slope = 0; - (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); - (*croppedData)[0].setX(staticData->first().x()); - - // crop upper bound: - if (staticData->last().x() > croppedData->last().x()) // other one must be cropped - qSwap(staticData, croppedData); - int highBound = findIndexAboveX(croppedData, staticData->last().x()); - if (highBound == -1) return QPolygonF(); // key ranges have no overlap - croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); - // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: - if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation - const int li = croppedData->size()-1; // last index - if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li-1).x())) - slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); - else - slope = 0; - (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); - (*croppedData)[li].setX(staticData->last().x()); - } else // mKeyAxis->orientation() == Qt::Vertical - { - // y is key - // crop lower bound: - if (staticData->first().y() < croppedData->first().y()) // other one must be cropped - qSwap(staticData, croppedData); - int lowBound = findIndexBelowY(croppedData, staticData->first().y()); - if (lowBound == -1) return QPolygonF(); // key ranges have no overlap - croppedData->remove(0, lowBound); - // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: - if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation - double slope; - if (!qFuzzyCompare(croppedData->at(1).y(), croppedData->at(0).y())) // avoid division by zero in step plots - slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); - else - slope = 0; - (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); - (*croppedData)[0].setY(staticData->first().y()); - - // crop upper bound: - if (staticData->last().y() > croppedData->last().y()) // other one must be cropped - qSwap(staticData, croppedData); - int highBound = findIndexAboveY(croppedData, staticData->last().y()); - if (highBound == -1) return QPolygonF(); // key ranges have no overlap - croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); - // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: - if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation - int li = croppedData->size()-1; // last index - if (!qFuzzyCompare(croppedData->at(li).y(), croppedData->at(li-1).y())) // avoid division by zero in step plots - slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); - else - slope = 0; - (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); - (*croppedData)[li].setY(staticData->last().y()); - } - - // return joined: - for (int i=otherSegmentData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted - thisSegmentData << otherSegmentData.at(i); - return QPolygonF(thisSegmentData); -} - -/*! \internal - - Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in - \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key - axis is horizontal. - - Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. -*/ -int QCPGraph::findIndexAboveX(const QVector *data, double x) const -{ - for (int i=data->size()-1; i>=0; --i) - { - if (data->at(i).x() < x) - { - if (isize()-1) - return i+1; - else - return data->size()-1; - } - } - return -1; -} - -/*! \internal - - Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in - \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key - axis is horizontal. - - Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. -*/ -int QCPGraph::findIndexBelowX(const QVector *data, double x) const -{ - for (int i=0; isize(); ++i) - { - if (data->at(i).x() > x) - { - if (i>0) - return i-1; - else - return 0; - } - } - return -1; -} - -/*! \internal - - Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in - \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key - axis is vertical. - - Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. -*/ -int QCPGraph::findIndexAboveY(const QVector *data, double y) const -{ - for (int i=data->size()-1; i>=0; --i) - { - if (data->at(i).y() < y) - { - if (isize()-1) - return i+1; - else - return data->size()-1; - } - } - return -1; -} - -/*! \internal - - Calculates the minimum distance in pixels the graph's representation has from the given \a - pixelPoint. This is used to determine whether the graph was clicked or not, e.g. in \ref - selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if - the graph has a line representation, the returned distance may be smaller than the distance to - the \a closestData point, since the distance to the graph line is also taken into account. - - If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape - is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. -*/ -double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const -{ - closestData = mDataContainer->constEnd(); - if (mDataContainer->isEmpty()) - return -1.0; - if (mLineStyle == lsNone && mScatterStyle.isNone()) - return -1.0; - - // calculate minimum distances to graph data points and find closestData iterator: - double minDistSqr = std::numeric_limits::max(); - // determine which key range comes into question, taking selection tolerance around pos into account: - double posKeyMin, posKeyMax, dummy; - pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); - pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); - if (posKeyMin > posKeyMax) - qSwap(posKeyMin, posKeyMax); - // iterate over found data points and then choose the one with the shortest distance to pos: - QCPGraphDataContainer::const_iterator begin = mDataContainer->findBegin(posKeyMin, true); - QCPGraphDataContainer::const_iterator end = mDataContainer->findEnd(posKeyMax, true); - for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) - { - const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestData = it; - } - } - - // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): - if (mLineStyle != lsNone) - { - // line displayed, calculate distance to line segments: - QVector lineData; - getLines(&lineData, QCPDataRange(0, dataCount())); - QCPVector2D p(pixelPoint); - const int step = mLineStyle==lsImpulse ? 2 : 1; // impulse plot differs from other line styles in that the lineData points are only pairwise connected - for (int i=0; i *data, double y) const -{ - for (int i=0; isize(); ++i) - { - if (data->at(i).y() > y) - { - if (i>0) - return i-1; - else - return 0; - } - } - return -1; -} -/* end of 'src/plottables/plottable-graph.cpp' */ - - -/* including file 'src/plottables/plottable-curve.cpp', size 63527 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPCurveData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPCurveData - \brief Holds the data of one single data point for QCPCurve. - - The stored data is: - \li \a t: the free ordering parameter of this curve point, like in the mathematical vector (x(t), y(t)). (This is the \a sortKey) - \li \a key: coordinate on the key axis of this curve point (this is the \a mainKey) - \li \a value: coordinate on the value axis of this curve point (this is the \a mainValue) - - The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for - \ref QCPDataContainer with \ref QCPCurveData as the DataType template parameter. See the - documentation there for an explanation regarding the data type's generic methods. - - \see QCPCurveDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPCurveData::sortKey() const - - Returns the \a t member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPCurveData QCPCurveData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey (assigned to the data point's \a t member). - All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPCurveData::sortKeyIsMainKey() - - Since the member \a key is the data point key coordinate and the member \a t is the data ordering - parameter, this method returns false. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPCurveData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPCurveData::mainValue() const - - Returns the \a value member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPCurveData::valueRange() const - - Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a curve data point with t, key and value set to zero. -*/ -QCPCurveData::QCPCurveData() : - t(0), - key(0), - value(0) -{ -} - -/*! - Constructs a curve data point with the specified \a t, \a key and \a value. -*/ -QCPCurveData::QCPCurveData(double t, double key, double value) : - t(t), - key(key), - value(value) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPCurve -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPCurve - \brief A plottable representing a parametric curve in a plot. - - \image html QCPCurve.png - - Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, - so their visual representation can have \a loops. This is realized by introducing a third - coordinate \a t, which defines the order of the points described by the other two coordinates \a - x and \a y. - - To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can - also access and modify the curve's data via the \ref data method, which returns a pointer to the - internal \ref QCPCurveDataContainer. - - Gaps in the curve can be created by adding data points with NaN as key and value - (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be - separated. - - \section qcpcurve-appearance Changing the appearance - - The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). - - \section qcpcurve-usage Usage - - Like all data representing objects in QCustomPlot, the QCPCurve is a plottable - (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies - (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - - Usually, you first create an instance: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 - which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes - ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. - The newly created plottable can be modified, e.g.: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-2 -*/ - -/* start of documentation of inline functions */ - -/*! \fn QSharedPointer QCPCurve::data() const - - Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may - use it to directly manipulate the data, which may be more convenient and faster than using the - regular \ref setData or \ref addData methods. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a - keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually - but use QCustomPlot::removePlottable() instead. -*/ -QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis) -{ - // modify inherited properties from abstract plottable: - setPen(QPen(Qt::blue, 0)); - setBrush(Qt::NoBrush); - - setScatterStyle(QCPScatterStyle()); - setLineStyle(lsLine); - setScatterSkip(0); -} - -QCPCurve::~QCPCurve() -{ -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPCurves may share the same data container safely. - Modifying the data in the container will then affect all curves that share the container. Sharing - can be achieved by simply exchanging the data containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the curve's data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-2 - - \see addData -*/ -void QCPCurve::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Replaces the current data with the provided points in \a t, \a keys and \a values. The provided - vectors should have equal length. Else, the number of added points will be the size of the - smallest vector. - - If you can guarantee that the passed data points are sorted by \a t in ascending order, you can - set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData -*/ -void QCPCurve::setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) -{ - mDataContainer->clear(); - addData(t, keys, values, alreadySorted); -} - - -/*! \overload - - Replaces the current data with the provided points in \a keys and \a values. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - The t parameter of each data point will be set to the integer index of the respective key/value - pair. - - \see addData -*/ -void QCPCurve::setData(const QVector &keys, const QVector &values) -{ - mDataContainer->clear(); - addData(keys, values); -} - -/*! - Sets the visual appearance of single data points in the plot. If set to \ref - QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate - line style). - - \see QCPScatterStyle, setLineStyle -*/ -void QCPCurve::setScatterStyle(const QCPScatterStyle &style) -{ - mScatterStyle = style; -} - -/*! - If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of - scatter points are skipped/not drawn after every drawn scatter point. - - This can be used to make the data appear sparser while for example still having a smooth line, - and to improve performance for very high density plots. - - If \a skip is set to 0 (default), all scatter points are drawn. - - \see setScatterStyle -*/ -void QCPCurve::setScatterSkip(int skip) -{ - mScatterSkip = qMax(0, skip); -} - -/*! - Sets how the single data points are connected in the plot or how they are represented visually - apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref - setScatterStyle to the desired scatter style. - - \see setScatterStyle -*/ -void QCPCurve::setLineStyle(QCPCurve::LineStyle style) -{ - mLineStyle = style; -} - -/*! \overload - - Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPCurve::addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) -{ - if (t.size() != keys.size() || t.size() != values.size()) - qDebug() << Q_FUNC_INFO << "ts, keys and values have different sizes:" << t.size() << keys.size() << values.size(); - const int n = qMin(qMin(t.size(), keys.size()), values.size()); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->t = t[i]; - it->key = keys[i]; - it->value = values[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - - Adds the provided points in \a keys and \a values to the current data. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - The t parameter of each data point will be set to the integer index of the respective key/value - pair. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPCurve::addData(const QVector &keys, const QVector &values) -{ - if (keys.size() != values.size()) - qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); - const int n = qMin(keys.size(), values.size()); - double tStart; - if (!mDataContainer->isEmpty()) - tStart = (mDataContainer->constEnd()-1)->t + 1.0; - else - tStart = 0; - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->t = tStart + i; - it->key = keys[i]; - it->value = values[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, true); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - Adds the provided data point as \a t, \a key and \a value to the current data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPCurve::addData(double t, double key, double value) -{ - mDataContainer->add(QCPCurveData(t, key, value)); -} - -/*! \overload - - Adds the provided data point as \a key and \a value to the current data. - - The t parameter is generated automatically by increments of 1 for each point, starting at the - highest t of previously existing data or 0, if the curve data is empty. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPCurve::addData(double key, double value) -{ - if (!mDataContainer->isEmpty()) - mDataContainer->add(QCPCurveData((mDataContainer->constEnd()-1)->t + 1.0, key, value)); - else - mDataContainer->add(QCPCurveData(0.0, key, value)); -} - -/* inherits documentation from base class */ -double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - QCPCurveDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - double result = pointDistance(pos, closestDataPoint); - if (details) - { - int pointIndex = closestDataPoint-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return result; - } else - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPCurve::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - return mDataContainer->keyRange(foundRange, inSignDomain); -} - -/* inherits documentation from base class */ -QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); -} - -/* inherits documentation from base class */ -void QCPCurve::draw(QCPPainter *painter) -{ - if (mDataContainer->isEmpty()) return; - - // allocate line vector: - QVector lines, scatters; - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - - // fill with curve data: - QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width - if (isSelectedSegment && mSelectionDecorator) - finalCurvePen = mSelectionDecorator->pen(); - - QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care) - getCurveLines(&lines, lineDataRange, finalCurvePen.widthF()); - - // check data validity if flag set: - #ifdef QCUSTOMPLOT_CHECK_DATA - for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) - { - if (QCP::isInvalidData(it->t) || - QCP::isInvalidData(it->key, it->value)) - qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); - } - #endif - - // draw curve fill: - applyFillAntialiasingHint(painter); - if (isSelectedSegment && mSelectionDecorator) - mSelectionDecorator->applyBrush(painter); - else - painter->setBrush(mBrush); - painter->setPen(Qt::NoPen); - if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) - painter->drawPolygon(QPolygonF(lines)); - - // draw curve line: - if (mLineStyle != lsNone) - { - painter->setPen(finalCurvePen); - painter->setBrush(Qt::NoBrush); - drawCurveLine(painter, lines); - } - - // draw scatters: - QCPScatterStyle finalScatterStyle = mScatterStyle; - if (isSelectedSegment && mSelectionDecorator) - finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); - if (!finalScatterStyle.isNone()) - { - getScatters(&scatters, allSegments.at(i), finalScatterStyle.size()); - drawScatterPlot(painter, scatters, finalScatterStyle); - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - // draw fill: - if (mBrush.style() != Qt::NoBrush) - { - applyFillAntialiasingHint(painter); - painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); - } - // draw line vertically centered: - if (mLineStyle != lsNone) - { - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens - } - // draw scatter symbol: - if (!mScatterStyle.isNone()) - { - applyScattersAntialiasingHint(painter); - // scale scatter pixmap if it's too large to fit in legend icon rect: - if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) - { - QCPScatterStyle scaledStyle(mScatterStyle); - scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); - scaledStyle.applyTo(painter, mPen); - scaledStyle.drawShape(painter, QRectF(rect).center()); - } else - { - mScatterStyle.applyTo(painter, mPen); - mScatterStyle.drawShape(painter, QRectF(rect).center()); - } - } -} - -/*! \internal - - Draws lines between the points in \a lines, given in pixel coordinates. - - \see drawScatterPlot, getCurveLines -*/ -void QCPCurve::drawCurveLine(QCPPainter *painter, const QVector &lines) const -{ - if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) - { - applyDefaultAntialiasingHint(painter); - drawPolyline(painter, lines); - } -} - -/*! \internal - - Draws scatter symbols at every point passed in \a points, given in pixel coordinates. The - scatters will be drawn with \a painter and have the appearance as specified in \a style. - - \see drawCurveLine, getCurveLines -*/ -void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const -{ - // draw scatter point symbols: - applyScattersAntialiasingHint(painter); - style.applyTo(painter, mPen); - for (int i=0; i *lines, const QCPDataRange &dataRange, double penWidth) const -{ - if (!lines) return; - lines->clear(); - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - // add margins to rect to compensate for stroke width - const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety - const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation()); - const double keyMax = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*keyAxis->pixelOrientation()); - const double valueMin = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)-strokeMargin*valueAxis->pixelOrientation()); - const double valueMax = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)+strokeMargin*valueAxis->pixelOrientation()); - QCPCurveDataContainer::const_iterator itBegin = mDataContainer->constBegin(); - QCPCurveDataContainer::const_iterator itEnd = mDataContainer->constEnd(); - mDataContainer->limitIteratorsToDataRange(itBegin, itEnd, dataRange); - if (itBegin == itEnd) - return; - QCPCurveDataContainer::const_iterator it = itBegin; - QCPCurveDataContainer::const_iterator prevIt = itEnd-1; - int prevRegion = getRegion(prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin); - QVector trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right) - while (it != itEnd) - { - const int currentRegion = getRegion(it->key, it->value, keyMin, valueMax, keyMax, valueMin); - if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R - { - if (currentRegion != 5) // segment doesn't end in R, so it's a candidate for removal - { - QPointF crossA, crossB; - if (prevRegion == 5) // we're coming from R, so add this point optimized - { - lines->append(getOptimizedPoint(currentRegion, it->key, it->value, prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin)); - // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point - *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); - } else if (mayTraverse(prevRegion, currentRegion) && - getTraverse(prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin, crossA, crossB)) - { - // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point: - QVector beforeTraverseCornerPoints, afterTraverseCornerPoints; - getTraverseCornerPoints(prevRegion, currentRegion, keyMin, valueMax, keyMax, valueMin, beforeTraverseCornerPoints, afterTraverseCornerPoints); - if (it != itBegin) - { - *lines << beforeTraverseCornerPoints; - lines->append(crossA); - lines->append(crossB); - *lines << afterTraverseCornerPoints; - } else - { - lines->append(crossB); - *lines << afterTraverseCornerPoints; - trailingPoints << beforeTraverseCornerPoints << crossA ; - } - } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s) - { - *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); - } - } else // segment does end in R, so we add previous point optimized and this point at original position - { - if (it == itBegin) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end - trailingPoints << getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); - else - lines->append(getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin)); - lines->append(coordsToPixels(it->key, it->value)); - } - } else // region didn't change - { - if (currentRegion == 5) // still in R, keep adding original points - { - lines->append(coordsToPixels(it->key, it->value)); - } else // still outside R, no need to add anything - { - // see how this is not doing anything? That's the main optimization... - } - } - prevIt = it; - prevRegion = currentRegion; - ++it; - } - *lines << trailingPoints; -} - -/*! \internal - - Called by \ref draw to generate points in pixel coordinates which represent the scatters of the - curve. If a scatter skip is configured (\ref setScatterSkip), the returned points are accordingly - sparser. - - Scatters that aren't visible in the current axis rect are optimized away. - - \a scatters will be filled with points in pixel coordinates, that can be drawn with \ref - drawScatterPlot. - - \a dataRange specifies the beginning and ending data indices that will be taken into account for - conversion. - - \a scatterWidth specifies the scatter width that will be used to later draw the scatters at pixel - coordinates generated by this function. This is needed here to calculate an accordingly wider - margin around the axis rect when performing the data point reduction. - - \see draw, drawScatterPlot -*/ -void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const -{ - if (!scatters) return; - scatters->clear(); - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); - QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); - mDataContainer->limitIteratorsToDataRange(begin, end, dataRange); - if (begin == end) - return; - const int scatterModulo = mScatterSkip+1; - const bool doScatterSkip = mScatterSkip > 0; - int endIndex = end-mDataContainer->constBegin(); - - QCPRange keyRange = keyAxis->range(); - QCPRange valueRange = valueAxis->range(); - // extend range to include width of scatter symbols: - keyRange.lower = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.lower)-scatterWidth*keyAxis->pixelOrientation()); - keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation()); - valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation()); - valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation()); - - QCPCurveDataContainer::const_iterator it = begin; - int itIndex = begin-mDataContainer->constBegin(); - while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter - { - ++itIndex; - ++it; - } - if (keyAxis->orientation() == Qt::Vertical) - { - while (it != end) - { - if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) - scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key))); - - // advance iterator to next (non-skipped) data point: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) // make sure we didn't jump over end - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - } - } else - { - while (it != end) - { - if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) - scatters->append(QPointF(keyAxis->coordToPixel(it->key), valueAxis->coordToPixel(it->value))); - - // advance iterator to next (non-skipped) data point: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) // make sure we didn't jump over end - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - } - } -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - It returns the region of the given point (\a key, \a value) with respect to a rectangle defined - by \a keyMin, \a keyMax, \a valueMin, and \a valueMax. - - The regions are enumerated from top to bottom (\a valueMin to \a valueMax) and left to right (\a - keyMin to \a keyMax): - - - - - -
147
258
369
- - With the rectangle being region 5, and the outer regions extending infinitely outwards. In the - curve optimization algorithm, region 5 is considered to be the visible portion of the plot. -*/ -int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const -{ - if (key < keyMin) // region 123 - { - if (value > valueMax) - return 1; - else if (value < valueMin) - return 3; - else - return 2; - } else if (key > keyMax) // region 789 - { - if (value > valueMax) - return 7; - else if (value < valueMin) - return 9; - else - return 8; - } else // region 456 - { - if (value > valueMax) - return 4; - else if (value < valueMin) - return 6; - else - return 5; - } -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - This method is used in case the current segment passes from inside the visible rect (region 5, - see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by - the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). - - It returns the intersection point of the segment with the border of region 5. - - For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or - whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or - leaving it. It is important though that \a otherRegion correctly identifies the other region not - equal to 5. -*/ -QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const -{ - // The intersection point interpolation here is done in pixel coordinates, so we don't need to - // differentiate between different axis scale types. Note that the nomenclature - // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be - // different in pixel coordinates (horz/vert key axes, reversed ranges) - - const double keyMinPx = mKeyAxis->coordToPixel(keyMin); - const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); - const double valueMinPx = mValueAxis->coordToPixel(valueMin); - const double valueMaxPx = mValueAxis->coordToPixel(valueMax); - const double otherValuePx = mValueAxis->coordToPixel(otherValue); - const double valuePx = mValueAxis->coordToPixel(value); - const double otherKeyPx = mKeyAxis->coordToPixel(otherKey); - const double keyPx = mKeyAxis->coordToPixel(key); - double intersectKeyPx = keyMinPx; // initial key just a fail-safe - double intersectValuePx = valueMinPx; // initial value just a fail-safe - switch (otherRegion) - { - case 1: // top and left edge - { - intersectValuePx = valueMaxPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) - { - intersectKeyPx = keyMinPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - } - break; - } - case 2: // left edge - { - intersectKeyPx = keyMinPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - break; - } - case 3: // bottom and left edge - { - intersectValuePx = valueMinPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) - { - intersectKeyPx = keyMinPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - } - break; - } - case 4: // top edge - { - intersectValuePx = valueMaxPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - break; - } - case 5: - { - break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table - } - case 6: // bottom edge - { - intersectValuePx = valueMinPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - break; - } - case 7: // top and right edge - { - intersectValuePx = valueMaxPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) - { - intersectKeyPx = keyMaxPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - } - break; - } - case 8: // right edge - { - intersectKeyPx = keyMaxPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - break; - } - case 9: // bottom and right edge - { - intersectValuePx = valueMinPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) - { - intersectKeyPx = keyMaxPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - } - break; - } - } - if (mKeyAxis->orientation() == Qt::Horizontal) - return QPointF(intersectKeyPx, intersectValuePx); - else - return QPointF(intersectValuePx, intersectKeyPx); -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - In situations where a single segment skips over multiple regions it might become necessary to add - extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment - doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. - This method provides these points that must be added, assuming the original segment doesn't - start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by - \ref getTraverseCornerPoints.) - - For example, consider a segment which directly goes from region 4 to 2 but originally is far out - to the top left such that it doesn't cross region 5. Naively optimizing these points by - projecting them on the top and left borders of region 5 will create a segment that surely crosses - 5, creating a visual artifact in the plot. This method prevents this by providing extra points at - the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without - traversing 5. -*/ -QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const -{ - QVector result; - switch (prevRegion) - { - case 1: - { - switch (currentRegion) - { - case 2: { result << coordsToPixels(keyMin, valueMax); break; } - case 4: { result << coordsToPixels(keyMin, valueMax); break; } - case 3: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); break; } - case 7: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); break; } - case 6: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } - case 8: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } - case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points - if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R - { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } - else - { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } - break; - } - } - break; - } - case 2: - { - switch (currentRegion) - { - case 1: { result << coordsToPixels(keyMin, valueMax); break; } - case 3: { result << coordsToPixels(keyMin, valueMin); break; } - case 4: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } - case 6: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } - case 7: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } - case 9: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - case 3: - { - switch (currentRegion) - { - case 2: { result << coordsToPixels(keyMin, valueMin); break; } - case 6: { result << coordsToPixels(keyMin, valueMin); break; } - case 1: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); break; } - case 9: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); break; } - case 4: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } - case 8: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } - case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points - if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R - { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } - else - { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } - break; - } - } - break; - } - case 4: - { - switch (currentRegion) - { - case 1: { result << coordsToPixels(keyMin, valueMax); break; } - case 7: { result << coordsToPixels(keyMax, valueMax); break; } - case 2: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } - case 8: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } - case 3: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } - case 9: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - case 5: - { - switch (currentRegion) - { - case 1: { result << coordsToPixels(keyMin, valueMax); break; } - case 7: { result << coordsToPixels(keyMax, valueMax); break; } - case 9: { result << coordsToPixels(keyMax, valueMin); break; } - case 3: { result << coordsToPixels(keyMin, valueMin); break; } - } - break; - } - case 6: - { - switch (currentRegion) - { - case 3: { result << coordsToPixels(keyMin, valueMin); break; } - case 9: { result << coordsToPixels(keyMax, valueMin); break; } - case 2: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } - case 8: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } - case 1: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } - case 7: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } - } - break; - } - case 7: - { - switch (currentRegion) - { - case 4: { result << coordsToPixels(keyMax, valueMax); break; } - case 8: { result << coordsToPixels(keyMax, valueMax); break; } - case 1: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); break; } - case 9: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); break; } - case 2: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } - case 6: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } - case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points - if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R - { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } - else - { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } - break; - } - } - break; - } - case 8: - { - switch (currentRegion) - { - case 7: { result << coordsToPixels(keyMax, valueMax); break; } - case 9: { result << coordsToPixels(keyMax, valueMin); break; } - case 4: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } - case 6: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } - case 1: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } - case 3: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } - } - break; - } - case 9: - { - switch (currentRegion) - { - case 6: { result << coordsToPixels(keyMax, valueMin); break; } - case 8: { result << coordsToPixels(keyMax, valueMin); break; } - case 3: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); break; } - case 7: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); break; } - case 2: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } - case 4: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } - case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points - if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R - { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } - else - { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } - break; - } - } - break; - } - } - return result; -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref - getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion - nor \a currentRegion is 5 itself. - - If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the - segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref - getTraverse). -*/ -bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const -{ - switch (prevRegion) - { - case 1: - { - switch (currentRegion) - { - case 4: - case 7: - case 2: - case 3: return false; - default: return true; - } - } - case 2: - { - switch (currentRegion) - { - case 1: - case 3: return false; - default: return true; - } - } - case 3: - { - switch (currentRegion) - { - case 1: - case 2: - case 6: - case 9: return false; - default: return true; - } - } - case 4: - { - switch (currentRegion) - { - case 1: - case 7: return false; - default: return true; - } - } - case 5: return false; // should never occur - case 6: - { - switch (currentRegion) - { - case 3: - case 9: return false; - default: return true; - } - } - case 7: - { - switch (currentRegion) - { - case 1: - case 4: - case 8: - case 9: return false; - default: return true; - } - } - case 8: - { - switch (currentRegion) - { - case 7: - case 9: return false; - default: return true; - } - } - case 9: - { - switch (currentRegion) - { - case 3: - case 6: - case 8: - case 7: return false; - default: return true; - } - } - default: return true; - } -} - - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - This method assumes that the \ref mayTraverse test has returned true, so there is a chance the - segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible - region 5. - - The return value of this method indicates whether the segment actually traverses region 5 or not. - - If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and - exit points of region 5. They will become the optimized points for that segment. -*/ -bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const -{ - // The intersection point interpolation here is done in pixel coordinates, so we don't need to - // differentiate between different axis scale types. Note that the nomenclature - // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be - // different in pixel coordinates (horz/vert key axes, reversed ranges) - - QList intersections; - const double valueMinPx = mValueAxis->coordToPixel(valueMin); - const double valueMaxPx = mValueAxis->coordToPixel(valueMax); - const double keyMinPx = mKeyAxis->coordToPixel(keyMin); - const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); - const double keyPx = mKeyAxis->coordToPixel(key); - const double valuePx = mValueAxis->coordToPixel(value); - const double prevKeyPx = mKeyAxis->coordToPixel(prevKey); - const double prevValuePx = mValueAxis->coordToPixel(prevValue); - if (qFuzzyIsNull(key-prevKey)) // line is parallel to value axis - { - // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMinPx) : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMaxPx) : QPointF(valueMaxPx, keyPx)); - } else if (qFuzzyIsNull(value-prevValue)) // line is parallel to key axis - { - // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, valuePx) : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, valuePx) : QPointF(valuePx, keyMaxPx)); - } else // line is skewed - { - double gamma; - double keyPerValuePx = (keyPx-prevKeyPx)/(valuePx-prevValuePx); - // check top of rect: - gamma = prevKeyPx + (valueMaxPx-prevValuePx)*keyPerValuePx; - if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMaxPx) : QPointF(valueMaxPx, gamma)); - // check bottom of rect: - gamma = prevKeyPx + (valueMinPx-prevValuePx)*keyPerValuePx; - if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMinPx) : QPointF(valueMinPx, gamma)); - const double valuePerKeyPx = 1.0/keyPerValuePx; - // check left of rect: - gamma = prevValuePx + (keyMinPx-prevKeyPx)*valuePerKeyPx; - if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, gamma) : QPointF(gamma, keyMinPx)); - // check right of rect: - gamma = prevValuePx + (keyMaxPx-prevKeyPx)*valuePerKeyPx; - if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, gamma) : QPointF(gamma, keyMaxPx)); - } - - // handle cases where found points isn't exactly 2: - if (intersections.size() > 2) - { - // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between: - double distSqrMax = 0; - QPointF pv1, pv2; - for (int i=0; i distSqrMax) - { - pv1 = intersections.at(i); - pv2 = intersections.at(k); - distSqrMax = distSqr; - } - } - } - intersections = QList() << pv1 << pv2; - } else if (intersections.size() != 2) - { - // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment - return false; - } - - // possibly re-sort points so optimized point segment has same direction as original segment: - double xDelta = keyPx-prevKeyPx; - double yDelta = valuePx-prevValuePx; - if (mKeyAxis->orientation() != Qt::Horizontal) - qSwap(xDelta, yDelta); - if (xDelta*(intersections.at(1).x()-intersections.at(0).x()) + yDelta*(intersections.at(1).y()-intersections.at(0).y()) < 0) // scalar product of both segments < 0 -> opposite direction - intersections.move(0, 1); - crossA = intersections.at(0); - crossB = intersections.at(1); - return true; -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - This method assumes that the \ref getTraverse test has returned true, so the segment definitely - traverses the visible region 5 when going from \a prevRegion to \a currentRegion. - - In certain situations it is not sufficient to merely generate the entry and exit points of the - segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in - addition to traversing region 5, skips another region outside of region 5, which makes it - necessary to add an optimized corner point there (very similar to the job \ref - getOptimizedCornerPoints does for segments that are completely in outside regions and don't - traverse 5). - - As an example, consider a segment going from region 1 to region 6, traversing the lower left - corner of region 5. In this configuration, the segment additionally crosses the border between - region 1 and 2 before entering region 5. This makes it necessary to add an additional point in - the top left corner, before adding the optimized traverse points. So in this case, the output - parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be - empty. - - In some cases, such as when going from region 1 to 9, it may even be necessary to add additional - corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse - return the respective corner points. -*/ -void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const -{ - switch (prevRegion) - { - case 1: - { - switch (currentRegion) - { - case 6: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } - case 9: { beforeTraverse << coordsToPixels(keyMin, valueMax); afterTraverse << coordsToPixels(keyMax, valueMin); break; } - case 8: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } - } - break; - } - case 2: - { - switch (currentRegion) - { - case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } - case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - case 3: - { - switch (currentRegion) - { - case 4: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } - case 7: { beforeTraverse << coordsToPixels(keyMin, valueMin); afterTraverse << coordsToPixels(keyMax, valueMax); break; } - case 8: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } - } - break; - } - case 4: - { - switch (currentRegion) - { - case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } - case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - case 5: { break; } // shouldn't happen because this method only handles full traverses - case 6: - { - switch (currentRegion) - { - case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } - case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } - } - break; - } - case 7: - { - switch (currentRegion) - { - case 2: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } - case 3: { beforeTraverse << coordsToPixels(keyMax, valueMax); afterTraverse << coordsToPixels(keyMin, valueMin); break; } - case 6: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } - } - break; - } - case 8: - { - switch (currentRegion) - { - case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } - case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } - } - break; - } - case 9: - { - switch (currentRegion) - { - case 2: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } - case 1: { beforeTraverse << coordsToPixels(keyMax, valueMin); afterTraverse << coordsToPixels(keyMin, valueMax); break; } - case 4: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - } -} - -/*! \internal - - Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a - pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in - \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that - if the curve has a line representation, the returned distance may be smaller than the distance to - the \a closestData point, since the distance to the curve line is also taken into account. - - If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape - is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns - -1.0. -*/ -double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const -{ - closestData = mDataContainer->constEnd(); - if (mDataContainer->isEmpty()) - return -1.0; - if (mLineStyle == lsNone && mScatterStyle.isNone()) - return -1.0; - - if (mDataContainer->size() == 1) - { - QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value); - closestData = mDataContainer->constBegin(); - return QCPVector2D(dataPoint-pixelPoint).length(); - } - - // calculate minimum distances to curve data points and find closestData iterator: - double minDistSqr = std::numeric_limits::max(); - // iterate over found data points and then choose the one with the shortest distance to pos: - QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); - QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); - for (QCPCurveDataContainer::const_iterator it=begin; it!=end; ++it) - { - const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestData = it; - } - } - - // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point): - if (mLineStyle != lsNone) - { - QVector lines; - getCurveLines(&lines, QCPDataRange(0, dataCount()), mParentPlot->selectionTolerance()*1.2); // optimized lines outside axis rect shouldn't respond to clicks at the edge, so use 1.2*tolerance as pen width - for (int i=0; i QCPBarsGroup::bars() const - - Returns all bars currently in this group. - - \see bars(int index) -*/ - -/*! \fn int QCPBarsGroup::size() const - - Returns the number of QCPBars plottables that are part of this group. - -*/ - -/*! \fn bool QCPBarsGroup::isEmpty() const - - Returns whether this bars group is empty. - - \see size -*/ - -/*! \fn bool QCPBarsGroup::contains(QCPBars *bars) - - Returns whether the specified \a bars plottable is part of this group. - -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a new bars group for the specified QCustomPlot instance. -*/ -QCPBarsGroup::QCPBarsGroup(QCustomPlot *parentPlot) : - QObject(parentPlot), - mParentPlot(parentPlot), - mSpacingType(stAbsolute), - mSpacing(4) -{ -} - -QCPBarsGroup::~QCPBarsGroup() -{ - clear(); -} - -/*! - Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. - - The actual spacing can then be specified with \ref setSpacing. - - \see setSpacing -*/ -void QCPBarsGroup::setSpacingType(SpacingType spacingType) -{ - mSpacingType = spacingType; -} - -/*! - Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is - defined by the current \ref SpacingType, which can be set with \ref setSpacingType. - - \see setSpacingType -*/ -void QCPBarsGroup::setSpacing(double spacing) -{ - mSpacing = spacing; -} - -/*! - Returns the QCPBars instance with the specified \a index in this group. If no such QCPBars - exists, returns 0. - - \see bars(), size -*/ -QCPBars *QCPBarsGroup::bars(int index) const -{ - if (index >= 0 && index < mBars.size()) - { - return mBars.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! - Removes all QCPBars plottables from this group. - - \see isEmpty -*/ -void QCPBarsGroup::clear() -{ - foreach (QCPBars *bars, mBars) // since foreach takes a copy, removing bars in the loop is okay - bars->setBarsGroup(0); // removes itself via removeBars -} - -/*! - Adds the specified \a bars plottable to this group. Alternatively, you can also use \ref - QCPBars::setBarsGroup on the \a bars instance. - - \see insert, remove -*/ -void QCPBarsGroup::append(QCPBars *bars) -{ - if (!bars) - { - qDebug() << Q_FUNC_INFO << "bars is 0"; - return; - } - - if (!mBars.contains(bars)) - bars->setBarsGroup(this); - else - qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast(bars); -} - -/*! - Inserts the specified \a bars plottable into this group at the specified index position \a i. - This gives you full control over the ordering of the bars. - - \a bars may already be part of this group. In that case, \a bars is just moved to the new index - position. - - \see append, remove -*/ -void QCPBarsGroup::insert(int i, QCPBars *bars) -{ - if (!bars) - { - qDebug() << Q_FUNC_INFO << "bars is 0"; - return; - } - - // first append to bars list normally: - if (!mBars.contains(bars)) - bars->setBarsGroup(this); - // then move to according position: - mBars.move(mBars.indexOf(bars), qBound(0, i, mBars.size()-1)); -} - -/*! - Removes the specified \a bars plottable from this group. - - \see contains, clear -*/ -void QCPBarsGroup::remove(QCPBars *bars) -{ - if (!bars) - { - qDebug() << Q_FUNC_INFO << "bars is 0"; - return; - } - - if (mBars.contains(bars)) - bars->setBarsGroup(0); - else - qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast(bars); -} - -/*! \internal - - Adds the specified \a bars to the internal mBars list of bars. This method does not change the - barsGroup property on \a bars. - - \see unregisterBars -*/ -void QCPBarsGroup::registerBars(QCPBars *bars) -{ - if (!mBars.contains(bars)) - mBars.append(bars); -} - -/*! \internal - - Removes the specified \a bars from the internal mBars list of bars. This method does not change - the barsGroup property on \a bars. - - \see registerBars -*/ -void QCPBarsGroup::unregisterBars(QCPBars *bars) -{ - mBars.removeOne(bars); -} - -/*! \internal - - Returns the pixel offset in the key dimension the specified \a bars plottable should have at the - given key coordinate \a keyCoord. The offset is relative to the pixel position of the key - coordinate \a keyCoord. -*/ -double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) -{ - // find list of all base bars in case some mBars are stacked: - QList baseBars; - foreach (const QCPBars *b, mBars) - { - while (b->barBelow()) - b = b->barBelow(); - if (!baseBars.contains(b)) - baseBars.append(b); - } - // find base bar this "bars" is stacked on: - const QCPBars *thisBase = bars; - while (thisBase->barBelow()) - thisBase = thisBase->barBelow(); - - // determine key pixel offset of this base bars considering all other base bars in this barsgroup: - double result = 0; - int index = baseBars.indexOf(thisBase); - if (index >= 0) - { - if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose) - { - return result; - } else - { - double lowerPixelWidth, upperPixelWidth; - int startIndex; - int dir = (index <= (baseBars.size()-1)/2) ? -1 : 1; // if bar is to lower keys of center, dir is negative - if (baseBars.size() % 2 == 0) // even number of bars - { - startIndex = baseBars.size()/2 + (dir < 0 ? -1 : 0); - result += getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing - } else // uneven number of bars - { - startIndex = (baseBars.size()-1)/2+dir; - baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); - result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar - result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing - } - for (int i = startIndex; i != index; i += dir) // add widths and spacings of bars in between center and our bars - { - baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); - result += qAbs(upperPixelWidth-lowerPixelWidth); - result += getPixelSpacing(baseBars.at(i), keyCoord); - } - // finally half of our bars width: - baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); - result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; - // correct sign of result depending on orientation and direction of key axis: - result *= dir*thisBase->keyAxis()->pixelOrientation(); - } - } - return result; -} - -/*! \internal - - Returns the spacing in pixels which is between this \a bars and the following one, both at the - key coordinate \a keyCoord. - - \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only - needed to get access to the key axis transformation and axis rect for the modes \ref - stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in - \ref stPlotCoords on a logarithmic axis. -*/ -double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) -{ - switch (mSpacingType) - { - case stAbsolute: - { - return mSpacing; - } - case stAxisRectRatio: - { - if (bars->keyAxis()->orientation() == Qt::Horizontal) - return bars->keyAxis()->axisRect()->width()*mSpacing; - else - return bars->keyAxis()->axisRect()->height()*mSpacing; - } - case stPlotCoords: - { - double keyPixel = bars->keyAxis()->coordToPixel(keyCoord); - return qAbs(bars->keyAxis()->coordToPixel(keyCoord+mSpacing)-keyPixel); - } - } - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPBarsData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPBarsData - \brief Holds the data of one single data point (one bar) for QCPBars. - - The stored data is: - \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey) - \li \a value: height coordinate on the value axis of this bar (this is the \a mainValue) - - The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for - \ref QCPDataContainer with \ref QCPBarsData as the DataType template parameter. See the - documentation there for an explanation regarding the data type's generic methods. - - \see QCPBarsDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPBarsData::sortKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPBarsData QCPBarsData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey. All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPBarsData::sortKeyIsMainKey() - - Since the member \a key is both the data point key coordinate and the data ordering parameter, - this method returns true. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPBarsData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPBarsData::mainValue() const - - Returns the \a value member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPBarsData::valueRange() const - - Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a bar data point with key and value set to zero. -*/ -QCPBarsData::QCPBarsData() : - key(0), - value(0) -{ -} - -/*! - Constructs a bar data point with the specified \a key and \a value. -*/ -QCPBarsData::QCPBarsData(double key, double value) : - key(key), - value(value) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPBars -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPBars - \brief A plottable representing a bar chart in a plot. - - \image html QCPBars.png - - To plot data, assign it with the \ref setData or \ref addData functions. - - \section qcpbars-appearance Changing the appearance - - The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). - The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. - - Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other - (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear - stacked. - - If you would like to group multiple QCPBars plottables together so they appear side by side as - shown below, use QCPBarsGroup. - - \image html QCPBarsGroup.png - - \section qcpbars-usage Usage - - Like all data representing objects in QCustomPlot, the QCPBars is a plottable - (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies - (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - - Usually, you first create an instance: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 - which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes - ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. - The newly created plottable can be modified, e.g.: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-2 -*/ - -/* start of documentation of inline functions */ - -/*! \fn QSharedPointer QCPBars::data() const - - Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may - use it to directly manipulate the data, which may be more convenient and faster than using the - regular \ref setData or \ref addData methods. -*/ - -/*! \fn QCPBars *QCPBars::barBelow() const - Returns the bars plottable that is directly below this bars plottable. - If there is no such plottable, returns 0. - - \see barAbove, moveBelow, moveAbove -*/ - -/*! \fn QCPBars *QCPBars::barAbove() const - Returns the bars plottable that is directly above this bars plottable. - If there is no such plottable, returns 0. - - \see barBelow, moveBelow, moveAbove -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a - keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually - but use QCustomPlot::removePlottable() instead. -*/ -QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis), - mWidth(0.75), - mWidthType(wtPlotCoords), - mBarsGroup(0), - mBaseValue(0), - mStackingGap(0) -{ - // modify inherited properties from abstract plottable: - mPen.setColor(Qt::blue); - mPen.setStyle(Qt::SolidLine); - mBrush.setColor(QColor(40, 50, 255, 30)); - mBrush.setStyle(Qt::SolidPattern); - mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); -} - -QCPBars::~QCPBars() -{ - setBarsGroup(0); - if (mBarBelow || mBarAbove) - connectBars(mBarBelow.data(), mBarAbove.data()); // take this bar out of any stacking -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPBars may share the same data container safely. - Modifying the data in the container will then affect all bars that share the container. Sharing - can be achieved by simply exchanging the data containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the bar's data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-2 - - \see addData -*/ -void QCPBars::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Replaces the current data with the provided points in \a keys and \a values. The provided - vectors should have equal length. Else, the number of added points will be the size of the - smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData -*/ -void QCPBars::setData(const QVector &keys, const QVector &values, bool alreadySorted) -{ - mDataContainer->clear(); - addData(keys, values, alreadySorted); -} - -/*! - Sets the width of the bars. - - How the number passed as \a width is interpreted (e.g. screen pixels, plot coordinates,...), - depends on the currently set width type, see \ref setWidthType and \ref WidthType. -*/ -void QCPBars::setWidth(double width) -{ - mWidth = width; -} - -/*! - Sets how the width of the bars is defined. See the documentation of \ref WidthType for an - explanation of the possible values for \a widthType. - - The default value is \ref wtPlotCoords. - - \see setWidth -*/ -void QCPBars::setWidthType(QCPBars::WidthType widthType) -{ - mWidthType = widthType; -} - -/*! - Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref - QCPBarsGroup::append. - - To remove this QCPBars from any group, set \a barsGroup to 0. -*/ -void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) -{ - // deregister at old group: - if (mBarsGroup) - mBarsGroup->unregisterBars(this); - mBarsGroup = barsGroup; - // register at new group: - if (mBarsGroup) - mBarsGroup->registerBars(this); -} - -/*! - Sets the base value of this bars plottable. - - The base value defines where on the value coordinate the bars start. How far the bars extend from - the base value is given by their individual value data. For example, if the base value is set to - 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at - 3. - - For stacked bars, only the base value of the bottom-most QCPBars has meaning. - - The default base value is 0. -*/ -void QCPBars::setBaseValue(double baseValue) -{ - mBaseValue = baseValue; -} - -/*! - If this bars plottable is stacked on top of another bars plottable (\ref moveAbove), this method - allows specifying a distance in \a pixels, by which the drawn bar rectangles will be separated by - the bars below it. -*/ -void QCPBars::setStackingGap(double pixels) -{ - mStackingGap = pixels; -} - -/*! \overload - - Adds the provided points in \a keys and \a values to the current data. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPBars::addData(const QVector &keys, const QVector &values, bool alreadySorted) -{ - if (keys.size() != values.size()) - qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); - const int n = qMin(keys.size(), values.size()); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->key = keys[i]; - it->value = values[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - Adds the provided data point as \a key and \a value to the current data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPBars::addData(double key, double value) -{ - mDataContainer->add(QCPBarsData(key, value)); -} - -/*! - Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear - below the bars of \a bars. The move target \a bars must use the same key and value axis as this - plottable. - - Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already - has a bars object below itself, this bars object is inserted between the two. If this bars object - is already between two other bars, the two other bars will be stacked on top of each other after - the operation. - - To remove this bars plottable from any stacking, set \a bars to 0. - - \see moveBelow, barAbove, barBelow -*/ -void QCPBars::moveBelow(QCPBars *bars) -{ - if (bars == this) return; - if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) - { - qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; - return; - } - // remove from stacking: - connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 - // if new bar given, insert this bar below it: - if (bars) - { - if (bars->mBarBelow) - connectBars(bars->mBarBelow.data(), this); - connectBars(this, bars); - } -} - -/*! - Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear - above the bars of \a bars. The move target \a bars must use the same key and value axis as this - plottable. - - Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already - has a bars object above itself, this bars object is inserted between the two. If this bars object - is already between two other bars, the two other bars will be stacked on top of each other after - the operation. - - To remove this bars plottable from any stacking, set \a bars to 0. - - \see moveBelow, barBelow, barAbove -*/ -void QCPBars::moveAbove(QCPBars *bars) -{ - if (bars == this) return; - if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) - { - qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; - return; - } - // remove from stacking: - connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 - // if new bar given, insert this bar above it: - if (bars) - { - if (bars->mBarAbove) - connectBars(this, bars->mBarAbove.data()); - connectBars(bars, this); - } -} - -/*! - \copydoc QCPPlottableInterface1D::selectTestRect -*/ -QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (rect.intersects(getBarRect(it->key, it->value))) - result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); - } - result.simplify(); - return result; -} - -/* inherits documentation from base class */ -double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - // get visible data range: - QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (getBarRect(it->key, it->value).contains(pos)) - { - if (details) - { - int pointIndex = it-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return mParentPlot->selectionTolerance()*0.99; - } - } - } - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - /* Note: If this QCPBars uses absolute pixels as width (or is in a QCPBarsGroup with spacing in - absolute pixels), using this method to adapt the key axis range to fit the bars into the - currently visible axis range will not work perfectly. Because in the moment the axis range is - changed to the new range, the fixed pixel widths/spacings will represent different coordinate - spans than before, which in turn would require a different key range to perfectly fit, and so on. - The only solution would be to iteratively approach the perfect fitting axis range, but the - mismatch isn't large enough in most applications, to warrant this here. If a user does need a - better fit, he should call the corresponding axis rescale multiple times in a row. - */ - QCPRange range; - range = mDataContainer->keyRange(foundRange, inSignDomain); - - // determine exact range of bars by including bar width and barsgroup offset: - if (foundRange && mKeyAxis) - { - double lowerPixelWidth, upperPixelWidth, keyPixel; - // lower range bound: - getPixelWidth(range.lower, lowerPixelWidth, upperPixelWidth); - keyPixel = mKeyAxis.data()->coordToPixel(range.lower) + lowerPixelWidth; - if (mBarsGroup) - keyPixel += mBarsGroup->keyPixelOffset(this, range.lower); - const double lowerCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); - if (!qIsNaN(lowerCorrected) && qIsFinite(lowerCorrected) && range.lower > lowerCorrected) - range.lower = lowerCorrected; - // upper range bound: - getPixelWidth(range.upper, lowerPixelWidth, upperPixelWidth); - keyPixel = mKeyAxis.data()->coordToPixel(range.upper) + upperPixelWidth; - if (mBarsGroup) - keyPixel += mBarsGroup->keyPixelOffset(this, range.upper); - const double upperCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); - if (!qIsNaN(upperCorrected) && qIsFinite(upperCorrected) && range.upper < upperCorrected) - range.upper = upperCorrected; - } - return range; -} - -/* inherits documentation from base class */ -QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - // Note: can't simply use mDataContainer->valueRange here because we need to - // take into account bar base value and possible stacking of multiple bars - QCPRange range; - range.lower = mBaseValue; - range.upper = mBaseValue; - bool haveLower = true; // set to true, because baseValue should always be visible in bar charts - bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts - QCPBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); - QCPBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); - if (inKeyRange != QCPRange()) - { - itBegin = mDataContainer->findBegin(inKeyRange.lower); - itEnd = mDataContainer->findEnd(inKeyRange.upper); - } - for (QCPBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - const double current = it->value + getStackedBaseValue(it->key, it->value >= 0); - if (qIsNaN(current)) continue; - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - } - - foundRange = true; // return true because bar charts always have the 0-line visible - return range; -} - -/* inherits documentation from base class */ -QPointF QCPBars::dataPixelPosition(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } - - const QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; - const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value); - const double keyPixel = keyAxis->coordToPixel(it->key) + (mBarsGroup ? mBarsGroup->keyPixelOffset(this, it->key) : 0); - if (keyAxis->orientation() == Qt::Horizontal) - return QPointF(keyPixel, valuePixel); - else - return QPointF(valuePixel, keyPixel); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return QPointF(); - } -} - -/* inherits documentation from base class */ -void QCPBars::draw(QCPPainter *painter) -{ - if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - if (mDataContainer->isEmpty()) return; - - QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - QCPBarsDataContainer::const_iterator begin = visibleBegin; - QCPBarsDataContainer::const_iterator end = visibleEnd; - mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); - if (begin == end) - continue; - - for (QCPBarsDataContainer::const_iterator it=begin; it!=end; ++it) - { - // check data validity if flag set: -#ifdef QCUSTOMPLOT_CHECK_DATA - if (QCP::isInvalidData(it->key, it->value)) - qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); -#endif - // draw bar: - if (isSelectedSegment && mSelectionDecorator) - { - mSelectionDecorator->applyBrush(painter); - mSelectionDecorator->applyPen(painter); - } else - { - painter->setBrush(mBrush); - painter->setPen(mPen); - } - applyDefaultAntialiasingHint(painter); - painter->drawPolygon(getBarRect(it->key, it->value)); - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - // draw filled rect: - applyDefaultAntialiasingHint(painter); - painter->setBrush(mBrush); - painter->setPen(mPen); - QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); - r.moveCenter(rect.center()); - painter->drawRect(r); -} - -/*! \internal - - called by \ref draw to determine which data (key) range is visible at the current key axis range - setting, so only that needs to be processed. It also takes into account the bar width. - - \a begin returns an iterator to the lowest data point that needs to be taken into account when - plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a - lower may still be just outside the visible range. - - \a end returns an iterator one higher than the highest visible data point. Same as before, \a end - may also lie just outside of the visible range. - - if the plottable contains no data, both \a begin and \a end point to constEnd. -*/ -void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const -{ - if (!mKeyAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key axis"; - begin = mDataContainer->constEnd(); - end = mDataContainer->constEnd(); - return; - } - if (mDataContainer->isEmpty()) - { - begin = mDataContainer->constEnd(); - end = mDataContainer->constEnd(); - return; - } - - // get visible data range as QMap iterators - begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower); - end = mDataContainer->findEnd(mKeyAxis.data()->range().upper); - double lowerPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().lower); - double upperPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().upper); - bool isVisible = false; - // walk left from begin to find lower bar that actually is completely outside visible pixel range: - QCPBarsDataContainer::const_iterator it = begin; - while (it != mDataContainer->constBegin()) - { - --it; - const QRectF barRect = getBarRect(it->key, it->value); - if (mKeyAxis.data()->orientation() == Qt::Horizontal) - isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.left() <= lowerPixelBound)); - else // keyaxis is vertical - isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.bottom() >= lowerPixelBound)); - if (isVisible) - begin = it; - else - break; - } - // walk right from ubound to find upper bar that actually is completely outside visible pixel range: - it = end; - while (it != mDataContainer->constEnd()) - { - const QRectF barRect = getBarRect(it->key, it->value); - if (mKeyAxis.data()->orientation() == Qt::Horizontal) - isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.right() >= upperPixelBound)); - else // keyaxis is vertical - isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.bottom() >= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.top() <= upperPixelBound)); - if (isVisible) - end = it+1; - else - break; - ++it; - } -} - -/*! \internal - - Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The - rect is shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref - setBaseValue), and to have non-overlapping border lines with the bars stacked below. -*/ -QRectF QCPBars::getBarRect(double key, double value) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } - - double lowerPixelWidth, upperPixelWidth; - getPixelWidth(key, lowerPixelWidth, upperPixelWidth); - double base = getStackedBaseValue(key, value >= 0); - double basePixel = valueAxis->coordToPixel(base); - double valuePixel = valueAxis->coordToPixel(base+value); - double keyPixel = keyAxis->coordToPixel(key); - if (mBarsGroup) - keyPixel += mBarsGroup->keyPixelOffset(this, key); - double bottomOffset = (mBarBelow && mPen != Qt::NoPen ? 1 : 0)*(mPen.isCosmetic() ? 1 : mPen.widthF()); - bottomOffset += mBarBelow ? mStackingGap : 0; - bottomOffset *= (value<0 ? -1 : 1)*valueAxis->pixelOrientation(); - if (qAbs(valuePixel-basePixel) <= qAbs(bottomOffset)) - bottomOffset = valuePixel-basePixel; - if (keyAxis->orientation() == Qt::Horizontal) - { - return QRectF(QPointF(keyPixel+lowerPixelWidth, valuePixel), QPointF(keyPixel+upperPixelWidth, basePixel+bottomOffset)).normalized(); - } else - { - return QRectF(QPointF(basePixel+bottomOffset, keyPixel+lowerPixelWidth), QPointF(valuePixel, keyPixel+upperPixelWidth)).normalized(); - } -} - -/*! \internal - - This function is used to determine the width of the bar at coordinate \a key, according to the - specified width (\ref setWidth) and width type (\ref setWidthType). - - The output parameters \a lower and \a upper return the number of pixels the bar extends to lower - and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a - lower is negative and \a upper positive). -*/ -void QCPBars::getPixelWidth(double key, double &lower, double &upper) const -{ - lower = 0; - upper = 0; - switch (mWidthType) - { - case wtAbsolute: - { - upper = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - lower = -upper; - break; - } - case wtAxisRectRatio: - { - if (mKeyAxis && mKeyAxis.data()->axisRect()) - { - if (mKeyAxis.data()->orientation() == Qt::Horizontal) - upper = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - else - upper = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - lower = -upper; - } else - qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; - break; - } - case wtPlotCoords: - { - if (mKeyAxis) - { - double keyPixel = mKeyAxis.data()->coordToPixel(key); - upper = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; - lower = mKeyAxis.data()->coordToPixel(key-mWidth*0.5)-keyPixel; - // no need to qSwap(lower, higher) when range reversed, because higher/lower are gained by - // coordinate transform which includes range direction - } else - qDebug() << Q_FUNC_INFO << "No key axis defined"; - break; - } - } -} - -/*! \internal - - This function is called to find at which value to start drawing the base of a bar at \a key, when - it is stacked on top of another QCPBars (e.g. with \ref moveAbove). - - positive and negative bars are separated per stack (positive are stacked above baseValue upwards, - negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the - bar for which we need the base value is negative, set \a positive to false. -*/ -double QCPBars::getStackedBaseValue(double key, bool positive) const -{ - if (mBarBelow) - { - double max = 0; // don't initialize with mBaseValue here because only base value of bottom-most bar has meaning in a bar stack - // find bars of mBarBelow that are approximately at key and find largest one: - double epsilon = qAbs(key)*(sizeof(key)==4 ? 1e-6 : 1e-14); // should be safe even when changed to use float at some point - if (key == 0) - epsilon = (sizeof(key)==4 ? 1e-6 : 1e-14); - QCPBarsDataContainer::const_iterator it = mBarBelow.data()->mDataContainer->findBegin(key-epsilon); - QCPBarsDataContainer::const_iterator itEnd = mBarBelow.data()->mDataContainer->findEnd(key+epsilon); - while (it != itEnd) - { - if (it->key > key-epsilon && it->key < key+epsilon) - { - if ((positive && it->value > max) || - (!positive && it->value < max)) - max = it->value; - } - ++it; - } - // recurse down the bar-stack to find the total height: - return max + mBarBelow.data()->getStackedBaseValue(key, positive); - } else - return mBaseValue; -} - -/*! \internal - - Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) - currently above lower and below upper will become disconnected to lower/upper. - - If lower is zero, upper will be disconnected at the bottom. - If upper is zero, lower will be disconnected at the top. -*/ -void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) -{ - if (!lower && !upper) return; - - if (!lower) // disconnect upper at bottom - { - // disconnect old bar below upper: - if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) - upper->mBarBelow.data()->mBarAbove = 0; - upper->mBarBelow = 0; - } else if (!upper) // disconnect lower at top - { - // disconnect old bar above lower: - if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) - lower->mBarAbove.data()->mBarBelow = 0; - lower->mBarAbove = 0; - } else // connect lower and upper - { - // disconnect old bar above lower: - if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) - lower->mBarAbove.data()->mBarBelow = 0; - // disconnect old bar below upper: - if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) - upper->mBarBelow.data()->mBarAbove = 0; - lower->mBarAbove = upper; - upper->mBarBelow = lower; - } -} -/* end of 'src/plottables/plottable-bars.cpp' */ - - -/* including file 'src/plottables/plottable-statisticalbox.cpp', size 28622 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPStatisticalBoxData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPStatisticalBoxData - \brief Holds the data of one single data point for QCPStatisticalBox. - - The stored data is: - - \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) - - \li \a minimum: the position of the lower whisker, typically the minimum measurement of the - sample that's not considered an outlier. - - \li \a lowerQuartile: the lower end of the box. The lower and the upper quartiles are the two - statistical quartiles around the median of the sample, they should contain 50% of the sample - data. - - \li \a median: the value of the median mark inside the quartile box. The median separates the - sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue) - - \li \a upperQuartile: the upper end of the box. The lower and the upper quartiles are the two - statistical quartiles around the median of the sample, they should contain 50% of the sample - data. - - \li \a maximum: the position of the upper whisker, typically the maximum measurement of the - sample that's not considered an outlier. - - \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key - coordinate of this data point (see \ref QCPStatisticalBox::setOutlierStyle) - - The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a - typedef for \ref QCPDataContainer with \ref QCPStatisticalBoxData as the DataType template - parameter. See the documentation there for an explanation regarding the data type's generic - methods. - - \see QCPStatisticalBoxDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPStatisticalBoxData::sortKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPStatisticalBoxData QCPStatisticalBoxData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey. All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPStatisticalBoxData::sortKeyIsMainKey() - - Since the member \a key is both the data point key coordinate and the data ordering parameter, - this method returns true. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPStatisticalBoxData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPStatisticalBoxData::mainValue() const - - Returns the \a median member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPStatisticalBoxData::valueRange() const - - Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box - data point, possibly further expanded by outliers. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a data point with key and all values set to zero. -*/ -QCPStatisticalBoxData::QCPStatisticalBoxData() : - key(0), - minimum(0), - lowerQuartile(0), - median(0), - upperQuartile(0), - maximum(0) -{ -} - -/*! - Constructs a data point with the specified \a key, \a minimum, \a lowerQuartile, \a median, \a - upperQuartile, \a maximum and optionally a number of \a outliers. -*/ -QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) : - key(key), - minimum(minimum), - lowerQuartile(lowerQuartile), - median(median), - upperQuartile(upperQuartile), - maximum(maximum), - outliers(outliers) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPStatisticalBox -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPStatisticalBox - \brief A plottable representing a single statistical box in a plot. - - \image html QCPStatisticalBox.png - - To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can - also access and modify the data via the \ref data method, which returns a pointer to the internal - \ref QCPStatisticalBoxDataContainer. - - Additionally each data point can itself have a list of outliers, drawn as scatter points at the - key coordinate of the respective statistical box data point. They can either be set by using the - respective \ref addData(double,double,double,double,double,double,const QVector&) - "addData" method or accessing the individual data points through \ref data, and setting the - QVector outliers of the data points directly. - - \section qcpstatisticalbox-appearance Changing the appearance - - The appearance of each data point box, ranging from the lower to the upper quartile, is - controlled via \ref setPen and \ref setBrush. You may change the width of the boxes with \ref - setWidth in plot coordinates. - - Each data point's visual representation also consists of two whiskers. Whiskers are the lines - which reach from the upper quartile to the maximum, and from the lower quartile to the minimum. - The appearance of the whiskers can be modified with: \ref setWhiskerPen, \ref setWhiskerBarPen, - \ref setWhiskerWidth. The whisker width is the width of the bar perpendicular to the whisker at - the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set - the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a - few pixels due to the pen cap being not perfectly flat. - - The median indicator line inside the box has its own pen, \ref setMedianPen. - - The outlier data points are drawn as normal scatter points. Their look can be controlled with - \ref setOutlierStyle - - \section qcpstatisticalbox-usage Usage - - Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable - (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies - (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - - Usually, you first create an instance: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 - which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes - ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. - The newly created plottable can be modified, e.g.: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-2 -*/ - -/* start documentation of inline functions */ - -/*! \fn QSharedPointer QCPStatisticalBox::data() const - - Returns a shared pointer to the internal data storage of type \ref - QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more - convenient and faster than using the regular \ref setData or \ref addData methods. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its - value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and - not have the same orientation. If either of these restrictions is violated, a corresponding - message is printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred - from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not - delete it manually but use QCustomPlot::removePlottable() instead. -*/ -QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis), - mWidth(0.5), - mWhiskerWidth(0.2), - mWhiskerPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap), - mWhiskerBarPen(Qt::black), - mWhiskerAntialiased(false), - mMedianPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap), - mOutlierStyle(QCPScatterStyle::ssCircle, Qt::blue, 6) -{ - setPen(QPen(Qt::black)); - setBrush(Qt::NoBrush); -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container - safely. Modifying the data in the container will then affect all statistical boxes that share the - container. Sharing can be achieved by simply exchanging the data containers wrapped in shared - pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the statistical box data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-2 - - \see addData -*/ -void QCPStatisticalBox::setData(QSharedPointer data) -{ - mDataContainer = data; -} -/*! \overload - - Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a - median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the - number of added points will be the size of the smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData -*/ -void QCPStatisticalBox::setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) -{ - mDataContainer->clear(); - addData(keys, minimum, lowerQuartile, median, upperQuartile, maximum, alreadySorted); -} - -/*! - Sets the width of the boxes in key coordinates. - - \see setWhiskerWidth -*/ -void QCPStatisticalBox::setWidth(double width) -{ - mWidth = width; -} - -/*! - Sets the width of the whiskers in key coordinates. - - Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower - quartile to the minimum. - - \see setWidth -*/ -void QCPStatisticalBox::setWhiskerWidth(double width) -{ - mWhiskerWidth = width; -} - -/*! - Sets the pen used for drawing the whisker backbone. - - Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower - quartile to the minimum. - - Make sure to set the \c capStyle of the passed \a pen to \c Qt::FlatCap. Otherwise the backbone - line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat. - - \see setWhiskerBarPen -*/ -void QCPStatisticalBox::setWhiskerPen(const QPen &pen) -{ - mWhiskerPen = pen; -} - -/*! - Sets the pen used for drawing the whisker bars. Those are the lines parallel to the key axis at - each end of the whisker backbone. - - Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower - quartile to the minimum. - - \see setWhiskerPen -*/ -void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) -{ - mWhiskerBarPen = pen; -} - -/*! - Sets whether the statistical boxes whiskers are drawn with antialiasing or not. - - Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and - QCustomPlot::setNotAntialiasedElements. -*/ -void QCPStatisticalBox::setWhiskerAntialiased(bool enabled) -{ - mWhiskerAntialiased = enabled; -} - -/*! - Sets the pen used for drawing the median indicator line inside the statistical boxes. -*/ -void QCPStatisticalBox::setMedianPen(const QPen &pen) -{ - mMedianPen = pen; -} - -/*! - Sets the appearance of the outlier data points. - - Outliers can be specified with the method - \ref addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) -*/ -void QCPStatisticalBox::setOutlierStyle(const QCPScatterStyle &style) -{ - mOutlierStyle = style; -} - -/*! \overload - - Adds the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and - \a maximum to the current data. The provided vectors should have equal length. Else, the number - of added points will be the size of the smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPStatisticalBox::addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) -{ - if (keys.size() != minimum.size() || minimum.size() != lowerQuartile.size() || lowerQuartile.size() != median.size() || - median.size() != upperQuartile.size() || upperQuartile.size() != maximum.size() || maximum.size() != keys.size()) - qDebug() << Q_FUNC_INFO << "keys, minimum, lowerQuartile, median, upperQuartile, maximum have different sizes:" - << keys.size() << minimum.size() << lowerQuartile.size() << median.size() << upperQuartile.size() << maximum.size(); - const int n = qMin(keys.size(), qMin(minimum.size(), qMin(lowerQuartile.size(), qMin(median.size(), qMin(upperQuartile.size(), maximum.size()))))); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->key = keys[i]; - it->minimum = minimum[i]; - it->lowerQuartile = lowerQuartile[i]; - it->median = median[i]; - it->upperQuartile = upperQuartile[i]; - it->maximum = maximum[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - - Adds the provided data point as \a key, \a minimum, \a lowerQuartile, \a median, \a upperQuartile - and \a maximum to the current data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPStatisticalBox::addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) -{ - mDataContainer->add(QCPStatisticalBoxData(key, minimum, lowerQuartile, median, upperQuartile, maximum, outliers)); -} - -/*! - \copydoc QCPPlottableInterface1D::selectTestRect -*/ -QCPDataSelection QCPStatisticalBox::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (rect.intersects(getQuartileBox(it))) - result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); - } - result.simplify(); - return result; -} - -/* inherits documentation from base class */ -double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis->axisRect()->rect().contains(pos.toPoint())) - { - // get visible data range: - QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; - QCPStatisticalBoxDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - getVisibleDataBounds(visibleBegin, visibleEnd); - double minDistSqr = std::numeric_limits::max(); - for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (getQuartileBox(it).contains(pos)) // quartile box - { - double currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } else // whiskers - { - const QVector whiskerBackbones(getWhiskerBackboneLines(it)); - for (int i=0; iconstBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return qSqrt(minDistSqr); - } - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPStatisticalBox::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); - // determine exact range by including width of bars/flags: - if (foundRange) - { - if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) - range.lower -= mWidth*0.5; - if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) - range.upper += mWidth*0.5; - } - return range; -} - -/* inherits documentation from base class */ -QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); -} - -/* inherits documentation from base class */ -void QCPStatisticalBox::draw(QCPPainter *painter) -{ - if (mDataContainer->isEmpty()) return; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - QCPStatisticalBoxDataContainer::const_iterator begin = visibleBegin; - QCPStatisticalBoxDataContainer::const_iterator end = visibleEnd; - mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); - if (begin == end) - continue; - - for (QCPStatisticalBoxDataContainer::const_iterator it=begin; it!=end; ++it) - { - // check data validity if flag set: -# ifdef QCUSTOMPLOT_CHECK_DATA - if (QCP::isInvalidData(it->key, it->minimum) || - QCP::isInvalidData(it->lowerQuartile, it->median) || - QCP::isInvalidData(it->upperQuartile, it->maximum)) - qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range has invalid data." << "Plottable name:" << name(); - for (int i=0; ioutliers.size(); ++i) - if (QCP::isInvalidData(it->outliers.at(i))) - qDebug() << Q_FUNC_INFO << "Data point outlier at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); -# endif - - if (isSelectedSegment && mSelectionDecorator) - { - mSelectionDecorator->applyPen(painter); - mSelectionDecorator->applyBrush(painter); - } else - { - painter->setPen(mPen); - painter->setBrush(mBrush); - } - QCPScatterStyle finalOutlierStyle = mOutlierStyle; - if (isSelectedSegment && mSelectionDecorator) - finalOutlierStyle = mSelectionDecorator->getFinalScatterStyle(mOutlierStyle); - drawStatisticalBox(painter, it, finalOutlierStyle); - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - // draw filled rect: - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - painter->setBrush(mBrush); - QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); - r.moveCenter(rect.center()); - painter->drawRect(r); -} - -/*! - Draws the graphical representation of a single statistical box with the data given by the - iterator \a it with the provided \a painter. - - If the statistical box has a set of outlier data points, they are drawn with \a outlierStyle. - - \see getQuartileBox, getWhiskerBackboneLines, getWhiskerBarLines -*/ -void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const -{ - // draw quartile box: - applyDefaultAntialiasingHint(painter); - const QRectF quartileBox = getQuartileBox(it); - painter->drawRect(quartileBox); - // draw median line with cliprect set to quartile box: - painter->save(); - painter->setClipRect(quartileBox, Qt::IntersectClip); - painter->setPen(mMedianPen); - painter->drawLine(QLineF(coordsToPixels(it->key-mWidth*0.5, it->median), coordsToPixels(it->key+mWidth*0.5, it->median))); - painter->restore(); - // draw whisker lines: - applyAntialiasingHint(painter, mWhiskerAntialiased, QCP::aePlottables); - painter->setPen(mWhiskerPen); - painter->drawLines(getWhiskerBackboneLines(it)); - painter->setPen(mWhiskerBarPen); - painter->drawLines(getWhiskerBarLines(it)); - // draw outliers: - applyScattersAntialiasingHint(painter); - outlierStyle.applyTo(painter, mPen); - for (int i=0; ioutliers.size(); ++i) - outlierStyle.drawShape(painter, coordsToPixels(it->key, it->outliers.at(i))); -} - -/*! \internal - - called by \ref draw to determine which data (key) range is visible at the current key axis range - setting, so only that needs to be processed. It also takes into account the bar width. - - \a begin returns an iterator to the lowest data point that needs to be taken into account when - plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a - lower may still be just outside the visible range. - - \a end returns an iterator one higher than the highest visible data point. Same as before, \a end - may also lie just outside of the visible range. - - if the plottable contains no data, both \a begin and \a end point to constEnd. -*/ -void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const -{ - if (!mKeyAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key axis"; - begin = mDataContainer->constEnd(); - end = mDataContainer->constEnd(); - return; - } - begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of box to include partially visible data points - end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of box to include partially visible data points -} - -/*! \internal - - Returns the box in plot coordinates (keys in x, values in y of the returned rect) that covers the - value range from the lower to the upper quartile, of the data given by \a it. - - \see drawStatisticalBox, getWhiskerBackboneLines, getWhiskerBarLines -*/ -QRectF QCPStatisticalBox::getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const -{ - QRectF result; - result.setTopLeft(coordsToPixels(it->key-mWidth*0.5, it->upperQuartile)); - result.setBottomRight(coordsToPixels(it->key+mWidth*0.5, it->lowerQuartile)); - return result; -} - -/*! \internal - - Returns the whisker backbones (keys in x, values in y of the returned lines) that cover the value - range from the minimum to the lower quartile, and from the upper quartile to the maximum of the - data given by \a it. - - \see drawStatisticalBox, getQuartileBox, getWhiskerBarLines -*/ -QVector QCPStatisticalBox::getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const -{ - QVector result(2); - result[0].setPoints(coordsToPixels(it->key, it->lowerQuartile), coordsToPixels(it->key, it->minimum)); // min backbone - result[1].setPoints(coordsToPixels(it->key, it->upperQuartile), coordsToPixels(it->key, it->maximum)); // max backbone - return result; -} - -/*! \internal - - Returns the whisker bars (keys in x, values in y of the returned lines) that are placed at the - end of the whisker backbones, at the minimum and maximum of the data given by \a it. - - \see drawStatisticalBox, getQuartileBox, getWhiskerBackboneLines -*/ -QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const -{ - QVector result(2); - result[0].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->minimum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->minimum)); // min bar - result[1].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->maximum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->maximum)); // max bar - return result; -} -/* end of 'src/plottables/plottable-statisticalbox.cpp' */ - - -/* including file 'src/plottables/plottable-colormap.cpp', size 47881 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPColorMapData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPColorMapData - \brief Holds the two-dimensional data of a QCPColorMap plottable. - - This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref - QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a - color, depending on the value. - - The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). - Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref - setKeyRange, \ref setValueRange). - - The data cells can be accessed in two ways: They can be directly addressed by an integer index - with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot - coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are - provided by the functions \ref coordToCell and \ref cellToCoord. - - A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if - allocated) has the same size as the data map. It can be accessed via \ref setAlpha, \ref - fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on - the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map. - - This class also buffers the minimum and maximum values that are in the data set, to provide - QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value - that is greater than the current maximum increases this maximum to the new value. However, - setting the cell that currently holds the maximum value to a smaller value doesn't decrease the - maximum again, because finding the true new maximum would require going through the entire data - array, which might be time consuming. The same holds for the data minimum. This functionality is - given by \ref recalculateDataBounds, such that you can decide when it is sensible to find the - true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience - parameter \a recalculateDataBounds which may be set to true to automatically call \ref - recalculateDataBounds internally. -*/ - -/* start of documentation of inline functions */ - -/*! \fn bool QCPColorMapData::isEmpty() const - - Returns whether this instance carries no data. This is equivalent to having a size where at least - one of the dimensions is 0 (see \ref setSize). -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction - and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap - at the coordinates \a keyRange and \a valueRange. - - \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange -*/ -QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : - mKeySize(0), - mValueSize(0), - mKeyRange(keyRange), - mValueRange(valueRange), - mIsEmpty(true), - mData(0), - mAlpha(0), - mDataModified(true) -{ - setSize(keySize, valueSize); - fill(0); -} - -QCPColorMapData::~QCPColorMapData() -{ - if (mData) - delete[] mData; - if (mAlpha) - delete[] mAlpha; -} - -/*! - Constructs a new QCPColorMapData instance copying the data and range of \a other. -*/ -QCPColorMapData::QCPColorMapData(const QCPColorMapData &other) : - mKeySize(0), - mValueSize(0), - mIsEmpty(true), - mData(0), - mAlpha(0), - mDataModified(true) -{ - *this = other; -} - -/*! - Overwrites this color map data instance with the data stored in \a other. The alpha map state is - transferred, too. -*/ -QCPColorMapData &QCPColorMapData::operator=(const QCPColorMapData &other) -{ - if (&other != this) - { - const int keySize = other.keySize(); - const int valueSize = other.valueSize(); - if (!other.mAlpha && mAlpha) - clearAlpha(); - setSize(keySize, valueSize); - if (other.mAlpha && !mAlpha) - createAlpha(false); - setRange(other.keyRange(), other.valueRange()); - if (!isEmpty()) - { - memcpy(mData, other.mData, sizeof(mData[0])*keySize*valueSize); - if (mAlpha) - memcpy(mAlpha, other.mAlpha, sizeof(mAlpha[0])*keySize*valueSize); - } - mDataBounds = other.mDataBounds; - mDataModified = true; - } - return *this; -} - -/* undocumented getter */ -double QCPColorMapData::data(double key, double value) -{ - int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; - int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; - if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) - return mData[valueCell*mKeySize + keyCell]; - else - return 0; -} - -/* undocumented getter */ -double QCPColorMapData::cell(int keyIndex, int valueIndex) -{ - if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) - return mData[valueIndex*mKeySize + keyIndex]; - else - return 0; -} - -/*! - Returns the alpha map value of the cell with the indices \a keyIndex and \a valueIndex. - - If this color map data doesn't have an alpha map (because \ref setAlpha was never called after - creation or after a call to \ref clearAlpha), returns 255, which corresponds to full opacity. - - \see setAlpha -*/ -unsigned char QCPColorMapData::alpha(int keyIndex, int valueIndex) -{ - if (mAlpha && keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) - return mAlpha[valueIndex*mKeySize + keyIndex]; - else - return 255; -} - -/*! - Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in - the value dimension. - - The current data is discarded and the map cells are set to 0, unless the map had already the - requested size. - - Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref - isEmpty returns true. - - \see setRange, setKeySize, setValueSize -*/ -void QCPColorMapData::setSize(int keySize, int valueSize) -{ - if (keySize != mKeySize || valueSize != mValueSize) - { - mKeySize = keySize; - mValueSize = valueSize; - if (mData) - delete[] mData; - mIsEmpty = mKeySize == 0 || mValueSize == 0; - if (!mIsEmpty) - { -#ifdef __EXCEPTIONS - try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message -#endif - mData = new double[mKeySize*mValueSize]; -#ifdef __EXCEPTIONS - } catch (...) { mData = 0; } -#endif - if (mData) - fill(0); - else - qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; - } else - mData = 0; - - if (mAlpha) // if we had an alpha map, recreate it with new size - createAlpha(); - - mDataModified = true; - } -} - -/*! - Resizes the data array to have \a keySize cells in the key dimension. - - The current data is discarded and the map cells are set to 0, unless the map had already the - requested size. - - Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. - - \see setKeyRange, setSize, setValueSize -*/ -void QCPColorMapData::setKeySize(int keySize) -{ - setSize(keySize, mValueSize); -} - -/*! - Resizes the data array to have \a valueSize cells in the value dimension. - - The current data is discarded and the map cells are set to 0, unless the map had already the - requested size. - - Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. - - \see setValueRange, setSize, setKeySize -*/ -void QCPColorMapData::setValueSize(int valueSize) -{ - setSize(mKeySize, valueSize); -} - -/*! - Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area - covered by the color map in plot coordinates. - - The outer cells will be centered on the range boundaries given to this function. For example, if - the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will - be cells centered on the key coordinates 2, 2.5 and 3. - - \see setSize -*/ -void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) -{ - setKeyRange(keyRange); - setValueRange(valueRange); -} - -/*! - Sets the coordinate range the data shall be distributed over in the key dimension. Together with - the value range, This defines the rectangular area covered by the color map in plot coordinates. - - The outer cells will be centered on the range boundaries given to this function. For example, if - the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will - be cells centered on the key coordinates 2, 2.5 and 3. - - \see setRange, setValueRange, setSize -*/ -void QCPColorMapData::setKeyRange(const QCPRange &keyRange) -{ - mKeyRange = keyRange; -} - -/*! - Sets the coordinate range the data shall be distributed over in the value dimension. Together with - the key range, This defines the rectangular area covered by the color map in plot coordinates. - - The outer cells will be centered on the range boundaries given to this function. For example, if - the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there - will be cells centered on the value coordinates 2, 2.5 and 3. - - \see setRange, setKeyRange, setSize -*/ -void QCPColorMapData::setValueRange(const QCPRange &valueRange) -{ - mValueRange = valueRange; -} - -/*! - Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a - z. - - \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or - value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, - you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to - determine the cell index. Rather directly access the cell index with \ref - QCPColorMapData::setCell. - - \see setCell, setRange -*/ -void QCPColorMapData::setData(double key, double value, double z) -{ - int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; - int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; - if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) - { - mData[valueCell*mKeySize + keyCell] = z; - if (z < mDataBounds.lower) - mDataBounds.lower = z; - if (z > mDataBounds.upper) - mDataBounds.upper = z; - mDataModified = true; - } -} - -/*! - Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices - enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see - \ref setSize). - - In the standard plot configuration (horizontal key axis and vertical value axis, both not - range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with - indices (keySize-1, valueSize-1) is in the top right corner of the color map. - - \see setData, setSize -*/ -void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) -{ - if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) - { - mData[valueIndex*mKeySize + keyIndex] = z; - if (z < mDataBounds.lower) - mDataBounds.lower = z; - if (z > mDataBounds.upper) - mDataBounds.upper = z; - mDataModified = true; - } else - qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; -} - -/*! - Sets the alpha of the color map cell given by \a keyIndex and \a valueIndex to \a alpha. A value - of 0 for \a alpha results in a fully transparent cell, and a value of 255 results in a fully - opaque cell. - - If an alpha map doesn't exist yet for this color map data, it will be created here. If you wish - to restore full opacity and free any allocated memory of the alpha map, call \ref clearAlpha. - - Note that the cell-wise alpha which can be configured here is independent of any alpha configured - in the color map's gradient (\ref QCPColorGradient). If a cell is affected both by the cell-wise - and gradient alpha, the alpha values will be blended accordingly during rendering of the color - map. - - \see fillAlpha, clearAlpha -*/ -void QCPColorMapData::setAlpha(int keyIndex, int valueIndex, unsigned char alpha) -{ - if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) - { - if (mAlpha || createAlpha()) - { - mAlpha[valueIndex*mKeySize + keyIndex] = alpha; - mDataModified = true; - } - } else - qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; -} - -/*! - Goes through the data and updates the buffered minimum and maximum data values. - - Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange - and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten - with a smaller or larger value respectively, since the buffered maximum/minimum values have been - updated the last time. Why this is the case is explained in the class description (\ref - QCPColorMapData). - - Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a - recalculateDataBounds for convenience. Setting this to true will call this method for you, before - doing the rescale. -*/ -void QCPColorMapData::recalculateDataBounds() -{ - if (mKeySize > 0 && mValueSize > 0) - { - double minHeight = mData[0]; - double maxHeight = mData[0]; - const int dataCount = mValueSize*mKeySize; - for (int i=0; i maxHeight) - maxHeight = mData[i]; - if (mData[i] < minHeight) - minHeight = mData[i]; - } - mDataBounds.lower = minHeight; - mDataBounds.upper = maxHeight; - } -} - -/*! - Frees the internal data memory. - - This is equivalent to calling \ref setSize "setSize(0, 0)". -*/ -void QCPColorMapData::clear() -{ - setSize(0, 0); -} - -/*! - Frees the internal alpha map. The color map will have full opacity again. -*/ -void QCPColorMapData::clearAlpha() -{ - if (mAlpha) - { - delete[] mAlpha; - mAlpha = 0; - mDataModified = true; - } -} - -/*! - Sets all cells to the value \a z. -*/ -void QCPColorMapData::fill(double z) -{ - const int dataCount = mValueSize*mKeySize; - for (int i=0; i(data); - return; - } - if (copy) - { - *mMapData = *data; - } else - { - delete mMapData; - mMapData = data; - } - mMapImageInvalidated = true; -} - -/*! - Sets the data range of this color map to \a dataRange. The data range defines which data values - are mapped to the color gradient. - - To make the data range span the full range of the data set, use \ref rescaleDataRange. - - \see QCPColorScale::setDataRange -*/ -void QCPColorMap::setDataRange(const QCPRange &dataRange) -{ - if (!QCPRange::validRange(dataRange)) return; - if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) - { - if (mDataScaleType == QCPAxis::stLogarithmic) - mDataRange = dataRange.sanitizedForLogScale(); - else - mDataRange = dataRange.sanitizedForLinScale(); - mMapImageInvalidated = true; - emit dataRangeChanged(mDataRange); - } -} - -/*! - Sets whether the data is correlated with the color gradient linearly or logarithmically. - - \see QCPColorScale::setDataScaleType -*/ -void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) -{ - if (mDataScaleType != scaleType) - { - mDataScaleType = scaleType; - mMapImageInvalidated = true; - emit dataScaleTypeChanged(mDataScaleType); - if (mDataScaleType == QCPAxis::stLogarithmic) - setDataRange(mDataRange.sanitizedForLogScale()); - } -} - -/*! - Sets the color gradient that is used to represent the data. For more details on how to create an - own gradient or use one of the preset gradients, see \ref QCPColorGradient. - - The colors defined by the gradient will be used to represent data values in the currently set - data range, see \ref setDataRange. Data points that are outside this data range will either be - colored uniformly with the respective gradient boundary color, or the gradient will repeat, - depending on \ref QCPColorGradient::setPeriodic. - - \see QCPColorScale::setGradient -*/ -void QCPColorMap::setGradient(const QCPColorGradient &gradient) -{ - if (mGradient != gradient) - { - mGradient = gradient; - mMapImageInvalidated = true; - emit gradientChanged(mGradient); - } -} - -/*! - Sets whether the color map image shall use bicubic interpolation when displaying the color map - shrinked or expanded, and not at a 1:1 pixel-to-data scale. - - \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" -*/ -void QCPColorMap::setInterpolate(bool enabled) -{ - mInterpolate = enabled; - mMapImageInvalidated = true; // because oversampling factors might need to change -} - -/*! - Sets whether the outer most data rows and columns are clipped to the specified key and value - range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). - - if \a enabled is set to false, the data points at the border of the color map are drawn with the - same width and height as all other data points. Since the data points are represented by - rectangles of one color centered on the data coordinate, this means that the shown color map - extends by half a data point over the specified key/value range in each direction. - - \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" -*/ -void QCPColorMap::setTightBoundary(bool enabled) -{ - mTightBoundary = enabled; -} - -/*! - Associates the color scale \a colorScale with this color map. - - This means that both the color scale and the color map synchronize their gradient, data range and - data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps - can be associated with one single color scale. This causes the color maps to also synchronize - those properties, via the mutual color scale. - - This function causes the color map to adopt the current color gradient, data range and data scale - type of \a colorScale. After this call, you may change these properties at either the color map - or the color scale, and the setting will be applied to both. - - Pass 0 as \a colorScale to disconnect the color scale from this color map again. -*/ -void QCPColorMap::setColorScale(QCPColorScale *colorScale) -{ - if (mColorScale) // unconnect signals from old color scale - { - disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); - disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); - disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); - disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); - disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); - disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); - } - mColorScale = colorScale; - if (mColorScale) // connect signals to new color scale - { - setGradient(mColorScale.data()->gradient()); - setDataRange(mColorScale.data()->dataRange()); - setDataScaleType(mColorScale.data()->dataScaleType()); - connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); - connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); - connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); - connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); - connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); - connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); - } -} - -/*! - Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the - current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, - only for the third data dimension of the color map. - - The minimum and maximum values of the data set are buffered in the internal QCPColorMapData - instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref - QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For - performance reasons, however, they are only updated in an expanding fashion. So the buffered - maximum can only increase and the buffered minimum can only decrease. In consequence, changes to - the data that actually lower the maximum of the data set (by overwriting the cell holding the - current maximum with a smaller value), aren't recognized and the buffered maximum overestimates - the true maximum of the data set. The same happens for the buffered minimum. To recalculate the - true minimum and maximum by explicitly looking at each cell, the method - QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a - recalculateDataBounds calls this method before setting the data range to the buffered minimum and - maximum. - - \see setDataRange -*/ -void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) -{ - if (recalculateDataBounds) - mMapData->recalculateDataBounds(); - setDataRange(mMapData->dataBounds()); -} - -/*! - Takes the current appearance of the color map and updates the legend icon, which is used to - represent this color map in the legend (see \ref QCPLegend). - - The \a transformMode specifies whether the rescaling is done by a faster, low quality image - scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm - (Qt::SmoothTransformation). - - The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to - the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured - legend icon size, the thumb will be rescaled during drawing of the legend item. - - \see setDataRange -*/ -void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) -{ - if (mMapImage.isNull() && !data()->isEmpty()) - updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) - - if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again - { - bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); - bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); - mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); - } -} - -/* inherits documentation from base class */ -double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if ((onlySelectable && mSelectable == QCP::stNone) || mMapData->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - double posKey, posValue; - pixelsToCoords(pos, posKey, posValue); - if (mMapData->keyRange().contains(posKey) && mMapData->valueRange().contains(posValue)) - { - if (details) - details->setValue(QCPDataSelection(QCPDataRange(0, 1))); // temporary solution, to facilitate whole-plottable selection. Replace in future version with segmented 2D selection. - return mParentPlot->selectionTolerance()*0.99; - } - } - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPColorMap::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - foundRange = true; - QCPRange result = mMapData->keyRange(); - result.normalize(); - if (inSignDomain == QCP::sdPositive) - { - if (result.lower <= 0 && result.upper > 0) - result.lower = result.upper*1e-3; - else if (result.lower <= 0 && result.upper <= 0) - foundRange = false; - } else if (inSignDomain == QCP::sdNegative) - { - if (result.upper >= 0 && result.lower < 0) - result.upper = result.lower*1e-3; - else if (result.upper >= 0 && result.lower >= 0) - foundRange = false; - } - return result; -} - -/* inherits documentation from base class */ -QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - if (inKeyRange != QCPRange()) - { - if (mMapData->keyRange().upper < inKeyRange.lower || mMapData->keyRange().lower > inKeyRange.upper) - { - foundRange = false; - return QCPRange(); - } - } - - foundRange = true; - QCPRange result = mMapData->valueRange(); - result.normalize(); - if (inSignDomain == QCP::sdPositive) - { - if (result.lower <= 0 && result.upper > 0) - result.lower = result.upper*1e-3; - else if (result.lower <= 0 && result.upper <= 0) - foundRange = false; - } else if (inSignDomain == QCP::sdNegative) - { - if (result.upper >= 0 && result.lower < 0) - result.upper = result.lower*1e-3; - else if (result.upper >= 0 && result.lower >= 0) - foundRange = false; - } - return result; -} - -/*! \internal - - Updates the internal map image buffer by going through the internal \ref QCPColorMapData and - turning the data values into color pixels with \ref QCPColorGradient::colorize. - - This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image - has been invalidated for a different reason (e.g. a change of the data range with \ref - setDataRange). - - If the map cell count is low, the image created will be oversampled in order to avoid a - QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images - without smooth transform enabled. Accordingly, oversampling isn't performed if \ref - setInterpolate is true. -*/ -void QCPColorMap::updateMapImage() -{ - QCPAxis *keyAxis = mKeyAxis.data(); - if (!keyAxis) return; - if (mMapData->isEmpty()) return; - - const QImage::Format format = QImage::Format_ARGB32_Premultiplied; - const int keySize = mMapData->keySize(); - const int valueSize = mMapData->valueSize(); - int keyOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)keySize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on - int valueOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)valueSize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on - - // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: - if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) - mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); - else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) - mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); - - if (mMapImage.isNull()) - { - qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; - mMapImage = QImage(QSize(10, 10), format); - mMapImage.fill(Qt::black); - } else - { - QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage - if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) - { - // resize undersampled map image to actual key/value cell sizes: - if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) - mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); - else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) - mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); - localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image - } else if (!mUndersampledMapImage.isNull()) - mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it - - const double *rawData = mMapData->mData; - const unsigned char *rawAlpha = mMapData->mAlpha; - if (keyAxis->orientation() == Qt::Horizontal) - { - const int lineCount = valueSize; - const int rowCount = keySize; - for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) - if (rawAlpha) - mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); - else - mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); - } - } else // keyAxis->orientation() == Qt::Vertical - { - const int lineCount = keySize; - const int rowCount = valueSize; - for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) - if (rawAlpha) - mGradient.colorize(rawData+line, rawAlpha+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); - else - mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); - } - } - - if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) - { - if (keyAxis->orientation() == Qt::Horizontal) - mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); - else - mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); - } - } - mMapData->mDataModified = false; - mMapImageInvalidated = false; -} - -/* inherits documentation from base class */ -void QCPColorMap::draw(QCPPainter *painter) -{ - if (mMapData->isEmpty()) return; - if (!mKeyAxis || !mValueAxis) return; - applyDefaultAntialiasingHint(painter); - - if (mMapData->mDataModified || mMapImageInvalidated) - updateMapImage(); - - // use buffer if painting vectorized (PDF): - const bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); - QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized - QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in - QPixmap mapBuffer; - if (useBuffer) - { - const double mapBufferPixelRatio = 3; // factor by which DPI is increased in embedded bitmaps - mapBufferTarget = painter->clipRegion().boundingRect(); - mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize()); - mapBuffer.fill(Qt::transparent); - localPainter = new QCPPainter(&mapBuffer); - localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); - localPainter->translate(-mapBufferTarget.topLeft()); - } - - QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), - coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); - // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): - double halfCellWidth = 0; // in pixels - double halfCellHeight = 0; // in pixels - if (keyAxis()->orientation() == Qt::Horizontal) - { - if (mMapData->keySize() > 1) - halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->keySize()-1); - if (mMapData->valueSize() > 1) - halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->valueSize()-1); - } else // keyAxis orientation is Qt::Vertical - { - if (mMapData->keySize() > 1) - halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->keySize()-1); - if (mMapData->valueSize() > 1) - halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->valueSize()-1); - } - imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight); - const bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); - const bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); - const bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform); - localPainter->setRenderHint(QPainter::SmoothPixmapTransform, mInterpolate); - QRegion clipBackup; - if (mTightBoundary) - { - clipBackup = localPainter->clipRegion(); - QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), - coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); - localPainter->setClipRect(tightClipRect, Qt::IntersectClip); - } - localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); - if (mTightBoundary) - localPainter->setClipRegion(clipBackup); - localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); - - if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter - { - delete localPainter; - painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer); - } -} - -/* inherits documentation from base class */ -void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - applyDefaultAntialiasingHint(painter); - // draw map thumbnail: - if (!mLegendIcon.isNull()) - { - QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation); - QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height()); - iconRect.moveCenter(rect.center()); - painter->drawPixmap(iconRect.topLeft(), scaledIcon); - } - /* - // draw frame: - painter->setBrush(Qt::NoBrush); - painter->setPen(Qt::black); - painter->drawRect(rect.adjusted(1, 1, 0, 0)); - */ -} -/* end of 'src/plottables/plottable-colormap.cpp' */ - - -/* including file 'src/plottables/plottable-financial.cpp', size 42610 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPFinancialData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPFinancialData - \brief Holds the data of one single data point for QCPFinancial. - - The stored data is: - \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) - \li \a open: The opening value at the data point (this is the \a mainValue) - \li \a high: The high/maximum value at the data point - \li \a low: The low/minimum value at the data point - \li \a close: The closing value at the data point - - The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef - for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the - documentation there for an explanation regarding the data type's generic methods. - - \see QCPFinancialDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPFinancialData::sortKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPFinancialData QCPFinancialData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey. All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPFinancialData::sortKeyIsMainKey() - - Since the member \a key is both the data point key coordinate and the data ordering parameter, - this method returns true. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPFinancialData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPFinancialData::mainValue() const - - Returns the \a open member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPFinancialData::valueRange() const - - Returns a QCPRange spanning from the \a low to the \a high value of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a data point with key and all values set to zero. -*/ -QCPFinancialData::QCPFinancialData() : - key(0), - open(0), - high(0), - low(0), - close(0) -{ -} - -/*! - Constructs a data point with the specified \a key and OHLC values. -*/ -QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) : - key(key), - open(open), - high(high), - low(low), - close(close) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPFinancial -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPFinancial - \brief A plottable representing a financial stock chart - - \image html QCPFinancial.png - - This plottable represents time series data binned to certain intervals, mainly used for stock - charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be - set via \ref setChartStyle. - - The data is passed via \ref setData as a set of open/high/low/close values at certain keys - (typically times). This means the data must be already binned appropriately. If data is only - available as a series of values (e.g. \a price against \a time), you can use the static - convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed - to \ref setData. - - The width of the OHLC bars/candlesticks can be controlled with \ref setWidth and \ref - setWidthType. A typical choice is to set the width type to \ref wtPlotCoords (the default) and - the width to (or slightly less than) one time bin interval width. - - \section qcpfinancial-appearance Changing the appearance - - Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored, - lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush). - - If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are - represented with a different pen and brush than negative changes (\a close < \a open). These can - be configured with \ref setPenPositive, \ref setPenNegative, \ref setBrushPositive, and \ref - setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection - however, the normal selected pen/brush (provided by the \ref selectionDecorator) is used, - irrespective of whether the chart is single- or two-colored. - - \section qcpfinancial-usage Usage - - Like all data representing objects in QCustomPlot, the QCPFinancial is a plottable - (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies - (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - - Usually, you first create an instance: - - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-1 - which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot - instance takes ownership of the plottable, so do not delete it manually but use - QCustomPlot::removePlottable() instead. The newly created plottable can be modified, e.g.: - - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-2 - Here we have used the static helper method \ref timeSeriesToOhlc, to turn a time-price data - series into a 24-hour binned open-high-low-close data series as QCPFinancial uses. -*/ - -/* start of documentation of inline functions */ - -/*! \fn QCPFinancialDataContainer *QCPFinancial::data() const - - Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may - use it to directly manipulate the data, which may be more convenient and faster than using the - regular \ref setData or \ref addData methods, in certain situations. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a - keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually - but use QCustomPlot::removePlottable() instead. -*/ -QCPFinancial::QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis), - mChartStyle(csCandlestick), - mWidth(0.5), - mWidthType(wtPlotCoords), - mTwoColored(true), - mBrushPositive(QBrush(QColor(50, 160, 0))), - mBrushNegative(QBrush(QColor(180, 0, 15))), - mPenPositive(QPen(QColor(40, 150, 0))), - mPenNegative(QPen(QColor(170, 5, 5))) -{ - mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); -} - -QCPFinancial::~QCPFinancial() -{ -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely. - Modifying the data in the container will then affect all financials that share the container. - Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the financial's data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-2 - - \see addData, timeSeriesToOhlc -*/ -void QCPFinancial::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a - close. The provided vectors should have equal length. Else, the number of added points will be - the size of the smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData, timeSeriesToOhlc -*/ -void QCPFinancial::setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) -{ - mDataContainer->clear(); - addData(keys, open, high, low, close, alreadySorted); -} - -/*! - Sets which representation style shall be used to display the OHLC data. -*/ -void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) -{ - mChartStyle = style; -} - -/*! - Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. - - A typical choice is to set it to (or slightly less than) one bin interval width. -*/ -void QCPFinancial::setWidth(double width) -{ - mWidth = width; -} - -/*! - Sets how the width of the financial bars is defined. See the documentation of \ref WidthType for - an explanation of the possible values for \a widthType. - - The default value is \ref wtPlotCoords. - - \see setWidth -*/ -void QCPFinancial::setWidthType(QCPFinancial::WidthType widthType) -{ - mWidthType = widthType; -} - -/*! - Sets whether this chart shall contrast positive from negative trends per data point by using two - separate colors to draw the respective bars/candlesticks. - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative -*/ -void QCPFinancial::setTwoColored(bool twoColored) -{ - mTwoColored = twoColored; -} - -/*! - If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills - of data points with a positive trend (i.e. bars/candlesticks with close >= open). - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setBrushNegative, setPenPositive, setPenNegative -*/ -void QCPFinancial::setBrushPositive(const QBrush &brush) -{ - mBrushPositive = brush; -} - -/*! - If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills - of data points with a negative trend (i.e. bars/candlesticks with close < open). - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setBrushPositive, setPenNegative, setPenPositive -*/ -void QCPFinancial::setBrushNegative(const QBrush &brush) -{ - mBrushNegative = brush; -} - -/*! - If \ref setTwoColored is set to true, this function controls the pen that is used to draw - outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setPenNegative, setBrushPositive, setBrushNegative -*/ -void QCPFinancial::setPenPositive(const QPen &pen) -{ - mPenPositive = pen; -} - -/*! - If \ref setTwoColored is set to true, this function controls the pen that is used to draw - outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setPenPositive, setBrushNegative, setBrushPositive -*/ -void QCPFinancial::setPenNegative(const QPen &pen) -{ - mPenNegative = pen; -} - -/*! \overload - - Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data. - The provided vectors should have equal length. Else, the number of added points will be the size - of the smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. - - \see timeSeriesToOhlc -*/ -void QCPFinancial::addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) -{ - if (keys.size() != open.size() || open.size() != high.size() || high.size() != low.size() || low.size() != close.size() || close.size() != keys.size()) - qDebug() << Q_FUNC_INFO << "keys, open, high, low, close have different sizes:" << keys.size() << open.size() << high.size() << low.size() << close.size(); - const int n = qMin(keys.size(), qMin(open.size(), qMin(high.size(), qMin(low.size(), close.size())))); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->key = keys[i]; - it->open = open[i]; - it->high = high[i]; - it->low = low[i]; - it->close = close[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - - Adds the provided data point as \a key, \a open, \a high, \a low and \a close to the current - data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. - - \see timeSeriesToOhlc -*/ -void QCPFinancial::addData(double key, double open, double high, double low, double close) -{ - mDataContainer->add(QCPFinancialData(key, open, high, low, close)); -} - -/*! - \copydoc QCPPlottableInterface1D::selectTestRect -*/ -QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - for (QCPFinancialDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (rect.intersects(selectionHitBox(it))) - result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); - } - result.simplify(); - return result; -} - -/* inherits documentation from base class */ -double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - // get visible data range: - QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; - QCPFinancialDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - getVisibleDataBounds(visibleBegin, visibleEnd); - // perform select test according to configured style: - double result = -1; - switch (mChartStyle) - { - case QCPFinancial::csOhlc: - result = ohlcSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; - case QCPFinancial::csCandlestick: - result = candlestickSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; - } - if (details) - { - int pointIndex = closestDataPoint-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return result; - } - - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPFinancial::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); - // determine exact range by including width of bars/flags: - if (foundRange) - { - if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) - range.lower -= mWidth*0.5; - if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) - range.upper += mWidth*0.5; - } - return range; -} - -/* inherits documentation from base class */ -QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); -} - -/*! - A convenience function that converts time series data (\a value against \a time) to OHLC binned - data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const - QCPFinancialDataContainer&). - - The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. - For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour - each, set \a timeBinSize to 3600. - - \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The - value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. - It merely defines the mathematical offset/phase of the bins that will be used to process the - data. -*/ -QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset) -{ - QCPFinancialDataContainer data; - int count = qMin(time.size(), value.size()); - if (count == 0) - return QCPFinancialDataContainer(); - - QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); - int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); - for (int i=0; i currentBinData.high) currentBinData.high = value.at(i); - if (i == count-1) // last data point is in current bin, finalize bin: - { - currentBinData.close = value.at(i); - currentBinData.key = timeBinOffset+(index)*timeBinSize; - data.add(currentBinData); - } - } else // data point not anymore in current bin, set close of old and open of new bin, and add old to map: - { - // finalize current bin: - currentBinData.close = value.at(i-1); - currentBinData.key = timeBinOffset+(index-1)*timeBinSize; - data.add(currentBinData); - // start next bin: - currentBinIndex = index; - currentBinData.open = value.at(i); - currentBinData.high = value.at(i); - currentBinData.low = value.at(i); - } - } - - return data; -} - -/* inherits documentation from base class */ -void QCPFinancial::draw(QCPPainter *painter) -{ - // get visible data range: - QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - QCPFinancialDataContainer::const_iterator begin = visibleBegin; - QCPFinancialDataContainer::const_iterator end = visibleEnd; - mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); - if (begin == end) - continue; - - // draw data segment according to configured style: - switch (mChartStyle) - { - case QCPFinancial::csOhlc: - drawOhlcPlot(painter, begin, end, isSelectedSegment); break; - case QCPFinancial::csCandlestick: - drawCandlestickPlot(painter, begin, end, isSelectedSegment); break; - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing - if (mChartStyle == csOhlc) - { - if (mTwoColored) - { - // draw upper left half icon with positive color: - painter->setBrush(mBrushPositive); - painter->setPen(mPenPositive); - painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); - // draw bottom right half icon with negative color: - painter->setBrush(mBrushNegative); - painter->setPen(mPenNegative); - painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); - } else - { - painter->setBrush(mBrush); - painter->setPen(mPen); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); - } - } else if (mChartStyle == csCandlestick) - { - if (mTwoColored) - { - // draw upper left half icon with positive color: - painter->setBrush(mBrushPositive); - painter->setPen(mPenPositive); - painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); - // draw bottom right half icon with negative color: - painter->setBrush(mBrushNegative); - painter->setPen(mPenNegative); - painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); - } else - { - painter->setBrush(mBrush); - painter->setPen(mPen); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); - } - } -} - -/*! \internal - - Draws the data from \a begin to \a end-1 as OHLC bars with the provided \a painter. - - This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. -*/ -void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - if (keyAxis->orientation() == Qt::Horizontal) - { - for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) - { - if (isSelected && mSelectionDecorator) - mSelectionDecorator->applyPen(painter); - else if (mTwoColored) - painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); - else - painter->setPen(mPen); - double keyPixel = keyAxis->coordToPixel(it->key); - double openPixel = valueAxis->coordToPixel(it->open); - double closePixel = valueAxis->coordToPixel(it->close); - // draw backbone: - painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(it->low))); - // draw open: - double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides - painter->drawLine(QPointF(keyPixel-pixelWidth, openPixel), QPointF(keyPixel, openPixel)); - // draw close: - painter->drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+pixelWidth, closePixel)); - } - } else - { - for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) - { - if (isSelected && mSelectionDecorator) - mSelectionDecorator->applyPen(painter); - else if (mTwoColored) - painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); - else - painter->setPen(mPen); - double keyPixel = keyAxis->coordToPixel(it->key); - double openPixel = valueAxis->coordToPixel(it->open); - double closePixel = valueAxis->coordToPixel(it->close); - // draw backbone: - painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(it->low), keyPixel)); - // draw open: - double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides - painter->drawLine(QPointF(openPixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel)); - // draw close: - painter->drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+pixelWidth)); - } - } -} - -/*! \internal - - Draws the data from \a begin to \a end-1 as Candlesticks with the provided \a painter. - - This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. -*/ -void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - if (keyAxis->orientation() == Qt::Horizontal) - { - for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) - { - if (isSelected && mSelectionDecorator) - { - mSelectionDecorator->applyPen(painter); - mSelectionDecorator->applyBrush(painter); - } else if (mTwoColored) - { - painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); - painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); - } else - { - painter->setPen(mPen); - painter->setBrush(mBrush); - } - double keyPixel = keyAxis->coordToPixel(it->key); - double openPixel = valueAxis->coordToPixel(it->open); - double closePixel = valueAxis->coordToPixel(it->close); - // draw high: - painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); - // draw low: - painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); - // draw open-close box: - double pixelWidth = getPixelWidth(it->key, keyPixel); - painter->drawRect(QRectF(QPointF(keyPixel-pixelWidth, closePixel), QPointF(keyPixel+pixelWidth, openPixel))); - } - } else // keyAxis->orientation() == Qt::Vertical - { - for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) - { - if (isSelected && mSelectionDecorator) - { - mSelectionDecorator->applyPen(painter); - mSelectionDecorator->applyBrush(painter); - } else if (mTwoColored) - { - painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); - painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); - } else - { - painter->setPen(mPen); - painter->setBrush(mBrush); - } - double keyPixel = keyAxis->coordToPixel(it->key); - double openPixel = valueAxis->coordToPixel(it->open); - double closePixel = valueAxis->coordToPixel(it->close); - // draw high: - painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); - // draw low: - painter->drawLine(QPointF(valueAxis->coordToPixel(it->low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); - // draw open-close box: - double pixelWidth = getPixelWidth(it->key, keyPixel); - painter->drawRect(QRectF(QPointF(closePixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel+pixelWidth))); - } - } -} - -/*! \internal - - This function is used to determine the width of the bar at coordinate \a key, according to the - specified width (\ref setWidth) and width type (\ref setWidthType). Provide the pixel position of - \a key in \a keyPixel (because usually this was already calculated via \ref QCPAxis::coordToPixel - when this function is called). - - It returns the number of pixels the bar extends to higher keys, relative to the \a key - coordinate. So with a non-reversed horizontal axis, the return value is positive. With a reversed - horizontal axis, the return value is negative. This is important so the open/close flags on the - \ref csOhlc bar are drawn to the correct side. -*/ -double QCPFinancial::getPixelWidth(double key, double keyPixel) const -{ - double result = 0; - switch (mWidthType) - { - case wtAbsolute: - { - if (mKeyAxis) - result = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - break; - } - case wtAxisRectRatio: - { - if (mKeyAxis && mKeyAxis.data()->axisRect()) - { - if (mKeyAxis.data()->orientation() == Qt::Horizontal) - result = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - else - result = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - } else - qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; - break; - } - case wtPlotCoords: - { - if (mKeyAxis) - result = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; - else - qDebug() << Q_FUNC_INFO << "No key axis defined"; - break; - } - } - return result; -} - -/*! \internal - - This method is a helper function for \ref selectTest. It is used to test for selection when the - chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. - - Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical - representation of the plottable, and \a closestDataPoint will point to the respective data point. -*/ -double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const -{ - closestDataPoint = mDataContainer->constEnd(); - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } - - double minDistSqr = std::numeric_limits::max(); - if (keyAxis->orientation() == Qt::Horizontal) - { - for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) - { - double keyPixel = keyAxis->coordToPixel(it->key); - // calculate distance to backbone: - double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low))); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } - } else // keyAxis->orientation() == Qt::Vertical - { - for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) - { - double keyPixel = keyAxis->coordToPixel(it->key); - // calculate distance to backbone: - double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel)); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } - } - return qSqrt(minDistSqr); -} - -/*! \internal - - This method is a helper function for \ref selectTest. It is used to test for selection when the - chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a - end. - - Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical - representation of the plottable, and \a closestDataPoint will point to the respective data point. -*/ -double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const -{ - closestDataPoint = mDataContainer->constEnd(); - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } - - double minDistSqr = std::numeric_limits::max(); - if (keyAxis->orientation() == Qt::Horizontal) - { - for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) - { - double currentDistSqr; - // determine whether pos is in open-close-box: - QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); - QCPRange boxValueRange(it->close, it->open); - double posKey, posValue; - pixelsToCoords(pos, posKey, posValue); - if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box - { - currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; - } else - { - // calculate distance to high/low lines: - double keyPixel = keyAxis->coordToPixel(it->key); - double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); - double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); - currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); - } - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } - } else // keyAxis->orientation() == Qt::Vertical - { - for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) - { - double currentDistSqr; - // determine whether pos is in open-close-box: - QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); - QCPRange boxValueRange(it->close, it->open); - double posKey, posValue; - pixelsToCoords(pos, posKey, posValue); - if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box - { - currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; - } else - { - // calculate distance to high/low lines: - double keyPixel = keyAxis->coordToPixel(it->key); - double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); - double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); - currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); - } - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } - } - return qSqrt(minDistSqr); -} - -/*! \internal - - called by the drawing methods to determine which data (key) range is visible at the current key - axis range setting, so only that needs to be processed. - - \a begin returns an iterator to the lowest data point that needs to be taken into account when - plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a - begin may still be just outside the visible range. - - \a end returns the iterator just above the highest data point that needs to be taken into - account. Same as before, \a end may also lie just outside of the visible range - - if the plottable contains no data, both \a begin and \a end point to \c constEnd. -*/ -void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const -{ - if (!mKeyAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key axis"; - begin = mDataContainer->constEnd(); - end = mDataContainer->constEnd(); - return; - } - begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of ohlc/candlestick to include partially visible data points - end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of ohlc/candlestick to include partially visible data points -} - -/*! \internal - - Returns the hit box in pixel coordinates that will be used for data selection with the selection - rect (\ref selectTestRect), of the data point given by \a it. -*/ -QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator it) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } - - double keyPixel = keyAxis->coordToPixel(it->key); - double highPixel = valueAxis->coordToPixel(it->high); - double lowPixel = valueAxis->coordToPixel(it->low); - double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it->key-mWidth*0.5); - if (keyAxis->orientation() == Qt::Horizontal) - return QRectF(keyPixel-keyWidthPixels, highPixel, keyWidthPixels*2, lowPixel-highPixel).normalized(); - else - return QRectF(highPixel, keyPixel-keyWidthPixels, lowPixel-highPixel, keyWidthPixels*2).normalized(); -} -/* end of 'src/plottables/plottable-financial.cpp' */ - - -/* including file 'src/plottables/plottable-errorbar.cpp', size 37355 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPErrorBarsData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPErrorBarsData - \brief Holds the data of one single error bar for QCPErrorBars. - - The stored data is: - \li \a errorMinus: how much the error bar extends towards negative coordinates from the data - point position - \li \a errorPlus: how much the error bar extends towards positive coordinates from the data point - position - - The container for storing the error bar information is \ref QCPErrorBarsDataContainer. It is a - typedef for QVector<\ref QCPErrorBarsData>. - - \see QCPErrorBarsDataContainer -*/ - -/*! - Constructs an error bar with errors set to zero. -*/ -QCPErrorBarsData::QCPErrorBarsData() : - errorMinus(0), - errorPlus(0) -{ -} - -/*! - Constructs an error bar with equal \a error in both negative and positive direction. -*/ -QCPErrorBarsData::QCPErrorBarsData(double error) : - errorMinus(error), - errorPlus(error) -{ -} - -/*! - Constructs an error bar with negative and positive errors set to \a errorMinus and \a errorPlus, - respectively. -*/ -QCPErrorBarsData::QCPErrorBarsData(double errorMinus, double errorPlus) : - errorMinus(errorMinus), - errorPlus(errorPlus) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPErrorBars -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPErrorBars - \brief A plottable that adds a set of error bars to other plottables. - - \image html QCPErrorBars.png - - The \ref QCPErrorBars plottable can be attached to other one-dimensional plottables (e.g. \ref - QCPGraph, \ref QCPCurve, \ref QCPBars, etc.) and equips them with error bars. - - Use \ref setDataPlottable to define for which plottable the \ref QCPErrorBars shall display the - error bars. The orientation of the error bars can be controlled with \ref setErrorType. - - By using \ref setData, you can supply the actual error data, either as symmetric error or - plus/minus asymmetric errors. \ref QCPErrorBars only stores the error data. The absolute - key/value position of each error bar will be adopted from the configured data plottable. The - error data of the \ref QCPErrorBars are associated one-to-one via their index to the data points - of the data plottable. You can directly access and manipulate the error bar data via \ref data. - - Set either of the plus/minus errors to NaN (qQNaN() or - std::numeric_limits::quiet_NaN()) to not show the respective error bar on the data point at - that index. - - \section qcperrorbars-appearance Changing the appearance - - The appearance of the error bars is defined by the pen (\ref setPen), and the width of the - whiskers (\ref setWhiskerWidth). Further, the error bar backbones may leave a gap around the data - point center to prevent that error bars are drawn too close to or even through scatter points. - This gap size can be controlled via \ref setSymbolGap. -*/ - -/* start of documentation of inline functions */ - -/*! \fn QSharedPointer QCPErrorBars::data() const - - Returns a shared pointer to the internal data storage of type \ref QCPErrorBarsDataContainer. You - may use it to directly manipulate the error values, which may be more convenient and faster than - using the regular \ref setData methods. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs an error bars plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - It is also important that the \a keyAxis and \a valueAxis are the same for the error bars - plottable and the data plottable that the error bars shall be drawn on (\ref setDataPlottable). - - The created \ref QCPErrorBars is automatically registered with the QCustomPlot instance inferred - from \a keyAxis. This QCustomPlot instance takes ownership of the \ref QCPErrorBars, so do not - delete it manually but use \ref QCustomPlot::removePlottable() instead. -*/ -QCPErrorBars::QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable(keyAxis, valueAxis), - mDataContainer(new QVector), - mErrorType(etValueError), - mWhiskerWidth(9), - mSymbolGap(10) -{ - setPen(QPen(Qt::black, 0)); - setBrush(Qt::NoBrush); -} - -QCPErrorBars::~QCPErrorBars() -{ -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple \ref QCPErrorBars instances may share the same data - container safely. Modifying the data in the container will then affect all \ref QCPErrorBars - instances that share the container. Sharing can be achieved by simply exchanging the data - containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, assign the - data containers directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-2 - (This uses different notation compared with other plottables, because the \ref QCPErrorBars - uses a \c QVector as its data container, instead of a \ref QCPDataContainer.) - - \see addData -*/ -void QCPErrorBars::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Sets symmetrical error values as specified in \a error. The errors will be associated one-to-one - by the data point index to the associated data plottable (\ref setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see addData -*/ -void QCPErrorBars::setData(const QVector &error) -{ - mDataContainer->clear(); - addData(error); -} - -/*! \overload - - Sets asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be - associated one-to-one by the data point index to the associated data plottable (\ref - setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see addData -*/ -void QCPErrorBars::setData(const QVector &errorMinus, const QVector &errorPlus) -{ - mDataContainer->clear(); - addData(errorMinus, errorPlus); -} - -/*! - Sets the data plottable to which the error bars will be applied. The error values specified e.g. - via \ref setData will be associated one-to-one by the data point index to the data points of \a - plottable. This means that the error bars will adopt the key/value coordinates of the data point - with the same index. - - The passed \a plottable must be a one-dimensional plottable, i.e. it must implement the \ref - QCPPlottableInterface1D. Further, it must not be a \ref QCPErrorBars instance itself. If either - of these restrictions is violated, a corresponding qDebug output is generated, and the data - plottable of this \ref QCPErrorBars instance is set to zero. - - For proper display, care must also be taken that the key and value axes of the \a plottable match - those configured for this \ref QCPErrorBars instance. -*/ -void QCPErrorBars::setDataPlottable(QCPAbstractPlottable *plottable) -{ - if (plottable && qobject_cast(plottable)) - { - mDataPlottable = 0; - qDebug() << Q_FUNC_INFO << "can't set another QCPErrorBars instance as data plottable"; - return; - } - if (plottable && !plottable->interface1D()) - { - mDataPlottable = 0; - qDebug() << Q_FUNC_INFO << "passed plottable doesn't implement 1d interface, can't associate with QCPErrorBars"; - return; - } - - mDataPlottable = plottable; -} - -/*! - Sets in which orientation the error bars shall appear on the data points. If your data needs both - error dimensions, create two \ref QCPErrorBars with different \a type. -*/ -void QCPErrorBars::setErrorType(ErrorType type) -{ - mErrorType = type; -} - -/*! - Sets the width of the whiskers (the short bars at the end of the actual error bar backbones) to - \a pixels. -*/ -void QCPErrorBars::setWhiskerWidth(double pixels) -{ - mWhiskerWidth = pixels; -} - -/*! - Sets the gap diameter around the data points that will be left out when drawing the error bar - backbones. This gap prevents that error bars are drawn too close to or even through scatter - points. -*/ -void QCPErrorBars::setSymbolGap(double pixels) -{ - mSymbolGap = pixels; -} - -/*! \overload - - Adds symmetrical error values as specified in \a error. The errors will be associated one-to-one - by the data point index to the associated data plottable (\ref setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see setData -*/ -void QCPErrorBars::addData(const QVector &error) -{ - addData(error, error); -} - -/*! \overload - - Adds asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be - associated one-to-one by the data point index to the associated data plottable (\ref - setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see setData -*/ -void QCPErrorBars::addData(const QVector &errorMinus, const QVector &errorPlus) -{ - if (errorMinus.size() != errorPlus.size()) - qDebug() << Q_FUNC_INFO << "minus and plus error vectors have different sizes:" << errorMinus.size() << errorPlus.size(); - const int n = qMin(errorMinus.size(), errorPlus.size()); - mDataContainer->reserve(n); - for (int i=0; iappend(QCPErrorBarsData(errorMinus.at(i), errorPlus.at(i))); -} - -/*! \overload - - Adds a single symmetrical error bar as specified in \a error. The errors will be associated - one-to-one by the data point index to the associated data plottable (\ref setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see setData -*/ -void QCPErrorBars::addData(double error) -{ - mDataContainer->append(QCPErrorBarsData(error)); -} - -/*! \overload - - Adds a single asymmetrical error bar as specified in \a errorMinus and \a errorPlus. The errors - will be associated one-to-one by the data point index to the associated data plottable (\ref - setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see setData -*/ -void QCPErrorBars::addData(double errorMinus, double errorPlus) -{ - mDataContainer->append(QCPErrorBarsData(errorMinus, errorPlus)); -} - -/* inherits documentation from base class */ -int QCPErrorBars::dataCount() const -{ - return mDataContainer->size(); -} - -/* inherits documentation from base class */ -double QCPErrorBars::dataMainKey(int index) const -{ - if (mDataPlottable) - return mDataPlottable->interface1D()->dataMainKey(index); - else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -double QCPErrorBars::dataSortKey(int index) const -{ - if (mDataPlottable) - return mDataPlottable->interface1D()->dataSortKey(index); - else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -double QCPErrorBars::dataMainValue(int index) const -{ - if (mDataPlottable) - return mDataPlottable->interface1D()->dataMainValue(index); - else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -QCPRange QCPErrorBars::dataValueRange(int index) const -{ - if (mDataPlottable) - { - const double value = mDataPlottable->interface1D()->dataMainValue(index); - if (index >= 0 && index < mDataContainer->size() && mErrorType == etValueError) - return QCPRange(value-mDataContainer->at(index).errorMinus, value+mDataContainer->at(index).errorPlus); - else - return QCPRange(value, value); - } else - { - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return QCPRange(); - } -} - -/* inherits documentation from base class */ -QPointF QCPErrorBars::dataPixelPosition(int index) const -{ - if (mDataPlottable) - return mDataPlottable->interface1D()->dataPixelPosition(index); - else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return QPointF(); -} - -/* inherits documentation from base class */ -bool QCPErrorBars::sortKeyIsMainKey() const -{ - if (mDataPlottable) - { - return mDataPlottable->interface1D()->sortKeyIsMainKey(); - } else - { - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return true; - } -} - -/*! - \copydoc QCPPlottableInterface1D::selectTestRect -*/ -QCPDataSelection QCPErrorBars::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if (!mDataPlottable) - return result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd, QCPDataRange(0, dataCount())); - - QVector backbones, whiskers; - for (QCPErrorBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - backbones.clear(); - whiskers.clear(); - getErrorBarLines(it, backbones, whiskers); - for (int i=0; iconstBegin(), it-mDataContainer->constBegin()+1), false); - break; - } - } - } - result.simplify(); - return result; -} - -/* inherits documentation from base class */ -int QCPErrorBars::findBegin(double sortKey, bool expandedRange) const -{ - if (mDataPlottable) - { - if (mDataContainer->isEmpty()) - return 0; - int beginIndex = mDataPlottable->interface1D()->findBegin(sortKey, expandedRange); - if (beginIndex >= mDataContainer->size()) - beginIndex = mDataContainer->size()-1; - return beginIndex; - } else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -int QCPErrorBars::findEnd(double sortKey, bool expandedRange) const -{ - if (mDataPlottable) - { - if (mDataContainer->isEmpty()) - return 0; - int endIndex = mDataPlottable->interface1D()->findEnd(sortKey, expandedRange); - if (endIndex > mDataContainer->size()) - endIndex = mDataContainer->size(); - return endIndex; - } else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -double QCPErrorBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if (!mDataPlottable) return -1; - - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - QCPErrorBarsDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - double result = pointDistance(pos, closestDataPoint); - if (details) - { - int pointIndex = closestDataPoint-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return result; - } else - return -1; -} - -/* inherits documentation from base class */ -void QCPErrorBars::draw(QCPPainter *painter) -{ - if (!mDataPlottable) return; - if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; - - // if the sort key isn't the main key, we must check the visibility for each data point/error bar individually - // (getVisibleDataBounds applies range restriction, but otherwise can only return full data range): - bool checkPointVisibility = !mDataPlottable->interface1D()->sortKeyIsMainKey(); - - // check data validity if flag set: -#ifdef QCUSTOMPLOT_CHECK_DATA - QCPErrorBarsDataContainer::const_iterator it; - for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) - { - if (QCP::isInvalidData(it->errorMinus, it->errorPlus)) - qDebug() << Q_FUNC_INFO << "Data point at index" << it-mDataContainer->constBegin() << "invalid." << "Plottable name:" << name(); - } -#endif - - applyDefaultAntialiasingHint(painter); - painter->setBrush(Qt::NoBrush); - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - QVector backbones, whiskers; - for (int i=0; i= unselectedSegments.size(); - if (isSelectedSegment && mSelectionDecorator) - mSelectionDecorator->applyPen(painter); - else - painter->setPen(mPen); - if (painter->pen().capStyle() == Qt::SquareCap) - { - QPen capFixPen(painter->pen()); - capFixPen.setCapStyle(Qt::FlatCap); - painter->setPen(capFixPen); - } - backbones.clear(); - whiskers.clear(); - for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) - { - if (!checkPointVisibility || errorBarVisible(it-mDataContainer->constBegin())) - getErrorBarLines(it, backbones, whiskers); - } - painter->drawLines(backbones); - painter->drawLines(whiskers); - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPErrorBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - if (mErrorType == etValueError && mValueAxis && mValueAxis->orientation() == Qt::Vertical) - { - painter->drawLine(QLineF(rect.center().x(), rect.top()+2, rect.center().x(), rect.bottom()-1)); - painter->drawLine(QLineF(rect.center().x()-4, rect.top()+2, rect.center().x()+4, rect.top()+2)); - painter->drawLine(QLineF(rect.center().x()-4, rect.bottom()-1, rect.center().x()+4, rect.bottom()-1)); - } else - { - painter->drawLine(QLineF(rect.left()+2, rect.center().y(), rect.right()-2, rect.center().y())); - painter->drawLine(QLineF(rect.left()+2, rect.center().y()-4, rect.left()+2, rect.center().y()+4)); - painter->drawLine(QLineF(rect.right()-2, rect.center().y()-4, rect.right()-2, rect.center().y()+4)); - } -} - -/* inherits documentation from base class */ -QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - if (!mDataPlottable) - { - foundRange = false; - return QCPRange(); - } - - QCPRange range; - bool haveLower = false; - bool haveUpper = false; - QCPErrorBarsDataContainer::const_iterator it; - for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) - { - if (mErrorType == etValueError) - { - // error bar doesn't extend in key dimension (except whisker but we ignore that here), so only use data point center - const double current = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); - if (qIsNaN(current)) continue; - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - } else // mErrorType == etKeyError - { - const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); - if (qIsNaN(dataKey)) continue; - // plus error: - double current = dataKey + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - // minus error: - current = dataKey - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - } - } - } - - if (haveUpper && !haveLower) - { - range.lower = range.upper; - haveLower = true; - } else if (haveLower && !haveUpper) - { - range.upper = range.lower; - haveUpper = true; - } - - foundRange = haveLower && haveUpper; - return range; -} - -/* inherits documentation from base class */ -QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - if (!mDataPlottable) - { - foundRange = false; - return QCPRange(); - } - - QCPRange range; - const bool restrictKeyRange = inKeyRange != QCPRange(); - bool haveLower = false; - bool haveUpper = false; - QCPErrorBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); - QCPErrorBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); - if (mDataPlottable->interface1D()->sortKeyIsMainKey() && restrictKeyRange) - { - itBegin = mDataContainer->constBegin()+findBegin(inKeyRange.lower); - itEnd = mDataContainer->constBegin()+findEnd(inKeyRange.upper); - } - for (QCPErrorBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - if (restrictKeyRange) - { - const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); - if (dataKey < inKeyRange.lower || dataKey > inKeyRange.upper) - continue; - } - if (mErrorType == etValueError) - { - const double dataValue = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); - if (qIsNaN(dataValue)) continue; - // plus error: - double current = dataValue + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - // minus error: - current = dataValue - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - } - } else // mErrorType == etKeyError - { - // error bar doesn't extend in value dimension (except whisker but we ignore that here), so only use data point center - const double current = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); - if (qIsNaN(current)) continue; - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - } - } - - if (haveUpper && !haveLower) - { - range.lower = range.upper; - haveLower = true; - } else if (haveLower && !haveUpper) - { - range.upper = range.lower; - haveUpper = true; - } - - foundRange = haveLower && haveUpper; - return range; -} - -/*! \internal - - Calculates the lines that make up the error bar belonging to the data point \a it. - - The resulting lines are added to \a backbones and \a whiskers. The vectors are not cleared, so - calling this method with different \a it but the same \a backbones and \a whiskers allows to - accumulate lines for multiple data points. - - This method assumes that \a it is a valid iterator within the bounds of this \ref QCPErrorBars - instance and within the bounds of the associated data plottable. -*/ -void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const -{ - if (!mDataPlottable) return; - - int index = it-mDataContainer->constBegin(); - QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); - if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) - return; - QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data(); - QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data(); - const double centerErrorAxisPixel = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); - const double centerOrthoAxisPixel = orthoAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); - const double centerErrorAxisCoord = errorAxis->pixelToCoord(centerErrorAxisPixel); // depending on plottable, this might be different from just mDataPlottable->interface1D()->dataMainKey/Value - const double symbolGap = mSymbolGap*0.5*errorAxis->pixelOrientation(); - // plus error: - double errorStart, errorEnd; - if (!qIsNaN(it->errorPlus)) - { - errorStart = centerErrorAxisPixel+symbolGap; - errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord+it->errorPlus); - if (errorAxis->orientation() == Qt::Vertical) - { - if ((errorStart > errorEnd) != errorAxis->rangeReversed()) - backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); - whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); - } else - { - if ((errorStart < errorEnd) != errorAxis->rangeReversed()) - backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); - whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); - } - } - // minus error: - if (!qIsNaN(it->errorMinus)) - { - errorStart = centerErrorAxisPixel-symbolGap; - errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord-it->errorMinus); - if (errorAxis->orientation() == Qt::Vertical) - { - if ((errorStart < errorEnd) != errorAxis->rangeReversed()) - backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); - whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); - } else - { - if ((errorStart > errorEnd) != errorAxis->rangeReversed()) - backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); - whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); - } - } -} - -/*! \internal - - This method outputs the currently visible data range via \a begin and \a end. The returned range - will also never exceed \a rangeRestriction. - - Since error bars with type \ref etKeyError may extend to arbitrarily positive and negative key - coordinates relative to their data point key, this method checks all outer error bars whether - they truly don't reach into the visible portion of the axis rect, by calling \ref - errorBarVisible. On the other hand error bars with type \ref etValueError that are associated - with data plottables whose sort key is equal to the main key (see \ref qcpdatacontainer-datatype - "QCPDataContainer DataType") can be handled very efficiently by finding the visible range of - error bars through binary search (\ref QCPPlottableInterface1D::findBegin and \ref - QCPPlottableInterface1D::findEnd). - - If the plottable's sort key is not equal to the main key, this method returns the full data - range, only restricted by \a rangeRestriction. Drawing optimization then has to be done on a - point-by-point basis in the \ref draw method. -*/ -void QCPErrorBars::getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key or value axis"; - end = mDataContainer->constEnd(); - begin = end; - return; - } - if (!mDataPlottable || rangeRestriction.isEmpty()) - { - end = mDataContainer->constEnd(); - begin = end; - return; - } - if (!mDataPlottable->interface1D()->sortKeyIsMainKey()) - { - // if the sort key isn't the main key, it's not possible to find a contiguous range of visible - // data points, so this method then only applies the range restriction and otherwise returns - // the full data range. Visibility checks must be done on a per-datapoin-basis during drawing - QCPDataRange dataRange(0, mDataContainer->size()); - dataRange = dataRange.bounded(rangeRestriction); - begin = mDataContainer->constBegin()+dataRange.begin(); - end = mDataContainer->constBegin()+dataRange.end(); - return; - } - - // get visible data range via interface from data plottable, and then restrict to available error data points: - const int n = qMin(mDataContainer->size(), mDataPlottable->interface1D()->dataCount()); - int beginIndex = mDataPlottable->interface1D()->findBegin(keyAxis->range().lower); - int endIndex = mDataPlottable->interface1D()->findEnd(keyAxis->range().upper); - int i = beginIndex; - while (i > 0 && i < n && i > rangeRestriction.begin()) - { - if (errorBarVisible(i)) - beginIndex = i; - --i; - } - i = endIndex; - while (i >= 0 && i < n && i < rangeRestriction.end()) - { - if (errorBarVisible(i)) - endIndex = i+1; - ++i; - } - QCPDataRange dataRange(beginIndex, endIndex); - dataRange = dataRange.bounded(rangeRestriction.bounded(QCPDataRange(0, mDataContainer->size()))); - begin = mDataContainer->constBegin()+dataRange.begin(); - end = mDataContainer->constBegin()+dataRange.end(); -} - -/*! \internal - - Calculates the minimum distance in pixels the error bars' representation has from the given \a - pixelPoint. This is used to determine whether the error bar was clicked or not, e.g. in \ref - selectTest. The closest data point to \a pixelPoint is returned in \a closestData. -*/ -double QCPErrorBars::pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const -{ - closestData = mDataContainer->constEnd(); - if (!mDataPlottable || mDataContainer->isEmpty()) - return -1.0; - if (!mKeyAxis || !mValueAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key or value axis"; - return -1.0; - } - - QCPErrorBarsDataContainer::const_iterator begin, end; - getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); - - // calculate minimum distances to error backbones (whiskers are ignored for speed) and find closestData iterator: - double minDistSqr = std::numeric_limits::max(); - QVector backbones, whiskers; - for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) - { - getErrorBarLines(it, backbones, whiskers); - for (int i=0; i &selectedSegments, QList &unselectedSegments) const -{ - selectedSegments.clear(); - unselectedSegments.clear(); - if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty - { - if (selected()) - selectedSegments << QCPDataRange(0, dataCount()); - else - unselectedSegments << QCPDataRange(0, dataCount()); - } else - { - QCPDataSelection sel(selection()); - sel.simplify(); - selectedSegments = sel.dataRanges(); - unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); - } -} - -/*! \internal - - Returns whether the error bar at the specified \a index is visible within the current key axis - range. - - This method assumes for performance reasons without checking that the key axis, the value axis, - and the data plottable (\ref setDataPlottable) are not zero and that \a index is within valid - bounds of this \ref QCPErrorBars instance and the bounds of the data plottable. -*/ -bool QCPErrorBars::errorBarVisible(int index) const -{ - QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); - const double centerKeyPixel = mKeyAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); - if (qIsNaN(centerKeyPixel)) - return false; - - double keyMin, keyMax; - if (mErrorType == etKeyError) - { - const double centerKey = mKeyAxis->pixelToCoord(centerKeyPixel); - const double errorPlus = mDataContainer->at(index).errorPlus; - const double errorMinus = mDataContainer->at(index).errorMinus; - keyMax = centerKey+(qIsNaN(errorPlus) ? 0 : errorPlus); - keyMin = centerKey-(qIsNaN(errorMinus) ? 0 : errorMinus); - } else // mErrorType == etValueError - { - keyMax = mKeyAxis->pixelToCoord(centerKeyPixel+mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); - keyMin = mKeyAxis->pixelToCoord(centerKeyPixel-mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); - } - return ((keyMax > mKeyAxis->range().lower) && (keyMin < mKeyAxis->range().upper)); -} - -/*! \internal - - Returns whether \a line intersects (or is contained in) \a pixelRect. - - \a line is assumed to be either perfectly horizontal or perfectly vertical, as is the case for - error bar lines. -*/ -bool QCPErrorBars::rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const -{ - if (pixelRect.left() > line.x1() && pixelRect.left() > line.x2()) - return false; - else if (pixelRect.right() < line.x1() && pixelRect.right() < line.x2()) - return false; - else if (pixelRect.top() > line.y1() && pixelRect.top() > line.y2()) - return false; - else if (pixelRect.bottom() < line.y1() && pixelRect.bottom() < line.y2()) - return false; - else - return true; -} -/* end of 'src/plottables/plottable-errorbar.cpp' */ - - -/* including file 'src/items/item-straightline.cpp', size 7592 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemStraightLine -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemStraightLine - \brief A straight line that spans infinitely in both directions - - \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a point1 and \a point2, which define the straight line. -*/ - -/*! - Creates a straight line item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - point1(createPosition(QLatin1String("point1"))), - point2(createPosition(QLatin1String("point2"))) -{ - point1->setCoords(0, 0); - point2->setCoords(1, 1); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue,2)); -} - -QCPItemStraightLine::~QCPItemStraightLine() -{ -} - -/*! - Sets the pen that will be used to draw the line - - \see setSelectedPen -*/ -void QCPItemStraightLine::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line when selected - - \see setPen, setSelected -*/ -void QCPItemStraightLine::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/* inherits documentation from base class */ -double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - return QCPVector2D(pos).distanceToStraightLine(point1->pixelPosition(), point2->pixelPosition()-point1->pixelPosition()); -} - -/* inherits documentation from base class */ -void QCPItemStraightLine::draw(QCPPainter *painter) -{ - QCPVector2D start(point1->pixelPosition()); - QCPVector2D end(point2->pixelPosition()); - // get visible segment of straight line inside clipRect: - double clipPad = mainPen().widthF(); - QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); - // paint visible segment, if existent: - if (!line.isNull()) - { - painter->setPen(mainPen()); - painter->drawLine(line); - } -} - -/*! \internal - - Returns the section of the straight line defined by \a base and direction vector \a - vec, that is visible in the specified \a rect. - - This is a helper function for \ref draw. -*/ -QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const -{ - double bx, by; - double gamma; - QLineF result; - if (vec.x() == 0 && vec.y() == 0) - return result; - if (qFuzzyIsNull(vec.x())) // line is vertical - { - // check top of rect: - bx = rect.left(); - by = rect.top(); - gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); - if (gamma >= 0 && gamma <= rect.width()) - result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical - } else if (qFuzzyIsNull(vec.y())) // line is horizontal - { - // check left of rect: - bx = rect.left(); - by = rect.top(); - gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); - if (gamma >= 0 && gamma <= rect.height()) - result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal - } else // line is skewed - { - QList pointVectors; - // check top of rect: - bx = rect.left(); - by = rect.top(); - gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); - if (gamma >= 0 && gamma <= rect.width()) - pointVectors.append(QCPVector2D(bx+gamma, by)); - // check bottom of rect: - bx = rect.left(); - by = rect.bottom(); - gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); - if (gamma >= 0 && gamma <= rect.width()) - pointVectors.append(QCPVector2D(bx+gamma, by)); - // check left of rect: - bx = rect.left(); - by = rect.top(); - gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); - if (gamma >= 0 && gamma <= rect.height()) - pointVectors.append(QCPVector2D(bx, by+gamma)); - // check right of rect: - bx = rect.right(); - by = rect.top(); - gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); - if (gamma >= 0 && gamma <= rect.height()) - pointVectors.append(QCPVector2D(bx, by+gamma)); - - // evaluate points: - if (pointVectors.size() == 2) - { - result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); - } else if (pointVectors.size() > 2) - { - // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: - double distSqrMax = 0; - QCPVector2D pv1, pv2; - for (int i=0; i distSqrMax) - { - pv1 = pointVectors.at(i); - pv2 = pointVectors.at(k); - distSqrMax = distSqr; - } - } - } - result.setPoints(pv1.toPointF(), pv2.toPointF()); - } - } - return result; -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the - item is not selected and mSelectedPen when it is. -*/ -QPen QCPItemStraightLine::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-straightline.cpp' */ - - -/* including file 'src/items/item-line.cpp', size 8498 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemLine -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemLine - \brief A line from one point to another - - \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a start and \a end, which define the end points of the line. - - With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. -*/ - -/*! - Creates a line item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - start(createPosition(QLatin1String("start"))), - end(createPosition(QLatin1String("end"))) -{ - start->setCoords(0, 0); - end->setCoords(1, 1); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue,2)); -} - -QCPItemLine::~QCPItemLine() -{ -} - -/*! - Sets the pen that will be used to draw the line - - \see setSelectedPen -*/ -void QCPItemLine::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line when selected - - \see setPen, setSelected -*/ -void QCPItemLine::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the line ending style of the head. The head corresponds to the \a end position. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify - a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode - - \see setTail -*/ -void QCPItemLine::setHead(const QCPLineEnding &head) -{ - mHead = head; -} - -/*! - Sets the line ending style of the tail. The tail corresponds to the \a start position. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify - a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode - - \see setHead -*/ -void QCPItemLine::setTail(const QCPLineEnding &tail) -{ - mTail = tail; -} - -/* inherits documentation from base class */ -double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - return qSqrt(QCPVector2D(pos).distanceSquaredToLine(start->pixelPosition(), end->pixelPosition())); -} - -/* inherits documentation from base class */ -void QCPItemLine::draw(QCPPainter *painter) -{ - QCPVector2D startVec(start->pixelPosition()); - QCPVector2D endVec(end->pixelPosition()); - if (qFuzzyIsNull((startVec-endVec).lengthSquared())) - return; - // get visible segment of straight line inside clipRect: - double clipPad = qMax(mHead.boundingDistance(), mTail.boundingDistance()); - clipPad = qMax(clipPad, (double)mainPen().widthF()); - QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); - // paint visible segment, if existent: - if (!line.isNull()) - { - painter->setPen(mainPen()); - painter->drawLine(line); - painter->setBrush(Qt::SolidPattern); - if (mTail.style() != QCPLineEnding::esNone) - mTail.draw(painter, startVec, startVec-endVec); - if (mHead.style() != QCPLineEnding::esNone) - mHead.draw(painter, endVec, endVec-startVec); - } -} - -/*! \internal - - Returns the section of the line defined by \a start and \a end, that is visible in the specified - \a rect. - - This is a helper function for \ref draw. -*/ -QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const -{ - bool containsStart = rect.contains(start.x(), start.y()); - bool containsEnd = rect.contains(end.x(), end.y()); - if (containsStart && containsEnd) - return QLineF(start.toPointF(), end.toPointF()); - - QCPVector2D base = start; - QCPVector2D vec = end-start; - double bx, by; - double gamma, mu; - QLineF result; - QList pointVectors; - - if (!qFuzzyIsNull(vec.y())) // line is not horizontal - { - // check top of rect: - bx = rect.left(); - by = rect.top(); - mu = (by-base.y())/vec.y(); - if (mu >= 0 && mu <= 1) - { - gamma = base.x()-bx + mu*vec.x(); - if (gamma >= 0 && gamma <= rect.width()) - pointVectors.append(QCPVector2D(bx+gamma, by)); - } - // check bottom of rect: - bx = rect.left(); - by = rect.bottom(); - mu = (by-base.y())/vec.y(); - if (mu >= 0 && mu <= 1) - { - gamma = base.x()-bx + mu*vec.x(); - if (gamma >= 0 && gamma <= rect.width()) - pointVectors.append(QCPVector2D(bx+gamma, by)); - } - } - if (!qFuzzyIsNull(vec.x())) // line is not vertical - { - // check left of rect: - bx = rect.left(); - by = rect.top(); - mu = (bx-base.x())/vec.x(); - if (mu >= 0 && mu <= 1) - { - gamma = base.y()-by + mu*vec.y(); - if (gamma >= 0 && gamma <= rect.height()) - pointVectors.append(QCPVector2D(bx, by+gamma)); - } - // check right of rect: - bx = rect.right(); - by = rect.top(); - mu = (bx-base.x())/vec.x(); - if (mu >= 0 && mu <= 1) - { - gamma = base.y()-by + mu*vec.y(); - if (gamma >= 0 && gamma <= rect.height()) - pointVectors.append(QCPVector2D(bx, by+gamma)); - } - } - - if (containsStart) - pointVectors.append(start); - if (containsEnd) - pointVectors.append(end); - - // evaluate points: - if (pointVectors.size() == 2) - { - result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); - } else if (pointVectors.size() > 2) - { - // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: - double distSqrMax = 0; - QCPVector2D pv1, pv2; - for (int i=0; i distSqrMax) - { - pv1 = pointVectors.at(i); - pv2 = pointVectors.at(k); - distSqrMax = distSqr; - } - } - } - result.setPoints(pv1.toPointF(), pv2.toPointF()); - } - return result; -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the - item is not selected and mSelectedPen when it is. -*/ -QPen QCPItemLine::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-line.cpp' */ - - -/* including file 'src/items/item-curve.cpp', size 7159 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemCurve -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemCurve - \brief A curved line from one point to another - - \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." - - It has four positions, \a start and \a end, which define the end points of the line, and two - control points which define the direction the line exits from the start and the direction from - which it approaches the end: \a startDir and \a endDir. - - With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an - arrow. - - Often it is desirable for the control points to stay at fixed relative positions to the start/end - point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, - and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. -*/ - -/*! - Creates a curve item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - start(createPosition(QLatin1String("start"))), - startDir(createPosition(QLatin1String("startDir"))), - endDir(createPosition(QLatin1String("endDir"))), - end(createPosition(QLatin1String("end"))) -{ - start->setCoords(0, 0); - startDir->setCoords(0.5, 0); - endDir->setCoords(0, 0.5); - end->setCoords(1, 1); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue,2)); -} - -QCPItemCurve::~QCPItemCurve() -{ -} - -/*! - Sets the pen that will be used to draw the line - - \see setSelectedPen -*/ -void QCPItemCurve::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line when selected - - \see setPen, setSelected -*/ -void QCPItemCurve::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the line ending style of the head. The head corresponds to the \a end position. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify - a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode - - \see setTail -*/ -void QCPItemCurve::setHead(const QCPLineEnding &head) -{ - mHead = head; -} - -/*! - Sets the line ending style of the tail. The tail corresponds to the \a start position. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify - a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode - - \see setHead -*/ -void QCPItemCurve::setTail(const QCPLineEnding &tail) -{ - mTail = tail; -} - -/* inherits documentation from base class */ -double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QPointF startVec(start->pixelPosition()); - QPointF startDirVec(startDir->pixelPosition()); - QPointF endDirVec(endDir->pixelPosition()); - QPointF endVec(end->pixelPosition()); - - QPainterPath cubicPath(startVec); - cubicPath.cubicTo(startDirVec, endDirVec, endVec); - - QPolygonF polygon = cubicPath.toSubpathPolygons().first(); - QCPVector2D p(pos); - double minDistSqr = std::numeric_limits::max(); - for (int i=1; ipixelPosition()); - QCPVector2D startDirVec(startDir->pixelPosition()); - QCPVector2D endDirVec(endDir->pixelPosition()); - QCPVector2D endVec(end->pixelPosition()); - if ((endVec-startVec).length() > 1e10) // too large curves cause crash - return; - - QPainterPath cubicPath(startVec.toPointF()); - cubicPath.cubicTo(startDirVec.toPointF(), endDirVec.toPointF(), endVec.toPointF()); - - // paint visible segment, if existent: - QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); - QRect cubicRect = cubicPath.controlPointRect().toRect(); - if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position - cubicRect.adjust(0, 0, 1, 1); - if (clip.intersects(cubicRect)) - { - painter->setPen(mainPen()); - painter->drawPath(cubicPath); - painter->setBrush(Qt::SolidPattern); - if (mTail.style() != QCPLineEnding::esNone) - mTail.draw(painter, startVec, M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); - if (mHead.style() != QCPLineEnding::esNone) - mHead.draw(painter, endVec, -cubicPath.angleAtPercent(1)/180.0*M_PI); - } -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the - item is not selected and mSelectedPen when it is. -*/ -QPen QCPItemCurve::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-curve.cpp' */ - - -/* including file 'src/items/item-rect.cpp', size 6479 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemRect -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemRect - \brief A rectangle - - \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a topLeft and \a bottomRight, which define the rectangle. -*/ - -/*! - Creates a rectangle item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - topLeft(createPosition(QLatin1String("topLeft"))), - bottomRight(createPosition(QLatin1String("bottomRight"))), - top(createAnchor(QLatin1String("top"), aiTop)), - topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), - right(createAnchor(QLatin1String("right"), aiRight)), - bottom(createAnchor(QLatin1String("bottom"), aiBottom)), - bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), - left(createAnchor(QLatin1String("left"), aiLeft)) -{ - topLeft->setCoords(0, 1); - bottomRight->setCoords(1, 0); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue,2)); - setBrush(Qt::NoBrush); - setSelectedBrush(Qt::NoBrush); -} - -QCPItemRect::~QCPItemRect() -{ -} - -/*! - Sets the pen that will be used to draw the line of the rectangle - - \see setSelectedPen, setBrush -*/ -void QCPItemRect::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line of the rectangle when selected - - \see setPen, setSelected -*/ -void QCPItemRect::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to - Qt::NoBrush. - - \see setSelectedBrush, setPen -*/ -void QCPItemRect::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a - brush to Qt::NoBrush. - - \see setBrush -*/ -void QCPItemRect::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/* inherits documentation from base class */ -double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()).normalized(); - bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; - return rectDistance(rect, pos, filledRect); -} - -/* inherits documentation from base class */ -void QCPItemRect::draw(QCPPainter *painter) -{ - QPointF p1 = topLeft->pixelPosition(); - QPointF p2 = bottomRight->pixelPosition(); - if (p1.toPoint() == p2.toPoint()) - return; - QRectF rect = QRectF(p1, p2).normalized(); - double clipPad = mainPen().widthF(); - QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); - if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect - { - painter->setPen(mainPen()); - painter->setBrush(mainBrush()); - painter->drawRect(rect); - } -} - -/* inherits documentation from base class */ -QPointF QCPItemRect::anchorPixelPosition(int anchorId) const -{ - QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); - switch (anchorId) - { - case aiTop: return (rect.topLeft()+rect.topRight())*0.5; - case aiTopRight: return rect.topRight(); - case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; - case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; - case aiBottomLeft: return rect.bottomLeft(); - case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; - } - - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemRect::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} - -/*! \internal - - Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item - is not selected and mSelectedBrush when it is. -*/ -QBrush QCPItemRect::mainBrush() const -{ - return mSelected ? mSelectedBrush : mBrush; -} -/* end of 'src/items/item-rect.cpp' */ - - -/* including file 'src/items/item-text.cpp', size 13338 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemText -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemText - \brief A text label - - \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." - - Its position is defined by the member \a position and the setting of \ref setPositionAlignment. - The latter controls which part of the text rect shall be aligned with \a position. - - The text alignment itself (i.e. left, center, right) can be controlled with \ref - setTextAlignment. - - The text may be rotated around the \a position point with \ref setRotation. -*/ - -/*! - Creates a text item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemText::QCPItemText(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - position(createPosition(QLatin1String("position"))), - topLeft(createAnchor(QLatin1String("topLeft"), aiTopLeft)), - top(createAnchor(QLatin1String("top"), aiTop)), - topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), - right(createAnchor(QLatin1String("right"), aiRight)), - bottomRight(createAnchor(QLatin1String("bottomRight"), aiBottomRight)), - bottom(createAnchor(QLatin1String("bottom"), aiBottom)), - bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), - left(createAnchor(QLatin1String("left"), aiLeft)), - mText(QLatin1String("text")), - mPositionAlignment(Qt::AlignCenter), - mTextAlignment(Qt::AlignTop|Qt::AlignHCenter), - mRotation(0) -{ - position->setCoords(0, 0); - - setPen(Qt::NoPen); - setSelectedPen(Qt::NoPen); - setBrush(Qt::NoBrush); - setSelectedBrush(Qt::NoBrush); - setColor(Qt::black); - setSelectedColor(Qt::blue); -} - -QCPItemText::~QCPItemText() -{ -} - -/*! - Sets the color of the text. -*/ -void QCPItemText::setColor(const QColor &color) -{ - mColor = color; -} - -/*! - Sets the color of the text that will be used when the item is selected. -*/ -void QCPItemText::setSelectedColor(const QColor &color) -{ - mSelectedColor = color; -} - -/*! - Sets the pen that will be used do draw a rectangular border around the text. To disable the - border, set \a pen to Qt::NoPen. - - \see setSelectedPen, setBrush, setPadding -*/ -void QCPItemText::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used do draw a rectangular border around the text, when the item is - selected. To disable the border, set \a pen to Qt::NoPen. - - \see setPen -*/ -void QCPItemText::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the brush that will be used do fill the background of the text. To disable the - background, set \a brush to Qt::NoBrush. - - \see setSelectedBrush, setPen, setPadding -*/ -void QCPItemText::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the - background, set \a brush to Qt::NoBrush. - - \see setBrush -*/ -void QCPItemText::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/*! - Sets the font of the text. - - \see setSelectedFont, setColor -*/ -void QCPItemText::setFont(const QFont &font) -{ - mFont = font; -} - -/*! - Sets the font of the text that will be used when the item is selected. - - \see setFont -*/ -void QCPItemText::setSelectedFont(const QFont &font) -{ - mSelectedFont = font; -} - -/*! - Sets the text that will be displayed. Multi-line texts are supported by inserting a line break - character, e.g. '\n'. - - \see setFont, setColor, setTextAlignment -*/ -void QCPItemText::setText(const QString &text) -{ - mText = text; -} - -/*! - Sets which point of the text rect shall be aligned with \a position. - - Examples: - \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such - that the top of the text rect will be horizontally centered on \a position. - \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the - bottom left corner of the text rect. - - If you want to control the alignment of (multi-lined) text within the text rect, use \ref - setTextAlignment. -*/ -void QCPItemText::setPositionAlignment(Qt::Alignment alignment) -{ - mPositionAlignment = alignment; -} - -/*! - Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). -*/ -void QCPItemText::setTextAlignment(Qt::Alignment alignment) -{ - mTextAlignment = alignment; -} - -/*! - Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated - around \a position. -*/ -void QCPItemText::setRotation(double degrees) -{ - mRotation = degrees; -} - -/*! - Sets the distance between the border of the text rectangle and the text. The appearance (and - visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. -*/ -void QCPItemText::setPadding(const QMargins &padding) -{ - mPadding = padding; -} - -/* inherits documentation from base class */ -double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - // The rect may be rotated, so we transform the actual clicked pos to the rotated - // coordinate system, so we can use the normal rectDistance function for non-rotated rects: - QPointF positionPixels(position->pixelPosition()); - QTransform inputTransform; - inputTransform.translate(positionPixels.x(), positionPixels.y()); - inputTransform.rotate(-mRotation); - inputTransform.translate(-positionPixels.x(), -positionPixels.y()); - QPointF rotatedPos = inputTransform.map(pos); - QFontMetrics fontMetrics(mFont); - QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); - QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); - QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); - textBoxRect.moveTopLeft(textPos.toPoint()); - - return rectDistance(textBoxRect, rotatedPos, true); -} - -/* inherits documentation from base class */ -void QCPItemText::draw(QCPPainter *painter) -{ - QPointF pos(position->pixelPosition()); - QTransform transform = painter->transform(); - transform.translate(pos.x(), pos.y()); - if (!qFuzzyIsNull(mRotation)) - transform.rotate(mRotation); - painter->setFont(mainFont()); - QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); - QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); - QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation - textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); - textBoxRect.moveTopLeft(textPos.toPoint()); - double clipPad = mainPen().widthF(); - QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); - if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect()))) - { - painter->setTransform(transform); - if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || - (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) - { - painter->setPen(mainPen()); - painter->setBrush(mainBrush()); - painter->drawRect(textBoxRect); - } - painter->setBrush(Qt::NoBrush); - painter->setPen(QPen(mainColor())); - painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); - } -} - -/* inherits documentation from base class */ -QPointF QCPItemText::anchorPixelPosition(int anchorId) const -{ - // get actual rect points (pretty much copied from draw function): - QPointF pos(position->pixelPosition()); - QTransform transform; - transform.translate(pos.x(), pos.y()); - if (!qFuzzyIsNull(mRotation)) - transform.rotate(mRotation); - QFontMetrics fontMetrics(mainFont()); - QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); - QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); - QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation - textBoxRect.moveTopLeft(textPos.toPoint()); - QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); - - switch (anchorId) - { - case aiTopLeft: return rectPoly.at(0); - case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; - case aiTopRight: return rectPoly.at(1); - case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; - case aiBottomRight: return rectPoly.at(2); - case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; - case aiBottomLeft: return rectPoly.at(3); - case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; - } - - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Returns the point that must be given to the QPainter::drawText function (which expects the top - left point of the text rect), according to the position \a pos, the text bounding box \a rect and - the requested \a positionAlignment. - - For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point - will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally - drawn at that point, the lower left corner of the resulting text rect is at \a pos. -*/ -QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const -{ - if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) - return pos; - - QPointF result = pos; // start at top left - if (positionAlignment.testFlag(Qt::AlignHCenter)) - result.rx() -= rect.width()/2.0; - else if (positionAlignment.testFlag(Qt::AlignRight)) - result.rx() -= rect.width(); - if (positionAlignment.testFlag(Qt::AlignVCenter)) - result.ry() -= rect.height()/2.0; - else if (positionAlignment.testFlag(Qt::AlignBottom)) - result.ry() -= rect.height(); - return result; -} - -/*! \internal - - Returns the font that should be used for drawing text. Returns mFont when the item is not selected - and mSelectedFont when it is. -*/ -QFont QCPItemText::mainFont() const -{ - return mSelected ? mSelectedFont : mFont; -} - -/*! \internal - - Returns the color that should be used for drawing text. Returns mColor when the item is not - selected and mSelectedColor when it is. -*/ -QColor QCPItemText::mainColor() const -{ - return mSelected ? mSelectedColor : mColor; -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemText::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} - -/*! \internal - - Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item - is not selected and mSelectedBrush when it is. -*/ -QBrush QCPItemText::mainBrush() const -{ - return mSelected ? mSelectedBrush : mBrush; -} -/* end of 'src/items/item-text.cpp' */ - - -/* including file 'src/items/item-ellipse.cpp', size 7863 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemEllipse -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemEllipse - \brief An ellipse - - \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. -*/ - -/*! - Creates an ellipse item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - topLeft(createPosition(QLatin1String("topLeft"))), - bottomRight(createPosition(QLatin1String("bottomRight"))), - topLeftRim(createAnchor(QLatin1String("topLeftRim"), aiTopLeftRim)), - top(createAnchor(QLatin1String("top"), aiTop)), - topRightRim(createAnchor(QLatin1String("topRightRim"), aiTopRightRim)), - right(createAnchor(QLatin1String("right"), aiRight)), - bottomRightRim(createAnchor(QLatin1String("bottomRightRim"), aiBottomRightRim)), - bottom(createAnchor(QLatin1String("bottom"), aiBottom)), - bottomLeftRim(createAnchor(QLatin1String("bottomLeftRim"), aiBottomLeftRim)), - left(createAnchor(QLatin1String("left"), aiLeft)), - center(createAnchor(QLatin1String("center"), aiCenter)) -{ - topLeft->setCoords(0, 1); - bottomRight->setCoords(1, 0); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue, 2)); - setBrush(Qt::NoBrush); - setSelectedBrush(Qt::NoBrush); -} - -QCPItemEllipse::~QCPItemEllipse() -{ -} - -/*! - Sets the pen that will be used to draw the line of the ellipse - - \see setSelectedPen, setBrush -*/ -void QCPItemEllipse::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line of the ellipse when selected - - \see setPen, setSelected -*/ -void QCPItemEllipse::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to - Qt::NoBrush. - - \see setSelectedBrush, setPen -*/ -void QCPItemEllipse::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a - brush to Qt::NoBrush. - - \see setBrush -*/ -void QCPItemEllipse::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/* inherits documentation from base class */ -double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QPointF p1 = topLeft->pixelPosition(); - QPointF p2 = bottomRight->pixelPosition(); - QPointF center((p1+p2)/2.0); - double a = qAbs(p1.x()-p2.x())/2.0; - double b = qAbs(p1.y()-p2.y())/2.0; - double x = pos.x()-center.x(); - double y = pos.y()-center.y(); - - // distance to border: - double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); - double result = qAbs(c-1)*qSqrt(x*x+y*y); - // filled ellipse, allow click inside to count as hit: - if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) - { - if (x*x/(a*a) + y*y/(b*b) <= 1) - result = mParentPlot->selectionTolerance()*0.99; - } - return result; -} - -/* inherits documentation from base class */ -void QCPItemEllipse::draw(QCPPainter *painter) -{ - QPointF p1 = topLeft->pixelPosition(); - QPointF p2 = bottomRight->pixelPosition(); - if (p1.toPoint() == p2.toPoint()) - return; - QRectF ellipseRect = QRectF(p1, p2).normalized(); - QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); - if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect - { - painter->setPen(mainPen()); - painter->setBrush(mainBrush()); -#ifdef __EXCEPTIONS - try // drawEllipse sometimes throws exceptions if ellipse is too big - { -#endif - painter->drawEllipse(ellipseRect); -#ifdef __EXCEPTIONS - } catch (...) - { - qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; - setVisible(false); - } -#endif - } -} - -/* inherits documentation from base class */ -QPointF QCPItemEllipse::anchorPixelPosition(int anchorId) const -{ - QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); - switch (anchorId) - { - case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); - case aiTop: return (rect.topLeft()+rect.topRight())*0.5; - case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); - case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; - case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); - case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; - case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); - case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; - case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; - } - - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemEllipse::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} - -/*! \internal - - Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item - is not selected and mSelectedBrush when it is. -*/ -QBrush QCPItemEllipse::mainBrush() const -{ - return mSelected ? mSelectedBrush : mBrush; -} -/* end of 'src/items/item-ellipse.cpp' */ - - -/* including file 'src/items/item-pixmap.cpp', size 10615 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemPixmap -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemPixmap - \brief An arbitrary pixmap - - \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will - be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to - fit the rectangle or be drawn aligned to the topLeft position. - - If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown - on the right side of the example image), the pixmap will be flipped in the respective - orientations. -*/ - -/*! - Creates a rectangle item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - topLeft(createPosition(QLatin1String("topLeft"))), - bottomRight(createPosition(QLatin1String("bottomRight"))), - top(createAnchor(QLatin1String("top"), aiTop)), - topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), - right(createAnchor(QLatin1String("right"), aiRight)), - bottom(createAnchor(QLatin1String("bottom"), aiBottom)), - bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), - left(createAnchor(QLatin1String("left"), aiLeft)), - mScaled(false), - mScaledPixmapInvalidated(true), - mAspectRatioMode(Qt::KeepAspectRatio), - mTransformationMode(Qt::SmoothTransformation) -{ - topLeft->setCoords(0, 1); - bottomRight->setCoords(1, 0); - - setPen(Qt::NoPen); - setSelectedPen(QPen(Qt::blue)); -} - -QCPItemPixmap::~QCPItemPixmap() -{ -} - -/*! - Sets the pixmap that will be displayed. -*/ -void QCPItemPixmap::setPixmap(const QPixmap &pixmap) -{ - mPixmap = pixmap; - mScaledPixmapInvalidated = true; - if (mPixmap.isNull()) - qDebug() << Q_FUNC_INFO << "pixmap is null"; -} - -/*! - Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a - bottomRight positions. -*/ -void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode) -{ - mScaled = scaled; - mAspectRatioMode = aspectRatioMode; - mTransformationMode = transformationMode; - mScaledPixmapInvalidated = true; -} - -/*! - Sets the pen that will be used to draw a border around the pixmap. - - \see setSelectedPen, setBrush -*/ -void QCPItemPixmap::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw a border around the pixmap when selected - - \see setPen, setSelected -*/ -void QCPItemPixmap::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/* inherits documentation from base class */ -double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - return rectDistance(getFinalRect(), pos, true); -} - -/* inherits documentation from base class */ -void QCPItemPixmap::draw(QCPPainter *painter) -{ - bool flipHorz = false; - bool flipVert = false; - QRect rect = getFinalRect(&flipHorz, &flipVert); - double clipPad = mainPen().style() == Qt::NoPen ? 0 : mainPen().widthF(); - QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); - if (boundingRect.intersects(clipRect())) - { - updateScaledPixmap(rect, flipHorz, flipVert); - painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); - QPen pen = mainPen(); - if (pen.style() != Qt::NoPen) - { - painter->setPen(pen); - painter->setBrush(Qt::NoBrush); - painter->drawRect(rect); - } - } -} - -/* inherits documentation from base class */ -QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const -{ - bool flipHorz; - bool flipVert; - QRect rect = getFinalRect(&flipHorz, &flipVert); - // we actually want denormal rects (negative width/height) here, so restore - // the flipped state: - if (flipHorz) - rect.adjust(rect.width(), 0, -rect.width(), 0); - if (flipVert) - rect.adjust(0, rect.height(), 0, -rect.height()); - - switch (anchorId) - { - case aiTop: return (rect.topLeft()+rect.topRight())*0.5; - case aiTopRight: return rect.topRight(); - case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; - case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; - case aiBottomLeft: return rect.bottomLeft(); - case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; - } - - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The - parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped - horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a - bottomRight.) - - This function only creates the scaled pixmap when the buffered pixmap has a different size than - the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does - not cause expensive rescaling every time. - - If scaling is disabled, sets mScaledPixmap to a null QPixmap. -*/ -void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) -{ - if (mPixmap.isNull()) - return; - - if (mScaled) - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - double devicePixelRatio = mPixmap.devicePixelRatio(); -#else - double devicePixelRatio = 1.0; -#endif - if (finalRect.isNull()) - finalRect = getFinalRect(&flipHorz, &flipVert); - if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()/devicePixelRatio) - { - mScaledPixmap = mPixmap.scaled(finalRect.size()*devicePixelRatio, mAspectRatioMode, mTransformationMode); - if (flipHorz || flipVert) - mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mScaledPixmap.setDevicePixelRatio(devicePixelRatio); -#endif - } - } else if (!mScaledPixmap.isNull()) - mScaledPixmap = QPixmap(); - mScaledPixmapInvalidated = false; -} - -/*! \internal - - Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions - and scaling settings. - - The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn - flipped horizontally or vertically in the returned rect. (The returned rect itself is always - normalized, i.e. the top left corner of the rect is actually further to the top/left than the - bottom right corner). This is the case when the item position \a topLeft is further to the - bottom/right than \a bottomRight. - - If scaling is disabled, returns a rect with size of the original pixmap and the top left corner - aligned with the item position \a topLeft. The position \a bottomRight is ignored. -*/ -QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const -{ - QRect result; - bool flipHorz = false; - bool flipVert = false; - QPoint p1 = topLeft->pixelPosition().toPoint(); - QPoint p2 = bottomRight->pixelPosition().toPoint(); - if (p1 == p2) - return QRect(p1, QSize(0, 0)); - if (mScaled) - { - QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); - QPoint topLeft = p1; - if (newSize.width() < 0) - { - flipHorz = true; - newSize.rwidth() *= -1; - topLeft.setX(p2.x()); - } - if (newSize.height() < 0) - { - flipVert = true; - newSize.rheight() *= -1; - topLeft.setY(p2.y()); - } - QSize scaledSize = mPixmap.size(); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - scaledSize /= mPixmap.devicePixelRatio(); - scaledSize.scale(newSize*mPixmap.devicePixelRatio(), mAspectRatioMode); -#else - scaledSize.scale(newSize, mAspectRatioMode); -#endif - result = QRect(topLeft, scaledSize); - } else - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - result = QRect(p1, mPixmap.size()/mPixmap.devicePixelRatio()); -#else - result = QRect(p1, mPixmap.size()); -#endif - } - if (flippedHorz) - *flippedHorz = flipHorz; - if (flippedVert) - *flippedVert = flipVert; - return result; -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemPixmap::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-pixmap.cpp' */ - - -/* including file 'src/items/item-tracer.cpp', size 14624 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemTracer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemTracer - \brief Item that sticks to QCPGraph data points - - \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." - - The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt - the coordinate axes of the graph and update its \a position to be on the graph's data. This means - the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a - QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a - position will have no effect because they will be overriden in the next redraw (this is when the - coordinate update happens). - - If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will - stay at the corresponding end of the graph. - - With \ref setInterpolating you may specify whether the tracer may only stay exactly on data - points or whether it interpolates data points linearly, if given a key that lies between two data - points of the graph. - - The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer - have no own visual appearance (set the style to \ref tsNone), and just connect other item - positions to the tracer \a position (used as an anchor) via \ref - QCPItemPosition::setParentAnchor. - - \note The tracer position is only automatically updated upon redraws. So when the data of the - graph changes and immediately afterwards (without a redraw) the position coordinates of the - tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref - updatePosition must be called manually, prior to reading the tracer coordinates. -*/ - -/*! - Creates a tracer item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - position(createPosition(QLatin1String("position"))), - mSize(6), - mStyle(tsCrosshair), - mGraph(0), - mGraphKey(0), - mInterpolating(false), - mType(-1) -{ - position->setCoords(0, 0); - - setBrush(Qt::NoBrush); - setSelectedBrush(Qt::NoBrush); - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue, 2)); -} - -QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush) - : QCPAbstractItem(parentPlot), - position(createPosition(QLatin1String("position"))), - mPen(pen), - mBrush(brush), - mSize(5), - mStyle(tsCircle), - mGraph(0), - mGraphKey(0), - mInterpolating(true), - mType(type), - mTimeStamp(timeStamp) -{ - position->setCoords(0, 0); - setSelectedBrush(Qt::NoBrush); - setSelectedPen(QPen(Qt::blue, 2)); -} - -QCPItemTracer::~QCPItemTracer() -{ -} - -/*! - Sets the pen that will be used to draw the line of the tracer - - \see setSelectedPen, setBrush -*/ -void QCPItemTracer::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line of the tracer when selected - - \see setPen, setSelected -*/ -void QCPItemTracer::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the brush that will be used to draw any fills of the tracer - - \see setSelectedBrush, setPen -*/ -void QCPItemTracer::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the brush that will be used to draw any fills of the tracer, when selected. - - \see setBrush, setSelected -*/ -void QCPItemTracer::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/*! - Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare - does, \ref tsCrosshair does not). -*/ -void QCPItemTracer::setSize(double size) -{ - mSize = size; -} - -/*! - Sets the style/visual appearance of the tracer. - - If you only want to use the tracer \a position as an anchor for other items, set \a style to - \ref tsNone. -*/ -void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) -{ - mStyle = style; -} - -/*! - Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type - QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. - - To free the tracer from any graph, set \a graph to 0. The tracer \a position can then be placed - freely like any other item position. This is the state the tracer will assume when its graph gets - deleted while still attached to it. - - \see setGraphKey -*/ -void QCPItemTracer::setGraph(QCPGraph *graph) -{ - if (graph) - { - if (graph->parentPlot() == mParentPlot) - { - position->setType(QCPItemPosition::ptPlotCoords); - position->setAxes(graph->keyAxis(), graph->valueAxis()); - mGraph = graph; - updatePosition(); - } else - qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; - } else - { - mGraph = 0; - } -} - -/*! - Sets the key of the graph's data point the tracer will be positioned at. This is the only free - coordinate of a tracer when attached to a graph. - - Depending on \ref setInterpolating, the tracer will be either positioned on the data point - closest to \a key, or will stay exactly at \a key and interpolate the value linearly. - - \see setGraph, setInterpolating -*/ -void QCPItemTracer::setGraphKey(double key) -{ - mGraphKey = key; -} - -void QCPItemTracer::setHidePoint(const QMap &hidePoint) -{ - m_hidePoint = hidePoint; -} - -void QCPItemTracer::addHidePoint(const qint64 &time, const QString &tag) -{ - m_hidePoint.insert(time, tag); -} - -/*! - Sets whether the value of the graph's data points shall be interpolated, when positioning the - tracer. - - If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on - the data point of the graph which is closest to the key, but which is not necessarily exactly - there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and - the appropriate value will be interpolated from the graph's data points linearly. - - \see setGraph, setGraphKey -*/ -void QCPItemTracer::setInterpolating(bool enabled) -{ - mInterpolating = enabled; -} - -void QCPItemTracer::setType(const int &type) -{ - mType = type; -} - -void QCPItemTracer::setTimeStamp(const qint64 &timeStamp) -{ - mTimeStamp = timeStamp; -} - -void QCPItemTracer::setInfo(const QStringList infos) -{ - m_infos = infos; -} - -void QCPItemTracer::showTips() -{ - QString tips; - QString strTime = QDateTime::fromMSecsSinceEpoch(position->key()).toString("yyyy-MM-dd hh:mm:ss zzz"); - tips += QString("%1: %2\n\n%3:\n\t").arg(tr("时间")).arg(strTime).arg(tr("事件信息")); - tips += m_infos.join("\t\n\t"); - tips += QString("\n"); - CToolTip::popup(mParentPlot->mapToGlobal(position->pixelPosition().toPoint()), tips, this->parentPlot()); -} - -/* inherits documentation from base class */ -double QCPItemTracer::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QPointF center(position->pixelPosition()); - double w = mSize/2.0; - QRect clip = clipRect(); - switch (mStyle) - { - case tsNone: return -1; - case tsPlus: - { - if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(center+QPointF(-w, 0), center+QPointF(w, 0)), - QCPVector2D(pos).distanceSquaredToLine(center+QPointF(0, -w), center+QPointF(0, w)))); - break; - } - case tsCrosshair: - { - return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(clip.left(), center.y()), QCPVector2D(clip.right(), center.y())), - QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(center.x(), clip.top()), QCPVector2D(center.x(), clip.bottom())))); - } - case tsCircle: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - { - // distance to border: - double centerDist = QCPVector2D(center-pos).length(); - double circleLine = w; - double result = qAbs(centerDist-circleLine); - // filled ellipse, allow click inside to count as hit: - if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) - { - if (centerDist <= circleLine) - result = mParentPlot->selectionTolerance()*0.99; - } - return result; - } - break; - } - case tsSquare: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - { - QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); - bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; - return rectDistance(rect, pos, filledRect); - } - break; - } - } - return -1; -} - -/* inherits documentation from base class */ -void QCPItemTracer::draw(QCPPainter *painter) -{ - updatePosition(); - if (mStyle == tsNone) - return; - - painter->setPen(mainPen()); - painter->setBrush(mainBrush()); - QPointF center(position->pixelPosition()); - double w = mSize/2.0; - QRect clip = clipRect(); - switch (mStyle) - { - case tsNone: return; - case tsPlus: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - { - painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); - painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); - } - break; - } - case tsCrosshair: - { - if (center.y() > clip.top() && center.y() < clip.bottom()) - painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); - if (center.x() > clip.left() && center.x() < clip.right()) - painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); - break; - } - case tsCircle: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - painter->drawEllipse(center, w, w); - break; - } - case tsSquare: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); - break; - } - } -} - -void QCPItemTracer::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - QCPAbstractItem::mousePressEvent(event, details); -} - -void QCPItemTracer::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - QCPAbstractItem::mouseMoveEvent(event, startPos); - - if(QPoint(event->pos() - position->pixelPosition().toPoint()).manhattanLength() > 8) - { - return; - } - emit itemTracerHoverd(mGraph->name(), mTimeStamp, m_hidePoint); -} - -/*! - If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a - position to reside on the graph data, depending on the configured key (\ref setGraphKey). - - It is called automatically on every redraw and normally doesn't need to be called manually. One - exception is when you want to read the tracer coordinates via \a position and are not sure that - the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. - In that situation, call this function before accessing \a position, to make sure you don't get - out-of-date coordinates. - - If there is no graph set on this tracer, this function does nothing. -*/ -void QCPItemTracer::updatePosition() -{ - if (mGraph) - { - if (mParentPlot->hasPlottable(mGraph)) - { - if (mGraph->data()->size() > 1) - { - QCPGraphDataContainer::const_iterator first = mGraph->data()->constBegin(); - QCPGraphDataContainer::const_iterator last = mGraph->data()->constEnd()-1; - if (mGraphKey <= first->key) - position->setCoords(first->key, first->value); - else if (mGraphKey >= last->key) - position->setCoords(last->key, last->value); - else - { - if(QCPGraph::lsStepLeft == mGraph->lineStyle()) - { - QCPGraphDataContainer::const_iterator it = mGraph->data()->findEnd(mGraphKey, false); - if(it != mGraph->data()->constBegin()) - { - --it; - } - if (mInterpolating) - { - position->setCoords(mGraphKey, it->value); - } - else - { - position->setCoords(it->key, it->value); - } - } - else - { - QCPGraphDataContainer::const_iterator it = mGraph->data()->findBegin(mGraphKey); - if (it != mGraph->data()->constEnd()) // mGraphKey is not exactly on last iterator, but somewhere between iterators - { - QCPGraphDataContainer::const_iterator prevIt = it; - ++it; // won't advance to constEnd because we handled that case (mGraphKey >= last->key) before - if (mInterpolating) - { - // interpolate between iterators around mGraphKey: - double slope = 0; - if (!qFuzzyCompare((double)it->key, (double)prevIt->key)) - slope = (it->value-prevIt->value)/(it->key-prevIt->key); - position->setCoords(mGraphKey, (mGraphKey-prevIt->key)*slope+prevIt->value); - } else - { - // find iterator with key closest to mGraphKey: - if (mGraphKey < (prevIt->key+it->key)*0.5) - position->setCoords(prevIt->key, prevIt->value); - else - position->setCoords(it->key, it->value); - } - } else // mGraphKey is exactly on last iterator (should actually be caught when comparing first/last keys, but this is a failsafe for fp uncertainty) - position->setCoords(it->key, it->value); - } - } - } else if (mGraph->data()->size() == 1) - { - QCPGraphDataContainer::const_iterator it = mGraph->data()->constBegin(); - position->setCoords(it->key, it->value); - } else - qDebug() << Q_FUNC_INFO << "graph has no data"; - } else - qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; - } -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemTracer::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} - -/*! \internal - - Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item - is not selected and mSelectedBrush when it is. -*/ -QBrush QCPItemTracer::mainBrush() const -{ - return mSelected ? mSelectedBrush : mBrush; -} -/* end of 'src/items/item-tracer.cpp' */ - - -/* including file 'src/items/item-bracket.cpp', size 10687 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemBracket -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemBracket - \brief A bracket for referencing/highlighting certain parts in the plot. - - \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a left and \a right, which define the span of the bracket. If \a left is - actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the - example image. - - The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket - stretches away from the embraced span, can be controlled with \ref setLength. - - \image html QCPItemBracket-length.png -
Demonstrating the effect of different values for \ref setLength, for styles \ref - bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
- - It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine - or QCPItemCurve) or a text label (QCPItemText), to the bracket. -*/ - -/*! - Creates a bracket item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - left(createPosition(QLatin1String("left"))), - right(createPosition(QLatin1String("right"))), - center(createAnchor(QLatin1String("center"), aiCenter)), - mLength(8), - mStyle(bsCalligraphic) -{ - left->setCoords(0, 0); - right->setCoords(1, 1); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue, 2)); -} - -QCPItemBracket::~QCPItemBracket() -{ -} - -/*! - Sets the pen that will be used to draw the bracket. - - Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the - stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use - \ref setLength, which has a similar effect. - - \see setSelectedPen -*/ -void QCPItemBracket::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the bracket when selected - - \see setPen, setSelected -*/ -void QCPItemBracket::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the \a length in pixels how far the bracket extends in the direction towards the embraced - span of the bracket (i.e. perpendicular to the left-right-direction) - - \image html QCPItemBracket-length.png -
Demonstrating the effect of different values for \ref setLength, for styles \ref - bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
-*/ -void QCPItemBracket::setLength(double length) -{ - mLength = length; -} - -/*! - Sets the style of the bracket, i.e. the shape/visual appearance. - - \see setPen -*/ -void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) -{ - mStyle = style; -} - -/* inherits documentation from base class */ -double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QCPVector2D p(pos); - QCPVector2D leftVec(left->pixelPosition()); - QCPVector2D rightVec(right->pixelPosition()); - if (leftVec.toPoint() == rightVec.toPoint()) - return -1; - - QCPVector2D widthVec = (rightVec-leftVec)*0.5; - QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; - QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; - - switch (mStyle) - { - case QCPItemBracket::bsSquare: - case QCPItemBracket::bsRound: - { - double a = p.distanceSquaredToLine(centerVec-widthVec, centerVec+widthVec); - double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec, centerVec-widthVec); - double c = p.distanceSquaredToLine(centerVec+widthVec+lengthVec, centerVec+widthVec); - return qSqrt(qMin(qMin(a, b), c)); - } - case QCPItemBracket::bsCurly: - case QCPItemBracket::bsCalligraphic: - { - double a = p.distanceSquaredToLine(centerVec-widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); - double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec*0.7, centerVec-widthVec*0.75+lengthVec*0.15); - double c = p.distanceSquaredToLine(centerVec+widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); - double d = p.distanceSquaredToLine(centerVec+widthVec+lengthVec*0.7, centerVec+widthVec*0.75+lengthVec*0.15); - return qSqrt(qMin(qMin(a, b), qMin(c, d))); - } - } - return -1; -} - -/* inherits documentation from base class */ -void QCPItemBracket::draw(QCPPainter *painter) -{ - QCPVector2D leftVec(left->pixelPosition()); - QCPVector2D rightVec(right->pixelPosition()); - if (leftVec.toPoint() == rightVec.toPoint()) - return; - - QCPVector2D widthVec = (rightVec-leftVec)*0.5; - QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; - QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; - - QPolygon boundingPoly; - boundingPoly << leftVec.toPoint() << rightVec.toPoint() - << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); - QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); - if (clip.intersects(boundingPoly.boundingRect())) - { - painter->setPen(mainPen()); - switch (mStyle) - { - case bsSquare: - { - painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); - painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); - painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - break; - } - case bsRound: - { - painter->setBrush(Qt::NoBrush); - QPainterPath path; - path.moveTo((centerVec+widthVec+lengthVec).toPointF()); - path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); - path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - painter->drawPath(path); - break; - } - case bsCurly: - { - painter->setBrush(Qt::NoBrush); - QPainterPath path; - path.moveTo((centerVec+widthVec+lengthVec).toPointF()); - path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+lengthVec).toPointF(), centerVec.toPointF()); - path.cubicTo((centerVec-0.4*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - painter->drawPath(path); - break; - } - case bsCalligraphic: - { - painter->setPen(Qt::NoPen); - painter->setBrush(QBrush(mainPen().color())); - QPainterPath path; - path.moveTo((centerVec+widthVec+lengthVec).toPointF()); - - path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); - path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - - path.cubicTo((centerVec-widthVec-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); - path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); - - painter->drawPath(path); - break; - } - } - } -} - -/* inherits documentation from base class */ -QPointF QCPItemBracket::anchorPixelPosition(int anchorId) const -{ - QCPVector2D leftVec(left->pixelPosition()); - QCPVector2D rightVec(right->pixelPosition()); - if (leftVec.toPoint() == rightVec.toPoint()) - return leftVec.toPointF(); - - QCPVector2D widthVec = (rightVec-leftVec)*0.5; - QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; - QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; - - switch (anchorId) - { - case aiCenter: - return centerVec.toPointF(); - } - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the - item is not selected and mSelectedPen when it is. -*/ -QPen QCPItemBracket::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-bracket.cpp' */ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2017 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 04.09.17 ** +** Version: 2.0.0 ** +****************************************************************************/ + +#include "qcustomplot.h" +#include "../widgets/CToolTip.h" + +/* including file 'src/vector2d.cpp', size 7340 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPVector2D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPVector2D + \brief Represents two doubles as a mathematical 2D vector + + This class acts as a replacement for QVector2D with the advantage of double precision instead of + single, and some convenience methods tailored for the QCustomPlot library. +*/ + +/* start documentation of inline functions */ + +/*! \fn void QCPVector2D::setX(double x) + + Sets the x coordinate of this vector to \a x. + + \see setY +*/ + +/*! \fn void QCPVector2D::setY(double y) + + Sets the y coordinate of this vector to \a y. + + \see setX +*/ + +/*! \fn double QCPVector2D::length() const + + Returns the length of this vector. + + \see lengthSquared +*/ + +/*! \fn double QCPVector2D::lengthSquared() const + + Returns the squared length of this vector. In some situations, e.g. when just trying to find the + shortest vector of a group, this is faster than calculating \ref length, because it avoids + calculation of a square root. + + \see length +*/ + +/*! \fn QPoint QCPVector2D::toPoint() const + + Returns a QPoint which has the x and y coordinates of this vector, truncating any floating point + information. + + \see toPointF +*/ + +/*! \fn QPointF QCPVector2D::toPointF() const + + Returns a QPointF which has the x and y coordinates of this vector. + + \see toPoint +*/ + +/*! \fn bool QCPVector2D::isNull() const + + Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y + coordinates, i.e. if both are binary equal to 0. +*/ + +/*! \fn QCPVector2D QCPVector2D::perpendicular() const + + Returns a vector perpendicular to this vector, with the same length. +*/ + +/*! \fn double QCPVector2D::dot() const + + Returns the dot/scalar product of this vector with the specified vector \a vec. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates to 0. +*/ +QCPVector2D::QCPVector2D() : + mX(0), + mY(0) +{ +} + +/*! + Creates a QCPVector2D object and initializes the \a x and \a y coordinates with the specified + values. +*/ +QCPVector2D::QCPVector2D(double x, double y) : + mX(x), + mY(y) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPoint &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPointF &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Normalizes this vector. After this operation, the length of the vector is equal to 1. + + \see normalized, length, lengthSquared +*/ +void QCPVector2D::normalize() +{ + double len = length(); + mX /= len; + mY /= len; +} + +/*! + Returns a normalized version of this vector. The length of the returned vector is equal to 1. + + \see normalize, length, lengthSquared +*/ +QCPVector2D QCPVector2D::normalized() const +{ + QCPVector2D result(mX, mY); + result.normalize(); + return result; +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a start and \a end. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const +{ + QCPVector2D v(end-start); + double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + double mu = v.dot(*this-start)/vLengthSqr; + if (mu < 0) + return (*this-start).lengthSquared(); + else if (mu > 1) + return (*this-end).lengthSquared(); + else + return ((start + mu*v)-*this).lengthSquared(); + } else + return (*this-start).lengthSquared(); +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a line. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QLineF &line) const +{ + return distanceSquaredToLine(QCPVector2D(line.p1()), QCPVector2D(line.p2())); +} + +/*! + Returns the shortest distance of this vector (interpreted as a point) to the infinite straight + line given by a \a base point and a \a direction vector. + + \see distanceSquaredToLine +*/ +double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const +{ + return qAbs((*this-base).dot(direction.perpendicular()))/direction.length(); +} + +/*! + Scales this vector by the given \a factor, i.e. the x and y components are multiplied by \a + factor. +*/ +QCPVector2D &QCPVector2D::operator*=(double factor) +{ + mX *= factor; + mY *= factor; + return *this; +} + +/*! + Scales this vector by the given \a divisor, i.e. the x and y components are divided by \a + divisor. +*/ +QCPVector2D &QCPVector2D::operator/=(double divisor) +{ + mX /= divisor; + mY /= divisor; + return *this; +} + +/*! + Adds the given \a vector to this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator+=(const QCPVector2D &vector) +{ + mX += vector.mX; + mY += vector.mY; + return *this; +} + +/*! + subtracts the given \a vector from this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator-=(const QCPVector2D &vector) +{ + mX -= vector.mX; + mY -= vector.mY; + return *this; +} +/* end of 'src/vector2d.cpp' */ + + +/* including file 'src/painter.cpp', size 8670 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPainter +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPainter + \brief QPainter subclass used internally + + This QPainter subclass is used to provide some extended functionality e.g. for tweaking position + consistency between antialiased and non-antialiased painting. Further it provides workarounds + for QPainter quirks. + + \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and + restore. So while it is possible to pass a QCPPainter instance to a function that expects a + QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because + it will call the base class implementations of the functions actually hidden by QCPPainter). +*/ + +/*! + Creates a new QCPPainter instance and sets default values +*/ +QCPPainter::QCPPainter() : + QPainter(), + mModes(pmDefault), + mIsAntialiasing(false) +{ + // don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and + // a call to begin() will follow +} + +/*! + Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just + like the analogous QPainter constructor, begins painting on \a device immediately. + + Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. +*/ +QCPPainter::QCPPainter(QPaintDevice *device) : + QPainter(device), + mModes(pmDefault), + mIsAntialiasing(false) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (isActive()) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif +} + +/*! + Sets the pen of the painter and applies certain fixes to it, depending on the mode of this + QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QPen &pen) +{ + QPainter::setPen(pen); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QColor &color) +{ + QPainter::setPen(color); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(Qt::PenStyle penStyle) +{ + QPainter::setPen(penStyle); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when + antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to + integer coordinates and then passes it to the original drawLine. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::drawLine(const QLineF &line) +{ + if (mIsAntialiasing || mModes.testFlag(pmVectorized)) + QPainter::drawLine(line); + else + QPainter::drawLine(line.toLine()); +} + +/*! + Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint + with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between + antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for + AA/Non-AA painting). +*/ +void QCPPainter::setAntialiasing(bool enabled) +{ + setRenderHint(QPainter::Antialiasing, enabled); + if (mIsAntialiasing != enabled) + { + mIsAntialiasing = enabled; + if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs + { + if (mIsAntialiasing) + translate(0.5, 0.5); + else + translate(-0.5, -0.5); + } + } +} + +/*! + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setModes(QCPPainter::PainterModes modes) +{ + mModes = modes; +} + +/*! + Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a + device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, + all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that + behaviour. + + The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets + the render hint as appropriate. + + \note this function hides the non-virtual base class implementation. +*/ +bool QCPPainter::begin(QPaintDevice *device) +{ + bool result = QPainter::begin(device); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (result) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif + return result; +} + +/*! \overload + + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) +{ + if (!enabled && mModes.testFlag(mode)) + mModes &= ~mode; + else if (enabled && !mModes.testFlag(mode)) + mModes |= mode; +} + +/*! + Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see restore +*/ +void QCPPainter::save() +{ + mAntialiasingStack.push(mIsAntialiasing); + QPainter::save(); +} + +/*! + Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see save +*/ +void QCPPainter::restore() +{ + if (!mAntialiasingStack.isEmpty()) + mIsAntialiasing = mAntialiasingStack.pop(); + else + qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; + QPainter::restore(); +} + +/*! + Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen + overrides when the \ref pmNonCosmetic mode is set. +*/ +void QCPPainter::makeNonCosmetic() +{ + if (qFuzzyIsNull(pen().widthF())) + { + QPen p = pen(); + p.setWidth(1); + QPainter::setPen(p); + } +} +/* end of 'src/painter.cpp' */ + + +/* including file 'src/paintbuffer.cpp', size 18502 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPaintBuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPaintBuffer + \brief The abstract base class for paint buffers, which define the rendering backend + + This abstract base class defines the basic interface that a paint buffer needs to provide in + order to be usable by QCustomPlot. + + A paint buffer manages both a surface to draw onto, and the matching paint device. The size of + the surface can be changed via \ref setSize. External classes (\ref QCustomPlot and \ref + QCPLayer) request a painter via \ref startPainting and then perform the draw calls. Once the + painting is complete, \ref donePainting is called, so the paint buffer implementation can do + clean up if necessary. Before rendering a frame, each paint buffer is usually filled with a color + using \ref clear (usually the color is \c Qt::transparent), to remove the contents of the + previous frame. + + The simplest paint buffer implementation is \ref QCPPaintBufferPixmap which allows regular + software rendering via the raster engine. Hardware accelerated rendering via pixel buffers and + frame buffer objects is provided by \ref QCPPaintBufferGlPbuffer and \ref QCPPaintBufferGlFbo. + They are used automatically if \ref QCustomPlot::setOpenGl is enabled. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual QCPPainter *QCPAbstractPaintBuffer::startPainting() = 0 + + Returns a \ref QCPPainter which is ready to draw to this buffer. The ownership and thus the + responsibility to delete the painter after the painting operations are complete is given to the + caller of this method. + + Once you are done using the painter, delete the painter and call \ref donePainting. + + While a painter generated with this method is active, you must not call \ref setSize, \ref + setDevicePixelRatio or \ref clear. + + This method may return 0, if a painter couldn't be activated on the buffer. This usually + indicates a problem with the respective painting backend. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::draw(QCPPainter *painter) const = 0 + + Draws the contents of this buffer with the provided \a painter. This is the method that is used + to finally join all paint buffers and draw them onto the screen. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::clear(const QColor &color) = 0 + + Fills the entire buffer with the provided \a color. To have an empty transparent buffer, use the + named color \c Qt::transparent. + + This method must not be called if there is currently a painter (acquired with \ref startPainting) + active. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::reallocateBuffer() = 0 + + Reallocates the internal buffer with the currently configured size (\ref setSize) and device + pixel ratio, if applicable (\ref setDevicePixelRatio). It is called as soon as any of those + properties are changed on this paint buffer. + + \note Subclasses of \ref QCPAbstractPaintBuffer must call their reimplementation of this method + in their constructor, to perform the first allocation (this can not be done by the base class + because calling pure virtual methods in base class constructors is not possible). +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of inline functions */ + +/*! \fn virtual void QCPAbstractPaintBuffer::donePainting() + + If you have acquired a \ref QCPPainter to paint onto this paint buffer via \ref startPainting, + call this method as soon as you are done with the painting operations and have deleted the + painter. + + paint buffer subclasses may use this method to perform any type of cleanup that is necessary. The + default implementation does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a paint buffer and initializes it with the provided \a size and \a devicePixelRatio. + + Subclasses must call their \ref reallocateBuffer implementation in their respective constructors. +*/ +QCPAbstractPaintBuffer::QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio) : + mSize(size), + mDevicePixelRatio(devicePixelRatio), + mInvalidated(true) +{ +} + +QCPAbstractPaintBuffer::~QCPAbstractPaintBuffer() +{ +} + +/*! + Sets the paint buffer size. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + If \a size is already the current buffer size, this method does nothing. +*/ +void QCPAbstractPaintBuffer::setSize(const QSize &size) +{ + if (mSize != size) + { + mSize = size; + reallocateBuffer(); + } +} + +/*! + Sets the invalidated flag to \a invalidated. + + This mechanism is used internally in conjunction with isolated replotting of \ref QCPLayer + instances (in \ref QCPLayer::lmBuffered mode). If \ref QCPLayer::replot is called on a buffered + layer, i.e. an isolated repaint of only that layer (and its dedicated paint buffer) is requested, + QCustomPlot will decide depending on the invalidated flags of other paint buffers whether it also + replots them, instead of only the layer on which the replot was called. + + The invalidated flag is set to true when \ref QCPLayer association has changed, i.e. if layers + were added or removed from this buffer, or if they were reordered. It is set to false as soon as + all associated \ref QCPLayer instances are drawn onto the buffer. + + Under normal circumstances, it is not necessary to manually call this method. +*/ +void QCPAbstractPaintBuffer::setInvalidated(bool invalidated) +{ + mInvalidated = invalidated; +} + +/*! + Sets the the device pixel ratio to \a ratio. This is useful to render on high-DPI output devices. + The ratio is automatically set to the device pixel ratio used by the parent QCustomPlot instance. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + \note This method is only available for Qt versions 5.4 and higher. +*/ +void QCPAbstractPaintBuffer::setDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mDevicePixelRatio = ratio; + reallocateBuffer(); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; +#endif + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferPixmap + \brief A paint buffer based on QPixmap, using software raster rendering + + This paint buffer is the default and fall-back paint buffer which uses software rendering and + QPixmap as internal buffer. It is used if \ref QCustomPlot::setOpenGl is false. +*/ + +/*! + Creates a pixmap paint buffer instancen with the specified \a size and \a devicePixelRatio, if + applicable. +*/ +QCPPaintBufferPixmap::QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio) : + QCPAbstractPaintBuffer(size, devicePixelRatio) +{ + QCPPaintBufferPixmap::reallocateBuffer(); +} + +QCPPaintBufferPixmap::~QCPPaintBufferPixmap() +{ +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferPixmap::startPainting() +{ + QCPPainter *result = new QCPPainter(&mBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::draw(QCPPainter *painter) const +{ + if (painter && painter->isActive()) + painter->drawPixmap(0, 0, mBuffer); + else + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::clear(const QColor &color) +{ + mBuffer.fill(color); +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::reallocateBuffer() +{ + setInvalidated(); + if (!qFuzzyCompare(1.0, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBuffer = QPixmap(mSize*mDevicePixelRatio); + mBuffer.setDevicePixelRatio(mDevicePixelRatio); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; + mBuffer = QPixmap(mSize); +#endif + } else + { + mBuffer = QPixmap(mSize); + } +} + + +#ifdef QCP_OPENGL_PBUFFER +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlPbuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlPbuffer + \brief A paint buffer based on OpenGL pixel buffers, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL pixel buffers (pbuffer) and is used in Qt versions before 5.0. + (See \ref QCPPaintBufferGlFbo used in newer Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlPbuffer instance with the specified \a size and \a + devicePixelRatio, if applicable. + + The parameter \a multisamples defines how many samples are used per pixel. Higher values thus + result in higher quality antialiasing. If the specified \a multisamples value exceeds the + capability of the graphics hardware, the highest supported multisampling is used. +*/ +QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlPBuffer(0), + mMultisamples(qMax(0, multisamples)) +{ + QCPPaintBufferGlPbuffer::reallocateBuffer(); +} + +QCPPaintBufferGlPbuffer::~QCPPaintBufferGlPbuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlPbuffer::startPainting() +{ + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + QCPPainter *result = new QCPPainter(mGlPBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer isn't valid, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlPBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::clear(const QColor &color) +{ + if (mGlPBuffer->isValid()) + { + mGlPBuffer->makeCurrent(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlPBuffer->doneCurrent(); + } else + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer invalid or context not current"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::reallocateBuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; + + QGLFormat format; + format.setAlpha(true); + format.setSamples(mMultisamples); + mGlPBuffer = new QGLPixelBuffer(mSize, format); +} +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlFbo +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlFbo + \brief A paint buffer based on OpenGL frame buffers objects, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL frame buffer objects (fbo) and is used in Qt versions 5.0 and + higher. (See \ref QCPPaintBufferGlPbuffer used in older Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlFbo instance with the specified \a size and \a devicePixelRatio, + if applicable. + + All frame buffer objects shall share one OpenGL context and paint device, which need to be set up + externally and passed via \a glContext and \a glPaintDevice. The set-up is done in \ref + QCustomPlot::setupOpenGl and the context and paint device are managed by the parent QCustomPlot + instance. +*/ +QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlContext(glContext), + mGlPaintDevice(glPaintDevice), + mGlFrameBuffer(0) +{ + QCPPaintBufferGlFbo::reallocateBuffer(); +} + +QCPPaintBufferGlFbo::~QCPPaintBufferGlFbo() +{ + if (mGlFrameBuffer) + delete mGlFrameBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlFbo::startPainting() +{ + if (mGlPaintDevice.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return 0; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + if (QOpenGLContext::currentContext() != mGlContext.data()) + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + mGlFrameBuffer->bind(); + QCPPainter *result = new QCPPainter(mGlPaintDevice.data()); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::donePainting() +{ + if (mGlFrameBuffer && mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + else + qDebug() << Q_FUNC_INFO << "Either OpenGL frame buffer not valid or was not bound"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlFrameBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::clear(const QColor &color) +{ + if (mGlContext.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + + if (QOpenGLContext::currentContext() != mGlContext.data()) + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + mGlFrameBuffer->bind(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlFrameBuffer->release(); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::reallocateBuffer() +{ + // release and delete possibly existing framebuffer: + if (mGlFrameBuffer) + { + if (mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + delete mGlFrameBuffer; + mGlFrameBuffer = 0; + } + + if (mGlContext.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (mGlPaintDevice.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return; + } + + // create new fbo with appropriate size: + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + QOpenGLFramebufferObjectFormat frameBufferFormat; + frameBufferFormat.setSamples(mGlContext.data()->format().samples()); + frameBufferFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + mGlFrameBuffer = new QOpenGLFramebufferObject(mSize*mDevicePixelRatio, frameBufferFormat); + if (mGlPaintDevice.data()->size() != mSize*mDevicePixelRatio) + mGlPaintDevice.data()->setSize(mSize*mDevicePixelRatio); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mGlPaintDevice.data()->setDevicePixelRatio(mDevicePixelRatio); +#endif +} +#endif // QCP_OPENGL_FBO +/* end of 'src/paintbuffer.cpp' */ + + +/* including file 'src/layer.cpp', size 37064 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayer + \brief A layer that may contain objects, to control the rendering order + + The Layering system of QCustomPlot is the mechanism to control the rendering order of the + elements inside the plot. + + It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of + one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, + QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers + bottom to top and successively draws the layerables of the layers into the paint buffer(s). + + A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base + class from which almost all visible objects derive, like axes, grids, graphs, items, etc. + + \section qcplayer-defaultlayers Default layers + + Initially, QCustomPlot has six layers: "background", "grid", "main", "axes", "legend" and + "overlay" (in that order). On top is the "overlay" layer, which only contains the QCustomPlot's + selection rect (\ref QCustomPlot::selectionRect). The next two layers "axes" and "legend" contain + the default axes and legend, so they will be drawn above plottables. In the middle, there is the + "main" layer. It is initially empty and set as the current layer (see + QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. are created on this + layer by default. Then comes the "grid" layer which contains the QCPGrid instances (which belong + tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background shall be drawn behind + everything else, thus the default QCPAxisRect instance is placed on the "background" layer. Of + course, the layer affiliation of the individual objects can be changed as required (\ref + QCPLayerable::setLayer). + + \section qcplayer-ordering Controlling the rendering order via layers + + Controlling the ordering of layerables in the plot is easy: Create a new layer in the position + you want the layerable to be in, e.g. above "main", with \ref QCustomPlot::addLayer. Then set the + current layer with \ref QCustomPlot::setCurrentLayer to that new layer and finally create the + objects normally. They will be placed on the new layer automatically, due to the current layer + setting. Alternatively you could have also ignored the current layer setting and just moved the + objects with \ref QCPLayerable::setLayer to the desired layer after creating them. + + It is also possible to move whole layers. For example, If you want the grid to be shown in front + of all plottables/items on the "main" layer, just move it above "main" with + QCustomPlot::moveLayer. + + The rendering order within one layer is simply by order of creation or insertion. The item + created last (or added last to the layer), is drawn on top of all other objects on that layer. + + When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below + the deleted layer, see QCustomPlot::removeLayer. + + \section qcplayer-buffering Replotting only a specific layer + + If the layer mode (\ref setMode) is set to \ref lmBuffered, you can replot only this specific + layer by calling \ref replot. In certain situations this can provide better replot performance, + compared with a full replot of all layers. Upon creation of a new layer, the layer mode is + initialized to \ref lmLogical. The only layer that is set to \ref lmBuffered in a new \ref + QCustomPlot instance is the "overlay" layer, containing the selection rect. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPLayer::children() const + + Returns a list of all layerables on this layer. The order corresponds to the rendering order: + layerables with higher indices are drawn above layerables with lower indices. +*/ + +/*! \fn int QCPLayer::index() const + + Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be + accessed via \ref QCustomPlot::layer. + + Layers with higher indices will be drawn above layers with lower indices. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPLayer instance. + + Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. + + \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. + This check is only performed by \ref QCustomPlot::addLayer. +*/ +QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : + QObject(parentPlot), + mParentPlot(parentPlot), + mName(layerName), + mIndex(-1), // will be set to a proper value by the QCustomPlot layer creation function + mVisible(true), + mMode(lmLogical) +{ + // Note: no need to make sure layerName is unique, because layer + // management is done with QCustomPlot functions. +} + +QCPLayer::~QCPLayer() +{ + // If child layerables are still on this layer, detach them, so they don't try to reach back to this + // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted + // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to + // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) + + while (!mChildren.isEmpty()) + mChildren.last()->setLayer(0); // removes itself from mChildren via removeChild() + + if (mParentPlot->currentLayer() == this) + qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand."; +} + +/*! + Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this + layer will be invisible. + + This function doesn't change the visibility property of the layerables (\ref + QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the + visibility of the parent layer into account. +*/ +void QCPLayer::setVisible(bool visible) +{ + mVisible = visible; +} + +/*! + Sets the rendering mode of this layer. + + If \a mode is set to \ref lmBuffered for a layer, it will be given a dedicated paint buffer by + the parent QCustomPlot instance. This means it may be replotted individually by calling \ref + QCPLayer::replot, without needing to replot all other layers. + + Layers which are set to \ref lmLogical (the default) are used only to define the rendering order + and can't be replotted individually. + + Note that each layer which is set to \ref lmBuffered requires additional paint buffers for the + layers below, above and for the layer itself. This increases the memory consumption and + (slightly) decreases the repainting speed because multiple paint buffers need to be joined. So + you should carefully choose which layers benefit from having their own paint buffer. A typical + example would be a layer which contains certain layerables (e.g. items) that need to be changed + and thus replotted regularly, while all other layerables on other layers stay static. By default, + only the topmost layer called "overlay" is in mode \ref lmBuffered, and contains the selection + rect. + + \see replot +*/ +void QCPLayer::setMode(QCPLayer::LayerMode mode) +{ + if (mMode != mode) + { + mMode = mode; + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } +} + +/*! \internal + + Draws the contents of this layer with the provided \a painter. + + \see replot, drawToPaintBuffer +*/ +void QCPLayer::draw(QCPPainter *painter) +{ + foreach (QCPLayerable *child, mChildren) + { + if (child->realVisibility()) + { + painter->save(); + painter->setClipRect(child->clipRect().translated(0, -1)); + child->applyDefaultAntialiasingHint(painter); + child->draw(painter); + painter->restore(); + } + } +} + +/*! \internal + + Draws the contents of this layer into the paint buffer which is associated with this layer. The + association is established by the parent QCustomPlot, which manages all paint buffers (see \ref + QCustomPlot::setupPaintBuffers). + + \see draw +*/ +void QCPLayer::drawToPaintBuffer() +{ + if (!mPaintBuffer.isNull()) + { + if (QCPPainter *painter = mPaintBuffer.data()->startPainting()) + { + if (painter->isActive()) + draw(painter); + else + qDebug() << Q_FUNC_INFO << "paint buffer returned inactive painter"; + delete painter; + mPaintBuffer.data()->donePainting(); + } else + qDebug() << Q_FUNC_INFO << "paint buffer returned zero painter"; + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; +} + +/*! + If the layer mode (\ref setMode) is set to \ref lmBuffered, this method allows replotting only + the layerables on this specific layer, without the need to replot all other layers (as a call to + \ref QCustomPlot::replot would do). + + If the layer mode is \ref lmLogical however, this method simply calls \ref QCustomPlot::replot on + the parent QCustomPlot instance. + + QCustomPlot also makes sure to replot all layers instead of only this one, if the layer ordering + has changed since the last full replot and the other paint buffers were thus invalidated. + + \see draw +*/ +void QCPLayer::replot() +{ + if (mMode == lmBuffered && !mParentPlot->hasInvalidatedPaintBuffers()) + { + if (!mPaintBuffer.isNull()) + { + mPaintBuffer.data()->clear(Qt::transparent); + drawToPaintBuffer(); + mPaintBuffer.data()->setInvalidated(false); + mParentPlot->update(); + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; + } else if (mMode == lmLogical) + mParentPlot->replot(); +} + +/*! \internal + + Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will + be prepended to the list, i.e. be drawn beneath the other layerables already in the list. + + This function does not change the \a mLayer member of \a layerable to this layer. (Use + QCPLayerable::setLayer to change the layer of an object, not this function.) + + \see removeChild +*/ +void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) +{ + if (!mChildren.contains(layerable)) + { + if (prepend) + mChildren.prepend(layerable); + else + mChildren.append(layerable); + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); +} + +/*! \internal + + Removes the \a layerable from the list of this layer. + + This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer + to change the layer of an object, not this function.) + + \see addChild +*/ +void QCPLayer::removeChild(QCPLayerable *layerable) +{ + if (mChildren.removeOne(layerable)) + { + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayerable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayerable + \brief Base class for all drawable objects + + This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid + etc. + + Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking + the layers accordingly. + + For details about the layering mechanism, see the QCPLayer documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayerable *QCPLayerable::parentLayerable() const + + Returns the parent layerable of this layerable. The parent layerable is used to provide + visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables + only get drawn if their parent layerables are visible, too. + + Note that a parent layerable is not necessarily also the QObject parent for memory management. + Further, a layerable doesn't always have a parent layerable, so this function may return 0. + + A parent layerable is set implicitly when placed inside layout elements and doesn't need to be + set manually by the user. +*/ + +/* end documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 + \internal + + This function applies the default antialiasing setting to the specified \a painter, using the + function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when + \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing + setting may be specified individually, this function should set the antialiasing state of the + most prominent entity. In this case however, the \ref draw function usually calls the specialized + versions of this function before drawing each entity, effectively overriding the setting of the + default antialiasing hint. + + First example: QCPGraph has multiple entities that have an antialiasing setting: The graph + line, fills and scatters. Those can be configured via QCPGraph::setAntialiased, + QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only + the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's + antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and + QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw + calls the respective specialized applyAntialiasingHint function. + + Second example: QCPItemLine consists only of a line so there is only one antialiasing + setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by + all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the + respective layerable subclass.) Consequently it only has the normal + QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to + care about setting any antialiasing states, because the default antialiasing hint is already set + on the painter when the \ref draw function is called, and that's the state it wants to draw the + line with. +*/ + +/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 + \internal + + This function draws the layerable with the specified \a painter. It is only called by + QCustomPlot, if the layerable is visible (\ref setVisible). + + Before this function is called, the painter's antialiasing state is set via \ref + applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was + set to \ref clipRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); + + This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to + a different layer. + + \see setLayer +*/ + +/* end documentation of signals */ + +/*! + Creates a new QCPLayerable instance. + + Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the + derived classes. + + If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a + targetLayer is an empty string, it places itself on the current layer of the plot (see \ref + QCustomPlot::setCurrentLayer). + + It is possible to provide 0 as \a plot. In that case, you should assign a parent plot at a later + time with \ref initializeParentPlot. + + The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable + parents are mainly used to control visibility in a hierarchy of layerables. This means a + layerable is only drawn, if all its ancestor layerables are also visible. Note that \a + parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a + plot does. It is not uncommon to set the QObject-parent to something else in the constructors of + QCPLayerable subclasses, to guarantee a working destruction hierarchy. +*/ +QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) : + QObject(plot), + mVisible(true), + mParentPlot(plot), + mParentLayerable(parentLayerable), + mLayer(0), + mAntialiased(true) +{ + if (mParentPlot) + { + if (targetLayer.isEmpty()) + setLayer(mParentPlot->currentLayer()); + else if (!setLayer(targetLayer)) + qDebug() << Q_FUNC_INFO << "setting QCPlayerable initial layer to" << targetLayer << "failed."; + } +} + +QCPLayerable::~QCPLayerable() +{ + if (mLayer) + { + mLayer->removeChild(this); + mLayer = 0; + } +} + +/*! + Sets the visibility of this layerable object. If an object is not visible, it will not be drawn + on the QCustomPlot surface, and user interaction with it (e.g. click and selection) is not + possible. +*/ +void QCPLayerable::setVisible(bool on) +{ + mVisible = on; +} + +/*! + Sets the \a layer of this layerable object. The object will be placed on top of the other objects + already on \a layer. + + If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or + interact/receive events). + + Returns true if the layer of this layerable was successfully changed to \a layer. +*/ +bool QCPLayerable::setLayer(QCPLayer *layer) +{ + return moveToLayer(layer, false); +} + +/*! \overload + Sets the layer of this layerable object by name + + Returns true on success, i.e. if \a layerName is a valid layer name. +*/ +bool QCPLayerable::setLayer(const QString &layerName) +{ + if (!mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (QCPLayer *layer = mParentPlot->layer(layerName)) + { + return setLayer(layer); + } else + { + qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; + return false; + } +} + +/*! + Sets whether this object will be drawn antialiased or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPLayerable::setAntialiased(bool enabled) +{ + mAntialiased = enabled; +} + +/*! + Returns whether this layerable is visible, taking the visibility of the layerable parent and the + visibility of this layerable's layer into account. This is the method that is consulted to decide + whether a layerable shall be drawn or not. + + If this layerable has a direct layerable parent (usually set via hierarchies implemented in + subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this + layerable has its visibility set to true and the parent layerable's \ref realVisibility returns + true. +*/ +bool QCPLayerable::realVisibility() const +{ + return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility()); +} + +/*! + This function is used to decide whether a click hits a layerable object or not. + + \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the + shortest pixel distance of this point to the object. If the object is either invisible or the + distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the + object is not selectable, -1.0 is returned, too. + + If the object is represented not by single lines but by an area like a \ref QCPItemText or the + bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In + these cases this function thus returns a constant value greater zero but still below the parent + plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). + + Providing a constant value for area objects allows selecting line objects even when they are + obscured by such area objects, by clicking close to the lines (i.e. closer than + 0.99*selectionTolerance). + + The actual setting of the selection state is not done by this function. This is handled by the + parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified + via the \ref selectEvent/\ref deselectEvent methods. + + \a details is an optional output parameter. Every layerable subclass may place any information + in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot + decides on the basis of this selectTest call, that the object was successfully selected. The + subsequent call to \ref selectEvent will carry the \a details. This is useful for multi-part + objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked + is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be + placed in \a details. So in the subsequent \ref selectEvent, the decision which part was + selected doesn't have to be done a second time for a single selection operation. + + You may pass 0 as \a details to indicate that you are not interested in those selection details. + + \see selectEvent, deselectEvent, mousePressEvent, wheelEvent, QCustomPlot::setInteractions +*/ +double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(pos) + Q_UNUSED(onlySelectable) + Q_UNUSED(details) + return -1.0; +} + +/*! \internal + + Sets the parent plot of this layerable. Use this function once to set the parent plot if you have + passed 0 in the constructor. It can not be used to move a layerable from one QCustomPlot to + another one. + + Note that, unlike when passing a non-null parent plot in the constructor, this function does not + make \a parentPlot the QObject-parent of this layerable. If you want this, call + QObject::setParent(\a parentPlot) in addition to this function. + + Further, you will probably want to set a layer (\ref setLayer) after calling this function, to + make the layerable appear on the QCustomPlot. + + The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized + so they can react accordingly (e.g. also initialize the parent plot of child layerables, like + QCPLayout does). +*/ +void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) +{ + if (mParentPlot) + { + qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; + return; + } + + if (!parentPlot) + qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; + + mParentPlot = parentPlot; + parentPlotInitialized(mParentPlot); +} + +/*! \internal + + Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not + become the QObject-parent (for memory management) of this layerable. + + The parent layerable has influence on the return value of the \ref realVisibility method. Only + layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be + drawn. + + \see realVisibility +*/ +void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) +{ + mParentLayerable = parentLayerable; +} + +/*! \internal + + Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to + the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is + false, the object will be appended. + + Returns true on success, i.e. if \a layer is a valid layer. +*/ +bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) +{ + if (layer && !mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (layer && layer->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; + return false; + } + + QCPLayer *oldLayer = mLayer; + if (mLayer) + mLayer->removeChild(this); + mLayer = layer; + if (mLayer) + mLayer->addChild(this, prepend); + if (mLayer != oldLayer) + emit layerChanged(mLayer); + return true; +} + +/*! \internal + + Sets the QCPainter::setAntialiasing state on the provided \a painter, depending on the \a + localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is + controlled via \a overrideElement. +*/ +void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const +{ + if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(false); + else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(true); + else + painter->setAntialiasing(localAntialiased); +} + +/*! \internal + + This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting + of a parent plot. This is the case when 0 was passed as parent plot in the constructor, and the + parent plot is set at a later time. + + For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any + QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level + element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To + propagate the parent plot to all the children of the hierarchy, the top level element then uses + this function to pass the parent plot on to its child elements. + + The default implementation does nothing. + + \see initializeParentPlot +*/ +void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) +{ + Q_UNUSED(parentPlot) +} + +/*! \internal + + Returns the selection category this layerable shall belong to. The selection category is used in + conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and + which aren't. + + Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref + QCP::iSelectOther. This is what the default implementation returns. + + \see QCustomPlot::setInteractions +*/ +QCP::Interaction QCPLayerable::selectionCategory() const +{ + return QCP::iSelectOther; +} + +/*! \internal + + Returns the clipping rectangle of this layerable object. By default, this is the viewport of the + parent QCustomPlot. Specific subclasses may reimplement this function to provide different + clipping rects. + + The returned clipping rect is set on the painter before the draw function of the respective + object is called. +*/ +QRect QCPLayerable::clipRect() const +{ + if (mParentPlot) + return mParentPlot->viewport(); + else + return QRect(); +} + +/*! \internal + + This event is called when the layerable shall be selected, as a consequence of a click by the + user. Subclasses should react to it by setting their selection state appropriately. The default + implementation does nothing. + + \a event is the mouse event that caused the selection. \a additive indicates, whether the user + was holding the multi-select-modifier while performing the selection (see \ref + QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled + (i.e. become selected when unselected and unselected when selected). + + Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. + returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). + The \a details data you output from \ref selectTest is fed back via \a details here. You may + use it to transport any kind of information from the selectTest to the possibly subsequent + selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable + that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need + to do the calculation again to find out which part was actually clicked. + + \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must + set the value either to true or false, depending on whether the selection state of this layerable + was actually changed. For layerables that only are selectable as a whole and not in parts, this + is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the + selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the + layerable was previously unselected and now is switched to the selected state. + + \see selectTest, deselectEvent +*/ +void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(additive) + Q_UNUSED(details) + Q_UNUSED(selectionStateChanged) +} + +/*! \internal + + This event is called when the layerable shall be deselected, either as consequence of a user + interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by + unsetting their selection appropriately. + + just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must + return true or false when the selection state of this layerable has changed or not changed, + respectively. + + \see selectTest, selectEvent +*/ +void QCPLayerable::deselectEvent(bool *selectionStateChanged) +{ + Q_UNUSED(selectionStateChanged) +} + +/*! + This event gets called when the user presses a mouse button while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + QCustomPlot uses an event propagation system that works the same as Qt's system. If your + layerable doesn't reimplement the \ref mousePressEvent or explicitly calls \c event->ignore() in + its reimplementation, the event will be propagated to the next layerable in the stacking order. + + Once a layerable has accepted the \ref mousePressEvent, it is considered the mouse grabber and + will receive all following calls to \ref mouseMoveEvent or \ref mouseReleaseEvent for this mouse + interaction (a "mouse interaction" in this context ends with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user moves the mouse while holding a mouse button, after this + layerable has become the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occured, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user releases the mouse button, after this layerable has become + the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occured, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user presses the mouse button a second time in a double-click, + while the cursor is over the layerable. Whether a cursor is over the layerable is decided by a + preceding call to \ref selectTest. + + The \ref mouseDoubleClickEvent is called instead of the second \ref mousePressEvent. So in the + case of a double-click, the event succession is + pressEvent – releaseEvent – doubleClickEvent – releaseEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + Similarly to \ref mousePressEvent, once a layerable has accepted the \ref mouseDoubleClickEvent, + it is considered the mouse grabber and will receive all following calls to \ref mouseMoveEvent + and \ref mouseReleaseEvent for this mouse interaction (a "mouse interaction" in this context ends + with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, wheelEvent +*/ +void QCPLayerable::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user turns the mouse scroll wheel while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). + + The \c event->delta() indicates how far the mouse wheel was turned, which is usually +/- 120 for + single rotation steps. However, if the mouse wheel is turned rapidly, multiple steps may + accumulate to one event, making \c event->delta() larger. On the other hand, if the wheel has + very smooth steps or none at all, the delta may be smaller. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent +*/ +void QCPLayerable::wheelEvent(QWheelEvent *event) +{ + event->ignore(); +} +/* end of 'src/layer.cpp' */ + + +/* including file 'src/axis/range.cpp', size 12221 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPRange +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPRange + \brief Represents the range an axis is encompassing. + + contains a \a lower and \a upper double value and provides convenience input, output and + modification functions. + + \see QCPAxis::setRange +*/ + +/* start of documentation of inline functions */ + +/*! \fn double QCPRange::size() const + + Returns the size of the range, i.e. \a upper-\a lower +*/ + +/*! \fn double QCPRange::center() const + + Returns the center of the range, i.e. (\a upper+\a lower)*0.5 +*/ + +/*! \fn void QCPRange::normalize() + + Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values are + swapped. +*/ + +/*! \fn bool QCPRange::contains(double value) const + + Returns true when \a value lies within or exactly on the borders of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator+=(const double& value) + + Adds \a value to both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator-=(const double& value) + + Subtracts \a value from both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator*=(const double& value) + + Multiplies both boundaries of the range by \a value. +*/ + +/*! \fn QCPRange &QCPRange::operator/=(const double& value) + + Divides both boundaries of the range by \a value. +*/ + +/* end of documentation of inline functions */ + +/*! + Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller + intervals would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a minimum magnitude of roughly 1e-308. + + \warning Do not use this constant to indicate "arbitrarily small" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining underflowing ranges. + + \see validRange, maxRange +*/ +//const double QCPRange::minRange = 1e-280; +const double QCPRange::minRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(1970, 0, 0)); + +/*! + Maximum values (negative and positive) the range will accept in range-changing functions. + Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a maximum magnitude of roughly 1e308. + + \warning Do not use this constant to indicate "arbitrarily large" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining overflowing ranges. + + \see validRange, minRange +*/ +//const double QCPRange::maxRange = 1e250; +const double QCPRange::maxRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 12, 31)); + +/*! + Constructs a range with \a lower and \a upper set to zero. +*/ +QCPRange::QCPRange() : + lower(0), + upper(0) +{ +} + +/*! \overload + + Constructs a range with the specified \a lower and \a upper values. + + The resulting range will be normalized (see \ref normalize), so if \a lower is not numerically + smaller than \a upper, they will be swapped. +*/ +QCPRange::QCPRange(double lower, double upper) : + lower(lower), + upper(upper) +{ + normalize(); +} + +/*! \overload + + Expands this range such that \a otherRange is contained in the new range. It is assumed that both + this range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, it will be replaced by the respective bound + of \a otherRange. + + If \a otherRange is already inside the current range, this function does nothing. + + \see expanded +*/ +void QCPRange::expand(const QCPRange &otherRange) +{ + if (lower > otherRange.lower || qIsNaN(lower)) + lower = otherRange.lower; + if (upper < otherRange.upper || qIsNaN(upper)) + upper = otherRange.upper; +} + +/*! \overload + + Expands this range such that \a includeCoord is contained in the new range. It is assumed that + this range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the respective bound will be set to \a + includeCoord. + + If \a includeCoord is already inside the current range, this function does nothing. + + \see expand +*/ +void QCPRange::expand(double includeCoord) +{ + if (lower > includeCoord || qIsNaN(lower)) + lower = includeCoord; + if (upper < includeCoord || qIsNaN(upper)) + upper = includeCoord; +} + + +/*! \overload + + Returns an expanded range that contains this and \a otherRange. It is assumed that both this + range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be taken from + \a otherRange. + + \see expand +*/ +QCPRange QCPRange::expanded(const QCPRange &otherRange) const +{ + QCPRange result = *this; + result.expand(otherRange); + return result; +} + +/*! \overload + + Returns an expanded range that includes the specified \a includeCoord. It is assumed that this + range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be set to \a + includeCoord. + + \see expand +*/ +QCPRange QCPRange::expanded(double includeCoord) const +{ + QCPRange result = *this; + result.expand(includeCoord); + return result; +} + +/*! + Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a + upperBound. If possible, the size of the current range is preserved in the process. + + If the range shall only be bounded at the lower side, you can set \a upperBound to \ref + QCPRange::maxRange. If it shall only be bounded at the upper side, set \a lowerBound to -\ref + QCPRange::maxRange. +*/ +QCPRange QCPRange::bounded(double lowerBound, double upperBound) const +{ + if (lowerBound > upperBound) + qSwap(lowerBound, upperBound); + + QCPRange result(lower, upper); + if (result.lower < lowerBound) + { + result.lower = lowerBound; + result.upper = lowerBound + size(); + if (result.upper > upperBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.upper = upperBound; + } else if (result.upper > upperBound) + { + result.upper = upperBound; + result.lower = upperBound - size(); + if (result.lower < lowerBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.lower = lowerBound; + } + + return result; +} + +/*! + Returns a sanitized version of the range. Sanitized means for logarithmic scales, that + the range won't span the positive and negative sign domain, i.e. contain zero. Further + \a lower will always be numerically smaller (or equal) to \a upper. + + If the original range does span positive and negative sign domains or contains zero, + the returned range will try to approximate the original range as good as possible. + If the positive interval of the original range is wider than the negative interval, the + returned range will only contain the positive interval, with lower bound set to \a rangeFac or + \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval + is wider than the positive interval, this time by changing the \a upper bound. +*/ +QCPRange QCPRange::sanitizedForLogScale() const +{ + double rangeFac = 1e-3; + QCPRange sanitizedRange(lower, upper); + sanitizedRange.normalize(); + // can't have range spanning negative and positive values in log plot, so change range to fix it + //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) + if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) + { + // case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) + else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) + { + // case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) + { + // find out whether negative or positive interval is wider to decide which sign domain will be chosen + if (-sanitizedRange.lower > sanitizedRange.upper) + { + // negative is wider, do same as in case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else + { + // positive is wider, do same as in case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } + } + // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper minRange && + upper < maxRange && + qAbs(lower-upper) > 1 && + qAbs(lower-upper) < maxRange - minRange); + +// return (lower > -maxRange && +// upper < maxRange && +// qAbs(lower-upper) > minRange && +// qAbs(lower-upper) < maxRange && +// !(lower > 0 && qIsInf(upper/lower)) && +// !(upper < 0 && qIsInf(lower/upper))); +} + +/*! + \overload + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(const QCPRange &range) +{ + return validRange(range.lower, range.upper); +// return (range.lower > -maxRange && +// range.upper < maxRange && +// qAbs(range.lower-range.upper) > minRange && +// qAbs(range.lower-range.upper) < maxRange && +// !(range.lower > 0 && qIsInf(range.upper/range.lower)) && +// !(range.upper < 0 && qIsInf(range.lower/range.upper))); +} +/* end of 'src/axis/range.cpp' */ + + +/* including file 'src/selection.cpp', size 21906 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataRange +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataRange + \brief Describes a data range given by begin and end index + + QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index + of a contiguous set of data points. The end index points to the data point above the last data point that's part of + the data range, similarly to the nomenclature used in standard iterators. + + Data Ranges are not bound to a certain plottable, thus they can be freely exchanged, created and + modified. If a non-contiguous data set shall be described, the class \ref QCPDataSelection is + used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref + QCPDataSelection is thus used. + + Both \ref QCPDataRange and \ref QCPDataSelection offer convenience methods to work with them, + e.g. \ref bounded, \ref expanded, \ref intersects, \ref intersection, \ref adjusted, \ref + contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be + used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding + \ref QCPDataSelection. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and + QCPDataRange. + + \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval + in floating point plot coordinates, e.g. the current axis range. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataRange::size() const + + Returns the number of data points described by this data range. This is equal to the end index + minus the begin index. + + \see length +*/ + +/*! \fn int QCPDataRange::length() const + + Returns the number of data points described by this data range. Equivalent to \ref size. +*/ + +/*! \fn void QCPDataRange::setBegin(int begin) + + Sets the begin of this data range. The \a begin index points to the first data point that is part + of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setEnd +*/ + +/*! \fn void QCPDataRange::setEnd(int end) + + Sets the end of this data range. The \a end index points to the data point just above the last + data point that is part of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setBegin +*/ + +/*! \fn bool QCPDataRange::isValid() const + + Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and + an end index greater or equal to the begin index. + + \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods + (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's + methods. The invalid range is not inherently prevented in QCPDataRange, to allow temporary + invalid begin/end values while manipulating the range. An invalid range is not necessarily empty + (\ref isEmpty), since its \ref length can be negative and thus non-zero. +*/ + +/*! \fn bool QCPDataRange::isEmpty() const + + Returns whether this range is empty, i.e. whether its begin index equals its end index. + + \see size, length +*/ + +/*! \fn QCPDataRange QCPDataRange::adjusted(int changeBegin, int changeEnd) const + + Returns a data range where \a changeBegin and \a changeEnd were added to the begin and end + indices, respectively. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataRange, with begin and end set to 0. +*/ +QCPDataRange::QCPDataRange() : + mBegin(0), + mEnd(0) +{ +} + +/*! + Creates a QCPDataRange, initialized with the specified \a begin and \a end. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). +*/ +QCPDataRange::QCPDataRange(int begin, int end) : + mBegin(begin), + mEnd(end) +{ +} + +/*! + Returns a data range that matches this data range, except that parts exceeding \a other are + excluded. + + This method is very similar to \ref intersection, with one distinction: If this range and the \a + other range share no intersection, the returned data range will be empty with begin and end set + to the respective boundary side of \a other, at which this range is residing. (\ref intersection + would just return a range with begin and end set to 0.) +*/ +QCPDataRange QCPDataRange::bounded(const QCPDataRange &other) const +{ + QCPDataRange result(intersection(other)); + if (result.isEmpty()) // no intersection, preserve respective bounding side of otherRange as both begin and end of return value + { + if (mEnd <= other.mBegin) + result = QCPDataRange(other.mBegin, other.mBegin); + else + result = QCPDataRange(other.mEnd, other.mEnd); + } + return result; +} + +/*! + Returns a data range that contains both this data range as well as \a other. +*/ +QCPDataRange QCPDataRange::expanded(const QCPDataRange &other) const +{ + return QCPDataRange(qMin(mBegin, other.mBegin), qMax(mEnd, other.mEnd)); +} + +/*! + Returns the data range which is contained in both this data range and \a other. + + This method is very similar to \ref bounded, with one distinction: If this range and the \a other + range share no intersection, the returned data range will be empty with begin and end set to 0. + (\ref bounded would return a range with begin and end set to one of the boundaries of \a other, + depending on which side this range is on.) + + \see QCPDataSelection::intersection +*/ +QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const +{ + QCPDataRange result(qMax(mBegin, other.mBegin), qMin(mEnd, other.mEnd)); + if (result.isValid()) + return result; + else + return QCPDataRange(); +} + +/*! + Returns whether this data range and \a other share common data points. + + \see intersection, contains +*/ +bool QCPDataRange::intersects(const QCPDataRange &other) const +{ + return !( (mBegin > other.mBegin && mBegin >= other.mEnd) || + (mEnd <= other.mBegin && mEnd < other.mEnd) ); +} + +/*! + Returns whether all data points described by this data range are also in \a other. + + \see intersects +*/ +bool QCPDataRange::contains(const QCPDataRange &other) const +{ + return mBegin <= other.mBegin && mEnd >= other.mEnd; +} + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataSelection +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataSelection + \brief Describes a data set by holding multiple QCPDataRange instances + + QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly + disjoint) set of data selection. + + The data selection can be modified with addition and subtraction operators which take + QCPDataSelection and QCPDataRange instances, as well as methods such as \ref addDataRange and + \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc. + + The method \ref simplify is used to join directly adjacent or even overlapping QCPDataRange + instances. QCPDataSelection automatically simplifies when using the addition/subtraction + operators. The only case when \ref simplify is left to the user, is when calling \ref + addDataRange, with the parameter \a simplify explicitly set to false. This is useful if many data + ranges will be added to the selection successively and the overhead for simplifying after each + iteration shall be avoided. In this case, you should make sure to call \ref simplify after + completing the operation. + + Use \ref enforceType to bring the data selection into a state complying with the constraints for + selections defined in \ref QCP::SelectionType. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on QCPDataSelection and + QCPDataRange. + + \section qcpdataselection-iterating Iterating over a data selection + + As an example, the following code snippet calculates the average value of a graph's data + \ref QCPAbstractPlottable::selection "selection": + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpdataselection-iterating-1 + +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataSelection::dataRangeCount() const + + Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref + dataRange via their index. + + \see dataRange, dataPointCount +*/ + +/*! \fn QList QCPDataSelection::dataRanges() const + + Returns all data ranges that make up the data selection. If the data selection is simplified (the + usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point + index. + + \see dataRange +*/ + +/*! \fn bool QCPDataSelection::isEmpty() const + + Returns true if there are no data ranges, and thus no data points, in this QCPDataSelection + instance. + + \see dataRangeCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataSelection. +*/ +QCPDataSelection::QCPDataSelection() +{ +} + +/*! + Creates a QCPDataSelection containing the provided \a range. +*/ +QCPDataSelection::QCPDataSelection(const QCPDataRange &range) +{ + mDataRanges.append(range); +} + +/*! + Returns true if this selection is identical (contains the same data ranges with the same begin + and end indices) to \a other. + + Note that both data selections must be in simplified state (the usual state of the selection, see + \ref simplify) for this operator to return correct results. +*/ +bool QCPDataSelection::operator==(const QCPDataSelection &other) const +{ + if (mDataRanges.size() != other.mDataRanges.size()) + return false; + for (int i=0; i= other.end()) + break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this + + if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored + { + if (thisBegin >= other.begin()) // range leading segment is encompassed + { + if (thisEnd <= other.end()) // range fully encompassed, remove completely + { + mDataRanges.removeAt(i); + continue; + } else // only leading segment is encompassed, trim accordingly + mDataRanges[i].setBegin(other.end()); + } else // leading segment is not encompassed + { + if (thisEnd <= other.end()) // only trailing segment is encompassed, trim accordingly + { + mDataRanges[i].setEnd(other.begin()); + } else // other lies inside this range, so split range + { + mDataRanges[i].setEnd(other.begin()); + mDataRanges.insert(i+1, QCPDataRange(other.end(), thisEnd)); + break; // since data ranges are sorted (and don't overlap) after simplify() call, we're done here + } + } + } + ++i; + } + + return *this; +} + +/*! + Returns the total number of data points contained in all data ranges that make up this data + selection. +*/ +int QCPDataSelection::dataPointCount() const +{ + int result = 0; + for (int i=0; i= 0 && index < mDataRanges.size()) + { + return mDataRanges.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of range:" << index; + return QCPDataRange(); + } +} + +/*! + Returns a \ref QCPDataRange which spans the entire data selection, including possible + intermediate segments which are not part of the original data selection. +*/ +QCPDataRange QCPDataSelection::span() const +{ + if (isEmpty()) + return QCPDataRange(); + else + return QCPDataRange(mDataRanges.first().begin(), mDataRanges.last().end()); +} + +/*! + Adds the given \a dataRange to this data selection. This is equivalent to the += operator but + allows disabling immediate simplification by setting \a simplify to false. This can improve + performance if adding a very large amount of data ranges successively. In this case, make sure to + call \ref simplify manually, after the operation. +*/ +void QCPDataSelection::addDataRange(const QCPDataRange &dataRange, bool simplify) +{ + mDataRanges.append(dataRange); + if (simplify) + this->simplify(); +} + +/*! + Removes all data ranges. The data selection then contains no data points. + + \ref isEmpty +*/ +void QCPDataSelection::clear() +{ + mDataRanges.clear(); +} + +/*! + Sorts all data ranges by range begin index in ascending order, and then joins directly adjacent + or overlapping ranges. This can reduce the number of individual data ranges in the selection, and + prevents possible double-counting when iterating over the data points held by the data ranges. + + This method is automatically called when using the addition/subtraction operators. The only case + when \ref simplify is left to the user, is when calling \ref addDataRange, with the parameter \a + simplify explicitly set to false. +*/ +void QCPDataSelection::simplify() +{ + // remove any empty ranges: + for (int i=mDataRanges.size()-1; i>=0; --i) + { + if (mDataRanges.at(i).isEmpty()) + mDataRanges.removeAt(i); + } + if (mDataRanges.isEmpty()) + return; + + // sort ranges by starting value, ascending: + std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin); + + // join overlapping/contiguous ranges: + int i = 1; + while (i < mDataRanges.size()) + { + if (mDataRanges.at(i-1).end() >= mDataRanges.at(i).begin()) // range i overlaps/joins with i-1, so expand range i-1 appropriately and remove range i from list + { + mDataRanges[i-1].setEnd(qMax(mDataRanges.at(i-1).end(), mDataRanges.at(i).end())); + mDataRanges.removeAt(i); + } else + ++i; + } +} + +/*! + Makes sure this data selection conforms to the specified \a type selection type. Before the type + is enforced, \ref simplify is called. + + Depending on \a type, enforcing means adding new data points that were previously not part of the + selection, or removing data points from the selection. If the current selection already conforms + to \a type, the data selection is not changed. + + \see QCP::SelectionType +*/ +void QCPDataSelection::enforceType(QCP::SelectionType type) +{ + simplify(); + switch (type) + { + case QCP::stNone: + { + mDataRanges.clear(); + break; + } + case QCP::stWhole: + { + // whole selection isn't defined by data range, so don't change anything (is handled in plottable methods) + break; + } + case QCP::stSingleData: + { + // reduce all data ranges to the single first data point: + if (!mDataRanges.isEmpty()) + { + if (mDataRanges.size() > 1) + mDataRanges = QList() << mDataRanges.first(); + if (mDataRanges.first().length() > 1) + mDataRanges.first().setEnd(mDataRanges.first().begin()+1); + } + break; + } + case QCP::stDataRange: + { + mDataRanges = QList() << span(); + break; + } + case QCP::stMultipleDataRanges: + { + // this is the selection type that allows all concievable combinations of ranges, so do nothing + break; + } + } +} + +/*! + Returns true if the data selection \a other is contained entirely in this data selection, i.e. + all data point indices that are in \a other are also in this data selection. + + \see QCPDataRange::contains +*/ +bool QCPDataSelection::contains(const QCPDataSelection &other) const +{ + if (other.isEmpty()) return false; + + int otherIndex = 0; + int thisIndex = 0; + while (thisIndex < mDataRanges.size() && otherIndex < other.mDataRanges.size()) + { + if (mDataRanges.at(thisIndex).contains(other.mDataRanges.at(otherIndex))) + ++otherIndex; + else + ++thisIndex; + } + return thisIndex < mDataRanges.size(); // if thisIndex ran all the way to the end to find a containing range for the current otherIndex, other is not contained in this +} + +/*! + Returns a data selection containing the points which are both in this data selection and in the + data range \a other. + + A common use case is to limit an unknown data selection to the valid range of a data container, + using \ref QCPDataContainer::dataRange as \a other. One can then safely iterate over the returned + data selection without exceeding the data container's bounds. +*/ +QCPDataSelection QCPDataSelection::intersection(const QCPDataRange &other) const +{ + QCPDataSelection result; + for (int i=0; iorientation() == Qt::Horizontal) + return QCPRange(axis->pixelToCoord(mRect.left()), axis->pixelToCoord(mRect.left()+mRect.width())); + else + return QCPRange(axis->pixelToCoord(mRect.top()+mRect.height()), axis->pixelToCoord(mRect.top())); + } else + { + qDebug() << Q_FUNC_INFO << "called with axis zero"; + return QCPRange(); + } +} + +/*! + Sets the pen that will be used to draw the selection rect outline. + + \see setBrush +*/ +void QCPSelectionRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used to fill the selection rect. By default the selection rect is not + filled, i.e. \a brush is Qt::NoBrush. + + \see setPen +*/ +void QCPSelectionRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + If there is currently a selection interaction going on (\ref isActive), the interaction is + canceled. The selection rect will emit the \ref canceled signal. +*/ +void QCPSelectionRect::cancel() +{ + if (mActive) + { + mActive = false; + emit canceled(mRect, 0); + } +} + +/*! \internal + + This method is called by QCustomPlot to indicate that a selection rect interaction was initiated. + The default implementation sets the selection rect to active, initializes the selection rect + geometry and emits the \ref started signal. +*/ +void QCPSelectionRect::startSelection(QMouseEvent *event) +{ + mActive = true; + mRect = QRect(event->pos(), event->pos()); + emit started(event); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs + to update its geometry. The default implementation updates the rect and emits the \ref changed + signal. +*/ +void QCPSelectionRect::moveSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + emit changed(mRect, event); + layer()->replot(); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has + finished by the user releasing the mouse button. The default implementation deactivates the + selection rect and emits the \ref accepted signal. +*/ +void QCPSelectionRect::endSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + mActive = false; + emit accepted(mRect, event); +} + +/*! \internal + + This method is called by QCustomPlot when a key has been pressed by the user while the selection + rect interaction is active. The default implementation allows to \ref cancel the interaction by + hitting the escape key. +*/ +void QCPSelectionRect::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape && mActive) + { + mActive = false; + emit canceled(mRect, event); + } +} + +/* inherits documentation from base class */ +void QCPSelectionRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/*! \internal + + If the selection rect is active (\ref isActive), draws the selection rect defined by \a mRect. + + \seebaseclassmethod +*/ +void QCPSelectionRect::draw(QCPPainter *painter) +{ + if (mActive) + { + painter->setPen(mPen); + painter->setBrush(mBrush); + painter->drawRect(mRect); + } +} +/* end of 'src/selectionrect.cpp' */ + + +/* including file 'src/layout.cpp', size 79064 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPMarginGroup +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPMarginGroup + \brief A margin group allows synchronization of margin sides if working with multiple layout elements. + + QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that + they will all have the same size, based on the largest required margin in the group. + + \n + \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" + \n + + In certain situations it is desirable that margins at specific sides are synchronized across + layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will + provide a cleaner look to the user if the left and right margins of the two axis rects are of the + same size. The left axis of the top axis rect will then be at the same horizontal position as the + left axis of the lower axis rect, making them appear aligned. The same applies for the right + axes. This is what QCPMarginGroup makes possible. + + To add/remove a specific side of a layout element to/from a margin group, use the \ref + QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call + \ref clear, or just delete the margin group. + + \section QCPMarginGroup-example Example + + First create a margin group: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 + Then set this group on the layout element sides: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-2 + Here, we've used the first two axis rects of the plot and synchronized their left margins with + each other and their right margins with each other. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const + + Returns a list of all layout elements that have their margin \a side associated with this margin + group. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPMarginGroup instance in \a parentPlot. +*/ +QCPMarginGroup::QCPMarginGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot) +{ + mChildren.insert(QCP::msLeft, QList()); + mChildren.insert(QCP::msRight, QList()); + mChildren.insert(QCP::msTop, QList()); + mChildren.insert(QCP::msBottom, QList()); +} + +QCPMarginGroup::~QCPMarginGroup() +{ + clear(); +} + +/*! + Returns whether this margin group is empty. If this function returns true, no layout elements use + this margin group to synchronize margin sides. +*/ +bool QCPMarginGroup::isEmpty() const +{ + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + if (!it.value().isEmpty()) + return false; + } + return true; +} + +/*! + Clears this margin group. The synchronization of the margin sides that use this margin group is + lifted and they will use their individual margin sizes again. +*/ +void QCPMarginGroup::clear() +{ + // make all children remove themselves from this margin group: + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + const QList elements = it.value(); + for (int i=elements.size()-1; i>=0; --i) + elements.at(i)->setMarginGroup(it.key(), 0); // removes itself from mChildren via removeChild + } +} + +/*! \internal + + Returns the synchronized common margin for \a side. This is the margin value that will be used by + the layout element on the respective side, if it is part of this margin group. + + The common margin is calculated by requesting the automatic margin (\ref + QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin + group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into + account, too.) +*/ +int QCPMarginGroup::commonMargin(QCP::MarginSide side) const +{ + // query all automatic margins of the layout elements in this margin group side and find maximum: + int result = 0; + const QList elements = mChildren.value(side); + for (int i=0; iautoMargins().testFlag(side)) + continue; + int m = qMax(elements.at(i)->calculateAutoMargin(side), QCP::getMarginValue(elements.at(i)->minimumMargins(), side)); + if (m > result) + result = m; + } + return result; +} + +/*! \internal + + Adds \a element to the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].contains(element)) + mChildren[side].append(element); + else + qDebug() << Q_FUNC_INFO << "element is already child of this margin group side" << reinterpret_cast(element); +} + +/*! \internal + + Removes \a element from the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].removeOne(element)) + qDebug() << Q_FUNC_INFO << "element is not child of this margin group side" << reinterpret_cast(element); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutElement + \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". + + This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. + + A Layout element is a rectangular object which can be placed in layouts. It has an outer rect + (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference + between outer and inner rect is called its margin. The margin can either be set to automatic or + manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be + set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, + the layout element subclass will control the value itself (via \ref calculateAutoMargin). + + Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level + layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref + QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. + + Thus in QCustomPlot one can divide layout elements into two categories: The ones that are + invisible by themselves, because they don't draw anything. Their only purpose is to manage the + position and size of other layout elements. This category of layout elements usually use + QCPLayout as base class. Then there is the category of layout elements which actually draw + something. For example, QCPAxisRect, QCPLegend and QCPTextElement are of this category. This does + not necessarily mean that the latter category can't have child layout elements. QCPLegend for + instance, actually derives from QCPLayoutGrid and the individual legend items are child layout + elements in the grid layout. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayout *QCPLayoutElement::layout() const + + Returns the parent layout of this layout element. +*/ + +/*! \fn QRect QCPLayoutElement::rect() const + + Returns the inner rect of this layout element. The inner rect is the outer rect (\ref outerRect, \ref + setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). + + In some cases, the area between outer and inner rect is left blank. In other cases the margin + area is used to display peripheral graphics while the main content is in the inner rect. This is + where automatic margin calculation becomes interesting because it allows the layout element to + adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect + draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if + \ref setAutoMargins is enabled) according to the space required by the labels of the axes. + + \see outerRect +*/ + +/*! \fn QRect QCPLayoutElement::outerRect() const + + Returns the outer rect of this layout element. The outer rect is the inner rect expanded by the + margins (\ref setMargins, \ref setAutoMargins). The outer rect is used (and set via \ref + setOuterRect) by the parent \ref QCPLayout to control the size of this layout element. + + \see rect +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutElement and sets default values. +*/ +QCPLayoutElement::QCPLayoutElement(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout) + mParentLayout(0), + mMinimumSize(), + mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), + mSizeConstraintRect(scrInnerRect), + mRect(0, 0, 0, 0), + mOuterRect(0, 0, 0, 0), + mMargins(0, 0, 0, 0), + mMinimumMargins(0, 0, 0, 0), + mAutoMargins(QCP::msAll) +{ +} + +QCPLayoutElement::~QCPLayoutElement() +{ + setMarginGroup(QCP::msAll, 0); // unregister at margin groups, if there are any + // unregister at layout: + if (qobject_cast(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor + mParentLayout->take(this); +} + +/*! + Sets the outer rect of this layout element. If the layout element is inside a layout, the layout + sets the position and size of this layout element using this function. + + Calling this function externally has no effect, since the layout will overwrite any changes to + the outer rect upon the next replot. + + The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. + + \see rect +*/ +void QCPLayoutElement::setOuterRect(const QRect &rect) +{ + if (mOuterRect != rect) + { + mOuterRect = rect; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all + sides, this function is used to manually set the margin on those sides. Sides that are still set + to be handled automatically are ignored and may have any value in \a margins. + + The margin is the distance between the outer rect (controlled by the parent layout via \ref + setOuterRect) and the inner \ref rect (which usually contains the main content of this layout + element). + + \see setAutoMargins +*/ +void QCPLayoutElement::setMargins(const QMargins &margins) +{ + if (mMargins != margins) + { + mMargins = margins; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + If \ref setAutoMargins is enabled on some or all margins, this function is used to provide + minimum values for those margins. + + The minimum values are not enforced on margin sides that were set to be under manual control via + \ref setAutoMargins. + + \see setAutoMargins +*/ +void QCPLayoutElement::setMinimumMargins(const QMargins &margins) +{ + if (mMinimumMargins != margins) + { + mMinimumMargins = margins; + } +} + +/*! + Sets on which sides the margin shall be calculated automatically. If a side is calculated + automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is + set to be controlled manually, the value may be specified with \ref setMargins. + + Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref + setMarginGroup), to synchronize (align) it with other layout elements in the plot. + + \see setMinimumMargins, setMargins, QCP::MarginSide +*/ +void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) +{ + mAutoMargins = sides; +} + +/*! + Sets the minimum size of this layout element. A parent layout tries to respect the \a size here + by changing row/column sizes in the layout accordingly. + + If the parent layout size is not sufficient to satisfy all minimum size constraints of its child + layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot + propagates the layout's size constraints to the outside by setting its own minimum QWidget size + accordingly, so violations of \a size should be exceptions. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMinimumSize(const QSize &size) +{ + if (mMinimumSize != size) + { + mMinimumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the minimum size of this layout element. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMinimumSize(int width, int height) +{ + setMinimumSize(QSize(width, height)); +} + +/*! + Sets the maximum size of this layout element. A parent layout tries to respect the \a size here + by changing row/column sizes in the layout accordingly. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMaximumSize(const QSize &size) +{ + if (mMaximumSize != size) + { + mMaximumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the maximum size of this layout element. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMaximumSize(int width, int height) +{ + setMaximumSize(QSize(width, height)); +} + +/*! + Sets to which rect of a layout element the size constraints apply. Size constraints can be set + via \ref setMinimumSize and \ref setMaximumSize. + + The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis + labels), whereas the inner rect (\ref rect) does not. + + \see setMinimumSize, setMaximumSize +*/ +void QCPLayoutElement::setSizeConstraintRect(SizeConstraintRect constraintRect) +{ + if (mSizeConstraintRect != constraintRect) + { + mSizeConstraintRect = constraintRect; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! + Sets the margin \a group of the specified margin \a sides. + + Margin groups allow synchronizing specified margins across layout elements, see the documentation + of \ref QCPMarginGroup. + + To unset the margin group of \a sides, set \a group to 0. + + Note that margin groups only work for margin sides that are set to automatic (\ref + setAutoMargins). + + \see QCP::MarginSide +*/ +void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) +{ + QVector sideVector; + if (sides.testFlag(QCP::msLeft)) sideVector.append(QCP::msLeft); + if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); + if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); + if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); + + for (int i=0; iremoveChild(side, this); + + if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there + { + mMarginGroups.remove(side); + } else // setting to a new group + { + mMarginGroups[side] = group; + group->addChild(side, this); + } + } + } +} + +/*! + Updates the layout element and sub-elements. This function is automatically called before every + replot by the parent layout element. It is called multiple times, once for every \ref + UpdatePhase. The phases are run through in the order of the enum values. For details about what + happens at the different phases, see the documentation of \ref UpdatePhase. + + Layout elements that have child elements should call the \ref update method of their child + elements, and pass the current \a phase unchanged. + + The default implementation executes the automatic margin mechanism in the \ref upMargins phase. + Subclasses should make sure to call the base class implementation. +*/ +void QCPLayoutElement::update(UpdatePhase phase) +{ + if (phase == upMargins) + { + if (mAutoMargins != QCP::msNone) + { + // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group: + QMargins newMargins = mMargins; + QList allMarginSides = QList() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom; + foreach (QCP::MarginSide side, allMarginSides) + { + if (mAutoMargins.testFlag(side)) // this side's margin shall be calculated automatically + { + if (mMarginGroups.contains(side)) + QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group + else + QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly + // apply minimum margin restrictions: + if (QCP::getMarginValue(newMargins, side) < QCP::getMarginValue(mMinimumMargins, side)) + QCP::setMarginValue(newMargins, side, QCP::getMarginValue(mMinimumMargins, side)); + } + } + setMargins(newMargins); + } + } +} + +/*! + Returns the suggested minimum size this layout element (the \ref outerRect) may be compressed to, + if no manual minimum size is set. + + if a minimum size (\ref setMinimumSize) was not set manually, parent layouts use the returned size + (usually indirectly through \ref QCPLayout::getFinalMinimumOuterSize) to determine the minimum + allowed size of this layout element. + + A manual minimum size is considered set if it is non-zero. + + The default implementation simply returns the sum of the horizontal margins for the width and the + sum of the vertical margins for the height. Reimplementations may use their detailed knowledge + about the layout element's content to provide size hints. +*/ +QSize QCPLayoutElement::minimumOuterSizeHint() const +{ + return QSize(mMargins.left()+mMargins.right(), mMargins.top()+mMargins.bottom()); +} + +/*! + Returns the suggested maximum size this layout element (the \ref outerRect) may be expanded to, + if no manual maximum size is set. + + if a maximum size (\ref setMaximumSize) was not set manually, parent layouts use the returned + size (usually indirectly through \ref QCPLayout::getFinalMaximumOuterSize) to determine the + maximum allowed size of this layout element. + + A manual maximum size is considered set if it is smaller than Qt's \c QWIDGETSIZE_MAX. + + The default implementation simply returns \c QWIDGETSIZE_MAX for both width and height, implying + no suggested maximum size. Reimplementations may use their detailed knowledge about the layout + element's content to provide size hints. +*/ +QSize QCPLayoutElement::maximumOuterSizeHint() const +{ + return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); +} + +/*! + Returns a list of all child elements in this layout element. If \a recursive is true, all + sub-child elements are included in the list, too. + + \warning There may be entries with value 0 in the returned list. (For example, QCPLayoutGrid may have + empty cells which yield 0 at the respective index.) +*/ +QList QCPLayoutElement::elements(bool recursive) const +{ + Q_UNUSED(recursive) + return QList(); +} + +/*! + Layout elements are sensitive to events inside their outer rect. If \a pos is within the outer + rect, this method returns a value corresponding to 0.99 times the parent plot's selection + tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is + true, -1.0 is returned. + + See \ref QCPLayerable::selectTest for a general explanation of this virtual method. + + QCPLayoutElement subclasses may reimplement this method to provide more specific selection test + behaviour. +*/ +double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + + if (onlySelectable) + return -1; + + if (QRectF(mOuterRect).contains(pos)) + { + if (mParentPlot) + return mParentPlot->selectionTolerance()*0.99; + else + { + qDebug() << Q_FUNC_INFO << "parent plot not defined"; + return -1; + } + } else + return -1; +} + +/*! \internal + + propagates the parent plot initialization to all child elements, by calling \ref + QCPLayerable::initializeParentPlot on them. +*/ +void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) +{ + foreach (QCPLayoutElement* el, elements(false)) + { + if (!el->parentPlot()) + el->initializeParentPlot(parentPlot); + } +} + +/*! \internal + + Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a + side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the + returned value will not be smaller than the specified minimum margin. + + The default implementation just returns the respective manual margin (\ref setMargins) or the + minimum margin, whichever is larger. +*/ +int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) +{ + return qMax(QCP::getMarginValue(mMargins, side), QCP::getMarginValue(mMinimumMargins, side)); +} + +/*! \internal + + This virtual method is called when this layout element was moved to a different QCPLayout, or + when this layout element has changed its logical position (e.g. row and/or column) within the + same QCPLayout. Subclasses may use this to react accordingly. + + Since this method is called after the completion of the move, you can access the new parent + layout via \ref layout(). + + The default implementation does nothing. +*/ +void QCPLayoutElement::layoutChanged() +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayout +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayout + \brief The abstract base class for layouts + + This is an abstract base class for layout elements whose main purpose is to define the position + and size of other child layout elements. In most cases, layouts don't draw anything themselves + (but there are exceptions to this, e.g. QCPLegend). + + QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. + + QCPLayout introduces a common interface for accessing and manipulating the child elements. Those + functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref + simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions + to this interface which are more specialized to the form of the layout. For example, \ref + QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid + more conveniently. + + Since this is an abstract base class, you can't instantiate it directly. Rather use one of its + subclasses like QCPLayoutGrid or QCPLayoutInset. + + For a general introduction to the layout system, see the dedicated documentation page \ref + thelayoutsystem "The Layout System". +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPLayout::elementCount() const = 0 + + Returns the number of elements/cells in the layout. + + \see elements, elementAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 + + Returns the element in the cell with the given \a index. If \a index is invalid, returns 0. + + Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. + QCPLayoutGrid), so this function may return 0 in those cases. You may use this function to check + whether a cell is empty or not. + + \see elements, elementCount, takeAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 + + Removes the element with the given \a index from the layout and returns it. + + If the \a index is invalid or the cell with that index is empty, returns 0. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see elementAt, take +*/ + +/*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 + + Removes the specified \a element from the layout and returns true on success. + + If the \a element isn't in this layout, returns false. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see takeAt +*/ + +/* end documentation of pure virtual functions */ + +/*! + Creates an instance of QCPLayout and sets default values. Note that since QCPLayout + is an abstract base class, it can't be instantiated directly. +*/ +QCPLayout::QCPLayout() +{ +} + +/*! + If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to + reposition and resize their cells. + + Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements". + + For details about this method and the update phases, see the documentation of \ref + QCPLayoutElement::update. +*/ +void QCPLayout::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + // set child element rects according to layout: + if (phase == upLayout) + updateLayout(); + + // propagate update call to child elements: + const int elCount = elementCount(); + for (int i=0; iupdate(phase); + } +} + +/* inherits documentation from base class */ +QList QCPLayout::elements(bool recursive) const +{ + const int c = elementCount(); + QList result; +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(c); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the + default implementation does nothing. + + Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit + simplification while QCPLayoutGrid does. +*/ +void QCPLayout::simplify() +{ +} + +/*! + Removes and deletes the element at the provided \a index. Returns true on success. If \a index is + invalid or points to an empty cell, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the returned element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see remove, takeAt +*/ +bool QCPLayout::removeAt(int index) +{ + if (QCPLayoutElement *el = takeAt(index)) + { + delete el; + return true; + } else + return false; +} + +/*! + Removes and deletes the provided \a element. Returns true on success. If \a element is not in the + layout, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see removeAt, take +*/ +bool QCPLayout::remove(QCPLayoutElement *element) +{ + if (take(element)) + { + delete element; + return true; + } else + return false; +} + +/*! + Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure + all empty cells are collapsed. + + \see remove, removeAt +*/ +void QCPLayout::clear() +{ + for (int i=elementCount()-1; i>=0; --i) + { + if (elementAt(i)) + removeAt(i); + } + simplify(); +} + +/*! + Subclasses call this method to report changed (minimum/maximum) size constraints. + + If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref + sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of + QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, + it may update itself and resize cells accordingly. +*/ +void QCPLayout::sizeConstraintsChanged() const +{ + if (QWidget *w = qobject_cast(parent())) + w->updateGeometry(); + else if (QCPLayout *l = qobject_cast(parent())) + l->sizeConstraintsChanged(); +} + +/*! \internal + + Subclasses reimplement this method to update the position and sizes of the child elements/cells + via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. + + The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay + within that rect. + + \ref getSectionSizes may help with the reimplementation of this function. + + \see update +*/ +void QCPLayout::updateLayout() +{ +} + + +/*! \internal + + Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the + \ref QCPLayerable::parentLayerable and the QObject parent to this layout. + + Further, if \a el didn't previously have a parent plot, calls \ref + QCPLayerable::initializeParentPlot on \a el to set the paret plot. + + This method is used by subclass specific methods that add elements to the layout. Note that this + method only changes properties in \a el. The removal from the old layout and the insertion into + the new layout must be done additionally. +*/ +void QCPLayout::adoptElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = this; + el->setParentLayerable(this); + el->setParent(this); + if (!el->parentPlot()) + el->initializeParentPlot(mParentPlot); + el->layoutChanged(); + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout + and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent + QCustomPlot. + + This method is used by subclass specific methods that remove elements from the layout (e.g. \ref + take or \ref takeAt). Note that this method only changes properties in \a el. The removal from + the old layout must be done additionally. +*/ +void QCPLayout::releaseElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = 0; + el->setParentLayerable(0); + el->setParent(mParentPlot); + // Note: Don't initializeParentPlot(0) here, because layout element will stay in same parent plot + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + This is a helper function for the implementation of \ref updateLayout in subclasses. + + It calculates the sizes of one-dimensional sections with provided constraints on maximum section + sizes, minimum section sizes, relative stretch factors and the final total size of all sections. + + The QVector entries refer to the sections. Thus all QVectors must have the same size. + + \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size + imposed, set all vector values to Qt's QWIDGETSIZE_MAX. + + \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size + imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than + \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, + not exceeding the allowed total size is taken to be more important than not going below minimum + section sizes.) + + \a stretchFactors give the relative proportions of the sections to each other. If all sections + shall be scaled equally, set all values equal. If the first section shall be double the size of + each individual other section, set the first number of \a stretchFactors to double the value of + the other individual values (e.g. {2, 1, 1, 1}). + + \a totalSize is the value that the final section sizes will add up to. Due to rounding, the + actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, + you could distribute the remaining difference on the sections. + + The return value is a QVector containing the section sizes. +*/ +QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const +{ + if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) + { + qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; + return QVector(); + } + if (stretchFactors.isEmpty()) + return QVector(); + int sectionCount = stretchFactors.size(); + QVector sectionSizes(sectionCount); + // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): + int minSizeSum = 0; + for (int i=0; i minimumLockedSections; + QList unfinishedSections; + for (int i=0; i result(sectionCount); + for (int i=0; iminimumOuterSizeHint(); + QSize minOuter = el->minimumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset minimum of 0) + if (minOuter.width() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + minOuter.rwidth() += el->margins().left() + el->margins().right(); + if (minOuter.height() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + minOuter.rheight() += el->margins().top() + el->margins().bottom(); + + return QSize(minOuter.width() > 0 ? minOuter.width() : minOuterHint.width(), + minOuter.height() > 0 ? minOuter.height() : minOuterHint.height());; +} + +/*! \internal + + This is a helper function for the implementation of subclasses. + + It returns the maximum size that should finally be used for the outer rect of the passed layout + element \a el. + + It takes into account whether a manual maximum size is set (\ref + QCPLayoutElement::setMaximumSize), which size constraint is set (\ref + QCPLayoutElement::setSizeConstraintRect), as well as the maximum size hint, if no manual maximum + size was set (\ref QCPLayoutElement::maximumOuterSizeHint). +*/ +QSize QCPLayout::getFinalMaximumOuterSize(const QCPLayoutElement *el) +{ + QSize maxOuterHint = el->maximumOuterSizeHint(); + QSize maxOuter = el->maximumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset maximum of QWIDGETSIZE_MAX) + if (maxOuter.width() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + maxOuter.rwidth() += el->margins().left() + el->margins().right(); + if (maxOuter.height() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + maxOuter.rheight() += el->margins().top() + el->margins().bottom(); + + return QSize(maxOuter.width() < QWIDGETSIZE_MAX ? maxOuter.width() : maxOuterHint.width(), + maxOuter.height() < QWIDGETSIZE_MAX ? maxOuter.height() : maxOuterHint.height()); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutGrid + \brief A layout that arranges child elements in a grid + + Elements are laid out in a grid with configurable stretch factors (\ref setColumnStretchFactor, + \ref setRowStretchFactor) and spacing (\ref setColumnSpacing, \ref setRowSpacing). + + Elements can be added to cells via \ref addElement. The grid is expanded if the specified row or + column doesn't exist yet. Whether a cell contains a valid layout element can be checked with \ref + hasElement, that element can be retrieved with \ref element. If rows and columns that only have + empty cells shall be removed, call \ref simplify. Removal of elements is either done by just + adding the element to a different layout or by using the QCPLayout interface \ref take or \ref + remove. + + If you use \ref addElement(QCPLayoutElement*) without explicit parameters for \a row and \a + column, the grid layout will choose the position according to the current \ref setFillOrder and + the wrapping (\ref setWrap). + + Row and column insertion can be performed with \ref insertRow and \ref insertColumn. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPLayoutGrid::rowCount() const + + Returns the number of rows in the layout. + + \see columnCount +*/ + +/*! \fn int QCPLayoutGrid::columnCount() const + + Returns the number of columns in the layout. + + \see rowCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutGrid and sets default values. +*/ +QCPLayoutGrid::QCPLayoutGrid() : + mColumnSpacing(5), + mRowSpacing(5), + mWrap(0), + mFillOrder(foRowsFirst) +{ +} + +QCPLayoutGrid::~QCPLayoutGrid() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the element in the cell in \a row and \a column. + + Returns 0 if either the row/column is invalid or if the cell is empty. In those cases, a qDebug + message is printed. To check whether a cell exists and isn't empty, use \ref hasElement. + + \see addElement, hasElement +*/ +QCPLayoutElement *QCPLayoutGrid::element(int row, int column) const +{ + if (row >= 0 && row < mElements.size()) + { + if (column >= 0 && column < mElements.first().size()) + { + if (QCPLayoutElement *result = mElements.at(row).at(column)) + return result; + else + qDebug() << Q_FUNC_INFO << "Requested cell is empty. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid column. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid row. Row:" << row << "Column:" << column; + return 0; +} + + +/*! \overload + + Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it + is first removed from there. If \a row or \a column don't exist yet, the layout is expanded + accordingly. + + Returns true if the element was added successfully, i.e. if the cell at \a row and \a column + didn't already have an element. + + Use the overload of this method without explicit row/column index to place the element according + to the configured fill order and wrapping settings. + + \see element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(int row, int column, QCPLayoutElement *element) +{ + if (!hasElement(row, column)) + { + if (element && element->layout()) // remove from old layout first + element->layout()->take(element); + expandTo(row+1, column+1); + mElements[row][column] = element; + if (element) + adoptElement(element); + return true; + } else + qDebug() << Q_FUNC_INFO << "There is already an element in the specified row/column:" << row << column; + return false; +} + +/*! \overload + + Adds the \a element to the next empty cell according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap). If \a element is already in a layout, it is first + removed from there. If necessary, the layout is expanded to hold the new element. + + Returns true if the element was added successfully. + + \see setFillOrder, setWrap, element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(QCPLayoutElement *element) +{ + int rowIndex = 0; + int colIndex = 0; + if (mFillOrder == foColumnsFirst) + { + while (hasElement(rowIndex, colIndex)) + { + ++colIndex; + if (colIndex >= mWrap && mWrap > 0) + { + colIndex = 0; + ++rowIndex; + } + } + } else + { + while (hasElement(rowIndex, colIndex)) + { + ++rowIndex; + if (rowIndex >= mWrap && mWrap > 0) + { + rowIndex = 0; + ++colIndex; + } + } + } + return addElement(rowIndex, colIndex, element); +} + +/*! + Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't + empty. + + \see element +*/ +bool QCPLayoutGrid::hasElement(int row, int column) +{ + if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) + return mElements.at(row).at(column); + else + return false; +} + +/*! + Sets the stretch \a factor of \a column. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactors, setRowStretchFactor +*/ +void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) +{ + if (column >= 0 && column < columnCount()) + { + if (factor > 0) + mColumnStretchFactors[column] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid column:" << column; +} + +/*! + Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactor, setRowStretchFactors +*/ +void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) +{ + if (factors.size() == mColumnStretchFactors.size()) + { + mColumnStretchFactors = factors; + for (int i=0; i= 0 && row < rowCount()) + { + if (factor > 0) + mRowStretchFactors[row] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid row:" << row; +} + +/*! + Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setRowStretchFactor, setColumnStretchFactors +*/ +void QCPLayoutGrid::setRowStretchFactors(const QList &factors) +{ + if (factors.size() == mRowStretchFactors.size()) + { + mRowStretchFactors = factors; + for (int i=0; i tempElements; + if (rearrange) + { + tempElements.reserve(elCount); + for (int i=0; i()); + mRowStretchFactors.append(1); + } + // go through rows and expand columns as necessary: + int newColCount = qMax(columnCount(), newColumnCount); + for (int i=0; i rowCount()) + newIndex = rowCount(); + + mRowStretchFactors.insert(newIndex, 1); + QList newRow; + for (int col=0; col columnCount()) + newIndex = columnCount(); + + mColumnStretchFactors.insert(newIndex, 1); + for (int row=0; row= 0 && row < rowCount()) + { + if (column >= 0 && column < columnCount()) + { + switch (mFillOrder) + { + case foRowsFirst: return column*rowCount() + row; + case foColumnsFirst: return row*columnCount() + column; + } + } else + qDebug() << Q_FUNC_INFO << "row index out of bounds:" << row; + } else + qDebug() << Q_FUNC_INFO << "column index out of bounds:" << column; + return 0; +} + +/*! + Converts the linear index to row and column indices and writes the result to \a row and \a + column. + + The way the cells are indexed depends on \ref setFillOrder. If it is \ref foRowsFirst, the + indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices + increase top to bottom and then left to right. + + If there are no cells (i.e. column or row count is zero), sets \a row and \a column to -1. + + For the retrieved \a row and \a column to be valid, the passed \a index must be valid itself, + i.e. greater or equal to zero and smaller than the current \ref elementCount. + + \see rowColToIndex +*/ +void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const +{ + row = -1; + column = -1; + const int nCols = columnCount(); + const int nRows = rowCount(); + if (nCols == 0 || nRows == 0) + return; + if (index < 0 || index >= elementCount()) + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return; + } + + switch (mFillOrder) + { + case foRowsFirst: + { + column = index / nRows; + row = index % nRows; + break; + } + case foColumnsFirst: + { + row = index / nCols; + column = index % nCols; + break; + } + } +} + +/* inherits documentation from base class */ +void QCPLayoutGrid::updateLayout() +{ + QVector minColWidths, minRowHeights, maxColWidths, maxRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + int totalRowSpacing = (rowCount()-1) * mRowSpacing; + int totalColSpacing = (columnCount()-1) * mColumnSpacing; + QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); + QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); + + // go through cells and set rects accordingly: + int yOffset = mRect.top(); + for (int row=0; row 0) + yOffset += rowHeights.at(row-1)+mRowSpacing; + int xOffset = mRect.left(); + for (int col=0; col 0) + xOffset += colWidths.at(col-1)+mColumnSpacing; + if (mElements.at(row).at(col)) + mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row))); + } + } +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::elementAt(int index) const +{ + if (index >= 0 && index < elementCount()) + { + int row, col; + indexToRowCol(index, row, col); + return mElements.at(row).at(col); + } else + return 0; +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + int row, col; + indexToRowCol(index, row, col); + mElements[row][col] = 0; + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutGrid::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; i QCPLayoutGrid::elements(bool recursive) const +{ + QList result; + const int elCount = elementCount(); +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(elCount); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing rows and columns which only contain empty cells. +*/ +void QCPLayoutGrid::simplify() +{ + // remove rows with only empty cells: + for (int row=rowCount()-1; row>=0; --row) + { + bool hasElements = false; + for (int col=0; col=0; --col) + { + bool hasElements = false; + for (int row=0; row minColWidths, minRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + QSize result(0, 0); + for (int i=0; i maxColWidths, maxRowHeights; + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + QSize result(0, 0); + for (int i=0; i QWIDGETSIZE_MAX) + result.setHeight(QWIDGETSIZE_MAX); + if (result.width() > QWIDGETSIZE_MAX) + result.setWidth(QWIDGETSIZE_MAX); + return result; +} + +/*! \internal + + Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights + respectively. + + The minimum height of a row is the largest minimum height of any element's outer rect in that + row. The minimum width of a column is the largest minimum width of any element's outer rect in + that column. + + This is a helper function for \ref updateLayout. + + \see getMaximumRowColSizes +*/ +void QCPLayoutGrid::getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const +{ + *minColWidths = QVector(columnCount(), 0); + *minRowHeights = QVector(rowCount(), 0); + for (int row=0; rowat(col) < minSize.width()) + (*minColWidths)[col] = minSize.width(); + if (minRowHeights->at(row) < minSize.height()) + (*minRowHeights)[row] = minSize.height(); + } + } + } +} + +/*! \internal + + Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights + respectively. + + The maximum height of a row is the smallest maximum height of any element's outer rect in that + row. The maximum width of a column is the smallest maximum width of any element's outer rect in + that column. + + This is a helper function for \ref updateLayout. + + \see getMinimumRowColSizes +*/ +void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const +{ + *maxColWidths = QVector(columnCount(), QWIDGETSIZE_MAX); + *maxRowHeights = QVector(rowCount(), QWIDGETSIZE_MAX); + for (int row=0; rowat(col) > maxSize.width()) + (*maxColWidths)[col] = maxSize.width(); + if (maxRowHeights->at(row) > maxSize.height()) + (*maxRowHeights)[row] = maxSize.height(); + } + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutInset +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPLayoutInset + \brief A layout that places child elements aligned to the border or arbitrarily positioned + + Elements are placed either aligned to the border or at arbitrary position in the area of the + layout. Which placement applies is controlled with the \ref InsetPlacement (\ref + setInsetPlacement). + + Elements are added via \ref addElement(QCPLayoutElement *element, Qt::Alignment alignment) or + addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset + placement will default to \ref ipBorderAligned and the element will be aligned according to the + \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at + arbitrary position and size, defined by \a rect. + + The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively. + + This is the layout that every QCPAxisRect has as \ref QCPAxisRect::insetLayout. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual void QCPLayoutInset::simplify() + + The QCPInsetLayout does not need simplification since it can never have empty cells due to its + linear index structure. This method does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutInset and sets default values. +*/ +QCPLayoutInset::QCPLayoutInset() +{ +} + +QCPLayoutInset::~QCPLayoutInset() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the placement type of the element with the specified \a index. +*/ +QCPLayoutInset::InsetPlacement QCPLayoutInset::insetPlacement(int index) const +{ + if (elementAt(index)) + return mInsetPlacement.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return ipFree; + } +} + +/*! + Returns the alignment of the element with the specified \a index. The alignment only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned. +*/ +Qt::Alignment QCPLayoutInset::insetAlignment(int index) const +{ + if (elementAt(index)) + return mInsetAlignment.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return 0; + } +} + +/*! + Returns the rect of the element with the specified \a index. The rect only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipFree. +*/ +QRectF QCPLayoutInset::insetRect(int index) const +{ + if (elementAt(index)) + return mInsetRect.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return QRectF(); + } +} + +/*! + Sets the inset placement type of the element with the specified \a index to \a placement. + + \see InsetPlacement +*/ +void QCPLayoutInset::setInsetPlacement(int index, QCPLayoutInset::InsetPlacement placement) +{ + if (elementAt(index)) + mInsetPlacement[index] = placement; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned, this function + is used to set the alignment of the element with the specified \a index to \a alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. +*/ +void QCPLayoutInset::setInsetAlignment(int index, Qt::Alignment alignment) +{ + if (elementAt(index)) + mInsetAlignment[index] = alignment; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the + position and size of the element with the specified \a index to \a rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + Note that the minimum and maximum sizes of the embedded element (\ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize) are enforced. +*/ +void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) +{ + if (elementAt(index)) + mInsetRect[index] = rect; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/* inherits documentation from base class */ +void QCPLayoutInset::updateLayout() +{ + for (int i=0; i finalMaxSize.width()) + insetRect.setWidth(finalMaxSize.width()); + if (insetRect.size().height() > finalMaxSize.height()) + insetRect.setHeight(finalMaxSize.height()); + } else if (mInsetPlacement.at(i) == ipBorderAligned) + { + insetRect.setSize(finalMinSize); + Qt::Alignment al = mInsetAlignment.at(i); + if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(rect().x()); + else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(rect().x()+rect().width()); + else insetRect.moveLeft(rect().x()+rect().width()*0.5-finalMinSize.width()*0.5); // default to Qt::AlignHCenter + if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(rect().y()); + else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(rect().y()+rect().height()); + else insetRect.moveTop(rect().y()+rect().height()*0.5-finalMinSize.height()*0.5); // default to Qt::AlignVCenter + } + mElements.at(i)->setOuterRect(insetRect); + } +} + +/* inherits documentation from base class */ +int QCPLayoutInset::elementCount() const +{ + return mElements.size(); +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::elementAt(int index) const +{ + if (index >= 0 && index < mElements.size()) + return mElements.at(index); + else + return 0; +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + mElements.removeAt(index); + mInsetPlacement.removeAt(index); + mInsetAlignment.removeAt(index); + mInsetRect.removeAt(index); + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutInset::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; irealVisibility() && mElements.at(i)->selectTest(pos, onlySelectable) >= 0) + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/*! + Adds the specified \a element to the layout as an inset aligned at the border (\ref + setInsetAlignment is initialized with \ref ipBorderAligned). The alignment is set to \a + alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. + + \see addElement(QCPLayoutElement *element, const QRectF &rect) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, Qt::Alignment alignment) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipBorderAligned); + mInsetAlignment.append(alignment); + mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4)); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} + +/*! + Adds the specified \a element to the layout as an inset with free positioning/sizing (\ref + setInsetAlignment is initialized with \ref ipFree). The position and size is set to \a + rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + \see addElement(QCPLayoutElement *element, Qt::Alignment alignment) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, const QRectF &rect) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipFree); + mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop); + mInsetRect.append(rect); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} +/* end of 'src/layout.cpp' */ + + +/* including file 'src/lineending.cpp', size 11536 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLineEnding +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLineEnding + \brief Handles the different ending decorations for line-like items + + \image html QCPLineEnding.png "The various ending styles currently supported" + + For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine + has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. + + The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can + be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of + the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. + For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite + directions, e.g. "outward". This can be changed by \ref setInverted, which would make the + respective arrow point inward. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a + QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. + \snippet documentation/doc-code-snippets/mainwindow.cpp qcplineending-sethead +*/ + +/*! + Creates a QCPLineEnding instance with default values (style \ref esNone). +*/ +QCPLineEnding::QCPLineEnding() : + mStyle(esNone), + mWidth(8), + mLength(10), + mInverted(false) +{ +} + +/*! + Creates a QCPLineEnding instance with the specified values. +*/ +QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : + mStyle(style), + mWidth(width), + mLength(length), + mInverted(inverted) +{ +} + +/*! + Sets the style of the ending decoration. +*/ +void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) +{ + mStyle = style; +} + +/*! + Sets the width of the ending decoration, if the style supports it. On arrows, for example, the + width defines the size perpendicular to the arrow's pointing direction. + + \see setLength +*/ +void QCPLineEnding::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the length of the ending decoration, if the style supports it. On arrows, for example, the + length defines the size in pointing direction. + + \see setWidth +*/ +void QCPLineEnding::setLength(double length) +{ + mLength = length; +} + +/*! + Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point + inward when \a inverted is set to true. + + Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or + discs, this doesn't make a difference. However, asymmetric styles like \ref esHalfBar are + affected by it, which can be used to control to which side the half bar points to. +*/ +void QCPLineEnding::setInverted(bool inverted) +{ + mInverted = inverted; +} + +/*! \internal + + Returns the maximum pixel radius the ending decoration might cover, starting from the position + the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). + + This is relevant for clipping. Only omit painting of the decoration when the position where the + decoration is supposed to be drawn is farther away from the clipping rect than the returned + distance. +*/ +double QCPLineEnding::boundingDistance() const +{ + switch (mStyle) + { + case esNone: + return 0; + + case esFlatArrow: + case esSpikeArrow: + case esLineArrow: + case esSkewedBar: + return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length + + case esDisc: + case esSquare: + case esDiamond: + case esBar: + case esHalfBar: + return mWidth*1.42; // items that only have a width -> width*sqrt(2) + + } + return 0; +} + +/*! + Starting from the origin of this line ending (which is style specific), returns the length + covered by the line ending symbol, in backward direction. + + For example, the \ref esSpikeArrow has a shorter real length than a \ref esFlatArrow, even if + both have the same \ref setLength value, because the spike arrow has an inward curved back, which + reduces the length along its center axis (the drawing origin for arrows is at the tip). + + This function is used for precise, style specific placement of line endings, for example in + QCPAxes. +*/ +double QCPLineEnding::realLength() const +{ + switch (mStyle) + { + case esNone: + case esLineArrow: + case esSkewedBar: + case esBar: + case esHalfBar: + return 0; + + case esFlatArrow: + return mLength; + + case esDisc: + case esSquare: + case esDiamond: + return mWidth*0.5; + + case esSpikeArrow: + return mLength*0.8; + } + return 0; +} + +/*! \internal + + Draws the line ending with the specified \a painter at the position \a pos. The direction of the + line ending is controlled with \a dir. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const +{ + if (mStyle == esNone) + return; + + QCPVector2D lengthVec = dir.normalized() * mLength*(mInverted ? -1 : 1); + if (lengthVec.isNull()) + lengthVec = QCPVector2D(1, 0); + QCPVector2D widthVec = dir.normalized().perpendicular() * mWidth*0.5*(mInverted ? -1 : 1); + + QPen penBackup = painter->pen(); + QBrush brushBackup = painter->brush(); + QPen miterPen = penBackup; + miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey + QBrush brush(painter->pen().color(), Qt::SolidPattern); + switch (mStyle) + { + case esNone: break; + case esFlatArrow: + { + QPointF points[3] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 3); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esSpikeArrow: + { + QPointF points[4] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec*0.8).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esLineArrow: + { + QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), + pos.toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawPolyline(points, 3); + painter->setPen(penBackup); + break; + } + case esDisc: + { + painter->setBrush(brush); + painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); + painter->setBrush(brushBackup); + break; + } + case esSquare: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), + (pos-widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esDiamond: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp).toPointF(), + (pos-widthVec).toPointF(), + (pos+widthVecPerp).toPointF(), + (pos+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esBar: + { + painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); + break; + } + case esHalfBar: + { + painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); + break; + } + case esSkewedBar: + { + if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic)) + { + // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)).toPointF()); + } else + { + // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF()); + } + break; + } + } +} + +/*! \internal + \overload + + Draws the line ending. The direction is controlled with the \a angle parameter in radians. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const +{ + draw(painter, pos, QCPVector2D(qCos(angle), qSin(angle))); +} +/* end of 'src/lineending.cpp' */ + + +/* including file 'src/axis/axisticker.cpp', size 18664 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTicker +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTicker + \brief The base class tick generator used by QCPAxis to create tick positions and tick labels + + Each QCPAxis has an internal QCPAxisTicker (or a subclass) in order to generate tick positions + and tick labels for the current axis range. The ticker of an axis can be set via \ref + QCPAxis::setTicker. Since that method takes a QSharedPointer, multiple + axes can share the same ticker instance. + + This base class generates normal tick coordinates and numeric labels for linear axes. It picks a + reasonable tick step (the separation between ticks) which results in readable tick labels. The + number of ticks that should be approximately generated can be set via \ref setTickCount. + Depending on the current tick step strategy (\ref setTickStepStrategy), the algorithm either + sacrifices readability to better match the specified tick count (\ref + QCPAxisTicker::tssMeetTickCount) or relaxes the tick count in favor of better tick steps (\ref + QCPAxisTicker::tssReadability), which is the default. + + The following more specialized axis ticker subclasses are available, see details in the + respective class documentation: + +
+ + + + + + + +
QCPAxisTickerFixed\image html axisticker-fixed.png
QCPAxisTickerLog\image html axisticker-log.png
QCPAxisTickerPi\image html axisticker-pi.png
QCPAxisTickerText\image html axisticker-text.png
QCPAxisTickerDateTime\image html axisticker-datetime.png
QCPAxisTickerTime\image html axisticker-time.png + \image html axisticker-time2.png
+
+ + \section axisticker-subclassing Creating own axis tickers + + Creating own axis tickers can be achieved very easily by sublassing QCPAxisTicker and + reimplementing some or all of the available virtual methods. + + In the simplest case you might wish to just generate different tick steps than the other tickers, + so you only reimplement the method \ref getTickStep. If you additionally want control over the + string that will be shown as tick label, reimplement \ref getTickLabel. + + If you wish to have complete control, you can generate the tick vectors and tick label vectors + yourself by reimplementing \ref createTickVector and \ref createLabelVector. The default + implementations use the previously mentioned virtual methods \ref getTickStep and \ref + getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case + of unequal tick steps, the method \ref getTickStep loses its usefulness and can be ignored. + + The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick + placement control is obtained by reimplementing \ref createSubTickVector. + + See the documentation of all these virtual methods in QCPAxisTicker for detailed information + about the parameters and expected return values. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTicker::QCPAxisTicker() : + mTickStepStrategy(tssReadability), + mTickCount(5), + mTickOrigin(0) +{ +} + +QCPAxisTicker::~QCPAxisTicker() +{ + +} + +/*! + Sets which strategy the axis ticker follows when choosing the size of the tick step. For the + available strategies, see \ref TickStepStrategy. +*/ +void QCPAxisTicker::setTickStepStrategy(QCPAxisTicker::TickStepStrategy strategy) +{ + mTickStepStrategy = strategy; +} + +/*! + Sets how many ticks this ticker shall aim to generate across the axis range. Note that \a count + is not guaranteed to be matched exactly, as generating readable tick intervals may conflict with + the requested number of ticks. + + Whether the readability has priority over meeting the requested \a count can be specified with + \ref setTickStepStrategy. +*/ +void QCPAxisTicker::setTickCount(int count) +{ + if (count > 0) + mTickCount = count; + else + qDebug() << Q_FUNC_INFO << "tick count must be greater than zero:" << count; +} + +/*! + Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a + concept and doesn't need to be inside the currently visible axis range. + + By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick + step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be + {-4, 1, 6, 11, 16,...}. +*/ +void QCPAxisTicker::setTickOrigin(double origin) +{ + mTickOrigin = origin; +} + +/*! + This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks), + tick label strings (\a tickLabels) and sub tick coordinates (\a subTicks). + + The ticks are generated for the specified \a range. The generated labels typically follow the + specified \a locale, \a formatChar and number \a precision, however this might be different (or + even irrelevant) for certain QCPAxisTicker subclasses. + + The output parameter \a ticks is filled with the generated tick positions in axis coordinates. + The output parameters \a subTicks and \a tickLabels are optional (set them to 0 if not needed) + and are respectively filled with sub tick coordinates, and tick label strings belonging to \a + ticks by index. +*/ +void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels) +{ + // generate (major) ticks: + double tickStep = getTickStep(range); + ticks = createTickVector(tickStep, range); + trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more) + + // generate sub ticks between major ticks: + if (subTicks) + { + if (ticks.size() > 0) + { + *subTicks = createSubTickVector(getSubTickCount(tickStep), ticks); + trimTicks(range, *subTicks, false); + } else + *subTicks = QVector(); + } + + // finally trim also outliers (no further clipping happens in axis drawing): + trimTicks(range, ticks, false); + // generate labels for visible ticks if requested: + if (tickLabels) + *tickLabels = createLabelVector(ticks, locale, formatChar, precision); +} + +/*! \internal + + Takes the entire currently visible axis range and returns a sensible tick step in + order to provide readable tick labels as well as a reasonable number of tick counts (see \ref + setTickCount, \ref setTickStepStrategy). + + If a QCPAxisTicker subclass only wants a different tick step behaviour than the default + implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper + function. +*/ +double QCPAxisTicker::getTickStep(const QCPRange &range) +{ + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return cleanMantissa(exactStep); +} + +/*! \internal + + Takes the \a tickStep, i.e. the distance between two consecutive ticks, and returns + an appropriate number of sub ticks for that specific tick step. + + Note that a returned sub tick count of e.g. 4 will split each tick interval into 5 sections. +*/ +int QCPAxisTicker::getSubTickCount(double tickStep) +{ + int result = 1; // default to 1, if no proper value can be found + + // separate integer and fractional part of mantissa: + double epsilon = 0.01; + double intPartf; + int intPart; + double fracPart = modf(getMantissa(tickStep), &intPartf); + intPart = intPartf; + + // handle cases with (almost) integer mantissa: + if (fracPart < epsilon || 1.0-fracPart < epsilon) + { + if (1.0-fracPart < epsilon) + ++intPart; + switch (intPart) + { + case 1: result = 4; break; // 1.0 -> 0.2 substep + case 2: result = 3; break; // 2.0 -> 0.5 substep + case 3: result = 2; break; // 3.0 -> 1.0 substep + case 4: result = 3; break; // 4.0 -> 1.0 substep + case 5: result = 4; break; // 5.0 -> 1.0 substep + case 6: result = 2; break; // 6.0 -> 2.0 substep + case 7: result = 6; break; // 7.0 -> 1.0 substep + case 8: result = 3; break; // 8.0 -> 2.0 substep + case 9: result = 2; break; // 9.0 -> 3.0 substep + } + } else + { + // handle cases with significantly fractional mantissa: + if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa + { + switch (intPart) + { + case 1: result = 2; break; // 1.5 -> 0.5 substep + case 2: result = 4; break; // 2.5 -> 0.5 substep + case 3: result = 4; break; // 3.5 -> 0.7 substep + case 4: result = 2; break; // 4.5 -> 1.5 substep + case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with default getTickStep from here on) + case 6: result = 4; break; // 6.5 -> 1.3 substep + case 7: result = 2; break; // 7.5 -> 2.5 substep + case 8: result = 4; break; // 8.5 -> 1.7 substep + case 9: result = 4; break; // 9.5 -> 1.9 substep + } + } + // if mantissa fraction isn't 0.0 or 0.5, don't bother finding good sub tick marks, leave default + } + + return result; +} + +/*! \internal + + This method returns the tick label string as it should be printed under the \a tick coordinate. + If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a + precision. + + If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is + enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will + be formatted accordingly using multiplication symbol and superscript during rendering of the + label automatically. +*/ +QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + return locale.toString(tick, formatChar.toLatin1(), precision); +} + +/*! \internal + + Returns a vector containing all coordinates of sub ticks that should be drawn. It generates \a + subTickCount sub ticks between each tick pair given in \a ticks. + + If a QCPAxisTicker subclass needs maximal control over the generated sub ticks, it should + reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to + base its result on \a subTickCount or \a ticks. +*/ +QVector QCPAxisTicker::createSubTickVector(int subTickCount, const QVector &ticks) +{ + QVector result; + if (subTickCount <= 0 || ticks.size() < 2) + return result; + + result.reserve((ticks.size()-1)*subTickCount); + for (int i=1; i QCPAxisTicker::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result; + // Generate tick positions according to tickStep: + qint64 firstStep = floor((range.lower-mTickOrigin)/tickStep); // do not use qFloor here, or we'll lose 64 bit precision + qint64 lastStep = ceil((range.upper-mTickOrigin)/tickStep); // do not use qCeil here, or we'll lose 64 bit precision + int tickcount = lastStep-firstStep+1; + if (tickcount < 0) tickcount = 0; + result.resize(tickcount); + for (int i=0; i QCPAxisTicker::createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision) +{ + QVector result; + result.reserve(ticks.size()); + for (int i=0; i &ticks, bool keepOneOutlier) const +{ + bool lowFound = false; + bool highFound = false; + int lowIndex = 0; + int highIndex = -1; + + for (int i=0; i < ticks.size(); ++i) + { + if (ticks.at(i) >= range.lower) + { + lowFound = true; + lowIndex = i; + break; + } + } + for (int i=ticks.size()-1; i >= 0; --i) + { + if (ticks.at(i) <= range.upper) + { + highFound = true; + highIndex = i; + break; + } + } + + if (highFound && lowFound) + { + int trimFront = qMax(0, lowIndex-(keepOneOutlier ? 1 : 0)); + int trimBack = qMax(0, ticks.size()-(keepOneOutlier ? 2 : 1)-highIndex); + if (trimFront > 0 || trimBack > 0) + ticks = ticks.mid(trimFront, ticks.size()-trimFront-trimBack); + } else // all ticks are either all below or all above the range + ticks.clear(); +} + +/*! \internal + + Returns the coordinate contained in \a candidates which is closest to the provided \a target. + + This method assumes \a candidates is not empty and sorted in ascending order. +*/ +double QCPAxisTicker::pickClosest(double target, const QVector &candidates) const +{ + if (candidates.size() == 1) + return candidates.first(); + QVector::const_iterator it = std::lower_bound(candidates.constBegin(), candidates.constEnd(), target); + if (it == candidates.constEnd()) + return *(it-1); + else if (it == candidates.constBegin()) + return *it; + else + return target-*(it-1) < *it-target ? *(it-1) : *it; +} + +/*! \internal + + Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also + returns the magnitude of \a input as a power of 10. + + For example, an input of 142.6 will return a mantissa of 1.426 and a magnitude of 100. +*/ +double QCPAxisTicker::getMantissa(double input, double *magnitude) const +{ + const double mag = qPow(10.0, qFloor(qLn(input)/qLn(10.0))); + if (magnitude) *magnitude = mag; + return input/mag; +} + +/*! \internal + + Returns a number that is close to \a input but has a clean, easier human readable mantissa. How + strongly the mantissa is altered, and thus how strong the result deviates from the original \a + input, depends on the current tick step strategy (see \ref setTickStepStrategy). +*/ +double QCPAxisTicker::cleanMantissa(double input) const +{ + double magnitude; + const double mantissa = getMantissa(input, &magnitude); + switch (mTickStepStrategy) + { + case tssReadability: + { + return pickClosest(mantissa, QVector() << 1.0 << 2.0 << 2.5 << 5.0 << 10.0)*magnitude; + } + case tssMeetTickCount: + { + // this gives effectively a mantissa of 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0 + if (mantissa <= 5.0) + return (int)(mantissa*2)/2.0*magnitude; // round digit after decimal point to 0.5 + else + return (int)(mantissa/2.0)*2.0*magnitude; // round to first digit in multiples of 2 + } + } + return input; +} +/* end of 'src/axis/axisticker.cpp' */ + + +/* including file 'src/axis/axistickerdatetime.cpp', size 14443 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerDateTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerDateTime + \brief Specialized axis ticker for calendar dates and times as axis ticks + + \image html axisticker-datetime.png + + This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The + plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00 + UTC). This is also used for example by QDateTime in the toTime_t()/setTime_t() methods + with a precision of one second. Since Qt 4.7, millisecond accuracy can be obtained from QDateTime + by using QDateTime::fromMSecsSinceEpoch()/1000.0. The static methods \ref dateTimeToKey + and \ref keyToDateTime conveniently perform this conversion achieving a precision of one + millisecond on all Qt versions. + + The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat. + If a different time spec (time zone) shall be used, see \ref setDateTimeSpec. + + This ticker produces unequal tick spacing in order to provide intuitive date and time-of-day + ticks. For example, if the axis range spans a few years such that there is one tick per year, + ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years, + will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in + the image above: even though the number of days varies month by month, this ticker generates + ticks on the same day of each month. + + If you would like to change the date/time that is used as a (mathematical) starting date for the + ticks, use the \ref setTickOrigin(const QDateTime &origin) method overload, which takes a + QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at + 9:45 of every year. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerdatetime-creation + + \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and + milliseconds, and are not interested in the intricacies of real calendar dates with months and + (leap) years, have a look at QCPAxisTickerTime instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerDateTime::QCPAxisTickerDateTime() : + mDateTimeFormat(QLatin1String("hh:mm:ss\ndd.MM.yy")), + mDateTimeSpec(Qt::LocalTime), + mDateStrategy(dsNone) +{ + setTickCount(4); +} + +/*! + Sets the format in which dates and times are displayed as tick labels. For details about the \a + format string, see the documentation of QDateTime::toString(). + + Newlines can be inserted with "\n". + + \see setDateTimeSpec +*/ +void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) +{ + mDateTimeFormat = format; +} + +/*! + Sets the time spec that is used for creating the tick labels from corresponding dates/times. + + The default value of QDateTime objects (and also QCPAxisTickerDateTime) is + Qt::LocalTime. However, if the date time values passed to QCustomPlot (e.g. in the form + of axis ranges or keys of a plottable) are given in the UTC spec, set \a spec to Qt::UTC + to get the correct axis labels. + + \see setDateTimeFormat +*/ +void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) +{ + mDateTimeSpec = spec; +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970, + 00:00 UTC). For the date time ticker it might be more intuitive to use the overload which + directly takes a QDateTime, see \ref setTickOrigin(const QDateTime &origin). + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(double origin) +{ + QCPAxisTicker::setTickOrigin(origin); +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) as a QDateTime \a origin. + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(const QDateTime &origin) +{ + setTickOrigin(dateTimeToKey(origin)); +} + +/*! \internal + + Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + Note that this tick step isn't used exactly when generating the tick vector in \ref + createTickVector, but only as a guiding value requiring some correction for each individual tick + interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day + in the month to the last day in the previous month from tick to tick, due to the non-uniform + length of months. The same problem arises with leap years. + + \seebaseclassmethod +*/ +double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + mDateStrategy = dsNone; + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + result = cleanMantissa(result); + } else if (result < 86400*30437.5*12) // below a year + { +// result = pickClosest(result, QVector() +// << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5*60 << 5*60 << 10*60 << 15*60 << 30*60 << 60*60 // second, minute, hour range +// << 3600*2 << 3600*3 << 3600*6 << 3600*12 << 3600*24 // hour to day range +// << 86400*2 << 86400*5 << 86400*7 << 86400*14 << 86400*30.4375 << 86400*30.4375*2 << 86400*30.4375*3 << 86400*30.4375*6 << 86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) + result = pickClosest(result, QVector() + << 1000 << 1000*2.5 << 1000*5 << 1000*10 << 1000*15 << 1000*30 << 1000*60 << 1000*2.5*60 << 1000*5*60 << 1000*10*60 << 1000*15*60 << 1000*30*60 << 1000*60*60 // second, minute, hour range + << 1000*3600*2 << 1000*3600*3 << 1000*3600*6 << 1000*3600*12 << 1000*3600*24 // hour to day range + << 1000*86400*2 << 1000*86400*5 << 1000*86400*7 << 1000*86400*14 << 1000*86400*30.4375 << 1000*86400*30.4375*2 << 1000*86400*30.4375*3 << 1000*86400*30.4375*6 << 1000*86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) + if (result > 86400*30437.5-1) // month tick intervals or larger + mDateStrategy = dsUniformDayInMonth; + else if (result > 3600*24*1000-1) // day tick intervals or larger + mDateStrategy = dsUniformTimeInDay; + } else // more than a year, go back to normal clean mantissa algorithm but in units of years + { + const double secondsPerYear = 86400*30437.5*12; // average including leap years + result = cleanMantissa(result/secondsPerYear)*secondsPerYear; + mDateStrategy = dsUniformDayInMonth; + } + return result; +} + +/*! \internal + + Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + \seebaseclassmethod +*/ +int QCPAxisTickerDateTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound64(tickStep)) // hand chosen subticks for specific minute/hour/day/week/month range (as specified in getTickStep) + { + case 5*1000*60: result = 4; break; + case 10*1000*60: result = 1; break; + case 15*1000*60: result = 2; break; + case 30*1000*60: result = 1; break; + case 60*1000*60: result = 3; break; + case 3600*1000*2: result = 3; break; + case 3600*1000*3: result = 2; break; + case 3600*1000*6: result = 1; break; + case 3600*1000*12: result = 3; break; + case 3600*1000*24: result = 3; break; + case 86400*1000*2: result = 1; break; + case 86400*1000*5: result = 4; break; + case 86400*1000*7: result = 6; break; + case 86400*1000*14: result = 1; break; + case (qint64)(86400*1000*30.4375+0.5): result = 3; break; + case (qint64)(86400*1000*30.4375*2+0.5): result = 1; break; + case (qint64)(86400*1000*30.4375*3+0.5): result = 2; break; + case (qint64)(86400*1000*30.4375*6+0.5): result = 5; break; + case (qint64)(86400*1000*30.4375*12+0.5): result = 3; break; + } + return result; +} + +/*! \internal + + Generates a date/time tick label for tick coordinate \a tick, based on the currently set format + (\ref setDateTimeFormat) and time spec (\ref setDateTimeSpec). + + \seebaseclassmethod +*/ +QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +} + +/*! \internal + + Uses the passed \a tickStep as a guiding value and applies corrections in order to obtain + non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month. + + \seebaseclassmethod +*/ +QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result = QCPAxisTicker::createTickVector(tickStep, range); + if (!result.isEmpty()) + { + if (mDateStrategy == dsUniformTimeInDay) + { + QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible + QDateTime tickDateTime; + for (int i=0; i 15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day + tickDateTime = tickDateTime.addMonths(-1); + tickDateTime.setDate(QDate(tickDateTime.date().year(), tickDateTime.date().month(), thisUniformDay)); + result[i] = dateTimeToKey(tickDateTime); + } + } + } + return result; +} + +/*! + A convenience method which turns \a key (in seconds since Epoch 1. Jan 1970, 00:00 UTC) into a + QDateTime object. This can be used to turn axis coordinates to actual QDateTimes. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::fromMSecsSinceEpoch in Qt 4.6) + + \see dateTimeToKey +*/ +QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) +{ + return QDateTime::fromMSecsSinceEpoch(key); +} + +/*! \overload + + A convenience method which turns a QDateTime object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::toMSecsSinceEpoch in Qt 4.6) + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime dateTime) +{ + return dateTime.toMSecsSinceEpoch(); +} + +/*! \overload + + A convenience method which turns a QDate object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDate date) +{ + return QDateTime(date).toMSecsSinceEpoch(); +} +/* end of 'src/axis/axistickerdatetime.cpp' */ + + +/* including file 'src/axis/axistickertime.cpp', size 11747 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerTime + \brief Specialized axis ticker for time spans in units of milliseconds to days + + \image html axisticker-time.png + + This QCPAxisTicker subclass generates ticks that corresponds to time intervals. + + The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref + setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate + zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date + and time. + + The time can be displayed in milliseconds, seconds, minutes, hours and days. Depending on the + largest available unit in the format specified with \ref setTimeFormat, any time spans above will + be carried in that largest unit. So for example if the format string is "%m:%s" and a tick at + coordinate value 7815 (being 2 hours, 10 minutes and 15 seconds) is created, the resulting tick + label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour + unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis + zero will carry a leading minus sign. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation + + Here is an example of a time axis providing time information in days, hours and minutes. Due to + the axis range spanning a few days and the wanted tick count (\ref setTickCount), the ticker + decided to use tick steps of 12 hours: + + \image html axisticker-time2.png + + The format string for this example is + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation-2 + + \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime + instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerTime::QCPAxisTickerTime() : + mTimeFormat(QLatin1String("%h:%m:%s")), + mSmallestUnit(tuSeconds), + mBiggestUnit(tuHours) +{ + setTickCount(4); + mFieldWidth[tuMilliseconds] = 3; + mFieldWidth[tuSeconds] = 2; + mFieldWidth[tuMinutes] = 2; + mFieldWidth[tuHours] = 2; + mFieldWidth[tuDays] = 1; + + mFormatPattern[tuMilliseconds] = QLatin1String("%z"); + mFormatPattern[tuSeconds] = QLatin1String("%s"); + mFormatPattern[tuMinutes] = QLatin1String("%m"); + mFormatPattern[tuHours] = QLatin1String("%h"); + mFormatPattern[tuDays] = QLatin1String("%d"); +} + +/*! + Sets the format that will be used to display time in the tick labels. + + The available patterns are: + - %%z for milliseconds + - %%s for seconds + - %%m for minutes + - %%h for hours + - %%d for days + + The field width (zero padding) can be controlled for each unit with \ref setFieldWidth. + + The largest unit that appears in \a format will carry all the remaining time of a certain tick + coordinate, even if it overflows the natural limit of the unit. For example, if %%m is the + largest unit it might become larger than 59 in order to consume larger time values. If on the + other hand %%h is available, the minutes will wrap around to zero after 59 and the time will + carry to the hour digit. +*/ +void QCPAxisTickerTime::setTimeFormat(const QString &format) +{ + mTimeFormat = format; + + // determine smallest and biggest unit in format, to optimize unit replacement and allow biggest + // unit to consume remaining time of a tick value and grow beyond its modulo (e.g. min > 59) + mSmallestUnit = tuMilliseconds; + mBiggestUnit = tuMilliseconds; + bool hasSmallest = false; + for (int i = tuMilliseconds; i <= tuDays; ++i) + { + TimeUnit unit = static_cast(i); + if (mTimeFormat.contains(mFormatPattern.value(unit))) + { + if (!hasSmallest) + { + mSmallestUnit = unit; + hasSmallest = true; + } + mBiggestUnit = unit; + } + } +} + +/*! + Sets the field widh of the specified \a unit to be \a width digits, when displayed in the tick + label. If the number for the specific unit is shorter than \a width, it will be padded with an + according number of zeros to the left in order to reach the field width. + + \see setTimeFormat +*/ +void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int width) +{ + mFieldWidth[unit] = qMax(width, 1); +} + +/*! \internal + + Returns the tick step appropriate for time displays, depending on the provided \a range and the + smallest available time unit in the current format (\ref setTimeFormat). For example if the unit + of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes) + that require sub-minute precision to be displayed correctly. + + \seebaseclassmethod +*/ +double QCPAxisTickerTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + if (mSmallestUnit == tuMilliseconds) + result = qMax(cleanMantissa(result), 0.001); // smallest tick step is 1 millisecond + else // have no milliseconds available in format, so stick with 1 second tickstep + result = 1.0; + } else if (result < 3600*24) // below a day + { + // the filling of availableSteps seems a bit contorted but it fills in a sorted fashion and thus saves a post-fill sorting run + QVector availableSteps; + // seconds range: + if (mSmallestUnit <= tuSeconds) + availableSteps << 1; + if (mSmallestUnit == tuMilliseconds) + availableSteps << 2.5; // only allow half second steps if milliseconds are there to display it + else if (mSmallestUnit == tuSeconds) + availableSteps << 2; + if (mSmallestUnit <= tuSeconds) + availableSteps << 5 << 10 << 15 << 30; + // minutes range: + if (mSmallestUnit <= tuMinutes) + availableSteps << 1*60; + if (mSmallestUnit <= tuSeconds) + availableSteps << 2.5*60; // only allow half minute steps if seconds are there to display it + else if (mSmallestUnit == tuMinutes) + availableSteps << 2*60; + if (mSmallestUnit <= tuMinutes) + availableSteps << 5*60 << 10*60 << 15*60 << 30*60; + // hours range: + if (mSmallestUnit <= tuHours) + availableSteps << 1*3600 << 2*3600 << 3*3600 << 6*3600 << 12*3600 << 24*3600; + // pick available step that is most appropriate to approximate ideal step: + result = pickClosest(result, availableSteps); + } else // more than a day, go back to normal clean mantissa algorithm but in units of days + { + const double secondsPerDay = 3600*24; + result = cleanMantissa(result/secondsPerDay)*secondsPerDay; + } + return result; +} + +/*! \internal + + Returns the sub tick count appropriate for the provided \a tickStep and time displays. + + \seebaseclassmethod +*/ +int QCPAxisTickerTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day range (as specified in getTickStep) + { + case 5*60: result = 4; break; + case 10*60: result = 1; break; + case 15*60: result = 2; break; + case 30*60: result = 1; break; + case 60*60: result = 3; break; + case 3600*2: result = 3; break; + case 3600*3: result = 2; break; + case 3600*6: result = 1; break; + case 3600*12: result = 3; break; + case 3600*24: result = 3; break; + } + return result; +} + +/*! \internal + + Returns the tick label corresponding to the provided \a tick and the configured format and field + widths (\ref setTimeFormat, \ref setFieldWidth). + + \seebaseclassmethod +*/ +QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + Q_UNUSED(locale) + bool negative = tick < 0; + if (negative) tick *= -1; + double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59) + double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time + + restValues[tuMilliseconds] = tick*1000; + values[tuMilliseconds] = modf(restValues[tuMilliseconds]/1000, &restValues[tuSeconds])*1000; + values[tuSeconds] = modf(restValues[tuSeconds]/60, &restValues[tuMinutes])*60; + values[tuMinutes] = modf(restValues[tuMinutes]/60, &restValues[tuHours])*60; + values[tuHours] = modf(restValues[tuHours]/24, &restValues[tuDays])*24; + // no need to set values[tuDays] because days are always a rest value (there is no higher unit so it consumes all remaining time) + + QString result = mTimeFormat; + for (int i = mSmallestUnit; i <= mBiggestUnit; ++i) + { + TimeUnit iUnit = static_cast(i); + replaceUnit(result, iUnit, qRound(iUnit == mBiggestUnit ? restValues[iUnit] : values[iUnit])); + } + if (negative) + result.prepend(QLatin1Char('-')); + return result; +} + +/*! \internal + + Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified + \a value, using the field width as specified with \ref setFieldWidth for the \a unit. +*/ +void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit unit, int value) const +{ + QString valueStr = QString::number(value); + while (valueStr.size() < mFieldWidth.value(unit)) + valueStr.prepend(QLatin1Char('0')); + + text.replace(mFormatPattern.value(unit), valueStr); +} +/* end of 'src/axis/axistickertime.cpp' */ + + +/* including file 'src/axis/axistickerfixed.cpp', size 5583 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerFixed +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerFixed + \brief Specialized axis ticker with a fixed tick step + + \image html axisticker-fixed.png + + This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It + is also possible to allow integer multiples and integer powers of the specified tick step with + \ref setScaleStrategy. + + A typical application of this ticker is to make an axis only display integers, by setting the + tick step of the ticker to 1.0 and the scale strategy to \ref ssMultiples. + + Another case is when a certain number has a special meaning and axis ticks should only appear at + multiples of that value. In this case you might also want to consider \ref QCPAxisTickerPi + because despite the name it is not limited to only pi symbols/values. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerfixed-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerFixed::QCPAxisTickerFixed() : + mTickStep(1.0), + mScaleStrategy(ssNone) +{ +} + +/*! + Sets the fixed tick interval to \a step. + + The axis ticker will only use this tick step when generating axis ticks. This might cause a very + high tick density and overlapping labels if the axis range is zoomed out. Using \ref + setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a + step. This will enable the ticker to reduce the number of ticks to a reasonable amount (see \ref + setTickCount). +*/ +void QCPAxisTickerFixed::setTickStep(double step) +{ + if (step > 0) + mTickStep = step; + else + qDebug() << Q_FUNC_INFO << "tick step must be greater than zero:" << step; +} + +/*! + Sets whether the specified tick step (\ref setTickStep) is absolutely fixed or whether + modifications may be applied to it before calculating the finally used tick step, such as + permitting multiples or powers. See \ref ScaleStrategy for details. + + The default strategy is \ref ssNone, which means the tick step is absolutely fixed. +*/ +void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy strategy) +{ + mScaleStrategy = strategy; +} + +/*! \internal + + Determines the actually used tick step from the specified tick step and scale strategy (\ref + setTickStep, \ref setScaleStrategy). + + This method either returns the specified tick step exactly, or, if the scale strategy is not \ref + ssNone, a modification of it to allow varying the number of ticks in the current axis range. + + \seebaseclassmethod +*/ +double QCPAxisTickerFixed::getTickStep(const QCPRange &range) +{ + switch (mScaleStrategy) + { + case ssNone: + { + return mTickStep; + } + case ssMultiples: + { + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + if (exactStep < mTickStep) + return mTickStep; + else + return (qint64)(cleanMantissa(exactStep/mTickStep)+0.5)*mTickStep; + } + case ssPowers: + { + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return qPow(mTickStep, (int)(qLn(exactStep)/qLn(mTickStep)+0.5)); + } + } + return mTickStep; +} +/* end of 'src/axis/axistickerfixed.cpp' */ + + +/* including file 'src/axis/axistickertext.cpp', size 8653 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerText +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerText + \brief Specialized axis ticker which allows arbitrary labels at specified coordinates + + \image html axisticker-text.png + + This QCPAxisTicker subclass generates ticks which can be directly specified by the user as + coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a + time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks + and modify the tick/label data there. + + This is useful for cases where the axis represents categories rather than numerical values. + + If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on + the axis range), it is a sign that you should probably create an own ticker by subclassing + QCPAxisTicker, instead of using this one. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertext-creation +*/ + +/* start of documentation of inline functions */ + +/*! \fn QMap &QCPAxisTickerText::ticks() + + Returns a non-const reference to the internal map which stores the tick coordinates and their + labels. + + You can access the map directly in order to add, remove or manipulate ticks, as an alternative to + using the methods provided by QCPAxisTickerText, such as \ref setTicks and \ref addTick. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerText::QCPAxisTickerText() : + mSubTickCount(0) +{ +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The map key of \a ticks corresponds to the axis + coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QMap &ticks) +{ + mTicks = ticks; +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis + coordinates, and the entries of \a labels are the respective strings that will appear as tick + labels. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QVector &positions, const QVector labels) +{ + clear(); + addTicks(positions, labels); +} + +/*! + Sets the number of sub ticks that shall appear between ticks. For QCPAxisTickerText, there is no + automatic sub tick count calculation. So if sub ticks are needed, they must be configured with this + method. +*/ +void QCPAxisTickerText::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! + Clears all ticks. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see setTicks, addTicks, addTick +*/ +void QCPAxisTickerText::clear() +{ + mTicks.clear(); +} + +/*! + Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a + label. + + \see addTicks, setTicks, clear +*/ +void QCPAxisTickerText::addTick(double position, QString label) +{ + mTicks.insert(position, label); +} + +/*! \overload + + Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to + the axis coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QMap &ticks) +{ + mTicks.unite(ticks); +} + +/*! \overload + + Adds the provided ticks to the ones already existing. The entries of \a positions correspond to + the axis coordinates, and the entries of \a labels are the respective strings that will appear as + tick labels. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QVector &positions, const QVector &labels) +{ + if (positions.size() != labels.size()) + qDebug() << Q_FUNC_INFO << "passed unequal length vectors for positions and labels:" << positions.size() << labels.size(); + int n = qMin(positions.size(), labels.size()); + for (int i=0; i QCPAxisTickerText::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (mTicks.isEmpty()) + return result; + + QMap::const_iterator start = mTicks.lowerBound(range.lower); + QMap::const_iterator end = mTicks.upperBound(range.upper); + // this method should try to give one tick outside of range so proper subticks can be generated: + if (start != mTicks.constBegin()) --start; + if (end != mTicks.constEnd()) ++end; + for (QMap::const_iterator it = start; it != end; ++it) + result.append(it.key()); + + return result; +} +/* end of 'src/axis/axistickertext.cpp' */ + + +/* including file 'src/axis/axistickerpi.cpp', size 11170 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerPi +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerPi + \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi + + \image html axisticker-pi.png + + This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic + constant with a numerical value specified with \ref setPiValue and an appearance in the tick + labels specified with \ref setPiSymbol. + + Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the + tick label can be configured with \ref setFractionStyle. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerpi-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerPi::QCPAxisTickerPi() : + mPiSymbol(QLatin1String(" ")+QChar(0x03C0)), + mPiValue(M_PI), + mPeriodicity(0), + mFractionStyle(fsUnicodeFractions), + mPiTickStep(0) +{ + setTickCount(4); +} + +/*! + Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick + label. + + If a space shall appear between the number and the symbol, make sure the space is contained in \a + symbol. +*/ +void QCPAxisTickerPi::setPiSymbol(QString symbol) +{ + mPiSymbol = symbol; +} + +/*! + Sets the numerical value that the symbolic constant has. + + This will be used to place the appropriate fractions of the symbol at the respective axis + coordinates. +*/ +void QCPAxisTickerPi::setPiValue(double pi) +{ + mPiValue = pi; +} + +/*! + Sets whether the axis labels shall appear periodicly and if so, at which multiplicity of the + symbolic constant. + + To disable periodicity, set \a multiplesOfPi to zero. + + For example, an axis that identifies 0 with 2pi would set \a multiplesOfPi to two. +*/ +void QCPAxisTickerPi::setPeriodicity(int multiplesOfPi) +{ + mPeriodicity = qAbs(multiplesOfPi); +} + +/*! + Sets how the numerical/fractional part preceding the symbolic constant is displayed in tick + labels. See \ref FractionStyle for the various options. +*/ +void QCPAxisTickerPi::setFractionStyle(QCPAxisTickerPi::FractionStyle style) +{ + mFractionStyle = style; +} + +/*! \internal + + Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence + the numerical/fractional part preceding the symbolic constant is made to have a readable + mantissa. + + \seebaseclassmethod +*/ +double QCPAxisTickerPi::getTickStep(const QCPRange &range) +{ + mPiTickStep = range.size()/mPiValue/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + mPiTickStep = cleanMantissa(mPiTickStep); + return mPiTickStep*mPiValue; +} + +/*! \internal + + Returns the sub tick count, using the constant's value (\ref setPiValue) as base unit. In + consequence the sub ticks divide the numerical/fractional part preceding the symbolic constant + reasonably, and not the total tick coordinate. + + \seebaseclassmethod +*/ +int QCPAxisTickerPi::getSubTickCount(double tickStep) +{ + return QCPAxisTicker::getSubTickCount(tickStep/mPiValue); +} + +/*! \internal + + Returns the tick label as a fractional/numerical part and a symbolic string as suffix. The + formatting of the fraction is done according to the specified \ref setFractionStyle. The appended + symbol is specified with \ref setPiSymbol. + + \seebaseclassmethod +*/ +QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + double tickInPis = tick/mPiValue; + if (mPeriodicity > 0) + tickInPis = fmod(tickInPis, mPeriodicity); + + if (mFractionStyle != fsFloatingPoint && mPiTickStep > 0.09 && mPiTickStep < 50) + { + // simply construct fraction from decimal like 1.234 -> 1234/1000 and then simplify fraction, smaller digits are irrelevant due to mPiTickStep conditional above + int denominator = 1000; + int numerator = qRound(tickInPis*denominator); + simplifyFraction(numerator, denominator); + if (qAbs(numerator) == 1 && denominator == 1) + return (numerator < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else if (numerator == 0) + return QLatin1String("0"); + else + return fractionToString(numerator, denominator) + mPiSymbol; + } else + { + if (qFuzzyIsNull(tickInPis)) + return QLatin1String("0"); + else if (qFuzzyCompare(qAbs(tickInPis), 1.0)) + return (tickInPis < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else + return QCPAxisTicker::getTickLabel(tickInPis, locale, formatChar, precision) + mPiSymbol; + } +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure + the fraction is in irreducible form, i.e. numerator and denominator don't share any common + factors which could be cancelled. +*/ +void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const +{ + if (numerator == 0 || denominator == 0) + return; + + int num = numerator; + int denom = denominator; + while (denom != 0) // euclidean gcd algorithm + { + int oldDenom = denom; + denom = num % denom; + num = oldDenom; + } + // num is now gcd of numerator and denominator + numerator /= num; + denominator /= num; +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and returns a string representation. + The result depends on the configured fraction style (\ref setFractionStyle). + + This method is used to format the numerical/fractional part when generating tick labels. It + simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out + any integer parts of the fraction (e.g. "10/4" becomes "2 1/2"). +*/ +QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const +{ + if (denominator == 0) + { + qDebug() << Q_FUNC_INFO << "called with zero denominator"; + return QString(); + } + if (mFractionStyle == fsFloatingPoint) // should never be the case when calling this function + { + qDebug() << Q_FUNC_INFO << "shouldn't be called with fraction style fsDecimal"; + return QString::number(numerator/(double)denominator); // failsafe + } + int sign = numerator*denominator < 0 ? -1 : 1; + numerator = qAbs(numerator); + denominator = qAbs(denominator); + + if (denominator == 1) + { + return QString::number(sign*numerator); + } else + { + int integerPart = numerator/denominator; + int remainder = numerator%denominator; + if (remainder == 0) + { + return QString::number(sign*integerPart); + } else + { + if (mFractionStyle == fsAsciiFractions) + { + return QString(QLatin1String("%1%2%3/%4")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart)+QLatin1String(" ") : QLatin1String("")) + .arg(remainder) + .arg(denominator); + } else if (mFractionStyle == fsUnicodeFractions) + { + return QString(QLatin1String("%1%2%3")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart) : QLatin1String("")) + .arg(unicodeFraction(remainder, denominator)); + } + } + } + return QString(); +} + +/*! \internal + + Returns the unicode string representation of the fraction given by \a numerator and \a + denominator. This is the representation used in \ref fractionToString when the fraction style + (\ref setFractionStyle) is \ref fsUnicodeFractions. + + This method doesn't use the single-character common fractions but builds each fraction from a + superscript unicode number, the unicode fraction character, and a subscript unicode number. +*/ +QString QCPAxisTickerPi::unicodeFraction(int numerator, int denominator) const +{ + return unicodeSuperscript(numerator)+QChar(0x2044)+unicodeSubscript(denominator); +} + +/*! \internal + + Returns the unicode string representing \a number as superscript. This is used to build + unicode fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSuperscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2070)); + + QString result; + while (number > 0) + { + const int digit = number%10; + switch (digit) + { + case 1: { result.prepend(QChar(0x00B9)); break; } + case 2: { result.prepend(QChar(0x00B2)); break; } + case 3: { result.prepend(QChar(0x00B3)); break; } + default: { result.prepend(QChar(0x2070+digit)); break; } + } + number /= 10; + } + return result; +} + +/*! \internal + + Returns the unicode string representing \a number as subscript. This is used to build unicode + fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSubscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2080)); + + QString result; + while (number > 0) + { + result.prepend(QChar(0x2080+number%10)); + number /= 10; + } + return result; +} +/* end of 'src/axis/axistickerpi.cpp' */ + + +/* including file 'src/axis/axistickerlog.cpp', size 7106 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerLog +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerLog + \brief Specialized axis ticker suited for logarithmic axes + + \image html axisticker-log.png + + This QCPAxisTicker subclass generates ticks with unequal tick intervals suited for logarithmic + axis scales. The ticks are placed at powers of the specified log base (\ref setLogBase). + + Especially in the case of a log base equal to 10 (the default), it might be desirable to have + tick labels in the form of powers of ten without mantissa display. To achieve this, set the + number precision (\ref QCPAxis::setNumberPrecision) to zero and the number format (\ref + QCPAxis::setNumberFormat) to scientific (exponential) display with beautifully typeset decimal + powers, so a format string of "eb". This will result in the following axis tick labels: + + \image html axisticker-log-powers.png + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerlog-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerLog::QCPAxisTickerLog() : + mLogBase(10.0), + mSubTickCount(8), // generates 10 intervals + mLogBaseLnInv(1.0/qLn(mLogBase)) +{ +} + +/*! + Sets the logarithm base used for tick coordinate generation. The ticks will be placed at integer + powers of \a base. +*/ +void QCPAxisTickerLog::setLogBase(double base) +{ + if (base > 0) + { + mLogBase = base; + mLogBaseLnInv = 1.0/qLn(mLogBase); + } else + qDebug() << Q_FUNC_INFO << "log base has to be greater than zero:" << base; +} + +/*! + Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced + linearly to provide a better visual guide, so the sub tick density increases toward the higher + tick. + + Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in + the case of logarithm base 10 an intuitive sub tick spacing would be achieved with eight sub + ticks (the default). This means e.g. between the ticks 10 and 100 there will be eight ticks, + namely at 20, 30, 40, 50, 60, 70, 80 and 90. +*/ +void QCPAxisTickerLog::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! \internal + + Since logarithmic tick steps are necessarily different for each tick interval, this method does + nothing in the case of QCPAxisTickerLog + + \seebaseclassmethod +*/ +double QCPAxisTickerLog::getTickStep(const QCPRange &range) +{ + // Logarithmic axis ticker has unequal tick spacing, so doesn't need this method + Q_UNUSED(range) + return 1.0; +} + +/*! \internal + + Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no + automatic sub tick count calculation necessary. + + \seebaseclassmethod +*/ +int QCPAxisTickerLog::getSubTickCount(double tickStep) +{ + Q_UNUSED(tickStep) + return mSubTickCount; +} + +/*! \internal + + Creates ticks with a spacing given by the logarithm base and an increasing integer power in the + provided \a range. The step in which the power increases tick by tick is chosen in order to keep + the total number of ticks as close as possible to the tick count (\ref setTickCount). The + parameter \a tickStep is ignored for QCPAxisTickerLog + + \seebaseclassmethod +*/ +QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (range.lower > 0 && range.upper > 0) // positive range + { + double exactPowerStep = qLn(range.upper/range.lower)*mLogBaseLnInv/(double)(mTickCount+1e-10); + double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); + double currentTick = qPow(newLogBase, qFloor(qLn(range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick *= newLogBase; + result.append(currentTick); + } + } else if (range.lower < 0 && range.upper < 0) // negative range + { + double exactPowerStep = qLn(range.lower/range.upper)*mLogBaseLnInv/(double)(mTickCount+1e-10); + double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); + double currentTick = -qPow(newLogBase, qCeil(qLn(-range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick /= newLogBase; + result.append(currentTick); + } + } else // invalid range for logarithmic scale, because lower and upper have different sign + { + qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << range.lower << ".." << range.upper; + } + + return result; +} +/* end of 'src/axis/axistickerlog.cpp' */ + + +/* including file 'src/axis/axis.cpp', size 99397 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGrid + \brief Responsible for drawing the grid of a QCPAxis. + + This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the + grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref + QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. + + The axis and grid drawing was split into two classes to allow them to be placed on different + layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid + in the background and the axes in the foreground, and any plottables/items in between. This + described situation is the default setup, see the QCPLayer documentation. +*/ + +/*! + Creates a QCPGrid instance and sets default values. + + You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. +*/ +QCPGrid::QCPGrid(QCPAxis *parentAxis) : + QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), + mParentAxis(parentAxis) +{ + // warning: this is called in QCPAxis constructor, so parentAxis members should not be accessed/called + setParent(parentAxis); + setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); + setSubGridVisible(false); + setAntialiased(false); + setAntialiasedSubGrid(false); + setAntialiasedZeroLine(false); +} + +/*! + Sets whether grid lines at sub tick marks are drawn. + + \see setSubGridPen +*/ +void QCPGrid::setSubGridVisible(bool visible) +{ + mSubGridVisible = visible; +} + +/*! + Sets whether sub grid lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedSubGrid(bool enabled) +{ + mAntialiasedSubGrid = enabled; +} + +/*! + Sets whether zero lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedZeroLine(bool enabled) +{ + mAntialiasedZeroLine = enabled; +} + +/*! + Sets the pen with which (major) grid lines are drawn. +*/ +void QCPGrid::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen with which sub grid lines are drawn. +*/ +void QCPGrid::setSubGridPen(const QPen &pen) +{ + mSubGridPen = pen; +} + +/*! + Sets the pen with which zero lines are drawn. + + Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid + lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. +*/ +void QCPGrid::setZeroLinePen(const QPen &pen) +{ + mZeroLinePen = pen; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing the major grid lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); +} + +/*! \internal + + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning + over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). +*/ +void QCPGrid::draw(QCPPainter *painter) +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + if (mParentAxis->subTicks() && mSubGridVisible) + drawSubGridLines(painter); + drawGridLines(painter); +} + +/*! \internal + + Draws the main grid lines and possibly a zero line with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + const int tickCount = mParentAxis->mTickVector.size(); + double t; // helper variable, result of coordinate-to-pixel transforms + if (mParentAxis->orientation() == Qt::Horizontal) + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + +/*! \internal + + Draws the sub grid lines with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawSubGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); + double t; // helper variable, result of coordinate-to-pixel transforms + painter->setPen(mSubGridPen); + if (mParentAxis->orientation() == Qt::Horizontal) + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxis +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxis + \brief Manages a single axis inside a QCustomPlot. + + Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via + QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and + QCustomPlot::yAxis2 (right). + + Axes are always part of an axis rect, see QCPAxisRect. + \image html AxisNamesOverview.png +
Naming convention of axis parts
+ \n + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line + on the left represents the QCustomPlot widget border.
+ + Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and + tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of + the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the + documentation of QCPAxisTicker. +*/ + +/* start of documentation of inline functions */ + +/*! \fn Qt::Orientation QCPAxis::orientation() const + + Returns the orientation of this axis. The axis orientation (horizontal or vertical) is deduced + from the axis type (left, top, right or bottom). + + \see orientation(AxisType type), pixelOrientation +*/ + +/*! \fn QCPGrid *QCPAxis::grid() const + + Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the + grid is displayed. +*/ + +/*! \fn static Qt::Orientation QCPAxis::orientation(AxisType type) + + Returns the orientation of the specified axis type + + \see orientation(), pixelOrientation +*/ + +/*! \fn int QCPAxis::pixelOrientation() const + + Returns which direction points towards higher coordinate values/keys, in pixel space. + + This method returns either 1 or -1. If it returns 1, then going in the positive direction along + the orientation of the axis in pixels corresponds to going from lower to higher axis coordinates. + On the other hand, if this method returns -1, going to smaller pixel values corresponds to going + from lower to higher axis coordinates. + + For example, this is useful to easily shift axis coordinates by a certain amount given in pixels, + without having to care about reversed or vertically aligned axes: + + \code + double newKey = keyAxis->pixelToCoord(keyAxis->coordToPixel(oldKey)+10*keyAxis->pixelOrientation()); + \endcode + + \a newKey will then contain a key that is ten pixels towards higher keys, starting from \a oldKey. +*/ + +/*! \fn QSharedPointer QCPAxis::ticker() const + + Returns a modifiable shared pointer to the currently installed axis ticker. The axis ticker is + responsible for generating the tick positions and tick labels of this axis. You can access the + \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count + (\ref QCPAxisTicker::setTickCount). + + You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see + the documentation there. A new axis ticker can be set with \ref setTicker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see setTicker +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) + + This signal is emitted when the range of this axis has changed. You can connect it to the \ref + setRange slot of another axis to communicate the new range to the other axis, in order for it to + be synchronized. + + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. + This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper + range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following + slot would limit the x axis to ranges between 0 and 10: + \code + customPlot->xAxis->setRange(newRange.bounded(0, 10)) + \endcode +*/ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) + \overload + + Additionally to the new range, this signal also provides the previous range held by the axis as + \a oldRange. +*/ + +/*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the scale type changes, by calls to \ref setScaleType +*/ + +/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) + + This signal is emitted when the selection state of this axis has changed, either by user interaction + or by a direct call to \ref setSelectedParts. +*/ + +/*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); + + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs an Axis instance of Type \a type for the axis rect \a parent. + + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create + them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, + create them manually and then inject them also via \ref QCPAxisRect::addAxis. +*/ +QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : + QCPLayerable(parent->parentPlot(), QString(), parent), + // axis base: + mAxisType(type), + mAxisRect(parent), + mPadding(5), + mOrientation(orientation(type)), + mSelectableParts(spAxis | spTickLabels | spAxisLabel), + mSelectedParts(spNone), + mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedBasePen(QPen(Qt::blue, 2)), + // axis label: + mLabel(), + mLabelFont(mParentPlot->font()), + mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), + mLabelColor(Qt::black), + mSelectedLabelColor(Qt::blue), + // tick labels: + mTickLabels(true), + mTickLabelFont(mParentPlot->font()), + mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), + mTickLabelColor(Qt::black), + mSelectedTickLabelColor(Qt::blue), + mNumberPrecision(6), + mNumberFormatChar('g'), + mNumberBeautifulPowers(true), + // ticks and subticks: + mTicks(true), + mSubTicks(true), + mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedTickPen(QPen(Qt::blue, 2)), + mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedSubTickPen(QPen(Qt::blue, 2)), + // scale and range: + mRange(0, 5), + mRangeReversed(false), + mScaleType(stLinear), + // internal members: + mGrid(new QCPGrid(this)), + mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())), + mTicker(new QCPAxisTicker), + mCachedMarginValid(false), + mCachedMargin(0) +{ + setParent(parent); + mGrid->setVisible(false); + setAntialiased(false); + setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again + + if (type == atTop) + { + setTickLabelPadding(3); + setLabelPadding(6); + } else if (type == atRight) + { + setTickLabelPadding(7); + setLabelPadding(12); + } else if (type == atBottom) + { + setTickLabelPadding(3); + setLabelPadding(3); + } else if (type == atLeft) + { + setTickLabelPadding(5); + setLabelPadding(10); + } +} + +QCPAxis::~QCPAxis() +{ + delete mAxisPainter; + delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLabelPadding() const +{ + return mAxisPainter->tickLabelPadding; +} + +/* No documentation as it is a property getter */ +double QCPAxis::tickLabelRotation() const +{ + return mAxisPainter->tickLabelRotation; +} + +/* No documentation as it is a property getter */ +QCPAxis::LabelSide QCPAxis::tickLabelSide() const +{ + return mAxisPainter->tickLabelSide; +} + +/* No documentation as it is a property getter */ +QString QCPAxis::numberFormat() const +{ + QString result; + result.append(mNumberFormatChar); + if (mNumberBeautifulPowers) + { + result.append(QLatin1Char('b')); + if (mAxisPainter->numberMultiplyCross) + result.append(QLatin1Char('c')); + } + return result; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthIn() const +{ + return mAxisPainter->tickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthOut() const +{ + return mAxisPainter->tickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthIn() const +{ + return mAxisPainter->subTickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthOut() const +{ + return mAxisPainter->subTickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::labelPadding() const +{ + return mAxisPainter->labelPadding; +} + +/* No documentation as it is a property getter */ +int QCPAxis::offset() const +{ + return mAxisPainter->offset; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::lowerEnding() const +{ + return mAxisPainter->lowerEnding; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::upperEnding() const +{ + return mAxisPainter->upperEnding; +} + +/*! + Sets whether the axis uses a linear scale or a logarithmic scale. + + Note that this method controls the coordinate transformation. You will likely also want to use a + logarithmic tick spacing and labeling, which can be achieved by setting an instance of \ref + QCPAxisTickerLog via \ref setTicker. See the documentation of \ref QCPAxisTickerLog about the + details of logarithmic axis tick creation. + + \ref setNumberPrecision +*/ +void QCPAxis::setScaleType(QCPAxis::ScaleType type) +{ + if (mScaleType != type) + { + mScaleType = type; + if (mScaleType == stLogarithmic) + setRange(mRange.sanitizedForLogScale()); + mCachedMarginValid = false; + emit scaleTypeChanged(mScaleType); + } +} + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis, use \ref setRangeReversed. +*/ +void QCPAxis::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + QCPRange oldRange = mRange; + if (mScaleType == stLogarithmic) + { + mRange = range.sanitizedForLogScale(); + } else + { + mRange = range.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPAxis::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPAxis::setSelectedParts(const SelectableParts &selected) +{ + if (mSelectedParts != selected) + { + mSelectedParts = selected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + \overload + + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPAxis::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + \overload + + Sets the range of the axis. + + The \a position coordinate indicates together with the \a alignment parameter, where the new + range will be positioned. \a size defines the size of the new axis range. \a alignment may be + Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, + or center of the range to be aligned with \a position. Any other values of \a alignment will + default to Qt::AlignCenter. +*/ +void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range. The upper bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + QCPRange oldRange = mRange; + mRange.lower = lower; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets the upper bound of the axis range. The lower bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + QCPRange oldRange = mRange; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. + + Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part + of the \ref setRange interface will still reference the mathematically smaller number than the \a + upper part. +*/ +void QCPAxis::setRangeReversed(bool reversed) +{ + mRangeReversed = reversed; +} + +/*! + The axis ticker is responsible for generating the tick positions and tick labels. See the + documentation of QCPAxisTicker for details on how to work with axis tickers. + + You can change the tick positioning/labeling behaviour of this axis by setting a different + QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis + ticker, access it via \ref ticker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see ticker +*/ +void QCPAxis::setTicker(QSharedPointer ticker) +{ + if (ticker) + mTicker = ticker; + else + qDebug() << Q_FUNC_INFO << "can not set 0 as axis ticker"; + // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector +} + +/*! + Sets whether tick marks are displayed. + + Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve + that, see \ref setTickLabels. + + \see setSubTicks +*/ +void QCPAxis::setTicks(bool show) +{ + if (mTicks != show) + { + mTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. +*/ +void QCPAxis::setTickLabels(bool show) +{ + if (mTickLabels != show) + { + mTickLabels = show; + mCachedMarginValid = false; + if (!mTickLabels) + mTickVectorLabels.clear(); + } +} + +/*! + Sets the distance between the axis base line (including any outward ticks) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPAxis::setTickLabelPadding(int padding) +{ + if (mAxisPainter->tickLabelPadding != padding) + { + mAxisPainter->tickLabelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the font of the tick labels. + + \see setTickLabels, setTickLabelColor +*/ +void QCPAxis::setTickLabelFont(const QFont &font) +{ + if (font != mTickLabelFont) + { + mTickLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the tick labels. + + \see setTickLabels, setTickLabelFont +*/ +void QCPAxis::setTickLabelColor(const QColor &color) +{ + mTickLabelColor = color; +} + +/*! + Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, + the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values + from -90 to 90 degrees. + + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For + other angles, the label is drawn with an offset such that it seems to point toward or away from + the tick mark. +*/ +void QCPAxis::setTickLabelRotation(double degrees) +{ + if (!qFuzzyIsNull(degrees-mAxisPainter->tickLabelRotation)) + { + mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0); + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. + + The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels + to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels + appear on the inside are additionally clipped to the axis rect. +*/ +void QCPAxis::setTickLabelSide(LabelSide side) +{ + mAxisPainter->tickLabelSide = side; + mCachedMarginValid = false; +} + +/*! + Sets the number format for the numbers in tick labels. This \a formatCode is an extended version + of the format code used e.g. by QString::number() and QLocale::toString(). For reference about + that, see the "Argument Formats" section in the detailed description of the QString class. + + \a formatCode is a string of one, two or three characters. The first character is identical to + the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed + format, 'g'/'G' scientific or fixed, whichever is shorter. + + The second and third characters are optional and specific to QCustomPlot:\n + If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. + "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPAxis::setNumberFormat(const QString &formatCode) +{ + if (formatCode.isEmpty()) + { + qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; + return; + } + mCachedMarginValid = false; + + // interpret first char as number format char: + QString allowedFormatChars(QLatin1String("eEfgG")); + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) + { + mNumberBeautifulPowers = true; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + return; + } + if (formatCode.length() < 3) + { + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == QLatin1Char('c')) + { + mAxisPainter->numberMultiplyCross = true; + } else if (formatCode.at(2) == QLatin1Char('d')) + { + mAxisPainter->numberMultiplyCross = false; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + return; + } +} + +/*! + Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) + for details. The effect of precisions are most notably for number Formats starting with 'e', see + \ref setNumberFormat +*/ +void QCPAxis::setNumberPrecision(int precision) +{ + if (mNumberPrecision != precision) + { + mNumberPrecision = precision; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels and axis label will increase their distance to the axis accordingly, so + they won't collide with the ticks. + + \see setSubTickLength, setTickLengthIn, setTickLengthOut +*/ +void QCPAxis::setTickLength(int inside, int outside) +{ + setTickLengthIn(inside); + setTickLengthOut(outside); +} + +/*! + Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach + inside the plot. + + \see setTickLengthOut, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthIn(int inside) +{ + if (mAxisPainter->tickLengthIn != inside) + { + mAxisPainter->tickLengthIn = inside; + } +} + +/*! + Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach + outside the plot. If \a outside is greater than zero, the tick labels and axis label will + increase their distance to the axis accordingly, so they won't collide with the ticks. + + \see setTickLengthIn, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthOut(int outside) +{ + if (mAxisPainter->tickLengthOut != outside) + { + mAxisPainter->tickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets whether sub tick marks are displayed. + + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) + + \see setTicks +*/ +void QCPAxis::setSubTicks(bool show) +{ + if (mSubTicks != show) + { + mSubTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside + the plot and \a outside is the length they will reach outside the plot. If \a outside is greater + than zero, the tick labels and axis label will increase their distance to the axis accordingly, + so they won't collide with the ticks. + + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut +*/ +void QCPAxis::setSubTickLength(int inside, int outside) +{ + setSubTickLengthIn(inside); + setSubTickLengthOut(outside); +} + +/*! + Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside + the plot. + + \see setSubTickLengthOut, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthIn(int inside) +{ + if (mAxisPainter->subTickLengthIn != inside) + { + mAxisPainter->subTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach + outside the plot. If \a outside is greater than zero, the tick labels will increase their + distance to the axis accordingly, so they won't collide with the ticks. + + \see setSubTickLengthIn, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthOut(int outside) +{ + if (mAxisPainter->subTickLengthOut != outside) + { + mAxisPainter->subTickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPAxis::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, tick marks will be drawn with. + + \see setTickLength, setBasePen +*/ +void QCPAxis::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPAxis::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPAxis::setLabelFont(const QFont &font) +{ + if (mLabelFont != font) + { + mLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPAxis::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the text of the axis label that will be shown below/above or next to the axis, depending on + its orientation. To disable axis labels, pass an empty string as \a str. +*/ +void QCPAxis::setLabel(const QString &str) +{ + if (mLabel != str) + { + mLabel = str; + mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the tick labels and the axis label. + + \see setTickLabelPadding, setPadding +*/ +void QCPAxis::setLabelPadding(int padding) +{ + if (mAxisPainter->labelPadding != padding) + { + mAxisPainter->labelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the padding of the axis. + + When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, + that is left blank. + + The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. + + \see setLabelPadding, setTickLabelPadding +*/ +void QCPAxis::setPadding(int padding) +{ + if (mPadding != padding) + { + mPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the offset the axis has to its axis rect side. + + If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, + only the offset of the inner most axis has meaning (even if it is set to be invisible). The + offset of the other, outer axes is controlled automatically, to place them at appropriate + positions. +*/ +void QCPAxis::setOffset(int offset) +{ + mAxisPainter->offset = offset; +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelFont(const QFont &font) +{ + if (font != mSelectedTickLabelFont) + { + mSelectedTickLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts + } +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelColor(const QColor &color) +{ + if (color != mSelectedTickLabelColor) + { + mSelectedTickLabelColor = color; + } +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! + Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setUpperEnding +*/ +void QCPAxis::setLowerEnding(const QCPLineEnding &ending) +{ + mAxisPainter->lowerEnding = ending; +} + +/*! + Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the right ending, for vertical axes the top ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setLowerEnding +*/ +void QCPAxis::setUpperEnding(const QCPLineEnding &ending) +{ + mAxisPainter->upperEnding = ending; +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPAxis::moveRange(double diff) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + mRange.lower += diff; + mRange.upper += diff; + } else // mScaleType == stLogarithmic + { + mRange.lower *= diff; + mRange.upper *= diff; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis by \a factor around the center of the current axis range. For + example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis + range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around + the center will have moved symmetrically closer). + + If you wish to scale around a different coordinate than the current axis range center, use the + overload \ref scaleRange(double factor, double center). +*/ +void QCPAxis::scaleRange(double factor) +{ + scaleRange(factor, range().center()); +} + +/*! \overload + + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). + + \see scaleRange(double factor) +*/ +void QCPAxis::scaleRange(double factor, double center) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + } else // mScaleType == stLogarithmic + { + if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range + { + QCPRange newRange; + newRange.lower = qPow(mRange.lower/center, factor)*center; + newRange.upper = qPow(mRange.upper/center, factor)*center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLogScale(); + } else + qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will + be done around the center of the current axis range. + + For example, if \a ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs + plotted with those axes will appear in a 1:1 aspect ratio, independent of the aspect ratio the + axis rect has. + + This is an operation that changes the range of this axis once, it doesn't fix the scale ratio + indefinitely. Note that calling this function in the constructor of the QCustomPlot's parent + won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent + will follow. +*/ +void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) +{ + int otherPixelSize, ownPixelSize; + + if (otherAxis->orientation() == Qt::Horizontal) + otherPixelSize = otherAxis->axisRect()->width(); + else + otherPixelSize = otherAxis->axisRect()->height(); + + if (orientation() == Qt::Horizontal) + ownPixelSize = axisRect()->width(); + else + ownPixelSize = axisRect()->height(); + + double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/(double)otherPixelSize; + setRange(range().center(), newRangeSize, Qt::AlignCenter); +} + +/*! + Changes the axis range such that all plottables associated with this axis are fully visible in + that dimension. + + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPAxis::rescale(bool onlyVisiblePlottables) +{ + QList p = plottables(); + QCPRange newRange; + bool haveRange = false; + for (int i=0; irealVisibility() && onlyVisiblePlottables) + continue; + QCPRange plottableRange; + bool currentFoundRange; + QCP::SignDomain signDomain = QCP::sdBoth; + if (mScaleType == stLogarithmic) + signDomain = (mRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + if (p.at(i)->keyAxis() == this) + plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain); + else + plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain); + if (currentFoundRange) + { + if (!haveRange) + newRange = plottableRange; + else + newRange.expand(plottableRange); + haveRange = true; + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mScaleType == stLinear) + { + newRange.lower = center-mRange.size()/2.0; + newRange.upper = center+mRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mRange.upper/mRange.lower); + newRange.upper = center*qSqrt(mRange.upper/mRange.lower); + } + } + setRange(newRange); + } +} + +/*! + Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. +*/ +double QCPAxis::pixelToCoord(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.lower; + else + return -(value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/(double)mAxisRect->width())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/(double)mAxisRect->width())*mRange.upper; + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.lower; + else + return -(mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/(double)mAxisRect->height())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->bottom())/(double)mAxisRect->height())*mRange.upper; + } + } +} + +/*! + Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. +*/ +double QCPAxis::coordToPixel(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mRange.lower)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + else + return (mRange.upper-value)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + } else // mScaleType == stLogarithmic + { + if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->right()+200 : mAxisRect->left()-200; + else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->left()-200 : mAxisRect->right()+200; + else + { + if (!mRangeReversed) + return qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + else + return qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + } + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return mAxisRect->bottom()-(value-mRange.lower)/mRange.size()*mAxisRect->height(); + else + return mAxisRect->bottom()-(mRange.upper-value)/mRange.size()*mAxisRect->height(); + } else // mScaleType == stLogarithmic + { + if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->top()-200 : mAxisRect->bottom()+200; + else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->bottom()+200 : mAxisRect->top()-200; + else + { + if (!mRangeReversed) + return mAxisRect->bottom()-qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + else + return mAxisRect->bottom()-qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + } + } + } +} + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions +*/ +QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const +{ + if (!mVisible) + return spNone; + + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) + return spAxis; + else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) + return spTickLabels; + else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) + return spAxisLabel; + else + return spNone; +} + +/* inherits documentation from base class */ +double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + SelectablePart part = getPartAt(pos); + if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) + return -1; + + if (details) + details->setValue(part); + return mParentPlot->selectionTolerance()*0.99; +} + +/*! + Returns a list of all the plottables that have this axis as key or value axis. + + If you are only interested in plottables of type QCPGraph, see \ref graphs. + + \see graphs, items +*/ +QList QCPAxis::plottables() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis() == this ||mParentPlot->mPlottables.at(i)->valueAxis() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that have this axis as key or value axis. + + \see plottables, items +*/ +QList QCPAxis::graphs() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis() == this || mParentPlot->mGraphs.at(i)->valueAxis() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis. An item is considered + associated with an axis if at least one of its positions uses the axis as key or value axis. + + \see plottables, graphs +*/ +QList QCPAxis::items() const +{ + QList result; + if (!mParentPlot) return result; + + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdkeyAxis() == this || positions.at(posId)->valueAxis() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + Transforms a margin side to the logically corresponding axis type. (QCP::msLeft to + QCPAxis::atLeft, QCP::msRight to QCPAxis::atRight, etc.) +*/ +QCPAxis::AxisType QCPAxis::marginSideToAxisType(QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return atLeft; + case QCP::msRight: return atRight; + case QCP::msTop: return atTop; + case QCP::msBottom: return atBottom; + default: break; + } + qDebug() << Q_FUNC_INFO << "Invalid margin side passed:" << (int)side; + return atLeft; +} + +/*! + Returns the axis type that describes the opposite axis of an axis with the specified \a type. +*/ +QCPAxis::AxisType QCPAxis::opposite(QCPAxis::AxisType type) +{ + switch (type) + { + case atLeft: return atRight; break; + case atRight: return atLeft; break; + case atBottom: return atTop; break; + case atTop: return atBottom; break; + default: qDebug() << Q_FUNC_INFO << "invalid axis type"; return atLeft; break; + } +} + +/* inherits documentation from base class */ +void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + SelectablePart part = details.value(); + if (mSelectableParts.testFlag(part)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^part : part); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAxis::deselectEvent(bool *selectionStateChanged) +{ + SelectableParts selBefore = mSelectedParts; + setSelectedParts(mSelectedParts & ~mSelectableParts); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis + (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref + QCPAxisRect::setRangeDragAxes) + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. +*/ +void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag) || + !mAxisRect->rangeDrag().testFlag(orientation()) || + !mAxisRect->rangeDragAxes(orientation()).contains(this)) + { + event->ignore(); + return; + } + + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + mDragStartRange = mRange; + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (mDragging) + { + const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y(); + const double currentPixel = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y(); + if (mScaleType == QCPAxis::stLinear) + { + const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel); + setRange(mDragStartRange.lower+diff, mDragStartRange.upper+diff); + } else if (mScaleType == QCPAxis::stLogarithmic) + { + const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); + setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); + } + + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user zoom individual axes + exclusively, by performing the wheel event on top of the axis. + + For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis + (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref + QCPAxisRect::setRangeZoomAxes) + + \seebaseclassmethod + + \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the + axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. +*/ +void QCPAxis::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom) || + !mAxisRect->rangeZoom().testFlag(orientation()) || + !mAxisRect->rangeZoomAxes(orientation()).contains(this)) + { + event->ignore(); + return; + } + + const double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps); + scaleRange(factor, pixelToCoord(orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y())); + mParentPlot->replot(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing axis lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/*! \internal + + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. + + \seebaseclassmethod +*/ +void QCPAxis::draw(QCPPainter *painter) +{ + QVector subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + subTickPositions.reserve(mSubTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->basePen = getBasePen(); + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->labelColor = getLabelColor(); + mAxisPainter->label = mLabel; + mAxisPainter->substituteExponent = mNumberBeautifulPowers; + mAxisPainter->tickPen = getTickPen(); + mAxisPainter->subTickPen = getSubTickPen(); + mAxisPainter->tickLabelFont = getTickLabelFont(); + mAxisPainter->tickLabelColor = getTickLabelColor(); + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->abbreviateDecimalPowers = mScaleType == stLogarithmic; + mAxisPainter->reversedEndings = mRangeReversed; + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + mAxisPainter->subTickPositions = subTickPositions; + mAxisPainter->draw(painter); +} + +/*! \internal + + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling + QCPAxisTicker::generate on the currently installed ticker. + + If a change in the label text/count is detected, the cached axis margin is invalidated to make + sure the next margin calculation recalculates the label sizes and returns an up-to-date value. +*/ +void QCPAxis::setupTickVectors() +{ + if (!mParentPlot) return; + if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; + + QVector oldLabels = mTickVectorLabels; + mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); + mCachedMarginValid &= mTickVectorLabels == oldLabels; // if labels have changed, margin might have changed, too +} + +/*! \internal + + Returns the pen that is used to draw the axis base line. Depending on the selection state, this + is either mSelectedBasePen or mBasePen. +*/ +QPen QCPAxis::getBasePen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; +} + +/*! \internal + + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this + is either mSelectedTickPen or mTickPen. +*/ +QPen QCPAxis::getTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; +} + +/*! \internal + + Returns the pen that is used to draw the subticks. Depending on the selection state, this + is either mSelectedSubTickPen or mSubTickPen. +*/ +QPen QCPAxis::getSubTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; +} + +/*! \internal + + Returns the font that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelFont or mTickLabelFont. +*/ +QFont QCPAxis::getTickLabelFont() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; +} + +/*! \internal + + Returns the font that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelFont or mLabelFont. +*/ +QFont QCPAxis::getLabelFont() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; +} + +/*! \internal + + Returns the color that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelColor or mTickLabelColor. +*/ +QColor QCPAxis::getTickLabelColor() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; +} + +/*! \internal + + Returns the color that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelColor or mLabelColor. +*/ +QColor QCPAxis::getLabelColor() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; +} + +/*! \internal + + Returns the appropriate outward margin for this axis. It is needed if \ref + QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref + atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom + margin and so forth. For the calculation, this function goes through similar steps as \ref draw, + so changing one function likely requires the modification of the other one as well. + + The margin consists of the outward tick length, tick label padding, tick label size, label + padding, label size, and padding. + + The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. + unchanged are very fast. +*/ +int QCPAxis::calculateMargin() +{ + if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis + return 0; + + if (mCachedMarginValid) + return mCachedMargin; + + // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels + int margin = 0; + + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->label = mLabel; + mAxisPainter->tickLabelFont = mTickLabelFont; + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + margin += mAxisPainter->size(); + margin += mPadding; + + mCachedMargin = margin; + mCachedMarginValid = true; + return margin; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAxis::selectionCategory() const +{ + return QCP::iSelectAxes; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisPainterPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisPainterPrivate + + \internal + \brief (Private) + + This is a private class and not part of the public QCustomPlot interface. + + It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and + axis label. It also buffers the labels to reduce replot times. The parameters are configured by + directly accessing the public member variables. +*/ + +/*! + Constructs a QCPAxisPainterPrivate instance. Make sure to not create a new instance on every + redraw, to utilize the caching mechanisms. +*/ +QCPAxisPainterPrivate::QCPAxisPainterPrivate(QCustomPlot *parentPlot) : + type(QCPAxis::atLeft), + basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + lowerEnding(QCPLineEnding::esNone), + upperEnding(QCPLineEnding::esNone), + labelPadding(0), + tickLabelPadding(0), + tickLabelRotation(0), + tickLabelSide(QCPAxis::lsOutside), + substituteExponent(true), + numberMultiplyCross(false), + tickLengthIn(5), + tickLengthOut(0), + subTickLengthIn(2), + subTickLengthOut(0), + tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + offset(0), + abbreviateDecimalPowers(false), + reversedEndings(false), + mParentPlot(parentPlot), + mLabelCache(16) // cache at most 16 (tick) labels +{ +} + +QCPAxisPainterPrivate::~QCPAxisPainterPrivate() +{ +} + +/*! \internal + + Draws the axis with the specified \a painter. + + The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set + here, too. +*/ +void QCPAxisPainterPrivate::draw(QCPPainter *painter) +{ + QByteArray newHash = generateLabelParameterHash(); + if (newHash != mLabelParameterHash) + { + mLabelCache.clear(); + mLabelParameterHash = newHash; + } + + QPoint origin; + switch (type) + { + case QCPAxis::atLeft: origin = axisRect.bottomLeft() +QPoint(-offset, 0); break; + case QCPAxis::atRight: origin = axisRect.bottomRight()+QPoint(+offset, 0); break; + case QCPAxis::atTop: origin = axisRect.topLeft() +QPoint(0, -offset); break; + case QCPAxis::atBottom: origin = axisRect.bottomLeft() +QPoint(0, +offset); break; + } + + double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) + switch (type) + { + case QCPAxis::atTop: yCor = -1; break; + case QCPAxis::atRight: xCor = 1; break; + default: break; + } + int margin = 0; + // draw baseline: + QLineF baseLine; + painter->setPen(basePen); + if (QCPAxis::orientation(type) == Qt::Horizontal) + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(axisRect.width()+xCor, yCor)); + else + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -axisRect.height()+yCor)); + if (reversedEndings) + baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later + painter->drawLine(baseLine); + + // draw ticks: + if (!tickPositions.isEmpty()) + { + painter->setPen(tickPen); + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis) + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(tickPositions.at(i)+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPositions.at(i)+xCor, origin.y()+tickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPositions.at(i)+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPositions.at(i)+yCor)); + } + } + + // draw subticks: + if (!subTickPositions.isEmpty()) + { + painter->setPen(subTickPen); + // direction of ticks ("inward" is right for left axis and left for right axis) + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(subTickPositions.at(i)+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPositions.at(i)+xCor, origin.y()+subTickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPositions.at(i)+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPositions.at(i)+yCor)); + } + } + margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // draw axis base endings: + bool antialiasingBackup = painter->antialiasing(); + painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't + painter->setBrush(QBrush(basePen.color())); + QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); + if (lowerEnding.style() != QCPLineEnding::esNone) + lowerEnding.draw(painter, QCPVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector); + if (upperEnding.style() != QCPLineEnding::esNone) + upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); + painter->setAntialiasing(antialiasingBackup); + + // tick labels: + QRect oldClipRect; + if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect + { + oldClipRect = painter->clipRegion().boundingRect(); + painter->setClipRect(axisRect); + } + QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label + if (!tickLabels.isEmpty()) + { + if (tickLabelSide == QCPAxis::lsOutside) + margin += tickLabelPadding; + painter->setFont(tickLabelFont); + painter->setPen(QPen(tickLabelColor)); + const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size()); + int distanceToAxis = margin; + if (tickLabelSide == QCPAxis::lsInside) + distanceToAxis = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + for (int i=0; isetClipRect(oldClipRect); + + // axis label: + QRect labelBounds; + if (!label.isEmpty()) + { + margin += labelPadding; + painter->setFont(labelFont); + painter->setPen(QPen(labelColor)); + labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, label); + if (type == QCPAxis::atLeft) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); + painter->rotate(-90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atRight) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-axisRect.height()); + painter->rotate(90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atTop) + painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + else if (type == QCPAxis::atBottom) + painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + } + + // set selection boxes: + int selectionTolerance = 0; + if (mParentPlot) + selectionTolerance = mParentPlot->selectionTolerance(); + else + qDebug() << Q_FUNC_INFO << "mParentPlot is null"; + int selAxisOutSize = qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance); + int selAxisInSize = selectionTolerance; + int selTickLabelSize; + int selTickLabelOffset; + if (tickLabelSide == QCPAxis::lsOutside) + { + selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = qMax(tickLengthOut, subTickLengthOut)+tickLabelPadding; + } else + { + selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + } + int selLabelSize = labelBounds.height(); + int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding; + if (type == QCPAxis::atLeft) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atRight) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atTop) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset); + } else if (type == QCPAxis::atBottom) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset); + } + mAxisSelectionBox = mAxisSelectionBox.normalized(); + mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized(); + mLabelSelectionBox = mLabelSelectionBox.normalized(); + // draw hitboxes for debug purposes: + //painter->setBrush(Qt::NoBrush); + //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); +} + +/*! \internal + + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone + direction) needed to fit the axis. +*/ +int QCPAxisPainterPrivate::size() const +{ + int result = 0; + + // get length of tick marks pointing outwards: + if (!tickPositions.isEmpty()) + result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // calculate size of tick labels: + if (tickLabelSide == QCPAxis::lsOutside) + { + QSize tickLabelsSize(0, 0); + if (!tickLabels.isEmpty()) + { + for (int i=0; ibufferDevicePixelRatio())); + result.append(QByteArray::number(tickLabelRotation)); + result.append(QByteArray::number((int)tickLabelSide)); + result.append(QByteArray::number((int)substituteExponent)); + result.append(QByteArray::number((int)numberMultiplyCross)); + result.append(tickLabelColor.name().toLatin1()+QByteArray::number(tickLabelColor.alpha(), 16)); + result.append(tickLabelFont.toString().toLatin1()); + return result; +} + +/*! \internal + + Draws a single tick label with the provided \a painter, utilizing the internal label cache to + significantly speed up drawing of labels that were drawn in previous calls. The tick label is + always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in + pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence + for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), + at which the label should be drawn. + + In order to later draw the axis label in a place that doesn't overlap with the tick labels, the + largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref + drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a + tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently + holds. + + The label is drawn with the font and pen that are currently set on the \a painter. To draw + superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref + getTickLabelData). +*/ +void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize) +{ + // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! + if (text.isEmpty()) return; + QSize finalSize; + QPointF labelAnchor; + switch (type) + { + case QCPAxis::atLeft: labelAnchor = QPointF(axisRect.left()-distanceToAxis-offset, position); break; + case QCPAxis::atRight: labelAnchor = QPointF(axisRect.right()+distanceToAxis+offset, position); break; + case QCPAxis::atTop: labelAnchor = QPointF(position, axisRect.top()-distanceToAxis-offset); break; + case QCPAxis::atBottom: labelAnchor = QPointF(position, axisRect.bottom()+distanceToAxis+offset); break; + } + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled + { + CachedLabel *cachedLabel = mLabelCache.take(text); // attempt to get label from cache + if (!cachedLabel) // no cached label existed, create it + { + cachedLabel = new CachedLabel; + TickLabelData labelData = getTickLabelData(painter->font(), text); + cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft(); + if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) + { + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio()); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF()); +# else + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); +# endif +#endif + } else + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); + cachedLabel->pixmap.fill(Qt::transparent); + QCPPainter cachePainter(&cachedLabel->pixmap); + cachePainter.setPen(painter->pen()); + drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData); + } + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); + else + labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + painter->drawPixmap(labelAnchor+cachedLabel->offset, cachedLabel->pixmap); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } + mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created + } else // label caching disabled, draw text directly on surface: + { + TickLabelData labelData = getTickLabelData(painter->font(), text); + QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData); + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); + else + labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData); + finalSize = labelData.rotatedTotalBounds.size(); + } + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a + y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to + directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when + QCP::phCacheLabels plotting hint is not set. +*/ +void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const +{ + // backup painter settings that we're about to change: + QTransform oldTransform = painter->transform(); + QFont oldFont = painter->font(); + + // transform painter to position/rotation: + painter->translate(x, y); + if (!qFuzzyIsNull(tickLabelRotation)) + painter->rotate(tickLabelRotation); + + // draw text: + if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); + if (!labelData.suffixPart.isEmpty()) + painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart); + painter->setFont(labelData.expFont); + painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); + } else + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); + } + + // reset painter settings to what it was before: + painter->setTransform(oldTransform); + painter->setFont(oldFont); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further + processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and + exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. +*/ +QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const +{ + TickLabelData result; + + // determine whether beautiful decimal powers should be used + bool useBeautifulPowers = false; + int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart + int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart + if (substituteExponent) + { + ePos = text.indexOf(QLatin1Char('e')); + if (ePos > 0 && text.at(ePos-1).isDigit()) + { + eLast = ePos; + while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) + ++eLast; + if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power + useBeautifulPowers = true; + } + } + + // calculate text bounding rects and do string preparation for beautiful decimal powers: + result.baseFont = font; + if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line + result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + if (useBeautifulPowers) + { + // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: + result.basePart = text.left(ePos); + result.suffixPart = text.mid(eLast+1); // also drawn normally but after exponent + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (abbreviateDecimalPowers && result.basePart == QLatin1String("1")) + result.basePart = QLatin1String("10"); + else + result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10"); + result.expPart = text.mid(ePos+1, eLast-ePos); + // clip "+" and leading zeros off expPart: + while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' + result.expPart.remove(1, 1); + if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) + result.expPart.remove(0, 1); + // prepare smaller font for exponent: + result.expFont = font; + if (result.expFont.pointSize() > 0) + result.expFont.setPointSize(result.expFont.pointSize()*0.75); + else + result.expFont.setPixelSize(result.expFont.pixelSize()*0.75); + // calculate bounding rects of base part(s), exponent part and total one: + result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); + result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); + if (!result.suffixPart.isEmpty()) + result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart); + result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA + } else // useBeautifulPowers == false + { + result.basePart = text; + result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); + } + result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler + + // calculate possibly different bounding rect after rotation: + result.rotatedTotalBounds = result.totalBounds; + if (!qFuzzyIsNull(tickLabelRotation)) + { + QTransform transform; + transform.rotate(tickLabelRotation); + result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); + } + + return result; +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Calculates the offset at which the top left corner of the specified tick label shall be drawn. + The offset is relative to a point right next to the tick the label belongs to. + + This function is thus responsible for e.g. centering tick labels under ticks and positioning them + appropriately when they are rotated. +*/ +QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &labelData) const +{ + /* + calculate label offset from base point at tick (non-trivial, for best visual appearance): short + explanation for bottom axis: The anchor, i.e. the point in the label that is placed + horizontally under the corresponding tick is always on the label side that is closer to the + axis (e.g. the left side of the text when we're rotating clockwise). On that side, the height + is halved and the resulting point is defined the anchor. This way, a 90 degree rotated text + will be centered under the tick (i.e. displaced horizontally by half its height). At the same + time, a 45 degree rotated text will "point toward" its tick, as is typical for rotated tick + labels. + */ + bool doRotation = !qFuzzyIsNull(tickLabelRotation); + bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes. + double radians = tickLabelRotation/180.0*M_PI; + int x=0, y=0; + if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height(); + y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = -labelData.totalBounds.width(); + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = 0; + y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = 0; + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0; + y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height(); + } else + { + x = -qSin(-radians)*labelData.totalBounds.height()/2.0; + y = -qCos(-radians)*labelData.totalBounds.height(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = -labelData.totalBounds.height(); + } + } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height()/2.0; + y = 0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height()/2.0; + y = +qSin(-radians)*labelData.totalBounds.width(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = 0; + } + } + + return QPointF(x, y); +} + +/*! \internal + + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label + to be drawn, depending on number format etc. Since only the largest tick label is wanted for the + margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a + smaller width/height. +*/ +void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const +{ + // note: this function must return the same tick label sizes as the placeTickLabel function. + QSize finalSize; + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label + { + const CachedLabel *cachedLabel = mLabelCache.object(text); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } else // label caching disabled or no label with this text cached: + { + TickLabelData labelData = getTickLabelData(font, text); + finalSize = labelData.rotatedTotalBounds.size(); + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} +/* end of 'src/axis/axis.cpp' */ + + +/* including file 'src/scatterstyle.cpp', size 17450 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPScatterStyle +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPScatterStyle + \brief Represents the visual appearance of scatter points + + This class holds information about shape, color and size of scatter points. In plottables like + QCPGraph it is used to store how scatter points shall be drawn. For example, \ref + QCPGraph::setScatterStyle takes a QCPScatterStyle instance. + + A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a + fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can + be controlled with \ref setSize. + + \section QCPScatterStyle-defining Specifying a scatter style + + You can set all these configurations either by calling the respective functions on an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 + + Or you can use one of the various constructors that take different parameter combinations, making + it easy to specify a scatter style in a single call, like so: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 + + \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable + + There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref + QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref + isPenDefined will return false. It leads to scatter points that inherit the pen from the + plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line + color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes + it very convenient to set up typical scatter settings: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation + + Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works + because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly + into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) + constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref + ScatterShape, where actually a QCPScatterStyle is expected. + + \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps + + QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. + + For custom shapes, you can provide a QPainterPath with the desired shape to the \ref + setCustomPath function or call the constructor that takes a painter path. The scatter shape will + automatically be set to \ref ssCustom. + + For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the + constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. + Note that \ref setSize does not influence the appearance of the pixmap. +*/ + +/* start documentation of inline functions */ + +/*! \fn bool QCPScatterStyle::isNone() const + + Returns whether the scatter shape is \ref ssNone. + + \see setShape +*/ + +/*! \fn bool QCPScatterStyle::isPenDefined() const + + Returns whether a pen has been defined for this scatter style. + + The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those + are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen + is undefined, the pen of the respective plottable will be used for drawing scatters. + + If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call + \ref undefinePen. + + \see setPen +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle() : + mSize(6), + mShape(ssNone), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or + brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) : + mSize(size), + mShape(shape), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + and size to \a size. No brush is defined, i.e. the scatter point will not be filled. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(Qt::NoBrush), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + the brush color to \a fill (with a solid pattern), and size to \a size. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(QBrush(fill)), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the + brush to \a brush, and size to \a size. + + \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen + and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n + QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n + doesn't necessarily lead C++ to use this constructor in some cases, but might mistake + Qt::NoPen for a QColor and use the + \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) + constructor instead (which will lead to an unexpected look of the scatter points). To prevent + this, be more explicit with the parameter types. For example, use QBrush(Qt::blue) + instead of just Qt::blue, to clearly point out to the compiler that this constructor is + wanted. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(shape), + mPen(pen), + mBrush(brush), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape + is set to \ref ssPixmap. +*/ +QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : + mSize(5), + mShape(ssPixmap), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPixmap(pixmap), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The + scatter shape is set to \ref ssCustom. + + The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly + different meaning than for built-in scatter points: The custom path will be drawn scaled by a + factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its + original size by default. To for example double the size of the path, set \a size to 12. +*/ +QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(ssCustom), + mPen(pen), + mBrush(brush), + mCustomPath(customPath), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Copies the specified \a properties from the \a other scatter style to this scatter style. +*/ +void QCPScatterStyle::setFromOther(const QCPScatterStyle &other, ScatterProperties properties) +{ + if (properties.testFlag(spPen)) + { + setPen(other.pen()); + if (!other.isPenDefined()) + undefinePen(); + } + if (properties.testFlag(spBrush)) + setBrush(other.brush()); + if (properties.testFlag(spSize)) + setSize(other.size()); + if (properties.testFlag(spShape)) + { + setShape(other.shape()); + if (other.shape() == ssPixmap) + setPixmap(other.pixmap()); + else if (other.shape() == ssCustom) + setCustomPath(other.customPath()); + } +} + +/*! + Sets the size (pixel diameter) of the drawn scatter points to \a size. + + \see setShape +*/ +void QCPScatterStyle::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the shape to \a shape. + + Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref + ssPixmap and \ref ssCustom, respectively. + + \see setSize +*/ +void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) +{ + mShape = shape; +} + +/*! + Sets the pen that will be used to draw scatter points to \a pen. + + If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after + a call to this function, even if \a pen is Qt::NoPen. If you have defined a pen + previously by calling this function and now wish to undefine the pen, call \ref undefinePen. + + \see setBrush +*/ +void QCPScatterStyle::setPen(const QPen &pen) +{ + mPenDefined = true; + mPen = pen; +} + +/*! + Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter + shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. + + \see setPen +*/ +void QCPScatterStyle::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the pixmap that will be drawn as scatter point to \a pixmap. + + Note that \ref setSize does not influence the appearance of the pixmap. + + The scatter shape is automatically set to \ref ssPixmap. +*/ +void QCPScatterStyle::setPixmap(const QPixmap &pixmap) +{ + setShape(ssPixmap); + mPixmap = pixmap; +} + +/*! + Sets the custom shape that will be drawn as scatter point to \a customPath. + + The scatter shape is automatically set to \ref ssCustom. +*/ +void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) +{ + setShape(ssCustom); + mCustomPath = customPath; +} + +/*! + Sets this scatter style to have an undefined pen (see \ref isPenDefined for what an undefined pen + implies). + + A call to \ref setPen will define a pen. +*/ +void QCPScatterStyle::undefinePen() +{ + mPenDefined = false; +} + +/*! + Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an + undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. + + This function is used by plottables (or any class that wants to draw scatters) just before a + number of scatters with this style shall be drawn with the \a painter. + + \see drawShape +*/ +void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const +{ + painter->setPen(mPenDefined ? mPen : defaultPen); + painter->setBrush(mBrush); +} + +/*! + Draws the scatter shape with \a painter at position \a pos. + + This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be + called before scatter points are drawn with \ref drawShape. + + \see applyTo +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, const QPointF &pos) const +{ + drawShape(painter, pos.x(), pos.y()); +} + +/*! \overload + Draws the scatter shape with \a painter at position \a x and \a y. +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const +{ + double w = mSize/2.0; + switch (mShape) + { + case ssNone: break; + case ssDot: + { + painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y)); + break; + } + case ssCross: + { + painter->drawLine(QLineF(x-w, y-w, x+w, y+w)); + painter->drawLine(QLineF(x-w, y+w, x+w, y-w)); + break; + } + case ssPlus: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCircle: + { + painter->drawEllipse(QPointF(x , y), w, w); + break; + } + case ssDisc: + { + QBrush b = painter->brush(); + painter->setBrush(painter->pen().color()); + painter->drawEllipse(QPointF(x , y), w, w); + painter->setBrush(b); + break; + } + case ssSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssDiamond: + { + QPointF lineArray[4] = {QPointF(x-w, y), + QPointF( x, y-w), + QPointF(x+w, y), + QPointF( x, y+w)}; + painter->drawPolygon(lineArray, 4); + break; + } + case ssStar: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); + break; + } + case ssTriangle: + { + QPointF lineArray[3] = {QPointF(x-w, y+0.755*w), + QPointF(x+w, y+0.755*w), + QPointF( x, y-0.977*w)}; + painter->drawPolygon(lineArray, 3); + break; + } + case ssTriangleInverted: + { + QPointF lineArray[3] = {QPointF(x-w, y-0.755*w), + QPointF(x+w, y-0.755*w), + QPointF( x, y+0.977*w)}; + painter->drawPolygon(lineArray, 3); + break; + } + case ssCrossSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); + painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); + break; + } + case ssPlusSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + painter->drawLine(QLineF(x-w, y, x+w*0.95, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCrossCircle: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707)); + break; + } + case ssPlusCircle: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssPeace: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x, y-w, x, y+w)); + painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); + break; + } + case ssPixmap: + { + const double widthHalf = mPixmap.width()*0.5; + const double heightHalf = mPixmap.height()*0.5; +#if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) + const QRectF clipRect = painter->clipRegion().boundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#else + const QRectF clipRect = painter->clipBoundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#endif + if (clipRect.contains(x, y)) + painter->drawPixmap(x-widthHalf, y-heightHalf, mPixmap); + break; + } + case ssCustom: + { + QTransform oldTransform = painter->transform(); + painter->translate(x, y); + painter->scale(mSize/6.0, mSize/6.0); + painter->drawPath(mCustomPath); + painter->setTransform(oldTransform); + break; + } + } +} +/* end of 'src/scatterstyle.cpp' */ + +//amalgamation: add datacontainer.cpp + +/* including file 'src/plottable.cpp', size 38845 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecorator +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecorator + \brief Controls how a plottable's data selection is drawn + + Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref + QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data. + + The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the + scatter style (\ref setScatterStyle) if the plottable draws scatters. Since a \ref + QCPScatterStyle is itself composed of different properties such as color shape and size, the + decorator allows specifying exactly which of those properties shall be used for the selected data + point, via \ref setUsedScatterProperties. + + A \ref QCPSelectionDecorator subclass instance can be passed to a plottable via \ref + QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance + of selected segments. + + Use \ref copyFrom to easily transfer the settings of one decorator to another one. This is + especially useful since plottables take ownership of the passed selection decorator, and thus the + same decorator instance can not be passed to multiple plottables. + + Selection decorators can also themselves perform drawing operations by reimplementing \ref + drawDecoration, which is called by the plottable's draw method. The base class \ref + QCPSelectionDecorator does not make use of this however. For example, \ref + QCPSelectionDecoratorBracket draws brackets around selected data segments. +*/ + +/*! + Creates a new QCPSelectionDecorator instance with default values +*/ +QCPSelectionDecorator::QCPSelectionDecorator() : + mPen(QColor(80, 80, 255), 2.5), + mBrush(Qt::NoBrush), + mScatterStyle(), + mUsedScatterProperties(QCPScatterStyle::spNone), + mPlottable(0) +{ +} + +QCPSelectionDecorator::~QCPSelectionDecorator() +{ +} + +/*! + Sets the pen that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the scatter style that will be used by the parent plottable to draw scatters in selected + data segments. + + \a usedProperties specifies which parts of the passed \a scatterStyle will be used by the + plottable. The used properties can also be changed via \ref setUsedScatterProperties. +*/ +void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties) +{ + mScatterStyle = scatterStyle; + setUsedScatterProperties(usedProperties); +} + +/*! + Use this method to define which properties of the scatter style (set via \ref setScatterStyle) + will be used for selected data segments. All properties of the scatter style that are not + specified in \a properties will remain as specified in the plottable's original scatter style. + + \see QCPScatterStyle::ScatterProperty +*/ +void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties) +{ + mUsedScatterProperties = properties; +} + +/*! + Sets the pen of \a painter to the pen of this selection decorator. + + \see applyBrush, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyPen(QCPPainter *painter) const +{ + painter->setPen(mPen); +} + +/*! + Sets the brush of \a painter to the brush of this selection decorator. + + \see applyPen, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const +{ + painter->setBrush(mBrush); +} + +/*! + Returns the scatter style that the parent plottable shall use for selected scatter points. The + plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending + on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this + selecion decorator's scatter style (\ref setScatterStyle), and \a unselectedStyle. + + \see applyPen, applyBrush, setScatterStyle +*/ +QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const +{ + QCPScatterStyle result(unselectedStyle); + result.setFromOther(mScatterStyle, mUsedScatterProperties); + + // if style shall inherit pen from plottable (has no own pen defined), give it the selected + // plottable pen explicitly, so it doesn't use the unselected plottable pen when used in the + // plottable: + if (!result.isPenDefined()) + result.setPen(mPen); + + return result; +} + +/*! + Copies all properties (e.g. color, fill, scatter style) of the \a other selection decorator to + this selection decorator. +*/ +void QCPSelectionDecorator::copyFrom(const QCPSelectionDecorator *other) +{ + setPen(other->pen()); + setBrush(other->brush()); + setScatterStyle(other->scatterStyle(), other->usedScatterProperties()); +} + +/*! + This method is called by all plottables' draw methods to allow custom selection decorations to be + drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data + selection for which the decoration shall be drawn. + + The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so + this method does nothing. +*/ +void QCPSelectionDecorator::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + Q_UNUSED(painter) + Q_UNUSED(selection) +} + +/*! \internal + + This method is called as soon as a selection decorator is associated with a plottable, by a call + to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access + data points via the \ref QCPAbstractPlottable::interface1D interface). + + If the selection decorator was already added to a different plottable before, this method aborts + the registration and returns false. +*/ +bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottable) + { + mPlottable = plottable; + return true; + } else + { + qDebug() << Q_FUNC_INFO << "This selection decorator is already registered with plottable:" << reinterpret_cast(mPlottable); + return false; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable + \brief The abstract base class for all data representing objects in a plot. + + It defines a very basic interface like name, pen, brush, visibility etc. Since this class is + abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to + create new ways of displaying data (see "Creating own plottables" below). Plottables that display + one-dimensional data (i.e. data points have a single key dimension and one or multiple values at + each key) are based off of the template subclass \ref QCPAbstractPlottable1D, see details + there. + + All further specifics are in the subclasses, for example: + \li A normal graph with possibly a line and/or scatter points \ref QCPGraph + (typically created with \ref QCustomPlot::addGraph) + \li A parametric curve: \ref QCPCurve + \li A bar chart: \ref QCPBars + \li A statistical box plot: \ref QCPStatisticalBox + \li A color encoded two-dimensional map: \ref QCPColorMap + \li An OHLC/Candlestick chart: \ref QCPFinancial + + \section plottables-subclassing Creating own plottables + + Subclassing directly from QCPAbstractPlottable is only recommended if you wish to display + two-dimensional data like \ref QCPColorMap, i.e. two logical key dimensions and one (or more) + data dimensions. If you want to display data with only one logical key dimension, you should + rather derive from \ref QCPAbstractPlottable1D. + + If subclassing QCPAbstractPlottable directly, these are the pure virtual functions you must + implement: + \li \ref selectTest + \li \ref draw + \li \ref drawLegendIcon + \li \ref getKeyRange + \li \ref getValueRange + + See the documentation of those functions for what they need to do. + + For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot + coordinates to pixel coordinates. This function is quite convenient, because it takes the + orientation of the key and value axes into account for you (x and y are swapped when the key axis + is vertical and the value axis horizontal). If you are worried about performance (i.e. you need + to translate many points in a loop like QCPGraph), you can directly use \ref + QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis + yourself. + + Here are some important members you inherit from QCPAbstractPlottable: + + + + + + + + + + + + + + + + + + + + + + + + + + +
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable + (e.g QCPGraph uses this pen for its graph lines and scatters)
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable + (e.g. QCPGraph uses this brush to control filling under the graph)
QPointer<\ref QCPAxis> \b mKeyAxis, \b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates + to pixels in either the key or value dimension. Make sure to check whether the pointer is null before using it. If one of + the axes is null, don't draw the plottable.
\ref QCPSelectionDecorator \b mSelectionDecoratorThe currently set selection decorator which specifies how selected data of the plottable shall be drawn and decorated. + When drawing your data, you must consult this decorator for the appropriate pen/brush before drawing unselected/selected data segments. + Finally, you should call its \ref QCPSelectionDecorator::drawDecoration method at the end of your \ref draw implementation.
\ref QCP::SelectionType \b mSelectableIn which composition, if at all, this plottable's data may be selected. Enforcing this setting on the data selection is done + by QCPAbstractPlottable automatically.
\ref QCPDataSelection \b mSelectionHolds the current selection state of the plottable's data, i.e. the selected data ranges (\ref QCPDataRange).
+*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionDecorator *QCPAbstractPlottable::selectionDecorator() const + + Provides access to the selection decorator of this plottable. The selection decorator controls + how selected data ranges are drawn (e.g. their pen color and fill), see \ref + QCPSelectionDecorator for details. + + If you wish to use an own \ref QCPSelectionDecorator subclass, pass an instance of it to \ref + setSelectionDecorator. +*/ + +/*! \fn bool QCPAbstractPlottable::selected() const + + Returns true if there are any data points of the plottable currently selected. Use \ref selection + to retrieve the current \ref QCPDataSelection. +*/ + +/*! \fn QCPDataSelection QCPAbstractPlottable::selection() const + + Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on + this plottable. + + \see selected, setSelection, setSelectable +*/ + +/*! \fn virtual QCPPlottableInterface1D *QCPAbstractPlottable::interface1D() + + If this plottable is a one-dimensional plottable, i.e. it implements the \ref + QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case + of a \ref QCPColorMap) returns zero. + + You can use this method to gain read access to data coordinates while holding a pointer to the + abstract base class only. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of pure virtual functions */ + +/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 + \internal + + called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation + of this plottable inside \a rect, next to the plottable name. + + The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't + appear outside the legend icon border. +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0 + + Returns the coordinate range that all data in this plottable span in the key axis dimension. For + logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref + QCP::sdPositive in order to restrict the returned range to that sign domain. E.g. when only + negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and all positive points + will be ignored for range calculation. For no restriction, just set \a inSignDomain to \ref + QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could + be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data). + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getValueRange +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0 + + Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span + in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref + QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign + domain. E.g. when only negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and + all positive points will be ignored for range calculation. For no restriction, just set \a + inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates + whether a range could be found or not. If this is false, you shouldn't use the returned range + (e.g. no points in data). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getKeyRange +*/ + +/* end of documentation of pure virtual functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether + there are any points selected or not. + + \see selectionChanged(const QCPDataSelection &selection) +*/ + +/*! \fn void QCPAbstractPlottable::selectionChanged(const QCPDataSelection &selection) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selection holds the + currently selected data ranges. + + \see selectionChanged(bool selected) +*/ + +/*! \fn void QCPAbstractPlottable::selectableChanged(QCP::SelectionType selectable); + + This signal is emitted when the selectability of this plottable has changed. + + \see setSelectable +*/ + +/* end of documentation of signals */ + +/*! + Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as + its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance + and have perpendicular orientations. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, + it can't be directly instantiated. + + You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. +*/ +QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()), + mName(), + mDesc(), + mAntialiasedFill(true), + mAntialiasedScatters(true), + mPen(Qt::black), + mBrush(Qt::NoBrush), + mKeyAxis(keyAxis), + mValueAxis(valueAxis), + mSelectable(QCP::stWhole), + mSelectionDecorator(0) +{ + if (keyAxis->parentPlot() != valueAxis->parentPlot()) + qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; + if (keyAxis->orientation() == valueAxis->orientation()) + qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; + + mParentPlot->registerPlottable(this); + setSelectionDecorator(new QCPSelectionDecorator); +} + +QCPAbstractPlottable::~QCPAbstractPlottable() +{ + if (mSelectionDecorator) + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} + +/*! + The name is the textual representation of this plottable as it is displayed in the legend + (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. +*/ +void QCPAbstractPlottable::setName(const QString &name) +{ + mName = name; +} + +void QCPAbstractPlottable::setDesc(const QString &desc) +{ + mDesc = desc; +} + +/*! + Sets whether fills of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedFill(bool enabled) +{ + mAntialiasedFill = enabled; +} + +/*! + Sets whether the scatter symbols of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) +{ + mAntialiasedScatters = enabled; +} + +/*! + The pen is used to draw basic lines that make up the plottable representation in the + plot. + + For example, the \ref QCPGraph subclass draws its graph lines with this pen. + + \see setBrush +*/ +void QCPAbstractPlottable::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + The brush is used to draw basic fills of the plottable representation in the + plot. The Fill can be a color, gradient or texture, see the usage of QBrush. + + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when + it's not set to Qt::NoBrush. + + \see setPen +*/ +void QCPAbstractPlottable::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal + to the plottable's value axis. This function performs no checks to make sure this is the case. + The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the + y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setValueAxis +*/ +void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) +{ + mKeyAxis = axis; +} + +/*! + The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is + orthogonal to the plottable's key axis. This function performs no checks to make sure this is the + case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and + the y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setKeyAxis +*/ +void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) +{ + mValueAxis = axis; +} + + +/*! + Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently + (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref + selectionDecorator). + + The entire selection mechanism for plottables is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when + you wish to change the selection state programmatically. + + Using \ref setSelectable you can further specify for each plottable whether and to which + granularity it is selectable. If \a selection is not compatible with the current \ref + QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted + accordingly (see \ref QCPDataSelection::enforceType). + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractPlottable::setSelection(QCPDataSelection selection) +{ + selection.enforceType(mSelectable); + if (mSelection != selection) + { + mSelection = selection; + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } +} + +/*! + Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to + customize the visual representation of selected data ranges further than by using the default + QCPSelectionDecorator. + + The plottable takes ownership of the \a decorator. + + The currently set decorator can be accessed via \ref selectionDecorator. +*/ +void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorator) +{ + if (decorator) + { + if (decorator->registerWithPlottable(this)) + { + if (mSelectionDecorator) // delete old decorator if necessary + delete mSelectionDecorator; + mSelectionDecorator = decorator; + } + } else if (mSelectionDecorator) // just clear decorator + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} + +/*! + Sets whether and to which granularity this plottable can be selected. + + A selection can happen by clicking on the QCustomPlot surface (When \ref + QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect + (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by + calling \ref setSelection. + + \see setSelection, QCP::SelectionType +*/ +void QCPAbstractPlottable::setSelectable(QCP::SelectionType selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + QCPDataSelection oldSelection = mSelection; + mSelection.enforceType(mSelectable); + emit selectableChanged(mSelectable); + if (mSelection != oldSelection) + { + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } + } +} + + +/*! + Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. + + \see pixelsToCoords, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + x = keyAxis->coordToPixel(key); + y = valueAxis->coordToPixel(value); + } else + { + y = keyAxis->coordToPixel(key); + x = valueAxis->coordToPixel(value); + } +} + +/*! \overload + + Transforms the given \a key and \a value to pixel coordinates and returns them in a QPointF. +*/ +const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); + else + return QPointF(valueAxis->coordToPixel(value), keyAxis->coordToPixel(key)); +} + +/*! + Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. + + \see coordsToPixels, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + key = keyAxis->pixelToCoord(x); + value = valueAxis->pixelToCoord(y); + } else + { + key = keyAxis->pixelToCoord(y); + value = valueAxis->pixelToCoord(x); + } +} + +/*! \overload + + Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. +*/ +void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const +{ + pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); +} + +/*! + Rescales the key and value axes associated with this plottable to contain all displayed data, so + the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make + sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. + Instead it will stay in the current sign domain and ignore all parts of the plottable that lie + outside of that domain. + + \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show + multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has + \a onlyEnlarge set to false (the default), and all subsequent set to true. + + \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale +*/ +void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const +{ + rescaleKeyAxis(onlyEnlarge); + rescaleValueAxis(onlyEnlarge); +} + +/*! + Rescales the key axis of the plottable so the whole plottable is visible. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (keyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (keyAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getKeyRange(foundRange, signDomain); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(keyAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (keyAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-keyAxis->range().size()/2.0; + newRange.upper = center+keyAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(keyAxis->range().upper/keyAxis->range().lower); + newRange.upper = center*qSqrt(keyAxis->range().upper/keyAxis->range().lower); + } + } + keyAxis->setRange(newRange); + } +} + +/*! + Rescales the value axis of the plottable so the whole plottable is visible. If \a inKeyRange is + set to true, only the data points which are in the currently visible key axis range are + considered. + + Returns true if the axis was actually scaled. This might not be the case if this plottable has an + invalid range, e.g. because it has no data points. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (valueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(valueAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-valueAxis->range().size()/2.0; + newRange.upper = center+valueAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); + newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); + } + } + valueAxis->setRange(newRange); + } +} + +/*! \overload + + Adds this plottable to the specified \a legend. + + Creates a QCPPlottableLegendItem which is inserted into the legend. Returns true on success, i.e. + when the legend exists and a legend item associated with this plottable isn't already in the + legend. + + If the plottable needs a more specialized representation in the legend, you can create a + corresponding subclass of \ref QCPPlottableLegendItem and add it to the legend manually instead + of calling this method. + + \see removeFromLegend, QCPLegend::addItem +*/ +bool QCPAbstractPlottable::addToLegend(QCPLegend *legend) +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + if (legend->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; + return false; + } + + if (!legend->hasItemWithPlottable(this)) + { + legend->addItem(new QCPPlottableLegendItem(legend, this)); + return true; + } else + return false; +} + +/*! \overload + + Adds this plottable to the legend of the parent QCustomPlot (\ref QCustomPlot::legend). + + \see removeFromLegend +*/ +bool QCPAbstractPlottable::addToLegend() +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return addToLegend(mParentPlot->legend); +} + +/*! \overload + + Removes the plottable from the specifed \a legend. This means the \ref QCPPlottableLegendItem + that is associated with this plottable is removed. + + Returns true on success, i.e. if the legend exists and a legend item associated with this + plottable was found and removed. + + \see addToLegend, QCPLegend::removeItem +*/ +bool QCPAbstractPlottable::removeFromLegend(QCPLegend *legend) const +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + + if (QCPPlottableLegendItem *lip = legend->itemWithPlottable(this)) + return legend->removeItem(lip); + else + return false; +} + +/*! \overload + + Removes the plottable from the legend of the parent QCustomPlot. + + \see addToLegend +*/ +bool QCPAbstractPlottable::removeFromLegend() const +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return removeFromLegend(mParentPlot->legend); +} + +/* inherits documentation from base class */ +QRect QCPAbstractPlottable::clipRect() const +{ + if (mKeyAxis && mValueAxis) + return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect(); + else + return QRect(); +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractPlottable::selectionCategory() const +{ + return QCP::iSelectPlottables; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable fills. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable scatter points. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint +*/ +void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + + if (mSelectable != QCP::stNone) + { + QCPDataSelection newSelection = details.value(); + QCPDataSelection selectionBefore = mSelection; + if (additive) + { + if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit + { + if (selected()) + setSelection(QCPDataSelection()); + else + setSelection(newSelection); + } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments + { + if (mSelection.contains(newSelection)) // if entire newSelection is already selected, toggle selection + setSelection(mSelection-newSelection); + else + setSelection(mSelection+newSelection); + } + } else + setSelection(newSelection); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable != QCP::stNone) + { + QCPDataSelection selectionBefore = mSelection; + setSelection(QCPDataSelection()); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} +/* end of 'src/plottable.cpp' */ + + +/* including file 'src/item.cpp', size 49269 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemAnchor +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemAnchor + \brief An anchor of an item to which positions can be attached to. + + An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't + control anything on its item, but provides a way to tie other items via their positions to the + anchor. + + For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. + Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can + attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by + calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the + QCPItemRect. This way the start of the line will now always follow the respective anchor location + on the rect item. + + Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an + anchor to other positions. + + To learn how to provide anchors in your own item subclasses, see the subclassing section of the + QCPAbstractItem documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() + + Returns 0 if this instance is merely a QCPItemAnchor, and a valid pointer of type QCPItemPosition* if + it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). + + This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids + dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with + gcc compiler). +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId) : + mName(name), + mParentPlot(parentPlot), + mParentItem(parentItem), + mAnchorId(anchorId) +{ +} + +QCPItemAnchor::~QCPItemAnchor() +{ + // unregister as parent at children: + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } +} + +/*! + Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. + + The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the + parent item, QCPItemAnchor is just an intermediary. +*/ +QPointF QCPItemAnchor::pixelPosition() const +{ + if (mParentItem) + { + if (mAnchorId > -1) + { + return mParentItem->anchorPixelPosition(mAnchorId); + } else + { + qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; + return QPointF(); + } + } else + { + qDebug() << Q_FUNC_INFO << "no parent item set"; + return QPointF(); + } +} + +/*! \internal + + Adds \a pos to the childX list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.contains(pos)) + mChildrenX.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childX list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + +/*! \internal + + Adds \a pos to the childY list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.contains(pos)) + mChildrenY.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childY list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPosition +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPosition + \brief Manages the position of an item. + + Every item has at least one public QCPItemPosition member pointer which provides ways to position the + item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: + \a topLeft and \a bottomRight. + + QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type + defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel + coordinates, as plot coordinates of certain axes, etc. For more advanced plots it is also + possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref + setTypeY). This way an item could be positioned at a fixed pixel distance from the top in the Y + direction, while following a plot coordinate in the X direction. + + A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie + multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords) + are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0) + means directly ontop of the parent anchor. For example, You could attach the \a start position of + a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting point of the line + always be centered under the text label, no matter where the text is moved to. For more advanced + plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see + \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X + direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B + in Y. + + Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent + anchor for other positions. + + To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPosition. This + works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref + setPixelPosition transforms the coordinates appropriately, to make the position appear at the specified + pixel values. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const + + Returns the current position type. + + If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the + type of the X coordinate. In that case rather use \a typeX() and \a typeY(). + + \see setType +*/ + +/*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const + + Returns the current parent anchor. + + If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), + this method returns the parent anchor of the Y coordinate. In that case rather use \a + parentAnchorX() and \a parentAnchorY(). + + \see setParentAnchor +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name) : + QCPItemAnchor(parentPlot, parentItem, name), + mPositionTypeX(ptAbsolute), + mPositionTypeY(ptAbsolute), + mKey(0), + mValue(0), + mParentAnchorX(0), + mParentAnchorY(0) +{ +} + +QCPItemPosition::~QCPItemPosition() +{ + // unregister as parent at children: + // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then + // the setParentAnchor(0) call the correct QCPItemPosition::pixelPosition function instead of QCPItemAnchor::pixelPosition + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } + // unregister as child in parent: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPItemPosition::axisRect() const +{ + return mAxisRect.data(); +} + +/*! + Sets the type of the position. The type defines how the coordinates passed to \ref setCoords + should be handled and how the QCPItemPosition should behave in the plot. + + The possible values for \a type can be separated in two main categories: + + \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords + and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. + By default, the QCustomPlot's x- and yAxis are used. + + \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This + corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref + ptAxisRectRatio. They differ only in the way the absolute position is described, see the + documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify + the axis rect with \ref setAxisRect. By default this is set to the main axis rect. + + Note that the position type \ref ptPlotCoords is only available (and sensible) when the position + has no parent anchor (\ref setParentAnchor). + + If the type is changed, the apparent pixel position on the plot is preserved. This means + the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. + + This method sets the type for both X and Y directions. It is also possible to set different types + for X and Y, see \ref setTypeX, \ref setTypeY. +*/ +void QCPItemPosition::setType(QCPItemPosition::PositionType type) +{ + setTypeX(type); + setTypeY(type); +} + +/*! + This method sets the position type of the X coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeY +*/ +void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) +{ + if (mPositionTypeX != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeX == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeX = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + This method sets the position type of the Y coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeX +*/ +void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) +{ + if (mPositionTypeY != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeY == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeY = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now + follow any position changes of the anchor. The local coordinate system of positions with a parent + anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence + the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) + + if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved + during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position + will be exactly on top of the parent anchor. + + To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to 0. + + If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is + set to \ref ptAbsolute, to keep the position in a valid state. + + This method sets the parent anchor for both X and Y directions. It is also possible to set + different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. +*/ +bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + bool successX = setParentAnchorX(parentAnchor, keepPixelPosition); + bool successY = setParentAnchorY(parentAnchor, keepPixelPosition); + return successX && successY; +} + +/*! + This method sets the parent anchor of the X coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorY +*/ +bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorX(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) + setTypeX(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildX(this); + mParentAnchorX = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(0, coords().y()); + return true; +} + +/*! + This method sets the parent anchor of the Y coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorX +*/ +bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorY(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) + setTypeY(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildY(this); + mParentAnchorY = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(coords().x(), 0); + return true; +} + +/*! + Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type + (\ref setType, \ref setTypeX, \ref setTypeY). + + For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position + on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the + QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the + plot coordinate system defined by the axes set by \ref setAxes. By default those are the + QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available + coordinate types and their meaning. + + If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a + value must also be provided in the different coordinate systems. Here, the X type refers to \a + key, and the Y type refers to \a value. + + \see setPixelPosition +*/ +void QCPItemPosition::setCoords(double key, double value) +{ + mKey = key; + mValue = value; +} + +/*! \overload + + Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the + meaning of \a value of the \ref setCoords(double key, double value) method. +*/ +void QCPItemPosition::setCoords(const QPointF &pos) +{ + setCoords(pos.x(), pos.y()); +} + +/*! + Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It + includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). + + \see setPixelPosition +*/ +QPointF QCPItemPosition::pixelPosition() const +{ + QPointF result; + + // determine X: + switch (mPositionTypeX) + { + case ptAbsolute: + { + result.rx() = mKey; + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + result.rx() = mKey*mParentPlot->viewport().width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mParentPlot->viewport().left(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.rx() = mKey*mAxisRect.data()->width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mAxisRect.data()->left(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + // determine Y: + switch (mPositionTypeY) + { + case ptAbsolute: + { + result.ry() = mValue; + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + result.ry() = mValue*mParentPlot->viewport().height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mParentPlot->viewport().top(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.ry() = mValue*mAxisRect.data()->height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mAxisRect.data()->top(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + result.ry() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + result.ry() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + return result; +} + +/*! + When \ref setType is \ref ptPlotCoords, this function may be used to specify the axes the + coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and + yAxis of the QCustomPlot. +*/ +void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + mKeyAxis = keyAxis; + mValueAxis = valueAxis; +} + +/*! + When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the + coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of + the QCustomPlot. +*/ +void QCPItemPosition::setAxisRect(QCPAxisRect *axisRect) +{ + mAxisRect = axisRect; +} + +/*! + Sets the apparent pixel position. This works no matter what type (\ref setType) this + QCPItemPosition is or what parent-child situation it is in, as coordinates are transformed + appropriately, to make the position finally appear at the specified pixel values. + + Only if the type is \ref ptAbsolute and no parent anchor is set, this function's effect is + identical to that of \ref setCoords. + + \see pixelPosition, setCoords +*/ +void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) +{ + double x = pixelPosition.x(); + double y = pixelPosition.y(); + + switch (mPositionTypeX) + { + case ptAbsolute: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mParentPlot->viewport().left(); + x /= (double)mParentPlot->viewport().width(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mAxisRect.data()->left(); + x /= (double)mAxisRect.data()->width(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + x = mKeyAxis.data()->pixelToCoord(x); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + y = mValueAxis.data()->pixelToCoord(x); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + switch (mPositionTypeY) + { + case ptAbsolute: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mParentPlot->viewport().top(); + y /= (double)mParentPlot->viewport().height(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mAxisRect.data()->top(); + y /= (double)mAxisRect.data()->height(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + x = mKeyAxis.data()->pixelToCoord(y); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + y = mValueAxis.data()->pixelToCoord(y); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + setCoords(x, y); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractItem + \brief The abstract base class for all items in a plot. + + In QCustomPlot, items are supplemental graphical elements that are neither plottables + (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus + plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each + specific item has at least one QCPItemPosition member which controls the positioning. Some items + are defined by more than one coordinate and thus have two or more QCPItemPosition members (For + example, QCPItemRect has \a topLeft and \a bottomRight). + + This abstract base class defines a very basic interface like visibility and clipping. Since this + class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass + yourself to create new items. + + The built-in items are: + + + + + + + + + + +
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
+ + \section items-clipping Clipping + + Items are by default clipped to the main axis rect (they are only visible inside the axis rect). + To make an item visible outside that axis rect, disable clipping via \ref setClipToAxisRect + "setClipToAxisRect(false)". + + On the other hand if you want the item to be clipped to a different axis rect, specify it via + \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and + in principle is independent of the coordinate axes the item might be tied to via its position + members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping + also contains the axes used for the item positions. + + \section items-using Using items + + First you instantiate the item you want to use and add it to the plot: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 + by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just + set the plot coordinates where the line should start/end: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-2 + If we don't want the line to be positioned in plot coordinates but a different coordinate system, + e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-3 + Then we can set the coordinates, this time in pixels: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 + and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 + + For more advanced plots, it is even possible to set different types and parent anchors per X/Y + coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref + QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. + + \section items-subclassing Creating own items + + To create an own item, you implement a subclass of QCPAbstractItem. These are the pure + virtual functions, you must implement: + \li \ref selectTest + \li \ref draw + + See the documentation of those functions for what they need to do. + + \subsection items-positioning Allowing the item to be positioned + + As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall + have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add + a public member of type QCPItemPosition like so: + + \code QCPItemPosition * const myPosition;\endcode + + the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition + instance it points to, can be modified, of course). + The initialization of this pointer is made easy with the \ref createPosition function. Just assign + the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition + takes a string which is the name of the position, typically this is identical to the variable name. + For example, the constructor of QCPItemExample could look like this: + + \code + QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + myPosition(createPosition("myPosition")) + { + // other constructor code + } + \endcode + + \subsection items-drawing The draw function + + To give your item a visual representation, reimplement the \ref draw function and use the passed + QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the + position member(s) via \ref QCPItemPosition::pixelPosition. + + To optimize performance you should calculate a bounding rect first (don't forget to take the pen + width into account), check whether it intersects the \ref clipRect, and only draw the item at all + if this is the case. + + \subsection items-selection The selectTest function + + Your implementation of the \ref selectTest function may use the helpers \ref + QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the + selection test becomes significantly simpler for most items. See the documentation of \ref + selectTest for what the function parameters mean and what the function should return. + + \subsection anchors Providing anchors + + Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public + member, e.g. + + \code QCPItemAnchor * const bottom;\endcode + + and create it in the constructor with the \ref createAnchor function, assigning it a name and an + anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). + Since anchors can be placed anywhere, relative to the item's position(s), your item needs to + provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int + anchorId) function. + + In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel + position when anything attached to the anchor needs to know the coordinates. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QList QCPAbstractItem::positions() const + + Returns all positions of the item in a list. + + \see anchors, position +*/ + +/*! \fn QList QCPAbstractItem::anchors() const + + Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always + also an anchor, the list will also contain the positions of this item. + + \see positions, anchor +*/ + +/* end of documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 + \internal + + Draws this item with the provided \a painter. + + The cliprect of the provided painter is set to the rect returned by \ref clipRect before this + function is called. The clipRect depends on the clipping settings defined by \ref + setClipToAxisRect and \ref setClipAxisRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPAbstractItem::selectionChanged(bool selected) + This signal is emitted when the selection state of this item has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end documentation of signals */ + +/*! + Base class constructor which initializes base class members. +*/ +QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), + mClipToAxisRect(false), + mSelectable(true), + mSelected(false) +{ + parentPlot->registerItem(this); + + QList rects = parentPlot->axisRects(); + if (rects.size() > 0) + { + setClipToAxisRect(true); + setClipAxisRect(rects.first()); + } +} + +QCPAbstractItem::~QCPAbstractItem() +{ + // don't delete mPositions because every position is also an anchor and thus in mAnchors + qDeleteAll(mAnchors); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPAbstractItem::clipAxisRect() const +{ + return mClipAxisRect.data(); +} + +/*! + Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the + entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. + + \see setClipAxisRect +*/ +void QCPAbstractItem::setClipToAxisRect(bool clip) +{ + mClipToAxisRect = clip; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref + setClipToAxisRect is set to true. + + \see setClipToAxisRect +*/ +void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) +{ + mClipAxisRect = rect; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected. + + \see QCustomPlot::setInteractions, setSelected +*/ +void QCPAbstractItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this item is selected or not. When selected, it might use a different visual + appearance (e.g. pen and brush), this depends on the specific item though. + + The entire selection mechanism for items is handled automatically when \ref + QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this + function when you wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by + that name, returns 0. + + This function provides an alternative way to access item positions. Normally, you access + positions direcly by their member pointers (which typically have the same variable name as \a + name). + + \see positions, anchor +*/ +QCPItemPosition *QCPAbstractItem::position(const QString &name) const +{ + for (int i=0; iname() == name) + return mPositions.at(i); + } + qDebug() << Q_FUNC_INFO << "position with name not found:" << name; + return 0; +} + +/*! + Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by + that name, returns 0. + + This function provides an alternative way to access item anchors. Normally, you access + anchors direcly by their member pointers (which typically have the same variable name as \a + name). + + \see anchors, position +*/ +QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const +{ + for (int i=0; iname() == name) + return mAnchors.at(i); + } + qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; + return 0; +} + +/*! + Returns whether this item has an anchor with the specified \a name. + + Note that you can check for positions with this function, too. This is because every position is + also an anchor (QCPItemPosition inherits from QCPItemAnchor). + + \see anchor, position +*/ +bool QCPAbstractItem::hasAnchor(const QString &name) const +{ + for (int i=0; iname() == name) + return true; + } + return false; +} + +/*! \internal + + Returns the rect the visual representation of this item is clipped to. This depends on the + current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. + + If the item is not clipped to an axis rect, QCustomPlot's viewport rect is returned. + + \see draw +*/ +QRect QCPAbstractItem::clipRect() const +{ + if (mClipToAxisRect && mClipAxisRect) + return mClipAxisRect.data()->rect(); + else + return mParentPlot->viewport(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing item lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); +} + +/*! \internal + + A convenience function which returns the selectTest value for a specified \a rect and a specified + click position \a pos. \a filledRect defines whether a click inside the rect should also be + considered a hit or whether only the rect border is sensitive to hits. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + For example, if your item consists of four rects, call this function four times, once for each + rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four + returned values. +*/ +double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const +{ + double result = -1; + + // distance to border: + QList lines; + lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) + << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); + double minDistSqr = std::numeric_limits::max(); + for (int i=0; i mParentPlot->selectionTolerance()*0.99) + { + if (rect.contains(pos)) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/*! \internal + + Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in + item subclasses if they want to provide anchors (QCPItemAnchor). + + For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor + ids and returns the respective pixel points of the specified anchor. + + \see createAnchor +*/ +QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const +{ + qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the position + member (This is needed to provide the name-based \ref position access to positions). + + Don't delete positions created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each position member. Don't create QCPItemPositions with \b new yourself, because they + won't be registered with the item properly. + + \see createAnchor +*/ +QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); + mPositions.append(newPosition); + mAnchors.append(newPosition); // every position is also an anchor + newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); + newPosition->setType(QCPItemPosition::ptPlotCoords); + if (mParentPlot->axisRect()) + newPosition->setAxisRect(mParentPlot->axisRect()); + newPosition->setCoords(0, 0); + return newPosition; +} + +/*! \internal + + Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the anchor + member (This is needed to provide the name based \ref anchor access to anchors). + + The \a anchorId must be a number identifying the created anchor. It is recommended to create an + enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor + to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns + the correct pixel coordinates for the passed anchor id. + + Don't delete anchors created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they + won't be registered with the item properly. + + \see createPosition +*/ +QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); + mAnchors.append(newAnchor); + return newAnchor; +} + +/* inherits documentation from base class */ +void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractItem::selectionCategory() const +{ + return QCP::iSelectItems; +} +/* end of 'src/item.cpp' */ + + +/* including file 'src/core.cpp', size 125037 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCustomPlot +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCustomPlot + + \brief The central class of the library. This is the QWidget which displays the plot and + interacts with the user. + + For tutorials on how to use QCustomPlot, see the website\n + http://www.qcustomplot.com/ +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionRect *QCustomPlot::selectionRect() const + + Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used + to handle and draw selection rect interactions (see \ref setSelectionRectMode). + + \see setSelectionRect +*/ + +/*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const + + Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just + one cell with the main QCPAxisRect inside. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse double click event. +*/ + +/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse press event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. +*/ + +/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse move event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. + + \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, + because the dragging starting point was saved the moment the mouse was pressed. Thus it only has + a meaning for the range drag axes that were set at that moment. If you want to change the drag + axes, consider doing this in the \ref mousePress signal instead. +*/ + +/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse release event. + + It is emitted before QCustomPlot handles any other mechanisms like object selection. So a + slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or + \ref QCPAbstractPlottable::setSelectable. +*/ + +/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse wheel event. + + It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref + QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. +*/ + +/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableDoubleClick +*/ + +/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is double clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableClick +*/ + +/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemDoubleClick +*/ + +/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is double clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemClick +*/ + +/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisDoubleClick +*/ + +/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is double clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisClick +*/ + +/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendDoubleClick +*/ + +/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is double clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendClick +*/ + +/*! \fn void QCustomPlot::selectionChangedByUser() + + This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by + clicking. It is not emitted when the selection state of an object has changed programmatically by + a direct call to setSelected()/setSelection() on an object or by calling \ref + deselectAll. + + In addition to this signal, selectable objects also provide individual signals, for example \ref + QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals + are emitted even if the selection state is changed programmatically. + + See the documentation of \ref setInteractions for details about the selection mechanism. + + \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends +*/ + +/*! \fn void QCustomPlot::beforeReplot() + + This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, afterReplot +*/ + +/*! \fn void QCustomPlot::afterReplot() + + This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, beforeReplot +*/ + +/* end of documentation of signals */ +/* start of documentation of public members */ + +/*! \var QCPAxis *QCustomPlot::xAxis + + A pointer to the primary x Axis (bottom) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis + + A pointer to the primary y Axis (left) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::xAxis2 + + A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis2 + + A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPLegend *QCustomPlot::legend + + A pointer to the default legend of the main axis rect. The legend is invisible by default. Use + QCPLegend::setVisible to change this. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple legends to the plot, use the layout system interface to + access the new legend. For example, legends can be placed inside an axis rect's \ref + QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If + the default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointer becomes 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/* end of documentation of public members */ + +/*! + Constructs a QCustomPlot and sets reasonable default values. +*/ +QCustomPlot::QCustomPlot(QWidget *parent) : + QWidget(parent), + xAxis(0), + yAxis(0), + xAxis2(0), + yAxis2(0), + legend(0), + mBufferDevicePixelRatio(1.0), // will be adapted to primary screen below + mPlotLayout(0), + mAutoAddPlottableToLegend(true), + mAntialiasedElements(QCP::aeNone), + mNotAntialiasedElements(QCP::aeNone), + mInteractions(0), + mSelectionTolerance(8), + mNoAntialiasingOnDrag(false), + mBackgroundBrush(Qt::white, Qt::SolidPattern), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mCurrentLayer(0), + mPlottingHints(QCP::phCacheLabels|QCP::phImmediateRefresh), + mMultiSelectModifier(Qt::ControlModifier), + mSelectionRectMode(QCP::srmNone), + mSelectionRect(0), + mOpenGl(false), + mSymbolPressed(false), + mMouseHasMoved(false), + mMouseEventLayerable(0), + mMouseSignalLayerable(0), + mReplotting(false), + mReplotQueued(false), + mOpenGlMultisamples(16), + mOpenGlAntialiasedElementsBackup(QCP::aeNone), + mOpenGlCacheLabelsBackup(true) +{ + setAttribute(Qt::WA_NoMousePropagation); + setAttribute(Qt::WA_OpaquePaintEvent); + setFocusPolicy(Qt::ClickFocus); + setMouseTracking(true); + QLocale currentLocale = locale(); + currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); + setLocale(currentLocale); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + setBufferDevicePixelRatio(QWidget::devicePixelRatioF()); +# else + setBufferDevicePixelRatio(QWidget::devicePixelRatio()); +# endif +#endif + + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // create initial layers: + mLayers.append(new QCPLayer(this, QLatin1String("background"))); + mLayers.append(new QCPLayer(this, QLatin1String("grid"))); + mLayers.append(new QCPLayer(this, QLatin1String("main"))); + mLayers.append(new QCPLayer(this, QLatin1String("axes"))); + mLayers.append(new QCPLayer(this, QLatin1String("legend"))); + mLayers.append(new QCPLayer(this, QLatin1String("overlay"))); + updateLayerIndices(); + setCurrentLayer(QLatin1String("main")); + layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered); + + // create initial layout, axis rect and legend: + mPlotLayout = new QCPLayoutGrid; + mPlotLayout->initializeParentPlot(this); + mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry + mPlotLayout->setLayer(QLatin1String("main")); + QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true); + mPlotLayout->addElement(0, 0, defaultAxisRect); + xAxis = defaultAxisRect->axis(QCPAxis::atBottom); + yAxis = defaultAxisRect->axis(QCPAxis::atLeft); + xAxis2 = defaultAxisRect->axis(QCPAxis::atTop); + yAxis2 = defaultAxisRect->axis(QCPAxis::atRight); + legend = new QCPLegend; + legend->setVisible(false); + defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); + defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); + + defaultAxisRect->setLayer(QLatin1String("background")); + xAxis->setLayer(QLatin1String("axes")); + yAxis->setLayer(QLatin1String("axes")); + xAxis2->setLayer(QLatin1String("axes")); + yAxis2->setLayer(QLatin1String("axes")); + xAxis->grid()->setLayer(QLatin1String("grid")); + yAxis->grid()->setLayer(QLatin1String("grid")); + xAxis2->grid()->setLayer(QLatin1String("grid")); + yAxis2->grid()->setLayer(QLatin1String("grid")); + legend->setLayer(QLatin1String("legend")); + + // create selection rect instance: + mSelectionRect = new QCPSelectionRect(this); + mSelectionRect->setLayer(QLatin1String("overlay")); + + setViewport(rect()); // needs to be called after mPlotLayout has been created + + replot(rpQueuedReplot); +} + +QCustomPlot::~QCustomPlot() +{ + clearPlottables(); + clearItems(true); + + if (mPlotLayout) + { + delete mPlotLayout; + mPlotLayout = 0; + } + + mCurrentLayer = 0; + qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed + mLayers.clear(); +} + +void QCustomPlot::setSymbolPos(const QPoint pos) +{ + mSymbolPos = QPoint(pos.x(), 0); +} + +/*! + Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is + removed from there. + + \see setNotAntialiasedElements +*/ +void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) +{ + mAntialiasedElements = antialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. + + See \ref setAntialiasedElements for details. + + \see setNotAntialiasedElement +*/ +void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) +{ + if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements &= ~antialiasedElement; + else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements |= antialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets which elements are forcibly drawn not antialiased as an \a or combination of + QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is + removed from there. + + \see setAntialiasedElements +*/ +void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) +{ + mNotAntialiasedElements = notAntialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. + + See \ref setNotAntialiasedElements for details. + + \see setAntialiasedElement +*/ +void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) +{ + if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements &= ~notAntialiasedElement; + else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements |= notAntialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the + plottable to the legend (QCustomPlot::legend). + + \see addGraph, QCPLegend::addItem +*/ +void QCustomPlot::setAutoAddPlottableToLegend(bool on) +{ + mAutoAddPlottableToLegend = on; +} + +/*! + Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction + enums. There are the following types of interactions: + + Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the + respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. + For details how to control which axes the user may drag/zoom and in what orientations, see \ref + QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, + \ref QCPAxisRect::setRangeZoomAxes. + + Plottable data selection is controlled by \ref QCP::iSelectPlottables. If \ref + QCP::iSelectPlottables is set, the user may select plottables (graphs, curves, bars,...) and + their data by clicking on them or in their vicinity (\ref setSelectionTolerance). Whether the + user can actually select a plottable and its data can further be restricted with the \ref + QCPAbstractPlottable::setSelectable method on the specific plottable. For details, see the + special page about the \ref dataselection "data selection mechanism". To retrieve a list of all + currently selected plottables, call \ref selectedPlottables. If you're only interested in + QCPGraphs, you may use the convenience function \ref selectedGraphs. + + Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user + may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find + out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of + all currently selected items, call \ref selectedItems. + + Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user + may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick + labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for + each axis. To retrieve a list of all axes that currently contain selected parts, call \ref + selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). + + Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may + select the legend itself or individual items by clicking on them. What parts exactly are + selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the + legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To + find out which child items are selected, call \ref QCPLegend::selectedItems. + + All other selectable elements The selection of all other selectable objects (e.g. + QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the + user may select those objects by clicking on them. To find out which are currently selected, you + need to check their selected state explicitly. + + If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is + emitted. Each selectable object additionally emits an individual selectionChanged signal whenever + their selection state has changed, i.e. not only by user interaction. + + To allow multiple objects to be selected by holding the selection modifier (\ref + setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. + + \note In addition to the selection mechanism presented here, QCustomPlot always emits + corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and + \ref plottableDoubleClick for example. + + \see setInteraction, setSelectionTolerance +*/ +void QCustomPlot::setInteractions(const QCP::Interactions &interactions) +{ + mInteractions = interactions; +} + +/*! + Sets the single \a interaction of this QCustomPlot to \a enabled. + + For details about the interaction system, see \ref setInteractions. + + \see setInteractions +*/ +void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) +{ + if (!enabled && mInteractions.testFlag(interaction)) + mInteractions &= ~interaction; + else if (enabled && !mInteractions.testFlag(interaction)) + mInteractions |= interaction; +} + +/*! + Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or + not. + + If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a + potential selection when the minimum distance between the click position and the graph line is + smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks + directly inside the area and ignore this selection tolerance. In other words, it only has meaning + for parts of objects that are too thin to exactly hit with a click and thus need such a + tolerance. + + \see setInteractions, QCPLayerable::selectTest +*/ +void QCustomPlot::setSelectionTolerance(int pixels) +{ + mSelectionTolerance = pixels; +} + +/*! + Sets whether antialiasing is disabled for this QCustomPlot while the user is dragging axes + ranges. If many objects, especially plottables, are drawn antialiased, this greatly improves + performance during dragging. Thus it creates a more responsive user experience. As soon as the + user stops dragging, the last replot is done with normal antialiasing, to restore high image + quality. + + \see setAntialiasedElements, setNotAntialiasedElements +*/ +void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) +{ + mNoAntialiasingOnDrag = enabled; +} + +/*! + Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. + + \see setPlottingHint +*/ +void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) +{ + mPlottingHints = hints; +} + +/*! + Sets the specified plotting \a hint to \a enabled. + + \see setPlottingHints +*/ +void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) +{ + QCP::PlottingHints newHints = mPlottingHints; + if (!enabled) + newHints &= ~hint; + else + newHints |= hint; + + if (newHints != mPlottingHints) + setPlottingHints(newHints); +} + +/*! + Sets the keyboard modifier that will be recognized as multi-select-modifier. + + If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple + objects (or data points) by clicking on them one after the other while holding down \a modifier. + + By default the multi-select-modifier is set to Qt::ControlModifier. + + \see setInteractions +*/ +void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) +{ + mMultiSelectModifier = modifier; +} + +/*! + Sets how QCustomPlot processes mouse click-and-drag interactions by the user. + + If \a mode is \ref QCP::srmNone, the mouse drag is forwarded to the underlying objects. For + example, QCPAxisRect may process a mouse drag by dragging axis ranges, see \ref + QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref + selectionRect) becomes activated and allows e.g. rect zooming and data point selection. + + If you wish to provide your user both with axis range dragging and data selection/range zooming, + use this method to switch between the modes just before the interaction is processed, e.g. in + reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether + the user is holding a certain keyboard modifier, and then decide which \a mode shall be set. + + If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the + interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes + will keep the selection rect active. Upon completion of the interaction, the behaviour is as + defined by the currently set \a mode, not the mode that was set when the interaction started. + + \see setInteractions, setSelectionRect, QCPSelectionRect +*/ +void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) +{ + if (mSelectionRect) + { + if (mode == QCP::srmNone) + mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect + + // disconnect old connections: + if (mSelectionRectMode == QCP::srmSelect) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + + // establish new ones: + if (mode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } + + mSelectionRectMode = mode; +} + +/*! + Sets the \ref QCPSelectionRect instance that QCustomPlot will use if \a mode is not \ref + QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of + the passed \a selectionRect. It can be accessed later via \ref selectionRect. + + This method is useful if you wish to replace the default QCPSelectionRect instance with an + instance of a QCPSelectionRect subclass, to introduce custom behaviour of the selection rect. + + \see setSelectionRectMode +*/ +void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) +{ + if (mSelectionRect) + delete mSelectionRect; + + mSelectionRect = selectionRect; + + if (mSelectionRect) + { + // establish connections with new selection rect: + if (mSelectionRectMode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } +} + +/*! + \warning This is still an experimental feature and its performance depends on the system that it + runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering + might cause context conflicts on some systems. + + This method allows to enable OpenGL plot rendering, for increased plotting performance of + graphically demanding plots (thick lines, translucent fills, etc.). + + If \a enabled is set to true, QCustomPlot will try to initialize OpenGL and, if successful, + continue plotting with hardware acceleration. The parameter \a multisampling controls how many + samples will be used per pixel, it essentially controls the antialiasing quality. If \a + multisampling is set too high for the current graphics hardware, the maximum allowed value will + be used. + + You can test whether switching to OpenGL rendering was successful by checking whether the + according getter \a QCustomPlot::openGl() returns true. If the OpenGL initialization fails, + rendering continues with the regular software rasterizer, and an according qDebug output is + generated. + + If switching to OpenGL was successful, this method disables label caching (\ref setPlottingHint + "setPlottingHint(QCP::phCacheLabels, false)") and turns on QCustomPlot's antialiasing override + for all elements (\ref setAntialiasedElements "setAntialiasedElements(QCP::aeAll)"), leading to a + higher quality output. The antialiasing override allows for pixel-grid aligned drawing in the + OpenGL paint device. As stated before, in OpenGL rendering the actual antialiasing of the plot is + controlled with \a multisampling. If \a enabled is set to false, the antialiasing/label caching + settings are restored to what they were before OpenGL was enabled, if they weren't altered in the + meantime. + + \note OpenGL support is only enabled if QCustomPlot is compiled with the macro \c QCUSTOMPLOT_USE_OPENGL + defined. This define must be set before including the QCustomPlot header both during compilation + of the QCustomPlot library as well as when compiling your application. It is best to just include + the line DEFINES += QCUSTOMPLOT_USE_OPENGL in the respective qmake project files. + \note If you are using a Qt version before 5.0, you must also add the module "opengl" to your \c + QT variable in the qmake project files. For Qt versions 5.0 and higher, QCustomPlot switches to a + newer OpenGL interface which is already in the "gui" module. +*/ +void QCustomPlot::setOpenGl(bool enabled, int multisampling) +{ + mOpenGlMultisamples = qMax(0, multisampling); +#ifdef QCUSTOMPLOT_USE_OPENGL + mOpenGl = enabled; + if (mOpenGl) + { + if (setupOpenGl()) + { + // backup antialiasing override and labelcaching setting so we can restore upon disabling OpenGL + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // set antialiasing override to antialias all (aligns gl pixel grid properly), and disable label caching (would use software rasterizer for pixmap caches): + setAntialiasedElements(QCP::aeAll); + setPlottingHint(QCP::phCacheLabels, false); + } else + { + qDebug() << Q_FUNC_INFO << "Failed to enable OpenGL, continuing plotting without hardware acceleration."; + mOpenGl = false; + } + } else + { + // restore antialiasing override and labelcaching to what it was before enabling OpenGL, if nobody changed it in the meantime: + if (mAntialiasedElements == QCP::aeAll) + setAntialiasedElements(mOpenGlAntialiasedElementsBackup); + if (!mPlottingHints.testFlag(QCP::phCacheLabels)) + setPlottingHint(QCP::phCacheLabels, mOpenGlCacheLabelsBackup); + freeOpenGl(); + } + // recreate all paint buffers: + mPaintBuffers.clear(); + setupPaintBuffers(); +#else + Q_UNUSED(enabled) + qDebug() << Q_FUNC_INFO << "QCustomPlot can't use OpenGL because QCUSTOMPLOT_USE_OPENGL was not defined during compilation (add 'DEFINES += QCUSTOMPLOT_USE_OPENGL' to your qmake .pro file)"; +#endif +} + +/*! + Sets the viewport of this QCustomPlot. Usually users of QCustomPlot don't need to change the + viewport manually. + + The viewport is the area in which the plot is drawn. All mechanisms, e.g. margin caluclation take + the viewport to be the outer border of the plot. The viewport normally is the rect() of the + QCustomPlot widget, i.e. a rect with top left (0, 0) and size of the QCustomPlot widget. + + Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically + an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger + and contains also the axes themselves, their tick numbers, their labels, or even additional axis + rects, color scales and other layout elements. + + This function is used to allow arbitrary size exports with \ref toPixmap, \ref savePng, \ref + savePdf, etc. by temporarily changing the viewport size. +*/ +void QCustomPlot::setViewport(const QRect &rect) +{ + mViewport = rect; + if (mPlotLayout) + mPlotLayout->setOuterRect(mViewport); +} + +/*! + Sets the device pixel ratio used by the paint buffers of this QCustomPlot instance. + + Normally, this doesn't need to be set manually, because it is initialized with the regular \a + QWidget::devicePixelRatio which is configured by Qt to fit the display device (e.g. 1 for normal + displays, 2 for High-DPI displays). + + Device pixel ratios are supported by Qt only for Qt versions since 5.4. If this method is called + when QCustomPlot is being used with older Qt versions, outputs an according qDebug message and + leaves the internal buffer device pixel ratio at 1.0. +*/ +void QCustomPlot::setBufferDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mBufferDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBufferDevicePixelRatio = ratio; + for (int i=0; isetDevicePixelRatio(mBufferDevicePixelRatio); + // Note: axis label cache has devicePixelRatio as part of cache hash, so no need to manually clear cache here +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mBufferDevicePixelRatio = 1.0; +#endif + } +} + +/*! + Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn + below all other objects in the plot. + + For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is + preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will + first be filled with that brush, before drawing the background pixmap. This can be useful for + background pixmaps with translucent areas. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! + Sets the background brush of the viewport (see \ref setViewport). + + Before drawing everything else, the background is filled with \a brush. If a background pixmap + was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport + before the background pixmap is drawn. This can be useful for background pixmaps with translucent + areas. + + Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be + useful for exporting to image formats which support transparency, e.g. \ref savePng. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the viewport, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is + set to true, control whether and how the aspect ratio of the original pixmap is preserved with + \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the viewport dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCustomPlot::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this + function to define whether and how the aspect ratio of the original pixmap is preserved. + + \see setBackground, setBackgroundScaled +*/ +void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the plottable with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + plottable, see QCustomPlot::plottable() + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + { + return mPlottables.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last plottable that was added to the plot. If there are no plottables in the plot, + returns 0. + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable() +{ + if (!mPlottables.isEmpty()) + { + return mPlottables.last(); + } else + return 0; +} + +/*! + Removes the specified plottable from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). + + Returns true on success. + + \see clearPlottables +*/ +bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); + return false; + } + + // remove plottable from legend: + plottable->removeFromLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.removeOne(graph); + // remove plottable: + delete plottable; + mPlottables.removeOne(plottable); + return true; +} + +/*! \overload + + Removes and deletes the plottable by its \a index. +*/ +bool QCustomPlot::removePlottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + return removePlottable(mPlottables[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all plottables from the plot and deletes them. Corresponding legend items are also + removed from the default legend (QCustomPlot::legend). + + Returns the number of plottables removed. + + \see removePlottable +*/ +int QCustomPlot::clearPlottables() +{ + int c = mPlottables.size(); + for (int i=c-1; i >= 0; --i) + removePlottable(mPlottables[i]); + return c; +} + +/*! + Returns the number of currently existing plottables in the plot + + \see plottable +*/ +int QCustomPlot::plottableCount() const +{ + return mPlottables.size(); +} + +/*! + Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. + + There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. + + \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedPlottables() const +{ + QList result; + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (plottable->selected()) + result.append(plottable); + } + return result; +} + +/*! + Returns the plottable at the pixel position \a pos. Plottables that only consist of single lines + (like graphs) have a tolerance band around them, see \ref setSelectionTolerance. If multiple + plottables come into consideration, the one closest to \a pos is returned. + + If \a onlySelectable is true, only plottables that are selectable + (QCPAbstractPlottable::setSelectable) are considered. + + If there is no plottable at \a pos, the return value is 0. + + \see itemAt, layoutElementAt +*/ +QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractPlottable *resultPlottable = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (onlySelectable && !plottable->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPabstractPlottable::selectable + continue; + if ((plottable->keyAxis()->axisRect()->rect() & plottable->valueAxis()->axisRect()->rect()).contains(pos.toPoint())) // only consider clicks inside the rect that is spanned by the plottable's key/value axes + { + double currentDistance = plottable->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultPlottable = plottable; + resultDistance = currentDistance; + } + } + } + + return resultPlottable; +} + +/*! + Returns whether this QCustomPlot instance contains the \a plottable. +*/ +bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const +{ + return mPlottables.contains(plottable); +} + +/*! + Returns the graph with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last created + graph, see QCustomPlot::graph() + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph(int index) const +{ + if (index >= 0 && index < mGraphs.size()) + { + return mGraphs.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, + returns 0. + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph() const +{ + if (!mGraphs.isEmpty()) + { + return mGraphs.last(); + } else + return 0; +} + +/*! + Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the + bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a + keyAxis and \a valueAxis must reside in this QCustomPlot. + + \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically + "y") for the graph. + + Returns a pointer to the newly created graph, or 0 if adding the graph failed. + + \see graph, graphCount, removeGraph, clearGraphs +*/ +QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + if (!keyAxis) keyAxis = xAxis; + if (!valueAxis) valueAxis = yAxis; + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)"; + return 0; + } + if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; + return 0; + } + + QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); + newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); + return newGraph; +} + +/*! + Removes the specified \a graph from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in + the plot have a channel fill set towards the removed graph, the channel fill property of those + graphs is reset to zero (no channel fill). + + Returns true on success. + + \see clearGraphs +*/ +bool QCustomPlot::removeGraph(QCPGraph *graph) +{ + return removePlottable(graph); +} + +/*! \overload + + Removes and deletes the graph by its \a index. +*/ +bool QCustomPlot::removeGraph(int index) +{ + if (index >= 0 && index < mGraphs.size()) + return removeGraph(mGraphs[index]); + else + return false; +} + +/*! + Removes all graphs from the plot and deletes them. Corresponding legend items are also removed + from the default legend (QCustomPlot::legend). + + Returns the number of graphs removed. + + \see removeGraph +*/ +int QCustomPlot::clearGraphs() +{ + int c = mGraphs.size(); + for (int i=c-1; i >= 0; --i) + removeGraph(mGraphs[i]); + return c; +} + +/*! + Returns the number of currently existing graphs in the plot + + \see graph, addGraph +*/ +int QCustomPlot::graphCount() const +{ + return mGraphs.size(); +} + +/*! + Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. + + If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, + etc., use \ref selectedPlottables. + + \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedGraphs() const +{ + QList result; + foreach (QCPGraph *graph, mGraphs) + { + if (graph->selected()) + result.append(graph); + } + return result; +} + +/*! + Returns the item with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + item, see QCustomPlot::item() + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item(int index) const +{ + if (index >= 0 && index < mItems.size()) + { + return mItems.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last item that was added to this plot. If there are no items in the plot, + returns 0. + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item() const +{ + if (!mItems.isEmpty()) + { + return mItems.last(); + } else + return 0; +} + +/*! + Removes the specified item from the plot and deletes it. + + Returns true on success. + + \see clearItems +*/ +bool QCustomPlot::removeItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + delete item; + mItems.removeOne(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); + return false; + } +} + +/*! \overload + + Removes and deletes the item by its \a index. +*/ +bool QCustomPlot::removeItem(int index) +{ + if (index >= 0 && index < mItems.size()) + return removeItem(mItems[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all items from the plot and deletes them. + + Returns the number of items removed. + + \see removeItem +*/ +int QCustomPlot::clearItems(bool clearTitle) +{ + int c = mItems.size(); + for (int i=c-1; i >= 0; --i) + { + if(mItems[i]->objectName() == "m_trendTitle") + { + if(!clearTitle) + { + continue; + } + } + removeItem(mItems[i]); + } + return c; +} + +/*! + Returns the number of currently existing items in the plot + + \see item +*/ +int QCustomPlot::itemCount() const +{ + return mItems.size(); +} + +/*! + Returns a list of the selected items. If no items are currently selected, the list is empty. + + \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected +*/ +QList QCustomPlot::selectedItems() const +{ + QList result; + foreach (QCPAbstractItem *item, mItems) + { + if (item->selected()) + result.append(item); + } + return result; +} + +/*! + Returns the item at the pixel position \a pos. Items that only consist of single lines (e.g. \ref + QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref + setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is + returned. + + If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are + considered. + + If there is no item at \a pos, the return value is 0. + + \see plottableAt, layoutElementAt +*/ +QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractItem *resultItem = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractItem *item, mItems) + { + if (onlySelectable && !item->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable + continue; + if (!item->clipToAxisRect() || item->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it + { + double currentDistance = item->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultItem = item; + resultDistance = currentDistance; + } + } + } + + return resultItem; +} + +/*! + Returns whether this QCustomPlot contains the \a item. + + \see item +*/ +bool QCustomPlot::hasItem(QCPAbstractItem *item) const +{ + return mItems.contains(item); +} + +/*! + Returns the layer with the specified \a name. If there is no layer with the specified name, 0 is + returned. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(const QString &name) const +{ + foreach (QCPLayer *layer, mLayers) + { + if (layer->name() == name) + return layer; + } + return 0; +} + +/*! \overload + + Returns the layer by \a index. If the index is invalid, 0 is returned. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(int index) const +{ + if (index >= 0 && index < mLayers.size()) + { + return mLayers.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Returns the layer that is set as current layer (see \ref setCurrentLayer). +*/ +QCPLayer *QCustomPlot::currentLayer() const +{ + return mCurrentLayer; +} + +/*! + Sets the layer with the specified \a name to be the current layer. All layerables (\ref + QCPLayerable), e.g. plottables and items, are created on the current layer. + + Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer +*/ +bool QCustomPlot::setCurrentLayer(const QString &name) +{ + if (QCPLayer *newCurrentLayer = layer(name)) + { + return setCurrentLayer(newCurrentLayer); + } else + { + qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; + return false; + } +} + +/*! \overload + + Sets the provided \a layer to be the current layer. + + Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. + + \see addLayer, moveLayer, removeLayer +*/ +bool QCustomPlot::setCurrentLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + + mCurrentLayer = layer; + return true; +} + +/*! + Returns the number of currently existing layers in the plot + + \see layer, addLayer +*/ +int QCustomPlot::layerCount() const +{ + return mLayers.size(); +} + +/*! + Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which + must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. + + Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a + valid layer inside this QCustomPlot. + + If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. + + For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. + + \see layer, moveLayer, removeLayer +*/ +bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!otherLayer) + otherLayer = mLayers.last(); + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + if (layer(name)) + { + qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; + return false; + } + + QCPLayer *newLayer = new QCPLayer(this, name); + mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); + updateLayerIndices(); + setupPaintBuffers(); // associates new layer with the appropriate paint buffer + return true; +} + +/*! + Removes the specified \a layer and returns true on success. + + All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below + \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both + cases, the total rendering order of all layerables in the QCustomPlot is preserved. + + If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom + layer) becomes the new current layer. + + It is not possible to remove the last layer of the plot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::removeLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (mLayers.size() < 2) + { + qDebug() << Q_FUNC_INFO << "can't remove last layer"; + return false; + } + + // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) + int removedIndex = layer->index(); + bool isFirstLayer = removedIndex==0; + QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); + QList children = layer->children(); + if (isFirstLayer) // prepend in reverse order (so order relative to each other stays the same) + { + for (int i=children.size()-1; i>=0; --i) + children.at(i)->moveToLayer(targetLayer, true); + } else // append normally + { + for (int i=0; imoveToLayer(targetLayer, false); + } + // if removed layer is current layer, change current layer to layer below/above: + if (layer == mCurrentLayer) + setCurrentLayer(targetLayer); + // invalidate the paint buffer that was responsible for this layer: + if (!layer->mPaintBuffer.isNull()) + layer->mPaintBuffer.data()->setInvalidated(); + // remove layer: + delete layer; + mLayers.removeOne(layer); + updateLayerIndices(); + return true; +} + +/*! + Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or + below is controlled with \a insertMode. + + Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the + QCustomPlot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + + if (layer->index() > otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); + else if (layer->index() < otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); + + // invalidate the paint buffers that are responsible for the layers: + if (!layer->mPaintBuffer.isNull()) + layer->mPaintBuffer.data()->setInvalidated(); + if (!otherLayer->mPaintBuffer.isNull()) + otherLayer->mPaintBuffer.data()->setInvalidated(); + + updateLayerIndices(); + return true; +} + +/*! + Returns the number of axis rects in the plot. + + All axis rects can be accessed via QCustomPlot::axisRect(). + + Initially, only one axis rect exists in the plot. + + \see axisRect, axisRects +*/ +int QCustomPlot::axisRectCount() const +{ + return axisRects().size(); +} + +/*! + Returns the axis rect with \a index. + + Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were + added, all of them may be accessed with this function in a linear fashion (even when they are + nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). + + \see axisRectCount, axisRects +*/ +QCPAxisRect *QCustomPlot::axisRect(int index) const +{ + const QList rectList = axisRects(); + if (index >= 0 && index < rectList.size()) + { + return rectList.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "invalid axis rect index" << index; + return 0; + } +} + +/*! + Returns all axis rects in the plot. + + \see axisRectCount, axisRect +*/ +QList QCustomPlot::axisRects() const +{ + QList result; + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) + { + if (element) + { + elementStack.push(element); + if (QCPAxisRect *ar = qobject_cast(element)) + result.append(ar); + } + } + } + + return result; +} + +/*! + Returns the layout element at pixel position \a pos. If there is no element at that position, + returns 0. + + Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on + any of its parent elements is set to false, it will not be considered. + + \see itemAt, plottableAt +*/ +QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const +{ + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + break; + } + } + } + return currentElement; +} + +/*! + Returns the layout element of type \ref QCPAxisRect at pixel position \a pos. This method ignores + other layout elements even if they are visually in front of the axis rect (e.g. a \ref + QCPLegend). If there is no axis rect at that position, returns 0. + + Only visible axis rects are used. If \ref QCPLayoutElement::setVisible on the axis rect itself or + on any of its parent elements is set to false, it will not be considered. + + \see layoutElementAt +*/ +QCPAxisRect *QCustomPlot::axisRectAt(const QPointF &pos) const +{ + QCPAxisRect *result = 0; + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + if (QCPAxisRect *ar = qobject_cast(currentElement)) + result = ar; + break; + } + } + } + return result; +} + +/*! + Returns the axes that currently have selected parts, i.e. whose selection state is not \ref + QCPAxis::spNone. + + \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, + QCPAxis::setSelectableParts +*/ +QList QCustomPlot::selectedAxes() const +{ + QList result, allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + { + if (axis->selectedParts() != QCPAxis::spNone) + result.append(axis); + } + + return result; +} + +/*! + Returns the legends that currently have selected parts, i.e. whose selection state is not \ref + QCPLegend::spNone. + + \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, + QCPLegend::setSelectableParts, QCPLegend::selectedItems +*/ +QList QCustomPlot::selectedLegends() const +{ + QList result; + + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) + { + if (subElement) + { + elementStack.push(subElement); + if (QCPLegend *leg = qobject_cast(subElement)) + { + if (leg->selectedParts() != QCPLegend::spNone) + result.append(leg); + } + } + } + } + + return result; +} + +/*! + Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. + + Since calling this function is not a user interaction, this does not emit the \ref + selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the + objects were previously selected. + + \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends +*/ +void QCustomPlot::deselectAll() +{ + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + layerable->deselectEvent(0); + } +} + +/*! + Causes a complete replot into the internal paint buffer(s). Finally, the widget surface is + refreshed with the new buffer contents. This is the method that must be called to make changes to + the plot, e.g. on the axis ranges or data points of graphs, visible. + + The parameter \a refreshPriority can be used to fine-tune the timing of the replot. For example + if your application calls \ref replot very quickly in succession (e.g. multiple independent + functions change some aspects of the plot and each wants to make sure the change gets replotted), + it is advisable to set \a refreshPriority to \ref QCustomPlot::rpQueuedReplot. This way, the + actual replotting is deferred to the next event loop iteration. Multiple successive calls of \ref + replot with this priority will only cause a single replot, avoiding redundant replots and + improving performance. + + Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the + QCustomPlot widget and user interactions (object selection and range dragging/zooming). + + Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref + afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two + signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite + recursion. + + If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to + replot only that specific layer via \ref QCPLayer::replot. See the documentation there for + details. +*/ +void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) +{ + if (refreshPriority == QCustomPlot::rpQueuedReplot) + { + if (!mReplotQueued) + { + mReplotQueued = true; + QTimer::singleShot(0, this, SLOT(replot())); + } + return; + } + + if (mReplotting) // incase signals loop back to replot slot + return; + mReplotting = true; + mReplotQueued = false; + emit beforeReplot(); + + updateLayout(); + // draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers: + setupPaintBuffers(); + foreach (QCPLayer *layer, mLayers) + layer->drawToPaintBuffer(); + for (int i=0; isetInvalidated(false); + + if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh) + repaint(); + else + update(); + + emit afterReplot(); + mReplotting = false; +} + +/*! + Rescales the axes such that all plottables (like graphs) in the plot are fully visible. + + if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true + (QCPLayerable::setVisible), will be used to rescale the axes. + + \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale +*/ +void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) +{ + QList allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + axis->rescale(onlyVisiblePlottables); +} + +/*! + Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale + of texts and lines will be derived from the specified \a width and \a height. This means, the + output will look like the normal on-screen output of a QCustomPlot widget with the corresponding + pixel width and height. If either \a width or \a height is zero, the exported image will have the + same dimensions as the QCustomPlot widget currently has. + + Setting \a exportPen to \ref QCP::epNoCosmetic allows to disable the use of cosmetic pens when + drawing to the PDF file. Cosmetic pens are pens with numerical width 0, which are always drawn as + a one pixel wide line, no matter what zoom factor is set in the PDF-Viewer. For more information + about cosmetic pens, see the QPainter and QPen documentation. + + The objects of the plot will appear in the current selection state. If you don't want any + selected objects to be painted in their selected look, deselect everything with \ref deselectAll + before calling this function. + + Returns true on success. + + \warning + \li If you plan on editing the exported PDF file with a vector graphics editor like Inkscape, it + is advised to set \a exportPen to \ref QCP::epNoCosmetic to avoid losing those cosmetic lines + (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). + \li If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting + PDF file. + + \note On Android systems, this method does nothing and issues an according qDebug warning + message. This is also the case if for other reasons the define flag \c QT_NO_PRINTER is set. + + \see savePng, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::ExportPen exportPen, const QString &pdfCreator, const QString &pdfTitle) +{ + bool success = false; +#ifdef QT_NO_PRINTER + Q_UNUSED(fileName) + Q_UNUSED(exportPen) + Q_UNUSED(width) + Q_UNUSED(height) + Q_UNUSED(pdfCreator) + Q_UNUSED(pdfTitle) + qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created."; +#else + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + QPrinter printer(QPrinter::ScreenResolution); + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setColorMode(QPrinter::Color); + printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator); + printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle); + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + printer.setFullPage(true); + printer.setPaperSize(viewport().size(), QPrinter::DevicePixel); +#else + QPageLayout pageLayout; + pageLayout.setMode(QPageLayout::FullPageMode); + pageLayout.setOrientation(QPageLayout::Portrait); + pageLayout.setMargins(QMarginsF(0, 0, 0, 0)); + pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch)); + printer.setPageLayout(pageLayout); +#endif + QCPPainter printpainter; + if (printpainter.begin(&printer)) + { + printpainter.setMode(QCPPainter::pmVectorized); + printpainter.setMode(QCPPainter::pmNoCaching); + printpainter.setMode(QCPPainter::pmNonCosmetic, exportPen==QCP::epNoCosmetic); + printpainter.setWindow(mViewport); + if (mBackgroundBrush.style() != Qt::NoBrush && + mBackgroundBrush.color() != Qt::white && + mBackgroundBrush.color() != Qt::transparent && + mBackgroundBrush.color().alpha() > 0) // draw pdf background color if not white/transparent + printpainter.fillRect(viewport(), mBackgroundBrush); + draw(&printpainter); + printpainter.end(); + success = true; + } + setViewport(oldViewport); +#endif // QT_NO_PRINTER + return success; +} + +/*! + Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the PNG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + If you want the PNG to have a transparent background, call \ref setBackground(const QBrush &brush) + with no brush (Qt::NoBrush) or a transparent color (Qt::transparent), before saving. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "PNG", quality, resolution, resolutionUnit); +} + +/*! + Saves a JPEG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the JPEG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveBmp, saveRastered +*/ +bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "JPG", quality, resolution, resolutionUnit); +} + +/*! + Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the BMP format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveJpg, saveRastered +*/ +bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "BMP", -1, resolution, resolutionUnit); +} + +/*! \internal + + Returns a minimum size hint that corresponds to the minimum size of the top level layout + (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum + size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. + This is especially important, when placed in a QLayout where other components try to take in as + much space as possible (e.g. QMdiArea). +*/ +QSize QCustomPlot::minimumSizeHint() const +{ + return mPlotLayout->minimumOuterSizeHint(); +} + +/*! \internal + + Returns a size hint that is the same as \ref minimumSizeHint. + +*/ +QSize QCustomPlot::sizeHint() const +{ + return mPlotLayout->minimumOuterSizeHint(); +} + +/*! \internal + + Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but + draws the internal buffer on the widget surface. +*/ +void QCustomPlot::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QCPPainter painter(this); + if (!painter.isActive()) + { + return; + } + painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem + if (mBackgroundBrush.style() != Qt::NoBrush) + painter.fillRect(mViewport, mBackgroundBrush); + drawBackground(&painter); + for (int bufferIndex = 0; bufferIndex < mPaintBuffers.size(); ++bufferIndex) + mPaintBuffers.at(bufferIndex)->draw(&painter); + + if(!axisRect()->isScaleRight()) + { + //< 横坐标有效值 + int x = mSymbolPos.x() >= yAxis->axisRect()->left() ? mSymbolPos.x() : yAxis->axisRect()->left(); + x = x <= yAxis->axisRect()->right() ? x : yAxis->axisRect()->right(); + //< 纵坐标 + int y = yAxis->axisRect()->top(); + + painter.save(); + painter.setPen(QColor(182, 194, 205)); + painter.setBrush(QColor(182, 194, 205)); + painter.setAntialiasing(true); + QPolygon polygon; + polygon.append(QPoint(x, y)); + polygon.append(QPoint(x + 3, y - 5)); + polygon.append(QPoint(x + 3, 0)); + polygon.append(QPoint(x - 3, 0)); + polygon.append(QPoint(x - 3, y - 5)); + painter.drawPolygon(polygon); + painter.drawLine(QPoint(x, y), QPoint(x, yAxis->axisRect()->bottom())); + painter.restore(); + } +} + +/*! \internal + + Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect + of mPlotLayout) is resized appropriately. Finally a \ref replot is performed. +*/ +void QCustomPlot::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + // resize and repaint the buffer: + setViewport(rect()); + replot(rpQueuedRefresh); // queued refresh is important here, to prevent painting issues in some contexts (e.g. MDI subwindow) +} + +/*! \internal + + Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then + determines the layerable under the cursor and forwards the event to it. Finally, emits the + specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref + axisDoubleClick, etc.). + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit mouseDoubleClick(event); + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + // determine layerable under the cursor (this event is called instead of the second press event in a double-click): + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->mouseDoubleClickEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + + // emit specialized object double click signals: + if (!candidates.isEmpty()) + { + if (QCPAbstractPlottable *ap = qobject_cast(candidates.first())) + { + int dataIndex = 0; + if (!details.first().value().isEmpty()) + dataIndex = details.first().value().dataRange().begin(); + emit plottableDoubleClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(candidates.first())) + emit axisDoubleClick(ax, details.first().value(), event); + else if (QCPAbstractItem *ai = qobject_cast(candidates.first())) + emit itemDoubleClick(ai, event); + else if (QCPLegend *lg = qobject_cast(candidates.first())) + emit legendDoubleClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(candidates.first())) + emit legendDoubleClick(li->parentLegend(), li, event); + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is pressed. Emits the mousePress signal. + + If the current \ref setSelectionRectMode is not \ref QCP::srmNone, passes the event to the + selection rect. Otherwise determines the layerable under the cursor and forwards the event to it. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCustomPlot::mousePressEvent(QMouseEvent *event) +{ + if(cursor().shape() == Qt::SizeHorCursor && event->button() == Qt::LeftButton) + { + mSymbolPos = event->pos(); + mSymbolPressed = true; + return; + } + + emit mousePress(event); + // save some state to tell in releaseEvent whether it was a click: + + + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + if (mSelectionRect && mSelectionRectMode != QCP::srmNone) + { + if (mSelectionRectMode != QCP::srmZoom || qobject_cast(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect + mSelectionRect->startSelection(event); + } else + { + // no selection rect interaction, prepare for click signal emission and forward event to layerable under the cursor: + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + if (!candidates.isEmpty()) + { + mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always topmost hit layerable (signal emitted in release event) + mMouseSignalLayerableDetails = details.first(); + } + // forward event to topmost candidate which accepts the event: + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events call ignore() on the event, in that case propagate to next candidate in list + candidates.at(i)->mousePressEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. + update(); +} + +/*! \internal + + Event handler for when the cursor is moved. Emits the \ref mouseMove signal. + + If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it + in order to update the rect geometry. + + Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the + layout element before), the mouseMoveEvent is forwarded to that element. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseMoveEvent(QMouseEvent *event) +{ + //< time tip + if(!axisRect()->isScaleRight() && !mSymbolPressed && qAbs(mSymbolPos.x() - event->pos().x()) < 5) + { + if(event->pos().y() > yAxis->axisRect()->top()) + { + if(Qt::SizeHorCursor != cursor().shape()) + { + setCursor(QCursor(Qt::SizeHorCursor)); + } + } + static QString preTipsContent = QString(); + QString strTime = QDateTime::fromMSecsSinceEpoch(xAxis->pixelToCoord(mSymbolPos.x())).toString("yyyy-MM-dd hh:mm:ss zzz"); + if(preTipsContent == strTime && findChild("ToolTip")) + { + return; + } + preTipsContent = strTime; + QFontMetrics metrics(QToolTip::font()); + int pixelsWide = metrics.width(strTime); + int pixelsHigh = metrics.height(); + QPoint position = mapToGlobal(QPoint(event->pos().x() - (pixelsWide / 2), -(pixelsHigh / 2))); + CToolTip::popup(position, strTime, this); + return; + } + + if(mSymbolPressed && event->pos().x() >= yAxis->mAxisRect->left() &&event->pos().x() <= yAxis->mAxisRect->right()) + { + setCursor(QCursor(Qt::SizeHorCursor)); + mSymbolPos = event->pos(); + emit symbolPosChanged(xAxis->pixelToCoord(mSymbolPos.x())); + update(); + return; + } + setCursor(QCursor(Qt::ArrowCursor)); + + + emit mouseMove(event); + if (!mMouseHasMoved && (mMousePressPos-event->pos()).manhattanLength() > 3) + mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release + + if (mSelectionRect && mSelectionRect->isActive()) + mSelectionRect->moveSelection(event); + else if (mMouseEventLayerable) // call event of affected layerable: + mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos); + + //< Extra By ZH + QList details; + QList candidates = layerableListAt(event->pos(), false, &details); + for (int i = 0; i < candidates.size(); ++i) + { + if(dynamic_cast(candidates.at(i))) + { + event->accept(); + candidates.at(i)->mouseMoveEvent(event, mMousePressPos); + } + } + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is released. Emits the \ref mouseRelease signal. + + If the mouse was moved less than a certain threshold in any direction since the \ref + mousePressEvent, it is considered a click which causes the selection mechanism (if activated via + \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse + click signals are emitted (e.g. \ref plottableClick, \ref axisClick, etc.) + + If a layerable is the mouse capturer (a \ref mousePressEvent happened on top of the layerable + before), the \ref mouseReleaseEvent is forwarded to that element. + + \see mousePressEvent, mouseMoveEvent +*/ +void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) +{ + emit mouseRelease(event); + + mSymbolPressed = false; + if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click + { + if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here + mSelectionRect->cancel(); + if (event->button() == Qt::LeftButton) + processPointSelection(event); + + // emit specialized click signals of QCustomPlot instance: + if (QCPAbstractPlottable *ap = qobject_cast(mMouseSignalLayerable)) + { + int dataIndex = 0; + if (!mMouseSignalLayerableDetails.value().isEmpty()) + dataIndex = mMouseSignalLayerableDetails.value().dataRange().begin(); + emit plottableClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(mMouseSignalLayerable)) + emit axisClick(ax, mMouseSignalLayerableDetails.value(), event); + else if (QCPAbstractItem *ai = qobject_cast(mMouseSignalLayerable)) + emit itemClick(ai, event); + else if (QCPLegend *lg = qobject_cast(mMouseSignalLayerable)) + emit legendClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(mMouseSignalLayerable)) + emit legendClick(li->parentLegend(), li, event); + mMouseSignalLayerable = 0; + } + + if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there + { + // finish selection rect, the appropriate action will be taken via signal-slot connection: + mSelectionRect->endSelection(event); + } else + { + // call event of affected layerable: + if (mMouseEventLayerable) + { + mMouseEventLayerable->mouseReleaseEvent(event, mMousePressPos); + mMouseEventLayerable = 0; + } + } + + if (noAntialiasingOnDrag()) + replot(rpQueuedReplot); + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for mouse wheel events. First, the \ref mouseWheel signal is emitted. Then + determines the affected layerable and forwards the event to it. +*/ +void QCustomPlot::wheelEvent(QWheelEvent *event) +{ + QRect rt = axisRect()->mRect; + if(event->pos().x() < rt.left() || event->pos().x() > rt.right() || event->pos().y() < rt.top() || event->pos().y() > rt.bottom()) + { + return; + } + + emit mouseWheel(event); + // forward event to layerable under cursor: + QList candidates = layerableListAt(event->pos(), false); + + + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->wheelEvent(event); + if (event->isAccepted()) + break; + } + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +bool QCustomPlot::eventFilter(QObject *object, QEvent *event) +{ + QLabel * pLabel = dynamic_cast(object); + if (pLabel) + { + if(event->type() == QEvent::Wheel) + { + QWheelEvent * pWheelEvent = dynamic_cast(event); + QWheelEvent e(mapFromGlobal(pWheelEvent->globalPos()), + pWheelEvent->globalPos(), + pWheelEvent->pixelDelta(), + pWheelEvent->angleDelta(), + pWheelEvent->delta(), + pWheelEvent->orientation(), + pWheelEvent->buttons(), + pWheelEvent->modifiers()); + + wheelEvent(&e); + return true; + } + else if(event->type() == QEvent::MouseMove) + { + QMouseEvent *pMouseEvent = dynamic_cast(event); + QPoint pt = mapFromGlobal(pMouseEvent->globalPos()); + QMouseEvent e(pMouseEvent->type(), + pt, pt, + pMouseEvent->screenPos(), + pMouseEvent->button(), + pMouseEvent->buttons(), + pMouseEvent->modifiers(), + pMouseEvent->source()); + mouseMoveEvent(&e); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +/*! \internal + + This function draws the entire plot, including background pixmap, with the specified \a painter. + It does not make use of the paint buffers like \ref replot, so this is the function typically + used by saving/exporting methods such as \ref savePdf or \ref toPainter. + + Note that it does not fill the background with the background brush (as the user may specify with + \ref setBackground(const QBrush &brush)), this is up to the respective functions calling this + method. +*/ +void QCustomPlot::draw(QCPPainter *painter) +{ + updateLayout(); + + // draw viewport background pixmap: + drawBackground(painter); + + // draw all layered objects (grid, axes, plottables, items, legend,...): + foreach (QCPLayer *layer, mLayers) + layer->draw(painter); + + /* Debug code to draw all layout element rects + foreach (QCPLayoutElement* el, findChildren()) + { + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(QColor(0, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->rect()); + painter->setPen(QPen(QColor(255, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->outerRect()); + } + */ +} + +/*! \internal + + Performs the layout update steps defined by \ref QCPLayoutElement::UpdatePhase, by calling \ref + QCPLayoutElement::update on the main plot layout. + + Here, the layout elements calculate their positions and margins, and prepare for the following + draw call. +*/ +void QCustomPlot::updateLayout() +{ + // run through layout phases: + mPlotLayout->update(QCPLayoutElement::upPreparation); + mPlotLayout->update(QCPLayoutElement::upMargins); + mPlotLayout->update(QCPLayoutElement::upLayout); +} + +/*! \internal + + Draws the viewport background pixmap of the plot. + + If a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the viewport with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + Note that this function does not draw a fill with the background brush + (\ref setBackground(const QBrush &brush)) beneath the pixmap. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::drawBackground(QCPPainter *painter) +{ + // Note: background color is handled in individual replot/save functions + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mViewport.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height())); + } + } +} + +/*! \internal + + Goes through the layers and makes sure this QCustomPlot instance holds the correct number of + paint buffers and that they have the correct configuration (size, pixel ratio, etc.). + Allocations, reallocations and deletions of paint buffers are performed as necessary. It also + associates the paint buffers with the layers, so they draw themselves into the right buffer when + \ref QCPLayer::drawToPaintBuffer is called. This means it associates adjacent \ref + QCPLayer::lmLogical layers to a mutual paint buffer and creates dedicated paint buffers for + layers in \ref QCPLayer::lmBuffered mode. + + This method uses \ref createPaintBuffer to create new paint buffers. + + After this method, the paint buffers are empty (filled with \c Qt::transparent) and invalidated + (so an attempt to replot only a single buffered layer causes a full replot). + + This method is called in every \ref replot call, prior to actually drawing the layers (into their + associated paint buffer). If the paint buffers don't need changing/reallocating, this method + basically leaves them alone and thus finishes very fast. +*/ +void QCustomPlot::setupPaintBuffers() +{ + int bufferIndex = 0; + if (mPaintBuffers.isEmpty()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + + for (int layerIndex = 0; layerIndex < mLayers.size(); ++layerIndex) + { + QCPLayer *layer = mLayers.at(layerIndex); + if (layer->mode() == QCPLayer::lmLogical) + { + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + } else if (layer->mode() == QCPLayer::lmBuffered) + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + if (layerIndex < mLayers.size()-1 && mLayers.at(layerIndex+1)->mode() == QCPLayer::lmLogical) // not last layer, and next one is logical, so prepare another buffer for next layerables + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + } + } + } + // remove unneeded buffers: + while (mPaintBuffers.size()-1 > bufferIndex) + mPaintBuffers.removeLast(); + // resize buffers to viewport size and clear contents: + for (int i=0; isetSize(viewport().size()); // won't do anything if already correct size + mPaintBuffers.at(i)->clear(Qt::transparent); + mPaintBuffers.at(i)->setInvalidated(); + } +} + +/*! \internal + + This method is used by \ref setupPaintBuffers when it needs to create new paint buffers. + + Depending on the current setting of \ref setOpenGl, and the current Qt version, different + backends (subclasses of \ref QCPAbstractPaintBuffer) are created, initialized with the proper + size and device pixel ratio, and returned. +*/ +QCPAbstractPaintBuffer *QCustomPlot::createPaintBuffer() +{ + if (mOpenGl) + { +#if defined(QCP_OPENGL_FBO) + return new QCPPaintBufferGlFbo(viewport().size(), mBufferDevicePixelRatio, mGlContext, mGlPaintDevice); +#elif defined(QCP_OPENGL_PBUFFER) + return new QCPPaintBufferGlPbuffer(viewport().size(), mBufferDevicePixelRatio, mOpenGlMultisamples); +#else + qDebug() << Q_FUNC_INFO << "OpenGL enabled even though no support for it compiled in, this shouldn't have happened. Falling back to pixmap paint buffer."; + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +#endif + } else + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +} + +/*! + This method returns whether any of the paint buffers held by this QCustomPlot instance are + invalidated. + + If any buffer is invalidated, a partial replot (\ref QCPLayer::replot) is not allowed and always + causes a full replot (\ref QCustomPlot::replot) of all layers. This is the case when for example + the layer order has changed, new layers were added, layers were removed, or layer modes were + changed (\ref QCPLayer::setMode). + + \see QCPAbstractPaintBuffer::setInvalidated +*/ +bool QCustomPlot::hasInvalidatedPaintBuffers() +{ + for (int i=0; iinvalidated()) + return true; + } + return false; +} + +/*! \internal + + When \ref setOpenGl is set to true, this method is used to initialize OpenGL (create a context, + surface, paint device). + + Returns true on success. + + If this method is successful, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the OpenGL-based paint buffer subclasses (\ref + QCPPaintBufferGlPbuffer, \ref QCPPaintBufferGlFbo) are used for subsequent replots. + + \see freeOpenGl +*/ +bool QCustomPlot::setupOpenGl() +{ +#ifdef QCP_OPENGL_FBO + freeOpenGl(); + QSurfaceFormat proposedSurfaceFormat; + proposedSurfaceFormat.setSamples(mOpenGlMultisamples); +#ifdef QCP_OPENGL_OFFSCREENSURFACE + QOffscreenSurface *surface = new QOffscreenSurface; +#else + QWindow *surface = new QWindow; + surface->setSurfaceType(QSurface::OpenGLSurface); +#endif + surface->setFormat(proposedSurfaceFormat); + surface->create(); + mGlSurface = QSharedPointer(surface); + mGlContext = QSharedPointer(new QOpenGLContext); + mGlContext->setFormat(mGlSurface->format()); + if (!mGlContext->create()) + { + qDebug() << Q_FUNC_INFO << "Failed to create OpenGL context"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!mGlContext->makeCurrent(mGlSurface.data())) // context needs to be current to create paint device + { + qDebug() << Q_FUNC_INFO << "Failed to make opengl context current"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) + { + qDebug() << Q_FUNC_INFO << "OpenGL of this system doesn't support frame buffer objects"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + mGlPaintDevice = QSharedPointer(new QOpenGLPaintDevice); + return true; +#elif defined(QCP_OPENGL_PBUFFER) + return QGLFormat::hasOpenGL(); +#else + return false; +#endif +} + +/*! \internal + + When \ref setOpenGl is set to false, this method is used to deinitialize OpenGL (releases the + context and frees resources). + + After OpenGL is disabled, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the standard software rendering paint buffer subclass (\ref + QCPPaintBufferPixmap) is used for subsequent replots. + + \see setupOpenGl +*/ +void QCustomPlot::freeOpenGl() +{ +#ifdef QCP_OPENGL_FBO + mGlPaintDevice.clear(); + mGlContext.clear(); + mGlSurface.clear(); +#endif +} + +/*! \internal + + This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot + so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. +*/ +void QCustomPlot::axisRemoved(QCPAxis *axis) +{ + if (xAxis == axis) + xAxis = 0; + if (xAxis2 == axis) + xAxis2 = 0; + if (yAxis == axis) + yAxis = 0; + if (yAxis2 == axis) + yAxis2 = 0; + + // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers +} + +/*! \internal + + This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so + it may clear its QCustomPlot::legend member accordingly. +*/ +void QCustomPlot::legendRemoved(QCPLegend *legend) +{ + if (this->legend == legend) + this->legend = 0; +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmSelect. + + First, it determines which axis rect was the origin of the selection rect judging by the starting + point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be + precise) associated with that axis rect and finds the data points that are in \a rect. It does + this by querying their \ref QCPAbstractPlottable1D::selectTestRect method. + + Then, the actual selection is done by calling the plottables' \ref + QCPAbstractPlottable::selectEvent, placing the found selected data points in the \a details + parameter as QVariant(\ref QCPDataSelection). All plottables that weren't touched by \a + rect receive a \ref QCPAbstractPlottable::deselectEvent. + + \see processRectZoom +*/ +void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) +{ + bool selectionStateChanged = false; + + if (mInteractions.testFlag(QCP::iSelectPlottables)) + { + QMap > potentialSelections; // map key is number of selected data points, so we have selections sorted by size + QRectF rectF(rect.normalized()); + if (QCPAxisRect *affectedAxisRect = axisRectAt(rectF.topLeft())) + { + // determine plottables that were hit by the rect and thus are candidates for selection: + foreach (QCPAbstractPlottable *plottable, affectedAxisRect->plottables()) + { + if (QCPPlottableInterface1D *plottableInterface = plottable->interface1D()) + { + QCPDataSelection dataSel = plottableInterface->selectTestRect(rectF, true); + if (!dataSel.isEmpty()) + potentialSelections.insertMulti(dataSel.dataPointCount(), QPair(plottable, dataSel)); + } + } + + if (!mInteractions.testFlag(QCP::iMultiSelect)) + { + // only leave plottable with most selected points in map, since we will only select a single plottable: + if (!potentialSelections.isEmpty()) + { + QMap >::iterator it = potentialSelections.begin(); + while (it != potentialSelections.end()-1) // erase all except last element + it = potentialSelections.erase(it); + } + } + + bool additive = event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + // emit deselection except to those plottables who will be selected afterwards: + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + // go through selections in reverse (largest selection first) and emit select events: + QMap >::const_iterator it = potentialSelections.constEnd(); + while (it != potentialSelections.constBegin()) + { + --it; + if (mInteractions.testFlag(it.value().first->selectionCategory())) + { + bool selChanged = false; + it.value().first->selectEvent(event, additive, QVariant::fromValue(it.value().second), &selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } else if (mSelectionRect) + mSelectionRect->layer()->replot(); +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmZoom. + + It determines which axis rect was the origin of the selection rect judging by the starting point + of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the + provided \a rect (see \ref QCPAxisRect::zoom). + + \see processRectSelection +*/ +void QCustomPlot::processRectZoom(QRect rect, QMouseEvent *event) +{ + Q_UNUSED(event) + if (QCPAxisRect *axisRect = axisRectAt(rect.topLeft())) + { + QList affectedAxes = QList() << axisRect->rangeZoomAxes(Qt::Horizontal) << axisRect->rangeZoomAxes(Qt::Vertical); + affectedAxes.removeAll(static_cast(0)); + axisRect->zoom(QRectF(rect), affectedAxes); + } + replot(rpQueuedReplot); // always replot to make selection rect disappear +} + +/*! \internal + + This method is called when a simple left mouse click was detected on the QCustomPlot surface. + + It first determines the layerable that was hit by the click, and then calls its \ref + QCPLayerable::selectEvent. All other layerables receive a QCPLayerable::deselectEvent (unless the + multi-select modifier was pressed, see \ref setMultiSelectModifier). + + In this method the hit layerable is determined a second time using \ref layerableAt (after the + one in \ref mousePressEvent), because we want \a onlySelectable set to true this time. This + implies that the mouse event grabber (mMouseEventLayerable) may be a different one from the + clicked layerable determined here. For example, if a non-selectable layerable is in front of a + selectable layerable at the click position, the front layerable will receive mouse events but the + selectable one in the back will receive the \ref QCPLayerable::selectEvent. + + \see processRectSelection, QCPLayerable::selectTest +*/ +void QCustomPlot::processPointSelection(QMouseEvent *event) +{ + QVariant details; + QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details); + bool selectionStateChanged = false; + bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + if (clickedLayerable && mInteractions.testFlag(clickedLayerable->selectionCategory())) + { + // a layerable was actually clicked, call its selectEvent: + bool selChanged = false; + clickedLayerable->selectEvent(event, additive, details, &selChanged); + selectionStateChanged |= selChanged; + } + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } +} + +/*! \internal + + Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend + is enabled, adds it to the legend (QCustomPlot::legend). QCustomPlot takes ownership of the + plottable. + + Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of + \a plottable is this QCustomPlot. + + This method is called automatically in the QCPAbstractPlottable base class constructor. +*/ +bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) +{ + if (mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); + return false; + } + if (plottable->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); + return false; + } + + mPlottables.append(plottable); + // possibly add plottable to legend: + if (mAutoAddPlottableToLegend) + plottable->addToLegend(); + if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) + plottable->setLayer(currentLayer()); + return true; +} + +/*! \internal + + In order to maintain the simplified graph interface of QCustomPlot, this method is called by the + QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true + on success, i.e. if \a graph is valid and wasn't already registered with this QCustomPlot. + + This graph specific registration happens in addition to the call to \ref registerPlottable by the + QCPAbstractPlottable base class. +*/ +bool QCustomPlot::registerGraph(QCPGraph *graph) +{ + if (!graph) + { + qDebug() << Q_FUNC_INFO << "passed graph is zero"; + return false; + } + if (mGraphs.contains(graph)) + { + qDebug() << Q_FUNC_INFO << "graph already registered with this QCustomPlot"; + return false; + } + + mGraphs.append(graph); + return true; +} + + +/*! \internal + + Registers the specified item with this QCustomPlot. QCustomPlot takes ownership of the item. + + Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a + item is this QCustomPlot. + + This method is called automatically in the QCPAbstractItem base class constructor. +*/ +bool QCustomPlot::registerItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + qDebug() << Q_FUNC_INFO << "item already added to this QCustomPlot:" << reinterpret_cast(item); + return false; + } + if (item->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast(item); + return false; + } + + mItems.append(item); + if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor) + item->setLayer(currentLayer()); + return true; +} + +/*! \internal + + Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called + after every operation that changes the layer indices, like layer removal, layer creation, layer + moving. +*/ +void QCustomPlot::updateLayerIndices() const +{ + for (int i=0; imIndex = i; +} + +/*! \internal + + Returns the top-most layerable at pixel position \a pos. If \a onlySelectable is set to true, + only those layerables that are selectable will be considered. (Layerable subclasses communicate + their selectability via the QCPLayerable::selectTest method, by returning -1.) + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableListAt, layoutElementAt, axisRectAt +*/ +QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const +{ + QList details; + QList candidates = layerableListAt(pos, onlySelectable, selectionDetails ? &details : 0); + if (selectionDetails && !details.isEmpty()) + *selectionDetails = details.first(); + if (!candidates.isEmpty()) + return candidates.first(); + else + return 0; +} + +/*! \internal + + Returns the layerables at pixel position \a pos. If \a onlySelectable is set to true, only those + layerables that are selectable will be considered. (Layerable subclasses communicate their + selectability via the QCPLayerable::selectTest method, by returning -1.) + + The returned list is sorted by the layerable/drawing order. If you only need to know the top-most + layerable, rather use \ref layerableAt. + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableAt, layoutElementAt, axisRectAt +*/ +QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails) const +{ + QList result; + for (int layerIndex=mLayers.size()-1; layerIndex>=0; --layerIndex) + { + const QList layerables = mLayers.at(layerIndex)->children(); + for (int i=layerables.size()-1; i>=0; --i) + { + if (!layerables.at(i)->realVisibility()) + continue; + QVariant details; + double dist = layerables.at(i)->selectTest(pos, onlySelectable, selectionDetails ? &details : 0); + if (dist >= 0 && dist < selectionTolerance()) + { + result.append(layerables.at(i)); + if (selectionDetails) + selectionDetails->append(details); + } + } + } + return result; +} + +/*! + Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is + sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead + to a full resolution file with width 200.) If the \a format supports compression, \a quality may + be between 0 and 100 to control it. + + Returns true on success. If this function fails, most likely the given \a format isn't supported + by the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The \a resolution will be written to the image file header (if the file format supports this) and + has no direct consequence for the quality or the pixel size. However, if opening the image with a + tool which respects the metadata, it will be able to scale the image to match either a given size + in real units of length (inch, centimeters, etc.), or the target display DPI. You can specify in + which units \a resolution is given, by setting \a resolutionUnit. The \a resolution is converted + to the format's expected resolution unit internally. + + \see saveBmp, saveJpg, savePng, savePdf +*/ +bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + QImage buffer = toPixmap(width, height, scale).toImage(); + + int dotsPerMeter = 0; + switch (resolutionUnit) + { + case QCP::ruDotsPerMeter: dotsPerMeter = resolution; break; + case QCP::ruDotsPerCentimeter: dotsPerMeter = resolution*100; break; + case QCP::ruDotsPerInch: dotsPerMeter = resolution/0.0254; break; + } + buffer.setDotsPerMeterX(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + buffer.setDotsPerMeterY(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + if (!buffer.isNull()) + return buffer.save(fileName, format, quality); + else + return false; +} + +/*! + Renders the plot to a pixmap and returns it. + + The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and + scale 2.0 lead to a full resolution pixmap with width 200.) + + \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf +*/ +QPixmap QCustomPlot::toPixmap(int width, int height, double scale) +{ + // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + int scaledWidth = qRound(scale*newWidth); + int scaledHeight = qRound(scale*newHeight); + + QPixmap result(scaledWidth, scaledHeight); + result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later + QCPPainter painter; + painter.begin(&result); + if (painter.isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter.setMode(QCPPainter::pmNoCaching); + if (!qFuzzyCompare(scale, 1.0)) + { + if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales + painter.setMode(QCPPainter::pmNonCosmetic); + painter.scale(scale, scale); + } + if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill + painter.fillRect(mViewport, mBackgroundBrush); + draw(&painter); + setViewport(oldViewport); + painter.end(); + } else // might happen if pixmap has width or height zero + { + qDebug() << Q_FUNC_INFO << "Couldn't activate painter on pixmap"; + return QPixmap(); + } + return result; +} + +/*! + Renders the plot using the passed \a painter. + + The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will + appear scaled accordingly. + + \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter + on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with + the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. + + \see toPixmap +*/ +void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) +{ + // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + if (painter->isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter->setMode(QCPPainter::pmNoCaching); + if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here + painter->fillRect(mViewport, mBackgroundBrush); + draw(painter); + setViewport(oldViewport); + } else + qDebug() << Q_FUNC_INFO << "Passed painter is not active"; +} +/* end of 'src/core.cpp' */ + +//amalgamation: add plottable1d.cpp + +/* including file 'src/colorgradient.cpp', size 24646 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorGradient +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorGradient + \brief Defines a color gradient for use with e.g. \ref QCPColorMap + + This class describes a color gradient which can be used to encode data with color. For example, + QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which + take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) + with a \a position from 0 to 1. In between these defined color positions, the + color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation. + + Alternatively, load one of the preset color gradients shown in the image below, with \ref + loadPreset, or by directly specifying the preset in the constructor. + + Apart from red, green and blue components, the gradient also interpolates the alpha values of the + configured color stops. This allows to display some portions of the data range as transparent in + the plot. + + \image html QCPColorGradient.png + + The \ref QCPColorGradient(GradientPreset preset) constructor allows directly converting a \ref + GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset + to all the \a setGradient methods, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient + + The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the + color gradient shall be applied periodically (wrapping around) to data values that lie outside + the data range specified on the plottable instance can be controlled with \ref setPeriodic. +*/ + +/*! + Constructs a new, empty QCPColorGradient with no predefined color stops. You can add own color + stops with \ref setColorStopAt. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient() : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); +} + +/*! + Constructs a new QCPColorGradient initialized with the colors and color interpolation according + to \a preset. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient(GradientPreset preset) : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); + loadPreset(preset); +} + +/* undocumented operator */ +bool QCPColorGradient::operator==(const QCPColorGradient &other) const +{ + return ((other.mLevelCount == this->mLevelCount) && + (other.mColorInterpolation == this->mColorInterpolation) && + (other.mPeriodic == this->mPeriodic) && + (other.mColorStops == this->mColorStops)); +} + +/*! + Sets the number of discretization levels of the color gradient to \a n. The default is 350 which + is typically enough to create a smooth appearance. The minimum number of levels is 2. + + \image html QCPColorGradient-levelcount.png +*/ +void QCPColorGradient::setLevelCount(int n) +{ + if (n < 2) + { + qDebug() << Q_FUNC_INFO << "n must be greater or equal 2 but was" << n; + n = 2; + } + if (n != mLevelCount) + { + mLevelCount = n; + mColorBufferInvalidated = true; + } +} + +/*! + Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the + colors are the values of the passed QMap \a colorStops. In between these color stops, the color + is interpolated according to \ref setColorInterpolation. + + A more convenient way to create a custom gradient may be to clear all color stops with \ref + clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with + \ref setColorStopAt. + + \see clearColorStops +*/ +void QCPColorGradient::setColorStops(const QMap &colorStops) +{ + mColorStops = colorStops; + mColorBufferInvalidated = true; +} + +/*! + Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between + these color stops, the color is interpolated according to \ref setColorInterpolation. + + \see setColorStops, clearColorStops +*/ +void QCPColorGradient::setColorStopAt(double position, const QColor &color) +{ + mColorStops.insert(position, color); + mColorBufferInvalidated = true; +} + +/*! + Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be + interpolated linearly in RGB or in HSV color space. + + For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, + whereas in HSV space the intermediate color is yellow. +*/ +void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation) +{ + if (interpolation != mColorInterpolation) + { + mColorInterpolation = interpolation; + mColorBufferInvalidated = true; + } +} + +/*! + Sets whether data points that are outside the configured data range (e.g. \ref + QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether + they all have the same color, corresponding to the respective gradient boundary color. + + \image html QCPColorGradient-periodic.png + + As shown in the image above, gradients that have the same start and end color are especially + suitable for a periodic gradient mapping, since they produce smooth color transitions throughout + the color map. A preset that has this property is \ref gpHues. + + In practice, using periodic color gradients makes sense when the data corresponds to a periodic + dimension, such as an angle or a phase. If this is not the case, the color encoding might become + ambiguous, because multiple different data values are shown as the same color. +*/ +void QCPColorGradient::setPeriodic(bool enabled) +{ + mPeriodic = enabled; +} + +/*! \overload + + This method is used to quickly convert a \a data array to colors. The colors will be output in + the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this + function. The data range that shall be used for mapping the data value to the gradient is passed + in \a range. \a logarithmic indicates whether the data values shall be mapped to colors + logarithmically. + + if \a data actually contains 2D-data linearized via [row*columnCount + column], you can + set \a dataIndexFactor to columnCount to convert a column instead of a row of the data + array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data + is addressed data[i*dataIndexFactor]. + + Use the overloaded method to additionally provide alpha map data. + + The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } +} + +/*! \overload + + Additionally to the other overload of \ref colorize, this method takes the array \a alpha, which + has the same size and structure as \a data and encodes the alpha information per data point. + + The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!alpha) + { + qDebug() << Q_FUNC_INFO << "null pointer given as alpha"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + if (alpha[dataIndexFactor*i] == 255) + { + scanLine[i] = mColorBuffer.at(index); + } else + { + const QRgb rgb = mColorBuffer.at(index); + const float alphaF = alpha[dataIndexFactor*i]/255.0f; + scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); + } + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + if (alpha[dataIndexFactor*i] == 255) + { + scanLine[i] = mColorBuffer.at(index); + } else + { + const QRgb rgb = mColorBuffer.at(index); + const float alphaF = alpha[dataIndexFactor*i]/255.0f; + scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); + } + } + } + } +} + +/*! \internal + + This method is used to colorize a single data value given in \a position, to colors. The data + range that shall be used for mapping the data value to the gradient is passed in \a range. \a + logarithmic indicates whether the data value shall be mapped to a color logarithmically. + + If an entire array of data values shall be converted, rather use \ref colorize, for better + performance. + + The returned QRgb has its r, g and b components premultiplied with alpha (see + QImage::Format_ARGB32_Premultiplied). +*/ +QRgb QCPColorGradient::color(double position, const QCPRange &range, bool logarithmic) +{ + // If you change something here, make sure to also adapt ::colorize() + if (mColorBufferInvalidated) + updateColorBuffer(); + int index = 0; + if (!logarithmic) + index = (position-range.lower)*(mLevelCount-1)/range.size(); + else + index = qLn(position/range.lower)/qLn(range.upper/range.lower)*(mLevelCount-1); + if (mPeriodic) + { + index = index % mLevelCount; + if (index < 0) + index += mLevelCount; + } else + { + if (index < 0) + index = 0; + else if (index >= mLevelCount) + index = mLevelCount-1; + } + return mColorBuffer.at(index); +} + +/*! + Clears the current color stops and loads the specified \a preset. A preset consists of predefined + color stops and the corresponding color interpolation method. + + The available presets are: + \image html QCPColorGradient.png +*/ +void QCPColorGradient::loadPreset(GradientPreset preset) +{ + clearColorStops(); + switch (preset) + { + case gpGrayscale: + setColorInterpolation(ciRGB); + setColorStopAt(0, Qt::black); + setColorStopAt(1, Qt::white); + break; + case gpHot: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 0, 0)); + setColorStopAt(0.2, QColor(180, 10, 0)); + setColorStopAt(0.4, QColor(245, 50, 0)); + setColorStopAt(0.6, QColor(255, 150, 10)); + setColorStopAt(0.8, QColor(255, 255, 50)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpCold: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.2, QColor(0, 10, 180)); + setColorStopAt(0.4, QColor(0, 50, 245)); + setColorStopAt(0.6, QColor(10, 150, 255)); + setColorStopAt(0.8, QColor(50, 255, 255)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpNight: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(10, 20, 30)); + setColorStopAt(1, QColor(250, 255, 250)); + break; + case gpCandy: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(0, 0, 255)); + setColorStopAt(1, QColor(255, 250, 250)); + break; + case gpGeography: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(70, 170, 210)); + setColorStopAt(0.20, QColor(90, 160, 180)); + setColorStopAt(0.25, QColor(45, 130, 175)); + setColorStopAt(0.30, QColor(100, 140, 125)); + setColorStopAt(0.5, QColor(100, 140, 100)); + setColorStopAt(0.6, QColor(130, 145, 120)); + setColorStopAt(0.7, QColor(140, 130, 120)); + setColorStopAt(0.9, QColor(180, 190, 190)); + setColorStopAt(1, QColor(210, 210, 230)); + break; + case gpIon: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 10, 10)); + setColorStopAt(0.45, QColor(0, 0, 255)); + setColorStopAt(0.8, QColor(0, 255, 255)); + setColorStopAt(1, QColor(0, 255, 0)); + break; + case gpThermal: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.15, QColor(20, 0, 120)); + setColorStopAt(0.33, QColor(200, 30, 140)); + setColorStopAt(0.6, QColor(255, 100, 0)); + setColorStopAt(0.85, QColor(255, 255, 40)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpPolar: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 255, 255)); + setColorStopAt(0.18, QColor(10, 70, 255)); + setColorStopAt(0.28, QColor(10, 10, 190)); + setColorStopAt(0.5, QColor(0, 0, 0)); + setColorStopAt(0.72, QColor(190, 10, 10)); + setColorStopAt(0.82, QColor(255, 70, 10)); + setColorStopAt(1, QColor(255, 255, 50)); + break; + case gpSpectrum: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 0, 50)); + setColorStopAt(0.15, QColor(0, 0, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.6, QColor(255, 255, 0)); + setColorStopAt(0.75, QColor(255, 30, 0)); + setColorStopAt(1, QColor(50, 0, 0)); + break; + case gpJet: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 100)); + setColorStopAt(0.15, QColor(0, 50, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.65, QColor(255, 255, 0)); + setColorStopAt(0.85, QColor(255, 30, 0)); + setColorStopAt(1, QColor(100, 0, 0)); + break; + case gpHues: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(255, 0, 0)); + setColorStopAt(1.0/3.0, QColor(0, 0, 255)); + setColorStopAt(2.0/3.0, QColor(0, 255, 0)); + setColorStopAt(1, QColor(255, 0, 0)); + break; + } +} + +/*! + Clears all color stops. + + \see setColorStops, setColorStopAt +*/ +void QCPColorGradient::clearColorStops() +{ + mColorStops.clear(); + mColorBufferInvalidated = true; +} + +/*! + Returns an inverted gradient. The inverted gradient has all properties as this \ref + QCPColorGradient, but the order of the color stops is inverted. + + \see setColorStops, setColorStopAt +*/ +QCPColorGradient QCPColorGradient::inverted() const +{ + QCPColorGradient result(*this); + result.clearColorStops(); + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + result.setColorStopAt(1.0-it.key(), it.value()); + return result; +} + +/*! \internal + + Returns true if the color gradient uses transparency, i.e. if any of the configured color stops + has an alpha value below 255. +*/ +bool QCPColorGradient::stopsUseAlpha() const +{ + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + { + if (it.value().alpha() < 255) + return true; + } + return false; +} + +/*! \internal + + Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly + convert positions to colors. This is where the interpolation between color stops is calculated. +*/ +void QCPColorGradient::updateColorBuffer() +{ + if (mColorBuffer.size() != mLevelCount) + mColorBuffer.resize(mLevelCount); + if (mColorStops.size() > 1) + { + double indexToPosFactor = 1.0/(double)(mLevelCount-1); + const bool useAlpha = stopsUseAlpha(); + for (int i=0; i::const_iterator it = mColorStops.lowerBound(position); + if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop + { + mColorBuffer[i] = (it-1).value().rgba(); + } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop + { + mColorBuffer[i] = it.value().rgba(); + } else // position is in between stops (or on an intermediate stop), interpolate color + { + QMap::const_iterator high = it; + QMap::const_iterator low = it-1; + double t = (position-low.key())/(high.key()-low.key()); // interpolation factor 0..1 + switch (mColorInterpolation) + { + case ciRGB: + { + if (useAlpha) + { + const int alpha = (1-t)*low.value().alpha() + t*high.value().alpha(); + const float alphaPremultiplier = alpha/255.0f; // since we use QImage::Format_ARGB32_Premultiplied + mColorBuffer[i] = qRgba(((1-t)*low.value().red() + t*high.value().red())*alphaPremultiplier, + ((1-t)*low.value().green() + t*high.value().green())*alphaPremultiplier, + ((1-t)*low.value().blue() + t*high.value().blue())*alphaPremultiplier, + alpha); + } else + { + mColorBuffer[i] = qRgb(((1-t)*low.value().red() + t*high.value().red()), + ((1-t)*low.value().green() + t*high.value().green()), + ((1-t)*low.value().blue() + t*high.value().blue())); + } + break; + } + case ciHSV: + { + QColor lowHsv = low.value().toHsv(); + QColor highHsv = high.value().toHsv(); + double hue = 0; + double hueDiff = highHsv.hueF()-lowHsv.hueF(); + if (hueDiff > 0.5) + hue = lowHsv.hueF() - t*(1.0-hueDiff); + else if (hueDiff < -0.5) + hue = lowHsv.hueF() + t*(1.0+hueDiff); + else + hue = lowHsv.hueF() + t*hueDiff; + if (hue < 0) hue += 1.0; + else if (hue >= 1.0) hue -= 1.0; + if (useAlpha) + { + const QRgb rgb = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + const float alpha = (1-t)*lowHsv.alphaF() + t*highHsv.alphaF(); + mColorBuffer[i] = qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha); + } + else + { + mColorBuffer[i] = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + } + break; + } + } + } + } + } else if (mColorStops.size() == 1) + { + const QRgb rgb = mColorStops.constBegin().value().rgb(); + const float alpha = mColorStops.constBegin().value().alphaF(); + mColorBuffer.fill(qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha)); + } else // mColorStops is empty, fill color buffer with black + { + mColorBuffer.fill(qRgb(0, 0, 0)); + } + mColorBufferInvalidated = false; +} +/* end of 'src/colorgradient.cpp' */ + + +/* including file 'src/selectiondecorator-bracket.cpp', size 12313 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecoratorBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecoratorBracket + \brief A selection decorator which draws brackets around each selected data segment + + Additionally to the regular highlighting of selected segments via color, fill and scatter style, + this \ref QCPSelectionDecorator subclass draws markers at the begin and end of each selected data + segment of the plottable. + + The shape of the markers can be controlled with \ref setBracketStyle, \ref setBracketWidth and + \ref setBracketHeight. The color/fill can be controlled with \ref setBracketPen and \ref + setBracketBrush. + + To introduce custom bracket styles, it is only necessary to sublcass \ref + QCPSelectionDecoratorBracket and reimplement \ref drawBracket. The rest will be managed by the + base class. +*/ + +/*! + Creates a new QCPSelectionDecoratorBracket instance with default values. +*/ +QCPSelectionDecoratorBracket::QCPSelectionDecoratorBracket() : + mBracketPen(QPen(Qt::black)), + mBracketBrush(Qt::NoBrush), + mBracketWidth(5), + mBracketHeight(50), + mBracketStyle(bsSquareBracket), + mTangentToData(false), + mTangentAverage(2) +{ + +} + +QCPSelectionDecoratorBracket::~QCPSelectionDecoratorBracket() +{ +} + +/*! + Sets the pen that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketPen(const QPen &pen) +{ + mBracketPen = pen; +} + +/*! + Sets the brush that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketBrush(const QBrush &brush) +{ + mBracketBrush = brush; +} + +/*! + Sets the width of the drawn bracket. The width dimension is always parallel to the key axis of + the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketWidth(int width) +{ + mBracketWidth = width; +} + +/*! + Sets the height of the drawn bracket. The height dimension is always perpendicular to the key axis + of the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketHeight(int height) +{ + mBracketHeight = height; +} + +/*! + Sets the shape that the bracket/marker will have. + + \see setBracketWidth, setBracketHeight +*/ +void QCPSelectionDecoratorBracket::setBracketStyle(QCPSelectionDecoratorBracket::BracketStyle style) +{ + mBracketStyle = style; +} + +/*! + Sets whether the brackets will be rotated such that they align with the slope of the data at the + position that they appear in. + + For noisy data, it might be more visually appealing to average the slope over multiple data + points. This can be configured via \ref setTangentAverage. +*/ +void QCPSelectionDecoratorBracket::setTangentToData(bool enabled) +{ + mTangentToData = enabled; +} + +/*! + Controls over how many data points the slope shall be averaged, when brackets shall be aligned + with the data (if \ref setTangentToData is true). + + From the position of the bracket, \a pointCount points towards the selected data range will be + taken into account. The smallest value of \a pointCount is 1, which is effectively equivalent to + disabling \ref setTangentToData. +*/ +void QCPSelectionDecoratorBracket::setTangentAverage(int pointCount) +{ + mTangentAverage = pointCount; + if (mTangentAverage < 1) + mTangentAverage = 1; +} + +/*! + Draws the bracket shape with \a painter. The parameter \a direction is either -1 or 1 and + indicates whether the bracket shall point to the left or the right (i.e. is a closing or opening + bracket, respectively). + + The passed \a painter already contains all transformations that are necessary to position and + rotate the bracket appropriately. Painting operations can be performed as if drawing upright + brackets on flat data with horizontal key axis, with (0, 0) being the center of the bracket. + + If you wish to sublcass \ref QCPSelectionDecoratorBracket in order to provide custom bracket + shapes (see \ref QCPSelectionDecoratorBracket::bsUserStyle), this is the method you should + reimplement. +*/ +void QCPSelectionDecoratorBracket::drawBracket(QCPPainter *painter, int direction) const +{ + switch (mBracketStyle) + { + case bsSquareBracket: + { + painter->drawLine(QLineF(mBracketWidth*direction, -mBracketHeight*0.5, 0, -mBracketHeight*0.5)); + painter->drawLine(QLineF(mBracketWidth*direction, mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + break; + } + case bsHalfEllipse: + { + painter->drawArc(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight, -90*16, -180*16*direction); + break; + } + case bsEllipse: + { + painter->drawEllipse(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight); + break; + } + case bsPlus: + { + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(-mBracketWidth*0.5, 0, mBracketWidth*0.5, 0)); + break; + } + default: + { + qDebug() << Q_FUNC_INFO << "unknown/custom bracket style can't be handeld by default implementation:" << static_cast(mBracketStyle); + break; + } + } +} + +/*! + Draws the bracket decoration on the data points at the begin and end of each selected data + segment given in \a seletion. + + It uses the method \ref drawBracket to actually draw the shapes. + + \seebaseclassmethod +*/ +void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + if (!mPlottable || selection.isEmpty()) return; + + if (QCPPlottableInterface1D *interface1d = mPlottable->interface1D()) + { + foreach (const QCPDataRange &dataRange, selection.dataRanges()) + { + // determine position and (if tangent mode is enabled) angle of brackets: + int openBracketDir = (mPlottable->keyAxis() && !mPlottable->keyAxis()->rangeReversed()) ? 1 : -1; + int closeBracketDir = -openBracketDir; + QPointF openBracketPos = getPixelCoordinates(interface1d, dataRange.begin()); + QPointF closeBracketPos = getPixelCoordinates(interface1d, dataRange.end()-1); + double openBracketAngle = 0; + double closeBracketAngle = 0; + if (mTangentToData) + { + openBracketAngle = getTangentAngle(interface1d, dataRange.begin(), openBracketDir); + closeBracketAngle = getTangentAngle(interface1d, dataRange.end()-1, closeBracketDir); + } + // draw opening bracket: + QTransform oldTransform = painter->transform(); + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(openBracketPos); + painter->rotate(openBracketAngle/M_PI*180.0); + drawBracket(painter, openBracketDir); + painter->setTransform(oldTransform); + // draw closing bracket: + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(closeBracketPos); + painter->rotate(closeBracketAngle/M_PI*180.0); + drawBracket(painter, closeBracketDir); + painter->setTransform(oldTransform); + } + } +} + +/*! \internal + + If \ref setTangentToData is enabled, brackets need to be rotated according to the data slope. + This method returns the angle in radians by which a bracket at the given \a dataIndex must be + rotated. + + The parameter \a direction must be set to either -1 or 1, representing whether it is an opening + or closing bracket. Since for slope calculation multiple data points are required, this defines + the direction in which the algorithm walks, starting at \a dataIndex, to average those data + points. (see \ref setTangentToData and \ref setTangentAverage) + + \a interface1d is the interface to the plottable's data which is used to query data coordinates. +*/ +double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const +{ + if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->dataCount()) + return 0; + direction = direction < 0 ? -1 : 1; // enforce direction is either -1 or 1 + + // how many steps we can actually go from index in the given direction without exceeding data bounds: + int averageCount; + if (direction < 0) + averageCount = qMin(mTangentAverage, dataIndex); + else + averageCount = qMin(mTangentAverage, interface1d->dataCount()-1-dataIndex); + qDebug() << averageCount; + // calculate point average of averageCount points: + QVector points(averageCount); + QPointF pointsAverage; + int currentIndex = dataIndex; + for (int i=0; ikeyAxis(); + QCPAxis *valueAxis = mPlottable->valueAxis(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(0, 0); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))); + else + return QPointF(valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex)), keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex))); +} +/* end of 'src/selectiondecorator-bracket.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47584 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisRect + \brief Holds multiple axes and arranges them in a rectangular shape. + + This class represents an axis rect, a rectangular area that is bounded on all sides with an + arbitrary number of axes. + + Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the + layout system allows to have multiple axis rects, e.g. arranged in a grid layout + (QCustomPlot::plotLayout). + + By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be + accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. + If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be + invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref + addAxes. To remove an axis, use \ref removeAxis. + + The axis rect layerable itself only draws a background pixmap or color, if specified (\ref + setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an + explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be + placed on other layers, independently of the axis rect. + + Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref + insetLayout and can be used to have other layout elements (or even other layouts with multiple + elements) hovering inside the axis rect. + + If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The + behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel + is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable + via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are + only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref + QCP::iRangeZoom. + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed + line on the far left indicates the viewport/widget border.
+*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const + + Returns the inset layout of this axis rect. It can be used to place other layout elements (or + even layouts with multiple other elements) inside/on top of an axis rect. + + \see QCPLayoutInset +*/ + +/*! \fn int QCPAxisRect::left() const + + Returns the pixel position of the left border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::right() const + + Returns the pixel position of the right border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::top() const + + Returns the pixel position of the top border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::bottom() const + + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::width() const + + Returns the pixel width of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::height() const + + Returns the pixel height of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QSize QCPAxisRect::size() const + + Returns the pixel size of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topLeft() const + + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, + so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topRight() const + + Returns the top right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomLeft() const + + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomRight() const + + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::center() const + + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPAxisRect instance and sets default values. An axis is added for each of the four + sides, the top and right axes are set invisible initially. +*/ +QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : + QCPLayoutElement(parentPlot), + mBackgroundBrush(Qt::NoBrush), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mInsetLayout(new QCPLayoutInset), + mRangeDrag(Qt::Horizontal|Qt::Vertical), + mRangeZoom(Qt::Horizontal|Qt::Vertical), + mRangeZoomFactorHorz(0.85), + mRangeZoomFactorVert(0.85), + mDragging(false), + mIsScaleRight(false) +{ + mInsetLayout->initializeParentPlot(mParentPlot); + mInsetLayout->setParentLayerable(this); + mInsetLayout->setParent(this); + + setMinimumSize(50, 50); + setMinimumMargins(QMargins(15, 15, 15, 15)); + mAxes.insert(QCPAxis::atLeft, QList()); + mAxes.insert(QCPAxis::atRight, QList()); + mAxes.insert(QCPAxis::atTop, QList()); + mAxes.insert(QCPAxis::atBottom, QList()); + + if (setupDefaultAxes) + { + QCPAxis *xAxis = addAxis(QCPAxis::atBottom); + QCPAxis *yAxis = addAxis(QCPAxis::atLeft); + QCPAxis *xAxis2 = addAxis(QCPAxis::atTop); + QCPAxis *yAxis2 = addAxis(QCPAxis::atRight); + setRangeDragAxes(xAxis, yAxis); + setRangeZoomAxes(xAxis, yAxis); + xAxis2->setVisible(false); + yAxis2->setVisible(false); + xAxis->grid()->setVisible(true); + yAxis->grid()->setVisible(true); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + xAxis2->grid()->setZeroLinePen(Qt::NoPen); + yAxis2->grid()->setZeroLinePen(Qt::NoPen); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + } +} + +QCPAxisRect::~QCPAxisRect() +{ + delete mInsetLayout; + mInsetLayout = 0; + + QList axesList = axes(); + for (int i=0; i ax(mAxes.value(type)); + if (index >= 0 && index < ax.size()) + { + return ax.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; + return 0; + } +} + +/*! + Returns all axes on the axis rect sides specified with \a types. + + \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of + multiple sides. + + \see axis +*/ +QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << mAxes.value(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << mAxes.value(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << mAxes.value(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << mAxes.value(QCPAxis::atBottom); + return result; +} + +/*! \overload + + Returns all axes of this axis rect. +*/ +QList QCPAxisRect::axes() const +{ + QList result; + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + result << it.value(); + } + return result; +} + +/*! + Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a + new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to + remove an axis, use \ref removeAxis instead of deleting it manually. + + You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was + previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership + of the axis, so you may not delete it afterwards. Further, the \a axis must have been created + with this axis rect as parent and with the same axis type as specified in \a type. If this is not + the case, a debug output is generated, the axis is not added, and the method returns 0. + + This method can not be used to move \a axis between axis rects. The same \a axis instance must + not be added multiple times to the same or different axis rects. + + If an axis rect side already contains one or more axes, the lower and upper endings of the new + axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref + QCPLineEnding::esHalfBar. + + \see addAxes, setupFullAxesBox +*/ +QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) +{ + QCPAxis *newAxis = axis; + if (!newAxis) + { + newAxis = new QCPAxis(this, type); + } else // user provided existing axis instance, do some sanity checks + { + if (newAxis->axisType() != type) + { + qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter"; + return 0; + } + if (newAxis->axisRect() != this) + { + qDebug() << Q_FUNC_INFO << "passed axis doesn't have this axis rect as parent axis rect"; + return 0; + } + if (axes().contains(newAxis)) + { + qDebug() << Q_FUNC_INFO << "passed axis is already owned by this axis rect"; + return 0; + } + } + if (mAxes[type].size() > 0) // multiple axes on one side, add half-bar axis ending to additional axes with offset + { + bool invert = (type == QCPAxis::atRight) || (type == QCPAxis::atBottom); + newAxis->setLowerEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, !invert)); + newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); + } + mAxes[type].append(newAxis); + + // reset convenience axis pointers on parent QCustomPlot if they are unset: + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + switch (type) + { + case QCPAxis::atBottom: { if (!mParentPlot->xAxis) mParentPlot->xAxis = newAxis; break; } + case QCPAxis::atLeft: { if (!mParentPlot->yAxis) mParentPlot->yAxis = newAxis; break; } + case QCPAxis::atTop: { if (!mParentPlot->xAxis2) mParentPlot->xAxis2 = newAxis; break; } + case QCPAxis::atRight: { if (!mParentPlot->yAxis2) mParentPlot->yAxis2 = newAxis; break; } + } + } + + return newAxis; +} + +/*! + Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an + or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. + + Returns a list of the added axes. + + \see addAxis, setupFullAxesBox +*/ +QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << addAxis(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << addAxis(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << addAxis(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << addAxis(QCPAxis::atBottom); + return result; +} + +/*! + Removes the specified \a axis from the axis rect and deletes it. + + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. + + \see addAxis +*/ +bool QCPAxisRect::removeAxis(QCPAxis *axis) +{ + // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers: + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(axis)) + { + if (it.value().first() == axis && it.value().size() > 1) // if removing first axis, transfer axis offset to the new first axis (which at this point is the second axis, if it exists) + it.value()[1]->setOffset(axis->offset()); + mAxes[it.key()].removeOne(axis); + if (qobject_cast(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot) + parentPlot()->axisRemoved(axis); + delete axis; + return true; + } + } + qDebug() << Q_FUNC_INFO << "Axis isn't in axis rect:" << reinterpret_cast(axis); + return false; +} + +/*! + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + All axes of this axis rect will have their range zoomed accordingly. If you only wish to zoom + specific axes, use the overloaded version of this method. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect) +{ + zoom(pixelRect, axes()); +} + +/*! \overload + + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + Only the axes passed in \a affectedAxes will have their ranges zoomed accordingly. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect, const QList &affectedAxes) +{ + foreach (QCPAxis *axis, affectedAxes) + { + if (!axis) + { + qDebug() << Q_FUNC_INFO << "a passed axis was zero"; + continue; + } + QCPRange pixelRange; + if (axis->orientation() == Qt::Horizontal) + pixelRange = QCPRange(pixelRect.left(), pixelRect.right()); + else + pixelRange = QCPRange(pixelRect.top(), pixelRect.bottom()); + axis->setRange(axis->pixelToCoord(pixelRange.lower), axis->pixelToCoord(pixelRange.upper)); + } +} + +/*! + Convenience function to create an axis on each side that doesn't have any axes yet and set their + visibility to true. Further, the top/right axes are assigned the following properties of the + bottom/left axes: + + \li range (\ref QCPAxis::setRange) + \li range reversed (\ref QCPAxis::setRangeReversed) + \li scale type (\ref QCPAxis::setScaleType) + \li tick visibility (\ref QCPAxis::setTicks) + \li number format (\ref QCPAxis::setNumberFormat) + \li number precision (\ref QCPAxis::setNumberPrecision) + \li tick count of ticker (\ref QCPAxisTicker::setTickCount) + \li tick origin of ticker (\ref QCPAxisTicker::setTickOrigin) + + Tick label visibility (\ref QCPAxis::setTickLabels) of the right and top axes are set to false. + + If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom + and left axes are connected to the \ref QCPAxis::setRange slots of the top and right axes. +*/ +void QCPAxisRect::setupFullAxesBox(bool connectRanges) +{ + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + if (axisCount(QCPAxis::atBottom) == 0) + xAxis = addAxis(QCPAxis::atBottom); + else + xAxis = axis(QCPAxis::atBottom); + + if (axisCount(QCPAxis::atLeft) == 0) + yAxis = addAxis(QCPAxis::atLeft); + else + yAxis = axis(QCPAxis::atLeft); + + if (axisCount(QCPAxis::atTop) == 0) + xAxis2 = addAxis(QCPAxis::atTop); + else + xAxis2 = axis(QCPAxis::atTop); + + if (axisCount(QCPAxis::atRight) == 0) + yAxis2 = addAxis(QCPAxis::atRight); + else + yAxis2 = axis(QCPAxis::atRight); + + xAxis->setVisible(true); + yAxis->setVisible(true); + xAxis2->setVisible(true); + yAxis2->setVisible(true); + xAxis2->setTickLabels(false); + yAxis2->setTickLabels(false); + + xAxis2->setRange(xAxis->range()); + xAxis2->setRangeReversed(xAxis->rangeReversed()); + xAxis2->setScaleType(xAxis->scaleType()); + xAxis2->setTicks(xAxis->ticks()); + xAxis2->setNumberFormat(xAxis->numberFormat()); + xAxis2->setNumberPrecision(xAxis->numberPrecision()); + xAxis2->ticker()->setTickCount(xAxis->ticker()->tickCount()); + xAxis2->ticker()->setTickOrigin(xAxis->ticker()->tickOrigin()); + + yAxis2->setRange(yAxis->range()); + yAxis2->setRangeReversed(yAxis->rangeReversed()); + yAxis2->setScaleType(yAxis->scaleType()); + yAxis2->setTicks(yAxis->ticks()); + yAxis2->setNumberFormat(yAxis->numberFormat()); + yAxis2->setNumberPrecision(yAxis->numberPrecision()); + yAxis2->ticker()->setTickCount(yAxis->ticker()->tickCount()); + yAxis2->ticker()->setTickOrigin(yAxis->ticker()->tickOrigin()); + + if (connectRanges) + { + connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); + connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); + } +} + +/*! + Returns a list of all the plottables that are associated with this axis rect. + + A plottable is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see graphs, items +*/ +QList QCPAxisRect::plottables() const +{ + // Note: don't append all QCPAxis::plottables() into a list, because we might get duplicate entries + QList result; + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis()->axisRect() == this || mParentPlot->mPlottables.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that are associated with this axis rect. + + A graph is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see plottables, items +*/ +QList QCPAxisRect::graphs() const +{ + // Note: don't append all QCPAxis::graphs() into a list, because we might get duplicate entries + QList result; + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis()->axisRect() == this || mParentPlot->mGraphs.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis rect. + + An item is considered associated with an axis rect if any of its positions has key or value axis + set to an axis that is in this axis rect, or if any of its positions has \ref + QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref + QCPAbstractItem::setClipAxisRect) is set to this axis rect. + + \see plottables, graphs +*/ +QList QCPAxisRect::items() const +{ + // Note: don't just append all QCPAxis::items() into a list, because we might get duplicate entries + // and miss those items that have this axis rect as clipAxisRect. + QList result; + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + if (mParentPlot->mItems.at(itemId)->clipAxisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + continue; + } + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdaxisRect() == this || + positions.at(posId)->keyAxis()->axisRect() == this || + positions.at(posId)->valueAxis()->axisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + This method is called automatically upon replot and doesn't need to be called by users of + QCPAxisRect. + + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), + and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its + QCPInsetLayout::update function. + + \seebaseclassmethod +*/ +void QCPAxisRect::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + switch (phase) + { + case upPreparation: + { + QList allAxes = axes(); + for (int i=0; isetupTickVectors(); + break; + } + case upLayout: + { + mInsetLayout->setOuterRect(rect()); + break; + } + default: break; + } + + // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): + mInsetLayout->update(phase); +} + +/* inherits documentation from base class */ +QList QCPAxisRect::elements(bool recursive) const +{ + QList result; + if (mInsetLayout) + { + result << mInsetLayout; + if (recursive) + result << mInsetLayout->elements(recursive); + } + return result; +} + +/* inherits documentation from base class */ +void QCPAxisRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPAxisRect::draw(QCPPainter *painter) +{ + drawBackground(painter); +} + +/*! + Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the + axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect + backgrounds are usually drawn below everything else. + + For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio + is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref + setBackground(const QBrush &brush). + + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) +*/ +void QCPAxisRect::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! \overload + + Sets \a brush as the background brush. The axis rect background will be filled with this brush. + Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds + are usually drawn below everything else. + + The brush will be drawn before (under) any background pixmap, which may be specified with \ref + setBackground(const QPixmap &pm). + + To disable drawing of a background brush, set \a brush to Qt::NoBrush. + + \see setBackground(const QPixmap &pm) +*/ +void QCPAxisRect::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled + is set to true, you may control whether and how the aspect ratio of the original pixmap is + preserved with \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the axis rect dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to + define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. + \see setBackground, setBackgroundScaled +*/ +void QCPAxisRect::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the range drag axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeDragAxes to retrieve a list with all set axes). + + \see setRangeDragAxes +*/ +QCPAxis *QCPAxisRect::rangeDragAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeDragHorzAxis.isEmpty() ? 0 : mRangeDragHorzAxis.first().data(); + else + return mRangeDragVertAxis.isEmpty() ? 0 : mRangeDragVertAxis.first().data(); +} + +/*! + Returns the range zoom axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeZoomAxes to retrieve a list with all set axes). + + \see setRangeZoomAxes +*/ +QCPAxis *QCPAxisRect::rangeZoomAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeZoomHorzAxis.isEmpty() ? 0 : mRangeZoomHorzAxis.first().data(); + else + return mRangeZoomVertAxis.isEmpty() ? 0 : mRangeZoomVertAxis.first().data(); +} + +/*! + Returns all range drag axes of the \a orientation provided. + + \see rangeZoomAxis, setRangeZoomAxes +*/ +QList QCPAxisRect::rangeDragAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + for (int i=0; i QCPAxisRect::rangeZoomAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + for (int i=0; iQt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeDrag to enable the range dragging interaction. + + \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag +*/ +void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) +{ + mRangeDrag = orientations; +} + +/*! + Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation + corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, + QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical + axis is the left axis (yAxis). + + To disable range zooming entirely, pass 0 as \a orientations or remove \ref QCP::iRangeZoom from \ref + QCustomPlot::setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeZoom to enable the range zooming interaction. + + \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag +*/ +void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) +{ + mRangeZoom = orientations; +} + +/*! \overload + + Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on + the QCustomPlot widget. Pass 0 if no axis shall be dragged in the respective orientation. + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to dragging interactions. + + \see setRangeZoomAxes +*/ +void QCPAxisRect::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical dragging. The drag + orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. drag a vertically oriented axis with a horizontal drag + motion, use the overload taking two separate lists for horizontal and vertical dragging. +*/ +void QCPAxisRect::setRangeDragAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical dragging, and + define specifically which axis reacts to which drag orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeDragAxes(QList horizontal, QList vertical) +{ + mRangeDragHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeDragVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on + the QCustomPlot widget. Pass 0 if no axis shall be zoomed in the respective orientation. + + The two axes can be zoomed with different strengths, when different factors are passed to \ref + setRangeZoomFactor(double horizontalFactor, double verticalFactor). + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to zooming interactions. + + \see setRangeDragAxes +*/ +void QCPAxisRect::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical range zooming. The + zoom orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. zoom a vertically oriented axis with a horizontal zoom + interaction, use the overload taking two separate lists for horizontal and vertical zooming. +*/ +void QCPAxisRect::setRangeZoomAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical zooming, and + define specifically which axis reacts to which zoom orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeZoomAxes(QList horizontal, QList vertical) +{ + mRangeZoomHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeZoomVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with + \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to + let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal + and which is vertical, can be set with \ref setRangeZoomAxes. + + When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) + will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the + same scrolling direction will zoom out. +*/ +void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFactor) +{ + mRangeZoomFactorHorz = horizontalFactor; + mRangeZoomFactorVert = verticalFactor; +} + +/*! \overload + + Sets both the horizontal and vertical zoom \a factor. +*/ +void QCPAxisRect::setRangeZoomFactor(double factor) +{ + mRangeZoomFactorHorz = factor; + mRangeZoomFactorVert = factor; +} + +/*! \internal + + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a + pixmap. + + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an + according filling inside the axis rect with the provided \a painter. + + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the axis rect with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::drawBackground(QCPPainter *painter) +{ + // draw background fill: + if (mBackgroundBrush != Qt::NoBrush) + painter->fillRect(mRect, mBackgroundBrush); + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mRect.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); + } + } +} + +/*! \internal + + This function makes sure multiple axes on the side specified with \a type don't collide, but are + distributed according to their respective space requirement (QCPAxis::calculateMargin). + + It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the + one with index zero. + + This function is called by \ref calculateAutoMargin. +*/ +void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) +{ + const QList axesList = mAxes.value(type); + if (axesList.isEmpty()) + return; + + bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false + for (int i=1; ioffset() + axesList.at(i-1)->calculateMargin(); + if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible) + { + if (!isFirstVisible) + offset += axesList.at(i)->tickLengthIn(); + isFirstVisible = false; + } + axesList.at(i)->setOffset(offset); + } +} + +/* inherits documentation from base class */ +int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) +{ + if (!mAutoMargins.testFlag(side)) + qDebug() << Q_FUNC_INFO << "Called with side that isn't specified as auto margin"; + + updateAxesOffset(QCPAxis::marginSideToAxisType(side)); + + // note: only need to look at the last (outer most) axis to determine the total margin, due to updateAxisOffset call + const QList axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); + if (axesList.size() > 0) + return axesList.last()->offset() + axesList.last()->calculateMargin(); + else + return 0; +} + +/*! \internal + + Reacts to a change in layout to potentially set the convenience axis pointers \ref + QCustomPlot::xAxis, \ref QCustomPlot::yAxis, etc. of the parent QCustomPlot to the respective + axes of this axis rect. This is only done if the respective convenience pointer is currently zero + and if there is no QCPAxisRect at position (0, 0) of the plot layout. + + This automation makes it simpler to replace the main axis rect with a newly created one, without + the need to manually reset the convenience pointers. +*/ +void QCPAxisRect::layoutChanged() +{ + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + if (axisCount(QCPAxis::atBottom) > 0 && !mParentPlot->xAxis) + mParentPlot->xAxis = axis(QCPAxis::atBottom); + if (axisCount(QCPAxis::atLeft) > 0 && !mParentPlot->yAxis) + mParentPlot->yAxis = axis(QCPAxis::atLeft); + if (axisCount(QCPAxis::atTop) > 0 && !mParentPlot->xAxis2) + mParentPlot->xAxis2 = axis(QCPAxis::atTop); + if (axisCount(QCPAxis::atRight) > 0 && !mParentPlot->yAxis2) + mParentPlot->yAxis2 = axis(QCPAxis::atRight); + } +} + +/*! \internal + + Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is + pressed, the range dragging interaction is initialized (the actual range manipulation happens in + the \ref mouseMoveEvent). + + The mDragging flag is set to true and some anchor points are set that are needed to determine the + distance the mouse was dragged in the mouse move/release events later. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + mDragStartHorzRange.clear(); + for (int i=0; irange()); + mDragStartVertRange.clear(); + for (int i=0; irange()); + } + } +} + +/*! \internal + + Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a + preceding \ref mousePressEvent, the range is moved accordingly. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + // Mouse range dragging interaction: + if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + + if (mRangeDrag.testFlag(Qt::Horizontal)) + { + for (int i=0; i= mDragStartHorzRange.size()) + break; + + //< Drag + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower+diff, mDragStartHorzRange.at(i).upper+diff); + + if(diff != 0) + { + mIsDragMove = true; + } + } + //< Scale + else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower*diff, mDragStartHorzRange.at(i).upper*diff); + if(diff != 0) + { + mIsDragMove = true; + } + } + } + } + + if (mRangeDrag.testFlag(Qt::Vertical)) + { + for (int i=0; i= mDragStartVertRange.size()) + break; + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower+diff, mDragStartVertRange.at(i).upper+diff); + } else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower*diff, mDragStartVertRange.at(i).upper*diff); + } + } + } + + if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot + { + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } + + } +} + +/* inherits documentation from base class */ +void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + + //< Note: update His Date + + if(mIsDragMove) + { + emit rangeDraged(); + mIsDragMove = false; + } + + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the + ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of + the scaling operation is the current cursor position inside the axis rect. The scaling factor is + dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural + zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. + + Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse + wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be + multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as + exponent of the range zoom factor. This takes care of the wheel direction automatically, by + inverting the factor, when the wheel step is negative (f^-1 = 1/f). +*/ +void QCPAxisRect::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) + { + if (mRangeZoom != 0) + { + double factor; + double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + if (mRangeZoom.testFlag(Qt::Horizontal)) + { + factor = qPow(mRangeZoomFactorHorz, wheelSteps); + for (int i=0; iscaleRange(factor,mRangeZoomHorzAxis.at(i)->range().upper); + } + else + { + mRangeZoomHorzAxis.at(i)->scaleRange(factor, mRangeZoomHorzAxis.at(i)->pixelToCoord(event->pos().x())); + } + emit rangeScaled(); + } + } + } + if (mRangeZoom.testFlag(Qt::Vertical)) + { + factor = qPow(mRangeZoomFactorVert, wheelSteps); + for (int i=0; iscaleRange(factor, mRangeZoomVertAxis.at(i)->pixelToCoord(event->pos().y())); + } + } + mParentPlot->replot(); + } + } +} +/* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-legend.cpp', size 31097 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractLegendItem + \brief The abstract base class for all entries in a QCPLegend. + + It defines a very basic interface for entries in a QCPLegend. For representing plottables in the + legend, the subclass \ref QCPPlottableLegendItem is more suitable. + + Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry + that's not even associated with a plottable). + + You must implement the following pure virtual functions: + \li \ref draw (from QCPLayerable) + + You inherit the following members you may use: + + + + + + + + +
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
+*/ + +/* start of documentation of signals */ + +/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) + + This signal is emitted when the selection state of this legend item has changed, either by user + interaction or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not + cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. +*/ +QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : + QCPLayoutElement(parent->parentPlot()), + mParentLegend(parent), + mFont(parent->font()), + mTextColor(parent->textColor()), + mSelectedFont(parent->selectedFont()), + mSelectedTextColor(parent->selectedTextColor()), + mSelectable(true), + mSelected(false) +{ + setLayer(QLatin1String("legend")); + setMargins(QMargins(0, 0, 0, 0)); +} + +/*! + Sets the default font of this specific legend item to \a font. + + \see setTextColor, QCPLegend::setFont +*/ +void QCPAbstractLegendItem::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the default text color of this specific legend item to \a color. + + \see setFont, QCPLegend::setTextColor +*/ +void QCPAbstractLegendItem::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + When this legend item is selected, \a font is used to draw generic text, instead of the normal + font set with \ref setFont. + + \see setFont, QCPLegend::setSelectedFont +*/ +void QCPAbstractLegendItem::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + When this legend item is selected, \a color is used to draw generic text, instead of the normal + color set with \ref setTextColor. + + \see setTextColor, QCPLegend::setSelectedTextColor +*/ +void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether this specific legend item is selectable. + + \see setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this specific legend item is selected. + + It is possible to set the selection state of this item by calling this function directly, even if + setSelectable is set to false. + + \see setSelectableParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (!mParentPlot) return -1; + if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) + return -1; + + if (mRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegendItems); +} + +/* inherits documentation from base class */ +QRect QCPAbstractLegendItem::clipRect() const +{ + return mOuterRect; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableLegendItem + \brief A legend item representing a plottable with an icon and the plottable name. + + This is the standard legend item for plottables. It displays an icon of the plottable next to the + plottable name. The icon is drawn by the respective plottable itself (\ref + QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. + For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the + middle. + + Legend items of this type are always associated with one plottable (retrievable via the + plottable() function and settable with the constructor). You may change the font of the plottable + name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref + QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. + + The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend + creates/removes legend items of this type. + + Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of + QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout + interface, QCPLegend has specialized functions for handling legend items conveniently, see the + documentation of \ref QCPLegend. +*/ + +/*! + Creates a new legend item associated with \a plottable. + + Once it's created, it can be added to the legend via \ref QCPLegend::addItem. + + A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref + QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. +*/ +QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : + QCPAbstractLegendItem(parent), + mPlottable(plottable) +{ + setAntialiased(false); +} + +/*! \internal + + Returns the pen that shall be used to draw the icon border, taking into account the selection + state of this item. +*/ +QPen QCPPlottableLegendItem::getIconBorderPen() const +{ + return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); +} + +/*! \internal + + Returns the text color that shall be used to draw text, taking into account the selection state + of this item. +*/ +QColor QCPPlottableLegendItem::getTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + +/*! \internal + + Returns the font that shall be used to draw text, taking into account the selection state of this + item. +*/ +QFont QCPPlottableLegendItem::getFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Draws the item with \a painter. The size and position of the drawn legend item is defined by the + parent layout (typically a \ref QCPLegend) and the \ref minimumOuterSizeHint and \ref + maximumOuterSizeHint of this legend item. +*/ +void QCPPlottableLegendItem::draw(QCPPainter *painter) +{ + if (!mPlottable) return; + painter->setFont(getFont()); + painter->setPen(QPen(getTextColor())); + QSizeF iconSize = mParentLegend->iconSize(); + QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); + QRectF iconRect(mRect.topLeft(), iconSize); + int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops + painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->desc()); + // draw icon: + painter->save(); + painter->setClipRect(iconRect, Qt::IntersectClip); + mPlottable->drawLegendIcon(painter, iconRect); + painter->restore(); + // draw icon border: + if (getIconBorderPen().style() != Qt::NoPen) + { + painter->setPen(getIconBorderPen()); + painter->setBrush(Qt::NoBrush); + int halfPen = qCeil(painter->pen().widthF()*0.5)+1; + painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped + painter->drawRect(iconRect); + } +} + +/*! \internal + + Calculates and returns the size of this item. This includes the icon, the text and the padding in + between. + + \seebaseclassmethod +*/ +QSize QCPPlottableLegendItem::minimumOuterSizeHint() const +{ + if (!mPlottable) return QSize(); + QSize result(0, 0); + QRect textRect; + QFontMetrics fontMetrics(getFont()); + QSize iconSize = mParentLegend->iconSize(); + textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); + result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); + result.setHeight(qMax(textRect.height(), iconSize.height())); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLegend +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLegend + \brief Manages a legend inside a QCustomPlot. + + A legend is a small box somewhere in the plot which lists plottables with their name and icon. + + A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the + plottable, for which a legend item shall be created. In the case of the main legend (\ref + QCustomPlot::legend), simply adding plottables to the plot while \ref + QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding + legend items. The legend item associated with a certain plottable can be removed with \ref + QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and + manipulate legend items directly: \ref item, \ref itemWithPlottable, \ref itemCount, \ref + addItem, \ref removeItem, etc. + + Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref + QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement + "QCPLayoutElements" which are placed in the grid layout of the legend. \ref QCPLegend only adds + an interface specialized for handling child elements of type \ref QCPAbstractLegendItem, as + mentioned above. In principle, any other layout elements may also be added to a legend via the + normal \ref QCPLayoutGrid interface. See the special page about \link thelayoutsystem The Layout + System\endlink for examples on how to add other elements to the legend and move it outside the axis + rect. + + Use the methods \ref setFillOrder and \ref setWrap inherited from \ref QCPLayoutGrid to control + in which order (column first or row first) the legend is filled up when calling \ref addItem, and + at which column or row wrapping occurs. + + By default, every QCustomPlot has one legend (\ref QCustomPlot::legend) which is placed in the + inset layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another + position inside the axis rect, use the methods of the \ref QCPLayoutInset. To move the legend + outside of the axis rect, place it anywhere else with the \ref QCPLayout/\ref QCPLayoutElement + interface. +*/ + +/* start of documentation of signals */ + +/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); + + This signal is emitted when the selection state of this legend has changed. + + \see setSelectedParts, setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs a new QCPLegend instance with default values. + + Note that by default, QCustomPlot already contains a legend ready to be used as \ref + QCustomPlot::legend +*/ +QCPLegend::QCPLegend() +{ + setFillOrder(QCPLayoutGrid::foRowsFirst); + setWrap(0); + + setRowSpacing(3); + setColumnSpacing(8); + setMargins(QMargins(7, 5, 7, 4)); + setAntialiased(false); + setIconSize(32, 18); + + setIconTextPadding(7); + + setSelectableParts(spLegendBox | spItems); + setSelectedParts(spNone); + + setBorderPen(QPen(Qt::black, 0)); + setSelectedBorderPen(QPen(Qt::blue, 2)); + setIconBorderPen(Qt::NoPen); + setSelectedIconBorderPen(QPen(Qt::blue, 2)); + setBrush(Qt::white); + setSelectedBrush(Qt::white); + setTextColor(Qt::black); + setSelectedTextColor(Qt::blue); +} + +QCPLegend::~QCPLegend() +{ + clearItems(); + if (qobject_cast(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot) + mParentPlot->legendRemoved(this); +} + +/* no doc for getter, see setSelectedParts */ +QCPLegend::SelectableParts QCPLegend::selectedParts() const +{ + // check whether any legend elements selected, if yes, add spItems to return value + bool hasSelectedItems = false; + for (int i=0; iselected()) + { + hasSelectedItems = true; + break; + } + } + if (hasSelectedItems) + return mSelectedParts | spItems; + else + return mSelectedParts & ~spItems; +} + +/*! + Sets the pen, the border of the entire legend is drawn with. +*/ +void QCPLegend::setBorderPen(const QPen &pen) +{ + mBorderPen = pen; +} + +/*! + Sets the brush of the legend background. +*/ +void QCPLegend::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will + use this font by default. However, a different font can be specified on a per-item-basis by + accessing the specific legend item. + + This function will also set \a font on all already existing legend items. + + \see QCPAbstractLegendItem::setFont +*/ +void QCPLegend::setFont(const QFont &font) +{ + mFont = font; + for (int i=0; isetFont(mFont); + } +} + +/*! + Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) + will use this color by default. However, a different colors can be specified on a per-item-basis + by accessing the specific legend item. + + This function will also set \a color on all already existing legend items. + + \see QCPAbstractLegendItem::setTextColor +*/ +void QCPLegend::setTextColor(const QColor &color) +{ + mTextColor = color; + for (int i=0; isetTextColor(color); + } +} + +/*! + Sets the size of legend icons. Legend items that draw an icon (e.g. a visual + representation of the graph) will use this size by default. +*/ +void QCPLegend::setIconSize(const QSize &size) +{ + mIconSize = size; +} + +/*! \overload +*/ +void QCPLegend::setIconSize(int width, int height) +{ + mIconSize.setWidth(width); + mIconSize.setHeight(height); +} + +/*! + Sets the horizontal space in pixels between the legend icon and the text next to it. + Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the + name of the graph) will use this space by default. +*/ +void QCPLegend::setIconTextPadding(int padding) +{ + mIconTextPadding = padding; +} + +/*! + Sets the pen used to draw a border around each legend icon. Legend items that draw an + icon (e.g. a visual representation of the graph) will use this pen by default. + + If no border is wanted, set this to \a Qt::NoPen. +*/ +void QCPLegend::setIconBorderPen(const QPen &pen) +{ + mIconBorderPen = pen; +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPLegend::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected + doesn't contain \ref spItems, those items become deselected. + + The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions + contains iSelectLegend. You only need to call this function when you wish to change the selection + state manually. + + This function can change the selection state of a part even when \ref setSelectableParts was set to a + value that actually excludes the part. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set + before, because there's no way to specify which exact items to newly select. Do this by calling + \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, + setSelectedFont +*/ +void QCPLegend::setSelectedParts(const SelectableParts &selected) +{ + SelectableParts newSelected = selected; + mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed + + if (mSelectedParts != newSelected) + { + if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that) + { + qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function"; + newSelected &= ~spItems; + } + if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems)) // spItems flag was unset, so clear item selection + { + for (int i=0; isetSelected(false); + } + } + mSelectedParts = newSelected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + When the legend box is selected, this pen is used to draw the border instead of the normal pen + set via \ref setBorderPen. + + \see setSelectedParts, setSelectableParts, setSelectedBrush +*/ +void QCPLegend::setSelectedBorderPen(const QPen &pen) +{ + mSelectedBorderPen = pen; +} + +/*! + Sets the pen legend items will use to draw their icon borders, when they are selected. + + \see setSelectedParts, setSelectableParts, setSelectedFont +*/ +void QCPLegend::setSelectedIconBorderPen(const QPen &pen) +{ + mSelectedIconBorderPen = pen; +} + +/*! + When the legend box is selected, this brush is used to draw the legend background instead of the normal brush + set via \ref setBrush. + + \see setSelectedParts, setSelectableParts, setSelectedBorderPen +*/ +void QCPLegend::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the default font that is used by legend items when they are selected. + + This function will also set \a font on all already existing legend items. + + \see setFont, QCPAbstractLegendItem::setSelectedFont +*/ +void QCPLegend::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; + for (int i=0; isetSelectedFont(font); + } +} + +/*! + Sets the default text color that is used by legend items when they are selected. + + This function will also set \a color on all already existing legend items. + + \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor +*/ +void QCPLegend::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; + for (int i=0; isetSelectedTextColor(color); + } +} + +/*! + Returns the item with index \a i. + + Note that the linear index depends on the current fill order (\ref setFillOrder). + + \see itemCount, addItem, itemWithPlottable +*/ +QCPAbstractLegendItem *QCPLegend::item(int index) const +{ + return qobject_cast(elementAt(index)); +} + +/*! + Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns 0. + + \see hasItemWithPlottable +*/ +QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + for (int i=0; i(item(i))) + { + if (pli->plottable() == plottable) + return pli; + } + } + return 0; +} + +/*! + Returns the number of items currently in the legend. + + Note that if empty cells are in the legend (e.g. by calling methods of the \ref QCPLayoutGrid + base class which allows creating empty cells), they are included in the returned count. + + \see item +*/ +int QCPLegend::itemCount() const +{ + return elementCount(); +} + +/*! + Returns whether the legend contains \a item. + + \see hasItemWithPlottable +*/ +bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const +{ + for (int i=0; iitem(i)) + return true; + } + return false; +} + +/*! + Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns false. + + \see itemWithPlottable +*/ +bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + return itemWithPlottable(plottable); +} + +/*! + Adds \a item to the legend, if it's not present already. The element is arranged according to the + current fill order (\ref setFillOrder) and wrapping (\ref setWrap). + + Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. + + The legend takes ownership of the item. + + \see removeItem, item, hasItem +*/ +bool QCPLegend::addItem(QCPAbstractLegendItem *item) +{ + return addElement(item); +} + +/*! \overload + + Removes the item with the specified \a index from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. Unlike \ref QCPLayoutGrid::removeAt, this method only removes + elements derived from \ref QCPAbstractLegendItem. + + \see itemCount, clearItems +*/ +bool QCPLegend::removeItem(int index) +{ + if (QCPAbstractLegendItem *ali = item(index)) + { + bool success = remove(ali); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; + } else + return false; +} + +/*! \overload + + Removes \a item from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. + + \see clearItems +*/ +bool QCPLegend::removeItem(QCPAbstractLegendItem *item) +{ + bool success = remove(item); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; +} + +/*! + Removes all items from the legend. +*/ +void QCPLegend::clearItems() +{ + for (int i=itemCount()-1; i>=0; --i) + removeItem(i); +} + +/*! + Returns the legend items that are currently selected. If no items are selected, + the list is empty. + + \see QCPAbstractLegendItem::setSelected, setSelectable +*/ +QList QCPLegend::selectedItems() const +{ + QList result; + for (int i=0; iselected()) + result.append(ali); + } + } + return result; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing main legend elements. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); +} + +/*! \internal + + Returns the pen used to paint the border of the legend, taking into account the selection state + of the legend box. +*/ +QPen QCPLegend::getBorderPen() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; +} + +/*! \internal + + Returns the brush used to paint the background of the legend, taking into account the selection + state of the legend box. +*/ +QBrush QCPLegend::getBrush() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush; +} + +/*! \internal + + Draws the legend box with the provided \a painter. The individual legend items are layerables + themselves, thus are drawn independently. +*/ +void QCPLegend::draw(QCPPainter *painter) +{ + // draw background rect: + painter->setBrush(getBrush()); + painter->setPen(getBorderPen()); + painter->drawRect(mOuterRect); +} + +/* inherits documentation from base class */ +double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) + return -1; + + if (mOuterRect.contains(pos.toPoint())) + { + if (details) details->setValue(spLegendBox); + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/* inherits documentation from base class */ +void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + mSelectedParts = selectedParts(); // in case item selection has changed + if (details.value() == spLegendBox && mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent) + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPLegend::deselectEvent(bool *selectionStateChanged) +{ + mSelectedParts = selectedParts(); // in case item selection has changed + if (mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(selectedParts() & ~spLegendBox); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPLegend::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractLegendItem::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) +{ + if (parentPlot && !parentPlot->legend) + parentPlot->legend = this; +} +/* end of 'src/layoutelements/layoutelement-legend.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12761 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPTextElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPTextElement + \brief A layout element displaying a text + + The text may be specified with \ref setText, the formatting can be controlled with \ref setFont, + \ref setTextColor, and \ref setTextFlags. + + A text element can be added as follows: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcptextelement-creation +*/ + +/* start documentation of signals */ + +/*! \fn void QCPTextElement::selectionChanged(bool selected) + + This signal is emitted when the selection state has changed to \a selected, either by user + interaction or by a direct call to \ref setSelected. + + \see setSelected, setSelectable +*/ + +/*! \fn void QCPTextElement::clicked(QMouseEvent *event) + + This signal is emitted when the text element is clicked. + + \see doubleClicked, selectTest +*/ + +/*! \fn void QCPTextElement::doubleClicked(QMouseEvent *event) + + This signal is emitted when the text element is double clicked. + + \see clicked, selectTest +*/ + +/* end documentation of signals */ + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref + setText). +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mText(), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mFont.setPointSizeF(pointSize); + mSelectedFont = parentPlot->font(); + mSelectedFont.setPointSizeF(pointSize); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize and the specified \a fontFamily. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(fontFamily, pointSize)), + mTextColor(Qt::black), + mSelectedFont(QFont(fontFamily, pointSize)), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with the specified \a font. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(font), + mTextColor(Qt::black), + mSelectedFont(font), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! + Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". + + \see setFont, setTextColor, setTextFlags +*/ +void QCPTextElement::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of + \c Qt::AlignmentFlag and \c Qt::TextFlag enums. + + Possible enums are: + - Qt::AlignLeft + - Qt::AlignRight + - Qt::AlignHCenter + - Qt::AlignJustify + - Qt::AlignTop + - Qt::AlignBottom + - Qt::AlignVCenter + - Qt::AlignCenter + - Qt::TextDontClip + - Qt::TextSingleLine + - Qt::TextExpandTabs + - Qt::TextShowMnemonic + - Qt::TextWordWrap + - Qt::TextIncludeTrailingSpaces +*/ +void QCPTextElement::setTextFlags(int flags) +{ + mTextFlags = flags; +} + +/*! + Sets the \a font of the text. + + \see setTextColor, setSelectedFont +*/ +void QCPTextElement::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the \a color of the text. + + \see setFont, setSelectedTextColor +*/ +void QCPTextElement::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + Sets the \a font of the text that will be used if the text element is selected (\ref setSelected). + + \see setFont +*/ +void QCPTextElement::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the \a color of the text that will be used if the text element is selected (\ref setSelected). + + \see setTextColor +*/ +void QCPTextElement::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether the user may select this text element. + + Note that even when \a selectable is set to false, the selection state may be changed + programmatically via \ref setSelected. +*/ +void QCPTextElement::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets the selection state of this text element to \a selected. If the selection has changed, \ref + selectionChanged is emitted. + + Note that this function can change the selection state independently of the current \ref + setSelectable state. +*/ +void QCPTextElement::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +void QCPTextElement::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/* inherits documentation from base class */ +void QCPTextElement::draw(QCPPainter *painter) +{ + painter->setFont(mainFont()); + painter->setPen(QPen(mainTextColor())); + painter->drawText(mRect, Qt::AlignCenter, mText, &mTextBoundingRect); +} + +/* inherits documentation from base class */ +QSize QCPTextElement::minimumOuterSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +QSize QCPTextElement::maximumOuterSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); + result.setWidth(QWIDGETSIZE_MAX); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +void QCPTextElement::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPTextElement::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/*! + Returns 0.99*selectionTolerance (see \ref QCustomPlot::setSelectionTolerance) when \a pos is + within the bounding box of the text element's text. Note that this bounding box is updated in the + draw call. + + If \a pos is outside the text's bounding box or if \a onlySelectable is true and this text + element is not selectable (\ref setSelectable), returns -1. + + \seebaseclassmethod +*/ +double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + if (mTextBoundingRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/*! + Accepts the mouse event in order to emit the according click signal in the \ref + mouseReleaseEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->accept(); +} + +/*! + Emits the \ref clicked signal if the cursor hasn't moved by more than a few pixels since the \ref + mousePressEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if ((QPointF(event->pos())-startPos).manhattanLength() <= 3) + emit clicked(event); +} + +/*! + Emits the \ref doubleClicked signal. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + emit doubleClicked(event); +} + +/*! \internal + + Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to + true, else mFont is returned. +*/ +QFont QCPTextElement::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to + true, else mTextColor is returned. +*/ +QColor QCPTextElement::mainTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} +/* end of 'src/layoutelements/layoutelement-textelement.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.cpp', size 25770 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScale +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScale + \brief A color scale for use with color coding data such as QCPColorMap + + This layout element can be placed on the plot to correlate a color gradient with data values. It + is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". + + \image html QCPColorScale.png + + The color scale can be either horizontal or vertical, as shown in the image above. The + orientation and the side where the numbers appear is controlled with \ref setType. + + Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are + connected, they share their gradient, data range and data scale type (\ref setGradient, \ref + setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color + scale, to make them all synchronize these properties. + + To have finer control over the number display and axis behaviour, you can directly access the + \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if + you want to change the number of automatically generated ticks, call + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-tickcount + + Placing a color scale next to the main axis rect works like with any other layout element: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation + In this case we have placed it to the right of the default axis rect, so it wasn't necessary to + call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color + scale can be set with \ref setLabel. + + For optimum appearance (like in the image above), it may be desirable to line up the axis rect and + the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup + + Color scales are initialized with a non-zero minimum top and bottom margin (\ref + setMinimumMargins), because vertical color scales are most common and the minimum top/bottom + margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a + horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you + might want to also change the minimum margins accordingly, e.g. setMinimumMargins(QMargins(6, 0, 6, 0)). +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPAxis *QCPColorScale::axis() const + + Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the + appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its + interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref + setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref + QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on + the QCPColorScale or on its QCPAxis. + + If the type of the color scale is changed with \ref setType, the axis returned by this method + will change, too, to either the left, right, bottom or top axis, depending on which type was set. +*/ + +/* end documentation of signals */ +/* start documentation of signals */ + +/*! \fn void QCPColorScale::dataRangeChanged(const QCPRange &newRange); + + This signal is emitted when the data range changes. + + \see setDataRange +*/ + +/*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the data scale type changes. + + \see setDataScaleType +*/ + +/*! \fn void QCPColorScale::gradientChanged(const QCPColorGradient &newGradient); + + This signal is emitted when the gradient changes. + + \see setGradient +*/ + +/* end documentation of signals */ + +/*! + Constructs a new QCPColorScale. +*/ +QCPColorScale::QCPColorScale(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight + mDataScaleType(QCPAxis::stLinear), + mBarWidth(20), + mAxisRect(new QCPColorScaleAxisRectPrivate(this)) +{ + setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used) + setType(QCPAxis::atRight); + setDataRange(QCPRange(0, 6)); +} + +QCPColorScale::~QCPColorScale() +{ + delete mAxisRect; +} + +/* undocumented getter */ +QString QCPColorScale::label() const +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return QString(); + } + + return mColorAxis.data()->label(); +} + +/* undocumented getter */ +bool QCPColorScale::rangeDrag() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/* undocumented getter */ +bool QCPColorScale::rangeZoom() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/*! + Sets at which side of the color scale the axis is placed, and thus also its orientation. + + Note that after setting \a type to a different value, the axis returned by \ref axis() will + be a different one. The new axis will adopt the following properties from the previous axis: The + range, scale type, label and ticker (the latter will be shared and not copied). +*/ +void QCPColorScale::setType(QCPAxis::AxisType type) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + if (mType != type) + { + mType = type; + QCPRange rangeTransfer(0, 6); + QString labelTransfer; + QSharedPointer tickerTransfer; + // transfer/revert some settings on old axis if it exists: + bool doTransfer = (bool)mColorAxis; + if (doTransfer) + { + rangeTransfer = mColorAxis.data()->range(); + labelTransfer = mColorAxis.data()->label(); + tickerTransfer = mColorAxis.data()->ticker(); + mColorAxis.data()->setLabel(QString()); + disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + QList allAxisTypes = QList() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop; + foreach (QCPAxis::AxisType atype, allAxisTypes) + { + mAxisRect.data()->axis(atype)->setTicks(atype == mType); + mAxisRect.data()->axis(atype)->setTickLabels(atype== mType); + } + // set new mColorAxis pointer: + mColorAxis = mAxisRect.data()->axis(mType); + // transfer settings to new axis: + if (doTransfer) + { + mColorAxis.data()->setRange(rangeTransfer); // range transfer necessary if axis changes from vertical to horizontal or vice versa (axes with same orientation are synchronized via signals) + mColorAxis.data()->setLabel(labelTransfer); + mColorAxis.data()->setTicker(tickerTransfer); + } + connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + mAxisRect.data()->setRangeDragAxes(QList() << mColorAxis.data()); + } +} + +/*! + Sets the range spanned by the color gradient and that is shown by the axis in the color scale. + + It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its range with \ref + QCPAxis::setRange. + + \see setDataScaleType, setGradient, rescaleDataRange +*/ +void QCPColorScale::setDataRange(const QCPRange &dataRange) +{ + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + mDataRange = dataRange; + if (mColorAxis) + mColorAxis.data()->setRange(mDataRange); + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets the scale type of the color scale, i.e. whether values are linearly associated with colors + or logarithmically. + + It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its scale type with \ref + QCPAxis::setScaleType. + + \see setDataRange, setGradient +*/ +void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + if (mColorAxis) + mColorAxis.data()->setScaleType(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + emit dataScaleTypeChanged(mDataScaleType); + } +} + +/*! + Sets the color gradient that will be used to represent data values. + + It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. + + \see setDataRange, setDataScaleType +*/ +void QCPColorScale::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + if (mAxisRect) + mAxisRect.data()->mGradientImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on + the internal \ref axis. +*/ +void QCPColorScale::setLabel(const QString &str) +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return; + } + + mColorAxis.data()->setLabel(str); +} + +/*! + Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed + will have. +*/ +void QCPColorScale::setBarWidth(int width) +{ + mBarWidth = width; +} + +/*! + Sets whether the user can drag the data range (\ref setDataRange). + + Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeDrag(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeDrag(0); +} + +/*! + Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. + + Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeZoom(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeZoom(0); +} + +/*! + Returns a list of all the color maps associated with this color scale. +*/ +QList QCPColorScale::colorMaps() const +{ + QList result; + for (int i=0; iplottableCount(); ++i) + { + if (QCPColorMap *cm = qobject_cast(mParentPlot->plottable(i))) + if (cm->colorScale() == this) + result.append(cm); + } + return result; +} + +/*! + Changes the data range such that all color maps associated with this color scale are fully mapped + to the gradient in the data dimension. + + \see setDataRange +*/ +void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) +{ + QList maps = colorMaps(); + QCPRange newRange; + bool haveRange = false; + QCP::SignDomain sign = QCP::sdBoth; + if (mDataScaleType == QCPAxis::stLogarithmic) + sign = (mDataRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + for (int i=0; irealVisibility() && onlyVisibleMaps) + continue; + QCPRange mapRange; + if (maps.at(i)->colorScale() == this) + { + bool currentFoundRange = true; + mapRange = maps.at(i)->data()->dataBounds(); + if (sign == QCP::sdPositive) + { + if (mapRange.lower <= 0 && mapRange.upper > 0) + mapRange.lower = mapRange.upper*1e-3; + else if (mapRange.lower <= 0 && mapRange.upper <= 0) + currentFoundRange = false; + } else if (sign == QCP::sdNegative) + { + if (mapRange.upper >= 0 && mapRange.lower < 0) + mapRange.upper = mapRange.lower*1e-3; + else if (mapRange.upper >= 0 && mapRange.lower >= 0) + currentFoundRange = false; + } + if (currentFoundRange) + { + if (!haveRange) + newRange = mapRange; + else + newRange.expand(mapRange); + haveRange = true; + } + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mDataScaleType == QCPAxis::stLinear) + { + newRange.lower = center-mDataRange.size()/2.0; + newRange.upper = center+mDataRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mDataRange.upper/mDataRange.lower); + newRange.upper = center*qSqrt(mDataRange.upper/mDataRange.lower); + } + } + setDataRange(newRange); + } +} + +/* inherits documentation from base class */ +void QCPColorScale::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + mAxisRect.data()->update(phase); + + switch (phase) + { + case upMargins: + { + if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) + { + setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); + setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); + } else + { + setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), QWIDGETSIZE_MAX); + setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), 0); + } + break; + } + case upLayout: + { + mAxisRect.data()->setOuterRect(rect()); + break; + } + default: break; + } +} + +/* inherits documentation from base class */ +void QCPColorScale::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPColorScale::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mousePressEvent(event, details); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseMoveEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseReleaseEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::wheelEvent(QWheelEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->wheelEvent(event); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScaleAxisRectPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScaleAxisRectPrivate + + \internal + \brief An axis rect subclass for use in a QCPColorScale + + This is a private class and not part of the public QCustomPlot interface. + + It provides the axis rect functionality for the QCPColorScale class. +*/ + + +/*! + Creates a new instance, as a child of \a parentColorScale. +*/ +QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale) : + QCPAxisRect(parentColorScale->parentPlot(), true), + mParentColorScale(parentColorScale), + mGradientImageInvalidated(true) +{ + setParentLayerable(parentColorScale); + setMinimumMargins(QMargins(0, 0, 0, 0)); + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + axis(type)->setVisible(true); + axis(type)->grid()->setVisible(false); + axis(type)->setPadding(0); + connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts))); + connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts))); + } + + connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); + + // make layer transfers of color scale transfer to axis rect and axes + // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); + foreach (QCPAxis::AxisType type, allAxisTypes) + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), axis(type), SLOT(setLayer(QCPLayer*))); +} + +/*! \internal + + Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws + it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. + + \seebaseclassmethod +*/ +void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) +{ + if (mGradientImageInvalidated) + updateGradientImage(); + + bool mirrorHorz = false; + bool mirrorVert = false; + if (mParentColorScale->mColorAxis) + { + mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); + mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); + } + + painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); + QCPAxisRect::draw(painter); +} + +/*! \internal + + Uses the current gradient of the parent \ref QCPColorScale (specified in the constructor) to + generate a gradient image. This gradient image will be used in the \ref draw method. +*/ +void QCPColorScaleAxisRectPrivate::updateGradientImage() +{ + if (rect().isEmpty()) + return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + int n = mParentColorScale->mGradient.levelCount(); + int w, h; + QVector data(n); + for (int i=0; imType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop) + { + w = n; + h = rect().height(); + mGradientImage = QImage(w, h, format); + QVector pixels; + for (int y=0; y(mGradientImage.scanLine(y))); + mParentColorScale->mGradient.colorize(data.constData(), QCPRange(0, n-1), pixels.first(), n); + for (int y=1; y(mGradientImage.scanLine(y)); + const QRgb lineColor = mParentColorScale->mGradient.color(data[h-1-y], QCPRange(0, n-1)); + for (int x=0; x allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectedParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectedParts(axis(type)->selectedParts() | QCPAxis::spAxis); + else + axis(type)->setSelectedParts(axis(type)->selectedParts() & ~QCPAxis::spAxis); + } + } +} + +/*! \internal + + This slot is connected to the selectableChanged signals of the four axes in the constructor. It + synchronizes the selectability of the axes. +*/ +void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts) +{ + // synchronize axis base selectability: + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectableParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectableParts(axis(type)->selectableParts() | QCPAxis::spAxis); + else + axis(type)->setSelectableParts(axis(type)->selectableParts() & ~QCPAxis::spAxis); + } + } +} +/* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ + + +/* including file 'src/plottables/plottable-graph.cpp', size 73960 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraphData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraphData + \brief Holds the data of one single data point for QCPGraph. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a value: coordinate on the value axis of this data point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPGraphData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPGraphDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPGraphData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPGraphData QCPGraphData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPGraphData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPGraphData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and value set to zero. +*/ +QCPGraphData::QCPGraphData() : + key(0), + value(0) +{ +} + +/*! + Constructs a data point with the specified \a key and \a value. +*/ +QCPGraphData::QCPGraphData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraph +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraph + \brief A plottable representing a graph in a plot. + + \image html QCPGraph.png + + Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be + accessed via QCustomPlot::graph. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPGraphDataContainer. + + Graphs are used to display single-valued data. Single-valued means that there should only be one + data point per unique key coordinate. In other words, the graph can't have \a loops. If you do + want to plot non-single-valued curves, rather use the QCPCurve plottable. + + Gaps in the graph line can be created by adding data points with NaN as value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpgraph-appearance Changing the appearance + + The appearance of the graph is mainly determined by the line style, scatter style, brush and pen + of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). + + \subsection filling Filling under or between graphs + + QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to + the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, + just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. + + By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill + between this graph and another one, call \ref setChannelFillGraph with the other graph as + parameter. + + \see QCustomPlot::addGraph, QCustomPlot::graph +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPGraph::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually + but use QCustomPlot::removePlottable() instead. + + To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. +*/ +QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis) +{ + // special handling for QCPGraphs to maintain the simple graph interface: + mParentPlot->registerGraph(this); + + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setLineStyle(lsLine); + setScatterSkip(0); + setChannelFillGraph(0); + setAdaptiveSampling(true); +} + +QCPGraph::~QCPGraph() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPGraphs may share the same data container safely. + Modifying the data in the container will then affect all graphs that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the graph's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-2 + + \see addData +*/ +void QCPGraph::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPGraph::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to + \ref lsNone and \ref setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPGraph::setLineStyle(LineStyle ls) +{ + mLineStyle = ls; +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPGraph::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPGraph::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets the target graph for filling the area between this graph and \a targetGraph with the current + brush (\ref setBrush). + + When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To + disable any filling, set the brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) +{ + // prevent setting channel target to this graph itself: + if (targetGraph == this) + { + qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; + mChannelFillGraph = 0; + return; + } + // prevent setting channel target to a graph not in the plot: + if (targetGraph && targetGraph->mParentPlot != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; + mChannelFillGraph = 0; + return; + } + + mChannelFillGraph = targetGraph; +} + +/*! + Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive + sampling technique can drastically improve the replot performance for graphs with a larger number + of points (e.g. above 10,000), without notably changing the appearance of the graph. + + By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive + sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no + disadvantage in almost all cases. + + \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" + + As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are + reproduced reliably, as well as the overall shape of the data set. The replot time reduces + dramatically though. This allows QCustomPlot to display large amounts of data in realtime. + + \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" + + Care must be taken when using high-density scatter plots in combination with adaptive sampling. + The adaptive sampling algorithm treats scatter plots more carefully than line plots which still + gives a significant reduction of replot times, but not quite as much as for line plots. This is + because scatter plots inherently need more data points to be preserved in order to still resemble + the original, non-adaptive-sampling plot. As shown above, the results still aren't quite + identical, as banding occurs for the outer data points. This is in fact intentional, such that + the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, + depends on the point density, i.e. the number of points in the plot. + + For some situations with scatter plots it might thus be desirable to manually turn adaptive + sampling off. For example, when saving the plot to disk. This can be achieved by setting \a + enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled + back to true afterwards. +*/ +void QCPGraph::setAdaptiveSampling(bool enabled) +{ + mAdaptiveSampling = enabled; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(double key, double value) +{ + mDataContainer->add(QCPGraphData(key, value)); +} + +double QCPGraph::value(const double &key) +{ + QCPDataContainer::const_iterator lower = mDataContainer->findBegin(key, true); + if(lower == mDataContainer->constEnd()) + { + return qSqrt(-1.); + } + + if(lsStepLeft == mLineStyle) + { + return lower->value; + } + + QCPDataContainer::const_iterator upper = mDataContainer->findEnd(key, false); + if(upper == mDataContainer->constEnd()) + { + return qSqrt(-1.); + } + + if(upper->key == lower->key) + { + return lower->value; + } + + double rate = (upper->value - lower->value) / (upper->key - lower->key); + return rate * (key - lower->key) + lower->value; +} + +/* inherits documentation from base class */ +double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPGraph::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + if (mLineStyle == lsNone && mScatterStyle.isNone()) return; + + QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + // get line pixel points appropriate to line style: + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) + getLines(&lines, lineDataRange); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPGraphDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } +#endif + + // draw fill of graph: + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + drawFill(painter, &lines); + + // draw line: + if (mLineStyle != lsNone) + { + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + painter->setBrush(Qt::NoBrush); + if (mLineStyle == lsImpulse) + drawImpulsePlot(painter, lines); + else + drawLinePlot(painter, lines); // also step plots can be drawn as a line plot + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i)); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedLineData, an branches + out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc. + according to the line style of the graph. + + \a lines will be filled with points in pixel coordinates, that can be drawn with the according + draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines + aren't necessarily the original data points. For example, step line styles require additional + points to form the steps when drawn. If the line style of the graph is \ref lsNone, the \a + lines vector will be empty. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. + + \see getScatters +*/ +void QCPGraph::getLines(QVector *lines, const QCPDataRange &dataRange) const +{ + if (!lines) return; + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + lines->clear(); + return; + } + + QVector lineData; + if (mLineStyle != lsNone) + getOptimizedLineData(&lineData, begin, end); + + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in lineData (significantly simplifies following processing) + std::reverse(lineData.begin(), lineData.end()); + + switch (mLineStyle) + { + case lsNone: lines->clear(); break; + case lsLine: *lines = dataToLines(lineData); break; + case lsStepLeft: *lines = dataToStepLeftLines(lineData); break; + case lsStepRight: *lines = dataToStepRightLines(lineData); break; + case lsStepCenter: *lines = dataToStepCenterLines(lineData); break; + case lsImpulse: *lines = dataToImpulseLines(lineData); break; + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedScatterData and then + converts them to pixel coordinates. The resulting points are returned in \a scatters, and can be + passed to \ref drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. +*/ +void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataRange) const +{ + if (!scatters) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; } + + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + scatters->clear(); + return; + } + + QVector data; + getOptimizedScatterData(&data, begin, end); + + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in data (significantly simplifies following processing) + std::reverse(data.begin(), data.end()); + + scatters->resize(data.size()); + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + (*scatters)[i].setY(keyAxis->coordToPixel(data.at(i).key)); + } + } + } else + { + for (int i=0; icoordToPixel(data.at(i).key)); + (*scatters)[i].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsLine. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + result[i].setY(keyAxis->coordToPixel(data.at(i).key)); + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key)); + result[i].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepLeft. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepLeftLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastValue = valueAxis->coordToPixel(data.first().value); + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(lastValue); + result[i*2+0].setY(key); + lastValue = valueAxis->coordToPixel(data.at(i).value); + result[i*2+1].setX(lastValue); + result[i*2+1].setY(key); + } + } else // key axis is horizontal + { + double lastValue = valueAxis->coordToPixel(data.first().value); + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(lastValue); + lastValue = valueAxis->coordToPixel(data.at(i).value); + result[i*2+1].setX(key); + result[i*2+1].setY(lastValue); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepRight. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepRightLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + result[i*2+0].setX(value); + result[i*2+0].setY(lastKey); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+1].setX(value); + result[i*2+1].setY(lastKey); + } + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + result[i*2+0].setX(lastKey); + result[i*2+0].setY(value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+1].setX(lastKey); + result[i*2+1].setY(value); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepCenter. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepCenterLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + result[0].setX(lastValue); + result[0].setY(lastKey); + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + result[i*2-1].setX(lastValue); + result[i*2-1].setY(key); + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+0].setX(lastValue); + result[i*2+0].setY(key); + } + result[data.size()*2-1].setX(lastValue); + result[data.size()*2-1].setY(lastKey); + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + result[0].setX(lastKey); + result[0].setY(lastValue); + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + result[i*2-1].setX(key); + result[i*2-1].setY(lastValue); + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(lastValue); + } + result[data.size()*2-1].setX(lastKey); + result[data.size()*2-1].setY(lastValue); + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsImpulse. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, getLines, drawImpulsePlot +*/ +QVector QCPGraph::dataToImpulseLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(valueAxis->coordToPixel(0)); + result[i*2+0].setY(key); + result[i*2+1].setX(valueAxis->coordToPixel(data.at(i).value)); + result[i*2+1].setY(key); + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(valueAxis->coordToPixel(0)); + result[i*2+1].setX(key); + result[i*2+1].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + return result; +} + +/*! \internal + + Draws the fill of the graph using the specified \a painter, with the currently set brush. + + Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref + getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. + + In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), + this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to + operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN + segments of the two involved graphs, before passing the overlapping pairs to \ref + getChannelFillPolygon. + + Pass the points of this graph's line as \a lines, in pixel coordinates. + + \see drawLinePlot, drawImpulsePlot, drawScatterPlot +*/ +void QCPGraph::drawFill(QCPPainter *painter, QVector *lines) const +{ + if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot + if (painter->brush().style() == Qt::NoBrush || painter->brush().color().alpha() == 0) return; + + applyFillAntialiasingHint(painter); + QVector segments = getNonNanSegments(lines, keyAxis()->orientation()); + if (!mChannelFillGraph) + { + // draw base fill under graph, fill goes all the way to the zero-value-line: + for (int i=0; idrawPolygon(getFillPolygon(lines, segments.at(i))); + } else + { + // draw fill between this graph and mChannelFillGraph: + QVector otherLines; + mChannelFillGraph->getLines(&otherLines, QCPDataRange(0, mChannelFillGraph->dataCount())); + if (!otherLines.isEmpty()) + { + QVector otherSegments = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation()); + QVector > segmentPairs = getOverlappingSegments(segments, lines, otherSegments, &otherLines); + for (int i=0; idrawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first, &otherLines, segmentPairs.at(i).second)); + } + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a scatters, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawLinePlot, drawImpulsePlot +*/ +void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const +{ + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; i &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws impulses from the provided data, i.e. it connects all line pairs in \a lines, given in + pixel coordinates. The \a lines necessary for impulses are generated by \ref dataToImpulseLines + from the regular graph data points. + + \see drawLinePlot, drawScatterPlot +*/ +void QCPGraph::drawImpulsePlot(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + QPen oldPen = painter->pen(); + QPen newPen = painter->pen(); + newPen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line + painter->setPen(newPen); + painter->drawLines(lines); + painter->setPen(oldPen); + } +} + +/*! \internal + + Returns via \a lineData the data points that need to be visualized for this graph when plotting + graph lines, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getLines to retrieve the basic working set of data. + + \see getOptimizedScatterData +*/ +void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const +{ + if (!lineData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (begin == end) return; + + int dataCount = end-begin; + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + if (2*keyPixelSpan+2 < (double)std::numeric_limits::max()) + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + QCPGraphDataContainer::const_iterator it = begin; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator currentIntervalFirstPoint = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); + double lastIntervalEndKey = currentIntervalStartKey; + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary + { + if (it->value < minValue) + minValue = it->value; + else if (it->value > maxValue) + maxValue = it->value; + ++intervalDataCount; + } else // new pixel interval started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + if (it->key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.8, (it-1)->value)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + lastIntervalEndKey = (it-1)->key; + minValue = it->value; + maxValue = it->value; + currentIntervalFirstPoint = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + ++it; + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + lineData->resize(dataCount); + std::copy(begin, end, lineData->begin()); + } +} + +/*! \internal + + Returns via \a scatterData the data points that need to be visualized for this graph when + plotting scatter points, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getScatters to retrieve the basic working set of data. + + \see getOptimizedLineData +*/ +void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const +{ + if (!scatterData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int beginIndex = begin-mDataContainer->constBegin(); + int endIndex = end-mDataContainer->constBegin(); + while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++beginIndex; + ++begin; + } + if (begin == end) return; + int dataCount = end-begin; + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + int keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + double valueMaxRange = valueAxis->range().upper; + double valueMinRange = valueAxis->range().lower; + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator minValueIt = it; + QCPGraphDataContainer::const_iterator maxValueIt = it; + QCPGraphDataContainer::const_iterator currentIntervalStart = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + // main loop over data points: + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary + { + if (it->value < minValue && it->value > valueMinRange && it->value < valueMaxRange) + { + minValue = it->value; + minValueIt = it; + } else if (it->value > maxValue && it->value > valueMinRange && it->value < valueMaxRange) + { + maxValue = it->value; + maxValueIt = it; + } + ++intervalDataCount; + } else // new pixel started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else + intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + minValue = it->value; + maxValue = it->value; + currentIntervalStart = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int intervalItIndex = intervalIt-mDataContainer->constBegin(); + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison: + { + intervalItIndex += scatterModulo; + if (intervalItIndex < itIndex) + intervalIt += scatterModulo; + else + { + intervalIt = it; + intervalItIndex = itIndex; + } + } + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + scatterData->reserve(dataCount); + while (it != end) + { + scatterData->append(*it); + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + This method takes into account that the drawing of data lines at the axis rect border always + requires the points just outside the visible axis range. So \a begin and \a end may actually + indicate a range that contains one additional data point to the left and right of the visible + axis range. +*/ +void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + if (rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + } else + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + // get visible data range: + begin = mDataContainer->findBegin(keyAxis->range().lower); + end = mDataContainer->findEnd(keyAxis->range().upper); + // limit lower/upperEnd to rangeRestriction: + mDataContainer->limitIteratorsToDataRange(begin, end, rangeRestriction); // this also ensures rangeRestriction outside data bounds doesn't break anything + } +} + +/*! \internal + + This method goes through the passed points in \a lineData and returns a list of the segments + which don't contain NaN data points. + + \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check + for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c + Qt::Vertical, the \a x member is checked. + + \see getOverlappingSegments, drawFill +*/ +QVector QCPGraph::getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const +{ + QVector result; + const int n = lineData->size(); + + QCPDataRange currentSegment(-1, -1); + int i = 0; + + if (keyOrientation == Qt::Horizontal) + { + while (i < n) + { + while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point + ++i; + if (i == n) + break; + currentSegment.setBegin(i++); + while (i < n && !qIsNaN(lineData->at(i).y())) // seek next NaN data point or end of data + ++i; + currentSegment.setEnd(i++); + result.append(currentSegment); + } + } else // keyOrientation == Qt::Vertical + { + while (i < n) + { + while (i < n && qIsNaN(lineData->at(i).x())) // seek next non-NaN data point + ++i; + if (i == n) + break; + currentSegment.setBegin(i++); + while (i < n && !qIsNaN(lineData->at(i).x())) // seek next NaN data point or end of data + ++i; + currentSegment.setEnd(i++); + result.append(currentSegment); + } + } + return result; +} + +/*! \internal + + This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and + \a otherSegments, and their associated point data \a thisData and \a otherData. + + It returns all pairs of segments (the first from \a thisSegments, the second from \a + otherSegments), which overlap in plot coordinates. + + This method is useful in the case of a channel fill between two graphs, when only those non-NaN + segments which actually overlap in their key coordinate shall be considered for drawing a channel + fill polygon. + + It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and + that the segments don't overlap themselves. The same is assumed for the segments in \a + otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments. + + \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon +*/ +QVector > QCPGraph::getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const +{ + QVector > result; + if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() || otherSegments.isEmpty()) + return result; + + int thisIndex = 0; + int otherIndex = 0; + const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical; + while (thisIndex < thisSegments.size() && otherIndex < otherSegments.size()) + { + if (thisSegments.at(thisIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow + { + ++thisIndex; + continue; + } + if (otherSegments.at(otherIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow + { + ++otherIndex; + continue; + } + double thisLower, thisUpper, otherLower, otherUpper; + if (!verticalKey) + { + thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x(); + thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).x(); + otherLower = otherData->at(otherSegments.at(otherIndex).begin()).x(); + otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).x(); + } else + { + thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y(); + thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).y(); + otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y(); + otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).y(); + } + + int bPrecedence; + if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence)) + result.append(QPair(thisSegments.at(thisIndex), otherSegments.at(otherIndex))); + + if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with next otherSegment, keeping current thisSegment + ++otherIndex; + else // otherSegment reaches further than thisSegment, so continue with next thisSegment, keeping current otherSegment + ++thisIndex; + } + + return result; +} + +/*! \internal + + Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper) + have overlap. + + The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the + \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher + coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if + both segment's upper bounds are identical, 0 is returned as \a bPrecedence. + + It is assumed that the lower bounds always have smaller or equal values than the upper bounds. + + \see getOverlappingSegments +*/ +bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const +{ + bPrecedence = 0; + if (aLower > bUpper) + { + bPrecedence = -1; + return false; + } else if (bLower > aUpper) + { + bPrecedence = 1; + return false; + } else + { + if (aUpper > bUpper) + bPrecedence = -1; + else if (aUpper < bUpper) + bPrecedence = 1; + + return true; + } +} + +/*! \internal + + Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis. + The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates + is in positive or negative infinity. So this case is handled separately by just closing the fill + polygon on the axis which lies in the direction towards the zero value. + + \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether + the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or + y value of the returned point, respectively. +*/ +QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + QPointF result; + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + if (keyAxis->orientation() == Qt::Horizontal) + { + result.setX(matchingDataPoint.x()); + result.setY(valueAxis->coordToPixel(0)); + } else // keyAxis->orientation() == Qt::Vertical + { + result.setX(valueAxis->coordToPixel(0)); + result.setY(matchingDataPoint.y()); + } + } else // valueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value 0 so we just fill all the way + // to the axis which is in the direction towards 0 + if (keyAxis->orientation() == Qt::Vertical) + { + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + result.setX(keyAxis->axisRect()->right()); + else + result.setX(keyAxis->axisRect()->left()); + result.setY(matchingDataPoint.y()); + } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) + { + result.setX(matchingDataPoint.x()); + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + result.setY(keyAxis->axisRect()->top()); + else + result.setY(keyAxis->axisRect()->bottom()); + } + } + return result; +} + +/*! \internal + + Returns the polygon needed for drawing normal fills between this graph and the key axis. + + Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment + which shall be used for the fill. The collection of \a lineData points described by \a segment + must not contain NaN data points (see \ref getNonNanSegments). + + The returned fill polygon will be closed at the key axis (the zero-value line) for linear value + axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect + side (see \ref getFillBasePoint). + + For increased performance (due to implicit sharing), keep the returned QPolygonF const. + + \see drawFill, getNonNanSegments +*/ +const QPolygonF QCPGraph::getFillPolygon(const QVector *lineData, QCPDataRange segment) const +{ + if (segment.size() < 2) + return QPolygonF(); + QPolygonF result(segment.size()+2); + + result[0] = getFillBasePoint(lineData->at(segment.begin())); + std::copy(lineData->constBegin()+segment.begin(), lineData->constBegin()+segment.end(), result.begin()+1); + result[result.size()-1] = getFillBasePoint(lineData->at(segment.end()-1)); + + return result; +} + +/*! \internal + + Returns the polygon needed for drawing (partial) channel fills between this graph and the graph + specified by \ref setChannelFillGraph. + + The data points of this graph are passed as pixel coordinates via \a thisData, the data of the + other graph as \a otherData. The returned polygon will be calculated for the specified data + segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a + otherData, respectively. + + The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by + \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap + need to be processed here. + + For increased performance due to implicit sharing, keep the returned QPolygonF const. + + \see drawFill, getOverlappingSegments, getNonNanSegments +*/ +const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const +{ + if (!mChannelFillGraph) + return QPolygonF(); + + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } + if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } + + if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) + return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) + + if (thisData->isEmpty()) return QPolygonF(); + QVector thisSegmentData(thisSegment.size()); + QVector otherSegmentData(otherSegment.size()); + std::copy(thisData->constBegin()+thisSegment.begin(), thisData->constBegin()+thisSegment.end(), thisSegmentData.begin()); + std::copy(otherData->constBegin()+otherSegment.begin(), otherData->constBegin()+otherSegment.end(), otherSegmentData.begin()); + // pointers to be able to swap them, depending which data range needs cropping: + QVector *staticData = &thisSegmentData; + QVector *croppedData = &otherSegmentData; + + // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): + if (keyAxis->orientation() == Qt::Horizontal) + { + // x is key + // crop lower bound: + if (staticData->first().x() < croppedData->first().x()) // other one must be cropped + qSwap(staticData, croppedData); + const int lowBound = findIndexBelowX(croppedData, staticData->first().x()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x())) + slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); + else + slope = 0; + (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); + (*croppedData)[0].setX(staticData->first().x()); + + // crop upper bound: + if (staticData->last().x() > croppedData->last().x()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveX(croppedData, staticData->last().x()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + const int li = croppedData->size()-1; // last index + if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li-1).x())) + slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); + else + slope = 0; + (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); + (*croppedData)[li].setX(staticData->last().x()); + } else // mKeyAxis->orientation() == Qt::Vertical + { + // y is key + // crop lower bound: + if (staticData->first().y() < croppedData->first().y()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexBelowY(croppedData, staticData->first().y()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (!qFuzzyCompare(croppedData->at(1).y(), croppedData->at(0).y())) // avoid division by zero in step plots + slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); + else + slope = 0; + (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); + (*croppedData)[0].setY(staticData->first().y()); + + // crop upper bound: + if (staticData->last().y() > croppedData->last().y()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveY(croppedData, staticData->last().y()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (!qFuzzyCompare(croppedData->at(li).y(), croppedData->at(li-1).y())) // avoid division by zero in step plots + slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); + else + slope = 0; + (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); + (*croppedData)[li].setY(staticData->last().y()); + } + + // return joined: + for (int i=otherSegmentData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted + thisSegmentData << otherSegmentData.at(i); + return QPolygonF(thisSegmentData); +} + +/*! \internal + + Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is horizontal. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveX(const QVector *data, double x) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).x() < x) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is horizontal. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowX(const QVector *data, double x) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).x() > x) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is vertical. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveY(const QVector *data, double y) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).y() < y) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Calculates the minimum distance in pixels the graph's representation has from the given \a + pixelPoint. This is used to determine whether the graph was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if + the graph has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the graph line is also taken into account. + + If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. +*/ +double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + // calculate minimum distances to graph data points and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPGraphDataContainer::const_iterator begin = mDataContainer->findBegin(posKeyMin, true); + QCPGraphDataContainer::const_iterator end = mDataContainer->findEnd(posKeyMax, true); + for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + // line displayed, calculate distance to line segments: + QVector lineData; + getLines(&lineData, QCPDataRange(0, dataCount())); + QCPVector2D p(pixelPoint); + const int step = mLineStyle==lsImpulse ? 2 : 1; // impulse plot differs from other line styles in that the lineData points are only pairwise connected + for (int i=0; i *data, double y) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).y() > y) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} +/* end of 'src/plottables/plottable-graph.cpp' */ + + +/* including file 'src/plottables/plottable-curve.cpp', size 63527 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurveData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurveData + \brief Holds the data of one single data point for QCPCurve. + + The stored data is: + \li \a t: the free ordering parameter of this curve point, like in the mathematical vector (x(t), y(t)). (This is the \a sortKey) + \li \a key: coordinate on the key axis of this curve point (this is the \a mainKey) + \li \a value: coordinate on the value axis of this curve point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPCurveData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPCurveDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPCurveData::sortKey() const + + Returns the \a t member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPCurveData QCPCurveData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey (assigned to the data point's \a t member). + All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPCurveData::sortKeyIsMainKey() + + Since the member \a key is the data point key coordinate and the member \a t is the data ordering + parameter, this method returns false. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPCurveData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a curve data point with t, key and value set to zero. +*/ +QCPCurveData::QCPCurveData() : + t(0), + key(0), + value(0) +{ +} + +/*! + Constructs a curve data point with the specified \a t, \a key and \a value. +*/ +QCPCurveData::QCPCurveData(double t, double key, double value) : + t(t), + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurve + \brief A plottable representing a parametric curve in a plot. + + \image html QCPCurve.png + + Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, + so their visual representation can have \a loops. This is realized by introducing a third + coordinate \a t, which defines the order of the points described by the other two coordinates \a + x and \a y. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the curve's data via the \ref data method, which returns a pointer to the + internal \ref QCPCurveDataContainer. + + Gaps in the curve can be created by adding data points with NaN as key and value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpcurve-appearance Changing the appearance + + The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). + + \section qcpcurve-usage Usage + + Like all data representing objects in QCustomPlot, the QCPCurve is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPCurve::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis) +{ + // modify inherited properties from abstract plottable: + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setScatterStyle(QCPScatterStyle()); + setLineStyle(lsLine); + setScatterSkip(0); +} + +QCPCurve::~QCPCurve() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPCurves may share the same data container safely. + Modifying the data in the container will then affect all curves that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the curve's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-2 + + \see addData +*/ +void QCPCurve::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a t, \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a t in ascending order, you can + set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPCurve::setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(t, keys, values, alreadySorted); +} + + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + \see addData +*/ +void QCPCurve::setData(const QVector &keys, const QVector &values) +{ + mDataContainer->clear(); + addData(keys, values); +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref + QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate + line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPCurve::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPCurve::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets how the single data points are connected in the plot or how they are represented visually + apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref + setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPCurve::setLineStyle(QCPCurve::LineStyle style) +{ + mLineStyle = style; +} + +/*! \overload + + Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (t.size() != keys.size() || t.size() != values.size()) + qDebug() << Q_FUNC_INFO << "ts, keys and values have different sizes:" << t.size() << keys.size() << values.size(); + const int n = qMin(qMin(t.size(), keys.size()), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = t[i]; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &keys, const QVector &values) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + double tStart; + if (!mDataContainer->isEmpty()) + tStart = (mDataContainer->constEnd()-1)->t + 1.0; + else + tStart = 0; + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = tStart + i; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, true); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a t, \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double t, double key, double value) +{ + mDataContainer->add(QCPCurveData(t, key, value)); +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + The t parameter is generated automatically by increments of 1 for each point, starting at the + highest t of previously existing data or 0, if the curve data is empty. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double key, double value) +{ + if (!mDataContainer->isEmpty()) + mDataContainer->add(QCPCurveData((mDataContainer->constEnd()-1)->t + 1.0, key, value)); + else + mDataContainer->add(QCPCurveData(0.0, key, value)); +} + +/* inherits documentation from base class */ +double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPCurveDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPCurve::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + + // allocate line vector: + QVector lines, scatters; + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + + // fill with curve data: + QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width + if (isSelectedSegment && mSelectionDecorator) + finalCurvePen = mSelectionDecorator->pen(); + + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care) + getCurveLines(&lines, lineDataRange, finalCurvePen.widthF()); + + // check data validity if flag set: + #ifdef QCUSTOMPLOT_CHECK_DATA + for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->t) || + QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } + #endif + + // draw curve fill: + applyFillAntialiasingHint(painter); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) + painter->drawPolygon(QPolygonF(lines)); + + // draw curve line: + if (mLineStyle != lsNone) + { + painter->setPen(finalCurvePen); + painter->setBrush(Qt::NoBrush); + drawCurveLine(painter, lines); + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i), finalScatterStyle.size()); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + Draws lines between the points in \a lines, given in pixel coordinates. + + \see drawScatterPlot, getCurveLines +*/ +void QCPCurve::drawCurveLine(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a points, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawCurveLine, getCurveLines +*/ +void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const +{ + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; i *lines, const QCPDataRange &dataRange, double penWidth) const +{ + if (!lines) return; + lines->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + // add margins to rect to compensate for stroke width + const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety + const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation()); + const double keyMax = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*keyAxis->pixelOrientation()); + const double valueMin = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)-strokeMargin*valueAxis->pixelOrientation()); + const double valueMax = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)+strokeMargin*valueAxis->pixelOrientation()); + QCPCurveDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(itBegin, itEnd, dataRange); + if (itBegin == itEnd) + return; + QCPCurveDataContainer::const_iterator it = itBegin; + QCPCurveDataContainer::const_iterator prevIt = itEnd-1; + int prevRegion = getRegion(prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin); + QVector trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right) + while (it != itEnd) + { + const int currentRegion = getRegion(it->key, it->value, keyMin, valueMax, keyMax, valueMin); + if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R + { + if (currentRegion != 5) // segment doesn't end in R, so it's a candidate for removal + { + QPointF crossA, crossB; + if (prevRegion == 5) // we're coming from R, so add this point optimized + { + lines->append(getOptimizedPoint(currentRegion, it->key, it->value, prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin)); + // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } else if (mayTraverse(prevRegion, currentRegion) && + getTraverse(prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin, crossA, crossB)) + { + // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point: + QVector beforeTraverseCornerPoints, afterTraverseCornerPoints; + getTraverseCornerPoints(prevRegion, currentRegion, keyMin, valueMax, keyMax, valueMin, beforeTraverseCornerPoints, afterTraverseCornerPoints); + if (it != itBegin) + { + *lines << beforeTraverseCornerPoints; + lines->append(crossA); + lines->append(crossB); + *lines << afterTraverseCornerPoints; + } else + { + lines->append(crossB); + *lines << afterTraverseCornerPoints; + trailingPoints << beforeTraverseCornerPoints << crossA ; + } + } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s) + { + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } + } else // segment does end in R, so we add previous point optimized and this point at original position + { + if (it == itBegin) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end + trailingPoints << getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + else + lines->append(getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin)); + lines->append(coordsToPixels(it->key, it->value)); + } + } else // region didn't change + { + if (currentRegion == 5) // still in R, keep adding original points + { + lines->append(coordsToPixels(it->key, it->value)); + } else // still outside R, no need to add anything + { + // see how this is not doing anything? That's the main optimization... + } + } + prevIt = it; + prevRegion = currentRegion; + ++it; + } + *lines << trailingPoints; +} + +/*! \internal + + Called by \ref draw to generate points in pixel coordinates which represent the scatters of the + curve. If a scatter skip is configured (\ref setScatterSkip), the returned points are accordingly + sparser. + + Scatters that aren't visible in the current axis rect are optimized away. + + \a scatters will be filled with points in pixel coordinates, that can be drawn with \ref + drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. + + \a scatterWidth specifies the scatter width that will be used to later draw the scatters at pixel + coordinates generated by this function. This is needed here to calculate an accordingly wider + margin around the axis rect when performing the data point reduction. + + \see draw, drawScatterPlot +*/ +void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const +{ + if (!scatters) return; + scatters->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(begin, end, dataRange); + if (begin == end) + return; + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int endIndex = end-mDataContainer->constBegin(); + + QCPRange keyRange = keyAxis->range(); + QCPRange valueRange = valueAxis->range(); + // extend range to include width of scatter symbols: + keyRange.lower = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.lower)-scatterWidth*keyAxis->pixelOrientation()); + keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation()); + valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation()); + valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation()); + + QCPCurveDataContainer::const_iterator it = begin; + int itIndex = begin-mDataContainer->constBegin(); + while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++itIndex; + ++it; + } + if (keyAxis->orientation() == Qt::Vertical) + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } else + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(keyAxis->coordToPixel(it->key), valueAxis->coordToPixel(it->value))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + It returns the region of the given point (\a key, \a value) with respect to a rectangle defined + by \a keyMin, \a keyMax, \a valueMin, and \a valueMax. + + The regions are enumerated from top to bottom (\a valueMin to \a valueMax) and left to right (\a + keyMin to \a keyMax): + + + + + +
147
258
369
+ + With the rectangle being region 5, and the outer regions extending infinitely outwards. In the + curve optimization algorithm, region 5 is considered to be the visible portion of the plot. +*/ +int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + if (key < keyMin) // region 123 + { + if (value > valueMax) + return 1; + else if (value < valueMin) + return 3; + else + return 2; + } else if (key > keyMax) // region 789 + { + if (value > valueMax) + return 7; + else if (value < valueMin) + return 9; + else + return 8; + } else // region 456 + { + if (value > valueMax) + return 4; + else if (value < valueMin) + return 6; + else + return 5; + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method is used in case the current segment passes from inside the visible rect (region 5, + see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by + the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). + + It returns the intersection point of the segment with the border of region 5. + + For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or + whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or + leaving it. It is important though that \a otherRegion correctly identifies the other region not + equal to 5. +*/ +QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + // The intersection point interpolation here is done in pixel coordinates, so we don't need to + // differentiate between different axis scale types. Note that the nomenclature + // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be + // different in pixel coordinates (horz/vert key axes, reversed ranges) + + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); + const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); + const double valueMinPx = mValueAxis->coordToPixel(valueMin); + const double valueMaxPx = mValueAxis->coordToPixel(valueMax); + const double otherValuePx = mValueAxis->coordToPixel(otherValue); + const double valuePx = mValueAxis->coordToPixel(value); + const double otherKeyPx = mKeyAxis->coordToPixel(otherKey); + const double keyPx = mKeyAxis->coordToPixel(key); + double intersectKeyPx = keyMinPx; // initial key just a fail-safe + double intersectValuePx = valueMinPx; // initial value just a fail-safe + switch (otherRegion) + { + case 1: // top and left edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 2: // left edge + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + break; + } + case 3: // bottom and left edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 4: // top edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + break; + } + case 5: + { + break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table + } + case 6: // bottom edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + break; + } + case 7: // top and right edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 8: // right edge + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + break; + } + case 9: // bottom and right edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + } + if (mKeyAxis->orientation() == Qt::Horizontal) + return QPointF(intersectKeyPx, intersectValuePx); + else + return QPointF(intersectValuePx, intersectKeyPx); +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + In situations where a single segment skips over multiple regions it might become necessary to add + extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment + doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. + This method provides these points that must be added, assuming the original segment doesn't + start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by + \ref getTraverseCornerPoints.) + + For example, consider a segment which directly goes from region 4 to 2 but originally is far out + to the top left such that it doesn't cross region 5. Naively optimizing these points by + projecting them on the top and left borders of region 5 will create a segment that surely crosses + 5, creating a visual artifact in the plot. This method prevents this by providing extra points at + the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without + traversing 5. +*/ +QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + QVector result; + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMax); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); break; } + case 6: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + else + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + break; + } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 7: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMin); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); break; } + case 1: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + else + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + break; + } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 3: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 6: + { + switch (currentRegion) + { + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 4: { result << coordsToPixels(keyMax, valueMax); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); break; } + case 1: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + else + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + break; + } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 6: { result << coordsToPixels(keyMax, valueMin); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 4: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + else + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + break; + } + } + break; + } + } + return result; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref + getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion + nor \a currentRegion is 5 itself. + + If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the + segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref + getTraverse). +*/ +bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 4: + case 7: + case 2: + case 3: return false; + default: return true; + } + } + case 2: + { + switch (currentRegion) + { + case 1: + case 3: return false; + default: return true; + } + } + case 3: + { + switch (currentRegion) + { + case 1: + case 2: + case 6: + case 9: return false; + default: return true; + } + } + case 4: + { + switch (currentRegion) + { + case 1: + case 7: return false; + default: return true; + } + } + case 5: return false; // should never occur + case 6: + { + switch (currentRegion) + { + case 3: + case 9: return false; + default: return true; + } + } + case 7: + { + switch (currentRegion) + { + case 1: + case 4: + case 8: + case 9: return false; + default: return true; + } + } + case 8: + { + switch (currentRegion) + { + case 7: + case 9: return false; + default: return true; + } + } + case 9: + { + switch (currentRegion) + { + case 3: + case 6: + case 8: + case 7: return false; + default: return true; + } + } + default: return true; + } +} + + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref mayTraverse test has returned true, so there is a chance the + segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible + region 5. + + The return value of this method indicates whether the segment actually traverses region 5 or not. + + If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and + exit points of region 5. They will become the optimized points for that segment. +*/ +bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const +{ + // The intersection point interpolation here is done in pixel coordinates, so we don't need to + // differentiate between different axis scale types. Note that the nomenclature + // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be + // different in pixel coordinates (horz/vert key axes, reversed ranges) + + QList intersections; + const double valueMinPx = mValueAxis->coordToPixel(valueMin); + const double valueMaxPx = mValueAxis->coordToPixel(valueMax); + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); + const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); + const double keyPx = mKeyAxis->coordToPixel(key); + const double valuePx = mValueAxis->coordToPixel(value); + const double prevKeyPx = mKeyAxis->coordToPixel(prevKey); + const double prevValuePx = mValueAxis->coordToPixel(prevValue); + if (qFuzzyIsNull(key-prevKey)) // line is parallel to value axis + { + // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMinPx) : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMaxPx) : QPointF(valueMaxPx, keyPx)); + } else if (qFuzzyIsNull(value-prevValue)) // line is parallel to key axis + { + // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, valuePx) : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, valuePx) : QPointF(valuePx, keyMaxPx)); + } else // line is skewed + { + double gamma; + double keyPerValuePx = (keyPx-prevKeyPx)/(valuePx-prevValuePx); + // check top of rect: + gamma = prevKeyPx + (valueMaxPx-prevValuePx)*keyPerValuePx; + if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMaxPx) : QPointF(valueMaxPx, gamma)); + // check bottom of rect: + gamma = prevKeyPx + (valueMinPx-prevValuePx)*keyPerValuePx; + if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMinPx) : QPointF(valueMinPx, gamma)); + const double valuePerKeyPx = 1.0/keyPerValuePx; + // check left of rect: + gamma = prevValuePx + (keyMinPx-prevKeyPx)*valuePerKeyPx; + if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, gamma) : QPointF(gamma, keyMinPx)); + // check right of rect: + gamma = prevValuePx + (keyMaxPx-prevKeyPx)*valuePerKeyPx; + if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, gamma) : QPointF(gamma, keyMaxPx)); + } + + // handle cases where found points isn't exactly 2: + if (intersections.size() > 2) + { + // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between: + double distSqrMax = 0; + QPointF pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = intersections.at(i); + pv2 = intersections.at(k); + distSqrMax = distSqr; + } + } + } + intersections = QList() << pv1 << pv2; + } else if (intersections.size() != 2) + { + // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment + return false; + } + + // possibly re-sort points so optimized point segment has same direction as original segment: + double xDelta = keyPx-prevKeyPx; + double yDelta = valuePx-prevValuePx; + if (mKeyAxis->orientation() != Qt::Horizontal) + qSwap(xDelta, yDelta); + if (xDelta*(intersections.at(1).x()-intersections.at(0).x()) + yDelta*(intersections.at(1).y()-intersections.at(0).y()) < 0) // scalar product of both segments < 0 -> opposite direction + intersections.move(0, 1); + crossA = intersections.at(0); + crossB = intersections.at(1); + return true; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref getTraverse test has returned true, so the segment definitely + traverses the visible region 5 when going from \a prevRegion to \a currentRegion. + + In certain situations it is not sufficient to merely generate the entry and exit points of the + segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in + addition to traversing region 5, skips another region outside of region 5, which makes it + necessary to add an optimized corner point there (very similar to the job \ref + getOptimizedCornerPoints does for segments that are completely in outside regions and don't + traverse 5). + + As an example, consider a segment going from region 1 to region 6, traversing the lower left + corner of region 5. In this configuration, the segment additionally crosses the border between + region 1 and 2 before entering region 5. This makes it necessary to add an additional point in + the top left corner, before adding the optimized traverse points. So in this case, the output + parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be + empty. + + In some cases, such as when going from region 1 to 9, it may even be necessary to add additional + corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse + return the respective corner points. +*/ +void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 6: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + case 9: { beforeTraverse << coordsToPixels(keyMin, valueMax); afterTraverse << coordsToPixels(keyMax, valueMin); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 4: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + case 7: { beforeTraverse << coordsToPixels(keyMin, valueMin); afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: { break; } // shouldn't happen because this method only handles full traverses + case 6: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + case 3: { beforeTraverse << coordsToPixels(keyMax, valueMax); afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 6: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + case 1: { beforeTraverse << coordsToPixels(keyMax, valueMin); afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 4: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + } +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in + \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that + if the curve has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the curve line is also taken into account. + + If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns + -1.0. +*/ +double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + if (mDataContainer->size() == 1) + { + QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value); + closestData = mDataContainer->constBegin(); + return QCPVector2D(dataPoint-pixelPoint).length(); + } + + // calculate minimum distances to curve data points and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + for (QCPCurveDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + QVector lines; + getCurveLines(&lines, QCPDataRange(0, dataCount()), mParentPlot->selectionTolerance()*1.2); // optimized lines outside axis rect shouldn't respond to clicks at the edge, so use 1.2*tolerance as pen width + for (int i=0; i QCPBarsGroup::bars() const + + Returns all bars currently in this group. + + \see bars(int index) +*/ + +/*! \fn int QCPBarsGroup::size() const + + Returns the number of QCPBars plottables that are part of this group. + +*/ + +/*! \fn bool QCPBarsGroup::isEmpty() const + + Returns whether this bars group is empty. + + \see size +*/ + +/*! \fn bool QCPBarsGroup::contains(QCPBars *bars) + + Returns whether the specified \a bars plottable is part of this group. + +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new bars group for the specified QCustomPlot instance. +*/ +QCPBarsGroup::QCPBarsGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot), + mSpacingType(stAbsolute), + mSpacing(4) +{ +} + +QCPBarsGroup::~QCPBarsGroup() +{ + clear(); +} + +/*! + Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. + + The actual spacing can then be specified with \ref setSpacing. + + \see setSpacing +*/ +void QCPBarsGroup::setSpacingType(SpacingType spacingType) +{ + mSpacingType = spacingType; +} + +/*! + Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is + defined by the current \ref SpacingType, which can be set with \ref setSpacingType. + + \see setSpacingType +*/ +void QCPBarsGroup::setSpacing(double spacing) +{ + mSpacing = spacing; +} + +/*! + Returns the QCPBars instance with the specified \a index in this group. If no such QCPBars + exists, returns 0. + + \see bars(), size +*/ +QCPBars *QCPBarsGroup::bars(int index) const +{ + if (index >= 0 && index < mBars.size()) + { + return mBars.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Removes all QCPBars plottables from this group. + + \see isEmpty +*/ +void QCPBarsGroup::clear() +{ + foreach (QCPBars *bars, mBars) // since foreach takes a copy, removing bars in the loop is okay + bars->setBarsGroup(0); // removes itself via removeBars +} + +/*! + Adds the specified \a bars plottable to this group. Alternatively, you can also use \ref + QCPBars::setBarsGroup on the \a bars instance. + + \see insert, remove +*/ +void QCPBarsGroup::append(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + else + qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast(bars); +} + +/*! + Inserts the specified \a bars plottable into this group at the specified index position \a i. + This gives you full control over the ordering of the bars. + + \a bars may already be part of this group. In that case, \a bars is just moved to the new index + position. + + \see append, remove +*/ +void QCPBarsGroup::insert(int i, QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + // first append to bars list normally: + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + // then move to according position: + mBars.move(mBars.indexOf(bars), qBound(0, i, mBars.size()-1)); +} + +/*! + Removes the specified \a bars plottable from this group. + + \see contains, clear +*/ +void QCPBarsGroup::remove(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (mBars.contains(bars)) + bars->setBarsGroup(0); + else + qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast(bars); +} + +/*! \internal + + Adds the specified \a bars to the internal mBars list of bars. This method does not change the + barsGroup property on \a bars. + + \see unregisterBars +*/ +void QCPBarsGroup::registerBars(QCPBars *bars) +{ + if (!mBars.contains(bars)) + mBars.append(bars); +} + +/*! \internal + + Removes the specified \a bars from the internal mBars list of bars. This method does not change + the barsGroup property on \a bars. + + \see registerBars +*/ +void QCPBarsGroup::unregisterBars(QCPBars *bars) +{ + mBars.removeOne(bars); +} + +/*! \internal + + Returns the pixel offset in the key dimension the specified \a bars plottable should have at the + given key coordinate \a keyCoord. The offset is relative to the pixel position of the key + coordinate \a keyCoord. +*/ +double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) +{ + // find list of all base bars in case some mBars are stacked: + QList baseBars; + foreach (const QCPBars *b, mBars) + { + while (b->barBelow()) + b = b->barBelow(); + if (!baseBars.contains(b)) + baseBars.append(b); + } + // find base bar this "bars" is stacked on: + const QCPBars *thisBase = bars; + while (thisBase->barBelow()) + thisBase = thisBase->barBelow(); + + // determine key pixel offset of this base bars considering all other base bars in this barsgroup: + double result = 0; + int index = baseBars.indexOf(thisBase); + if (index >= 0) + { + if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose) + { + return result; + } else + { + double lowerPixelWidth, upperPixelWidth; + int startIndex; + int dir = (index <= (baseBars.size()-1)/2) ? -1 : 1; // if bar is to lower keys of center, dir is negative + if (baseBars.size() % 2 == 0) // even number of bars + { + startIndex = baseBars.size()/2 + (dir < 0 ? -1 : 0); + result += getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing + } else // uneven number of bars + { + startIndex = (baseBars.size()-1)/2+dir; + baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar + result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing + } + for (int i = startIndex; i != index; i += dir) // add widths and spacings of bars in between center and our bars + { + baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth); + result += getPixelSpacing(baseBars.at(i), keyCoord); + } + // finally half of our bars width: + baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; + // correct sign of result depending on orientation and direction of key axis: + result *= dir*thisBase->keyAxis()->pixelOrientation(); + } + } + return result; +} + +/*! \internal + + Returns the spacing in pixels which is between this \a bars and the following one, both at the + key coordinate \a keyCoord. + + \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only + needed to get access to the key axis transformation and axis rect for the modes \ref + stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in + \ref stPlotCoords on a logarithmic axis. +*/ +double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) +{ + switch (mSpacingType) + { + case stAbsolute: + { + return mSpacing; + } + case stAxisRectRatio: + { + if (bars->keyAxis()->orientation() == Qt::Horizontal) + return bars->keyAxis()->axisRect()->width()*mSpacing; + else + return bars->keyAxis()->axisRect()->height()*mSpacing; + } + case stPlotCoords: + { + double keyPixel = bars->keyAxis()->coordToPixel(keyCoord); + return qAbs(bars->keyAxis()->coordToPixel(keyCoord+mSpacing)-keyPixel); + } + } + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBarsData + \brief Holds the data of one single data point (one bar) for QCPBars. + + The stored data is: + \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey) + \li \a value: height coordinate on the value axis of this bar (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPBarsData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPBarsDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPBarsData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPBarsData QCPBarsData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPBarsData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPBarsData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a bar data point with key and value set to zero. +*/ +QCPBarsData::QCPBarsData() : + key(0), + value(0) +{ +} + +/*! + Constructs a bar data point with the specified \a key and \a value. +*/ +QCPBarsData::QCPBarsData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBars + \brief A plottable representing a bar chart in a plot. + + \image html QCPBars.png + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section qcpbars-appearance Changing the appearance + + The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). + The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. + + Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other + (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear + stacked. + + If you would like to group multiple QCPBars plottables together so they appear side by side as + shown below, use QCPBarsGroup. + + \image html QCPBarsGroup.png + + \section qcpbars-usage Usage + + Like all data representing objects in QCustomPlot, the QCPBars is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/*! \fn QCPBars *QCPBars::barBelow() const + Returns the bars plottable that is directly below this bars plottable. + If there is no such plottable, returns 0. + + \see barAbove, moveBelow, moveAbove +*/ + +/*! \fn QCPBars *QCPBars::barAbove() const + Returns the bars plottable that is directly above this bars plottable. + If there is no such plottable, returns 0. + + \see barBelow, moveBelow, moveAbove +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.75), + mWidthType(wtPlotCoords), + mBarsGroup(0), + mBaseValue(0), + mStackingGap(0) +{ + // modify inherited properties from abstract plottable: + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(QColor(40, 50, 255, 30)); + mBrush.setStyle(Qt::SolidPattern); + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPBars::~QCPBars() +{ + setBarsGroup(0); + if (mBarBelow || mBarAbove) + connectBars(mBarBelow.data(), mBarAbove.data()); // take this bar out of any stacking +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPBars may share the same data container safely. + Modifying the data in the container will then affect all bars that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the bar's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-2 + + \see addData +*/ +void QCPBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPBars::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets the width of the bars. + + How the number passed as \a width is interpreted (e.g. screen pixels, plot coordinates,...), + depends on the currently set width type, see \ref setWidthType and \ref WidthType. +*/ +void QCPBars::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the bars is defined. See the documentation of \ref WidthType for an + explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPBars::setWidthType(QCPBars::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref + QCPBarsGroup::append. + + To remove this QCPBars from any group, set \a barsGroup to 0. +*/ +void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) +{ + // deregister at old group: + if (mBarsGroup) + mBarsGroup->unregisterBars(this); + mBarsGroup = barsGroup; + // register at new group: + if (mBarsGroup) + mBarsGroup->registerBars(this); +} + +/*! + Sets the base value of this bars plottable. + + The base value defines where on the value coordinate the bars start. How far the bars extend from + the base value is given by their individual value data. For example, if the base value is set to + 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at + 3. + + For stacked bars, only the base value of the bottom-most QCPBars has meaning. + + The default base value is 0. +*/ +void QCPBars::setBaseValue(double baseValue) +{ + mBaseValue = baseValue; +} + +/*! + If this bars plottable is stacked on top of another bars plottable (\ref moveAbove), this method + allows specifying a distance in \a pixels, by which the drawn bar rectangles will be separated by + the bars below it. +*/ +void QCPBars::setStackingGap(double pixels) +{ + mStackingGap = pixels; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(double key, double value) +{ + mDataContainer->add(QCPBarsData(key, value)); +} + +/*! + Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear + below the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object below itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barAbove, barBelow +*/ +void QCPBars::moveBelow(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar below it: + if (bars) + { + if (bars->mBarBelow) + connectBars(bars->mBarBelow.data(), this); + connectBars(this, bars); + } +} + +/*! + Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear + above the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object above itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barBelow, barAbove +*/ +void QCPBars::moveAbove(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar above it: + if (bars) + { + if (bars->mBarAbove) + connectBars(this, bars->mBarAbove.data()); + connectBars(bars, this); + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getBarRect(it->key, it->value))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getBarRect(it->key, it->value).contains(pos)) + { + if (details) + { + int pointIndex = it-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return mParentPlot->selectionTolerance()*0.99; + } + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + /* Note: If this QCPBars uses absolute pixels as width (or is in a QCPBarsGroup with spacing in + absolute pixels), using this method to adapt the key axis range to fit the bars into the + currently visible axis range will not work perfectly. Because in the moment the axis range is + changed to the new range, the fixed pixel widths/spacings will represent different coordinate + spans than before, which in turn would require a different key range to perfectly fit, and so on. + The only solution would be to iteratively approach the perfect fitting axis range, but the + mismatch isn't large enough in most applications, to warrant this here. If a user does need a + better fit, he should call the corresponding axis rescale multiple times in a row. + */ + QCPRange range; + range = mDataContainer->keyRange(foundRange, inSignDomain); + + // determine exact range of bars by including bar width and barsgroup offset: + if (foundRange && mKeyAxis) + { + double lowerPixelWidth, upperPixelWidth, keyPixel; + // lower range bound: + getPixelWidth(range.lower, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.lower) + lowerPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.lower); + const double lowerCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(lowerCorrected) && qIsFinite(lowerCorrected) && range.lower > lowerCorrected) + range.lower = lowerCorrected; + // upper range bound: + getPixelWidth(range.upper, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.upper) + upperPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.upper); + const double upperCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(upperCorrected) && qIsFinite(upperCorrected) && range.upper < upperCorrected) + range.upper = upperCorrected; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + // Note: can't simply use mDataContainer->valueRange here because we need to + // take into account bar base value and possible stacking of multiple bars + QCPRange range; + range.lower = mBaseValue; + range.upper = mBaseValue; + bool haveLower = true; // set to true, because baseValue should always be visible in bar charts + bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts + QCPBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (inKeyRange != QCPRange()) + { + itBegin = mDataContainer->findBegin(inKeyRange.lower); + itEnd = mDataContainer->findEnd(inKeyRange.upper); + } + for (QCPBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + const double current = it->value + getStackedBaseValue(it->key, it->value >= 0); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + + foundRange = true; // return true because bar charts always have the 0-line visible + return range; +} + +/* inherits documentation from base class */ +QPointF QCPBars::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + const QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value); + const double keyPixel = keyAxis->coordToPixel(it->key) + (mBarsGroup ? mBarsGroup->keyPixelOffset(this, it->key) : 0); + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyPixel, valuePixel); + else + return QPointF(valuePixel, keyPixel); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/* inherits documentation from base class */ +void QCPBars::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mDataContainer->isEmpty()) return; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPBarsDataContainer::const_iterator begin = visibleBegin; + QCPBarsDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +#endif + // draw bar: + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyBrush(painter); + mSelectionDecorator->applyPen(painter); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + } + applyDefaultAntialiasingHint(painter); + painter->drawPolygon(getBarRect(it->key, it->value)); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setBrush(mBrush); + painter->setPen(mPen); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + if (mDataContainer->isEmpty()) + { + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + + // get visible data range as QMap iterators + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower); + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper); + double lowerPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().lower); + double upperPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().upper); + bool isVisible = false; + // walk left from begin to find lower bar that actually is completely outside visible pixel range: + QCPBarsDataContainer::const_iterator it = begin; + while (it != mDataContainer->constBegin()) + { + --it; + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.left() <= lowerPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.bottom() >= lowerPixelBound)); + if (isVisible) + begin = it; + else + break; + } + // walk right from ubound to find upper bar that actually is completely outside visible pixel range: + it = end; + while (it != mDataContainer->constEnd()) + { + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.right() >= upperPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.bottom() >= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.top() <= upperPixelBound)); + if (isVisible) + end = it+1; + else + break; + ++it; + } +} + +/*! \internal + + Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The + rect is shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref + setBaseValue), and to have non-overlapping border lines with the bars stacked below. +*/ +QRectF QCPBars::getBarRect(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } + + double lowerPixelWidth, upperPixelWidth; + getPixelWidth(key, lowerPixelWidth, upperPixelWidth); + double base = getStackedBaseValue(key, value >= 0); + double basePixel = valueAxis->coordToPixel(base); + double valuePixel = valueAxis->coordToPixel(base+value); + double keyPixel = keyAxis->coordToPixel(key); + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, key); + double bottomOffset = (mBarBelow && mPen != Qt::NoPen ? 1 : 0)*(mPen.isCosmetic() ? 1 : mPen.widthF()); + bottomOffset += mBarBelow ? mStackingGap : 0; + bottomOffset *= (value<0 ? -1 : 1)*valueAxis->pixelOrientation(); + if (qAbs(valuePixel-basePixel) <= qAbs(bottomOffset)) + bottomOffset = valuePixel-basePixel; + if (keyAxis->orientation() == Qt::Horizontal) + { + return QRectF(QPointF(keyPixel+lowerPixelWidth, valuePixel), QPointF(keyPixel+upperPixelWidth, basePixel+bottomOffset)).normalized(); + } else + { + return QRectF(QPointF(basePixel+bottomOffset, keyPixel+lowerPixelWidth), QPointF(valuePixel, keyPixel+upperPixelWidth)).normalized(); + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). + + The output parameters \a lower and \a upper return the number of pixels the bar extends to lower + and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a + lower is negative and \a upper positive). +*/ +void QCPBars::getPixelWidth(double key, double &lower, double &upper) const +{ + lower = 0; + upper = 0; + switch (mWidthType) + { + case wtAbsolute: + { + upper = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + upper = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + upper = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + { + double keyPixel = mKeyAxis.data()->coordToPixel(key); + upper = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + lower = mKeyAxis.data()->coordToPixel(key-mWidth*0.5)-keyPixel; + // no need to qSwap(lower, higher) when range reversed, because higher/lower are gained by + // coordinate transform which includes range direction + } else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } +} + +/*! \internal + + This function is called to find at which value to start drawing the base of a bar at \a key, when + it is stacked on top of another QCPBars (e.g. with \ref moveAbove). + + positive and negative bars are separated per stack (positive are stacked above baseValue upwards, + negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the + bar for which we need the base value is negative, set \a positive to false. +*/ +double QCPBars::getStackedBaseValue(double key, bool positive) const +{ + if (mBarBelow) + { + double max = 0; // don't initialize with mBaseValue here because only base value of bottom-most bar has meaning in a bar stack + // find bars of mBarBelow that are approximately at key and find largest one: + double epsilon = qAbs(key)*(sizeof(key)==4 ? 1e-6 : 1e-14); // should be safe even when changed to use float at some point + if (key == 0) + epsilon = (sizeof(key)==4 ? 1e-6 : 1e-14); + QCPBarsDataContainer::const_iterator it = mBarBelow.data()->mDataContainer->findBegin(key-epsilon); + QCPBarsDataContainer::const_iterator itEnd = mBarBelow.data()->mDataContainer->findEnd(key+epsilon); + while (it != itEnd) + { + if (it->key > key-epsilon && it->key < key+epsilon) + { + if ((positive && it->value > max) || + (!positive && it->value < max)) + max = it->value; + } + ++it; + } + // recurse down the bar-stack to find the total height: + return max + mBarBelow.data()->getStackedBaseValue(key, positive); + } else + return mBaseValue; +} + +/*! \internal + + Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) + currently above lower and below upper will become disconnected to lower/upper. + + If lower is zero, upper will be disconnected at the bottom. + If upper is zero, lower will be disconnected at the top. +*/ +void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) +{ + if (!lower && !upper) return; + + if (!lower) // disconnect upper at bottom + { + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + upper->mBarBelow = 0; + } else if (!upper) // disconnect lower at top + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + lower->mBarAbove = 0; + } else // connect lower and upper + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + lower->mBarAbove = upper; + upper->mBarBelow = lower; + } +} +/* end of 'src/plottables/plottable-bars.cpp' */ + + +/* including file 'src/plottables/plottable-statisticalbox.cpp', size 28622 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBoxData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBoxData + \brief Holds the data of one single data point for QCPStatisticalBox. + + The stored data is: + + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + + \li \a minimum: the position of the lower whisker, typically the minimum measurement of the + sample that's not considered an outlier. + + \li \a lowerQuartile: the lower end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a median: the value of the median mark inside the quartile box. The median separates the + sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue) + + \li \a upperQuartile: the upper end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a maximum: the position of the upper whisker, typically the maximum measurement of the + sample that's not considered an outlier. + + \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key + coordinate of this data point (see \ref QCPStatisticalBox::setOutlierStyle) + + The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a + typedef for \ref QCPDataContainer with \ref QCPStatisticalBoxData as the DataType template + parameter. See the documentation there for an explanation regarding the data type's generic + methods. + + \see QCPStatisticalBoxDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPStatisticalBoxData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPStatisticalBoxData QCPStatisticalBoxData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPStatisticalBoxData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainValue() const + + Returns the \a median member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPStatisticalBoxData::valueRange() const + + Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box + data point, possibly further expanded by outliers. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData() : + key(0), + minimum(0), + lowerQuartile(0), + median(0), + upperQuartile(0), + maximum(0) +{ +} + +/*! + Constructs a data point with the specified \a key, \a minimum, \a lowerQuartile, \a median, \a + upperQuartile, \a maximum and optionally a number of \a outliers. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) : + key(key), + minimum(minimum), + lowerQuartile(lowerQuartile), + median(median), + upperQuartile(upperQuartile), + maximum(maximum), + outliers(outliers) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBox +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBox + \brief A plottable representing a single statistical box in a plot. + + \image html QCPStatisticalBox.png + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPStatisticalBoxDataContainer. + + Additionally each data point can itself have a list of outliers, drawn as scatter points at the + key coordinate of the respective statistical box data point. They can either be set by using the + respective \ref addData(double,double,double,double,double,double,const QVector&) + "addData" method or accessing the individual data points through \ref data, and setting the + QVector outliers of the data points directly. + + \section qcpstatisticalbox-appearance Changing the appearance + + The appearance of each data point box, ranging from the lower to the upper quartile, is + controlled via \ref setPen and \ref setBrush. You may change the width of the boxes with \ref + setWidth in plot coordinates. + + Each data point's visual representation also consists of two whiskers. Whiskers are the lines + which reach from the upper quartile to the maximum, and from the lower quartile to the minimum. + The appearance of the whiskers can be modified with: \ref setWhiskerPen, \ref setWhiskerBarPen, + \ref setWhiskerWidth. The whisker width is the width of the bar perpendicular to the whisker at + the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set + the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a + few pixels due to the pen cap being not perfectly flat. + + The median indicator line inside the box has its own pen, \ref setMedianPen. + + The outlier data points are drawn as normal scatter points. Their look can be controlled with + \ref setOutlierStyle + + \section qcpstatisticalbox-usage Usage + + Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-2 +*/ + +/* start documentation of inline functions */ + +/*! \fn QSharedPointer QCPStatisticalBox::data() const + + Returns a shared pointer to the internal data storage of type \ref + QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more + convenient and faster than using the regular \ref setData or \ref addData methods. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its + value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and + not have the same orientation. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not + delete it manually but use QCustomPlot::removePlottable() instead. +*/ +QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.5), + mWhiskerWidth(0.2), + mWhiskerPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap), + mWhiskerBarPen(Qt::black), + mWhiskerAntialiased(false), + mMedianPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap), + mOutlierStyle(QCPScatterStyle::ssCircle, Qt::blue, 6) +{ + setPen(QPen(Qt::black)); + setBrush(Qt::NoBrush); +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container + safely. Modifying the data in the container will then affect all statistical boxes that share the + container. Sharing can be achieved by simply exchanging the data containers wrapped in shared + pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the statistical box data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-2 + + \see addData +*/ +void QCPStatisticalBox::setData(QSharedPointer data) +{ + mDataContainer = data; +} +/*! \overload + + Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a + median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the + number of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPStatisticalBox::setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, minimum, lowerQuartile, median, upperQuartile, maximum, alreadySorted); +} + +/*! + Sets the width of the boxes in key coordinates. + + \see setWhiskerWidth +*/ +void QCPStatisticalBox::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the width of the whiskers in key coordinates. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWidth +*/ +void QCPStatisticalBox::setWhiskerWidth(double width) +{ + mWhiskerWidth = width; +} + +/*! + Sets the pen used for drawing the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + Make sure to set the \c capStyle of the passed \a pen to \c Qt::FlatCap. Otherwise the backbone + line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat. + + \see setWhiskerBarPen +*/ +void QCPStatisticalBox::setWhiskerPen(const QPen &pen) +{ + mWhiskerPen = pen; +} + +/*! + Sets the pen used for drawing the whisker bars. Those are the lines parallel to the key axis at + each end of the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWhiskerPen +*/ +void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) +{ + mWhiskerBarPen = pen; +} + +/*! + Sets whether the statistical boxes whiskers are drawn with antialiasing or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPStatisticalBox::setWhiskerAntialiased(bool enabled) +{ + mWhiskerAntialiased = enabled; +} + +/*! + Sets the pen used for drawing the median indicator line inside the statistical boxes. +*/ +void QCPStatisticalBox::setMedianPen(const QPen &pen) +{ + mMedianPen = pen; +} + +/*! + Sets the appearance of the outlier data points. + + Outliers can be specified with the method + \ref addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +*/ +void QCPStatisticalBox::setOutlierStyle(const QCPScatterStyle &style) +{ + mOutlierStyle = style; +} + +/*! \overload + + Adds the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and + \a maximum to the current data. The provided vectors should have equal length. Else, the number + of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + if (keys.size() != minimum.size() || minimum.size() != lowerQuartile.size() || lowerQuartile.size() != median.size() || + median.size() != upperQuartile.size() || upperQuartile.size() != maximum.size() || maximum.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, minimum, lowerQuartile, median, upperQuartile, maximum have different sizes:" + << keys.size() << minimum.size() << lowerQuartile.size() << median.size() << upperQuartile.size() << maximum.size(); + const int n = qMin(keys.size(), qMin(minimum.size(), qMin(lowerQuartile.size(), qMin(median.size(), qMin(upperQuartile.size(), maximum.size()))))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->minimum = minimum[i]; + it->lowerQuartile = lowerQuartile[i]; + it->median = median[i]; + it->upperQuartile = upperQuartile[i]; + it->maximum = maximum[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a minimum, \a lowerQuartile, \a median, \a upperQuartile + and \a maximum to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +{ + mDataContainer->add(QCPStatisticalBoxData(key, minimum, lowerQuartile, median, upperQuartile, maximum, outliers)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPStatisticalBox::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getQuartileBox(it))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + QCPStatisticalBoxDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + double minDistSqr = std::numeric_limits::max(); + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getQuartileBox(it).contains(pos)) // quartile box + { + double currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } else // whiskers + { + const QVector whiskerBackbones(getWhiskerBackboneLines(it)); + for (int i=0; iconstBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return qSqrt(minDistSqr); + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPStatisticalBoxDataContainer::const_iterator begin = visibleBegin; + QCPStatisticalBoxDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPStatisticalBoxDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +# ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->minimum) || + QCP::isInvalidData(it->lowerQuartile, it->median) || + QCP::isInvalidData(it->upperQuartile, it->maximum)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range has invalid data." << "Plottable name:" << name(); + for (int i=0; ioutliers.size(); ++i) + if (QCP::isInvalidData(it->outliers.at(i))) + qDebug() << Q_FUNC_INFO << "Data point outlier at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +# endif + + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + QCPScatterStyle finalOutlierStyle = mOutlierStyle; + if (isSelectedSegment && mSelectionDecorator) + finalOutlierStyle = mSelectionDecorator->getFinalScatterStyle(mOutlierStyle); + drawStatisticalBox(painter, it, finalOutlierStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->setBrush(mBrush); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! + Draws the graphical representation of a single statistical box with the data given by the + iterator \a it with the provided \a painter. + + If the statistical box has a set of outlier data points, they are drawn with \a outlierStyle. + + \see getQuartileBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const +{ + // draw quartile box: + applyDefaultAntialiasingHint(painter); + const QRectF quartileBox = getQuartileBox(it); + painter->drawRect(quartileBox); + // draw median line with cliprect set to quartile box: + painter->save(); + painter->setClipRect(quartileBox, Qt::IntersectClip); + painter->setPen(mMedianPen); + painter->drawLine(QLineF(coordsToPixels(it->key-mWidth*0.5, it->median), coordsToPixels(it->key+mWidth*0.5, it->median))); + painter->restore(); + // draw whisker lines: + applyAntialiasingHint(painter, mWhiskerAntialiased, QCP::aePlottables); + painter->setPen(mWhiskerPen); + painter->drawLines(getWhiskerBackboneLines(it)); + painter->setPen(mWhiskerBarPen); + painter->drawLines(getWhiskerBarLines(it)); + // draw outliers: + applyScattersAntialiasingHint(painter); + outlierStyle.applyTo(painter, mPen); + for (int i=0; ioutliers.size(); ++i) + outlierStyle.drawShape(painter, coordsToPixels(it->key, it->outliers.at(i))); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of box to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of box to include partially visible data points +} + +/*! \internal + + Returns the box in plot coordinates (keys in x, values in y of the returned rect) that covers the + value range from the lower to the upper quartile, of the data given by \a it. + + \see drawStatisticalBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +QRectF QCPStatisticalBox::getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QRectF result; + result.setTopLeft(coordsToPixels(it->key-mWidth*0.5, it->upperQuartile)); + result.setBottomRight(coordsToPixels(it->key+mWidth*0.5, it->lowerQuartile)); + return result; +} + +/*! \internal + + Returns the whisker backbones (keys in x, values in y of the returned lines) that cover the value + range from the minimum to the lower quartile, and from the upper quartile to the maximum of the + data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBarLines +*/ +QVector QCPStatisticalBox::getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key, it->lowerQuartile), coordsToPixels(it->key, it->minimum)); // min backbone + result[1].setPoints(coordsToPixels(it->key, it->upperQuartile), coordsToPixels(it->key, it->maximum)); // max backbone + return result; +} + +/*! \internal + + Returns the whisker bars (keys in x, values in y of the returned lines) that are placed at the + end of the whisker backbones, at the minimum and maximum of the data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBackboneLines +*/ +QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->minimum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->minimum)); // min bar + result[1].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->maximum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->maximum)); // max bar + return result; +} +/* end of 'src/plottables/plottable-statisticalbox.cpp' */ + + +/* including file 'src/plottables/plottable-colormap.cpp', size 47881 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorMapData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorMapData + \brief Holds the two-dimensional data of a QCPColorMap plottable. + + This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref + QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a + color, depending on the value. + + The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). + Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref + setKeyRange, \ref setValueRange). + + The data cells can be accessed in two ways: They can be directly addressed by an integer index + with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot + coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are + provided by the functions \ref coordToCell and \ref cellToCoord. + + A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if + allocated) has the same size as the data map. It can be accessed via \ref setAlpha, \ref + fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on + the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map. + + This class also buffers the minimum and maximum values that are in the data set, to provide + QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value + that is greater than the current maximum increases this maximum to the new value. However, + setting the cell that currently holds the maximum value to a smaller value doesn't decrease the + maximum again, because finding the true new maximum would require going through the entire data + array, which might be time consuming. The same holds for the data minimum. This functionality is + given by \ref recalculateDataBounds, such that you can decide when it is sensible to find the + true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience + parameter \a recalculateDataBounds which may be set to true to automatically call \ref + recalculateDataBounds internally. +*/ + +/* start of documentation of inline functions */ + +/*! \fn bool QCPColorMapData::isEmpty() const + + Returns whether this instance carries no data. This is equivalent to having a size where at least + one of the dimensions is 0 (see \ref setSize). +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction + and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap + at the coordinates \a keyRange and \a valueRange. + + \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange +*/ +QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : + mKeySize(0), + mValueSize(0), + mKeyRange(keyRange), + mValueRange(valueRange), + mIsEmpty(true), + mData(0), + mAlpha(0), + mDataModified(true) +{ + setSize(keySize, valueSize); + fill(0); +} + +QCPColorMapData::~QCPColorMapData() +{ + if (mData) + delete[] mData; + if (mAlpha) + delete[] mAlpha; +} + +/*! + Constructs a new QCPColorMapData instance copying the data and range of \a other. +*/ +QCPColorMapData::QCPColorMapData(const QCPColorMapData &other) : + mKeySize(0), + mValueSize(0), + mIsEmpty(true), + mData(0), + mAlpha(0), + mDataModified(true) +{ + *this = other; +} + +/*! + Overwrites this color map data instance with the data stored in \a other. The alpha map state is + transferred, too. +*/ +QCPColorMapData &QCPColorMapData::operator=(const QCPColorMapData &other) +{ + if (&other != this) + { + const int keySize = other.keySize(); + const int valueSize = other.valueSize(); + if (!other.mAlpha && mAlpha) + clearAlpha(); + setSize(keySize, valueSize); + if (other.mAlpha && !mAlpha) + createAlpha(false); + setRange(other.keyRange(), other.valueRange()); + if (!isEmpty()) + { + memcpy(mData, other.mData, sizeof(mData[0])*keySize*valueSize); + if (mAlpha) + memcpy(mAlpha, other.mAlpha, sizeof(mAlpha[0])*keySize*valueSize); + } + mDataBounds = other.mDataBounds; + mDataModified = true; + } + return *this; +} + +/* undocumented getter */ +double QCPColorMapData::data(double key, double value) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + return mData[valueCell*mKeySize + keyCell]; + else + return 0; +} + +/* undocumented getter */ +double QCPColorMapData::cell(int keyIndex, int valueIndex) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mData[valueIndex*mKeySize + keyIndex]; + else + return 0; +} + +/*! + Returns the alpha map value of the cell with the indices \a keyIndex and \a valueIndex. + + If this color map data doesn't have an alpha map (because \ref setAlpha was never called after + creation or after a call to \ref clearAlpha), returns 255, which corresponds to full opacity. + + \see setAlpha +*/ +unsigned char QCPColorMapData::alpha(int keyIndex, int valueIndex) +{ + if (mAlpha && keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mAlpha[valueIndex*mKeySize + keyIndex]; + else + return 255; +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in + the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref + isEmpty returns true. + + \see setRange, setKeySize, setValueSize +*/ +void QCPColorMapData::setSize(int keySize, int valueSize) +{ + if (keySize != mKeySize || valueSize != mValueSize) + { + mKeySize = keySize; + mValueSize = valueSize; + if (mData) + delete[] mData; + mIsEmpty = mKeySize == 0 || mValueSize == 0; + if (!mIsEmpty) + { +#ifdef __EXCEPTIONS + try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message +#endif + mData = new double[mKeySize*mValueSize]; +#ifdef __EXCEPTIONS + } catch (...) { mData = 0; } +#endif + if (mData) + fill(0); + else + qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; + } else + mData = 0; + + if (mAlpha) // if we had an alpha map, recreate it with new size + createAlpha(); + + mDataModified = true; + } +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. + + \see setKeyRange, setSize, setValueSize +*/ +void QCPColorMapData::setKeySize(int keySize) +{ + setSize(keySize, mValueSize); +} + +/*! + Resizes the data array to have \a valueSize cells in the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. + + \see setValueRange, setSize, setKeySize +*/ +void QCPColorMapData::setValueSize(int valueSize) +{ + setSize(mKeySize, valueSize); +} + +/*! + Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area + covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setSize +*/ +void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) +{ + setKeyRange(keyRange); + setValueRange(valueRange); +} + +/*! + Sets the coordinate range the data shall be distributed over in the key dimension. Together with + the value range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setRange, setValueRange, setSize +*/ +void QCPColorMapData::setKeyRange(const QCPRange &keyRange) +{ + mKeyRange = keyRange; +} + +/*! + Sets the coordinate range the data shall be distributed over in the value dimension. Together with + the key range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there + will be cells centered on the value coordinates 2, 2.5 and 3. + + \see setRange, setKeyRange, setSize +*/ +void QCPColorMapData::setValueRange(const QCPRange &valueRange) +{ + mValueRange = valueRange; +} + +/*! + Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a + z. + + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or + value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, + you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to + determine the cell index. Rather directly access the cell index with \ref + QCPColorMapData::setCell. + + \see setCell, setRange +*/ +void QCPColorMapData::setData(double key, double value, double z) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + { + mData[valueCell*mKeySize + keyCell] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } +} + +/*! + Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices + enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see + \ref setSize). + + In the standard plot configuration (horizontal key axis and vertical value axis, both not + range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with + indices (keySize-1, valueSize-1) is in the top right corner of the color map. + + \see setData, setSize +*/ +void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + mData[valueIndex*mKeySize + keyIndex] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Sets the alpha of the color map cell given by \a keyIndex and \a valueIndex to \a alpha. A value + of 0 for \a alpha results in a fully transparent cell, and a value of 255 results in a fully + opaque cell. + + If an alpha map doesn't exist yet for this color map data, it will be created here. If you wish + to restore full opacity and free any allocated memory of the alpha map, call \ref clearAlpha. + + Note that the cell-wise alpha which can be configured here is independent of any alpha configured + in the color map's gradient (\ref QCPColorGradient). If a cell is affected both by the cell-wise + and gradient alpha, the alpha values will be blended accordingly during rendering of the color + map. + + \see fillAlpha, clearAlpha +*/ +void QCPColorMapData::setAlpha(int keyIndex, int valueIndex, unsigned char alpha) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + if (mAlpha || createAlpha()) + { + mAlpha[valueIndex*mKeySize + keyIndex] = alpha; + mDataModified = true; + } + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Goes through the data and updates the buffered minimum and maximum data values. + + Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange + and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten + with a smaller or larger value respectively, since the buffered maximum/minimum values have been + updated the last time. Why this is the case is explained in the class description (\ref + QCPColorMapData). + + Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a + recalculateDataBounds for convenience. Setting this to true will call this method for you, before + doing the rescale. +*/ +void QCPColorMapData::recalculateDataBounds() +{ + if (mKeySize > 0 && mValueSize > 0) + { + double minHeight = mData[0]; + double maxHeight = mData[0]; + const int dataCount = mValueSize*mKeySize; + for (int i=0; i maxHeight) + maxHeight = mData[i]; + if (mData[i] < minHeight) + minHeight = mData[i]; + } + mDataBounds.lower = minHeight; + mDataBounds.upper = maxHeight; + } +} + +/*! + Frees the internal data memory. + + This is equivalent to calling \ref setSize "setSize(0, 0)". +*/ +void QCPColorMapData::clear() +{ + setSize(0, 0); +} + +/*! + Frees the internal alpha map. The color map will have full opacity again. +*/ +void QCPColorMapData::clearAlpha() +{ + if (mAlpha) + { + delete[] mAlpha; + mAlpha = 0; + mDataModified = true; + } +} + +/*! + Sets all cells to the value \a z. +*/ +void QCPColorMapData::fill(double z) +{ + const int dataCount = mValueSize*mKeySize; + for (int i=0; i(data); + return; + } + if (copy) + { + *mMapData = *data; + } else + { + delete mMapData; + mMapData = data; + } + mMapImageInvalidated = true; +} + +/*! + Sets the data range of this color map to \a dataRange. The data range defines which data values + are mapped to the color gradient. + + To make the data range span the full range of the data set, use \ref rescaleDataRange. + + \see QCPColorScale::setDataRange +*/ +void QCPColorMap::setDataRange(const QCPRange &dataRange) +{ + if (!QCPRange::validRange(dataRange)) return; + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + if (mDataScaleType == QCPAxis::stLogarithmic) + mDataRange = dataRange.sanitizedForLogScale(); + else + mDataRange = dataRange.sanitizedForLinScale(); + mMapImageInvalidated = true; + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets whether the data is correlated with the color gradient linearly or logarithmically. + + \see QCPColorScale::setDataScaleType +*/ +void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + mMapImageInvalidated = true; + emit dataScaleTypeChanged(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + } +} + +/*! + Sets the color gradient that is used to represent the data. For more details on how to create an + own gradient or use one of the preset gradients, see \ref QCPColorGradient. + + The colors defined by the gradient will be used to represent data values in the currently set + data range, see \ref setDataRange. Data points that are outside this data range will either be + colored uniformly with the respective gradient boundary color, or the gradient will repeat, + depending on \ref QCPColorGradient::setPeriodic. + + \see QCPColorScale::setGradient +*/ +void QCPColorMap::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + mMapImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets whether the color map image shall use bicubic interpolation when displaying the color map + shrinked or expanded, and not at a 1:1 pixel-to-data scale. + + \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" +*/ +void QCPColorMap::setInterpolate(bool enabled) +{ + mInterpolate = enabled; + mMapImageInvalidated = true; // because oversampling factors might need to change +} + +/*! + Sets whether the outer most data rows and columns are clipped to the specified key and value + range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). + + if \a enabled is set to false, the data points at the border of the color map are drawn with the + same width and height as all other data points. Since the data points are represented by + rectangles of one color centered on the data coordinate, this means that the shown color map + extends by half a data point over the specified key/value range in each direction. + + \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" +*/ +void QCPColorMap::setTightBoundary(bool enabled) +{ + mTightBoundary = enabled; +} + +/*! + Associates the color scale \a colorScale with this color map. + + This means that both the color scale and the color map synchronize their gradient, data range and + data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps + can be associated with one single color scale. This causes the color maps to also synchronize + those properties, via the mutual color scale. + + This function causes the color map to adopt the current color gradient, data range and data scale + type of \a colorScale. After this call, you may change these properties at either the color map + or the color scale, and the setting will be applied to both. + + Pass 0 as \a colorScale to disconnect the color scale from this color map again. +*/ +void QCPColorMap::setColorScale(QCPColorScale *colorScale) +{ + if (mColorScale) // unconnect signals from old color scale + { + disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + mColorScale = colorScale; + if (mColorScale) // connect signals to new color scale + { + setGradient(mColorScale.data()->gradient()); + setDataRange(mColorScale.data()->dataRange()); + setDataScaleType(mColorScale.data()->dataScaleType()); + connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } +} + +/*! + Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the + current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, + only for the third data dimension of the color map. + + The minimum and maximum values of the data set are buffered in the internal QCPColorMapData + instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref + QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For + performance reasons, however, they are only updated in an expanding fashion. So the buffered + maximum can only increase and the buffered minimum can only decrease. In consequence, changes to + the data that actually lower the maximum of the data set (by overwriting the cell holding the + current maximum with a smaller value), aren't recognized and the buffered maximum overestimates + the true maximum of the data set. The same happens for the buffered minimum. To recalculate the + true minimum and maximum by explicitly looking at each cell, the method + QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a + recalculateDataBounds calls this method before setting the data range to the buffered minimum and + maximum. + + \see setDataRange +*/ +void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) +{ + if (recalculateDataBounds) + mMapData->recalculateDataBounds(); + setDataRange(mMapData->dataBounds()); +} + +/*! + Takes the current appearance of the color map and updates the legend icon, which is used to + represent this color map in the legend (see \ref QCPLegend). + + The \a transformMode specifies whether the rescaling is done by a faster, low quality image + scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm + (Qt::SmoothTransformation). + + The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to + the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured + legend icon size, the thumb will be rescaled during drawing of the legend item. + + \see setDataRange +*/ +void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) +{ + if (mMapImage.isNull() && !data()->isEmpty()) + updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) + + if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again + { + bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + } +} + +/* inherits documentation from base class */ +double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mMapData->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (mMapData->keyRange().contains(posKey) && mMapData->valueRange().contains(posValue)) + { + if (details) + details->setValue(QCPDataSelection(QCPDataRange(0, 1))); // temporary solution, to facilitate whole-plottable selection. Replace in future version with segmented 2D selection. + return mParentPlot->selectionTolerance()*0.99; + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + foundRange = true; + QCPRange result = mMapData->keyRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (inKeyRange != QCPRange()) + { + if (mMapData->keyRange().upper < inKeyRange.lower || mMapData->keyRange().lower > inKeyRange.upper) + { + foundRange = false; + return QCPRange(); + } + } + + foundRange = true; + QCPRange result = mMapData->valueRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/*! \internal + + Updates the internal map image buffer by going through the internal \ref QCPColorMapData and + turning the data values into color pixels with \ref QCPColorGradient::colorize. + + This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image + has been invalidated for a different reason (e.g. a change of the data range with \ref + setDataRange). + + If the map cell count is low, the image created will be oversampled in order to avoid a + QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images + without smooth transform enabled. Accordingly, oversampling isn't performed if \ref + setInterpolate is true. +*/ +void QCPColorMap::updateMapImage() +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) return; + if (mMapData->isEmpty()) return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + const int keySize = mMapData->keySize(); + const int valueSize = mMapData->valueSize(); + int keyOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)keySize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + int valueOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)valueSize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + + // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: + if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) + mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); + else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) + mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); + + if (mMapImage.isNull()) + { + qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; + mMapImage = QImage(QSize(10, 10), format); + mMapImage.fill(Qt::black); + } else + { + QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + // resize undersampled map image to actual key/value cell sizes: + if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) + mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); + else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) + mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); + localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image + } else if (!mUndersampledMapImage.isNull()) + mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it + + const double *rawData = mMapData->mData; + const unsigned char *rawAlpha = mMapData->mAlpha; + if (keyAxis->orientation() == Qt::Horizontal) + { + const int lineCount = valueSize; + const int rowCount = keySize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + } + } else // keyAxis->orientation() == Qt::Vertical + { + const int lineCount = keySize; + const int rowCount = valueSize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line, rawAlpha+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + } + } + + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + if (keyAxis->orientation() == Qt::Horizontal) + mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + else + mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + } + } + mMapData->mDataModified = false; + mMapImageInvalidated = false; +} + +/* inherits documentation from base class */ +void QCPColorMap::draw(QCPPainter *painter) +{ + if (mMapData->isEmpty()) return; + if (!mKeyAxis || !mValueAxis) return; + applyDefaultAntialiasingHint(painter); + + if (mMapData->mDataModified || mMapImageInvalidated) + updateMapImage(); + + // use buffer if painting vectorized (PDF): + const bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); + QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized + QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in + QPixmap mapBuffer; + if (useBuffer) + { + const double mapBufferPixelRatio = 3; // factor by which DPI is increased in embedded bitmaps + mapBufferTarget = painter->clipRegion().boundingRect(); + mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize()); + mapBuffer.fill(Qt::transparent); + localPainter = new QCPPainter(&mapBuffer); + localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); + localPainter->translate(-mapBufferTarget.topLeft()); + } + + QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): + double halfCellWidth = 0; // in pixels + double halfCellHeight = 0; // in pixels + if (keyAxis()->orientation() == Qt::Horizontal) + { + if (mMapData->keySize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->valueSize()-1); + } else // keyAxis orientation is Qt::Vertical + { + if (mMapData->keySize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->valueSize()-1); + } + imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight); + const bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + const bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + const bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, mInterpolate); + QRegion clipBackup; + if (mTightBoundary) + { + clipBackup = localPainter->clipRegion(); + QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + localPainter->setClipRect(tightClipRect, Qt::IntersectClip); + } + localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); + if (mTightBoundary) + localPainter->setClipRegion(clipBackup); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); + + if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter + { + delete localPainter; + painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer); + } +} + +/* inherits documentation from base class */ +void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + // draw map thumbnail: + if (!mLegendIcon.isNull()) + { + QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation); + QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height()); + iconRect.moveCenter(rect.center()); + painter->drawPixmap(iconRect.topLeft(), scaledIcon); + } + /* + // draw frame: + painter->setBrush(Qt::NoBrush); + painter->setPen(Qt::black); + painter->drawRect(rect.adjusted(1, 1, 0, 0)); + */ +} +/* end of 'src/plottables/plottable-colormap.cpp' */ + + +/* including file 'src/plottables/plottable-financial.cpp', size 42610 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancialData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancialData + \brief Holds the data of one single data point for QCPFinancial. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a open: The opening value at the data point (this is the \a mainValue) + \li \a high: The high/maximum value at the data point + \li \a low: The low/minimum value at the data point + \li \a close: The closing value at the data point + + The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef + for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPFinancialDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPFinancialData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPFinancialData QCPFinancialData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPFinancialData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainValue() const + + Returns the \a open member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPFinancialData::valueRange() const + + Returns a QCPRange spanning from the \a low to the \a high value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPFinancialData::QCPFinancialData() : + key(0), + open(0), + high(0), + low(0), + close(0) +{ +} + +/*! + Constructs a data point with the specified \a key and OHLC values. +*/ +QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) : + key(key), + open(open), + high(high), + low(low), + close(close) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancial +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancial + \brief A plottable representing a financial stock chart + + \image html QCPFinancial.png + + This plottable represents time series data binned to certain intervals, mainly used for stock + charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be + set via \ref setChartStyle. + + The data is passed via \ref setData as a set of open/high/low/close values at certain keys + (typically times). This means the data must be already binned appropriately. If data is only + available as a series of values (e.g. \a price against \a time), you can use the static + convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed + to \ref setData. + + The width of the OHLC bars/candlesticks can be controlled with \ref setWidth and \ref + setWidthType. A typical choice is to set the width type to \ref wtPlotCoords (the default) and + the width to (or slightly less than) one time bin interval width. + + \section qcpfinancial-appearance Changing the appearance + + Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored, + lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush). + + If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are + represented with a different pen and brush than negative changes (\a close < \a open). These can + be configured with \ref setPenPositive, \ref setPenNegative, \ref setBrushPositive, and \ref + setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection + however, the normal selected pen/brush (provided by the \ref selectionDecorator) is used, + irrespective of whether the chart is single- or two-colored. + + \section qcpfinancial-usage Usage + + Like all data representing objects in QCustomPlot, the QCPFinancial is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot + instance takes ownership of the plottable, so do not delete it manually but use + QCustomPlot::removePlottable() instead. The newly created plottable can be modified, e.g.: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-2 + Here we have used the static helper method \ref timeSeriesToOhlc, to turn a time-price data + series into a 24-hour binned open-high-low-close data series as QCPFinancial uses. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPFinancialDataContainer *QCPFinancial::data() const + + Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods, in certain situations. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPFinancial::QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mChartStyle(csCandlestick), + mWidth(0.5), + mWidthType(wtPlotCoords), + mTwoColored(true), + mBrushPositive(QBrush(QColor(50, 160, 0))), + mBrushNegative(QBrush(QColor(180, 0, 15))), + mPenPositive(QPen(QColor(40, 150, 0))), + mPenNegative(QPen(QColor(170, 5, 5))) +{ + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPFinancial::~QCPFinancial() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely. + Modifying the data in the container will then affect all financials that share the container. + Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the financial's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-2 + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a + close. The provided vectors should have equal length. Else, the number of added points will be + the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, open, high, low, close, alreadySorted); +} + +/*! + Sets which representation style shall be used to display the OHLC data. +*/ +void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) +{ + mChartStyle = style; +} + +/*! + Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. + + A typical choice is to set it to (or slightly less than) one bin interval width. +*/ +void QCPFinancial::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the financial bars is defined. See the documentation of \ref WidthType for + an explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPFinancial::setWidthType(QCPFinancial::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets whether this chart shall contrast positive from negative trends per data point by using two + separate colors to draw the respective bars/candlesticks. + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setTwoColored(bool twoColored) +{ + mTwoColored = twoColored; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushNegative, setPenPositive, setPenNegative +*/ +void QCPFinancial::setBrushPositive(const QBrush &brush) +{ + mBrushPositive = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushPositive, setPenNegative, setPenPositive +*/ +void QCPFinancial::setBrushNegative(const QBrush &brush) +{ + mBrushNegative = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setPenPositive(const QPen &pen) +{ + mPenPositive = pen; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setBrushNegative, setBrushPositive +*/ +void QCPFinancial::setPenNegative(const QPen &pen) +{ + mPenNegative = pen; +} + +/*! \overload + + Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data. + The provided vectors should have equal length. Else, the number of added points will be the size + of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + if (keys.size() != open.size() || open.size() != high.size() || high.size() != low.size() || low.size() != close.size() || close.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, open, high, low, close have different sizes:" << keys.size() << open.size() << high.size() << low.size() << close.size(); + const int n = qMin(keys.size(), qMin(open.size(), qMin(high.size(), qMin(low.size(), close.size())))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->open = open[i]; + it->high = high[i]; + it->low = low[i]; + it->close = close[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a open, \a high, \a low and \a close to the current + data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(double key, double open, double high, double low, double close) +{ + mDataContainer->add(QCPFinancialData(key, open, high, low, close)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPFinancialDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(selectionHitBox(it))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + QCPFinancialDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + // perform select test according to configured style: + double result = -1; + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + result = ohlcSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + case QCPFinancial::csCandlestick: + result = candlestickSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + } + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } + + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/*! + A convenience function that converts time series data (\a value against \a time) to OHLC binned + data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const + QCPFinancialDataContainer&). + + The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. + For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour + each, set \a timeBinSize to 3600. + + \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The + value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. + It merely defines the mathematical offset/phase of the bins that will be used to process the + data. +*/ +QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset) +{ + QCPFinancialDataContainer data; + int count = qMin(time.size(), value.size()); + if (count == 0) + return QCPFinancialDataContainer(); + + QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); + int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); + for (int i=0; i currentBinData.high) currentBinData.high = value.at(i); + if (i == count-1) // last data point is in current bin, finalize bin: + { + currentBinData.close = value.at(i); + currentBinData.key = timeBinOffset+(index)*timeBinSize; + data.add(currentBinData); + } + } else // data point not anymore in current bin, set close of old and open of new bin, and add old to map: + { + // finalize current bin: + currentBinData.close = value.at(i-1); + currentBinData.key = timeBinOffset+(index-1)*timeBinSize; + data.add(currentBinData); + // start next bin: + currentBinIndex = index; + currentBinData.open = value.at(i); + currentBinData.high = value.at(i); + currentBinData.low = value.at(i); + } + } + + return data; +} + +/* inherits documentation from base class */ +void QCPFinancial::draw(QCPPainter *painter) +{ + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPFinancialDataContainer::const_iterator begin = visibleBegin; + QCPFinancialDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + // draw data segment according to configured style: + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + drawOhlcPlot(painter, begin, end, isSelectedSegment); break; + case QCPFinancial::csCandlestick: + drawCandlestickPlot(painter, begin, end, isSelectedSegment); break; + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing + if (mChartStyle == csOhlc) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } + } else if (mChartStyle == csCandlestick) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as OHLC bars with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. +*/ +void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(it->low))); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(keyPixel-pixelWidth, openPixel), QPointF(keyPixel, openPixel)); + // draw close: + painter->drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+pixelWidth, closePixel)); + } + } else + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(it->low), keyPixel)); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(openPixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel)); + // draw close: + painter->drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+pixelWidth)); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as Candlesticks with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. +*/ +void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + // draw low: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(keyPixel-pixelWidth, closePixel), QPointF(keyPixel+pixelWidth, openPixel))); + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + // draw low: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(closePixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel+pixelWidth))); + } + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). Provide the pixel position of + \a key in \a keyPixel (because usually this was already calculated via \ref QCPAxis::coordToPixel + when this function is called). + + It returns the number of pixels the bar extends to higher keys, relative to the \a key + coordinate. So with a non-reversed horizontal axis, the return value is positive. With a reversed + horizontal axis, the return value is negative. This is important so the open/close flags on the + \ref csOhlc bar are drawn to the correct side. +*/ +double QCPFinancial::getPixelWidth(double key, double keyPixel) const +{ + double result = 0; + switch (mWidthType) + { + case wtAbsolute: + { + if (mKeyAxis) + result = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + result = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + result = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + result = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } + return result; +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low))); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel)); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a + end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + called by the drawing methods to determine which data (key) range is visible at the current key + axis range setting, so only that needs to be processed. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + begin may still be just outside the visible range. + + \a end returns the iterator just above the highest data point that needs to be taken into + account. Same as before, \a end may also lie just outside of the visible range + + if the plottable contains no data, both \a begin and \a end point to \c constEnd. +*/ +void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of ohlc/candlestick to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of ohlc/candlestick to include partially visible data points +} + +/*! \internal + + Returns the hit box in pixel coordinates that will be used for data selection with the selection + rect (\ref selectTestRect), of the data point given by \a it. +*/ +QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator it) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } + + double keyPixel = keyAxis->coordToPixel(it->key); + double highPixel = valueAxis->coordToPixel(it->high); + double lowPixel = valueAxis->coordToPixel(it->low); + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it->key-mWidth*0.5); + if (keyAxis->orientation() == Qt::Horizontal) + return QRectF(keyPixel-keyWidthPixels, highPixel, keyWidthPixels*2, lowPixel-highPixel).normalized(); + else + return QRectF(highPixel, keyPixel-keyWidthPixels, lowPixel-highPixel, keyWidthPixels*2).normalized(); +} +/* end of 'src/plottables/plottable-financial.cpp' */ + + +/* including file 'src/plottables/plottable-errorbar.cpp', size 37355 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBarsData + \brief Holds the data of one single error bar for QCPErrorBars. + + The stored data is: + \li \a errorMinus: how much the error bar extends towards negative coordinates from the data + point position + \li \a errorPlus: how much the error bar extends towards positive coordinates from the data point + position + + The container for storing the error bar information is \ref QCPErrorBarsDataContainer. It is a + typedef for QVector<\ref QCPErrorBarsData>. + + \see QCPErrorBarsDataContainer +*/ + +/*! + Constructs an error bar with errors set to zero. +*/ +QCPErrorBarsData::QCPErrorBarsData() : + errorMinus(0), + errorPlus(0) +{ +} + +/*! + Constructs an error bar with equal \a error in both negative and positive direction. +*/ +QCPErrorBarsData::QCPErrorBarsData(double error) : + errorMinus(error), + errorPlus(error) +{ +} + +/*! + Constructs an error bar with negative and positive errors set to \a errorMinus and \a errorPlus, + respectively. +*/ +QCPErrorBarsData::QCPErrorBarsData(double errorMinus, double errorPlus) : + errorMinus(errorMinus), + errorPlus(errorPlus) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBars + \brief A plottable that adds a set of error bars to other plottables. + + \image html QCPErrorBars.png + + The \ref QCPErrorBars plottable can be attached to other one-dimensional plottables (e.g. \ref + QCPGraph, \ref QCPCurve, \ref QCPBars, etc.) and equips them with error bars. + + Use \ref setDataPlottable to define for which plottable the \ref QCPErrorBars shall display the + error bars. The orientation of the error bars can be controlled with \ref setErrorType. + + By using \ref setData, you can supply the actual error data, either as symmetric error or + plus/minus asymmetric errors. \ref QCPErrorBars only stores the error data. The absolute + key/value position of each error bar will be adopted from the configured data plottable. The + error data of the \ref QCPErrorBars are associated one-to-one via their index to the data points + of the data plottable. You can directly access and manipulate the error bar data via \ref data. + + Set either of the plus/minus errors to NaN (qQNaN() or + std::numeric_limits::quiet_NaN()) to not show the respective error bar on the data point at + that index. + + \section qcperrorbars-appearance Changing the appearance + + The appearance of the error bars is defined by the pen (\ref setPen), and the width of the + whiskers (\ref setWhiskerWidth). Further, the error bar backbones may leave a gap around the data + point center to prevent that error bars are drawn too close to or even through scatter points. + This gap size can be controlled via \ref setSymbolGap. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPErrorBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPErrorBarsDataContainer. You + may use it to directly manipulate the error values, which may be more convenient and faster than + using the regular \ref setData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs an error bars plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + It is also important that the \a keyAxis and \a valueAxis are the same for the error bars + plottable and the data plottable that the error bars shall be drawn on (\ref setDataPlottable). + + The created \ref QCPErrorBars is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the \ref QCPErrorBars, so do not + delete it manually but use \ref QCustomPlot::removePlottable() instead. +*/ +QCPErrorBars::QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QVector), + mErrorType(etValueError), + mWhiskerWidth(9), + mSymbolGap(10) +{ + setPen(QPen(Qt::black, 0)); + setBrush(Qt::NoBrush); +} + +QCPErrorBars::~QCPErrorBars() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple \ref QCPErrorBars instances may share the same data + container safely. Modifying the data in the container will then affect all \ref QCPErrorBars + instances that share the container. Sharing can be achieved by simply exchanging the data + containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, assign the + data containers directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-2 + (This uses different notation compared with other plottables, because the \ref QCPErrorBars + uses a \c QVector as its data container, instead of a \ref QCPDataContainer.) + + \see addData +*/ +void QCPErrorBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Sets symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &error) +{ + mDataContainer->clear(); + addData(error); +} + +/*! \overload + + Sets asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &errorMinus, const QVector &errorPlus) +{ + mDataContainer->clear(); + addData(errorMinus, errorPlus); +} + +/*! + Sets the data plottable to which the error bars will be applied. The error values specified e.g. + via \ref setData will be associated one-to-one by the data point index to the data points of \a + plottable. This means that the error bars will adopt the key/value coordinates of the data point + with the same index. + + The passed \a plottable must be a one-dimensional plottable, i.e. it must implement the \ref + QCPPlottableInterface1D. Further, it must not be a \ref QCPErrorBars instance itself. If either + of these restrictions is violated, a corresponding qDebug output is generated, and the data + plottable of this \ref QCPErrorBars instance is set to zero. + + For proper display, care must also be taken that the key and value axes of the \a plottable match + those configured for this \ref QCPErrorBars instance. +*/ +void QCPErrorBars::setDataPlottable(QCPAbstractPlottable *plottable) +{ + if (plottable && qobject_cast(plottable)) + { + mDataPlottable = 0; + qDebug() << Q_FUNC_INFO << "can't set another QCPErrorBars instance as data plottable"; + return; + } + if (plottable && !plottable->interface1D()) + { + mDataPlottable = 0; + qDebug() << Q_FUNC_INFO << "passed plottable doesn't implement 1d interface, can't associate with QCPErrorBars"; + return; + } + + mDataPlottable = plottable; +} + +/*! + Sets in which orientation the error bars shall appear on the data points. If your data needs both + error dimensions, create two \ref QCPErrorBars with different \a type. +*/ +void QCPErrorBars::setErrorType(ErrorType type) +{ + mErrorType = type; +} + +/*! + Sets the width of the whiskers (the short bars at the end of the actual error bar backbones) to + \a pixels. +*/ +void QCPErrorBars::setWhiskerWidth(double pixels) +{ + mWhiskerWidth = pixels; +} + +/*! + Sets the gap diameter around the data points that will be left out when drawing the error bar + backbones. This gap prevents that error bars are drawn too close to or even through scatter + points. +*/ +void QCPErrorBars::setSymbolGap(double pixels) +{ + mSymbolGap = pixels; +} + +/*! \overload + + Adds symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &error) +{ + addData(error, error); +} + +/*! \overload + + Adds asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &errorMinus, const QVector &errorPlus) +{ + if (errorMinus.size() != errorPlus.size()) + qDebug() << Q_FUNC_INFO << "minus and plus error vectors have different sizes:" << errorMinus.size() << errorPlus.size(); + const int n = qMin(errorMinus.size(), errorPlus.size()); + mDataContainer->reserve(n); + for (int i=0; iappend(QCPErrorBarsData(errorMinus.at(i), errorPlus.at(i))); +} + +/*! \overload + + Adds a single symmetrical error bar as specified in \a error. The errors will be associated + one-to-one by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double error) +{ + mDataContainer->append(QCPErrorBarsData(error)); +} + +/*! \overload + + Adds a single asymmetrical error bar as specified in \a errorMinus and \a errorPlus. The errors + will be associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double errorMinus, double errorPlus) +{ + mDataContainer->append(QCPErrorBarsData(errorMinus, errorPlus)); +} + +/* inherits documentation from base class */ +int QCPErrorBars::dataCount() const +{ + return mDataContainer->size(); +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataSortKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataSortKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainValue(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainValue(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::dataValueRange(int index) const +{ + if (mDataPlottable) + { + const double value = mDataPlottable->interface1D()->dataMainValue(index); + if (index >= 0 && index < mDataContainer->size() && mErrorType == etValueError) + return QCPRange(value-mDataContainer->at(index).errorMinus, value+mDataContainer->at(index).errorPlus); + else + return QCPRange(value, value); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return QCPRange(); + } +} + +/* inherits documentation from base class */ +QPointF QCPErrorBars::dataPixelPosition(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataPixelPosition(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return QPointF(); +} + +/* inherits documentation from base class */ +bool QCPErrorBars::sortKeyIsMainKey() const +{ + if (mDataPlottable) + { + return mDataPlottable->interface1D()->sortKeyIsMainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return true; + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPErrorBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if (!mDataPlottable) + return result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd, QCPDataRange(0, dataCount())); + + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + backbones.clear(); + whiskers.clear(); + getErrorBarLines(it, backbones, whiskers); + for (int i=0; iconstBegin(), it-mDataContainer->constBegin()+1), false); + break; + } + } + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findBegin(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int beginIndex = mDataPlottable->interface1D()->findBegin(sortKey, expandedRange); + if (beginIndex >= mDataContainer->size()) + beginIndex = mDataContainer->size()-1; + return beginIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findEnd(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int endIndex = mDataPlottable->interface1D()->findEnd(sortKey, expandedRange); + if (endIndex > mDataContainer->size()) + endIndex = mDataContainer->size(); + return endIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mDataPlottable) return -1; + + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPErrorBarsDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +void QCPErrorBars::draw(QCPPainter *painter) +{ + if (!mDataPlottable) return; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + + // if the sort key isn't the main key, we must check the visibility for each data point/error bar individually + // (getVisibleDataBounds applies range restriction, but otherwise can only return full data range): + bool checkPointVisibility = !mDataPlottable->interface1D()->sortKeyIsMainKey(); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->errorMinus, it->errorPlus)) + qDebug() << Q_FUNC_INFO << "Data point at index" << it-mDataContainer->constBegin() << "invalid." << "Plottable name:" << name(); + } +#endif + + applyDefaultAntialiasingHint(painter); + painter->setBrush(Qt::NoBrush); + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + QVector backbones, whiskers; + for (int i=0; i= unselectedSegments.size(); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + if (painter->pen().capStyle() == Qt::SquareCap) + { + QPen capFixPen(painter->pen()); + capFixPen.setCapStyle(Qt::FlatCap); + painter->setPen(capFixPen); + } + backbones.clear(); + whiskers.clear(); + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (!checkPointVisibility || errorBarVisible(it-mDataContainer->constBegin())) + getErrorBarLines(it, backbones, whiskers); + } + painter->drawLines(backbones); + painter->drawLines(whiskers); + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPErrorBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + if (mErrorType == etValueError && mValueAxis && mValueAxis->orientation() == Qt::Vertical) + { + painter->drawLine(QLineF(rect.center().x(), rect.top()+2, rect.center().x(), rect.bottom()-1)); + painter->drawLine(QLineF(rect.center().x()-4, rect.top()+2, rect.center().x()+4, rect.top()+2)); + painter->drawLine(QLineF(rect.center().x()-4, rect.bottom()-1, rect.center().x()+4, rect.bottom()-1)); + } else + { + painter->drawLine(QLineF(rect.left()+2, rect.center().y(), rect.right()-2, rect.center().y())); + painter->drawLine(QLineF(rect.left()+2, rect.center().y()-4, rect.left()+2, rect.center().y()+4)); + painter->drawLine(QLineF(rect.right()-2, rect.center().y()-4, rect.right()-2, rect.center().y()+4)); + } +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + if (!mDataPlottable) + { + foundRange = false; + return QCPRange(); + } + + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (mErrorType == etValueError) + { + // error bar doesn't extend in key dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } else // mErrorType == etKeyError + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (qIsNaN(dataKey)) continue; + // plus error: + double current = dataKey + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataKey - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (!mDataPlottable) + { + foundRange = false; + return QCPRange(); + } + + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPErrorBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (mDataPlottable->interface1D()->sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = mDataContainer->constBegin()+findBegin(inKeyRange.lower); + itEnd = mDataContainer->constBegin()+findEnd(inKeyRange.upper); + } + for (QCPErrorBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange) + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (dataKey < inKeyRange.lower || dataKey > inKeyRange.upper) + continue; + } + if (mErrorType == etValueError) + { + const double dataValue = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); + if (qIsNaN(dataValue)) continue; + // plus error: + double current = dataValue + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataValue - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } else // mErrorType == etKeyError + { + // error bar doesn't extend in value dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! \internal + + Calculates the lines that make up the error bar belonging to the data point \a it. + + The resulting lines are added to \a backbones and \a whiskers. The vectors are not cleared, so + calling this method with different \a it but the same \a backbones and \a whiskers allows to + accumulate lines for multiple data points. + + This method assumes that \a it is a valid iterator within the bounds of this \ref QCPErrorBars + instance and within the bounds of the associated data plottable. +*/ +void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const +{ + if (!mDataPlottable) return; + + int index = it-mDataContainer->constBegin(); + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) + return; + QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data(); + QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data(); + const double centerErrorAxisPixel = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerOrthoAxisPixel = orthoAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerErrorAxisCoord = errorAxis->pixelToCoord(centerErrorAxisPixel); // depending on plottable, this might be different from just mDataPlottable->interface1D()->dataMainKey/Value + const double symbolGap = mSymbolGap*0.5*errorAxis->pixelOrientation(); + // plus error: + double errorStart, errorEnd; + if (!qIsNaN(it->errorPlus)) + { + errorStart = centerErrorAxisPixel+symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord+it->errorPlus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } + // minus error: + if (!qIsNaN(it->errorMinus)) + { + errorStart = centerErrorAxisPixel-symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord-it->errorMinus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } +} + +/*! \internal + + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + Since error bars with type \ref etKeyError may extend to arbitrarily positive and negative key + coordinates relative to their data point key, this method checks all outer error bars whether + they truly don't reach into the visible portion of the axis rect, by calling \ref + errorBarVisible. On the other hand error bars with type \ref etValueError that are associated + with data plottables whose sort key is equal to the main key (see \ref qcpdatacontainer-datatype + "QCPDataContainer DataType") can be handled very efficiently by finding the visible range of + error bars through binary search (\ref QCPPlottableInterface1D::findBegin and \ref + QCPPlottableInterface1D::findEnd). + + If the plottable's sort key is not equal to the main key, this method returns the full data + range, only restricted by \a rangeRestriction. Drawing optimization then has to be done on a + point-by-point basis in the \ref draw method. +*/ +void QCPErrorBars::getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable || rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable->interface1D()->sortKeyIsMainKey()) + { + // if the sort key isn't the main key, it's not possible to find a contiguous range of visible + // data points, so this method then only applies the range restriction and otherwise returns + // the full data range. Visibility checks must be done on a per-datapoin-basis during drawing + QCPDataRange dataRange(0, mDataContainer->size()); + dataRange = dataRange.bounded(rangeRestriction); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); + return; + } + + // get visible data range via interface from data plottable, and then restrict to available error data points: + const int n = qMin(mDataContainer->size(), mDataPlottable->interface1D()->dataCount()); + int beginIndex = mDataPlottable->interface1D()->findBegin(keyAxis->range().lower); + int endIndex = mDataPlottable->interface1D()->findEnd(keyAxis->range().upper); + int i = beginIndex; + while (i > 0 && i < n && i > rangeRestriction.begin()) + { + if (errorBarVisible(i)) + beginIndex = i; + --i; + } + i = endIndex; + while (i >= 0 && i < n && i < rangeRestriction.end()) + { + if (errorBarVisible(i)) + endIndex = i+1; + ++i; + } + QCPDataRange dataRange(beginIndex, endIndex); + dataRange = dataRange.bounded(rangeRestriction.bounded(QCPDataRange(0, mDataContainer->size()))); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); +} + +/*! \internal + + Calculates the minimum distance in pixels the error bars' representation has from the given \a + pixelPoint. This is used to determine whether the error bar was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. +*/ +double QCPErrorBars::pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (!mDataPlottable || mDataContainer->isEmpty()) + return -1.0; + if (!mKeyAxis || !mValueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + return -1.0; + } + + QCPErrorBarsDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); + + // calculate minimum distances to error backbones (whiskers are ignored for speed) and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + getErrorBarLines(it, backbones, whiskers); + for (int i=0; i &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! \internal + + Returns whether the error bar at the specified \a index is visible within the current key axis + range. + + This method assumes for performance reasons without checking that the key axis, the value axis, + and the data plottable (\ref setDataPlottable) are not zero and that \a index is within valid + bounds of this \ref QCPErrorBars instance and the bounds of the data plottable. +*/ +bool QCPErrorBars::errorBarVisible(int index) const +{ + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + const double centerKeyPixel = mKeyAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + if (qIsNaN(centerKeyPixel)) + return false; + + double keyMin, keyMax; + if (mErrorType == etKeyError) + { + const double centerKey = mKeyAxis->pixelToCoord(centerKeyPixel); + const double errorPlus = mDataContainer->at(index).errorPlus; + const double errorMinus = mDataContainer->at(index).errorMinus; + keyMax = centerKey+(qIsNaN(errorPlus) ? 0 : errorPlus); + keyMin = centerKey-(qIsNaN(errorMinus) ? 0 : errorMinus); + } else // mErrorType == etValueError + { + keyMax = mKeyAxis->pixelToCoord(centerKeyPixel+mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + keyMin = mKeyAxis->pixelToCoord(centerKeyPixel-mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + } + return ((keyMax > mKeyAxis->range().lower) && (keyMin < mKeyAxis->range().upper)); +} + +/*! \internal + + Returns whether \a line intersects (or is contained in) \a pixelRect. + + \a line is assumed to be either perfectly horizontal or perfectly vertical, as is the case for + error bar lines. +*/ +bool QCPErrorBars::rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const +{ + if (pixelRect.left() > line.x1() && pixelRect.left() > line.x2()) + return false; + else if (pixelRect.right() < line.x1() && pixelRect.right() < line.x2()) + return false; + else if (pixelRect.top() > line.y1() && pixelRect.top() > line.y2()) + return false; + else if (pixelRect.bottom() < line.y1() && pixelRect.bottom() < line.y2()) + return false; + else + return true; +} +/* end of 'src/plottables/plottable-errorbar.cpp' */ + + +/* including file 'src/items/item-straightline.cpp', size 7592 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemStraightLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemStraightLine + \brief A straight line that spans infinitely in both directions + + \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a point1 and \a point2, which define the straight line. +*/ + +/*! + Creates a straight line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + point1(createPosition(QLatin1String("point1"))), + point2(createPosition(QLatin1String("point2"))) +{ + point1->setCoords(0, 0); + point2->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemStraightLine::~QCPItemStraightLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemStraightLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemStraightLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return QCPVector2D(pos).distanceToStraightLine(point1->pixelPosition(), point2->pixelPosition()-point1->pixelPosition()); +} + +/* inherits documentation from base class */ +void QCPItemStraightLine::draw(QCPPainter *painter) +{ + QCPVector2D start(point1->pixelPosition()); + QCPVector2D end(point2->pixelPosition()); + // get visible segment of straight line inside clipRect: + double clipPad = mainPen().widthF(); + QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + } +} + +/*! \internal + + Returns the section of the straight line defined by \a base and direction vector \a + vec, that is visible in the specified \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const +{ + double bx, by; + double gamma; + QLineF result; + if (vec.x() == 0 && vec.y() == 0) + return result; + if (qFuzzyIsNull(vec.x())) // line is vertical + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical + } else if (qFuzzyIsNull(vec.y())) // line is horizontal + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal + } else // line is skewed + { + QList pointVectors; + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + // check right of rect: + bx = rect.right(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemStraightLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-straightline.cpp' */ + + +/* including file 'src/items/item-line.cpp', size 8498 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemLine + \brief A line from one point to another + + \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a start and \a end, which define the end points of the line. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. +*/ + +/*! + Creates a line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemLine::~QCPItemLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemLine::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemLine::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return qSqrt(QCPVector2D(pos).distanceSquaredToLine(start->pixelPosition(), end->pixelPosition())); +} + +/* inherits documentation from base class */ +void QCPItemLine::draw(QCPPainter *painter) +{ + QCPVector2D startVec(start->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if (qFuzzyIsNull((startVec-endVec).lengthSquared())) + return; + // get visible segment of straight line inside clipRect: + double clipPad = qMax(mHead.boundingDistance(), mTail.boundingDistance()); + clipPad = qMax(clipPad, (double)mainPen().widthF()); + QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, startVec-endVec); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, endVec-startVec); + } +} + +/*! \internal + + Returns the section of the line defined by \a start and \a end, that is visible in the specified + \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const +{ + bool containsStart = rect.contains(start.x(), start.y()); + bool containsEnd = rect.contains(end.x(), end.y()); + if (containsStart && containsEnd) + return QLineF(start.toPointF(), end.toPointF()); + + QCPVector2D base = start; + QCPVector2D vec = end-start; + double bx, by; + double gamma, mu; + QLineF result; + QList pointVectors; + + if (!qFuzzyIsNull(vec.y())) // line is not horizontal + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + } + if (!qFuzzyIsNull(vec.x())) // line is not vertical + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + // check right of rect: + bx = rect.right(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + } + + if (containsStart) + pointVectors.append(start); + if (containsEnd) + pointVectors.append(end); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-line.cpp' */ + + +/* including file 'src/items/item-curve.cpp', size 7159 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemCurve + \brief A curved line from one point to another + + \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." + + It has four positions, \a start and \a end, which define the end points of the line, and two + control points which define the direction the line exits from the start and the direction from + which it approaches the end: \a startDir and \a endDir. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an + arrow. + + Often it is desirable for the control points to stay at fixed relative positions to the start/end + point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, + and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. +*/ + +/*! + Creates a curve item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + startDir(createPosition(QLatin1String("startDir"))), + endDir(createPosition(QLatin1String("endDir"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + startDir->setCoords(0.5, 0); + endDir->setCoords(0, 0.5); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemCurve::~QCPItemCurve() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemCurve::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemCurve::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemCurve::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemCurve::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF startVec(start->pixelPosition()); + QPointF startDirVec(startDir->pixelPosition()); + QPointF endDirVec(endDir->pixelPosition()); + QPointF endVec(end->pixelPosition()); + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + QPolygonF polygon = cubicPath.toSubpathPolygons().first(); + QCPVector2D p(pos); + double minDistSqr = std::numeric_limits::max(); + for (int i=1; ipixelPosition()); + QCPVector2D startDirVec(startDir->pixelPosition()); + QCPVector2D endDirVec(endDir->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if ((endVec-startVec).length() > 1e10) // too large curves cause crash + return; + + QPainterPath cubicPath(startVec.toPointF()); + cubicPath.cubicTo(startDirVec.toPointF(), endDirVec.toPointF(), endVec.toPointF()); + + // paint visible segment, if existent: + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + QRect cubicRect = cubicPath.controlPointRect().toRect(); + if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position + cubicRect.adjust(0, 0, 1, 1); + if (clip.intersects(cubicRect)) + { + painter->setPen(mainPen()); + painter->drawPath(cubicPath); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, -cubicPath.angleAtPercent(1)/180.0*M_PI); + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemCurve::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-curve.cpp' */ + + +/* including file 'src/items/item-rect.cpp', size 6479 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemRect + \brief A rectangle + + \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemRect::~QCPItemRect() +{ +} + +/*! + Sets the pen that will be used to draw the line of the rectangle + + \see setSelectedPen, setBrush +*/ +void QCPItemRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the rectangle when selected + + \see setPen, setSelected +*/ +void QCPItemRect::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemRect::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()).normalized(); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); +} + +/* inherits documentation from base class */ +void QCPItemRect::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF rect = QRectF(p1, p2).normalized(); + double clipPad = mainPen().widthF(); + QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(rect); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemRect::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemRect::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemRect::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-rect.cpp' */ + + +/* including file 'src/items/item-text.cpp', size 13338 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemText +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemText + \brief A text label + + \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." + + Its position is defined by the member \a position and the setting of \ref setPositionAlignment. + The latter controls which part of the text rect shall be aligned with \a position. + + The text alignment itself (i.e. left, center, right) can be controlled with \ref + setTextAlignment. + + The text may be rotated around the \a position point with \ref setRotation. +*/ + +/*! + Creates a text item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemText::QCPItemText(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + topLeft(createAnchor(QLatin1String("topLeft"), aiTopLeft)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRight(createAnchor(QLatin1String("bottomRight"), aiBottomRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mText(QLatin1String("text")), + mPositionAlignment(Qt::AlignCenter), + mTextAlignment(Qt::AlignTop|Qt::AlignHCenter), + mRotation(0) +{ + position->setCoords(0, 0); + + setPen(Qt::NoPen); + setSelectedPen(Qt::NoPen); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setColor(Qt::black); + setSelectedColor(Qt::blue); +} + +QCPItemText::~QCPItemText() +{ +} + +/*! + Sets the color of the text. +*/ +void QCPItemText::setColor(const QColor &color) +{ + mColor = color; +} + +/*! + Sets the color of the text that will be used when the item is selected. +*/ +void QCPItemText::setSelectedColor(const QColor &color) +{ + mSelectedColor = color; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text. To disable the + border, set \a pen to Qt::NoPen. + + \see setSelectedPen, setBrush, setPadding +*/ +void QCPItemText::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text, when the item is + selected. To disable the border, set \a pen to Qt::NoPen. + + \see setPen +*/ +void QCPItemText::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used do fill the background of the text. To disable the + background, set \a brush to Qt::NoBrush. + + \see setSelectedBrush, setPen, setPadding +*/ +void QCPItemText::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the + background, set \a brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemText::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the font of the text. + + \see setSelectedFont, setColor +*/ +void QCPItemText::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the font of the text that will be used when the item is selected. + + \see setFont +*/ +void QCPItemText::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the text that will be displayed. Multi-line texts are supported by inserting a line break + character, e.g. '\n'. + + \see setFont, setColor, setTextAlignment +*/ +void QCPItemText::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets which point of the text rect shall be aligned with \a position. + + Examples: + \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such + that the top of the text rect will be horizontally centered on \a position. + \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the + bottom left corner of the text rect. + + If you want to control the alignment of (multi-lined) text within the text rect, use \ref + setTextAlignment. +*/ +void QCPItemText::setPositionAlignment(Qt::Alignment alignment) +{ + mPositionAlignment = alignment; +} + +/*! + Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). +*/ +void QCPItemText::setTextAlignment(Qt::Alignment alignment) +{ + mTextAlignment = alignment; +} + +/*! + Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated + around \a position. +*/ +void QCPItemText::setRotation(double degrees) +{ + mRotation = degrees; +} + +/*! + Sets the distance between the border of the text rectangle and the text. The appearance (and + visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. +*/ +void QCPItemText::setPadding(const QMargins &padding) +{ + mPadding = padding; +} + +/* inherits documentation from base class */ +double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + // The rect may be rotated, so we transform the actual clicked pos to the rotated + // coordinate system, so we can use the normal rectDistance function for non-rotated rects: + QPointF positionPixels(position->pixelPosition()); + QTransform inputTransform; + inputTransform.translate(positionPixels.x(), positionPixels.y()); + inputTransform.rotate(-mRotation); + inputTransform.translate(-positionPixels.x(), -positionPixels.y()); + QPointF rotatedPos = inputTransform.map(pos); + QFontMetrics fontMetrics(mFont); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); + textBoxRect.moveTopLeft(textPos.toPoint()); + + return rectDistance(textBoxRect, rotatedPos, true); +} + +/* inherits documentation from base class */ +void QCPItemText::draw(QCPPainter *painter) +{ + QPointF pos(position->pixelPosition()); + QTransform transform = painter->transform(); + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + painter->setFont(mainFont()); + QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); + textBoxRect.moveTopLeft(textPos.toPoint()); + double clipPad = mainPen().widthF(); + QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect()))) + { + painter->setTransform(transform); + if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || + (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(textBoxRect); + } + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(mainColor())); + painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemText::anchorPixelPosition(int anchorId) const +{ + // get actual rect points (pretty much copied from draw function): + QPointF pos(position->pixelPosition()); + QTransform transform; + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + QFontMetrics fontMetrics(mainFont()); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textBoxRect.moveTopLeft(textPos.toPoint()); + QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); + + switch (anchorId) + { + case aiTopLeft: return rectPoly.at(0); + case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; + case aiTopRight: return rectPoly.at(1); + case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; + case aiBottomRight: return rectPoly.at(2); + case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; + case aiBottomLeft: return rectPoly.at(3); + case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the point that must be given to the QPainter::drawText function (which expects the top + left point of the text rect), according to the position \a pos, the text bounding box \a rect and + the requested \a positionAlignment. + + For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point + will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally + drawn at that point, the lower left corner of the resulting text rect is at \a pos. +*/ +QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const +{ + if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) + return pos; + + QPointF result = pos; // start at top left + if (positionAlignment.testFlag(Qt::AlignHCenter)) + result.rx() -= rect.width()/2.0; + else if (positionAlignment.testFlag(Qt::AlignRight)) + result.rx() -= rect.width(); + if (positionAlignment.testFlag(Qt::AlignVCenter)) + result.ry() -= rect.height()/2.0; + else if (positionAlignment.testFlag(Qt::AlignBottom)) + result.ry() -= rect.height(); + return result; +} + +/*! \internal + + Returns the font that should be used for drawing text. Returns mFont when the item is not selected + and mSelectedFont when it is. +*/ +QFont QCPItemText::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the color that should be used for drawing text. Returns mColor when the item is not + selected and mSelectedColor when it is. +*/ +QColor QCPItemText::mainColor() const +{ + return mSelected ? mSelectedColor : mColor; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemText::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemText::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-text.cpp' */ + + +/* including file 'src/items/item-ellipse.cpp', size 7863 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemEllipse +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemEllipse + \brief An ellipse + + \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. +*/ + +/*! + Creates an ellipse item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + topLeftRim(createAnchor(QLatin1String("topLeftRim"), aiTopLeftRim)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRightRim(createAnchor(QLatin1String("topRightRim"), aiTopRightRim)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRightRim(createAnchor(QLatin1String("bottomRightRim"), aiBottomRightRim)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeftRim(createAnchor(QLatin1String("bottomLeftRim"), aiBottomLeftRim)), + left(createAnchor(QLatin1String("left"), aiLeft)), + center(createAnchor(QLatin1String("center"), aiCenter)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemEllipse::~QCPItemEllipse() +{ +} + +/*! + Sets the pen that will be used to draw the line of the ellipse + + \see setSelectedPen, setBrush +*/ +void QCPItemEllipse::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the ellipse when selected + + \see setPen, setSelected +*/ +void QCPItemEllipse::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemEllipse::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemEllipse::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + QPointF center((p1+p2)/2.0); + double a = qAbs(p1.x()-p2.x())/2.0; + double b = qAbs(p1.y()-p2.y())/2.0; + double x = pos.x()-center.x(); + double y = pos.y()-center.y(); + + // distance to border: + double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); + double result = qAbs(c-1)*qSqrt(x*x+y*y); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (x*x/(a*a) + y*y/(b*b) <= 1) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/* inherits documentation from base class */ +void QCPItemEllipse::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF ellipseRect = QRectF(p1, p2).normalized(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); +#ifdef __EXCEPTIONS + try // drawEllipse sometimes throws exceptions if ellipse is too big + { +#endif + painter->drawEllipse(ellipseRect); +#ifdef __EXCEPTIONS + } catch (...) + { + qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; + setVisible(false); + } +#endif + } +} + +/* inherits documentation from base class */ +QPointF QCPItemEllipse::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemEllipse::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemEllipse::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-ellipse.cpp' */ + + +/* including file 'src/items/item-pixmap.cpp', size 10615 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPixmap + \brief An arbitrary pixmap + + \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will + be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to + fit the rectangle or be drawn aligned to the topLeft position. + + If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown + on the right side of the example image), the pixmap will be flipped in the respective + orientations. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mScaled(false), + mScaledPixmapInvalidated(true), + mAspectRatioMode(Qt::KeepAspectRatio), + mTransformationMode(Qt::SmoothTransformation) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(Qt::NoPen); + setSelectedPen(QPen(Qt::blue)); +} + +QCPItemPixmap::~QCPItemPixmap() +{ +} + +/*! + Sets the pixmap that will be displayed. +*/ +void QCPItemPixmap::setPixmap(const QPixmap &pixmap) +{ + mPixmap = pixmap; + mScaledPixmapInvalidated = true; + if (mPixmap.isNull()) + qDebug() << Q_FUNC_INFO << "pixmap is null"; +} + +/*! + Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a + bottomRight positions. +*/ +void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode) +{ + mScaled = scaled; + mAspectRatioMode = aspectRatioMode; + mTransformationMode = transformationMode; + mScaledPixmapInvalidated = true; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap. + + \see setSelectedPen, setBrush +*/ +void QCPItemPixmap::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap when selected + + \see setPen, setSelected +*/ +void QCPItemPixmap::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return rectDistance(getFinalRect(), pos, true); +} + +/* inherits documentation from base class */ +void QCPItemPixmap::draw(QCPPainter *painter) +{ + bool flipHorz = false; + bool flipVert = false; + QRect rect = getFinalRect(&flipHorz, &flipVert); + double clipPad = mainPen().style() == Qt::NoPen ? 0 : mainPen().widthF(); + QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) + { + updateScaledPixmap(rect, flipHorz, flipVert); + painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); + QPen pen = mainPen(); + if (pen.style() != Qt::NoPen) + { + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawRect(rect); + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const +{ + bool flipHorz; + bool flipVert; + QRect rect = getFinalRect(&flipHorz, &flipVert); + // we actually want denormal rects (negative width/height) here, so restore + // the flipped state: + if (flipHorz) + rect.adjust(rect.width(), 0, -rect.width(), 0); + if (flipVert) + rect.adjust(0, rect.height(), 0, -rect.height()); + + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The + parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped + horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a + bottomRight.) + + This function only creates the scaled pixmap when the buffered pixmap has a different size than + the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does + not cause expensive rescaling every time. + + If scaling is disabled, sets mScaledPixmap to a null QPixmap. +*/ +void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) +{ + if (mPixmap.isNull()) + return; + + if (mScaled) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + double devicePixelRatio = mPixmap.devicePixelRatio(); +#else + double devicePixelRatio = 1.0; +#endif + if (finalRect.isNull()) + finalRect = getFinalRect(&flipHorz, &flipVert); + if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()/devicePixelRatio) + { + mScaledPixmap = mPixmap.scaled(finalRect.size()*devicePixelRatio, mAspectRatioMode, mTransformationMode); + if (flipHorz || flipVert) + mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mScaledPixmap.setDevicePixelRatio(devicePixelRatio); +#endif + } + } else if (!mScaledPixmap.isNull()) + mScaledPixmap = QPixmap(); + mScaledPixmapInvalidated = false; +} + +/*! \internal + + Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions + and scaling settings. + + The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn + flipped horizontally or vertically in the returned rect. (The returned rect itself is always + normalized, i.e. the top left corner of the rect is actually further to the top/left than the + bottom right corner). This is the case when the item position \a topLeft is further to the + bottom/right than \a bottomRight. + + If scaling is disabled, returns a rect with size of the original pixmap and the top left corner + aligned with the item position \a topLeft. The position \a bottomRight is ignored. +*/ +QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const +{ + QRect result; + bool flipHorz = false; + bool flipVert = false; + QPoint p1 = topLeft->pixelPosition().toPoint(); + QPoint p2 = bottomRight->pixelPosition().toPoint(); + if (p1 == p2) + return QRect(p1, QSize(0, 0)); + if (mScaled) + { + QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); + QPoint topLeft = p1; + if (newSize.width() < 0) + { + flipHorz = true; + newSize.rwidth() *= -1; + topLeft.setX(p2.x()); + } + if (newSize.height() < 0) + { + flipVert = true; + newSize.rheight() *= -1; + topLeft.setY(p2.y()); + } + QSize scaledSize = mPixmap.size(); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + scaledSize /= mPixmap.devicePixelRatio(); + scaledSize.scale(newSize*mPixmap.devicePixelRatio(), mAspectRatioMode); +#else + scaledSize.scale(newSize, mAspectRatioMode); +#endif + result = QRect(topLeft, scaledSize); + } else + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + result = QRect(p1, mPixmap.size()/mPixmap.devicePixelRatio()); +#else + result = QRect(p1, mPixmap.size()); +#endif + } + if (flippedHorz) + *flippedHorz = flipHorz; + if (flippedVert) + *flippedVert = flipVert; + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemPixmap::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-pixmap.cpp' */ + + +/* including file 'src/items/item-tracer.cpp', size 14624 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemTracer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemTracer + \brief Item that sticks to QCPGraph data points + + \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." + + The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt + the coordinate axes of the graph and update its \a position to be on the graph's data. This means + the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a + QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a + position will have no effect because they will be overriden in the next redraw (this is when the + coordinate update happens). + + If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will + stay at the corresponding end of the graph. + + With \ref setInterpolating you may specify whether the tracer may only stay exactly on data + points or whether it interpolates data points linearly, if given a key that lies between two data + points of the graph. + + The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer + have no own visual appearance (set the style to \ref tsNone), and just connect other item + positions to the tracer \a position (used as an anchor) via \ref + QCPItemPosition::setParentAnchor. + + \note The tracer position is only automatically updated upon redraws. So when the data of the + graph changes and immediately afterwards (without a redraw) the position coordinates of the + tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref + updatePosition must be called manually, prior to reading the tracer coordinates. +*/ + +/*! + Creates a tracer item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mSize(6), + mStyle(tsCrosshair), + mGraph(0), + mGraphKey(0), + mInterpolating(false), + mType(-1) +{ + position->setCoords(0, 0); + + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush) + : QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mPen(pen), + mBrush(brush), + mSize(5), + mStyle(tsCircle), + mGraph(0), + mGraphKey(0), + mInterpolating(true), + mType(type), + mTimeStamp(timeStamp) +{ + position->setCoords(0, 0); + setSelectedBrush(Qt::NoBrush); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemTracer::~QCPItemTracer() +{ +} + +/*! + Sets the pen that will be used to draw the line of the tracer + + \see setSelectedPen, setBrush +*/ +void QCPItemTracer::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the tracer when selected + + \see setPen, setSelected +*/ +void QCPItemTracer::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer + + \see setSelectedBrush, setPen +*/ +void QCPItemTracer::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer, when selected. + + \see setBrush, setSelected +*/ +void QCPItemTracer::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare + does, \ref tsCrosshair does not). +*/ +void QCPItemTracer::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the style/visual appearance of the tracer. + + If you only want to use the tracer \a position as an anchor for other items, set \a style to + \ref tsNone. +*/ +void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) +{ + mStyle = style; +} + +/*! + Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type + QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. + + To free the tracer from any graph, set \a graph to 0. The tracer \a position can then be placed + freely like any other item position. This is the state the tracer will assume when its graph gets + deleted while still attached to it. + + \see setGraphKey +*/ +void QCPItemTracer::setGraph(QCPGraph *graph) +{ + if (graph) + { + if (graph->parentPlot() == mParentPlot) + { + position->setType(QCPItemPosition::ptPlotCoords); + position->setAxes(graph->keyAxis(), graph->valueAxis()); + mGraph = graph; + updatePosition(); + } else + qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; + } else + { + mGraph = 0; + } +} + +/*! + Sets the key of the graph's data point the tracer will be positioned at. This is the only free + coordinate of a tracer when attached to a graph. + + Depending on \ref setInterpolating, the tracer will be either positioned on the data point + closest to \a key, or will stay exactly at \a key and interpolate the value linearly. + + \see setGraph, setInterpolating +*/ +void QCPItemTracer::setGraphKey(double key) +{ + mGraphKey = key; +} + +void QCPItemTracer::setHidePoint(const QMap &hidePoint) +{ + m_hidePoint = hidePoint; +} + +void QCPItemTracer::addHidePoint(const qint64 &time, const QString &tag) +{ + m_hidePoint.insert(time, tag); +} + +/*! + Sets whether the value of the graph's data points shall be interpolated, when positioning the + tracer. + + If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on + the data point of the graph which is closest to the key, but which is not necessarily exactly + there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and + the appropriate value will be interpolated from the graph's data points linearly. + + \see setGraph, setGraphKey +*/ +void QCPItemTracer::setInterpolating(bool enabled) +{ + mInterpolating = enabled; +} + +void QCPItemTracer::setType(const int &type) +{ + mType = type; +} + +void QCPItemTracer::setTimeStamp(const qint64 &timeStamp) +{ + mTimeStamp = timeStamp; +} + +void QCPItemTracer::setInfo(const QStringList infos) +{ + m_infos = infos; +} + +void QCPItemTracer::showTips() +{ + QString tips; + QString strTime = QDateTime::fromMSecsSinceEpoch(position->key()).toString("yyyy-MM-dd hh:mm:ss zzz"); + tips += QString("%1: %2\n\n%3:\n\t").arg(tr("时间")).arg(strTime).arg(tr("事件信息")); + tips += m_infos.join("\t\n\t"); + tips += QString("\n"); + CToolTip::popup(mParentPlot->mapToGlobal(position->pixelPosition().toPoint()), tips, this->parentPlot()); +} + +/* inherits documentation from base class */ +double QCPItemTracer::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return -1; + case tsPlus: + { + if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(center+QPointF(-w, 0), center+QPointF(w, 0)), + QCPVector2D(pos).distanceSquaredToLine(center+QPointF(0, -w), center+QPointF(0, w)))); + break; + } + case tsCrosshair: + { + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(clip.left(), center.y()), QCPVector2D(clip.right(), center.y())), + QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(center.x(), clip.top()), QCPVector2D(center.x(), clip.bottom())))); + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + // distance to border: + double centerDist = QCPVector2D(center-pos).length(); + double circleLine = w; + double result = qAbs(centerDist-circleLine); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (centerDist <= circleLine) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; + } + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); + } + break; + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemTracer::draw(QCPPainter *painter) +{ + updatePosition(); + if (mStyle == tsNone) + return; + + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return; + case tsPlus: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); + painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); + } + break; + } + case tsCrosshair: + { + if (center.y() > clip.top() && center.y() < clip.bottom()) + painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); + if (center.x() > clip.left() && center.x() < clip.right()) + painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); + break; + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawEllipse(center, w, w); + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); + break; + } + } +} + +void QCPItemTracer::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + QCPAbstractItem::mousePressEvent(event, details); +} + +void QCPItemTracer::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + QCPAbstractItem::mouseMoveEvent(event, startPos); + + if(QPoint(event->pos() - position->pixelPosition().toPoint()).manhattanLength() > 8) + { + return; + } + emit itemTracerHoverd(mGraph->name(), mTimeStamp, m_hidePoint); +} + +/*! + If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a + position to reside on the graph data, depending on the configured key (\ref setGraphKey). + + It is called automatically on every redraw and normally doesn't need to be called manually. One + exception is when you want to read the tracer coordinates via \a position and are not sure that + the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. + In that situation, call this function before accessing \a position, to make sure you don't get + out-of-date coordinates. + + If there is no graph set on this tracer, this function does nothing. +*/ +void QCPItemTracer::updatePosition() +{ + if (mGraph) + { + if (mParentPlot->hasPlottable(mGraph)) + { + if (mGraph->data()->size() > 1) + { + QCPGraphDataContainer::const_iterator first = mGraph->data()->constBegin(); + QCPGraphDataContainer::const_iterator last = mGraph->data()->constEnd()-1; + if (mGraphKey <= first->key) + position->setCoords(first->key, first->value); + else if (mGraphKey >= last->key) + position->setCoords(last->key, last->value); + else + { + if(QCPGraph::lsStepLeft == mGraph->lineStyle()) + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->findEnd(mGraphKey, false); + if(it != mGraph->data()->constBegin()) + { + --it; + } + if (mInterpolating) + { + position->setCoords(mGraphKey, it->value); + } + else + { + position->setCoords(it->key, it->value); + } + } + else + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->findBegin(mGraphKey); + if (it != mGraph->data()->constEnd()) // mGraphKey is not exactly on last iterator, but somewhere between iterators + { + QCPGraphDataContainer::const_iterator prevIt = it; + ++it; // won't advance to constEnd because we handled that case (mGraphKey >= last->key) before + if (mInterpolating) + { + // interpolate between iterators around mGraphKey: + double slope = 0; + if (!qFuzzyCompare((double)it->key, (double)prevIt->key)) + slope = (it->value-prevIt->value)/(it->key-prevIt->key); + position->setCoords(mGraphKey, (mGraphKey-prevIt->key)*slope+prevIt->value); + } else + { + // find iterator with key closest to mGraphKey: + if (mGraphKey < (prevIt->key+it->key)*0.5) + position->setCoords(prevIt->key, prevIt->value); + else + position->setCoords(it->key, it->value); + } + } else // mGraphKey is exactly on last iterator (should actually be caught when comparing first/last keys, but this is a failsafe for fp uncertainty) + position->setCoords(it->key, it->value); + } + } + } else if (mGraph->data()->size() == 1) + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->constBegin(); + position->setCoords(it->key, it->value); + } else + qDebug() << Q_FUNC_INFO << "graph has no data"; + } else + qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemTracer::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemTracer::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-tracer.cpp' */ + + +/* including file 'src/items/item-bracket.cpp', size 10687 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemBracket + \brief A bracket for referencing/highlighting certain parts in the plot. + + \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a left and \a right, which define the span of the bracket. If \a left is + actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the + example image. + + The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket + stretches away from the embraced span, can be controlled with \ref setLength. + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+ + It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine + or QCPItemCurve) or a text label (QCPItemText), to the bracket. +*/ + +/*! + Creates a bracket item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + left(createPosition(QLatin1String("left"))), + right(createPosition(QLatin1String("right"))), + center(createAnchor(QLatin1String("center"), aiCenter)), + mLength(8), + mStyle(bsCalligraphic) +{ + left->setCoords(0, 0); + right->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemBracket::~QCPItemBracket() +{ +} + +/*! + Sets the pen that will be used to draw the bracket. + + Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the + stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use + \ref setLength, which has a similar effect. + + \see setSelectedPen +*/ +void QCPItemBracket::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the bracket when selected + + \see setPen, setSelected +*/ +void QCPItemBracket::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the \a length in pixels how far the bracket extends in the direction towards the embraced + span of the bracket (i.e. perpendicular to the left-right-direction) + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+*/ +void QCPItemBracket::setLength(double length) +{ + mLength = length; +} + +/*! + Sets the style of the bracket, i.e. the shape/visual appearance. + + \see setPen +*/ +void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) +{ + mStyle = style; +} + +/* inherits documentation from base class */ +double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QCPVector2D p(pos); + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return -1; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (mStyle) + { + case QCPItemBracket::bsSquare: + case QCPItemBracket::bsRound: + { + double a = p.distanceSquaredToLine(centerVec-widthVec, centerVec+widthVec); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec, centerVec-widthVec); + double c = p.distanceSquaredToLine(centerVec+widthVec+lengthVec, centerVec+widthVec); + return qSqrt(qMin(qMin(a, b), c)); + } + case QCPItemBracket::bsCurly: + case QCPItemBracket::bsCalligraphic: + { + double a = p.distanceSquaredToLine(centerVec-widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec*0.7, centerVec-widthVec*0.75+lengthVec*0.15); + double c = p.distanceSquaredToLine(centerVec+widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double d = p.distanceSquaredToLine(centerVec+widthVec+lengthVec*0.7, centerVec+widthVec*0.75+lengthVec*0.15); + return qSqrt(qMin(qMin(a, b), qMin(c, d))); + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemBracket::draw(QCPPainter *painter) +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + QPolygon boundingPoly; + boundingPoly << leftVec.toPoint() << rightVec.toPoint() + << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (clip.intersects(boundingPoly.boundingRect())) + { + painter->setPen(mainPen()); + switch (mStyle) + { + case bsSquare: + { + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + break; + } + case bsRound: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCurly: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCalligraphic: + { + painter->setPen(Qt::NoPen); + painter->setBrush(QBrush(mainPen().color())); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec-widthVec-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); + path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + + painter->drawPath(path); + break; + } + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemBracket::anchorPixelPosition(int anchorId) const +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return leftVec.toPointF(); + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (anchorId) + { + case aiCenter: + return centerVec.toPointF(); + } + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemBracket::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-bracket.cpp' */ diff --git a/product/src/gui/plugin/ISCSTrendCurves/plot/qcustomplot.h b/product/src/gui/plugin/ISCSTrendCurves/plot/qcustomplot.h index 42356d41..81a546a6 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/plot/qcustomplot.h +++ b/product/src/gui/plugin/ISCSTrendCurves/plot/qcustomplot.h @@ -1,6717 +1,6717 @@ -/*************************************************************************** -** ** -** QCustomPlot, an easy to use, modern plotting widget for Qt ** -** Copyright (C) 2011-2017 Emanuel Eichhammer ** -** ** -** This program is free software: you can redistribute it and/or modify ** -** it under the terms of the GNU General Public License as published by ** -** the Free Software Foundation, either version 3 of the License, or ** -** (at your option) any later version. ** -** ** -** This program is distributed in the hope that it will be useful, ** -** but WITHOUT ANY WARRANTY; without even the implied warranty of ** -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** -** GNU General Public License for more details. ** -** ** -** You should have received a copy of the GNU General Public License ** -** along with this program. If not, see http://www.gnu.org/licenses/. ** -** ** -**************************************************************************** -** Author: Emanuel Eichhammer ** -** Website/Contact: http://www.qcustomplot.com/ ** -** Date: 04.09.17 ** -** Version: 2.0.0 ** -****************************************************************************/ - -#ifndef QCUSTOMPLOT_H -#define QCUSTOMPLOT_H - -#include - -// some Qt version/configuration dependent macros to include or exclude certain code paths: -#ifdef QCUSTOMPLOT_USE_OPENGL -# if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -# define QCP_OPENGL_PBUFFER -# else -# define QCP_OPENGL_FBO -# endif -# if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) -# define QCP_OPENGL_OFFSCREENSURFACE -# endif -#endif - -#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) -# define QCP_DEVICEPIXELRATIO_SUPPORTED -# if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) -# define QCP_DEVICEPIXELRATIO_FLOAT -# endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef QCP_OPENGL_FBO -# include -# include -# ifdef QCP_OPENGL_OFFSCREENSURFACE -# include -# else -# include -# endif -#endif -#ifdef QCP_OPENGL_PBUFFER -# include -#endif -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -# include -# include -# include -# include -#else -# include -# include -# include -#endif - -class QCPPainter; -class QCustomPlot; -class QCPLayerable; -class QCPLayoutElement; -class QCPLayout; -class QCPAxis; -class QCPAxisRect; -class QCPAxisPainterPrivate; -class QCPAbstractPlottable; -class QCPGraph; -class QCPAbstractItem; -class QCPPlottableInterface1D; -class QCPLegend; -class QCPItemPosition; -class QCPLayer; -class QCPAbstractLegendItem; -class QCPSelectionRect; -class QCPColorMap; -class QCPColorScale; -class QCPBars; - -/* including file 'src/global.h', size 16225 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -// decl definitions for shared library compilation/usage: -#if defined(QCUSTOMPLOT_COMPILE_LIBRARY) -# define QCP_LIB_DECL Q_DECL_EXPORT -#elif defined(QCUSTOMPLOT_USE_LIBRARY) -# define QCP_LIB_DECL Q_DECL_IMPORT -#else -# define QCP_LIB_DECL -#endif - -// define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5) -#ifndef Q_DECL_OVERRIDE -# define Q_DECL_OVERRIDE -#endif - -/*! - The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot - library. - - It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. -*/ -#ifndef Q_MOC_RUN -namespace QCP { -#else -class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace - Q_GADGET - Q_ENUMS(ExportPen) - Q_ENUMS(ResolutionUnit) - Q_ENUMS(SignDomain) - Q_ENUMS(MarginSide) - Q_FLAGS(MarginSides) - Q_ENUMS(AntialiasedElement) - Q_FLAGS(AntialiasedElements) - Q_ENUMS(PlottingHint) - Q_FLAGS(PlottingHints) - Q_ENUMS(Interaction) - Q_FLAGS(Interactions) - Q_ENUMS(SelectionRectMode) - Q_ENUMS(SelectionType) -public: -#endif - -/*! - Defines the different units in which the image resolution can be specified in the export - functions. - - \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered -*/ -enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) - ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) - ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) - }; - -/*! - Defines how cosmetic pens (pens with numerical width 0) are handled during export. - - \see QCustomPlot::savePdf -*/ -enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting - ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level) - }; - -/*! - Represents negative and positive sign domain, e.g. for passing to \ref - QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. - - This is primarily needed when working with logarithmic axis scales, since only one of the sign - domains can be visible at a time. -*/ -enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero - ,sdBoth ///< Both sign domains, including zero, i.e. all numbers - ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero - }; - -/*! - Defines the sides of a rectangular entity to which margins can be applied. - - \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins -*/ -enum MarginSide { msLeft = 0x01 ///< 0x01 left margin - ,msRight = 0x02 ///< 0x02 right margin - ,msTop = 0x04 ///< 0x04 top margin - ,msBottom = 0x08 ///< 0x08 bottom margin - ,msAll = 0xFF ///< 0xFF all margins - ,msNone = 0x00 ///< 0x00 no margin - }; -Q_DECLARE_FLAGS(MarginSides, MarginSide) - -/*! - Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is - neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective - element how it is drawn. Typically it provides a \a setAntialiased function for this. - - \c AntialiasedElements is a flag of or-combined elements of this enum type. - - \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements -*/ -enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks - ,aeGrid = 0x0002 ///< 0x0002 Grid lines - ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines - ,aeLegend = 0x0008 ///< 0x0008 Legend box - ,aeLegendItems = 0x0010 ///< 0x0010 Legend items - ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables - ,aeItems = 0x0040 ///< 0x0040 Main lines of items - ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) - ,aeFills = 0x0100 ///< 0x0100 Borders of fills (e.g. under or between graphs) - ,aeZeroLine = 0x0200 ///< 0x0200 Zero-lines, see \ref QCPGrid::setZeroLinePen - ,aeOther = 0x8000 ///< 0x8000 Other elements that don't fit into any of the existing categories - ,aeAll = 0xFFFF ///< 0xFFFF All elements - ,aeNone = 0x0000 ///< 0x0000 No elements - }; -Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) - -/*! - Defines plotting hints that control various aspects of the quality and speed of plotting. - - \see QCustomPlot::setPlottingHints -*/ -enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set - ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment - ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens. - ,phImmediateRefresh = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint. - ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). - ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. - }; -Q_DECLARE_FLAGS(PlottingHints, PlottingHint) - -/*! - Defines the mouse interactions possible with QCustomPlot. - - \c Interactions is a flag of or-combined elements of this enum type. - - \see QCustomPlot::setInteractions -*/ -enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) - ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) - ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking - ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) - ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) - ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) - ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) - ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, other layout elements,...) - }; -Q_DECLARE_FLAGS(Interactions, Interaction) - -/*! - Defines the behaviour of the selection rect. - - \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect -*/ -enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging - ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly. - ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.) - ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction. - }; - -/*! - Defines the different ways a plottable can be selected. These images show the effect of the - different selection types, when the indicated selection rect was dragged: - -
- - - - - - - - -
\image html selectiontype-none.png stNone\image html selectiontype-whole.png stWhole\image html selectiontype-singledata.png stSingleData\image html selectiontype-datarange.png stDataRange\image html selectiontype-multipledataranges.png stMultipleDataRanges
-
- - \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType -*/ -enum SelectionType { stNone ///< The plottable is not selectable - ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected. - ,stSingleData ///< One individual data point can be selected at a time - ,stDataRange ///< Multiple contiguous data points (a data range) can be selected - ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected - }; - -/*! \internal - - Returns whether the specified \a value is considered an invalid data value for plottables (i.e. - is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the - compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. -*/ -inline bool isInvalidData(double value) -{ - return qIsNaN(value) || qIsInf(value); -} - -/*! \internal - \overload - - Checks two arguments instead of one. -*/ -inline bool isInvalidData(double value1, double value2) -{ - return isInvalidData(value1) || isInvalidData(value2); -} - -/*! \internal - - Sets the specified \a side of \a margins to \a value - - \see getMarginValue -*/ -inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) -{ - switch (side) - { - case QCP::msLeft: margins.setLeft(value); break; - case QCP::msRight: margins.setRight(value); break; - case QCP::msTop: margins.setTop(value); break; - case QCP::msBottom: margins.setBottom(value); break; - case QCP::msAll: margins = QMargins(value, value, value, value); break; - default: break; - } -} - -/*! \internal - - Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or - \ref QCP::msAll, returns 0. - - \see setMarginValue -*/ -inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) -{ - switch (side) - { - case QCP::msLeft: return margins.left(); - case QCP::msRight: return margins.right(); - case QCP::msTop: return margins.top(); - case QCP::msBottom: return margins.bottom(); - default: break; - } - return 0; -} - - -extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace - -} // end of namespace QCP -Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) -Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) -Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) -Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) -Q_DECLARE_METATYPE(QCP::ExportPen) -Q_DECLARE_METATYPE(QCP::ResolutionUnit) -Q_DECLARE_METATYPE(QCP::SignDomain) -Q_DECLARE_METATYPE(QCP::MarginSide) -Q_DECLARE_METATYPE(QCP::AntialiasedElement) -Q_DECLARE_METATYPE(QCP::PlottingHint) -Q_DECLARE_METATYPE(QCP::Interaction) -Q_DECLARE_METATYPE(QCP::SelectionRectMode) -Q_DECLARE_METATYPE(QCP::SelectionType) - -/* end of 'src/global.h' */ - - -/* including file 'src/vector2d.h', size 4928 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPVector2D -{ -public: - QCPVector2D(); - QCPVector2D(double x, double y); - QCPVector2D(const QPoint &point); - QCPVector2D(const QPointF &point); - - // getters: - double x() const { return mX; } - double y() const { return mY; } - double &rx() { return mX; } - double &ry() { return mY; } - - // setters: - void setX(double x) { mX = x; } - void setY(double y) { mY = y; } - - // non-virtual methods: - double length() const { return qSqrt(mX*mX+mY*mY); } - double lengthSquared() const { return mX*mX+mY*mY; } - QPoint toPoint() const { return QPoint(mX, mY); } - QPointF toPointF() const { return QPointF(mX, mY); } - - bool isNull() const { return qIsNull(mX) && qIsNull(mY); } - void normalize(); - QCPVector2D normalized() const; - QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); } - double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; } - double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; - double distanceSquaredToLine(const QLineF &line) const; - double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; - - QCPVector2D &operator*=(double factor); - QCPVector2D &operator/=(double divisor); - QCPVector2D &operator+=(const QCPVector2D &vector); - QCPVector2D &operator-=(const QCPVector2D &vector); - -private: - // property members: - double mX, mY; - - friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); - friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); - friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); - friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2); - friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2); - friend inline const QCPVector2D operator-(const QCPVector2D &vec); -}; -Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE); - -inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } -inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } -inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); } -inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); } -inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); } -inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); } - -/*! \relates QCPVector2D - - Prints \a vec in a human readable format to the qDebug output. -*/ -inline QDebug operator<< (QDebug d, const QCPVector2D &vec) -{ - d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")"; - return d.space(); -} - -/* end of 'src/vector2d.h' */ - - -/* including file 'src/painter.h', size 4035 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPPainter : public QPainter -{ - Q_GADGET -public: - /*! - Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, - depending on whether they are wanted on the respective output device. - */ - enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices - ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. - ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels - ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) - }; - Q_ENUMS(PainterMode) - Q_FLAGS(PainterModes) - Q_DECLARE_FLAGS(PainterModes, PainterMode) - - QCPPainter(); - explicit QCPPainter(QPaintDevice *device); - - // getters: - bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } - PainterModes modes() const { return mModes; } - - // setters: - void setAntialiasing(bool enabled); - void setMode(PainterMode mode, bool enabled=true); - void setModes(PainterModes modes); - - // methods hiding non-virtual base class functions (QPainter bug workarounds): - bool begin(QPaintDevice *device); - void setPen(const QPen &pen); - void setPen(const QColor &color); - void setPen(Qt::PenStyle penStyle); - void drawLine(const QLineF &line); - void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} - void save(); - void restore(); - - // non-virtual methods: - void makeNonCosmetic(); - -protected: - // property members: - PainterModes mModes; - bool mIsAntialiasing; - - // non-property members: - QStack mAntialiasingStack; -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) -Q_DECLARE_METATYPE(QCPPainter::PainterMode) - -/* end of 'src/painter.h' */ - - -/* including file 'src/paintbuffer.h', size 4958 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAbstractPaintBuffer -{ -public: - explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); - virtual ~QCPAbstractPaintBuffer(); - - // getters: - QSize size() const { return mSize; } - bool invalidated() const { return mInvalidated; } - double devicePixelRatio() const { return mDevicePixelRatio; } - - // setters: - void setSize(const QSize &size); - void setInvalidated(bool invalidated=true); - void setDevicePixelRatio(double ratio); - - // introduced virtual methods: - virtual QCPPainter *startPainting() = 0; - virtual void donePainting() {} - virtual void draw(QCPPainter *painter) const = 0; - virtual void clear(const QColor &color) = 0; - -protected: - // property members: - QSize mSize; - double mDevicePixelRatio; - - // non-property members: - bool mInvalidated; - - // introduced virtual methods: - virtual void reallocateBuffer() = 0; -}; - - -class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer -{ -public: - explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); - virtual ~QCPPaintBufferPixmap(); - - // reimplemented virtual methods: - virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; - void clear(const QColor &color) Q_DECL_OVERRIDE; - -protected: - // non-property members: - QPixmap mBuffer; - - // reimplemented virtual methods: - virtual void reallocateBuffer() Q_DECL_OVERRIDE; -}; - - -#ifdef QCP_OPENGL_PBUFFER -class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer -{ -public: - explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); - virtual ~QCPPaintBufferGlPbuffer(); - - // reimplemented virtual methods: - virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; - void clear(const QColor &color) Q_DECL_OVERRIDE; - -protected: - // non-property members: - QGLPixelBuffer *mGlPBuffer; - int mMultisamples; - - // reimplemented virtual methods: - virtual void reallocateBuffer() Q_DECL_OVERRIDE; -}; -#endif // QCP_OPENGL_PBUFFER - - -#ifdef QCP_OPENGL_FBO -class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer -{ -public: - explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice); - virtual ~QCPPaintBufferGlFbo(); - - // reimplemented virtual methods: - virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; - virtual void donePainting() Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; - void clear(const QColor &color) Q_DECL_OVERRIDE; - -protected: - // non-property members: - QWeakPointer mGlContext; - QWeakPointer mGlPaintDevice; - QOpenGLFramebufferObject *mGlFrameBuffer; - - // reimplemented virtual methods: - virtual void reallocateBuffer() Q_DECL_OVERRIDE; -}; -#endif // QCP_OPENGL_FBO - -/* end of 'src/paintbuffer.h' */ - - -/* including file 'src/layer.h', size 6885 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPLayer : public QObject -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) - Q_PROPERTY(QString name READ name) - Q_PROPERTY(int index READ index) - Q_PROPERTY(QList children READ children) - Q_PROPERTY(bool visible READ visible WRITE setVisible) - Q_PROPERTY(LayerMode mode READ mode WRITE setMode) - /// \endcond -public: - - /*! - Defines the different rendering modes of a layer. Depending on the mode, certain layers can be - replotted individually, without the need to replot (possibly complex) layerables on other - layers. - - \see setMode - */ - enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. - ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). - }; - Q_ENUMS(LayerMode) - - QCPLayer(QCustomPlot* parentPlot, const QString &layerName); - virtual ~QCPLayer(); - - // getters: - QCustomPlot *parentPlot() const { return mParentPlot; } - QString name() const { return mName; } - int index() const { return mIndex; } - QList children() const { return mChildren; } - bool visible() const { return mVisible; } - LayerMode mode() const { return mMode; } - - // setters: - void setVisible(bool visible); - void setMode(LayerMode mode); - - // non-virtual methods: - void replot(); - -protected: - // property members: - QCustomPlot *mParentPlot; - QString mName; - int mIndex; - QList mChildren; - bool mVisible; - LayerMode mMode; - - // non-property members: - QWeakPointer mPaintBuffer; - - // non-virtual methods: - void draw(QCPPainter *painter); - void drawToPaintBuffer(); - void addChild(QCPLayerable *layerable, bool prepend); - void removeChild(QCPLayerable *layerable); - -private: - Q_DISABLE_COPY(QCPLayer) - - friend class QCustomPlot; - friend class QCPLayerable; -}; -Q_DECLARE_METATYPE(QCPLayer::LayerMode) - -class QCP_LIB_DECL QCPLayerable : public QObject -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(bool visible READ visible WRITE setVisible) - Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) - Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) - Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) - Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) - /// \endcond -public: - QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); - virtual ~QCPLayerable(); - - // getters: - bool visible() const { return mVisible; } - QCustomPlot *parentPlot() const { return mParentPlot; } - QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } - QCPLayer *layer() const { return mLayer; } - bool antialiased() const { return mAntialiased; } - - // setters: - void setVisible(bool on); - Q_SLOT bool setLayer(QCPLayer *layer); - bool setLayer(const QString &layerName); - void setAntialiased(bool enabled); - - // introduced virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; - - // non-property methods: - bool realVisibility() const; - -signals: - void layerChanged(QCPLayer *newLayer); - -protected: - // property members: - bool mVisible; - QCustomPlot *mParentPlot; - QPointer mParentLayerable; - QCPLayer *mLayer; - bool mAntialiased; - - // introduced virtual methods: - virtual void parentPlotInitialized(QCustomPlot *parentPlot); - virtual QCP::Interaction selectionCategory() const; - virtual QRect clipRect() const; - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; - virtual void draw(QCPPainter *painter) = 0; - // selection events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); - virtual void deselectEvent(bool *selectionStateChanged); - // low-level mouse events: - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); - virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); - virtual void wheelEvent(QWheelEvent *event); - - // non-property methods: - void initializeParentPlot(QCustomPlot *parentPlot); - void setParentLayerable(QCPLayerable* parentLayerable); - bool moveToLayer(QCPLayer *layer, bool prepend); - void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; - -private: - Q_DISABLE_COPY(QCPLayerable) - - friend class QCustomPlot; - friend class QCPLayer; - friend class QCPAxisRect; -}; - -/* end of 'src/layer.h' */ - - -/* including file 'src/axis/range.h', size 5280 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPRange -{ -public: - double lower, upper; - - QCPRange(); - QCPRange(double lower, double upper); - - bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } - bool operator!=(const QCPRange& other) const { return !(*this == other); } - - QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } - QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } - QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } - QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } - friend inline const QCPRange operator+(const QCPRange&, double); - friend inline const QCPRange operator+(double, const QCPRange&); - friend inline const QCPRange operator-(const QCPRange& range, double value); - friend inline const QCPRange operator*(const QCPRange& range, double value); - friend inline const QCPRange operator*(double value, const QCPRange& range); - friend inline const QCPRange operator/(const QCPRange& range, double value); - - double size() const { return upper-lower; } - double center() const { return (upper+lower)*0.5; } - void normalize() { if (lower > upper) qSwap(lower, upper); } - void expand(const QCPRange &otherRange); - void expand(double includeCoord); - QCPRange expanded(const QCPRange &otherRange) const; - QCPRange expanded(double includeCoord) const; - QCPRange bounded(double lowerBound, double upperBound) const; - QCPRange sanitizedForLogScale() const; - QCPRange sanitizedForLinScale() const; - bool contains(double value) const { return value >= lower && value <= upper; } - - static bool validRange(double lower, double upper); - static bool validRange(const QCPRange &range); - static const double minRange; - static const double maxRange; - -}; -Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); - -/*! \relates QCPRange - - Prints \a range in a human readable format to the qDebug output. -*/ -inline QDebug operator<< (QDebug d, const QCPRange &range) -{ - d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")"; - return d.space(); -} - -/*! - Adds \a value to both boundaries of the range. -*/ -inline const QCPRange operator+(const QCPRange& range, double value) -{ - QCPRange result(range); - result += value; - return result; -} - -/*! - Adds \a value to both boundaries of the range. -*/ -inline const QCPRange operator+(double value, const QCPRange& range) -{ - QCPRange result(range); - result += value; - return result; -} - -/*! - Subtracts \a value from both boundaries of the range. -*/ -inline const QCPRange operator-(const QCPRange& range, double value) -{ - QCPRange result(range); - result -= value; - return result; -} - -/*! - Multiplies both boundaries of the range by \a value. -*/ -inline const QCPRange operator*(const QCPRange& range, double value) -{ - QCPRange result(range); - result *= value; - return result; -} - -/*! - Multiplies both boundaries of the range by \a value. -*/ -inline const QCPRange operator*(double value, const QCPRange& range) -{ - QCPRange result(range); - result *= value; - return result; -} - -/*! - Divides both boundaries of the range by \a value. -*/ -inline const QCPRange operator/(const QCPRange& range, double value) -{ - QCPRange result(range); - result /= value; - return result; -} - -/* end of 'src/axis/range.h' */ - - -/* including file 'src/selection.h', size 8579 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPDataRange -{ -public: - QCPDataRange(); - QCPDataRange(int begin, int end); - - bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; } - bool operator!=(const QCPDataRange& other) const { return !(*this == other); } - - // getters: - int begin() const { return mBegin; } - int end() const { return mEnd; } - int size() const { return mEnd-mBegin; } - int length() const { return size(); } - - // setters: - void setBegin(int begin) { mBegin = begin; } - void setEnd(int end) { mEnd = end; } - - // non-property methods: - bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } - bool isEmpty() const { return length() == 0; } - QCPDataRange bounded(const QCPDataRange &other) const; - QCPDataRange expanded(const QCPDataRange &other) const; - QCPDataRange intersection(const QCPDataRange &other) const; - QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); } - bool intersects(const QCPDataRange &other) const; - bool contains(const QCPDataRange &other) const; - -private: - // property members: - int mBegin, mEnd; - -}; -Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE); - - -class QCP_LIB_DECL QCPDataSelection -{ -public: - explicit QCPDataSelection(); - explicit QCPDataSelection(const QCPDataRange &range); - - bool operator==(const QCPDataSelection& other) const; - bool operator!=(const QCPDataSelection& other) const { return !(*this == other); } - QCPDataSelection &operator+=(const QCPDataSelection& other); - QCPDataSelection &operator+=(const QCPDataRange& other); - QCPDataSelection &operator-=(const QCPDataSelection& other); - QCPDataSelection &operator-=(const QCPDataRange& other); - friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b); - friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b); - friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b); - friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b); - friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b); - friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b); - friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b); - friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b); - - // getters: - int dataRangeCount() const { return mDataRanges.size(); } - int dataPointCount() const; - QCPDataRange dataRange(int index=0) const; - QList dataRanges() const { return mDataRanges; } - QCPDataRange span() const; - - // non-property methods: - void addDataRange(const QCPDataRange &dataRange, bool simplify=true); - void clear(); - bool isEmpty() const { return mDataRanges.isEmpty(); } - void simplify(); - void enforceType(QCP::SelectionType type); - bool contains(const QCPDataSelection &other) const; - QCPDataSelection intersection(const QCPDataRange &other) const; - QCPDataSelection intersection(const QCPDataSelection &other) const; - QCPDataSelection inverse(const QCPDataRange &outerRange) const; - -private: - // property members: - QList mDataRanges; - - inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); } -}; -Q_DECLARE_METATYPE(QCPDataSelection) - - -/*! - Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. - The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). -*/ -inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b) -{ - QCPDataSelection result(a); - result += b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. - The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). -*/ -inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b) -{ - QCPDataSelection result(a); - result += b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. - The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). -*/ -inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b) -{ - QCPDataSelection result(a); - result += b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. - The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). -*/ -inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b) -{ - QCPDataSelection result(a); - result += b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. -*/ -inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b) -{ - QCPDataSelection result(a); - result -= b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. -*/ -inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b) -{ - QCPDataSelection result(a); - result -= b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. -*/ -inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b) -{ - QCPDataSelection result(a); - result -= b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. -*/ -inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b) -{ - QCPDataSelection result(a); - result -= b; - return result; -} - -/*! \relates QCPDataRange - - Prints \a dataRange in a human readable format to the qDebug output. -*/ -inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange) -{ - d.nospace() << "[" << dataRange.begin() << ".." << dataRange.end()-1 << "]"; - return d.space(); -} - -/*! \relates QCPDataSelection - - Prints \a selection in a human readable format to the qDebug output. -*/ -inline QDebug operator<< (QDebug d, const QCPDataSelection &selection) -{ - d.nospace() << "QCPDataSelection("; - for (int i=0; i elements(QCP::MarginSide side) const { return mChildren.value(side); } - bool isEmpty() const; - void clear(); - -protected: - // non-property members: - QCustomPlot *mParentPlot; - QHash > mChildren; - - // introduced virtual methods: - virtual int commonMargin(QCP::MarginSide side) const; - - // non-virtual methods: - void addChild(QCP::MarginSide side, QCPLayoutElement *element); - void removeChild(QCP::MarginSide side, QCPLayoutElement *element); - -private: - Q_DISABLE_COPY(QCPMarginGroup) - - friend class QCPLayoutElement; -}; - - -class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPLayout* layout READ layout) - Q_PROPERTY(QRect rect READ rect) - Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) - Q_PROPERTY(QMargins margins READ margins WRITE setMargins) - Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) - Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) - Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) - Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect) - /// \endcond -public: - /*! - Defines the phases of the update process, that happens just before a replot. At each phase, - \ref update is called with the according UpdatePhase value. - */ - enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout - ,upMargins ///< Phase in which the margins are calculated and set - ,upLayout ///< Final phase in which the layout system places the rects of the elements - }; - Q_ENUMS(UpdatePhase) - - /*! - Defines to which rect of a layout element the size constraints that can be set via \ref - setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the - margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect) - does not. - - \see setSizeConstraintRect - */ - enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect - , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins - }; - Q_ENUMS(SizeConstraintRect) - - explicit QCPLayoutElement(QCustomPlot *parentPlot=0); - virtual ~QCPLayoutElement(); - - // getters: - QCPLayout *layout() const { return mParentLayout; } - QRect rect() const { return mRect; } - QRect outerRect() const { return mOuterRect; } - QMargins margins() const { return mMargins; } - QMargins minimumMargins() const { return mMinimumMargins; } - QCP::MarginSides autoMargins() const { return mAutoMargins; } - QSize minimumSize() const { return mMinimumSize; } - QSize maximumSize() const { return mMaximumSize; } - SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; } - QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } - QHash marginGroups() const { return mMarginGroups; } - - // setters: - void setOuterRect(const QRect &rect); - void setMargins(const QMargins &margins); - void setMinimumMargins(const QMargins &margins); - void setAutoMargins(QCP::MarginSides sides); - void setMinimumSize(const QSize &size); - void setMinimumSize(int width, int height); - void setMaximumSize(const QSize &size); - void setMaximumSize(int width, int height); - void setSizeConstraintRect(SizeConstraintRect constraintRect); - void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); - - // introduced virtual methods: - virtual void update(UpdatePhase phase); - virtual QSize minimumOuterSizeHint() const; - virtual QSize maximumOuterSizeHint() const; - virtual QList elements(bool recursive) const; - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - -protected: - // property members: - QCPLayout *mParentLayout; - QSize mMinimumSize, mMaximumSize; - SizeConstraintRect mSizeConstraintRect; - QRect mRect, mOuterRect; - QMargins mMargins, mMinimumMargins; - QCP::MarginSides mAutoMargins; - QHash mMarginGroups; - - // introduced virtual methods: - virtual int calculateAutoMargin(QCP::MarginSide side); - virtual void layoutChanged(); - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) } - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } - virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; - -private: - Q_DISABLE_COPY(QCPLayoutElement) - - friend class QCustomPlot; - friend class QCPLayout; - friend class QCPMarginGroup; -}; -Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase) - - -class QCP_LIB_DECL QCPLayout : public QCPLayoutElement -{ - Q_OBJECT -public: - explicit QCPLayout(); - - // reimplemented virtual methods: - virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; - virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual int elementCount() const = 0; - virtual QCPLayoutElement* elementAt(int index) const = 0; - virtual QCPLayoutElement* takeAt(int index) = 0; - virtual bool take(QCPLayoutElement* element) = 0; - virtual void simplify(); - - // non-virtual methods: - bool removeAt(int index); - bool remove(QCPLayoutElement* element); - void clear(); - -protected: - // introduced virtual methods: - virtual void updateLayout(); - - // non-virtual methods: - void sizeConstraintsChanged() const; - void adoptElement(QCPLayoutElement *el); - void releaseElement(QCPLayoutElement *el); - QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; - static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el); - static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el); - -private: - Q_DISABLE_COPY(QCPLayout) - friend class QCPLayoutElement; -}; - - -class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(int rowCount READ rowCount) - Q_PROPERTY(int columnCount READ columnCount) - Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) - Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) - Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) - Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) - Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder) - Q_PROPERTY(int wrap READ wrap WRITE setWrap) - /// \endcond -public: - - /*! - Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). - The column/row at which wrapping into the next row/column occurs can be specified with \ref - setWrap. - - \see setFillOrder - */ - enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap. - ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. - }; - Q_ENUMS(FillOrder) - - explicit QCPLayoutGrid(); - virtual ~QCPLayoutGrid(); - - // getters: - int rowCount() const { return mElements.size(); } - int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } - QList columnStretchFactors() const { return mColumnStretchFactors; } - QList rowStretchFactors() const { return mRowStretchFactors; } - int columnSpacing() const { return mColumnSpacing; } - int rowSpacing() const { return mRowSpacing; } - int wrap() const { return mWrap; } - FillOrder fillOrder() const { return mFillOrder; } - - // setters: - void setColumnStretchFactor(int column, double factor); - void setColumnStretchFactors(const QList &factors); - void setRowStretchFactor(int row, double factor); - void setRowStretchFactors(const QList &factors); - void setColumnSpacing(int pixels); - void setRowSpacing(int pixels); - void setWrap(int count); - void setFillOrder(FillOrder order, bool rearrange=true); - - // reimplemented virtual methods: - virtual void updateLayout() Q_DECL_OVERRIDE; - virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); } - virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; - virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; - virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; - virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; - virtual void simplify() Q_DECL_OVERRIDE; - virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; - virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; - - // non-virtual methods: - QCPLayoutElement *element(int row, int column) const; - bool addElement(int row, int column, QCPLayoutElement *element); - bool addElement(QCPLayoutElement *element); - bool hasElement(int row, int column); - void expandTo(int newRowCount, int newColumnCount); - void insertRow(int newIndex); - void insertColumn(int newIndex); - int rowColToIndex(int row, int column) const; - void indexToRowCol(int index, int &row, int &column) const; - -protected: - // property members: - QList > mElements; - QList mColumnStretchFactors; - QList mRowStretchFactors; - int mColumnSpacing, mRowSpacing; - int mWrap; - FillOrder mFillOrder; - - // non-virtual methods: - void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; - void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; - -private: - Q_DISABLE_COPY(QCPLayoutGrid) -}; -Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder) - - -class QCP_LIB_DECL QCPLayoutInset : public QCPLayout -{ - Q_OBJECT -public: - /*! - Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. - */ - enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect - ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment - }; - Q_ENUMS(InsetPlacement) - - explicit QCPLayoutInset(); - virtual ~QCPLayoutInset(); - - // getters: - InsetPlacement insetPlacement(int index) const; - Qt::Alignment insetAlignment(int index) const; - QRectF insetRect(int index) const; - - // setters: - void setInsetPlacement(int index, InsetPlacement placement); - void setInsetAlignment(int index, Qt::Alignment alignment); - void setInsetRect(int index, const QRectF &rect); - - // reimplemented virtual methods: - virtual void updateLayout() Q_DECL_OVERRIDE; - virtual int elementCount() const Q_DECL_OVERRIDE; - virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; - virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; - virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; - virtual void simplify() Q_DECL_OVERRIDE {} - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void addElement(QCPLayoutElement *element, Qt::Alignment alignment); - void addElement(QCPLayoutElement *element, const QRectF &rect); - -protected: - // property members: - QList mElements; - QList mInsetPlacement; - QList mInsetAlignment; - QList mInsetRect; - -private: - Q_DISABLE_COPY(QCPLayoutInset) -}; -Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement) - -/* end of 'src/layout.h' */ - - -/* including file 'src/lineending.h', size 4426 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPLineEnding -{ - Q_GADGET -public: - /*! - Defines the type of ending decoration for line-like items, e.g. an arrow. - - \image html QCPLineEnding.png - - The width and length of these decorations can be controlled with the functions \ref setWidth - and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only - support a width, the length property is ignored. - - \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding - */ - enum EndingStyle { esNone ///< No ending decoration - ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) - ,esSpikeArrow ///< A filled arrow head with an indented back - ,esLineArrow ///< A non-filled arrow head with open back - ,esDisc ///< A filled circle - ,esSquare ///< A filled square - ,esDiamond ///< A filled diamond (45 degrees rotated square) - ,esBar ///< A bar perpendicular to the line - ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) - ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) - }; - Q_ENUMS(EndingStyle) - - QCPLineEnding(); - QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); - - // getters: - EndingStyle style() const { return mStyle; } - double width() const { return mWidth; } - double length() const { return mLength; } - bool inverted() const { return mInverted; } - - // setters: - void setStyle(EndingStyle style); - void setWidth(double width); - void setLength(double length); - void setInverted(bool inverted); - - // non-property methods: - double boundingDistance() const; - double realLength() const; - void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; - void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; - -protected: - // property members: - EndingStyle mStyle; - double mWidth, mLength; - bool mInverted; -}; -Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); -Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle) - -/* end of 'src/lineending.h' */ - - -/* including file 'src/axis/axisticker.h', size 4177 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTicker -{ - Q_GADGET -public: - /*! - Defines the strategies that the axis ticker may follow when choosing the size of the tick step. - - \see setTickStepStrategy - */ - enum TickStepStrategy - { - tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount) - ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count - }; - Q_ENUMS(TickStepStrategy) - - QCPAxisTicker(); - virtual ~QCPAxisTicker(); - - // getters: - TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } - int tickCount() const { return mTickCount; } - double tickOrigin() const { return mTickOrigin; } - - // setters: - void setTickStepStrategy(TickStepStrategy strategy); - void setTickCount(int count); - void setTickOrigin(double origin); - - // introduced virtual methods: - virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); - -protected: - // property members: - TickStepStrategy mTickStepStrategy; - int mTickCount; - double mTickOrigin; - - // introduced virtual methods: - virtual double getTickStep(const QCPRange &range); - virtual int getSubTickCount(double tickStep); - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision); - virtual QVector createTickVector(double tickStep, const QCPRange &range); - virtual QVector createSubTickVector(int subTickCount, const QVector &ticks); - virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision); - - // non-virtual methods: - void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const; - double pickClosest(double target, const QVector &candidates) const; - double getMantissa(double input, double *magnitude=0) const; - double cleanMantissa(double input) const; -}; -Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) -Q_DECLARE_METATYPE(QSharedPointer) - -/* end of 'src/axis/axisticker.h' */ - - -/* including file 'src/axis/axistickerdatetime.h', size 3289 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker -{ -public: - QCPAxisTickerDateTime(); - - // getters: - QString dateTimeFormat() const { return mDateTimeFormat; } - Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } - - // setters: - void setDateTimeFormat(const QString &format); - void setDateTimeSpec(Qt::TimeSpec spec); - void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) - void setTickOrigin(const QDateTime &origin); - - // static methods: - static QDateTime keyToDateTime(double key); - static double dateTimeToKey(const QDateTime dateTime); - static double dateTimeToKey(const QDate date); - -protected: - // property members: - QString mDateTimeFormat; - Qt::TimeSpec mDateTimeSpec; - - // non-property members: - enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; -}; - -/* end of 'src/axis/axistickerdatetime.h' */ - - -/* including file 'src/axis/axistickertime.h', size 3542 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker -{ - Q_GADGET -public: - /*! - Defines the logical units in which fractions of time spans can be expressed. - - \see setFieldWidth, setTimeFormat - */ - enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) - ,tuSeconds ///< Seconds (%%s in \ref setTimeFormat) - ,tuMinutes ///< Minutes (%%m in \ref setTimeFormat) - ,tuHours ///< Hours (%%h in \ref setTimeFormat) - ,tuDays ///< Days (%%d in \ref setTimeFormat) - }; - Q_ENUMS(TimeUnit) - - QCPAxisTickerTime(); - - // getters: - QString timeFormat() const { return mTimeFormat; } - int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } - - // setters: - void setTimeFormat(const QString &format); - void setFieldWidth(TimeUnit unit, int width); - -protected: - // property members: - QString mTimeFormat; - QHash mFieldWidth; - - // non-property members: - TimeUnit mSmallestUnit, mBiggestUnit; - QHash mFormatPattern; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - - // non-virtual methods: - void replaceUnit(QString &text, TimeUnit unit, int value) const; -}; -Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit) - -/* end of 'src/axis/axistickertime.h' */ - - -/* including file 'src/axis/axistickerfixed.h', size 3308 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker -{ - Q_GADGET -public: - /*! - Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to - control the number of ticks in the axis range. - - \see setScaleStrategy - */ - enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out. - ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount. - ,ssPowers ///< An integer power of the specified tick step is allowed. - }; - Q_ENUMS(ScaleStrategy) - - QCPAxisTickerFixed(); - - // getters: - double tickStep() const { return mTickStep; } - ScaleStrategy scaleStrategy() const { return mScaleStrategy; } - - // setters: - void setTickStep(double step); - void setScaleStrategy(ScaleStrategy strategy); - -protected: - // property members: - double mTickStep; - ScaleStrategy mScaleStrategy; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; -}; -Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy) - -/* end of 'src/axis/axistickerfixed.h' */ - - -/* including file 'src/axis/axistickertext.h', size 3085 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker -{ -public: - QCPAxisTickerText(); - - // getters: - QMap &ticks() { return mTicks; } - int subTickCount() const { return mSubTickCount; } - - // setters: - void setTicks(const QMap &ticks); - void setTicks(const QVector &positions, const QVector labels); - void setSubTickCount(int subTicks); - - // non-virtual methods: - void clear(); - void addTick(double position, QString label); - void addTicks(const QMap &ticks); - void addTicks(const QVector &positions, const QVector &labels); - -protected: - // property members: - QMap mTicks; - int mSubTickCount; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; - -}; - -/* end of 'src/axis/axistickertext.h' */ - - -/* including file 'src/axis/axistickerpi.h', size 3911 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker -{ - Q_GADGET -public: - /*! - Defines how fractions should be displayed in tick labels. - - \see setFractionStyle - */ - enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125". - ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8" - ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol. - }; - Q_ENUMS(FractionStyle) - - QCPAxisTickerPi(); - - // getters: - QString piSymbol() const { return mPiSymbol; } - double piValue() const { return mPiValue; } - bool periodicity() const { return mPeriodicity; } - FractionStyle fractionStyle() const { return mFractionStyle; } - - // setters: - void setPiSymbol(QString symbol); - void setPiValue(double pi); - void setPeriodicity(int multiplesOfPi); - void setFractionStyle(FractionStyle style); - -protected: - // property members: - QString mPiSymbol; - double mPiValue; - int mPeriodicity; - FractionStyle mFractionStyle; - - // non-property members: - double mPiTickStep; // size of one tick step in units of mPiValue - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - - // non-virtual methods: - void simplifyFraction(int &numerator, int &denominator) const; - QString fractionToString(int numerator, int denominator) const; - QString unicodeFraction(int numerator, int denominator) const; - QString unicodeSuperscript(int number) const; - QString unicodeSubscript(int number) const; -}; -Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle) - -/* end of 'src/axis/axistickerpi.h' */ - - -/* including file 'src/axis/axistickerlog.h', size 2663 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker -{ -public: - QCPAxisTickerLog(); - - // getters: - double logBase() const { return mLogBase; } - int subTickCount() const { return mSubTickCount; } - - // setters: - void setLogBase(double base); - void setSubTickCount(int subTicks); - -protected: - // property members: - double mLogBase; - int mSubTickCount; - - // non-property members: - double mLogBaseLnInv; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; -}; - -/* end of 'src/axis/axistickerlog.h' */ - - -/* including file 'src/axis/axis.h', size 20634 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPGrid :public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) - Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) - Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) - Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) - /// \endcond -public: - explicit QCPGrid(QCPAxis *parentAxis); - - // getters: - bool subGridVisible() const { return mSubGridVisible; } - bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } - bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } - QPen pen() const { return mPen; } - QPen subGridPen() const { return mSubGridPen; } - QPen zeroLinePen() const { return mZeroLinePen; } - - // setters: - void setSubGridVisible(bool visible); - void setAntialiasedSubGrid(bool enabled); - void setAntialiasedZeroLine(bool enabled); - void setPen(const QPen &pen); - void setSubGridPen(const QPen &pen); - void setZeroLinePen(const QPen &pen); - -protected: - // property members: - bool mSubGridVisible; - bool mAntialiasedSubGrid, mAntialiasedZeroLine; - QPen mPen, mSubGridPen, mZeroLinePen; - - // non-property members: - QCPAxis *mParentAxis; - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - // non-virtual methods: - void drawGridLines(QCPPainter *painter) const; - void drawSubGridLines(QCPPainter *painter) const; - - friend class QCPAxis; -}; - - -class QCP_LIB_DECL QCPAxis : public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(AxisType axisType READ axisType) - Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) - Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) - Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) - Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) - Q_PROPERTY(QSharedPointer ticker READ ticker WRITE setTicker) - Q_PROPERTY(bool ticks READ ticks WRITE setTicks) - Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) - Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) - Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) - Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) - Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) - Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) - Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) - Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) - Q_PROPERTY(QVector tickVector READ tickVector) - Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels) - Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) - Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) - Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks) - Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) - Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) - Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) - Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) - Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) - Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) - Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) - Q_PROPERTY(QString label READ label WRITE setLabel) - Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) - Q_PROPERTY(int padding READ padding WRITE setPadding) - Q_PROPERTY(int offset READ offset WRITE setOffset) - Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) - Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) - Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) - Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) - Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) - Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) - Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) - Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) - Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) - Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) - Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) - Q_PROPERTY(QCPGrid* grid READ grid) - /// \endcond -public: - /*! - Defines at which side of the axis rect the axis will appear. This also affects how the tick - marks are drawn, on which side the labels are placed etc. - */ - enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect - ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect - ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect - ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect - }; - Q_ENUMS(AxisType) - Q_FLAGS(AxisTypes) - Q_DECLARE_FLAGS(AxisTypes, AxisType) - /*! - Defines on which side of the axis the tick labels (numbers) shall appear. - - \see setTickLabelSide - */ - enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect - ,lsOutside ///< Tick labels will be displayed outside the axis rect - }; - Q_ENUMS(LabelSide) - /*! - Defines the scale of an axis. - \see setScaleType - */ - enum ScaleType { stLinear ///< Linear scaling - ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). - }; - Q_ENUMS(ScaleType) - /*! - Defines the selectable parts of an axis. - \see setSelectableParts, setSelectedParts - */ - enum SelectablePart { spNone = 0 ///< None of the selectable parts - ,spAxis = 0x001 ///< The axis backbone and tick marks - ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) - ,spAxisLabel = 0x004 ///< The axis label - }; - Q_ENUMS(SelectablePart) - Q_FLAGS(SelectableParts) - Q_DECLARE_FLAGS(SelectableParts, SelectablePart) - - explicit QCPAxis(QCPAxisRect *parent, AxisType type); - virtual ~QCPAxis(); - - // getters: - AxisType axisType() const { return mAxisType; } - QCPAxisRect *axisRect() const { return mAxisRect; } - ScaleType scaleType() const { return mScaleType; } - const QCPRange range() const { return mRange; } - bool rangeReversed() const { return mRangeReversed; } - QSharedPointer ticker() const { return mTicker; } - bool ticks() const { return mTicks; } - bool tickLabels() const { return mTickLabels; } - int tickLabelPadding() const; - QFont tickLabelFont() const { return mTickLabelFont; } - QColor tickLabelColor() const { return mTickLabelColor; } - double tickLabelRotation() const; - LabelSide tickLabelSide() const; - QString numberFormat() const; - int numberPrecision() const { return mNumberPrecision; } - QVector tickVector() const { return mTickVector; } - QVector tickVectorLabels() const { return mTickVectorLabels; } - int tickLengthIn() const; - int tickLengthOut() const; - bool subTicks() const { return mSubTicks; } - int subTickLengthIn() const; - int subTickLengthOut() const; - QPen basePen() const { return mBasePen; } - QPen tickPen() const { return mTickPen; } - QPen subTickPen() const { return mSubTickPen; } - QFont labelFont() const { return mLabelFont; } - QColor labelColor() const { return mLabelColor; } - QString label() const { return mLabel; } - int labelPadding() const; - int padding() const { return mPadding; } - int offset() const; - SelectableParts selectedParts() const { return mSelectedParts; } - SelectableParts selectableParts() const { return mSelectableParts; } - QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } - QFont selectedLabelFont() const { return mSelectedLabelFont; } - QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } - QColor selectedLabelColor() const { return mSelectedLabelColor; } - QPen selectedBasePen() const { return mSelectedBasePen; } - QPen selectedTickPen() const { return mSelectedTickPen; } - QPen selectedSubTickPen() const { return mSelectedSubTickPen; } - QCPLineEnding lowerEnding() const; - QCPLineEnding upperEnding() const; - QCPGrid *grid() const { return mGrid; } - - // setters: - Q_SLOT void setScaleType(QCPAxis::ScaleType type); - Q_SLOT void setRange(const QCPRange &range); - void setRange(double lower, double upper); - void setRange(double position, double size, Qt::AlignmentFlag alignment); - void setRangeLower(double lower); - void setRangeUpper(double upper); - void setRangeReversed(bool reversed); - void setTicker(QSharedPointer ticker); - void setTicks(bool show); - void setTickLabels(bool show); - void setTickLabelPadding(int padding); - void setTickLabelFont(const QFont &font); - void setTickLabelColor(const QColor &color); - void setTickLabelRotation(double degrees); - void setTickLabelSide(LabelSide side); - void setNumberFormat(const QString &formatCode); - void setNumberPrecision(int precision); - void setTickLength(int inside, int outside=0); - void setTickLengthIn(int inside); - void setTickLengthOut(int outside); - void setSubTicks(bool show); - void setSubTickLength(int inside, int outside=0); - void setSubTickLengthIn(int inside); - void setSubTickLengthOut(int outside); - void setBasePen(const QPen &pen); - void setTickPen(const QPen &pen); - void setSubTickPen(const QPen &pen); - void setLabelFont(const QFont &font); - void setLabelColor(const QColor &color); - void setLabel(const QString &str); - void setLabelPadding(int padding); - void setPadding(int padding); - void setOffset(int offset); - void setSelectedTickLabelFont(const QFont &font); - void setSelectedLabelFont(const QFont &font); - void setSelectedTickLabelColor(const QColor &color); - void setSelectedLabelColor(const QColor &color); - void setSelectedBasePen(const QPen &pen); - void setSelectedTickPen(const QPen &pen); - void setSelectedSubTickPen(const QPen &pen); - Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); - Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); - void setLowerEnding(const QCPLineEnding &ending); - void setUpperEnding(const QCPLineEnding &ending); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - // non-property methods: - Qt::Orientation orientation() const { return mOrientation; } - int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; } - void moveRange(double diff); - void scaleRange(double factor); - void scaleRange(double factor, double center); - void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); - void rescale(bool onlyVisiblePlottables=false); - double pixelToCoord(double value) const; - double coordToPixel(double value) const; - SelectablePart getPartAt(const QPointF &pos) const; - QList plottables() const; - QList graphs() const; - QList items() const; - - static AxisType marginSideToAxisType(QCP::MarginSide side); - static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } - static AxisType opposite(AxisType type); - -signals: - void rangeChanged(const QCPRange &newRange); - void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); - void scaleTypeChanged(QCPAxis::ScaleType scaleType); - void selectionChanged(const QCPAxis::SelectableParts &parts); - void selectableChanged(const QCPAxis::SelectableParts &parts); - -protected: - // property members: - // axis base: - AxisType mAxisType; - QCPAxisRect *mAxisRect; - //int mOffset; // in QCPAxisPainter - int mPadding; - Qt::Orientation mOrientation; - SelectableParts mSelectableParts, mSelectedParts; - QPen mBasePen, mSelectedBasePen; - //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter - // axis label: - //int mLabelPadding; // in QCPAxisPainter - QString mLabel; - QFont mLabelFont, mSelectedLabelFont; - QColor mLabelColor, mSelectedLabelColor; - // tick labels: - //int mTickLabelPadding; // in QCPAxisPainter - bool mTickLabels; - //double mTickLabelRotation; // in QCPAxisPainter - QFont mTickLabelFont, mSelectedTickLabelFont; - QColor mTickLabelColor, mSelectedTickLabelColor; - int mNumberPrecision; - QLatin1Char mNumberFormatChar; - bool mNumberBeautifulPowers; - //bool mNumberMultiplyCross; // QCPAxisPainter - // ticks and subticks: - bool mTicks; - bool mSubTicks; - //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter - QPen mTickPen, mSelectedTickPen; - QPen mSubTickPen, mSelectedSubTickPen; - // scale and range: - QCPRange mRange; - bool mRangeReversed; - ScaleType mScaleType; - - // non-property members: - QCPGrid *mGrid; - QCPAxisPainterPrivate *mAxisPainter; - QSharedPointer mTicker; - QVector mTickVector; - QVector mTickVectorLabels; - QVector mSubTickVector; - bool mCachedMarginValid; - int mCachedMargin; - bool mDragging; - QCPRange mDragStartRange; - QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; - - // introduced virtual methods: - virtual int calculateMargin(); - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - // mouse events: - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); - virtual void wheelEvent(QWheelEvent *event); - - // non-virtual methods: - void setupTickVectors(); - QPen getBasePen() const; - QPen getTickPen() const; - QPen getSubTickPen() const; - QFont getTickLabelFont() const; - QFont getLabelFont() const; - QColor getTickLabelColor() const; - QColor getLabelColor() const; - -private: - Q_DISABLE_COPY(QCPAxis) - - friend class QCustomPlot; - friend class QCPGrid; - friend class QCPAxisRect; -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) -Q_DECLARE_METATYPE(QCPAxis::AxisType) -Q_DECLARE_METATYPE(QCPAxis::LabelSide) -Q_DECLARE_METATYPE(QCPAxis::ScaleType) -Q_DECLARE_METATYPE(QCPAxis::SelectablePart) - - -class QCPAxisPainterPrivate -{ -public: - explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); - virtual ~QCPAxisPainterPrivate(); - - virtual void draw(QCPPainter *painter); - virtual int size() const; - void clearCache(); - - QRect axisSelectionBox() const { return mAxisSelectionBox; } - QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } - QRect labelSelectionBox() const { return mLabelSelectionBox; } - - // public property members: - QCPAxis::AxisType type; - QPen basePen; - QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters - int labelPadding; // directly accessed by QCPAxis setters/getters - QFont labelFont; - QColor labelColor; - QString label; - int tickLabelPadding; // directly accessed by QCPAxis setters/getters - double tickLabelRotation; // directly accessed by QCPAxis setters/getters - QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters - bool substituteExponent; - bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters - int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters - QPen tickPen, subTickPen; - QFont tickLabelFont; - QColor tickLabelColor; - QRect axisRect, viewportRect; - double offset; // directly accessed by QCPAxis setters/getters - bool abbreviateDecimalPowers; - bool reversedEndings; - - QVector subTickPositions; - QVector tickPositions; - QVector tickLabels; - -protected: - struct CachedLabel - { - QPointF offset; - QPixmap pixmap; - }; - struct TickLabelData - { - QString basePart, expPart, suffixPart; - QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds; - QFont baseFont, expFont; - }; - QCustomPlot *mParentPlot; - QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters - QCache mLabelCache; - QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; - - virtual QByteArray generateLabelParameterHash() const; - - virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); - virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; - virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; - virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; - virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; -}; - -/* end of 'src/axis/axis.h' */ - - -/* including file 'src/scatterstyle.h', size 7275 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPScatterStyle -{ - Q_GADGET -public: - /*! - Represents the various properties of a scatter style instance. For example, this enum is used - to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when - highlighting selected data points. - - Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref - setFromOther. - */ - enum ScatterProperty { spNone = 0x00 ///< 0x00 None - ,spPen = 0x01 ///< 0x01 The pen property, see \ref setPen - ,spBrush = 0x02 ///< 0x02 The brush property, see \ref setBrush - ,spSize = 0x04 ///< 0x04 The size property, see \ref setSize - ,spShape = 0x08 ///< 0x08 The shape property, see \ref setShape - ,spAll = 0xFF ///< 0xFF All properties - }; - Q_ENUMS(ScatterProperty) - Q_FLAGS(ScatterProperties) - Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty) - - /*! - Defines the shape used for scatter points. - - On plottables/items that draw scatters, the sizes of these visualizations (with exception of - \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are - drawn with the pen and brush specified with \ref setPen and \ref setBrush. - */ - enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) - ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) - ,ssCross ///< \enumimage{ssCross.png} a cross - ,ssPlus ///< \enumimage{ssPlus.png} a plus - ,ssCircle ///< \enumimage{ssCircle.png} a circle - ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) - ,ssSquare ///< \enumimage{ssSquare.png} a square - ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond - ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus - ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline - ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner - ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside - ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside - ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside - ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside - ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines - ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates - ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) - }; - Q_ENUMS(ScatterShape) - - QCPScatterStyle(); - QCPScatterStyle(ScatterShape shape, double size=6); - QCPScatterStyle(ScatterShape shape, const QColor &color, double size); - QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); - QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); - QCPScatterStyle(const QPixmap &pixmap); - QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); - - // getters: - double size() const { return mSize; } - ScatterShape shape() const { return mShape; } - QPen pen() const { return mPen; } - QBrush brush() const { return mBrush; } - QPixmap pixmap() const { return mPixmap; } - QPainterPath customPath() const { return mCustomPath; } - - // setters: - void setFromOther(const QCPScatterStyle &other, ScatterProperties properties); - void setSize(double size); - void setShape(ScatterShape shape); - void setPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setPixmap(const QPixmap &pixmap); - void setCustomPath(const QPainterPath &customPath); - - // non-property methods: - bool isNone() const { return mShape == ssNone; } - bool isPenDefined() const { return mPenDefined; } - void undefinePen(); - void applyTo(QCPPainter *painter, const QPen &defaultPen) const; - void drawShape(QCPPainter *painter, const QPointF &pos) const; - void drawShape(QCPPainter *painter, double x, double y) const; - -protected: - // property members: - double mSize; - ScatterShape mShape; - QPen mPen; - QBrush mBrush; - QPixmap mPixmap; - QPainterPath mCustomPath; - - // non-property members: - bool mPenDefined; -}; -Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties) -Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty) -Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) - -/* end of 'src/scatterstyle.h' */ - - -/* including file 'src/datacontainer.h', size 4596 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -/*! \relates QCPDataContainer - Returns whether the sort key of \a a is less than the sort key of \a b. - - \see QCPDataContainer::sort -*/ -template -inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); } - -template -class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below) -{ -public: - typedef typename QVector::const_iterator const_iterator; - typedef typename QVector::iterator iterator; - - QCPDataContainer(); - - // pointer to data - QVector * data() { return &mData; } - - // getters: - int size() const { return mData.size()-mPreallocSize; } - bool isEmpty() const { return size() == 0; } - bool autoSqueeze() const { return mAutoSqueeze; } - - // setters: - void setAutoSqueeze(bool enabled); - - // non-virtual methods: - void set(const QCPDataContainer &data); - void set(const QVector &data, bool alreadySorted=false); - void add(const QCPDataContainer &data); - void add(const QVector &data, bool alreadySorted=false); - void add(const DataType &data); - void removeBefore(double sortKey); - void removeAfter(double sortKey); - void remove(double sortKeyFrom, double sortKeyTo); - void remove(double sortKey); - void clear(); - void sort(); - void squeeze(bool preAllocation=true, bool postAllocation=true); - - const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; } - const_iterator constEnd() const { return mData.constEnd(); } - iterator begin() { return mData.begin()+mPreallocSize; } - iterator end() { return mData.end(); } - const_iterator findBegin(double sortKey, bool expandedRange=true) const; - const_iterator findEnd(double sortKey, bool expandedRange=true) const; - const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); } - QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth); - QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()); - QCPDataRange dataRange() const { return QCPDataRange(0, size()); } - void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const; - -protected: - // property members: - bool mAutoSqueeze; - - // non-property memebers: - QVector mData; - int mPreallocSize; - int mPreallocIteration; - - // non-virtual methods: - void preallocateGrow(int minimumPreallocSize); - void performAutoSqueeze(); -}; - -// include implementation in header since it is a class template: - -/* including file 'src/datacontainer.cpp', size 31349 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPDataContainer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPDataContainer - \brief The generic data container for one-dimensional plottables - - This class template provides a fast container for data storage of one-dimensional data. The data - type is specified as template parameter (called \a DataType in the following) and must provide - some methods as described in the \ref qcpdatacontainer-datatype "next section". - - The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well - as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The - container uses a preallocation and a postallocation scheme, such that appending and prepending - data (with respect to the sort key) is very fast and minimizes reallocations. If data is added - which needs to be inserted between existing keys, the merge usually can be done quickly too, - using the fact that existing data is always sorted. The user can further improve performance by - specifying that added data is already itself sorted by key, if he can guarantee that this is the - case (see for example \ref add(const QVector &data, bool alreadySorted)). - - The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If - it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin, - \ref end). Changing data members that are not the sort key (for most data types called \a key) is - safe from the container's perspective. - - Great care must be taken however if the sort key is modified through the non-const iterators. For - performance reasons, the iterators don't automatically cause a re-sorting upon their - manipulation. It is thus the responsibility of the user to leave the container in a sorted state - when finished with the data manipulation, before calling any other methods on the container. A - complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref - sort. Failing to do so can not be detected by the container efficiently and will cause both - rendering artifacts and potential data loss. - - Implementing one-dimensional plottables that make use of a \ref QCPDataContainer is usually - done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D", which - introduces an according \a mDataContainer member and some convenience methods. - - \section qcpdatacontainer-datatype Requirements for the DataType template parameter - - The template parameter DataType is the type of the stored data points. It must be - trivially copyable and have the following public methods, preferably inline: - - \li double sortKey() const\n Returns the member variable of this data point that is the - sort key, defining the ordering in the container. Often this variable is simply called \a key. - - \li static DataType fromSortKey(double sortKey)\n Returns a new instance of the data - type initialized with its sort key set to \a sortKey. - - \li static bool sortKeyIsMainKey()\n Returns true if the sort key is equal to the main - key (see method \c mainKey below). For most plottables this is the case. It is not the case for - example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason - why QCPCurve unlike QCPGraph can display parametric curves with loops. - - \li double mainKey() const\n Returns the variable of this data point considered the main - key. This is commonly the variable that is used as the coordinate of this data point on the key - axis of the plottable. This method is used for example when determining the automatic axis - rescaling of key axes (\ref QCPAxis::rescale). - - \li double mainValue() const\n Returns the variable of this data point considered the - main value. This is commonly the variable that is used as the coordinate of this data point on - the value axis of the plottable. - - \li QCPRange valueRange() const\n Returns the range this data point spans in the value - axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with - both lower and upper set to the main data point value. However if the data points can represent - multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close - values at each \a key) this method should return the range those values span. This method is used - for example when determining the automatic axis rescaling of value axes (\ref - QCPAxis::rescale). -*/ - -/* start documentation of inline functions */ - -/*! \fn int QCPDataContainer::size() const - - Returns the number of data points in the container. -*/ - -/*! \fn bool QCPDataContainer::isEmpty() const - - Returns whether this container holds no data points. -*/ - -/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constBegin() const - - Returns a const iterator to the first data point in this container. -*/ - -/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constEnd() const - - Returns a const iterator to the element past the last data point in this container. -*/ - -/*! \fn QCPDataContainer::iterator QCPDataContainer::begin() const - - Returns a non-const iterator to the first data point in this container. - - You can manipulate the data points in-place through the non-const iterators, but great care must - be taken when manipulating the sort key of a data point, see \ref sort, or the detailed - description of this class. -*/ - -/*! \fn QCPDataContainer::iterator QCPDataContainer::end() const - - Returns a non-const iterator to the element past the last data point in this container. - - You can manipulate the data points in-place through the non-const iterators, but great care must - be taken when manipulating the sort key of a data point, see \ref sort, or the detailed - description of this class. -*/ - -/*! \fn QCPDataContainer::const_iterator QCPDataContainer::at(int index) const - - Returns a const iterator to the element with the specified \a index. If \a index points beyond - the available elements in this container, returns \ref constEnd, i.e. an iterator past the last - valid element. - - You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref - dataselection-accessing "data selection page" for an example. -*/ - -/*! \fn QCPDataRange QCPDataContainer::dataRange() const - - Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the - begin index of the returned range is 0, and the end index is \ref size. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted - data -*/ -template -QCPDataContainer::QCPDataContainer() : - mAutoSqueeze(true), - mPreallocSize(0), - mPreallocIteration(0) -{ -} - -/*! - Sets whether the container automatically decides when to release memory from its post- and - preallocation pools when data points are removed. By default this is enabled and for typical - applications shouldn't be changed. - - If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with - \ref squeeze. -*/ -template -void QCPDataContainer::setAutoSqueeze(bool enabled) -{ - if (mAutoSqueeze != enabled) - { - mAutoSqueeze = enabled; - if (mAutoSqueeze) - performAutoSqueeze(); - } -} - -/*! \overload - - Replaces the current data in this container with the provided \a data. - - \see add, remove -*/ -template -void QCPDataContainer::set(const QCPDataContainer &data) -{ - clear(); - add(data); -} - -/*! \overload - - Replaces the current data in this container with the provided \a data - - If you can guarantee that the data points in \a data have ascending order with respect to the - DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. - - \see add, remove -*/ -template -void QCPDataContainer::set(const QVector &data, bool alreadySorted) -{ - mData = data; - mPreallocSize = 0; - mPreallocIteration = 0; - if (!alreadySorted) - sort(); -} - -/*! \overload - - Adds the provided \a data to the current data in this container. - - \see set, remove -*/ -template -void QCPDataContainer::add(const QCPDataContainer &data) -{ - if (data.isEmpty()) - return; - - const int n = data.size(); - const int oldSize = size(); - - if (oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones - { - if (mPreallocSize < n) - preallocateGrow(n); - mPreallocSize -= n; - std::copy(data.constBegin(), data.constEnd(), begin()); - } else // don't need to prepend, so append and merge if necessary - { - mData.resize(mData.size()+n); - std::copy(data.constBegin(), data.constEnd(), end()-n); - if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions - std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); - } -} - -/*! - Adds the provided data points in \a data to the current data. - - If you can guarantee that the data points in \a data have ascending order with respect to the - DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. - - \see set, remove -*/ -template -void QCPDataContainer::add(const QVector &data, bool alreadySorted) -{ - if (data.isEmpty()) - return; - if (isEmpty()) - { - set(data, alreadySorted); - return; - } - - const int n = data.size(); - const int oldSize = size(); - - if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones - { - if (mPreallocSize < n) - preallocateGrow(n); - mPreallocSize -= n; - std::copy(data.constBegin(), data.constEnd(), begin()); - } else // don't need to prepend, so append and then sort and merge if necessary - { - mData.resize(mData.size()+n); - std::copy(data.constBegin(), data.constEnd(), end()-n); - if (!alreadySorted) // sort appended subrange if it wasn't already sorted - std::sort(end()-n, end(), qcpLessThanSortKey); - if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions - std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); - } -} - -/*! \overload - - Adds the provided single data point to the current data. - - \see remove -*/ -template -void QCPDataContainer::add(const DataType &data) -{ - if (isEmpty() || !qcpLessThanSortKey(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones - { - mData.append(data); - } else if (qcpLessThanSortKey(data, *constBegin())) // quickly handle prepends using preallocated space - { - if (mPreallocSize < 1) - preallocateGrow(1); - --mPreallocSize; - *begin() = data; - } else // handle inserts, maintaining sorted keys - { - QCPDataContainer::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey); - mData.insert(insertionPoint, data); - } -} - -/*! - Removes all data points with (sort-)keys smaller than or equal to \a sortKey. - - \see removeAfter, remove, clear -*/ -template -void QCPDataContainer::removeBefore(double sortKey) -{ - QCPDataContainer::iterator it = begin(); - QCPDataContainer::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - mPreallocSize += itEnd-it; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) - if (mAutoSqueeze) - performAutoSqueeze(); -} - -/*! - Removes all data points with (sort-)keys greater than or equal to \a sortKey. - - \see removeBefore, remove, clear -*/ -template -void QCPDataContainer::removeAfter(double sortKey) -{ - QCPDataContainer::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - QCPDataContainer::iterator itEnd = end(); - mData.erase(it, itEnd); // typically adds it to the postallocated block - if (mAutoSqueeze) - performAutoSqueeze(); -} - -/*! - Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a - sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single - data point with known (sort-)key, use \ref remove(double sortKey). - - \see removeBefore, removeAfter, clear -*/ -template -void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) -{ - if (sortKeyFrom >= sortKeyTo || isEmpty()) - return; - - QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey); - QCPDataContainer::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey); - mData.erase(it, itEnd); - if (mAutoSqueeze) - performAutoSqueeze(); -} - -/*! \overload - - Removes a single data point at \a sortKey. If the position is not known with absolute (binary) - precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small - fuzziness interval around the suspected position, depeding on the precision with which the - (sort-)key is known. - - \see removeBefore, removeAfter, clear -*/ -template -void QCPDataContainer::remove(double sortKey) -{ - QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - if (it != end() && it->sortKey() == sortKey) - { - if (it == begin()) - ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) - else - mData.erase(it); - } - if (mAutoSqueeze) - performAutoSqueeze(); -} - -/*! - Removes all data points. - - \see remove, removeAfter, removeBefore -*/ -template -void QCPDataContainer::clear() -{ - mData.clear(); - mPreallocIteration = 0; - mPreallocSize = 0; -} - -/*! - Re-sorts all data points in the container by their sort key. - - When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add, - \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full - resort is never necessary. However, if you choose to directly manipulate the sort key on data - points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it - is your responsibility to bring the container back into a sorted state before any other methods - are called on it. This can be achieved by calling this method immediately after finishing the - sort key manipulation. -*/ -template -void QCPDataContainer::sort() -{ - std::sort(begin(), end(), qcpLessThanSortKey); -} - -/*! - Frees all unused memory that is currently in the preallocation and postallocation pools. - - Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref - setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical - applications. - - The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation - should be freed, respectively. -*/ -template -void QCPDataContainer::squeeze(bool preAllocation, bool postAllocation) -{ - if (preAllocation) - { - if (mPreallocSize > 0) - { - std::copy(begin(), end(), mData.begin()); - mData.resize(size()); - mPreallocSize = 0; - } - mPreallocIteration = 0; - } - if (postAllocation) - mData.squeeze(); -} - -/*! - Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just - above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be - considered, otherwise the one just above. - - This can be used in conjunction with \ref findEnd to iterate over data points within a given key - range, including or excluding the bounding data points that are just beyond the specified range. - - If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is - returned. - - If the container is empty, returns \ref constEnd. - - \see findEnd, QCPPlottableInterface1D::findBegin -*/ -template -typename QCPDataContainer::const_iterator QCPDataContainer::findBegin(double sortKey, bool expandedRange) const -{ - if (isEmpty()) - return constEnd(); - - QCPDataContainer::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty - --it; - return it; -} - -/*! - Returns an iterator to the element after the data point with a (sort-)key that is equal to, just - above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey - will be considered, otherwise the one just below. - - This can be used in conjunction with \ref findBegin to iterate over data points within a given - key range, including the bounding data points that are just below and above the specified range. - - If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is - returned. - - If the container is empty, \ref constEnd is returned. - - \see findBegin, QCPPlottableInterface1D::findEnd -*/ -template -typename QCPDataContainer::const_iterator QCPDataContainer::findEnd(double sortKey, bool expandedRange) const -{ - if (isEmpty()) - return constEnd(); - - QCPDataContainer::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - if (expandedRange && it != constEnd()) - ++it; - return it; -} - -/*! - Returns the range encompassed by the (main-)key coordinate of all data points. The output - parameter \a foundRange indicates whether a sensible range was found. If this is false, you - should not use the returned QCPRange (e.g. the data container is empty or all points have the - same key). - - Use \a signDomain to control which sign of the key coordinates should be considered. This is - relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a - time. - - If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is - the case for most plottables, this method uses this fact and finds the range very quickly. - - \see valueRange -*/ -template -QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain signDomain) -{ - if (isEmpty()) - { - foundRange = false; - return QCPRange(); - } - QCPRange range; - bool haveLower = false; - bool haveUpper = false; - double current; - - QCPDataContainer::const_iterator it = constBegin(); - QCPDataContainer::const_iterator itEnd = constEnd(); - if (signDomain == QCP::sdBoth) // range may be anywhere - { - if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value - { - while (it != itEnd) // find first non-nan going up from left - { - if (!qIsNaN(it->mainValue())) - { - range.lower = it->mainKey(); - haveLower = true; - break; - } - ++it; - } - it = itEnd; - while (it != constBegin()) // find first non-nan going down from right - { - --it; - if (!qIsNaN(it->mainValue())) - { - range.upper = it->mainKey(); - haveUpper = true; - break; - } - } - } else // DataType is not sorted by main key, go through all data points and accordingly expand range - { - while (it != itEnd) - { - if (!qIsNaN(it->mainValue())) - { - current = it->mainKey(); - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - ++it; - } - } - } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain - { - while (it != itEnd) - { - if (!qIsNaN(it->mainValue())) - { - current = it->mainKey(); - if ((current < range.lower || !haveLower) && current < 0) - { - range.lower = current; - haveLower = true; - } - if ((current > range.upper || !haveUpper) && current < 0) - { - range.upper = current; - haveUpper = true; - } - } - ++it; - } - } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain - { - while (it != itEnd) - { - if (!qIsNaN(it->mainValue())) - { - current = it->mainKey(); - if ((current < range.lower || !haveLower) && current > 0) - { - range.lower = current; - haveLower = true; - } - if ((current > range.upper || !haveUpper) && current > 0) - { - range.upper = current; - haveUpper = true; - } - } - ++it; - } - } - - foundRange = haveLower && haveUpper; - return range; -} - -/*! - Returns the range encompassed by the value coordinates of the data points in the specified key - range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The - output parameter \a foundRange indicates whether a sensible range was found. If this is false, - you should not use the returned QCPRange (e.g. the data container is empty or all points have the - same value). - - If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), - all data points are considered, without any restriction on the keys. - - Use \a signDomain to control which sign of the value coordinates should be considered. This is - relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a - time. - - \see keyRange -*/ -template -QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange) -{ - if (isEmpty()) - { - foundRange = false; - return QCPRange(); - } - QCPRange range; - const bool restrictKeyRange = inKeyRange != QCPRange(); - bool haveLower = false; - bool haveUpper = false; - QCPRange current; - QCPDataContainer::const_iterator itBegin = constBegin(); - QCPDataContainer::const_iterator itEnd = constEnd(); - if (DataType::sortKeyIsMainKey() && restrictKeyRange) - { - itBegin = findBegin(inKeyRange.lower); - itEnd = findEnd(inKeyRange.upper); - } - if (signDomain == QCP::sdBoth) // range may be anywhere - { - for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) - continue; - current = it->valueRange(); - if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower)) - { - range.lower = current.lower; - haveLower = true; - } - if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper)) - { - range.upper = current.upper; - haveUpper = true; - } - } - } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain - { - for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) - continue; - current = it->valueRange(); - if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower)) - { - range.lower = current.lower; - haveLower = true; - } - if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper)) - { - range.upper = current.upper; - haveUpper = true; - } - } - } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain - { - for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) - continue; - current = it->valueRange(); - if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower)) - { - range.lower = current.lower; - haveLower = true; - } - if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper)) - { - range.upper = current.upper; - haveUpper = true; - } - } - } - - foundRange = haveLower && haveUpper; - return range; -} - -/*! - Makes sure \a begin and \a end mark a data range that is both within the bounds of this data - container's data, as well as within the specified \a dataRange. The initial range described by - the passed iterators \a begin and \a end is never expanded, only contracted if necessary. - - This function doesn't require for \a dataRange to be within the bounds of this data container's - valid range. -*/ -template -void QCPDataContainer::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const -{ - QCPDataRange iteratorRange(begin-constBegin(), end-constBegin()); - iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange())); - begin = constBegin()+iteratorRange.begin(); - end = constBegin()+iteratorRange.end(); -} - -/*! \internal - - Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on - the preallocation history, the container will grow by more than requested, to speed up future - consecutive size increases. - - if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this - method does nothing. -*/ -template -void QCPDataContainer::preallocateGrow(int minimumPreallocSize) -{ - if (minimumPreallocSize <= mPreallocSize) - return; - - int newPreallocSize = minimumPreallocSize; - newPreallocSize += (1u< -void QCPDataContainer::performAutoSqueeze() -{ - const int totalAlloc = mData.capacity(); - const int postAllocSize = totalAlloc-mData.size(); - const int usedSize = size(); - bool shrinkPostAllocation = false; - bool shrinkPreAllocation = false; - if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size - { - shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate! - shrinkPreAllocation = mPreallocSize*10 > usedSize; - } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother - { - shrinkPostAllocation = postAllocSize > usedSize*5; - shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller - } - - if (shrinkPreAllocation || shrinkPostAllocation) - squeeze(shrinkPreAllocation, shrinkPostAllocation); -} -/* end of 'src/datacontainer.cpp' */ - - -/* end of 'src/datacontainer.h' */ - - -/* including file 'src/plottable.h', size 8312 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPSelectionDecorator -{ - Q_GADGET -public: - QCPSelectionDecorator(); - virtual ~QCPSelectionDecorator(); - - // getters: - QPen pen() const { return mPen; } - QBrush brush() const { return mBrush; } - QCPScatterStyle scatterStyle() const { return mScatterStyle; } - QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; } - - // setters: - void setPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); - void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); - - // non-virtual methods: - void applyPen(QCPPainter *painter) const; - void applyBrush(QCPPainter *painter) const; - QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; - - // introduced virtual methods: - virtual void copyFrom(const QCPSelectionDecorator *other); - virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); - -protected: - // property members: - QPen mPen; - QBrush mBrush; - QCPScatterStyle mScatterStyle; - QCPScatterStyle::ScatterProperties mUsedScatterProperties; - // non-property members: - QCPAbstractPlottable *mPlottable; - - // introduced virtual methods: - virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); - -private: - Q_DISABLE_COPY(QCPSelectionDecorator) - friend class QCPAbstractPlottable; -}; -Q_DECLARE_METATYPE(QCPSelectionDecorator*) - - -class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) - Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) - Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) - Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) - Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged) - Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator) - /// \endcond -public: - QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPAbstractPlottable(); - - // getters: - QString name() const { return mName; } - QString desc() const { return mDesc; } - bool antialiasedFill() const { return mAntialiasedFill; } - bool antialiasedScatters() const { return mAntialiasedScatters; } - QPen pen() const { return mPen; } - QBrush brush() const { return mBrush; } - QCPAxis *keyAxis() const { return mKeyAxis.data(); } - QCPAxis *valueAxis() const { return mValueAxis.data(); } - QCP::SelectionType selectable() const { return mSelectable; } - bool selected() const { return !mSelection.isEmpty(); } - QCPDataSelection selection() const { return mSelection; } - QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } - - // setters: - void setName(const QString &name); - void setDesc(const QString &desc); - void setAntialiasedFill(bool enabled); - void setAntialiasedScatters(bool enabled); - void setPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setKeyAxis(QCPAxis *axis); - void setValueAxis(QCPAxis *axis); - Q_SLOT void setSelectable(QCP::SelectionType selectable); - Q_SLOT void setSelection(QCPDataSelection selection); - void setSelectionDecorator(QCPSelectionDecorator *decorator); - - // introduced virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; - virtual QCPPlottableInterface1D *interface1D() { return 0; } - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; - - // non-property methods: - void coordsToPixels(double key, double value, double &x, double &y) const; - const QPointF coordsToPixels(double key, double value) const; - void pixelsToCoords(double x, double y, double &key, double &value) const; - void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; - void rescaleAxes(bool onlyEnlarge=false) const; - void rescaleKeyAxis(bool onlyEnlarge=false) const; - void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; - bool addToLegend(QCPLegend *legend); - bool addToLegend(); - bool removeFromLegend(QCPLegend *legend) const; - bool removeFromLegend() const; - -signals: - void selectionChanged(bool selected); - void selectionChanged(const QCPDataSelection &selection); - void selectableChanged(QCP::SelectionType selectable); - -protected: - // property members: - QString mName; - QString mDesc; - bool mAntialiasedFill, mAntialiasedScatters; - QPen mPen; - QBrush mBrush; - QPointer mKeyAxis, mValueAxis; - QCP::SelectionType mSelectable; - QCPDataSelection mSelection; - QCPSelectionDecorator *mSelectionDecorator; - - // reimplemented virtual methods: - virtual QRect clipRect() const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; - - // non-virtual methods: - void applyFillAntialiasingHint(QCPPainter *painter) const; - void applyScattersAntialiasingHint(QCPPainter *painter) const; - -private: - Q_DISABLE_COPY(QCPAbstractPlottable) - - friend class QCustomPlot; - friend class QCPAxis; - friend class QCPPlottableLegendItem; -}; - - -/* end of 'src/plottable.h' */ - - -/* including file 'src/item.h', size 9384 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemAnchor -{ - Q_GADGET -public: - QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); - virtual ~QCPItemAnchor(); - - // getters: - QString name() const { return mName; } - virtual QPointF pixelPosition() const; - -protected: - // property members: - QString mName; - - // non-property members: - QCustomPlot *mParentPlot; - QCPAbstractItem *mParentItem; - int mAnchorId; - QSet mChildrenX, mChildrenY; - - // introduced virtual methods: - virtual QCPItemPosition *toQCPItemPosition() { return 0; } - - // non-virtual methods: - void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent - void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted - void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent - void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted - -private: - Q_DISABLE_COPY(QCPItemAnchor) - - friend class QCPItemPosition; -}; - - - -class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor -{ - Q_GADGET -public: - /*! - Defines the ways an item position can be specified. Thus it defines what the numbers passed to - \ref setCoords actually mean. - - \see setType - */ - enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. - ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top - ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and - ///< vertically at the top of the viewport/widget, etc. - ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top - ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and - ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. - ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). - }; - Q_ENUMS(PositionType) - - QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name); - virtual ~QCPItemPosition(); - - // getters: - PositionType type() const { return typeX(); } - PositionType typeX() const { return mPositionTypeX; } - PositionType typeY() const { return mPositionTypeY; } - QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } - QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } - QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } - double key() const { return mKey; } - double value() const { return mValue; } - QPointF coords() const { return QPointF(mKey, mValue); } - QCPAxis *keyAxis() const { return mKeyAxis.data(); } - QCPAxis *valueAxis() const { return mValueAxis.data(); } - QCPAxisRect *axisRect() const; - virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; - - // setters: - void setType(PositionType type); - void setTypeX(PositionType type); - void setTypeY(PositionType type); - bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); - bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); - bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); - void setCoords(double key, double value); - void setCoords(const QPointF &coords); - void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); - void setAxisRect(QCPAxisRect *axisRect); - void setPixelPosition(const QPointF &pixelPosition); - -protected: - // property members: - PositionType mPositionTypeX, mPositionTypeY; - QPointer mKeyAxis, mValueAxis; - QPointer mAxisRect; - double mKey, mValue; - QCPItemAnchor *mParentAnchorX, *mParentAnchorY; - - // reimplemented virtual methods: - virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } - -private: - Q_DISABLE_COPY(QCPItemPosition) - -}; -Q_DECLARE_METATYPE(QCPItemPosition::PositionType) - - -class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) - Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) - Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) - Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) - /// \endcond -public: - explicit QCPAbstractItem(QCustomPlot *parentPlot); - virtual ~QCPAbstractItem(); - - // getters: - bool clipToAxisRect() const { return mClipToAxisRect; } - QCPAxisRect *clipAxisRect() const; - bool selectable() const { return mSelectable; } - bool selected() const { return mSelected; } - - // setters: - void setClipToAxisRect(bool clip); - void setClipAxisRect(QCPAxisRect *rect); - Q_SLOT void setSelectable(bool selectable); - Q_SLOT void setSelected(bool selected); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE = 0; - - // non-virtual methods: - QList positions() const { return mPositions; } - QList anchors() const { return mAnchors; } - QCPItemPosition *position(const QString &name) const; - QCPItemAnchor *anchor(const QString &name) const; - bool hasAnchor(const QString &name) const; - -signals: - void selectionChanged(bool selected); - void selectableChanged(bool selectable); - -protected: - // property members: - bool mClipToAxisRect; - QPointer mClipAxisRect; - QList mPositions; - QList mAnchors; - bool mSelectable, mSelected; - - // reimplemented virtual methods: - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - virtual QRect clipRect() const Q_DECL_OVERRIDE; - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual QPointF anchorPixelPosition(int anchorId) const; - - // non-virtual methods: - double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const; - QCPItemPosition *createPosition(const QString &name); - QCPItemAnchor *createAnchor(const QString &name, int anchorId); - -private: - Q_DISABLE_COPY(QCPAbstractItem) - - friend class QCustomPlot; - friend class QCPItemAnchor; -}; - -/* end of 'src/item.h' */ - - -/* including file 'src/core.h', size 14886 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCustomPlot : public QWidget -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) - Q_PROPERTY(QPixmap background READ background WRITE setBackground) - Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) - Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) - Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) - Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) - Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) - Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) - Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) - Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl) - /// \endcond -public: - /*! - Defines how a layer should be inserted relative to an other layer. - - \see addLayer, moveLayer - */ - enum LayerInsertMode { limBelow ///< Layer is inserted below other layer - ,limAbove ///< Layer is inserted above other layer - }; - Q_ENUMS(LayerInsertMode) - - /*! - Defines with what timing the QCustomPlot surface is refreshed after a replot. - - \see replot - */ - enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot - ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided. - ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints. - ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. - }; - Q_ENUMS(RefreshPriority) - - explicit QCustomPlot(QWidget *parent = 0); - virtual ~QCustomPlot(); - - // getters: - QRect viewport() const { return mViewport; } - double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } - QPixmap background() const { return mBackgroundPixmap; } - bool backgroundScaled() const { return mBackgroundScaled; } - Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } - QCPLayoutGrid *plotLayout() const { return mPlotLayout; } - QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } - QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } - bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } - const QCP::Interactions interactions() const { return mInteractions; } - int selectionTolerance() const { return mSelectionTolerance; } - bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } - QCP::PlottingHints plottingHints() const { return mPlottingHints; } - Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } - QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } - QCPSelectionRect *selectionRect() const { return mSelectionRect; } - bool openGl() const { return mOpenGl; } - QPoint symbolPos() { return mSymbolPos; } - - // setters: - void setSymbolPos(const QPoint pos); - void setViewport(const QRect &rect); - void setBufferDevicePixelRatio(double ratio); - void setBackground(const QPixmap &pm); - void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); - void setBackground(const QBrush &brush); - void setBackgroundScaled(bool scaled); - void setBackgroundScaledMode(Qt::AspectRatioMode mode); - void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); - void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); - void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); - void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); - void setAutoAddPlottableToLegend(bool on); - void setInteractions(const QCP::Interactions &interactions); - void setInteraction(const QCP::Interaction &interaction, bool enabled=true); - void setSelectionTolerance(int pixels); - void setNoAntialiasingOnDrag(bool enabled); - void setPlottingHints(const QCP::PlottingHints &hints); - void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); - void setMultiSelectModifier(Qt::KeyboardModifier modifier); - void setSelectionRectMode(QCP::SelectionRectMode mode); - void setSelectionRect(QCPSelectionRect *selectionRect); - void setOpenGl(bool enabled, int multisampling=16); - - // non-property methods: - // plottable interface: - QCPAbstractPlottable *plottable(int index); - QCPAbstractPlottable *plottable(); - bool removePlottable(QCPAbstractPlottable *plottable); - bool removePlottable(int index); - int clearPlottables(); - int plottableCount() const; - QList selectedPlottables() const; - QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; - bool hasPlottable(QCPAbstractPlottable *plottable) const; - - // specialized interface for QCPGraph: - QCPGraph *graph(int index) const; - QCPGraph *graph() const; - QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); - bool removeGraph(QCPGraph *graph); - bool removeGraph(int index); - int clearGraphs(); - int graphCount() const; - QList selectedGraphs() const; - - // item interface: - QCPAbstractItem *item(int index) const; - QCPAbstractItem *item() const; - bool removeItem(QCPAbstractItem *item); - bool removeItem(int index); - int clearItems(bool clearTitle = false); - int itemCount() const; - QList selectedItems() const; - QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; - bool hasItem(QCPAbstractItem *item) const; - - // layer interface: - QCPLayer *layer(const QString &name) const; - QCPLayer *layer(int index) const; - QCPLayer *currentLayer() const; - bool setCurrentLayer(const QString &name); - bool setCurrentLayer(QCPLayer *layer); - int layerCount() const; - bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); - bool removeLayer(QCPLayer *layer); - bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); - - // axis rect/layout interface: - int axisRectCount() const; - QCPAxisRect* axisRect(int index=0) const; - QList axisRects() const; - QCPLayoutElement* layoutElementAt(const QPointF &pos) const; - QCPAxisRect* axisRectAt(const QPointF &pos) const; - Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); - - QList selectedAxes() const; - QList selectedLegends() const; - Q_SLOT void deselectAll(); - - bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); - bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); - bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); - bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); - bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); - QPixmap toPixmap(int width=0, int height=0, double scale=1.0); - void toPainter(QCPPainter *painter, int width=0, int height=0); - Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); - - QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; - QCPLegend *legend; - -signals: - void mouseDoubleClick(QMouseEvent *event); - void mousePress(QMouseEvent *event); - void mouseMove(QMouseEvent *event); - void mouseRelease(QMouseEvent *event); - void mouseWheel(QWheelEvent *event); - - //< 鼠标按下 更新CCurveLegendModel值 - void symbolPosChanged(const double &value); - - void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); - void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); - void itemClick(QCPAbstractItem *item, QMouseEvent *event); - void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); - void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); - void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); - void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); - void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); - - void selectionChangedByUser(); - void beforeReplot(); - void afterReplot(); - -protected: - // property members: - QRect mViewport; - double mBufferDevicePixelRatio; - QCPLayoutGrid *mPlotLayout; - bool mAutoAddPlottableToLegend; - QList mPlottables; - QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph - QList mItems; - QList mLayers; - QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; - QCP::Interactions mInteractions; - int mSelectionTolerance; - bool mNoAntialiasingOnDrag; - QBrush mBackgroundBrush; - QPixmap mBackgroundPixmap; - QPixmap mScaledBackgroundPixmap; - bool mBackgroundScaled; - Qt::AspectRatioMode mBackgroundScaledMode; - QCPLayer *mCurrentLayer; - QCP::PlottingHints mPlottingHints; - Qt::KeyboardModifier mMultiSelectModifier; - QCP::SelectionRectMode mSelectionRectMode; - QCPSelectionRect *mSelectionRect; - bool mOpenGl; - - // non-property members: - QList > mPaintBuffers; - bool mSymbolPressed; - QPoint mSymbolPos; - QPoint mMousePressPos; - bool mMouseHasMoved; - QPointer mMouseEventLayerable; - QPointer mMouseSignalLayerable; - QVariant mMouseEventLayerableDetails; - QVariant mMouseSignalLayerableDetails; - bool mReplotting; - bool mReplotQueued; - int mOpenGlMultisamples; - QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup; - bool mOpenGlCacheLabelsBackup; -#ifdef QCP_OPENGL_FBO - QSharedPointer mGlContext; - QSharedPointer mGlSurface; - QSharedPointer mGlPaintDevice; -#endif - - // reimplemented virtual methods: - virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; - virtual QSize sizeHint() const Q_DECL_OVERRIDE; - virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; - virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - - bool eventFilter(QObject *object, QEvent *event); - - // introduced virtual methods: - virtual void draw(QCPPainter *painter); - virtual void updateLayout(); - virtual void axisRemoved(QCPAxis *axis); - virtual void legendRemoved(QCPLegend *legend); - Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); - Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); - Q_SLOT virtual void processPointSelection(QMouseEvent *event); - - // non-virtual methods: - bool registerPlottable(QCPAbstractPlottable *plottable); - bool registerGraph(QCPGraph *graph); - bool registerItem(QCPAbstractItem* item); - void updateLayerIndices() const; - QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; - QList layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails=0) const; - void drawBackground(QCPPainter *painter); - void setupPaintBuffers(); - QCPAbstractPaintBuffer *createPaintBuffer(); - bool hasInvalidatedPaintBuffers(); - bool setupOpenGl(); - void freeOpenGl(); - - friend class QCPLegend; - friend class QCPAxis; - friend class QCPLayer; - friend class QCPAxisRect; - friend class QCPAbstractPlottable; - friend class QCPGraph; - friend class QCPAbstractItem; -}; -Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode) -Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) - -/* end of 'src/core.h' */ - - -/* including file 'src/plottable1d.h', size 4544 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCPPlottableInterface1D -{ -public: - virtual ~QCPPlottableInterface1D() {} - // introduced pure virtual methods: - virtual int dataCount() const = 0; - virtual double dataMainKey(int index) const = 0; - virtual double dataSortKey(int index) const = 0; - virtual double dataMainValue(int index) const = 0; - virtual QCPRange dataValueRange(int index) const = 0; - virtual QPointF dataPixelPosition(int index) const = 0; - virtual bool sortKeyIsMainKey() const = 0; - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; - virtual int findBegin(double sortKey, bool expandedRange=true) const = 0; - virtual int findEnd(double sortKey, bool expandedRange=true) const = 0; -}; - -template -class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below) -{ - // No Q_OBJECT macro due to template class - -public: - QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPAbstractPlottable1D(); - - // virtual methods of 1d plottable interface: - virtual int dataCount() const Q_DECL_OVERRIDE; - virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; - virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; - virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; - virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; - virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; - virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } - -protected: - // property members: - QSharedPointer > mDataContainer; - - // helpers for subclasses: - void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; - void drawPolyline(QCPPainter *painter, const QVector &lineData) const; - -private: - Q_DISABLE_COPY(QCPAbstractPlottable1D) - -}; - -// include implementation in header since it is a class template: - -/* including file 'src/plottable1d.cpp', size 22240 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPlottableInterface1D -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPlottableInterface1D - \brief Defines an abstract interface for one-dimensional plottables - - This class contains only pure virtual methods which define a common interface to the data - of one-dimensional plottables. - - For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred - base class for one-dimensional plottables). So if you use that template class as base class of - your one-dimensional plottable, you won't have to care about implementing the 1d interface - yourself. - - If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d - interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref - QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure - virtual methods of the 1d interface, matching your data container. Also, reimplement \ref - QCPAbstractPlottable::interface1D to return the \c this pointer. - - If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this - interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return - value. If it indeed implements this interface, you may use it to access the plottable's data - without needing to know the exact type of the plottable or its data point type. -*/ - -/* start documentation of pure virtual functions */ - -/*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; - - Returns the number of data points of the plottable. -*/ - -/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; - - Returns a data selection containing all the data points of this plottable which are contained (or - hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref - dataselection "data selection mechanism"). - - If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not - selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). - - \note \a rect must be a normalized rect (positive or zero width and height). This is especially - important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily - normalized. Use QRect::normalized() when passing a rect which might not be normalized. -*/ - -/*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 - - Returns the main key of the data point at the given \a index. - - What the main key is, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 - - Returns the sort key of the data point at the given \a index. - - What the sort key is, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 - - Returns the main value of the data point at the given \a index. - - What the main value is, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 - - Returns the value range of the data point at the given \a index. - - What the value range is, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0 - - Returns the pixel position on the widget surface at which the data point at the given \a index - appears. - - Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel - coordinates. However, depending on the plottable, this might be a different apparent position - than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data - values can be shifted depending on their stacking, bar grouping or configured base value. -*/ - -/*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0 - - Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey). - - What the sort and main keys are, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0 - - Returns the index of the data point with a (sort-)key that is equal to, just below, or just above - \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered, - otherwise the one just above. - - This can be used in conjunction with \ref findEnd to iterate over data points within a given key - range, including or excluding the bounding data points that are just beyond the specified range. - - If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned. - - If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop - using these methods will not iterate over the index 0). - - \see findEnd, QCPDataContainer::findBegin -*/ - -/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0 - - Returns the index one after the data point with a (sort-)key that is equal to, just above, or - just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be - considered, otherwise the one just below. - - This can be used in conjunction with \ref findBegin to iterate over data points within a given - key range, including the bounding data points that are just below and above the specified range. - - If \a expandedRange is true but there are no data points above \a sortKey, the index just above the - highest data point is returned. - - If the container is empty, returns 0. - - \see findBegin, QCPDataContainer::findEnd -*/ - -/* end documentation of pure virtual functions */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractPlottable1D -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractPlottable1D - \brief A template base class for plottables with one-dimensional data - - This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref - QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with - one key dimension), such as \ref QCPGraph and QCPCurve. - - The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref - QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member - \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer") and - implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most - subclassed plottables don't need to worry about this anymore. - - Further, it provides a convenience method for retrieving selected/unselected data segments via - \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to - draw selected segments with a different pen/brush than unselected segments (also see \ref - QCPSelectionDecorator). - - This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref - QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data - interface. In spite of that, most plottable subclasses will want to reimplement those methods - again, to provide a more accurate hit test based on their specific data visualization geometry. -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() - - Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D - interface. - - \seebaseclassmethod -*/ - -/* end documentation of inline functions */ - -/*! - Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable - "QCPAbstractPlottable" constructor and allocates the \a mDataContainer. -*/ -template -QCPAbstractPlottable1D::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable(keyAxis, valueAxis), - mDataContainer(new QCPDataContainer) -{ -} - -template -QCPAbstractPlottable1D::~QCPAbstractPlottable1D() -{ -} - -/*! - \copydoc QCPPlottableInterface1D::dataCount -*/ -template -int QCPAbstractPlottable1D::dataCount() const -{ - return mDataContainer->size(); -} - -/*! - \copydoc QCPPlottableInterface1D::dataMainKey -*/ -template -double QCPAbstractPlottable1D::dataMainKey(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - return (mDataContainer->constBegin()+index)->mainKey(); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return 0; - } -} - -/*! - \copydoc QCPPlottableInterface1D::dataSortKey -*/ -template -double QCPAbstractPlottable1D::dataSortKey(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - return (mDataContainer->constBegin()+index)->sortKey(); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return 0; - } -} - -/*! - \copydoc QCPPlottableInterface1D::dataMainValue -*/ -template -double QCPAbstractPlottable1D::dataMainValue(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - return (mDataContainer->constBegin()+index)->mainValue(); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return 0; - } -} - -/*! - \copydoc QCPPlottableInterface1D::dataValueRange -*/ -template -QCPRange QCPAbstractPlottable1D::dataValueRange(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - return (mDataContainer->constBegin()+index)->valueRange(); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return QCPRange(0, 0); - } -} - -/*! - \copydoc QCPPlottableInterface1D::dataPixelPosition -*/ -template -QPointF QCPAbstractPlottable1D::dataPixelPosition(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - const typename QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; - return coordsToPixels(it->mainKey(), it->mainValue()); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return QPointF(); - } -} - -/*! - \copydoc QCPPlottableInterface1D::sortKeyIsMainKey -*/ -template -bool QCPAbstractPlottable1D::sortKeyIsMainKey() const -{ - return DataType::sortKeyIsMainKey(); -} - -/*! - Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is - point-like. Most subclasses will want to reimplement this method again, to provide a more - accurate hit test based on the true data visualization geometry. - - \seebaseclassmethod -*/ -template -QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - // convert rect given in pixels to ranges given in plot coordinates: - double key1, value1, key2, value2; - pixelsToCoords(rect.topLeft(), key1, value1); - pixelsToCoords(rect.bottomRight(), key2, value2); - QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2 - QCPRange valueRange(value1, value2); - typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); - typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); - if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: - { - begin = mDataContainer->findBegin(keyRange.lower, false); - end = mDataContainer->findEnd(keyRange.upper, false); - } - if (begin == end) - return result; - - int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect - for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) - { - if (currentSegmentBegin == -1) - { - if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment - currentSegmentBegin = it-mDataContainer->constBegin(); - } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended - { - result.addDataRange(QCPDataRange(currentSegmentBegin, it-mDataContainer->constBegin()), false); - currentSegmentBegin = -1; - } - } - // process potential last segment: - if (currentSegmentBegin != -1) - result.addDataRange(QCPDataRange(currentSegmentBegin, end-mDataContainer->constBegin()), false); - - result.simplify(); - return result; -} - -/*! - \copydoc QCPPlottableInterface1D::findBegin -*/ -template -int QCPAbstractPlottable1D::findBegin(double sortKey, bool expandedRange) const -{ - return mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin(); -} - -/*! - \copydoc QCPPlottableInterface1D::findEnd -*/ -template -int QCPAbstractPlottable1D::findEnd(double sortKey, bool expandedRange) const -{ - return mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin(); -} - -/*! - Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is - point-like. Most subclasses will want to reimplement this method again, to provide a more - accurate hit test based on the true data visualization geometry. - - \seebaseclassmethod -*/ -template -double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - QCPDataSelection selectionResult; - double minDistSqr = std::numeric_limits::max(); - int minDistIndex = mDataContainer->size(); - - typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); - typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); - if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: - { - // determine which key range comes into question, taking selection tolerance around pos into account: - double posKeyMin, posKeyMax, dummy; - pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); - pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); - if (posKeyMin > posKeyMax) - qSwap(posKeyMin, posKeyMax); - begin = mDataContainer->findBegin(posKeyMin, true); - end = mDataContainer->findEnd(posKeyMax, true); - } - if (begin == end) - return -1; - QCPRange keyRange(mKeyAxis->range()); - QCPRange valueRange(mValueAxis->range()); - for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) - { - const double mainKey = it->mainKey(); - const double mainValue = it->mainValue(); - if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points - { - const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared(); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - minDistIndex = it-mDataContainer->constBegin(); - } - } - } - if (minDistIndex != mDataContainer->size()) - selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false); - - selectionResult.simplify(); - if (details) - details->setValue(selectionResult); - return qSqrt(minDistSqr); -} - -/*! - Splits all data into selected and unselected segments and outputs them via \a selectedSegments - and \a unselectedSegments, respectively. - - This is useful when subclasses implement their \ref draw method and need to draw selected - segments with a different pen/brush than unselected segments (also see \ref - QCPSelectionDecorator). - - \see setSelection -*/ -template -void QCPAbstractPlottable1D::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const -{ - selectedSegments.clear(); - unselectedSegments.clear(); - if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty - { - if (selected()) - selectedSegments << QCPDataRange(0, dataCount()); - else - unselectedSegments << QCPDataRange(0, dataCount()); - } else - { - QCPDataSelection sel(selection()); - sel.simplify(); - selectedSegments = sel.dataRanges(); - unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); - } -} - -/*! - A helper method which draws a line with the passed \a painter, according to the pixel data in \a - lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is - the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or - crashing). - - Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c - QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter - style allows. -*/ -template -void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QVector &lineData) const -{ - // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: - if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && - painter->pen().style() == Qt::SolidLine && - !painter->modes().testFlag(QCPPainter::pmVectorized) && - !painter->modes().testFlag(QCPPainter::pmNoCaching)) - { - int i = 0; - bool lastIsNan = false; - const int lineDataSize = lineData.size(); - while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN - ++i; - ++i; // because drawing works in 1 point retrospect - while (i < lineDataSize) - { - if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line - { - if (!lastIsNan) - painter->drawLine(lineData.at(i-1), lineData.at(i)); - else - lastIsNan = false; - } else - lastIsNan = true; - ++i; - } - } else - { - int segmentStart = 0; - int i = 0; - const int lineDataSize = lineData.size(); - while (i < lineDataSize) - { - if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block - { - painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point - segmentStart = i+1; - } - ++i; - } - // draw last segment: - painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart); - } -} -/* end of 'src/plottable1d.cpp' */ - - -/* end of 'src/plottable1d.h' */ - - -/* including file 'src/colorgradient.h', size 6243 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPColorGradient -{ - Q_GADGET -public: - /*! - Defines the color spaces in which color interpolation between gradient stops can be performed. - - \see setColorInterpolation - */ - enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated - ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) - }; - Q_ENUMS(ColorInterpolation) - - /*! - Defines the available presets that can be loaded with \ref loadPreset. See the documentation - there for an image of the presets. - */ - enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) - ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) - ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) - ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) - ,gpCandy ///< Blue over pink to white - ,gpGeography ///< Colors suitable to represent different elevations on geographical maps - ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) - ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white - ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values - ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) - ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) - ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) - }; - Q_ENUMS(GradientPreset) - - QCPColorGradient(); - QCPColorGradient(GradientPreset preset); - bool operator==(const QCPColorGradient &other) const; - bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } - - // getters: - int levelCount() const { return mLevelCount; } - QMap colorStops() const { return mColorStops; } - ColorInterpolation colorInterpolation() const { return mColorInterpolation; } - bool periodic() const { return mPeriodic; } - - // setters: - void setLevelCount(int n); - void setColorStops(const QMap &colorStops); - void setColorStopAt(double position, const QColor &color); - void setColorInterpolation(ColorInterpolation interpolation); - void setPeriodic(bool enabled); - - // non-property methods: - void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); - void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); - QRgb color(double position, const QCPRange &range, bool logarithmic=false); - void loadPreset(GradientPreset preset); - void clearColorStops(); - QCPColorGradient inverted() const; - -protected: - // property members: - int mLevelCount; - QMap mColorStops; - ColorInterpolation mColorInterpolation; - bool mPeriodic; - - // non-property members: - QVector mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied) - bool mColorBufferInvalidated; - - // non-virtual methods: - bool stopsUseAlpha() const; - void updateColorBuffer(); -}; -Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation) -Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) - -/* end of 'src/colorgradient.h' */ - - -/* including file 'src/selectiondecorator-bracket.h', size 4442 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator -{ - Q_GADGET -public: - - /*! - Defines which shape is drawn at the boundaries of selected data ranges. - - Some of the bracket styles further allow specifying a height and/or width, see \ref - setBracketHeight and \ref setBracketWidth. - */ - enum BracketStyle { bsSquareBracket ///< A square bracket is drawn. - ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. - ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. - ,bsPlus ///< A plus is drawn. - ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket. - }; - Q_ENUMS(BracketStyle) - - QCPSelectionDecoratorBracket(); - virtual ~QCPSelectionDecoratorBracket(); - - // getters: - QPen bracketPen() const { return mBracketPen; } - QBrush bracketBrush() const { return mBracketBrush; } - int bracketWidth() const { return mBracketWidth; } - int bracketHeight() const { return mBracketHeight; } - BracketStyle bracketStyle() const { return mBracketStyle; } - bool tangentToData() const { return mTangentToData; } - int tangentAverage() const { return mTangentAverage; } - - // setters: - void setBracketPen(const QPen &pen); - void setBracketBrush(const QBrush &brush); - void setBracketWidth(int width); - void setBracketHeight(int height); - void setBracketStyle(BracketStyle style); - void setTangentToData(bool enabled); - void setTangentAverage(int pointCount); - - // introduced virtual methods: - virtual void drawBracket(QCPPainter *painter, int direction) const; - - // virtual methods: - virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; - -protected: - // property members: - QPen mBracketPen; - QBrush mBracketBrush; - int mBracketWidth; - int mBracketHeight; - BracketStyle mBracketStyle; - bool mTangentToData; - int mTangentAverage; - - // non-virtual methods: - double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const; - QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; - -}; -Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) - -/* end of 'src/selectiondecorator-bracket.h' */ - - -/* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPixmap background READ background WRITE setBackground) - Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) - Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) - Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) - Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) - /// \endcond -public: - explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); - virtual ~QCPAxisRect(); - - // getters: - QPixmap background() const { return mBackgroundPixmap; } - QBrush backgroundBrush() const { return mBackgroundBrush; } - bool backgroundScaled() const { return mBackgroundScaled; } - Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } - Qt::Orientations rangeDrag() const { return mRangeDrag; } - Qt::Orientations rangeZoom() const { return mRangeZoom; } - QCPAxis *rangeDragAxis(Qt::Orientation orientation); - QCPAxis *rangeZoomAxis(Qt::Orientation orientation); - QList rangeDragAxes(Qt::Orientation orientation); - QList rangeZoomAxes(Qt::Orientation orientation); - double rangeZoomFactor(Qt::Orientation orientation); - - // setters: - void setBackground(const QPixmap &pm); - void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); - void setBackground(const QBrush &brush); - void setBackgroundScaled(bool scaled); - void setBackgroundScaledMode(Qt::AspectRatioMode mode); - void setRangeDrag(Qt::Orientations orientations); - void setRangeZoom(Qt::Orientations orientations); - void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); - void setRangeDragAxes(QList axes); - void setRangeDragAxes(QList horizontal, QList vertical); - void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); - void setRangeZoomAxes(QList axes); - void setRangeZoomAxes(QList horizontal, QList vertical); - void setRangeZoomFactor(double horizontalFactor, double verticalFactor); - void setRangeZoomFactor(double factor); - - // non-property methods: - int axisCount(QCPAxis::AxisType type) const; - QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; - QList axes(QCPAxis::AxisTypes types) const; - QList axes() const; - QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); - QList addAxes(QCPAxis::AxisTypes types); - bool removeAxis(QCPAxis *axis); - QCPLayoutInset *insetLayout() const { return mInsetLayout; } - - void zoom(const QRectF &pixelRect); - void zoom(const QRectF &pixelRect, const QList &affectedAxes); - void setupFullAxesBox(bool connectRanges=false); - QList plottables() const; - QList graphs() const; - QList items() const; - - // read-only interface imitating a QRect: - int left() const { return mRect.left(); } - int right() const { return mRect.right(); } - int top() const { return mRect.top(); } - int bottom() const { return mRect.bottom(); } - int width() const { return mRect.width(); } - int height() const { return mRect.height(); } - QSize size() const { return mRect.size(); } - QPoint topLeft() const { return mRect.topLeft(); } - QPoint topRight() const { return mRect.topRight(); } - QPoint bottomLeft() const { return mRect.bottomLeft(); } - QPoint bottomRight() const { return mRect.bottomRight(); } - QPoint center() const { return mRect.center(); } - - // reimplemented virtual methods: - virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; - virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; - - void setScaleRight(const bool &scaleRight = true) { mIsScaleRight = scaleRight; } - bool isScaleRight() { return mIsScaleRight; } - -signals: - void rangeDraged(); - void rangeScaled(); - -protected: - // property members: - QBrush mBackgroundBrush; - QPixmap mBackgroundPixmap; - QPixmap mScaledBackgroundPixmap; - bool mBackgroundScaled; - Qt::AspectRatioMode mBackgroundScaledMode; - QCPLayoutInset *mInsetLayout; - Qt::Orientations mRangeDrag, mRangeZoom; - QList > mRangeDragHorzAxis, mRangeDragVertAxis; - QList > mRangeZoomHorzAxis, mRangeZoomVertAxis; - double mRangeZoomFactorHorz, mRangeZoomFactorVert; - - // non-property members: - QList mDragStartHorzRange, mDragStartVertRange; - QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; - bool mDragging; - QHash > mAxes; - - //< ZH - bool mIsScaleRight; - bool mIsDragMove; - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE; - virtual void layoutChanged() Q_DECL_OVERRIDE; - // events: - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - - // non-property methods: - void drawBackground(QCPPainter *painter); - void updateAxesOffset(QCPAxis::AxisType type); - -private: - Q_DISABLE_COPY(QCPAxisRect) - - friend class QCustomPlot; -}; - - -/* end of 'src/layoutelements/layoutelement-axisrect.h' */ - - -/* including file 'src/layoutelements/layoutelement-legend.h', size 10397 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) - Q_PROPERTY(QFont font READ font WRITE setFont) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) - Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) - Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) - Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) - /// \endcond -public: - explicit QCPAbstractLegendItem(QCPLegend *parent); - - // getters: - QCPLegend *parentLegend() const { return mParentLegend; } - QFont font() const { return mFont; } - QColor textColor() const { return mTextColor; } - QFont selectedFont() const { return mSelectedFont; } - QColor selectedTextColor() const { return mSelectedTextColor; } - bool selectable() const { return mSelectable; } - bool selected() const { return mSelected; } - - // setters: - void setFont(const QFont &font); - void setTextColor(const QColor &color); - void setSelectedFont(const QFont &font); - void setSelectedTextColor(const QColor &color); - Q_SLOT void setSelectable(bool selectable); - Q_SLOT void setSelected(bool selected); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - -signals: - void selectionChanged(bool selected); - void selectableChanged(bool selectable); - -protected: - // property members: - QCPLegend *mParentLegend; - QFont mFont; - QColor mTextColor; - QFont mSelectedFont; - QColor mSelectedTextColor; - bool mSelectable, mSelected; - - // reimplemented virtual methods: - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual QRect clipRect() const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - -private: - Q_DISABLE_COPY(QCPAbstractLegendItem) - - friend class QCPLegend; -}; - - -class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem -{ - Q_OBJECT -public: - QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); - - // getters: - QCPAbstractPlottable *plottable() { return mPlottable; } - -protected: - // property members: - QCPAbstractPlottable *mPlottable; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen getIconBorderPen() const; - QColor getTextColor() const; - QFont getFont() const; -}; - - -class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QFont font READ font WRITE setFont) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) - Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) - Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) - Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) - Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) - Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) - Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) - Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) - /// \endcond -public: - /*! - Defines the selectable parts of a legend - - \see setSelectedParts, setSelectableParts - */ - enum SelectablePart { spNone = 0x000 ///< 0x000 None - ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) - ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) - }; - Q_ENUMS(SelectablePart) - Q_FLAGS(SelectableParts) - Q_DECLARE_FLAGS(SelectableParts, SelectablePart) - - explicit QCPLegend(); - virtual ~QCPLegend(); - - // getters: - QPen borderPen() const { return mBorderPen; } - QBrush brush() const { return mBrush; } - QFont font() const { return mFont; } - QColor textColor() const { return mTextColor; } - QSize iconSize() const { return mIconSize; } - int iconTextPadding() const { return mIconTextPadding; } - QPen iconBorderPen() const { return mIconBorderPen; } - SelectableParts selectableParts() const { return mSelectableParts; } - SelectableParts selectedParts() const; - QPen selectedBorderPen() const { return mSelectedBorderPen; } - QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } - QBrush selectedBrush() const { return mSelectedBrush; } - QFont selectedFont() const { return mSelectedFont; } - QColor selectedTextColor() const { return mSelectedTextColor; } - - // setters: - void setBorderPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setFont(const QFont &font); - void setTextColor(const QColor &color); - void setIconSize(const QSize &size); - void setIconSize(int width, int height); - void setIconTextPadding(int padding); - void setIconBorderPen(const QPen &pen); - Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); - Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); - void setSelectedBorderPen(const QPen &pen); - void setSelectedIconBorderPen(const QPen &pen); - void setSelectedBrush(const QBrush &brush); - void setSelectedFont(const QFont &font); - void setSelectedTextColor(const QColor &color); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QCPAbstractLegendItem *item(int index) const; - QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; - int itemCount() const; - bool hasItem(QCPAbstractLegendItem *item) const; - bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; - bool addItem(QCPAbstractLegendItem *item); - bool removeItem(int index); - bool removeItem(QCPAbstractLegendItem *item); - void clearItems(); - QList selectedItems() const; - -signals: - void selectionChanged(QCPLegend::SelectableParts parts); - void selectableChanged(QCPLegend::SelectableParts parts); - -protected: - // property members: - QPen mBorderPen, mIconBorderPen; - QBrush mBrush; - QFont mFont; - QColor mTextColor; - QSize mIconSize; - int mIconTextPadding; - SelectableParts mSelectedParts, mSelectableParts; - QPen mSelectedBorderPen, mSelectedIconBorderPen; - QBrush mSelectedBrush; - QFont mSelectedFont; - QColor mSelectedTextColor; - - // reimplemented virtual methods: - virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen getBorderPen() const; - QBrush getBrush() const; - -private: - Q_DISABLE_COPY(QCPLegend) - - friend class QCustomPlot; - friend class QCPAbstractLegendItem; -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) -Q_DECLARE_METATYPE(QCPLegend::SelectablePart) - -/* end of 'src/layoutelements/layoutelement-legend.h' */ - - -/* including file 'src/layoutelements/layoutelement-textelement.h', size 5353 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QString text READ text WRITE setText) - Q_PROPERTY(QFont font READ font WRITE setFont) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) - Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) - Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) - Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) - /// \endcond -public: - explicit QCPTextElement(QCustomPlot *parentPlot); - QCPTextElement(QCustomPlot *parentPlot, const QString &text); - QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); - QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize); - QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); - - // getters: - QString text() const { return mText; } - int textFlags() const { return mTextFlags; } - QFont font() const { return mFont; } - QColor textColor() const { return mTextColor; } - QFont selectedFont() const { return mSelectedFont; } - QColor selectedTextColor() const { return mSelectedTextColor; } - bool selectable() const { return mSelectable; } - bool selected() const { return mSelected; } - - // setters: - void setText(const QString &text); - void setTextFlags(int flags); - void setFont(const QFont &font); - void setTextColor(const QColor &color); - void setSelectedFont(const QFont &font); - void setSelectedTextColor(const QColor &color); - Q_SLOT void setSelectable(bool selectable); - Q_SLOT void setSelected(bool selected); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - -signals: - void selectionChanged(bool selected); - void selectableChanged(bool selectable); - void clicked(QMouseEvent *event); - void doubleClicked(QMouseEvent *event); - -protected: - // property members: - QString mText; - int mTextFlags; - QFont mFont; - QColor mTextColor; - QFont mSelectedFont; - QColor mSelectedTextColor; - QRect mTextBoundingRect; - bool mSelectable, mSelected; - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; - virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - - // non-virtual methods: - QFont mainFont() const; - QColor mainTextColor() const; - -private: - Q_DISABLE_COPY(QCPTextElement) -}; - - - -/* end of 'src/layoutelements/layoutelement-textelement.h' */ - - -/* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -class QCPColorScaleAxisRectPrivate : public QCPAxisRect -{ - Q_OBJECT -public: - explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); -protected: - QCPColorScale *mParentColorScale; - QImage mGradientImage; - bool mGradientImageInvalidated; - // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale - using QCPAxisRect::calculateAutoMargin; - using QCPAxisRect::mousePressEvent; - using QCPAxisRect::mouseMoveEvent; - using QCPAxisRect::mouseReleaseEvent; - using QCPAxisRect::wheelEvent; - using QCPAxisRect::update; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - void updateGradientImage(); - Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); - Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); - friend class QCPColorScale; -}; - - -class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) - Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) - Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) - Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) - Q_PROPERTY(QString label READ label WRITE setLabel) - Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) - Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) - Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) - /// \endcond -public: - explicit QCPColorScale(QCustomPlot *parentPlot); - virtual ~QCPColorScale(); - - // getters: - QCPAxis *axis() const { return mColorAxis.data(); } - QCPAxis::AxisType type() const { return mType; } - QCPRange dataRange() const { return mDataRange; } - QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } - QCPColorGradient gradient() const { return mGradient; } - QString label() const; - int barWidth () const { return mBarWidth; } - bool rangeDrag() const; - bool rangeZoom() const; - - // setters: - void setType(QCPAxis::AxisType type); - Q_SLOT void setDataRange(const QCPRange &dataRange); - Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); - Q_SLOT void setGradient(const QCPColorGradient &gradient); - void setLabel(const QString &str); - void setBarWidth(int width); - void setRangeDrag(bool enabled); - void setRangeZoom(bool enabled); - - // non-property methods: - QList colorMaps() const; - void rescaleDataRange(bool onlyVisibleMaps); - - // reimplemented virtual methods: - virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; - -signals: - void dataRangeChanged(const QCPRange &newRange); - void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); - void gradientChanged(const QCPColorGradient &newGradient); - -protected: - // property members: - QCPAxis::AxisType mType; - QCPRange mDataRange; - QCPAxis::ScaleType mDataScaleType; - QCPColorGradient mGradient; - int mBarWidth; - - // non-property members: - QPointer mAxisRect; - QPointer mColorAxis; - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - // events: - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - -private: - Q_DISABLE_COPY(QCPColorScale) - - friend class QCPColorScaleAxisRectPrivate; -}; - - -/* end of 'src/layoutelements/layoutelement-colorscale.h' */ - - -/* including file 'src/plottables/plottable-graph.h', size 9294 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPGraphData -{ -public: - QCPGraphData(); - QCPGraphData(double key, double value); - - inline double sortKey() const { return key; } - inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0); } - inline static bool sortKeyIsMainKey() { return true; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return value; } - - inline QCPRange valueRange() const { return QCPRange(value, value); } - - double key, value; -}; -Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPGraphDataContainer - - Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. - - This template instantiation is the container in which QCPGraph holds its data. For details about - the generic container, see the documentation of the class template \ref QCPDataContainer. - - \see QCPGraphData, QCPGraph::setData -*/ -typedef QCPDataContainer QCPGraphDataContainer; - -class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) - Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) - Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) - Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) - Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) - /// \endcond -public: - /*! - Defines how the graph's line is represented visually in the plot. The line is drawn with the - current pen of the graph (\ref setPen). - \see setLineStyle - */ - enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented - ///< with symbols according to the scatter style, see \ref setScatterStyle) - ,lsLine ///< data points are connected by a straight line - ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point - ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point - ,lsStepCenter ///< line is drawn as steps where the step is in between two data points - ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line - }; - Q_ENUMS(LineStyle) - - explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPGraph(); - - // getters: - QSharedPointer data() const { return mDataContainer; } - LineStyle lineStyle() const { return mLineStyle; } - QCPScatterStyle scatterStyle() const { return mScatterStyle; } - int scatterSkip() const { return mScatterSkip; } - QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } - bool adaptiveSampling() const { return mAdaptiveSampling; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); - void setLineStyle(LineStyle ls); - void setScatterStyle(const QCPScatterStyle &style); - void setScatterSkip(int skip); - void setChannelFillGraph(QCPGraph *targetGraph); - void setAdaptiveSampling(bool enabled); - - // non-property methods: - void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); - void addData(double key, double value); - - /** - * @brief value 根据key值,查找value - */ - double value(const double &key); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - -protected: - // property members: - LineStyle mLineStyle; - QCPScatterStyle mScatterStyle; - int mScatterSkip; - QPointer mChannelFillGraph; - bool mAdaptiveSampling; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual void drawFill(QCPPainter *painter, QVector *lines) const; - virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; - virtual void drawLinePlot(QCPPainter *painter, const QVector &lines) const; - virtual void drawImpulsePlot(QCPPainter *painter, const QVector &lines) const; - - virtual void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; - virtual void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; - - // non-virtual methods: - void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; - void getLines(QVector *lines, const QCPDataRange &dataRange) const; - void getScatters(QVector *scatters, const QCPDataRange &dataRange) const; - QVector dataToLines(const QVector &data) const; - QVector dataToStepLeftLines(const QVector &data) const; - QVector dataToStepRightLines(const QVector &data) const; - QVector dataToStepCenterLines(const QVector &data) const; - QVector dataToImpulseLines(const QVector &data) const; - QVector getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const; - QVector > getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const; - bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const; - QPointF getFillBasePoint(QPointF matchingDataPoint) const; - const QPolygonF getFillPolygon(const QVector *lineData, QCPDataRange segment) const; - const QPolygonF getChannelFillPolygon(const QVector *lineData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const; - int findIndexBelowX(const QVector *data, double x) const; - int findIndexAboveX(const QVector *data, double x) const; - int findIndexBelowY(const QVector *data, double y) const; - int findIndexAboveY(const QVector *data, double y) const; - double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; -Q_DECLARE_METATYPE(QCPGraph::LineStyle) - -/* end of 'src/plottables/plottable-graph.h' */ - - -/* including file 'src/plottables/plottable-curve.h', size 7409 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPCurveData -{ -public: - QCPCurveData(); - QCPCurveData(double t, double key, double value); - - inline double sortKey() const { return t; } - inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } - inline static bool sortKeyIsMainKey() { return false; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return value; } - - inline QCPRange valueRange() const { return QCPRange(value, value); } - - double t, key, value; -}; -Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPCurveDataContainer - - Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a - sortKey() (returning \a t) is different from \a mainKey() (returning \a key). - - This template instantiation is the container in which QCPCurve holds its data. For details about - the generic container, see the documentation of the class template \ref QCPDataContainer. - - \see QCPCurveData, QCPCurve::setData -*/ -typedef QCPDataContainer QCPCurveDataContainer; - -class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) - Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) - Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) - /// \endcond -public: - /*! - Defines how the curve's line is represented visually in the plot. The line is drawn with the - current pen of the curve (\ref setPen). - \see setLineStyle - */ - enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) - ,lsLine ///< Data points are connected with a straight line - }; - Q_ENUMS(LineStyle) - - explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPCurve(); - - // getters: - QSharedPointer data() const { return mDataContainer; } - QCPScatterStyle scatterStyle() const { return mScatterStyle; } - int scatterSkip() const { return mScatterSkip; } - LineStyle lineStyle() const { return mLineStyle; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); - void setData(const QVector &keys, const QVector &values); - void setScatterStyle(const QCPScatterStyle &style); - void setScatterSkip(int skip); - void setLineStyle(LineStyle style); - - // non-property methods: - void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); - void addData(const QVector &keys, const QVector &values); - void addData(double t, double key, double value); - void addData(double key, double value); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - -protected: - // property members: - QCPScatterStyle mScatterStyle; - int mScatterSkip; - LineStyle mLineStyle; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual void drawCurveLine(QCPPainter *painter, const QVector &lines) const; - virtual void drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const; - - // non-virtual methods: - void getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const; - void getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const; - int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; - QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; - QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; - bool mayTraverse(int prevRegion, int currentRegion) const; - bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const; - void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const; - double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; -Q_DECLARE_METATYPE(QCPCurve::LineStyle) - -/* end of 'src/plottables/plottable-curve.h' */ - - -/* including file 'src/plottables/plottable-bars.h', size 8924 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPBarsGroup : public QObject -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) - Q_PROPERTY(double spacing READ spacing WRITE setSpacing) - /// \endcond -public: - /*! - Defines the ways the spacing between bars in the group can be specified. Thus it defines what - the number passed to \ref setSpacing actually means. - - \see setSpacingType, setSpacing - */ - enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels - ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size - ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range - }; - Q_ENUMS(SpacingType) - - QCPBarsGroup(QCustomPlot *parentPlot); - virtual ~QCPBarsGroup(); - - // getters: - SpacingType spacingType() const { return mSpacingType; } - double spacing() const { return mSpacing; } - - // setters: - void setSpacingType(SpacingType spacingType); - void setSpacing(double spacing); - - // non-virtual methods: - QList bars() const { return mBars; } - QCPBars* bars(int index) const; - int size() const { return mBars.size(); } - bool isEmpty() const { return mBars.isEmpty(); } - void clear(); - bool contains(QCPBars *bars) const { return mBars.contains(bars); } - void append(QCPBars *bars); - void insert(int i, QCPBars *bars); - void remove(QCPBars *bars); - -protected: - // non-property members: - QCustomPlot *mParentPlot; - SpacingType mSpacingType; - double mSpacing; - QList mBars; - - // non-virtual methods: - void registerBars(QCPBars *bars); - void unregisterBars(QCPBars *bars); - - // virtual methods: - double keyPixelOffset(const QCPBars *bars, double keyCoord); - double getPixelSpacing(const QCPBars *bars, double keyCoord); - -private: - Q_DISABLE_COPY(QCPBarsGroup) - - friend class QCPBars; -}; -Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) - - -class QCP_LIB_DECL QCPBarsData -{ -public: - QCPBarsData(); - QCPBarsData(double key, double value); - - inline double sortKey() const { return key; } - inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } - inline static bool sortKeyIsMainKey() { return true; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return value; } - - inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here - - double key, value; -}; -Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPBarsDataContainer - - Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. - - This template instantiation is the container in which QCPBars holds its data. For details about - the generic container, see the documentation of the class template \ref QCPDataContainer. - - \see QCPBarsData, QCPBars::setData -*/ -typedef QCPDataContainer QCPBarsDataContainer; - -class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(double width READ width WRITE setWidth) - Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) - Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) - Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) - Q_PROPERTY(double stackingGap READ stackingGap WRITE setStackingGap) - Q_PROPERTY(QCPBars* barBelow READ barBelow) - Q_PROPERTY(QCPBars* barAbove READ barAbove) - /// \endcond -public: - /*! - Defines the ways the width of the bar can be specified. Thus it defines what the number passed - to \ref setWidth actually means. - - \see setWidthType, setWidth - */ - enum WidthType { wtAbsolute ///< Bar width is in absolute pixels - ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size - ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range - }; - Q_ENUMS(WidthType) - - explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPBars(); - - // getters: - double width() const { return mWidth; } - WidthType widthType() const { return mWidthType; } - QCPBarsGroup *barsGroup() const { return mBarsGroup; } - double baseValue() const { return mBaseValue; } - double stackingGap() const { return mStackingGap; } - QCPBars *barBelow() const { return mBarBelow.data(); } - QCPBars *barAbove() const { return mBarAbove.data(); } - QSharedPointer data() const { return mDataContainer; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); - void setWidth(double width); - void setWidthType(WidthType widthType); - void setBarsGroup(QCPBarsGroup *barsGroup); - void setBaseValue(double baseValue); - void setStackingGap(double pixels); - - // non-property methods: - void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); - void addData(double key, double value); - void moveBelow(QCPBars *bars); - void moveAbove(QCPBars *bars); - - // reimplemented virtual methods: - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; - -protected: - // property members: - double mWidth; - WidthType mWidthType; - QCPBarsGroup *mBarsGroup; - double mBaseValue; - double mStackingGap; - QPointer mBarBelow, mBarAbove; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const; - QRectF getBarRect(double key, double value) const; - void getPixelWidth(double key, double &lower, double &upper) const; - double getStackedBaseValue(double key, bool positive) const; - static void connectBars(QCPBars* lower, QCPBars* upper); - - friend class QCustomPlot; - friend class QCPLegend; - friend class QCPBarsGroup; -}; -Q_DECLARE_METATYPE(QCPBars::WidthType) - -/* end of 'src/plottables/plottable-bars.h' */ - - -/* including file 'src/plottables/plottable-statisticalbox.h', size 7516 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPStatisticalBoxData -{ -public: - QCPStatisticalBoxData(); - QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector& outliers=QVector()); - - inline double sortKey() const { return key; } - inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); } - inline static bool sortKeyIsMainKey() { return true; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return median; } - - inline QCPRange valueRange() const - { - QCPRange result(minimum, maximum); - for (QVector::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); ++it) - result.expand(*it); - return result; - } - - double key, minimum, lowerQuartile, median, upperQuartile, maximum; - QVector outliers; -}; -Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); - - -/*! \typedef QCPStatisticalBoxDataContainer - - Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. - - This template instantiation is the container in which QCPStatisticalBox holds its data. For - details about the generic container, see the documentation of the class template \ref - QCPDataContainer. - - \see QCPStatisticalBoxData, QCPStatisticalBox::setData -*/ -typedef QCPDataContainer QCPStatisticalBoxDataContainer; - -class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(double width READ width WRITE setWidth) - Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) - Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) - Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) - Q_PROPERTY(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased) - Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) - Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) - /// \endcond -public: - explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); - - // getters: - QSharedPointer data() const { return mDataContainer; } - double width() const { return mWidth; } - double whiskerWidth() const { return mWhiskerWidth; } - QPen whiskerPen() const { return mWhiskerPen; } - QPen whiskerBarPen() const { return mWhiskerBarPen; } - bool whiskerAntialiased() const { return mWhiskerAntialiased; } - QPen medianPen() const { return mMedianPen; } - QCPScatterStyle outlierStyle() const { return mOutlierStyle; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); - void setWidth(double width); - void setWhiskerWidth(double width); - void setWhiskerPen(const QPen &pen); - void setWhiskerBarPen(const QPen &pen); - void setWhiskerAntialiased(bool enabled); - void setMedianPen(const QPen &pen); - void setOutlierStyle(const QCPScatterStyle &style); - - // non-property methods: - void addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); - void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers=QVector()); - - // reimplemented virtual methods: - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - -protected: - // property members: - double mWidth; - double mWhiskerWidth; - QPen mWhiskerPen, mWhiskerBarPen; - bool mWhiskerAntialiased; - QPen mMedianPen; - QCPScatterStyle mOutlierStyle; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const; - - // non-virtual methods: - void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const; - QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const; - QVector getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; - QVector getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; - -/* end of 'src/plottables/plottable-statisticalbox.h' */ - - -/* including file 'src/plottables/plottable-colormap.h', size 7070 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPColorMapData -{ -public: - QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); - ~QCPColorMapData(); - QCPColorMapData(const QCPColorMapData &other); - QCPColorMapData &operator=(const QCPColorMapData &other); - - // getters: - int keySize() const { return mKeySize; } - int valueSize() const { return mValueSize; } - QCPRange keyRange() const { return mKeyRange; } - QCPRange valueRange() const { return mValueRange; } - QCPRange dataBounds() const { return mDataBounds; } - double data(double key, double value); - double cell(int keyIndex, int valueIndex); - unsigned char alpha(int keyIndex, int valueIndex); - - // setters: - void setSize(int keySize, int valueSize); - void setKeySize(int keySize); - void setValueSize(int valueSize); - void setRange(const QCPRange &keyRange, const QCPRange &valueRange); - void setKeyRange(const QCPRange &keyRange); - void setValueRange(const QCPRange &valueRange); - void setData(double key, double value, double z); - void setCell(int keyIndex, int valueIndex, double z); - void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); - - // non-property methods: - void recalculateDataBounds(); - void clear(); - void clearAlpha(); - void fill(double z); - void fillAlpha(unsigned char alpha); - bool isEmpty() const { return mIsEmpty; } - void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; - void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; - -protected: - // property members: - int mKeySize, mValueSize; - QCPRange mKeyRange, mValueRange; - bool mIsEmpty; - - // non-property members: - double *mData; - unsigned char *mAlpha; - QCPRange mDataBounds; - bool mDataModified; - - bool createAlpha(bool initializeOpaque=true); - - friend class QCPColorMap; -}; - - -class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) - Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) - Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) - Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) - Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) - Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) - /// \endcond -public: - explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPColorMap(); - - // getters: - QCPColorMapData *data() const { return mMapData; } - QCPRange dataRange() const { return mDataRange; } - QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } - bool interpolate() const { return mInterpolate; } - bool tightBoundary() const { return mTightBoundary; } - QCPColorGradient gradient() const { return mGradient; } - QCPColorScale *colorScale() const { return mColorScale.data(); } - - // setters: - void setData(QCPColorMapData *data, bool copy=false); - Q_SLOT void setDataRange(const QCPRange &dataRange); - Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); - Q_SLOT void setGradient(const QCPColorGradient &gradient); - void setInterpolate(bool enabled); - void setTightBoundary(bool enabled); - void setColorScale(QCPColorScale *colorScale); - - // non-property methods: - void rescaleDataRange(bool recalculateDataBounds=false); - Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - -signals: - void dataRangeChanged(const QCPRange &newRange); - void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); - void gradientChanged(const QCPColorGradient &newGradient); - -protected: - // property members: - QCPRange mDataRange; - QCPAxis::ScaleType mDataScaleType; - QCPColorMapData *mMapData; - QCPColorGradient mGradient; - bool mInterpolate; - bool mTightBoundary; - QPointer mColorScale; - - // non-property members: - QImage mMapImage, mUndersampledMapImage; - QPixmap mLegendIcon; - bool mMapImageInvalidated; - - // introduced virtual methods: - virtual void updateMapImage(); - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - friend class QCustomPlot; - friend class QCPLegend; -}; - -/* end of 'src/plottables/plottable-colormap.h' */ - - -/* including file 'src/plottables/plottable-financial.h', size 8622 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPFinancialData -{ -public: - QCPFinancialData(); - QCPFinancialData(double key, double open, double high, double low, double close); - - inline double sortKey() const { return key; } - inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); } - inline static bool sortKeyIsMainKey() { return true; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return open; } - - inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them - - double key, open, high, low, close; -}; -Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPFinancialDataContainer - - Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. - - This template instantiation is the container in which QCPFinancial holds its data. For details - about the generic container, see the documentation of the class template \ref QCPDataContainer. - - \see QCPFinancialData, QCPFinancial::setData -*/ -typedef QCPDataContainer QCPFinancialDataContainer; - -class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) - Q_PROPERTY(double width READ width WRITE setWidth) - Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) - Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) - Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) - Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) - Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) - Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) - /// \endcond -public: - /*! - Defines the ways the width of the financial bar can be specified. Thus it defines what the - number passed to \ref setWidth actually means. - - \see setWidthType, setWidth - */ - enum WidthType { wtAbsolute ///< width is in absolute pixels - ,wtAxisRectRatio ///< width is given by a fraction of the axis rect size - ,wtPlotCoords ///< width is in key coordinates and thus scales with the key axis range - }; - Q_ENUMS(WidthType) - - /*! - Defines the possible representations of OHLC data in the plot. - - \see setChartStyle - */ - enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation - ,csCandlestick ///< Candlestick representation - }; - Q_ENUMS(ChartStyle) - - explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPFinancial(); - - // getters: - QSharedPointer data() const { return mDataContainer; } - ChartStyle chartStyle() const { return mChartStyle; } - double width() const { return mWidth; } - WidthType widthType() const { return mWidthType; } - bool twoColored() const { return mTwoColored; } - QBrush brushPositive() const { return mBrushPositive; } - QBrush brushNegative() const { return mBrushNegative; } - QPen penPositive() const { return mPenPositive; } - QPen penNegative() const { return mPenNegative; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); - void setChartStyle(ChartStyle style); - void setWidth(double width); - void setWidthType(WidthType widthType); - void setTwoColored(bool twoColored); - void setBrushPositive(const QBrush &brush); - void setBrushNegative(const QBrush &brush); - void setPenPositive(const QPen &pen); - void setPenNegative(const QPen &pen); - - // non-property methods: - void addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); - void addData(double key, double open, double high, double low, double close); - - // reimplemented virtual methods: - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - - // static methods: - static QCPFinancialDataContainer timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); - -protected: - // property members: - ChartStyle mChartStyle; - double mWidth; - WidthType mWidthType; - bool mTwoColored; - QBrush mBrushPositive, mBrushNegative; - QPen mPenPositive, mPenNegative; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); - void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); - double getPixelWidth(double key, double keyPixel) const; - double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; - double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; - void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const; - QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; -Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) - -/* end of 'src/plottables/plottable-financial.h' */ - - -/* including file 'src/plottables/plottable-errorbar.h', size 7727 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPErrorBarsData -{ -public: - QCPErrorBarsData(); - explicit QCPErrorBarsData(double error); - QCPErrorBarsData(double errorMinus, double errorPlus); - - double errorMinus, errorPlus; -}; -Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPErrorBarsDataContainer - - Container for storing \ref QCPErrorBarsData points. It is a typedef for QVector<\ref - QCPErrorBarsData>. - - This is the container in which \ref QCPErrorBars holds its data. Unlike most other data - containers for plottables, it is not based on \ref QCPDataContainer. This is because the error - bars plottable is special in that it doesn't store its own key and value coordinate per error - bar. It adopts the key and value from the plottable to which the error bars shall be applied - (\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a - sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices - of the other plottable's data. - - \see QCPErrorBarsData, QCPErrorBars::setData -*/ -typedef QVector QCPErrorBarsDataContainer; - -class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QSharedPointer data READ data WRITE setData) - Q_PROPERTY(QCPAbstractPlottable* dataPlottable READ dataPlottable WRITE setDataPlottable) - Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) - Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) - Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap) - /// \endcond -public: - - /*! - Defines in which orientation the error bars shall appear. If your data needs both error - dimensions, create two \ref QCPErrorBars with different \ref ErrorType. - - \see setErrorType - */ - enum ErrorType { etKeyError ///< The errors are for the key dimension (bars appear parallel to the key axis) - ,etValueError ///< The errors are for the value dimension (bars appear parallel to the value axis) - }; - Q_ENUMS(ErrorType) - - explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPErrorBars(); - // getters: - QSharedPointer data() const { return mDataContainer; } - QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); } - ErrorType errorType() const { return mErrorType; } - double whiskerWidth() const { return mWhiskerWidth; } - double symbolGap() const { return mSymbolGap; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &error); - void setData(const QVector &errorMinus, const QVector &errorPlus); - void setDataPlottable(QCPAbstractPlottable* plottable); - void setErrorType(ErrorType type); - void setWhiskerWidth(double pixels); - void setSymbolGap(double pixels); - - // non-property methods: - void addData(const QVector &error); - void addData(const QVector &errorMinus, const QVector &errorPlus); - void addData(double error); - void addData(double errorMinus, double errorPlus); - - // virtual methods of 1d plottable interface: - virtual int dataCount() const Q_DECL_OVERRIDE; - virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; - virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; - virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; - virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; - virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; - virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } - -protected: - // property members: - QSharedPointer mDataContainer; - QPointer mDataPlottable; - ErrorType mErrorType; - double mWhiskerWidth; - double mSymbolGap; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const; - void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; - double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const; - // helpers: - void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; - bool errorBarVisible(int index) const; - bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; - -/* end of 'src/plottables/plottable-errorbar.h' */ - - -/* including file 'src/items/item-straightline.h', size 3117 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - /// \endcond -public: - explicit QCPItemStraightLine(QCustomPlot *parentPlot); - virtual ~QCPItemStraightLine(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const point1; - QCPItemPosition * const point2; - -protected: - // property members: - QPen mPen, mSelectedPen; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - // non-virtual methods: - QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, const QRect &rect) const; - QPen mainPen() const; -}; - -/* end of 'src/items/item-straightline.h' */ - - -/* including file 'src/items/item-line.h', size 3407 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) - Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) - /// \endcond -public: - explicit QCPItemLine(QCustomPlot *parentPlot); - virtual ~QCPItemLine(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QCPLineEnding head() const { return mHead; } - QCPLineEnding tail() const { return mTail; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setHead(const QCPLineEnding &head); - void setTail(const QCPLineEnding &tail); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const start; - QCPItemPosition * const end; - -protected: - // property members: - QPen mPen, mSelectedPen; - QCPLineEnding mHead, mTail; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - // non-virtual methods: - QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; - QPen mainPen() const; -}; - -/* end of 'src/items/item-line.h' */ - - -/* including file 'src/items/item-curve.h', size 3379 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) - Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) - /// \endcond -public: - explicit QCPItemCurve(QCustomPlot *parentPlot); - virtual ~QCPItemCurve(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QCPLineEnding head() const { return mHead; } - QCPLineEnding tail() const { return mTail; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setHead(const QCPLineEnding &head); - void setTail(const QCPLineEnding &tail); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const start; - QCPItemPosition * const startDir; - QCPItemPosition * const endDir; - QCPItemPosition * const end; - -protected: - // property members: - QPen mPen, mSelectedPen; - QCPLineEnding mHead, mTail; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen mainPen() const; -}; - -/* end of 'src/items/item-curve.h' */ - - -/* including file 'src/items/item-rect.h', size 3688 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - /// \endcond -public: - explicit QCPItemRect(QCustomPlot *parentPlot); - virtual ~QCPItemRect(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QBrush brush() const { return mBrush; } - QBrush selectedBrush() const { return mSelectedBrush; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setSelectedBrush(const QBrush &brush); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const topLeft; - QCPItemPosition * const bottomRight; - QCPItemAnchor * const top; - QCPItemAnchor * const topRight; - QCPItemAnchor * const right; - QCPItemAnchor * const bottom; - QCPItemAnchor * const bottomLeft; - QCPItemAnchor * const left; - -protected: - enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; - - // property members: - QPen mPen, mSelectedPen; - QBrush mBrush, mSelectedBrush; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen mainPen() const; - QBrush mainBrush() const; -}; - -/* end of 'src/items/item-rect.h' */ - - -/* including file 'src/items/item-text.h', size 5554 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemText : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - Q_PROPERTY(QFont font READ font WRITE setFont) - Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) - Q_PROPERTY(QString text READ text WRITE setText) - Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) - Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) - Q_PROPERTY(double rotation READ rotation WRITE setRotation) - Q_PROPERTY(QMargins padding READ padding WRITE setPadding) - /// \endcond -public: - explicit QCPItemText(QCustomPlot *parentPlot); - virtual ~QCPItemText(); - - // getters: - QColor color() const { return mColor; } - QColor selectedColor() const { return mSelectedColor; } - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QBrush brush() const { return mBrush; } - QBrush selectedBrush() const { return mSelectedBrush; } - QFont font() const { return mFont; } - QFont selectedFont() const { return mSelectedFont; } - QString text() const { return mText; } - Qt::Alignment positionAlignment() const { return mPositionAlignment; } - Qt::Alignment textAlignment() const { return mTextAlignment; } - double rotation() const { return mRotation; } - QMargins padding() const { return mPadding; } - - // setters; - void setColor(const QColor &color); - void setSelectedColor(const QColor &color); - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setSelectedBrush(const QBrush &brush); - void setFont(const QFont &font); - void setSelectedFont(const QFont &font); - void setText(const QString &text); - void setPositionAlignment(Qt::Alignment alignment); - void setTextAlignment(Qt::Alignment alignment); - void setRotation(double degrees); - void setPadding(const QMargins &padding); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const position; - QCPItemAnchor * const topLeft; - QCPItemAnchor * const top; - QCPItemAnchor * const topRight; - QCPItemAnchor * const right; - QCPItemAnchor * const bottomRight; - QCPItemAnchor * const bottom; - QCPItemAnchor * const bottomLeft; - QCPItemAnchor * const left; - -protected: - enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; - - // property members: - QColor mColor, mSelectedColor; - QPen mPen, mSelectedPen; - QBrush mBrush, mSelectedBrush; - QFont mFont, mSelectedFont; - QString mText; - Qt::Alignment mPositionAlignment; - Qt::Alignment mTextAlignment; - double mRotation; - QMargins mPadding; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; - QFont mainFont() const; - QColor mainColor() const; - QPen mainPen() const; - QBrush mainBrush() const; -}; - -/* end of 'src/items/item-text.h' */ - - -/* including file 'src/items/item-ellipse.h', size 3868 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - /// \endcond -public: - explicit QCPItemEllipse(QCustomPlot *parentPlot); - virtual ~QCPItemEllipse(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QBrush brush() const { return mBrush; } - QBrush selectedBrush() const { return mSelectedBrush; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setSelectedBrush(const QBrush &brush); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const topLeft; - QCPItemPosition * const bottomRight; - QCPItemAnchor * const topLeftRim; - QCPItemAnchor * const top; - QCPItemAnchor * const topRightRim; - QCPItemAnchor * const right; - QCPItemAnchor * const bottomRightRim; - QCPItemAnchor * const bottom; - QCPItemAnchor * const bottomLeftRim; - QCPItemAnchor * const left; - QCPItemAnchor * const center; - -protected: - enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; - - // property members: - QPen mPen, mSelectedPen; - QBrush mBrush, mSelectedBrush; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen mainPen() const; - QBrush mainBrush() const; -}; - -/* end of 'src/items/item-ellipse.h' */ - - -/* including file 'src/items/item-pixmap.h', size 4373 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) - Q_PROPERTY(bool scaled READ scaled WRITE setScaled) - Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) - Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - /// \endcond -public: - explicit QCPItemPixmap(QCustomPlot *parentPlot); - virtual ~QCPItemPixmap(); - - // getters: - QPixmap pixmap() const { return mPixmap; } - bool scaled() const { return mScaled; } - Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } - Qt::TransformationMode transformationMode() const { return mTransformationMode; } - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - - // setters; - void setPixmap(const QPixmap &pixmap); - void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const topLeft; - QCPItemPosition * const bottomRight; - QCPItemAnchor * const top; - QCPItemAnchor * const topRight; - QCPItemAnchor * const right; - QCPItemAnchor * const bottom; - QCPItemAnchor * const bottomLeft; - QCPItemAnchor * const left; - -protected: - enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; - - // property members: - QPixmap mPixmap; - QPixmap mScaledPixmap; - bool mScaled; - bool mScaledPixmapInvalidated; - Qt::AspectRatioMode mAspectRatioMode; - Qt::TransformationMode mTransformationMode; - QPen mPen, mSelectedPen; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); - QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; - QPen mainPen() const; -}; - -/* end of 'src/items/item-pixmap.h' */ - - -/* including file 'src/items/item-tracer.h', size 4762 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - Q_PROPERTY(double size READ size WRITE setSize) - Q_PROPERTY(TracerStyle style READ style WRITE setStyle) - Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) - Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) - Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) - /// \endcond -public: - /*! - The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. - - \see setStyle - */ - enum TracerStyle { tsNone ///< The tracer is not visible - ,tsPlus ///< A plus shaped crosshair with limited size - ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect - ,tsCircle ///< A circle - ,tsSquare ///< A square - }; - Q_ENUMS(TracerStyle) - - explicit QCPItemTracer(QCustomPlot *parentPlot); - QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush); - virtual ~QCPItemTracer(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QBrush brush() const { return mBrush; } - QBrush selectedBrush() const { return mSelectedBrush; } - double size() const { return mSize; } - TracerStyle style() const { return mStyle; } - QCPGraph *graph() const { return mGraph; } - double graphKey() const { return mGraphKey; } - bool interpolating() const { return mInterpolating; } - int type() const { return mType; } - qint64 timeStamp() const { return mTimeStamp; } - QMap hidePoint() const { return m_hidePoint; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setSelectedBrush(const QBrush &brush); - void setSize(double size); - void setStyle(TracerStyle style); - void setGraph(QCPGraph *graph); - void setGraphKey(double key); - void setHidePoint(const QMap &hidePoint); - void addHidePoint(const qint64 &time, const QString &tag); - void setInterpolating(bool enabled); - - void setType(const int &type); - void setTimeStamp(const qint64 &timeStamp); - void setInfo(const QStringList infos); - - void showTips(); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void updatePosition(); - - QCPItemPosition * const position; - -signals: - void itemTracerHoverd(const QString &name, const qint64 &time, const QMap& timeTag); - -protected: - // property members: - QPen mPen, mSelectedPen; - QBrush mBrush, mSelectedBrush; - double mSize; - TracerStyle mStyle; - QCPGraph *mGraph; - QMap m_hidePoint; - double mGraphKey; - bool mInterpolating; - int mType; - qint64 mTimeStamp; - QStringList m_infos; - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - - - virtual void mousePressEvent (QMouseEvent *event, const QVariant &details); - - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); - - // non-virtual methods: - QPen mainPen() const; - QBrush mainBrush() const; -}; -Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle) - -/* end of 'src/items/item-tracer.h' */ - - -/* including file 'src/items/item-bracket.h', size 3969 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(double length READ length WRITE setLength) - Q_PROPERTY(BracketStyle style READ style WRITE setStyle) - /// \endcond -public: - /*! - Defines the various visual shapes of the bracket item. The appearance can be further modified - by \ref setLength and \ref setPen. - - \see setStyle - */ - enum BracketStyle { bsSquare ///< A brace with angled edges - ,bsRound ///< A brace with round edges - ,bsCurly ///< A curly brace - ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression - }; - Q_ENUMS(BracketStyle) - - explicit QCPItemBracket(QCustomPlot *parentPlot); - virtual ~QCPItemBracket(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - double length() const { return mLength; } - BracketStyle style() const { return mStyle; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setLength(double length); - void setStyle(BracketStyle style); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const left; - QCPItemPosition * const right; - QCPItemAnchor * const center; - -protected: - // property members: - enum AnchorIndex {aiCenter}; - QPen mPen, mSelectedPen; - double mLength; - BracketStyle mStyle; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen mainPen() const; -}; -Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle) - -/* end of 'src/items/item-bracket.h' */ - - -#endif // QCUSTOMPLOT_H - +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2017 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 04.09.17 ** +** Version: 2.0.0 ** +****************************************************************************/ + +#ifndef QCUSTOMPLOT_H +#define QCUSTOMPLOT_H + +#include + +// some Qt version/configuration dependent macros to include or exclude certain code paths: +#ifdef QCUSTOMPLOT_USE_OPENGL +# if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# define QCP_OPENGL_PBUFFER +# else +# define QCP_OPENGL_FBO +# endif +# if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) +# define QCP_OPENGL_OFFSCREENSURFACE +# endif +#endif + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) +# define QCP_DEVICEPIXELRATIO_SUPPORTED +# if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) +# define QCP_DEVICEPIXELRATIO_FLOAT +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef QCP_OPENGL_FBO +# include +# include +# ifdef QCP_OPENGL_OFFSCREENSURFACE +# include +# else +# include +# endif +#endif +#ifdef QCP_OPENGL_PBUFFER +# include +#endif +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# include +# include +# include +# include +#else +# include +# include +# include +#endif + +class QCPPainter; +class QCustomPlot; +class QCPLayerable; +class QCPLayoutElement; +class QCPLayout; +class QCPAxis; +class QCPAxisRect; +class QCPAxisPainterPrivate; +class QCPAbstractPlottable; +class QCPGraph; +class QCPAbstractItem; +class QCPPlottableInterface1D; +class QCPLegend; +class QCPItemPosition; +class QCPLayer; +class QCPAbstractLegendItem; +class QCPSelectionRect; +class QCPColorMap; +class QCPColorScale; +class QCPBars; + +/* including file 'src/global.h', size 16225 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +// decl definitions for shared library compilation/usage: +#if defined(QCUSTOMPLOT_COMPILE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_EXPORT +#elif defined(QCUSTOMPLOT_USE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_IMPORT +#else +# define QCP_LIB_DECL +#endif + +// define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5) +#ifndef Q_DECL_OVERRIDE +# define Q_DECL_OVERRIDE +#endif + +/*! + The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot + library. + + It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. +*/ +#ifndef Q_MOC_RUN +namespace QCP { +#else +class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace + Q_GADGET + Q_ENUMS(ExportPen) + Q_ENUMS(ResolutionUnit) + Q_ENUMS(SignDomain) + Q_ENUMS(MarginSide) + Q_FLAGS(MarginSides) + Q_ENUMS(AntialiasedElement) + Q_FLAGS(AntialiasedElements) + Q_ENUMS(PlottingHint) + Q_FLAGS(PlottingHints) + Q_ENUMS(Interaction) + Q_FLAGS(Interactions) + Q_ENUMS(SelectionRectMode) + Q_ENUMS(SelectionType) +public: +#endif + +/*! + Defines the different units in which the image resolution can be specified in the export + functions. + + \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered +*/ +enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) + ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) + ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) + }; + +/*! + Defines how cosmetic pens (pens with numerical width 0) are handled during export. + + \see QCustomPlot::savePdf +*/ +enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting + ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level) + }; + +/*! + Represents negative and positive sign domain, e.g. for passing to \ref + QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. + + This is primarily needed when working with logarithmic axis scales, since only one of the sign + domains can be visible at a time. +*/ +enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero + ,sdBoth ///< Both sign domains, including zero, i.e. all numbers + ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero + }; + +/*! + Defines the sides of a rectangular entity to which margins can be applied. + + \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins +*/ +enum MarginSide { msLeft = 0x01 ///< 0x01 left margin + ,msRight = 0x02 ///< 0x02 right margin + ,msTop = 0x04 ///< 0x04 top margin + ,msBottom = 0x08 ///< 0x08 bottom margin + ,msAll = 0xFF ///< 0xFF all margins + ,msNone = 0x00 ///< 0x00 no margin + }; +Q_DECLARE_FLAGS(MarginSides, MarginSide) + +/*! + Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is + neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective + element how it is drawn. Typically it provides a \a setAntialiased function for this. + + \c AntialiasedElements is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements +*/ +enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks + ,aeGrid = 0x0002 ///< 0x0002 Grid lines + ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines + ,aeLegend = 0x0008 ///< 0x0008 Legend box + ,aeLegendItems = 0x0010 ///< 0x0010 Legend items + ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables + ,aeItems = 0x0040 ///< 0x0040 Main lines of items + ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) + ,aeFills = 0x0100 ///< 0x0100 Borders of fills (e.g. under or between graphs) + ,aeZeroLine = 0x0200 ///< 0x0200 Zero-lines, see \ref QCPGrid::setZeroLinePen + ,aeOther = 0x8000 ///< 0x8000 Other elements that don't fit into any of the existing categories + ,aeAll = 0xFFFF ///< 0xFFFF All elements + ,aeNone = 0x0000 ///< 0x0000 No elements + }; +Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) + +/*! + Defines plotting hints that control various aspects of the quality and speed of plotting. + + \see QCustomPlot::setPlottingHints +*/ +enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set + ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment + ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens. + ,phImmediateRefresh = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint. + ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). + ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. + }; +Q_DECLARE_FLAGS(PlottingHints, PlottingHint) + +/*! + Defines the mouse interactions possible with QCustomPlot. + + \c Interactions is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setInteractions +*/ +enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) + ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) + ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking + ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) + ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) + ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) + ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) + ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, other layout elements,...) + }; +Q_DECLARE_FLAGS(Interactions, Interaction) + +/*! + Defines the behaviour of the selection rect. + + \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect +*/ +enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging + ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly. + ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.) + ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction. + }; + +/*! + Defines the different ways a plottable can be selected. These images show the effect of the + different selection types, when the indicated selection rect was dragged: + +
+ + + + + + + + +
\image html selectiontype-none.png stNone\image html selectiontype-whole.png stWhole\image html selectiontype-singledata.png stSingleData\image html selectiontype-datarange.png stDataRange\image html selectiontype-multipledataranges.png stMultipleDataRanges
+
+ + \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType +*/ +enum SelectionType { stNone ///< The plottable is not selectable + ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected. + ,stSingleData ///< One individual data point can be selected at a time + ,stDataRange ///< Multiple contiguous data points (a data range) can be selected + ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected + }; + +/*! \internal + + Returns whether the specified \a value is considered an invalid data value for plottables (i.e. + is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the + compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. +*/ +inline bool isInvalidData(double value) +{ + return qIsNaN(value) || qIsInf(value); +} + +/*! \internal + \overload + + Checks two arguments instead of one. +*/ +inline bool isInvalidData(double value1, double value2) +{ + return isInvalidData(value1) || isInvalidData(value2); +} + +/*! \internal + + Sets the specified \a side of \a margins to \a value + + \see getMarginValue +*/ +inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) +{ + switch (side) + { + case QCP::msLeft: margins.setLeft(value); break; + case QCP::msRight: margins.setRight(value); break; + case QCP::msTop: margins.setTop(value); break; + case QCP::msBottom: margins.setBottom(value); break; + case QCP::msAll: margins = QMargins(value, value, value, value); break; + default: break; + } +} + +/*! \internal + + Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or + \ref QCP::msAll, returns 0. + + \see setMarginValue +*/ +inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return margins.left(); + case QCP::msRight: return margins.right(); + case QCP::msTop: return margins.top(); + case QCP::msBottom: return margins.bottom(); + default: break; + } + return 0; +} + + +extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace + +} // end of namespace QCP +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) +Q_DECLARE_METATYPE(QCP::ExportPen) +Q_DECLARE_METATYPE(QCP::ResolutionUnit) +Q_DECLARE_METATYPE(QCP::SignDomain) +Q_DECLARE_METATYPE(QCP::MarginSide) +Q_DECLARE_METATYPE(QCP::AntialiasedElement) +Q_DECLARE_METATYPE(QCP::PlottingHint) +Q_DECLARE_METATYPE(QCP::Interaction) +Q_DECLARE_METATYPE(QCP::SelectionRectMode) +Q_DECLARE_METATYPE(QCP::SelectionType) + +/* end of 'src/global.h' */ + + +/* including file 'src/vector2d.h', size 4928 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPVector2D +{ +public: + QCPVector2D(); + QCPVector2D(double x, double y); + QCPVector2D(const QPoint &point); + QCPVector2D(const QPointF &point); + + // getters: + double x() const { return mX; } + double y() const { return mY; } + double &rx() { return mX; } + double &ry() { return mY; } + + // setters: + void setX(double x) { mX = x; } + void setY(double y) { mY = y; } + + // non-virtual methods: + double length() const { return qSqrt(mX*mX+mY*mY); } + double lengthSquared() const { return mX*mX+mY*mY; } + QPoint toPoint() const { return QPoint(mX, mY); } + QPointF toPointF() const { return QPointF(mX, mY); } + + bool isNull() const { return qIsNull(mX) && qIsNull(mY); } + void normalize(); + QCPVector2D normalized() const; + QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); } + double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; } + double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; + double distanceSquaredToLine(const QLineF &line) const; + double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; + + QCPVector2D &operator*=(double factor); + QCPVector2D &operator/=(double divisor); + QCPVector2D &operator+=(const QCPVector2D &vector); + QCPVector2D &operator-=(const QCPVector2D &vector); + +private: + // property members: + double mX, mY; + + friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); + friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); + friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); + friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec); +}; +Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE); + +inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); } +inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); } + +/*! \relates QCPVector2D + + Prints \a vec in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPVector2D &vec) +{ + d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")"; + return d.space(); +} + +/* end of 'src/vector2d.h' */ + + +/* including file 'src/painter.h', size 4035 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPPainter : public QPainter +{ + Q_GADGET +public: + /*! + Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, + depending on whether they are wanted on the respective output device. + */ + enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices + ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. + ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels + ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) + }; + Q_ENUMS(PainterMode) + Q_FLAGS(PainterModes) + Q_DECLARE_FLAGS(PainterModes, PainterMode) + + QCPPainter(); + explicit QCPPainter(QPaintDevice *device); + + // getters: + bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } + PainterModes modes() const { return mModes; } + + // setters: + void setAntialiasing(bool enabled); + void setMode(PainterMode mode, bool enabled=true); + void setModes(PainterModes modes); + + // methods hiding non-virtual base class functions (QPainter bug workarounds): + bool begin(QPaintDevice *device); + void setPen(const QPen &pen); + void setPen(const QColor &color); + void setPen(Qt::PenStyle penStyle); + void drawLine(const QLineF &line); + void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} + void save(); + void restore(); + + // non-virtual methods: + void makeNonCosmetic(); + +protected: + // property members: + PainterModes mModes; + bool mIsAntialiasing; + + // non-property members: + QStack mAntialiasingStack; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) +Q_DECLARE_METATYPE(QCPPainter::PainterMode) + +/* end of 'src/painter.h' */ + + +/* including file 'src/paintbuffer.h', size 4958 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAbstractPaintBuffer +{ +public: + explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); + virtual ~QCPAbstractPaintBuffer(); + + // getters: + QSize size() const { return mSize; } + bool invalidated() const { return mInvalidated; } + double devicePixelRatio() const { return mDevicePixelRatio; } + + // setters: + void setSize(const QSize &size); + void setInvalidated(bool invalidated=true); + void setDevicePixelRatio(double ratio); + + // introduced virtual methods: + virtual QCPPainter *startPainting() = 0; + virtual void donePainting() {} + virtual void draw(QCPPainter *painter) const = 0; + virtual void clear(const QColor &color) = 0; + +protected: + // property members: + QSize mSize; + double mDevicePixelRatio; + + // non-property members: + bool mInvalidated; + + // introduced virtual methods: + virtual void reallocateBuffer() = 0; +}; + + +class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); + virtual ~QCPPaintBufferPixmap(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QPixmap mBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; + + +#ifdef QCP_OPENGL_PBUFFER +class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); + virtual ~QCPPaintBufferGlPbuffer(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QGLPixelBuffer *mGlPBuffer; + int mMultisamples; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice); + virtual ~QCPPaintBufferGlFbo(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void donePainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QWeakPointer mGlContext; + QWeakPointer mGlPaintDevice; + QOpenGLFramebufferObject *mGlFrameBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_FBO + +/* end of 'src/paintbuffer.h' */ + + +/* including file 'src/layer.h', size 6885 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPLayer : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(int index READ index) + Q_PROPERTY(QList children READ children) + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(LayerMode mode READ mode WRITE setMode) + /// \endcond +public: + + /*! + Defines the different rendering modes of a layer. Depending on the mode, certain layers can be + replotted individually, without the need to replot (possibly complex) layerables on other + layers. + + \see setMode + */ + enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. + ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). + }; + Q_ENUMS(LayerMode) + + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); + virtual ~QCPLayer(); + + // getters: + QCustomPlot *parentPlot() const { return mParentPlot; } + QString name() const { return mName; } + int index() const { return mIndex; } + QList children() const { return mChildren; } + bool visible() const { return mVisible; } + LayerMode mode() const { return mMode; } + + // setters: + void setVisible(bool visible); + void setMode(LayerMode mode); + + // non-virtual methods: + void replot(); + +protected: + // property members: + QCustomPlot *mParentPlot; + QString mName; + int mIndex; + QList mChildren; + bool mVisible; + LayerMode mMode; + + // non-property members: + QWeakPointer mPaintBuffer; + + // non-virtual methods: + void draw(QCPPainter *painter); + void drawToPaintBuffer(); + void addChild(QCPLayerable *layerable, bool prepend); + void removeChild(QCPLayerable *layerable); + +private: + Q_DISABLE_COPY(QCPLayer) + + friend class QCustomPlot; + friend class QCPLayerable; +}; +Q_DECLARE_METATYPE(QCPLayer::LayerMode) + +class QCP_LIB_DECL QCPLayerable : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) + Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) + Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) + /// \endcond +public: + QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); + virtual ~QCPLayerable(); + + // getters: + bool visible() const { return mVisible; } + QCustomPlot *parentPlot() const { return mParentPlot; } + QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } + QCPLayer *layer() const { return mLayer; } + bool antialiased() const { return mAntialiased; } + + // setters: + void setVisible(bool on); + Q_SLOT bool setLayer(QCPLayer *layer); + bool setLayer(const QString &layerName); + void setAntialiased(bool enabled); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-property methods: + bool realVisibility() const; + +signals: + void layerChanged(QCPLayer *newLayer); + +protected: + // property members: + bool mVisible; + QCustomPlot *mParentPlot; + QPointer mParentLayerable; + QCPLayer *mLayer; + bool mAntialiased; + + // introduced virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; + virtual void draw(QCPPainter *painter) = 0; + // selection events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + // low-level mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); + virtual void wheelEvent(QWheelEvent *event); + + // non-property methods: + void initializeParentPlot(QCustomPlot *parentPlot); + void setParentLayerable(QCPLayerable* parentLayerable); + bool moveToLayer(QCPLayer *layer, bool prepend); + void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; + +private: + Q_DISABLE_COPY(QCPLayerable) + + friend class QCustomPlot; + friend class QCPLayer; + friend class QCPAxisRect; +}; + +/* end of 'src/layer.h' */ + + +/* including file 'src/axis/range.h', size 5280 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPRange +{ +public: + double lower, upper; + + QCPRange(); + QCPRange(double lower, double upper); + + bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } + bool operator!=(const QCPRange& other) const { return !(*this == other); } + + QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } + QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } + QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } + QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } + friend inline const QCPRange operator+(const QCPRange&, double); + friend inline const QCPRange operator+(double, const QCPRange&); + friend inline const QCPRange operator-(const QCPRange& range, double value); + friend inline const QCPRange operator*(const QCPRange& range, double value); + friend inline const QCPRange operator*(double value, const QCPRange& range); + friend inline const QCPRange operator/(const QCPRange& range, double value); + + double size() const { return upper-lower; } + double center() const { return (upper+lower)*0.5; } + void normalize() { if (lower > upper) qSwap(lower, upper); } + void expand(const QCPRange &otherRange); + void expand(double includeCoord); + QCPRange expanded(const QCPRange &otherRange) const; + QCPRange expanded(double includeCoord) const; + QCPRange bounded(double lowerBound, double upperBound) const; + QCPRange sanitizedForLogScale() const; + QCPRange sanitizedForLinScale() const; + bool contains(double value) const { return value >= lower && value <= upper; } + + static bool validRange(double lower, double upper); + static bool validRange(const QCPRange &range); + static const double minRange; + static const double maxRange; + +}; +Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); + +/*! \relates QCPRange + + Prints \a range in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPRange &range) +{ + d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")"; + return d.space(); +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(const QCPRange& range, double value) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(double value, const QCPRange& range) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Subtracts \a value from both boundaries of the range. +*/ +inline const QCPRange operator-(const QCPRange& range, double value) +{ + QCPRange result(range); + result -= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(const QCPRange& range, double value) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(double value, const QCPRange& range) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Divides both boundaries of the range by \a value. +*/ +inline const QCPRange operator/(const QCPRange& range, double value) +{ + QCPRange result(range); + result /= value; + return result; +} + +/* end of 'src/axis/range.h' */ + + +/* including file 'src/selection.h', size 8579 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPDataRange +{ +public: + QCPDataRange(); + QCPDataRange(int begin, int end); + + bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; } + bool operator!=(const QCPDataRange& other) const { return !(*this == other); } + + // getters: + int begin() const { return mBegin; } + int end() const { return mEnd; } + int size() const { return mEnd-mBegin; } + int length() const { return size(); } + + // setters: + void setBegin(int begin) { mBegin = begin; } + void setEnd(int end) { mEnd = end; } + + // non-property methods: + bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } + bool isEmpty() const { return length() == 0; } + QCPDataRange bounded(const QCPDataRange &other) const; + QCPDataRange expanded(const QCPDataRange &other) const; + QCPDataRange intersection(const QCPDataRange &other) const; + QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); } + bool intersects(const QCPDataRange &other) const; + bool contains(const QCPDataRange &other) const; + +private: + // property members: + int mBegin, mEnd; + +}; +Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPDataSelection +{ +public: + explicit QCPDataSelection(); + explicit QCPDataSelection(const QCPDataRange &range); + + bool operator==(const QCPDataSelection& other) const; + bool operator!=(const QCPDataSelection& other) const { return !(*this == other); } + QCPDataSelection &operator+=(const QCPDataSelection& other); + QCPDataSelection &operator+=(const QCPDataRange& other); + QCPDataSelection &operator-=(const QCPDataSelection& other); + QCPDataSelection &operator-=(const QCPDataRange& other); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b); + + // getters: + int dataRangeCount() const { return mDataRanges.size(); } + int dataPointCount() const; + QCPDataRange dataRange(int index=0) const; + QList dataRanges() const { return mDataRanges; } + QCPDataRange span() const; + + // non-property methods: + void addDataRange(const QCPDataRange &dataRange, bool simplify=true); + void clear(); + bool isEmpty() const { return mDataRanges.isEmpty(); } + void simplify(); + void enforceType(QCP::SelectionType type); + bool contains(const QCPDataSelection &other) const; + QCPDataSelection intersection(const QCPDataRange &other) const; + QCPDataSelection intersection(const QCPDataSelection &other) const; + QCPDataSelection inverse(const QCPDataRange &outerRange) const; + +private: + // property members: + QList mDataRanges; + + inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); } +}; +Q_DECLARE_METATYPE(QCPDataSelection) + + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! \relates QCPDataRange + + Prints \a dataRange in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange) +{ + d.nospace() << "[" << dataRange.begin() << ".." << dataRange.end()-1 << "]"; + return d.space(); +} + +/*! \relates QCPDataSelection + + Prints \a selection in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataSelection &selection) +{ + d.nospace() << "QCPDataSelection("; + for (int i=0; i elements(QCP::MarginSide side) const { return mChildren.value(side); } + bool isEmpty() const; + void clear(); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + QHash > mChildren; + + // introduced virtual methods: + virtual int commonMargin(QCP::MarginSide side) const; + + // non-virtual methods: + void addChild(QCP::MarginSide side, QCPLayoutElement *element); + void removeChild(QCP::MarginSide side, QCPLayoutElement *element); + +private: + Q_DISABLE_COPY(QCPMarginGroup) + + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLayout* layout READ layout) + Q_PROPERTY(QRect rect READ rect) + Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) + Q_PROPERTY(QMargins margins READ margins WRITE setMargins) + Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) + Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) + Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) + Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect) + /// \endcond +public: + /*! + Defines the phases of the update process, that happens just before a replot. At each phase, + \ref update is called with the according UpdatePhase value. + */ + enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout + ,upMargins ///< Phase in which the margins are calculated and set + ,upLayout ///< Final phase in which the layout system places the rects of the elements + }; + Q_ENUMS(UpdatePhase) + + /*! + Defines to which rect of a layout element the size constraints that can be set via \ref + setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the + margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect) + does not. + + \see setSizeConstraintRect + */ + enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect + , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins + }; + Q_ENUMS(SizeConstraintRect) + + explicit QCPLayoutElement(QCustomPlot *parentPlot=0); + virtual ~QCPLayoutElement(); + + // getters: + QCPLayout *layout() const { return mParentLayout; } + QRect rect() const { return mRect; } + QRect outerRect() const { return mOuterRect; } + QMargins margins() const { return mMargins; } + QMargins minimumMargins() const { return mMinimumMargins; } + QCP::MarginSides autoMargins() const { return mAutoMargins; } + QSize minimumSize() const { return mMinimumSize; } + QSize maximumSize() const { return mMaximumSize; } + SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; } + QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } + QHash marginGroups() const { return mMarginGroups; } + + // setters: + void setOuterRect(const QRect &rect); + void setMargins(const QMargins &margins); + void setMinimumMargins(const QMargins &margins); + void setAutoMargins(QCP::MarginSides sides); + void setMinimumSize(const QSize &size); + void setMinimumSize(int width, int height); + void setMaximumSize(const QSize &size); + void setMaximumSize(int width, int height); + void setSizeConstraintRect(SizeConstraintRect constraintRect); + void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); + + // introduced virtual methods: + virtual void update(UpdatePhase phase); + virtual QSize minimumOuterSizeHint() const; + virtual QSize maximumOuterSizeHint() const; + virtual QList elements(bool recursive) const; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPLayout *mParentLayout; + QSize mMinimumSize, mMaximumSize; + SizeConstraintRect mSizeConstraintRect; + QRect mRect, mOuterRect; + QMargins mMargins, mMinimumMargins; + QCP::MarginSides mAutoMargins; + QHash mMarginGroups; + + // introduced virtual methods: + virtual int calculateAutoMargin(QCP::MarginSide side); + virtual void layoutChanged(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPLayoutElement) + + friend class QCustomPlot; + friend class QCPLayout; + friend class QCPMarginGroup; +}; +Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase) + + +class QCP_LIB_DECL QCPLayout : public QCPLayoutElement +{ + Q_OBJECT +public: + explicit QCPLayout(); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual int elementCount() const = 0; + virtual QCPLayoutElement* elementAt(int index) const = 0; + virtual QCPLayoutElement* takeAt(int index) = 0; + virtual bool take(QCPLayoutElement* element) = 0; + virtual void simplify(); + + // non-virtual methods: + bool removeAt(int index); + bool remove(QCPLayoutElement* element); + void clear(); + +protected: + // introduced virtual methods: + virtual void updateLayout(); + + // non-virtual methods: + void sizeConstraintsChanged() const; + void adoptElement(QCPLayoutElement *el); + void releaseElement(QCPLayoutElement *el); + QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; + static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el); + static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el); + +private: + Q_DISABLE_COPY(QCPLayout) + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(int rowCount READ rowCount) + Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) + Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) + Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) + Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) + Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder) + Q_PROPERTY(int wrap READ wrap WRITE setWrap) + /// \endcond +public: + + /*! + Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). + The column/row at which wrapping into the next row/column occurs can be specified with \ref + setWrap. + + \see setFillOrder + */ + enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap. + ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. + }; + Q_ENUMS(FillOrder) + + explicit QCPLayoutGrid(); + virtual ~QCPLayoutGrid(); + + // getters: + int rowCount() const { return mElements.size(); } + int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } + QList columnStretchFactors() const { return mColumnStretchFactors; } + QList rowStretchFactors() const { return mRowStretchFactors; } + int columnSpacing() const { return mColumnSpacing; } + int rowSpacing() const { return mRowSpacing; } + int wrap() const { return mWrap; } + FillOrder fillOrder() const { return mFillOrder; } + + // setters: + void setColumnStretchFactor(int column, double factor); + void setColumnStretchFactors(const QList &factors); + void setRowStretchFactor(int row, double factor); + void setRowStretchFactors(const QList &factors); + void setColumnSpacing(int pixels); + void setRowSpacing(int pixels); + void setWrap(int count); + void setFillOrder(FillOrder order, bool rearrange=true); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); } + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPLayoutElement *element(int row, int column) const; + bool addElement(int row, int column, QCPLayoutElement *element); + bool addElement(QCPLayoutElement *element); + bool hasElement(int row, int column); + void expandTo(int newRowCount, int newColumnCount); + void insertRow(int newIndex); + void insertColumn(int newIndex); + int rowColToIndex(int row, int column) const; + void indexToRowCol(int index, int &row, int &column) const; + +protected: + // property members: + QList > mElements; + QList mColumnStretchFactors; + QList mRowStretchFactors; + int mColumnSpacing, mRowSpacing; + int mWrap; + FillOrder mFillOrder; + + // non-virtual methods: + void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; + void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; + +private: + Q_DISABLE_COPY(QCPLayoutGrid) +}; +Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder) + + +class QCP_LIB_DECL QCPLayoutInset : public QCPLayout +{ + Q_OBJECT +public: + /*! + Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. + */ + enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect + ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment + }; + Q_ENUMS(InsetPlacement) + + explicit QCPLayoutInset(); + virtual ~QCPLayoutInset(); + + // getters: + InsetPlacement insetPlacement(int index) const; + Qt::Alignment insetAlignment(int index) const; + QRectF insetRect(int index) const; + + // setters: + void setInsetPlacement(int index, InsetPlacement placement); + void setInsetAlignment(int index, Qt::Alignment alignment); + void setInsetRect(int index, const QRectF &rect); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE {} + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void addElement(QCPLayoutElement *element, Qt::Alignment alignment); + void addElement(QCPLayoutElement *element, const QRectF &rect); + +protected: + // property members: + QList mElements; + QList mInsetPlacement; + QList mInsetAlignment; + QList mInsetRect; + +private: + Q_DISABLE_COPY(QCPLayoutInset) +}; +Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement) + +/* end of 'src/layout.h' */ + + +/* including file 'src/lineending.h', size 4426 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPLineEnding +{ + Q_GADGET +public: + /*! + Defines the type of ending decoration for line-like items, e.g. an arrow. + + \image html QCPLineEnding.png + + The width and length of these decorations can be controlled with the functions \ref setWidth + and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only + support a width, the length property is ignored. + + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding + */ + enum EndingStyle { esNone ///< No ending decoration + ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) + ,esSpikeArrow ///< A filled arrow head with an indented back + ,esLineArrow ///< A non-filled arrow head with open back + ,esDisc ///< A filled circle + ,esSquare ///< A filled square + ,esDiamond ///< A filled diamond (45 degrees rotated square) + ,esBar ///< A bar perpendicular to the line + ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) + ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) + }; + Q_ENUMS(EndingStyle) + + QCPLineEnding(); + QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); + + // getters: + EndingStyle style() const { return mStyle; } + double width() const { return mWidth; } + double length() const { return mLength; } + bool inverted() const { return mInverted; } + + // setters: + void setStyle(EndingStyle style); + void setWidth(double width); + void setLength(double length); + void setInverted(bool inverted); + + // non-property methods: + double boundingDistance() const; + double realLength() const; + void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; + void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; + +protected: + // property members: + EndingStyle mStyle; + double mWidth, mLength; + bool mInverted; +}; +Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); +Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle) + +/* end of 'src/lineending.h' */ + + +/* including file 'src/axis/axisticker.h', size 4177 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the strategies that the axis ticker may follow when choosing the size of the tick step. + + \see setTickStepStrategy + */ + enum TickStepStrategy + { + tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount) + ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count + }; + Q_ENUMS(TickStepStrategy) + + QCPAxisTicker(); + virtual ~QCPAxisTicker(); + + // getters: + TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } + int tickCount() const { return mTickCount; } + double tickOrigin() const { return mTickOrigin; } + + // setters: + void setTickStepStrategy(TickStepStrategy strategy); + void setTickCount(int count); + void setTickOrigin(double origin); + + // introduced virtual methods: + virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); + +protected: + // property members: + TickStepStrategy mTickStepStrategy; + int mTickCount; + double mTickOrigin; + + // introduced virtual methods: + virtual double getTickStep(const QCPRange &range); + virtual int getSubTickCount(double tickStep); + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision); + virtual QVector createTickVector(double tickStep, const QCPRange &range); + virtual QVector createSubTickVector(int subTickCount, const QVector &ticks); + virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision); + + // non-virtual methods: + void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const; + double pickClosest(double target, const QVector &candidates) const; + double getMantissa(double input, double *magnitude=0) const; + double cleanMantissa(double input) const; +}; +Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) +Q_DECLARE_METATYPE(QSharedPointer) + +/* end of 'src/axis/axisticker.h' */ + + +/* including file 'src/axis/axistickerdatetime.h', size 3289 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker +{ +public: + QCPAxisTickerDateTime(); + + // getters: + QString dateTimeFormat() const { return mDateTimeFormat; } + Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } + + // setters: + void setDateTimeFormat(const QString &format); + void setDateTimeSpec(Qt::TimeSpec spec); + void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) + void setTickOrigin(const QDateTime &origin); + + // static methods: + static QDateTime keyToDateTime(double key); + static double dateTimeToKey(const QDateTime dateTime); + static double dateTimeToKey(const QDate date); + +protected: + // property members: + QString mDateTimeFormat; + Qt::TimeSpec mDateTimeSpec; + + // non-property members: + enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerdatetime.h' */ + + +/* including file 'src/axis/axistickertime.h', size 3542 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the logical units in which fractions of time spans can be expressed. + + \see setFieldWidth, setTimeFormat + */ + enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) + ,tuSeconds ///< Seconds (%%s in \ref setTimeFormat) + ,tuMinutes ///< Minutes (%%m in \ref setTimeFormat) + ,tuHours ///< Hours (%%h in \ref setTimeFormat) + ,tuDays ///< Days (%%d in \ref setTimeFormat) + }; + Q_ENUMS(TimeUnit) + + QCPAxisTickerTime(); + + // getters: + QString timeFormat() const { return mTimeFormat; } + int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } + + // setters: + void setTimeFormat(const QString &format); + void setFieldWidth(TimeUnit unit, int width); + +protected: + // property members: + QString mTimeFormat; + QHash mFieldWidth; + + // non-property members: + TimeUnit mSmallestUnit, mBiggestUnit; + QHash mFormatPattern; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void replaceUnit(QString &text, TimeUnit unit, int value) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit) + +/* end of 'src/axis/axistickertime.h' */ + + +/* including file 'src/axis/axistickerfixed.h', size 3308 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to + control the number of ticks in the axis range. + + \see setScaleStrategy + */ + enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out. + ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount. + ,ssPowers ///< An integer power of the specified tick step is allowed. + }; + Q_ENUMS(ScaleStrategy) + + QCPAxisTickerFixed(); + + // getters: + double tickStep() const { return mTickStep; } + ScaleStrategy scaleStrategy() const { return mScaleStrategy; } + + // setters: + void setTickStep(double step); + void setScaleStrategy(ScaleStrategy strategy); + +protected: + // property members: + double mTickStep; + ScaleStrategy mScaleStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; +}; +Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy) + +/* end of 'src/axis/axistickerfixed.h' */ + + +/* including file 'src/axis/axistickertext.h', size 3085 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker +{ +public: + QCPAxisTickerText(); + + // getters: + QMap &ticks() { return mTicks; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setTicks(const QMap &ticks); + void setTicks(const QVector &positions, const QVector labels); + void setSubTickCount(int subTicks); + + // non-virtual methods: + void clear(); + void addTick(double position, QString label); + void addTicks(const QMap &ticks); + void addTicks(const QVector &positions, const QVector &labels); + +protected: + // property members: + QMap mTicks; + int mSubTickCount; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; + +}; + +/* end of 'src/axis/axistickertext.h' */ + + +/* including file 'src/axis/axistickerpi.h', size 3911 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how fractions should be displayed in tick labels. + + \see setFractionStyle + */ + enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125". + ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8" + ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol. + }; + Q_ENUMS(FractionStyle) + + QCPAxisTickerPi(); + + // getters: + QString piSymbol() const { return mPiSymbol; } + double piValue() const { return mPiValue; } + bool periodicity() const { return mPeriodicity; } + FractionStyle fractionStyle() const { return mFractionStyle; } + + // setters: + void setPiSymbol(QString symbol); + void setPiValue(double pi); + void setPeriodicity(int multiplesOfPi); + void setFractionStyle(FractionStyle style); + +protected: + // property members: + QString mPiSymbol; + double mPiValue; + int mPeriodicity; + FractionStyle mFractionStyle; + + // non-property members: + double mPiTickStep; // size of one tick step in units of mPiValue + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void simplifyFraction(int &numerator, int &denominator) const; + QString fractionToString(int numerator, int denominator) const; + QString unicodeFraction(int numerator, int denominator) const; + QString unicodeSuperscript(int number) const; + QString unicodeSubscript(int number) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle) + +/* end of 'src/axis/axistickerpi.h' */ + + +/* including file 'src/axis/axistickerlog.h', size 2663 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker +{ +public: + QCPAxisTickerLog(); + + // getters: + double logBase() const { return mLogBase; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setLogBase(double base); + void setSubTickCount(int subTicks); + +protected: + // property members: + double mLogBase; + int mSubTickCount; + + // non-property members: + double mLogBaseLnInv; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerlog.h' */ + + +/* including file 'src/axis/axis.h', size 20634 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPGrid :public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) + Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) + Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) + Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) + /// \endcond +public: + explicit QCPGrid(QCPAxis *parentAxis); + + // getters: + bool subGridVisible() const { return mSubGridVisible; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen pen() const { return mPen; } + QPen subGridPen() const { return mSubGridPen; } + QPen zeroLinePen() const { return mZeroLinePen; } + + // setters: + void setSubGridVisible(bool visible); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + +protected: + // property members: + bool mSubGridVisible; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mPen, mSubGridPen, mZeroLinePen; + + // non-property members: + QCPAxis *mParentAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawGridLines(QCPPainter *painter) const; + void drawSubGridLines(QCPPainter *painter) const; + + friend class QCPAxis; +}; + + +class QCP_LIB_DECL QCPAxis : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(AxisType axisType READ axisType) + Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) + Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) + Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) + Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) + Q_PROPERTY(QSharedPointer ticker READ ticker WRITE setTicker) + Q_PROPERTY(bool ticks READ ticks WRITE setTicks) + Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) + Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) + Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) + Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) + Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) + Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) + Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) + Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) + Q_PROPERTY(QVector tickVector READ tickVector) + Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels) + Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) + Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) + Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks) + Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) + Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) + Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) + Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) + Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) + Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) + Q_PROPERTY(int padding READ padding WRITE setPadding) + Q_PROPERTY(int offset READ offset WRITE setOffset) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) + Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) + Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) + Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) + Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) + Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) + Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) + Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) + Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) + Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) + Q_PROPERTY(QCPGrid* grid READ grid) + /// \endcond +public: + /*! + Defines at which side of the axis rect the axis will appear. This also affects how the tick + marks are drawn, on which side the labels are placed etc. + */ + enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect + ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect + ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect + ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect + }; + Q_ENUMS(AxisType) + Q_FLAGS(AxisTypes) + Q_DECLARE_FLAGS(AxisTypes, AxisType) + /*! + Defines on which side of the axis the tick labels (numbers) shall appear. + + \see setTickLabelSide + */ + enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect + ,lsOutside ///< Tick labels will be displayed outside the axis rect + }; + Q_ENUMS(LabelSide) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPAxis(QCPAxisRect *parent, AxisType type); + virtual ~QCPAxis(); + + // getters: + AxisType axisType() const { return mAxisType; } + QCPAxisRect *axisRect() const { return mAxisRect; } + ScaleType scaleType() const { return mScaleType; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + QSharedPointer ticker() const { return mTicker; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const; + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const; + LabelSide tickLabelSide() const; + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const; + int tickLengthOut() const; + bool subTicks() const { return mSubTicks; } + int subTickLengthIn() const; + int subTickLengthOut() const; + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const; + int padding() const { return mPadding; } + int offset() const; + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + QCPLineEnding lowerEnding() const; + QCPLineEnding upperEnding() const; + QCPGrid *grid() const { return mGrid; } + + // setters: + Q_SLOT void setScaleType(QCPAxis::ScaleType type); + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setTicker(QSharedPointer ticker); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelSide(LabelSide side); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTicks(bool show); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setPadding(int padding); + void setOffset(int offset); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); + void setLowerEnding(const QCPLineEnding &ending); + void setUpperEnding(const QCPLineEnding &ending); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-property methods: + Qt::Orientation orientation() const { return mOrientation; } + int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; } + void moveRange(double diff); + void scaleRange(double factor); + void scaleRange(double factor, double center); + void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); + void rescale(bool onlyVisiblePlottables=false); + double pixelToCoord(double value) const; + double coordToPixel(double value) const; + SelectablePart getPartAt(const QPointF &pos) const; + QList plottables() const; + QList graphs() const; + QList items() const; + + static AxisType marginSideToAxisType(QCP::MarginSide side); + static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } + static AxisType opposite(AxisType type); + +signals: + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void scaleTypeChanged(QCPAxis::ScaleType scaleType); + void selectionChanged(const QCPAxis::SelectableParts &parts); + void selectableChanged(const QCPAxis::SelectableParts &parts); + +protected: + // property members: + // axis base: + AxisType mAxisType; + QCPAxisRect *mAxisRect; + //int mOffset; // in QCPAxisPainter + int mPadding; + Qt::Orientation mOrientation; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter + // axis label: + //int mLabelPadding; // in QCPAxisPainter + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; // in QCPAxisPainter + bool mTickLabels; + //double mTickLabelRotation; // in QCPAxisPainter + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + //bool mNumberMultiplyCross; // QCPAxisPainter + // ticks and subticks: + bool mTicks; + bool mSubTicks; + //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + ScaleType mScaleType; + + // non-property members: + QCPGrid *mGrid; + QCPAxisPainterPrivate *mAxisPainter; + QSharedPointer mTicker; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mSubTickVector; + bool mCachedMarginValid; + int mCachedMargin; + bool mDragging; + QCPRange mDragStartRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + + // introduced virtual methods: + virtual int calculateMargin(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + // mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); + virtual void wheelEvent(QWheelEvent *event); + + // non-virtual methods: + void setupTickVectors(); + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPAxis) + + friend class QCustomPlot; + friend class QCPGrid; + friend class QCPAxisRect; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) +Q_DECLARE_METATYPE(QCPAxis::AxisType) +Q_DECLARE_METATYPE(QCPAxis::LabelSide) +Q_DECLARE_METATYPE(QCPAxis::ScaleType) +Q_DECLARE_METATYPE(QCPAxis::SelectablePart) + + +class QCPAxisPainterPrivate +{ +public: + explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); + virtual ~QCPAxisPainterPrivate(); + + virtual void draw(QCPPainter *painter); + virtual int size() const; + void clearCache(); + + QRect axisSelectionBox() const { return mAxisSelectionBox; } + QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } + QRect labelSelectionBox() const { return mLabelSelectionBox; } + + // public property members: + QCPAxis::AxisType type; + QPen basePen; + QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters + int labelPadding; // directly accessed by QCPAxis setters/getters + QFont labelFont; + QColor labelColor; + QString label; + int tickLabelPadding; // directly accessed by QCPAxis setters/getters + double tickLabelRotation; // directly accessed by QCPAxis setters/getters + QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters + bool substituteExponent; + bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters + int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters + QPen tickPen, subTickPen; + QFont tickLabelFont; + QColor tickLabelColor; + QRect axisRect, viewportRect; + double offset; // directly accessed by QCPAxis setters/getters + bool abbreviateDecimalPowers; + bool reversedEndings; + + QVector subTickPositions; + QVector tickPositions; + QVector tickLabels; + +protected: + struct CachedLabel + { + QPointF offset; + QPixmap pixmap; + }; + struct TickLabelData + { + QString basePart, expPart, suffixPart; + QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds; + QFont baseFont, expFont; + }; + QCustomPlot *mParentPlot; + QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters + QCache mLabelCache; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + + virtual QByteArray generateLabelParameterHash() const; + + virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); + virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; + virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; + virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; + virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; +}; + +/* end of 'src/axis/axis.h' */ + + +/* including file 'src/scatterstyle.h', size 7275 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPScatterStyle +{ + Q_GADGET +public: + /*! + Represents the various properties of a scatter style instance. For example, this enum is used + to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when + highlighting selected data points. + + Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref + setFromOther. + */ + enum ScatterProperty { spNone = 0x00 ///< 0x00 None + ,spPen = 0x01 ///< 0x01 The pen property, see \ref setPen + ,spBrush = 0x02 ///< 0x02 The brush property, see \ref setBrush + ,spSize = 0x04 ///< 0x04 The size property, see \ref setSize + ,spShape = 0x08 ///< 0x08 The shape property, see \ref setShape + ,spAll = 0xFF ///< 0xFF All properties + }; + Q_ENUMS(ScatterProperty) + Q_FLAGS(ScatterProperties) + Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty) + + /*! + Defines the shape used for scatter points. + + On plottables/items that draw scatters, the sizes of these visualizations (with exception of + \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are + drawn with the pen and brush specified with \ref setPen and \ref setBrush. + */ + enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) + ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) + ,ssCross ///< \enumimage{ssCross.png} a cross + ,ssPlus ///< \enumimage{ssPlus.png} a plus + ,ssCircle ///< \enumimage{ssCircle.png} a circle + ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) + ,ssSquare ///< \enumimage{ssSquare.png} a square + ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond + ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus + ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline + ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner + ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside + ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside + ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside + ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside + ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines + ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates + ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) + }; + Q_ENUMS(ScatterShape) + + QCPScatterStyle(); + QCPScatterStyle(ScatterShape shape, double size=6); + QCPScatterStyle(ScatterShape shape, const QColor &color, double size); + QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); + QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); + QCPScatterStyle(const QPixmap &pixmap); + QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); + + // getters: + double size() const { return mSize; } + ScatterShape shape() const { return mShape; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QPixmap pixmap() const { return mPixmap; } + QPainterPath customPath() const { return mCustomPath; } + + // setters: + void setFromOther(const QCPScatterStyle &other, ScatterProperties properties); + void setSize(double size); + void setShape(ScatterShape shape); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setPixmap(const QPixmap &pixmap); + void setCustomPath(const QPainterPath &customPath); + + // non-property methods: + bool isNone() const { return mShape == ssNone; } + bool isPenDefined() const { return mPenDefined; } + void undefinePen(); + void applyTo(QCPPainter *painter, const QPen &defaultPen) const; + void drawShape(QCPPainter *painter, const QPointF &pos) const; + void drawShape(QCPPainter *painter, double x, double y) const; + +protected: + // property members: + double mSize; + ScatterShape mShape; + QPen mPen; + QBrush mBrush; + QPixmap mPixmap; + QPainterPath mCustomPath; + + // non-property members: + bool mPenDefined; +}; +Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) + +/* end of 'src/scatterstyle.h' */ + + +/* including file 'src/datacontainer.h', size 4596 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +/*! \relates QCPDataContainer + Returns whether the sort key of \a a is less than the sort key of \a b. + + \see QCPDataContainer::sort +*/ +template +inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); } + +template +class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below) +{ +public: + typedef typename QVector::const_iterator const_iterator; + typedef typename QVector::iterator iterator; + + QCPDataContainer(); + + // pointer to data + QVector * data() { return &mData; } + + // getters: + int size() const { return mData.size()-mPreallocSize; } + bool isEmpty() const { return size() == 0; } + bool autoSqueeze() const { return mAutoSqueeze; } + + // setters: + void setAutoSqueeze(bool enabled); + + // non-virtual methods: + void set(const QCPDataContainer &data); + void set(const QVector &data, bool alreadySorted=false); + void add(const QCPDataContainer &data); + void add(const QVector &data, bool alreadySorted=false); + void add(const DataType &data); + void removeBefore(double sortKey); + void removeAfter(double sortKey); + void remove(double sortKeyFrom, double sortKeyTo); + void remove(double sortKey); + void clear(); + void sort(); + void squeeze(bool preAllocation=true, bool postAllocation=true); + + const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; } + const_iterator constEnd() const { return mData.constEnd(); } + iterator begin() { return mData.begin()+mPreallocSize; } + iterator end() { return mData.end(); } + const_iterator findBegin(double sortKey, bool expandedRange=true) const; + const_iterator findEnd(double sortKey, bool expandedRange=true) const; + const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); } + QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth); + QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()); + QCPDataRange dataRange() const { return QCPDataRange(0, size()); } + void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const; + +protected: + // property members: + bool mAutoSqueeze; + + // non-property memebers: + QVector mData; + int mPreallocSize; + int mPreallocIteration; + + // non-virtual methods: + void preallocateGrow(int minimumPreallocSize); + void performAutoSqueeze(); +}; + +// include implementation in header since it is a class template: + +/* including file 'src/datacontainer.cpp', size 31349 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataContainer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataContainer + \brief The generic data container for one-dimensional plottables + + This class template provides a fast container for data storage of one-dimensional data. The data + type is specified as template parameter (called \a DataType in the following) and must provide + some methods as described in the \ref qcpdatacontainer-datatype "next section". + + The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well + as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The + container uses a preallocation and a postallocation scheme, such that appending and prepending + data (with respect to the sort key) is very fast and minimizes reallocations. If data is added + which needs to be inserted between existing keys, the merge usually can be done quickly too, + using the fact that existing data is always sorted. The user can further improve performance by + specifying that added data is already itself sorted by key, if he can guarantee that this is the + case (see for example \ref add(const QVector &data, bool alreadySorted)). + + The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If + it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin, + \ref end). Changing data members that are not the sort key (for most data types called \a key) is + safe from the container's perspective. + + Great care must be taken however if the sort key is modified through the non-const iterators. For + performance reasons, the iterators don't automatically cause a re-sorting upon their + manipulation. It is thus the responsibility of the user to leave the container in a sorted state + when finished with the data manipulation, before calling any other methods on the container. A + complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref + sort. Failing to do so can not be detected by the container efficiently and will cause both + rendering artifacts and potential data loss. + + Implementing one-dimensional plottables that make use of a \ref QCPDataContainer is usually + done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D", which + introduces an according \a mDataContainer member and some convenience methods. + + \section qcpdatacontainer-datatype Requirements for the DataType template parameter + + The template parameter DataType is the type of the stored data points. It must be + trivially copyable and have the following public methods, preferably inline: + + \li double sortKey() const\n Returns the member variable of this data point that is the + sort key, defining the ordering in the container. Often this variable is simply called \a key. + + \li static DataType fromSortKey(double sortKey)\n Returns a new instance of the data + type initialized with its sort key set to \a sortKey. + + \li static bool sortKeyIsMainKey()\n Returns true if the sort key is equal to the main + key (see method \c mainKey below). For most plottables this is the case. It is not the case for + example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason + why QCPCurve unlike QCPGraph can display parametric curves with loops. + + \li double mainKey() const\n Returns the variable of this data point considered the main + key. This is commonly the variable that is used as the coordinate of this data point on the key + axis of the plottable. This method is used for example when determining the automatic axis + rescaling of key axes (\ref QCPAxis::rescale). + + \li double mainValue() const\n Returns the variable of this data point considered the + main value. This is commonly the variable that is used as the coordinate of this data point on + the value axis of the plottable. + + \li QCPRange valueRange() const\n Returns the range this data point spans in the value + axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with + both lower and upper set to the main data point value. However if the data points can represent + multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close + values at each \a key) this method should return the range those values span. This method is used + for example when determining the automatic axis rescaling of value axes (\ref + QCPAxis::rescale). +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataContainer::size() const + + Returns the number of data points in the container. +*/ + +/*! \fn bool QCPDataContainer::isEmpty() const + + Returns whether this container holds no data points. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constBegin() const + + Returns a const iterator to the first data point in this container. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constEnd() const + + Returns a const iterator to the element past the last data point in this container. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::begin() const + + Returns a non-const iterator to the first data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::end() const + + Returns a non-const iterator to the element past the last data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::at(int index) const + + Returns a const iterator to the element with the specified \a index. If \a index points beyond + the available elements in this container, returns \ref constEnd, i.e. an iterator past the last + valid element. + + You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref + dataselection-accessing "data selection page" for an example. +*/ + +/*! \fn QCPDataRange QCPDataContainer::dataRange() const + + Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the + begin index of the returned range is 0, and the end index is \ref size. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted + data +*/ +template +QCPDataContainer::QCPDataContainer() : + mAutoSqueeze(true), + mPreallocSize(0), + mPreallocIteration(0) +{ +} + +/*! + Sets whether the container automatically decides when to release memory from its post- and + preallocation pools when data points are removed. By default this is enabled and for typical + applications shouldn't be changed. + + If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with + \ref squeeze. +*/ +template +void QCPDataContainer::setAutoSqueeze(bool enabled) +{ + if (mAutoSqueeze != enabled) + { + mAutoSqueeze = enabled; + if (mAutoSqueeze) + performAutoSqueeze(); + } +} + +/*! \overload + + Replaces the current data in this container with the provided \a data. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QCPDataContainer &data) +{ + clear(); + add(data); +} + +/*! \overload + + Replaces the current data in this container with the provided \a data + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QVector &data, bool alreadySorted) +{ + mData = data; + mPreallocSize = 0; + mPreallocIteration = 0; + if (!alreadySorted) + sort(); +} + +/*! \overload + + Adds the provided \a data to the current data in this container. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QCPDataContainer &data) +{ + if (data.isEmpty()) + return; + + const int n = data.size(); + const int oldSize = size(); + + if (oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! + Adds the provided data points in \a data to the current data. + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QVector &data, bool alreadySorted) +{ + if (data.isEmpty()) + return; + if (isEmpty()) + { + set(data, alreadySorted); + return; + } + + const int n = data.size(); + const int oldSize = size(); + + if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and then sort and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (!alreadySorted) // sort appended subrange if it wasn't already sorted + std::sort(end()-n, end(), qcpLessThanSortKey); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! \overload + + Adds the provided single data point to the current data. + + \see remove +*/ +template +void QCPDataContainer::add(const DataType &data) +{ + if (isEmpty() || !qcpLessThanSortKey(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones + { + mData.append(data); + } else if (qcpLessThanSortKey(data, *constBegin())) // quickly handle prepends using preallocated space + { + if (mPreallocSize < 1) + preallocateGrow(1); + --mPreallocSize; + *begin() = data; + } else // handle inserts, maintaining sorted keys + { + QCPDataContainer::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey); + mData.insert(insertionPoint, data); + } +} + +/*! + Removes all data points with (sort-)keys smaller than or equal to \a sortKey. + + \see removeAfter, remove, clear +*/ +template +void QCPDataContainer::removeBefore(double sortKey) +{ + QCPDataContainer::iterator it = begin(); + QCPDataContainer::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + mPreallocSize += itEnd-it; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys greater than or equal to \a sortKey. + + \see removeBefore, remove, clear +*/ +template +void QCPDataContainer::removeAfter(double sortKey) +{ + QCPDataContainer::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = end(); + mData.erase(it, itEnd); // typically adds it to the postallocated block + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a + sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single + data point with known (sort-)key, use \ref remove(double sortKey). + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) +{ + if (sortKeyFrom >= sortKeyTo || isEmpty()) + return; + + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey); + mData.erase(it, itEnd); + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! \overload + + Removes a single data point at \a sortKey. If the position is not known with absolute (binary) + precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small + fuzziness interval around the suspected position, depeding on the precision with which the + (sort-)key is known. + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKey) +{ + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (it != end() && it->sortKey() == sortKey) + { + if (it == begin()) + ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + else + mData.erase(it); + } + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points. + + \see remove, removeAfter, removeBefore +*/ +template +void QCPDataContainer::clear() +{ + mData.clear(); + mPreallocIteration = 0; + mPreallocSize = 0; +} + +/*! + Re-sorts all data points in the container by their sort key. + + When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add, + \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full + resort is never necessary. However, if you choose to directly manipulate the sort key on data + points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it + is your responsibility to bring the container back into a sorted state before any other methods + are called on it. This can be achieved by calling this method immediately after finishing the + sort key manipulation. +*/ +template +void QCPDataContainer::sort() +{ + std::sort(begin(), end(), qcpLessThanSortKey); +} + +/*! + Frees all unused memory that is currently in the preallocation and postallocation pools. + + Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref + setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical + applications. + + The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation + should be freed, respectively. +*/ +template +void QCPDataContainer::squeeze(bool preAllocation, bool postAllocation) +{ + if (preAllocation) + { + if (mPreallocSize > 0) + { + std::copy(begin(), end(), mData.begin()); + mData.resize(size()); + mPreallocSize = 0; + } + mPreallocIteration = 0; + } + if (postAllocation) + mData.squeeze(); +} + +/*! + Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just + above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be + considered, otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is + returned. + + If the container is empty, returns \ref constEnd. + + \see findEnd, QCPPlottableInterface1D::findBegin +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findBegin(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty + --it; + return it; +} + +/*! + Returns an iterator to the element after the data point with a (sort-)key that is equal to, just + above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey + will be considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is + returned. + + If the container is empty, \ref constEnd is returned. + + \see findBegin, QCPPlottableInterface1D::findEnd +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findEnd(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constEnd()) + ++it; + return it; +} + +/*! + Returns the range encompassed by the (main-)key coordinate of all data points. The output + parameter \a foundRange indicates whether a sensible range was found. If this is false, you + should not use the returned QCPRange (e.g. the data container is empty or all points have the + same key). + + Use \a signDomain to control which sign of the key coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is + the case for most plottables, this method uses this fact and finds the range very quickly. + + \see valueRange +*/ +template +QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain signDomain) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + double current; + + QCPDataContainer::const_iterator it = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (signDomain == QCP::sdBoth) // range may be anywhere + { + if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value + { + while (it != itEnd) // find first non-nan going up from left + { + if (!qIsNaN(it->mainValue())) + { + range.lower = it->mainKey(); + haveLower = true; + break; + } + ++it; + } + it = itEnd; + while (it != constBegin()) // find first non-nan going down from right + { + --it; + if (!qIsNaN(it->mainValue())) + { + range.upper = it->mainKey(); + haveUpper = true; + break; + } + } + } else // DataType is not sorted by main key, go through all data points and accordingly expand range + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Returns the range encompassed by the value coordinates of the data points in the specified key + range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The + output parameter \a foundRange indicates whether a sensible range was found. If this is false, + you should not use the returned QCPRange (e.g. the data container is empty or all points have the + same value). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Use \a signDomain to control which sign of the value coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + \see keyRange +*/ +template +QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPRange current; + QCPDataContainer::const_iterator itBegin = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (DataType::sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = findBegin(inKeyRange.lower); + itEnd = findEnd(inKeyRange.upper); + } + if (signDomain == QCP::sdBoth) // range may be anywhere + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Makes sure \a begin and \a end mark a data range that is both within the bounds of this data + container's data, as well as within the specified \a dataRange. The initial range described by + the passed iterators \a begin and \a end is never expanded, only contracted if necessary. + + This function doesn't require for \a dataRange to be within the bounds of this data container's + valid range. +*/ +template +void QCPDataContainer::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const +{ + QCPDataRange iteratorRange(begin-constBegin(), end-constBegin()); + iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange())); + begin = constBegin()+iteratorRange.begin(); + end = constBegin()+iteratorRange.end(); +} + +/*! \internal + + Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on + the preallocation history, the container will grow by more than requested, to speed up future + consecutive size increases. + + if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this + method does nothing. +*/ +template +void QCPDataContainer::preallocateGrow(int minimumPreallocSize) +{ + if (minimumPreallocSize <= mPreallocSize) + return; + + int newPreallocSize = minimumPreallocSize; + newPreallocSize += (1u< +void QCPDataContainer::performAutoSqueeze() +{ + const int totalAlloc = mData.capacity(); + const int postAllocSize = totalAlloc-mData.size(); + const int usedSize = size(); + bool shrinkPostAllocation = false; + bool shrinkPreAllocation = false; + if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size + { + shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate! + shrinkPreAllocation = mPreallocSize*10 > usedSize; + } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother + { + shrinkPostAllocation = postAllocSize > usedSize*5; + shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller + } + + if (shrinkPreAllocation || shrinkPostAllocation) + squeeze(shrinkPreAllocation, shrinkPostAllocation); +} +/* end of 'src/datacontainer.cpp' */ + + +/* end of 'src/datacontainer.h' */ + + +/* including file 'src/plottable.h', size 8312 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPSelectionDecorator +{ + Q_GADGET +public: + QCPSelectionDecorator(); + virtual ~QCPSelectionDecorator(); + + // getters: + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; } + + // setters: + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); + void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); + + // non-virtual methods: + void applyPen(QCPPainter *painter) const; + void applyBrush(QCPPainter *painter) const; + QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; + + // introduced virtual methods: + virtual void copyFrom(const QCPSelectionDecorator *other); + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); + +protected: + // property members: + QPen mPen; + QBrush mBrush; + QCPScatterStyle mScatterStyle; + QCPScatterStyle::ScatterProperties mUsedScatterProperties; + // non-property members: + QCPAbstractPlottable *mPlottable; + + // introduced virtual methods: + virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); + +private: + Q_DISABLE_COPY(QCPSelectionDecorator) + friend class QCPAbstractPlottable; +}; +Q_DECLARE_METATYPE(QCPSelectionDecorator*) + + +class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) + Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) + Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) + Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged) + Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator) + /// \endcond +public: + QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable(); + + // getters: + QString name() const { return mName; } + QString desc() const { return mDesc; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCP::SelectionType selectable() const { return mSelectable; } + bool selected() const { return !mSelection.isEmpty(); } + QCPDataSelection selection() const { return mSelection; } + QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } + + // setters: + void setName(const QString &name); + void setDesc(const QString &desc); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setKeyAxis(QCPAxis *axis); + void setValueAxis(QCPAxis *axis); + Q_SLOT void setSelectable(QCP::SelectionType selectable); + Q_SLOT void setSelection(QCPDataSelection selection); + void setSelectionDecorator(QCPSelectionDecorator *decorator); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; + virtual QCPPlottableInterface1D *interface1D() { return 0; } + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; + + // non-property methods: + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; + bool addToLegend(QCPLegend *legend); + bool addToLegend(); + bool removeFromLegend(QCPLegend *legend) const; + bool removeFromLegend() const; + +signals: + void selectionChanged(bool selected); + void selectionChanged(const QCPDataSelection &selection); + void selectableChanged(QCP::SelectionType selectable); + +protected: + // property members: + QString mName; + QString mDesc; + bool mAntialiasedFill, mAntialiasedScatters; + QPen mPen; + QBrush mBrush; + QPointer mKeyAxis, mValueAxis; + QCP::SelectionType mSelectable; + QCPDataSelection mSelection; + QCPSelectionDecorator *mSelectionDecorator; + + // reimplemented virtual methods: + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; + + // non-virtual methods: + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable) + + friend class QCustomPlot; + friend class QCPAxis; + friend class QCPPlottableLegendItem; +}; + + +/* end of 'src/plottable.h' */ + + +/* including file 'src/item.h', size 9384 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemAnchor +{ + Q_GADGET +public: + QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); + virtual ~QCPItemAnchor(); + + // getters: + QString name() const { return mName; } + virtual QPointF pixelPosition() const; + +protected: + // property members: + QString mName; + + // non-property members: + QCustomPlot *mParentPlot; + QCPAbstractItem *mParentItem; + int mAnchorId; + QSet mChildrenX, mChildrenY; + + // introduced virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return 0; } + + // non-virtual methods: + void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + +private: + Q_DISABLE_COPY(QCPItemAnchor) + + friend class QCPItemPosition; +}; + + + +class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor +{ + Q_GADGET +public: + /*! + Defines the ways an item position can be specified. Thus it defines what the numbers passed to + \ref setCoords actually mean. + + \see setType + */ + enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. + ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the viewport/widget, etc. + ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. + ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). + }; + Q_ENUMS(PositionType) + + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name); + virtual ~QCPItemPosition(); + + // getters: + PositionType type() const { return typeX(); } + PositionType typeX() const { return mPositionTypeX; } + PositionType typeY() const { return mPositionTypeY; } + QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } + QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } + QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } + double key() const { return mKey; } + double value() const { return mValue; } + QPointF coords() const { return QPointF(mKey, mValue); } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCPAxisRect *axisRect() const; + virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; + + // setters: + void setType(PositionType type); + void setTypeX(PositionType type); + void setTypeY(PositionType type); + bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + void setCoords(double key, double value); + void setCoords(const QPointF &coords); + void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); + void setAxisRect(QCPAxisRect *axisRect); + void setPixelPosition(const QPointF &pixelPosition); + +protected: + // property members: + PositionType mPositionTypeX, mPositionTypeY; + QPointer mKeyAxis, mValueAxis; + QPointer mAxisRect; + double mKey, mValue; + QCPItemAnchor *mParentAnchorX, *mParentAnchorY; + + // reimplemented virtual methods: + virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } + +private: + Q_DISABLE_COPY(QCPItemPosition) + +}; +Q_DECLARE_METATYPE(QCPItemPosition::PositionType) + + +class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) + Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPAbstractItem(QCustomPlot *parentPlot); + virtual ~QCPAbstractItem(); + + // getters: + bool clipToAxisRect() const { return mClipToAxisRect; } + QCPAxisRect *clipAxisRect() const; + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setClipToAxisRect(bool clip); + void setClipAxisRect(QCPAxisRect *rect); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE = 0; + + // non-virtual methods: + QList positions() const { return mPositions; } + QList anchors() const { return mAnchors; } + QCPItemPosition *position(const QString &name) const; + QCPItemAnchor *anchor(const QString &name) const; + bool hasAnchor(const QString &name) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + bool mClipToAxisRect; + QPointer mClipAxisRect; + QList mPositions; + QList mAnchors; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual QPointF anchorPixelPosition(int anchorId) const; + + // non-virtual methods: + double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const; + QCPItemPosition *createPosition(const QString &name); + QCPItemAnchor *createAnchor(const QString &name, int anchorId); + +private: + Q_DISABLE_COPY(QCPAbstractItem) + + friend class QCustomPlot; + friend class QCPItemAnchor; +}; + +/* end of 'src/item.h' */ + + +/* including file 'src/core.h', size 14886 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCustomPlot : public QWidget +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) + Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) + Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) + Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) + Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) + Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl) + /// \endcond +public: + /*! + Defines how a layer should be inserted relative to an other layer. + + \see addLayer, moveLayer + */ + enum LayerInsertMode { limBelow ///< Layer is inserted below other layer + ,limAbove ///< Layer is inserted above other layer + }; + Q_ENUMS(LayerInsertMode) + + /*! + Defines with what timing the QCustomPlot surface is refreshed after a replot. + + \see replot + */ + enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot + ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided. + ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints. + ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. + }; + Q_ENUMS(RefreshPriority) + + explicit QCustomPlot(QWidget *parent = 0); + virtual ~QCustomPlot(); + + // getters: + QRect viewport() const { return mViewport; } + double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + QCPLayoutGrid *plotLayout() const { return mPlotLayout; } + QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } + QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } + bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } + const QCP::Interactions interactions() const { return mInteractions; } + int selectionTolerance() const { return mSelectionTolerance; } + bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } + QCP::PlottingHints plottingHints() const { return mPlottingHints; } + Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } + QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } + QCPSelectionRect *selectionRect() const { return mSelectionRect; } + bool openGl() const { return mOpenGl; } + QPoint symbolPos() { return mSymbolPos; } + + // setters: + void setSymbolPos(const QPoint pos); + void setViewport(const QRect &rect); + void setBufferDevicePixelRatio(double ratio); + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); + void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); + void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); + void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); + void setAutoAddPlottableToLegend(bool on); + void setInteractions(const QCP::Interactions &interactions); + void setInteraction(const QCP::Interaction &interaction, bool enabled=true); + void setSelectionTolerance(int pixels); + void setNoAntialiasingOnDrag(bool enabled); + void setPlottingHints(const QCP::PlottingHints &hints); + void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); + void setMultiSelectModifier(Qt::KeyboardModifier modifier); + void setSelectionRectMode(QCP::SelectionRectMode mode); + void setSelectionRect(QCPSelectionRect *selectionRect); + void setOpenGl(bool enabled, int multisampling=16); + + // non-property methods: + // plottable interface: + QCPAbstractPlottable *plottable(int index); + QCPAbstractPlottable *plottable(); + bool removePlottable(QCPAbstractPlottable *plottable); + bool removePlottable(int index); + int clearPlottables(); + int plottableCount() const; + QList selectedPlottables() const; + QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasPlottable(QCPAbstractPlottable *plottable) const; + + // specialized interface for QCPGraph: + QCPGraph *graph(int index) const; + QCPGraph *graph() const; + QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); + bool removeGraph(QCPGraph *graph); + bool removeGraph(int index); + int clearGraphs(); + int graphCount() const; + QList selectedGraphs() const; + + // item interface: + QCPAbstractItem *item(int index) const; + QCPAbstractItem *item() const; + bool removeItem(QCPAbstractItem *item); + bool removeItem(int index); + int clearItems(bool clearTitle = false); + int itemCount() const; + QList selectedItems() const; + QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasItem(QCPAbstractItem *item) const; + + // layer interface: + QCPLayer *layer(const QString &name) const; + QCPLayer *layer(int index) const; + QCPLayer *currentLayer() const; + bool setCurrentLayer(const QString &name); + bool setCurrentLayer(QCPLayer *layer); + int layerCount() const; + bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); + bool removeLayer(QCPLayer *layer); + bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); + + // axis rect/layout interface: + int axisRectCount() const; + QCPAxisRect* axisRect(int index=0) const; + QList axisRects() const; + QCPLayoutElement* layoutElementAt(const QPointF &pos) const; + QCPAxisRect* axisRectAt(const QPointF &pos) const; + Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); + + QList selectedAxes() const; + QList selectedLegends() const; + Q_SLOT void deselectAll(); + + bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); + bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + QPixmap toPixmap(int width=0, int height=0, double scale=1.0); + void toPainter(QCPPainter *painter, int width=0, int height=0); + Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); + + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + QCPLegend *legend; + +signals: + void mouseDoubleClick(QMouseEvent *event); + void mousePress(QMouseEvent *event); + void mouseMove(QMouseEvent *event); + void mouseRelease(QMouseEvent *event); + void mouseWheel(QWheelEvent *event); + + //< 鼠标按下 更新CCurveLegendModel值 + void symbolPosChanged(const double &value); + + void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void itemClick(QCPAbstractItem *item, QMouseEvent *event); + void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); + void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + + void selectionChangedByUser(); + void beforeReplot(); + void afterReplot(); + +protected: + // property members: + QRect mViewport; + double mBufferDevicePixelRatio; + QCPLayoutGrid *mPlotLayout; + bool mAutoAddPlottableToLegend; + QList mPlottables; + QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph + QList mItems; + QList mLayers; + QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; + QCP::Interactions mInteractions; + int mSelectionTolerance; + bool mNoAntialiasingOnDrag; + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayer *mCurrentLayer; + QCP::PlottingHints mPlottingHints; + Qt::KeyboardModifier mMultiSelectModifier; + QCP::SelectionRectMode mSelectionRectMode; + QCPSelectionRect *mSelectionRect; + bool mOpenGl; + + // non-property members: + QList > mPaintBuffers; + bool mSymbolPressed; + QPoint mSymbolPos; + QPoint mMousePressPos; + bool mMouseHasMoved; + QPointer mMouseEventLayerable; + QPointer mMouseSignalLayerable; + QVariant mMouseEventLayerableDetails; + QVariant mMouseSignalLayerableDetails; + bool mReplotting; + bool mReplotQueued; + int mOpenGlMultisamples; + QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup; + bool mOpenGlCacheLabelsBackup; +#ifdef QCP_OPENGL_FBO + QSharedPointer mGlContext; + QSharedPointer mGlSurface; + QSharedPointer mGlPaintDevice; +#endif + + // reimplemented virtual methods: + virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + virtual QSize sizeHint() const Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + bool eventFilter(QObject *object, QEvent *event); + + // introduced virtual methods: + virtual void draw(QCPPainter *painter); + virtual void updateLayout(); + virtual void axisRemoved(QCPAxis *axis); + virtual void legendRemoved(QCPLegend *legend); + Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processPointSelection(QMouseEvent *event); + + // non-virtual methods: + bool registerPlottable(QCPAbstractPlottable *plottable); + bool registerGraph(QCPGraph *graph); + bool registerItem(QCPAbstractItem* item); + void updateLayerIndices() const; + QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; + QList layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails=0) const; + void drawBackground(QCPPainter *painter); + void setupPaintBuffers(); + QCPAbstractPaintBuffer *createPaintBuffer(); + bool hasInvalidatedPaintBuffers(); + bool setupOpenGl(); + void freeOpenGl(); + + friend class QCPLegend; + friend class QCPAxis; + friend class QCPLayer; + friend class QCPAxisRect; + friend class QCPAbstractPlottable; + friend class QCPGraph; + friend class QCPAbstractItem; +}; +Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode) +Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) + +/* end of 'src/core.h' */ + + +/* including file 'src/plottable1d.h', size 4544 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCPPlottableInterface1D +{ +public: + virtual ~QCPPlottableInterface1D() {} + // introduced pure virtual methods: + virtual int dataCount() const = 0; + virtual double dataMainKey(int index) const = 0; + virtual double dataSortKey(int index) const = 0; + virtual double dataMainValue(int index) const = 0; + virtual QCPRange dataValueRange(int index) const = 0; + virtual QPointF dataPixelPosition(int index) const = 0; + virtual bool sortKeyIsMainKey() const = 0; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + virtual int findBegin(double sortKey, bool expandedRange=true) const = 0; + virtual int findEnd(double sortKey, bool expandedRange=true) const = 0; +}; + +template +class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below) +{ + // No Q_OBJECT macro due to template class + +public: + QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable1D(); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const Q_DECL_OVERRIDE; + virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; + virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; + virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; + virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer > mDataContainer; + + // helpers for subclasses: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + void drawPolyline(QCPPainter *painter, const QVector &lineData) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable1D) + +}; + +// include implementation in header since it is a class template: + +/* including file 'src/plottable1d.cpp', size 22240 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableInterface1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableInterface1D + \brief Defines an abstract interface for one-dimensional plottables + + This class contains only pure virtual methods which define a common interface to the data + of one-dimensional plottables. + + For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred + base class for one-dimensional plottables). So if you use that template class as base class of + your one-dimensional plottable, you won't have to care about implementing the 1d interface + yourself. + + If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d + interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref + QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure + virtual methods of the 1d interface, matching your data container. Also, reimplement \ref + QCPAbstractPlottable::interface1D to return the \c this pointer. + + If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this + interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return + value. If it indeed implements this interface, you may use it to access the plottable's data + without needing to know the exact type of the plottable or its data point type. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; + + Returns the number of data points of the plottable. +*/ + +/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + + Returns a data selection containing all the data points of this plottable which are contained (or + hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref + dataselection "data selection mechanism"). + + If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not + selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). + + \note \a rect must be a normalized rect (positive or zero width and height). This is especially + important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily + normalized. Use QRect::normalized() when passing a rect which might not be normalized. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 + + Returns the main key of the data point at the given \a index. + + What the main key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 + + Returns the sort key of the data point at the given \a index. + + What the sort key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 + + Returns the main value of the data point at the given \a index. + + What the main value is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 + + Returns the value range of the data point at the given \a index. + + What the value range is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0 + + Returns the pixel position on the widget surface at which the data point at the given \a index + appears. + + Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel + coordinates. However, depending on the plottable, this might be a different apparent position + than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data + values can be shifted depending on their stacking, bar grouping or configured base value. +*/ + +/*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0 + + Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey). + + What the sort and main keys are, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0 + + Returns the index of the data point with a (sort-)key that is equal to, just below, or just above + \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered, + otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned. + + If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop + using these methods will not iterate over the index 0). + + \see findEnd, QCPDataContainer::findBegin +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0 + + Returns the index one after the data point with a (sort-)key that is equal to, just above, or + just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be + considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, the index just above the + highest data point is returned. + + If the container is empty, returns 0. + + \see findBegin, QCPDataContainer::findEnd +*/ + +/* end documentation of pure virtual functions */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable1D + \brief A template base class for plottables with one-dimensional data + + This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref + QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with + one key dimension), such as \ref QCPGraph and QCPCurve. + + The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref + QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member + \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer") and + implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most + subclassed plottables don't need to worry about this anymore. + + Further, it provides a convenience method for retrieving selected/unselected data segments via + \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to + draw selected segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref + QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data + interface. In spite of that, most plottable subclasses will want to reimplement those methods + again, to provide a more accurate hit test based on their specific data visualization geometry. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() + + Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D + interface. + + \seebaseclassmethod +*/ + +/* end documentation of inline functions */ + +/*! + Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable + "QCPAbstractPlottable" constructor and allocates the \a mDataContainer. +*/ +template +QCPAbstractPlottable1D::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QCPDataContainer) +{ +} + +template +QCPAbstractPlottable1D::~QCPAbstractPlottable1D() +{ +} + +/*! + \copydoc QCPPlottableInterface1D::dataCount +*/ +template +int QCPAbstractPlottable1D::dataCount() const +{ + return mDataContainer->size(); +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainKey +*/ +template +double QCPAbstractPlottable1D::dataMainKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataSortKey +*/ +template +double QCPAbstractPlottable1D::dataSortKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->sortKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainValue +*/ +template +double QCPAbstractPlottable1D::dataMainValue(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainValue(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataValueRange +*/ +template +QCPRange QCPAbstractPlottable1D::dataValueRange(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->valueRange(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QCPRange(0, 0); + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataPixelPosition +*/ +template +QPointF QCPAbstractPlottable1D::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + const typename QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + return coordsToPixels(it->mainKey(), it->mainValue()); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/*! + \copydoc QCPPlottableInterface1D::sortKeyIsMainKey +*/ +template +bool QCPAbstractPlottable1D::sortKeyIsMainKey() const +{ + return DataType::sortKeyIsMainKey(); +} + +/*! + Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + // convert rect given in pixels to ranges given in plot coordinates: + double key1, value1, key2, value2; + pixelsToCoords(rect.topLeft(), key1, value1); + pixelsToCoords(rect.bottomRight(), key2, value2); + QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2 + QCPRange valueRange(value1, value2); + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + begin = mDataContainer->findBegin(keyRange.lower, false); + end = mDataContainer->findEnd(keyRange.upper, false); + } + if (begin == end) + return result; + + int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (currentSegmentBegin == -1) + { + if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment + currentSegmentBegin = it-mDataContainer->constBegin(); + } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended + { + result.addDataRange(QCPDataRange(currentSegmentBegin, it-mDataContainer->constBegin()), false); + currentSegmentBegin = -1; + } + } + // process potential last segment: + if (currentSegmentBegin != -1) + result.addDataRange(QCPDataRange(currentSegmentBegin, end-mDataContainer->constBegin()), false); + + result.simplify(); + return result; +} + +/*! + \copydoc QCPPlottableInterface1D::findBegin +*/ +template +int QCPAbstractPlottable1D::findBegin(double sortKey, bool expandedRange) const +{ + return mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin(); +} + +/*! + \copydoc QCPPlottableInterface1D::findEnd +*/ +template +int QCPAbstractPlottable1D::findEnd(double sortKey, bool expandedRange) const +{ + return mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin(); +} + +/*! + Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + QCPDataSelection selectionResult; + double minDistSqr = std::numeric_limits::max(); + int minDistIndex = mDataContainer->size(); + + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + begin = mDataContainer->findBegin(posKeyMin, true); + end = mDataContainer->findEnd(posKeyMax, true); + } + if (begin == end) + return -1; + QCPRange keyRange(mKeyAxis->range()); + QCPRange valueRange(mValueAxis->range()); + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double mainKey = it->mainKey(); + const double mainValue = it->mainValue(); + if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points + { + const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + minDistIndex = it-mDataContainer->constBegin(); + } + } + } + if (minDistIndex != mDataContainer->size()) + selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false); + + selectionResult.simplify(); + if (details) + details->setValue(selectionResult); + return qSqrt(minDistSqr); +} + +/*! + Splits all data into selected and unselected segments and outputs them via \a selectedSegments + and \a unselectedSegments, respectively. + + This is useful when subclasses implement their \ref draw method and need to draw selected + segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + \see setSelection +*/ +template +void QCPAbstractPlottable1D::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! + A helper method which draws a line with the passed \a painter, according to the pixel data in \a + lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is + the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or + crashing). + + Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c + QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter + style allows. +*/ +template +void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QVector &lineData) const +{ + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->modes().testFlag(QCPPainter::pmVectorized) && + !painter->modes().testFlag(QCPPainter::pmNoCaching)) + { + int i = 0; + bool lastIsNan = false; + const int lineDataSize = lineData.size(); + while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN + ++i; + ++i; // because drawing works in 1 point retrospect + while (i < lineDataSize) + { + if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line + { + if (!lastIsNan) + painter->drawLine(lineData.at(i-1), lineData.at(i)); + else + lastIsNan = false; + } else + lastIsNan = true; + ++i; + } + } else + { + int segmentStart = 0; + int i = 0; + const int lineDataSize = lineData.size(); + while (i < lineDataSize) + { + if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block + { + painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point + segmentStart = i+1; + } + ++i; + } + // draw last segment: + painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart); + } +} +/* end of 'src/plottable1d.cpp' */ + + +/* end of 'src/plottable1d.h' */ + + +/* including file 'src/colorgradient.h', size 6243 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPColorGradient +{ + Q_GADGET +public: + /*! + Defines the color spaces in which color interpolation between gradient stops can be performed. + + \see setColorInterpolation + */ + enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated + ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) + }; + Q_ENUMS(ColorInterpolation) + + /*! + Defines the available presets that can be loaded with \ref loadPreset. See the documentation + there for an image of the presets. + */ + enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) + ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) + ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) + ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) + ,gpCandy ///< Blue over pink to white + ,gpGeography ///< Colors suitable to represent different elevations on geographical maps + ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) + ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white + ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values + ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) + ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) + ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) + }; + Q_ENUMS(GradientPreset) + + QCPColorGradient(); + QCPColorGradient(GradientPreset preset); + bool operator==(const QCPColorGradient &other) const; + bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } + + // getters: + int levelCount() const { return mLevelCount; } + QMap colorStops() const { return mColorStops; } + ColorInterpolation colorInterpolation() const { return mColorInterpolation; } + bool periodic() const { return mPeriodic; } + + // setters: + void setLevelCount(int n); + void setColorStops(const QMap &colorStops); + void setColorStopAt(double position, const QColor &color); + void setColorInterpolation(ColorInterpolation interpolation); + void setPeriodic(bool enabled); + + // non-property methods: + void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + QRgb color(double position, const QCPRange &range, bool logarithmic=false); + void loadPreset(GradientPreset preset); + void clearColorStops(); + QCPColorGradient inverted() const; + +protected: + // property members: + int mLevelCount; + QMap mColorStops; + ColorInterpolation mColorInterpolation; + bool mPeriodic; + + // non-property members: + QVector mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied) + bool mColorBufferInvalidated; + + // non-virtual methods: + bool stopsUseAlpha() const; + void updateColorBuffer(); +}; +Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation) +Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) + +/* end of 'src/colorgradient.h' */ + + +/* including file 'src/selectiondecorator-bracket.h', size 4442 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator +{ + Q_GADGET +public: + + /*! + Defines which shape is drawn at the boundaries of selected data ranges. + + Some of the bracket styles further allow specifying a height and/or width, see \ref + setBracketHeight and \ref setBracketWidth. + */ + enum BracketStyle { bsSquareBracket ///< A square bracket is drawn. + ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsPlus ///< A plus is drawn. + ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket. + }; + Q_ENUMS(BracketStyle) + + QCPSelectionDecoratorBracket(); + virtual ~QCPSelectionDecoratorBracket(); + + // getters: + QPen bracketPen() const { return mBracketPen; } + QBrush bracketBrush() const { return mBracketBrush; } + int bracketWidth() const { return mBracketWidth; } + int bracketHeight() const { return mBracketHeight; } + BracketStyle bracketStyle() const { return mBracketStyle; } + bool tangentToData() const { return mTangentToData; } + int tangentAverage() const { return mTangentAverage; } + + // setters: + void setBracketPen(const QPen &pen); + void setBracketBrush(const QBrush &brush); + void setBracketWidth(int width); + void setBracketHeight(int height); + void setBracketStyle(BracketStyle style); + void setTangentToData(bool enabled); + void setTangentAverage(int pointCount); + + // introduced virtual methods: + virtual void drawBracket(QCPPainter *painter, int direction) const; + + // virtual methods: + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; + +protected: + // property members: + QPen mBracketPen; + QBrush mBracketBrush; + int mBracketWidth; + int mBracketHeight; + BracketStyle mBracketStyle; + bool mTangentToData; + int mTangentAverage; + + // non-virtual methods: + double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const; + QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; + +}; +Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) + +/* end of 'src/selectiondecorator-bracket.h' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); + virtual ~QCPAxisRect(); + + // getters: + QPixmap background() const { return mBackgroundPixmap; } + QBrush backgroundBrush() const { return mBackgroundBrush; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + Qt::Orientations rangeDrag() const { return mRangeDrag; } + Qt::Orientations rangeZoom() const { return mRangeZoom; } + QCPAxis *rangeDragAxis(Qt::Orientation orientation); + QCPAxis *rangeZoomAxis(Qt::Orientation orientation); + QList rangeDragAxes(Qt::Orientation orientation); + QList rangeZoomAxes(Qt::Orientation orientation); + double rangeZoomFactor(Qt::Orientation orientation); + + // setters: + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setRangeDrag(Qt::Orientations orientations); + void setRangeZoom(Qt::Orientations orientations); + void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeDragAxes(QList axes); + void setRangeDragAxes(QList horizontal, QList vertical); + void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomAxes(QList axes); + void setRangeZoomAxes(QList horizontal, QList vertical); + void setRangeZoomFactor(double horizontalFactor, double verticalFactor); + void setRangeZoomFactor(double factor); + + // non-property methods: + int axisCount(QCPAxis::AxisType type) const; + QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; + QList axes(QCPAxis::AxisTypes types) const; + QList axes() const; + QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); + QList addAxes(QCPAxis::AxisTypes types); + bool removeAxis(QCPAxis *axis); + QCPLayoutInset *insetLayout() const { return mInsetLayout; } + + void zoom(const QRectF &pixelRect); + void zoom(const QRectF &pixelRect, const QList &affectedAxes); + void setupFullAxesBox(bool connectRanges=false); + QList plottables() const; + QList graphs() const; + QList items() const; + + // read-only interface imitating a QRect: + int left() const { return mRect.left(); } + int right() const { return mRect.right(); } + int top() const { return mRect.top(); } + int bottom() const { return mRect.bottom(); } + int width() const { return mRect.width(); } + int height() const { return mRect.height(); } + QSize size() const { return mRect.size(); } + QPoint topLeft() const { return mRect.topLeft(); } + QPoint topRight() const { return mRect.topRight(); } + QPoint bottomLeft() const { return mRect.bottomLeft(); } + QPoint bottomRight() const { return mRect.bottomRight(); } + QPoint center() const { return mRect.center(); } + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + void setScaleRight(const bool &scaleRight = true) { mIsScaleRight = scaleRight; } + bool isScaleRight() { return mIsScaleRight; } + +signals: + void rangeDraged(); + void rangeScaled(); + +protected: + // property members: + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayoutInset *mInsetLayout; + Qt::Orientations mRangeDrag, mRangeZoom; + QList > mRangeDragHorzAxis, mRangeDragVertAxis; + QList > mRangeZoomHorzAxis, mRangeZoomVertAxis; + double mRangeZoomFactorHorz, mRangeZoomFactorVert; + + // non-property members: + QList mDragStartHorzRange, mDragStartVertRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + bool mDragging; + QHash > mAxes; + + //< ZH + bool mIsScaleRight; + bool mIsDragMove; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE; + virtual void layoutChanged() Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // non-property methods: + void drawBackground(QCPPainter *painter); + void updateAxesOffset(QCPAxis::AxisType type); + +private: + Q_DISABLE_COPY(QCPAxisRect) + + friend class QCustomPlot; +}; + + +/* end of 'src/layoutelements/layoutelement-axisrect.h' */ + + +/* including file 'src/layoutelements/layoutelement-legend.h', size 10397 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) + /// \endcond +public: + explicit QCPAbstractLegendItem(QCPLegend *parent); + + // getters: + QCPLegend *parentLegend() const { return mParentLegend; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QCPLegend *mParentLegend; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPAbstractLegendItem) + + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); + + // getters: + QCPAbstractPlottable *plottable() { return mPlottable; } + +protected: + // property members: + QCPAbstractPlottable *mPlottable; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; +}; + + +class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) + Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) + Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) + Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + /// \endcond +public: + /*! + Defines the selectable parts of a legend + + \see setSelectedParts, setSelectableParts + */ + enum SelectablePart { spNone = 0x000 ///< 0x000 None + ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) + ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPLegend(); + virtual ~QCPLegend(); + + // getters: + QPen borderPen() const { return mBorderPen; } + QBrush brush() const { return mBrush; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QSize iconSize() const { return mIconSize; } + int iconTextPadding() const { return mIconTextPadding; } + QPen iconBorderPen() const { return mIconBorderPen; } + SelectableParts selectableParts() const { return mSelectableParts; } + SelectableParts selectedParts() const; + QPen selectedBorderPen() const { return mSelectedBorderPen; } + QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + + // setters: + void setBorderPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setIconSize(const QSize &size); + void setIconSize(int width, int height); + void setIconTextPadding(int padding); + void setIconBorderPen(const QPen &pen); + Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); + void setSelectedBorderPen(const QPen &pen); + void setSelectedIconBorderPen(const QPen &pen); + void setSelectedBrush(const QBrush &brush); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPAbstractLegendItem *item(int index) const; + QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; + int itemCount() const; + bool hasItem(QCPAbstractLegendItem *item) const; + bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; + bool addItem(QCPAbstractLegendItem *item); + bool removeItem(int index); + bool removeItem(QCPAbstractLegendItem *item); + void clearItems(); + QList selectedItems() const; + +signals: + void selectionChanged(QCPLegend::SelectableParts parts); + void selectableChanged(QCPLegend::SelectableParts parts); + +protected: + // property members: + QPen mBorderPen, mIconBorderPen; + QBrush mBrush; + QFont mFont; + QColor mTextColor; + QSize mIconSize; + int mIconTextPadding; + SelectableParts mSelectedParts, mSelectableParts; + QPen mSelectedBorderPen, mSelectedIconBorderPen; + QBrush mSelectedBrush; + QFont mSelectedFont; + QColor mSelectedTextColor; + + // reimplemented virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getBorderPen() const; + QBrush getBrush() const; + +private: + Q_DISABLE_COPY(QCPLegend) + + friend class QCustomPlot; + friend class QCPAbstractLegendItem; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) +Q_DECLARE_METATYPE(QCPLegend::SelectablePart) + +/* end of 'src/layoutelements/layoutelement-legend.h' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.h', size 5353 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPTextElement(QCustomPlot *parentPlot); + QCPTextElement(QCustomPlot *parentPlot, const QString &text); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); + + // getters: + QString text() const { return mText; } + int textFlags() const { return mTextFlags; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setText(const QString &text); + void setTextFlags(int flags); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + void clicked(QMouseEvent *event); + void doubleClicked(QMouseEvent *event); + +protected: + // property members: + QString mText; + int mTextFlags; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + QRect mTextBoundingRect; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QFont mainFont() const; + QColor mainTextColor() const; + +private: + Q_DISABLE_COPY(QCPTextElement) +}; + + + +/* end of 'src/layoutelements/layoutelement-textelement.h' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +class QCPColorScaleAxisRectPrivate : public QCPAxisRect +{ + Q_OBJECT +public: + explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); +protected: + QCPColorScale *mParentColorScale; + QImage mGradientImage; + bool mGradientImageInvalidated; + // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale + using QCPAxisRect::calculateAutoMargin; + using QCPAxisRect::mousePressEvent; + using QCPAxisRect::mouseMoveEvent; + using QCPAxisRect::mouseReleaseEvent; + using QCPAxisRect::wheelEvent; + using QCPAxisRect::update; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + void updateGradientImage(); + Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); + Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); + friend class QCPColorScale; +}; + + +class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) + Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPColorScale(QCustomPlot *parentPlot); + virtual ~QCPColorScale(); + + // getters: + QCPAxis *axis() const { return mColorAxis.data(); } + QCPAxis::AxisType type() const { return mType; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + QCPColorGradient gradient() const { return mGradient; } + QString label() const; + int barWidth () const { return mBarWidth; } + bool rangeDrag() const; + bool rangeZoom() const; + + // setters: + void setType(QCPAxis::AxisType type); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setLabel(const QString &str); + void setBarWidth(int width); + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + + // non-property methods: + QList colorMaps() const; + void rescaleDataRange(bool onlyVisibleMaps); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPAxis::AxisType mType; + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorGradient mGradient; + int mBarWidth; + + // non-property members: + QPointer mAxisRect; + QPointer mColorAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPColorScale) + + friend class QCPColorScaleAxisRectPrivate; +}; + + +/* end of 'src/layoutelements/layoutelement-colorscale.h' */ + + +/* including file 'src/plottables/plottable-graph.h', size 9294 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPGraphData +{ +public: + QCPGraphData(); + QCPGraphData(double key, double value); + + inline double sortKey() const { return key; } + inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPGraphDataContainer + + Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPGraph holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPGraphData, QCPGraph::setData +*/ +typedef QCPDataContainer QCPGraphDataContainer; + +class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) + Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) + /// \endcond +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point + ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point + ,lsStepCenter ///< line is drawn as steps where the step is in between two data points + ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line + }; + Q_ENUMS(LineStyle) + + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPGraph(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + LineStyle lineStyle() const { return mLineStyle; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } + bool adaptiveSampling() const { return mAdaptiveSampling; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setLineStyle(LineStyle ls); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setChannelFillGraph(QCPGraph *targetGraph); + void setAdaptiveSampling(bool enabled); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + + /** + * @brief value 根据key值,查找value + */ + double value(const double &key); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + LineStyle mLineStyle; + QCPScatterStyle mScatterStyle; + int mScatterSkip; + QPointer mChannelFillGraph; + bool mAdaptiveSampling; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawFill(QCPPainter *painter, QVector *lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; + virtual void drawLinePlot(QCPPainter *painter, const QVector &lines) const; + virtual void drawImpulsePlot(QCPPainter *painter, const QVector &lines) const; + + virtual void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; + virtual void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + void getLines(QVector *lines, const QCPDataRange &dataRange) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange) const; + QVector dataToLines(const QVector &data) const; + QVector dataToStepLeftLines(const QVector &data) const; + QVector dataToStepRightLines(const QVector &data) const; + QVector dataToStepCenterLines(const QVector &data) const; + QVector dataToImpulseLines(const QVector &data) const; + QVector getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const; + QVector > getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const; + bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const; + QPointF getFillBasePoint(QPointF matchingDataPoint) const; + const QPolygonF getFillPolygon(const QVector *lineData, QCPDataRange segment) const; + const QPolygonF getChannelFillPolygon(const QVector *lineData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const; + int findIndexBelowX(const QVector *data, double x) const; + int findIndexAboveX(const QVector *data, double x) const; + int findIndexBelowY(const QVector *data, double y) const; + int findIndexAboveY(const QVector *data, double y) const; + double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPGraph::LineStyle) + +/* end of 'src/plottables/plottable-graph.h' */ + + +/* including file 'src/plottables/plottable-curve.h', size 7409 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPCurveData +{ +public: + QCPCurveData(); + QCPCurveData(double t, double key, double value); + + inline double sortKey() const { return t; } + inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } + inline static bool sortKeyIsMainKey() { return false; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double t, key, value; +}; +Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPCurveDataContainer + + Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a + sortKey() (returning \a t) is different from \a mainKey() (returning \a key). + + This template instantiation is the container in which QCPCurve holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPCurveData, QCPCurve::setData +*/ +typedef QCPDataContainer QCPCurveDataContainer; + +class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + /// \endcond +public: + /*! + Defines how the curve's line is represented visually in the plot. The line is drawn with the + current pen of the curve (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) + ,lsLine ///< Data points are connected with a straight line + }; + Q_ENUMS(LineStyle) + + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPCurve(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + LineStyle lineStyle() const { return mLineStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void setData(const QVector &keys, const QVector &values); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setLineStyle(LineStyle style); + + // non-property methods: + void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(const QVector &keys, const QVector &values); + void addData(double t, double key, double value); + void addData(double key, double value); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPScatterStyle mScatterStyle; + int mScatterSkip; + LineStyle mLineStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawCurveLine(QCPPainter *painter, const QVector &lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const; + + // non-virtual methods: + void getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const; + int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + bool mayTraverse(int prevRegion, int currentRegion) const; + bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const; + void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const; + double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPCurve::LineStyle) + +/* end of 'src/plottables/plottable-curve.h' */ + + +/* including file 'src/plottables/plottable-bars.h', size 8924 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPBarsGroup : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) + Q_PROPERTY(double spacing READ spacing WRITE setSpacing) + /// \endcond +public: + /*! + Defines the ways the spacing between bars in the group can be specified. Thus it defines what + the number passed to \ref setSpacing actually means. + + \see setSpacingType, setSpacing + */ + enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels + ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size + ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(SpacingType) + + QCPBarsGroup(QCustomPlot *parentPlot); + virtual ~QCPBarsGroup(); + + // getters: + SpacingType spacingType() const { return mSpacingType; } + double spacing() const { return mSpacing; } + + // setters: + void setSpacingType(SpacingType spacingType); + void setSpacing(double spacing); + + // non-virtual methods: + QList bars() const { return mBars; } + QCPBars* bars(int index) const; + int size() const { return mBars.size(); } + bool isEmpty() const { return mBars.isEmpty(); } + void clear(); + bool contains(QCPBars *bars) const { return mBars.contains(bars); } + void append(QCPBars *bars); + void insert(int i, QCPBars *bars); + void remove(QCPBars *bars); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + SpacingType mSpacingType; + double mSpacing; + QList mBars; + + // non-virtual methods: + void registerBars(QCPBars *bars); + void unregisterBars(QCPBars *bars); + + // virtual methods: + double keyPixelOffset(const QCPBars *bars, double keyCoord); + double getPixelSpacing(const QCPBars *bars, double keyCoord); + +private: + Q_DISABLE_COPY(QCPBarsGroup) + + friend class QCPBars; +}; +Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) + + +class QCP_LIB_DECL QCPBarsData +{ +public: + QCPBarsData(); + QCPBarsData(double key, double value); + + inline double sortKey() const { return key; } + inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here + + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPBarsDataContainer + + Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPBars holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPBarsData, QCPBars::setData +*/ +typedef QCPDataContainer QCPBarsDataContainer; + +class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) + Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) + Q_PROPERTY(double stackingGap READ stackingGap WRITE setStackingGap) + Q_PROPERTY(QCPBars* barBelow READ barBelow) + Q_PROPERTY(QCPBars* barAbove READ barAbove) + /// \endcond +public: + /*! + Defines the ways the width of the bar can be specified. Thus it defines what the number passed + to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< Bar width is in absolute pixels + ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size + ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPBars(); + + // getters: + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + QCPBarsGroup *barsGroup() const { return mBarsGroup; } + double baseValue() const { return mBaseValue; } + double stackingGap() const { return mStackingGap; } + QCPBars *barBelow() const { return mBarBelow.data(); } + QCPBars *barAbove() const { return mBarAbove.data(); } + QSharedPointer data() const { return mDataContainer; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setBarsGroup(QCPBarsGroup *barsGroup); + void setBaseValue(double baseValue); + void setStackingGap(double pixels); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + void moveBelow(QCPBars *bars); + void moveAbove(QCPBars *bars); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + WidthType mWidthType; + QCPBarsGroup *mBarsGroup; + double mBaseValue; + double mStackingGap; + QPointer mBarBelow, mBarAbove; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const; + QRectF getBarRect(double key, double value) const; + void getPixelWidth(double key, double &lower, double &upper) const; + double getStackedBaseValue(double key, bool positive) const; + static void connectBars(QCPBars* lower, QCPBars* upper); + + friend class QCustomPlot; + friend class QCPLegend; + friend class QCPBarsGroup; +}; +Q_DECLARE_METATYPE(QCPBars::WidthType) + +/* end of 'src/plottables/plottable-bars.h' */ + + +/* including file 'src/plottables/plottable-statisticalbox.h', size 7516 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPStatisticalBoxData +{ +public: + QCPStatisticalBoxData(); + QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector& outliers=QVector()); + + inline double sortKey() const { return key; } + inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return median; } + + inline QCPRange valueRange() const + { + QCPRange result(minimum, maximum); + for (QVector::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); ++it) + result.expand(*it); + return result; + } + + double key, minimum, lowerQuartile, median, upperQuartile, maximum; + QVector outliers; +}; +Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); + + +/*! \typedef QCPStatisticalBoxDataContainer + + Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPStatisticalBox holds its data. For + details about the generic container, see the documentation of the class template \ref + QCPDataContainer. + + \see QCPStatisticalBoxData, QCPStatisticalBox::setData +*/ +typedef QCPDataContainer QCPStatisticalBoxDataContainer; + +class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) + Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) + Q_PROPERTY(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased) + Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) + Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) + /// \endcond +public: + explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + QSharedPointer data() const { return mDataContainer; } + double width() const { return mWidth; } + double whiskerWidth() const { return mWhiskerWidth; } + QPen whiskerPen() const { return mWhiskerPen; } + QPen whiskerBarPen() const { return mWhiskerBarPen; } + bool whiskerAntialiased() const { return mWhiskerAntialiased; } + QPen medianPen() const { return mMedianPen; } + QCPScatterStyle outlierStyle() const { return mOutlierStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void setWidth(double width); + void setWhiskerWidth(double width); + void setWhiskerPen(const QPen &pen); + void setWhiskerBarPen(const QPen &pen); + void setWhiskerAntialiased(bool enabled); + void setMedianPen(const QPen &pen); + void setOutlierStyle(const QCPScatterStyle &style); + + // non-property methods: + void addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers=QVector()); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + double mWhiskerWidth; + QPen mWhiskerPen, mWhiskerBarPen; + bool mWhiskerAntialiased; + QPen mMedianPen; + QCPScatterStyle mOutlierStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const; + QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-statisticalbox.h' */ + + +/* including file 'src/plottables/plottable-colormap.h', size 7070 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPColorMapData +{ +public: + QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); + ~QCPColorMapData(); + QCPColorMapData(const QCPColorMapData &other); + QCPColorMapData &operator=(const QCPColorMapData &other); + + // getters: + int keySize() const { return mKeySize; } + int valueSize() const { return mValueSize; } + QCPRange keyRange() const { return mKeyRange; } + QCPRange valueRange() const { return mValueRange; } + QCPRange dataBounds() const { return mDataBounds; } + double data(double key, double value); + double cell(int keyIndex, int valueIndex); + unsigned char alpha(int keyIndex, int valueIndex); + + // setters: + void setSize(int keySize, int valueSize); + void setKeySize(int keySize); + void setValueSize(int valueSize); + void setRange(const QCPRange &keyRange, const QCPRange &valueRange); + void setKeyRange(const QCPRange &keyRange); + void setValueRange(const QCPRange &valueRange); + void setData(double key, double value, double z); + void setCell(int keyIndex, int valueIndex, double z); + void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); + + // non-property methods: + void recalculateDataBounds(); + void clear(); + void clearAlpha(); + void fill(double z); + void fillAlpha(unsigned char alpha); + bool isEmpty() const { return mIsEmpty; } + void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; + void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; + +protected: + // property members: + int mKeySize, mValueSize; + QCPRange mKeyRange, mValueRange; + bool mIsEmpty; + + // non-property members: + double *mData; + unsigned char *mAlpha; + QCPRange mDataBounds; + bool mDataModified; + + bool createAlpha(bool initializeOpaque=true); + + friend class QCPColorMap; +}; + + +class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) + Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) + Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) + /// \endcond +public: + explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPColorMap(); + + // getters: + QCPColorMapData *data() const { return mMapData; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + bool interpolate() const { return mInterpolate; } + bool tightBoundary() const { return mTightBoundary; } + QCPColorGradient gradient() const { return mGradient; } + QCPColorScale *colorScale() const { return mColorScale.data(); } + + // setters: + void setData(QCPColorMapData *data, bool copy=false); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setInterpolate(bool enabled); + void setTightBoundary(bool enabled); + void setColorScale(QCPColorScale *colorScale); + + // non-property methods: + void rescaleDataRange(bool recalculateDataBounds=false); + Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorMapData *mMapData; + QCPColorGradient mGradient; + bool mInterpolate; + bool mTightBoundary; + QPointer mColorScale; + + // non-property members: + QImage mMapImage, mUndersampledMapImage; + QPixmap mLegendIcon; + bool mMapImageInvalidated; + + // introduced virtual methods: + virtual void updateMapImage(); + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-colormap.h' */ + + +/* including file 'src/plottables/plottable-financial.h', size 8622 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPFinancialData +{ +public: + QCPFinancialData(); + QCPFinancialData(double key, double open, double high, double low, double close); + + inline double sortKey() const { return key; } + inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return open; } + + inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them + + double key, open, high, low, close; +}; +Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPFinancialDataContainer + + Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPFinancial holds its data. For details + about the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPFinancialData, QCPFinancial::setData +*/ +typedef QCPDataContainer QCPFinancialDataContainer; + +class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) + Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) + Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) + Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) + Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) + /// \endcond +public: + /*! + Defines the ways the width of the financial bar can be specified. Thus it defines what the + number passed to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< width is in absolute pixels + ,wtAxisRectRatio ///< width is given by a fraction of the axis rect size + ,wtPlotCoords ///< width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + /*! + Defines the possible representations of OHLC data in the plot. + + \see setChartStyle + */ + enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation + ,csCandlestick ///< Candlestick representation + }; + Q_ENUMS(ChartStyle) + + explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPFinancial(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + ChartStyle chartStyle() const { return mChartStyle; } + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + bool twoColored() const { return mTwoColored; } + QBrush brushPositive() const { return mBrushPositive; } + QBrush brushNegative() const { return mBrushNegative; } + QPen penPositive() const { return mPenPositive; } + QPen penNegative() const { return mPenNegative; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void setChartStyle(ChartStyle style); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setTwoColored(bool twoColored); + void setBrushPositive(const QBrush &brush); + void setBrushNegative(const QBrush &brush); + void setPenPositive(const QPen &pen); + void setPenNegative(const QPen &pen); + + // non-property methods: + void addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void addData(double key, double open, double high, double low, double close); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // static methods: + static QCPFinancialDataContainer timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); + +protected: + // property members: + ChartStyle mChartStyle; + double mWidth; + WidthType mWidthType; + bool mTwoColored; + QBrush mBrushPositive, mBrushNegative; + QPen mPenPositive, mPenNegative; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + double getPixelWidth(double key, double keyPixel) const; + double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const; + QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) + +/* end of 'src/plottables/plottable-financial.h' */ + + +/* including file 'src/plottables/plottable-errorbar.h', size 7727 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPErrorBarsData +{ +public: + QCPErrorBarsData(); + explicit QCPErrorBarsData(double error); + QCPErrorBarsData(double errorMinus, double errorPlus); + + double errorMinus, errorPlus; +}; +Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPErrorBarsDataContainer + + Container for storing \ref QCPErrorBarsData points. It is a typedef for QVector<\ref + QCPErrorBarsData>. + + This is the container in which \ref QCPErrorBars holds its data. Unlike most other data + containers for plottables, it is not based on \ref QCPDataContainer. This is because the error + bars plottable is special in that it doesn't store its own key and value coordinate per error + bar. It adopts the key and value from the plottable to which the error bars shall be applied + (\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a + sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices + of the other plottable's data. + + \see QCPErrorBarsData, QCPErrorBars::setData +*/ +typedef QVector QCPErrorBarsDataContainer; + +class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QSharedPointer data READ data WRITE setData) + Q_PROPERTY(QCPAbstractPlottable* dataPlottable READ dataPlottable WRITE setDataPlottable) + Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap) + /// \endcond +public: + + /*! + Defines in which orientation the error bars shall appear. If your data needs both error + dimensions, create two \ref QCPErrorBars with different \ref ErrorType. + + \see setErrorType + */ + enum ErrorType { etKeyError ///< The errors are for the key dimension (bars appear parallel to the key axis) + ,etValueError ///< The errors are for the value dimension (bars appear parallel to the value axis) + }; + Q_ENUMS(ErrorType) + + explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPErrorBars(); + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); } + ErrorType errorType() const { return mErrorType; } + double whiskerWidth() const { return mWhiskerWidth; } + double symbolGap() const { return mSymbolGap; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &error); + void setData(const QVector &errorMinus, const QVector &errorPlus); + void setDataPlottable(QCPAbstractPlottable* plottable); + void setErrorType(ErrorType type); + void setWhiskerWidth(double pixels); + void setSymbolGap(double pixels); + + // non-property methods: + void addData(const QVector &error); + void addData(const QVector &errorMinus, const QVector &errorPlus); + void addData(double error); + void addData(double errorMinus, double errorPlus); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const Q_DECL_OVERRIDE; + virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; + virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; + virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; + virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer mDataContainer; + QPointer mDataPlottable; + ErrorType mErrorType; + double mWhiskerWidth; + double mSymbolGap; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const; + void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const; + // helpers: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + bool errorBarVisible(int index) const; + bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-errorbar.h' */ + + +/* including file 'src/items/item-straightline.h', size 3117 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemStraightLine(QCustomPlot *parentPlot); + virtual ~QCPItemStraightLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const point1; + QCPItemPosition * const point2; + +protected: + // property members: + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-straightline.h' */ + + +/* including file 'src/items/item-line.h', size 3407 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemLine(QCustomPlot *parentPlot); + virtual ~QCPItemLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-line.h' */ + + +/* including file 'src/items/item-curve.h', size 3379 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemCurve(QCustomPlot *parentPlot); + virtual ~QCPItemCurve(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const startDir; + QCPItemPosition * const endDir; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; + +/* end of 'src/items/item-curve.h' */ + + +/* including file 'src/items/item-rect.h', size 3688 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemRect(QCustomPlot *parentPlot); + virtual ~QCPItemRect(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-rect.h' */ + + +/* including file 'src/items/item-text.h', size 5554 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemText : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) + Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) + Q_PROPERTY(double rotation READ rotation WRITE setRotation) + Q_PROPERTY(QMargins padding READ padding WRITE setPadding) + /// \endcond +public: + explicit QCPItemText(QCustomPlot *parentPlot); + virtual ~QCPItemText(); + + // getters: + QColor color() const { return mColor; } + QColor selectedColor() const { return mSelectedColor; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont font() const { return mFont; } + QFont selectedFont() const { return mSelectedFont; } + QString text() const { return mText; } + Qt::Alignment positionAlignment() const { return mPositionAlignment; } + Qt::Alignment textAlignment() const { return mTextAlignment; } + double rotation() const { return mRotation; } + QMargins padding() const { return mPadding; } + + // setters; + void setColor(const QColor &color); + void setSelectedColor(const QColor &color); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setFont(const QFont &font); + void setSelectedFont(const QFont &font); + void setText(const QString &text); + void setPositionAlignment(Qt::Alignment alignment); + void setTextAlignment(Qt::Alignment alignment); + void setRotation(double degrees); + void setPadding(const QMargins &padding); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const position; + QCPItemAnchor * const topLeft; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRight; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QColor mColor, mSelectedColor; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QFont mFont, mSelectedFont; + QString mText; + Qt::Alignment mPositionAlignment; + Qt::Alignment mTextAlignment; + double mRotation; + QMargins mPadding; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; + QFont mainFont() const; + QColor mainColor() const; + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-text.h' */ + + +/* including file 'src/items/item-ellipse.h', size 3868 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemEllipse(QCustomPlot *parentPlot); + virtual ~QCPItemEllipse(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const topLeftRim; + QCPItemAnchor * const top; + QCPItemAnchor * const topRightRim; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRightRim; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeftRim; + QCPItemAnchor * const left; + QCPItemAnchor * const center; + +protected: + enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-ellipse.h' */ + + +/* including file 'src/items/item-pixmap.h', size 4373 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) + Q_PROPERTY(bool scaled READ scaled WRITE setScaled) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) + Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemPixmap(QCustomPlot *parentPlot); + virtual ~QCPItemPixmap(); + + // getters: + QPixmap pixmap() const { return mPixmap; } + bool scaled() const { return mScaled; } + Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } + Qt::TransformationMode transformationMode() const { return mTransformationMode; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPixmap(const QPixmap &pixmap); + void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPixmap mPixmap; + QPixmap mScaledPixmap; + bool mScaled; + bool mScaledPixmapInvalidated; + Qt::AspectRatioMode mAspectRatioMode; + Qt::TransformationMode mTransformationMode; + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); + QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-pixmap.h' */ + + +/* including file 'src/items/item-tracer.h', size 4762 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(double size READ size WRITE setSize) + Q_PROPERTY(TracerStyle style READ style WRITE setStyle) + Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) + Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) + Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) + /// \endcond +public: + /*! + The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. + + \see setStyle + */ + enum TracerStyle { tsNone ///< The tracer is not visible + ,tsPlus ///< A plus shaped crosshair with limited size + ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect + ,tsCircle ///< A circle + ,tsSquare ///< A square + }; + Q_ENUMS(TracerStyle) + + explicit QCPItemTracer(QCustomPlot *parentPlot); + QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush); + virtual ~QCPItemTracer(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + double size() const { return mSize; } + TracerStyle style() const { return mStyle; } + QCPGraph *graph() const { return mGraph; } + double graphKey() const { return mGraphKey; } + bool interpolating() const { return mInterpolating; } + int type() const { return mType; } + qint64 timeStamp() const { return mTimeStamp; } + QMap hidePoint() const { return m_hidePoint; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setSize(double size); + void setStyle(TracerStyle style); + void setGraph(QCPGraph *graph); + void setGraphKey(double key); + void setHidePoint(const QMap &hidePoint); + void addHidePoint(const qint64 &time, const QString &tag); + void setInterpolating(bool enabled); + + void setType(const int &type); + void setTimeStamp(const qint64 &timeStamp); + void setInfo(const QStringList infos); + + void showTips(); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updatePosition(); + + QCPItemPosition * const position; + +signals: + void itemTracerHoverd(const QString &name, const qint64 &time, const QMap& timeTag); + +protected: + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + double mSize; + TracerStyle mStyle; + QCPGraph *mGraph; + QMap m_hidePoint; + double mGraphKey; + bool mInterpolating; + int mType; + qint64 mTimeStamp; + QStringList m_infos; + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + + + virtual void mousePressEvent (QMouseEvent *event, const QVariant &details); + + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; +Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle) + +/* end of 'src/items/item-tracer.h' */ + + +/* including file 'src/items/item-bracket.h', size 3969 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(double length READ length WRITE setLength) + Q_PROPERTY(BracketStyle style READ style WRITE setStyle) + /// \endcond +public: + /*! + Defines the various visual shapes of the bracket item. The appearance can be further modified + by \ref setLength and \ref setPen. + + \see setStyle + */ + enum BracketStyle { bsSquare ///< A brace with angled edges + ,bsRound ///< A brace with round edges + ,bsCurly ///< A curly brace + ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression + }; + Q_ENUMS(BracketStyle) + + explicit QCPItemBracket(QCustomPlot *parentPlot); + virtual ~QCPItemBracket(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + double length() const { return mLength; } + BracketStyle style() const { return mStyle; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setLength(double length); + void setStyle(BracketStyle style); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const left; + QCPItemPosition * const right; + QCPItemAnchor * const center; + +protected: + // property members: + enum AnchorIndex {aiCenter}; + QPen mPen, mSelectedPen; + double mLength; + BracketStyle mStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; +Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle) + +/* end of 'src/items/item-bracket.h' */ + + +#endif // QCUSTOMPLOT_H + diff --git a/product/src/gui/plugin/ISCSTrendCurves/resource/color.cfg b/product/src/gui/plugin/ISCSTrendCurves/resource/color.cfg index e6e13a32..f5f10d54 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/resource/color.cfg +++ b/product/src/gui/plugin/ISCSTrendCurves/resource/color.cfg @@ -1,16 +1,16 @@ -#EF3829 -#EFD752 -#6BA2D6 -#DEAECE -#EF968C -#18A28C -#8C3C39 -#63498C -#6B4531 -#EFDFDE -#BD6DA5 -#C6D729 -#103852 -#B5B2B5 -#CEAA9C +#EF3829 +#EFD752 +#6BA2D6 +#DEAECE +#EF968C +#18A28C +#8C3C39 +#63498C +#6B4531 +#EFDFDE +#BD6DA5 +#C6D729 +#103852 +#B5B2B5 +#CEAA9C #F7EFEF \ No newline at end of file diff --git a/product/src/gui/plugin/ISCSTrendCurves/style.qrc b/product/src/gui/plugin/ISCSTrendCurves/style.qrc index 71723dc6..85edbbb1 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/style.qrc +++ b/product/src/gui/plugin/ISCSTrendCurves/style.qrc @@ -1,5 +1,5 @@ - - - resource/color.cfg - - + + + resource/color.cfg + + diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CCalendarWidget.cpp b/product/src/gui/plugin/ISCSTrendCurves/widgets/CCalendarWidget.cpp index ec4a8700..84f59f65 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CCalendarWidget.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CCalendarWidget.cpp @@ -1,41 +1,41 @@ -#include "CCalendarWidget.h" -#include - -CCalendarWidget::CCalendarWidget(QWidget *parent) - : QCalendarWidget(parent) -{ - setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); - setAttribute(Qt::WA_DeleteOnClose); - setHorizontalHeaderFormat(NoHorizontalHeader); - setVerticalHeaderFormat(NoVerticalHeader); - - setMinimumDate(QDate(1970, 0, 0)); - setMaximumDate(QDate(2037, 12, 31)); - - installEventFilter(this); - -} - -CCalendarWidget::~CCalendarWidget() -{ -} - -QSize CCalendarWidget::sizeHint() const -{ - return QSize(260, 180); -} - - -bool CCalendarWidget::eventFilter(QObject *object, QEvent *event) -{ - if (object == this) - { - if (QEvent::WindowDeactivate == event->type()) - { - this->close(); - event->accept(); - return true; - } - } - return QWidget::eventFilter(object, event); -} +#include "CCalendarWidget.h" +#include + +CCalendarWidget::CCalendarWidget(QWidget *parent) + : QCalendarWidget(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_DeleteOnClose); + setHorizontalHeaderFormat(NoHorizontalHeader); + setVerticalHeaderFormat(NoVerticalHeader); + + setMinimumDate(QDate(1970, 0, 0)); + setMaximumDate(QDate(2037, 12, 31)); + + installEventFilter(this); + +} + +CCalendarWidget::~CCalendarWidget() +{ +} + +QSize CCalendarWidget::sizeHint() const +{ + return QSize(260, 180); +} + + +bool CCalendarWidget::eventFilter(QObject *object, QEvent *event) +{ + if (object == this) + { + if (QEvent::WindowDeactivate == event->type()) + { + this->close(); + event->accept(); + return true; + } + } + return QWidget::eventFilter(object, event); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CCalendarWidget.h b/product/src/gui/plugin/ISCSTrendCurves/widgets/CCalendarWidget.h index bc3cfda1..aa30d8a2 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CCalendarWidget.h +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CCalendarWidget.h @@ -1,19 +1,19 @@ -#ifndef CCALENDARWIDGET_H -#define CCALENDARWIDGET_H - -#include - -class CCalendarWidget : public QCalendarWidget -{ - Q_OBJECT -public: - CCalendarWidget(QWidget *parent = Q_NULLPTR); - ~CCalendarWidget(); - -protected: - QSize sizeHint() const; - - bool eventFilter(QObject *object, QEvent *event); -}; - -#endif // CCALENDARWIDGET_H +#ifndef CCALENDARWIDGET_H +#define CCALENDARWIDGET_H + +#include + +class CCalendarWidget : public QCalendarWidget +{ + Q_OBJECT +public: + CCalendarWidget(QWidget *parent = Q_NULLPTR); + ~CCalendarWidget(); + +protected: + QSize sizeHint() const; + + bool eventFilter(QObject *object, QEvent *event); +}; + +#endif // CCALENDARWIDGET_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CEditCollectWidget.cpp b/product/src/gui/plugin/ISCSTrendCurves/widgets/CEditCollectWidget.cpp index be7ee160..fb0b9c4e 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CEditCollectWidget.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CEditCollectWidget.cpp @@ -1,66 +1,66 @@ -#include "CEditCollectWidget.h" -#include -#include -#include -#include -#include -#include - -CEditCollectWidget::CEditCollectWidget(QWidget *parent) : - QDialog(parent) -{ - installEventFilter(this); -// setAttribute(Qt::WA_DeleteOnClose); - setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); - - QHBoxLayout * pTopLayout = new QHBoxLayout(); - QLabel * label = new QLabel(tr("趋势名称:"), this); - m_pNameEdit = new QLineEdit(this); - m_pNameEdit->setMinimumHeight(25); - pTopLayout->addWidget(label, 0); - pTopLayout->addWidget(m_pNameEdit, 10); - pTopLayout->setMargin(0); - QHBoxLayout * pBottomLayout = new QHBoxLayout(); - QPushButton * ok = new QPushButton(tr("确定"), this); - QPushButton * cancle = new QPushButton(tr("取消"), this); - pBottomLayout->addStretch(10); - pBottomLayout->addWidget(ok, 1); - pBottomLayout->addWidget(cancle, 1); - pBottomLayout->setMargin(0); - QVBoxLayout * layout = new QVBoxLayout(this); - layout->addLayout(pTopLayout, 1); - layout->addLayout(pBottomLayout, 1); - setLayout(layout); - layout->setMargin(0); - setContentsMargins(5,0,5,0); - setMaximumHeight(75); - - connect(ok, &QPushButton::clicked, this, [=]() { - emit acceptedInput(); - }); - connect(cancle, &QPushButton::clicked, this, [=]() { close(); }); -} - -CEditCollectWidget::~CEditCollectWidget() -{ - -} - -QString CEditCollectWidget::text() -{ - return m_pNameEdit->text(); -} - -bool CEditCollectWidget::eventFilter(QObject *object, QEvent *event) -{ - if (object == this) - { - if (QEvent::WindowDeactivate == event->type()) - { - this->close(); - event->accept(); - return true; - } - } - return QDialog::eventFilter(object, event); -} +#include "CEditCollectWidget.h" +#include +#include +#include +#include +#include +#include + +CEditCollectWidget::CEditCollectWidget(QWidget *parent) : + QDialog(parent) +{ + installEventFilter(this); +// setAttribute(Qt::WA_DeleteOnClose); + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + + QHBoxLayout * pTopLayout = new QHBoxLayout(); + QLabel * label = new QLabel(tr("趋势名称:"), this); + m_pNameEdit = new QLineEdit(this); + m_pNameEdit->setMinimumHeight(25); + pTopLayout->addWidget(label, 0); + pTopLayout->addWidget(m_pNameEdit, 10); + pTopLayout->setMargin(0); + QHBoxLayout * pBottomLayout = new QHBoxLayout(); + QPushButton * ok = new QPushButton(tr("确定"), this); + QPushButton * cancle = new QPushButton(tr("取消"), this); + pBottomLayout->addStretch(10); + pBottomLayout->addWidget(ok, 1); + pBottomLayout->addWidget(cancle, 1); + pBottomLayout->setMargin(0); + QVBoxLayout * layout = new QVBoxLayout(this); + layout->addLayout(pTopLayout, 1); + layout->addLayout(pBottomLayout, 1); + setLayout(layout); + layout->setMargin(0); + setContentsMargins(5,0,5,0); + setMaximumHeight(75); + + connect(ok, &QPushButton::clicked, this, [=]() { + emit acceptedInput(); + }); + connect(cancle, &QPushButton::clicked, this, [=]() { close(); }); +} + +CEditCollectWidget::~CEditCollectWidget() +{ + +} + +QString CEditCollectWidget::text() +{ + return m_pNameEdit->text(); +} + +bool CEditCollectWidget::eventFilter(QObject *object, QEvent *event) +{ + if (object == this) + { + if (QEvent::WindowDeactivate == event->type()) + { + this->close(); + event->accept(); + return true; + } + } + return QDialog::eventFilter(object, event); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CEditCollectWidget.h b/product/src/gui/plugin/ISCSTrendCurves/widgets/CEditCollectWidget.h index 09c8c1ae..97d8266d 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CEditCollectWidget.h +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CEditCollectWidget.h @@ -1,26 +1,26 @@ -#ifndef CEDITCOLLECTWIDGET_H -#define CEDITCOLLECTWIDGET_H - -#include - -class QLineEdit; -class CEditCollectWidget : public QDialog -{ - Q_OBJECT -public: - explicit CEditCollectWidget(QWidget *parent = 0); - ~CEditCollectWidget(); - - QString text(); - -signals: - void acceptedInput(); - -protected: - bool eventFilter(QObject *object, QEvent *event); - -private: - QLineEdit * m_pNameEdit; -}; - -#endif // CEDITCOLLECTWIDGET_H +#ifndef CEDITCOLLECTWIDGET_H +#define CEDITCOLLECTWIDGET_H + +#include + +class QLineEdit; +class CEditCollectWidget : public QDialog +{ + Q_OBJECT +public: + explicit CEditCollectWidget(QWidget *parent = 0); + ~CEditCollectWidget(); + + QString text(); + +signals: + void acceptedInput(); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private: + QLineEdit * m_pNameEdit; +}; + +#endif // CEDITCOLLECTWIDGET_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CTabButton.cpp b/product/src/gui/plugin/ISCSTrendCurves/widgets/CTabButton.cpp index 07ad6330..abd2c898 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CTabButton.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CTabButton.cpp @@ -1,428 +1,428 @@ -#include "CTabButton.h" -#include -#include "CCalendarWidget.h" - -CTabButton::CTabButton(QWidget *parent) - : QPushButton(parent), - m_isShowCalendarEnable(false) -{ - paddingLeft = 5; - paddingRight = 5; - paddingTop = 5; - paddingBottom = 5; - textAlign = TextAlign_Center; - - showLine = true; - lineSpace = 0; - lineWidth = 6; - linePosition = LinePosition_Bottom; - lineColor = QColor(24, 144, 255); - - normalBgColor = QColor(0, 38, 75); - hoverBgColor = QColor(2, 49, 93); - checkBgColor = QColor(2, 49, 93); - normalTextColor = QColor(182, 194, 205); - hoverTextColor = QColor(255, 255, 255); - checkTextColor = QColor(20, 130, 231); - - normalBgBrush = Qt::NoBrush; - hoverBgBrush = Qt::NoBrush; - checkBgBrush = Qt::NoBrush; - - font = QFont("Microsoft YaHei"); - font.setPointSize(12); - hover = false; - setCheckable(true); -} - -void CTabButton::setShowCalendarEnable(const bool &enable) -{ - m_isShowCalendarEnable = enable; -} - - -int CTabButton::getPaddingLeft() const -{ - return this->paddingLeft; -} - -int CTabButton::getPaddingRight() const -{ - return this->paddingRight; -} - -int CTabButton::getPaddingTop() const -{ - return this->paddingTop; -} - -int CTabButton::getPaddingBottom() const -{ - return this->paddingBottom; -} - -CTabButton::TextAlign CTabButton::getTextAlign() const -{ - return this->textAlign; -} - -QColor CTabButton::getNormalBgColor() const -{ - return this->normalBgColor; -} - -QColor CTabButton::getHoverBgColor() const -{ - return this->hoverBgColor; -} - -QColor CTabButton::getCheckBgColor() const -{ - return this->checkBgColor; -} - -QColor CTabButton::getNormalTextColor() const -{ - return this->normalTextColor; -} - -QColor CTabButton::getHoverTextColor() const -{ - return this->hoverTextColor; -} - -QColor CTabButton::getCheckTextColor() const -{ - return this->checkTextColor; -} - -QFont CTabButton::getFont() const -{ - return this->font; -} - - -void CTabButton::setPaddingLeft(int paddingLeft) -{ - if (this->paddingLeft != paddingLeft) { - this->paddingLeft = paddingLeft; - update(); - } -} - -void CTabButton::setPaddingRight(int paddingRight) -{ - if (this->paddingRight != paddingRight) { - this->paddingRight = paddingRight; - update(); - } -} - -void CTabButton::setPaddingTop(int paddingTop) -{ - if (this->paddingTop != paddingTop) { - this->paddingTop = paddingTop; - update(); - } -} - -void CTabButton::setPaddingBottom(int paddingBottom) -{ - if (this->paddingBottom != paddingBottom) { - this->paddingBottom = paddingBottom; - update(); - } -} - -void CTabButton::setPadding(int padding) -{ - setPadding(padding, padding, padding, padding); -} - -void CTabButton::setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) -{ - this->paddingLeft = paddingLeft; - this->paddingRight = paddingRight; - this->paddingTop = paddingTop; - this->paddingBottom = paddingBottom; - update(); -} - -void CTabButton::setTextAlign(const CTabButton::TextAlign &textAlign) -{ - if (this->textAlign != textAlign) { - this->textAlign = textAlign; - update(); - } -} - -void CTabButton::setShowLine(bool showLine) -{ - if (this->showLine != showLine) { - this->showLine = showLine; - update(); - } -} - -void CTabButton::setLineSpace(int lineSpace) -{ - if (this->lineSpace != lineSpace) { - this->lineSpace = lineSpace; - update(); - } -} - -void CTabButton::setLineWidth(int lineWidth) -{ - if (this->lineWidth != lineWidth) { - this->lineWidth = lineWidth; - update(); - } -} - -void CTabButton::setLinePosition(const CTabButton::LinePosition &linePosition) -{ - if (this->linePosition != linePosition) { - this->linePosition = linePosition; - update(); - } -} - -void CTabButton::setLineColor(const QColor &lineColor) -{ - if (this->lineColor != lineColor) { - this->lineColor = lineColor; - update(); - } -} - -void CTabButton::setNormalBgColor(const QColor &normalBgColor) -{ - if (this->normalBgColor != normalBgColor) { - this->normalBgColor = normalBgColor; - update(); - } -} - -void CTabButton::setHoverBgColor(const QColor &hoverBgColor) -{ - if (this->hoverBgColor != hoverBgColor) { - this->hoverBgColor = hoverBgColor; - update(); - } -} - -void CTabButton::setCheckBgColor(const QColor &checkBgColor) -{ - if (this->checkBgColor != checkBgColor) { - this->checkBgColor = checkBgColor; - update(); - } -} - -void CTabButton::setNormalTextColor(const QColor &normalTextColor) -{ - if (this->normalTextColor != normalTextColor) { - this->normalTextColor = normalTextColor; - update(); - } -} - -void CTabButton::setHoverTextColor(const QColor &hoverTextColor) -{ - if (this->hoverTextColor != hoverTextColor) { - this->hoverTextColor = hoverTextColor; - update(); - } -} - -void CTabButton::setCheckTextColor(const QColor &checkTextColor) -{ - if (this->checkTextColor != checkTextColor) { - this->checkTextColor = checkTextColor; - update(); - } -} - -void CTabButton::setNormalBgBrush(const QBrush &normalBgBrush) -{ - if (this->normalBgBrush != normalBgBrush) { - this->normalBgBrush = normalBgBrush; - update(); - } -} - -void CTabButton::setHoverBgBrush(const QBrush &hoverBgBrush) -{ - if (this->hoverBgBrush != hoverBgBrush) { - this->hoverBgBrush = hoverBgBrush; - update(); - } -} - -void CTabButton::setCheckBgBrush(const QBrush &checkBgBrush) -{ - if (this->checkBgBrush != checkBgBrush) { - this->checkBgBrush = checkBgBrush; - update(); - } -} - -void CTabButton::setFont(const QFont &font) -{ - this->font = font; -} - - -void CTabButton::enterEvent(QEvent *) -{ - hover = true; - update(); -} - -void CTabButton::leaveEvent(QEvent *) -{ - hover = false; - update(); -} - -void CTabButton::paintEvent(QPaintEvent *e) -{ - QPushButton::paintEvent(e); -// //绘制准备工作,启用反锯齿 -// QPainter painter(this); -// painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); - -// //绘制背景 -// drawBg(&painter); -// //绘制文字 -// drawText(&painter); -// //绘制边框线条 -// drawLine(&painter); -} - -void CTabButton::drawBg(QPainter *painter) -{ - painter->save(); - painter->setPen(Qt::NoPen); - - int width = this->width(); - int height = this->height(); - - QRect bgRect; - if (linePosition == LinePosition_Left) { - bgRect = QRect(lineSpace, 0, width - lineSpace, height); - } else if (linePosition == LinePosition_Right) { - bgRect = QRect(0, 0, width - lineSpace, height); - } else if (linePosition == LinePosition_Top) { - bgRect = QRect(0, lineSpace, width, height - lineSpace); - } else if (linePosition == LinePosition_Bottom) { - bgRect = QRect(0, 0, width, height - lineSpace); - } - - //如果画刷存在则取画刷 - QBrush bgBrush; - if (isChecked()) { - bgBrush = checkBgBrush; - } else if (hover) { - bgBrush = hoverBgBrush; - } else { - bgBrush = normalBgBrush; - } - - if (bgBrush != Qt::NoBrush) { - painter->setBrush(bgBrush); - } else { - //根据当前状态选择对应颜色 - QColor bgColor; - if (isChecked()) { - bgColor = checkBgColor; - } else if (hover) { - bgColor = hoverBgColor; - } else { - bgColor = normalBgColor; - } - - painter->setBrush(bgColor); - } - - painter->drawRect(bgRect); - - painter->restore(); -} - -void CTabButton::drawText(QPainter *painter) -{ - painter->save(); - painter->setBrush(Qt::NoBrush); - - //根据当前状态选择对应颜色 - QColor textColor; - if (isChecked()) { - textColor = checkTextColor; - } else if (hover) { - textColor = hoverTextColor; - } else { - textColor = normalTextColor; - } - - QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom); - painter->setPen(textColor); - painter->setFont(font); - painter->drawText(textRect, textAlign | Qt::AlignVCenter, text()); - - painter->restore(); -} - - -void CTabButton::drawLine(QPainter *painter) -{ - if (!showLine) { - return; - } - - if (!isChecked()) { - return; - } - - painter->save(); - - QPen pen; - pen.setWidth(lineWidth); - pen.setColor(lineColor); - painter->setPen(pen); - - //根据线条位置设置线条坐标 - QPoint pointStart, pointEnd; - if (linePosition == LinePosition_Left) { - pointStart = QPoint(0, 0); - pointEnd = QPoint(0, height()); - } else if (linePosition == LinePosition_Right) { - pointStart = QPoint(width(), 0); - pointEnd = QPoint(width(), height()); - } else if (linePosition == LinePosition_Top) { - pointStart = QPoint(0, 0); - pointEnd = QPoint(width(), 0); - } else if (linePosition == LinePosition_Bottom) { - pointStart = QPoint(0, height()); - pointEnd = QPoint(width(), height()); - } - - painter->drawLine(pointStart, pointEnd); - - painter->restore(); -} - -void CTabButton::contextMenuEvent(QContextMenuEvent *event) -{ - Q_UNUSED(event) - if(!m_isShowCalendarEnable) - { - return; - } - CCalendarWidget * calendar = new CCalendarWidget(this); - calendar->setSelectedDate(QDate::currentDate()); - connect(calendar, &CCalendarWidget::clicked, this, &CTabButton::dataChanged); - calendar->show(); - calendar->move(parentWidget()->mapToGlobal(QPoint(width(), height() + 2))); -} +#include "CTabButton.h" +#include +#include "CCalendarWidget.h" + +CTabButton::CTabButton(QWidget *parent) + : QPushButton(parent), + m_isShowCalendarEnable(false) +{ + paddingLeft = 5; + paddingRight = 5; + paddingTop = 5; + paddingBottom = 5; + textAlign = TextAlign_Center; + + showLine = true; + lineSpace = 0; + lineWidth = 6; + linePosition = LinePosition_Bottom; + lineColor = QColor(24, 144, 255); + + normalBgColor = QColor(0, 38, 75); + hoverBgColor = QColor(2, 49, 93); + checkBgColor = QColor(2, 49, 93); + normalTextColor = QColor(182, 194, 205); + hoverTextColor = QColor(255, 255, 255); + checkTextColor = QColor(20, 130, 231); + + normalBgBrush = Qt::NoBrush; + hoverBgBrush = Qt::NoBrush; + checkBgBrush = Qt::NoBrush; + + font = QFont("Microsoft YaHei"); + font.setPointSize(12); + hover = false; + setCheckable(true); +} + +void CTabButton::setShowCalendarEnable(const bool &enable) +{ + m_isShowCalendarEnable = enable; +} + + +int CTabButton::getPaddingLeft() const +{ + return this->paddingLeft; +} + +int CTabButton::getPaddingRight() const +{ + return this->paddingRight; +} + +int CTabButton::getPaddingTop() const +{ + return this->paddingTop; +} + +int CTabButton::getPaddingBottom() const +{ + return this->paddingBottom; +} + +CTabButton::TextAlign CTabButton::getTextAlign() const +{ + return this->textAlign; +} + +QColor CTabButton::getNormalBgColor() const +{ + return this->normalBgColor; +} + +QColor CTabButton::getHoverBgColor() const +{ + return this->hoverBgColor; +} + +QColor CTabButton::getCheckBgColor() const +{ + return this->checkBgColor; +} + +QColor CTabButton::getNormalTextColor() const +{ + return this->normalTextColor; +} + +QColor CTabButton::getHoverTextColor() const +{ + return this->hoverTextColor; +} + +QColor CTabButton::getCheckTextColor() const +{ + return this->checkTextColor; +} + +QFont CTabButton::getFont() const +{ + return this->font; +} + + +void CTabButton::setPaddingLeft(int paddingLeft) +{ + if (this->paddingLeft != paddingLeft) { + this->paddingLeft = paddingLeft; + update(); + } +} + +void CTabButton::setPaddingRight(int paddingRight) +{ + if (this->paddingRight != paddingRight) { + this->paddingRight = paddingRight; + update(); + } +} + +void CTabButton::setPaddingTop(int paddingTop) +{ + if (this->paddingTop != paddingTop) { + this->paddingTop = paddingTop; + update(); + } +} + +void CTabButton::setPaddingBottom(int paddingBottom) +{ + if (this->paddingBottom != paddingBottom) { + this->paddingBottom = paddingBottom; + update(); + } +} + +void CTabButton::setPadding(int padding) +{ + setPadding(padding, padding, padding, padding); +} + +void CTabButton::setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) +{ + this->paddingLeft = paddingLeft; + this->paddingRight = paddingRight; + this->paddingTop = paddingTop; + this->paddingBottom = paddingBottom; + update(); +} + +void CTabButton::setTextAlign(const CTabButton::TextAlign &textAlign) +{ + if (this->textAlign != textAlign) { + this->textAlign = textAlign; + update(); + } +} + +void CTabButton::setShowLine(bool showLine) +{ + if (this->showLine != showLine) { + this->showLine = showLine; + update(); + } +} + +void CTabButton::setLineSpace(int lineSpace) +{ + if (this->lineSpace != lineSpace) { + this->lineSpace = lineSpace; + update(); + } +} + +void CTabButton::setLineWidth(int lineWidth) +{ + if (this->lineWidth != lineWidth) { + this->lineWidth = lineWidth; + update(); + } +} + +void CTabButton::setLinePosition(const CTabButton::LinePosition &linePosition) +{ + if (this->linePosition != linePosition) { + this->linePosition = linePosition; + update(); + } +} + +void CTabButton::setLineColor(const QColor &lineColor) +{ + if (this->lineColor != lineColor) { + this->lineColor = lineColor; + update(); + } +} + +void CTabButton::setNormalBgColor(const QColor &normalBgColor) +{ + if (this->normalBgColor != normalBgColor) { + this->normalBgColor = normalBgColor; + update(); + } +} + +void CTabButton::setHoverBgColor(const QColor &hoverBgColor) +{ + if (this->hoverBgColor != hoverBgColor) { + this->hoverBgColor = hoverBgColor; + update(); + } +} + +void CTabButton::setCheckBgColor(const QColor &checkBgColor) +{ + if (this->checkBgColor != checkBgColor) { + this->checkBgColor = checkBgColor; + update(); + } +} + +void CTabButton::setNormalTextColor(const QColor &normalTextColor) +{ + if (this->normalTextColor != normalTextColor) { + this->normalTextColor = normalTextColor; + update(); + } +} + +void CTabButton::setHoverTextColor(const QColor &hoverTextColor) +{ + if (this->hoverTextColor != hoverTextColor) { + this->hoverTextColor = hoverTextColor; + update(); + } +} + +void CTabButton::setCheckTextColor(const QColor &checkTextColor) +{ + if (this->checkTextColor != checkTextColor) { + this->checkTextColor = checkTextColor; + update(); + } +} + +void CTabButton::setNormalBgBrush(const QBrush &normalBgBrush) +{ + if (this->normalBgBrush != normalBgBrush) { + this->normalBgBrush = normalBgBrush; + update(); + } +} + +void CTabButton::setHoverBgBrush(const QBrush &hoverBgBrush) +{ + if (this->hoverBgBrush != hoverBgBrush) { + this->hoverBgBrush = hoverBgBrush; + update(); + } +} + +void CTabButton::setCheckBgBrush(const QBrush &checkBgBrush) +{ + if (this->checkBgBrush != checkBgBrush) { + this->checkBgBrush = checkBgBrush; + update(); + } +} + +void CTabButton::setFont(const QFont &font) +{ + this->font = font; +} + + +void CTabButton::enterEvent(QEvent *) +{ + hover = true; + update(); +} + +void CTabButton::leaveEvent(QEvent *) +{ + hover = false; + update(); +} + +void CTabButton::paintEvent(QPaintEvent *e) +{ + QPushButton::paintEvent(e); +// //绘制准备工作,启用反锯齿 +// QPainter painter(this); +// painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + +// //绘制背景 +// drawBg(&painter); +// //绘制文字 +// drawText(&painter); +// //绘制边框线条 +// drawLine(&painter); +} + +void CTabButton::drawBg(QPainter *painter) +{ + painter->save(); + painter->setPen(Qt::NoPen); + + int width = this->width(); + int height = this->height(); + + QRect bgRect; + if (linePosition == LinePosition_Left) { + bgRect = QRect(lineSpace, 0, width - lineSpace, height); + } else if (linePosition == LinePosition_Right) { + bgRect = QRect(0, 0, width - lineSpace, height); + } else if (linePosition == LinePosition_Top) { + bgRect = QRect(0, lineSpace, width, height - lineSpace); + } else if (linePosition == LinePosition_Bottom) { + bgRect = QRect(0, 0, width, height - lineSpace); + } + + //如果画刷存在则取画刷 + QBrush bgBrush; + if (isChecked()) { + bgBrush = checkBgBrush; + } else if (hover) { + bgBrush = hoverBgBrush; + } else { + bgBrush = normalBgBrush; + } + + if (bgBrush != Qt::NoBrush) { + painter->setBrush(bgBrush); + } else { + //根据当前状态选择对应颜色 + QColor bgColor; + if (isChecked()) { + bgColor = checkBgColor; + } else if (hover) { + bgColor = hoverBgColor; + } else { + bgColor = normalBgColor; + } + + painter->setBrush(bgColor); + } + + painter->drawRect(bgRect); + + painter->restore(); +} + +void CTabButton::drawText(QPainter *painter) +{ + painter->save(); + painter->setBrush(Qt::NoBrush); + + //根据当前状态选择对应颜色 + QColor textColor; + if (isChecked()) { + textColor = checkTextColor; + } else if (hover) { + textColor = hoverTextColor; + } else { + textColor = normalTextColor; + } + + QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom); + painter->setPen(textColor); + painter->setFont(font); + painter->drawText(textRect, textAlign | Qt::AlignVCenter, text()); + + painter->restore(); +} + + +void CTabButton::drawLine(QPainter *painter) +{ + if (!showLine) { + return; + } + + if (!isChecked()) { + return; + } + + painter->save(); + + QPen pen; + pen.setWidth(lineWidth); + pen.setColor(lineColor); + painter->setPen(pen); + + //根据线条位置设置线条坐标 + QPoint pointStart, pointEnd; + if (linePosition == LinePosition_Left) { + pointStart = QPoint(0, 0); + pointEnd = QPoint(0, height()); + } else if (linePosition == LinePosition_Right) { + pointStart = QPoint(width(), 0); + pointEnd = QPoint(width(), height()); + } else if (linePosition == LinePosition_Top) { + pointStart = QPoint(0, 0); + pointEnd = QPoint(width(), 0); + } else if (linePosition == LinePosition_Bottom) { + pointStart = QPoint(0, height()); + pointEnd = QPoint(width(), height()); + } + + painter->drawLine(pointStart, pointEnd); + + painter->restore(); +} + +void CTabButton::contextMenuEvent(QContextMenuEvent *event) +{ + Q_UNUSED(event) + if(!m_isShowCalendarEnable) + { + return; + } + CCalendarWidget * calendar = new CCalendarWidget(this); + calendar->setSelectedDate(QDate::currentDate()); + connect(calendar, &CCalendarWidget::clicked, this, &CTabButton::dataChanged); + calendar->show(); + calendar->move(parentWidget()->mapToGlobal(QPoint(width(), height() + 2))); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CTabButton.h b/product/src/gui/plugin/ISCSTrendCurves/widgets/CTabButton.h index e74897d3..56a7c409 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CTabButton.h +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CTabButton.h @@ -1,136 +1,136 @@ -#ifndef CTABBUTTON_H -#define CTABBUTTON_H - -#include -#include - -class CTabButton : public QPushButton -{ - Q_OBJECT - -public: - enum TextAlign { - TextAlign_Left = 0x0001, //左侧对齐 - TextAlign_Right = 0x0002, //右侧对齐 - TextAlign_Top = 0x0020, //顶部对齐 - TextAlign_Bottom = 0x0040, //底部对齐 - TextAlign_Center = 0x0004 //居中对齐 - }; - - enum LinePosition { - LinePosition_Left = 0, //左侧 - LinePosition_Right = 1, //右侧 - LinePosition_Top = 2, //顶部 - LinePosition_Bottom = 3 //底部 - }; - - explicit CTabButton(QWidget *parent = Q_NULLPTR); - - void setShowCalendarEnable(const bool &enable); - - int getPaddingLeft() const; - int getPaddingRight() const; - int getPaddingTop() const; - int getPaddingBottom() const; - TextAlign getTextAlign() const; - - QColor getNormalBgColor() const; - QColor getHoverBgColor() const; - QColor getCheckBgColor() const; - QColor getNormalTextColor() const; - QColor getHoverTextColor() const; - QColor getCheckTextColor() const; - - QFont getFont() const; - -public slots: - //设置文字间隔 - void setPaddingLeft(int paddingLeft); - void setPaddingRight(int paddingRight); - void setPaddingTop(int paddingTop); - void setPaddingBottom(int paddingBottom); - void setPadding(int padding); - void setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom); - - //设置文字对齐 - void setTextAlign(const TextAlign &textAlign); - - //设置显示线条 - void setShowLine(bool showLine); - //设置线条间隔 - void setLineSpace(int lineSpace); - //设置线条宽度 - void setLineWidth(int lineWidth); - //设置线条位置 - void setLinePosition(const LinePosition &linePosition); - //设置线条颜色 - void setLineColor(const QColor &lineColor); - - //设置正常背景颜色 - void setNormalBgColor(const QColor &normalBgColor); - //设置悬停背景颜色 - void setHoverBgColor(const QColor &hoverBgColor); - //设置选中背景颜色 - void setCheckBgColor(const QColor &checkBgColor); - - //设置正常文字颜色 - void setNormalTextColor(const QColor &normalTextColor); - //设置悬停文字颜色 - void setHoverTextColor(const QColor &hoverTextColor); - //设置选中文字颜色 - void setCheckTextColor(const QColor &checkTextColor); - - //设置正常背景画刷 - void setNormalBgBrush(const QBrush &normalBgBrush); - //设置悬停背景画刷 - void setHoverBgBrush(const QBrush &hoverBgBrush); - //设置选中背景画刷 - void setCheckBgBrush(const QBrush &checkBgBrush); - - void setFont(const QFont &font); - -signals: - void dataChanged(const QDate &date); - -protected: - void enterEvent(QEvent *); - void leaveEvent(QEvent *); - void paintEvent(QPaintEvent *e); - void drawBg(QPainter *painter); - void drawText(QPainter *painter); - void drawLine(QPainter *painter); - - void contextMenuEvent(QContextMenuEvent *event); - -private: - int paddingLeft; //文字左侧间隔 - int paddingRight; //文字右侧间隔 - int paddingTop; //文字顶部间隔 - int paddingBottom; //文字底部间隔 - TextAlign textAlign; //文字对齐 - - bool showLine; //显示线条 - int lineSpace; //线条间隔 - int lineWidth; //线条宽度 - LinePosition linePosition; //线条位置 - QColor lineColor; //线条颜色 - - QColor normalBgColor; //正常背景颜色 - QColor hoverBgColor; //悬停背景颜色 - QColor checkBgColor; //选中背景颜色 - QColor normalTextColor; //正常文字颜色 - QColor hoverTextColor; //悬停文字颜色 - QColor checkTextColor; //选中文字颜色 - - QBrush normalBgBrush; //正常背景画刷 - QBrush hoverBgBrush; //悬停背景画刷 - QBrush checkBgBrush; //选中背景画刷 - - QFont font; - - bool hover; //悬停标志位 - - bool m_isShowCalendarEnable; -}; - -#endif // CTABBUTTON_H +#ifndef CTABBUTTON_H +#define CTABBUTTON_H + +#include +#include + +class CTabButton : public QPushButton +{ + Q_OBJECT + +public: + enum TextAlign { + TextAlign_Left = 0x0001, //左侧对齐 + TextAlign_Right = 0x0002, //右侧对齐 + TextAlign_Top = 0x0020, //顶部对齐 + TextAlign_Bottom = 0x0040, //底部对齐 + TextAlign_Center = 0x0004 //居中对齐 + }; + + enum LinePosition { + LinePosition_Left = 0, //左侧 + LinePosition_Right = 1, //右侧 + LinePosition_Top = 2, //顶部 + LinePosition_Bottom = 3 //底部 + }; + + explicit CTabButton(QWidget *parent = Q_NULLPTR); + + void setShowCalendarEnable(const bool &enable); + + int getPaddingLeft() const; + int getPaddingRight() const; + int getPaddingTop() const; + int getPaddingBottom() const; + TextAlign getTextAlign() const; + + QColor getNormalBgColor() const; + QColor getHoverBgColor() const; + QColor getCheckBgColor() const; + QColor getNormalTextColor() const; + QColor getHoverTextColor() const; + QColor getCheckTextColor() const; + + QFont getFont() const; + +public slots: + //设置文字间隔 + void setPaddingLeft(int paddingLeft); + void setPaddingRight(int paddingRight); + void setPaddingTop(int paddingTop); + void setPaddingBottom(int paddingBottom); + void setPadding(int padding); + void setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom); + + //设置文字对齐 + void setTextAlign(const TextAlign &textAlign); + + //设置显示线条 + void setShowLine(bool showLine); + //设置线条间隔 + void setLineSpace(int lineSpace); + //设置线条宽度 + void setLineWidth(int lineWidth); + //设置线条位置 + void setLinePosition(const LinePosition &linePosition); + //设置线条颜色 + void setLineColor(const QColor &lineColor); + + //设置正常背景颜色 + void setNormalBgColor(const QColor &normalBgColor); + //设置悬停背景颜色 + void setHoverBgColor(const QColor &hoverBgColor); + //设置选中背景颜色 + void setCheckBgColor(const QColor &checkBgColor); + + //设置正常文字颜色 + void setNormalTextColor(const QColor &normalTextColor); + //设置悬停文字颜色 + void setHoverTextColor(const QColor &hoverTextColor); + //设置选中文字颜色 + void setCheckTextColor(const QColor &checkTextColor); + + //设置正常背景画刷 + void setNormalBgBrush(const QBrush &normalBgBrush); + //设置悬停背景画刷 + void setHoverBgBrush(const QBrush &hoverBgBrush); + //设置选中背景画刷 + void setCheckBgBrush(const QBrush &checkBgBrush); + + void setFont(const QFont &font); + +signals: + void dataChanged(const QDate &date); + +protected: + void enterEvent(QEvent *); + void leaveEvent(QEvent *); + void paintEvent(QPaintEvent *e); + void drawBg(QPainter *painter); + void drawText(QPainter *painter); + void drawLine(QPainter *painter); + + void contextMenuEvent(QContextMenuEvent *event); + +private: + int paddingLeft; //文字左侧间隔 + int paddingRight; //文字右侧间隔 + int paddingTop; //文字顶部间隔 + int paddingBottom; //文字底部间隔 + TextAlign textAlign; //文字对齐 + + bool showLine; //显示线条 + int lineSpace; //线条间隔 + int lineWidth; //线条宽度 + LinePosition linePosition; //线条位置 + QColor lineColor; //线条颜色 + + QColor normalBgColor; //正常背景颜色 + QColor hoverBgColor; //悬停背景颜色 + QColor checkBgColor; //选中背景颜色 + QColor normalTextColor; //正常文字颜色 + QColor hoverTextColor; //悬停文字颜色 + QColor checkTextColor; //选中文字颜色 + + QBrush normalBgBrush; //正常背景画刷 + QBrush hoverBgBrush; //悬停背景画刷 + QBrush checkBgBrush; //选中背景画刷 + + QFont font; + + bool hover; //悬停标志位 + + bool m_isShowCalendarEnable; +}; + +#endif // CTABBUTTON_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CToolTip.cpp b/product/src/gui/plugin/ISCSTrendCurves/widgets/CToolTip.cpp index ca4b1a79..df30688a 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CToolTip.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CToolTip.cpp @@ -1,71 +1,71 @@ -#include "CToolTip.h" -#include -#include -#include -#include -#include - -CToolTip::CToolTip(QWidget *parent) - : QDialog(parent) -{ - setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); - setAttribute(Qt::WA_DeleteOnClose); - setObjectName("ToolTip"); - label_ = new QLabel(this); - label_->setMouseTracking(true); - label_->installEventFilter(parent); - QHBoxLayout *mLayout = new QHBoxLayout(this); - mLayout->addWidget(label_); - mLayout->setMargin(3); - installEventFilter(this); - label_->setStyleSheet("color:white;"); - setStyleSheet("CToolTip { \ - border: 1px solid #B6C2CD; \ - border-radius: 3px; \ - background: #051E2F; \ - }"); -} - -CToolTip::~CToolTip() -{ -} - -QString CToolTip::text() -{ - return label_->text(); -} - -void CToolTip::setText(const QString &text) -{ - label_->setText(text); -} - -bool CToolTip::eventFilter(QObject *object, QEvent *event) -{ - if (object == this) - { - if (QEvent::WindowDeactivate == event->type()) - { - this->close(); - event->accept(); - return true; - } - } - return QWidget::eventFilter(object, event); -} - -void CToolTip::popup(QPoint pos, const QString &text, QWidget *parent) -{ - CToolTip * tip = new CToolTip(parent); - tip->setText(text); - tip->show(); - int screenWidth = QApplication::desktop()->screenGeometry().width(); - if((tip->width() + pos.x()) < screenWidth) - { - tip->move(pos); - } - else - { - tip->move(pos.x() - tip->width(), pos.y()); - } -} +#include "CToolTip.h" +#include +#include +#include +#include +#include + +CToolTip::CToolTip(QWidget *parent) + : QDialog(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_DeleteOnClose); + setObjectName("ToolTip"); + label_ = new QLabel(this); + label_->setMouseTracking(true); + label_->installEventFilter(parent); + QHBoxLayout *mLayout = new QHBoxLayout(this); + mLayout->addWidget(label_); + mLayout->setMargin(3); + installEventFilter(this); + label_->setStyleSheet("color:white;"); + setStyleSheet("CToolTip { \ + border: 1px solid #B6C2CD; \ + border-radius: 3px; \ + background: #051E2F; \ + }"); +} + +CToolTip::~CToolTip() +{ +} + +QString CToolTip::text() +{ + return label_->text(); +} + +void CToolTip::setText(const QString &text) +{ + label_->setText(text); +} + +bool CToolTip::eventFilter(QObject *object, QEvent *event) +{ + if (object == this) + { + if (QEvent::WindowDeactivate == event->type()) + { + this->close(); + event->accept(); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +void CToolTip::popup(QPoint pos, const QString &text, QWidget *parent) +{ + CToolTip * tip = new CToolTip(parent); + tip->setText(text); + tip->show(); + int screenWidth = QApplication::desktop()->screenGeometry().width(); + if((tip->width() + pos.x()) < screenWidth) + { + tip->move(pos); + } + else + { + tip->move(pos.x() - tip->width(), pos.y()); + } +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CToolTip.h b/product/src/gui/plugin/ISCSTrendCurves/widgets/CToolTip.h index 92ec4b3f..27affd5a 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CToolTip.h +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CToolTip.h @@ -1,25 +1,25 @@ -#ifndef CTOOLTIP_H -#define CTOOLTIP_H - -#include - -class QLabel; -class CToolTip : public QDialog -{ - Q_OBJECT -public: - CToolTip(QWidget *parent = nullptr); - ~CToolTip(); - - QString text(); - void setText(const QString &text); - static void popup(QPoint pos, const QString &text, QWidget *parent = nullptr); - -protected: - bool eventFilter(QObject *object, QEvent *event); - -private: - QLabel *label_; -}; - -#endif // CTOOLTIP_H +#ifndef CTOOLTIP_H +#define CTOOLTIP_H + +#include + +class QLabel; +class CToolTip : public QDialog +{ + Q_OBJECT +public: + CToolTip(QWidget *parent = nullptr); + ~CToolTip(); + + QString text(); + void setText(const QString &text); + static void popup(QPoint pos, const QString &text, QWidget *parent = nullptr); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private: + QLabel *label_; +}; + +#endif // CTOOLTIP_H diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CTrendAddWidget.cpp b/product/src/gui/plugin/ISCSTrendCurves/widgets/CTrendAddWidget.cpp index 96766edc..e2a537aa 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CTrendAddWidget.cpp +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CTrendAddWidget.cpp @@ -1,78 +1,78 @@ -#include "CTrendAddWidget.h" -#include "CTrendInfoManage.h" -#include -#include -#include -#include -#include -#include - -CTrendAddWidget::CTrendAddWidget(QWidget *parent) - : QDialog(parent) -{ - QGridLayout *layout = new QGridLayout(this); - location = new QComboBox(); - subSyste = new QComboBox(); - nameEdit = new QLineEdit(); - QPushButton *accept = new QPushButton(tr("确认")); - QPushButton *reject = new QPushButton(tr("取消")); - QLabel *label1 = new QLabel(tr("位置")); - QLabel *label2 = new QLabel(tr("专业")); - QLabel *label3 = new QLabel(tr("趋势名称")); - - layout->addWidget(label1, 0, 0); - layout->addWidget(location, 0, 1, 1, -1); - layout->addWidget(label2, 1, 0); - layout->addWidget(subSyste, 1, 1, 1, -1); - layout->addWidget(label3, 2, 0); - layout->addWidget(nameEdit, 2, 1, 1, -1); - layout->addWidget(accept, 3, 1); - layout->addWidget(reject, 3, 2); - setLayout(layout); - - connect(accept, SIGNAL(clicked()), this, SLOT(slotAccept())); - connect(reject, SIGNAL(clicked()), this, SLOT(slotReject())); - - QMap locationMap = CTrendInfoManage::instance()->locationInfo(); - QMap subSysteMap = CTrendInfoManage::instance()->subSystemInfo(); - QMap::const_iterator loaIter = locationMap.constBegin(); - for(; loaIter != locationMap.constEnd(); ++loaIter) - { - location->addItem(loaIter.value(), loaIter.key()); - } - QMap::const_iterator subIter = subSysteMap.constBegin(); - for(; subIter != subSysteMap.constEnd(); ++subIter) - { - subSyste->addItem(subIter.value(), subIter.key()); - } -} - -CTrendAddWidget::~CTrendAddWidget() -{ - -} - -int CTrendAddWidget::locationId() -{ - return location->currentData().toInt(); -} - -int CTrendAddWidget::subSysteId() -{ - return subSyste->currentData().toInt(); -} - -QString CTrendAddWidget::text() -{ - return nameEdit->text(); -} - -void CTrendAddWidget::slotAccept() -{ - emit acceptedInput(); -} - -void CTrendAddWidget::slotReject() -{ - close(); -} +#include "CTrendAddWidget.h" +#include "CTrendInfoManage.h" +#include +#include +#include +#include +#include +#include + +CTrendAddWidget::CTrendAddWidget(QWidget *parent) + : QDialog(parent) +{ + QGridLayout *layout = new QGridLayout(this); + location = new QComboBox(); + subSyste = new QComboBox(); + nameEdit = new QLineEdit(); + QPushButton *accept = new QPushButton(tr("确认")); + QPushButton *reject = new QPushButton(tr("取消")); + QLabel *label1 = new QLabel(tr("位置")); + QLabel *label2 = new QLabel(tr("专业")); + QLabel *label3 = new QLabel(tr("趋势名称")); + + layout->addWidget(label1, 0, 0); + layout->addWidget(location, 0, 1, 1, -1); + layout->addWidget(label2, 1, 0); + layout->addWidget(subSyste, 1, 1, 1, -1); + layout->addWidget(label3, 2, 0); + layout->addWidget(nameEdit, 2, 1, 1, -1); + layout->addWidget(accept, 3, 1); + layout->addWidget(reject, 3, 2); + setLayout(layout); + + connect(accept, SIGNAL(clicked()), this, SLOT(slotAccept())); + connect(reject, SIGNAL(clicked()), this, SLOT(slotReject())); + + QMap locationMap = CTrendInfoManage::instance()->locationInfo(); + QMap subSysteMap = CTrendInfoManage::instance()->subSystemInfo(); + QMap::const_iterator loaIter = locationMap.constBegin(); + for(; loaIter != locationMap.constEnd(); ++loaIter) + { + location->addItem(loaIter.value(), loaIter.key()); + } + QMap::const_iterator subIter = subSysteMap.constBegin(); + for(; subIter != subSysteMap.constEnd(); ++subIter) + { + subSyste->addItem(subIter.value(), subIter.key()); + } +} + +CTrendAddWidget::~CTrendAddWidget() +{ + +} + +int CTrendAddWidget::locationId() +{ + return location->currentData().toInt(); +} + +int CTrendAddWidget::subSysteId() +{ + return subSyste->currentData().toInt(); +} + +QString CTrendAddWidget::text() +{ + return nameEdit->text(); +} + +void CTrendAddWidget::slotAccept() +{ + emit acceptedInput(); +} + +void CTrendAddWidget::slotReject() +{ + close(); +} diff --git a/product/src/gui/plugin/ISCSTrendCurves/widgets/CTrendAddWidget.h b/product/src/gui/plugin/ISCSTrendCurves/widgets/CTrendAddWidget.h index 510c2b8b..9ce2b4bc 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/widgets/CTrendAddWidget.h +++ b/product/src/gui/plugin/ISCSTrendCurves/widgets/CTrendAddWidget.h @@ -1,33 +1,33 @@ -#ifndef CTRENDADDWIDGET_H -#define CTRENDADDWIDGET_H - -#include - -class QLineEdit; -class QComboBox; -class CTrendAddWidget : public QDialog -{ - Q_OBJECT -public: - explicit CTrendAddWidget(QWidget *parent = nullptr); - ~CTrendAddWidget(); - - int locationId(); - int subSysteId(); - QString text(); - -signals: - void acceptedInput(); - -private slots: - void slotAccept(); - - void slotReject(); - -private: - QLineEdit *nameEdit; - QComboBox *location; - QComboBox *subSyste; -}; - -#endif // CTRENDADDWIDGET_H +#ifndef CTRENDADDWIDGET_H +#define CTRENDADDWIDGET_H + +#include + +class QLineEdit; +class QComboBox; +class CTrendAddWidget : public QDialog +{ + Q_OBJECT +public: + explicit CTrendAddWidget(QWidget *parent = nullptr); + ~CTrendAddWidget(); + + int locationId(); + int subSysteId(); + QString text(); + +signals: + void acceptedInput(); + +private slots: + void slotAccept(); + + void slotReject(); + +private: + QLineEdit *nameEdit; + QComboBox *location; + QComboBox *subSyste; +}; + +#endif // CTRENDADDWIDGET_H diff --git a/product/src/gui/plugin/InverseTimeLimit/CExcelOpt.cpp b/product/src/gui/plugin/InverseTimeLimit/CExcelOpt.cpp index 84d9300a..a2d3683f 100644 --- a/product/src/gui/plugin/InverseTimeLimit/CExcelOpt.cpp +++ b/product/src/gui/plugin/InverseTimeLimit/CExcelOpt.cpp @@ -1,285 +1,285 @@ -#include "CExcelOpt.h" -#include -#include -#include - -CExcelOpt::CExcelOpt(QObject *parent) - : QObject(parent) -{ - m_mutex = new QMutex(); - - m_vecDevXls.resize(6); -} - -void CExcelOpt::release() -{ - delete this; -} - -#ifdef OS_WINDOWS -void CExcelOpt::slotUpdateDevXls(const DeviceXlsVector &devXls) -{ - QMutexLocker locker(m_mutex); - - m_vecDevXls = devXls; - - if(m_vecDevXls.size() != 6) - { - m_vecDevXls.resize(6); - } -} - -bool CExcelOpt::slotExcelToCsvFile(const QString &excelFileName, const QString &csvFileName, int flag) -{ - QMutexLocker locker(m_mutex); - - if (!QFile::exists(excelFileName)) - { - emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); - return false; - } - - // 当pApplication析构的时候会将其所有相关的子对象都清理 - QScopedPointer pApplication(new QAxObject()); - - // 设置连接Excel控件,需要在GUI的环境下才能成功 - bool ok = pApplication->setControl("Excel.Application"); - if (!ok) - { - emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); - return false; - } - emit sigSetValue(5); - - pApplication->dynamicCall("SetVisible(bool)", false); // false表示不显示窗体 - pApplication->setProperty("DisplayAlerts", false); // false表示不显示(输出)任何警告信息。 - emit sigSetValue(10); - - QAxObject *pWorkBooks = pApplication->querySubObject("Workbooks"); // Excel工作薄(对象) - if (pWorkBooks == 0) - { - emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); - return false; - } - emit sigSetValue(15); - - QAxObject *pWorkBook = pWorkBooks->querySubObject("Open(const QString &)", excelFileName); // 打开一个Excel文件 - if (pWorkBook == 0) - { - emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); - return false; - } - emit sigSetValue(20); - - QAxObject *pSheets = pWorkBook->querySubObject("WorkSheets"); // Excel工作表集 - if (pSheets == 0) - { - emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); - return false; - } - emit sigSetValue(50); - - int sheet_count = pSheets->property("Count").toInt(); //获取工作表数目 - if(sheet_count > 0) - { - QAxObject *work_sheet = pSheets->querySubObject("Item(int)", 4); // 得到指定索引的工作表 - if (work_sheet == 0) - { - emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); - return false; - } - emit sigSetValue(60); - - // QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", 1); - QAxObject *used_range = work_sheet->querySubObject("UsedRange"); - QAxObject *rows = used_range->querySubObject("Rows"); - QAxObject *columns = used_range->querySubObject("Columns"); - //int row_start = used_range->property("Row").toInt(); //获取起始行:1 - //int column_start = used_range->property("Column").toInt(); //获取起始列 - int lNumRows = rows->property("Count").toInt(); //获取行数 - int lNumCols = columns->property("Count").toInt(); //获取列数 - emit sigSetValue(65); - - int r, c; - for(r=1;r<=lNumRows;r++) - { - for(c=1;c<=lNumCols;c++) - { - if(flag == EN_OPEN) - { - - - for (int xx=0;xx<6;xx++) - { - if (r== (5 + (xx*7))) - { - char S='S'-'A' + 1; - char U='U'-'A' + 1; - char V='V'-'A' + 1; - - if (c==S) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - m_vecDevXls[xx].name =val; - } - - if (c==U) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - m_vecDevXls[xx].VB =val; - } - - if (c==V) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - m_vecDevXls[xx].VT=val; - } - } - - if (r== (7 + (xx*7))) - { - char S='S'-'A' + 1; - char T='T'-'A' + 1; - char V='V'-'A' + 1; - char W='W'-'A' + 1; - char X='X'-'A' + 1; - if (c==S) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - m_vecDevXls[xx].CO=val; - } - - if (c==T) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - m_vecDevXls[xx].t=val; - } - - if (c==V) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - m_vecDevXls[xx].ts=val; - } - - if (c==W) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - m_vecDevXls[xx].I=val; - } - - if (c==X) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - m_vecDevXls[xx].tt=val; - } - } - } - }else - { - - - for (int xx=0;xx<6;xx++) - { - if (r== (5 + (xx*7))) - { - char S='S'-'A' + 1; - char U='U'-'A' + 1; - char V='V'-'A' + 1; - - if (c==S) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", m_vecDevXls[xx].name); - } - - if (c==U) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", m_vecDevXls[xx].VB); - - } - - if (c==V) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", m_vecDevXls[xx].VT); - } - } - - if (r== (7 + (xx*7))) - { - char S='S'-'A' + 1; - char T='T'-'A' + 1; - char V='V'-'A' + 1; - char W='W'-'A' + 1; - char X='X'-'A' + 1; - if (c==S) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", m_vecDevXls[xx].CO); - } - - if (c==T) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", m_vecDevXls[xx].t); - - } - - if (c==V) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", m_vecDevXls[xx].ts); - } - - if (c==W) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", m_vecDevXls[xx].I); - } - - if (c==X) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", m_vecDevXls[xx].tt); - - } - } - } - - } - } - } - } - - QAxObject *pSheet5 = pSheets->querySubObject("Item(int)", 5); // 得到指定索引的工作表 - emit sigSetValue(85); - - // 另存为文件, 3: txt文件(空格分隔)| 6: csv文件(逗号分隔) - int saveType=44; - if(flag == EN_SAVE) - { - pSheet5->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(csvFileName)); - }else - { - pSheet5->dynamicCall("SaveAs(const QString&, int)", QDir::toNativeSeparators(csvFileName), saveType); - } - // pWorkBooks->dynamicCall("SaveAs(const QString&, int)", QDir::toNativeSeparators(csvFileName), 44); - emit sigSetValue(95); - - pWorkBooks->dynamicCall("Close(Boolean)", false);//关闭工作簿 - pApplication->dynamicCall("Quit(void)"); - - emit sigSetValue(100); - emit sigExcelToCsvResult(true, csvFileName, m_vecDevXls, flag); - return true; -} -#endif +#include "CExcelOpt.h" +#include +#include +#include + +CExcelOpt::CExcelOpt(QObject *parent) + : QObject(parent) +{ + m_mutex = new QMutex(); + + m_vecDevXls.resize(6); +} + +void CExcelOpt::release() +{ + delete this; +} + +#ifdef OS_WINDOWS +void CExcelOpt::slotUpdateDevXls(const DeviceXlsVector &devXls) +{ + QMutexLocker locker(m_mutex); + + m_vecDevXls = devXls; + + if(m_vecDevXls.size() != 6) + { + m_vecDevXls.resize(6); + } +} + +bool CExcelOpt::slotExcelToCsvFile(const QString &excelFileName, const QString &csvFileName, int flag) +{ + QMutexLocker locker(m_mutex); + + if (!QFile::exists(excelFileName)) + { + emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); + return false; + } + + // 当pApplication析构的时候会将其所有相关的子对象都清理 + QScopedPointer pApplication(new QAxObject()); + + // 设置连接Excel控件,需要在GUI的环境下才能成功 + bool ok = pApplication->setControl("Excel.Application"); + if (!ok) + { + emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); + return false; + } + emit sigSetValue(5); + + pApplication->dynamicCall("SetVisible(bool)", false); // false表示不显示窗体 + pApplication->setProperty("DisplayAlerts", false); // false表示不显示(输出)任何警告信息。 + emit sigSetValue(10); + + QAxObject *pWorkBooks = pApplication->querySubObject("Workbooks"); // Excel工作薄(对象) + if (pWorkBooks == 0) + { + emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); + return false; + } + emit sigSetValue(15); + + QAxObject *pWorkBook = pWorkBooks->querySubObject("Open(const QString &)", excelFileName); // 打开一个Excel文件 + if (pWorkBook == 0) + { + emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); + return false; + } + emit sigSetValue(20); + + QAxObject *pSheets = pWorkBook->querySubObject("WorkSheets"); // Excel工作表集 + if (pSheets == 0) + { + emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); + return false; + } + emit sigSetValue(50); + + int sheet_count = pSheets->property("Count").toInt(); //获取工作表数目 + if(sheet_count > 0) + { + QAxObject *work_sheet = pSheets->querySubObject("Item(int)", 4); // 得到指定索引的工作表 + if (work_sheet == 0) + { + emit sigExcelToCsvResult(false, csvFileName, m_vecDevXls, flag); + return false; + } + emit sigSetValue(60); + + // QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", 1); + QAxObject *used_range = work_sheet->querySubObject("UsedRange"); + QAxObject *rows = used_range->querySubObject("Rows"); + QAxObject *columns = used_range->querySubObject("Columns"); + //int row_start = used_range->property("Row").toInt(); //获取起始行:1 + //int column_start = used_range->property("Column").toInt(); //获取起始列 + int lNumRows = rows->property("Count").toInt(); //获取行数 + int lNumCols = columns->property("Count").toInt(); //获取列数 + emit sigSetValue(65); + + int r, c; + for(r=1;r<=lNumRows;r++) + { + for(c=1;c<=lNumCols;c++) + { + if(flag == EN_OPEN) + { + + + for (int xx=0;xx<6;xx++) + { + if (r== (5 + (xx*7))) + { + char S='S'-'A' + 1; + char U='U'-'A' + 1; + char V='V'-'A' + 1; + + if (c==S) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + m_vecDevXls[xx].name =val; + } + + if (c==U) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + m_vecDevXls[xx].VB =val; + } + + if (c==V) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + m_vecDevXls[xx].VT=val; + } + } + + if (r== (7 + (xx*7))) + { + char S='S'-'A' + 1; + char T='T'-'A' + 1; + char V='V'-'A' + 1; + char W='W'-'A' + 1; + char X='X'-'A' + 1; + if (c==S) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + m_vecDevXls[xx].CO=val; + } + + if (c==T) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + m_vecDevXls[xx].t=val; + } + + if (c==V) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + m_vecDevXls[xx].ts=val; + } + + if (c==W) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + m_vecDevXls[xx].I=val; + } + + if (c==X) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + m_vecDevXls[xx].tt=val; + } + } + } + }else + { + + + for (int xx=0;xx<6;xx++) + { + if (r== (5 + (xx*7))) + { + char S='S'-'A' + 1; + char U='U'-'A' + 1; + char V='V'-'A' + 1; + + if (c==S) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", m_vecDevXls[xx].name); + } + + if (c==U) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", m_vecDevXls[xx].VB); + + } + + if (c==V) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", m_vecDevXls[xx].VT); + } + } + + if (r== (7 + (xx*7))) + { + char S='S'-'A' + 1; + char T='T'-'A' + 1; + char V='V'-'A' + 1; + char W='W'-'A' + 1; + char X='X'-'A' + 1; + if (c==S) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", m_vecDevXls[xx].CO); + } + + if (c==T) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", m_vecDevXls[xx].t); + + } + + if (c==V) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", m_vecDevXls[xx].ts); + } + + if (c==W) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", m_vecDevXls[xx].I); + } + + if (c==X) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", m_vecDevXls[xx].tt); + + } + } + } + + } + } + } + } + + QAxObject *pSheet5 = pSheets->querySubObject("Item(int)", 5); // 得到指定索引的工作表 + emit sigSetValue(85); + + // 另存为文件, 3: txt文件(空格分隔)| 6: csv文件(逗号分隔) + int saveType=44; + if(flag == EN_SAVE) + { + pSheet5->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(csvFileName)); + }else + { + pSheet5->dynamicCall("SaveAs(const QString&, int)", QDir::toNativeSeparators(csvFileName), saveType); + } + // pWorkBooks->dynamicCall("SaveAs(const QString&, int)", QDir::toNativeSeparators(csvFileName), 44); + emit sigSetValue(95); + + pWorkBooks->dynamicCall("Close(Boolean)", false);//关闭工作簿 + pApplication->dynamicCall("Quit(void)"); + + emit sigSetValue(100); + emit sigExcelToCsvResult(true, csvFileName, m_vecDevXls, flag); + return true; +} +#endif diff --git a/product/src/gui/plugin/InverseTimeLimit/CExcelOpt.h b/product/src/gui/plugin/InverseTimeLimit/CExcelOpt.h index 4f5cd35f..1ccb0770 100644 --- a/product/src/gui/plugin/InverseTimeLimit/CExcelOpt.h +++ b/product/src/gui/plugin/InverseTimeLimit/CExcelOpt.h @@ -1,41 +1,41 @@ -#ifndef CEXCELOPT_H -#define CEXCELOPT_H - -#ifdef WIN32 - -#include -#include - -#else -#endif - -#include "para.h" -#include -#include - -class QMutex; -class CExcelOpt : public QObject -{ - Q_OBJECT -public: - CExcelOpt(QObject *parent=Q_NULLPTR); - - void release(); - - void slotUpdateDevXls(const DeviceXlsVector &devXls); - -#ifdef OS_WINDOWS - bool slotExcelToCsvFile(const QString &excelFileName, const QString &csvFileName, int flag); -#endif - -signals: - void sigExcelToCsvResult(bool bSuccess, const QString &csvFileName, const DeviceXlsVector &devXls, int flag); - - void sigSetValue(int nValue); - -private: - DeviceXlsVector m_vecDevXls; - QMutex * m_mutex; -}; - -#endif // CEXCELOPT_H +#ifndef CEXCELOPT_H +#define CEXCELOPT_H + +#ifdef WIN32 + +#include +#include + +#else +#endif + +#include "para.h" +#include +#include + +class QMutex; +class CExcelOpt : public QObject +{ + Q_OBJECT +public: + CExcelOpt(QObject *parent=Q_NULLPTR); + + void release(); + + void slotUpdateDevXls(const DeviceXlsVector &devXls); + +#ifdef OS_WINDOWS + bool slotExcelToCsvFile(const QString &excelFileName, const QString &csvFileName, int flag); +#endif + +signals: + void sigExcelToCsvResult(bool bSuccess, const QString &csvFileName, const DeviceXlsVector &devXls, int flag); + + void sigSetValue(int nValue); + +private: + DeviceXlsVector m_vecDevXls; + QMutex * m_mutex; +}; + +#endif // CEXCELOPT_H diff --git a/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.cpp b/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.cpp index 5c9cac09..e0cafade 100644 --- a/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.cpp +++ b/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CInversetimelimitPluginWidget.h" -#include "inversetimelimit.h" -#include - -CInversetimelimitPluginWidge::CInversetimelimitPluginWidge(QObject *parent): QObject(parent) -{ - -} - -CInversetimelimitPluginWidge::~CInversetimelimitPluginWidge() -{ - -} - -bool CInversetimelimitPluginWidge::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - InverseTimeLimit *pWidget = new InverseTimeLimit(editMode, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CInversetimelimitPluginWidge::release() -{ - -} +#include "CInversetimelimitPluginWidget.h" +#include "inversetimelimit.h" +#include + +CInversetimelimitPluginWidge::CInversetimelimitPluginWidge(QObject *parent): QObject(parent) +{ + +} + +CInversetimelimitPluginWidge::~CInversetimelimitPluginWidge() +{ + +} + +bool CInversetimelimitPluginWidge::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + InverseTimeLimit *pWidget = new InverseTimeLimit(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CInversetimelimitPluginWidge::release() +{ + +} diff --git a/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.h b/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.h index aabc0c60..9a38dc97 100644 --- a/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.h +++ b/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CINVERSETIMELIMITPLUGINWIDGET_H -#define CINVERSETIMELIMITPLUGINWIDGET_H - - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CInversetimelimitPluginWidge : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CInversetimelimitPluginWidge(QObject *parent = 0); - ~CInversetimelimitPluginWidge(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CINVERSETIMELIMITPLUGINWIDGET_H +#ifndef CINVERSETIMELIMITPLUGINWIDGET_H +#define CINVERSETIMELIMITPLUGINWIDGET_H + + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CInversetimelimitPluginWidge : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CInversetimelimitPluginWidge(QObject *parent = 0); + ~CInversetimelimitPluginWidge(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CINVERSETIMELIMITPLUGINWIDGET_H diff --git a/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.cpp b/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.cpp index d26f35aa..0ab825fa 100644 --- a/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.cpp +++ b/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.cpp @@ -1,34 +1,34 @@ -#include "CProcessDialog.h" -#include "ui_CProcessDialog.h" -#include - -CProcessDialog::CProcessDialog(QDialog *parent) : - QDialog(parent), - ui(new Ui::CProcessDialog) -{ - ui->setupUi(this); - setWindowFlags(windowFlags()|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); - setWindowModality(Qt::ApplicationModal); - connect( ui->pb_cancel, SIGNAL(clicked(bool)), this, SLOT(slotPbcancelClicked(bool)), Qt::DirectConnection ); - ui->pb_cancel->setHidden(true); -} - -CProcessDialog::~CProcessDialog() -{ - delete ui; -} - -void CProcessDialog::slotPbcancelClicked( bool ) -{ - signalCancel(); -} - -void CProcessDialog::slotSetValue( int nValue ) -{ - ui->progressBar->setValue( nValue ); -} - -void CProcessDialog::reset() -{ - ui->progressBar->setValue( 0 ); -} +#include "CProcessDialog.h" +#include "ui_CProcessDialog.h" +#include + +CProcessDialog::CProcessDialog(QDialog *parent) : + QDialog(parent), + ui(new Ui::CProcessDialog) +{ + ui->setupUi(this); + setWindowFlags(windowFlags()|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); + setWindowModality(Qt::ApplicationModal); + connect( ui->pb_cancel, SIGNAL(clicked(bool)), this, SLOT(slotPbcancelClicked(bool)), Qt::DirectConnection ); + ui->pb_cancel->setHidden(true); +} + +CProcessDialog::~CProcessDialog() +{ + delete ui; +} + +void CProcessDialog::slotPbcancelClicked( bool ) +{ + signalCancel(); +} + +void CProcessDialog::slotSetValue( int nValue ) +{ + ui->progressBar->setValue( nValue ); +} + +void CProcessDialog::reset() +{ + ui->progressBar->setValue( 0 ); +} diff --git a/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.h b/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.h index 2f322338..bb06cd74 100644 --- a/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.h +++ b/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.h @@ -1,32 +1,32 @@ -#ifndef CPROCESSDIALOG_H -#define CPROCESSDIALOG_H - -#include - -namespace Ui { -class CProcessDialog; -} - -class CProcessDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CProcessDialog(QDialog *parent = 0); - ~CProcessDialog(); - -signals: - void signalCancel(); - -public slots: - void slotPbcancelClicked( bool bChecked ); - void slotSetValue( int nValue ); - -public: - void reset(); - -private: - Ui::CProcessDialog *ui; -}; - -#endif // CPROCESSDIALOG_H +#ifndef CPROCESSDIALOG_H +#define CPROCESSDIALOG_H + +#include + +namespace Ui { +class CProcessDialog; +} + +class CProcessDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CProcessDialog(QDialog *parent = 0); + ~CProcessDialog(); + +signals: + void signalCancel(); + +public slots: + void slotPbcancelClicked( bool bChecked ); + void slotSetValue( int nValue ); + +public: + void reset(); + +private: + Ui::CProcessDialog *ui; +}; + +#endif // CPROCESSDIALOG_H diff --git a/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.ui b/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.ui index 5c0c5d70..206716dc 100644 --- a/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.ui +++ b/product/src/gui/plugin/InverseTimeLimit/CProcessDialog.ui @@ -1,71 +1,71 @@ - - - CProcessDialog - - - - 0 - 0 - 400 - 28 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 28 - - - - 0 - - - Qt::Horizontal - - - - - - - - 0 - 28 - - - - 取消 - - - false - - - false - - - - - - - - + + + CProcessDialog + + + + 0 + 0 + 400 + 28 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 28 + + + + 0 + + + Qt::Horizontal + + + + + + + + 0 + 28 + + + + 取消 + + + false + + + false + + + + + + + + diff --git a/product/src/gui/plugin/InverseTimeLimit/InverseTimeLimit.pro b/product/src/gui/plugin/InverseTimeLimit/InverseTimeLimit.pro index 50f9e356..96358551 100644 --- a/product/src/gui/plugin/InverseTimeLimit/InverseTimeLimit.pro +++ b/product/src/gui/plugin/InverseTimeLimit/InverseTimeLimit.pro @@ -1,69 +1,69 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-07-29T16:16:48 -# -#------------------------------------------------- -#requires(win32) - -#requires(win32) - -QT += core gui - -QT += webenginewidgets - -#requires(win32) -win32{ -QT += axcontainer -} - - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = InverseTimeLimitWidget - - - - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - main.cpp \ - inversetimelimit.cpp \ - CInversetimelimitPluginWidget.cpp \ - CExcelOpt.cpp \ - CProcessDialog.cpp - -HEADERS += \ - inversetimelimit.h \ - para.h \ - CInversetimelimitPluginWidget.h \ - CExcelOpt.h \ - CProcessDialog.h - -FORMS += \ - inversetimelimit.ui \ - CProcessDialog.ui - - -LIBS += -lpub_utility_api - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2021-07-29T16:16:48 +# +#------------------------------------------------- +#requires(win32) + +#requires(win32) + +QT += core gui + +QT += webenginewidgets + +#requires(win32) +win32{ +QT += axcontainer +} + + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = InverseTimeLimitWidget + + + + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + inversetimelimit.cpp \ + CInversetimelimitPluginWidget.cpp \ + CExcelOpt.cpp \ + CProcessDialog.cpp + +HEADERS += \ + inversetimelimit.h \ + para.h \ + CInversetimelimitPluginWidget.h \ + CExcelOpt.h \ + CProcessDialog.h + +FORMS += \ + inversetimelimit.ui \ + CProcessDialog.ui + + +LIBS += -lpub_utility_api + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.cpp b/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.cpp index 3edf7066..e26f943c 100644 --- a/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.cpp +++ b/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.cpp @@ -1,330 +1,330 @@ -#include "inversetimelimit.h" -#include "ui_inversetimelimit.h" -#include "CProcessDialog.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include -#include - -InverseTimeLimit::InverseTimeLimit(bool editMode, QWidget *parent) : - QWidget(parent), - ui(new Ui::InverseTimeLimit), - view(Q_NULLPTR), - m_pExcelOpt(Q_NULLPTR), - m_pExcelOptThread(Q_NULLPTR), - m_processDialog(Q_NULLPTR) -{ - ui->setupUi(this); - -#ifdef OS_WINDOWS - ui->label_49->setVisible(false); - if(!editMode) - { - QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); - QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); - - qRegisterMetaType("DeviceXlsVector"); - - m_processDialog = new CProcessDialog; - m_processDialog->hide(); - - m_pExcelOpt = new CExcelOpt; - m_pExcelOptThread = new QThread(this); - m_pExcelOpt->moveToThread(m_pExcelOptThread); - connect(m_pExcelOptThread, &QThread::finished, m_pExcelOptThread, &QThread::deleteLater); - connect(this, &InverseTimeLimit::releaseExcelOptThread, m_pExcelOpt, &CExcelOpt::release, Qt::BlockingQueuedConnection); - connect(this, &InverseTimeLimit::sigExcelToCsvFile, m_pExcelOpt, &CExcelOpt::slotExcelToCsvFile); - connect(this, &InverseTimeLimit::sigUpdateDevXls, m_pExcelOpt, &CExcelOpt::slotUpdateDevXls); - connect(m_pExcelOpt, &CExcelOpt::sigExcelToCsvResult, this, &InverseTimeLimit::slot_ExcelToCsvResult); - connect(m_pExcelOpt, &CExcelOpt::sigSetValue, m_processDialog, &CProcessDialog::slotSetValue); - m_pExcelOptThread->start(); - } -#else - ui->label_49->setVisible(true); -#endif - - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -InverseTimeLimit::~InverseTimeLimit() -{ - if(m_processDialog) - { - delete m_processDialog; - } - m_processDialog = Q_NULLPTR; - - if(m_pExcelOpt) - { - emit releaseExcelOptThread(); - m_pExcelOpt = Q_NULLPTR; - } - - if(m_pExcelOptThread) - { - m_pExcelOptThread->quit(); - m_pExcelOptThread->wait(); - } - m_pExcelOptThread = Q_NULLPTR; - - delete ui; -} - -int InverseTimeLimit::iniDevXls(DeviceXlsVector &devXls) -{ - devXls.resize(6); - devXls[0].name= ui->lineEdit_CurName1->text().trimmed(); - devXls[0].CO= ui->comboBox_Co1->currentText().trimmed(); - devXls[0].VB= ui->lineEdit_Vb1->text().trimmed(); - devXls[0].VT= ui->lineEdit_Vt1->text().trimmed(); - devXls[0].t = ui->lineEdit_t1->text().trimmed(); - devXls[0].ts= ui->lineEdit_I1->text().trimmed(); - devXls[0].I= ui->lineEdit_II1->text().trimmed(); - devXls[0].tt = ui->lineEdit_tt1->text().trimmed(); - - devXls[1].name= ui->lineEdit_CurName2->text().trimmed(); - devXls[1].CO= ui->comboBox_Co2->currentText().trimmed(); - devXls[1].VB= ui->lineEdit_Vb2->text().trimmed(); - devXls[1].VT= ui->lineEdit_Vt2->text().trimmed(); - devXls[1].t = ui->lineEdit_t2->text().trimmed(); - devXls[1].ts= ui->lineEdit_I2->text().trimmed(); - devXls[1].I= ui->lineEdit_II2->text().trimmed(); - devXls[1].tt = ui->lineEdit_tt2->text().trimmed(); - - devXls[2].name= ui->lineEdit_CurName3->text().trimmed(); - devXls[2].CO= ui->comboBox_Co3->currentText().trimmed(); - devXls[2].VB= ui->lineEdit_Vb3->text().trimmed(); - devXls[2].VT= ui->lineEdit_Vt3->text().trimmed(); - devXls[2].t = ui->lineEdit_t3->text().trimmed(); - devXls[2].ts= ui->lineEdit_I3->text().trimmed(); - devXls[2].I= ui->lineEdit_II3->text().trimmed(); - devXls[2].tt = ui->lineEdit_tt3->text().trimmed(); - - devXls[3].name= ui->lineEdit_CurName4->text().trimmed(); - devXls[3].CO= ui->comboBox_Co4->currentText().trimmed(); - devXls[3].VB= ui->lineEdit_Vb4->text().trimmed(); - devXls[3].VT= ui->lineEdit_Vt4->text().trimmed(); - devXls[3].t = ui->lineEdit_t4->text().trimmed(); - devXls[3].ts= ui->lineEdit_I4->text().trimmed(); - devXls[3].I= ui->lineEdit_II4->text().trimmed(); - devXls[3].tt = ui->lineEdit_tt4->text().trimmed(); - - devXls[4].name= ui->lineEdit_CurName5->text().trimmed(); - devXls[4].CO= ui->comboBox_Co5->currentText().trimmed(); - devXls[4].VB= ui->lineEdit_Vb5->text().trimmed(); - devXls[4].VT= ui->lineEdit_Vt5->text().trimmed(); - devXls[4].t = ui->lineEdit_t5->text().trimmed(); - devXls[4].ts= ui->lineEdit_I5->text().trimmed(); - devXls[4].I= ui->lineEdit_II5->text().trimmed(); - devXls[4].tt = ui->lineEdit_tt5->text().trimmed(); - - devXls[5].name= ui->lineEdit_CurName6->text().trimmed(); - devXls[5].CO= ui->comboBox_Co6->currentText().trimmed(); - devXls[5].VB= ui->lineEdit_Vb6->text().trimmed(); - devXls[5].VT= ui->lineEdit_Vt6->text().trimmed(); - devXls[5].t = ui->lineEdit_t6->text().trimmed(); - devXls[5].ts= ui->lineEdit_I6->text().trimmed(); - devXls[5].I= ui->lineEdit_II6->text().trimmed(); - devXls[5].tt = ui->lineEdit_tt6->text().trimmed(); - - return 0; -} - -int InverseTimeLimit::iniUiDevXls(const DeviceXlsVector &devXls) -{ - if(devXls.size() < 6) - { - return -1; - } - ui->lineEdit_CurName1->setText(devXls[0].name); - ui->comboBox_Co1->setCurrentText(devXls[0].CO); - - ui->lineEdit_Vb1->setText(devXls[0].VB ); - ui->lineEdit_Vt1->setText(devXls[0].VT ); - ui->lineEdit_t1->setText(devXls[0].t ); - ui->lineEdit_I1->setText(devXls[0].ts ); - ui->lineEdit_II1->setText(devXls[0].I ); - ui->lineEdit_tt1->setText(devXls[0].tt ); - - ui->lineEdit_CurName2->setText(devXls[1].name); - ui->comboBox_Co2->setItemText(0,devXls[1].CO); - ui->lineEdit_Vb2->setText(devXls[1].VB ); - ui->lineEdit_Vt2->setText(devXls[1].VT ); - ui->lineEdit_t2->setText(devXls[1].t ); - ui->lineEdit_I2->setText(devXls[1].ts ); - ui->lineEdit_II2->setText(devXls[1].I ); - ui->lineEdit_tt2->setText(devXls[1].tt ); - - ui->lineEdit_CurName3->setText(devXls[2].name); - ui->comboBox_Co3->setItemText(0,devXls[2].CO); - ui->lineEdit_Vb3->setText(devXls[2].VB ); - ui->lineEdit_Vt3->setText(devXls[2].VT ); - ui->lineEdit_t3->setText(devXls[2].t ); - ui->lineEdit_I3->setText(devXls[2].ts ); - ui->lineEdit_II3->setText(devXls[2].I ); - ui->lineEdit_tt3->setText(devXls[2].tt ); - - ui->lineEdit_CurName4->setText(devXls[3].name); - ui->comboBox_Co4->setItemText(0,devXls[3].CO); - ui->lineEdit_Vb4->setText(devXls[3].VB ); - ui->lineEdit_Vt4->setText(devXls[3].VT ); - ui->lineEdit_t4->setText(devXls[3].t ); - ui->lineEdit_I4->setText(devXls[3].ts ); - ui->lineEdit_II4->setText(devXls[3].I ); - ui->lineEdit_tt4->setText(devXls[3].tt ); - - ui->lineEdit_CurName5->setText(devXls[4].name); - ui->comboBox_Co5->setItemText(0,devXls[4].CO); - ui->lineEdit_Vb5->setText(devXls[4].VB ); - ui->lineEdit_Vt5->setText(devXls[4].VT ); - ui->lineEdit_t5->setText(devXls[4].t ); - ui->lineEdit_I5->setText(devXls[4].ts ); - ui->lineEdit_II5->setText(devXls[4].I ); - ui->lineEdit_tt5->setText(devXls[4].tt ); - - ui->lineEdit_CurName6->setText(devXls[5].name); - ui->comboBox_Co6->setItemText(0,devXls[5].CO); - ui->lineEdit_Vb6->setText(devXls[5].VB ); - ui->lineEdit_Vt6->setText(devXls[5].VT ); - ui->lineEdit_t6->setText(devXls[5].t ); - ui->lineEdit_I6->setText(devXls[5].ts ); - ui->lineEdit_II6->setText(devXls[5].I ); - ui->lineEdit_tt6->setText(devXls[5].tt ); - - return 0; -} - -void InverseTimeLimit::clearFile() -{ - QString fileNameHtml = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/" + "table.htm"; - QFile htmFile (fileNameHtml); - if( htmFile.exists() == true) - { - //删除之前文件 - htmFile.remove(); - } -} - -void InverseTimeLimit::setButtonEnable(bool bEnable) -{ - m_processDialog->reset(); - m_processDialog->setHidden(bEnable); - ui->pushButton->setEnabled(bEnable); - ui->pushButton_save->setEnabled(bEnable); - ui->pushButton_create->setEnabled(bEnable); -} - -void InverseTimeLimit::buildEngineView() -{ -#ifdef OS_WINDOWS - if(view == Q_NULLPTR) - { - view = new QWebEngineView(this); - QGridLayout *lay = new QGridLayout(); - lay->addWidget(view); - lay->setContentsMargins(0,0,0,0); - ui->widget->setLayout(lay); - view->show(); - } -#else -#endif -} - -void InverseTimeLimit::on_pushButton_clicked() -{ -#ifdef OS_WINDOWS - QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; - QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), - path, - tr("File (*.xlsx)")); - - if(fileName != "") - { - setButtonEnable(false); - ui->lineEdit->setText(fileName); - QString fileNameHtml = path + "table.htm"; - - clearFile(); - emit sigExcelToCsvFile(fileName, fileNameHtml, EN_OPEN); - } -#else -#endif - -} - -void InverseTimeLimit::on_pushButton_save_clicked() -{ -#ifdef OS_WINDOWS - QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; - QString fileName = ui->lineEdit->text().trimmed(); - QString fileNameHtml = QFileDialog::getSaveFileName(this, - tr("Open Config"), - path, - tr("Config Files (*.xlsx)")); - - if (fileNameHtml != "" && fileName!="") - { - setButtonEnable(false); - emit sigExcelToCsvFile(fileName, fileNameHtml, EN_SAVE); - } -#else -#endif -} - - -void InverseTimeLimit::on_pushButton_create_released() -{ -#ifdef OS_WINDOWS - QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; - QString fileName = ui->lineEdit->text().trimmed(); - - if(fileName !="") - { - setButtonEnable(false); - clearFile(); - - DeviceXlsVector devXls; - iniDevXls(devXls); - emit sigUpdateDevXls(devXls); - - QString fileNameHtml = path + "table.htm"; - emit sigExcelToCsvFile(fileName, fileNameHtml, EN_CREATE, devXls); - } -#else -#endif -} - -void InverseTimeLimit::slot_ExcelToCsvResult(bool bSuccess, const QString &csvFileName, const DeviceXlsVector &devXls, int flag) -{ - if(bSuccess == false) - { - setButtonEnable(true); - return; - } - if(flag == EN_OPEN) - { - iniUiDevXls(devXls); - } - if(flag != EN_SAVE) - { - buildEngineView(); - QTextCodec *code = QTextCodec::codecForName("gbk"); - view->load(QUrl(QString::fromLatin1(code->fromUnicode(csvFileName)))); - } - setButtonEnable(true); -} +#include "inversetimelimit.h" +#include "ui_inversetimelimit.h" +#include "CProcessDialog.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include +#include + +InverseTimeLimit::InverseTimeLimit(bool editMode, QWidget *parent) : + QWidget(parent), + ui(new Ui::InverseTimeLimit), + view(Q_NULLPTR), + m_pExcelOpt(Q_NULLPTR), + m_pExcelOptThread(Q_NULLPTR), + m_processDialog(Q_NULLPTR) +{ + ui->setupUi(this); + +#ifdef OS_WINDOWS + ui->label_49->setVisible(false); + if(!editMode) + { + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + + qRegisterMetaType("DeviceXlsVector"); + + m_processDialog = new CProcessDialog; + m_processDialog->hide(); + + m_pExcelOpt = new CExcelOpt; + m_pExcelOptThread = new QThread(this); + m_pExcelOpt->moveToThread(m_pExcelOptThread); + connect(m_pExcelOptThread, &QThread::finished, m_pExcelOptThread, &QThread::deleteLater); + connect(this, &InverseTimeLimit::releaseExcelOptThread, m_pExcelOpt, &CExcelOpt::release, Qt::BlockingQueuedConnection); + connect(this, &InverseTimeLimit::sigExcelToCsvFile, m_pExcelOpt, &CExcelOpt::slotExcelToCsvFile); + connect(this, &InverseTimeLimit::sigUpdateDevXls, m_pExcelOpt, &CExcelOpt::slotUpdateDevXls); + connect(m_pExcelOpt, &CExcelOpt::sigExcelToCsvResult, this, &InverseTimeLimit::slot_ExcelToCsvResult); + connect(m_pExcelOpt, &CExcelOpt::sigSetValue, m_processDialog, &CProcessDialog::slotSetValue); + m_pExcelOptThread->start(); + } +#else + ui->label_49->setVisible(true); +#endif + + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +InverseTimeLimit::~InverseTimeLimit() +{ + if(m_processDialog) + { + delete m_processDialog; + } + m_processDialog = Q_NULLPTR; + + if(m_pExcelOpt) + { + emit releaseExcelOptThread(); + m_pExcelOpt = Q_NULLPTR; + } + + if(m_pExcelOptThread) + { + m_pExcelOptThread->quit(); + m_pExcelOptThread->wait(); + } + m_pExcelOptThread = Q_NULLPTR; + + delete ui; +} + +int InverseTimeLimit::iniDevXls(DeviceXlsVector &devXls) +{ + devXls.resize(6); + devXls[0].name= ui->lineEdit_CurName1->text().trimmed(); + devXls[0].CO= ui->comboBox_Co1->currentText().trimmed(); + devXls[0].VB= ui->lineEdit_Vb1->text().trimmed(); + devXls[0].VT= ui->lineEdit_Vt1->text().trimmed(); + devXls[0].t = ui->lineEdit_t1->text().trimmed(); + devXls[0].ts= ui->lineEdit_I1->text().trimmed(); + devXls[0].I= ui->lineEdit_II1->text().trimmed(); + devXls[0].tt = ui->lineEdit_tt1->text().trimmed(); + + devXls[1].name= ui->lineEdit_CurName2->text().trimmed(); + devXls[1].CO= ui->comboBox_Co2->currentText().trimmed(); + devXls[1].VB= ui->lineEdit_Vb2->text().trimmed(); + devXls[1].VT= ui->lineEdit_Vt2->text().trimmed(); + devXls[1].t = ui->lineEdit_t2->text().trimmed(); + devXls[1].ts= ui->lineEdit_I2->text().trimmed(); + devXls[1].I= ui->lineEdit_II2->text().trimmed(); + devXls[1].tt = ui->lineEdit_tt2->text().trimmed(); + + devXls[2].name= ui->lineEdit_CurName3->text().trimmed(); + devXls[2].CO= ui->comboBox_Co3->currentText().trimmed(); + devXls[2].VB= ui->lineEdit_Vb3->text().trimmed(); + devXls[2].VT= ui->lineEdit_Vt3->text().trimmed(); + devXls[2].t = ui->lineEdit_t3->text().trimmed(); + devXls[2].ts= ui->lineEdit_I3->text().trimmed(); + devXls[2].I= ui->lineEdit_II3->text().trimmed(); + devXls[2].tt = ui->lineEdit_tt3->text().trimmed(); + + devXls[3].name= ui->lineEdit_CurName4->text().trimmed(); + devXls[3].CO= ui->comboBox_Co4->currentText().trimmed(); + devXls[3].VB= ui->lineEdit_Vb4->text().trimmed(); + devXls[3].VT= ui->lineEdit_Vt4->text().trimmed(); + devXls[3].t = ui->lineEdit_t4->text().trimmed(); + devXls[3].ts= ui->lineEdit_I4->text().trimmed(); + devXls[3].I= ui->lineEdit_II4->text().trimmed(); + devXls[3].tt = ui->lineEdit_tt4->text().trimmed(); + + devXls[4].name= ui->lineEdit_CurName5->text().trimmed(); + devXls[4].CO= ui->comboBox_Co5->currentText().trimmed(); + devXls[4].VB= ui->lineEdit_Vb5->text().trimmed(); + devXls[4].VT= ui->lineEdit_Vt5->text().trimmed(); + devXls[4].t = ui->lineEdit_t5->text().trimmed(); + devXls[4].ts= ui->lineEdit_I5->text().trimmed(); + devXls[4].I= ui->lineEdit_II5->text().trimmed(); + devXls[4].tt = ui->lineEdit_tt5->text().trimmed(); + + devXls[5].name= ui->lineEdit_CurName6->text().trimmed(); + devXls[5].CO= ui->comboBox_Co6->currentText().trimmed(); + devXls[5].VB= ui->lineEdit_Vb6->text().trimmed(); + devXls[5].VT= ui->lineEdit_Vt6->text().trimmed(); + devXls[5].t = ui->lineEdit_t6->text().trimmed(); + devXls[5].ts= ui->lineEdit_I6->text().trimmed(); + devXls[5].I= ui->lineEdit_II6->text().trimmed(); + devXls[5].tt = ui->lineEdit_tt6->text().trimmed(); + + return 0; +} + +int InverseTimeLimit::iniUiDevXls(const DeviceXlsVector &devXls) +{ + if(devXls.size() < 6) + { + return -1; + } + ui->lineEdit_CurName1->setText(devXls[0].name); + ui->comboBox_Co1->setCurrentText(devXls[0].CO); + + ui->lineEdit_Vb1->setText(devXls[0].VB ); + ui->lineEdit_Vt1->setText(devXls[0].VT ); + ui->lineEdit_t1->setText(devXls[0].t ); + ui->lineEdit_I1->setText(devXls[0].ts ); + ui->lineEdit_II1->setText(devXls[0].I ); + ui->lineEdit_tt1->setText(devXls[0].tt ); + + ui->lineEdit_CurName2->setText(devXls[1].name); + ui->comboBox_Co2->setItemText(0,devXls[1].CO); + ui->lineEdit_Vb2->setText(devXls[1].VB ); + ui->lineEdit_Vt2->setText(devXls[1].VT ); + ui->lineEdit_t2->setText(devXls[1].t ); + ui->lineEdit_I2->setText(devXls[1].ts ); + ui->lineEdit_II2->setText(devXls[1].I ); + ui->lineEdit_tt2->setText(devXls[1].tt ); + + ui->lineEdit_CurName3->setText(devXls[2].name); + ui->comboBox_Co3->setItemText(0,devXls[2].CO); + ui->lineEdit_Vb3->setText(devXls[2].VB ); + ui->lineEdit_Vt3->setText(devXls[2].VT ); + ui->lineEdit_t3->setText(devXls[2].t ); + ui->lineEdit_I3->setText(devXls[2].ts ); + ui->lineEdit_II3->setText(devXls[2].I ); + ui->lineEdit_tt3->setText(devXls[2].tt ); + + ui->lineEdit_CurName4->setText(devXls[3].name); + ui->comboBox_Co4->setItemText(0,devXls[3].CO); + ui->lineEdit_Vb4->setText(devXls[3].VB ); + ui->lineEdit_Vt4->setText(devXls[3].VT ); + ui->lineEdit_t4->setText(devXls[3].t ); + ui->lineEdit_I4->setText(devXls[3].ts ); + ui->lineEdit_II4->setText(devXls[3].I ); + ui->lineEdit_tt4->setText(devXls[3].tt ); + + ui->lineEdit_CurName5->setText(devXls[4].name); + ui->comboBox_Co5->setItemText(0,devXls[4].CO); + ui->lineEdit_Vb5->setText(devXls[4].VB ); + ui->lineEdit_Vt5->setText(devXls[4].VT ); + ui->lineEdit_t5->setText(devXls[4].t ); + ui->lineEdit_I5->setText(devXls[4].ts ); + ui->lineEdit_II5->setText(devXls[4].I ); + ui->lineEdit_tt5->setText(devXls[4].tt ); + + ui->lineEdit_CurName6->setText(devXls[5].name); + ui->comboBox_Co6->setItemText(0,devXls[5].CO); + ui->lineEdit_Vb6->setText(devXls[5].VB ); + ui->lineEdit_Vt6->setText(devXls[5].VT ); + ui->lineEdit_t6->setText(devXls[5].t ); + ui->lineEdit_I6->setText(devXls[5].ts ); + ui->lineEdit_II6->setText(devXls[5].I ); + ui->lineEdit_tt6->setText(devXls[5].tt ); + + return 0; +} + +void InverseTimeLimit::clearFile() +{ + QString fileNameHtml = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/" + "table.htm"; + QFile htmFile (fileNameHtml); + if( htmFile.exists() == true) + { + //删除之前文件 + htmFile.remove(); + } +} + +void InverseTimeLimit::setButtonEnable(bool bEnable) +{ + m_processDialog->reset(); + m_processDialog->setHidden(bEnable); + ui->pushButton->setEnabled(bEnable); + ui->pushButton_save->setEnabled(bEnable); + ui->pushButton_create->setEnabled(bEnable); +} + +void InverseTimeLimit::buildEngineView() +{ +#ifdef OS_WINDOWS + if(view == Q_NULLPTR) + { + view = new QWebEngineView(this); + QGridLayout *lay = new QGridLayout(); + lay->addWidget(view); + lay->setContentsMargins(0,0,0,0); + ui->widget->setLayout(lay); + view->show(); + } +#else +#endif +} + +void InverseTimeLimit::on_pushButton_clicked() +{ +#ifdef OS_WINDOWS + QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; + QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), + path, + tr("File (*.xlsx)")); + + if(fileName != "") + { + setButtonEnable(false); + ui->lineEdit->setText(fileName); + QString fileNameHtml = path + "table.htm"; + + clearFile(); + emit sigExcelToCsvFile(fileName, fileNameHtml, EN_OPEN); + } +#else +#endif + +} + +void InverseTimeLimit::on_pushButton_save_clicked() +{ +#ifdef OS_WINDOWS + QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; + QString fileName = ui->lineEdit->text().trimmed(); + QString fileNameHtml = QFileDialog::getSaveFileName(this, + tr("Open Config"), + path, + tr("Config Files (*.xlsx)")); + + if (fileNameHtml != "" && fileName!="") + { + setButtonEnable(false); + emit sigExcelToCsvFile(fileName, fileNameHtml, EN_SAVE); + } +#else +#endif +} + + +void InverseTimeLimit::on_pushButton_create_released() +{ +#ifdef OS_WINDOWS + QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; + QString fileName = ui->lineEdit->text().trimmed(); + + if(fileName !="") + { + setButtonEnable(false); + clearFile(); + + DeviceXlsVector devXls; + iniDevXls(devXls); + emit sigUpdateDevXls(devXls); + + QString fileNameHtml = path + "table.htm"; + emit sigExcelToCsvFile(fileName, fileNameHtml, EN_CREATE, devXls); + } +#else +#endif +} + +void InverseTimeLimit::slot_ExcelToCsvResult(bool bSuccess, const QString &csvFileName, const DeviceXlsVector &devXls, int flag) +{ + if(bSuccess == false) + { + setButtonEnable(true); + return; + } + if(flag == EN_OPEN) + { + iniUiDevXls(devXls); + } + if(flag != EN_SAVE) + { + buildEngineView(); + QTextCodec *code = QTextCodec::codecForName("gbk"); + view->load(QUrl(QString::fromLatin1(code->fromUnicode(csvFileName)))); + } + setButtonEnable(true); +} diff --git a/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.h b/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.h index cc5b88df..f457c3c4 100644 --- a/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.h +++ b/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.h @@ -1,53 +1,53 @@ -#ifndef INVERSETIMELIMIT_H -#define INVERSETIMELIMIT_H - -#include -#include -#include "CExcelOpt.h" - -namespace Ui { -class InverseTimeLimit; -} - -class CProcessDialog; -class InverseTimeLimit : public QWidget -{ - Q_OBJECT - -public: - explicit InverseTimeLimit(bool editMode, QWidget *parent = 0); - ~InverseTimeLimit(); - -signals: - void sigUpdateDevXls(const DeviceXlsVector &devXls); - - void sigExcelToCsvFile(const QString &excelFileName, const QString &csvFileName, int flag, const DeviceXlsVector &devXls = DeviceXlsVector()); - - void releaseExcelOptThread(); - -public slots: - void slot_ExcelToCsvResult(bool bSuccess, const QString &csvFileName, const DeviceXlsVector &devXls, int flag); - -private slots: - void on_pushButton_clicked(); - - void on_pushButton_save_clicked(); - - void on_pushButton_create_released(); - -private: - int iniUiDevXls(const DeviceXlsVector& devXls); - int iniDevXls(DeviceXlsVector &devXls); - void clearFile( ); - void setButtonEnable(bool bEnable); - void buildEngineView(); - -private: - Ui::InverseTimeLimit *ui; - QWebEngineView *view; - CExcelOpt * m_pExcelOpt; - QThread * m_pExcelOptThread; - CProcessDialog * m_processDialog; -}; - -#endif // INVERSETIMELIMIT_H +#ifndef INVERSETIMELIMIT_H +#define INVERSETIMELIMIT_H + +#include +#include +#include "CExcelOpt.h" + +namespace Ui { +class InverseTimeLimit; +} + +class CProcessDialog; +class InverseTimeLimit : public QWidget +{ + Q_OBJECT + +public: + explicit InverseTimeLimit(bool editMode, QWidget *parent = 0); + ~InverseTimeLimit(); + +signals: + void sigUpdateDevXls(const DeviceXlsVector &devXls); + + void sigExcelToCsvFile(const QString &excelFileName, const QString &csvFileName, int flag, const DeviceXlsVector &devXls = DeviceXlsVector()); + + void releaseExcelOptThread(); + +public slots: + void slot_ExcelToCsvResult(bool bSuccess, const QString &csvFileName, const DeviceXlsVector &devXls, int flag); + +private slots: + void on_pushButton_clicked(); + + void on_pushButton_save_clicked(); + + void on_pushButton_create_released(); + +private: + int iniUiDevXls(const DeviceXlsVector& devXls); + int iniDevXls(DeviceXlsVector &devXls); + void clearFile( ); + void setButtonEnable(bool bEnable); + void buildEngineView(); + +private: + Ui::InverseTimeLimit *ui; + QWebEngineView *view; + CExcelOpt * m_pExcelOpt; + QThread * m_pExcelOptThread; + CProcessDialog * m_processDialog; +}; + +#endif // INVERSETIMELIMIT_H diff --git a/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.ui b/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.ui index 1f607788..48ebf24f 100644 --- a/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.ui +++ b/product/src/gui/plugin/InverseTimeLimit/inversetimelimit.ui @@ -1,832 +1,832 @@ - - - InverseTimeLimit - - - - 0 - 0 - 1359 - 1130 - - - - InverseTimeLimit - - - - - - - - 420 - 30 - 561 - 141 - - - - - 26 - - - - false - - - 该功能只支持在windows系统运行 - - - false - - - - - - - - - 0 - 0 - - - - 曲线配置 - - - - - - - - 选择文件 - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 生成曲线 - - - - - - - 保存模板 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - true - - - - - 0 - 0 - 418 - 1016 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 设备1 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备2 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备3 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备4 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备5 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备6 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - - - - - - - - - - + + + InverseTimeLimit + + + + 0 + 0 + 1359 + 1130 + + + + InverseTimeLimit + + + + + + + + 420 + 30 + 561 + 141 + + + + + 26 + + + + false + + + 该功能只支持在windows系统运行 + + + false + + + + + + + + + 0 + 0 + + + + 曲线配置 + + + + + + + + 选择文件 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 生成曲线 + + + + + + + 保存模板 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + true + + + + + 0 + 0 + 418 + 1016 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 设备1 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备2 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备3 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备4 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备5 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备6 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/InverseTimeLimit/main.cpp b/product/src/gui/plugin/InverseTimeLimit/main.cpp index d6253634..97fd9ce6 100644 --- a/product/src/gui/plugin/InverseTimeLimit/main.cpp +++ b/product/src/gui/plugin/InverseTimeLimit/main.cpp @@ -1,11 +1,11 @@ -#include "inversetimelimit.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - InverseTimeLimit w(false); - w.show(); - - return a.exec(); -} +#include "inversetimelimit.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + InverseTimeLimit w(false); + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/InverseTimeLimit/mainwindow.cpp b/product/src/gui/plugin/InverseTimeLimit/mainwindow.cpp index 7febf6a0..9e752635 100644 --- a/product/src/gui/plugin/InverseTimeLimit/mainwindow.cpp +++ b/product/src/gui/plugin/InverseTimeLimit/mainwindow.cpp @@ -1,445 +1,445 @@ -#include "mainwindow.h" -#include "ui_mainwindow.h" -#include -#include -#include -#include -#include -#include -#include - - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow) -{ - ui->setupUi(this); - this->setWindowFlags(this->windowFlags() &~ Qt::WindowMaximizeButtonHint); - - view = new QWebEngineView(this); - - QGridLayout *lay = new QGridLayout(this); - lay->addWidget(view); - lay->setContentsMargins(0,0,0,0); - ui->widget->setLayout(lay); - view->show(); -} - -int MainWindow::iniDevXls() -{ - - devXls[0].name= ui->lineEdit_CurName1->text().trimmed(); - devXls[0].CO= ui->comboBox_Co1->currentText().trimmed(); - devXls[0].VB= ui->lineEdit_Vb1->text().trimmed(); - devXls[0].VT= ui->lineEdit_Vt1->text().trimmed(); - devXls[0].t = ui->lineEdit_t1->text().trimmed(); - devXls[0].ts= ui->lineEdit_I1->text().trimmed(); - devXls[0].I= ui->lineEdit_II1->text().trimmed(); - devXls[0].tt = ui->lineEdit_tt1->text().trimmed(); - - devXls[1].name= ui->lineEdit_CurName2->text().trimmed(); - devXls[1].CO= ui->comboBox_Co2->currentText().trimmed(); - devXls[1].VB= ui->lineEdit_Vb2->text().trimmed(); - devXls[1].VT= ui->lineEdit_Vt2->text().trimmed(); - devXls[1].t = ui->lineEdit_t2->text().trimmed(); - devXls[1].ts= ui->lineEdit_I2->text().trimmed(); - devXls[1].I= ui->lineEdit_II2->text().trimmed(); - devXls[1].tt = ui->lineEdit_tt2->text().trimmed(); - - devXls[2].name= ui->lineEdit_CurName3->text().trimmed(); - devXls[2].CO= ui->comboBox_Co3->currentText().trimmed(); - devXls[2].VB= ui->lineEdit_Vb3->text().trimmed(); - devXls[2].VT= ui->lineEdit_Vt3->text().trimmed(); - devXls[2].t = ui->lineEdit_t3->text().trimmed(); - devXls[2].ts= ui->lineEdit_I3->text().trimmed(); - devXls[2].I= ui->lineEdit_II3->text().trimmed(); - devXls[2].tt = ui->lineEdit_tt3->text().trimmed(); - - devXls[3].name= ui->lineEdit_CurName4->text().trimmed(); - devXls[3].CO= ui->comboBox_Co4->currentText().trimmed(); - devXls[3].VB= ui->lineEdit_Vb4->text().trimmed(); - devXls[3].VT= ui->lineEdit_Vt4->text().trimmed(); - devXls[3].t = ui->lineEdit_t4->text().trimmed(); - devXls[3].ts= ui->lineEdit_I4->text().trimmed(); - devXls[3].I= ui->lineEdit_II4->text().trimmed(); - devXls[3].tt = ui->lineEdit_tt4->text().trimmed(); - - devXls[4].name= ui->lineEdit_CurName5->text().trimmed(); - devXls[4].CO= ui->comboBox_Co5->currentText().trimmed(); - devXls[4].VB= ui->lineEdit_Vb5->text().trimmed(); - devXls[4].VT= ui->lineEdit_Vt5->text().trimmed(); - devXls[4].t = ui->lineEdit_t5->text().trimmed(); - devXls[4].ts= ui->lineEdit_I5->text().trimmed(); - devXls[4].I= ui->lineEdit_II5->text().trimmed(); - devXls[4].tt = ui->lineEdit_tt5->text().trimmed(); - - devXls[5].name= ui->lineEdit_CurName6->text().trimmed(); - devXls[5].CO= ui->comboBox_Co6->currentText().trimmed(); - devXls[5].VB= ui->lineEdit_Vb6->text().trimmed(); - devXls[5].VT= ui->lineEdit_Vt6->text().trimmed(); - devXls[5].t = ui->lineEdit_t6->text().trimmed(); - devXls[5].ts= ui->lineEdit_I6->text().trimmed(); - devXls[5].I= ui->lineEdit_II6->text().trimmed(); - devXls[5].tt = ui->lineEdit_tt6->text().trimmed(); - - return 0; -} - -int MainWindow::iniDevXls2() -{ - ui->lineEdit_CurName1->setText(devXls[0].name); - ui->comboBox_Co1->setCurrentText(devXls[0].CO); - - ui->lineEdit_Vb1->setText(devXls[0].VB ); - ui->lineEdit_Vt1->setText(devXls[0].VT ); - ui->lineEdit_t1->setText(devXls[0].t ); - ui->lineEdit_I1->setText(devXls[0].ts ); - ui->lineEdit_II1->setText(devXls[0].I ); - ui->lineEdit_tt1->setText(devXls[0].tt ); - - ui->lineEdit_CurName2->setText(devXls[1].name); - ui->comboBox_Co2->setItemText(0,devXls[1].CO); - ui->lineEdit_Vb2->setText(devXls[1].VB ); - ui->lineEdit_Vt2->setText(devXls[1].VT ); - ui->lineEdit_t2->setText(devXls[1].t ); - ui->lineEdit_I2->setText(devXls[1].ts ); - ui->lineEdit_II2->setText(devXls[1].I ); - ui->lineEdit_tt2->setText(devXls[1].tt ); - - ui->lineEdit_CurName3->setText(devXls[2].name); - ui->comboBox_Co3->setItemText(0,devXls[2].CO); - ui->lineEdit_Vb3->setText(devXls[2].VB ); - ui->lineEdit_Vt3->setText(devXls[2].VT ); - ui->lineEdit_t3->setText(devXls[2].t ); - ui->lineEdit_I3->setText(devXls[2].ts ); - ui->lineEdit_II3->setText(devXls[2].I ); - ui->lineEdit_tt3->setText(devXls[2].tt ); - - ui->lineEdit_CurName4->setText(devXls[3].name); - ui->comboBox_Co4->setItemText(0,devXls[3].CO); - ui->lineEdit_Vb4->setText(devXls[3].VB ); - ui->lineEdit_Vt4->setText(devXls[3].VT ); - ui->lineEdit_t4->setText(devXls[3].t ); - ui->lineEdit_I4->setText(devXls[3].ts ); - ui->lineEdit_II4->setText(devXls[3].I ); - ui->lineEdit_tt4->setText(devXls[3].tt ); - - ui->lineEdit_CurName5->setText(devXls[4].name); - ui->comboBox_Co5->setItemText(0,devXls[4].CO); - ui->lineEdit_Vb5->setText(devXls[4].VB ); - ui->lineEdit_Vt5->setText(devXls[4].VT ); - ui->lineEdit_t5->setText(devXls[4].t ); - ui->lineEdit_I5->setText(devXls[4].ts ); - ui->lineEdit_II5->setText(devXls[4].I ); - ui->lineEdit_tt5->setText(devXls[4].tt ); - - ui->lineEdit_CurName6->setText(devXls[5].name); - ui->comboBox_Co6->setItemText(0,devXls[5].CO); - ui->lineEdit_Vb6->setText(devXls[5].VB ); - ui->lineEdit_Vt6->setText(devXls[5].VT ); - ui->lineEdit_t6->setText(devXls[5].t ); - ui->lineEdit_I6->setText(devXls[5].ts ); - ui->lineEdit_II6->setText(devXls[5].I ); - ui->lineEdit_tt6->setText(devXls[5].tt ); - - return 0; -} - -bool MainWindow::ExcelToCsvFile(const QString &excelFileName, const QString &csvFileName,int flag) -{ - if (!QFile::exists(excelFileName)) - return false; - - // 当pApplication析构的时候会将其所有相关的子对象都清理 - QScopedPointer pApplication(new QAxObject()); - - // 设置连接Excel控件,需要在GUI的环境下才能成功 - bool ok = pApplication->setControl("Excel.Application"); - if (!ok) - return false; - - pApplication->dynamicCall("SetVisible(bool)", false); // false表示不显示窗体 - pApplication->setProperty("DisplayAlerts", false); // false表示不显示(输出)任何警告信息。 - QAxObject *pWorkBooks = pApplication->querySubObject("Workbooks"); // Excel工作薄(对象) - if (pWorkBooks == 0) - return false; - - QAxObject *pWorkBook = pWorkBooks->querySubObject("Open(const QString &)", excelFileName); // 打开一个Excel文件 - if (pWorkBook == 0) - return false; - - QAxObject *pSheets = pWorkBook->querySubObject("WorkSheets"); // Excel工作表集 - if (pSheets == 0) - return false; - - int sheet_count = pSheets->property("Count").toInt(); //获取工作表数目 - - if(sheet_count > 0) - { - QAxObject *work_sheet = pSheets->querySubObject("Item(int)", 4); // 得到指定索引的工作表 - if (work_sheet == 0) - return false; - - // QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", 1); - QAxObject *used_range = work_sheet->querySubObject("UsedRange"); - QAxObject *rows = used_range->querySubObject("Rows"); - QAxObject *columns = used_range->querySubObject("Columns"); - int row_start = used_range->property("Row").toInt(); //获取起始行:1 - int column_start = used_range->property("Column").toInt(); //获取起始列 - int lNumRows = rows->property("Count").toInt(); //获取行数 - int lNumCols = columns->property("Count").toInt(); //获取列数 - - int r, c; - for(r=1;r<=lNumRows;r++) - { - for(c=1;c<=lNumCols;c++) - { - if(flag ==0) - { - - - for (int xx=0;xx<6;xx++) - { - if (r== (5 + (xx*7))) - { - char S='S'-'A' + 1; - char U='U'-'A' + 1; - char V='V'-'A' + 1; - - if (c==S) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - devXls[xx].name =val; - } - - if (c==U) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - devXls[xx].VB =val; - } - - if (c==V) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - devXls[xx].VT=val; - } - } - - if (r== (7 + (xx*7))) - { - char S='S'-'A' + 1; - char T='T'-'A' + 1; - char V='V'-'A' + 1; - char W='W'-'A' + 1; - char X='X'-'A' + 1; - if (c==S) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - devXls[xx].CO=val; - } - - if (c==T) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - devXls[xx].t=val; - } - - if (c==V) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - devXls[xx].ts=val; - } - - if (c==W) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - devXls[xx].I=val; - } - - if (c==X) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 - devXls[xx].tt=val; - } - } - } - }else - { - - - for (int xx=0;xx<6;xx++) - { - if (r== (5 + (xx*7))) - { - char S='S'-'A' + 1; - char U='U'-'A' + 1; - char V='V'-'A' + 1; - - if (c==S) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", devXls[xx].name); - } - - if (c==U) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", devXls[xx].VB); - - } - - if (c==V) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", devXls[xx].VT); - } - } - - if (r== (7 + (xx*7))) - { - char S='S'-'A' + 1; - char T='T'-'A' + 1; - char V='V'-'A' + 1; - char W='W'-'A' + 1; - char X='X'-'A' + 1; - if (c==S) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", devXls[xx].CO); - } - - if (c==T) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", devXls[xx].t); - - } - - if (c==V) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", devXls[xx].ts); - } - - if (c==W) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", devXls[xx].I); - } - - if (c==X) - { - QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); - cell->setProperty("Value2", devXls[xx].tt); - - } - } - } - - } - } - } - } - - QAxObject *pSheet5 = pSheets->querySubObject("Item(int)", 5); // 得到指定索引的工作表 - - - // 另存为文件, 3: txt文件(空格分隔)| 6: csv文件(逗号分隔) - int saveType=44; - if(flag ==2) - { - pSheet5->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(csvFileName)); - }else - { - pSheet5->dynamicCall("SaveAs(const QString&, int)", QDir::toNativeSeparators(csvFileName), saveType); - } - // pWorkBooks->dynamicCall("SaveAs(const QString&, int)", QDir::toNativeSeparators(csvFileName), 44); - pWorkBooks->dynamicCall("Close()");//关闭工作簿 - pApplication->dynamicCall("Quit()"); - - QTextCodec *code = QTextCodec::codecForName("gbk"); - view->load(QUrl(QString::fromLatin1(code->fromUnicode(csvFileName)) )); - return true; -} - - - -MainWindow::~MainWindow() -{ - delete ui; -} - -void MainWindow::Update() -{ - -} - -void MainWindow::on_pushButton_clicked() -{ - - QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; - QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), - path, - tr("File (*.xlsx)")); - - if(fileName !="") - { - ui->lineEdit->setText(fileName); - QString fileNameHtml = path + "table.htm"; - - clearFile(); - ExcelToCsvFile(fileName,fileNameHtml,0); - iniDevXls2(); - } - -} -void MainWindow::clearFile() -{ - QString fileNameHtml = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/" + "table.htm"; - QFile htmFile (fileNameHtml); - if( htmFile.exists() == true) - { - //删除之前文件 - htmFile.remove(); - } -} - -void MainWindow::on_pushButton_create_clicked() -{ - QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; - QString fileName = ui->lineEdit->text().trimmed(); - - if(fileName !="") - { - clearFile(); - iniDevXls(); - QString fileNameHtml = path + "table.htm"; - ExcelToCsvFile(fileName,fileNameHtml,1); - - } -} - -void MainWindow::on_pushButton_save_clicked() -{ - QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; - QString fileName = ui->lineEdit->text().trimmed(); - QString fileNameHtml = QFileDialog::getSaveFileName(this, - tr("Open Config"), - path, - tr("Config Files (*.xlsx)")); - - if (fileNameHtml != "" && fileName!="" ) - { - ExcelToCsvFile(fileName,fileNameHtml,2); - } - - -} +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include +#include +#include +#include +#include +#include +#include + + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + this->setWindowFlags(this->windowFlags() &~ Qt::WindowMaximizeButtonHint); + + view = new QWebEngineView(this); + + QGridLayout *lay = new QGridLayout(this); + lay->addWidget(view); + lay->setContentsMargins(0,0,0,0); + ui->widget->setLayout(lay); + view->show(); +} + +int MainWindow::iniDevXls() +{ + + devXls[0].name= ui->lineEdit_CurName1->text().trimmed(); + devXls[0].CO= ui->comboBox_Co1->currentText().trimmed(); + devXls[0].VB= ui->lineEdit_Vb1->text().trimmed(); + devXls[0].VT= ui->lineEdit_Vt1->text().trimmed(); + devXls[0].t = ui->lineEdit_t1->text().trimmed(); + devXls[0].ts= ui->lineEdit_I1->text().trimmed(); + devXls[0].I= ui->lineEdit_II1->text().trimmed(); + devXls[0].tt = ui->lineEdit_tt1->text().trimmed(); + + devXls[1].name= ui->lineEdit_CurName2->text().trimmed(); + devXls[1].CO= ui->comboBox_Co2->currentText().trimmed(); + devXls[1].VB= ui->lineEdit_Vb2->text().trimmed(); + devXls[1].VT= ui->lineEdit_Vt2->text().trimmed(); + devXls[1].t = ui->lineEdit_t2->text().trimmed(); + devXls[1].ts= ui->lineEdit_I2->text().trimmed(); + devXls[1].I= ui->lineEdit_II2->text().trimmed(); + devXls[1].tt = ui->lineEdit_tt2->text().trimmed(); + + devXls[2].name= ui->lineEdit_CurName3->text().trimmed(); + devXls[2].CO= ui->comboBox_Co3->currentText().trimmed(); + devXls[2].VB= ui->lineEdit_Vb3->text().trimmed(); + devXls[2].VT= ui->lineEdit_Vt3->text().trimmed(); + devXls[2].t = ui->lineEdit_t3->text().trimmed(); + devXls[2].ts= ui->lineEdit_I3->text().trimmed(); + devXls[2].I= ui->lineEdit_II3->text().trimmed(); + devXls[2].tt = ui->lineEdit_tt3->text().trimmed(); + + devXls[3].name= ui->lineEdit_CurName4->text().trimmed(); + devXls[3].CO= ui->comboBox_Co4->currentText().trimmed(); + devXls[3].VB= ui->lineEdit_Vb4->text().trimmed(); + devXls[3].VT= ui->lineEdit_Vt4->text().trimmed(); + devXls[3].t = ui->lineEdit_t4->text().trimmed(); + devXls[3].ts= ui->lineEdit_I4->text().trimmed(); + devXls[3].I= ui->lineEdit_II4->text().trimmed(); + devXls[3].tt = ui->lineEdit_tt4->text().trimmed(); + + devXls[4].name= ui->lineEdit_CurName5->text().trimmed(); + devXls[4].CO= ui->comboBox_Co5->currentText().trimmed(); + devXls[4].VB= ui->lineEdit_Vb5->text().trimmed(); + devXls[4].VT= ui->lineEdit_Vt5->text().trimmed(); + devXls[4].t = ui->lineEdit_t5->text().trimmed(); + devXls[4].ts= ui->lineEdit_I5->text().trimmed(); + devXls[4].I= ui->lineEdit_II5->text().trimmed(); + devXls[4].tt = ui->lineEdit_tt5->text().trimmed(); + + devXls[5].name= ui->lineEdit_CurName6->text().trimmed(); + devXls[5].CO= ui->comboBox_Co6->currentText().trimmed(); + devXls[5].VB= ui->lineEdit_Vb6->text().trimmed(); + devXls[5].VT= ui->lineEdit_Vt6->text().trimmed(); + devXls[5].t = ui->lineEdit_t6->text().trimmed(); + devXls[5].ts= ui->lineEdit_I6->text().trimmed(); + devXls[5].I= ui->lineEdit_II6->text().trimmed(); + devXls[5].tt = ui->lineEdit_tt6->text().trimmed(); + + return 0; +} + +int MainWindow::iniDevXls2() +{ + ui->lineEdit_CurName1->setText(devXls[0].name); + ui->comboBox_Co1->setCurrentText(devXls[0].CO); + + ui->lineEdit_Vb1->setText(devXls[0].VB ); + ui->lineEdit_Vt1->setText(devXls[0].VT ); + ui->lineEdit_t1->setText(devXls[0].t ); + ui->lineEdit_I1->setText(devXls[0].ts ); + ui->lineEdit_II1->setText(devXls[0].I ); + ui->lineEdit_tt1->setText(devXls[0].tt ); + + ui->lineEdit_CurName2->setText(devXls[1].name); + ui->comboBox_Co2->setItemText(0,devXls[1].CO); + ui->lineEdit_Vb2->setText(devXls[1].VB ); + ui->lineEdit_Vt2->setText(devXls[1].VT ); + ui->lineEdit_t2->setText(devXls[1].t ); + ui->lineEdit_I2->setText(devXls[1].ts ); + ui->lineEdit_II2->setText(devXls[1].I ); + ui->lineEdit_tt2->setText(devXls[1].tt ); + + ui->lineEdit_CurName3->setText(devXls[2].name); + ui->comboBox_Co3->setItemText(0,devXls[2].CO); + ui->lineEdit_Vb3->setText(devXls[2].VB ); + ui->lineEdit_Vt3->setText(devXls[2].VT ); + ui->lineEdit_t3->setText(devXls[2].t ); + ui->lineEdit_I3->setText(devXls[2].ts ); + ui->lineEdit_II3->setText(devXls[2].I ); + ui->lineEdit_tt3->setText(devXls[2].tt ); + + ui->lineEdit_CurName4->setText(devXls[3].name); + ui->comboBox_Co4->setItemText(0,devXls[3].CO); + ui->lineEdit_Vb4->setText(devXls[3].VB ); + ui->lineEdit_Vt4->setText(devXls[3].VT ); + ui->lineEdit_t4->setText(devXls[3].t ); + ui->lineEdit_I4->setText(devXls[3].ts ); + ui->lineEdit_II4->setText(devXls[3].I ); + ui->lineEdit_tt4->setText(devXls[3].tt ); + + ui->lineEdit_CurName5->setText(devXls[4].name); + ui->comboBox_Co5->setItemText(0,devXls[4].CO); + ui->lineEdit_Vb5->setText(devXls[4].VB ); + ui->lineEdit_Vt5->setText(devXls[4].VT ); + ui->lineEdit_t5->setText(devXls[4].t ); + ui->lineEdit_I5->setText(devXls[4].ts ); + ui->lineEdit_II5->setText(devXls[4].I ); + ui->lineEdit_tt5->setText(devXls[4].tt ); + + ui->lineEdit_CurName6->setText(devXls[5].name); + ui->comboBox_Co6->setItemText(0,devXls[5].CO); + ui->lineEdit_Vb6->setText(devXls[5].VB ); + ui->lineEdit_Vt6->setText(devXls[5].VT ); + ui->lineEdit_t6->setText(devXls[5].t ); + ui->lineEdit_I6->setText(devXls[5].ts ); + ui->lineEdit_II6->setText(devXls[5].I ); + ui->lineEdit_tt6->setText(devXls[5].tt ); + + return 0; +} + +bool MainWindow::ExcelToCsvFile(const QString &excelFileName, const QString &csvFileName,int flag) +{ + if (!QFile::exists(excelFileName)) + return false; + + // 当pApplication析构的时候会将其所有相关的子对象都清理 + QScopedPointer pApplication(new QAxObject()); + + // 设置连接Excel控件,需要在GUI的环境下才能成功 + bool ok = pApplication->setControl("Excel.Application"); + if (!ok) + return false; + + pApplication->dynamicCall("SetVisible(bool)", false); // false表示不显示窗体 + pApplication->setProperty("DisplayAlerts", false); // false表示不显示(输出)任何警告信息。 + QAxObject *pWorkBooks = pApplication->querySubObject("Workbooks"); // Excel工作薄(对象) + if (pWorkBooks == 0) + return false; + + QAxObject *pWorkBook = pWorkBooks->querySubObject("Open(const QString &)", excelFileName); // 打开一个Excel文件 + if (pWorkBook == 0) + return false; + + QAxObject *pSheets = pWorkBook->querySubObject("WorkSheets"); // Excel工作表集 + if (pSheets == 0) + return false; + + int sheet_count = pSheets->property("Count").toInt(); //获取工作表数目 + + if(sheet_count > 0) + { + QAxObject *work_sheet = pSheets->querySubObject("Item(int)", 4); // 得到指定索引的工作表 + if (work_sheet == 0) + return false; + + // QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", 1); + QAxObject *used_range = work_sheet->querySubObject("UsedRange"); + QAxObject *rows = used_range->querySubObject("Rows"); + QAxObject *columns = used_range->querySubObject("Columns"); + int row_start = used_range->property("Row").toInt(); //获取起始行:1 + int column_start = used_range->property("Column").toInt(); //获取起始列 + int lNumRows = rows->property("Count").toInt(); //获取行数 + int lNumCols = columns->property("Count").toInt(); //获取列数 + + int r, c; + for(r=1;r<=lNumRows;r++) + { + for(c=1;c<=lNumCols;c++) + { + if(flag ==0) + { + + + for (int xx=0;xx<6;xx++) + { + if (r== (5 + (xx*7))) + { + char S='S'-'A' + 1; + char U='U'-'A' + 1; + char V='V'-'A' + 1; + + if (c==S) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + devXls[xx].name =val; + } + + if (c==U) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + devXls[xx].VB =val; + } + + if (c==V) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + devXls[xx].VT=val; + } + } + + if (r== (7 + (xx*7))) + { + char S='S'-'A' + 1; + char T='T'-'A' + 1; + char V='V'-'A' + 1; + char W='W'-'A' + 1; + char X='X'-'A' + 1; + if (c==S) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + devXls[xx].CO=val; + } + + if (c==T) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + devXls[xx].t=val; + } + + if (c==V) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + devXls[xx].ts=val; + } + + if (c==W) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + devXls[xx].I=val; + } + + if (c==X) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + QString val = cell->dynamicCall("Value2()").toString();//获取单元格内容 + devXls[xx].tt=val; + } + } + } + }else + { + + + for (int xx=0;xx<6;xx++) + { + if (r== (5 + (xx*7))) + { + char S='S'-'A' + 1; + char U='U'-'A' + 1; + char V='V'-'A' + 1; + + if (c==S) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", devXls[xx].name); + } + + if (c==U) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", devXls[xx].VB); + + } + + if (c==V) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", devXls[xx].VT); + } + } + + if (r== (7 + (xx*7))) + { + char S='S'-'A' + 1; + char T='T'-'A' + 1; + char V='V'-'A' + 1; + char W='W'-'A' + 1; + char X='X'-'A' + 1; + if (c==S) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", devXls[xx].CO); + } + + if (c==T) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", devXls[xx].t); + + } + + if (c==V) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", devXls[xx].ts); + } + + if (c==W) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", devXls[xx].I); + } + + if (c==X) + { + QAxObject *cell = work_sheet->querySubObject("Cells(int,int)", r, c); + cell->setProperty("Value2", devXls[xx].tt); + + } + } + } + + } + } + } + } + + QAxObject *pSheet5 = pSheets->querySubObject("Item(int)", 5); // 得到指定索引的工作表 + + + // 另存为文件, 3: txt文件(空格分隔)| 6: csv文件(逗号分隔) + int saveType=44; + if(flag ==2) + { + pSheet5->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(csvFileName)); + }else + { + pSheet5->dynamicCall("SaveAs(const QString&, int)", QDir::toNativeSeparators(csvFileName), saveType); + } + // pWorkBooks->dynamicCall("SaveAs(const QString&, int)", QDir::toNativeSeparators(csvFileName), 44); + pWorkBooks->dynamicCall("Close()");//关闭工作簿 + pApplication->dynamicCall("Quit()"); + + QTextCodec *code = QTextCodec::codecForName("gbk"); + view->load(QUrl(QString::fromLatin1(code->fromUnicode(csvFileName)) )); + return true; +} + + + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::Update() +{ + +} + +void MainWindow::on_pushButton_clicked() +{ + + QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; + QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), + path, + tr("File (*.xlsx)")); + + if(fileName !="") + { + ui->lineEdit->setText(fileName); + QString fileNameHtml = path + "table.htm"; + + clearFile(); + ExcelToCsvFile(fileName,fileNameHtml,0); + iniDevXls2(); + } + +} +void MainWindow::clearFile() +{ + QString fileNameHtml = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/" + "table.htm"; + QFile htmFile (fileNameHtml); + if( htmFile.exists() == true) + { + //删除之前文件 + htmFile.remove(); + } +} + +void MainWindow::on_pushButton_create_clicked() +{ + QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; + QString fileName = ui->lineEdit->text().trimmed(); + + if(fileName !="") + { + clearFile(); + iniDevXls(); + QString fileNameHtml = path + "table.htm"; + ExcelToCsvFile(fileName,fileNameHtml,1); + + } +} + +void MainWindow::on_pushButton_save_clicked() +{ + QString path = QApplication::applicationDirPath()+"/../../data/InverseTimeLimit/"; + QString fileName = ui->lineEdit->text().trimmed(); + QString fileNameHtml = QFileDialog::getSaveFileName(this, + tr("Open Config"), + path, + tr("Config Files (*.xlsx)")); + + if (fileNameHtml != "" && fileName!="" ) + { + ExcelToCsvFile(fileName,fileNameHtml,2); + } + + +} diff --git a/product/src/gui/plugin/InverseTimeLimit/mainwindow.h b/product/src/gui/plugin/InverseTimeLimit/mainwindow.h index 9fb665c4..5033a8f3 100644 --- a/product/src/gui/plugin/InverseTimeLimit/mainwindow.h +++ b/product/src/gui/plugin/InverseTimeLimit/mainwindow.h @@ -1,47 +1,47 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "para.h" - -namespace Ui { -class MainWindow; -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - -private slots: - void on_pushButton_clicked(); - - void on_pushButton_create_clicked(); - - void on_pushButton_save_clicked(); - -private: - Ui::MainWindow *ui; - QWebEngineView *view; - - - bool ExcelToCsvFile(const QString &excelFileName, const QString &csvFileName,int flag); - - int iniDevXls2(); - int iniDevXls(); - void Update(); - void clearFile( ); - DeviceXls devXls[6]; -}; - -#endif // MAINWINDOW_H +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "para.h" + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private slots: + void on_pushButton_clicked(); + + void on_pushButton_create_clicked(); + + void on_pushButton_save_clicked(); + +private: + Ui::MainWindow *ui; + QWebEngineView *view; + + + bool ExcelToCsvFile(const QString &excelFileName, const QString &csvFileName,int flag); + + int iniDevXls2(); + int iniDevXls(); + void Update(); + void clearFile( ); + DeviceXls devXls[6]; +}; + +#endif // MAINWINDOW_H diff --git a/product/src/gui/plugin/InverseTimeLimit/mainwindow.ui b/product/src/gui/plugin/InverseTimeLimit/mainwindow.ui index ef4f5e10..6a124c4d 100644 --- a/product/src/gui/plugin/InverseTimeLimit/mainwindow.ui +++ b/product/src/gui/plugin/InverseTimeLimit/mainwindow.ui @@ -1,761 +1,761 @@ - - - MainWindow - - - - 0 - 0 - 1232 - 895 - - - - 协调曲线 - - - - - - - - 0 - 0 - - - - - 300 - 16777215 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 选择文件 - - - - - - - - - - - - - - 生成曲线 - - - - - - - 保存模板 - - - - - - - - - 设备1 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备2 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备3 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备4 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备5 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - 设备6 - - - - 2 - - - - - 曲线名称 - - - - - - - - - - CO曲线 - - - - - - - - EIT - - - - - SIT - - - - - VIT - - - - - UIT - - - - - - - - Vb(基准) - - - - - - - - - - Vt(换算) - - - - - - - - - - I> - - - - - - - - - - t> - - - - - - - - - - I>> - - - - - - - - - - t>> - - - - - - - - - - - - - - - - - - - - - - + + + MainWindow + + + + 0 + 0 + 1232 + 895 + + + + 协调曲线 + + + + + + + + 0 + 0 + + + + + 300 + 16777215 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 选择文件 + + + + + + + + + + + + + + 生成曲线 + + + + + + + 保存模板 + + + + + + + + + 设备1 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备2 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备3 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备4 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备5 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + 设备6 + + + + 2 + + + + + 曲线名称 + + + + + + + + + + CO曲线 + + + + + + + + EIT + + + + + SIT + + + + + VIT + + + + + UIT + + + + + + + + Vb(基准) + + + + + + + + + + Vt(换算) + + + + + + + + + + I> + + + + + + + + + + t> + + + + + + + + + + I>> + + + + + + + + + + t>> + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/InverseTimeLimit/para.h b/product/src/gui/plugin/InverseTimeLimit/para.h index 297cda18..ac6ffc82 100644 --- a/product/src/gui/plugin/InverseTimeLimit/para.h +++ b/product/src/gui/plugin/InverseTimeLimit/para.h @@ -1,36 +1,36 @@ -#ifndef PARA_H -#define PARA_H -#include -#include - -struct DeviceXls -{ - QString name; - QString CO; - QString VB; - QString VT; - QString t; - QString ts; - QString I; - QString tt; -}; - -struct SAVE_FORMULA -{ - int sheetno; - int row; - int col; - QString formula; -}; - -typedef QVector DeviceXlsVector; - - -enum EN_OPTFLAG -{ - EN_OPEN = 0, - EN_CREATE, - EN_SAVE -}; - -#endif // PARA_H +#ifndef PARA_H +#define PARA_H +#include +#include + +struct DeviceXls +{ + QString name; + QString CO; + QString VB; + QString VT; + QString t; + QString ts; + QString I; + QString tt; +}; + +struct SAVE_FORMULA +{ + int sheetno; + int row; + int col; + QString formula; +}; + +typedef QVector DeviceXlsVector; + + +enum EN_OPTFLAG +{ + EN_OPEN = 0, + EN_CREATE, + EN_SAVE +}; + +#endif // PARA_H diff --git a/product/src/gui/plugin/InverseTimeLimit/ui_mainwindow.h b/product/src/gui/plugin/InverseTimeLimit/ui_mainwindow.h index 684f8412..7ceea76c 100644 --- a/product/src/gui/plugin/InverseTimeLimit/ui_mainwindow.h +++ b/product/src/gui/plugin/InverseTimeLimit/ui_mainwindow.h @@ -1,877 +1,877 @@ -/******************************************************************************** -** Form generated from reading UI file 'mainwindow.ui' -** -** Created by: Qt User Interface Compiler version 5.9.2 -** -** WARNING! All changes made in this file will be lost when recompiling UI file! -********************************************************************************/ - -#ifndef UI_MAINWINDOW_H -#define UI_MAINWINDOW_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class Ui_MainWindow -{ -public: - QWidget *centralWidget; - QGridLayout *gridLayout_3; - QFrame *frame; - QGridLayout *gridLayout_8; - QHBoxLayout *horizontalLayout; - QPushButton *pushButton; - QLineEdit *lineEdit; - QHBoxLayout *horizontalLayout_2; - QPushButton *pushButton_create; - QPushButton *pushButton_save; - QGroupBox *groupBox; - QGridLayout *gridLayout; - QLabel *label; - QLineEdit *lineEdit_CurName1; - QLabel *label_2; - QComboBox *comboBox_Co1; - QLabel *label_3; - QLineEdit *lineEdit_Vb1; - QLabel *label_4; - QLineEdit *lineEdit_Vt1; - QLabel *label_5; - QLineEdit *lineEdit_I1; - QLabel *label_6; - QLineEdit *lineEdit_t1; - QLabel *label_7; - QLineEdit *lineEdit_II1; - QLabel *label_8; - QLineEdit *lineEdit_tt1; - QGroupBox *groupBox_2; - QGridLayout *gridLayout_2; - QLabel *label_9; - QLineEdit *lineEdit_CurName2; - QLabel *label_10; - QComboBox *comboBox_Co2; - QLabel *label_11; - QLineEdit *lineEdit_Vb2; - QLabel *label_12; - QLineEdit *lineEdit_Vt2; - QLabel *label_13; - QLineEdit *lineEdit_I2; - QLabel *label_14; - QLineEdit *lineEdit_t2; - QLabel *label_15; - QLineEdit *lineEdit_II2; - QLabel *label_16; - QLineEdit *lineEdit_tt2; - QGroupBox *groupBox_3; - QGridLayout *gridLayout_4; - QLabel *label_17; - QLineEdit *lineEdit_CurName3; - QLabel *label_18; - QComboBox *comboBox_Co3; - QLabel *label_19; - QLineEdit *lineEdit_Vb3; - QLabel *label_20; - QLineEdit *lineEdit_Vt3; - QLabel *label_21; - QLineEdit *lineEdit_I3; - QLabel *label_22; - QLineEdit *lineEdit_t3; - QLabel *label_23; - QLineEdit *lineEdit_II3; - QLabel *label_24; - QLineEdit *lineEdit_tt3; - QGroupBox *groupBox_4; - QGridLayout *gridLayout_5; - QLabel *label_25; - QLineEdit *lineEdit_CurName4; - QLabel *label_26; - QComboBox *comboBox_Co4; - QLabel *label_27; - QLineEdit *lineEdit_Vb4; - QLabel *label_28; - QLineEdit *lineEdit_Vt4; - QLabel *label_29; - QLineEdit *lineEdit_I4; - QLabel *label_30; - QLineEdit *lineEdit_t4; - QLabel *label_31; - QLineEdit *lineEdit_II4; - QLabel *label_32; - QLineEdit *lineEdit_tt4; - QGroupBox *groupBox_5; - QGridLayout *gridLayout_6; - QLabel *label_33; - QLineEdit *lineEdit_CurName5; - QLabel *label_34; - QComboBox *comboBox_Co5; - QLabel *label_35; - QLineEdit *lineEdit_Vb5; - QLabel *label_36; - QLineEdit *lineEdit_Vt5; - QLabel *label_37; - QLineEdit *lineEdit_I5; - QLabel *label_38; - QLineEdit *lineEdit_t5; - QLabel *label_39; - QLineEdit *lineEdit_II5; - QLabel *label_40; - QLineEdit *lineEdit_tt5; - QGroupBox *groupBox_6; - QGridLayout *gridLayout_7; - QLabel *label_41; - QLineEdit *lineEdit_CurName6; - QLabel *label_42; - QComboBox *comboBox_Co6; - QLabel *label_43; - QLineEdit *lineEdit_Vb6; - QLabel *label_44; - QLineEdit *lineEdit_Vt6; - QLabel *label_45; - QLineEdit *lineEdit_I6; - QLabel *label_46; - QLineEdit *lineEdit_t6; - QLabel *label_47; - QLineEdit *lineEdit_II6; - QLabel *label_48; - QLineEdit *lineEdit_tt6; - QWidget *widget; - - void setupUi(QMainWindow *MainWindow) - { - if (MainWindow->objectName().isEmpty()) - MainWindow->setObjectName(QStringLiteral("MainWindow")); - MainWindow->resize(1232, 895); - centralWidget = new QWidget(MainWindow); - centralWidget->setObjectName(QStringLiteral("centralWidget")); - gridLayout_3 = new QGridLayout(centralWidget); - gridLayout_3->setSpacing(6); - gridLayout_3->setContentsMargins(11, 11, 11, 11); - gridLayout_3->setObjectName(QStringLiteral("gridLayout_3")); - frame = new QFrame(centralWidget); - frame->setObjectName(QStringLiteral("frame")); - QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(frame->sizePolicy().hasHeightForWidth()); - frame->setSizePolicy(sizePolicy); - frame->setMaximumSize(QSize(300, 16777215)); - frame->setFrameShape(QFrame::StyledPanel); - frame->setFrameShadow(QFrame::Raised); - gridLayout_8 = new QGridLayout(frame); - gridLayout_8->setSpacing(6); - gridLayout_8->setContentsMargins(11, 11, 11, 11); - gridLayout_8->setObjectName(QStringLiteral("gridLayout_8")); - horizontalLayout = new QHBoxLayout(); - horizontalLayout->setSpacing(6); - horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); - pushButton = new QPushButton(frame); - pushButton->setObjectName(QStringLiteral("pushButton")); - - horizontalLayout->addWidget(pushButton); - - lineEdit = new QLineEdit(frame); - lineEdit->setObjectName(QStringLiteral("lineEdit")); - - horizontalLayout->addWidget(lineEdit); - - - gridLayout_8->addLayout(horizontalLayout, 0, 0, 1, 1); - - horizontalLayout_2 = new QHBoxLayout(); - horizontalLayout_2->setSpacing(6); - horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); - pushButton_create = new QPushButton(frame); - pushButton_create->setObjectName(QStringLiteral("pushButton_create")); - - horizontalLayout_2->addWidget(pushButton_create); - - pushButton_save = new QPushButton(frame); - pushButton_save->setObjectName(QStringLiteral("pushButton_save")); - - horizontalLayout_2->addWidget(pushButton_save); - - - gridLayout_8->addLayout(horizontalLayout_2, 1, 0, 1, 1); - - groupBox = new QGroupBox(frame); - groupBox->setObjectName(QStringLiteral("groupBox")); - gridLayout = new QGridLayout(groupBox); - gridLayout->setSpacing(6); - gridLayout->setContentsMargins(11, 11, 11, 11); - gridLayout->setObjectName(QStringLiteral("gridLayout")); - gridLayout->setVerticalSpacing(2); - label = new QLabel(groupBox); - label->setObjectName(QStringLiteral("label")); - - gridLayout->addWidget(label, 0, 0, 1, 1); - - lineEdit_CurName1 = new QLineEdit(groupBox); - lineEdit_CurName1->setObjectName(QStringLiteral("lineEdit_CurName1")); - - gridLayout->addWidget(lineEdit_CurName1, 0, 1, 1, 1); - - label_2 = new QLabel(groupBox); - label_2->setObjectName(QStringLiteral("label_2")); - - gridLayout->addWidget(label_2, 0, 2, 1, 1); - - comboBox_Co1 = new QComboBox(groupBox); - comboBox_Co1->setObjectName(QStringLiteral("comboBox_Co1")); - - gridLayout->addWidget(comboBox_Co1, 0, 3, 1, 1); - - label_3 = new QLabel(groupBox); - label_3->setObjectName(QStringLiteral("label_3")); - - gridLayout->addWidget(label_3, 1, 0, 1, 1); - - lineEdit_Vb1 = new QLineEdit(groupBox); - lineEdit_Vb1->setObjectName(QStringLiteral("lineEdit_Vb1")); - - gridLayout->addWidget(lineEdit_Vb1, 1, 1, 1, 1); - - label_4 = new QLabel(groupBox); - label_4->setObjectName(QStringLiteral("label_4")); - - gridLayout->addWidget(label_4, 1, 2, 1, 1); - - lineEdit_Vt1 = new QLineEdit(groupBox); - lineEdit_Vt1->setObjectName(QStringLiteral("lineEdit_Vt1")); - - gridLayout->addWidget(lineEdit_Vt1, 1, 3, 1, 1); - - label_5 = new QLabel(groupBox); - label_5->setObjectName(QStringLiteral("label_5")); - - gridLayout->addWidget(label_5, 2, 0, 1, 1); - - lineEdit_I1 = new QLineEdit(groupBox); - lineEdit_I1->setObjectName(QStringLiteral("lineEdit_I1")); - - gridLayout->addWidget(lineEdit_I1, 2, 1, 1, 1); - - label_6 = new QLabel(groupBox); - label_6->setObjectName(QStringLiteral("label_6")); - - gridLayout->addWidget(label_6, 2, 2, 1, 1); - - lineEdit_t1 = new QLineEdit(groupBox); - lineEdit_t1->setObjectName(QStringLiteral("lineEdit_t1")); - - gridLayout->addWidget(lineEdit_t1, 2, 3, 1, 1); - - label_7 = new QLabel(groupBox); - label_7->setObjectName(QStringLiteral("label_7")); - - gridLayout->addWidget(label_7, 3, 0, 1, 1); - - lineEdit_II1 = new QLineEdit(groupBox); - lineEdit_II1->setObjectName(QStringLiteral("lineEdit_II1")); - - gridLayout->addWidget(lineEdit_II1, 3, 1, 1, 1); - - label_8 = new QLabel(groupBox); - label_8->setObjectName(QStringLiteral("label_8")); - - gridLayout->addWidget(label_8, 3, 2, 1, 1); - - lineEdit_tt1 = new QLineEdit(groupBox); - lineEdit_tt1->setObjectName(QStringLiteral("lineEdit_tt1")); - - gridLayout->addWidget(lineEdit_tt1, 3, 3, 1, 1); - - - gridLayout_8->addWidget(groupBox, 2, 0, 1, 1); - - groupBox_2 = new QGroupBox(frame); - groupBox_2->setObjectName(QStringLiteral("groupBox_2")); - gridLayout_2 = new QGridLayout(groupBox_2); - gridLayout_2->setSpacing(6); - gridLayout_2->setContentsMargins(11, 11, 11, 11); - gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); - gridLayout_2->setVerticalSpacing(2); - label_9 = new QLabel(groupBox_2); - label_9->setObjectName(QStringLiteral("label_9")); - - gridLayout_2->addWidget(label_9, 0, 0, 1, 1); - - lineEdit_CurName2 = new QLineEdit(groupBox_2); - lineEdit_CurName2->setObjectName(QStringLiteral("lineEdit_CurName2")); - - gridLayout_2->addWidget(lineEdit_CurName2, 0, 1, 1, 1); - - label_10 = new QLabel(groupBox_2); - label_10->setObjectName(QStringLiteral("label_10")); - - gridLayout_2->addWidget(label_10, 0, 2, 1, 1); - - comboBox_Co2 = new QComboBox(groupBox_2); - comboBox_Co2->setObjectName(QStringLiteral("comboBox_Co2")); - - gridLayout_2->addWidget(comboBox_Co2, 0, 3, 1, 1); - - label_11 = new QLabel(groupBox_2); - label_11->setObjectName(QStringLiteral("label_11")); - - gridLayout_2->addWidget(label_11, 1, 0, 1, 1); - - lineEdit_Vb2 = new QLineEdit(groupBox_2); - lineEdit_Vb2->setObjectName(QStringLiteral("lineEdit_Vb2")); - - gridLayout_2->addWidget(lineEdit_Vb2, 1, 1, 1, 1); - - label_12 = new QLabel(groupBox_2); - label_12->setObjectName(QStringLiteral("label_12")); - - gridLayout_2->addWidget(label_12, 1, 2, 1, 1); - - lineEdit_Vt2 = new QLineEdit(groupBox_2); - lineEdit_Vt2->setObjectName(QStringLiteral("lineEdit_Vt2")); - - gridLayout_2->addWidget(lineEdit_Vt2, 1, 3, 1, 1); - - label_13 = new QLabel(groupBox_2); - label_13->setObjectName(QStringLiteral("label_13")); - - gridLayout_2->addWidget(label_13, 2, 0, 1, 1); - - lineEdit_I2 = new QLineEdit(groupBox_2); - lineEdit_I2->setObjectName(QStringLiteral("lineEdit_I2")); - - gridLayout_2->addWidget(lineEdit_I2, 2, 1, 1, 1); - - label_14 = new QLabel(groupBox_2); - label_14->setObjectName(QStringLiteral("label_14")); - - gridLayout_2->addWidget(label_14, 2, 2, 1, 1); - - lineEdit_t2 = new QLineEdit(groupBox_2); - lineEdit_t2->setObjectName(QStringLiteral("lineEdit_t2")); - - gridLayout_2->addWidget(lineEdit_t2, 2, 3, 1, 1); - - label_15 = new QLabel(groupBox_2); - label_15->setObjectName(QStringLiteral("label_15")); - - gridLayout_2->addWidget(label_15, 3, 0, 1, 1); - - lineEdit_II2 = new QLineEdit(groupBox_2); - lineEdit_II2->setObjectName(QStringLiteral("lineEdit_II2")); - - gridLayout_2->addWidget(lineEdit_II2, 3, 1, 1, 1); - - label_16 = new QLabel(groupBox_2); - label_16->setObjectName(QStringLiteral("label_16")); - - gridLayout_2->addWidget(label_16, 3, 2, 1, 1); - - lineEdit_tt2 = new QLineEdit(groupBox_2); - lineEdit_tt2->setObjectName(QStringLiteral("lineEdit_tt2")); - - gridLayout_2->addWidget(lineEdit_tt2, 3, 3, 1, 1); - - - gridLayout_8->addWidget(groupBox_2, 3, 0, 1, 1); - - groupBox_3 = new QGroupBox(frame); - groupBox_3->setObjectName(QStringLiteral("groupBox_3")); - gridLayout_4 = new QGridLayout(groupBox_3); - gridLayout_4->setSpacing(6); - gridLayout_4->setContentsMargins(11, 11, 11, 11); - gridLayout_4->setObjectName(QStringLiteral("gridLayout_4")); - gridLayout_4->setVerticalSpacing(2); - label_17 = new QLabel(groupBox_3); - label_17->setObjectName(QStringLiteral("label_17")); - - gridLayout_4->addWidget(label_17, 0, 0, 1, 1); - - lineEdit_CurName3 = new QLineEdit(groupBox_3); - lineEdit_CurName3->setObjectName(QStringLiteral("lineEdit_CurName3")); - - gridLayout_4->addWidget(lineEdit_CurName3, 0, 1, 1, 1); - - label_18 = new QLabel(groupBox_3); - label_18->setObjectName(QStringLiteral("label_18")); - - gridLayout_4->addWidget(label_18, 0, 2, 1, 1); - - comboBox_Co3 = new QComboBox(groupBox_3); - comboBox_Co3->setObjectName(QStringLiteral("comboBox_Co3")); - - gridLayout_4->addWidget(comboBox_Co3, 0, 3, 1, 1); - - label_19 = new QLabel(groupBox_3); - label_19->setObjectName(QStringLiteral("label_19")); - - gridLayout_4->addWidget(label_19, 1, 0, 1, 1); - - lineEdit_Vb3 = new QLineEdit(groupBox_3); - lineEdit_Vb3->setObjectName(QStringLiteral("lineEdit_Vb3")); - - gridLayout_4->addWidget(lineEdit_Vb3, 1, 1, 1, 1); - - label_20 = new QLabel(groupBox_3); - label_20->setObjectName(QStringLiteral("label_20")); - - gridLayout_4->addWidget(label_20, 1, 2, 1, 1); - - lineEdit_Vt3 = new QLineEdit(groupBox_3); - lineEdit_Vt3->setObjectName(QStringLiteral("lineEdit_Vt3")); - - gridLayout_4->addWidget(lineEdit_Vt3, 1, 3, 1, 1); - - label_21 = new QLabel(groupBox_3); - label_21->setObjectName(QStringLiteral("label_21")); - - gridLayout_4->addWidget(label_21, 2, 0, 1, 1); - - lineEdit_I3 = new QLineEdit(groupBox_3); - lineEdit_I3->setObjectName(QStringLiteral("lineEdit_I3")); - - gridLayout_4->addWidget(lineEdit_I3, 2, 1, 1, 1); - - label_22 = new QLabel(groupBox_3); - label_22->setObjectName(QStringLiteral("label_22")); - - gridLayout_4->addWidget(label_22, 2, 2, 1, 1); - - lineEdit_t3 = new QLineEdit(groupBox_3); - lineEdit_t3->setObjectName(QStringLiteral("lineEdit_t3")); - - gridLayout_4->addWidget(lineEdit_t3, 2, 3, 1, 1); - - label_23 = new QLabel(groupBox_3); - label_23->setObjectName(QStringLiteral("label_23")); - - gridLayout_4->addWidget(label_23, 3, 0, 1, 1); - - lineEdit_II3 = new QLineEdit(groupBox_3); - lineEdit_II3->setObjectName(QStringLiteral("lineEdit_II3")); - - gridLayout_4->addWidget(lineEdit_II3, 3, 1, 1, 1); - - label_24 = new QLabel(groupBox_3); - label_24->setObjectName(QStringLiteral("label_24")); - - gridLayout_4->addWidget(label_24, 3, 2, 1, 1); - - lineEdit_tt3 = new QLineEdit(groupBox_3); - lineEdit_tt3->setObjectName(QStringLiteral("lineEdit_tt3")); - - gridLayout_4->addWidget(lineEdit_tt3, 3, 3, 1, 1); - - - gridLayout_8->addWidget(groupBox_3, 4, 0, 1, 1); - - groupBox_4 = new QGroupBox(frame); - groupBox_4->setObjectName(QStringLiteral("groupBox_4")); - gridLayout_5 = new QGridLayout(groupBox_4); - gridLayout_5->setSpacing(6); - gridLayout_5->setContentsMargins(11, 11, 11, 11); - gridLayout_5->setObjectName(QStringLiteral("gridLayout_5")); - gridLayout_5->setVerticalSpacing(2); - label_25 = new QLabel(groupBox_4); - label_25->setObjectName(QStringLiteral("label_25")); - - gridLayout_5->addWidget(label_25, 0, 0, 1, 1); - - lineEdit_CurName4 = new QLineEdit(groupBox_4); - lineEdit_CurName4->setObjectName(QStringLiteral("lineEdit_CurName4")); - - gridLayout_5->addWidget(lineEdit_CurName4, 0, 1, 1, 1); - - label_26 = new QLabel(groupBox_4); - label_26->setObjectName(QStringLiteral("label_26")); - - gridLayout_5->addWidget(label_26, 0, 2, 1, 1); - - comboBox_Co4 = new QComboBox(groupBox_4); - comboBox_Co4->setObjectName(QStringLiteral("comboBox_Co4")); - - gridLayout_5->addWidget(comboBox_Co4, 0, 3, 1, 1); - - label_27 = new QLabel(groupBox_4); - label_27->setObjectName(QStringLiteral("label_27")); - - gridLayout_5->addWidget(label_27, 1, 0, 1, 1); - - lineEdit_Vb4 = new QLineEdit(groupBox_4); - lineEdit_Vb4->setObjectName(QStringLiteral("lineEdit_Vb4")); - - gridLayout_5->addWidget(lineEdit_Vb4, 1, 1, 1, 1); - - label_28 = new QLabel(groupBox_4); - label_28->setObjectName(QStringLiteral("label_28")); - - gridLayout_5->addWidget(label_28, 1, 2, 1, 1); - - lineEdit_Vt4 = new QLineEdit(groupBox_4); - lineEdit_Vt4->setObjectName(QStringLiteral("lineEdit_Vt4")); - - gridLayout_5->addWidget(lineEdit_Vt4, 1, 3, 1, 1); - - label_29 = new QLabel(groupBox_4); - label_29->setObjectName(QStringLiteral("label_29")); - - gridLayout_5->addWidget(label_29, 2, 0, 1, 1); - - lineEdit_I4 = new QLineEdit(groupBox_4); - lineEdit_I4->setObjectName(QStringLiteral("lineEdit_I4")); - - gridLayout_5->addWidget(lineEdit_I4, 2, 1, 1, 1); - - label_30 = new QLabel(groupBox_4); - label_30->setObjectName(QStringLiteral("label_30")); - - gridLayout_5->addWidget(label_30, 2, 2, 1, 1); - - lineEdit_t4 = new QLineEdit(groupBox_4); - lineEdit_t4->setObjectName(QStringLiteral("lineEdit_t4")); - - gridLayout_5->addWidget(lineEdit_t4, 2, 3, 1, 1); - - label_31 = new QLabel(groupBox_4); - label_31->setObjectName(QStringLiteral("label_31")); - - gridLayout_5->addWidget(label_31, 3, 0, 1, 1); - - lineEdit_II4 = new QLineEdit(groupBox_4); - lineEdit_II4->setObjectName(QStringLiteral("lineEdit_II4")); - - gridLayout_5->addWidget(lineEdit_II4, 3, 1, 1, 1); - - label_32 = new QLabel(groupBox_4); - label_32->setObjectName(QStringLiteral("label_32")); - - gridLayout_5->addWidget(label_32, 3, 2, 1, 1); - - lineEdit_tt4 = new QLineEdit(groupBox_4); - lineEdit_tt4->setObjectName(QStringLiteral("lineEdit_tt4")); - - gridLayout_5->addWidget(lineEdit_tt4, 3, 3, 1, 1); - - - gridLayout_8->addWidget(groupBox_4, 5, 0, 1, 1); - - groupBox_5 = new QGroupBox(frame); - groupBox_5->setObjectName(QStringLiteral("groupBox_5")); - gridLayout_6 = new QGridLayout(groupBox_5); - gridLayout_6->setSpacing(6); - gridLayout_6->setContentsMargins(11, 11, 11, 11); - gridLayout_6->setObjectName(QStringLiteral("gridLayout_6")); - gridLayout_6->setVerticalSpacing(2); - label_33 = new QLabel(groupBox_5); - label_33->setObjectName(QStringLiteral("label_33")); - - gridLayout_6->addWidget(label_33, 0, 0, 1, 1); - - lineEdit_CurName5 = new QLineEdit(groupBox_5); - lineEdit_CurName5->setObjectName(QStringLiteral("lineEdit_CurName5")); - - gridLayout_6->addWidget(lineEdit_CurName5, 0, 1, 1, 1); - - label_34 = new QLabel(groupBox_5); - label_34->setObjectName(QStringLiteral("label_34")); - - gridLayout_6->addWidget(label_34, 0, 2, 1, 1); - - comboBox_Co5 = new QComboBox(groupBox_5); - comboBox_Co5->setObjectName(QStringLiteral("comboBox_Co5")); - - gridLayout_6->addWidget(comboBox_Co5, 0, 3, 1, 1); - - label_35 = new QLabel(groupBox_5); - label_35->setObjectName(QStringLiteral("label_35")); - - gridLayout_6->addWidget(label_35, 1, 0, 1, 1); - - lineEdit_Vb5 = new QLineEdit(groupBox_5); - lineEdit_Vb5->setObjectName(QStringLiteral("lineEdit_Vb5")); - - gridLayout_6->addWidget(lineEdit_Vb5, 1, 1, 1, 1); - - label_36 = new QLabel(groupBox_5); - label_36->setObjectName(QStringLiteral("label_36")); - - gridLayout_6->addWidget(label_36, 1, 2, 1, 1); - - lineEdit_Vt5 = new QLineEdit(groupBox_5); - lineEdit_Vt5->setObjectName(QStringLiteral("lineEdit_Vt5")); - - gridLayout_6->addWidget(lineEdit_Vt5, 1, 3, 1, 1); - - label_37 = new QLabel(groupBox_5); - label_37->setObjectName(QStringLiteral("label_37")); - - gridLayout_6->addWidget(label_37, 2, 0, 1, 1); - - lineEdit_I5 = new QLineEdit(groupBox_5); - lineEdit_I5->setObjectName(QStringLiteral("lineEdit_I5")); - - gridLayout_6->addWidget(lineEdit_I5, 2, 1, 1, 1); - - label_38 = new QLabel(groupBox_5); - label_38->setObjectName(QStringLiteral("label_38")); - - gridLayout_6->addWidget(label_38, 2, 2, 1, 1); - - lineEdit_t5 = new QLineEdit(groupBox_5); - lineEdit_t5->setObjectName(QStringLiteral("lineEdit_t5")); - - gridLayout_6->addWidget(lineEdit_t5, 2, 3, 1, 1); - - label_39 = new QLabel(groupBox_5); - label_39->setObjectName(QStringLiteral("label_39")); - - gridLayout_6->addWidget(label_39, 3, 0, 1, 1); - - lineEdit_II5 = new QLineEdit(groupBox_5); - lineEdit_II5->setObjectName(QStringLiteral("lineEdit_II5")); - - gridLayout_6->addWidget(lineEdit_II5, 3, 1, 1, 1); - - label_40 = new QLabel(groupBox_5); - label_40->setObjectName(QStringLiteral("label_40")); - - gridLayout_6->addWidget(label_40, 3, 2, 1, 1); - - lineEdit_tt5 = new QLineEdit(groupBox_5); - lineEdit_tt5->setObjectName(QStringLiteral("lineEdit_tt5")); - - gridLayout_6->addWidget(lineEdit_tt5, 3, 3, 1, 1); - - - gridLayout_8->addWidget(groupBox_5, 6, 0, 1, 1); - - groupBox_6 = new QGroupBox(frame); - groupBox_6->setObjectName(QStringLiteral("groupBox_6")); - gridLayout_7 = new QGridLayout(groupBox_6); - gridLayout_7->setSpacing(6); - gridLayout_7->setContentsMargins(11, 11, 11, 11); - gridLayout_7->setObjectName(QStringLiteral("gridLayout_7")); - gridLayout_7->setVerticalSpacing(2); - label_41 = new QLabel(groupBox_6); - label_41->setObjectName(QStringLiteral("label_41")); - - gridLayout_7->addWidget(label_41, 0, 0, 1, 1); - - lineEdit_CurName6 = new QLineEdit(groupBox_6); - lineEdit_CurName6->setObjectName(QStringLiteral("lineEdit_CurName6")); - - gridLayout_7->addWidget(lineEdit_CurName6, 0, 1, 1, 1); - - label_42 = new QLabel(groupBox_6); - label_42->setObjectName(QStringLiteral("label_42")); - - gridLayout_7->addWidget(label_42, 0, 2, 1, 1); - - comboBox_Co6 = new QComboBox(groupBox_6); - comboBox_Co6->setObjectName(QStringLiteral("comboBox_Co6")); - - gridLayout_7->addWidget(comboBox_Co6, 0, 3, 1, 1); - - label_43 = new QLabel(groupBox_6); - label_43->setObjectName(QStringLiteral("label_43")); - - gridLayout_7->addWidget(label_43, 1, 0, 1, 1); - - lineEdit_Vb6 = new QLineEdit(groupBox_6); - lineEdit_Vb6->setObjectName(QStringLiteral("lineEdit_Vb6")); - - gridLayout_7->addWidget(lineEdit_Vb6, 1, 1, 1, 1); - - label_44 = new QLabel(groupBox_6); - label_44->setObjectName(QStringLiteral("label_44")); - - gridLayout_7->addWidget(label_44, 1, 2, 1, 1); - - lineEdit_Vt6 = new QLineEdit(groupBox_6); - lineEdit_Vt6->setObjectName(QStringLiteral("lineEdit_Vt6")); - - gridLayout_7->addWidget(lineEdit_Vt6, 1, 3, 1, 1); - - label_45 = new QLabel(groupBox_6); - label_45->setObjectName(QStringLiteral("label_45")); - - gridLayout_7->addWidget(label_45, 2, 0, 1, 1); - - lineEdit_I6 = new QLineEdit(groupBox_6); - lineEdit_I6->setObjectName(QStringLiteral("lineEdit_I6")); - - gridLayout_7->addWidget(lineEdit_I6, 2, 1, 1, 1); - - label_46 = new QLabel(groupBox_6); - label_46->setObjectName(QStringLiteral("label_46")); - - gridLayout_7->addWidget(label_46, 2, 2, 1, 1); - - lineEdit_t6 = new QLineEdit(groupBox_6); - lineEdit_t6->setObjectName(QStringLiteral("lineEdit_t6")); - - gridLayout_7->addWidget(lineEdit_t6, 2, 3, 1, 1); - - label_47 = new QLabel(groupBox_6); - label_47->setObjectName(QStringLiteral("label_47")); - - gridLayout_7->addWidget(label_47, 3, 0, 1, 1); - - lineEdit_II6 = new QLineEdit(groupBox_6); - lineEdit_II6->setObjectName(QStringLiteral("lineEdit_II6")); - - gridLayout_7->addWidget(lineEdit_II6, 3, 1, 1, 1); - - label_48 = new QLabel(groupBox_6); - label_48->setObjectName(QStringLiteral("label_48")); - - gridLayout_7->addWidget(label_48, 3, 2, 1, 1); - - lineEdit_tt6 = new QLineEdit(groupBox_6); - lineEdit_tt6->setObjectName(QStringLiteral("lineEdit_tt6")); - - gridLayout_7->addWidget(lineEdit_tt6, 3, 3, 1, 1); - - - gridLayout_8->addWidget(groupBox_6, 7, 0, 1, 1); - - - gridLayout_3->addWidget(frame, 0, 1, 1, 1); - - widget = new QWidget(centralWidget); - widget->setObjectName(QStringLiteral("widget")); - - gridLayout_3->addWidget(widget, 0, 0, 1, 1); - - MainWindow->setCentralWidget(centralWidget); - - retranslateUi(MainWindow); - - QMetaObject::connectSlotsByName(MainWindow); - } // setupUi - - void retranslateUi(QMainWindow *MainWindow) - { - MainWindow->setWindowTitle(QApplication::translate("MainWindow", "\345\215\217\350\260\203\346\233\262\347\272\277", Q_NULLPTR)); - pushButton->setText(QApplication::translate("MainWindow", "\351\200\211\346\213\251\346\226\207\344\273\266", Q_NULLPTR)); - pushButton_create->setText(QApplication::translate("MainWindow", "\347\224\237\346\210\220\346\233\262\347\272\277", Q_NULLPTR)); - pushButton_save->setText(QApplication::translate("MainWindow", "\344\277\235\345\255\230\346\250\241\346\235\277", Q_NULLPTR)); - groupBox->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2071", Q_NULLPTR)); - label->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); - label_2->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); - comboBox_Co1->clear(); - comboBox_Co1->insertItems(0, QStringList() - << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) - ); - label_3->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); - label_4->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); - label_5->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); - label_6->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); - label_7->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); - label_8->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); - groupBox_2->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2072", Q_NULLPTR)); - label_9->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); - label_10->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); - comboBox_Co2->clear(); - comboBox_Co2->insertItems(0, QStringList() - << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) - ); - label_11->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); - label_12->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); - label_13->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); - label_14->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); - label_15->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); - label_16->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); - groupBox_3->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2073", Q_NULLPTR)); - label_17->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); - label_18->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); - comboBox_Co3->clear(); - comboBox_Co3->insertItems(0, QStringList() - << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) - ); - label_19->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); - label_20->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); - label_21->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); - label_22->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); - label_23->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); - label_24->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); - groupBox_4->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2074", Q_NULLPTR)); - label_25->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); - label_26->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); - comboBox_Co4->clear(); - comboBox_Co4->insertItems(0, QStringList() - << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) - ); - label_27->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); - label_28->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); - label_29->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); - label_30->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); - label_31->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); - label_32->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); - groupBox_5->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2075", Q_NULLPTR)); - label_33->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); - label_34->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); - comboBox_Co5->clear(); - comboBox_Co5->insertItems(0, QStringList() - << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) - ); - label_35->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); - label_36->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); - label_37->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); - label_38->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); - label_39->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); - label_40->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); - groupBox_6->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2076", Q_NULLPTR)); - label_41->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); - label_42->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); - comboBox_Co6->clear(); - comboBox_Co6->insertItems(0, QStringList() - << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) - << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) - ); - label_43->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); - label_44->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); - label_45->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); - label_46->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); - label_47->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); - label_48->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); - } // retranslateUi - -}; - -namespace Ui { - class MainWindow: public Ui_MainWindow {}; -} // namespace Ui - -QT_END_NAMESPACE - -#endif // UI_MAINWINDOW_H +/******************************************************************************** +** Form generated from reading UI file 'mainwindow.ui' +** +** Created by: Qt User Interface Compiler version 5.9.2 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_MAINWINDOW_H +#define UI_MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_MainWindow +{ +public: + QWidget *centralWidget; + QGridLayout *gridLayout_3; + QFrame *frame; + QGridLayout *gridLayout_8; + QHBoxLayout *horizontalLayout; + QPushButton *pushButton; + QLineEdit *lineEdit; + QHBoxLayout *horizontalLayout_2; + QPushButton *pushButton_create; + QPushButton *pushButton_save; + QGroupBox *groupBox; + QGridLayout *gridLayout; + QLabel *label; + QLineEdit *lineEdit_CurName1; + QLabel *label_2; + QComboBox *comboBox_Co1; + QLabel *label_3; + QLineEdit *lineEdit_Vb1; + QLabel *label_4; + QLineEdit *lineEdit_Vt1; + QLabel *label_5; + QLineEdit *lineEdit_I1; + QLabel *label_6; + QLineEdit *lineEdit_t1; + QLabel *label_7; + QLineEdit *lineEdit_II1; + QLabel *label_8; + QLineEdit *lineEdit_tt1; + QGroupBox *groupBox_2; + QGridLayout *gridLayout_2; + QLabel *label_9; + QLineEdit *lineEdit_CurName2; + QLabel *label_10; + QComboBox *comboBox_Co2; + QLabel *label_11; + QLineEdit *lineEdit_Vb2; + QLabel *label_12; + QLineEdit *lineEdit_Vt2; + QLabel *label_13; + QLineEdit *lineEdit_I2; + QLabel *label_14; + QLineEdit *lineEdit_t2; + QLabel *label_15; + QLineEdit *lineEdit_II2; + QLabel *label_16; + QLineEdit *lineEdit_tt2; + QGroupBox *groupBox_3; + QGridLayout *gridLayout_4; + QLabel *label_17; + QLineEdit *lineEdit_CurName3; + QLabel *label_18; + QComboBox *comboBox_Co3; + QLabel *label_19; + QLineEdit *lineEdit_Vb3; + QLabel *label_20; + QLineEdit *lineEdit_Vt3; + QLabel *label_21; + QLineEdit *lineEdit_I3; + QLabel *label_22; + QLineEdit *lineEdit_t3; + QLabel *label_23; + QLineEdit *lineEdit_II3; + QLabel *label_24; + QLineEdit *lineEdit_tt3; + QGroupBox *groupBox_4; + QGridLayout *gridLayout_5; + QLabel *label_25; + QLineEdit *lineEdit_CurName4; + QLabel *label_26; + QComboBox *comboBox_Co4; + QLabel *label_27; + QLineEdit *lineEdit_Vb4; + QLabel *label_28; + QLineEdit *lineEdit_Vt4; + QLabel *label_29; + QLineEdit *lineEdit_I4; + QLabel *label_30; + QLineEdit *lineEdit_t4; + QLabel *label_31; + QLineEdit *lineEdit_II4; + QLabel *label_32; + QLineEdit *lineEdit_tt4; + QGroupBox *groupBox_5; + QGridLayout *gridLayout_6; + QLabel *label_33; + QLineEdit *lineEdit_CurName5; + QLabel *label_34; + QComboBox *comboBox_Co5; + QLabel *label_35; + QLineEdit *lineEdit_Vb5; + QLabel *label_36; + QLineEdit *lineEdit_Vt5; + QLabel *label_37; + QLineEdit *lineEdit_I5; + QLabel *label_38; + QLineEdit *lineEdit_t5; + QLabel *label_39; + QLineEdit *lineEdit_II5; + QLabel *label_40; + QLineEdit *lineEdit_tt5; + QGroupBox *groupBox_6; + QGridLayout *gridLayout_7; + QLabel *label_41; + QLineEdit *lineEdit_CurName6; + QLabel *label_42; + QComboBox *comboBox_Co6; + QLabel *label_43; + QLineEdit *lineEdit_Vb6; + QLabel *label_44; + QLineEdit *lineEdit_Vt6; + QLabel *label_45; + QLineEdit *lineEdit_I6; + QLabel *label_46; + QLineEdit *lineEdit_t6; + QLabel *label_47; + QLineEdit *lineEdit_II6; + QLabel *label_48; + QLineEdit *lineEdit_tt6; + QWidget *widget; + + void setupUi(QMainWindow *MainWindow) + { + if (MainWindow->objectName().isEmpty()) + MainWindow->setObjectName(QStringLiteral("MainWindow")); + MainWindow->resize(1232, 895); + centralWidget = new QWidget(MainWindow); + centralWidget->setObjectName(QStringLiteral("centralWidget")); + gridLayout_3 = new QGridLayout(centralWidget); + gridLayout_3->setSpacing(6); + gridLayout_3->setContentsMargins(11, 11, 11, 11); + gridLayout_3->setObjectName(QStringLiteral("gridLayout_3")); + frame = new QFrame(centralWidget); + frame->setObjectName(QStringLiteral("frame")); + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(frame->sizePolicy().hasHeightForWidth()); + frame->setSizePolicy(sizePolicy); + frame->setMaximumSize(QSize(300, 16777215)); + frame->setFrameShape(QFrame::StyledPanel); + frame->setFrameShadow(QFrame::Raised); + gridLayout_8 = new QGridLayout(frame); + gridLayout_8->setSpacing(6); + gridLayout_8->setContentsMargins(11, 11, 11, 11); + gridLayout_8->setObjectName(QStringLiteral("gridLayout_8")); + horizontalLayout = new QHBoxLayout(); + horizontalLayout->setSpacing(6); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); + pushButton = new QPushButton(frame); + pushButton->setObjectName(QStringLiteral("pushButton")); + + horizontalLayout->addWidget(pushButton); + + lineEdit = new QLineEdit(frame); + lineEdit->setObjectName(QStringLiteral("lineEdit")); + + horizontalLayout->addWidget(lineEdit); + + + gridLayout_8->addLayout(horizontalLayout, 0, 0, 1, 1); + + horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setSpacing(6); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + pushButton_create = new QPushButton(frame); + pushButton_create->setObjectName(QStringLiteral("pushButton_create")); + + horizontalLayout_2->addWidget(pushButton_create); + + pushButton_save = new QPushButton(frame); + pushButton_save->setObjectName(QStringLiteral("pushButton_save")); + + horizontalLayout_2->addWidget(pushButton_save); + + + gridLayout_8->addLayout(horizontalLayout_2, 1, 0, 1, 1); + + groupBox = new QGroupBox(frame); + groupBox->setObjectName(QStringLiteral("groupBox")); + gridLayout = new QGridLayout(groupBox); + gridLayout->setSpacing(6); + gridLayout->setContentsMargins(11, 11, 11, 11); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gridLayout->setVerticalSpacing(2); + label = new QLabel(groupBox); + label->setObjectName(QStringLiteral("label")); + + gridLayout->addWidget(label, 0, 0, 1, 1); + + lineEdit_CurName1 = new QLineEdit(groupBox); + lineEdit_CurName1->setObjectName(QStringLiteral("lineEdit_CurName1")); + + gridLayout->addWidget(lineEdit_CurName1, 0, 1, 1, 1); + + label_2 = new QLabel(groupBox); + label_2->setObjectName(QStringLiteral("label_2")); + + gridLayout->addWidget(label_2, 0, 2, 1, 1); + + comboBox_Co1 = new QComboBox(groupBox); + comboBox_Co1->setObjectName(QStringLiteral("comboBox_Co1")); + + gridLayout->addWidget(comboBox_Co1, 0, 3, 1, 1); + + label_3 = new QLabel(groupBox); + label_3->setObjectName(QStringLiteral("label_3")); + + gridLayout->addWidget(label_3, 1, 0, 1, 1); + + lineEdit_Vb1 = new QLineEdit(groupBox); + lineEdit_Vb1->setObjectName(QStringLiteral("lineEdit_Vb1")); + + gridLayout->addWidget(lineEdit_Vb1, 1, 1, 1, 1); + + label_4 = new QLabel(groupBox); + label_4->setObjectName(QStringLiteral("label_4")); + + gridLayout->addWidget(label_4, 1, 2, 1, 1); + + lineEdit_Vt1 = new QLineEdit(groupBox); + lineEdit_Vt1->setObjectName(QStringLiteral("lineEdit_Vt1")); + + gridLayout->addWidget(lineEdit_Vt1, 1, 3, 1, 1); + + label_5 = new QLabel(groupBox); + label_5->setObjectName(QStringLiteral("label_5")); + + gridLayout->addWidget(label_5, 2, 0, 1, 1); + + lineEdit_I1 = new QLineEdit(groupBox); + lineEdit_I1->setObjectName(QStringLiteral("lineEdit_I1")); + + gridLayout->addWidget(lineEdit_I1, 2, 1, 1, 1); + + label_6 = new QLabel(groupBox); + label_6->setObjectName(QStringLiteral("label_6")); + + gridLayout->addWidget(label_6, 2, 2, 1, 1); + + lineEdit_t1 = new QLineEdit(groupBox); + lineEdit_t1->setObjectName(QStringLiteral("lineEdit_t1")); + + gridLayout->addWidget(lineEdit_t1, 2, 3, 1, 1); + + label_7 = new QLabel(groupBox); + label_7->setObjectName(QStringLiteral("label_7")); + + gridLayout->addWidget(label_7, 3, 0, 1, 1); + + lineEdit_II1 = new QLineEdit(groupBox); + lineEdit_II1->setObjectName(QStringLiteral("lineEdit_II1")); + + gridLayout->addWidget(lineEdit_II1, 3, 1, 1, 1); + + label_8 = new QLabel(groupBox); + label_8->setObjectName(QStringLiteral("label_8")); + + gridLayout->addWidget(label_8, 3, 2, 1, 1); + + lineEdit_tt1 = new QLineEdit(groupBox); + lineEdit_tt1->setObjectName(QStringLiteral("lineEdit_tt1")); + + gridLayout->addWidget(lineEdit_tt1, 3, 3, 1, 1); + + + gridLayout_8->addWidget(groupBox, 2, 0, 1, 1); + + groupBox_2 = new QGroupBox(frame); + groupBox_2->setObjectName(QStringLiteral("groupBox_2")); + gridLayout_2 = new QGridLayout(groupBox_2); + gridLayout_2->setSpacing(6); + gridLayout_2->setContentsMargins(11, 11, 11, 11); + gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); + gridLayout_2->setVerticalSpacing(2); + label_9 = new QLabel(groupBox_2); + label_9->setObjectName(QStringLiteral("label_9")); + + gridLayout_2->addWidget(label_9, 0, 0, 1, 1); + + lineEdit_CurName2 = new QLineEdit(groupBox_2); + lineEdit_CurName2->setObjectName(QStringLiteral("lineEdit_CurName2")); + + gridLayout_2->addWidget(lineEdit_CurName2, 0, 1, 1, 1); + + label_10 = new QLabel(groupBox_2); + label_10->setObjectName(QStringLiteral("label_10")); + + gridLayout_2->addWidget(label_10, 0, 2, 1, 1); + + comboBox_Co2 = new QComboBox(groupBox_2); + comboBox_Co2->setObjectName(QStringLiteral("comboBox_Co2")); + + gridLayout_2->addWidget(comboBox_Co2, 0, 3, 1, 1); + + label_11 = new QLabel(groupBox_2); + label_11->setObjectName(QStringLiteral("label_11")); + + gridLayout_2->addWidget(label_11, 1, 0, 1, 1); + + lineEdit_Vb2 = new QLineEdit(groupBox_2); + lineEdit_Vb2->setObjectName(QStringLiteral("lineEdit_Vb2")); + + gridLayout_2->addWidget(lineEdit_Vb2, 1, 1, 1, 1); + + label_12 = new QLabel(groupBox_2); + label_12->setObjectName(QStringLiteral("label_12")); + + gridLayout_2->addWidget(label_12, 1, 2, 1, 1); + + lineEdit_Vt2 = new QLineEdit(groupBox_2); + lineEdit_Vt2->setObjectName(QStringLiteral("lineEdit_Vt2")); + + gridLayout_2->addWidget(lineEdit_Vt2, 1, 3, 1, 1); + + label_13 = new QLabel(groupBox_2); + label_13->setObjectName(QStringLiteral("label_13")); + + gridLayout_2->addWidget(label_13, 2, 0, 1, 1); + + lineEdit_I2 = new QLineEdit(groupBox_2); + lineEdit_I2->setObjectName(QStringLiteral("lineEdit_I2")); + + gridLayout_2->addWidget(lineEdit_I2, 2, 1, 1, 1); + + label_14 = new QLabel(groupBox_2); + label_14->setObjectName(QStringLiteral("label_14")); + + gridLayout_2->addWidget(label_14, 2, 2, 1, 1); + + lineEdit_t2 = new QLineEdit(groupBox_2); + lineEdit_t2->setObjectName(QStringLiteral("lineEdit_t2")); + + gridLayout_2->addWidget(lineEdit_t2, 2, 3, 1, 1); + + label_15 = new QLabel(groupBox_2); + label_15->setObjectName(QStringLiteral("label_15")); + + gridLayout_2->addWidget(label_15, 3, 0, 1, 1); + + lineEdit_II2 = new QLineEdit(groupBox_2); + lineEdit_II2->setObjectName(QStringLiteral("lineEdit_II2")); + + gridLayout_2->addWidget(lineEdit_II2, 3, 1, 1, 1); + + label_16 = new QLabel(groupBox_2); + label_16->setObjectName(QStringLiteral("label_16")); + + gridLayout_2->addWidget(label_16, 3, 2, 1, 1); + + lineEdit_tt2 = new QLineEdit(groupBox_2); + lineEdit_tt2->setObjectName(QStringLiteral("lineEdit_tt2")); + + gridLayout_2->addWidget(lineEdit_tt2, 3, 3, 1, 1); + + + gridLayout_8->addWidget(groupBox_2, 3, 0, 1, 1); + + groupBox_3 = new QGroupBox(frame); + groupBox_3->setObjectName(QStringLiteral("groupBox_3")); + gridLayout_4 = new QGridLayout(groupBox_3); + gridLayout_4->setSpacing(6); + gridLayout_4->setContentsMargins(11, 11, 11, 11); + gridLayout_4->setObjectName(QStringLiteral("gridLayout_4")); + gridLayout_4->setVerticalSpacing(2); + label_17 = new QLabel(groupBox_3); + label_17->setObjectName(QStringLiteral("label_17")); + + gridLayout_4->addWidget(label_17, 0, 0, 1, 1); + + lineEdit_CurName3 = new QLineEdit(groupBox_3); + lineEdit_CurName3->setObjectName(QStringLiteral("lineEdit_CurName3")); + + gridLayout_4->addWidget(lineEdit_CurName3, 0, 1, 1, 1); + + label_18 = new QLabel(groupBox_3); + label_18->setObjectName(QStringLiteral("label_18")); + + gridLayout_4->addWidget(label_18, 0, 2, 1, 1); + + comboBox_Co3 = new QComboBox(groupBox_3); + comboBox_Co3->setObjectName(QStringLiteral("comboBox_Co3")); + + gridLayout_4->addWidget(comboBox_Co3, 0, 3, 1, 1); + + label_19 = new QLabel(groupBox_3); + label_19->setObjectName(QStringLiteral("label_19")); + + gridLayout_4->addWidget(label_19, 1, 0, 1, 1); + + lineEdit_Vb3 = new QLineEdit(groupBox_3); + lineEdit_Vb3->setObjectName(QStringLiteral("lineEdit_Vb3")); + + gridLayout_4->addWidget(lineEdit_Vb3, 1, 1, 1, 1); + + label_20 = new QLabel(groupBox_3); + label_20->setObjectName(QStringLiteral("label_20")); + + gridLayout_4->addWidget(label_20, 1, 2, 1, 1); + + lineEdit_Vt3 = new QLineEdit(groupBox_3); + lineEdit_Vt3->setObjectName(QStringLiteral("lineEdit_Vt3")); + + gridLayout_4->addWidget(lineEdit_Vt3, 1, 3, 1, 1); + + label_21 = new QLabel(groupBox_3); + label_21->setObjectName(QStringLiteral("label_21")); + + gridLayout_4->addWidget(label_21, 2, 0, 1, 1); + + lineEdit_I3 = new QLineEdit(groupBox_3); + lineEdit_I3->setObjectName(QStringLiteral("lineEdit_I3")); + + gridLayout_4->addWidget(lineEdit_I3, 2, 1, 1, 1); + + label_22 = new QLabel(groupBox_3); + label_22->setObjectName(QStringLiteral("label_22")); + + gridLayout_4->addWidget(label_22, 2, 2, 1, 1); + + lineEdit_t3 = new QLineEdit(groupBox_3); + lineEdit_t3->setObjectName(QStringLiteral("lineEdit_t3")); + + gridLayout_4->addWidget(lineEdit_t3, 2, 3, 1, 1); + + label_23 = new QLabel(groupBox_3); + label_23->setObjectName(QStringLiteral("label_23")); + + gridLayout_4->addWidget(label_23, 3, 0, 1, 1); + + lineEdit_II3 = new QLineEdit(groupBox_3); + lineEdit_II3->setObjectName(QStringLiteral("lineEdit_II3")); + + gridLayout_4->addWidget(lineEdit_II3, 3, 1, 1, 1); + + label_24 = new QLabel(groupBox_3); + label_24->setObjectName(QStringLiteral("label_24")); + + gridLayout_4->addWidget(label_24, 3, 2, 1, 1); + + lineEdit_tt3 = new QLineEdit(groupBox_3); + lineEdit_tt3->setObjectName(QStringLiteral("lineEdit_tt3")); + + gridLayout_4->addWidget(lineEdit_tt3, 3, 3, 1, 1); + + + gridLayout_8->addWidget(groupBox_3, 4, 0, 1, 1); + + groupBox_4 = new QGroupBox(frame); + groupBox_4->setObjectName(QStringLiteral("groupBox_4")); + gridLayout_5 = new QGridLayout(groupBox_4); + gridLayout_5->setSpacing(6); + gridLayout_5->setContentsMargins(11, 11, 11, 11); + gridLayout_5->setObjectName(QStringLiteral("gridLayout_5")); + gridLayout_5->setVerticalSpacing(2); + label_25 = new QLabel(groupBox_4); + label_25->setObjectName(QStringLiteral("label_25")); + + gridLayout_5->addWidget(label_25, 0, 0, 1, 1); + + lineEdit_CurName4 = new QLineEdit(groupBox_4); + lineEdit_CurName4->setObjectName(QStringLiteral("lineEdit_CurName4")); + + gridLayout_5->addWidget(lineEdit_CurName4, 0, 1, 1, 1); + + label_26 = new QLabel(groupBox_4); + label_26->setObjectName(QStringLiteral("label_26")); + + gridLayout_5->addWidget(label_26, 0, 2, 1, 1); + + comboBox_Co4 = new QComboBox(groupBox_4); + comboBox_Co4->setObjectName(QStringLiteral("comboBox_Co4")); + + gridLayout_5->addWidget(comboBox_Co4, 0, 3, 1, 1); + + label_27 = new QLabel(groupBox_4); + label_27->setObjectName(QStringLiteral("label_27")); + + gridLayout_5->addWidget(label_27, 1, 0, 1, 1); + + lineEdit_Vb4 = new QLineEdit(groupBox_4); + lineEdit_Vb4->setObjectName(QStringLiteral("lineEdit_Vb4")); + + gridLayout_5->addWidget(lineEdit_Vb4, 1, 1, 1, 1); + + label_28 = new QLabel(groupBox_4); + label_28->setObjectName(QStringLiteral("label_28")); + + gridLayout_5->addWidget(label_28, 1, 2, 1, 1); + + lineEdit_Vt4 = new QLineEdit(groupBox_4); + lineEdit_Vt4->setObjectName(QStringLiteral("lineEdit_Vt4")); + + gridLayout_5->addWidget(lineEdit_Vt4, 1, 3, 1, 1); + + label_29 = new QLabel(groupBox_4); + label_29->setObjectName(QStringLiteral("label_29")); + + gridLayout_5->addWidget(label_29, 2, 0, 1, 1); + + lineEdit_I4 = new QLineEdit(groupBox_4); + lineEdit_I4->setObjectName(QStringLiteral("lineEdit_I4")); + + gridLayout_5->addWidget(lineEdit_I4, 2, 1, 1, 1); + + label_30 = new QLabel(groupBox_4); + label_30->setObjectName(QStringLiteral("label_30")); + + gridLayout_5->addWidget(label_30, 2, 2, 1, 1); + + lineEdit_t4 = new QLineEdit(groupBox_4); + lineEdit_t4->setObjectName(QStringLiteral("lineEdit_t4")); + + gridLayout_5->addWidget(lineEdit_t4, 2, 3, 1, 1); + + label_31 = new QLabel(groupBox_4); + label_31->setObjectName(QStringLiteral("label_31")); + + gridLayout_5->addWidget(label_31, 3, 0, 1, 1); + + lineEdit_II4 = new QLineEdit(groupBox_4); + lineEdit_II4->setObjectName(QStringLiteral("lineEdit_II4")); + + gridLayout_5->addWidget(lineEdit_II4, 3, 1, 1, 1); + + label_32 = new QLabel(groupBox_4); + label_32->setObjectName(QStringLiteral("label_32")); + + gridLayout_5->addWidget(label_32, 3, 2, 1, 1); + + lineEdit_tt4 = new QLineEdit(groupBox_4); + lineEdit_tt4->setObjectName(QStringLiteral("lineEdit_tt4")); + + gridLayout_5->addWidget(lineEdit_tt4, 3, 3, 1, 1); + + + gridLayout_8->addWidget(groupBox_4, 5, 0, 1, 1); + + groupBox_5 = new QGroupBox(frame); + groupBox_5->setObjectName(QStringLiteral("groupBox_5")); + gridLayout_6 = new QGridLayout(groupBox_5); + gridLayout_6->setSpacing(6); + gridLayout_6->setContentsMargins(11, 11, 11, 11); + gridLayout_6->setObjectName(QStringLiteral("gridLayout_6")); + gridLayout_6->setVerticalSpacing(2); + label_33 = new QLabel(groupBox_5); + label_33->setObjectName(QStringLiteral("label_33")); + + gridLayout_6->addWidget(label_33, 0, 0, 1, 1); + + lineEdit_CurName5 = new QLineEdit(groupBox_5); + lineEdit_CurName5->setObjectName(QStringLiteral("lineEdit_CurName5")); + + gridLayout_6->addWidget(lineEdit_CurName5, 0, 1, 1, 1); + + label_34 = new QLabel(groupBox_5); + label_34->setObjectName(QStringLiteral("label_34")); + + gridLayout_6->addWidget(label_34, 0, 2, 1, 1); + + comboBox_Co5 = new QComboBox(groupBox_5); + comboBox_Co5->setObjectName(QStringLiteral("comboBox_Co5")); + + gridLayout_6->addWidget(comboBox_Co5, 0, 3, 1, 1); + + label_35 = new QLabel(groupBox_5); + label_35->setObjectName(QStringLiteral("label_35")); + + gridLayout_6->addWidget(label_35, 1, 0, 1, 1); + + lineEdit_Vb5 = new QLineEdit(groupBox_5); + lineEdit_Vb5->setObjectName(QStringLiteral("lineEdit_Vb5")); + + gridLayout_6->addWidget(lineEdit_Vb5, 1, 1, 1, 1); + + label_36 = new QLabel(groupBox_5); + label_36->setObjectName(QStringLiteral("label_36")); + + gridLayout_6->addWidget(label_36, 1, 2, 1, 1); + + lineEdit_Vt5 = new QLineEdit(groupBox_5); + lineEdit_Vt5->setObjectName(QStringLiteral("lineEdit_Vt5")); + + gridLayout_6->addWidget(lineEdit_Vt5, 1, 3, 1, 1); + + label_37 = new QLabel(groupBox_5); + label_37->setObjectName(QStringLiteral("label_37")); + + gridLayout_6->addWidget(label_37, 2, 0, 1, 1); + + lineEdit_I5 = new QLineEdit(groupBox_5); + lineEdit_I5->setObjectName(QStringLiteral("lineEdit_I5")); + + gridLayout_6->addWidget(lineEdit_I5, 2, 1, 1, 1); + + label_38 = new QLabel(groupBox_5); + label_38->setObjectName(QStringLiteral("label_38")); + + gridLayout_6->addWidget(label_38, 2, 2, 1, 1); + + lineEdit_t5 = new QLineEdit(groupBox_5); + lineEdit_t5->setObjectName(QStringLiteral("lineEdit_t5")); + + gridLayout_6->addWidget(lineEdit_t5, 2, 3, 1, 1); + + label_39 = new QLabel(groupBox_5); + label_39->setObjectName(QStringLiteral("label_39")); + + gridLayout_6->addWidget(label_39, 3, 0, 1, 1); + + lineEdit_II5 = new QLineEdit(groupBox_5); + lineEdit_II5->setObjectName(QStringLiteral("lineEdit_II5")); + + gridLayout_6->addWidget(lineEdit_II5, 3, 1, 1, 1); + + label_40 = new QLabel(groupBox_5); + label_40->setObjectName(QStringLiteral("label_40")); + + gridLayout_6->addWidget(label_40, 3, 2, 1, 1); + + lineEdit_tt5 = new QLineEdit(groupBox_5); + lineEdit_tt5->setObjectName(QStringLiteral("lineEdit_tt5")); + + gridLayout_6->addWidget(lineEdit_tt5, 3, 3, 1, 1); + + + gridLayout_8->addWidget(groupBox_5, 6, 0, 1, 1); + + groupBox_6 = new QGroupBox(frame); + groupBox_6->setObjectName(QStringLiteral("groupBox_6")); + gridLayout_7 = new QGridLayout(groupBox_6); + gridLayout_7->setSpacing(6); + gridLayout_7->setContentsMargins(11, 11, 11, 11); + gridLayout_7->setObjectName(QStringLiteral("gridLayout_7")); + gridLayout_7->setVerticalSpacing(2); + label_41 = new QLabel(groupBox_6); + label_41->setObjectName(QStringLiteral("label_41")); + + gridLayout_7->addWidget(label_41, 0, 0, 1, 1); + + lineEdit_CurName6 = new QLineEdit(groupBox_6); + lineEdit_CurName6->setObjectName(QStringLiteral("lineEdit_CurName6")); + + gridLayout_7->addWidget(lineEdit_CurName6, 0, 1, 1, 1); + + label_42 = new QLabel(groupBox_6); + label_42->setObjectName(QStringLiteral("label_42")); + + gridLayout_7->addWidget(label_42, 0, 2, 1, 1); + + comboBox_Co6 = new QComboBox(groupBox_6); + comboBox_Co6->setObjectName(QStringLiteral("comboBox_Co6")); + + gridLayout_7->addWidget(comboBox_Co6, 0, 3, 1, 1); + + label_43 = new QLabel(groupBox_6); + label_43->setObjectName(QStringLiteral("label_43")); + + gridLayout_7->addWidget(label_43, 1, 0, 1, 1); + + lineEdit_Vb6 = new QLineEdit(groupBox_6); + lineEdit_Vb6->setObjectName(QStringLiteral("lineEdit_Vb6")); + + gridLayout_7->addWidget(lineEdit_Vb6, 1, 1, 1, 1); + + label_44 = new QLabel(groupBox_6); + label_44->setObjectName(QStringLiteral("label_44")); + + gridLayout_7->addWidget(label_44, 1, 2, 1, 1); + + lineEdit_Vt6 = new QLineEdit(groupBox_6); + lineEdit_Vt6->setObjectName(QStringLiteral("lineEdit_Vt6")); + + gridLayout_7->addWidget(lineEdit_Vt6, 1, 3, 1, 1); + + label_45 = new QLabel(groupBox_6); + label_45->setObjectName(QStringLiteral("label_45")); + + gridLayout_7->addWidget(label_45, 2, 0, 1, 1); + + lineEdit_I6 = new QLineEdit(groupBox_6); + lineEdit_I6->setObjectName(QStringLiteral("lineEdit_I6")); + + gridLayout_7->addWidget(lineEdit_I6, 2, 1, 1, 1); + + label_46 = new QLabel(groupBox_6); + label_46->setObjectName(QStringLiteral("label_46")); + + gridLayout_7->addWidget(label_46, 2, 2, 1, 1); + + lineEdit_t6 = new QLineEdit(groupBox_6); + lineEdit_t6->setObjectName(QStringLiteral("lineEdit_t6")); + + gridLayout_7->addWidget(lineEdit_t6, 2, 3, 1, 1); + + label_47 = new QLabel(groupBox_6); + label_47->setObjectName(QStringLiteral("label_47")); + + gridLayout_7->addWidget(label_47, 3, 0, 1, 1); + + lineEdit_II6 = new QLineEdit(groupBox_6); + lineEdit_II6->setObjectName(QStringLiteral("lineEdit_II6")); + + gridLayout_7->addWidget(lineEdit_II6, 3, 1, 1, 1); + + label_48 = new QLabel(groupBox_6); + label_48->setObjectName(QStringLiteral("label_48")); + + gridLayout_7->addWidget(label_48, 3, 2, 1, 1); + + lineEdit_tt6 = new QLineEdit(groupBox_6); + lineEdit_tt6->setObjectName(QStringLiteral("lineEdit_tt6")); + + gridLayout_7->addWidget(lineEdit_tt6, 3, 3, 1, 1); + + + gridLayout_8->addWidget(groupBox_6, 7, 0, 1, 1); + + + gridLayout_3->addWidget(frame, 0, 1, 1, 1); + + widget = new QWidget(centralWidget); + widget->setObjectName(QStringLiteral("widget")); + + gridLayout_3->addWidget(widget, 0, 0, 1, 1); + + MainWindow->setCentralWidget(centralWidget); + + retranslateUi(MainWindow); + + QMetaObject::connectSlotsByName(MainWindow); + } // setupUi + + void retranslateUi(QMainWindow *MainWindow) + { + MainWindow->setWindowTitle(QApplication::translate("MainWindow", "\345\215\217\350\260\203\346\233\262\347\272\277", Q_NULLPTR)); + pushButton->setText(QApplication::translate("MainWindow", "\351\200\211\346\213\251\346\226\207\344\273\266", Q_NULLPTR)); + pushButton_create->setText(QApplication::translate("MainWindow", "\347\224\237\346\210\220\346\233\262\347\272\277", Q_NULLPTR)); + pushButton_save->setText(QApplication::translate("MainWindow", "\344\277\235\345\255\230\346\250\241\346\235\277", Q_NULLPTR)); + groupBox->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2071", Q_NULLPTR)); + label->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); + label_2->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); + comboBox_Co1->clear(); + comboBox_Co1->insertItems(0, QStringList() + << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) + ); + label_3->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); + label_4->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); + label_5->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); + label_6->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); + label_7->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); + label_8->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); + groupBox_2->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2072", Q_NULLPTR)); + label_9->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); + label_10->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); + comboBox_Co2->clear(); + comboBox_Co2->insertItems(0, QStringList() + << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) + ); + label_11->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); + label_12->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); + label_13->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); + label_14->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); + label_15->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); + label_16->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); + groupBox_3->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2073", Q_NULLPTR)); + label_17->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); + label_18->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); + comboBox_Co3->clear(); + comboBox_Co3->insertItems(0, QStringList() + << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) + ); + label_19->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); + label_20->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); + label_21->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); + label_22->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); + label_23->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); + label_24->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); + groupBox_4->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2074", Q_NULLPTR)); + label_25->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); + label_26->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); + comboBox_Co4->clear(); + comboBox_Co4->insertItems(0, QStringList() + << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) + ); + label_27->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); + label_28->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); + label_29->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); + label_30->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); + label_31->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); + label_32->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); + groupBox_5->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2075", Q_NULLPTR)); + label_33->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); + label_34->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); + comboBox_Co5->clear(); + comboBox_Co5->insertItems(0, QStringList() + << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) + ); + label_35->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); + label_36->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); + label_37->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); + label_38->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); + label_39->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); + label_40->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); + groupBox_6->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\2076", Q_NULLPTR)); + label_41->setText(QApplication::translate("MainWindow", "\346\233\262\347\272\277\345\220\215\347\247\260", Q_NULLPTR)); + label_42->setText(QApplication::translate("MainWindow", "CO\346\233\262\347\272\277", Q_NULLPTR)); + comboBox_Co6->clear(); + comboBox_Co6->insertItems(0, QStringList() + << QApplication::translate("MainWindow", "EIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "SIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "VIT", Q_NULLPTR) + << QApplication::translate("MainWindow", "UIT", Q_NULLPTR) + ); + label_43->setText(QApplication::translate("MainWindow", "Vb(\345\237\272\345\207\206)", Q_NULLPTR)); + label_44->setText(QApplication::translate("MainWindow", "Vt(\346\215\242\347\256\227)", Q_NULLPTR)); + label_45->setText(QApplication::translate("MainWindow", "I>", Q_NULLPTR)); + label_46->setText(QApplication::translate("MainWindow", "t>", Q_NULLPTR)); + label_47->setText(QApplication::translate("MainWindow", "I>>", Q_NULLPTR)); + label_48->setText(QApplication::translate("MainWindow", "t>>", Q_NULLPTR)); + } // retranslateUi + +}; + +namespace Ui { + class MainWindow: public Ui_MainWindow {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_MAINWINDOW_H diff --git a/product/src/gui/plugin/IpcPlusWidget/CCamInfo.cpp b/product/src/gui/plugin/IpcPlusWidget/CCamInfo.cpp index fa66ed1e..7c3f5b60 100644 --- a/product/src/gui/plugin/IpcPlusWidget/CCamInfo.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/CCamInfo.cpp @@ -1,358 +1,358 @@ -#include "CCamInfo.h" -#include "OnvifLibs/onvif.h" -#include -#include "CPresetInfo.h" -#include -CCamInfo::CCamInfo() -{ - -} -std::string CCamInfo::pointTag() const -{ - return m_pointTag; -} - -void CCamInfo::setPointTag(const std::string &pointTag) -{ - m_pointTag = pointTag; -} - -std::string CCamInfo::camTag() const -{ - return m_camTag; -} - -void CCamInfo::setCamTag(const std::string &camTag) -{ - m_camTag = camTag; -} - -std::string CCamInfo::presetTag() const -{ - return m_presetTag; -} - -void CCamInfo::setPresetTag(const std::string &presetTag) -{ - m_presetTag = presetTag; -} - - - - -std::string CCamInfo::ip() const -{ - return m_ip; -} - -void CCamInfo::setIp(const std::string &ip) -{ - m_ip = ip; -} - -std::string CCamInfo::description() const -{ - return m_description; -} - -void CCamInfo::setDescription(const std::string &description) -{ - m_description = description; -} - -std::string CCamInfo::username() const -{ - return m_username; -} - -void CCamInfo::setUsername(const std::string &username) -{ - m_username = username; -} - -std::string CCamInfo::password() const -{ - return m_password; -} - -void CCamInfo::setPassword(const std::string &password) -{ - m_password = password; -} - -std::string CCamInfo::serviceAddr() const -{ - return m_serviceAddr; -} - -void CCamInfo::setServiceAddr(const std::string &serviceAddr) -{ - m_serviceAddr = serviceAddr; -} - -std::string CCamInfo::mediaAddr() const -{ - return m_mediaAddr; -} - -void CCamInfo::setMediaAddr(const std::string &mediaAddr) -{ - m_mediaAddr = mediaAddr; -} - -std::string CCamInfo::ptzAddr() const -{ - return m_ptzAddr; -} - -void CCamInfo::setPtzAddr(const std::string &ptzAddr) -{ - m_ptzAddr = ptzAddr; -} - -std::string CCamInfo::recordSearchAddr() const -{ - return m_recordSearchAddr; -} - -void CCamInfo::setRecordSearchAddr(const std::string &recordSearchAddr) -{ - m_recordSearchAddr = recordSearchAddr; -} - -std::string CCamInfo::replayAddr() const -{ - return m_replayAddr; -} - -void CCamInfo::setReplayAddr(const std::string &replayAddr) -{ - m_replayAddr = replayAddr; -} - -bool CCamInfo::isStreamEnabled() const -{ - return m_isStreamEnabled; -} - -void CCamInfo::setIsStreamEnabled(bool isStreamEnabled) -{ - m_isStreamEnabled = isStreamEnabled; -} - -bool CCamInfo::isPtzEnabled() const -{ - return m_isPtzEnabled; -} - -void CCamInfo::setIsPtzEnabled(bool isPtzEnabled) -{ - m_isPtzEnabled = isPtzEnabled; -} - -bool CCamInfo::isReplayEnabled() const -{ - return m_isReplayEnabled; -} - -void CCamInfo::setIsReplayEnabled(bool isReplayEnabled) -{ - m_isReplayEnabled = isReplayEnabled; -} - -std::vector CCamInfo::presets() const -{ - return m_presets; -} - -void CCamInfo::setPresets(const std::vector &presets) -{ - m_presets = presets; -} - -void CCamInfo::addPreset(const std::string &presetTag_, const std::string &presetToken_, const std::string &presetDesc_) -{ - m_presets.push_back(CPresetInfo(presetTag_,presetToken_,presetDesc_)); -} - -bool CCamInfo::getPresetDesc(const std::string &preset_tag, std::string &outDesc) -{ - for(int i = 0; i < (int)m_presets.size(); i++) - { - if(m_presets.at(i).presetTag == preset_tag) - { - outDesc = m_presets.at(i).presetDesc; - return true; - } - } - return false; -} - -bool CCamInfo::getPresetToken(const std::string &preset_tag, std::string &outToken) -{ - for(int i = 0; i < (int)m_presets.size(); i++) - { - if(m_presets.at(i).presetTag == preset_tag) - { - outToken = m_presets.at(i).presetToken; - return true; - } - } - return false; -} - -int CCamInfo::getChan_no() const -{ - return m_chan_no; -} - -void CCamInfo::setChan_no(int chan_no) -{ - m_chan_no = chan_no; -} - -int CCamInfo::getOnvifArgs() -{ - - - - /*** - * 大概想一下,应该做什么。 - * 最终目的,填充streamRtspAddr(直播用)和replayRtspAddr(回放用)和profileToken(ptz用,搭配ptzxaddr) 和能力使能 - * 1. 生成onvif的device_address - * 2. 获取能力 capabilities,根据能力填充使能信息 - * 若MediaXAddr为空,则无法直播 - * 若PTZXAddr为空,则无法进行ptz控制 - * 若SearchXAddr和ReplayXAddr有一为空,则无法进行回放 - * 3. 填充直播相关的东西 - * 3.1 获取profile - * 3.2 获取直播地址 - * 4. 获取录播相关的东西 - * 4.1 获取录播recordingtoken - * 4.2 获取回放地址 - * - * - */ - - LOGINFO("In getOnvifArgs() start getCapabilities"); - std::string service_addr = std::string("http://") + this->ip() + "/onvif/device_service"; - this->setServiceAddr(service_addr); - - //=============能力相关================= - XAddr addr; - int result = 0; - result =Onvif::getCapabilities(service_addr,addr); - - if(addr.MediaXAddr == "") - { - this->setIsStreamEnabled(false); - } - - if(addr.PTZXAddr == "") - { - this->setIsPtzEnabled(false); - } - this->setPtzAddr(addr.PTZXAddr); - - if(addr.ReplayXAddr == "" || addr.SearchXAddr == "") - { - this->setIsReplayEnabled(false); - } - //=============能力相关================= - - LOGINFO("In getOnvifArgs() start getStreamInfo"); - //=============直播相关==================== - if(addr.MediaXAddr != "") - { - if(Onvif::getProfileTokens(addr.MediaXAddr,this->getChan_no(),this->username(),this->password(),this->m_mediaProfileToken) != Onvif::NoError) - { - this->setIsStreamEnabled(false); - } - else - { - if(Onvif::getStreamUrl(addr.MediaXAddr,this->m_mediaProfileToken,this->username(),this->password(),this->m_streamRtspAddr) != Onvif::NoError) - { - this->setIsStreamEnabled(false); - } - else - { - this->m_streamRtspAddr = this->m_streamRtspAddr.substr(0,7) + this->username() + ":" + this->password() + "@" + this->m_streamRtspAddr.substr(7); - } - } - } - //=============直播相关==================== - - LOGINFO("In getOnvifArgs() start getReplayInfo"); - //=============回放相关==================== - - if(addr.ReplayXAddr != "" && addr.SearchXAddr != "") - { - if(Onvif::getRecordToken(addr.SearchXAddr,this->getChan_no(),this->username(),this->password(),this->m_recordToken) != Onvif::NoError) - { - this->setIsReplayEnabled(false); - } - else - { - if(Onvif::getReplayUrl(addr.ReplayXAddr,this->m_recordToken,this->username(),this->password(),this->m_replayRtspAddr) != Onvif::NoError) - { - this->setIsReplayEnabled(false); - } - else - { - this->m_replayRtspAddr = this->m_replayRtspAddr.substr(0,7) + this->username() + ":" + this->password() + "@" +this->m_replayRtspAddr.substr(7); - } - } - } - //=============回放相关==================== - return result; -} - -std::string CCamInfo::getStreamRtspAddr() const -{ - return m_streamRtspAddr; -} - -std::string CCamInfo::getReplayRtspAddr() const -{ - return m_replayRtspAddr; -} - -bool CCamInfo::continuousMove(int cmd, double cmd_speed) -{ - if(!m_isPtzEnabled) - return false; - - if(Onvif::continuousMove(this->ptzAddr(),this->m_mediaProfileToken,this->username(),this->password(),cmd,cmd_speed) == -1) - { - return false; - } - return true; -} - -bool CCamInfo::stopMove() -{ - if(!m_isPtzEnabled) - return false; - - if(Onvif::stopMove(this->ptzAddr(),this->m_mediaProfileToken,this->username(),this->password()) == -1) - { - return false; - } - return true; -} - -bool CCamInfo::gotoPreset(const std::string &preset_tag) -{ - if(!m_isPtzEnabled) - return false; - - std::string preset_token; - if(!getPresetToken(preset_tag,preset_token)) - return false; - if(Onvif::gotoPreset(this->ptzAddr(),this->m_mediaProfileToken,preset_token,this->username(),this->password()) == -1) - { - return false; - } - return true; -} - +#include "CCamInfo.h" +#include "OnvifLibs/onvif.h" +#include +#include "CPresetInfo.h" +#include +CCamInfo::CCamInfo() +{ + +} +std::string CCamInfo::pointTag() const +{ + return m_pointTag; +} + +void CCamInfo::setPointTag(const std::string &pointTag) +{ + m_pointTag = pointTag; +} + +std::string CCamInfo::camTag() const +{ + return m_camTag; +} + +void CCamInfo::setCamTag(const std::string &camTag) +{ + m_camTag = camTag; +} + +std::string CCamInfo::presetTag() const +{ + return m_presetTag; +} + +void CCamInfo::setPresetTag(const std::string &presetTag) +{ + m_presetTag = presetTag; +} + + + + +std::string CCamInfo::ip() const +{ + return m_ip; +} + +void CCamInfo::setIp(const std::string &ip) +{ + m_ip = ip; +} + +std::string CCamInfo::description() const +{ + return m_description; +} + +void CCamInfo::setDescription(const std::string &description) +{ + m_description = description; +} + +std::string CCamInfo::username() const +{ + return m_username; +} + +void CCamInfo::setUsername(const std::string &username) +{ + m_username = username; +} + +std::string CCamInfo::password() const +{ + return m_password; +} + +void CCamInfo::setPassword(const std::string &password) +{ + m_password = password; +} + +std::string CCamInfo::serviceAddr() const +{ + return m_serviceAddr; +} + +void CCamInfo::setServiceAddr(const std::string &serviceAddr) +{ + m_serviceAddr = serviceAddr; +} + +std::string CCamInfo::mediaAddr() const +{ + return m_mediaAddr; +} + +void CCamInfo::setMediaAddr(const std::string &mediaAddr) +{ + m_mediaAddr = mediaAddr; +} + +std::string CCamInfo::ptzAddr() const +{ + return m_ptzAddr; +} + +void CCamInfo::setPtzAddr(const std::string &ptzAddr) +{ + m_ptzAddr = ptzAddr; +} + +std::string CCamInfo::recordSearchAddr() const +{ + return m_recordSearchAddr; +} + +void CCamInfo::setRecordSearchAddr(const std::string &recordSearchAddr) +{ + m_recordSearchAddr = recordSearchAddr; +} + +std::string CCamInfo::replayAddr() const +{ + return m_replayAddr; +} + +void CCamInfo::setReplayAddr(const std::string &replayAddr) +{ + m_replayAddr = replayAddr; +} + +bool CCamInfo::isStreamEnabled() const +{ + return m_isStreamEnabled; +} + +void CCamInfo::setIsStreamEnabled(bool isStreamEnabled) +{ + m_isStreamEnabled = isStreamEnabled; +} + +bool CCamInfo::isPtzEnabled() const +{ + return m_isPtzEnabled; +} + +void CCamInfo::setIsPtzEnabled(bool isPtzEnabled) +{ + m_isPtzEnabled = isPtzEnabled; +} + +bool CCamInfo::isReplayEnabled() const +{ + return m_isReplayEnabled; +} + +void CCamInfo::setIsReplayEnabled(bool isReplayEnabled) +{ + m_isReplayEnabled = isReplayEnabled; +} + +std::vector CCamInfo::presets() const +{ + return m_presets; +} + +void CCamInfo::setPresets(const std::vector &presets) +{ + m_presets = presets; +} + +void CCamInfo::addPreset(const std::string &presetTag_, const std::string &presetToken_, const std::string &presetDesc_) +{ + m_presets.push_back(CPresetInfo(presetTag_,presetToken_,presetDesc_)); +} + +bool CCamInfo::getPresetDesc(const std::string &preset_tag, std::string &outDesc) +{ + for(int i = 0; i < (int)m_presets.size(); i++) + { + if(m_presets.at(i).presetTag == preset_tag) + { + outDesc = m_presets.at(i).presetDesc; + return true; + } + } + return false; +} + +bool CCamInfo::getPresetToken(const std::string &preset_tag, std::string &outToken) +{ + for(int i = 0; i < (int)m_presets.size(); i++) + { + if(m_presets.at(i).presetTag == preset_tag) + { + outToken = m_presets.at(i).presetToken; + return true; + } + } + return false; +} + +int CCamInfo::getChan_no() const +{ + return m_chan_no; +} + +void CCamInfo::setChan_no(int chan_no) +{ + m_chan_no = chan_no; +} + +int CCamInfo::getOnvifArgs() +{ + + + + /*** + * 大概想一下,应该做什么。 + * 最终目的,填充streamRtspAddr(直播用)和replayRtspAddr(回放用)和profileToken(ptz用,搭配ptzxaddr) 和能力使能 + * 1. 生成onvif的device_address + * 2. 获取能力 capabilities,根据能力填充使能信息 + * 若MediaXAddr为空,则无法直播 + * 若PTZXAddr为空,则无法进行ptz控制 + * 若SearchXAddr和ReplayXAddr有一为空,则无法进行回放 + * 3. 填充直播相关的东西 + * 3.1 获取profile + * 3.2 获取直播地址 + * 4. 获取录播相关的东西 + * 4.1 获取录播recordingtoken + * 4.2 获取回放地址 + * + * + */ + + LOGINFO("In getOnvifArgs() start getCapabilities"); + std::string service_addr = std::string("http://") + this->ip() + "/onvif/device_service"; + this->setServiceAddr(service_addr); + + //=============能力相关================= + XAddr addr; + int result = 0; + result =Onvif::getCapabilities(service_addr,addr); + + if(addr.MediaXAddr == "") + { + this->setIsStreamEnabled(false); + } + + if(addr.PTZXAddr == "") + { + this->setIsPtzEnabled(false); + } + this->setPtzAddr(addr.PTZXAddr); + + if(addr.ReplayXAddr == "" || addr.SearchXAddr == "") + { + this->setIsReplayEnabled(false); + } + //=============能力相关================= + + LOGINFO("In getOnvifArgs() start getStreamInfo"); + //=============直播相关==================== + if(addr.MediaXAddr != "") + { + if(Onvif::getProfileTokens(addr.MediaXAddr,this->getChan_no(),this->username(),this->password(),this->m_mediaProfileToken) != Onvif::NoError) + { + this->setIsStreamEnabled(false); + } + else + { + if(Onvif::getStreamUrl(addr.MediaXAddr,this->m_mediaProfileToken,this->username(),this->password(),this->m_streamRtspAddr) != Onvif::NoError) + { + this->setIsStreamEnabled(false); + } + else + { + this->m_streamRtspAddr = this->m_streamRtspAddr.substr(0,7) + this->username() + ":" + this->password() + "@" + this->m_streamRtspAddr.substr(7); + } + } + } + //=============直播相关==================== + + LOGINFO("In getOnvifArgs() start getReplayInfo"); + //=============回放相关==================== + + if(addr.ReplayXAddr != "" && addr.SearchXAddr != "") + { + if(Onvif::getRecordToken(addr.SearchXAddr,this->getChan_no(),this->username(),this->password(),this->m_recordToken) != Onvif::NoError) + { + this->setIsReplayEnabled(false); + } + else + { + if(Onvif::getReplayUrl(addr.ReplayXAddr,this->m_recordToken,this->username(),this->password(),this->m_replayRtspAddr) != Onvif::NoError) + { + this->setIsReplayEnabled(false); + } + else + { + this->m_replayRtspAddr = this->m_replayRtspAddr.substr(0,7) + this->username() + ":" + this->password() + "@" +this->m_replayRtspAddr.substr(7); + } + } + } + //=============回放相关==================== + return result; +} + +std::string CCamInfo::getStreamRtspAddr() const +{ + return m_streamRtspAddr; +} + +std::string CCamInfo::getReplayRtspAddr() const +{ + return m_replayRtspAddr; +} + +bool CCamInfo::continuousMove(int cmd, double cmd_speed) +{ + if(!m_isPtzEnabled) + return false; + + if(Onvif::continuousMove(this->ptzAddr(),this->m_mediaProfileToken,this->username(),this->password(),cmd,cmd_speed) == -1) + { + return false; + } + return true; +} + +bool CCamInfo::stopMove() +{ + if(!m_isPtzEnabled) + return false; + + if(Onvif::stopMove(this->ptzAddr(),this->m_mediaProfileToken,this->username(),this->password()) == -1) + { + return false; + } + return true; +} + +bool CCamInfo::gotoPreset(const std::string &preset_tag) +{ + if(!m_isPtzEnabled) + return false; + + std::string preset_token; + if(!getPresetToken(preset_tag,preset_token)) + return false; + if(Onvif::gotoPreset(this->ptzAddr(),this->m_mediaProfileToken,preset_token,this->username(),this->password()) == -1) + { + return false; + } + return true; +} + diff --git a/product/src/gui/plugin/IpcPlusWidget/CCamInfo.h b/product/src/gui/plugin/IpcPlusWidget/CCamInfo.h index daf0c68e..4b557197 100644 --- a/product/src/gui/plugin/IpcPlusWidget/CCamInfo.h +++ b/product/src/gui/plugin/IpcPlusWidget/CCamInfo.h @@ -1,127 +1,127 @@ -#ifndef CCAMINFO_H -#define CCAMINFO_H - -#include -#include -#include -#include "CPresetInfo.h" -class CCamInfo -{ -public: - enum PtzCmd { - Left, - Right, - //open/read/seek network stream error. value must be less then ResourceError because of correct_error_by_ffmpeg - NetworkError, // all above and before NoError are NetworkError - - }; - - - CCamInfo(); - - std::string pointTag() const; - void setPointTag(const std::string &pointTag); - - std::string camTag() const; - void setCamTag(const std::string &camTag); - - std::string presetTag() const; - void setPresetTag(const std::string &presetTag); - - std::string ip() const; - void setIp(const std::string &ip); - - int getChan_no() const; - void setChan_no(int chan_no); - - std::string description() const; - void setDescription(const std::string &description); - - std::string username() const; - void setUsername(const std::string &username); - - std::string password() const; - void setPassword(const std::string &password); - - std::string serviceAddr() const; - - std::string mediaAddr() const; - void setMediaAddr(const std::string &mediaAddr); - - std::string ptzAddr() const; - void setPtzAddr(const std::string &ptzAddr); - - std::string recordSearchAddr() const; - void setRecordSearchAddr(const std::string &recordSearchAddr); - - std::string replayAddr() const; - void setReplayAddr(const std::string &replayAddr); - - bool isStreamEnabled() const; - void setIsStreamEnabled(bool isStreamEnabled); - - bool isPtzEnabled() const; - void setIsPtzEnabled(bool isPtzEnabled); - - bool isReplayEnabled() const; - void setIsReplayEnabled(bool isReplayEnabled); - - std::vector presets() const; - void setPresets(const std::vector &presets); - void addPreset(const std::string &presetTag_, - const std::string &presetToken_, - const std::string &presetDesc_); - - bool getPresetToken(const std::string &preset_tag, std::string &outToken); - bool getPresetDesc(const std::string &preset_tag, std::string &outDesc); - //< onvif 相关的接口 - /** - * @brief getOnvifArgs 通过onvif获取相关的参数 - * - * 参数 m_streamRtspAddr和m_replayRtspAddr以及m_ptzAddr,和直播,回放和控制使能相关的信息。 - * @return 0 -成功 1-失败 - */ - int getOnvifArgs(); - - std::string getStreamRtspAddr() const; - std::string getReplayRtspAddr() const; - - bool continuousMove(int cmd, double cmd_speed); - bool stopMove(); - bool gotoPreset(const std::string & preset_tag); - - - -private: - void setServiceAddr(const std::string &serviceAddr); - - - std::string m_pointTag; - std::string m_camTag; - std::string m_presetTag; - std::vector m_presets; - int m_chan_no; - std::string m_ip; - std::string m_description; - std::string m_username; - std::string m_password; - - std::string m_serviceAddr; - std::string m_mediaAddr; - std::string m_ptzAddr; - std::string m_recordSearchAddr; - std::string m_replayAddr; - std::string m_mediaProfileToken; - std::string m_recordToken; - - std::string m_streamRtspAddr; - std::string m_replayRtspAddr; - - - bool m_isStreamEnabled= true; - bool m_isPtzEnabled=true; - bool m_isReplayEnabled=true; - -}; - -#endif // CCAMINFO_H +#ifndef CCAMINFO_H +#define CCAMINFO_H + +#include +#include +#include +#include "CPresetInfo.h" +class CCamInfo +{ +public: + enum PtzCmd { + Left, + Right, + //open/read/seek network stream error. value must be less then ResourceError because of correct_error_by_ffmpeg + NetworkError, // all above and before NoError are NetworkError + + }; + + + CCamInfo(); + + std::string pointTag() const; + void setPointTag(const std::string &pointTag); + + std::string camTag() const; + void setCamTag(const std::string &camTag); + + std::string presetTag() const; + void setPresetTag(const std::string &presetTag); + + std::string ip() const; + void setIp(const std::string &ip); + + int getChan_no() const; + void setChan_no(int chan_no); + + std::string description() const; + void setDescription(const std::string &description); + + std::string username() const; + void setUsername(const std::string &username); + + std::string password() const; + void setPassword(const std::string &password); + + std::string serviceAddr() const; + + std::string mediaAddr() const; + void setMediaAddr(const std::string &mediaAddr); + + std::string ptzAddr() const; + void setPtzAddr(const std::string &ptzAddr); + + std::string recordSearchAddr() const; + void setRecordSearchAddr(const std::string &recordSearchAddr); + + std::string replayAddr() const; + void setReplayAddr(const std::string &replayAddr); + + bool isStreamEnabled() const; + void setIsStreamEnabled(bool isStreamEnabled); + + bool isPtzEnabled() const; + void setIsPtzEnabled(bool isPtzEnabled); + + bool isReplayEnabled() const; + void setIsReplayEnabled(bool isReplayEnabled); + + std::vector presets() const; + void setPresets(const std::vector &presets); + void addPreset(const std::string &presetTag_, + const std::string &presetToken_, + const std::string &presetDesc_); + + bool getPresetToken(const std::string &preset_tag, std::string &outToken); + bool getPresetDesc(const std::string &preset_tag, std::string &outDesc); + //< onvif 相关的接口 + /** + * @brief getOnvifArgs 通过onvif获取相关的参数 + * + * 参数 m_streamRtspAddr和m_replayRtspAddr以及m_ptzAddr,和直播,回放和控制使能相关的信息。 + * @return 0 -成功 1-失败 + */ + int getOnvifArgs(); + + std::string getStreamRtspAddr() const; + std::string getReplayRtspAddr() const; + + bool continuousMove(int cmd, double cmd_speed); + bool stopMove(); + bool gotoPreset(const std::string & preset_tag); + + + +private: + void setServiceAddr(const std::string &serviceAddr); + + + std::string m_pointTag; + std::string m_camTag; + std::string m_presetTag; + std::vector m_presets; + int m_chan_no; + std::string m_ip; + std::string m_description; + std::string m_username; + std::string m_password; + + std::string m_serviceAddr; + std::string m_mediaAddr; + std::string m_ptzAddr; + std::string m_recordSearchAddr; + std::string m_replayAddr; + std::string m_mediaProfileToken; + std::string m_recordToken; + + std::string m_streamRtspAddr; + std::string m_replayRtspAddr; + + + bool m_isStreamEnabled= true; + bool m_isPtzEnabled=true; + bool m_isReplayEnabled=true; + +}; + +#endif // CCAMINFO_H diff --git a/product/src/gui/plugin/IpcPlusWidget/COnvifOpt.cpp b/product/src/gui/plugin/IpcPlusWidget/COnvifOpt.cpp index b27de5c3..dd3cf570 100644 --- a/product/src/gui/plugin/IpcPlusWidget/COnvifOpt.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/COnvifOpt.cpp @@ -1,27 +1,27 @@ -#include "COnvifOpt.h" -#include "common/Common.h" -#include "pub_logger_api/logger.h" -COnvifOpt::COnvifOpt(QObject *parent) : QObject(parent) -{ - -} - -COnvifOpt::~COnvifOpt() -{ - LOGINFO(":~COnvifOpt()"); - -} - -void COnvifOpt::slotCamInfo(CCamInfo caminfo) -{ - LOGINFO("in slotCamInfo(),start getOnvifArgs()"); - if(kbdSuccess ==caminfo.getOnvifArgs()) - { - emit sigInitStream(caminfo,kbdSuccess); - }else - { - emit sigInitStream(caminfo,kbdFailed); - } - LOGINFO("sig sigInitStream emit"); - -} +#include "COnvifOpt.h" +#include "common/Common.h" +#include "pub_logger_api/logger.h" +COnvifOpt::COnvifOpt(QObject *parent) : QObject(parent) +{ + +} + +COnvifOpt::~COnvifOpt() +{ + LOGINFO(":~COnvifOpt()"); + +} + +void COnvifOpt::slotCamInfo(CCamInfo caminfo) +{ + LOGINFO("in slotCamInfo(),start getOnvifArgs()"); + if(kbdSuccess ==caminfo.getOnvifArgs()) + { + emit sigInitStream(caminfo,kbdSuccess); + }else + { + emit sigInitStream(caminfo,kbdFailed); + } + LOGINFO("sig sigInitStream emit"); + +} diff --git a/product/src/gui/plugin/IpcPlusWidget/COnvifOpt.h b/product/src/gui/plugin/IpcPlusWidget/COnvifOpt.h index fc1f0581..1af95489 100644 --- a/product/src/gui/plugin/IpcPlusWidget/COnvifOpt.h +++ b/product/src/gui/plugin/IpcPlusWidget/COnvifOpt.h @@ -1,18 +1,18 @@ -#ifndef CONVIFOPT_H -#define CONVIFOPT_H - -#include -#include "CCamInfo.h" -class COnvifOpt : public QObject -{ - Q_OBJECT -public: - explicit COnvifOpt(QObject *parent = nullptr); - ~COnvifOpt(); -signals: - void sigInitStream(CCamInfo caminfo,int result); -public slots: - void slotCamInfo(CCamInfo caminfo); -}; - -#endif // CONVIFOPT_H +#ifndef CONVIFOPT_H +#define CONVIFOPT_H + +#include +#include "CCamInfo.h" +class COnvifOpt : public QObject +{ + Q_OBJECT +public: + explicit COnvifOpt(QObject *parent = nullptr); + ~COnvifOpt(); +signals: + void sigInitStream(CCamInfo caminfo,int result); +public slots: + void slotCamInfo(CCamInfo caminfo); +}; + +#endif // CONVIFOPT_H diff --git a/product/src/gui/plugin/IpcPlusWidget/CPresetInfo.h b/product/src/gui/plugin/IpcPlusWidget/CPresetInfo.h index c626dd78..224411ae 100644 --- a/product/src/gui/plugin/IpcPlusWidget/CPresetInfo.h +++ b/product/src/gui/plugin/IpcPlusWidget/CPresetInfo.h @@ -1,23 +1,23 @@ -#ifndef CPRESETINFO_H -#define CPRESETINFO_H - -#include - -class CPresetInfo -{ -public: - CPresetInfo(const std::string &presetTag_, - const std::string &presetToken_, - const std::string &presetDesc_) - { - presetToken = presetToken_; - presetTag = presetTag_; - presetDesc = presetDesc_; - } - - std::string presetToken; - std::string presetTag; - std::string presetDesc; -}; - -#endif // CPRESETINFO_H +#ifndef CPRESETINFO_H +#define CPRESETINFO_H + +#include + +class CPresetInfo +{ +public: + CPresetInfo(const std::string &presetTag_, + const std::string &presetToken_, + const std::string &presetDesc_) + { + presetToken = presetToken_; + presetTag = presetTag_; + presetDesc = presetDesc_; + } + + std::string presetToken; + std::string presetTag; + std::string presetDesc; +}; + +#endif // CPRESETINFO_H diff --git a/product/src/gui/plugin/IpcPlusWidget/CRdbAccessUtilty.cpp b/product/src/gui/plugin/IpcPlusWidget/CRdbAccessUtilty.cpp index b04e0d44..0eaf3bfa 100644 --- a/product/src/gui/plugin/IpcPlusWidget/CRdbAccessUtilty.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/CRdbAccessUtilty.cpp @@ -1,187 +1,187 @@ -#include "CRdbAccessUtilty.h" -#include "pub_logger_api/logger.h" -#include -#include "Common.h" - -CRdbAccessUtilty::CRdbAccessUtilty(int nDomainId,int nAppId) -{ - m_pNetRdbApi = new kbd_dbms::CRdbNetApi(); - - m_pNetRdbApi->connect(nDomainId,nAppId); - -} - -CRdbAccessUtilty::~CRdbAccessUtilty() -{ - if(NULL != m_pNetRdbApi) - { - delete m_pNetRdbApi; - m_pNetRdbApi =NULL; - } -} - -bool CRdbAccessUtilty::getCamInfo(std::string pointtag, CCamInfo & outCamInfo) -{ - std::string pointtype,pointTagWithoutType; - if(splitTagName(pointtag,pointtype,pointTagWithoutType) == kbdFailed) - { - LOGERROR("分割标签名错误,标签名为[%s]",pointtag.c_str()); - return false; - } - - //< 查询点表,填充camera_id和preset_id - if(queryPointTable(pointTagWithoutType,pointtype,outCamInfo) == false) - { - LOGERROR("查询点表错误,标签名为[%s],表名[%s]",pointtag.c_str(),pointtype.c_str()); - return false; - } - - //< 查询点表,填充camera_id和preset_id - if(queryCameraInfoTable(outCamInfo) == false) - { - LOGERROR("查询cctv_camera_info表错误,标签名为[%s]",outCamInfo.camTag().c_str()); - return false; - } - - //< 查询点表,填充camera_id和preset_id - if(queryPresetTable(outCamInfo) == false) - { - LOGERROR("查询cctv_orientation表错误,标签名为[%s]",outCamInfo.camTag().c_str()); - return false; - } - - return true; -} - -int CRdbAccessUtilty::splitTagName(const std::string &inTag, std::string &outType, std::string &outTagName) -{ - std::size_t firstDotindex = inTag.find_first_of('.'); - if(firstDotindex == std::string::npos) - { - return kbdFailed; - } - - // 赋值表名; - if(inTag.substr(0,firstDotindex) == std::string("analog")) - { - outType = "analog"; - } - else if(inTag.substr(0,firstDotindex) == std::string("accuml")){ - outType = "accuml"; - } - else if(inTag.substr(0,firstDotindex) == std::string("digital")){ - outType = "digital"; - } - else if(inTag.substr(0,firstDotindex) == std::string("mix")){ - outType = "mix"; - }else{ - return kbdFailed; - } - - outTagName = inTag.substr(firstDotindex+1,inTag.size()); - return kbdSuccess; -} - -bool CRdbAccessUtilty::queryPointTable(const std::string &pointtag, const std::string &pointType, CCamInfo &outCamInfo) -{ - kbd_idlfile::RdbRet objRet; - std::vector vecKey,vecColumn; - vecKey.push_back(pointtag); - - vecColumn.push_back("camera_tag"); - vecColumn.push_back("preset_id"); - if(m_pNetRdbApi->queryByKey(pointType,vecKey,vecColumn,objRet) == false) - { - LOGERROR("queryPointTable 未查询到条目"); - return false; - } - - if(objRet.msgrecord_size() != 1 || objRet.msgrecord(0).msgvaluearray_size() != 2 ) - { - LOGERROR("queryPointTable 查询结果不对"); - return false; - } - - outCamInfo.setCamTag(objRet.msgrecord(0).msgvaluearray(0).strvalue()); - outCamInfo.setPresetTag(objRet.msgrecord(0).msgvaluearray(1).strvalue()); - return true; -} - -bool CRdbAccessUtilty::queryCameraInfoTable(CCamInfo &outCamInfo) -{ - kbd_idlfile::RdbRet objRet; - std::vector vecKey,vecColumn; - vecKey.push_back(outCamInfo.camTag()); - - vecColumn.push_back("camera_ip"); - vecColumn.push_back("description"); - vecColumn.push_back("chan_no"); - vecColumn.push_back("username"); - vecColumn.push_back("password"); - if(m_pNetRdbApi->queryByKey("cctv_camera_info",vecKey,vecColumn,objRet) == false) - { - LOGERROR("queryCameraInfoTable 未查询到条目"); - return false; - } - - if(objRet.msgrecord_size() != 1 || objRet.msgrecord(0).msgvaluearray_size() != 5 ) - { - LOGERROR("queryCameraInfoTable 查询结果不对"); - return false; - } - - outCamInfo.setIp(objRet.msgrecord(0).msgvaluearray(0).strvalue()); - outCamInfo.setDescription(objRet.msgrecord(0).msgvaluearray(1).strvalue()); - outCamInfo.setChan_no(objRet.msgrecord(0).msgvaluearray(2).nvalue()); - outCamInfo.setUsername(objRet.msgrecord(0).msgvaluearray(3).strvalue()); - outCamInfo.setPassword(objRet.msgrecord(0).msgvaluearray(4).strvalue()); - - return true; -} - -bool CRdbAccessUtilty::queryPresetTable(CCamInfo &outCamInfo) -{ - using namespace kbd_dbms; - using namespace kbd_idlfile; - - kbd_idlfile::RdbQuery msgQuery; - msgQuery.set_strtablename("cctv_orientation"); - - msgQuery.add_strselectcolnamearr("tag_name"); - msgQuery.add_strselectcolnamearr("description"); - msgQuery.add_strselectcolnamearr("preset_token"); - - kbd_idlfile::RdbCondition *pCondtion = msgQuery.add_msgcondition(); - pCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pCondtion->set_strcolumnname("camera_tag_name"); - SVariable *pCondValue = pCondtion->mutable_msgvalue(); - pCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pCondValue->set_strvalue(outCamInfo.camTag().c_str()); - - kbd_idlfile::RdbRet retMsg; - - bool bRet; - bRet = m_pNetRdbApi->query(msgQuery, retMsg); - if (false == bRet) - { - LOGERROR("queryPresetTable 未查询到条目"); - return false; - } - else - { - for (int i = 0; i < retMsg.msgrecord_size(); ++i) - { - if(retMsg.msgrecord(i).msgvaluearray_size() != 3) - { - LOGERROR("queryPresetTable 查询结果不对"); - } - - outCamInfo.addPreset(retMsg.msgrecord(i).msgvaluearray(0).strvalue(), - retMsg.msgrecord(i).msgvaluearray(2).strvalue(), - retMsg.msgrecord(i).msgvaluearray(1).strvalue()); - } - } - return true; -} - +#include "CRdbAccessUtilty.h" +#include "pub_logger_api/logger.h" +#include +#include "Common.h" + +CRdbAccessUtilty::CRdbAccessUtilty(int nDomainId,int nAppId) +{ + m_pNetRdbApi = new kbd_dbms::CRdbNetApi(); + + m_pNetRdbApi->connect(nDomainId,nAppId); + +} + +CRdbAccessUtilty::~CRdbAccessUtilty() +{ + if(NULL != m_pNetRdbApi) + { + delete m_pNetRdbApi; + m_pNetRdbApi =NULL; + } +} + +bool CRdbAccessUtilty::getCamInfo(std::string pointtag, CCamInfo & outCamInfo) +{ + std::string pointtype,pointTagWithoutType; + if(splitTagName(pointtag,pointtype,pointTagWithoutType) == kbdFailed) + { + LOGERROR("分割标签名错误,标签名为[%s]",pointtag.c_str()); + return false; + } + + //< 查询点表,填充camera_id和preset_id + if(queryPointTable(pointTagWithoutType,pointtype,outCamInfo) == false) + { + LOGERROR("查询点表错误,标签名为[%s],表名[%s]",pointtag.c_str(),pointtype.c_str()); + return false; + } + + //< 查询点表,填充camera_id和preset_id + if(queryCameraInfoTable(outCamInfo) == false) + { + LOGERROR("查询cctv_camera_info表错误,标签名为[%s]",outCamInfo.camTag().c_str()); + return false; + } + + //< 查询点表,填充camera_id和preset_id + if(queryPresetTable(outCamInfo) == false) + { + LOGERROR("查询cctv_orientation表错误,标签名为[%s]",outCamInfo.camTag().c_str()); + return false; + } + + return true; +} + +int CRdbAccessUtilty::splitTagName(const std::string &inTag, std::string &outType, std::string &outTagName) +{ + std::size_t firstDotindex = inTag.find_first_of('.'); + if(firstDotindex == std::string::npos) + { + return kbdFailed; + } + + // 赋值表名; + if(inTag.substr(0,firstDotindex) == std::string("analog")) + { + outType = "analog"; + } + else if(inTag.substr(0,firstDotindex) == std::string("accuml")){ + outType = "accuml"; + } + else if(inTag.substr(0,firstDotindex) == std::string("digital")){ + outType = "digital"; + } + else if(inTag.substr(0,firstDotindex) == std::string("mix")){ + outType = "mix"; + }else{ + return kbdFailed; + } + + outTagName = inTag.substr(firstDotindex+1,inTag.size()); + return kbdSuccess; +} + +bool CRdbAccessUtilty::queryPointTable(const std::string &pointtag, const std::string &pointType, CCamInfo &outCamInfo) +{ + kbd_idlfile::RdbRet objRet; + std::vector vecKey,vecColumn; + vecKey.push_back(pointtag); + + vecColumn.push_back("camera_tag"); + vecColumn.push_back("preset_id"); + if(m_pNetRdbApi->queryByKey(pointType,vecKey,vecColumn,objRet) == false) + { + LOGERROR("queryPointTable 未查询到条目"); + return false; + } + + if(objRet.msgrecord_size() != 1 || objRet.msgrecord(0).msgvaluearray_size() != 2 ) + { + LOGERROR("queryPointTable 查询结果不对"); + return false; + } + + outCamInfo.setCamTag(objRet.msgrecord(0).msgvaluearray(0).strvalue()); + outCamInfo.setPresetTag(objRet.msgrecord(0).msgvaluearray(1).strvalue()); + return true; +} + +bool CRdbAccessUtilty::queryCameraInfoTable(CCamInfo &outCamInfo) +{ + kbd_idlfile::RdbRet objRet; + std::vector vecKey,vecColumn; + vecKey.push_back(outCamInfo.camTag()); + + vecColumn.push_back("camera_ip"); + vecColumn.push_back("description"); + vecColumn.push_back("chan_no"); + vecColumn.push_back("username"); + vecColumn.push_back("password"); + if(m_pNetRdbApi->queryByKey("cctv_camera_info",vecKey,vecColumn,objRet) == false) + { + LOGERROR("queryCameraInfoTable 未查询到条目"); + return false; + } + + if(objRet.msgrecord_size() != 1 || objRet.msgrecord(0).msgvaluearray_size() != 5 ) + { + LOGERROR("queryCameraInfoTable 查询结果不对"); + return false; + } + + outCamInfo.setIp(objRet.msgrecord(0).msgvaluearray(0).strvalue()); + outCamInfo.setDescription(objRet.msgrecord(0).msgvaluearray(1).strvalue()); + outCamInfo.setChan_no(objRet.msgrecord(0).msgvaluearray(2).nvalue()); + outCamInfo.setUsername(objRet.msgrecord(0).msgvaluearray(3).strvalue()); + outCamInfo.setPassword(objRet.msgrecord(0).msgvaluearray(4).strvalue()); + + return true; +} + +bool CRdbAccessUtilty::queryPresetTable(CCamInfo &outCamInfo) +{ + using namespace kbd_dbms; + using namespace kbd_idlfile; + + kbd_idlfile::RdbQuery msgQuery; + msgQuery.set_strtablename("cctv_orientation"); + + msgQuery.add_strselectcolnamearr("tag_name"); + msgQuery.add_strselectcolnamearr("description"); + msgQuery.add_strselectcolnamearr("preset_token"); + + kbd_idlfile::RdbCondition *pCondtion = msgQuery.add_msgcondition(); + pCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pCondtion->set_strcolumnname("camera_tag_name"); + SVariable *pCondValue = pCondtion->mutable_msgvalue(); + pCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pCondValue->set_strvalue(outCamInfo.camTag().c_str()); + + kbd_idlfile::RdbRet retMsg; + + bool bRet; + bRet = m_pNetRdbApi->query(msgQuery, retMsg); + if (false == bRet) + { + LOGERROR("queryPresetTable 未查询到条目"); + return false; + } + else + { + for (int i = 0; i < retMsg.msgrecord_size(); ++i) + { + if(retMsg.msgrecord(i).msgvaluearray_size() != 3) + { + LOGERROR("queryPresetTable 查询结果不对"); + } + + outCamInfo.addPreset(retMsg.msgrecord(i).msgvaluearray(0).strvalue(), + retMsg.msgrecord(i).msgvaluearray(2).strvalue(), + retMsg.msgrecord(i).msgvaluearray(1).strvalue()); + } + } + return true; +} + diff --git a/product/src/gui/plugin/IpcPlusWidget/CRdbAccessUtilty.h b/product/src/gui/plugin/IpcPlusWidget/CRdbAccessUtilty.h index 32e234fc..14b261a5 100644 --- a/product/src/gui/plugin/IpcPlusWidget/CRdbAccessUtilty.h +++ b/product/src/gui/plugin/IpcPlusWidget/CRdbAccessUtilty.h @@ -1,34 +1,34 @@ -#ifndef CRDBACCESSUTILTY_H -#define CRDBACCESSUTILTY_H - - -#include -#include -#include "rdb_net_api/CRdbNetApi.h" -#include "CCamInfo.h" - -class CRdbAccessUtilty -{ -public: - CRdbAccessUtilty(int nDomainId, int nAppId); - virtual ~CRdbAccessUtilty(); - - /** - * @brief getCamInfo 点标签 mix/acc/digital/analog - * @param pointtag - * @param outCamInfo - * @return - */ - bool getCamInfo(std::string pointtag, CCamInfo &outCamInfo); -private: - static int splitTagName(const std::string &inTag, std::string &outType, std::string &outTagName); - - bool queryPointTable(const std::string &pointtag,const std::string &pointType,CCamInfo &outCamInfo); - bool queryCameraInfoTable(CCamInfo &outCamInfo); - bool queryPresetTable(CCamInfo &outCamInfo); - - - kbd_dbms::CRdbNetApi *m_pNetRdbApi; //网络实时数据库接口指针 -}; - -#endif // CRDBACCESSUTILTY_H +#ifndef CRDBACCESSUTILTY_H +#define CRDBACCESSUTILTY_H + + +#include +#include +#include "rdb_net_api/CRdbNetApi.h" +#include "CCamInfo.h" + +class CRdbAccessUtilty +{ +public: + CRdbAccessUtilty(int nDomainId, int nAppId); + virtual ~CRdbAccessUtilty(); + + /** + * @brief getCamInfo 点标签 mix/acc/digital/analog + * @param pointtag + * @param outCamInfo + * @return + */ + bool getCamInfo(std::string pointtag, CCamInfo &outCamInfo); +private: + static int splitTagName(const std::string &inTag, std::string &outType, std::string &outTagName); + + bool queryPointTable(const std::string &pointtag,const std::string &pointType,CCamInfo &outCamInfo); + bool queryCameraInfoTable(CCamInfo &outCamInfo); + bool queryPresetTable(CCamInfo &outCamInfo); + + + kbd_dbms::CRdbNetApi *m_pNetRdbApi; //网络实时数据库接口指针 +}; + +#endif // CRDBACCESSUTILTY_H diff --git a/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.cpp b/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.cpp index 7fad7916..d529d3b2 100644 --- a/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "IpcPlusPluginWidget.h" -#include "IpcPlusWidget.h" -#include "pub_logger_api/logger.h" -IpcPlusPluginWidget::IpcPlusPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -IpcPlusPluginWidget::~IpcPlusPluginWidget() -{ - -} - -bool IpcPlusPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - IpcPlusWidget *pWidget = new IpcPlusWidget(editMode,parent); - Q_UNUSED(ptrVec); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void IpcPlusPluginWidget::release() -{ - LOGINFO("IpcPlusPluginWidget()::::release()"); - -} +#include "IpcPlusPluginWidget.h" +#include "IpcPlusWidget.h" +#include "pub_logger_api/logger.h" +IpcPlusPluginWidget::IpcPlusPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +IpcPlusPluginWidget::~IpcPlusPluginWidget() +{ + +} + +bool IpcPlusPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + IpcPlusWidget *pWidget = new IpcPlusWidget(editMode,parent); + Q_UNUSED(ptrVec); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void IpcPlusPluginWidget::release() +{ + LOGINFO("IpcPlusPluginWidget()::::release()"); + +} diff --git a/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.h b/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.h index 242c3de9..f91ac87f 100644 --- a/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.h +++ b/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef IPCPLUSPLUGINWIDGET_H -#define IPCPLUSPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class IpcPlusPluginWidget : public QObject,public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - IpcPlusPluginWidget(QObject *parent=0); - ~IpcPlusPluginWidget(); - - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // IPCPLUSPLUGINWIDGET_H +#ifndef IPCPLUSPLUGINWIDGET_H +#define IPCPLUSPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class IpcPlusPluginWidget : public QObject,public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + IpcPlusPluginWidget(QObject *parent=0); + ~IpcPlusPluginWidget(); + + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // IPCPLUSPLUGINWIDGET_H diff --git a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.cpp b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.cpp index ef193e20..62c90db0 100644 --- a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.cpp @@ -1,851 +1,851 @@ -#include "IpcPlusWidget.h" -#include "ui_IpcPlusWidget.h" -#include -#include -#include -#include -#include "VoiceSlider.h" -#include -#include -#include "pub_logger_api/logger.h" -#include "CRdbAccessUtilty.h" -#include "operate_server_api/JsonOptCommand.h" -#include "common/MessageChannel.h" -#include "CCamInfo.h" -#include "CPresetInfo.h" -#include -#include -#include "common/Common.h" -#include -#include "pub_utility_api/FileStyle.h" -#include - -#define APP_NAME "hmi" -#define NODE_NAME "test_node" -#define VIDEO_SERVER_RTU_NAME "##$$video_server$$##" - -#define PTZ_UP 0 -#define PTZ_DOWN 1 -#define PTZ_LEFT 2 -#define PTZ_RIGHT 3 -#define PTZ_ZOOMIN 4 -#define PTZ_ZOOMOUT 5 - -#define CCTV_ONVIF_MOVE "58" -#define CCTV_ONVIF_STOPMOVE "59" -#define CCTV_ONVIF_GOTOPRESET "57" - -#define KEY_CMD_TYPE "cmd_type" -#define CAMERA_TAG "camera_tag" -#define PTZ_COMMOND "commond" -#define PTZ_SPEED "speed" -#define PRESET_TAG "preset_tag" - -#define PTZ_UI_TEST true - - -using namespace QtAV; -using namespace kbd_net; -IpcPlusWidget::IpcPlusWidget(bool editMode, QWidget *parent) : - QWidget(parent), - m_player(Q_NULLPTR), - m_s_vo(Q_NULLPTR), - m_voice(30), - ui(new Ui::IpcPlusWidget) -{ - - ui->setupUi(this); - QGuiApplication::setAttribute(Qt::AA_UseOpenGLES); - - init(); - setCapturePath(); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("ipcPlus.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - qRegisterMetaType< CCamInfo >("CCamInfo"); - qRegisterMetaType< std::vector >("VectorCPresetInfo"); - if(!editMode) - { - COnvifOpt *onvifOpt = new COnvifOpt; - onvifOpt->moveToThread(&m_onvifThread); - connect(&m_onvifThread,&QThread::finished, onvifOpt,&QObject::deleteLater); - connect(this,&IpcPlusWidget::sigCamInfo,onvifOpt,&COnvifOpt::slotCamInfo); - connect(onvifOpt,&COnvifOpt::sigInitStream,this,&IpcPlusWidget::slotInitStream); - - - connect(m_play,&QPushButton::clicked,this,&IpcPlusWidget::play); - connect(m_pause,&QPushButton::clicked,this,&IpcPlusWidget::pause); - connect(m_cap,&QPushButton::clicked,this,&IpcPlusWidget::capture); - connect(m_left,&QPushButton::pressed,this,&IpcPlusWidget::leftPressed); - connect(m_left,&QPushButton::released,this,&IpcPlusWidget::released); - - connect(m_right,&QPushButton::pressed,this,&IpcPlusWidget::rightPressed); - connect(m_right,&QPushButton::released,this,&IpcPlusWidget::released); - - connect(m_up,&QPushButton::pressed,this,&IpcPlusWidget::upPressed); - connect(m_up,&QPushButton::released,this,&IpcPlusWidget::released); - - connect(m_down,&QPushButton::pressed,this,&IpcPlusWidget::downPressed); - connect(m_down,&QPushButton::released,this,&IpcPlusWidget::released); - - connect(m_tretch,&QPushButton::pressed,this,&IpcPlusWidget::tretchPressed); - connect(m_tretch,&QPushButton::released,this,&IpcPlusWidget::released_1); - - connect(m_draw,&QPushButton::pressed,this,&IpcPlusWidget::drawPressed); - connect(m_draw,&QPushButton::released,this,&IpcPlusWidget::released_1); - - connect(m_far,&QPushButton::pressed,this,&IpcPlusWidget::farPressed); - connect(m_far,&QPushButton::released,this,&IpcPlusWidget::released_1); - - connect(m_near,&QPushButton::pressed,this,&IpcPlusWidget::nearPressed); - connect(m_near,&QPushButton::released,this,&IpcPlusWidget::released_1); - - connect(m_big,&QPushButton::pressed,this,&IpcPlusWidget::bigPressed); - connect(m_big,&QPushButton::released,this,&IpcPlusWidget::released_1); - - connect(m_small,&QPushButton::pressed,this,&IpcPlusWidget::smallPressed); - connect(m_small,&QPushButton::released,this,&IpcPlusWidget::released_1); - - connect(m_allot,&QPushButton::clicked,this,&IpcPlusWidget::gotoPreset); - - connect(m_voiceOpen,&QPushButton::clicked,this,&IpcPlusWidget::voiceSliderShow); - connect(m_voiceClose,&QPushButton::clicked,this,&IpcPlusWidget::voiceSliderShow); - connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&IpcPlusWidget::slotVoiceClose); - connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&IpcPlusWidget::slotVoiceOpen); - - connect(m_combox,&QComboBox::currentTextChanged,this,&IpcPlusWidget::slot_presets_itemChanged); - m_onvifThread.start(); - } -} - -IpcPlusWidget::~IpcPlusWidget() -{ - m_onvifThread.quit(); - m_onvifThread.wait(); - if(m_player != Q_NULLPTR) - { - delete m_player; - } - m_player = Q_NULLPTR; - - if(m_player != Q_NULLPTR) - { - delete m_player; - } - m_player = Q_NULLPTR; - if(m_s_vo != Q_NULLPTR) - { - delete m_s_vo; - } - m_s_vo = Q_NULLPTR; - - delete ui; -} - -void IpcPlusWidget::setStreamInfo(QString pointTag) -{ - m_pointTag = pointTag; - LOGINFO("In setStreamInfo,start LoadCamInfo"); - loadCamInfo(); -} - -void IpcPlusWidget::setNodeInfo(int nDomainId, int nAppid) -{ - m_nDomainId = nDomainId; - m_nAppId = nAppid; -} - -void IpcPlusWidget::setNodeName(const QString &nodeName) -{ - m_strNodeName = nodeName.toStdString(); -} - -void IpcPlusWidget::setAppName(const QString &appName) -{ - m_strAppName = appName.toStdString(); -} - -void IpcPlusWidget::slotInitStream(CCamInfo caminfo,int result) -{ - LOGINFO("slotInitStream()"); - - if(result == kbdFailed) - { -// QMessageBox::information(this,tr("提醒"),tr("设置直播流失败")); - LOGINFO("information QMessagexBox 设置直播流失败"); - return ; - } - m_caminfo=caminfo; - - //< 预置点加载 - //< todo - QStandardItemModel * comModel = new QStandardItemModel; - std::vector presets = m_caminfo.presets(); - for(int i = 0; i < (int)presets.size();i++) - { -// m_combox->addItem(QString::fromStdString(presets[i].presetTag) + ":" + presets[i].presetDesc.c_str(),presets[i].presetTag.c_str()); - QStandardItem * model = new QStandardItem; - model->setText(presets[i].presetDesc.c_str()); - model->setData(presets[i].presetTag.c_str(), Qt::UserRole); - model->setToolTip(QString::fromStdString(presets[i].presetTag) + ":" + presets[i].presetDesc.c_str()); - comModel->appendRow(model); - } - m_combox->setModel(comModel); - startStream(); - - //< 转到预置点 - if(m_caminfo.isPtzEnabled() && m_caminfo.presetTag() != "") - { - if( !ptzGotopreset( m_caminfo.presetTag() ) ) - LOGERROR("转到预置点失败"); - } -} - -void IpcPlusWidget::init() -{ - QVBoxLayout *vl = new QVBoxLayout(this); - ui->frame->setLayout(vl); - //this->setLayout(vl); - - m_player = new AVPlayer(this); -// m_s_vo =VideoRenderer::create(VideoRendererId_GLWidget2); - m_s_vo = new VideoOutput(this); - m_s_vo->widget()->setContentsMargins(0,0,0,0); - Widgets::registerRenderers(); - m_player->setRenderer(m_s_vo); - vl->setContentsMargins(0,0,0,0); - - QHBoxLayout *hlayout = new QHBoxLayout(); - hlayout->setContentsMargins(10,10,10,10); - - m_control_1 = new QWidget(this); - m_control_1->setMaximumHeight(40); - m_control_2 = new QWidget(this); - m_control_2->setMaximumHeight(100); - - m_play = new QPushButton(m_control_1); - m_play->setFixedSize(20,20); - m_play->setObjectName("play"); - m_pause = new QPushButton(m_control_1); - m_pause->setFixedSize(20,20); - m_pause->setObjectName("pause"); - - m_cap = new QPushButton(m_control_1); - m_cap->setFixedSize(26,26); - m_cap->setObjectName("cap"); - - m_voiceOpen = new QPushButton(m_control_1); - m_voiceOpen->setObjectName("voiceOpen"); - m_voiceOpen->setFixedSize(26,26); - m_voiceClose = new QPushButton(m_control_1); - m_voiceClose->setObjectName("voiceClose"); - m_voiceClose->setFixedSize(26,26); - - - QGridLayout *glayout = new QGridLayout(this); - glayout->setContentsMargins(10,0,10,0); - - m_up = new QPushButton(m_control_2); - m_up->setFixedSize(30,20); - m_up->setObjectName("up"); - - m_left = new QPushButton(m_control_2); - m_left->setFixedSize(20,30); - m_left->setObjectName("left"); - - m_right = new QPushButton(m_control_2); - m_right->setFixedSize(20,30); - m_right->setObjectName("right"); - - m_down = new QPushButton(m_control_2); - m_down->setFixedSize(30,20); - m_down->setObjectName("down"); - m_ptz.setFixedSize(30,30); - m_ptz.setText(tr("ptz")); - m_ptz.setAlignment(Qt::AlignCenter); - glayout->addWidget(m_up,0,1); - - glayout->addWidget(m_left,1,0); - glayout->addWidget(&m_ptz,1,1); - glayout->addWidget(m_right,1,2); - glayout->addWidget(m_down,2,1); - - QGridLayout *glayout2 = new QGridLayout(this); - glayout2->setContentsMargins(10,0,10,0); - - m_tj.setText(tr("调焦")); - m_tj.setFixedSize(40,20); - m_tj.setAlignment(Qt::AlignCenter); - m_jj.setText(tr("聚焦")); - m_jj.setFixedSize(40,20); - m_jj.setAlignment(Qt::AlignCenter); - m_gq.setText(tr("光圈")); - m_gq.setFixedSize(40,20); - m_gq.setAlignment(Qt::AlignCenter); - - m_draw = new QPushButton(m_control_2); - m_draw->setFixedSize(30,20); - m_draw->setObjectName("draw"); - m_draw->setText(tr("缩")); - - m_tretch = new QPushButton(m_control_2); - m_tretch->setFixedSize(30,20); - m_tretch->setObjectName("tretch"); - m_tretch->setText(tr("伸")); - - m_near = new QPushButton(m_control_2); - m_near->setFixedSize(30,20); - m_near->setObjectName("near"); - m_near->setText(tr("近")); - - m_far = new QPushButton(m_control_2); - m_far->setFixedSize(30,20); - m_far->setObjectName("far"); - m_far->setText(tr("远")); - - m_big = new QPushButton(m_control_2); - m_big->setFixedSize(30,20); - m_big->setObjectName("big"); - m_big->setText(tr("大")); - - m_small = new QPushButton(m_control_2); - m_small->setFixedSize(30,20); - m_small->setObjectName("small"); - m_small->setText(tr("小")); - - glayout2->addWidget(m_draw,0,0); - glayout2->addWidget(&m_tj,0,1); - glayout2->addWidget(m_tretch,0,2); - - glayout2->addWidget(m_near,1,0); - glayout2->addWidget(&m_jj,1,1); - glayout2->addWidget(m_far,1,2); - - glayout2->addWidget(m_big,2,0); - glayout2->addWidget(&m_gq,2,1); - glayout2->addWidget(m_small,2,2); - - m_preset.setText(tr("预置点:")); - m_preset.setMinimumHeight(25); - m_combox = new QComboBox(m_control_2); - m_combox->setMinimumHeight(25); - m_combox->setView(new QListView()); - m_allot = new QPushButton(m_control_2); - m_allot->setText(tr("调用")); - m_allot->setMinimumHeight(25); - m_allot->setObjectName("allot"); - - QVBoxLayout *hlayout1 = new QVBoxLayout(this); - hlayout1->addWidget(&m_preset); - hlayout1->addWidget(m_combox); - QVBoxLayout *vlayout = new QVBoxLayout(this); - vlayout->addLayout(hlayout1); - vlayout->addWidget(m_allot); - QHBoxLayout *hlayout3 = new QHBoxLayout(this); - hlayout3->setContentsMargins(20,0,20,0); - hlayout3->addLayout(glayout); - hlayout3->addLayout(glayout2); - hlayout3->addLayout(vlayout); - - hlayout->addWidget(m_play); - hlayout->addWidget(m_pause); - hlayout->addStretch(); - hlayout->addWidget(m_cap); - hlayout->addWidget(m_voiceOpen); - hlayout->addWidget(m_voiceClose); - - m_control_1->setLayout(hlayout); - m_control_1->setObjectName("control_1"); - m_control_2->setLayout(hlayout3); - m_control_2->setObjectName("control_2"); - vl->addWidget(m_s_vo->widget()); - vl->addWidget(m_control_1); - vl->addWidget(m_control_2); - m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); - m_play->setHidden(true); - m_voiceClose->setHidden(true); -} - -void IpcPlusWidget::loadCamInfo() -{ - - CRdbAccessUtilty rdbutilty(m_nDomainId,m_nAppId); - if(rdbutilty.getCamInfo(m_pointTag.toStdString(),m_caminfo) == false) - { - QMessageBox::information(this,tr("提醒"),tr("内存库读取失败")); - return; - } - emit sigCamInfo(m_caminfo); -} - -void IpcPlusWidget::startStream() -{ - if(m_player->isPlaying()) - { - return; - } - - m_player->setBufferMode(QtAV::BufferTime); - m_player->audio()->setBufferSamples(64); - m_player->setBufferValue(50); - - m_playerCfgParser.applyToPlayer(*m_player); - - m_player->setFile(m_caminfo.getStreamRtspAddr().c_str()); - setVoiceNum(); - m_player->play(); -} - -void IpcPlusWidget::setCapturePath() -{ - if(m_player != NULL) - { - m_player->videoCapture()->setCaptureName("cap"); - m_player->videoCapture()->setCaptureDir("../../data/videocap"); - m_player->videoCapture()->setQuality(100); - m_player->videoCapture()->setSaveFormat("jpg"); - } -} - -bool IpcPlusWidget::ptzContinuousMove(int cmd, double cmd_speed) -{ - if(PTZ_UI_TEST) - { - return m_caminfo.continuousMove(cmd,cmd_speed); - } - else - { - return sendOptContinuousMove(cmd,cmd_speed); - } -} - -bool IpcPlusWidget::ptzStopMove() -{ - if(PTZ_UI_TEST) - { - return m_caminfo.stopMove(); - } - else - { - return sendOptStopMove(); - } -} - -bool IpcPlusWidget::ptzGotopreset(const std::string &preset_tag) -{ - if(PTZ_UI_TEST) - { - if(m_caminfo.gotoPreset(preset_tag) == false) - { - return false; - } - } - else - { - if(this->sendOptGotopreset(preset_tag) == false) - { - return false; - } - } - return true; -} - -bool IpcPlusWidget::sendOptContinuousMove(int cmd, double cmd_speed) -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_strAppName; - stCustomCmd.stHead.nSrcDomainID = m_nDomainId; - stCustomCmd.stHead.nDstDomainID = m_nDomainId; - stCustomCmd.stHead.nAppID = m_nAppId; - stCustomCmd.stHead.strHostName = m_strNodeName; - stCustomCmd.stHead.strInstName = m_strAppName; - stCustomCmd.stHead.strCommName = m_com.getName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加转动命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE;//转动 - stOptKeyValue.strKeyValue = CCTV_ONVIF_MOVE ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_caminfo.camTag() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加方向 - stOptKeyValue.strKeyName = PTZ_COMMOND; - stOptKeyValue.strKeyValue = QString::number(cmd).toStdString() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加速度 - stOptKeyValue.strKeyName = PTZ_SPEED; - stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - bool bRet = false; - CMbMessage objMsg; - - objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 - objMsg.setSubject(m_nAppId,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 - objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff - - bRet = m_com.sendMsgToDomain(objMsg,m_nDomainId); //发送到主机 - if (bRet == false) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - -bool IpcPlusWidget::sendOptStopMove() -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_strAppName; - stCustomCmd.stHead.nSrcDomainID = m_nDomainId; - stCustomCmd.stHead.nDstDomainID = m_nDomainId; - stCustomCmd.stHead.nAppID = m_nAppId; - stCustomCmd.stHead.strHostName = m_strNodeName; - stCustomCmd.stHead.strInstName = m_strAppName; - stCustomCmd.stHead.strCommName = m_com.getName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加停止转动命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE; - stOptKeyValue.strKeyValue = CCTV_ONVIF_STOPMOVE ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_caminfo.camTag() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - bool bRet = false; - CMbMessage objMsg; - - objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 - objMsg.setSubject(m_nAppId,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 - objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff - - bRet = m_com.sendMsgToDomain(objMsg,m_nDomainId); //发送到主机 - if (bRet == false) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - -bool IpcPlusWidget::sendOptGotopreset(const std::string &preset_tag) -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_strAppName; - stCustomCmd.stHead.nSrcDomainID = m_nDomainId; - stCustomCmd.stHead.nDstDomainID = m_nDomainId; - stCustomCmd.stHead.nAppID = m_nAppId; - stCustomCmd.stHead.strHostName = m_strNodeName; - stCustomCmd.stHead.strInstName = m_strAppName; - stCustomCmd.stHead.strCommName = m_com.getName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加转到预置点命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE; - stOptKeyValue.strKeyValue = CCTV_ONVIF_GOTOPRESET ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_caminfo.camTag() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加预置点标签 - stOptKeyValue.strKeyName = PRESET_TAG; - stOptKeyValue.strKeyValue = preset_tag; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - - bool bRet = false; - CMbMessage objMsg; - - objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 - objMsg.setSubject(m_nAppId,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 - objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff - - bRet = m_com.sendMsgToDomain(objMsg,m_nDomainId); //发送到主机 - if (bRet == false) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - -void IpcPlusWidget::gotoPreset() -{ - if(!m_player->isPlaying()) - return; - else - { - if(ptzGotopreset(m_combox->currentData().toString().toStdString().c_str()) == false) - { - LOGERROR("cannot gotopreset %s",m_combox->currentData().toString().toStdString().c_str()); - qDebug() << "转到预置点失败"; - } - } -} - -void IpcPlusWidget::setShowVoice(bool bo) -{ - if(!bo) - { - m_voiceOpen->setHidden(true); - m_voiceClose->setHidden(false); - }else - { - m_voiceOpen->setHidden(false); - m_voiceClose->setHidden(true); - } -} - -void IpcPlusWidget::setVoiceNum() -{ - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(m_voice*0.04); - if (ao) - { - ao->setVolume(v); - } -} - -void IpcPlusWidget::play() -{ - m_play->setHidden(true); - m_pause->setHidden(false); - if(m_player->isPaused()) - { - setVoiceNum(); - m_player->pause(!m_player->isPaused()); - return; - } -} - -void IpcPlusWidget::pause() -{ - m_play->setHidden(false); - m_pause->setHidden(true); - if(m_player->isPaused()) - { - return; - }else - { - m_player->pause(!m_player->isPaused()); - } -} - -void IpcPlusWidget::capture() -{ - if (m_player->isPlaying()) { - m_player->videoCapture()->setCaptureName(QDateTime::currentDateTime().toString("yyyy_MMdd_hhmmss_z")); - m_player->videoCapture()->capture(); - } -} - -void IpcPlusWidget::leftPressed() -{ - if(!m_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_LEFT,1) == false) - { - qDebug() << "向左转动失败"; - } -} - -void IpcPlusWidget::released() -{ - if(!m_player->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; -} - -void IpcPlusWidget::rightPressed() -{ - if(!m_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_RIGHT,1) == false) - { - qDebug() << "向右转动失败"; - return; - } -} - -void IpcPlusWidget::upPressed() -{ - if(!m_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_UP,1) == false) - { - qDebug() << "向上转动失败"; - } -} - -void IpcPlusWidget::downPressed() -{ - if(!m_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_DOWN,1) == false) - { - qDebug() << "向下转动失败"; - } -} - -void IpcPlusWidget::tretchPressed() -{ - if(!m_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_ZOOMIN,getCurrentCmdspeed()) == false) - { - qDebug() << "zoomin转动失败"; - } -} - -void IpcPlusWidget::released_1() -{ - if(!m_player->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; -} - -void IpcPlusWidget::drawPressed() -{ - if(!m_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_ZOOMOUT,getCurrentCmdspeed()) == false) - { - qDebug() << "zoomout转动失败"; - } -} - -void IpcPlusWidget::farPressed() -{ - -} - -void IpcPlusWidget::nearPressed() -{ - -} - -void IpcPlusWidget::bigPressed() -{ - -} - -void IpcPlusWidget::smallPressed() -{ - -} - -void IpcPlusWidget::voiceSliderShow() -{ - if(m_voiceSlider->getStatus() == false) - { - QPoint gpos =mapToGlobal(m_voiceOpen->pos()); - int x= m_control_1->pos().y()-52; - m_voiceSlider->move(gpos-QPoint(159,0)+QPoint(0,x)); - m_voiceSlider->show(); - m_voiceSlider->setStatus(true); - }else - { - m_voiceSlider->hide(); - m_voiceSlider->setStatus(false); - } -} - -void IpcPlusWidget::slotVoiceClose(int voice) -{ - setShowVoice(false); - m_voice = voice; - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void IpcPlusWidget::slotVoiceOpen(int voice) -{ - setShowVoice(true); - m_voice = voice; - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -double IpcPlusWidget::getCurrentCmdspeed() -{ - return 1.0; -} - -void IpcPlusWidget::slot_presets_itemChanged(const QString &str) -{ - m_combox->setToolTip(str); -} +#include "IpcPlusWidget.h" +#include "ui_IpcPlusWidget.h" +#include +#include +#include +#include +#include "VoiceSlider.h" +#include +#include +#include "pub_logger_api/logger.h" +#include "CRdbAccessUtilty.h" +#include "operate_server_api/JsonOptCommand.h" +#include "common/MessageChannel.h" +#include "CCamInfo.h" +#include "CPresetInfo.h" +#include +#include +#include "common/Common.h" +#include +#include "pub_utility_api/FileStyle.h" +#include + +#define APP_NAME "hmi" +#define NODE_NAME "test_node" +#define VIDEO_SERVER_RTU_NAME "##$$video_server$$##" + +#define PTZ_UP 0 +#define PTZ_DOWN 1 +#define PTZ_LEFT 2 +#define PTZ_RIGHT 3 +#define PTZ_ZOOMIN 4 +#define PTZ_ZOOMOUT 5 + +#define CCTV_ONVIF_MOVE "58" +#define CCTV_ONVIF_STOPMOVE "59" +#define CCTV_ONVIF_GOTOPRESET "57" + +#define KEY_CMD_TYPE "cmd_type" +#define CAMERA_TAG "camera_tag" +#define PTZ_COMMOND "commond" +#define PTZ_SPEED "speed" +#define PRESET_TAG "preset_tag" + +#define PTZ_UI_TEST true + + +using namespace QtAV; +using namespace kbd_net; +IpcPlusWidget::IpcPlusWidget(bool editMode, QWidget *parent) : + QWidget(parent), + m_player(Q_NULLPTR), + m_s_vo(Q_NULLPTR), + m_voice(30), + ui(new Ui::IpcPlusWidget) +{ + + ui->setupUi(this); + QGuiApplication::setAttribute(Qt::AA_UseOpenGLES); + + init(); + setCapturePath(); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("ipcPlus.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + qRegisterMetaType< CCamInfo >("CCamInfo"); + qRegisterMetaType< std::vector >("VectorCPresetInfo"); + if(!editMode) + { + COnvifOpt *onvifOpt = new COnvifOpt; + onvifOpt->moveToThread(&m_onvifThread); + connect(&m_onvifThread,&QThread::finished, onvifOpt,&QObject::deleteLater); + connect(this,&IpcPlusWidget::sigCamInfo,onvifOpt,&COnvifOpt::slotCamInfo); + connect(onvifOpt,&COnvifOpt::sigInitStream,this,&IpcPlusWidget::slotInitStream); + + + connect(m_play,&QPushButton::clicked,this,&IpcPlusWidget::play); + connect(m_pause,&QPushButton::clicked,this,&IpcPlusWidget::pause); + connect(m_cap,&QPushButton::clicked,this,&IpcPlusWidget::capture); + connect(m_left,&QPushButton::pressed,this,&IpcPlusWidget::leftPressed); + connect(m_left,&QPushButton::released,this,&IpcPlusWidget::released); + + connect(m_right,&QPushButton::pressed,this,&IpcPlusWidget::rightPressed); + connect(m_right,&QPushButton::released,this,&IpcPlusWidget::released); + + connect(m_up,&QPushButton::pressed,this,&IpcPlusWidget::upPressed); + connect(m_up,&QPushButton::released,this,&IpcPlusWidget::released); + + connect(m_down,&QPushButton::pressed,this,&IpcPlusWidget::downPressed); + connect(m_down,&QPushButton::released,this,&IpcPlusWidget::released); + + connect(m_tretch,&QPushButton::pressed,this,&IpcPlusWidget::tretchPressed); + connect(m_tretch,&QPushButton::released,this,&IpcPlusWidget::released_1); + + connect(m_draw,&QPushButton::pressed,this,&IpcPlusWidget::drawPressed); + connect(m_draw,&QPushButton::released,this,&IpcPlusWidget::released_1); + + connect(m_far,&QPushButton::pressed,this,&IpcPlusWidget::farPressed); + connect(m_far,&QPushButton::released,this,&IpcPlusWidget::released_1); + + connect(m_near,&QPushButton::pressed,this,&IpcPlusWidget::nearPressed); + connect(m_near,&QPushButton::released,this,&IpcPlusWidget::released_1); + + connect(m_big,&QPushButton::pressed,this,&IpcPlusWidget::bigPressed); + connect(m_big,&QPushButton::released,this,&IpcPlusWidget::released_1); + + connect(m_small,&QPushButton::pressed,this,&IpcPlusWidget::smallPressed); + connect(m_small,&QPushButton::released,this,&IpcPlusWidget::released_1); + + connect(m_allot,&QPushButton::clicked,this,&IpcPlusWidget::gotoPreset); + + connect(m_voiceOpen,&QPushButton::clicked,this,&IpcPlusWidget::voiceSliderShow); + connect(m_voiceClose,&QPushButton::clicked,this,&IpcPlusWidget::voiceSliderShow); + connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&IpcPlusWidget::slotVoiceClose); + connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&IpcPlusWidget::slotVoiceOpen); + + connect(m_combox,&QComboBox::currentTextChanged,this,&IpcPlusWidget::slot_presets_itemChanged); + m_onvifThread.start(); + } +} + +IpcPlusWidget::~IpcPlusWidget() +{ + m_onvifThread.quit(); + m_onvifThread.wait(); + if(m_player != Q_NULLPTR) + { + delete m_player; + } + m_player = Q_NULLPTR; + + if(m_player != Q_NULLPTR) + { + delete m_player; + } + m_player = Q_NULLPTR; + if(m_s_vo != Q_NULLPTR) + { + delete m_s_vo; + } + m_s_vo = Q_NULLPTR; + + delete ui; +} + +void IpcPlusWidget::setStreamInfo(QString pointTag) +{ + m_pointTag = pointTag; + LOGINFO("In setStreamInfo,start LoadCamInfo"); + loadCamInfo(); +} + +void IpcPlusWidget::setNodeInfo(int nDomainId, int nAppid) +{ + m_nDomainId = nDomainId; + m_nAppId = nAppid; +} + +void IpcPlusWidget::setNodeName(const QString &nodeName) +{ + m_strNodeName = nodeName.toStdString(); +} + +void IpcPlusWidget::setAppName(const QString &appName) +{ + m_strAppName = appName.toStdString(); +} + +void IpcPlusWidget::slotInitStream(CCamInfo caminfo,int result) +{ + LOGINFO("slotInitStream()"); + + if(result == kbdFailed) + { +// QMessageBox::information(this,tr("提醒"),tr("设置直播流失败")); + LOGINFO("information QMessagexBox 设置直播流失败"); + return ; + } + m_caminfo=caminfo; + + //< 预置点加载 + //< todo + QStandardItemModel * comModel = new QStandardItemModel; + std::vector presets = m_caminfo.presets(); + for(int i = 0; i < (int)presets.size();i++) + { +// m_combox->addItem(QString::fromStdString(presets[i].presetTag) + ":" + presets[i].presetDesc.c_str(),presets[i].presetTag.c_str()); + QStandardItem * model = new QStandardItem; + model->setText(presets[i].presetDesc.c_str()); + model->setData(presets[i].presetTag.c_str(), Qt::UserRole); + model->setToolTip(QString::fromStdString(presets[i].presetTag) + ":" + presets[i].presetDesc.c_str()); + comModel->appendRow(model); + } + m_combox->setModel(comModel); + startStream(); + + //< 转到预置点 + if(m_caminfo.isPtzEnabled() && m_caminfo.presetTag() != "") + { + if( !ptzGotopreset( m_caminfo.presetTag() ) ) + LOGERROR("转到预置点失败"); + } +} + +void IpcPlusWidget::init() +{ + QVBoxLayout *vl = new QVBoxLayout(this); + ui->frame->setLayout(vl); + //this->setLayout(vl); + + m_player = new AVPlayer(this); +// m_s_vo =VideoRenderer::create(VideoRendererId_GLWidget2); + m_s_vo = new VideoOutput(this); + m_s_vo->widget()->setContentsMargins(0,0,0,0); + Widgets::registerRenderers(); + m_player->setRenderer(m_s_vo); + vl->setContentsMargins(0,0,0,0); + + QHBoxLayout *hlayout = new QHBoxLayout(); + hlayout->setContentsMargins(10,10,10,10); + + m_control_1 = new QWidget(this); + m_control_1->setMaximumHeight(40); + m_control_2 = new QWidget(this); + m_control_2->setMaximumHeight(100); + + m_play = new QPushButton(m_control_1); + m_play->setFixedSize(20,20); + m_play->setObjectName("play"); + m_pause = new QPushButton(m_control_1); + m_pause->setFixedSize(20,20); + m_pause->setObjectName("pause"); + + m_cap = new QPushButton(m_control_1); + m_cap->setFixedSize(26,26); + m_cap->setObjectName("cap"); + + m_voiceOpen = new QPushButton(m_control_1); + m_voiceOpen->setObjectName("voiceOpen"); + m_voiceOpen->setFixedSize(26,26); + m_voiceClose = new QPushButton(m_control_1); + m_voiceClose->setObjectName("voiceClose"); + m_voiceClose->setFixedSize(26,26); + + + QGridLayout *glayout = new QGridLayout(this); + glayout->setContentsMargins(10,0,10,0); + + m_up = new QPushButton(m_control_2); + m_up->setFixedSize(30,20); + m_up->setObjectName("up"); + + m_left = new QPushButton(m_control_2); + m_left->setFixedSize(20,30); + m_left->setObjectName("left"); + + m_right = new QPushButton(m_control_2); + m_right->setFixedSize(20,30); + m_right->setObjectName("right"); + + m_down = new QPushButton(m_control_2); + m_down->setFixedSize(30,20); + m_down->setObjectName("down"); + m_ptz.setFixedSize(30,30); + m_ptz.setText(tr("ptz")); + m_ptz.setAlignment(Qt::AlignCenter); + glayout->addWidget(m_up,0,1); + + glayout->addWidget(m_left,1,0); + glayout->addWidget(&m_ptz,1,1); + glayout->addWidget(m_right,1,2); + glayout->addWidget(m_down,2,1); + + QGridLayout *glayout2 = new QGridLayout(this); + glayout2->setContentsMargins(10,0,10,0); + + m_tj.setText(tr("调焦")); + m_tj.setFixedSize(40,20); + m_tj.setAlignment(Qt::AlignCenter); + m_jj.setText(tr("聚焦")); + m_jj.setFixedSize(40,20); + m_jj.setAlignment(Qt::AlignCenter); + m_gq.setText(tr("光圈")); + m_gq.setFixedSize(40,20); + m_gq.setAlignment(Qt::AlignCenter); + + m_draw = new QPushButton(m_control_2); + m_draw->setFixedSize(30,20); + m_draw->setObjectName("draw"); + m_draw->setText(tr("缩")); + + m_tretch = new QPushButton(m_control_2); + m_tretch->setFixedSize(30,20); + m_tretch->setObjectName("tretch"); + m_tretch->setText(tr("伸")); + + m_near = new QPushButton(m_control_2); + m_near->setFixedSize(30,20); + m_near->setObjectName("near"); + m_near->setText(tr("近")); + + m_far = new QPushButton(m_control_2); + m_far->setFixedSize(30,20); + m_far->setObjectName("far"); + m_far->setText(tr("远")); + + m_big = new QPushButton(m_control_2); + m_big->setFixedSize(30,20); + m_big->setObjectName("big"); + m_big->setText(tr("大")); + + m_small = new QPushButton(m_control_2); + m_small->setFixedSize(30,20); + m_small->setObjectName("small"); + m_small->setText(tr("小")); + + glayout2->addWidget(m_draw,0,0); + glayout2->addWidget(&m_tj,0,1); + glayout2->addWidget(m_tretch,0,2); + + glayout2->addWidget(m_near,1,0); + glayout2->addWidget(&m_jj,1,1); + glayout2->addWidget(m_far,1,2); + + glayout2->addWidget(m_big,2,0); + glayout2->addWidget(&m_gq,2,1); + glayout2->addWidget(m_small,2,2); + + m_preset.setText(tr("预置点:")); + m_preset.setMinimumHeight(25); + m_combox = new QComboBox(m_control_2); + m_combox->setMinimumHeight(25); + m_combox->setView(new QListView()); + m_allot = new QPushButton(m_control_2); + m_allot->setText(tr("调用")); + m_allot->setMinimumHeight(25); + m_allot->setObjectName("allot"); + + QVBoxLayout *hlayout1 = new QVBoxLayout(this); + hlayout1->addWidget(&m_preset); + hlayout1->addWidget(m_combox); + QVBoxLayout *vlayout = new QVBoxLayout(this); + vlayout->addLayout(hlayout1); + vlayout->addWidget(m_allot); + QHBoxLayout *hlayout3 = new QHBoxLayout(this); + hlayout3->setContentsMargins(20,0,20,0); + hlayout3->addLayout(glayout); + hlayout3->addLayout(glayout2); + hlayout3->addLayout(vlayout); + + hlayout->addWidget(m_play); + hlayout->addWidget(m_pause); + hlayout->addStretch(); + hlayout->addWidget(m_cap); + hlayout->addWidget(m_voiceOpen); + hlayout->addWidget(m_voiceClose); + + m_control_1->setLayout(hlayout); + m_control_1->setObjectName("control_1"); + m_control_2->setLayout(hlayout3); + m_control_2->setObjectName("control_2"); + vl->addWidget(m_s_vo->widget()); + vl->addWidget(m_control_1); + vl->addWidget(m_control_2); + m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); + m_play->setHidden(true); + m_voiceClose->setHidden(true); +} + +void IpcPlusWidget::loadCamInfo() +{ + + CRdbAccessUtilty rdbutilty(m_nDomainId,m_nAppId); + if(rdbutilty.getCamInfo(m_pointTag.toStdString(),m_caminfo) == false) + { + QMessageBox::information(this,tr("提醒"),tr("内存库读取失败")); + return; + } + emit sigCamInfo(m_caminfo); +} + +void IpcPlusWidget::startStream() +{ + if(m_player->isPlaying()) + { + return; + } + + m_player->setBufferMode(QtAV::BufferTime); + m_player->audio()->setBufferSamples(64); + m_player->setBufferValue(50); + + m_playerCfgParser.applyToPlayer(*m_player); + + m_player->setFile(m_caminfo.getStreamRtspAddr().c_str()); + setVoiceNum(); + m_player->play(); +} + +void IpcPlusWidget::setCapturePath() +{ + if(m_player != NULL) + { + m_player->videoCapture()->setCaptureName("cap"); + m_player->videoCapture()->setCaptureDir("../../data/videocap"); + m_player->videoCapture()->setQuality(100); + m_player->videoCapture()->setSaveFormat("jpg"); + } +} + +bool IpcPlusWidget::ptzContinuousMove(int cmd, double cmd_speed) +{ + if(PTZ_UI_TEST) + { + return m_caminfo.continuousMove(cmd,cmd_speed); + } + else + { + return sendOptContinuousMove(cmd,cmd_speed); + } +} + +bool IpcPlusWidget::ptzStopMove() +{ + if(PTZ_UI_TEST) + { + return m_caminfo.stopMove(); + } + else + { + return sendOptStopMove(); + } +} + +bool IpcPlusWidget::ptzGotopreset(const std::string &preset_tag) +{ + if(PTZ_UI_TEST) + { + if(m_caminfo.gotoPreset(preset_tag) == false) + { + return false; + } + } + else + { + if(this->sendOptGotopreset(preset_tag) == false) + { + return false; + } + } + return true; +} + +bool IpcPlusWidget::sendOptContinuousMove(int cmd, double cmd_speed) +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_strAppName; + stCustomCmd.stHead.nSrcDomainID = m_nDomainId; + stCustomCmd.stHead.nDstDomainID = m_nDomainId; + stCustomCmd.stHead.nAppID = m_nAppId; + stCustomCmd.stHead.strHostName = m_strNodeName; + stCustomCmd.stHead.strInstName = m_strAppName; + stCustomCmd.stHead.strCommName = m_com.getName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加转动命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE;//转动 + stOptKeyValue.strKeyValue = CCTV_ONVIF_MOVE ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_caminfo.camTag() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加方向 + stOptKeyValue.strKeyName = PTZ_COMMOND; + stOptKeyValue.strKeyValue = QString::number(cmd).toStdString() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加速度 + stOptKeyValue.strKeyName = PTZ_SPEED; + stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + bool bRet = false; + CMbMessage objMsg; + + objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 + objMsg.setSubject(m_nAppId,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 + objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff + + bRet = m_com.sendMsgToDomain(objMsg,m_nDomainId); //发送到主机 + if (bRet == false) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + +bool IpcPlusWidget::sendOptStopMove() +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_strAppName; + stCustomCmd.stHead.nSrcDomainID = m_nDomainId; + stCustomCmd.stHead.nDstDomainID = m_nDomainId; + stCustomCmd.stHead.nAppID = m_nAppId; + stCustomCmd.stHead.strHostName = m_strNodeName; + stCustomCmd.stHead.strInstName = m_strAppName; + stCustomCmd.stHead.strCommName = m_com.getName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加停止转动命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE; + stOptKeyValue.strKeyValue = CCTV_ONVIF_STOPMOVE ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_caminfo.camTag() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + bool bRet = false; + CMbMessage objMsg; + + objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 + objMsg.setSubject(m_nAppId,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 + objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff + + bRet = m_com.sendMsgToDomain(objMsg,m_nDomainId); //发送到主机 + if (bRet == false) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + +bool IpcPlusWidget::sendOptGotopreset(const std::string &preset_tag) +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_strAppName; + stCustomCmd.stHead.nSrcDomainID = m_nDomainId; + stCustomCmd.stHead.nDstDomainID = m_nDomainId; + stCustomCmd.stHead.nAppID = m_nAppId; + stCustomCmd.stHead.strHostName = m_strNodeName; + stCustomCmd.stHead.strInstName = m_strAppName; + stCustomCmd.stHead.strCommName = m_com.getName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加转到预置点命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE; + stOptKeyValue.strKeyValue = CCTV_ONVIF_GOTOPRESET ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_caminfo.camTag() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加预置点标签 + stOptKeyValue.strKeyName = PRESET_TAG; + stOptKeyValue.strKeyValue = preset_tag; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + + bool bRet = false; + CMbMessage objMsg; + + objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 + objMsg.setSubject(m_nAppId,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 + objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff + + bRet = m_com.sendMsgToDomain(objMsg,m_nDomainId); //发送到主机 + if (bRet == false) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + +void IpcPlusWidget::gotoPreset() +{ + if(!m_player->isPlaying()) + return; + else + { + if(ptzGotopreset(m_combox->currentData().toString().toStdString().c_str()) == false) + { + LOGERROR("cannot gotopreset %s",m_combox->currentData().toString().toStdString().c_str()); + qDebug() << "转到预置点失败"; + } + } +} + +void IpcPlusWidget::setShowVoice(bool bo) +{ + if(!bo) + { + m_voiceOpen->setHidden(true); + m_voiceClose->setHidden(false); + }else + { + m_voiceOpen->setHidden(false); + m_voiceClose->setHidden(true); + } +} + +void IpcPlusWidget::setVoiceNum() +{ + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(m_voice*0.04); + if (ao) + { + ao->setVolume(v); + } +} + +void IpcPlusWidget::play() +{ + m_play->setHidden(true); + m_pause->setHidden(false); + if(m_player->isPaused()) + { + setVoiceNum(); + m_player->pause(!m_player->isPaused()); + return; + } +} + +void IpcPlusWidget::pause() +{ + m_play->setHidden(false); + m_pause->setHidden(true); + if(m_player->isPaused()) + { + return; + }else + { + m_player->pause(!m_player->isPaused()); + } +} + +void IpcPlusWidget::capture() +{ + if (m_player->isPlaying()) { + m_player->videoCapture()->setCaptureName(QDateTime::currentDateTime().toString("yyyy_MMdd_hhmmss_z")); + m_player->videoCapture()->capture(); + } +} + +void IpcPlusWidget::leftPressed() +{ + if(!m_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_LEFT,1) == false) + { + qDebug() << "向左转动失败"; + } +} + +void IpcPlusWidget::released() +{ + if(!m_player->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; +} + +void IpcPlusWidget::rightPressed() +{ + if(!m_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_RIGHT,1) == false) + { + qDebug() << "向右转动失败"; + return; + } +} + +void IpcPlusWidget::upPressed() +{ + if(!m_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_UP,1) == false) + { + qDebug() << "向上转动失败"; + } +} + +void IpcPlusWidget::downPressed() +{ + if(!m_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_DOWN,1) == false) + { + qDebug() << "向下转动失败"; + } +} + +void IpcPlusWidget::tretchPressed() +{ + if(!m_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_ZOOMIN,getCurrentCmdspeed()) == false) + { + qDebug() << "zoomin转动失败"; + } +} + +void IpcPlusWidget::released_1() +{ + if(!m_player->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; +} + +void IpcPlusWidget::drawPressed() +{ + if(!m_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_ZOOMOUT,getCurrentCmdspeed()) == false) + { + qDebug() << "zoomout转动失败"; + } +} + +void IpcPlusWidget::farPressed() +{ + +} + +void IpcPlusWidget::nearPressed() +{ + +} + +void IpcPlusWidget::bigPressed() +{ + +} + +void IpcPlusWidget::smallPressed() +{ + +} + +void IpcPlusWidget::voiceSliderShow() +{ + if(m_voiceSlider->getStatus() == false) + { + QPoint gpos =mapToGlobal(m_voiceOpen->pos()); + int x= m_control_1->pos().y()-52; + m_voiceSlider->move(gpos-QPoint(159,0)+QPoint(0,x)); + m_voiceSlider->show(); + m_voiceSlider->setStatus(true); + }else + { + m_voiceSlider->hide(); + m_voiceSlider->setStatus(false); + } +} + +void IpcPlusWidget::slotVoiceClose(int voice) +{ + setShowVoice(false); + m_voice = voice; + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void IpcPlusWidget::slotVoiceOpen(int voice) +{ + setShowVoice(true); + m_voice = voice; + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +double IpcPlusWidget::getCurrentCmdspeed() +{ + return 1.0; +} + +void IpcPlusWidget::slot_presets_itemChanged(const QString &str) +{ + m_combox->setToolTip(str); +} diff --git a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.h b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.h index 27873bcd..2d151b41 100644 --- a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.h +++ b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.h @@ -1,136 +1,136 @@ -#ifndef IPCPLUSWIDGET_H -#define IPCPLUSWIDGET_H - -#include -#include -#include -#include -#include -#include "net_msg_bus_api/CMbCommunicator.h" -#include "CCamInfo.h" -#include "COnvifOpt.h" -#include -#include -class Slider; -class QPushButton; -class QWidget; -class QToolButton; -class Renderer; -class VoiceSlider; -class QComboBox; - -namespace QtAV { - class AVPlayer; - class WidgetRenderer; - class AVError; -} -namespace Ui { -class IpcPlusWidget; -} - -class IpcPlusWidget : public QWidget -{ - Q_OBJECT -public: - explicit IpcPlusWidget(bool editMode = false,QWidget *parent = 0); - ~IpcPlusWidget(); -public slots: - void setStreamInfo(QString pointTag); - void setNodeInfo(int nDomainId,int nAppid); - void setNodeName(const QString &nodeName); - void setAppName(const QString &appName); - - void slotInitStream(CCamInfo caminfo, int result); -signals: - void sigCamInfo(CCamInfo caminfo); -private: - void init(); - void loadCamInfo(); - void startStream(); - void setCapturePath(); - - bool ptzContinuousMove(int cmd,double cmd_speed = 1); - bool ptzStopMove(); - bool ptzGotopreset(const std::string &preset_tag); - - bool sendOptContinuousMove(int cmd, double cmd_speed = 1); - bool sendOptStopMove(); - bool sendOptGotopreset(const std::string &preset_tag); - - void gotoPreset(); - - void setShowVoice(bool bo); - - void setVoiceNum(); -private slots: - void play(); - void pause(); - void capture(); - - void leftPressed(); - void released(); - - void rightPressed(); - - void upPressed(); - - void downPressed(); - - void tretchPressed(); - void released_1(); - - void drawPressed(); - - void farPressed(); - - void nearPressed(); - - void bigPressed(); - - void smallPressed(); - - void voiceSliderShow(); - - void slotVoiceClose(int voice); - - void slotVoiceOpen(int voice); - - double getCurrentCmdspeed(); - - void slot_presets_itemChanged(const QString & str); -private: - QtAV::AVPlayer *m_player; - QtAV::VideoRenderer *m_s_vo; - CPlayerCfgParser m_playerCfgParser; - QPushButton *m_play,*m_pause; - - QPushButton *m_cap; //抓图 - QPushButton *m_voiceOpen,*m_voiceClose; - VoiceSlider *m_voiceSlider; - - QLabel m_ptz,m_tj,m_jj,m_gq,m_preset;//云台 调焦 聚焦 光圈 - QPushButton *m_up,*m_down,*m_left,*m_right; //上下左右 - QPushButton *m_tretch,*m_draw,*m_far,*m_near,*m_big,*m_small; //伸 缩 远 近 大 小 - QWidget *m_control_1; - QWidget *m_control_2; - QComboBox *m_combox; - QPushButton *m_allot; //调用 - - int m_nDomainId; - int m_nAppId; - std::string m_strNodeName; - std::string m_strAppName; - - kbd_net::CMbCommunicator m_com; - - //< 摄像头相关信息 - QString m_pointTag; //< 摄像头关联点 - CCamInfo m_caminfo; - int m_voice; - Ui::IpcPlusWidget *ui; - - QThread m_onvifThread; - -}; - -#endif // IPCPLUSWIDGET_H +#ifndef IPCPLUSWIDGET_H +#define IPCPLUSWIDGET_H + +#include +#include +#include +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "CCamInfo.h" +#include "COnvifOpt.h" +#include +#include +class Slider; +class QPushButton; +class QWidget; +class QToolButton; +class Renderer; +class VoiceSlider; +class QComboBox; + +namespace QtAV { + class AVPlayer; + class WidgetRenderer; + class AVError; +} +namespace Ui { +class IpcPlusWidget; +} + +class IpcPlusWidget : public QWidget +{ + Q_OBJECT +public: + explicit IpcPlusWidget(bool editMode = false,QWidget *parent = 0); + ~IpcPlusWidget(); +public slots: + void setStreamInfo(QString pointTag); + void setNodeInfo(int nDomainId,int nAppid); + void setNodeName(const QString &nodeName); + void setAppName(const QString &appName); + + void slotInitStream(CCamInfo caminfo, int result); +signals: + void sigCamInfo(CCamInfo caminfo); +private: + void init(); + void loadCamInfo(); + void startStream(); + void setCapturePath(); + + bool ptzContinuousMove(int cmd,double cmd_speed = 1); + bool ptzStopMove(); + bool ptzGotopreset(const std::string &preset_tag); + + bool sendOptContinuousMove(int cmd, double cmd_speed = 1); + bool sendOptStopMove(); + bool sendOptGotopreset(const std::string &preset_tag); + + void gotoPreset(); + + void setShowVoice(bool bo); + + void setVoiceNum(); +private slots: + void play(); + void pause(); + void capture(); + + void leftPressed(); + void released(); + + void rightPressed(); + + void upPressed(); + + void downPressed(); + + void tretchPressed(); + void released_1(); + + void drawPressed(); + + void farPressed(); + + void nearPressed(); + + void bigPressed(); + + void smallPressed(); + + void voiceSliderShow(); + + void slotVoiceClose(int voice); + + void slotVoiceOpen(int voice); + + double getCurrentCmdspeed(); + + void slot_presets_itemChanged(const QString & str); +private: + QtAV::AVPlayer *m_player; + QtAV::VideoRenderer *m_s_vo; + CPlayerCfgParser m_playerCfgParser; + QPushButton *m_play,*m_pause; + + QPushButton *m_cap; //抓图 + QPushButton *m_voiceOpen,*m_voiceClose; + VoiceSlider *m_voiceSlider; + + QLabel m_ptz,m_tj,m_jj,m_gq,m_preset;//云台 调焦 聚焦 光圈 + QPushButton *m_up,*m_down,*m_left,*m_right; //上下左右 + QPushButton *m_tretch,*m_draw,*m_far,*m_near,*m_big,*m_small; //伸 缩 远 近 大 小 + QWidget *m_control_1; + QWidget *m_control_2; + QComboBox *m_combox; + QPushButton *m_allot; //调用 + + int m_nDomainId; + int m_nAppId; + std::string m_strNodeName; + std::string m_strAppName; + + kbd_net::CMbCommunicator m_com; + + //< 摄像头相关信息 + QString m_pointTag; //< 摄像头关联点 + CCamInfo m_caminfo; + int m_voice; + Ui::IpcPlusWidget *ui; + + QThread m_onvifThread; + +}; + +#endif // IPCPLUSWIDGET_H diff --git a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.pro b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.pro index 32d18812..060d63f1 100644 --- a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.pro +++ b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.pro @@ -1,104 +1,104 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-03-26T11:28:36 -# -#------------------------------------------------- - -QT += core gui -CONFIG += no_batch - - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = IpcPlusWidget -TEMPLATE = lib -CONFIG += plugin -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -INCLUDEPATH += $$PWD \ - $$PWD/../../../3rd/include/QTAV/ \ - $$PWD/../../../3rd/include/QtAVWidgets/ \ - -SOURCES += \ -# main.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - IpcPlusWidget.cpp \ - VoiceSlider.cpp \ - IpcPlusPluginWidget.cpp \ - CCamInfo.cpp \ - CRdbAccessUtilty.cpp \ - COnvifOpt.cpp - - -HEADERS += \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - IpcPlusWidget.h \ - VoiceSlider.h \ - IpcPlusPluginWidget.h \ - CCamInfo.h \ - CPresetInfo.h \ - CRdbAccessUtilty.h \ - COnvifOpt.h - - -FORMS += \ - IpcPlusWidget.ui \ - VoiceSlider.ui - -LIBS += -llog4cplus -lpub_logger_api -lrdb_net_api -LIBS += -lnet_msg_bus_api -lpub_utility_api -LIBS += -lprotobuf - - -win32-msvc* { - -CONFIG(debug, debug|release) { - LIBS += -lQtAVd1 -lQtAVWidgetsd1 -} -CONFIG(release, debug|release) { - LIBS += -lQtAV1 -lQtAVWidgets1 -} -} - -linux-g++*{ - LIBS += -lQtAV -lQtAVWidgets -} - -LIBS += -lOnvifLib - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -#必须在common.pri之后包含 -#------------------------------------------------------------------- -QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri -exists($$QTAV_PRI) { - include($$QTAV_PRI) -}else { - error("FATAL error: can not find qtav.pri") -} - - -QTAVCFGPARSER_PRI=$$SRC_ROOT_PATH/tools/playerCfgParser/qtavconfigparser.pri -exists($$QTAVCFGPARSER_PRI) { - include($$QTAVCFGPARSER_PRI) -}else { - error("FATAL error: can not find qtavcfgparser.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2020-03-26T11:28:36 +# +#------------------------------------------------- + +QT += core gui +CONFIG += no_batch + + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = IpcPlusWidget +TEMPLATE = lib +CONFIG += plugin +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +INCLUDEPATH += $$PWD \ + $$PWD/../../../3rd/include/QTAV/ \ + $$PWD/../../../3rd/include/QtAVWidgets/ \ + +SOURCES += \ +# main.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + IpcPlusWidget.cpp \ + VoiceSlider.cpp \ + IpcPlusPluginWidget.cpp \ + CCamInfo.cpp \ + CRdbAccessUtilty.cpp \ + COnvifOpt.cpp + + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + IpcPlusWidget.h \ + VoiceSlider.h \ + IpcPlusPluginWidget.h \ + CCamInfo.h \ + CPresetInfo.h \ + CRdbAccessUtilty.h \ + COnvifOpt.h + + +FORMS += \ + IpcPlusWidget.ui \ + VoiceSlider.ui + +LIBS += -llog4cplus -lpub_logger_api -lrdb_net_api +LIBS += -lnet_msg_bus_api -lpub_utility_api +LIBS += -lprotobuf + + +win32-msvc* { + +CONFIG(debug, debug|release) { + LIBS += -lQtAVd1 -lQtAVWidgetsd1 +} +CONFIG(release, debug|release) { + LIBS += -lQtAV1 -lQtAVWidgets1 +} +} + +linux-g++*{ + LIBS += -lQtAV -lQtAVWidgets +} + +LIBS += -lOnvifLib + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +#必须在common.pri之后包含 +#------------------------------------------------------------------- +QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri +exists($$QTAV_PRI) { + include($$QTAV_PRI) +}else { + error("FATAL error: can not find qtav.pri") +} + + +QTAVCFGPARSER_PRI=$$SRC_ROOT_PATH/tools/playerCfgParser/qtavconfigparser.pri +exists($$QTAVCFGPARSER_PRI) { + include($$QTAVCFGPARSER_PRI) +}else { + error("FATAL error: can not find qtavcfgparser.pri") +} + diff --git a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.ui b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.ui index d2401d43..43198aa0 100644 --- a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.ui +++ b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.ui @@ -1,47 +1,47 @@ - - - IpcPlusWidget - - - - 0 - 0 - 503 - 419 - - - - IpcPlusWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - + + + IpcPlusWidget + + + + 0 + 0 + 503 + 419 + + + + IpcPlusWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + diff --git a/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.cpp b/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.cpp index c7e5a562..5b07b54b 100644 --- a/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.cpp @@ -1,77 +1,77 @@ -#include "VoiceSlider.h" -#include "ui_VoiceSlider.h" - -VoiceSlider::VoiceSlider(int voice,bool bo, QWidget *parent, Qt::WindowFlags f) : - QWidget(parent,f), - m_bo(bo), - m_isShow(false), - ui(new Ui::VoiceSlider) -{ - ui->setupUi(this); - ui->voiceOpen->setObjectName("voiceOpen"); - ui->voiceClose->setObjectName("voiceClose"); - m_voice = voice; - setWindowOpacity(0.5); - connect(ui->horizontalSlider,&QSlider::valueChanged,this,&VoiceSlider::slotSetVoice); - connect(ui->voiceOpen,&QPushButton::clicked,this,&VoiceSlider::slotCloseVoice); - connect(ui->voiceClose,&QPushButton::clicked,this,&VoiceSlider::slotOpenVoice); - ui->horizontalSlider->setValue(m_voice); - setButtonShow(m_bo); -} - -VoiceSlider::~VoiceSlider() -{ - delete ui; -} - -void VoiceSlider::slotSetVoice(int value) -{ - ui->label->setText(QString("%1").arg(value)); - m_voice = value; - if(value == 0) - { - setButtonShow(false); - emit sigVoiceClose(value); - }else - { - setButtonShow(true); - emit sigVoiceOpen(value); - } -} - -void VoiceSlider::slotCloseVoice() -{ - setButtonShow(false); - emit sigVoiceClose(0); -} - -void VoiceSlider::slotOpenVoice() -{ - setButtonShow(true); - emit sigVoiceOpen(m_voice); -} - -void VoiceSlider::setStatus(bool show) -{ - m_isShow = show; -} - -bool VoiceSlider::getStatus() -{ - return m_isShow; -} - -void VoiceSlider::setButtonShow(bool show) -{ - if(show) - { - m_bo = show; - ui->voiceOpen->setHidden(false); - ui->voiceClose->setHidden(true); - }else - { - m_bo = !show; - ui->voiceOpen->setHidden(true); - ui->voiceClose->setHidden(false); - } -} +#include "VoiceSlider.h" +#include "ui_VoiceSlider.h" + +VoiceSlider::VoiceSlider(int voice,bool bo, QWidget *parent, Qt::WindowFlags f) : + QWidget(parent,f), + m_bo(bo), + m_isShow(false), + ui(new Ui::VoiceSlider) +{ + ui->setupUi(this); + ui->voiceOpen->setObjectName("voiceOpen"); + ui->voiceClose->setObjectName("voiceClose"); + m_voice = voice; + setWindowOpacity(0.5); + connect(ui->horizontalSlider,&QSlider::valueChanged,this,&VoiceSlider::slotSetVoice); + connect(ui->voiceOpen,&QPushButton::clicked,this,&VoiceSlider::slotCloseVoice); + connect(ui->voiceClose,&QPushButton::clicked,this,&VoiceSlider::slotOpenVoice); + ui->horizontalSlider->setValue(m_voice); + setButtonShow(m_bo); +} + +VoiceSlider::~VoiceSlider() +{ + delete ui; +} + +void VoiceSlider::slotSetVoice(int value) +{ + ui->label->setText(QString("%1").arg(value)); + m_voice = value; + if(value == 0) + { + setButtonShow(false); + emit sigVoiceClose(value); + }else + { + setButtonShow(true); + emit sigVoiceOpen(value); + } +} + +void VoiceSlider::slotCloseVoice() +{ + setButtonShow(false); + emit sigVoiceClose(0); +} + +void VoiceSlider::slotOpenVoice() +{ + setButtonShow(true); + emit sigVoiceOpen(m_voice); +} + +void VoiceSlider::setStatus(bool show) +{ + m_isShow = show; +} + +bool VoiceSlider::getStatus() +{ + return m_isShow; +} + +void VoiceSlider::setButtonShow(bool show) +{ + if(show) + { + m_bo = show; + ui->voiceOpen->setHidden(false); + ui->voiceClose->setHidden(true); + }else + { + m_bo = !show; + ui->voiceOpen->setHidden(true); + ui->voiceClose->setHidden(false); + } +} diff --git a/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.h b/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.h index dcba008b..a3c5c39d 100644 --- a/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.h +++ b/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.h @@ -1,39 +1,39 @@ -#ifndef VOICESLIDER_H -#define VOICESLIDER_H - -#include - -namespace Ui { -class VoiceSlider; -} - -class VoiceSlider : public QWidget -{ - Q_OBJECT - -public: - explicit VoiceSlider(int voice,bool bo,QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); - ~VoiceSlider(); -signals: - void sigVoiceClose(int value); - void sigVoiceOpen(int value); -public: - void slotSetVoice(int value); - void slotCloseVoice(); - void slotOpenVoice(); - void setStatus(bool show); - bool getStatus(); -private: - void setButtonShow(bool show); -private: - - int m_voice; - bool m_bo; - bool m_isShow; - - Ui::VoiceSlider *ui; - - -}; - -#endif // VOICESLIDER_H +#ifndef VOICESLIDER_H +#define VOICESLIDER_H + +#include + +namespace Ui { +class VoiceSlider; +} + +class VoiceSlider : public QWidget +{ + Q_OBJECT + +public: + explicit VoiceSlider(int voice,bool bo,QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); + ~VoiceSlider(); +signals: + void sigVoiceClose(int value); + void sigVoiceOpen(int value); +public: + void slotSetVoice(int value); + void slotCloseVoice(); + void slotOpenVoice(); + void setStatus(bool show); + bool getStatus(); +private: + void setButtonShow(bool show); +private: + + int m_voice; + bool m_bo; + bool m_isShow; + + Ui::VoiceSlider *ui; + + +}; + +#endif // VOICESLIDER_H diff --git a/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.ui b/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.ui index 58c8e4e3..5519720c 100644 --- a/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.ui +++ b/product/src/gui/plugin/IpcPlusWidget/VoiceSlider.ui @@ -1,122 +1,122 @@ - - - VoiceSlider - - - - 0 - 0 - 194 - 33 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - 26 - - - - - 30 - 16777215 - - - - - - - - - - - - 0 - 26 - - - - - 30 - 16777215 - - - - - - - - - - - Qt::Horizontal - - - - - - - - 30 - 0 - - - - Qt::LeftToRight - - - - - - 0 - - - Qt::AlignCenter - - - - - - - - - - - - - + + + VoiceSlider + + + + 0 + 0 + 194 + 33 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 26 + + + + + 30 + 16777215 + + + + + + + + + + + + 0 + 26 + + + + + 30 + 16777215 + + + + + + + + + + + Qt::Horizontal + + + + + + + + 30 + 0 + + + + Qt::LeftToRight + + + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/IpcPlusWidget/main.cpp b/product/src/gui/plugin/IpcPlusWidget/main.cpp index e7ac8204..176a0a6f 100644 --- a/product/src/gui/plugin/IpcPlusWidget/main.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/main.cpp @@ -1,26 +1,26 @@ -#include "IpcPlusWidget.h" -#include -#include "net_msg_bus_api/MsgBusApi.h" -#include "pub_logger_api/logger.h" -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - { - IpcPlusWidget w(false,NULL); - w.setNodeInfo(1,4); - w.setNodeName("kbdctrd-jxd"); - w.setAppName("hmi"); - w.setStreamInfo("analog.syx.ZLQR2_jgxh.WD"); - w.show(); - a.exec(); - } - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "IpcPlusWidget.h" +#include +#include "net_msg_bus_api/MsgBusApi.h" +#include "pub_logger_api/logger.h" +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + { + IpcPlusWidget w(false,NULL); + w.setNodeInfo(1,4); + w.setNodeName("kbdctrd-jxd"); + w.setAppName("hmi"); + w.setStreamInfo("analog.syx.ZLQR2_jgxh.WD"); + w.show(); + a.exec(); + } + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/IpcViewerWidget/IpcViewerWidget.pro b/product/src/gui/plugin/IpcViewerWidget/IpcViewerWidget.pro index 36f43270..90f9c323 100644 --- a/product/src/gui/plugin/IpcViewerWidget/IpcViewerWidget.pro +++ b/product/src/gui/plugin/IpcViewerWidget/IpcViewerWidget.pro @@ -1,120 +1,120 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-02-21T10:03:40 -# -#------------------------------------------------- - -QT += core gui -CONFIG += no_batch - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = IpcViewerWidget -TEMPLATE = lib -#TEMPLATE = app -CONFIG += plugin - - - - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - - -DEFINES += IPCVIEWERWIDGET_LIBRARY - - -SOURCES += \ - main.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - crdbaccessutilty.cpp \ - ccaminfo.cpp \ - ipcviewerpluginwidget.cpp \ - ipcviewerwidget.cpp \ - cipcviewermsgbusmng.cpp - -HEADERS += \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - crdbaccessutilty.h \ - ccaminfo.h \ - ipcviewerpluginwidget.h \ - ipcviewerwidget.h \ - cipcviewermsgbusmng.h \ - ipcViewerWidget_global.h - -FORMS += \ - ipcviewerwidget.ui - -TRANSLATIONS += $$PWD/en.ts - -include($$PWD/../../../idl_files/idl_files.pri) - -LIB += -lboost_system \ - -lboost_filesystem \ - -lboost_thread \ - -lnet_msg_bus_api \ - - -LIBS += -llog4cplus -lpub_logger_api -lrdb_net_api -LIBS += -lnet_msg_bus_api -lpub_utility_api -LIBS += -lprotobuf - - -win32-msvc* { - -CONFIG(debug, debug|release) { - LIBS += -lQtAVd1 -lQtAVWidgetsd1 -} -CONFIG(release, debug|release) { - LIBS += -lQtAV1 -lQtAVWidgets1 -} -} - -linux-g++*{ - LIBS += -lQtAV -lQtAVWidgets -} - -LIBS += -lOnvifLib - - - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -#必须在common.pri之后包含 -#------------------------------------------------------------------- -QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri -exists($$QTAV_PRI) { - include($$QTAV_PRI) -}else { - error("FATAL error: can not find qtav.pri") -} - -QTAVCFGPARSER_PRI=$$SRC_ROOT_PATH/tools/playerCfgParser/qtavconfigparser.pri -exists($$QTAVCFGPARSER_PRI) { - include($$QTAVCFGPARSER_PRI) -}else { - error("FATAL error: can not find qtavcfgparser.pri") -} - - - - - -RESOURCES += \ - res.qrc - +#------------------------------------------------- +# +# Project created by QtCreator 2020-02-21T10:03:40 +# +#------------------------------------------------- + +QT += core gui +CONFIG += no_batch + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = IpcViewerWidget +TEMPLATE = lib +#TEMPLATE = app +CONFIG += plugin + + + + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + + +DEFINES += IPCVIEWERWIDGET_LIBRARY + + +SOURCES += \ + main.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + crdbaccessutilty.cpp \ + ccaminfo.cpp \ + ipcviewerpluginwidget.cpp \ + ipcviewerwidget.cpp \ + cipcviewermsgbusmng.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + crdbaccessutilty.h \ + ccaminfo.h \ + ipcviewerpluginwidget.h \ + ipcviewerwidget.h \ + cipcviewermsgbusmng.h \ + ipcViewerWidget_global.h + +FORMS += \ + ipcviewerwidget.ui + +TRANSLATIONS += $$PWD/en.ts + +include($$PWD/../../../idl_files/idl_files.pri) + +LIB += -lboost_system \ + -lboost_filesystem \ + -lboost_thread \ + -lnet_msg_bus_api \ + + +LIBS += -llog4cplus -lpub_logger_api -lrdb_net_api +LIBS += -lnet_msg_bus_api -lpub_utility_api +LIBS += -lprotobuf + + +win32-msvc* { + +CONFIG(debug, debug|release) { + LIBS += -lQtAVd1 -lQtAVWidgetsd1 +} +CONFIG(release, debug|release) { + LIBS += -lQtAV1 -lQtAVWidgets1 +} +} + +linux-g++*{ + LIBS += -lQtAV -lQtAVWidgets +} + +LIBS += -lOnvifLib + + + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +#必须在common.pri之后包含 +#------------------------------------------------------------------- +QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri +exists($$QTAV_PRI) { + include($$QTAV_PRI) +}else { + error("FATAL error: can not find qtav.pri") +} + +QTAVCFGPARSER_PRI=$$SRC_ROOT_PATH/tools/playerCfgParser/qtavconfigparser.pri +exists($$QTAVCFGPARSER_PRI) { + include($$QTAVCFGPARSER_PRI) +}else { + error("FATAL error: can not find qtavcfgparser.pri") +} + + + + + +RESOURCES += \ + res.qrc + diff --git a/product/src/gui/plugin/IpcViewerWidget/ccaminfo.cpp b/product/src/gui/plugin/IpcViewerWidget/ccaminfo.cpp index dbb820b5..29734689 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ccaminfo.cpp +++ b/product/src/gui/plugin/IpcViewerWidget/ccaminfo.cpp @@ -1,465 +1,465 @@ -#include "ccaminfo.h" -#include "OnvifLibs/onvif.h" -#include -#include -#include - -#define PRESET_CHAN_NO 1 - -CCamInfo::CCamInfo() -{ - -} - -std::string CCamInfo::pointTag() const -{ - return m_pointTag; -} - -void CCamInfo::setPointTag(const std::string &pointTag) -{ - m_pointTag = pointTag; -} - -std::string CCamInfo::camTag() const -{ - return m_camTag; -} - -void CCamInfo::setCamTag(const std::string &camTag) -{ - m_camTag = camTag; -} - -std::string CCamInfo::presetTag() const -{ - return m_presetTag; -} - -void CCamInfo::setPresetTag(const std::string &presetTag) -{ - m_presetTag = presetTag; -} - - - - -std::string CCamInfo::ip() const -{ - return m_ip; -} - -void CCamInfo::setIp(const std::string &ip) -{ - m_ip = ip; -} - -std::string CCamInfo::description() const -{ - return m_description; -} - -void CCamInfo::setDescription(const std::string &description) -{ - m_description = description; -} - -std::string CCamInfo::username() const -{ - return m_username; -} - -void CCamInfo::setUsername(const std::string &username) -{ - m_username = username; -} - -std::string CCamInfo::password() const -{ - return m_password; -} - -void CCamInfo::setPassword(const std::string &password) -{ - m_password = password; -} - -std::string CCamInfo::serviceAddr() const -{ - return m_serviceAddr; -} - -void CCamInfo::setServiceAddr(const std::string &serviceAddr) -{ - m_serviceAddr = serviceAddr; -} - -void CCamInfo::getNvrArgs() -{ - QElapsedTimer timer; - timer.start(); - //< 录像ip相关=============================================================================================== - /*** - * 原来的东西不变 - * ,填充streamRtspAddr(直播用)和replayRtspAddr(回放用)和profileToken(ptz用,搭配ptzxaddr) 和能力使能 - * 1. 生成onvif的device_address - * 2. 获取能力 capabilities,根据能力填充使能信息 - * 若MediaXAddr为空,则无法直播 - * 若PTZXAddr为空,则无法进行ptz控制 - * 若SearchXAddr和ReplayXAddr有一为空,则无法进行回放 - * 3. 填充直播相关的东西 - * 3.1 获取profile - * 3.2 获取直播地址 - * 4. 获取录播相关的东西 - * 4.1 获取录播recordingtoken - * 4.2 获取回放地址 - * - * - */ - - std::string service_addr = std::string("http://") + this->ip() + "/onvif/device_service"; - this->setServiceAddr(service_addr); - - //=============能力相关================= - XAddr addr; - Onvif::getCapabilities(service_addr,addr); - - if(addr.MediaXAddr == "") - { - this->setIsStreamEnabled(false); - } - - if(addr.PTZXAddr == "") - { - this->setIsPtzEnabled(false); - } - this->setPtzAddr(addr.PTZXAddr); - - if(addr.ReplayXAddr == "" || addr.SearchXAddr == "") - { - this->setIsReplayEnabled(false); - } - //=============能力相关================= - - qDebug() << "能力相关 " << timer.elapsed() /1000.0 << "s"; - timer.restart(); - - //=============直播相关==================== - if(addr.MediaXAddr != "") - { - if(Onvif::getProfileTokens(addr.MediaXAddr,this->getChanNo(),this->username(),this->password(),this->m_mediaProfileToken) != Onvif::NoError) - { - this->setIsStreamEnabled(false); - } - else - { - if(Onvif::getStreamUrl(addr.MediaXAddr,this->m_mediaProfileToken,this->username(),this->password(),this->m_streamRtspAddr) != Onvif::NoError) - { - this->setIsStreamEnabled(false); - } - else - { - this->m_streamRtspAddr = this->m_streamRtspAddr.substr(0,7) + this->username() + ":" + this->password() + "@" + this->m_streamRtspAddr.substr(7); - } - } - } - //=============直播相关==================== - - qDebug() << "直播相关 " << timer.elapsed() /1000.0 << "s"; - timer.restart(); - - //=============回放相关==================== - - if(addr.ReplayXAddr != "" && addr.SearchXAddr != "") - { - if(Onvif::getRecordToken(addr.SearchXAddr,this->getChanNo(),this->username(),this->password(),this->m_recordToken) != Onvif::NoError) - { - this->setIsReplayEnabled(false); - } - else - { - if(Onvif::getReplayUrl(addr.ReplayXAddr,this->m_recordToken,this->username(),this->password(),this->m_replayRtspAddr) != Onvif::NoError) - { - this->setIsReplayEnabled(false); - } - else - { - this->m_replayRtspAddr = this->m_replayRtspAddr.substr(0,7) + this->username() + ":" + this->password() + "@" +this->m_replayRtspAddr.substr(7); - } - } - } - //=============回放相关==================== - //> 录像ip相关=============================================================================================== - qDebug() << "回放相关 " << timer.elapsed() /1000.0 << "s"; - timer.restart(); -} - -void CCamInfo::getPresetArgs() -{ - /*** - * 云台ip相关的东西比较少,获取profile能够转到预置点即可 - */ - - std::string service_addr = std::string("http://") + this->getPtzIp() + "/onvif/device_service"; - this->setPreServiceAddr(service_addr); - - //=============能力相关================= - XAddr addr; - Onvif::getCapabilities(service_addr,addr); - - if(addr.MediaXAddr == "" || addr.PTZXAddr == "") - { - this->setIsPresetEnabled(false); - return; - } - this->setPrePtzAddr(addr.PTZXAddr); - - //=============能力相关================= - if(Onvif::getProfileTokens(addr.MediaXAddr,PRESET_CHAN_NO,this->username(),this->password(),this->m_prePtzMediaProfile) != Onvif::NoError) - { - this->setIsPresetEnabled(false); - } -} - -bool CCamInfo::getIsPresetEnabled() const -{ - return m_isPresetEnabled; -} - -void CCamInfo::setIsPresetEnabled(bool isPresetEnabled) -{ - m_isPresetEnabled = isPresetEnabled; -} - -std::string CCamInfo::getPrePtzMediaProfile() const -{ - return m_prePtzMediaProfile; -} - -void CCamInfo::setPrePtzMediaProfile(const std::string &prePtzMediaProfile) -{ - m_prePtzMediaProfile = prePtzMediaProfile; -} - -std::string CCamInfo::getPrePtzAddr() const -{ - return m_prePtzAddr; -} - -void CCamInfo::setPrePtzAddr(const std::string &prePtzAddr) -{ - m_prePtzAddr = prePtzAddr; -} - -std::string CCamInfo::getPreMediaAddr() const -{ - return m_preMediaAddr; -} - -void CCamInfo::setPreMediaAddr(const std::string &preMediaAddr) -{ - m_preMediaAddr = preMediaAddr; -} - -std::string CCamInfo::getPreServiceAddr() const -{ - return m_preServiceAddr; -} - -void CCamInfo::setPreServiceAddr(const std::string &preServiceAddr) -{ - m_preServiceAddr = preServiceAddr; -} - -std::string CCamInfo::getPtzIp() const -{ - return m_ptzIp; -} - -void CCamInfo::setPtzIp(const std::string &ptzIp) -{ - m_ptzIp = ptzIp; -} - - -std::string CCamInfo::mediaAddr() const -{ - return m_mediaAddr; -} - -void CCamInfo::setMediaAddr(const std::string &mediaAddr) -{ - m_mediaAddr = mediaAddr; -} - -std::string CCamInfo::ptzAddr() const -{ - return m_ptzAddr; -} - -void CCamInfo::setPtzAddr(const std::string &ptzAddr) -{ - m_ptzAddr = ptzAddr; -} - -std::string CCamInfo::recordSearchAddr() const -{ - return m_recordSearchAddr; -} - -void CCamInfo::setRecordSearchAddr(const std::string &recordSearchAddr) -{ - m_recordSearchAddr = recordSearchAddr; -} - -std::string CCamInfo::replayAddr() const -{ - return m_replayAddr; -} - -void CCamInfo::setReplayAddr(const std::string &replayAddr) -{ - m_replayAddr = replayAddr; -} - -bool CCamInfo::isStreamEnabled() const -{ - return m_isStreamEnabled; -} - -void CCamInfo::setIsStreamEnabled(bool isStreamEnabled) -{ - m_isStreamEnabled = isStreamEnabled; -} - -bool CCamInfo::isPtzEnabled() const -{ - return m_isPtzEnabled; -} - -void CCamInfo::setIsPtzEnabled(bool isPtzEnabled) -{ - m_isPtzEnabled = isPtzEnabled; -} - -bool CCamInfo::isReplayEnabled() const -{ - return m_isReplayEnabled; -} - -void CCamInfo::setIsReplayEnabled(bool isReplayEnabled) -{ - m_isReplayEnabled = isReplayEnabled; -} - -std::vector CCamInfo::presets() const -{ - return m_presets; -} - -void CCamInfo::setPresets(const std::vector &presets) -{ - m_presets = presets; -} - -void CCamInfo::addPreset(const std::string &presetTag_, const std::string &presetToken_, const std::string &presetDesc_) -{ - m_presets.push_back(CPresetInfo(presetTag_,presetToken_,presetDesc_)); -} - -bool CCamInfo::getPresetDesc(const std::string &preset_tag, std::string &outDesc) -{ - for(int i = 0; i < (int)m_presets.size(); i++) - { - if(m_presets.at(i).presetTag == preset_tag) - { - outDesc = m_presets.at(i).presetDesc; - return true; - } - } - return false; -} - -bool CCamInfo::getPresetToken(const std::string &preset_tag, std::string &outToken) -{ - for(int i = 0; i < (int)m_presets.size(); i++) - { - if(m_presets.at(i).presetTag == preset_tag) - { - outToken = m_presets.at(i).presetToken; - return true; - } - } - return false; -} - -int CCamInfo::getChanNo() const -{ - return m_chanNo; -} - -void CCamInfo::setChanNo(int chan_no) -{ - m_chanNo = chan_no; -} - -void CCamInfo::getOnvifArgs() -{ - QElapsedTimer timer; - timer.start(); - getNvrArgs(); - qDebug() << "first onvif " << timer.elapsed() /1000.0 << "s"; - timer.restart(); - getPresetArgs(); - qDebug() << "second onvif " << timer.elapsed() /1000.0 << "s"; -} - -std::string CCamInfo::getStreamRtspAddr() const -{ - return m_streamRtspAddr; -} - -std::string CCamInfo::getReplayRtspAddr() const -{ - return m_replayRtspAddr; -} - -bool CCamInfo::continuousMove(int cmd, double cmd_speed) -{ - if(!m_isPtzEnabled) - return false; - - if(Onvif::continuousMove(this->ptzAddr(),this->m_mediaProfileToken,this->username(),this->password(),cmd,cmd_speed) == -1) - { - return false; - } - return true; -} - -bool CCamInfo::stopMove() -{ - if(!m_isPtzEnabled) - return false; - - if(Onvif::stopMove(this->ptzAddr(),this->m_mediaProfileToken,this->username(),this->password()) == -1) - { - return false; - } - return true; -} - -bool CCamInfo::gotoPreset(const std::string &preset_tag) -{ - if(!m_isPresetEnabled) - return false; - - std::string preset_token; - if(!getPresetToken(preset_tag,preset_token)) - return false; - if(Onvif::gotoPreset(this->getPrePtzAddr(),this->m_prePtzMediaProfile,preset_token,this->username(),this->password()) == -1) - { - return false; - } - return true; -} - +#include "ccaminfo.h" +#include "OnvifLibs/onvif.h" +#include +#include +#include + +#define PRESET_CHAN_NO 1 + +CCamInfo::CCamInfo() +{ + +} + +std::string CCamInfo::pointTag() const +{ + return m_pointTag; +} + +void CCamInfo::setPointTag(const std::string &pointTag) +{ + m_pointTag = pointTag; +} + +std::string CCamInfo::camTag() const +{ + return m_camTag; +} + +void CCamInfo::setCamTag(const std::string &camTag) +{ + m_camTag = camTag; +} + +std::string CCamInfo::presetTag() const +{ + return m_presetTag; +} + +void CCamInfo::setPresetTag(const std::string &presetTag) +{ + m_presetTag = presetTag; +} + + + + +std::string CCamInfo::ip() const +{ + return m_ip; +} + +void CCamInfo::setIp(const std::string &ip) +{ + m_ip = ip; +} + +std::string CCamInfo::description() const +{ + return m_description; +} + +void CCamInfo::setDescription(const std::string &description) +{ + m_description = description; +} + +std::string CCamInfo::username() const +{ + return m_username; +} + +void CCamInfo::setUsername(const std::string &username) +{ + m_username = username; +} + +std::string CCamInfo::password() const +{ + return m_password; +} + +void CCamInfo::setPassword(const std::string &password) +{ + m_password = password; +} + +std::string CCamInfo::serviceAddr() const +{ + return m_serviceAddr; +} + +void CCamInfo::setServiceAddr(const std::string &serviceAddr) +{ + m_serviceAddr = serviceAddr; +} + +void CCamInfo::getNvrArgs() +{ + QElapsedTimer timer; + timer.start(); + //< 录像ip相关=============================================================================================== + /*** + * 原来的东西不变 + * ,填充streamRtspAddr(直播用)和replayRtspAddr(回放用)和profileToken(ptz用,搭配ptzxaddr) 和能力使能 + * 1. 生成onvif的device_address + * 2. 获取能力 capabilities,根据能力填充使能信息 + * 若MediaXAddr为空,则无法直播 + * 若PTZXAddr为空,则无法进行ptz控制 + * 若SearchXAddr和ReplayXAddr有一为空,则无法进行回放 + * 3. 填充直播相关的东西 + * 3.1 获取profile + * 3.2 获取直播地址 + * 4. 获取录播相关的东西 + * 4.1 获取录播recordingtoken + * 4.2 获取回放地址 + * + * + */ + + std::string service_addr = std::string("http://") + this->ip() + "/onvif/device_service"; + this->setServiceAddr(service_addr); + + //=============能力相关================= + XAddr addr; + Onvif::getCapabilities(service_addr,addr); + + if(addr.MediaXAddr == "") + { + this->setIsStreamEnabled(false); + } + + if(addr.PTZXAddr == "") + { + this->setIsPtzEnabled(false); + } + this->setPtzAddr(addr.PTZXAddr); + + if(addr.ReplayXAddr == "" || addr.SearchXAddr == "") + { + this->setIsReplayEnabled(false); + } + //=============能力相关================= + + qDebug() << "能力相关 " << timer.elapsed() /1000.0 << "s"; + timer.restart(); + + //=============直播相关==================== + if(addr.MediaXAddr != "") + { + if(Onvif::getProfileTokens(addr.MediaXAddr,this->getChanNo(),this->username(),this->password(),this->m_mediaProfileToken) != Onvif::NoError) + { + this->setIsStreamEnabled(false); + } + else + { + if(Onvif::getStreamUrl(addr.MediaXAddr,this->m_mediaProfileToken,this->username(),this->password(),this->m_streamRtspAddr) != Onvif::NoError) + { + this->setIsStreamEnabled(false); + } + else + { + this->m_streamRtspAddr = this->m_streamRtspAddr.substr(0,7) + this->username() + ":" + this->password() + "@" + this->m_streamRtspAddr.substr(7); + } + } + } + //=============直播相关==================== + + qDebug() << "直播相关 " << timer.elapsed() /1000.0 << "s"; + timer.restart(); + + //=============回放相关==================== + + if(addr.ReplayXAddr != "" && addr.SearchXAddr != "") + { + if(Onvif::getRecordToken(addr.SearchXAddr,this->getChanNo(),this->username(),this->password(),this->m_recordToken) != Onvif::NoError) + { + this->setIsReplayEnabled(false); + } + else + { + if(Onvif::getReplayUrl(addr.ReplayXAddr,this->m_recordToken,this->username(),this->password(),this->m_replayRtspAddr) != Onvif::NoError) + { + this->setIsReplayEnabled(false); + } + else + { + this->m_replayRtspAddr = this->m_replayRtspAddr.substr(0,7) + this->username() + ":" + this->password() + "@" +this->m_replayRtspAddr.substr(7); + } + } + } + //=============回放相关==================== + //> 录像ip相关=============================================================================================== + qDebug() << "回放相关 " << timer.elapsed() /1000.0 << "s"; + timer.restart(); +} + +void CCamInfo::getPresetArgs() +{ + /*** + * 云台ip相关的东西比较少,获取profile能够转到预置点即可 + */ + + std::string service_addr = std::string("http://") + this->getPtzIp() + "/onvif/device_service"; + this->setPreServiceAddr(service_addr); + + //=============能力相关================= + XAddr addr; + Onvif::getCapabilities(service_addr,addr); + + if(addr.MediaXAddr == "" || addr.PTZXAddr == "") + { + this->setIsPresetEnabled(false); + return; + } + this->setPrePtzAddr(addr.PTZXAddr); + + //=============能力相关================= + if(Onvif::getProfileTokens(addr.MediaXAddr,PRESET_CHAN_NO,this->username(),this->password(),this->m_prePtzMediaProfile) != Onvif::NoError) + { + this->setIsPresetEnabled(false); + } +} + +bool CCamInfo::getIsPresetEnabled() const +{ + return m_isPresetEnabled; +} + +void CCamInfo::setIsPresetEnabled(bool isPresetEnabled) +{ + m_isPresetEnabled = isPresetEnabled; +} + +std::string CCamInfo::getPrePtzMediaProfile() const +{ + return m_prePtzMediaProfile; +} + +void CCamInfo::setPrePtzMediaProfile(const std::string &prePtzMediaProfile) +{ + m_prePtzMediaProfile = prePtzMediaProfile; +} + +std::string CCamInfo::getPrePtzAddr() const +{ + return m_prePtzAddr; +} + +void CCamInfo::setPrePtzAddr(const std::string &prePtzAddr) +{ + m_prePtzAddr = prePtzAddr; +} + +std::string CCamInfo::getPreMediaAddr() const +{ + return m_preMediaAddr; +} + +void CCamInfo::setPreMediaAddr(const std::string &preMediaAddr) +{ + m_preMediaAddr = preMediaAddr; +} + +std::string CCamInfo::getPreServiceAddr() const +{ + return m_preServiceAddr; +} + +void CCamInfo::setPreServiceAddr(const std::string &preServiceAddr) +{ + m_preServiceAddr = preServiceAddr; +} + +std::string CCamInfo::getPtzIp() const +{ + return m_ptzIp; +} + +void CCamInfo::setPtzIp(const std::string &ptzIp) +{ + m_ptzIp = ptzIp; +} + + +std::string CCamInfo::mediaAddr() const +{ + return m_mediaAddr; +} + +void CCamInfo::setMediaAddr(const std::string &mediaAddr) +{ + m_mediaAddr = mediaAddr; +} + +std::string CCamInfo::ptzAddr() const +{ + return m_ptzAddr; +} + +void CCamInfo::setPtzAddr(const std::string &ptzAddr) +{ + m_ptzAddr = ptzAddr; +} + +std::string CCamInfo::recordSearchAddr() const +{ + return m_recordSearchAddr; +} + +void CCamInfo::setRecordSearchAddr(const std::string &recordSearchAddr) +{ + m_recordSearchAddr = recordSearchAddr; +} + +std::string CCamInfo::replayAddr() const +{ + return m_replayAddr; +} + +void CCamInfo::setReplayAddr(const std::string &replayAddr) +{ + m_replayAddr = replayAddr; +} + +bool CCamInfo::isStreamEnabled() const +{ + return m_isStreamEnabled; +} + +void CCamInfo::setIsStreamEnabled(bool isStreamEnabled) +{ + m_isStreamEnabled = isStreamEnabled; +} + +bool CCamInfo::isPtzEnabled() const +{ + return m_isPtzEnabled; +} + +void CCamInfo::setIsPtzEnabled(bool isPtzEnabled) +{ + m_isPtzEnabled = isPtzEnabled; +} + +bool CCamInfo::isReplayEnabled() const +{ + return m_isReplayEnabled; +} + +void CCamInfo::setIsReplayEnabled(bool isReplayEnabled) +{ + m_isReplayEnabled = isReplayEnabled; +} + +std::vector CCamInfo::presets() const +{ + return m_presets; +} + +void CCamInfo::setPresets(const std::vector &presets) +{ + m_presets = presets; +} + +void CCamInfo::addPreset(const std::string &presetTag_, const std::string &presetToken_, const std::string &presetDesc_) +{ + m_presets.push_back(CPresetInfo(presetTag_,presetToken_,presetDesc_)); +} + +bool CCamInfo::getPresetDesc(const std::string &preset_tag, std::string &outDesc) +{ + for(int i = 0; i < (int)m_presets.size(); i++) + { + if(m_presets.at(i).presetTag == preset_tag) + { + outDesc = m_presets.at(i).presetDesc; + return true; + } + } + return false; +} + +bool CCamInfo::getPresetToken(const std::string &preset_tag, std::string &outToken) +{ + for(int i = 0; i < (int)m_presets.size(); i++) + { + if(m_presets.at(i).presetTag == preset_tag) + { + outToken = m_presets.at(i).presetToken; + return true; + } + } + return false; +} + +int CCamInfo::getChanNo() const +{ + return m_chanNo; +} + +void CCamInfo::setChanNo(int chan_no) +{ + m_chanNo = chan_no; +} + +void CCamInfo::getOnvifArgs() +{ + QElapsedTimer timer; + timer.start(); + getNvrArgs(); + qDebug() << "first onvif " << timer.elapsed() /1000.0 << "s"; + timer.restart(); + getPresetArgs(); + qDebug() << "second onvif " << timer.elapsed() /1000.0 << "s"; +} + +std::string CCamInfo::getStreamRtspAddr() const +{ + return m_streamRtspAddr; +} + +std::string CCamInfo::getReplayRtspAddr() const +{ + return m_replayRtspAddr; +} + +bool CCamInfo::continuousMove(int cmd, double cmd_speed) +{ + if(!m_isPtzEnabled) + return false; + + if(Onvif::continuousMove(this->ptzAddr(),this->m_mediaProfileToken,this->username(),this->password(),cmd,cmd_speed) == -1) + { + return false; + } + return true; +} + +bool CCamInfo::stopMove() +{ + if(!m_isPtzEnabled) + return false; + + if(Onvif::stopMove(this->ptzAddr(),this->m_mediaProfileToken,this->username(),this->password()) == -1) + { + return false; + } + return true; +} + +bool CCamInfo::gotoPreset(const std::string &preset_tag) +{ + if(!m_isPresetEnabled) + return false; + + std::string preset_token; + if(!getPresetToken(preset_tag,preset_token)) + return false; + if(Onvif::gotoPreset(this->getPrePtzAddr(),this->m_prePtzMediaProfile,preset_token,this->username(),this->password()) == -1) + { + return false; + } + return true; +} + diff --git a/product/src/gui/plugin/IpcViewerWidget/ccaminfo.h b/product/src/gui/plugin/IpcViewerWidget/ccaminfo.h index 99b652f6..11b65060 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ccaminfo.h +++ b/product/src/gui/plugin/IpcViewerWidget/ccaminfo.h @@ -1,202 +1,202 @@ -#ifndef CCAMINFO_H -#define CCAMINFO_H - -#include -#include -#include - -/** - @brief 摄像头信息类 - @author ganyuhang - @date 2020-04-16 更新 - */ -class CPresetInfo -{ -public: - CPresetInfo(const std::string &presetTag_, - const std::string &presetToken_, - const std::string &presetDesc_) - { - presetToken = presetToken_; - presetTag = presetTag_; - presetDesc = presetDesc_; - } - - std::string presetToken; - std::string presetTag; - std::string presetDesc; -}; - -class CCamInfo -{ -public: - - CCamInfo(); - - std::string pointTag() const; - void setPointTag(const std::string &pointTag); - - std::string camTag() const; - void setCamTag(const std::string &camTag); - - std::string presetTag() const; - void setPresetTag(const std::string &presetTag); - - //< 预置点相关 - std::vector presets() const; - void setPresets(const std::vector &presets); - void addPreset(const std::string &presetTag_, - const std::string &presetToken_, - const std::string &presetDesc_); - - bool getPresetToken(const std::string &preset_tag, std::string &outToken); - bool getPresetDesc(const std::string &preset_tag, std::string &outDesc); - //> 预置点相关 - - std::string ip() const; - void setIp(const std::string &ip); - std::string getPtzIp() const; - void setPtzIp(const std::string &ptzIp); - - - int getChanNo() const; - void setChanNo(int chan_no); - - std::string description() const; - void setDescription(const std::string &description); - - std::string username() const; - void setUsername(const std::string &username); - - std::string password() const; - void setPassword(const std::string &password); - - //< 录像机ip相关属性 - std::string serviceAddr() const; - - std::string mediaAddr() const; - void setMediaAddr(const std::string &mediaAddr); - - std::string ptzAddr() const; - void setPtzAddr(const std::string &ptzAddr); - - std::string recordSearchAddr() const; - void setRecordSearchAddr(const std::string &recordSearchAddr); - - std::string replayAddr() const; - void setReplayAddr(const std::string &replayAddr); - - std::string getStreamRtspAddr() const; - std::string getReplayRtspAddr() const; - //> 录像机ip相关属性 - - - //< 云台ip相关属性 - std::string getPreServiceAddr() const; - - std::string getPreMediaAddr() const; - void setPreMediaAddr(const std::string &preMediaAddr); - - std::string getPrePtzAddr() const; - void setPrePtzAddr(const std::string &prePtzAddr); - - std::string getPrePtzMediaProfile() const; - void setPrePtzMediaProfile(const std::string &prePtzMediaProfile); - - bool continuousMove(int cmd, double cmd_speed); - bool stopMove(); - bool gotoPreset(const std::string & preset_tag); - //> 云台ip相关属性 - - - - //< 使能相关属性 - bool isStreamEnabled() const; - void setIsStreamEnabled(bool isStreamEnabled); - - bool isPtzEnabled() const; - void setIsPtzEnabled(bool isPtzEnabled); - - bool isReplayEnabled() const; - void setIsReplayEnabled(bool isReplayEnabled); - - bool getIsPresetEnabled() const; - void setIsPresetEnabled(bool isPresetEnabled); - //> 使能相关属性 - - - - /** - * @brief getOnvifArgs 通过onvif获取相关的参数 - * - * 参数 m_streamRtspAddr和m_replayRtspAddr以及m_ptzAddr,和直播,回放和控制使能相关的信息。 - */ - void getOnvifArgs(); - - -private: - void setServiceAddr(const std::string &serviceAddr); - void setPreServiceAddr(const std::string &preServiceAddr); - - - void getNvrArgs(); - void getPresetArgs(); - - - std::string m_pointTag; //< 点标签 [mix/analog/accuml/digital].[对应表tag_name] - std::string m_camTag; //< 点关联摄像头标签 cctv_camera_info表主键tag_name - std::string m_presetTag; //< 点关联预置点标签 cctv_orientation表主键tag_name - std::vector m_presets; //< 摄像头关联所有预置点 - - /** - * @brief m_chan_no - * - * @date 2020-04-16 兼容性修改,地铁一号线录像机设备不支持获取预置点 - * 录像/直播的通道,解释,可以参考SVN/ISCS6000文档\04系统设计\专业应用\CCTV\ISCS综合监控系统_概要设计说明书_视频告警和CCTV.docx - * http链接:http://192.168.79.248:88/svn/%E8%BD%A8%E9%81%93%E4%BA%A4%E9%80%9A%E7%BB%BC%E5%90%88%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F/Development_Repository/ISCS6000%E6%96%87%E6%A1%A3/04%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1/%E4%B8%93%E4%B8%9A%E5%BA%94%E7%94%A8/CCTV/ISCS%E7%BB%BC%E5%90%88%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F_%E6%A6%82%E8%A6%81%E8%AE%BE%E8%AE%A1%E8%AF%B4%E6%98%8E%E4%B9%A6_%E8%A7%86%E9%A2%91%E5%91%8A%E8%AD%A6%E5%92%8CCCTV.docx - * 有两个ip:录像机ip和云台ip - * - * 录像机ip用于直播、回放和PTZ控制,这里的chan_no时录像机ip的通道 - * 云台ip用于控制转到预置点,云台ip的通道为1 - * 录像机ip和云台ip的用户名和密码相一致 - */ - int m_chanNo; - std::string m_ip; - std::string m_ptzIp; - - std::string m_description; // 摄像头描述 - std::string m_username; // 用户名 - std::string m_password; // 密码 - - //< 录像机ip相关onvif属性 - std::string m_serviceAddr; // onvif服务地址 onvif入口总地址,请参见onvif协议 - std::string m_mediaAddr; // onvif的media协议入口地址 - std::string m_ptzAddr; // onvif的ptz协议入口地址 - std::string m_recordSearchAddr; // onvif的录像搜索协议地址 - std::string m_replayAddr; // onvif的replay协议地址 - std::string m_mediaProfileToken;// onvif的media播放profile - std::string m_recordToken; // onvif录像的token - std::string m_streamRtspAddr; // 直播rtsp地址 - std::string m_replayRtspAddr; // 回放rtsp地址 - //> 录像机ip相关onvif属性 - - //< 云台ip相关的onvif属性 - std::string m_preServiceAddr; // 云台ip的onvif服务入口总地址 - std::string m_preMediaAddr; // 云台ip的media服务入口地址 - std::string m_prePtzAddr; // 云台ip的ptz服务入口地址 - std::string m_prePtzMediaProfile; // 云台ip的media的profileToken - //> 云台ip相关的onvif属性 - - - /** - * @brief m_isStreamEnabled,m_isPtzEnabled,m_isReplayEnabled - * 直播,云台,回放使能选项 - */ - bool m_isStreamEnabled= true; - bool m_isPtzEnabled=true; - bool m_isReplayEnabled=true; - bool m_isPresetEnabled=true; - -}; - -#endif // CCAMINFO_H +#ifndef CCAMINFO_H +#define CCAMINFO_H + +#include +#include +#include + +/** + @brief 摄像头信息类 + @author ganyuhang + @date 2020-04-16 更新 + */ +class CPresetInfo +{ +public: + CPresetInfo(const std::string &presetTag_, + const std::string &presetToken_, + const std::string &presetDesc_) + { + presetToken = presetToken_; + presetTag = presetTag_; + presetDesc = presetDesc_; + } + + std::string presetToken; + std::string presetTag; + std::string presetDesc; +}; + +class CCamInfo +{ +public: + + CCamInfo(); + + std::string pointTag() const; + void setPointTag(const std::string &pointTag); + + std::string camTag() const; + void setCamTag(const std::string &camTag); + + std::string presetTag() const; + void setPresetTag(const std::string &presetTag); + + //< 预置点相关 + std::vector presets() const; + void setPresets(const std::vector &presets); + void addPreset(const std::string &presetTag_, + const std::string &presetToken_, + const std::string &presetDesc_); + + bool getPresetToken(const std::string &preset_tag, std::string &outToken); + bool getPresetDesc(const std::string &preset_tag, std::string &outDesc); + //> 预置点相关 + + std::string ip() const; + void setIp(const std::string &ip); + std::string getPtzIp() const; + void setPtzIp(const std::string &ptzIp); + + + int getChanNo() const; + void setChanNo(int chan_no); + + std::string description() const; + void setDescription(const std::string &description); + + std::string username() const; + void setUsername(const std::string &username); + + std::string password() const; + void setPassword(const std::string &password); + + //< 录像机ip相关属性 + std::string serviceAddr() const; + + std::string mediaAddr() const; + void setMediaAddr(const std::string &mediaAddr); + + std::string ptzAddr() const; + void setPtzAddr(const std::string &ptzAddr); + + std::string recordSearchAddr() const; + void setRecordSearchAddr(const std::string &recordSearchAddr); + + std::string replayAddr() const; + void setReplayAddr(const std::string &replayAddr); + + std::string getStreamRtspAddr() const; + std::string getReplayRtspAddr() const; + //> 录像机ip相关属性 + + + //< 云台ip相关属性 + std::string getPreServiceAddr() const; + + std::string getPreMediaAddr() const; + void setPreMediaAddr(const std::string &preMediaAddr); + + std::string getPrePtzAddr() const; + void setPrePtzAddr(const std::string &prePtzAddr); + + std::string getPrePtzMediaProfile() const; + void setPrePtzMediaProfile(const std::string &prePtzMediaProfile); + + bool continuousMove(int cmd, double cmd_speed); + bool stopMove(); + bool gotoPreset(const std::string & preset_tag); + //> 云台ip相关属性 + + + + //< 使能相关属性 + bool isStreamEnabled() const; + void setIsStreamEnabled(bool isStreamEnabled); + + bool isPtzEnabled() const; + void setIsPtzEnabled(bool isPtzEnabled); + + bool isReplayEnabled() const; + void setIsReplayEnabled(bool isReplayEnabled); + + bool getIsPresetEnabled() const; + void setIsPresetEnabled(bool isPresetEnabled); + //> 使能相关属性 + + + + /** + * @brief getOnvifArgs 通过onvif获取相关的参数 + * + * 参数 m_streamRtspAddr和m_replayRtspAddr以及m_ptzAddr,和直播,回放和控制使能相关的信息。 + */ + void getOnvifArgs(); + + +private: + void setServiceAddr(const std::string &serviceAddr); + void setPreServiceAddr(const std::string &preServiceAddr); + + + void getNvrArgs(); + void getPresetArgs(); + + + std::string m_pointTag; //< 点标签 [mix/analog/accuml/digital].[对应表tag_name] + std::string m_camTag; //< 点关联摄像头标签 cctv_camera_info表主键tag_name + std::string m_presetTag; //< 点关联预置点标签 cctv_orientation表主键tag_name + std::vector m_presets; //< 摄像头关联所有预置点 + + /** + * @brief m_chan_no + * + * @date 2020-04-16 兼容性修改,地铁一号线录像机设备不支持获取预置点 + * 录像/直播的通道,解释,可以参考SVN/ISCS6000文档\04系统设计\专业应用\CCTV\ISCS综合监控系统_概要设计说明书_视频告警和CCTV.docx + * http链接:http://192.168.79.248:88/svn/%E8%BD%A8%E9%81%93%E4%BA%A4%E9%80%9A%E7%BB%BC%E5%90%88%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F/Development_Repository/ISCS6000%E6%96%87%E6%A1%A3/04%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1/%E4%B8%93%E4%B8%9A%E5%BA%94%E7%94%A8/CCTV/ISCS%E7%BB%BC%E5%90%88%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F_%E6%A6%82%E8%A6%81%E8%AE%BE%E8%AE%A1%E8%AF%B4%E6%98%8E%E4%B9%A6_%E8%A7%86%E9%A2%91%E5%91%8A%E8%AD%A6%E5%92%8CCCTV.docx + * 有两个ip:录像机ip和云台ip + * + * 录像机ip用于直播、回放和PTZ控制,这里的chan_no时录像机ip的通道 + * 云台ip用于控制转到预置点,云台ip的通道为1 + * 录像机ip和云台ip的用户名和密码相一致 + */ + int m_chanNo; + std::string m_ip; + std::string m_ptzIp; + + std::string m_description; // 摄像头描述 + std::string m_username; // 用户名 + std::string m_password; // 密码 + + //< 录像机ip相关onvif属性 + std::string m_serviceAddr; // onvif服务地址 onvif入口总地址,请参见onvif协议 + std::string m_mediaAddr; // onvif的media协议入口地址 + std::string m_ptzAddr; // onvif的ptz协议入口地址 + std::string m_recordSearchAddr; // onvif的录像搜索协议地址 + std::string m_replayAddr; // onvif的replay协议地址 + std::string m_mediaProfileToken;// onvif的media播放profile + std::string m_recordToken; // onvif录像的token + std::string m_streamRtspAddr; // 直播rtsp地址 + std::string m_replayRtspAddr; // 回放rtsp地址 + //> 录像机ip相关onvif属性 + + //< 云台ip相关的onvif属性 + std::string m_preServiceAddr; // 云台ip的onvif服务入口总地址 + std::string m_preMediaAddr; // 云台ip的media服务入口地址 + std::string m_prePtzAddr; // 云台ip的ptz服务入口地址 + std::string m_prePtzMediaProfile; // 云台ip的media的profileToken + //> 云台ip相关的onvif属性 + + + /** + * @brief m_isStreamEnabled,m_isPtzEnabled,m_isReplayEnabled + * 直播,云台,回放使能选项 + */ + bool m_isStreamEnabled= true; + bool m_isPtzEnabled=true; + bool m_isReplayEnabled=true; + bool m_isPresetEnabled=true; + +}; + +#endif // CCAMINFO_H diff --git a/product/src/gui/plugin/IpcViewerWidget/cipcviewermsgbusmng.cpp b/product/src/gui/plugin/IpcViewerWidget/cipcviewermsgbusmng.cpp index 3692750a..9591427e 100644 --- a/product/src/gui/plugin/IpcViewerWidget/cipcviewermsgbusmng.cpp +++ b/product/src/gui/plugin/IpcViewerWidget/cipcviewermsgbusmng.cpp @@ -1,42 +1,42 @@ -#include "cipcviewermsgbusmng.h" -#include "pub_logger_api/logger.h" -#include "common/MessageChannel.h" - - - -CIpcViewerMsgBusMng::CIpcViewerMsgBusMng() -{ - -} - -bool CIpcViewerMsgBusMng::sendMsgToDomain(int nMessageType, int nChannel, const std::string &strMessage) -{ - using namespace kbd_net; - - bool bRet = false; - CMbMessage objMsg; - - objMsg.setMsgType(nMessageType); //指定消息类型 - objMsg.setSubject(m_nAppid,nChannel); //下发通道 - objMsg.setData(strMessage); //设置需要发送数据 TO Protobuff - - bRet = m_objCommon.sendMsgToDomain(objMsg,m_nDomainid); //发送到主机 - if (bRet == false) - { - LOGERROR("VideoAlarmMsgBusMng::sendToHost(), Message[MsgType='%d', nAppID='%d' Channel='%d'] send fail .", - nMessageType,m_nAppid,nChannel); - return false; - } - return true; -} - -std::string CIpcViewerMsgBusMng::getCommunicatorName() -{ - return m_objCommon.getName(); -} - -void CIpcViewerMsgBusMng::setNodeInfo(int nDomainId, int nAppid) -{ - m_nDomainid = nDomainId; - m_nAppid = nAppid; -} +#include "cipcviewermsgbusmng.h" +#include "pub_logger_api/logger.h" +#include "common/MessageChannel.h" + + + +CIpcViewerMsgBusMng::CIpcViewerMsgBusMng() +{ + +} + +bool CIpcViewerMsgBusMng::sendMsgToDomain(int nMessageType, int nChannel, const std::string &strMessage) +{ + using namespace kbd_net; + + bool bRet = false; + CMbMessage objMsg; + + objMsg.setMsgType(nMessageType); //指定消息类型 + objMsg.setSubject(m_nAppid,nChannel); //下发通道 + objMsg.setData(strMessage); //设置需要发送数据 TO Protobuff + + bRet = m_objCommon.sendMsgToDomain(objMsg,m_nDomainid); //发送到主机 + if (bRet == false) + { + LOGERROR("VideoAlarmMsgBusMng::sendToHost(), Message[MsgType='%d', nAppID='%d' Channel='%d'] send fail .", + nMessageType,m_nAppid,nChannel); + return false; + } + return true; +} + +std::string CIpcViewerMsgBusMng::getCommunicatorName() +{ + return m_objCommon.getName(); +} + +void CIpcViewerMsgBusMng::setNodeInfo(int nDomainId, int nAppid) +{ + m_nDomainid = nDomainId; + m_nAppid = nAppid; +} diff --git a/product/src/gui/plugin/IpcViewerWidget/cipcviewermsgbusmng.h b/product/src/gui/plugin/IpcViewerWidget/cipcviewermsgbusmng.h index ee2b12f6..f560dd68 100644 --- a/product/src/gui/plugin/IpcViewerWidget/cipcviewermsgbusmng.h +++ b/product/src/gui/plugin/IpcViewerWidget/cipcviewermsgbusmng.h @@ -1,22 +1,22 @@ -#ifndef CIPCVIEWERMSGBUSMNG_H -#define CIPCVIEWERMSGBUSMNG_H -#include "net_msg_bus_api/CMbCommunicator.h" - - -class CIpcViewerMsgBusMng -{ -public: - CIpcViewerMsgBusMng(); - - bool sendMsgToDomain(int nMessageType,int nChannel,const std::string &strMessage); - std::string getCommunicatorName(); - - void setNodeInfo(int nDomainId,int nAppid); - -private: - kbd_net::CMbCommunicator m_objCommon; - int m_nDomainid; - int m_nAppid; -}; - -#endif // CIPCVIEWERMSGBUSMNG_H +#ifndef CIPCVIEWERMSGBUSMNG_H +#define CIPCVIEWERMSGBUSMNG_H +#include "net_msg_bus_api/CMbCommunicator.h" + + +class CIpcViewerMsgBusMng +{ +public: + CIpcViewerMsgBusMng(); + + bool sendMsgToDomain(int nMessageType,int nChannel,const std::string &strMessage); + std::string getCommunicatorName(); + + void setNodeInfo(int nDomainId,int nAppid); + +private: + kbd_net::CMbCommunicator m_objCommon; + int m_nDomainid; + int m_nAppid; +}; + +#endif // CIPCVIEWERMSGBUSMNG_H diff --git a/product/src/gui/plugin/IpcViewerWidget/crdbaccessutilty.cpp b/product/src/gui/plugin/IpcViewerWidget/crdbaccessutilty.cpp index 80d8cfe0..7310e3a1 100644 --- a/product/src/gui/plugin/IpcViewerWidget/crdbaccessutilty.cpp +++ b/product/src/gui/plugin/IpcViewerWidget/crdbaccessutilty.cpp @@ -1,189 +1,189 @@ -#include "crdbaccessutilty.h" -#include "pub_logger_api/logger.h" -#include -#include "Common.h" - -CRdbAccessUtilty::CRdbAccessUtilty(int nDomainId,int nAppId) -{ - m_pNetRdbApi = new kbd_dbms::CRdbNetApi(); - - m_pNetRdbApi->connect(nDomainId,nAppId); - -} - -CRdbAccessUtilty::~CRdbAccessUtilty() -{ - if(NULL != m_pNetRdbApi) - { - delete m_pNetRdbApi; - m_pNetRdbApi =NULL; - } -} - -bool CRdbAccessUtilty::getCamInfo(std::string pointtag, CCamInfo & outCamInfo) -{ - std::string pointtype,pointTagWithoutType; - if(splitTagName(pointtag,pointtype,pointTagWithoutType) == kbdFailed) - { - LOGERROR("分割标签名错误,标签名为[%s]",pointtag.c_str()); - return false; - } - - //< 查询点表,填充camera_id和preset_id - if(queryPointTable(pointTagWithoutType,pointtype,outCamInfo) == false) - { - LOGERROR("查询点表错误,标签名为[%s],表名[%s]",pointtag.c_str(),pointtype.c_str()); - return false; - } - - //< 查询点表, - if(queryCameraInfoTable(outCamInfo) == false) - { - LOGERROR("查询cctv_camera_info表错误,标签名为[%s]",outCamInfo.camTag().c_str()); - return false; - } - - //< 查询点表, - if(queryPresetTable(outCamInfo) == false) - { - LOGERROR("查询cctv_orientation表错误,标签名为[%s]",outCamInfo.camTag().c_str()); - return false; - } - - return true; -} - -int CRdbAccessUtilty::splitTagName(const std::string &inTag, std::string &outType, std::string &outTagName) -{ - std::size_t firstDotindex = inTag.find_first_of('.'); - if(firstDotindex == std::string::npos) - { - return kbdFailed; - } - - // 赋值表名; - if(inTag.substr(0,firstDotindex) == std::string("analog")) - { - outType = "analog"; - } - else if(inTag.substr(0,firstDotindex) == std::string("accuml")){ - outType = "accuml"; - } - else if(inTag.substr(0,firstDotindex) == std::string("digital")){ - outType = "digital"; - } - else if(inTag.substr(0,firstDotindex) == std::string("mix")){ - outType = "mix"; - }else{ - return kbdFailed; - } - - outTagName = inTag.substr(firstDotindex+1,inTag.size()); - return kbdSuccess; -} - -bool CRdbAccessUtilty::queryPointTable(const std::string &pointtag, const std::string &pointType, CCamInfo &outCamInfo) -{ - kbd_idlfile::RdbRet objRet; - std::vector vecKey,vecColumn; - vecKey.push_back(pointtag); - - vecColumn.push_back("camera_tag"); - vecColumn.push_back("preset_id"); - if(m_pNetRdbApi->queryByKey(pointType,vecKey,vecColumn,objRet) == false) - { - LOGERROR("queryPointTable 未查询到条目"); - return false; - } - - if(objRet.msgrecord_size() != 1 || objRet.msgrecord(0).msgvaluearray_size() != 2 ) - { - LOGERROR("queryPointTable 查询结果不对"); - return false; - } - - outCamInfo.setCamTag(objRet.msgrecord(0).msgvaluearray(0).strvalue()); - outCamInfo.setPresetTag(objRet.msgrecord(0).msgvaluearray(1).strvalue()); - return true; -} - -bool CRdbAccessUtilty::queryCameraInfoTable(CCamInfo &outCamInfo) -{ - kbd_idlfile::RdbRet objRet; - std::vector vecKey,vecColumn; - vecKey.push_back(outCamInfo.camTag()); - - vecColumn.push_back("camera_ip"); - vecColumn.push_back("camera_ptz_ip"); - vecColumn.push_back("description"); - vecColumn.push_back("chan_no"); - vecColumn.push_back("username"); - vecColumn.push_back("password"); - if(m_pNetRdbApi->queryByKey("cctv_camera_info",vecKey,vecColumn,objRet) == false) - { - LOGERROR("queryCameraInfoTable 未查询到条目"); - return false; - } - - if(objRet.msgrecord_size() != 1 || objRet.msgrecord(0).msgvaluearray_size() != 6 ) - { - LOGERROR("queryCameraInfoTable 查询结果不对"); - return false; - } - - outCamInfo.setIp(objRet.msgrecord(0).msgvaluearray(0).strvalue()); - outCamInfo.setPtzIp(objRet.msgrecord(0).msgvaluearray(1).strvalue()); - outCamInfo.setDescription(objRet.msgrecord(0).msgvaluearray(2).strvalue()); - outCamInfo.setChanNo(objRet.msgrecord(0).msgvaluearray(3).nvalue()); - outCamInfo.setUsername(objRet.msgrecord(0).msgvaluearray(4).strvalue()); - outCamInfo.setPassword(objRet.msgrecord(0).msgvaluearray(5).strvalue()); - - return true; -} - -bool CRdbAccessUtilty::queryPresetTable(CCamInfo &outCamInfo) -{ - using namespace kbd_dbms; - using namespace kbd_idlfile; - - kbd_idlfile::RdbQuery msgQuery; - msgQuery.set_strtablename("cctv_orientation"); - - msgQuery.add_strselectcolnamearr("tag_name"); - msgQuery.add_strselectcolnamearr("description"); - msgQuery.add_strselectcolnamearr("preset_token"); - - kbd_idlfile::RdbCondition *pCondtion = msgQuery.add_msgcondition(); - pCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pCondtion->set_strcolumnname("camera_tag_name"); - SVariable *pCondValue = pCondtion->mutable_msgvalue(); - pCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pCondValue->set_strvalue(outCamInfo.camTag().c_str()); - - kbd_idlfile::RdbRet retMsg; - - bool bRet; - bRet = m_pNetRdbApi->query(msgQuery, retMsg); - if (false == bRet) - { - LOGERROR("queryPresetTable 未查询到条目"); - return false; - } - else - { - for (int i = 0; i < retMsg.msgrecord_size(); ++i) - { - if(retMsg.msgrecord(i).msgvaluearray_size() != 3) - { - LOGERROR("queryPresetTable 查询结果不对"); - } - - outCamInfo.addPreset(retMsg.msgrecord(i).msgvaluearray(0).strvalue(), - retMsg.msgrecord(i).msgvaluearray(2).strvalue(), - retMsg.msgrecord(i).msgvaluearray(1).strvalue()); - } - } - return true; -} - +#include "crdbaccessutilty.h" +#include "pub_logger_api/logger.h" +#include +#include "Common.h" + +CRdbAccessUtilty::CRdbAccessUtilty(int nDomainId,int nAppId) +{ + m_pNetRdbApi = new kbd_dbms::CRdbNetApi(); + + m_pNetRdbApi->connect(nDomainId,nAppId); + +} + +CRdbAccessUtilty::~CRdbAccessUtilty() +{ + if(NULL != m_pNetRdbApi) + { + delete m_pNetRdbApi; + m_pNetRdbApi =NULL; + } +} + +bool CRdbAccessUtilty::getCamInfo(std::string pointtag, CCamInfo & outCamInfo) +{ + std::string pointtype,pointTagWithoutType; + if(splitTagName(pointtag,pointtype,pointTagWithoutType) == kbdFailed) + { + LOGERROR("分割标签名错误,标签名为[%s]",pointtag.c_str()); + return false; + } + + //< 查询点表,填充camera_id和preset_id + if(queryPointTable(pointTagWithoutType,pointtype,outCamInfo) == false) + { + LOGERROR("查询点表错误,标签名为[%s],表名[%s]",pointtag.c_str(),pointtype.c_str()); + return false; + } + + //< 查询点表, + if(queryCameraInfoTable(outCamInfo) == false) + { + LOGERROR("查询cctv_camera_info表错误,标签名为[%s]",outCamInfo.camTag().c_str()); + return false; + } + + //< 查询点表, + if(queryPresetTable(outCamInfo) == false) + { + LOGERROR("查询cctv_orientation表错误,标签名为[%s]",outCamInfo.camTag().c_str()); + return false; + } + + return true; +} + +int CRdbAccessUtilty::splitTagName(const std::string &inTag, std::string &outType, std::string &outTagName) +{ + std::size_t firstDotindex = inTag.find_first_of('.'); + if(firstDotindex == std::string::npos) + { + return kbdFailed; + } + + // 赋值表名; + if(inTag.substr(0,firstDotindex) == std::string("analog")) + { + outType = "analog"; + } + else if(inTag.substr(0,firstDotindex) == std::string("accuml")){ + outType = "accuml"; + } + else if(inTag.substr(0,firstDotindex) == std::string("digital")){ + outType = "digital"; + } + else if(inTag.substr(0,firstDotindex) == std::string("mix")){ + outType = "mix"; + }else{ + return kbdFailed; + } + + outTagName = inTag.substr(firstDotindex+1,inTag.size()); + return kbdSuccess; +} + +bool CRdbAccessUtilty::queryPointTable(const std::string &pointtag, const std::string &pointType, CCamInfo &outCamInfo) +{ + kbd_idlfile::RdbRet objRet; + std::vector vecKey,vecColumn; + vecKey.push_back(pointtag); + + vecColumn.push_back("camera_tag"); + vecColumn.push_back("preset_id"); + if(m_pNetRdbApi->queryByKey(pointType,vecKey,vecColumn,objRet) == false) + { + LOGERROR("queryPointTable 未查询到条目"); + return false; + } + + if(objRet.msgrecord_size() != 1 || objRet.msgrecord(0).msgvaluearray_size() != 2 ) + { + LOGERROR("queryPointTable 查询结果不对"); + return false; + } + + outCamInfo.setCamTag(objRet.msgrecord(0).msgvaluearray(0).strvalue()); + outCamInfo.setPresetTag(objRet.msgrecord(0).msgvaluearray(1).strvalue()); + return true; +} + +bool CRdbAccessUtilty::queryCameraInfoTable(CCamInfo &outCamInfo) +{ + kbd_idlfile::RdbRet objRet; + std::vector vecKey,vecColumn; + vecKey.push_back(outCamInfo.camTag()); + + vecColumn.push_back("camera_ip"); + vecColumn.push_back("camera_ptz_ip"); + vecColumn.push_back("description"); + vecColumn.push_back("chan_no"); + vecColumn.push_back("username"); + vecColumn.push_back("password"); + if(m_pNetRdbApi->queryByKey("cctv_camera_info",vecKey,vecColumn,objRet) == false) + { + LOGERROR("queryCameraInfoTable 未查询到条目"); + return false; + } + + if(objRet.msgrecord_size() != 1 || objRet.msgrecord(0).msgvaluearray_size() != 6 ) + { + LOGERROR("queryCameraInfoTable 查询结果不对"); + return false; + } + + outCamInfo.setIp(objRet.msgrecord(0).msgvaluearray(0).strvalue()); + outCamInfo.setPtzIp(objRet.msgrecord(0).msgvaluearray(1).strvalue()); + outCamInfo.setDescription(objRet.msgrecord(0).msgvaluearray(2).strvalue()); + outCamInfo.setChanNo(objRet.msgrecord(0).msgvaluearray(3).nvalue()); + outCamInfo.setUsername(objRet.msgrecord(0).msgvaluearray(4).strvalue()); + outCamInfo.setPassword(objRet.msgrecord(0).msgvaluearray(5).strvalue()); + + return true; +} + +bool CRdbAccessUtilty::queryPresetTable(CCamInfo &outCamInfo) +{ + using namespace kbd_dbms; + using namespace kbd_idlfile; + + kbd_idlfile::RdbQuery msgQuery; + msgQuery.set_strtablename("cctv_orientation"); + + msgQuery.add_strselectcolnamearr("tag_name"); + msgQuery.add_strselectcolnamearr("description"); + msgQuery.add_strselectcolnamearr("preset_token"); + + kbd_idlfile::RdbCondition *pCondtion = msgQuery.add_msgcondition(); + pCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pCondtion->set_strcolumnname("camera_tag_name"); + SVariable *pCondValue = pCondtion->mutable_msgvalue(); + pCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pCondValue->set_strvalue(outCamInfo.camTag().c_str()); + + kbd_idlfile::RdbRet retMsg; + + bool bRet; + bRet = m_pNetRdbApi->query(msgQuery, retMsg); + if (false == bRet) + { + LOGERROR("queryPresetTable 未查询到条目"); + return false; + } + else + { + for (int i = 0; i < retMsg.msgrecord_size(); ++i) + { + if(retMsg.msgrecord(i).msgvaluearray_size() != 3) + { + LOGERROR("queryPresetTable 查询结果不对"); + } + + outCamInfo.addPreset(retMsg.msgrecord(i).msgvaluearray(0).strvalue(), + retMsg.msgrecord(i).msgvaluearray(2).strvalue(), + retMsg.msgrecord(i).msgvaluearray(1).strvalue()); + } + } + return true; +} + diff --git a/product/src/gui/plugin/IpcViewerWidget/crdbaccessutilty.h b/product/src/gui/plugin/IpcViewerWidget/crdbaccessutilty.h index b091c9a8..f15d95d6 100644 --- a/product/src/gui/plugin/IpcViewerWidget/crdbaccessutilty.h +++ b/product/src/gui/plugin/IpcViewerWidget/crdbaccessutilty.h @@ -1,38 +1,38 @@ -/** - @author ganyuhang - @date 2020-02-25 - @brief 访问内存库工具类 - **/ -#ifndef CRDBACCESSUTILTY_H -#define CRDBACCESSUTILTY_H - -#include -#include -#include "rdb_net_api/CRdbNetApi.h" -#include - -class CRdbAccessUtilty -{ -public: - CRdbAccessUtilty(int nDomainId, int nAppId); - virtual ~CRdbAccessUtilty(); - - /** - * @brief getCamInfo 点标签 mix/acc/digital/analog - * @param pointtag - * @param outCamInfo - * @return - */ - bool getCamInfo(std::string pointtag, CCamInfo &outCamInfo); -private: - static int splitTagName(const std::string &inTag, std::string &outType, std::string &outTagName); - - bool queryPointTable(const std::string &pointtag,const std::string &pointType,CCamInfo &outCamInfo); - bool queryCameraInfoTable(CCamInfo &outCamInfo); - bool queryPresetTable(CCamInfo &outCamInfo); - - - kbd_dbms::CRdbNetApi *m_pNetRdbApi; //网络实时数据库接口指针 -}; - -#endif // CRDBACCESSUTILTY_H +/** + @author ganyuhang + @date 2020-02-25 + @brief 访问内存库工具类 + **/ +#ifndef CRDBACCESSUTILTY_H +#define CRDBACCESSUTILTY_H + +#include +#include +#include "rdb_net_api/CRdbNetApi.h" +#include + +class CRdbAccessUtilty +{ +public: + CRdbAccessUtilty(int nDomainId, int nAppId); + virtual ~CRdbAccessUtilty(); + + /** + * @brief getCamInfo 点标签 mix/acc/digital/analog + * @param pointtag + * @param outCamInfo + * @return + */ + bool getCamInfo(std::string pointtag, CCamInfo &outCamInfo); +private: + static int splitTagName(const std::string &inTag, std::string &outType, std::string &outTagName); + + bool queryPointTable(const std::string &pointtag,const std::string &pointType,CCamInfo &outCamInfo); + bool queryCameraInfoTable(CCamInfo &outCamInfo); + bool queryPresetTable(CCamInfo &outCamInfo); + + + kbd_dbms::CRdbNetApi *m_pNetRdbApi; //网络实时数据库接口指针 +}; + +#endif // CRDBACCESSUTILTY_H diff --git a/product/src/gui/plugin/IpcViewerWidget/en.ts b/product/src/gui/plugin/IpcViewerWidget/en.ts index 5386d267..5a48b95b 100644 --- a/product/src/gui/plugin/IpcViewerWidget/en.ts +++ b/product/src/gui/plugin/IpcViewerWidget/en.ts @@ -1,17 +1,17 @@ - - - - - IpcViwerWidget - - - IpcViwerWidget - - - - - 实时视频 - Streaming - - - + + + + + IpcViwerWidget + + + IpcViwerWidget + + + + + 实时视频 + Streaming + + + diff --git a/product/src/gui/plugin/IpcViewerWidget/img/camera-hovered.svg b/product/src/gui/plugin/IpcViewerWidget/img/camera-hovered.svg index c2e455da..4f6ffcb8 100644 --- a/product/src/gui/plugin/IpcViewerWidget/img/camera-hovered.svg +++ b/product/src/gui/plugin/IpcViewerWidget/img/camera-hovered.svg @@ -1,6 +1,6 @@ - - - - - + + + + + \ No newline at end of file diff --git a/product/src/gui/plugin/IpcViewerWidget/img/camera.svg b/product/src/gui/plugin/IpcViewerWidget/img/camera.svg index 0411c9b6..ec5e62a7 100644 --- a/product/src/gui/plugin/IpcViewerWidget/img/camera.svg +++ b/product/src/gui/plugin/IpcViewerWidget/img/camera.svg @@ -1,6 +1,6 @@ - - - - - + + + + + \ No newline at end of file diff --git a/product/src/gui/plugin/IpcViewerWidget/img/play-hovered.svg b/product/src/gui/plugin/IpcViewerWidget/img/play-hovered.svg index eefbef27..5f11f65a 100644 --- a/product/src/gui/plugin/IpcViewerWidget/img/play-hovered.svg +++ b/product/src/gui/plugin/IpcViewerWidget/img/play-hovered.svg @@ -1,7 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/product/src/gui/plugin/IpcViewerWidget/img/vol-hovered.svg b/product/src/gui/plugin/IpcViewerWidget/img/vol-hovered.svg index d650d341..896640bb 100644 --- a/product/src/gui/plugin/IpcViewerWidget/img/vol-hovered.svg +++ b/product/src/gui/plugin/IpcViewerWidget/img/vol-hovered.svg @@ -1,6 +1,6 @@ - - - - - + + + + + \ No newline at end of file diff --git a/product/src/gui/plugin/IpcViewerWidget/img/vol.svg b/product/src/gui/plugin/IpcViewerWidget/img/vol.svg index 773972d4..92939f39 100644 --- a/product/src/gui/plugin/IpcViewerWidget/img/vol.svg +++ b/product/src/gui/plugin/IpcViewerWidget/img/vol.svg @@ -1,6 +1,6 @@ - - - - - + + + + + \ No newline at end of file diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcViewerWidget_global.h b/product/src/gui/plugin/IpcViewerWidget/ipcViewerWidget_global.h index d4588fba..278e8a7b 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcViewerWidget_global.h +++ b/product/src/gui/plugin/IpcViewerWidget/ipcViewerWidget_global.h @@ -1,13 +1,13 @@ -#ifndef IPCVIEWERWIDGET_GLOBAL_H -#define IPCVIEWERWIDGET_GLOBAL_H - - -#include - -#if defined(IPCVIEWERWIDGET_LIBRARY) -# define IPCVIEWERWIDGET_API Q_DECL_EXPORT -#else -# define IPCVIEWERWIDGET_API Q_DECL_IMPORT -#endif - -#endif // IPCVIEWERWIDGET_GLOBAL_H +#ifndef IPCVIEWERWIDGET_GLOBAL_H +#define IPCVIEWERWIDGET_GLOBAL_H + + +#include + +#if defined(IPCVIEWERWIDGET_LIBRARY) +# define IPCVIEWERWIDGET_API Q_DECL_EXPORT +#else +# define IPCVIEWERWIDGET_API Q_DECL_IMPORT +#endif + +#endif // IPCVIEWERWIDGET_GLOBAL_H diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.cpp b/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.cpp index 4acebfd0..0e75b20f 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.cpp +++ b/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.cpp @@ -1,26 +1,26 @@ -#include "ipcviewerpluginwidget.h" -#include "ipcviewerwidget.h" - -IpcViewerPluginWidget::IpcViewerPluginWidget(QObject *parent): QObject(parent) -{ - -} - -IpcViewerPluginWidget::~IpcViewerPluginWidget() -{ - -} - -bool IpcViewerPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - IpcViewerWidget *pWidget = new IpcViewerWidget(parent,editMode); - Q_UNUSED(ptrVec); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void IpcViewerPluginWidget::release() -{ - -} +#include "ipcviewerpluginwidget.h" +#include "ipcviewerwidget.h" + +IpcViewerPluginWidget::IpcViewerPluginWidget(QObject *parent): QObject(parent) +{ + +} + +IpcViewerPluginWidget::~IpcViewerPluginWidget() +{ + +} + +bool IpcViewerPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + IpcViewerWidget *pWidget = new IpcViewerWidget(parent,editMode); + Q_UNUSED(ptrVec); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void IpcViewerPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.h b/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.h index acc23c1e..3b783a45 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.h +++ b/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.h @@ -1,22 +1,22 @@ -#ifndef IPCVIEWERPLUGINWIDGET_H -#define IPCVIEWERPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - - -class IpcViewerPluginWidget: public QObject,public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - IpcViewerPluginWidget(QObject *parent=0); - ~IpcViewerPluginWidget(); - - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // IPCVIEWERPLUGINWIDGET_H +#ifndef IPCVIEWERPLUGINWIDGET_H +#define IPCVIEWERPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + + +class IpcViewerPluginWidget: public QObject,public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + IpcViewerPluginWidget(QObject *parent=0); + ~IpcViewerPluginWidget(); + + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // IPCVIEWERPLUGINWIDGET_H diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.cpp b/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.cpp index dad05fca..c7920f92 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.cpp +++ b/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.cpp @@ -1,1075 +1,1075 @@ -#include "ipcviewerwidget.h" -#include "ui_ipcviewerwidget.h" -#include -#include -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "operate_server_api/JsonOptCommand.h" -#include -#include -#include -#include -#include -#include -#include -#include "pub_utility_api/FileStyle.h" - - -#define APP_NAME "hmi" -#define NODE_NAME "test_node" -#define VIDEO_SERVER_RTU_NAME "##$$video_server$$##" - -#define PTZ_UP 0 -#define PTZ_DOWN 1 -#define PTZ_LEFT 2 -#define PTZ_RIGHT 3 -#define PTZ_ZOOMIN 4 -#define PTZ_ZOOMOUT 5 - -#define CCTV_ONVIF_MOVE "58" -#define CCTV_ONVIF_STOPMOVE "59" -#define CCTV_ONVIF_GOTOPRESET "57" - -#define KEY_CMD_TYPE "cmd_type" -#define CAMERA_TAG "camera_tag" -#define PTZ_COMMOND "commond" -#define PTZ_SPEED "speed" -#define PRESET_TAG "preset_tag" - -#define PTZ_UI_TEST true - - - - -IpcViewerWidget::IpcViewerWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::IpcViewerWidget), - m_caminfo(NULL), - m_isStreamFirst(true), - m_isEditMode(editMode), - m_strNodeName(NODE_NAME), - m_strAppName(APP_NAME), - m_msgBusMng(new CIpcViewerMsgBusMng) -{ - Q_UNUSED(editMode) - ui->setupUi(this); - - QApplication::setAttribute(Qt::AA_UseOpenGLES); - QtAV::Widgets::registerRenderers(); - QtAV::setLogLevel(QtAV::LogOff); - initUi(); - - if(m_isStreamFirst) - { - ui->tabWidget->setCurrentIndex(0); - } - else - { - ui->tabWidget->setCurrentIndex(1); - } - - if(!m_isEditMode){ - if(m_playerCfgParser.isValid()) - { - m_playerCfgParser.applyToPlayer(*m_s_player); - m_playerCfgParser.applyToPlayer(*m_r_player); - } - else - { - showMsg(tr("播放器配置错误")); - } - } - - - - QtAV::Widgets::registerRenderers(); - -} - - -IpcViewerWidget::~IpcViewerWidget() -{ - delete ui; - delete m_s_player; - delete m_s_vo; - - delete m_r_player; - delete m_r_vo; - - delete m_msgBusMng; - - if(m_caminfo != NULL) - { - delete m_caminfo; - } - -} - -void IpcViewerWidget::setStreamInfo(QString pointTag) -{ - if(m_isEditMode) - return; - m_pointTag = pointTag; - loadCamInfo(); -} - -void IpcViewerWidget::setReplayInfo(QString pointTag, quint64 startTimestamp, quint64 endTimestamp) -{ - if(m_isEditMode) - return; - m_isStreamFirst = false; - ui->tabWidget->setCurrentIndex(1); - m_pointTag = pointTag; - m_replayStartTime = startTimestamp; - m_replayEndTime = endTimestamp; - - QDateTime datetime = QDateTime::fromMSecsSinceEpoch(startTimestamp); - ui->dateEdit->setDate(datetime.date()); - ui->timeEdit_starttime->setTime(datetime.time()); - ui->timeEdit_starttime->setTime(QDateTime::fromMSecsSinceEpoch(endTimestamp).time()); - loadCamInfo(); -} - -void IpcViewerWidget::setNodeInfo(int nDomainId, int nAppid) -{ - m_nDomainId = nDomainId; - m_nAppId = nAppid; - m_msgBusMng->setNodeInfo(nDomainId,nAppid); -} - -void IpcViewerWidget::setNodeName(const QString &nodeName) -{ - m_strNodeName = nodeName.toStdString(); -} - -void IpcViewerWidget::setAppName(const QString &appName) -{ - m_strAppName = appName.toStdString(); -} - - -void IpcViewerWidget::on_tabWidget_currentChanged(int index) -{ - switch (index) { - case 0: - this->setWindowTitle(tr("实时视频")); - - m_s_player->audio()->setMute(false); - m_r_player->audio()->setMute(true); - - //< 从录像切换到直播 - if(!m_isStreamFirst) - { - startStream(); - } - - break; - case 1: - this->setWindowTitle(tr("录像回放")); - - m_s_player->audio()->setMute(true); - m_r_player->audio()->setMute(false); - - - break; - default: - break; - } -} - - -void IpcViewerWidget::on_btn_play_clicked() -{ - playPauseStream(); -} - -void IpcViewerWidget::on_btn_vol_clicked() -{ - if(isMute == true) - { - //< 停止静音 - m_s_player->audio()->setMute(false); - m_s_player->audio()->setVolume(qreal(ui->volSlider->value() / 100.0)); - - ui->btn_vol->setChecked(false); - ui->volSlider->setDisabled(false); - isMute = false; - } - else - { - //< 开始静音 - m_s_player->audio()->setMute(true); - ui->btn_vol->setChecked(true); - ui->volSlider->setDisabled(true); - isMute = true; - } -} - -void IpcViewerWidget::initUi() -{ - - - this->setWindowTitle(tr("实时视频")); - this->setWindowFlags(windowFlags() & Qt::FramelessWindowHint & ~Qt::WindowContextHelpButtonHint); - initStylesheet(); - initStreamUi(); - initStreamConnect(); - initReplayUi(); - initReplayConnect(); - setCapturePath(); -} - -void IpcViewerWidget::initStylesheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("ipcViewer.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void IpcViewerWidget::initStreamUi() -{ - ui->btn_fullScreen->setHidden(true);// 暂时隐藏全屏按钮 - - m_s_player = new QtAV::AVPlayer(this); - m_s_vo = new QtAV::VideoOutput(this); - if (!m_s_vo->widget()) { - showMsg(tr("QtAV error:Can not create video renderer")); - return; - } - m_s_player->setRenderer(m_s_vo); - QHBoxLayout *hlayout = new QHBoxLayout; - QVBoxLayout *vlayout = new QVBoxLayout; - - ui->frame_2->setSizePolicy(ui->frame_2->sizePolicy().horizontalPolicy(),QSizePolicy::Fixed); - ui->frame_2->setMinimumHeight(25); - -// ui->frame->setSizePolicy(QSizePolicy::Fixed,ui->frame->sizePolicy().verticalPolicy()); -// ui->frame->setMinimumWidth(170); -// ui->frame->setMaximumWidth(170); - - m_s_vo->widget()->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); - m_s_vo->widget()->setMinimumHeight(279); - m_s_vo->widget()->setMinimumWidth(496); - vlayout->addWidget(m_s_vo->widget()); - vlayout->addWidget(ui->frame_2); - hlayout->addLayout(vlayout); - hlayout->addWidget(ui->frame); - ui->tab->setLayout(hlayout); - - - - ui->frame->setFrameStyle(QFrame::Box | QFrame::Plain); - ui->frame_2->setFrameStyle(QFrame::Box | QFrame::Plain); - - - int BtnSize = 25; - QPixmap pixmapR(":img/right.png"); - pixmapR = pixmapR.scaled( BtnSize, BtnSize, Qt::KeepAspectRatio ); - ui->right->setFixedSize(pixmapR.size()); - ui->right->setMask(pixmapR.mask()); - - QPixmap pixmapL(":img/left.png"); - pixmapL = pixmapL.scaled( BtnSize, BtnSize, Qt::KeepAspectRatio ); - ui->left->setFixedSize(pixmapL.size()); - ui->left->setMask(pixmapL.mask()); - - - QPixmap pixmapU(":img/up.png"); - pixmapU = pixmapU.scaled( BtnSize, BtnSize, Qt::KeepAspectRatio ); - ui->up->setFixedSize(pixmapU.size()); - ui->up->setMask(pixmapU.mask()); - - QPixmap pixmapD(":img/down.png"); - pixmapD = pixmapD.scaled( BtnSize, BtnSize, Qt::KeepAspectRatio ); - ui->down->setFixedSize(pixmapD.size()); - ui->down->setMask(pixmapD.mask()); - - QPixmap pixmapPlay(":img/play.png"); - pixmapPlay = pixmapPlay.scaled( 16, 16, Qt::KeepAspectRatio ); - ui->btn_play->setFixedSize(pixmapPlay.size()); - ui->btn_play->setCheckable(true); - - QPixmap pixmapCam(":img/camera.svg"); - pixmapCam = pixmapCam.scaled( 16, 16, Qt::KeepAspectRatio ); - ui->btn_cam->setFixedSize(pixmapCam.size()); - ui->btn_cam->setCheckable(true); - - QPixmap pixmapVol(":img/vol.svg"); - pixmapVol = pixmapVol.scaled( 16, 16, Qt::KeepAspectRatio ); - ui->btn_vol->setFixedSize(pixmapVol.size()); - ui->btn_vol->setCheckable(true); - - QPixmap pixmapFullScreen(":img/fullscreen.png"); - pixmapFullScreen = pixmapFullScreen.scaled( 16, 16, Qt::KeepAspectRatio ); - ui->btn_fullScreen->setFixedSize(pixmapFullScreen.size()); -} - -void IpcViewerWidget::initStreamConnect() -{ - connect(m_s_player,&QtAV::AVPlayer::error,this,&IpcViewerWidget::streamPlayErrCheck); - connect(this,&IpcViewerWidget::startStreamCapture,m_s_player->videoCapture(),&QtAV::VideoCapture::capture); - connect(ui->btn_fullScreen,&QPushButton::clicked,this,&IpcViewerWidget::showStreamFullScreen); - connect(&m_streamPlayCheck,&QTimer::timeout,this,&IpcViewerWidget::checkStreamStatus); -} - -void IpcViewerWidget::initReplayUi() -{ - // hidden 元素 -// ui->replayslider->setHidden(true); -// ui->label_time_r->setHidden(true); - - ui->dateEdit->setDate(QDate::currentDate().addDays(-1)); - ui->timeEdit_starttime->setTime(QTime(8,0,0)); - ui->timeEdit_endtime->setTime(QTime(10,0,0)); - - m_r_player = new QtAV::AVPlayer(this); - m_r_vo = new QtAV::VideoOutput(this); - if (!m_s_vo->widget()) { - showMsg(tr("QtAV error:Can not create video renderer")); - return; - } - m_r_player->setRenderer(m_r_vo); - QHBoxLayout *hlayout = new QHBoxLayout; - QVBoxLayout *vlayout = new QVBoxLayout; - - ui->frame_record_play->setSizePolicy(ui->frame_record_play->sizePolicy().horizontalPolicy(),QSizePolicy::Fixed); - ui->frame_record_play->setMinimumHeight(25); - -// ui->frame_record_search->setSizePolicy(QSizePolicy::Fixed,ui->frame_record_search->sizePolicy().verticalPolicy()); -// ui->frame_record_search->setMinimumWidth(170); -// ui->frame_record_search->setMaximumWidth(170); - - m_r_vo->widget()->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); - m_r_vo->widget()->setMinimumHeight(279); - m_r_vo->widget()->setMinimumWidth(496); - vlayout->addWidget(m_r_vo->widget()); - vlayout->addWidget(ui->frame_record_play); - hlayout->addLayout(vlayout); - hlayout->addWidget(ui->frame_record_search); - ui->tab_2->setLayout(hlayout); - - - ui->frame_record_search->setFrameStyle(QFrame::Box | QFrame::Plain); - ui->frame_record_play->setFrameStyle(QFrame::Box | QFrame::Plain); - - - QPixmap pixmapPlay(":img/play.png"); - pixmapPlay = pixmapPlay.scaled( 16, 16, Qt::KeepAspectRatio ); - ui->btn_play_r->setFixedSize(pixmapPlay.size()); - ui->btn_play_r->setCheckable(true); - - QPixmap pixmapCam(":img/camera.svg"); - pixmapCam = pixmapCam.scaled( 16, 16, Qt::KeepAspectRatio ); - ui->btn_cam_r->setFixedSize(pixmapCam.size()); - ui->btn_cam_r->setCheckable(true); - - QPixmap pixmapVol(":img/vol.svg"); - pixmapVol = pixmapVol.scaled( 16, 16, Qt::KeepAspectRatio ); - ui->btn_vol_r->setFixedSize(pixmapVol.size()); - ui->btn_vol_r->setCheckable(true); - - - -} - -void IpcViewerWidget::initReplayConnect() -{ - connect(m_r_player,&QtAV::AVPlayer::error,this,&IpcViewerWidget::replayPlayErrCheck); - connect(this,&IpcViewerWidget::startReplayCapture,m_r_player->videoCapture(),&QtAV::VideoCapture::capture); -// connect(m_r_player,&QtAV::AVPlayer::started,this,&IpcViewerWidget::startUpdateCurrrentReplayTime); - connect(m_r_player,&QtAV::AVPlayer::stopped,this,&IpcViewerWidget::stopHandler); - connect(ui->comboBox_presets,&QComboBox::currentTextChanged,this,&IpcViewerWidget::slot_presets_itemChanged); -} - -void IpcViewerWidget::loadCamInfo() -{ - if(m_caminfo == NULL) - { - m_caminfo = new CCamInfo; - } - else - { - return; - } - - CRdbAccessUtilty rdbutilty(m_nDomainId,m_nAppId); - if(rdbutilty.getCamInfo(m_pointTag.toStdString(),*m_caminfo) == false) - { - showMsg(tr("请检查摄像头设备建模是否正确")); - return; - } - m_caminfo->getOnvifArgs(); - - setStreamEnabled(m_caminfo->isStreamEnabled()); - setReplayEnabled(m_caminfo->isReplayEnabled()); - setPtzEnabled(m_caminfo->isPtzEnabled()); - - //< 预置点加载 - std::vector presets = m_caminfo->presets(); - for(int i = 0; i < (int)presets.size();i++) - { - ui->comboBox_presets->addItem(QString::fromStdString( presets[i].presetDesc),presets[i].presetTag.c_str()); - ui->comboBox_presets->setItemData(i,QString::fromStdString(presets[i].presetTag) + ":" + presets[i].presetDesc.c_str(), Qt::ToolTipRole); - } - - //< 根据设置开始直播 - if(m_isStreamFirst) - { - startStream(); - //< 转到预置点 - if(m_caminfo->isPtzEnabled() && m_caminfo->presetTag() != "") - { - if( !ptzGotopreset( m_caminfo->presetTag() ) ) - LOGERROR("转到预置点失败"); - } - } - else - { - startReplay(); - } - -} - -void IpcViewerWidget::startStream() -{ - - if(m_s_player->isPlaying()) - { - return; - } -m_streamPlayCheck.setInterval(3000); - m_s_player->setBufferMode(QtAV::BufferPackets); - m_s_player->setBufferValue(1); - - m_s_player->setFile(m_caminfo->getStreamRtspAddr().c_str()); - m_s_player->play(); - m_streamPlayCheck.setInterval(3000); - m_streamPlayCheck.start(); - playPauseStreamUi(); - - -// qDebug() << m_caminfo->getStreamRtspAddr().c_str(); - -} - -void IpcViewerWidget::startReplay() -{ - QString replayUrl = m_caminfo->getReplayRtspAddr().c_str(); -// replayUrl += "&starttime=" + QDateTime::fromMSecsSinceEpoch(m_replayStartTime).toTimeSpec(Qt::OffsetFromUTC).toString("yyyyMMdd't'hhmmss'z'"); -// replayUrl += "&endtime=" + QDateTime::fromMSecsSinceEpoch(m_replayEndTime).toTimeSpec(Qt::OffsetFromUTC).toString("yyyyMMdd't'hhmmss'z'"); - replayUrl += "&starttime=" + QDateTime::fromMSecsSinceEpoch(m_replayStartTime).toString("yyyyMMdd't'hhmmss'z'"); - replayUrl += "&endtime=" + QDateTime::fromMSecsSinceEpoch(m_replayEndTime).toString("yyyyMMdd't'hhmmss'z'"); - qDebug() << "replayUrl: " << replayUrl; - - m_r_player->setBufferMode(QtAV::BufferTime); - m_r_player->setBufferValue(50); - m_r_player->audio()->setBufferSamples(64); - m_r_player->setFile(replayUrl); - m_r_player->play(); - setReplayUiToPause(); -} - -void IpcViewerWidget::showStreamFullScreen() -{ - if(!isFullScreen) - { - showFullScreen(); - isFullScreen = true; - } - else - { - showNormal(); - isFullScreen = false; - } -} - -void IpcViewerWidget::setCapturePath() -{ - if(m_s_player != NULL) - { - m_s_player->videoCapture()->setCaptureDir("../../data/videocap"); - m_s_player->videoCapture()->setQuality(100); - m_s_player->videoCapture()->setSaveFormat("jpg"); - } - - if(m_r_player != NULL) - { - m_r_player->videoCapture()->setCaptureDir("../../data/videocap"); - m_r_player->videoCapture()->setQuality(100); - m_r_player->videoCapture()->setSaveFormat("jpg"); - } -} - -void IpcViewerWidget::checkStreamStatus() -{ - if( !m_s_player->isPlaying()) - { - qDebug() << QTime::currentTime().toString() + " Player status" << m_s_player->isPlaying(); - if(!isPause) - m_s_player->play(); - } -} - -void IpcViewerWidget::streamPlayErrCheck(const QtAV::AVError &e) -{ - qDebug() << "stream error happend" << e.string().toStdString().c_str(); -} - -void IpcViewerWidget::replayPlayErrCheck(const QtAV::AVError &e) -{ - if(e.error() == QtAV::AVError::FormatError){ - LOGERROR("查询录像错误,%s",e.string().toStdString().c_str()); - showMsg(tr("无法查询到该段时间录像或者请关闭其他回放窗口")); - } -} - -void IpcViewerWidget::playPauseStreamOp() -{ - m_s_player->pause(!m_s_player->isPaused()); -} - -void IpcViewerWidget::playPauseStreamUi() -{ - if(isPause == false) - { - //< 准备暂停 - setStreamUiToPlay(); - } - else{ - //< 准备播放 - setStreamUiToPause(); - } -} - -void IpcViewerWidget::playPauseStream() -{ - playPauseStreamOp(); - playPauseStreamUi(); -} - -void IpcViewerWidget::setReplayUiToPause() -{ - ui->btn_play_r->setChecked(true); - isPauseR = false; -} - -void IpcViewerWidget::setReplayUiToPlay() -{ - ui->btn_play_r->setChecked(false); - isPauseR = true; -} - -void IpcViewerWidget::playPauseReplayOp() -{ - if (m_s_player->isPaused()) { - m_r_player->play(); - return; - } - m_r_player->pause(!m_r_player->isPaused()); -} - -void IpcViewerWidget::playPauseReplayUi() -{ - if(isPauseR == false) - { - //< 准备暂停 - setReplayUiToPlay(); - } - else{ - //< 准备播放 - setReplayUiToPause(); - } -} - -void IpcViewerWidget::playPauseReplay() -{ - playPauseReplayOp(); - playPauseReplayUi(); -} - -double IpcViewerWidget::getCurrentCmdspeed() -{ - return ui->slider_cmdspeed->value() / 100.0; -} - - -void IpcViewerWidget::showMsg(const QString& msg) -{ - ui->mShowMsgLable->setText(msg); - - if (!msg.isEmpty()) - { - QTimer::singleShot(5000, this, SLOT(showMsg())); - } -} - -void IpcViewerWidget::stopHandler() -{ - playPauseReplayUi(); -} - -void IpcViewerWidget::slot_presets_itemChanged(const QString & str) -{ - ui->comboBox_presets->setToolTip(str); -} - -void IpcViewerWidget::setStreamEnabled(bool isStreamEnabled) -{ - ui->tab->setEnabled(isStreamEnabled); -} - -void IpcViewerWidget::setPtzEnabled(bool isPtzEnabled) -{ - ui->frame->setEnabled(isPtzEnabled); -} - -void IpcViewerWidget::setReplayEnabled(bool isReplayEnabled) -{ - ui->tab_2->setEnabled(isReplayEnabled); -} - -bool IpcViewerWidget::ptzContinuousMove(int cmd, double cmd_speed) -{ - if(PTZ_UI_TEST) - { - return m_caminfo->continuousMove(cmd,cmd_speed); - } - else - { - return sendOptContinuousMove(cmd,cmd_speed); - } -} - -bool IpcViewerWidget::ptzStopMove() -{ - if(PTZ_UI_TEST) - { - return m_caminfo->stopMove(); - } - else - { - return sendOptStopMove(); - } -} - -bool IpcViewerWidget::ptzGotopreset(const std::string &preset_tag) -{ - if(PTZ_UI_TEST) - { - if(m_caminfo->gotoPreset(preset_tag) == false) - { - return false; - } - } - else - { - if(this->sendOptGotopreset(preset_tag) == false) - { - return false; - } - } - return true; - -} - -bool IpcViewerWidget::sendOptContinuousMove(int cmd, double cmd_speed) -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_strAppName; - stCustomCmd.stHead.nSrcDomainID = m_nDomainId; - stCustomCmd.stHead.nDstDomainID = m_nDomainId; - stCustomCmd.stHead.nAppID = m_nAppId; - stCustomCmd.stHead.strHostName = m_strNodeName; - stCustomCmd.stHead.strInstName = m_strAppName; - stCustomCmd.stHead.strCommName = m_msgBusMng->getCommunicatorName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加转动命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE;//转动 - stOptKeyValue.strKeyValue = CCTV_ONVIF_MOVE ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_caminfo->camTag() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加方向 - stOptKeyValue.strKeyName = PTZ_COMMOND; - stOptKeyValue.strKeyValue = QString::number(cmd).toStdString() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加速度 - stOptKeyValue.strKeyName = PTZ_SPEED; - stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - - if(!m_msgBusMng->sendMsgToDomain(MT_OPT_COMMON_DOWN,CH_HMI_TO_OPT_OPTCMD_DOWN,strMsg)) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - -bool IpcViewerWidget::sendOptStopMove() -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_strAppName; - stCustomCmd.stHead.nSrcDomainID = m_nDomainId; - stCustomCmd.stHead.nDstDomainID = m_nDomainId; - stCustomCmd.stHead.nAppID = m_nAppId; - stCustomCmd.stHead.strHostName = m_strNodeName; - stCustomCmd.stHead.strInstName = m_strAppName; - stCustomCmd.stHead.strCommName = m_msgBusMng->getCommunicatorName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加停止转动命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE; - stOptKeyValue.strKeyValue = CCTV_ONVIF_STOPMOVE ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_caminfo->camTag() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - - if(!m_msgBusMng->sendMsgToDomain(MT_OPT_COMMON_DOWN,CH_HMI_TO_OPT_OPTCMD_DOWN,strMsg)) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - -bool IpcViewerWidget::sendOptGotopreset(const std::string &preset_tag) -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_strAppName; - stCustomCmd.stHead.nSrcDomainID = m_nDomainId; - stCustomCmd.stHead.nDstDomainID = m_nDomainId; - stCustomCmd.stHead.nAppID = m_nAppId; - stCustomCmd.stHead.strHostName = m_strNodeName; - stCustomCmd.stHead.strInstName = m_strAppName; - stCustomCmd.stHead.strCommName = m_msgBusMng->getCommunicatorName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加转到预置点命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE; - stOptKeyValue.strKeyValue = CCTV_ONVIF_GOTOPRESET ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_caminfo->camTag() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加预置点标签 - stOptKeyValue.strKeyName = PRESET_TAG; - stOptKeyValue.strKeyValue = preset_tag; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - - if(!m_msgBusMng->sendMsgToDomain(MT_OPT_COMMON_DOWN,CH_HMI_TO_OPT_OPTCMD_DOWN,strMsg)) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - -void IpcViewerWidget::setStreamUiToPause() -{ - ui->btn_play->setChecked(true); - isPause = false; -} - -void IpcViewerWidget::setStreamUiToPlay() -{ - ui->btn_play->setChecked(false); - isPause = true; -} - -void IpcViewerWidget::on_btn_play_r_clicked() -{ - playPauseReplay(); -} - -void IpcViewerWidget::on_btn_vol_r_clicked() -{ - if(isMuteR == true) - { - //< 停止静音 - m_r_player->audio()->setMute(false); - m_r_player->audio()->setVolume(qreal(ui->volSlider->value() / 100.0)); - - ui->btn_vol_r->setChecked(false); - ui->volSlider_r->setDisabled(false); - isMuteR = false; - } - else - { - //< 开始静音 - m_r_player->audio()->setMute(true); - - ui->btn_vol_r->setChecked(true); - ui->volSlider_r->setDisabled(true); - isMuteR = true; - } -} - -void IpcViewerWidget::on_volSlider_valueChanged(int value) -{ - m_s_player->audio()->setVolume(qreal(value / 100.0)); - -} - -void IpcViewerWidget::on_btn_cam_clicked() -{ - if (m_s_player->isPlaying()) { - m_s_player->videoCapture()->setCaptureName(QDateTime::currentDateTime().toString("yyyy_MMdd_hhmmss_z")); - emit this->startStreamCapture(); - } -} - -void IpcViewerWidget::on_volSlider_r_valueChanged(int value) -{ - m_r_player->audio()->setVolume(qreal(value / 100.0)); - -} - - - -void IpcViewerWidget::on_btn_record_query_clicked() -{ - if(m_caminfo == NULL) - { - return; - } - m_r_player->stop(); - setReplayUiToPlay(); - if(ui->timeEdit_endtime->time() < ui->timeEdit_starttime->time()) - { - showMsg(tr("请开始时间小于结束时间")); - return; - } - - if(ui->timeEdit_starttime->time().secsTo(ui->timeEdit_endtime->time()) < 20) - { - showMsg(tr("间隔时间请大于等于20s")); - return; - } - m_replayStartTime = QDateTime(ui->dateEdit->date(),ui->timeEdit_starttime->time()).toMSecsSinceEpoch(); - m_replayEndTime = QDateTime(ui->dateEdit->date(),ui->timeEdit_endtime->time()).toMSecsSinceEpoch(); - - m_r_timer.setInterval(1000); - m_r_timer.setSingleShot(true); - connect(&m_r_timer,&QTimer::timeout,this,&IpcViewerWidget::startReplay); - m_r_timer.start(); - -} - - - -//< 云台控制 - -void IpcViewerWidget::on_right_pressed() -{ - if(!m_s_player->isPlaying()) - return; - - - if(ptzContinuousMove(PTZ_RIGHT,getCurrentCmdspeed()) == false) - { - qDebug() << "向右转动失败"; - return; - } - -} - -void IpcViewerWidget::on_right_released() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; - -} - -void IpcViewerWidget::on_left_pressed() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_LEFT,getCurrentCmdspeed()) == false) - { - qDebug() << "向左转动失败"; - } -} - -void IpcViewerWidget::on_left_released() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; -} - - - -void IpcViewerWidget::on_up_pressed() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_UP,getCurrentCmdspeed()) == false) - { - qDebug() << "向上转动失败"; - } -} - -void IpcViewerWidget::on_up_released() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; -} - -void IpcViewerWidget::on_down_pressed() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_DOWN,getCurrentCmdspeed()) == false) - { - qDebug() << "向下转动失败"; - } -} - -void IpcViewerWidget::on_down_released() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; -} - - -void IpcViewerWidget::on_btn_zoomin_pressed() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_ZOOMIN,getCurrentCmdspeed()) == false) - { - qDebug() << "zoomin转动失败"; - } -} - -void IpcViewerWidget::on_btn_zoomin_released() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; -} - -void IpcViewerWidget::on_btn_zoomout_released() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; -} - -void IpcViewerWidget::on_btn_zoomout_pressed() -{ - if(!m_s_player->isPlaying()) - return; - if(ptzContinuousMove(PTZ_ZOOMOUT,getCurrentCmdspeed()) == false) - { - qDebug() << "zoomout转动失败"; - } -} - -//> 云台控制 - -void IpcViewerWidget::on_btn_gotopreset_clicked() -{ - if(!m_s_player->isPlaying()) - return; - else - { - if(ptzGotopreset(ui->comboBox_presets->currentData().toString().toStdString().c_str()) == false) - { - LOGERROR("cannot gotopreset %s",ui->comboBox_presets->currentData().toString().toStdString().c_str()); - qDebug() << "转到预置点失败"; - } - } -} - -void IpcViewerWidget::on_btn_cam_r_clicked() -{ - if (m_r_player->isPlaying()) { - m_r_player->videoCapture()->setCaptureName(QDateTime::currentDateTime().toString("yyyy_MMdd_hhmmss_z")); - emit this->startReplayCapture(); - } -} - - +#include "ipcviewerwidget.h" +#include "ui_ipcviewerwidget.h" +#include +#include +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "operate_server_api/JsonOptCommand.h" +#include +#include +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + + +#define APP_NAME "hmi" +#define NODE_NAME "test_node" +#define VIDEO_SERVER_RTU_NAME "##$$video_server$$##" + +#define PTZ_UP 0 +#define PTZ_DOWN 1 +#define PTZ_LEFT 2 +#define PTZ_RIGHT 3 +#define PTZ_ZOOMIN 4 +#define PTZ_ZOOMOUT 5 + +#define CCTV_ONVIF_MOVE "58" +#define CCTV_ONVIF_STOPMOVE "59" +#define CCTV_ONVIF_GOTOPRESET "57" + +#define KEY_CMD_TYPE "cmd_type" +#define CAMERA_TAG "camera_tag" +#define PTZ_COMMOND "commond" +#define PTZ_SPEED "speed" +#define PRESET_TAG "preset_tag" + +#define PTZ_UI_TEST true + + + + +IpcViewerWidget::IpcViewerWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::IpcViewerWidget), + m_caminfo(NULL), + m_isStreamFirst(true), + m_isEditMode(editMode), + m_strNodeName(NODE_NAME), + m_strAppName(APP_NAME), + m_msgBusMng(new CIpcViewerMsgBusMng) +{ + Q_UNUSED(editMode) + ui->setupUi(this); + + QApplication::setAttribute(Qt::AA_UseOpenGLES); + QtAV::Widgets::registerRenderers(); + QtAV::setLogLevel(QtAV::LogOff); + initUi(); + + if(m_isStreamFirst) + { + ui->tabWidget->setCurrentIndex(0); + } + else + { + ui->tabWidget->setCurrentIndex(1); + } + + if(!m_isEditMode){ + if(m_playerCfgParser.isValid()) + { + m_playerCfgParser.applyToPlayer(*m_s_player); + m_playerCfgParser.applyToPlayer(*m_r_player); + } + else + { + showMsg(tr("播放器配置错误")); + } + } + + + + QtAV::Widgets::registerRenderers(); + +} + + +IpcViewerWidget::~IpcViewerWidget() +{ + delete ui; + delete m_s_player; + delete m_s_vo; + + delete m_r_player; + delete m_r_vo; + + delete m_msgBusMng; + + if(m_caminfo != NULL) + { + delete m_caminfo; + } + +} + +void IpcViewerWidget::setStreamInfo(QString pointTag) +{ + if(m_isEditMode) + return; + m_pointTag = pointTag; + loadCamInfo(); +} + +void IpcViewerWidget::setReplayInfo(QString pointTag, quint64 startTimestamp, quint64 endTimestamp) +{ + if(m_isEditMode) + return; + m_isStreamFirst = false; + ui->tabWidget->setCurrentIndex(1); + m_pointTag = pointTag; + m_replayStartTime = startTimestamp; + m_replayEndTime = endTimestamp; + + QDateTime datetime = QDateTime::fromMSecsSinceEpoch(startTimestamp); + ui->dateEdit->setDate(datetime.date()); + ui->timeEdit_starttime->setTime(datetime.time()); + ui->timeEdit_starttime->setTime(QDateTime::fromMSecsSinceEpoch(endTimestamp).time()); + loadCamInfo(); +} + +void IpcViewerWidget::setNodeInfo(int nDomainId, int nAppid) +{ + m_nDomainId = nDomainId; + m_nAppId = nAppid; + m_msgBusMng->setNodeInfo(nDomainId,nAppid); +} + +void IpcViewerWidget::setNodeName(const QString &nodeName) +{ + m_strNodeName = nodeName.toStdString(); +} + +void IpcViewerWidget::setAppName(const QString &appName) +{ + m_strAppName = appName.toStdString(); +} + + +void IpcViewerWidget::on_tabWidget_currentChanged(int index) +{ + switch (index) { + case 0: + this->setWindowTitle(tr("实时视频")); + + m_s_player->audio()->setMute(false); + m_r_player->audio()->setMute(true); + + //< 从录像切换到直播 + if(!m_isStreamFirst) + { + startStream(); + } + + break; + case 1: + this->setWindowTitle(tr("录像回放")); + + m_s_player->audio()->setMute(true); + m_r_player->audio()->setMute(false); + + + break; + default: + break; + } +} + + +void IpcViewerWidget::on_btn_play_clicked() +{ + playPauseStream(); +} + +void IpcViewerWidget::on_btn_vol_clicked() +{ + if(isMute == true) + { + //< 停止静音 + m_s_player->audio()->setMute(false); + m_s_player->audio()->setVolume(qreal(ui->volSlider->value() / 100.0)); + + ui->btn_vol->setChecked(false); + ui->volSlider->setDisabled(false); + isMute = false; + } + else + { + //< 开始静音 + m_s_player->audio()->setMute(true); + ui->btn_vol->setChecked(true); + ui->volSlider->setDisabled(true); + isMute = true; + } +} + +void IpcViewerWidget::initUi() +{ + + + this->setWindowTitle(tr("实时视频")); + this->setWindowFlags(windowFlags() & Qt::FramelessWindowHint & ~Qt::WindowContextHelpButtonHint); + initStylesheet(); + initStreamUi(); + initStreamConnect(); + initReplayUi(); + initReplayConnect(); + setCapturePath(); +} + +void IpcViewerWidget::initStylesheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("ipcViewer.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void IpcViewerWidget::initStreamUi() +{ + ui->btn_fullScreen->setHidden(true);// 暂时隐藏全屏按钮 + + m_s_player = new QtAV::AVPlayer(this); + m_s_vo = new QtAV::VideoOutput(this); + if (!m_s_vo->widget()) { + showMsg(tr("QtAV error:Can not create video renderer")); + return; + } + m_s_player->setRenderer(m_s_vo); + QHBoxLayout *hlayout = new QHBoxLayout; + QVBoxLayout *vlayout = new QVBoxLayout; + + ui->frame_2->setSizePolicy(ui->frame_2->sizePolicy().horizontalPolicy(),QSizePolicy::Fixed); + ui->frame_2->setMinimumHeight(25); + +// ui->frame->setSizePolicy(QSizePolicy::Fixed,ui->frame->sizePolicy().verticalPolicy()); +// ui->frame->setMinimumWidth(170); +// ui->frame->setMaximumWidth(170); + + m_s_vo->widget()->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); + m_s_vo->widget()->setMinimumHeight(279); + m_s_vo->widget()->setMinimumWidth(496); + vlayout->addWidget(m_s_vo->widget()); + vlayout->addWidget(ui->frame_2); + hlayout->addLayout(vlayout); + hlayout->addWidget(ui->frame); + ui->tab->setLayout(hlayout); + + + + ui->frame->setFrameStyle(QFrame::Box | QFrame::Plain); + ui->frame_2->setFrameStyle(QFrame::Box | QFrame::Plain); + + + int BtnSize = 25; + QPixmap pixmapR(":img/right.png"); + pixmapR = pixmapR.scaled( BtnSize, BtnSize, Qt::KeepAspectRatio ); + ui->right->setFixedSize(pixmapR.size()); + ui->right->setMask(pixmapR.mask()); + + QPixmap pixmapL(":img/left.png"); + pixmapL = pixmapL.scaled( BtnSize, BtnSize, Qt::KeepAspectRatio ); + ui->left->setFixedSize(pixmapL.size()); + ui->left->setMask(pixmapL.mask()); + + + QPixmap pixmapU(":img/up.png"); + pixmapU = pixmapU.scaled( BtnSize, BtnSize, Qt::KeepAspectRatio ); + ui->up->setFixedSize(pixmapU.size()); + ui->up->setMask(pixmapU.mask()); + + QPixmap pixmapD(":img/down.png"); + pixmapD = pixmapD.scaled( BtnSize, BtnSize, Qt::KeepAspectRatio ); + ui->down->setFixedSize(pixmapD.size()); + ui->down->setMask(pixmapD.mask()); + + QPixmap pixmapPlay(":img/play.png"); + pixmapPlay = pixmapPlay.scaled( 16, 16, Qt::KeepAspectRatio ); + ui->btn_play->setFixedSize(pixmapPlay.size()); + ui->btn_play->setCheckable(true); + + QPixmap pixmapCam(":img/camera.svg"); + pixmapCam = pixmapCam.scaled( 16, 16, Qt::KeepAspectRatio ); + ui->btn_cam->setFixedSize(pixmapCam.size()); + ui->btn_cam->setCheckable(true); + + QPixmap pixmapVol(":img/vol.svg"); + pixmapVol = pixmapVol.scaled( 16, 16, Qt::KeepAspectRatio ); + ui->btn_vol->setFixedSize(pixmapVol.size()); + ui->btn_vol->setCheckable(true); + + QPixmap pixmapFullScreen(":img/fullscreen.png"); + pixmapFullScreen = pixmapFullScreen.scaled( 16, 16, Qt::KeepAspectRatio ); + ui->btn_fullScreen->setFixedSize(pixmapFullScreen.size()); +} + +void IpcViewerWidget::initStreamConnect() +{ + connect(m_s_player,&QtAV::AVPlayer::error,this,&IpcViewerWidget::streamPlayErrCheck); + connect(this,&IpcViewerWidget::startStreamCapture,m_s_player->videoCapture(),&QtAV::VideoCapture::capture); + connect(ui->btn_fullScreen,&QPushButton::clicked,this,&IpcViewerWidget::showStreamFullScreen); + connect(&m_streamPlayCheck,&QTimer::timeout,this,&IpcViewerWidget::checkStreamStatus); +} + +void IpcViewerWidget::initReplayUi() +{ + // hidden 元素 +// ui->replayslider->setHidden(true); +// ui->label_time_r->setHidden(true); + + ui->dateEdit->setDate(QDate::currentDate().addDays(-1)); + ui->timeEdit_starttime->setTime(QTime(8,0,0)); + ui->timeEdit_endtime->setTime(QTime(10,0,0)); + + m_r_player = new QtAV::AVPlayer(this); + m_r_vo = new QtAV::VideoOutput(this); + if (!m_s_vo->widget()) { + showMsg(tr("QtAV error:Can not create video renderer")); + return; + } + m_r_player->setRenderer(m_r_vo); + QHBoxLayout *hlayout = new QHBoxLayout; + QVBoxLayout *vlayout = new QVBoxLayout; + + ui->frame_record_play->setSizePolicy(ui->frame_record_play->sizePolicy().horizontalPolicy(),QSizePolicy::Fixed); + ui->frame_record_play->setMinimumHeight(25); + +// ui->frame_record_search->setSizePolicy(QSizePolicy::Fixed,ui->frame_record_search->sizePolicy().verticalPolicy()); +// ui->frame_record_search->setMinimumWidth(170); +// ui->frame_record_search->setMaximumWidth(170); + + m_r_vo->widget()->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); + m_r_vo->widget()->setMinimumHeight(279); + m_r_vo->widget()->setMinimumWidth(496); + vlayout->addWidget(m_r_vo->widget()); + vlayout->addWidget(ui->frame_record_play); + hlayout->addLayout(vlayout); + hlayout->addWidget(ui->frame_record_search); + ui->tab_2->setLayout(hlayout); + + + ui->frame_record_search->setFrameStyle(QFrame::Box | QFrame::Plain); + ui->frame_record_play->setFrameStyle(QFrame::Box | QFrame::Plain); + + + QPixmap pixmapPlay(":img/play.png"); + pixmapPlay = pixmapPlay.scaled( 16, 16, Qt::KeepAspectRatio ); + ui->btn_play_r->setFixedSize(pixmapPlay.size()); + ui->btn_play_r->setCheckable(true); + + QPixmap pixmapCam(":img/camera.svg"); + pixmapCam = pixmapCam.scaled( 16, 16, Qt::KeepAspectRatio ); + ui->btn_cam_r->setFixedSize(pixmapCam.size()); + ui->btn_cam_r->setCheckable(true); + + QPixmap pixmapVol(":img/vol.svg"); + pixmapVol = pixmapVol.scaled( 16, 16, Qt::KeepAspectRatio ); + ui->btn_vol_r->setFixedSize(pixmapVol.size()); + ui->btn_vol_r->setCheckable(true); + + + +} + +void IpcViewerWidget::initReplayConnect() +{ + connect(m_r_player,&QtAV::AVPlayer::error,this,&IpcViewerWidget::replayPlayErrCheck); + connect(this,&IpcViewerWidget::startReplayCapture,m_r_player->videoCapture(),&QtAV::VideoCapture::capture); +// connect(m_r_player,&QtAV::AVPlayer::started,this,&IpcViewerWidget::startUpdateCurrrentReplayTime); + connect(m_r_player,&QtAV::AVPlayer::stopped,this,&IpcViewerWidget::stopHandler); + connect(ui->comboBox_presets,&QComboBox::currentTextChanged,this,&IpcViewerWidget::slot_presets_itemChanged); +} + +void IpcViewerWidget::loadCamInfo() +{ + if(m_caminfo == NULL) + { + m_caminfo = new CCamInfo; + } + else + { + return; + } + + CRdbAccessUtilty rdbutilty(m_nDomainId,m_nAppId); + if(rdbutilty.getCamInfo(m_pointTag.toStdString(),*m_caminfo) == false) + { + showMsg(tr("请检查摄像头设备建模是否正确")); + return; + } + m_caminfo->getOnvifArgs(); + + setStreamEnabled(m_caminfo->isStreamEnabled()); + setReplayEnabled(m_caminfo->isReplayEnabled()); + setPtzEnabled(m_caminfo->isPtzEnabled()); + + //< 预置点加载 + std::vector presets = m_caminfo->presets(); + for(int i = 0; i < (int)presets.size();i++) + { + ui->comboBox_presets->addItem(QString::fromStdString( presets[i].presetDesc),presets[i].presetTag.c_str()); + ui->comboBox_presets->setItemData(i,QString::fromStdString(presets[i].presetTag) + ":" + presets[i].presetDesc.c_str(), Qt::ToolTipRole); + } + + //< 根据设置开始直播 + if(m_isStreamFirst) + { + startStream(); + //< 转到预置点 + if(m_caminfo->isPtzEnabled() && m_caminfo->presetTag() != "") + { + if( !ptzGotopreset( m_caminfo->presetTag() ) ) + LOGERROR("转到预置点失败"); + } + } + else + { + startReplay(); + } + +} + +void IpcViewerWidget::startStream() +{ + + if(m_s_player->isPlaying()) + { + return; + } +m_streamPlayCheck.setInterval(3000); + m_s_player->setBufferMode(QtAV::BufferPackets); + m_s_player->setBufferValue(1); + + m_s_player->setFile(m_caminfo->getStreamRtspAddr().c_str()); + m_s_player->play(); + m_streamPlayCheck.setInterval(3000); + m_streamPlayCheck.start(); + playPauseStreamUi(); + + +// qDebug() << m_caminfo->getStreamRtspAddr().c_str(); + +} + +void IpcViewerWidget::startReplay() +{ + QString replayUrl = m_caminfo->getReplayRtspAddr().c_str(); +// replayUrl += "&starttime=" + QDateTime::fromMSecsSinceEpoch(m_replayStartTime).toTimeSpec(Qt::OffsetFromUTC).toString("yyyyMMdd't'hhmmss'z'"); +// replayUrl += "&endtime=" + QDateTime::fromMSecsSinceEpoch(m_replayEndTime).toTimeSpec(Qt::OffsetFromUTC).toString("yyyyMMdd't'hhmmss'z'"); + replayUrl += "&starttime=" + QDateTime::fromMSecsSinceEpoch(m_replayStartTime).toString("yyyyMMdd't'hhmmss'z'"); + replayUrl += "&endtime=" + QDateTime::fromMSecsSinceEpoch(m_replayEndTime).toString("yyyyMMdd't'hhmmss'z'"); + qDebug() << "replayUrl: " << replayUrl; + + m_r_player->setBufferMode(QtAV::BufferTime); + m_r_player->setBufferValue(50); + m_r_player->audio()->setBufferSamples(64); + m_r_player->setFile(replayUrl); + m_r_player->play(); + setReplayUiToPause(); +} + +void IpcViewerWidget::showStreamFullScreen() +{ + if(!isFullScreen) + { + showFullScreen(); + isFullScreen = true; + } + else + { + showNormal(); + isFullScreen = false; + } +} + +void IpcViewerWidget::setCapturePath() +{ + if(m_s_player != NULL) + { + m_s_player->videoCapture()->setCaptureDir("../../data/videocap"); + m_s_player->videoCapture()->setQuality(100); + m_s_player->videoCapture()->setSaveFormat("jpg"); + } + + if(m_r_player != NULL) + { + m_r_player->videoCapture()->setCaptureDir("../../data/videocap"); + m_r_player->videoCapture()->setQuality(100); + m_r_player->videoCapture()->setSaveFormat("jpg"); + } +} + +void IpcViewerWidget::checkStreamStatus() +{ + if( !m_s_player->isPlaying()) + { + qDebug() << QTime::currentTime().toString() + " Player status" << m_s_player->isPlaying(); + if(!isPause) + m_s_player->play(); + } +} + +void IpcViewerWidget::streamPlayErrCheck(const QtAV::AVError &e) +{ + qDebug() << "stream error happend" << e.string().toStdString().c_str(); +} + +void IpcViewerWidget::replayPlayErrCheck(const QtAV::AVError &e) +{ + if(e.error() == QtAV::AVError::FormatError){ + LOGERROR("查询录像错误,%s",e.string().toStdString().c_str()); + showMsg(tr("无法查询到该段时间录像或者请关闭其他回放窗口")); + } +} + +void IpcViewerWidget::playPauseStreamOp() +{ + m_s_player->pause(!m_s_player->isPaused()); +} + +void IpcViewerWidget::playPauseStreamUi() +{ + if(isPause == false) + { + //< 准备暂停 + setStreamUiToPlay(); + } + else{ + //< 准备播放 + setStreamUiToPause(); + } +} + +void IpcViewerWidget::playPauseStream() +{ + playPauseStreamOp(); + playPauseStreamUi(); +} + +void IpcViewerWidget::setReplayUiToPause() +{ + ui->btn_play_r->setChecked(true); + isPauseR = false; +} + +void IpcViewerWidget::setReplayUiToPlay() +{ + ui->btn_play_r->setChecked(false); + isPauseR = true; +} + +void IpcViewerWidget::playPauseReplayOp() +{ + if (m_s_player->isPaused()) { + m_r_player->play(); + return; + } + m_r_player->pause(!m_r_player->isPaused()); +} + +void IpcViewerWidget::playPauseReplayUi() +{ + if(isPauseR == false) + { + //< 准备暂停 + setReplayUiToPlay(); + } + else{ + //< 准备播放 + setReplayUiToPause(); + } +} + +void IpcViewerWidget::playPauseReplay() +{ + playPauseReplayOp(); + playPauseReplayUi(); +} + +double IpcViewerWidget::getCurrentCmdspeed() +{ + return ui->slider_cmdspeed->value() / 100.0; +} + + +void IpcViewerWidget::showMsg(const QString& msg) +{ + ui->mShowMsgLable->setText(msg); + + if (!msg.isEmpty()) + { + QTimer::singleShot(5000, this, SLOT(showMsg())); + } +} + +void IpcViewerWidget::stopHandler() +{ + playPauseReplayUi(); +} + +void IpcViewerWidget::slot_presets_itemChanged(const QString & str) +{ + ui->comboBox_presets->setToolTip(str); +} + +void IpcViewerWidget::setStreamEnabled(bool isStreamEnabled) +{ + ui->tab->setEnabled(isStreamEnabled); +} + +void IpcViewerWidget::setPtzEnabled(bool isPtzEnabled) +{ + ui->frame->setEnabled(isPtzEnabled); +} + +void IpcViewerWidget::setReplayEnabled(bool isReplayEnabled) +{ + ui->tab_2->setEnabled(isReplayEnabled); +} + +bool IpcViewerWidget::ptzContinuousMove(int cmd, double cmd_speed) +{ + if(PTZ_UI_TEST) + { + return m_caminfo->continuousMove(cmd,cmd_speed); + } + else + { + return sendOptContinuousMove(cmd,cmd_speed); + } +} + +bool IpcViewerWidget::ptzStopMove() +{ + if(PTZ_UI_TEST) + { + return m_caminfo->stopMove(); + } + else + { + return sendOptStopMove(); + } +} + +bool IpcViewerWidget::ptzGotopreset(const std::string &preset_tag) +{ + if(PTZ_UI_TEST) + { + if(m_caminfo->gotoPreset(preset_tag) == false) + { + return false; + } + } + else + { + if(this->sendOptGotopreset(preset_tag) == false) + { + return false; + } + } + return true; + +} + +bool IpcViewerWidget::sendOptContinuousMove(int cmd, double cmd_speed) +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_strAppName; + stCustomCmd.stHead.nSrcDomainID = m_nDomainId; + stCustomCmd.stHead.nDstDomainID = m_nDomainId; + stCustomCmd.stHead.nAppID = m_nAppId; + stCustomCmd.stHead.strHostName = m_strNodeName; + stCustomCmd.stHead.strInstName = m_strAppName; + stCustomCmd.stHead.strCommName = m_msgBusMng->getCommunicatorName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加转动命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE;//转动 + stOptKeyValue.strKeyValue = CCTV_ONVIF_MOVE ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_caminfo->camTag() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加方向 + stOptKeyValue.strKeyName = PTZ_COMMOND; + stOptKeyValue.strKeyValue = QString::number(cmd).toStdString() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加速度 + stOptKeyValue.strKeyName = PTZ_SPEED; + stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + + if(!m_msgBusMng->sendMsgToDomain(MT_OPT_COMMON_DOWN,CH_HMI_TO_OPT_OPTCMD_DOWN,strMsg)) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + +bool IpcViewerWidget::sendOptStopMove() +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_strAppName; + stCustomCmd.stHead.nSrcDomainID = m_nDomainId; + stCustomCmd.stHead.nDstDomainID = m_nDomainId; + stCustomCmd.stHead.nAppID = m_nAppId; + stCustomCmd.stHead.strHostName = m_strNodeName; + stCustomCmd.stHead.strInstName = m_strAppName; + stCustomCmd.stHead.strCommName = m_msgBusMng->getCommunicatorName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加停止转动命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE; + stOptKeyValue.strKeyValue = CCTV_ONVIF_STOPMOVE ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_caminfo->camTag() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + + if(!m_msgBusMng->sendMsgToDomain(MT_OPT_COMMON_DOWN,CH_HMI_TO_OPT_OPTCMD_DOWN,strMsg)) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + +bool IpcViewerWidget::sendOptGotopreset(const std::string &preset_tag) +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_strAppName; + stCustomCmd.stHead.nSrcDomainID = m_nDomainId; + stCustomCmd.stHead.nDstDomainID = m_nDomainId; + stCustomCmd.stHead.nAppID = m_nAppId; + stCustomCmd.stHead.strHostName = m_strNodeName; + stCustomCmd.stHead.strInstName = m_strAppName; + stCustomCmd.stHead.strCommName = m_msgBusMng->getCommunicatorName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加转到预置点命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE; + stOptKeyValue.strKeyValue = CCTV_ONVIF_GOTOPRESET ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_caminfo->camTag() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加预置点标签 + stOptKeyValue.strKeyName = PRESET_TAG; + stOptKeyValue.strKeyValue = preset_tag; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + + if(!m_msgBusMng->sendMsgToDomain(MT_OPT_COMMON_DOWN,CH_HMI_TO_OPT_OPTCMD_DOWN,strMsg)) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_nAppId, + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + +void IpcViewerWidget::setStreamUiToPause() +{ + ui->btn_play->setChecked(true); + isPause = false; +} + +void IpcViewerWidget::setStreamUiToPlay() +{ + ui->btn_play->setChecked(false); + isPause = true; +} + +void IpcViewerWidget::on_btn_play_r_clicked() +{ + playPauseReplay(); +} + +void IpcViewerWidget::on_btn_vol_r_clicked() +{ + if(isMuteR == true) + { + //< 停止静音 + m_r_player->audio()->setMute(false); + m_r_player->audio()->setVolume(qreal(ui->volSlider->value() / 100.0)); + + ui->btn_vol_r->setChecked(false); + ui->volSlider_r->setDisabled(false); + isMuteR = false; + } + else + { + //< 开始静音 + m_r_player->audio()->setMute(true); + + ui->btn_vol_r->setChecked(true); + ui->volSlider_r->setDisabled(true); + isMuteR = true; + } +} + +void IpcViewerWidget::on_volSlider_valueChanged(int value) +{ + m_s_player->audio()->setVolume(qreal(value / 100.0)); + +} + +void IpcViewerWidget::on_btn_cam_clicked() +{ + if (m_s_player->isPlaying()) { + m_s_player->videoCapture()->setCaptureName(QDateTime::currentDateTime().toString("yyyy_MMdd_hhmmss_z")); + emit this->startStreamCapture(); + } +} + +void IpcViewerWidget::on_volSlider_r_valueChanged(int value) +{ + m_r_player->audio()->setVolume(qreal(value / 100.0)); + +} + + + +void IpcViewerWidget::on_btn_record_query_clicked() +{ + if(m_caminfo == NULL) + { + return; + } + m_r_player->stop(); + setReplayUiToPlay(); + if(ui->timeEdit_endtime->time() < ui->timeEdit_starttime->time()) + { + showMsg(tr("请开始时间小于结束时间")); + return; + } + + if(ui->timeEdit_starttime->time().secsTo(ui->timeEdit_endtime->time()) < 20) + { + showMsg(tr("间隔时间请大于等于20s")); + return; + } + m_replayStartTime = QDateTime(ui->dateEdit->date(),ui->timeEdit_starttime->time()).toMSecsSinceEpoch(); + m_replayEndTime = QDateTime(ui->dateEdit->date(),ui->timeEdit_endtime->time()).toMSecsSinceEpoch(); + + m_r_timer.setInterval(1000); + m_r_timer.setSingleShot(true); + connect(&m_r_timer,&QTimer::timeout,this,&IpcViewerWidget::startReplay); + m_r_timer.start(); + +} + + + +//< 云台控制 + +void IpcViewerWidget::on_right_pressed() +{ + if(!m_s_player->isPlaying()) + return; + + + if(ptzContinuousMove(PTZ_RIGHT,getCurrentCmdspeed()) == false) + { + qDebug() << "向右转动失败"; + return; + } + +} + +void IpcViewerWidget::on_right_released() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; + +} + +void IpcViewerWidget::on_left_pressed() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_LEFT,getCurrentCmdspeed()) == false) + { + qDebug() << "向左转动失败"; + } +} + +void IpcViewerWidget::on_left_released() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; +} + + + +void IpcViewerWidget::on_up_pressed() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_UP,getCurrentCmdspeed()) == false) + { + qDebug() << "向上转动失败"; + } +} + +void IpcViewerWidget::on_up_released() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; +} + +void IpcViewerWidget::on_down_pressed() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_DOWN,getCurrentCmdspeed()) == false) + { + qDebug() << "向下转动失败"; + } +} + +void IpcViewerWidget::on_down_released() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; +} + + +void IpcViewerWidget::on_btn_zoomin_pressed() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_ZOOMIN,getCurrentCmdspeed()) == false) + { + qDebug() << "zoomin转动失败"; + } +} + +void IpcViewerWidget::on_btn_zoomin_released() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; +} + +void IpcViewerWidget::on_btn_zoomout_released() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; +} + +void IpcViewerWidget::on_btn_zoomout_pressed() +{ + if(!m_s_player->isPlaying()) + return; + if(ptzContinuousMove(PTZ_ZOOMOUT,getCurrentCmdspeed()) == false) + { + qDebug() << "zoomout转动失败"; + } +} + +//> 云台控制 + +void IpcViewerWidget::on_btn_gotopreset_clicked() +{ + if(!m_s_player->isPlaying()) + return; + else + { + if(ptzGotopreset(ui->comboBox_presets->currentData().toString().toStdString().c_str()) == false) + { + LOGERROR("cannot gotopreset %s",ui->comboBox_presets->currentData().toString().toStdString().c_str()); + qDebug() << "转到预置点失败"; + } + } +} + +void IpcViewerWidget::on_btn_cam_r_clicked() +{ + if (m_r_player->isPlaying()) { + m_r_player->videoCapture()->setCaptureName(QDateTime::currentDateTime().toString("yyyy_MMdd_hhmmss_z")); + emit this->startReplayCapture(); + } +} + + diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.h b/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.h index 56a41920..f0254d8c 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.h +++ b/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.h @@ -1,207 +1,207 @@ -#ifndef IPCVIEWERWIDGET_H -#define IPCVIEWERWIDGET_H - -#include -#include -#include -#include -#include -#include - -namespace Ui { -class IpcViewerWidget; -} - -namespace QtAV { - class AVPlayer; - class VideoOutput; - class AVError; -} - -class CIpcViewerMsgBusMng; -class CCamInfo; -class IPCVIEWERWIDGET_API IpcViewerWidget : public QWidget -{ - Q_OBJECT - -public: - /** - * @brief IpcViwerWidget 构造函数 - * @param parent - * @param isStreamFirst 是否直播开始首屏 - */ - IpcViewerWidget(QWidget *parent = 0,bool editMode = false); - ~IpcViewerWidget(); - -public slots: - /** - * @brief setStreamInfo 设置直播信息 - * @param pointTag - */ - void setStreamInfo(QString pointTag); - - /** - * @brief setReplayInfo 设置回放信息 - * @param pointTag - * @param startTimestamp - * @param endTimestamp - */ - void setReplayInfo(QString pointTag, - quint64 startTimestamp = QDateTime::currentMSecsSinceEpoch() - 30, - quint64 endTimestamp = QDateTime::currentMSecsSinceEpoch()); - - void setNodeInfo(int nDomainId,int nAppid); - void setNodeName(const QString &nodeName); - void setAppName(const QString &appName); - -private slots: - void on_tabWidget_currentChanged(int index); - void on_btn_play_clicked(); - void on_btn_vol_clicked(); - - void on_right_pressed(); - void on_right_released(); - - void on_left_pressed(); - void on_left_released(); - - void on_up_pressed(); - void on_up_released(); - - void on_down_pressed(); - void on_down_released(); - - void on_btn_zoomin_pressed(); - void on_btn_zoomin_released(); - void on_btn_zoomout_released(); - void on_btn_zoomout_pressed(); - - void on_btn_play_r_clicked(); - void on_btn_vol_r_clicked(); - - void on_volSlider_valueChanged(int value); - - void on_btn_cam_clicked(); - - void on_volSlider_r_valueChanged(int value); - void on_btn_record_query_clicked(); - - - void on_btn_gotopreset_clicked(); - - void on_btn_cam_r_clicked(); - - void showMsg(const QString& msg = QString()); -signals: - void startStreamCapture(); - void startReplayCapture(); - - -private: - void initUi(); - void initStylesheet(); - void initStreamUi(); - void initStreamConnect(); - void initReplayUi(); - void initReplayConnect(); - - void loadCamInfo(); - void setCapturePath(); - - void checkStreamStatus(); - void streamPlayErrCheck(const QtAV::AVError &e); - void replayPlayErrCheck(const QtAV::AVError &e); - - //< 使能控件 - void setStreamEnabled(bool isStreamEnabled); - void setPtzEnabled(bool isPtzEnabled); - void setReplayEnabled(bool isReplayEnabled); - - bool ptzContinuousMove(int cmd,double cmd_speed = 1); - bool ptzStopMove(); - bool ptzGotopreset(const std::string &preset_tag); - - bool sendOptContinuousMove(int cmd, double cmd_speed = 1); - bool sendOptStopMove(); - bool sendOptGotopreset(const std::string &preset_tag); - - // 播放参数相关 - void startStream(); - void startReplay(); - - //< 全屏播放 - void showStreamFullScreen(); - //> 全屏播放 - - //< 播放暂停控件相关 - void setStreamUiToPause(); - void setStreamUiToPlay(); - void playPauseStreamOp(); - void playPauseStreamUi(); - void playPauseStream(); - - void setReplayUiToPause(); - void setReplayUiToPlay(); - void playPauseReplayOp(); - void playPauseReplayUi(); - void playPauseReplay(); - //> 播放暂停控件相关 - - double getCurrentCmdspeed(); - -private slots: -// void startUpdateCurrrentReplayTime(); -// void updateCurrentReplayTime(); - void stopHandler(); - void slot_presets_itemChanged(const QString & str); - - -private: - int m_nDomainId; - int m_nAppId; - - - Ui::IpcViewerWidget *ui; - CCamInfo *m_caminfo; - - - //< 摄像头相关信息 - QString m_pointTag; //< 摄像头关联点 - - quint64 m_replayStartTime; - quint64 m_replayEndTime; - quint64 m_currentReplayTime; - - bool m_isStreamFirst; - - - //< 控件成员 - bool m_isEditMode; - bool isPause = true; - bool isMute = false; - bool isPauseR = true; - bool isMuteR = false; - bool isFullScreen = false; - QtAV::AVPlayer *m_s_player; - QtAV::VideoOutput *m_s_vo; - QtAV::AVPlayer *m_r_player; - QtAV::VideoOutput *m_r_vo; - - - std::string m_strNodeName; - std::string m_strAppName; - - CIpcViewerMsgBusMng* m_msgBusMng; - - //< 定时器 - QTimer m_r_timer; - QTimer m_r_playCountTimer; - CPlayerCfgParser m_playerCfgParser; - QTimer m_streamPlayCheck; - - QLabel* m_msgLabel; -}; - - -#endif // IPCVIEWERWIDGET_H - +#ifndef IPCVIEWERWIDGET_H +#define IPCVIEWERWIDGET_H + +#include +#include +#include +#include +#include +#include + +namespace Ui { +class IpcViewerWidget; +} + +namespace QtAV { + class AVPlayer; + class VideoOutput; + class AVError; +} + +class CIpcViewerMsgBusMng; +class CCamInfo; +class IPCVIEWERWIDGET_API IpcViewerWidget : public QWidget +{ + Q_OBJECT + +public: + /** + * @brief IpcViwerWidget 构造函数 + * @param parent + * @param isStreamFirst 是否直播开始首屏 + */ + IpcViewerWidget(QWidget *parent = 0,bool editMode = false); + ~IpcViewerWidget(); + +public slots: + /** + * @brief setStreamInfo 设置直播信息 + * @param pointTag + */ + void setStreamInfo(QString pointTag); + + /** + * @brief setReplayInfo 设置回放信息 + * @param pointTag + * @param startTimestamp + * @param endTimestamp + */ + void setReplayInfo(QString pointTag, + quint64 startTimestamp = QDateTime::currentMSecsSinceEpoch() - 30, + quint64 endTimestamp = QDateTime::currentMSecsSinceEpoch()); + + void setNodeInfo(int nDomainId,int nAppid); + void setNodeName(const QString &nodeName); + void setAppName(const QString &appName); + +private slots: + void on_tabWidget_currentChanged(int index); + void on_btn_play_clicked(); + void on_btn_vol_clicked(); + + void on_right_pressed(); + void on_right_released(); + + void on_left_pressed(); + void on_left_released(); + + void on_up_pressed(); + void on_up_released(); + + void on_down_pressed(); + void on_down_released(); + + void on_btn_zoomin_pressed(); + void on_btn_zoomin_released(); + void on_btn_zoomout_released(); + void on_btn_zoomout_pressed(); + + void on_btn_play_r_clicked(); + void on_btn_vol_r_clicked(); + + void on_volSlider_valueChanged(int value); + + void on_btn_cam_clicked(); + + void on_volSlider_r_valueChanged(int value); + void on_btn_record_query_clicked(); + + + void on_btn_gotopreset_clicked(); + + void on_btn_cam_r_clicked(); + + void showMsg(const QString& msg = QString()); +signals: + void startStreamCapture(); + void startReplayCapture(); + + +private: + void initUi(); + void initStylesheet(); + void initStreamUi(); + void initStreamConnect(); + void initReplayUi(); + void initReplayConnect(); + + void loadCamInfo(); + void setCapturePath(); + + void checkStreamStatus(); + void streamPlayErrCheck(const QtAV::AVError &e); + void replayPlayErrCheck(const QtAV::AVError &e); + + //< 使能控件 + void setStreamEnabled(bool isStreamEnabled); + void setPtzEnabled(bool isPtzEnabled); + void setReplayEnabled(bool isReplayEnabled); + + bool ptzContinuousMove(int cmd,double cmd_speed = 1); + bool ptzStopMove(); + bool ptzGotopreset(const std::string &preset_tag); + + bool sendOptContinuousMove(int cmd, double cmd_speed = 1); + bool sendOptStopMove(); + bool sendOptGotopreset(const std::string &preset_tag); + + // 播放参数相关 + void startStream(); + void startReplay(); + + //< 全屏播放 + void showStreamFullScreen(); + //> 全屏播放 + + //< 播放暂停控件相关 + void setStreamUiToPause(); + void setStreamUiToPlay(); + void playPauseStreamOp(); + void playPauseStreamUi(); + void playPauseStream(); + + void setReplayUiToPause(); + void setReplayUiToPlay(); + void playPauseReplayOp(); + void playPauseReplayUi(); + void playPauseReplay(); + //> 播放暂停控件相关 + + double getCurrentCmdspeed(); + +private slots: +// void startUpdateCurrrentReplayTime(); +// void updateCurrentReplayTime(); + void stopHandler(); + void slot_presets_itemChanged(const QString & str); + + +private: + int m_nDomainId; + int m_nAppId; + + + Ui::IpcViewerWidget *ui; + CCamInfo *m_caminfo; + + + //< 摄像头相关信息 + QString m_pointTag; //< 摄像头关联点 + + quint64 m_replayStartTime; + quint64 m_replayEndTime; + quint64 m_currentReplayTime; + + bool m_isStreamFirst; + + + //< 控件成员 + bool m_isEditMode; + bool isPause = true; + bool isMute = false; + bool isPauseR = true; + bool isMuteR = false; + bool isFullScreen = false; + QtAV::AVPlayer *m_s_player; + QtAV::VideoOutput *m_s_vo; + QtAV::AVPlayer *m_r_player; + QtAV::VideoOutput *m_r_vo; + + + std::string m_strNodeName; + std::string m_strAppName; + + CIpcViewerMsgBusMng* m_msgBusMng; + + //< 定时器 + QTimer m_r_timer; + QTimer m_r_playCountTimer; + CPlayerCfgParser m_playerCfgParser; + QTimer m_streamPlayCheck; + + QLabel* m_msgLabel; +}; + + +#endif // IPCVIEWERWIDGET_H + diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.ui b/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.ui index 90092421..e9c327a5 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.ui +++ b/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.ui @@ -1,857 +1,857 @@ - - - IpcViewerWidget - - - - 0 - 0 - 548 - 281 - - - - Form - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - 0 - - - - - - - 实时视频 - - - - - 220 - 20 - 210 - 435 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - ptz - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - 移动速度 - - - - - - - 1 - - - 100 - - - 1 - - - 100 - - - Qt::Horizontal - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - 0 - 0 - - - - 调焦 - - - Qt::AlignCenter - - - - - - - + - - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - 聚焦 - - - Qt::AlignCenter - - - - - - - + - - - - - - - - - - - - - - - - - - - 光圈 - - - Qt::AlignCenter - - - - - - - + - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - 预置位: - - - - - - - - 0 - 0 - - - - QComboBox::AdjustToContentsOnFirstShow - - - - - - - - 0 - 0 - - - - 调用 - - - - - - - - - - - 20 - 160 - 252 - 40 - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 6 - - - 0 - - - 6 - - - 0 - - - - - - - - - - - true - - - false - - - false - - - - - - - Qt::Horizontal - - - - 52 - 20 - - - - - - - - true - - - #btn_fullScreen -{ -border-image:url(:img/fullscreen.png) -} -#btn_fullScreen:hover -{ -border-image:url(:img/fullscreen_hovered.png) -} - - - - - - - - - - - - - - - - - true - - - false - - - false - - - - - - - - - - - - - true - - - false - - - false - - - - - - - - 0 - 0 - - - - - 16777215 - 16 - - - - 100 - - - 100 - - - Qt::Horizontal - - - - - - - - - 录像回放 - - - - - 210 - 0 - 110 - 241 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - Qt::Vertical - - - - 20 - 17 - - - - - - - - - - 选择日期 - - - - - - - - 2020 - 2 - 16 - - - - - - - - - - Qt::Vertical - - - - 20 - 1 - - - - - - - - - - - - 开始时间 - - - - - - - H:mm:ss - - - - - - - - - - - - - - 结束时间 - - - - - - - H:mm:ss - - - - - - - - - - - - - - 查询 - - - - - - - Qt::Vertical - - - - 20 - 17 - - - - - - - - - - 0 - 90 - 243 - 43 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 6 - - - 0 - - - 0 - - - - - - - - - - - true - - - false - - - false - - - - - - - Qt::Horizontal - - - - 43 - 20 - - - - - - - - - - - - - - true - - - false - - - false - - - - - - - - - - - - - true - - - false - - - false - - - - - - - - 0 - 0 - - - - - 16777215 - 16 - - - - 1 - - - 100 - - - 100 - - - Qt::Horizontal - - - - - - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 28 - - - - - 16777215 - 28 - - - - - - - - - - - - - - - - - - + + + IpcViewerWidget + + + + 0 + 0 + 548 + 281 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + 0 + + + + + + + 实时视频 + + + + + 220 + 20 + 210 + 435 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + ptz + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 移动速度 + + + + + + + 1 + + + 100 + + + 1 + + + 100 + + + Qt::Horizontal + + + + + + + + + + + + 0 + 0 + + + + - + + + + + + + + 0 + 0 + + + + 调焦 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + + - + + + + + + + + 0 + 0 + + + + 聚焦 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + + - + + + + + + + 光圈 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 预置位: + + + + + + + + 0 + 0 + + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + + 0 + 0 + + + + 调用 + + + + + + + + + + + 20 + 160 + 252 + 40 + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 6 + + + 0 + + + 6 + + + 0 + + + + + + + + + + + true + + + false + + + false + + + + + + + Qt::Horizontal + + + + 52 + 20 + + + + + + + + true + + + #btn_fullScreen +{ +border-image:url(:img/fullscreen.png) +} +#btn_fullScreen:hover +{ +border-image:url(:img/fullscreen_hovered.png) +} + + + + + + + + + + + + + + + + + true + + + false + + + false + + + + + + + + + + + + + true + + + false + + + false + + + + + + + + 0 + 0 + + + + + 16777215 + 16 + + + + 100 + + + 100 + + + Qt::Horizontal + + + + + + + + + 录像回放 + + + + + 210 + 0 + 110 + 241 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + Qt::Vertical + + + + 20 + 17 + + + + + + + + + + 选择日期 + + + + + + + + 2020 + 2 + 16 + + + + + + + + + + Qt::Vertical + + + + 20 + 1 + + + + + + + + + + + + 开始时间 + + + + + + + H:mm:ss + + + + + + + + + + + + + + 结束时间 + + + + + + + H:mm:ss + + + + + + + + + + + + + + 查询 + + + + + + + Qt::Vertical + + + + 20 + 17 + + + + + + + + + + 0 + 90 + 243 + 43 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 6 + + + 0 + + + 0 + + + + + + + + + + + true + + + false + + + false + + + + + + + Qt::Horizontal + + + + 43 + 20 + + + + + + + + + + + + + + true + + + false + + + false + + + + + + + + + + + + + true + + + false + + + false + + + + + + + + 0 + 0 + + + + + 16777215 + 16 + + + + 1 + + + 100 + + + 100 + + + Qt::Horizontal + + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 28 + + + + + 16777215 + 28 + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcviwerwidget.ui b/product/src/gui/plugin/IpcViewerWidget/ipcviwerwidget.ui index f79e877f..79410d0d 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcviwerwidget.ui +++ b/product/src/gui/plugin/IpcViewerWidget/ipcviwerwidget.ui @@ -1,803 +1,803 @@ - - - IpcViwerWidget - - - - 0 - 0 - 328 - 262 - - - - - 0 - 0 - - - - IpcViwerWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - 0 - - - - 实时视频 - - - - - 220 - 20 - 111 - 221 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 9 - - - 9 - - - 9 - - - 9 - - - - - - - #up -{ -border-image:url(:img/up.png) -} -#up:hover -{ -border-image:url(:img/up-hovered.png) -} -#up:pressed -{ -border-image:url(:img/up-clicked.png) -} - - - - - - - - - - #left -{ -border-image:url(:img/left.png) -} -#left:hover -{ -border-image:url(:img/left-hovered.png) -} -#left:pressed -{ -border-image:url(:img/left-clicked.png) -} - - - - - - - - - - ptz - - - Qt::AlignCenter - - - - - - - #right -{ -border-image:url(:img/right.png) -} -#right:hover -{ -border-image:url(:img/right-hovered.png) -} -#right:pressed -{ -border-image:url(:img/right-clicked.png) -} - - - - - - - - - - - - #down -{ -border-image:url(:img/down.png) -} -#down:hover -{ -border-image:url(:img/down-hovered.png) -} -#down:pressed -{ -border-image:url(:img/down-clicked.png) -} - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - 调焦 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - 聚焦 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - - - - - - - - - 光圈 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - 预置位: - - - - - - - QComboBox::AdjustToContentsOnFirstShow - - - - 测试预置点 - - - - - - - - - - - 0 - 0 - - - - 转到 - - - - - - - - - 20 - 160 - 252 - 40 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 6 - - - 0 - - - 6 - - - 0 - - - - - #btn_play -{ -border-image:url(:img/play.png) -} -#btn_play:hover -{ -border-image:url(:img/play-hovered.png) -} - - - - - - - true - - - false - - - false - - - - - - - Qt::Horizontal - - - - 52 - 20 - - - - - - - - #btn_cam -{ -border-image:url(:img/camera.svg) -} -#btn_cam:hover -{ -border-image:url(:img/camera-hovered.svg) -} - - - - - - - true - - - false - - - false - - - - - - - #btn_vol -{ -border-image:url(:img/vol.svg) -} -#btn_vol:hover -{ -border-image:url(:img/vol-hovered.svg) -} - - - - - - - true - - - false - - - false - - - - - - - - 0 - 0 - - - - - 16777215 - 16 - - - - 100 - - - 100 - - - Qt::Horizontal - - - - - - - - - 录像 - - - - - 210 - 0 - 110 - 241 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - Qt::Vertical - - - - 20 - 17 - - - - - - - - - - 选择日期 - - - - - - - - - - - - Qt::Vertical - - - - 20 - 1 - - - - - - - - - - - - 开始时间 - - - - - - - - - - - - - - 结束时间 - - - - - - - - - - - - - - 查询 - - - - - - - Qt::Vertical - - - - 20 - 17 - - - - - - - - - - 0 - 90 - 338 - 36 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 6 - - - 0 - - - 6 - - - 0 - - - - - #btn_play_r -{ -border-image:url(:img/play.png) -} -#btn_play_r:hover -{ -border-image:url(:img/play-hovered.png) -} - - - - - - - true - - - false - - - false - - - - - - - - 0 - 0 - - - - - 16777215 - 16 - - - - Qt::Horizontal - - - - - - - 01:01:01 - - - - - - - #btn_cam_r -{ -border-image:url(:img/camera.svg) -} -#btn_cam_r:hover -{ -border-image:url(:img/camera-hovered.svg) -} - - - - - - - true - - - false - - - false - - - - - - - #btn_vol_r -{ -border-image:url(:img/vol.svg) -} -#btn_vol_r:hover -{ -border-image:url(:img/vol-hovered.svg) -} - - - - - - - true - - - false - - - false - - - - - - - - 0 - 0 - - - - - 16777215 - 16 - - - - 1 - - - 100 - - - 100 - - - Qt::Horizontal - - - - - - - - - - - - - - + + + IpcViwerWidget + + + + 0 + 0 + 328 + 262 + + + + + 0 + 0 + + + + IpcViwerWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 0 + + + + 实时视频 + + + + + 220 + 20 + 111 + 221 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + + #up +{ +border-image:url(:img/up.png) +} +#up:hover +{ +border-image:url(:img/up-hovered.png) +} +#up:pressed +{ +border-image:url(:img/up-clicked.png) +} + + + + + + + + + + #left +{ +border-image:url(:img/left.png) +} +#left:hover +{ +border-image:url(:img/left-hovered.png) +} +#left:pressed +{ +border-image:url(:img/left-clicked.png) +} + + + + + + + + + + ptz + + + Qt::AlignCenter + + + + + + + #right +{ +border-image:url(:img/right.png) +} +#right:hover +{ +border-image:url(:img/right-hovered.png) +} +#right:pressed +{ +border-image:url(:img/right-clicked.png) +} + + + + + + + + + + + + #down +{ +border-image:url(:img/down.png) +} +#down:hover +{ +border-image:url(:img/down-hovered.png) +} +#down:pressed +{ +border-image:url(:img/down-clicked.png) +} + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + 调焦 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + 聚焦 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + + + + + + + + 光圈 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 预置位: + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + 测试预置点 + + + + + + + + + + + 0 + 0 + + + + 转到 + + + + + + + + + 20 + 160 + 252 + 40 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 6 + + + 0 + + + 6 + + + 0 + + + + + #btn_play +{ +border-image:url(:img/play.png) +} +#btn_play:hover +{ +border-image:url(:img/play-hovered.png) +} + + + + + + + true + + + false + + + false + + + + + + + Qt::Horizontal + + + + 52 + 20 + + + + + + + + #btn_cam +{ +border-image:url(:img/camera.svg) +} +#btn_cam:hover +{ +border-image:url(:img/camera-hovered.svg) +} + + + + + + + true + + + false + + + false + + + + + + + #btn_vol +{ +border-image:url(:img/vol.svg) +} +#btn_vol:hover +{ +border-image:url(:img/vol-hovered.svg) +} + + + + + + + true + + + false + + + false + + + + + + + + 0 + 0 + + + + + 16777215 + 16 + + + + 100 + + + 100 + + + Qt::Horizontal + + + + + + + + + 录像 + + + + + 210 + 0 + 110 + 241 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + Qt::Vertical + + + + 20 + 17 + + + + + + + + + + 选择日期 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 1 + + + + + + + + + + + + 开始时间 + + + + + + + + + + + + + + 结束时间 + + + + + + + + + + + + + + 查询 + + + + + + + Qt::Vertical + + + + 20 + 17 + + + + + + + + + + 0 + 90 + 338 + 36 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 6 + + + 0 + + + 6 + + + 0 + + + + + #btn_play_r +{ +border-image:url(:img/play.png) +} +#btn_play_r:hover +{ +border-image:url(:img/play-hovered.png) +} + + + + + + + true + + + false + + + false + + + + + + + + 0 + 0 + + + + + 16777215 + 16 + + + + Qt::Horizontal + + + + + + + 01:01:01 + + + + + + + #btn_cam_r +{ +border-image:url(:img/camera.svg) +} +#btn_cam_r:hover +{ +border-image:url(:img/camera-hovered.svg) +} + + + + + + + true + + + false + + + false + + + + + + + #btn_vol_r +{ +border-image:url(:img/vol.svg) +} +#btn_vol_r:hover +{ +border-image:url(:img/vol-hovered.svg) +} + + + + + + + true + + + false + + + false + + + + + + + + 0 + 0 + + + + + 16777215 + 16 + + + + 1 + + + 100 + + + 100 + + + Qt::Horizontal + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/IpcViewerWidget/main.cpp b/product/src/gui/plugin/IpcViewerWidget/main.cpp index c46c2039..37ff7037 100644 --- a/product/src/gui/plugin/IpcViewerWidget/main.cpp +++ b/product/src/gui/plugin/IpcViewerWidget/main.cpp @@ -1,40 +1,40 @@ -#include "ipcviewerwidget.h" -#include - -#include -#include - -#include -#include "net_msg_bus_api/MsgBusApi.h" - - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - - - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - - IpcViewerWidget w; - w.setNodeInfo(1,4); - w.setNodeName("kbd-rd-gyh"); - w.setAppName("hmi"); - - - //< 设置直播 -// w.setStreamInfo("digital.syx.1#BYQBH_dlq.Pos"); - - //< 设置录播 - w.setReplayInfo("digital.station1.G01_dlq.Pos",QDateTime(QDate(2020,4,17),QTime(16,04,00)).toMSecsSinceEpoch(),QDateTime(QDate(2020,4,17),QTime(16,05,00)).toMSecsSinceEpoch() ); - w.show(); - - - int result = a.exec(); - - //<释放消息总线 - kbd_net::releaseMsgBus(); - return result; -} +#include "ipcviewerwidget.h" +#include + +#include +#include + +#include +#include "net_msg_bus_api/MsgBusApi.h" + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + + IpcViewerWidget w; + w.setNodeInfo(1,4); + w.setNodeName("kbd-rd-gyh"); + w.setAppName("hmi"); + + + //< 设置直播 +// w.setStreamInfo("digital.syx.1#BYQBH_dlq.Pos"); + + //< 设置录播 + w.setReplayInfo("digital.station1.G01_dlq.Pos",QDateTime(QDate(2020,4,17),QTime(16,04,00)).toMSecsSinceEpoch(),QDateTime(QDate(2020,4,17),QTime(16,05,00)).toMSecsSinceEpoch() ); + w.show(); + + + int result = a.exec(); + + //<释放消息总线 + kbd_net::releaseMsgBus(); + return result; +} diff --git a/product/src/gui/plugin/IpcViewerWidget/rdbtabledef.h b/product/src/gui/plugin/IpcViewerWidget/rdbtabledef.h index 3b6c41a7..a46d02fd 100644 --- a/product/src/gui/plugin/IpcViewerWidget/rdbtabledef.h +++ b/product/src/gui/plugin/IpcViewerWidget/rdbtabledef.h @@ -1,314 +1,314 @@ -#ifndef RDBTABLEDEF_H -#define RDBTABLEDEF_H - -#include - -//模拟量全结构定义 -typedef struct SSAnaPointAll -{ - char tag_name[64] ; - char description[128] ; - char rtu_tag[64] ; - int dev_type ; - char device[64] ; - int seq_no ; - int location_id ; - int sub_system ; - int is_control ; - double gray ; - double contrast ; - int qcolor ; - double value ; - int status ; - int64 last_update_time ; - int64 last_change_time ; - int unit_id ; - char sound_name1[32] ; - char sound_name2[32] ; - char sound_name3[32] ; - int region_id ; - char opt_handover_group[64] ; - int is_limit ; - int point_type ; - int point_class ; - int point_property ; - int point_sort ; - char point_tp_name[64] ; - int is_sample ; - int is_statistics ; - int sample_period ; - double sample_deadband ; - char camera_tag[64] ; - char preset_id[64] ; - SAnaPointAll() - { - memset(tag_name, 0, 64); - memset(description, 0, 128); - memset(device, 0, 64); - memset(rtu_tag, 0, 64); - memset(sound_name1, 0, 32); - memset(sound_name2, 0, 32); - memset(sound_name3, 0, 32); - memset(opt_handover_group, 0, 64); - memset(point_tp_name, 0, 64); - memset(camera_tag, 0, 64); - memset(preset_id, 0, 64); - } -}SAnaPointAll; - - -//累计量全结构定义 -typedef struct SSAccPointAll -{ - char tag_name[64] ; - char description[128] ; - char device[64] ; - int seq_no ; - int location_id ; - int sub_system ; - char rtu_tag[64] ; - double gray ; - double contrast ; - int qcolor ; - int64 raw_value ; - double value ; - int status ; - int64 last_update_time ; - int64 last_change_time ; - int unit_id ; - char sound_name1[32] ; - char sound_name2[32] ; - char sound_name3[32] ; - int region_id ; - char opt_handover_group[64] ; - int is_limit ; - int point_type ; - int point_class ; - int point_property ; - int point_sort ; - int dev_type ; - char point_tp_name[64] ; - int is_sample ; - int is_statistics ; - int sample_period ; - double sample_deadband ; - char camera_tag[64] ; - char preset_id[64] ; - SAccPointAll() - { - value = 0.0 ; - status = 0; - memset(tag_name, 0, 64); - memset(description, 0, 128); - memset(device, 0, 64); - memset(rtu_tag, 0, 64); - memset(sound_name1, 0, 32); - memset(sound_name2, 0, 32); - memset(sound_name3, 0, 32); - memset(opt_handover_group, 0, 64); - memset(point_tp_name, 0, 64); - memset(camera_tag, 0, 64); - memset(preset_id, 0, 64); - } -}SAccPointAll; - - -//混合量全结构定义 -typedef struct SSMixPointAll -{ - char tag_name[64] ; - char description[128] ; - char device[64] ; - int seq_no ; - int location_id ; - int sub_system ; - char rtu_tag[64] ; - int is_control ; - char state_text_name[64] ; - double gray ; - double contrast ; - int qcolor ; - int value ; - int status ; - int64 last_update_time ; - int64 last_change_time ; - double raw_value ; - char method[64] ; - int alarm_priority ; - char pic_name[64] ; - char sound_name1[32] ; - char sound_name2[32] ; - char sound_name3[32] ; - int alarm_delay_time ; - int is_water_alm ; - int is_ack_on_rtn ; - int del_act_on_ack ; - int is_never_alm_on_rtn ; - int region_id ; - char opt_handover_group[64] ; - int is_summary ; - int summary_value ; - int summary_status ; - int point_type ; - int point_class ; - int point_property ; - int point_sort ; - int dev_type ; - char point_tp_name[64] ; - int is_sample ; - int is_statistics ; - int sample_period ; - char camera_tag[64] ; - char preset_id[64] ; - SMixPointAll() - { - memset(tag_name, 0, 64); - memset(description, 0, 128); - memset(device, 0, 64); - memset(rtu_tag, 0, 64); - memset(state_text_name, 0, 64); - memset(method, 0, 64); - memset(pic_name, 0, 64); - memset(sound_name1, 0, 32); - memset(sound_name2, 0, 32); - memset(sound_name3, 0, 32); - memset(opt_handover_group, 0, 64); - memset(point_tp_name, 0, 64); - memset(camera_tag, 0, 64); - memset(preset_id, 0, 64); - } -}SMixPointAll; - -typedef struct SSDigPointAll -{ - char tag_name[64] ; - char description[128] ; - char device[64] ; - int seq_no ; - int location_id ; - int sub_system ; - char rtu_tag[64] ; - int is_control ; - char state_text_name[64] ; - int value_num ; - double gray ; - double contrast ; - int qcolor ; - int value ; - int status ; - int64 last_update_time ; - int value1 ; - int status1 ; - int64 last_change_time1 ; - int value2 ; - int status2 ; - int64 last_change_time2 ; - int value3 ; - int status3 ; - int64 last_change_time3 ; - int value4 ; - int status4 ; - int64 last_change_time4 ; - int value5 ; - int status5 ; - int64 last_change_time5 ; - int alarm_priority ; - char pic_name[64] ; - char sound_name1[32] ; - char sound_name2[32] ; - char sound_name3[32] ; - int alarm_delay_time ; - int input_delay_time ; - int is_water_alm ; - int is_ack_on_rtn ; - int del_act_on_ack ; - int is_never_alm_on_rtn ; - int region_id ; - char opt_handover_group[64] ; - int is_summary ; - int summary_value ; - int summary_status ; - int point_type ; - int point_class ; - int point_property ; - int point_sort ; - int dev_type ; - char point_tp_name[64] ; - int is_sample ; - int is_statistics ; - int sample_period ; - int is_alarm_freq ; - int alarm_freq ; - char alarm_freq_desc[64] ; - int is_alarm_time ; - int alarm_time ; - char alarm_time_desc[64] ; - int alarm_freq_range ; - char infer_name[64] ; - char camera_tag[64] ; - char preset_id[64] ; - SDigPointAll() - { - memset(tag_name, 0, 64); - memset(description, 0, 128); - memset(device, 0, 64); - memset(rtu_tag, 0, 64); - memset(state_text_name, 0, 64); - memset(sound_name1, 0, 32); - memset(sound_name2, 0, 32); - memset(sound_name3, 0, 32); - memset(pic_name, 0, 64); - memset(opt_handover_group, 0, 64); - memset(point_tp_name, 0, 64); - memset(alarm_freq_desc, 0, 64); - memset(infer_name, 0, 64); - memset(camera_tag, 0, 64); - memset(preset_id, 0, 64); - } -}SDigPointAll; - - -typedef struct SSCamInfo -{ - char tag_name[64] ; - char camera_name[64] ; - int camera_tpye; - int location_id; - char cameara_ip[32] ; - int camera_port ; - int camera_no ; - char description[128] ; - char profile_token[128] ; - char username[128] ; - char password[128] ; - SCamInfo() - { - memset(tag_name, 0, 64); - memset(description, 0, 128); - memset(cameara_ip, 0, 32); - memset(camera_name, 0, 64); - memset(profile_token, 0, 128); - memset(username, 0, 128); - memset(password, 0, 128); - } -}SCamInfo; - -typedef struct SSPreSetInfo -{ - int location_id; - char description[100]; - int orientation_no ; - char tag_name[64] ; - char cameara_tag_name[64]; - char preset_token[128] ; - SCamInfo() - { - memset(tag_name, 0, 64); - memset(description, 0, 128); - memset(preset_token, 0, 128); - memset(cameara_tag_name, 0, 64); - } -}SSPreSetInfo; - - -#endif // RDBTABLEDEF_H +#ifndef RDBTABLEDEF_H +#define RDBTABLEDEF_H + +#include + +//模拟量全结构定义 +typedef struct SSAnaPointAll +{ + char tag_name[64] ; + char description[128] ; + char rtu_tag[64] ; + int dev_type ; + char device[64] ; + int seq_no ; + int location_id ; + int sub_system ; + int is_control ; + double gray ; + double contrast ; + int qcolor ; + double value ; + int status ; + int64 last_update_time ; + int64 last_change_time ; + int unit_id ; + char sound_name1[32] ; + char sound_name2[32] ; + char sound_name3[32] ; + int region_id ; + char opt_handover_group[64] ; + int is_limit ; + int point_type ; + int point_class ; + int point_property ; + int point_sort ; + char point_tp_name[64] ; + int is_sample ; + int is_statistics ; + int sample_period ; + double sample_deadband ; + char camera_tag[64] ; + char preset_id[64] ; + SAnaPointAll() + { + memset(tag_name, 0, 64); + memset(description, 0, 128); + memset(device, 0, 64); + memset(rtu_tag, 0, 64); + memset(sound_name1, 0, 32); + memset(sound_name2, 0, 32); + memset(sound_name3, 0, 32); + memset(opt_handover_group, 0, 64); + memset(point_tp_name, 0, 64); + memset(camera_tag, 0, 64); + memset(preset_id, 0, 64); + } +}SAnaPointAll; + + +//累计量全结构定义 +typedef struct SSAccPointAll +{ + char tag_name[64] ; + char description[128] ; + char device[64] ; + int seq_no ; + int location_id ; + int sub_system ; + char rtu_tag[64] ; + double gray ; + double contrast ; + int qcolor ; + int64 raw_value ; + double value ; + int status ; + int64 last_update_time ; + int64 last_change_time ; + int unit_id ; + char sound_name1[32] ; + char sound_name2[32] ; + char sound_name3[32] ; + int region_id ; + char opt_handover_group[64] ; + int is_limit ; + int point_type ; + int point_class ; + int point_property ; + int point_sort ; + int dev_type ; + char point_tp_name[64] ; + int is_sample ; + int is_statistics ; + int sample_period ; + double sample_deadband ; + char camera_tag[64] ; + char preset_id[64] ; + SAccPointAll() + { + value = 0.0 ; + status = 0; + memset(tag_name, 0, 64); + memset(description, 0, 128); + memset(device, 0, 64); + memset(rtu_tag, 0, 64); + memset(sound_name1, 0, 32); + memset(sound_name2, 0, 32); + memset(sound_name3, 0, 32); + memset(opt_handover_group, 0, 64); + memset(point_tp_name, 0, 64); + memset(camera_tag, 0, 64); + memset(preset_id, 0, 64); + } +}SAccPointAll; + + +//混合量全结构定义 +typedef struct SSMixPointAll +{ + char tag_name[64] ; + char description[128] ; + char device[64] ; + int seq_no ; + int location_id ; + int sub_system ; + char rtu_tag[64] ; + int is_control ; + char state_text_name[64] ; + double gray ; + double contrast ; + int qcolor ; + int value ; + int status ; + int64 last_update_time ; + int64 last_change_time ; + double raw_value ; + char method[64] ; + int alarm_priority ; + char pic_name[64] ; + char sound_name1[32] ; + char sound_name2[32] ; + char sound_name3[32] ; + int alarm_delay_time ; + int is_water_alm ; + int is_ack_on_rtn ; + int del_act_on_ack ; + int is_never_alm_on_rtn ; + int region_id ; + char opt_handover_group[64] ; + int is_summary ; + int summary_value ; + int summary_status ; + int point_type ; + int point_class ; + int point_property ; + int point_sort ; + int dev_type ; + char point_tp_name[64] ; + int is_sample ; + int is_statistics ; + int sample_period ; + char camera_tag[64] ; + char preset_id[64] ; + SMixPointAll() + { + memset(tag_name, 0, 64); + memset(description, 0, 128); + memset(device, 0, 64); + memset(rtu_tag, 0, 64); + memset(state_text_name, 0, 64); + memset(method, 0, 64); + memset(pic_name, 0, 64); + memset(sound_name1, 0, 32); + memset(sound_name2, 0, 32); + memset(sound_name3, 0, 32); + memset(opt_handover_group, 0, 64); + memset(point_tp_name, 0, 64); + memset(camera_tag, 0, 64); + memset(preset_id, 0, 64); + } +}SMixPointAll; + +typedef struct SSDigPointAll +{ + char tag_name[64] ; + char description[128] ; + char device[64] ; + int seq_no ; + int location_id ; + int sub_system ; + char rtu_tag[64] ; + int is_control ; + char state_text_name[64] ; + int value_num ; + double gray ; + double contrast ; + int qcolor ; + int value ; + int status ; + int64 last_update_time ; + int value1 ; + int status1 ; + int64 last_change_time1 ; + int value2 ; + int status2 ; + int64 last_change_time2 ; + int value3 ; + int status3 ; + int64 last_change_time3 ; + int value4 ; + int status4 ; + int64 last_change_time4 ; + int value5 ; + int status5 ; + int64 last_change_time5 ; + int alarm_priority ; + char pic_name[64] ; + char sound_name1[32] ; + char sound_name2[32] ; + char sound_name3[32] ; + int alarm_delay_time ; + int input_delay_time ; + int is_water_alm ; + int is_ack_on_rtn ; + int del_act_on_ack ; + int is_never_alm_on_rtn ; + int region_id ; + char opt_handover_group[64] ; + int is_summary ; + int summary_value ; + int summary_status ; + int point_type ; + int point_class ; + int point_property ; + int point_sort ; + int dev_type ; + char point_tp_name[64] ; + int is_sample ; + int is_statistics ; + int sample_period ; + int is_alarm_freq ; + int alarm_freq ; + char alarm_freq_desc[64] ; + int is_alarm_time ; + int alarm_time ; + char alarm_time_desc[64] ; + int alarm_freq_range ; + char infer_name[64] ; + char camera_tag[64] ; + char preset_id[64] ; + SDigPointAll() + { + memset(tag_name, 0, 64); + memset(description, 0, 128); + memset(device, 0, 64); + memset(rtu_tag, 0, 64); + memset(state_text_name, 0, 64); + memset(sound_name1, 0, 32); + memset(sound_name2, 0, 32); + memset(sound_name3, 0, 32); + memset(pic_name, 0, 64); + memset(opt_handover_group, 0, 64); + memset(point_tp_name, 0, 64); + memset(alarm_freq_desc, 0, 64); + memset(infer_name, 0, 64); + memset(camera_tag, 0, 64); + memset(preset_id, 0, 64); + } +}SDigPointAll; + + +typedef struct SSCamInfo +{ + char tag_name[64] ; + char camera_name[64] ; + int camera_tpye; + int location_id; + char cameara_ip[32] ; + int camera_port ; + int camera_no ; + char description[128] ; + char profile_token[128] ; + char username[128] ; + char password[128] ; + SCamInfo() + { + memset(tag_name, 0, 64); + memset(description, 0, 128); + memset(cameara_ip, 0, 32); + memset(camera_name, 0, 64); + memset(profile_token, 0, 128); + memset(username, 0, 128); + memset(password, 0, 128); + } +}SCamInfo; + +typedef struct SSPreSetInfo +{ + int location_id; + char description[100]; + int orientation_no ; + char tag_name[64] ; + char cameara_tag_name[64]; + char preset_token[128] ; + SCamInfo() + { + memset(tag_name, 0, 64); + memset(description, 0, 128); + memset(preset_token, 0, 128); + memset(cameara_tag_name, 0, 64); + } +}SSPreSetInfo; + + +#endif // RDBTABLEDEF_H diff --git a/product/src/gui/plugin/IpcViewerWidget/res.qrc b/product/src/gui/plugin/IpcViewerWidget/res.qrc index 8a66d9d0..5cd40422 100644 --- a/product/src/gui/plugin/IpcViewerWidget/res.qrc +++ b/product/src/gui/plugin/IpcViewerWidget/res.qrc @@ -1,26 +1,26 @@ - - - img/down.png - img/down-clicked.png - img/down-hovered.png - img/left.png - img/left-clicked.png - img/left-hovered.png - img/right.png - img/right-clicked.png - img/right-hovered.png - img/up.png - img/up-clicked.png - img/up-hovered.png - img/play.png - img/camera.svg - img/vol.svg - img/vol-hovered.svg - img/camera-hovered.svg - img/play-hovered.png - img/pause.png - img/vol-mute.svg - img/fullscreen.png - img/fullscreen_hovered.png - - + + + img/down.png + img/down-clicked.png + img/down-hovered.png + img/left.png + img/left-clicked.png + img/left-hovered.png + img/right.png + img/right-clicked.png + img/right-hovered.png + img/up.png + img/up-clicked.png + img/up-hovered.png + img/play.png + img/camera.svg + img/vol.svg + img/vol-hovered.svg + img/camera-hovered.svg + img/play-hovered.png + img/pause.png + img/vol-mute.svg + img/fullscreen.png + img/fullscreen_hovered.png + + diff --git a/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadMng.cpp b/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadMng.cpp index 1efd8a24..dcb93d9c 100644 --- a/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadMng.cpp +++ b/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadMng.cpp @@ -1,81 +1,81 @@ -#include "CCamInfoLoadMng.h" -#include -#include -#include -#include -CCamInfoLoadMng::CCamInfoLoadMng(QObject *parent) : QObject(parent),m_resultCnt(0) -{ - -} - -CCamInfoLoadMng::~CCamInfoLoadMng() -{ - for(int i = 0; i < threads.size();i++) - { - if(threads.at(i)) - { - threads.at(i)->quit(); - threads.at(i)->wait(); - delete threads.at(i); - } - } -} - -void CCamInfoLoadMng::setCamInfoVec(std::vector *pcamInfoVec) -{ - m_pCamInfoVec = pcamInfoVec; -} - -void CCamInfoLoadMng::setTagInfo(QList *pAppIdList, QList *pLocationIdList, QStringList *pPointTagList) -{ - m_pPointTagList = pPointTagList; - m_pAppIdList = pAppIdList; - m_pLocationIdList = pLocationIdList; -} - -void CCamInfoLoadMng::handleResults(int result) -{ -// qDebug() << QString("from result [%1]").arg(result) << m_timer.elapsed() /1000.0 << "s"; - LOGDEBUG( QString("thread %1 loaded at %2 s").arg(QString::number(result)).arg(QString::number( m_timer.elapsed() /1000.0)).toStdString().c_str() ); - m_resultCnt++; - if(m_resultCnt == threads.size()) - { - emit resultReady(); - } -} - -bool CCamInfoLoadMng::allocateThread() -{ - // 条件检查 - if(!m_pAppIdList || !m_pPointTagList || !m_pCamInfoVec || !m_pLocationIdList) - return false; - - if(m_pAppIdList->size() != m_pPointTagList->size() || m_pAppIdList->size() != m_pLocationIdList->size() ) - return false; - - auto it = m_pCamInfoVec->begin(); - for(int i = 0; i < m_pAppIdList->size();i++) - { - QThread * workerThread = new QThread; - if(workerThread){ - threads.push_back(workerThread); - } - else{ - return false; - } - CCamInfoLoadWorker *worker = new CCamInfoLoadWorker(&*it,m_pAppIdList->at(i),m_pLocationIdList->at(i),m_pPointTagList->at(i),i); - if(worker) - { - worker->moveToThread(workerThread); - connect(workerThread, &QThread::finished, worker, &QObject::deleteLater); - connect(this, &CCamInfoLoadMng::operate, worker, &CCamInfoLoadWorker::doWork); - connect(worker, &CCamInfoLoadWorker::resultReady, this, &CCamInfoLoadMng::handleResults); - workerThread->start(); - it++; - }else - { - return false; - } - } - return true; -} +#include "CCamInfoLoadMng.h" +#include +#include +#include +#include +CCamInfoLoadMng::CCamInfoLoadMng(QObject *parent) : QObject(parent),m_resultCnt(0) +{ + +} + +CCamInfoLoadMng::~CCamInfoLoadMng() +{ + for(int i = 0; i < threads.size();i++) + { + if(threads.at(i)) + { + threads.at(i)->quit(); + threads.at(i)->wait(); + delete threads.at(i); + } + } +} + +void CCamInfoLoadMng::setCamInfoVec(std::vector *pcamInfoVec) +{ + m_pCamInfoVec = pcamInfoVec; +} + +void CCamInfoLoadMng::setTagInfo(QList *pAppIdList, QList *pLocationIdList, QStringList *pPointTagList) +{ + m_pPointTagList = pPointTagList; + m_pAppIdList = pAppIdList; + m_pLocationIdList = pLocationIdList; +} + +void CCamInfoLoadMng::handleResults(int result) +{ +// qDebug() << QString("from result [%1]").arg(result) << m_timer.elapsed() /1000.0 << "s"; + LOGDEBUG( QString("thread %1 loaded at %2 s").arg(QString::number(result)).arg(QString::number( m_timer.elapsed() /1000.0)).toStdString().c_str() ); + m_resultCnt++; + if(m_resultCnt == threads.size()) + { + emit resultReady(); + } +} + +bool CCamInfoLoadMng::allocateThread() +{ + // 条件检查 + if(!m_pAppIdList || !m_pPointTagList || !m_pCamInfoVec || !m_pLocationIdList) + return false; + + if(m_pAppIdList->size() != m_pPointTagList->size() || m_pAppIdList->size() != m_pLocationIdList->size() ) + return false; + + auto it = m_pCamInfoVec->begin(); + for(int i = 0; i < m_pAppIdList->size();i++) + { + QThread * workerThread = new QThread; + if(workerThread){ + threads.push_back(workerThread); + } + else{ + return false; + } + CCamInfoLoadWorker *worker = new CCamInfoLoadWorker(&*it,m_pAppIdList->at(i),m_pLocationIdList->at(i),m_pPointTagList->at(i),i); + if(worker) + { + worker->moveToThread(workerThread); + connect(workerThread, &QThread::finished, worker, &QObject::deleteLater); + connect(this, &CCamInfoLoadMng::operate, worker, &CCamInfoLoadWorker::doWork); + connect(worker, &CCamInfoLoadWorker::resultReady, this, &CCamInfoLoadMng::handleResults); + workerThread->start(); + it++; + }else + { + return false; + } + } + return true; +} diff --git a/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadMng.h b/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadMng.h index a9ead638..e67b7c1e 100644 --- a/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadMng.h +++ b/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadMng.h @@ -1,42 +1,42 @@ -#ifndef CCAMINFOLOADMNG_H -#define CCAMINFOLOADMNG_H - -#include -#include <../IpcViewerWidget/ccaminfo.h> -#include - - -class CCamInfo; -class CCamInfoLoadMng : public QObject -{ - Q_OBJECT -public: - explicit CCamInfoLoadMng(QObject *parent = nullptr); - ~CCamInfoLoadMng(); - - void setCamInfoVec(std::vector* pcamInfoVec); - void setTagInfo(QList *pAppIdList, QList *pLocationIdList,QStringList *pPointTagList); - QElapsedTimer m_timer; - - -signals: - void resultReady(); - void operate(); - -public slots: - bool allocateThread(); - void handleResults(int result); - - -private: - std::vector *m_pCamInfoVec; - QStringList *m_pPointTagList; - QList *m_pAppIdList; - QList *m_pLocationIdList; - int m_resultCnt; - - QList threads; - -}; - -#endif // CCAMINFOLOADMNG_H +#ifndef CCAMINFOLOADMNG_H +#define CCAMINFOLOADMNG_H + +#include +#include <../IpcViewerWidget/ccaminfo.h> +#include + + +class CCamInfo; +class CCamInfoLoadMng : public QObject +{ + Q_OBJECT +public: + explicit CCamInfoLoadMng(QObject *parent = nullptr); + ~CCamInfoLoadMng(); + + void setCamInfoVec(std::vector* pcamInfoVec); + void setTagInfo(QList *pAppIdList, QList *pLocationIdList,QStringList *pPointTagList); + QElapsedTimer m_timer; + + +signals: + void resultReady(); + void operate(); + +public slots: + bool allocateThread(); + void handleResults(int result); + + +private: + std::vector *m_pCamInfoVec; + QStringList *m_pPointTagList; + QList *m_pAppIdList; + QList *m_pLocationIdList; + int m_resultCnt; + + QList threads; + +}; + +#endif // CCAMINFOLOADMNG_H diff --git a/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadWorker.cpp b/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadWorker.cpp index 4b440c4a..ece1af91 100644 --- a/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadWorker.cpp +++ b/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadWorker.cpp @@ -1,29 +1,29 @@ -#include "CCamInfoLoadWorker.h" -#include -#include -#include <../IpcViewerWidget/crdbaccessutilty.h> -#include - -CCamInfoLoadWorker::CCamInfoLoadWorker(CCamInfo* camInfo, int appid, int locationid, const QString & pointTag, int jobid) : - m_camInfo(camInfo), - m_appId(appid), - m_locationId(locationid), - m_pointTag(pointTag), - m_jobId(jobid) -{ - -} - -void CCamInfoLoadWorker::doWork() -{ - CRdbAccessUtilty rdbutilty(m_locationId,m_appId); - if(!rdbutilty.getCamInfo(m_pointTag.toStdString(),*m_camInfo)) - { - LOGERROR(QString("标签%1,加载失败,locationid is %2,appId is %3").arg(m_pointTag).arg(QString::number(m_locationId)).arg(QString::number(m_appId)).toStdString().c_str() ); - emit resultReady(m_jobId); - return; - } - m_camInfo->getOnvifArgs(); - - emit resultReady(m_jobId); -} +#include "CCamInfoLoadWorker.h" +#include +#include +#include <../IpcViewerWidget/crdbaccessutilty.h> +#include + +CCamInfoLoadWorker::CCamInfoLoadWorker(CCamInfo* camInfo, int appid, int locationid, const QString & pointTag, int jobid) : + m_camInfo(camInfo), + m_appId(appid), + m_locationId(locationid), + m_pointTag(pointTag), + m_jobId(jobid) +{ + +} + +void CCamInfoLoadWorker::doWork() +{ + CRdbAccessUtilty rdbutilty(m_locationId,m_appId); + if(!rdbutilty.getCamInfo(m_pointTag.toStdString(),*m_camInfo)) + { + LOGERROR(QString("标签%1,加载失败,locationid is %2,appId is %3").arg(m_pointTag).arg(QString::number(m_locationId)).arg(QString::number(m_appId)).toStdString().c_str() ); + emit resultReady(m_jobId); + return; + } + m_camInfo->getOnvifArgs(); + + emit resultReady(m_jobId); +} diff --git a/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadWorker.h b/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadWorker.h index 16f8ad20..a5ed46d1 100644 --- a/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadWorker.h +++ b/product/src/gui/plugin/IpcWallWidget/CCamInfoLoadWorker.h @@ -1,27 +1,27 @@ -#ifndef CCAMINFOLOADWORKER_H -#define CCAMINFOLOADWORKER_H - -#include -#include <../IpcViewerWidget/ccaminfo.h> - - -class CCamInfoLoadWorker : public QObject -{ - Q_OBJECT -public: - explicit CCamInfoLoadWorker(CCamInfo* camInfo,int appid,int locationid,const QString & pointTag,int jobid); -signals: - void resultReady(int jobId); - -public slots: - void doWork(); - -private: - CCamInfo* m_camInfo; - int m_appId; - int m_locationId; - QString m_pointTag; - int m_jobId; -}; - -#endif // CCAMINFOLOADWORKER_H +#ifndef CCAMINFOLOADWORKER_H +#define CCAMINFOLOADWORKER_H + +#include +#include <../IpcViewerWidget/ccaminfo.h> + + +class CCamInfoLoadWorker : public QObject +{ + Q_OBJECT +public: + explicit CCamInfoLoadWorker(CCamInfo* camInfo,int appid,int locationid,const QString & pointTag,int jobid); +signals: + void resultReady(int jobId); + +public slots: + void doWork(); + +private: + CCamInfo* m_camInfo; + int m_appId; + int m_locationId; + QString m_pointTag; + int m_jobId; +}; + +#endif // CCAMINFOLOADWORKER_H diff --git a/product/src/gui/plugin/IpcWallWidget/IpcWallWidget.pro b/product/src/gui/plugin/IpcWallWidget/IpcWallWidget.pro index 2031e88e..5e554c77 100644 --- a/product/src/gui/plugin/IpcWallWidget/IpcWallWidget.pro +++ b/product/src/gui/plugin/IpcWallWidget/IpcWallWidget.pro @@ -1,110 +1,110 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-02-21T10:03:40 -# -#------------------------------------------------- - -QT += core gui -CONFIG += no_batch - - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = IpcWallWidget -TEMPLATE = lib -#TEMPLATE = app -CONFIG += plugin - - - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - - -#DEFINES += IPCVIEWERWIDGET_LIBRARY - - -SOURCES += main.cpp VideoWall.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - $$PWD/../IpcPlusWidget/VoiceSlider.cpp \ - $$PWD/../IpcViewerWidget/ccaminfo.cpp \ - $$PWD/../IpcViewerWidget/crdbaccessutilty.cpp \ - ipcWallPluginWidget.cpp \ - CCamInfoLoadWorker.cpp \ - CCamInfoLoadMng.cpp - -HEADERS += VideoWall.h \ - $$PWD/../IpcPlusWidget/VoiceSlider.h \ - $$PWD/../IpcViewerWidget/ccaminfo.h \ - $$PWD/../IpcViewerWidget/crdbaccessutilty.h \ - CCamInfoLoadMng.h \ - ipcWallPluginWidge.h \ - CCamInfoLoadWorker.h - -FORMS += $$PWD/../IpcPlusWidget/VoiceSlider.ui - -TRANSLATIONS += $$PWD/en.ts - -INCLUDEPATH += ../IpcViewerWidget - -include($$PWD/../../../idl_files/idl_files.pri) - -LIB += -lboost_system \ - -lboost_filesystem \ - -lboost_thread \ - -lnet_msg_bus_api \ - - -LIBS += -llog4cplus -lpub_logger_api -lrdb_net_api -LIBS += -lnet_msg_bus_api -lpub_utility_api -LIBS += -lprotobuf - -win32-msvc* { - -CONFIG(debug, debug|release) { - LIBS += -lQtAVd1 -lQtAVWidgetsd1 -} -CONFIG(release, debug|release) { - LIBS += -lQtAV1 -lQtAVWidgets1 -} -} - -linux-g++*{ - LIBS += -lQtAV -lQtAVWidgets -} - -LIBS += -lOnvifLib - - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -#必须在common.pri之后包含 -#------------------------------------------------------------------- -QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri -exists($$QTAV_PRI) { - include($$QTAV_PRI) -}else { - error("FATAL error: can not find qtav.pri") -} - - -QTAVCFGPARSER_PRI=$$SRC_ROOT_PATH/tools/playerCfgParser/qtavconfigparser.pri -exists($$QTAVCFGPARSER_PRI) { - include($$QTAVCFGPARSER_PRI) -}else { - error("FATAL error: can not find qtavcfgparser.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2020-02-21T10:03:40 +# +#------------------------------------------------- + +QT += core gui +CONFIG += no_batch + + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = IpcWallWidget +TEMPLATE = lib +#TEMPLATE = app +CONFIG += plugin + + + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + + +#DEFINES += IPCVIEWERWIDGET_LIBRARY + + +SOURCES += main.cpp VideoWall.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + $$PWD/../IpcPlusWidget/VoiceSlider.cpp \ + $$PWD/../IpcViewerWidget/ccaminfo.cpp \ + $$PWD/../IpcViewerWidget/crdbaccessutilty.cpp \ + ipcWallPluginWidget.cpp \ + CCamInfoLoadWorker.cpp \ + CCamInfoLoadMng.cpp + +HEADERS += VideoWall.h \ + $$PWD/../IpcPlusWidget/VoiceSlider.h \ + $$PWD/../IpcViewerWidget/ccaminfo.h \ + $$PWD/../IpcViewerWidget/crdbaccessutilty.h \ + CCamInfoLoadMng.h \ + ipcWallPluginWidge.h \ + CCamInfoLoadWorker.h + +FORMS += $$PWD/../IpcPlusWidget/VoiceSlider.ui + +TRANSLATIONS += $$PWD/en.ts + +INCLUDEPATH += ../IpcViewerWidget + +include($$PWD/../../../idl_files/idl_files.pri) + +LIB += -lboost_system \ + -lboost_filesystem \ + -lboost_thread \ + -lnet_msg_bus_api \ + + +LIBS += -llog4cplus -lpub_logger_api -lrdb_net_api +LIBS += -lnet_msg_bus_api -lpub_utility_api +LIBS += -lprotobuf + +win32-msvc* { + +CONFIG(debug, debug|release) { + LIBS += -lQtAVd1 -lQtAVWidgetsd1 +} +CONFIG(release, debug|release) { + LIBS += -lQtAV1 -lQtAVWidgets1 +} +} + +linux-g++*{ + LIBS += -lQtAV -lQtAVWidgets +} + +LIBS += -lOnvifLib + + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +#必须在common.pri之后包含 +#------------------------------------------------------------------- +QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri +exists($$QTAV_PRI) { + include($$QTAV_PRI) +}else { + error("FATAL error: can not find qtav.pri") +} + + +QTAVCFGPARSER_PRI=$$SRC_ROOT_PATH/tools/playerCfgParser/qtavconfigparser.pri +exists($$QTAVCFGPARSER_PRI) { + include($$QTAVCFGPARSER_PRI) +}else { + error("FATAL error: can not find qtavcfgparser.pri") +} diff --git a/product/src/gui/plugin/IpcWallWidget/VideoWall.cpp b/product/src/gui/plugin/IpcWallWidget/VideoWall.cpp index 0ee7719d..11e0aa94 100644 --- a/product/src/gui/plugin/IpcWallWidget/VideoWall.cpp +++ b/product/src/gui/plugin/IpcWallWidget/VideoWall.cpp @@ -1,1195 +1,1195 @@ -/****************************************************************************** - VideoWall: this file is part of QtAV examples - Copyright (C) 2012-2016 Wang Bin - -* This file is part of QtAV - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -******************************************************************************/ - -#include "VideoWall.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include <../IpcPlusWidget/VoiceSlider.h> -#include -#include -#include -#include -#include -#include "pub_utility_api/FileStyle.h" -#include "operate_server_api/JsonOptCommand.h" -#include "common/Common.h" -#include "common/MessageChannel.h" -#include - - - -using namespace QtAV; -using namespace kbd_net; - -const int kSyncInterval = 10000; - -#define PTZ_UI_TEST true -#define VIDEO_SERVER_RTU_NAME "##$$video_server$$##" - -#define PTZ_UP 0 -#define PTZ_DOWN 1 -#define PTZ_LEFT 2 -#define PTZ_RIGHT 3 -#define PTZ_ZOOMIN 4 -#define PTZ_ZOOMOUT 5 - -#define CCTV_ONVIF_MOVE "58" -#define CCTV_ONVIF_STOPMOVE "59" -#define CCTV_ONVIF_GOTOPRESET "57" - -#define KEY_CMD_TYPE "cmd_type" -#define CAMERA_TAG "camera_tag" -#define PTZ_COMMOND "commond" -#define PTZ_SPEED "speed" -#define PRESET_TAG "preset_tag" - - - -VideoWall::VideoWall(QWidget *parent, bool editMode) : - QWidget(parent),m_editMode(editMode),m_rows(2),m_columns(2),view(0),m_ptzui(0),menu(0),curWid(0),curNo(-1),m_loadMng(this) -{ - QtAV::Widgets::registerRenderers(); - QApplication::setAttribute(Qt::AA_UseOpenGLES); - QtAV::setLogLevel(QtAV::LogOff); - - clock = new AVClock(this); - clock->setClockType(AVClock::ExternalClock); - view = new QWidget(this); - view->installEventFilter(this); - view->setStyleSheet(" background-color: black;"); - m_ptzui = new QWidget(this); - QVBoxLayout* layout = new QVBoxLayout; - layout->addWidget(view); - layout->addWidget(m_ptzui); - layout->setSizeConstraint(QLayout::SetMaximumSize); - layout->setSpacing(0); - layout->setMargin(0); - layout->setContentsMargins(0, 0, 0, 0); - this->setLayout(layout); - intiPtzUi(); - connect(&m_loadMng,&CCamInfoLoadMng::resultReady,this,&VideoWall::handleLoadResults); - connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&VideoWall::slotVoiceClose); - connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&VideoWall::slotVoiceOpen); - connect(m_voiceOpen,&QPushButton::clicked,this,&VideoWall::voiceSliderShow); - connect(m_voiceClose,&QPushButton::clicked,this,&VideoWall::voiceSliderShow); - connect(m_play, &QPushButton::clicked,this,&VideoWall::playCtl); - connect(m_cap,&QPushButton::clicked,this,&VideoWall::capture); - - connect(m_pause,&QPushButton::clicked,this,&VideoWall::pauseCtl); - connect(m_left,&QPushButton::pressed,this,&VideoWall::leftPressed); - connect(m_left,&QPushButton::released,this,&VideoWall::released); - - connect(m_right,&QPushButton::pressed,this,&VideoWall::rightPressed); - connect(m_right,&QPushButton::released,this,&VideoWall::released); - - connect(m_up,&QPushButton::pressed,this,&VideoWall::upPressed); - connect(m_up,&QPushButton::released,this,&VideoWall::released); - - connect(m_down,&QPushButton::pressed,this,&VideoWall::downPressed); - connect(m_down,&QPushButton::released,this,&VideoWall::released); - - connect(m_tretch,&QPushButton::pressed,this,&VideoWall::tretchPressed); - connect(m_tretch,&QPushButton::released,this,&VideoWall::released); - - connect(m_draw,&QPushButton::pressed,this,&VideoWall::drawPressed); - connect(m_draw,&QPushButton::released,this,&VideoWall::released); - - connect(m_allot,&QPushButton::clicked,this,&VideoWall::gotoPreset); - - connect(&m_playersCheckTimer,&QTimer::timeout,this,&VideoWall::checkPlayerStatus); -} - -VideoWall::~VideoWall() -{ - if (menu) { - delete menu; - menu = 0; - } - if (!players.isEmpty()) { - foreach (AVPlayer *player, players) { - player->stop(); - VideoRenderer* renderer = player->renderer(); - if (renderer->widget()) { - renderer->widget()->close(); //TODO: rename - if (!renderer->widget()->testAttribute(Qt::WA_DeleteOnClose) && !renderer->widget()->parent()) - delete renderer; - delete player; - } - } - players.clear(); - } - delete view; -} - - -void VideoWall::setRows(int n) -{ - m_rows = n; -} - -void VideoWall::setCols(int n) -{ - m_columns = n; -} - -void VideoWall::setCapturePath(const QString &path) -{ - if(m_editMode) - return; - if(players.isEmpty()) - return; - if(path.isEmpty()) - return; - for(int i = 0;i < players.size();i++) - { - players[i]->videoCapture()->setCaptureName("cap"); - players[i]->videoCapture()->setCaptureDir(path); - players[i]->videoCapture()->setQuality(100); - players[i]->videoCapture()->setSaveFormat("jpg"); - } -} - -void VideoWall::setPtzUiHidden(bool isPtzHidden) -{ - this->m_ptzui->setHidden(isPtzHidden); -} - - -void VideoWall::showUi() -{ - if(m_editMode) - return; - if( m_rows * m_columns < m_pointTagList.size()) - { - m_columns = (int )sqrt((double) m_pointTagList.size() ) + 1; - m_rows = m_columns; - } - - if (!players.isEmpty()) { - foreach (AVPlayer *player, players) { - player->stop(); - VideoRenderer* renderer = player->renderer(); - if (renderer->widget()) { - renderer->widget()->close(); - if (!renderer->widget()->testAttribute(Qt::WA_DeleteOnClose) && !renderer->widget()->parent()) - delete renderer; - delete player; - } - } - players.clear(); - } - qDebug("show wall: %d x %d", m_rows, m_columns); - - int w = view ? view->frameGeometry().width()/m_columns : qApp->desktop()->width()/m_columns; - int h = view ? view->frameGeometry().height()/m_rows : qApp->desktop()->height()/m_rows; - if (view) { - QGridLayout *layout = new QGridLayout; - layout->setSizeConstraint(QLayout::SetMaximumSize); - layout->setSpacing(0); - layout->setMargin(0); - layout->setContentsMargins(0, 0, 0, 0); - view->setLayout(layout); - } - - VideoRendererId v = VideoRendererId_OpenGLWidget; - for (int i = 0; i < m_rows; ++i) { - for (int j = 0; j < m_columns; ++j) { - VideoRenderer* renderer = VideoRenderer::create(v); - renderer->widget()->setWindowFlags(renderer->widget()->windowFlags()| Qt::FramelessWindowHint); - renderer->widget()->setAttribute(Qt::WA_DeleteOnClose); - renderer->widget()->resize(w, h); - renderer->widget()->move(j*w, i*h); - AVPlayer *player = new AVPlayer; - if(m_playerCfgParser.isValid()){ - m_playerCfgParser.applyToPlayer(*player); - } - player->setRenderer(renderer); -// connect(player, SIGNAL(started()), SLOT(changeClockType())); - QWidget* widget = new QWidget; - QGridLayout* layout = new QGridLayout; - widget->setLayout(layout); - layout->setSpacing(0); - layout->setMargin(0); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(renderer->widget()); - players.append(player); - if (view){ - ((QGridLayout*)view->layout())->addWidget(widget, i, j); - m_widgetMap.insert(renderer->widget(),players.size()-1); - } - } - } - setCapturePath(); -} - -void VideoWall::play(const QString &file) -{ - if (players.isEmpty()) - return; - clock->reset(); - clock->start(); - foreach (AVPlayer *player, players) { - player->setBufferMode(QtAV::BufferTime); - player->setBufferValue(50); - player->audio()->setBufferSamples(64); - - - player->play(file); - } - timer_id = startTimer(kSyncInterval); -} - - - -void VideoWall::setTagList(const QVariantList &locationIdList, const QVariantList &appIdList, const QVariantList& tagList) -{ - - int size = locationIdList.size(); - if(size != appIdList.size() && size != tagList.size()) - return; - for(int i = 0; i < size; i++) - { - m_locationIdList << locationIdList.at(i).value(); - m_appIdList << appIdList.at(i).value(); - } - - m_pointTagList << qvariant_cast(tagList); - - -} - -void VideoWall::setNodeName(const QString &nodeName) -{ - m_nodeName = nodeName; -} - -void VideoWall::setAppName(const QString &appName) -{ - m_appName = appName; -} - -void VideoWall::setViewSize(int w, int h) -{ - view->resize(w,h); - -} - - -void VideoWall::stop() -{ - clock->reset(); - killTimer(timer_id); - foreach (AVPlayer* player, players) { - player->stop(); //check playing? - } -} - - - -bool VideoWall::eventFilter(QObject *watched, QEvent *event) -{ - //qDebug("EventFilter::eventFilter to %p", watched); - Q_UNUSED(watched); - if (players.isEmpty()) - return false; - QEvent::Type type = event->type(); - switch (type) { - case QEvent::KeyPress: { - //qDebug("Event target = %p %p", watched, player->renderer); - //avoid receive an event multiple times - QKeyEvent *key_event = static_cast(event); - int key = key_event->key(); - Qt::KeyboardModifiers modifiers = key_event->modifiers(); - Q_UNUSED(modifiers) - switch (key) { - case Qt::Key_F: { - QWidget *w = qApp->activeWindow(); - if (!w) - return false; - if (w->isFullScreen()) - w->showNormal(); - else - w->showFullScreen(); - } - break; - case Qt::Key_P: - clock->reset(); - clock->start(); - - killTimer(timer_id); - foreach (AVPlayer* player, players) { - player->play(); - } - timer_id = startTimer(kSyncInterval); - break; - case Qt::Key_S: - stop(); - break; - case Qt::Key_Space: //check playing? - clock->pause(!clock->isPaused()); - foreach (AVPlayer* player, players) { - player->pause(!player->isPaused()); - } - break; - case Qt::Key_Up: - foreach (AVPlayer* player, players) { - if (player->audio()) { - qreal v = player->audio()->volume(); - if (v > 0.5) - v += 0.1; - else if (v > 0.1) - v += 0.05; - else - v += 0.025; - player->audio()->setVolume(v); - } - } - break; - case Qt::Key_Down: - foreach (AVPlayer* player, players) { - if (player->audio()) { - qreal v = player->audio()->volume(); - if (v > 0.5) - v -= 0.1; - else if (v > 0.1) - v -= 0.05; - else - v -= 0.025; - player->audio()->setVolume(v); - } - } - break; - case Qt::Key_M: - foreach (AVPlayer* player, players) { - if (player->audio()) { - player->audio()->setMute(!player->audio()->isMute()); - } - } - break; - default: - return false; - } - break; - } -// case QEvent::ContextMenu: { -// QContextMenuEvent *e = static_cast(event); -// if (!menu) { -// menu = new QMenu(); -// menu->addAction(tr("Open"), this, SLOT(openLocalFile())); -// menu->addAction(tr("Open Url"), this, SLOT(openUrl())); -// menu->addSeparator(); -// } -// menu->popup(e->globalPos()); -// menu->exec(); -// } -// case QEvent::DragEnter: -// case QEvent::DragMove: { -// QDropEvent *e = static_cast(event); -// e->acceptProposedAction(); -// } -// break; -// case QEvent::Drop: { -// QDropEvent *e = static_cast(event); -// QString path = e->mimeData()->urls().first().toLocalFile(); -// stop(); -// play(path); -// e->acceptProposedAction(); -// } -// break; - case QEvent::MouseButtonPress: { - QMouseEvent *me = static_cast(event); - Qt::MouseButton mbt = me->button(); - if (mbt != Qt::LeftButton) break; - QWidget *mpWindow = static_cast(view->childAt(me->pos())); - if(!mpWindow) break; - if(m_widgetMap.find(mpWindow) != m_widgetMap.end()){ - curNo = m_widgetMap[mpWindow]; - if(curNo <= -1 || curNo >= m_camInfoVec.size()){ - curNo = 0; // 异常序号过滤 - } - } - else - { - break; - } - if(curWid){ - curWid->setStyleSheet(""); - curWid->layout()->setContentsMargins(0, 0, 0, 0); - } - curWid = static_cast(mpWindow->parent()); - curWid->setStyleSheet("border: 2px solid white;"); - curWid->layout()->setContentsMargins(2, 2, 2, 2); - loadPtzCtrl(); - } - break; - default: - return false; - } - return true; //false: for text input -} - -void VideoWall::timerEvent(QTimerEvent *e) -{ - if (e->timerId() != timer_id) { - qDebug("Not clock id"); - return; - } - if (!clock->isActive()) { - qDebug("clock not running"); - return; - } - foreach (AVPlayer *player, players){ - Q_UNUSED(player) -// player->masterClock()->updateExternalClock(*clock); - } -} - -void VideoWall::changeClockType() -{ - AVPlayer* player = qobject_cast(sender()); - player->masterClock()->setClockAuto(false); - player->masterClock()->setClockType(AVClock::ExternalClock); -} - -void VideoWall::handleLoadResults() -{ - playStream(); - loadPtzCtrl(); -} - -void VideoWall::slotVoiceClose(int voice) -{ - setShowVoice(false); - m_voice = voice; - AudioOutput *ao = players[curNo] ?players[curNo]->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void VideoWall::slotVoiceOpen(int voice) -{ - setShowVoice(true); - m_voice = voice; - AudioOutput *ao = players[curNo] ?players[curNo]->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void VideoWall::voiceSliderShow() -{ - if(m_voiceSlider->getStatus() == false){ - m_voiceSlider->move(m_voiceOpen->parentWidget()->mapToGlobal(m_voiceOpen->pos()) - QPoint(150,50)); - m_voiceSlider->show(); - m_voiceSlider->setStatus(true); - } - else{ - m_voiceSlider->hide(); - m_voiceSlider->setStatus(false); - - } -} - -void VideoWall::setShowVoice(bool bo) -{ - if(!bo) - { - m_voiceOpen->setHidden(true); - m_voiceClose->setHidden(false); - }else - { - m_voiceOpen->setHidden(false); - m_voiceClose->setHidden(true); - } -} - -void VideoWall::playCtl() -{ - m_play->setHidden(true); - m_pause->setHidden(false); - if(players[curNo]->isPaused()) - { - players[curNo]->pause(!players[curNo]->isPaused()); - return; - } -} - -void VideoWall::pauseCtl() -{ - m_play->setHidden(false); - m_pause->setHidden(true); - if(players[curNo]->isPaused()) - { - return; - }else - { - players[curNo]->pause(!players[curNo]->isPaused()); - } -} - - - -void VideoWall::playStream() -{ - if(m_editMode) - return; - if (players.isEmpty()) - return; - clock->reset(); - clock->start(); - bool initSelect = false; - for(int i = 0; i < (int)m_camInfoVec.size();i++) - { - if(m_camInfoVec[i].isStreamEnabled()) - { - if(i > players.size()) - return; - qDebug() << "player size is " << QString::number(players.size()); - players.at(i)->setBufferMode(QtAV::BufferTime); - players.at(i)->audio()->setBufferSamples(64); - players.at(i)->setBufferValue(50); - - players.at(i)->play(m_camInfoVec[i].getStreamRtspAddr().c_str()); - if(!initSelect){ - curWid = static_cast( players.at(i)->renderer()->widget()->parent() ); - curWid->setStyleSheet("border: 2px solid white;"); - curWid->layout()->setContentsMargins(2, 2, 2, 2); - curNo = i; - initSelect = true; - m_play->setHidden(false); - m_pause->setHidden(true); - } - } - } - - timer_id = startTimer(kSyncInterval); - m_playersCheckTimer.setInterval(kSyncInterval); - m_playersCheckTimer.start(); -} - -void VideoWall::loadPtzCtrl() -{ - muteOther(curNo); - m_combox->clear(); - - if(curNo == -1) - return; - - if(players[curNo]->isPlaying()) - { - m_play->setHidden(true); - m_pause->setHidden(false); - } - else{ - m_play->setHidden(false); - m_pause->setHidden(true); - } - - - if(!m_camInfoVec[curNo].isPtzEnabled()) - { - m_control_2->setDisabled(true); - return; - } - - // 加载调用列表 - std::vector presets = m_camInfoVec[curNo].presets(); - for(int i = 0; i < (int)presets.size();i++) - m_combox->addItem(QString::fromStdString(presets[i].presetTag) + ":" + presets[i].presetDesc.c_str(),presets[i].presetTag.c_str()); -} - - -void VideoWall::intiPtzUi() -{ - loadPtzUiQss(); - m_ptzui->setSizePolicy(m_ptzui->sizePolicy().horizontalPolicy(),QSizePolicy::Fixed); - m_ptzui->setObjectName("ptzui"); - QVBoxLayout *vl = new QVBoxLayout(); - m_ptzui->setLayout(vl); - - QHBoxLayout *hlayout = new QHBoxLayout(); - { - hlayout->setContentsMargins(10,10,10,10); - - m_control_1 = new QWidget(this); - m_control_1->setMaximumHeight(40); - m_control_2 = new QWidget(this); - m_control_2->setMaximumHeight(100); - - m_play = new QPushButton(m_control_1); - m_play->setFixedSize(20,20); - m_play->setObjectName("play"); - m_pause = new QPushButton(m_control_1); - m_pause->setFixedSize(20,20); - m_pause->setObjectName("pause"); - - m_cap = new QPushButton(m_control_1); - m_cap->setFixedSize(26,26); - m_cap->setObjectName("cap"); - - m_voiceOpen = new QPushButton(m_control_1); - m_voiceOpen->setObjectName("voiceOpen"); - m_voiceOpen->setFixedSize(26,26); - m_voiceClose = new QPushButton(m_control_1); - m_voiceClose->setObjectName("voiceClose"); - m_voiceClose->setFixedSize(26,26); - - hlayout->addWidget(m_play); - hlayout->addWidget(m_pause); - hlayout->addStretch(); - hlayout->addWidget(m_cap); - hlayout->addWidget(m_voiceOpen); - hlayout->addWidget(m_voiceClose); - } - - QGridLayout *glayout = new QGridLayout(); - { - glayout->setContentsMargins(10,0,10,0); - - m_up = new QPushButton(m_control_2); - m_up->setFixedSize(30,20); - m_up->setObjectName("up"); - - m_left = new QPushButton(m_control_2); - m_left->setFixedSize(20,30); - m_left->setObjectName("left"); - - m_right = new QPushButton(m_control_2); - m_right->setFixedSize(20,30); - m_right->setObjectName("right"); - - m_down = new QPushButton(m_control_2); - m_down->setFixedSize(30,20); - m_down->setObjectName("down"); - m_ptz.setFixedSize(30,30); - m_ptz.setText(tr("ptz")); - m_ptz.setAlignment(Qt::AlignCenter); - glayout->addWidget(m_up,0,1); - - glayout->addWidget(m_left,1,0); - glayout->addWidget(&m_ptz,1,1); - glayout->addWidget(m_right,1,2); - glayout->addWidget(m_down,2,1); - } - - QGridLayout *glayout2 = new QGridLayout(); - { - glayout2->setContentsMargins(10,0,10,0); - - m_tj.setText(tr("调焦")); - m_tj.setFixedSize(40,20); - m_tj.setAlignment(Qt::AlignCenter); - m_jj.setText(tr("聚焦")); - m_jj.setFixedSize(40,20); - m_jj.setAlignment(Qt::AlignCenter); - m_gq.setText(tr("光圈")); - m_gq.setFixedSize(40,20); - m_gq.setAlignment(Qt::AlignCenter); - - m_draw = new QPushButton(m_control_2); - m_draw->setFixedSize(30,20); - m_draw->setObjectName("draw"); - m_draw->setText(tr("缩")); - - m_tretch = new QPushButton(m_control_2); - m_tretch->setFixedSize(30,20); - m_tretch->setObjectName("tretch"); - m_tretch->setText(tr("伸")); - - m_near = new QPushButton(m_control_2); - m_near->setFixedSize(30,20); - m_near->setObjectName("near"); - m_near->setText(tr("近")); - - m_far = new QPushButton(m_control_2); - m_far->setFixedSize(30,20); - m_far->setObjectName("far"); - m_far->setText(tr("远")); - - m_big = new QPushButton(m_control_2); - m_big->setFixedSize(30,20); - m_big->setObjectName("big"); - m_big->setText(tr("大")); - - m_small = new QPushButton(m_control_2); - m_small->setFixedSize(30,20); - m_small->setObjectName("small"); - m_small->setText(tr("小")); - - glayout2->addWidget(m_draw,0,0); - glayout2->addWidget(&m_tj,0,1); - glayout2->addWidget(m_tretch,0,2); - - glayout2->addWidget(m_near,1,0); - glayout2->addWidget(&m_jj,1,1); - glayout2->addWidget(m_far,1,2); - - glayout2->addWidget(m_big,2,0); - glayout2->addWidget(&m_gq,2,1); - glayout2->addWidget(m_small,2,2); - } - - { - m_preset.setText(tr("预置点")); - m_preset.setMinimumHeight(25); - m_combox = new QComboBox(m_control_2); - m_combox->setMinimumHeight(25); - m_combox->setMinimumWidth(200); - m_combox->setView(new QListView()); - m_allot = new QPushButton(m_control_2); - m_allot->setText(tr("调用")); - m_allot->setMinimumHeight(25); - m_allot->setMaximumWidth(100); - m_allot->setObjectName("allot"); - - QHBoxLayout *hlayout1 = new QHBoxLayout(); - hlayout1->addWidget(&m_preset); - hlayout1->addWidget(m_combox); - QVBoxLayout *vlayout = new QVBoxLayout(); - vlayout->addLayout(hlayout1); - vlayout->addWidget(m_allot); - QHBoxLayout *hlayout3 = new QHBoxLayout(); - hlayout3->setContentsMargins(20,0,20,0); - hlayout3->addLayout(glayout); - hlayout3->addStretch(); - hlayout3->addLayout(glayout2); - hlayout3->addStretch(); - hlayout3->addLayout(vlayout); - - m_control_1->setLayout(hlayout); - m_control_1->setObjectName("control_1"); - m_control_2->setLayout(hlayout3); - m_control_2->setObjectName("control_2"); - m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); - m_voiceSlider->setWindowOpacity(1); - m_play->setHidden(true); - m_voiceClose->setHidden(true); - } - vl->addLayout(hlayout); - vl->addWidget(m_control_1); - vl->addWidget(m_control_2); - -} - -void VideoWall::loadPtzUiQss() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("ipcPlus.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void VideoWall::setErrMsg(const QString &errMsg) -{ - LOGERROR(errMsg.toStdString().c_str()); - m_errMsg = errMsg; - m_isErr = true; -} - -void VideoWall::muteOther(int notMute) -{ - for(int i = 0; i < players.size();i++) - { - if(i == notMute) - continue; - players[i]->audio()->setMute(true); - } -} - -bool VideoWall::ptzContinuousMove(int cmd, double cmd_speed) -{ - if(PTZ_UI_TEST) - { - return m_camInfoVec[curNo].continuousMove(cmd,cmd_speed); - } - else - { - return sendOptContinuousMove(cmd,cmd_speed); - } -} - -bool VideoWall::ptzStopMove() -{ - if(PTZ_UI_TEST) - { - return m_camInfoVec[curNo].stopMove(); - } - else - { - return sendOptStopMove(); - } -} - -bool VideoWall::ptzGotopreset(const std::string &preset_tag) -{ - if(PTZ_UI_TEST) - { - if(m_camInfoVec[curNo].gotoPreset(preset_tag) == false) - { - return false; - } - } - else - { - if(this->sendOptGotopreset(preset_tag) == false) - { - return false; - } - } - return true; -} - -bool VideoWall::sendOptContinuousMove(int cmd, double cmd_speed) -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_appName.toStdString(); - stCustomCmd.stHead.nSrcDomainID = m_locationIdList[curNo]; - stCustomCmd.stHead.nDstDomainID = m_locationIdList[curNo]; - stCustomCmd.stHead.nAppID = m_appIdList[curNo]; - stCustomCmd.stHead.strHostName = m_nodeName.toStdString(); - stCustomCmd.stHead.strInstName = m_appName.toStdString(); - stCustomCmd.stHead.strCommName = m_com.getName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加转动命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE;//转动 - stOptKeyValue.strKeyValue = CCTV_ONVIF_MOVE ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_camInfoVec[curNo].camTag() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加方向 - stOptKeyValue.strKeyName = PTZ_COMMOND; - stOptKeyValue.strKeyValue = QString::number(cmd).toStdString() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加速度 - stOptKeyValue.strKeyName = PTZ_SPEED; - stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - bool bRet = false; - CMbMessage objMsg; - - objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 - objMsg.setSubject(m_appIdList[curNo],CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 - objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff - - bRet = m_com.sendMsgToDomain(objMsg, m_locationIdList[curNo]); //发送到主机 - if (bRet == false) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_appIdList[curNo], - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - -bool VideoWall::sendOptStopMove() -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_appName.toStdString(); - stCustomCmd.stHead.nSrcDomainID = m_locationIdList[curNo]; - stCustomCmd.stHead.nDstDomainID = m_locationIdList[curNo]; - stCustomCmd.stHead.nAppID = m_appIdList[curNo]; - stCustomCmd.stHead.strHostName = m_nodeName.toStdString(); - stCustomCmd.stHead.strInstName = m_appName.toStdString(); - stCustomCmd.stHead.strCommName = m_com.getName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加停止转动命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE; - stOptKeyValue.strKeyValue = CCTV_ONVIF_STOPMOVE ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_camInfoVec[curNo].camTag() ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - bool bRet = false; - CMbMessage objMsg; - - objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 - objMsg.setSubject(m_appIdList[curNo],CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 - objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff - - bRet = m_com.sendMsgToDomain(objMsg,m_locationIdList[curNo]); //发送到主机 - if (bRet == false) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_appIdList[curNo], - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - -bool VideoWall::sendOptGotopreset(const std::string &preset_tag) -{ - SOptCustCtrlRequest stCustomCmd; - stCustomCmd.stHead.strSrcTag = m_appName.toStdString(); - stCustomCmd.stHead.nSrcDomainID = m_locationIdList[curNo]; - stCustomCmd.stHead.nDstDomainID = m_locationIdList[curNo]; - stCustomCmd.stHead.nAppID = m_appIdList[curNo]; - stCustomCmd.stHead.strHostName = m_nodeName.toStdString(); - stCustomCmd.stHead.strInstName = m_appName.toStdString(); - stCustomCmd.stHead.strCommName = m_com.getName(); - stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); - stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; - - - // 添加转到预置点命令 - SOptCustCtrlQueue stOptKeyValue; - stOptKeyValue.strKeyName = KEY_CMD_TYPE; - stOptKeyValue.strKeyValue = CCTV_ONVIF_GOTOPRESET ; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加摄像头标签 - stOptKeyValue.strKeyName = CAMERA_TAG; - stOptKeyValue.strKeyValue = m_camInfoVec[curNo].camTag(); - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - // 添加预置点标签 - stOptKeyValue.strKeyName = PRESET_TAG; - stOptKeyValue.strKeyValue = preset_tag; - stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return false; - } - - bool bRet = false; - CMbMessage objMsg; - - objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 - objMsg.setSubject(m_appIdList[curNo],CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 - objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff - - bRet = m_com.sendMsgToDomain(objMsg,m_locationIdList[curNo]); //发送到主机 - if (bRet == false) - { - LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_appIdList[curNo], - CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); - return false; - } - return true; -} - - -void VideoWall::leftPressed() -{ - if(!players[curNo]->isPlaying()) - return; - if(ptzContinuousMove(PTZ_LEFT,1) == false) - { - qDebug() << "向左转动失败"; - } -} - -void VideoWall::rightPressed() -{ - if(!players[curNo]->isPlaying()) - return; - if(ptzContinuousMove(PTZ_RIGHT,1) == false) - { - qDebug() << "向右转动失败"; - return; - } -} - -void VideoWall::upPressed() -{ - if(!players[curNo]->isPlaying()) - return; - if(ptzContinuousMove(PTZ_UP,1) == false) - { - qDebug() << "向上转动失败"; - } -} - -void VideoWall::downPressed() -{ - if(!players[curNo]->isPlaying()) - return; - if(ptzContinuousMove(PTZ_DOWN,1) == false) - { - qDebug() << "向下转动失败"; - } -} - -void VideoWall::tretchPressed() -{ - if(!players[curNo]->isPlaying()) - return; - if(ptzContinuousMove(PTZ_ZOOMIN,1) == false) - { - qDebug() << "zoomin转动失败"; - } -} - -void VideoWall::drawPressed() -{ - if(!players[curNo]->isPlaying()) - return; - if(ptzContinuousMove(PTZ_ZOOMOUT,1) == false) - { - qDebug() << "zoomout转动失败"; - } -} - -void VideoWall::released() -{ - if(!players[curNo]->isPlaying()) - return; - if(ptzStopMove() == false) - qDebug() << "停止转动失败"; -} - -void VideoWall::gotoPreset() -{ - if(!players[curNo]->isPlaying()) - return; - else - { - if(ptzGotopreset(m_combox->currentData().toString().toStdString().c_str()) == false) - { - LOGERROR("cannot gotopreset %s",m_combox->currentData().toString().toStdString().c_str()); - qDebug() << "转到预置点失败"; - } - } -} - -void VideoWall::capture() -{ - if (players[curNo]->isPlaying()) { - players[curNo]->videoCapture()->setCaptureName(QDateTime::currentDateTime().toString("yyyy_MMdd_hhmmss_z")); - players[curNo]->videoCapture()->capture(); - } -} - -void VideoWall::checkPlayerStatus() -{ - if(players.empty()) - return; - - for(int i = 0; i < (int)m_camInfoVec.size();i++) - { - if(m_camInfoVec[i].isStreamEnabled()) - { - if(!players.at(i)->isPlaying()) - { - qDebug() << "player " << QString::number(i) << "resume play"; - players.at(i)->play(); - } - } - } - -} - -void VideoWall::loadCamInfo() -{ - if(m_editMode) - return; - for(int i = 0; i < m_appIdList.size();i++) - { - m_camInfoVec.emplace_back(CCamInfo()); - } - m_loadMng.setCamInfoVec(&m_camInfoVec); - m_loadMng.setTagInfo(&m_appIdList,&m_locationIdList,&m_pointTagList); - - if(!m_loadMng.allocateThread()) - { - setErrMsg(tr("请检查计算机内存资源是否足够,无法开辟足够的线程")); - return; - } - - emit m_loadMng.operate(); - m_loadMng.m_timer.start(); - -} - -void VideoWall::showErrMsg() -{ - if(m_isErr){ - QMessageBox::information(this,tr("错误提醒"),m_errMsg); - } -} +/****************************************************************************** + VideoWall: this file is part of QtAV examples + Copyright (C) 2012-2016 Wang Bin + +* This file is part of QtAV + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include "VideoWall.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include <../IpcPlusWidget/VoiceSlider.h> +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" +#include "operate_server_api/JsonOptCommand.h" +#include "common/Common.h" +#include "common/MessageChannel.h" +#include + + + +using namespace QtAV; +using namespace kbd_net; + +const int kSyncInterval = 10000; + +#define PTZ_UI_TEST true +#define VIDEO_SERVER_RTU_NAME "##$$video_server$$##" + +#define PTZ_UP 0 +#define PTZ_DOWN 1 +#define PTZ_LEFT 2 +#define PTZ_RIGHT 3 +#define PTZ_ZOOMIN 4 +#define PTZ_ZOOMOUT 5 + +#define CCTV_ONVIF_MOVE "58" +#define CCTV_ONVIF_STOPMOVE "59" +#define CCTV_ONVIF_GOTOPRESET "57" + +#define KEY_CMD_TYPE "cmd_type" +#define CAMERA_TAG "camera_tag" +#define PTZ_COMMOND "commond" +#define PTZ_SPEED "speed" +#define PRESET_TAG "preset_tag" + + + +VideoWall::VideoWall(QWidget *parent, bool editMode) : + QWidget(parent),m_editMode(editMode),m_rows(2),m_columns(2),view(0),m_ptzui(0),menu(0),curWid(0),curNo(-1),m_loadMng(this) +{ + QtAV::Widgets::registerRenderers(); + QApplication::setAttribute(Qt::AA_UseOpenGLES); + QtAV::setLogLevel(QtAV::LogOff); + + clock = new AVClock(this); + clock->setClockType(AVClock::ExternalClock); + view = new QWidget(this); + view->installEventFilter(this); + view->setStyleSheet(" background-color: black;"); + m_ptzui = new QWidget(this); + QVBoxLayout* layout = new QVBoxLayout; + layout->addWidget(view); + layout->addWidget(m_ptzui); + layout->setSizeConstraint(QLayout::SetMaximumSize); + layout->setSpacing(0); + layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); + this->setLayout(layout); + intiPtzUi(); + connect(&m_loadMng,&CCamInfoLoadMng::resultReady,this,&VideoWall::handleLoadResults); + connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&VideoWall::slotVoiceClose); + connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&VideoWall::slotVoiceOpen); + connect(m_voiceOpen,&QPushButton::clicked,this,&VideoWall::voiceSliderShow); + connect(m_voiceClose,&QPushButton::clicked,this,&VideoWall::voiceSliderShow); + connect(m_play, &QPushButton::clicked,this,&VideoWall::playCtl); + connect(m_cap,&QPushButton::clicked,this,&VideoWall::capture); + + connect(m_pause,&QPushButton::clicked,this,&VideoWall::pauseCtl); + connect(m_left,&QPushButton::pressed,this,&VideoWall::leftPressed); + connect(m_left,&QPushButton::released,this,&VideoWall::released); + + connect(m_right,&QPushButton::pressed,this,&VideoWall::rightPressed); + connect(m_right,&QPushButton::released,this,&VideoWall::released); + + connect(m_up,&QPushButton::pressed,this,&VideoWall::upPressed); + connect(m_up,&QPushButton::released,this,&VideoWall::released); + + connect(m_down,&QPushButton::pressed,this,&VideoWall::downPressed); + connect(m_down,&QPushButton::released,this,&VideoWall::released); + + connect(m_tretch,&QPushButton::pressed,this,&VideoWall::tretchPressed); + connect(m_tretch,&QPushButton::released,this,&VideoWall::released); + + connect(m_draw,&QPushButton::pressed,this,&VideoWall::drawPressed); + connect(m_draw,&QPushButton::released,this,&VideoWall::released); + + connect(m_allot,&QPushButton::clicked,this,&VideoWall::gotoPreset); + + connect(&m_playersCheckTimer,&QTimer::timeout,this,&VideoWall::checkPlayerStatus); +} + +VideoWall::~VideoWall() +{ + if (menu) { + delete menu; + menu = 0; + } + if (!players.isEmpty()) { + foreach (AVPlayer *player, players) { + player->stop(); + VideoRenderer* renderer = player->renderer(); + if (renderer->widget()) { + renderer->widget()->close(); //TODO: rename + if (!renderer->widget()->testAttribute(Qt::WA_DeleteOnClose) && !renderer->widget()->parent()) + delete renderer; + delete player; + } + } + players.clear(); + } + delete view; +} + + +void VideoWall::setRows(int n) +{ + m_rows = n; +} + +void VideoWall::setCols(int n) +{ + m_columns = n; +} + +void VideoWall::setCapturePath(const QString &path) +{ + if(m_editMode) + return; + if(players.isEmpty()) + return; + if(path.isEmpty()) + return; + for(int i = 0;i < players.size();i++) + { + players[i]->videoCapture()->setCaptureName("cap"); + players[i]->videoCapture()->setCaptureDir(path); + players[i]->videoCapture()->setQuality(100); + players[i]->videoCapture()->setSaveFormat("jpg"); + } +} + +void VideoWall::setPtzUiHidden(bool isPtzHidden) +{ + this->m_ptzui->setHidden(isPtzHidden); +} + + +void VideoWall::showUi() +{ + if(m_editMode) + return; + if( m_rows * m_columns < m_pointTagList.size()) + { + m_columns = (int )sqrt((double) m_pointTagList.size() ) + 1; + m_rows = m_columns; + } + + if (!players.isEmpty()) { + foreach (AVPlayer *player, players) { + player->stop(); + VideoRenderer* renderer = player->renderer(); + if (renderer->widget()) { + renderer->widget()->close(); + if (!renderer->widget()->testAttribute(Qt::WA_DeleteOnClose) && !renderer->widget()->parent()) + delete renderer; + delete player; + } + } + players.clear(); + } + qDebug("show wall: %d x %d", m_rows, m_columns); + + int w = view ? view->frameGeometry().width()/m_columns : qApp->desktop()->width()/m_columns; + int h = view ? view->frameGeometry().height()/m_rows : qApp->desktop()->height()/m_rows; + if (view) { + QGridLayout *layout = new QGridLayout; + layout->setSizeConstraint(QLayout::SetMaximumSize); + layout->setSpacing(0); + layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); + view->setLayout(layout); + } + + VideoRendererId v = VideoRendererId_OpenGLWidget; + for (int i = 0; i < m_rows; ++i) { + for (int j = 0; j < m_columns; ++j) { + VideoRenderer* renderer = VideoRenderer::create(v); + renderer->widget()->setWindowFlags(renderer->widget()->windowFlags()| Qt::FramelessWindowHint); + renderer->widget()->setAttribute(Qt::WA_DeleteOnClose); + renderer->widget()->resize(w, h); + renderer->widget()->move(j*w, i*h); + AVPlayer *player = new AVPlayer; + if(m_playerCfgParser.isValid()){ + m_playerCfgParser.applyToPlayer(*player); + } + player->setRenderer(renderer); +// connect(player, SIGNAL(started()), SLOT(changeClockType())); + QWidget* widget = new QWidget; + QGridLayout* layout = new QGridLayout; + widget->setLayout(layout); + layout->setSpacing(0); + layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(renderer->widget()); + players.append(player); + if (view){ + ((QGridLayout*)view->layout())->addWidget(widget, i, j); + m_widgetMap.insert(renderer->widget(),players.size()-1); + } + } + } + setCapturePath(); +} + +void VideoWall::play(const QString &file) +{ + if (players.isEmpty()) + return; + clock->reset(); + clock->start(); + foreach (AVPlayer *player, players) { + player->setBufferMode(QtAV::BufferTime); + player->setBufferValue(50); + player->audio()->setBufferSamples(64); + + + player->play(file); + } + timer_id = startTimer(kSyncInterval); +} + + + +void VideoWall::setTagList(const QVariantList &locationIdList, const QVariantList &appIdList, const QVariantList& tagList) +{ + + int size = locationIdList.size(); + if(size != appIdList.size() && size != tagList.size()) + return; + for(int i = 0; i < size; i++) + { + m_locationIdList << locationIdList.at(i).value(); + m_appIdList << appIdList.at(i).value(); + } + + m_pointTagList << qvariant_cast(tagList); + + +} + +void VideoWall::setNodeName(const QString &nodeName) +{ + m_nodeName = nodeName; +} + +void VideoWall::setAppName(const QString &appName) +{ + m_appName = appName; +} + +void VideoWall::setViewSize(int w, int h) +{ + view->resize(w,h); + +} + + +void VideoWall::stop() +{ + clock->reset(); + killTimer(timer_id); + foreach (AVPlayer* player, players) { + player->stop(); //check playing? + } +} + + + +bool VideoWall::eventFilter(QObject *watched, QEvent *event) +{ + //qDebug("EventFilter::eventFilter to %p", watched); + Q_UNUSED(watched); + if (players.isEmpty()) + return false; + QEvent::Type type = event->type(); + switch (type) { + case QEvent::KeyPress: { + //qDebug("Event target = %p %p", watched, player->renderer); + //avoid receive an event multiple times + QKeyEvent *key_event = static_cast(event); + int key = key_event->key(); + Qt::KeyboardModifiers modifiers = key_event->modifiers(); + Q_UNUSED(modifiers) + switch (key) { + case Qt::Key_F: { + QWidget *w = qApp->activeWindow(); + if (!w) + return false; + if (w->isFullScreen()) + w->showNormal(); + else + w->showFullScreen(); + } + break; + case Qt::Key_P: + clock->reset(); + clock->start(); + + killTimer(timer_id); + foreach (AVPlayer* player, players) { + player->play(); + } + timer_id = startTimer(kSyncInterval); + break; + case Qt::Key_S: + stop(); + break; + case Qt::Key_Space: //check playing? + clock->pause(!clock->isPaused()); + foreach (AVPlayer* player, players) { + player->pause(!player->isPaused()); + } + break; + case Qt::Key_Up: + foreach (AVPlayer* player, players) { + if (player->audio()) { + qreal v = player->audio()->volume(); + if (v > 0.5) + v += 0.1; + else if (v > 0.1) + v += 0.05; + else + v += 0.025; + player->audio()->setVolume(v); + } + } + break; + case Qt::Key_Down: + foreach (AVPlayer* player, players) { + if (player->audio()) { + qreal v = player->audio()->volume(); + if (v > 0.5) + v -= 0.1; + else if (v > 0.1) + v -= 0.05; + else + v -= 0.025; + player->audio()->setVolume(v); + } + } + break; + case Qt::Key_M: + foreach (AVPlayer* player, players) { + if (player->audio()) { + player->audio()->setMute(!player->audio()->isMute()); + } + } + break; + default: + return false; + } + break; + } +// case QEvent::ContextMenu: { +// QContextMenuEvent *e = static_cast(event); +// if (!menu) { +// menu = new QMenu(); +// menu->addAction(tr("Open"), this, SLOT(openLocalFile())); +// menu->addAction(tr("Open Url"), this, SLOT(openUrl())); +// menu->addSeparator(); +// } +// menu->popup(e->globalPos()); +// menu->exec(); +// } +// case QEvent::DragEnter: +// case QEvent::DragMove: { +// QDropEvent *e = static_cast(event); +// e->acceptProposedAction(); +// } +// break; +// case QEvent::Drop: { +// QDropEvent *e = static_cast(event); +// QString path = e->mimeData()->urls().first().toLocalFile(); +// stop(); +// play(path); +// e->acceptProposedAction(); +// } +// break; + case QEvent::MouseButtonPress: { + QMouseEvent *me = static_cast(event); + Qt::MouseButton mbt = me->button(); + if (mbt != Qt::LeftButton) break; + QWidget *mpWindow = static_cast(view->childAt(me->pos())); + if(!mpWindow) break; + if(m_widgetMap.find(mpWindow) != m_widgetMap.end()){ + curNo = m_widgetMap[mpWindow]; + if(curNo <= -1 || curNo >= m_camInfoVec.size()){ + curNo = 0; // 异常序号过滤 + } + } + else + { + break; + } + if(curWid){ + curWid->setStyleSheet(""); + curWid->layout()->setContentsMargins(0, 0, 0, 0); + } + curWid = static_cast(mpWindow->parent()); + curWid->setStyleSheet("border: 2px solid white;"); + curWid->layout()->setContentsMargins(2, 2, 2, 2); + loadPtzCtrl(); + } + break; + default: + return false; + } + return true; //false: for text input +} + +void VideoWall::timerEvent(QTimerEvent *e) +{ + if (e->timerId() != timer_id) { + qDebug("Not clock id"); + return; + } + if (!clock->isActive()) { + qDebug("clock not running"); + return; + } + foreach (AVPlayer *player, players){ + Q_UNUSED(player) +// player->masterClock()->updateExternalClock(*clock); + } +} + +void VideoWall::changeClockType() +{ + AVPlayer* player = qobject_cast(sender()); + player->masterClock()->setClockAuto(false); + player->masterClock()->setClockType(AVClock::ExternalClock); +} + +void VideoWall::handleLoadResults() +{ + playStream(); + loadPtzCtrl(); +} + +void VideoWall::slotVoiceClose(int voice) +{ + setShowVoice(false); + m_voice = voice; + AudioOutput *ao = players[curNo] ?players[curNo]->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void VideoWall::slotVoiceOpen(int voice) +{ + setShowVoice(true); + m_voice = voice; + AudioOutput *ao = players[curNo] ?players[curNo]->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void VideoWall::voiceSliderShow() +{ + if(m_voiceSlider->getStatus() == false){ + m_voiceSlider->move(m_voiceOpen->parentWidget()->mapToGlobal(m_voiceOpen->pos()) - QPoint(150,50)); + m_voiceSlider->show(); + m_voiceSlider->setStatus(true); + } + else{ + m_voiceSlider->hide(); + m_voiceSlider->setStatus(false); + + } +} + +void VideoWall::setShowVoice(bool bo) +{ + if(!bo) + { + m_voiceOpen->setHidden(true); + m_voiceClose->setHidden(false); + }else + { + m_voiceOpen->setHidden(false); + m_voiceClose->setHidden(true); + } +} + +void VideoWall::playCtl() +{ + m_play->setHidden(true); + m_pause->setHidden(false); + if(players[curNo]->isPaused()) + { + players[curNo]->pause(!players[curNo]->isPaused()); + return; + } +} + +void VideoWall::pauseCtl() +{ + m_play->setHidden(false); + m_pause->setHidden(true); + if(players[curNo]->isPaused()) + { + return; + }else + { + players[curNo]->pause(!players[curNo]->isPaused()); + } +} + + + +void VideoWall::playStream() +{ + if(m_editMode) + return; + if (players.isEmpty()) + return; + clock->reset(); + clock->start(); + bool initSelect = false; + for(int i = 0; i < (int)m_camInfoVec.size();i++) + { + if(m_camInfoVec[i].isStreamEnabled()) + { + if(i > players.size()) + return; + qDebug() << "player size is " << QString::number(players.size()); + players.at(i)->setBufferMode(QtAV::BufferTime); + players.at(i)->audio()->setBufferSamples(64); + players.at(i)->setBufferValue(50); + + players.at(i)->play(m_camInfoVec[i].getStreamRtspAddr().c_str()); + if(!initSelect){ + curWid = static_cast( players.at(i)->renderer()->widget()->parent() ); + curWid->setStyleSheet("border: 2px solid white;"); + curWid->layout()->setContentsMargins(2, 2, 2, 2); + curNo = i; + initSelect = true; + m_play->setHidden(false); + m_pause->setHidden(true); + } + } + } + + timer_id = startTimer(kSyncInterval); + m_playersCheckTimer.setInterval(kSyncInterval); + m_playersCheckTimer.start(); +} + +void VideoWall::loadPtzCtrl() +{ + muteOther(curNo); + m_combox->clear(); + + if(curNo == -1) + return; + + if(players[curNo]->isPlaying()) + { + m_play->setHidden(true); + m_pause->setHidden(false); + } + else{ + m_play->setHidden(false); + m_pause->setHidden(true); + } + + + if(!m_camInfoVec[curNo].isPtzEnabled()) + { + m_control_2->setDisabled(true); + return; + } + + // 加载调用列表 + std::vector presets = m_camInfoVec[curNo].presets(); + for(int i = 0; i < (int)presets.size();i++) + m_combox->addItem(QString::fromStdString(presets[i].presetTag) + ":" + presets[i].presetDesc.c_str(),presets[i].presetTag.c_str()); +} + + +void VideoWall::intiPtzUi() +{ + loadPtzUiQss(); + m_ptzui->setSizePolicy(m_ptzui->sizePolicy().horizontalPolicy(),QSizePolicy::Fixed); + m_ptzui->setObjectName("ptzui"); + QVBoxLayout *vl = new QVBoxLayout(); + m_ptzui->setLayout(vl); + + QHBoxLayout *hlayout = new QHBoxLayout(); + { + hlayout->setContentsMargins(10,10,10,10); + + m_control_1 = new QWidget(this); + m_control_1->setMaximumHeight(40); + m_control_2 = new QWidget(this); + m_control_2->setMaximumHeight(100); + + m_play = new QPushButton(m_control_1); + m_play->setFixedSize(20,20); + m_play->setObjectName("play"); + m_pause = new QPushButton(m_control_1); + m_pause->setFixedSize(20,20); + m_pause->setObjectName("pause"); + + m_cap = new QPushButton(m_control_1); + m_cap->setFixedSize(26,26); + m_cap->setObjectName("cap"); + + m_voiceOpen = new QPushButton(m_control_1); + m_voiceOpen->setObjectName("voiceOpen"); + m_voiceOpen->setFixedSize(26,26); + m_voiceClose = new QPushButton(m_control_1); + m_voiceClose->setObjectName("voiceClose"); + m_voiceClose->setFixedSize(26,26); + + hlayout->addWidget(m_play); + hlayout->addWidget(m_pause); + hlayout->addStretch(); + hlayout->addWidget(m_cap); + hlayout->addWidget(m_voiceOpen); + hlayout->addWidget(m_voiceClose); + } + + QGridLayout *glayout = new QGridLayout(); + { + glayout->setContentsMargins(10,0,10,0); + + m_up = new QPushButton(m_control_2); + m_up->setFixedSize(30,20); + m_up->setObjectName("up"); + + m_left = new QPushButton(m_control_2); + m_left->setFixedSize(20,30); + m_left->setObjectName("left"); + + m_right = new QPushButton(m_control_2); + m_right->setFixedSize(20,30); + m_right->setObjectName("right"); + + m_down = new QPushButton(m_control_2); + m_down->setFixedSize(30,20); + m_down->setObjectName("down"); + m_ptz.setFixedSize(30,30); + m_ptz.setText(tr("ptz")); + m_ptz.setAlignment(Qt::AlignCenter); + glayout->addWidget(m_up,0,1); + + glayout->addWidget(m_left,1,0); + glayout->addWidget(&m_ptz,1,1); + glayout->addWidget(m_right,1,2); + glayout->addWidget(m_down,2,1); + } + + QGridLayout *glayout2 = new QGridLayout(); + { + glayout2->setContentsMargins(10,0,10,0); + + m_tj.setText(tr("调焦")); + m_tj.setFixedSize(40,20); + m_tj.setAlignment(Qt::AlignCenter); + m_jj.setText(tr("聚焦")); + m_jj.setFixedSize(40,20); + m_jj.setAlignment(Qt::AlignCenter); + m_gq.setText(tr("光圈")); + m_gq.setFixedSize(40,20); + m_gq.setAlignment(Qt::AlignCenter); + + m_draw = new QPushButton(m_control_2); + m_draw->setFixedSize(30,20); + m_draw->setObjectName("draw"); + m_draw->setText(tr("缩")); + + m_tretch = new QPushButton(m_control_2); + m_tretch->setFixedSize(30,20); + m_tretch->setObjectName("tretch"); + m_tretch->setText(tr("伸")); + + m_near = new QPushButton(m_control_2); + m_near->setFixedSize(30,20); + m_near->setObjectName("near"); + m_near->setText(tr("近")); + + m_far = new QPushButton(m_control_2); + m_far->setFixedSize(30,20); + m_far->setObjectName("far"); + m_far->setText(tr("远")); + + m_big = new QPushButton(m_control_2); + m_big->setFixedSize(30,20); + m_big->setObjectName("big"); + m_big->setText(tr("大")); + + m_small = new QPushButton(m_control_2); + m_small->setFixedSize(30,20); + m_small->setObjectName("small"); + m_small->setText(tr("小")); + + glayout2->addWidget(m_draw,0,0); + glayout2->addWidget(&m_tj,0,1); + glayout2->addWidget(m_tretch,0,2); + + glayout2->addWidget(m_near,1,0); + glayout2->addWidget(&m_jj,1,1); + glayout2->addWidget(m_far,1,2); + + glayout2->addWidget(m_big,2,0); + glayout2->addWidget(&m_gq,2,1); + glayout2->addWidget(m_small,2,2); + } + + { + m_preset.setText(tr("预置点")); + m_preset.setMinimumHeight(25); + m_combox = new QComboBox(m_control_2); + m_combox->setMinimumHeight(25); + m_combox->setMinimumWidth(200); + m_combox->setView(new QListView()); + m_allot = new QPushButton(m_control_2); + m_allot->setText(tr("调用")); + m_allot->setMinimumHeight(25); + m_allot->setMaximumWidth(100); + m_allot->setObjectName("allot"); + + QHBoxLayout *hlayout1 = new QHBoxLayout(); + hlayout1->addWidget(&m_preset); + hlayout1->addWidget(m_combox); + QVBoxLayout *vlayout = new QVBoxLayout(); + vlayout->addLayout(hlayout1); + vlayout->addWidget(m_allot); + QHBoxLayout *hlayout3 = new QHBoxLayout(); + hlayout3->setContentsMargins(20,0,20,0); + hlayout3->addLayout(glayout); + hlayout3->addStretch(); + hlayout3->addLayout(glayout2); + hlayout3->addStretch(); + hlayout3->addLayout(vlayout); + + m_control_1->setLayout(hlayout); + m_control_1->setObjectName("control_1"); + m_control_2->setLayout(hlayout3); + m_control_2->setObjectName("control_2"); + m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); + m_voiceSlider->setWindowOpacity(1); + m_play->setHidden(true); + m_voiceClose->setHidden(true); + } + vl->addLayout(hlayout); + vl->addWidget(m_control_1); + vl->addWidget(m_control_2); + +} + +void VideoWall::loadPtzUiQss() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("ipcPlus.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void VideoWall::setErrMsg(const QString &errMsg) +{ + LOGERROR(errMsg.toStdString().c_str()); + m_errMsg = errMsg; + m_isErr = true; +} + +void VideoWall::muteOther(int notMute) +{ + for(int i = 0; i < players.size();i++) + { + if(i == notMute) + continue; + players[i]->audio()->setMute(true); + } +} + +bool VideoWall::ptzContinuousMove(int cmd, double cmd_speed) +{ + if(PTZ_UI_TEST) + { + return m_camInfoVec[curNo].continuousMove(cmd,cmd_speed); + } + else + { + return sendOptContinuousMove(cmd,cmd_speed); + } +} + +bool VideoWall::ptzStopMove() +{ + if(PTZ_UI_TEST) + { + return m_camInfoVec[curNo].stopMove(); + } + else + { + return sendOptStopMove(); + } +} + +bool VideoWall::ptzGotopreset(const std::string &preset_tag) +{ + if(PTZ_UI_TEST) + { + if(m_camInfoVec[curNo].gotoPreset(preset_tag) == false) + { + return false; + } + } + else + { + if(this->sendOptGotopreset(preset_tag) == false) + { + return false; + } + } + return true; +} + +bool VideoWall::sendOptContinuousMove(int cmd, double cmd_speed) +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_appName.toStdString(); + stCustomCmd.stHead.nSrcDomainID = m_locationIdList[curNo]; + stCustomCmd.stHead.nDstDomainID = m_locationIdList[curNo]; + stCustomCmd.stHead.nAppID = m_appIdList[curNo]; + stCustomCmd.stHead.strHostName = m_nodeName.toStdString(); + stCustomCmd.stHead.strInstName = m_appName.toStdString(); + stCustomCmd.stHead.strCommName = m_com.getName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加转动命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE;//转动 + stOptKeyValue.strKeyValue = CCTV_ONVIF_MOVE ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_camInfoVec[curNo].camTag() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加方向 + stOptKeyValue.strKeyName = PTZ_COMMOND; + stOptKeyValue.strKeyValue = QString::number(cmd).toStdString() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加速度 + stOptKeyValue.strKeyName = PTZ_SPEED; + stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + bool bRet = false; + CMbMessage objMsg; + + objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 + objMsg.setSubject(m_appIdList[curNo],CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 + objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff + + bRet = m_com.sendMsgToDomain(objMsg, m_locationIdList[curNo]); //发送到主机 + if (bRet == false) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_appIdList[curNo], + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + +bool VideoWall::sendOptStopMove() +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_appName.toStdString(); + stCustomCmd.stHead.nSrcDomainID = m_locationIdList[curNo]; + stCustomCmd.stHead.nDstDomainID = m_locationIdList[curNo]; + stCustomCmd.stHead.nAppID = m_appIdList[curNo]; + stCustomCmd.stHead.strHostName = m_nodeName.toStdString(); + stCustomCmd.stHead.strInstName = m_appName.toStdString(); + stCustomCmd.stHead.strCommName = m_com.getName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加停止转动命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE; + stOptKeyValue.strKeyValue = CCTV_ONVIF_STOPMOVE ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_camInfoVec[curNo].camTag() ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + bool bRet = false; + CMbMessage objMsg; + + objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 + objMsg.setSubject(m_appIdList[curNo],CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 + objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff + + bRet = m_com.sendMsgToDomain(objMsg,m_locationIdList[curNo]); //发送到主机 + if (bRet == false) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_appIdList[curNo], + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + +bool VideoWall::sendOptGotopreset(const std::string &preset_tag) +{ + SOptCustCtrlRequest stCustomCmd; + stCustomCmd.stHead.strSrcTag = m_appName.toStdString(); + stCustomCmd.stHead.nSrcDomainID = m_locationIdList[curNo]; + stCustomCmd.stHead.nDstDomainID = m_locationIdList[curNo]; + stCustomCmd.stHead.nAppID = m_appIdList[curNo]; + stCustomCmd.stHead.strHostName = m_nodeName.toStdString(); + stCustomCmd.stHead.strInstName = m_appName.toStdString(); + stCustomCmd.stHead.strCommName = m_com.getName(); + stCustomCmd.stHead.nOptTime = QDateTime::currentMSecsSinceEpoch(); + stCustomCmd.strRtuTag = VIDEO_SERVER_RTU_NAME; + + + // 添加转到预置点命令 + SOptCustCtrlQueue stOptKeyValue; + stOptKeyValue.strKeyName = KEY_CMD_TYPE; + stOptKeyValue.strKeyValue = CCTV_ONVIF_GOTOPRESET ; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加摄像头标签 + stOptKeyValue.strKeyName = CAMERA_TAG; + stOptKeyValue.strKeyValue = m_camInfoVec[curNo].camTag(); + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + // 添加预置点标签 + stOptKeyValue.strKeyName = PRESET_TAG; + stOptKeyValue.strKeyValue = preset_tag; + stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); + + COptCustCtrlRequest objReq; + std::string strMsg = objReq.generate(stCustomCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return false; + } + + bool bRet = false; + CMbMessage objMsg; + + objMsg.setMsgType(MT_OPT_COMMON_DOWN); //指定消息类型 + objMsg.setSubject(m_appIdList[curNo],CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 + objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff + + bRet = m_com.sendMsgToDomain(objMsg,m_locationIdList[curNo]); //发送到主机 + if (bRet == false) + { + LOGERROR("发送消息失败.AppId=[%d],CH=[%d],MT=[%d]", m_appIdList[curNo], + CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_COMMON_DOWN); + return false; + } + return true; +} + + +void VideoWall::leftPressed() +{ + if(!players[curNo]->isPlaying()) + return; + if(ptzContinuousMove(PTZ_LEFT,1) == false) + { + qDebug() << "向左转动失败"; + } +} + +void VideoWall::rightPressed() +{ + if(!players[curNo]->isPlaying()) + return; + if(ptzContinuousMove(PTZ_RIGHT,1) == false) + { + qDebug() << "向右转动失败"; + return; + } +} + +void VideoWall::upPressed() +{ + if(!players[curNo]->isPlaying()) + return; + if(ptzContinuousMove(PTZ_UP,1) == false) + { + qDebug() << "向上转动失败"; + } +} + +void VideoWall::downPressed() +{ + if(!players[curNo]->isPlaying()) + return; + if(ptzContinuousMove(PTZ_DOWN,1) == false) + { + qDebug() << "向下转动失败"; + } +} + +void VideoWall::tretchPressed() +{ + if(!players[curNo]->isPlaying()) + return; + if(ptzContinuousMove(PTZ_ZOOMIN,1) == false) + { + qDebug() << "zoomin转动失败"; + } +} + +void VideoWall::drawPressed() +{ + if(!players[curNo]->isPlaying()) + return; + if(ptzContinuousMove(PTZ_ZOOMOUT,1) == false) + { + qDebug() << "zoomout转动失败"; + } +} + +void VideoWall::released() +{ + if(!players[curNo]->isPlaying()) + return; + if(ptzStopMove() == false) + qDebug() << "停止转动失败"; +} + +void VideoWall::gotoPreset() +{ + if(!players[curNo]->isPlaying()) + return; + else + { + if(ptzGotopreset(m_combox->currentData().toString().toStdString().c_str()) == false) + { + LOGERROR("cannot gotopreset %s",m_combox->currentData().toString().toStdString().c_str()); + qDebug() << "转到预置点失败"; + } + } +} + +void VideoWall::capture() +{ + if (players[curNo]->isPlaying()) { + players[curNo]->videoCapture()->setCaptureName(QDateTime::currentDateTime().toString("yyyy_MMdd_hhmmss_z")); + players[curNo]->videoCapture()->capture(); + } +} + +void VideoWall::checkPlayerStatus() +{ + if(players.empty()) + return; + + for(int i = 0; i < (int)m_camInfoVec.size();i++) + { + if(m_camInfoVec[i].isStreamEnabled()) + { + if(!players.at(i)->isPlaying()) + { + qDebug() << "player " << QString::number(i) << "resume play"; + players.at(i)->play(); + } + } + } + +} + +void VideoWall::loadCamInfo() +{ + if(m_editMode) + return; + for(int i = 0; i < m_appIdList.size();i++) + { + m_camInfoVec.emplace_back(CCamInfo()); + } + m_loadMng.setCamInfoVec(&m_camInfoVec); + m_loadMng.setTagInfo(&m_appIdList,&m_locationIdList,&m_pointTagList); + + if(!m_loadMng.allocateThread()) + { + setErrMsg(tr("请检查计算机内存资源是否足够,无法开辟足够的线程")); + return; + } + + emit m_loadMng.operate(); + m_loadMng.m_timer.start(); + +} + +void VideoWall::showErrMsg() +{ + if(m_isErr){ + QMessageBox::information(this,tr("错误提醒"),m_errMsg); + } +} diff --git a/product/src/gui/plugin/IpcWallWidget/VideoWall.h b/product/src/gui/plugin/IpcWallWidget/VideoWall.h index f9823118..dfae132a 100644 --- a/product/src/gui/plugin/IpcWallWidget/VideoWall.h +++ b/product/src/gui/plugin/IpcWallWidget/VideoWall.h @@ -1,170 +1,170 @@ -/****************************************************************************** - VideoWall: this file is part of QtAV examples - Copyright (C) 2013-2016 Wang Bin - -* This file is part of QtAV - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -******************************************************************************/ - -#ifndef QTAV_VIDEOWALL_H -#define QTAV_VIDEOWALL_H - -#include -#include -#include -#include -#include -#include -#include -#include <../IpcViewerWidget/ccaminfo.h> -#include -#include "net_msg_bus_api/CMbCommunicator.h" -#include - - -class Slider; -class QPushButton; -class QWidget; -class QToolButton; -class Renderer; -class VoiceSlider; -class QComboBox; - - -QT_BEGIN_NAMESPACE -class QMenu; -QT_END_NAMESPACE -class VideoWall : public QWidget -{ - Q_OBJECT -public: - explicit VideoWall(QWidget *parent = 0, bool editMode = false); - ~VideoWall(); - void setVideoRendererTypeString(const QString& vt); - -public slots: - void showUi(); - void loadCamInfo(); - void showErrMsg(); - void stop(); - - void play(const QString& file);// for debug - - void setTagList(const QVariantList &locationIdList, const QVariantList &appIdList, const QVariantList &tagList); - void setNodeName(const QString& nodeName); - void setAppName(const QString& appName); - - void setViewSize(int w, int h); - void setRows(int n); - void setCols(int n); - void setCapturePath(const QString &path = QStringLiteral("../../data/videocap")); - void setPtzUiHidden(bool isPtzHidden); - -protected: - virtual bool eventFilter(QObject *, QEvent *); - virtual void timerEvent(QTimerEvent *e); - -private Q_SLOTS: - void changeClockType(); - void handleLoadResults(); - - void slotVoiceClose(int voice); - void slotVoiceOpen(int voice); - void voiceSliderShow(); - void setShowVoice(bool bo); - - void playCtl(); - void pauseCtl(); - -private: - - void playStream(); - void loadPtzCtrl(); - void intiPtzUi(); - void loadPtzUiQss(); - void setErrMsg(const QString &errMsg); - void muteOther(int notMute); - - bool ptzContinuousMove(int cmd,double cmd_speed = 1); - bool ptzStopMove(); - bool ptzGotopreset(const std::string &preset_tag); - - bool sendOptContinuousMove(int cmd, double cmd_speed = 1); - bool sendOptStopMove(); - bool sendOptGotopreset(const std::string &preset_tag); - void leftPressed(); - void rightPressed(); - void upPressed(); - void downPressed(); - - void tretchPressed(); - void drawPressed(); - void released(); - - void gotoPreset(); - void capture(); - - void checkPlayerStatus(); - - //< 摄像机参数相关 - QStringList m_pointTagList; - QList m_appIdList; - QList m_locationIdList; - - std::vector m_camInfoVec; - //> 摄像机参数相关 - - QString m_nodeName; - QString m_appName; - - bool m_editMode; - int m_rows, m_columns; - int timer_id; - QtAV::AVClock *clock; - QList players; - QWidget *view; - QWidget *m_ptzui; - QMenu *menu; - CPlayerCfgParser m_playerCfgParser; - QMap m_widgetMap; - QWidget *curWid; - int curNo; - - QPushButton *m_play,*m_pause; - kbd_net::CMbCommunicator m_com; - - - QPushButton *m_cap; //抓图 - QPushButton *m_voiceOpen,*m_voiceClose; - VoiceSlider *m_voiceSlider; - - QLabel m_ptz,m_tj,m_jj,m_gq,m_preset;//云台 调焦 聚焦 光圈 - QPushButton *m_up,*m_down,*m_left,*m_right; //上下左右 - QPushButton *m_tretch,*m_draw,*m_far,*m_near,*m_big,*m_small; //伸 缩 远 近 大 小 - QWidget *m_control_1; - QWidget *m_control_2; - QComboBox *m_combox; - QPushButton *m_allot; //调用 - int m_voice; - bool m_isErr=false; - QString m_errMsg; - CCamInfoLoadMng m_loadMng; - - QTimer m_playersCheckTimer; - -}; - - -#endif // QTAV_VIDEOWALL_H +/****************************************************************************** + VideoWall: this file is part of QtAV examples + Copyright (C) 2013-2016 Wang Bin + +* This file is part of QtAV + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#ifndef QTAV_VIDEOWALL_H +#define QTAV_VIDEOWALL_H + +#include +#include +#include +#include +#include +#include +#include +#include <../IpcViewerWidget/ccaminfo.h> +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include + + +class Slider; +class QPushButton; +class QWidget; +class QToolButton; +class Renderer; +class VoiceSlider; +class QComboBox; + + +QT_BEGIN_NAMESPACE +class QMenu; +QT_END_NAMESPACE +class VideoWall : public QWidget +{ + Q_OBJECT +public: + explicit VideoWall(QWidget *parent = 0, bool editMode = false); + ~VideoWall(); + void setVideoRendererTypeString(const QString& vt); + +public slots: + void showUi(); + void loadCamInfo(); + void showErrMsg(); + void stop(); + + void play(const QString& file);// for debug + + void setTagList(const QVariantList &locationIdList, const QVariantList &appIdList, const QVariantList &tagList); + void setNodeName(const QString& nodeName); + void setAppName(const QString& appName); + + void setViewSize(int w, int h); + void setRows(int n); + void setCols(int n); + void setCapturePath(const QString &path = QStringLiteral("../../data/videocap")); + void setPtzUiHidden(bool isPtzHidden); + +protected: + virtual bool eventFilter(QObject *, QEvent *); + virtual void timerEvent(QTimerEvent *e); + +private Q_SLOTS: + void changeClockType(); + void handleLoadResults(); + + void slotVoiceClose(int voice); + void slotVoiceOpen(int voice); + void voiceSliderShow(); + void setShowVoice(bool bo); + + void playCtl(); + void pauseCtl(); + +private: + + void playStream(); + void loadPtzCtrl(); + void intiPtzUi(); + void loadPtzUiQss(); + void setErrMsg(const QString &errMsg); + void muteOther(int notMute); + + bool ptzContinuousMove(int cmd,double cmd_speed = 1); + bool ptzStopMove(); + bool ptzGotopreset(const std::string &preset_tag); + + bool sendOptContinuousMove(int cmd, double cmd_speed = 1); + bool sendOptStopMove(); + bool sendOptGotopreset(const std::string &preset_tag); + void leftPressed(); + void rightPressed(); + void upPressed(); + void downPressed(); + + void tretchPressed(); + void drawPressed(); + void released(); + + void gotoPreset(); + void capture(); + + void checkPlayerStatus(); + + //< 摄像机参数相关 + QStringList m_pointTagList; + QList m_appIdList; + QList m_locationIdList; + + std::vector m_camInfoVec; + //> 摄像机参数相关 + + QString m_nodeName; + QString m_appName; + + bool m_editMode; + int m_rows, m_columns; + int timer_id; + QtAV::AVClock *clock; + QList players; + QWidget *view; + QWidget *m_ptzui; + QMenu *menu; + CPlayerCfgParser m_playerCfgParser; + QMap m_widgetMap; + QWidget *curWid; + int curNo; + + QPushButton *m_play,*m_pause; + kbd_net::CMbCommunicator m_com; + + + QPushButton *m_cap; //抓图 + QPushButton *m_voiceOpen,*m_voiceClose; + VoiceSlider *m_voiceSlider; + + QLabel m_ptz,m_tj,m_jj,m_gq,m_preset;//云台 调焦 聚焦 光圈 + QPushButton *m_up,*m_down,*m_left,*m_right; //上下左右 + QPushButton *m_tretch,*m_draw,*m_far,*m_near,*m_big,*m_small; //伸 缩 远 近 大 小 + QWidget *m_control_1; + QWidget *m_control_2; + QComboBox *m_combox; + QPushButton *m_allot; //调用 + int m_voice; + bool m_isErr=false; + QString m_errMsg; + CCamInfoLoadMng m_loadMng; + + QTimer m_playersCheckTimer; + +}; + + +#endif // QTAV_VIDEOWALL_H diff --git a/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidge.h b/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidge.h index acc23c1e..3b783a45 100644 --- a/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidge.h +++ b/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidge.h @@ -1,22 +1,22 @@ -#ifndef IPCVIEWERPLUGINWIDGET_H -#define IPCVIEWERPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - - -class IpcViewerPluginWidget: public QObject,public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - IpcViewerPluginWidget(QObject *parent=0); - ~IpcViewerPluginWidget(); - - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // IPCVIEWERPLUGINWIDGET_H +#ifndef IPCVIEWERPLUGINWIDGET_H +#define IPCVIEWERPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + + +class IpcViewerPluginWidget: public QObject,public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + IpcViewerPluginWidget(QObject *parent=0); + ~IpcViewerPluginWidget(); + + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // IPCVIEWERPLUGINWIDGET_H diff --git a/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidget.cpp b/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidget.cpp index 7113dddc..33b3adb9 100644 --- a/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidget.cpp +++ b/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "ipcWallPluginWidge.h" -#include "VideoWall.h" -#include -IpcViewerPluginWidget::IpcViewerPluginWidget(QObject *parent): QObject(parent) -{ - -} - -IpcViewerPluginWidget::~IpcViewerPluginWidget() -{ - -} - -bool IpcViewerPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - VideoWall *pWidget = new VideoWall(parent,editMode); - Q_UNUSED(ptrVec); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void IpcViewerPluginWidget::release() -{ - -} +#include "ipcWallPluginWidge.h" +#include "VideoWall.h" +#include +IpcViewerPluginWidget::IpcViewerPluginWidget(QObject *parent): QObject(parent) +{ + +} + +IpcViewerPluginWidget::~IpcViewerPluginWidget() +{ + +} + +bool IpcViewerPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + VideoWall *pWidget = new VideoWall(parent,editMode); + Q_UNUSED(ptrVec); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void IpcViewerPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/IpcWallWidget/main.cpp b/product/src/gui/plugin/IpcWallWidget/main.cpp index 31bb772e..0653bf04 100644 --- a/product/src/gui/plugin/IpcWallWidget/main.cpp +++ b/product/src/gui/plugin/IpcWallWidget/main.cpp @@ -1,89 +1,89 @@ -/****************************************************************************** - VideoWall: this file is part of QtAV examples - Copyright (C) 2012-2016 Wang Bin - -* This file is part of QtAV - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -******************************************************************************/ - -#include -#include -#include -#include -#include -#include "VideoWall.h" -#include -#include "net_msg_bus_api/MsgBusApi.h" -#include - -void append(QVariantList &list1,QVariantList &list2,QVariantList &list3) -{ - size_t size = QInputDialog::getInt(NULL, QString("QInputDialog::getText()"), - QString("Test Ipc Size:")); - for(size_t i = 0;i < size; i++) - { - list1 << 1; - list2 << 4; - list3 << "analog.syx.ZLQR2_jgxh.WD"; - } -} - - -int main(int argc, char *argv[]) -{ - QGuiApplication::setAttribute(Qt::AA_UseDesktopOpenGL); - kbd_public::StartLogSystem("BASE","ipcwall"); - - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - - QApplication a(argc, argv); - - QVariantList list1,list2,list3; - append(list1,list2,list3); -// list1 << 1 << 1 << 1 << 1 << 1 << 1; -// list2 << 4 << 4 << 4 << 4 << 4 << 4; -// list3 << "analog.syx.ZLQR2_jgxh.WD"; -// list3 << "analog.syx.ZLQR2_jgxh.WD"; -// list3 << "analog.syx.ZLQR2_jgxh.WD"; -// list3 << "analog.syx.ZLQR2_jgxh.WD"; -// list3 << "analog.syx.ZLQR2_jgxh.WD"; -// list3 << "analog.syx.ZLQR2_jgxh.WD"; - { - - VideoWall wall; - // wall.setRows(2); - // wall.setCols(3); - wall.resize(982,698); - wall.show(); - wall.setTagList(list1,list2,list3); - wall.showUi(); - wall.loadCamInfo(); - wall.showErrMsg(); - // QString file = "rtsp://admin:kbdct123@192.168.79.231:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1"; - // wall.play(file); - - int result ; - { - result = a.exec(); - } - } - kbd_public::StopLogSystem(); - //<释放消息总线 - kbd_net::releaseMsgBus(); - return 0; -} +/****************************************************************************** + VideoWall: this file is part of QtAV examples + Copyright (C) 2012-2016 Wang Bin + +* This file is part of QtAV + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "VideoWall.h" +#include +#include "net_msg_bus_api/MsgBusApi.h" +#include + +void append(QVariantList &list1,QVariantList &list2,QVariantList &list3) +{ + size_t size = QInputDialog::getInt(NULL, QString("QInputDialog::getText()"), + QString("Test Ipc Size:")); + for(size_t i = 0;i < size; i++) + { + list1 << 1; + list2 << 4; + list3 << "analog.syx.ZLQR2_jgxh.WD"; + } +} + + +int main(int argc, char *argv[]) +{ + QGuiApplication::setAttribute(Qt::AA_UseDesktopOpenGL); + kbd_public::StartLogSystem("BASE","ipcwall"); + + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + + QApplication a(argc, argv); + + QVariantList list1,list2,list3; + append(list1,list2,list3); +// list1 << 1 << 1 << 1 << 1 << 1 << 1; +// list2 << 4 << 4 << 4 << 4 << 4 << 4; +// list3 << "analog.syx.ZLQR2_jgxh.WD"; +// list3 << "analog.syx.ZLQR2_jgxh.WD"; +// list3 << "analog.syx.ZLQR2_jgxh.WD"; +// list3 << "analog.syx.ZLQR2_jgxh.WD"; +// list3 << "analog.syx.ZLQR2_jgxh.WD"; +// list3 << "analog.syx.ZLQR2_jgxh.WD"; + { + + VideoWall wall; + // wall.setRows(2); + // wall.setCols(3); + wall.resize(982,698); + wall.show(); + wall.setTagList(list1,list2,list3); + wall.showUi(); + wall.loadCamInfo(); + wall.showErrMsg(); + // QString file = "rtsp://admin:kbdct123@192.168.79.231:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1"; + // wall.play(file); + + int result ; + { + result = a.exec(); + } + } + kbd_public::StopLogSystem(); + //<释放消息总线 + kbd_net::releaseMsgBus(); + return 0; +} diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitCommon.h b/product/src/gui/plugin/LimitOptWidget/CLimitCommon.h index f8263d46..664d8849 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitCommon.h +++ b/product/src/gui/plugin/LimitOptWidget/CLimitCommon.h @@ -1,44 +1,44 @@ -#ifndef CLIMITCOMMON_H -#define CLIMITCOMMON_H - -#include - -//< 限值信息 -struct ST_TAG_LIMIT -{ - QString tag_name; - QString description; - QString device; - QString deviceGroup; - int limit_type; - int is_limit; - float limit_num; - float limit_up1; - float limit_low1; - float limit_up2; - float limit_low2; - float limit_up3; - float limit_low3; - int location_id; - int region_id; - int domain_id; - int app_id; -}; - -//< 是否越限 -enum EN_LIMIT -{ - LIMIT_DISABLE = 0, - LIMIT_ENABLE -}; - -//< 越限级别 -enum EN_LIMIT_NUM -{ - LIMIT_NUM_0 = 0, - LIMIT_NUM_1, - LIMIT_NUM_2, - LIMIT_NUM_3 -}; - -#endif // CLIMITCOMMON_H +#ifndef CLIMITCOMMON_H +#define CLIMITCOMMON_H + +#include + +//< 限值信息 +struct ST_TAG_LIMIT +{ + QString tag_name; + QString description; + QString device; + QString deviceGroup; + int limit_type; + int is_limit; + float limit_num; + float limit_up1; + float limit_low1; + float limit_up2; + float limit_low2; + float limit_up3; + float limit_low3; + int location_id; + int region_id; + int domain_id; + int app_id; +}; + +//< 是否越限 +enum EN_LIMIT +{ + LIMIT_DISABLE = 0, + LIMIT_ENABLE +}; + +//< 越限级别 +enum EN_LIMIT_NUM +{ + LIMIT_NUM_0 = 0, + LIMIT_NUM_1, + LIMIT_NUM_2, + LIMIT_NUM_3 +}; + +#endif // CLIMITCOMMON_H diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.cpp b/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.cpp index b7342ff5..c09eee42 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.cpp +++ b/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.cpp @@ -1,676 +1,676 @@ -#include "CLimitOptWidget.h" -#include "ui_CLimitOptWidget.h" -#include "CTableDelegate.h" -#include "CLimitOptWork.h" -#include "public/pub_logger_api/logger.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include -#include - -using namespace kbd_public; - -CLimitOptWidget::CLimitOptWidget(QWidget *parent, bool editModel) : - QWidget(parent), - m_ptrSysInfo(Q_NULLPTR), - m_pLimitOptWork(Q_NULLPTR), - ui(new Ui::CLimitOptWidget) -{ - ui->setupUi(this); - - initStyleSheet(); - initView(); - - if(!editModel) - { - initData(); - } -} - -CLimitOptWidget::~CLimitOptWidget() -{ - if(m_pLimitOptWork) - { - delete m_pLimitOptWork; - } - m_pLimitOptWork = Q_NULLPTR; - - delete ui; -} - -void CLimitOptWidget::addPoints(const QStringList &tagList) -{ - QString tagName; - QString pointTag; - int domainId; - int appId; - for(int nIndex(0); nIndex < tagList.length(); nIndex++) - { - tagName = tagList[nIndex]; - if(tagName.split(".").length() != 7) - { - LOGINFO("限值设置添加测点:忽略无效测点 [%s]", tagName.toStdString().c_str()); - continue; - } - if(truncTag(tagName, "table") != "analog") - { - LOGINFO("限值设置添加测点:忽略非模拟量测点 [%s]", tagName.toStdString().c_str()); - continue; - } - appId = getAppIdBySubName(truncTag(tagName, "sub")); - domainId = getDomainIdByLocName(truncTag(tagName, "location")); - m_objRdbNetApi.connect(domainId, appId); - - //< 查询 analog - pointTag = truncTag(tagName, "p"); - std::vector vecKeyP; - vecKeyP.push_back(pointTag.toStdString()); - std::vector vecColumnP; - vecColumnP.push_back("description"); - vecColumnP.push_back("device"); - vecColumnP.push_back("is_limit"); - vecColumnP.push_back("location_id"); - vecColumnP.push_back("region_id"); - kbd_idlfile::RdbRet objRetl; - if(false == m_objRdbNetApi.queryByKey("analog", vecKeyP, vecColumnP, objRetl)) - { - LOGINFO("限值设置添加测点:查询模拟量测点失败 [%s]", tagName.toStdString().c_str()); - continue; - } - ST_TAG_LIMIT st_Tag_Limit; - st_Tag_Limit.domain_id = domainId; - st_Tag_Limit.app_id = appId; - for(int i=0; i < objRetl.msgrecord_size(); i++) - { - st_Tag_Limit.tag_name = pointTag; - st_Tag_Limit.description = QString::fromStdString(objRetl.msgrecord(i).msgvaluearray(0).strvalue()); - st_Tag_Limit.device = QString::fromStdString(objRetl.msgrecord(i).msgvaluearray(1).strvalue()); - st_Tag_Limit.is_limit = objRetl.msgrecord(i).msgvaluearray(2).nvalue(); - st_Tag_Limit.location_id = objRetl.msgrecord(i).msgvaluearray(3).nvalue(); - st_Tag_Limit.region_id = objRetl.msgrecord(i).msgvaluearray(4).nvalue(); - } - - //< 查询 dev_info - std::vector vecKeyD; - vecKeyD.push_back(st_Tag_Limit.device.toStdString()); - std::vector vecColumnD; - vecColumnD.push_back("description"); - vecColumnD.push_back("group_tag_name"); - kbd_idlfile::RdbRet objRetlD; - if(false == m_objRdbNetApi.queryByKey("dev_info", vecKeyD, vecColumnD, objRetlD)) - { - LOGINFO("限值设置添加测点:查询设备信息失败 [%s]", tagName.toStdString().c_str()); - continue; - } - for(int i=0; i < objRetlD.msgrecord_size(); i++) - { - st_Tag_Limit.device = QString::fromStdString(objRetlD.msgrecord(i).msgvaluearray(0).strvalue()); - st_Tag_Limit.deviceGroup = QString::fromStdString(objRetlD.msgrecord(i).msgvaluearray(1).strvalue()); - } - - //< 查询 dev_group - st_Tag_Limit.deviceGroup = getDevGroupDesc(st_Tag_Limit.deviceGroup); - - //< 查询 analog_limit_info - if(st_Tag_Limit.is_limit == LIMIT_ENABLE) - { - std::vector vecKeyLimit; - vecKeyLimit.push_back(pointTag.toStdString()); - std::vector vecColumnLimit; - vecColumnLimit.push_back("limit_type"); - vecColumnLimit.push_back("limit_num"); - vecColumnLimit.push_back("limit_up1"); - vecColumnLimit.push_back("limit_low1"); - vecColumnLimit.push_back("limit_up2"); - vecColumnLimit.push_back("limit_low2"); - vecColumnLimit.push_back("limit_up3"); - vecColumnLimit.push_back("limit_low3"); - kbd_idlfile::RdbRet objRetLimit; - if(false == m_objRdbNetApi.queryByKey("analog_limit_info", vecKeyLimit, vecColumnLimit, objRetLimit)) - { - LOGINFO("限值设置添加测点:查询模拟量越限信息失败 [%s]", tagName.toStdString().c_str()); - continue; - } - for(int i=0; i < objRetLimit.msgrecord_size(); i++) - { - st_Tag_Limit.limit_type = objRetLimit.msgrecord(i).msgvaluearray(0).nvalue(); - st_Tag_Limit.limit_num = objRetLimit.msgrecord(i).msgvaluearray(1).nvalue(); - st_Tag_Limit.limit_up1 = objRetLimit.msgrecord(i).msgvaluearray(2).dvalue(); - st_Tag_Limit.limit_low1 = objRetLimit.msgrecord(i).msgvaluearray(3).dvalue(); - st_Tag_Limit.limit_up2 = objRetLimit.msgrecord(i).msgvaluearray(4).dvalue(); - st_Tag_Limit.limit_low2 = objRetLimit.msgrecord(i).msgvaluearray(5).dvalue(); - st_Tag_Limit.limit_up3 = objRetLimit.msgrecord(i).msgvaluearray(6).dvalue(); - st_Tag_Limit.limit_low3 = objRetLimit.msgrecord(i).msgvaluearray(7).dvalue(); - } - } - else - { - st_Tag_Limit.limit_type = 1; - st_Tag_Limit.limit_num = 0; - st_Tag_Limit.limit_up1 = 0; - st_Tag_Limit.limit_low1 = 0; - st_Tag_Limit.limit_up2 = 0; - st_Tag_Limit.limit_low2 = 0; - st_Tag_Limit.limit_up3 = 0; - st_Tag_Limit.limit_low3 = 0; - } - - m_tagIndex.insert(pointTag, m_limitList.length()); - m_limitList.push_back(st_Tag_Limit); - } - - updateTableData(); -} - -void CLimitOptWidget::setColumnWidth(int column, int width) -{ - ui->m_tableWidget->setColumnWidth(column, width); -} - -void CLimitOptWidget::setColumnHidden(int column, int hidden) -{ - ui->m_tableWidget->setColumnHidden(column, hidden); -} - -void CLimitOptWidget::slotConfirmClicked() -{ - setOptEnable(false); - QList limitList; - getTableData(limitList); - - QMap, int> limitEnable; - QMap, QList>> limitPara; - QString cmdStr; - m_preLimitList = m_limitList; - for(int nIndex(0); nIndex < limitList.length(); nIndex++) - { - const ST_TAG_LIMIT &st_Tag_Limit = limitList[nIndex]; - int tagIndex = m_tagIndex.value(st_Tag_Limit.tag_name, -1); - if(-1 == tagIndex) - { - LOGINFO("限值保存: 查找点索引失败!"); - continue; - } - if(tagIndex > m_limitList.length()-1) - { - LOGINFO("限值保存: 点索引越限!"); - continue; - } - ST_TAG_LIMIT &pre_Tag_Limit = m_limitList[tagIndex]; - if(pre_Tag_Limit.tag_name != st_Tag_Limit.tag_name) - { - LOGINFO("限值保存: 点索引不一致!"); - continue; - } - QPair domainAppPair = qMakePair(pre_Tag_Limit.domain_id, pre_Tag_Limit.app_id); - bool isChange = false; - if(st_Tag_Limit.is_limit != pre_Tag_Limit.is_limit) - { - cmdStr = pre_Tag_Limit.description + "[" + pre_Tag_Limit.deviceGroup + "-" + pre_Tag_Limit.device + "]"; - limitEnable[qMakePair(st_Tag_Limit.tag_name,cmdStr)] = st_Tag_Limit.is_limit; - pre_Tag_Limit.is_limit = st_Tag_Limit.is_limit; - isChange = true; - } - if(st_Tag_Limit.limit_num != pre_Tag_Limit.limit_num) - { - cmdStr = QString("analog_limit_info.%1.limit_num").arg(st_Tag_Limit.tag_name); - limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_num)); - pre_Tag_Limit.limit_num = st_Tag_Limit.limit_num; - isChange = true; - } - if(st_Tag_Limit.limit_up1 != pre_Tag_Limit.limit_up1) - { - cmdStr = QString("analog_limit_info.%1.limit_up1").arg(st_Tag_Limit.tag_name); - limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_up1)); - pre_Tag_Limit.limit_up1 = st_Tag_Limit.limit_up1; - isChange = true; - } - if(st_Tag_Limit.limit_low1 != pre_Tag_Limit.limit_low1) - { - cmdStr = QString("analog_limit_info.%1.limit_low1").arg(st_Tag_Limit.tag_name); - limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_low1)); - pre_Tag_Limit.limit_low1 = st_Tag_Limit.limit_low1; - isChange = true; - } - if(st_Tag_Limit.limit_up2 != pre_Tag_Limit.limit_up2) - { - cmdStr = QString("analog_limit_info.%1.limit_up2").arg(st_Tag_Limit.tag_name); - limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_up2)); - pre_Tag_Limit.limit_up2 = st_Tag_Limit.limit_up2; - isChange = true; - } - if(st_Tag_Limit.limit_low2 != pre_Tag_Limit.limit_low2) - { - cmdStr = QString("analog_limit_info.%1.limit_low2").arg(st_Tag_Limit.tag_name); - limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_low2)); - pre_Tag_Limit.limit_low2 = st_Tag_Limit.limit_low2; - isChange = true; - } - if(st_Tag_Limit.limit_up3 != pre_Tag_Limit.limit_up3) - { - cmdStr = QString("analog_limit_info.%1.limit_up3").arg(st_Tag_Limit.tag_name); - limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_up3)); - pre_Tag_Limit.limit_up3 = st_Tag_Limit.limit_up3; - isChange = true; - } - if(st_Tag_Limit.limit_low3 != pre_Tag_Limit.limit_low3) - { - cmdStr = QString("analog_limit_info.%1.limit_low3").arg(st_Tag_Limit.tag_name); - limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_low3)); - pre_Tag_Limit.limit_low3 = st_Tag_Limit.limit_low3; - isChange = true; - } - if(isChange) - { - if(false == isValidCheck(st_Tag_Limit)) - { - m_limitList = m_preLimitList; - setOptEnable(true); - return; - } - if(false == checkPerm(pre_Tag_Limit.region_id, pre_Tag_Limit.location_id)) - { - QMessageBox::information(this, tr("提示"), tr("%1[%2-%3], 无标签操作权限!") - .arg(pre_Tag_Limit.description) - .arg(pre_Tag_Limit.deviceGroup) - .arg(pre_Tag_Limit.device), QMessageBox::Ok); - m_limitList = m_preLimitList; - setOptEnable(true); - return; - } - } - } - - if(m_pLimitOptWork) - { - QString errorStr; - if(false == m_pLimitOptWork->executeCmd(limitEnable, limitPara, errorStr)) - { - m_limitList = m_preLimitList; - QMessageBox::information(this, tr("提示"), errorStr, QMessageBox::Ok); - } - else - { - updateTableData(); - QMessageBox::information(this, tr("提示"), tr("设置成功"), QMessageBox::Ok); - } - } - setOptEnable(true); -} - -void CLimitOptWidget::slotCancelClicked() -{ - emit closeWnd(); -} - -void CLimitOptWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CLimitOptWidget::initView() -{ - ui->m_tableWidget->horizontalHeader()->setStretchLastSection(true); - ui->m_tableWidget->setColumnCount(9); - ui->m_tableWidget->setHorizontalHeaderLabels(QStringList() - << tr("设备属性") - << tr("是否越限") - << tr("越限级别") - << tr("越上限") - << tr("越下限") - << tr("越上上限") - << tr("越下下限") - << tr("越三级上限") - << tr("越三级下限")); - ui->m_tableWidget->hideColumn(COLUMN_UP3); - ui->m_tableWidget->hideColumn(COLUMN_LOW3); - ui->m_tableWidget->setColumnWidth(COLUMN_TAG, 320); - ui->m_tableWidget->setColumnWidth(COLUMN_LIMIT, 70); - ui->m_tableWidget->setColumnWidth(COLUMN_NUM, 95); - ui->m_tableWidget->setColumnWidth(COLUMN_UP1, 75); - ui->m_tableWidget->setColumnWidth(COLUMN_LOW1, 75); - ui->m_tableWidget->setColumnWidth(COLUMN_UP2, 75); - ui->m_tableWidget->setColumnWidth(COLUMN_LOW2, 75); - ui->m_tableWidget->setColumnWidth(COLUMN_UP3, 75); - ui->m_tableWidget->setColumnWidth(COLUMN_LOW3, 75); -} - -void CLimitOptWidget::initData() -{ - CTableDelegate * desc = new CTableDelegate(ui->m_tableWidget, CTableDelegate::ReadOnly); - CTableDelegate * limit = new CTableDelegate(ui->m_tableWidget, CTableDelegate::ComboBox); - CTableDelegate * limit_num = new CTableDelegate(ui->m_tableWidget, CTableDelegate::ComboBox); - ui->m_tableWidget->setItemDelegateForColumn(0, desc); - ui->m_tableWidget->setItemDelegateForColumn(1, limit); - ui->m_tableWidget->setItemDelegateForColumn(2, limit_num); - limit->setComboxMap(getLimitMap()); - limit_num->setComboxMap(getLimitNumMap()); - - connect(ui->m_confirm, &QPushButton::clicked, this, &CLimitOptWidget::slotConfirmClicked); - connect(ui->m_cancel, &QPushButton::clicked, this, &CLimitOptWidget::slotCancelClicked); - - initSysInfo(); - initPermMng(); - loadLocDomainMap(); -} - -void CLimitOptWidget::updateTableData() -{ - ui->m_tableWidget->clearContents(); - ui->m_tableWidget->setRowCount(0); - int rowCount = 0; - for(int nIndex(0); nIndex < m_limitList.length(); nIndex++) - { - const ST_TAG_LIMIT &st_Tag_Limit = m_limitList[nIndex]; - QTableWidgetItem * tagItem = new QTableWidgetItem(st_Tag_Limit.description + "[" + st_Tag_Limit.deviceGroup + "-" + st_Tag_Limit.device + "]"); - QTableWidgetItem * limitItem = new QTableWidgetItem(getLimitMap().value(st_Tag_Limit.is_limit, tr("未知"))); - QTableWidgetItem * numItem = new QTableWidgetItem(getLimitNumMap().value(st_Tag_Limit.limit_num, tr("未知"))); - QTableWidgetItem * up1Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_up1)); - QTableWidgetItem * low1Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_low1)); - QTableWidgetItem * up2Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_up2)); - QTableWidgetItem * low2Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_low2)); - QTableWidgetItem * up3Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_up3)); - QTableWidgetItem * low3Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_low3)); - tagItem->setData(Qt::UserRole, st_Tag_Limit.tag_name); - limitItem->setData(Qt::UserRole, st_Tag_Limit.is_limit); - numItem->setData(Qt::UserRole, st_Tag_Limit.limit_num); - up1Item->setData(Qt::UserRole, st_Tag_Limit.limit_up1); - low1Item->setData(Qt::UserRole, st_Tag_Limit.limit_low1); - up2Item->setData(Qt::UserRole, st_Tag_Limit.limit_up2); - low2Item->setData(Qt::UserRole, st_Tag_Limit.limit_low2); - up3Item->setData(Qt::UserRole, st_Tag_Limit.limit_up3); - low3Item->setData(Qt::UserRole, st_Tag_Limit.limit_low3); - tagItem->setTextAlignment(Qt::AlignCenter); - limitItem->setTextAlignment(Qt::AlignCenter); - numItem->setTextAlignment(Qt::AlignCenter); - up1Item->setTextAlignment(Qt::AlignCenter); - low1Item->setTextAlignment(Qt::AlignCenter); - up2Item->setTextAlignment(Qt::AlignCenter); - low2Item->setTextAlignment(Qt::AlignCenter); - up3Item->setTextAlignment(Qt::AlignCenter); - low3Item->setTextAlignment(Qt::AlignCenter); - ui->m_tableWidget->insertRow(rowCount); - ui->m_tableWidget->setItem(rowCount, COLUMN_TAG, tagItem); - ui->m_tableWidget->setItem(rowCount, COLUMN_LIMIT, limitItem); - ui->m_tableWidget->setItem(rowCount, COLUMN_NUM, numItem); - ui->m_tableWidget->setItem(rowCount, COLUMN_UP1, up1Item); - ui->m_tableWidget->setItem(rowCount, COLUMN_LOW1, low1Item); - ui->m_tableWidget->setItem(rowCount, COLUMN_UP2, up2Item); - ui->m_tableWidget->setItem(rowCount, COLUMN_LOW2, low2Item); - ui->m_tableWidget->setItem(rowCount, COLUMN_UP3, up3Item); - ui->m_tableWidget->setItem(rowCount, COLUMN_LOW3, low3Item); - rowCount++; - } -} - -void CLimitOptWidget::getTableData(QList &limitList) -{ - int rowCount = ui->m_tableWidget->rowCount(); - for(int nIndex(0); nIndex < rowCount; nIndex++) - { - ST_TAG_LIMIT st_Tag_Limit; - st_Tag_Limit.tag_name = ui->m_tableWidget->item(nIndex, COLUMN_TAG)->data(Qt::UserRole).toString(); - st_Tag_Limit.is_limit = ui->m_tableWidget->item(nIndex, COLUMN_LIMIT)->data(Qt::UserRole).toInt(); - st_Tag_Limit.limit_num = ui->m_tableWidget->item(nIndex, COLUMN_NUM)->data(Qt::UserRole).toInt(); - st_Tag_Limit.limit_up1 = ui->m_tableWidget->item(nIndex, COLUMN_UP1)->data(Qt::DisplayRole).toFloat(); - st_Tag_Limit.limit_low1 = ui->m_tableWidget->item(nIndex, COLUMN_LOW1)->data(Qt::DisplayRole).toFloat(); - st_Tag_Limit.limit_up2 = ui->m_tableWidget->item(nIndex, COLUMN_UP2)->data(Qt::DisplayRole).toFloat(); - st_Tag_Limit.limit_low2 = ui->m_tableWidget->item(nIndex, COLUMN_LOW2)->data(Qt::DisplayRole).toFloat(); - st_Tag_Limit.limit_up3 = ui->m_tableWidget->item(nIndex, COLUMN_UP3)->data(Qt::DisplayRole).toFloat(); - st_Tag_Limit.limit_low3 = ui->m_tableWidget->item(nIndex, COLUMN_LOW3)->data(Qt::DisplayRole).toFloat(); - limitList.push_back(st_Tag_Limit); - } -} - -bool CLimitOptWidget::isValidCheck(const ST_TAG_LIMIT &st_Tag_Limit) -{ - if(st_Tag_Limit.is_limit == LIMIT_DISABLE) - { - return true; - } - if(st_Tag_Limit.limit_num <= 0) - { - return true; - } - if(st_Tag_Limit.limit_low1 >= st_Tag_Limit.limit_up1) - { - QMessageBox::information(this, tr("提示"), tr("越上限应大于越下限!") , QMessageBox::Ok); - return false; - } - if(st_Tag_Limit.limit_num <= 1) - { - return true; - } - if(st_Tag_Limit.limit_low2 >= st_Tag_Limit.limit_up2) - { - QMessageBox::information(this, tr("提示"), tr("越上上限应大于越下下限!") , QMessageBox::Ok); - return false; - } - if(st_Tag_Limit.limit_low2 >= st_Tag_Limit.limit_low1) - { - QMessageBox::information(this, tr("提示"), tr("越下下限应小于越下限!") , QMessageBox::Ok); - return false; - } - if(st_Tag_Limit.limit_up2 <= st_Tag_Limit.limit_up1) - { - QMessageBox::information(this, tr("提示"), tr("越上上限应大于越上限!") , QMessageBox::Ok); - return false; - } - -// if(st_Tag_Limit.limit_low3 >= st_Tag_Limit.limit_up3) -// { -// QMessageBox::information(this, tr("提示"), tr("越三级上限应大于越三级下限!") , QMessageBox::Ok); -// return false; -// } -// if(st_Tag_Limit.limit_low3 >= st_Tag_Limit.limit_low2) -// { -// QMessageBox::information(this, tr("提示"), tr("越三级下限应小于越下下限!") , QMessageBox::Ok); -// return false; -// } -// if(st_Tag_Limit.limit_up3 <= st_Tag_Limit.limit_up2) -// { -// QMessageBox::information(this, tr("提示"), tr("越三级上限应大于越上上限!") , QMessageBox::Ok); -// return false; -// } - return true; -} - -void CLimitOptWidget::initSysInfo() -{ - if (!createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("限值设置创建系统信息访问库实例失败!"); - } - m_pLimitOptWork = new CLimitOptWork; -} - -void CLimitOptWidget::initPermMng() -{ - kbd_service::CPermMngApiPtr ptrPermMng = kbd_service::getPermMngInstance("base"); - if(ptrPermMng == NULL || (PERM_NORMAL != ptrPermMng->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return; - } - std::string tmp = "FUNC_SPE_OPT_OVERRIDE"; - if(PERM_NORMAL > ptrPermMng->GetSpeFunc(tmp, m_vecPermRegionId, m_vecPermLocationId)) - { - LOGERROR("权限接口获取当前登录用户的特殊功能责任区和车站信息失败!"); - return; - } -} - -bool CLimitOptWidget::checkPerm(int regionId, int locationId) -{ - std::vector::iterator rIter = std::find_if(m_vecPermRegionId.begin(), m_vecPermRegionId.end(), [=](int a){return a==regionId;}); - if(rIter == m_vecPermRegionId.end()) - { - return false; - } - - std::vector::iterator lIter = std::find_if(m_vecPermLocationId.begin(), m_vecPermLocationId.end(), [=](int a){return a==locationId;}); - if(lIter == m_vecPermLocationId.end()) - { - return false; - } - - return true; -} - -void CLimitOptWidget::loadLocDomainMap() -{ - if(false == m_objRdbApi.open("BASE", "sys_model_location_info")) - { - LOGERROR("限值设置加载厂站信息失败: [%s]", m_objRdbApi.getErrorMsg().c_str()); - return; - } - kbd_dbms::CRdbQueryResult oResult; - std::vector vecSelectColumn; - vecSelectColumn.push_back("tag_name"); - vecSelectColumn.push_back("domain_id"); - if(false == m_objRdbApi.select(oResult, vecSelectColumn)) - { - LOGERROR("限值设置加载厂站信息失败: [%s]", m_objRdbApi.getErrorMsg().c_str()); - m_objRdbApi.close(); - return; - } - m_objRdbApi.close(); - - m_locDomainMap.clear(); - for(int nIndex(0); nIndex < oResult.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType tag_name; - kbd_dbms::CVarType domain_id; - oResult.getColumnValue(nIndex, 0, tag_name); - oResult.getColumnValue(nIndex, 1, domain_id); - m_locDomainMap.insert(QString::fromStdString(tag_name.toStdString()), domain_id.toInt()); - } -} - -int CLimitOptWidget::getAppIdBySubName(const QString &subName) -{ - if(m_ptrSysInfo == Q_NULLPTR) - { - return CN_InvalidAppId; - } - SAppInfo stAppInfo; - if(kbdFailed == m_ptrSysInfo->getAppInfoBySubsystemName(subName.toStdString(), stAppInfo)) - { - return CN_InvalidAppId; - } - return stAppInfo.nId; -} - -int CLimitOptWidget::getDomainIdByLocName(const QString &locName) -{ - return m_locDomainMap.value(locName, CN_InvalidDomainId); -} - -QString CLimitOptWidget::getDevGroupDesc(const QString &devGroupTag) -{ - if(false == m_objRdbApi.open("BASE", "dev_group")) - { - LOGERROR("限值设置查询dev_group失败: [%s]", m_objRdbApi.getErrorMsg().c_str()); - return ""; - } - kbd_dbms::CONDINFO oCondInfo; - oCondInfo.relationop = ATTRCOND_EQU; - memcpy(oCondInfo.name, "tag_name", strlen("tag_name")); - oCondInfo.conditionval = devGroupTag.toStdString(); - kbd_dbms::CRdbQueryResult oResult; - std::string sSelectColumn = "description"; - if(false == m_objRdbApi.select(oCondInfo, oResult, sSelectColumn)) - { - LOGERROR("限值设置查询dev_group失败: [%s]", m_objRdbApi.getErrorMsg().c_str()); - m_objRdbApi.close(); - return ""; - } - m_objRdbApi.close(); - - for(int nIndex(0); nIndex < oResult.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType description; - oResult.getColumnValue(nIndex, 0, description); - return QString::fromStdString(description.toStdString()); - } - return ""; -} - -QMap CLimitOptWidget::getLimitMap() -{ - QMap Map; - Map.insert(LIMIT_DISABLE, tr("否")); - Map.insert(LIMIT_ENABLE, tr("是")); - return Map; -} - -QMap CLimitOptWidget::getLimitNumMap() -{ - QMap Map; - Map.insert(LIMIT_NUM_0, tr("无越限")); - Map.insert(LIMIT_NUM_1, tr("一级越限")); - Map.insert(LIMIT_NUM_2, tr("二级越限")); -// Map.insert(LIMIT_NUM_3, tr("三级越限")); - return Map; -} - -QString CLimitOptWidget::truncTag(const QString &tagName, const QString &format) -{ - QString ret = ""; - if(format == "location") - { - ret = tagName.section(".", 0, 0); - } - else if(format == "sub") - { - ret = tagName.section(".", 1, 1); - } - else if(format == "table") - { - ret = tagName.section(".", 2, 2); - } - else if(format == "dev") - { - ret = tagName.section(".", 3, 4); - } - else if(format == "devg") - { - QStringList temp = tagName.section(".", 3, 4).split("_"); - temp.pop_back(); - ret = temp.join("_"); - } - else if(format == "p") - { - ret = tagName.section(".", 3, 5); - } - else if(format == "point") - { - ret = tagName.section(".", 5, 5); - } - else if(format == "v") - { - ret = tagName.section(".", -1, -1); - } - return ret; -} - -void CLimitOptWidget::setOptEnable(bool enable) -{ - ui->m_confirm->setEnabled(enable); - ui->m_cancel->setEnabled(enable); -} +#include "CLimitOptWidget.h" +#include "ui_CLimitOptWidget.h" +#include "CTableDelegate.h" +#include "CLimitOptWork.h" +#include "public/pub_logger_api/logger.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include +#include + +using namespace kbd_public; + +CLimitOptWidget::CLimitOptWidget(QWidget *parent, bool editModel) : + QWidget(parent), + m_ptrSysInfo(Q_NULLPTR), + m_pLimitOptWork(Q_NULLPTR), + ui(new Ui::CLimitOptWidget) +{ + ui->setupUi(this); + + initStyleSheet(); + initView(); + + if(!editModel) + { + initData(); + } +} + +CLimitOptWidget::~CLimitOptWidget() +{ + if(m_pLimitOptWork) + { + delete m_pLimitOptWork; + } + m_pLimitOptWork = Q_NULLPTR; + + delete ui; +} + +void CLimitOptWidget::addPoints(const QStringList &tagList) +{ + QString tagName; + QString pointTag; + int domainId; + int appId; + for(int nIndex(0); nIndex < tagList.length(); nIndex++) + { + tagName = tagList[nIndex]; + if(tagName.split(".").length() != 7) + { + LOGINFO("限值设置添加测点:忽略无效测点 [%s]", tagName.toStdString().c_str()); + continue; + } + if(truncTag(tagName, "table") != "analog") + { + LOGINFO("限值设置添加测点:忽略非模拟量测点 [%s]", tagName.toStdString().c_str()); + continue; + } + appId = getAppIdBySubName(truncTag(tagName, "sub")); + domainId = getDomainIdByLocName(truncTag(tagName, "location")); + m_objRdbNetApi.connect(domainId, appId); + + //< 查询 analog + pointTag = truncTag(tagName, "p"); + std::vector vecKeyP; + vecKeyP.push_back(pointTag.toStdString()); + std::vector vecColumnP; + vecColumnP.push_back("description"); + vecColumnP.push_back("device"); + vecColumnP.push_back("is_limit"); + vecColumnP.push_back("location_id"); + vecColumnP.push_back("region_id"); + kbd_idlfile::RdbRet objRetl; + if(false == m_objRdbNetApi.queryByKey("analog", vecKeyP, vecColumnP, objRetl)) + { + LOGINFO("限值设置添加测点:查询模拟量测点失败 [%s]", tagName.toStdString().c_str()); + continue; + } + ST_TAG_LIMIT st_Tag_Limit; + st_Tag_Limit.domain_id = domainId; + st_Tag_Limit.app_id = appId; + for(int i=0; i < objRetl.msgrecord_size(); i++) + { + st_Tag_Limit.tag_name = pointTag; + st_Tag_Limit.description = QString::fromStdString(objRetl.msgrecord(i).msgvaluearray(0).strvalue()); + st_Tag_Limit.device = QString::fromStdString(objRetl.msgrecord(i).msgvaluearray(1).strvalue()); + st_Tag_Limit.is_limit = objRetl.msgrecord(i).msgvaluearray(2).nvalue(); + st_Tag_Limit.location_id = objRetl.msgrecord(i).msgvaluearray(3).nvalue(); + st_Tag_Limit.region_id = objRetl.msgrecord(i).msgvaluearray(4).nvalue(); + } + + //< 查询 dev_info + std::vector vecKeyD; + vecKeyD.push_back(st_Tag_Limit.device.toStdString()); + std::vector vecColumnD; + vecColumnD.push_back("description"); + vecColumnD.push_back("group_tag_name"); + kbd_idlfile::RdbRet objRetlD; + if(false == m_objRdbNetApi.queryByKey("dev_info", vecKeyD, vecColumnD, objRetlD)) + { + LOGINFO("限值设置添加测点:查询设备信息失败 [%s]", tagName.toStdString().c_str()); + continue; + } + for(int i=0; i < objRetlD.msgrecord_size(); i++) + { + st_Tag_Limit.device = QString::fromStdString(objRetlD.msgrecord(i).msgvaluearray(0).strvalue()); + st_Tag_Limit.deviceGroup = QString::fromStdString(objRetlD.msgrecord(i).msgvaluearray(1).strvalue()); + } + + //< 查询 dev_group + st_Tag_Limit.deviceGroup = getDevGroupDesc(st_Tag_Limit.deviceGroup); + + //< 查询 analog_limit_info + if(st_Tag_Limit.is_limit == LIMIT_ENABLE) + { + std::vector vecKeyLimit; + vecKeyLimit.push_back(pointTag.toStdString()); + std::vector vecColumnLimit; + vecColumnLimit.push_back("limit_type"); + vecColumnLimit.push_back("limit_num"); + vecColumnLimit.push_back("limit_up1"); + vecColumnLimit.push_back("limit_low1"); + vecColumnLimit.push_back("limit_up2"); + vecColumnLimit.push_back("limit_low2"); + vecColumnLimit.push_back("limit_up3"); + vecColumnLimit.push_back("limit_low3"); + kbd_idlfile::RdbRet objRetLimit; + if(false == m_objRdbNetApi.queryByKey("analog_limit_info", vecKeyLimit, vecColumnLimit, objRetLimit)) + { + LOGINFO("限值设置添加测点:查询模拟量越限信息失败 [%s]", tagName.toStdString().c_str()); + continue; + } + for(int i=0; i < objRetLimit.msgrecord_size(); i++) + { + st_Tag_Limit.limit_type = objRetLimit.msgrecord(i).msgvaluearray(0).nvalue(); + st_Tag_Limit.limit_num = objRetLimit.msgrecord(i).msgvaluearray(1).nvalue(); + st_Tag_Limit.limit_up1 = objRetLimit.msgrecord(i).msgvaluearray(2).dvalue(); + st_Tag_Limit.limit_low1 = objRetLimit.msgrecord(i).msgvaluearray(3).dvalue(); + st_Tag_Limit.limit_up2 = objRetLimit.msgrecord(i).msgvaluearray(4).dvalue(); + st_Tag_Limit.limit_low2 = objRetLimit.msgrecord(i).msgvaluearray(5).dvalue(); + st_Tag_Limit.limit_up3 = objRetLimit.msgrecord(i).msgvaluearray(6).dvalue(); + st_Tag_Limit.limit_low3 = objRetLimit.msgrecord(i).msgvaluearray(7).dvalue(); + } + } + else + { + st_Tag_Limit.limit_type = 1; + st_Tag_Limit.limit_num = 0; + st_Tag_Limit.limit_up1 = 0; + st_Tag_Limit.limit_low1 = 0; + st_Tag_Limit.limit_up2 = 0; + st_Tag_Limit.limit_low2 = 0; + st_Tag_Limit.limit_up3 = 0; + st_Tag_Limit.limit_low3 = 0; + } + + m_tagIndex.insert(pointTag, m_limitList.length()); + m_limitList.push_back(st_Tag_Limit); + } + + updateTableData(); +} + +void CLimitOptWidget::setColumnWidth(int column, int width) +{ + ui->m_tableWidget->setColumnWidth(column, width); +} + +void CLimitOptWidget::setColumnHidden(int column, int hidden) +{ + ui->m_tableWidget->setColumnHidden(column, hidden); +} + +void CLimitOptWidget::slotConfirmClicked() +{ + setOptEnable(false); + QList limitList; + getTableData(limitList); + + QMap, int> limitEnable; + QMap, QList>> limitPara; + QString cmdStr; + m_preLimitList = m_limitList; + for(int nIndex(0); nIndex < limitList.length(); nIndex++) + { + const ST_TAG_LIMIT &st_Tag_Limit = limitList[nIndex]; + int tagIndex = m_tagIndex.value(st_Tag_Limit.tag_name, -1); + if(-1 == tagIndex) + { + LOGINFO("限值保存: 查找点索引失败!"); + continue; + } + if(tagIndex > m_limitList.length()-1) + { + LOGINFO("限值保存: 点索引越限!"); + continue; + } + ST_TAG_LIMIT &pre_Tag_Limit = m_limitList[tagIndex]; + if(pre_Tag_Limit.tag_name != st_Tag_Limit.tag_name) + { + LOGINFO("限值保存: 点索引不一致!"); + continue; + } + QPair domainAppPair = qMakePair(pre_Tag_Limit.domain_id, pre_Tag_Limit.app_id); + bool isChange = false; + if(st_Tag_Limit.is_limit != pre_Tag_Limit.is_limit) + { + cmdStr = pre_Tag_Limit.description + "[" + pre_Tag_Limit.deviceGroup + "-" + pre_Tag_Limit.device + "]"; + limitEnable[qMakePair(st_Tag_Limit.tag_name,cmdStr)] = st_Tag_Limit.is_limit; + pre_Tag_Limit.is_limit = st_Tag_Limit.is_limit; + isChange = true; + } + if(st_Tag_Limit.limit_num != pre_Tag_Limit.limit_num) + { + cmdStr = QString("analog_limit_info.%1.limit_num").arg(st_Tag_Limit.tag_name); + limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_num)); + pre_Tag_Limit.limit_num = st_Tag_Limit.limit_num; + isChange = true; + } + if(st_Tag_Limit.limit_up1 != pre_Tag_Limit.limit_up1) + { + cmdStr = QString("analog_limit_info.%1.limit_up1").arg(st_Tag_Limit.tag_name); + limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_up1)); + pre_Tag_Limit.limit_up1 = st_Tag_Limit.limit_up1; + isChange = true; + } + if(st_Tag_Limit.limit_low1 != pre_Tag_Limit.limit_low1) + { + cmdStr = QString("analog_limit_info.%1.limit_low1").arg(st_Tag_Limit.tag_name); + limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_low1)); + pre_Tag_Limit.limit_low1 = st_Tag_Limit.limit_low1; + isChange = true; + } + if(st_Tag_Limit.limit_up2 != pre_Tag_Limit.limit_up2) + { + cmdStr = QString("analog_limit_info.%1.limit_up2").arg(st_Tag_Limit.tag_name); + limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_up2)); + pre_Tag_Limit.limit_up2 = st_Tag_Limit.limit_up2; + isChange = true; + } + if(st_Tag_Limit.limit_low2 != pre_Tag_Limit.limit_low2) + { + cmdStr = QString("analog_limit_info.%1.limit_low2").arg(st_Tag_Limit.tag_name); + limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_low2)); + pre_Tag_Limit.limit_low2 = st_Tag_Limit.limit_low2; + isChange = true; + } + if(st_Tag_Limit.limit_up3 != pre_Tag_Limit.limit_up3) + { + cmdStr = QString("analog_limit_info.%1.limit_up3").arg(st_Tag_Limit.tag_name); + limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_up3)); + pre_Tag_Limit.limit_up3 = st_Tag_Limit.limit_up3; + isChange = true; + } + if(st_Tag_Limit.limit_low3 != pre_Tag_Limit.limit_low3) + { + cmdStr = QString("analog_limit_info.%1.limit_low3").arg(st_Tag_Limit.tag_name); + limitPara[domainAppPair].append(qMakePair(cmdStr, st_Tag_Limit.limit_low3)); + pre_Tag_Limit.limit_low3 = st_Tag_Limit.limit_low3; + isChange = true; + } + if(isChange) + { + if(false == isValidCheck(st_Tag_Limit)) + { + m_limitList = m_preLimitList; + setOptEnable(true); + return; + } + if(false == checkPerm(pre_Tag_Limit.region_id, pre_Tag_Limit.location_id)) + { + QMessageBox::information(this, tr("提示"), tr("%1[%2-%3], 无标签操作权限!") + .arg(pre_Tag_Limit.description) + .arg(pre_Tag_Limit.deviceGroup) + .arg(pre_Tag_Limit.device), QMessageBox::Ok); + m_limitList = m_preLimitList; + setOptEnable(true); + return; + } + } + } + + if(m_pLimitOptWork) + { + QString errorStr; + if(false == m_pLimitOptWork->executeCmd(limitEnable, limitPara, errorStr)) + { + m_limitList = m_preLimitList; + QMessageBox::information(this, tr("提示"), errorStr, QMessageBox::Ok); + } + else + { + updateTableData(); + QMessageBox::information(this, tr("提示"), tr("设置成功"), QMessageBox::Ok); + } + } + setOptEnable(true); +} + +void CLimitOptWidget::slotCancelClicked() +{ + emit closeWnd(); +} + +void CLimitOptWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CLimitOptWidget::initView() +{ + ui->m_tableWidget->horizontalHeader()->setStretchLastSection(true); + ui->m_tableWidget->setColumnCount(9); + ui->m_tableWidget->setHorizontalHeaderLabels(QStringList() + << tr("设备属性") + << tr("是否越限") + << tr("越限级别") + << tr("越上限") + << tr("越下限") + << tr("越上上限") + << tr("越下下限") + << tr("越三级上限") + << tr("越三级下限")); + ui->m_tableWidget->hideColumn(COLUMN_UP3); + ui->m_tableWidget->hideColumn(COLUMN_LOW3); + ui->m_tableWidget->setColumnWidth(COLUMN_TAG, 320); + ui->m_tableWidget->setColumnWidth(COLUMN_LIMIT, 70); + ui->m_tableWidget->setColumnWidth(COLUMN_NUM, 95); + ui->m_tableWidget->setColumnWidth(COLUMN_UP1, 75); + ui->m_tableWidget->setColumnWidth(COLUMN_LOW1, 75); + ui->m_tableWidget->setColumnWidth(COLUMN_UP2, 75); + ui->m_tableWidget->setColumnWidth(COLUMN_LOW2, 75); + ui->m_tableWidget->setColumnWidth(COLUMN_UP3, 75); + ui->m_tableWidget->setColumnWidth(COLUMN_LOW3, 75); +} + +void CLimitOptWidget::initData() +{ + CTableDelegate * desc = new CTableDelegate(ui->m_tableWidget, CTableDelegate::ReadOnly); + CTableDelegate * limit = new CTableDelegate(ui->m_tableWidget, CTableDelegate::ComboBox); + CTableDelegate * limit_num = new CTableDelegate(ui->m_tableWidget, CTableDelegate::ComboBox); + ui->m_tableWidget->setItemDelegateForColumn(0, desc); + ui->m_tableWidget->setItemDelegateForColumn(1, limit); + ui->m_tableWidget->setItemDelegateForColumn(2, limit_num); + limit->setComboxMap(getLimitMap()); + limit_num->setComboxMap(getLimitNumMap()); + + connect(ui->m_confirm, &QPushButton::clicked, this, &CLimitOptWidget::slotConfirmClicked); + connect(ui->m_cancel, &QPushButton::clicked, this, &CLimitOptWidget::slotCancelClicked); + + initSysInfo(); + initPermMng(); + loadLocDomainMap(); +} + +void CLimitOptWidget::updateTableData() +{ + ui->m_tableWidget->clearContents(); + ui->m_tableWidget->setRowCount(0); + int rowCount = 0; + for(int nIndex(0); nIndex < m_limitList.length(); nIndex++) + { + const ST_TAG_LIMIT &st_Tag_Limit = m_limitList[nIndex]; + QTableWidgetItem * tagItem = new QTableWidgetItem(st_Tag_Limit.description + "[" + st_Tag_Limit.deviceGroup + "-" + st_Tag_Limit.device + "]"); + QTableWidgetItem * limitItem = new QTableWidgetItem(getLimitMap().value(st_Tag_Limit.is_limit, tr("未知"))); + QTableWidgetItem * numItem = new QTableWidgetItem(getLimitNumMap().value(st_Tag_Limit.limit_num, tr("未知"))); + QTableWidgetItem * up1Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_up1)); + QTableWidgetItem * low1Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_low1)); + QTableWidgetItem * up2Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_up2)); + QTableWidgetItem * low2Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_low2)); + QTableWidgetItem * up3Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_up3)); + QTableWidgetItem * low3Item = new QTableWidgetItem(QString::number(st_Tag_Limit.limit_low3)); + tagItem->setData(Qt::UserRole, st_Tag_Limit.tag_name); + limitItem->setData(Qt::UserRole, st_Tag_Limit.is_limit); + numItem->setData(Qt::UserRole, st_Tag_Limit.limit_num); + up1Item->setData(Qt::UserRole, st_Tag_Limit.limit_up1); + low1Item->setData(Qt::UserRole, st_Tag_Limit.limit_low1); + up2Item->setData(Qt::UserRole, st_Tag_Limit.limit_up2); + low2Item->setData(Qt::UserRole, st_Tag_Limit.limit_low2); + up3Item->setData(Qt::UserRole, st_Tag_Limit.limit_up3); + low3Item->setData(Qt::UserRole, st_Tag_Limit.limit_low3); + tagItem->setTextAlignment(Qt::AlignCenter); + limitItem->setTextAlignment(Qt::AlignCenter); + numItem->setTextAlignment(Qt::AlignCenter); + up1Item->setTextAlignment(Qt::AlignCenter); + low1Item->setTextAlignment(Qt::AlignCenter); + up2Item->setTextAlignment(Qt::AlignCenter); + low2Item->setTextAlignment(Qt::AlignCenter); + up3Item->setTextAlignment(Qt::AlignCenter); + low3Item->setTextAlignment(Qt::AlignCenter); + ui->m_tableWidget->insertRow(rowCount); + ui->m_tableWidget->setItem(rowCount, COLUMN_TAG, tagItem); + ui->m_tableWidget->setItem(rowCount, COLUMN_LIMIT, limitItem); + ui->m_tableWidget->setItem(rowCount, COLUMN_NUM, numItem); + ui->m_tableWidget->setItem(rowCount, COLUMN_UP1, up1Item); + ui->m_tableWidget->setItem(rowCount, COLUMN_LOW1, low1Item); + ui->m_tableWidget->setItem(rowCount, COLUMN_UP2, up2Item); + ui->m_tableWidget->setItem(rowCount, COLUMN_LOW2, low2Item); + ui->m_tableWidget->setItem(rowCount, COLUMN_UP3, up3Item); + ui->m_tableWidget->setItem(rowCount, COLUMN_LOW3, low3Item); + rowCount++; + } +} + +void CLimitOptWidget::getTableData(QList &limitList) +{ + int rowCount = ui->m_tableWidget->rowCount(); + for(int nIndex(0); nIndex < rowCount; nIndex++) + { + ST_TAG_LIMIT st_Tag_Limit; + st_Tag_Limit.tag_name = ui->m_tableWidget->item(nIndex, COLUMN_TAG)->data(Qt::UserRole).toString(); + st_Tag_Limit.is_limit = ui->m_tableWidget->item(nIndex, COLUMN_LIMIT)->data(Qt::UserRole).toInt(); + st_Tag_Limit.limit_num = ui->m_tableWidget->item(nIndex, COLUMN_NUM)->data(Qt::UserRole).toInt(); + st_Tag_Limit.limit_up1 = ui->m_tableWidget->item(nIndex, COLUMN_UP1)->data(Qt::DisplayRole).toFloat(); + st_Tag_Limit.limit_low1 = ui->m_tableWidget->item(nIndex, COLUMN_LOW1)->data(Qt::DisplayRole).toFloat(); + st_Tag_Limit.limit_up2 = ui->m_tableWidget->item(nIndex, COLUMN_UP2)->data(Qt::DisplayRole).toFloat(); + st_Tag_Limit.limit_low2 = ui->m_tableWidget->item(nIndex, COLUMN_LOW2)->data(Qt::DisplayRole).toFloat(); + st_Tag_Limit.limit_up3 = ui->m_tableWidget->item(nIndex, COLUMN_UP3)->data(Qt::DisplayRole).toFloat(); + st_Tag_Limit.limit_low3 = ui->m_tableWidget->item(nIndex, COLUMN_LOW3)->data(Qt::DisplayRole).toFloat(); + limitList.push_back(st_Tag_Limit); + } +} + +bool CLimitOptWidget::isValidCheck(const ST_TAG_LIMIT &st_Tag_Limit) +{ + if(st_Tag_Limit.is_limit == LIMIT_DISABLE) + { + return true; + } + if(st_Tag_Limit.limit_num <= 0) + { + return true; + } + if(st_Tag_Limit.limit_low1 >= st_Tag_Limit.limit_up1) + { + QMessageBox::information(this, tr("提示"), tr("越上限应大于越下限!") , QMessageBox::Ok); + return false; + } + if(st_Tag_Limit.limit_num <= 1) + { + return true; + } + if(st_Tag_Limit.limit_low2 >= st_Tag_Limit.limit_up2) + { + QMessageBox::information(this, tr("提示"), tr("越上上限应大于越下下限!") , QMessageBox::Ok); + return false; + } + if(st_Tag_Limit.limit_low2 >= st_Tag_Limit.limit_low1) + { + QMessageBox::information(this, tr("提示"), tr("越下下限应小于越下限!") , QMessageBox::Ok); + return false; + } + if(st_Tag_Limit.limit_up2 <= st_Tag_Limit.limit_up1) + { + QMessageBox::information(this, tr("提示"), tr("越上上限应大于越上限!") , QMessageBox::Ok); + return false; + } + +// if(st_Tag_Limit.limit_low3 >= st_Tag_Limit.limit_up3) +// { +// QMessageBox::information(this, tr("提示"), tr("越三级上限应大于越三级下限!") , QMessageBox::Ok); +// return false; +// } +// if(st_Tag_Limit.limit_low3 >= st_Tag_Limit.limit_low2) +// { +// QMessageBox::information(this, tr("提示"), tr("越三级下限应小于越下下限!") , QMessageBox::Ok); +// return false; +// } +// if(st_Tag_Limit.limit_up3 <= st_Tag_Limit.limit_up2) +// { +// QMessageBox::information(this, tr("提示"), tr("越三级上限应大于越上上限!") , QMessageBox::Ok); +// return false; +// } + return true; +} + +void CLimitOptWidget::initSysInfo() +{ + if (!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("限值设置创建系统信息访问库实例失败!"); + } + m_pLimitOptWork = new CLimitOptWork; +} + +void CLimitOptWidget::initPermMng() +{ + kbd_service::CPermMngApiPtr ptrPermMng = kbd_service::getPermMngInstance("base"); + if(ptrPermMng == NULL || (PERM_NORMAL != ptrPermMng->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + std::string tmp = "FUNC_SPE_OPT_OVERRIDE"; + if(PERM_NORMAL > ptrPermMng->GetSpeFunc(tmp, m_vecPermRegionId, m_vecPermLocationId)) + { + LOGERROR("权限接口获取当前登录用户的特殊功能责任区和车站信息失败!"); + return; + } +} + +bool CLimitOptWidget::checkPerm(int regionId, int locationId) +{ + std::vector::iterator rIter = std::find_if(m_vecPermRegionId.begin(), m_vecPermRegionId.end(), [=](int a){return a==regionId;}); + if(rIter == m_vecPermRegionId.end()) + { + return false; + } + + std::vector::iterator lIter = std::find_if(m_vecPermLocationId.begin(), m_vecPermLocationId.end(), [=](int a){return a==locationId;}); + if(lIter == m_vecPermLocationId.end()) + { + return false; + } + + return true; +} + +void CLimitOptWidget::loadLocDomainMap() +{ + if(false == m_objRdbApi.open("BASE", "sys_model_location_info")) + { + LOGERROR("限值设置加载厂站信息失败: [%s]", m_objRdbApi.getErrorMsg().c_str()); + return; + } + kbd_dbms::CRdbQueryResult oResult; + std::vector vecSelectColumn; + vecSelectColumn.push_back("tag_name"); + vecSelectColumn.push_back("domain_id"); + if(false == m_objRdbApi.select(oResult, vecSelectColumn)) + { + LOGERROR("限值设置加载厂站信息失败: [%s]", m_objRdbApi.getErrorMsg().c_str()); + m_objRdbApi.close(); + return; + } + m_objRdbApi.close(); + + m_locDomainMap.clear(); + for(int nIndex(0); nIndex < oResult.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType tag_name; + kbd_dbms::CVarType domain_id; + oResult.getColumnValue(nIndex, 0, tag_name); + oResult.getColumnValue(nIndex, 1, domain_id); + m_locDomainMap.insert(QString::fromStdString(tag_name.toStdString()), domain_id.toInt()); + } +} + +int CLimitOptWidget::getAppIdBySubName(const QString &subName) +{ + if(m_ptrSysInfo == Q_NULLPTR) + { + return CN_InvalidAppId; + } + SAppInfo stAppInfo; + if(kbdFailed == m_ptrSysInfo->getAppInfoBySubsystemName(subName.toStdString(), stAppInfo)) + { + return CN_InvalidAppId; + } + return stAppInfo.nId; +} + +int CLimitOptWidget::getDomainIdByLocName(const QString &locName) +{ + return m_locDomainMap.value(locName, CN_InvalidDomainId); +} + +QString CLimitOptWidget::getDevGroupDesc(const QString &devGroupTag) +{ + if(false == m_objRdbApi.open("BASE", "dev_group")) + { + LOGERROR("限值设置查询dev_group失败: [%s]", m_objRdbApi.getErrorMsg().c_str()); + return ""; + } + kbd_dbms::CONDINFO oCondInfo; + oCondInfo.relationop = ATTRCOND_EQU; + memcpy(oCondInfo.name, "tag_name", strlen("tag_name")); + oCondInfo.conditionval = devGroupTag.toStdString(); + kbd_dbms::CRdbQueryResult oResult; + std::string sSelectColumn = "description"; + if(false == m_objRdbApi.select(oCondInfo, oResult, sSelectColumn)) + { + LOGERROR("限值设置查询dev_group失败: [%s]", m_objRdbApi.getErrorMsg().c_str()); + m_objRdbApi.close(); + return ""; + } + m_objRdbApi.close(); + + for(int nIndex(0); nIndex < oResult.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType description; + oResult.getColumnValue(nIndex, 0, description); + return QString::fromStdString(description.toStdString()); + } + return ""; +} + +QMap CLimitOptWidget::getLimitMap() +{ + QMap Map; + Map.insert(LIMIT_DISABLE, tr("否")); + Map.insert(LIMIT_ENABLE, tr("是")); + return Map; +} + +QMap CLimitOptWidget::getLimitNumMap() +{ + QMap Map; + Map.insert(LIMIT_NUM_0, tr("无越限")); + Map.insert(LIMIT_NUM_1, tr("一级越限")); + Map.insert(LIMIT_NUM_2, tr("二级越限")); +// Map.insert(LIMIT_NUM_3, tr("三级越限")); + return Map; +} + +QString CLimitOptWidget::truncTag(const QString &tagName, const QString &format) +{ + QString ret = ""; + if(format == "location") + { + ret = tagName.section(".", 0, 0); + } + else if(format == "sub") + { + ret = tagName.section(".", 1, 1); + } + else if(format == "table") + { + ret = tagName.section(".", 2, 2); + } + else if(format == "dev") + { + ret = tagName.section(".", 3, 4); + } + else if(format == "devg") + { + QStringList temp = tagName.section(".", 3, 4).split("_"); + temp.pop_back(); + ret = temp.join("_"); + } + else if(format == "p") + { + ret = tagName.section(".", 3, 5); + } + else if(format == "point") + { + ret = tagName.section(".", 5, 5); + } + else if(format == "v") + { + ret = tagName.section(".", -1, -1); + } + return ret; +} + +void CLimitOptWidget::setOptEnable(bool enable) +{ + ui->m_confirm->setEnabled(enable); + ui->m_cancel->setEnabled(enable); +} diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.h b/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.h index 4efb0b67..00d055bf 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.h +++ b/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.h @@ -1,105 +1,105 @@ -#ifndef CLIMITOPTWIDGET_H -#define CLIMITOPTWIDGET_H - -#include -#include -#include "CLimitCommon.h" -#include "rdb_api/CRdbAccess.h" -#include "rdb_net_api/CRdbNetApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" - -namespace Ui { -class CLimitOptWidget; -} - -class CLimitOptWork; -class CLimitOptWidget : public QWidget -{ - Q_OBJECT - -public: - enum TABLE_COLUMN - { - COLUMN_TAG = 0, - COLUMN_LIMIT, - COLUMN_NUM, - COLUMN_UP1, - COLUMN_LOW1, - COLUMN_UP2, - COLUMN_LOW2, - COLUMN_UP3, - COLUMN_LOW3 - }; - explicit CLimitOptWidget(QWidget *parent = 0, bool editModel = true); - ~CLimitOptWidget(); - -signals: - void closeWnd(); - -public slots: - /** - * @brief addPoints 添加测点 - * @param tagList "station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value" - */ - void addPoints(const QStringList &tagList); - - void setColumnWidth(int column, int width); - - void setColumnHidden(int column, int hidden); - -private slots: - void slotConfirmClicked(); - - void slotCancelClicked(); - -private: - void initStyleSheet(); - - void initView(); - - void initData(); - - void updateTableData(); - - void getTableData(QList &limitList); - - bool isValidCheck(const ST_TAG_LIMIT &st_Tag_Limit); - - void initSysInfo(); - - void initPermMng(); - - bool checkPerm(int regionId, int locationId); - - void loadLocDomainMap(); - - int getAppIdBySubName(const QString &subName); - - int getDomainIdByLocName(const QString &locName); - - QString getDevGroupDesc(const QString &devGroupTag); - - QMap getLimitMap(); - - QMap getLimitNumMap(); - - QString truncTag(const QString& tagName, const QString& format); - - void setOptEnable(bool enable); - -private: - Ui::CLimitOptWidget *ui; - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; - kbd_dbms::CRdbAccess m_objRdbApi; - kbd_dbms::CRdbNetApi m_objRdbNetApi; - CLimitOptWork *m_pLimitOptWork; - QMap m_locDomainMap; - std::vector m_vecPermRegionId; - std::vector m_vecPermLocationId; - - QMap m_tagIndex; - QList m_preLimitList; - QList m_limitList; -}; - -#endif // CLIMITOPTWIDGET_H +#ifndef CLIMITOPTWIDGET_H +#define CLIMITOPTWIDGET_H + +#include +#include +#include "CLimitCommon.h" +#include "rdb_api/CRdbAccess.h" +#include "rdb_net_api/CRdbNetApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" + +namespace Ui { +class CLimitOptWidget; +} + +class CLimitOptWork; +class CLimitOptWidget : public QWidget +{ + Q_OBJECT + +public: + enum TABLE_COLUMN + { + COLUMN_TAG = 0, + COLUMN_LIMIT, + COLUMN_NUM, + COLUMN_UP1, + COLUMN_LOW1, + COLUMN_UP2, + COLUMN_LOW2, + COLUMN_UP3, + COLUMN_LOW3 + }; + explicit CLimitOptWidget(QWidget *parent = 0, bool editModel = true); + ~CLimitOptWidget(); + +signals: + void closeWnd(); + +public slots: + /** + * @brief addPoints 添加测点 + * @param tagList "station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value" + */ + void addPoints(const QStringList &tagList); + + void setColumnWidth(int column, int width); + + void setColumnHidden(int column, int hidden); + +private slots: + void slotConfirmClicked(); + + void slotCancelClicked(); + +private: + void initStyleSheet(); + + void initView(); + + void initData(); + + void updateTableData(); + + void getTableData(QList &limitList); + + bool isValidCheck(const ST_TAG_LIMIT &st_Tag_Limit); + + void initSysInfo(); + + void initPermMng(); + + bool checkPerm(int regionId, int locationId); + + void loadLocDomainMap(); + + int getAppIdBySubName(const QString &subName); + + int getDomainIdByLocName(const QString &locName); + + QString getDevGroupDesc(const QString &devGroupTag); + + QMap getLimitMap(); + + QMap getLimitNumMap(); + + QString truncTag(const QString& tagName, const QString& format); + + void setOptEnable(bool enable); + +private: + Ui::CLimitOptWidget *ui; + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; + kbd_dbms::CRdbAccess m_objRdbApi; + kbd_dbms::CRdbNetApi m_objRdbNetApi; + CLimitOptWork *m_pLimitOptWork; + QMap m_locDomainMap; + std::vector m_vecPermRegionId; + std::vector m_vecPermLocationId; + + QMap m_tagIndex; + QList m_preLimitList; + QList m_limitList; +}; + +#endif // CLIMITOPTWIDGET_H diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.ui b/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.ui index 35143749..57924f36 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.ui +++ b/product/src/gui/plugin/LimitOptWidget/CLimitOptWidget.ui @@ -1,64 +1,64 @@ - - - CLimitOptWidget - - - - 0 - 0 - 560 - 273 - - - - CLimitOptWidget - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - - - Qt::Horizontal - - - - 217 - 20 - - - - - - - - 确认 - - - - - - - 关闭 - - - - - - - - - + + + CLimitOptWidget + + + + 0 + 0 + 560 + 273 + + + + CLimitOptWidget + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + + + Qt::Horizontal + + + + 217 + 20 + + + + + + + + 确认 + + + + + + + 关闭 + + + + + + + + + diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.cpp b/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.cpp index 5d1f0a2d..fd131ee6 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.cpp +++ b/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.cpp @@ -1,259 +1,259 @@ -#include "CLimitOptWork.h" -#include "public/pub_logger_api/logger.h" -#include "db_api_ex/CDbApi.h" -#include "alarm_server_api/AlarmCommonDef.h" -#include "alarm_server_api/CAlmApiForApp.h" -#include "public/pub_utility_api/TimeUtil.h" - -using namespace kbd_public; -using namespace kbd_service; -using namespace kbd_dbms; - -CLimitOptWork::CLimitOptWork(QObject *parent) - : QObject(parent), - m_communicator(Q_NULLPTR), - m_ptrSysInfo(Q_NULLPTR), - m_ptrPermMng(Q_NULLPTR), - m_pAlmApi(Q_NULLPTR) -{ - m_isInit = initSysApi(); -} - -CLimitOptWork::~CLimitOptWork() -{ - if(m_pAlmApi) - { - m_pAlmApi->suspendThread(); - delete m_pAlmApi; - } - m_pAlmApi = Q_NULLPTR; - - if(m_communicator) - { - delete m_communicator; - } - m_communicator = Q_NULLPTR; -} - -bool CLimitOptWork::executeCmd(const QMap, int> &limitEnable, - const QMap, QList > > &limitPara, QString &errorStr) -{ - if(false == m_isInit) - { - errorStr = tr("系统初始化失败!"); - return false; - } - - if(false == updateLimitEnable(limitEnable)) - { - errorStr = tr("更改是否越限失败!"); - return false; - } - - if(false == updateLimitPara(limitPara)) - { - errorStr = tr("更改越限信息失败!"); - return false; - } - return true; -} - -bool CLimitOptWork::initSysApi() -{ - if(false == createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return false; - } - m_ptrPermMng = getPermMngInstance("base"); - if(Q_NULLPTR == m_ptrPermMng) - { - LOGERROR("创建权限接口访问库实例失败!"); - return false; - } - if(PERM_NORMAL != m_ptrPermMng->PermDllInit()) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - SNodeInfo stNodeInfo; - SAppInfo stAppInfo; - if(kbdFailed == m_ptrSysInfo->getLocalNodeInfo(stNodeInfo)) - { - LOGERROR("获取本机节点信息失败!"); - return false; - } - m_nDomainId = stNodeInfo.nDomainId; - m_strName = stNodeInfo.strName; - m_nLocationId = stNodeInfo.nLocationId; - if(kbdFailed == m_ptrSysInfo->getAppInfoByName("public", stAppInfo)) - { - LOGERROR("获取public应用信息失败!"); - return false; - } - m_pAlmApi = new CAlmApiForApp(stNodeInfo.nDomainId, stAppInfo.nId); - m_pAlmApi->resumeThread(); - LOGINFO("CAlmApiForApp domain: %d, app: %d", stNodeInfo.nDomainId, stAppInfo.nId); - m_communicator = new kbd_net::CMbCommunicator(); - return true; -} - -bool CLimitOptWork::updateLimitEnable(const QMap, int> &limitEnable) -{ - CDbApi dbWrite(DB_CONN_MODEL_WRITE); - if(!dbWrite.open()) - { - LOGERROR("数据库写接口打开失败!"); - return false; - } - QMap, int>::const_iterator iter = limitEnable.constBegin(); - for(; iter != limitEnable.constEnd(); iter++) - { - QList listColName; - listColName.push_back("IS_LIMIT"); - QList listVal; - listVal.push_back(iter.value()); - CDbCondition objCondition; - objCondition.m_eCompare = CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = CDbCondition::LOGIC_AND; - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_value = iter.key().first; - - if(false == dbWrite.update("analog", listColName, listVal, objCondition)) - { - LOGERROR("更新越限信息失败: [%s], [%s]", iter.key().first.toStdString().c_str(), dbWrite.getLastErrorString().toStdString().c_str()); - return false; - } - if(false == sendAlarm(iter.key().second, iter.value())) - { - LOGERROR("越限设置添加告警失败!"); - } - } - return true; -} - -bool CLimitOptWork::updateLimitPara(const QMap, QList > > &limitPara) -{ - QMap, QList > >::const_iterator iter = limitPara.constBegin(); - for(; iter != limitPara.constEnd(); iter++) - { - kbd_net::CMbMessage msg; - msg.setMsgType(MT_OPT_AI_LIMIT_SET_DOWN); - msg.setSubject(iter.key().second, CH_HMI_TO_OPT_OPTCMD_DOWN); - - SAiLimitSet sAiLimitSet; - CAiLimitSet cAiLimitSet; - if(false == createReqHead(sAiLimitSet.stHead, iter.key().first, iter.key().second)) - { - return false; - } - const QList > &cmdList = iter.value(); - for(int nIndex(0); nIndex < cmdList.length(); nIndex++) - { - SAiLimitQueue sAiLimit; - sAiLimit.strKeyIdTag = cmdList[nIndex].first.toStdString(); - sAiLimit.fValue = cmdList[nIndex].second; - sAiLimitSet.vecAiLimitQueue.push_back(sAiLimit); - } - std::string content = cAiLimitSet.generate(sAiLimitSet); - msg.setData(content); - - if(false == m_communicator->sendMsgToDomain(msg, iter.key().first)) - { - LOGERROR("下发限值设置命令失败 [%s]!", content.c_str()); - return false; - } - } - return true; -} - -bool CLimitOptWork::createReqHead(SOptReqHead &head, const int &nDomainId, const int &nAppId) -{ - if(Q_NULLPTR == m_ptrPermMng) - { - return false; - } - int nUserId; - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(PERM_NORMAL != m_ptrPermMng->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - LOGERROR("获取当前登录用户信息失败!"); - return false; - } - - head.strSrcTag = "LimitOptWidget"; - head.nSrcDomainID = m_nDomainId; - head.nDstDomainID = nDomainId; - head.nAppID = nAppId; - head.strHostName = m_strName; - head.strInstName = strInstanceName; - head.strCommName = m_communicator->getName(); - head.nUserID = nUserId; - head.nUserGroupID = nUserGrpId; - head.nOptTime = getUTCTimeMsec(); - - return true; -} - -bool CLimitOptWork::sendAlarm(const QString &alarm, int isLimit) -{ - kbd_idlfile::SAppAddAlm stAppAddAlarm; - kbd_idlfile::SAlmInfoFromApp &stAlmInfoFromApp = *(stAppAddAlarm.add_alm_info()); - stAlmInfoFromApp.set_alm_type(ALM_TYPE_OPERATE); - stAlmInfoFromApp.set_time_stamp(getUTCTimeMsec()); - stAlmInfoFromApp.set_status(ALM_STAT_OPT_MODEL_MODIFY); - stAlmInfoFromApp.set_location_id(m_nLocationId); - stAlmInfoFromApp.set_alm_style(kbd_idlfile::enAlmStyle::AS_EVENT_ONLY); - stAlmInfoFromApp.set_region_id(-1); //< 责任区ID,HMI 系统操作责任区统一为-1,系统事件 - - std::string strAlias = ""; - if( m_ptrPermMng) - { - int nUserId; - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(PERM_NORMAL > m_ptrPermMng->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - LOGERROR("越限设置添加告警: 获取当前登录用户信息失败!"); - } - else - { - m_ptrPermMng->GetUserAliasByUserId(nUserId, strAlias); - } - } - QString alarmDesc; - alarmDesc += alarm; - if(isLimit) - { - alarmDesc += tr(" 越限设置 "); - } - else - { - alarmDesc += tr(" 取消越限设置 "); - } - alarmDesc += tr("操作员: "); - alarmDesc += QString::fromStdString(strAlias); - alarmDesc += ", "; - alarmDesc += tr("操作主机: "); - alarmDesc += QString::fromStdString(m_strName); - - kbd_idlfile::SAlmKeyword stAlmKeyword; - stAlmKeyword.set_id(ALM_KEY_ALM_DESC); - stAlmKeyword.set_value(alarmDesc.toStdString().c_str()); - stAlmInfoFromApp.add_alm_keyword()->CopyFrom(stAlmKeyword); - if(m_pAlmApi) - { - bool isAlarm = m_pAlmApi->addAlarm(stAppAddAlarm); - if(!isAlarm) - { - LOGERROR("越限设置添加告警失败 [%s]!", alarmDesc.toStdString().c_str()); - } - return isAlarm; - } - return false; -} +#include "CLimitOptWork.h" +#include "public/pub_logger_api/logger.h" +#include "db_api_ex/CDbApi.h" +#include "alarm_server_api/AlarmCommonDef.h" +#include "alarm_server_api/CAlmApiForApp.h" +#include "public/pub_utility_api/TimeUtil.h" + +using namespace kbd_public; +using namespace kbd_service; +using namespace kbd_dbms; + +CLimitOptWork::CLimitOptWork(QObject *parent) + : QObject(parent), + m_communicator(Q_NULLPTR), + m_ptrSysInfo(Q_NULLPTR), + m_ptrPermMng(Q_NULLPTR), + m_pAlmApi(Q_NULLPTR) +{ + m_isInit = initSysApi(); +} + +CLimitOptWork::~CLimitOptWork() +{ + if(m_pAlmApi) + { + m_pAlmApi->suspendThread(); + delete m_pAlmApi; + } + m_pAlmApi = Q_NULLPTR; + + if(m_communicator) + { + delete m_communicator; + } + m_communicator = Q_NULLPTR; +} + +bool CLimitOptWork::executeCmd(const QMap, int> &limitEnable, + const QMap, QList > > &limitPara, QString &errorStr) +{ + if(false == m_isInit) + { + errorStr = tr("系统初始化失败!"); + return false; + } + + if(false == updateLimitEnable(limitEnable)) + { + errorStr = tr("更改是否越限失败!"); + return false; + } + + if(false == updateLimitPara(limitPara)) + { + errorStr = tr("更改越限信息失败!"); + return false; + } + return true; +} + +bool CLimitOptWork::initSysApi() +{ + if(false == createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + m_ptrPermMng = getPermMngInstance("base"); + if(Q_NULLPTR == m_ptrPermMng) + { + LOGERROR("创建权限接口访问库实例失败!"); + return false; + } + if(PERM_NORMAL != m_ptrPermMng->PermDllInit()) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + SNodeInfo stNodeInfo; + SAppInfo stAppInfo; + if(kbdFailed == m_ptrSysInfo->getLocalNodeInfo(stNodeInfo)) + { + LOGERROR("获取本机节点信息失败!"); + return false; + } + m_nDomainId = stNodeInfo.nDomainId; + m_strName = stNodeInfo.strName; + m_nLocationId = stNodeInfo.nLocationId; + if(kbdFailed == m_ptrSysInfo->getAppInfoByName("public", stAppInfo)) + { + LOGERROR("获取public应用信息失败!"); + return false; + } + m_pAlmApi = new CAlmApiForApp(stNodeInfo.nDomainId, stAppInfo.nId); + m_pAlmApi->resumeThread(); + LOGINFO("CAlmApiForApp domain: %d, app: %d", stNodeInfo.nDomainId, stAppInfo.nId); + m_communicator = new kbd_net::CMbCommunicator(); + return true; +} + +bool CLimitOptWork::updateLimitEnable(const QMap, int> &limitEnable) +{ + CDbApi dbWrite(DB_CONN_MODEL_WRITE); + if(!dbWrite.open()) + { + LOGERROR("数据库写接口打开失败!"); + return false; + } + QMap, int>::const_iterator iter = limitEnable.constBegin(); + for(; iter != limitEnable.constEnd(); iter++) + { + QList listColName; + listColName.push_back("IS_LIMIT"); + QList listVal; + listVal.push_back(iter.value()); + CDbCondition objCondition; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_value = iter.key().first; + + if(false == dbWrite.update("analog", listColName, listVal, objCondition)) + { + LOGERROR("更新越限信息失败: [%s], [%s]", iter.key().first.toStdString().c_str(), dbWrite.getLastErrorString().toStdString().c_str()); + return false; + } + if(false == sendAlarm(iter.key().second, iter.value())) + { + LOGERROR("越限设置添加告警失败!"); + } + } + return true; +} + +bool CLimitOptWork::updateLimitPara(const QMap, QList > > &limitPara) +{ + QMap, QList > >::const_iterator iter = limitPara.constBegin(); + for(; iter != limitPara.constEnd(); iter++) + { + kbd_net::CMbMessage msg; + msg.setMsgType(MT_OPT_AI_LIMIT_SET_DOWN); + msg.setSubject(iter.key().second, CH_HMI_TO_OPT_OPTCMD_DOWN); + + SAiLimitSet sAiLimitSet; + CAiLimitSet cAiLimitSet; + if(false == createReqHead(sAiLimitSet.stHead, iter.key().first, iter.key().second)) + { + return false; + } + const QList > &cmdList = iter.value(); + for(int nIndex(0); nIndex < cmdList.length(); nIndex++) + { + SAiLimitQueue sAiLimit; + sAiLimit.strKeyIdTag = cmdList[nIndex].first.toStdString(); + sAiLimit.fValue = cmdList[nIndex].second; + sAiLimitSet.vecAiLimitQueue.push_back(sAiLimit); + } + std::string content = cAiLimitSet.generate(sAiLimitSet); + msg.setData(content); + + if(false == m_communicator->sendMsgToDomain(msg, iter.key().first)) + { + LOGERROR("下发限值设置命令失败 [%s]!", content.c_str()); + return false; + } + } + return true; +} + +bool CLimitOptWork::createReqHead(SOptReqHead &head, const int &nDomainId, const int &nAppId) +{ + if(Q_NULLPTR == m_ptrPermMng) + { + return false; + } + int nUserId; + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(PERM_NORMAL != m_ptrPermMng->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + LOGERROR("获取当前登录用户信息失败!"); + return false; + } + + head.strSrcTag = "LimitOptWidget"; + head.nSrcDomainID = m_nDomainId; + head.nDstDomainID = nDomainId; + head.nAppID = nAppId; + head.strHostName = m_strName; + head.strInstName = strInstanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = nUserId; + head.nUserGroupID = nUserGrpId; + head.nOptTime = getUTCTimeMsec(); + + return true; +} + +bool CLimitOptWork::sendAlarm(const QString &alarm, int isLimit) +{ + kbd_idlfile::SAppAddAlm stAppAddAlarm; + kbd_idlfile::SAlmInfoFromApp &stAlmInfoFromApp = *(stAppAddAlarm.add_alm_info()); + stAlmInfoFromApp.set_alm_type(ALM_TYPE_OPERATE); + stAlmInfoFromApp.set_time_stamp(getUTCTimeMsec()); + stAlmInfoFromApp.set_status(ALM_STAT_OPT_MODEL_MODIFY); + stAlmInfoFromApp.set_location_id(m_nLocationId); + stAlmInfoFromApp.set_alm_style(kbd_idlfile::enAlmStyle::AS_EVENT_ONLY); + stAlmInfoFromApp.set_region_id(-1); //< 责任区ID,HMI 系统操作责任区统一为-1,系统事件 + + std::string strAlias = ""; + if( m_ptrPermMng) + { + int nUserId; + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(PERM_NORMAL > m_ptrPermMng->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + LOGERROR("越限设置添加告警: 获取当前登录用户信息失败!"); + } + else + { + m_ptrPermMng->GetUserAliasByUserId(nUserId, strAlias); + } + } + QString alarmDesc; + alarmDesc += alarm; + if(isLimit) + { + alarmDesc += tr(" 越限设置 "); + } + else + { + alarmDesc += tr(" 取消越限设置 "); + } + alarmDesc += tr("操作员: "); + alarmDesc += QString::fromStdString(strAlias); + alarmDesc += ", "; + alarmDesc += tr("操作主机: "); + alarmDesc += QString::fromStdString(m_strName); + + kbd_idlfile::SAlmKeyword stAlmKeyword; + stAlmKeyword.set_id(ALM_KEY_ALM_DESC); + stAlmKeyword.set_value(alarmDesc.toStdString().c_str()); + stAlmInfoFromApp.add_alm_keyword()->CopyFrom(stAlmKeyword); + if(m_pAlmApi) + { + bool isAlarm = m_pAlmApi->addAlarm(stAppAddAlarm); + if(!isAlarm) + { + LOGERROR("越限设置添加告警失败 [%s]!", alarmDesc.toStdString().c_str()); + } + return isAlarm; + } + return false; +} diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.h b/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.h index 880689c5..4c3b7a68 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.h +++ b/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.h @@ -1,53 +1,53 @@ -#ifndef CLIMITOPTWORK_H -#define CLIMITOPTWORK_H - -#include -#include -#include "common/MessageChannel.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "service/operate_server_api/JsonMessageStruct.h" -#include "service/operate_server_api/JsonOptCommand.h" -#include "alarm_server_api/CAlmApiForApp.h" - -class CLimitOptWork : public QObject -{ -public: - CLimitOptWork(QObject *parent=Q_NULLPTR); - ~CLimitOptWork(); - - /** - * @brief executeCmd 更新越限信息 - * @param limitEnable QMap<(点标签,描述), 是否越限> - * @param limitPara QMap< (域ID, 应用ID), 自定义命令(strKeyIdTag,fValue) > - * @param errorStr 错误信息 - */ - bool executeCmd(const QMap, int> &limitEnable, - const QMap, QList>> &limitPara, - QString &errorStr); - -private: - bool initSysApi(); - - bool updateLimitEnable(const QMap, int> &limitEnable); - - bool updateLimitPara(const QMap, QList > > &limitPara); - - bool createReqHead(SOptReqHead &head, const int &nDomainId, const int &nAppId); - - bool sendAlarm(const QString &alarm, int isLimit); - -private: - kbd_net::CMbCommunicator *m_communicator; - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; - kbd_service::CPermMngApiPtr m_ptrPermMng; - kbd_service::CAlmApiForApp *m_pAlmApi; - bool m_isInit; - int m_nDomainId; - int m_nLocationId; - std::string m_strName; -}; - -#endif // CLIMITOPTWORK_H +#ifndef CLIMITOPTWORK_H +#define CLIMITOPTWORK_H + +#include +#include +#include "common/MessageChannel.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "alarm_server_api/CAlmApiForApp.h" + +class CLimitOptWork : public QObject +{ +public: + CLimitOptWork(QObject *parent=Q_NULLPTR); + ~CLimitOptWork(); + + /** + * @brief executeCmd 更新越限信息 + * @param limitEnable QMap<(点标签,描述), 是否越限> + * @param limitPara QMap< (域ID, 应用ID), 自定义命令(strKeyIdTag,fValue) > + * @param errorStr 错误信息 + */ + bool executeCmd(const QMap, int> &limitEnable, + const QMap, QList>> &limitPara, + QString &errorStr); + +private: + bool initSysApi(); + + bool updateLimitEnable(const QMap, int> &limitEnable); + + bool updateLimitPara(const QMap, QList > > &limitPara); + + bool createReqHead(SOptReqHead &head, const int &nDomainId, const int &nAppId); + + bool sendAlarm(const QString &alarm, int isLimit); + +private: + kbd_net::CMbCommunicator *m_communicator; + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; + kbd_service::CPermMngApiPtr m_ptrPermMng; + kbd_service::CAlmApiForApp *m_pAlmApi; + bool m_isInit; + int m_nDomainId; + int m_nLocationId; + std::string m_strName; +}; + +#endif // CLIMITOPTWORK_H diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.cpp b/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.cpp index 9981d5e4..d3771802 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.cpp +++ b/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CLimitPluginWidget.h" -#include "CLimitOptWidget.h" - -CLimitPluginWidget::CLimitPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CLimitPluginWidget::~CLimitPluginWidget() -{ - -} - -bool CLimitPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - Q_UNUSED(ptrVec); - CLimitOptWidget *pWidget = new CLimitOptWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CLimitPluginWidget::release() -{ - -} +#include +#include "CLimitPluginWidget.h" +#include "CLimitOptWidget.h" + +CLimitPluginWidget::CLimitPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CLimitPluginWidget::~CLimitPluginWidget() +{ + +} + +bool CLimitPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec); + CLimitOptWidget *pWidget = new CLimitOptWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CLimitPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.h b/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.h index 4af1f8c7..fa8a320e 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.h +++ b/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CLIMITPLUGINWIDGET_H -#define CLIMITPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CLimitPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CLimitPluginWidget(QObject *parent = 0); - ~CLimitPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - - -#endif // CLIMITPLUGINWIDGET_H +#ifndef CLIMITPLUGINWIDGET_H +#define CLIMITPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CLimitPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CLimitPluginWidget(QObject *parent = 0); + ~CLimitPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + + +#endif // CLIMITPLUGINWIDGET_H diff --git a/product/src/gui/plugin/LimitOptWidget/CTableDelegate.cpp b/product/src/gui/plugin/LimitOptWidget/CTableDelegate.cpp index c3d918d3..1747409d 100644 --- a/product/src/gui/plugin/LimitOptWidget/CTableDelegate.cpp +++ b/product/src/gui/plugin/LimitOptWidget/CTableDelegate.cpp @@ -1,87 +1,87 @@ -#include "CTableDelegate.h" -#include -#include - -CTableDelegate::CTableDelegate(QObject *parent, CTableDelegate::DelegateWidget type) - : QStyledItemDelegate(parent), - m_type(type) -{ - -} - -void CTableDelegate::setComboxMap(const QMap &map) -{ - m_comboxMap = map; -} - -QWidget *CTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - switch (m_type) { - case ReadOnly: - return NULL; - case LineEdit: - return new QLineEdit(parent); - case ComboBox:{ - QComboBox *box= new QComboBox(parent); - QMap::const_iterator iter - = m_comboxMap.constBegin(); - for(; iter != m_comboxMap.constEnd(); iter++) - { - box->addItem(iter.value(), iter.key()); - } - return box; - } - default: - return QStyledItemDelegate::createEditor(parent, option, index); - } -} - -void CTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - switch(m_type){ - case LineEdit: - { - QLineEdit *edit = static_cast(editor); - edit->setText(index.data(Qt::DisplayRole).toString()); - break; - } - case ComboBox: - { - QComboBox *comb = static_cast(editor); - comb->setCurrentIndex(comb->findText(index.data(Qt::DisplayRole).toString())); - break; - } - default: - QStyledItemDelegate::setEditorData(editor, index); - } -} - -void CTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - switch (m_type) { - case LineEdit: - { - QLineEdit *edit = static_cast(editor); - model->setData(index, edit->text(), Qt::DisplayRole); - break; - } - case ComboBox: - { - QComboBox *comb = static_cast(editor); - if(model->data(index, Qt::DisplayRole) != comb->currentText()) - { - model->setData(index, comb->currentText(), Qt::DisplayRole); - model->setData(index, comb->currentData(), Qt::UserRole); - } - break; - } - default: - QStyledItemDelegate::setModelData(editor, model, index); - } -} - -void CTableDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(index) - editor->setGeometry(option.rect); -} +#include "CTableDelegate.h" +#include +#include + +CTableDelegate::CTableDelegate(QObject *parent, CTableDelegate::DelegateWidget type) + : QStyledItemDelegate(parent), + m_type(type) +{ + +} + +void CTableDelegate::setComboxMap(const QMap &map) +{ + m_comboxMap = map; +} + +QWidget *CTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + switch (m_type) { + case ReadOnly: + return NULL; + case LineEdit: + return new QLineEdit(parent); + case ComboBox:{ + QComboBox *box= new QComboBox(parent); + QMap::const_iterator iter + = m_comboxMap.constBegin(); + for(; iter != m_comboxMap.constEnd(); iter++) + { + box->addItem(iter.value(), iter.key()); + } + return box; + } + default: + return QStyledItemDelegate::createEditor(parent, option, index); + } +} + +void CTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + switch(m_type){ + case LineEdit: + { + QLineEdit *edit = static_cast(editor); + edit->setText(index.data(Qt::DisplayRole).toString()); + break; + } + case ComboBox: + { + QComboBox *comb = static_cast(editor); + comb->setCurrentIndex(comb->findText(index.data(Qt::DisplayRole).toString())); + break; + } + default: + QStyledItemDelegate::setEditorData(editor, index); + } +} + +void CTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + switch (m_type) { + case LineEdit: + { + QLineEdit *edit = static_cast(editor); + model->setData(index, edit->text(), Qt::DisplayRole); + break; + } + case ComboBox: + { + QComboBox *comb = static_cast(editor); + if(model->data(index, Qt::DisplayRole) != comb->currentText()) + { + model->setData(index, comb->currentText(), Qt::DisplayRole); + model->setData(index, comb->currentData(), Qt::UserRole); + } + break; + } + default: + QStyledItemDelegate::setModelData(editor, model, index); + } +} + +void CTableDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect); +} diff --git a/product/src/gui/plugin/LimitOptWidget/CTableDelegate.h b/product/src/gui/plugin/LimitOptWidget/CTableDelegate.h index 244b7196..ed699691 100644 --- a/product/src/gui/plugin/LimitOptWidget/CTableDelegate.h +++ b/product/src/gui/plugin/LimitOptWidget/CTableDelegate.h @@ -1,37 +1,37 @@ -#ifndef CTABLEDELEGATE_H -#define CTABLEDELEGATE_H - -#include - -class CTableDelegate : public QStyledItemDelegate -{ -public: - enum DelegateWidget{ - ReadOnly = 0, - LineEdit = 1, - ComboBox = 2, - }; - - CTableDelegate(QObject *parent = 0, DelegateWidget type = LineEdit); - - void setComboxMap(const QMap &map); - - QWidget *createEditor(QWidget *parent, - const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE; - - void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; - void setModelData(QWidget *editor, - QAbstractItemModel *model, - const QModelIndex &index) const Q_DECL_OVERRIDE; - - void updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE; - -private: - DelegateWidget m_type; - QMap m_comboxMap; -}; - -#endif // CTABLEDELEGATE_H +#ifndef CTABLEDELEGATE_H +#define CTABLEDELEGATE_H + +#include + +class CTableDelegate : public QStyledItemDelegate +{ +public: + enum DelegateWidget{ + ReadOnly = 0, + LineEdit = 1, + ComboBox = 2, + }; + + CTableDelegate(QObject *parent = 0, DelegateWidget type = LineEdit); + + void setComboxMap(const QMap &map); + + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; + void setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const Q_DECL_OVERRIDE; + + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &index) const Q_DECL_OVERRIDE; + +private: + DelegateWidget m_type; + QMap m_comboxMap; +}; + +#endif // CTABLEDELEGATE_H diff --git a/product/src/gui/plugin/LimitOptWidget/LimitOptWidget.pro b/product/src/gui/plugin/LimitOptWidget/LimitOptWidget.pro index cbe959f1..dc6f47f5 100644 --- a/product/src/gui/plugin/LimitOptWidget/LimitOptWidget.pro +++ b/product/src/gui/plugin/LimitOptWidget/LimitOptWidget.pro @@ -1,71 +1,71 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-10-28T10:04:59 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = LimitOptWidget - -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - main.cpp \ - CLimitOptWidget.cpp \ - CTableDelegate.cpp \ - CLimitPluginWidget.cpp \ - CLimitOptWork.cpp - -HEADERS += \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - CLimitOptWidget.h \ - CLimitCommon.h \ - CTableDelegate.h \ - CLimitPluginWidget.h \ - CLimitOptWork.h - -FORMS += \ - CLimitOptWidget.ui - -LIBS += \ - -lboost_chrono \ - -ldb_base_api \ - -ldb_api_ex \ - -lrdb_api \ - -lrdb_net_api \ - -llog4cplus \ - -lpub_logger_api \ - -lprotobuf \ - -lpub_sysinfo_api \ - -lpub_utility_api \ - -lperm_mng_api \ - -lnet_msg_bus_api \ - -lalarm_server_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-10-28T10:04:59 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = LimitOptWidget + +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + main.cpp \ + CLimitOptWidget.cpp \ + CTableDelegate.cpp \ + CLimitPluginWidget.cpp \ + CLimitOptWork.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CLimitOptWidget.h \ + CLimitCommon.h \ + CTableDelegate.h \ + CLimitPluginWidget.h \ + CLimitOptWork.h + +FORMS += \ + CLimitOptWidget.ui + +LIBS += \ + -lboost_chrono \ + -ldb_base_api \ + -ldb_api_ex \ + -lrdb_api \ + -lrdb_net_api \ + -llog4cplus \ + -lpub_logger_api \ + -lprotobuf \ + -lpub_sysinfo_api \ + -lpub_utility_api \ + -lperm_mng_api \ + -lnet_msg_bus_api \ + -lalarm_server_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/LimitOptWidget/main.cpp b/product/src/gui/plugin/LimitOptWidget/main.cpp index 05009913..caf0ea29 100644 --- a/product/src/gui/plugin/LimitOptWidget/main.cpp +++ b/product/src/gui/plugin/LimitOptWidget/main.cpp @@ -1,11 +1,11 @@ -#include "CLimitOptWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CLimitOptWidget w; - w.show(); - - return a.exec(); -} +#include "CLimitOptWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CLimitOptWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/CHistoryActionModel.cpp b/product/src/gui/plugin/LinkCtrlWidget/CHistoryActionModel.cpp index b4fe3b99..5f95d077 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CHistoryActionModel.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CHistoryActionModel.cpp @@ -1,294 +1,294 @@ -#include "CHistoryActionModel.h" - -CHistoryActionTreeModelItem::CHistoryActionTreeModelItem(CHistoryActionTreeModelItem *parent) - : m_parent(parent) -{ - m_listChild.clear(); - if(Q_NULLPTR != m_parent) - { - m_parent->appendChild(this); - } -} - -CHistoryActionTreeModelItem::CHistoryActionTreeModelItem(const QList &data, CHistoryActionTreeModelItem *parent) - : m_parent(parent), - m_data(data) -{ - m_listChild.clear(); - if(Q_NULLPTR != m_parent) - { - m_parent->appendChild(this); - } -} - -CHistoryActionTreeModelItem::~CHistoryActionTreeModelItem() -{ - qDeleteAll(m_listChild); - if (Q_NULLPTR != m_parent) - { - m_parent->removeChild(this); - } -} - -bool CHistoryActionTreeModelItem::isRootItem() -{ - if (m_parent == Q_NULLPTR) - { - return true; - } - return false; -} - -CHistoryActionTreeModelItem *CHistoryActionTreeModelItem::parent() -{ - return m_parent; -} - -CHistoryActionTreeModelItem *CHistoryActionTreeModelItem::child(const int row) -{ - if(row < m_listChild.size()) - { - return m_listChild.value(row); - } - - return Q_NULLPTR; -} - -void CHistoryActionTreeModelItem::appendChild(CHistoryActionTreeModelItem *child) -{ - m_listChild.append(child); -} - -void CHistoryActionTreeModelItem::removeChild(CHistoryActionTreeModelItem *child) -{ - m_listChild.removeOne(child); -} - -void CHistoryActionTreeModelItem::clear() -{ - if (!m_listChild.isEmpty()) - { - QList::iterator it = m_listChild.begin(); - while (it != m_listChild.end()) - { - CHistoryActionTreeModelItem * item = *it; - it = m_listChild.erase(it); - item->clear(); - delete item; - } - } -} - -int CHistoryActionTreeModelItem::row() -{ - if(m_parent) - { - return m_parent->m_listChild.indexOf(this); - } - return 0; -} - -int CHistoryActionTreeModelItem::childCount() -{ - if (m_listChild.isEmpty()) - { - return 0; - } - - return m_listChild.size(); -} - -int CHistoryActionTreeModelItem::columnCount() -{ - return m_data.size(); -} - -QVariant CHistoryActionTreeModelItem::data(QModelIndex index) -{ - return m_data.value(index.column()); -} - -bool CHistoryActionTreeModelItem::setData(QModelIndex index, const QVariant &value) -{ - if(!index.isValid() || !value.isValid()) - { - return false; - } - if(index.column() >= m_data.size()) - { - return false; - } - - m_data[index.column()] = value; - return true; -} - -CHistoryActionModel::CHistoryActionModel(QObject *parent) - : QAbstractItemModel(parent), - m_rootItem(Q_NULLPTR) -{ - m_header << tr("动作") << tr("位置") << tr("描述") << tr("执行结果"); -} - -void CHistoryActionModel::updateModelFunctionData(const QList &listFuncInfo) -{ - beginResetModel(); - if(Q_NULLPTR != m_rootItem) - { - m_rootItem->clear(); - delete m_rootItem; - } - m_rootItem = new CHistoryActionTreeModelItem(); - for(int nIndx(0); nIndx < listFuncInfo.size(); nIndx++) - { - QList values; - values.append(listFuncInfo[nIndx].funcDescription); - values.append(QVariant()); - values.append(QVariant()); - values.append(QVariant()); - CHistoryActionTreeModelItem * item = new CHistoryActionTreeModelItem(values, m_rootItem); - Q_UNUSED(item) - } - endResetModel(); -} - -void CHistoryActionModel::updateModelActionData(const QList &listActionInfo) -{ - beginResetModel(); - for(int nIndex(0); nIndex < m_rootItem->childCount(); nIndex++) - { - CHistoryActionTreeModelItem * parent = m_rootItem->child(nIndex); - QString funcDescription = parent->data(createIndex(nIndex, History_Action_Column::nameColumn)).toString(); - for(int nActionIndex(0); nActionIndex < listActionInfo.size(); nActionIndex++) - { - if(listActionInfo[nActionIndex].functionDescription == funcDescription) - { - QList values; - values.append(listActionInfo[nActionIndex].actionDescription); - values.append(listActionInfo[nActionIndex].location); - values.append(listActionInfo[nActionIndex].description); - values.append(listActionInfo[nActionIndex].status); - CHistoryActionTreeModelItem * item = new CHistoryActionTreeModelItem(values, parent); - Q_UNUSED(item) - } - } - } - endResetModel(); -} - -QVariant CHistoryActionModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(orientation) - if(Qt::DisplayRole == role) - { - return m_header[section]; - } - if (Qt::TextAlignmentRole == role) - { - return Qt::AlignCenter; - } - return QVariant(); -} - -QModelIndex CHistoryActionModel::index(int row, int column, const QModelIndex &parent) const -{ - if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) - { - return QModelIndex(); - } - - CHistoryActionTreeModelItem * parentItem; - if(!parent.isValid()) - { - parentItem = m_rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - if(parentItem) - { - CHistoryActionTreeModelItem *childItem = parentItem->child(row); - if(childItem) - { - return createIndex(row,column,childItem); - } - } - return QModelIndex(); -} - -QModelIndex CHistoryActionModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - CHistoryActionTreeModelItem *childItem = static_cast(index.internalPointer()); - if (!childItem) - { - return QModelIndex(); - } - - CHistoryActionTreeModelItem *parentItem = childItem->parent(); - - if (parentItem == m_rootItem) - { - return QModelIndex(); - } - - return createIndex(parentItem->row(), index.column(), parentItem); -} - -int CHistoryActionModel::rowCount(const QModelIndex &parent) const -{ - if(!parent.isValid()) - { - if (NULL != m_rootItem) - { - return m_rootItem->childCount(); - } - else - { - return 0; - } - } - else - { - CHistoryActionTreeModelItem * parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); - } -} - -int CHistoryActionModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return m_header.size(); -} - -QVariant CHistoryActionModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - { - return QVariant(); - } - if(Qt::TextAlignmentRole == role) - { - if(index.column() != History_Action_Column::nameColumn) - { - return QVariant(Qt::AlignCenter); - }else - { - return QVariant(Qt::AlignVCenter | Qt::AlignLeft); - } - } - - if(Qt::DisplayRole == role) - { - CHistoryActionTreeModelItem * item = static_cast(index.internalPointer()); - return item->data(index); - } - return QVariant(); -} - +#include "CHistoryActionModel.h" + +CHistoryActionTreeModelItem::CHistoryActionTreeModelItem(CHistoryActionTreeModelItem *parent) + : m_parent(parent) +{ + m_listChild.clear(); + if(Q_NULLPTR != m_parent) + { + m_parent->appendChild(this); + } +} + +CHistoryActionTreeModelItem::CHistoryActionTreeModelItem(const QList &data, CHistoryActionTreeModelItem *parent) + : m_parent(parent), + m_data(data) +{ + m_listChild.clear(); + if(Q_NULLPTR != m_parent) + { + m_parent->appendChild(this); + } +} + +CHistoryActionTreeModelItem::~CHistoryActionTreeModelItem() +{ + qDeleteAll(m_listChild); + if (Q_NULLPTR != m_parent) + { + m_parent->removeChild(this); + } +} + +bool CHistoryActionTreeModelItem::isRootItem() +{ + if (m_parent == Q_NULLPTR) + { + return true; + } + return false; +} + +CHistoryActionTreeModelItem *CHistoryActionTreeModelItem::parent() +{ + return m_parent; +} + +CHistoryActionTreeModelItem *CHistoryActionTreeModelItem::child(const int row) +{ + if(row < m_listChild.size()) + { + return m_listChild.value(row); + } + + return Q_NULLPTR; +} + +void CHistoryActionTreeModelItem::appendChild(CHistoryActionTreeModelItem *child) +{ + m_listChild.append(child); +} + +void CHistoryActionTreeModelItem::removeChild(CHistoryActionTreeModelItem *child) +{ + m_listChild.removeOne(child); +} + +void CHistoryActionTreeModelItem::clear() +{ + if (!m_listChild.isEmpty()) + { + QList::iterator it = m_listChild.begin(); + while (it != m_listChild.end()) + { + CHistoryActionTreeModelItem * item = *it; + it = m_listChild.erase(it); + item->clear(); + delete item; + } + } +} + +int CHistoryActionTreeModelItem::row() +{ + if(m_parent) + { + return m_parent->m_listChild.indexOf(this); + } + return 0; +} + +int CHistoryActionTreeModelItem::childCount() +{ + if (m_listChild.isEmpty()) + { + return 0; + } + + return m_listChild.size(); +} + +int CHistoryActionTreeModelItem::columnCount() +{ + return m_data.size(); +} + +QVariant CHistoryActionTreeModelItem::data(QModelIndex index) +{ + return m_data.value(index.column()); +} + +bool CHistoryActionTreeModelItem::setData(QModelIndex index, const QVariant &value) +{ + if(!index.isValid() || !value.isValid()) + { + return false; + } + if(index.column() >= m_data.size()) + { + return false; + } + + m_data[index.column()] = value; + return true; +} + +CHistoryActionModel::CHistoryActionModel(QObject *parent) + : QAbstractItemModel(parent), + m_rootItem(Q_NULLPTR) +{ + m_header << tr("动作") << tr("位置") << tr("描述") << tr("执行结果"); +} + +void CHistoryActionModel::updateModelFunctionData(const QList &listFuncInfo) +{ + beginResetModel(); + if(Q_NULLPTR != m_rootItem) + { + m_rootItem->clear(); + delete m_rootItem; + } + m_rootItem = new CHistoryActionTreeModelItem(); + for(int nIndx(0); nIndx < listFuncInfo.size(); nIndx++) + { + QList values; + values.append(listFuncInfo[nIndx].funcDescription); + values.append(QVariant()); + values.append(QVariant()); + values.append(QVariant()); + CHistoryActionTreeModelItem * item = new CHistoryActionTreeModelItem(values, m_rootItem); + Q_UNUSED(item) + } + endResetModel(); +} + +void CHistoryActionModel::updateModelActionData(const QList &listActionInfo) +{ + beginResetModel(); + for(int nIndex(0); nIndex < m_rootItem->childCount(); nIndex++) + { + CHistoryActionTreeModelItem * parent = m_rootItem->child(nIndex); + QString funcDescription = parent->data(createIndex(nIndex, History_Action_Column::nameColumn)).toString(); + for(int nActionIndex(0); nActionIndex < listActionInfo.size(); nActionIndex++) + { + if(listActionInfo[nActionIndex].functionDescription == funcDescription) + { + QList values; + values.append(listActionInfo[nActionIndex].actionDescription); + values.append(listActionInfo[nActionIndex].location); + values.append(listActionInfo[nActionIndex].description); + values.append(listActionInfo[nActionIndex].status); + CHistoryActionTreeModelItem * item = new CHistoryActionTreeModelItem(values, parent); + Q_UNUSED(item) + } + } + } + endResetModel(); +} + +QVariant CHistoryActionModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(orientation) + if(Qt::DisplayRole == role) + { + return m_header[section]; + } + if (Qt::TextAlignmentRole == role) + { + return Qt::AlignCenter; + } + return QVariant(); +} + +QModelIndex CHistoryActionModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) + { + return QModelIndex(); + } + + CHistoryActionTreeModelItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + CHistoryActionTreeModelItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,column,childItem); + } + } + return QModelIndex(); +} + +QModelIndex CHistoryActionModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CHistoryActionTreeModelItem *childItem = static_cast(index.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + CHistoryActionTreeModelItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + { + return QModelIndex(); + } + + return createIndex(parentItem->row(), index.column(), parentItem); +} + +int CHistoryActionModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (NULL != m_rootItem) + { + return m_rootItem->childCount(); + } + else + { + return 0; + } + } + else + { + CHistoryActionTreeModelItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int CHistoryActionModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_header.size(); +} + +QVariant CHistoryActionModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + if(Qt::TextAlignmentRole == role) + { + if(index.column() != History_Action_Column::nameColumn) + { + return QVariant(Qt::AlignCenter); + }else + { + return QVariant(Qt::AlignVCenter | Qt::AlignLeft); + } + } + + if(Qt::DisplayRole == role) + { + CHistoryActionTreeModelItem * item = static_cast(index.internalPointer()); + return item->data(index); + } + return QVariant(); +} + diff --git a/product/src/gui/plugin/LinkCtrlWidget/CHistoryActionModel.h b/product/src/gui/plugin/LinkCtrlWidget/CHistoryActionModel.h index 98ae6605..0b22080d 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CHistoryActionModel.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CHistoryActionModel.h @@ -1,71 +1,71 @@ -#ifndef CHISTORYACTIONMODEL_H -#define CHISTORYACTIONMODEL_H - -#include -#include "link_history_def.h" - -namespace History_Action_Column -{ - const int nameColumn = 0; - const int locationColumn = 1; - const int descriptColumn = 2; - const int resultColumn = 3; -} - -class CHistoryActionTreeModelItem : public QObject -{ - Q_OBJECT - friend class CHistoryActionModel; - -public: - CHistoryActionTreeModelItem(CHistoryActionTreeModelItem * parent = Q_NULLPTR); - CHistoryActionTreeModelItem(const QList &data, CHistoryActionTreeModelItem * parent = Q_NULLPTR); - ~CHistoryActionTreeModelItem(); - - bool isRootItem(); - CHistoryActionTreeModelItem * parent(); - CHistoryActionTreeModelItem * child(const int row); - void appendChild(CHistoryActionTreeModelItem *child); - void removeChild(CHistoryActionTreeModelItem *child); - void clear(); - - int row(); - int childCount(); - int columnCount(); - QVariant data(QModelIndex index); - bool setData(QModelIndex index, const QVariant &value); - -private: - CHistoryActionTreeModelItem * m_parent; - QList m_data; - QList m_listChild; -}; - -class CHistoryActionModel : public QAbstractItemModel -{ - Q_OBJECT -public: - explicit CHistoryActionModel(QObject *parent = nullptr); - - void updateModelFunctionData(const QList &listFuncInfo); - - void updateModelActionData(const QList &listActionInfo); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: - QStringList m_header; - CHistoryActionTreeModelItem * m_rootItem; -}; - -#endif // CHISTORYACTIONMODEL_H +#ifndef CHISTORYACTIONMODEL_H +#define CHISTORYACTIONMODEL_H + +#include +#include "link_history_def.h" + +namespace History_Action_Column +{ + const int nameColumn = 0; + const int locationColumn = 1; + const int descriptColumn = 2; + const int resultColumn = 3; +} + +class CHistoryActionTreeModelItem : public QObject +{ + Q_OBJECT + friend class CHistoryActionModel; + +public: + CHistoryActionTreeModelItem(CHistoryActionTreeModelItem * parent = Q_NULLPTR); + CHistoryActionTreeModelItem(const QList &data, CHistoryActionTreeModelItem * parent = Q_NULLPTR); + ~CHistoryActionTreeModelItem(); + + bool isRootItem(); + CHistoryActionTreeModelItem * parent(); + CHistoryActionTreeModelItem * child(const int row); + void appendChild(CHistoryActionTreeModelItem *child); + void removeChild(CHistoryActionTreeModelItem *child); + void clear(); + + int row(); + int childCount(); + int columnCount(); + QVariant data(QModelIndex index); + bool setData(QModelIndex index, const QVariant &value); + +private: + CHistoryActionTreeModelItem * m_parent; + QList m_data; + QList m_listChild; +}; + +class CHistoryActionModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit CHistoryActionModel(QObject *parent = nullptr); + + void updateModelFunctionData(const QList &listFuncInfo); + + void updateModelActionData(const QList &listActionInfo); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QStringList m_header; + CHistoryActionTreeModelItem * m_rootItem; +}; + +#endif // CHISTORYACTIONMODEL_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.cpp b/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.cpp index ec17ae6c..320d6c2b 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.cpp @@ -1,139 +1,139 @@ -#include "CHistoryLinkFilterDialog.h" -#include "ui_CHistoryLinkFilterDialog.h" - -CHistoryLinkFilterDialog::CHistoryLinkFilterDialog(QStringList locationList, QStringList userNameList, QWidget *parent) : - QDialog(parent), - ui(new Ui::CHistoryLinkFilterDialog) -{ - ui->setupUi(this); - ui->locationListWidget->insertItems(0, locationList); - ui->userListWidget->insertItems(0, userNameList); - - QStringList resultList; - resultList << tr("执行成功") << tr("执行失败") << tr("执行终止") << tr("执行跳过"); - ui->resultListWidget->insertItems(0, resultList); - connect(this, &CHistoryLinkFilterDialog::accepted, this, &CHistoryLinkFilterDialog::updateFilter); -} - -CHistoryLinkFilterDialog::~CHistoryLinkFilterDialog() -{ - delete ui; -} - -void CHistoryLinkFilterDialog::initialize(const History_Filter_Condition &condition) -{ - m_linkFilterCondition = condition; - ui->locationFilter->setChecked(m_linkFilterCondition.locationFilter); - ui->userFilter->setChecked(m_linkFilterCondition.userFilter); - ui->resultFilter->setChecked(m_linkFilterCondition.resultFilter); - ui->typeFilter->setChecked(m_linkFilterCondition.typeFilter); - ui->timeFilter->setChecked(m_linkFilterCondition.timeFilter); - - for(int nIndex(0); nIndex < ui->locationListWidget->count(); nIndex++) - { - QString locationName = ui->locationListWidget->item(nIndex)->text(); - if(m_linkFilterCondition.locationList.contains(locationName)) - { - ui->locationListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); - } - } - - for(int nIndex(0); nIndex < ui->userListWidget->count(); nIndex++) - { - QString userName = ui->userListWidget->item(nIndex)->text(); - if(m_linkFilterCondition.userList.contains(userName)) - { - ui->userListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); - } - } - - for(int nIndex(0); nIndex < ui->resultListWidget->count(); nIndex++) - { - QString result = ui->resultListWidget->item(nIndex)->text(); - if(m_linkFilterCondition.resultList.contains(result)) - { - ui->resultListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); - } - } - - if(m_linkFilterCondition.isStandardType) - { - ui->standardLink->setChecked(true); - } - else - { - ui->customLink->setChecked(true); - } - - ui->startTime->blockSignals(true); - ui->endTime->blockSignals(true); - ui->startTime->setDateTime(m_linkFilterCondition.startTime); - ui->endTime->setDateTime(m_linkFilterCondition.endTime); - ui->startTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); - ui->endTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); - ui->startTime->blockSignals(false); - ui->endTime->blockSignals(false); -} - -History_Filter_Condition CHistoryLinkFilterDialog::LinkFilterCondition() -{ - return m_linkFilterCondition; -} - -void CHistoryLinkFilterDialog::updateFilter() -{ - m_linkFilterCondition.locationFilter = ui->locationFilter->isChecked(); - m_linkFilterCondition.userFilter = ui->userFilter->isChecked(); - m_linkFilterCondition.resultFilter = ui->resultFilter->isChecked(); - m_linkFilterCondition.typeFilter = ui->typeFilter->isChecked(); - m_linkFilterCondition.timeFilter = ui->timeFilter->isChecked(); - - m_linkFilterCondition.locationList.clear(); - foreach (QListWidgetItem* item, ui->locationListWidget->selectedItems()) - { - m_linkFilterCondition.locationList.append(item->text()); - } - - m_linkFilterCondition.userList.clear(); - foreach (QListWidgetItem* item, ui->userListWidget->selectedItems()) - { - m_linkFilterCondition.userList.append(item->text()); - } - - m_linkFilterCondition.resultList.clear(); - foreach (QListWidgetItem* item, ui->resultListWidget->selectedItems()) - { - m_linkFilterCondition.resultList.append(item->text()); - } - - m_linkFilterCondition.isStandardType = ui->standardLink->isChecked(); - - m_linkFilterCondition.startTime = ui->startTime->dateTime(); - m_linkFilterCondition.endTime = ui->endTime->dateTime(); -} - -void CHistoryLinkFilterDialog::on_startTime_dateTimeChanged(const QDateTime &dateTime) -{ - qint64 endTime = ui->endTime->dateTime().toMSecsSinceEpoch(); - if(dateTime.toMSecsSinceEpoch() > endTime) - { - QDateTime startTime = QDateTime::fromMSecsSinceEpoch(endTime); - QTime time = startTime.time(); - time.setHMS(time.hour(), time.minute(), time.second(), 0); - startTime.setTime(time); - ui->startTime->setDateTime(startTime); - } -} - -void CHistoryLinkFilterDialog::on_endTime_dateTimeChanged(const QDateTime &dateTime) -{ - qint64 startTime = ui->startTime->dateTime().toMSecsSinceEpoch(); - if(dateTime.toMSecsSinceEpoch() < startTime) - { - QDateTime endTime = QDateTime::fromMSecsSinceEpoch(startTime); - QTime time = endTime.time(); - time.setHMS(time.hour(), time.minute(), time.second(), 999); - endTime.setTime(time); - ui->endTime->setDateTime(endTime); - } -} +#include "CHistoryLinkFilterDialog.h" +#include "ui_CHistoryLinkFilterDialog.h" + +CHistoryLinkFilterDialog::CHistoryLinkFilterDialog(QStringList locationList, QStringList userNameList, QWidget *parent) : + QDialog(parent), + ui(new Ui::CHistoryLinkFilterDialog) +{ + ui->setupUi(this); + ui->locationListWidget->insertItems(0, locationList); + ui->userListWidget->insertItems(0, userNameList); + + QStringList resultList; + resultList << tr("执行成功") << tr("执行失败") << tr("执行终止") << tr("执行跳过"); + ui->resultListWidget->insertItems(0, resultList); + connect(this, &CHistoryLinkFilterDialog::accepted, this, &CHistoryLinkFilterDialog::updateFilter); +} + +CHistoryLinkFilterDialog::~CHistoryLinkFilterDialog() +{ + delete ui; +} + +void CHistoryLinkFilterDialog::initialize(const History_Filter_Condition &condition) +{ + m_linkFilterCondition = condition; + ui->locationFilter->setChecked(m_linkFilterCondition.locationFilter); + ui->userFilter->setChecked(m_linkFilterCondition.userFilter); + ui->resultFilter->setChecked(m_linkFilterCondition.resultFilter); + ui->typeFilter->setChecked(m_linkFilterCondition.typeFilter); + ui->timeFilter->setChecked(m_linkFilterCondition.timeFilter); + + for(int nIndex(0); nIndex < ui->locationListWidget->count(); nIndex++) + { + QString locationName = ui->locationListWidget->item(nIndex)->text(); + if(m_linkFilterCondition.locationList.contains(locationName)) + { + ui->locationListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); + } + } + + for(int nIndex(0); nIndex < ui->userListWidget->count(); nIndex++) + { + QString userName = ui->userListWidget->item(nIndex)->text(); + if(m_linkFilterCondition.userList.contains(userName)) + { + ui->userListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); + } + } + + for(int nIndex(0); nIndex < ui->resultListWidget->count(); nIndex++) + { + QString result = ui->resultListWidget->item(nIndex)->text(); + if(m_linkFilterCondition.resultList.contains(result)) + { + ui->resultListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); + } + } + + if(m_linkFilterCondition.isStandardType) + { + ui->standardLink->setChecked(true); + } + else + { + ui->customLink->setChecked(true); + } + + ui->startTime->blockSignals(true); + ui->endTime->blockSignals(true); + ui->startTime->setDateTime(m_linkFilterCondition.startTime); + ui->endTime->setDateTime(m_linkFilterCondition.endTime); + ui->startTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); + ui->endTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); + ui->startTime->blockSignals(false); + ui->endTime->blockSignals(false); +} + +History_Filter_Condition CHistoryLinkFilterDialog::LinkFilterCondition() +{ + return m_linkFilterCondition; +} + +void CHistoryLinkFilterDialog::updateFilter() +{ + m_linkFilterCondition.locationFilter = ui->locationFilter->isChecked(); + m_linkFilterCondition.userFilter = ui->userFilter->isChecked(); + m_linkFilterCondition.resultFilter = ui->resultFilter->isChecked(); + m_linkFilterCondition.typeFilter = ui->typeFilter->isChecked(); + m_linkFilterCondition.timeFilter = ui->timeFilter->isChecked(); + + m_linkFilterCondition.locationList.clear(); + foreach (QListWidgetItem* item, ui->locationListWidget->selectedItems()) + { + m_linkFilterCondition.locationList.append(item->text()); + } + + m_linkFilterCondition.userList.clear(); + foreach (QListWidgetItem* item, ui->userListWidget->selectedItems()) + { + m_linkFilterCondition.userList.append(item->text()); + } + + m_linkFilterCondition.resultList.clear(); + foreach (QListWidgetItem* item, ui->resultListWidget->selectedItems()) + { + m_linkFilterCondition.resultList.append(item->text()); + } + + m_linkFilterCondition.isStandardType = ui->standardLink->isChecked(); + + m_linkFilterCondition.startTime = ui->startTime->dateTime(); + m_linkFilterCondition.endTime = ui->endTime->dateTime(); +} + +void CHistoryLinkFilterDialog::on_startTime_dateTimeChanged(const QDateTime &dateTime) +{ + qint64 endTime = ui->endTime->dateTime().toMSecsSinceEpoch(); + if(dateTime.toMSecsSinceEpoch() > endTime) + { + QDateTime startTime = QDateTime::fromMSecsSinceEpoch(endTime); + QTime time = startTime.time(); + time.setHMS(time.hour(), time.minute(), time.second(), 0); + startTime.setTime(time); + ui->startTime->setDateTime(startTime); + } +} + +void CHistoryLinkFilterDialog::on_endTime_dateTimeChanged(const QDateTime &dateTime) +{ + qint64 startTime = ui->startTime->dateTime().toMSecsSinceEpoch(); + if(dateTime.toMSecsSinceEpoch() < startTime) + { + QDateTime endTime = QDateTime::fromMSecsSinceEpoch(startTime); + QTime time = endTime.time(); + time.setHMS(time.hour(), time.minute(), time.second(), 999); + endTime.setTime(time); + ui->endTime->setDateTime(endTime); + } +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.h b/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.h index 6fa7c4fa..9e7d3885 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.h @@ -1,67 +1,67 @@ -#ifndef CHISTORYLINKFILTERDIALOG_H -#define CHISTORYLINKFILTERDIALOG_H - -#include -#include - -namespace Ui { -class CHistoryLinkFilterDialog; -} - -struct History_Filter_Condition -{ - History_Filter_Condition() - { - locationFilter = false; - locationList = QStringList(); - userFilter = false; - userList = QStringList(); - resultFilter = false; - resultList = QStringList(); - typeFilter = false; - isStandardType = true; - timeFilter = false; - startTime = QDateTime(QDate::currentDate()); - endTime = QDateTime::currentDateTime(); - } - - bool locationFilter; - QStringList locationList; - bool userFilter; - QStringList userList; - bool resultFilter; - QStringList resultList; - bool typeFilter; - bool isStandardType; - bool timeFilter; - QDateTime startTime; - QDateTime endTime; -}; - -class CHistoryLinkFilterDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CHistoryLinkFilterDialog(QStringList locationList, QStringList userNameList, QWidget *parent = 0); - ~CHistoryLinkFilterDialog(); - - void initialize(const History_Filter_Condition &condition); - - History_Filter_Condition LinkFilterCondition(); - -protected slots: - void updateFilter(); - -private slots: - void on_startTime_dateTimeChanged(const QDateTime &dateTime); - - void on_endTime_dateTimeChanged(const QDateTime &dateTime); - -private: - Ui::CHistoryLinkFilterDialog *ui; - - History_Filter_Condition m_linkFilterCondition; -}; - -#endif // CHISTORYLINKFILTERDIALOG_H +#ifndef CHISTORYLINKFILTERDIALOG_H +#define CHISTORYLINKFILTERDIALOG_H + +#include +#include + +namespace Ui { +class CHistoryLinkFilterDialog; +} + +struct History_Filter_Condition +{ + History_Filter_Condition() + { + locationFilter = false; + locationList = QStringList(); + userFilter = false; + userList = QStringList(); + resultFilter = false; + resultList = QStringList(); + typeFilter = false; + isStandardType = true; + timeFilter = false; + startTime = QDateTime(QDate::currentDate()); + endTime = QDateTime::currentDateTime(); + } + + bool locationFilter; + QStringList locationList; + bool userFilter; + QStringList userList; + bool resultFilter; + QStringList resultList; + bool typeFilter; + bool isStandardType; + bool timeFilter; + QDateTime startTime; + QDateTime endTime; +}; + +class CHistoryLinkFilterDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CHistoryLinkFilterDialog(QStringList locationList, QStringList userNameList, QWidget *parent = 0); + ~CHistoryLinkFilterDialog(); + + void initialize(const History_Filter_Condition &condition); + + History_Filter_Condition LinkFilterCondition(); + +protected slots: + void updateFilter(); + +private slots: + void on_startTime_dateTimeChanged(const QDateTime &dateTime); + + void on_endTime_dateTimeChanged(const QDateTime &dateTime); + +private: + Ui::CHistoryLinkFilterDialog *ui; + + History_Filter_Condition m_linkFilterCondition; +}; + +#endif // CHISTORYLINKFILTERDIALOG_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.ui b/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.ui index 568ee5a7..b2610e29 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.ui +++ b/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkFilterDialog.ui @@ -1,236 +1,236 @@ - - - CHistoryLinkFilterDialog - - - - 0 - 0 - 543 - 418 - - - - 过滤 - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - - - - - 位置 - - - true - - - false - - - - - - QAbstractItemView::MultiSelection - - - - - - - - - - 用户 - - - true - - - false - - - - - - QAbstractItemView::MultiSelection - - - - - - - - - - 结果 - - - true - - - false - - - - - - QAbstractItemView::MultiSelection - - - - - - - - - - - - 9 - - - - - 类型 - - - true - - - false - - - - - - 标准联动 - - - true - - - - - - - 自定义联动 - - - - - - - - - - 时间 - - - true - - - false - - - - - - - - 起始时间: - - - - - - - - - - 结束时间: - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - CHistoryLinkFilterDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - CHistoryLinkFilterDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - + + + CHistoryLinkFilterDialog + + + + 0 + 0 + 543 + 418 + + + + 过滤 + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + + 位置 + + + true + + + false + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + + 用户 + + + true + + + false + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + + 结果 + + + true + + + false + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + + + + 9 + + + + + 类型 + + + true + + + false + + + + + + 标准联动 + + + true + + + + + + + 自定义联动 + + + + + + + + + + 时间 + + + true + + + false + + + + + + + + 起始时间: + + + + + + + + + + 结束时间: + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + CHistoryLinkFilterDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CHistoryLinkFilterDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkModel.h b/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkModel.h index 48e220ea..4d5f6f02 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkModel.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CHistoryLinkModel.h @@ -1,50 +1,50 @@ -#ifndef CHISTORYLINKMODEL_H -#define CHISTORYLINKMODEL_H - -#include -#include "link_history_def.h" - -namespace History_Link_Column -{ - const int linkColumn = 0; - const int locationColumn = 1; - const int timeColumn = 2; - const int userColumn = 3; - const int typeColumn = 4; - const int resultColumn = 5; -} - -class CHistoryLinkModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - explicit CHistoryLinkModel(QObject *parent = nullptr); - - void setHistoryLinkData(QList listLink); - - QString LinkName(const QModelIndex &index); - - quint64 LinkTime(const QModelIndex &index); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &child) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - bool setLinkTypeList(QStringList linkList); - -private: - QStringList m_header; - QStringList m_linkType; - QList m_data; -}; - -#endif // CHISTORYLINKMODEL_H +#ifndef CHISTORYLINKMODEL_H +#define CHISTORYLINKMODEL_H + +#include +#include "link_history_def.h" + +namespace History_Link_Column +{ + const int linkColumn = 0; + const int locationColumn = 1; + const int timeColumn = 2; + const int userColumn = 3; + const int typeColumn = 4; + const int resultColumn = 5; +} + +class CHistoryLinkModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CHistoryLinkModel(QObject *parent = nullptr); + + void setHistoryLinkData(QList listLink); + + QString LinkName(const QModelIndex &index); + + quint64 LinkTime(const QModelIndex &index); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + bool setLinkTypeList(QStringList linkList); + +private: + QStringList m_header; + QStringList m_linkType; + QList m_data; +}; + +#endif // CHISTORYLINKMODEL_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CHistroyLinkModel.cpp b/product/src/gui/plugin/LinkCtrlWidget/CHistroyLinkModel.cpp index ad379796..e7e3bb1a 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CHistroyLinkModel.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CHistroyLinkModel.cpp @@ -1,145 +1,145 @@ -#include "CHistoryLinkModel.h" -#include - -CHistoryLinkModel::CHistoryLinkModel(QObject *parent) - : QAbstractItemModel(parent) -{ - m_header << tr("名称") << tr("位置") << tr("时间") << tr("用户") << tr("类型") << tr("执行结果"); -} - -void CHistoryLinkModel::setHistoryLinkData(QList listLink) -{ - beginResetModel(); - m_data.clear(); - m_data = listLink; - endResetModel(); -} - -QString CHistoryLinkModel::LinkName(const QModelIndex &index) -{ - if(!index.isValid()) - { - return QString(); - } - return m_data[index.row()].linkName; -} - -quint64 CHistoryLinkModel::LinkTime(const QModelIndex &index) -{ - if(!index.isValid()) - { - return 0; - } - return m_data[index.row()].time; -} - -QVariant CHistoryLinkModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::Horizontal != orientation || Qt::DisplayRole != role) - { - return QVariant(); - } - return m_header[section]; -} - -QModelIndex CHistoryLinkModel::index(int row, int column, const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return createIndex(row, column); -} - -QModelIndex CHistoryLinkModel::parent(const QModelIndex &child) const -{ - Q_UNUSED(child) - return QModelIndex(); -} - -int CHistoryLinkModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_data.size(); -} - -int CHistoryLinkModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.size(); -} - -QVariant CHistoryLinkModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || (Qt::DisplayRole != role && Qt::TextAlignmentRole != role)) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - - if(Qt::DisplayRole == role) - { - switch (index.column()) - { - case History_Link_Column::linkColumn: - { - return m_data[index.row()].linkDescription; - } - case History_Link_Column::locationColumn: - { - return m_data[index.row()].location; - } - case History_Link_Column::timeColumn: - { - QDateTime dt = QDateTime::fromSecsSinceEpoch(m_data[index.row()].time); - dt.setTimeSpec(Qt::LocalTime); - return dt.toString("yyyy-MM-dd hh:mm:ss"); - } - case History_Link_Column::userColumn: - { - return m_data[index.row()].userName; - } - case History_Link_Column::typeColumn: - { -// if(0 == m_data[index.row()].linkType) -// { -// return tr("标准顺控"); -// } -// else if(1 == m_data[index.row()].linkType) -// { -// return tr("自定义顺控"); -// } -// return m_data[index.row()].linkType; - - for(int dex = 0;dex < m_linkType.size(); dex++) - { - if(m_data[index.row()].linkType == dex) - { - return m_linkType.at(dex); - } - } - return m_data[index.row()].linkType; - } - case History_Link_Column::resultColumn: - { - return m_data[index.row()].status; - } - default: - { - break; - } - } - } - return QVariant(); -} - -bool CHistoryLinkModel::setLinkTypeList(QStringList linkList) -{ - m_linkType = linkList; - return true; -} +#include "CHistoryLinkModel.h" +#include + +CHistoryLinkModel::CHistoryLinkModel(QObject *parent) + : QAbstractItemModel(parent) +{ + m_header << tr("名称") << tr("位置") << tr("时间") << tr("用户") << tr("类型") << tr("执行结果"); +} + +void CHistoryLinkModel::setHistoryLinkData(QList listLink) +{ + beginResetModel(); + m_data.clear(); + m_data = listLink; + endResetModel(); +} + +QString CHistoryLinkModel::LinkName(const QModelIndex &index) +{ + if(!index.isValid()) + { + return QString(); + } + return m_data[index.row()].linkName; +} + +quint64 CHistoryLinkModel::LinkTime(const QModelIndex &index) +{ + if(!index.isValid()) + { + return 0; + } + return m_data[index.row()].time; +} + +QVariant CHistoryLinkModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::Horizontal != orientation || Qt::DisplayRole != role) + { + return QVariant(); + } + return m_header[section]; +} + +QModelIndex CHistoryLinkModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return createIndex(row, column); +} + +QModelIndex CHistoryLinkModel::parent(const QModelIndex &child) const +{ + Q_UNUSED(child) + return QModelIndex(); +} + +int CHistoryLinkModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_data.size(); +} + +int CHistoryLinkModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.size(); +} + +QVariant CHistoryLinkModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || (Qt::DisplayRole != role && Qt::TextAlignmentRole != role)) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + if(Qt::DisplayRole == role) + { + switch (index.column()) + { + case History_Link_Column::linkColumn: + { + return m_data[index.row()].linkDescription; + } + case History_Link_Column::locationColumn: + { + return m_data[index.row()].location; + } + case History_Link_Column::timeColumn: + { + QDateTime dt = QDateTime::fromSecsSinceEpoch(m_data[index.row()].time); + dt.setTimeSpec(Qt::LocalTime); + return dt.toString("yyyy-MM-dd hh:mm:ss"); + } + case History_Link_Column::userColumn: + { + return m_data[index.row()].userName; + } + case History_Link_Column::typeColumn: + { +// if(0 == m_data[index.row()].linkType) +// { +// return tr("标准顺控"); +// } +// else if(1 == m_data[index.row()].linkType) +// { +// return tr("自定义顺控"); +// } +// return m_data[index.row()].linkType; + + for(int dex = 0;dex < m_linkType.size(); dex++) + { + if(m_data[index.row()].linkType == dex) + { + return m_linkType.at(dex); + } + } + return m_data[index.row()].linkType; + } + case History_Link_Column::resultColumn: + { + return m_data[index.row()].status; + } + default: + { + break; + } + } + } + return QVariant(); +} + +bool CHistoryLinkModel::setLinkTypeList(QStringList linkList) +{ + m_linkType = linkList; + return true; +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlDataManage.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlDataManage.cpp index 9e4b6e43..5a168e1f 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlDataManage.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlDataManage.cpp @@ -1,413 +1,413 @@ -#include "CLinkCtrlDataManage.h" -#include "linkctrl_def.h" -#include "CLinkCtrlMessageHandle.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include -#include -#include - -using namespace kbd_dbms; -using namespace kbd_idlfile::linkage; - -CLinkCtrlDataManage::CLinkCtrlDataManage(QObject *parent) - : QObject(parent), - m_Timer(NULL), - m_linkCtrlMsgHandle(NULL) -{ - //关系库 - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - - //网络实时库 - m_rdbNetApi = new CRdbNetApi(); - - m_linkCtrlMsgHandle = new CLinkCtrlMessageHandle(this); -} - -CLinkCtrlDataManage::~CLinkCtrlDataManage() -{ - if(m_linkCtrlMsgHandle) - { - delete m_linkCtrlMsgHandle; - } - m_linkCtrlMsgHandle = NULL; - - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(m_rdbNetApi) - { - delete m_rdbNetApi; - } - m_rdbNetApi = NULL; -} - -QList CLinkCtrlDataManage::queryLinkCtrlList() -{ - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - spSysInfo->getLocalNodeInfo(stNodeInfo); - } - - QList linkageList; - if(!m_pReadDb->isOpen()) - { - return linkageList; - } - //<查询联动 - QSqlQuery query; - QString sqlSequenceQuery = QString("select name, description, exec_type, link_type, location_id, timeflag from %1").arg(LINKAGE_SETTING); - m_pReadDb->execute(sqlSequenceQuery, query); - if(query.isActive()) - { - while(query.next()) - { - S_LINKCTRL_INFO info; - info.nodeType = E_Node_LinkCtrl; - info.linkageName = query.value(0).toString(); - info.linkageDescription = query.value(1).toString(); - info.exeType = query.value(2).toInt(); - info.linkType = query.value(3).toInt(); - info.locationID = query.value(4).toInt(); - if(stNodeInfo.nLocationId != info.locationID) - { - continue; - } - info.timeFlag = query.value(5).toULongLong(); - linkageList.append(info); - } - } - return linkageList; -} - -QList CLinkCtrlDataManage::queryLinkFunctionList(const QString &linkCtrlName) -{ - QList LinkList; - QList linkFuncList; - if(!m_pReadDb->isOpen()) - { - return QList(); - } - - //<查询功能 - QSqlQuery query; - QString sqlSequenceQuery = QString("select DISTINCT \ - %1.linkage_name, \ - %1.func_name, \ - %2.description, \ - %1.func_no, \ - %1.relation, \ - %1.timeflag \ - FROM \ - %1 LEFT JOIN %2 ON \ - %1.func_name = %2.name \ - WHERE \ - %1.linkage_name = '%3'").arg(LINKAGE_DEFINE).arg(LINKAGE_FUNCTION).arg(linkCtrlName); - m_pReadDb->execute(sqlSequenceQuery, query); - if(query.isActive()) - { - QStringList funcNameList; - while(query.next()) - { - S_LINKCTRL_INFO info; - info.nodeType = E_Node_Function; - info.linkageName = query.value(0).toString(); - info.funcName = query.value(1).toString(); - if(funcNameList.contains(info.funcName)) - { - Q_ASSERT(false); - } - else - { - funcNameList.append(info.funcName); - } - - info.funcDescription = query.value(2).toString(); - info.funcNo = query.value(3).toInt(); - info.relation = query.value(4).toInt(); - info.timeFlag = query.value(5).toULongLong(); - if (linkCtrlName == info.linkageName) - { - bool result = false; - for (int nIndex(0); nIndex < linkFuncList.size(); nIndex++) - { - if (info.funcNo < linkFuncList[nIndex].funcNo) - { - linkFuncList.insert(nIndex, info); - result = true; - break; - } - } - if (!result) - { - linkFuncList.append(info); - } - } - } - LinkList.append(linkFuncList); - - } - - //<查询动作 - for(int nIndex(0); nIndex < linkFuncList.size(); nIndex++) - { - QList linkActionList; - sqlSequenceQuery = QString("SELECT \ - %1.linkage_name, \ - %1.func_name, \ - %1.func_no, \ - %2.action_no, \ - %2.action_name,\ - %3.description,\ - %2.delaytime, \ - %2.failstrage, \ - %3.timeflag \ - FROM \ - %1, \ - %2, \ - %3 \ - WHERE \ - %1.func_name = '%4' \ - AND %1.func_name = %2.name \ - AND %2.action_name = %3.name").arg(LINKAGE_DEFINE).arg(LINKAGE_FUNCTION).arg(LINKAGE_ACTION).arg(linkFuncList[nIndex].funcName); - m_pReadDb->execute(sqlSequenceQuery, query); - if(query.isActive()) - { - while(query.next()) - { - S_LINKCTRL_INFO info; - info.nodeType = E_Node_Action; - info.linkageName = query.value(0).toString(); - info.funcName = query.value(1).toString(); - info.funcNo = query.value(2).toInt(); - info.actionNo = query.value(3).toInt(); - info.actionName = query.value(4).toString(); - info.actionDescription = query.value(5).toString(); - info.delayTime = query.value(6).toULongLong(); - info.fallStrage = query.value(7).toInt(); - info.timeFlag = query.value(8).toULongLong(); - info.relation = -1; - if (linkCtrlName == info.linkageName) - { - bool result = false; - for (int i(0); i < linkActionList.size(); i++) - { - if (info.actionNo < linkActionList[i].actionNo) - { - linkActionList.insert(i, info); - result = true; - break; - } - } - if (!result) - { - linkActionList.append(info); - } - } - } - } - LinkList.append(linkActionList); - } - - return LinkList; -} - -void CLinkCtrlDataManage::requestLinkOperation(const int &nDomainID, const QString &linkName, const quint64 &timeFlag, const E_LCS_STATUS &nodeState, const QList &nodeList, const E_LINK_OPERATETYPE & type) -{ - int nUserId = -1; - int nUserGrpId = -1; - std::string strUserName = ""; - int nLevel = -1; - int nLoginSec = -1; - std::string strInstanceName = ""; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - if(0 == permMngPtr->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - permMngPtr->GetUserAliasByUserId(nUserId, strUserName); - } - else - { - LOGERROR("请求联动操作[权限获取失败]!"); - return; - } - } - else - { - LOGERROR("请求联动操作[创建权限闭锁参数访问接口实例]!"); - return; - } - - LinkOperateMessage msg; - LcsPkgHead * head = new LcsPkgHead(); - head->set_source_tag("hmi"); - head->set_msg_type((enLcsMsgType)E_LinkOperate_Message); - - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - spSysInfo->getLocalNodeInfo(stNodeInfo); - } - head->set_source_domain(stNodeInfo.nDomainId); - head->set_target_domain(nDomainID); - head->set_para1(0); - head->set_para2(0); - msg.set_allocated_pkg_head(head); - - LOGINFO("Linkage RequestLinkOperation[source_domain: %d, target_domain: %d]", stNodeInfo.nDomainId, nDomainID); - LinkNodeStatusParameter * linkNodeParameter = new LinkNodeStatusParameter(); - linkNodeParameter->set_link_name(linkName.toStdString()); - linkNodeParameter->set_check_state(enumnodePartiallyChecked); - linkNodeParameter->set_timeflag(timeFlag); - linkNodeParameter->set_node_state((ENLcsStatus)nodeState); - linkNodeParameter->set_link_desc(""); - msg.set_allocated_link_node(linkNodeParameter); - - - - foreach(S_LINKCTRL_INFO info, nodeList) - { - if (info.nodeType == 1) - { - FucNodeStatusParameter * functionNodeParameter = linkNodeParameter->add_nodelist(); - functionNodeParameter->set_fuc_name(info.funcName.toStdString()); - functionNodeParameter->set_check_state((ENLcsNodeCheckStatus)info.checked); - functionNodeParameter->set_timeflag(info.timeFlag); - functionNodeParameter->set_node_state((ENLcsStatus)info.status); - functionNodeParameter->set_fuc_desc(""); - } - } - - foreach(S_LINKCTRL_INFO info, nodeList) - { - if (info.nodeType == 2) - { - for (int nIndex(0); nIndex < linkNodeParameter->nodelist_size(); nIndex++) - { - if (info.funcName.toStdString() == linkNodeParameter->nodelist(nIndex).fuc_name()) - { - ActionNodeStatusParameter * actionNodeParameter = linkNodeParameter->mutable_nodelist(nIndex)->add_nodelist(); - actionNodeParameter->set_action_name(info.actionName.toStdString()); - actionNodeParameter->set_check_state((ENLcsNodeCheckStatus)info.checked); - actionNodeParameter->set_timeflag(info.timeFlag); - actionNodeParameter->set_node_state((ENLcsStatus)info.status); - actionNodeParameter->set_action_desc(""); - } - } - } - } - - ActorParameter * actorParameter = msg.mutable_actor(); - actorParameter->set_user_id(nUserId); - actorParameter->set_user_groupid(nUserGrpId); - actorParameter->set_host_name(stNodeInfo.strName); - actorParameter->set_user_name(strUserName); - msg.set_opreate_type((ENLinkOperateType)type); - try - { - m_linkCtrlMsgHandle->linkOperateRequest(msg); - } - catch (const std::exception& e) - { - qDebug() << e.what(); - } - -} - -bool CLinkCtrlDataManage::receiveLinkOperateAck(kbd_idlfile::linkage::LinkOperateMessageAck &msg) -{ - if (msg.has_execute_status()) - { - QString strLinkDescription = QString::fromStdString(msg.link_node().link_desc()); - E_LINK_OPERATETYPE type = (E_LINK_OPERATETYPE)msg.opreate_type(); - ExecuteStatusParameter * parameter = msg.mutable_execute_status(); - if (0 != parameter->statuscode()) - { - int nErrorCode = parameter->erro_param().errorcode(); - QString strErrorDescription = QString::fromStdString(parameter->erro_param().errordescription()); - emit sigRequestLinkOperationFail(strLinkDescription, type, nErrorCode, strErrorDescription); - } - } - return true; -} - -bool CLinkCtrlDataManage::recvUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage &msg) -{ - kbd_idlfile::linkage::UiRequestMessage * requestMessage = new kbd_idlfile::linkage::UiRequestMessage(msg); - emit sigRecvLinkUserInterveneRequest(requestMessage); - return true; -} - -void CLinkCtrlDataManage::replyUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessageAck &msg) -{ - try - { - m_linkCtrlMsgHandle->userInterveneResponse(msg); - } - catch (const std::exception&e) - { - qDebug() << e.what(); - } - -} - -bool CLinkCtrlDataManage::recvLinkStartRequest(kbd_idlfile::linkage::LinkStartRequestMessage &msg) -{ - quint64 triggerTime = msg.trigger_time(); - LinkNodeStatusParameter * linkNodeParameter = msg.mutable_nodelist(); - QString strLinkName = QString::fromStdString(linkNodeParameter->link_name()); - int nLinkState = (int)linkNodeParameter->node_state(); - emit sigLinkAgeStart(strLinkName, nLinkState, triggerTime); - return true; -} - -bool CLinkCtrlDataManage::recvLinkStateChange(kbd_idlfile::linkage::StatusChangeMessage &msg) -{ - try - { - LinkNodeStatusParameter * linkNodeParameter = msg.mutable_nodelist(); - QString strLinkName = QString::fromStdString(linkNodeParameter->link_name()); - int nLinkState = (int)linkNodeParameter->node_state(); - quint64 nTimeFlag = linkNodeParameter->timeflag(); - //< 消息内没有触发事件,第三个参数triggerTime为0表示不刷新此值 - emit sigUpdateLinkAgeState(strLinkName, nLinkState, 0, nTimeFlag); - if (linkNodeParameter->nodelist_size() > 0) - { - for (int nFunctionIndex(0); nFunctionIndex < linkNodeParameter->nodelist_size(); nFunctionIndex++) - { - FucNodeStatusParameter fucNodeStatusParameter = linkNodeParameter->nodelist(nFunctionIndex); - QString strFunctionName = QString::fromStdString(fucNodeStatusParameter.fuc_name()); - int nFunctionState = (int)fucNodeStatusParameter.node_state(); - emit sigUpdateFunctionState(strLinkName, strFunctionName, nFunctionState); - if (fucNodeStatusParameter.nodelist_size() > 0) - { - for (int nActionndex(0); nActionndex < linkNodeParameter->nodelist_size(); nActionndex++) - { - ActionNodeStatusParameter actionNodeStatusParameter = fucNodeStatusParameter.nodelist(nActionndex); - QString strActionName = QString::fromStdString(actionNodeStatusParameter.action_name()); - int nActionState = (int)actionNodeStatusParameter.node_state(); - emit sigUpdateActionState(strLinkName, strFunctionName, strActionName, nActionState); - } - } - } - } - return true; - } - catch(...) - { - qDebug() << "recvLinkStateChange, exception!"; - return false; - } -} - - +#include "CLinkCtrlDataManage.h" +#include "linkctrl_def.h" +#include "CLinkCtrlMessageHandle.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include +#include + +using namespace kbd_dbms; +using namespace kbd_idlfile::linkage; + +CLinkCtrlDataManage::CLinkCtrlDataManage(QObject *parent) + : QObject(parent), + m_Timer(NULL), + m_linkCtrlMsgHandle(NULL) +{ + //关系库 + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + //网络实时库 + m_rdbNetApi = new CRdbNetApi(); + + m_linkCtrlMsgHandle = new CLinkCtrlMessageHandle(this); +} + +CLinkCtrlDataManage::~CLinkCtrlDataManage() +{ + if(m_linkCtrlMsgHandle) + { + delete m_linkCtrlMsgHandle; + } + m_linkCtrlMsgHandle = NULL; + + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rdbNetApi) + { + delete m_rdbNetApi; + } + m_rdbNetApi = NULL; +} + +QList CLinkCtrlDataManage::queryLinkCtrlList() +{ + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + spSysInfo->getLocalNodeInfo(stNodeInfo); + } + + QList linkageList; + if(!m_pReadDb->isOpen()) + { + return linkageList; + } + //<查询联动 + QSqlQuery query; + QString sqlSequenceQuery = QString("select name, description, exec_type, link_type, location_id, timeflag from %1").arg(LINKAGE_SETTING); + m_pReadDb->execute(sqlSequenceQuery, query); + if(query.isActive()) + { + while(query.next()) + { + S_LINKCTRL_INFO info; + info.nodeType = E_Node_LinkCtrl; + info.linkageName = query.value(0).toString(); + info.linkageDescription = query.value(1).toString(); + info.exeType = query.value(2).toInt(); + info.linkType = query.value(3).toInt(); + info.locationID = query.value(4).toInt(); + if(stNodeInfo.nLocationId != info.locationID) + { + continue; + } + info.timeFlag = query.value(5).toULongLong(); + linkageList.append(info); + } + } + return linkageList; +} + +QList CLinkCtrlDataManage::queryLinkFunctionList(const QString &linkCtrlName) +{ + QList LinkList; + QList linkFuncList; + if(!m_pReadDb->isOpen()) + { + return QList(); + } + + //<查询功能 + QSqlQuery query; + QString sqlSequenceQuery = QString("select DISTINCT \ + %1.linkage_name, \ + %1.func_name, \ + %2.description, \ + %1.func_no, \ + %1.relation, \ + %1.timeflag \ + FROM \ + %1 LEFT JOIN %2 ON \ + %1.func_name = %2.name \ + WHERE \ + %1.linkage_name = '%3'").arg(LINKAGE_DEFINE).arg(LINKAGE_FUNCTION).arg(linkCtrlName); + m_pReadDb->execute(sqlSequenceQuery, query); + if(query.isActive()) + { + QStringList funcNameList; + while(query.next()) + { + S_LINKCTRL_INFO info; + info.nodeType = E_Node_Function; + info.linkageName = query.value(0).toString(); + info.funcName = query.value(1).toString(); + if(funcNameList.contains(info.funcName)) + { + Q_ASSERT(false); + } + else + { + funcNameList.append(info.funcName); + } + + info.funcDescription = query.value(2).toString(); + info.funcNo = query.value(3).toInt(); + info.relation = query.value(4).toInt(); + info.timeFlag = query.value(5).toULongLong(); + if (linkCtrlName == info.linkageName) + { + bool result = false; + for (int nIndex(0); nIndex < linkFuncList.size(); nIndex++) + { + if (info.funcNo < linkFuncList[nIndex].funcNo) + { + linkFuncList.insert(nIndex, info); + result = true; + break; + } + } + if (!result) + { + linkFuncList.append(info); + } + } + } + LinkList.append(linkFuncList); + + } + + //<查询动作 + for(int nIndex(0); nIndex < linkFuncList.size(); nIndex++) + { + QList linkActionList; + sqlSequenceQuery = QString("SELECT \ + %1.linkage_name, \ + %1.func_name, \ + %1.func_no, \ + %2.action_no, \ + %2.action_name,\ + %3.description,\ + %2.delaytime, \ + %2.failstrage, \ + %3.timeflag \ + FROM \ + %1, \ + %2, \ + %3 \ + WHERE \ + %1.func_name = '%4' \ + AND %1.func_name = %2.name \ + AND %2.action_name = %3.name").arg(LINKAGE_DEFINE).arg(LINKAGE_FUNCTION).arg(LINKAGE_ACTION).arg(linkFuncList[nIndex].funcName); + m_pReadDb->execute(sqlSequenceQuery, query); + if(query.isActive()) + { + while(query.next()) + { + S_LINKCTRL_INFO info; + info.nodeType = E_Node_Action; + info.linkageName = query.value(0).toString(); + info.funcName = query.value(1).toString(); + info.funcNo = query.value(2).toInt(); + info.actionNo = query.value(3).toInt(); + info.actionName = query.value(4).toString(); + info.actionDescription = query.value(5).toString(); + info.delayTime = query.value(6).toULongLong(); + info.fallStrage = query.value(7).toInt(); + info.timeFlag = query.value(8).toULongLong(); + info.relation = -1; + if (linkCtrlName == info.linkageName) + { + bool result = false; + for (int i(0); i < linkActionList.size(); i++) + { + if (info.actionNo < linkActionList[i].actionNo) + { + linkActionList.insert(i, info); + result = true; + break; + } + } + if (!result) + { + linkActionList.append(info); + } + } + } + } + LinkList.append(linkActionList); + } + + return LinkList; +} + +void CLinkCtrlDataManage::requestLinkOperation(const int &nDomainID, const QString &linkName, const quint64 &timeFlag, const E_LCS_STATUS &nodeState, const QList &nodeList, const E_LINK_OPERATETYPE & type) +{ + int nUserId = -1; + int nUserGrpId = -1; + std::string strUserName = ""; + int nLevel = -1; + int nLoginSec = -1; + std::string strInstanceName = ""; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + if(0 == permMngPtr->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + permMngPtr->GetUserAliasByUserId(nUserId, strUserName); + } + else + { + LOGERROR("请求联动操作[权限获取失败]!"); + return; + } + } + else + { + LOGERROR("请求联动操作[创建权限闭锁参数访问接口实例]!"); + return; + } + + LinkOperateMessage msg; + LcsPkgHead * head = new LcsPkgHead(); + head->set_source_tag("hmi"); + head->set_msg_type((enLcsMsgType)E_LinkOperate_Message); + + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + spSysInfo->getLocalNodeInfo(stNodeInfo); + } + head->set_source_domain(stNodeInfo.nDomainId); + head->set_target_domain(nDomainID); + head->set_para1(0); + head->set_para2(0); + msg.set_allocated_pkg_head(head); + + LOGINFO("Linkage RequestLinkOperation[source_domain: %d, target_domain: %d]", stNodeInfo.nDomainId, nDomainID); + LinkNodeStatusParameter * linkNodeParameter = new LinkNodeStatusParameter(); + linkNodeParameter->set_link_name(linkName.toStdString()); + linkNodeParameter->set_check_state(enumnodePartiallyChecked); + linkNodeParameter->set_timeflag(timeFlag); + linkNodeParameter->set_node_state((ENLcsStatus)nodeState); + linkNodeParameter->set_link_desc(""); + msg.set_allocated_link_node(linkNodeParameter); + + + + foreach(S_LINKCTRL_INFO info, nodeList) + { + if (info.nodeType == 1) + { + FucNodeStatusParameter * functionNodeParameter = linkNodeParameter->add_nodelist(); + functionNodeParameter->set_fuc_name(info.funcName.toStdString()); + functionNodeParameter->set_check_state((ENLcsNodeCheckStatus)info.checked); + functionNodeParameter->set_timeflag(info.timeFlag); + functionNodeParameter->set_node_state((ENLcsStatus)info.status); + functionNodeParameter->set_fuc_desc(""); + } + } + + foreach(S_LINKCTRL_INFO info, nodeList) + { + if (info.nodeType == 2) + { + for (int nIndex(0); nIndex < linkNodeParameter->nodelist_size(); nIndex++) + { + if (info.funcName.toStdString() == linkNodeParameter->nodelist(nIndex).fuc_name()) + { + ActionNodeStatusParameter * actionNodeParameter = linkNodeParameter->mutable_nodelist(nIndex)->add_nodelist(); + actionNodeParameter->set_action_name(info.actionName.toStdString()); + actionNodeParameter->set_check_state((ENLcsNodeCheckStatus)info.checked); + actionNodeParameter->set_timeflag(info.timeFlag); + actionNodeParameter->set_node_state((ENLcsStatus)info.status); + actionNodeParameter->set_action_desc(""); + } + } + } + } + + ActorParameter * actorParameter = msg.mutable_actor(); + actorParameter->set_user_id(nUserId); + actorParameter->set_user_groupid(nUserGrpId); + actorParameter->set_host_name(stNodeInfo.strName); + actorParameter->set_user_name(strUserName); + msg.set_opreate_type((ENLinkOperateType)type); + try + { + m_linkCtrlMsgHandle->linkOperateRequest(msg); + } + catch (const std::exception& e) + { + qDebug() << e.what(); + } + +} + +bool CLinkCtrlDataManage::receiveLinkOperateAck(kbd_idlfile::linkage::LinkOperateMessageAck &msg) +{ + if (msg.has_execute_status()) + { + QString strLinkDescription = QString::fromStdString(msg.link_node().link_desc()); + E_LINK_OPERATETYPE type = (E_LINK_OPERATETYPE)msg.opreate_type(); + ExecuteStatusParameter * parameter = msg.mutable_execute_status(); + if (0 != parameter->statuscode()) + { + int nErrorCode = parameter->erro_param().errorcode(); + QString strErrorDescription = QString::fromStdString(parameter->erro_param().errordescription()); + emit sigRequestLinkOperationFail(strLinkDescription, type, nErrorCode, strErrorDescription); + } + } + return true; +} + +bool CLinkCtrlDataManage::recvUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage &msg) +{ + kbd_idlfile::linkage::UiRequestMessage * requestMessage = new kbd_idlfile::linkage::UiRequestMessage(msg); + emit sigRecvLinkUserInterveneRequest(requestMessage); + return true; +} + +void CLinkCtrlDataManage::replyUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessageAck &msg) +{ + try + { + m_linkCtrlMsgHandle->userInterveneResponse(msg); + } + catch (const std::exception&e) + { + qDebug() << e.what(); + } + +} + +bool CLinkCtrlDataManage::recvLinkStartRequest(kbd_idlfile::linkage::LinkStartRequestMessage &msg) +{ + quint64 triggerTime = msg.trigger_time(); + LinkNodeStatusParameter * linkNodeParameter = msg.mutable_nodelist(); + QString strLinkName = QString::fromStdString(linkNodeParameter->link_name()); + int nLinkState = (int)linkNodeParameter->node_state(); + emit sigLinkAgeStart(strLinkName, nLinkState, triggerTime); + return true; +} + +bool CLinkCtrlDataManage::recvLinkStateChange(kbd_idlfile::linkage::StatusChangeMessage &msg) +{ + try + { + LinkNodeStatusParameter * linkNodeParameter = msg.mutable_nodelist(); + QString strLinkName = QString::fromStdString(linkNodeParameter->link_name()); + int nLinkState = (int)linkNodeParameter->node_state(); + quint64 nTimeFlag = linkNodeParameter->timeflag(); + //< 消息内没有触发事件,第三个参数triggerTime为0表示不刷新此值 + emit sigUpdateLinkAgeState(strLinkName, nLinkState, 0, nTimeFlag); + if (linkNodeParameter->nodelist_size() > 0) + { + for (int nFunctionIndex(0); nFunctionIndex < linkNodeParameter->nodelist_size(); nFunctionIndex++) + { + FucNodeStatusParameter fucNodeStatusParameter = linkNodeParameter->nodelist(nFunctionIndex); + QString strFunctionName = QString::fromStdString(fucNodeStatusParameter.fuc_name()); + int nFunctionState = (int)fucNodeStatusParameter.node_state(); + emit sigUpdateFunctionState(strLinkName, strFunctionName, nFunctionState); + if (fucNodeStatusParameter.nodelist_size() > 0) + { + for (int nActionndex(0); nActionndex < linkNodeParameter->nodelist_size(); nActionndex++) + { + ActionNodeStatusParameter actionNodeStatusParameter = fucNodeStatusParameter.nodelist(nActionndex); + QString strActionName = QString::fromStdString(actionNodeStatusParameter.action_name()); + int nActionState = (int)actionNodeStatusParameter.node_state(); + emit sigUpdateActionState(strLinkName, strFunctionName, strActionName, nActionState); + } + } + } + } + return true; + } + catch(...) + { + qDebug() << "recvLinkStateChange, exception!"; + return false; + } +} + + diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlDataManage.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlDataManage.h index 131d7e3b..aa616932 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlDataManage.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlDataManage.h @@ -1,73 +1,73 @@ -#ifndef CLINKCTRLDATAMANAGE_H -#define CLINKCTRLDATAMANAGE_H - -#include -#include "linkctrl_def.h" -#include "db_api_ex/CDbApi.h" -#include "dbms/rdb_api/CRdbAccessEx.h" -#include "../dbms/rdb_net_api/CRdbNetApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "../../idl_files/LinkageMessage.pb.h" - -#define COMAPP ("comapp") -#define LINKAGE_SETTING ("linkage_setting") -#define LINKAGE_DEFINE ("linkage_define") -#define LINKAGE_FUNCTION ("linkage_function") -#define LINKAGE_ACTION ("linkage_action") - -struct S_LINKCTRL_INFO; -class QTimer; -class CLinkCtrlMessageHandle; - -class CLinkCtrlDataManage : public QObject -{ - Q_OBJECT -public: - explicit CLinkCtrlDataManage(QObject *parent = nullptr); - ~CLinkCtrlDataManage(); - - - - QList queryLinkCtrlList(); - QList queryLinkFunctionList(const QString &linkCtrlName); - - /*********************************************************************** - * @brief requestLinkOperation 界面发起联动请求 - * @param linkName 联动名称 - * @param timeFlag 时标 - * @param nodeState 节点状态 - * @param nodeList 功能节点 - ***********************************************************************/ - void requestLinkOperation(const int &nDomainID, - const QString &linkName, - const quint64 &timeFlag, - const E_LCS_STATUS & nodeState, - const QList &nodeList, - const E_LINK_OPERATETYPE & type); - - bool receiveLinkOperateAck(kbd_idlfile::linkage::LinkOperateMessageAck &msg); - - bool recvUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage &msg); - - void replyUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessageAck &msg); - - bool recvLinkStartRequest(kbd_idlfile::linkage::LinkStartRequestMessage &msg); - - bool recvLinkStateChange(kbd_idlfile::linkage::StatusChangeMessage &msg); - -signals: - void sigRequestLinkOperationFail(const QString &strLinkName, const E_LINK_OPERATETYPE &type, const int &nErrorCode, const QString &strErrorCode); - void sigLinkAgeStart(const QString &strLinkName, const int &state, const quint64 &triggerTime); - void sigUpdateLinkAgeState(const QString &strLinkName, int state, quint64 triggerTime, quint64 timeFlag); - void sigUpdateFunctionState(const QString &strLinkName, const QString &strFunctionName, const int &state); - void sigUpdateActionState(const QString &strLinkName, const QString &strFunctionName, const QString &strActionName, const int &state); - void sigRecvLinkUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage *msg); - -private: - QTimer * m_Timer; - CLinkCtrlMessageHandle * m_linkCtrlMsgHandle; - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbNetApi * m_rdbNetApi; -}; - -#endif // CLINKCTRLDATAMANAGE_H +#ifndef CLINKCTRLDATAMANAGE_H +#define CLINKCTRLDATAMANAGE_H + +#include +#include "linkctrl_def.h" +#include "db_api_ex/CDbApi.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "../dbms/rdb_net_api/CRdbNetApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "../../idl_files/LinkageMessage.pb.h" + +#define COMAPP ("comapp") +#define LINKAGE_SETTING ("linkage_setting") +#define LINKAGE_DEFINE ("linkage_define") +#define LINKAGE_FUNCTION ("linkage_function") +#define LINKAGE_ACTION ("linkage_action") + +struct S_LINKCTRL_INFO; +class QTimer; +class CLinkCtrlMessageHandle; + +class CLinkCtrlDataManage : public QObject +{ + Q_OBJECT +public: + explicit CLinkCtrlDataManage(QObject *parent = nullptr); + ~CLinkCtrlDataManage(); + + + + QList queryLinkCtrlList(); + QList queryLinkFunctionList(const QString &linkCtrlName); + + /*********************************************************************** + * @brief requestLinkOperation 界面发起联动请求 + * @param linkName 联动名称 + * @param timeFlag 时标 + * @param nodeState 节点状态 + * @param nodeList 功能节点 + ***********************************************************************/ + void requestLinkOperation(const int &nDomainID, + const QString &linkName, + const quint64 &timeFlag, + const E_LCS_STATUS & nodeState, + const QList &nodeList, + const E_LINK_OPERATETYPE & type); + + bool receiveLinkOperateAck(kbd_idlfile::linkage::LinkOperateMessageAck &msg); + + bool recvUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage &msg); + + void replyUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessageAck &msg); + + bool recvLinkStartRequest(kbd_idlfile::linkage::LinkStartRequestMessage &msg); + + bool recvLinkStateChange(kbd_idlfile::linkage::StatusChangeMessage &msg); + +signals: + void sigRequestLinkOperationFail(const QString &strLinkName, const E_LINK_OPERATETYPE &type, const int &nErrorCode, const QString &strErrorCode); + void sigLinkAgeStart(const QString &strLinkName, const int &state, const quint64 &triggerTime); + void sigUpdateLinkAgeState(const QString &strLinkName, int state, quint64 triggerTime, quint64 timeFlag); + void sigUpdateFunctionState(const QString &strLinkName, const QString &strFunctionName, const int &state); + void sigUpdateActionState(const QString &strLinkName, const QString &strFunctionName, const QString &strActionName, const int &state); + void sigRecvLinkUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage *msg); + +private: + QTimer * m_Timer; + CLinkCtrlMessageHandle * m_linkCtrlMsgHandle; + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbNetApi * m_rdbNetApi; +}; + +#endif // CLINKCTRLDATAMANAGE_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.cpp index 9c530b20..02af651d 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.cpp @@ -1,38 +1,38 @@ -#include "CLinkCtrlMessageHandle.h" -#include "CLinkCtrlDataManage.h" - -CLinkCtrlMessageHandle::CLinkCtrlMessageHandle(CLinkCtrlDataManage * linkCtrlDataManage) - : m_linkCtrlDataManage(linkCtrlDataManage) -{ - start(); -} - -CLinkCtrlMessageHandle::~CLinkCtrlMessageHandle() -{ - stop(); -} - -bool CLinkCtrlMessageHandle::handleLinkOperateResponse(kbd_idlfile::linkage::LinkOperateMessageAck &msg) -{ - qDebug() << "receiveLinkOperateAck "; - return m_linkCtrlDataManage->receiveLinkOperateAck(msg); -} - -bool CLinkCtrlMessageHandle::handleUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage &msg) -{ - qDebug() << "recvUserInterveneRequest "; - return m_linkCtrlDataManage->recvUserInterveneRequest(msg); -} - -bool CLinkCtrlMessageHandle::handleLinkStartRequest(kbd_idlfile::linkage::LinkStartRequestMessage &msg) -{ - qDebug() << "recvLinkStartRequest "; - return m_linkCtrlDataManage->recvLinkStartRequest(msg); -} - -bool CLinkCtrlMessageHandle::handleLinkStateChange(kbd_idlfile::linkage::StatusChangeMessage &msg) -{ - return true; - qDebug() << "recvLinkStateChange "; - return m_linkCtrlDataManage->recvLinkStateChange(msg); -} +#include "CLinkCtrlMessageHandle.h" +#include "CLinkCtrlDataManage.h" + +CLinkCtrlMessageHandle::CLinkCtrlMessageHandle(CLinkCtrlDataManage * linkCtrlDataManage) + : m_linkCtrlDataManage(linkCtrlDataManage) +{ + start(); +} + +CLinkCtrlMessageHandle::~CLinkCtrlMessageHandle() +{ + stop(); +} + +bool CLinkCtrlMessageHandle::handleLinkOperateResponse(kbd_idlfile::linkage::LinkOperateMessageAck &msg) +{ + qDebug() << "receiveLinkOperateAck "; + return m_linkCtrlDataManage->receiveLinkOperateAck(msg); +} + +bool CLinkCtrlMessageHandle::handleUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage &msg) +{ + qDebug() << "recvUserInterveneRequest "; + return m_linkCtrlDataManage->recvUserInterveneRequest(msg); +} + +bool CLinkCtrlMessageHandle::handleLinkStartRequest(kbd_idlfile::linkage::LinkStartRequestMessage &msg) +{ + qDebug() << "recvLinkStartRequest "; + return m_linkCtrlDataManage->recvLinkStartRequest(msg); +} + +bool CLinkCtrlMessageHandle::handleLinkStateChange(kbd_idlfile::linkage::StatusChangeMessage &msg) +{ + return true; + qDebug() << "recvLinkStateChange "; + return m_linkCtrlDataManage->recvLinkStateChange(msg); +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.h index 7d2dfcc1..77767f9f 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.h @@ -1,37 +1,37 @@ -#ifndef CLINKCTRLMESSAGEHANDLE_H -#define CLINKCTRLMESSAGEHANDLE_H - -#include "application/linkage_server_api/CLinkageForHmiApi.h" - -class CLinkCtrlDataManage; - -class CLinkCtrlMessageHandle : public kbd_application::CLinkageForHmiApi -{ -public: - CLinkCtrlMessageHandle(CLinkCtrlDataManage * linkCtrlDataManage); - ~CLinkCtrlMessageHandle(); - - //1 hmi->server 发起的请求联动操作 - //bool linkOperateRequest(kbd_idlfile::LinkOperateMessage& msg); - - //2 server->hmi 请求联动操作的应答 - virtual bool handleLinkOperateResponse(kbd_idlfile::linkage::LinkOperateMessageAck& msg); - - //1 server->hmi 发起的人工干预 请求 - virtual bool handleUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage& msg); - - //2 hmi ->server 人工干预应答 - //bool userInterveneResponse(kbd_idlfile::UiRequestMessageAck& msg); - - - //server->hmi 请求联动操作 应答 server 发起的 半自动请求开始 - virtual bool handleLinkStartRequest(kbd_idlfile::linkage::LinkStartRequestMessage& msg); - - //server->hmi 联动状态更新 - virtual bool handleLinkStateChange(kbd_idlfile::linkage::StatusChangeMessage& msg); - -private: - CLinkCtrlDataManage * m_linkCtrlDataManage; -}; - -#endif // CLINKCTRLMESSAGEHANDLE_H +#ifndef CLINKCTRLMESSAGEHANDLE_H +#define CLINKCTRLMESSAGEHANDLE_H + +#include "application/linkage_server_api/CLinkageForHmiApi.h" + +class CLinkCtrlDataManage; + +class CLinkCtrlMessageHandle : public kbd_application::CLinkageForHmiApi +{ +public: + CLinkCtrlMessageHandle(CLinkCtrlDataManage * linkCtrlDataManage); + ~CLinkCtrlMessageHandle(); + + //1 hmi->server 发起的请求联动操作 + //bool linkOperateRequest(kbd_idlfile::LinkOperateMessage& msg); + + //2 server->hmi 请求联动操作的应答 + virtual bool handleLinkOperateResponse(kbd_idlfile::linkage::LinkOperateMessageAck& msg); + + //1 server->hmi 发起的人工干预 请求 + virtual bool handleUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage& msg); + + //2 hmi ->server 人工干预应答 + //bool userInterveneResponse(kbd_idlfile::UiRequestMessageAck& msg); + + + //server->hmi 请求联动操作 应答 server 发起的 半自动请求开始 + virtual bool handleLinkStartRequest(kbd_idlfile::linkage::LinkStartRequestMessage& msg); + + //server->hmi 联动状态更新 + virtual bool handleLinkStateChange(kbd_idlfile::linkage::StatusChangeMessage& msg); + +private: + CLinkCtrlDataManage * m_linkCtrlDataManage; +}; + +#endif // CLINKCTRLMESSAGEHANDLE_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.cpp index c0a901b8..b714bb0e 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CLinkCtrlPluginWidget.h" -#include "CLinkCtrlWidget.h" - -CLinkCtrlPluginWidget::CLinkCtrlPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CLinkCtrlPluginWidget::~CLinkCtrlPluginWidget() -{ - -} - -bool CLinkCtrlPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **linkCtrlWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CLinkCtrlWidget *pWidget = new CLinkCtrlWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *linkCtrlWidget = (IPluginWidget *)pWidget; - return true; -} - -void CLinkCtrlPluginWidget::release() -{ - -} +#include +#include "CLinkCtrlPluginWidget.h" +#include "CLinkCtrlWidget.h" + +CLinkCtrlPluginWidget::CLinkCtrlPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CLinkCtrlPluginWidget::~CLinkCtrlPluginWidget() +{ + +} + +bool CLinkCtrlPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **linkCtrlWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CLinkCtrlWidget *pWidget = new CLinkCtrlWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *linkCtrlWidget = (IPluginWidget *)pWidget; + return true; +} + +void CLinkCtrlPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.h index 35781fbe..bb1d1412 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CLINKCTRLPLUGINWIDGET_H -#define CLINKCTRLPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CLinkCtrlPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CLinkCtrlPluginWidget(QObject *parent = 0); - ~CLinkCtrlPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **linkCtrlWidget, QVector ptrVec); - void release(); -}; - -#endif //CLINKCTRLPLUGINWIDGET_H - +#ifndef CLINKCTRLPLUGINWIDGET_H +#define CLINKCTRLPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CLinkCtrlPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CLinkCtrlPluginWidget(QObject *parent = 0); + ~CLinkCtrlPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **linkCtrlWidget, QVector ptrVec); + void release(); +}; + +#endif //CLINKCTRLPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlStateManage.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlStateManage.cpp index 4008bc99..78191803 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlStateManage.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlStateManage.cpp @@ -1,263 +1,263 @@ -#include "CLinkCtrlStateManage.h" -#include "linkctrl_def.h" -#include "CLinkCtrlMessageHandle.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include -#include -#include - -using namespace kbd_dbms; -using namespace kbd_idlfile; - -CLinkCtrlStateManage::CLinkCtrlStateManage(QObject *parent) - : QObject(parent) -{ - //网络实时库 - m_rdbNetApi = new CRdbNetApi(); -} - -CLinkCtrlStateManage::~CLinkCtrlStateManage() -{ - if(m_rdbNetApi) - { - delete m_rdbNetApi; - } - m_rdbNetApi = NULL; -} - -void CLinkCtrlStateManage::subscribeLinkCtrlList(QList list) -{ - QMutexLocker locker(&mutex); - m_linkAgeList.append(list); - if(NULL != m_Timer) - { - m_Timer->stop(); - delete m_Timer; - } - m_Timer = new QTimer(); - m_Timer->setInterval(1000); - connect(m_Timer, &QTimer::timeout, this, &CLinkCtrlStateManage::updateLinkAgeState); - m_Timer->start(); -} - -void CLinkCtrlStateManage::clearSubscribe() -{ - QMutexLocker locker(&mutex); - m_linkAgeList.clear(); - if(NULL != m_Timer) - { - m_Timer->stop(); - delete m_Timer; - } - m_Timer = NULL; -} - -void CLinkCtrlStateManage::updateLinkAgeState() -{ - QMutexLocker locker(&mutex); - if(m_Timer) - { - m_Timer->stop(); - } - while(m_rdbNetApi->checkStatus()) - { - kbd_idlfile::RdbRet retMsg; - if (m_rdbNetApi->getRet(&retMsg)) - { - if(retMsg.msgrecord_size() != 0) - { - for (int nIndex(0); nIndex < retMsg.msgrecord_size(); nIndex++) - { - int node_type = retMsg.msgrecord(nIndex).msgvaluearray(3).nvalue(); - if (node_type ==(int)E_Node_LinkCtrl) - { - if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(0).edatatype()) - { - int status = retMsg.msgrecord(nIndex).msgvaluearray(0).nvalue(); - quint64 triggerTime = retMsg.msgrecord(nIndex).msgvaluearray(1).ulvalue(); - quint64 timeFlag = retMsg.msgrecord(nIndex).msgvaluearray(2).ulvalue(); - QString linkageName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(4).strvalue()); - emit sigUpdateLinkAgeState(linkageName, status, triggerTime, timeFlag); - } - } - else if (node_type ==(int)E_Node_Function) - { - if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(0).edatatype()) - { - int value = retMsg.msgrecord(nIndex).msgvaluearray(0).nvalue(); - QString linkageName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(4).strvalue()); - QString funcName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(5).strvalue()); - emit sigUpdateFunctionState(linkageName, funcName, value); - } - } - else if (node_type ==(int)E_Node_Action) - { - if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(0).edatatype()) - { - int value = retMsg.msgrecord(nIndex).msgvaluearray(0).nvalue(); - QString linkageName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(4).strvalue()); - QString funcName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(5).strvalue()); - QString actionName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(6).strvalue()); - emit sigUpdateActionState(linkageName, funcName, actionName, value); - } - } - } - } - } - } - try - { - bool bValid = false; - if ( m_nDomainID <= 0 || m_nAppID <= 0 ) - { - kbd_public::CSysInfoInterfacePtr spSysInfo; - if ( kbd_public::createSysInfoInstance( spSysInfo )) - { - kbd_public::SNodeInfo nodeInfo; - spSysInfo->getLocalNodeInfo( nodeInfo ); - kbd_public::SAppInfo appInfo; - spSysInfo->getAppInfoByName(COMAPP, appInfo ); - - m_nDomainID = nodeInfo.nDomainId; - m_nAppID = appInfo.nId; - - bValid = true; - } - } - else - bValid = true; - - - if ( bValid ) - { - //query state - //< todo 多域时是不是有问题,应该按联动所属域查询 - m_rdbNetApi->connect(m_nDomainID, m_nAppID); - foreach (S_LINKCTRL_INFO linkage, m_linkAgeList) - { - kbd_idlfile::RdbQuery query; - query.set_strtablename("linkage_running"); - std::string *pStatusColName = query.add_strselectcolnamearr(); - *pStatusColName = "status"; - std::string *pTriggerColName = query.add_strselectcolnamearr(); - *pTriggerColName = "trigger_time"; - std::string *pTimeFlagColName = query.add_strselectcolnamearr(); - *pTimeFlagColName = "timeflag"; - std::string *pNodeTypeColName = query.add_strselectcolnamearr(); - *pNodeTypeColName = "node_type"; - std::string *pLinkageNameColName = query.add_strselectcolnamearr(); - *pLinkageNameColName = "linkage_name"; - std::string *pFuncNameColName = query.add_strselectcolnamearr(); - *pFuncNameColName = "func_name"; - std::string *pActionNameColName = query.add_strselectcolnamearr(); - *pActionNameColName = "action_name"; - - kbd_idlfile::RdbCondition *pLinkAgeCondtion = query.add_msgcondition(); - pLinkAgeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pLinkAgeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pLinkAgeCondtion->set_strcolumnname("linkage_name"); - SVariable *pLinkAgeCondValue = pLinkAgeCondtion->mutable_msgvalue(); - pLinkAgeCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pLinkAgeCondValue->set_strvalue(linkage.linkageName.toStdString()); - - if(E_Node_LinkCtrl == linkage.nodeType) - { - kbd_idlfile::RdbCondition *pLinkNodeCondtion = query.add_msgcondition(); - pLinkNodeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pLinkNodeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pLinkNodeCondtion->set_strcolumnname("node_type"); - SVariable *pLinkNodeCondValue = pLinkNodeCondtion->mutable_msgvalue(); - pLinkNodeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); - pLinkNodeCondValue->set_nvalue((int)E_Node_LinkCtrl); - -// kbd_idlfile::RdbCondition *pLinkTypeCondtion = query.add_msgcondition(); -// pLinkTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); -// pLinkTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); -// pLinkTypeCondtion->set_strcolumnname("link_type"); -// SVariable *pLinkTypeCondValue = pLinkTypeCondtion->mutable_msgvalue(); -// pLinkTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); -// pLinkTypeCondValue->set_nvalue((int)E_Node_Function); - - kbd_idlfile::RdbRet retMsg; - m_rdbNetApi->query(query, retMsg, true); - } - else if(E_Node_Function == linkage.nodeType) - { - kbd_idlfile::RdbCondition *pFuncCondtion = query.add_msgcondition(); - pFuncCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pFuncCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pFuncCondtion->set_strcolumnname("func_name"); - SVariable *pFuncCondValue = pFuncCondtion->mutable_msgvalue(); - pFuncCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pFuncCondValue->set_strvalue(linkage.funcName.toStdString()); - - kbd_idlfile::RdbCondition *pLinkNodeCondtion = query.add_msgcondition(); - pLinkNodeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pLinkNodeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pLinkNodeCondtion->set_strcolumnname("node_type"); - SVariable *pLinkNodeCondValue = pLinkNodeCondtion->mutable_msgvalue(); - pLinkNodeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); - pLinkNodeCondValue->set_nvalue((int)E_Node_Function); - -// kbd_idlfile::RdbCondition *pLinkTypeCondtion = query.add_msgcondition(); -// pLinkTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); -// pLinkTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); -// pLinkTypeCondtion->set_strcolumnname("link_type"); -// SVariable *pLinkTypeCondValue = pLinkTypeCondtion->mutable_msgvalue(); -// pLinkTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); -// pLinkTypeCondValue->set_nvalue((int)E_Node_LinkCtrl); - - kbd_idlfile::RdbRet retMsg; - m_rdbNetApi->query(query, retMsg, true); - } - else if(E_Node_Action == linkage.nodeType) - { - kbd_idlfile::RdbCondition *pFuncCondtion = query.add_msgcondition(); - pFuncCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pFuncCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pFuncCondtion->set_strcolumnname("func_name"); - SVariable *pFuncCondValue = pFuncCondtion->mutable_msgvalue(); - pFuncCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pFuncCondValue->set_strvalue(linkage.funcName.toStdString()); - - kbd_idlfile::RdbCondition *pActionCondtion = query.add_msgcondition(); - pActionCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pActionCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pActionCondtion->set_strcolumnname("action_name"); - SVariable *pActionCondValue = pActionCondtion->mutable_msgvalue(); - pActionCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pActionCondValue->set_strvalue(linkage.actionName.toStdString()); - - kbd_idlfile::RdbCondition *pLinkNodeCondtion = query.add_msgcondition(); - pLinkNodeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pLinkNodeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pLinkNodeCondtion->set_strcolumnname("node_type"); - SVariable *pLinkNodeCondValue = pLinkNodeCondtion->mutable_msgvalue(); - pLinkNodeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); - pLinkNodeCondValue->set_nvalue((int)E_Node_Action); - -// kbd_idlfile::RdbCondition *pLinkTypeCondtion = query.add_msgcondition(); -// pLinkTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); -// pLinkTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); -// pLinkTypeCondtion->set_strcolumnname("link_type"); -// SVariable *pLinkTypeCondValue = pLinkTypeCondtion->mutable_msgvalue(); -// pLinkTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); -// pLinkTypeCondValue->set_nvalue((int)E_Node_LinkCtrl); - - kbd_idlfile::RdbRet retMsg; - m_rdbNetApi->query(query, retMsg, true); - } - } - } - } - catch(...) - { - qDebug() << "updateLinkAgeState "; - } - - if(m_Timer) - { - m_Timer->start(); - } -} - +#include "CLinkCtrlStateManage.h" +#include "linkctrl_def.h" +#include "CLinkCtrlMessageHandle.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include +#include + +using namespace kbd_dbms; +using namespace kbd_idlfile; + +CLinkCtrlStateManage::CLinkCtrlStateManage(QObject *parent) + : QObject(parent) +{ + //网络实时库 + m_rdbNetApi = new CRdbNetApi(); +} + +CLinkCtrlStateManage::~CLinkCtrlStateManage() +{ + if(m_rdbNetApi) + { + delete m_rdbNetApi; + } + m_rdbNetApi = NULL; +} + +void CLinkCtrlStateManage::subscribeLinkCtrlList(QList list) +{ + QMutexLocker locker(&mutex); + m_linkAgeList.append(list); + if(NULL != m_Timer) + { + m_Timer->stop(); + delete m_Timer; + } + m_Timer = new QTimer(); + m_Timer->setInterval(1000); + connect(m_Timer, &QTimer::timeout, this, &CLinkCtrlStateManage::updateLinkAgeState); + m_Timer->start(); +} + +void CLinkCtrlStateManage::clearSubscribe() +{ + QMutexLocker locker(&mutex); + m_linkAgeList.clear(); + if(NULL != m_Timer) + { + m_Timer->stop(); + delete m_Timer; + } + m_Timer = NULL; +} + +void CLinkCtrlStateManage::updateLinkAgeState() +{ + QMutexLocker locker(&mutex); + if(m_Timer) + { + m_Timer->stop(); + } + while(m_rdbNetApi->checkStatus()) + { + kbd_idlfile::RdbRet retMsg; + if (m_rdbNetApi->getRet(&retMsg)) + { + if(retMsg.msgrecord_size() != 0) + { + for (int nIndex(0); nIndex < retMsg.msgrecord_size(); nIndex++) + { + int node_type = retMsg.msgrecord(nIndex).msgvaluearray(3).nvalue(); + if (node_type ==(int)E_Node_LinkCtrl) + { + if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(0).edatatype()) + { + int status = retMsg.msgrecord(nIndex).msgvaluearray(0).nvalue(); + quint64 triggerTime = retMsg.msgrecord(nIndex).msgvaluearray(1).ulvalue(); + quint64 timeFlag = retMsg.msgrecord(nIndex).msgvaluearray(2).ulvalue(); + QString linkageName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(4).strvalue()); + emit sigUpdateLinkAgeState(linkageName, status, triggerTime, timeFlag); + } + } + else if (node_type ==(int)E_Node_Function) + { + if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(0).edatatype()) + { + int value = retMsg.msgrecord(nIndex).msgvaluearray(0).nvalue(); + QString linkageName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(4).strvalue()); + QString funcName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(5).strvalue()); + emit sigUpdateFunctionState(linkageName, funcName, value); + } + } + else if (node_type ==(int)E_Node_Action) + { + if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(0).edatatype()) + { + int value = retMsg.msgrecord(nIndex).msgvaluearray(0).nvalue(); + QString linkageName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(4).strvalue()); + QString funcName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(5).strvalue()); + QString actionName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(6).strvalue()); + emit sigUpdateActionState(linkageName, funcName, actionName, value); + } + } + } + } + } + } + try + { + bool bValid = false; + if ( m_nDomainID <= 0 || m_nAppID <= 0 ) + { + kbd_public::CSysInfoInterfacePtr spSysInfo; + if ( kbd_public::createSysInfoInstance( spSysInfo )) + { + kbd_public::SNodeInfo nodeInfo; + spSysInfo->getLocalNodeInfo( nodeInfo ); + kbd_public::SAppInfo appInfo; + spSysInfo->getAppInfoByName(COMAPP, appInfo ); + + m_nDomainID = nodeInfo.nDomainId; + m_nAppID = appInfo.nId; + + bValid = true; + } + } + else + bValid = true; + + + if ( bValid ) + { + //query state + //< todo 多域时是不是有问题,应该按联动所属域查询 + m_rdbNetApi->connect(m_nDomainID, m_nAppID); + foreach (S_LINKCTRL_INFO linkage, m_linkAgeList) + { + kbd_idlfile::RdbQuery query; + query.set_strtablename("linkage_running"); + std::string *pStatusColName = query.add_strselectcolnamearr(); + *pStatusColName = "status"; + std::string *pTriggerColName = query.add_strselectcolnamearr(); + *pTriggerColName = "trigger_time"; + std::string *pTimeFlagColName = query.add_strselectcolnamearr(); + *pTimeFlagColName = "timeflag"; + std::string *pNodeTypeColName = query.add_strselectcolnamearr(); + *pNodeTypeColName = "node_type"; + std::string *pLinkageNameColName = query.add_strselectcolnamearr(); + *pLinkageNameColName = "linkage_name"; + std::string *pFuncNameColName = query.add_strselectcolnamearr(); + *pFuncNameColName = "func_name"; + std::string *pActionNameColName = query.add_strselectcolnamearr(); + *pActionNameColName = "action_name"; + + kbd_idlfile::RdbCondition *pLinkAgeCondtion = query.add_msgcondition(); + pLinkAgeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pLinkAgeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pLinkAgeCondtion->set_strcolumnname("linkage_name"); + SVariable *pLinkAgeCondValue = pLinkAgeCondtion->mutable_msgvalue(); + pLinkAgeCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pLinkAgeCondValue->set_strvalue(linkage.linkageName.toStdString()); + + if(E_Node_LinkCtrl == linkage.nodeType) + { + kbd_idlfile::RdbCondition *pLinkNodeCondtion = query.add_msgcondition(); + pLinkNodeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pLinkNodeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pLinkNodeCondtion->set_strcolumnname("node_type"); + SVariable *pLinkNodeCondValue = pLinkNodeCondtion->mutable_msgvalue(); + pLinkNodeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); + pLinkNodeCondValue->set_nvalue((int)E_Node_LinkCtrl); + +// kbd_idlfile::RdbCondition *pLinkTypeCondtion = query.add_msgcondition(); +// pLinkTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); +// pLinkTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); +// pLinkTypeCondtion->set_strcolumnname("link_type"); +// SVariable *pLinkTypeCondValue = pLinkTypeCondtion->mutable_msgvalue(); +// pLinkTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); +// pLinkTypeCondValue->set_nvalue((int)E_Node_Function); + + kbd_idlfile::RdbRet retMsg; + m_rdbNetApi->query(query, retMsg, true); + } + else if(E_Node_Function == linkage.nodeType) + { + kbd_idlfile::RdbCondition *pFuncCondtion = query.add_msgcondition(); + pFuncCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pFuncCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pFuncCondtion->set_strcolumnname("func_name"); + SVariable *pFuncCondValue = pFuncCondtion->mutable_msgvalue(); + pFuncCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pFuncCondValue->set_strvalue(linkage.funcName.toStdString()); + + kbd_idlfile::RdbCondition *pLinkNodeCondtion = query.add_msgcondition(); + pLinkNodeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pLinkNodeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pLinkNodeCondtion->set_strcolumnname("node_type"); + SVariable *pLinkNodeCondValue = pLinkNodeCondtion->mutable_msgvalue(); + pLinkNodeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); + pLinkNodeCondValue->set_nvalue((int)E_Node_Function); + +// kbd_idlfile::RdbCondition *pLinkTypeCondtion = query.add_msgcondition(); +// pLinkTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); +// pLinkTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); +// pLinkTypeCondtion->set_strcolumnname("link_type"); +// SVariable *pLinkTypeCondValue = pLinkTypeCondtion->mutable_msgvalue(); +// pLinkTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); +// pLinkTypeCondValue->set_nvalue((int)E_Node_LinkCtrl); + + kbd_idlfile::RdbRet retMsg; + m_rdbNetApi->query(query, retMsg, true); + } + else if(E_Node_Action == linkage.nodeType) + { + kbd_idlfile::RdbCondition *pFuncCondtion = query.add_msgcondition(); + pFuncCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pFuncCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pFuncCondtion->set_strcolumnname("func_name"); + SVariable *pFuncCondValue = pFuncCondtion->mutable_msgvalue(); + pFuncCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pFuncCondValue->set_strvalue(linkage.funcName.toStdString()); + + kbd_idlfile::RdbCondition *pActionCondtion = query.add_msgcondition(); + pActionCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pActionCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pActionCondtion->set_strcolumnname("action_name"); + SVariable *pActionCondValue = pActionCondtion->mutable_msgvalue(); + pActionCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pActionCondValue->set_strvalue(linkage.actionName.toStdString()); + + kbd_idlfile::RdbCondition *pLinkNodeCondtion = query.add_msgcondition(); + pLinkNodeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pLinkNodeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pLinkNodeCondtion->set_strcolumnname("node_type"); + SVariable *pLinkNodeCondValue = pLinkNodeCondtion->mutable_msgvalue(); + pLinkNodeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); + pLinkNodeCondValue->set_nvalue((int)E_Node_Action); + +// kbd_idlfile::RdbCondition *pLinkTypeCondtion = query.add_msgcondition(); +// pLinkTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); +// pLinkTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); +// pLinkTypeCondtion->set_strcolumnname("link_type"); +// SVariable *pLinkTypeCondValue = pLinkTypeCondtion->mutable_msgvalue(); +// pLinkTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); +// pLinkTypeCondValue->set_nvalue((int)E_Node_LinkCtrl); + + kbd_idlfile::RdbRet retMsg; + m_rdbNetApi->query(query, retMsg, true); + } + } + } + } + catch(...) + { + qDebug() << "updateLinkAgeState "; + } + + if(m_Timer) + { + m_Timer->start(); + } +} + diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlStateManage.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlStateManage.h index 7d71ff10..6429cc8a 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlStateManage.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlStateManage.h @@ -1,41 +1,41 @@ -#ifndef CLINKSTATESTATEMANAGE_H -#define CLINKSTATESTATEMANAGE_H - -#include -#include "linkctrl_def.h" -#include "dbms/rdb_api/CRdbAccessEx.h" -#include "../dbms/rdb_net_api/CRdbNetApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "db_api_ex/CDbApi.h" - -#define COMAPP ("comapp") - -class CLinkCtrlStateManage : public QObject -{ - Q_OBJECT -public: - explicit CLinkCtrlStateManage(QObject *parent = nullptr); - ~CLinkCtrlStateManage(); - - void updateLinkAgeState(); - -signals: - void sigUpdateLinkAgeState(const QString &strLinkName, int state, quint64 triggerTime, quint64 timeFlag); - void sigUpdateFunctionState(const QString &strLinkName, const QString &strFunctionName, const int &state); - void sigUpdateActionState(const QString &strLinkName, const QString &strFunctionName, const QString &strActionName, const int &state); - -public slots: - void subscribeLinkCtrlList(QList list); - void clearSubscribe(); - -private: - int m_nDomainID{-1}; - int m_nAppID{-1}; - QTimer * m_Timer{nullptr}; - kbd_dbms::CRdbNetApi * m_rdbNetApi{nullptr}; - QMutex mutex; - QList m_linkAgeList; - -}; - -#endif // CLINKSTATESTATEMANAGE_H +#ifndef CLINKSTATESTATEMANAGE_H +#define CLINKSTATESTATEMANAGE_H + +#include +#include "linkctrl_def.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "../dbms/rdb_net_api/CRdbNetApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "db_api_ex/CDbApi.h" + +#define COMAPP ("comapp") + +class CLinkCtrlStateManage : public QObject +{ + Q_OBJECT +public: + explicit CLinkCtrlStateManage(QObject *parent = nullptr); + ~CLinkCtrlStateManage(); + + void updateLinkAgeState(); + +signals: + void sigUpdateLinkAgeState(const QString &strLinkName, int state, quint64 triggerTime, quint64 timeFlag); + void sigUpdateFunctionState(const QString &strLinkName, const QString &strFunctionName, const int &state); + void sigUpdateActionState(const QString &strLinkName, const QString &strFunctionName, const QString &strActionName, const int &state); + +public slots: + void subscribeLinkCtrlList(QList list); + void clearSubscribe(); + +private: + int m_nDomainID{-1}; + int m_nAppID{-1}; + QTimer * m_Timer{nullptr}; + kbd_dbms::CRdbNetApi * m_rdbNetApi{nullptr}; + QMutex mutex; + QList m_linkAgeList; + +}; + +#endif // CLINKSTATESTATEMANAGE_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTableModel.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTableModel.cpp index 014a1c46..4ee79fc3 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTableModel.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTableModel.cpp @@ -1,259 +1,259 @@ -#include "CLinkCtrlTableModel.h" -#include "QDateTime" - -CLinkCtrlTableModel::CLinkCtrlTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header << tr("联动名称") << tr("联动类型") << tr("联动状态") << tr("执行方式") << tr("触发时间"); -} - -void CLinkCtrlTableModel::reset() -{ - beginResetModel(); - m_linkCtrlList.clear(); - endResetModel(); -} - -void CLinkCtrlTableModel::updateModelData(const QList listLinkCtrlInfo) -{ - for (int nIndex(0); nIndex < listLinkCtrlInfo.size(); nIndex++) - { - bool isLinkCtrlExist = false; - for (int nLinkCtrlIndex(0); nLinkCtrlIndex < m_linkCtrlList.size(); nLinkCtrlIndex++) - { - if (listLinkCtrlInfo[nIndex].linkageName == m_linkCtrlList[nLinkCtrlIndex].linkageName && listLinkCtrlInfo[nIndex].nodeType == 0) - { - isLinkCtrlExist = true; - m_linkCtrlList[nLinkCtrlIndex] = listLinkCtrlInfo[nIndex]; - QModelIndex topLeft = createIndex(nLinkCtrlIndex, 0); - QModelIndex bottomRight = createIndex(nLinkCtrlIndex, columnCount()); - emit dataChanged(topLeft, bottomRight); - } - } - if (!isLinkCtrlExist) - { - insertLinkAge(listLinkCtrlInfo[nIndex]); - } - } -} - -void CLinkCtrlTableModel::insertLinkAge(S_LINKCTRL_INFO info) -{ - beginInsertRows(QModelIndex(), m_linkCtrlList.size(), m_linkCtrlList.size()); - m_linkCtrlList.append(info); - endInsertRows(); - emit sigRowCountChanged(); -} - -QModelIndex CLinkCtrlTableModel::indexof(const QString &strLinkName) -{ - for (int nIndex(0); nIndex < m_linkCtrlList.size(); nIndex++) - { - if (strLinkName == m_linkCtrlList[nIndex].linkageName) - { - QModelIndex modelIndex = createIndex(nIndex, 0); - return modelIndex; - } - } - return QModelIndex(); -} - -QVariant CLinkCtrlTableModel::value(const QModelIndex &index) -{ - if (!index.isValid()) - { - return QVariant(); - } - switch (index.column()) - { - case 0: - return m_linkCtrlList[index.row()].linkageName; - case 1: - return m_linkCtrlList[index.row()].linkType; - case 2: - return m_linkCtrlList[index.row()].status; - case 3: - return m_linkCtrlList[index.row()].exeType; - case 4: - return m_linkCtrlList[index.row()].triggerTime; - default: - break; - } - return QVariant(); -} - -void CLinkCtrlTableModel::updateLinkAgeState(const QString &strLinkName, const int &state, const quint64 &triggerTime) -{ - for (int nIndex(0); nIndex < m_linkCtrlList.size(); nIndex++) - { - if (strLinkName == m_linkCtrlList[nIndex].linkageName) - { - QModelIndex topLeft = createIndex(nIndex, 0); - QModelIndex bottomRight = createIndex(nIndex, columnCount()); - m_linkCtrlList[nIndex].status = state; - if (triggerTime > 0) - { - m_linkCtrlList[nIndex].triggerTime = triggerTime; - } - emit dataChanged(topLeft, bottomRight); - } - } -} - -bool CLinkCtrlTableModel::contains(const QString &strLinkName) -{ - foreach(S_LINKCTRL_INFO info, m_linkCtrlList) - { - if (info.linkageName == strLinkName) - { - return true; - } - } - return false; -} - -QVariant CLinkCtrlTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole != role || section < 0) - { - return QVariant(); - } - - if(Qt::Horizontal == orientation) - { - return m_header[section]; - } - else - { - return section; - } -} - -int CLinkCtrlTableModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_linkCtrlList.size(); -} - -int CLinkCtrlTableModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.size(); -} - -QVariant CLinkCtrlTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || (Qt::DisplayRole != role && Qt::TextAlignmentRole != role)) - return QVariant(); - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignVCenter | Qt::AlignHCenter); - } - - switch (index.column()) - { - case 0: - { - return m_linkCtrlList[index.row()].linkageDescription; - } - case 1: - { -// switch (m_linkCtrlList[index.row()].linkType) -// { -// case 0: -// return tr("联动执行"); -// case 1: -// return tr("联动报告111"); -// default: -// break; -// } - for(int dex = 0;dex < m_linkType.size(); dex++) - { - if(m_linkCtrlList[index.row()].linkType == dex) - { - return m_linkType.at(dex); - } - } - break; - } - case 2: - { - qint32 status = m_linkCtrlList[index.row()].status; - switch ( (E_LCS_STATUS)status ) - { - case E_RESTING_STATUS: - return tr("未执行"); - //break; - case E_RUNNING_STATUS: - return tr("正在执行"); - //break; - case E_TRIGGERED_STATUS: - return tr("已触发"); - //break; - case E_FAILED_STATUS: - return tr("执行失败"); - //break; - case E_SUCCESS_STATUS: - return tr("执行成功"); - //break; - case E_STOP_STATUS: - return tr("执行终止"); - //break; - case E_PAUSE_STATUS: - return tr("执行暂停"); - //break; - case E_SKIP_STATUS: - return tr("执行跳过"); - //break; - case E_INVALID_STATUS: - default: - return tr("过期配置"); - //break; - } - break; - } - case 3: - { - switch (m_linkCtrlList[index.row()].exeType) - { - case 0: - return tr("全自动"); - case 1: - return tr("半自动"); - case 2: - return tr("手动"); - default: - break; - } - break; - } - case 4: - { - if(E_INVALID_STATUS == (E_LCS_STATUS)m_linkCtrlList[index.row()].status) - { - return tr("请点击“所有联动”按钮刷新配置"); - } - if(m_linkCtrlList[index.row()].triggerTime == 0) - { - return QVariant(); - } - return QDateTime::fromSecsSinceEpoch(m_linkCtrlList[index.row()].triggerTime).toString("yyyy-MM-dd hh:mm:ss"); - break; - } - default: - break; - } - return QVariant(); -} - -bool CLinkCtrlTableModel::setLinkTypeList(QStringList linkList) -{ - m_linkType = linkList; - return true; -} - +#include "CLinkCtrlTableModel.h" +#include "QDateTime" + +CLinkCtrlTableModel::CLinkCtrlTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header << tr("联动名称") << tr("联动类型") << tr("联动状态") << tr("执行方式") << tr("触发时间"); +} + +void CLinkCtrlTableModel::reset() +{ + beginResetModel(); + m_linkCtrlList.clear(); + endResetModel(); +} + +void CLinkCtrlTableModel::updateModelData(const QList listLinkCtrlInfo) +{ + for (int nIndex(0); nIndex < listLinkCtrlInfo.size(); nIndex++) + { + bool isLinkCtrlExist = false; + for (int nLinkCtrlIndex(0); nLinkCtrlIndex < m_linkCtrlList.size(); nLinkCtrlIndex++) + { + if (listLinkCtrlInfo[nIndex].linkageName == m_linkCtrlList[nLinkCtrlIndex].linkageName && listLinkCtrlInfo[nIndex].nodeType == 0) + { + isLinkCtrlExist = true; + m_linkCtrlList[nLinkCtrlIndex] = listLinkCtrlInfo[nIndex]; + QModelIndex topLeft = createIndex(nLinkCtrlIndex, 0); + QModelIndex bottomRight = createIndex(nLinkCtrlIndex, columnCount()); + emit dataChanged(topLeft, bottomRight); + } + } + if (!isLinkCtrlExist) + { + insertLinkAge(listLinkCtrlInfo[nIndex]); + } + } +} + +void CLinkCtrlTableModel::insertLinkAge(S_LINKCTRL_INFO info) +{ + beginInsertRows(QModelIndex(), m_linkCtrlList.size(), m_linkCtrlList.size()); + m_linkCtrlList.append(info); + endInsertRows(); + emit sigRowCountChanged(); +} + +QModelIndex CLinkCtrlTableModel::indexof(const QString &strLinkName) +{ + for (int nIndex(0); nIndex < m_linkCtrlList.size(); nIndex++) + { + if (strLinkName == m_linkCtrlList[nIndex].linkageName) + { + QModelIndex modelIndex = createIndex(nIndex, 0); + return modelIndex; + } + } + return QModelIndex(); +} + +QVariant CLinkCtrlTableModel::value(const QModelIndex &index) +{ + if (!index.isValid()) + { + return QVariant(); + } + switch (index.column()) + { + case 0: + return m_linkCtrlList[index.row()].linkageName; + case 1: + return m_linkCtrlList[index.row()].linkType; + case 2: + return m_linkCtrlList[index.row()].status; + case 3: + return m_linkCtrlList[index.row()].exeType; + case 4: + return m_linkCtrlList[index.row()].triggerTime; + default: + break; + } + return QVariant(); +} + +void CLinkCtrlTableModel::updateLinkAgeState(const QString &strLinkName, const int &state, const quint64 &triggerTime) +{ + for (int nIndex(0); nIndex < m_linkCtrlList.size(); nIndex++) + { + if (strLinkName == m_linkCtrlList[nIndex].linkageName) + { + QModelIndex topLeft = createIndex(nIndex, 0); + QModelIndex bottomRight = createIndex(nIndex, columnCount()); + m_linkCtrlList[nIndex].status = state; + if (triggerTime > 0) + { + m_linkCtrlList[nIndex].triggerTime = triggerTime; + } + emit dataChanged(topLeft, bottomRight); + } + } +} + +bool CLinkCtrlTableModel::contains(const QString &strLinkName) +{ + foreach(S_LINKCTRL_INFO info, m_linkCtrlList) + { + if (info.linkageName == strLinkName) + { + return true; + } + } + return false; +} + +QVariant CLinkCtrlTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole != role || section < 0) + { + return QVariant(); + } + + if(Qt::Horizontal == orientation) + { + return m_header[section]; + } + else + { + return section; + } +} + +int CLinkCtrlTableModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_linkCtrlList.size(); +} + +int CLinkCtrlTableModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.size(); +} + +QVariant CLinkCtrlTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || (Qt::DisplayRole != role && Qt::TextAlignmentRole != role)) + return QVariant(); + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignVCenter | Qt::AlignHCenter); + } + + switch (index.column()) + { + case 0: + { + return m_linkCtrlList[index.row()].linkageDescription; + } + case 1: + { +// switch (m_linkCtrlList[index.row()].linkType) +// { +// case 0: +// return tr("联动执行"); +// case 1: +// return tr("联动报告111"); +// default: +// break; +// } + for(int dex = 0;dex < m_linkType.size(); dex++) + { + if(m_linkCtrlList[index.row()].linkType == dex) + { + return m_linkType.at(dex); + } + } + break; + } + case 2: + { + qint32 status = m_linkCtrlList[index.row()].status; + switch ( (E_LCS_STATUS)status ) + { + case E_RESTING_STATUS: + return tr("未执行"); + //break; + case E_RUNNING_STATUS: + return tr("正在执行"); + //break; + case E_TRIGGERED_STATUS: + return tr("已触发"); + //break; + case E_FAILED_STATUS: + return tr("执行失败"); + //break; + case E_SUCCESS_STATUS: + return tr("执行成功"); + //break; + case E_STOP_STATUS: + return tr("执行终止"); + //break; + case E_PAUSE_STATUS: + return tr("执行暂停"); + //break; + case E_SKIP_STATUS: + return tr("执行跳过"); + //break; + case E_INVALID_STATUS: + default: + return tr("过期配置"); + //break; + } + break; + } + case 3: + { + switch (m_linkCtrlList[index.row()].exeType) + { + case 0: + return tr("全自动"); + case 1: + return tr("半自动"); + case 2: + return tr("手动"); + default: + break; + } + break; + } + case 4: + { + if(E_INVALID_STATUS == (E_LCS_STATUS)m_linkCtrlList[index.row()].status) + { + return tr("请点击“所有联动”按钮刷新配置"); + } + if(m_linkCtrlList[index.row()].triggerTime == 0) + { + return QVariant(); + } + return QDateTime::fromSecsSinceEpoch(m_linkCtrlList[index.row()].triggerTime).toString("yyyy-MM-dd hh:mm:ss"); + break; + } + default: + break; + } + return QVariant(); +} + +bool CLinkCtrlTableModel::setLinkTypeList(QStringList linkList) +{ + m_linkType = linkList; + return true; +} + diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTableModel.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTableModel.h index e176e40f..51f62c70 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTableModel.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTableModel.h @@ -1,46 +1,46 @@ -#ifndef CLINKCTRLTABLEMODEL_H -#define CLINKCTRLTABLEMODEL_H - -#include -#include "linkctrl_def.h" - -class CLinkCtrlTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CLinkCtrlTableModel(QObject *parent = nullptr); - - void reset(); - - void updateModelData(const QList listLinkCtrlInfo); - - void insertLinkAge(S_LINKCTRL_INFO info); - - QModelIndex indexof(const QString &strLinkName); - - QVariant value(const QModelIndex &index); - - void updateLinkAgeState(const QString &strLinkName, const int &state, const quint64 &triggerTime = 0); - - bool contains(const QString &strLinkName); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - bool setLinkTypeList(QStringList linkList); - -signals: - void sigRowCountChanged(); - -private: - QStringList m_header; - QStringList m_linkType; - QList m_linkCtrlList; -}; - -#endif // CLINKCTRLTABLEMODEL_H +#ifndef CLINKCTRLTABLEMODEL_H +#define CLINKCTRLTABLEMODEL_H + +#include +#include "linkctrl_def.h" + +class CLinkCtrlTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CLinkCtrlTableModel(QObject *parent = nullptr); + + void reset(); + + void updateModelData(const QList listLinkCtrlInfo); + + void insertLinkAge(S_LINKCTRL_INFO info); + + QModelIndex indexof(const QString &strLinkName); + + QVariant value(const QModelIndex &index); + + void updateLinkAgeState(const QString &strLinkName, const int &state, const quint64 &triggerTime = 0); + + bool contains(const QString &strLinkName); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + bool setLinkTypeList(QStringList linkList); + +signals: + void sigRowCountChanged(); + +private: + QStringList m_header; + QStringList m_linkType; + QList m_linkCtrlList; +}; + +#endif // CLINKCTRLTABLEMODEL_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeModel.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeModel.cpp index ec1669bd..a887d4ed 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeModel.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeModel.cpp @@ -1,565 +1,565 @@ -#include "CLinkCtrlTreeModel.h" - -CLinkCtrlTreeModelItem::CLinkCtrlTreeModelItem(CLinkCtrlTreeModelItem *parent) - : m_parent(parent), - m_strDescription(QString()) -{ - m_listChild.clear(); - if(Q_NULLPTR != m_parent) - { - m_parent->appendChild(this); - } -} - -CLinkCtrlTreeModelItem::CLinkCtrlTreeModelItem(const QList &data, CLinkCtrlTreeModelItem *parent) - : m_data(data), - m_parent(parent), - m_strDescription(QString()) -{ - m_listChild.clear(); - if(Q_NULLPTR != m_parent) - { - m_parent->appendChild(this); - } -} - -CLinkCtrlTreeModelItem::~CLinkCtrlTreeModelItem() -{ - qDeleteAll(m_listChild); - if (Q_NULLPTR != m_parent) - { - m_parent->removeChild(this); - } -} - -bool CLinkCtrlTreeModelItem::isRootItem() -{ - if (m_parent == Q_NULLPTR) - { - return true; - } - return false; -} - -CLinkCtrlTreeModelItem *CLinkCtrlTreeModelItem::child(const int row) -{ - if(row < m_listChild.size()) - { - return m_listChild.value(row); - } - - return Q_NULLPTR; -} - -void CLinkCtrlTreeModelItem::appendChild(CLinkCtrlTreeModelItem *child) -{ - m_listChild.append(child); -} - -void CLinkCtrlTreeModelItem::removeChild(CLinkCtrlTreeModelItem *child) -{ - m_listChild.removeOne(child); -} - -void CLinkCtrlTreeModelItem::clear() -{ - if (!m_listChild.isEmpty()) - { - QList::iterator it = m_listChild.begin(); - while (it != m_listChild.end()) - { - CLinkCtrlTreeModelItem * item = *it; - it = m_listChild.erase(it); - item->clear(); - delete item; - } - } -} - -CLinkCtrlTreeModelItem *CLinkCtrlTreeModelItem::parent() -{ - return m_parent; -} - -int CLinkCtrlTreeModelItem::row() -{ - if(m_parent) - { - return m_parent->m_listChild.indexOf(this); - } - return 0; -} - -int CLinkCtrlTreeModelItem::childCount() -{ - if (m_listChild.isEmpty()) - { - return 0; - } - - return m_listChild.size(); -} - -int CLinkCtrlTreeModelItem::columnCount() -{ - return m_data.size(); -} - -QVariant CLinkCtrlTreeModelItem::data(QModelIndex index) -{ - return m_data.value(index.column()); -} - -bool CLinkCtrlTreeModelItem::setData(QModelIndex index, const QVariant &value) -{ - if(!index.isValid() || !value.isValid()) - { - return false; - } - m_data[index.column()] = value; - if (1 == index.column()) - { - QString functionName; - QString actionName; - if (m_parent->isRootItem()) - { - functionName = m_data[0].toString(); - actionName = QString(""); - } - else if (!m_parent->isRootItem()) - { - functionName = m_parent->m_data[0].toString(); - actionName = m_data[0].toString(); - } - emit itemCheckStateChanged(functionName, actionName, value.toInt()); - } - return true; -} - -QString CLinkCtrlTreeModelItem::description() -{ - return m_strDescription; -} - -void CLinkCtrlTreeModelItem::setDescription(const QString &desc) -{ - m_strDescription = desc; -} - -CLinkCtrlTreeModel::CLinkCtrlTreeModel(QObject *parent) - : QAbstractItemModel(parent), - m_rootItem(Q_NULLPTR) -{ - m_header << tr("内容") << tr("选择") << tr("执行方式") << tr("延迟时间")<< tr("失败处理") << tr("执行状态"); -} - -void CLinkCtrlTreeModel::reset() -{ - if (m_rootItem) - { - beginResetModel(); - m_rootItem->clear(); - endResetModel(); - } -} - -void CLinkCtrlTreeModel::updateModelData(const QList &listLinkCtrlInfo) -{ - beginResetModel(); - if(Q_NULLPTR != m_rootItem) - { - m_rootItem->clear(); - delete m_rootItem; - } - m_rootItem = new CLinkCtrlTreeModelItem(); - for(int nIndex(0); nIndex < listLinkCtrlInfo.size(); nIndex++) - { - if(1 == listLinkCtrlInfo[nIndex].nodeType) - { - QList values; - values.append(listLinkCtrlInfo[nIndex].funcName); - values.append(listLinkCtrlInfo[nIndex].checked); - values.append(listLinkCtrlInfo[nIndex].relation); - values.append(listLinkCtrlInfo[nIndex].delayTime); - values.append(listLinkCtrlInfo[nIndex].fallStrage); - values.append(listLinkCtrlInfo[nIndex].status); - - CLinkCtrlTreeModelItem * item = new CLinkCtrlTreeModelItem(values, m_rootItem); - item->setDescription(listLinkCtrlInfo[nIndex].funcDescription); - connect(item, &CLinkCtrlTreeModelItem::itemCheckStateChanged, this, &CLinkCtrlTreeModel::itemCheckStateChanged); - for (int nChildIndx(0); nChildIndx < listLinkCtrlInfo.size(); nChildIndx++) - { - if (2 == listLinkCtrlInfo[nChildIndx].nodeType - && listLinkCtrlInfo[nChildIndx].linkageName == listLinkCtrlInfo[nIndex].linkageName - && listLinkCtrlInfo[nChildIndx].funcName == listLinkCtrlInfo[nIndex].funcName) - { - QList childValues; - childValues.append(listLinkCtrlInfo[nChildIndx].actionName); - childValues.append(listLinkCtrlInfo[nChildIndx].checked); - childValues.append(listLinkCtrlInfo[nChildIndx].relation); - childValues.append(listLinkCtrlInfo[nChildIndx].delayTime); - childValues.append(listLinkCtrlInfo[nChildIndx].fallStrage); - childValues.append(listLinkCtrlInfo[nChildIndx].status); - - CLinkCtrlTreeModelItem * childItem = new CLinkCtrlTreeModelItem(childValues, item); - childItem->setDescription(listLinkCtrlInfo[nChildIndx].actionDescription); - connect(childItem, &CLinkCtrlTreeModelItem::itemCheckStateChanged, this, &CLinkCtrlTreeModel::itemCheckStateChanged); - } - } - } - } - endResetModel(); -} -void CLinkCtrlTreeModel::updateFunctionState(const QString &strFunctionName, const int &state) -{ - if(m_rootItem) - { - int nRowCount = m_rootItem->childCount(); - for (int nIndex(0); nIndex < nRowCount; nIndex++) - { - QModelIndex nameIndex = createIndex(nIndex, 0); - if(nameIndex.isValid()) - { - if (strFunctionName == m_rootItem->child(nIndex)->data(nameIndex).toString()) - { - QModelIndex stateIndex = createIndex(nIndex, columnCount() - 1); - if(m_rootItem->child(nIndex)) - { - m_rootItem->child(nIndex)->setData(stateIndex, state); - } - emit dataChanged(nameIndex, stateIndex); - } - } - } - } -} - -void CLinkCtrlTreeModel::updateActionState(const QString &strFunctionName, const QString &strActionName, const int &state) -{ - if(m_rootItem) - { - int nRowCount = m_rootItem->childCount(); - for (int nIndex(0); nIndex < nRowCount; nIndex++) - { - QModelIndex functionIndex = createIndex(nIndex, 0); - CLinkCtrlTreeModelItem * functionItem = m_rootItem->child(nIndex); - if(functionItem) - { - if (strFunctionName == functionItem->data(functionIndex).toString()) - { - for (int nChildIndex(0); nChildIndex < functionItem->childCount(); nChildIndex++) - { - if(functionItem->child(nChildIndex)) - { - CLinkCtrlTreeModelItem *childItem = functionItem->child(nChildIndex); - QModelIndex nameIndex = createIndex(nChildIndex, 0, childItem); - if (strActionName == childItem->data(nameIndex).toString()) - { - QModelIndex stateIndex = createIndex(nChildIndex, columnCount() - 1, childItem); - childItem->setData(stateIndex, state); - emit dataChanged(nameIndex, stateIndex); - } - } - } - } - } - } - } -} - -QVariant CLinkCtrlTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return m_header[section]; - } - if (Qt::TextAlignmentRole == role) - { - return Qt::AlignCenter; - } - return QVariant(); -} - -QModelIndex CLinkCtrlTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) - { - return QModelIndex(); - } - - CLinkCtrlTreeModelItem * parentItem; - if(!parent.isValid()) - { - parentItem = m_rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - if(parentItem) - { - CLinkCtrlTreeModelItem *childItem = parentItem->child(row); - if(childItem) - { - return createIndex(row,column,childItem); - } - } - - return QModelIndex(); -} - -QModelIndex CLinkCtrlTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - CLinkCtrlTreeModelItem *childItem = static_cast(index.internalPointer()); - if (!childItem) - { - return QModelIndex(); - } - - CLinkCtrlTreeModelItem *parentItem = childItem->parent(); - - if (parentItem == m_rootItem) - { - return QModelIndex(); - } - - return createIndex(parentItem->row(), index.column(), parentItem); -} - -int CLinkCtrlTreeModel::rowCount(const QModelIndex &parent) const -{ - if(!parent.isValid()) - { - if (NULL != m_rootItem) - { - return m_rootItem->childCount(); - } - else - { - return 0; - } - } - else - { - CLinkCtrlTreeModelItem * parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); - } -} - -int CLinkCtrlTreeModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return m_header.size(); -} - -QVariant CLinkCtrlTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - CLinkCtrlTreeModelItem * item = static_cast(index.internalPointer()); - if(item) - { - if (Qt::TextAlignmentRole == role) - { - if(item->childCount() > 0 && index.column() == 0) - { - return QVariant(Qt::AlignVCenter | Qt::AlignLeft); - } - else - { - return QVariant(Qt::AlignVCenter | Qt::AlignHCenter); - } - } - - switch (index.column()) - { - case 0: - if (Qt::DisplayRole == role) - { - return item->description(); - } - break; - case 1: - if(Qt::CheckStateRole == role) - { - return item->data(index).toInt(); - } - else if (Qt::DisplayRole == role) - { - return QVariant(); - } - break; - case 2: - if (Qt::DisplayRole == role) - { - qint32 relation = item->data(index).toInt(); - if (0 == relation) - { - return tr("串行"); - } - else if (1 == relation) - { - return tr("并行"); - } - else - { - return ""; - } - } - break; - case 3: - if (Qt::DisplayRole == role) - { - if (item->childCount() > 0) - { - return QVariant(); - } - return QString::number(item->data(index).toInt()) + tr(" 秒"); - } - break; - case 4: - if (Qt::DisplayRole == role) - { - if (item->childCount() > 0) - { - return QVariant(); - } - qint32 fallStrage = item->data(index).toInt(); - if (0 == fallStrage) - { - return tr("自动跳过"); - } - else if (1 == fallStrage) - { - return tr("人工干预"); - } - else if (2 == fallStrage) - { - return tr("终止联动"); - } - else if (3 == fallStrage) - { - return tr("执行下个功能"); - } - } - break; - case 5: - if (Qt::DisplayRole == role) - { - if(item->childCount() > 0) - { - return tr(""); //< 功能不显示状态 - } - - qint32 status = item->data(index).toInt(); - if (E_RESTING_STATUS == (E_LCS_STATUS)status) - { - return tr("未执行"); - } - else if (E_RUNNING_STATUS == (E_LCS_STATUS)status) - { - return tr("正在执行"); - } - else if (E_TRIGGERED_STATUS == (E_LCS_STATUS)status) - { - return tr("已触发"); - } - else if (E_FAILED_STATUS == (E_LCS_STATUS)status) - { - return tr("执行失败"); - } - else if (E_SUCCESS_STATUS == (E_LCS_STATUS)status) - { - return tr("执行成功"); - } - else if (E_STOP_STATUS == (E_LCS_STATUS)status) - { - return tr("执行终止"); - } - else if (E_PAUSE_STATUS == (E_LCS_STATUS)status) - { - return tr("执行暂停"); - } - else if (E_SKIP_STATUS == (E_LCS_STATUS)status) - { - return tr("执行跳过"); - } - } - break; - default: - break; - } - - - } - return QVariant(); -} - -bool CLinkCtrlTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - - if(Qt::CheckStateRole != role || !index.isValid()) - { - return false; - } - if(index.column() == 1) - { - CLinkCtrlTreeModelItem * item = static_cast(index.internalPointer()); - if(item) - { - item->setData(index, value); - if(0 == value || 2 == value) - { - for(int nRow(0); nRow < item->childCount(); nRow++) - { - QModelIndex childeIndex = this->index(nRow, index.column(), index); - item->child(nRow)->setData(childeIndex, value); - emit dataChanged(childeIndex, childeIndex); - } - if(Q_NULLPTR != item->parent() && m_rootItem != item->parent()) - { - bool isEqu = true; - for(int nRow(0); nRow < item->parent()->childCount(); nRow++) - { - if(item->parent()->child(nRow)->data(index) != value) - { - isEqu = false; - break; - } - } - if(isEqu) - { - item->parent()->setData(parent(index), value); - } - else - { - item->parent()->setData(parent(index), 1); - } - emit dataChanged(parent(index), parent(index)); - } - } - } - } - return true; -} - -Qt::ItemFlags CLinkCtrlTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - if(index.column() == 1) - { - return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; - } - return Qt::ItemIsEnabled; -} +#include "CLinkCtrlTreeModel.h" + +CLinkCtrlTreeModelItem::CLinkCtrlTreeModelItem(CLinkCtrlTreeModelItem *parent) + : m_parent(parent), + m_strDescription(QString()) +{ + m_listChild.clear(); + if(Q_NULLPTR != m_parent) + { + m_parent->appendChild(this); + } +} + +CLinkCtrlTreeModelItem::CLinkCtrlTreeModelItem(const QList &data, CLinkCtrlTreeModelItem *parent) + : m_data(data), + m_parent(parent), + m_strDescription(QString()) +{ + m_listChild.clear(); + if(Q_NULLPTR != m_parent) + { + m_parent->appendChild(this); + } +} + +CLinkCtrlTreeModelItem::~CLinkCtrlTreeModelItem() +{ + qDeleteAll(m_listChild); + if (Q_NULLPTR != m_parent) + { + m_parent->removeChild(this); + } +} + +bool CLinkCtrlTreeModelItem::isRootItem() +{ + if (m_parent == Q_NULLPTR) + { + return true; + } + return false; +} + +CLinkCtrlTreeModelItem *CLinkCtrlTreeModelItem::child(const int row) +{ + if(row < m_listChild.size()) + { + return m_listChild.value(row); + } + + return Q_NULLPTR; +} + +void CLinkCtrlTreeModelItem::appendChild(CLinkCtrlTreeModelItem *child) +{ + m_listChild.append(child); +} + +void CLinkCtrlTreeModelItem::removeChild(CLinkCtrlTreeModelItem *child) +{ + m_listChild.removeOne(child); +} + +void CLinkCtrlTreeModelItem::clear() +{ + if (!m_listChild.isEmpty()) + { + QList::iterator it = m_listChild.begin(); + while (it != m_listChild.end()) + { + CLinkCtrlTreeModelItem * item = *it; + it = m_listChild.erase(it); + item->clear(); + delete item; + } + } +} + +CLinkCtrlTreeModelItem *CLinkCtrlTreeModelItem::parent() +{ + return m_parent; +} + +int CLinkCtrlTreeModelItem::row() +{ + if(m_parent) + { + return m_parent->m_listChild.indexOf(this); + } + return 0; +} + +int CLinkCtrlTreeModelItem::childCount() +{ + if (m_listChild.isEmpty()) + { + return 0; + } + + return m_listChild.size(); +} + +int CLinkCtrlTreeModelItem::columnCount() +{ + return m_data.size(); +} + +QVariant CLinkCtrlTreeModelItem::data(QModelIndex index) +{ + return m_data.value(index.column()); +} + +bool CLinkCtrlTreeModelItem::setData(QModelIndex index, const QVariant &value) +{ + if(!index.isValid() || !value.isValid()) + { + return false; + } + m_data[index.column()] = value; + if (1 == index.column()) + { + QString functionName; + QString actionName; + if (m_parent->isRootItem()) + { + functionName = m_data[0].toString(); + actionName = QString(""); + } + else if (!m_parent->isRootItem()) + { + functionName = m_parent->m_data[0].toString(); + actionName = m_data[0].toString(); + } + emit itemCheckStateChanged(functionName, actionName, value.toInt()); + } + return true; +} + +QString CLinkCtrlTreeModelItem::description() +{ + return m_strDescription; +} + +void CLinkCtrlTreeModelItem::setDescription(const QString &desc) +{ + m_strDescription = desc; +} + +CLinkCtrlTreeModel::CLinkCtrlTreeModel(QObject *parent) + : QAbstractItemModel(parent), + m_rootItem(Q_NULLPTR) +{ + m_header << tr("内容") << tr("选择") << tr("执行方式") << tr("延迟时间")<< tr("失败处理") << tr("执行状态"); +} + +void CLinkCtrlTreeModel::reset() +{ + if (m_rootItem) + { + beginResetModel(); + m_rootItem->clear(); + endResetModel(); + } +} + +void CLinkCtrlTreeModel::updateModelData(const QList &listLinkCtrlInfo) +{ + beginResetModel(); + if(Q_NULLPTR != m_rootItem) + { + m_rootItem->clear(); + delete m_rootItem; + } + m_rootItem = new CLinkCtrlTreeModelItem(); + for(int nIndex(0); nIndex < listLinkCtrlInfo.size(); nIndex++) + { + if(1 == listLinkCtrlInfo[nIndex].nodeType) + { + QList values; + values.append(listLinkCtrlInfo[nIndex].funcName); + values.append(listLinkCtrlInfo[nIndex].checked); + values.append(listLinkCtrlInfo[nIndex].relation); + values.append(listLinkCtrlInfo[nIndex].delayTime); + values.append(listLinkCtrlInfo[nIndex].fallStrage); + values.append(listLinkCtrlInfo[nIndex].status); + + CLinkCtrlTreeModelItem * item = new CLinkCtrlTreeModelItem(values, m_rootItem); + item->setDescription(listLinkCtrlInfo[nIndex].funcDescription); + connect(item, &CLinkCtrlTreeModelItem::itemCheckStateChanged, this, &CLinkCtrlTreeModel::itemCheckStateChanged); + for (int nChildIndx(0); nChildIndx < listLinkCtrlInfo.size(); nChildIndx++) + { + if (2 == listLinkCtrlInfo[nChildIndx].nodeType + && listLinkCtrlInfo[nChildIndx].linkageName == listLinkCtrlInfo[nIndex].linkageName + && listLinkCtrlInfo[nChildIndx].funcName == listLinkCtrlInfo[nIndex].funcName) + { + QList childValues; + childValues.append(listLinkCtrlInfo[nChildIndx].actionName); + childValues.append(listLinkCtrlInfo[nChildIndx].checked); + childValues.append(listLinkCtrlInfo[nChildIndx].relation); + childValues.append(listLinkCtrlInfo[nChildIndx].delayTime); + childValues.append(listLinkCtrlInfo[nChildIndx].fallStrage); + childValues.append(listLinkCtrlInfo[nChildIndx].status); + + CLinkCtrlTreeModelItem * childItem = new CLinkCtrlTreeModelItem(childValues, item); + childItem->setDescription(listLinkCtrlInfo[nChildIndx].actionDescription); + connect(childItem, &CLinkCtrlTreeModelItem::itemCheckStateChanged, this, &CLinkCtrlTreeModel::itemCheckStateChanged); + } + } + } + } + endResetModel(); +} +void CLinkCtrlTreeModel::updateFunctionState(const QString &strFunctionName, const int &state) +{ + if(m_rootItem) + { + int nRowCount = m_rootItem->childCount(); + for (int nIndex(0); nIndex < nRowCount; nIndex++) + { + QModelIndex nameIndex = createIndex(nIndex, 0); + if(nameIndex.isValid()) + { + if (strFunctionName == m_rootItem->child(nIndex)->data(nameIndex).toString()) + { + QModelIndex stateIndex = createIndex(nIndex, columnCount() - 1); + if(m_rootItem->child(nIndex)) + { + m_rootItem->child(nIndex)->setData(stateIndex, state); + } + emit dataChanged(nameIndex, stateIndex); + } + } + } + } +} + +void CLinkCtrlTreeModel::updateActionState(const QString &strFunctionName, const QString &strActionName, const int &state) +{ + if(m_rootItem) + { + int nRowCount = m_rootItem->childCount(); + for (int nIndex(0); nIndex < nRowCount; nIndex++) + { + QModelIndex functionIndex = createIndex(nIndex, 0); + CLinkCtrlTreeModelItem * functionItem = m_rootItem->child(nIndex); + if(functionItem) + { + if (strFunctionName == functionItem->data(functionIndex).toString()) + { + for (int nChildIndex(0); nChildIndex < functionItem->childCount(); nChildIndex++) + { + if(functionItem->child(nChildIndex)) + { + CLinkCtrlTreeModelItem *childItem = functionItem->child(nChildIndex); + QModelIndex nameIndex = createIndex(nChildIndex, 0, childItem); + if (strActionName == childItem->data(nameIndex).toString()) + { + QModelIndex stateIndex = createIndex(nChildIndex, columnCount() - 1, childItem); + childItem->setData(stateIndex, state); + emit dataChanged(nameIndex, stateIndex); + } + } + } + } + } + } + } +} + +QVariant CLinkCtrlTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return m_header[section]; + } + if (Qt::TextAlignmentRole == role) + { + return Qt::AlignCenter; + } + return QVariant(); +} + +QModelIndex CLinkCtrlTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) + { + return QModelIndex(); + } + + CLinkCtrlTreeModelItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + CLinkCtrlTreeModelItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,column,childItem); + } + } + + return QModelIndex(); +} + +QModelIndex CLinkCtrlTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CLinkCtrlTreeModelItem *childItem = static_cast(index.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + CLinkCtrlTreeModelItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + { + return QModelIndex(); + } + + return createIndex(parentItem->row(), index.column(), parentItem); +} + +int CLinkCtrlTreeModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (NULL != m_rootItem) + { + return m_rootItem->childCount(); + } + else + { + return 0; + } + } + else + { + CLinkCtrlTreeModelItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int CLinkCtrlTreeModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_header.size(); +} + +QVariant CLinkCtrlTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + CLinkCtrlTreeModelItem * item = static_cast(index.internalPointer()); + if(item) + { + if (Qt::TextAlignmentRole == role) + { + if(item->childCount() > 0 && index.column() == 0) + { + return QVariant(Qt::AlignVCenter | Qt::AlignLeft); + } + else + { + return QVariant(Qt::AlignVCenter | Qt::AlignHCenter); + } + } + + switch (index.column()) + { + case 0: + if (Qt::DisplayRole == role) + { + return item->description(); + } + break; + case 1: + if(Qt::CheckStateRole == role) + { + return item->data(index).toInt(); + } + else if (Qt::DisplayRole == role) + { + return QVariant(); + } + break; + case 2: + if (Qt::DisplayRole == role) + { + qint32 relation = item->data(index).toInt(); + if (0 == relation) + { + return tr("串行"); + } + else if (1 == relation) + { + return tr("并行"); + } + else + { + return ""; + } + } + break; + case 3: + if (Qt::DisplayRole == role) + { + if (item->childCount() > 0) + { + return QVariant(); + } + return QString::number(item->data(index).toInt()) + tr(" 秒"); + } + break; + case 4: + if (Qt::DisplayRole == role) + { + if (item->childCount() > 0) + { + return QVariant(); + } + qint32 fallStrage = item->data(index).toInt(); + if (0 == fallStrage) + { + return tr("自动跳过"); + } + else if (1 == fallStrage) + { + return tr("人工干预"); + } + else if (2 == fallStrage) + { + return tr("终止联动"); + } + else if (3 == fallStrage) + { + return tr("执行下个功能"); + } + } + break; + case 5: + if (Qt::DisplayRole == role) + { + if(item->childCount() > 0) + { + return tr(""); //< 功能不显示状态 + } + + qint32 status = item->data(index).toInt(); + if (E_RESTING_STATUS == (E_LCS_STATUS)status) + { + return tr("未执行"); + } + else if (E_RUNNING_STATUS == (E_LCS_STATUS)status) + { + return tr("正在执行"); + } + else if (E_TRIGGERED_STATUS == (E_LCS_STATUS)status) + { + return tr("已触发"); + } + else if (E_FAILED_STATUS == (E_LCS_STATUS)status) + { + return tr("执行失败"); + } + else if (E_SUCCESS_STATUS == (E_LCS_STATUS)status) + { + return tr("执行成功"); + } + else if (E_STOP_STATUS == (E_LCS_STATUS)status) + { + return tr("执行终止"); + } + else if (E_PAUSE_STATUS == (E_LCS_STATUS)status) + { + return tr("执行暂停"); + } + else if (E_SKIP_STATUS == (E_LCS_STATUS)status) + { + return tr("执行跳过"); + } + } + break; + default: + break; + } + + + } + return QVariant(); +} + +bool CLinkCtrlTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + + if(Qt::CheckStateRole != role || !index.isValid()) + { + return false; + } + if(index.column() == 1) + { + CLinkCtrlTreeModelItem * item = static_cast(index.internalPointer()); + if(item) + { + item->setData(index, value); + if(0 == value || 2 == value) + { + for(int nRow(0); nRow < item->childCount(); nRow++) + { + QModelIndex childeIndex = this->index(nRow, index.column(), index); + item->child(nRow)->setData(childeIndex, value); + emit dataChanged(childeIndex, childeIndex); + } + if(Q_NULLPTR != item->parent() && m_rootItem != item->parent()) + { + bool isEqu = true; + for(int nRow(0); nRow < item->parent()->childCount(); nRow++) + { + if(item->parent()->child(nRow)->data(index) != value) + { + isEqu = false; + break; + } + } + if(isEqu) + { + item->parent()->setData(parent(index), value); + } + else + { + item->parent()->setData(parent(index), 1); + } + emit dataChanged(parent(index), parent(index)); + } + } + } + } + return true; +} + +Qt::ItemFlags CLinkCtrlTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + if(index.column() == 1) + { + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + } + return Qt::ItemIsEnabled; +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeModel.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeModel.h index 6c36c765..9dbbad71 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeModel.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeModel.h @@ -1,80 +1,80 @@ -#ifndef CLINKCTRLTREEMODEL_H -#define CLINKCTRLTREEMODEL_H - -#include -#include "linkctrl_def.h" - -class CLinkCtrlTreeModelItem : public QObject -{ - Q_OBJECT - friend class CLinkCtrlTreeModel; - -public: - CLinkCtrlTreeModelItem(CLinkCtrlTreeModelItem * parent = Q_NULLPTR); - CLinkCtrlTreeModelItem(const QList &data, CLinkCtrlTreeModelItem * parent = Q_NULLPTR); - ~CLinkCtrlTreeModelItem(); - - bool isRootItem(); - CLinkCtrlTreeModelItem * parent(); - CLinkCtrlTreeModelItem * child(const int row); - void appendChild(CLinkCtrlTreeModelItem *child); - void removeChild(CLinkCtrlTreeModelItem *child); - void clear(); - - int row(); - int childCount(); - int columnCount(); - QVariant data(QModelIndex index); - bool setData(QModelIndex index, const QVariant &value); - - QString description(); - void setDescription(const QString &desc); - -signals: - void itemCheckStateChanged(const QString functionName, const QString actionName, const int checkedState); - -private: - QList m_data; - CLinkCtrlTreeModelItem * m_parent; - QList m_listChild; - QString m_strDescription; -}; - -class CLinkCtrlTreeModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - explicit CLinkCtrlTreeModel(QObject *parent = nullptr); - - void reset(); - - void updateModelData(const QList &listLinkCtrlInfo); - - void updateFunctionState(const QString &strFunctionName, const int &state); - - void updateActionState(const QString &strFunctionName, const QString &strActionName, const int &state); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - -signals: - void itemCheckStateChanged(const QString functionName, const QString actionName, const int checkedState); - -private: - QStringList m_header; - CLinkCtrlTreeModelItem * m_rootItem; -}; - -#endif // CLINKCTRLTREEMODEL_H +#ifndef CLINKCTRLTREEMODEL_H +#define CLINKCTRLTREEMODEL_H + +#include +#include "linkctrl_def.h" + +class CLinkCtrlTreeModelItem : public QObject +{ + Q_OBJECT + friend class CLinkCtrlTreeModel; + +public: + CLinkCtrlTreeModelItem(CLinkCtrlTreeModelItem * parent = Q_NULLPTR); + CLinkCtrlTreeModelItem(const QList &data, CLinkCtrlTreeModelItem * parent = Q_NULLPTR); + ~CLinkCtrlTreeModelItem(); + + bool isRootItem(); + CLinkCtrlTreeModelItem * parent(); + CLinkCtrlTreeModelItem * child(const int row); + void appendChild(CLinkCtrlTreeModelItem *child); + void removeChild(CLinkCtrlTreeModelItem *child); + void clear(); + + int row(); + int childCount(); + int columnCount(); + QVariant data(QModelIndex index); + bool setData(QModelIndex index, const QVariant &value); + + QString description(); + void setDescription(const QString &desc); + +signals: + void itemCheckStateChanged(const QString functionName, const QString actionName, const int checkedState); + +private: + QList m_data; + CLinkCtrlTreeModelItem * m_parent; + QList m_listChild; + QString m_strDescription; +}; + +class CLinkCtrlTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CLinkCtrlTreeModel(QObject *parent = nullptr); + + void reset(); + + void updateModelData(const QList &listLinkCtrlInfo); + + void updateFunctionState(const QString &strFunctionName, const int &state); + + void updateActionState(const QString &strFunctionName, const QString &strActionName, const int &state); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + +signals: + void itemCheckStateChanged(const QString functionName, const QString actionName, const int checkedState); + +private: + QStringList m_header; + CLinkCtrlTreeModelItem * m_rootItem; +}; + +#endif // CLINKCTRLTREEMODEL_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeView.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeView.cpp index 4fe9949d..3624cacc 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeView.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeView.cpp @@ -1,51 +1,51 @@ -#include "CLinkCtrlTreeView.h" -#include - -CLinkCtrlTreeView::CLinkCtrlTreeView(QWidget *parent) - : QTreeView(parent), - m_bAcceptMouseEvent(true) -{ -} - -CLinkCtrlTreeView::~CLinkCtrlTreeView() -{ - -} - -void CLinkCtrlTreeView::setAcceptMouseEvent(const bool &bEnable) -{ - m_bAcceptMouseEvent = bEnable; -} - -void CLinkCtrlTreeView::mousePressEvent(QMouseEvent *event) -{ - if(m_bAcceptMouseEvent) - { - return QTreeView::mousePressEvent(event); - } - event->accept(); - return; -} - -void CLinkCtrlTreeView::mouseMoveEvent(QMouseEvent *event) -{ - if(m_bAcceptMouseEvent) - { - return QTreeView::mouseMoveEvent(event); - } - event->accept(); - return; -} - -void CLinkCtrlTreeView::mouseReleaseEvent(QMouseEvent *event) -{ - if(m_bAcceptMouseEvent) - { - return QTreeView::mouseReleaseEvent(event); - } - event->accept(); - return; -} - - - +#include "CLinkCtrlTreeView.h" +#include + +CLinkCtrlTreeView::CLinkCtrlTreeView(QWidget *parent) + : QTreeView(parent), + m_bAcceptMouseEvent(true) +{ +} + +CLinkCtrlTreeView::~CLinkCtrlTreeView() +{ + +} + +void CLinkCtrlTreeView::setAcceptMouseEvent(const bool &bEnable) +{ + m_bAcceptMouseEvent = bEnable; +} + +void CLinkCtrlTreeView::mousePressEvent(QMouseEvent *event) +{ + if(m_bAcceptMouseEvent) + { + return QTreeView::mousePressEvent(event); + } + event->accept(); + return; +} + +void CLinkCtrlTreeView::mouseMoveEvent(QMouseEvent *event) +{ + if(m_bAcceptMouseEvent) + { + return QTreeView::mouseMoveEvent(event); + } + event->accept(); + return; +} + +void CLinkCtrlTreeView::mouseReleaseEvent(QMouseEvent *event) +{ + if(m_bAcceptMouseEvent) + { + return QTreeView::mouseReleaseEvent(event); + } + event->accept(); + return; +} + + + diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeView.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeView.h index 9ef509d0..8aa0787c 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeView.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlTreeView.h @@ -1,24 +1,24 @@ -#ifndef CLINKCTRLTREEVIEW_H -#define CLINKCTRLTREEVIEW_H - -#include - -class CLinkCtrlTreeView : public QTreeView -{ - Q_OBJECT -public: - explicit CLinkCtrlTreeView(QWidget *parent = Q_NULLPTR); - ~CLinkCtrlTreeView(); - - void setAcceptMouseEvent(const bool &bEnable); - -protected: - void mousePressEvent(QMouseEvent * event); - void mouseMoveEvent(QMouseEvent * event); - void mouseReleaseEvent(QMouseEvent * event); - -private: - bool m_bAcceptMouseEvent; -}; - -#endif // CLINKCTRLTREEVIEW_H +#ifndef CLINKCTRLTREEVIEW_H +#define CLINKCTRLTREEVIEW_H + +#include + +class CLinkCtrlTreeView : public QTreeView +{ + Q_OBJECT +public: + explicit CLinkCtrlTreeView(QWidget *parent = Q_NULLPTR); + ~CLinkCtrlTreeView(); + + void setAcceptMouseEvent(const bool &bEnable); + +protected: + void mousePressEvent(QMouseEvent * event); + void mouseMoveEvent(QMouseEvent * event); + void mouseReleaseEvent(QMouseEvent * event); + +private: + bool m_bAcceptMouseEvent; +}; + +#endif // CLINKCTRLTREEVIEW_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.cpp index ca86b7c7..c6015d4e 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.cpp @@ -1,1101 +1,1101 @@ -#include "CLinkCtrlWidget.h" -#include "ui_CLinkCtrlWidget.h" -#include "CLinkCtrlDataManage.h" -#include "CLinkCtrlStateManage.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include -#include -#include -#include -#include -#include -#include -#include "CLinkDBInterface.h" -#include "CHistoryLinkModel.h" -#include "CHistoryActionModel.h" -#include "CTableViewPrinter.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CommonConfigParse.h" -#include "pub_utility_api/FileStyle.h" -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" -#include -#include - - -using namespace kbd_public; -using namespace kbd_dbms; -using namespace kbd_idlfile::linkage; -using boost::property_tree::ptree; -using namespace std; - -CLinkCtrlWidget::CLinkCtrlWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CLinkCtrlWidget), - m_permTimer(NULL), - m_pLinkCtrlTableModel(NULL), - m_pLinkCtrlTreeModel(NULL), - m_linkCtrlDataManage(NULL), - m_linkCtrlStateManage(NULL), - m_userInterveneRequestDialog(NULL), - m_historyLinkModel(NULL), - m_historyActionModel(NULL), - m_linkDBInterface(NULL) -{ - ui->setupUi(this); - if(!editMode) - { - qRegisterMetaType("E_LINK_OPERATETYPE"); - qRegisterMetaType >("LISTLINKCTRL"); - qRegisterMetaType("kbd_idlfile::linkage::UiRequestMessage"); - initialize(); - } - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("linkCtrl.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - -} - -CLinkCtrlWidget::~CLinkCtrlWidget() -{ - emit sigClearSubscribe(); - - if(m_linkDBInterface) - { - //m_linkDBInterface->slotUnSubScribeLinkList(); - delete m_linkDBInterface; - } - m_linkDBInterface = NULL; - - if(m_historyLinkModel) - { - delete m_historyLinkModel; - } - m_historyLinkModel = NULL; - - if(m_historyActionModel) - { - delete m_historyActionModel; - } - m_historyActionModel = NULL; - - if(m_permTimer) - { - m_permTimer->stop(); - delete m_permTimer; - } - m_permTimer = NULL; - - if(m_linkCtrlStateManage) - { - delete m_linkCtrlStateManage; - } - m_linkCtrlStateManage = NULL; - - if(m_linkCtrlDataManage) - { - delete m_linkCtrlDataManage; - } - m_linkCtrlDataManage = NULL; - - delete ui; - - qDebug() << "~CLinkCtrlWidget()"; -} - -void CLinkCtrlWidget::initialize() -{ - m_linkDBInterface = new CLinkDBInterface(); - m_historyLinkModel = new CHistoryLinkModel(this); - m_historyActionModel = new CHistoryActionModel(this); - - m_linkCtrlStateManage = new CLinkCtrlStateManage(); - m_linkCtrlDataManage = new CLinkCtrlDataManage(); - m_linkCtrlList = m_linkCtrlDataManage->queryLinkCtrlList(); - connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigRequestLinkOperationFail, this, &CLinkCtrlWidget::slotRequestLinkOperationFail, Qt::QueuedConnection); - connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigLinkAgeStart, this, &CLinkCtrlWidget::slotLinkAgeStart, Qt::QueuedConnection); - connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigUpdateLinkAgeState, this, &CLinkCtrlWidget::slotUpdateLinkAgeState, Qt::QueuedConnection); - connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigUpdateFunctionState, this, &CLinkCtrlWidget::slotUpdateFunctionState, Qt::QueuedConnection); - connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigUpdateActionState, this, &CLinkCtrlWidget::slotUpdateActionState, Qt::QueuedConnection); - connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigRecvLinkUserInterveneRequest, this, &CLinkCtrlWidget::slotRecvLinkUserInterveneRequest, Qt::QueuedConnection); - connect(m_linkCtrlStateManage, &CLinkCtrlStateManage::sigUpdateLinkAgeState, this, &CLinkCtrlWidget::slotUpdateLinkAgeState, Qt::QueuedConnection); - connect(m_linkCtrlStateManage, &CLinkCtrlStateManage::sigUpdateFunctionState, this, &CLinkCtrlWidget::slotUpdateFunctionState, Qt::QueuedConnection); - connect(m_linkCtrlStateManage, &CLinkCtrlStateManage::sigUpdateActionState, this, &CLinkCtrlWidget::slotUpdateActionState, Qt::QueuedConnection); - connect(this, &CLinkCtrlWidget::sigSubscribeLinkCtrlList, m_linkCtrlStateManage, &CLinkCtrlStateManage::subscribeLinkCtrlList, Qt::QueuedConnection); - connect(this, &CLinkCtrlWidget::sigClearSubscribe, m_linkCtrlStateManage, &CLinkCtrlStateManage::clearSubscribe, Qt::QueuedConnection); - - m_pLinkCtrlTableModel = new CLinkCtrlTableModel(this); - ui->linkCtrlTableView->setModel(m_pLinkCtrlTableModel); - ui->linkCtrlTableView->setColumnWidth(0, 300); - ui->linkCtrlTableView->setColumnWidth(1, 150); - ui->linkCtrlTableView->setColumnWidth(2, 150); - - m_pLinkCtrlTreeModel = new CLinkCtrlTreeModel(this); - ui->actionTreeView->setModel(m_pLinkCtrlTreeModel); - ui->actionTreeView->setColumnWidth(0, 300); - ui->actionTreeView->setColumnWidth(1, 150); - ui->actionTreeView->setColumnWidth(2, 150); - ui->actionTreeView->setHeaderHidden(false); - - //2020-6-15 modifi linkage type by read configuretion file - if(readLinkTypeDescXml()==kbdSuccess) - { - QStringList linkTypeList; - for(int index=0;index < (int)m_linkTypeStr.size(); index++) - { - QListWidgetItem *item = new QListWidgetItem; - item->setText(QString::fromStdString(m_linkTypeStr[std::to_string(index)])); - item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - ui->linkCtrlList->addItem(item); - - QString str = QString::fromStdString(m_linkTypeStr[std::to_string(index)]); - linkTypeList.append(str); - - } - m_pLinkCtrlTableModel->setLinkTypeList(linkTypeList); - m_historyLinkModel->setLinkTypeList(linkTypeList); - } - - connect(ui->linkCtrlList, &QListWidget::itemClicked, this, &CLinkCtrlWidget::updateRunLink); - - //2020-6-10 add link report - m_linkDBInterface->initDataBase(); - connect(ui->linkReportList, &QListWidget::itemClicked, this, &CLinkCtrlWidget::updateReportLink); - //< 联动报告界面 - ui->historyLinkView->setModel(m_historyLinkModel); - ui->historyLinkView->setColumnWidth(History_Link_Column::timeColumn, 150); - ui->exportLink->setVisible(false); - ui->printLink->setVisible(false); - - ui->historyActionView->setModel(m_historyActionModel); - ui->historyActionView->setHeaderHidden(false); - connect(ui->historyLinkView, &QTableView::clicked, this, &CLinkCtrlWidget::updateHistoryActionData); - ui->historyActionView->setColumnWidth(History_Action_Column::nameColumn, 180); - ui->historyActionView->setColumnWidth(History_Action_Column::descriptColumn, 250); - connect(ui->historyFilter, &QPushButton::clicked, this, &CLinkCtrlWidget::filterHistoryLink); - connect(ui->printLink, &QPushButton::clicked, this, &CLinkCtrlWidget::print); - - - - connect(ui->allLinkCtrlButton, &QPushButton::clicked, this, &CLinkCtrlWidget::slotUpdateLinkCtrlList); - connect(ui->waitForExceLinkCtrlButton, &QPushButton::clicked, this, &CLinkCtrlWidget::slotUpdateLinkCtrlList); - connect(ui->searchButton, &QPushButton::clicked, this, &CLinkCtrlWidget::slotUpdateLinkCtrlTableView); - //connect(ui->linkCtrlList, &QListWidget::itemSelectionChanged, this, &CLinkCtrlWidget::slotUpdateLinkCtrlTableView); - connect(ui->linkCtrlTableView, &QTableView::clicked, this, &CLinkCtrlWidget::slotUpdateLinkOperateEnable); - connect(ui->linkCtrlTableView, &QTableView::clicked, this, &CLinkCtrlWidget::slotUpdateLinkCtrlActionTreeView); - connect(ui->excution, &QPushButton::clicked, this, &CLinkCtrlWidget::slotExecution); - connect(ui->single, &QPushButton::clicked, this, &CLinkCtrlWidget::slotSingleStep); - connect(ui->pause, &QPushButton::clicked, this, &CLinkCtrlWidget::slotPause); - connect(ui->termination, &QPushButton::clicked, this, &CLinkCtrlWidget::slotTermination); - connect(m_pLinkCtrlTableModel, &CLinkCtrlTableModel::sigRowCountChanged, this, &CLinkCtrlWidget::slotUpdateLinkCtrlTableViewSelect); - connect(m_pLinkCtrlTreeModel, &CLinkCtrlTreeModel::itemCheckStateChanged, this, &CLinkCtrlWidget::slotLinkCtrlCheckStateChanged); - ui->linkCtrlList->setCurrentRow(0); - updateRunLink(); //初始化执行一次 - ui->pause->setEnabled(false); - ui->termination->setEnabled(false); - m_permTimer = new QTimer(); - m_permTimer->setInterval(1000); - connect(m_permTimer, &QTimer::timeout, this, &CLinkCtrlWidget::updatePerm); - m_permTimer->start(); - -} - -void CLinkCtrlWidget::login() -{ - -} - -void CLinkCtrlWidget::logout() -{ - -} - -bool CLinkCtrlWidget::getLinkCtrlPerm() -{ - //<权限处理 - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::string tmp = FUNC_NOM_LINK_CTRL; - if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) - { - return true; - } - } - return false; -} - -void CLinkCtrlWidget::slotExecution() -{ - if(!getLinkCtrlPerm()) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备联动操作权限!")); - msgBox.exec(); - return; - } - - QModelIndex index = ui->linkCtrlTableView->currentIndex(); - if(!index.isValid()) - { - QMessageBox::warning(NULL, tr("错误"), tr("当前未选中联动")); - return; - } - index = index.sibling(index.row(), 0); - QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); - - kbd_public::CSysInfoInterfacePtr spSysInfo; - kbd_public::SLocationInfo stLocationInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - foreach (S_LINKCTRL_INFO info, m_linkCtrlList) - { - if(info.linkageName == strLinkAgeName) - { - quint64 timeFlag = info.timeFlag; - E_LCS_STATUS nodeState = (E_LCS_STATUS)info.status; - QList nodeList = m_linkFunctionTree; - spSysInfo->getLocationInfoById(info.locationID, stLocationInfo); - m_linkCtrlDataManage->requestLinkOperation(stLocationInfo.nDomainId, strLinkAgeName, timeFlag, nodeState, nodeList, E_LINK_START); - break; - } - } - } -} - -void CLinkCtrlWidget::slotSingleStep() -{ - if(!getLinkCtrlPerm()) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备联动操作权限!")); - msgBox.exec(); - return; - } - - QModelIndex index = ui->linkCtrlTableView->currentIndex(); - if (!index.isValid()) - { - QMessageBox::warning(NULL, tr("错误"), tr("当前未选中联动")); - return; - } - E_LINK_OPERATETYPE type = E_SES_START; - if (!ui->excution->isEnabled()) - { - type = E_SES_CONTINUE; - } - index = index.sibling(index.row(), 0); - QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); - - kbd_public::CSysInfoInterfacePtr spSysInfo; - kbd_public::SLocationInfo stLocationInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - foreach(S_LINKCTRL_INFO info, m_linkCtrlList) - { - if (info.linkageName == strLinkAgeName) - { - quint64 timeFlag = info.timeFlag; - E_LCS_STATUS nodeState = (E_LCS_STATUS)info.status; - QList nodeList = m_linkFunctionTree; - spSysInfo->getLocationInfoById(info.locationID, stLocationInfo); - m_linkCtrlDataManage->requestLinkOperation(stLocationInfo.nDomainId, strLinkAgeName, timeFlag, nodeState, nodeList, type); - break; - } - } - } -} - -void CLinkCtrlWidget::slotPause() -{ - if(!getLinkCtrlPerm()) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备联动操作权限!")); - msgBox.exec(); - return; - } - - QModelIndex index = ui->linkCtrlTableView->currentIndex(); - if (!index.isValid()) - { - QMessageBox::warning(NULL, tr("错误"), tr("当前未选中联动")); - return; - } - E_LINK_OPERATETYPE type = E_LINK_PAUSE; - if (ui->pause->text() == tr("继续")) - { - type = E_LINK_CONTINUE; - } - - index = index.sibling(index.row(), 0); - QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); - - kbd_public::CSysInfoInterfacePtr spSysInfo; - kbd_public::SLocationInfo stLocationInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - foreach(S_LINKCTRL_INFO info, m_linkCtrlList) - { - if (info.linkageName == strLinkAgeName) - { - quint64 timeFlag = info.timeFlag; - E_LCS_STATUS nodeState = (E_LCS_STATUS)info.status; - QList nodeList = m_linkFunctionTree; - spSysInfo->getLocationInfoById(info.locationID, stLocationInfo); - m_linkCtrlDataManage->requestLinkOperation(stLocationInfo.nDomainId, strLinkAgeName, timeFlag, nodeState, nodeList, type); - break; - } - } - } -} - -void CLinkCtrlWidget::slotTermination() -{ - if(!getLinkCtrlPerm()) - { - QMessageBox msgBox; - msgBox.setText(tr("当前用户不具备联动操作权限!")); - msgBox.exec(); - return; - } - - ui->linkCtrlTableView->setFocus(); - QModelIndex index = ui->linkCtrlTableView->currentIndex(); - if (!index.isValid()) - { - QMessageBox::warning(NULL, tr("错误"), tr("当前未选中联动")); - return; - } - index = index.sibling(index.row(), 0); - QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); - - kbd_public::CSysInfoInterfacePtr spSysInfo; - kbd_public::SLocationInfo stLocationInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - foreach(S_LINKCTRL_INFO info, m_linkCtrlList) - { - if (info.linkageName == strLinkAgeName) - { - quint64 timeFlag = info.timeFlag; - E_LCS_STATUS nodeState = (E_LCS_STATUS)info.status; - QList nodeList = m_linkFunctionTree; - spSysInfo->getLocationInfoById(info.locationID, stLocationInfo); - m_linkCtrlDataManage->requestLinkOperation(stLocationInfo.nDomainId, strLinkAgeName, timeFlag, nodeState, nodeList, E_LINK_STOP); - break; - } - } - } -} - -void CLinkCtrlWidget::slotUpdateLinkCtrlList() -{ - m_linkCtrlList = m_linkCtrlDataManage->queryLinkCtrlList(); - slotUpdateLinkCtrlTableView(); -} - -void CLinkCtrlWidget::slotUpdateLinkOperateEnable(const QModelIndex &index) -{ - if (!index.isValid()) - { - return; - } - if (E_RUNNING_STATUS == (E_LCS_STATUS)m_pLinkCtrlTableModel->value(index.sibling(index.row(), 2)).toInt()) - { - updateUiButtonState(E_RESTING_STATUS); - } -} - -void CLinkCtrlWidget::slotUpdateLinkCtrlTableView() -{ - if(dynamic_cast(sender())) - { - m_linkCtrlList = m_linkCtrlDataManage->queryLinkCtrlList(); - } - - QList linkCtrlList = m_linkCtrlList; - - //<待执行联动 - bool bIsWaitForExcute = ui->waitForExceLinkCtrlButton->isChecked(); - - //<联动类型过滤 - int nLinkCtrlType = ui->linkCtrlList->currentRow(); - - //<关键词 - QString strKeyWord = ui->searchLineEdit->text(); - - - QList::iterator iter = linkCtrlList.begin(); - while (iter != linkCtrlList.end()) - { - //Filter - if(bIsWaitForExcute) - { - if(E_Exec_Semi_Auto != (*iter).exeType || E_TRIGGERED_STATUS != (*iter).status) - { - iter = linkCtrlList.erase(iter); - continue; - } - } - - if((*iter).linkType != nLinkCtrlType) - { - iter = linkCtrlList.erase(iter); - continue; - } - if(!strKeyWord.isEmpty()) - { - if(!(*iter).linkageDescription.contains(strKeyWord)) - { - iter = linkCtrlList.erase(iter); - continue; - } - } - iter++; - } - m_pLinkCtrlTableModel->reset(); - m_pLinkCtrlTreeModel->reset(); - m_pLinkCtrlTableModel->updateModelData(linkCtrlList); - if(!linkCtrlList.isEmpty()) - { - ui->linkCtrlTableView->selectRow(0); - slotUpdateLinkOperateEnable(ui->linkCtrlTableView->currentIndex()); - } - -// ui->linkCtrlTableView->setFocus(); - slotUpdateLinkCtrlActionTreeView(); -} - -void CLinkCtrlWidget::slotUpdateLinkCtrlActionTreeView() -{ - emit sigClearSubscribe(); - - ui->excution->setEnabled(false); - ui->single->setEnabled(false); - ui->pause->setText(tr("暂停")); - ui->pause->setEnabled(false); - ui->termination->setEnabled(false); - - QModelIndex index = ui->linkCtrlTableView->currentIndex(); - if(!index.isValid()) - { - return; - } - index = index.sibling(index.row(), 0); - QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); - - m_linkFunctionTree = m_linkCtrlDataManage->queryLinkFunctionList(strLinkAgeName); - - m_pLinkCtrlTreeModel->updateModelData(m_linkFunctionTree); - - for(int nIndex(0); nIndex < m_linkFunctionTree.size(); nIndex++) - { - QModelIndex modelIndex = m_pLinkCtrlTreeModel->index(nIndex, 0); - ui->actionTreeView->expand(modelIndex); - } - ui->actionTreeView->setColumnWidth(1, 40); - ui->actionTreeView->setColumnWidth(2, 80); - emit sigSubscribeLinkCtrlList(m_linkCtrlList); - emit sigSubscribeLinkCtrlList(m_linkFunctionTree); -} - -void CLinkCtrlWidget::slotUpdateLinkCtrlTableViewSelect() -{ - if (1 == m_pLinkCtrlTableModel->rowCount()) - { - ui->linkCtrlTableView->selectRow(0); - slotUpdateLinkCtrlActionTreeView(); - } -} - -void CLinkCtrlWidget::slotLinkCtrlCheckStateChanged(const QString functionName, const QString actionName, const int checkedState) -{ - QModelIndex index = ui->linkCtrlTableView->currentIndex(); - if (!index.isValid()) - { - return; - } - index = index.sibling(index.row(), 0); - for (int nIndex(0); nIndex < m_linkFunctionTree.size(); nIndex++) - { - if (m_linkFunctionTree[nIndex].funcName == functionName && m_linkFunctionTree[nIndex].actionName == actionName) - { - m_linkFunctionTree[nIndex].checked = checkedState; - break; - } - } -} - -void CLinkCtrlWidget::slotRequestLinkOperationFail(const QString &strLinkDescription, const E_LINK_OPERATETYPE &type, const int &nErrorCode, const QString &strErrorCode) -{ - Q_UNUSED(type) - QString content = QString("%1%2\n%3%4\n%5%6\n").arg(tr("联动名称: ")).arg(strLinkDescription).arg(tr("错误代码: ")).arg(nErrorCode).arg(tr("错误描述: ")).arg(strErrorCode); - QMessageBox::warning(NULL, tr("联动操作请求失败"), content); - if (m_pLinkCtrlTableModel->contains(strLinkDescription)) - { - updateUiButtonState(E_RESTING_STATUS); - } -} - - -void CLinkCtrlWidget::slotRecvLinkUserInterveneRequest(UiRequestMessage *msg) -{ - if(!getLinkCtrlPerm()) - { - return; - } - handleUserInterveneRequest(*msg); - delete msg; -} - -void CLinkCtrlWidget::handleUserInterveneRequest(UiRequestMessage &msg) -{ - if (m_userInterveneRequestDialog ) - { - return; - } - - LinkNodeStatusParameter * linkNodeParameter = msg.mutable_nodelist(); - QString strLinkName = QString::fromStdString(linkNodeParameter->link_desc()); - QString strErrorMessage; - if (!msg.mutable_execute_status()->statuscode()) - { - ErrorParameter * pErrorParameter = msg.mutable_execute_status()->mutable_erro_param(); - strErrorMessage = QString::fromStdString(pErrorParameter->errordescription()); - } - if (strErrorMessage.isEmpty()) - { - strErrorMessage = tr("执行失败,请求人工干预!"); - } - - QString strFunctionName; - QString strActionName; - if (linkNodeParameter->nodelist_size() > 0) - { - for (int nFunctionIndex(0); nFunctionIndex < linkNodeParameter->nodelist_size(); nFunctionIndex++) - { - FucNodeStatusParameter fucNodeStatusParameter = linkNodeParameter->nodelist(nFunctionIndex); - strFunctionName = QString::fromStdString(fucNodeStatusParameter.fuc_desc()); - if (fucNodeStatusParameter.nodelist_size() > 0) - { - for (int nActionndex(0); nActionndex < linkNodeParameter->nodelist_size(); nActionndex++) - { - ActionNodeStatusParameter actionNodeStatusParameter = fucNodeStatusParameter.nodelist(nActionndex); - strActionName = QString::fromStdString(actionNodeStatusParameter.action_desc()); - break; - } - break; - } - } - } - - QString content = QString("%1%2\n%3%4\n%5%6\n\n%7").arg(tr("联动名称: ")). - arg(strLinkName).arg(tr("功能名称: ")).arg(strFunctionName).arg(tr("动作名称: ")).arg(strActionName).arg(strErrorMessage); - m_userInterveneRequestDialog = new QMessageBox(QMessageBox::Question, tr("人工干预请求"), content, QMessageBox::NoButton, this); - E_UIOPERATE_TYPE type; - - if(m_userInterveneRequestDialog != NULL) - { - QAbstractButton * retry = m_userInterveneRequestDialog->addButton(tr("重试"), QMessageBox::AcceptRole); - QAbstractButton * stop = m_userInterveneRequestDialog->addButton(tr("终止"), QMessageBox::RejectRole); - QAbstractButton * skip = m_userInterveneRequestDialog->addButton(tr("跳过"), QMessageBox::NoRole); - m_userInterveneRequestDialog->exec(); - if (m_userInterveneRequestDialog->clickedButton() == retry) - { - type = E_OP_RETRY; - } - else if (m_userInterveneRequestDialog->clickedButton() == stop) - { - type = E_OP_STOP; - } - else if (m_userInterveneRequestDialog->clickedButton() == skip) - { - type = E_OP_SKIP; - } - delete m_userInterveneRequestDialog; - m_userInterveneRequestDialog = NULL; - - } - - kbd_idlfile::linkage::UiRequestMessageAck msgAck; - if(!buildUserInterveneReplyMsg(msg, type, msgAck)) - { - return; - } - m_linkCtrlDataManage->replyUserInterveneRequest(msgAck); -} - -void CLinkCtrlWidget::slotLinkAgeStart(const QString &strLinkName, const int &state, const quint64 &triggerTime) -{ - for (int nIndex(0); nIndex < m_linkCtrlList.size(); nIndex++) - { - if (strLinkName == m_linkCtrlList[nIndex].linkageName && 0 == m_linkCtrlList[nIndex].nodeType) - { - m_linkCtrlList[nIndex].status = state; - m_linkCtrlList[nIndex].triggerTime = triggerTime; - } - } - if (m_pLinkCtrlTableModel->contains(strLinkName)) - { - m_pLinkCtrlTableModel->updateLinkAgeState(strLinkName, state, triggerTime); - } - else - { - foreach(S_LINKCTRL_INFO info, m_linkCtrlList) - { - if (info.linkageName == strLinkName) - { - bool bIsWaitForExcute = ui->waitForExceLinkCtrlButton->isChecked(); - int nLinkCtrlType = ui->linkCtrlList->currentRow(); - QString strKeyWord = ui->searchLineEdit->text(); - if (bIsWaitForExcute) - { - if (E_Exec_Semi_Auto != info.exeType || E_TRIGGERED_STATUS != info.status) - { - return; - } - } - if (info.linkType != nLinkCtrlType) - { - return; - } - if (!strKeyWord.isEmpty()) - { - if (!info.linkageName.contains(strKeyWord)) - { - return; - } - } - m_pLinkCtrlTableModel->insertLinkAge(info); - } - } - } - -} - -void CLinkCtrlWidget::slotUpdateLinkAgeState( const QString &strLinkName, int state, - quint64 triggerTime, quint64 timeFlag ) -{ - for ( int nIndex( 0 ); nIndex < m_linkCtrlList.size(); nIndex++ ) - { - if ( strLinkName == m_linkCtrlList[nIndex].linkageName && E_Node_LinkCtrl == m_linkCtrlList[nIndex].nodeType ) - { - //< 配置已发生修改 - if ( timeFlag != m_linkCtrlList[nIndex].timeFlag ) - state = E_INVALID_STATUS; - - if ( triggerTime > 0 ) - m_linkCtrlList[nIndex].triggerTime = triggerTime; - - m_linkCtrlList[nIndex].status = state; - } - } - - QModelIndex modelIndex = ui->linkCtrlTableView->currentIndex(). - sibling( ui->linkCtrlTableView->currentIndex().row(), 0 ); - if ( strLinkName == m_pLinkCtrlTableModel->value( modelIndex ).toString()) - { - updateUiButtonState(( E_LCS_STATUS ) state ); - } - m_pLinkCtrlTableModel->updateLinkAgeState( strLinkName, state, triggerTime ); -} - -void CLinkCtrlWidget::slotUpdateFunctionState(const QString &strLinkName, const QString &strFunctionName, const int &state) -{ - m_pLinkCtrlTreeModel->updateFunctionState(strFunctionName, state); - for (int nIndex(0); nIndex < m_linkFunctionTree.size(); nIndex++) - { - if (strLinkName == m_linkFunctionTree[nIndex].linkageName && strFunctionName == m_linkFunctionTree[nIndex].funcName && E_Node_Function == m_linkFunctionTree[nIndex].nodeType) - { - m_linkFunctionTree[nIndex].status = state; - } - } -} - -void CLinkCtrlWidget::slotUpdateActionState(const QString &strLinkName, const QString &strFunctionName, const QString &strActionName, const int &state) -{ - m_pLinkCtrlTreeModel->updateActionState(strFunctionName, strActionName, state); - for (int nIndex(0); nIndex < m_linkFunctionTree.size(); nIndex++) - { - if (strLinkName == m_linkFunctionTree[nIndex].linkageName && strFunctionName == m_linkFunctionTree[nIndex].funcName && strActionName == m_linkFunctionTree[nIndex].actionName && E_Node_Action == m_linkFunctionTree[nIndex].nodeType) - { - m_linkFunctionTree[nIndex].status = state; - } - } -} - -void CLinkCtrlWidget::updatePerm() -{ - bool isPerm = getLinkCtrlPerm(); - ui->excution->setVisible(isPerm); - ui->single->setVisible(isPerm); - ui->pause->setVisible(isPerm); - ui->termination->setVisible(isPerm); -} - -//2020-6-10 -void CLinkCtrlWidget::updateRunLink() -{ - ui->stackedWidget->setCurrentIndex(0); - slotUpdateLinkCtrlTableView(); - -} - -void CLinkCtrlWidget::updateReportLink() -{ - ui->stackedWidget->setCurrentIndex(1); - loadLinkReport(); -} - - -void CLinkCtrlWidget::updateUiButtonState(const E_LCS_STATUS type) -{ - switch (type) - { - case E_RESTING_STATUS: //<未执行 - { - ui->excution->setEnabled(true); - ui->single->setEnabled(true); - ui->pause->setEnabled(false); - ui->pause->setText(tr("暂停")); - ui->termination->setEnabled(false); - break; - } - case E_RUNNING_STATUS: //<正在执行 - { - ui->excution->setEnabled(false); - ui->single->setEnabled(false); - ui->pause->setEnabled(true); - ui->pause->setText(tr("暂停")); - ui->termination->setEnabled(true); - break; - } - case E_FAILED_STATUS: //<执行失败 - case E_SUCCESS_STATUS: //<执行成功 - case E_STOP_STATUS: //<执行终止 - { - ui->excution->setEnabled(false); - ui->single->setEnabled(false); - ui->pause->setEnabled(false); - ui->pause->setText(tr("暂停")); - ui->termination->setEnabled(false); - break; - } - case E_PAUSE_STATUS: //<执行暂停 - { - ui->excution->setEnabled(false); - ui->single->setEnabled(false); - ui->pause->setEnabled(true); - ui->pause->setText(tr("继续")); - ui->termination->setEnabled(true); - break; - } - case E_TRIGGERED_STATUS: //已触发 - { - ui->excution->setEnabled(true); - ui->single->setEnabled(true); - ui->pause->setEnabled(false); - ui->pause->setText(tr("暂停")); - ui->termination->setEnabled(true); - break; - } - case E_INVALID_STATUS: //时标不一致 - { - ui->excution->setEnabled(false); - ui->single->setEnabled(false); - ui->pause->setEnabled(false); - ui->pause->setText(tr("继续")); - ui->termination->setEnabled(true); - break; - } - default: - { - ui->excution->setEnabled(false); - ui->single->setEnabled(false); - ui->pause->setText(tr("暂停")); - ui->pause->setEnabled(false); - ui->termination->setEnabled(false); - break; - } - } -} - -bool CLinkCtrlWidget::buildUserInterveneReplyMsg(const kbd_idlfile::linkage::UiRequestMessage &sourceMsg, const E_UIOPERATE_TYPE &type, UiRequestMessageAck &msgAck) -{ - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - spSysInfo->getLocalNodeInfo(stNodeInfo); - } - else - { - LOGERROR("构建人工干预回复消息错误 [创建系统信息访问库实例失败]!"); - return false; - } - - int nUserId = -1; - int nUserGrpId = -1; - std::string strUserName = ""; - int nLevel = -1; - int nLoginSec = -1; - std::string strInstanceName = ""; - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - if(0 == permMngPtr->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - permMngPtr->GetUserNameByUserId(nUserId, strUserName); - } - else - { - LOGERROR("构建人工干预回复消息错误[权限获取失败]!"); - return false; - } - } - else - { - LOGERROR("构建人工干预回复消息错误[创建权限闭锁参数访问接口实例]!"); - return false; - } - - LcsPkgHead * head = new LcsPkgHead(); - head->set_source_tag("hmi"); - head->set_msg_type((enLcsMsgType)E_LinkOperate_Message); - head->set_source_domain(stNodeInfo.nDomainId); - head->set_target_domain(sourceMsg.pkg_head().source_domain()); - head->set_para1(sourceMsg.pkg_head().para1()); - head->set_para2(sourceMsg.pkg_head().para2()); - msgAck.set_allocated_pkg_head(head); - - LinkNodeStatusParameter * linkNodeParameter = new LinkNodeStatusParameter(); - *linkNodeParameter = sourceMsg.nodelist(); - msgAck.set_allocated_nodelist(linkNodeParameter); - - ActorParameter * actorParameter = new ActorParameter(); - actorParameter->set_user_id(nUserId); - actorParameter->set_user_groupid(nUserGrpId); - actorParameter->set_host_name(stNodeInfo.strName); - actorParameter->set_user_name(strUserName); - msgAck.set_allocated_actor(actorParameter); - - msgAck.set_optype((ENUiOperateType)type); - return true; -} - -/*********************************Report UI CONFIG BEGIN*************************************/ -void CLinkCtrlWidget::loadLinkReport() -{ - QDateTime end = QDateTime::currentDateTime(); - end.setTimeSpec(Qt::UTC); - QDateTime start = end.addDays(-30); - m_listHistroyLink = m_linkDBInterface->queryHistoryLinkNodeList(start, end); - QList::iterator it = m_listHistroyLink.begin(); - while (it != m_listHistroyLink.end()) - { - if(m_historyCondition.locationFilter) - { - if(!m_historyCondition.locationList.contains(it->location)) - { - it = m_listHistroyLink.erase(it); - continue; - } - } - if(m_historyCondition.userFilter) - { - if(!m_historyCondition.userList.contains(it->userName)) - { - it = m_listHistroyLink.erase(it); - continue; - } - } - if(m_historyCondition.resultFilter) - { - if(!m_historyCondition.resultList.contains(it->status)) - { - it = m_listHistroyLink.erase(it); - continue; - } - } - if(m_historyCondition.typeFilter) - { - if((m_historyCondition.isStandardType && 0 != it->linkType) || (!m_historyCondition.isStandardType && 1 != it->linkType)) - { - it = m_listHistroyLink.erase(it); - continue; - } - } - - if(m_historyCondition.timeFilter) - { - QDateTime time = QDateTime::fromSecsSinceEpoch(it->time); - if(m_historyCondition.startTime > time || m_historyCondition.endTime < time) - { - it = m_listHistroyLink.erase(it); - continue; - } - } - it++; - } - m_historyLinkModel->setHistoryLinkData(m_listHistroyLink); - if(!m_listHistroyLink.isEmpty()) - { - ui->historyLinkView->selectRow(0); - updateHistoryActionData(); - } - else - { - QList listFunctionHistory; - m_historyActionModel->updateModelFunctionData(listFunctionHistory); - } -} - -void CLinkCtrlWidget::updateHistoryActionData() -{ - QModelIndex modelIndex = ui->historyLinkView->currentIndex(); - - QString currentLinkName = m_historyLinkModel->LinkName(modelIndex); - quint64 currentLinkTime = m_historyLinkModel->LinkTime(modelIndex); - QList listFunctionHistory = m_linkDBInterface->queryHistoryFunctionNodeList(currentLinkName, currentLinkTime); - QList listActionHistory; - foreach (FunctionHistory funcHistory, listFunctionHistory) - { - listActionHistory.append(m_linkDBInterface->queryHistoryActionNodeList(funcHistory.linkName, funcHistory.funcName, funcHistory.time)); - } - m_historyActionModel->updateModelFunctionData(listFunctionHistory); - m_historyActionModel->updateModelActionData(listActionHistory); - ui->historyActionView->expandAll(); -} - -int CLinkCtrlWidget::readLinkTypeDescXml() -{ - std::string linkTypeStr; - - //< 读取LINKAGE_SETTING配置文件,获取联动类型 - std::string path = kbd_public::CFileUtil::getPathOfResFile("model_studio/setting/table/LINKAGE_SETTING.xml"); - if(readXml(path,linkTypeStr)==kbdFailed) - { - LOGERROR("readLinkTypeDescXml load [zh] LINKAGE_SETTING.xml error"); - return kbdFailed; - } - - std::vector destination; - boost::split( destination, linkTypeStr, boost::is_any_of( "/" ), boost::token_compress_on ); - std::vector::iterator it ; - for( it= destination.begin(); it != destination.end(); ++ it ) - { - std::vector destination2; - destination2.clear(); - boost::split( destination2, *it, boost::is_any_of( ":" ), boost::token_compress_on ); - m_linkTypeStr.insert(std::pair(destination2.at(0), destination2.at(1))); - - } - return kbdSuccess; -} - -int CLinkCtrlWidget::readXml(std::string fileName,std::string &strValue) -{ - ptree pt; - namespace xml = boost::property_tree::xml_parser; - - strValue = "LINK_TYPE"; - try - { - xml::read_xml(fileName, pt); //第三个参数不填默认为0 - BOOST_AUTO(module, pt.get_child("Table")); - - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - - if(pModuleIter->first == "COLS") - { - ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - - if (pParamIter->first == "COL") - { - std::string strKey = pParamIter->second.get(".SQLName"); - if(strKey == "LINK_TYPE") - strValue = pParamIter->second.get(".valueLimit"); - } - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg = [%s]", fileName.c_str(),ex.what()); - return kbdFailed; - } - - if(strValue == "LINK_TYPE") - { - LOGERROR("获取联动类型值失败!"); - return kbdFailed; - } - return kbdSuccess; -} - -void CLinkCtrlWidget::filterHistoryLink() -{ - QStringList locationList = m_linkDBInterface->queryAllLocationName(); - QStringList userNameList = m_linkDBInterface->queryUserIDMap().values(); - CHistoryLinkFilterDialog linkFilterDlg(locationList, userNameList, this); - linkFilterDlg.initialize(m_historyCondition); - if(QDialog::Accepted != linkFilterDlg.exec()) - { - return; - } - - m_historyCondition = linkFilterDlg.LinkFilterCondition(); - loadLinkReport(); -} - -void CLinkCtrlWidget::print() -{ - QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); - if(!fileName.isEmpty()) - { - QTableView view(ui->historyLinkView); - view.setModel(ui->historyLinkView->model()); - view.horizontalHeader()->resizeSection(2, 250); - - QPrinter printer; - printer.setPageSize(QPagedPaintDevice::A4); - printer.setPageOrientation(QPageLayout::Landscape); - - printer.setOutputFileName(fileName); - printer.setOutputFormat(QPrinter::PdfFormat); - - CTableViewPrinter viewPrinter(&view); - viewPrinter.print(&printer); - } -} -/*********************************Report UI CONFIG END*************************************/ +#include "CLinkCtrlWidget.h" +#include "ui_CLinkCtrlWidget.h" +#include "CLinkCtrlDataManage.h" +#include "CLinkCtrlStateManage.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include +#include +#include +#include +#include +#include +#include "CLinkDBInterface.h" +#include "CHistoryLinkModel.h" +#include "CHistoryActionModel.h" +#include "CTableViewPrinter.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/FileStyle.h" +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include +#include + + +using namespace kbd_public; +using namespace kbd_dbms; +using namespace kbd_idlfile::linkage; +using boost::property_tree::ptree; +using namespace std; + +CLinkCtrlWidget::CLinkCtrlWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CLinkCtrlWidget), + m_permTimer(NULL), + m_pLinkCtrlTableModel(NULL), + m_pLinkCtrlTreeModel(NULL), + m_linkCtrlDataManage(NULL), + m_linkCtrlStateManage(NULL), + m_userInterveneRequestDialog(NULL), + m_historyLinkModel(NULL), + m_historyActionModel(NULL), + m_linkDBInterface(NULL) +{ + ui->setupUi(this); + if(!editMode) + { + qRegisterMetaType("E_LINK_OPERATETYPE"); + qRegisterMetaType >("LISTLINKCTRL"); + qRegisterMetaType("kbd_idlfile::linkage::UiRequestMessage"); + initialize(); + } + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("linkCtrl.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + +} + +CLinkCtrlWidget::~CLinkCtrlWidget() +{ + emit sigClearSubscribe(); + + if(m_linkDBInterface) + { + //m_linkDBInterface->slotUnSubScribeLinkList(); + delete m_linkDBInterface; + } + m_linkDBInterface = NULL; + + if(m_historyLinkModel) + { + delete m_historyLinkModel; + } + m_historyLinkModel = NULL; + + if(m_historyActionModel) + { + delete m_historyActionModel; + } + m_historyActionModel = NULL; + + if(m_permTimer) + { + m_permTimer->stop(); + delete m_permTimer; + } + m_permTimer = NULL; + + if(m_linkCtrlStateManage) + { + delete m_linkCtrlStateManage; + } + m_linkCtrlStateManage = NULL; + + if(m_linkCtrlDataManage) + { + delete m_linkCtrlDataManage; + } + m_linkCtrlDataManage = NULL; + + delete ui; + + qDebug() << "~CLinkCtrlWidget()"; +} + +void CLinkCtrlWidget::initialize() +{ + m_linkDBInterface = new CLinkDBInterface(); + m_historyLinkModel = new CHistoryLinkModel(this); + m_historyActionModel = new CHistoryActionModel(this); + + m_linkCtrlStateManage = new CLinkCtrlStateManage(); + m_linkCtrlDataManage = new CLinkCtrlDataManage(); + m_linkCtrlList = m_linkCtrlDataManage->queryLinkCtrlList(); + connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigRequestLinkOperationFail, this, &CLinkCtrlWidget::slotRequestLinkOperationFail, Qt::QueuedConnection); + connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigLinkAgeStart, this, &CLinkCtrlWidget::slotLinkAgeStart, Qt::QueuedConnection); + connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigUpdateLinkAgeState, this, &CLinkCtrlWidget::slotUpdateLinkAgeState, Qt::QueuedConnection); + connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigUpdateFunctionState, this, &CLinkCtrlWidget::slotUpdateFunctionState, Qt::QueuedConnection); + connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigUpdateActionState, this, &CLinkCtrlWidget::slotUpdateActionState, Qt::QueuedConnection); + connect(m_linkCtrlDataManage, &CLinkCtrlDataManage::sigRecvLinkUserInterveneRequest, this, &CLinkCtrlWidget::slotRecvLinkUserInterveneRequest, Qt::QueuedConnection); + connect(m_linkCtrlStateManage, &CLinkCtrlStateManage::sigUpdateLinkAgeState, this, &CLinkCtrlWidget::slotUpdateLinkAgeState, Qt::QueuedConnection); + connect(m_linkCtrlStateManage, &CLinkCtrlStateManage::sigUpdateFunctionState, this, &CLinkCtrlWidget::slotUpdateFunctionState, Qt::QueuedConnection); + connect(m_linkCtrlStateManage, &CLinkCtrlStateManage::sigUpdateActionState, this, &CLinkCtrlWidget::slotUpdateActionState, Qt::QueuedConnection); + connect(this, &CLinkCtrlWidget::sigSubscribeLinkCtrlList, m_linkCtrlStateManage, &CLinkCtrlStateManage::subscribeLinkCtrlList, Qt::QueuedConnection); + connect(this, &CLinkCtrlWidget::sigClearSubscribe, m_linkCtrlStateManage, &CLinkCtrlStateManage::clearSubscribe, Qt::QueuedConnection); + + m_pLinkCtrlTableModel = new CLinkCtrlTableModel(this); + ui->linkCtrlTableView->setModel(m_pLinkCtrlTableModel); + ui->linkCtrlTableView->setColumnWidth(0, 300); + ui->linkCtrlTableView->setColumnWidth(1, 150); + ui->linkCtrlTableView->setColumnWidth(2, 150); + + m_pLinkCtrlTreeModel = new CLinkCtrlTreeModel(this); + ui->actionTreeView->setModel(m_pLinkCtrlTreeModel); + ui->actionTreeView->setColumnWidth(0, 300); + ui->actionTreeView->setColumnWidth(1, 150); + ui->actionTreeView->setColumnWidth(2, 150); + ui->actionTreeView->setHeaderHidden(false); + + //2020-6-15 modifi linkage type by read configuretion file + if(readLinkTypeDescXml()==kbdSuccess) + { + QStringList linkTypeList; + for(int index=0;index < (int)m_linkTypeStr.size(); index++) + { + QListWidgetItem *item = new QListWidgetItem; + item->setText(QString::fromStdString(m_linkTypeStr[std::to_string(index)])); + item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + ui->linkCtrlList->addItem(item); + + QString str = QString::fromStdString(m_linkTypeStr[std::to_string(index)]); + linkTypeList.append(str); + + } + m_pLinkCtrlTableModel->setLinkTypeList(linkTypeList); + m_historyLinkModel->setLinkTypeList(linkTypeList); + } + + connect(ui->linkCtrlList, &QListWidget::itemClicked, this, &CLinkCtrlWidget::updateRunLink); + + //2020-6-10 add link report + m_linkDBInterface->initDataBase(); + connect(ui->linkReportList, &QListWidget::itemClicked, this, &CLinkCtrlWidget::updateReportLink); + //< 联动报告界面 + ui->historyLinkView->setModel(m_historyLinkModel); + ui->historyLinkView->setColumnWidth(History_Link_Column::timeColumn, 150); + ui->exportLink->setVisible(false); + ui->printLink->setVisible(false); + + ui->historyActionView->setModel(m_historyActionModel); + ui->historyActionView->setHeaderHidden(false); + connect(ui->historyLinkView, &QTableView::clicked, this, &CLinkCtrlWidget::updateHistoryActionData); + ui->historyActionView->setColumnWidth(History_Action_Column::nameColumn, 180); + ui->historyActionView->setColumnWidth(History_Action_Column::descriptColumn, 250); + connect(ui->historyFilter, &QPushButton::clicked, this, &CLinkCtrlWidget::filterHistoryLink); + connect(ui->printLink, &QPushButton::clicked, this, &CLinkCtrlWidget::print); + + + + connect(ui->allLinkCtrlButton, &QPushButton::clicked, this, &CLinkCtrlWidget::slotUpdateLinkCtrlList); + connect(ui->waitForExceLinkCtrlButton, &QPushButton::clicked, this, &CLinkCtrlWidget::slotUpdateLinkCtrlList); + connect(ui->searchButton, &QPushButton::clicked, this, &CLinkCtrlWidget::slotUpdateLinkCtrlTableView); + //connect(ui->linkCtrlList, &QListWidget::itemSelectionChanged, this, &CLinkCtrlWidget::slotUpdateLinkCtrlTableView); + connect(ui->linkCtrlTableView, &QTableView::clicked, this, &CLinkCtrlWidget::slotUpdateLinkOperateEnable); + connect(ui->linkCtrlTableView, &QTableView::clicked, this, &CLinkCtrlWidget::slotUpdateLinkCtrlActionTreeView); + connect(ui->excution, &QPushButton::clicked, this, &CLinkCtrlWidget::slotExecution); + connect(ui->single, &QPushButton::clicked, this, &CLinkCtrlWidget::slotSingleStep); + connect(ui->pause, &QPushButton::clicked, this, &CLinkCtrlWidget::slotPause); + connect(ui->termination, &QPushButton::clicked, this, &CLinkCtrlWidget::slotTermination); + connect(m_pLinkCtrlTableModel, &CLinkCtrlTableModel::sigRowCountChanged, this, &CLinkCtrlWidget::slotUpdateLinkCtrlTableViewSelect); + connect(m_pLinkCtrlTreeModel, &CLinkCtrlTreeModel::itemCheckStateChanged, this, &CLinkCtrlWidget::slotLinkCtrlCheckStateChanged); + ui->linkCtrlList->setCurrentRow(0); + updateRunLink(); //初始化执行一次 + ui->pause->setEnabled(false); + ui->termination->setEnabled(false); + m_permTimer = new QTimer(); + m_permTimer->setInterval(1000); + connect(m_permTimer, &QTimer::timeout, this, &CLinkCtrlWidget::updatePerm); + m_permTimer->start(); + +} + +void CLinkCtrlWidget::login() +{ + +} + +void CLinkCtrlWidget::logout() +{ + +} + +bool CLinkCtrlWidget::getLinkCtrlPerm() +{ + //<权限处理 + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::string tmp = FUNC_NOM_LINK_CTRL; + if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) + { + return true; + } + } + return false; +} + +void CLinkCtrlWidget::slotExecution() +{ + if(!getLinkCtrlPerm()) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备联动操作权限!")); + msgBox.exec(); + return; + } + + QModelIndex index = ui->linkCtrlTableView->currentIndex(); + if(!index.isValid()) + { + QMessageBox::warning(NULL, tr("错误"), tr("当前未选中联动")); + return; + } + index = index.sibling(index.row(), 0); + QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); + + kbd_public::CSysInfoInterfacePtr spSysInfo; + kbd_public::SLocationInfo stLocationInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + foreach (S_LINKCTRL_INFO info, m_linkCtrlList) + { + if(info.linkageName == strLinkAgeName) + { + quint64 timeFlag = info.timeFlag; + E_LCS_STATUS nodeState = (E_LCS_STATUS)info.status; + QList nodeList = m_linkFunctionTree; + spSysInfo->getLocationInfoById(info.locationID, stLocationInfo); + m_linkCtrlDataManage->requestLinkOperation(stLocationInfo.nDomainId, strLinkAgeName, timeFlag, nodeState, nodeList, E_LINK_START); + break; + } + } + } +} + +void CLinkCtrlWidget::slotSingleStep() +{ + if(!getLinkCtrlPerm()) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备联动操作权限!")); + msgBox.exec(); + return; + } + + QModelIndex index = ui->linkCtrlTableView->currentIndex(); + if (!index.isValid()) + { + QMessageBox::warning(NULL, tr("错误"), tr("当前未选中联动")); + return; + } + E_LINK_OPERATETYPE type = E_SES_START; + if (!ui->excution->isEnabled()) + { + type = E_SES_CONTINUE; + } + index = index.sibling(index.row(), 0); + QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); + + kbd_public::CSysInfoInterfacePtr spSysInfo; + kbd_public::SLocationInfo stLocationInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + foreach(S_LINKCTRL_INFO info, m_linkCtrlList) + { + if (info.linkageName == strLinkAgeName) + { + quint64 timeFlag = info.timeFlag; + E_LCS_STATUS nodeState = (E_LCS_STATUS)info.status; + QList nodeList = m_linkFunctionTree; + spSysInfo->getLocationInfoById(info.locationID, stLocationInfo); + m_linkCtrlDataManage->requestLinkOperation(stLocationInfo.nDomainId, strLinkAgeName, timeFlag, nodeState, nodeList, type); + break; + } + } + } +} + +void CLinkCtrlWidget::slotPause() +{ + if(!getLinkCtrlPerm()) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备联动操作权限!")); + msgBox.exec(); + return; + } + + QModelIndex index = ui->linkCtrlTableView->currentIndex(); + if (!index.isValid()) + { + QMessageBox::warning(NULL, tr("错误"), tr("当前未选中联动")); + return; + } + E_LINK_OPERATETYPE type = E_LINK_PAUSE; + if (ui->pause->text() == tr("继续")) + { + type = E_LINK_CONTINUE; + } + + index = index.sibling(index.row(), 0); + QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); + + kbd_public::CSysInfoInterfacePtr spSysInfo; + kbd_public::SLocationInfo stLocationInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + foreach(S_LINKCTRL_INFO info, m_linkCtrlList) + { + if (info.linkageName == strLinkAgeName) + { + quint64 timeFlag = info.timeFlag; + E_LCS_STATUS nodeState = (E_LCS_STATUS)info.status; + QList nodeList = m_linkFunctionTree; + spSysInfo->getLocationInfoById(info.locationID, stLocationInfo); + m_linkCtrlDataManage->requestLinkOperation(stLocationInfo.nDomainId, strLinkAgeName, timeFlag, nodeState, nodeList, type); + break; + } + } + } +} + +void CLinkCtrlWidget::slotTermination() +{ + if(!getLinkCtrlPerm()) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备联动操作权限!")); + msgBox.exec(); + return; + } + + ui->linkCtrlTableView->setFocus(); + QModelIndex index = ui->linkCtrlTableView->currentIndex(); + if (!index.isValid()) + { + QMessageBox::warning(NULL, tr("错误"), tr("当前未选中联动")); + return; + } + index = index.sibling(index.row(), 0); + QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); + + kbd_public::CSysInfoInterfacePtr spSysInfo; + kbd_public::SLocationInfo stLocationInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + foreach(S_LINKCTRL_INFO info, m_linkCtrlList) + { + if (info.linkageName == strLinkAgeName) + { + quint64 timeFlag = info.timeFlag; + E_LCS_STATUS nodeState = (E_LCS_STATUS)info.status; + QList nodeList = m_linkFunctionTree; + spSysInfo->getLocationInfoById(info.locationID, stLocationInfo); + m_linkCtrlDataManage->requestLinkOperation(stLocationInfo.nDomainId, strLinkAgeName, timeFlag, nodeState, nodeList, E_LINK_STOP); + break; + } + } + } +} + +void CLinkCtrlWidget::slotUpdateLinkCtrlList() +{ + m_linkCtrlList = m_linkCtrlDataManage->queryLinkCtrlList(); + slotUpdateLinkCtrlTableView(); +} + +void CLinkCtrlWidget::slotUpdateLinkOperateEnable(const QModelIndex &index) +{ + if (!index.isValid()) + { + return; + } + if (E_RUNNING_STATUS == (E_LCS_STATUS)m_pLinkCtrlTableModel->value(index.sibling(index.row(), 2)).toInt()) + { + updateUiButtonState(E_RESTING_STATUS); + } +} + +void CLinkCtrlWidget::slotUpdateLinkCtrlTableView() +{ + if(dynamic_cast(sender())) + { + m_linkCtrlList = m_linkCtrlDataManage->queryLinkCtrlList(); + } + + QList linkCtrlList = m_linkCtrlList; + + //<待执行联动 + bool bIsWaitForExcute = ui->waitForExceLinkCtrlButton->isChecked(); + + //<联动类型过滤 + int nLinkCtrlType = ui->linkCtrlList->currentRow(); + + //<关键词 + QString strKeyWord = ui->searchLineEdit->text(); + + + QList::iterator iter = linkCtrlList.begin(); + while (iter != linkCtrlList.end()) + { + //Filter + if(bIsWaitForExcute) + { + if(E_Exec_Semi_Auto != (*iter).exeType || E_TRIGGERED_STATUS != (*iter).status) + { + iter = linkCtrlList.erase(iter); + continue; + } + } + + if((*iter).linkType != nLinkCtrlType) + { + iter = linkCtrlList.erase(iter); + continue; + } + if(!strKeyWord.isEmpty()) + { + if(!(*iter).linkageDescription.contains(strKeyWord)) + { + iter = linkCtrlList.erase(iter); + continue; + } + } + iter++; + } + m_pLinkCtrlTableModel->reset(); + m_pLinkCtrlTreeModel->reset(); + m_pLinkCtrlTableModel->updateModelData(linkCtrlList); + if(!linkCtrlList.isEmpty()) + { + ui->linkCtrlTableView->selectRow(0); + slotUpdateLinkOperateEnable(ui->linkCtrlTableView->currentIndex()); + } + +// ui->linkCtrlTableView->setFocus(); + slotUpdateLinkCtrlActionTreeView(); +} + +void CLinkCtrlWidget::slotUpdateLinkCtrlActionTreeView() +{ + emit sigClearSubscribe(); + + ui->excution->setEnabled(false); + ui->single->setEnabled(false); + ui->pause->setText(tr("暂停")); + ui->pause->setEnabled(false); + ui->termination->setEnabled(false); + + QModelIndex index = ui->linkCtrlTableView->currentIndex(); + if(!index.isValid()) + { + return; + } + index = index.sibling(index.row(), 0); + QString strLinkAgeName = m_pLinkCtrlTableModel->value(index).toString(); + + m_linkFunctionTree = m_linkCtrlDataManage->queryLinkFunctionList(strLinkAgeName); + + m_pLinkCtrlTreeModel->updateModelData(m_linkFunctionTree); + + for(int nIndex(0); nIndex < m_linkFunctionTree.size(); nIndex++) + { + QModelIndex modelIndex = m_pLinkCtrlTreeModel->index(nIndex, 0); + ui->actionTreeView->expand(modelIndex); + } + ui->actionTreeView->setColumnWidth(1, 40); + ui->actionTreeView->setColumnWidth(2, 80); + emit sigSubscribeLinkCtrlList(m_linkCtrlList); + emit sigSubscribeLinkCtrlList(m_linkFunctionTree); +} + +void CLinkCtrlWidget::slotUpdateLinkCtrlTableViewSelect() +{ + if (1 == m_pLinkCtrlTableModel->rowCount()) + { + ui->linkCtrlTableView->selectRow(0); + slotUpdateLinkCtrlActionTreeView(); + } +} + +void CLinkCtrlWidget::slotLinkCtrlCheckStateChanged(const QString functionName, const QString actionName, const int checkedState) +{ + QModelIndex index = ui->linkCtrlTableView->currentIndex(); + if (!index.isValid()) + { + return; + } + index = index.sibling(index.row(), 0); + for (int nIndex(0); nIndex < m_linkFunctionTree.size(); nIndex++) + { + if (m_linkFunctionTree[nIndex].funcName == functionName && m_linkFunctionTree[nIndex].actionName == actionName) + { + m_linkFunctionTree[nIndex].checked = checkedState; + break; + } + } +} + +void CLinkCtrlWidget::slotRequestLinkOperationFail(const QString &strLinkDescription, const E_LINK_OPERATETYPE &type, const int &nErrorCode, const QString &strErrorCode) +{ + Q_UNUSED(type) + QString content = QString("%1%2\n%3%4\n%5%6\n").arg(tr("联动名称: ")).arg(strLinkDescription).arg(tr("错误代码: ")).arg(nErrorCode).arg(tr("错误描述: ")).arg(strErrorCode); + QMessageBox::warning(NULL, tr("联动操作请求失败"), content); + if (m_pLinkCtrlTableModel->contains(strLinkDescription)) + { + updateUiButtonState(E_RESTING_STATUS); + } +} + + +void CLinkCtrlWidget::slotRecvLinkUserInterveneRequest(UiRequestMessage *msg) +{ + if(!getLinkCtrlPerm()) + { + return; + } + handleUserInterveneRequest(*msg); + delete msg; +} + +void CLinkCtrlWidget::handleUserInterveneRequest(UiRequestMessage &msg) +{ + if (m_userInterveneRequestDialog ) + { + return; + } + + LinkNodeStatusParameter * linkNodeParameter = msg.mutable_nodelist(); + QString strLinkName = QString::fromStdString(linkNodeParameter->link_desc()); + QString strErrorMessage; + if (!msg.mutable_execute_status()->statuscode()) + { + ErrorParameter * pErrorParameter = msg.mutable_execute_status()->mutable_erro_param(); + strErrorMessage = QString::fromStdString(pErrorParameter->errordescription()); + } + if (strErrorMessage.isEmpty()) + { + strErrorMessage = tr("执行失败,请求人工干预!"); + } + + QString strFunctionName; + QString strActionName; + if (linkNodeParameter->nodelist_size() > 0) + { + for (int nFunctionIndex(0); nFunctionIndex < linkNodeParameter->nodelist_size(); nFunctionIndex++) + { + FucNodeStatusParameter fucNodeStatusParameter = linkNodeParameter->nodelist(nFunctionIndex); + strFunctionName = QString::fromStdString(fucNodeStatusParameter.fuc_desc()); + if (fucNodeStatusParameter.nodelist_size() > 0) + { + for (int nActionndex(0); nActionndex < linkNodeParameter->nodelist_size(); nActionndex++) + { + ActionNodeStatusParameter actionNodeStatusParameter = fucNodeStatusParameter.nodelist(nActionndex); + strActionName = QString::fromStdString(actionNodeStatusParameter.action_desc()); + break; + } + break; + } + } + } + + QString content = QString("%1%2\n%3%4\n%5%6\n\n%7").arg(tr("联动名称: ")). + arg(strLinkName).arg(tr("功能名称: ")).arg(strFunctionName).arg(tr("动作名称: ")).arg(strActionName).arg(strErrorMessage); + m_userInterveneRequestDialog = new QMessageBox(QMessageBox::Question, tr("人工干预请求"), content, QMessageBox::NoButton, this); + E_UIOPERATE_TYPE type; + + if(m_userInterveneRequestDialog != NULL) + { + QAbstractButton * retry = m_userInterveneRequestDialog->addButton(tr("重试"), QMessageBox::AcceptRole); + QAbstractButton * stop = m_userInterveneRequestDialog->addButton(tr("终止"), QMessageBox::RejectRole); + QAbstractButton * skip = m_userInterveneRequestDialog->addButton(tr("跳过"), QMessageBox::NoRole); + m_userInterveneRequestDialog->exec(); + if (m_userInterveneRequestDialog->clickedButton() == retry) + { + type = E_OP_RETRY; + } + else if (m_userInterveneRequestDialog->clickedButton() == stop) + { + type = E_OP_STOP; + } + else if (m_userInterveneRequestDialog->clickedButton() == skip) + { + type = E_OP_SKIP; + } + delete m_userInterveneRequestDialog; + m_userInterveneRequestDialog = NULL; + + } + + kbd_idlfile::linkage::UiRequestMessageAck msgAck; + if(!buildUserInterveneReplyMsg(msg, type, msgAck)) + { + return; + } + m_linkCtrlDataManage->replyUserInterveneRequest(msgAck); +} + +void CLinkCtrlWidget::slotLinkAgeStart(const QString &strLinkName, const int &state, const quint64 &triggerTime) +{ + for (int nIndex(0); nIndex < m_linkCtrlList.size(); nIndex++) + { + if (strLinkName == m_linkCtrlList[nIndex].linkageName && 0 == m_linkCtrlList[nIndex].nodeType) + { + m_linkCtrlList[nIndex].status = state; + m_linkCtrlList[nIndex].triggerTime = triggerTime; + } + } + if (m_pLinkCtrlTableModel->contains(strLinkName)) + { + m_pLinkCtrlTableModel->updateLinkAgeState(strLinkName, state, triggerTime); + } + else + { + foreach(S_LINKCTRL_INFO info, m_linkCtrlList) + { + if (info.linkageName == strLinkName) + { + bool bIsWaitForExcute = ui->waitForExceLinkCtrlButton->isChecked(); + int nLinkCtrlType = ui->linkCtrlList->currentRow(); + QString strKeyWord = ui->searchLineEdit->text(); + if (bIsWaitForExcute) + { + if (E_Exec_Semi_Auto != info.exeType || E_TRIGGERED_STATUS != info.status) + { + return; + } + } + if (info.linkType != nLinkCtrlType) + { + return; + } + if (!strKeyWord.isEmpty()) + { + if (!info.linkageName.contains(strKeyWord)) + { + return; + } + } + m_pLinkCtrlTableModel->insertLinkAge(info); + } + } + } + +} + +void CLinkCtrlWidget::slotUpdateLinkAgeState( const QString &strLinkName, int state, + quint64 triggerTime, quint64 timeFlag ) +{ + for ( int nIndex( 0 ); nIndex < m_linkCtrlList.size(); nIndex++ ) + { + if ( strLinkName == m_linkCtrlList[nIndex].linkageName && E_Node_LinkCtrl == m_linkCtrlList[nIndex].nodeType ) + { + //< 配置已发生修改 + if ( timeFlag != m_linkCtrlList[nIndex].timeFlag ) + state = E_INVALID_STATUS; + + if ( triggerTime > 0 ) + m_linkCtrlList[nIndex].triggerTime = triggerTime; + + m_linkCtrlList[nIndex].status = state; + } + } + + QModelIndex modelIndex = ui->linkCtrlTableView->currentIndex(). + sibling( ui->linkCtrlTableView->currentIndex().row(), 0 ); + if ( strLinkName == m_pLinkCtrlTableModel->value( modelIndex ).toString()) + { + updateUiButtonState(( E_LCS_STATUS ) state ); + } + m_pLinkCtrlTableModel->updateLinkAgeState( strLinkName, state, triggerTime ); +} + +void CLinkCtrlWidget::slotUpdateFunctionState(const QString &strLinkName, const QString &strFunctionName, const int &state) +{ + m_pLinkCtrlTreeModel->updateFunctionState(strFunctionName, state); + for (int nIndex(0); nIndex < m_linkFunctionTree.size(); nIndex++) + { + if (strLinkName == m_linkFunctionTree[nIndex].linkageName && strFunctionName == m_linkFunctionTree[nIndex].funcName && E_Node_Function == m_linkFunctionTree[nIndex].nodeType) + { + m_linkFunctionTree[nIndex].status = state; + } + } +} + +void CLinkCtrlWidget::slotUpdateActionState(const QString &strLinkName, const QString &strFunctionName, const QString &strActionName, const int &state) +{ + m_pLinkCtrlTreeModel->updateActionState(strFunctionName, strActionName, state); + for (int nIndex(0); nIndex < m_linkFunctionTree.size(); nIndex++) + { + if (strLinkName == m_linkFunctionTree[nIndex].linkageName && strFunctionName == m_linkFunctionTree[nIndex].funcName && strActionName == m_linkFunctionTree[nIndex].actionName && E_Node_Action == m_linkFunctionTree[nIndex].nodeType) + { + m_linkFunctionTree[nIndex].status = state; + } + } +} + +void CLinkCtrlWidget::updatePerm() +{ + bool isPerm = getLinkCtrlPerm(); + ui->excution->setVisible(isPerm); + ui->single->setVisible(isPerm); + ui->pause->setVisible(isPerm); + ui->termination->setVisible(isPerm); +} + +//2020-6-10 +void CLinkCtrlWidget::updateRunLink() +{ + ui->stackedWidget->setCurrentIndex(0); + slotUpdateLinkCtrlTableView(); + +} + +void CLinkCtrlWidget::updateReportLink() +{ + ui->stackedWidget->setCurrentIndex(1); + loadLinkReport(); +} + + +void CLinkCtrlWidget::updateUiButtonState(const E_LCS_STATUS type) +{ + switch (type) + { + case E_RESTING_STATUS: //<未执行 + { + ui->excution->setEnabled(true); + ui->single->setEnabled(true); + ui->pause->setEnabled(false); + ui->pause->setText(tr("暂停")); + ui->termination->setEnabled(false); + break; + } + case E_RUNNING_STATUS: //<正在执行 + { + ui->excution->setEnabled(false); + ui->single->setEnabled(false); + ui->pause->setEnabled(true); + ui->pause->setText(tr("暂停")); + ui->termination->setEnabled(true); + break; + } + case E_FAILED_STATUS: //<执行失败 + case E_SUCCESS_STATUS: //<执行成功 + case E_STOP_STATUS: //<执行终止 + { + ui->excution->setEnabled(false); + ui->single->setEnabled(false); + ui->pause->setEnabled(false); + ui->pause->setText(tr("暂停")); + ui->termination->setEnabled(false); + break; + } + case E_PAUSE_STATUS: //<执行暂停 + { + ui->excution->setEnabled(false); + ui->single->setEnabled(false); + ui->pause->setEnabled(true); + ui->pause->setText(tr("继续")); + ui->termination->setEnabled(true); + break; + } + case E_TRIGGERED_STATUS: //已触发 + { + ui->excution->setEnabled(true); + ui->single->setEnabled(true); + ui->pause->setEnabled(false); + ui->pause->setText(tr("暂停")); + ui->termination->setEnabled(true); + break; + } + case E_INVALID_STATUS: //时标不一致 + { + ui->excution->setEnabled(false); + ui->single->setEnabled(false); + ui->pause->setEnabled(false); + ui->pause->setText(tr("继续")); + ui->termination->setEnabled(true); + break; + } + default: + { + ui->excution->setEnabled(false); + ui->single->setEnabled(false); + ui->pause->setText(tr("暂停")); + ui->pause->setEnabled(false); + ui->termination->setEnabled(false); + break; + } + } +} + +bool CLinkCtrlWidget::buildUserInterveneReplyMsg(const kbd_idlfile::linkage::UiRequestMessage &sourceMsg, const E_UIOPERATE_TYPE &type, UiRequestMessageAck &msgAck) +{ + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + spSysInfo->getLocalNodeInfo(stNodeInfo); + } + else + { + LOGERROR("构建人工干预回复消息错误 [创建系统信息访问库实例失败]!"); + return false; + } + + int nUserId = -1; + int nUserGrpId = -1; + std::string strUserName = ""; + int nLevel = -1; + int nLoginSec = -1; + std::string strInstanceName = ""; + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + if(0 == permMngPtr->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + permMngPtr->GetUserNameByUserId(nUserId, strUserName); + } + else + { + LOGERROR("构建人工干预回复消息错误[权限获取失败]!"); + return false; + } + } + else + { + LOGERROR("构建人工干预回复消息错误[创建权限闭锁参数访问接口实例]!"); + return false; + } + + LcsPkgHead * head = new LcsPkgHead(); + head->set_source_tag("hmi"); + head->set_msg_type((enLcsMsgType)E_LinkOperate_Message); + head->set_source_domain(stNodeInfo.nDomainId); + head->set_target_domain(sourceMsg.pkg_head().source_domain()); + head->set_para1(sourceMsg.pkg_head().para1()); + head->set_para2(sourceMsg.pkg_head().para2()); + msgAck.set_allocated_pkg_head(head); + + LinkNodeStatusParameter * linkNodeParameter = new LinkNodeStatusParameter(); + *linkNodeParameter = sourceMsg.nodelist(); + msgAck.set_allocated_nodelist(linkNodeParameter); + + ActorParameter * actorParameter = new ActorParameter(); + actorParameter->set_user_id(nUserId); + actorParameter->set_user_groupid(nUserGrpId); + actorParameter->set_host_name(stNodeInfo.strName); + actorParameter->set_user_name(strUserName); + msgAck.set_allocated_actor(actorParameter); + + msgAck.set_optype((ENUiOperateType)type); + return true; +} + +/*********************************Report UI CONFIG BEGIN*************************************/ +void CLinkCtrlWidget::loadLinkReport() +{ + QDateTime end = QDateTime::currentDateTime(); + end.setTimeSpec(Qt::UTC); + QDateTime start = end.addDays(-30); + m_listHistroyLink = m_linkDBInterface->queryHistoryLinkNodeList(start, end); + QList::iterator it = m_listHistroyLink.begin(); + while (it != m_listHistroyLink.end()) + { + if(m_historyCondition.locationFilter) + { + if(!m_historyCondition.locationList.contains(it->location)) + { + it = m_listHistroyLink.erase(it); + continue; + } + } + if(m_historyCondition.userFilter) + { + if(!m_historyCondition.userList.contains(it->userName)) + { + it = m_listHistroyLink.erase(it); + continue; + } + } + if(m_historyCondition.resultFilter) + { + if(!m_historyCondition.resultList.contains(it->status)) + { + it = m_listHistroyLink.erase(it); + continue; + } + } + if(m_historyCondition.typeFilter) + { + if((m_historyCondition.isStandardType && 0 != it->linkType) || (!m_historyCondition.isStandardType && 1 != it->linkType)) + { + it = m_listHistroyLink.erase(it); + continue; + } + } + + if(m_historyCondition.timeFilter) + { + QDateTime time = QDateTime::fromSecsSinceEpoch(it->time); + if(m_historyCondition.startTime > time || m_historyCondition.endTime < time) + { + it = m_listHistroyLink.erase(it); + continue; + } + } + it++; + } + m_historyLinkModel->setHistoryLinkData(m_listHistroyLink); + if(!m_listHistroyLink.isEmpty()) + { + ui->historyLinkView->selectRow(0); + updateHistoryActionData(); + } + else + { + QList listFunctionHistory; + m_historyActionModel->updateModelFunctionData(listFunctionHistory); + } +} + +void CLinkCtrlWidget::updateHistoryActionData() +{ + QModelIndex modelIndex = ui->historyLinkView->currentIndex(); + + QString currentLinkName = m_historyLinkModel->LinkName(modelIndex); + quint64 currentLinkTime = m_historyLinkModel->LinkTime(modelIndex); + QList listFunctionHistory = m_linkDBInterface->queryHistoryFunctionNodeList(currentLinkName, currentLinkTime); + QList listActionHistory; + foreach (FunctionHistory funcHistory, listFunctionHistory) + { + listActionHistory.append(m_linkDBInterface->queryHistoryActionNodeList(funcHistory.linkName, funcHistory.funcName, funcHistory.time)); + } + m_historyActionModel->updateModelFunctionData(listFunctionHistory); + m_historyActionModel->updateModelActionData(listActionHistory); + ui->historyActionView->expandAll(); +} + +int CLinkCtrlWidget::readLinkTypeDescXml() +{ + std::string linkTypeStr; + + //< 读取LINKAGE_SETTING配置文件,获取联动类型 + std::string path = kbd_public::CFileUtil::getPathOfResFile("model_studio/setting/table/LINKAGE_SETTING.xml"); + if(readXml(path,linkTypeStr)==kbdFailed) + { + LOGERROR("readLinkTypeDescXml load [zh] LINKAGE_SETTING.xml error"); + return kbdFailed; + } + + std::vector destination; + boost::split( destination, linkTypeStr, boost::is_any_of( "/" ), boost::token_compress_on ); + std::vector::iterator it ; + for( it= destination.begin(); it != destination.end(); ++ it ) + { + std::vector destination2; + destination2.clear(); + boost::split( destination2, *it, boost::is_any_of( ":" ), boost::token_compress_on ); + m_linkTypeStr.insert(std::pair(destination2.at(0), destination2.at(1))); + + } + return kbdSuccess; +} + +int CLinkCtrlWidget::readXml(std::string fileName,std::string &strValue) +{ + ptree pt; + namespace xml = boost::property_tree::xml_parser; + + strValue = "LINK_TYPE"; + try + { + xml::read_xml(fileName, pt); //第三个参数不填默认为0 + BOOST_AUTO(module, pt.get_child("Table")); + + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + + if(pModuleIter->first == "COLS") + { + ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + + if (pParamIter->first == "COL") + { + std::string strKey = pParamIter->second.get(".SQLName"); + if(strKey == "LINK_TYPE") + strValue = pParamIter->second.get(".valueLimit"); + } + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg = [%s]", fileName.c_str(),ex.what()); + return kbdFailed; + } + + if(strValue == "LINK_TYPE") + { + LOGERROR("获取联动类型值失败!"); + return kbdFailed; + } + return kbdSuccess; +} + +void CLinkCtrlWidget::filterHistoryLink() +{ + QStringList locationList = m_linkDBInterface->queryAllLocationName(); + QStringList userNameList = m_linkDBInterface->queryUserIDMap().values(); + CHistoryLinkFilterDialog linkFilterDlg(locationList, userNameList, this); + linkFilterDlg.initialize(m_historyCondition); + if(QDialog::Accepted != linkFilterDlg.exec()) + { + return; + } + + m_historyCondition = linkFilterDlg.LinkFilterCondition(); + loadLinkReport(); +} + +void CLinkCtrlWidget::print() +{ + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); + if(!fileName.isEmpty()) + { + QTableView view(ui->historyLinkView); + view.setModel(ui->historyLinkView->model()); + view.horizontalHeader()->resizeSection(2, 250); + + QPrinter printer; + printer.setPageSize(QPagedPaintDevice::A4); + printer.setPageOrientation(QPageLayout::Landscape); + + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + + CTableViewPrinter viewPrinter(&view); + viewPrinter.print(&printer); + } +} +/*********************************Report UI CONFIG END*************************************/ diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.h index 2ecab926..8a26c7b7 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.h @@ -1,108 +1,108 @@ -#ifndef CLINKCTRLWIDGET_H -#define CLINKCTRLWIDGET_H - -#include -#include "linkctrl_def.h" -#include "CLinkCtrlTableModel.h" -#include "CLinkCtrlTreeModel.h" -#include "../../idl_files/LinkageMessage.pb.h" -#include "CHistoryLinkFilterDialog.h" - -#define BUTTONROLE ("Invalid") -#define FUNC_NOM_LINK_CTRL ("FUNC_NOM_PSCADA_LINK_CTRL") - -namespace Ui { -class CLinkCtrlWidget; -} -class QThread; -class QMessageBox; -class CLinkCtrlDataManage; -class CLinkCtrlStateManage; - -struct LinkHistory; -class CLinkDBInterface; -class CHistoryLinkModel; -class CHistoryActionModel; - -class CLinkCtrlWidget : public QWidget -{ - Q_OBJECT -public: - explicit CLinkCtrlWidget(QWidget *parent, bool editMode); - ~CLinkCtrlWidget(); - - void initialize(); - -public slots: - void login(); - - void logout(); - -signals: - void sigSubscribeLinkCtrlList(QList list); - void sigClearSubscribe(); - -protected slots: - void slotExecution(); - void slotSingleStep(); - void slotPause(); - void slotTermination(); - - void slotUpdateLinkCtrlList(); - void slotUpdateLinkOperateEnable(const QModelIndex &index = QModelIndex()); - void slotUpdateLinkCtrlTableView(); - void slotUpdateLinkCtrlActionTreeView(); - void slotUpdateLinkCtrlTableViewSelect(); - void slotLinkCtrlCheckStateChanged(const QString functionName, const QString actionName, const int checkedState); - - void slotRequestLinkOperationFail(const QString &strLinkDescription, const E_LINK_OPERATETYPE &type, const int &nErrorCode, const QString &strErrorCode); - void slotRecvLinkUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage *msg); - void slotLinkAgeStart(const QString &strLinkName, const int &state, const quint64 &triggerTime); - - //< triggerTime 为0不刷新此值 - void slotUpdateLinkAgeState(const QString &strLinkName, int state, quint64 triggerTime, quint64 timeFlag); - void slotUpdateFunctionState(const QString &strLinkName, const QString &strFunctionName, const int &state); - void slotUpdateActionState(const QString &strLinkName, const QString &strFunctionName, const QString &strActionName, const int &state); - void updatePerm(); -private slots: - void updateRunLink(); - void updateReportLink(); - void filterHistoryLink(); - void print(); - -private: - bool getLinkCtrlPerm(); - void updateUiButtonState(const E_LCS_STATUS type); - void handleUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage &msg); - bool buildUserInterveneReplyMsg(const kbd_idlfile::linkage::UiRequestMessage &sourceMsg, const E_UIOPERATE_TYPE &type, kbd_idlfile::linkage::UiRequestMessageAck &msgAck); - void loadLinkReport(); - void updateHistoryActionData(); - int readLinkTypeDescXml(); - int readXml(std::string fileName,std::string &strValue); -private: - Ui::CLinkCtrlWidget *ui; - QTimer * m_permTimer; - CLinkCtrlTableModel * m_pLinkCtrlTableModel; - CLinkCtrlTreeModel * m_pLinkCtrlTreeModel; - CLinkCtrlDataManage * m_linkCtrlDataManage; - CLinkCtrlStateManage * m_linkCtrlStateManage; - QList m_linkCtrlList; - QList m_linkFunctionTree; - QMessageBox * m_userInterveneRequestDialog; - - //report - CHistoryLinkModel * m_historyLinkModel; - CHistoryActionModel * m_historyActionModel; - CLinkDBInterface * m_linkDBInterface; - QList m_listHistroyLink; - History_Filter_Condition m_historyCondition; - - std::map m_linkTypeStr; - -}; - -Q_DECLARE_METATYPE(E_LINK_OPERATETYPE) -Q_DECLARE_METATYPE(QList) -Q_DECLARE_METATYPE(kbd_idlfile::linkage::UiRequestMessage) - -#endif // CLINKCTRLWIDGET_H +#ifndef CLINKCTRLWIDGET_H +#define CLINKCTRLWIDGET_H + +#include +#include "linkctrl_def.h" +#include "CLinkCtrlTableModel.h" +#include "CLinkCtrlTreeModel.h" +#include "../../idl_files/LinkageMessage.pb.h" +#include "CHistoryLinkFilterDialog.h" + +#define BUTTONROLE ("Invalid") +#define FUNC_NOM_LINK_CTRL ("FUNC_NOM_PSCADA_LINK_CTRL") + +namespace Ui { +class CLinkCtrlWidget; +} +class QThread; +class QMessageBox; +class CLinkCtrlDataManage; +class CLinkCtrlStateManage; + +struct LinkHistory; +class CLinkDBInterface; +class CHistoryLinkModel; +class CHistoryActionModel; + +class CLinkCtrlWidget : public QWidget +{ + Q_OBJECT +public: + explicit CLinkCtrlWidget(QWidget *parent, bool editMode); + ~CLinkCtrlWidget(); + + void initialize(); + +public slots: + void login(); + + void logout(); + +signals: + void sigSubscribeLinkCtrlList(QList list); + void sigClearSubscribe(); + +protected slots: + void slotExecution(); + void slotSingleStep(); + void slotPause(); + void slotTermination(); + + void slotUpdateLinkCtrlList(); + void slotUpdateLinkOperateEnable(const QModelIndex &index = QModelIndex()); + void slotUpdateLinkCtrlTableView(); + void slotUpdateLinkCtrlActionTreeView(); + void slotUpdateLinkCtrlTableViewSelect(); + void slotLinkCtrlCheckStateChanged(const QString functionName, const QString actionName, const int checkedState); + + void slotRequestLinkOperationFail(const QString &strLinkDescription, const E_LINK_OPERATETYPE &type, const int &nErrorCode, const QString &strErrorCode); + void slotRecvLinkUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage *msg); + void slotLinkAgeStart(const QString &strLinkName, const int &state, const quint64 &triggerTime); + + //< triggerTime 为0不刷新此值 + void slotUpdateLinkAgeState(const QString &strLinkName, int state, quint64 triggerTime, quint64 timeFlag); + void slotUpdateFunctionState(const QString &strLinkName, const QString &strFunctionName, const int &state); + void slotUpdateActionState(const QString &strLinkName, const QString &strFunctionName, const QString &strActionName, const int &state); + void updatePerm(); +private slots: + void updateRunLink(); + void updateReportLink(); + void filterHistoryLink(); + void print(); + +private: + bool getLinkCtrlPerm(); + void updateUiButtonState(const E_LCS_STATUS type); + void handleUserInterveneRequest(kbd_idlfile::linkage::UiRequestMessage &msg); + bool buildUserInterveneReplyMsg(const kbd_idlfile::linkage::UiRequestMessage &sourceMsg, const E_UIOPERATE_TYPE &type, kbd_idlfile::linkage::UiRequestMessageAck &msgAck); + void loadLinkReport(); + void updateHistoryActionData(); + int readLinkTypeDescXml(); + int readXml(std::string fileName,std::string &strValue); +private: + Ui::CLinkCtrlWidget *ui; + QTimer * m_permTimer; + CLinkCtrlTableModel * m_pLinkCtrlTableModel; + CLinkCtrlTreeModel * m_pLinkCtrlTreeModel; + CLinkCtrlDataManage * m_linkCtrlDataManage; + CLinkCtrlStateManage * m_linkCtrlStateManage; + QList m_linkCtrlList; + QList m_linkFunctionTree; + QMessageBox * m_userInterveneRequestDialog; + + //report + CHistoryLinkModel * m_historyLinkModel; + CHistoryActionModel * m_historyActionModel; + CLinkDBInterface * m_linkDBInterface; + QList m_listHistroyLink; + History_Filter_Condition m_historyCondition; + + std::map m_linkTypeStr; + +}; + +Q_DECLARE_METATYPE(E_LINK_OPERATETYPE) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(kbd_idlfile::linkage::UiRequestMessage) + +#endif // CLINKCTRLWIDGET_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.ui b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.ui index 6a67edb0..4d4a5d76 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.ui +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.ui @@ -1,686 +1,686 @@ - - - CLinkCtrlWidget - - - - 0 - 0 - 1102 - 664 - - - - 联动 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - - - - 16777215 - 16777215 - - - - 联动类型 - - - - 0 - - - 5 - - - 0 - - - 0 - - - - - - 100 - 0 - - - - QListView{ - outline:0px; -} -QListView::item{ - height: 32px; -} - - - false - - - QAbstractItemView::SingleSelection - - - false - - - - - - - - - - Qt::Vertical - - - - - - - 0 - - - - - 0 - - - 9 - - - 0 - - - 0 - - - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 6 - - - 3 - - - 6 - - - 6 - - - 0 - - - 3 - - - - - 6 - - - 0 - - - - - 联动列表 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 45 - 16777215 - - - - 搜索 - - - - - - - - 100 - 0 - - - - 待执行联动 - - - true - - - false - - - false - - - true - - - - - - - - 100 - 0 - - - - 所有联动 - - - true - - - true - - - false - - - true - - - - - - - - - QTableView{ - outline:0px; -} -QTableView::item{ - outline:0px; -} - - - true - - - false - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - false - - - - - - - - - - Qt::Horizontal - - - - - - - 动作列表 - - - - 0 - - - 0 - - - 0 - - - 3 - - - - - QTreeView{ - outline:0px; -} - - - true - - - true - - - true - - - true - - - true - - - false - - - false - - - true - - - - - - - - - - 60 - 16777215 - - - - 终止 - - - - - - - - 60 - 16777215 - - - - 执行 - - - - - - - - 60 - 16777215 - - - - 单步 - - - - - - - - 60 - 16777215 - - - - 暂停 - - - - - - - - - Qt::Vertical - - - - 20 - 183 - - - - - - - - - - - - - - - 0 - - - 9 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 6 - - - 3 - - - 6 - - - 6 - - - 3 - - - - - Qt::Horizontal - - - - 639 - 20 - - - - - - - - 历史列表 - - - - - - - QTableView{ - outline:0px; -} -QTableView::item{ - outline:0px; -} - - - true - - - false - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - - - - - 过滤 - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 6 - - - 3 - - - 6 - - - 0 - - - 6 - - - - - 执行详情 - - - - - - - true - - - false - - - true - - - - - - - Qt::Horizontal - - - - 720 - 20 - - - - - - - - - - Qt::Horizontal - - - - 258 - 20 - - - - - - - - 导出 - - - - - - - 打印 - - - - - - - - - - - - - - - - - 16777215 - 16777215 - - - - 联动报告 - - - - 0 - - - 5 - - - 0 - - - 0 - - - - - - 100 - 0 - - - - QListView{ - outline:0px; -} -QListView::item{ - height: 32px; -} - - - true - - - - 联动报告 - - - - 微软雅黑 - false - - - - AlignCenter - - - - - - - - - - - - - - - - CLinkCtrlTreeView - QTreeView -
CLinkCtrlTreeView.h
-
-
- - -
+ + + CLinkCtrlWidget + + + + 0 + 0 + 1102 + 664 + + + + 联动 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + 16777215 + 16777215 + + + + 联动类型 + + + + 0 + + + 5 + + + 0 + + + 0 + + + + + + 100 + 0 + + + + QListView{ + outline:0px; +} +QListView::item{ + height: 32px; +} + + + false + + + QAbstractItemView::SingleSelection + + + false + + + + + + + + + + Qt::Vertical + + + + + + + 0 + + + + + 0 + + + 9 + + + 0 + + + 0 + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 6 + + + 3 + + + 6 + + + 6 + + + 0 + + + 3 + + + + + 6 + + + 0 + + + + + 联动列表 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 45 + 16777215 + + + + 搜索 + + + + + + + + 100 + 0 + + + + 待执行联动 + + + true + + + false + + + false + + + true + + + + + + + + 100 + 0 + + + + 所有联动 + + + true + + + true + + + false + + + true + + + + + + + + + QTableView{ + outline:0px; +} +QTableView::item{ + outline:0px; +} + + + true + + + false + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + false + + + + + + + + + + Qt::Horizontal + + + + + + + 动作列表 + + + + 0 + + + 0 + + + 0 + + + 3 + + + + + QTreeView{ + outline:0px; +} + + + true + + + true + + + true + + + true + + + true + + + false + + + false + + + true + + + + + + + + + + 60 + 16777215 + + + + 终止 + + + + + + + + 60 + 16777215 + + + + 执行 + + + + + + + + 60 + 16777215 + + + + 单步 + + + + + + + + 60 + 16777215 + + + + 暂停 + + + + + + + + + Qt::Vertical + + + + 20 + 183 + + + + + + + + + + + + + + + 0 + + + 9 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 6 + + + 3 + + + 6 + + + 6 + + + 3 + + + + + Qt::Horizontal + + + + 639 + 20 + + + + + + + + 历史列表 + + + + + + + QTableView{ + outline:0px; +} +QTableView::item{ + outline:0px; +} + + + true + + + false + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + 过滤 + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 6 + + + 3 + + + 6 + + + 0 + + + 6 + + + + + 执行详情 + + + + + + + true + + + false + + + true + + + + + + + Qt::Horizontal + + + + 720 + 20 + + + + + + + + + + Qt::Horizontal + + + + 258 + 20 + + + + + + + + 导出 + + + + + + + 打印 + + + + + + + + + + + + + + + + + 16777215 + 16777215 + + + + 联动报告 + + + + 0 + + + 5 + + + 0 + + + 0 + + + + + + 100 + 0 + + + + QListView{ + outline:0px; +} +QListView::item{ + height: 32px; +} + + + true + + + + 联动报告 + + + + 微软雅黑 + false + + + + AlignCenter + + + + + + + + + + + + + + + + CLinkCtrlTreeView + QTreeView +
CLinkCtrlTreeView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkDBInterface.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkDBInterface.cpp index e3c821e8..6d4fb6fd 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkDBInterface.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkDBInterface.cpp @@ -1,638 +1,638 @@ -#include "CLinkDBInterface.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "../../idl_files/LinkageMessage.pb.h" -#include "../../idl_files/RdbServerMessage.pb.h" - -using namespace kbd_dbms; -using namespace kbd_idlfile; - -CLinkDBInterface::CLinkDBInterface() - : m_timer(NULL) -{ -} - -CLinkDBInterface::~CLinkDBInterface() -{ - //slotUnSubScribeLinkList(); - - if(NULL != m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(NULL != m_rtdbAccessEx) - { - delete m_rtdbAccessEx; - } - m_rtdbAccessEx = NULL; - - if(NULL != m_rdbNetApi) - { - delete m_rdbNetApi; - } - m_rdbNetApi = NULL; -} - -void CLinkDBInterface::initDataBase() -{ - //关系库 - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - - //实时库 - m_rtdbAccessEx = new CRdbAccessEx(); - - //网络实时库 - m_rdbNetApi = new CRdbNetApi(); -} - -QString CLinkDBInterface::queryLocationName(const int nLocationID) -{ - QMutexLocker locker(&linkmutex); - QString locationName = QString(); - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("description"); - - CONDINFO conditionName; - conditionName.logicalop = ATTRCOND_AND; - conditionName.relationop = ATTRCOND_EQU; - memcpy(conditionName.name,"location_id", strlen("location_id") ); - conditionName.conditionval = (int32_t)nLocationID; - - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccessEx->select(conditionName, result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - locationName = QString::fromStdString(value.toStdString()); - break; - } - } - } - m_rtdbAccessEx->close(); - return locationName; -} - -/* -QString CLinkDBInterface::queryUserName(const int nUserID) -{ - QMutexLocker locker(&mutex); - QString userName; - std::string strApplicationName = "base"; - std::string strTableName = "rm_user_def"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("perm_name"); - - CONDINFO conditionName; - conditionName.logicalop = ATTRCOND_AND; - conditionName.relationop = ATTRCOND_EQU; - memcpy(conditionName.name, "perm_id", strlen("perm_id")); - conditionName.conditionval = nUserID; - - if(m_rtdbAccessEx->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - userName = QString::fromStdString(value.toStdString()); - break; - } - } - } - m_rtdbAccessEx->close(); - return userName; -} - -*/ -QStringList CLinkDBInterface::queryAllLocationName() -{ - QMutexLocker locker(&linkmutex); - QStringList locationNameList; - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("description"); - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccessEx->select(result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - locationNameList.append(QString::fromStdString(value.toStdString())); - } - } - } - m_rtdbAccessEx->close(); - return locationNameList; -} - -QMap CLinkDBInterface::queryUserIDMap() -{ - QMutexLocker locker(&linkmutex); - QMap userNameMap; - std::string strApplicationName = "base"; - std::string strTableName = "rm_user_def"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("perm_id"); - columns.push_back("perm_alias"); - - if(m_rtdbAccessEx->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType id; - CVarType name; - result.getColumnValue(nIndex, 0, id); - result.getColumnValue(nIndex, 1, name); - userNameMap.insert(id, QString::fromStdString(name.toStdString())); - } - } - } - m_rtdbAccessEx->close(); - return userNameMap; -} - -QString CLinkDBInterface::queryTagName(const QString &strTableName, const QString &strTaginfo) -{ - if(strTaginfo.isEmpty()) - { - return QString(); - } - - QString strTagName; - if(!m_pReadDb->isOpen()) - { - return QString(); - } - QSqlQuery query; - QString sqlQuery = QString("select description from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - strTagName = query.value(0).toString(); - } - } - return strTagName; -} - -QString CLinkDBInterface::queryTagTextName(const QString &strTableName, const QString &strTaginfo) -{ - if(strTaginfo.isEmpty()) - { - return QString(); - } - - QString strTagTextName; - if(!m_pReadDb->isOpen()) - { - return QString(); - } - QSqlQuery query; - QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - strTagTextName = query.value(0).toString(); - } - } - return strTagTextName; -} - -/* -QString CLinkDBInterface::queryStateName(const QString &strStateTextName, const int &nActualValue) -{ - QMutexLocker locker(&mutex); - QString strStateName; - std::string strApplicationName = "base"; - std::string strTableName = "dict_state_text_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - - std::vector vecCondInfo; - CONDINFO conditionName; - conditionName.logicalop = ATTRCOND_AND; - conditionName.relationop = ATTRCOND_EQU; - memcpy(conditionName.name, "state_text_name", strlen("state_text_name")); - conditionName.conditionval = strStateTextName.toStdString(); - vecCondInfo.push_back(conditionName); - - CONDINFO conditionState; - conditionState.logicalop = ATTRCOND_AND; - conditionState.relationop = ATTRCOND_EQU; - memcpy(conditionState.name, "actual_value", strlen("actual_value")); - conditionState.conditionval = nActualValue; - vecCondInfo.push_back(conditionState); - - - kbd_dbms::CRdbQueryResult result; - - std::vector columns; - columns.push_back("display_value"); - - if(m_rtdbAccessEx->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - strStateName = QString::fromStdString(value.toStdString()); - } - } - } - m_rtdbAccessEx->close(); - return strStateName; -} -*/ - -/* -QList CLinkDBInterface::queryRunLinkNodeList() -{ - QList LinkList; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - return LinkList; - } - - kbd_public::SNodeInfo stNodeInfo; - spSysInfo->getLocalNodeInfo(stNodeInfo); - bool res = m_dbInterface->open(); - if(res) - { - //<查询顺控 - QSqlQuery query; - QString sqlLinkQuery = QString("select name, description, seq_type, location_id, timeflag from %1").arg(Link_SETTING); - m_dbInterface->execute(sqlLinkQuery, query); - if(query.isActive()) - { - while(query.next()) - { - QString seqName = query.value(0).toString(); - Link Link; - Link.seqName = seqName; - Link.seqDescription = query.value(1).toString(); - Link.seqType = query.value(2).toInt(); - Link.locationID = query.value(3).toInt(); - Link.location = queryLocationName(Link.locationID); - Link.timeFlag = query.value(4).toULongLong(); - Link.nodeType = E_Node_Link; - LinkList.append(Link); - } - } - } - m_dbInterface->close(); - - return LinkList; -} -*/ - -QList CLinkDBInterface::queryHistoryLinkNodeList(const QDateTime &start, const QDateTime &end) -{ - QMap userMap = queryUserIDMap(); - - QList LinkHistoryList; - if(!m_pReadDb->isOpen()) - { - return LinkHistoryList; - } - QSqlQuery query; - QString sqlQuery = QString( "select " - "%1.linkage_name, " - "%1.time, " - "%1.status, " - "%1.location_id, " - "%1.user_id, " - "%1.linkage_type, " - "%2.description " - "from %1, %2 " - "where %1.linkage_name = %2.name " - "and %1.time >= %3 and %1.time <= %4 " - "order by %1.time desc" ) - .arg(LINK_HISTORY).arg(LINK_SETTING) - .arg( start.toSecsSinceEpoch()).arg( end.toSecsSinceEpoch()); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - LinkHistory info; - info.linkName = query.value(0).toString(); - info.time = query.value(1).toULongLong(); - info.status = query.value(2).toString(); - info.location = queryLocationName(query.value(3).toInt()); - info.userID = query.value(4).toString(); - info.userName = userMap.value(QString(info.userID).toInt()); - info.linkType = query.value(5).toInt(); - info.linkDescription = query.value(6).toString(); - LinkHistoryList.append(info); - } - } - return LinkHistoryList; -} - -QList CLinkDBInterface::queryHistoryFunctionNodeList(const QString &LinkName, const quint64 &LinkTime) -{ - QList functionHistoryList; - if(!m_pReadDb->isOpen()) - { - return functionHistoryList; - } - QSqlQuery query; - QString sqlQuery = QString( "select DISTINCT " - "%1.linkage_name, " - "%1.time, " - "%1.func_name, " - "%1.func_no, " - "%1.relation, " - "%1.status, " - "%1.location_id, " - "%2.description " - "from %1, %2 " - "where %1.func_name = %2.name " - "and %1.linkage_name = '%3' and %1.time = %4 " - "order by %1.func_no asc" ) - .arg(LINK_FUNCTION_HISTORY).arg(LINK_FUNCTION) - .arg( LinkName ).arg( LinkTime ); - - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - FunctionHistory info; - info.linkName = query.value(0).toString(); - info.time = query.value(1).toULongLong(); - info.funcName = query.value(2).toString(); - info.funcNO = query.value(3).toInt(); - info.relation = query.value(4).toInt(); - info.status = query.value(5).toString(); - info.location = queryLocationName(query.value(6).toInt()); - info.funcDescription = query.value(7).toString(); - functionHistoryList.append(info); - } - } - return functionHistoryList; -} - -QList CLinkDBInterface::queryHistoryActionNodeList(const QString &LinkName, const QString &functionName, const quint64 &LinkTime) -{ - QList actionHistoryList; - if(!m_pReadDb->isOpen()) - { - return actionHistoryList; - } - QSqlQuery query; - QString sqlQuery = QString("select DISTINCT \ - %1.linkage_name, \ - %1.time, \ - %1.func_name, \ - %2.description, \ - %1.action_no, \ - %1.action_name, \ - %3.description, \ - %1.status, \ - %1.starttime, \ - %1.stoptime, \ - %1.key_id_tag, \ - %1.targetvalue, \ - %1.location_id, \ - %1.discribe \ - from %1, %2, %3 \ - where %1.linkage_name = '%4' \ - and %1.func_name = '%5' \ - and %1.func_name = %2.name \ - and %1.action_name = %3.name \ - and %1.time = %6 \ - order by %1.action_no asc") - .arg(LINK_ACTION_HISTORY).arg(LINK_FUNCTION).arg(LINK_ACTION).arg(LinkName).arg(functionName).arg(LinkTime); - - m_pReadDb->execute(sqlQuery, query); - - if(query.isActive()) - { - while(query.next()) - { - ActionHistory info; - info.linkName = query.value(0).toString(); - info.time = query.value(1).toULongLong(); - info.funcName = query.value(2).toString(); - info.functionDescription = query.value(3).toString(); - info.actionNO = query.value(4).toInt(); - info.actionName = query.value(5).toString(); - info.actionDescription = query.value(6).toString(); - info.status = query.value(7).toString(); - info.startTime = query.value(8).toULongLong(); - info.stopTime = query.value(9).toULongLong(); - info.KeyIdTag = query.value(10).toString(); - info.targetValue = query.value(11).toInt(); - info.location = queryLocationName(query.value(12).toInt()); - info.description = query.value(13).toString(); - actionHistoryList.append(info); - } - } - return actionHistoryList; -} - - -/* -void CLinkDBInterface::slotSubScribeLinkList(QList listLink) -{ - QMutexLocker locker(&mutex); - if(m_timer != NULL) - { - m_timer->stop(); - } - delete m_timer; - - m_listLink.append(listLink); - m_timer = new QTimer(); - m_timer->setInterval(1000); - connect(m_timer, SIGNAL(timeout()), this, SLOT(updataLinkExecuteState())); - m_timer->start(); -} - -void CLinkDBInterface::slotUnSubScribeLinkList() -{ - QMutexLocker locker(&mutex); - if(m_timer != NULL) - { - m_timer->stop(); - delete m_timer; - } - m_timer = NULL; - m_listLink.clear(); -} -*/ - -/* -void CLinkDBInterface::updataLinkState(QList &listLink) -{ - //query state - QMutexLocker locker(&mutex); - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - kbd_public::SAppInfo appInfo; - spSysInfo->getAppInfoByName(COMAPP, appInfo); - for(int nIndex(0); nIndex < listLink.size(); nIndex++) - { - if(E_Node_Link == listLink.at(nIndex).nodeType) - { - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(listLink.at(nIndex).locationID, stLocationInfo); - m_rdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); - - try - { - kbd_idlfile::RdbQuery query; - query.set_strtablename("Link_running"); - std::string *pStatusColName = query.add_strselectcolnamearr(); - *pStatusColName = "status"; - - kbd_idlfile::RdbCondition *pLinkNodeTypeCondtion = query.add_msgcondition(); - pLinkNodeTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pLinkNodeTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pLinkNodeTypeCondtion->set_strcolumnname("node_type"); - - SVariable *pSeqNodeTypeCondValue = pLinkNodeTypeCondtion->mutable_msgvalue(); - pSeqNodeTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); - pSeqNodeTypeCondValue->set_nvalue((int)E_Node_Link); - - kbd_idlfile::RdbCondition *pLinkNameCondtion = query.add_msgcondition(); - pLinkNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pLinkNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pLinkNameCondtion->set_strcolumnname("seq_name"); - - SVariable *pSeqNameCondValue = pLinkNameCondtion->mutable_msgvalue(); - pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pSeqNameCondValue->set_strvalue(listLink.at(nIndex).seqName.toStdString()); - - kbd_idlfile::RdbRet retMsg; - if (m_rdbNetApi->query(query, retMsg)) - { - if(retMsg.msgrecord_size() != 0) - { - - E_EXECUTING_STATE state = (E_EXECUTING_STATE)retMsg.msgrecord(0).msgvaluearray(0).nvalue(); - listLink[nIndex].executeState = state; - } - } - } - catch(...) - { - LOGERROR("updataLinkState [rdbNetApi query exception!]"); - } - } - } - } -} - -void CLinkDBInterface::updataLinkExecuteState() -{ - QMutexLocker locker(&mutex); - if(m_timer) - { - m_timer->stop(); - } - - while(m_rdbNetApi->checkStatus()) - { - kbd_idlfile::RdbRet retMsg; - if (m_rdbNetApi->getRet(&retMsg)) - { - if(retMsg.msgrecord_size() != 0) - { - QString seqName = QString::fromStdString(retMsg.msgrecord(0).msgvaluearray(0).strvalue()); - E_EXECUTING_STATE state = (E_EXECUTING_STATE)retMsg.msgrecord(0).msgvaluearray(1).nvalue(); - emit sigUpdateLinkState(seqName, state); - } - } - } - - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - for(int nIndex(0); nIndex < m_listLink.size(); nIndex++) - { - if(E_Node_Link == m_listLink.at(nIndex).nodeType) - { - if(m_listLink.at(nIndex).nodeType != E_Node_Link) - { - continue; - } - - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(m_listLink.at(nIndex).locationID, stLocationInfo); - kbd_public::SAppInfo appInfo; - spSysInfo->getAppInfoByName(COMAPP, appInfo); - m_rdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); - - kbd_idlfile::RdbQuery query; - query.set_strtablename("Link_running"); - - std::string *pSeqColName = query.add_strselectcolnamearr(); - *pSeqColName = "seq_name"; - - std::string *pStatusColName = query.add_strselectcolnamearr(); - *pStatusColName = "status"; - - kbd_idlfile::RdbCondition *pLinkNodeTypeCondtion = query.add_msgcondition(); - pLinkNodeTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pLinkNodeTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pLinkNodeTypeCondtion->set_strcolumnname("node_type"); - - SVariable *pSeqNodeTypeCondValue = pLinkNodeTypeCondtion->mutable_msgvalue(); - pSeqNodeTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); - pSeqNodeTypeCondValue->set_nvalue((int)E_Node_Link); - - kbd_idlfile::RdbCondition *pLinkNameCondtion = query.add_msgcondition(); - pLinkNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pLinkNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pLinkNameCondtion->set_strcolumnname("seq_name"); - - SVariable *pSeqNameCondValue = pLinkNameCondtion->mutable_msgvalue(); - pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pSeqNameCondValue->set_strvalue(m_listLink.at(nIndex).seqName.toStdString()); - - kbd_idlfile::RdbRet retMsg; - m_rdbNetApi->query(query, retMsg, true); - } - } - } - if(m_timer) - { - m_timer->start(); - } -} -*/ +#include "CLinkDBInterface.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "../../idl_files/LinkageMessage.pb.h" +#include "../../idl_files/RdbServerMessage.pb.h" + +using namespace kbd_dbms; +using namespace kbd_idlfile; + +CLinkDBInterface::CLinkDBInterface() + : m_timer(NULL) +{ +} + +CLinkDBInterface::~CLinkDBInterface() +{ + //slotUnSubScribeLinkList(); + + if(NULL != m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(NULL != m_rtdbAccessEx) + { + delete m_rtdbAccessEx; + } + m_rtdbAccessEx = NULL; + + if(NULL != m_rdbNetApi) + { + delete m_rdbNetApi; + } + m_rdbNetApi = NULL; +} + +void CLinkDBInterface::initDataBase() +{ + //关系库 + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + //实时库 + m_rtdbAccessEx = new CRdbAccessEx(); + + //网络实时库 + m_rdbNetApi = new CRdbNetApi(); +} + +QString CLinkDBInterface::queryLocationName(const int nLocationID) +{ + QMutexLocker locker(&linkmutex); + QString locationName = QString(); + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("description"); + + CONDINFO conditionName; + conditionName.logicalop = ATTRCOND_AND; + conditionName.relationop = ATTRCOND_EQU; + memcpy(conditionName.name,"location_id", strlen("location_id") ); + conditionName.conditionval = (int32_t)nLocationID; + + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccessEx->select(conditionName, result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + locationName = QString::fromStdString(value.toStdString()); + break; + } + } + } + m_rtdbAccessEx->close(); + return locationName; +} + +/* +QString CLinkDBInterface::queryUserName(const int nUserID) +{ + QMutexLocker locker(&mutex); + QString userName; + std::string strApplicationName = "base"; + std::string strTableName = "rm_user_def"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_name"); + + CONDINFO conditionName; + conditionName.logicalop = ATTRCOND_AND; + conditionName.relationop = ATTRCOND_EQU; + memcpy(conditionName.name, "perm_id", strlen("perm_id")); + conditionName.conditionval = nUserID; + + if(m_rtdbAccessEx->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + userName = QString::fromStdString(value.toStdString()); + break; + } + } + } + m_rtdbAccessEx->close(); + return userName; +} + +*/ +QStringList CLinkDBInterface::queryAllLocationName() +{ + QMutexLocker locker(&linkmutex); + QStringList locationNameList; + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("description"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccessEx->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + locationNameList.append(QString::fromStdString(value.toStdString())); + } + } + } + m_rtdbAccessEx->close(); + return locationNameList; +} + +QMap CLinkDBInterface::queryUserIDMap() +{ + QMutexLocker locker(&linkmutex); + QMap userNameMap; + std::string strApplicationName = "base"; + std::string strTableName = "rm_user_def"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_id"); + columns.push_back("perm_alias"); + + if(m_rtdbAccessEx->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType id; + CVarType name; + result.getColumnValue(nIndex, 0, id); + result.getColumnValue(nIndex, 1, name); + userNameMap.insert(id, QString::fromStdString(name.toStdString())); + } + } + } + m_rtdbAccessEx->close(); + return userNameMap; +} + +QString CLinkDBInterface::queryTagName(const QString &strTableName, const QString &strTaginfo) +{ + if(strTaginfo.isEmpty()) + { + return QString(); + } + + QString strTagName; + if(!m_pReadDb->isOpen()) + { + return QString(); + } + QSqlQuery query; + QString sqlQuery = QString("select description from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + strTagName = query.value(0).toString(); + } + } + return strTagName; +} + +QString CLinkDBInterface::queryTagTextName(const QString &strTableName, const QString &strTaginfo) +{ + if(strTaginfo.isEmpty()) + { + return QString(); + } + + QString strTagTextName; + if(!m_pReadDb->isOpen()) + { + return QString(); + } + QSqlQuery query; + QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + strTagTextName = query.value(0).toString(); + } + } + return strTagTextName; +} + +/* +QString CLinkDBInterface::queryStateName(const QString &strStateTextName, const int &nActualValue) +{ + QMutexLocker locker(&mutex); + QString strStateName; + std::string strApplicationName = "base"; + std::string strTableName = "dict_state_text_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + + std::vector vecCondInfo; + CONDINFO conditionName; + conditionName.logicalop = ATTRCOND_AND; + conditionName.relationop = ATTRCOND_EQU; + memcpy(conditionName.name, "state_text_name", strlen("state_text_name")); + conditionName.conditionval = strStateTextName.toStdString(); + vecCondInfo.push_back(conditionName); + + CONDINFO conditionState; + conditionState.logicalop = ATTRCOND_AND; + conditionState.relationop = ATTRCOND_EQU; + memcpy(conditionState.name, "actual_value", strlen("actual_value")); + conditionState.conditionval = nActualValue; + vecCondInfo.push_back(conditionState); + + + kbd_dbms::CRdbQueryResult result; + + std::vector columns; + columns.push_back("display_value"); + + if(m_rtdbAccessEx->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + strStateName = QString::fromStdString(value.toStdString()); + } + } + } + m_rtdbAccessEx->close(); + return strStateName; +} +*/ + +/* +QList CLinkDBInterface::queryRunLinkNodeList() +{ + QList LinkList; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + return LinkList; + } + + kbd_public::SNodeInfo stNodeInfo; + spSysInfo->getLocalNodeInfo(stNodeInfo); + bool res = m_dbInterface->open(); + if(res) + { + //<查询顺控 + QSqlQuery query; + QString sqlLinkQuery = QString("select name, description, seq_type, location_id, timeflag from %1").arg(Link_SETTING); + m_dbInterface->execute(sqlLinkQuery, query); + if(query.isActive()) + { + while(query.next()) + { + QString seqName = query.value(0).toString(); + Link Link; + Link.seqName = seqName; + Link.seqDescription = query.value(1).toString(); + Link.seqType = query.value(2).toInt(); + Link.locationID = query.value(3).toInt(); + Link.location = queryLocationName(Link.locationID); + Link.timeFlag = query.value(4).toULongLong(); + Link.nodeType = E_Node_Link; + LinkList.append(Link); + } + } + } + m_dbInterface->close(); + + return LinkList; +} +*/ + +QList CLinkDBInterface::queryHistoryLinkNodeList(const QDateTime &start, const QDateTime &end) +{ + QMap userMap = queryUserIDMap(); + + QList LinkHistoryList; + if(!m_pReadDb->isOpen()) + { + return LinkHistoryList; + } + QSqlQuery query; + QString sqlQuery = QString( "select " + "%1.linkage_name, " + "%1.time, " + "%1.status, " + "%1.location_id, " + "%1.user_id, " + "%1.linkage_type, " + "%2.description " + "from %1, %2 " + "where %1.linkage_name = %2.name " + "and %1.time >= %3 and %1.time <= %4 " + "order by %1.time desc" ) + .arg(LINK_HISTORY).arg(LINK_SETTING) + .arg( start.toSecsSinceEpoch()).arg( end.toSecsSinceEpoch()); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + LinkHistory info; + info.linkName = query.value(0).toString(); + info.time = query.value(1).toULongLong(); + info.status = query.value(2).toString(); + info.location = queryLocationName(query.value(3).toInt()); + info.userID = query.value(4).toString(); + info.userName = userMap.value(QString(info.userID).toInt()); + info.linkType = query.value(5).toInt(); + info.linkDescription = query.value(6).toString(); + LinkHistoryList.append(info); + } + } + return LinkHistoryList; +} + +QList CLinkDBInterface::queryHistoryFunctionNodeList(const QString &LinkName, const quint64 &LinkTime) +{ + QList functionHistoryList; + if(!m_pReadDb->isOpen()) + { + return functionHistoryList; + } + QSqlQuery query; + QString sqlQuery = QString( "select DISTINCT " + "%1.linkage_name, " + "%1.time, " + "%1.func_name, " + "%1.func_no, " + "%1.relation, " + "%1.status, " + "%1.location_id, " + "%2.description " + "from %1, %2 " + "where %1.func_name = %2.name " + "and %1.linkage_name = '%3' and %1.time = %4 " + "order by %1.func_no asc" ) + .arg(LINK_FUNCTION_HISTORY).arg(LINK_FUNCTION) + .arg( LinkName ).arg( LinkTime ); + + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + FunctionHistory info; + info.linkName = query.value(0).toString(); + info.time = query.value(1).toULongLong(); + info.funcName = query.value(2).toString(); + info.funcNO = query.value(3).toInt(); + info.relation = query.value(4).toInt(); + info.status = query.value(5).toString(); + info.location = queryLocationName(query.value(6).toInt()); + info.funcDescription = query.value(7).toString(); + functionHistoryList.append(info); + } + } + return functionHistoryList; +} + +QList CLinkDBInterface::queryHistoryActionNodeList(const QString &LinkName, const QString &functionName, const quint64 &LinkTime) +{ + QList actionHistoryList; + if(!m_pReadDb->isOpen()) + { + return actionHistoryList; + } + QSqlQuery query; + QString sqlQuery = QString("select DISTINCT \ + %1.linkage_name, \ + %1.time, \ + %1.func_name, \ + %2.description, \ + %1.action_no, \ + %1.action_name, \ + %3.description, \ + %1.status, \ + %1.starttime, \ + %1.stoptime, \ + %1.key_id_tag, \ + %1.targetvalue, \ + %1.location_id, \ + %1.discribe \ + from %1, %2, %3 \ + where %1.linkage_name = '%4' \ + and %1.func_name = '%5' \ + and %1.func_name = %2.name \ + and %1.action_name = %3.name \ + and %1.time = %6 \ + order by %1.action_no asc") + .arg(LINK_ACTION_HISTORY).arg(LINK_FUNCTION).arg(LINK_ACTION).arg(LinkName).arg(functionName).arg(LinkTime); + + m_pReadDb->execute(sqlQuery, query); + + if(query.isActive()) + { + while(query.next()) + { + ActionHistory info; + info.linkName = query.value(0).toString(); + info.time = query.value(1).toULongLong(); + info.funcName = query.value(2).toString(); + info.functionDescription = query.value(3).toString(); + info.actionNO = query.value(4).toInt(); + info.actionName = query.value(5).toString(); + info.actionDescription = query.value(6).toString(); + info.status = query.value(7).toString(); + info.startTime = query.value(8).toULongLong(); + info.stopTime = query.value(9).toULongLong(); + info.KeyIdTag = query.value(10).toString(); + info.targetValue = query.value(11).toInt(); + info.location = queryLocationName(query.value(12).toInt()); + info.description = query.value(13).toString(); + actionHistoryList.append(info); + } + } + return actionHistoryList; +} + + +/* +void CLinkDBInterface::slotSubScribeLinkList(QList listLink) +{ + QMutexLocker locker(&mutex); + if(m_timer != NULL) + { + m_timer->stop(); + } + delete m_timer; + + m_listLink.append(listLink); + m_timer = new QTimer(); + m_timer->setInterval(1000); + connect(m_timer, SIGNAL(timeout()), this, SLOT(updataLinkExecuteState())); + m_timer->start(); +} + +void CLinkDBInterface::slotUnSubScribeLinkList() +{ + QMutexLocker locker(&mutex); + if(m_timer != NULL) + { + m_timer->stop(); + delete m_timer; + } + m_timer = NULL; + m_listLink.clear(); +} +*/ + +/* +void CLinkDBInterface::updataLinkState(QList &listLink) +{ + //query state + QMutexLocker locker(&mutex); + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + kbd_public::SAppInfo appInfo; + spSysInfo->getAppInfoByName(COMAPP, appInfo); + for(int nIndex(0); nIndex < listLink.size(); nIndex++) + { + if(E_Node_Link == listLink.at(nIndex).nodeType) + { + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(listLink.at(nIndex).locationID, stLocationInfo); + m_rdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); + + try + { + kbd_idlfile::RdbQuery query; + query.set_strtablename("Link_running"); + std::string *pStatusColName = query.add_strselectcolnamearr(); + *pStatusColName = "status"; + + kbd_idlfile::RdbCondition *pLinkNodeTypeCondtion = query.add_msgcondition(); + pLinkNodeTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pLinkNodeTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pLinkNodeTypeCondtion->set_strcolumnname("node_type"); + + SVariable *pSeqNodeTypeCondValue = pLinkNodeTypeCondtion->mutable_msgvalue(); + pSeqNodeTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); + pSeqNodeTypeCondValue->set_nvalue((int)E_Node_Link); + + kbd_idlfile::RdbCondition *pLinkNameCondtion = query.add_msgcondition(); + pLinkNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pLinkNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pLinkNameCondtion->set_strcolumnname("seq_name"); + + SVariable *pSeqNameCondValue = pLinkNameCondtion->mutable_msgvalue(); + pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pSeqNameCondValue->set_strvalue(listLink.at(nIndex).seqName.toStdString()); + + kbd_idlfile::RdbRet retMsg; + if (m_rdbNetApi->query(query, retMsg)) + { + if(retMsg.msgrecord_size() != 0) + { + + E_EXECUTING_STATE state = (E_EXECUTING_STATE)retMsg.msgrecord(0).msgvaluearray(0).nvalue(); + listLink[nIndex].executeState = state; + } + } + } + catch(...) + { + LOGERROR("updataLinkState [rdbNetApi query exception!]"); + } + } + } + } +} + +void CLinkDBInterface::updataLinkExecuteState() +{ + QMutexLocker locker(&mutex); + if(m_timer) + { + m_timer->stop(); + } + + while(m_rdbNetApi->checkStatus()) + { + kbd_idlfile::RdbRet retMsg; + if (m_rdbNetApi->getRet(&retMsg)) + { + if(retMsg.msgrecord_size() != 0) + { + QString seqName = QString::fromStdString(retMsg.msgrecord(0).msgvaluearray(0).strvalue()); + E_EXECUTING_STATE state = (E_EXECUTING_STATE)retMsg.msgrecord(0).msgvaluearray(1).nvalue(); + emit sigUpdateLinkState(seqName, state); + } + } + } + + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + for(int nIndex(0); nIndex < m_listLink.size(); nIndex++) + { + if(E_Node_Link == m_listLink.at(nIndex).nodeType) + { + if(m_listLink.at(nIndex).nodeType != E_Node_Link) + { + continue; + } + + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(m_listLink.at(nIndex).locationID, stLocationInfo); + kbd_public::SAppInfo appInfo; + spSysInfo->getAppInfoByName(COMAPP, appInfo); + m_rdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); + + kbd_idlfile::RdbQuery query; + query.set_strtablename("Link_running"); + + std::string *pSeqColName = query.add_strselectcolnamearr(); + *pSeqColName = "seq_name"; + + std::string *pStatusColName = query.add_strselectcolnamearr(); + *pStatusColName = "status"; + + kbd_idlfile::RdbCondition *pLinkNodeTypeCondtion = query.add_msgcondition(); + pLinkNodeTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pLinkNodeTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pLinkNodeTypeCondtion->set_strcolumnname("node_type"); + + SVariable *pSeqNodeTypeCondValue = pLinkNodeTypeCondtion->mutable_msgvalue(); + pSeqNodeTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); + pSeqNodeTypeCondValue->set_nvalue((int)E_Node_Link); + + kbd_idlfile::RdbCondition *pLinkNameCondtion = query.add_msgcondition(); + pLinkNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pLinkNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pLinkNameCondtion->set_strcolumnname("seq_name"); + + SVariable *pSeqNameCondValue = pLinkNameCondtion->mutable_msgvalue(); + pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pSeqNameCondValue->set_strvalue(m_listLink.at(nIndex).seqName.toStdString()); + + kbd_idlfile::RdbRet retMsg; + m_rdbNetApi->query(query, retMsg, true); + } + } + } + if(m_timer) + { + m_timer->start(); + } +} +*/ diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkDBInterface.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkDBInterface.h index 01bfbd42..2ebcc155 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkDBInterface.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkDBInterface.h @@ -1,72 +1,72 @@ -#ifndef CLINKDBINTERFACE_H -#define CLINKDBINTERFACE_H - -#include "link_history_def.h" -#include "linkctrl_def.h" -#include "db_api_ex/CDbApi.h" -#include "dbms/rdb_api/CRdbAccessEx.h" -#include "../dbms/rdb_net_api/CRdbNetApi.h" - -#define COMAPP ("comapp") -#define LINK_SETTING ("linkage_setting") -#define LINK_DEFINE ("linkage_define") -#define LINK_FUNCTION ("linkage_function") -#define LINK_ACTION ("linkage_action") -#define LINK_HISTORY ("linkage_history") -#define LINK_FUNCTION_HISTORY ("linkage_function_history") -#define LINK_ACTION_HISTORY ("linkage_action_event") - -class CLinkDBInterface : public QObject -{ - Q_OBJECT -public: - CLinkDBInterface(); - - ~CLinkDBInterface(); - - void initDataBase(); - - QString queryLocationName(const int nLocationID); - - //QString queryUserName(const int nUserID); - - QStringList queryAllLocationName(); - - QMap queryUserIDMap(); - - QString queryTagName(const QString &strTableName, const QString &strTaginfo); - - QString queryTagTextName(const QString &strTableName, const QString &strTaginfo); - - // QString queryStateName(const QString &strStateTextName, const int &nActualValue); - - //QList queryRunLinkNodeList(); - - QList queryHistoryLinkNodeList(const QDateTime &start, const QDateTime &end); - - QList queryHistoryFunctionNodeList(const QString &linkName, const quint64 &linkTime); - - QList queryHistoryActionNodeList(const QString &linkName, const QString &functionName, const quint64 &linkTime); - - // void slotSubScribeLinkList(QList listLink); - //void slotUnSubScribeLinkList(); - -//signals: - //void sigUpdateLinkState(const QString &linkName, const E_EXECUTING_STATE &state); - -//protected: -// void updataLinkState(QList &listLink); - -protected slots: - // void updataLinkExecuteState(); - -private: - QMutex linkmutex; - QTimer * m_timer; - //QList m_listLink; - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccessEx * m_rtdbAccessEx; - kbd_dbms::CRdbNetApi * m_rdbNetApi; -}; - -#endif // CLINKDBINTERFACE_H +#ifndef CLINKDBINTERFACE_H +#define CLINKDBINTERFACE_H + +#include "link_history_def.h" +#include "linkctrl_def.h" +#include "db_api_ex/CDbApi.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "../dbms/rdb_net_api/CRdbNetApi.h" + +#define COMAPP ("comapp") +#define LINK_SETTING ("linkage_setting") +#define LINK_DEFINE ("linkage_define") +#define LINK_FUNCTION ("linkage_function") +#define LINK_ACTION ("linkage_action") +#define LINK_HISTORY ("linkage_history") +#define LINK_FUNCTION_HISTORY ("linkage_function_history") +#define LINK_ACTION_HISTORY ("linkage_action_event") + +class CLinkDBInterface : public QObject +{ + Q_OBJECT +public: + CLinkDBInterface(); + + ~CLinkDBInterface(); + + void initDataBase(); + + QString queryLocationName(const int nLocationID); + + //QString queryUserName(const int nUserID); + + QStringList queryAllLocationName(); + + QMap queryUserIDMap(); + + QString queryTagName(const QString &strTableName, const QString &strTaginfo); + + QString queryTagTextName(const QString &strTableName, const QString &strTaginfo); + + // QString queryStateName(const QString &strStateTextName, const int &nActualValue); + + //QList queryRunLinkNodeList(); + + QList queryHistoryLinkNodeList(const QDateTime &start, const QDateTime &end); + + QList queryHistoryFunctionNodeList(const QString &linkName, const quint64 &linkTime); + + QList queryHistoryActionNodeList(const QString &linkName, const QString &functionName, const quint64 &linkTime); + + // void slotSubScribeLinkList(QList listLink); + //void slotUnSubScribeLinkList(); + +//signals: + //void sigUpdateLinkState(const QString &linkName, const E_EXECUTING_STATE &state); + +//protected: +// void updataLinkState(QList &listLink); + +protected slots: + // void updataLinkExecuteState(); + +private: + QMutex linkmutex; + QTimer * m_timer; + //QList m_listLink; + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccessEx * m_rtdbAccessEx; + kbd_dbms::CRdbNetApi * m_rdbNetApi; +}; + +#endif // CLINKDBINTERFACE_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApi.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApi.cpp index 54e93dd3..30edf3ca 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApi.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApi.cpp @@ -1,40 +1,40 @@ -#include "application/linkage_server_api/CLinkageForHmiApi.h" -#include "CLinkageForHmiApiImpl.h" - -using namespace kbd_application; - -CLinkageForHmiApi::CLinkageForHmiApi(int appid) -{ - m_pImpl = new CLinkageForHmiApiImpl(appid, this); -} - -CLinkageForHmiApi::~CLinkageForHmiApi() -{ - if (m_pImpl) - { - delete m_pImpl; - m_pImpl = NULL; - } -} - -bool CLinkageForHmiApi::start() -{ - return m_pImpl->start(); -} - -bool CLinkageForHmiApi::stop() -{ - return m_pImpl->stop(); -} - -bool CLinkageForHmiApi::linkOperateRequest( - LinkOperateMessage& msg) -{ - return m_pImpl->linkOperateRequest(msg); -} - -bool CLinkageForHmiApi::userInterveneResponse( - UiRequestMessageAck& msg) -{ - return m_pImpl->userInterveneResponse(msg); +#include "application/linkage_server_api/CLinkageForHmiApi.h" +#include "CLinkageForHmiApiImpl.h" + +using namespace kbd_application; + +CLinkageForHmiApi::CLinkageForHmiApi(int appid) +{ + m_pImpl = new CLinkageForHmiApiImpl(appid, this); +} + +CLinkageForHmiApi::~CLinkageForHmiApi() +{ + if (m_pImpl) + { + delete m_pImpl; + m_pImpl = NULL; + } +} + +bool CLinkageForHmiApi::start() +{ + return m_pImpl->start(); +} + +bool CLinkageForHmiApi::stop() +{ + return m_pImpl->stop(); +} + +bool CLinkageForHmiApi::linkOperateRequest( + LinkOperateMessage& msg) +{ + return m_pImpl->linkOperateRequest(msg); +} + +bool CLinkageForHmiApi::userInterveneResponse( + UiRequestMessageAck& msg) +{ + return m_pImpl->userInterveneResponse(msg); } \ No newline at end of file diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.cpp index 267b58ec..df8d1e35 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.cpp @@ -1,201 +1,201 @@ -#include "public/pub_logger_api/logger.h" -#include "MessageChannel.h" -#include "Common.h" - -#include "CLinkageForHmiApiImpl.h" - -using namespace kbd_application; -using namespace kbd_idlfile::linkage; - -kbd_application::CLinkageForHmiApiImpl::CLinkageForHmiApiImpl( - int appid, - CLinkageForHmiApi* api) : - CTimerThreadBase("CLinkageForHmiApiImpl thread", 100), - m_ptrInterface(api), - m_nServerAppId(appid) -{ -} - -CLinkageForHmiApiImpl::~CLinkageForHmiApiImpl() -{ - this->quit(); -} - -bool CLinkageForHmiApiImpl::start() -{ - this->resume(); - return true; -} - -bool CLinkageForHmiApiImpl::stop() -{ - this->suspend(); - return true; -} - -void CLinkageForHmiApiImpl::afterResume() -{ - LOGINFO("订阅联动服务通道 appid[%d] channel[%d]", - m_nServerAppId, - CH_LINK_TO_HMI_CTRL_UP); - - m_objRecvLinkCMb.addSub( - m_nServerAppId, - CH_LINK_TO_HMI_CTRL_UP); -} - -void CLinkageForHmiApiImpl::afterSuspend() -{ - m_objRecvLinkCMb.delSub( - m_nServerAppId, - CH_LINK_TO_HMI_CTRL_UP); - - LOGINFO("取消订阅联动服务通道 appid[%d] channel[%d]", - m_nServerAppId, - CH_LINK_TO_HMI_CTRL_UP); -} -void CLinkageForHmiApiImpl::execute() -{ - using namespace kbd_idlfile; - if (!m_objRecvLinkCMb.recvMsg(m_objRecvMsg)) - { - return; - } - - recvMsgLink(m_objRecvMsg); -} - -bool CLinkageForHmiApiImpl::recvMsgLink( - kbd_net::CMbMessage& msg) -{ - try { - using namespace kbd_idlfile; - - if (msg.getMsgType() != MT_LINKAGE_CTRL_HMI_UP) - { - LOGERROR("在CH_HMI_TO_LINK_CTRL_DOWN 这个通道中收到 其他类型的消息:[%d]", - msg.getMsgType()); - return false; - } - - LOGINFO("recvMsgLink msgType[%d]", - msg.getMsgType()); - - int msgType = msg.getPara1(); - switch (msgType) - { - case enumStatusMessage: - { - StatusChangeMessage dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - msg.getDataSize())) - { - BOOST_ASSERT(false); - return false; - } - return handleLinkStateChange(dataMsg); - } - break; - case enumLinkStartRequestMessage: - { - LinkStartRequestMessage dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - msg.getDataSize())) - { - BOOST_ASSERT(false); - } - return handleLinkStartRequest(dataMsg); - } - break; - case enumLinkOperateMessageAck: - { - LinkOperateMessageAck dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - msg.getDataSize())) - { - BOOST_ASSERT(false); - } - return handleLinkOperateResponse(dataMsg); - } - break; - case enumUiRequestMessage: - { - UiRequestMessage dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - msg.getDataSize())) - { - BOOST_ASSERT(false); - } - return handleUserInterveneRequest(dataMsg); - } - break; - default: - BOOST_ASSERT(false); - break; - } - } - catch (std::exception &ex) - { - LOGERROR(ex.what()); - return false; - } - - return false; -} - -bool CLinkageForHmiApiImpl::sendToLink(kbd_net::CMbMessage& msg, int domain) -{ - LOGINFO("sendMsgToDomain domain[%d] appid[%d] msgType[%d] Subject[%d]", - domain, - m_nServerAppId, - MT_LINKAGE_CTRL_HMI_DOWN, - CH_HMI_TO_LINK_CTRL_DOWN); - - msg.setMsgType(MT_LINKAGE_CTRL_HMI_DOWN); - msg.setSubject(m_nServerAppId, CH_HMI_TO_LINK_CTRL_DOWN); - return m_objSendLinkCMb.sendMsgToDomain(msg, domain); -} - -bool CLinkageForHmiApiImpl::linkOperateRequest( - LinkOperateMessage& msg) -{ - int domain = msg.pkg_head().target_domain(); - kbd_net::CMbMessage objMessage; - objMessage.setPara1(enumLinkOperateMessage); - objMessage.setData(msg.SerializeAsString()); - return sendToLink(objMessage, domain); -} - -bool CLinkageForHmiApiImpl::userInterveneResponse( - UiRequestMessageAck& msg) -{ - int domain = msg.pkg_head().target_domain(); - kbd_net::CMbMessage objMessage; - objMessage.setPara1(enumUiRequestMessageAck); - objMessage.setData(msg.SerializeAsString()); - return sendToLink(objMessage, domain); -} - -bool CLinkageForHmiApiImpl::handleLinkOperateResponse( - LinkOperateMessageAck& msg) -{ - return m_ptrInterface->handleLinkOperateResponse(msg); -} - -bool CLinkageForHmiApiImpl::handleUserInterveneRequest( - UiRequestMessage& msg) -{ - return m_ptrInterface->handleUserInterveneRequest(msg); -} - -bool CLinkageForHmiApiImpl::handleLinkStartRequest( - LinkStartRequestMessage& msg) -{ - return m_ptrInterface->handleLinkStartRequest(msg); -} - -bool CLinkageForHmiApiImpl::handleLinkStateChange( - StatusChangeMessage& msg) -{ - return m_ptrInterface->handleLinkStateChange(msg); -} +#include "public/pub_logger_api/logger.h" +#include "MessageChannel.h" +#include "Common.h" + +#include "CLinkageForHmiApiImpl.h" + +using namespace kbd_application; +using namespace kbd_idlfile::linkage; + +kbd_application::CLinkageForHmiApiImpl::CLinkageForHmiApiImpl( + int appid, + CLinkageForHmiApi* api) : + CTimerThreadBase("CLinkageForHmiApiImpl thread", 100), + m_ptrInterface(api), + m_nServerAppId(appid) +{ +} + +CLinkageForHmiApiImpl::~CLinkageForHmiApiImpl() +{ + this->quit(); +} + +bool CLinkageForHmiApiImpl::start() +{ + this->resume(); + return true; +} + +bool CLinkageForHmiApiImpl::stop() +{ + this->suspend(); + return true; +} + +void CLinkageForHmiApiImpl::afterResume() +{ + LOGINFO("订阅联动服务通道 appid[%d] channel[%d]", + m_nServerAppId, + CH_LINK_TO_HMI_CTRL_UP); + + m_objRecvLinkCMb.addSub( + m_nServerAppId, + CH_LINK_TO_HMI_CTRL_UP); +} + +void CLinkageForHmiApiImpl::afterSuspend() +{ + m_objRecvLinkCMb.delSub( + m_nServerAppId, + CH_LINK_TO_HMI_CTRL_UP); + + LOGINFO("取消订阅联动服务通道 appid[%d] channel[%d]", + m_nServerAppId, + CH_LINK_TO_HMI_CTRL_UP); +} +void CLinkageForHmiApiImpl::execute() +{ + using namespace kbd_idlfile; + if (!m_objRecvLinkCMb.recvMsg(m_objRecvMsg)) + { + return; + } + + recvMsgLink(m_objRecvMsg); +} + +bool CLinkageForHmiApiImpl::recvMsgLink( + kbd_net::CMbMessage& msg) +{ + try { + using namespace kbd_idlfile; + + if (msg.getMsgType() != MT_LINKAGE_CTRL_HMI_UP) + { + LOGERROR("在CH_HMI_TO_LINK_CTRL_DOWN 这个通道中收到 其他类型的消息:[%d]", + msg.getMsgType()); + return false; + } + + LOGINFO("recvMsgLink msgType[%d]", + msg.getMsgType()); + + int msgType = msg.getPara1(); + switch (msgType) + { + case enumStatusMessage: + { + StatusChangeMessage dataMsg; + if (!dataMsg.ParseFromArray(msg.getDataPtr(), + msg.getDataSize())) + { + BOOST_ASSERT(false); + return false; + } + return handleLinkStateChange(dataMsg); + } + break; + case enumLinkStartRequestMessage: + { + LinkStartRequestMessage dataMsg; + if (!dataMsg.ParseFromArray(msg.getDataPtr(), + msg.getDataSize())) + { + BOOST_ASSERT(false); + } + return handleLinkStartRequest(dataMsg); + } + break; + case enumLinkOperateMessageAck: + { + LinkOperateMessageAck dataMsg; + if (!dataMsg.ParseFromArray(msg.getDataPtr(), + msg.getDataSize())) + { + BOOST_ASSERT(false); + } + return handleLinkOperateResponse(dataMsg); + } + break; + case enumUiRequestMessage: + { + UiRequestMessage dataMsg; + if (!dataMsg.ParseFromArray(msg.getDataPtr(), + msg.getDataSize())) + { + BOOST_ASSERT(false); + } + return handleUserInterveneRequest(dataMsg); + } + break; + default: + BOOST_ASSERT(false); + break; + } + } + catch (std::exception &ex) + { + LOGERROR(ex.what()); + return false; + } + + return false; +} + +bool CLinkageForHmiApiImpl::sendToLink(kbd_net::CMbMessage& msg, int domain) +{ + LOGINFO("sendMsgToDomain domain[%d] appid[%d] msgType[%d] Subject[%d]", + domain, + m_nServerAppId, + MT_LINKAGE_CTRL_HMI_DOWN, + CH_HMI_TO_LINK_CTRL_DOWN); + + msg.setMsgType(MT_LINKAGE_CTRL_HMI_DOWN); + msg.setSubject(m_nServerAppId, CH_HMI_TO_LINK_CTRL_DOWN); + return m_objSendLinkCMb.sendMsgToDomain(msg, domain); +} + +bool CLinkageForHmiApiImpl::linkOperateRequest( + LinkOperateMessage& msg) +{ + int domain = msg.pkg_head().target_domain(); + kbd_net::CMbMessage objMessage; + objMessage.setPara1(enumLinkOperateMessage); + objMessage.setData(msg.SerializeAsString()); + return sendToLink(objMessage, domain); +} + +bool CLinkageForHmiApiImpl::userInterveneResponse( + UiRequestMessageAck& msg) +{ + int domain = msg.pkg_head().target_domain(); + kbd_net::CMbMessage objMessage; + objMessage.setPara1(enumUiRequestMessageAck); + objMessage.setData(msg.SerializeAsString()); + return sendToLink(objMessage, domain); +} + +bool CLinkageForHmiApiImpl::handleLinkOperateResponse( + LinkOperateMessageAck& msg) +{ + return m_ptrInterface->handleLinkOperateResponse(msg); +} + +bool CLinkageForHmiApiImpl::handleUserInterveneRequest( + UiRequestMessage& msg) +{ + return m_ptrInterface->handleUserInterveneRequest(msg); +} + +bool CLinkageForHmiApiImpl::handleLinkStartRequest( + LinkStartRequestMessage& msg) +{ + return m_ptrInterface->handleLinkStartRequest(msg); +} + +bool CLinkageForHmiApiImpl::handleLinkStateChange( + StatusChangeMessage& msg) +{ + return m_ptrInterface->handleLinkStateChange(msg); +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.h index 532d32ae..16f08937 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.h @@ -1,63 +1,63 @@ -#ifndef CLINKAGEFORHMIAPIIMPL_H -#define CLINKAGEFORHMIAPIIMPL_H - -#include -#include "pub_utility_api/TimerThreadBase.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "application/linkage_server_api/CLinkageForHmiApi.h" - -namespace kbd_application { - using namespace kbd_idlfile::linkage; - - class CLinkageForHmiApiImpl - : public kbd_public::CTimerThreadBase - { - public: - CLinkageForHmiApiImpl(int appid, CLinkageForHmiApi* api); - ~CLinkageForHmiApiImpl(); - - //开启线程 - bool start(); - - //停止线程 - bool stop(); - - //1 hmi->server 发起的请求联动操作 - bool linkOperateRequest( - LinkOperateMessage& msg); - //2 hmi ->server 人工干预应答 - bool userInterveneResponse( - UiRequestMessageAck& msg); - - protected: - void afterSuspend(); - void afterResume(); - void execute(); - private: - //2 server->hmi 请求联动操作 的 应答 - bool handleLinkOperateResponse( - LinkOperateMessageAck& msg); - //1 server->hmi 发起的人工干预 请求 - bool handleUserInterveneRequest( - UiRequestMessage& msg); - //server->hmi 请求联动操作 应答 server 发起的 半自动请求开始 - bool handleLinkStartRequest( - LinkStartRequestMessage& msg); - //server->hmi 联动状态更新 - bool handleLinkStateChange( - StatusChangeMessage& msg); - - bool sendToLink(kbd_net::CMbMessage& msg, int domain); - - bool recvMsgLink(kbd_net::CMbMessage& msg); - private: - CLinkageForHmiApi* m_ptrInterface; - kbd_net::CMbMessage m_objRecvMsg; - - kbd_net::CMbCommunicator m_objSendLinkCMb;//发送 linkage - kbd_net::CMbCommunicator m_objRecvLinkCMb;//接收 linkage - - const int m_nServerAppId; - }; -} +#ifndef CLINKAGEFORHMIAPIIMPL_H +#define CLINKAGEFORHMIAPIIMPL_H + +#include +#include "pub_utility_api/TimerThreadBase.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "application/linkage_server_api/CLinkageForHmiApi.h" + +namespace kbd_application { + using namespace kbd_idlfile::linkage; + + class CLinkageForHmiApiImpl + : public kbd_public::CTimerThreadBase + { + public: + CLinkageForHmiApiImpl(int appid, CLinkageForHmiApi* api); + ~CLinkageForHmiApiImpl(); + + //开启线程 + bool start(); + + //停止线程 + bool stop(); + + //1 hmi->server 发起的请求联动操作 + bool linkOperateRequest( + LinkOperateMessage& msg); + //2 hmi ->server 人工干预应答 + bool userInterveneResponse( + UiRequestMessageAck& msg); + + protected: + void afterSuspend(); + void afterResume(); + void execute(); + private: + //2 server->hmi 请求联动操作 的 应答 + bool handleLinkOperateResponse( + LinkOperateMessageAck& msg); + //1 server->hmi 发起的人工干预 请求 + bool handleUserInterveneRequest( + UiRequestMessage& msg); + //server->hmi 请求联动操作 应答 server 发起的 半自动请求开始 + bool handleLinkStartRequest( + LinkStartRequestMessage& msg); + //server->hmi 联动状态更新 + bool handleLinkStateChange( + StatusChangeMessage& msg); + + bool sendToLink(kbd_net::CMbMessage& msg, int domain); + + bool recvMsgLink(kbd_net::CMbMessage& msg); + private: + CLinkageForHmiApi* m_ptrInterface; + kbd_net::CMbMessage m_objRecvMsg; + + kbd_net::CMbCommunicator m_objSendLinkCMb;//发送 linkage + kbd_net::CMbCommunicator m_objRecvLinkCMb;//接收 linkage + + const int m_nServerAppId; + }; +} #endif // CLINKAGEFORHMIAPIIMPL_H \ No newline at end of file diff --git a/product/src/gui/plugin/LinkCtrlWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/LinkCtrlWidget/CTableViewPrinter.cpp index e8d0b703..afbf955c 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CTableViewPrinter.cpp @@ -1,122 +1,122 @@ -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include - -CTableViewPrinter::CTableViewPrinter(QTableView *view) - : m_pView(view) -{ - m_pModel = view->model(); -} - -void CTableViewPrinter::print(QPrinter * printer) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - - qreal marginHorizontal = 20; - qreal marginVertical = 20; - - QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); - printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); - - int length = 0; - horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); - for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) - { - length += horizontalHeader->sectionSize(nSection); - } - horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); - - QPainter painter(printer); - - renderHeader(painter); - - int offset = 0; - int currentPage = 0; - int horizontalHeaderHeight = horizontalHeader->height(); - for(int row(0); row < m_pModel->rowCount(); row++) - { - if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) - { - horizontalHeaderHeight = 0; - } - - - if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) - { - printer->newPage(); - currentPage++; - offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - } - - for(int column(0); column < m_pModel->columnCount(); column++) - { - int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - int rowHeight = m_pView->rowHeight(row); - int columnWidth = m_pView->columnWidth(column); - - //< draw item - QStyleOptionViewItem opt; - opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); - painter.save(); - painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); - painter.restore(); - - //< Vertical Line - if(column == 0) - { - QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - //< Horizontal Line - int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; - QPoint left(verticalHeader->width(), rowPosition); - QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); - drawGridLine(&painter, left, right); - - } -} - -void CTableViewPrinter::renderHeader(QPainter &painter) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - for(int column(0); column < horizontalHeader->count(); column++) - { - painter.save(); - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); - painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); - painter.restore(); - } - int columnPosition = horizontalHeader->width() + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); -} - -void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) -{ - painter->save(); - QStyleOptionViewItem opt; - const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); - const QColor gridColor = static_cast(gridHint); - painter->setPen(gridColor); - painter->drawLine(p1, p2); - painter->restore(); -} +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include + +CTableViewPrinter::CTableViewPrinter(QTableView *view) + : m_pView(view) +{ + m_pModel = view->model(); +} + +void CTableViewPrinter::print(QPrinter * printer) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); + printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + + int length = 0; + horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); + for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) + { + length += horizontalHeader->sectionSize(nSection); + } + horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); + + QPainter painter(printer); + + renderHeader(painter); + + int offset = 0; + int currentPage = 0; + int horizontalHeaderHeight = horizontalHeader->height(); + for(int row(0); row < m_pModel->rowCount(); row++) + { + if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) + { + horizontalHeaderHeight = 0; + } + + + if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) + { + printer->newPage(); + currentPage++; + offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + } + + for(int column(0); column < m_pModel->columnCount(); column++) + { + int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + int rowHeight = m_pView->rowHeight(row); + int columnWidth = m_pView->columnWidth(column); + + //< draw item + QStyleOptionViewItem opt; + opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); + painter.save(); + painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); + painter.restore(); + + //< Vertical Line + if(column == 0) + { + QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + //< Horizontal Line + int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; + QPoint left(verticalHeader->width(), rowPosition); + QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); + drawGridLine(&painter, left, right); + + } +} + +void CTableViewPrinter::renderHeader(QPainter &painter) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + for(int column(0); column < horizontalHeader->count(); column++) + { + painter.save(); + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); + painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); + painter.restore(); + } + int columnPosition = horizontalHeader->width() + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); +} + +void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + QStyleOptionViewItem opt; + const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); + const QColor gridColor = static_cast(gridHint); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/CTableViewPrinter.h b/product/src/gui/plugin/LinkCtrlWidget/CTableViewPrinter.h index 82304f16..839198f2 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CTableViewPrinter.h @@ -1,24 +1,24 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H - -class QPointF; -class QPainter; -class QPrinter; -class QTableView; -class QAbstractItemModel; - -class CTableViewPrinter -{ -public: - explicit CTableViewPrinter(QTableView * view); - - void print(QPrinter *printer); - void renderHeader(QPainter &painter); - void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); - -private: - QTableView * m_pView; - QAbstractItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H + +class QPointF; +class QPainter; +class QPrinter; +class QTableView; +class QAbstractItemModel; + +class CTableViewPrinter +{ +public: + explicit CTableViewPrinter(QTableView * view); + + void print(QPrinter *printer); + void renderHeader(QPainter &painter); + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + +private: + QTableView * m_pView; + QAbstractItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/LinkCtrlWidget.pro b/product/src/gui/plugin/LinkCtrlWidget/LinkCtrlWidget.pro index 9bd658f6..0b9702ba 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/LinkCtrlWidget.pro +++ b/product/src/gui/plugin/LinkCtrlWidget/LinkCtrlWidget.pro @@ -1,69 +1,69 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-05-21T16:10:45 -# -#------------------------------------------------- - -QT += core gui sql xml printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = LinkCtrlWidget -CONFIG += plugin - -DEFINES += LINKAGE_SERVER_API_EXPORT - -SOURCES += \ - CLinkCtrlWidget.cpp \ - CLinkCtrlTableModel.cpp \ - CLinkCtrlTreeModel.cpp \ - CLinkCtrlTreeView.cpp \ - CLinkCtrlDataManage.cpp \ - CLinkCtrlMessageHandle.cpp \ - CLinkCtrlPluginWidget.cpp \ - CLinkCtrlStateManage.cpp \ - CLinkageForHmiApi.cpp \ - CLinkageForHmiApiImpl.cpp \ - CLinkDBInterface.cpp \ - CHistroyLinkModel.cpp \ - CHistoryActionModel.cpp \ - CHistoryLinkFilterDialog.cpp \ - CTableViewPrinter.cpp - - -HEADERS += \ - CLinkCtrlWidget.h \ - CLinkCtrlTableModel.h \ - linkctrl_def.h \ - CLinkCtrlTreeModel.h \ - CLinkCtrlTreeView.h \ - CLinkCtrlDataManage.h \ - CLinkCtrlMessageHandle.h \ - CLinkCtrlPluginWidget.h \ - CLinkCtrlStateManage.h \ - CLinkageForHmiApiImpl.h \ - CLinkDBInterface.h \ - CHistoryLinkModel.h \ - link_history_def.h \ - CHistoryActionModel.h \ - CHistoryLinkFilterDialog.h \ - CTableViewPrinter.h \ - ../../../include/application/linkage_server_api/CLinkageApiExport.h \ - ../../../include/application/linkage_server_api/CLinkageForHmiApi.h - - -FORMS += \ - CHistoryLinkFilterDialog.ui \ - CLinkCtrlWidget.ui - -LIBS += -llog4cplus -lboost_system -lboost_thread -lboost_date_time -lprotobuf -lpub_logger_api -lperm_mng_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lrdb_net_api -lpub_sysinfo_api -lnet_msg_bus_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2018-05-21T16:10:45 +# +#------------------------------------------------- + +QT += core gui sql xml printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = LinkCtrlWidget +CONFIG += plugin + +DEFINES += LINKAGE_SERVER_API_EXPORT + +SOURCES += \ + CLinkCtrlWidget.cpp \ + CLinkCtrlTableModel.cpp \ + CLinkCtrlTreeModel.cpp \ + CLinkCtrlTreeView.cpp \ + CLinkCtrlDataManage.cpp \ + CLinkCtrlMessageHandle.cpp \ + CLinkCtrlPluginWidget.cpp \ + CLinkCtrlStateManage.cpp \ + CLinkageForHmiApi.cpp \ + CLinkageForHmiApiImpl.cpp \ + CLinkDBInterface.cpp \ + CHistroyLinkModel.cpp \ + CHistoryActionModel.cpp \ + CHistoryLinkFilterDialog.cpp \ + CTableViewPrinter.cpp + + +HEADERS += \ + CLinkCtrlWidget.h \ + CLinkCtrlTableModel.h \ + linkctrl_def.h \ + CLinkCtrlTreeModel.h \ + CLinkCtrlTreeView.h \ + CLinkCtrlDataManage.h \ + CLinkCtrlMessageHandle.h \ + CLinkCtrlPluginWidget.h \ + CLinkCtrlStateManage.h \ + CLinkageForHmiApiImpl.h \ + CLinkDBInterface.h \ + CHistoryLinkModel.h \ + link_history_def.h \ + CHistoryActionModel.h \ + CHistoryLinkFilterDialog.h \ + CTableViewPrinter.h \ + ../../../include/application/linkage_server_api/CLinkageApiExport.h \ + ../../../include/application/linkage_server_api/CLinkageForHmiApi.h + + +FORMS += \ + CHistoryLinkFilterDialog.ui \ + CLinkCtrlWidget.ui + +LIBS += -llog4cplus -lboost_system -lboost_thread -lboost_date_time -lprotobuf -lpub_logger_api -lperm_mng_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lrdb_net_api -lpub_sysinfo_api -lnet_msg_bus_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/LinkCtrlWidget/link_history_def.h b/product/src/gui/plugin/LinkCtrlWidget/link_history_def.h index 55618bf8..bbf0f4da 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/link_history_def.h +++ b/product/src/gui/plugin/LinkCtrlWidget/link_history_def.h @@ -1,50 +1,50 @@ -#ifndef LINK_HISTORY_DEF_H -#define LINK_HISTORY_DEF_H - -#include - -struct LinkHistory -{ - QString linkName; - QString linkDescription; - quint64 time; - QString status; - QString location; - QString userID; - QString userName; - QString userGroup; - QString hostName; - int linkType; -}; - -struct FunctionHistory -{ - QString linkName; - quint64 time; - QString funcName; - QString funcDescription; - int funcNO; - int relation; - QString status; - QString location; -}; - -struct ActionHistory -{ - QString linkName; - quint64 time; - QString funcName; - QString functionDescription; - int actionNO; - QString actionName; - QString actionDescription; - QString status; - quint64 startTime; - quint64 stopTime; - QString KeyIdTag; - int targetValue; - QString location; - QString description; -}; - -#endif +#ifndef LINK_HISTORY_DEF_H +#define LINK_HISTORY_DEF_H + +#include + +struct LinkHistory +{ + QString linkName; + QString linkDescription; + quint64 time; + QString status; + QString location; + QString userID; + QString userName; + QString userGroup; + QString hostName; + int linkType; +}; + +struct FunctionHistory +{ + QString linkName; + quint64 time; + QString funcName; + QString funcDescription; + int funcNO; + int relation; + QString status; + QString location; +}; + +struct ActionHistory +{ + QString linkName; + quint64 time; + QString funcName; + QString functionDescription; + int actionNO; + QString actionName; + QString actionDescription; + QString status; + quint64 startTime; + quint64 stopTime; + QString KeyIdTag; + int targetValue; + QString location; + QString description; +}; + +#endif diff --git a/product/src/gui/plugin/LinkCtrlWidget/linkctrl_def.h b/product/src/gui/plugin/LinkCtrlWidget/linkctrl_def.h index 7678610a..1cd99b84 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/linkctrl_def.h +++ b/product/src/gui/plugin/LinkCtrlWidget/linkctrl_def.h @@ -1,97 +1,97 @@ -#ifndef LINKCTRL_DEF_H -#define LINKCTRL_DEF_H - -#include - -//<消息类型 -enum E_LCS_MSGTYPE -{ - E_Status_Message = 1, // hmi 联动状态更新 - E_LinkStartRequest_Message, // hmi 联动操作请求 - E_LinkOperate_Message, //lcs hmi发送给联动服务的操作 - E_LinkOperate_MessageAck, //hmi hmi发送给联动服务的操作应答 - E_UiRequest_Message, //<人工干预请求 - E_UiRequest_MessageAck //<人工干预请求 应答 -}; - -//<联动状态 -enum E_LCS_STATUS -{ - E_RESTING_STATUS, //<未执行 - E_RUNNING_STATUS, //<正在执行 - E_TRIGGERED_STATUS, //<已触发 - E_FAILED_STATUS, //<执行失败 - E_SUCCESS_STATUS, //<执行成功 - E_STOP_STATUS, //<执行终止 - E_PAUSE_STATUS, //<执行暂停 - E_SKIP_STATUS, //<执行跳过 - E_INVALID_STATUS //<时标不一致 -}; - -//<联动类型 -enum E_NODE_TYPE -{ - E_Node_LinkCtrl, //<联动 - E_Node_Function, //<功能 - E_Node_Action //<动作 -}; - -//<勾选状态 -enum E_LCS_NodeCheckStatus -{ - E_Node_UnChecked, //<不勾选 - E_Node_PartiallyChecked, //<部分勾选 - E_Node_Checked //<勾选 -}; - -//link操作类型 -enum E_LINK_OPERATETYPE -{ - E_LINK_START, //<联动开始 - E_LINK_STOP, //<联动中止 - E_LINK_PAUSE, //<联动暂停 - E_LINK_CONTINUE, //<联动继续 - E_SES_START, //<单步开始 - E_SES_CONTINUE, //<单步继续 - E_SES_EXECUTE //<正在执行 -}; - -enum E_UIOPERATE_TYPE -{ - E_OP_RETRY = 1, //<重试 - E_OP_STOP, //<终止 - E_OP_SKIP //<跳过 -}; - -enum E_EXEC_TYPE -{ - E_Exec_Auto, //<全自动 - E_Exec_Semi_Auto, //<半自动 - E_Exec_Manua //<手动 -}; - -//<联动、功能、动作定义 -struct S_LINKCTRL_INFO -{ - QString linkageName; //<联动名称 - QString linkageDescription; //<联动描述 - QString funcName; //<功能名 - QString funcDescription; //<功能描述 - QString actionName; //<动作名 - QString actionDescription; //<动作描述 - qint32 actionNo{0}; //<动作序号 - qint32 funcNo{0}; //<功能序号 - qint32 locationID{0}; //<车站 - qint32 nodeType{0}; //节点类型 0 联动节点 1 功能节点 2 动作节点 - qint32 status{E_RESTING_STATUS}; //<执行状态 - qint32 checked{E_Node_Checked}; //<勾选状态 0 不勾选 1部分勾选 2勾选 - quint64 triggerTime{0}; //<触发时间 - quint64 timeFlag{0}; //<时间戳 - qint32 relation{0}; //<串并行方式 0 串 1并 - qint32 linkType{0}; //<联动类型 - qint32 exeType{0}; //<执行方式 0 全自动 1 半自动 2 手动 - qint32 delayTime{0}; //<延迟时间 - qint32 fallStrage{0}; //<失败处理方式 0自动跳过 1人工干预 2 自动终止 3自动重试 -}; - -#endif // LINKCTRL_DEF_H +#ifndef LINKCTRL_DEF_H +#define LINKCTRL_DEF_H + +#include + +//<消息类型 +enum E_LCS_MSGTYPE +{ + E_Status_Message = 1, // hmi 联动状态更新 + E_LinkStartRequest_Message, // hmi 联动操作请求 + E_LinkOperate_Message, //lcs hmi发送给联动服务的操作 + E_LinkOperate_MessageAck, //hmi hmi发送给联动服务的操作应答 + E_UiRequest_Message, //<人工干预请求 + E_UiRequest_MessageAck //<人工干预请求 应答 +}; + +//<联动状态 +enum E_LCS_STATUS +{ + E_RESTING_STATUS, //<未执行 + E_RUNNING_STATUS, //<正在执行 + E_TRIGGERED_STATUS, //<已触发 + E_FAILED_STATUS, //<执行失败 + E_SUCCESS_STATUS, //<执行成功 + E_STOP_STATUS, //<执行终止 + E_PAUSE_STATUS, //<执行暂停 + E_SKIP_STATUS, //<执行跳过 + E_INVALID_STATUS //<时标不一致 +}; + +//<联动类型 +enum E_NODE_TYPE +{ + E_Node_LinkCtrl, //<联动 + E_Node_Function, //<功能 + E_Node_Action //<动作 +}; + +//<勾选状态 +enum E_LCS_NodeCheckStatus +{ + E_Node_UnChecked, //<不勾选 + E_Node_PartiallyChecked, //<部分勾选 + E_Node_Checked //<勾选 +}; + +//link操作类型 +enum E_LINK_OPERATETYPE +{ + E_LINK_START, //<联动开始 + E_LINK_STOP, //<联动中止 + E_LINK_PAUSE, //<联动暂停 + E_LINK_CONTINUE, //<联动继续 + E_SES_START, //<单步开始 + E_SES_CONTINUE, //<单步继续 + E_SES_EXECUTE //<正在执行 +}; + +enum E_UIOPERATE_TYPE +{ + E_OP_RETRY = 1, //<重试 + E_OP_STOP, //<终止 + E_OP_SKIP //<跳过 +}; + +enum E_EXEC_TYPE +{ + E_Exec_Auto, //<全自动 + E_Exec_Semi_Auto, //<半自动 + E_Exec_Manua //<手动 +}; + +//<联动、功能、动作定义 +struct S_LINKCTRL_INFO +{ + QString linkageName; //<联动名称 + QString linkageDescription; //<联动描述 + QString funcName; //<功能名 + QString funcDescription; //<功能描述 + QString actionName; //<动作名 + QString actionDescription; //<动作描述 + qint32 actionNo{0}; //<动作序号 + qint32 funcNo{0}; //<功能序号 + qint32 locationID{0}; //<车站 + qint32 nodeType{0}; //节点类型 0 联动节点 1 功能节点 2 动作节点 + qint32 status{E_RESTING_STATUS}; //<执行状态 + qint32 checked{E_Node_Checked}; //<勾选状态 0 不勾选 1部分勾选 2勾选 + quint64 triggerTime{0}; //<触发时间 + quint64 timeFlag{0}; //<时间戳 + qint32 relation{0}; //<串并行方式 0 串 1并 + qint32 linkType{0}; //<联动类型 + qint32 exeType{0}; //<执行方式 0 全自动 1 半自动 2 手动 + qint32 delayTime{0}; //<延迟时间 + qint32 fallStrage{0}; //<失败处理方式 0自动跳过 1人工干预 2 自动终止 3自动重试 +}; + +#endif // LINKCTRL_DEF_H diff --git a/product/src/gui/plugin/LinkCtrlWidget/main.cpp b/product/src/gui/plugin/LinkCtrlWidget/main.cpp index 6a1a53dd..5f3d2681 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/main.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/main.cpp @@ -1,27 +1,27 @@ -#include "CLinkCtrlWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" - - -int main(int argc, char *argv[]) -{ - - QApplication a(argc, argv); - - - kbd_public::StartLogSystem(NULL, "HMI", "LinkCtrl"); - kbd_net::initMsgBus("Alarm_Client", "1", true); - - { - CLinkCtrlWidget w; - w.initialize(); - w.show(); - a.exec(); - } - - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "CLinkCtrlWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" + + +int main(int argc, char *argv[]) +{ + + QApplication a(argc, argv); + + + kbd_public::StartLogSystem(NULL, "HMI", "LinkCtrl"); + kbd_net::initMsgBus("Alarm_Client", "1", true); + + { + CLinkCtrlWidget w; + w.initialize(); + w.show(); + a.exec(); + } + + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/LoadStatWidget/LoadDefTblWidget.cpp b/product/src/gui/plugin/LoadStatWidget/LoadDefTblWidget.cpp index d88a9710..8c5750a4 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadDefTblWidget.cpp +++ b/product/src/gui/plugin/LoadStatWidget/LoadDefTblWidget.cpp @@ -1,112 +1,112 @@ -#include "LoadDefTblWidget.h" -#include -#include -#include "CustomWidget/kbdselectpointdlg.h" -#include -#include "kbdtabledatamgr.h" -#include "kbdtable.h" -#include "pub_utility_api/FileUtil.h" -#include "kbdpropertydlg.h" -#include "kbdpropertydlg.h" -#include "kbdpropertypanel.h" -#include "kbddbdesign.h" -#include -#include - -CLoadDefTblWidget::CLoadDefTblWidget(QWidget *parent) : - QWidget(parent) -{ - - KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); - - QWidget * widget = this; - QHBoxLayout *hLayout1 = new QHBoxLayout; - hLayout1->setContentsMargins(0, 0, 0, 0); - - hLayout1->addWidget(new QLabel(tr("位置"),this)); - m_cbLocation= new QComboBox; - KbdDbDesign ds; - QString sql = "SELECT * FROM SYS_MODEL_LOCATION_INFO order by LOCATION_NO;"; - ds.getSqlInfoToCombobox(sql,CN_DESC,CN_TAG_NAME,m_cbLocation); - connect(m_cbLocation,&QComboBox::currentTextChanged,this,&CLoadDefTblWidget::onLocationChange); - - QVBoxLayout *vLayout1 = new QVBoxLayout; - vLayout1->setContentsMargins(2, 2, 2, 2); - QToolBar *bar = new QToolBar(widget); - - m_tableTotal = new KbdTable(widget,REWRITE_COMMIT); - bar->setIconSize(QSize(24,24)); - - bar->addAction(QIcon(":/icons/icons/new.png"),tr("添加记录"),this,SLOT(onAddTableTotalRow())); - bar->addAction(QIcon(":/icons/icons/delete.png"),tr("删除记录"),m_tableTotal,SLOT(onRemoveRowNotCommit())); - bar->addAction(QIcon(":/icons/icons/undo.png"),tr("撤销更改"),m_tableTotal,SLOT(onUndo())); - bar->addAction(QIcon(":/icons/icons/save.png"),tr("保存"),this,SLOT(onSaveTableTotal())); - bar->addSeparator(); - bar->addAction(QIcon(":/icons/icons/Excel-export.png"),tr("Excel导出"),m_tableTotal,SLOT(onExcelExport())); - bar->addAction(QIcon(":/icons/icons/Excel-Impor.png"),tr("Excel导入"),this,SLOT(onImportExcel())); - - hLayout1->addWidget(m_cbLocation); - hLayout1->addWidget(bar); - hLayout1->addStretch(); - QWidget *w = new QWidget; - w->setLayout(hLayout1); - vLayout1->addWidget(w); - vLayout1->addWidget(m_tableTotal); - widget->setLayout(vLayout1); - - QString filter = QString("tag_name LIKE '%1%'").arg(m_cbLocation->currentData().toString()); - KbdTableModel *model = KbdTableDataMgr::getInstance()->createModel(Common::createViewName("LOAD_STAT_DEFINE.xml",filter)); - if(model == NULL){ - return; - } - m_tableTotal->setModel(model); -} - -CLoadDefTblWidget::~CLoadDefTblWidget() -{ -} - -void CLoadDefTblWidget::onAddTableTotalRow() -{ - KbdTableModel *model = qobject_cast(m_tableTotal->model()); - if(model == NULL) - return; - - KbdPropertyDlg dlg(false, this); - dlg.panel()->setDisplayRow(model,model->rowCount()); - dlg.panel()->setDotStringPrefix("TAG_NAME",m_cbLocation->currentData().toString()); - if(dlg.exec() == QDialog::Rejected) - return; - - QStringList rowDatas = dlg.panel()->getPropertyData(); - m_tableTotal->onAddRowNotCommit(rowDatas); -} - -void CLoadDefTblWidget::onSaveTableTotal() -{ - KbdTableModel *model = qobject_cast(m_tableTotal->model()); - if(model == NULL) - return; - m_tableTotal->saveWithReWrite(false); - emit onChanged(); -} - -void CLoadDefTblWidget::onImportExcel() -{ - m_tableTotal->onImportExcel(); - emit onChanged(); -} - -void CLoadDefTblWidget::onLocationChange() -{ - KbdTableModel *model = qobject_cast(m_tableTotal->model()); - if(model == NULL) - return; - - QString filter = QString("tag_name LIKE '%1%'").arg(m_cbLocation->currentData().toString()); - model = KbdTableDataMgr::getInstance()->createModel(Common::createViewName("LOAD_STAT_DEFINE.xml",filter)); - if(model == NULL){ - return; - } - m_tableTotal->setModel(model); -} +#include "LoadDefTblWidget.h" +#include +#include +#include "CustomWidget/kbdselectpointdlg.h" +#include +#include "kbdtabledatamgr.h" +#include "kbdtable.h" +#include "pub_utility_api/FileUtil.h" +#include "kbdpropertydlg.h" +#include "kbdpropertydlg.h" +#include "kbdpropertypanel.h" +#include "kbddbdesign.h" +#include +#include + +CLoadDefTblWidget::CLoadDefTblWidget(QWidget *parent) : + QWidget(parent) +{ + + KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); + + QWidget * widget = this; + QHBoxLayout *hLayout1 = new QHBoxLayout; + hLayout1->setContentsMargins(0, 0, 0, 0); + + hLayout1->addWidget(new QLabel(tr("位置"),this)); + m_cbLocation= new QComboBox; + KbdDbDesign ds; + QString sql = "SELECT * FROM SYS_MODEL_LOCATION_INFO order by LOCATION_NO;"; + ds.getSqlInfoToCombobox(sql,CN_DESC,CN_TAG_NAME,m_cbLocation); + connect(m_cbLocation,&QComboBox::currentTextChanged,this,&CLoadDefTblWidget::onLocationChange); + + QVBoxLayout *vLayout1 = new QVBoxLayout; + vLayout1->setContentsMargins(2, 2, 2, 2); + QToolBar *bar = new QToolBar(widget); + + m_tableTotal = new KbdTable(widget,REWRITE_COMMIT); + bar->setIconSize(QSize(24,24)); + + bar->addAction(QIcon(":/icons/icons/new.png"),tr("添加记录"),this,SLOT(onAddTableTotalRow())); + bar->addAction(QIcon(":/icons/icons/delete.png"),tr("删除记录"),m_tableTotal,SLOT(onRemoveRowNotCommit())); + bar->addAction(QIcon(":/icons/icons/undo.png"),tr("撤销更改"),m_tableTotal,SLOT(onUndo())); + bar->addAction(QIcon(":/icons/icons/save.png"),tr("保存"),this,SLOT(onSaveTableTotal())); + bar->addSeparator(); + bar->addAction(QIcon(":/icons/icons/Excel-export.png"),tr("Excel导出"),m_tableTotal,SLOT(onExcelExport())); + bar->addAction(QIcon(":/icons/icons/Excel-Impor.png"),tr("Excel导入"),this,SLOT(onImportExcel())); + + hLayout1->addWidget(m_cbLocation); + hLayout1->addWidget(bar); + hLayout1->addStretch(); + QWidget *w = new QWidget; + w->setLayout(hLayout1); + vLayout1->addWidget(w); + vLayout1->addWidget(m_tableTotal); + widget->setLayout(vLayout1); + + QString filter = QString("tag_name LIKE '%1%'").arg(m_cbLocation->currentData().toString()); + KbdTableModel *model = KbdTableDataMgr::getInstance()->createModel(Common::createViewName("LOAD_STAT_DEFINE.xml",filter)); + if(model == NULL){ + return; + } + m_tableTotal->setModel(model); +} + +CLoadDefTblWidget::~CLoadDefTblWidget() +{ +} + +void CLoadDefTblWidget::onAddTableTotalRow() +{ + KbdTableModel *model = qobject_cast(m_tableTotal->model()); + if(model == NULL) + return; + + KbdPropertyDlg dlg(false, this); + dlg.panel()->setDisplayRow(model,model->rowCount()); + dlg.panel()->setDotStringPrefix("TAG_NAME",m_cbLocation->currentData().toString()); + if(dlg.exec() == QDialog::Rejected) + return; + + QStringList rowDatas = dlg.panel()->getPropertyData(); + m_tableTotal->onAddRowNotCommit(rowDatas); +} + +void CLoadDefTblWidget::onSaveTableTotal() +{ + KbdTableModel *model = qobject_cast(m_tableTotal->model()); + if(model == NULL) + return; + m_tableTotal->saveWithReWrite(false); + emit onChanged(); +} + +void CLoadDefTblWidget::onImportExcel() +{ + m_tableTotal->onImportExcel(); + emit onChanged(); +} + +void CLoadDefTblWidget::onLocationChange() +{ + KbdTableModel *model = qobject_cast(m_tableTotal->model()); + if(model == NULL) + return; + + QString filter = QString("tag_name LIKE '%1%'").arg(m_cbLocation->currentData().toString()); + model = KbdTableDataMgr::getInstance()->createModel(Common::createViewName("LOAD_STAT_DEFINE.xml",filter)); + if(model == NULL){ + return; + } + m_tableTotal->setModel(model); +} diff --git a/product/src/gui/plugin/LoadStatWidget/LoadDefTblWidget.h b/product/src/gui/plugin/LoadStatWidget/LoadDefTblWidget.h index fff12373..12385e39 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadDefTblWidget.h +++ b/product/src/gui/plugin/LoadStatWidget/LoadDefTblWidget.h @@ -1,30 +1,30 @@ -#ifndef LOADDEFTBLWIDGET_H -#define LOADDEFTBLWIDGET_H - -#include - -class KbdTable; -class QComboBox; -class CLoadDefTblWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CLoadDefTblWidget(QWidget *parent = 0); - ~CLoadDefTblWidget(); -signals: - void onChanged(); -private slots: - void onAddTableTotalRow(); - void onSaveTableTotal(); - void onImportExcel(); - void onLocationChange(); -private: - - KbdTable *m_tableTotal; - QComboBox *m_cbLocation; - - -}; - -#endif // LOADDEFTBLWIDGET_H +#ifndef LOADDEFTBLWIDGET_H +#define LOADDEFTBLWIDGET_H + +#include + +class KbdTable; +class QComboBox; +class CLoadDefTblWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CLoadDefTblWidget(QWidget *parent = 0); + ~CLoadDefTblWidget(); +signals: + void onChanged(); +private slots: + void onAddTableTotalRow(); + void onSaveTableTotal(); + void onImportExcel(); + void onLocationChange(); +private: + + KbdTable *m_tableTotal; + QComboBox *m_cbLocation; + + +}; + +#endif // LOADDEFTBLWIDGET_H diff --git a/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.cpp b/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.cpp index 2dab4074..a14f8c04 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.cpp +++ b/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.cpp @@ -1,24 +1,24 @@ -#include "LoadStatPluginWidget.h" -#include - -LoadStatPluginWidget::LoadStatPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -LoadStatPluginWidget::~LoadStatPluginWidget() -{ - -} - -bool LoadStatPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - - return true; -} - - -void LoadStatPluginWidget::release() -{ - -} +#include "LoadStatPluginWidget.h" +#include + +LoadStatPluginWidget::LoadStatPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +LoadStatPluginWidget::~LoadStatPluginWidget() +{ + +} + +bool LoadStatPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + + return true; +} + + +void LoadStatPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.h b/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.h index b0cb66d8..9ec9b4ab 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.h +++ b/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef LOADSTATPLUGINWIDGET_H -#define LOADSTATPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class LoadStatPluginWidget : public QObject,public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - LoadStatPluginWidget(QObject *parent = nullptr); - ~LoadStatPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); - -}; - -#endif // LOADSTATPLUGINWIDGET_H +#ifndef LOADSTATPLUGINWIDGET_H +#define LOADSTATPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class LoadStatPluginWidget : public QObject,public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + LoadStatPluginWidget(QObject *parent = nullptr); + ~LoadStatPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); + +}; + +#endif // LOADSTATPLUGINWIDGET_H diff --git a/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.cpp b/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.cpp index eb99d036..c31da2ff 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.cpp +++ b/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.cpp @@ -1,53 +1,53 @@ -#include "LoadStatWidget.h" -#include "ui_LoadStatWidget.h" -#include -#include -CLoadStatWidget::CLoadStatWidget(QWidget *parent) - : QWidget(parent) - , ui(new Ui::LoadStatWidget) -{ - ui->setupUi(this); - - initUi(); - -} - -CLoadStatWidget::~CLoadStatWidget() -{ - delete ui; -} - -void CLoadStatWidget::initUi() -{ - initTabCfg(); - initTabRealTime(); - initTabHis(); - initTabRisk(); -} - -void CLoadStatWidget::initTabCfg() -{ - QVBoxLayout * lay = new QVBoxLayout; - ui->tab_cfg->setLayout(lay); - - lay->setContentsMargins(0, 0, 0, 0); - m_widDefTbl = new CLoadDefTblWidget; - lay->addWidget(m_widDefTbl); - -} - -void CLoadStatWidget::initTabRealTime() -{ - -} - -void CLoadStatWidget::initTabHis() -{ - -} - -void CLoadStatWidget::initTabRisk() -{ - -} - +#include "LoadStatWidget.h" +#include "ui_LoadStatWidget.h" +#include +#include +CLoadStatWidget::CLoadStatWidget(QWidget *parent) + : QWidget(parent) + , ui(new Ui::LoadStatWidget) +{ + ui->setupUi(this); + + initUi(); + +} + +CLoadStatWidget::~CLoadStatWidget() +{ + delete ui; +} + +void CLoadStatWidget::initUi() +{ + initTabCfg(); + initTabRealTime(); + initTabHis(); + initTabRisk(); +} + +void CLoadStatWidget::initTabCfg() +{ + QVBoxLayout * lay = new QVBoxLayout; + ui->tab_cfg->setLayout(lay); + + lay->setContentsMargins(0, 0, 0, 0); + m_widDefTbl = new CLoadDefTblWidget; + lay->addWidget(m_widDefTbl); + +} + +void CLoadStatWidget::initTabRealTime() +{ + +} + +void CLoadStatWidget::initTabHis() +{ + +} + +void CLoadStatWidget::initTabRisk() +{ + +} + diff --git a/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.h b/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.h index 6152b2d1..eecaccf0 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.h +++ b/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.h @@ -1,30 +1,30 @@ -#ifndef LOADSTATWIDGET_H -#define LOADSTATWIDGET_H - -#include - -QT_BEGIN_NAMESPACE -namespace Ui { class LoadStatWidget; } -QT_END_NAMESPACE - -class CLoadDefTblWidget; -class CLoadStatWidget : public QWidget -{ - Q_OBJECT - -public: - CLoadStatWidget(QWidget *parent = nullptr); - ~CLoadStatWidget(); - -private: - Ui::LoadStatWidget *ui; - CLoadDefTblWidget * m_widDefTbl; - - - void initUi(); - void initTabCfg(); - void initTabRealTime(); - void initTabHis(); - void initTabRisk(); -}; -#endif // LOADSTATWIDGET_H +#ifndef LOADSTATWIDGET_H +#define LOADSTATWIDGET_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class LoadStatWidget; } +QT_END_NAMESPACE + +class CLoadDefTblWidget; +class CLoadStatWidget : public QWidget +{ + Q_OBJECT + +public: + CLoadStatWidget(QWidget *parent = nullptr); + ~CLoadStatWidget(); + +private: + Ui::LoadStatWidget *ui; + CLoadDefTblWidget * m_widDefTbl; + + + void initUi(); + void initTabCfg(); + void initTabRealTime(); + void initTabHis(); + void initTabRisk(); +}; +#endif // LOADSTATWIDGET_H diff --git a/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.pro b/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.pro index f4690620..1c21e91e 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.pro +++ b/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.pro @@ -1,42 +1,42 @@ -QT += core gui charts sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -CONFIG += c++11 - -# You can make your code fail to compile if it uses deprecated APIs. -# In order to do so, uncomment the following line. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -TEMPLATE = lib -#TEMPLATE = app -CONFIG += plugin - -SOURCES += \ - LoadDefTblWidget.cpp \ - LoadStatPluginWidget.cpp \ - main.cpp \ - LoadStatWidget.cpp - -HEADERS += \ - LoadDefTblWidget.h \ - LoadStatPluginWidget.h \ - LoadStatWidget.h - -FORMS += \ - LoadStatWidget.ui - - - -INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx \ - $$PWD/../../../../../platform/src/include/tools/model_table \ - - -LIBS += -lmodel_table -lpub_utility_api -lmodel_common - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +QT += core gui charts sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +TEMPLATE = lib +#TEMPLATE = app +CONFIG += plugin + +SOURCES += \ + LoadDefTblWidget.cpp \ + LoadStatPluginWidget.cpp \ + main.cpp \ + LoadStatWidget.cpp + +HEADERS += \ + LoadDefTblWidget.h \ + LoadStatPluginWidget.h \ + LoadStatWidget.h + +FORMS += \ + LoadStatWidget.ui + + + +INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx \ + $$PWD/../../../../../platform/src/include/tools/model_table \ + + +LIBS += -lmodel_table -lpub_utility_api -lmodel_common + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.ui b/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.ui index d6cf9380..c07d8998 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.ui +++ b/product/src/gui/plugin/LoadStatWidget/LoadStatWidget.ui @@ -1,60 +1,60 @@ - - - LoadStatWidget - - - - 0 - 0 - 800 - 600 - - - - LoadStatWidget - - - - 1 - - - 1 - - - 1 - - - 1 - - - - - 0 - - - - 配置 - - - - - 实时 - - - - - 历史 - - - - - 风险点 - - - - - - - - - + + + LoadStatWidget + + + + 0 + 0 + 800 + 600 + + + + LoadStatWidget + + + + 1 + + + 1 + + + 1 + + + 1 + + + + + 0 + + + + 配置 + + + + + 实时 + + + + + 历史 + + + + + 风险点 + + + + + + + + + diff --git a/product/src/gui/plugin/LoadStatWidget/main.cpp b/product/src/gui/plugin/LoadStatWidget/main.cpp index 52a87ddf..db807460 100644 --- a/product/src/gui/plugin/LoadStatWidget/main.cpp +++ b/product/src/gui/plugin/LoadStatWidget/main.cpp @@ -1,14 +1,14 @@ -#include "LoadStatWidget.h" - -#include -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CLoadStatWidget w; - w.show(); -// CLoadDefTblWidget w; -// w.show(); - return a.exec(); -} +#include "LoadStatWidget.h" + +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CLoadStatWidget w; + w.show(); +// CLoadDefTblWidget w; +// w.show(); + return a.exec(); +} diff --git a/product/src/gui/plugin/MediaWidget/CMediaAVWidget.cpp b/product/src/gui/plugin/MediaWidget/CMediaAVWidget.cpp index 19089479..c2c9d92f 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaAVWidget.cpp +++ b/product/src/gui/plugin/MediaWidget/CMediaAVWidget.cpp @@ -1,353 +1,353 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CMediaAVWidget.h" -#include "ui_CMediaAVWidget.h" -#include "Slider.h" -#include "Renderer.h" -#include "VoiceSlider.h" -#include "CMediaCommon.h" -using namespace QtAV; -CMediaAVWidget::CMediaAVWidget(QWidget *parent) : - QWidget(parent), - m_path(QString()), - m_preview(NULL), - m_voice(30), - ui(new Ui::CMediaAVWidget) -{ - ui->setupUi(this); - m_player = new AVPlayer(this); - m_player->setSpeed(1); - m_player->setRepeat(65535); - QVBoxLayout *vl = new QVBoxLayout(); - setLayout(vl); - m_renderer = new Renderer(this); - m_renderer->show(); - m_renderer->setContentsMargins(0,0,0,0); - Widgets::registerRenderers(); - m_player->setRenderer(m_renderer); - vl->setContentsMargins(0,0,0,0); - - QHBoxLayout *controlLayout = new QHBoxLayout(); - controlLayout->setContentsMargins(10,10,10,10); - m_control = new QWidget(this); - m_control->setMaximumHeight(40); - m_timerSlider = new Slider(m_control); - m_timerSlider->setDisabled(true); - m_timerSlider->setTracking(true); - m_timerSlider->setOrientation(Qt::Horizontal); - m_timerSlider->setMinimum(0); - m_current = new QLabel(m_control); - m_current->setToolTip(tr("current time")); - m_current->setContentsMargins(QMargins(10, 2, 10, 2)); - m_current->setText(QString::fromLatin1("00:00:00")); - m_end = new QLabel(m_control); - m_end->setToolTip(tr("duration")); - m_end->setContentsMargins(QMargins(10, 2, 10, 2)); - m_end->setText(QString::fromLatin1("00:00:00")); - m_play = new QPushButton(m_control); - m_play->setObjectName("play"); - m_pause = new QPushButton(m_control); - m_pause->setObjectName("pause"); - m_play->setFixedSize(20,20); - m_pause->setFixedSize(20,20); - m_play->setHidden(false); - m_pause->setHidden(true); - m_cap = new QToolButton(m_control); - m_cap->setObjectName("m_cap"); - m_cap->setFixedSize(26,26); - m_voiceOpen = new QPushButton(m_control); - m_voiceOpen->setObjectName("m_voiceOpen"); - m_voiceOpen->setFixedSize(26,26); - - m_voiceClose = new QPushButton(m_control); - m_voiceClose->setObjectName("m_voiceClose"); - m_voiceClose->setFixedSize(26,26); - - m_control->setLayout(controlLayout); - controlLayout->addWidget(m_play); - controlLayout->addWidget(m_pause); - controlLayout->addWidget(m_current); - controlLayout->addWidget(m_timerSlider); - controlLayout->addWidget(m_end); - controlLayout->addWidget(m_cap); - controlLayout->addWidget(m_voiceOpen); - controlLayout->addWidget(m_voiceClose); - m_voiceOpen->setHidden(false); - m_voiceClose->setHidden(true); - m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); - - vl->addWidget(m_renderer); - vl->addWidget(m_control); - setCaptureConfig(); - connect(m_timerSlider, SIGNAL(sliderMoved(int)), SLOT(seek(int))); - connect(m_timerSlider, SIGNAL(sliderPressed()), SLOT(seek())); - connect(m_timerSlider, SIGNAL(onLeave()), SLOT(onTimeSliderLeave())); - connect(m_timerSlider, SIGNAL(onHover(int,int)), SLOT(onTimeSliderHover(int,int))); - connect(m_player,&AVPlayer::started,this,&CMediaAVWidget::startPlay); - connect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(onPositionChange(qint64))); - connect(m_renderer,&Renderer::click,this,&CMediaAVWidget::playPause); - connect(m_renderer,&Renderer::avPlay,this,&CMediaAVWidget::play); - connect(m_renderer,&Renderer::ccdPlay,this,&CMediaAVWidget::slotCCDPlay); - connect(m_play,&QPushButton::clicked,this,&CMediaAVWidget::playPause); - connect(m_pause,&QPushButton::clicked,this,&CMediaAVWidget::playPause); - connect(m_cap,&QToolButton::clicked,m_player->videoCapture(),&VideoCapture::capture); - connect(m_voiceOpen,&QPushButton::clicked,this,&CMediaAVWidget::voiceSliderShow); - connect(m_voiceClose,&QPushButton::clicked,this,&CMediaAVWidget::voiceSliderShow); - connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&CMediaAVWidget::slotVoiceClose); - connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&CMediaAVWidget::slotVoiceOpen); -} - -CMediaAVWidget::~CMediaAVWidget() -{ - delete ui; -} - -void CMediaAVWidget::setPath(const QString &path) -{ - m_path = path; - QStringList list = m_path.split("/"); - if(list.size() <= 0) - { - m_name = ""; - return ; - } - QString name = list.at(list.size()-1); - m_name = name.split(".").at(0); -} - -void CMediaAVWidget::play(QString path) -{ - if(m_path.compare(path) == 0) - { - if (!m_player->isPlaying()) { - m_player->play(); - setVoiceNum(); - setShowButton(true); - return; - } - if(m_player->isPaused()) - { - m_player->pause(!m_player->isPaused()); - setShowButton(true); - } - }else - { - setPath(path); - m_player->play(m_path); - setVoiceNum(); - setShowButton(true); - } -} - -void CMediaAVWidget::stop() -{ - if(m_player->isPlaying()) - { - setPath(""); - m_player->stop(); - } -} - -void CMediaAVWidget::setRepeat(int max) -{ - m_player->setRepeat(max); -} - -void CMediaAVWidget::setBarHidden(bool isHidden) -{ - m_control->setHidden(isHidden); -} - -bool CMediaAVWidget::isPlaying() -{ - return m_player->isPlaying(); -} - -void CMediaAVWidget::playPause() -{ - if(m_path.isEmpty()) - { - return ; - } - if (!m_player->isPlaying()) { - m_player->play(); - setShowButton(true); - setVoiceNum(); - return; - } - if(m_player->isPaused()) - { - m_player->pause(false); - setShowButton(true); - }else - { - m_player->pause(true); - setShowButton(false); - } -} - -void CMediaAVWidget::slotCCDPlay(QString path) -{ - emit sigCCDPlay(path); -} - -void CMediaAVWidget::seek() -{ - seek(m_timerSlider->value()); -} - -void CMediaAVWidget::seek(int value) -{ - m_player->setSeekType(AccurateSeek); - m_player->seek((qint64)value); - if (!m_preview) - return; - m_preview->setTimestamp(value); - m_preview->preview(); - m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); - m_preview->resize(160, 90); - m_preview->show(); -} - -void CMediaAVWidget::onTimeSliderHover(int pos, int value) -{ - Q_UNUSED(pos); - const QPoint gpos =QCursor::pos(); - QToolTip::showText(gpos, QTime(0, 0, 0).addMSecs(value).toString(QString::fromLatin1("HH:mm:ss"))); - if (!m_preview) - m_preview = new VideoPreviewWidget(); - - m_preview->setWindowTitle(tr("多媒体")); - m_preview->setFile(m_player->file()); - m_preview->setTimestamp(value); - m_preview->preview(); - const int w = 160; - const int h = 90; - m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); - m_preview->resize(w, h); - m_preview->move(gpos - QPoint(w/2, h)); - m_preview->show(); -} - -void CMediaAVWidget::onTimeSliderLeave() -{ - if (m_preview && m_preview->isVisible()) - m_preview->hide(); -} - -void CMediaAVWidget::voiceSliderShow() -{ - if(m_voiceSlider->getStatus() == false) - { - QPoint gpos =mapToGlobal(m_voiceOpen->pos()); - int x= m_control->pos().y()-52; - m_voiceSlider->move(gpos-QPoint(159,0)+QPoint(0,x)); - m_voiceSlider->show(); - m_voiceSlider->setStatus(true); - }else - { - m_voiceSlider->hide(); - m_voiceSlider->setStatus(false); - } -} - -void CMediaAVWidget::slotVoiceClose(int voice) -{ - //声音范围为0-4 - setShowVoice(false); - m_voice = voice; - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void CMediaAVWidget::slotVoiceOpen(int voice) -{ - //声音范围为0-4 - setShowVoice(true); - m_voice = voice; - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void CMediaAVWidget::startPlay() -{ - m_timerSlider->setMinimum(m_player->mediaStartPosition()); - m_timerSlider->setMaximum(m_player->mediaStopPosition()); - m_timerSlider->setValue(0); - m_timerSlider->setEnabled(m_player->isSeekable()); - m_end->setText(QTime(0, 0, 0).addMSecs(m_player->mediaStopPosition()).toString(QString::fromLatin1("HH:mm:ss"))); -} - -void CMediaAVWidget::onPositionChange(qint64 pos) -{ - if (m_player->isSeekable()) - m_timerSlider->setValue(pos); - - int stopPos = m_player->mediaStopPosition(); - if(stopPos > pos && pos+200 > stopPos) - { - m_player->setPosition(2); - } - - m_current->setText(QTime(0, 0, 0).addMSecs(pos).toString(QString::fromLatin1("HH:mm:ss"))); -} - -void CMediaAVWidget::setShowButton(bool bo) -{ - if(bo) - { - m_play->setHidden(true); - m_pause->setHidden(false); - }else - { - m_pause->setHidden(true); - m_play->setHidden(false); - } -} - -void CMediaAVWidget::setCaptureConfig() -{ - m_player->videoCapture()->setCaptureDir("../../data/Media/cam"); - m_player->videoCapture()->setQuality(100); - - m_player->videoCapture()->setSaveFormat("jpg"); -} - -void CMediaAVWidget::setShowVoice(bool bo) -{ - if(!bo) - { - m_voiceOpen->setHidden(true); - m_voiceClose->setHidden(false); - }else - { - m_voiceOpen->setHidden(false); - m_voiceClose->setHidden(true); - } -} - -void CMediaAVWidget::setVoiceNum() -{ - //声音范围为0-4 - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(m_voice*0.04); - if (ao) - { - ao->setVolume(v); - } -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CMediaAVWidget.h" +#include "ui_CMediaAVWidget.h" +#include "Slider.h" +#include "Renderer.h" +#include "VoiceSlider.h" +#include "CMediaCommon.h" +using namespace QtAV; +CMediaAVWidget::CMediaAVWidget(QWidget *parent) : + QWidget(parent), + m_path(QString()), + m_preview(NULL), + m_voice(30), + ui(new Ui::CMediaAVWidget) +{ + ui->setupUi(this); + m_player = new AVPlayer(this); + m_player->setSpeed(1); + m_player->setRepeat(65535); + QVBoxLayout *vl = new QVBoxLayout(); + setLayout(vl); + m_renderer = new Renderer(this); + m_renderer->show(); + m_renderer->setContentsMargins(0,0,0,0); + Widgets::registerRenderers(); + m_player->setRenderer(m_renderer); + vl->setContentsMargins(0,0,0,0); + + QHBoxLayout *controlLayout = new QHBoxLayout(); + controlLayout->setContentsMargins(10,10,10,10); + m_control = new QWidget(this); + m_control->setMaximumHeight(40); + m_timerSlider = new Slider(m_control); + m_timerSlider->setDisabled(true); + m_timerSlider->setTracking(true); + m_timerSlider->setOrientation(Qt::Horizontal); + m_timerSlider->setMinimum(0); + m_current = new QLabel(m_control); + m_current->setToolTip(tr("current time")); + m_current->setContentsMargins(QMargins(10, 2, 10, 2)); + m_current->setText(QString::fromLatin1("00:00:00")); + m_end = new QLabel(m_control); + m_end->setToolTip(tr("duration")); + m_end->setContentsMargins(QMargins(10, 2, 10, 2)); + m_end->setText(QString::fromLatin1("00:00:00")); + m_play = new QPushButton(m_control); + m_play->setObjectName("play"); + m_pause = new QPushButton(m_control); + m_pause->setObjectName("pause"); + m_play->setFixedSize(20,20); + m_pause->setFixedSize(20,20); + m_play->setHidden(false); + m_pause->setHidden(true); + m_cap = new QToolButton(m_control); + m_cap->setObjectName("m_cap"); + m_cap->setFixedSize(26,26); + m_voiceOpen = new QPushButton(m_control); + m_voiceOpen->setObjectName("m_voiceOpen"); + m_voiceOpen->setFixedSize(26,26); + + m_voiceClose = new QPushButton(m_control); + m_voiceClose->setObjectName("m_voiceClose"); + m_voiceClose->setFixedSize(26,26); + + m_control->setLayout(controlLayout); + controlLayout->addWidget(m_play); + controlLayout->addWidget(m_pause); + controlLayout->addWidget(m_current); + controlLayout->addWidget(m_timerSlider); + controlLayout->addWidget(m_end); + controlLayout->addWidget(m_cap); + controlLayout->addWidget(m_voiceOpen); + controlLayout->addWidget(m_voiceClose); + m_voiceOpen->setHidden(false); + m_voiceClose->setHidden(true); + m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); + + vl->addWidget(m_renderer); + vl->addWidget(m_control); + setCaptureConfig(); + connect(m_timerSlider, SIGNAL(sliderMoved(int)), SLOT(seek(int))); + connect(m_timerSlider, SIGNAL(sliderPressed()), SLOT(seek())); + connect(m_timerSlider, SIGNAL(onLeave()), SLOT(onTimeSliderLeave())); + connect(m_timerSlider, SIGNAL(onHover(int,int)), SLOT(onTimeSliderHover(int,int))); + connect(m_player,&AVPlayer::started,this,&CMediaAVWidget::startPlay); + connect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(onPositionChange(qint64))); + connect(m_renderer,&Renderer::click,this,&CMediaAVWidget::playPause); + connect(m_renderer,&Renderer::avPlay,this,&CMediaAVWidget::play); + connect(m_renderer,&Renderer::ccdPlay,this,&CMediaAVWidget::slotCCDPlay); + connect(m_play,&QPushButton::clicked,this,&CMediaAVWidget::playPause); + connect(m_pause,&QPushButton::clicked,this,&CMediaAVWidget::playPause); + connect(m_cap,&QToolButton::clicked,m_player->videoCapture(),&VideoCapture::capture); + connect(m_voiceOpen,&QPushButton::clicked,this,&CMediaAVWidget::voiceSliderShow); + connect(m_voiceClose,&QPushButton::clicked,this,&CMediaAVWidget::voiceSliderShow); + connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&CMediaAVWidget::slotVoiceClose); + connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&CMediaAVWidget::slotVoiceOpen); +} + +CMediaAVWidget::~CMediaAVWidget() +{ + delete ui; +} + +void CMediaAVWidget::setPath(const QString &path) +{ + m_path = path; + QStringList list = m_path.split("/"); + if(list.size() <= 0) + { + m_name = ""; + return ; + } + QString name = list.at(list.size()-1); + m_name = name.split(".").at(0); +} + +void CMediaAVWidget::play(QString path) +{ + if(m_path.compare(path) == 0) + { + if (!m_player->isPlaying()) { + m_player->play(); + setVoiceNum(); + setShowButton(true); + return; + } + if(m_player->isPaused()) + { + m_player->pause(!m_player->isPaused()); + setShowButton(true); + } + }else + { + setPath(path); + m_player->play(m_path); + setVoiceNum(); + setShowButton(true); + } +} + +void CMediaAVWidget::stop() +{ + if(m_player->isPlaying()) + { + setPath(""); + m_player->stop(); + } +} + +void CMediaAVWidget::setRepeat(int max) +{ + m_player->setRepeat(max); +} + +void CMediaAVWidget::setBarHidden(bool isHidden) +{ + m_control->setHidden(isHidden); +} + +bool CMediaAVWidget::isPlaying() +{ + return m_player->isPlaying(); +} + +void CMediaAVWidget::playPause() +{ + if(m_path.isEmpty()) + { + return ; + } + if (!m_player->isPlaying()) { + m_player->play(); + setShowButton(true); + setVoiceNum(); + return; + } + if(m_player->isPaused()) + { + m_player->pause(false); + setShowButton(true); + }else + { + m_player->pause(true); + setShowButton(false); + } +} + +void CMediaAVWidget::slotCCDPlay(QString path) +{ + emit sigCCDPlay(path); +} + +void CMediaAVWidget::seek() +{ + seek(m_timerSlider->value()); +} + +void CMediaAVWidget::seek(int value) +{ + m_player->setSeekType(AccurateSeek); + m_player->seek((qint64)value); + if (!m_preview) + return; + m_preview->setTimestamp(value); + m_preview->preview(); + m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); + m_preview->resize(160, 90); + m_preview->show(); +} + +void CMediaAVWidget::onTimeSliderHover(int pos, int value) +{ + Q_UNUSED(pos); + const QPoint gpos =QCursor::pos(); + QToolTip::showText(gpos, QTime(0, 0, 0).addMSecs(value).toString(QString::fromLatin1("HH:mm:ss"))); + if (!m_preview) + m_preview = new VideoPreviewWidget(); + + m_preview->setWindowTitle(tr("多媒体")); + m_preview->setFile(m_player->file()); + m_preview->setTimestamp(value); + m_preview->preview(); + const int w = 160; + const int h = 90; + m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); + m_preview->resize(w, h); + m_preview->move(gpos - QPoint(w/2, h)); + m_preview->show(); +} + +void CMediaAVWidget::onTimeSliderLeave() +{ + if (m_preview && m_preview->isVisible()) + m_preview->hide(); +} + +void CMediaAVWidget::voiceSliderShow() +{ + if(m_voiceSlider->getStatus() == false) + { + QPoint gpos =mapToGlobal(m_voiceOpen->pos()); + int x= m_control->pos().y()-52; + m_voiceSlider->move(gpos-QPoint(159,0)+QPoint(0,x)); + m_voiceSlider->show(); + m_voiceSlider->setStatus(true); + }else + { + m_voiceSlider->hide(); + m_voiceSlider->setStatus(false); + } +} + +void CMediaAVWidget::slotVoiceClose(int voice) +{ + //声音范围为0-4 + setShowVoice(false); + m_voice = voice; + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void CMediaAVWidget::slotVoiceOpen(int voice) +{ + //声音范围为0-4 + setShowVoice(true); + m_voice = voice; + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void CMediaAVWidget::startPlay() +{ + m_timerSlider->setMinimum(m_player->mediaStartPosition()); + m_timerSlider->setMaximum(m_player->mediaStopPosition()); + m_timerSlider->setValue(0); + m_timerSlider->setEnabled(m_player->isSeekable()); + m_end->setText(QTime(0, 0, 0).addMSecs(m_player->mediaStopPosition()).toString(QString::fromLatin1("HH:mm:ss"))); +} + +void CMediaAVWidget::onPositionChange(qint64 pos) +{ + if (m_player->isSeekable()) + m_timerSlider->setValue(pos); + + int stopPos = m_player->mediaStopPosition(); + if(stopPos > pos && pos+200 > stopPos) + { + m_player->setPosition(2); + } + + m_current->setText(QTime(0, 0, 0).addMSecs(pos).toString(QString::fromLatin1("HH:mm:ss"))); +} + +void CMediaAVWidget::setShowButton(bool bo) +{ + if(bo) + { + m_play->setHidden(true); + m_pause->setHidden(false); + }else + { + m_pause->setHidden(true); + m_play->setHidden(false); + } +} + +void CMediaAVWidget::setCaptureConfig() +{ + m_player->videoCapture()->setCaptureDir("../../data/Media/cam"); + m_player->videoCapture()->setQuality(100); + + m_player->videoCapture()->setSaveFormat("jpg"); +} + +void CMediaAVWidget::setShowVoice(bool bo) +{ + if(!bo) + { + m_voiceOpen->setHidden(true); + m_voiceClose->setHidden(false); + }else + { + m_voiceOpen->setHidden(false); + m_voiceClose->setHidden(true); + } +} + +void CMediaAVWidget::setVoiceNum() +{ + //声音范围为0-4 + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(m_voice*0.04); + if (ao) + { + ao->setVolume(v); + } +} diff --git a/product/src/gui/plugin/MediaWidget/CMediaAVWidget.h b/product/src/gui/plugin/MediaWidget/CMediaAVWidget.h index 962be121..03e14072 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaAVWidget.h +++ b/product/src/gui/plugin/MediaWidget/CMediaAVWidget.h @@ -1,93 +1,93 @@ -#ifndef CMediaAVWIDGET_H -#define CMediaAVWIDGET_H - -#include -#include -#include -class Slider; -class QPushButton; -class QWidget; -class QLabel; -class QToolButton; -class Renderer; -class VoiceSlider; -namespace Ui { -class CMediaAVWidget; -} - -class CMediaAVWidget : public QWidget -{ - Q_OBJECT - -public: - CMediaAVWidget(QWidget *parent = 0); - ~CMediaAVWidget(); - - bool isPlaying(); - - void setPath(const QString &path); - - void stop(); - - void pause(); - - void setRepeat(int max); - - void setBarHidden(bool isHidden); -signals: - void sigCCDPlay(QString path); -public slots: - void play(QString path); - void playPause(); - void slotCCDPlay(QString path); - - void seek(); - void seek(int value); - - void onTimeSliderHover(int pos, int value); - void onTimeSliderLeave(); - - void voiceSliderShow(); - - void slotVoiceClose(int voice); - - void slotVoiceOpen(int voice); -private slots: - void startPlay(); - void onPositionChange(qint64 pos); -private: - /** - * @brief setShowButton 设置播放暂停按钮 - * @param bo true-播放状态 false-暂停状态 - */ - void setShowButton(bool bo); - - void setCaptureConfig(); - - void setShowVoice(bool bo); - - void setVoiceNum(); - -private: - Ui::CMediaAVWidget *ui; - Renderer* m_renderer; - QtAV::AVPlayer *m_player; - Slider *m_timerSlider; - QWidget *m_control; - - QString m_path; - QString m_name; - QLabel *m_current, *m_end; - QToolButton *m_cap; //抓图 - - QPushButton *m_play; - QPushButton *m_pause; - QPushButton *m_voiceOpen; - QPushButton *m_voiceClose; - VoiceSlider *m_voiceSlider; - //QPushButton *m_voice_0; - QtAV::VideoPreviewWidget *m_preview; - int m_voice; -}; - -#endif // CMediaAVWIDGET_H +#ifndef CMediaAVWIDGET_H +#define CMediaAVWIDGET_H + +#include +#include +#include +class Slider; +class QPushButton; +class QWidget; +class QLabel; +class QToolButton; +class Renderer; +class VoiceSlider; +namespace Ui { +class CMediaAVWidget; +} + +class CMediaAVWidget : public QWidget +{ + Q_OBJECT + +public: + CMediaAVWidget(QWidget *parent = 0); + ~CMediaAVWidget(); + + bool isPlaying(); + + void setPath(const QString &path); + + void stop(); + + void pause(); + + void setRepeat(int max); + + void setBarHidden(bool isHidden); +signals: + void sigCCDPlay(QString path); +public slots: + void play(QString path); + void playPause(); + void slotCCDPlay(QString path); + + void seek(); + void seek(int value); + + void onTimeSliderHover(int pos, int value); + void onTimeSliderLeave(); + + void voiceSliderShow(); + + void slotVoiceClose(int voice); + + void slotVoiceOpen(int voice); +private slots: + void startPlay(); + void onPositionChange(qint64 pos); +private: + /** + * @brief setShowButton 设置播放暂停按钮 + * @param bo true-播放状态 false-暂停状态 + */ + void setShowButton(bool bo); + + void setCaptureConfig(); + + void setShowVoice(bool bo); + + void setVoiceNum(); + +private: + Ui::CMediaAVWidget *ui; + Renderer* m_renderer; + QtAV::AVPlayer *m_player; + Slider *m_timerSlider; + QWidget *m_control; + + QString m_path; + QString m_name; + QLabel *m_current, *m_end; + QToolButton *m_cap; //抓图 + + QPushButton *m_play; + QPushButton *m_pause; + QPushButton *m_voiceOpen; + QPushButton *m_voiceClose; + VoiceSlider *m_voiceSlider; + //QPushButton *m_voice_0; + QtAV::VideoPreviewWidget *m_preview; + int m_voice; +}; + +#endif // CMediaAVWIDGET_H diff --git a/product/src/gui/plugin/MediaWidget/CMediaAVWidget.ui b/product/src/gui/plugin/MediaWidget/CMediaAVWidget.ui index 2edce2dd..efe03e6a 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaAVWidget.ui +++ b/product/src/gui/plugin/MediaWidget/CMediaAVWidget.ui @@ -1,25 +1,25 @@ - - - CMediaAVWidget - - - - 0 - 0 - 533 - 672 - - - - - 0 - 0 - - - - Form - - - - - + + + CMediaAVWidget + + + + 0 + 0 + 533 + 672 + + + + + 0 + 0 + + + + Form + + + + + diff --git a/product/src/gui/plugin/MediaWidget/CMediaCommon.h b/product/src/gui/plugin/MediaWidget/CMediaCommon.h index 992bb132..0632b570 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaCommon.h +++ b/product/src/gui/plugin/MediaWidget/CMediaCommon.h @@ -1,24 +1,24 @@ -#ifndef CMediaLINKCOMMON_H -#define CMediaLINKCOMMON_H - -#include -#include "DataType.h" - -const std::string CN_MediaCtrlWidget = "CMediaLinkCtrlWidget";//当前进程名 - -#define DEV_TYPE "JQR" //设备类型表 - -enum E_Media_FILE_TYPE -{ - E_Media_CCD = 0, //图片 - E_Media_CUT_CCD = 1, //截图 - E_Media_VIDEO = 2, //视频 - -}; -enum E_Media_SORTKEY -{ - E_SORT_TIME = 0, //< 文件 - E_SORT_DEV, //< 设备 - E_SORT_TYPE, //< 类型 -}; -#endif // CMediaLINKCOMMON_H +#ifndef CMediaLINKCOMMON_H +#define CMediaLINKCOMMON_H + +#include +#include "DataType.h" + +const std::string CN_MediaCtrlWidget = "CMediaLinkCtrlWidget";//当前进程名 + +#define DEV_TYPE "JQR" //设备类型表 + +enum E_Media_FILE_TYPE +{ + E_Media_CCD = 0, //图片 + E_Media_CUT_CCD = 1, //截图 + E_Media_VIDEO = 2, //视频 + +}; +enum E_Media_SORTKEY +{ + E_SORT_TIME = 0, //< 文件 + E_SORT_DEV, //< 设备 + E_SORT_TYPE, //< 类型 +}; +#endif // CMediaLINKCOMMON_H diff --git a/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.cpp b/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.cpp index 6e076871..18fdfbde 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.cpp +++ b/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.cpp @@ -1,25 +1,25 @@ -#include "CMediaPluginWidget.h" -#include "CMediaWidget.h" -#include -CMediaPluginWidget::CMediaPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CMediaPluginWidget::~CMediaPluginWidget() -{ - -} - -bool CMediaPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec) -{ - CMediaWidget *pWidget = new CMediaWidget(editMode,parent); - *widget = (QWidget *)pWidget; - *pluginWidget = (IPluginWidget *)pWidget; - return true; -} - -void CMediaPluginWidget::release() -{ - -} +#include "CMediaPluginWidget.h" +#include "CMediaWidget.h" +#include +CMediaPluginWidget::CMediaPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CMediaPluginWidget::~CMediaPluginWidget() +{ + +} + +bool CMediaPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec) +{ + CMediaWidget *pWidget = new CMediaWidget(editMode,parent); + *widget = (QWidget *)pWidget; + *pluginWidget = (IPluginWidget *)pWidget; + return true; +} + +void CMediaPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.h b/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.h index 51f5135e..fe0a7204 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.h +++ b/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.h @@ -1,19 +1,19 @@ -#ifndef CMediaPLUGINWIDGET_H -#define CMediaPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CMediaPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CMediaPluginWidget(QObject *parent = nullptr); - ~CMediaPluginWidget(); - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec); - void release(); -}; - -#endif // CMediaPLUGINWIDGET_H +#ifndef CMediaPLUGINWIDGET_H +#define CMediaPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CMediaPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CMediaPluginWidget(QObject *parent = nullptr); + ~CMediaPluginWidget(); + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec); + void release(); +}; + +#endif // CMediaPLUGINWIDGET_H diff --git a/product/src/gui/plugin/MediaWidget/CMediaWidget.cpp b/product/src/gui/plugin/MediaWidget/CMediaWidget.cpp index a05fb9cd..39d486c3 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaWidget.cpp +++ b/product/src/gui/plugin/MediaWidget/CMediaWidget.cpp @@ -1,106 +1,106 @@ -#include "CMediaWidget.h" -#include "ui_CMediaWidget.h" -#include "CMediaAVWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include "pub_utility_api/FileStyle.h" - -CMediaWidget::CMediaWidget(bool editMode,QWidget *parent) : - QWidget(parent), - m_avWidget(Q_NULLPTR), - m_bEditMode(editMode), - ui(new Ui::CMediaWidget) -{ - if(editMode) - { - QLabel *label = new QLabel(this); - label->setPixmap(QPixmap(":/view")); - label->setScaledContents(true); - QGridLayout *lay = new QGridLayout(this); - lay->addWidget(label); - setLayout(lay); - } - else - { - ui->setupUi(this); - - initView(); - - connect(m_avWidget,&CMediaAVWidget::sigCCDPlay,this,&CMediaWidget::slotCCDPlay,Qt::QueuedConnection); - connect(ui->label,&Label::avPlay,this,&CMediaWidget::slotAvPlay,Qt::QueuedConnection); - connect(ui->label,&Label::ccdPlay,this,&CMediaWidget::slotCCDPlay,Qt::QueuedConnection); - - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("media.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - } -} - -CMediaWidget::~CMediaWidget() -{ - delete ui; -} - - -void CMediaWidget::slotAvPlay(QString path) -{ - ui->stackedWidget->setCurrentIndex(0); - ui->label->clear(); - m_avWidget->play(path); -} - -void CMediaWidget::slotCCDPlay(QString path) -{ - m_avWidget->stop(); - ui->stackedWidget->setCurrentIndex(1); - ui->label->clear(); - ui->label->setStyleSheet("QLabel{image:url("+path+");}"); -} - -void CMediaWidget::setRepeat(int max) -{ - m_avWidget->setRepeat(max); -} - -void CMediaWidget::setBarHidden(bool isHidden) -{ - m_avWidget->setBarHidden(isHidden); -} - -void CMediaWidget::initView() -{ - QGridLayout *avLay = new QGridLayout(ui->avWidget); - m_avWidget = new CMediaAVWidget(this); - avLay->setContentsMargins(0,0,0,0); - avLay->addWidget(m_avWidget); - ui->label->setContentsMargins(0,0,0,0); - - setWindowTitle(tr("多媒体")); - ui->stackedWidget->setCurrentIndex(0); -} +#include "CMediaWidget.h" +#include "ui_CMediaWidget.h" +#include "CMediaAVWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + +CMediaWidget::CMediaWidget(bool editMode,QWidget *parent) : + QWidget(parent), + m_avWidget(Q_NULLPTR), + m_bEditMode(editMode), + ui(new Ui::CMediaWidget) +{ + if(editMode) + { + QLabel *label = new QLabel(this); + label->setPixmap(QPixmap(":/view")); + label->setScaledContents(true); + QGridLayout *lay = new QGridLayout(this); + lay->addWidget(label); + setLayout(lay); + } + else + { + ui->setupUi(this); + + initView(); + + connect(m_avWidget,&CMediaAVWidget::sigCCDPlay,this,&CMediaWidget::slotCCDPlay,Qt::QueuedConnection); + connect(ui->label,&Label::avPlay,this,&CMediaWidget::slotAvPlay,Qt::QueuedConnection); + connect(ui->label,&Label::ccdPlay,this,&CMediaWidget::slotCCDPlay,Qt::QueuedConnection); + + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("media.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + } +} + +CMediaWidget::~CMediaWidget() +{ + delete ui; +} + + +void CMediaWidget::slotAvPlay(QString path) +{ + ui->stackedWidget->setCurrentIndex(0); + ui->label->clear(); + m_avWidget->play(path); +} + +void CMediaWidget::slotCCDPlay(QString path) +{ + m_avWidget->stop(); + ui->stackedWidget->setCurrentIndex(1); + ui->label->clear(); + ui->label->setStyleSheet("QLabel{image:url("+path+");}"); +} + +void CMediaWidget::setRepeat(int max) +{ + m_avWidget->setRepeat(max); +} + +void CMediaWidget::setBarHidden(bool isHidden) +{ + m_avWidget->setBarHidden(isHidden); +} + +void CMediaWidget::initView() +{ + QGridLayout *avLay = new QGridLayout(ui->avWidget); + m_avWidget = new CMediaAVWidget(this); + avLay->setContentsMargins(0,0,0,0); + avLay->addWidget(m_avWidget); + ui->label->setContentsMargins(0,0,0,0); + + setWindowTitle(tr("多媒体")); + ui->stackedWidget->setCurrentIndex(0); +} diff --git a/product/src/gui/plugin/MediaWidget/CMediaWidget.h b/product/src/gui/plugin/MediaWidget/CMediaWidget.h index 1e777ddf..3006c8f5 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaWidget.h +++ b/product/src/gui/plugin/MediaWidget/CMediaWidget.h @@ -1,40 +1,40 @@ -#ifndef CMediaLINKCTRLWIDGET_H -#define CMediaLINKCTRLWIDGET_H - -#include -class CMediaCCDVideoForm; -class CMediaAVWidget; -class CMediaCtrlWidget; -class CMediaCCDVideoItemModel; -class QThread; -class CMediaFileCollect; -class CMediaFileMng; -namespace Ui { -class CMediaWidget; -} - -class CMediaWidget : public QWidget -{ - Q_OBJECT -public: - explicit CMediaWidget(bool editMode = false, QWidget *parent = 0); - ~CMediaWidget(); - - -public slots: - void slotAvPlay(QString path); - void slotCCDPlay(QString path); - void setRepeat(int max); - void setBarHidden(bool isHidden); -private: - void initView(); - -private: - Ui::CMediaWidget *ui; - - CMediaAVWidget * m_avWidget; - - bool m_bEditMode; -}; - -#endif // CMediaLINKCTRLWIDGET_H +#ifndef CMediaLINKCTRLWIDGET_H +#define CMediaLINKCTRLWIDGET_H + +#include +class CMediaCCDVideoForm; +class CMediaAVWidget; +class CMediaCtrlWidget; +class CMediaCCDVideoItemModel; +class QThread; +class CMediaFileCollect; +class CMediaFileMng; +namespace Ui { +class CMediaWidget; +} + +class CMediaWidget : public QWidget +{ + Q_OBJECT +public: + explicit CMediaWidget(bool editMode = false, QWidget *parent = 0); + ~CMediaWidget(); + + +public slots: + void slotAvPlay(QString path); + void slotCCDPlay(QString path); + void setRepeat(int max); + void setBarHidden(bool isHidden); +private: + void initView(); + +private: + Ui::CMediaWidget *ui; + + CMediaAVWidget * m_avWidget; + + bool m_bEditMode; +}; + +#endif // CMediaLINKCTRLWIDGET_H diff --git a/product/src/gui/plugin/MediaWidget/CMediaWidget.ui b/product/src/gui/plugin/MediaWidget/CMediaWidget.ui index 15c81355..09f9cee3 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaWidget.ui +++ b/product/src/gui/plugin/MediaWidget/CMediaWidget.ui @@ -1,115 +1,115 @@ - - - CMediaWidget - - - - 0 - 0 - 972 - 500 - - - - CRobotLinkCtrlWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - 0 - - - 1 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - - - - - - Label - QLabel -
Label.h
-
-
- - -
+ + + CMediaWidget + + + + 0 + 0 + 972 + 500 + + + + CRobotLinkCtrlWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 0 + + + 1 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + + Label + QLabel +
Label.h
+
+
+ + +
diff --git a/product/src/gui/plugin/MediaWidget/Label.cpp b/product/src/gui/plugin/MediaWidget/Label.cpp index b56b3ebe..1a60ab67 100644 --- a/product/src/gui/plugin/MediaWidget/Label.cpp +++ b/product/src/gui/plugin/MediaWidget/Label.cpp @@ -1,29 +1,29 @@ -#include "Label.h" -#include -#include -Label::Label(QWidget *parent): - QLabel(parent) -{ - -} - -void Label::contextMenuEvent(QContextMenuEvent *event) -{ - QMenu menu(this); - QAction * openAction = menu.addAction(tr("打开")); - connect(openAction,&QAction::triggered,[=](){ - QString file = QFileDialog::getOpenFileName(this, tr("打开"),"","Files(*.jpg *.png *.mp4)"); - if (file.isEmpty()) - return; - QFileInfo fileInfo(file); - if(fileInfo.suffix() == "mp4") - { - emit avPlay(file); - }else if(fileInfo.suffix() == "jpg" ||fileInfo.suffix() == "png") - { - emit ccdPlay(file); - } - }); - menu.exec(QCursor::pos()); - QWidget::contextMenuEvent(event); -} +#include "Label.h" +#include +#include +Label::Label(QWidget *parent): + QLabel(parent) +{ + +} + +void Label::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu(this); + QAction * openAction = menu.addAction(tr("打开")); + connect(openAction,&QAction::triggered,[=](){ + QString file = QFileDialog::getOpenFileName(this, tr("打开"),"","Files(*.jpg *.png *.mp4)"); + if (file.isEmpty()) + return; + QFileInfo fileInfo(file); + if(fileInfo.suffix() == "mp4") + { + emit avPlay(file); + }else if(fileInfo.suffix() == "jpg" ||fileInfo.suffix() == "png") + { + emit ccdPlay(file); + } + }); + menu.exec(QCursor::pos()); + QWidget::contextMenuEvent(event); +} diff --git a/product/src/gui/plugin/MediaWidget/Label.h b/product/src/gui/plugin/MediaWidget/Label.h index 9ade896b..5e1b5dc4 100644 --- a/product/src/gui/plugin/MediaWidget/Label.h +++ b/product/src/gui/plugin/MediaWidget/Label.h @@ -1,17 +1,17 @@ -#ifndef LABEL_H -#define LABEL_H - -#include -class Label : public QLabel -{ - Q_OBJECT -public: - Label(QWidget *parent = 0); -signals: - void avPlay(QString file); - void ccdPlay(QString file); -protected: - virtual void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // LABEL_H +#ifndef LABEL_H +#define LABEL_H + +#include +class Label : public QLabel +{ + Q_OBJECT +public: + Label(QWidget *parent = 0); +signals: + void avPlay(QString file); + void ccdPlay(QString file); +protected: + virtual void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // LABEL_H diff --git a/product/src/gui/plugin/MediaWidget/MediaWidget.pro b/product/src/gui/plugin/MediaWidget/MediaWidget.pro index df7bca20..b12d15b7 100644 --- a/product/src/gui/plugin/MediaWidget/MediaWidget.pro +++ b/product/src/gui/plugin/MediaWidget/MediaWidget.pro @@ -1,91 +1,91 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-02-12T08:50:48 -# -#------------------------------------------------- - -QT += core sql printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -TEMPLATE = lib -TARGET = MediaWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -INCLUDEPATH += $$PWD \ - $$PWD/../../../3rd/include/QTAV/ \ - $$PWD/../../../3rd/include/QtAVWidgets/ \ - - -win32-msvc* { - -CONFIG(debug, debug|release) { - LIBS += -lQtAVd1 -lQtAVWidgetsd1 -} -CONFIG(release, debug|release) { - LIBS += -lQtAV1 -lQtAVWidgets1 -} -} - - -linux-g++*{ - LIBS += -lQtAV -lQtAVWidgets -} - -LIBS += -llog4cplus -lboost_system -lboost_filesystem -lpub_logger_api -lpub_utility_api -ldb_sysinfo_api -LIBS += -lboost_system -lboost_chrono - -SOURCES += \ - main.cpp \ - CMediaPluginWidget.cpp \ - CMediaAVWidget.cpp \ - Slider.cpp \ - VoiceSlider.cpp \ - CMediaWidget.cpp \ - Renderer.cpp \ - Label.cpp - -HEADERS += \ - CMediaPluginWidget.h \ - CMediaAVWidget.h \ - Slider.h \ - VoiceSlider.h \ - CMediaCommon.h \ - CMediaWidget.h \ - Renderer.h \ - Label.h - -FORMS += \ - CMediaAVWidget.ui \ - VoiceSlider.ui \ - CMediaWidget.ui - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -#必须在common.pri之后包含 -#------------------------------------------------------------------- -QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri -exists($$QTAV_PRI) { - include($$QTAV_PRI) -}else { - error("FATAL error: can not find qtav.pri") -} - -RESOURCES += \ - resource.qrc +#------------------------------------------------- +# +# Project created by QtCreator 2020-02-12T08:50:48 +# +#------------------------------------------------- + +QT += core sql printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +TEMPLATE = lib +TARGET = MediaWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +INCLUDEPATH += $$PWD \ + $$PWD/../../../3rd/include/QTAV/ \ + $$PWD/../../../3rd/include/QtAVWidgets/ \ + + +win32-msvc* { + +CONFIG(debug, debug|release) { + LIBS += -lQtAVd1 -lQtAVWidgetsd1 +} +CONFIG(release, debug|release) { + LIBS += -lQtAV1 -lQtAVWidgets1 +} +} + + +linux-g++*{ + LIBS += -lQtAV -lQtAVWidgets +} + +LIBS += -llog4cplus -lboost_system -lboost_filesystem -lpub_logger_api -lpub_utility_api -ldb_sysinfo_api +LIBS += -lboost_system -lboost_chrono + +SOURCES += \ + main.cpp \ + CMediaPluginWidget.cpp \ + CMediaAVWidget.cpp \ + Slider.cpp \ + VoiceSlider.cpp \ + CMediaWidget.cpp \ + Renderer.cpp \ + Label.cpp + +HEADERS += \ + CMediaPluginWidget.h \ + CMediaAVWidget.h \ + Slider.h \ + VoiceSlider.h \ + CMediaCommon.h \ + CMediaWidget.h \ + Renderer.h \ + Label.h + +FORMS += \ + CMediaAVWidget.ui \ + VoiceSlider.ui \ + CMediaWidget.ui + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +#必须在common.pri之后包含 +#------------------------------------------------------------------- +QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri +exists($$QTAV_PRI) { + include($$QTAV_PRI) +}else { + error("FATAL error: can not find qtav.pri") +} + +RESOURCES += \ + resource.qrc diff --git a/product/src/gui/plugin/MediaWidget/Renderer.cpp b/product/src/gui/plugin/MediaWidget/Renderer.cpp index 6ae17def..351f40c1 100644 --- a/product/src/gui/plugin/MediaWidget/Renderer.cpp +++ b/product/src/gui/plugin/MediaWidget/Renderer.cpp @@ -1,39 +1,39 @@ -#include "Renderer.h" -#include -#include -Renderer::Renderer(QWidget *parent): - WidgetRenderer(parent) -{ - -} - -void Renderer::mouseReleaseEvent(QMouseEvent *event) -{ - if(event->button() == Qt::LeftButton) - { - emit click(); - } - QWidget::mouseReleaseEvent(event); -} - -void Renderer::contextMenuEvent(QContextMenuEvent *event) -{ - QMenu menu(this); - QAction * openAction = menu.addAction(tr("打开")); - connect(openAction,&QAction::triggered,[=](){ - QString file = QFileDialog::getOpenFileName(this, tr("打开"),"","Files(*.jpg *.png *.mp4)"); - if (file.isEmpty()) - return; - - QFileInfo fileInfo(file); - if(fileInfo.suffix() == "mp4") - { - emit avPlay(file); - }else if(fileInfo.suffix() == "jpg" ||fileInfo.suffix() == "png") - { - emit ccdPlay(file); - } - }); - menu.exec(QCursor::pos()); - QWidget::contextMenuEvent(event); -} +#include "Renderer.h" +#include +#include +Renderer::Renderer(QWidget *parent): + WidgetRenderer(parent) +{ + +} + +void Renderer::mouseReleaseEvent(QMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + emit click(); + } + QWidget::mouseReleaseEvent(event); +} + +void Renderer::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu(this); + QAction * openAction = menu.addAction(tr("打开")); + connect(openAction,&QAction::triggered,[=](){ + QString file = QFileDialog::getOpenFileName(this, tr("打开"),"","Files(*.jpg *.png *.mp4)"); + if (file.isEmpty()) + return; + + QFileInfo fileInfo(file); + if(fileInfo.suffix() == "mp4") + { + emit avPlay(file); + }else if(fileInfo.suffix() == "jpg" ||fileInfo.suffix() == "png") + { + emit ccdPlay(file); + } + }); + menu.exec(QCursor::pos()); + QWidget::contextMenuEvent(event); +} diff --git a/product/src/gui/plugin/MediaWidget/Renderer.h b/product/src/gui/plugin/MediaWidget/Renderer.h index 869d4400..86d2a2ef 100644 --- a/product/src/gui/plugin/MediaWidget/Renderer.h +++ b/product/src/gui/plugin/MediaWidget/Renderer.h @@ -1,22 +1,22 @@ -#ifndef RENDERER_H -#define RENDERER_H -#include -#include -#include - -class Renderer :public QtAV::WidgetRenderer -{ - Q_OBJECT -public: - Renderer(QWidget *parent = 0); -signals: - void click(); - - void ccdPlay(QString file); - void avPlay(QString file); -protected: - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // RENDERER_H +#ifndef RENDERER_H +#define RENDERER_H +#include +#include +#include + +class Renderer :public QtAV::WidgetRenderer +{ + Q_OBJECT +public: + Renderer(QWidget *parent = 0); +signals: + void click(); + + void ccdPlay(QString file); + void avPlay(QString file); +protected: + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // RENDERER_H diff --git a/product/src/gui/plugin/MediaWidget/Slider.cpp b/product/src/gui/plugin/MediaWidget/Slider.cpp index c2ac87fb..13981231 100644 --- a/product/src/gui/plugin/MediaWidget/Slider.cpp +++ b/product/src/gui/plugin/MediaWidget/Slider.cpp @@ -1,116 +1,116 @@ -#include "Slider.h" -#include -#include -#include -#include -#include -Slider::Slider(QWidget *parent): - QSlider(parent) -{ - setOrientation(Qt::Horizontal); - setMouseTracking(true); - setWindowOpacity(0.7); -} - -Slider::~Slider() -{ - -} - -void Slider::enterEvent(QEvent *event) -{ - emit onEnter(); - QSlider::enterEvent(event); -} - -void Slider::leaveEvent(QEvent *event) -{ - emit onLeave(); - QSlider::leaveEvent(event); -} - -void Slider::mouseMoveEvent(QMouseEvent *event) -{ - const int o = style()->pixelMetric(QStyle::PM_SliderLength ) - 1; - int v = QStyle::sliderValueFromPosition(minimum(), maximum(), event->pos().x()-o/2, width()-o, false); - emit onHover(event->x(), v); - QSlider::mouseMoveEvent(event); -} - -void Slider::mousePressEvent(QMouseEvent *event) -{ - qDebug("pressed (%d, %d)", event->pos().x(), event->pos().y()); - if (event->button() == Qt::LeftButton) { - QStyleOptionSlider opt; - initStyleOption(&opt); - const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); - const QPoint center = sliderRect.center() - sliderRect.topLeft(); - // to take half of the slider off for the setSliderPosition call we use the center - topLeft - - if (!sliderRect.contains(event->pos())) { - qDebug("accept"); - event->accept(); - - int v = pixelPosToRangeValue(pick(event->pos() - center)); - setSliderPosition(v); - triggerAction(SliderMove); - setRepeatAction(SliderNoAction); - emit sliderMoved(v);//TODO: ok? - emit sliderPressed(); //TODO: ok? - } else { - QSlider::mousePressEvent(event); - } - } else { - QSlider::mousePressEvent(event); - } -} - -int Slider::pick(const QPoint &pt) const -{ - return orientation() == Qt::Horizontal ? pt.x() : pt.y(); -} - -int Slider::pixelPosToRangeValue(int pos) const -{ - QStyleOptionSlider opt; - initStyleOption(&opt); - QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); - QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); - int sliderMin, sliderMax, sliderLength; - if (orientation() == Qt::Horizontal) { - sliderLength = sr.width(); - sliderMin = gr.x(); - sliderMax = gr.right() - sliderLength + 1; - } else { - sliderLength = sr.height(); - sliderMin = gr.y(); - sliderMax = gr.bottom() - sliderLength + 1; - } - return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, - sliderMax - sliderMin, opt.upsideDown); -} - -void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const -{ - if (!option) - return; - - option->initFrom(this); - option->subControls = QStyle::SC_None; - option->activeSubControls = QStyle::SC_None; - option->orientation = orientation(); - option->maximum = maximum(); - option->minimum = minimum(); - option->tickPosition = (QSlider::TickPosition) tickPosition(); - option->tickInterval = tickInterval(); - option->upsideDown = (orientation() == Qt::Horizontal) ? - (invertedAppearance() != (option->direction == Qt::RightToLeft)) - : (!invertedAppearance()); - option->direction = Qt::LeftToRight; // we use the upsideDown option instead - option->sliderPosition = sliderPosition(); - option->sliderValue = value(); - option->singleStep = singleStep(); - option->pageStep = pageStep(); - if (orientation() == Qt::Horizontal) - option->state |= QStyle::State_Horizontal; -} +#include "Slider.h" +#include +#include +#include +#include +#include +Slider::Slider(QWidget *parent): + QSlider(parent) +{ + setOrientation(Qt::Horizontal); + setMouseTracking(true); + setWindowOpacity(0.7); +} + +Slider::~Slider() +{ + +} + +void Slider::enterEvent(QEvent *event) +{ + emit onEnter(); + QSlider::enterEvent(event); +} + +void Slider::leaveEvent(QEvent *event) +{ + emit onLeave(); + QSlider::leaveEvent(event); +} + +void Slider::mouseMoveEvent(QMouseEvent *event) +{ + const int o = style()->pixelMetric(QStyle::PM_SliderLength ) - 1; + int v = QStyle::sliderValueFromPosition(minimum(), maximum(), event->pos().x()-o/2, width()-o, false); + emit onHover(event->x(), v); + QSlider::mouseMoveEvent(event); +} + +void Slider::mousePressEvent(QMouseEvent *event) +{ + qDebug("pressed (%d, %d)", event->pos().x(), event->pos().y()); + if (event->button() == Qt::LeftButton) { + QStyleOptionSlider opt; + initStyleOption(&opt); + const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + const QPoint center = sliderRect.center() - sliderRect.topLeft(); + // to take half of the slider off for the setSliderPosition call we use the center - topLeft + + if (!sliderRect.contains(event->pos())) { + qDebug("accept"); + event->accept(); + + int v = pixelPosToRangeValue(pick(event->pos() - center)); + setSliderPosition(v); + triggerAction(SliderMove); + setRepeatAction(SliderNoAction); + emit sliderMoved(v);//TODO: ok? + emit sliderPressed(); //TODO: ok? + } else { + QSlider::mousePressEvent(event); + } + } else { + QSlider::mousePressEvent(event); + } +} + +int Slider::pick(const QPoint &pt) const +{ + return orientation() == Qt::Horizontal ? pt.x() : pt.y(); +} + +int Slider::pixelPosToRangeValue(int pos) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt); + QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); + QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + int sliderMin, sliderMax, sliderLength; + if (orientation() == Qt::Horizontal) { + sliderLength = sr.width(); + sliderMin = gr.x(); + sliderMax = gr.right() - sliderLength + 1; + } else { + sliderLength = sr.height(); + sliderMin = gr.y(); + sliderMax = gr.bottom() - sliderLength + 1; + } + return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, + sliderMax - sliderMin, opt.upsideDown); +} + +void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const +{ + if (!option) + return; + + option->initFrom(this); + option->subControls = QStyle::SC_None; + option->activeSubControls = QStyle::SC_None; + option->orientation = orientation(); + option->maximum = maximum(); + option->minimum = minimum(); + option->tickPosition = (QSlider::TickPosition) tickPosition(); + option->tickInterval = tickInterval(); + option->upsideDown = (orientation() == Qt::Horizontal) ? + (invertedAppearance() != (option->direction == Qt::RightToLeft)) + : (!invertedAppearance()); + option->direction = Qt::LeftToRight; // we use the upsideDown option instead + option->sliderPosition = sliderPosition(); + option->sliderValue = value(); + option->singleStep = singleStep(); + option->pageStep = pageStep(); + if (orientation() == Qt::Horizontal) + option->state |= QStyle::State_Horizontal; +} diff --git a/product/src/gui/plugin/MediaWidget/Slider.h b/product/src/gui/plugin/MediaWidget/Slider.h index b72a6f8c..0ce56d6a 100644 --- a/product/src/gui/plugin/MediaWidget/Slider.h +++ b/product/src/gui/plugin/MediaWidget/Slider.h @@ -1,27 +1,27 @@ -#ifndef SLIDER_H -#define SLIDER_H -#include - -class Slider : public QSlider -{ - Q_OBJECT -public: - Slider(QWidget *parent = 0); - ~Slider(); - -signals: - void onEnter(); - void onLeave(); - void onHover(int pos, int value); -protected: - virtual void enterEvent(QEvent *event); - virtual void leaveEvent(QEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - - inline int pick(const QPoint &pt) const; - int pixelPosToRangeValue(int pos) const; - void initStyleOption_Qt430(QStyleOptionSlider *option) const; -}; - -#endif // SLIDER_H +#ifndef SLIDER_H +#define SLIDER_H +#include + +class Slider : public QSlider +{ + Q_OBJECT +public: + Slider(QWidget *parent = 0); + ~Slider(); + +signals: + void onEnter(); + void onLeave(); + void onHover(int pos, int value); +protected: + virtual void enterEvent(QEvent *event); + virtual void leaveEvent(QEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + + inline int pick(const QPoint &pt) const; + int pixelPosToRangeValue(int pos) const; + void initStyleOption_Qt430(QStyleOptionSlider *option) const; +}; + +#endif // SLIDER_H diff --git a/product/src/gui/plugin/MediaWidget/VoiceSlider.cpp b/product/src/gui/plugin/MediaWidget/VoiceSlider.cpp index 79df3689..5edc7320 100644 --- a/product/src/gui/plugin/MediaWidget/VoiceSlider.cpp +++ b/product/src/gui/plugin/MediaWidget/VoiceSlider.cpp @@ -1,77 +1,77 @@ -#include "VoiceSlider.h" -#include "ui_VoiceSlider.h" - -VoiceSlider::VoiceSlider(int voice,bool bo, QWidget *parent, Qt::WindowFlags f) : - QWidget(parent,f), - m_bo(bo), - m_isShow(false), - ui(new Ui::VoiceSlider) -{ - ui->setupUi(this); - ui->voiceOpen->setObjectName("m_voiceOpen"); - ui->voiceClose->setObjectName("m_voiceClose"); - m_voice = voice; - setWindowOpacity(0.5); - connect(ui->horizontalSlider,&QSlider::valueChanged,this,&VoiceSlider::slotSetVoice); - connect(ui->voiceOpen,&QPushButton::clicked,this,&VoiceSlider::slotCloseVoice); - connect(ui->voiceClose,&QPushButton::clicked,this,&VoiceSlider::slotOpenVoice); - ui->horizontalSlider->setValue(m_voice); - setButtonShow(m_bo); -} - -VoiceSlider::~VoiceSlider() -{ - delete ui; -} - -void VoiceSlider::slotSetVoice(int value) -{ - ui->label->setText(QString("%1").arg(value)); - m_voice = value; - if(value == 0) - { - setButtonShow(false); - emit sigVoiceClose(value); - }else - { - setButtonShow(true); - emit sigVoiceOpen(value); - } -} - -void VoiceSlider::slotCloseVoice() -{ - setButtonShow(false); - emit sigVoiceClose(0); -} - -void VoiceSlider::slotOpenVoice() -{ - setButtonShow(true); - emit sigVoiceOpen(m_voice); -} - -void VoiceSlider::setStatus(bool show) -{ - m_isShow = show; -} - -bool VoiceSlider::getStatus() -{ - return m_isShow; -} - -void VoiceSlider::setButtonShow(bool show) -{ - if(show) - { - m_bo = show; - ui->voiceOpen->setHidden(false); - ui->voiceClose->setHidden(true); - }else - { - m_bo = !show; - ui->voiceOpen->setHidden(true); - ui->voiceClose->setHidden(false); - } -} +#include "VoiceSlider.h" +#include "ui_VoiceSlider.h" + +VoiceSlider::VoiceSlider(int voice,bool bo, QWidget *parent, Qt::WindowFlags f) : + QWidget(parent,f), + m_bo(bo), + m_isShow(false), + ui(new Ui::VoiceSlider) +{ + ui->setupUi(this); + ui->voiceOpen->setObjectName("m_voiceOpen"); + ui->voiceClose->setObjectName("m_voiceClose"); + m_voice = voice; + setWindowOpacity(0.5); + connect(ui->horizontalSlider,&QSlider::valueChanged,this,&VoiceSlider::slotSetVoice); + connect(ui->voiceOpen,&QPushButton::clicked,this,&VoiceSlider::slotCloseVoice); + connect(ui->voiceClose,&QPushButton::clicked,this,&VoiceSlider::slotOpenVoice); + ui->horizontalSlider->setValue(m_voice); + setButtonShow(m_bo); +} + +VoiceSlider::~VoiceSlider() +{ + delete ui; +} + +void VoiceSlider::slotSetVoice(int value) +{ + ui->label->setText(QString("%1").arg(value)); + m_voice = value; + if(value == 0) + { + setButtonShow(false); + emit sigVoiceClose(value); + }else + { + setButtonShow(true); + emit sigVoiceOpen(value); + } +} + +void VoiceSlider::slotCloseVoice() +{ + setButtonShow(false); + emit sigVoiceClose(0); +} + +void VoiceSlider::slotOpenVoice() +{ + setButtonShow(true); + emit sigVoiceOpen(m_voice); +} + +void VoiceSlider::setStatus(bool show) +{ + m_isShow = show; +} + +bool VoiceSlider::getStatus() +{ + return m_isShow; +} + +void VoiceSlider::setButtonShow(bool show) +{ + if(show) + { + m_bo = show; + ui->voiceOpen->setHidden(false); + ui->voiceClose->setHidden(true); + }else + { + m_bo = !show; + ui->voiceOpen->setHidden(true); + ui->voiceClose->setHidden(false); + } +} diff --git a/product/src/gui/plugin/MediaWidget/VoiceSlider.h b/product/src/gui/plugin/MediaWidget/VoiceSlider.h index 56f01201..ad09d51e 100644 --- a/product/src/gui/plugin/MediaWidget/VoiceSlider.h +++ b/product/src/gui/plugin/MediaWidget/VoiceSlider.h @@ -1,35 +1,35 @@ -#ifndef VOICESLIDER_H -#define VOICESLIDER_H - -#include - -namespace Ui { -class VoiceSlider; -} - -class VoiceSlider : public QWidget -{ - Q_OBJECT - -public: - explicit VoiceSlider(int voice,bool bo,QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); - ~VoiceSlider(); -signals: - void sigVoiceClose(int value); - void sigVoiceOpen(int value); -public: - void slotSetVoice(int value); - void slotCloseVoice(); - void slotOpenVoice(); - void setStatus(bool show); - bool getStatus(); - bool m_isShow; -private: - void setButtonShow(bool show); -private: - Ui::VoiceSlider *ui; - int m_voice; - bool m_bo; -}; - -#endif // VOICESLIDER_H +#ifndef VOICESLIDER_H +#define VOICESLIDER_H + +#include + +namespace Ui { +class VoiceSlider; +} + +class VoiceSlider : public QWidget +{ + Q_OBJECT + +public: + explicit VoiceSlider(int voice,bool bo,QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); + ~VoiceSlider(); +signals: + void sigVoiceClose(int value); + void sigVoiceOpen(int value); +public: + void slotSetVoice(int value); + void slotCloseVoice(); + void slotOpenVoice(); + void setStatus(bool show); + bool getStatus(); + bool m_isShow; +private: + void setButtonShow(bool show); +private: + Ui::VoiceSlider *ui; + int m_voice; + bool m_bo; +}; + +#endif // VOICESLIDER_H diff --git a/product/src/gui/plugin/MediaWidget/VoiceSlider.ui b/product/src/gui/plugin/MediaWidget/VoiceSlider.ui index c6c22443..dc2b07a1 100644 --- a/product/src/gui/plugin/MediaWidget/VoiceSlider.ui +++ b/product/src/gui/plugin/MediaWidget/VoiceSlider.ui @@ -1,125 +1,125 @@ - - - VoiceSlider - - - - 0 - 0 - 194 - 34 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - 26 - - - - - 30 - 16777215 - - - - - - - - - - - - 0 - 26 - - - - - 30 - 16777215 - - - - - - - - - - - Qt::Horizontal - - - - - - - - 30 - 0 - - - - Qt::LeftToRight - - - - - - 53 - - - Qt::AlignCenter - - - - - - - - - - - - - + + + VoiceSlider + + + + 0 + 0 + 194 + 34 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 26 + + + + + 30 + 16777215 + + + + + + + + + + + + 0 + 26 + + + + + 30 + 16777215 + + + + + + + + + + + Qt::Horizontal + + + + + + + + 30 + 0 + + + + Qt::LeftToRight + + + + + + 53 + + + Qt::AlignCenter + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/MediaWidget/main.cpp b/product/src/gui/plugin/MediaWidget/main.cpp index 512d37ef..ec22499e 100644 --- a/product/src/gui/plugin/MediaWidget/main.cpp +++ b/product/src/gui/plugin/MediaWidget/main.cpp @@ -1,24 +1,24 @@ -#include "CMediaWidget.h" -#include -#include "pub_logger_api/logger.h" - -#include "CMediaAVWidget.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - kbd_public::StartLogSystem("", "hmi"); - { - CMediaWidget w(false,NULL); - - QString file = "C:/Users/sjq/Desktop/综合监控录屏和截图/ISCS轨道交通综合监控系统-录制.mp4"; - w.setRepeat(1); - w.slotAvPlay(file); - w.setBarHidden(true); - w.show(); - a.exec(); - } - //<释放消息总线 - kbd_public::StopLogSystem(); - return 0; -} +#include "CMediaWidget.h" +#include +#include "pub_logger_api/logger.h" + +#include "CMediaAVWidget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + kbd_public::StartLogSystem("", "hmi"); + { + CMediaWidget w(false,NULL); + + QString file = "C:/Users/sjq/Desktop/综合监控录屏和截图/ISCS轨道交通综合监控系统-录制.mp4"; + w.setRepeat(1); + w.slotAvPlay(file); + w.setBarHidden(true); + w.show(); + a.exec(); + } + //<释放消息总线 + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/MediaWidget/resource.qrc b/product/src/gui/plugin/MediaWidget/resource.qrc index 00d590c9..115fc542 100644 --- a/product/src/gui/plugin/MediaWidget/resource.qrc +++ b/product/src/gui/plugin/MediaWidget/resource.qrc @@ -1,5 +1,5 @@ - - - view.png - - + + + view.png + + diff --git a/product/src/gui/plugin/NavigationWidget/CColorLabel.cpp b/product/src/gui/plugin/NavigationWidget/CColorLabel.cpp index 1e0f86e7..2033d81c 100644 --- a/product/src/gui/plugin/NavigationWidget/CColorLabel.cpp +++ b/product/src/gui/plugin/NavigationWidget/CColorLabel.cpp @@ -1,49 +1,49 @@ -#include -#include -#include -#include -#include "CColorLabel.h" - -CColorLabel::CColorLabel(QWidget *parent) - : QLabel(parent) -{ - color = Qt::transparent; -} - -const QColor CColorLabel::getColor() const -{ - return color; -} - -void CColorLabel::setColor(const QColor &color) -{ - this->color = color; -} - -void CColorLabel::paintEvent(QPaintEvent *pEvent) -{ - Q_UNUSED(pEvent) - QPainter painter(this); - painter.setPen(Qt::darkGray); - painter.drawRect(rect().adjusted(0, 0, -1, -1)); - - painter.setPen(Qt::white); - painter.setBrush(color); - painter.drawRect(rect().adjusted(1, 1, -2, -2)); -} - -void CColorLabel::mousePressEvent(QMouseEvent *pEvent) -{ - QLabel::mousePressEvent(pEvent); - showColorPickDialog(); -} - -void CColorLabel::showColorPickDialog() -{ - QColor c = QColorDialog::getColor(color, this, QString()); - if(c.isValid()) - { - color = c; - emit colorChanged(color); - } -} +#include +#include +#include +#include +#include "CColorLabel.h" + +CColorLabel::CColorLabel(QWidget *parent) + : QLabel(parent) +{ + color = Qt::transparent; +} + +const QColor CColorLabel::getColor() const +{ + return color; +} + +void CColorLabel::setColor(const QColor &color) +{ + this->color = color; +} + +void CColorLabel::paintEvent(QPaintEvent *pEvent) +{ + Q_UNUSED(pEvent) + QPainter painter(this); + painter.setPen(Qt::darkGray); + painter.drawRect(rect().adjusted(0, 0, -1, -1)); + + painter.setPen(Qt::white); + painter.setBrush(color); + painter.drawRect(rect().adjusted(1, 1, -2, -2)); +} + +void CColorLabel::mousePressEvent(QMouseEvent *pEvent) +{ + QLabel::mousePressEvent(pEvent); + showColorPickDialog(); +} + +void CColorLabel::showColorPickDialog() +{ + QColor c = QColorDialog::getColor(color, this, QString()); + if(c.isValid()) + { + color = c; + emit colorChanged(color); + } +} diff --git a/product/src/gui/plugin/NavigationWidget/CColorLabel.h b/product/src/gui/plugin/NavigationWidget/CColorLabel.h index 437d1df7..7fdbb60c 100644 --- a/product/src/gui/plugin/NavigationWidget/CColorLabel.h +++ b/product/src/gui/plugin/NavigationWidget/CColorLabel.h @@ -1,29 +1,29 @@ -#ifndef CCOLORLABEL_H -#define CCOLORLABEL_H - -#include - -class CColorLabel : public QLabel -{ - Q_OBJECT -public: - explicit CColorLabel(QWidget *parent = nullptr); - - const QColor getColor() const; - void setColor(const QColor &color); - -signals: - void colorChanged(const QColor &color); - -protected: - void paintEvent(QPaintEvent *pEvent); - void mousePressEvent(QMouseEvent *pEvent); - -private: - void showColorPickDialog(); - -private: - QColor color; -}; - -#endif // CCOLORLABEL_H +#ifndef CCOLORLABEL_H +#define CCOLORLABEL_H + +#include + +class CColorLabel : public QLabel +{ + Q_OBJECT +public: + explicit CColorLabel(QWidget *parent = nullptr); + + const QColor getColor() const; + void setColor(const QColor &color); + +signals: + void colorChanged(const QColor &color); + +protected: + void paintEvent(QPaintEvent *pEvent); + void mousePressEvent(QMouseEvent *pEvent); + +private: + void showColorPickDialog(); + +private: + QColor color; +}; + +#endif // CCOLORLABEL_H diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationConfigDialog.cpp b/product/src/gui/plugin/NavigationWidget/CNavigationConfigDialog.cpp index ab7b468f..ce05f99e 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationConfigDialog.cpp +++ b/product/src/gui/plugin/NavigationWidget/CNavigationConfigDialog.cpp @@ -1,433 +1,433 @@ -#include -#include "CNavigationConfigDialog.h" -#include "CNavigationWidget.h" -#include "CColorLabel.h" -#include "ui_NavigationConfigDialog.h" -#include "public/pub_utility_api/FileUtil.h" - -CNavigationConfigDialog::CNavigationConfigDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::NavigationConfigDialog), - m_itemIndex(0) -{ - ui->setupUi(this); - initialize(); -} - -CNavigationConfigDialog::~CNavigationConfigDialog() -{ - delete ui; -} - -void CNavigationConfigDialog::initialize() -{ - ui->navigationWidget->setNavigationMode(CNavigationWidget::CONFIG_MODE); - - QMap nodeMap; - ui->navigationWidget->getNodeTypeMap(nodeMap); - QMap::const_iterator iter = nodeMap.constBegin(); - for(; iter != nodeMap.constEnd(); iter++) - { - ui->itemOptTypeComb->addItem(iter.value(), iter.key()); - } - - auto sigValueChanged = static_cast(&QSpinBox::valueChanged); - - //< initialize color - ui->navigationBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->backgroundColor)); - connect(ui->navigationBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateNavigationWidgetColor); - - ui->itemTopLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]))); - connect(ui->itemTopLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemTopLevelBgColor); - - ui->itemTopLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]))); - connect(ui->itemTopLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemTopLevelTextColor); - - ui->itemTopLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL])); - connect(ui->itemTopLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemTopLevelIndentation); - - ui->itemChildLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]))); - connect(ui->itemChildLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemChildLevelBgColor); - - ui->itemChildLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]))); - connect(ui->itemChildLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemChildLevelTextColor); - - ui->itemChildLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL])); - connect(ui->itemChildLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemChildLevelIndentation); - - ui->itemLeafLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]))); - connect(ui->itemLeafLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemLeafLevelBgColor); - - ui->itemLeafLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]))); - connect(ui->itemLeafLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemLeafLevelTextColor); - - ui->itemLeafLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL])); - connect(ui->itemLeafLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemLeafLevelIndentation); - - ui->itemFocusBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemSelectedColor)); - connect(ui->itemFocusBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemFocusBgColor); - - ui->itemFocusTextColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemSelectedTextColor)); - connect(ui->itemFocusTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemFocusTextColor); - - ui->itemHoverBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemHoveredColor)); - connect(ui->itemHoverBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemHoverBgColor); - - ui->itemHoverTextColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemHoveredTextColor)); - connect(ui->itemHoverTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemHoverTextColor); - - connect(ui->itemIconPathButton, &QPushButton::clicked, this, &CNavigationConfigDialog::updateItemIconPath); - connect(ui->itemIconPathEditor, &QLineEdit::textChanged, this, &CNavigationConfigDialog::updateItemIconPathManual); - - connect(ui->itemDataPathButton, &QPushButton::clicked, this, &CNavigationConfigDialog::updateItemDataPath); - connect(ui->itemDataPathEditor, &QLineEdit::textChanged, this, &CNavigationConfigDialog::updateItemDataPathManual); - - connect(ui->itemEnableBox, &QCheckBox::toggled, this, &CNavigationConfigDialog::updateItemEnable); - connect(ui->itemWebBox, &QCheckBox::toggled, this, &CNavigationConfigDialog::updateItemWeb); - connect(ui->itemOptTypeComb, &QComboBox::currentTextChanged, this, &CNavigationConfigDialog::updateItemOptType); - - connect(ui->insertItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertTopLevelItem); - connect(ui->insertChildButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertChildItem); - connect(ui->insertLevelItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertLevelItem); - connect(ui->removeItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onRemoveLevelItem); - connect(ui->importBtn, &QPushButton::clicked, this, &CNavigationConfigDialog::onImport); - connect(ui->exportBtn, &QPushButton::clicked, this, &CNavigationConfigDialog::onExport); - connect(ui->clearButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onClearItem); - - connect(ui->navigationWidget, &CNavigationWidget::itemSelectionChanged, this, &CNavigationConfigDialog::updateButtonState); - - ui->iconFrame->setEnabled(false); - ui->clearButton->setEnabled(false); - ui->removeItemButton->setEnabled(false); - ui->insertChildButton->setEnabled(false); - ui->insertLevelItemButton->setEnabled(false); - - onClearItem(); -} - -const CNavigationWidget *CNavigationConfigDialog::NavigationWidegt() const -{ - return ui->navigationWidget; -} - -void CNavigationConfigDialog::updateItems(const CNavigationWidget *pNavigation) -{ - ui->navigationWidget->updateItems(pNavigation); - for(int nIndex(0); nIndex < pNavigation->topLevelItemCount(); nIndex++) - { - m_itemIndex++; - QTreeWidgetItem * item = pNavigation->topLevelItem(nIndex); - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - m_itemIndex++; - QTreeWidgetItem * childItem = item->child(nChildIndex); - for(int nLeafIndex(0); nLeafIndex < childItem->childCount(); nLeafIndex++) - { - m_itemIndex++; - } - } - } - updateButtonState(); -} - -void CNavigationConfigDialog::updateNavigationWidgetColor(const QColor &color) -{ - ui->navigationWidget->m_pItemProxy->backgroundColor = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemTopLevelBgColor(const QColor &color) -{ - std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]) = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemTopLevelTextColor(const QColor &color) -{ - std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]) = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemTopLevelIndentation(const int &indentation) -{ - std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]) = indentation; - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemChildLevelBgColor(const QColor &color) -{ - std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]) = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemChildLevelTextColor(const QColor &color) -{ - std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]) = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemChildLevelIndentation(const int &indentation) -{ - std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]) = indentation; - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemLeafLevelBgColor(const QColor &color) -{ - std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]) = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemLeafLevelTextColor(const QColor &color) -{ - std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]) = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemLeafLevelIndentation(const int &indentation) -{ - std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]) = indentation; - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemFocusBgColor(const QColor &color) -{ - ui->navigationWidget->m_pItemProxy->itemSelectedColor = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemFocusTextColor(const QColor &color) -{ - ui->navigationWidget->m_pItemProxy->itemSelectedTextColor = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemHoverBgColor(const QColor &color) -{ - ui->navigationWidget->m_pItemProxy->itemHoveredColor = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemHoverTextColor(const QColor &color) -{ - ui->navigationWidget->m_pItemProxy->itemHoveredTextColor = color.rgba(); - updateNavigationWidget(); -} - -void CNavigationConfigDialog::updateItemIconPath() -{ - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - std::string defaultPath = kbd_public::CFileUtil::getCurModuleDir(); - QString strIconFilePath = QString::fromStdString(defaultPath) + QString("..%1..%1data%1back_pixmap%1").arg(QDir::separator()); - QString strFileName = QFileDialog::getOpenFileName(this, tr("打开"), strIconFilePath, "*.jpg; *.png"); - if(strFileName.isEmpty()) - { - return; - } - ui->itemIconPathEditor->setText(strFileName); - item->setData(0, IconPath_Role, strFileName); - item->setIcon(0, QIcon(strFileName)); - } -} - -void CNavigationConfigDialog::updateItemIconPathManual() -{ - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - item->setData(0, IconPath_Role, ui->itemIconPathEditor->text()); - item->setIcon(0, QIcon(ui->itemIconPathEditor->text())); - } -} - -void CNavigationConfigDialog::updateItemDataPath() -{ - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - QString strGraphFilePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()); - QString filter = ""; - if(ui->itemOptTypeComb->currentData().toInt() == CNavigationWidget::SWITCH_GRAPH) - { - strGraphFilePath += QString("..%1..%1data%1pic%1").arg(QDir::separator()); - filter = "*.glx"; - } - QString strFileName = QFileDialog::getOpenFileName(this, tr("打开"), strGraphFilePath, filter); - if(strFileName.isEmpty()) - { - return; - } - if(strFileName.right(4) == ".exe") - strFileName.remove(-4, 4); - //QDir dir(strGraphFilePath); - ui->itemDataPathEditor->setText(strFileName); - item->setData(0, Qt::UserRole, strFileName); - } -} - -void CNavigationConfigDialog::updateItemDataPathManual() -{ - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - item->setData(0, Qt::UserRole, ui->itemDataPathEditor->text()); - } -} - -void CNavigationConfigDialog::updateItemEnable(bool checked) -{ - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - item->setData(0, Enable_Role, checked ? CNavigationWidget::Enable : CNavigationWidget::Disable); - } -} - -void CNavigationConfigDialog::updateItemWeb(bool checked) -{ - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - item->setData(0, Web_Role, checked ? CNavigationWidget::Enable : CNavigationWidget::Disable); - } -} - -void CNavigationConfigDialog::updateItemOptType(const QString &text) -{ - Q_UNUSED(text) - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - item->setData(0, Opt_Role, ui->itemOptTypeComb->currentData().toInt()); - } -} - -void CNavigationConfigDialog::onInsertTopLevelItem() -{ - ui->navigationWidget->addTopLevelItem(m_itemIndex, tr("新建项目_") + QString::number(m_itemIndex)); - m_itemIndex++; -} - -void CNavigationConfigDialog::onInsertChildItem() -{ - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - QList parents; - if(CNavigationWidget::TOP_LEVEL == item->data(0, Level_Role).toInt()) - { - parents << item->data(0, Item_Role).toInt(); - } - else if(CNavigationWidget::CHILD_LEVEL == item->data(0, Level_Role).toInt()) - { - parents << item->parent()->data(0, Item_Role).toInt(); - parents << item->data(0, Item_Role).toInt(); - } - else - { - return; - } - - ui->navigationWidget->addChildItem(m_itemIndex, parents, tr("新建项目_") + QString::number(m_itemIndex)); - m_itemIndex++; - item->setExpanded(true); - } -} - -void CNavigationConfigDialog::onInsertLevelItem() -{ - QTreeWidgetItem * item = ui->navigationWidget->currentItem(); - if(item) - { - QList parents; - if(CNavigationWidget::TOP_LEVEL == item->data(0, Level_Role).toInt()) - { - parents << item->data(0, Item_Role).toInt(); - } - else if(CNavigationWidget::CHILD_LEVEL == item->data(0, Level_Role).toInt()) - { - parents << item->parent()->data(0, Item_Role).toInt(); - parents << item->data(0, Item_Role).toInt(); - } - else if(CNavigationWidget::LEAF_LEVEL == item->data(0, Level_Role).toInt()) - { - parents << item->parent()->parent()->data(0, Item_Role).toInt(); - parents << item->parent()->data(0, Item_Role).toInt(); - parents << item->data(0, Item_Role).toInt(); - } - else - { - return; - } - - ui->navigationWidget->addLevelItem(m_itemIndex, parents, tr("新建项目_") + QString::number(m_itemIndex)); - m_itemIndex++; - } -} - -void CNavigationConfigDialog::onRemoveLevelItem() -{ - if(ui->navigationWidget->currentItem()) - { - ui->navigationWidget->removeItem(ui->navigationWidget->currentItem()); - updateButtonState(); - } -} - -void CNavigationConfigDialog::onImport() -{ - int row = ui->navigationWidget->slotImport(); - if(row != -1) - { - m_itemIndex = row; - } -} - -void CNavigationConfigDialog::onExport() -{ - ui->navigationWidget->slotExport(); -} - -void CNavigationConfigDialog::onClearItem() -{ - ui->navigationWidget->clearItems(); - updateButtonState(); - m_itemIndex = 0; -} - - -void CNavigationConfigDialog::updateButtonState() -{ - QTreeWidgetItem * current = ui->navigationWidget->currentItem(); - ui->insertChildButton->setEnabled(Q_NULLPTR != current); - ui->insertLevelItemButton->setEnabled(Q_NULLPTR != current); - ui->removeItemButton->setEnabled(Q_NULLPTR != current); - ui->clearButton->setEnabled(ui->navigationWidget->topLevelItemCount()); - ui->iconFrame->setEnabled(Q_NULLPTR != current); - if(Q_NULLPTR != current) - { - CNavigationWidget::Node_Level level = (CNavigationWidget::Node_Level)ui->navigationWidget->currentItem()->data(0, Level_Role).toInt(); - ui->insertChildButton->setEnabled(CNavigationWidget::LEAF_LEVEL != level); - ui->itemIconPathEditor->setText(current->data(0, IconPath_Role).toString()); - ui->itemDataPathEditor->setText(current->data(0, Qt::UserRole).toString()); - ui->itemEnableBox->setChecked(current->data(0, Enable_Role).toInt() == CNavigationWidget::Enable? true:false); - ui->itemWebBox->setChecked(current->data(0, Web_Role).toInt() == CNavigationWidget::Enable? true:false); - ui->itemOptTypeComb->setCurrentIndex(ui->itemOptTypeComb->findData(current->data(0, Opt_Role).toInt())); - } - else - { - ui->itemIconPathEditor->setText(""); - ui->itemDataPathEditor->setText(""); - ui->itemEnableBox->setChecked(false); - ui->itemWebBox->setChecked(false); - ui->itemOptTypeComb->setCurrentIndex(0); - } -} - -void CNavigationConfigDialog::updateNavigationWidget() -{ - ui->navigationWidget->setFocus(); - ui->navigationWidget->update(); -} +#include +#include "CNavigationConfigDialog.h" +#include "CNavigationWidget.h" +#include "CColorLabel.h" +#include "ui_NavigationConfigDialog.h" +#include "public/pub_utility_api/FileUtil.h" + +CNavigationConfigDialog::CNavigationConfigDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::NavigationConfigDialog), + m_itemIndex(0) +{ + ui->setupUi(this); + initialize(); +} + +CNavigationConfigDialog::~CNavigationConfigDialog() +{ + delete ui; +} + +void CNavigationConfigDialog::initialize() +{ + ui->navigationWidget->setNavigationMode(CNavigationWidget::CONFIG_MODE); + + QMap nodeMap; + ui->navigationWidget->getNodeTypeMap(nodeMap); + QMap::const_iterator iter = nodeMap.constBegin(); + for(; iter != nodeMap.constEnd(); iter++) + { + ui->itemOptTypeComb->addItem(iter.value(), iter.key()); + } + + auto sigValueChanged = static_cast(&QSpinBox::valueChanged); + + //< initialize color + ui->navigationBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->backgroundColor)); + connect(ui->navigationBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateNavigationWidgetColor); + + ui->itemTopLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]))); + connect(ui->itemTopLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemTopLevelBgColor); + + ui->itemTopLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]))); + connect(ui->itemTopLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemTopLevelTextColor); + + ui->itemTopLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL])); + connect(ui->itemTopLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemTopLevelIndentation); + + ui->itemChildLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]))); + connect(ui->itemChildLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemChildLevelBgColor); + + ui->itemChildLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]))); + connect(ui->itemChildLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemChildLevelTextColor); + + ui->itemChildLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL])); + connect(ui->itemChildLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemChildLevelIndentation); + + ui->itemLeafLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]))); + connect(ui->itemLeafLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemLeafLevelBgColor); + + ui->itemLeafLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]))); + connect(ui->itemLeafLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemLeafLevelTextColor); + + ui->itemLeafLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL])); + connect(ui->itemLeafLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemLeafLevelIndentation); + + ui->itemFocusBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemSelectedColor)); + connect(ui->itemFocusBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemFocusBgColor); + + ui->itemFocusTextColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemSelectedTextColor)); + connect(ui->itemFocusTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemFocusTextColor); + + ui->itemHoverBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemHoveredColor)); + connect(ui->itemHoverBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemHoverBgColor); + + ui->itemHoverTextColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemHoveredTextColor)); + connect(ui->itemHoverTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemHoverTextColor); + + connect(ui->itemIconPathButton, &QPushButton::clicked, this, &CNavigationConfigDialog::updateItemIconPath); + connect(ui->itemIconPathEditor, &QLineEdit::textChanged, this, &CNavigationConfigDialog::updateItemIconPathManual); + + connect(ui->itemDataPathButton, &QPushButton::clicked, this, &CNavigationConfigDialog::updateItemDataPath); + connect(ui->itemDataPathEditor, &QLineEdit::textChanged, this, &CNavigationConfigDialog::updateItemDataPathManual); + + connect(ui->itemEnableBox, &QCheckBox::toggled, this, &CNavigationConfigDialog::updateItemEnable); + connect(ui->itemWebBox, &QCheckBox::toggled, this, &CNavigationConfigDialog::updateItemWeb); + connect(ui->itemOptTypeComb, &QComboBox::currentTextChanged, this, &CNavigationConfigDialog::updateItemOptType); + + connect(ui->insertItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertTopLevelItem); + connect(ui->insertChildButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertChildItem); + connect(ui->insertLevelItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertLevelItem); + connect(ui->removeItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onRemoveLevelItem); + connect(ui->importBtn, &QPushButton::clicked, this, &CNavigationConfigDialog::onImport); + connect(ui->exportBtn, &QPushButton::clicked, this, &CNavigationConfigDialog::onExport); + connect(ui->clearButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onClearItem); + + connect(ui->navigationWidget, &CNavigationWidget::itemSelectionChanged, this, &CNavigationConfigDialog::updateButtonState); + + ui->iconFrame->setEnabled(false); + ui->clearButton->setEnabled(false); + ui->removeItemButton->setEnabled(false); + ui->insertChildButton->setEnabled(false); + ui->insertLevelItemButton->setEnabled(false); + + onClearItem(); +} + +const CNavigationWidget *CNavigationConfigDialog::NavigationWidegt() const +{ + return ui->navigationWidget; +} + +void CNavigationConfigDialog::updateItems(const CNavigationWidget *pNavigation) +{ + ui->navigationWidget->updateItems(pNavigation); + for(int nIndex(0); nIndex < pNavigation->topLevelItemCount(); nIndex++) + { + m_itemIndex++; + QTreeWidgetItem * item = pNavigation->topLevelItem(nIndex); + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_itemIndex++; + QTreeWidgetItem * childItem = item->child(nChildIndex); + for(int nLeafIndex(0); nLeafIndex < childItem->childCount(); nLeafIndex++) + { + m_itemIndex++; + } + } + } + updateButtonState(); +} + +void CNavigationConfigDialog::updateNavigationWidgetColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->backgroundColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemTopLevelBgColor(const QColor &color) +{ + std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemTopLevelTextColor(const QColor &color) +{ + std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemTopLevelIndentation(const int &indentation) +{ + std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]) = indentation; + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemChildLevelBgColor(const QColor &color) +{ + std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemChildLevelTextColor(const QColor &color) +{ + std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemChildLevelIndentation(const int &indentation) +{ + std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::CHILD_LEVEL]) = indentation; + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemLeafLevelBgColor(const QColor &color) +{ + std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemLeafLevelTextColor(const QColor &color) +{ + std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemLeafLevelIndentation(const int &indentation) +{ + std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CNavigationWidget::LEAF_LEVEL]) = indentation; + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemFocusBgColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->itemSelectedColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemFocusTextColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->itemSelectedTextColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemHoverBgColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->itemHoveredColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemHoverTextColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->itemHoveredTextColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemIconPath() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + std::string defaultPath = kbd_public::CFileUtil::getCurModuleDir(); + QString strIconFilePath = QString::fromStdString(defaultPath) + QString("..%1..%1data%1back_pixmap%1").arg(QDir::separator()); + QString strFileName = QFileDialog::getOpenFileName(this, tr("打开"), strIconFilePath, "*.jpg; *.png"); + if(strFileName.isEmpty()) + { + return; + } + ui->itemIconPathEditor->setText(strFileName); + item->setData(0, IconPath_Role, strFileName); + item->setIcon(0, QIcon(strFileName)); + } +} + +void CNavigationConfigDialog::updateItemIconPathManual() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, IconPath_Role, ui->itemIconPathEditor->text()); + item->setIcon(0, QIcon(ui->itemIconPathEditor->text())); + } +} + +void CNavigationConfigDialog::updateItemDataPath() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + QString strGraphFilePath = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()); + QString filter = ""; + if(ui->itemOptTypeComb->currentData().toInt() == CNavigationWidget::SWITCH_GRAPH) + { + strGraphFilePath += QString("..%1..%1data%1pic%1").arg(QDir::separator()); + filter = "*.glx"; + } + QString strFileName = QFileDialog::getOpenFileName(this, tr("打开"), strGraphFilePath, filter); + if(strFileName.isEmpty()) + { + return; + } + if(strFileName.right(4) == ".exe") + strFileName.remove(-4, 4); + //QDir dir(strGraphFilePath); + ui->itemDataPathEditor->setText(strFileName); + item->setData(0, Qt::UserRole, strFileName); + } +} + +void CNavigationConfigDialog::updateItemDataPathManual() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, Qt::UserRole, ui->itemDataPathEditor->text()); + } +} + +void CNavigationConfigDialog::updateItemEnable(bool checked) +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, Enable_Role, checked ? CNavigationWidget::Enable : CNavigationWidget::Disable); + } +} + +void CNavigationConfigDialog::updateItemWeb(bool checked) +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, Web_Role, checked ? CNavigationWidget::Enable : CNavigationWidget::Disable); + } +} + +void CNavigationConfigDialog::updateItemOptType(const QString &text) +{ + Q_UNUSED(text) + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, Opt_Role, ui->itemOptTypeComb->currentData().toInt()); + } +} + +void CNavigationConfigDialog::onInsertTopLevelItem() +{ + ui->navigationWidget->addTopLevelItem(m_itemIndex, tr("新建项目_") + QString::number(m_itemIndex)); + m_itemIndex++; +} + +void CNavigationConfigDialog::onInsertChildItem() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + QList parents; + if(CNavigationWidget::TOP_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->data(0, Item_Role).toInt(); + } + else if(CNavigationWidget::CHILD_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->parent()->data(0, Item_Role).toInt(); + parents << item->data(0, Item_Role).toInt(); + } + else + { + return; + } + + ui->navigationWidget->addChildItem(m_itemIndex, parents, tr("新建项目_") + QString::number(m_itemIndex)); + m_itemIndex++; + item->setExpanded(true); + } +} + +void CNavigationConfigDialog::onInsertLevelItem() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + QList parents; + if(CNavigationWidget::TOP_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->data(0, Item_Role).toInt(); + } + else if(CNavigationWidget::CHILD_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->parent()->data(0, Item_Role).toInt(); + parents << item->data(0, Item_Role).toInt(); + } + else if(CNavigationWidget::LEAF_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->parent()->parent()->data(0, Item_Role).toInt(); + parents << item->parent()->data(0, Item_Role).toInt(); + parents << item->data(0, Item_Role).toInt(); + } + else + { + return; + } + + ui->navigationWidget->addLevelItem(m_itemIndex, parents, tr("新建项目_") + QString::number(m_itemIndex)); + m_itemIndex++; + } +} + +void CNavigationConfigDialog::onRemoveLevelItem() +{ + if(ui->navigationWidget->currentItem()) + { + ui->navigationWidget->removeItem(ui->navigationWidget->currentItem()); + updateButtonState(); + } +} + +void CNavigationConfigDialog::onImport() +{ + int row = ui->navigationWidget->slotImport(); + if(row != -1) + { + m_itemIndex = row; + } +} + +void CNavigationConfigDialog::onExport() +{ + ui->navigationWidget->slotExport(); +} + +void CNavigationConfigDialog::onClearItem() +{ + ui->navigationWidget->clearItems(); + updateButtonState(); + m_itemIndex = 0; +} + + +void CNavigationConfigDialog::updateButtonState() +{ + QTreeWidgetItem * current = ui->navigationWidget->currentItem(); + ui->insertChildButton->setEnabled(Q_NULLPTR != current); + ui->insertLevelItemButton->setEnabled(Q_NULLPTR != current); + ui->removeItemButton->setEnabled(Q_NULLPTR != current); + ui->clearButton->setEnabled(ui->navigationWidget->topLevelItemCount()); + ui->iconFrame->setEnabled(Q_NULLPTR != current); + if(Q_NULLPTR != current) + { + CNavigationWidget::Node_Level level = (CNavigationWidget::Node_Level)ui->navigationWidget->currentItem()->data(0, Level_Role).toInt(); + ui->insertChildButton->setEnabled(CNavigationWidget::LEAF_LEVEL != level); + ui->itemIconPathEditor->setText(current->data(0, IconPath_Role).toString()); + ui->itemDataPathEditor->setText(current->data(0, Qt::UserRole).toString()); + ui->itemEnableBox->setChecked(current->data(0, Enable_Role).toInt() == CNavigationWidget::Enable? true:false); + ui->itemWebBox->setChecked(current->data(0, Web_Role).toInt() == CNavigationWidget::Enable? true:false); + ui->itemOptTypeComb->setCurrentIndex(ui->itemOptTypeComb->findData(current->data(0, Opt_Role).toInt())); + } + else + { + ui->itemIconPathEditor->setText(""); + ui->itemDataPathEditor->setText(""); + ui->itemEnableBox->setChecked(false); + ui->itemWebBox->setChecked(false); + ui->itemOptTypeComb->setCurrentIndex(0); + } +} + +void CNavigationConfigDialog::updateNavigationWidget() +{ + ui->navigationWidget->setFocus(); + ui->navigationWidget->update(); +} diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationConfigDialog.h b/product/src/gui/plugin/NavigationWidget/CNavigationConfigDialog.h index 179e2cca..d66854b4 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationConfigDialog.h +++ b/product/src/gui/plugin/NavigationWidget/CNavigationConfigDialog.h @@ -1,75 +1,75 @@ -#ifndef CNAVIGATIONCONFIGDIALOG_H -#define CNAVIGATIONCONFIGDIALOG_H - -#include - -namespace Ui { -class NavigationConfigDialog; -} - -class CNavigationWidget; - -class CNavigationConfigDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CNavigationConfigDialog(QWidget *parent = 0); - ~CNavigationConfigDialog(); - - void initialize(); - - const CNavigationWidget * NavigationWidegt() const; - - void updateItems(const CNavigationWidget *pNavigation); - -private: - void updateNavigationWidgetColor(const QColor &color); - - void updateItemTopLevelBgColor(const QColor &color); - void updateItemTopLevelTextColor(const QColor &color); - void updateItemTopLevelIndentation(const int &indentation); - - void updateItemChildLevelBgColor(const QColor &color); - void updateItemChildLevelTextColor(const QColor &color); - void updateItemChildLevelIndentation(const int &indentation); - - void updateItemLeafLevelBgColor(const QColor &color); - void updateItemLeafLevelTextColor(const QColor &color); - void updateItemLeafLevelIndentation(const int &indentation); - - void updateItemFocusBgColor(const QColor &color); - void updateItemFocusTextColor(const QColor &color); - - void updateItemHoverBgColor(const QColor &color); - void updateItemHoverTextColor(const QColor &color); - - void updateItemIconPath(); - void updateItemIconPathManual(); - - void updateItemDataPath(); - void updateItemDataPathManual(); - - void updateItemEnable(bool checked); - void updateItemWeb(bool checked); - void updateItemOptType(const QString &text); - - void onInsertTopLevelItem(); - void onInsertChildItem(); - void onInsertLevelItem(); - void onRemoveLevelItem(); - void onImport(); - void onExport(); - void onClearItem(); - - void updateButtonState(); - - void updateNavigationWidget(); - -private: - Ui::NavigationConfigDialog *ui; - - int m_itemIndex; -}; - -#endif // CNAVIGATIONCONFIGDIALOG_H +#ifndef CNAVIGATIONCONFIGDIALOG_H +#define CNAVIGATIONCONFIGDIALOG_H + +#include + +namespace Ui { +class NavigationConfigDialog; +} + +class CNavigationWidget; + +class CNavigationConfigDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CNavigationConfigDialog(QWidget *parent = 0); + ~CNavigationConfigDialog(); + + void initialize(); + + const CNavigationWidget * NavigationWidegt() const; + + void updateItems(const CNavigationWidget *pNavigation); + +private: + void updateNavigationWidgetColor(const QColor &color); + + void updateItemTopLevelBgColor(const QColor &color); + void updateItemTopLevelTextColor(const QColor &color); + void updateItemTopLevelIndentation(const int &indentation); + + void updateItemChildLevelBgColor(const QColor &color); + void updateItemChildLevelTextColor(const QColor &color); + void updateItemChildLevelIndentation(const int &indentation); + + void updateItemLeafLevelBgColor(const QColor &color); + void updateItemLeafLevelTextColor(const QColor &color); + void updateItemLeafLevelIndentation(const int &indentation); + + void updateItemFocusBgColor(const QColor &color); + void updateItemFocusTextColor(const QColor &color); + + void updateItemHoverBgColor(const QColor &color); + void updateItemHoverTextColor(const QColor &color); + + void updateItemIconPath(); + void updateItemIconPathManual(); + + void updateItemDataPath(); + void updateItemDataPathManual(); + + void updateItemEnable(bool checked); + void updateItemWeb(bool checked); + void updateItemOptType(const QString &text); + + void onInsertTopLevelItem(); + void onInsertChildItem(); + void onInsertLevelItem(); + void onRemoveLevelItem(); + void onImport(); + void onExport(); + void onClearItem(); + + void updateButtonState(); + + void updateNavigationWidget(); + +private: + Ui::NavigationConfigDialog *ui; + + int m_itemIndex; +}; + +#endif // CNAVIGATIONCONFIGDIALOG_H diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.cpp b/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.cpp index d2c62ddf..efe75312 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.cpp +++ b/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.cpp @@ -1,209 +1,209 @@ -#include "CNavigationDelegate.h" -#include "CNavigationWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include - -CNavigationDelegate::CNavigationDelegate(ITEM_STYLE_PROXY *proxy, QObject *parent) - : QStyledItemDelegate(parent), - m_pTreeView(Q_NULLPTR), - m_pixmapWidth(16), - m_pixmapHeight(16), - m_rowHeight(36), - m_currentHoverIndex(QModelIndex()), - m_pItemProxy(proxy) -{ - m_strExpandIconName = QString("://image/arrowExpand.png"); - m_strCollapseIconName = QString("://image/arrowCollapse.png"); - m_strExpandIconHoverName = QString("://image/arrowExpandHover.png"); - m_strCollapseIconHoverName = QString("://image/arrowCollapseHover.png"); -} - -CNavigationDelegate::~CNavigationDelegate() -{ - -} - -void CNavigationDelegate::setView(QTreeView *pTreeView) -{ - m_pTreeView = pTreeView; -} - -void CNavigationDelegate::setBranchIconSize(const QSize &size) -{ - m_pixmapHeight = size.height(); - m_pixmapWidth = size.width(); -} - -void CNavigationDelegate::setExpandIcon(const QString &iconName) -{ - m_strExpandIconName = iconName; -} - -void CNavigationDelegate::setCollapseIcon(const QString &iconName) -{ - m_strCollapseIconName = iconName; -} - -QWidget *CNavigationDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(option) - if(!index.isValid()) - { - return Q_NULLPTR; - } - QTreeWidgetItem * item = reinterpret_cast(index.internalPointer()); - if(item) - { - if(0 == index.column()) - { - QLineEdit * pLineEdit = new QLineEdit(parent); - pLineEdit->setText(item->text(0)); - return pLineEdit; - } - } - return Q_NULLPTR; -} - -void CNavigationDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - int level = index.data(Level_Role).toInt(); - int delta = m_pItemProxy->indicatorWidth + m_pItemProxy->iconMargin * 2 + std::get<3>(m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]) + std::get<4>(m_pItemProxy->vecItemStyle[level]); - QRect rt = editor->geometry(); - rt.setLeft(delta); - editor->setGeometry(std::move(rt)); - return; -} - -void CNavigationDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QStyleOptionViewItem viewOption(option); - if (viewOption.state & QStyle::State_HasFocus) - { - viewOption.state = viewOption.state ^ QStyle::State_HasFocus; - } - - if(!index.isValid()) - { - if (m_pTreeView) - { - painter->fillRect(m_pTreeView->rect(), QColor::fromRgba(m_pItemProxy->backgroundColor)); - } - return; - } - drawItem(painter, viewOption, index); - - bool bExpanded = false; - if (m_pTreeView != NULL) - { - const QAbstractItemModel *model = index.model(); - if (!model->hasChildren(index)) - { - return; - } - bExpanded = m_pTreeView->isExpanded(index); - } - - int height = (viewOption.rect.height() - m_pixmapWidth) / 2; - QPixmap pixmap; - if(index == m_currentHoverIndex) - { - pixmap = bExpanded ? QPixmap(m_strExpandIconHoverName) : QPixmap(m_strCollapseIconHoverName); - } - else - { - pixmap = bExpanded ? QPixmap(m_strExpandIconName) : QPixmap(m_strCollapseIconName); - } - QRect decorationRect = QRect(viewOption.rect.left() + viewOption.rect.width() - ((m_rowHeight + m_pixmapWidth) / 2), viewOption.rect.top() + height, m_pixmapWidth, m_pixmapHeight); - painter->drawPixmap(decorationRect, pixmap); -} - -bool CNavigationDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ -// int height = (option.rect.height() - m_pixmapWidth) / 2; -// QRect decorationRect = QRect(option.rect.left() + option.rect.width() - ((m_rowHeight + m_pixmapWidth) / 2), option.rect.top() + height, m_pixmapWidth, m_pixmapHeight); - - QMouseEvent * pEvent = dynamic_cast(event); - if (pEvent) - { - if(m_currentHoverIndex != index) - { - m_currentHoverIndex = index; - return true; - } - - if (pEvent->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonPress) - { - m_pTreeView->setExpanded(index, !m_pTreeView->isExpanded(index)); - } - } - else - { - m_currentHoverIndex = QModelIndex(); - } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} - -QSize CNavigationDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QSize size = QStyledItemDelegate::sizeHint(option, index); - return QSize(size.width(), m_rowHeight); -} - -void CNavigationDelegate::drawItem(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - painter->save(); - painter->setRenderHint(QPainter::Antialiasing, true); - QTextOption textOpiton; - textOpiton.setAlignment(option.displayAlignment); - - QRect rt(m_pTreeView->rect().left(), option.rect.top(), m_pTreeView->rect().width(), option.rect.height()); - - int level = index.data(Level_Role).toInt(); - - QPen pen(QColor::fromRgba(std::get<1>(m_pItemProxy->vecItemStyle[level]))); - QBrush brush(QColor::fromRgba(std::get<0>(m_pItemProxy->vecItemStyle[level]))); - if (option.state & QStyle::State_MouseOver) - { - pen.setColor(QColor::fromRgba(m_pItemProxy->itemHoveredTextColor)); - brush.setColor(QColor::fromRgba(m_pItemProxy->itemHoveredColor)); - } - if (option.state & QStyle::State_Selected) - { - pen.setColor(QColor::fromRgba(m_pItemProxy->itemSelectedTextColor)); - brush.setColor(QColor::fromRgba(m_pItemProxy->itemSelectedColor)); - } - painter->fillRect(rt, std::move(brush)); - - - int delta = m_pItemProxy->indicatorWidth + m_pItemProxy->iconMargin + std::get<4>(m_pItemProxy->vecItemStyle[level]); - - //< draw Icon - int iconSize = std::get<3>(m_pItemProxy->vecItemStyle[level]); - QTreeWidgetItem * item = reinterpret_cast(index.internalPointer()); - if(item) - { - QPixmap pixmap = item->icon(0).pixmap(iconSize, iconSize); - if(!pixmap.isNull()) - { - QRect iconRect(delta + level, option.rect.top() + (option.rect.height() - iconSize) / 2., iconSize, iconSize); - painter->drawPixmap(iconRect, pixmap); - } - } - - //< draw Text - delta += std::get<3>(m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]); - delta += m_pItemProxy->iconMargin; - rt.adjust(delta, 0, 0, 0); - painter->setPen(std::move(pen)); - QFont font = option.font; - font.setPixelSize(std::get<2>(m_pItemProxy->vecItemStyle[level])); - painter->setFont(std::move(font)); - painter->drawText(rt, index.data().toString(), textOpiton); - painter->restore(); -} +#include "CNavigationDelegate.h" +#include "CNavigationWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include + +CNavigationDelegate::CNavigationDelegate(ITEM_STYLE_PROXY *proxy, QObject *parent) + : QStyledItemDelegate(parent), + m_pTreeView(Q_NULLPTR), + m_pixmapWidth(16), + m_pixmapHeight(16), + m_rowHeight(36), + m_currentHoverIndex(QModelIndex()), + m_pItemProxy(proxy) +{ + m_strExpandIconName = QString("://image/arrowExpand.png"); + m_strCollapseIconName = QString("://image/arrowCollapse.png"); + m_strExpandIconHoverName = QString("://image/arrowExpandHover.png"); + m_strCollapseIconHoverName = QString("://image/arrowCollapseHover.png"); +} + +CNavigationDelegate::~CNavigationDelegate() +{ + +} + +void CNavigationDelegate::setView(QTreeView *pTreeView) +{ + m_pTreeView = pTreeView; +} + +void CNavigationDelegate::setBranchIconSize(const QSize &size) +{ + m_pixmapHeight = size.height(); + m_pixmapWidth = size.width(); +} + +void CNavigationDelegate::setExpandIcon(const QString &iconName) +{ + m_strExpandIconName = iconName; +} + +void CNavigationDelegate::setCollapseIcon(const QString &iconName) +{ + m_strCollapseIconName = iconName; +} + +QWidget *CNavigationDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid()) + { + return Q_NULLPTR; + } + QTreeWidgetItem * item = reinterpret_cast(index.internalPointer()); + if(item) + { + if(0 == index.column()) + { + QLineEdit * pLineEdit = new QLineEdit(parent); + pLineEdit->setText(item->text(0)); + return pLineEdit; + } + } + return Q_NULLPTR; +} + +void CNavigationDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + int level = index.data(Level_Role).toInt(); + int delta = m_pItemProxy->indicatorWidth + m_pItemProxy->iconMargin * 2 + std::get<3>(m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]) + std::get<4>(m_pItemProxy->vecItemStyle[level]); + QRect rt = editor->geometry(); + rt.setLeft(delta); + editor->setGeometry(std::move(rt)); + return; +} + +void CNavigationDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem viewOption(option); + if (viewOption.state & QStyle::State_HasFocus) + { + viewOption.state = viewOption.state ^ QStyle::State_HasFocus; + } + + if(!index.isValid()) + { + if (m_pTreeView) + { + painter->fillRect(m_pTreeView->rect(), QColor::fromRgba(m_pItemProxy->backgroundColor)); + } + return; + } + drawItem(painter, viewOption, index); + + bool bExpanded = false; + if (m_pTreeView != NULL) + { + const QAbstractItemModel *model = index.model(); + if (!model->hasChildren(index)) + { + return; + } + bExpanded = m_pTreeView->isExpanded(index); + } + + int height = (viewOption.rect.height() - m_pixmapWidth) / 2; + QPixmap pixmap; + if(index == m_currentHoverIndex) + { + pixmap = bExpanded ? QPixmap(m_strExpandIconHoverName) : QPixmap(m_strCollapseIconHoverName); + } + else + { + pixmap = bExpanded ? QPixmap(m_strExpandIconName) : QPixmap(m_strCollapseIconName); + } + QRect decorationRect = QRect(viewOption.rect.left() + viewOption.rect.width() - ((m_rowHeight + m_pixmapWidth) / 2), viewOption.rect.top() + height, m_pixmapWidth, m_pixmapHeight); + painter->drawPixmap(decorationRect, pixmap); +} + +bool CNavigationDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ +// int height = (option.rect.height() - m_pixmapWidth) / 2; +// QRect decorationRect = QRect(option.rect.left() + option.rect.width() - ((m_rowHeight + m_pixmapWidth) / 2), option.rect.top() + height, m_pixmapWidth, m_pixmapHeight); + + QMouseEvent * pEvent = dynamic_cast(event); + if (pEvent) + { + if(m_currentHoverIndex != index) + { + m_currentHoverIndex = index; + return true; + } + + if (pEvent->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonPress) + { + m_pTreeView->setExpanded(index, !m_pTreeView->isExpanded(index)); + } + } + else + { + m_currentHoverIndex = QModelIndex(); + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +QSize CNavigationDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QSize size = QStyledItemDelegate::sizeHint(option, index); + return QSize(size.width(), m_rowHeight); +} + +void CNavigationDelegate::drawItem(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + QTextOption textOpiton; + textOpiton.setAlignment(option.displayAlignment); + + QRect rt(m_pTreeView->rect().left(), option.rect.top(), m_pTreeView->rect().width(), option.rect.height()); + + int level = index.data(Level_Role).toInt(); + + QPen pen(QColor::fromRgba(std::get<1>(m_pItemProxy->vecItemStyle[level]))); + QBrush brush(QColor::fromRgba(std::get<0>(m_pItemProxy->vecItemStyle[level]))); + if (option.state & QStyle::State_MouseOver) + { + pen.setColor(QColor::fromRgba(m_pItemProxy->itemHoveredTextColor)); + brush.setColor(QColor::fromRgba(m_pItemProxy->itemHoveredColor)); + } + if (option.state & QStyle::State_Selected) + { + pen.setColor(QColor::fromRgba(m_pItemProxy->itemSelectedTextColor)); + brush.setColor(QColor::fromRgba(m_pItemProxy->itemSelectedColor)); + } + painter->fillRect(rt, std::move(brush)); + + + int delta = m_pItemProxy->indicatorWidth + m_pItemProxy->iconMargin + std::get<4>(m_pItemProxy->vecItemStyle[level]); + + //< draw Icon + int iconSize = std::get<3>(m_pItemProxy->vecItemStyle[level]); + QTreeWidgetItem * item = reinterpret_cast(index.internalPointer()); + if(item) + { + QPixmap pixmap = item->icon(0).pixmap(iconSize, iconSize); + if(!pixmap.isNull()) + { + QRect iconRect(delta + level, option.rect.top() + (option.rect.height() - iconSize) / 2., iconSize, iconSize); + painter->drawPixmap(iconRect, pixmap); + } + } + + //< draw Text + delta += std::get<3>(m_pItemProxy->vecItemStyle[CNavigationWidget::TOP_LEVEL]); + delta += m_pItemProxy->iconMargin; + rt.adjust(delta, 0, 0, 0); + painter->setPen(std::move(pen)); + QFont font = option.font; + font.setPixelSize(std::get<2>(m_pItemProxy->vecItemStyle[level])); + painter->setFont(std::move(font)); + painter->drawText(rt, index.data().toString(), textOpiton); + painter->restore(); +} diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.h b/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.h index 7e8f3c70..1007cecd 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.h +++ b/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.h @@ -1,56 +1,56 @@ -#ifndef CNAVIGATIONDELEGATE_H -#define CNAVIGATIONDELEGATE_H - -#include -#include - -struct ITEM_STYLE_PROXY; - -class CNavigationDelegate : public QStyledItemDelegate -{ - Q_OBJECT - - friend class CNavigationWidget; - -public: - CNavigationDelegate(ITEM_STYLE_PROXY * proxy, QObject *parent = Q_NULLPTR); - - virtual ~CNavigationDelegate(); - - void setView(QTreeView *pTreeView); - - void setBranchIconSize(const QSize &size); - - void setExpandIcon(const QString &iconName); - void setCollapseIcon(const QString &iconName); - - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; - - void setEditorData(QWidget *editor, const QModelIndex &index) const; - - void paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const Q_DECL_OVERRIDE; - - bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; - - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; - -protected: - void drawItem(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const; - -private: - QTreeView * m_pTreeView; - - int m_pixmapWidth; - int m_pixmapHeight; - int m_rowHeight; - - QModelIndex m_currentHoverIndex; - QString m_strExpandIconName; - QString m_strCollapseIconName; - QString m_strExpandIconHoverName; - QString m_strCollapseIconHoverName; - - ITEM_STYLE_PROXY * m_pItemProxy; -}; - -#endif // CNAVIGATIONDELEGATE_H +#ifndef CNAVIGATIONDELEGATE_H +#define CNAVIGATIONDELEGATE_H + +#include +#include + +struct ITEM_STYLE_PROXY; + +class CNavigationDelegate : public QStyledItemDelegate +{ + Q_OBJECT + + friend class CNavigationWidget; + +public: + CNavigationDelegate(ITEM_STYLE_PROXY * proxy, QObject *parent = Q_NULLPTR); + + virtual ~CNavigationDelegate(); + + void setView(QTreeView *pTreeView); + + void setBranchIconSize(const QSize &size); + + void setExpandIcon(const QString &iconName); + void setCollapseIcon(const QString &iconName); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setEditorData(QWidget *editor, const QModelIndex &index) const; + + void paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const Q_DECL_OVERRIDE; + + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; + +protected: + void drawItem(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const; + +private: + QTreeView * m_pTreeView; + + int m_pixmapWidth; + int m_pixmapHeight; + int m_rowHeight; + + QModelIndex m_currentHoverIndex; + QString m_strExpandIconName; + QString m_strCollapseIconName; + QString m_strExpandIconHoverName; + QString m_strCollapseIconHoverName; + + ITEM_STYLE_PROXY * m_pItemProxy; +}; + +#endif // CNAVIGATIONDELEGATE_H diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.cpp b/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.cpp index 6d85c665..b40bcc39 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.cpp +++ b/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CNavigationPluginWidget.h" -#include "CNavigationWidget.h" - -CNavigationPluginWidget::CNavigationPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CNavigationPluginWidget::~CNavigationPluginWidget() -{ - -} - -bool CNavigationPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CNavigationWidget *pWidget = new CNavigationWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *pNavigationWidget = (IPluginWidget *)pWidget; - return true; -} - -void CNavigationPluginWidget::release() -{ - -} +#include +#include "CNavigationPluginWidget.h" +#include "CNavigationWidget.h" + +CNavigationPluginWidget::CNavigationPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CNavigationPluginWidget::~CNavigationPluginWidget() +{ + +} + +bool CNavigationPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CNavigationWidget *pWidget = new CNavigationWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pNavigationWidget = (IPluginWidget *)pWidget; + return true; +} + +void CNavigationPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.h b/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.h index 6c4b7c2a..afb1b2ec 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.h +++ b/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CNAVIGATIONPLUGINWIDGET_H -#define CNAVIGATIONPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CNavigationPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CNavigationPluginWidget(QObject *parent = 0); - ~CNavigationPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec); - void release(); -}; - -#endif //CNAVIGATIONPLUGINWIDGET_H - +#ifndef CNAVIGATIONPLUGINWIDGET_H +#define CNAVIGATIONPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CNavigationPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CNavigationPluginWidget(QObject *parent = 0); + ~CNavigationPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec); + void release(); +}; + +#endif //CNAVIGATIONPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationWidget.cpp b/product/src/gui/plugin/NavigationWidget/CNavigationWidget.cpp index 299760a8..7eb50151 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationWidget.cpp +++ b/product/src/gui/plugin/NavigationWidget/CNavigationWidget.cpp @@ -1,1202 +1,1202 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CNavigationWidget.h" -#include "CNavigationDelegate.h" -#include "CNavigationConfigDialog.h" -#include "public/pub_utility_api/FileUtil.h" -#include "model_excel/xlsx/xlsxdocument.h" - -const int Level_Role = Qt::UserRole + 1; -const int Corner_Role = Qt::UserRole + 2; -const int IconPath_Role = Qt::UserRole + 3; -const int Item_Role = Qt::UserRole + 4; -const int Enable_Role = Qt::UserRole + 5; -const int Web_Role = Qt::UserRole + 6; -const int Opt_Role = Qt::UserRole + 7; -const int Url_Role = Qt::UserRole + 8; - -CNavigationWidget::CNavigationWidget(QWidget *parent, bool editMode) - : QTreeWidget(parent), - m_pItemProxy(Q_NULLPTR), - m_pItemDelegate(Q_NULLPTR), - m_navigationMode(EXPLORER_MODE) -{ - if(editMode) - { - m_navigationMode = EDIT_MODE; - } - initialize(); -} - -CNavigationWidget::~CNavigationWidget() -{ - if(m_pItemProxy) - { - delete m_pItemProxy; - } - m_pItemProxy = Q_NULLPTR; -} - -void CNavigationWidget::initialize() -{ - setStyleSheet("background-color:transparent;QLineEdit:edit-focus{background-color:white}"); - setMouseTracking(true); - setRootIsDecorated(false); - header()->setVisible(false); - connect(this, &CNavigationWidget::currentItemChanged, this, &CNavigationWidget::itemSelectedChanged); - connect(this, &CNavigationWidget::itemClicked, this, &CNavigationWidget::itemSelected); - - std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); - m_strFileHomePath = QString::fromStdString(currentPath) + QString("..%1..%1data%1").arg(QDir::separator()); - m_mapEnable.insert(Enable, tr("是")); - m_mapEnable.insert(Disable, tr("否")); - m_mapNodeType.insert(SWITCH_GRAPH, tr("切换画面")); - m_mapNodeType.insert(EXTERN_PRO, tr("调用程序")); - - initStyleProxy(); - loadItemDelegate(); - - QString strItemConfigFile = m_strFileHomePath + QString("model%1NavigationWidget.json").arg(QDir::separator()); - read(strItemConfigFile); - if(EDIT_MODE != m_navigationMode) - { - expandAll(); - } -} - -void CNavigationWidget::setNavigationMode(const CNavigationWidget::Navigation_Mode &navigationMode) -{ - m_navigationMode = navigationMode; - if(CONFIG_MODE == m_navigationMode) - { - connect(this, &CNavigationWidget::itemDoubleClicked, this, &CNavigationWidget::editItem); - setEditTriggers(DoubleClicked); - } -} - -void CNavigationWidget::config() -{ - return; //< 1.4.1 统一到菜单配置 - CNavigationConfigDialog cfg; - cfg.updateItems(this); - int res = cfg.exec(); - if(QDialog::Accepted == res) - { - clear(); - const CNavigationWidget * pNavigation = cfg.NavigationWidegt(); - updateItems(pNavigation); - updateStyleProxy(pNavigation->m_pItemProxy); - QString strItemConfigFile = m_strFileHomePath + QString("model%1NavigationWidget.json").arg(QDir::separator()); - write(strItemConfigFile); - } -} - -void CNavigationWidget::setTopLevelIndexes(const QString &strIndexes) -{ - QList indexVisibleList; - QStringList listIndex = strIndexes.split(","); - foreach (QString strIndex, listIndex) - { - indexVisibleList.append(strIndex.toInt()); - } - - bool isFirstItem = true; - for(int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) - { - if(nIndex < indexVisibleList.size()) - { - bool isHidden = (0 == indexVisibleList.at(nIndex)); - topLevelItem(nIndex)->setHidden(isHidden); - QTreeWidgetItem *item = topLevelItem(nIndex); - while(!isHidden && isFirstItem && item) - { - if(item->data(0,Qt::UserRole).toString() != QString()) - { - isFirstItem = false; - setCurrentIndex(indexFromItem(item)); - emit itemClicked(item,0); - break; - } - item = item->child(0); - } - } - else - { - topLevelItem(nIndex)->setHidden(true); - } - } -} - -void CNavigationWidget::setItemSelected(const QString &data) -{ - QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); - QString dataPath = dataDir.absoluteFilePath(data); - for(int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) - { - if(topLevelItem(nIndex)->isHidden()) - { - continue; - } - QTreeWidgetItem * item = findItem(dataPath, topLevelItem(nIndex)); - if(item) - { - this->clearSelection(); - item->setSelected(true); - break; - } - } -} - -void CNavigationWidget::paintEvent(QPaintEvent *event) -{ - QPainter painter(viewport()); - painter.fillRect(viewport()->rect(), m_pItemProxy->backgroundColor); - QTreeView::paintEvent(event); -} - -void CNavigationWidget::initStyleProxy() -{ - m_pItemProxy = new ITEM_STYLE_PROXY(); - m_pItemProxy->indicatorWidth = 3; - m_pItemProxy->iconMargin = 5; - - m_pItemProxy->backgroundColor = 0x000C17; - m_pItemProxy->itemHoveredColor = 0x002C53; - m_pItemProxy->itemSelectedColor = 0x022C53; - - m_pItemProxy->itemTextColor = 0xBFC8D5; - m_pItemProxy->itemHoveredTextColor = 0xFFFFFF; - m_pItemProxy->itemSelectedTextColor = 0x1890FF; - - NodeInfo topNodeInfo(0x002140, 0xBFC8D5, 15, 21, 0); - NodeInfo childNodeInfo(0x000C17, 0xBFC8D5, 14, 16, 0); - NodeInfo leafNodeInfo(0x000C17, 0xBFC8D5, 12, 14, 0); - m_pItemProxy->vecItemStyle.push_back(std::move(topNodeInfo)); - m_pItemProxy->vecItemStyle.push_back(std::move(childNodeInfo)); - m_pItemProxy->vecItemStyle.push_back(std::move(leafNodeInfo)); -} - -void CNavigationWidget::getNodeTypeMap(QMap &map) -{ - map = m_mapNodeType; -} - -void CNavigationWidget::addTopLevelItem(const int &number, const QString &caption, const QString &data, const QString &icon, - const int &enable, const int &web, const int &type, const QString &url) -{ - if(caption.isEmpty()) - { - return; - } - QTreeWidgetItem * topLevelItem = new QTreeWidgetItem(QStringList() << caption); - topLevelItem->setData(0, Level_Role, TOP_LEVEL); - topLevelItem->setData(0, Corner_Role, false); - topLevelItem->setData(0, IconPath_Role, icon); - topLevelItem->setData(0, Item_Role, number); - topLevelItem->setData(0, Enable_Role, enable); - topLevelItem->setData(0, Web_Role, web); - topLevelItem->setData(0, Opt_Role, type); - topLevelItem->setData(0, Url_Role, url); - - if(!data.isEmpty()) - { - topLevelItem->setData(0, Qt::UserRole, data); - } - - if(!icon.isEmpty()) - { - topLevelItem->setIcon(0, QIcon(icon)); - } - - QTreeWidget::addTopLevelItem(topLevelItem); - if(CONFIG_MODE == m_navigationMode) - { - topLevelItem->setFlags(topLevelItem->flags() | Qt::ItemIsEditable); - topLevelItem->setExpanded(true); - setCurrentItem(topLevelItem); - } -} - -void CNavigationWidget::addChildItem(const int &number, const QList &parents, const QString &caption, const QString &data, const QString &icon, - const int &enable, const int &web, const int &type, const QString &url) -{ - if(parents.isEmpty() || caption.isEmpty()) - { - return; - } - - for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) - { - if(topLevelItem(nIndex)->data(0, Item_Role).toInt() == parents.first()) - { - QTreeWidgetItem * parent = topLevelItem(nIndex); - //< 查找二级节点 - if(1 < parents.size()) - { - //< 查找失败则添加到二级节点 - for(int nChildIndex(0); nChildIndex < parent->childCount(); nChildIndex++) - { - if(parent->child(nChildIndex)->data(0, Item_Role).toInt() == parents.at(1)) - { - parent = parent->child(nChildIndex); - break; - } - } - } - QTreeWidgetItem * item = new QTreeWidgetItem(parent, QStringList() << caption); - item->setData(0, Level_Role, parent->data(0, Level_Role).toInt() + 1); - item->setData(0, Corner_Role, false); - item->setData(0, IconPath_Role, icon); - item->setData(0, Item_Role, number); - item->setData(0, Enable_Role, enable); - item->setData(0, Web_Role, web); - item->setData(0, Opt_Role, type); - item->setData(0, Url_Role, url); - if(!data.isEmpty()) - { - item->setData(0, Qt::UserRole, data); - } - - if(!icon.isEmpty()) - { - item->setIcon(0, QIcon(icon)); - } - - if(CONFIG_MODE == m_navigationMode) - { - item->setFlags(item->flags() | Qt::ItemIsEditable); - item->parent()->setExpanded(true); - item->parent()->setSelected(true); - } - } - } -} - -void CNavigationWidget::addLevelItem(const int &number, const QList &parents, const QString &caption, const QString &data, const QString &icon, - const int &enable, const int &web, const int &type, const QString &url) -{ - if(parents.isEmpty() || caption.isEmpty()) - { - return; - } - - for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) - { - if(topLevelItem(nIndex)->data(0, Item_Role).toInt() == parents.at(0)) - { - QTreeWidgetItem * item = new QTreeWidgetItem(QStringList() << caption); - item->setData(0, Corner_Role, false); - item->setData(0, IconPath_Role, icon); - item->setData(0, Item_Role, number); - item->setData(0, Enable_Role, enable); - item->setData(0, Web_Role, web); - item->setData(0, Opt_Role, type); - item->setData(0, Url_Role, url); - if(!data.isEmpty()) - { - item->setData(0, Qt::UserRole, data); - } - if(!icon.isEmpty()) - { - item->setIcon(0, QIcon(icon)); - } - - QTreeWidgetItem * top = topLevelItem(nIndex); - //< 查找二级节点 - if(1 < parents.size()) - { - for(int nChildIndex(0); nChildIndex < top->childCount(); nChildIndex++) - { - if(top->child(nChildIndex)->data(0, Item_Role).toInt() == parents.at(1)) - { - QTreeWidgetItem * child = top->child(nChildIndex); - //< 查找三级节点 - if(2 < parents.size()) - { - for(int nLeafIndex(0); nLeafIndex < child->childCount(); nLeafIndex++) - { - if(child->child(nLeafIndex)->data(0, Item_Role).toInt() == parents.at(2)) - { - item->setData(0, Level_Role, child->data(0, Level_Role).toInt() + 1); - child->insertChild(nLeafIndex, item); - if(CONFIG_MODE == m_navigationMode) - { - item->setFlags(item->flags() | Qt::ItemIsEditable); - item->setSelected(true); - setCurrentItem(item); - } - return; - } - } - } - item->setData(0, Level_Role, top->data(0, Level_Role).toInt() + 1); - top->insertChild(nChildIndex, item); - if(CONFIG_MODE == m_navigationMode) - { - item->setFlags(item->flags() | Qt::ItemIsEditable); - item->setSelected(true); - setCurrentItem(item); - } - return; - } - } - } - item->setData(0, Level_Role, TOP_LEVEL); - QTreeWidget::insertTopLevelItem(nIndex, item); - if(CONFIG_MODE == m_navigationMode) - { - item->setFlags(item->flags() | Qt::ItemIsEditable); - item->setSelected(true); - setCurrentItem(item); - } - return; - } - } -} - -void CNavigationWidget::removeItem(QTreeWidgetItem *item) -{ - if(item->parent()) - { - item->parent()->removeChild(item); - } - else - { - takeTopLevelItem(indexFromItem(item).row()); - } -} - -int CNavigationWidget::slotImport() -{ - QString filePath = QFileDialog::getOpenFileName(this, tr("导入"), "", "*.xlsx"); - if(filePath.isEmpty()) - return -1; - - clear(); - QXlsx::Document xlsx(filePath); - QXlsx::CellRange cellRange = xlsx.currentWorksheet()->dimension(); - QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); - QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); - QDir exeDir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); - QMultiMap numberMap; - int nItemNumber = 0; - for(int row=cellRange.firstRow()+1; row<=cellRange.lastRow(); row++) - { - QString firName = xlsx.read(row, 1).toString().trimmed(); - if(firName.isEmpty()) - { - continue; - } - QString name; - QString secName = xlsx.read(row, 2).toString().trimmed(); - QString trdName = xlsx.read(row, 3).toString().trimmed(); - int used = getEnable(xlsx.read(row, 4).toString()); - int opt = getNodeType(xlsx.read(row, 5).toString()); - QString icon = xlsx.read(row, 6).toString(); - QString data = xlsx.read(row, 7).toString(); - int web = getEnable(xlsx.read(row, 8).toString()); - if(!data.isEmpty()) - { - if(opt == EXTERN_PRO) - { - data = exeDir.absoluteFilePath(data); - } - else - { - data = dataDir.absoluteFilePath(data); - } - } - if(!icon.isEmpty()) - { - icon = iconDir.absoluteFilePath(icon); - } - if(secName.isEmpty()) - { - name = firName; - addTopLevelItem(nItemNumber, firName, data, icon, used, web, opt); - } - else if(!secName.isEmpty() && trdName.isEmpty()) - { - QList list; - list.append(findValue(numberMap, firName)); - name = secName; - addChildItem(nItemNumber, list, secName, data, icon, used, web, opt); - } - else - { - QList list; - list.append(findValue(numberMap, firName)); - list.append(findValue(numberMap, secName)); - name = trdName; - addChildItem(nItemNumber, list, trdName, data, icon, used, web, opt); - } - - numberMap.insert(name, nItemNumber++); - } - return nItemNumber; -} - -void CNavigationWidget::slotExport() -{ - QString filePath = QFileDialog::getSaveFileName(this, tr("导出"), "nav.xlsx", "*.xlsx"); - if(filePath.isEmpty()) - return; - - QXlsx::Document xlsx; - - xlsx.write(hexTo26(0)+"1", tr("一级")); - xlsx.write(hexTo26(1)+"1", tr("二级")); - xlsx.write(hexTo26(2)+"1", tr("三级")); - xlsx.write(hexTo26(3)+"1", tr("是否使用")); - xlsx.write(hexTo26(4)+"1", tr("操作")); - xlsx.write(hexTo26(5)+"1", tr("图标")); - xlsx.write(hexTo26(6)+"1", tr("数据")); - xlsx.write(hexTo26(7)+"1", tr("web发布")); - xlsx.setColumnWidth(1, 8, 30); - - QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); - QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); - QDir exeDir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); - int row = 2; - for (int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) - { - //< Top_Level_Item - QTreeWidgetItem * item_top_level = topLevelItem(nIndex); - QString tName = item_top_level->data(0, Qt::DisplayRole).toString(); - QString tData = dataDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString()); - if(item_top_level->data(0, Opt_Role).toInt() == EXTERN_PRO) - { - tData = exeDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString()); - } - QString tIcon = iconDir.relativeFilePath(item_top_level->data(0, IconPath_Role).toString()); - QString tUsed = getEnableStr(item_top_level->data(0, Enable_Role).toInt()); - QString tOpt = getNodeTypeStr(item_top_level->data(0, Opt_Role).toInt()); - QString tWeb = getEnableStr(item_top_level->data(0, Web_Role).toInt()); - xlsx.write(hexTo26(0)+QString::number(row), tName); - xlsx.write(hexTo26(3)+QString::number(row), tUsed); - xlsx.write(hexTo26(4)+QString::number(row), tOpt); - xlsx.write(hexTo26(5)+QString::number(row), tIcon); - xlsx.write(hexTo26(6)+QString::number(row), tData); - xlsx.write(hexTo26(7)+QString::number(row++), tWeb); - for (int nChildIndex(0); nChildIndex < item_top_level->childCount(); ++nChildIndex) - { - //< Child_Level_Item - QTreeWidgetItem * item_child_level = item_top_level->child(nChildIndex); - QString cName = item_child_level->data(0, Qt::DisplayRole).toString(); - QString cData = dataDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString()); - if(item_child_level->data(0, Opt_Role).toInt() == EXTERN_PRO) - { - cData = exeDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString()); - } - QString cIcon = iconDir.relativeFilePath(item_child_level->data(0, IconPath_Role).toString()); - QString cUsed = getEnableStr(item_child_level->data(0, Enable_Role).toInt()); - QString cOpt = getNodeTypeStr(item_child_level->data(0, Opt_Role).toInt()); - QString cWeb = getEnableStr(item_child_level->data(0, Web_Role).toInt()); - xlsx.write(hexTo26(0)+QString::number(row), tName); - xlsx.write(hexTo26(1)+QString::number(row), cName); - xlsx.write(hexTo26(3)+QString::number(row), cUsed); - xlsx.write(hexTo26(4)+QString::number(row), cOpt); - xlsx.write(hexTo26(5)+QString::number(row), cIcon); - xlsx.write(hexTo26(6)+QString::number(row), cData); - xlsx.write(hexTo26(7)+QString::number(row++), cWeb); - for (int nLeafIndex(0); nLeafIndex < item_child_level->childCount(); ++nLeafIndex) - { - //< Leaf_Level_Item - QTreeWidgetItem * item_leaf_level = item_child_level->child(nLeafIndex); - QString lName = item_leaf_level->data(0, Qt::DisplayRole).toString(); - QString lData = dataDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString()); - if(item_leaf_level->data(0, Opt_Role).toInt() == EXTERN_PRO) - { - lData = exeDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString()); - } - QString lIcon = iconDir.relativeFilePath(item_leaf_level->data(0, IconPath_Role).toString()); - QString lUsed = getEnableStr(item_leaf_level->data(0, Enable_Role).toInt()); - QString lOpt = getNodeTypeStr(item_leaf_level->data(0, Opt_Role).toInt()); - QString lWeb = getEnableStr(item_leaf_level->data(0, Web_Role).toInt()); - xlsx.write(hexTo26(0)+QString::number(row), tName); - xlsx.write(hexTo26(1)+QString::number(row), cName); - xlsx.write(hexTo26(2)+QString::number(row), lName); - xlsx.write(hexTo26(3)+QString::number(row), lUsed); - xlsx.write(hexTo26(4)+QString::number(row), lOpt); - xlsx.write(hexTo26(5)+QString::number(row), lIcon); - xlsx.write(hexTo26(6)+QString::number(row), lData); - xlsx.write(hexTo26(7)+QString::number(row++), lWeb); - } - } - } - - if(xlsx.saveAs(filePath)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } -} - -void CNavigationWidget::clearItems() -{ - clear(); -} - -void CNavigationWidget::loadItemDelegate() -{ - m_pItemDelegate = new CNavigationDelegate(m_pItemProxy, this); - m_pItemDelegate->setView(this); - setItemDelegate(m_pItemDelegate); -} - -void CNavigationWidget::updateItems(const CNavigationWidget *pNavigation) -{ - if(Q_NULLPTR == pNavigation) - { - return; - } - - for(int nIndex(0); nIndex < pNavigation->topLevelItemCount(); nIndex++) - { - QTreeWidgetItem * item = pNavigation->topLevelItem(nIndex); - QTreeWidgetItem * newItem = buildNewItem(item); - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - QTreeWidgetItem * childItem = item->child(nChildIndex); - QTreeWidgetItem * newChildItem = buildNewItem(childItem); - for(int nLeafIndex(0); nLeafIndex < childItem->childCount(); nLeafIndex++) - { - newChildItem->addChild(buildNewItem(childItem->child(nLeafIndex))); - } - newItem->addChild(newChildItem); - } - QTreeWidget::addTopLevelItem(newItem); - } -} - -QTreeWidgetItem *CNavigationWidget::buildNewItem(const QTreeWidgetItem *parent) -{ - QTreeWidgetItem * item = new QTreeWidgetItem(*parent); - item->setData(0, Corner_Role, false); - if(CONFIG_MODE == m_navigationMode) - { - item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable); - } - else - { - item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); - } - return item; -} - -void CNavigationWidget::updateStyleProxy(const ITEM_STYLE_PROXY *proxy) -{ - if(Q_NULLPTR == proxy) - { - return; - } - m_pItemProxy->backgroundColor = proxy->backgroundColor; - m_pItemProxy->itemHoveredColor = proxy->itemHoveredColor; - m_pItemProxy->itemSelectedColor = proxy->itemSelectedColor; - m_pItemProxy->itemTextColor = proxy->itemTextColor; - m_pItemProxy->itemHoveredTextColor = proxy->itemHoveredTextColor; - m_pItemProxy->itemSelectedTextColor = proxy->itemSelectedTextColor; - m_pItemProxy->vecItemStyle = proxy->vecItemStyle; -} - -void CNavigationWidget::contextMenuEvent(QContextMenuEvent *e) -{ - if(EDIT_MODE == m_navigationMode) - { - QMenu menu; - QAction * pActionCfg = new QAction(tr("属性配置")); - connect(pActionCfg, &QAction::triggered, this, &CNavigationWidget::config); - menu.addAction(pActionCfg); - menu.exec(e->globalPos()); - } - else if(EXPLORER_MODE == m_navigationMode) - { - QMenu menu; - QAction * pActionExp = new QAction(tr("全部展开")); - QAction * pActionCol = new QAction(tr("全部收缩")); - connect(pActionExp, &QAction::triggered, this, [=](){expandAll();}); - connect(pActionCol, &QAction::triggered, this, [=](){collapseAll();}); - menu.addAction(pActionExp); - menu.addAction(pActionCol); - menu.exec(e->globalPos()); - } -} - -void CNavigationWidget::itemSelectedChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) -{ - setFocus(); - update(); - if(previous) - { - if(TOP_LEVEL == previous->data(0, Level_Role)) - { - previous->setData(0, Corner_Role, false); - } - else if(CHILD_LEVEL == previous->data(0, Level_Role)) - { - previous->parent()->setData(0, Corner_Role, false); - } - else if(LEAF_LEVEL == previous->data(0, Level_Role)) - { - previous->parent()->parent()->setData(0, Corner_Role, false); - } - } - - if(current) - { - if(TOP_LEVEL == current->data(0, Level_Role)) - { - current->setData(0, Corner_Role, true); - } - else if(CHILD_LEVEL == current->data(0, Level_Role)) - { - current->parent()->setData(0, Corner_Role, true); - } - else if(LEAF_LEVEL == current->data(0, Level_Role)) - { - current->parent()->parent()->setData(0, Corner_Role, true); - } - -// QFileInfo info(current->data(0, Qt::UserRole).toString()); -// emit graphItemClicked(current->data(0, Qt::DisplayRole).toString(), info.fileName()); - } -} - -void CNavigationWidget::itemSelected(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column) - if(item) - { - if(TOP_LEVEL == item->data(0, Level_Role)) - { - item->setData(0, Corner_Role, true); - } - else if(CHILD_LEVEL == item->data(0, Level_Role)) - { - item->parent()->setData(0, Corner_Role, true); - } - else if(LEAF_LEVEL == item->data(0, Level_Role)) - { - item->parent()->parent()->setData(0, Corner_Role, true); - } - - QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); - QString fileName = dataDir.relativeFilePath(item->data(0, Qt::UserRole).toString()); - emit graphItemClicked(item->data(0, Qt::DisplayRole).toString(), fileName, - item->data(0, Opt_Role).toInt(), item->data(0, Url_Role).toString()); - } -} - -void CNavigationWidget::setIconSize(const int &width, const int &height) -{ - QTreeWidget::setIconSize(QSize(width, height)); -} - -void CNavigationWidget::setBranchIconSize(const int &width, const int &height) -{ - if(m_pItemDelegate) - { - m_pItemDelegate->setBranchIconSize(QSize(width, height)); - } -} - -void CNavigationWidget::setRowHeight(const int &rowHeight) -{ - if(m_pItemDelegate) - { - m_pItemDelegate->m_rowHeight = rowHeight; - } - resize(size()); -} - -void CNavigationWidget::setIndentation(const int &indentation) -{ - QTreeWidget::setIndentation(indentation); -} - -void CNavigationWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const -{ - if(!index.isValid()) - { - return; - } - QTreeWidget::drawRow(painter, options, index); - - if(index.data(Corner_Role).toBool()) - { - QRect rt = visualRect(index); - painter->setPen(Qt::transparent); - painter->setBrush(QColor(m_pItemProxy->itemSelectedTextColor)); - painter->drawRect(QRectF(rt.x(), rt.y() + 0.5, m_pItemProxy->indicatorWidth, rt.height() - 0.5)); - } -} - -void CNavigationWidget::setTreeBackgroundColor(const rgb &color) -{ - if(m_pItemProxy) - { - m_pItemProxy->backgroundColor = color; - } -} - -void CNavigationWidget::setItemHoverBackgroundColor(const rgb &color) -{ - if(m_pItemProxy) - { - m_pItemProxy->itemHoveredColor = color; - } -} - -void CNavigationWidget::setItemSelectedBackgroundColor(const rgb &color) -{ - if(m_pItemProxy) - { - m_pItemProxy->itemSelectedColor = color; - } -} - -void CNavigationWidget::setTextColor(const rgb &color) -{ - if(m_pItemProxy) - { - m_pItemProxy->itemTextColor = color; - } -} - -void CNavigationWidget::setTextHoverColor(const rgb &color) -{ - if(m_pItemProxy) - { - m_pItemProxy->itemHoveredTextColor = color; - } -} - -void CNavigationWidget::setTextSelectedColor(const rgb &color) -{ - if(m_pItemProxy) - { - m_pItemProxy->itemSelectedTextColor = color; - } -} - -void CNavigationWidget::setItemBackgroundColor(const rgb &color, const Node_Level &level) -{ - if(m_pItemProxy) - { - std::get<0>(m_pItemProxy->vecItemStyle[level]) = color; - } -} - -void CNavigationWidget::setItemTextSize(const int &size, const Node_Level &level) -{ - if(m_pItemProxy) - { - std::get<2>(m_pItemProxy->vecItemStyle[level]) = size; - } -} - -void CNavigationWidget::read(const QString &strFileName) -{ - QFile loadFile(strFileName); - if(!loadFile.open(QIODevice::ReadOnly)) - { - qDebug() << "could't open file 'NavigationWidget.json'!"; - return; - } - - QByteArray data = loadFile.readAll(); - loadFile.close(); - - QJsonParseError json_error; - QJsonDocument jsonDoc(QJsonDocument::fromJson(data, &json_error)); - - if(json_error.error != QJsonParseError::NoError) - { - qDebug() << "'NavigationWidget.json' parse Error!"; - return; - } - - QJsonObject root = jsonDoc.object(); - if(root.contains("configure")) - { - QJsonObject configObject = root.value("configure").toObject(); - m_pItemProxy->backgroundColor = QColor(configObject["backgroundColor"].toString()).rgb(); - m_pItemProxy->indicatorWidth = configObject["indicatorWidth"].toInt(); - m_pItemProxy->iconMargin = configObject["iconMargin"].toInt(); - m_pItemDelegate->m_rowHeight = configObject["rowHeight"].toInt(); - - std::get<0>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemBgColor"].toString()).rgb(); - std::get<1>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemTextColor"].toString()).rgb(); - std::get<2>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemTextSize"].toInt(); - std::get<3>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemIconSize"].toInt(); - std::get<4>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemIndentation"].toInt(); - - std::get<0>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemBgColor"].toString()).rgb(); - std::get<1>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemTextColor"].toString()).rgb(); - std::get<2>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemTextSize"].toInt(); - std::get<3>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemIconSize"].toInt(); - std::get<4>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemIndentation"].toInt(); - - std::get<0>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemBgColor"].toString()).rgb(); - std::get<1>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemTextColor"].toString()).rgb(); - std::get<2>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemTextSize"].toInt(); - std::get<3>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemIconSize"].toInt(); - std::get<4>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemIndentation"].toInt(); - - m_pItemProxy->itemHoveredColor = QColor(configObject["itemHoveredBgColor"].toString()).rgb(); - m_pItemProxy->itemSelectedColor = QColor(configObject["itemSelectedColor"].toString()).rgb(); - m_pItemProxy->itemHoveredTextColor = QColor(configObject["itemHoveredTextColor"].toString()).rgb(); - m_pItemProxy->itemSelectedTextColor = QColor(configObject["itemSelectedTextColor"].toString()).rgb(); - } - - if(root.contains("items")) - { - QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); - QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); - QDir exeDir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); - QJsonArray itemArray = root.value("items").toArray(); - int nItemNumber = 0; - for(int nIndex(0); nIndex< itemArray.size(); nIndex++) - { - QJsonObject topLevelObject = itemArray[nIndex].toObject(); - QTreeWidgetItem * item_top_level = new QTreeWidgetItem(this); - item_top_level->setData(0, Qt::DisplayRole, topLevelObject.value("name").toString()); - item_top_level->setData(0, Level_Role, TOP_LEVEL); - item_top_level->setData(0, Item_Role, nItemNumber++); - item_top_level->setData(0, Enable_Role, topLevelObject.value("used").toInt(Enable)); - item_top_level->setData(0, Web_Role, topLevelObject.value("web").toInt(Enable)); - item_top_level->setData(0, Opt_Role, topLevelObject.value("opt").toInt(SWITCH_GRAPH)); - item_top_level->setData(0, Url_Role, topLevelObject.value("url").toString()); - if(!topLevelObject.value("data").toString().isEmpty()) - { - if(topLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) - { - item_top_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(topLevelObject.value("data").toString())); - } - else - { - item_top_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(topLevelObject.value("data").toString())); - } - } - QString topLevelIconName = topLevelObject.value("icon").toString(); - if(!topLevelIconName.isEmpty()) - { - item_top_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(topLevelIconName)); - item_top_level->setIcon(0, QIcon(iconDir.absoluteFilePath(topLevelIconName))); - } - - QJsonArray childArray = topLevelObject.value("items").toArray(); - for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) - { - QJsonObject childLevelObject = childArray[nChildIndex].toObject(); - QTreeWidgetItem * item_child_level = new QTreeWidgetItem(item_top_level); - item_child_level->setData(0, Qt::DisplayRole, childLevelObject.value("name").toString()); - item_child_level->setData(0, Level_Role, CHILD_LEVEL); - item_child_level->setData(0, Item_Role, nItemNumber++); - item_child_level->setData(0, Enable_Role, childLevelObject.value("used").toInt(Enable)); - item_child_level->setData(0, Web_Role, childLevelObject.value("web").toInt(Enable)); - item_child_level->setData(0, Opt_Role, childLevelObject.value("opt").toInt(SWITCH_GRAPH)); - item_child_level->setData(0, Url_Role, childLevelObject.value("url").toString()); - if(!childLevelObject.value("data").toString().isEmpty()) - { - if(childLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) - { - item_child_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(childLevelObject.value("data").toString())); - } - else - { - item_child_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(childLevelObject.value("data").toString())); - } - } - QString childLevelIconName = childLevelObject.value("icon").toString(); - if(!childLevelIconName.isEmpty()) - { - item_child_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(childLevelIconName)); - item_child_level->setIcon(0, QIcon(iconDir.absoluteFilePath(childLevelIconName))); - } - - QJsonArray leafArray = childLevelObject.value("items").toArray(); - for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) - { - QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); - QTreeWidgetItem * item_leaf_level = new QTreeWidgetItem(item_child_level); - item_leaf_level->setData(0, Qt::DisplayRole, leafLevelObject.value("name").toString()); - item_leaf_level->setData(0, Level_Role, LEAF_LEVEL); - item_leaf_level->setData(0, Item_Role, nItemNumber++); - item_leaf_level->setData(0, Enable_Role, leafLevelObject.value("used").toInt(Enable)); - item_leaf_level->setData(0, Web_Role, leafLevelObject.value("web").toInt(Enable)); - item_leaf_level->setData(0, Opt_Role, leafLevelObject.value("opt").toInt(SWITCH_GRAPH)); - item_leaf_level->setData(0, Url_Role, leafLevelObject.value("url").toString()); - if(!leafLevelObject.value("data").toString().isEmpty()) - { - if(leafLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) - { - item_leaf_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(leafLevelObject.value("data").toString())); - } - else - { - item_leaf_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(leafLevelObject.value("data").toString())); - } - } - QString leafLevelIconName = leafLevelObject.value("icon").toString(); - if(!leafLevelIconName.isEmpty()) - { - item_leaf_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(leafLevelIconName)); - item_leaf_level->setIcon(0, QIcon(iconDir.absoluteFilePath(leafLevelIconName))); - } - item_child_level->addChild(item_leaf_level); - if(EXPLORER_MODE == m_navigationMode) - { - item_leaf_level->setHidden(item_leaf_level->data(0, Enable_Role).toInt()==Enable?false:true); - } - } - item_top_level->addChild(item_child_level); - if(EXPLORER_MODE == m_navigationMode) - { - item_child_level->setHidden(item_child_level->data(0, Enable_Role).toInt()==Enable?false:true); - } - } - QTreeWidget::addTopLevelItem(item_top_level); - if(EXPLORER_MODE == m_navigationMode) - { - item_top_level->setHidden(item_top_level->data(0, Enable_Role).toInt()==Enable?false:true); - } - } - } -} - -void CNavigationWidget::write(const QString &strFileName) -{ - QFile file(strFileName); - //< 不存在则创建 - if(!file.exists()) - { - file.setFileName(strFileName); - } - - if(file.open(QIODevice::WriteOnly | QIODevice::Text)) - { - // 清空文件中的原有内容 - file.resize(0); - - //< Configure - QJsonObject object; - QJsonObject configObject; - configObject.insert("backgroundColor", QColor(m_pItemProxy->backgroundColor).name().toUpper()); - configObject.insert("indicatorWidth", (int)m_pItemProxy->indicatorWidth); - configObject.insert("iconMargin", (int)m_pItemProxy->iconMargin); - configObject.insert("rowHeight", (int)m_pItemDelegate->m_rowHeight); - - configObject.insert("levelTopItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[TOP_LEVEL])).name().toUpper()); - configObject.insert("levelTopItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[TOP_LEVEL])).name().toUpper()); - configObject.insert("levelTopItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); - configObject.insert("levelTopItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); - configObject.insert("levelTopItemIndentation", (int)std::get<4>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); - - configObject.insert("levelChildItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])).name().toUpper()); - configObject.insert("levelChildItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])).name().toUpper()); - configObject.insert("levelChildItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); - configObject.insert("levelChildItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); - configObject.insert("levelChildItemIndentation",(int)std::get<4>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); - - configObject.insert("levelLeafItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])).name().toUpper()); - configObject.insert("levelLeafItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])).name().toUpper()); - configObject.insert("levelLeafItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); - configObject.insert("levelLeafItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); - configObject.insert("levelLeafItemIndentation", (int)std::get<4>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); - - configObject.insert("itemHoveredBgColor", QColor(m_pItemProxy->itemHoveredColor).name().toUpper()); - configObject.insert("itemSelectedColor", QColor(m_pItemProxy->itemSelectedColor).name().toUpper()); - configObject.insert("itemHoveredTextColor", QColor(m_pItemProxy->itemHoveredTextColor).name().toUpper()); - configObject.insert("itemSelectedTextColor", QColor(m_pItemProxy->itemSelectedTextColor).name().toUpper()); - - //< Items - QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); - QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); - QDir exeDir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); - QJsonArray itemsArray; - for (int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) - { - //< Top_Level_Item - QJsonObject topLevelObject; - QJsonArray topLevelArray; - QTreeWidgetItem * item_top_level = topLevelItem(nIndex); - topLevelObject.insert("name", item_top_level->data(0, Qt::DisplayRole).toString()); - if(item_top_level->data(0, Opt_Role).toInt() == EXTERN_PRO) - { - topLevelObject.insert("data", exeDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString())); - } - else - { - topLevelObject.insert("data", dataDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString())); - } - topLevelObject.insert("icon", iconDir.relativeFilePath(item_top_level->data(0, IconPath_Role).toString())); - topLevelObject.insert("used", item_top_level->data(0, Enable_Role).toInt()); - topLevelObject.insert("web", item_top_level->data(0, Web_Role).toInt()); - topLevelObject.insert("opt", item_top_level->data(0, Opt_Role).toInt()); - topLevelObject.insert("url", item_top_level->data(0, Url_Role).toString()); - for (int nChildIndex(0); nChildIndex < item_top_level->childCount(); ++nChildIndex) - { - //< Child_Level_Item - QJsonObject childLevelObject; - QJsonArray childLevelArray; - QTreeWidgetItem * item_child_level = item_top_level->child(nChildIndex); - childLevelObject.insert("name", item_child_level->data(0, Qt::DisplayRole).toString()); - if(item_child_level->data(0, Opt_Role).toInt() == EXTERN_PRO) - { - childLevelObject.insert("data", exeDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString())); - } - else - { - childLevelObject.insert("data", dataDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString())); - } - childLevelObject.insert("icon", iconDir.relativeFilePath(item_child_level->data(0, IconPath_Role).toString())); - childLevelObject.insert("used", item_child_level->data(0, Enable_Role).toInt()); - childLevelObject.insert("web", item_child_level->data(0, Web_Role).toInt()); - childLevelObject.insert("opt", item_child_level->data(0, Opt_Role).toInt()); - childLevelObject.insert("url", item_child_level->data(0, Url_Role).toString()); - for (int nLeafIndex(0); nLeafIndex < item_child_level->childCount(); ++nLeafIndex) - { - //< Leaf_Level_Item - QJsonObject LeafLevelObject; - QTreeWidgetItem * item_leaf_level = item_child_level->child(nLeafIndex); - LeafLevelObject.insert("name", item_leaf_level->data(0, Qt::DisplayRole).toString()); - if(item_leaf_level->data(0, Opt_Role).toInt() == EXTERN_PRO) - { - LeafLevelObject.insert("data", exeDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString())); - } - else - { - LeafLevelObject.insert("data", dataDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString())); - } - LeafLevelObject.insert("icon", iconDir.relativeFilePath(item_leaf_level->data(0, IconPath_Role).toString())); - LeafLevelObject.insert("used", item_leaf_level->data(0, Enable_Role).toInt()); - LeafLevelObject.insert("web", item_leaf_level->data(0, Web_Role).toInt()); - LeafLevelObject.insert("opt", item_leaf_level->data(0, Opt_Role).toInt()); - LeafLevelObject.insert("url", item_leaf_level->data(0, Url_Role).toString()); - childLevelArray.append(LeafLevelObject); - } - childLevelObject.insert("items", childLevelArray); - topLevelArray.append(childLevelObject); - } - topLevelObject.insert("items", topLevelArray); - itemsArray.append(topLevelObject); - } - - QJsonDocument doc; - object.insert("configure", configObject); - object.insert("items", itemsArray); - doc.setObject(object); - file.write(doc.toJson()); - } -} - -QString CNavigationWidget::hexTo26(int number) -{ - int p = 26; //进制 - int c = 0; //取余后的数字 - QString temp; - - while (true) { - c = number % p; - number = number / p; - if(number != 0) - { - temp.prepend(QString(QChar(0x41 + c))); - } - else - { - temp.prepend(QString(QChar(0x41 + c))); - break; - } - number--; - } - - return temp; -} - -int CNavigationWidget::findValue(const QMap &map, const QString &key) -{ - QMap::const_iterator iter = --map.constEnd(); - for(; iter != --map.constBegin(); iter--) - { - if(iter.key() == key) - { - return iter.value(); - } - } - return -1; -} - -QString CNavigationWidget::getNodeTypeStr(int type) -{ - return m_mapNodeType.value(type, ""); -} - -int CNavigationWidget::getNodeType(const QString &str) -{ - QMap::const_iterator iter = m_mapNodeType.constBegin(); - for(; iter != m_mapNodeType.constEnd(); iter++) - { - if(iter.value() == str) - { - return iter.key(); - } - } - return 1; -} - -QString CNavigationWidget::getEnableStr(int enable) -{ - return m_mapEnable.value(enable, ""); -} - -int CNavigationWidget::getEnable(const QString &str) -{ - QMap::const_iterator iter = m_mapEnable.constBegin(); - for(; iter != m_mapEnable.constEnd(); iter++) - { - if(iter.value() == str) - { - return iter.key(); - } - } - return 1; -} - -QTreeWidgetItem *CNavigationWidget::findItem(const QString &data, QTreeWidgetItem *parent) -{ - if(parent->data(0, Qt::UserRole).toString() == data) - { - return parent; - } - for(int nIndex(0); nIndex < parent->childCount(); ++nIndex) - { - QTreeWidgetItem * item = parent->child(nIndex); - if(!item) - { - continue; - } - QTreeWidgetItem * find = findItem(data, item); - if(find) - { - return find; - } - } - return NULL; -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CNavigationWidget.h" +#include "CNavigationDelegate.h" +#include "CNavigationConfigDialog.h" +#include "public/pub_utility_api/FileUtil.h" +#include "model_excel/xlsx/xlsxdocument.h" + +const int Level_Role = Qt::UserRole + 1; +const int Corner_Role = Qt::UserRole + 2; +const int IconPath_Role = Qt::UserRole + 3; +const int Item_Role = Qt::UserRole + 4; +const int Enable_Role = Qt::UserRole + 5; +const int Web_Role = Qt::UserRole + 6; +const int Opt_Role = Qt::UserRole + 7; +const int Url_Role = Qt::UserRole + 8; + +CNavigationWidget::CNavigationWidget(QWidget *parent, bool editMode) + : QTreeWidget(parent), + m_pItemProxy(Q_NULLPTR), + m_pItemDelegate(Q_NULLPTR), + m_navigationMode(EXPLORER_MODE) +{ + if(editMode) + { + m_navigationMode = EDIT_MODE; + } + initialize(); +} + +CNavigationWidget::~CNavigationWidget() +{ + if(m_pItemProxy) + { + delete m_pItemProxy; + } + m_pItemProxy = Q_NULLPTR; +} + +void CNavigationWidget::initialize() +{ + setStyleSheet("background-color:transparent;QLineEdit:edit-focus{background-color:white}"); + setMouseTracking(true); + setRootIsDecorated(false); + header()->setVisible(false); + connect(this, &CNavigationWidget::currentItemChanged, this, &CNavigationWidget::itemSelectedChanged); + connect(this, &CNavigationWidget::itemClicked, this, &CNavigationWidget::itemSelected); + + std::string currentPath = kbd_public::CFileUtil::getCurModuleDir(); + m_strFileHomePath = QString::fromStdString(currentPath) + QString("..%1..%1data%1").arg(QDir::separator()); + m_mapEnable.insert(Enable, tr("是")); + m_mapEnable.insert(Disable, tr("否")); + m_mapNodeType.insert(SWITCH_GRAPH, tr("切换画面")); + m_mapNodeType.insert(EXTERN_PRO, tr("调用程序")); + + initStyleProxy(); + loadItemDelegate(); + + QString strItemConfigFile = m_strFileHomePath + QString("model%1NavigationWidget.json").arg(QDir::separator()); + read(strItemConfigFile); + if(EDIT_MODE != m_navigationMode) + { + expandAll(); + } +} + +void CNavigationWidget::setNavigationMode(const CNavigationWidget::Navigation_Mode &navigationMode) +{ + m_navigationMode = navigationMode; + if(CONFIG_MODE == m_navigationMode) + { + connect(this, &CNavigationWidget::itemDoubleClicked, this, &CNavigationWidget::editItem); + setEditTriggers(DoubleClicked); + } +} + +void CNavigationWidget::config() +{ + return; //< 1.4.1 统一到菜单配置 + CNavigationConfigDialog cfg; + cfg.updateItems(this); + int res = cfg.exec(); + if(QDialog::Accepted == res) + { + clear(); + const CNavigationWidget * pNavigation = cfg.NavigationWidegt(); + updateItems(pNavigation); + updateStyleProxy(pNavigation->m_pItemProxy); + QString strItemConfigFile = m_strFileHomePath + QString("model%1NavigationWidget.json").arg(QDir::separator()); + write(strItemConfigFile); + } +} + +void CNavigationWidget::setTopLevelIndexes(const QString &strIndexes) +{ + QList indexVisibleList; + QStringList listIndex = strIndexes.split(","); + foreach (QString strIndex, listIndex) + { + indexVisibleList.append(strIndex.toInt()); + } + + bool isFirstItem = true; + for(int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) + { + if(nIndex < indexVisibleList.size()) + { + bool isHidden = (0 == indexVisibleList.at(nIndex)); + topLevelItem(nIndex)->setHidden(isHidden); + QTreeWidgetItem *item = topLevelItem(nIndex); + while(!isHidden && isFirstItem && item) + { + if(item->data(0,Qt::UserRole).toString() != QString()) + { + isFirstItem = false; + setCurrentIndex(indexFromItem(item)); + emit itemClicked(item,0); + break; + } + item = item->child(0); + } + } + else + { + topLevelItem(nIndex)->setHidden(true); + } + } +} + +void CNavigationWidget::setItemSelected(const QString &data) +{ + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QString dataPath = dataDir.absoluteFilePath(data); + for(int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) + { + if(topLevelItem(nIndex)->isHidden()) + { + continue; + } + QTreeWidgetItem * item = findItem(dataPath, topLevelItem(nIndex)); + if(item) + { + this->clearSelection(); + item->setSelected(true); + break; + } + } +} + +void CNavigationWidget::paintEvent(QPaintEvent *event) +{ + QPainter painter(viewport()); + painter.fillRect(viewport()->rect(), m_pItemProxy->backgroundColor); + QTreeView::paintEvent(event); +} + +void CNavigationWidget::initStyleProxy() +{ + m_pItemProxy = new ITEM_STYLE_PROXY(); + m_pItemProxy->indicatorWidth = 3; + m_pItemProxy->iconMargin = 5; + + m_pItemProxy->backgroundColor = 0x000C17; + m_pItemProxy->itemHoveredColor = 0x002C53; + m_pItemProxy->itemSelectedColor = 0x022C53; + + m_pItemProxy->itemTextColor = 0xBFC8D5; + m_pItemProxy->itemHoveredTextColor = 0xFFFFFF; + m_pItemProxy->itemSelectedTextColor = 0x1890FF; + + NodeInfo topNodeInfo(0x002140, 0xBFC8D5, 15, 21, 0); + NodeInfo childNodeInfo(0x000C17, 0xBFC8D5, 14, 16, 0); + NodeInfo leafNodeInfo(0x000C17, 0xBFC8D5, 12, 14, 0); + m_pItemProxy->vecItemStyle.push_back(std::move(topNodeInfo)); + m_pItemProxy->vecItemStyle.push_back(std::move(childNodeInfo)); + m_pItemProxy->vecItemStyle.push_back(std::move(leafNodeInfo)); +} + +void CNavigationWidget::getNodeTypeMap(QMap &map) +{ + map = m_mapNodeType; +} + +void CNavigationWidget::addTopLevelItem(const int &number, const QString &caption, const QString &data, const QString &icon, + const int &enable, const int &web, const int &type, const QString &url) +{ + if(caption.isEmpty()) + { + return; + } + QTreeWidgetItem * topLevelItem = new QTreeWidgetItem(QStringList() << caption); + topLevelItem->setData(0, Level_Role, TOP_LEVEL); + topLevelItem->setData(0, Corner_Role, false); + topLevelItem->setData(0, IconPath_Role, icon); + topLevelItem->setData(0, Item_Role, number); + topLevelItem->setData(0, Enable_Role, enable); + topLevelItem->setData(0, Web_Role, web); + topLevelItem->setData(0, Opt_Role, type); + topLevelItem->setData(0, Url_Role, url); + + if(!data.isEmpty()) + { + topLevelItem->setData(0, Qt::UserRole, data); + } + + if(!icon.isEmpty()) + { + topLevelItem->setIcon(0, QIcon(icon)); + } + + QTreeWidget::addTopLevelItem(topLevelItem); + if(CONFIG_MODE == m_navigationMode) + { + topLevelItem->setFlags(topLevelItem->flags() | Qt::ItemIsEditable); + topLevelItem->setExpanded(true); + setCurrentItem(topLevelItem); + } +} + +void CNavigationWidget::addChildItem(const int &number, const QList &parents, const QString &caption, const QString &data, const QString &icon, + const int &enable, const int &web, const int &type, const QString &url) +{ + if(parents.isEmpty() || caption.isEmpty()) + { + return; + } + + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->data(0, Item_Role).toInt() == parents.first()) + { + QTreeWidgetItem * parent = topLevelItem(nIndex); + //< 查找二级节点 + if(1 < parents.size()) + { + //< 查找失败则添加到二级节点 + for(int nChildIndex(0); nChildIndex < parent->childCount(); nChildIndex++) + { + if(parent->child(nChildIndex)->data(0, Item_Role).toInt() == parents.at(1)) + { + parent = parent->child(nChildIndex); + break; + } + } + } + QTreeWidgetItem * item = new QTreeWidgetItem(parent, QStringList() << caption); + item->setData(0, Level_Role, parent->data(0, Level_Role).toInt() + 1); + item->setData(0, Corner_Role, false); + item->setData(0, IconPath_Role, icon); + item->setData(0, Item_Role, number); + item->setData(0, Enable_Role, enable); + item->setData(0, Web_Role, web); + item->setData(0, Opt_Role, type); + item->setData(0, Url_Role, url); + if(!data.isEmpty()) + { + item->setData(0, Qt::UserRole, data); + } + + if(!icon.isEmpty()) + { + item->setIcon(0, QIcon(icon)); + } + + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->parent()->setExpanded(true); + item->parent()->setSelected(true); + } + } + } +} + +void CNavigationWidget::addLevelItem(const int &number, const QList &parents, const QString &caption, const QString &data, const QString &icon, + const int &enable, const int &web, const int &type, const QString &url) +{ + if(parents.isEmpty() || caption.isEmpty()) + { + return; + } + + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->data(0, Item_Role).toInt() == parents.at(0)) + { + QTreeWidgetItem * item = new QTreeWidgetItem(QStringList() << caption); + item->setData(0, Corner_Role, false); + item->setData(0, IconPath_Role, icon); + item->setData(0, Item_Role, number); + item->setData(0, Enable_Role, enable); + item->setData(0, Web_Role, web); + item->setData(0, Opt_Role, type); + item->setData(0, Url_Role, url); + if(!data.isEmpty()) + { + item->setData(0, Qt::UserRole, data); + } + if(!icon.isEmpty()) + { + item->setIcon(0, QIcon(icon)); + } + + QTreeWidgetItem * top = topLevelItem(nIndex); + //< 查找二级节点 + if(1 < parents.size()) + { + for(int nChildIndex(0); nChildIndex < top->childCount(); nChildIndex++) + { + if(top->child(nChildIndex)->data(0, Item_Role).toInt() == parents.at(1)) + { + QTreeWidgetItem * child = top->child(nChildIndex); + //< 查找三级节点 + if(2 < parents.size()) + { + for(int nLeafIndex(0); nLeafIndex < child->childCount(); nLeafIndex++) + { + if(child->child(nLeafIndex)->data(0, Item_Role).toInt() == parents.at(2)) + { + item->setData(0, Level_Role, child->data(0, Level_Role).toInt() + 1); + child->insertChild(nLeafIndex, item); + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->setSelected(true); + setCurrentItem(item); + } + return; + } + } + } + item->setData(0, Level_Role, top->data(0, Level_Role).toInt() + 1); + top->insertChild(nChildIndex, item); + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->setSelected(true); + setCurrentItem(item); + } + return; + } + } + } + item->setData(0, Level_Role, TOP_LEVEL); + QTreeWidget::insertTopLevelItem(nIndex, item); + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->setSelected(true); + setCurrentItem(item); + } + return; + } + } +} + +void CNavigationWidget::removeItem(QTreeWidgetItem *item) +{ + if(item->parent()) + { + item->parent()->removeChild(item); + } + else + { + takeTopLevelItem(indexFromItem(item).row()); + } +} + +int CNavigationWidget::slotImport() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("导入"), "", "*.xlsx"); + if(filePath.isEmpty()) + return -1; + + clear(); + QXlsx::Document xlsx(filePath); + QXlsx::CellRange cellRange = xlsx.currentWorksheet()->dimension(); + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QDir exeDir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); + QMultiMap numberMap; + int nItemNumber = 0; + for(int row=cellRange.firstRow()+1; row<=cellRange.lastRow(); row++) + { + QString firName = xlsx.read(row, 1).toString().trimmed(); + if(firName.isEmpty()) + { + continue; + } + QString name; + QString secName = xlsx.read(row, 2).toString().trimmed(); + QString trdName = xlsx.read(row, 3).toString().trimmed(); + int used = getEnable(xlsx.read(row, 4).toString()); + int opt = getNodeType(xlsx.read(row, 5).toString()); + QString icon = xlsx.read(row, 6).toString(); + QString data = xlsx.read(row, 7).toString(); + int web = getEnable(xlsx.read(row, 8).toString()); + if(!data.isEmpty()) + { + if(opt == EXTERN_PRO) + { + data = exeDir.absoluteFilePath(data); + } + else + { + data = dataDir.absoluteFilePath(data); + } + } + if(!icon.isEmpty()) + { + icon = iconDir.absoluteFilePath(icon); + } + if(secName.isEmpty()) + { + name = firName; + addTopLevelItem(nItemNumber, firName, data, icon, used, web, opt); + } + else if(!secName.isEmpty() && trdName.isEmpty()) + { + QList list; + list.append(findValue(numberMap, firName)); + name = secName; + addChildItem(nItemNumber, list, secName, data, icon, used, web, opt); + } + else + { + QList list; + list.append(findValue(numberMap, firName)); + list.append(findValue(numberMap, secName)); + name = trdName; + addChildItem(nItemNumber, list, trdName, data, icon, used, web, opt); + } + + numberMap.insert(name, nItemNumber++); + } + return nItemNumber; +} + +void CNavigationWidget::slotExport() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("导出"), "nav.xlsx", "*.xlsx"); + if(filePath.isEmpty()) + return; + + QXlsx::Document xlsx; + + xlsx.write(hexTo26(0)+"1", tr("一级")); + xlsx.write(hexTo26(1)+"1", tr("二级")); + xlsx.write(hexTo26(2)+"1", tr("三级")); + xlsx.write(hexTo26(3)+"1", tr("是否使用")); + xlsx.write(hexTo26(4)+"1", tr("操作")); + xlsx.write(hexTo26(5)+"1", tr("图标")); + xlsx.write(hexTo26(6)+"1", tr("数据")); + xlsx.write(hexTo26(7)+"1", tr("web发布")); + xlsx.setColumnWidth(1, 8, 30); + + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QDir exeDir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); + int row = 2; + for (int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) + { + //< Top_Level_Item + QTreeWidgetItem * item_top_level = topLevelItem(nIndex); + QString tName = item_top_level->data(0, Qt::DisplayRole).toString(); + QString tData = dataDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString()); + if(item_top_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + tData = exeDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString()); + } + QString tIcon = iconDir.relativeFilePath(item_top_level->data(0, IconPath_Role).toString()); + QString tUsed = getEnableStr(item_top_level->data(0, Enable_Role).toInt()); + QString tOpt = getNodeTypeStr(item_top_level->data(0, Opt_Role).toInt()); + QString tWeb = getEnableStr(item_top_level->data(0, Web_Role).toInt()); + xlsx.write(hexTo26(0)+QString::number(row), tName); + xlsx.write(hexTo26(3)+QString::number(row), tUsed); + xlsx.write(hexTo26(4)+QString::number(row), tOpt); + xlsx.write(hexTo26(5)+QString::number(row), tIcon); + xlsx.write(hexTo26(6)+QString::number(row), tData); + xlsx.write(hexTo26(7)+QString::number(row++), tWeb); + for (int nChildIndex(0); nChildIndex < item_top_level->childCount(); ++nChildIndex) + { + //< Child_Level_Item + QTreeWidgetItem * item_child_level = item_top_level->child(nChildIndex); + QString cName = item_child_level->data(0, Qt::DisplayRole).toString(); + QString cData = dataDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString()); + if(item_child_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + cData = exeDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString()); + } + QString cIcon = iconDir.relativeFilePath(item_child_level->data(0, IconPath_Role).toString()); + QString cUsed = getEnableStr(item_child_level->data(0, Enable_Role).toInt()); + QString cOpt = getNodeTypeStr(item_child_level->data(0, Opt_Role).toInt()); + QString cWeb = getEnableStr(item_child_level->data(0, Web_Role).toInt()); + xlsx.write(hexTo26(0)+QString::number(row), tName); + xlsx.write(hexTo26(1)+QString::number(row), cName); + xlsx.write(hexTo26(3)+QString::number(row), cUsed); + xlsx.write(hexTo26(4)+QString::number(row), cOpt); + xlsx.write(hexTo26(5)+QString::number(row), cIcon); + xlsx.write(hexTo26(6)+QString::number(row), cData); + xlsx.write(hexTo26(7)+QString::number(row++), cWeb); + for (int nLeafIndex(0); nLeafIndex < item_child_level->childCount(); ++nLeafIndex) + { + //< Leaf_Level_Item + QTreeWidgetItem * item_leaf_level = item_child_level->child(nLeafIndex); + QString lName = item_leaf_level->data(0, Qt::DisplayRole).toString(); + QString lData = dataDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString()); + if(item_leaf_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + lData = exeDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString()); + } + QString lIcon = iconDir.relativeFilePath(item_leaf_level->data(0, IconPath_Role).toString()); + QString lUsed = getEnableStr(item_leaf_level->data(0, Enable_Role).toInt()); + QString lOpt = getNodeTypeStr(item_leaf_level->data(0, Opt_Role).toInt()); + QString lWeb = getEnableStr(item_leaf_level->data(0, Web_Role).toInt()); + xlsx.write(hexTo26(0)+QString::number(row), tName); + xlsx.write(hexTo26(1)+QString::number(row), cName); + xlsx.write(hexTo26(2)+QString::number(row), lName); + xlsx.write(hexTo26(3)+QString::number(row), lUsed); + xlsx.write(hexTo26(4)+QString::number(row), lOpt); + xlsx.write(hexTo26(5)+QString::number(row), lIcon); + xlsx.write(hexTo26(6)+QString::number(row), lData); + xlsx.write(hexTo26(7)+QString::number(row++), lWeb); + } + } + } + + if(xlsx.saveAs(filePath)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } +} + +void CNavigationWidget::clearItems() +{ + clear(); +} + +void CNavigationWidget::loadItemDelegate() +{ + m_pItemDelegate = new CNavigationDelegate(m_pItemProxy, this); + m_pItemDelegate->setView(this); + setItemDelegate(m_pItemDelegate); +} + +void CNavigationWidget::updateItems(const CNavigationWidget *pNavigation) +{ + if(Q_NULLPTR == pNavigation) + { + return; + } + + for(int nIndex(0); nIndex < pNavigation->topLevelItemCount(); nIndex++) + { + QTreeWidgetItem * item = pNavigation->topLevelItem(nIndex); + QTreeWidgetItem * newItem = buildNewItem(item); + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + QTreeWidgetItem * childItem = item->child(nChildIndex); + QTreeWidgetItem * newChildItem = buildNewItem(childItem); + for(int nLeafIndex(0); nLeafIndex < childItem->childCount(); nLeafIndex++) + { + newChildItem->addChild(buildNewItem(childItem->child(nLeafIndex))); + } + newItem->addChild(newChildItem); + } + QTreeWidget::addTopLevelItem(newItem); + } +} + +QTreeWidgetItem *CNavigationWidget::buildNewItem(const QTreeWidgetItem *parent) +{ + QTreeWidgetItem * item = new QTreeWidgetItem(*parent); + item->setData(0, Corner_Role, false); + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable); + } + else + { + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + } + return item; +} + +void CNavigationWidget::updateStyleProxy(const ITEM_STYLE_PROXY *proxy) +{ + if(Q_NULLPTR == proxy) + { + return; + } + m_pItemProxy->backgroundColor = proxy->backgroundColor; + m_pItemProxy->itemHoveredColor = proxy->itemHoveredColor; + m_pItemProxy->itemSelectedColor = proxy->itemSelectedColor; + m_pItemProxy->itemTextColor = proxy->itemTextColor; + m_pItemProxy->itemHoveredTextColor = proxy->itemHoveredTextColor; + m_pItemProxy->itemSelectedTextColor = proxy->itemSelectedTextColor; + m_pItemProxy->vecItemStyle = proxy->vecItemStyle; +} + +void CNavigationWidget::contextMenuEvent(QContextMenuEvent *e) +{ + if(EDIT_MODE == m_navigationMode) + { + QMenu menu; + QAction * pActionCfg = new QAction(tr("属性配置")); + connect(pActionCfg, &QAction::triggered, this, &CNavigationWidget::config); + menu.addAction(pActionCfg); + menu.exec(e->globalPos()); + } + else if(EXPLORER_MODE == m_navigationMode) + { + QMenu menu; + QAction * pActionExp = new QAction(tr("全部展开")); + QAction * pActionCol = new QAction(tr("全部收缩")); + connect(pActionExp, &QAction::triggered, this, [=](){expandAll();}); + connect(pActionCol, &QAction::triggered, this, [=](){collapseAll();}); + menu.addAction(pActionExp); + menu.addAction(pActionCol); + menu.exec(e->globalPos()); + } +} + +void CNavigationWidget::itemSelectedChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + setFocus(); + update(); + if(previous) + { + if(TOP_LEVEL == previous->data(0, Level_Role)) + { + previous->setData(0, Corner_Role, false); + } + else if(CHILD_LEVEL == previous->data(0, Level_Role)) + { + previous->parent()->setData(0, Corner_Role, false); + } + else if(LEAF_LEVEL == previous->data(0, Level_Role)) + { + previous->parent()->parent()->setData(0, Corner_Role, false); + } + } + + if(current) + { + if(TOP_LEVEL == current->data(0, Level_Role)) + { + current->setData(0, Corner_Role, true); + } + else if(CHILD_LEVEL == current->data(0, Level_Role)) + { + current->parent()->setData(0, Corner_Role, true); + } + else if(LEAF_LEVEL == current->data(0, Level_Role)) + { + current->parent()->parent()->setData(0, Corner_Role, true); + } + +// QFileInfo info(current->data(0, Qt::UserRole).toString()); +// emit graphItemClicked(current->data(0, Qt::DisplayRole).toString(), info.fileName()); + } +} + +void CNavigationWidget::itemSelected(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column) + if(item) + { + if(TOP_LEVEL == item->data(0, Level_Role)) + { + item->setData(0, Corner_Role, true); + } + else if(CHILD_LEVEL == item->data(0, Level_Role)) + { + item->parent()->setData(0, Corner_Role, true); + } + else if(LEAF_LEVEL == item->data(0, Level_Role)) + { + item->parent()->parent()->setData(0, Corner_Role, true); + } + + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QString fileName = dataDir.relativeFilePath(item->data(0, Qt::UserRole).toString()); + emit graphItemClicked(item->data(0, Qt::DisplayRole).toString(), fileName, + item->data(0, Opt_Role).toInt(), item->data(0, Url_Role).toString()); + } +} + +void CNavigationWidget::setIconSize(const int &width, const int &height) +{ + QTreeWidget::setIconSize(QSize(width, height)); +} + +void CNavigationWidget::setBranchIconSize(const int &width, const int &height) +{ + if(m_pItemDelegate) + { + m_pItemDelegate->setBranchIconSize(QSize(width, height)); + } +} + +void CNavigationWidget::setRowHeight(const int &rowHeight) +{ + if(m_pItemDelegate) + { + m_pItemDelegate->m_rowHeight = rowHeight; + } + resize(size()); +} + +void CNavigationWidget::setIndentation(const int &indentation) +{ + QTreeWidget::setIndentation(indentation); +} + +void CNavigationWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + QTreeWidget::drawRow(painter, options, index); + + if(index.data(Corner_Role).toBool()) + { + QRect rt = visualRect(index); + painter->setPen(Qt::transparent); + painter->setBrush(QColor(m_pItemProxy->itemSelectedTextColor)); + painter->drawRect(QRectF(rt.x(), rt.y() + 0.5, m_pItemProxy->indicatorWidth, rt.height() - 0.5)); + } +} + +void CNavigationWidget::setTreeBackgroundColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->backgroundColor = color; + } +} + +void CNavigationWidget::setItemHoverBackgroundColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemHoveredColor = color; + } +} + +void CNavigationWidget::setItemSelectedBackgroundColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemSelectedColor = color; + } +} + +void CNavigationWidget::setTextColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemTextColor = color; + } +} + +void CNavigationWidget::setTextHoverColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemHoveredTextColor = color; + } +} + +void CNavigationWidget::setTextSelectedColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemSelectedTextColor = color; + } +} + +void CNavigationWidget::setItemBackgroundColor(const rgb &color, const Node_Level &level) +{ + if(m_pItemProxy) + { + std::get<0>(m_pItemProxy->vecItemStyle[level]) = color; + } +} + +void CNavigationWidget::setItemTextSize(const int &size, const Node_Level &level) +{ + if(m_pItemProxy) + { + std::get<2>(m_pItemProxy->vecItemStyle[level]) = size; + } +} + +void CNavigationWidget::read(const QString &strFileName) +{ + QFile loadFile(strFileName); + if(!loadFile.open(QIODevice::ReadOnly)) + { + qDebug() << "could't open file 'NavigationWidget.json'!"; + return; + } + + QByteArray data = loadFile.readAll(); + loadFile.close(); + + QJsonParseError json_error; + QJsonDocument jsonDoc(QJsonDocument::fromJson(data, &json_error)); + + if(json_error.error != QJsonParseError::NoError) + { + qDebug() << "'NavigationWidget.json' parse Error!"; + return; + } + + QJsonObject root = jsonDoc.object(); + if(root.contains("configure")) + { + QJsonObject configObject = root.value("configure").toObject(); + m_pItemProxy->backgroundColor = QColor(configObject["backgroundColor"].toString()).rgb(); + m_pItemProxy->indicatorWidth = configObject["indicatorWidth"].toInt(); + m_pItemProxy->iconMargin = configObject["iconMargin"].toInt(); + m_pItemDelegate->m_rowHeight = configObject["rowHeight"].toInt(); + + std::get<0>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemBgColor"].toString()).rgb(); + std::get<1>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemTextColor"].toString()).rgb(); + std::get<2>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemTextSize"].toInt(); + std::get<3>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemIconSize"].toInt(); + std::get<4>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemIndentation"].toInt(); + + std::get<0>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemBgColor"].toString()).rgb(); + std::get<1>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemTextColor"].toString()).rgb(); + std::get<2>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemTextSize"].toInt(); + std::get<3>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemIconSize"].toInt(); + std::get<4>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemIndentation"].toInt(); + + std::get<0>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemBgColor"].toString()).rgb(); + std::get<1>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemTextColor"].toString()).rgb(); + std::get<2>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemTextSize"].toInt(); + std::get<3>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemIconSize"].toInt(); + std::get<4>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemIndentation"].toInt(); + + m_pItemProxy->itemHoveredColor = QColor(configObject["itemHoveredBgColor"].toString()).rgb(); + m_pItemProxy->itemSelectedColor = QColor(configObject["itemSelectedColor"].toString()).rgb(); + m_pItemProxy->itemHoveredTextColor = QColor(configObject["itemHoveredTextColor"].toString()).rgb(); + m_pItemProxy->itemSelectedTextColor = QColor(configObject["itemSelectedTextColor"].toString()).rgb(); + } + + if(root.contains("items")) + { + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QDir exeDir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); + QJsonArray itemArray = root.value("items").toArray(); + int nItemNumber = 0; + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + QTreeWidgetItem * item_top_level = new QTreeWidgetItem(this); + item_top_level->setData(0, Qt::DisplayRole, topLevelObject.value("name").toString()); + item_top_level->setData(0, Level_Role, TOP_LEVEL); + item_top_level->setData(0, Item_Role, nItemNumber++); + item_top_level->setData(0, Enable_Role, topLevelObject.value("used").toInt(Enable)); + item_top_level->setData(0, Web_Role, topLevelObject.value("web").toInt(Enable)); + item_top_level->setData(0, Opt_Role, topLevelObject.value("opt").toInt(SWITCH_GRAPH)); + item_top_level->setData(0, Url_Role, topLevelObject.value("url").toString()); + if(!topLevelObject.value("data").toString().isEmpty()) + { + if(topLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) + { + item_top_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(topLevelObject.value("data").toString())); + } + else + { + item_top_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(topLevelObject.value("data").toString())); + } + } + QString topLevelIconName = topLevelObject.value("icon").toString(); + if(!topLevelIconName.isEmpty()) + { + item_top_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(topLevelIconName)); + item_top_level->setIcon(0, QIcon(iconDir.absoluteFilePath(topLevelIconName))); + } + + QJsonArray childArray = topLevelObject.value("items").toArray(); + for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) + { + QJsonObject childLevelObject = childArray[nChildIndex].toObject(); + QTreeWidgetItem * item_child_level = new QTreeWidgetItem(item_top_level); + item_child_level->setData(0, Qt::DisplayRole, childLevelObject.value("name").toString()); + item_child_level->setData(0, Level_Role, CHILD_LEVEL); + item_child_level->setData(0, Item_Role, nItemNumber++); + item_child_level->setData(0, Enable_Role, childLevelObject.value("used").toInt(Enable)); + item_child_level->setData(0, Web_Role, childLevelObject.value("web").toInt(Enable)); + item_child_level->setData(0, Opt_Role, childLevelObject.value("opt").toInt(SWITCH_GRAPH)); + item_child_level->setData(0, Url_Role, childLevelObject.value("url").toString()); + if(!childLevelObject.value("data").toString().isEmpty()) + { + if(childLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) + { + item_child_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(childLevelObject.value("data").toString())); + } + else + { + item_child_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(childLevelObject.value("data").toString())); + } + } + QString childLevelIconName = childLevelObject.value("icon").toString(); + if(!childLevelIconName.isEmpty()) + { + item_child_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(childLevelIconName)); + item_child_level->setIcon(0, QIcon(iconDir.absoluteFilePath(childLevelIconName))); + } + + QJsonArray leafArray = childLevelObject.value("items").toArray(); + for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) + { + QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); + QTreeWidgetItem * item_leaf_level = new QTreeWidgetItem(item_child_level); + item_leaf_level->setData(0, Qt::DisplayRole, leafLevelObject.value("name").toString()); + item_leaf_level->setData(0, Level_Role, LEAF_LEVEL); + item_leaf_level->setData(0, Item_Role, nItemNumber++); + item_leaf_level->setData(0, Enable_Role, leafLevelObject.value("used").toInt(Enable)); + item_leaf_level->setData(0, Web_Role, leafLevelObject.value("web").toInt(Enable)); + item_leaf_level->setData(0, Opt_Role, leafLevelObject.value("opt").toInt(SWITCH_GRAPH)); + item_leaf_level->setData(0, Url_Role, leafLevelObject.value("url").toString()); + if(!leafLevelObject.value("data").toString().isEmpty()) + { + if(leafLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) + { + item_leaf_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(leafLevelObject.value("data").toString())); + } + else + { + item_leaf_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(leafLevelObject.value("data").toString())); + } + } + QString leafLevelIconName = leafLevelObject.value("icon").toString(); + if(!leafLevelIconName.isEmpty()) + { + item_leaf_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(leafLevelIconName)); + item_leaf_level->setIcon(0, QIcon(iconDir.absoluteFilePath(leafLevelIconName))); + } + item_child_level->addChild(item_leaf_level); + if(EXPLORER_MODE == m_navigationMode) + { + item_leaf_level->setHidden(item_leaf_level->data(0, Enable_Role).toInt()==Enable?false:true); + } + } + item_top_level->addChild(item_child_level); + if(EXPLORER_MODE == m_navigationMode) + { + item_child_level->setHidden(item_child_level->data(0, Enable_Role).toInt()==Enable?false:true); + } + } + QTreeWidget::addTopLevelItem(item_top_level); + if(EXPLORER_MODE == m_navigationMode) + { + item_top_level->setHidden(item_top_level->data(0, Enable_Role).toInt()==Enable?false:true); + } + } + } +} + +void CNavigationWidget::write(const QString &strFileName) +{ + QFile file(strFileName); + //< 不存在则创建 + if(!file.exists()) + { + file.setFileName(strFileName); + } + + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + // 清空文件中的原有内容 + file.resize(0); + + //< Configure + QJsonObject object; + QJsonObject configObject; + configObject.insert("backgroundColor", QColor(m_pItemProxy->backgroundColor).name().toUpper()); + configObject.insert("indicatorWidth", (int)m_pItemProxy->indicatorWidth); + configObject.insert("iconMargin", (int)m_pItemProxy->iconMargin); + configObject.insert("rowHeight", (int)m_pItemDelegate->m_rowHeight); + + configObject.insert("levelTopItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[TOP_LEVEL])).name().toUpper()); + configObject.insert("levelTopItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[TOP_LEVEL])).name().toUpper()); + configObject.insert("levelTopItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); + configObject.insert("levelTopItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); + configObject.insert("levelTopItemIndentation", (int)std::get<4>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); + + configObject.insert("levelChildItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])).name().toUpper()); + configObject.insert("levelChildItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])).name().toUpper()); + configObject.insert("levelChildItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); + configObject.insert("levelChildItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); + configObject.insert("levelChildItemIndentation",(int)std::get<4>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); + + configObject.insert("levelLeafItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])).name().toUpper()); + configObject.insert("levelLeafItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])).name().toUpper()); + configObject.insert("levelLeafItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); + configObject.insert("levelLeafItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); + configObject.insert("levelLeafItemIndentation", (int)std::get<4>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); + + configObject.insert("itemHoveredBgColor", QColor(m_pItemProxy->itemHoveredColor).name().toUpper()); + configObject.insert("itemSelectedColor", QColor(m_pItemProxy->itemSelectedColor).name().toUpper()); + configObject.insert("itemHoveredTextColor", QColor(m_pItemProxy->itemHoveredTextColor).name().toUpper()); + configObject.insert("itemSelectedTextColor", QColor(m_pItemProxy->itemSelectedTextColor).name().toUpper()); + + //< Items + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QDir exeDir(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir())); + QJsonArray itemsArray; + for (int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) + { + //< Top_Level_Item + QJsonObject topLevelObject; + QJsonArray topLevelArray; + QTreeWidgetItem * item_top_level = topLevelItem(nIndex); + topLevelObject.insert("name", item_top_level->data(0, Qt::DisplayRole).toString()); + if(item_top_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + topLevelObject.insert("data", exeDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString())); + } + else + { + topLevelObject.insert("data", dataDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString())); + } + topLevelObject.insert("icon", iconDir.relativeFilePath(item_top_level->data(0, IconPath_Role).toString())); + topLevelObject.insert("used", item_top_level->data(0, Enable_Role).toInt()); + topLevelObject.insert("web", item_top_level->data(0, Web_Role).toInt()); + topLevelObject.insert("opt", item_top_level->data(0, Opt_Role).toInt()); + topLevelObject.insert("url", item_top_level->data(0, Url_Role).toString()); + for (int nChildIndex(0); nChildIndex < item_top_level->childCount(); ++nChildIndex) + { + //< Child_Level_Item + QJsonObject childLevelObject; + QJsonArray childLevelArray; + QTreeWidgetItem * item_child_level = item_top_level->child(nChildIndex); + childLevelObject.insert("name", item_child_level->data(0, Qt::DisplayRole).toString()); + if(item_child_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + childLevelObject.insert("data", exeDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString())); + } + else + { + childLevelObject.insert("data", dataDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString())); + } + childLevelObject.insert("icon", iconDir.relativeFilePath(item_child_level->data(0, IconPath_Role).toString())); + childLevelObject.insert("used", item_child_level->data(0, Enable_Role).toInt()); + childLevelObject.insert("web", item_child_level->data(0, Web_Role).toInt()); + childLevelObject.insert("opt", item_child_level->data(0, Opt_Role).toInt()); + childLevelObject.insert("url", item_child_level->data(0, Url_Role).toString()); + for (int nLeafIndex(0); nLeafIndex < item_child_level->childCount(); ++nLeafIndex) + { + //< Leaf_Level_Item + QJsonObject LeafLevelObject; + QTreeWidgetItem * item_leaf_level = item_child_level->child(nLeafIndex); + LeafLevelObject.insert("name", item_leaf_level->data(0, Qt::DisplayRole).toString()); + if(item_leaf_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + LeafLevelObject.insert("data", exeDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString())); + } + else + { + LeafLevelObject.insert("data", dataDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString())); + } + LeafLevelObject.insert("icon", iconDir.relativeFilePath(item_leaf_level->data(0, IconPath_Role).toString())); + LeafLevelObject.insert("used", item_leaf_level->data(0, Enable_Role).toInt()); + LeafLevelObject.insert("web", item_leaf_level->data(0, Web_Role).toInt()); + LeafLevelObject.insert("opt", item_leaf_level->data(0, Opt_Role).toInt()); + LeafLevelObject.insert("url", item_leaf_level->data(0, Url_Role).toString()); + childLevelArray.append(LeafLevelObject); + } + childLevelObject.insert("items", childLevelArray); + topLevelArray.append(childLevelObject); + } + topLevelObject.insert("items", topLevelArray); + itemsArray.append(topLevelObject); + } + + QJsonDocument doc; + object.insert("configure", configObject); + object.insert("items", itemsArray); + doc.setObject(object); + file.write(doc.toJson()); + } +} + +QString CNavigationWidget::hexTo26(int number) +{ + int p = 26; //进制 + int c = 0; //取余后的数字 + QString temp; + + while (true) { + c = number % p; + number = number / p; + if(number != 0) + { + temp.prepend(QString(QChar(0x41 + c))); + } + else + { + temp.prepend(QString(QChar(0x41 + c))); + break; + } + number--; + } + + return temp; +} + +int CNavigationWidget::findValue(const QMap &map, const QString &key) +{ + QMap::const_iterator iter = --map.constEnd(); + for(; iter != --map.constBegin(); iter--) + { + if(iter.key() == key) + { + return iter.value(); + } + } + return -1; +} + +QString CNavigationWidget::getNodeTypeStr(int type) +{ + return m_mapNodeType.value(type, ""); +} + +int CNavigationWidget::getNodeType(const QString &str) +{ + QMap::const_iterator iter = m_mapNodeType.constBegin(); + for(; iter != m_mapNodeType.constEnd(); iter++) + { + if(iter.value() == str) + { + return iter.key(); + } + } + return 1; +} + +QString CNavigationWidget::getEnableStr(int enable) +{ + return m_mapEnable.value(enable, ""); +} + +int CNavigationWidget::getEnable(const QString &str) +{ + QMap::const_iterator iter = m_mapEnable.constBegin(); + for(; iter != m_mapEnable.constEnd(); iter++) + { + if(iter.value() == str) + { + return iter.key(); + } + } + return 1; +} + +QTreeWidgetItem *CNavigationWidget::findItem(const QString &data, QTreeWidgetItem *parent) +{ + if(parent->data(0, Qt::UserRole).toString() == data) + { + return parent; + } + for(int nIndex(0); nIndex < parent->childCount(); ++nIndex) + { + QTreeWidgetItem * item = parent->child(nIndex); + if(!item) + { + continue; + } + QTreeWidgetItem * find = findItem(data, item); + if(find) + { + return find; + } + } + return NULL; +} diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationWidget.h b/product/src/gui/plugin/NavigationWidget/CNavigationWidget.h index 220fb481..59d22194 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationWidget.h +++ b/product/src/gui/plugin/NavigationWidget/CNavigationWidget.h @@ -1,188 +1,188 @@ -#ifndef CNAVIGATIONWIDGET_H -#define CNAVIGATIONWIDGET_H - -#include -#include "CNavigationConfigDialog.h" -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CNavigationDelegate; - -typedef unsigned int rgb; - -typedef std::tuple NodeInfo; //< 节点背景颜色、节点字体颜色、节点字体大小、图标大小、偏移像素 - -extern const int Level_Role; //< 节点层级 -extern const int Corner_Role; //< 活动根节点 -extern const int IconPath_Role; //< 节点图标路径 -extern const int Item_Role; //< 节点数 -extern const int Enable_Role; //< 是否启用 -extern const int Web_Role; //< 是否web发布 -extern const int Opt_Role; //< 操作类型 -extern const int Url_Role; //< 加载网页url - -struct ITEM_STYLE_PROXY -{ - int indicatorWidth; - int iconMargin; - - //< 填充颜色 - rgb backgroundColor; - rgb itemHoveredColor; - rgb itemSelectedColor; - - //< 文字颜色 - rgb itemTextColor; - rgb itemHoveredTextColor; - rgb itemSelectedTextColor; - - std::vector< NodeInfo > vecItemStyle; -}; - -class CNavigationWidget : public QTreeWidget, public IPluginWidget -{ - Q_OBJECT - friend class CNavigationConfigDialog; -public: - enum Navigation_Mode - { - EXPLORER_MODE = 0, - EDIT_MODE, - CONFIG_MODE, - }; - - enum Node_Level - { - TOP_LEVEL = 0, - CHILD_LEVEL, - LEAF_LEVEL - }; - - enum Node_Type - { - NONE = 0, //< 无操作 - SWITCH_GRAPH, //< 切换画面 - SWITCH_NAV, //< 切换导航 - EXTERN_PRO, //< 调用程序 - }; - - enum Node_Enable - { - Enable = 1, - Disable = 2, - }; - - explicit CNavigationWidget(QWidget *parent = Q_NULLPTR, bool editMode = true); - - ~CNavigationWidget(); - - void setNavigationMode(const Navigation_Mode &navigationMode); - - virtual void config(); - virtual void release(){} - virtual bool read(CGStream &ios) { Q_UNUSED(ios); return false; } - virtual bool write(CGStream &ios) { Q_UNUSED(ios); return false; } - virtual void setProperty(const QString &propertyName, QVariant value) { Q_UNUSED(propertyName); Q_UNUSED(value);} - virtual void getProperty(QList< QPair > &propertyList) { Q_UNUSED(propertyList); } - -/************************************ 脚本接口-[begin] ****************************************/ - -public Q_SLOTS: - void setTopLevelIndexes(const QString &strIndexes); - - void setItemSelected(const QString &data); - - void addTopLevelItem(const int &number, const QString &caption, const QString &data = QString(), const QString &icon = QString(), - const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); - - void addChildItem(const int &number, const QList &parents, const QString &caption, const QString &data = QString(), const QString &icon = QString(), - const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); - - void addLevelItem(const int &number, const QList &parents, const QString &caption, const QString &data = QString(), const QString &icon = QString(), - const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); - - void removeItem(QTreeWidgetItem *item); - - int slotImport(); - - void slotExport(); - - void clearItems(); - - void setIconSize(const int &width, const int &height); - void setBranchIconSize(const int &width, const int &height); - - void setRowHeight(const int &rowHeight); - - void setIndentation(const int &indentation); - - void initStyleProxy(); - - void getNodeTypeMap(QMap &map); - - /******************** 样式设置-[begin] ************************/ - void setTreeBackgroundColor(const rgb &color); - void setItemHoverBackgroundColor(const rgb &color); - void setItemSelectedBackgroundColor(const rgb &color); - - void setTextColor(const rgb &color); - void setTextHoverColor(const rgb &color); - void setTextSelectedColor(const rgb &color); - - void setItemBackgroundColor(const rgb &color, const Node_Level &level); - void setItemTextSize(const int &size, const Node_Level &level); - /******************** 样式设置-[end] *************************/ - -Q_SIGNALS: - void graphItemClicked(const QString &caption, const QString &data, const int &type, const QString &url); - -/************************************* 脚本接口-[end] ********************************************/ - - -private: - void initialize(); - - void loadItemDelegate(); - - void updateItems(const CNavigationWidget * pNavigation); - - QTreeWidgetItem * buildNewItem(const QTreeWidgetItem * parent); - - void updateStyleProxy(const ITEM_STYLE_PROXY * proxy); - - void paintEvent(QPaintEvent *event); - - void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const; - - void contextMenuEvent(QContextMenuEvent *e); - - void read(const QString &strFileName); - - void write(const QString &strFileName); - - QString hexTo26(int number); - - int findValue(const QMap &map, const QString &key); - - QString getNodeTypeStr(int type); - int getNodeType(const QString &str); - - QString getEnableStr(int enable); - int getEnable(const QString &str); - - QTreeWidgetItem * findItem(const QString &data, QTreeWidgetItem * parent); - -protected slots: - void itemSelectedChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); - void itemSelected(QTreeWidgetItem *item, int column); - -private: - ITEM_STYLE_PROXY * m_pItemProxy; - CNavigationDelegate * m_pItemDelegate; - Navigation_Mode m_navigationMode; - - QString m_strFileHomePath; - QMap m_mapEnable; - QMap m_mapNodeType; -}; - -#endif // CNAVIGATIONWIDGET_H +#ifndef CNAVIGATIONWIDGET_H +#define CNAVIGATIONWIDGET_H + +#include +#include "CNavigationConfigDialog.h" +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CNavigationDelegate; + +typedef unsigned int rgb; + +typedef std::tuple NodeInfo; //< 节点背景颜色、节点字体颜色、节点字体大小、图标大小、偏移像素 + +extern const int Level_Role; //< 节点层级 +extern const int Corner_Role; //< 活动根节点 +extern const int IconPath_Role; //< 节点图标路径 +extern const int Item_Role; //< 节点数 +extern const int Enable_Role; //< 是否启用 +extern const int Web_Role; //< 是否web发布 +extern const int Opt_Role; //< 操作类型 +extern const int Url_Role; //< 加载网页url + +struct ITEM_STYLE_PROXY +{ + int indicatorWidth; + int iconMargin; + + //< 填充颜色 + rgb backgroundColor; + rgb itemHoveredColor; + rgb itemSelectedColor; + + //< 文字颜色 + rgb itemTextColor; + rgb itemHoveredTextColor; + rgb itemSelectedTextColor; + + std::vector< NodeInfo > vecItemStyle; +}; + +class CNavigationWidget : public QTreeWidget, public IPluginWidget +{ + Q_OBJECT + friend class CNavigationConfigDialog; +public: + enum Navigation_Mode + { + EXPLORER_MODE = 0, + EDIT_MODE, + CONFIG_MODE, + }; + + enum Node_Level + { + TOP_LEVEL = 0, + CHILD_LEVEL, + LEAF_LEVEL + }; + + enum Node_Type + { + NONE = 0, //< 无操作 + SWITCH_GRAPH, //< 切换画面 + SWITCH_NAV, //< 切换导航 + EXTERN_PRO, //< 调用程序 + }; + + enum Node_Enable + { + Enable = 1, + Disable = 2, + }; + + explicit CNavigationWidget(QWidget *parent = Q_NULLPTR, bool editMode = true); + + ~CNavigationWidget(); + + void setNavigationMode(const Navigation_Mode &navigationMode); + + virtual void config(); + virtual void release(){} + virtual bool read(CGStream &ios) { Q_UNUSED(ios); return false; } + virtual bool write(CGStream &ios) { Q_UNUSED(ios); return false; } + virtual void setProperty(const QString &propertyName, QVariant value) { Q_UNUSED(propertyName); Q_UNUSED(value);} + virtual void getProperty(QList< QPair > &propertyList) { Q_UNUSED(propertyList); } + +/************************************ 脚本接口-[begin] ****************************************/ + +public Q_SLOTS: + void setTopLevelIndexes(const QString &strIndexes); + + void setItemSelected(const QString &data); + + void addTopLevelItem(const int &number, const QString &caption, const QString &data = QString(), const QString &icon = QString(), + const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); + + void addChildItem(const int &number, const QList &parents, const QString &caption, const QString &data = QString(), const QString &icon = QString(), + const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); + + void addLevelItem(const int &number, const QList &parents, const QString &caption, const QString &data = QString(), const QString &icon = QString(), + const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); + + void removeItem(QTreeWidgetItem *item); + + int slotImport(); + + void slotExport(); + + void clearItems(); + + void setIconSize(const int &width, const int &height); + void setBranchIconSize(const int &width, const int &height); + + void setRowHeight(const int &rowHeight); + + void setIndentation(const int &indentation); + + void initStyleProxy(); + + void getNodeTypeMap(QMap &map); + + /******************** 样式设置-[begin] ************************/ + void setTreeBackgroundColor(const rgb &color); + void setItemHoverBackgroundColor(const rgb &color); + void setItemSelectedBackgroundColor(const rgb &color); + + void setTextColor(const rgb &color); + void setTextHoverColor(const rgb &color); + void setTextSelectedColor(const rgb &color); + + void setItemBackgroundColor(const rgb &color, const Node_Level &level); + void setItemTextSize(const int &size, const Node_Level &level); + /******************** 样式设置-[end] *************************/ + +Q_SIGNALS: + void graphItemClicked(const QString &caption, const QString &data, const int &type, const QString &url); + +/************************************* 脚本接口-[end] ********************************************/ + + +private: + void initialize(); + + void loadItemDelegate(); + + void updateItems(const CNavigationWidget * pNavigation); + + QTreeWidgetItem * buildNewItem(const QTreeWidgetItem * parent); + + void updateStyleProxy(const ITEM_STYLE_PROXY * proxy); + + void paintEvent(QPaintEvent *event); + + void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const; + + void contextMenuEvent(QContextMenuEvent *e); + + void read(const QString &strFileName); + + void write(const QString &strFileName); + + QString hexTo26(int number); + + int findValue(const QMap &map, const QString &key); + + QString getNodeTypeStr(int type); + int getNodeType(const QString &str); + + QString getEnableStr(int enable); + int getEnable(const QString &str); + + QTreeWidgetItem * findItem(const QString &data, QTreeWidgetItem * parent); + +protected slots: + void itemSelectedChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void itemSelected(QTreeWidgetItem *item, int column); + +private: + ITEM_STYLE_PROXY * m_pItemProxy; + CNavigationDelegate * m_pItemDelegate; + Navigation_Mode m_navigationMode; + + QString m_strFileHomePath; + QMap m_mapEnable; + QMap m_mapNodeType; +}; + +#endif // CNAVIGATIONWIDGET_H diff --git a/product/src/gui/plugin/NavigationWidget/NavigationConfigDialog.ui b/product/src/gui/plugin/NavigationWidget/NavigationConfigDialog.ui index bf5c12a7..aca5d2e4 100644 --- a/product/src/gui/plugin/NavigationWidget/NavigationConfigDialog.ui +++ b/product/src/gui/plugin/NavigationWidget/NavigationConfigDialog.ui @@ -1,1095 +1,1095 @@ - - - NavigationConfigDialog - - - - 0 - 0 - 610 - 575 - - - - 导航栏配置 - - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - 3 - - - - - - 60 - 21 - - - - - 60 - 21 - - - - 导入 - - - 导入 - - - false - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 添加节点 - - - - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 删除节点 - - - - - - false - - - - - - - - 18 - 18 - - - - - 21 - 21 - - - - - false - - - - 清空 - - - × - - - false - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 添加子节点 - - - - - - false - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 插入节点 - - - | - - - false - - - - - - - true - - - false - - - - 导航栏 - - - - - - - - - 60 - 21 - - - - - 60 - 21 - - - - 导出 - - - 导出 - - - false - - - - - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - QFrame::Box - - - QFrame::Sunken - - - - - - 背景颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - 文字颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - - - 背景颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - 文字颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - - - - 鼠标选中: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - 鼠标悬停: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 启用: - - - - - - - - - - - - - - web发布: - - - - - - - - - - - - - - 图标: - - - - - - - 0 - - - - - - 24 - 22 - - - - - 24 - 22 - - - - ... - - - false - - - - - - - - - - - - 操作: - - - - - - - 数据: - - - - - - - 0 - - - 6 - - - - - - 24 - 22 - - - - - 24 - 22 - - - - ... - - - false - - - - - - - - - - - - - - - - - - 项属性: - - - - - - - 节点层级属性: - - - - - - - 节点状态属性: - - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - - - - 70 - 21 - - - - - - - - - - - - - - 背景颜色: - - - - - - - - - - 窗口配置: - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - 0 - - - - 一级节点 - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - QFrame::Box - - - QFrame::Sunken - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 级别背景颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - 级别文字颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - 级别缩进距离: - - - - - - - px - - - - - - - - - - - 二级节点 - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - QFrame::Box - - - QFrame::Sunken - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 级别背景颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - 级别文字颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - 级别缩进距离: - - - - - - - px - - - - - - - - - - - 三级节点 - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - QFrame::Box - - - QFrame::Sunken - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 级别背景颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - 级别文字颜色: - - - - - - - - 70 - 21 - - - - - - - - - - - - - - 级别缩进距离: - - - - - - - px - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 246 - 20 - - - - - - - - - 50 - 0 - - - - 取消 - - - false - - - - - - - - 50 - 0 - - - - 确定 - - - false - - - - - - - - - - CNavigationWidget - QTreeWidget -
CNavigationWidget.h
-
- - CColorLabel - QLabel -
CColorLabel.h
-
-
- - - - ok - clicked() - NavigationConfigDialog - accept() - - - 485 - 549 - - - 457 - 606 - - - - - cancle - clicked() - NavigationConfigDialog - reject() - - - 568 - 543 - - - 577 - 623 - - - - -
+ + + NavigationConfigDialog + + + + 0 + 0 + 610 + 575 + + + + 导航栏配置 + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + 3 + + + + + + 60 + 21 + + + + + 60 + 21 + + + + 导入 + + + 导入 + + + false + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 添加节点 + + + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 删除节点 + + + + + + false + + + + + + + + 18 + 18 + + + + + 21 + 21 + + + + + false + + + + 清空 + + + × + + + false + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 添加子节点 + + + + + + false + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 插入节点 + + + | + + + false + + + + + + + true + + + false + + + + 导航栏 + + + + + + + + + 60 + 21 + + + + + 60 + 21 + + + + 导出 + + + 导出 + + + false + + + + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + 背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + 背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + + + + 鼠标选中: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + 鼠标悬停: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 启用: + + + + + + + + + + + + + + web发布: + + + + + + + + + + + + + + 图标: + + + + + + + 0 + + + + + + 24 + 22 + + + + + 24 + 22 + + + + ... + + + false + + + + + + + + + + + + 操作: + + + + + + + 数据: + + + + + + + 0 + + + 6 + + + + + + 24 + 22 + + + + + 24 + 22 + + + + ... + + + false + + + + + + + + + + + + + + + + + + 项属性: + + + + + + + 节点层级属性: + + + + + + + 节点状态属性: + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + + 70 + 21 + + + + + + + + + + + + + + 背景颜色: + + + + + + + + + + 窗口配置: + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 0 + + + + 一级节点 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 级别背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别缩进距离: + + + + + + + px + + + + + + + + + + + 二级节点 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 级别背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别缩进距离: + + + + + + + px + + + + + + + + + + + 三级节点 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 级别背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别缩进距离: + + + + + + + px + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 246 + 20 + + + + + + + + + 50 + 0 + + + + 取消 + + + false + + + + + + + + 50 + 0 + + + + 确定 + + + false + + + + + + + + + + CNavigationWidget + QTreeWidget +
CNavigationWidget.h
+
+ + CColorLabel + QLabel +
CColorLabel.h
+
+
+ + + + ok + clicked() + NavigationConfigDialog + accept() + + + 485 + 549 + + + 457 + 606 + + + + + cancle + clicked() + NavigationConfigDialog + reject() + + + 568 + 543 + + + 577 + 623 + + + + +
diff --git a/product/src/gui/plugin/NavigationWidget/NavigationResource.qrc b/product/src/gui/plugin/NavigationWidget/NavigationResource.qrc index 4080fb00..78593735 100644 --- a/product/src/gui/plugin/NavigationWidget/NavigationResource.qrc +++ b/product/src/gui/plugin/NavigationWidget/NavigationResource.qrc @@ -1,8 +1,8 @@ - - - image/arrowCollapse.png - image/arrowCollapseHover.png - image/arrowExpand.png - image/arrowExpandHover.png - - + + + image/arrowCollapse.png + image/arrowCollapseHover.png + image/arrowExpand.png + image/arrowExpandHover.png + + diff --git a/product/src/gui/plugin/NavigationWidget/NavigationWidget.pro b/product/src/gui/plugin/NavigationWidget/NavigationWidget.pro index 18768494..586cf2af 100644 --- a/product/src/gui/plugin/NavigationWidget/NavigationWidget.pro +++ b/product/src/gui/plugin/NavigationWidget/NavigationWidget.pro @@ -1,46 +1,46 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-12-09T00:12:34 -# -#------------------------------------------------- - -QT += core gui printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = NavigationWidget -TEMPLATE = lib - -CONFIG += plugin - -SOURCES += \ - CNavigationWidget.cpp \ - CNavigationDelegate.cpp \ - CColorLabel.cpp \ - CNavigationPluginWidget.cpp \ - CNavigationConfigDialog.cpp - -HEADERS += \ - CNavigationWidget.h \ - CNavigationDelegate.h \ - CColorLabel.h \ - CNavigationPluginWidget.h \ - CNavigationConfigDialog.h - -FORMS += \ - NavigationConfigDialog.ui - -RESOURCES += \ - NavigationResource.qrc - -LIBS += -lpub_utility_api \ - -lmodel_excel - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2018-12-09T00:12:34 +# +#------------------------------------------------- + +QT += core gui printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = NavigationWidget +TEMPLATE = lib + +CONFIG += plugin + +SOURCES += \ + CNavigationWidget.cpp \ + CNavigationDelegate.cpp \ + CColorLabel.cpp \ + CNavigationPluginWidget.cpp \ + CNavigationConfigDialog.cpp + +HEADERS += \ + CNavigationWidget.h \ + CNavigationDelegate.h \ + CColorLabel.h \ + CNavigationPluginWidget.h \ + CNavigationConfigDialog.h + +FORMS += \ + NavigationConfigDialog.ui + +RESOURCES += \ + NavigationResource.qrc + +LIBS += -lpub_utility_api \ + -lmodel_excel + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.cpp b/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.cpp index 309937e5..dd8ca7fd 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.cpp +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.cpp @@ -1,783 +1,783 @@ -#include "COperationOrderForm.h" -#include "ui_COperationOrderForm.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_logger_api/logger.h" -#include -#include -#include -#include - -COperationOrderForm::COperationOrderForm(QWidget *parent) : - QDialog(parent), - ui(new Ui::COperationOrderForm), - m_ptrPrinter(new COrderPrinter()) -{ - ui->setupUi(this); - - m_editOrderId = ui->m_editOrderId; - m_editName = ui->m_editName; - m_table = ui->m_table; - m_editDesc = ui->m_editDesc; - m_editRemarks = ui->m_editRemarks; - m_operator= ui->m_operator; - m_guard = ui->m_guard; - m_duty = ui->m_duty; - m_editStartTime = ui->m_editStartTime; - m_editEndTime = ui->m_editEndTime; - - connect(ui->add,SIGNAL(clicked(bool)),this,SLOT(slot_addOneOperate())); - connect(ui->del,SIGNAL(clicked(bool)),this,SLOT(slot_deleteOneOperate())); - connect(ui->up,SIGNAL(clicked(bool)),this,SLOT(slot_upOneOperate())); - connect(ui->down,SIGNAL(clicked(bool)),this,SLOT(slot_downOneOperate())); - connect(ui->print,SIGNAL(clicked(bool)),this,SLOT(slot_print())); - connect(ui->preprint,SIGNAL(clicked(bool)),this,SLOT(slot_preview())); - connect(ui->save,SIGNAL(clicked(bool)),this,SLOT(slot_saveModel())); - - QDateTime current = QDateTime::currentDateTime(); - ui->m_editStartTime->setDateTime(current); - ui->m_editEndTime->setDateTime(current); - - initTableView(); -} - -COperationOrderForm::~COperationOrderForm() -{ - if(m_ptrPrinter) - { - delete m_ptrPrinter; - m_ptrPrinter = NULL; - } -} - -void COperationOrderForm::initTableView() -{ - ui->m_table->setColumnCount(5); - ui->m_table->setRowCount(0); - ui->m_table->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->m_table->verticalHeader()->setVisible(false); - ui->m_table->setHorizontalHeaderLabels(QStringList()<m_table->horizontalHeader()->setSectionResizeMode(1,QHeaderView::Stretch); - ui->m_table->horizontalHeader()->setSectionResizeMode(2,QHeaderView::Stretch); - ui->m_table->hideColumn(3); - ui->m_table->hideColumn(4); -} - -void COperationOrderForm::initViewData() -{ - initUserComb(); - readOrderInfoData(); - resetViewData(); -} - -void COperationOrderForm::insertTableData(const SOrderPreStoreInfo &vect) -{ - ui->m_table->blockSignals(true); - int curRow = ui->m_table->rowCount(); - ui->m_table->insertRow(curRow); - - int seqNo = vect.seqNo; - QString desc = vect.optDesc; - QString remarks = vect.remarks; - QString keyIdTag = vect.keyIdTag; - int ctrlValue = vect.ctrlValue; - - QTableWidgetItem *seqNoi = new QTableWidgetItem(); - seqNoi->setText(QString::number(seqNo)); - QTableWidgetItem *desci = new QTableWidgetItem(); - desci->setText(desc); - QTableWidgetItem *remarksi = new QTableWidgetItem(); - remarksi->setText(remarks); - QTableWidgetItem *keyIdTagi = new QTableWidgetItem(); - keyIdTagi->setText(keyIdTag); - QTableWidgetItem *ctrlValuei = new QTableWidgetItem(); - ctrlValuei->setText(QString::number(ctrlValue)); - - ui->m_table->setItem(curRow,0,seqNoi); - ui->m_table->item(curRow,0)->setTextAlignment(Qt::AlignCenter); - ui->m_table->setItem(curRow,1,desci); - ui->m_table->item(curRow,1)->setTextAlignment(Qt::AlignCenter); - ui->m_table->setItem(curRow,2,remarksi); - ui->m_table->item(curRow,2)->setTextAlignment(Qt::AlignCenter); - ui->m_table->setItem(curRow,3,keyIdTagi); - ui->m_table->setItem(curRow,4,ctrlValuei); - ui->m_table->blockSignals(false); -} - -void COperationOrderForm::initUserComb() -{ - ui->m_operator->clear(); - ui->m_guard->clear(); - ui->m_duty->clear(); - - CSqlDbCtrl dbCtrl; - QMap resultMap = dbCtrl.readUserInfo(); - QMap::const_iterator iter = resultMap.constBegin(); - for(; iter != resultMap.constEnd(); iter++) - { - ui->m_operator->addItem(iter.value(), iter.key()); - ui->m_guard->addItem(iter.value(), iter.key()); - ui->m_duty->addItem(iter.value(), iter.key()); - } -} - -void COperationOrderForm::closeEvent(QCloseEvent *event) -{ - QDialog::closeEvent(event); -} - -void COperationOrderForm::slot_addOneOperate() -{ - int curRow = ui->m_table->currentRow(); - if(curRow < 0) - { - curRow = 0; - } - ui->m_table->insertRow(curRow); - - for(int col = 1;colm_table->columnCount();++col) - { - QTableWidgetItem *colItem = new QTableWidgetItem(""); - ui->m_table->setItem(curRow,col,colItem); - ui->m_table->item(curRow,col)->setTextAlignment(Qt::AlignCenter); - } - - int rowCount = ui->m_table->rowCount(); - for(int i=curRow; im_table->setItem(i,0,ui->m_table->takeItem(i+1,0)); - } - QTableWidgetItem *item = new QTableWidgetItem(); - item->setText(QString::number(rowCount)); - ui->m_table->setItem(rowCount-1,0,item); - ui->m_table->item(rowCount-1,0)->setTextAlignment(Qt::AlignCenter); -} - -void COperationOrderForm::slot_deleteOneOperate() -{ - int curRow = ui->m_table->currentRow(); - if(curRow < 0) - { - return; - } - ui->m_table->removeRow(curRow); - m_changedList.append(curRow); - - int rowCount = ui->m_table->rowCount(); - for(int i=curRow; isetText(QString::number(i+1)); - ui->m_table->setItem(i,0,item); - ui->m_table->item(i,0)->setTextAlignment(Qt::AlignCenter); - } - - if(curRow+1 > rowCount) - { - ui->m_table->selectRow(rowCount-1); - } - else - ui->m_table->selectRow(curRow); - -} - -void COperationOrderForm::slot_upOneOperate() -{ - int curRow = ui->m_table->currentRow(); - if(curRow <= 0) - { - return; - } - int insertRow = curRow - 1; - - ui->m_table->insertRow(insertRow); - for(int i=0;im_table->columnCount();++i) - { - if(i==0) - { - ui->m_table->setItem(insertRow,0,ui->m_table->takeItem(curRow,0)); - ui->m_table->setItem(curRow,0,ui->m_table->takeItem(curRow+1,0)); - } - else - ui->m_table->setItem(insertRow,i,ui->m_table->takeItem(curRow+1,i)); - } - ui->m_table->removeRow(curRow+1); - - if(m_changedList.indexOf(curRow) != -1 - || m_changedList.indexOf(insertRow) != -1) - { - on_m_table_cellChanged(curRow,0); - on_m_table_cellChanged(insertRow,0); - } - ui->m_table->selectRow(insertRow); - - -} - -void COperationOrderForm::slot_downOneOperate() -{ - int curRow = ui->m_table->currentRow(); - int row = ui->m_table->rowCount(); - if(curRow == -1) - { - return; - } - if(curRow+1 >= row) - { - return; - } - int insertRow = curRow + 2; - - ui->m_table->insertRow(insertRow); - for(int i=0;im_table->columnCount();++i) - { - if(i==0) - { - ui->m_table->setItem(insertRow,0,ui->m_table->takeItem(curRow+1,0)); - ui->m_table->setItem(curRow+1,0,ui->m_table->takeItem(curRow,0)); - } - else - ui->m_table->setItem(insertRow,i,ui->m_table->takeItem(curRow,i)); - } - ui->m_table->removeRow(curRow); - - if(m_changedList.indexOf(curRow) != -1 - || m_changedList.indexOf(insertRow-1) != -1) - { - on_m_table_cellChanged(curRow,0); - on_m_table_cellChanged(insertRow-1,0); - } - ui->m_table->selectRow(insertRow-1); -} - -int COperationOrderForm::slot_saveModel() -{ - if(omPermCheck() == false) - { - return -1; - } - - ui->m_table->setCurrentCell(-1,-1); - if(!checkTableData()) - { - return -1; - } - - //if (!checkOrderModel()) - { - // return -1; - } - - if(!updateDbModelData()) - { - return -1; - } - - - resetViewData(); - - return 0; -} - -bool COperationOrderForm::checkTableData() -{ - for(int row=0;rowm_table->rowCount();++row) - { - if(ui->m_table->item(row,0) == NULL) - { - QMessageBox::warning(this, tr("提示"), tr("行:%1 顺序为空!").arg(row+1), QMessageBox::Ok); - return false; - } - - for(int n=row+1;nm_table->rowCount();++n) - { - if(ui->m_table->item(row,0)->text() == ui->m_table->item(n,0)->text()) - { - QMessageBox::warning(this, tr("提示"), tr("行:%1 与行:%2 顺序重复!").arg(row+1).arg(n+1), QMessageBox::Ok); - return false; - } - } - - if(ui->m_table->item(row,1) == NULL) - { - QMessageBox::warning(this, tr("提示"), tr("行:%1 操作内容为空!").arg(row+1), QMessageBox::Ok); - return false; - } - } - return true; -} - -bool COperationOrderForm::checkOrderModel() -{ - CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); - bool re = true; - if(ui->m_editName->text() != m_sOrderInfo.orderName) - { - QList orderName; - - dbCtrl.readOrderName(orderName); - if(orderName.indexOf(ui->m_editName->text()) != -1) - { - QMessageBox::warning(this, tr("提示"), tr("典型票名已存在!"), QMessageBox::Ok); - return false; - } - - bool re = dbCtrl.updateOneOrderData(ui->m_editName->text(),m_sOrderInfo.id); - if(!re) - { - QMessageBox::warning(this, tr("提示"), tr("典型票名: '%1' 保存失败!").arg(ui->m_editName->text()), QMessageBox::Ok); - return false; - } - else - { - m_sOrderInfo.orderName = ui->m_editName->text(); - } - } - - if(ui->m_editDesc->text() != m_sOrderInfo.orderDesc - || ui->m_editRemarks->toPlainText() != m_sOrderInfo.remarks) - { - re = dbCtrl.updateOneOrderData(ui->m_editDesc->text(), - ui->m_editRemarks->toPlainText(), - m_sOrderInfo.id); - if(!re) - { - QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return false; - } - else - { - m_sOrderInfo.orderDesc = ui->m_editDesc->text(); - m_sOrderInfo.remarks = ui->m_editRemarks->toPlainText(); - } - } - return re; -} - -bool COperationOrderForm::updateDbModelData() -{ - CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); - - bool ret = true; - QString orderName = ui->m_editName->text(); - int order_id = dbCtrl.getOrderId(orderName); - if (order_id != -1) - { - int ret = QMessageBox::information(this, tr("提示"), tr("已经存在“%1”,是否覆盖?").arg(orderName), - QMessageBox::Cancel | QMessageBox::Ok, QMessageBox::Cancel); - - if (ret == QMessageBox::Cancel) - { - return false; - } - - ret = dbCtrl.deleteOneOrderData(orderName); - if (ret == false) - { - QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return ret; - } - - ret = dbCtrl.deleteAllOrderInfoData(order_id); - if (ret == false) - { - QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return ret; - } - } - - order_id = dbCtrl.readOrderDataMaxId(); - if (order_id == -1) - { - QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return false; - } - - SOrderPreStore order; - order.id = order_id; - order.orderDesc = ui->m_editDesc->text(); - order.orderName = orderName; - order.remarks = ui->m_editRemarks->toPlainText(); - - ret = dbCtrl.insertOneOrderData(order); - if (ret == false) - { - QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return ret; - } - - ret = dbCtrl.deleteAllOrderInfoData(order_id); - if (ret == false) - { - QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return ret; - } - - for (int row = 0; row < ui->m_table->rowCount(); ++row) - { - int seq = ui->m_table->item(row, 0)->text().toInt(); - - SOrderPreStoreInfo info = getOrderInfo(row, order_id); - ret = dbCtrl.insertOneOrderInfoData(info); - if (ret == false) - { - QMessageBox::warning(this, tr("提示"), tr("行:%1 保存失败!").arg(row + 1), QMessageBox::Ok); - return ret; - } - continue; - } - - QMessageBox::warning(this, tr("提示"), tr("保存成功!"), QMessageBox::Ok); - return ret; -} - -void COperationOrderForm::slot_print() -{ - if(omPermCheck() == false) - { - return; - } - - if(!checkBeforePrint()) - { - return; - } - - saveToHis(); - - printInit(); - - int ret = m_ptrPrinter->print(ui->m_table); - if(ret == 1) - { - QMessageBox::warning(this, tr("提示"), tr("打印成功!"), QMessageBox::Ok); - } - else if(ret == -1) - { - QMessageBox::warning(this, tr("提示"), tr("打印失败!"), QMessageBox::Ok); - } -} - -bool COperationOrderForm::saveToHis() -{ - CSqlDbCtrl dbCtrl; - int hisMaxNum = dbCtrl.readOrderHisMixID(); - - if(hisMaxNum == -1) - { - QMessageBox::warning(this, tr("提示"), tr("打开历史表失败!"), QMessageBox::Ok); - return false; - } - - if(insertHisTable(hisMaxNum) == false) - { - QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return false; - } - - for(int i=0; im_table->rowCount(); ++i) - { - if(insertHisInfoTable(hisMaxNum,i) == false) - { - QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); - return false; - } - } - - return true; -} - -void COperationOrderForm::printInit() -{ - m_ptrPrinter->initPrintEnv(); - m_ptrPrinter->setPrintCaption(ui->m_editName->text()); - - QString no = tr("操作票号: ") + ui->m_editOrderId->text(); - - int columnCount = 0; - for(int nIndex(0); nIndex < ui->m_table->columnCount(); nIndex++) - { - if(!ui->m_table->isColumnHidden(nIndex)) - { - columnCount += 1; - } - } - m_ptrPrinter->setPrintParagraph(no, columnCount); - - QString startTime = tr("操作开始时间: ") + ui->m_editStartTime->text(); - m_ptrPrinter->setPrintParagraph(startTime, columnCount, false, true); - - QString endTime = tr("操作结束时间: ") + ui->m_editEndTime->text(); - m_ptrPrinter->setPrintParagraph(endTime, columnCount, false, true); - - QString paragraph = tr("操作任务: ") + ui->m_editDesc->text(); - m_ptrPrinter->setPrintParagraph(paragraph, columnCount, false, true); - - QString markText = ui->m_editRemarks->toPlainText(); - markText = markText.replace("/\n/g", "

"); - QString mark = tr("备注:
") + markText; - m_ptrPrinter->setPrintParagraph(mark, columnCount, true, true); - - CSqlDbCtrl dbCtrl; - - QPair operatr; - operatr.first = tr("操作人:"); - operatr.second = ui->m_operator->currentText(); - if(ui->m_sign->isChecked()) - { - m_ptrPrinter->setPrintWithBack(operatr, 1, dbCtrl.readSignatureData(ui->m_operator->currentData().toInt())); - } - else - { - m_ptrPrinter->setPrintWithBack(operatr, 1, QString()); - } - - QPair guard; - guard.first = tr("监护人:"); - guard.second = ui->m_guard->currentText(); - if(ui->m_sign->isChecked()) - { - m_ptrPrinter->setPrintWithBack(guard, 1, dbCtrl.readSignatureData(ui->m_guard->currentData().toInt())); - } - else - { - m_ptrPrinter->setPrintWithBack(guard, 1, QString()); - } - - QPair duty; - duty.first = tr("值班负责人:"); - duty.second = ui->m_duty->currentText(); - if(ui->m_sign->isChecked()) - { - m_ptrPrinter->setPrintWithBack(duty, 1, dbCtrl.readSignatureData(ui->m_duty->currentData().toInt())); - } - else - { - m_ptrPrinter->setPrintWithBack(duty, 1, QString()); - } -} - -bool COperationOrderForm::isViewDataChange() -{ - if (m_sOrderInfo.begin_time != 0) - { - qint64 time = ui->m_editStartTime->dateTime().toTime_t(); - if (m_sOrderInfo.begin_time/1000 != time) - { - return true; - } - } - - if (m_sOrderInfo.end_time != 0) - { - qint64 time = ui->m_editEndTime->dateTime().toTime_t(); - if (m_sOrderInfo.end_time / 1000 != time) - { - return true; - } - } - - if (!m_sOrderInfo.OPERATOR.isEmpty()) - { - QString str = ui->m_operator->currentText(); - if (m_sOrderInfo.OPERATOR != str) - { - return true; - } - } - - if (!m_sOrderInfo.guardian.isEmpty()) - { - QString str = ui->m_guard->currentText(); - if (m_sOrderInfo.guardian != str) - { - return true; - } - } - - if (!m_sOrderInfo.duty_manager.isEmpty()) - { - QString str = ui->m_duty->currentText(); - if (m_sOrderInfo.duty_manager != str) - { - return true; - } - } - - if (ui->m_editName->text() != m_sOrderInfo.orderName - || ui->m_editDesc->text() != m_sOrderInfo.orderDesc - || ui->m_editRemarks->toPlainText() != m_sOrderInfo.remarks - || m_changedList.length() != 0) - { - return true; - } - - return false; -} - -void COperationOrderForm::resetViewData() -{ - qint64 time = ui->m_editStartTime->dateTime().toTime_t(); - m_sOrderInfo.begin_time = time * 1000; - time = ui->m_editEndTime->dateTime().toTime_t(); - m_sOrderInfo.end_time = time * 1000; - m_sOrderInfo.duty_manager = ui->m_duty->currentText(); - m_sOrderInfo.guardian = ui->m_guard->currentText(); - m_sOrderInfo.id = ui->m_editOrderId->text().toInt(); - m_sOrderInfo.OPERATOR = ui->m_operator->currentText(); - m_sOrderInfo.orderDesc = ui->m_editDesc->text(); - m_sOrderInfo.orderName = ui->m_editName->text(); - m_sOrderInfo.remarks = ui->m_editRemarks->toPlainText(); - m_changedList.clear(); -} - -bool COperationOrderForm::insertHisTable(int num) -{ - CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); - SOrderHis his; - - his.id = num; - his.order_no = ui->m_editOrderId->text(); - his.order_name = ui->m_editName->text(); - his.order_desc = ui->m_editDesc->text(); - his.begin_time = ui->m_editStartTime->dateTime().toMSecsSinceEpoch(); - his.end_time = ui->m_editEndTime->dateTime().toMSecsSinceEpoch(); - his.remarks = ui->m_editRemarks->toPlainText(); - his.OPERATOR = ui->m_operator->currentText(); - his.guardian = ui->m_guard->currentText(); - his.duty_manager = ui->m_duty->currentText(); - his.exec_state = -1; - - return dbCtrl.insertOneOrderHisData(his); -} - -bool COperationOrderForm::insertHisInfoTable(int num, int row) -{ - CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); - SOrderHisInfo hisInfo; - - hisInfo.order_id = num; - hisInfo.seq_no = ui->m_table->item(row,0)->text().toInt(); - hisInfo.opt_desc = ui->m_table->item(row,1)->text(); - hisInfo.key_id_tag = ui->m_table->item(row,3)->text(); - hisInfo.ctrl_value = ui->m_table->item(row,4)->text().toInt(); - hisInfo.remarks = ui->m_table->item(row,2)->text(); - hisInfo.exec_state = -1; - - return dbCtrl.insertOneOrderHisInfoData(hisInfo); -} - -void COperationOrderForm::slot_preview() -{ - if(omPermCheck() == false) - { - return; - } - - if(!checkBeforePrint()) - { - return; - } - - printInit(); - - m_ptrPrinter->preview(ui->m_table); -} - -bool COperationOrderForm::checkBeforePrint() -{ - if(ui->m_editName->text().isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("典型票名为空!"), QMessageBox::Ok); - return false; - } - - if(ui->m_editOrderId->text().isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("操作票号为空!"), QMessageBox::Ok); - return false; - } - - if(ui->m_operator->currentText().isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("操作人为空!"), QMessageBox::Ok); - return false; - } - - if(ui->m_guard->currentText().isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("监护人为空!"), QMessageBox::Ok); - return false; - } - - if(ui->m_duty->currentText().isEmpty()) - { - QMessageBox::warning(this, tr("提示"), tr("值班负责人为空!"), QMessageBox::Ok); - return false; - } - - return true; -} - -SOrderPreStoreInfo COperationOrderForm::getOrderInfo(int row, int orderId) -{ - SOrderPreStoreInfo info; - - info.orderId = orderId; - info.seqNo = ui->m_table->item(row,0)->text().toInt(); - info.optDesc = ui->m_table->item(row,1)->text(); - - if(ui->m_table->item(row,3) == NULL) - { - info.keyIdTag = ""; - } - else - { - info.keyIdTag = ui->m_table->item(row,3)->text(); - } - - if(ui->m_table->item(row,4) == NULL) - { - info.ctrlValue = -1; - } - else - { - info.ctrlValue = ui->m_table->item(row,4)->text().toInt(); - } - - if(ui->m_table->item(row,2) == NULL) - { - info.remarks = ""; - } - else - { - info.remarks = ui->m_table->item(row,2)->text(); - } - - return info; -} - -void COperationOrderForm::on_m_table_cellChanged(int row, int column) -{ - Q_UNUSED(column) - if(m_changedList.indexOf(row) == -1) - { - m_changedList.append(row); - } -} - -bool COperationOrderForm::omPermCheck() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - std::string tmpStr = "FUNC_NOM_OM"; - if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) - { - QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限!"), QMessageBox::Ok); - return false; - } - return true; -} +#include "COperationOrderForm.h" +#include "ui_COperationOrderForm.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_logger_api/logger.h" +#include +#include +#include +#include + +COperationOrderForm::COperationOrderForm(QWidget *parent) : + QDialog(parent), + ui(new Ui::COperationOrderForm), + m_ptrPrinter(new COrderPrinter()) +{ + ui->setupUi(this); + + m_editOrderId = ui->m_editOrderId; + m_editName = ui->m_editName; + m_table = ui->m_table; + m_editDesc = ui->m_editDesc; + m_editRemarks = ui->m_editRemarks; + m_operator= ui->m_operator; + m_guard = ui->m_guard; + m_duty = ui->m_duty; + m_editStartTime = ui->m_editStartTime; + m_editEndTime = ui->m_editEndTime; + + connect(ui->add,SIGNAL(clicked(bool)),this,SLOT(slot_addOneOperate())); + connect(ui->del,SIGNAL(clicked(bool)),this,SLOT(slot_deleteOneOperate())); + connect(ui->up,SIGNAL(clicked(bool)),this,SLOT(slot_upOneOperate())); + connect(ui->down,SIGNAL(clicked(bool)),this,SLOT(slot_downOneOperate())); + connect(ui->print,SIGNAL(clicked(bool)),this,SLOT(slot_print())); + connect(ui->preprint,SIGNAL(clicked(bool)),this,SLOT(slot_preview())); + connect(ui->save,SIGNAL(clicked(bool)),this,SLOT(slot_saveModel())); + + QDateTime current = QDateTime::currentDateTime(); + ui->m_editStartTime->setDateTime(current); + ui->m_editEndTime->setDateTime(current); + + initTableView(); +} + +COperationOrderForm::~COperationOrderForm() +{ + if(m_ptrPrinter) + { + delete m_ptrPrinter; + m_ptrPrinter = NULL; + } +} + +void COperationOrderForm::initTableView() +{ + ui->m_table->setColumnCount(5); + ui->m_table->setRowCount(0); + ui->m_table->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->m_table->verticalHeader()->setVisible(false); + ui->m_table->setHorizontalHeaderLabels(QStringList()<m_table->horizontalHeader()->setSectionResizeMode(1,QHeaderView::Stretch); + ui->m_table->horizontalHeader()->setSectionResizeMode(2,QHeaderView::Stretch); + ui->m_table->hideColumn(3); + ui->m_table->hideColumn(4); +} + +void COperationOrderForm::initViewData() +{ + initUserComb(); + readOrderInfoData(); + resetViewData(); +} + +void COperationOrderForm::insertTableData(const SOrderPreStoreInfo &vect) +{ + ui->m_table->blockSignals(true); + int curRow = ui->m_table->rowCount(); + ui->m_table->insertRow(curRow); + + int seqNo = vect.seqNo; + QString desc = vect.optDesc; + QString remarks = vect.remarks; + QString keyIdTag = vect.keyIdTag; + int ctrlValue = vect.ctrlValue; + + QTableWidgetItem *seqNoi = new QTableWidgetItem(); + seqNoi->setText(QString::number(seqNo)); + QTableWidgetItem *desci = new QTableWidgetItem(); + desci->setText(desc); + QTableWidgetItem *remarksi = new QTableWidgetItem(); + remarksi->setText(remarks); + QTableWidgetItem *keyIdTagi = new QTableWidgetItem(); + keyIdTagi->setText(keyIdTag); + QTableWidgetItem *ctrlValuei = new QTableWidgetItem(); + ctrlValuei->setText(QString::number(ctrlValue)); + + ui->m_table->setItem(curRow,0,seqNoi); + ui->m_table->item(curRow,0)->setTextAlignment(Qt::AlignCenter); + ui->m_table->setItem(curRow,1,desci); + ui->m_table->item(curRow,1)->setTextAlignment(Qt::AlignCenter); + ui->m_table->setItem(curRow,2,remarksi); + ui->m_table->item(curRow,2)->setTextAlignment(Qt::AlignCenter); + ui->m_table->setItem(curRow,3,keyIdTagi); + ui->m_table->setItem(curRow,4,ctrlValuei); + ui->m_table->blockSignals(false); +} + +void COperationOrderForm::initUserComb() +{ + ui->m_operator->clear(); + ui->m_guard->clear(); + ui->m_duty->clear(); + + CSqlDbCtrl dbCtrl; + QMap resultMap = dbCtrl.readUserInfo(); + QMap::const_iterator iter = resultMap.constBegin(); + for(; iter != resultMap.constEnd(); iter++) + { + ui->m_operator->addItem(iter.value(), iter.key()); + ui->m_guard->addItem(iter.value(), iter.key()); + ui->m_duty->addItem(iter.value(), iter.key()); + } +} + +void COperationOrderForm::closeEvent(QCloseEvent *event) +{ + QDialog::closeEvent(event); +} + +void COperationOrderForm::slot_addOneOperate() +{ + int curRow = ui->m_table->currentRow(); + if(curRow < 0) + { + curRow = 0; + } + ui->m_table->insertRow(curRow); + + for(int col = 1;colm_table->columnCount();++col) + { + QTableWidgetItem *colItem = new QTableWidgetItem(""); + ui->m_table->setItem(curRow,col,colItem); + ui->m_table->item(curRow,col)->setTextAlignment(Qt::AlignCenter); + } + + int rowCount = ui->m_table->rowCount(); + for(int i=curRow; im_table->setItem(i,0,ui->m_table->takeItem(i+1,0)); + } + QTableWidgetItem *item = new QTableWidgetItem(); + item->setText(QString::number(rowCount)); + ui->m_table->setItem(rowCount-1,0,item); + ui->m_table->item(rowCount-1,0)->setTextAlignment(Qt::AlignCenter); +} + +void COperationOrderForm::slot_deleteOneOperate() +{ + int curRow = ui->m_table->currentRow(); + if(curRow < 0) + { + return; + } + ui->m_table->removeRow(curRow); + m_changedList.append(curRow); + + int rowCount = ui->m_table->rowCount(); + for(int i=curRow; isetText(QString::number(i+1)); + ui->m_table->setItem(i,0,item); + ui->m_table->item(i,0)->setTextAlignment(Qt::AlignCenter); + } + + if(curRow+1 > rowCount) + { + ui->m_table->selectRow(rowCount-1); + } + else + ui->m_table->selectRow(curRow); + +} + +void COperationOrderForm::slot_upOneOperate() +{ + int curRow = ui->m_table->currentRow(); + if(curRow <= 0) + { + return; + } + int insertRow = curRow - 1; + + ui->m_table->insertRow(insertRow); + for(int i=0;im_table->columnCount();++i) + { + if(i==0) + { + ui->m_table->setItem(insertRow,0,ui->m_table->takeItem(curRow,0)); + ui->m_table->setItem(curRow,0,ui->m_table->takeItem(curRow+1,0)); + } + else + ui->m_table->setItem(insertRow,i,ui->m_table->takeItem(curRow+1,i)); + } + ui->m_table->removeRow(curRow+1); + + if(m_changedList.indexOf(curRow) != -1 + || m_changedList.indexOf(insertRow) != -1) + { + on_m_table_cellChanged(curRow,0); + on_m_table_cellChanged(insertRow,0); + } + ui->m_table->selectRow(insertRow); + + +} + +void COperationOrderForm::slot_downOneOperate() +{ + int curRow = ui->m_table->currentRow(); + int row = ui->m_table->rowCount(); + if(curRow == -1) + { + return; + } + if(curRow+1 >= row) + { + return; + } + int insertRow = curRow + 2; + + ui->m_table->insertRow(insertRow); + for(int i=0;im_table->columnCount();++i) + { + if(i==0) + { + ui->m_table->setItem(insertRow,0,ui->m_table->takeItem(curRow+1,0)); + ui->m_table->setItem(curRow+1,0,ui->m_table->takeItem(curRow,0)); + } + else + ui->m_table->setItem(insertRow,i,ui->m_table->takeItem(curRow,i)); + } + ui->m_table->removeRow(curRow); + + if(m_changedList.indexOf(curRow) != -1 + || m_changedList.indexOf(insertRow-1) != -1) + { + on_m_table_cellChanged(curRow,0); + on_m_table_cellChanged(insertRow-1,0); + } + ui->m_table->selectRow(insertRow-1); +} + +int COperationOrderForm::slot_saveModel() +{ + if(omPermCheck() == false) + { + return -1; + } + + ui->m_table->setCurrentCell(-1,-1); + if(!checkTableData()) + { + return -1; + } + + //if (!checkOrderModel()) + { + // return -1; + } + + if(!updateDbModelData()) + { + return -1; + } + + + resetViewData(); + + return 0; +} + +bool COperationOrderForm::checkTableData() +{ + for(int row=0;rowm_table->rowCount();++row) + { + if(ui->m_table->item(row,0) == NULL) + { + QMessageBox::warning(this, tr("提示"), tr("行:%1 顺序为空!").arg(row+1), QMessageBox::Ok); + return false; + } + + for(int n=row+1;nm_table->rowCount();++n) + { + if(ui->m_table->item(row,0)->text() == ui->m_table->item(n,0)->text()) + { + QMessageBox::warning(this, tr("提示"), tr("行:%1 与行:%2 顺序重复!").arg(row+1).arg(n+1), QMessageBox::Ok); + return false; + } + } + + if(ui->m_table->item(row,1) == NULL) + { + QMessageBox::warning(this, tr("提示"), tr("行:%1 操作内容为空!").arg(row+1), QMessageBox::Ok); + return false; + } + } + return true; +} + +bool COperationOrderForm::checkOrderModel() +{ + CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); + bool re = true; + if(ui->m_editName->text() != m_sOrderInfo.orderName) + { + QList orderName; + + dbCtrl.readOrderName(orderName); + if(orderName.indexOf(ui->m_editName->text()) != -1) + { + QMessageBox::warning(this, tr("提示"), tr("典型票名已存在!"), QMessageBox::Ok); + return false; + } + + bool re = dbCtrl.updateOneOrderData(ui->m_editName->text(),m_sOrderInfo.id); + if(!re) + { + QMessageBox::warning(this, tr("提示"), tr("典型票名: '%1' 保存失败!").arg(ui->m_editName->text()), QMessageBox::Ok); + return false; + } + else + { + m_sOrderInfo.orderName = ui->m_editName->text(); + } + } + + if(ui->m_editDesc->text() != m_sOrderInfo.orderDesc + || ui->m_editRemarks->toPlainText() != m_sOrderInfo.remarks) + { + re = dbCtrl.updateOneOrderData(ui->m_editDesc->text(), + ui->m_editRemarks->toPlainText(), + m_sOrderInfo.id); + if(!re) + { + QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return false; + } + else + { + m_sOrderInfo.orderDesc = ui->m_editDesc->text(); + m_sOrderInfo.remarks = ui->m_editRemarks->toPlainText(); + } + } + return re; +} + +bool COperationOrderForm::updateDbModelData() +{ + CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); + + bool ret = true; + QString orderName = ui->m_editName->text(); + int order_id = dbCtrl.getOrderId(orderName); + if (order_id != -1) + { + int ret = QMessageBox::information(this, tr("提示"), tr("已经存在“%1”,是否覆盖?").arg(orderName), + QMessageBox::Cancel | QMessageBox::Ok, QMessageBox::Cancel); + + if (ret == QMessageBox::Cancel) + { + return false; + } + + ret = dbCtrl.deleteOneOrderData(orderName); + if (ret == false) + { + QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return ret; + } + + ret = dbCtrl.deleteAllOrderInfoData(order_id); + if (ret == false) + { + QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return ret; + } + } + + order_id = dbCtrl.readOrderDataMaxId(); + if (order_id == -1) + { + QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return false; + } + + SOrderPreStore order; + order.id = order_id; + order.orderDesc = ui->m_editDesc->text(); + order.orderName = orderName; + order.remarks = ui->m_editRemarks->toPlainText(); + + ret = dbCtrl.insertOneOrderData(order); + if (ret == false) + { + QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return ret; + } + + ret = dbCtrl.deleteAllOrderInfoData(order_id); + if (ret == false) + { + QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return ret; + } + + for (int row = 0; row < ui->m_table->rowCount(); ++row) + { + int seq = ui->m_table->item(row, 0)->text().toInt(); + + SOrderPreStoreInfo info = getOrderInfo(row, order_id); + ret = dbCtrl.insertOneOrderInfoData(info); + if (ret == false) + { + QMessageBox::warning(this, tr("提示"), tr("行:%1 保存失败!").arg(row + 1), QMessageBox::Ok); + return ret; + } + continue; + } + + QMessageBox::warning(this, tr("提示"), tr("保存成功!"), QMessageBox::Ok); + return ret; +} + +void COperationOrderForm::slot_print() +{ + if(omPermCheck() == false) + { + return; + } + + if(!checkBeforePrint()) + { + return; + } + + saveToHis(); + + printInit(); + + int ret = m_ptrPrinter->print(ui->m_table); + if(ret == 1) + { + QMessageBox::warning(this, tr("提示"), tr("打印成功!"), QMessageBox::Ok); + } + else if(ret == -1) + { + QMessageBox::warning(this, tr("提示"), tr("打印失败!"), QMessageBox::Ok); + } +} + +bool COperationOrderForm::saveToHis() +{ + CSqlDbCtrl dbCtrl; + int hisMaxNum = dbCtrl.readOrderHisMixID(); + + if(hisMaxNum == -1) + { + QMessageBox::warning(this, tr("提示"), tr("打开历史表失败!"), QMessageBox::Ok); + return false; + } + + if(insertHisTable(hisMaxNum) == false) + { + QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return false; + } + + for(int i=0; im_table->rowCount(); ++i) + { + if(insertHisInfoTable(hisMaxNum,i) == false) + { + QMessageBox::warning(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); + return false; + } + } + + return true; +} + +void COperationOrderForm::printInit() +{ + m_ptrPrinter->initPrintEnv(); + m_ptrPrinter->setPrintCaption(ui->m_editName->text()); + + QString no = tr("操作票号: ") + ui->m_editOrderId->text(); + + int columnCount = 0; + for(int nIndex(0); nIndex < ui->m_table->columnCount(); nIndex++) + { + if(!ui->m_table->isColumnHidden(nIndex)) + { + columnCount += 1; + } + } + m_ptrPrinter->setPrintParagraph(no, columnCount); + + QString startTime = tr("操作开始时间: ") + ui->m_editStartTime->text(); + m_ptrPrinter->setPrintParagraph(startTime, columnCount, false, true); + + QString endTime = tr("操作结束时间: ") + ui->m_editEndTime->text(); + m_ptrPrinter->setPrintParagraph(endTime, columnCount, false, true); + + QString paragraph = tr("操作任务: ") + ui->m_editDesc->text(); + m_ptrPrinter->setPrintParagraph(paragraph, columnCount, false, true); + + QString markText = ui->m_editRemarks->toPlainText(); + markText = markText.replace("/\n/g", "
"); + QString mark = tr("备注:
") + markText; + m_ptrPrinter->setPrintParagraph(mark, columnCount, true, true); + + CSqlDbCtrl dbCtrl; + + QPair operatr; + operatr.first = tr("操作人:"); + operatr.second = ui->m_operator->currentText(); + if(ui->m_sign->isChecked()) + { + m_ptrPrinter->setPrintWithBack(operatr, 1, dbCtrl.readSignatureData(ui->m_operator->currentData().toInt())); + } + else + { + m_ptrPrinter->setPrintWithBack(operatr, 1, QString()); + } + + QPair guard; + guard.first = tr("监护人:"); + guard.second = ui->m_guard->currentText(); + if(ui->m_sign->isChecked()) + { + m_ptrPrinter->setPrintWithBack(guard, 1, dbCtrl.readSignatureData(ui->m_guard->currentData().toInt())); + } + else + { + m_ptrPrinter->setPrintWithBack(guard, 1, QString()); + } + + QPair duty; + duty.first = tr("值班负责人:"); + duty.second = ui->m_duty->currentText(); + if(ui->m_sign->isChecked()) + { + m_ptrPrinter->setPrintWithBack(duty, 1, dbCtrl.readSignatureData(ui->m_duty->currentData().toInt())); + } + else + { + m_ptrPrinter->setPrintWithBack(duty, 1, QString()); + } +} + +bool COperationOrderForm::isViewDataChange() +{ + if (m_sOrderInfo.begin_time != 0) + { + qint64 time = ui->m_editStartTime->dateTime().toTime_t(); + if (m_sOrderInfo.begin_time/1000 != time) + { + return true; + } + } + + if (m_sOrderInfo.end_time != 0) + { + qint64 time = ui->m_editEndTime->dateTime().toTime_t(); + if (m_sOrderInfo.end_time / 1000 != time) + { + return true; + } + } + + if (!m_sOrderInfo.OPERATOR.isEmpty()) + { + QString str = ui->m_operator->currentText(); + if (m_sOrderInfo.OPERATOR != str) + { + return true; + } + } + + if (!m_sOrderInfo.guardian.isEmpty()) + { + QString str = ui->m_guard->currentText(); + if (m_sOrderInfo.guardian != str) + { + return true; + } + } + + if (!m_sOrderInfo.duty_manager.isEmpty()) + { + QString str = ui->m_duty->currentText(); + if (m_sOrderInfo.duty_manager != str) + { + return true; + } + } + + if (ui->m_editName->text() != m_sOrderInfo.orderName + || ui->m_editDesc->text() != m_sOrderInfo.orderDesc + || ui->m_editRemarks->toPlainText() != m_sOrderInfo.remarks + || m_changedList.length() != 0) + { + return true; + } + + return false; +} + +void COperationOrderForm::resetViewData() +{ + qint64 time = ui->m_editStartTime->dateTime().toTime_t(); + m_sOrderInfo.begin_time = time * 1000; + time = ui->m_editEndTime->dateTime().toTime_t(); + m_sOrderInfo.end_time = time * 1000; + m_sOrderInfo.duty_manager = ui->m_duty->currentText(); + m_sOrderInfo.guardian = ui->m_guard->currentText(); + m_sOrderInfo.id = ui->m_editOrderId->text().toInt(); + m_sOrderInfo.OPERATOR = ui->m_operator->currentText(); + m_sOrderInfo.orderDesc = ui->m_editDesc->text(); + m_sOrderInfo.orderName = ui->m_editName->text(); + m_sOrderInfo.remarks = ui->m_editRemarks->toPlainText(); + m_changedList.clear(); +} + +bool COperationOrderForm::insertHisTable(int num) +{ + CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); + SOrderHis his; + + his.id = num; + his.order_no = ui->m_editOrderId->text(); + his.order_name = ui->m_editName->text(); + his.order_desc = ui->m_editDesc->text(); + his.begin_time = ui->m_editStartTime->dateTime().toMSecsSinceEpoch(); + his.end_time = ui->m_editEndTime->dateTime().toMSecsSinceEpoch(); + his.remarks = ui->m_editRemarks->toPlainText(); + his.OPERATOR = ui->m_operator->currentText(); + his.guardian = ui->m_guard->currentText(); + his.duty_manager = ui->m_duty->currentText(); + his.exec_state = -1; + + return dbCtrl.insertOneOrderHisData(his); +} + +bool COperationOrderForm::insertHisInfoTable(int num, int row) +{ + CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); + SOrderHisInfo hisInfo; + + hisInfo.order_id = num; + hisInfo.seq_no = ui->m_table->item(row,0)->text().toInt(); + hisInfo.opt_desc = ui->m_table->item(row,1)->text(); + hisInfo.key_id_tag = ui->m_table->item(row,3)->text(); + hisInfo.ctrl_value = ui->m_table->item(row,4)->text().toInt(); + hisInfo.remarks = ui->m_table->item(row,2)->text(); + hisInfo.exec_state = -1; + + return dbCtrl.insertOneOrderHisInfoData(hisInfo); +} + +void COperationOrderForm::slot_preview() +{ + if(omPermCheck() == false) + { + return; + } + + if(!checkBeforePrint()) + { + return; + } + + printInit(); + + m_ptrPrinter->preview(ui->m_table); +} + +bool COperationOrderForm::checkBeforePrint() +{ + if(ui->m_editName->text().isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("典型票名为空!"), QMessageBox::Ok); + return false; + } + + if(ui->m_editOrderId->text().isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("操作票号为空!"), QMessageBox::Ok); + return false; + } + + if(ui->m_operator->currentText().isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("操作人为空!"), QMessageBox::Ok); + return false; + } + + if(ui->m_guard->currentText().isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("监护人为空!"), QMessageBox::Ok); + return false; + } + + if(ui->m_duty->currentText().isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("值班负责人为空!"), QMessageBox::Ok); + return false; + } + + return true; +} + +SOrderPreStoreInfo COperationOrderForm::getOrderInfo(int row, int orderId) +{ + SOrderPreStoreInfo info; + + info.orderId = orderId; + info.seqNo = ui->m_table->item(row,0)->text().toInt(); + info.optDesc = ui->m_table->item(row,1)->text(); + + if(ui->m_table->item(row,3) == NULL) + { + info.keyIdTag = ""; + } + else + { + info.keyIdTag = ui->m_table->item(row,3)->text(); + } + + if(ui->m_table->item(row,4) == NULL) + { + info.ctrlValue = -1; + } + else + { + info.ctrlValue = ui->m_table->item(row,4)->text().toInt(); + } + + if(ui->m_table->item(row,2) == NULL) + { + info.remarks = ""; + } + else + { + info.remarks = ui->m_table->item(row,2)->text(); + } + + return info; +} + +void COperationOrderForm::on_m_table_cellChanged(int row, int column) +{ + Q_UNUSED(column) + if(m_changedList.indexOf(row) == -1) + { + m_changedList.append(row); + } +} + +bool COperationOrderForm::omPermCheck() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string tmpStr = "FUNC_NOM_OM"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限!"), QMessageBox::Ok); + return false; + } + return true; +} diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.h b/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.h index 5e1d850d..badbcf1c 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.h +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.h @@ -1,88 +1,88 @@ -#ifndef COPERATIONORDERFORM_H -#define COPERATIONORDERFORM_H - -#include -#include -#include -#include -#include -#include -#include -#include "SDbTableDefine.h" -#include "CSqlDbCtrl.h" -#include "COrderPrinter.h" - -namespace Ui { -class COperationOrderForm; -} - - -class COperationOrderForm : public QDialog -{ - Q_OBJECT - -public: - explicit COperationOrderForm(QWidget *parent); - ~COperationOrderForm(); - - void initViewData(); - -protected: - virtual void closeEvent(QCloseEvent *event); - -protected slots: - void slot_addOneOperate(); - void slot_deleteOneOperate(); - void slot_upOneOperate(); - void slot_downOneOperate(); - int slot_saveModel(); - void slot_print(); - void slot_preview(); - void on_m_table_cellChanged(int row, int column); - -protected: - void initTableView(); - virtual void readOrderInfoData() = 0; - void insertTableData(const SOrderPreStoreInfo& vect); - void initUserComb(); - bool updateDbModelData(); - SOrderPreStoreInfo getOrderInfo(int row,int orderId); - bool checkTableData(); - bool checkOrderModel(); - bool checkBeforePrint(); - - bool insertHisTable(int num); - bool insertHisInfoTable(int num, int row); - bool saveToHis(); - - void printInit(); - - bool isViewDataChange(); - - void resetViewData(); - bool omPermCheck(); - - virtual bool isHisForm() { return false; }; - -protected: - Ui::COperationOrderForm *ui; - COrderPrinter *m_ptrPrinter; - - QList m_changedList; - - QLineEdit* m_editOrderId; - QLineEdit* m_editName; - QTableWidget* m_table; - QLineEdit* m_editDesc; - QTextEdit* m_editRemarks; - QDateTimeEdit* m_editStartTime; - QDateTimeEdit* m_editEndTime; - QComboBox* m_operator; - QComboBox* m_guard; - QComboBox* m_duty; - - SOrderViewInfo m_sOrderInfo; - -}; - -#endif // COPERATIONORDERFORM_H +#ifndef COPERATIONORDERFORM_H +#define COPERATIONORDERFORM_H + +#include +#include +#include +#include +#include +#include +#include +#include "SDbTableDefine.h" +#include "CSqlDbCtrl.h" +#include "COrderPrinter.h" + +namespace Ui { +class COperationOrderForm; +} + + +class COperationOrderForm : public QDialog +{ + Q_OBJECT + +public: + explicit COperationOrderForm(QWidget *parent); + ~COperationOrderForm(); + + void initViewData(); + +protected: + virtual void closeEvent(QCloseEvent *event); + +protected slots: + void slot_addOneOperate(); + void slot_deleteOneOperate(); + void slot_upOneOperate(); + void slot_downOneOperate(); + int slot_saveModel(); + void slot_print(); + void slot_preview(); + void on_m_table_cellChanged(int row, int column); + +protected: + void initTableView(); + virtual void readOrderInfoData() = 0; + void insertTableData(const SOrderPreStoreInfo& vect); + void initUserComb(); + bool updateDbModelData(); + SOrderPreStoreInfo getOrderInfo(int row,int orderId); + bool checkTableData(); + bool checkOrderModel(); + bool checkBeforePrint(); + + bool insertHisTable(int num); + bool insertHisInfoTable(int num, int row); + bool saveToHis(); + + void printInit(); + + bool isViewDataChange(); + + void resetViewData(); + bool omPermCheck(); + + virtual bool isHisForm() { return false; }; + +protected: + Ui::COperationOrderForm *ui; + COrderPrinter *m_ptrPrinter; + + QList m_changedList; + + QLineEdit* m_editOrderId; + QLineEdit* m_editName; + QTableWidget* m_table; + QLineEdit* m_editDesc; + QTextEdit* m_editRemarks; + QDateTimeEdit* m_editStartTime; + QDateTimeEdit* m_editEndTime; + QComboBox* m_operator; + QComboBox* m_guard; + QComboBox* m_duty; + + SOrderViewInfo m_sOrderInfo; + +}; + +#endif // COPERATIONORDERFORM_H diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.ui b/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.ui index 10f8cf85..005f23cf 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.ui +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.ui @@ -1,376 +1,376 @@ - - - COperationOrderForm - - - - 0 - 0 - 819 - 460 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 15 - - - - - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 60 - 16777215 - - - - 增加 - - - - - - - - 60 - 16777215 - - - - 删除 - - - - - - - - 60 - 16777215 - - - - 上移 - - - - - - - - 60 - 16777215 - - - - 下移 - - - - - - - - 60 - 16777215 - - - - 保存模板 - - - - - - - - 60 - 16777215 - - - - 开票打印 - - - - - - - - 60 - 16777215 - - - - 预览 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - 备注 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 686 - 17 - - - - - - - - 操作任务 - - - - - - - 操作人 - - - - - - - - - - - - 监护人 - - - - - - - - - - 值班负责人 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 电子签章 - - - - - - - - - yyyy/MM/dd HH:mm:ss - - - - - - - 结束时间 - - - - - - - yyyy/MM/dd HH:mm:ss - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 操作票号 - - - - - - - - - - - - 开始时间 - - - - - - - 签章 - - - - - - - - + + + COperationOrderForm + + + + 0 + 0 + 819 + 460 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 15 + + + + + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 60 + 16777215 + + + + 增加 + + + + + + + + 60 + 16777215 + + + + 删除 + + + + + + + + 60 + 16777215 + + + + 上移 + + + + + + + + 60 + 16777215 + + + + 下移 + + + + + + + + 60 + 16777215 + + + + 保存模板 + + + + + + + + 60 + 16777215 + + + + 开票打印 + + + + + + + + 60 + 16777215 + + + + 预览 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 备注 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 686 + 17 + + + + + + + + 操作任务 + + + + + + + 操作人 + + + + + + + + + + + + 监护人 + + + + + + + + + + 值班负责人 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 电子签章 + + + + + + + + + yyyy/MM/dd HH:mm:ss + + + + + + + 结束时间 + + + + + + + yyyy/MM/dd HH:mm:ss + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 操作票号 + + + + + + + + + + + + 开始时间 + + + + + + + 签章 + + + + + + + + diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderHisForm.cpp b/product/src/gui/plugin/OrderManageWidget/COperationOrderHisForm.cpp index 6908865c..447d8ce2 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderHisForm.cpp +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderHisForm.cpp @@ -1,102 +1,102 @@ -#include "COperationOrderHisForm.h" -#include - -COperationOrderHisForm::COperationOrderHisForm(QWidget *parent): - COperationOrderForm(parent) -{ - -} - -COperationOrderHisForm::~COperationOrderHisForm() -{ - -} - -void COperationOrderHisForm::showHisView(const SOrderHis& info) -{ - m_sOrderInfo.id = info.id; - m_sOrderInfo.order_no = info.order_no; - m_sOrderInfo.orderDesc = info.order_desc; - m_sOrderInfo.remarks = info.remarks; - m_sOrderInfo.orderName = info.order_name; - m_sOrderInfo.begin_time = info.begin_time; - m_sOrderInfo.end_time = info.end_time; - m_sOrderInfo.OPERATOR = info.OPERATOR; - m_sOrderInfo.guardian = info.guardian; - m_sOrderInfo.duty_manager = info.duty_manager; -} - -bool COperationOrderHisForm::isHisForm() -{ - return true; -} - -void COperationOrderHisForm::closeEvent(QCloseEvent *event) -{ - COperationOrderForm::closeEvent(event); -} - -void COperationOrderHisForm::readOrderInfoData() -{ - QVector objs; - CSqlDbCtrl dbCtrl; - if (!dbCtrl.readOptOrderHisInfo(m_sOrderInfo.id, objs)) - { - return; - } - - showHisData(objs); -} - -void COperationOrderHisForm::showHisData(const QVector& objs) -{ - m_table->setRowCount(0); - m_table->clearContents(); - - m_editOrderId->setText(m_sOrderInfo.order_no); - m_editName->setText(m_sOrderInfo.orderName); - m_editDesc->setText(m_sOrderInfo.orderDesc); - m_editRemarks->setText(m_sOrderInfo.remarks); - m_editStartTime->setDateTime(QDateTime::fromTime_t(m_sOrderInfo.begin_time / 1000)); - m_editEndTime->setDateTime(QDateTime::fromTime_t(m_sOrderInfo.end_time / 1000)); - m_operator->setCurrentText(m_sOrderInfo.OPERATOR); - m_guard->setCurrentText(m_sOrderInfo.guardian); - m_duty->setCurrentText(m_sOrderInfo.duty_manager); - - QVector::const_iterator iter = objs.begin(); - for (; iter != objs.end(); ++iter) - { - const SOrderHisInfo& obj = *iter; - - m_table->blockSignals(true); - int curRow = m_table->rowCount(); - m_table->insertRow(curRow); - - int seqNo = obj.seq_no; - QString desc = obj.opt_desc; - QString remarks = obj.remarks; - QString keyIdTag = obj.key_id_tag; - int ctrlValue = obj.ctrl_value; - - QTableWidgetItem *seqNoi = new QTableWidgetItem(); - seqNoi->setText(QString::number(seqNo)); - QTableWidgetItem *desci = new QTableWidgetItem(); - desci->setText(desc); - QTableWidgetItem *remarksi = new QTableWidgetItem(); - remarksi->setText(remarks); - QTableWidgetItem *keyIdTagi = new QTableWidgetItem(); - keyIdTagi->setText(keyIdTag); - QTableWidgetItem *ctrlValuei = new QTableWidgetItem(); - ctrlValuei->setText(QString::number(ctrlValue)); - - m_table->setItem(curRow, 0, seqNoi); - m_table->item(curRow, 0)->setTextAlignment(Qt::AlignCenter); - m_table->setItem(curRow, 1, desci); - m_table->item(curRow, 1)->setTextAlignment(Qt::AlignCenter); - m_table->setItem(curRow, 2, remarksi); - m_table->item(curRow, 2)->setTextAlignment(Qt::AlignCenter); - m_table->setItem(curRow, 3, keyIdTagi); - m_table->setItem(curRow, 4, ctrlValuei); - m_table->blockSignals(false); - } -} +#include "COperationOrderHisForm.h" +#include + +COperationOrderHisForm::COperationOrderHisForm(QWidget *parent): + COperationOrderForm(parent) +{ + +} + +COperationOrderHisForm::~COperationOrderHisForm() +{ + +} + +void COperationOrderHisForm::showHisView(const SOrderHis& info) +{ + m_sOrderInfo.id = info.id; + m_sOrderInfo.order_no = info.order_no; + m_sOrderInfo.orderDesc = info.order_desc; + m_sOrderInfo.remarks = info.remarks; + m_sOrderInfo.orderName = info.order_name; + m_sOrderInfo.begin_time = info.begin_time; + m_sOrderInfo.end_time = info.end_time; + m_sOrderInfo.OPERATOR = info.OPERATOR; + m_sOrderInfo.guardian = info.guardian; + m_sOrderInfo.duty_manager = info.duty_manager; +} + +bool COperationOrderHisForm::isHisForm() +{ + return true; +} + +void COperationOrderHisForm::closeEvent(QCloseEvent *event) +{ + COperationOrderForm::closeEvent(event); +} + +void COperationOrderHisForm::readOrderInfoData() +{ + QVector objs; + CSqlDbCtrl dbCtrl; + if (!dbCtrl.readOptOrderHisInfo(m_sOrderInfo.id, objs)) + { + return; + } + + showHisData(objs); +} + +void COperationOrderHisForm::showHisData(const QVector& objs) +{ + m_table->setRowCount(0); + m_table->clearContents(); + + m_editOrderId->setText(m_sOrderInfo.order_no); + m_editName->setText(m_sOrderInfo.orderName); + m_editDesc->setText(m_sOrderInfo.orderDesc); + m_editRemarks->setText(m_sOrderInfo.remarks); + m_editStartTime->setDateTime(QDateTime::fromTime_t(m_sOrderInfo.begin_time / 1000)); + m_editEndTime->setDateTime(QDateTime::fromTime_t(m_sOrderInfo.end_time / 1000)); + m_operator->setCurrentText(m_sOrderInfo.OPERATOR); + m_guard->setCurrentText(m_sOrderInfo.guardian); + m_duty->setCurrentText(m_sOrderInfo.duty_manager); + + QVector::const_iterator iter = objs.begin(); + for (; iter != objs.end(); ++iter) + { + const SOrderHisInfo& obj = *iter; + + m_table->blockSignals(true); + int curRow = m_table->rowCount(); + m_table->insertRow(curRow); + + int seqNo = obj.seq_no; + QString desc = obj.opt_desc; + QString remarks = obj.remarks; + QString keyIdTag = obj.key_id_tag; + int ctrlValue = obj.ctrl_value; + + QTableWidgetItem *seqNoi = new QTableWidgetItem(); + seqNoi->setText(QString::number(seqNo)); + QTableWidgetItem *desci = new QTableWidgetItem(); + desci->setText(desc); + QTableWidgetItem *remarksi = new QTableWidgetItem(); + remarksi->setText(remarks); + QTableWidgetItem *keyIdTagi = new QTableWidgetItem(); + keyIdTagi->setText(keyIdTag); + QTableWidgetItem *ctrlValuei = new QTableWidgetItem(); + ctrlValuei->setText(QString::number(ctrlValue)); + + m_table->setItem(curRow, 0, seqNoi); + m_table->item(curRow, 0)->setTextAlignment(Qt::AlignCenter); + m_table->setItem(curRow, 1, desci); + m_table->item(curRow, 1)->setTextAlignment(Qt::AlignCenter); + m_table->setItem(curRow, 2, remarksi); + m_table->item(curRow, 2)->setTextAlignment(Qt::AlignCenter); + m_table->setItem(curRow, 3, keyIdTagi); + m_table->setItem(curRow, 4, ctrlValuei); + m_table->blockSignals(false); + } +} diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderHisForm.h b/product/src/gui/plugin/OrderManageWidget/COperationOrderHisForm.h index e8bdc8a6..b1f82856 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderHisForm.h +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderHisForm.h @@ -1,28 +1,28 @@ -#ifndef COPERATIONORDERHISFORM_H -#define COPERATIONORDERHISFORM_H -#include "COperationOrderForm.h" -#include "CSqlDbCtrl.h" - -class COperationOrderHisForm : public COperationOrderForm -{ - Q_OBJECT -public: - COperationOrderHisForm(QWidget *parent); - ~COperationOrderHisForm(); - - void showHisView(const SOrderHis& obj); - - virtual bool isHisForm(); -protected: - virtual void closeEvent(QCloseEvent *event); -private: - virtual void readOrderInfoData(); - - void showHisData(const QVector& objs); - -}; - - - - -#endif // COPERATIONORDERHISFORM_H +#ifndef COPERATIONORDERHISFORM_H +#define COPERATIONORDERHISFORM_H +#include "COperationOrderForm.h" +#include "CSqlDbCtrl.h" + +class COperationOrderHisForm : public COperationOrderForm +{ + Q_OBJECT +public: + COperationOrderHisForm(QWidget *parent); + ~COperationOrderHisForm(); + + void showHisView(const SOrderHis& obj); + + virtual bool isHisForm(); +protected: + virtual void closeEvent(QCloseEvent *event); +private: + virtual void readOrderInfoData(); + + void showHisData(const QVector& objs); + +}; + + + + +#endif // COPERATIONORDERHISFORM_H diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderModelForm.cpp b/product/src/gui/plugin/OrderManageWidget/COperationOrderModelForm.cpp index f6064381..ce09cde7 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderModelForm.cpp +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderModelForm.cpp @@ -1,75 +1,75 @@ -#include "COperationOrderModelForm.h" -#include -#include - -COperationOrderModelForm::COperationOrderModelForm(QWidget *parent): - COperationOrderForm(parent) -{ - -} - -COperationOrderModelForm::~COperationOrderModelForm() -{ - -} - -void COperationOrderModelForm::showView(const SOrderPreStore &info) -{ - CSqlDbCtrl dbCtrl; - m_sOrderInfo.id = info.id; - m_sOrderInfo.order_no = QString::number( dbCtrl.readOrderHisMixID()); - m_sOrderInfo.orderName = info.orderName; - m_sOrderInfo.orderDesc = info.orderDesc; - m_sOrderInfo.remarks = info.remarks; - m_sOrderInfo.begin_time = 0; - m_sOrderInfo.end_time = 0; - m_sOrderInfo.OPERATOR = ""; - m_sOrderInfo.guardian = ""; - m_sOrderInfo.duty_manager = ""; - -} - -void COperationOrderModelForm::closeEvent(QCloseEvent *event) -{ - bool isViewChange = isViewDataChange(); - if (isViewChange) - { - int ret = QMessageBox::information(this, tr("提示"), tr("是否保存模板更改?"), QMessageBox::Cancel | QMessageBox::Ok, QMessageBox::Cancel); - - if (ret == QMessageBox::Cancel) - { - event->accept(); - return; - } - else if (ret == QMessageBox::Ok) - { - event->ignore(); - slot_saveModel(); - return; - } - } - event->accept(); - - COperationOrderForm::closeEvent(event); -} - -void COperationOrderModelForm::readOrderInfoData() -{ - CSqlDbCtrl dbCtrl; - m_vecOrderInfo.clear(); - - m_vecOrderInfo = dbCtrl.readOrderInfoById(m_sOrderInfo.id); - - m_table->setRowCount(0); - m_table->clearContents(); - m_editOrderId->setText(m_sOrderInfo.order_no); - m_editName->setText(m_sOrderInfo.orderName); - m_editRemarks->setText(""); - m_editDesc->setText(m_sOrderInfo.orderDesc); - - QVector::iterator iter = m_vecOrderInfo.begin(); - for (; iter != m_vecOrderInfo.end(); ++iter) - { - insertTableData(*iter); - } -} +#include "COperationOrderModelForm.h" +#include +#include + +COperationOrderModelForm::COperationOrderModelForm(QWidget *parent): + COperationOrderForm(parent) +{ + +} + +COperationOrderModelForm::~COperationOrderModelForm() +{ + +} + +void COperationOrderModelForm::showView(const SOrderPreStore &info) +{ + CSqlDbCtrl dbCtrl; + m_sOrderInfo.id = info.id; + m_sOrderInfo.order_no = QString::number( dbCtrl.readOrderHisMixID()); + m_sOrderInfo.orderName = info.orderName; + m_sOrderInfo.orderDesc = info.orderDesc; + m_sOrderInfo.remarks = info.remarks; + m_sOrderInfo.begin_time = 0; + m_sOrderInfo.end_time = 0; + m_sOrderInfo.OPERATOR = ""; + m_sOrderInfo.guardian = ""; + m_sOrderInfo.duty_manager = ""; + +} + +void COperationOrderModelForm::closeEvent(QCloseEvent *event) +{ + bool isViewChange = isViewDataChange(); + if (isViewChange) + { + int ret = QMessageBox::information(this, tr("提示"), tr("是否保存模板更改?"), QMessageBox::Cancel | QMessageBox::Ok, QMessageBox::Cancel); + + if (ret == QMessageBox::Cancel) + { + event->accept(); + return; + } + else if (ret == QMessageBox::Ok) + { + event->ignore(); + slot_saveModel(); + return; + } + } + event->accept(); + + COperationOrderForm::closeEvent(event); +} + +void COperationOrderModelForm::readOrderInfoData() +{ + CSqlDbCtrl dbCtrl; + m_vecOrderInfo.clear(); + + m_vecOrderInfo = dbCtrl.readOrderInfoById(m_sOrderInfo.id); + + m_table->setRowCount(0); + m_table->clearContents(); + m_editOrderId->setText(m_sOrderInfo.order_no); + m_editName->setText(m_sOrderInfo.orderName); + m_editRemarks->setText(""); + m_editDesc->setText(m_sOrderInfo.orderDesc); + + QVector::iterator iter = m_vecOrderInfo.begin(); + for (; iter != m_vecOrderInfo.end(); ++iter) + { + insertTableData(*iter); + } +} diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderModelForm.h b/product/src/gui/plugin/OrderManageWidget/COperationOrderModelForm.h index 9dcaa1bd..7033b50f 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderModelForm.h +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderModelForm.h @@ -1,25 +1,25 @@ -#ifndef COPERATIONORDERMODELFORM_H -#define COPERATIONORDERMODELFORM_H -#include "COperationOrderForm.h" -#include "CSqlDbCtrl.h" - -class COperationOrderModelForm : public COperationOrderForm -{ - Q_OBJECT -public: - COperationOrderModelForm(QWidget *parent); - ~COperationOrderModelForm(); - - void showView(const SOrderPreStore &info); -protected: - virtual void closeEvent(QCloseEvent *event); -private: - virtual void readOrderInfoData(); - -private: - QVector m_vecOrderInfo; - - -}; - -#endif // COPERATIONORDERMODELFORM_H +#ifndef COPERATIONORDERMODELFORM_H +#define COPERATIONORDERMODELFORM_H +#include "COperationOrderForm.h" +#include "CSqlDbCtrl.h" + +class COperationOrderModelForm : public COperationOrderForm +{ + Q_OBJECT +public: + COperationOrderModelForm(QWidget *parent); + ~COperationOrderModelForm(); + + void showView(const SOrderPreStore &info); +protected: + virtual void closeEvent(QCloseEvent *event); +private: + virtual void readOrderInfoData(); + +private: + QVector m_vecOrderInfo; + + +}; + +#endif // COPERATIONORDERMODELFORM_H diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.cpp b/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.cpp index 5c3b69ba..61163e83 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.cpp +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.cpp @@ -1,28 +1,28 @@ -#include -#include "COperationOrderPluginWidget.h" -#include "COrderManageWidget.h" -#include "Mainwindow.h" - -COperationOrderPluginWidget::COperationOrderPluginWidget(QObject *parent): QObject(parent) -{ - -} - -COperationOrderPluginWidget::~COperationOrderPluginWidget() -{ - -} - -bool COperationOrderPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - Mainwindow *pWidget = new Mainwindow(parent,editMode); - *widget = (QWidget *)pWidget; - *reportWidget = (IPluginWidget *)pWidget; - return true; -} - -void COperationOrderPluginWidget::release() -{ - -} +#include +#include "COperationOrderPluginWidget.h" +#include "COrderManageWidget.h" +#include "Mainwindow.h" + +COperationOrderPluginWidget::COperationOrderPluginWidget(QObject *parent): QObject(parent) +{ + +} + +COperationOrderPluginWidget::~COperationOrderPluginWidget() +{ + +} + +bool COperationOrderPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + Mainwindow *pWidget = new Mainwindow(parent,editMode); + *widget = (QWidget *)pWidget; + *reportWidget = (IPluginWidget *)pWidget; + return true; +} + +void COperationOrderPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.h b/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.h index fcca64d8..a9dbba56 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.h +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef COPERATIONORDERPLUGINWIDGET_H -#define COPERATIONORDERPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class COperationOrderPluginWidget: public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - COperationOrderPluginWidget(QObject *parent = 0); - ~COperationOrderPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); - void release(); -}; - -#endif // COPERATIONORDERPLUGINWIDGET_H +#ifndef COPERATIONORDERPLUGINWIDGET_H +#define COPERATIONORDERPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class COperationOrderPluginWidget: public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + COperationOrderPluginWidget(QObject *parent = 0); + ~COperationOrderPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); + void release(); +}; + +#endif // COPERATIONORDERPLUGINWIDGET_H diff --git a/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.cpp b/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.cpp index b89919c5..3799a69a 100644 --- a/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.cpp +++ b/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.cpp @@ -1,259 +1,259 @@ -#include "COrderManageWidget.h" -#include "ui_COrderManageWidget.h" -#include -#include "pub_utility_api/FileStyle.h" -#include "COperationOrderModelForm.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_logger_api/logger.h" - -COrderManageWidget::COrderManageWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::COrderManageWidget) -{ - ui->setupUi(this); - - initManageWidget(); - initManageTableWidget(); - if(!editMode) - { - readOrderData(); - initManageWidgetData(); - } -} - -COrderManageWidget::~COrderManageWidget() -{ -} - -void COrderManageWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("orderManage.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void COrderManageWidget::initManageWidget() -{ - m_orderManageTree = ui->m_orderManageTree; - m_orderManageTable = ui->m_orderManageTable; - - m_orderManageTree->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_orderManageTree,SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),this,SLOT(slot_treeItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); - - m_orderManageTree->setColumnCount(4); - m_orderManageTree->header()->hide(); - m_orderManageTree->hideColumn(1); - m_orderManageTree->hideColumn(2); - m_orderManageTree->hideColumn(3); - m_orderManageTree->setColumnWidth(0,200); - - connect(ui->refreshBtn, SIGNAL(clicked(bool)), this, SLOT(slot_refreshBtnClicked())); -} - -void COrderManageWidget::initManageTableWidget() -{ - m_orderManageTable->setColumnCount(2); - m_orderManageTable->setRowCount(0); - m_orderManageTable->verticalHeader()->setVisible(false); - m_orderManageTable->setHorizontalHeaderLabels(QStringList()<horizontalHeader()->setSectionResizeMode(1,QHeaderView::Stretch); - m_orderManageTable->setSelectionBehavior(QAbstractItemView::SelectRows); - m_orderManageTable->setEditTriggers(0); -} - -void COrderManageWidget::readOrderData() -{ - CSqlDbCtrl dbCtrl; - m_vecOrder = dbCtrl.readOrderPrestore(); - m_vecOrderInfo = dbCtrl.readOrderPrestoreInfo(); -} - -void COrderManageWidget::initManageWidgetData() -{ - m_orderManageTree->clear(); - if(m_vecOrder.length() <= 0) - { - return; - } - - for(int i=0; isetText(0,m_vecOrder.at(i).orderName); - item->setText(1,m_vecOrder.at(i).remarks); - item->setText(2,QString::number(m_vecOrder.at(i).id)); - item->setText(3,m_vecOrder.at(i).orderDesc); - } - - m_orderManageTree->expandAll(); -} - -void COrderManageWidget::slot_treeItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) -{ - QTreeWidgetItem* curItem = m_orderManageTree->currentItem(); - if (!curItem) - { - m_orderManageTable->clearContents(); - m_orderManageTable->setRowCount(0); - return; - } - - Q_UNUSED(previous) - m_orderManageTable->clearContents(); - m_orderManageTable->setRowCount(0); - int orderId = current->text(2).toInt(); - - QVector::iterator iter = m_vecOrderInfo.begin(); - for(; iter != m_vecOrderInfo.end(); ++iter) - { - if(iter->orderId == orderId) - { - showTableData(*iter); - } - } -} - -void COrderManageWidget::showTableData(const SOrderPreStoreInfo& vect) -{ - int curRow = m_orderManageTable->rowCount(); - m_orderManageTable->insertRow(curRow); - - int seqNo = vect.seqNo; - QString desc = vect.optDesc; - - QTableWidgetItem *seqNoi = new QTableWidgetItem(); - seqNoi->setText(QString::number(seqNo)); - QTableWidgetItem *desci = new QTableWidgetItem(); - desci->setText(desc); - - m_orderManageTable->setItem(curRow,0,seqNoi); - m_orderManageTable->item(curRow,0)->setTextAlignment(Qt::AlignCenter); - m_orderManageTable->setItem(curRow,1,desci); - m_orderManageTable->item(curRow,1)->setTextAlignment(Qt::AlignCenter); -} - -void COrderManageWidget::on_m_delBtn_clicked() -{ - if ( omPermCheck() == false ) - { - QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限!"), QMessageBox::Ok); - return; - } - - QTreeWidgetItem* item = m_orderManageTree->currentItem(); - - if(!item) - { - QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); - return; - } - if(QMessageBox::question(this,tr("提示"),tr("是否删除 %1 ?").arg(item->text(0)),QMessageBox::Ok,QMessageBox::Cancel) - == QMessageBox::Cancel) - { - return; - } - CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); - - bool ret = dbCtrl.deleteOneOrderData((item->text(2)).toInt()); - - if(ret) - { - dbCtrl.deleteAllOrderInfoData((item->text(2)).toInt()); - delete item; - item = NULL; - } - else - { - QMessageBox::warning(this, tr("提示"), tr("删除失败!"), QMessageBox::Ok); - } -} - -void COrderManageWidget::on_m_editBtn_clicked() -{ - QTreeWidgetItem* item = m_orderManageTree->currentItem(); - if(!item) - { - QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); - return; - } - SOrderPreStore info; - info.id = item->text(2).toInt(); - info.remarks = item->text(1); - info.orderDesc = item->text(3); - info.orderName = item->text(0); - - COperationOrderModelForm form(this); - connect(&form,SIGNAL(orderNameUpdated()),this,SLOT(slot_orderNameUpdate())); - connect(&form,SIGNAL(orderInfoUpdated()),this,SLOT(slot_orderInfoUpdate())); - form.showView(info); - form.initViewData(); - - form.exec(); -} - -void COrderManageWidget::slot_orderNameUpdate() -{ - CSqlDbCtrl dbCtrl; - m_orderManageTree->clear(); - m_vecOrder = dbCtrl.readOrderPrestore(); - m_orderManageTable->clearContents(); - m_orderManageTable->setRowCount(0); - initManageWidgetData(); -} - -void COrderManageWidget::slot_orderInfoUpdate() -{ - CSqlDbCtrl dbCtrl; - m_vecOrderInfo = dbCtrl.readOrderPrestoreInfo(); -} - -void COrderManageWidget::slot_refreshBtnClicked() -{ - readOrderData(); - initManageWidgetData(); - m_orderManageTable->clearContents(); - m_orderManageTable->setRowCount(0); -} - -void COrderManageWidget::showEvent(QShowEvent *event) -{ - slot_refreshBtnClicked(); - QWidget::showEvent(event); -} - -bool COrderManageWidget::omPermCheck() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - std::string tmpStr = "FUNC_NOM_OM"; - if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) - { - return false; - } - return true; -} +#include "COrderManageWidget.h" +#include "ui_COrderManageWidget.h" +#include +#include "pub_utility_api/FileStyle.h" +#include "COperationOrderModelForm.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_logger_api/logger.h" + +COrderManageWidget::COrderManageWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::COrderManageWidget) +{ + ui->setupUi(this); + + initManageWidget(); + initManageTableWidget(); + if(!editMode) + { + readOrderData(); + initManageWidgetData(); + } +} + +COrderManageWidget::~COrderManageWidget() +{ +} + +void COrderManageWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("orderManage.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void COrderManageWidget::initManageWidget() +{ + m_orderManageTree = ui->m_orderManageTree; + m_orderManageTable = ui->m_orderManageTable; + + m_orderManageTree->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_orderManageTree,SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),this,SLOT(slot_treeItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); + + m_orderManageTree->setColumnCount(4); + m_orderManageTree->header()->hide(); + m_orderManageTree->hideColumn(1); + m_orderManageTree->hideColumn(2); + m_orderManageTree->hideColumn(3); + m_orderManageTree->setColumnWidth(0,200); + + connect(ui->refreshBtn, SIGNAL(clicked(bool)), this, SLOT(slot_refreshBtnClicked())); +} + +void COrderManageWidget::initManageTableWidget() +{ + m_orderManageTable->setColumnCount(2); + m_orderManageTable->setRowCount(0); + m_orderManageTable->verticalHeader()->setVisible(false); + m_orderManageTable->setHorizontalHeaderLabels(QStringList()<horizontalHeader()->setSectionResizeMode(1,QHeaderView::Stretch); + m_orderManageTable->setSelectionBehavior(QAbstractItemView::SelectRows); + m_orderManageTable->setEditTriggers(0); +} + +void COrderManageWidget::readOrderData() +{ + CSqlDbCtrl dbCtrl; + m_vecOrder = dbCtrl.readOrderPrestore(); + m_vecOrderInfo = dbCtrl.readOrderPrestoreInfo(); +} + +void COrderManageWidget::initManageWidgetData() +{ + m_orderManageTree->clear(); + if(m_vecOrder.length() <= 0) + { + return; + } + + for(int i=0; isetText(0,m_vecOrder.at(i).orderName); + item->setText(1,m_vecOrder.at(i).remarks); + item->setText(2,QString::number(m_vecOrder.at(i).id)); + item->setText(3,m_vecOrder.at(i).orderDesc); + } + + m_orderManageTree->expandAll(); +} + +void COrderManageWidget::slot_treeItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + QTreeWidgetItem* curItem = m_orderManageTree->currentItem(); + if (!curItem) + { + m_orderManageTable->clearContents(); + m_orderManageTable->setRowCount(0); + return; + } + + Q_UNUSED(previous) + m_orderManageTable->clearContents(); + m_orderManageTable->setRowCount(0); + int orderId = current->text(2).toInt(); + + QVector::iterator iter = m_vecOrderInfo.begin(); + for(; iter != m_vecOrderInfo.end(); ++iter) + { + if(iter->orderId == orderId) + { + showTableData(*iter); + } + } +} + +void COrderManageWidget::showTableData(const SOrderPreStoreInfo& vect) +{ + int curRow = m_orderManageTable->rowCount(); + m_orderManageTable->insertRow(curRow); + + int seqNo = vect.seqNo; + QString desc = vect.optDesc; + + QTableWidgetItem *seqNoi = new QTableWidgetItem(); + seqNoi->setText(QString::number(seqNo)); + QTableWidgetItem *desci = new QTableWidgetItem(); + desci->setText(desc); + + m_orderManageTable->setItem(curRow,0,seqNoi); + m_orderManageTable->item(curRow,0)->setTextAlignment(Qt::AlignCenter); + m_orderManageTable->setItem(curRow,1,desci); + m_orderManageTable->item(curRow,1)->setTextAlignment(Qt::AlignCenter); +} + +void COrderManageWidget::on_m_delBtn_clicked() +{ + if ( omPermCheck() == false ) + { + QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限!"), QMessageBox::Ok); + return; + } + + QTreeWidgetItem* item = m_orderManageTree->currentItem(); + + if(!item) + { + QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); + return; + } + if(QMessageBox::question(this,tr("提示"),tr("是否删除 %1 ?").arg(item->text(0)),QMessageBox::Ok,QMessageBox::Cancel) + == QMessageBox::Cancel) + { + return; + } + CSqlDbCtrl dbCtrl(DB_CONN_MODEL_WRITE); + + bool ret = dbCtrl.deleteOneOrderData((item->text(2)).toInt()); + + if(ret) + { + dbCtrl.deleteAllOrderInfoData((item->text(2)).toInt()); + delete item; + item = NULL; + } + else + { + QMessageBox::warning(this, tr("提示"), tr("删除失败!"), QMessageBox::Ok); + } +} + +void COrderManageWidget::on_m_editBtn_clicked() +{ + QTreeWidgetItem* item = m_orderManageTree->currentItem(); + if(!item) + { + QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); + return; + } + SOrderPreStore info; + info.id = item->text(2).toInt(); + info.remarks = item->text(1); + info.orderDesc = item->text(3); + info.orderName = item->text(0); + + COperationOrderModelForm form(this); + connect(&form,SIGNAL(orderNameUpdated()),this,SLOT(slot_orderNameUpdate())); + connect(&form,SIGNAL(orderInfoUpdated()),this,SLOT(slot_orderInfoUpdate())); + form.showView(info); + form.initViewData(); + + form.exec(); +} + +void COrderManageWidget::slot_orderNameUpdate() +{ + CSqlDbCtrl dbCtrl; + m_orderManageTree->clear(); + m_vecOrder = dbCtrl.readOrderPrestore(); + m_orderManageTable->clearContents(); + m_orderManageTable->setRowCount(0); + initManageWidgetData(); +} + +void COrderManageWidget::slot_orderInfoUpdate() +{ + CSqlDbCtrl dbCtrl; + m_vecOrderInfo = dbCtrl.readOrderPrestoreInfo(); +} + +void COrderManageWidget::slot_refreshBtnClicked() +{ + readOrderData(); + initManageWidgetData(); + m_orderManageTable->clearContents(); + m_orderManageTable->setRowCount(0); +} + +void COrderManageWidget::showEvent(QShowEvent *event) +{ + slot_refreshBtnClicked(); + QWidget::showEvent(event); +} + +bool COrderManageWidget::omPermCheck() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string tmpStr = "FUNC_NOM_OM"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + return false; + } + return true; +} diff --git a/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.h b/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.h index e8d291f8..7476d93f 100644 --- a/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.h +++ b/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.h @@ -1,52 +1,52 @@ -#ifndef CORDERMANAGEWIDGET_H -#define CORDERMANAGEWIDGET_H - -#include -#include "SDbTableDefine.h" -#include "CSqlDbCtrl.h" -#include "COperationOrderForm.h" - -namespace Ui { -class COrderManageWidget; -} - -class QTreeWidget; -class QTreeWidgetItem; -class QTableWidget; -class COrderManageWidget : public QWidget -{ - Q_OBJECT - -public: - explicit COrderManageWidget(QWidget *parent,bool editMode); - ~COrderManageWidget(); - -private slots: - void slot_treeItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); - void on_m_delBtn_clicked(); - void on_m_editBtn_clicked(); - void slot_orderNameUpdate(); - void slot_orderInfoUpdate(); - void slot_refreshBtnClicked(); - -protected: - void showEvent(QShowEvent *event); -private: - void initStyleSheet(); - void initManageWidget(); - void initManageTableWidget(); - void readOrderData(); - void initManageWidgetData(); - void showTableData(const SOrderPreStoreInfo &vect); - bool omPermCheck(); - -private: - Ui::COrderManageWidget *ui; - QTreeWidget *m_orderManageTree; - QTableWidget *m_orderManageTable; - QVector m_vecOrder; - QVector m_vecOrderInfo; - QList m_isChanged; -}; - -#endif // CORDERMANAGEWIDGET_H +#ifndef CORDERMANAGEWIDGET_H +#define CORDERMANAGEWIDGET_H + +#include +#include "SDbTableDefine.h" +#include "CSqlDbCtrl.h" +#include "COperationOrderForm.h" + +namespace Ui { +class COrderManageWidget; +} + +class QTreeWidget; +class QTreeWidgetItem; +class QTableWidget; +class COrderManageWidget : public QWidget +{ + Q_OBJECT + +public: + explicit COrderManageWidget(QWidget *parent,bool editMode); + ~COrderManageWidget(); + +private slots: + void slot_treeItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void on_m_delBtn_clicked(); + void on_m_editBtn_clicked(); + void slot_orderNameUpdate(); + void slot_orderInfoUpdate(); + void slot_refreshBtnClicked(); + +protected: + void showEvent(QShowEvent *event); +private: + void initStyleSheet(); + void initManageWidget(); + void initManageTableWidget(); + void readOrderData(); + void initManageWidgetData(); + void showTableData(const SOrderPreStoreInfo &vect); + bool omPermCheck(); + +private: + Ui::COrderManageWidget *ui; + QTreeWidget *m_orderManageTree; + QTableWidget *m_orderManageTable; + QVector m_vecOrder; + QVector m_vecOrderInfo; + QList m_isChanged; +}; + +#endif // CORDERMANAGEWIDGET_H diff --git a/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.ui b/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.ui index 06c8bf24..afcb519f 100644 --- a/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.ui +++ b/product/src/gui/plugin/OrderManageWidget/COrderManageWidget.ui @@ -1,124 +1,124 @@ - - - COrderManageWidget - - - - 0 - 0 - 707 - 545 - - - - 典型票管理 - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - - - - 300 - 16777215 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 1 - - - - - - - - - - Qt::Horizontal - - - - 428 - 20 - - - - - - - - 刷新 - - - - - - - 编辑 - - - - - - - 删除 - - - - - - - - - - - - - - - - - - 删除 - - - - - 自动开票 - - - - - - - + + + COrderManageWidget + + + + 0 + 0 + 707 + 545 + + + + 典型票管理 + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + + 300 + 16777215 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 1 + + + + + + + + + + Qt::Horizontal + + + + 428 + 20 + + + + + + + + 刷新 + + + + + + + 编辑 + + + + + + + 删除 + + + + + + + + + + + + + + + + + + 删除 + + + + + 自动开票 + + + + + + + diff --git a/product/src/gui/plugin/OrderManageWidget/COrderPrinter.cpp b/product/src/gui/plugin/OrderManageWidget/COrderPrinter.cpp index 37d69b0b..346348d3 100644 --- a/product/src/gui/plugin/OrderManageWidget/COrderPrinter.cpp +++ b/product/src/gui/plugin/OrderManageWidget/COrderPrinter.cpp @@ -1,199 +1,199 @@ -#include "COrderPrinter.h" -#include - -COrderPrinter::COrderPrinter() -{ - m_textprinter = new CTextPrinter(); -} - -COrderPrinter::~COrderPrinter() -{ - if(m_textprinter) - { - delete m_textprinter; - m_textprinter = NULL; - } -} - -static QString s_captionTmpt = "

%1

"; -static QString s_footerTmpt = "

&page;

"; -static QString s_paragraphTmpt = "

%1

"; -static QString s_trTmpt = "

%2

\n"; -static QString s_tdTmpt = "

%2

\n"; -//static QString s_backTmpt = "

%2

" -// "%4" -// "

\n"; -static QString s_backTmpt = "

%2

\n"; -static QString s_noBackTmpt = "

%2
%3

\n"; - -void COrderPrinter::initPrintEnv() -{ - m_frontStr = ""; - m_rearStr = ""; - m_frontGridStr = ""; - m_rearGridStr = ""; - m_streamStr = ""; - m_backGridStr.clear(); - - m_printStream.flush(); - m_printStream << "\n" - "\n" - "\n" - << "\n" - << "\n"; - - if(!m_textprinter) - { - m_textprinter = new CTextPrinter(); - m_textprinter->setFooterSize(10); - } - - m_printStream.setString(&m_streamStr); -} - -void COrderPrinter::setPrintCaption(const QString &caption) -{ - if(!m_textprinter) - { - return; - } - m_printStream << s_captionTmpt.arg(caption); -} - -void COrderPrinter::setPrintWithBack(const QPair ¶graph, int columnCount, const QString &background) -{ - if(!m_textprinter) - { - return; - } - if(background.isEmpty()) - { - m_backGridStr.append(s_noBackTmpt.arg(columnCount).arg(paragraph.first).arg(paragraph.second)); - } - else - { - m_backGridStr.append(s_backTmpt.arg(columnCount).arg(paragraph.first).arg(background)); - } -} - -void COrderPrinter::setPrintParagraph(const QString ¶graph, int columnCount, bool rear, bool grid) -{ - if(!m_textprinter) - { - return; - } - - if(rear) - { - if(grid) - { - m_rearGridStr += s_trTmpt.arg(columnCount).arg(paragraph); - } - else - { - m_rearStr += s_paragraphTmpt.arg(paragraph); - } - } - else - { - if(grid) - { - m_frontGridStr += s_trTmpt.arg(columnCount).arg(paragraph); - } - else - { - m_printStream << s_paragraphTmpt.arg(paragraph); - } - } -} - -void COrderPrinter::preview(const QTableWidget *table) -{ - if(!m_textprinter) - { - return; - } - genTableStream(table); - QTextDocument *document = new QTextDocument; - document->setHtml(m_printStream.readAll()); - m_textprinter->setFooterText(s_footerTmpt); - m_textprinter->preview(document, QObject::tr("预览")); - delete document; -} - -void COrderPrinter::genTableStream(const QTableWidget *table) -{ - int rowCount = table->model()->rowCount(); - int columnCount = table->model()->columnCount(); - - m_printStream << "\n"; - - if(!m_frontGridStr.isEmpty()) - { - m_printStream << m_frontGridStr; - } - - m_printStream << ""; - for(int column = 0; column < columnCount; column++) - { - if (!table->isColumnHidden(column)) - { - m_printStream << s_tdTmpt.arg("center").arg(table->model()->headerData(column, Qt::Horizontal).toString()); - } - } - m_printStream << "\n"; - - for(int row = 0; row < rowCount; row++) - { - m_printStream << ""; - for(int column = 0; column < columnCount; column++) - { - if(!table->isColumnHidden(column)) - { - QString data = table->model()->data(table->model()->index(row, column)).toString().simplified(); - m_printStream << s_tdTmpt.arg("left").arg((!data.isEmpty()) ? data : QString(" ")); - } - } - m_printStream << "\n"; - } - - if(!m_rearGridStr.isEmpty()) - { - m_printStream << m_rearGridStr; - } - - if(!m_backGridStr.isEmpty()) - { - m_printStream << ""; - foreach (QString str, m_backGridStr) { - m_printStream << str; - } - m_printStream << "\n"; - } - - m_printStream << "
\n"; - - if(!m_rearStr.isEmpty()) - { - m_printStream << m_rearStr; - } - - m_printStream << "\n" - "\n"; -} - -int COrderPrinter::print(const QTableWidget *table) -{ - if(!m_textprinter) - { - return -1; - } - genTableStream(table); - QTextDocument *document = new QTextDocument; - document->setHtml(m_printStream.readAll()); - m_textprinter->setFooterText(s_footerTmpt); - int ret = m_textprinter->print(document, QObject::tr("打印")); - delete document; - return ret; -} - +#include "COrderPrinter.h" +#include + +COrderPrinter::COrderPrinter() +{ + m_textprinter = new CTextPrinter(); +} + +COrderPrinter::~COrderPrinter() +{ + if(m_textprinter) + { + delete m_textprinter; + m_textprinter = NULL; + } +} + +static QString s_captionTmpt = "

%1

"; +static QString s_footerTmpt = "

&page;

"; +static QString s_paragraphTmpt = "

%1

"; +static QString s_trTmpt = "

%2

\n"; +static QString s_tdTmpt = "

%2

\n"; +//static QString s_backTmpt = "

%2

" +// "%4" +// "

\n"; +static QString s_backTmpt = "

%2

\n"; +static QString s_noBackTmpt = "

%2
%3

\n"; + +void COrderPrinter::initPrintEnv() +{ + m_frontStr = ""; + m_rearStr = ""; + m_frontGridStr = ""; + m_rearGridStr = ""; + m_streamStr = ""; + m_backGridStr.clear(); + + m_printStream.flush(); + m_printStream << "\n" + "\n" + "\n" + << "\n" + << "\n"; + + if(!m_textprinter) + { + m_textprinter = new CTextPrinter(); + m_textprinter->setFooterSize(10); + } + + m_printStream.setString(&m_streamStr); +} + +void COrderPrinter::setPrintCaption(const QString &caption) +{ + if(!m_textprinter) + { + return; + } + m_printStream << s_captionTmpt.arg(caption); +} + +void COrderPrinter::setPrintWithBack(const QPair ¶graph, int columnCount, const QString &background) +{ + if(!m_textprinter) + { + return; + } + if(background.isEmpty()) + { + m_backGridStr.append(s_noBackTmpt.arg(columnCount).arg(paragraph.first).arg(paragraph.second)); + } + else + { + m_backGridStr.append(s_backTmpt.arg(columnCount).arg(paragraph.first).arg(background)); + } +} + +void COrderPrinter::setPrintParagraph(const QString ¶graph, int columnCount, bool rear, bool grid) +{ + if(!m_textprinter) + { + return; + } + + if(rear) + { + if(grid) + { + m_rearGridStr += s_trTmpt.arg(columnCount).arg(paragraph); + } + else + { + m_rearStr += s_paragraphTmpt.arg(paragraph); + } + } + else + { + if(grid) + { + m_frontGridStr += s_trTmpt.arg(columnCount).arg(paragraph); + } + else + { + m_printStream << s_paragraphTmpt.arg(paragraph); + } + } +} + +void COrderPrinter::preview(const QTableWidget *table) +{ + if(!m_textprinter) + { + return; + } + genTableStream(table); + QTextDocument *document = new QTextDocument; + document->setHtml(m_printStream.readAll()); + m_textprinter->setFooterText(s_footerTmpt); + m_textprinter->preview(document, QObject::tr("预览")); + delete document; +} + +void COrderPrinter::genTableStream(const QTableWidget *table) +{ + int rowCount = table->model()->rowCount(); + int columnCount = table->model()->columnCount(); + + m_printStream << "\n"; + + if(!m_frontGridStr.isEmpty()) + { + m_printStream << m_frontGridStr; + } + + m_printStream << ""; + for(int column = 0; column < columnCount; column++) + { + if (!table->isColumnHidden(column)) + { + m_printStream << s_tdTmpt.arg("center").arg(table->model()->headerData(column, Qt::Horizontal).toString()); + } + } + m_printStream << "\n"; + + for(int row = 0; row < rowCount; row++) + { + m_printStream << ""; + for(int column = 0; column < columnCount; column++) + { + if(!table->isColumnHidden(column)) + { + QString data = table->model()->data(table->model()->index(row, column)).toString().simplified(); + m_printStream << s_tdTmpt.arg("left").arg((!data.isEmpty()) ? data : QString(" ")); + } + } + m_printStream << "\n"; + } + + if(!m_rearGridStr.isEmpty()) + { + m_printStream << m_rearGridStr; + } + + if(!m_backGridStr.isEmpty()) + { + m_printStream << ""; + foreach (QString str, m_backGridStr) { + m_printStream << str; + } + m_printStream << "\n"; + } + + m_printStream << "
\n"; + + if(!m_rearStr.isEmpty()) + { + m_printStream << m_rearStr; + } + + m_printStream << "\n" + "\n"; +} + +int COrderPrinter::print(const QTableWidget *table) +{ + if(!m_textprinter) + { + return -1; + } + genTableStream(table); + QTextDocument *document = new QTextDocument; + document->setHtml(m_printStream.readAll()); + m_textprinter->setFooterText(s_footerTmpt); + int ret = m_textprinter->print(document, QObject::tr("打印")); + delete document; + return ret; +} + diff --git a/product/src/gui/plugin/OrderManageWidget/COrderPrinter.h b/product/src/gui/plugin/OrderManageWidget/COrderPrinter.h index 2b371bd4..949f41f7 100644 --- a/product/src/gui/plugin/OrderManageWidget/COrderPrinter.h +++ b/product/src/gui/plugin/OrderManageWidget/COrderPrinter.h @@ -1,35 +1,35 @@ -#ifndef CORDERPRINTER_H -#define CORDERPRINTER_H - -#include -#include -#include -#include "CTextPrinter.h" - -class COrderPrinter -{ -public: - COrderPrinter(); - ~COrderPrinter(); - - void initPrintEnv(); - void setPrintCaption(const QString &caption); - void setPrintWithBack(const QPair ¶graph, int columnCount = 1, const QString &background = ""); - void setPrintParagraph(const QString ¶graph, int columnCount, bool rear=false, bool grid=false); - void genTableStream(const QTableWidget *table); - - void preview(const QTableWidget *table); - int print(const QTableWidget *table); -private: - QString m_frontStr; - QString m_rearStr; - QString m_frontGridStr; - QString m_rearGridStr; - QString m_streamStr; - QStringList m_backGridStr; - - QTextStream m_printStream; - CTextPrinter *m_textprinter; -}; - -#endif // CORDERPRINTER_H +#ifndef CORDERPRINTER_H +#define CORDERPRINTER_H + +#include +#include +#include +#include "CTextPrinter.h" + +class COrderPrinter +{ +public: + COrderPrinter(); + ~COrderPrinter(); + + void initPrintEnv(); + void setPrintCaption(const QString &caption); + void setPrintWithBack(const QPair ¶graph, int columnCount = 1, const QString &background = ""); + void setPrintParagraph(const QString ¶graph, int columnCount, bool rear=false, bool grid=false); + void genTableStream(const QTableWidget *table); + + void preview(const QTableWidget *table); + int print(const QTableWidget *table); +private: + QString m_frontStr; + QString m_rearStr; + QString m_frontGridStr; + QString m_rearGridStr; + QString m_streamStr; + QStringList m_backGridStr; + + QTextStream m_printStream; + CTextPrinter *m_textprinter; +}; + +#endif // CORDERPRINTER_H diff --git a/product/src/gui/plugin/OrderManageWidget/CRecordForm.cpp b/product/src/gui/plugin/OrderManageWidget/CRecordForm.cpp index 492fa596..b1f17606 100644 --- a/product/src/gui/plugin/OrderManageWidget/CRecordForm.cpp +++ b/product/src/gui/plugin/OrderManageWidget/CRecordForm.cpp @@ -1,352 +1,352 @@ -#include "CRecordForm.h" -#include "ui_CRecordForm.h" -#include -#include "dbms/db_api_ex/CDbApi.h" -#include "SDbTableDefine.h" -#include "COperationOrderHisForm.h" - -CRecordForm::CRecordForm(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CRecordForm) -{ - ui->setupUi(this); - - if(!editMode) - { - initTreeView(); - initDateTime(); - CSqlDbCtrl dbCtrl; - g_optOrderHisData = dbCtrl.readOptOrderHis(); - initTreeViewData(); - updateCombo(); - initSignal(); - } -} - -CRecordForm::~CRecordForm() -{ - delete ui; -} - -void CRecordForm::showEvent(QShowEvent *event) -{ - slot_refreshBtnClicked(); - QWidget::showEvent(event); -} - -void CRecordForm::initTreeView() -{ - ui->treeWidget->setColumnWidth(3,175); - ui->treeWidget->setColumnWidth(4,175); - //ui->treeWidget->setColumnHidden(10,true); - //ui->treeWidget->setColumnHidden(9,true); - //ui->treeWidget->setColumnHidden(0,true); - ui->treeWidget->header()->setDefaultAlignment(Qt::AlignCenter); -} - -void CRecordForm::initDateTime() -{ - QDateTime curTime = QDateTime::currentDateTime(); - - ui->m_execTimeBegin->setDateTime(curTime.addDays(-1)); - ui->m_execTimeEnd->setDateTime(curTime.addDays(1)); - ui->m_finishTimeBegin->setDateTime(curTime.addDays(-1)); - ui->m_finishTimeEnd->setDateTime(curTime.addDays(1)); - ui->m_execTimeBegin->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); - ui->m_execTimeEnd->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); - ui->m_finishTimeBegin->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); - ui->m_finishTimeEnd->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); - -} - -void CRecordForm::initSignal() -{ - connect(ui->m_operatorRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_guardianRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_dutyManagerRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_startTimeRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_endTimeRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_orderNameRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_orderIdRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); - - connect(ui->m_orderNameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_orderIdEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slot_updateTreeViewData())); - - connect(ui->treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int )), this, SLOT(slot_openOptOrder())); - connect(ui->m_detail, SIGNAL(clicked()), this, SLOT(slot_openOptOrder())); - connect(ui->refreshBtn, SIGNAL(clicked()), this, SLOT(slot_refreshBtnClicked())); - - connect(ui->m_operatorComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_guardianComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_dutyManagerComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_updateTreeViewData())); - - connect(ui->m_execTimeBegin, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_execTimeEnd, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_finishTimeBegin, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(slot_updateTreeViewData())); - connect(ui->m_finishTimeEnd, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(slot_updateTreeViewData())); - -} - -void CRecordForm::initTreeViewData() -{ - ui->treeWidget->clear(); - QVector::iterator iter = g_optOrderHisData.begin(); - for(; iter != g_optOrderHisData.end(); ++iter) - { - SOrderHis& record = *iter; - if(!checkCondition(record)) - { - continue; - } - - addTreeItem(record); - } -} - -void CRecordForm::initComb(QComboBox *box, QString data) -{ - if(box->findText(data) == -1) - { - box->addItem(data); - } -} - -void CRecordForm::addTreeItem(const SOrderHis &record) -{ - QTreeWidgetItem* item = new QTreeWidgetItem(); - item->setText(0,QString::number(record.id)); - item->setText(1,record.order_no); - item->setText(2,record.order_name); - item->setText(3,getTimeByUtc(record.begin_time)); - item->setData(3,Qt::UserRole+1,record.begin_time); - item->setText(4,getTimeByUtc(record.end_time)); - item->setData(4,Qt::UserRole+1,record.end_time); - item->setText(5,record.OPERATOR); - item->setText(6,record.guardian); - item->setText(7,record.duty_manager); - item->setText(8,getExecState(record.exec_state)); - item->setData(8,Qt::UserRole+1,record.exec_state); - item->setText(9,record.order_desc); - item->setText(10,record.remarks); - - item->setTextAlignment(0, Qt::AlignCenter); - item->setTextAlignment(1, Qt::AlignCenter); - item->setTextAlignment(2, Qt::AlignCenter); - item->setTextAlignment(3, Qt::AlignCenter); - item->setTextAlignment(4, Qt::AlignCenter); - item->setTextAlignment(5, Qt::AlignCenter); - item->setTextAlignment(6, Qt::AlignCenter); - item->setTextAlignment(7, Qt::AlignCenter); - item->setTextAlignment(8, Qt::AlignCenter); - item->setTextAlignment(9, Qt::AlignCenter); - item->setTextAlignment(10, Qt::AlignCenter); - ui->treeWidget->addTopLevelItem(item); -} - -QString CRecordForm::getTimeByUtc(qint64 time) -{ - return QDateTime::fromTime_t(time/1000).toString("yyyy-MM-dd hh:mm:ss"); -} - -QString CRecordForm::getExecState(int numb) -{ - QString str = ""; - switch(numb) - { - case 0: - str = tr("未执行"); - break; - case 1: - str = tr("已执行"); - break; - default: - str = tr("未确认"); - break; - } - return str; -} - -bool CRecordForm::checkCondition(const SOrderHis &obj) -{ - if(ui->m_operatorRbtn->isChecked()) - { - QString opt = ui->m_operatorComb->currentText(); - if(obj.OPERATOR != opt) - { - return false; - } - } - - if(ui->m_guardianRbtn->isChecked()) - { - QString guardian = ui->m_guardianComb->currentText(); - if(obj.guardian != guardian) - { - return false; - } - } - - if(ui->m_dutyManagerRbtn->isChecked()) - { - QString dutyManager = ui->m_dutyManagerComb->currentText(); - if(obj.duty_manager != dutyManager) - { - return false; - } - } - - if(ui->m_startTimeRbtn->isChecked()) - { - if(!checkExecDateTimeRange(obj.begin_time)) - { - return false; - } - } - - if(ui->m_endTimeRbtn->isChecked()) - { - if(!checkFinishDateTimeRange(obj.end_time)) - { - return false; - } - } - - if(ui->m_orderNameRbtn->isChecked()) - { - QString orderName = ui->m_orderNameEdit->text(); - if(!obj.order_name.contains(orderName)) - { - return false; - } - } - - if(ui->m_orderIdRbtn->isChecked()) - { - QString orderId = ui->m_orderIdEdit->text(); - QString searchStr = QString("%1").arg(obj.order_no); - if(!searchStr.contains(orderId)) - { - return false; - } - } - - return true; -} - -bool CRecordForm::checkExecDateTimeRange(qint64 timeflag) -{ - qint64 checkTime = timeflag / 1000; - qint64 begin = ui->m_execTimeBegin->dateTime().toTime_t(); - qint64 end = ui->m_execTimeEnd->dateTime().toTime_t(); - if(checkTime < begin || checkTime >end) - { - return false; - } - else - { - return true; - } -} - -bool CRecordForm::checkFinishDateTimeRange(qint64 timeflag) -{ - qint64 checkTime = timeflag / 1000; - qint64 begin = ui->m_finishTimeBegin->dateTime().toTime_t(); - qint64 end = ui->m_finishTimeEnd->dateTime().toTime_t(); - if(checkTime < begin || checkTime >end) - { - return false; - } - else - { - return true; - } -} - -QJsonArray CRecordForm::getOrderHeader(QTreeWidgetItem *item) -{ - QJsonArray simulateHeader; - QJsonObject headObj; - headObj.insert("id",item->text(0).toInt()); - headObj.insert("order_no",item->text(1)); - headObj.insert("order_name",item->text(2)); - headObj.insert("begin_time",item->data(3,Qt::UserRole+1).toLongLong()); - headObj.insert("end_time",item->data(4,Qt::UserRole+1).toLongLong()); - headObj.insert("operator",item->text(5)); - headObj.insert("guardian",item->text(6)); - headObj.insert("duty_manager",item->text(7)); - headObj.insert("order_desc",item->text(9)); - headObj.insert("remarks",item->text(10)); - - simulateHeader.append(headObj); - return simulateHeader; -} - -void CRecordForm::updateCombo() -{ - ui->m_operatorComb->clear(); - ui->m_guardianComb->clear(); - ui->m_dutyManagerComb->clear(); - - QVector::iterator iter = g_optOrderHisData.begin(); - for (; iter != g_optOrderHisData.end(); ++iter) - { - SOrderHis& record = *iter; - initComb(ui->m_operatorComb, record.OPERATOR); - initComb(ui->m_guardianComb, record.guardian); - initComb(ui->m_dutyManagerComb, record.duty_manager); - } -} - -SOrderHis* CRecordForm::findOrderHis(int orderId) -{ - QVector::iterator iter = g_optOrderHisData.begin(); - for (; iter != g_optOrderHisData.end(); ++iter) - { - SOrderHis& record = *iter; - if (record.id == orderId) - { - return &record; - } - } - - return NULL; -} - -void CRecordForm::slot_updateTreeViewData() -{ - initTreeViewData(); -} - -void CRecordForm::slot_openOptOrder() -{ - QTreeWidgetItem*item = ui->treeWidget->currentItem(); - if(!item) - { - QMessageBox::warning(this, tr("提示"), tr("请选择一项!"), QMessageBox::Ok); - return ; - } - - int orderId = item->text(0).toInt(); - SOrderHis* info = findOrderHis(orderId); - if (!info) - { - return; - } - - COperationOrderHisForm form(this); - form.showHisView(*info); - form.initViewData(); - form.exec(); - - slot_refreshBtnClicked(); -} - -void CRecordForm::slot_refreshBtnClicked() -{ - CSqlDbCtrl dbCtrl; - g_optOrderHisData = dbCtrl.readOptOrderHis(); - initTreeViewData(); - updateCombo(); -} - +#include "CRecordForm.h" +#include "ui_CRecordForm.h" +#include +#include "dbms/db_api_ex/CDbApi.h" +#include "SDbTableDefine.h" +#include "COperationOrderHisForm.h" + +CRecordForm::CRecordForm(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CRecordForm) +{ + ui->setupUi(this); + + if(!editMode) + { + initTreeView(); + initDateTime(); + CSqlDbCtrl dbCtrl; + g_optOrderHisData = dbCtrl.readOptOrderHis(); + initTreeViewData(); + updateCombo(); + initSignal(); + } +} + +CRecordForm::~CRecordForm() +{ + delete ui; +} + +void CRecordForm::showEvent(QShowEvent *event) +{ + slot_refreshBtnClicked(); + QWidget::showEvent(event); +} + +void CRecordForm::initTreeView() +{ + ui->treeWidget->setColumnWidth(3,175); + ui->treeWidget->setColumnWidth(4,175); + //ui->treeWidget->setColumnHidden(10,true); + //ui->treeWidget->setColumnHidden(9,true); + //ui->treeWidget->setColumnHidden(0,true); + ui->treeWidget->header()->setDefaultAlignment(Qt::AlignCenter); +} + +void CRecordForm::initDateTime() +{ + QDateTime curTime = QDateTime::currentDateTime(); + + ui->m_execTimeBegin->setDateTime(curTime.addDays(-1)); + ui->m_execTimeEnd->setDateTime(curTime.addDays(1)); + ui->m_finishTimeBegin->setDateTime(curTime.addDays(-1)); + ui->m_finishTimeEnd->setDateTime(curTime.addDays(1)); + ui->m_execTimeBegin->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); + ui->m_execTimeEnd->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); + ui->m_finishTimeBegin->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); + ui->m_finishTimeEnd->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); + +} + +void CRecordForm::initSignal() +{ + connect(ui->m_operatorRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_guardianRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_dutyManagerRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_startTimeRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_endTimeRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_orderNameRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_orderIdRbtn, SIGNAL(stateChanged(int)), this, SLOT(slot_updateTreeViewData())); + + connect(ui->m_orderNameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_orderIdEdit, SIGNAL(textChanged(const QString &)), this, SLOT(slot_updateTreeViewData())); + + connect(ui->treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int )), this, SLOT(slot_openOptOrder())); + connect(ui->m_detail, SIGNAL(clicked()), this, SLOT(slot_openOptOrder())); + connect(ui->refreshBtn, SIGNAL(clicked()), this, SLOT(slot_refreshBtnClicked())); + + connect(ui->m_operatorComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_guardianComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_dutyManagerComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_updateTreeViewData())); + + connect(ui->m_execTimeBegin, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_execTimeEnd, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_finishTimeBegin, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(slot_updateTreeViewData())); + connect(ui->m_finishTimeEnd, SIGNAL(dateTimeChanged(const QDateTime &)), this, SLOT(slot_updateTreeViewData())); + +} + +void CRecordForm::initTreeViewData() +{ + ui->treeWidget->clear(); + QVector::iterator iter = g_optOrderHisData.begin(); + for(; iter != g_optOrderHisData.end(); ++iter) + { + SOrderHis& record = *iter; + if(!checkCondition(record)) + { + continue; + } + + addTreeItem(record); + } +} + +void CRecordForm::initComb(QComboBox *box, QString data) +{ + if(box->findText(data) == -1) + { + box->addItem(data); + } +} + +void CRecordForm::addTreeItem(const SOrderHis &record) +{ + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0,QString::number(record.id)); + item->setText(1,record.order_no); + item->setText(2,record.order_name); + item->setText(3,getTimeByUtc(record.begin_time)); + item->setData(3,Qt::UserRole+1,record.begin_time); + item->setText(4,getTimeByUtc(record.end_time)); + item->setData(4,Qt::UserRole+1,record.end_time); + item->setText(5,record.OPERATOR); + item->setText(6,record.guardian); + item->setText(7,record.duty_manager); + item->setText(8,getExecState(record.exec_state)); + item->setData(8,Qt::UserRole+1,record.exec_state); + item->setText(9,record.order_desc); + item->setText(10,record.remarks); + + item->setTextAlignment(0, Qt::AlignCenter); + item->setTextAlignment(1, Qt::AlignCenter); + item->setTextAlignment(2, Qt::AlignCenter); + item->setTextAlignment(3, Qt::AlignCenter); + item->setTextAlignment(4, Qt::AlignCenter); + item->setTextAlignment(5, Qt::AlignCenter); + item->setTextAlignment(6, Qt::AlignCenter); + item->setTextAlignment(7, Qt::AlignCenter); + item->setTextAlignment(8, Qt::AlignCenter); + item->setTextAlignment(9, Qt::AlignCenter); + item->setTextAlignment(10, Qt::AlignCenter); + ui->treeWidget->addTopLevelItem(item); +} + +QString CRecordForm::getTimeByUtc(qint64 time) +{ + return QDateTime::fromTime_t(time/1000).toString("yyyy-MM-dd hh:mm:ss"); +} + +QString CRecordForm::getExecState(int numb) +{ + QString str = ""; + switch(numb) + { + case 0: + str = tr("未执行"); + break; + case 1: + str = tr("已执行"); + break; + default: + str = tr("未确认"); + break; + } + return str; +} + +bool CRecordForm::checkCondition(const SOrderHis &obj) +{ + if(ui->m_operatorRbtn->isChecked()) + { + QString opt = ui->m_operatorComb->currentText(); + if(obj.OPERATOR != opt) + { + return false; + } + } + + if(ui->m_guardianRbtn->isChecked()) + { + QString guardian = ui->m_guardianComb->currentText(); + if(obj.guardian != guardian) + { + return false; + } + } + + if(ui->m_dutyManagerRbtn->isChecked()) + { + QString dutyManager = ui->m_dutyManagerComb->currentText(); + if(obj.duty_manager != dutyManager) + { + return false; + } + } + + if(ui->m_startTimeRbtn->isChecked()) + { + if(!checkExecDateTimeRange(obj.begin_time)) + { + return false; + } + } + + if(ui->m_endTimeRbtn->isChecked()) + { + if(!checkFinishDateTimeRange(obj.end_time)) + { + return false; + } + } + + if(ui->m_orderNameRbtn->isChecked()) + { + QString orderName = ui->m_orderNameEdit->text(); + if(!obj.order_name.contains(orderName)) + { + return false; + } + } + + if(ui->m_orderIdRbtn->isChecked()) + { + QString orderId = ui->m_orderIdEdit->text(); + QString searchStr = QString("%1").arg(obj.order_no); + if(!searchStr.contains(orderId)) + { + return false; + } + } + + return true; +} + +bool CRecordForm::checkExecDateTimeRange(qint64 timeflag) +{ + qint64 checkTime = timeflag / 1000; + qint64 begin = ui->m_execTimeBegin->dateTime().toTime_t(); + qint64 end = ui->m_execTimeEnd->dateTime().toTime_t(); + if(checkTime < begin || checkTime >end) + { + return false; + } + else + { + return true; + } +} + +bool CRecordForm::checkFinishDateTimeRange(qint64 timeflag) +{ + qint64 checkTime = timeflag / 1000; + qint64 begin = ui->m_finishTimeBegin->dateTime().toTime_t(); + qint64 end = ui->m_finishTimeEnd->dateTime().toTime_t(); + if(checkTime < begin || checkTime >end) + { + return false; + } + else + { + return true; + } +} + +QJsonArray CRecordForm::getOrderHeader(QTreeWidgetItem *item) +{ + QJsonArray simulateHeader; + QJsonObject headObj; + headObj.insert("id",item->text(0).toInt()); + headObj.insert("order_no",item->text(1)); + headObj.insert("order_name",item->text(2)); + headObj.insert("begin_time",item->data(3,Qt::UserRole+1).toLongLong()); + headObj.insert("end_time",item->data(4,Qt::UserRole+1).toLongLong()); + headObj.insert("operator",item->text(5)); + headObj.insert("guardian",item->text(6)); + headObj.insert("duty_manager",item->text(7)); + headObj.insert("order_desc",item->text(9)); + headObj.insert("remarks",item->text(10)); + + simulateHeader.append(headObj); + return simulateHeader; +} + +void CRecordForm::updateCombo() +{ + ui->m_operatorComb->clear(); + ui->m_guardianComb->clear(); + ui->m_dutyManagerComb->clear(); + + QVector::iterator iter = g_optOrderHisData.begin(); + for (; iter != g_optOrderHisData.end(); ++iter) + { + SOrderHis& record = *iter; + initComb(ui->m_operatorComb, record.OPERATOR); + initComb(ui->m_guardianComb, record.guardian); + initComb(ui->m_dutyManagerComb, record.duty_manager); + } +} + +SOrderHis* CRecordForm::findOrderHis(int orderId) +{ + QVector::iterator iter = g_optOrderHisData.begin(); + for (; iter != g_optOrderHisData.end(); ++iter) + { + SOrderHis& record = *iter; + if (record.id == orderId) + { + return &record; + } + } + + return NULL; +} + +void CRecordForm::slot_updateTreeViewData() +{ + initTreeViewData(); +} + +void CRecordForm::slot_openOptOrder() +{ + QTreeWidgetItem*item = ui->treeWidget->currentItem(); + if(!item) + { + QMessageBox::warning(this, tr("提示"), tr("请选择一项!"), QMessageBox::Ok); + return ; + } + + int orderId = item->text(0).toInt(); + SOrderHis* info = findOrderHis(orderId); + if (!info) + { + return; + } + + COperationOrderHisForm form(this); + form.showHisView(*info); + form.initViewData(); + form.exec(); + + slot_refreshBtnClicked(); +} + +void CRecordForm::slot_refreshBtnClicked() +{ + CSqlDbCtrl dbCtrl; + g_optOrderHisData = dbCtrl.readOptOrderHis(); + initTreeViewData(); + updateCombo(); +} + diff --git a/product/src/gui/plugin/OrderManageWidget/CRecordForm.h b/product/src/gui/plugin/OrderManageWidget/CRecordForm.h index 4f7364de..ca5e744c 100644 --- a/product/src/gui/plugin/OrderManageWidget/CRecordForm.h +++ b/product/src/gui/plugin/OrderManageWidget/CRecordForm.h @@ -1,53 +1,53 @@ -#ifndef CRECORDFORM_H -#define CRECORDFORM_H - -#include -#include -#include -#include -#include "SDbTableDefine.h" -#include "CSqlDbCtrl.h" - -namespace Ui { -class CRecordForm; -} - -class CRecordForm : public QWidget -{ - Q_OBJECT - -public: - explicit CRecordForm(QWidget *parent, bool editMode); - ~CRecordForm(); -protected: - void showEvent(QShowEvent *event); -private: - void initTreeView(); - void initDateTime(); - void initSignal(); - void initTreeViewData(); - void initComb(QComboBox* box,QString data); - void addTreeItem(const SOrderHis& record); - - QString getTimeByUtc(qint64 time); - QString getExecState(int numb); - bool checkCondition(const SOrderHis& record); - - bool checkExecDateTimeRange(qint64 timeflag); - bool checkFinishDateTimeRange(qint64 timeflag); - - QJsonArray getOrderHeader(QTreeWidgetItem* item); - void updateCombo(); - - SOrderHis* findOrderHis(int orderId); -private slots: - void slot_updateTreeViewData(); - void slot_openOptOrder(); - void slot_refreshBtnClicked(); - -private: - Ui::CRecordForm *ui; - QVector g_optOrderHisData; -}; - -#endif // CRECORDFORM_H +#ifndef CRECORDFORM_H +#define CRECORDFORM_H + +#include +#include +#include +#include +#include "SDbTableDefine.h" +#include "CSqlDbCtrl.h" + +namespace Ui { +class CRecordForm; +} + +class CRecordForm : public QWidget +{ + Q_OBJECT + +public: + explicit CRecordForm(QWidget *parent, bool editMode); + ~CRecordForm(); +protected: + void showEvent(QShowEvent *event); +private: + void initTreeView(); + void initDateTime(); + void initSignal(); + void initTreeViewData(); + void initComb(QComboBox* box,QString data); + void addTreeItem(const SOrderHis& record); + + QString getTimeByUtc(qint64 time); + QString getExecState(int numb); + bool checkCondition(const SOrderHis& record); + + bool checkExecDateTimeRange(qint64 timeflag); + bool checkFinishDateTimeRange(qint64 timeflag); + + QJsonArray getOrderHeader(QTreeWidgetItem* item); + void updateCombo(); + + SOrderHis* findOrderHis(int orderId); +private slots: + void slot_updateTreeViewData(); + void slot_openOptOrder(); + void slot_refreshBtnClicked(); + +private: + Ui::CRecordForm *ui; + QVector g_optOrderHisData; +}; + +#endif // CRECORDFORM_H diff --git a/product/src/gui/plugin/OrderManageWidget/CRecordForm.ui b/product/src/gui/plugin/OrderManageWidget/CRecordForm.ui index b14bc172..662021f6 100644 --- a/product/src/gui/plugin/OrderManageWidget/CRecordForm.ui +++ b/product/src/gui/plugin/OrderManageWidget/CRecordForm.ui @@ -1,227 +1,227 @@ - - - CRecordForm - - - - 0 - 0 - 867 - 510 - - - - Form - - - - - - - 0 - 0 - - - - 检索条件 - - - - - - - - - - - - 按值班负责人 - - - - - - - - - - 按票名包含 - - - - - - - - - - - - - 按操作人 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - 按操作票号 - - - - - - - - - - - - - 按执行时间 - - - - - - - 按完成时间 - - - - - - - 按监护人 - - - - - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - 序号 - - - - - 操作票号 - - - - - 操作票名 - - - - - 开始时间 - - - - - 结束时间 - - - - - 操作人 - - - - - 监护人 - - - - - 值班负责人 - - - - - 执行状态 - - - - - 描述 - - - - - 备注 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 刷新 - - - - - - - 详细 - - - - - - - - - - - - - + + + CRecordForm + + + + 0 + 0 + 867 + 510 + + + + Form + + + + + + + 0 + 0 + + + + 检索条件 + + + + + + + + + + + + 按值班负责人 + + + + + + + + + + 按票名包含 + + + + + + + + + + + + + 按操作人 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 按操作票号 + + + + + + + + + + + + + 按执行时间 + + + + + + + 按完成时间 + + + + + + + 按监护人 + + + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 序号 + + + + + 操作票号 + + + + + 操作票名 + + + + + 开始时间 + + + + + 结束时间 + + + + + 操作人 + + + + + 监护人 + + + + + 值班负责人 + + + + + 执行状态 + + + + + 描述 + + + + + 备注 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 刷新 + + + + + + + 详细 + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/OrderManageWidget/CSqlDbCtrl.cpp b/product/src/gui/plugin/OrderManageWidget/CSqlDbCtrl.cpp index 05dcc508..8251f870 100644 --- a/product/src/gui/plugin/OrderManageWidget/CSqlDbCtrl.cpp +++ b/product/src/gui/plugin/OrderManageWidget/CSqlDbCtrl.cpp @@ -1,591 +1,591 @@ -#include "CSqlDbCtrl.h" -#include -#include -#include "pub_sysinfo_api/SysInfoApi.h" - -CSqlDbCtrl::CSqlDbCtrl( EDbConnType eType) -{ - m_pDbApi = new kbd_dbms::CDbApi(eType); - m_pDbApi->open(); -// m_pDbApi = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); -// m_pDbApi->open(); - -// m_pDbApi = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); -// m_pDbApi->open(); -} - -CSqlDbCtrl::~CSqlDbCtrl() -{ - if(m_pDbApi) - { - m_pDbApi->close(); - delete m_pDbApi; - } - m_pDbApi = NULL; -} - -QVector CSqlDbCtrl::readOrderPrestore() -{ - QVector vect; - if(!m_pDbApi->isOpen()) - { - return vect; - } - QString Execute = QString("SELECT id,order_name,order_desc,remarks FROM operation_order_model "); - - QSqlQuery Query; - - m_pDbApi->execute(Execute,Query); - - if(Query.isActive()) - { - while(Query.next()) - { - SOrderPreStore st; - st.id = Query.value(0).toInt(); - st.orderName = Query.value(1).toString(); - st.orderDesc = Query.value(2).toString(); - st.remarks = Query.value(3).toString(); - vect.push_back(st); - } - } - return vect; -} - -void CSqlDbCtrl::readOrderName(QList &orderName) -{ - if(!m_pDbApi->isOpen()) - { - return; - } - QString Execute = QString("SELECT order_name FROM operation_order_model "); - - QSqlQuery Query; - - m_pDbApi->execute(Execute,Query); - - if(Query.isActive()) - { - while(Query.next()) - { - orderName.push_back(Query.value(0).toString()); - } - } -} - -QVector CSqlDbCtrl::readOrderPrestoreInfo() -{ - QVector vect; - if(!m_pDbApi->isOpen()) - { - return vect; - } - QString Execute = QString("SELECT order_id,seq_no,opt_desc,key_id_tag,ctrl_value,remarks FROM operation_order_model_info "); - - QSqlQuery Query; - - m_pDbApi->execute(Execute,Query); - - if(Query.isActive()) - { - while(Query.next()) - { - SOrderPreStoreInfo st; - st.orderId = Query.value(0).toInt(); - st.seqNo = Query.value(1).toInt(); - st.optDesc = Query.value(2).toString(); - st.keyIdTag = Query.value(3).toString(); - st.ctrlValue = Query.value(4).toInt(); - st.remarks = Query.value(5).toString(); - vect.push_back(st); - } - } - - return vect; -} - -QVector CSqlDbCtrl::readOptOrderHis() -{ - QVector objs; - if (!m_pDbApi->isOpen()) - { - return objs; - } - - QSqlQuery query; - QString sqlQuery = QString("SELECT " - "id," - "order_no," - "order_name," - "order_desc," - "begin_time," - "end_time," - "remarks," - "operator," - "guardian," - "duty_manager," - "exec_state" - " FROM operation_order_his "); - - m_pDbApi->execute(sqlQuery, query); - while (query.next()) - { - SOrderHis obj; - obj.id = query.value(0).toInt(); - obj.order_no = query.value(1).toString(); - obj.order_name = query.value(2).toString(); - obj.order_desc = query.value(3).toString(); - obj.begin_time = query.value(4).toLongLong(); - obj.end_time = query.value(5).toLongLong(); - obj.remarks = query.value(6).toString(); - obj.OPERATOR = query.value(7).toString(); - obj.guardian = query.value(8).toString(); - obj.duty_manager = query.value(9).toString(); - obj.exec_state = query.value(10).toInt(); - objs.push_back(obj); - } - - return objs; -} - -bool CSqlDbCtrl::readOptOrderHisInfo(int orderId, QVector& objs) -{ - if (!m_pDbApi->isOpen()) - { - return false; - } - - QSqlQuery query; - QString sqlQuery = QString("SELECT " - "order_id," - "seq_no," - "opt_desc," - "key_id_tag," - "ctrl_value," - "remarks," - "exec_state" - " FROM operation_order_his_info " - " WHERE order_id = %1 ").arg(orderId); - - m_pDbApi->execute(sqlQuery, query); - while (query.next()) - { - SOrderHisInfo obj; - obj.order_id = query.value(0).toInt(); - obj.seq_no = query.value(1).toInt(); - obj.opt_desc = query.value(2).toString(); - obj.key_id_tag = query.value(3).toString(); - obj.ctrl_value = query.value(4).toInt(); - obj.remarks = query.value(5).toString(); - obj.exec_state = query.value(6).toInt(); - objs.push_back(obj); - } - - return true; -} - -SOrderPreStore CSqlDbCtrl::readOrderByName(const QString &orderName) -{ - SOrderPreStore vect; - if(!m_pDbApi->isOpen()) - { - return vect; - } - QString Execute = QString("SELECT id,order_name,order_desc,remarks FROM operation_order_model WHERE order_name='%1'").arg(orderName); - - QSqlQuery Query; - - m_pDbApi->execute(Execute,Query); - - if(Query.isActive()) - { - while(Query.next()) - { - vect.id = Query.value(0).toInt(); - vect.orderName = Query.value(1).toString(); - vect.orderDesc = Query.value(2).toString(); - vect.remarks = Query.value(3).toString(); - } - } - - return vect; -} - -QVector CSqlDbCtrl::readOrderInfoById(int order_id) -{ - QVector vect; - if(!m_pDbApi->isOpen()) - { - return vect; - } - QString Execute = QString("SELECT order_id,seq_no,opt_desc,key_id_tag,ctrl_value,remarks FROM operation_order_model_info WHERE order_id=%1").arg(order_id); - - QSqlQuery Query; - - m_pDbApi->execute(Execute,Query); - - if(Query.isActive()) - { - while(Query.next()) - { - SOrderPreStoreInfo st; - st.orderId = Query.value(0).toInt(); - st.seqNo = Query.value(1).toInt(); - st.optDesc = Query.value(2).toString(); - st.keyIdTag = Query.value(3).toString(); - st.ctrlValue = Query.value(4).toInt(); - st.remarks = Query.value(5).toString(); - vect.push_back(st); - } - } - - return vect; -} - -int CSqlDbCtrl::readOrderDataMaxId() -{ - int ret = -1; - if (!m_pDbApi->isOpen()) - { - return ret; - } - - QString Execute = QString("SELECT id FROM operation_order_model"); - - QSqlQuery Query; - - m_pDbApi->execute(Execute, Query); - ret = 1; - if (Query.isActive()) - { - while (Query.next()) - { - int id = Query.value(0).toInt(); - if (ret <= id) - { - ret = id + 1; - } - } - } - - return ret; -} - -bool CSqlDbCtrl::deleteOneOrderData(int order_id) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("DELETE FROM operation_order_model WHERE id=%1").arg(order_id); - ret = m_pDbApi->execute(Execute); - return ret; -} - -bool CSqlDbCtrl::deleteOneOrderData(const QString& order_name) -{ - bool ret = false; - if (!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("DELETE FROM operation_order_model WHERE order_name='%1'").arg(order_name); - ret = m_pDbApi->execute(Execute); - return ret; -} - -bool CSqlDbCtrl::isExitOrderData(int order_id) -{ - bool ret = false; - if (!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("SELECT id FROM operation_order_model WHERE id=%1").arg(order_id); - - QSqlQuery Query; - - m_pDbApi->execute(Execute, Query); - - if (Query.isActive()) - { - if (Query.next()) - { - return true; - } - } - - return false; -} - -int CSqlDbCtrl::getOrderId(const QString& order_name) -{ - int ret = -1; - if (!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("SELECT id FROM operation_order_model WHERE order_name='%1'").arg(order_name); - - QSqlQuery Query; - - m_pDbApi->execute(Execute, Query); - - if (Query.isActive()) - { - if (Query.next()) - { - return Query.value(0).toInt(); - } - } - - return -1; -} - -bool CSqlDbCtrl::insertOneOrderData(const SOrderPreStore& order) -{ - bool ret = false; - if (!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("INSERT INTO operation_order_model VALUES(%1,'%2','%3','%4')") - .arg(order.id) - .arg(order.orderName) - .arg(order.orderDesc) - .arg(order.remarks); - - ret = m_pDbApi->execute(Execute); - - return ret; -} - -bool CSqlDbCtrl::updateOneOrderData(const QString &order_name,int order_id) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("UPDATE operation_order_model SET order_name='%1' WHERE id=%2") - .arg(order_name) - .arg(order_id); - - ret = m_pDbApi->execute(Execute); - - return ret; -} - -bool CSqlDbCtrl::updateOneOrderData(const QString &order_desc, const QString &remarks, int order_id) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("UPDATE operation_order_model SET order_desc='%1',remarks='%2' WHERE id=%3") - .arg(order_desc) - .arg(remarks) - .arg(order_id); - - ret = m_pDbApi->execute(Execute); - - return ret; -} - -bool CSqlDbCtrl::updateOneOrderInfoData(const SOrderPreStoreInfo& info) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("UPDATE operation_order_model_info SET opt_desc='%1',key_id_tag='%2',ctrl_value=%3,remarks='%4' " - "WHERE order_id=%5 and seq_no=%6") - .arg(info.optDesc) - .arg(info.keyIdTag) - .arg(info.ctrlValue) - .arg(info.remarks) - .arg(info.orderId) - .arg(info.seqNo); - - ret = m_pDbApi->execute(Execute); - - return ret; -} - -bool CSqlDbCtrl::deleteOneOrderInfoData(int order_id, int seq_no) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("DELETE FROM operation_order_model_info WHERE order_id=%1 and seq_no=%2") - .arg(order_id) - .arg(seq_no); - - ret = m_pDbApi->execute(Execute); - - return ret; -} - -bool CSqlDbCtrl::deleteAllOrderInfoData(int order_id) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("DELETE FROM operation_order_model_info WHERE order_id=%1") - .arg(order_id); - - ret = m_pDbApi->execute(Execute); - - return ret; -} - -bool CSqlDbCtrl::insertOneOrderInfoData(const SOrderPreStoreInfo &info) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("INSERT INTO operation_order_model_info VALUES(%1,%2,'%3','%4',%5,'%6')") - .arg(info.orderId) - .arg(info.seqNo) - .arg(info.optDesc) - .arg(info.keyIdTag) - .arg(info.ctrlValue) - .arg(info.remarks); - - ret = m_pDbApi->execute(Execute); - return ret; -} - -int CSqlDbCtrl::readOrderHisMixID() -{ - int ret = -1; - if(!m_pDbApi->isOpen()) - { - return ret; - } - - ret = 1; - - QString Execute = QString("SELECT id FROM operation_order_his"); - - QSqlQuery Query; - - m_pDbApi->execute(Execute,Query); - - if(Query.isActive()) - { - while (Query.next()) - { - int id = Query.value(0).toInt(); - if (ret <= id) - { - ret = id + 1; - } - } - } - - return ret; -} - -bool CSqlDbCtrl::insertOneOrderHisData(const SOrderHis &info) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("INSERT INTO operation_order_his VALUES(%1,'%2','%3','%4',%5,%6,'%7','%8','%9','%10',%11)") - .arg(info.id) - .arg(info.order_no) - .arg(info.order_name) - .arg(info.order_desc) - .arg(info.begin_time) - .arg(info.end_time) - .arg(info.remarks) - .arg(info.OPERATOR) - .arg(info.guardian) - .arg(info.duty_manager) - .arg(info.exec_state); - - ret = m_pDbApi->execute(Execute); - - return ret; -} - -bool CSqlDbCtrl::insertOneOrderHisInfoData(const SOrderHisInfo &info) -{ - bool ret = false; - if(!m_pDbApi->isOpen()) - { - return ret; - } - QString Execute = QString("INSERT INTO operation_order_his_info VALUES(%1,%2,'%3','%4',%5,'%6',%7)") - .arg(info.order_id) - .arg(info.seq_no) - .arg(info.opt_desc) - .arg(info.key_id_tag) - .arg(info.ctrl_value) - .arg(info.remarks) - .arg(info.exec_state); - - ret = m_pDbApi->execute(Execute); - - return ret; -} - -QMap CSqlDbCtrl::readUserInfo() -{ - QMap result; - if(!m_pDbApi->isOpen()) - { - return result; - } - QString Execute = QString("SELECT PERM_ID,PERM_ALIAS FROM rm_user_def WHERE PERM_ID>10"); - - QSqlQuery Query; - - m_pDbApi->execute(Execute,Query); - - if(Query.isActive()) - { - while(Query.next()) - { - result.insert(Query.value(0).toInt(), Query.value(1).toString()); - } - } - - return result; -} - -QString CSqlDbCtrl::readSignatureData(int perm_id) -{ - QString byteArray; - if(!m_pDbApi->isOpen()) - { - return byteArray; - } - - QString Execute = QString("SELECT data_base64 FROM rm_user_signature_info WHERE user_id = '%1';").arg(perm_id); - - QSqlQuery Query; - - m_pDbApi->execute(Execute, Query); - - if(Query.isActive()) - { - while(Query.next()) - { - byteArray = Query.value(0).toString(); - } - } - return byteArray; -} +#include "CSqlDbCtrl.h" +#include +#include +#include "pub_sysinfo_api/SysInfoApi.h" + +CSqlDbCtrl::CSqlDbCtrl( EDbConnType eType) +{ + m_pDbApi = new kbd_dbms::CDbApi(eType); + m_pDbApi->open(); +// m_pDbApi = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); +// m_pDbApi->open(); + +// m_pDbApi = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); +// m_pDbApi->open(); +} + +CSqlDbCtrl::~CSqlDbCtrl() +{ + if(m_pDbApi) + { + m_pDbApi->close(); + delete m_pDbApi; + } + m_pDbApi = NULL; +} + +QVector CSqlDbCtrl::readOrderPrestore() +{ + QVector vect; + if(!m_pDbApi->isOpen()) + { + return vect; + } + QString Execute = QString("SELECT id,order_name,order_desc,remarks FROM operation_order_model "); + + QSqlQuery Query; + + m_pDbApi->execute(Execute,Query); + + if(Query.isActive()) + { + while(Query.next()) + { + SOrderPreStore st; + st.id = Query.value(0).toInt(); + st.orderName = Query.value(1).toString(); + st.orderDesc = Query.value(2).toString(); + st.remarks = Query.value(3).toString(); + vect.push_back(st); + } + } + return vect; +} + +void CSqlDbCtrl::readOrderName(QList &orderName) +{ + if(!m_pDbApi->isOpen()) + { + return; + } + QString Execute = QString("SELECT order_name FROM operation_order_model "); + + QSqlQuery Query; + + m_pDbApi->execute(Execute,Query); + + if(Query.isActive()) + { + while(Query.next()) + { + orderName.push_back(Query.value(0).toString()); + } + } +} + +QVector CSqlDbCtrl::readOrderPrestoreInfo() +{ + QVector vect; + if(!m_pDbApi->isOpen()) + { + return vect; + } + QString Execute = QString("SELECT order_id,seq_no,opt_desc,key_id_tag,ctrl_value,remarks FROM operation_order_model_info "); + + QSqlQuery Query; + + m_pDbApi->execute(Execute,Query); + + if(Query.isActive()) + { + while(Query.next()) + { + SOrderPreStoreInfo st; + st.orderId = Query.value(0).toInt(); + st.seqNo = Query.value(1).toInt(); + st.optDesc = Query.value(2).toString(); + st.keyIdTag = Query.value(3).toString(); + st.ctrlValue = Query.value(4).toInt(); + st.remarks = Query.value(5).toString(); + vect.push_back(st); + } + } + + return vect; +} + +QVector CSqlDbCtrl::readOptOrderHis() +{ + QVector objs; + if (!m_pDbApi->isOpen()) + { + return objs; + } + + QSqlQuery query; + QString sqlQuery = QString("SELECT " + "id," + "order_no," + "order_name," + "order_desc," + "begin_time," + "end_time," + "remarks," + "operator," + "guardian," + "duty_manager," + "exec_state" + " FROM operation_order_his "); + + m_pDbApi->execute(sqlQuery, query); + while (query.next()) + { + SOrderHis obj; + obj.id = query.value(0).toInt(); + obj.order_no = query.value(1).toString(); + obj.order_name = query.value(2).toString(); + obj.order_desc = query.value(3).toString(); + obj.begin_time = query.value(4).toLongLong(); + obj.end_time = query.value(5).toLongLong(); + obj.remarks = query.value(6).toString(); + obj.OPERATOR = query.value(7).toString(); + obj.guardian = query.value(8).toString(); + obj.duty_manager = query.value(9).toString(); + obj.exec_state = query.value(10).toInt(); + objs.push_back(obj); + } + + return objs; +} + +bool CSqlDbCtrl::readOptOrderHisInfo(int orderId, QVector& objs) +{ + if (!m_pDbApi->isOpen()) + { + return false; + } + + QSqlQuery query; + QString sqlQuery = QString("SELECT " + "order_id," + "seq_no," + "opt_desc," + "key_id_tag," + "ctrl_value," + "remarks," + "exec_state" + " FROM operation_order_his_info " + " WHERE order_id = %1 ").arg(orderId); + + m_pDbApi->execute(sqlQuery, query); + while (query.next()) + { + SOrderHisInfo obj; + obj.order_id = query.value(0).toInt(); + obj.seq_no = query.value(1).toInt(); + obj.opt_desc = query.value(2).toString(); + obj.key_id_tag = query.value(3).toString(); + obj.ctrl_value = query.value(4).toInt(); + obj.remarks = query.value(5).toString(); + obj.exec_state = query.value(6).toInt(); + objs.push_back(obj); + } + + return true; +} + +SOrderPreStore CSqlDbCtrl::readOrderByName(const QString &orderName) +{ + SOrderPreStore vect; + if(!m_pDbApi->isOpen()) + { + return vect; + } + QString Execute = QString("SELECT id,order_name,order_desc,remarks FROM operation_order_model WHERE order_name='%1'").arg(orderName); + + QSqlQuery Query; + + m_pDbApi->execute(Execute,Query); + + if(Query.isActive()) + { + while(Query.next()) + { + vect.id = Query.value(0).toInt(); + vect.orderName = Query.value(1).toString(); + vect.orderDesc = Query.value(2).toString(); + vect.remarks = Query.value(3).toString(); + } + } + + return vect; +} + +QVector CSqlDbCtrl::readOrderInfoById(int order_id) +{ + QVector vect; + if(!m_pDbApi->isOpen()) + { + return vect; + } + QString Execute = QString("SELECT order_id,seq_no,opt_desc,key_id_tag,ctrl_value,remarks FROM operation_order_model_info WHERE order_id=%1").arg(order_id); + + QSqlQuery Query; + + m_pDbApi->execute(Execute,Query); + + if(Query.isActive()) + { + while(Query.next()) + { + SOrderPreStoreInfo st; + st.orderId = Query.value(0).toInt(); + st.seqNo = Query.value(1).toInt(); + st.optDesc = Query.value(2).toString(); + st.keyIdTag = Query.value(3).toString(); + st.ctrlValue = Query.value(4).toInt(); + st.remarks = Query.value(5).toString(); + vect.push_back(st); + } + } + + return vect; +} + +int CSqlDbCtrl::readOrderDataMaxId() +{ + int ret = -1; + if (!m_pDbApi->isOpen()) + { + return ret; + } + + QString Execute = QString("SELECT id FROM operation_order_model"); + + QSqlQuery Query; + + m_pDbApi->execute(Execute, Query); + ret = 1; + if (Query.isActive()) + { + while (Query.next()) + { + int id = Query.value(0).toInt(); + if (ret <= id) + { + ret = id + 1; + } + } + } + + return ret; +} + +bool CSqlDbCtrl::deleteOneOrderData(int order_id) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("DELETE FROM operation_order_model WHERE id=%1").arg(order_id); + ret = m_pDbApi->execute(Execute); + return ret; +} + +bool CSqlDbCtrl::deleteOneOrderData(const QString& order_name) +{ + bool ret = false; + if (!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("DELETE FROM operation_order_model WHERE order_name='%1'").arg(order_name); + ret = m_pDbApi->execute(Execute); + return ret; +} + +bool CSqlDbCtrl::isExitOrderData(int order_id) +{ + bool ret = false; + if (!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("SELECT id FROM operation_order_model WHERE id=%1").arg(order_id); + + QSqlQuery Query; + + m_pDbApi->execute(Execute, Query); + + if (Query.isActive()) + { + if (Query.next()) + { + return true; + } + } + + return false; +} + +int CSqlDbCtrl::getOrderId(const QString& order_name) +{ + int ret = -1; + if (!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("SELECT id FROM operation_order_model WHERE order_name='%1'").arg(order_name); + + QSqlQuery Query; + + m_pDbApi->execute(Execute, Query); + + if (Query.isActive()) + { + if (Query.next()) + { + return Query.value(0).toInt(); + } + } + + return -1; +} + +bool CSqlDbCtrl::insertOneOrderData(const SOrderPreStore& order) +{ + bool ret = false; + if (!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("INSERT INTO operation_order_model VALUES(%1,'%2','%3','%4')") + .arg(order.id) + .arg(order.orderName) + .arg(order.orderDesc) + .arg(order.remarks); + + ret = m_pDbApi->execute(Execute); + + return ret; +} + +bool CSqlDbCtrl::updateOneOrderData(const QString &order_name,int order_id) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("UPDATE operation_order_model SET order_name='%1' WHERE id=%2") + .arg(order_name) + .arg(order_id); + + ret = m_pDbApi->execute(Execute); + + return ret; +} + +bool CSqlDbCtrl::updateOneOrderData(const QString &order_desc, const QString &remarks, int order_id) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("UPDATE operation_order_model SET order_desc='%1',remarks='%2' WHERE id=%3") + .arg(order_desc) + .arg(remarks) + .arg(order_id); + + ret = m_pDbApi->execute(Execute); + + return ret; +} + +bool CSqlDbCtrl::updateOneOrderInfoData(const SOrderPreStoreInfo& info) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("UPDATE operation_order_model_info SET opt_desc='%1',key_id_tag='%2',ctrl_value=%3,remarks='%4' " + "WHERE order_id=%5 and seq_no=%6") + .arg(info.optDesc) + .arg(info.keyIdTag) + .arg(info.ctrlValue) + .arg(info.remarks) + .arg(info.orderId) + .arg(info.seqNo); + + ret = m_pDbApi->execute(Execute); + + return ret; +} + +bool CSqlDbCtrl::deleteOneOrderInfoData(int order_id, int seq_no) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("DELETE FROM operation_order_model_info WHERE order_id=%1 and seq_no=%2") + .arg(order_id) + .arg(seq_no); + + ret = m_pDbApi->execute(Execute); + + return ret; +} + +bool CSqlDbCtrl::deleteAllOrderInfoData(int order_id) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("DELETE FROM operation_order_model_info WHERE order_id=%1") + .arg(order_id); + + ret = m_pDbApi->execute(Execute); + + return ret; +} + +bool CSqlDbCtrl::insertOneOrderInfoData(const SOrderPreStoreInfo &info) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("INSERT INTO operation_order_model_info VALUES(%1,%2,'%3','%4',%5,'%6')") + .arg(info.orderId) + .arg(info.seqNo) + .arg(info.optDesc) + .arg(info.keyIdTag) + .arg(info.ctrlValue) + .arg(info.remarks); + + ret = m_pDbApi->execute(Execute); + return ret; +} + +int CSqlDbCtrl::readOrderHisMixID() +{ + int ret = -1; + if(!m_pDbApi->isOpen()) + { + return ret; + } + + ret = 1; + + QString Execute = QString("SELECT id FROM operation_order_his"); + + QSqlQuery Query; + + m_pDbApi->execute(Execute,Query); + + if(Query.isActive()) + { + while (Query.next()) + { + int id = Query.value(0).toInt(); + if (ret <= id) + { + ret = id + 1; + } + } + } + + return ret; +} + +bool CSqlDbCtrl::insertOneOrderHisData(const SOrderHis &info) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("INSERT INTO operation_order_his VALUES(%1,'%2','%3','%4',%5,%6,'%7','%8','%9','%10',%11)") + .arg(info.id) + .arg(info.order_no) + .arg(info.order_name) + .arg(info.order_desc) + .arg(info.begin_time) + .arg(info.end_time) + .arg(info.remarks) + .arg(info.OPERATOR) + .arg(info.guardian) + .arg(info.duty_manager) + .arg(info.exec_state); + + ret = m_pDbApi->execute(Execute); + + return ret; +} + +bool CSqlDbCtrl::insertOneOrderHisInfoData(const SOrderHisInfo &info) +{ + bool ret = false; + if(!m_pDbApi->isOpen()) + { + return ret; + } + QString Execute = QString("INSERT INTO operation_order_his_info VALUES(%1,%2,'%3','%4',%5,'%6',%7)") + .arg(info.order_id) + .arg(info.seq_no) + .arg(info.opt_desc) + .arg(info.key_id_tag) + .arg(info.ctrl_value) + .arg(info.remarks) + .arg(info.exec_state); + + ret = m_pDbApi->execute(Execute); + + return ret; +} + +QMap CSqlDbCtrl::readUserInfo() +{ + QMap result; + if(!m_pDbApi->isOpen()) + { + return result; + } + QString Execute = QString("SELECT PERM_ID,PERM_ALIAS FROM rm_user_def WHERE PERM_ID>10"); + + QSqlQuery Query; + + m_pDbApi->execute(Execute,Query); + + if(Query.isActive()) + { + while(Query.next()) + { + result.insert(Query.value(0).toInt(), Query.value(1).toString()); + } + } + + return result; +} + +QString CSqlDbCtrl::readSignatureData(int perm_id) +{ + QString byteArray; + if(!m_pDbApi->isOpen()) + { + return byteArray; + } + + QString Execute = QString("SELECT data_base64 FROM rm_user_signature_info WHERE user_id = '%1';").arg(perm_id); + + QSqlQuery Query; + + m_pDbApi->execute(Execute, Query); + + if(Query.isActive()) + { + while(Query.next()) + { + byteArray = Query.value(0).toString(); + } + } + return byteArray; +} diff --git a/product/src/gui/plugin/OrderManageWidget/CSqlDbCtrl.h b/product/src/gui/plugin/OrderManageWidget/CSqlDbCtrl.h index 80bb0d29..22bed0fc 100644 --- a/product/src/gui/plugin/OrderManageWidget/CSqlDbCtrl.h +++ b/product/src/gui/plugin/OrderManageWidget/CSqlDbCtrl.h @@ -1,49 +1,49 @@ -#ifndef CSQLDBCTRL_H -#define CSQLDBCTRL_H - -#include "db_api_ex/CDbApi.h" -#include "SDbTableDefine.h" -#include - -class CSqlDbCtrl -{ -public: - CSqlDbCtrl(EDbConnType eType = DB_CONN_MODEL_READ);//DB_CONN_MODEL_WRITE - ~CSqlDbCtrl(); - - QVector readOrderPrestore(); - void readOrderName(QList& orderName); - QVector readOrderPrestoreInfo(); - - QVector readOptOrderHis(); - bool readOptOrderHisInfo(int orderId,QVector& objs); - - - SOrderPreStore readOrderByName(const QString& orderName); - QVector readOrderInfoById(int order_id); - - int readOrderDataMaxId(); - bool deleteOneOrderData(int order_id); - bool deleteOneOrderData(const QString& order_name); - bool isExitOrderData(int order_id); - int getOrderId(const QString& order_name); - bool insertOneOrderData(const SOrderPreStore& order); - bool updateOneOrderData(const QString& order_name, int order_id); - bool updateOneOrderData(const QString& order_desc, const QString& remarks, int order_id); - bool updateOneOrderInfoData(const SOrderPreStoreInfo& info); - bool deleteOneOrderInfoData(int order_id, int seq_no); - bool deleteAllOrderInfoData(int order_id); - bool insertOneOrderInfoData(const SOrderPreStoreInfo& info); - - int readOrderHisMixID(); - bool insertOneOrderHisData(const SOrderHis& info); - bool insertOneOrderHisInfoData(const SOrderHisInfo& info); - - QMap readUserInfo(); - QString readSignatureData(int perm_id); - -private: - kbd_dbms::CDbApi * m_pDbApi; -}; - -#endif // CSQLDBCTRL_H +#ifndef CSQLDBCTRL_H +#define CSQLDBCTRL_H + +#include "db_api_ex/CDbApi.h" +#include "SDbTableDefine.h" +#include + +class CSqlDbCtrl +{ +public: + CSqlDbCtrl(EDbConnType eType = DB_CONN_MODEL_READ);//DB_CONN_MODEL_WRITE + ~CSqlDbCtrl(); + + QVector readOrderPrestore(); + void readOrderName(QList& orderName); + QVector readOrderPrestoreInfo(); + + QVector readOptOrderHis(); + bool readOptOrderHisInfo(int orderId,QVector& objs); + + + SOrderPreStore readOrderByName(const QString& orderName); + QVector readOrderInfoById(int order_id); + + int readOrderDataMaxId(); + bool deleteOneOrderData(int order_id); + bool deleteOneOrderData(const QString& order_name); + bool isExitOrderData(int order_id); + int getOrderId(const QString& order_name); + bool insertOneOrderData(const SOrderPreStore& order); + bool updateOneOrderData(const QString& order_name, int order_id); + bool updateOneOrderData(const QString& order_desc, const QString& remarks, int order_id); + bool updateOneOrderInfoData(const SOrderPreStoreInfo& info); + bool deleteOneOrderInfoData(int order_id, int seq_no); + bool deleteAllOrderInfoData(int order_id); + bool insertOneOrderInfoData(const SOrderPreStoreInfo& info); + + int readOrderHisMixID(); + bool insertOneOrderHisData(const SOrderHis& info); + bool insertOneOrderHisInfoData(const SOrderHisInfo& info); + + QMap readUserInfo(); + QString readSignatureData(int perm_id); + +private: + kbd_dbms::CDbApi * m_pDbApi; +}; + +#endif // CSQLDBCTRL_H diff --git a/product/src/gui/plugin/OrderManageWidget/CTextPrinter.cpp b/product/src/gui/plugin/OrderManageWidget/CTextPrinter.cpp index 494ce746..c5e5250a 100644 --- a/product/src/gui/plugin/OrderManageWidget/CTextPrinter.cpp +++ b/product/src/gui/plugin/OrderManageWidget/CTextPrinter.cpp @@ -1,396 +1,396 @@ -#include "CTextPrinter.h" - -#include -#include -#include -#include -#include -#include -#include - -static inline double mmToInches(double mm) -{ - return mm * 0.039370147; -} - -CTextPrinter::CTextPrinter(QObject *parent) - : QObject(parent) -{ - m_leftmargin = 15.0; - m_rightmargin = 15.0; - m_topmargin = 15.0; - m_bottommargin = 15.0; - m_spacing = 5.0; - m_footersize = 0.0; - m_footerrule = 0.5; - - m_tempDoc = NULL, - m_parent = qobject_cast(parent); - - m_printer = new QPrinter(QPrinter::HighResolution); - m_printer->setFullPage(true); - m_printer->setOrientation(QPrinter::Landscape); - m_printer->setPageSize(QPrinter::A4); -} - -CTextPrinter::~CTextPrinter() -{ - if(m_printer) - { - delete m_printer; - m_printer = NULL; - } -} - -QPrinter::PageSize CTextPrinter::pageSize() const -{ - return m_printer->pageSize(); -} - -void CTextPrinter::setPageSize(QPrinter::PageSize size) -{ - m_printer->setPageSize(size); -} - -QPrinter::Orientation CTextPrinter::orientation() const -{ - return m_printer->orientation(); -} - -void CTextPrinter::setOrientation(QPrinter::Orientation orientation) -{ - m_printer->setOrientation(orientation); -} - -double CTextPrinter::leftMargin() const -{ - return m_leftmargin; -} - -void CTextPrinter::setLeftMargin(double margin) -{ - if((margin > 0) && (margin < m_printer->paperRect().width() / 2)) - { - m_leftmargin = margin; - } - else - { - m_leftmargin = 0; - } -} - -double CTextPrinter::rightMargin() const -{ - return m_rightmargin; -} - -void CTextPrinter::setRightMargin(double margin) -{ - if((margin > 0) && (margin < m_printer->paperRect().width() / 2)) - { - m_rightmargin = margin; - } - else - { - m_rightmargin = 0; - } -} - -double CTextPrinter::topMargin() const -{ - return m_topmargin; -} - -void CTextPrinter::setTopMargin(double margin) -{ - if((margin > 0) && (margin < m_printer->paperRect().height() / 4)) - { - m_topmargin = margin; - } - else - { - m_topmargin = 0; - } -} - -double CTextPrinter::bottomMargin() const -{ - return m_bottommargin; -} - -void CTextPrinter::setBottomMargin(double margin) -{ - if((margin > 0) && (margin < m_printer->paperRect().height() / 4)) - { - m_bottommargin = margin; - } - else - { - m_bottommargin = 0; - } -} - -void CTextPrinter::setMargins(double margin) -{ - if ((margin > 0) - && (margin < m_printer->paperRect().height() / 2) - && (margin < m_printer->paperRect().width() / 2)) - { - m_leftmargin = m_rightmargin = m_topmargin = m_bottommargin = margin; - } - else - { - m_leftmargin = m_rightmargin = m_topmargin = m_bottommargin = 0; - } -} - -double CTextPrinter::spacing() const -{ - return m_spacing; -} - -void CTextPrinter::setSpacing(double spacing) -{ - if((spacing > 0) && (spacing <= m_printer->paperRect().height() / 8)) - { - m_spacing = spacing; - } - else - { - m_spacing = 0; - } -} - -double CTextPrinter::footerSize() const -{ - return m_footersize; -} - -void CTextPrinter::setFooterSize(double size) -{ - if((size > 0) && (size <= m_printer->paperRect().height() / 8)) - { - m_footersize = size; - } - else - { - m_footersize = 0; - } -} - -double CTextPrinter::footerRule() const -{ - return m_footerrule; -} - -void CTextPrinter::setFooterRule(double pointsize) -{ - m_footerrule = qMax(0.0, pointsize); -} - -const QString &CTextPrinter::footerText() const -{ - return m_footertext; -} - -void CTextPrinter::setFooterText(const QString &text) -{ - m_footertext = text; -} - -int CTextPrinter::print(const QTextDocument *document, const QString &caption) -{ - if(!document) - return -1; - - m_printer->setOutputFormat(QPrinter::NativeFormat); - m_printer->setOutputFileName(QString()); - - QPrintDialog dialog(m_printer, m_parent); - dialog.setWindowTitle(caption); - if(dialog.exec() == QDialog::Rejected) - return 0; - - m_tempDoc = document->clone(); - int ret = print(m_printer); - - delete m_tempDoc; - m_tempDoc = 0; - return ret; -} - -void CTextPrinter::preview(const QTextDocument *document, const QString &caption) -{ - if(!document) - return; - - QPrintPreviewDialog *dialog = new QPrintPreviewDialog(m_printer, m_parent); - dialog->setFixedSize(920,640); - dialog->setWindowTitle(caption); - connect(dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print(QPrinter*))); - - m_tempDoc = document->clone(); - dialog->exec(); - - delete m_tempDoc; - m_tempDoc = 0; - - delete dialog; -} - -QRectF CTextPrinter::paperRect(QPaintDevice *device) -{ - QRectF rect = m_printer->paperRect(); - rect.setWidth(rect.width() * device->logicalDpiX() / m_printer->logicalDpiX()); - rect.setHeight(rect.height() * device->logicalDpiY() / m_printer->logicalDpiY()); - - return rect; -} - -QRectF CTextPrinter::contentRect(QPaintDevice *device) -{ - QRectF rect = paperRect(device); - - rect.adjust(mmToInches(m_leftmargin) * device->logicalDpiX(), - mmToInches(m_topmargin) * device->logicalDpiY(), - -mmToInches(m_rightmargin) * device->logicalDpiX(), - -mmToInches(m_bottommargin) * device->logicalDpiY()); - - if (m_footersize > 0) - { - rect.adjust(0, 0, 0, -mmToInches(m_footersize) * device->logicalDpiY()); - rect.adjust(0, 0, 0, -mmToInches(m_spacing) * device->logicalDpiY()); - } - - return rect; -} - -QRectF CTextPrinter::footerRect(QPaintDevice *device) -{ - QRectF rect = paperRect(device); - rect.adjust(mmToInches(m_leftmargin) * device->logicalDpiX(), 0, - -mmToInches(m_rightmargin) * device->logicalDpiX(), - -mmToInches(m_bottommargin) * device->logicalDpiY()); - - rect.setTop(rect.bottom() - mmToInches(m_footersize) * device->logicalDpiY()); - - return rect; -} - -int CTextPrinter::print(QPrinter *printer) -{ - if(!printer || !m_tempDoc) - { - return -1; - } - m_tempDoc->setUseDesignMetrics(true); - m_tempDoc->documentLayout()->setPaintDevice(printer); - m_tempDoc->setPageSize(contentRect(printer).size()); - - QTextFrameFormat fmt = m_tempDoc->rootFrame()->frameFormat(); - fmt.setMargin(0); - m_tempDoc->rootFrame()->setFrameFormat(fmt); - - int doccopies; - int pagecopies; - if(printer->collateCopies()) - { - doccopies = 1; - pagecopies = printer->numCopies(); - } - else - { - doccopies = printer->numCopies(); - pagecopies = 1; - } - - int firstpage = printer->fromPage(); - int lastpage = printer->toPage(); - if(firstpage == 0 && lastpage == 0) - { - firstpage = 1; - lastpage = m_tempDoc->pageCount(); - } - - bool ascending = true; - if(printer->pageOrder() == QPrinter::LastPageFirst) - { - int tmp = firstpage; - firstpage = lastpage; - lastpage = tmp; - ascending = false; - } - - QPainter painter(printer); - painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, true); - for(int dc=0; dcprinterState() == QPrinter::Aborted || printer->printerState() == QPrinter::Error) - { - return -1; - } - - paintPage(&painter, m_tempDoc, pagenum); - if(pc < pagecopies-1) - printer->newPage(); - } - if(pagenum == lastpage) - break; - if(ascending) - pagenum++; - else - pagenum--; - printer->newPage(); - } - - if(dc < doccopies-1) - printer->newPage(); - } - return 1; -} - -void CTextPrinter::paintPage(QPainter *painter, QTextDocument *document, int pagenum) -{ - QRectF rect; - double onepoint = painter->device()->logicalDpiY() / 72.0; - - if(m_footersize > 0) - { - rect = footerRect(painter->device()); - if(m_footerrule > 0.0) - { - painter->save(); - painter->translate(0, -onepoint + (-m_footerrule * onepoint / 2.0)); - painter->setPen(QPen(Qt::black, m_footerrule * onepoint)); - painter->drawLine(rect.topLeft(), rect.topRight()); - painter->restore(); - } - QString footer = m_footertext; - footer.replace("&page;", QString::number(pagenum)); - painter->save(); - painter->translate(rect.left(), rect.top()); - QRectF clip(0, 0, rect.width(), rect.height()); - QTextDocument doc; - doc.setUseDesignMetrics(true); - doc.setHtml(footer); - doc.documentLayout()->setPaintDevice(painter->device()); - doc.setPageSize(rect.size()); - doc.drawContents(painter, clip); - painter->restore(); - } - - painter->save(); - - rect = contentRect(painter->device()); - painter->translate(rect.left(), rect.top() - (pagenum-1) * rect.height()); - QRectF clip(0, (pagenum-1) * rect.height(), rect.width(), rect.height()); - document->drawContents(painter, clip); - - painter->restore(); -} - +#include "CTextPrinter.h" + +#include +#include +#include +#include +#include +#include +#include + +static inline double mmToInches(double mm) +{ + return mm * 0.039370147; +} + +CTextPrinter::CTextPrinter(QObject *parent) + : QObject(parent) +{ + m_leftmargin = 15.0; + m_rightmargin = 15.0; + m_topmargin = 15.0; + m_bottommargin = 15.0; + m_spacing = 5.0; + m_footersize = 0.0; + m_footerrule = 0.5; + + m_tempDoc = NULL, + m_parent = qobject_cast(parent); + + m_printer = new QPrinter(QPrinter::HighResolution); + m_printer->setFullPage(true); + m_printer->setOrientation(QPrinter::Landscape); + m_printer->setPageSize(QPrinter::A4); +} + +CTextPrinter::~CTextPrinter() +{ + if(m_printer) + { + delete m_printer; + m_printer = NULL; + } +} + +QPrinter::PageSize CTextPrinter::pageSize() const +{ + return m_printer->pageSize(); +} + +void CTextPrinter::setPageSize(QPrinter::PageSize size) +{ + m_printer->setPageSize(size); +} + +QPrinter::Orientation CTextPrinter::orientation() const +{ + return m_printer->orientation(); +} + +void CTextPrinter::setOrientation(QPrinter::Orientation orientation) +{ + m_printer->setOrientation(orientation); +} + +double CTextPrinter::leftMargin() const +{ + return m_leftmargin; +} + +void CTextPrinter::setLeftMargin(double margin) +{ + if((margin > 0) && (margin < m_printer->paperRect().width() / 2)) + { + m_leftmargin = margin; + } + else + { + m_leftmargin = 0; + } +} + +double CTextPrinter::rightMargin() const +{ + return m_rightmargin; +} + +void CTextPrinter::setRightMargin(double margin) +{ + if((margin > 0) && (margin < m_printer->paperRect().width() / 2)) + { + m_rightmargin = margin; + } + else + { + m_rightmargin = 0; + } +} + +double CTextPrinter::topMargin() const +{ + return m_topmargin; +} + +void CTextPrinter::setTopMargin(double margin) +{ + if((margin > 0) && (margin < m_printer->paperRect().height() / 4)) + { + m_topmargin = margin; + } + else + { + m_topmargin = 0; + } +} + +double CTextPrinter::bottomMargin() const +{ + return m_bottommargin; +} + +void CTextPrinter::setBottomMargin(double margin) +{ + if((margin > 0) && (margin < m_printer->paperRect().height() / 4)) + { + m_bottommargin = margin; + } + else + { + m_bottommargin = 0; + } +} + +void CTextPrinter::setMargins(double margin) +{ + if ((margin > 0) + && (margin < m_printer->paperRect().height() / 2) + && (margin < m_printer->paperRect().width() / 2)) + { + m_leftmargin = m_rightmargin = m_topmargin = m_bottommargin = margin; + } + else + { + m_leftmargin = m_rightmargin = m_topmargin = m_bottommargin = 0; + } +} + +double CTextPrinter::spacing() const +{ + return m_spacing; +} + +void CTextPrinter::setSpacing(double spacing) +{ + if((spacing > 0) && (spacing <= m_printer->paperRect().height() / 8)) + { + m_spacing = spacing; + } + else + { + m_spacing = 0; + } +} + +double CTextPrinter::footerSize() const +{ + return m_footersize; +} + +void CTextPrinter::setFooterSize(double size) +{ + if((size > 0) && (size <= m_printer->paperRect().height() / 8)) + { + m_footersize = size; + } + else + { + m_footersize = 0; + } +} + +double CTextPrinter::footerRule() const +{ + return m_footerrule; +} + +void CTextPrinter::setFooterRule(double pointsize) +{ + m_footerrule = qMax(0.0, pointsize); +} + +const QString &CTextPrinter::footerText() const +{ + return m_footertext; +} + +void CTextPrinter::setFooterText(const QString &text) +{ + m_footertext = text; +} + +int CTextPrinter::print(const QTextDocument *document, const QString &caption) +{ + if(!document) + return -1; + + m_printer->setOutputFormat(QPrinter::NativeFormat); + m_printer->setOutputFileName(QString()); + + QPrintDialog dialog(m_printer, m_parent); + dialog.setWindowTitle(caption); + if(dialog.exec() == QDialog::Rejected) + return 0; + + m_tempDoc = document->clone(); + int ret = print(m_printer); + + delete m_tempDoc; + m_tempDoc = 0; + return ret; +} + +void CTextPrinter::preview(const QTextDocument *document, const QString &caption) +{ + if(!document) + return; + + QPrintPreviewDialog *dialog = new QPrintPreviewDialog(m_printer, m_parent); + dialog->setFixedSize(920,640); + dialog->setWindowTitle(caption); + connect(dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print(QPrinter*))); + + m_tempDoc = document->clone(); + dialog->exec(); + + delete m_tempDoc; + m_tempDoc = 0; + + delete dialog; +} + +QRectF CTextPrinter::paperRect(QPaintDevice *device) +{ + QRectF rect = m_printer->paperRect(); + rect.setWidth(rect.width() * device->logicalDpiX() / m_printer->logicalDpiX()); + rect.setHeight(rect.height() * device->logicalDpiY() / m_printer->logicalDpiY()); + + return rect; +} + +QRectF CTextPrinter::contentRect(QPaintDevice *device) +{ + QRectF rect = paperRect(device); + + rect.adjust(mmToInches(m_leftmargin) * device->logicalDpiX(), + mmToInches(m_topmargin) * device->logicalDpiY(), + -mmToInches(m_rightmargin) * device->logicalDpiX(), + -mmToInches(m_bottommargin) * device->logicalDpiY()); + + if (m_footersize > 0) + { + rect.adjust(0, 0, 0, -mmToInches(m_footersize) * device->logicalDpiY()); + rect.adjust(0, 0, 0, -mmToInches(m_spacing) * device->logicalDpiY()); + } + + return rect; +} + +QRectF CTextPrinter::footerRect(QPaintDevice *device) +{ + QRectF rect = paperRect(device); + rect.adjust(mmToInches(m_leftmargin) * device->logicalDpiX(), 0, + -mmToInches(m_rightmargin) * device->logicalDpiX(), + -mmToInches(m_bottommargin) * device->logicalDpiY()); + + rect.setTop(rect.bottom() - mmToInches(m_footersize) * device->logicalDpiY()); + + return rect; +} + +int CTextPrinter::print(QPrinter *printer) +{ + if(!printer || !m_tempDoc) + { + return -1; + } + m_tempDoc->setUseDesignMetrics(true); + m_tempDoc->documentLayout()->setPaintDevice(printer); + m_tempDoc->setPageSize(contentRect(printer).size()); + + QTextFrameFormat fmt = m_tempDoc->rootFrame()->frameFormat(); + fmt.setMargin(0); + m_tempDoc->rootFrame()->setFrameFormat(fmt); + + int doccopies; + int pagecopies; + if(printer->collateCopies()) + { + doccopies = 1; + pagecopies = printer->numCopies(); + } + else + { + doccopies = printer->numCopies(); + pagecopies = 1; + } + + int firstpage = printer->fromPage(); + int lastpage = printer->toPage(); + if(firstpage == 0 && lastpage == 0) + { + firstpage = 1; + lastpage = m_tempDoc->pageCount(); + } + + bool ascending = true; + if(printer->pageOrder() == QPrinter::LastPageFirst) + { + int tmp = firstpage; + firstpage = lastpage; + lastpage = tmp; + ascending = false; + } + + QPainter painter(printer); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, true); + for(int dc=0; dcprinterState() == QPrinter::Aborted || printer->printerState() == QPrinter::Error) + { + return -1; + } + + paintPage(&painter, m_tempDoc, pagenum); + if(pc < pagecopies-1) + printer->newPage(); + } + if(pagenum == lastpage) + break; + if(ascending) + pagenum++; + else + pagenum--; + printer->newPage(); + } + + if(dc < doccopies-1) + printer->newPage(); + } + return 1; +} + +void CTextPrinter::paintPage(QPainter *painter, QTextDocument *document, int pagenum) +{ + QRectF rect; + double onepoint = painter->device()->logicalDpiY() / 72.0; + + if(m_footersize > 0) + { + rect = footerRect(painter->device()); + if(m_footerrule > 0.0) + { + painter->save(); + painter->translate(0, -onepoint + (-m_footerrule * onepoint / 2.0)); + painter->setPen(QPen(Qt::black, m_footerrule * onepoint)); + painter->drawLine(rect.topLeft(), rect.topRight()); + painter->restore(); + } + QString footer = m_footertext; + footer.replace("&page;", QString::number(pagenum)); + painter->save(); + painter->translate(rect.left(), rect.top()); + QRectF clip(0, 0, rect.width(), rect.height()); + QTextDocument doc; + doc.setUseDesignMetrics(true); + doc.setHtml(footer); + doc.documentLayout()->setPaintDevice(painter->device()); + doc.setPageSize(rect.size()); + doc.drawContents(painter, clip); + painter->restore(); + } + + painter->save(); + + rect = contentRect(painter->device()); + painter->translate(rect.left(), rect.top() - (pagenum-1) * rect.height()); + QRectF clip(0, (pagenum-1) * rect.height(), rect.width(), rect.height()); + document->drawContents(painter, clip); + + painter->restore(); +} + diff --git a/product/src/gui/plugin/OrderManageWidget/CTextPrinter.h b/product/src/gui/plugin/OrderManageWidget/CTextPrinter.h index ae777603..e0d2b2a7 100644 --- a/product/src/gui/plugin/OrderManageWidget/CTextPrinter.h +++ b/product/src/gui/plugin/OrderManageWidget/CTextPrinter.h @@ -1,76 +1,76 @@ -#ifndef CTEXTPRINTER_H -#define CTEXTPRINTER_H - -#include -#include -#include "CTextPrinter.h" - -class QTextDocument; -class QWidget; - -class CTextPrinter : public QObject -{ - Q_OBJECT -public: - explicit CTextPrinter(QObject *parent = 0); - ~CTextPrinter(); - - int print(const QTextDocument *document, const QString &caption = QString()); - void preview(const QTextDocument *document, const QString &caption = QString()); - - QPrinter::PageSize pageSize() const; - void setPageSize(QPrinter::PageSize size); - QPrinter::Orientation orientation() const; - void setOrientation(QPrinter::Orientation orientation); - - double leftMargin() const; - void setLeftMargin(double margin); - double rightMargin() const; - void setRightMargin(double margin); - double topMargin() const; - void setTopMargin(double margin); - double bottomMargin() const; - void setBottomMargin(double margin); - void setMargins(double margin); - - double spacing() const; - void setSpacing(double spacing); - - double footerSize() const; - void setFooterSize(double size); - double footerRule() const; - void setFooterRule(double pointsize); - const QString &footerText() const; - void setFooterText(const QString &text); - -private: - CTextPrinter(const CTextPrinter&); - CTextPrinter &operator=(const CTextPrinter&); - - QRectF paperRect(QPaintDevice *device); - QRectF contentRect(QPaintDevice *device); - QRectF headerRect(QPaintDevice *device); - QRectF footerRect(QPaintDevice *device); - - void paintPage(QPainter *painter, QTextDocument *document, int pagenum); -private slots: - int print(QPrinter *printer); - -private: - QWidget *m_parent; - QPrinter *m_printer; - - QTextDocument *m_tempDoc; - - double m_leftmargin; - double m_rightmargin; - double m_topmargin; - double m_bottommargin; - double m_spacing; - - double m_footersize; - double m_footerrule; - QString m_footertext; -}; - -#endif // CTEXTPRINTER_H +#ifndef CTEXTPRINTER_H +#define CTEXTPRINTER_H + +#include +#include +#include "CTextPrinter.h" + +class QTextDocument; +class QWidget; + +class CTextPrinter : public QObject +{ + Q_OBJECT +public: + explicit CTextPrinter(QObject *parent = 0); + ~CTextPrinter(); + + int print(const QTextDocument *document, const QString &caption = QString()); + void preview(const QTextDocument *document, const QString &caption = QString()); + + QPrinter::PageSize pageSize() const; + void setPageSize(QPrinter::PageSize size); + QPrinter::Orientation orientation() const; + void setOrientation(QPrinter::Orientation orientation); + + double leftMargin() const; + void setLeftMargin(double margin); + double rightMargin() const; + void setRightMargin(double margin); + double topMargin() const; + void setTopMargin(double margin); + double bottomMargin() const; + void setBottomMargin(double margin); + void setMargins(double margin); + + double spacing() const; + void setSpacing(double spacing); + + double footerSize() const; + void setFooterSize(double size); + double footerRule() const; + void setFooterRule(double pointsize); + const QString &footerText() const; + void setFooterText(const QString &text); + +private: + CTextPrinter(const CTextPrinter&); + CTextPrinter &operator=(const CTextPrinter&); + + QRectF paperRect(QPaintDevice *device); + QRectF contentRect(QPaintDevice *device); + QRectF headerRect(QPaintDevice *device); + QRectF footerRect(QPaintDevice *device); + + void paintPage(QPainter *painter, QTextDocument *document, int pagenum); +private slots: + int print(QPrinter *printer); + +private: + QWidget *m_parent; + QPrinter *m_printer; + + QTextDocument *m_tempDoc; + + double m_leftmargin; + double m_rightmargin; + double m_topmargin; + double m_bottommargin; + double m_spacing; + + double m_footersize; + double m_footerrule; + QString m_footertext; +}; + +#endif // CTEXTPRINTER_H diff --git a/product/src/gui/plugin/OrderManageWidget/Mainwindow.cpp b/product/src/gui/plugin/OrderManageWidget/Mainwindow.cpp index 7185521a..127cb089 100644 --- a/product/src/gui/plugin/OrderManageWidget/Mainwindow.cpp +++ b/product/src/gui/plugin/OrderManageWidget/Mainwindow.cpp @@ -1,60 +1,60 @@ -#include "Mainwindow.h" -#include "ui_Mainwindow.h" -#include "COrderManageWidget.h" -#include "CRecordForm.h" -#include "pub_utility_api/FileStyle.h" - -Mainwindow::Mainwindow(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::Mainwindow) -{ - ui->setupUi(this); - - COrderManageWidget* m_orderWidget = new COrderManageWidget(ui->tab,editMode); - QGridLayout* gridLayout = new QGridLayout(ui->tab); - //gridLayout->setContentsMargins(0,0,0,0); - gridLayout->setMargin(0); - gridLayout->addWidget(m_orderWidget, 0, 0, 1, 1); - - - CRecordForm* m_recordWidget = new CRecordForm(ui->tab_2,editMode); - QGridLayout* gridLayout_2 = new QGridLayout(ui->tab_2); - //gridLayout_2->setContentsMargins(0,0,0,0); - gridLayout_2->setMargin(0); - gridLayout_2->addWidget(m_recordWidget, 0, 0, 1, 1); - - initStyleSheet(); -} - -Mainwindow::~Mainwindow() -{ - delete ui; -} - -void Mainwindow::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("orderManage.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} +#include "Mainwindow.h" +#include "ui_Mainwindow.h" +#include "COrderManageWidget.h" +#include "CRecordForm.h" +#include "pub_utility_api/FileStyle.h" + +Mainwindow::Mainwindow(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::Mainwindow) +{ + ui->setupUi(this); + + COrderManageWidget* m_orderWidget = new COrderManageWidget(ui->tab,editMode); + QGridLayout* gridLayout = new QGridLayout(ui->tab); + //gridLayout->setContentsMargins(0,0,0,0); + gridLayout->setMargin(0); + gridLayout->addWidget(m_orderWidget, 0, 0, 1, 1); + + + CRecordForm* m_recordWidget = new CRecordForm(ui->tab_2,editMode); + QGridLayout* gridLayout_2 = new QGridLayout(ui->tab_2); + //gridLayout_2->setContentsMargins(0,0,0,0); + gridLayout_2->setMargin(0); + gridLayout_2->addWidget(m_recordWidget, 0, 0, 1, 1); + + initStyleSheet(); +} + +Mainwindow::~Mainwindow() +{ + delete ui; +} + +void Mainwindow::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("orderManage.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} diff --git a/product/src/gui/plugin/OrderManageWidget/Mainwindow.h b/product/src/gui/plugin/OrderManageWidget/Mainwindow.h index f40edb43..7a929168 100644 --- a/product/src/gui/plugin/OrderManageWidget/Mainwindow.h +++ b/product/src/gui/plugin/OrderManageWidget/Mainwindow.h @@ -1,29 +1,29 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include - -namespace Ui { -class Mainwindow; -} - -class Mainwindow : public QWidget -{ - Q_OBJECT - -public: - explicit Mainwindow(QWidget *parent, bool editMode); - ~Mainwindow(); - -private: - void initStyleSheet(); - -public: -signals: - void sigOpenOrder(const QString& jsonData); - -private: - Ui::Mainwindow *ui; -}; - -#endif // MAINWINDOW_H +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +namespace Ui { +class Mainwindow; +} + +class Mainwindow : public QWidget +{ + Q_OBJECT + +public: + explicit Mainwindow(QWidget *parent, bool editMode); + ~Mainwindow(); + +private: + void initStyleSheet(); + +public: +signals: + void sigOpenOrder(const QString& jsonData); + +private: + Ui::Mainwindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/product/src/gui/plugin/OrderManageWidget/Mainwindow.ui b/product/src/gui/plugin/OrderManageWidget/Mainwindow.ui index 94a8f1e3..e06cb9dd 100644 --- a/product/src/gui/plugin/OrderManageWidget/Mainwindow.ui +++ b/product/src/gui/plugin/OrderManageWidget/Mainwindow.ui @@ -1,62 +1,62 @@ - - - Mainwindow - - - - 0 - 0 - 789 - 532 - - - - Form - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - - 票库管理 - - - - - 开票记录 - - - - - - - - - - - - + + + Mainwindow + + + + 0 + 0 + 789 + 532 + + + + Form + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + + 票库管理 + + + + + 开票记录 + + + + + + + + + + + + diff --git a/product/src/gui/plugin/OrderManageWidget/OrderManageWidget.pro b/product/src/gui/plugin/OrderManageWidget/OrderManageWidget.pro index f959f8d1..eaec9b40 100644 --- a/product/src/gui/plugin/OrderManageWidget/OrderManageWidget.pro +++ b/product/src/gui/plugin/OrderManageWidget/OrderManageWidget.pro @@ -1,76 +1,76 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-12-04T14:49:57 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport - -TARGET = OrderManageWidget -TEMPLATE = lib - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - COrderManageWidget.cpp \ - CSqlDbCtrl.cpp \ - COperationOrderPluginWidget.cpp \ - COrderPrinter.cpp \ - CTextPrinter.cpp \ - COperationOrderForm.cpp \ - Mainwindow.cpp \ -# main.cpp \ - CRecordForm.cpp \ - COperationOrderModelForm.cpp \ - COperationOrderHisForm.cpp - -HEADERS += \ - COrderManageWidget.h \ - CSqlDbCtrl.h \ - SDbTableDefine.h \ - COperationOrderPluginWidget.h \ - COrderPrinter.h \ - CTextPrinter.h \ - COperationOrderForm.h \ - Mainwindow.h \ - CRecordForm.h \ - COperationOrderModelForm.h \ - COperationOrderHisForm.h - -FORMS += \ - COrderManageWidget.ui \ - COperationOrderForm.ui \ - Mainwindow.ui \ - CRecordForm.ui - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -ldb_base_api \ - -ldb_api_ex \ - -lpub_utility_api \ - -lperm_mng_api \ - -lsys_login_api - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2018-12-04T14:49:57 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport + +TARGET = OrderManageWidget +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + COrderManageWidget.cpp \ + CSqlDbCtrl.cpp \ + COperationOrderPluginWidget.cpp \ + COrderPrinter.cpp \ + CTextPrinter.cpp \ + COperationOrderForm.cpp \ + Mainwindow.cpp \ +# main.cpp \ + CRecordForm.cpp \ + COperationOrderModelForm.cpp \ + COperationOrderHisForm.cpp + +HEADERS += \ + COrderManageWidget.h \ + CSqlDbCtrl.h \ + SDbTableDefine.h \ + COperationOrderPluginWidget.h \ + COrderPrinter.h \ + CTextPrinter.h \ + COperationOrderForm.h \ + Mainwindow.h \ + CRecordForm.h \ + COperationOrderModelForm.h \ + COperationOrderHisForm.h + +FORMS += \ + COrderManageWidget.ui \ + COperationOrderForm.ui \ + Mainwindow.ui \ + CRecordForm.ui + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lpub_utility_api \ + -lperm_mng_api \ + -lsys_login_api + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/OrderManageWidget/SDbTableDefine.h b/product/src/gui/plugin/OrderManageWidget/SDbTableDefine.h index 99b30c7b..20059049 100644 --- a/product/src/gui/plugin/OrderManageWidget/SDbTableDefine.h +++ b/product/src/gui/plugin/OrderManageWidget/SDbTableDefine.h @@ -1,72 +1,72 @@ -#ifndef SDBTABLEDEFINE_H -#define SDBTABLEDEFINE_H - -#include - -//典型操作票 -struct SOrderPreStore -{ - int id; - QString orderName; - QString orderDesc; - QString remarks; -}; - -//典型操作票信息表 -struct SOrderPreStoreInfo -{ - int orderId; - int seqNo; - QString optDesc; - QString keyIdTag; - int ctrlValue; - QString remarks; -}; - -//历史操作票 -struct SOrderHis -{ - int id; - QString order_no; - QString order_name; - QString order_desc; - qint64 begin_time; - qint64 end_time; - QString remarks; - QString OPERATOR; - QString guardian; - QString duty_manager; - int exec_state; -}; - -//历史操作票信息表 -struct SOrderHisInfo -{ - int order_id; - int seq_no; - QString opt_desc; - QString key_id_tag; - int ctrl_value; - QString remarks; - int exec_state; -}; - - -struct SOrderViewInfo -{ - int id; - QString order_no; - QString orderName; - QString orderDesc; - QString remarks; - - qint64 begin_time; - qint64 end_time; - - QString OPERATOR; - QString guardian; - QString duty_manager; -}; - - -#endif // SDBTABLEDEFINE_H +#ifndef SDBTABLEDEFINE_H +#define SDBTABLEDEFINE_H + +#include + +//典型操作票 +struct SOrderPreStore +{ + int id; + QString orderName; + QString orderDesc; + QString remarks; +}; + +//典型操作票信息表 +struct SOrderPreStoreInfo +{ + int orderId; + int seqNo; + QString optDesc; + QString keyIdTag; + int ctrlValue; + QString remarks; +}; + +//历史操作票 +struct SOrderHis +{ + int id; + QString order_no; + QString order_name; + QString order_desc; + qint64 begin_time; + qint64 end_time; + QString remarks; + QString OPERATOR; + QString guardian; + QString duty_manager; + int exec_state; +}; + +//历史操作票信息表 +struct SOrderHisInfo +{ + int order_id; + int seq_no; + QString opt_desc; + QString key_id_tag; + int ctrl_value; + QString remarks; + int exec_state; +}; + + +struct SOrderViewInfo +{ + int id; + QString order_no; + QString orderName; + QString orderDesc; + QString remarks; + + qint64 begin_time; + qint64 end_time; + + QString OPERATOR; + QString guardian; + QString duty_manager; +}; + + +#endif // SDBTABLEDEFINE_H diff --git a/product/src/gui/plugin/OrderManageWidget/main.cpp b/product/src/gui/plugin/OrderManageWidget/main.cpp index d402def0..ff4855da 100644 --- a/product/src/gui/plugin/OrderManageWidget/main.cpp +++ b/product/src/gui/plugin/OrderManageWidget/main.cpp @@ -1,38 +1,38 @@ - -#include - -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "Mainwindow.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); -// kbd_public::StartLogSystem("HMI", "hmi"); -// if (!(kbd_net::initMsgBus("HMI", "HMI"))) -// { -// return -1; -// } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("Admin", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - { - Mainwindow w(false,NULL); - w.show(); - a.exec(); - } - //<释放消息总线 -// kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} + +#include + +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "Mainwindow.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); +// kbd_public::StartLogSystem("HMI", "hmi"); +// if (!(kbd_net::initMsgBus("HMI", "HMI"))) +// { +// return -1; +// } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("Admin", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + { + Mainwindow w(false,NULL); + w.show(); + a.exec(); + } + //<释放消息总线 +// kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/OrderManageWidget/resourse.qrc b/product/src/gui/plugin/OrderManageWidget/resourse.qrc index 07ca3d3a..2295e73f 100644 --- a/product/src/gui/plugin/OrderManageWidget/resourse.qrc +++ b/product/src/gui/plugin/OrderManageWidget/resourse.qrc @@ -1,11 +1,11 @@ - - - resourse/删除.png - resourse/保存.png - resourse/新建.png - resourse/上移.png - resourse/下移.png - resourse/打印预览.png - resourse/打印.png - - + + + resourse/删除.png + resourse/保存.png + resourse/新建.png + resourse/上移.png + resourse/下移.png + resourse/打印预览.png + resourse/打印.png + + diff --git a/product/src/gui/plugin/PointLockWidget/CConditionModel.cpp b/product/src/gui/plugin/PointLockWidget/CConditionModel.cpp index 6c56ef55..771376e4 100644 --- a/product/src/gui/plugin/PointLockWidget/CConditionModel.cpp +++ b/product/src/gui/plugin/PointLockWidget/CConditionModel.cpp @@ -1,138 +1,138 @@ -#include "CConditionModel.h" -#include "CDbInterfaceMng.h" - -CConditionModel::CConditionModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header <desc; - - break; - case 1: - { - ConditionInfoPtr info = m_list[index.row()]; - QString text = QString(); - QString text1 = QString(); - if(info->table == "digital") - { - text = CDbInterfaceMng::instance()->getDigitalValueDescByText(info->digitalText,info->value1); - }else - { - text = getText(info->cond1,info->value1); - text1 = getText(info->cond2,info->value2); - if(!text1.isEmpty() && !text.isEmpty()) - { - text+=tr(" 且 "); - text+=text1; - } - } - return text; - } - break; - default: - break; - } - } - return QVariant(); -} - -QString CConditionModel::getText(int cond, double value) -{ - QString text = QString(); - switch (cond) { - case 0: - - break; - case 1: - text+=tr("小于 %1 ").arg(QString::number(value)); - break; - case 2: - text+=tr("小于等于 %1 ").arg(QString::number(value)); - break; - case 3: - text+=tr("等于 %1 ").arg(QString::number(value)); - break; - case 4: - text+=tr("大于等于 %1 ").arg(QString::number(value)); - break; - case 5: - text+=tr("大于 %1 ").arg(QString::number(value)); - break; - case 6: - text+=tr("不等于 %1 ").arg(QString::number(value)); - break; - default: - break; - } - return text; -} - -void CConditionModel::updateData(QList &condList) -{ - beginResetModel(); - m_list = condList; - endResetModel(); -} - -ConditionInfoPtr CConditionModel::getDataByIndex(const QModelIndex &index) -{ - if(!index.isValid() || m_list.count()desc; + + break; + case 1: + { + ConditionInfoPtr info = m_list[index.row()]; + QString text = QString(); + QString text1 = QString(); + if(info->table == "digital") + { + text = CDbInterfaceMng::instance()->getDigitalValueDescByText(info->digitalText,info->value1); + }else + { + text = getText(info->cond1,info->value1); + text1 = getText(info->cond2,info->value2); + if(!text1.isEmpty() && !text.isEmpty()) + { + text+=tr(" 且 "); + text+=text1; + } + } + return text; + } + break; + default: + break; + } + } + return QVariant(); +} + +QString CConditionModel::getText(int cond, double value) +{ + QString text = QString(); + switch (cond) { + case 0: + + break; + case 1: + text+=tr("小于 %1 ").arg(QString::number(value)); + break; + case 2: + text+=tr("小于等于 %1 ").arg(QString::number(value)); + break; + case 3: + text+=tr("等于 %1 ").arg(QString::number(value)); + break; + case 4: + text+=tr("大于等于 %1 ").arg(QString::number(value)); + break; + case 5: + text+=tr("大于 %1 ").arg(QString::number(value)); + break; + case 6: + text+=tr("不等于 %1 ").arg(QString::number(value)); + break; + default: + break; + } + return text; +} + +void CConditionModel::updateData(QList &condList) +{ + beginResetModel(); + m_list = condList; + endResetModel(); +} + +ConditionInfoPtr CConditionModel::getDataByIndex(const QModelIndex &index) +{ + if(!index.isValid() || m_list.count() -#include "CPointInfo.h" - -class CConditionModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CConditionModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - static QString getText(int cond,double value); - - void updateData(QList &condList); - - ConditionInfoPtr getDataByIndex( const QModelIndex &index); - void removeData(QModelIndex index); -private: - - QStringList m_header; - QList m_list; -}; - -#endif // CCONDITIONMODEL_H +#ifndef CCONDITIONMODEL_H +#define CCONDITIONMODEL_H + +#include +#include "CPointInfo.h" + +class CConditionModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CConditionModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + static QString getText(int cond,double value); + + void updateData(QList &condList); + + ConditionInfoPtr getDataByIndex( const QModelIndex &index); + void removeData(QModelIndex index); +private: + + QStringList m_header; + QList m_list; +}; + +#endif // CCONDITIONMODEL_H diff --git a/product/src/gui/plugin/PointLockWidget/CDbInterfaceMng.cpp b/product/src/gui/plugin/PointLockWidget/CDbInterfaceMng.cpp index ba255e74..bd4f8148 100644 --- a/product/src/gui/plugin/PointLockWidget/CDbInterfaceMng.cpp +++ b/product/src/gui/plugin/PointLockWidget/CDbInterfaceMng.cpp @@ -1,642 +1,642 @@ -#include "CDbInterfaceMng.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_dbms; - -CDbInterfaceMng *CDbInterfaceMng::m_pInstance = NULL; - -CDbInterfaceMng *CDbInterfaceMng::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CDbInterfaceMng(); - } - return m_pInstance; -} - -void CDbInterfaceMng::destory() -{ - if(m_pWriteDb) - { - m_pWriteDb->close(); - delete m_pWriteDb; - } - m_pWriteDb = NULL; - - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - m_pInstance = NULL; - delete this; -} - -QMap CDbInterfaceMng::locationInfo() -{ - return m_locationInfo; -} - -QList CDbInterfaceMng::locationOrderList() -{ - return m_locOrderList; -} - -QString CDbInterfaceMng::getLocationDesc(const int &locId) -{ - return m_locationInfo.value(locId); -} - - -QList > CDbInterfaceMng::devGroupInfoList(const int &location) -{ - return m_devGroupInfoMap.value(location, QList >()); -} - -QList CDbInterfaceMng::getPointByDev(const QString &dev) -{ - QList list; - getDiByDev(dev,list); - getAiByDev(dev,list); - getPiByDev(dev,list); - getMiByDev(dev,list); - return list; -} - -QMap CDbInterfaceMng::deviceInfo(const QString &devGroupName) -{ - return m_devGDevInfoMap.value(devGroupName, QMap()); -} - -QString CDbInterfaceMng::getDigitalTextByCtrlPoint(const QString &tag) -{ - QString digitalText =QString(); - if(!m_pWriteDb->isOpen()) - { - return digitalText; - } - QSqlQuery query; - QString sqlQuery = QString("select ctrl_act_name from digital_control where tag_name = '%1'").arg(tag); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - digitalText = query.value(0).toString(); - } - return digitalText; -} - -int CDbInterfaceMng::getCtrlGrpTextByCtrlPoint(const QString &tag,QString &ctrlGrpText,QString &title) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QSqlQuery query; - QString sqlQuery = QString("select %1.ctrl_act_name,%2.description from %1 left join %2 on %1.tag_name = %2.tag_name where %2.tag_name = '%3' ").arg("digital_control").arg("digital").arg(tag); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - ctrlGrpText = query.value(0).toString(); - title = query.value(1).toString(); - } - return kbdSuccess; -} - -QMap CDbInterfaceMng::getDigitalTextMapByKey(const QString &key) -{ - return m_digitalTextMap.value(key,QMap()); -} - -QMap CDbInterfaceMng::getCtrlGrpTextMapByKey(const QString &key) -{ - return m_ctrlGroupMap.value(key,QMap()); -} - -QString CDbInterfaceMng::getDigitalValueDescByText(const QString &text, int value) -{ - return m_digitalTextMap.value(text,QMap()).value(value,""); -} - -QString CDbInterfaceMng::getCtrlGrpDescByText(const QString &text, int value) -{ - return m_ctrlGroupMap.value(text,QMap()).value(value,""); -} - -QList CDbInterfaceMng::getConditionInfoByPointInfo(const QString &tag, int value) -{ - QList list; - if(!m_pWriteDb->isOpen()) - { - return list; - } - QSqlQuery query; - QString sql = QString("select condition_tag_name,condition_desc,condition1,value1,condition2,value2,condition_table" - " from point_lock_condition_info where tag_name = '%1' and actual_value = %2").arg(tag).arg(value); - - m_pWriteDb->execute(sql, query); - - while(query.next()) - { - ConditionInfoPtr condinfo(new CConditionInfo()); - condinfo->tag = query.value(0).toString(); - condinfo->desc = query.value(1).toString(); - condinfo->cond1 = query.value(2).toInt(); - condinfo->value1 = query.value(3).toDouble(); - condinfo->cond2 = query.value(4).toInt(); - condinfo->value2 = query.value(5).toDouble(); - condinfo->table = query.value(6).toString(); - list.append(condinfo); - } - for(int index(0);indextable == "digital") - { - QSqlQuery query1; - sql = QString("select state_text_name from digital where tag_name ='%1'").arg(list.at(index)->tag); - m_pWriteDb->execute(sql,query1); - while (query1.next()) { - list.at(index)->digitalText = query1.value(0).toString(); - } - } - } - return list; -} - -PointInfoPtr CDbInterfaceMng::getLockConfigInfo(const QString &tag, int value) -{ - if(!m_pWriteDb->isOpen()) - { - return Q_NULLPTR; - } - QSqlQuery query; - QString sql = QString("select TAG_NAME,ACTUAL_VALUE,ISENABLE from point_lock_config_info where tag_name = '%1' and actual_value = %2").arg(tag).arg(value); - - m_pWriteDb->execute(sql, query); - - while(query.next()) - { - PointInfoPtr info(new CPointInfo()); - info->tag = query.value(0).toString(); - info->value = query.value(1).toInt(); - info->enable = query.value(2).toInt(); - return info; - } - return Q_NULLPTR; -} - -PointInfoPtrList CDbInterfaceMng::getLockConfigInfo(const QString &tag) -{ - PointInfoPtrList resultList; - if(!m_pWriteDb->isOpen()) - { - return resultList; - } - QSqlQuery query; - QString sql = QString("select TAG_NAME,ACTUAL_VALUE,ISENABLE from point_lock_config_info where tag_name = '%1'").arg(tag); - - m_pWriteDb->execute(sql, query); - - while(query.next()) - { - PointInfoPtr info(new CPointInfo()); - info->tag = query.value(0).toString(); - info->value = query.value(1).toInt(); - info->enable = query.value(2).toInt(); - resultList.push_back(info); - } - return resultList; -} - -int CDbInterfaceMng::addPointLock(const QString &tag, int digitalValue, int check) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QString sqlQuery = QString("insert into point_lock_config_info(tag_name,actual_value,isEnable) values('%1',%2,%3)").arg(tag).arg(QString::number(digitalValue)).arg(QString::number(check)); - - if(m_pWriteDb->execute(sqlQuery)) - { - return kbdSuccess; - } - return kbdFailed; -} - -int CDbInterfaceMng::delPointLock(const QString &tag, int digitalValue) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QString sqlQuery = QString("delete from point_lock_config_info where tag_name='%1' and actual_value='%2'").arg(tag).arg(QString::number(digitalValue)); - - if(m_pWriteDb->execute(sqlQuery)) - { - return kbdSuccess; - } - return kbdFailed; -} - -int CDbInterfaceMng::updatePointLock(const QString &tag, int digitalValue, bool isEnable) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QString sqlQuery = QString("update point_lock_config_info set isEnable = %1 where tag_name = '%2' and actual_value = %3").arg(isEnable?1:0).arg(tag).arg(digitalValue); - - if(m_pWriteDb->execute(sqlQuery)) - { - return kbdSuccess; - } - return kbdFailed; -} - -QString CDbInterfaceMng::getDevgByDevTag(const QString dev) -{ - return m_devDevgMap.value(dev,""); -} - -int CDbInterfaceMng::addConditionLock(const QString &tag, int value, ConditionInfoPtr condInfo) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QString sqlQuery = QString(); - sqlQuery = QString("insert into point_lock_condition_info(tag_name,actual_value,condition_tag_name,condition_desc,condition1" - ",value1,condition2,value2,condition_table) values('%1',%2,'%3','%4',%5,%6,%7,%8,'%9')").arg(tag) - .arg(QString::number(value)).arg(condInfo->tag).arg(condInfo->desc).arg(condInfo->cond1).arg(condInfo->value1) - .arg(condInfo->cond2).arg(condInfo->value2).arg(condInfo->table); - - qDebug()<execute(sqlQuery)) - { - return kbdSuccess; - } - return kbdFailed; -} - -int CDbInterfaceMng::delConditionLock(const QString &tag, int value, ConditionInfoPtr condInfo) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - - QString sql = QString("delete from point_lock_condition_info where tag_name ='%1' and actual_value = %2 and condition_tag_name = '%3' ") - .arg(tag).arg(value).arg(condInfo->tag); - - if(m_pWriteDb->execute(sql)) - { - return kbdSuccess; - }else - { - return kbdFailed; - } - return kbdFailed; -} - -QString CDbInterfaceMng::getDevgDescByDevTag(const QString dev) -{ - return m_devgInfoMap.value(m_devDevgMap.value(dev,""),""); -} - -int CDbInterfaceMng::getPointDesc(const QString &tag, const QString &table, QString &description) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QSqlQuery query; - QString sqlQuery = QString("select description from %1 where tag_name = '%2' ").arg(table).arg(tag); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - description = query.value(0).toString(); - return kbdSuccess; - } - return kbdFailed; -} - -CDbInterfaceMng::CDbInterfaceMng() -{ - m_pWriteDb = new CDbApi(DB_CONN_MODEL_WRITE); - m_pWriteDb->open(); - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - loadRTLocation(); - loadDevGroupInfo(); - loadDeviceInfo(); - loadDigitalText(); - loadOptCtrlActDefine(); -} - -void CDbInterfaceMng::loadRTLocation() -{ - m_locationInfo.clear(); - m_locOrderList.clear(); - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"); - LOGDEBUG("readLocation():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - int id = query.value(0).toInt(); - QString desc = query.value(1).toString(); - m_locationInfo[id] = desc; - m_locOrderList.push_back(id); - } -// kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); -// if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) -// { -// LOGERROR("权限接口初始化失败!"); -// return; -// } -// int level; -// std::vector vecLocationId; -// std::vector vecPermPic; -// if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) -// { -// LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); -// return; -// } - -// std::string strApplicationName = "base"; -// std::string strTableName = "sys_model_location_info"; -// QPair id_value; -// id_value.first = "location_id"; -// id_value.second = "description"; -// if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) -// { -// kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); -// kbd_dbms::CRdbQueryResult result; -// std::vector columns; -// columns.push_back(id_value.first); -// columns.push_back(id_value.second); - -// if(m_rtdbAccess->select(result, columns)) -// { -// m_locationInfo.clear(); -// for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) -// { -// kbd_dbms::CVarType key; -// kbd_dbms::CVarType value; -// result.getColumnValue(nIndex, 0, key); -// result.getColumnValue(nIndex, 1, value); - -// std::vector ::const_iterator it = vecLocationId.cbegin(); -// while (it != vecLocationId.cend()) -// { -// if(key.toInt() == *it) -// { -// m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); -// } -// ++it; -// } -// } -// } -// } -// m_rtdbAccess->close(); -} - -void CDbInterfaceMng::loadDevGroupInfo() -{ - QSqlQuery query; - - QString strLoctionFilter; - if(!m_locationInfo.keys().isEmpty()) - { - QStringList listLocation; - foreach (int nLocationID, m_locationInfo.keys()) - { - listLocation.append(QString::number(nLocationID)); - } - strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); - }else - { - return ; - } - QString sqlSequenceQuery = QString("select tag_name, description, location_id from dev_group where sub_system > 3 "); - if(!strLoctionFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); - }else - { - sqlSequenceQuery.append(QString(" order by dev_group_no asc;")); - } - m_pWriteDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - QPair pair; - pair.first = query.value(0).toString(); - pair.second = query.value(1).toString(); - m_devgInfoMap[pair.first] = pair.second; - QMap > >::iterator it = m_devGroupInfoMap.find(query.value(2).toInt()); - if(it !=m_devGroupInfoMap.end()) - { - QList > &devgList = it.value(); - devgList.append(pair); - }else - { - QList > devgList; - devgList.append(pair); - m_devGroupInfoMap[query.value(2).toInt()] = devgList; - } - } -} - -void CDbInterfaceMng::loadDeviceInfo() -{ - m_devDevgMap.clear(); - m_devGDevInfoMap.clear(); - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,GROUP_TAG_NAME from dev_info"); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - QString devg = query.value(2).toString(); - m_devDevgMap[tag] = devg; - QMap >::iterator iter = m_devGDevInfoMap.find(devg); - if(iter != m_devGDevInfoMap.end()) - { - m_devGDevInfoMap[devg].insert(tag,desc); - }else - { - QMap devMap; - devMap.insert(tag,desc); - m_devGDevInfoMap[devg] = devMap; - } - } -} - -void CDbInterfaceMng::loadDigitalText() -{ - m_digitalTextMap.clear(); - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select state_text_name,actual_value,display_value from %1").arg("dict_state_text_info"); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString state_text_name = query.value(0).toString(); - int actual_value = query.value(1).toInt(); - QString display_value = query.value(2).toString(); - QMap >::iterator iter = m_digitalTextMap.find(state_text_name); - if(iter != m_digitalTextMap.end()) - { - iter.value().insert(actual_value,display_value); - }else - { - QMap actualMap; - actualMap.insert(actual_value,display_value); - m_digitalTextMap[state_text_name] = actualMap; - } - } -} - -void CDbInterfaceMng::loadOptCtrlActDefine() -{ - m_ctrlGroupMap.clear(); - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select ctrl_grp_name,target_value,ctrl_act_name from %1").arg("opt_ctrl_act_define"); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString grpName = query.value(0).toString(); - int targetValue = query.value(1).toInt(); - QString actName = query.value(2).toString(); - QMap >::iterator iter = m_ctrlGroupMap.find(grpName); - if(iter != m_ctrlGroupMap.end()) - { - iter.value().insert(targetValue,actName); - }else - { - QMap actualMap; - actualMap.insert(targetValue,actName); - m_ctrlGroupMap[grpName] = actualMap; - } - } -} - -void CDbInterfaceMng::getDiByDev(const QString &dev, QList &list) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE,STATE_TEXT_NAME from digital where device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devg = getDevgByDevTag(query.value(2).toString()); - info.digitalText = query.value(3).toString(); - info.table = "digital"; - list.append(info); - } -} - -void CDbInterfaceMng::getAiByDev(const QString &dev, QList &list) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from analog where device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devg = getDevgByDevTag(query.value(2).toString()); - info.table = "analog"; - list.append(info); - } -} - -void CDbInterfaceMng::getPiByDev(const QString &dev, QList &list) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from accuml where device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devg = getDevgByDevTag(query.value(2).toString()); - info.table = "accuml"; - list.append(info); - } -} - -void CDbInterfaceMng::getMiByDev(const QString &dev, QList &list) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from mix where device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devg = getDevgByDevTag(query.value(2).toString()); - info.table = "mix"; - list.append(info); - } -} +#include "CDbInterfaceMng.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" + +using namespace kbd_dbms; + +CDbInterfaceMng *CDbInterfaceMng::m_pInstance = NULL; + +CDbInterfaceMng *CDbInterfaceMng::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDbInterfaceMng(); + } + return m_pInstance; +} + +void CDbInterfaceMng::destory() +{ + if(m_pWriteDb) + { + m_pWriteDb->close(); + delete m_pWriteDb; + } + m_pWriteDb = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_pInstance = NULL; + delete this; +} + +QMap CDbInterfaceMng::locationInfo() +{ + return m_locationInfo; +} + +QList CDbInterfaceMng::locationOrderList() +{ + return m_locOrderList; +} + +QString CDbInterfaceMng::getLocationDesc(const int &locId) +{ + return m_locationInfo.value(locId); +} + + +QList > CDbInterfaceMng::devGroupInfoList(const int &location) +{ + return m_devGroupInfoMap.value(location, QList >()); +} + +QList CDbInterfaceMng::getPointByDev(const QString &dev) +{ + QList list; + getDiByDev(dev,list); + getAiByDev(dev,list); + getPiByDev(dev,list); + getMiByDev(dev,list); + return list; +} + +QMap CDbInterfaceMng::deviceInfo(const QString &devGroupName) +{ + return m_devGDevInfoMap.value(devGroupName, QMap()); +} + +QString CDbInterfaceMng::getDigitalTextByCtrlPoint(const QString &tag) +{ + QString digitalText =QString(); + if(!m_pWriteDb->isOpen()) + { + return digitalText; + } + QSqlQuery query; + QString sqlQuery = QString("select ctrl_act_name from digital_control where tag_name = '%1'").arg(tag); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + digitalText = query.value(0).toString(); + } + return digitalText; +} + +int CDbInterfaceMng::getCtrlGrpTextByCtrlPoint(const QString &tag,QString &ctrlGrpText,QString &title) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QSqlQuery query; + QString sqlQuery = QString("select %1.ctrl_act_name,%2.description from %1 left join %2 on %1.tag_name = %2.tag_name where %2.tag_name = '%3' ").arg("digital_control").arg("digital").arg(tag); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + ctrlGrpText = query.value(0).toString(); + title = query.value(1).toString(); + } + return kbdSuccess; +} + +QMap CDbInterfaceMng::getDigitalTextMapByKey(const QString &key) +{ + return m_digitalTextMap.value(key,QMap()); +} + +QMap CDbInterfaceMng::getCtrlGrpTextMapByKey(const QString &key) +{ + return m_ctrlGroupMap.value(key,QMap()); +} + +QString CDbInterfaceMng::getDigitalValueDescByText(const QString &text, int value) +{ + return m_digitalTextMap.value(text,QMap()).value(value,""); +} + +QString CDbInterfaceMng::getCtrlGrpDescByText(const QString &text, int value) +{ + return m_ctrlGroupMap.value(text,QMap()).value(value,""); +} + +QList CDbInterfaceMng::getConditionInfoByPointInfo(const QString &tag, int value) +{ + QList list; + if(!m_pWriteDb->isOpen()) + { + return list; + } + QSqlQuery query; + QString sql = QString("select condition_tag_name,condition_desc,condition1,value1,condition2,value2,condition_table" + " from point_lock_condition_info where tag_name = '%1' and actual_value = %2").arg(tag).arg(value); + + m_pWriteDb->execute(sql, query); + + while(query.next()) + { + ConditionInfoPtr condinfo(new CConditionInfo()); + condinfo->tag = query.value(0).toString(); + condinfo->desc = query.value(1).toString(); + condinfo->cond1 = query.value(2).toInt(); + condinfo->value1 = query.value(3).toDouble(); + condinfo->cond2 = query.value(4).toInt(); + condinfo->value2 = query.value(5).toDouble(); + condinfo->table = query.value(6).toString(); + list.append(condinfo); + } + for(int index(0);indextable == "digital") + { + QSqlQuery query1; + sql = QString("select state_text_name from digital where tag_name ='%1'").arg(list.at(index)->tag); + m_pWriteDb->execute(sql,query1); + while (query1.next()) { + list.at(index)->digitalText = query1.value(0).toString(); + } + } + } + return list; +} + +PointInfoPtr CDbInterfaceMng::getLockConfigInfo(const QString &tag, int value) +{ + if(!m_pWriteDb->isOpen()) + { + return Q_NULLPTR; + } + QSqlQuery query; + QString sql = QString("select TAG_NAME,ACTUAL_VALUE,ISENABLE from point_lock_config_info where tag_name = '%1' and actual_value = %2").arg(tag).arg(value); + + m_pWriteDb->execute(sql, query); + + while(query.next()) + { + PointInfoPtr info(new CPointInfo()); + info->tag = query.value(0).toString(); + info->value = query.value(1).toInt(); + info->enable = query.value(2).toInt(); + return info; + } + return Q_NULLPTR; +} + +PointInfoPtrList CDbInterfaceMng::getLockConfigInfo(const QString &tag) +{ + PointInfoPtrList resultList; + if(!m_pWriteDb->isOpen()) + { + return resultList; + } + QSqlQuery query; + QString sql = QString("select TAG_NAME,ACTUAL_VALUE,ISENABLE from point_lock_config_info where tag_name = '%1'").arg(tag); + + m_pWriteDb->execute(sql, query); + + while(query.next()) + { + PointInfoPtr info(new CPointInfo()); + info->tag = query.value(0).toString(); + info->value = query.value(1).toInt(); + info->enable = query.value(2).toInt(); + resultList.push_back(info); + } + return resultList; +} + +int CDbInterfaceMng::addPointLock(const QString &tag, int digitalValue, int check) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QString sqlQuery = QString("insert into point_lock_config_info(tag_name,actual_value,isEnable) values('%1',%2,%3)").arg(tag).arg(QString::number(digitalValue)).arg(QString::number(check)); + + if(m_pWriteDb->execute(sqlQuery)) + { + return kbdSuccess; + } + return kbdFailed; +} + +int CDbInterfaceMng::delPointLock(const QString &tag, int digitalValue) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QString sqlQuery = QString("delete from point_lock_config_info where tag_name='%1' and actual_value='%2'").arg(tag).arg(QString::number(digitalValue)); + + if(m_pWriteDb->execute(sqlQuery)) + { + return kbdSuccess; + } + return kbdFailed; +} + +int CDbInterfaceMng::updatePointLock(const QString &tag, int digitalValue, bool isEnable) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QString sqlQuery = QString("update point_lock_config_info set isEnable = %1 where tag_name = '%2' and actual_value = %3").arg(isEnable?1:0).arg(tag).arg(digitalValue); + + if(m_pWriteDb->execute(sqlQuery)) + { + return kbdSuccess; + } + return kbdFailed; +} + +QString CDbInterfaceMng::getDevgByDevTag(const QString dev) +{ + return m_devDevgMap.value(dev,""); +} + +int CDbInterfaceMng::addConditionLock(const QString &tag, int value, ConditionInfoPtr condInfo) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QString sqlQuery = QString(); + sqlQuery = QString("insert into point_lock_condition_info(tag_name,actual_value,condition_tag_name,condition_desc,condition1" + ",value1,condition2,value2,condition_table) values('%1',%2,'%3','%4',%5,%6,%7,%8,'%9')").arg(tag) + .arg(QString::number(value)).arg(condInfo->tag).arg(condInfo->desc).arg(condInfo->cond1).arg(condInfo->value1) + .arg(condInfo->cond2).arg(condInfo->value2).arg(condInfo->table); + + qDebug()<execute(sqlQuery)) + { + return kbdSuccess; + } + return kbdFailed; +} + +int CDbInterfaceMng::delConditionLock(const QString &tag, int value, ConditionInfoPtr condInfo) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + + QString sql = QString("delete from point_lock_condition_info where tag_name ='%1' and actual_value = %2 and condition_tag_name = '%3' ") + .arg(tag).arg(value).arg(condInfo->tag); + + if(m_pWriteDb->execute(sql)) + { + return kbdSuccess; + }else + { + return kbdFailed; + } + return kbdFailed; +} + +QString CDbInterfaceMng::getDevgDescByDevTag(const QString dev) +{ + return m_devgInfoMap.value(m_devDevgMap.value(dev,""),""); +} + +int CDbInterfaceMng::getPointDesc(const QString &tag, const QString &table, QString &description) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QSqlQuery query; + QString sqlQuery = QString("select description from %1 where tag_name = '%2' ").arg(table).arg(tag); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + description = query.value(0).toString(); + return kbdSuccess; + } + return kbdFailed; +} + +CDbInterfaceMng::CDbInterfaceMng() +{ + m_pWriteDb = new CDbApi(DB_CONN_MODEL_WRITE); + m_pWriteDb->open(); + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + loadRTLocation(); + loadDevGroupInfo(); + loadDeviceInfo(); + loadDigitalText(); + loadOptCtrlActDefine(); +} + +void CDbInterfaceMng::loadRTLocation() +{ + m_locationInfo.clear(); + m_locOrderList.clear(); + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"); + LOGDEBUG("readLocation():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString desc = query.value(1).toString(); + m_locationInfo[id] = desc; + m_locOrderList.push_back(id); + } +// kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); +// if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) +// { +// LOGERROR("权限接口初始化失败!"); +// return; +// } +// int level; +// std::vector vecLocationId; +// std::vector vecPermPic; +// if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) +// { +// LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); +// return; +// } + +// std::string strApplicationName = "base"; +// std::string strTableName = "sys_model_location_info"; +// QPair id_value; +// id_value.first = "location_id"; +// id_value.second = "description"; +// if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) +// { +// kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); +// kbd_dbms::CRdbQueryResult result; +// std::vector columns; +// columns.push_back(id_value.first); +// columns.push_back(id_value.second); + +// if(m_rtdbAccess->select(result, columns)) +// { +// m_locationInfo.clear(); +// for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) +// { +// kbd_dbms::CVarType key; +// kbd_dbms::CVarType value; +// result.getColumnValue(nIndex, 0, key); +// result.getColumnValue(nIndex, 1, value); + +// std::vector ::const_iterator it = vecLocationId.cbegin(); +// while (it != vecLocationId.cend()) +// { +// if(key.toInt() == *it) +// { +// m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); +// } +// ++it; +// } +// } +// } +// } +// m_rtdbAccess->close(); +} + +void CDbInterfaceMng::loadDevGroupInfo() +{ + QSqlQuery query; + + QString strLoctionFilter; + if(!m_locationInfo.keys().isEmpty()) + { + QStringList listLocation; + foreach (int nLocationID, m_locationInfo.keys()) + { + listLocation.append(QString::number(nLocationID)); + } + strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); + }else + { + return ; + } + QString sqlSequenceQuery = QString("select tag_name, description, location_id from dev_group where sub_system > 3 "); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); + }else + { + sqlSequenceQuery.append(QString(" order by dev_group_no asc;")); + } + m_pWriteDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + QPair pair; + pair.first = query.value(0).toString(); + pair.second = query.value(1).toString(); + m_devgInfoMap[pair.first] = pair.second; + QMap > >::iterator it = m_devGroupInfoMap.find(query.value(2).toInt()); + if(it !=m_devGroupInfoMap.end()) + { + QList > &devgList = it.value(); + devgList.append(pair); + }else + { + QList > devgList; + devgList.append(pair); + m_devGroupInfoMap[query.value(2).toInt()] = devgList; + } + } +} + +void CDbInterfaceMng::loadDeviceInfo() +{ + m_devDevgMap.clear(); + m_devGDevInfoMap.clear(); + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,GROUP_TAG_NAME from dev_info"); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + QString devg = query.value(2).toString(); + m_devDevgMap[tag] = devg; + QMap >::iterator iter = m_devGDevInfoMap.find(devg); + if(iter != m_devGDevInfoMap.end()) + { + m_devGDevInfoMap[devg].insert(tag,desc); + }else + { + QMap devMap; + devMap.insert(tag,desc); + m_devGDevInfoMap[devg] = devMap; + } + } +} + +void CDbInterfaceMng::loadDigitalText() +{ + m_digitalTextMap.clear(); + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select state_text_name,actual_value,display_value from %1").arg("dict_state_text_info"); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString state_text_name = query.value(0).toString(); + int actual_value = query.value(1).toInt(); + QString display_value = query.value(2).toString(); + QMap >::iterator iter = m_digitalTextMap.find(state_text_name); + if(iter != m_digitalTextMap.end()) + { + iter.value().insert(actual_value,display_value); + }else + { + QMap actualMap; + actualMap.insert(actual_value,display_value); + m_digitalTextMap[state_text_name] = actualMap; + } + } +} + +void CDbInterfaceMng::loadOptCtrlActDefine() +{ + m_ctrlGroupMap.clear(); + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select ctrl_grp_name,target_value,ctrl_act_name from %1").arg("opt_ctrl_act_define"); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString grpName = query.value(0).toString(); + int targetValue = query.value(1).toInt(); + QString actName = query.value(2).toString(); + QMap >::iterator iter = m_ctrlGroupMap.find(grpName); + if(iter != m_ctrlGroupMap.end()) + { + iter.value().insert(targetValue,actName); + }else + { + QMap actualMap; + actualMap.insert(targetValue,actName); + m_ctrlGroupMap[grpName] = actualMap; + } + } +} + +void CDbInterfaceMng::getDiByDev(const QString &dev, QList &list) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE,STATE_TEXT_NAME from digital where device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devg = getDevgByDevTag(query.value(2).toString()); + info.digitalText = query.value(3).toString(); + info.table = "digital"; + list.append(info); + } +} + +void CDbInterfaceMng::getAiByDev(const QString &dev, QList &list) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from analog where device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devg = getDevgByDevTag(query.value(2).toString()); + info.table = "analog"; + list.append(info); + } +} + +void CDbInterfaceMng::getPiByDev(const QString &dev, QList &list) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from accuml where device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devg = getDevgByDevTag(query.value(2).toString()); + info.table = "accuml"; + list.append(info); + } +} + +void CDbInterfaceMng::getMiByDev(const QString &dev, QList &list) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from mix where device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devg = getDevgByDevTag(query.value(2).toString()); + info.table = "mix"; + list.append(info); + } +} diff --git a/product/src/gui/plugin/PointLockWidget/CDbInterfaceMng.h b/product/src/gui/plugin/PointLockWidget/CDbInterfaceMng.h index 0585a42a..9528c76e 100644 --- a/product/src/gui/plugin/PointLockWidget/CDbInterfaceMng.h +++ b/product/src/gui/plugin/PointLockWidget/CDbInterfaceMng.h @@ -1,89 +1,89 @@ -#ifndef CDBINTERFACEMNG_H -#define CDBINTERFACEMNG_H - -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/db_api_ex/CDbApi.h" -#include "CPointInfo.h" -#include "CPointLockCommon.h" - -class CDbInterfaceMng -{ -public: - static CDbInterfaceMng * instance(); - void destory(); - - QMap locationInfo(); - - QString getLocationDesc(const int &locId); - - QList locationOrderList(); - - QList > devGroupInfoList(const int& location); - - QList getPointByDev(const QString &dev); - - QMap deviceInfo(const QString &devGroupName); - - QString getDigitalTextByCtrlPoint(const QString &tag); - int getCtrlGrpTextByCtrlPoint(const QString &tag,QString &ctrlGrpText,QString &title); - QMap getDigitalTextMapByKey(const QString &key); - - QMap getCtrlGrpTextMapByKey(const QString &key); - - QString getDigitalValueDescByText(const QString &text, int value); - QString getCtrlGrpDescByText(const QString &text, int value); - - QList getConditionInfoByPointInfo(const QString &tag,int value); - - PointInfoPtr getLockConfigInfo(const QString &tag, int value); - PointInfoPtrList getLockConfigInfo(const QString &tag); - - int addPointLock(const QString & tag,int digitalValue,int check); - - int delPointLock(const QString & tag, int digitalValue); - - int updatePointLock(const QString & tag, int digitalValue, bool isEnable); - - QString getDevgByDevTag(const QString dev); - - int addConditionLock(const QString &tag , int value , ConditionInfoPtr condInfo); - - int delConditionLock(const QString &tag ,int value ,ConditionInfoPtr condInfo); - - QString getDevgDescByDevTag(const QString dev); - - int getPointDesc(const QString &tag, const QString &table, QString &description); - -private: - CDbInterfaceMng(); - - void loadRTLocation(); - void loadDevGroupInfo(); - void loadDeviceInfo(); - void loadDigitalText(); - void loadOptCtrlActDefine(); - - void getDiByDev(const QString &dev,QList &list); - void getAiByDev(const QString &dev,QList &list); - void getPiByDev(const QString &dev,QList &list); - void getMiByDev(const QString &dev,QList &list); -private: - - static CDbInterfaceMng * m_pInstance; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CDbApi * m_pWriteDb; - QMap m_locationInfo; - QList m_locOrderList; - - QMap > > m_devGroupInfoMap; //为了设备组号排序 - QMap m_devgInfoMap; //设备组和设备组描述映射 - QMap > m_devGDevInfoMap; //设备组和设备映射 - QMap m_devDevgMap; //设备和设备组标签映射 - QMap > m_digitalTextMap; //数字量文本 - - QMap > m_ctrlGroupMap; //控制动作组 -}; - -#endif // CDBINTERFACEMNG_H +#ifndef CDBINTERFACEMNG_H +#define CDBINTERFACEMNG_H + +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "CPointInfo.h" +#include "CPointLockCommon.h" + +class CDbInterfaceMng +{ +public: + static CDbInterfaceMng * instance(); + void destory(); + + QMap locationInfo(); + + QString getLocationDesc(const int &locId); + + QList locationOrderList(); + + QList > devGroupInfoList(const int& location); + + QList getPointByDev(const QString &dev); + + QMap deviceInfo(const QString &devGroupName); + + QString getDigitalTextByCtrlPoint(const QString &tag); + int getCtrlGrpTextByCtrlPoint(const QString &tag,QString &ctrlGrpText,QString &title); + QMap getDigitalTextMapByKey(const QString &key); + + QMap getCtrlGrpTextMapByKey(const QString &key); + + QString getDigitalValueDescByText(const QString &text, int value); + QString getCtrlGrpDescByText(const QString &text, int value); + + QList getConditionInfoByPointInfo(const QString &tag,int value); + + PointInfoPtr getLockConfigInfo(const QString &tag, int value); + PointInfoPtrList getLockConfigInfo(const QString &tag); + + int addPointLock(const QString & tag,int digitalValue,int check); + + int delPointLock(const QString & tag, int digitalValue); + + int updatePointLock(const QString & tag, int digitalValue, bool isEnable); + + QString getDevgByDevTag(const QString dev); + + int addConditionLock(const QString &tag , int value , ConditionInfoPtr condInfo); + + int delConditionLock(const QString &tag ,int value ,ConditionInfoPtr condInfo); + + QString getDevgDescByDevTag(const QString dev); + + int getPointDesc(const QString &tag, const QString &table, QString &description); + +private: + CDbInterfaceMng(); + + void loadRTLocation(); + void loadDevGroupInfo(); + void loadDeviceInfo(); + void loadDigitalText(); + void loadOptCtrlActDefine(); + + void getDiByDev(const QString &dev,QList &list); + void getAiByDev(const QString &dev,QList &list); + void getPiByDev(const QString &dev,QList &list); + void getMiByDev(const QString &dev,QList &list); +private: + + static CDbInterfaceMng * m_pInstance; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CDbApi * m_pWriteDb; + QMap m_locationInfo; + QList m_locOrderList; + + QMap > > m_devGroupInfoMap; //为了设备组号排序 + QMap m_devgInfoMap; //设备组和设备组描述映射 + QMap > m_devGDevInfoMap; //设备组和设备映射 + QMap m_devDevgMap; //设备和设备组标签映射 + QMap > m_digitalTextMap; //数字量文本 + + QMap > m_ctrlGroupMap; //控制动作组 +}; + +#endif // CDBINTERFACEMNG_H diff --git a/product/src/gui/plugin/PointLockWidget/CPointInfo.cpp b/product/src/gui/plugin/PointLockWidget/CPointInfo.cpp index abfa5b11..020d323d 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointInfo.cpp +++ b/product/src/gui/plugin/PointLockWidget/CPointInfo.cpp @@ -1,35 +1,35 @@ -#include "CPointInfo.h" - -CPointInfo::CPointInfo() -{ - -} - -CPointInfo::CPointInfo(const PointInfoPtr &other) -{ - tag = other->tag; - desc = other->desc; - value = other->value; - enable = other->enable; - loc = other->loc; - dev = other->dev; - devg = other->devg; - digitalText = other->digitalText; -} - -CConditionInfo::CConditionInfo() -{ - -} - -CConditionInfo::CConditionInfo(const ConditionInfoPtr &other) -{ - tag = other->tag; - desc = other->desc; - table = other->table; - cond1 = other->cond1; - value1 = other->value1; - cond2 = other->cond2; - value2 = other->value2; - digitalText = other->digitalText; -} +#include "CPointInfo.h" + +CPointInfo::CPointInfo() +{ + +} + +CPointInfo::CPointInfo(const PointInfoPtr &other) +{ + tag = other->tag; + desc = other->desc; + value = other->value; + enable = other->enable; + loc = other->loc; + dev = other->dev; + devg = other->devg; + digitalText = other->digitalText; +} + +CConditionInfo::CConditionInfo() +{ + +} + +CConditionInfo::CConditionInfo(const ConditionInfoPtr &other) +{ + tag = other->tag; + desc = other->desc; + table = other->table; + cond1 = other->cond1; + value1 = other->value1; + cond2 = other->cond2; + value2 = other->value2; + digitalText = other->digitalText; +} diff --git a/product/src/gui/plugin/PointLockWidget/CPointInfo.h b/product/src/gui/plugin/PointLockWidget/CPointInfo.h index 3f58d989..c2271e41 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointInfo.h +++ b/product/src/gui/plugin/PointLockWidget/CPointInfo.h @@ -1,46 +1,46 @@ -#ifndef CPOINTINFO_H -#define CPOINTINFO_H - - -#include - -class CPointInfo; -class CConditionInfo; -typedef QSharedPointer PointInfoPtr; -typedef QSharedPointer ConditionInfoPtr; -typedef QList> PointInfoPtrList; - -class CPointInfo -{ -public: - CPointInfo(); - CPointInfo(const PointInfoPtr &other); - - QString tag; - QString desc; - int loc; - QString digitalText; - QString dev; - QString devg; - int value; - int enable; -}; - - -class CConditionInfo -{ -public: - CConditionInfo(); - CConditionInfo(const ConditionInfoPtr &other); - - QString tag; - QString desc; - QString table; - int cond1; - double value1; - int cond2; - double value2; - QString digitalText; -}; - -#endif // CPOINTINFO_H +#ifndef CPOINTINFO_H +#define CPOINTINFO_H + + +#include + +class CPointInfo; +class CConditionInfo; +typedef QSharedPointer PointInfoPtr; +typedef QSharedPointer ConditionInfoPtr; +typedef QList> PointInfoPtrList; + +class CPointInfo +{ +public: + CPointInfo(); + CPointInfo(const PointInfoPtr &other); + + QString tag; + QString desc; + int loc; + QString digitalText; + QString dev; + QString devg; + int value; + int enable; +}; + + +class CConditionInfo +{ +public: + CConditionInfo(); + CConditionInfo(const ConditionInfoPtr &other); + + QString tag; + QString desc; + QString table; + int cond1; + double value1; + int cond2; + double value2; + QString digitalText; +}; + +#endif // CPOINTINFO_H diff --git a/product/src/gui/plugin/PointLockWidget/CPointLockCommon.h b/product/src/gui/plugin/PointLockWidget/CPointLockCommon.h index 34cffad3..6d9d89fd 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointLockCommon.h +++ b/product/src/gui/plugin/PointLockWidget/CPointLockCommon.h @@ -1,24 +1,24 @@ -#ifndef CPOINTLOCKCOMMON_H -#define CPOINTLOCKCOMMON_H - -#include - -enum EN_TREE_POINT_TYPE -{ - EN_TREE_POINT_LOC = 1001, - EN_TREE_POINT_SUB = 1002, - EN_TREE_POINT_DEVG = 1003, - EN_TREE_POINT_DEV = 1004 -}; - -struct PointInfo -{ - QString tag; - QString desc; - int loc; - QString devg; - QString digitalText; - QString table; - PointInfo() {} -}; -#endif // CPOINTLOCKCOMMON_H +#ifndef CPOINTLOCKCOMMON_H +#define CPOINTLOCKCOMMON_H + +#include + +enum EN_TREE_POINT_TYPE +{ + EN_TREE_POINT_LOC = 1001, + EN_TREE_POINT_SUB = 1002, + EN_TREE_POINT_DEVG = 1003, + EN_TREE_POINT_DEV = 1004 +}; + +struct PointInfo +{ + QString tag; + QString desc; + int loc; + QString devg; + QString digitalText; + QString table; + PointInfo() {} +}; +#endif // CPOINTLOCKCOMMON_H diff --git a/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.cpp b/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.cpp index 1807d44b..fdb616f3 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.cpp +++ b/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "CPointLockPluginWidget.h" -#include -#include "CPointLockWidget.h" -#include "pub_logger_api/logger.h" -CPointLockPluginWidget::CPointLockPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CPointLockPluginWidget::~CPointLockPluginWidget() -{ - -} - -bool CPointLockPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **lockWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CPointLockWidget *pWidget = new CPointLockWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *lockWidget = (IPluginWidget *)pWidget; - return true; -} - -void CPointLockPluginWidget::release() -{ - -} +#include "CPointLockPluginWidget.h" +#include +#include "CPointLockWidget.h" +#include "pub_logger_api/logger.h" +CPointLockPluginWidget::CPointLockPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CPointLockPluginWidget::~CPointLockPluginWidget() +{ + +} + +bool CPointLockPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **lockWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CPointLockWidget *pWidget = new CPointLockWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *lockWidget = (IPluginWidget *)pWidget; + return true; +} + +void CPointLockPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.h b/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.h index 002b08b7..2f7df159 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.h +++ b/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CPOINTLOCKPLUGINWIDGET_H -#define CPOINTLOCKPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CPointLockPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CPointLockPluginWidget(QObject *parent = 0); - ~CPointLockPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **lockWidget, QVector ptrVec); - void release(); -}; - -#endif // CPOINTLOCKPLUGINWIDGET_H +#ifndef CPOINTLOCKPLUGINWIDGET_H +#define CPOINTLOCKPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CPointLockPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CPointLockPluginWidget(QObject *parent = 0); + ~CPointLockPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **lockWidget, QVector ptrVec); + void release(); +}; + +#endif // CPOINTLOCKPLUGINWIDGET_H diff --git a/product/src/gui/plugin/PointLockWidget/CPointLockWidget.cpp b/product/src/gui/plugin/PointLockWidget/CPointLockWidget.cpp index 70dc685f..b8ef2c59 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointLockWidget.cpp +++ b/product/src/gui/plugin/PointLockWidget/CPointLockWidget.cpp @@ -1,405 +1,405 @@ -#include "CPointLockWidget.h" -#include "ui_CPointLockWidget.h" -#include "db_api_ex/CDbApi.h" -#include -#include "pub_utility_api/FileStyle.h" -#include -#include "CDbInterfaceMng.h" -#include "CPointLockCommon.h" -#include -#include - -CPointLockWidget::CPointLockWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CPointLockWidget), - m_pCondModel(Q_NULLPTR) -{ - ui->setupUi(this); - - initStyle(); - if(!editMode) - { - initConditionView(); - initConnect(); - } - ui->stackedWidget->setCurrentIndex(0); - ui->stackedWidget_2->setCurrentIndex(1); -} - -CPointLockWidget::~CPointLockWidget() -{ - delete ui; -} - -void CPointLockWidget::initCond(const QString &table, const QString &state) -{ - ui->cValue->clear(); - if(table == "digital") - { - ui->stackedWidget_2->setCurrentIndex(0); - QMap stateValueMap = CDbInterfaceMng::instance()->getDigitalTextMapByKey(state); - QMap::iterator it = stateValueMap.begin(); - while (it!= stateValueMap.end()) { - ui->cValue->addItem(it.value(),it.key()); - it++; - } - }else - { - ui->stackedWidget_2->setCurrentIndex(1); - } -} - -void CPointLockWidget::updateList(const QString &dev) -{ - QList list = CDbInterfaceMng::instance()->getPointByDev(dev); - for(int index(0);indexlistWidget); - item->setText(list.at(index).desc); - item->setData(Qt::UserRole,list.at(index).tag); - item->setData(Qt::UserRole+1,list.at(index).table); - item->setData(Qt::UserRole+2,list.at(index).digitalText); - - ui->listWidget->addItem(item); - } -} - -void CPointLockWidget::init(QString tag) -{ - //xk.PSCADA.digital.xk.2#JX_jgxh.TX.value - QStringList tagBlockList = tag.split("."); - if(tagBlockList.isEmpty() || tagBlockList.count() != 7) - { - return; - } - - m_strTable = tagBlockList[2]; - m_tag = QString("%1.%2.%3").arg(tagBlockList[3]).arg(tagBlockList[4]).arg(tagBlockList[5]); - - QString title = QString(); - if(m_strTable == "digital") - { - QString ctrlGrgText = QString(); - if(CDbInterfaceMng::instance()->getCtrlGrpTextByCtrlPoint(m_tag, ctrlGrgText, title) == kbdFailed) - { - return; - } - QMap ctrlGrpTextMap = CDbInterfaceMng::instance()->getCtrlGrpTextMapByKey(ctrlGrgText); - QMap::iterator it = ctrlGrpTextMap.begin(); - while (it!= ctrlGrpTextMap.end()) { - ui->comboBox->addItem(it.value(),it.key()); - it++; - } - } - else if(m_strTable == "analog") - { - ui->label->setText(tr("状态值")); - ui->comboBox->setEditable(true); - QValidator *validator = new QDoubleValidator(); - ui->comboBox->lineEdit()->setValidator(validator); - if(CDbInterfaceMng::instance()->getPointDesc(m_tag, m_strTable, title) == kbdFailed) - { - return; - } - PointInfoPtrList ctrlList = CDbInterfaceMng::instance()->getLockConfigInfo(m_tag); - foreach (PointInfoPtr info, ctrlList) { - ui->comboBox->addItem(QString::number(info->value), info->value); - } - } - else - { - return; - } - ui->lTitle->setText(title); - - initTable(); -} - -void CPointLockWidget::slotStateChanged(int) -{ - int value; - getCtrlValue(value); - - CDbInterfaceMng::instance()->updatePointLock(m_tag,value,ui->checkBox->isChecked()); -} - -void CPointLockWidget::slotComboxChanged(const QString &) -{ - initTable(); -} - -void CPointLockWidget::slotAddCondition() -{ - ui->stackedWidget->setCurrentIndex(1); - ui->comboBox->setEnabled(false); - ui->pAddCondition->setEnabled(false); - ui->pDelCondition->setEnabled(false); - - initTreeWidget(); -} - -void CPointLockWidget::slotDelCondition() -{ - QModelIndexList modelIndexList = ui->tableView->selectionModel()->selectedIndexes(); - if(modelIndexList.count()<=0) - { - showMess(tr("提示"),tr("请选中需要删除的行")); - return ; - } - int value; - getCtrlValue(value); - ConditionInfoPtr info = m_pCondModel->getDataByIndex(modelIndexList.at(0)); - if(CDbInterfaceMng::instance()->delConditionLock(m_tag,value,info) == kbdSuccess) - { - m_pCondModel->removeData(modelIndexList.at(0)); - //showMess(tr("提示"),tr("删除成功")); - } - QList condList = CDbInterfaceMng::instance()->getConditionInfoByPointInfo(m_tag,value); - if(condList.length() == 0) - { - CDbInterfaceMng::instance()->delPointLock(m_tag, value); - } -} - -void CPointLockWidget::slotCancleClicked() -{ - ui->stackedWidget->setCurrentIndex(0); - ui->comboBox->setEnabled(true); - ui->pAddCondition->setEnabled(true); - ui->pDelCondition->setEnabled(true); -} - -void CPointLockWidget::slotOkClicked() -{ - QString tag = ui->listWidget->currentIndex().data(Qt::UserRole).toString(); - if(tag.isEmpty()) - { - showMess(tr("提示"),tr("请选择测点标签")); - return ; - } - - int value; - getCtrlValue(value); - PointInfoPtr pointInfo = CDbInterfaceMng::instance()->getLockConfigInfo(m_tag,value); - if(pointInfo == Q_NULLPTR) - { - if(CDbInterfaceMng::instance()->addPointLock(m_tag,value,1) == kbdFailed) - { - showMess(tr("提示"),tr("添加失败")); - return; - } - } - - ConditionInfoPtr info(new CConditionInfo()); - QListWidgetItem *item =ui->listWidget->currentItem(); - QString table = item->data(Qt::UserRole+1).toString(); - info->tag = item->data(Qt::UserRole).toString(); - info->table = table; - info->desc = QString("%1-%2").arg(CDbInterfaceMng::instance()->getDevgDescByDevTag(m_curDev)).arg(item->text()); - if(table == "digital") - { - info->cond1 = 0; - info->cond2 = 0; - info->value1 = ui->cValue->currentData().toDouble(); - info->value2 = 0; - }else - { - info->cond1 = ui->ccondition1->currentIndex(); - info->cond2 = ui->ccondition2->currentIndex(); - info->value1 = ui->dValue1->value(); - info->value2 = ui->dValue2->value(); - } - if(CDbInterfaceMng::instance()->addConditionLock(m_tag,value,info) == kbdSuccess) - { - initTable(); - if(m_strTable == "analog" && ui->comboBox->findText(QString::number(value)) == -1) - { - ui->comboBox->addItem(QString::number(value), value); - } - slotCancleClicked(); - } - else - { - showMess(tr("提示"),tr("添加失败")); - } -} - -void CPointLockWidget::treeItemClicked(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - ui->listWidget->clear(); - initCond(); - m_curDev = QString(); - if(item == Q_NULLPTR) - { - return ; - } - if(item->data(0,Qt::UserRole).toInt() == EN_TREE_POINT_DEV) - { - m_curDev =item->data(0,Qt::UserRole+1).toString(); - updateList(m_curDev); - } -} - -void CPointLockWidget::listItemClicked(QListWidgetItem *item) -{ - QString tag = item->data(Qt::UserRole).toString(); - QString table = item->data(Qt::UserRole+1).toString(); - QString state = item->data(Qt::UserRole+2).toString(); - if(tag.isEmpty()) - { - return ; - } - initCond(table,state); -} - -void CPointLockWidget::initStyle() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("devgrouplock.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - else - { - qDebug() << "devgrouplock.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CPointLockWidget::initTable() -{ - int value; - getCtrlValue(value); - - PointInfoPtr info = CDbInterfaceMng::instance()->getLockConfigInfo(m_tag,value); - if(info == Q_NULLPTR) - { - ui->checkBox->setEnabled(false); - } - else - { - ui->checkBox->blockSignals(true); - if(info->enable == 1) - { - ui->checkBox->setChecked(true); - }else - { - ui->checkBox->setChecked(false); - } - ui->checkBox->setEnabled(true); - ui->checkBox->blockSignals(false); - } - //获取配置 - QList condList = CDbInterfaceMng::instance()->getConditionInfoByPointInfo(m_tag,value); - m_pCondModel->updateData(condList); -} - -void CPointLockWidget::initConditionView() -{ - if(m_pCondModel == Q_NULLPTR) - { - m_pCondModel = new CConditionModel(); - ui->tableView->setModel(m_pCondModel); - ui->tableView->setColumnWidth(0,220); - } -} - -void CPointLockWidget::initConnect() -{ - connect(ui->comboBox,&QComboBox::currentTextChanged,this,&CPointLockWidget::slotComboxChanged); - connect(ui->checkBox,&QCheckBox::stateChanged,this,&CPointLockWidget::slotStateChanged); - connect(ui->pAddCondition,&QPushButton::clicked,this,&CPointLockWidget::slotAddCondition); - connect(ui->pDelCondition,&QPushButton::clicked,this,&CPointLockWidget::slotDelCondition); - - connect(ui->pCancle,&QPushButton::clicked,this,&CPointLockWidget::slotCancleClicked); - connect(ui->pOk,&QPushButton::clicked,this,&CPointLockWidget::slotOkClicked); - connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CPointLockWidget::treeItemClicked); - connect(ui->listWidget,&QListWidget::itemClicked,this,&CPointLockWidget::listItemClicked); -} - -void CPointLockWidget::initTreeWidget() -{ - cleanTreeWidget(); - ui->treeWidget->setColumnCount(1); - QList locList = CDbInterfaceMng::instance()->locationOrderList(); - foreach (const int &locId, locList) { - QString desc = CDbInterfaceMng::instance()->getLocationDesc(locId); - QTreeWidgetItem *locItem = new QTreeWidgetItem(); - locItem->setText(0,desc); - locItem->setData(0,Qt::UserRole,(int)EN_TREE_POINT_LOC);//类型 - locItem->setData(0,Qt::UserRole+1,locId);//值 - ui->treeWidget->addTopLevelItem(locItem); - - QList > devGroupInfoList = CDbInterfaceMng::instance()->devGroupInfoList(locId); - for(int index(0);indexsetText(0,devGroupInfoList.at(index).second); - devgItem->setData(0,Qt::UserRole,(int)EN_TREE_POINT_DEVG);//类型 - devgItem->setData(0,Qt::UserRole+1,devGroupInfoList.at(index).first);//值 - locItem->addChild(devgItem); - QMap devInfo = CDbInterfaceMng::instance()->deviceInfo(devGroupInfoList.at(index).first); - - QMap::iterator pos = devInfo.begin(); - while (pos != devInfo.end()) { - QTreeWidgetItem *devItem = new QTreeWidgetItem(); - devItem->setText(0,pos.value()); - devItem->setData(0,Qt::UserRole,(int)EN_TREE_POINT_DEV);//类型 - devItem->setData(0,Qt::UserRole+1,pos.key());//值 - devgItem->addChild(devItem); - pos++; - } - } - } -} - -void CPointLockWidget::cleanTreeWidget() -{ - for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) - { - delete ui->treeWidget->takeTopLevelItem(index); - } -} - -bool CPointLockWidget::getCtrlValue(int &value) -{ - if(m_strTable == "digital") - { - value = ui->comboBox->currentData().toInt(); - return true; - } - else if(m_strTable == "analog") - { - value = ui->comboBox->currentText().toInt(); - return true; - } - return false; -} - -void CPointLockWidget::showMess(const QString &title, const QString &mess) -{ - QMessageBox::information(this,title,mess); -} +#include "CPointLockWidget.h" +#include "ui_CPointLockWidget.h" +#include "db_api_ex/CDbApi.h" +#include +#include "pub_utility_api/FileStyle.h" +#include +#include "CDbInterfaceMng.h" +#include "CPointLockCommon.h" +#include +#include + +CPointLockWidget::CPointLockWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CPointLockWidget), + m_pCondModel(Q_NULLPTR) +{ + ui->setupUi(this); + + initStyle(); + if(!editMode) + { + initConditionView(); + initConnect(); + } + ui->stackedWidget->setCurrentIndex(0); + ui->stackedWidget_2->setCurrentIndex(1); +} + +CPointLockWidget::~CPointLockWidget() +{ + delete ui; +} + +void CPointLockWidget::initCond(const QString &table, const QString &state) +{ + ui->cValue->clear(); + if(table == "digital") + { + ui->stackedWidget_2->setCurrentIndex(0); + QMap stateValueMap = CDbInterfaceMng::instance()->getDigitalTextMapByKey(state); + QMap::iterator it = stateValueMap.begin(); + while (it!= stateValueMap.end()) { + ui->cValue->addItem(it.value(),it.key()); + it++; + } + }else + { + ui->stackedWidget_2->setCurrentIndex(1); + } +} + +void CPointLockWidget::updateList(const QString &dev) +{ + QList list = CDbInterfaceMng::instance()->getPointByDev(dev); + for(int index(0);indexlistWidget); + item->setText(list.at(index).desc); + item->setData(Qt::UserRole,list.at(index).tag); + item->setData(Qt::UserRole+1,list.at(index).table); + item->setData(Qt::UserRole+2,list.at(index).digitalText); + + ui->listWidget->addItem(item); + } +} + +void CPointLockWidget::init(QString tag) +{ + //xk.PSCADA.digital.xk.2#JX_jgxh.TX.value + QStringList tagBlockList = tag.split("."); + if(tagBlockList.isEmpty() || tagBlockList.count() != 7) + { + return; + } + + m_strTable = tagBlockList[2]; + m_tag = QString("%1.%2.%3").arg(tagBlockList[3]).arg(tagBlockList[4]).arg(tagBlockList[5]); + + QString title = QString(); + if(m_strTable == "digital") + { + QString ctrlGrgText = QString(); + if(CDbInterfaceMng::instance()->getCtrlGrpTextByCtrlPoint(m_tag, ctrlGrgText, title) == kbdFailed) + { + return; + } + QMap ctrlGrpTextMap = CDbInterfaceMng::instance()->getCtrlGrpTextMapByKey(ctrlGrgText); + QMap::iterator it = ctrlGrpTextMap.begin(); + while (it!= ctrlGrpTextMap.end()) { + ui->comboBox->addItem(it.value(),it.key()); + it++; + } + } + else if(m_strTable == "analog") + { + ui->label->setText(tr("状态值")); + ui->comboBox->setEditable(true); + QValidator *validator = new QDoubleValidator(); + ui->comboBox->lineEdit()->setValidator(validator); + if(CDbInterfaceMng::instance()->getPointDesc(m_tag, m_strTable, title) == kbdFailed) + { + return; + } + PointInfoPtrList ctrlList = CDbInterfaceMng::instance()->getLockConfigInfo(m_tag); + foreach (PointInfoPtr info, ctrlList) { + ui->comboBox->addItem(QString::number(info->value), info->value); + } + } + else + { + return; + } + ui->lTitle->setText(title); + + initTable(); +} + +void CPointLockWidget::slotStateChanged(int) +{ + int value; + getCtrlValue(value); + + CDbInterfaceMng::instance()->updatePointLock(m_tag,value,ui->checkBox->isChecked()); +} + +void CPointLockWidget::slotComboxChanged(const QString &) +{ + initTable(); +} + +void CPointLockWidget::slotAddCondition() +{ + ui->stackedWidget->setCurrentIndex(1); + ui->comboBox->setEnabled(false); + ui->pAddCondition->setEnabled(false); + ui->pDelCondition->setEnabled(false); + + initTreeWidget(); +} + +void CPointLockWidget::slotDelCondition() +{ + QModelIndexList modelIndexList = ui->tableView->selectionModel()->selectedIndexes(); + if(modelIndexList.count()<=0) + { + showMess(tr("提示"),tr("请选中需要删除的行")); + return ; + } + int value; + getCtrlValue(value); + ConditionInfoPtr info = m_pCondModel->getDataByIndex(modelIndexList.at(0)); + if(CDbInterfaceMng::instance()->delConditionLock(m_tag,value,info) == kbdSuccess) + { + m_pCondModel->removeData(modelIndexList.at(0)); + //showMess(tr("提示"),tr("删除成功")); + } + QList condList = CDbInterfaceMng::instance()->getConditionInfoByPointInfo(m_tag,value); + if(condList.length() == 0) + { + CDbInterfaceMng::instance()->delPointLock(m_tag, value); + } +} + +void CPointLockWidget::slotCancleClicked() +{ + ui->stackedWidget->setCurrentIndex(0); + ui->comboBox->setEnabled(true); + ui->pAddCondition->setEnabled(true); + ui->pDelCondition->setEnabled(true); +} + +void CPointLockWidget::slotOkClicked() +{ + QString tag = ui->listWidget->currentIndex().data(Qt::UserRole).toString(); + if(tag.isEmpty()) + { + showMess(tr("提示"),tr("请选择测点标签")); + return ; + } + + int value; + getCtrlValue(value); + PointInfoPtr pointInfo = CDbInterfaceMng::instance()->getLockConfigInfo(m_tag,value); + if(pointInfo == Q_NULLPTR) + { + if(CDbInterfaceMng::instance()->addPointLock(m_tag,value,1) == kbdFailed) + { + showMess(tr("提示"),tr("添加失败")); + return; + } + } + + ConditionInfoPtr info(new CConditionInfo()); + QListWidgetItem *item =ui->listWidget->currentItem(); + QString table = item->data(Qt::UserRole+1).toString(); + info->tag = item->data(Qt::UserRole).toString(); + info->table = table; + info->desc = QString("%1-%2").arg(CDbInterfaceMng::instance()->getDevgDescByDevTag(m_curDev)).arg(item->text()); + if(table == "digital") + { + info->cond1 = 0; + info->cond2 = 0; + info->value1 = ui->cValue->currentData().toDouble(); + info->value2 = 0; + }else + { + info->cond1 = ui->ccondition1->currentIndex(); + info->cond2 = ui->ccondition2->currentIndex(); + info->value1 = ui->dValue1->value(); + info->value2 = ui->dValue2->value(); + } + if(CDbInterfaceMng::instance()->addConditionLock(m_tag,value,info) == kbdSuccess) + { + initTable(); + if(m_strTable == "analog" && ui->comboBox->findText(QString::number(value)) == -1) + { + ui->comboBox->addItem(QString::number(value), value); + } + slotCancleClicked(); + } + else + { + showMess(tr("提示"),tr("添加失败")); + } +} + +void CPointLockWidget::treeItemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + ui->listWidget->clear(); + initCond(); + m_curDev = QString(); + if(item == Q_NULLPTR) + { + return ; + } + if(item->data(0,Qt::UserRole).toInt() == EN_TREE_POINT_DEV) + { + m_curDev =item->data(0,Qt::UserRole+1).toString(); + updateList(m_curDev); + } +} + +void CPointLockWidget::listItemClicked(QListWidgetItem *item) +{ + QString tag = item->data(Qt::UserRole).toString(); + QString table = item->data(Qt::UserRole+1).toString(); + QString state = item->data(Qt::UserRole+2).toString(); + if(tag.isEmpty()) + { + return ; + } + initCond(table,state); +} + +void CPointLockWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("devgrouplock.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + else + { + qDebug() << "devgrouplock.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CPointLockWidget::initTable() +{ + int value; + getCtrlValue(value); + + PointInfoPtr info = CDbInterfaceMng::instance()->getLockConfigInfo(m_tag,value); + if(info == Q_NULLPTR) + { + ui->checkBox->setEnabled(false); + } + else + { + ui->checkBox->blockSignals(true); + if(info->enable == 1) + { + ui->checkBox->setChecked(true); + }else + { + ui->checkBox->setChecked(false); + } + ui->checkBox->setEnabled(true); + ui->checkBox->blockSignals(false); + } + //获取配置 + QList condList = CDbInterfaceMng::instance()->getConditionInfoByPointInfo(m_tag,value); + m_pCondModel->updateData(condList); +} + +void CPointLockWidget::initConditionView() +{ + if(m_pCondModel == Q_NULLPTR) + { + m_pCondModel = new CConditionModel(); + ui->tableView->setModel(m_pCondModel); + ui->tableView->setColumnWidth(0,220); + } +} + +void CPointLockWidget::initConnect() +{ + connect(ui->comboBox,&QComboBox::currentTextChanged,this,&CPointLockWidget::slotComboxChanged); + connect(ui->checkBox,&QCheckBox::stateChanged,this,&CPointLockWidget::slotStateChanged); + connect(ui->pAddCondition,&QPushButton::clicked,this,&CPointLockWidget::slotAddCondition); + connect(ui->pDelCondition,&QPushButton::clicked,this,&CPointLockWidget::slotDelCondition); + + connect(ui->pCancle,&QPushButton::clicked,this,&CPointLockWidget::slotCancleClicked); + connect(ui->pOk,&QPushButton::clicked,this,&CPointLockWidget::slotOkClicked); + connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CPointLockWidget::treeItemClicked); + connect(ui->listWidget,&QListWidget::itemClicked,this,&CPointLockWidget::listItemClicked); +} + +void CPointLockWidget::initTreeWidget() +{ + cleanTreeWidget(); + ui->treeWidget->setColumnCount(1); + QList locList = CDbInterfaceMng::instance()->locationOrderList(); + foreach (const int &locId, locList) { + QString desc = CDbInterfaceMng::instance()->getLocationDesc(locId); + QTreeWidgetItem *locItem = new QTreeWidgetItem(); + locItem->setText(0,desc); + locItem->setData(0,Qt::UserRole,(int)EN_TREE_POINT_LOC);//类型 + locItem->setData(0,Qt::UserRole+1,locId);//值 + ui->treeWidget->addTopLevelItem(locItem); + + QList > devGroupInfoList = CDbInterfaceMng::instance()->devGroupInfoList(locId); + for(int index(0);indexsetText(0,devGroupInfoList.at(index).second); + devgItem->setData(0,Qt::UserRole,(int)EN_TREE_POINT_DEVG);//类型 + devgItem->setData(0,Qt::UserRole+1,devGroupInfoList.at(index).first);//值 + locItem->addChild(devgItem); + QMap devInfo = CDbInterfaceMng::instance()->deviceInfo(devGroupInfoList.at(index).first); + + QMap::iterator pos = devInfo.begin(); + while (pos != devInfo.end()) { + QTreeWidgetItem *devItem = new QTreeWidgetItem(); + devItem->setText(0,pos.value()); + devItem->setData(0,Qt::UserRole,(int)EN_TREE_POINT_DEV);//类型 + devItem->setData(0,Qt::UserRole+1,pos.key());//值 + devgItem->addChild(devItem); + pos++; + } + } + } +} + +void CPointLockWidget::cleanTreeWidget() +{ + for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) + { + delete ui->treeWidget->takeTopLevelItem(index); + } +} + +bool CPointLockWidget::getCtrlValue(int &value) +{ + if(m_strTable == "digital") + { + value = ui->comboBox->currentData().toInt(); + return true; + } + else if(m_strTable == "analog") + { + value = ui->comboBox->currentText().toInt(); + return true; + } + return false; +} + +void CPointLockWidget::showMess(const QString &title, const QString &mess) +{ + QMessageBox::information(this,title,mess); +} diff --git a/product/src/gui/plugin/PointLockWidget/CPointLockWidget.h b/product/src/gui/plugin/PointLockWidget/CPointLockWidget.h index 23f54e81..7f4f74dc 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointLockWidget.h +++ b/product/src/gui/plugin/PointLockWidget/CPointLockWidget.h @@ -1,78 +1,78 @@ -#ifndef CPOINTLOCKWIDGET_H -#define CPOINTLOCKWIDGET_H - -#include -#include "PointLockCommon.h" -#include -#include "CConditionModel.h" - -#include -#include - -namespace Ui { -class CPointLockWidget; -} - -class CPointLockWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CPointLockWidget(QWidget *parent = 0, bool editMode = false); - ~CPointLockWidget(); - - void initCond(const QString &table = QString(),const QString &state=QString()); - - void updateList(const QString &dev); - -public slots: - void init(QString tag); - - void slotStateChanged(int); - - void slotComboxChanged(const QString &); - - void slotAddCondition(); - - void slotDelCondition(); - - void slotCancleClicked(); - - void slotOkClicked(); - - void treeItemClicked(QTreeWidgetItem *item, int column); - - void listItemClicked(QListWidgetItem *item); - -private: - void initStyle(); - - void initTable(); - - void initConditionView(); - - void initConnect(); - - void initTreeWidget(); - - void cleanTreeWidget(); - - bool getCtrlValue(int &value); - -private: - void showMess(const QString &title,const QString &mess); - -private: - Ui::CPointLockWidget *ui; - - CConditionModel *m_pCondModel; - - QMap dictMap; - - QString m_tag; //控制点标签 - QString m_strTable; //控制点表名 - - QString m_curDev; -}; - -#endif // CPOINTLOCKWIDGET_H +#ifndef CPOINTLOCKWIDGET_H +#define CPOINTLOCKWIDGET_H + +#include +#include "PointLockCommon.h" +#include +#include "CConditionModel.h" + +#include +#include + +namespace Ui { +class CPointLockWidget; +} + +class CPointLockWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CPointLockWidget(QWidget *parent = 0, bool editMode = false); + ~CPointLockWidget(); + + void initCond(const QString &table = QString(),const QString &state=QString()); + + void updateList(const QString &dev); + +public slots: + void init(QString tag); + + void slotStateChanged(int); + + void slotComboxChanged(const QString &); + + void slotAddCondition(); + + void slotDelCondition(); + + void slotCancleClicked(); + + void slotOkClicked(); + + void treeItemClicked(QTreeWidgetItem *item, int column); + + void listItemClicked(QListWidgetItem *item); + +private: + void initStyle(); + + void initTable(); + + void initConditionView(); + + void initConnect(); + + void initTreeWidget(); + + void cleanTreeWidget(); + + bool getCtrlValue(int &value); + +private: + void showMess(const QString &title,const QString &mess); + +private: + Ui::CPointLockWidget *ui; + + CConditionModel *m_pCondModel; + + QMap dictMap; + + QString m_tag; //控制点标签 + QString m_strTable; //控制点表名 + + QString m_curDev; +}; + +#endif // CPOINTLOCKWIDGET_H diff --git a/product/src/gui/plugin/PointLockWidget/CPointLockWidget.ui b/product/src/gui/plugin/PointLockWidget/CPointLockWidget.ui index 44c5dafc..7cc18d84 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointLockWidget.ui +++ b/product/src/gui/plugin/PointLockWidget/CPointLockWidget.ui @@ -1,456 +1,456 @@ - - - CPointLockWidget - - - - 0 - 0 - 556 - 452 - - - - 闭锁配置 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - Agency FB - 14 - - - - 1-1AH5-断路器 - - - Qt::AlignCenter - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 6 - - - - - 控制状态 - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - - - - 添加 - - - - - - - 删除 - - - - - - - - - 启用 - - - - - - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - - - - - - - - - - 0 - 0 - - - - 1 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 条件 - - - - - - - - - - Qt::Horizontal - - - - 646 - 20 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 条件 - - - - - - - - - - - - - 小于 - - - - - 小于等于 - - - - - 等于 - - - - - 大于等于 - - - - - 大于 - - - - - 不等于 - - - - - - - - -10000.000000000000000 - - - 1000000.000000000000000 - - - - - - - - - - - - - - - - - - - - 小于 - - - - - 小于等于 - - - - - 等于 - - - - - 大于等于 - - - - - 大于 - - - - - 不等于 - - - - - - - - -10000.000000000000000 - - - 1000000.000000000000000 - - - - - - - Qt::Horizontal - - - - 415 - 20 - - - - - - - - - - - - - - - - 设备列表 - - - AlignCenter - - - - - - - - - - - - - - - - - + + + CPointLockWidget + + + + 0 + 0 + 556 + 452 + + + + 闭锁配置 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + Agency FB + 14 + + + + 1-1AH5-断路器 + + + Qt::AlignCenter + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 6 + + + + + 控制状态 + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + + + + 添加 + + + + + + + 删除 + + + + + + + + + 启用 + + + + + + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + + + + + + + + + + 0 + 0 + + + + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 条件 + + + + + + + + + + Qt::Horizontal + + + + 646 + 20 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 条件 + + + + + + + + + + + + + 小于 + + + + + 小于等于 + + + + + 等于 + + + + + 大于等于 + + + + + 大于 + + + + + 不等于 + + + + + + + + -10000.000000000000000 + + + 1000000.000000000000000 + + + + + + + + + + + + + + + + + + + + 小于 + + + + + 小于等于 + + + + + 等于 + + + + + 大于等于 + + + + + 大于 + + + + + 不等于 + + + + + + + + -10000.000000000000000 + + + 1000000.000000000000000 + + + + + + + Qt::Horizontal + + + + 415 + 20 + + + + + + + + + + + + + + + + 设备列表 + + + AlignCenter + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/PointLockWidget/PointLockCommon.h b/product/src/gui/plugin/PointLockWidget/PointLockCommon.h index 7a029ecd..8cc6052c 100644 --- a/product/src/gui/plugin/PointLockWidget/PointLockCommon.h +++ b/product/src/gui/plugin/PointLockWidget/PointLockCommon.h @@ -1,17 +1,17 @@ -#ifndef POINTLOCKCOMMON_H -#define POINTLOCKCOMMON_H - -#include - -struct DictStateTextInfo -{ - QString state_text_name; - int actual_value; - QString display_value; - DictStateTextInfo() { - state_text_name = QString(); - actual_value = -1; - display_value = QString(); - } -}; -#endif // POINTLOCKCOMMON_H +#ifndef POINTLOCKCOMMON_H +#define POINTLOCKCOMMON_H + +#include + +struct DictStateTextInfo +{ + QString state_text_name; + int actual_value; + QString display_value; + DictStateTextInfo() { + state_text_name = QString(); + actual_value = -1; + display_value = QString(); + } +}; +#endif // POINTLOCKCOMMON_H diff --git a/product/src/gui/plugin/PointLockWidget/PointLockWidget.pro b/product/src/gui/plugin/PointLockWidget/PointLockWidget.pro index b531241d..2f6349bf 100644 --- a/product/src/gui/plugin/PointLockWidget/PointLockWidget.pro +++ b/product/src/gui/plugin/PointLockWidget/PointLockWidget.pro @@ -1,58 +1,58 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-08-04T17:14:45 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = PointLockWidget -TEMPLATE = lib - -CONFIG +=plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - main.cpp \ - CPointLockWidget.cpp \ - CDbInterfaceMng.cpp \ - CPointInfo.cpp \ - CConditionModel.cpp \ - CPointLockPluginWidget.cpp - -HEADERS += \ - CPointLockWidget.h \ - PointLockCommon.h \ - CDbInterfaceMng.h \ - CPointInfo.h \ - CConditionModel.h \ - CPointLockCommon.h \ - CPointLockPluginWidget.h - -FORMS += \ - CPointLockWidget.ui - - - -LIBS += -llog4cplus -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api - -COMMON_PRI =$$PWD/../../../common.pri -exists($$COMMON_PRI){ - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2021-08-04T17:14:45 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = PointLockWidget +TEMPLATE = lib + +CONFIG +=plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + CPointLockWidget.cpp \ + CDbInterfaceMng.cpp \ + CPointInfo.cpp \ + CConditionModel.cpp \ + CPointLockPluginWidget.cpp + +HEADERS += \ + CPointLockWidget.h \ + PointLockCommon.h \ + CDbInterfaceMng.h \ + CPointInfo.h \ + CConditionModel.h \ + CPointLockCommon.h \ + CPointLockPluginWidget.h + +FORMS += \ + CPointLockWidget.ui + + + +LIBS += -llog4cplus -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api + +COMMON_PRI =$$PWD/../../../common.pri +exists($$COMMON_PRI){ + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/PointLockWidget/main.cpp b/product/src/gui/plugin/PointLockWidget/main.cpp index e2c0c137..f93fc6c7 100644 --- a/product/src/gui/plugin/PointLockWidget/main.cpp +++ b/product/src/gui/plugin/PointLockWidget/main.cpp @@ -1,11 +1,11 @@ -#include "CPointLockWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CPointLockWidget w; - w.show(); - - return a.exec(); -} +#include "CPointLockWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CPointLockWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/PointRealDataWidget/CDbInterface.cpp b/product/src/gui/plugin/PointRealDataWidget/CDbInterface.cpp index aeb1adaa..3d66487e 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CDbInterface.cpp +++ b/product/src/gui/plugin/PointRealDataWidget/CDbInterface.cpp @@ -1,382 +1,382 @@ -#include "CDbInterface.h" -#include "public/pub_logger_api/logger.h" - -using namespace kbd_dbms; - -CDbInterface *CDbInterface::m_pInstance = NULL; - -CDbInterface::CDbInterface() -{ - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_rtdbNetAcs = new kbd_dbms::CRdbNetApi(); - - readUnitInfo(); -} - -CDbInterface *CDbInterface::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CDbInterface(); - } - return m_pInstance; -} - -void CDbInterface::destory() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(m_rtdbNetAcs) - { - delete m_rtdbNetAcs; - } - m_rtdbNetAcs = NULL; - - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - m_mapDevGroup.clear(); - m_mapDevice.clear(); - m_mapUnit.clear(); - m_pInstance = NULL; - delete this; -} - -int CDbInterface::readDomainId(const QString &location) -{ - if(!m_pReadDb->isOpen()) - { - return -1; - } - QSqlQuery query; - QString tableName = "sys_model_location_info"; - QList listColName; - listColName.append("DOMAIN_ID"); - CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_eCompare = CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = CDbCondition::LOGIC_AND; - objCondition.m_value = location; - - QList listOrderBy; - listOrderBy << CDbOrder("location_no"); - - if(m_pReadDb->select(tableName, listColName, objCondition, listOrderBy, query)) - { - while(query.next()) - { - return query.value(0).toInt(); - } - } - return -1; -} - -int CDbInterface::readAppId(const QString &appName) -{ - if(!m_pReadDb->isOpen()) - { - return -1; - } - QSqlQuery query; - QString tableName = "sys_model_app_info"; - QList listColName; - listColName.append("APP_ID"); - CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_eCompare = CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = CDbCondition::LOGIC_AND; - objCondition.m_value = appName; - - if(m_pReadDb->select(tableName, listColName, objCondition, query)) - { - while(query.next()) - { - return query.value(0).toInt(); - } - } - return -1; -} - -bool CDbInterface::readDevice(const QString &devGroup, QStringList &device) -{ - QStringList tagList = m_mapDevice.value(devGroup); - if(!tagList.isEmpty()) - { - device.append(tagList); - return true; - } - - if(!m_pReadDb->isOpen()) - { - return false; - } - - QSqlQuery query; - QString tableName = "dev_info"; - QList listColName; - listColName.append("TAG_NAME"); - CDbCondition objCondition; - objCondition.m_sColName = "GROUP_TAG_NAME"; - objCondition.m_eCompare = CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = CDbCondition::LOGIC_AND; - objCondition.m_value = devGroup; - - QString tag; - if(m_pReadDb->select(tableName, listColName, objCondition, query)) - { - while(query.next()) - { - tag = query.value(0).toString(); - device.append(tag); - m_mapDevice[devGroup].append(tag); - } - return true; - } - return false; -} - -QString CDbInterface::readDevGroup(const QString &devGroup) -{ - QString desc = m_mapDevGroup.value(devGroup); - if(!desc.isEmpty()) - { - return desc; - } - - if(!m_pReadDb->isOpen()) - { - return QString(); - } - - QSqlQuery query; - QString tableName = "dev_group"; - QList listColName; - listColName.append("DESCRIPTION"); - CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_eCompare = CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = CDbCondition::LOGIC_AND; - objCondition.m_value = devGroup; - - if(m_pReadDb->select(tableName, listColName, objCondition, query)) - { - while(query.next()) - { - desc = query.value(0).toString(); - m_mapDevGroup.insert(devGroup, desc); - } - } - return desc; -} - -QString CDbInterface::readPointInfo(const QString &tagName, const QString &table) -{ - if(!m_pReadDb->isOpen()) - { - return QString(); - } - - QString ret; - QSqlQuery query; - QList listColName; - listColName.append("DESCRIPTION"); - if(table == "analog" || table == "accuml") - { - listColName.append("UNIT_ID"); - } - else if(table == "digital" || table == "mix") - { - listColName.append("STATE_TEXT_NAME"); - } - CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_eCompare = CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = CDbCondition::LOGIC_AND; - objCondition.m_value = tagName; - if(m_pReadDb->select(table, listColName, objCondition, query)) - { - while(query.next()) - { - QString desc = query.value(0).toString(); - QString temp; - if(table == "analog" || table == "accuml") - { - temp = getUnitName(query.value(1).toInt()); - } - else if(table == "digital" || table == "mix") - { - temp = query.value(1).toString(); - } - ret = desc + "," + temp; - } - } - return ret; -} - -QString CDbInterface::readChannelTag(const QString &device, const QString &table) -{ - if(!m_pReadDb->isOpen()) - { - return QString(); - } - - QString ret; - QSqlQuery query; - QList listColName; - listColName.append("RTU_TAG"); - CDbCondition objCondition; - objCondition.m_sColName = "DEVICE"; - objCondition.m_eCompare = CDbCondition::COMPARE_EQ; - objCondition.m_eLogic = CDbCondition::LOGIC_AND; - objCondition.m_value = device; - if(m_pReadDb->select(table, listColName, objCondition, query)) - { - while(query.next()) - { - ret = query.value(0).toString(); - break; - } - } - if(ret.isEmpty()) - { - return QString(); - } - listColName.clear(); - listColName.append("CHAN_TAG"); - objCondition.m_sColName = "TAG_NAME"; - objCondition.m_value = ret; - if(m_pReadDb->select("fes_rtu_para", listColName, objCondition, query)) - { - while(query.next()) - { - ret = query.value(0).toString(); - } - } - return ret; -} - -bool CDbInterface::readPointValue(SRealData &sRealData) -{ - double value = qSqrt(-1); - m_rtdbNetAcs->connect(sRealData.nDomainId, sRealData.nAppId); - std::string sTable = sRealData.table_name.toStdString(); - std::string sKey = sRealData.tag_name.toStdString(); - std::string sColumn= sRealData.column.toStdString(); - kbd_idlfile::RdbRet objRet; - - if(m_rtdbNetAcs->queryByKey(sTable, sKey, sColumn, objRet)) - { - int recordNum = objRet.msgrecord_size(); - for (int i = 0; i < recordNum; ++i) - { - if(sTable == "analog" || sTable == "accuml") - { - value = objRet.msgrecord(i).msgvaluearray(0).dvalue(); - } - else if(sTable == "digital" || sTable == "mix") - { - value = objRet.msgrecord(i).msgvaluearray(0).nvalue(); - } - else if(sTable == "fes_channel_para") - { - value = objRet.msgrecord(i).msgvaluearray(0).nvalue(); - } - } - if(!std::isnan(value)) - { - sRealData.isInit = true; - sRealData.value = value; - } - } - else - { - LOGERROR("readPointValue fail: %s, table: %s, key: %s", - m_rtdbNetAcs->getErr().c_str(), - sTable.c_str(), sKey.c_str()); - return false; - } - return true; -} - -QString CDbInterface::getUnitName(int unitId) -{ - QMap::const_iterator iter = m_mapUnit.find(unitId); - if(iter != m_mapUnit.constEnd()) - { - return iter.value(); - } - return QString(); -} - -QString CDbInterface::getStateTextNameByValue(const QString &textName, int value) -{ - QString ret = QString::number(value); - if(m_rtdbAccess->open("base", "dict_state_text_info")) - { - CONDINFO condition1; - memcpy(condition1.name, "state_text_name", strlen("state_text_name")); - condition1.logicalop = ATTRCOND_AND; - condition1.relationop = ATTRCOND_EQU; - condition1.conditionval = textName.toStdString().c_str(); - - CONDINFO condition2; - memcpy(condition2.name, "actual_value", strlen("actual_value")); - condition2.logicalop = ATTRCOND_AND; - condition2.relationop = ATTRCOND_EQU; - condition2.conditionval = value; - - std::vector vecCondInfo; - vecCondInfo.push_back(condition1); - vecCondInfo.push_back(condition2); - - CRdbQueryResult result; - std::vector columns; - columns.push_back("display_value"); - if(m_rtdbAccess->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - ret = QString::fromStdString(value.toStdString()); - } - } - m_rtdbAccess->close(); - } - return ret; -} - -void CDbInterface::readUnitInfo() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QSqlQuery query; - QString tableName = "dict_unit_info"; - QList listColName; - listColName.append("UNIT_ID"); - listColName.append("UNIT_NAME"); - - if(m_pReadDb->select(tableName, listColName, query)) - { - while(query.next()) - { - int id = query.value(0).toInt(); - QString name = query.value(1).toString(); - - m_mapUnit.insert(id, name); - } - } -} +#include "CDbInterface.h" +#include "public/pub_logger_api/logger.h" + +using namespace kbd_dbms; + +CDbInterface *CDbInterface::m_pInstance = NULL; + +CDbInterface::CDbInterface() +{ + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_rtdbNetAcs = new kbd_dbms::CRdbNetApi(); + + readUnitInfo(); +} + +CDbInterface *CDbInterface::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDbInterface(); + } + return m_pInstance; +} + +void CDbInterface::destory() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbNetAcs) + { + delete m_rtdbNetAcs; + } + m_rtdbNetAcs = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_mapDevGroup.clear(); + m_mapDevice.clear(); + m_mapUnit.clear(); + m_pInstance = NULL; + delete this; +} + +int CDbInterface::readDomainId(const QString &location) +{ + if(!m_pReadDb->isOpen()) + { + return -1; + } + QSqlQuery query; + QString tableName = "sys_model_location_info"; + QList listColName; + listColName.append("DOMAIN_ID"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = location; + + QList listOrderBy; + listOrderBy << CDbOrder("location_no"); + + if(m_pReadDb->select(tableName, listColName, objCondition, listOrderBy, query)) + { + while(query.next()) + { + return query.value(0).toInt(); + } + } + return -1; +} + +int CDbInterface::readAppId(const QString &appName) +{ + if(!m_pReadDb->isOpen()) + { + return -1; + } + QSqlQuery query; + QString tableName = "sys_model_app_info"; + QList listColName; + listColName.append("APP_ID"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = appName; + + if(m_pReadDb->select(tableName, listColName, objCondition, query)) + { + while(query.next()) + { + return query.value(0).toInt(); + } + } + return -1; +} + +bool CDbInterface::readDevice(const QString &devGroup, QStringList &device) +{ + QStringList tagList = m_mapDevice.value(devGroup); + if(!tagList.isEmpty()) + { + device.append(tagList); + return true; + } + + if(!m_pReadDb->isOpen()) + { + return false; + } + + QSqlQuery query; + QString tableName = "dev_info"; + QList listColName; + listColName.append("TAG_NAME"); + CDbCondition objCondition; + objCondition.m_sColName = "GROUP_TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = devGroup; + + QString tag; + if(m_pReadDb->select(tableName, listColName, objCondition, query)) + { + while(query.next()) + { + tag = query.value(0).toString(); + device.append(tag); + m_mapDevice[devGroup].append(tag); + } + return true; + } + return false; +} + +QString CDbInterface::readDevGroup(const QString &devGroup) +{ + QString desc = m_mapDevGroup.value(devGroup); + if(!desc.isEmpty()) + { + return desc; + } + + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QSqlQuery query; + QString tableName = "dev_group"; + QList listColName; + listColName.append("DESCRIPTION"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = devGroup; + + if(m_pReadDb->select(tableName, listColName, objCondition, query)) + { + while(query.next()) + { + desc = query.value(0).toString(); + m_mapDevGroup.insert(devGroup, desc); + } + } + return desc; +} + +QString CDbInterface::readPointInfo(const QString &tagName, const QString &table) +{ + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QString ret; + QSqlQuery query; + QList listColName; + listColName.append("DESCRIPTION"); + if(table == "analog" || table == "accuml") + { + listColName.append("UNIT_ID"); + } + else if(table == "digital" || table == "mix") + { + listColName.append("STATE_TEXT_NAME"); + } + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = tagName; + if(m_pReadDb->select(table, listColName, objCondition, query)) + { + while(query.next()) + { + QString desc = query.value(0).toString(); + QString temp; + if(table == "analog" || table == "accuml") + { + temp = getUnitName(query.value(1).toInt()); + } + else if(table == "digital" || table == "mix") + { + temp = query.value(1).toString(); + } + ret = desc + "," + temp; + } + } + return ret; +} + +QString CDbInterface::readChannelTag(const QString &device, const QString &table) +{ + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QString ret; + QSqlQuery query; + QList listColName; + listColName.append("RTU_TAG"); + CDbCondition objCondition; + objCondition.m_sColName = "DEVICE"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = device; + if(m_pReadDb->select(table, listColName, objCondition, query)) + { + while(query.next()) + { + ret = query.value(0).toString(); + break; + } + } + if(ret.isEmpty()) + { + return QString(); + } + listColName.clear(); + listColName.append("CHAN_TAG"); + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_value = ret; + if(m_pReadDb->select("fes_rtu_para", listColName, objCondition, query)) + { + while(query.next()) + { + ret = query.value(0).toString(); + } + } + return ret; +} + +bool CDbInterface::readPointValue(SRealData &sRealData) +{ + double value = qSqrt(-1); + m_rtdbNetAcs->connect(sRealData.nDomainId, sRealData.nAppId); + std::string sTable = sRealData.table_name.toStdString(); + std::string sKey = sRealData.tag_name.toStdString(); + std::string sColumn= sRealData.column.toStdString(); + kbd_idlfile::RdbRet objRet; + + if(m_rtdbNetAcs->queryByKey(sTable, sKey, sColumn, objRet)) + { + int recordNum = objRet.msgrecord_size(); + for (int i = 0; i < recordNum; ++i) + { + if(sTable == "analog" || sTable == "accuml") + { + value = objRet.msgrecord(i).msgvaluearray(0).dvalue(); + } + else if(sTable == "digital" || sTable == "mix") + { + value = objRet.msgrecord(i).msgvaluearray(0).nvalue(); + } + else if(sTable == "fes_channel_para") + { + value = objRet.msgrecord(i).msgvaluearray(0).nvalue(); + } + } + if(!std::isnan(value)) + { + sRealData.isInit = true; + sRealData.value = value; + } + } + else + { + LOGERROR("readPointValue fail: %s, table: %s, key: %s", + m_rtdbNetAcs->getErr().c_str(), + sTable.c_str(), sKey.c_str()); + return false; + } + return true; +} + +QString CDbInterface::getUnitName(int unitId) +{ + QMap::const_iterator iter = m_mapUnit.find(unitId); + if(iter != m_mapUnit.constEnd()) + { + return iter.value(); + } + return QString(); +} + +QString CDbInterface::getStateTextNameByValue(const QString &textName, int value) +{ + QString ret = QString::number(value); + if(m_rtdbAccess->open("base", "dict_state_text_info")) + { + CONDINFO condition1; + memcpy(condition1.name, "state_text_name", strlen("state_text_name")); + condition1.logicalop = ATTRCOND_AND; + condition1.relationop = ATTRCOND_EQU; + condition1.conditionval = textName.toStdString().c_str(); + + CONDINFO condition2; + memcpy(condition2.name, "actual_value", strlen("actual_value")); + condition2.logicalop = ATTRCOND_AND; + condition2.relationop = ATTRCOND_EQU; + condition2.conditionval = value; + + std::vector vecCondInfo; + vecCondInfo.push_back(condition1); + vecCondInfo.push_back(condition2); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("display_value"); + if(m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + ret = QString::fromStdString(value.toStdString()); + } + } + m_rtdbAccess->close(); + } + return ret; +} + +void CDbInterface::readUnitInfo() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QSqlQuery query; + QString tableName = "dict_unit_info"; + QList listColName; + listColName.append("UNIT_ID"); + listColName.append("UNIT_NAME"); + + if(m_pReadDb->select(tableName, listColName, query)) + { + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + + m_mapUnit.insert(id, name); + } + } +} diff --git a/product/src/gui/plugin/PointRealDataWidget/CDbInterface.h b/product/src/gui/plugin/PointRealDataWidget/CDbInterface.h index 7e90fe6b..48951cb3 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CDbInterface.h +++ b/product/src/gui/plugin/PointRealDataWidget/CDbInterface.h @@ -1,40 +1,40 @@ -#ifndef CDBINTERFACE_H -#define CDBINTERFACE_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/rdb_net_api/CRdbNetApi.h" -#include "dbms/db_api_ex/CDbApi.h" -#include "CPointPublic.h" - -class CDbInterface -{ -public: - static CDbInterface * instance(); - void destory(); - - int readDomainId(const QString &location); - int readAppId(const QString &appName); - bool readDevice(const QString &devGroup, QStringList &device); - QString readDevGroup(const QString &devGroup); - QString readPointInfo(const QString &tagName, const QString &table); - QString readChannelTag(const QString &device, const QString &table); - bool readPointValue(SRealData &sRealData); - QString getUnitName(int unitId); - QString getStateTextNameByValue(const QString &textName, int value); - -private: - CDbInterface(); - void readUnitInfo(); - -private: - static CDbInterface * m_pInstance; - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CRdbNetApi * m_rtdbNetAcs; - QMap m_mapDevGroup; - QMap m_mapDevice; - QMap m_mapUnit; -}; - -#endif // CDBINTERFACE_H +#ifndef CDBINTERFACE_H +#define CDBINTERFACE_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_net_api/CRdbNetApi.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "CPointPublic.h" + +class CDbInterface +{ +public: + static CDbInterface * instance(); + void destory(); + + int readDomainId(const QString &location); + int readAppId(const QString &appName); + bool readDevice(const QString &devGroup, QStringList &device); + QString readDevGroup(const QString &devGroup); + QString readPointInfo(const QString &tagName, const QString &table); + QString readChannelTag(const QString &device, const QString &table); + bool readPointValue(SRealData &sRealData); + QString getUnitName(int unitId); + QString getStateTextNameByValue(const QString &textName, int value); + +private: + CDbInterface(); + void readUnitInfo(); + +private: + static CDbInterface * m_pInstance; + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CRdbNetApi * m_rtdbNetAcs; + QMap m_mapDevGroup; + QMap m_mapDevice; + QMap m_mapUnit; +}; + +#endif // CDBINTERFACE_H diff --git a/product/src/gui/plugin/PointRealDataWidget/CPointPublic.h b/product/src/gui/plugin/PointRealDataWidget/CPointPublic.h index 22318913..5a0e7265 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CPointPublic.h +++ b/product/src/gui/plugin/PointRealDataWidget/CPointPublic.h @@ -1,48 +1,48 @@ -#ifndef CPOINTPUBLIC_H -#define CPOINTPUBLIC_H - -#include -#include - -enum EN_AppContext -{ - RT_MODE = 1, - PDR_MODE -}; - -enum EN_NodeType -{ - TYPE_POINT = 0, - TYPE_DEVGROUP, - TYPE_CHANNEL -}; - -struct SRealData -{ - QString tag_name; - QString description; - QString table_name; - double value; - uint status; - QString unit; - QString stateTextName; - int nDomainId; - int nAppId; - bool isInit; - char type; - QString column; - SRealData() - { - value = 0; - status = 0; - nDomainId = -1; - nAppId = -1; - isInit = false; - type = TYPE_POINT; - column = "value"; - } -}; - -typedef QSharedPointer SRealDataPtr; - -#endif // CPOINTPUBLIC_H +#ifndef CPOINTPUBLIC_H +#define CPOINTPUBLIC_H + +#include +#include + +enum EN_AppContext +{ + RT_MODE = 1, + PDR_MODE +}; + +enum EN_NodeType +{ + TYPE_POINT = 0, + TYPE_DEVGROUP, + TYPE_CHANNEL +}; + +struct SRealData +{ + QString tag_name; + QString description; + QString table_name; + double value; + uint status; + QString unit; + QString stateTextName; + int nDomainId; + int nAppId; + bool isInit; + char type; + QString column; + SRealData() + { + value = 0; + status = 0; + nDomainId = -1; + nAppId = -1; + isInit = false; + type = TYPE_POINT; + column = "value"; + } +}; + +typedef QSharedPointer SRealDataPtr; + +#endif // CPOINTPUBLIC_H diff --git a/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.cpp b/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.cpp index a264a3a6..17539760 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.cpp +++ b/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.cpp @@ -1,642 +1,642 @@ -#include "CPointRealDataWidget.h" -#include "CDbInterface.h" -#include "CRealTableModel.h" -#include "CRealDataCollect.h" -#include -#include -#include - -CPointRealDataWidget::CPointRealDataWidget(bool editMode, QWidget *parent) - : QWidget(parent), - m_isEditMode(editMode), - m_nGroupNo(1), - m_isRtdbNormal(true), - m_pTimer(NULL), - m_pDpcdaForApp(NULL) -{ - initialize(); -} - -CPointRealDataWidget::~CPointRealDataWidget() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - delete m_pDpcdaForApp; - } - m_pDpcdaForApp = NULL; - - if(!m_isEditMode) - { - CRealDataCollect::instance()->release(); - - CDbInterface::instance()->destory(); - } -} - -void CPointRealDataWidget::initialize() -{ - if(m_isEditMode) - { - QTableView * tableView = new QTableView(); - QGridLayout * layout = new QGridLayout(this); - layout->addWidget(tableView); - layout->setMargin(0); - setLayout(layout); - return; - } - - setChannelText(tr("通讯状态"), tr("正常"), tr("异常")); - - qRegisterMetaType>>("QMap>"); - qRegisterMetaType>>("QMap>"); - qRegisterMetaType>>("QMap>"); - - m_objAppContext = RT_MODE; - CRealDataCollect::instance()->setAppContext(m_objAppContext); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateAi, this, &CPointRealDataWidget::slotUpdateAi); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CPointRealDataWidget::slotUpdateDi); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updatePi, this, &CPointRealDataWidget::slotUpdatePi); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateMi, this, &CPointRealDataWidget::slotUpdateMi); - m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); - - m_pTimer = new QTimer(this); - connect(m_pTimer, &QTimer::timeout, this, &CPointRealDataWidget::onTimer); - m_pTimer->start(1000); -} - -void CPointRealDataWidget::switchAppcontext(int appContext) -{ - if(m_objAppContext == appContext) - { - return; - } - m_objAppContext = (EN_AppContext)appContext; - if(m_objAppContext == PDR_MODE) - { - m_pTimer->stop(); - } - else - { - m_pTimer->start(1000); - } - - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - } - - CRealDataCollect::instance()->setAppContext(m_objAppContext); - - QMap >::iterator iter = m_groupMap.begin(); - for(; iter != m_groupMap.end(); iter++) - { - QList &dataList = iter.value(); - QList::iterator it = dataList.begin(); - for(; it != dataList.end(); it++) - { - SRealData &data = *it; - data.isInit = false; - if(data.type == TYPE_POINT) - { - m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), data.column.toStdString()); - } - } - } -} - -int CPointRealDataWidget::addGroup(const QStringList &name, int row, int column) -{ - QTableView * tableView = new QTableView(); - tableView->setSelectionMode(QAbstractItemView::NoSelection); - tableView->horizontalHeader()->setStretchLastSection(true); - tableView->horizontalHeader()->setSectionsClickable(false); - tableView->setFocusPolicy(Qt::NoFocus); - tableView->setAlternatingRowColors(true); - tableView->verticalHeader()->setVisible(false); - tableView->setShowGrid(false); - tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - CRealTableModel * tableModel = new CRealTableModel(tableView, name); - tableModel->updateChannelText(m_channelTxList); - tableView->setModel(tableModel); - - if(!layout()) - { - QGridLayout *layout = new QGridLayout(this); - layout->setMargin(0); - layout->setSpacing(0); - setLayout(layout); - } - QGridLayout *gLayout = dynamic_cast(layout()); - gLayout->addWidget(tableView, row, column); - - m_groupMap.insert(m_nGroupNo, QList()); - m_tableMap.insert(m_nGroupNo, tableView); - - return m_nGroupNo++; -} - -QString CPointRealDataWidget::addPoint(int GroupNo, const QStringList &RealTagList, const QStringList &PointList) -{ - if(m_groupMap.find(GroupNo) == m_groupMap.constEnd()) - { - return tr("未找到组号%1!").arg(QString::number(GroupNo)); - } - - //< 得到所有可能的点标签 - QMap tagMap; - QString devGroup; - foreach (QString RealTag, RealTagList) { - if(RealTag.isEmpty() || RealTag.split(".").length() != 7) - { - continue; - } - bool channel = false; - QStringList devList; - devGroup = truncTag(RealTag, "g"); - CDbInterface::instance()->readDevice(devGroup, devList); - QString value; - QString sub; - foreach (QString device, devList) { - sub = truncTag(RealTag, "l") + "." + truncTag(RealTag, "a"); - foreach (QString Point, PointList) { - if(Point.isEmpty() || Point.split(".").length() != 3) - { - continue; - } - value = Point.section(".", 2, 2); - if(value == "channel") - { - if(channel) - { - continue; - } - channel = true; - } - tagMap[devGroup].append(sub + "." + Point.section(".", 0, 0) + "." + device + "." + Point.section(".", 1, 1) + "." + value); - } - } - } - - for(int nIndex=0; nIndexreadChannelTag(truncTag(tagName, "d"), table); - } - else - { - temp = CDbInterface::instance()->readPointInfo(truncTag(tagName, "p"), table); - } - if(temp.isEmpty()) - { - continue; - } - if(vlast == "channel") - { - realData.tag_name = temp; - realData.description = m_channelTxList[0]; - realData.table_name = "fes_channel_para"; - realData.column = "status"; - realData.type = TYPE_CHANNEL; - } - else - { - m_tagMap[GroupNo].append(QVariant::fromValue(tagName)); - realData.tag_name = truncTag(tagName, "p"); - realData.description = temp.section(",", 0, 0); - realData.table_name = table; - if(realData.table_name == "analog" || realData.table_name == "accuml") - { - realData.unit = temp.section(",", 1, 1); - } - else if(realData.table_name == "digital" || realData.table_name == "mix") - { - realData.stateTextName = temp.section(",", 1, 1); - } - } - realData.nDomainId = CDbInterface::instance()->readDomainId(truncTag(tagName, "l")); - realData.nAppId = CDbInterface::instance()->readAppId(truncTag(tagName, "a")); - if(insertIndex == -1) - { - insertIndex = m_groupMap[GroupNo].length(); - } - m_groupMap[GroupNo].append(realData); - if(realData.type == TYPE_POINT) - { - m_pDpcdaForApp->subscribe(realData.table_name.toStdString(), realData.tag_name.toStdString(), realData.column.toStdString()); - } - } - if(insertIndex == -1) - { - continue; - } - if(RealTagList.length() > 1) - { - QString description = CDbInterface::instance()->readDevGroup(devGroup); - if(!description.isEmpty()) - { - SRealData sRealData; - sRealData.tag_name = devGroup; - sRealData.description = description; - sRealData.type = TYPE_DEVGROUP; - m_groupMap[GroupNo].insert(insertIndex, sRealData); - } - } - } - - QTableView *view = m_tableMap.value(GroupNo); - if(view) - { - CRealTableModel *model = dynamic_cast(view->model()); - model->updateRealData(m_groupMap[GroupNo]); - } - return ""; -} - -QVariantList CPointRealDataWidget::getPointList(int GroupNo) -{ - return m_tagMap.value(GroupNo); -} - -void CPointRealDataWidget::setColumnWidth(int GroupNo, int column, int width) -{ - QTableView *view = m_tableMap.value(GroupNo); - if(view) - { - if(column == -1) - { - for(int nIndex(0); nIndexmodel()->columnCount(); nIndex++) - { - view->setColumnWidth(nIndex, width); - } - } - else - { - view->setColumnWidth(column, width); - } - } -} - -void CPointRealDataWidget::setRowHeight(int GroupNo, int row, int height) -{ - QTableView *view = m_tableMap.value(GroupNo); - if(view) - { - if(row == -1) - { - for(int nIndex(0); nIndexmodel()->rowCount(); nIndex++) - { - view->setRowHeight(nIndex, height); - } - } - else - { - view->setRowHeight(row, height); - } - } -} - -void CPointRealDataWidget::setColumnCount(int GroupNo, int count) -{ - QTableView *view = m_tableMap.value(GroupNo); - if(view) - { - CRealTableModel *model = dynamic_cast(view->model()); - model->setColumnCount(count); - } -} - -void CPointRealDataWidget::setHeaderVisible(int GroupNo, int header, bool visible) -{ - QTableView *view = m_tableMap.value(GroupNo); - if(view) - { - if(header == Qt::Horizontal) - { - view->horizontalHeader()->setVisible(visible); - } - else if(header == Qt::Vertical) - { - view->verticalHeader()->setVisible(visible); - } - } -} - -void CPointRealDataWidget::setShowGrid(int GroupNo, bool isShow) -{ - QTableView *view = m_tableMap.value(GroupNo); - if(view) - { - view->setShowGrid(isShow); - } -} - -void CPointRealDataWidget::setScrollBarOn(int GroupNo, int direct, bool on) -{ - QTableView *view = m_tableMap.value(GroupNo); - if(view) - { - if(direct == Qt::Horizontal) - { - view->setHorizontalScrollBarPolicy(on ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); - } - else if(direct == Qt::Vertical) - { - view->setVerticalScrollBarPolicy(on ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); - } - } -} - -void CPointRealDataWidget::setAlternatingRowColors(int GroupNo, bool enable) -{ - QTableView *view = m_tableMap.value(GroupNo); - if(view) - { - view->setAlternatingRowColors(enable); - } -} - -void CPointRealDataWidget::setChannelText(const QString &text, const QString &normal, const QString &abnormal) -{ - m_channelTxList.clear(); - m_channelTxList.append(text); - m_channelTxList.append(normal); - m_channelTxList.append(abnormal); - - QMap::const_iterator iter = m_tableMap.constBegin(); - for(; iter != m_tableMap.constEnd(); iter++) - { - QTableView * view = iter.value(); - if(view) - { - CRealTableModel *model = dynamic_cast(view->model()); - model->updateChannelText(m_channelTxList); - } - } -} - -void CPointRealDataWidget::updatePointValue(const QSet &groupSet) -{ - foreach (const int &groupNo, groupSet) - { - QTableView *view = m_tableMap.value(groupNo); - if(view == NULL) - { - continue; - } - CRealTableModel *model = dynamic_cast(view->model()); - QList temp = m_groupMap.value(groupNo); - model->updateRealValue(temp); - } -} - -void CPointRealDataWidget::updatePointValue(int groupNo, QList data) -{ - QTableView *view = m_tableMap.value(groupNo); - if(view == NULL) - { - return; - } - CRealTableModel *model = dynamic_cast(view->model()); - model->updateRealValue(data); -} - -void CPointRealDataWidget::onTimer() -{ - if(m_objAppContext == PDR_MODE || !m_isRtdbNormal) - { - m_pTimer->stop(); - return; - } - - QMap >::iterator iter = m_groupMap.begin(); - for(; iter != m_groupMap.end(); iter++) - { - QList &listData = iter.value(); - bool change = false; - for(int nIndex(0); nIndexreadPointValue(sRealData)) - { - change = true; - } - else - { - m_isRtdbNormal = false; - } - } - if(change) - { - updatePointValue(iter.key(), listData); - } - } -} - -void CPointRealDataWidget::slotUpdateAi(const QMap > &aiMap) -{ - QSet groupSet; - QMap >::const_iterator iter = aiMap.constBegin(); - for(; iter != aiMap.constEnd(); iter++) - { - QMap >::iterator it = m_groupMap.begin(); - for(; it != m_groupMap.end(); it++) - { - QList &dataList = it.value(); - for(int i = 0; i < dataList.length(); i++) - { - SRealData &data = dataList[i]; - if(data.table_name != "analog") - { - continue; - } - if(data.tag_name != iter.key()) - { - continue; - } - data.isInit = true; - data.value = iter.value().first; - data.status = iter.value().second; - groupSet.insert(it.key()); - break; - } - } - } - if(!groupSet.isEmpty()) - { - updatePointValue(groupSet); - } -} - -void CPointRealDataWidget::slotUpdateDi(const QMap > &diMap) -{ - QSet groupSet; - QMap >::const_iterator iter = diMap.constBegin(); - for(; iter != diMap.constEnd(); iter++) - { - QMap >::iterator it = m_groupMap.begin(); - for(; it != m_groupMap.end(); it++) - { - QList &dataList = it.value(); - for(int i = 0; i < dataList.length(); i++) - { - SRealData &data = dataList[i]; - if(data.table_name != "digital") - { - continue; - } - if(data.tag_name != iter.key()) - { - continue; - } - data.isInit = true; - data.value = iter.value().first; - data.status = iter.value().second; - groupSet.insert(it.key()); - break; - } - } - } - if(!groupSet.isEmpty()) - { - updatePointValue(groupSet); - } -} - -void CPointRealDataWidget::slotUpdatePi(const QMap > &piMap) -{ - QSet groupSet; - QMap >::const_iterator iter = piMap.constBegin(); - for(; iter != piMap.constEnd(); iter++) - { - QMap >::iterator it = m_groupMap.begin(); - for(; it != m_groupMap.end(); it++) - { - QList &dataList = it.value(); - for(int i = 0; i < dataList.length(); i++) - { - SRealData &data = dataList[i]; - if(data.table_name != "accuml") - { - continue; - } - if(data.tag_name != iter.key()) - { - continue; - } - data.isInit = true; - data.value = iter.value().first; - data.status = iter.value().second; - groupSet.insert(it.key()); - break; - } - } - } - if(!groupSet.isEmpty()) - { - updatePointValue(groupSet); - } -} - -void CPointRealDataWidget::slotUpdateMi(const QMap > &miMap) -{ - QSet groupSet; - QMap >::const_iterator iter = miMap.constBegin(); - for(; iter != miMap.constEnd(); iter++) - { - QMap >::iterator it = m_groupMap.begin(); - for(; it != m_groupMap.end(); it++) - { - QList &dataList = it.value(); - for(int i = 0; i < dataList.length(); i++) - { - SRealData &data = dataList[i]; - if(data.table_name != "mix") - { - continue; - } - if(data.tag_name != iter.key()) - { - continue; - } - data.isInit = true; - data.value = iter.value().first; - data.status = iter.value().second; - groupSet.insert(it.key()); - break; - } - } - } - if(!groupSet.isEmpty()) - { - updatePointValue(groupSet); - } -} - -QString CPointRealDataWidget::truncTag(const QString &tagName, const QString &format) -{ - QString ret = ""; - if(format == "l") - { - ret = tagName.section(".", 0, 0); - } - else if(format == "a") - { - ret = tagName.section(".", 1, 1); - } - else if(format == "t") - { - ret = tagName.section(".", 2, 2); - } - else if(format == "d") - { - ret = tagName.section(".", 3, 4); - } - else if(format == "g") - { - QStringList temp = tagName.section(".", 3, 4).split("_"); - temp.pop_back(); - ret = temp.join("_"); - } - else if(format == "p") - { - ret = tagName.section(".", 3, 5); - } - else if(format == "point") - { - ret = tagName.section(".", 5, 5); - } - else if(format == "v") - { - ret = tagName.section(".", -1, -1); - } - return ret; -} +#include "CPointRealDataWidget.h" +#include "CDbInterface.h" +#include "CRealTableModel.h" +#include "CRealDataCollect.h" +#include +#include +#include + +CPointRealDataWidget::CPointRealDataWidget(bool editMode, QWidget *parent) + : QWidget(parent), + m_isEditMode(editMode), + m_nGroupNo(1), + m_isRtdbNormal(true), + m_pTimer(NULL), + m_pDpcdaForApp(NULL) +{ + initialize(); +} + +CPointRealDataWidget::~CPointRealDataWidget() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = NULL; + + if(!m_isEditMode) + { + CRealDataCollect::instance()->release(); + + CDbInterface::instance()->destory(); + } +} + +void CPointRealDataWidget::initialize() +{ + if(m_isEditMode) + { + QTableView * tableView = new QTableView(); + QGridLayout * layout = new QGridLayout(this); + layout->addWidget(tableView); + layout->setMargin(0); + setLayout(layout); + return; + } + + setChannelText(tr("通讯状态"), tr("正常"), tr("异常")); + + qRegisterMetaType>>("QMap>"); + qRegisterMetaType>>("QMap>"); + qRegisterMetaType>>("QMap>"); + + m_objAppContext = RT_MODE; + CRealDataCollect::instance()->setAppContext(m_objAppContext); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateAi, this, &CPointRealDataWidget::slotUpdateAi); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CPointRealDataWidget::slotUpdateDi); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updatePi, this, &CPointRealDataWidget::slotUpdatePi); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateMi, this, &CPointRealDataWidget::slotUpdateMi); + m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); + + m_pTimer = new QTimer(this); + connect(m_pTimer, &QTimer::timeout, this, &CPointRealDataWidget::onTimer); + m_pTimer->start(1000); +} + +void CPointRealDataWidget::switchAppcontext(int appContext) +{ + if(m_objAppContext == appContext) + { + return; + } + m_objAppContext = (EN_AppContext)appContext; + if(m_objAppContext == PDR_MODE) + { + m_pTimer->stop(); + } + else + { + m_pTimer->start(1000); + } + + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + } + + CRealDataCollect::instance()->setAppContext(m_objAppContext); + + QMap >::iterator iter = m_groupMap.begin(); + for(; iter != m_groupMap.end(); iter++) + { + QList &dataList = iter.value(); + QList::iterator it = dataList.begin(); + for(; it != dataList.end(); it++) + { + SRealData &data = *it; + data.isInit = false; + if(data.type == TYPE_POINT) + { + m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), data.column.toStdString()); + } + } + } +} + +int CPointRealDataWidget::addGroup(const QStringList &name, int row, int column) +{ + QTableView * tableView = new QTableView(); + tableView->setSelectionMode(QAbstractItemView::NoSelection); + tableView->horizontalHeader()->setStretchLastSection(true); + tableView->horizontalHeader()->setSectionsClickable(false); + tableView->setFocusPolicy(Qt::NoFocus); + tableView->setAlternatingRowColors(true); + tableView->verticalHeader()->setVisible(false); + tableView->setShowGrid(false); + tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + CRealTableModel * tableModel = new CRealTableModel(tableView, name); + tableModel->updateChannelText(m_channelTxList); + tableView->setModel(tableModel); + + if(!layout()) + { + QGridLayout *layout = new QGridLayout(this); + layout->setMargin(0); + layout->setSpacing(0); + setLayout(layout); + } + QGridLayout *gLayout = dynamic_cast(layout()); + gLayout->addWidget(tableView, row, column); + + m_groupMap.insert(m_nGroupNo, QList()); + m_tableMap.insert(m_nGroupNo, tableView); + + return m_nGroupNo++; +} + +QString CPointRealDataWidget::addPoint(int GroupNo, const QStringList &RealTagList, const QStringList &PointList) +{ + if(m_groupMap.find(GroupNo) == m_groupMap.constEnd()) + { + return tr("未找到组号%1!").arg(QString::number(GroupNo)); + } + + //< 得到所有可能的点标签 + QMap tagMap; + QString devGroup; + foreach (QString RealTag, RealTagList) { + if(RealTag.isEmpty() || RealTag.split(".").length() != 7) + { + continue; + } + bool channel = false; + QStringList devList; + devGroup = truncTag(RealTag, "g"); + CDbInterface::instance()->readDevice(devGroup, devList); + QString value; + QString sub; + foreach (QString device, devList) { + sub = truncTag(RealTag, "l") + "." + truncTag(RealTag, "a"); + foreach (QString Point, PointList) { + if(Point.isEmpty() || Point.split(".").length() != 3) + { + continue; + } + value = Point.section(".", 2, 2); + if(value == "channel") + { + if(channel) + { + continue; + } + channel = true; + } + tagMap[devGroup].append(sub + "." + Point.section(".", 0, 0) + "." + device + "." + Point.section(".", 1, 1) + "." + value); + } + } + } + + for(int nIndex=0; nIndexreadChannelTag(truncTag(tagName, "d"), table); + } + else + { + temp = CDbInterface::instance()->readPointInfo(truncTag(tagName, "p"), table); + } + if(temp.isEmpty()) + { + continue; + } + if(vlast == "channel") + { + realData.tag_name = temp; + realData.description = m_channelTxList[0]; + realData.table_name = "fes_channel_para"; + realData.column = "status"; + realData.type = TYPE_CHANNEL; + } + else + { + m_tagMap[GroupNo].append(QVariant::fromValue(tagName)); + realData.tag_name = truncTag(tagName, "p"); + realData.description = temp.section(",", 0, 0); + realData.table_name = table; + if(realData.table_name == "analog" || realData.table_name == "accuml") + { + realData.unit = temp.section(",", 1, 1); + } + else if(realData.table_name == "digital" || realData.table_name == "mix") + { + realData.stateTextName = temp.section(",", 1, 1); + } + } + realData.nDomainId = CDbInterface::instance()->readDomainId(truncTag(tagName, "l")); + realData.nAppId = CDbInterface::instance()->readAppId(truncTag(tagName, "a")); + if(insertIndex == -1) + { + insertIndex = m_groupMap[GroupNo].length(); + } + m_groupMap[GroupNo].append(realData); + if(realData.type == TYPE_POINT) + { + m_pDpcdaForApp->subscribe(realData.table_name.toStdString(), realData.tag_name.toStdString(), realData.column.toStdString()); + } + } + if(insertIndex == -1) + { + continue; + } + if(RealTagList.length() > 1) + { + QString description = CDbInterface::instance()->readDevGroup(devGroup); + if(!description.isEmpty()) + { + SRealData sRealData; + sRealData.tag_name = devGroup; + sRealData.description = description; + sRealData.type = TYPE_DEVGROUP; + m_groupMap[GroupNo].insert(insertIndex, sRealData); + } + } + } + + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + model->updateRealData(m_groupMap[GroupNo]); + } + return ""; +} + +QVariantList CPointRealDataWidget::getPointList(int GroupNo) +{ + return m_tagMap.value(GroupNo); +} + +void CPointRealDataWidget::setColumnWidth(int GroupNo, int column, int width) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + if(column == -1) + { + for(int nIndex(0); nIndexmodel()->columnCount(); nIndex++) + { + view->setColumnWidth(nIndex, width); + } + } + else + { + view->setColumnWidth(column, width); + } + } +} + +void CPointRealDataWidget::setRowHeight(int GroupNo, int row, int height) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + if(row == -1) + { + for(int nIndex(0); nIndexmodel()->rowCount(); nIndex++) + { + view->setRowHeight(nIndex, height); + } + } + else + { + view->setRowHeight(row, height); + } + } +} + +void CPointRealDataWidget::setColumnCount(int GroupNo, int count) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + model->setColumnCount(count); + } +} + +void CPointRealDataWidget::setHeaderVisible(int GroupNo, int header, bool visible) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + if(header == Qt::Horizontal) + { + view->horizontalHeader()->setVisible(visible); + } + else if(header == Qt::Vertical) + { + view->verticalHeader()->setVisible(visible); + } + } +} + +void CPointRealDataWidget::setShowGrid(int GroupNo, bool isShow) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + view->setShowGrid(isShow); + } +} + +void CPointRealDataWidget::setScrollBarOn(int GroupNo, int direct, bool on) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + if(direct == Qt::Horizontal) + { + view->setHorizontalScrollBarPolicy(on ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); + } + else if(direct == Qt::Vertical) + { + view->setVerticalScrollBarPolicy(on ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); + } + } +} + +void CPointRealDataWidget::setAlternatingRowColors(int GroupNo, bool enable) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + view->setAlternatingRowColors(enable); + } +} + +void CPointRealDataWidget::setChannelText(const QString &text, const QString &normal, const QString &abnormal) +{ + m_channelTxList.clear(); + m_channelTxList.append(text); + m_channelTxList.append(normal); + m_channelTxList.append(abnormal); + + QMap::const_iterator iter = m_tableMap.constBegin(); + for(; iter != m_tableMap.constEnd(); iter++) + { + QTableView * view = iter.value(); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + model->updateChannelText(m_channelTxList); + } + } +} + +void CPointRealDataWidget::updatePointValue(const QSet &groupSet) +{ + foreach (const int &groupNo, groupSet) + { + QTableView *view = m_tableMap.value(groupNo); + if(view == NULL) + { + continue; + } + CRealTableModel *model = dynamic_cast(view->model()); + QList temp = m_groupMap.value(groupNo); + model->updateRealValue(temp); + } +} + +void CPointRealDataWidget::updatePointValue(int groupNo, QList data) +{ + QTableView *view = m_tableMap.value(groupNo); + if(view == NULL) + { + return; + } + CRealTableModel *model = dynamic_cast(view->model()); + model->updateRealValue(data); +} + +void CPointRealDataWidget::onTimer() +{ + if(m_objAppContext == PDR_MODE || !m_isRtdbNormal) + { + m_pTimer->stop(); + return; + } + + QMap >::iterator iter = m_groupMap.begin(); + for(; iter != m_groupMap.end(); iter++) + { + QList &listData = iter.value(); + bool change = false; + for(int nIndex(0); nIndexreadPointValue(sRealData)) + { + change = true; + } + else + { + m_isRtdbNormal = false; + } + } + if(change) + { + updatePointValue(iter.key(), listData); + } + } +} + +void CPointRealDataWidget::slotUpdateAi(const QMap > &aiMap) +{ + QSet groupSet; + QMap >::const_iterator iter = aiMap.constBegin(); + for(; iter != aiMap.constEnd(); iter++) + { + QMap >::iterator it = m_groupMap.begin(); + for(; it != m_groupMap.end(); it++) + { + QList &dataList = it.value(); + for(int i = 0; i < dataList.length(); i++) + { + SRealData &data = dataList[i]; + if(data.table_name != "analog") + { + continue; + } + if(data.tag_name != iter.key()) + { + continue; + } + data.isInit = true; + data.value = iter.value().first; + data.status = iter.value().second; + groupSet.insert(it.key()); + break; + } + } + } + if(!groupSet.isEmpty()) + { + updatePointValue(groupSet); + } +} + +void CPointRealDataWidget::slotUpdateDi(const QMap > &diMap) +{ + QSet groupSet; + QMap >::const_iterator iter = diMap.constBegin(); + for(; iter != diMap.constEnd(); iter++) + { + QMap >::iterator it = m_groupMap.begin(); + for(; it != m_groupMap.end(); it++) + { + QList &dataList = it.value(); + for(int i = 0; i < dataList.length(); i++) + { + SRealData &data = dataList[i]; + if(data.table_name != "digital") + { + continue; + } + if(data.tag_name != iter.key()) + { + continue; + } + data.isInit = true; + data.value = iter.value().first; + data.status = iter.value().second; + groupSet.insert(it.key()); + break; + } + } + } + if(!groupSet.isEmpty()) + { + updatePointValue(groupSet); + } +} + +void CPointRealDataWidget::slotUpdatePi(const QMap > &piMap) +{ + QSet groupSet; + QMap >::const_iterator iter = piMap.constBegin(); + for(; iter != piMap.constEnd(); iter++) + { + QMap >::iterator it = m_groupMap.begin(); + for(; it != m_groupMap.end(); it++) + { + QList &dataList = it.value(); + for(int i = 0; i < dataList.length(); i++) + { + SRealData &data = dataList[i]; + if(data.table_name != "accuml") + { + continue; + } + if(data.tag_name != iter.key()) + { + continue; + } + data.isInit = true; + data.value = iter.value().first; + data.status = iter.value().second; + groupSet.insert(it.key()); + break; + } + } + } + if(!groupSet.isEmpty()) + { + updatePointValue(groupSet); + } +} + +void CPointRealDataWidget::slotUpdateMi(const QMap > &miMap) +{ + QSet groupSet; + QMap >::const_iterator iter = miMap.constBegin(); + for(; iter != miMap.constEnd(); iter++) + { + QMap >::iterator it = m_groupMap.begin(); + for(; it != m_groupMap.end(); it++) + { + QList &dataList = it.value(); + for(int i = 0; i < dataList.length(); i++) + { + SRealData &data = dataList[i]; + if(data.table_name != "mix") + { + continue; + } + if(data.tag_name != iter.key()) + { + continue; + } + data.isInit = true; + data.value = iter.value().first; + data.status = iter.value().second; + groupSet.insert(it.key()); + break; + } + } + } + if(!groupSet.isEmpty()) + { + updatePointValue(groupSet); + } +} + +QString CPointRealDataWidget::truncTag(const QString &tagName, const QString &format) +{ + QString ret = ""; + if(format == "l") + { + ret = tagName.section(".", 0, 0); + } + else if(format == "a") + { + ret = tagName.section(".", 1, 1); + } + else if(format == "t") + { + ret = tagName.section(".", 2, 2); + } + else if(format == "d") + { + ret = tagName.section(".", 3, 4); + } + else if(format == "g") + { + QStringList temp = tagName.section(".", 3, 4).split("_"); + temp.pop_back(); + ret = temp.join("_"); + } + else if(format == "p") + { + ret = tagName.section(".", 3, 5); + } + else if(format == "point") + { + ret = tagName.section(".", 5, 5); + } + else if(format == "v") + { + ret = tagName.section(".", -1, -1); + } + return ret; +} diff --git a/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.h b/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.h index cf995e18..f2f44038 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.h +++ b/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.h @@ -1,143 +1,143 @@ -#ifndef CPOINTREALDATAWIDGET_H -#define CPOINTREALDATAWIDGET_H - -#include -#include -#include -#include -#include "CPointPublic.h" -#include "dp_chg_data_api/CDpcdaForApp.h" - -class QTableView; -class CRealDataCollect; -class CPointRealDataWidget : public QWidget -{ - Q_OBJECT - -public: - CPointRealDataWidget(bool editMode, QWidget *parent = 0); - ~CPointRealDataWidget(); - - void initialize(); - -public slots: - /** - * @brief switchAppcontext 切换数据来源 - * @param appContext 1: 实时数据 2: 事故反演 - */ - void switchAppcontext(int appContext = 1); - - /** - * @brief addGroup 添加数据组 - * @param name 组名 为空不显示 - * @param row 行号 QGridLayout - * @param column 列号 QGridLayout - * @return 组号 - */ - int addGroup(const QStringList &name, int row, int column); - - /** - * @brief addPoint 往组内添加测点 - * @param GroupNo 组号 - * @param RealTagList 关联测点列表 "station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value" - * @param PointList 测点列表 "digital.OC1.value" - * @return 成功返回空字符串,失败返回错误信息 - */ - QString addPoint(int GroupNo, const QStringList &RealTagList, const QStringList &PointList); - - /** - * @brief getPointList 获取组内测点列表 - * @param GroupNo 组号 - * @return 测点列表 - */ - QVariantList getPointList(int GroupNo); - - /** - * @brief setColumnWidth 设置组的列宽 - * @param GroupNo 组号 - * @param column 列号 -1代表所有列 - * @param width 宽度 - */ - void setColumnWidth(int GroupNo, int column, int width); - - /** - * @brief setRowHeight 设置组的行高 - * @param GroupNo 组号 - * @param row 行号 -1代表所有行 - * @param height 高度 - */ - void setRowHeight(int GroupNo, int row, int height); - - /** - * @brief setColumnCount 设置列数 - * @param GroupNo 组号 - * @param count 列数 - */ - void setColumnCount(int GroupNo, int count); - - /** - * @brief setHeaderVisible 设置表头是否显示 - * @param GroupNo 组号 - * @param header 1:水平 2:垂直 - * @param visible 是否显示 - */ - void setHeaderVisible(int GroupNo, int header = Qt::Horizontal, bool visible = true); - - /** - * @brief setShowGrid 设置是否显示表格网格线 - * @param GroupNo 组号 - * @param isShow 是否显示 - */ - void setShowGrid(int GroupNo, bool isShow = true); - - /** - * @brief setScrollBarOn 设置是否显示滚动条 - * @param GroupNo 组号 - * @param direct 1:水平 2:垂直 - * @param on 是否显示 - */ - void setScrollBarOn(int GroupNo, int direct = Qt::Horizontal, bool on = true); - - /** - * @brief setAlternatingRowColors 设置启用间隔色 - * @param GroupNo 组号 - * @param enable 是否启用 - */ - void setAlternatingRowColors(int GroupNo, bool enable = true); - - /** - * @brief setChannelText 设置通讯状态文本 - * @param text 显示名称 默认为通讯状态 - * @param normal 状态正常显示文本 默认为正常 - * @param abnormal 状态异常显示文本 默认为异常 - */ - void setChannelText(const QString& text, const QString &normal, const QString &abnormal); - -private slots: - void updatePointValue(const QSet &groupSet); - void updatePointValue(int groupNo, QList data); - - void onTimer(); - void slotUpdateAi(const QMap>& aiMap); - void slotUpdateDi(const QMap>& diMap); - void slotUpdatePi(const QMap>& piMap); - void slotUpdateMi(const QMap>& miMap); - -private: - QString truncTag(const QString &tagName, const QString &format); - -private: - bool m_isEditMode; - int m_nGroupNo; - bool m_isRtdbNormal; - EN_AppContext m_objAppContext; - QTimer * m_pTimer; - kbd_service::CDpcdaForApp *m_pDpcdaForApp; - QMap m_tableMap; - QMap > m_groupMap; - QMap m_tagMap; - - QStringList m_channelTxList; -}; - -#endif // CPOINTREALDATAWIDGET_H +#ifndef CPOINTREALDATAWIDGET_H +#define CPOINTREALDATAWIDGET_H + +#include +#include +#include +#include +#include "CPointPublic.h" +#include "dp_chg_data_api/CDpcdaForApp.h" + +class QTableView; +class CRealDataCollect; +class CPointRealDataWidget : public QWidget +{ + Q_OBJECT + +public: + CPointRealDataWidget(bool editMode, QWidget *parent = 0); + ~CPointRealDataWidget(); + + void initialize(); + +public slots: + /** + * @brief switchAppcontext 切换数据来源 + * @param appContext 1: 实时数据 2: 事故反演 + */ + void switchAppcontext(int appContext = 1); + + /** + * @brief addGroup 添加数据组 + * @param name 组名 为空不显示 + * @param row 行号 QGridLayout + * @param column 列号 QGridLayout + * @return 组号 + */ + int addGroup(const QStringList &name, int row, int column); + + /** + * @brief addPoint 往组内添加测点 + * @param GroupNo 组号 + * @param RealTagList 关联测点列表 "station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value" + * @param PointList 测点列表 "digital.OC1.value" + * @return 成功返回空字符串,失败返回错误信息 + */ + QString addPoint(int GroupNo, const QStringList &RealTagList, const QStringList &PointList); + + /** + * @brief getPointList 获取组内测点列表 + * @param GroupNo 组号 + * @return 测点列表 + */ + QVariantList getPointList(int GroupNo); + + /** + * @brief setColumnWidth 设置组的列宽 + * @param GroupNo 组号 + * @param column 列号 -1代表所有列 + * @param width 宽度 + */ + void setColumnWidth(int GroupNo, int column, int width); + + /** + * @brief setRowHeight 设置组的行高 + * @param GroupNo 组号 + * @param row 行号 -1代表所有行 + * @param height 高度 + */ + void setRowHeight(int GroupNo, int row, int height); + + /** + * @brief setColumnCount 设置列数 + * @param GroupNo 组号 + * @param count 列数 + */ + void setColumnCount(int GroupNo, int count); + + /** + * @brief setHeaderVisible 设置表头是否显示 + * @param GroupNo 组号 + * @param header 1:水平 2:垂直 + * @param visible 是否显示 + */ + void setHeaderVisible(int GroupNo, int header = Qt::Horizontal, bool visible = true); + + /** + * @brief setShowGrid 设置是否显示表格网格线 + * @param GroupNo 组号 + * @param isShow 是否显示 + */ + void setShowGrid(int GroupNo, bool isShow = true); + + /** + * @brief setScrollBarOn 设置是否显示滚动条 + * @param GroupNo 组号 + * @param direct 1:水平 2:垂直 + * @param on 是否显示 + */ + void setScrollBarOn(int GroupNo, int direct = Qt::Horizontal, bool on = true); + + /** + * @brief setAlternatingRowColors 设置启用间隔色 + * @param GroupNo 组号 + * @param enable 是否启用 + */ + void setAlternatingRowColors(int GroupNo, bool enable = true); + + /** + * @brief setChannelText 设置通讯状态文本 + * @param text 显示名称 默认为通讯状态 + * @param normal 状态正常显示文本 默认为正常 + * @param abnormal 状态异常显示文本 默认为异常 + */ + void setChannelText(const QString& text, const QString &normal, const QString &abnormal); + +private slots: + void updatePointValue(const QSet &groupSet); + void updatePointValue(int groupNo, QList data); + + void onTimer(); + void slotUpdateAi(const QMap>& aiMap); + void slotUpdateDi(const QMap>& diMap); + void slotUpdatePi(const QMap>& piMap); + void slotUpdateMi(const QMap>& miMap); + +private: + QString truncTag(const QString &tagName, const QString &format); + +private: + bool m_isEditMode; + int m_nGroupNo; + bool m_isRtdbNormal; + EN_AppContext m_objAppContext; + QTimer * m_pTimer; + kbd_service::CDpcdaForApp *m_pDpcdaForApp; + QMap m_tableMap; + QMap > m_groupMap; + QMap m_tagMap; + + QStringList m_channelTxList; +}; + +#endif // CPOINTREALDATAWIDGET_H diff --git a/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.cpp b/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.cpp index da263916..84d8c39c 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.cpp +++ b/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "CPointRealPluginWidget.h" -#include "CPointRealDataWidget.h" -#include - -CPointRealPluginWidget::CPointRealPluginWidget() -{ - -} - -CPointRealPluginWidget::~CPointRealPluginWidget() -{ - -} - -bool CPointRealPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CPointRealDataWidget *pWidget = new CPointRealDataWidget(editMode, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CPointRealPluginWidget::release() -{ - -} +#include "CPointRealPluginWidget.h" +#include "CPointRealDataWidget.h" +#include + +CPointRealPluginWidget::CPointRealPluginWidget() +{ + +} + +CPointRealPluginWidget::~CPointRealPluginWidget() +{ + +} + +bool CPointRealPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CPointRealDataWidget *pWidget = new CPointRealDataWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CPointRealPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.h b/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.h index 82f51a64..64233d8e 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.h +++ b/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CPOINTREALPLUGINWIDGET_H -#define CPOINTREALPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CPointRealPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CPointRealPluginWidget(); - ~CPointRealPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CPOINTREALPLUGINWIDGET_H +#ifndef CPOINTREALPLUGINWIDGET_H +#define CPOINTREALPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CPointRealPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CPointRealPluginWidget(); + ~CPointRealPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CPOINTREALPLUGINWIDGET_H diff --git a/product/src/gui/plugin/PointRealDataWidget/CRealDataCollect.cpp b/product/src/gui/plugin/PointRealDataWidget/CRealDataCollect.cpp index baaf69ca..61b9c27d 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CRealDataCollect.cpp +++ b/product/src/gui/plugin/PointRealDataWidget/CRealDataCollect.cpp @@ -1,286 +1,286 @@ -#include "CRealDataCollect.h" -#include - -CRealDataCollect* CRealDataCollect::m_pInstance = NULL; - -CRealDataCollect::CRealDataCollect(EN_AppContext appContext) - : m_pMbComm(NULL), - m_pTimer(NULL), - m_nTimeCount(0), - m_objAppContext(appContext) -{ - initMsg(); - if(!addSub()) - { - return; - } - - m_pTimer = new QTimer(this); - connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); - m_pTimer->start(100); -} - -CRealDataCollect *CRealDataCollect::instance() -{ - if(m_pInstance == NULL) - { - m_pInstance = new CRealDataCollect(RT_MODE); - } - return m_pInstance; -} - -void CRealDataCollect::setAppContext(EN_AppContext appContext) -{ - if(m_objAppContext == appContext) - { - return; - } - - delSub(); - clearMsg(); - m_aiMap.clear(); - m_diMap.clear(); - m_piMap.clear(); - m_miMap.clear(); - - m_objAppContext = appContext; - addSub(); -} - -void CRealDataCollect::release() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - delSub(); - closeMsg(); - m_pInstance = NULL; - delete this; -} - -void CRealDataCollect::initMsg() -{ - if(m_pMbComm == NULL) - { - m_pMbComm = new kbd_net::CMbCommunicator("PointRealDataWidget"); - } -} - -void CRealDataCollect::closeMsg() -{ - if(m_pMbComm != NULL) - { - delete m_pMbComm; - } - m_pMbComm = NULL; -} - -void CRealDataCollect::clearMsg() -{ - if(m_pMbComm) - { - kbd_net::CMbMessage objMsg; - while(m_pMbComm->recvMsg(objMsg, 0)) - {} - } -} - -bool CRealDataCollect::addSub() -{ - if(m_pMbComm) - { - if(m_objAppContext == RT_MODE) - { - return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else if(m_objAppContext == PDR_MODE) - { - return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET); - } - else - { - return false; - } - } - else - { - return false; - } -} - -bool CRealDataCollect::delSub() -{ - if(m_pMbComm) - { - if(m_objAppContext == RT_MODE) - { - return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else if(m_objAppContext == PDR_MODE) - { - return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET); - } - else - { - return false; - } - } - else - { - return false; - } -} - -void CRealDataCollect::recvMessage() -{ - m_nTimeCount = (m_nTimeCount + 1) % 36000; - - if(m_nTimeCount % 10 == 0) - { - processChangeData(); - } - - try - { - kbd_net::CMbMessage objMsg; - for(int i = 0; i < 6; i++) - { - if(m_pMbComm->recvMsg(objMsg, 0)) - { - if(objMsg.isValid()) - { - if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) - { - continue; - } - if((objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) - && (objMsg.getChannelID() != (CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET))) - { - continue; - } - parserMsg(objMsg); - } - } - } - } - catch(...) - { - - } -} - -void CRealDataCollect::processChangeData() -{ - if(!m_aiMap.isEmpty()) - { - emit signal_updateAi(m_aiMap); - m_aiMap.clear(); - } - - if(!m_diMap.isEmpty()) - { - emit signal_updateDi(m_diMap); - m_diMap.clear(); - } - - if(!m_piMap.isEmpty()) - { - emit signal_updatePi(m_piMap); - m_piMap.clear(); - } - - if(!m_miMap.isEmpty()) - { - emit signal_updateMi(m_miMap); - m_miMap.clear(); - } -} - -int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) -{ - kbd_idlfile::SRealTimeDataPkg changeDataPackage; - try - { - changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); - int aiSize = changeDataPackage.stairtd_size(); - if(aiSize > 0) - { - kbd_idlfile::SAiRealTimeData aiStru; - QString tagName; - float value; - uint status; - for(int i = 0; i < aiSize;++i) - { - aiStru = changeDataPackage.stairtd(i); - tagName = QString::fromStdString(aiStru.strtagname()); - value = aiStru.fvalue(); - status = aiStru.ustatus(); -// emit signal_updateAi(tagName, value, status); - m_aiMap[tagName] = qMakePair(value, status); - } - } - - int diSize = changeDataPackage.stdirtd_size(); - if(diSize > 0) - { - kbd_idlfile::SDiRealTimeData diStu; - QString tagName; - int value; - uint status; - for(int i = 0; i < diSize; ++i) - { - diStu = changeDataPackage.stdirtd(i); - tagName = QString::fromStdString(diStu.strtagname()); - value = diStu.nvalue(); - status = diStu.ustatus(); -// emit signal_updateDi(tagName, value, status); - m_diMap[tagName] = qMakePair(value, status); - } - } - - int piSize = changeDataPackage.stpirtd_size(); - if(piSize > 0) - { - kbd_idlfile::SPiRealTimeData piStu; - QString tagName; - double value; - uint status; - for(int i = 0 ; i < piSize; ++i) - { - piStu = changeDataPackage.stpirtd(i); - tagName = QString::fromStdString(piStu.strtagname()); - value = piStu.dvalue(); - status = piStu.ustatus(); -// emit signal_updatePi(tagName, value, status); - m_piMap[tagName] = qMakePair(value, status); - } - } - - int miSize = changeDataPackage.stmirtd_size(); - if(miSize > 0) - { - kbd_idlfile::SMiRealTimeData miStu; - QString tagName; - int value; - uint status; - for(int i = 0 ; i < miSize ; ++i) - { - miStu = changeDataPackage.stmirtd(i); - tagName = QString::fromStdString(miStu.strtagname()); - value = miStu.nvalue(); - status = miStu.ustatus(); -// emit signal_updateMi(tagName, value, status); - m_miMap[tagName] = qMakePair(value, status); - } - } - } - catch(...) - { - return 0; - } - return 1; -} +#include "CRealDataCollect.h" +#include + +CRealDataCollect* CRealDataCollect::m_pInstance = NULL; + +CRealDataCollect::CRealDataCollect(EN_AppContext appContext) + : m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0), + m_objAppContext(appContext) +{ + initMsg(); + if(!addSub()) + { + return; + } + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CRealDataCollect *CRealDataCollect::instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CRealDataCollect(RT_MODE); + } + return m_pInstance; +} + +void CRealDataCollect::setAppContext(EN_AppContext appContext) +{ + if(m_objAppContext == appContext) + { + return; + } + + delSub(); + clearMsg(); + m_aiMap.clear(); + m_diMap.clear(); + m_piMap.clear(); + m_miMap.clear(); + + m_objAppContext = appContext; + addSub(); +} + +void CRealDataCollect::release() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(); + closeMsg(); + m_pInstance = NULL; + delete this; +} + +void CRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new kbd_net::CMbCommunicator("PointRealDataWidget"); + } +} + +void CRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +void CRealDataCollect::clearMsg() +{ + if(m_pMbComm) + { + kbd_net::CMbMessage objMsg; + while(m_pMbComm->recvMsg(objMsg, 0)) + {} + } +} + +bool CRealDataCollect::addSub() +{ + if(m_pMbComm) + { + if(m_objAppContext == RT_MODE) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else if(m_objAppContext == PDR_MODE) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET); + } + else + { + return false; + } + } + else + { + return false; + } +} + +bool CRealDataCollect::delSub() +{ + if(m_pMbComm) + { + if(m_objAppContext == RT_MODE) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else if(m_objAppContext == PDR_MODE) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET); + } + else + { + return false; + } + } + else + { + return false; + } +} + +void CRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { + processChangeData(); + } + + try + { + kbd_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) + { + continue; + } + if((objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) + && (objMsg.getChannelID() != (CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET))) + { + continue; + } + parserMsg(objMsg); + } + } + } + } + catch(...) + { + + } +} + +void CRealDataCollect::processChangeData() +{ + if(!m_aiMap.isEmpty()) + { + emit signal_updateAi(m_aiMap); + m_aiMap.clear(); + } + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + + if(!m_piMap.isEmpty()) + { + emit signal_updatePi(m_piMap); + m_piMap.clear(); + } + + if(!m_miMap.isEmpty()) + { + emit signal_updateMi(m_miMap); + m_miMap.clear(); + } +} + +int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) +{ + kbd_idlfile::SRealTimeDataPkg changeDataPackage; + try + { + changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); + int aiSize = changeDataPackage.stairtd_size(); + if(aiSize > 0) + { + kbd_idlfile::SAiRealTimeData aiStru; + QString tagName; + float value; + uint status; + for(int i = 0; i < aiSize;++i) + { + aiStru = changeDataPackage.stairtd(i); + tagName = QString::fromStdString(aiStru.strtagname()); + value = aiStru.fvalue(); + status = aiStru.ustatus(); +// emit signal_updateAi(tagName, value, status); + m_aiMap[tagName] = qMakePair(value, status); + } + } + + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + kbd_idlfile::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); +// emit signal_updateDi(tagName, value, status); + m_diMap[tagName] = qMakePair(value, status); + } + } + + int piSize = changeDataPackage.stpirtd_size(); + if(piSize > 0) + { + kbd_idlfile::SPiRealTimeData piStu; + QString tagName; + double value; + uint status; + for(int i = 0 ; i < piSize; ++i) + { + piStu = changeDataPackage.stpirtd(i); + tagName = QString::fromStdString(piStu.strtagname()); + value = piStu.dvalue(); + status = piStu.ustatus(); +// emit signal_updatePi(tagName, value, status); + m_piMap[tagName] = qMakePair(value, status); + } + } + + int miSize = changeDataPackage.stmirtd_size(); + if(miSize > 0) + { + kbd_idlfile::SMiRealTimeData miStu; + QString tagName; + int value; + uint status; + for(int i = 0 ; i < miSize ; ++i) + { + miStu = changeDataPackage.stmirtd(i); + tagName = QString::fromStdString(miStu.strtagname()); + value = miStu.nvalue(); + status = miStu.ustatus(); +// emit signal_updateMi(tagName, value, status); + m_miMap[tagName] = qMakePair(value, status); + } + } + } + catch(...) + { + return 0; + } + return 1; +} diff --git a/product/src/gui/plugin/PointRealDataWidget/CRealDataCollect.h b/product/src/gui/plugin/PointRealDataWidget/CRealDataCollect.h index 5ac1b5a4..b0e8cd89 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CRealDataCollect.h +++ b/product/src/gui/plugin/PointRealDataWidget/CRealDataCollect.h @@ -1,56 +1,56 @@ -#ifndef CREALDATACOLLECT_H -#define CREALDATACOLLECT_H - -#include -#include -#include "net_msg_bus_api/CMbCommunicator.h" -#include "MessageChannel.h" -#include "DataProcMessage.pb.h" -#include "CPointPublic.h" - -class QTimer; -class CRealDataCollect : public QObject -{ - Q_OBJECT -public: - static CRealDataCollect * instance(); - - void setAppContext(EN_AppContext appContext = RT_MODE); - - void release(); - -private: - CRealDataCollect(EN_AppContext appContext = RT_MODE); - - void initMsg(); - void closeMsg(); - void clearMsg(); - bool addSub(); - bool delSub(); - - int parserMsg(const kbd_net::CMbMessage &); - -private slots: - void recvMessage(); - void processChangeData(); - -signals: - void signal_updateAi(QMap> aiMap); - void signal_updateDi(QMap> diMap); - void signal_updatePi(QMap> piMap); - void signal_updateMi(QMap> miMap); - -private: - kbd_net::CMbCommunicator *m_pMbComm; - QTimer * m_pTimer; - int m_nTimeCount; - EN_AppContext m_objAppContext; - QMap> m_aiMap; - QMap> m_diMap; - QMap> m_piMap; - QMap> m_miMap; - - static CRealDataCollect * m_pInstance; -}; - -#endif // CREALDATACOLLECT_H +#ifndef CREALDATACOLLECT_H +#define CREALDATACOLLECT_H + +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" +#include "CPointPublic.h" + +class QTimer; +class CRealDataCollect : public QObject +{ + Q_OBJECT +public: + static CRealDataCollect * instance(); + + void setAppContext(EN_AppContext appContext = RT_MODE); + + void release(); + +private: + CRealDataCollect(EN_AppContext appContext = RT_MODE); + + void initMsg(); + void closeMsg(); + void clearMsg(); + bool addSub(); + bool delSub(); + + int parserMsg(const kbd_net::CMbMessage &); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateAi(QMap> aiMap); + void signal_updateDi(QMap> diMap); + void signal_updatePi(QMap> piMap); + void signal_updateMi(QMap> miMap); + +private: + kbd_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + EN_AppContext m_objAppContext; + QMap> m_aiMap; + QMap> m_diMap; + QMap> m_piMap; + QMap> m_miMap; + + static CRealDataCollect * m_pInstance; +}; + +#endif // CREALDATACOLLECT_H diff --git a/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.cpp b/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.cpp index b600f4be..e0798046 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.cpp +++ b/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.cpp @@ -1,148 +1,148 @@ -#include "CRealTableModel.h" -#include "CDbInterface.h" - -CRealTableModel::CRealTableModel(QObject *parent, const QStringList &header) - : QAbstractTableModel(parent), - m_header(header), - nColumnCount(3) -{ - m_valueFont.setBold(true); -} - -void CRealTableModel::updateChannelText(const QStringList &textList) -{ - m_channelTxList = textList; -} - -void CRealTableModel::setColumnCount(int count) -{ - nColumnCount = count; -} - -void CRealTableModel::updateRealData(const QList &dataList) -{ - beginResetModel(); - m_listRealData = dataList; - endResetModel(); -} - -void CRealTableModel::updateRealValue(QList &dataList) -{ - m_listRealData.swap(dataList); - update(); -} - -void CRealTableModel::update() -{ - QModelIndex topLeft = createIndex(0, 1); - QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 2); - emit dataChanged(topLeft, bottomRight); -} - -QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(role == Qt::DisplayRole) - { - if(orientation == Qt::Horizontal) - { - return m_header.value(section, ""); - } - } - return QVariant(); -} - -int CRealTableModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_listRealData.size(); -} - -int CRealTableModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return nColumnCount; -} - -QVariant CRealTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if(role == Qt::TextAlignmentRole) - { - if(index.column() == 0) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - } - else - { - return Qt::AlignCenter; - } - } - else if(role == Qt::ToolTipRole && index.column() == 0) - { - return m_listRealData.at(index.row()).description; - } - else if(role == Qt::FontRole && index.column() == 1) - { - return QVariant(m_valueFont); - } - - if(role != Qt::DisplayRole) - { - return QVariant(); - } - - switch (index.column()) { - case 0: - { - if(m_listRealData.at(index.row()).type == TYPE_DEVGROUP) - { - return m_listRealData.at(index.row()).description; - } - return " "+m_listRealData.at(index.row()).description; - break; - } - case 1: - { - if(m_listRealData.at(index.row()).isInit == false) - { - return ""; - } - if(m_listRealData.at(index.row()).table_name == "analog") - { - return QString::number(m_listRealData.at(index.row()).value, 'f', 2); - } - else if(m_listRealData.at(index.row()).table_name == "digital") - { - return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value); - } - else if(m_listRealData.at(index.row()).table_name == "accuml") - { - return QString::number(m_listRealData.at(index.row()).value, 'f', 2); - } - else if(m_listRealData.at(index.row()).table_name == "mix") - { - return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value); - } - else if(m_listRealData.at(index.row()).table_name == "fes_channel_para") - { - return m_listRealData.at(index.row()).value == 2 ? m_channelTxList[1] : m_channelTxList[2]; - } - break; - } - case 2: - { - return m_listRealData.at(index.row()).unit; - break; - } - default: - break; - } - - return QVariant(); -} +#include "CRealTableModel.h" +#include "CDbInterface.h" + +CRealTableModel::CRealTableModel(QObject *parent, const QStringList &header) + : QAbstractTableModel(parent), + m_header(header), + nColumnCount(3) +{ + m_valueFont.setBold(true); +} + +void CRealTableModel::updateChannelText(const QStringList &textList) +{ + m_channelTxList = textList; +} + +void CRealTableModel::setColumnCount(int count) +{ + nColumnCount = count; +} + +void CRealTableModel::updateRealData(const QList &dataList) +{ + beginResetModel(); + m_listRealData = dataList; + endResetModel(); +} + +void CRealTableModel::updateRealValue(QList &dataList) +{ + m_listRealData.swap(dataList); + update(); +} + +void CRealTableModel::update() +{ + QModelIndex topLeft = createIndex(0, 1); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 2); + emit dataChanged(topLeft, bottomRight); +} + +QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(role == Qt::DisplayRole) + { + if(orientation == Qt::Horizontal) + { + return m_header.value(section, ""); + } + } + return QVariant(); +} + +int CRealTableModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_listRealData.size(); +} + +int CRealTableModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return nColumnCount; +} + +QVariant CRealTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if(role == Qt::TextAlignmentRole) + { + if(index.column() == 0) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + } + else + { + return Qt::AlignCenter; + } + } + else if(role == Qt::ToolTipRole && index.column() == 0) + { + return m_listRealData.at(index.row()).description; + } + else if(role == Qt::FontRole && index.column() == 1) + { + return QVariant(m_valueFont); + } + + if(role != Qt::DisplayRole) + { + return QVariant(); + } + + switch (index.column()) { + case 0: + { + if(m_listRealData.at(index.row()).type == TYPE_DEVGROUP) + { + return m_listRealData.at(index.row()).description; + } + return " "+m_listRealData.at(index.row()).description; + break; + } + case 1: + { + if(m_listRealData.at(index.row()).isInit == false) + { + return ""; + } + if(m_listRealData.at(index.row()).table_name == "analog") + { + return QString::number(m_listRealData.at(index.row()).value, 'f', 2); + } + else if(m_listRealData.at(index.row()).table_name == "digital") + { + return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value); + } + else if(m_listRealData.at(index.row()).table_name == "accuml") + { + return QString::number(m_listRealData.at(index.row()).value, 'f', 2); + } + else if(m_listRealData.at(index.row()).table_name == "mix") + { + return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value); + } + else if(m_listRealData.at(index.row()).table_name == "fes_channel_para") + { + return m_listRealData.at(index.row()).value == 2 ? m_channelTxList[1] : m_channelTxList[2]; + } + break; + } + case 2: + { + return m_listRealData.at(index.row()).unit; + break; + } + default: + break; + } + + return QVariant(); +} diff --git a/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.h b/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.h index 0c6d279f..b4de9c0e 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.h +++ b/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.h @@ -1,40 +1,40 @@ -#ifndef CREALTABLEMODEL_H -#define CREALTABLEMODEL_H - -#include -#include -#include "CPointPublic.h" - -class CRealTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CRealTableModel(QObject *parent = nullptr, const QStringList &header = QStringList()); - - void updateChannelText(const QStringList &textList); - - void setColumnCount(int count); - - void updateRealData(const QList &dataList); - - void updateRealValue(QList &dataList); - - void update(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: - QStringList m_header; - int nColumnCount; - QList m_listRealData; - QStringList m_channelTxList; - QFont m_valueFont; -}; - -#endif // CREALTABLEMODEL_H +#ifndef CREALTABLEMODEL_H +#define CREALTABLEMODEL_H + +#include +#include +#include "CPointPublic.h" + +class CRealTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CRealTableModel(QObject *parent = nullptr, const QStringList &header = QStringList()); + + void updateChannelText(const QStringList &textList); + + void setColumnCount(int count); + + void updateRealData(const QList &dataList); + + void updateRealValue(QList &dataList); + + void update(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QStringList m_header; + int nColumnCount; + QList m_listRealData; + QStringList m_channelTxList; + QFont m_valueFont; +}; + +#endif // CREALTABLEMODEL_H diff --git a/product/src/gui/plugin/PointRealDataWidget/PointRealDataWidget.pro b/product/src/gui/plugin/PointRealDataWidget/PointRealDataWidget.pro index 28ebee7f..848d20d4 100644 --- a/product/src/gui/plugin/PointRealDataWidget/PointRealDataWidget.pro +++ b/product/src/gui/plugin/PointRealDataWidget/PointRealDataWidget.pro @@ -1,59 +1,59 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-07-20T10:33:02 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = PointRealDataWidget -TEMPLATE = lib - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CPointRealDataWidget.cpp \ - CRealTableModel.cpp \ - CDbInterface.cpp \ - CPointRealPluginWidget.cpp \ - CRealDataCollect.cpp - -HEADERS += \ - CPointRealDataWidget.h \ - CRealTableModel.h \ - CDbInterface.h \ - CPointPublic.h \ - CPointRealPluginWidget.h \ - CRealDataCollect.h - -LIBS += \ - -ldb_base_api \ - -ldb_api_ex \ - -lrdb_api \ - -lrdb_net_api \ - -llog4cplus \ - -lpub_logger_api \ - -lprotobuf \ - -lnet_msg_bus_api \ - -ldp_chg_data_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-07-20T10:33:02 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = PointRealDataWidget +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CPointRealDataWidget.cpp \ + CRealTableModel.cpp \ + CDbInterface.cpp \ + CPointRealPluginWidget.cpp \ + CRealDataCollect.cpp + +HEADERS += \ + CPointRealDataWidget.h \ + CRealTableModel.h \ + CDbInterface.h \ + CPointPublic.h \ + CPointRealPluginWidget.h \ + CRealDataCollect.h + +LIBS += \ + -ldb_base_api \ + -ldb_api_ex \ + -lrdb_api \ + -lrdb_net_api \ + -llog4cplus \ + -lpub_logger_api \ + -lprotobuf \ + -lnet_msg_bus_api \ + -ldp_chg_data_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/PointRealDataWidget/main.cpp b/product/src/gui/plugin/PointRealDataWidget/main.cpp index 0414e51f..d4e333c2 100644 --- a/product/src/gui/plugin/PointRealDataWidget/main.cpp +++ b/product/src/gui/plugin/PointRealDataWidget/main.cpp @@ -1,22 +1,22 @@ -#include -#include "CPointRealDataWidget.h" -#include "net/net_msg_bus_api/MsgBusApi.h" - -int main(int argc, char *argv[]) -{ - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - - { - QApplication a(argc, argv); - CPointRealDataWidget w(true); - w.show(); - - a.exec(); - } - - kbd_net::releaseMsgBus(); - return 0; -} +#include +#include "CPointRealDataWidget.h" +#include "net/net_msg_bus_api/MsgBusApi.h" + +int main(int argc, char *argv[]) +{ + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + + { + QApplication a(argc, argv); + CPointRealDataWidget w(true); + w.show(); + + a.exec(); + } + + kbd_net::releaseMsgBus(); + return 0; +} diff --git a/product/src/gui/plugin/PointsLockWidget/CConditionModel.cpp b/product/src/gui/plugin/PointsLockWidget/CConditionModel.cpp index 5d52932d..8ccb7acc 100644 --- a/product/src/gui/plugin/PointsLockWidget/CConditionModel.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CConditionModel.cpp @@ -1,141 +1,141 @@ -#include "CConditionModel.h" -#include "CDbInterfaceMng.h" - -CConditionModel::CConditionModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header<desc; - - break; - case 1: - { - ConditionInfoPtr info = m_list[index.row()]; - QString text = QString(); - QString text1 = QString(); - if(info->table == "digital") - { - text = CDbInterfaceMng::instance()->getDigitalValueDescByText(info->digitalText,info->value1); - }else - { - text = getText(info->cond1,info->value1); - text1 = getText(info->cond2,info->value2); - if(!text1.isEmpty() && !text.isEmpty()) - { - text+=tr(" 且 "); - text+=text1; - } - } - return text; - } - break; - default: - break; - } - } - return QVariant(); -} - -void CConditionModel::updateData(QList &condList) -{ - beginResetModel(); - m_list = condList; - endResetModel(); -} - -QString CConditionModel::getText(int cond, double value) -{ - QString text = QString(); - switch (cond) { - case 0: - - break; - case 1: - text+=tr("小于 %1 ").arg(QString::number(value)); - break; - case 2: - text+=tr("小于等于 %1 ").arg(QString::number(value)); - break; - case 3: - text+=tr("等于 %1 ").arg(QString::number(value)); - break; - case 4: - text+=tr("大于等于 %1 ").arg(QString::number(value)); - break; - case 5: - text+=tr("大于 %1 ").arg(QString::number(value)); - break; - case 6: - text+=tr("不等于 %1 ").arg(QString::number(value)); - break; - default: - break; - } - return text; -} - -ConditionInfoPtr CConditionModel::getDataByIndex(const QModelIndex &index) -{ - if(!index.isValid() || m_list.count()desc; + + break; + case 1: + { + ConditionInfoPtr info = m_list[index.row()]; + QString text = QString(); + QString text1 = QString(); + if(info->table == "digital") + { + text = CDbInterfaceMng::instance()->getDigitalValueDescByText(info->digitalText,info->value1); + }else + { + text = getText(info->cond1,info->value1); + text1 = getText(info->cond2,info->value2); + if(!text1.isEmpty() && !text.isEmpty()) + { + text+=tr(" 且 "); + text+=text1; + } + } + return text; + } + break; + default: + break; + } + } + return QVariant(); +} + +void CConditionModel::updateData(QList &condList) +{ + beginResetModel(); + m_list = condList; + endResetModel(); +} + +QString CConditionModel::getText(int cond, double value) +{ + QString text = QString(); + switch (cond) { + case 0: + + break; + case 1: + text+=tr("小于 %1 ").arg(QString::number(value)); + break; + case 2: + text+=tr("小于等于 %1 ").arg(QString::number(value)); + break; + case 3: + text+=tr("等于 %1 ").arg(QString::number(value)); + break; + case 4: + text+=tr("大于等于 %1 ").arg(QString::number(value)); + break; + case 5: + text+=tr("大于 %1 ").arg(QString::number(value)); + break; + case 6: + text+=tr("不等于 %1 ").arg(QString::number(value)); + break; + default: + break; + } + return text; +} + +ConditionInfoPtr CConditionModel::getDataByIndex(const QModelIndex &index) +{ + if(!index.isValid() || m_list.count() -#include "CPointsInfo.h" -class CConditionModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CConditionModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - void updateData(QList &condList); - - static QString getText(int cond,double value); - - ConditionInfoPtr getDataByIndex( const QModelIndex &index); - void removeData(QModelIndex index); -private: - QStringList m_header; - - QList m_list; -}; - -#endif // CCONDITIONMODEL_H +#ifndef CCONDITIONMODEL_H +#define CCONDITIONMODEL_H + +#include +#include "CPointsInfo.h" +class CConditionModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CConditionModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + void updateData(QList &condList); + + static QString getText(int cond,double value); + + ConditionInfoPtr getDataByIndex( const QModelIndex &index); + void removeData(QModelIndex index); +private: + QStringList m_header; + + QList m_list; +}; + +#endif // CCONDITIONMODEL_H diff --git a/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.cpp b/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.cpp index 5928088f..7732c739 100644 --- a/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.cpp @@ -1,184 +1,184 @@ -#include "CConditionOptDialog.h" -#include "ui_CConditionOptDialog.h" -#include "PointsLockCommon.h" -#include "CDbInterfaceMng.h" -#include - -CConditionOptDialog::CConditionOptDialog(int mode,PointsInfoPtr info,QWidget *parent) : - QDialog(parent), - ui(new Ui::CConditionOptDialog), - m_mode(mode), - m_info(info) -{ - ui->setupUi(this); - if(m_mode == EN_CONDITION_OPT_ADD) - { - setWindowTitle(tr("添加闭锁条件")); - }else - { - setWindowTitle(tr("编辑闭锁条件")); - } - initConnect(); - initTreeWidget(); -} - -CConditionOptDialog::~CConditionOptDialog() -{ - delete ui; -} - -void CConditionOptDialog::initConnect() -{ - connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CConditionOptDialog::treeItemClicked); - connect(ui->listWidget,&QListWidget::itemClicked,this,&CConditionOptDialog::listItemClicked); - connect(ui->pOk,&QPushButton::clicked,this,&CConditionOptDialog::okClicked); - connect(ui->pCancle,&QPushButton::clicked,this,&CConditionOptDialog::reject); -} - -void CConditionOptDialog::initTreeWidget() -{ - cleanTreeWidget(); - ui->treeWidget->setColumnCount(1); - QMap locMap = CDbInterfaceMng::instance()->locationInfo(); - QMap::iterator it =locMap.begin(); - while (it != locMap.end()) { - QTreeWidgetItem *locItem = new QTreeWidgetItem(); - locItem->setText(0,it.value()); - locItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_LOC);//类型 - locItem->setData(0,Qt::UserRole+1,it.key());//值 - ui->treeWidget->addTopLevelItem(locItem); - - QList > devGroupInfoList = CDbInterfaceMng::instance()->devGroupInfoList(it.key()); - for(int index(0);indexsetText(0,devGroupInfoList.at(index).second); - devgItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_DEVG);//类型 - devgItem->setData(0,Qt::UserRole+1,devGroupInfoList.at(index).first);//值 - locItem->addChild(devgItem); - QMap devInfo = CDbInterfaceMng::instance()->deviceInfo(devGroupInfoList.at(index).first); - - QMap::iterator pos = devInfo.begin(); - while (pos != devInfo.end()) { - QTreeWidgetItem *devItem = new QTreeWidgetItem(); - devItem->setText(0,pos.value()); - devItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_DEV);//类型 - devItem->setData(0,Qt::UserRole+1,pos.key());//值 - devgItem->addChild(devItem); - pos++; - } - } - it++; - } -} - -void CConditionOptDialog::cleanTreeWidget() -{ - for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) - { - QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); - ui->treeWidget->removeItemWidget(item,0); - } -} - -void CConditionOptDialog::updateList(const QString &dev) -{ - QList list = CDbInterfaceMng::instance()->getPointByDev(dev); - for(int index(0);indexlistWidget); - item->setText(list.at(index).desc); - item->setData(Qt::UserRole,list.at(index).tag); - item->setData(Qt::UserRole+1,list.at(index).table); - item->setData(Qt::UserRole+2,list.at(index).digitalText); - - ui->listWidget->addItem(item); - } -} - -void CConditionOptDialog::initCond(const QString &table, const QString &state) -{ - ui->cValue->clear(); - if(table == "digital") - { - ui->stackedWidget->setCurrentIndex(0); - QMap stateValueMap = CDbInterfaceMng::instance()->getDigitalTextMapByKey(state); - QMap::iterator it = stateValueMap.begin(); - while (it!= stateValueMap.end()) { - - ui->cValue->addItem(it.value(),it.key()); - it++; - } - }else - { - ui->stackedWidget->setCurrentIndex(1); - } -} - -void CConditionOptDialog::treeItemClicked(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - ui->listWidget->clear(); - initCond(); - m_curDev = QString(); - if(item == Q_NULLPTR) - { - return ; - } - if(item->data(0,Qt::UserRole).toInt() == EN_TREE_POINTS_DEV) - { - m_curDev =item->data(0,Qt::UserRole+1).toString(); - updateList(m_curDev); - } -} - -void CConditionOptDialog::listItemClicked(QListWidgetItem *item) -{ - QString tag = item->data(Qt::UserRole).toString(); - QString table = item->data(Qt::UserRole+1).toString(); - QString state = item->data(Qt::UserRole+2).toString(); - if(tag.isEmpty()) - { - return ; - } - initCond(table,state); -} - -void CConditionOptDialog::okClicked() -{ - QString tag =ui->listWidget->currentIndex().data(Qt::UserRole).toString(); - if(tag.isEmpty()) - { - showMess(tr("提示"),tr("请选择测点标签")); - return ; - } - ConditionInfoPtr info(new CConditionInfo()); - QListWidgetItem *item =ui->listWidget->currentItem(); - QString table = item->data(Qt::UserRole+1).toString(); - info->tag = item->data(Qt::UserRole).toString(); - info->table = table; - info->desc = QString("%1-%2").arg(CDbInterfaceMng::instance()->getDevgDescByDevTag(m_curDev)).arg(item->text()); - if(table == "digital") - { - - info->value1 = ui->cValue->currentData().toDouble(); - }else - { - info->cond1 = ui->ccondition1->currentIndex(); - info->cond2 = ui->ccondition2->currentIndex(); - info->value1 = ui->dValue1->value(); - info->value2 = ui->dValue2->value(); - } - if(CDbInterfaceMng::instance()->addConditionLock(m_info,info) == kbdSuccess) - { - accept(); - }else - { - showMess(tr("提示"),tr("添加失败")); - } -} - -void CConditionOptDialog::showMess(const QString &title, const QString &mess) -{ - QMessageBox::information(this,title,mess); -} +#include "CConditionOptDialog.h" +#include "ui_CConditionOptDialog.h" +#include "PointsLockCommon.h" +#include "CDbInterfaceMng.h" +#include + +CConditionOptDialog::CConditionOptDialog(int mode,PointsInfoPtr info,QWidget *parent) : + QDialog(parent), + ui(new Ui::CConditionOptDialog), + m_mode(mode), + m_info(info) +{ + ui->setupUi(this); + if(m_mode == EN_CONDITION_OPT_ADD) + { + setWindowTitle(tr("添加闭锁条件")); + }else + { + setWindowTitle(tr("编辑闭锁条件")); + } + initConnect(); + initTreeWidget(); +} + +CConditionOptDialog::~CConditionOptDialog() +{ + delete ui; +} + +void CConditionOptDialog::initConnect() +{ + connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CConditionOptDialog::treeItemClicked); + connect(ui->listWidget,&QListWidget::itemClicked,this,&CConditionOptDialog::listItemClicked); + connect(ui->pOk,&QPushButton::clicked,this,&CConditionOptDialog::okClicked); + connect(ui->pCancle,&QPushButton::clicked,this,&CConditionOptDialog::reject); +} + +void CConditionOptDialog::initTreeWidget() +{ + cleanTreeWidget(); + ui->treeWidget->setColumnCount(1); + QMap locMap = CDbInterfaceMng::instance()->locationInfo(); + QMap::iterator it =locMap.begin(); + while (it != locMap.end()) { + QTreeWidgetItem *locItem = new QTreeWidgetItem(); + locItem->setText(0,it.value()); + locItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_LOC);//类型 + locItem->setData(0,Qt::UserRole+1,it.key());//值 + ui->treeWidget->addTopLevelItem(locItem); + + QList > devGroupInfoList = CDbInterfaceMng::instance()->devGroupInfoList(it.key()); + for(int index(0);indexsetText(0,devGroupInfoList.at(index).second); + devgItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_DEVG);//类型 + devgItem->setData(0,Qt::UserRole+1,devGroupInfoList.at(index).first);//值 + locItem->addChild(devgItem); + QMap devInfo = CDbInterfaceMng::instance()->deviceInfo(devGroupInfoList.at(index).first); + + QMap::iterator pos = devInfo.begin(); + while (pos != devInfo.end()) { + QTreeWidgetItem *devItem = new QTreeWidgetItem(); + devItem->setText(0,pos.value()); + devItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_DEV);//类型 + devItem->setData(0,Qt::UserRole+1,pos.key());//值 + devgItem->addChild(devItem); + pos++; + } + } + it++; + } +} + +void CConditionOptDialog::cleanTreeWidget() +{ + for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) + { + QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); + ui->treeWidget->removeItemWidget(item,0); + } +} + +void CConditionOptDialog::updateList(const QString &dev) +{ + QList list = CDbInterfaceMng::instance()->getPointByDev(dev); + for(int index(0);indexlistWidget); + item->setText(list.at(index).desc); + item->setData(Qt::UserRole,list.at(index).tag); + item->setData(Qt::UserRole+1,list.at(index).table); + item->setData(Qt::UserRole+2,list.at(index).digitalText); + + ui->listWidget->addItem(item); + } +} + +void CConditionOptDialog::initCond(const QString &table, const QString &state) +{ + ui->cValue->clear(); + if(table == "digital") + { + ui->stackedWidget->setCurrentIndex(0); + QMap stateValueMap = CDbInterfaceMng::instance()->getDigitalTextMapByKey(state); + QMap::iterator it = stateValueMap.begin(); + while (it!= stateValueMap.end()) { + + ui->cValue->addItem(it.value(),it.key()); + it++; + } + }else + { + ui->stackedWidget->setCurrentIndex(1); + } +} + +void CConditionOptDialog::treeItemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + ui->listWidget->clear(); + initCond(); + m_curDev = QString(); + if(item == Q_NULLPTR) + { + return ; + } + if(item->data(0,Qt::UserRole).toInt() == EN_TREE_POINTS_DEV) + { + m_curDev =item->data(0,Qt::UserRole+1).toString(); + updateList(m_curDev); + } +} + +void CConditionOptDialog::listItemClicked(QListWidgetItem *item) +{ + QString tag = item->data(Qt::UserRole).toString(); + QString table = item->data(Qt::UserRole+1).toString(); + QString state = item->data(Qt::UserRole+2).toString(); + if(tag.isEmpty()) + { + return ; + } + initCond(table,state); +} + +void CConditionOptDialog::okClicked() +{ + QString tag =ui->listWidget->currentIndex().data(Qt::UserRole).toString(); + if(tag.isEmpty()) + { + showMess(tr("提示"),tr("请选择测点标签")); + return ; + } + ConditionInfoPtr info(new CConditionInfo()); + QListWidgetItem *item =ui->listWidget->currentItem(); + QString table = item->data(Qt::UserRole+1).toString(); + info->tag = item->data(Qt::UserRole).toString(); + info->table = table; + info->desc = QString("%1-%2").arg(CDbInterfaceMng::instance()->getDevgDescByDevTag(m_curDev)).arg(item->text()); + if(table == "digital") + { + + info->value1 = ui->cValue->currentData().toDouble(); + }else + { + info->cond1 = ui->ccondition1->currentIndex(); + info->cond2 = ui->ccondition2->currentIndex(); + info->value1 = ui->dValue1->value(); + info->value2 = ui->dValue2->value(); + } + if(CDbInterfaceMng::instance()->addConditionLock(m_info,info) == kbdSuccess) + { + accept(); + }else + { + showMess(tr("提示"),tr("添加失败")); + } +} + +void CConditionOptDialog::showMess(const QString &title, const QString &mess) +{ + QMessageBox::information(this,title,mess); +} diff --git a/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.h b/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.h index e32f953b..758a16f9 100644 --- a/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.h +++ b/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.h @@ -1,50 +1,50 @@ -#ifndef CCONDITIONOPTDIALOG_H -#define CCONDITIONOPTDIALOG_H - -#include -#include -#include - -#include "CPointsInfo.h" - -namespace Ui { -class CConditionOptDialog; -} - -class CConditionOptDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CConditionOptDialog(int mode,PointsInfoPtr info, QWidget *parent = 0); - ~CConditionOptDialog(); - -private: - void initConnect(); - void initTreeWidget(); - - void cleanTreeWidget(); - - void updateList(const QString &dev); - - void initCond(const QString &table = QString(),const QString &state=QString()); - -private slots: - void treeItemClicked(QTreeWidgetItem *item, int column); - - void listItemClicked(QListWidgetItem *item); - - void okClicked(); - -private: - void showMess(const QString &title,const QString &mess); - -private: - Ui::CConditionOptDialog *ui; - int m_mode; - PointsInfoPtr m_info; - - QString m_curDev; -}; - -#endif // CCONDITIONOPTDIALOG_H +#ifndef CCONDITIONOPTDIALOG_H +#define CCONDITIONOPTDIALOG_H + +#include +#include +#include + +#include "CPointsInfo.h" + +namespace Ui { +class CConditionOptDialog; +} + +class CConditionOptDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CConditionOptDialog(int mode,PointsInfoPtr info, QWidget *parent = 0); + ~CConditionOptDialog(); + +private: + void initConnect(); + void initTreeWidget(); + + void cleanTreeWidget(); + + void updateList(const QString &dev); + + void initCond(const QString &table = QString(),const QString &state=QString()); + +private slots: + void treeItemClicked(QTreeWidgetItem *item, int column); + + void listItemClicked(QListWidgetItem *item); + + void okClicked(); + +private: + void showMess(const QString &title,const QString &mess); + +private: + Ui::CConditionOptDialog *ui; + int m_mode; + PointsInfoPtr m_info; + + QString m_curDev; +}; + +#endif // CCONDITIONOPTDIALOG_H diff --git a/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.ui b/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.ui index 88d70511..17f31d60 100644 --- a/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.ui +++ b/product/src/gui/plugin/PointsLockWidget/CConditionOptDialog.ui @@ -1,272 +1,272 @@ - - - CConditionOptDialog - - - - 0 - 0 - 790 - 496 - - - - Dialog - - - - - - - - - - 设备信息 - - - AlignCenter - - - - - - - - - - - - - - - - - - 0 - 0 - - - - 1 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 条件 - - - - - - - - - - Qt::Horizontal - - - - 646 - 20 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 条件 - - - - - - - - - - - - - 小于 - - - - - 小于等于 - - - - - 等于 - - - - - 大于等于 - - - - - 大于 - - - - - 不等于 - - - - - - - - -10000.000000000000000 - - - 1000000.000000000000000 - - - - - - - - - - - - - - - - - - - - 小于 - - - - - 小于等于 - - - - - 等于 - - - - - 大于等于 - - - - - 大于 - - - - - 不等于 - - - - - - - - -10000.000000000000000 - - - 1000000.000000000000000 - - - - - - - Qt::Horizontal - - - - 415 - 20 - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - - - - + + + CConditionOptDialog + + + + 0 + 0 + 790 + 496 + + + + Dialog + + + + + + + + + + 设备信息 + + + AlignCenter + + + + + + + + + + + + + + + + + + 0 + 0 + + + + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 条件 + + + + + + + + + + Qt::Horizontal + + + + 646 + 20 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 条件 + + + + + + + + + + + + + 小于 + + + + + 小于等于 + + + + + 等于 + + + + + 大于等于 + + + + + 大于 + + + + + 不等于 + + + + + + + + -10000.000000000000000 + + + 1000000.000000000000000 + + + + + + + + + + + + + + + + + + + + 小于 + + + + + 小于等于 + + + + + 等于 + + + + + 大于等于 + + + + + 大于 + + + + + 不等于 + + + + + + + + -10000.000000000000000 + + + 1000000.000000000000000 + + + + + + + Qt::Horizontal + + + + 415 + 20 + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + + + + diff --git a/product/src/gui/plugin/PointsLockWidget/CConditionView.cpp b/product/src/gui/plugin/PointsLockWidget/CConditionView.cpp index f47360c0..d4f0d99b 100644 --- a/product/src/gui/plugin/PointsLockWidget/CConditionView.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CConditionView.cpp @@ -1,14 +1,14 @@ -#include "CConditionView.h" -#include -#include - -CConditionView::CConditionView(QWidget *parent) - : QTableView(parent) -{ - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - - horizontalHeader()->setVisible(true); -} +#include "CConditionView.h" +#include +#include + +CConditionView::CConditionView(QWidget *parent) + : QTableView(parent) +{ + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + + horizontalHeader()->setVisible(true); +} diff --git a/product/src/gui/plugin/PointsLockWidget/CConditionView.h b/product/src/gui/plugin/PointsLockWidget/CConditionView.h index 717f34e0..af5d0bd4 100644 --- a/product/src/gui/plugin/PointsLockWidget/CConditionView.h +++ b/product/src/gui/plugin/PointsLockWidget/CConditionView.h @@ -1,14 +1,14 @@ -#ifndef CCONDITIONVIEW_H -#define CCONDITIONVIEW_H -#include - -#include - -class CConditionView : public QTableView -{ - Q_OBJECT -public: - CConditionView(QWidget *parent = Q_NULLPTR); -}; - -#endif // CCONDITIONVIEW_H +#ifndef CCONDITIONVIEW_H +#define CCONDITIONVIEW_H +#include + +#include + +class CConditionView : public QTableView +{ + Q_OBJECT +public: + CConditionView(QWidget *parent = Q_NULLPTR); +}; + +#endif // CCONDITIONVIEW_H diff --git a/product/src/gui/plugin/PointsLockWidget/CDbInterfaceMng.cpp b/product/src/gui/plugin/PointsLockWidget/CDbInterfaceMng.cpp index 793c84a3..807bb8aa 100644 --- a/product/src/gui/plugin/PointsLockWidget/CDbInterfaceMng.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CDbInterfaceMng.cpp @@ -1,637 +1,637 @@ -#include "CDbInterfaceMng.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_dbms; - -CDbInterfaceMng *CDbInterfaceMng::m_pInstance = NULL; - -CDbInterfaceMng *CDbInterfaceMng::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CDbInterfaceMng(); - } - return m_pInstance; -} - -void CDbInterfaceMng::destory() -{ - if(m_pWriteDb) - { - m_pWriteDb->close(); - delete m_pWriteDb; - } - m_pWriteDb = NULL; - - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - m_pInstance = NULL; - delete this; -} - -QMap CDbInterfaceMng::locationInfo() -{ - return m_locationInfo; -} - -QList > CDbInterfaceMng::devGroupInfoList(const int &location) -{ - return m_devGroupInfoMap.value(location, QList >()); -} - -QMap CDbInterfaceMng::deviceInfo(const QString &devGroupName) -{ - return m_devGDevInfoMap.value(devGroupName, QMap()); -} - -QList CDbInterfaceMng::getCtrlPointByDev(const QString &dev) -{ - QList list; - if(!m_pWriteDb->isOpen()) - { - return list; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from digital where is_control = 1 and device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointsInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - list.append(info); - } - return list; -} - -QList CDbInterfaceMng::getPointByDev(const QString &dev) -{ - QList list; - getDiByDev(dev,list); - getAiByDev(dev,list); - getPiByDev(dev,list); - getMiByDev(dev,list); - return list; -} - -QString CDbInterfaceMng::getCtrlGrpTextByCtrlPoint(const QString &tag) -{ - QString ctrlGrpText =QString(); - if(!m_pWriteDb->isOpen()) - { - return ctrlGrpText; - } - QSqlQuery query; - QString sqlQuery = QString("select ctrl_act_name from digital_control where tag_name = '%1'").arg(tag); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - ctrlGrpText = query.value(0).toString(); - } - return ctrlGrpText; -} - -QMap CDbInterfaceMng::getDigitalTextMapByKey(const QString &key) -{ - return m_digitalTextMap.value(key,QMap()); -} - -QMap CDbInterfaceMng::getCtrlGrpTextMapByKey(const QString &key) -{ - return m_ctrlGroupMap.value(key,QMap()); -} - -int CDbInterfaceMng::addPointLock(const QString &tag, int digitalValue, int check) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QString sqlQuery = QString("insert into point_lock_config_info(tag_name,actual_value,isEnable) values('%1',%2,%3)").arg(tag).arg(QString::number(digitalValue)).arg(QString::number(check)); - - if(m_pWriteDb->execute(sqlQuery)) - { - return kbdSuccess; - } - return kbdFailed; -} - -int CDbInterfaceMng::updatePointLock(PointsInfoPtr info, bool isEnable) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QString sqlQuery = QString("update point_lock_config_info set isEnable = %1 where tag_name = '%2' and actual_value = %3").arg(isEnable?1:0).arg(info->tag).arg(info->value); - - if(m_pWriteDb->execute(sqlQuery)) - { - return kbdSuccess; - } - return kbdFailed; -} - -int CDbInterfaceMng::delPointLock(PointsInfoPtr info) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - m_pWriteDb->transaction(); - QString sql1 = QString("delete from point_lock_config_info where tag_name ='%1' and actual_value = %2").arg(info->tag).arg(info->value); - QString sql2 = QString("delete from point_lock_condition_info where tag_name ='%1' and actual_value = %2").arg(info->tag).arg(info->value); - if(m_pWriteDb->execute(sql1) && m_pWriteDb->execute(sql2)) - { - m_pWriteDb->commit(); - return kbdSuccess; - }else - { - m_pWriteDb->rollback(); - return kbdFailed; - } - return kbdFailed; -} - -QString CDbInterfaceMng::getLocDescById(int loc) -{ - return m_locationInfo.value(loc,""); -} - -QString CDbInterfaceMng::getDevgDescByDevg(const QString &devg) -{ - return m_devgInfoMap.value(devg,""); -} - -QString CDbInterfaceMng::getDigitalValueDescByText(const QString &text,int value) -{ - return m_digitalTextMap.value(text,QMap()).value(value,""); -} - -QString CDbInterfaceMng::getCtrlGrpDescByText(const QString &text, int value) -{ - return m_ctrlGroupMap.value(text,QMap()).value(value,""); -} - -QList CDbInterfaceMng::getLockConfigInfo() -{ - QList list; - if(!m_pWriteDb->isOpen()) - { - return list; - } - - QMap m_ctrlMap; - QSqlQuery query; - QString sql = QString("select TAG_NAME,CTRL_ACT_NAME from digital_control"); - m_pWriteDb->execute(sql, query); - while(query.next()) - { - m_ctrlMap[query.value(0).toString()] = query.value(1).toString(); - } - - sql = QString("select %1.TAG_NAME,%1.ACTUAL_VALUE,%1.ISENABLE,%2.DESCRIPTION,%2.LOCATION_ID,%2.DEVICE,%2.state_text_name from %1 left" - " join %2 on %1.TAG_NAME = %2.TAG_NAME").arg("point_lock_config_info").arg("digital"); - - m_pWriteDb->execute(sql, query); - - while(query.next()) - { - PointsInfoPtr info(new CPointsInfo()); - info->tag = query.value(0).toString(); - info->value = query.value(1).toInt(); - info->enable = query.value(2).toInt(); - info->desc = query.value(3).toString(); - info->loc = query.value(4).toInt(); - info->dev = query.value(5).toString(); - info->ctrlGrpText = m_ctrlMap.value(info->tag,""); - info->devg = getDevgByDevTag(info->dev); - - if(m_locationInfo.keys().contains(info->loc)) - { - list.append(info); - } - } - return list; -} - -QString CDbInterfaceMng::getDevgByDevTag(const QString dev) -{ - return m_devDevgMap.value(dev,""); -} - -QString CDbInterfaceMng::getDevgDescByDevTag(const QString dev) -{ - return m_devgInfoMap.value(m_devDevgMap.value(dev,""),""); -} - -QList CDbInterfaceMng::getConditionInfoByPointInfo(PointsInfoPtr info) -{ - QList list; - if(!m_pWriteDb->isOpen()) - { - return list; - } - QSqlQuery query; - QString sql = QString("select condition_tag_name,condition_desc,condition1,value1,condition2,value2,condition_table" - " from point_lock_condition_info where tag_name = '%1' and actual_value = %2").arg(info->tag).arg(info->value); - - m_pWriteDb->execute(sql, query); - - while(query.next()) - { - ConditionInfoPtr condinfo(new CConditionInfo()); - condinfo->tag = query.value(0).toString(); - condinfo->desc = query.value(1).toString(); - condinfo->cond1 = query.value(2).toInt(); - condinfo->value1 = query.value(3).toDouble(); - condinfo->cond2 = query.value(4).toInt(); - condinfo->value2 = query.value(5).toDouble(); - condinfo->table = query.value(6).toString(); - list.append(condinfo); - } - for(int index(0);indextable == "digital") - { - QSqlQuery query1; - sql = QString("select state_text_name from digital where tag_name ='%1'").arg(list.at(index)->tag); - m_pWriteDb->execute(sql,query1); - while (query1.next()) { - list.at(index)->digitalText = query1.value(0).toString(); - } - } - } - return list; -} - -int CDbInterfaceMng::addConditionLock(PointsInfoPtr pointInfo, ConditionInfoPtr condInfo) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - QString sqlQuery = QString(); - if(condInfo->table == "digital") - { - sqlQuery = QString("insert into point_lock_condition_info(tag_name,actual_value,condition_tag_name,condition_desc" - ",value1,condition_table) values('%1',%2,'%3','%4',%5,'%6')").arg(pointInfo->tag) - .arg(QString::number(pointInfo->value)).arg(condInfo->tag).arg(condInfo->desc).arg(condInfo->value1) - .arg(condInfo->table); - }else - { - sqlQuery = QString("insert into point_lock_condition_info(tag_name,actual_value,condition_tag_name,condition_desc,condition1" - ",value1,condition2,value2,condition_table) values('%1',%2,'%3','%4',%5,%6,%7,%8,'%9')").arg(pointInfo->tag) - .arg(QString::number(pointInfo->value)).arg(condInfo->tag).arg(condInfo->desc).arg(condInfo->cond1).arg(condInfo->value1) - .arg(condInfo->cond2).arg(condInfo->value2).arg(condInfo->table); - } - - - qDebug()<execute(sqlQuery)) - { - return kbdSuccess; - } - return kbdFailed; -} - -int CDbInterfaceMng::delConditionLock(PointsInfoPtr pointInfo, ConditionInfoPtr condInfo) -{ - if(!m_pWriteDb->isOpen()) - { - return kbdFailed; - } - - QString sql = QString("delete from point_lock_condition_info where tag_name ='%1' and actual_value = %2 and condition_tag_name = '%3' ") - .arg(pointInfo->tag).arg(pointInfo->value).arg(condInfo->tag); - - if(m_pWriteDb->execute(sql)) - { - return kbdSuccess; - }else - { - return kbdFailed; - } - return kbdFailed; -} - -CDbInterfaceMng::CDbInterfaceMng() -{ - m_pWriteDb = new CDbApi(DB_CONN_MODEL_WRITE); - m_pWriteDb->open(); - - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - loadRTLocation(); - loadDevGroupInfo(); - loadDeviceInfo(); - loadDigitalText(); - loadOptCtrlActDefine(); -} - -void CDbInterfaceMng::loadRTLocation() -{ - m_locationInfo.clear(); - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"); - LOGDEBUG("readLocation():sql[%s]",sqlQuery.toStdString().c_str()); - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - int id = query.value(0).toInt(); - QString desc = query.value(1).toString(); - m_locationInfo[id] = desc; - } -// kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); -// if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) -// { -// LOGERROR("权限接口初始化失败!"); -// return; -// } -// int level; -// std::vector vecLocationId; -// std::vector vecPermPic; -// if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) -// { -// LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); -// return; -// } - -// std::string strApplicationName = "base"; -// std::string strTableName = "sys_model_location_info"; -// QPair id_value; -// id_value.first = "location_id"; -// id_value.second = "description"; -// if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) -// { -// kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); -// kbd_dbms::CRdbQueryResult result; -// std::vector columns; -// columns.push_back(id_value.first); -// columns.push_back(id_value.second); - -// if(m_rtdbAccess->select(result, columns)) -// { -// m_locationInfo.clear(); -// for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) -// { -// kbd_dbms::CVarType key; -// kbd_dbms::CVarType value; -// result.getColumnValue(nIndex, 0, key); -// result.getColumnValue(nIndex, 1, value); - -// std::vector ::const_iterator it = vecLocationId.cbegin(); -// while (it != vecLocationId.cend()) -// { -// if(key.toInt() == *it) -// { -// m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); -// } -// ++it; -// } -// } -// } -// } -// m_rtdbAccess->close(); -} - -void CDbInterfaceMng::loadDevGroupInfo() -{ - QSqlQuery query; - - //< 查询pscada专业所有设备组 - QString strLoctionFilter; - if(!m_locationInfo.keys().isEmpty()) - { - QStringList listLocation; - foreach (int nLocationID, m_locationInfo.keys()) - { - listLocation.append(QString::number(nLocationID)); - } - strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); - }else - { - return ; - } - QString sqlSequenceQuery = QString("select tag_name, description, location_id from dev_group where sub_system > 3 "); - if(!strLoctionFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); - }else - { - sqlSequenceQuery.append(QString(" order by dev_group_no asc;")); - } - m_pWriteDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - QPair pair; - pair.first = query.value(0).toString(); - pair.second = query.value(1).toString(); - m_devgInfoMap[pair.first] = pair.second; - QMap > >::iterator it = m_devGroupInfoMap.find(query.value(2).toInt()); - if(it !=m_devGroupInfoMap.end()) - { - QList > &devgList = it.value(); - devgList.append(pair); - }else - { - QList > devgList; - devgList.append(pair); - m_devGroupInfoMap[query.value(2).toInt()] = devgList; - } - } -} - -void CDbInterfaceMng::loadDeviceInfo() -{ - m_devDevgMap.clear(); - m_devGDevInfoMap.clear(); - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,GROUP_TAG_NAME from dev_info"); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString tag = query.value(0).toString(); - QString desc = query.value(1).toString(); - QString devg = query.value(2).toString(); - m_devDevgMap[tag] = devg; - QMap >::iterator iter = m_devGDevInfoMap.find(devg); - if(iter != m_devGDevInfoMap.end()) - { - m_devGDevInfoMap[devg].insert(tag,desc); - }else - { - QMap devMap; - devMap.insert(tag,desc); - m_devGDevInfoMap[devg] = devMap; - } - } -} - -void CDbInterfaceMng::loadDigitalText() -{ - m_digitalTextMap.clear(); - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select state_text_name,actual_value,display_value from %1").arg("dict_state_text_info"); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString state_text_name = query.value(0).toString(); - int actual_value = query.value(1).toInt(); - QString display_value = query.value(2).toString(); - QMap >::iterator iter = m_digitalTextMap.find(state_text_name); - if(iter != m_digitalTextMap.end()) - { - iter.value().insert(actual_value,display_value); - }else - { - QMap actualMap; - actualMap.insert(actual_value,display_value); - m_digitalTextMap[state_text_name] = actualMap; - } - } -} - -void CDbInterfaceMng::loadOptCtrlActDefine() -{ - m_ctrlGroupMap.clear(); - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select ctrl_grp_name,target_value,ctrl_act_name from %1").arg("opt_ctrl_act_define"); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - QString grpName = query.value(0).toString(); - int targetValue = query.value(1).toInt(); - QString actName = query.value(2).toString(); - QMap >::iterator iter = m_ctrlGroupMap.find(grpName); - if(iter != m_ctrlGroupMap.end()) - { - iter.value().insert(targetValue,actName); - }else - { - QMap actualMap; - actualMap.insert(targetValue,actName); - m_ctrlGroupMap[grpName] = actualMap; - } - } -} - -void CDbInterfaceMng::getDiByDev(const QString &dev, QList &list) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE,STATE_TEXT_NAME from digital where device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointsInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devg = getDevgByDevTag(query.value(2).toString()); - info.digitalText = query.value(3).toString(); - info.table = "digital"; - list.append(info); - } -} - -void CDbInterfaceMng::getAiByDev(const QString &dev, QList &list) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from analog where device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointsInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devg = getDevgByDevTag(query.value(2).toString()); - info.table = "analog"; - list.append(info); - } -} - -void CDbInterfaceMng::getPiByDev(const QString &dev, QList &list) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from accuml where device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointsInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devg = getDevgByDevTag(query.value(2).toString()); - info.table = "accuml"; - list.append(info); - } -} - -void CDbInterfaceMng::getMiByDev(const QString &dev, QList &list) -{ - if(!m_pWriteDb->isOpen()) - { - return ; - } - QSqlQuery query; - QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from mix where device = '%1'").arg(dev); - - m_pWriteDb->execute(sqlQuery, query); - - while(query.next()) - { - PointsInfo info; - info.tag = query.value(0).toString(); - info.desc = query.value(1).toString(); - info.devg = getDevgByDevTag(query.value(2).toString()); - info.table = "mix"; - list.append(info); - } -} +#include "CDbInterfaceMng.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" + +using namespace kbd_dbms; + +CDbInterfaceMng *CDbInterfaceMng::m_pInstance = NULL; + +CDbInterfaceMng *CDbInterfaceMng::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDbInterfaceMng(); + } + return m_pInstance; +} + +void CDbInterfaceMng::destory() +{ + if(m_pWriteDb) + { + m_pWriteDb->close(); + delete m_pWriteDb; + } + m_pWriteDb = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_pInstance = NULL; + delete this; +} + +QMap CDbInterfaceMng::locationInfo() +{ + return m_locationInfo; +} + +QList > CDbInterfaceMng::devGroupInfoList(const int &location) +{ + return m_devGroupInfoMap.value(location, QList >()); +} + +QMap CDbInterfaceMng::deviceInfo(const QString &devGroupName) +{ + return m_devGDevInfoMap.value(devGroupName, QMap()); +} + +QList CDbInterfaceMng::getCtrlPointByDev(const QString &dev) +{ + QList list; + if(!m_pWriteDb->isOpen()) + { + return list; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from digital where is_control = 1 and device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointsInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + list.append(info); + } + return list; +} + +QList CDbInterfaceMng::getPointByDev(const QString &dev) +{ + QList list; + getDiByDev(dev,list); + getAiByDev(dev,list); + getPiByDev(dev,list); + getMiByDev(dev,list); + return list; +} + +QString CDbInterfaceMng::getCtrlGrpTextByCtrlPoint(const QString &tag) +{ + QString ctrlGrpText =QString(); + if(!m_pWriteDb->isOpen()) + { + return ctrlGrpText; + } + QSqlQuery query; + QString sqlQuery = QString("select ctrl_act_name from digital_control where tag_name = '%1'").arg(tag); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + ctrlGrpText = query.value(0).toString(); + } + return ctrlGrpText; +} + +QMap CDbInterfaceMng::getDigitalTextMapByKey(const QString &key) +{ + return m_digitalTextMap.value(key,QMap()); +} + +QMap CDbInterfaceMng::getCtrlGrpTextMapByKey(const QString &key) +{ + return m_ctrlGroupMap.value(key,QMap()); +} + +int CDbInterfaceMng::addPointLock(const QString &tag, int digitalValue, int check) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QString sqlQuery = QString("insert into point_lock_config_info(tag_name,actual_value,isEnable) values('%1',%2,%3)").arg(tag).arg(QString::number(digitalValue)).arg(QString::number(check)); + + if(m_pWriteDb->execute(sqlQuery)) + { + return kbdSuccess; + } + return kbdFailed; +} + +int CDbInterfaceMng::updatePointLock(PointsInfoPtr info, bool isEnable) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QString sqlQuery = QString("update point_lock_config_info set isEnable = %1 where tag_name = '%2' and actual_value = %3").arg(isEnable?1:0).arg(info->tag).arg(info->value); + + if(m_pWriteDb->execute(sqlQuery)) + { + return kbdSuccess; + } + return kbdFailed; +} + +int CDbInterfaceMng::delPointLock(PointsInfoPtr info) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + m_pWriteDb->transaction(); + QString sql1 = QString("delete from point_lock_config_info where tag_name ='%1' and actual_value = %2").arg(info->tag).arg(info->value); + QString sql2 = QString("delete from point_lock_condition_info where tag_name ='%1' and actual_value = %2").arg(info->tag).arg(info->value); + if(m_pWriteDb->execute(sql1) && m_pWriteDb->execute(sql2)) + { + m_pWriteDb->commit(); + return kbdSuccess; + }else + { + m_pWriteDb->rollback(); + return kbdFailed; + } + return kbdFailed; +} + +QString CDbInterfaceMng::getLocDescById(int loc) +{ + return m_locationInfo.value(loc,""); +} + +QString CDbInterfaceMng::getDevgDescByDevg(const QString &devg) +{ + return m_devgInfoMap.value(devg,""); +} + +QString CDbInterfaceMng::getDigitalValueDescByText(const QString &text,int value) +{ + return m_digitalTextMap.value(text,QMap()).value(value,""); +} + +QString CDbInterfaceMng::getCtrlGrpDescByText(const QString &text, int value) +{ + return m_ctrlGroupMap.value(text,QMap()).value(value,""); +} + +QList CDbInterfaceMng::getLockConfigInfo() +{ + QList list; + if(!m_pWriteDb->isOpen()) + { + return list; + } + + QMap m_ctrlMap; + QSqlQuery query; + QString sql = QString("select TAG_NAME,CTRL_ACT_NAME from digital_control"); + m_pWriteDb->execute(sql, query); + while(query.next()) + { + m_ctrlMap[query.value(0).toString()] = query.value(1).toString(); + } + + sql = QString("select %1.TAG_NAME,%1.ACTUAL_VALUE,%1.ISENABLE,%2.DESCRIPTION,%2.LOCATION_ID,%2.DEVICE,%2.state_text_name from %1 left" + " join %2 on %1.TAG_NAME = %2.TAG_NAME").arg("point_lock_config_info").arg("digital"); + + m_pWriteDb->execute(sql, query); + + while(query.next()) + { + PointsInfoPtr info(new CPointsInfo()); + info->tag = query.value(0).toString(); + info->value = query.value(1).toInt(); + info->enable = query.value(2).toInt(); + info->desc = query.value(3).toString(); + info->loc = query.value(4).toInt(); + info->dev = query.value(5).toString(); + info->ctrlGrpText = m_ctrlMap.value(info->tag,""); + info->devg = getDevgByDevTag(info->dev); + + if(m_locationInfo.keys().contains(info->loc)) + { + list.append(info); + } + } + return list; +} + +QString CDbInterfaceMng::getDevgByDevTag(const QString dev) +{ + return m_devDevgMap.value(dev,""); +} + +QString CDbInterfaceMng::getDevgDescByDevTag(const QString dev) +{ + return m_devgInfoMap.value(m_devDevgMap.value(dev,""),""); +} + +QList CDbInterfaceMng::getConditionInfoByPointInfo(PointsInfoPtr info) +{ + QList list; + if(!m_pWriteDb->isOpen()) + { + return list; + } + QSqlQuery query; + QString sql = QString("select condition_tag_name,condition_desc,condition1,value1,condition2,value2,condition_table" + " from point_lock_condition_info where tag_name = '%1' and actual_value = %2").arg(info->tag).arg(info->value); + + m_pWriteDb->execute(sql, query); + + while(query.next()) + { + ConditionInfoPtr condinfo(new CConditionInfo()); + condinfo->tag = query.value(0).toString(); + condinfo->desc = query.value(1).toString(); + condinfo->cond1 = query.value(2).toInt(); + condinfo->value1 = query.value(3).toDouble(); + condinfo->cond2 = query.value(4).toInt(); + condinfo->value2 = query.value(5).toDouble(); + condinfo->table = query.value(6).toString(); + list.append(condinfo); + } + for(int index(0);indextable == "digital") + { + QSqlQuery query1; + sql = QString("select state_text_name from digital where tag_name ='%1'").arg(list.at(index)->tag); + m_pWriteDb->execute(sql,query1); + while (query1.next()) { + list.at(index)->digitalText = query1.value(0).toString(); + } + } + } + return list; +} + +int CDbInterfaceMng::addConditionLock(PointsInfoPtr pointInfo, ConditionInfoPtr condInfo) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + QString sqlQuery = QString(); + if(condInfo->table == "digital") + { + sqlQuery = QString("insert into point_lock_condition_info(tag_name,actual_value,condition_tag_name,condition_desc" + ",value1,condition_table) values('%1',%2,'%3','%4',%5,'%6')").arg(pointInfo->tag) + .arg(QString::number(pointInfo->value)).arg(condInfo->tag).arg(condInfo->desc).arg(condInfo->value1) + .arg(condInfo->table); + }else + { + sqlQuery = QString("insert into point_lock_condition_info(tag_name,actual_value,condition_tag_name,condition_desc,condition1" + ",value1,condition2,value2,condition_table) values('%1',%2,'%3','%4',%5,%6,%7,%8,'%9')").arg(pointInfo->tag) + .arg(QString::number(pointInfo->value)).arg(condInfo->tag).arg(condInfo->desc).arg(condInfo->cond1).arg(condInfo->value1) + .arg(condInfo->cond2).arg(condInfo->value2).arg(condInfo->table); + } + + + qDebug()<execute(sqlQuery)) + { + return kbdSuccess; + } + return kbdFailed; +} + +int CDbInterfaceMng::delConditionLock(PointsInfoPtr pointInfo, ConditionInfoPtr condInfo) +{ + if(!m_pWriteDb->isOpen()) + { + return kbdFailed; + } + + QString sql = QString("delete from point_lock_condition_info where tag_name ='%1' and actual_value = %2 and condition_tag_name = '%3' ") + .arg(pointInfo->tag).arg(pointInfo->value).arg(condInfo->tag); + + if(m_pWriteDb->execute(sql)) + { + return kbdSuccess; + }else + { + return kbdFailed; + } + return kbdFailed; +} + +CDbInterfaceMng::CDbInterfaceMng() +{ + m_pWriteDb = new CDbApi(DB_CONN_MODEL_WRITE); + m_pWriteDb->open(); + + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + loadRTLocation(); + loadDevGroupInfo(); + loadDeviceInfo(); + loadDigitalText(); + loadOptCtrlActDefine(); +} + +void CDbInterfaceMng::loadRTLocation() +{ + m_locationInfo.clear(); + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION from sys_model_location_info order by LOCATION_NO"); + LOGDEBUG("readLocation():sql[%s]",sqlQuery.toStdString().c_str()); + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString desc = query.value(1).toString(); + m_locationInfo[id] = desc; + } +// kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); +// if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) +// { +// LOGERROR("权限接口初始化失败!"); +// return; +// } +// int level; +// std::vector vecLocationId; +// std::vector vecPermPic; +// if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) +// { +// LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); +// return; +// } + +// std::string strApplicationName = "base"; +// std::string strTableName = "sys_model_location_info"; +// QPair id_value; +// id_value.first = "location_id"; +// id_value.second = "description"; +// if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) +// { +// kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); +// kbd_dbms::CRdbQueryResult result; +// std::vector columns; +// columns.push_back(id_value.first); +// columns.push_back(id_value.second); + +// if(m_rtdbAccess->select(result, columns)) +// { +// m_locationInfo.clear(); +// for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) +// { +// kbd_dbms::CVarType key; +// kbd_dbms::CVarType value; +// result.getColumnValue(nIndex, 0, key); +// result.getColumnValue(nIndex, 1, value); + +// std::vector ::const_iterator it = vecLocationId.cbegin(); +// while (it != vecLocationId.cend()) +// { +// if(key.toInt() == *it) +// { +// m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); +// } +// ++it; +// } +// } +// } +// } +// m_rtdbAccess->close(); +} + +void CDbInterfaceMng::loadDevGroupInfo() +{ + QSqlQuery query; + + //< 查询pscada专业所有设备组 + QString strLoctionFilter; + if(!m_locationInfo.keys().isEmpty()) + { + QStringList listLocation; + foreach (int nLocationID, m_locationInfo.keys()) + { + listLocation.append(QString::number(nLocationID)); + } + strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); + }else + { + return ; + } + QString sqlSequenceQuery = QString("select tag_name, description, location_id from dev_group where sub_system > 3 "); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); + }else + { + sqlSequenceQuery.append(QString(" order by dev_group_no asc;")); + } + m_pWriteDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + QPair pair; + pair.first = query.value(0).toString(); + pair.second = query.value(1).toString(); + m_devgInfoMap[pair.first] = pair.second; + QMap > >::iterator it = m_devGroupInfoMap.find(query.value(2).toInt()); + if(it !=m_devGroupInfoMap.end()) + { + QList > &devgList = it.value(); + devgList.append(pair); + }else + { + QList > devgList; + devgList.append(pair); + m_devGroupInfoMap[query.value(2).toInt()] = devgList; + } + } +} + +void CDbInterfaceMng::loadDeviceInfo() +{ + m_devDevgMap.clear(); + m_devGDevInfoMap.clear(); + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,GROUP_TAG_NAME from dev_info"); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + QString devg = query.value(2).toString(); + m_devDevgMap[tag] = devg; + QMap >::iterator iter = m_devGDevInfoMap.find(devg); + if(iter != m_devGDevInfoMap.end()) + { + m_devGDevInfoMap[devg].insert(tag,desc); + }else + { + QMap devMap; + devMap.insert(tag,desc); + m_devGDevInfoMap[devg] = devMap; + } + } +} + +void CDbInterfaceMng::loadDigitalText() +{ + m_digitalTextMap.clear(); + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select state_text_name,actual_value,display_value from %1").arg("dict_state_text_info"); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString state_text_name = query.value(0).toString(); + int actual_value = query.value(1).toInt(); + QString display_value = query.value(2).toString(); + QMap >::iterator iter = m_digitalTextMap.find(state_text_name); + if(iter != m_digitalTextMap.end()) + { + iter.value().insert(actual_value,display_value); + }else + { + QMap actualMap; + actualMap.insert(actual_value,display_value); + m_digitalTextMap[state_text_name] = actualMap; + } + } +} + +void CDbInterfaceMng::loadOptCtrlActDefine() +{ + m_ctrlGroupMap.clear(); + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select ctrl_grp_name,target_value,ctrl_act_name from %1").arg("opt_ctrl_act_define"); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + QString grpName = query.value(0).toString(); + int targetValue = query.value(1).toInt(); + QString actName = query.value(2).toString(); + QMap >::iterator iter = m_ctrlGroupMap.find(grpName); + if(iter != m_ctrlGroupMap.end()) + { + iter.value().insert(targetValue,actName); + }else + { + QMap actualMap; + actualMap.insert(targetValue,actName); + m_ctrlGroupMap[grpName] = actualMap; + } + } +} + +void CDbInterfaceMng::getDiByDev(const QString &dev, QList &list) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE,STATE_TEXT_NAME from digital where device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointsInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devg = getDevgByDevTag(query.value(2).toString()); + info.digitalText = query.value(3).toString(); + info.table = "digital"; + list.append(info); + } +} + +void CDbInterfaceMng::getAiByDev(const QString &dev, QList &list) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from analog where device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointsInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devg = getDevgByDevTag(query.value(2).toString()); + info.table = "analog"; + list.append(info); + } +} + +void CDbInterfaceMng::getPiByDev(const QString &dev, QList &list) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from accuml where device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointsInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devg = getDevgByDevTag(query.value(2).toString()); + info.table = "accuml"; + list.append(info); + } +} + +void CDbInterfaceMng::getMiByDev(const QString &dev, QList &list) +{ + if(!m_pWriteDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,DEVICE from mix where device = '%1'").arg(dev); + + m_pWriteDb->execute(sqlQuery, query); + + while(query.next()) + { + PointsInfo info; + info.tag = query.value(0).toString(); + info.desc = query.value(1).toString(); + info.devg = getDevgByDevTag(query.value(2).toString()); + info.table = "mix"; + list.append(info); + } +} diff --git a/product/src/gui/plugin/PointsLockWidget/CDbInterfaceMng.h b/product/src/gui/plugin/PointsLockWidget/CDbInterfaceMng.h index 15f8f15a..275ad309 100644 --- a/product/src/gui/plugin/PointsLockWidget/CDbInterfaceMng.h +++ b/product/src/gui/plugin/PointsLockWidget/CDbInterfaceMng.h @@ -1,86 +1,86 @@ -#ifndef CDBINTERFACEMNG_H -#define CDBINTERFACEMNG_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/db_api_ex/CDbApi.h" -#include -#include "PointsLockCommon.h" -#include "CPointsInfo.h" - -class CDbInterfaceMng -{ -public: - static CDbInterfaceMng * instance(); - void destory(); - - QMap locationInfo(); - - QList > devGroupInfoList(const int& location); - - QMap deviceInfo(const QString &devGroupName); - - QList getCtrlPointByDev(const QString &dev); - - QList getPointByDev(const QString &dev); - - QString getCtrlGrpTextByCtrlPoint(const QString &tag); - - QMap getDigitalTextMapByKey(const QString &key); - - QMap getCtrlGrpTextMapByKey(const QString &key); - - int addPointLock(const QString & tag,int digitalValue,int check); - - int updatePointLock(PointsInfoPtr info,bool isEnable); - int delPointLock(PointsInfoPtr info); - QString getLocDescById(int loc); - - QString getDevgDescByDevg(const QString &devg); - - QString getDigitalValueDescByText(const QString &text, int value); - - QString getCtrlGrpDescByText(const QString &text, int value); - - QList getLockConfigInfo(); - - QString getDevgByDevTag(const QString dev); - - QString getDevgDescByDevTag(const QString dev); - - QList getConditionInfoByPointInfo(PointsInfoPtr info); - - int addConditionLock(PointsInfoPtr pointInfo,ConditionInfoPtr condInfo); - - int delConditionLock(PointsInfoPtr pointInfo ,ConditionInfoPtr condInfo); -private: - - CDbInterfaceMng(); - - void loadRTLocation(); - void loadDevGroupInfo(); - void loadDeviceInfo(); - void loadDigitalText(); - void loadOptCtrlActDefine(); - - void getDiByDev(const QString &dev,QList &list); - void getAiByDev(const QString &dev,QList &list); - void getPiByDev(const QString &dev,QList &list); - void getMiByDev(const QString &dev,QList &list); - -private: - static CDbInterfaceMng * m_pInstance; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_dbms::CDbApi * m_pWriteDb; - QMap m_locationInfo; //< LocationID-LocationDesc - - QMap > > m_devGroupInfoMap; //为了设备组号排序 - QMap m_devgInfoMap; //设备组和设备组描述映射 - QMap > m_devGDevInfoMap; //设备组和设备映射 - QMap m_devDevgMap; //设备和设备组标签映射 - QMap > m_digitalTextMap; //数字量文本 - QMap > m_ctrlGroupMap; //控制动作组 - -}; - -#endif // CDBINTERFACEMNG_H +#ifndef CDBINTERFACEMNG_H +#define CDBINTERFACEMNG_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" +#include +#include "PointsLockCommon.h" +#include "CPointsInfo.h" + +class CDbInterfaceMng +{ +public: + static CDbInterfaceMng * instance(); + void destory(); + + QMap locationInfo(); + + QList > devGroupInfoList(const int& location); + + QMap deviceInfo(const QString &devGroupName); + + QList getCtrlPointByDev(const QString &dev); + + QList getPointByDev(const QString &dev); + + QString getCtrlGrpTextByCtrlPoint(const QString &tag); + + QMap getDigitalTextMapByKey(const QString &key); + + QMap getCtrlGrpTextMapByKey(const QString &key); + + int addPointLock(const QString & tag,int digitalValue,int check); + + int updatePointLock(PointsInfoPtr info,bool isEnable); + int delPointLock(PointsInfoPtr info); + QString getLocDescById(int loc); + + QString getDevgDescByDevg(const QString &devg); + + QString getDigitalValueDescByText(const QString &text, int value); + + QString getCtrlGrpDescByText(const QString &text, int value); + + QList getLockConfigInfo(); + + QString getDevgByDevTag(const QString dev); + + QString getDevgDescByDevTag(const QString dev); + + QList getConditionInfoByPointInfo(PointsInfoPtr info); + + int addConditionLock(PointsInfoPtr pointInfo,ConditionInfoPtr condInfo); + + int delConditionLock(PointsInfoPtr pointInfo ,ConditionInfoPtr condInfo); +private: + + CDbInterfaceMng(); + + void loadRTLocation(); + void loadDevGroupInfo(); + void loadDeviceInfo(); + void loadDigitalText(); + void loadOptCtrlActDefine(); + + void getDiByDev(const QString &dev,QList &list); + void getAiByDev(const QString &dev,QList &list); + void getPiByDev(const QString &dev,QList &list); + void getMiByDev(const QString &dev,QList &list); + +private: + static CDbInterfaceMng * m_pInstance; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_dbms::CDbApi * m_pWriteDb; + QMap m_locationInfo; //< LocationID-LocationDesc + + QMap > > m_devGroupInfoMap; //为了设备组号排序 + QMap m_devgInfoMap; //设备组和设备组描述映射 + QMap > m_devGDevInfoMap; //设备组和设备映射 + QMap m_devDevgMap; //设备和设备组标签映射 + QMap > m_digitalTextMap; //数字量文本 + QMap > m_ctrlGroupMap; //控制动作组 + +}; + +#endif // CDBINTERFACEMNG_H diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsInfo.cpp b/product/src/gui/plugin/PointsLockWidget/CPointsInfo.cpp index 3ef8f9f0..da174a79 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsInfo.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CPointsInfo.cpp @@ -1,35 +1,35 @@ -#include "CPointsInfo.h" - -CPointsInfo::CPointsInfo() -{ - -} - -CPointsInfo::CPointsInfo(const PointsInfoPtr &other) -{ - tag = other->tag; - desc = other->desc; - value = other->value; - enable = other->enable; - loc = other->loc; - dev = other->dev; - devg = other->devg; - ctrlGrpText = other->ctrlGrpText; -} - -CConditionInfo::CConditionInfo() -{ - -} - -CConditionInfo::CConditionInfo(const ConditionInfoPtr &other) -{ - tag = other->tag; - desc = other->desc; - table = other->table; - cond1 = other->cond1; - value1 = other->value1; - cond2 = other->cond2; - value2 = other->value2; - digitalText = other->digitalText; -} +#include "CPointsInfo.h" + +CPointsInfo::CPointsInfo() +{ + +} + +CPointsInfo::CPointsInfo(const PointsInfoPtr &other) +{ + tag = other->tag; + desc = other->desc; + value = other->value; + enable = other->enable; + loc = other->loc; + dev = other->dev; + devg = other->devg; + ctrlGrpText = other->ctrlGrpText; +} + +CConditionInfo::CConditionInfo() +{ + +} + +CConditionInfo::CConditionInfo(const ConditionInfoPtr &other) +{ + tag = other->tag; + desc = other->desc; + table = other->table; + cond1 = other->cond1; + value1 = other->value1; + cond2 = other->cond2; + value2 = other->value2; + digitalText = other->digitalText; +} diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsInfo.h b/product/src/gui/plugin/PointsLockWidget/CPointsInfo.h index 8823460a..cd89ac96 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsInfo.h +++ b/product/src/gui/plugin/PointsLockWidget/CPointsInfo.h @@ -1,44 +1,44 @@ -#ifndef CPOINTSINFO_H -#define CPOINTSINFO_H - -#include - -class CPointsInfo; -class CConditionInfo; -typedef QSharedPointer PointsInfoPtr; -typedef QSharedPointer ConditionInfoPtr; - -class CPointsInfo -{ -public: - CPointsInfo(); - CPointsInfo(const PointsInfoPtr &other); - - QString tag; - QString desc; - int loc; - QString ctrlGrpText; - QString dev; - QString devg; - int value; - int enable; -}; - - -class CConditionInfo -{ -public: - CConditionInfo(); - CConditionInfo(const ConditionInfoPtr &other); - - QString tag; - QString desc; - QString table; - int cond1; - double value1; - int cond2; - double value2; - QString digitalText; -}; - -#endif // CPOINTSINFO_H +#ifndef CPOINTSINFO_H +#define CPOINTSINFO_H + +#include + +class CPointsInfo; +class CConditionInfo; +typedef QSharedPointer PointsInfoPtr; +typedef QSharedPointer ConditionInfoPtr; + +class CPointsInfo +{ +public: + CPointsInfo(); + CPointsInfo(const PointsInfoPtr &other); + + QString tag; + QString desc; + int loc; + QString ctrlGrpText; + QString dev; + QString devg; + int value; + int enable; +}; + + +class CConditionInfo +{ +public: + CConditionInfo(); + CConditionInfo(const ConditionInfoPtr &other); + + QString tag; + QString desc; + QString table; + int cond1; + double value1; + int cond2; + double value2; + QString digitalText; +}; + +#endif // CPOINTSINFO_H diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.cpp b/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.cpp index 9274f0c1..c8457117 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "CPointsLockPluginWidget.h" -#include -#include "PointsLockWidget.h" -#include "pub_logger_api/logger.h" -CPointsLockPluginWidget::CPointsLockPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CPointsLockPluginWidget::~CPointsLockPluginWidget() -{ - -} - -bool CPointsLockPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **lockWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - PointsLockWidget *pWidget = new PointsLockWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *lockWidget = (IPluginWidget *)pWidget; - return true; -} - -void CPointsLockPluginWidget::release() -{ - -} +#include "CPointsLockPluginWidget.h" +#include +#include "PointsLockWidget.h" +#include "pub_logger_api/logger.h" +CPointsLockPluginWidget::CPointsLockPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CPointsLockPluginWidget::~CPointsLockPluginWidget() +{ + +} + +bool CPointsLockPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **lockWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + PointsLockWidget *pWidget = new PointsLockWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *lockWidget = (IPluginWidget *)pWidget; + return true; +} + +void CPointsLockPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.h b/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.h index f37931fc..1c4b6ef9 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.h +++ b/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CPOINTSLOCKPLUGINWIDGET_H -#define CPOINTSLOCKPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CPointsLockPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CPointsLockPluginWidget(QObject *parent = 0); - - ~CPointsLockPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **lockWidget, QVector ptrVec); - void release(); -}; - -#endif // CPOINTSLOCKPLUGINWIDGET_H +#ifndef CPOINTSLOCKPLUGINWIDGET_H +#define CPOINTSLOCKPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CPointsLockPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CPointsLockPluginWidget(QObject *parent = 0); + + ~CPointsLockPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **lockWidget, QVector ptrVec); + void release(); +}; + +#endif // CPOINTSLOCKPLUGINWIDGET_H diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.cpp b/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.cpp index ce7f87cd..dccd2275 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.cpp @@ -1,167 +1,167 @@ -#include "CPointsOptDialog.h" -#include "ui_CPointsOptDialog.h" -#include "CDbInterfaceMng.h" -#include "PointsLockCommon.h" -#include - -CPointsOptDialog::CPointsOptDialog(int mode, QWidget *parent) : - QDialog(parent), - ui(new Ui::CPointsOptDialog), - m_mode(mode) -{ - ui->setupUi(this); - - if(m_mode == EN_POINT_OPT_ADD) - { - setWindowTitle(tr("添加闭锁测点")); - }else - { - setWindowTitle(tr("编辑闭锁测点")); - } - initConnect(); - initTreeWidget(); -} - -CPointsOptDialog::~CPointsOptDialog() -{ - delete ui; -} - -void CPointsOptDialog::initConnect() -{ - - connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CPointsOptDialog::treeItemClicked); - connect(ui->listWidget,&QListWidget::itemClicked,this,&CPointsOptDialog::listItemClicked); - - - connect(ui->pOk,&QPushButton::clicked,this,&CPointsOptDialog::okClicked); - connect(ui->pCancle,&QPushButton::clicked,this,&CPointsOptDialog::reject); -} - -void CPointsOptDialog::initTreeWidget() -{ - cleanTreeWidget(); - ui->treeWidget->setColumnCount(1); - QMap locMap = CDbInterfaceMng::instance()->locationInfo(); - QMap::iterator it =locMap.begin(); - while (it != locMap.end()) { - QTreeWidgetItem *locItem = new QTreeWidgetItem(); - locItem->setText(0,it.value()); - locItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_LOC);//类型 - locItem->setData(0,Qt::UserRole+1,it.key());//值 - ui->treeWidget->addTopLevelItem(locItem); - - QList > devGroupInfoList = CDbInterfaceMng::instance()->devGroupInfoList(it.key()); - for(int index(0);indexsetText(0,devGroupInfoList.at(index).second); - devgItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_DEVG);//类型 - devgItem->setData(0,Qt::UserRole+1,devGroupInfoList.at(index).first);//值 - locItem->addChild(devgItem); - QMap devInfo = CDbInterfaceMng::instance()->deviceInfo(devGroupInfoList.at(index).first); - - QMap::iterator pos = devInfo.begin(); - while (pos != devInfo.end()) { - QTreeWidgetItem *devItem = new QTreeWidgetItem(); - devItem->setText(0,pos.value()); - devItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_DEV);//类型 - devItem->setData(0,Qt::UserRole+1,pos.key());//值 - devgItem->addChild(devItem); - pos++; - } - } - it++; - } -} - -void CPointsOptDialog::cleanTreeWidget() -{ - for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) - { - QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); - ui->treeWidget->removeItemWidget(item,0); - } -} - -void CPointsOptDialog::updateList(const QString &dev) -{ - QList list = CDbInterfaceMng::instance()->getCtrlPointByDev(dev); - for(int index(0);indexlistWidget); - item->setText(list.at(index).desc); - item->setData(Qt::UserRole,list.at(index).tag); - ui->listWidget->addItem(item); - } -} - -void CPointsOptDialog::treeItemClicked(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - ui->listWidget->clear(); - ui->comboBox->clear(); - if(item == Q_NULLPTR) - { - return ; - } - if(item->data(0,Qt::UserRole).toInt() == EN_TREE_POINTS_DEV) - { - QString dev =item->data(0,Qt::UserRole+1).toString(); - updateList(dev); - } -} - -void CPointsOptDialog::listItemClicked(QListWidgetItem *item) -{ - ui->comboBox->clear(); - QString tag = item->data(Qt::UserRole).toString(); - if(tag.isEmpty()) - { - return ; - } - QString ctrlGrpText = CDbInterfaceMng::instance()->getCtrlGrpTextByCtrlPoint(tag); - if(ctrlGrpText.isEmpty()) - { - return ; - } - QMap ctrlGrpTextMap = CDbInterfaceMng::instance()->getCtrlGrpTextMapByKey(ctrlGrpText); - QMap::iterator it = ctrlGrpTextMap.begin(); - while (it!= ctrlGrpTextMap.end()) { - - ui->comboBox->addItem(it.value(),it.key()); - it++; - } -} - -void CPointsOptDialog::okClicked() -{ - - QString tag =ui->listWidget->currentIndex().data(Qt::UserRole).toString(); - if(tag.isEmpty()) - { - showMess(tr("提示"),tr("请选择测点标签")); - return ; - } - if(ui->comboBox->count() <=0) - { - showMess(tr("提示"),tr("请选择控制动作组")); - return ; - } - int value = ui->comboBox->currentData().toInt(); - - int check = ui->checkBox->isChecked() ? 1:0; - if(CDbInterfaceMng::instance()->addPointLock(tag,value,check) == kbdSuccess) - { - accept(); - }else - { - showMess(tr("提示"),tr("添加失败")); - } - -} - -void CPointsOptDialog::showMess(const QString &title, const QString &mess) -{ - QMessageBox::information(this,title,mess); -} +#include "CPointsOptDialog.h" +#include "ui_CPointsOptDialog.h" +#include "CDbInterfaceMng.h" +#include "PointsLockCommon.h" +#include + +CPointsOptDialog::CPointsOptDialog(int mode, QWidget *parent) : + QDialog(parent), + ui(new Ui::CPointsOptDialog), + m_mode(mode) +{ + ui->setupUi(this); + + if(m_mode == EN_POINT_OPT_ADD) + { + setWindowTitle(tr("添加闭锁测点")); + }else + { + setWindowTitle(tr("编辑闭锁测点")); + } + initConnect(); + initTreeWidget(); +} + +CPointsOptDialog::~CPointsOptDialog() +{ + delete ui; +} + +void CPointsOptDialog::initConnect() +{ + + connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CPointsOptDialog::treeItemClicked); + connect(ui->listWidget,&QListWidget::itemClicked,this,&CPointsOptDialog::listItemClicked); + + + connect(ui->pOk,&QPushButton::clicked,this,&CPointsOptDialog::okClicked); + connect(ui->pCancle,&QPushButton::clicked,this,&CPointsOptDialog::reject); +} + +void CPointsOptDialog::initTreeWidget() +{ + cleanTreeWidget(); + ui->treeWidget->setColumnCount(1); + QMap locMap = CDbInterfaceMng::instance()->locationInfo(); + QMap::iterator it =locMap.begin(); + while (it != locMap.end()) { + QTreeWidgetItem *locItem = new QTreeWidgetItem(); + locItem->setText(0,it.value()); + locItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_LOC);//类型 + locItem->setData(0,Qt::UserRole+1,it.key());//值 + ui->treeWidget->addTopLevelItem(locItem); + + QList > devGroupInfoList = CDbInterfaceMng::instance()->devGroupInfoList(it.key()); + for(int index(0);indexsetText(0,devGroupInfoList.at(index).second); + devgItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_DEVG);//类型 + devgItem->setData(0,Qt::UserRole+1,devGroupInfoList.at(index).first);//值 + locItem->addChild(devgItem); + QMap devInfo = CDbInterfaceMng::instance()->deviceInfo(devGroupInfoList.at(index).first); + + QMap::iterator pos = devInfo.begin(); + while (pos != devInfo.end()) { + QTreeWidgetItem *devItem = new QTreeWidgetItem(); + devItem->setText(0,pos.value()); + devItem->setData(0,Qt::UserRole,(int)EN_TREE_POINTS_DEV);//类型 + devItem->setData(0,Qt::UserRole+1,pos.key());//值 + devgItem->addChild(devItem); + pos++; + } + } + it++; + } +} + +void CPointsOptDialog::cleanTreeWidget() +{ + for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) + { + QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); + ui->treeWidget->removeItemWidget(item,0); + } +} + +void CPointsOptDialog::updateList(const QString &dev) +{ + QList list = CDbInterfaceMng::instance()->getCtrlPointByDev(dev); + for(int index(0);indexlistWidget); + item->setText(list.at(index).desc); + item->setData(Qt::UserRole,list.at(index).tag); + ui->listWidget->addItem(item); + } +} + +void CPointsOptDialog::treeItemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + ui->listWidget->clear(); + ui->comboBox->clear(); + if(item == Q_NULLPTR) + { + return ; + } + if(item->data(0,Qt::UserRole).toInt() == EN_TREE_POINTS_DEV) + { + QString dev =item->data(0,Qt::UserRole+1).toString(); + updateList(dev); + } +} + +void CPointsOptDialog::listItemClicked(QListWidgetItem *item) +{ + ui->comboBox->clear(); + QString tag = item->data(Qt::UserRole).toString(); + if(tag.isEmpty()) + { + return ; + } + QString ctrlGrpText = CDbInterfaceMng::instance()->getCtrlGrpTextByCtrlPoint(tag); + if(ctrlGrpText.isEmpty()) + { + return ; + } + QMap ctrlGrpTextMap = CDbInterfaceMng::instance()->getCtrlGrpTextMapByKey(ctrlGrpText); + QMap::iterator it = ctrlGrpTextMap.begin(); + while (it!= ctrlGrpTextMap.end()) { + + ui->comboBox->addItem(it.value(),it.key()); + it++; + } +} + +void CPointsOptDialog::okClicked() +{ + + QString tag =ui->listWidget->currentIndex().data(Qt::UserRole).toString(); + if(tag.isEmpty()) + { + showMess(tr("提示"),tr("请选择测点标签")); + return ; + } + if(ui->comboBox->count() <=0) + { + showMess(tr("提示"),tr("请选择控制动作组")); + return ; + } + int value = ui->comboBox->currentData().toInt(); + + int check = ui->checkBox->isChecked() ? 1:0; + if(CDbInterfaceMng::instance()->addPointLock(tag,value,check) == kbdSuccess) + { + accept(); + }else + { + showMess(tr("提示"),tr("添加失败")); + } + +} + +void CPointsOptDialog::showMess(const QString &title, const QString &mess) +{ + QMessageBox::information(this,title,mess); +} diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.h b/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.h index 532362dd..bedce5f5 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.h +++ b/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.h @@ -1,48 +1,48 @@ -#ifndef CPOINTSOPTDIALOG_H -#define CPOINTSOPTDIALOG_H - -#include -#include -#include -#include "CPointsInfo.h" - -namespace Ui { -class CPointsOptDialog; -} - -class CPointsOptDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CPointsOptDialog(int mode,QWidget *parent = 0); - ~CPointsOptDialog(); - -private: - - void initConnect(); - void initTreeWidget(); - - void cleanTreeWidget(); - - void updateList(const QString &dev); - -private slots: - void treeItemClicked(QTreeWidgetItem *item, int column); - - void listItemClicked(QListWidgetItem *item); - - void okClicked(); - -private: - void showMess(const QString &title,const QString &mess); - -private: - Ui::CPointsOptDialog *ui; - - int m_mode; - - PointsInfoPtr m_info; -}; - -#endif // CPOINTSOPTDIALOG_H +#ifndef CPOINTSOPTDIALOG_H +#define CPOINTSOPTDIALOG_H + +#include +#include +#include +#include "CPointsInfo.h" + +namespace Ui { +class CPointsOptDialog; +} + +class CPointsOptDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CPointsOptDialog(int mode,QWidget *parent = 0); + ~CPointsOptDialog(); + +private: + + void initConnect(); + void initTreeWidget(); + + void cleanTreeWidget(); + + void updateList(const QString &dev); + +private slots: + void treeItemClicked(QTreeWidgetItem *item, int column); + + void listItemClicked(QListWidgetItem *item); + + void okClicked(); + +private: + void showMess(const QString &title,const QString &mess); + +private: + Ui::CPointsOptDialog *ui; + + int m_mode; + + PointsInfoPtr m_info; +}; + +#endif // CPOINTSOPTDIALOG_H diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.ui b/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.ui index 4a82ea67..6e8cb7af 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.ui +++ b/product/src/gui/plugin/PointsLockWidget/CPointsOptDialog.ui @@ -1,101 +1,101 @@ - - - CPointsOptDialog - - - - 0 - 0 - 473 - 390 - - - - Dialog - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - - - - - - - - 控制值 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 启用 - - - - - - - - - - 设备列表 - - - AlignCenter - - - - - - - - - + + + CPointsOptDialog + + + + 0 + 0 + 473 + 390 + + + + Dialog + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + + + + + + + + 控制值 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 启用 + + + + + + + + + + 设备列表 + + + AlignCenter + + + + + + + + + diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsTableModel.cpp b/product/src/gui/plugin/PointsLockWidget/CPointsTableModel.cpp index d890de8f..502c0dd6 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsTableModel.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CPointsTableModel.cpp @@ -1,112 +1,112 @@ -#include "CPointsTableModel.h" -#include "CDbInterfaceMng.h" -CPointsTableModel::CPointsTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header<= m_list.count()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - else if(Qt::DisplayRole == role) - { - switch ( index.column() ) - { - case 0 : - { - return CDbInterfaceMng::instance()->getLocDescById(m_list[index.row()]->loc); - } - case 1 : - { - return CDbInterfaceMng::instance()->getDevgDescByDevg(m_list[index.row()]->devg); - } - case 2 : - { - return m_list[index.row()]->desc; - } - case 3 : - { - if(m_list[index.row()]->enable == 0) - { - return tr("未启用"); - }else - { - return tr("已启用"); - } - } - case 4 : - { - return CDbInterfaceMng::instance()->getCtrlGrpDescByText(m_list[index.row()]->ctrlGrpText,m_list[index.row()]->value); - } - - default: - break; - } - } - return QVariant(); -} - -void CPointsTableModel::updateData(const QList &list) -{ - beginResetModel(); - m_list = list; - endResetModel(); -} - -PointsInfoPtr CPointsTableModel::getDataByIndex(QModelIndex index) -{ - if(!index.isValid() || m_list.count()= m_list.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + else if(Qt::DisplayRole == role) + { + switch ( index.column() ) + { + case 0 : + { + return CDbInterfaceMng::instance()->getLocDescById(m_list[index.row()]->loc); + } + case 1 : + { + return CDbInterfaceMng::instance()->getDevgDescByDevg(m_list[index.row()]->devg); + } + case 2 : + { + return m_list[index.row()]->desc; + } + case 3 : + { + if(m_list[index.row()]->enable == 0) + { + return tr("未启用"); + }else + { + return tr("已启用"); + } + } + case 4 : + { + return CDbInterfaceMng::instance()->getCtrlGrpDescByText(m_list[index.row()]->ctrlGrpText,m_list[index.row()]->value); + } + + default: + break; + } + } + return QVariant(); +} + +void CPointsTableModel::updateData(const QList &list) +{ + beginResetModel(); + m_list = list; + endResetModel(); +} + +PointsInfoPtr CPointsTableModel::getDataByIndex(QModelIndex index) +{ + if(!index.isValid() || m_list.count() -#include "CPointsInfo.h" - -class CPointsTableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CPointsTableModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - void updateData(const QList &list); - - PointsInfoPtr getDataByIndex(QModelIndex index); - - void removeData(QModelIndex index); -private: - - QStringList m_header; - - QList m_list; -}; - -#endif // CPOINTSTABLEMODEL_H +#ifndef CPOINTSTABLEMODEL_H +#define CPOINTSTABLEMODEL_H + +#include +#include "CPointsInfo.h" + +class CPointsTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CPointsTableModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + void updateData(const QList &list); + + PointsInfoPtr getDataByIndex(QModelIndex index); + + void removeData(QModelIndex index); +private: + + QStringList m_header; + + QList m_list; +}; + +#endif // CPOINTSTABLEMODEL_H diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsView.cpp b/product/src/gui/plugin/PointsLockWidget/CPointsView.cpp index 2867d16d..01286047 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsView.cpp +++ b/product/src/gui/plugin/PointsLockWidget/CPointsView.cpp @@ -1,14 +1,14 @@ -#include "CPointsView.h" -#include -#include - -CPointsView::CPointsView(QWidget *parent) - : QTableView(parent) -{ - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - - horizontalHeader()->setVisible(true); -} +#include "CPointsView.h" +#include +#include + +CPointsView::CPointsView(QWidget *parent) + : QTableView(parent) +{ + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + + horizontalHeader()->setVisible(true); +} diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsView.h b/product/src/gui/plugin/PointsLockWidget/CPointsView.h index e9a873c9..a514282e 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsView.h +++ b/product/src/gui/plugin/PointsLockWidget/CPointsView.h @@ -1,16 +1,16 @@ -#ifndef CPOINTSVIEW_H -#define CPOINTSVIEW_H - -#include - -#include - -class CPointsView : public QTableView -{ - Q_OBJECT - -public: - CPointsView(QWidget *parent = Q_NULLPTR); -}; - -#endif // CPOINTSVIEW_H +#ifndef CPOINTSVIEW_H +#define CPOINTSVIEW_H + +#include + +#include + +class CPointsView : public QTableView +{ + Q_OBJECT + +public: + CPointsView(QWidget *parent = Q_NULLPTR); +}; + +#endif // CPOINTSVIEW_H diff --git a/product/src/gui/plugin/PointsLockWidget/PointsLockCommon.h b/product/src/gui/plugin/PointsLockWidget/PointsLockCommon.h index 02db2a96..821dda72 100644 --- a/product/src/gui/plugin/PointsLockWidget/PointsLockCommon.h +++ b/product/src/gui/plugin/PointsLockWidget/PointsLockCommon.h @@ -1,37 +1,37 @@ -#ifndef POINTSLOCKCOMMON_H -#define POINTSLOCKCOMMON_H - -#include - -enum EN_POINT_OPT_TYPE -{ - EN_POINT_OPT_ADD = 0, - EN_POINT_OPT_EDIT =1 -}; - -enum EN_CONDITION_OPT_TYPE -{ - EN_CONDITION_OPT_ADD = 0, - EN_CONDITION_OPT_EDIT =1 -}; - -enum EN_TREE_POINTS_TYPE -{ - EN_TREE_POINTS_LOC = 1001, - EN_TREE_POINTS_SUB = 1002, - EN_TREE_POINTS_DEVG = 1003, - EN_TREE_POINTS_DEV = 1004 -}; - -struct PointsInfo -{ - QString tag; - QString desc; - int loc; - QString devg; - QString digitalText; - QString table; - PointsInfo() {} -}; - -#endif // POINTSLOCKCOMMON_H +#ifndef POINTSLOCKCOMMON_H +#define POINTSLOCKCOMMON_H + +#include + +enum EN_POINT_OPT_TYPE +{ + EN_POINT_OPT_ADD = 0, + EN_POINT_OPT_EDIT =1 +}; + +enum EN_CONDITION_OPT_TYPE +{ + EN_CONDITION_OPT_ADD = 0, + EN_CONDITION_OPT_EDIT =1 +}; + +enum EN_TREE_POINTS_TYPE +{ + EN_TREE_POINTS_LOC = 1001, + EN_TREE_POINTS_SUB = 1002, + EN_TREE_POINTS_DEVG = 1003, + EN_TREE_POINTS_DEV = 1004 +}; + +struct PointsInfo +{ + QString tag; + QString desc; + int loc; + QString devg; + QString digitalText; + QString table; + PointsInfo() {} +}; + +#endif // POINTSLOCKCOMMON_H diff --git a/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.cpp b/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.cpp index 0c1cd9a6..7cbc01ac 100644 --- a/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.cpp +++ b/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.cpp @@ -1,264 +1,264 @@ -#include "PointsLockWidget.h" -#include "ui_PointsLockWidget.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include "CDbInterfaceMng.h" -#include "CPointsOptDialog.h" -#include "PointsLockCommon.h" -#include "CConditionOptDialog.h" -#include -#include - -PointsLockWidget::PointsLockWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::PointsLockWidget), - m_pmodel(Q_NULLPTR), - m_pCondModel(Q_NULLPTR), - m_curinfo(Q_NULLPTR) -{ - ui->setupUi(this); - - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - else - { - qDebug() << "public.qss 无法打开!"; - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("devgrouplock.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - else - { - qDebug() << "devgrouplock.qss 无法打开!"; - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - ui->splitter->setSizes(QList()<<800<<300); - ui->widget->setEnabled(false); - if(!editMode) - { - loadData(); - initialize(); - } -} - -PointsLockWidget::~PointsLockWidget() -{ - delete ui; -} - -void PointsLockWidget::initialize() -{ - CDbInterfaceMng::instance(); - initTableView(); - initConditionView(); - initConnect(); -} - -void PointsLockWidget::initConnect() -{ - connect(ui->pAddPoint,&QToolButton::clicked,this,&PointsLockWidget::slotAddPoint); - connect(ui->pDelPoint,&QToolButton::clicked,this,&PointsLockWidget::slotDelPoint); - connect(ui->tableView,&CPointsView::clicked,this,&PointsLockWidget::showPointsLock); - connect(ui->pAddCondition,&QToolButton::clicked,this,&PointsLockWidget::slotAddCondition); - connect(ui->pDelCondition,&QToolButton::clicked,this,&PointsLockWidget::slotDelCondition); -} - -void PointsLockWidget::initTableView() -{ - if(m_pmodel == Q_NULLPTR) - { - m_pmodel = new CPointsTableModel(); - ui->tableView->setModel(m_pmodel); - ui->tableView->setColumnWidth(0,150); - ui->tableView->setColumnWidth(1,150); - ui->tableView->setColumnWidth(2,150); - ui->tableView->setColumnWidth(3,150); - } - m_pmodel->updateData(m_dataList); -} - -void PointsLockWidget::initConditionView() -{ - if(m_pCondModel == Q_NULLPTR) - { - m_pCondModel = new CConditionModel(); - ui->tableView_2->setModel(m_pCondModel); - ui->tableView_2->setColumnWidth(0,220); - } -} - -void PointsLockWidget::loadData() -{ - m_dataList.clear(); - m_dataList = CDbInterfaceMng::instance()->getLockConfigInfo(); -} - -void PointsLockWidget::initConditionWidget(PointsInfoPtr &info) -{ - QList condList; - ui->comboBox->clear(); - m_pCondModel->updateData(condList); - if(info == Q_NULLPTR) - { - ui->widget->setEnabled(false); - return; - } - - QString text = CDbInterfaceMng::instance()->getCtrlGrpDescByText(info->ctrlGrpText,info->value); - - ui->comboBox->addItem(text,info->value); - condList = CDbInterfaceMng::instance()->getConditionInfoByPointInfo(info); - m_pCondModel->updateData(condList); -} - -void PointsLockWidget::slotAddPoint() -{ - CPointsOptDialog dlg(EN_POINT_OPT_ADD,this); - if(dlg.exec() == QDialog::Accepted) - { - loadData(); - initTableView(); - m_curinfo = Q_NULLPTR; - initConditionWidget(m_curinfo); - } -} - -void PointsLockWidget::slotDelPoint() -{ - QModelIndexList modelIndexList = ui->tableView->selectionModel()->selectedIndexes(); - if(modelIndexList.count() <= 0) - { - showMess(tr("提示"),tr("请选中需要删除的行")); - return ; - } - PointsInfoPtr info = m_pmodel->getDataByIndex(modelIndexList.at(0)); - if(CDbInterfaceMng::instance()->delPointLock(info) == kbdSuccess) - { - m_pmodel->removeData(modelIndexList.at(0)); - ui->tableView->clearSelection(); - m_curinfo = Q_NULLPTR; - initConditionWidget(m_curinfo); - //showMess(tr("提示"),tr("删除成功")); - } -} - -void PointsLockWidget::showPointsLock(const QModelIndex &index) -{ - ui->widget->setEnabled(true); - m_curinfo = m_pmodel->getDataByIndex(index); - initConditionWidget(m_curinfo); -} - -void PointsLockWidget::slotAddCondition() -{ - CConditionOptDialog dlg(EN_CONDITION_OPT_ADD,m_curinfo,this); - if(dlg.exec() == QDialog::Accepted) - { - if(m_curinfo != Q_NULLPTR) - { - initConditionWidget(m_curinfo); - } - } -} - -void PointsLockWidget::slotDelCondition() -{ - QModelIndexList modelIndexList = ui->tableView_2->selectionModel()->selectedIndexes(); - if(modelIndexList.count()<=0) - { - showMess(tr("提示"),tr("请选中需要删除的行")); - return ; - } - ConditionInfoPtr info = m_pCondModel->getDataByIndex(modelIndexList.at(0)); - if(m_curinfo != Q_NULLPTR && CDbInterfaceMng::instance()->delConditionLock(m_curinfo,info) == kbdSuccess) - { - m_pCondModel->removeData(modelIndexList.at(0)); - //showMess(tr("提示"),tr("删除成功")); - } -} - -void PointsLockWidget::contextMenuEvent(QContextMenuEvent *event) -{ - QWidget::contextMenuEvent(event); - if(!m_pmodel) - { - return; - } - if(event->pos().x() < ui->tableView->pos().x()) - { - return; - } - QRect headerRect = ui->tableView->horizontalHeader()->rect(); - headerRect.moveTopLeft(ui->tableView->mapTo(this, QPoint())); - QModelIndex index_ = ui->tableView->indexAt(ui->tableView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); - if(!index_.isValid()) - { - return; - } - QModelIndexList indexLists = ui->tableView->selectionModel()->selectedIndexes(); - //判断右键位置是否在选中区 - QModelIndex index = ui->tableView->currentIndex(); - if(!indexLists.contains(index)) - { - ui->tableView->clearSelection(); - ui->tableView->setCurrentIndex(index); - } - PointsInfoPtr info = m_pmodel->getDataByIndex(index); - if(info == Q_NULLPTR) - { - return; - } - QMenu menu(this); - if(info->enable == 1) - { - QAction * cancleAction = menu.addAction(tr("禁用")); - connect(cancleAction,&QAction::triggered,[=](){ - if(CDbInterfaceMng::instance()->updatePointLock(info,false)) - { - showMess(tr("提示"),tr("禁用失败")); - }else - { - info->enable = 0; - } - }); - }else - { - QAction * selectAction = menu.addAction(tr("启用")); - connect(selectAction, &QAction::triggered, [=](){ - if(CDbInterfaceMng::instance()->updatePointLock(info,true)) - { - showMess(tr("提示"),tr("启用失败")); - }else - { - info->enable = 1; - } - }); - } - - menu.exec(QCursor::pos()); -} - -void PointsLockWidget::showMess(const QString &title, const QString &mess) -{ - QMessageBox::information(this,title,mess); - -} +#include "PointsLockWidget.h" +#include "ui_PointsLockWidget.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include "CDbInterfaceMng.h" +#include "CPointsOptDialog.h" +#include "PointsLockCommon.h" +#include "CConditionOptDialog.h" +#include +#include + +PointsLockWidget::PointsLockWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::PointsLockWidget), + m_pmodel(Q_NULLPTR), + m_pCondModel(Q_NULLPTR), + m_curinfo(Q_NULLPTR) +{ + ui->setupUi(this); + + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("devgrouplock.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + else + { + qDebug() << "devgrouplock.qss 无法打开!"; + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + ui->splitter->setSizes(QList()<<800<<300); + ui->widget->setEnabled(false); + if(!editMode) + { + loadData(); + initialize(); + } +} + +PointsLockWidget::~PointsLockWidget() +{ + delete ui; +} + +void PointsLockWidget::initialize() +{ + CDbInterfaceMng::instance(); + initTableView(); + initConditionView(); + initConnect(); +} + +void PointsLockWidget::initConnect() +{ + connect(ui->pAddPoint,&QToolButton::clicked,this,&PointsLockWidget::slotAddPoint); + connect(ui->pDelPoint,&QToolButton::clicked,this,&PointsLockWidget::slotDelPoint); + connect(ui->tableView,&CPointsView::clicked,this,&PointsLockWidget::showPointsLock); + connect(ui->pAddCondition,&QToolButton::clicked,this,&PointsLockWidget::slotAddCondition); + connect(ui->pDelCondition,&QToolButton::clicked,this,&PointsLockWidget::slotDelCondition); +} + +void PointsLockWidget::initTableView() +{ + if(m_pmodel == Q_NULLPTR) + { + m_pmodel = new CPointsTableModel(); + ui->tableView->setModel(m_pmodel); + ui->tableView->setColumnWidth(0,150); + ui->tableView->setColumnWidth(1,150); + ui->tableView->setColumnWidth(2,150); + ui->tableView->setColumnWidth(3,150); + } + m_pmodel->updateData(m_dataList); +} + +void PointsLockWidget::initConditionView() +{ + if(m_pCondModel == Q_NULLPTR) + { + m_pCondModel = new CConditionModel(); + ui->tableView_2->setModel(m_pCondModel); + ui->tableView_2->setColumnWidth(0,220); + } +} + +void PointsLockWidget::loadData() +{ + m_dataList.clear(); + m_dataList = CDbInterfaceMng::instance()->getLockConfigInfo(); +} + +void PointsLockWidget::initConditionWidget(PointsInfoPtr &info) +{ + QList condList; + ui->comboBox->clear(); + m_pCondModel->updateData(condList); + if(info == Q_NULLPTR) + { + ui->widget->setEnabled(false); + return; + } + + QString text = CDbInterfaceMng::instance()->getCtrlGrpDescByText(info->ctrlGrpText,info->value); + + ui->comboBox->addItem(text,info->value); + condList = CDbInterfaceMng::instance()->getConditionInfoByPointInfo(info); + m_pCondModel->updateData(condList); +} + +void PointsLockWidget::slotAddPoint() +{ + CPointsOptDialog dlg(EN_POINT_OPT_ADD,this); + if(dlg.exec() == QDialog::Accepted) + { + loadData(); + initTableView(); + m_curinfo = Q_NULLPTR; + initConditionWidget(m_curinfo); + } +} + +void PointsLockWidget::slotDelPoint() +{ + QModelIndexList modelIndexList = ui->tableView->selectionModel()->selectedIndexes(); + if(modelIndexList.count() <= 0) + { + showMess(tr("提示"),tr("请选中需要删除的行")); + return ; + } + PointsInfoPtr info = m_pmodel->getDataByIndex(modelIndexList.at(0)); + if(CDbInterfaceMng::instance()->delPointLock(info) == kbdSuccess) + { + m_pmodel->removeData(modelIndexList.at(0)); + ui->tableView->clearSelection(); + m_curinfo = Q_NULLPTR; + initConditionWidget(m_curinfo); + //showMess(tr("提示"),tr("删除成功")); + } +} + +void PointsLockWidget::showPointsLock(const QModelIndex &index) +{ + ui->widget->setEnabled(true); + m_curinfo = m_pmodel->getDataByIndex(index); + initConditionWidget(m_curinfo); +} + +void PointsLockWidget::slotAddCondition() +{ + CConditionOptDialog dlg(EN_CONDITION_OPT_ADD,m_curinfo,this); + if(dlg.exec() == QDialog::Accepted) + { + if(m_curinfo != Q_NULLPTR) + { + initConditionWidget(m_curinfo); + } + } +} + +void PointsLockWidget::slotDelCondition() +{ + QModelIndexList modelIndexList = ui->tableView_2->selectionModel()->selectedIndexes(); + if(modelIndexList.count()<=0) + { + showMess(tr("提示"),tr("请选中需要删除的行")); + return ; + } + ConditionInfoPtr info = m_pCondModel->getDataByIndex(modelIndexList.at(0)); + if(m_curinfo != Q_NULLPTR && CDbInterfaceMng::instance()->delConditionLock(m_curinfo,info) == kbdSuccess) + { + m_pCondModel->removeData(modelIndexList.at(0)); + //showMess(tr("提示"),tr("删除成功")); + } +} + +void PointsLockWidget::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(!m_pmodel) + { + return; + } + if(event->pos().x() < ui->tableView->pos().x()) + { + return; + } + QRect headerRect = ui->tableView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->tableView->mapTo(this, QPoint())); + QModelIndex index_ = ui->tableView->indexAt(ui->tableView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QModelIndexList indexLists = ui->tableView->selectionModel()->selectedIndexes(); + //判断右键位置是否在选中区 + QModelIndex index = ui->tableView->currentIndex(); + if(!indexLists.contains(index)) + { + ui->tableView->clearSelection(); + ui->tableView->setCurrentIndex(index); + } + PointsInfoPtr info = m_pmodel->getDataByIndex(index); + if(info == Q_NULLPTR) + { + return; + } + QMenu menu(this); + if(info->enable == 1) + { + QAction * cancleAction = menu.addAction(tr("禁用")); + connect(cancleAction,&QAction::triggered,[=](){ + if(CDbInterfaceMng::instance()->updatePointLock(info,false)) + { + showMess(tr("提示"),tr("禁用失败")); + }else + { + info->enable = 0; + } + }); + }else + { + QAction * selectAction = menu.addAction(tr("启用")); + connect(selectAction, &QAction::triggered, [=](){ + if(CDbInterfaceMng::instance()->updatePointLock(info,true)) + { + showMess(tr("提示"),tr("启用失败")); + }else + { + info->enable = 1; + } + }); + } + + menu.exec(QCursor::pos()); +} + +void PointsLockWidget::showMess(const QString &title, const QString &mess) +{ + QMessageBox::information(this,title,mess); + +} diff --git a/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.h b/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.h index d9e8fc22..2835e195 100644 --- a/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.h +++ b/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.h @@ -1,62 +1,62 @@ -#ifndef POINTSLOCKWIDGET_H -#define POINTSLOCKWIDGET_H - -#include -#include "CPointsTableModel.h" -#include "CConditionModel.h" - -namespace Ui { -class PointsLockWidget; -} - -class PointsLockWidget : public QWidget -{ - Q_OBJECT - -public: - explicit PointsLockWidget(QWidget *parent = 0, bool editMode = false); - ~PointsLockWidget(); - -private: - void initialize(); - - void initConnect(); - - void initTreeWidget(); - - void cleanTreeWidget(); - - void initTableView(); - - void initConditionView(); - - void loadData(); - - void initConditionWidget(PointsInfoPtr &info); - -public slots: - void slotAddPoint(); - - void slotDelPoint(); - - void showPointsLock(const QModelIndex &index); - - void slotAddCondition(); - - void slotDelCondition(); - -protected: - void contextMenuEvent(QContextMenuEvent *event); -private: - void showMess(const QString &title,const QString &mess); - -private: - Ui::PointsLockWidget *ui; - - CPointsTableModel *m_pmodel; - CConditionModel *m_pCondModel; - QList m_dataList; - PointsInfoPtr m_curinfo; -}; - -#endif // POINTSLOCKWIDGET_H +#ifndef POINTSLOCKWIDGET_H +#define POINTSLOCKWIDGET_H + +#include +#include "CPointsTableModel.h" +#include "CConditionModel.h" + +namespace Ui { +class PointsLockWidget; +} + +class PointsLockWidget : public QWidget +{ + Q_OBJECT + +public: + explicit PointsLockWidget(QWidget *parent = 0, bool editMode = false); + ~PointsLockWidget(); + +private: + void initialize(); + + void initConnect(); + + void initTreeWidget(); + + void cleanTreeWidget(); + + void initTableView(); + + void initConditionView(); + + void loadData(); + + void initConditionWidget(PointsInfoPtr &info); + +public slots: + void slotAddPoint(); + + void slotDelPoint(); + + void showPointsLock(const QModelIndex &index); + + void slotAddCondition(); + + void slotDelCondition(); + +protected: + void contextMenuEvent(QContextMenuEvent *event); +private: + void showMess(const QString &title,const QString &mess); + +private: + Ui::PointsLockWidget *ui; + + CPointsTableModel *m_pmodel; + CConditionModel *m_pCondModel; + QList m_dataList; + PointsInfoPtr m_curinfo; +}; + +#endif // POINTSLOCKWIDGET_H diff --git a/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.pro b/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.pro index 172a814d..cecec33e 100644 --- a/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.pro +++ b/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.pro @@ -1,72 +1,72 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-08-05T17:39:44 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = PointsLockWidget - -TEMPLATE = lib - - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - #main.cpp \ - PointsLockWidget.cpp \ - CDbInterfaceMng.cpp \ - CPointsOptDialog.cpp \ - CPointsView.cpp \ - CPointsTableModel.cpp \ - CPointsInfo.cpp \ - CConditionView.cpp \ - CConditionModel.cpp \ - CConditionOptDialog.cpp \ - CPointsLockPluginWidget.cpp - -HEADERS += \ - PointsLockWidget.h \ - CDbInterfaceMng.h \ - CPointsOptDialog.h \ - PointsLockCommon.h \ - CPointsView.h \ - CPointsTableModel.h \ - CPointsInfo.h \ - CConditionView.h \ - CConditionModel.h \ - CConditionOptDialog.h \ - CPointsLockPluginWidget.h - -FORMS += \ - PointsLockWidget.ui \ - CPointsOptDialog.ui \ - CConditionOptDialog.ui - - -LIBS += -llog4cplus -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api - -COMMON_PRI =$$PWD/../../../common.pri -exists($$COMMON_PRI){ - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -RESOURCES += \ - resource.qrc +#------------------------------------------------- +# +# Project created by QtCreator 2021-08-05T17:39:44 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = PointsLockWidget + +TEMPLATE = lib + + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + #main.cpp \ + PointsLockWidget.cpp \ + CDbInterfaceMng.cpp \ + CPointsOptDialog.cpp \ + CPointsView.cpp \ + CPointsTableModel.cpp \ + CPointsInfo.cpp \ + CConditionView.cpp \ + CConditionModel.cpp \ + CConditionOptDialog.cpp \ + CPointsLockPluginWidget.cpp + +HEADERS += \ + PointsLockWidget.h \ + CDbInterfaceMng.h \ + CPointsOptDialog.h \ + PointsLockCommon.h \ + CPointsView.h \ + CPointsTableModel.h \ + CPointsInfo.h \ + CConditionView.h \ + CConditionModel.h \ + CConditionOptDialog.h \ + CPointsLockPluginWidget.h + +FORMS += \ + PointsLockWidget.ui \ + CPointsOptDialog.ui \ + CConditionOptDialog.ui + + +LIBS += -llog4cplus -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -lpub_sysinfo_api + +COMMON_PRI =$$PWD/../../../common.pri +exists($$COMMON_PRI){ + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +RESOURCES += \ + resource.qrc diff --git a/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.ui b/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.ui index c8bc5c32..e37eef05 100644 --- a/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.ui +++ b/product/src/gui/plugin/PointsLockWidget/PointsLockWidget.ui @@ -1,178 +1,178 @@ - - - PointsLockWidget - - - - 0 - 0 - 1085 - 567 - - - - PointsLockWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - 280 - 20 - - - - - - - - QAbstractItemView::SingleSelection - - - - - - - border:0px; - - - - - - - :/icons/new.png:/icons/new.png - - - - - - - border:0px; - - - - - - - :/icons/delete.png:/icons/delete.png - - - - - - - - - - - - - - 控制状态 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - false - - - - - - - border:0px; - - - - - - - :/icons/new.png:/icons/new.png - - - - - - - border:0px; - - - - - - - :/icons/delete.png:/icons/delete.png - - - - - - - - - - - - - CPointsView - QTableView -
CPointsView.h
-
- - CConditionView - QTableView -
CConditionView.h
-
-
- - - - -
+ + + PointsLockWidget + + + + 0 + 0 + 1085 + 567 + + + + PointsLockWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + 280 + 20 + + + + + + + + QAbstractItemView::SingleSelection + + + + + + + border:0px; + + + + + + + :/icons/new.png:/icons/new.png + + + + + + + border:0px; + + + + + + + :/icons/delete.png:/icons/delete.png + + + + + + + + + + + + + + 控制状态 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + false + + + + + + + border:0px; + + + + + + + :/icons/new.png:/icons/new.png + + + + + + + border:0px; + + + + + + + :/icons/delete.png:/icons/delete.png + + + + + + + + + + + + + CPointsView + QTableView +
CPointsView.h
+
+ + CConditionView + QTableView +
CConditionView.h
+
+
+ + + + +
diff --git a/product/src/gui/plugin/PointsLockWidget/main.cpp b/product/src/gui/plugin/PointsLockWidget/main.cpp index 0e04cae5..b75e5f31 100644 --- a/product/src/gui/plugin/PointsLockWidget/main.cpp +++ b/product/src/gui/plugin/PointsLockWidget/main.cpp @@ -1,11 +1,11 @@ -#include "PointsLockWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - PointsLockWidget w; - w.show(); - - return a.exec(); -} +#include "PointsLockWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + PointsLockWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/PointsLockWidget/resource.qrc b/product/src/gui/plugin/PointsLockWidget/resource.qrc index e760cc74..04f52dac 100644 --- a/product/src/gui/plugin/PointsLockWidget/resource.qrc +++ b/product/src/gui/plugin/PointsLockWidget/resource.qrc @@ -1,6 +1,6 @@ - - - icons/delete.png - icons/new.png - - + + + icons/delete.png + icons/new.png + + diff --git a/product/src/gui/plugin/RelaySettingWidget/CDbMng.cpp b/product/src/gui/plugin/RelaySettingWidget/CDbMng.cpp index e86efebc..05793f16 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CDbMng.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CDbMng.cpp @@ -1,413 +1,413 @@ -#include "CDbMng.h" -#include "pub_logger_api/logger.h" -#include "pub_sysinfo_api/SysInfoApi.h" - -using namespace kbd_dbms; - -CDbMng *CDbMng::m_pInstance = NULL; - - -CDbMng *CDbMng::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CDbMng(); - } - return m_pInstance; -} - -void CDbMng::destory() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - m_pInstance = NULL; - delete this; -} - -QMap CDbMng::getLocInfo() -{ - if(!m_locMap.isEmpty()) - { - return m_locMap; - } - - if(!m_pReadDb->isOpen()) - { - LOGERROR("getLocInfo():数据库读模型打开失败!"); - return m_locMap; - } - - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION,DOMAIN_ID from sys_model_location_info order by LOCATION_NO"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - RelayLoc relayLoc; - relayLoc.id = query.value(0).toInt(); - relayLoc.desc = query.value(1).toString(); - relayLoc.domainId = query.value(2).toInt(); - m_locMap.insert(relayLoc.id, relayLoc); - } - return m_locMap; -} - -QMap CDbMng::getRtuInfo() -{ - if(!m_rtuMap.isEmpty()) - { - return m_rtuMap; - } - if(!m_pReadDb->isOpen()) - { - LOGERROR("getRtuInfo():数据库读模型打开失败!"); - return m_rtuMap; - } - - QSqlQuery query; - QString sqlQuery = QString("select LOCATION_ID,SUB_SYSTEM,TAG_NAME,DESCRIPTION from fes_rtu_para"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - RelayRtu relayRtu; - relayRtu.locId = query.value(0).toInt(); - relayRtu.subId = query.value(1).toInt(); - relayRtu.name = query.value(2).toString(); - relayRtu.desc = query.value(3).toString(); - - m_rtuMap.insert(relayRtu.name, relayRtu); - } - return m_rtuMap; -} - -QMap CDbMng::getDevInfo() -{ - if(!m_devMap.isEmpty()) - { - return m_devMap; - } - - if(!m_pReadDb->isOpen()) - { - LOGERROR("getDevInfo():数据库读模型打开失败!"); - return m_devMap; - } - - QSqlQuery query; - QString sqlQuery = QString("select fes_dev_info.LOCATION_ID,fes_dev_info.SUB_SYSTEM,fes_dev_info.RTU_TAG,fes_dev_info.TAG_NAME," - "fes_dev_info.DEV_DESC,fes_dev_info.DEV_ID from fes_dev_info inner join fes_const on fes_const.DEV_TAG = fes_dev_info.TAG_NAME " - "group by fes_dev_info.TAG_NAME"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - RelayDev relayDev; - relayDev.locId = query.value(0).toInt(); - relayDev.subId = query.value(1).toInt(); - relayDev.rtuName = query.value(2).toString(); - relayDev.name = query.value(3).toString(); - relayDev.desc = query.value(4).toString(); - relayDev.id = query.value(5).toInt(); - - m_devMap.insert(relayDev.name, relayDev); - } - return m_devMap; -} - -QMap > > CDbMng::getLocRtuDevInfo() -{ - if(!m_locRtuDevMap.isEmpty()) - { - return m_locRtuDevMap; - } - if(m_devMap.isEmpty()) - { - getDevInfo(); - } - QMap::iterator it = m_devMap.begin(); - while (it != m_devMap.end()) { - RelayDev &dev = it.value(); - QMap > >::iterator pos = m_locRtuDevMap.find(dev.locId); - if(pos != m_locRtuDevMap.end()) - { - QMap > &relayRtuDev = pos.value(); - QMap >::iterator itpos = relayRtuDev.find(dev.rtuName); - if(itpos != relayRtuDev.end()) - { - QMap & relayDev = itpos.value(); - relayDev[dev.name] = dev; - }else - { - QMap relayDev; - relayDev[dev.name] = dev; - relayRtuDev[dev.rtuName] = relayDev; - } - }else - { - QMap relayDev; - relayDev[dev.name] = dev; - QMap > relayRtuDev; - relayRtuDev[dev.rtuName] = relayDev; - m_locRtuDevMap[dev.locId] = relayRtuDev; - } - it++; - } - return m_locRtuDevMap; -} - -QMap CDbMng::getUnitInfo() -{ - if(!m_unitMap.isEmpty()) - { - return m_unitMap; - } - - if(!m_pReadDb->isOpen()) - { - LOGERROR("getUnitInfo():数据库读模型打开失败!"); - return m_unitMap; - } - - QSqlQuery query; - QString sqlQuery = QString("select UNIT_ID,UNIT_NAME from dict_unit_info"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - RelayUnit relayUnit; - relayUnit.id = query.value(0).toInt(); - relayUnit.name = query.value(1).toString(); - - m_unitMap.insert(relayUnit.id, relayUnit); - } - return m_unitMap; -} - -QMap > CDbMng::getDictInfo() -{ - if(!m_dictMap.isEmpty()) - { - return m_dictMap; - } - - if(!m_pReadDb->isOpen()) - { - LOGERROR("getDictInfo():数据库读模型打开失败!"); - return m_dictMap; - } - - QSqlQuery query; - QString sqlQuery = QString("select CLASS_NAME,ACTUAL_VALUE,DISPLAY_NAME from dict_text_define"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - RelayDictState relayDict; - relayDict.name = query.value(0).toString(); - relayDict.value = query.value(1).toInt(); - relayDict.displayName = query.value(2).toString(); - - QMap >::iterator it = m_dictMap.find(relayDict.name); - if(it != m_dictMap.end()) - { - it.value().append(relayDict); - }else - { - QList relayDictList; - relayDictList.append(relayDict); - m_dictMap[relayDict.name] = relayDictList; - } - - } - return m_dictMap; -} - -QList CDbMng::getSettingByDev(const QString &dev) -{ - QList setList; - if(!m_pReadDb->isOpen()) - { - LOGERROR("getSettingByDev():数据库读模型打开失败!"); - return setList; - } - - QSqlQuery query; - QString sqlQuery = QString("SELECT t1.tag_name,t1.description,t1.group_no,t1.rtu_tag,t1.rtu_no,t1.dot_no," - "t1.seq_no,t1.sub_system,t1.location_id,t1.dev_tag,t1.value,t1.value_type,t1.unit_id," - "t1.value_text,t1.value_ratio,t1.value_added,t1.value_max,t1.value_min,t1.value_default," - "t1.value_verify,t1.ex_info,t2.domain_id,t2.description FROM fes_const as t1 left join " - "sys_model_location_info as t2 on t1.location_id = t2.location_id where t1.dev_tag = '%1'" - " order by t1.seq_no;").arg(dev); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - RelaySetting relaySetting; - relaySetting.tagName = query.value(0).toString(); - relaySetting.desc = query.value(1).toString(); - relaySetting.groupNo = query.value(2).toInt(); - - relaySetting.rtuTag = query.value(3).toString(); - relaySetting.rtuNo = query.value(4).toInt(); - relaySetting.dotNo = query.value(5).toInt(); - relaySetting.seqNo = query.value(6).toInt(); - relaySetting.subSystem = query.value(7).toInt(); - relaySetting.locId = query.value(8).toInt(); - relaySetting.devTag = query.value(9).toString(); - relaySetting.value = query.value(10).toFloat(); - relaySetting.valueType = query.value(11).toInt(); - relaySetting.unitId = query.value(12).toInt(); - relaySetting.valueText = query.value(13).toString(); - relaySetting.valueRatio = query.value(14).toFloat(); - relaySetting.valueAdded = query.value(15).toFloat(); - relaySetting.valueMax = query.value(16).toFloat(); - relaySetting.valueMin = query.value(17).toFloat(); - relaySetting.valueDefault = query.value(18).toFloat(); - relaySetting.valueVerify = query.value(19).toFloat(); - relaySetting.exInfo = query.value(20).toString(); - relaySetting.domainId = query.value(21).toInt(); - relaySetting.locDesc = query.value(22).toString(); - relaySetting.keyIdTag = QString("%1.%2.%3").arg("fes_const").arg(relaySetting.tagName).arg("value"); - - - setList.append(relaySetting); - } - return setList; -} - -QList CDbMng::getSetting() -{ - QList setList; - if(!m_pReadDb->isOpen()) - { - LOGERROR("getSetting():数据库读模型打开失败!"); - return setList; - } - kbd_public::CSysInfoInterfacePtr sysInfoPtr; - if(!kbd_public::createSysInfoInstance(sysInfoPtr)) - { - LOGERROR("getSetting():创建系统信息访问库实例失败!"); - return setList; - } - - QSqlQuery query; - QString sqlQuery = QString("SELECT t1.tag_name,t1.description,t1.group_no,t1.rtu_tag,t1.rtu_no,t1.dot_no," - "t1.seq_no,t1.sub_system,t1.location_id,t1.dev_tag,t1.value,t1.value_type,t1.unit_id," - "t1.value_text,t1.value_ratio,t1.value_added,t1.value_max,t1.value_min,t1.value_default," - "t1.value_verify,t1.ex_info,t2.domain_id,t2.description FROM fes_const as t1 left join " - "sys_model_location_info as t2 on t1.location_id = t2.location_id order by t1.seq_no;"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - RelaySetting relaySetting; - relaySetting.tagName = query.value(0).toString(); - relaySetting.desc = query.value(1).toString(); - relaySetting.groupNo = query.value(2).toInt(); - - relaySetting.rtuTag = query.value(3).toString(); - relaySetting.rtuNo = query.value(4).toInt(); - relaySetting.dotNo = query.value(5).toInt(); - relaySetting.seqNo = query.value(6).toInt(); - relaySetting.subSystem = query.value(7).toInt(); - relaySetting.locId = query.value(8).toInt(); - relaySetting.devTag = query.value(9).toString(); - relaySetting.value = query.value(10).toFloat(); - relaySetting.valueType = query.value(11).toInt(); - relaySetting.unitId = query.value(12).toInt(); - relaySetting.valueText = query.value(13).toString(); - relaySetting.valueRatio = query.value(14).toFloat(); - relaySetting.valueAdded = query.value(15).toFloat(); - relaySetting.valueMax = query.value(16).toFloat(); - relaySetting.valueMin = query.value(17).toFloat(); - relaySetting.valueDefault = query.value(18).toFloat(); - relaySetting.valueVerify = query.value(19).toFloat(); - relaySetting.exInfo = query.value(20).toString(); - relaySetting.domainId = query.value(21).toInt(); - relaySetting.locDesc = query.value(22).toString(); - relaySetting.keyIdTag = QString("%1.%2.%3").arg("fes_const").arg(relaySetting.tagName).arg("value"); - - kbd_public::SAppInfo stAppInfo; - if(kbdSuccess != sysInfoPtr->getAppInfoBySubsystemId(relaySetting.subSystem, stAppInfo)) - { - relaySetting.nAppId = relaySetting.subSystem; - } - else - { - relaySetting.nAppId = stAppInfo.nId; - } - - setList.append(relaySetting); - } - return setList; -} - -int CDbMng::getDevIdByTag(const QString &name) -{ - return m_devMap.value(name).id; -} - -QString CDbMng::getFesDevByKeyIdTag(const QString &keyIdTag) -{ - QString retStr; - if(!m_pReadDb->isOpen()) - { - LOGERROR("getFesDevByKeyIdTag():数据库读模型打开失败!"); - return retStr; - } - - QStringList keyIdTagList = keyIdTag.split("."); - QString table = keyIdTagList.at(2); - QString fesTable = QString("fes_%1").arg(table); - keyIdTagList.removeAt(0); - keyIdTagList.removeAt(0); - keyIdTagList.removeAt(0); - keyIdTagList.removeLast(); - QString appTagName =keyIdTagList.join("."); - - QSqlQuery query; - QString sqlQuery = QString("select DEV_TAG from %1 where APP_TAG_NAME='%2'") - .arg(fesTable).arg(appTagName); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - retStr = query.value(0).toString(); - break; - } - - return retStr; -} - -CDbMng::CDbMng() -{ - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - m_locMap.clear(); - m_rtuMap.clear(); - m_devMap.clear(); - m_locRtuDevMap.clear(); - m_unitMap.clear(); - -} +#include "CDbMng.h" +#include "pub_logger_api/logger.h" +#include "pub_sysinfo_api/SysInfoApi.h" + +using namespace kbd_dbms; + +CDbMng *CDbMng::m_pInstance = NULL; + + +CDbMng *CDbMng::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDbMng(); + } + return m_pInstance; +} + +void CDbMng::destory() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_pInstance = NULL; + delete this; +} + +QMap CDbMng::getLocInfo() +{ + if(!m_locMap.isEmpty()) + { + return m_locMap; + } + + if(!m_pReadDb->isOpen()) + { + LOGERROR("getLocInfo():数据库读模型打开失败!"); + return m_locMap; + } + + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID,DESCRIPTION,DOMAIN_ID from sys_model_location_info order by LOCATION_NO"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + RelayLoc relayLoc; + relayLoc.id = query.value(0).toInt(); + relayLoc.desc = query.value(1).toString(); + relayLoc.domainId = query.value(2).toInt(); + m_locMap.insert(relayLoc.id, relayLoc); + } + return m_locMap; +} + +QMap CDbMng::getRtuInfo() +{ + if(!m_rtuMap.isEmpty()) + { + return m_rtuMap; + } + if(!m_pReadDb->isOpen()) + { + LOGERROR("getRtuInfo():数据库读模型打开失败!"); + return m_rtuMap; + } + + QSqlQuery query; + QString sqlQuery = QString("select LOCATION_ID,SUB_SYSTEM,TAG_NAME,DESCRIPTION from fes_rtu_para"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + RelayRtu relayRtu; + relayRtu.locId = query.value(0).toInt(); + relayRtu.subId = query.value(1).toInt(); + relayRtu.name = query.value(2).toString(); + relayRtu.desc = query.value(3).toString(); + + m_rtuMap.insert(relayRtu.name, relayRtu); + } + return m_rtuMap; +} + +QMap CDbMng::getDevInfo() +{ + if(!m_devMap.isEmpty()) + { + return m_devMap; + } + + if(!m_pReadDb->isOpen()) + { + LOGERROR("getDevInfo():数据库读模型打开失败!"); + return m_devMap; + } + + QSqlQuery query; + QString sqlQuery = QString("select fes_dev_info.LOCATION_ID,fes_dev_info.SUB_SYSTEM,fes_dev_info.RTU_TAG,fes_dev_info.TAG_NAME," + "fes_dev_info.DEV_DESC,fes_dev_info.DEV_ID from fes_dev_info inner join fes_const on fes_const.DEV_TAG = fes_dev_info.TAG_NAME " + "group by fes_dev_info.TAG_NAME"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + RelayDev relayDev; + relayDev.locId = query.value(0).toInt(); + relayDev.subId = query.value(1).toInt(); + relayDev.rtuName = query.value(2).toString(); + relayDev.name = query.value(3).toString(); + relayDev.desc = query.value(4).toString(); + relayDev.id = query.value(5).toInt(); + + m_devMap.insert(relayDev.name, relayDev); + } + return m_devMap; +} + +QMap > > CDbMng::getLocRtuDevInfo() +{ + if(!m_locRtuDevMap.isEmpty()) + { + return m_locRtuDevMap; + } + if(m_devMap.isEmpty()) + { + getDevInfo(); + } + QMap::iterator it = m_devMap.begin(); + while (it != m_devMap.end()) { + RelayDev &dev = it.value(); + QMap > >::iterator pos = m_locRtuDevMap.find(dev.locId); + if(pos != m_locRtuDevMap.end()) + { + QMap > &relayRtuDev = pos.value(); + QMap >::iterator itpos = relayRtuDev.find(dev.rtuName); + if(itpos != relayRtuDev.end()) + { + QMap & relayDev = itpos.value(); + relayDev[dev.name] = dev; + }else + { + QMap relayDev; + relayDev[dev.name] = dev; + relayRtuDev[dev.rtuName] = relayDev; + } + }else + { + QMap relayDev; + relayDev[dev.name] = dev; + QMap > relayRtuDev; + relayRtuDev[dev.rtuName] = relayDev; + m_locRtuDevMap[dev.locId] = relayRtuDev; + } + it++; + } + return m_locRtuDevMap; +} + +QMap CDbMng::getUnitInfo() +{ + if(!m_unitMap.isEmpty()) + { + return m_unitMap; + } + + if(!m_pReadDb->isOpen()) + { + LOGERROR("getUnitInfo():数据库读模型打开失败!"); + return m_unitMap; + } + + QSqlQuery query; + QString sqlQuery = QString("select UNIT_ID,UNIT_NAME from dict_unit_info"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + RelayUnit relayUnit; + relayUnit.id = query.value(0).toInt(); + relayUnit.name = query.value(1).toString(); + + m_unitMap.insert(relayUnit.id, relayUnit); + } + return m_unitMap; +} + +QMap > CDbMng::getDictInfo() +{ + if(!m_dictMap.isEmpty()) + { + return m_dictMap; + } + + if(!m_pReadDb->isOpen()) + { + LOGERROR("getDictInfo():数据库读模型打开失败!"); + return m_dictMap; + } + + QSqlQuery query; + QString sqlQuery = QString("select CLASS_NAME,ACTUAL_VALUE,DISPLAY_NAME from dict_text_define"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + RelayDictState relayDict; + relayDict.name = query.value(0).toString(); + relayDict.value = query.value(1).toInt(); + relayDict.displayName = query.value(2).toString(); + + QMap >::iterator it = m_dictMap.find(relayDict.name); + if(it != m_dictMap.end()) + { + it.value().append(relayDict); + }else + { + QList relayDictList; + relayDictList.append(relayDict); + m_dictMap[relayDict.name] = relayDictList; + } + + } + return m_dictMap; +} + +QList CDbMng::getSettingByDev(const QString &dev) +{ + QList setList; + if(!m_pReadDb->isOpen()) + { + LOGERROR("getSettingByDev():数据库读模型打开失败!"); + return setList; + } + + QSqlQuery query; + QString sqlQuery = QString("SELECT t1.tag_name,t1.description,t1.group_no,t1.rtu_tag,t1.rtu_no,t1.dot_no," + "t1.seq_no,t1.sub_system,t1.location_id,t1.dev_tag,t1.value,t1.value_type,t1.unit_id," + "t1.value_text,t1.value_ratio,t1.value_added,t1.value_max,t1.value_min,t1.value_default," + "t1.value_verify,t1.ex_info,t2.domain_id,t2.description FROM fes_const as t1 left join " + "sys_model_location_info as t2 on t1.location_id = t2.location_id where t1.dev_tag = '%1'" + " order by t1.seq_no;").arg(dev); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + RelaySetting relaySetting; + relaySetting.tagName = query.value(0).toString(); + relaySetting.desc = query.value(1).toString(); + relaySetting.groupNo = query.value(2).toInt(); + + relaySetting.rtuTag = query.value(3).toString(); + relaySetting.rtuNo = query.value(4).toInt(); + relaySetting.dotNo = query.value(5).toInt(); + relaySetting.seqNo = query.value(6).toInt(); + relaySetting.subSystem = query.value(7).toInt(); + relaySetting.locId = query.value(8).toInt(); + relaySetting.devTag = query.value(9).toString(); + relaySetting.value = query.value(10).toFloat(); + relaySetting.valueType = query.value(11).toInt(); + relaySetting.unitId = query.value(12).toInt(); + relaySetting.valueText = query.value(13).toString(); + relaySetting.valueRatio = query.value(14).toFloat(); + relaySetting.valueAdded = query.value(15).toFloat(); + relaySetting.valueMax = query.value(16).toFloat(); + relaySetting.valueMin = query.value(17).toFloat(); + relaySetting.valueDefault = query.value(18).toFloat(); + relaySetting.valueVerify = query.value(19).toFloat(); + relaySetting.exInfo = query.value(20).toString(); + relaySetting.domainId = query.value(21).toInt(); + relaySetting.locDesc = query.value(22).toString(); + relaySetting.keyIdTag = QString("%1.%2.%3").arg("fes_const").arg(relaySetting.tagName).arg("value"); + + + setList.append(relaySetting); + } + return setList; +} + +QList CDbMng::getSetting() +{ + QList setList; + if(!m_pReadDb->isOpen()) + { + LOGERROR("getSetting():数据库读模型打开失败!"); + return setList; + } + kbd_public::CSysInfoInterfacePtr sysInfoPtr; + if(!kbd_public::createSysInfoInstance(sysInfoPtr)) + { + LOGERROR("getSetting():创建系统信息访问库实例失败!"); + return setList; + } + + QSqlQuery query; + QString sqlQuery = QString("SELECT t1.tag_name,t1.description,t1.group_no,t1.rtu_tag,t1.rtu_no,t1.dot_no," + "t1.seq_no,t1.sub_system,t1.location_id,t1.dev_tag,t1.value,t1.value_type,t1.unit_id," + "t1.value_text,t1.value_ratio,t1.value_added,t1.value_max,t1.value_min,t1.value_default," + "t1.value_verify,t1.ex_info,t2.domain_id,t2.description FROM fes_const as t1 left join " + "sys_model_location_info as t2 on t1.location_id = t2.location_id order by t1.seq_no;"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + RelaySetting relaySetting; + relaySetting.tagName = query.value(0).toString(); + relaySetting.desc = query.value(1).toString(); + relaySetting.groupNo = query.value(2).toInt(); + + relaySetting.rtuTag = query.value(3).toString(); + relaySetting.rtuNo = query.value(4).toInt(); + relaySetting.dotNo = query.value(5).toInt(); + relaySetting.seqNo = query.value(6).toInt(); + relaySetting.subSystem = query.value(7).toInt(); + relaySetting.locId = query.value(8).toInt(); + relaySetting.devTag = query.value(9).toString(); + relaySetting.value = query.value(10).toFloat(); + relaySetting.valueType = query.value(11).toInt(); + relaySetting.unitId = query.value(12).toInt(); + relaySetting.valueText = query.value(13).toString(); + relaySetting.valueRatio = query.value(14).toFloat(); + relaySetting.valueAdded = query.value(15).toFloat(); + relaySetting.valueMax = query.value(16).toFloat(); + relaySetting.valueMin = query.value(17).toFloat(); + relaySetting.valueDefault = query.value(18).toFloat(); + relaySetting.valueVerify = query.value(19).toFloat(); + relaySetting.exInfo = query.value(20).toString(); + relaySetting.domainId = query.value(21).toInt(); + relaySetting.locDesc = query.value(22).toString(); + relaySetting.keyIdTag = QString("%1.%2.%3").arg("fes_const").arg(relaySetting.tagName).arg("value"); + + kbd_public::SAppInfo stAppInfo; + if(kbdSuccess != sysInfoPtr->getAppInfoBySubsystemId(relaySetting.subSystem, stAppInfo)) + { + relaySetting.nAppId = relaySetting.subSystem; + } + else + { + relaySetting.nAppId = stAppInfo.nId; + } + + setList.append(relaySetting); + } + return setList; +} + +int CDbMng::getDevIdByTag(const QString &name) +{ + return m_devMap.value(name).id; +} + +QString CDbMng::getFesDevByKeyIdTag(const QString &keyIdTag) +{ + QString retStr; + if(!m_pReadDb->isOpen()) + { + LOGERROR("getFesDevByKeyIdTag():数据库读模型打开失败!"); + return retStr; + } + + QStringList keyIdTagList = keyIdTag.split("."); + QString table = keyIdTagList.at(2); + QString fesTable = QString("fes_%1").arg(table); + keyIdTagList.removeAt(0); + keyIdTagList.removeAt(0); + keyIdTagList.removeAt(0); + keyIdTagList.removeLast(); + QString appTagName =keyIdTagList.join("."); + + QSqlQuery query; + QString sqlQuery = QString("select DEV_TAG from %1 where APP_TAG_NAME='%2'") + .arg(fesTable).arg(appTagName); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + retStr = query.value(0).toString(); + break; + } + + return retStr; +} + +CDbMng::CDbMng() +{ + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + m_locMap.clear(); + m_rtuMap.clear(); + m_devMap.clear(); + m_locRtuDevMap.clear(); + m_unitMap.clear(); + +} diff --git a/product/src/gui/plugin/RelaySettingWidget/CDbMng.h b/product/src/gui/plugin/RelaySettingWidget/CDbMng.h index b451f33b..5c5a4b4f 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CDbMng.h +++ b/product/src/gui/plugin/RelaySettingWidget/CDbMng.h @@ -1,46 +1,46 @@ -#ifndef CDBMNG_H -#define CDBMNG_H - -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/db_api_ex/CDbApi.h" - -#include "CRelaySettingCommon.h" - -class CDbMng -{ -public: - static CDbMng * instance(); - void destory(); - - QMap getLocInfo(); - QMap getRtuInfo(); - QMap getDevInfo(); - QMap > > getLocRtuDevInfo(); - QMap getUnitInfo(); - QMap> getDictInfo(); - - QList getSettingByDev(const QString &dev); - QList getSetting(); - - int getDevIdByTag(const QString & name); - QString getFesDevByKeyIdTag(const QString &keyIdTag); -private: - CDbMng(); - -private: - static CDbMng * m_pInstance; - - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccess * m_rtdbAccess; - - QMap m_locMap; - QMap m_rtuMap; - QMap m_devMap; - - QMap > > m_locRtuDevMap; - - QMap m_unitMap; - QMap > m_dictMap; -}; - -#endif // CDBMNG_H +#ifndef CDBMNG_H +#define CDBMNG_H + +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" + +#include "CRelaySettingCommon.h" + +class CDbMng +{ +public: + static CDbMng * instance(); + void destory(); + + QMap getLocInfo(); + QMap getRtuInfo(); + QMap getDevInfo(); + QMap > > getLocRtuDevInfo(); + QMap getUnitInfo(); + QMap> getDictInfo(); + + QList getSettingByDev(const QString &dev); + QList getSetting(); + + int getDevIdByTag(const QString & name); + QString getFesDevByKeyIdTag(const QString &keyIdTag); +private: + CDbMng(); + +private: + static CDbMng * m_pInstance; + + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccess * m_rtdbAccess; + + QMap m_locMap; + QMap m_rtuMap; + QMap m_devMap; + + QMap > > m_locRtuDevMap; + + QMap m_unitMap; + QMap > m_dictMap; +}; + +#endif // CDBMNG_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CLogMng.cpp b/product/src/gui/plugin/RelaySettingWidget/CLogMng.cpp index 051e273c..b6eba262 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CLogMng.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CLogMng.cpp @@ -1,69 +1,69 @@ -#include "CLogMng.h" -#include -#include -#include -#include - -CLogMng *CLogMng::m_pInstance = NULL; - -CLogMng *CLogMng::Instance() -{ - if(m_pInstance == NULL) - { - m_pInstance = new CLogMng(); - } - return m_pInstance; -} - -void CLogMng::Destory() -{ - m_pInstance = NULL; - deleteLater(); -} - -void CLogMng::WriteLog(const QString &log) -{ - if(!m_bEnableWrite) - { - return ; - } - - QString filePath = QString("%1/%2").arg(m_strLogPath).arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")); - int first = filePath.lastIndexOf("/"); - //QString name = filePath.right(filePath.length()-first-1); - QString path = filePath.left(first); - QDir dir; - if(!dir.exists(path)) - { - dir.mkpath(path); - } - QFile file(filePath); - QString mes =QString("%1 %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(log); - - if(file.open(QIODevice::WriteOnly | QIODevice::Append )) - { - QTextStream textStream(&file); - textStream << mes << "\r\n"; - // file.write(mes.toStdString().c_str(),mes.size()); - - file.close(); - } - -} - -CLogMng::CLogMng(): QObject() -{ - m_bEnableWrite = true; - m_strLogPath =QDir::currentPath()+"/ProtectLog"; -} - -void CLogMng::saveStatusChange(int status) -{ - if(status) - { - m_bEnableWrite = true; - }else - { - m_bEnableWrite = false; - } -} +#include "CLogMng.h" +#include +#include +#include +#include + +CLogMng *CLogMng::m_pInstance = NULL; + +CLogMng *CLogMng::Instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CLogMng(); + } + return m_pInstance; +} + +void CLogMng::Destory() +{ + m_pInstance = NULL; + deleteLater(); +} + +void CLogMng::WriteLog(const QString &log) +{ + if(!m_bEnableWrite) + { + return ; + } + + QString filePath = QString("%1/%2").arg(m_strLogPath).arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")); + int first = filePath.lastIndexOf("/"); + //QString name = filePath.right(filePath.length()-first-1); + QString path = filePath.left(first); + QDir dir; + if(!dir.exists(path)) + { + dir.mkpath(path); + } + QFile file(filePath); + QString mes =QString("%1 %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(log); + + if(file.open(QIODevice::WriteOnly | QIODevice::Append )) + { + QTextStream textStream(&file); + textStream << mes << "\r\n"; + // file.write(mes.toStdString().c_str(),mes.size()); + + file.close(); + } + +} + +CLogMng::CLogMng(): QObject() +{ + m_bEnableWrite = true; + m_strLogPath =QDir::currentPath()+"/ProtectLog"; +} + +void CLogMng::saveStatusChange(int status) +{ + if(status) + { + m_bEnableWrite = true; + }else + { + m_bEnableWrite = false; + } +} diff --git a/product/src/gui/plugin/RelaySettingWidget/CLogMng.h b/product/src/gui/plugin/RelaySettingWidget/CLogMng.h index 65a4db4c..2e019438 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CLogMng.h +++ b/product/src/gui/plugin/RelaySettingWidget/CLogMng.h @@ -1,33 +1,33 @@ -#ifndef CLOGMNG_H -#define CLOGMNG_H - -#include - -class CLogMng : public QObject -{ - Q_OBJECT -public: - static CLogMng *Instance(); - - void Destory(); - - void WriteLog(const QString &log); - -private: - CLogMng(); - -signals: - -public slots: - void saveStatusChange(int status); - -private: - - static CLogMng * m_pInstance; - - bool m_bEnableWrite; - QString m_strLogPath; - -}; - -#endif // CLOGMNG_H +#ifndef CLOGMNG_H +#define CLOGMNG_H + +#include + +class CLogMng : public QObject +{ + Q_OBJECT +public: + static CLogMng *Instance(); + + void Destory(); + + void WriteLog(const QString &log); + +private: + CLogMng(); + +signals: + +public slots: + void saveStatusChange(int status); + +private: + + static CLogMng * m_pInstance; + + bool m_bEnableWrite; + QString m_strLogPath; + +}; + +#endif // CLOGMNG_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelayCommon.h b/product/src/gui/plugin/RelaySettingWidget/CRelayCommon.h index fbf1913b..ded4e68b 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelayCommon.h +++ b/product/src/gui/plugin/RelaySettingWidget/CRelayCommon.h @@ -1,77 +1,77 @@ -#ifndef CRELAYCOMMON_H -#define CRELAYCOMMON_H - -#include - -struct SRelayChanl -{ - - QString loc; //< 位置描述 - QString chanlDesc; //< 通道描述 - int chanlAddr; //< 通道地址 - QString ip; //< ip - int port; //< 端口号 - int index; //< 下标 - QString blockFileName; - QString paraFileName; - SRelayChanl(){ - - } -}; - -struct SRelayGroup -{ - int id; //< 组id - QString desc; //< 组描述 - SRelayGroup(){ - - } -}; - -struct SRelayBlock -{ - int funcNo; //< 功能码 - ushort startAddr; //< 寄存器起始地址 - ushort registerLen; //< 寄存器个数 - bool blockChangeFlag; - bool isFlag; - SRelayBlock(){ - blockChangeFlag = false; - isFlag = false; - } -}; - -struct SRelayPara -{ - float fValue; //< 值 - int pAddr; //< 寄存器地址 - float modulus; //< 系数 - int revise; //< 附加值 - int boardNo; //< 定值组号 - int pointNo; //< 定值点号 - int valueType; //< 值类型 - QString name; //< 名称 - bool isFlag; - int glFlag; //< 过流标示 - int timeFlag; //< 延迟标示 - SRelayPara(){ - fValue = 0.0; - isFlag = false; - glFlag = false; - timeFlag = false; - } -}; - -struct SRelayData -{ - QString chanName; - QString name; - float value; - SRelayData(){ - - } -}; - - - -#endif // CRELAYCOMMON_H +#ifndef CRELAYCOMMON_H +#define CRELAYCOMMON_H + +#include + +struct SRelayChanl +{ + + QString loc; //< 位置描述 + QString chanlDesc; //< 通道描述 + int chanlAddr; //< 通道地址 + QString ip; //< ip + int port; //< 端口号 + int index; //< 下标 + QString blockFileName; + QString paraFileName; + SRelayChanl(){ + + } +}; + +struct SRelayGroup +{ + int id; //< 组id + QString desc; //< 组描述 + SRelayGroup(){ + + } +}; + +struct SRelayBlock +{ + int funcNo; //< 功能码 + ushort startAddr; //< 寄存器起始地址 + ushort registerLen; //< 寄存器个数 + bool blockChangeFlag; + bool isFlag; + SRelayBlock(){ + blockChangeFlag = false; + isFlag = false; + } +}; + +struct SRelayPara +{ + float fValue; //< 值 + int pAddr; //< 寄存器地址 + float modulus; //< 系数 + int revise; //< 附加值 + int boardNo; //< 定值组号 + int pointNo; //< 定值点号 + int valueType; //< 值类型 + QString name; //< 名称 + bool isFlag; + int glFlag; //< 过流标示 + int timeFlag; //< 延迟标示 + SRelayPara(){ + fValue = 0.0; + isFlag = false; + glFlag = false; + timeFlag = false; + } +}; + +struct SRelayData +{ + QString chanName; + QString name; + float value; + SRelayData(){ + + } +}; + + + +#endif // CRELAYCOMMON_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelayFile.cpp b/product/src/gui/plugin/RelaySettingWidget/CRelayFile.cpp index 89ac2b53..43be57ca 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelayFile.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CRelayFile.cpp @@ -1,142 +1,142 @@ -#include "CRelayFile.h" -#include -#include -#include -#include -CRelayFile::CRelayFile() -{ - QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); - -} - -QList CRelayFile::getChanlList() -{ - QList chanList; - QDir dir = QDir::current(); - QFile file(dir.filePath("../../data/protect/ChanlPara.csv")); - - if(!file.open(QIODevice::ReadOnly)) - { - return chanList; - } - QTextStream *out = new QTextStream(&file); - // out->setCodec(QTextCodec::codecForName("GBK")); - QString ss = out->readLine(); - while(!out->atEnd()) - { - ss = out->readLine(); - QStringList tempbar = ss.split(","); - if(tempbar.size() < 5) - { - continue; - } - SRelayChanl relayChanl; - relayChanl.loc = tempbar[0]; - relayChanl.chanlDesc = tempbar[1]; - relayChanl.chanlAddr = tempbar[2].toInt(); - relayChanl.ip = tempbar[3]; - relayChanl.port = tempbar[4].toInt(); - relayChanl.blockFileName = tempbar[5]; - relayChanl.paraFileName = tempbar[6]; - relayChanl.index = chanList.size(); - chanList.append(relayChanl); - } - file.close(); - return chanList; -} - -QList CRelayFile::getGroupList() -{ - QList groupList; - QDir dir = QDir::current(); - QFile file(dir.filePath("../../data/protect/Type.csv")); - if(!file.open(QIODevice::ReadOnly)) - { - return groupList; - } - QTextStream *out = new QTextStream(&file); - // out->setCodec(QTextCodec::codecForName("GBK")); - QString ss = out->readLine(); - while(!out->atEnd()) - { - ss = out->readLine(); - QStringList tempbar = ss.split(","); - if(tempbar.size() < 2) - { - continue; - } - SRelayGroup relayGroup; - relayGroup.desc = tempbar[0]; - relayGroup.id = tempbar[1].toInt(); - groupList.append(relayGroup); - - } - file.close(); - return groupList; -} - -QList CRelayFile::getBlockList(const QString &fileName) -{ - QList blockList; - QDir dir = QDir::current(); - QFile file(dir.filePath(QString("../../data/protect/%1.csv").arg(fileName))); - if(!file.open(QIODevice::ReadOnly)) - { - return blockList; - } - QTextStream *out = new QTextStream(&file); - // out->setCodec(QTextCodec::codecForName("GBK")); - QString ss = out->readLine(); - while(!out->atEnd()) - { - ss = out->readLine(); - QStringList tempbar = ss.split(","); - if(tempbar.size() < 3) - { - continue; - } - SRelayBlock relayBlock; - relayBlock.funcNo = tempbar[0].toInt(); - relayBlock.startAddr = tempbar[1].toUShort(); - relayBlock.registerLen = tempbar[2].toUShort(); - blockList.append(relayBlock); - } - file.close(); - return blockList; -} - -QList CRelayFile::getParaList(const QString &fileName) -{ - QList paraList; - QDir dir = QDir::current(); - QFile file(dir.filePath(QString("../../data/protect/%1.csv").arg(fileName))); - if(!file.open(QIODevice::ReadOnly)) - { - return paraList; - } - QTextStream *out = new QTextStream(&file); - // out->setCodec(QTextCodec::codecForName("GBK")); - QString ss = out->readLine(); - while(!out->atEnd()) - { - ss = out->readLine(); - QStringList tempbar = ss.split(","); - if(tempbar.size() < 9) - { - continue; - } - SRelayPara relayPara; - relayPara.pAddr = tempbar[0].toInt(); - relayPara.boardNo = tempbar[1].toInt(); - relayPara.pointNo = tempbar[2].toInt(); - relayPara.modulus = tempbar[3].toFloat(); - relayPara.revise = tempbar[4].toInt(); - relayPara.valueType = tempbar[5].toInt(); - relayPara.name = tempbar[6]; - relayPara.glFlag = tempbar[7] == 1 ? true :false; - relayPara.timeFlag = tempbar[8] == 1 ? true :false; - paraList.append(relayPara); - } - file.close(); - return paraList; -} +#include "CRelayFile.h" +#include +#include +#include +#include +CRelayFile::CRelayFile() +{ + QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); + +} + +QList CRelayFile::getChanlList() +{ + QList chanList; + QDir dir = QDir::current(); + QFile file(dir.filePath("../../data/protect/ChanlPara.csv")); + + if(!file.open(QIODevice::ReadOnly)) + { + return chanList; + } + QTextStream *out = new QTextStream(&file); + // out->setCodec(QTextCodec::codecForName("GBK")); + QString ss = out->readLine(); + while(!out->atEnd()) + { + ss = out->readLine(); + QStringList tempbar = ss.split(","); + if(tempbar.size() < 5) + { + continue; + } + SRelayChanl relayChanl; + relayChanl.loc = tempbar[0]; + relayChanl.chanlDesc = tempbar[1]; + relayChanl.chanlAddr = tempbar[2].toInt(); + relayChanl.ip = tempbar[3]; + relayChanl.port = tempbar[4].toInt(); + relayChanl.blockFileName = tempbar[5]; + relayChanl.paraFileName = tempbar[6]; + relayChanl.index = chanList.size(); + chanList.append(relayChanl); + } + file.close(); + return chanList; +} + +QList CRelayFile::getGroupList() +{ + QList groupList; + QDir dir = QDir::current(); + QFile file(dir.filePath("../../data/protect/Type.csv")); + if(!file.open(QIODevice::ReadOnly)) + { + return groupList; + } + QTextStream *out = new QTextStream(&file); + // out->setCodec(QTextCodec::codecForName("GBK")); + QString ss = out->readLine(); + while(!out->atEnd()) + { + ss = out->readLine(); + QStringList tempbar = ss.split(","); + if(tempbar.size() < 2) + { + continue; + } + SRelayGroup relayGroup; + relayGroup.desc = tempbar[0]; + relayGroup.id = tempbar[1].toInt(); + groupList.append(relayGroup); + + } + file.close(); + return groupList; +} + +QList CRelayFile::getBlockList(const QString &fileName) +{ + QList blockList; + QDir dir = QDir::current(); + QFile file(dir.filePath(QString("../../data/protect/%1.csv").arg(fileName))); + if(!file.open(QIODevice::ReadOnly)) + { + return blockList; + } + QTextStream *out = new QTextStream(&file); + // out->setCodec(QTextCodec::codecForName("GBK")); + QString ss = out->readLine(); + while(!out->atEnd()) + { + ss = out->readLine(); + QStringList tempbar = ss.split(","); + if(tempbar.size() < 3) + { + continue; + } + SRelayBlock relayBlock; + relayBlock.funcNo = tempbar[0].toInt(); + relayBlock.startAddr = tempbar[1].toUShort(); + relayBlock.registerLen = tempbar[2].toUShort(); + blockList.append(relayBlock); + } + file.close(); + return blockList; +} + +QList CRelayFile::getParaList(const QString &fileName) +{ + QList paraList; + QDir dir = QDir::current(); + QFile file(dir.filePath(QString("../../data/protect/%1.csv").arg(fileName))); + if(!file.open(QIODevice::ReadOnly)) + { + return paraList; + } + QTextStream *out = new QTextStream(&file); + // out->setCodec(QTextCodec::codecForName("GBK")); + QString ss = out->readLine(); + while(!out->atEnd()) + { + ss = out->readLine(); + QStringList tempbar = ss.split(","); + if(tempbar.size() < 9) + { + continue; + } + SRelayPara relayPara; + relayPara.pAddr = tempbar[0].toInt(); + relayPara.boardNo = tempbar[1].toInt(); + relayPara.pointNo = tempbar[2].toInt(); + relayPara.modulus = tempbar[3].toFloat(); + relayPara.revise = tempbar[4].toInt(); + relayPara.valueType = tempbar[5].toInt(); + relayPara.name = tempbar[6]; + relayPara.glFlag = tempbar[7] == 1 ? true :false; + relayPara.timeFlag = tempbar[8] == 1 ? true :false; + paraList.append(relayPara); + } + file.close(); + return paraList; +} diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelayFile.h b/product/src/gui/plugin/RelaySettingWidget/CRelayFile.h index a588695b..c659a524 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelayFile.h +++ b/product/src/gui/plugin/RelaySettingWidget/CRelayFile.h @@ -1,21 +1,21 @@ -#ifndef CRELAYFILE_H -#define CRELAYFILE_H - -#include "CRelayCommon.h" -#include - -class CRelayFile -{ -public: - CRelayFile(); - - QList getChanlList(); - - QList getGroupList(); - - QList getBlockList(const QString &fileName); - - QList getParaList(const QString &fileName); -}; - -#endif // CRELAYFILE_H +#ifndef CRELAYFILE_H +#define CRELAYFILE_H + +#include "CRelayCommon.h" +#include + +class CRelayFile +{ +public: + CRelayFile(); + + QList getChanlList(); + + QList getGroupList(); + + QList getBlockList(const QString &fileName); + + QList getParaList(const QString &fileName); +}; + +#endif // CRELAYFILE_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingCommon.h b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingCommon.h index 8b781f70..5648ded1 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingCommon.h +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingCommon.h @@ -1,93 +1,93 @@ -#ifndef CRELAYSETTINGCOMMON_H -#define CRELAYSETTINGCOMMON_H - -#include - -struct RelayLoc -{ - int id; //< 位置id <主> - QString name; //< 位置标签 - QString desc; //< 位置描述 - int domainId; //< 域id - RelayLoc() {} -}; - -struct RelayRtu -{ - QString name; //< rtu标签 <主> - QString desc; //< rtu描述 - int locId; //< 位置id - int subId; //< 应用id - RelayRtu() {} -}; - -struct RelayDev -{ - int id; //< 设备id - QString name; //< 设备标签 <主> - QString desc; //< 设备描述 - int locId; //< 位置id - int subId; //< 应用id - QString rtuName; //< rtu标签 - RelayDev() {} -}; - -struct RelayUnit -{ - int id; //< 单位id - QString name; //< 单位标签 - RelayUnit() {} -}; - -struct RelayDictState -{ - QString name; //< dict 标签 - int value; //< 值 - QString displayName; -}; -struct RelaySetting -{ - QString tagName; - QString desc; - int groupNo; - QString rtuTag; - int rtuNo; - int dotNo; - int seqNo; - int subSystem; - int nAppId; - int locId; - QString devTag; - float value; - int valueType; - int unitId; - QString valueText; - float valueRatio; - float valueAdded; - float valueMax; - float valueMin; - float valueDefault; - float valueVerify; - QString exInfo; - int domainId; - QString locDesc; - QString keyIdTag; - RelaySetting() { - value = -1; - } -}; - -struct RelayCmdReply -{ - QString rtu_tag; - int isSuccess; - QString resultStr; - int dev_id; - int cur_group; - QList dotList; - QList valueList; - RelayCmdReply() {} -}; - - -#endif // CRELAYSETTINGCOMMON_H +#ifndef CRELAYSETTINGCOMMON_H +#define CRELAYSETTINGCOMMON_H + +#include + +struct RelayLoc +{ + int id; //< 位置id <主> + QString name; //< 位置标签 + QString desc; //< 位置描述 + int domainId; //< 域id + RelayLoc() {} +}; + +struct RelayRtu +{ + QString name; //< rtu标签 <主> + QString desc; //< rtu描述 + int locId; //< 位置id + int subId; //< 应用id + RelayRtu() {} +}; + +struct RelayDev +{ + int id; //< 设备id + QString name; //< 设备标签 <主> + QString desc; //< 设备描述 + int locId; //< 位置id + int subId; //< 应用id + QString rtuName; //< rtu标签 + RelayDev() {} +}; + +struct RelayUnit +{ + int id; //< 单位id + QString name; //< 单位标签 + RelayUnit() {} +}; + +struct RelayDictState +{ + QString name; //< dict 标签 + int value; //< 值 + QString displayName; +}; +struct RelaySetting +{ + QString tagName; + QString desc; + int groupNo; + QString rtuTag; + int rtuNo; + int dotNo; + int seqNo; + int subSystem; + int nAppId; + int locId; + QString devTag; + float value; + int valueType; + int unitId; + QString valueText; + float valueRatio; + float valueAdded; + float valueMax; + float valueMin; + float valueDefault; + float valueVerify; + QString exInfo; + int domainId; + QString locDesc; + QString keyIdTag; + RelaySetting() { + value = -1; + } +}; + +struct RelayCmdReply +{ + QString rtu_tag; + int isSuccess; + QString resultStr; + int dev_id; + int cur_group; + QList dotList; + QList valueList; + RelayCmdReply() {} +}; + + +#endif // CRELAYSETTINGCOMMON_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingDelegate.cpp b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingDelegate.cpp index 94a08a4d..65a33b83 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingDelegate.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingDelegate.cpp @@ -1,92 +1,92 @@ -#include "CRelaySettingDelegate.h" -#include -#include - - -CRelaySettingDelegate::CRelaySettingDelegate(QObject *parent):QStyledItemDelegate(parent) -{ - m_dictMap = CDbMng::instance()->getDictInfo(); -} - -CRelaySettingDelegate::~CRelaySettingDelegate() -{ - m_dictMap.clear(); -} - -void CRelaySettingDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QStyledItemDelegate::paint(painter,option,index); -} - -QSize CRelaySettingDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - return QStyledItemDelegate::sizeHint(option,index); -} - -QWidget *CRelaySettingDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - int type = index.data(Qt::UserRole+10).toInt(); - if(index.isValid() &&type == 2 && (index.column() == COMBOXCOL1 || index.column() == COMBOXCOL2 || index.column() == COMBOXCOL3)) - { - QComboBox *edit = new QComboBox(parent); - edit->setView(new QListView()); - if(index.column() != COMBOXCOL2) - { - edit->setEnabled(false); - }else - { - edit->setEnabled(true); - } - - edit->installEventFilter(const_cast(this)); - return edit; - }else - { - return QStyledItemDelegate::createEditor(parent,option,index); - } -} - -void CRelaySettingDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - int type = index.data(Qt::UserRole+10).toInt(); - QString text = index.data(Qt::UserRole+11).toString(); - - if(index.isValid()&& type == 2 && (index.column() == COMBOXCOL1 || index.column() == COMBOXCOL2 || index.column() == COMBOXCOL3)) - { - QString value = index.model()->data(index,Qt::DisplayRole).toString(); - QComboBox *combox = static_cast(editor); - QMap >::const_iterator it = m_dictMap.find(text); - if (it != m_dictMap.end()) { - QList dictList = it.value(); - for(int index(0);indexaddItem(dictList.at(index).displayName,dictList.at(index).value); - } - } - if(value.isEmpty()) - { - combox->setCurrentIndex(0); - }else - { - combox->setCurrentText(value); - } - - }else - { - QStyledItemDelegate::setEditorData(editor,index); - } -} - -void CRelaySettingDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - int type = index.data(Qt::UserRole+10).toInt(); - if(index.isValid() && type == 2 &&(index.column() == COMBOXCOL1 || index.column() == COMBOXCOL2 || index.column() == COMBOXCOL3)) - { - QComboBox *combox = static_cast (editor); - model->setData(index,combox->currentText(),Qt::EditRole); - model->setData(index,combox->currentData(Qt::UserRole),Qt::UserRole); - }else - { - QStyledItemDelegate::setModelData(editor,model,index); - } -} +#include "CRelaySettingDelegate.h" +#include +#include + + +CRelaySettingDelegate::CRelaySettingDelegate(QObject *parent):QStyledItemDelegate(parent) +{ + m_dictMap = CDbMng::instance()->getDictInfo(); +} + +CRelaySettingDelegate::~CRelaySettingDelegate() +{ + m_dictMap.clear(); +} + +void CRelaySettingDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter,option,index); +} + +QSize CRelaySettingDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return QStyledItemDelegate::sizeHint(option,index); +} + +QWidget *CRelaySettingDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + int type = index.data(Qt::UserRole+10).toInt(); + if(index.isValid() &&type == 2 && (index.column() == COMBOXCOL1 || index.column() == COMBOXCOL2 || index.column() == COMBOXCOL3)) + { + QComboBox *edit = new QComboBox(parent); + edit->setView(new QListView()); + if(index.column() != COMBOXCOL2) + { + edit->setEnabled(false); + }else + { + edit->setEnabled(true); + } + + edit->installEventFilter(const_cast(this)); + return edit; + }else + { + return QStyledItemDelegate::createEditor(parent,option,index); + } +} + +void CRelaySettingDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + int type = index.data(Qt::UserRole+10).toInt(); + QString text = index.data(Qt::UserRole+11).toString(); + + if(index.isValid()&& type == 2 && (index.column() == COMBOXCOL1 || index.column() == COMBOXCOL2 || index.column() == COMBOXCOL3)) + { + QString value = index.model()->data(index,Qt::DisplayRole).toString(); + QComboBox *combox = static_cast(editor); + QMap >::const_iterator it = m_dictMap.find(text); + if (it != m_dictMap.end()) { + QList dictList = it.value(); + for(int index(0);indexaddItem(dictList.at(index).displayName,dictList.at(index).value); + } + } + if(value.isEmpty()) + { + combox->setCurrentIndex(0); + }else + { + combox->setCurrentText(value); + } + + }else + { + QStyledItemDelegate::setEditorData(editor,index); + } +} + +void CRelaySettingDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + int type = index.data(Qt::UserRole+10).toInt(); + if(index.isValid() && type == 2 &&(index.column() == COMBOXCOL1 || index.column() == COMBOXCOL2 || index.column() == COMBOXCOL3)) + { + QComboBox *combox = static_cast (editor); + model->setData(index,combox->currentText(),Qt::EditRole); + model->setData(index,combox->currentData(Qt::UserRole),Qt::UserRole); + }else + { + QStyledItemDelegate::setModelData(editor,model,index); + } +} diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingDelegate.h b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingDelegate.h index 240f31d6..4e8c2755 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingDelegate.h +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingDelegate.h @@ -1,38 +1,38 @@ -#ifndef CRELAYSETTINGDELEGATE_H -#define CRELAYSETTINGDELEGATE_H - -#include -#include -#include -#include -#include -#include "CDbMng.h" - -#define COMBOXCOL1 3 -#define COMBOXCOL2 4 -#define COMBOXCOL3 5 -class CRelaySettingDelegate : public QStyledItemDelegate -{ - Q_OBJECT - -public: - CRelaySettingDelegate(QObject *parent = Q_NULLPTR); - ~CRelaySettingDelegate(); - -public: - void paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const ; - - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; - - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; - - void setEditorData(QWidget *editor, const QModelIndex &index) const ; - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const ; - -private: - QMap > m_dictMap; -}; - -#endif // CRELAYSETTINGDELEGATE_H +#ifndef CRELAYSETTINGDELEGATE_H +#define CRELAYSETTINGDELEGATE_H + +#include +#include +#include +#include +#include +#include "CDbMng.h" + +#define COMBOXCOL1 3 +#define COMBOXCOL2 4 +#define COMBOXCOL3 5 +class CRelaySettingDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + CRelaySettingDelegate(QObject *parent = Q_NULLPTR); + ~CRelaySettingDelegate(); + +public: + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const ; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const ; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const ; + +private: + QMap > m_dictMap; +}; + +#endif // CRELAYSETTINGDELEGATE_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.cpp b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.cpp index c7231efa..0013ac58 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.cpp @@ -1,474 +1,474 @@ -#include "CRelaySettingMsgMng.h" -#include "pub_logger_api/logger.h" -#include -#include "CDbMng.h" - -int CUST_CMD_OUT_TIME = 35; - -CRelaySettingMsgMng::CRelaySettingMsgMng(QObject *parent) : QObject(parent), - m_communicator(Q_NULLPTR), - m_timer(Q_NULLPTR) -{ - init(); -} - -CRelaySettingMsgMng::~CRelaySettingMsgMng() -{ - if(m_timer) - { - m_timer->stop(); - delete m_timer; - } - m_timer = Q_NULLPTR; - - delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); - - if(m_communicator != Q_NULLPTR) - { - delete m_communicator; - } - m_communicator = Q_NULLPTR; -} - -void CRelaySettingMsgMng::slotcmd(const QList &keyList, const QList &valueList, const RelaySetting &relaySetting, const QString &cmd) -{ -// { -// /** -// * @brief test 仅测试代码使用 -// */ -// test(cmd,1); -// return ; -// } - addSub(); - m_requestCmd = cmd; - kbd_net::CMbMessage msg; - msg.setMsgType(MT_OPT_COMMON_DOWN); - msg.setSubject(relaySetting.nAppId, CH_HMI_TO_OPT_OPTCMD_DOWN); - COptCustCtrlRequest cOptCustCtrlRequest; - SOptCustCtrlRequest sOptCustCtrlRequest; - sOptCustCtrlRequest.stHead = createReqHead(relaySetting); - sOptCustCtrlRequest.strKeyIdTag = relaySetting.keyIdTag.toStdString(); - sOptCustCtrlRequest.strRtuTag = relaySetting.rtuTag.toStdString(); - sOptCustCtrlRequest.vecOptCustCtrlQueue = createCtrlQueue(keyList,valueList); - - std::string content = cOptCustCtrlRequest.generate(sOptCustCtrlRequest); - msg.setData(content); - if(!m_communicator->sendMsgToDomain(msg, relaySetting.domainId)) - { - emit sendError(); - delSub(); - return ; - }else - { - m_timer->start(500); - } - - m_curRtu = sOptCustCtrlRequest.strRtuTag; - m_strHostName = sOptCustCtrlRequest.stHead.strHostName; - m_strInstName = sOptCustCtrlRequest.stHead.strInstName; - m_nOptTime = sOptCustCtrlRequest.stHead.nOptTime; -} - -void CRelaySettingMsgMng::recvMessage() -{ - kbd_net::CMbMessage msg; - if(m_communicator->recvMsg(msg, 50)) - { - if(msg.getMsgType() != MT_OPT_COMMON_UP) - { - return; - } - - COptCustCtrlReply cOptCustCtrlReply; - SOptCustCtrlReply sOptCustCtrlReply; - std::string str((const char*)msg.getDataPtr(), msg.getDataSize()); - cOptCustCtrlReply.parse(str, sOptCustCtrlReply); - - if(parseMsg(sOptCustCtrlReply)) - { - m_timer->stop(); - delSub(); - return ; - } - } - int64 nTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - if(nTime -m_nOptTime > CUST_CMD_OUT_TIME*1000) - { - m_timer->stop(); - delSub(); - emit recvOuttime(); - } -} - -void CRelaySettingMsgMng::init() -{ - if(!createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - } - - m_permMng = getPermMngInstance("base"); - if(m_permMng != NULL) - { - if(m_permMng->PermDllInit() != PERM_NORMAL) - { - LOGERROR("权限接口初始化失败!"); - } - } - initMsg(); - if(!addSub(0, CH_OPT_TO_HMI_OPTCMD_UP)) - { - return; - } - m_timer = new QTimer(this); - connect(m_timer, SIGNAL(timeout()), this, SLOT(recvMessage())); - -} - -void CRelaySettingMsgMng::initMsg() -{ - if(m_communicator == Q_NULLPTR) - { - m_communicator = new kbd_net::CMbCommunicator(); - } -} - -void CRelaySettingMsgMng::closeMsg() -{ - if(m_communicator != NULL) - { - delete m_communicator; - } - m_communicator = NULL; -} - -bool CRelaySettingMsgMng::addSub(int appID, int channel) -{ - if(m_communicator) - { - m_communicator->addSub(appID, channel); - } - return true; -} - -bool CRelaySettingMsgMng::delSub(int appID, int channel) -{ - if(m_communicator) - { - m_communicator->delSub(appID, channel); - } - kbd_net::CMbMessage msg; - while (m_communicator->recvMsg(msg, 0)) { - - } - return true; -} - -bool CRelaySettingMsgMng::addSub() -{ - return addSub(0, CH_OPT_TO_HMI_OPTCMD_UP); -} - -bool CRelaySettingMsgMng::delSub() -{ - return delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); -} - -SOptReqHead CRelaySettingMsgMng::createReqHead(const RelaySetting &relaySetting) -{ - SOptReqHead head; - SNodeInfo nodeInfo; - int userID; - int usergID; - int level; - int loginSec; - std::string instanceName; - - m_ptrSysInfo->getLocalNodeInfo(nodeInfo); - if(m_permMng) - { - m_permMng->CurUser(userID, usergID, level, loginSec, instanceName); - } - - head.strSrcTag = "hmi"; - head.nSrcDomainID = nodeInfo.nDomainId; - head.nDstDomainID = relaySetting.domainId; - head.nAppID = relaySetting.nAppId; - head.strHostName = nodeInfo.strName; - head.strInstName = instanceName; - head.strCommName = m_communicator->getName(); - head.nUserID = userID; - head.nUserGroupID = usergID; - head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - - return head; -} - -std::vector CRelaySettingMsgMng::createCtrlQueue(const QList &keyList,const QList &valueList) -{ - std::vector queueVec; - for(int index(0);index::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - - if(iter->strKeyName == "cmd_type") - { - cmdType = iter->strKeyValue; - break; - } - ++iter; - } - if(QString::fromStdString(cmdType) != m_requestCmd) - { - return false; - } - if(cmdType == "const_value_read") - { - return parseReadMsg(sOptCustCtrlReply); - }else if(cmdType == "const_value_edit") - { - return parseEditMsg(sOptCustCtrlReply); - }else if(cmdType == "const_value_affirm") - { - return parseAffirmMsg(sOptCustCtrlReply); - }else if(cmdType == "const_group_edit") - { - return parseGEditMsg(sOptCustCtrlReply); - }else - { - return false; - } -} - -bool CRelaySettingMsgMng::checkMsg(std::string strHostName, std::string strInstName, int64 nOptTime) -{ - if(m_strHostName != strHostName) - { - return false; - } - if(m_strInstName != strInstName) - { - return false; - } - if(m_nOptTime != nOptTime) - { - return false; - } - return true; -} - -bool CRelaySettingMsgMng::parseReadMsg(const SOptCustCtrlReply &sOptCustCtrlReply) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "dev_id") - { - relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - else if(iter->strKeyName == "cur_value") - { - relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); - } - ++iter; - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,m_requestCmd); - return true; -} - -bool CRelaySettingMsgMng::parseEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "dev_id") - { - relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - else if(iter->strKeyName == "ack_value")//ack_value cur_value - { - relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); - } - - - - ++iter; - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,m_requestCmd); - return true; -} - -bool CRelaySettingMsgMng::parseAffirmMsg(const SOptCustCtrlReply &sOptCustCtrlReply) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "dev_id") - { - relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - else if(iter->strKeyName == "cur_value") - { - relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); - } - ++iter; - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,m_requestCmd); - return true; -} - -bool CRelaySettingMsgMng::parseGEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "dev_id") - { - relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - ++iter; - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,m_requestCmd); - return true; -} - -void CRelaySettingMsgMng::test(const QString &cmd,int isSuccess) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = isSuccess; - if(isSuccess == 1) - { - relayCmdReply.resultStr = "成功"; - }else - { - relayCmdReply.resultStr = "失败"; - } - if(cmd == "const_value_read") - { - readTest(relayCmdReply,cmd); - }else if(cmd == "const_value_edit") - { - editTest(relayCmdReply,cmd); - }else if(cmd == "const_value_affirm") - { - affirmTest(relayCmdReply,cmd); - }else if(cmd == "const_group_edit") - { - editGroupTest(relayCmdReply,cmd); - } -} - -void CRelaySettingMsgMng::readTest(RelayCmdReply &relayCmdReply, const QString &cmd) -{ - relayCmdReply.dev_id = 0; - relayCmdReply.cur_group = 0; - for(int index(0);index<3;index++) - { - relayCmdReply.dotList.append(index); - relayCmdReply.valueList.append(0); - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,cmd); -} - -void CRelaySettingMsgMng::editTest(RelayCmdReply &relayCmdReply, const QString &cmd) -{ - relayCmdReply.dev_id = 0; - relayCmdReply.cur_group = 0; - for(int index(0);index<3;index++) - { - relayCmdReply.dotList.append(index); - relayCmdReply.valueList.append(1); - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,cmd); -} - -void CRelaySettingMsgMng::affirmTest(RelayCmdReply &relayCmdReply, const QString &cmd) -{ - relayCmdReply.dev_id = 0; - relayCmdReply.cur_group = 0; - for(int index(0);index<3;index++) - { - relayCmdReply.dotList.append(index); - relayCmdReply.valueList.append(1); - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,cmd); -} - -void CRelaySettingMsgMng::editGroupTest(RelayCmdReply &relayCmdReply, const QString &cmd) -{ - relayCmdReply.dev_id = 0; - relayCmdReply.cur_group = 1; - - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,cmd); -} +#include "CRelaySettingMsgMng.h" +#include "pub_logger_api/logger.h" +#include +#include "CDbMng.h" + +int CUST_CMD_OUT_TIME = 35; + +CRelaySettingMsgMng::CRelaySettingMsgMng(QObject *parent) : QObject(parent), + m_communicator(Q_NULLPTR), + m_timer(Q_NULLPTR) +{ + init(); +} + +CRelaySettingMsgMng::~CRelaySettingMsgMng() +{ + if(m_timer) + { + m_timer->stop(); + delete m_timer; + } + m_timer = Q_NULLPTR; + + delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); + + if(m_communicator != Q_NULLPTR) + { + delete m_communicator; + } + m_communicator = Q_NULLPTR; +} + +void CRelaySettingMsgMng::slotcmd(const QList &keyList, const QList &valueList, const RelaySetting &relaySetting, const QString &cmd) +{ +// { +// /** +// * @brief test 仅测试代码使用 +// */ +// test(cmd,1); +// return ; +// } + addSub(); + m_requestCmd = cmd; + kbd_net::CMbMessage msg; + msg.setMsgType(MT_OPT_COMMON_DOWN); + msg.setSubject(relaySetting.nAppId, CH_HMI_TO_OPT_OPTCMD_DOWN); + COptCustCtrlRequest cOptCustCtrlRequest; + SOptCustCtrlRequest sOptCustCtrlRequest; + sOptCustCtrlRequest.stHead = createReqHead(relaySetting); + sOptCustCtrlRequest.strKeyIdTag = relaySetting.keyIdTag.toStdString(); + sOptCustCtrlRequest.strRtuTag = relaySetting.rtuTag.toStdString(); + sOptCustCtrlRequest.vecOptCustCtrlQueue = createCtrlQueue(keyList,valueList); + + std::string content = cOptCustCtrlRequest.generate(sOptCustCtrlRequest); + msg.setData(content); + if(!m_communicator->sendMsgToDomain(msg, relaySetting.domainId)) + { + emit sendError(); + delSub(); + return ; + }else + { + m_timer->start(500); + } + + m_curRtu = sOptCustCtrlRequest.strRtuTag; + m_strHostName = sOptCustCtrlRequest.stHead.strHostName; + m_strInstName = sOptCustCtrlRequest.stHead.strInstName; + m_nOptTime = sOptCustCtrlRequest.stHead.nOptTime; +} + +void CRelaySettingMsgMng::recvMessage() +{ + kbd_net::CMbMessage msg; + if(m_communicator->recvMsg(msg, 50)) + { + if(msg.getMsgType() != MT_OPT_COMMON_UP) + { + return; + } + + COptCustCtrlReply cOptCustCtrlReply; + SOptCustCtrlReply sOptCustCtrlReply; + std::string str((const char*)msg.getDataPtr(), msg.getDataSize()); + cOptCustCtrlReply.parse(str, sOptCustCtrlReply); + + if(parseMsg(sOptCustCtrlReply)) + { + m_timer->stop(); + delSub(); + return ; + } + } + int64 nTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + if(nTime -m_nOptTime > CUST_CMD_OUT_TIME*1000) + { + m_timer->stop(); + delSub(); + emit recvOuttime(); + } +} + +void CRelaySettingMsgMng::init() +{ + if(!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + + m_permMng = getPermMngInstance("base"); + if(m_permMng != NULL) + { + if(m_permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + } + } + initMsg(); + if(!addSub(0, CH_OPT_TO_HMI_OPTCMD_UP)) + { + return; + } + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(recvMessage())); + +} + +void CRelaySettingMsgMng::initMsg() +{ + if(m_communicator == Q_NULLPTR) + { + m_communicator = new kbd_net::CMbCommunicator(); + } +} + +void CRelaySettingMsgMng::closeMsg() +{ + if(m_communicator != NULL) + { + delete m_communicator; + } + m_communicator = NULL; +} + +bool CRelaySettingMsgMng::addSub(int appID, int channel) +{ + if(m_communicator) + { + m_communicator->addSub(appID, channel); + } + return true; +} + +bool CRelaySettingMsgMng::delSub(int appID, int channel) +{ + if(m_communicator) + { + m_communicator->delSub(appID, channel); + } + kbd_net::CMbMessage msg; + while (m_communicator->recvMsg(msg, 0)) { + + } + return true; +} + +bool CRelaySettingMsgMng::addSub() +{ + return addSub(0, CH_OPT_TO_HMI_OPTCMD_UP); +} + +bool CRelaySettingMsgMng::delSub() +{ + return delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); +} + +SOptReqHead CRelaySettingMsgMng::createReqHead(const RelaySetting &relaySetting) +{ + SOptReqHead head; + SNodeInfo nodeInfo; + int userID; + int usergID; + int level; + int loginSec; + std::string instanceName; + + m_ptrSysInfo->getLocalNodeInfo(nodeInfo); + if(m_permMng) + { + m_permMng->CurUser(userID, usergID, level, loginSec, instanceName); + } + + head.strSrcTag = "hmi"; + head.nSrcDomainID = nodeInfo.nDomainId; + head.nDstDomainID = relaySetting.domainId; + head.nAppID = relaySetting.nAppId; + head.strHostName = nodeInfo.strName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = userID; + head.nUserGroupID = usergID; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + return head; +} + +std::vector CRelaySettingMsgMng::createCtrlQueue(const QList &keyList,const QList &valueList) +{ + std::vector queueVec; + for(int index(0);index::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + + if(iter->strKeyName == "cmd_type") + { + cmdType = iter->strKeyValue; + break; + } + ++iter; + } + if(QString::fromStdString(cmdType) != m_requestCmd) + { + return false; + } + if(cmdType == "const_value_read") + { + return parseReadMsg(sOptCustCtrlReply); + }else if(cmdType == "const_value_edit") + { + return parseEditMsg(sOptCustCtrlReply); + }else if(cmdType == "const_value_affirm") + { + return parseAffirmMsg(sOptCustCtrlReply); + }else if(cmdType == "const_group_edit") + { + return parseGEditMsg(sOptCustCtrlReply); + }else + { + return false; + } +} + +bool CRelaySettingMsgMng::checkMsg(std::string strHostName, std::string strInstName, int64 nOptTime) +{ + if(m_strHostName != strHostName) + { + return false; + } + if(m_strInstName != strInstName) + { + return false; + } + if(m_nOptTime != nOptTime) + { + return false; + } + return true; +} + +bool CRelaySettingMsgMng::parseReadMsg(const SOptCustCtrlReply &sOptCustCtrlReply) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "dev_id") + { + relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + else if(iter->strKeyName == "cur_value") + { + relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); + } + ++iter; + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,m_requestCmd); + return true; +} + +bool CRelaySettingMsgMng::parseEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "dev_id") + { + relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + else if(iter->strKeyName == "ack_value")//ack_value cur_value + { + relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); + } + + + + ++iter; + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,m_requestCmd); + return true; +} + +bool CRelaySettingMsgMng::parseAffirmMsg(const SOptCustCtrlReply &sOptCustCtrlReply) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "dev_id") + { + relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + else if(iter->strKeyName == "cur_value") + { + relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); + } + ++iter; + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,m_requestCmd); + return true; +} + +bool CRelaySettingMsgMng::parseGEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "dev_id") + { + relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + ++iter; + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,m_requestCmd); + return true; +} + +void CRelaySettingMsgMng::test(const QString &cmd,int isSuccess) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = isSuccess; + if(isSuccess == 1) + { + relayCmdReply.resultStr = "成功"; + }else + { + relayCmdReply.resultStr = "失败"; + } + if(cmd == "const_value_read") + { + readTest(relayCmdReply,cmd); + }else if(cmd == "const_value_edit") + { + editTest(relayCmdReply,cmd); + }else if(cmd == "const_value_affirm") + { + affirmTest(relayCmdReply,cmd); + }else if(cmd == "const_group_edit") + { + editGroupTest(relayCmdReply,cmd); + } +} + +void CRelaySettingMsgMng::readTest(RelayCmdReply &relayCmdReply, const QString &cmd) +{ + relayCmdReply.dev_id = 0; + relayCmdReply.cur_group = 0; + for(int index(0);index<3;index++) + { + relayCmdReply.dotList.append(index); + relayCmdReply.valueList.append(0); + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,cmd); +} + +void CRelaySettingMsgMng::editTest(RelayCmdReply &relayCmdReply, const QString &cmd) +{ + relayCmdReply.dev_id = 0; + relayCmdReply.cur_group = 0; + for(int index(0);index<3;index++) + { + relayCmdReply.dotList.append(index); + relayCmdReply.valueList.append(1); + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,cmd); +} + +void CRelaySettingMsgMng::affirmTest(RelayCmdReply &relayCmdReply, const QString &cmd) +{ + relayCmdReply.dev_id = 0; + relayCmdReply.cur_group = 0; + for(int index(0);index<3;index++) + { + relayCmdReply.dotList.append(index); + relayCmdReply.valueList.append(1); + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,cmd); +} + +void CRelaySettingMsgMng::editGroupTest(RelayCmdReply &relayCmdReply, const QString &cmd) +{ + relayCmdReply.dev_id = 0; + relayCmdReply.cur_group = 1; + + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,cmd); +} diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.h b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.h index 5f1c78b8..97dca3e5 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.h +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.h @@ -1,82 +1,82 @@ -#ifndef CRELAYSETTINGMSGMNG_H -#define CRELAYSETTINGMSGMNG_H - -#include -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "service/operate_server_api/JsonMessageStruct.h" -#include "service/operate_server_api/JsonOptCommand.h" -#include "common/MessageChannel.h" -#include -#include "CRelaySettingCommon.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" - -using namespace kbd_public; -using namespace kbd_service; - -class CRelaySettingMsgMng : public QObject -{ - Q_OBJECT -public: - explicit CRelaySettingMsgMng(QObject *parent = nullptr); - virtual ~CRelaySettingMsgMng(); -signals: - - void recvOuttime(); - - void dataChanged(const RelayCmdReply &reply,const QString &cmd); - - void sendError(); - -public slots: - void slotcmd(const QList &keyList, const QList &valueList, const RelaySetting &relaySetting,const QString & cmd); - void recvMessage(); - -private: - void init(); - void initMsg(); - void closeMsg(); - - bool addSub(int appID, int channel); - bool delSub(int appID, int channel); - - bool addSub(); - bool delSub(); - SOptReqHead createReqHead(const RelaySetting &relaySetting); - std::vector createCtrlQueue(const QList &keyList, const QList &valueList); - - bool parseMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - bool checkMsg(std::string strHostName, std::string strInstName, int64 nOptTime); - - bool parseReadMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - bool parseEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - bool parseAffirmMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - bool parseGEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - void test(const QString & cmd, int isSuccess); - - void readTest(RelayCmdReply &relayCmdReply,const QString &cmd); - void editTest(RelayCmdReply &relayCmdReply,const QString &cmd); - void affirmTest(RelayCmdReply &relayCmdReply,const QString &cmd); - void editGroupTest(RelayCmdReply &relayCmdReply,const QString &cmd); -private: - kbd_net::CMbCommunicator *m_communicator; - QTimer *m_timer; - - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; - CPermMngApiPtr m_permMng; - - std::string m_curRtu; - std::string m_strHostName; - std::string m_strInstName; - int64 m_nOptTime; - - QString m_requestCmd; -}; - -#endif // CRELAYSETTINGMSGMNG_H +#ifndef CRELAYSETTINGMSGMNG_H +#define CRELAYSETTINGMSGMNG_H + +#include +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "common/MessageChannel.h" +#include +#include "CRelaySettingCommon.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" + +using namespace kbd_public; +using namespace kbd_service; + +class CRelaySettingMsgMng : public QObject +{ + Q_OBJECT +public: + explicit CRelaySettingMsgMng(QObject *parent = nullptr); + virtual ~CRelaySettingMsgMng(); +signals: + + void recvOuttime(); + + void dataChanged(const RelayCmdReply &reply,const QString &cmd); + + void sendError(); + +public slots: + void slotcmd(const QList &keyList, const QList &valueList, const RelaySetting &relaySetting,const QString & cmd); + void recvMessage(); + +private: + void init(); + void initMsg(); + void closeMsg(); + + bool addSub(int appID, int channel); + bool delSub(int appID, int channel); + + bool addSub(); + bool delSub(); + SOptReqHead createReqHead(const RelaySetting &relaySetting); + std::vector createCtrlQueue(const QList &keyList, const QList &valueList); + + bool parseMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + bool checkMsg(std::string strHostName, std::string strInstName, int64 nOptTime); + + bool parseReadMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + bool parseEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + bool parseAffirmMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + bool parseGEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + void test(const QString & cmd, int isSuccess); + + void readTest(RelayCmdReply &relayCmdReply,const QString &cmd); + void editTest(RelayCmdReply &relayCmdReply,const QString &cmd); + void affirmTest(RelayCmdReply &relayCmdReply,const QString &cmd); + void editGroupTest(RelayCmdReply &relayCmdReply,const QString &cmd); +private: + kbd_net::CMbCommunicator *m_communicator; + QTimer *m_timer; + + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; + CPermMngApiPtr m_permMng; + + std::string m_curRtu; + std::string m_strHostName; + std::string m_strInstName; + int64 m_nOptTime; + + QString m_requestCmd; +}; + +#endif // CRELAYSETTINGMSGMNG_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.cpp b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.cpp index 7d8e86e4..d55c7994 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CRelaySettingPluginWidget.h" -#include "CRelaySettingWidget.h" -#include - -CRelaySettingPluginWidget::CRelaySettingPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CRelaySettingPluginWidget::~CRelaySettingPluginWidget() -{ - -} - -bool CRelaySettingPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CRelaySettingWidget *pWidget = new CRelaySettingWidget(editMode, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CRelaySettingPluginWidget::release() -{ - -} +#include "CRelaySettingPluginWidget.h" +#include "CRelaySettingWidget.h" +#include + +CRelaySettingPluginWidget::CRelaySettingPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CRelaySettingPluginWidget::~CRelaySettingPluginWidget() +{ + +} + +bool CRelaySettingPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CRelaySettingWidget *pWidget = new CRelaySettingWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CRelaySettingPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.h b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.h index 48b99129..793d1a75 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.h +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CRELAYSETTINGPLUGINWIDGET_H -#define CRELAYSETTINGPLUGINWIDGET_H - - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CRelaySettingPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CRelaySettingPluginWidget(QObject *parent = 0); - ~CRelaySettingPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CRELAYSETTINGPLUGINWIDGET_H +#ifndef CRELAYSETTINGPLUGINWIDGET_H +#define CRELAYSETTINGPLUGINWIDGET_H + + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CRelaySettingPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CRelaySettingPluginWidget(QObject *parent = 0); + ~CRelaySettingPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CRELAYSETTINGPLUGINWIDGET_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.cpp b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.cpp index 35b3bb4b..af7eaa29 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.cpp @@ -1,1696 +1,1696 @@ -/** -*@file ConstWidget -*@brief 保护定值插件 -*@author jxd -*@date 2021-05-12 -*/ -#include "CRelaySettingWidget.h" -#include "ui_CRelaySettingWidget.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include "pub_logger_api/logger.h" -#include "CDbMng.h" -#include -#include "CRelaySettingDelegate.h" - - - -CRelaySettingWidget::CRelaySettingWidget(bool editMode, QWidget *parent) : - QWidget(parent), - ui(new Ui::CRelaySettingWidget), - m_ptrSysInfo(Q_NULLPTR), - m_msgMng(Q_NULLPTR), - m_pWork(Q_NULLPTR),m_ModbusChannlIndex(-1) -{ - ui->setupUi(this); - - qRegisterMetaType("RelaySetting"); - qRegisterMetaType("RelayCmdReply"); - qRegisterMetaType >("QList"); - - m_clickDev.clear(); - initStyleSheet(); - ui->splitter->setSizes(QList()<<220<<1200); - if(!editMode) - { - initialize(); - } -} - -CRelaySettingWidget::~CRelaySettingWidget() -{ - if(m_msgMng) - { - delete m_msgMng; - } - m_msgMng = Q_NULLPTR; - - CDbMng::instance()->destory(); - - if(m_workThread.isRunning()) - { - m_workThread.quit(); - m_workThread.wait(); - } - - delete ui; -} - -void CRelaySettingWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - -} - -void CRelaySettingWidget::initialize() -{ - m_enableList<getLocalNodeInfo(m_nodeInfo) == kbdSuccess) - { - LOGINFO("获取节点信息成功!"); - }else - { - LOGINFO("获取节点信息失败!"); - } - //3. - m_permMng = getPermMngInstance("base"); - if(m_permMng != NULL) - { - if(m_permMng->PermDllInit() != PERM_NORMAL) - { - LOGERROR("权限接口初始化失败!"); - } - } - - //4.获取位置 - loadLoc(); - //5.获取rtu - loadRtu(); - //6.获取前置设备 - loadDev(); - //7.获取位置rtu设备 - loadLocRtuDev(); - //8.获取unit - loadUnit(); - //9.获取dict - loadDict(); - //10.获取保护定值 - loadSetting(); - - //获取modbus - loadModbusConfig(); - - initModbusData(); - - initView(); - initConn(); - - -} - -//loadModbus -void CRelaySettingWidget::loadModbusConfig() -{ - loadModbusChanl(); - loadModbusGroup(); -} - -void CRelaySettingWidget::initModbusData() -{ - if(!m_pWork) - { - m_pWork = new CWorker(); - } - m_pWork->moveToThread(&m_workThread); - - m_workThread.start(); -} - -void CRelaySettingWidget::loadModbusChanl() -{ - m_locChanlList.clear(); - CRelayFile relayFile; - chanlList = relayFile.getChanlList(); - - for(int i(0);i > &pair= m_locChanlList[j]; - if(pair.first == relayChanl.loc) - { - isEixt = true; - pair.second.append(relayChanl); - break; - } - } - if(!isEixt) - { - QList relayList; - relayList.append(relayChanl); - m_locChanlList.append(qMakePair >(relayChanl.loc,relayList)); - } - } - - //获得通道参数 - -} - -void CRelaySettingWidget::loadModbusGroup() -{ - m_groupList.clear(); - CRelayFile relayFile; - m_groupList = relayFile.getGroupList(); -} -// - -void CRelaySettingWidget::loadLoc() -{ - m_locMap = CDbMng::instance()->getLocInfo(); -} - -void CRelaySettingWidget::loadRtu() -{ - m_rtuMap = CDbMng::instance()->getRtuInfo(); -} - -void CRelaySettingWidget::loadDev() -{ - m_devMap = CDbMng::instance()->getDevInfo(); -} - -void CRelaySettingWidget::loadLocRtuDev() -{ - m_locRtuDevMap = CDbMng::instance()->getLocRtuDevInfo(); -} - -void CRelaySettingWidget::loadUnit() -{ - m_unitMap = CDbMng::instance()->getUnitInfo(); -} - -void CRelaySettingWidget::loadDict() -{ - m_dictMap = CDbMng::instance()->getDictInfo(); -} - -void CRelaySettingWidget::loadSetting() -{ - m_setList = CDbMng::instance()->getSetting(); -} - - -/*void CRelaySettingWidget::insertToTable(const SRelayData &relayData) - -{ - int rowCount = ui->tableWidget->rowCount(); - ui->tableWidget->insertRow(rowCount); - QTableWidgetItem *item = new QTableWidgetItem(); - item->setText(relayData.chanName); - ui->tableWidget->setItem(rowCount,0,item); - - item = new QTableWidgetItem(); - item->setText(relayData.name); - ui->tableWidget->setItem(rowCount,1,item); - - item = new QTableWidgetItem(); - item->setText(QString::number(relayData.value)); - ui->tableWidget->setItem(rowCount,2,item); -}*/ - -void CRelaySettingWidget::slotModbusDataChange(QList relayDataList, bool isFaild, QString error) -{ - - // QMessageBox::warning(this,tr("提示"),"11111111"); - m_enableList.clear(); - m_enableList<tableWidget->setRowCount(0); - // setViewEnable(true); - for(int index(0);indexcomboBox->setView(new QListView()); - initTree(); - initModbusTree(); - - initTable(); - setCtrlBtnEnable(false); -} - -void CRelaySettingWidget::initModbusTree() -{ - ui->treeWidget->setColumnCount(1); - for(int i(0);i > &pair= m_locChanlList[i]; - - QTreeWidgetItem *locItem = new QTreeWidgetItem(ui->treeWidget); - locItem->setText(0,pair.first); - locItem->setData(0,Qt::UserRole,(int)EN_RELAY_TREE_LOC); - ui->treeWidget->addTopLevelItem(locItem); - locItem->setExpanded(true); - - // locItem->setCheckState(0,Qt::Unchecked); - QList &relayChanlList = pair.second; - for(int j(0);jsetCheckState(0,Qt::Unchecked); - chanlItem->setText(0,relayChanl.chanlDesc); - chanlItem->setData(0,Qt::UserRole,(int)EN_RELAY_TREE_CHANL); - chanlItem->setData(0,Qt::UserRole+1,relayChanl.chanlAddr); - chanlItem->setData(0,Qt::UserRole+2,relayChanl.loc); - chanlItem->setData(0,Qt::UserRole+3,relayChanl.ip); - chanlItem->setData(0,Qt::UserRole+4,relayChanl.port); - chanlItem->setData(0,Qt::UserRole+5,relayChanl.index); - - ui->mGroupCb->addItem(relayChanl.chanlDesc,""); - - locItem->addChild(chanlItem); - } - } -} - -void CRelaySettingWidget::initTree() -{ - cleanTree(); - ui->treeWidget->setColumnCount(1); - QMap > >::iterator locIter = m_locRtuDevMap.begin(); - while (locIter != m_locRtuDevMap.end()) - { - - int locId = locIter.key(); - QString locDesc = m_locMap.value(locId).desc; - QTreeWidgetItem *locItem = new QTreeWidgetItem(); - locItem->setText(0,locDesc); - locItem->setData(0,Qt::UserRole,(int)EN_RELAY_LOC); - locItem->setData(0,Qt::UserRole+1,locId); - ui->treeWidget->addTopLevelItem(locItem); - locItem->setExpanded(true); - QMap > & rtuDevMap = locIter.value(); - QMap >::iterator rtuIter = rtuDevMap.begin(); - while (rtuIter != rtuDevMap.end()) { - QString rtuName = rtuIter.key(); - QString rtuDesc = m_rtuMap.value(rtuName).desc; - QTreeWidgetItem *rtuItem = new QTreeWidgetItem(); - rtuItem->setText(0,rtuDesc); - rtuItem->setData(0,Qt::UserRole,(int)EN_RELAY_RTU); - rtuItem->setData(0,Qt::UserRole+1,rtuName); - locItem->addChild(rtuItem); - QMap & devMap = rtuIter.value(); - QMap::iterator devIter = devMap.begin(); - while (devIter != devMap.end()) { - - QString devName = devIter.key(); - if((!mFilterDevs.isEmpty()) && (!mFilterDevs.contains(devName))) - { - devIter++; - continue; - } - - QString devDesc = devIter.value().desc; - QTreeWidgetItem *devItem = new QTreeWidgetItem(); - QString showDesc = devDesc.isEmpty() ? devName : devDesc; - devItem->setText(0,showDesc); - devItem->setData(0,Qt::UserRole,(int)EN_RELAY_DEV); - devItem->setData(0,Qt::UserRole+1,devName); - rtuItem->addChild(devItem); - - ui->mGroupCb->addItem(showDesc,devName); - - devIter++; - } - rtuIter++; - } - locIter++; - } -} - -void CRelaySettingWidget::cleanTree() -{ - ui->mGroupCb->clear(); - for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) - { - QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); - itemChildClear(item); - ui->treeWidget->removeItemWidget(item,0); - } -} - -void CRelaySettingWidget::itemChildClear(QTreeWidgetItem *item) -{ - if(item == Q_NULLPTR) - { - return ; - } - for(int index(item->childCount()-1);index>=0;index--) - { - QTreeWidgetItem *childItem = item->child(index); - itemChildClear(childItem); - item->removeChild(childItem); - } -} - -void CRelaySettingWidget::initConn() -{ - connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CRelaySettingWidget::treeItemClicked); - connect(ui->tableWidget,&QTableWidget::itemDoubleClicked,this,&CRelaySettingWidget::tableItemDoubleClicked); - connect(ui->read,&QPushButton::clicked,this,&CRelaySettingWidget::readBtnClicked); - connect(ui->edit,&QPushButton::clicked,this,&CRelaySettingWidget::editBtnClicked); - connect(ui->confirm,&QPushButton::clicked,this,&CRelaySettingWidget::confirmBtnClicked); - connect(ui->clear,&QPushButton::clicked,this,&CRelaySettingWidget::clearBtnClicked); - connect(ui->change,&QPushButton::clicked,this,&CRelaySettingWidget::changeGDevClicked); - connect(this,&CRelaySettingWidget::sigcmd,m_msgMng,&CRelaySettingMsgMng::slotcmd); - connect(m_msgMng,&CRelaySettingMsgMng::recvOuttime,this,&CRelaySettingWidget::slotRecvOuttime); - connect(m_msgMng,&CRelaySettingMsgMng::dataChanged,this,&CRelaySettingWidget::slotDataChanged); - connect(m_msgMng,&CRelaySettingMsgMng::sendError,this,&CRelaySettingWidget::slotError); - - connect(ui->mGroupCb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int))); - //Modbus - connect(&m_workThread,&QThread::started,m_pWork,&CWorker::init,Qt::QueuedConnection); - connect(&m_workThread,&QThread::finished,m_pWork,&QObject::deleteLater); - - connect(this,&CRelaySettingWidget::sigSearchData,m_pWork,&CWorker::slotSearch,Qt::QueuedConnection); - connect(m_pWork,&CWorker::sigDataChange,this,&CRelaySettingWidget::slotModbusDataChange,Qt::QueuedConnection); -} - -void CRelaySettingWidget::brush() -{ - ui->curGroup->setText(""); - initGroupCmb(); - ui->tableWidget->setRowCount(0); - if(m_clickDev.isEmpty()) - { - return ; - } - for(int index(0);indexcomboBox->clear(); - if (m_clickDev.isEmpty()) - { - return ; - } - RelaySetting relaySetting; - if(getGroupData(relaySetting)) - { - updateGroupCmb(relaySetting); - } -} - -void CRelaySettingWidget::updateGroupCmb(const RelaySetting &relaySetting) -{ - - relaySetting.valueMin; - int min = (int)relaySetting.valueMin; - int max = (int)relaySetting.valueMax; - if(max == 65535 || max == 32767) - { - ui->comboBox->addItem("0",0); - return; - } - - for(int i=min; i 100) - { - break; - } - ui->comboBox->addItem(QString("%1").arg(i),i); - } -} - -void CRelaySettingWidget::insertToTableModbus(RelaySetting relaySetting, int index) -{ - int rowCount = ui->tableWidget->rowCount(); - ui->tableWidget->insertRow(rowCount); - - QTableWidgetItem *item = new QTableWidgetItem(); - item->setText(QString::number(index)); - item->setData(Qt::UserRole,index); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,0,item); - - item = new QTableWidgetItem(); - item->setText(relaySetting.desc); - item->setData(Qt::UserRole,relaySetting.tagName); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,1,item); - - item = new QTableWidgetItem(); - item->setText(QString::number(relaySetting.groupNo)); - item->setData(Qt::UserRole,relaySetting.groupNo); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,2,item); - - item = new QTableWidgetItem(); - item->setText(""); - item->setData(Qt::UserRole,""); - item->setText(QString::number(relaySetting.value)); - item->setData(Qt::UserRole,relaySetting.value); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,3,item); - - item = new QTableWidgetItem(); - item->setText(""); - item->setData(Qt::UserRole,""); - item->setData(Qt::UserRole+10,relaySetting.valueType); - item->setData(Qt::UserRole+11,relaySetting.valueText); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,4,item); - - item = new QTableWidgetItem(); - item->setText(""); - item->setData(Qt::UserRole,""); - item->setData(Qt::UserRole+10,relaySetting.valueType); - item->setData(Qt::UserRole+11,relaySetting.valueText); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,5,item); - - item = new QTableWidgetItem(); - item->setText(QString("%1~%2").arg(QString::number(relaySetting.valueMin)).arg(QString::number(relaySetting.valueMax))); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,6,item); - - item = new QTableWidgetItem(); - item->setText(m_unitMap.value(relaySetting.unitId).name); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,7,item); - - item = new QTableWidgetItem(); - item->setText(QString::number(index)); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,8,item); - - item = new QTableWidgetItem(); - item->setText("0"); - item->setData(Qt::UserRole,0); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,9,item); -} - -void CRelaySettingWidget::insertToTable(RelaySetting relaySetting, int index) -{ - int rowCount = ui->tableWidget->rowCount(); - ui->tableWidget->insertRow(rowCount); - - QTableWidgetItem *item = new QTableWidgetItem(); - item->setText(QString::number(index)); - item->setData(Qt::UserRole,index); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,0,item); - - item = new QTableWidgetItem(); - item->setText(relaySetting.desc); - item->setData(Qt::UserRole,relaySetting.tagName); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,1,item); - - item = new QTableWidgetItem(); - item->setText(QString::number(relaySetting.groupNo)); - item->setData(Qt::UserRole,relaySetting.groupNo); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,2,item); - - item = new QTableWidgetItem(); - item->setText(""); - item->setData(Qt::UserRole,""); - item->setData(Qt::UserRole+10,relaySetting.valueType); - item->setData(Qt::UserRole+11,relaySetting.valueText); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,3,item); - - item = new QTableWidgetItem(); - item->setText(""); - item->setData(Qt::UserRole,""); - item->setData(Qt::UserRole+10,relaySetting.valueType); - item->setData(Qt::UserRole+11,relaySetting.valueText); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,4,item); - - item = new QTableWidgetItem(); - item->setText(""); - item->setData(Qt::UserRole,""); - item->setData(Qt::UserRole+10,relaySetting.valueType); - item->setData(Qt::UserRole+11,relaySetting.valueText); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,5,item); - - item = new QTableWidgetItem(); - item->setText(QString("%1~%2").arg(QString::number(relaySetting.valueMin)).arg(QString::number(relaySetting.valueMax))); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,6,item); - - item = new QTableWidgetItem(); - item->setText(m_unitMap.value(relaySetting.unitId).name); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,7,item); - - item = new QTableWidgetItem(); - item->setText(QString::number(relaySetting.seqNo)); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,8,item); - - item = new QTableWidgetItem(); - item->setText("0"); - item->setData(Qt::UserRole,0); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,9,item); -} - -void CRelaySettingWidget::initTable() -{ - ui->tableWidget->setColumnHidden(2,true); - ui->tableWidget->setColumnHidden(9,true); - ui->tableWidget->setItemDelegateForColumn( 0, new CRelaySettingDelegate() ); - ui->tableWidget->setItemDelegateForColumn( 2, new CRelaySettingDelegate() ); - ui->tableWidget->setItemDelegateForColumn( 3, new CRelaySettingDelegate() ); - ui->tableWidget->setItemDelegateForColumn( 4, new CRelaySettingDelegate() ); - ui->tableWidget->setItemDelegateForColumn( 5, new CRelaySettingDelegate() ); - ui->tableWidget->setItemDelegateForColumn( 6, new CRelaySettingDelegate() ); - ui->tableWidget->setItemDelegateForColumn( 7, new CRelaySettingDelegate() ); - ui->tableWidget->setItemDelegateForColumn( 8, new CRelaySettingDelegate() ); -} - -bool CRelaySettingWidget::getGroupData(RelaySetting &set) -{ - for(int index(0);indextableWidget->setEnabled(isEnable); - ui->treeWidget->setEnabled(isEnable); - ui->comboBox->setEnabled(isEnable); - ui->clear->setEnabled(isEnable); - ui->change->setEnabled(m_enableList[0]); - ui->read->setEnabled(m_enableList[1]); - ui->edit->setEnabled(m_enableList[2]); - ui->confirm->setEnabled(m_enableList[3]); - - RelaySetting set; - if(!getGroupData(set)) - { - ui->comboBox->setEnabled(false); - ui->change->setEnabled(false); - } -} - -void CRelaySettingWidget::setEnableBtnList(bool isSuccess) -{ - m_enableList.clear(); - if(isSuccess) - { - if(m_requestCmd == "const_group_edit") - { - m_enableList<comboBox->setEnabled(isEnable); - ui->change->setEnabled(isEnable); - ui->edit->setEnabled(isEnable); - ui->confirm->setEnabled(isEnable); -} - -void CRelaySettingWidget::dealValueReadDownInfo(const QMap &updateData) -{ - RelaySetting relaySetting; - - bool isExit = getGroupData(relaySetting); - if(!isExit) - { - ui->curGroup->setText(""); - } - - QMap::const_iterator it = updateData.constBegin(); - while (it != updateData.constEnd()) { - - if(isExit && relaySetting.seqNo == it.key()) - { - ui->curGroup->setText(QString::number(it.value())); - } - showValueAndDefaultValue(it.key(),it.value()); - it++; - } -} - -void CRelaySettingWidget::showValueAndDefaultValue(int dot, float value) -{ - int tableIndex = findTableIndex(dot); - if(tableIndex == -1) - { - return ; - } - RelaySetting relaySetting = getDataObj(tableIndex); - value = getValueWithRatio(relaySetting,value); - QString display_value = getDisplayValue(relaySetting,value,true); - if(display_value.isEmpty()) - { - ui->tableWidget->item(tableIndex,9)->setText("1"); - ui->tableWidget->item(tableIndex,9)->setData(Qt::UserRole,1); - } - ui->tableWidget->item(tableIndex,3)->setText(display_value); - ui->tableWidget->item(tableIndex,3)->setData(Qt::UserRole,QString::number(value)); - - ui->tableWidget->item(tableIndex,4)->setText(display_value); - ui->tableWidget->item(tableIndex,4)->setData(Qt::UserRole,QString::number(value)); -} - -int CRelaySettingWidget::findTableIndex(int dot) -{ - for(int index(0);indextableWidget->rowCount();index++) - { - if(ui->tableWidget->item(index,8)->text().toInt() == dot) - { - return index; - } - } - return -1; -} - -RelaySetting CRelaySettingWidget::getDataObj(int tableIndex) -{ - int index = ui->tableWidget->item(tableIndex,0)->data(Qt::DisplayRole).toInt(); - RelaySetting relaySetting = m_setList[index]; - - if(relaySetting.valueText != "") - { - relaySetting.value = getActualValue(relaySetting,ui->tableWidget->item(tableIndex,3)->data(Qt::DisplayRole).toString()); - relaySetting.valueDefault = getActualValue(relaySetting,ui->tableWidget->item(tableIndex,4)->data(Qt::DisplayRole).toString()); - relaySetting.valueVerify = getActualValue(relaySetting,ui->tableWidget->item(tableIndex,5)->data(Qt::DisplayRole).toString()); - } - else - { - - QString value = ui->tableWidget->item(tableIndex,3)->data(Qt::DisplayRole).toString(); - if(value.isEmpty()) - { - relaySetting.value = -1; - }else - { - relaySetting.value = ui->tableWidget->item(tableIndex,3)->data(Qt::DisplayRole).toFloat(); - } - - value = ui->tableWidget->item(tableIndex,4)->data(Qt::DisplayRole).toString(); - if(value.isEmpty()) - { - relaySetting.valueDefault = -1; - }else - { - relaySetting.valueDefault = ui->tableWidget->item(tableIndex,4)->data(Qt::DisplayRole).toFloat(); - } - - value = ui->tableWidget->item(tableIndex,5)->data(Qt::DisplayRole).toString(); - if(value.isEmpty()) - { - relaySetting.valueVerify = -1; - }else - { - relaySetting.valueVerify = ui->tableWidget->item(tableIndex,5)->data(Qt::DisplayRole).toFloat(); - } - } - return relaySetting; -} - -float CRelaySettingWidget::getActualValue(RelaySetting relaySetting, QString curValue) -{ - float actual_value = -1; - QMap >::const_iterator it = m_dictMap.find(relaySetting.valueText); - if(it != m_dictMap.end()) - { - QList dictList = it.value(); - for(int index(0);index >::const_iterator it = m_dictMap.find(relaySetting.valueText); - if(it != m_dictMap.end()) - { - QList dictList = it.value(); - for(int index(0);indexPermCheck(PERM_NOM_FUNC_DEF,(char*)&str)) - { - QMessageBox::warning(this,tr("提示"),tr("无保护定值操作权限!")); - return false; - }else - { - return true; - } -} - -bool CRelaySettingWidget::checkAllItemValue() -{ - for(int index(0);indextableWidget->rowCount();++index) - { - RelaySetting relaySetting = getDataObj(index); - if( relaySetting.value == -1) - { - if(ui->tableWidget->item(index,9)->data(Qt::UserRole).toInt() == 1) - { - continue; - } - QMessageBox::warning(this,tr("提示"),tr("行:%1,当前值无效,请先读取!").arg(QString::number(index+1))); - return false; - } - } - return true; -} - -bool CRelaySettingWidget::checkAllItemValueDefault() -{ - bool isValid = false; - for(int index(0);indextableWidget->rowCount();++index) - { - RelaySetting relaySetting = getDataObj(index); - if(relaySetting.value == relaySetting.valueDefault) - { - continue; - } - - if(relaySetting.valueDefault == -1) - { - QMessageBox::warning(this,tr("提示"),tr("行:%1,预置值无效,请先读取!").arg(QString::number(index+1))); - return false; - } - - if(relaySetting.valueDefault < relaySetting.valueMin - || relaySetting.valueDefault >relaySetting.valueMax) - { - QMessageBox::warning(this,tr("提示"),tr("行:%1,预置值不在设定范围!").arg(QString::number(index+1))); - return false; - } - - isValid = true; - } - - return isValid; -} - -bool CRelaySettingWidget::checkAllItemValueVerify() -{ - for(int index(0);indextableWidget->rowCount();++index) - { - RelaySetting relaySetting = getDataObj(index); - if(relaySetting.valueVerify == -1 && relaySetting.value != relaySetting.valueDefault) - { - QMessageBox::warning(this,tr("提示"),tr("行:%1,返校值无效!").arg(QString::number(index+1))); - return false; - } - } - return true; -} - -bool CRelaySettingWidget::checkUniformity() -{ - bool isValid = false; - for(int index(0);indextableWidget->rowCount();++index) - { - RelaySetting relaySetting = getDataObj(index); - - if(ui->tableWidget->item(index,9)->data(Qt::UserRole).toInt() == 1) - { - continue; - } - - if(relaySetting.value == relaySetting.valueDefault) - { - continue; - } - - if(relaySetting.valueDefault != relaySetting.valueVerify) - { - QMessageBox::warning(this,tr("提示"),tr("行:%1,预置值与返校值不一致!").arg(QString::number(index+1))); - return false; - } - isValid = true; - } - return isValid; -} - -void CRelaySettingWidget::getReadData(QList &keyList, QList &valueList, const RelaySetting &relaySetting) -{ - keyList.append("cmd_type"); - valueList.append("const_value_read"); - keyList.append("dev_id"); - valueList.append(QString::number(CDbMng::instance()->getDevIdByTag(relaySetting.devTag))); -} - -void CRelaySettingWidget::getEditData(QList &keyList, QList &valueList, const RelaySetting &relaySetting) -{ - keyList.append("cmd_type"); - valueList.append("const_value_edit"); - keyList.append("dev_id"); - valueList.append(QString("%1").arg(CDbMng::instance()->getDevIdByTag(m_clickDev))); - QString curGroup = ui->curGroup->text(); - if(relaySetting.valueType == 5) - { - keyList.append("dot_no"); - valueList.append("32767"); - keyList.append("cur_value"); - valueList.append(curGroup); - keyList.append("edit_value"); - valueList.append(curGroup); - } - - for(int index(0);indextableWidget->rowCount();index++) - { - RelaySetting setting =getDataObj(index); - if(ui->tableWidget->item(index,9)->data(Qt::UserRole) == 1) - { - continue; - } - - if (setting.value == setting.valueDefault) - { - continue; - } - - if(setting.value == -1) - { - // continue; - } - - if(setting.valueDefault == -1) - { - // continue; - } - float value_current = getValueWithoutRatio(setting,setting.value); - float value_default = getValueWithoutRatio(setting,setting.valueDefault); - - keyList.append("dot_no"); - valueList.append(QString::number(setting.seqNo)); - keyList.append("cur_value"); - valueList.append(QString::number(value_current)); - keyList.append("edit_value"); - valueList.append(QString::number(value_default)); - } -} - -void CRelaySettingWidget::getAffirmData(QList &keyList, QList &valueList, const RelaySetting &relaySetting) -{ - QString curGroup = "1"; - if(relaySetting.valueType == 5) - { - curGroup = ui->curGroup->text(); - } - - keyList.append("cmd_type"); - valueList.append("const_value_affirm"); - keyList.append("dev_id"); - valueList.append(QString("%1").arg(CDbMng::instance()->getDevIdByTag(m_clickDev))); - keyList.append("group_no"); - valueList.append(curGroup); - - for(int index(0);indextableWidget->rowCount();++index) - { - RelaySetting set = getDataObj(index); - - if(ui->tableWidget->item(index,9)->data(Qt::UserRole).toInt() == 1) - { - continue; - } - - if (set.value == set.valueDefault) - { - continue; - } - - if(set.value == -1) - { - continue; - } - - if(set.valueDefault== -1) - { - continue; - } - - if(set.valueVerify == -1) - { - continue; - } - - float value_verify = getValueWithoutRatio(set,set.valueVerify); - - keyList.append("dot_no"); - valueList.append(QString::number(set.seqNo)); - - keyList.append("edit_value"); - valueList.append(QString::number(value_verify)); - } -} - -void CRelaySettingWidget::getGEditData(QList &keyList, QList &valueList, const RelaySetting &relaySetting) -{ - QString curGroup = ui->curGroup->text(); - QString changeGroup = QString::number(getSelectGroup()); - keyList.append("cmd_type"); - valueList.append("const_group_edit"); - keyList.append("dev_id"); - valueList.append(QString("%1").arg(CDbMng::instance()->getDevIdByTag(m_clickDev))); - keyList.append("dot_no"); - valueList.append(QString::number(relaySetting.seqNo)); - keyList.append("cur_group"); - valueList.append(curGroup); - keyList.append("edit_group"); - valueList.append(changeGroup); -} - -void CRelaySettingWidget::dealRead(const RelayCmdReply &reply) -{ - QMap m_updateData; - for(int index(0);index m_updateData; - for(int index(0);index m_updateData; - for(int index(0);indexcurGroup->setText(QString::number(reply.cur_group)); -} - -void CRelaySettingWidget::dealValueEditDownInfo(const QMap &updateData) -{ - QMap::const_iterator it = updateData.constBegin(); - while (it != updateData.constEnd()) { - int tableIndex = findTableIndex(it.key()); - if(tableIndex == -1) - { - it++; - continue; - } - RelaySetting relaySetting = getDataObj(tableIndex); - float value = getValueWithRatio(relaySetting,it.value()); - - if(relaySetting.valueText != "") - { - QString display_value = getDisplayValue(relaySetting,value,false); - ui->tableWidget->item(tableIndex,5)->setText(display_value); - ui->tableWidget->item(tableIndex,5)->setData(Qt::UserRole,QString::number(value)); - } - else - { - ui->tableWidget->item(tableIndex,5)->setText(QString::number(value)); - ui->tableWidget->item(tableIndex,5)->setData(Qt::UserRole,QString::number(value)); - } - it++; - } -} - -void CRelaySettingWidget::dealValueAffirmDownInfo(const QMap &updateData) -{ - QMap::const_iterator it = updateData.constBegin(); - while (it != updateData.constEnd()) { - int tableIndex = findTableIndex(it.key()); - if(tableIndex == -1) - { - it++; - continue; - } - RelaySetting relaySetting = getDataObj(tableIndex); - float value = getValueWithRatio(relaySetting,it.value()); - - if(relaySetting.valueText != "") - { - QString display_value = getDisplayValue(relaySetting,value,false); - ui->tableWidget->item(tableIndex,3)->setText(display_value); - ui->tableWidget->item(tableIndex,3)->setData(Qt::UserRole,QString::number(value)); - } - else - { - ui->tableWidget->item(tableIndex,3)->setText(QString::number(value)); - ui->tableWidget->item(tableIndex,3)->setData(Qt::UserRole,QString::number(value)); - } - it++; - } -} - -int CRelaySettingWidget::getSelectGroup() -{ - int row = ui->comboBox->currentIndex(); - if(row<0) - { - return -1; - } - - return ui->comboBox->currentData(Qt::UserRole).toInt(); -} - -bool CRelaySettingWidget::checkCurGroup(int groupNo) -{ - QString curGroup = ui->curGroup->text(); - if (curGroup.isEmpty()) - { - QMessageBox::warning(this,tr("提示"),tr("请先查询当前执行组!")); - return false; - } - - if (groupNo == curGroup.toInt()) - { - QMessageBox::warning(this,tr("提示"),tr("设置的组号应不为当前执行组!")); - return false; - } - return true; -} - -void CRelaySettingWidget::treeItemClicked(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column); - if(item == Q_NULLPTR) - { - return ; - } - if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_LOC) - { - return ; - }else if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_RTU) - { - return ; - }else if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_DEV) - { - m_ModbusChannlIndex =-1; - QString clickedDev = item->data(0,Qt::UserRole+1).toString(); - if(m_clickDev == clickedDev) - { - return ; - } - - ui->mGroupCb->setCurrentIndex(ui->mGroupCb->findData(clickedDev)); - - m_clickDev = clickedDev; - }else if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_TREE_LOC) - { - return ; - }else if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_TREE_CHANL) - { - //获取通道号 - m_clickDev.clear(); - - int ChannlIndex = item->data(0,Qt::UserRole+5).toInt(); - if(ChannlIndex == m_ModbusChannlIndex) - { - return ; - } - //从服务获取通道点信息 - - m_ModbusChannlIndex =ChannlIndex; - QString paraFileName= chanlList[m_ModbusChannlIndex].paraFileName; - QString chanlDesc = chanlList[m_ModbusChannlIndex].chanlDesc; - ui->mGroupCb->setCurrentIndex(ui->mGroupCb->findText(chanlDesc)); - CRelayFile relayFile; - QList m_paralist= relayFile.getParaList(paraFileName); - //显示定值列表 - ui->tableWidget->setRowCount(0); - for(int index(0);indexcolumn() != 4) - { - ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - }else - { - ui->tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked); - } -} - -void CRelaySettingWidget::readBtnClicked() -{ - if(!m_clickDev.isEmpty()) - { - RelaySetting relaySetting; - if(!getGroupData(relaySetting)) - { - if(!getGroupDevice(relaySetting)) - { - return ; - } - } - m_requestCmd = "const_value_read"; - QList keyList; - QList valueList; - getReadData(keyList,valueList,relaySetting); - m_enableLastList = m_enableList; - ui->curGroup->setText(""); - m_enableList.clear(); - m_enableList<=0) - { - //发送读取定值 - - - int groupNo = 0; - QList indexList; - indexList.append(m_ModbusChannlIndex); - m_enableList.clear(); - m_enableList< keyList; - QList valueList; - getEditData(keyList,valueList,relaySetting); - m_enableLastList = m_enableList; - m_enableList.clear(); - m_enableList< keyList; - QList valueList; - getAffirmData(keyList,valueList,relaySetting); - m_enableLastList = m_enableList; - m_enableList.clear(); - m_enableList<tableWidget->rowCount(); ++index) - { - ui->tableWidget->item(index,3)->setText(""); - ui->tableWidget->item(index,3)->setData(Qt::UserRole,QString::number(-1)); - - ui->tableWidget->item(index,4)->setText(""); - ui->tableWidget->item(index,4)->setData(Qt::UserRole,QString::number(-1)); - - ui->tableWidget->item(index,5)->setText(""); - ui->tableWidget->item(index,5)->setData(Qt::UserRole,QString::number(-1)); - } - m_enableList.clear(); - m_enableList< keyList; - QList valueList; - getGEditData(keyList,valueList,relaySetting); - m_enableLastList = m_enableList; - m_enableList.clear(); - m_enableList<treeWidget->setHidden(isHide); -} - -void CRelaySettingWidget::setFilterGroup(const QString &groupPoints) -{ - mFilterDevs.clear(); - if(groupPoints.isEmpty()) - { - return; - } - //station1.PSCADA.digital.station1.NQ-G10_dlq.Pos.value - QStringList points = groupPoints.split(","); - for(int i=0; igetFesDevByKeyIdTag(keyIdTag); - mFilterDevs.push_back(fesDev); - } - - initView(); -} - -QString CRelaySettingWidget::getFesDevByKeyIdTag(const QString &keyIdTag) -{ - QString retStr; - kbd_dbms::CDbApi* m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - if(!m_pReadDb->open()) - { - return retStr; - } - - QStringList keyIdTagList = keyIdTag.split("."); - QString table = keyIdTagList.at(2); - QString fesTable = QString("fes_%1").arg(table); - keyIdTagList.removeAt(0); - keyIdTagList.removeAt(0); - keyIdTagList.removeAt(0); - keyIdTagList.removeLast(); - QString appTagName =keyIdTagList.join("."); - - QSqlQuery query; - QString sqlQuery = QString("select DEV_TAG from %1 where APP_TAG_NAME='%2'") - .arg(fesTable).arg(appTagName); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - retStr = query.value(0).toString(); - break; - } - - m_pReadDb->close(); - - return retStr; -} - -void CRelaySettingWidget::slotRecvOuttime() -{ - m_enableList =m_enableLastList; - setEnableBtnList(false); - m_requestCmd = ""; - setStartCmdState(true); - QMessageBox::warning(this,tr("提示"),tr("接收超时!")); -} - -void CRelaySettingWidget::slotCurrentIndexChanged(int curIndex) -{ - QString indexDev = ui->mGroupCb->currentData().toString(); - int filterType = EN_RELAY_DEV; - if(indexDev.isEmpty()) - { - filterType = EN_RELAY_TREE_CHANL; - indexDev = ui->mGroupCb->currentText(); - } - - QTreeWidgetItemIterator it(ui->treeWidget); - while (*it) { - QTreeWidgetItem* item = *it; - int type = item->data(0,Qt::UserRole).toInt(); - if(type != EN_RELAY_DEV && type != EN_RELAY_TREE_CHANL) - { - ++it; - continue; - } - - QString devName; - if(filterType == EN_RELAY_TREE_CHANL) - { - devName = item->text(0); - } - else - { - devName = item->data(0,Qt::UserRole+1).toString(); - } - - if(devName == indexDev) - { - ui->treeWidget->setCurrentItem(item); - treeItemClicked(item,0); - break; - } - ++it; - } -} - -void CRelaySettingWidget::slotDataChanged(const RelayCmdReply &reply,const QString &cmd) -{ - setEnableBtnList(reply.isSuccess); - // if(reply.isSuccess != 1) - { - QMessageBox::warning(this,tr("提示"),reply.resultStr); - } - - if(reply.isSuccess==1) - { - if(cmd == "const_value_read") - { - dealRead(reply); - }else if(cmd == "const_value_edit") - { - dealEdit(reply); - }else if(cmd == "const_value_affirm") - { - dealAffirm(reply); - }else if(cmd == "const_group_edit") - { - dealGroupEdit(reply); - } - } - - setStartCmdState(true); -} - -void CRelaySettingWidget::slotError() -{ - m_enableList =m_enableLastList; - setEnableBtnList(false); - m_requestCmd = ""; - setStartCmdState(true); - QMessageBox::warning(this,tr("提示"),tr("发送命令失败!")); -} +/** +*@file ConstWidget +*@brief 保护定值插件 +*@author jxd +*@date 2021-05-12 +*/ +#include "CRelaySettingWidget.h" +#include "ui_CRelaySettingWidget.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include "pub_logger_api/logger.h" +#include "CDbMng.h" +#include +#include "CRelaySettingDelegate.h" + + + +CRelaySettingWidget::CRelaySettingWidget(bool editMode, QWidget *parent) : + QWidget(parent), + ui(new Ui::CRelaySettingWidget), + m_ptrSysInfo(Q_NULLPTR), + m_msgMng(Q_NULLPTR), + m_pWork(Q_NULLPTR),m_ModbusChannlIndex(-1) +{ + ui->setupUi(this); + + qRegisterMetaType("RelaySetting"); + qRegisterMetaType("RelayCmdReply"); + qRegisterMetaType >("QList"); + + m_clickDev.clear(); + initStyleSheet(); + ui->splitter->setSizes(QList()<<220<<1200); + if(!editMode) + { + initialize(); + } +} + +CRelaySettingWidget::~CRelaySettingWidget() +{ + if(m_msgMng) + { + delete m_msgMng; + } + m_msgMng = Q_NULLPTR; + + CDbMng::instance()->destory(); + + if(m_workThread.isRunning()) + { + m_workThread.quit(); + m_workThread.wait(); + } + + delete ui; +} + +void CRelaySettingWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + +} + +void CRelaySettingWidget::initialize() +{ + m_enableList<getLocalNodeInfo(m_nodeInfo) == kbdSuccess) + { + LOGINFO("获取节点信息成功!"); + }else + { + LOGINFO("获取节点信息失败!"); + } + //3. + m_permMng = getPermMngInstance("base"); + if(m_permMng != NULL) + { + if(m_permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + } + } + + //4.获取位置 + loadLoc(); + //5.获取rtu + loadRtu(); + //6.获取前置设备 + loadDev(); + //7.获取位置rtu设备 + loadLocRtuDev(); + //8.获取unit + loadUnit(); + //9.获取dict + loadDict(); + //10.获取保护定值 + loadSetting(); + + //获取modbus + loadModbusConfig(); + + initModbusData(); + + initView(); + initConn(); + + +} + +//loadModbus +void CRelaySettingWidget::loadModbusConfig() +{ + loadModbusChanl(); + loadModbusGroup(); +} + +void CRelaySettingWidget::initModbusData() +{ + if(!m_pWork) + { + m_pWork = new CWorker(); + } + m_pWork->moveToThread(&m_workThread); + + m_workThread.start(); +} + +void CRelaySettingWidget::loadModbusChanl() +{ + m_locChanlList.clear(); + CRelayFile relayFile; + chanlList = relayFile.getChanlList(); + + for(int i(0);i > &pair= m_locChanlList[j]; + if(pair.first == relayChanl.loc) + { + isEixt = true; + pair.second.append(relayChanl); + break; + } + } + if(!isEixt) + { + QList relayList; + relayList.append(relayChanl); + m_locChanlList.append(qMakePair >(relayChanl.loc,relayList)); + } + } + + //获得通道参数 + +} + +void CRelaySettingWidget::loadModbusGroup() +{ + m_groupList.clear(); + CRelayFile relayFile; + m_groupList = relayFile.getGroupList(); +} +// + +void CRelaySettingWidget::loadLoc() +{ + m_locMap = CDbMng::instance()->getLocInfo(); +} + +void CRelaySettingWidget::loadRtu() +{ + m_rtuMap = CDbMng::instance()->getRtuInfo(); +} + +void CRelaySettingWidget::loadDev() +{ + m_devMap = CDbMng::instance()->getDevInfo(); +} + +void CRelaySettingWidget::loadLocRtuDev() +{ + m_locRtuDevMap = CDbMng::instance()->getLocRtuDevInfo(); +} + +void CRelaySettingWidget::loadUnit() +{ + m_unitMap = CDbMng::instance()->getUnitInfo(); +} + +void CRelaySettingWidget::loadDict() +{ + m_dictMap = CDbMng::instance()->getDictInfo(); +} + +void CRelaySettingWidget::loadSetting() +{ + m_setList = CDbMng::instance()->getSetting(); +} + + +/*void CRelaySettingWidget::insertToTable(const SRelayData &relayData) + +{ + int rowCount = ui->tableWidget->rowCount(); + ui->tableWidget->insertRow(rowCount); + QTableWidgetItem *item = new QTableWidgetItem(); + item->setText(relayData.chanName); + ui->tableWidget->setItem(rowCount,0,item); + + item = new QTableWidgetItem(); + item->setText(relayData.name); + ui->tableWidget->setItem(rowCount,1,item); + + item = new QTableWidgetItem(); + item->setText(QString::number(relayData.value)); + ui->tableWidget->setItem(rowCount,2,item); +}*/ + +void CRelaySettingWidget::slotModbusDataChange(QList relayDataList, bool isFaild, QString error) +{ + + // QMessageBox::warning(this,tr("提示"),"11111111"); + m_enableList.clear(); + m_enableList<tableWidget->setRowCount(0); + // setViewEnable(true); + for(int index(0);indexcomboBox->setView(new QListView()); + initTree(); + initModbusTree(); + + initTable(); + setCtrlBtnEnable(false); +} + +void CRelaySettingWidget::initModbusTree() +{ + ui->treeWidget->setColumnCount(1); + for(int i(0);i > &pair= m_locChanlList[i]; + + QTreeWidgetItem *locItem = new QTreeWidgetItem(ui->treeWidget); + locItem->setText(0,pair.first); + locItem->setData(0,Qt::UserRole,(int)EN_RELAY_TREE_LOC); + ui->treeWidget->addTopLevelItem(locItem); + locItem->setExpanded(true); + + // locItem->setCheckState(0,Qt::Unchecked); + QList &relayChanlList = pair.second; + for(int j(0);jsetCheckState(0,Qt::Unchecked); + chanlItem->setText(0,relayChanl.chanlDesc); + chanlItem->setData(0,Qt::UserRole,(int)EN_RELAY_TREE_CHANL); + chanlItem->setData(0,Qt::UserRole+1,relayChanl.chanlAddr); + chanlItem->setData(0,Qt::UserRole+2,relayChanl.loc); + chanlItem->setData(0,Qt::UserRole+3,relayChanl.ip); + chanlItem->setData(0,Qt::UserRole+4,relayChanl.port); + chanlItem->setData(0,Qt::UserRole+5,relayChanl.index); + + ui->mGroupCb->addItem(relayChanl.chanlDesc,""); + + locItem->addChild(chanlItem); + } + } +} + +void CRelaySettingWidget::initTree() +{ + cleanTree(); + ui->treeWidget->setColumnCount(1); + QMap > >::iterator locIter = m_locRtuDevMap.begin(); + while (locIter != m_locRtuDevMap.end()) + { + + int locId = locIter.key(); + QString locDesc = m_locMap.value(locId).desc; + QTreeWidgetItem *locItem = new QTreeWidgetItem(); + locItem->setText(0,locDesc); + locItem->setData(0,Qt::UserRole,(int)EN_RELAY_LOC); + locItem->setData(0,Qt::UserRole+1,locId); + ui->treeWidget->addTopLevelItem(locItem); + locItem->setExpanded(true); + QMap > & rtuDevMap = locIter.value(); + QMap >::iterator rtuIter = rtuDevMap.begin(); + while (rtuIter != rtuDevMap.end()) { + QString rtuName = rtuIter.key(); + QString rtuDesc = m_rtuMap.value(rtuName).desc; + QTreeWidgetItem *rtuItem = new QTreeWidgetItem(); + rtuItem->setText(0,rtuDesc); + rtuItem->setData(0,Qt::UserRole,(int)EN_RELAY_RTU); + rtuItem->setData(0,Qt::UserRole+1,rtuName); + locItem->addChild(rtuItem); + QMap & devMap = rtuIter.value(); + QMap::iterator devIter = devMap.begin(); + while (devIter != devMap.end()) { + + QString devName = devIter.key(); + if((!mFilterDevs.isEmpty()) && (!mFilterDevs.contains(devName))) + { + devIter++; + continue; + } + + QString devDesc = devIter.value().desc; + QTreeWidgetItem *devItem = new QTreeWidgetItem(); + QString showDesc = devDesc.isEmpty() ? devName : devDesc; + devItem->setText(0,showDesc); + devItem->setData(0,Qt::UserRole,(int)EN_RELAY_DEV); + devItem->setData(0,Qt::UserRole+1,devName); + rtuItem->addChild(devItem); + + ui->mGroupCb->addItem(showDesc,devName); + + devIter++; + } + rtuIter++; + } + locIter++; + } +} + +void CRelaySettingWidget::cleanTree() +{ + ui->mGroupCb->clear(); + for(int index(ui->treeWidget->topLevelItemCount()-1);index>=0;index--) + { + QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index); + itemChildClear(item); + ui->treeWidget->removeItemWidget(item,0); + } +} + +void CRelaySettingWidget::itemChildClear(QTreeWidgetItem *item) +{ + if(item == Q_NULLPTR) + { + return ; + } + for(int index(item->childCount()-1);index>=0;index--) + { + QTreeWidgetItem *childItem = item->child(index); + itemChildClear(childItem); + item->removeChild(childItem); + } +} + +void CRelaySettingWidget::initConn() +{ + connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&CRelaySettingWidget::treeItemClicked); + connect(ui->tableWidget,&QTableWidget::itemDoubleClicked,this,&CRelaySettingWidget::tableItemDoubleClicked); + connect(ui->read,&QPushButton::clicked,this,&CRelaySettingWidget::readBtnClicked); + connect(ui->edit,&QPushButton::clicked,this,&CRelaySettingWidget::editBtnClicked); + connect(ui->confirm,&QPushButton::clicked,this,&CRelaySettingWidget::confirmBtnClicked); + connect(ui->clear,&QPushButton::clicked,this,&CRelaySettingWidget::clearBtnClicked); + connect(ui->change,&QPushButton::clicked,this,&CRelaySettingWidget::changeGDevClicked); + connect(this,&CRelaySettingWidget::sigcmd,m_msgMng,&CRelaySettingMsgMng::slotcmd); + connect(m_msgMng,&CRelaySettingMsgMng::recvOuttime,this,&CRelaySettingWidget::slotRecvOuttime); + connect(m_msgMng,&CRelaySettingMsgMng::dataChanged,this,&CRelaySettingWidget::slotDataChanged); + connect(m_msgMng,&CRelaySettingMsgMng::sendError,this,&CRelaySettingWidget::slotError); + + connect(ui->mGroupCb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int))); + //Modbus + connect(&m_workThread,&QThread::started,m_pWork,&CWorker::init,Qt::QueuedConnection); + connect(&m_workThread,&QThread::finished,m_pWork,&QObject::deleteLater); + + connect(this,&CRelaySettingWidget::sigSearchData,m_pWork,&CWorker::slotSearch,Qt::QueuedConnection); + connect(m_pWork,&CWorker::sigDataChange,this,&CRelaySettingWidget::slotModbusDataChange,Qt::QueuedConnection); +} + +void CRelaySettingWidget::brush() +{ + ui->curGroup->setText(""); + initGroupCmb(); + ui->tableWidget->setRowCount(0); + if(m_clickDev.isEmpty()) + { + return ; + } + for(int index(0);indexcomboBox->clear(); + if (m_clickDev.isEmpty()) + { + return ; + } + RelaySetting relaySetting; + if(getGroupData(relaySetting)) + { + updateGroupCmb(relaySetting); + } +} + +void CRelaySettingWidget::updateGroupCmb(const RelaySetting &relaySetting) +{ + + relaySetting.valueMin; + int min = (int)relaySetting.valueMin; + int max = (int)relaySetting.valueMax; + if(max == 65535 || max == 32767) + { + ui->comboBox->addItem("0",0); + return; + } + + for(int i=min; i 100) + { + break; + } + ui->comboBox->addItem(QString("%1").arg(i),i); + } +} + +void CRelaySettingWidget::insertToTableModbus(RelaySetting relaySetting, int index) +{ + int rowCount = ui->tableWidget->rowCount(); + ui->tableWidget->insertRow(rowCount); + + QTableWidgetItem *item = new QTableWidgetItem(); + item->setText(QString::number(index)); + item->setData(Qt::UserRole,index); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,0,item); + + item = new QTableWidgetItem(); + item->setText(relaySetting.desc); + item->setData(Qt::UserRole,relaySetting.tagName); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,1,item); + + item = new QTableWidgetItem(); + item->setText(QString::number(relaySetting.groupNo)); + item->setData(Qt::UserRole,relaySetting.groupNo); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,2,item); + + item = new QTableWidgetItem(); + item->setText(""); + item->setData(Qt::UserRole,""); + item->setText(QString::number(relaySetting.value)); + item->setData(Qt::UserRole,relaySetting.value); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,3,item); + + item = new QTableWidgetItem(); + item->setText(""); + item->setData(Qt::UserRole,""); + item->setData(Qt::UserRole+10,relaySetting.valueType); + item->setData(Qt::UserRole+11,relaySetting.valueText); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,4,item); + + item = new QTableWidgetItem(); + item->setText(""); + item->setData(Qt::UserRole,""); + item->setData(Qt::UserRole+10,relaySetting.valueType); + item->setData(Qt::UserRole+11,relaySetting.valueText); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,5,item); + + item = new QTableWidgetItem(); + item->setText(QString("%1~%2").arg(QString::number(relaySetting.valueMin)).arg(QString::number(relaySetting.valueMax))); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,6,item); + + item = new QTableWidgetItem(); + item->setText(m_unitMap.value(relaySetting.unitId).name); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,7,item); + + item = new QTableWidgetItem(); + item->setText(QString::number(index)); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,8,item); + + item = new QTableWidgetItem(); + item->setText("0"); + item->setData(Qt::UserRole,0); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,9,item); +} + +void CRelaySettingWidget::insertToTable(RelaySetting relaySetting, int index) +{ + int rowCount = ui->tableWidget->rowCount(); + ui->tableWidget->insertRow(rowCount); + + QTableWidgetItem *item = new QTableWidgetItem(); + item->setText(QString::number(index)); + item->setData(Qt::UserRole,index); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,0,item); + + item = new QTableWidgetItem(); + item->setText(relaySetting.desc); + item->setData(Qt::UserRole,relaySetting.tagName); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,1,item); + + item = new QTableWidgetItem(); + item->setText(QString::number(relaySetting.groupNo)); + item->setData(Qt::UserRole,relaySetting.groupNo); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,2,item); + + item = new QTableWidgetItem(); + item->setText(""); + item->setData(Qt::UserRole,""); + item->setData(Qt::UserRole+10,relaySetting.valueType); + item->setData(Qt::UserRole+11,relaySetting.valueText); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,3,item); + + item = new QTableWidgetItem(); + item->setText(""); + item->setData(Qt::UserRole,""); + item->setData(Qt::UserRole+10,relaySetting.valueType); + item->setData(Qt::UserRole+11,relaySetting.valueText); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,4,item); + + item = new QTableWidgetItem(); + item->setText(""); + item->setData(Qt::UserRole,""); + item->setData(Qt::UserRole+10,relaySetting.valueType); + item->setData(Qt::UserRole+11,relaySetting.valueText); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,5,item); + + item = new QTableWidgetItem(); + item->setText(QString("%1~%2").arg(QString::number(relaySetting.valueMin)).arg(QString::number(relaySetting.valueMax))); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,6,item); + + item = new QTableWidgetItem(); + item->setText(m_unitMap.value(relaySetting.unitId).name); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,7,item); + + item = new QTableWidgetItem(); + item->setText(QString::number(relaySetting.seqNo)); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,8,item); + + item = new QTableWidgetItem(); + item->setText("0"); + item->setData(Qt::UserRole,0); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,9,item); +} + +void CRelaySettingWidget::initTable() +{ + ui->tableWidget->setColumnHidden(2,true); + ui->tableWidget->setColumnHidden(9,true); + ui->tableWidget->setItemDelegateForColumn( 0, new CRelaySettingDelegate() ); + ui->tableWidget->setItemDelegateForColumn( 2, new CRelaySettingDelegate() ); + ui->tableWidget->setItemDelegateForColumn( 3, new CRelaySettingDelegate() ); + ui->tableWidget->setItemDelegateForColumn( 4, new CRelaySettingDelegate() ); + ui->tableWidget->setItemDelegateForColumn( 5, new CRelaySettingDelegate() ); + ui->tableWidget->setItemDelegateForColumn( 6, new CRelaySettingDelegate() ); + ui->tableWidget->setItemDelegateForColumn( 7, new CRelaySettingDelegate() ); + ui->tableWidget->setItemDelegateForColumn( 8, new CRelaySettingDelegate() ); +} + +bool CRelaySettingWidget::getGroupData(RelaySetting &set) +{ + for(int index(0);indextableWidget->setEnabled(isEnable); + ui->treeWidget->setEnabled(isEnable); + ui->comboBox->setEnabled(isEnable); + ui->clear->setEnabled(isEnable); + ui->change->setEnabled(m_enableList[0]); + ui->read->setEnabled(m_enableList[1]); + ui->edit->setEnabled(m_enableList[2]); + ui->confirm->setEnabled(m_enableList[3]); + + RelaySetting set; + if(!getGroupData(set)) + { + ui->comboBox->setEnabled(false); + ui->change->setEnabled(false); + } +} + +void CRelaySettingWidget::setEnableBtnList(bool isSuccess) +{ + m_enableList.clear(); + if(isSuccess) + { + if(m_requestCmd == "const_group_edit") + { + m_enableList<comboBox->setEnabled(isEnable); + ui->change->setEnabled(isEnable); + ui->edit->setEnabled(isEnable); + ui->confirm->setEnabled(isEnable); +} + +void CRelaySettingWidget::dealValueReadDownInfo(const QMap &updateData) +{ + RelaySetting relaySetting; + + bool isExit = getGroupData(relaySetting); + if(!isExit) + { + ui->curGroup->setText(""); + } + + QMap::const_iterator it = updateData.constBegin(); + while (it != updateData.constEnd()) { + + if(isExit && relaySetting.seqNo == it.key()) + { + ui->curGroup->setText(QString::number(it.value())); + } + showValueAndDefaultValue(it.key(),it.value()); + it++; + } +} + +void CRelaySettingWidget::showValueAndDefaultValue(int dot, float value) +{ + int tableIndex = findTableIndex(dot); + if(tableIndex == -1) + { + return ; + } + RelaySetting relaySetting = getDataObj(tableIndex); + value = getValueWithRatio(relaySetting,value); + QString display_value = getDisplayValue(relaySetting,value,true); + if(display_value.isEmpty()) + { + ui->tableWidget->item(tableIndex,9)->setText("1"); + ui->tableWidget->item(tableIndex,9)->setData(Qt::UserRole,1); + } + ui->tableWidget->item(tableIndex,3)->setText(display_value); + ui->tableWidget->item(tableIndex,3)->setData(Qt::UserRole,QString::number(value)); + + ui->tableWidget->item(tableIndex,4)->setText(display_value); + ui->tableWidget->item(tableIndex,4)->setData(Qt::UserRole,QString::number(value)); +} + +int CRelaySettingWidget::findTableIndex(int dot) +{ + for(int index(0);indextableWidget->rowCount();index++) + { + if(ui->tableWidget->item(index,8)->text().toInt() == dot) + { + return index; + } + } + return -1; +} + +RelaySetting CRelaySettingWidget::getDataObj(int tableIndex) +{ + int index = ui->tableWidget->item(tableIndex,0)->data(Qt::DisplayRole).toInt(); + RelaySetting relaySetting = m_setList[index]; + + if(relaySetting.valueText != "") + { + relaySetting.value = getActualValue(relaySetting,ui->tableWidget->item(tableIndex,3)->data(Qt::DisplayRole).toString()); + relaySetting.valueDefault = getActualValue(relaySetting,ui->tableWidget->item(tableIndex,4)->data(Qt::DisplayRole).toString()); + relaySetting.valueVerify = getActualValue(relaySetting,ui->tableWidget->item(tableIndex,5)->data(Qt::DisplayRole).toString()); + } + else + { + + QString value = ui->tableWidget->item(tableIndex,3)->data(Qt::DisplayRole).toString(); + if(value.isEmpty()) + { + relaySetting.value = -1; + }else + { + relaySetting.value = ui->tableWidget->item(tableIndex,3)->data(Qt::DisplayRole).toFloat(); + } + + value = ui->tableWidget->item(tableIndex,4)->data(Qt::DisplayRole).toString(); + if(value.isEmpty()) + { + relaySetting.valueDefault = -1; + }else + { + relaySetting.valueDefault = ui->tableWidget->item(tableIndex,4)->data(Qt::DisplayRole).toFloat(); + } + + value = ui->tableWidget->item(tableIndex,5)->data(Qt::DisplayRole).toString(); + if(value.isEmpty()) + { + relaySetting.valueVerify = -1; + }else + { + relaySetting.valueVerify = ui->tableWidget->item(tableIndex,5)->data(Qt::DisplayRole).toFloat(); + } + } + return relaySetting; +} + +float CRelaySettingWidget::getActualValue(RelaySetting relaySetting, QString curValue) +{ + float actual_value = -1; + QMap >::const_iterator it = m_dictMap.find(relaySetting.valueText); + if(it != m_dictMap.end()) + { + QList dictList = it.value(); + for(int index(0);index >::const_iterator it = m_dictMap.find(relaySetting.valueText); + if(it != m_dictMap.end()) + { + QList dictList = it.value(); + for(int index(0);indexPermCheck(PERM_NOM_FUNC_DEF,(char*)&str)) + { + QMessageBox::warning(this,tr("提示"),tr("无保护定值操作权限!")); + return false; + }else + { + return true; + } +} + +bool CRelaySettingWidget::checkAllItemValue() +{ + for(int index(0);indextableWidget->rowCount();++index) + { + RelaySetting relaySetting = getDataObj(index); + if( relaySetting.value == -1) + { + if(ui->tableWidget->item(index,9)->data(Qt::UserRole).toInt() == 1) + { + continue; + } + QMessageBox::warning(this,tr("提示"),tr("行:%1,当前值无效,请先读取!").arg(QString::number(index+1))); + return false; + } + } + return true; +} + +bool CRelaySettingWidget::checkAllItemValueDefault() +{ + bool isValid = false; + for(int index(0);indextableWidget->rowCount();++index) + { + RelaySetting relaySetting = getDataObj(index); + if(relaySetting.value == relaySetting.valueDefault) + { + continue; + } + + if(relaySetting.valueDefault == -1) + { + QMessageBox::warning(this,tr("提示"),tr("行:%1,预置值无效,请先读取!").arg(QString::number(index+1))); + return false; + } + + if(relaySetting.valueDefault < relaySetting.valueMin + || relaySetting.valueDefault >relaySetting.valueMax) + { + QMessageBox::warning(this,tr("提示"),tr("行:%1,预置值不在设定范围!").arg(QString::number(index+1))); + return false; + } + + isValid = true; + } + + return isValid; +} + +bool CRelaySettingWidget::checkAllItemValueVerify() +{ + for(int index(0);indextableWidget->rowCount();++index) + { + RelaySetting relaySetting = getDataObj(index); + if(relaySetting.valueVerify == -1 && relaySetting.value != relaySetting.valueDefault) + { + QMessageBox::warning(this,tr("提示"),tr("行:%1,返校值无效!").arg(QString::number(index+1))); + return false; + } + } + return true; +} + +bool CRelaySettingWidget::checkUniformity() +{ + bool isValid = false; + for(int index(0);indextableWidget->rowCount();++index) + { + RelaySetting relaySetting = getDataObj(index); + + if(ui->tableWidget->item(index,9)->data(Qt::UserRole).toInt() == 1) + { + continue; + } + + if(relaySetting.value == relaySetting.valueDefault) + { + continue; + } + + if(relaySetting.valueDefault != relaySetting.valueVerify) + { + QMessageBox::warning(this,tr("提示"),tr("行:%1,预置值与返校值不一致!").arg(QString::number(index+1))); + return false; + } + isValid = true; + } + return isValid; +} + +void CRelaySettingWidget::getReadData(QList &keyList, QList &valueList, const RelaySetting &relaySetting) +{ + keyList.append("cmd_type"); + valueList.append("const_value_read"); + keyList.append("dev_id"); + valueList.append(QString::number(CDbMng::instance()->getDevIdByTag(relaySetting.devTag))); +} + +void CRelaySettingWidget::getEditData(QList &keyList, QList &valueList, const RelaySetting &relaySetting) +{ + keyList.append("cmd_type"); + valueList.append("const_value_edit"); + keyList.append("dev_id"); + valueList.append(QString("%1").arg(CDbMng::instance()->getDevIdByTag(m_clickDev))); + QString curGroup = ui->curGroup->text(); + if(relaySetting.valueType == 5) + { + keyList.append("dot_no"); + valueList.append("32767"); + keyList.append("cur_value"); + valueList.append(curGroup); + keyList.append("edit_value"); + valueList.append(curGroup); + } + + for(int index(0);indextableWidget->rowCount();index++) + { + RelaySetting setting =getDataObj(index); + if(ui->tableWidget->item(index,9)->data(Qt::UserRole) == 1) + { + continue; + } + + if (setting.value == setting.valueDefault) + { + continue; + } + + if(setting.value == -1) + { + // continue; + } + + if(setting.valueDefault == -1) + { + // continue; + } + float value_current = getValueWithoutRatio(setting,setting.value); + float value_default = getValueWithoutRatio(setting,setting.valueDefault); + + keyList.append("dot_no"); + valueList.append(QString::number(setting.seqNo)); + keyList.append("cur_value"); + valueList.append(QString::number(value_current)); + keyList.append("edit_value"); + valueList.append(QString::number(value_default)); + } +} + +void CRelaySettingWidget::getAffirmData(QList &keyList, QList &valueList, const RelaySetting &relaySetting) +{ + QString curGroup = "1"; + if(relaySetting.valueType == 5) + { + curGroup = ui->curGroup->text(); + } + + keyList.append("cmd_type"); + valueList.append("const_value_affirm"); + keyList.append("dev_id"); + valueList.append(QString("%1").arg(CDbMng::instance()->getDevIdByTag(m_clickDev))); + keyList.append("group_no"); + valueList.append(curGroup); + + for(int index(0);indextableWidget->rowCount();++index) + { + RelaySetting set = getDataObj(index); + + if(ui->tableWidget->item(index,9)->data(Qt::UserRole).toInt() == 1) + { + continue; + } + + if (set.value == set.valueDefault) + { + continue; + } + + if(set.value == -1) + { + continue; + } + + if(set.valueDefault== -1) + { + continue; + } + + if(set.valueVerify == -1) + { + continue; + } + + float value_verify = getValueWithoutRatio(set,set.valueVerify); + + keyList.append("dot_no"); + valueList.append(QString::number(set.seqNo)); + + keyList.append("edit_value"); + valueList.append(QString::number(value_verify)); + } +} + +void CRelaySettingWidget::getGEditData(QList &keyList, QList &valueList, const RelaySetting &relaySetting) +{ + QString curGroup = ui->curGroup->text(); + QString changeGroup = QString::number(getSelectGroup()); + keyList.append("cmd_type"); + valueList.append("const_group_edit"); + keyList.append("dev_id"); + valueList.append(QString("%1").arg(CDbMng::instance()->getDevIdByTag(m_clickDev))); + keyList.append("dot_no"); + valueList.append(QString::number(relaySetting.seqNo)); + keyList.append("cur_group"); + valueList.append(curGroup); + keyList.append("edit_group"); + valueList.append(changeGroup); +} + +void CRelaySettingWidget::dealRead(const RelayCmdReply &reply) +{ + QMap m_updateData; + for(int index(0);index m_updateData; + for(int index(0);index m_updateData; + for(int index(0);indexcurGroup->setText(QString::number(reply.cur_group)); +} + +void CRelaySettingWidget::dealValueEditDownInfo(const QMap &updateData) +{ + QMap::const_iterator it = updateData.constBegin(); + while (it != updateData.constEnd()) { + int tableIndex = findTableIndex(it.key()); + if(tableIndex == -1) + { + it++; + continue; + } + RelaySetting relaySetting = getDataObj(tableIndex); + float value = getValueWithRatio(relaySetting,it.value()); + + if(relaySetting.valueText != "") + { + QString display_value = getDisplayValue(relaySetting,value,false); + ui->tableWidget->item(tableIndex,5)->setText(display_value); + ui->tableWidget->item(tableIndex,5)->setData(Qt::UserRole,QString::number(value)); + } + else + { + ui->tableWidget->item(tableIndex,5)->setText(QString::number(value)); + ui->tableWidget->item(tableIndex,5)->setData(Qt::UserRole,QString::number(value)); + } + it++; + } +} + +void CRelaySettingWidget::dealValueAffirmDownInfo(const QMap &updateData) +{ + QMap::const_iterator it = updateData.constBegin(); + while (it != updateData.constEnd()) { + int tableIndex = findTableIndex(it.key()); + if(tableIndex == -1) + { + it++; + continue; + } + RelaySetting relaySetting = getDataObj(tableIndex); + float value = getValueWithRatio(relaySetting,it.value()); + + if(relaySetting.valueText != "") + { + QString display_value = getDisplayValue(relaySetting,value,false); + ui->tableWidget->item(tableIndex,3)->setText(display_value); + ui->tableWidget->item(tableIndex,3)->setData(Qt::UserRole,QString::number(value)); + } + else + { + ui->tableWidget->item(tableIndex,3)->setText(QString::number(value)); + ui->tableWidget->item(tableIndex,3)->setData(Qt::UserRole,QString::number(value)); + } + it++; + } +} + +int CRelaySettingWidget::getSelectGroup() +{ + int row = ui->comboBox->currentIndex(); + if(row<0) + { + return -1; + } + + return ui->comboBox->currentData(Qt::UserRole).toInt(); +} + +bool CRelaySettingWidget::checkCurGroup(int groupNo) +{ + QString curGroup = ui->curGroup->text(); + if (curGroup.isEmpty()) + { + QMessageBox::warning(this,tr("提示"),tr("请先查询当前执行组!")); + return false; + } + + if (groupNo == curGroup.toInt()) + { + QMessageBox::warning(this,tr("提示"),tr("设置的组号应不为当前执行组!")); + return false; + } + return true; +} + +void CRelaySettingWidget::treeItemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + if(item == Q_NULLPTR) + { + return ; + } + if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_LOC) + { + return ; + }else if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_RTU) + { + return ; + }else if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_DEV) + { + m_ModbusChannlIndex =-1; + QString clickedDev = item->data(0,Qt::UserRole+1).toString(); + if(m_clickDev == clickedDev) + { + return ; + } + + ui->mGroupCb->setCurrentIndex(ui->mGroupCb->findData(clickedDev)); + + m_clickDev = clickedDev; + }else if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_TREE_LOC) + { + return ; + }else if(item->data(0,Qt::UserRole).toInt() == EN_RELAY_TREE_CHANL) + { + //获取通道号 + m_clickDev.clear(); + + int ChannlIndex = item->data(0,Qt::UserRole+5).toInt(); + if(ChannlIndex == m_ModbusChannlIndex) + { + return ; + } + //从服务获取通道点信息 + + m_ModbusChannlIndex =ChannlIndex; + QString paraFileName= chanlList[m_ModbusChannlIndex].paraFileName; + QString chanlDesc = chanlList[m_ModbusChannlIndex].chanlDesc; + ui->mGroupCb->setCurrentIndex(ui->mGroupCb->findText(chanlDesc)); + CRelayFile relayFile; + QList m_paralist= relayFile.getParaList(paraFileName); + //显示定值列表 + ui->tableWidget->setRowCount(0); + for(int index(0);indexcolumn() != 4) + { + ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + }else + { + ui->tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked); + } +} + +void CRelaySettingWidget::readBtnClicked() +{ + if(!m_clickDev.isEmpty()) + { + RelaySetting relaySetting; + if(!getGroupData(relaySetting)) + { + if(!getGroupDevice(relaySetting)) + { + return ; + } + } + m_requestCmd = "const_value_read"; + QList keyList; + QList valueList; + getReadData(keyList,valueList,relaySetting); + m_enableLastList = m_enableList; + ui->curGroup->setText(""); + m_enableList.clear(); + m_enableList<=0) + { + //发送读取定值 + + + int groupNo = 0; + QList indexList; + indexList.append(m_ModbusChannlIndex); + m_enableList.clear(); + m_enableList< keyList; + QList valueList; + getEditData(keyList,valueList,relaySetting); + m_enableLastList = m_enableList; + m_enableList.clear(); + m_enableList< keyList; + QList valueList; + getAffirmData(keyList,valueList,relaySetting); + m_enableLastList = m_enableList; + m_enableList.clear(); + m_enableList<tableWidget->rowCount(); ++index) + { + ui->tableWidget->item(index,3)->setText(""); + ui->tableWidget->item(index,3)->setData(Qt::UserRole,QString::number(-1)); + + ui->tableWidget->item(index,4)->setText(""); + ui->tableWidget->item(index,4)->setData(Qt::UserRole,QString::number(-1)); + + ui->tableWidget->item(index,5)->setText(""); + ui->tableWidget->item(index,5)->setData(Qt::UserRole,QString::number(-1)); + } + m_enableList.clear(); + m_enableList< keyList; + QList valueList; + getGEditData(keyList,valueList,relaySetting); + m_enableLastList = m_enableList; + m_enableList.clear(); + m_enableList<treeWidget->setHidden(isHide); +} + +void CRelaySettingWidget::setFilterGroup(const QString &groupPoints) +{ + mFilterDevs.clear(); + if(groupPoints.isEmpty()) + { + return; + } + //station1.PSCADA.digital.station1.NQ-G10_dlq.Pos.value + QStringList points = groupPoints.split(","); + for(int i=0; igetFesDevByKeyIdTag(keyIdTag); + mFilterDevs.push_back(fesDev); + } + + initView(); +} + +QString CRelaySettingWidget::getFesDevByKeyIdTag(const QString &keyIdTag) +{ + QString retStr; + kbd_dbms::CDbApi* m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + return retStr; + } + + QStringList keyIdTagList = keyIdTag.split("."); + QString table = keyIdTagList.at(2); + QString fesTable = QString("fes_%1").arg(table); + keyIdTagList.removeAt(0); + keyIdTagList.removeAt(0); + keyIdTagList.removeAt(0); + keyIdTagList.removeLast(); + QString appTagName =keyIdTagList.join("."); + + QSqlQuery query; + QString sqlQuery = QString("select DEV_TAG from %1 where APP_TAG_NAME='%2'") + .arg(fesTable).arg(appTagName); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + retStr = query.value(0).toString(); + break; + } + + m_pReadDb->close(); + + return retStr; +} + +void CRelaySettingWidget::slotRecvOuttime() +{ + m_enableList =m_enableLastList; + setEnableBtnList(false); + m_requestCmd = ""; + setStartCmdState(true); + QMessageBox::warning(this,tr("提示"),tr("接收超时!")); +} + +void CRelaySettingWidget::slotCurrentIndexChanged(int curIndex) +{ + QString indexDev = ui->mGroupCb->currentData().toString(); + int filterType = EN_RELAY_DEV; + if(indexDev.isEmpty()) + { + filterType = EN_RELAY_TREE_CHANL; + indexDev = ui->mGroupCb->currentText(); + } + + QTreeWidgetItemIterator it(ui->treeWidget); + while (*it) { + QTreeWidgetItem* item = *it; + int type = item->data(0,Qt::UserRole).toInt(); + if(type != EN_RELAY_DEV && type != EN_RELAY_TREE_CHANL) + { + ++it; + continue; + } + + QString devName; + if(filterType == EN_RELAY_TREE_CHANL) + { + devName = item->text(0); + } + else + { + devName = item->data(0,Qt::UserRole+1).toString(); + } + + if(devName == indexDev) + { + ui->treeWidget->setCurrentItem(item); + treeItemClicked(item,0); + break; + } + ++it; + } +} + +void CRelaySettingWidget::slotDataChanged(const RelayCmdReply &reply,const QString &cmd) +{ + setEnableBtnList(reply.isSuccess); + // if(reply.isSuccess != 1) + { + QMessageBox::warning(this,tr("提示"),reply.resultStr); + } + + if(reply.isSuccess==1) + { + if(cmd == "const_value_read") + { + dealRead(reply); + }else if(cmd == "const_value_edit") + { + dealEdit(reply); + }else if(cmd == "const_value_affirm") + { + dealAffirm(reply); + }else if(cmd == "const_group_edit") + { + dealGroupEdit(reply); + } + } + + setStartCmdState(true); +} + +void CRelaySettingWidget::slotError() +{ + m_enableList =m_enableLastList; + setEnableBtnList(false); + m_requestCmd = ""; + setStartCmdState(true); + QMessageBox::warning(this,tr("提示"),tr("发送命令失败!")); +} diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.h b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.h index 11bb0996..2eb5fb4e 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.h +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.h @@ -1,230 +1,230 @@ -#ifndef CRELAYSETTINGWIDGET_H -#define CRELAYSETTINGWIDGET_H - -#include -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" -#include "CRelaySettingCommon.h" -#include -#include "CRelaySettingMsgMng.h" -#include -#include "sys/sys_login_api/CLoginDlg.h" - -#include "CWorker.h" -#include "CRelayFile.h" -#include "CRelayCommon.h" - -namespace Ui { -class CRelaySettingWidget; -} - -enum EN_RELAY_TYPE -{ - EN_RELAY_LOC = 1001, - EN_RELAY_RTU = 1002, - EN_RELAY_DEV = 1003 -}; - -enum EN_RELAY_TREE_TYPE -{ - EN_RELAY_TREE_LOC = 2001, - EN_RELAY_TREE_CHANL = 20002 -}; - -using namespace kbd_public; -using namespace kbd_service; - -class CRelaySettingWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CRelaySettingWidget(bool editMode, QWidget *parent = 0); - ~CRelaySettingWidget(); - -private: - void initStyleSheet(); - - - void loadLoc(); - - void loadRtu(); - - void loadDev(); - - void loadLocRtuDev(); - - void loadUnit(); - - void loadDict(); - - void loadSetting(); - - void initView(); - - void initTree(); - - void cleanTree(); - - void itemChildClear(QTreeWidgetItem * item); - - void initConn(); - - void brush(); - - void initGroupCmb(); - - void updateGroupCmb(const RelaySetting &relaySetting); - - void insertToTable(RelaySetting relaySetting,int index); - - void insertToTableModbus(RelaySetting relaySetting,int index); - - void initTable(); - - bool getGroupData(RelaySetting &set); - bool getGroupDevice(RelaySetting &set); - - void setStartCmdState(bool isEnable); - - void setEnableBtnList(bool isSuccess); - - void setCtrlBtnEnable(bool isEnable); - - void dealValueReadDownInfo(const QMap &updateData); - - void showValueAndDefaultValue(int dot, float value); - - int findTableIndex(int dot); - - RelaySetting getDataObj(int tableIndex); - - float getActualValue(RelaySetting relaySetting, QString curValue); - - float getValueWithRatio(RelaySetting &relaySetting, float value); - - float getValueWithoutRatio(RelaySetting &relaySetting, float value); - - QString getDisplayValue(RelaySetting &relaySetting, float &value,bool bo); - - bool checkPermCtrl(); - - bool checkAllItemValue(); - - bool checkAllItemValueDefault(); - - bool checkAllItemValueVerify(); - - bool checkUniformity(); - - void getReadData(QList &keyList,QList &valueList,const RelaySetting &relaySetting); - - void getEditData(QList &keyList,QList &valueList,const RelaySetting &relaySetting); - - void getAffirmData(QList &keyList,QList &valueList,const RelaySetting &relaySetting); - - void getGEditData(QList &keyList,QList &valueList,const RelaySetting &relaySetting); - - void dealRead(const RelayCmdReply &reply); - - void dealEdit(const RelayCmdReply &reply); - - void dealAffirm(const RelayCmdReply &reply); - - void dealGroupEdit(const RelayCmdReply &reply); - - void dealValueEditDownInfo(const QMap &updateData); - - void dealValueAffirmDownInfo(const QMap &updateData); - - int getSelectGroup(); - - bool checkCurGroup(int groupNo); - - //modbus - void loadModbusConfig(); - - void loadModbusChanl(); - - void loadModbusGroup(); - - void initModbusData(); - - void initModbusTree(); - - //void insertToTable(const SRelayData & relayData); - -private slots: - void treeItemClicked(QTreeWidgetItem *item, int column); - - void tableItemDoubleClicked(QTableWidgetItem *item); - - void readBtnClicked(); - - void editBtnClicked(); - - void confirmBtnClicked(); - - void clearBtnClicked(); - - void changeGDevClicked(); - -public slots: - void setTreeHidden(bool isHide); - void setFilterGroup(const QString& groupPoints); - void initialize(); - - QString getFesDevByKeyIdTag(const QString& keyIdTag); - - void slotRecvOuttime(); - void slotCurrentIndexChanged(int curIndex); - - void slotDataChanged(const RelayCmdReply &reply,const QString &cmd); - - void slotError(); - - //ModbusTCP - void slotModbusDataChange(QList relayDataList,bool isFaild,QString error); -signals: - void sigcmd(const QList &keyList,const QList &valueList,const RelaySetting &relaySetting,const QString & cmd); - - //ModbusTCP - void sigSearchData(const QList &indexList,int groupNo); -private: - Ui::CRelaySettingWidget *ui; - - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; - CPermMngApiPtr m_permMng; - kbd_public::SNodeInfo m_nodeInfo; - - QMap m_locMap; - QMap m_rtuMap; - QMap m_devMap; - - QMap > > m_locRtuDevMap; - - QMap m_unitMap; - QMap > m_dictMap; - - QList m_setList; - - QString m_clickDev; - - CRelaySettingMsgMng *m_msgMng; - QList m_enableList; - QList m_enableLastList; - - QString m_requestCmd; - - //ModbusTCP - QList< QPair > > m_locChanlList; - QList m_groupList; - - QThread m_workThread; //工作线程 - QList chanlList; - CWorker *m_pWork; - int m_ModbusChannlIndex; - QStringList mFilterDevs; -}; - -#endif // CRELAYSETTINGWIDGET_H +#ifndef CRELAYSETTINGWIDGET_H +#define CRELAYSETTINGWIDGET_H + +#include +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "CRelaySettingCommon.h" +#include +#include "CRelaySettingMsgMng.h" +#include +#include "sys/sys_login_api/CLoginDlg.h" + +#include "CWorker.h" +#include "CRelayFile.h" +#include "CRelayCommon.h" + +namespace Ui { +class CRelaySettingWidget; +} + +enum EN_RELAY_TYPE +{ + EN_RELAY_LOC = 1001, + EN_RELAY_RTU = 1002, + EN_RELAY_DEV = 1003 +}; + +enum EN_RELAY_TREE_TYPE +{ + EN_RELAY_TREE_LOC = 2001, + EN_RELAY_TREE_CHANL = 20002 +}; + +using namespace kbd_public; +using namespace kbd_service; + +class CRelaySettingWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CRelaySettingWidget(bool editMode, QWidget *parent = 0); + ~CRelaySettingWidget(); + +private: + void initStyleSheet(); + + + void loadLoc(); + + void loadRtu(); + + void loadDev(); + + void loadLocRtuDev(); + + void loadUnit(); + + void loadDict(); + + void loadSetting(); + + void initView(); + + void initTree(); + + void cleanTree(); + + void itemChildClear(QTreeWidgetItem * item); + + void initConn(); + + void brush(); + + void initGroupCmb(); + + void updateGroupCmb(const RelaySetting &relaySetting); + + void insertToTable(RelaySetting relaySetting,int index); + + void insertToTableModbus(RelaySetting relaySetting,int index); + + void initTable(); + + bool getGroupData(RelaySetting &set); + bool getGroupDevice(RelaySetting &set); + + void setStartCmdState(bool isEnable); + + void setEnableBtnList(bool isSuccess); + + void setCtrlBtnEnable(bool isEnable); + + void dealValueReadDownInfo(const QMap &updateData); + + void showValueAndDefaultValue(int dot, float value); + + int findTableIndex(int dot); + + RelaySetting getDataObj(int tableIndex); + + float getActualValue(RelaySetting relaySetting, QString curValue); + + float getValueWithRatio(RelaySetting &relaySetting, float value); + + float getValueWithoutRatio(RelaySetting &relaySetting, float value); + + QString getDisplayValue(RelaySetting &relaySetting, float &value,bool bo); + + bool checkPermCtrl(); + + bool checkAllItemValue(); + + bool checkAllItemValueDefault(); + + bool checkAllItemValueVerify(); + + bool checkUniformity(); + + void getReadData(QList &keyList,QList &valueList,const RelaySetting &relaySetting); + + void getEditData(QList &keyList,QList &valueList,const RelaySetting &relaySetting); + + void getAffirmData(QList &keyList,QList &valueList,const RelaySetting &relaySetting); + + void getGEditData(QList &keyList,QList &valueList,const RelaySetting &relaySetting); + + void dealRead(const RelayCmdReply &reply); + + void dealEdit(const RelayCmdReply &reply); + + void dealAffirm(const RelayCmdReply &reply); + + void dealGroupEdit(const RelayCmdReply &reply); + + void dealValueEditDownInfo(const QMap &updateData); + + void dealValueAffirmDownInfo(const QMap &updateData); + + int getSelectGroup(); + + bool checkCurGroup(int groupNo); + + //modbus + void loadModbusConfig(); + + void loadModbusChanl(); + + void loadModbusGroup(); + + void initModbusData(); + + void initModbusTree(); + + //void insertToTable(const SRelayData & relayData); + +private slots: + void treeItemClicked(QTreeWidgetItem *item, int column); + + void tableItemDoubleClicked(QTableWidgetItem *item); + + void readBtnClicked(); + + void editBtnClicked(); + + void confirmBtnClicked(); + + void clearBtnClicked(); + + void changeGDevClicked(); + +public slots: + void setTreeHidden(bool isHide); + void setFilterGroup(const QString& groupPoints); + void initialize(); + + QString getFesDevByKeyIdTag(const QString& keyIdTag); + + void slotRecvOuttime(); + void slotCurrentIndexChanged(int curIndex); + + void slotDataChanged(const RelayCmdReply &reply,const QString &cmd); + + void slotError(); + + //ModbusTCP + void slotModbusDataChange(QList relayDataList,bool isFaild,QString error); +signals: + void sigcmd(const QList &keyList,const QList &valueList,const RelaySetting &relaySetting,const QString & cmd); + + //ModbusTCP + void sigSearchData(const QList &indexList,int groupNo); +private: + Ui::CRelaySettingWidget *ui; + + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; + CPermMngApiPtr m_permMng; + kbd_public::SNodeInfo m_nodeInfo; + + QMap m_locMap; + QMap m_rtuMap; + QMap m_devMap; + + QMap > > m_locRtuDevMap; + + QMap m_unitMap; + QMap > m_dictMap; + + QList m_setList; + + QString m_clickDev; + + CRelaySettingMsgMng *m_msgMng; + QList m_enableList; + QList m_enableLastList; + + QString m_requestCmd; + + //ModbusTCP + QList< QPair > > m_locChanlList; + QList m_groupList; + + QThread m_workThread; //工作线程 + QList chanlList; + CWorker *m_pWork; + int m_ModbusChannlIndex; + QStringList mFilterDevs; +}; + +#endif // CRELAYSETTINGWIDGET_H diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.ui b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.ui index b08c2baf..d05818a3 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.ui +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.ui @@ -1,281 +1,281 @@ - - - CRelaySettingWidget - - - - 0 - 0 - 1019 - 593 - - - - 保护定值管理 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - Qt::Horizontal - - - - true - - - - 位置/通道/前置设备 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 切换 - - - - - - - 当前执行组: - - - - - - - 前置设备 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - - - - Qt::AlignCenter - - - - - - - - - - QAbstractItemView::SelectRows - - - - 序号 - - - - - 定值名称 - - - - - 定值组号 - - - - - 当前值 - - - - - 预置值 - - - - - 返校值 - - - - - 范围 - - - - - 单位 - - - - - 定值代号 - - - - - isError - - - - - - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - 0 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 读取 - - - - - - - 修改 - - - - - - - 确认 - - - - - - - 清空 - - - - - - - - - - - - - - - + + + CRelaySettingWidget + + + + 0 + 0 + 1019 + 593 + + + + 保护定值管理 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Horizontal + + + + true + + + + 位置/通道/前置设备 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 切换 + + + + + + + 当前执行组: + + + + + + + 前置设备 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + + + Qt::AlignCenter + + + + + + + + + + QAbstractItemView::SelectRows + + + + 序号 + + + + + 定值名称 + + + + + 定值组号 + + + + + 当前值 + + + + + 预置值 + + + + + 返校值 + + + + + 范围 + + + + + 单位 + + + + + 定值代号 + + + + + isError + + + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 读取 + + + + + + + 修改 + + + + + + + 确认 + + + + + + + 清空 + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/RelaySettingWidget/CWorker.cpp b/product/src/gui/plugin/RelaySettingWidget/CWorker.cpp index 46248bb8..f0249c4f 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CWorker.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CWorker.cpp @@ -1,96 +1,96 @@ -#include "CWorker.h" -#include "CRelaySettingCommon.h" -#include -#include -#include "CLogMng.h" - -CWorker::CWorker(QObject *parent): - QObject(parent) -{ - qRegisterMetaType >("QList"); -} - -void CWorker::init() -{ - qDebug()<<"cworker init()"; -} - -void CWorker::slotSearch(const QList &indexList, int groupNo) -{ - qDebug()<<"slotSearch"; - - CLogMng::Instance()->WriteLog("slotSearch 1"); - - - QList relayDataList; - relayDataList.clear(); - bool isFaild = false; - QString error = ""; - - for(int i=0;iWriteLog("slotSearch 2"); - int ret= m_modbus.readDz(indexList[i],groupNo,m_chanlParmList[indexList[i]].dzstr,&m_chanlParmList[indexList[i]].readNum); - - CLogMng::Instance()->WriteLog("slotSearch 3"); - - QString chanName =m_modbus.m_chanllist[indexList[i]].chanlDesc; - - if(ret ==5) - { - for(int j=0; jWriteLog("slotSearch 4"); - emit sigDataChange(relayDataList,isFaild,error); - - CLogMng::Instance()->WriteLog("slotSearch 5"); -} +#include "CWorker.h" +#include "CRelaySettingCommon.h" +#include +#include +#include "CLogMng.h" + +CWorker::CWorker(QObject *parent): + QObject(parent) +{ + qRegisterMetaType >("QList"); +} + +void CWorker::init() +{ + qDebug()<<"cworker init()"; +} + +void CWorker::slotSearch(const QList &indexList, int groupNo) +{ + qDebug()<<"slotSearch"; + + CLogMng::Instance()->WriteLog("slotSearch 1"); + + + QList relayDataList; + relayDataList.clear(); + bool isFaild = false; + QString error = ""; + + for(int i=0;iWriteLog("slotSearch 2"); + int ret= m_modbus.readDz(indexList[i],groupNo,m_chanlParmList[indexList[i]].dzstr,&m_chanlParmList[indexList[i]].readNum); + + CLogMng::Instance()->WriteLog("slotSearch 3"); + + QString chanName =m_modbus.m_chanllist[indexList[i]].chanlDesc; + + if(ret ==5) + { + for(int j=0; jWriteLog("slotSearch 4"); + emit sigDataChange(relayDataList,isFaild,error); + + CLogMng::Instance()->WriteLog("slotSearch 5"); +} diff --git a/product/src/gui/plugin/RelaySettingWidget/CWorker.h b/product/src/gui/plugin/RelaySettingWidget/CWorker.h index 966394ed..ba8c7a18 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CWorker.h +++ b/product/src/gui/plugin/RelaySettingWidget/CWorker.h @@ -1,32 +1,32 @@ -#ifndef CWORKER_H -#define CWORKER_H - -#include -#include "CRelayCommon.h" -#include -#include "ModbusTCP.h" -#include "publicpara.h" -#include "CRelaySettingCommon.h" - -class CWorker : public QObject -{ - Q_OBJECT - -public: - CWorker(QObject *parent = nullptr); - - void init(); - -signals: - void sigDataChange(QList relayDataList,bool isFaild,QString error); - -public slots: - void slotSearch(const QList &indexList,int groupNo); - -private: - ModbusTcpm m_modbus; - CHANPARA_ m_chanlParmList[CHAN_MAX_NUM]; - -}; - -#endif // CWORKER_H +#ifndef CWORKER_H +#define CWORKER_H + +#include +#include "CRelayCommon.h" +#include +#include "ModbusTCP.h" +#include "publicpara.h" +#include "CRelaySettingCommon.h" + +class CWorker : public QObject +{ + Q_OBJECT + +public: + CWorker(QObject *parent = nullptr); + + void init(); + +signals: + void sigDataChange(QList relayDataList,bool isFaild,QString error); + +public slots: + void slotSearch(const QList &indexList,int groupNo); + +private: + ModbusTcpm m_modbus; + CHANPARA_ m_chanlParmList[CHAN_MAX_NUM]; + +}; + +#endif // CWORKER_H diff --git a/product/src/gui/plugin/RelaySettingWidget/ModbusTCP.cpp b/product/src/gui/plugin/RelaySettingWidget/ModbusTCP.cpp index 0c0c2521..7da42852 100644 --- a/product/src/gui/plugin/RelaySettingWidget/ModbusTCP.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/ModbusTCP.cpp @@ -1,560 +1,560 @@ -//处理的方法有一点特殊,在数据库中增加一个MODBUS配置表,记录的是要发送的命令以及刷新周期,读表时按序号排序并给每一条记录排号 -//与遥测遥信的对应关系是:对于同一个地址的测量设备的记录,遥测时记录在前的放在前 -//比如:同是一号地址的两条03命令码记录前一条记录长度为8各,后一条记录的长度4个,那么前一条记录对应的遥测号为0-7,后一条记录 -//对应的遥测号为8-11,遥信时记录在前的也放在前,但有一点需特别注意,如果前一条记录长度不为8的倍数,那么后一条记录 -//对应的遥信号也要从8的倍数开始 - -//#include - -#include -//#include -#include "ModbusTCP.h" -#include -#include -#include -#include -#include "CRelayFile.h" -#include -#include -#include -#include -#include -#include "CLogMng.h" - - -#ifdef WIN32 - -#include -#include -#define in_addr_t unsigned long -#define SHUT_RDWR 2 -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif -#define socklen_t int -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef int SOCKET; -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define closesocket close -#define ioctlsocket ioctl -#endif - - -ModbusTcpm::ModbusTcpm() -{ - int i = 0; - for(i=0;iWriteLog(log); - } - - -ModbusTcpm::~ModbusTcpm() -{ - -} - -void ModbusTcpm::GetChanlParaInfo() -{ - for(int i=0; i< m_chanllist.count();i++) - { - if(i >= CHAN_MAX_NUM) - { - break; - } - - chClient[i].port = m_chanllist[i].port; - if(m_chanllist[i].ip.length() < 20) - { - strcpy(chClient[i].ipAddr,m_chanllist[i].ip.toStdString().c_str()); - } - - - chClient[i].Addr = m_chanllist[i].chanlAddr; - strcpy(chClient[i].paraFileName,m_chanllist[i].paraFileName.toStdString().c_str()); - strcpy(chClient[i].blockFileName,m_chanllist[i].blockFileName.toStdString().c_str()); - - chClient[i].chanFlag = true; - } - chanNum=m_chanllist.count(); - -} - - - -void ModbusTcpm::GetDzBlockParaInfo(int tdNo) -{ - - chClient[tdNo].DzBlockNum = 0; - - //name - QString blockFileName =chClient[tdNo].blockFileName; - - CRelayFile relayFile ; - m_blocklist= relayFile.getBlockList(blockFileName); - for(int i=0; i< m_blocklist.count();i++) - { - if(chClient[tdNo].DzBlockNum > BLOCK_MAX_NUM ) - { - return; - } - - chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].chNo = tdNo; - chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].FunCode = m_blocklist[i].funcNo; - chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].StartAddr = m_blocklist[i].startAddr; - chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].RegisterLen = m_blocklist[i].registerLen; - chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].DzBlockChagFlag = m_blocklist[i].blockChangeFlag; - chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].isFlag = true; - chClient[tdNo].DzBlockNum++; - } - -} - -void ModbusTcpm::GetDzBlockParaInfo() -{ - CRelayFile File ; - m_chanllist= File.getChanlList(); - - // m_blocklist= File.getBlockList(); - - // m_paralist = File.getParaList(); -} - -void ModbusTcpm::GetDzInfo(int tdNo) -{ - - chClient[tdNo].dzNum = 0; - QString paraFileName =chClient[tdNo].paraFileName; - CRelayFile relayFile ; - m_paralist= relayFile.getParaList(paraFileName); - - for(int i=0; i< m_paralist.count();i++) - { - - if(chClient[tdNo].dzNum > DZ_DATA_MAX_NUM ) - { - return; - } - - chClient[tdNo].dzstr[chClient[tdNo].dzNum].chNo = tdNo; - chClient[tdNo].dzstr[chClient[tdNo].dzNum].pAddr = m_paralist[i].pAddr; - - - if(m_paralist[i].name.length() < DZ_NAME_LEN) - { - strcpy( chClient[tdNo].dzstr[chClient[tdNo].dzNum].dzName,m_paralist[i].name.toStdString().c_str()); - } - - chClient[tdNo].dzstr[chClient[tdNo].dzNum].pAddr = m_paralist[i].pAddr; - chClient[tdNo].dzstr[chClient[tdNo].dzNum].BoardNo = m_paralist[i].boardNo; - chClient[tdNo].dzstr[chClient[tdNo].dzNum].PointNo = m_paralist[i].pointNo; - chClient[tdNo].dzstr[chClient[tdNo].dzNum].Modulus = m_paralist[i].modulus; - - chClient[tdNo].dzstr[chClient[tdNo].dzNum].Revise = m_paralist[i].revise; - chClient[tdNo].dzstr[chClient[tdNo].dzNum].ValueType = m_paralist[i].valueType; - - chClient[tdNo].dzstr[chClient[tdNo].dzNum].glFlag = m_paralist[i].glFlag; - chClient[tdNo].dzstr[chClient[tdNo].dzNum].timeFlag = m_paralist[i].timeFlag; - chClient[tdNo].dzstr[chClient[tdNo].dzNum].isFlag = true; - chClient[tdNo].dzNum++; - } - -} - -void ModbusTcpm::NewConnectVar(int chNo) -{ - chClient[chNo].SendCount = 0; - chClient[chNo].RcvCount = 0; -} - -bool ModbusTcpm::QueryModbus(int chNo,BYTE Addr,BYTE FunCode,ushort StartAddr,ushort Len) -{ - BYTE Data[500]; - bool flag = false; - Data[0] = 0; //事务处理标识符 - Data[1] = 0; //事务处理标识符 - Data[2] = 0; //协议标识符 - Data[3] = 0; //协议标识符 - Data[4] = 0; - Data[5] = 6; - Data[6] = Addr; - Data[7] = FunCode; - Data[8] = (BYTE)(StartAddr >> 8); - Data[9] = (BYTE)StartAddr; - Data[10] = (BYTE)(Len >> 8); - Data[11] = (BYTE)Len; - flag = SendData(chNo,Data,12); - - QString log="send 12: "; - for(int i=0;i<12;i++) - { - log += QString("%1 ").arg(Data[i],2,16,QChar('0')); - - } - writelog(log); - return flag; -} - -bool ModbusTcpm::RcvModBus(int chNo,int Addr,int FunCode,int Len,BYTE *zData) -{ - int TempLen=0,i,RcvLen=0,j; - BYTE RcvTempData[1025],bdata[1025]; - int rxn; - - for(i = 0;i < 10;i ++) - { - if((!chClient[chNo].clientIsOk) || (chClient[chNo].m_Sock < 1)) - return false; - - // QThread::Sleep(10); - QThread::msleep(10); - RcvLen=0; - - #ifdef OS_WINDOWS - rxn = recv(chClient[chNo].m_Sock,(char *)bdata,1024,0); - #else - rxn = recv(chClient[chNo].m_Sock,(char *)bdata,1024,MSG_DONTWAIT); - #endif - - // rxn = recv(chClient[chNo].m_Sock,(char *)bdata,1024,0); - - if(rxn == -1) - { - //int err = GetLastError(); - //if( (err == WSAEINTR)||(err == WSAEWOULDBLOCK) ) - // rxn = 0; - continue; - } - RcvLen = rxn; - if(RcvLen > 0) - { - for(j = 0; j < RcvLen; j ++) - RcvTempData[TempLen+j] = bdata[j]; - TempLen += RcvLen; - } - if(TempLen >= Len) - break; - } - - QString log= QString("recv %1 :").arg(TempLen); - for(int i=0;i Len )//接收错帧 - { - log = QString("lenght error;correct length: %1").arg(Len); - writelog(log); - return false; - } - else - if((RcvTempData[6] == Addr)&&(RcvTempData[7] == FunCode)) - { - for(j = 0;j < Len;j ++) - zData[j] = RcvTempData[j]; - return true; - } - - log = QString("lenght error;correct length: %1").arg(Len); - writelog(log); - - return false; -} - -bool ModbusTcpm::SendData(int chNo,BYTE *Data,int Len) -{ - if(!chClient[chNo].clientIsOk) - return false; - if(chClient[chNo].m_Sock < 1) return false; - int txn = -1; - - //txn = send(chClient[chNo].m_Sock,(char *)Data,Len,0); - -#ifdef OS_WINDOWS - txn = ::send(chClient[chNo].m_Sock , (char *)Data, Len, 0); -#else - txn = ::send(chClient[chNo].m_Sock , (char *)Data , Len , MSG_NOSIGNAL); -#endif - - if(txn==SOCKET_ERROR) - { - //int err = GetLastError(); - return false; - } - return true; -} - -int ModbusTcpm::CreateSocket(int chNo) -{ - chClient[chNo].m_Sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - if(chClient[chNo].m_Sock<0) - { - return false; - } - int temp = 1000; - setsockopt(chClient[chNo].m_Sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&temp,sizeof(temp)); - setsockopt(chClient[chNo].m_Sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&temp,sizeof(temp)); - - return true; -} - -bool ModbusTcpm::ConnectServer(int chNo) -{ - NewConnectVar(chNo); - in_addr addr; - addr.s_addr = inet_addr(chClient[chNo].ipAddr); - if(addr.s_addr == INADDR_NONE) - return false; - - struct sockaddr_in m_SendAddr; - m_SendAddr.sin_family = AF_INET; - m_SendAddr.sin_port = htons(chClient[chNo].port); - m_SendAddr.sin_addr = addr; - if(CreateSocket(chNo)==false) - { - Close_Socket(chNo); - return false; - } - - //set as non_blocking sock - // unsigned long block_flag = true; - // ioctlsocket(chClient[chNo].m_Sock,FIONBIO,&block_flag); - - if(connect(chClient[chNo].m_Sock,(struct sockaddr *)&m_SendAddr,sizeof(m_SendAddr))<0) - { - //注意:对于有多线程的进程,errno作为全局变量是被多个线程 - //共享的,因此应当立即保存当前的错误码,以免被其它线程修改 - - -#ifdef WIN32//UNIX下有多线程经常把get_last_error()改变,索性不管 - int err = GetLastError(); - if(err==WSAEISCONN) - return TRUE; - if((err==WSAEINPROGRESS)||(err==WSAEWOULDBLOCK)||(err==WSAEINTR)) -#endif - { - struct timeval tmptv; - tmptv.tv_sec=5; - tmptv.tv_usec=0; - fd_set rfd,wfd;//using rfd for compability with posix.1g and BSD. - FD_ZERO(&rfd);FD_ZERO(&wfd); - int my_sock = chClient[chNo].m_Sock; - if(my_sock<0) - { - Close_Socket(chNo); - return false; - } - FD_SET(my_sock,&rfd);FD_SET(my_sock,&wfd); - int ret = select(my_sock+1,&rfd,&wfd,0,&tmptv); - if(ret>0) - { - if( FD_ISSET(my_sock,&rfd)||FD_ISSET(my_sock,&wfd) ) - { - int error = 0; - socklen_t len = sizeof(error); - if( ( getsockopt(my_sock,SOL_SOCKET,SO_ERROR,(char*)&error,(socklen_t*)&len)>=0 ) - //solaris pending error:return 0 with an eeor - &&(!error)//BSD:getsockopt() return 0,but error exists - ) - { - //不存在IP也是这种情况 - // chClient[chNo].clientIsOk = true; - // return true; - } - } - } - } - Close_Socket(chNo); - return false; - } - chClient[chNo].clientIsOk = true; - return true; -} - -void ModbusTcpm::Close_Socket(int chNo) -{ - if(chClient[chNo].m_Sock <= 0 ) - { - chClient[chNo].m_Sock = -1; - return; - } - closesocket(chClient[chNo].m_Sock); - chClient[chNo].m_Sock = -1; -} - -int ModbusTcpm::readDz(int chNo,int group,DZSTR *readDzStr,int *readDzNum) -{ - if ( nullptr == readDzStr || nullptr == readDzNum ) - return 13;//没有配置定值点 - - uint DWordData,DWordData1,DWordData2; - int StartAddr,StartAddr1,Len1,FunCode,Addr,i,j; - int RegNo,ValueType,IntData; - float WriteValue; - int flag = 0,dzCodeNo,rDzNum; - - BYTE Data[500]; - ushort DzBoardNo; - - if(chClient[chNo].DzBlockNum < 1) return 9; //没有数据块就退出读定值过程 - if(chClient[chNo].dzNum < 1) return 13; //没有配置保护定值点 - - if(!ConnectServer(chNo)) - { - writelog(QString("%1 连接失败!").arg(chClient[chNo].ipAddr)); - return 10; - } - - if(group) - { - StartAddr = 0xD080; //D080 - StartAddr1 = 0xD000; //D000 - } - else - { - StartAddr = 0x2080; //D080 - StartAddr1 = 0x2000; //D000 - } - - Addr = chClient[chNo].Addr; - rDzNum = 0; - for(i = 0; i < chClient[chNo].DzBlockNum; i ++) - { - if(chClient[chNo].DzBlock[i].chNo != chNo) - continue; - FunCode = 0x06; - DzBoardNo = chClient[chNo].DzBlock[i].StartAddr; //保护定值组编号 - - QueryModbus(chNo,Addr,FunCode,StartAddr,DzBoardNo); - if(RcvModBus(chNo,Addr,FunCode,12,Data)) - {//1 - FunCode = 0x03; - Len1=0x7d; - // Len1=0x50; - //printf("取定值数据...\n"); - QueryModbus(chNo,Addr,FunCode,StartAddr1,Len1); - if(RcvModBus(chNo,Addr,FunCode,2*Len1+9,Data)) - {//2 - dzCodeNo = (Data[3+6]<<8) | Data[4+6]; - if(dzCodeNo != DzBoardNo)//当返回的定值组号和读取时的定值组号一致,表示定值修改成功 - { - if(flag==1) - { - flag=2; - writelog("flag=2"); - } - // printf("定值块%d定值读取失败!读取块地址%d,返回块地址%d\n",i+1,Len,dzCodeNo); - QString mes= QString("DzBoardNo = %1 dzCodeNo: %2").arg(DzBoardNo).arg(dzCodeNo); - writelog(mes); - continue; - } - writelog("DzBoardNo OK!"); - for(j = 0; j < chClient[chNo].DzBlock[i].RegisterLen; j ++) //解析每一个定值(RegisterLen:每组定值的个数) - { - for(RegNo=0; RegNo < chClient[chNo].dzNum; RegNo ++) - { - if((chClient[chNo].dzstr[RegNo].chNo != chNo)||(chClient[chNo].dzstr[RegNo].BoardNo != DzBoardNo)) - continue;//当定值组号和定值组里的定值序号对应时,才更新定值数据 - - - if(chClient[chNo].dzstr[RegNo].PointNo == j) - { - if( flag == 0) - { - flag = 1; - writelog("flag=1"); - } - - DWordData = Data[4*j+5+6]; DWordData<<=24; - DWordData1 = Data[4*j+6+6]; DWordData1<<=16; - DWordData2 = Data[4*j+7+6]; DWordData2<<=8; - DWordData = DWordData+DWordData1+DWordData2+Data[4*j+8+6]; - //printf("d1=%d d2=%d d3=%d d4=%d\n",Data[4*j+5],Data[4*j+6],Data[4*j+7],Data[4*j+8]); - - ValueType = chClient[chNo].dzstr[RegNo].ValueType; - if(ValueType == 0) - WriteValue = (float)DWordData;//无符号 - else if(ValueType == 2)//浮点型 - { - memcpy(&WriteValue,&DWordData,sizeof(float)); - if(WriteValue != WriteValue) - WriteValue = 0; - } - else - { - IntData = DWordData; - WriteValue = (float)IntData; - }//有符号 - chClient[chNo].dzstr[RegNo].fValue = WriteValue*chClient[chNo].dzstr[RegNo].Modulus + chClient[chNo].dzstr[RegNo].Revise; - readDzStr[rDzNum].BoardNo = chClient[chNo].dzstr[RegNo].BoardNo; - readDzStr[rDzNum].PointNo = chClient[chNo].dzstr[RegNo].PointNo; - readDzStr[rDzNum].fValue = chClient[chNo].dzstr[RegNo].fValue; - strcpy(readDzStr[rDzNum].dzName,chClient[chNo].dzstr[RegNo].dzName); - readDzStr[rDzNum].chNo = chNo; - readDzStr[rDzNum].glFlag = chClient[chNo].dzstr[RegNo].glFlag; - readDzStr[rDzNum].timeFlag = chClient[chNo].dzstr[RegNo].timeFlag; - rDzNum ++; - break; - } - } - } - }//2 - }//1 - } - - *readDzNum = rDzNum; - Close_Socket(chNo); - if(flag == 1) - { - // readDzSig(dzstr,dzNum,5); - return 5;//定值读取成功 - } - else if(flag == 2) - { - // readDzSig(dzstr,dzNum,16); - return 16;//部分定值读取成功 - } - - return 6;//定值读取失败 -} - -int ModbusTcpm::setDz(int chNo,MOD_DZ_STR *mstr,int ModDzNum) -{ - - Q_UNUSED(chNo); - Q_UNUSED(mstr); - Q_UNUSED(ModDzNum); - return 7; //定值修改失败 -} +//处理的方法有一点特殊,在数据库中增加一个MODBUS配置表,记录的是要发送的命令以及刷新周期,读表时按序号排序并给每一条记录排号 +//与遥测遥信的对应关系是:对于同一个地址的测量设备的记录,遥测时记录在前的放在前 +//比如:同是一号地址的两条03命令码记录前一条记录长度为8各,后一条记录的长度4个,那么前一条记录对应的遥测号为0-7,后一条记录 +//对应的遥测号为8-11,遥信时记录在前的也放在前,但有一点需特别注意,如果前一条记录长度不为8的倍数,那么后一条记录 +//对应的遥信号也要从8的倍数开始 + +//#include + +#include +//#include +#include "ModbusTCP.h" +#include +#include +#include +#include +#include "CRelayFile.h" +#include +#include +#include +#include +#include +#include "CLogMng.h" + + +#ifdef WIN32 + +#include +#include +#define in_addr_t unsigned long +#define SHUT_RDWR 2 +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif +#define socklen_t int +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef int SOCKET; +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define closesocket close +#define ioctlsocket ioctl +#endif + + +ModbusTcpm::ModbusTcpm() +{ + int i = 0; + for(i=0;iWriteLog(log); + } + + +ModbusTcpm::~ModbusTcpm() +{ + +} + +void ModbusTcpm::GetChanlParaInfo() +{ + for(int i=0; i< m_chanllist.count();i++) + { + if(i >= CHAN_MAX_NUM) + { + break; + } + + chClient[i].port = m_chanllist[i].port; + if(m_chanllist[i].ip.length() < 20) + { + strcpy(chClient[i].ipAddr,m_chanllist[i].ip.toStdString().c_str()); + } + + + chClient[i].Addr = m_chanllist[i].chanlAddr; + strcpy(chClient[i].paraFileName,m_chanllist[i].paraFileName.toStdString().c_str()); + strcpy(chClient[i].blockFileName,m_chanllist[i].blockFileName.toStdString().c_str()); + + chClient[i].chanFlag = true; + } + chanNum=m_chanllist.count(); + +} + + + +void ModbusTcpm::GetDzBlockParaInfo(int tdNo) +{ + + chClient[tdNo].DzBlockNum = 0; + + //name + QString blockFileName =chClient[tdNo].blockFileName; + + CRelayFile relayFile ; + m_blocklist= relayFile.getBlockList(blockFileName); + for(int i=0; i< m_blocklist.count();i++) + { + if(chClient[tdNo].DzBlockNum > BLOCK_MAX_NUM ) + { + return; + } + + chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].chNo = tdNo; + chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].FunCode = m_blocklist[i].funcNo; + chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].StartAddr = m_blocklist[i].startAddr; + chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].RegisterLen = m_blocklist[i].registerLen; + chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].DzBlockChagFlag = m_blocklist[i].blockChangeFlag; + chClient[tdNo].DzBlock[chClient[tdNo].DzBlockNum].isFlag = true; + chClient[tdNo].DzBlockNum++; + } + +} + +void ModbusTcpm::GetDzBlockParaInfo() +{ + CRelayFile File ; + m_chanllist= File.getChanlList(); + + // m_blocklist= File.getBlockList(); + + // m_paralist = File.getParaList(); +} + +void ModbusTcpm::GetDzInfo(int tdNo) +{ + + chClient[tdNo].dzNum = 0; + QString paraFileName =chClient[tdNo].paraFileName; + CRelayFile relayFile ; + m_paralist= relayFile.getParaList(paraFileName); + + for(int i=0; i< m_paralist.count();i++) + { + + if(chClient[tdNo].dzNum > DZ_DATA_MAX_NUM ) + { + return; + } + + chClient[tdNo].dzstr[chClient[tdNo].dzNum].chNo = tdNo; + chClient[tdNo].dzstr[chClient[tdNo].dzNum].pAddr = m_paralist[i].pAddr; + + + if(m_paralist[i].name.length() < DZ_NAME_LEN) + { + strcpy( chClient[tdNo].dzstr[chClient[tdNo].dzNum].dzName,m_paralist[i].name.toStdString().c_str()); + } + + chClient[tdNo].dzstr[chClient[tdNo].dzNum].pAddr = m_paralist[i].pAddr; + chClient[tdNo].dzstr[chClient[tdNo].dzNum].BoardNo = m_paralist[i].boardNo; + chClient[tdNo].dzstr[chClient[tdNo].dzNum].PointNo = m_paralist[i].pointNo; + chClient[tdNo].dzstr[chClient[tdNo].dzNum].Modulus = m_paralist[i].modulus; + + chClient[tdNo].dzstr[chClient[tdNo].dzNum].Revise = m_paralist[i].revise; + chClient[tdNo].dzstr[chClient[tdNo].dzNum].ValueType = m_paralist[i].valueType; + + chClient[tdNo].dzstr[chClient[tdNo].dzNum].glFlag = m_paralist[i].glFlag; + chClient[tdNo].dzstr[chClient[tdNo].dzNum].timeFlag = m_paralist[i].timeFlag; + chClient[tdNo].dzstr[chClient[tdNo].dzNum].isFlag = true; + chClient[tdNo].dzNum++; + } + +} + +void ModbusTcpm::NewConnectVar(int chNo) +{ + chClient[chNo].SendCount = 0; + chClient[chNo].RcvCount = 0; +} + +bool ModbusTcpm::QueryModbus(int chNo,BYTE Addr,BYTE FunCode,ushort StartAddr,ushort Len) +{ + BYTE Data[500]; + bool flag = false; + Data[0] = 0; //事务处理标识符 + Data[1] = 0; //事务处理标识符 + Data[2] = 0; //协议标识符 + Data[3] = 0; //协议标识符 + Data[4] = 0; + Data[5] = 6; + Data[6] = Addr; + Data[7] = FunCode; + Data[8] = (BYTE)(StartAddr >> 8); + Data[9] = (BYTE)StartAddr; + Data[10] = (BYTE)(Len >> 8); + Data[11] = (BYTE)Len; + flag = SendData(chNo,Data,12); + + QString log="send 12: "; + for(int i=0;i<12;i++) + { + log += QString("%1 ").arg(Data[i],2,16,QChar('0')); + + } + writelog(log); + return flag; +} + +bool ModbusTcpm::RcvModBus(int chNo,int Addr,int FunCode,int Len,BYTE *zData) +{ + int TempLen=0,i,RcvLen=0,j; + BYTE RcvTempData[1025],bdata[1025]; + int rxn; + + for(i = 0;i < 10;i ++) + { + if((!chClient[chNo].clientIsOk) || (chClient[chNo].m_Sock < 1)) + return false; + + // QThread::Sleep(10); + QThread::msleep(10); + RcvLen=0; + + #ifdef OS_WINDOWS + rxn = recv(chClient[chNo].m_Sock,(char *)bdata,1024,0); + #else + rxn = recv(chClient[chNo].m_Sock,(char *)bdata,1024,MSG_DONTWAIT); + #endif + + // rxn = recv(chClient[chNo].m_Sock,(char *)bdata,1024,0); + + if(rxn == -1) + { + //int err = GetLastError(); + //if( (err == WSAEINTR)||(err == WSAEWOULDBLOCK) ) + // rxn = 0; + continue; + } + RcvLen = rxn; + if(RcvLen > 0) + { + for(j = 0; j < RcvLen; j ++) + RcvTempData[TempLen+j] = bdata[j]; + TempLen += RcvLen; + } + if(TempLen >= Len) + break; + } + + QString log= QString("recv %1 :").arg(TempLen); + for(int i=0;i Len )//接收错帧 + { + log = QString("lenght error;correct length: %1").arg(Len); + writelog(log); + return false; + } + else + if((RcvTempData[6] == Addr)&&(RcvTempData[7] == FunCode)) + { + for(j = 0;j < Len;j ++) + zData[j] = RcvTempData[j]; + return true; + } + + log = QString("lenght error;correct length: %1").arg(Len); + writelog(log); + + return false; +} + +bool ModbusTcpm::SendData(int chNo,BYTE *Data,int Len) +{ + if(!chClient[chNo].clientIsOk) + return false; + if(chClient[chNo].m_Sock < 1) return false; + int txn = -1; + + //txn = send(chClient[chNo].m_Sock,(char *)Data,Len,0); + +#ifdef OS_WINDOWS + txn = ::send(chClient[chNo].m_Sock , (char *)Data, Len, 0); +#else + txn = ::send(chClient[chNo].m_Sock , (char *)Data , Len , MSG_NOSIGNAL); +#endif + + if(txn==SOCKET_ERROR) + { + //int err = GetLastError(); + return false; + } + return true; +} + +int ModbusTcpm::CreateSocket(int chNo) +{ + chClient[chNo].m_Sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + if(chClient[chNo].m_Sock<0) + { + return false; + } + int temp = 1000; + setsockopt(chClient[chNo].m_Sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&temp,sizeof(temp)); + setsockopt(chClient[chNo].m_Sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&temp,sizeof(temp)); + + return true; +} + +bool ModbusTcpm::ConnectServer(int chNo) +{ + NewConnectVar(chNo); + in_addr addr; + addr.s_addr = inet_addr(chClient[chNo].ipAddr); + if(addr.s_addr == INADDR_NONE) + return false; + + struct sockaddr_in m_SendAddr; + m_SendAddr.sin_family = AF_INET; + m_SendAddr.sin_port = htons(chClient[chNo].port); + m_SendAddr.sin_addr = addr; + if(CreateSocket(chNo)==false) + { + Close_Socket(chNo); + return false; + } + + //set as non_blocking sock + // unsigned long block_flag = true; + // ioctlsocket(chClient[chNo].m_Sock,FIONBIO,&block_flag); + + if(connect(chClient[chNo].m_Sock,(struct sockaddr *)&m_SendAddr,sizeof(m_SendAddr))<0) + { + //注意:对于有多线程的进程,errno作为全局变量是被多个线程 + //共享的,因此应当立即保存当前的错误码,以免被其它线程修改 + + +#ifdef WIN32//UNIX下有多线程经常把get_last_error()改变,索性不管 + int err = GetLastError(); + if(err==WSAEISCONN) + return TRUE; + if((err==WSAEINPROGRESS)||(err==WSAEWOULDBLOCK)||(err==WSAEINTR)) +#endif + { + struct timeval tmptv; + tmptv.tv_sec=5; + tmptv.tv_usec=0; + fd_set rfd,wfd;//using rfd for compability with posix.1g and BSD. + FD_ZERO(&rfd);FD_ZERO(&wfd); + int my_sock = chClient[chNo].m_Sock; + if(my_sock<0) + { + Close_Socket(chNo); + return false; + } + FD_SET(my_sock,&rfd);FD_SET(my_sock,&wfd); + int ret = select(my_sock+1,&rfd,&wfd,0,&tmptv); + if(ret>0) + { + if( FD_ISSET(my_sock,&rfd)||FD_ISSET(my_sock,&wfd) ) + { + int error = 0; + socklen_t len = sizeof(error); + if( ( getsockopt(my_sock,SOL_SOCKET,SO_ERROR,(char*)&error,(socklen_t*)&len)>=0 ) + //solaris pending error:return 0 with an eeor + &&(!error)//BSD:getsockopt() return 0,but error exists + ) + { + //不存在IP也是这种情况 + // chClient[chNo].clientIsOk = true; + // return true; + } + } + } + } + Close_Socket(chNo); + return false; + } + chClient[chNo].clientIsOk = true; + return true; +} + +void ModbusTcpm::Close_Socket(int chNo) +{ + if(chClient[chNo].m_Sock <= 0 ) + { + chClient[chNo].m_Sock = -1; + return; + } + closesocket(chClient[chNo].m_Sock); + chClient[chNo].m_Sock = -1; +} + +int ModbusTcpm::readDz(int chNo,int group,DZSTR *readDzStr,int *readDzNum) +{ + if ( nullptr == readDzStr || nullptr == readDzNum ) + return 13;//没有配置定值点 + + uint DWordData,DWordData1,DWordData2; + int StartAddr,StartAddr1,Len1,FunCode,Addr,i,j; + int RegNo,ValueType,IntData; + float WriteValue; + int flag = 0,dzCodeNo,rDzNum; + + BYTE Data[500]; + ushort DzBoardNo; + + if(chClient[chNo].DzBlockNum < 1) return 9; //没有数据块就退出读定值过程 + if(chClient[chNo].dzNum < 1) return 13; //没有配置保护定值点 + + if(!ConnectServer(chNo)) + { + writelog(QString("%1 连接失败!").arg(chClient[chNo].ipAddr)); + return 10; + } + + if(group) + { + StartAddr = 0xD080; //D080 + StartAddr1 = 0xD000; //D000 + } + else + { + StartAddr = 0x2080; //D080 + StartAddr1 = 0x2000; //D000 + } + + Addr = chClient[chNo].Addr; + rDzNum = 0; + for(i = 0; i < chClient[chNo].DzBlockNum; i ++) + { + if(chClient[chNo].DzBlock[i].chNo != chNo) + continue; + FunCode = 0x06; + DzBoardNo = chClient[chNo].DzBlock[i].StartAddr; //保护定值组编号 + + QueryModbus(chNo,Addr,FunCode,StartAddr,DzBoardNo); + if(RcvModBus(chNo,Addr,FunCode,12,Data)) + {//1 + FunCode = 0x03; + Len1=0x7d; + // Len1=0x50; + //printf("取定值数据...\n"); + QueryModbus(chNo,Addr,FunCode,StartAddr1,Len1); + if(RcvModBus(chNo,Addr,FunCode,2*Len1+9,Data)) + {//2 + dzCodeNo = (Data[3+6]<<8) | Data[4+6]; + if(dzCodeNo != DzBoardNo)//当返回的定值组号和读取时的定值组号一致,表示定值修改成功 + { + if(flag==1) + { + flag=2; + writelog("flag=2"); + } + // printf("定值块%d定值读取失败!读取块地址%d,返回块地址%d\n",i+1,Len,dzCodeNo); + QString mes= QString("DzBoardNo = %1 dzCodeNo: %2").arg(DzBoardNo).arg(dzCodeNo); + writelog(mes); + continue; + } + writelog("DzBoardNo OK!"); + for(j = 0; j < chClient[chNo].DzBlock[i].RegisterLen; j ++) //解析每一个定值(RegisterLen:每组定值的个数) + { + for(RegNo=0; RegNo < chClient[chNo].dzNum; RegNo ++) + { + if((chClient[chNo].dzstr[RegNo].chNo != chNo)||(chClient[chNo].dzstr[RegNo].BoardNo != DzBoardNo)) + continue;//当定值组号和定值组里的定值序号对应时,才更新定值数据 + + + if(chClient[chNo].dzstr[RegNo].PointNo == j) + { + if( flag == 0) + { + flag = 1; + writelog("flag=1"); + } + + DWordData = Data[4*j+5+6]; DWordData<<=24; + DWordData1 = Data[4*j+6+6]; DWordData1<<=16; + DWordData2 = Data[4*j+7+6]; DWordData2<<=8; + DWordData = DWordData+DWordData1+DWordData2+Data[4*j+8+6]; + //printf("d1=%d d2=%d d3=%d d4=%d\n",Data[4*j+5],Data[4*j+6],Data[4*j+7],Data[4*j+8]); + + ValueType = chClient[chNo].dzstr[RegNo].ValueType; + if(ValueType == 0) + WriteValue = (float)DWordData;//无符号 + else if(ValueType == 2)//浮点型 + { + memcpy(&WriteValue,&DWordData,sizeof(float)); + if(WriteValue != WriteValue) + WriteValue = 0; + } + else + { + IntData = DWordData; + WriteValue = (float)IntData; + }//有符号 + chClient[chNo].dzstr[RegNo].fValue = WriteValue*chClient[chNo].dzstr[RegNo].Modulus + chClient[chNo].dzstr[RegNo].Revise; + readDzStr[rDzNum].BoardNo = chClient[chNo].dzstr[RegNo].BoardNo; + readDzStr[rDzNum].PointNo = chClient[chNo].dzstr[RegNo].PointNo; + readDzStr[rDzNum].fValue = chClient[chNo].dzstr[RegNo].fValue; + strcpy(readDzStr[rDzNum].dzName,chClient[chNo].dzstr[RegNo].dzName); + readDzStr[rDzNum].chNo = chNo; + readDzStr[rDzNum].glFlag = chClient[chNo].dzstr[RegNo].glFlag; + readDzStr[rDzNum].timeFlag = chClient[chNo].dzstr[RegNo].timeFlag; + rDzNum ++; + break; + } + } + } + }//2 + }//1 + } + + *readDzNum = rDzNum; + Close_Socket(chNo); + if(flag == 1) + { + // readDzSig(dzstr,dzNum,5); + return 5;//定值读取成功 + } + else if(flag == 2) + { + // readDzSig(dzstr,dzNum,16); + return 16;//部分定值读取成功 + } + + return 6;//定值读取失败 +} + +int ModbusTcpm::setDz(int chNo,MOD_DZ_STR *mstr,int ModDzNum) +{ + + Q_UNUSED(chNo); + Q_UNUSED(mstr); + Q_UNUSED(ModDzNum); + return 7; //定值修改失败 +} diff --git a/product/src/gui/plugin/RelaySettingWidget/ModbusTCP.h b/product/src/gui/plugin/RelaySettingWidget/ModbusTCP.h index f33f30d7..4f622516 100644 --- a/product/src/gui/plugin/RelaySettingWidget/ModbusTCP.h +++ b/product/src/gui/plugin/RelaySettingWidget/ModbusTCP.h @@ -1,69 +1,69 @@ -#include "publicpara.h" -#include -#include "CRelayCommon.h" - -///////////////////////////////////////////// -#define RXTXBUFSIZE 8192 - -struct CH_Client_STR -{ - bool clientIsOk; - - bool InitialFlag; //初始化标志 - bool LinkOk; - int SendCount;//发送序号 - int RcvCount;//接收序号 - int FrameType;//发送帧类型 - int Addr; - - bool sendInitFlag; - int DzBlockPollNo; - int ModDzNum; - int m_Sock; - char ipAddr[20]; - int port; - bool chanFlag; - int dzNum; - int DzBlockNum; - - char blockFileName[256]; - char paraFileName[256]; - MOD_DZ_STR ModDzStr[DZ_DATA_MAX_NUM]; - DZSTR dzstr[DZ_DATA_MAX_NUM]; - DZ_BLOCK_STR DzBlock[BLOCK_MAX_NUM]; - -}; - -class ModbusTcpm -{ -public: - ModbusTcpm(); - ~ModbusTcpm(); - int readDz(int,int,DZSTR*,int*); - int setDz(int,MOD_DZ_STR*,int); - -private: - CH_Client_STR chClient[CHAN_MAX_NUM]; - bool RcvModBus(int chNo,int Addr,int FunCode,int Len,BYTE *zData); - bool QueryModbus(int chNo,BYTE Addr,BYTE FunCode,ushort StartAddr,ushort Len); - bool SendData(int chNo,BYTE *Data,int Len); - void NewConnectVar(int); - bool ConnectServer(int chNo); - int CreateSocket(int chNo); - void Close_Socket(int chNo); - void GetChanlParaInfo(); - void GetDzBlockParaInfo(int tdNo); - void GetDzBlockParaInfo(); - void GetDzInfo(int tdNo); - void writelog(QString log); - -public: - QList m_chanllist; - -private: - int chanNum; - QList m_blocklist; - QList m_paralist; - - QString m_strLog; -}; +#include "publicpara.h" +#include +#include "CRelayCommon.h" + +///////////////////////////////////////////// +#define RXTXBUFSIZE 8192 + +struct CH_Client_STR +{ + bool clientIsOk; + + bool InitialFlag; //初始化标志 + bool LinkOk; + int SendCount;//发送序号 + int RcvCount;//接收序号 + int FrameType;//发送帧类型 + int Addr; + + bool sendInitFlag; + int DzBlockPollNo; + int ModDzNum; + int m_Sock; + char ipAddr[20]; + int port; + bool chanFlag; + int dzNum; + int DzBlockNum; + + char blockFileName[256]; + char paraFileName[256]; + MOD_DZ_STR ModDzStr[DZ_DATA_MAX_NUM]; + DZSTR dzstr[DZ_DATA_MAX_NUM]; + DZ_BLOCK_STR DzBlock[BLOCK_MAX_NUM]; + +}; + +class ModbusTcpm +{ +public: + ModbusTcpm(); + ~ModbusTcpm(); + int readDz(int,int,DZSTR*,int*); + int setDz(int,MOD_DZ_STR*,int); + +private: + CH_Client_STR chClient[CHAN_MAX_NUM]; + bool RcvModBus(int chNo,int Addr,int FunCode,int Len,BYTE *zData); + bool QueryModbus(int chNo,BYTE Addr,BYTE FunCode,ushort StartAddr,ushort Len); + bool SendData(int chNo,BYTE *Data,int Len); + void NewConnectVar(int); + bool ConnectServer(int chNo); + int CreateSocket(int chNo); + void Close_Socket(int chNo); + void GetChanlParaInfo(); + void GetDzBlockParaInfo(int tdNo); + void GetDzBlockParaInfo(); + void GetDzInfo(int tdNo); + void writelog(QString log); + +public: + QList m_chanllist; + +private: + int chanNum; + QList m_blocklist; + QList m_paralist; + + QString m_strLog; +}; diff --git a/product/src/gui/plugin/RelaySettingWidget/RelaySettingWidget.pro b/product/src/gui/plugin/RelaySettingWidget/RelaySettingWidget.pro index 47a0ce33..3cdf1c24 100644 --- a/product/src/gui/plugin/RelaySettingWidget/RelaySettingWidget.pro +++ b/product/src/gui/plugin/RelaySettingWidget/RelaySettingWidget.pro @@ -1,86 +1,86 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-05-07T14:09:49 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib - -TARGET = RelaySettingWidget - -CONFIG += plugin -CONFIG += c++11 -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ -# main.cpp \ - CDbMng.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - CRelaySettingWidget.cpp \ - CRelaySettingMsgMng.cpp \ - CRelaySettingDelegate.cpp \ - CRelaySettingPluginWidget.cpp \ - CLogMng.cpp \ - CRelayFile.cpp \ - CWorker.cpp \ - ModbusTCP.cpp \ - -HEADERS += \ - CDbMng.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - CRelaySettingWidget.h \ - CRelaySettingCommon.h \ - CRelaySettingMsgMng.h \ - CRelaySettingDelegate.h \ - CRelaySettingPluginWidget.h \ - CLogMng.h \ - CRelayCommon.h \ - CRelayFile.h \ - CWorker.h \ - ModbusTCP.h \ - publicpara.h - -FORMS += \ - CRelaySettingWidget.ui - -LIBS += \ - -lprotobuf \ - -ldb_base_api \ - -ldb_api_ex \ - -lnet_msg_bus_api \ - -lpub_sysinfo_api \ - -lperm_mng_api \ - -llog4cplus \ - -lpub_logger_api \ - -ldp_chg_data_api \ - -lrdb_api \ - -lrdb_net_api \ - -lpub_utility_api \ - -lpub_sysinfo_api \ - -lsys_login_api - - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-05-07T14:09:49 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib + +TARGET = RelaySettingWidget + +CONFIG += plugin +CONFIG += c++11 +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ +# main.cpp \ + CDbMng.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + CRelaySettingWidget.cpp \ + CRelaySettingMsgMng.cpp \ + CRelaySettingDelegate.cpp \ + CRelaySettingPluginWidget.cpp \ + CLogMng.cpp \ + CRelayFile.cpp \ + CWorker.cpp \ + ModbusTCP.cpp \ + +HEADERS += \ + CDbMng.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CRelaySettingWidget.h \ + CRelaySettingCommon.h \ + CRelaySettingMsgMng.h \ + CRelaySettingDelegate.h \ + CRelaySettingPluginWidget.h \ + CLogMng.h \ + CRelayCommon.h \ + CRelayFile.h \ + CWorker.h \ + ModbusTCP.h \ + publicpara.h + +FORMS += \ + CRelaySettingWidget.ui + +LIBS += \ + -lprotobuf \ + -ldb_base_api \ + -ldb_api_ex \ + -lnet_msg_bus_api \ + -lpub_sysinfo_api \ + -lperm_mng_api \ + -llog4cplus \ + -lpub_logger_api \ + -ldp_chg_data_api \ + -lrdb_api \ + -lrdb_net_api \ + -lpub_utility_api \ + -lpub_sysinfo_api \ + -lsys_login_api + + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/RelaySettingWidget/main.cpp b/product/src/gui/plugin/RelaySettingWidget/main.cpp index 143f4e0a..b6f90ce9 100644 --- a/product/src/gui/plugin/RelaySettingWidget/main.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/main.cpp @@ -1,40 +1,40 @@ -#include "CRelaySettingWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - kbd_public::StartLogSystem("HMI", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - { - CRelaySettingWidget w(false); - //设置过滤条件 - w.setFilterGroup("station1.PSCADA.digital.station1.NQ-G14_dlq.Pos.value,station1.PSCADA.digital.station1.NQ-G16_dlq.Pos.value"); - w.setTreeHidden(true);//隐藏左侧设备树 - - w.show(); - app.exec(); - } - - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "CRelaySettingWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + kbd_public::StartLogSystem("HMI", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + { + CRelaySettingWidget w(false); + //设置过滤条件 + w.setFilterGroup("station1.PSCADA.digital.station1.NQ-G14_dlq.Pos.value,station1.PSCADA.digital.station1.NQ-G16_dlq.Pos.value"); + w.setTreeHidden(true);//隐藏左侧设备树 + + w.show(); + app.exec(); + } + + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/RelaySettingWidget/publicpara.h b/product/src/gui/plugin/RelaySettingWidget/publicpara.h index 8891d66a..7c93d7e6 100644 --- a/product/src/gui/plugin/RelaySettingWidget/publicpara.h +++ b/product/src/gui/plugin/RelaySettingWidget/publicpara.h @@ -1,64 +1,64 @@ -#ifndef PUBLICPARA_H -#define PUBLICPARA_H - -#define CHAN_MAX_NUM 256 //通道数 -#define DZ_DATA_MAX_NUM 50 //点数 -#define BLOCK_MAX_NUM 40 //点数 -#define DZ_NAME_LEN 40 -#define MAX_PATH 260 - -typedef unsigned char BYTE; -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; - - - -typedef struct -{ - int chNo; - float fValue; //值 - int pAddr; //寄存器地址 - float Modulus; //系数 - int Revise; //附加值 - int BoardNo; //定值组号 - int PointNo; //定值点号 - int ValueType; //值类型 - char dzName[DZ_NAME_LEN]; //定值名称 - bool isFlag; - int glFlag; //过流标示 - int timeFlag; //延迟标示 -}DZSTR; - -typedef struct -{ - int chNo; - BYTE FunCode; - ushort StartAddr; - ushort RegisterLen; - bool DzBlockChagFlag; - bool isFlag; -}DZ_BLOCK_STR; - -typedef struct -{ - int chNo; - int dzNo; - int DzBlockNo; - int DzModFlag; - float fValue; //值 -}MOD_DZ_STR; - -typedef struct CHANPARA{ - int chNo; //通道序号 - int checkFlag; - DZSTR dzstr[DZ_DATA_MAX_NUM]; - int readNum; - CHANPARA(){ - - } -}CHANPARA_; - - -#endif // PUBLICPARA_H +#ifndef PUBLICPARA_H +#define PUBLICPARA_H + +#define CHAN_MAX_NUM 256 //通道数 +#define DZ_DATA_MAX_NUM 50 //点数 +#define BLOCK_MAX_NUM 40 //点数 +#define DZ_NAME_LEN 40 +#define MAX_PATH 260 + +typedef unsigned char BYTE; +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + + + +typedef struct +{ + int chNo; + float fValue; //值 + int pAddr; //寄存器地址 + float Modulus; //系数 + int Revise; //附加值 + int BoardNo; //定值组号 + int PointNo; //定值点号 + int ValueType; //值类型 + char dzName[DZ_NAME_LEN]; //定值名称 + bool isFlag; + int glFlag; //过流标示 + int timeFlag; //延迟标示 +}DZSTR; + +typedef struct +{ + int chNo; + BYTE FunCode; + ushort StartAddr; + ushort RegisterLen; + bool DzBlockChagFlag; + bool isFlag; +}DZ_BLOCK_STR; + +typedef struct +{ + int chNo; + int dzNo; + int DzBlockNo; + int DzModFlag; + float fValue; //值 +}MOD_DZ_STR; + +typedef struct CHANPARA{ + int chNo; //通道序号 + int checkFlag; + DZSTR dzstr[DZ_DATA_MAX_NUM]; + int readNum; + CHANPARA(){ + + } +}CHANPARA_; + + +#endif // PUBLICPARA_H diff --git a/product/src/gui/plugin/ReportApp/CReportPluginWidget.cpp b/product/src/gui/plugin/ReportApp/CReportPluginWidget.cpp index b5cbf2fd..1807edbc 100644 --- a/product/src/gui/plugin/ReportApp/CReportPluginWidget.cpp +++ b/product/src/gui/plugin/ReportApp/CReportPluginWidget.cpp @@ -1,26 +1,26 @@ -#include -#include "CReportPluginWidget.h" -#include "CReportWidget.h" - -CReportPluginWidget::CReportPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CReportPluginWidget::~CReportPluginWidget() -{ - -} - -bool CReportPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) -{ - CReportWidget *pWidget = new CReportWidget(parent,editMode); - *widget = (QWidget *)pWidget; - *reportWidget = (IPluginWidget *)pWidget; - return true; -} - -void CReportPluginWidget::release() -{ - -} +#include +#include "CReportPluginWidget.h" +#include "CReportWidget.h" + +CReportPluginWidget::CReportPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CReportPluginWidget::~CReportPluginWidget() +{ + +} + +bool CReportPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) +{ + CReportWidget *pWidget = new CReportWidget(parent,editMode); + *widget = (QWidget *)pWidget; + *reportWidget = (IPluginWidget *)pWidget; + return true; +} + +void CReportPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ReportApp/CReportPluginWidget.h b/product/src/gui/plugin/ReportApp/CReportPluginWidget.h index af5ba798..c4243eb7 100644 --- a/product/src/gui/plugin/ReportApp/CReportPluginWidget.h +++ b/product/src/gui/plugin/ReportApp/CReportPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CREPORTPLUGINWIDGET_H -#define CREPORTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CReportPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CReportPluginWidget(QObject *parent = 0); - ~CReportPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); - void release(); -}; - -#endif // CREPORTPLUGINWIDGET_H +#ifndef CREPORTPLUGINWIDGET_H +#define CREPORTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CReportPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CReportPluginWidget(QObject *parent = 0); + ~CReportPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); + void release(); +}; + +#endif // CREPORTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/ReportApp/CReportStackedWidget.cpp b/product/src/gui/plugin/ReportApp/CReportStackedWidget.cpp index b1e4b90a..b6862b75 100644 --- a/product/src/gui/plugin/ReportApp/CReportStackedWidget.cpp +++ b/product/src/gui/plugin/ReportApp/CReportStackedWidget.cpp @@ -1,48 +1,48 @@ -#include "CReportStackedWidget.h" - -CReportStackedWidget::CReportStackedWidget(QWidget *parent) - :QStackedWidget(parent) -{ - init(); -} - -void CReportStackedWidget::init() -{ - view = new CReportWebView(this); - preview = new CReportWebView(this); - this->addWidget(view); - QWidget *previewWidget = new QWidget(this); - QPushButton *backToViewBtn = new QPushButton(this); - QVBoxLayout* vlay = new QVBoxLayout(this); - backToViewBtn->setText(tr("返回")); - vlay->setMargin(0); - vlay->addWidget(preview); - vlay->addWidget(backToViewBtn); - previewWidget->setLayout(vlay); - this->addWidget(previewWidget); - this->setCurrentIndex(0); - connect(backToViewBtn, &QPushButton::clicked, this, &CReportStackedWidget::slotBackBtnClicked); -} - -void CReportStackedWidget::slotBackBtnClicked() -{ - this->setCurrentIndex(0); - preview->load(QUrl("about:blank")); -} - -CReportWebView *CReportStackedWidget::getView(int index) -{ - if (index == 0) - { - return view; - } - else if (index == 1) - { - this->setCurrentIndex(1); - return preview; - } - else - { - return NULL; - } -} +#include "CReportStackedWidget.h" + +CReportStackedWidget::CReportStackedWidget(QWidget *parent) + :QStackedWidget(parent) +{ + init(); +} + +void CReportStackedWidget::init() +{ + view = new CReportWebView(this); + preview = new CReportWebView(this); + this->addWidget(view); + QWidget *previewWidget = new QWidget(this); + QPushButton *backToViewBtn = new QPushButton(this); + QVBoxLayout* vlay = new QVBoxLayout(this); + backToViewBtn->setText(tr("返回")); + vlay->setMargin(0); + vlay->addWidget(preview); + vlay->addWidget(backToViewBtn); + previewWidget->setLayout(vlay); + this->addWidget(previewWidget); + this->setCurrentIndex(0); + connect(backToViewBtn, &QPushButton::clicked, this, &CReportStackedWidget::slotBackBtnClicked); +} + +void CReportStackedWidget::slotBackBtnClicked() +{ + this->setCurrentIndex(0); + preview->load(QUrl("about:blank")); +} + +CReportWebView *CReportStackedWidget::getView(int index) +{ + if (index == 0) + { + return view; + } + else if (index == 1) + { + this->setCurrentIndex(1); + return preview; + } + else + { + return NULL; + } +} diff --git a/product/src/gui/plugin/ReportApp/CReportStackedWidget.h b/product/src/gui/plugin/ReportApp/CReportStackedWidget.h index 4d584796..5591a847 100644 --- a/product/src/gui/plugin/ReportApp/CReportStackedWidget.h +++ b/product/src/gui/plugin/ReportApp/CReportStackedWidget.h @@ -1,23 +1,23 @@ -#ifndef CREPORTSTACKEDWIDGET_H -#define CREPORTSTACKEDWIDGET_H -#include "CReportWebView.h" -#include "CReportWidget.h" -#include -#include -#include -class CReportWebView; -class CReportStackedWidget: public QStackedWidget -{ - Q_OBJECT -public: - CReportStackedWidget(QWidget *parent = nullptr); - CReportWebView *view; - CReportWebView *preview; -public slots: - CReportWebView *getView(int index); -private: - void init(); - void slotBackBtnClicked(); -}; - -#endif // CREPORTSTACKEDWIDGET_H +#ifndef CREPORTSTACKEDWIDGET_H +#define CREPORTSTACKEDWIDGET_H +#include "CReportWebView.h" +#include "CReportWidget.h" +#include +#include +#include +class CReportWebView; +class CReportStackedWidget: public QStackedWidget +{ + Q_OBJECT +public: + CReportStackedWidget(QWidget *parent = nullptr); + CReportWebView *view; + CReportWebView *preview; +public slots: + CReportWebView *getView(int index); +private: + void init(); + void slotBackBtnClicked(); +}; + +#endif // CREPORTSTACKEDWIDGET_H diff --git a/product/src/gui/plugin/ReportApp/CReportWebView.cpp b/product/src/gui/plugin/ReportApp/CReportWebView.cpp index f5e7e490..0193d1b3 100644 --- a/product/src/gui/plugin/ReportApp/CReportWebView.cpp +++ b/product/src/gui/plugin/ReportApp/CReportWebView.cpp @@ -1,22 +1,22 @@ -#include "CReportWebView.h" - -CReportWebView::CReportWebView(QWidget *parent) - : QWebEngineView(parent) -{ - this->setContextMenuPolicy(Qt::NoContextMenu); - this->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled,false); - this->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); - this->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); -} - -QWebEngineView *CReportWebView::createWindow(QWebEnginePage::WebWindowType type) -{ - Q_UNUSED(type) - CReportStackedWidget *StackedWidget = qobject_cast(parentWidget()); - if (!StackedWidget) - { - return nullptr; - } - return StackedWidget->getView(1); -} - +#include "CReportWebView.h" + +CReportWebView::CReportWebView(QWidget *parent) + : QWebEngineView(parent) +{ + this->setContextMenuPolicy(Qt::NoContextMenu); + this->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled,false); + this->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); + this->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); +} + +QWebEngineView *CReportWebView::createWindow(QWebEnginePage::WebWindowType type) +{ + Q_UNUSED(type) + CReportStackedWidget *StackedWidget = qobject_cast(parentWidget()); + if (!StackedWidget) + { + return nullptr; + } + return StackedWidget->getView(1); +} + diff --git a/product/src/gui/plugin/ReportApp/CReportWebView.h b/product/src/gui/plugin/ReportApp/CReportWebView.h index 9d25eac0..fecafd47 100644 --- a/product/src/gui/plugin/ReportApp/CReportWebView.h +++ b/product/src/gui/plugin/ReportApp/CReportWebView.h @@ -1,17 +1,17 @@ -#ifndef CREPORTWEBVIEW_H -#define CREPORTWEBVIEW_H - -#include -#include -#include -class CReportWebView : public QWebEngineView -{ - Q_OBJECT -public: - CReportWebView(QWidget *parent = nullptr); - -protected: - QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override; -}; - -#endif // CREPORTWEBVIEW_H +#ifndef CREPORTWEBVIEW_H +#define CREPORTWEBVIEW_H + +#include +#include +#include +class CReportWebView : public QWebEngineView +{ + Q_OBJECT +public: + CReportWebView(QWidget *parent = nullptr); + +protected: + QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override; +}; + +#endif // CREPORTWEBVIEW_H diff --git a/product/src/gui/plugin/ReportApp/CReportWidget.cpp b/product/src/gui/plugin/ReportApp/CReportWidget.cpp index ff30e920..f83c74e6 100644 --- a/product/src/gui/plugin/ReportApp/CReportWidget.cpp +++ b/product/src/gui/plugin/ReportApp/CReportWidget.cpp @@ -1,260 +1,260 @@ -#include "CReportWidget.h" -#include -#include -#include -#include - -CReportWidget::CReportWidget(const QString &language, QWidget *parent) - : QWidget(parent) -{ - m_updateTimer = NULL; - stackedWidget = NULL; - m_strLanguage = language; - - { - initLog(); - loadTranslator(); - init(); - } -} - -CReportWidget::~CReportWidget() -{ - if(m_updateTimer) - { - m_updateTimer->stop(); - delete m_updateTimer; - m_updateTimer = NULL; - } - if(stackedWidget) - { - QWebEngineProfile * engineProfile = stackedWidget->view->page()->profile(); - engineProfile->clearHttpCache(); - QWebEngineCookieStore *cookie = engineProfile->cookieStore(); - cookie->deleteAllCookies(); - stackedWidget = NULL; - } - releaseLog(); -} - -void CReportWidget::init() -{ - setWindowFlag(Qt::WindowStaysOnTopHint); - QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); - stackedWidget = new CReportStackedWidget(this); - QHBoxLayout* hlay = new QHBoxLayout(this); - hlay->addWidget(stackedWidget); - hlay->setMargin(0); - this->setLayout(hlay); - m_updateTimer = new QTimer(); - m_updateTimer->setInterval(5000); - connect(m_updateTimer, &QTimer::timeout, this, &CReportWidget::slotUpdateTime); - connect(stackedWidget->view, &QWebEngineView::loadFinished, this, &CReportWidget::slotLoadFinish); - connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, - this, &CReportWidget::handleDownloadRequest); - m_isHTML = false; - m_changeAddr = false; - m_addrNum = 0; - m_UsergId = -1; - m_editPerm = false; - number = 0; - m_browserMode = InValid; - m_strView = ":1120/page/view.html"; - m_strDesign = ":1120/page/design.html"; - - initUrl(); - initSetting(); -} - -void CReportWidget::initUrl() -{ - QString strFileName = "../../data/model/report.xml"; - - QFile file(strFileName); - if (!file.open(QIODevice::ReadOnly)) - { - return; - } - - QDomDocument document; - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - QDomElement root = document.documentElement(); - if(!root.isNull()) - { - QDomNodeList viewList = root.elementsByTagName("View"); - if(viewList.length() > 0) - { - m_strView = viewList.at(0).toElement().attribute("html", QString()); - } - QDomNodeList designList = root.elementsByTagName("Design"); - if(designList.length() > 0) - { - m_strDesign = designList.at(0).toElement().attribute("html", QString()); - } - } -} - -void CReportWidget::initSetting() -{ - QSettings settings(QSettings::UserScope, QLatin1String("user_var")); - QVariant info("undefined"); - if(settings.contains("report")) - { - info = settings.value("report"); - } - - if(info != "undefined") - { - printLog("!undefined"); - QVariantList vaList = info.toList(); - int netNum = vaList[0].toInt(); - m_ServerAddr[0] = vaList[1].toString().toStdString(); - m_ServerAddr[1] = vaList[2].toString().toStdString(); - int id = vaList[3].toInt(); - m_editPerm = vaList[4].toBool(); - browserMode mode = (browserMode)vaList[5].toInt(); - if(mode == 0) - { - setWindowTitle(tr("报表浏览")); - } - else - { - setWindowTitle(tr("报表编辑")); - } - if(netNum > 1) - { - m_changeAddr = true; - } - if(mode != m_browserMode || id != m_UsergId) - { - m_browserMode = mode; - m_UsergId = id; - loadPage(); - } - } -} - -void CReportWidget::loadTranslator() -{ - QTranslator *sysTranslator = new QTranslator(this); - QString path = "../common/resource/" + m_strLanguage + "/report/translate/report.qm"; - if(false == sysTranslator->load(path)) - { - printLog(QString("loadTranslator false: %1").arg(path)); - } - else - { - QCoreApplication::installTranslator(sysTranslator); - } -} - -void CReportWidget::loadPage() -{ - printLog("loadPage"); - m_isHTML = true; - if(m_browserMode == ViewMode) - { - printLog(QString("ViewMode %1").arg(m_UsergId)); - QString urlstr ="http://" + QString::fromStdString(m_ServerAddr[m_addrNum]) + m_strView; - QUrl url(urlstr); - QUrlQuery query; - query.addQueryItem("userGroup", QString::number(m_UsergId)); - url.setQuery(query); - printLog(url.toString()); - stackedWidget->view->load(url); - printLog("ViewMode end"); - } - else if (m_browserMode == EditMode) - { - printLog("EditMode"); - if(!m_editPerm) - { - QUrl a = QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/../../data/report/PERM_FORBIT_EDIT.html"); - stackedWidget->view->load(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/../../data/report/PERM_FORBIT_EDIT.html")); - return; - } - QString urlstr ="http://" + QString::fromStdString(m_ServerAddr[m_addrNum]) + m_strDesign; - QUrl url(urlstr); - printLog(url.toString()); - stackedWidget->view->load(url); - printLog("EditMode end"); - } -} - -void CReportWidget::slotUpdateTime() -{ - m_updateTimer->stop(); - if (m_changeAddr) - { - m_addrNum = 1 - m_addrNum; - } - loadPage(); -} - -void CReportWidget::slotLoadFinish(bool ok) -{ - printLog("slotLoadFinish"); - if(m_isHTML) - { - if (!ok) - { - printLog("slotLoadFinish false"); - stackedWidget->view->load(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/../../data/report/FAIL_PAGE.html")); - if(m_changeAddr && !m_addrNum) - m_updateTimer->start(); - } - } - m_isHTML = false; - printLog("slotLoadFinish end"); -} - -void CReportWidget::handleDownloadRequest(QWebEngineDownloadItem *download) -{ - QString path = QFileDialog::getSaveFileName(this, tr("导出报表"), download->path()); - if (!path.isEmpty()) - { - download->setPath(path); - download->accept(); - } -} - -void CReportWidget::initLog() -{ - m_logFile.setFileName("../../log/HMI/report.log"); - m_logFile.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Append); - - printLog("==================== initLog ===================="); -} - -void CReportWidget::releaseLog() -{ - printLog("releaseLog"); - - if(m_logFile.isOpen()) - { - m_logFile.close(); - } -} - -void CReportWidget::printLog(const QString &log) -{ - QTextStream textStream(&m_logFile); - textStream << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz ") << log << endl; -} - -void CReportWidget::showEvent(QShowEvent *event) -{ - if(number == 1) - { - initSetting(); - } - number = 1; - - QWidget::showEvent(event); -} +#include "CReportWidget.h" +#include +#include +#include +#include + +CReportWidget::CReportWidget(const QString &language, QWidget *parent) + : QWidget(parent) +{ + m_updateTimer = NULL; + stackedWidget = NULL; + m_strLanguage = language; + + { + initLog(); + loadTranslator(); + init(); + } +} + +CReportWidget::~CReportWidget() +{ + if(m_updateTimer) + { + m_updateTimer->stop(); + delete m_updateTimer; + m_updateTimer = NULL; + } + if(stackedWidget) + { + QWebEngineProfile * engineProfile = stackedWidget->view->page()->profile(); + engineProfile->clearHttpCache(); + QWebEngineCookieStore *cookie = engineProfile->cookieStore(); + cookie->deleteAllCookies(); + stackedWidget = NULL; + } + releaseLog(); +} + +void CReportWidget::init() +{ + setWindowFlag(Qt::WindowStaysOnTopHint); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + stackedWidget = new CReportStackedWidget(this); + QHBoxLayout* hlay = new QHBoxLayout(this); + hlay->addWidget(stackedWidget); + hlay->setMargin(0); + this->setLayout(hlay); + m_updateTimer = new QTimer(); + m_updateTimer->setInterval(5000); + connect(m_updateTimer, &QTimer::timeout, this, &CReportWidget::slotUpdateTime); + connect(stackedWidget->view, &QWebEngineView::loadFinished, this, &CReportWidget::slotLoadFinish); + connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, + this, &CReportWidget::handleDownloadRequest); + m_isHTML = false; + m_changeAddr = false; + m_addrNum = 0; + m_UsergId = -1; + m_editPerm = false; + number = 0; + m_browserMode = InValid; + m_strView = ":1120/page/view.html"; + m_strDesign = ":1120/page/design.html"; + + initUrl(); + initSetting(); +} + +void CReportWidget::initUrl() +{ + QString strFileName = "../../data/model/report.xml"; + + QFile file(strFileName); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + + QDomDocument document; + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(!root.isNull()) + { + QDomNodeList viewList = root.elementsByTagName("View"); + if(viewList.length() > 0) + { + m_strView = viewList.at(0).toElement().attribute("html", QString()); + } + QDomNodeList designList = root.elementsByTagName("Design"); + if(designList.length() > 0) + { + m_strDesign = designList.at(0).toElement().attribute("html", QString()); + } + } +} + +void CReportWidget::initSetting() +{ + QSettings settings(QSettings::UserScope, QLatin1String("user_var")); + QVariant info("undefined"); + if(settings.contains("report")) + { + info = settings.value("report"); + } + + if(info != "undefined") + { + printLog("!undefined"); + QVariantList vaList = info.toList(); + int netNum = vaList[0].toInt(); + m_ServerAddr[0] = vaList[1].toString().toStdString(); + m_ServerAddr[1] = vaList[2].toString().toStdString(); + int id = vaList[3].toInt(); + m_editPerm = vaList[4].toBool(); + browserMode mode = (browserMode)vaList[5].toInt(); + if(mode == 0) + { + setWindowTitle(tr("报表浏览")); + } + else + { + setWindowTitle(tr("报表编辑")); + } + if(netNum > 1) + { + m_changeAddr = true; + } + if(mode != m_browserMode || id != m_UsergId) + { + m_browserMode = mode; + m_UsergId = id; + loadPage(); + } + } +} + +void CReportWidget::loadTranslator() +{ + QTranslator *sysTranslator = new QTranslator(this); + QString path = "../common/resource/" + m_strLanguage + "/report/translate/report.qm"; + if(false == sysTranslator->load(path)) + { + printLog(QString("loadTranslator false: %1").arg(path)); + } + else + { + QCoreApplication::installTranslator(sysTranslator); + } +} + +void CReportWidget::loadPage() +{ + printLog("loadPage"); + m_isHTML = true; + if(m_browserMode == ViewMode) + { + printLog(QString("ViewMode %1").arg(m_UsergId)); + QString urlstr ="http://" + QString::fromStdString(m_ServerAddr[m_addrNum]) + m_strView; + QUrl url(urlstr); + QUrlQuery query; + query.addQueryItem("userGroup", QString::number(m_UsergId)); + url.setQuery(query); + printLog(url.toString()); + stackedWidget->view->load(url); + printLog("ViewMode end"); + } + else if (m_browserMode == EditMode) + { + printLog("EditMode"); + if(!m_editPerm) + { + QUrl a = QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/../../data/report/PERM_FORBIT_EDIT.html"); + stackedWidget->view->load(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/../../data/report/PERM_FORBIT_EDIT.html")); + return; + } + QString urlstr ="http://" + QString::fromStdString(m_ServerAddr[m_addrNum]) + m_strDesign; + QUrl url(urlstr); + printLog(url.toString()); + stackedWidget->view->load(url); + printLog("EditMode end"); + } +} + +void CReportWidget::slotUpdateTime() +{ + m_updateTimer->stop(); + if (m_changeAddr) + { + m_addrNum = 1 - m_addrNum; + } + loadPage(); +} + +void CReportWidget::slotLoadFinish(bool ok) +{ + printLog("slotLoadFinish"); + if(m_isHTML) + { + if (!ok) + { + printLog("slotLoadFinish false"); + stackedWidget->view->load(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/../../data/report/FAIL_PAGE.html")); + if(m_changeAddr && !m_addrNum) + m_updateTimer->start(); + } + } + m_isHTML = false; + printLog("slotLoadFinish end"); +} + +void CReportWidget::handleDownloadRequest(QWebEngineDownloadItem *download) +{ + QString path = QFileDialog::getSaveFileName(this, tr("导出报表"), download->path()); + if (!path.isEmpty()) + { + download->setPath(path); + download->accept(); + } +} + +void CReportWidget::initLog() +{ + m_logFile.setFileName("../../log/HMI/report.log"); + m_logFile.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Append); + + printLog("==================== initLog ===================="); +} + +void CReportWidget::releaseLog() +{ + printLog("releaseLog"); + + if(m_logFile.isOpen()) + { + m_logFile.close(); + } +} + +void CReportWidget::printLog(const QString &log) +{ + QTextStream textStream(&m_logFile); + textStream << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz ") << log << endl; +} + +void CReportWidget::showEvent(QShowEvent *event) +{ + if(number == 1) + { + initSetting(); + } + number = 1; + + QWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/ReportApp/CReportWidget.h b/product/src/gui/plugin/ReportApp/CReportWidget.h index 13fc29d9..a8cb5cbb 100644 --- a/product/src/gui/plugin/ReportApp/CReportWidget.h +++ b/product/src/gui/plugin/ReportApp/CReportWidget.h @@ -1,83 +1,83 @@ -#ifndef CREPORTWIDGET_H -#define CREPORTWIDGET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -//#include -//#include -//#include - -//using namespace kbd_service; -//using namespace kbd_public; -class CReportWebView; -class CReportStackedWidget; - -class CReportWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CReportWidget(const QString& language = "zh", QWidget *parent = NULL); - ~CReportWidget(); - enum browserMode - { - InValid = -1, - ViewMode = 0, - EditMode - }; - -public: - void initLog(); - void releaseLog(); - void printLog(const QString& log); - -private: - void init(); - void initUrl(); - void initSetting(); - void loadTranslator(); - void updateUserInfo(); - void loadPage(); - void slotLoadFinish(bool ok); - void slotUpdateTime(); - void handleDownloadRequest(QWebEngineDownloadItem *download); - -private slots: - void showEvent(QShowEvent *event); - -private: - CReportStackedWidget *stackedWidget; - QTimer * m_updateTimer; - QString m_strLanguage; - browserMode m_browserMode; - bool m_isHTML; - - int m_UsergId; - bool m_editPerm; - std::string m_ServerAddr[2]; - bool m_changeAddr; - int m_addrNum; - QFile m_logFile; - - int number; - QString m_strView; - QString m_strDesign; -}; - - - - -#endif // CREPORTWIDGET_H +#ifndef CREPORTWIDGET_H +#define CREPORTWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +//#include +//#include +//#include + +//using namespace kbd_service; +//using namespace kbd_public; +class CReportWebView; +class CReportStackedWidget; + +class CReportWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CReportWidget(const QString& language = "zh", QWidget *parent = NULL); + ~CReportWidget(); + enum browserMode + { + InValid = -1, + ViewMode = 0, + EditMode + }; + +public: + void initLog(); + void releaseLog(); + void printLog(const QString& log); + +private: + void init(); + void initUrl(); + void initSetting(); + void loadTranslator(); + void updateUserInfo(); + void loadPage(); + void slotLoadFinish(bool ok); + void slotUpdateTime(); + void handleDownloadRequest(QWebEngineDownloadItem *download); + +private slots: + void showEvent(QShowEvent *event); + +private: + CReportStackedWidget *stackedWidget; + QTimer * m_updateTimer; + QString m_strLanguage; + browserMode m_browserMode; + bool m_isHTML; + + int m_UsergId; + bool m_editPerm; + std::string m_ServerAddr[2]; + bool m_changeAddr; + int m_addrNum; + QFile m_logFile; + + int number; + QString m_strView; + QString m_strDesign; +}; + + + + +#endif // CREPORTWIDGET_H diff --git a/product/src/gui/plugin/ReportApp/ReportWidget.pro b/product/src/gui/plugin/ReportApp/ReportWidget.pro index a070c6d9..5758aaef 100644 --- a/product/src/gui/plugin/ReportApp/ReportWidget.pro +++ b/product/src/gui/plugin/ReportApp/ReportWidget.pro @@ -1,66 +1,66 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-11-13T14:55:16 -# -#------------------------------------------------- - -QT += core gui webenginewidgets xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = ReportWidget -TEMPLATE = app - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CReportWidget.cpp \ -# CReportPluginWidget.cpp \ - main.cpp \ - CReportWebView.cpp \ - CReportStackedWidget.cpp \ - SingleApplication.cpp \ - SingleApplication_p.cpp - -HEADERS += \ - CReportWidget.h \ -# CReportPluginWidget.h \ - CReportWebView.h \ - CReportStackedWidget.h \ - SingleApplication.h \ - SingleApplication_p.h - -RESOURCES += \ - resource.qrc - -#LIBS += \ -# -lperm_mng_api \ -# -lpub_sysinfo_api \ -# -lpub_utility_api - -#include($$PWD/../../idl_files/idl_files.pri) -win32-msvc* { - LIBS += -ladvapi32 -} - -#CONFIG += console - -DEFINES += QAPPLICATION_CLASS=QApplication - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2018-11-13T14:55:16 +# +#------------------------------------------------- + +QT += core gui webenginewidgets xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ReportWidget +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CReportWidget.cpp \ +# CReportPluginWidget.cpp \ + main.cpp \ + CReportWebView.cpp \ + CReportStackedWidget.cpp \ + SingleApplication.cpp \ + SingleApplication_p.cpp + +HEADERS += \ + CReportWidget.h \ +# CReportPluginWidget.h \ + CReportWebView.h \ + CReportStackedWidget.h \ + SingleApplication.h \ + SingleApplication_p.h + +RESOURCES += \ + resource.qrc + +#LIBS += \ +# -lperm_mng_api \ +# -lpub_sysinfo_api \ +# -lpub_utility_api + +#include($$PWD/../../idl_files/idl_files.pri) +win32-msvc* { + LIBS += -ladvapi32 +} + +#CONFIG += console + +DEFINES += QAPPLICATION_CLASS=QApplication + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/ReportApp/SingleApplication.cpp b/product/src/gui/plugin/ReportApp/SingleApplication.cpp index 47be7783..07e848a4 100644 --- a/product/src/gui/plugin/ReportApp/SingleApplication.cpp +++ b/product/src/gui/plugin/ReportApp/SingleApplication.cpp @@ -1,182 +1,182 @@ -// The MIT License (MIT) -// -// Copyright (c) Itay Grudev 2015 - 2018 -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include -#include -#include -#include -#include - -#include "SingleApplication.h" -#include "SingleApplication_p.h" -#include - -/** - * @brief Constructor. Checks and fires up LocalServer or closes the program - * if another instance already exists - * @param argc - * @param argv - * @param {bool} allowSecondaryInstances - */ -SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout ) - : app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) ) -{ - Q_D(SingleApplication); - -#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) - // On Android and iOS since the library is not supported fallback to - // standard QApplication behaviour by simply returning at this point. - qWarning() << "SingleApplication is not supported on Android and iOS systems."; - return; -#endif - - // Store the current mode of the program - d->options = options; - - // Generating an application ID used for identifying the shared memory - // block and QLocalServer - d->genBlockServerName(); - -#ifdef Q_OS_UNIX - // By explicitly attaching it and then deleting it we make sure that the - // memory is deleted even after the process has crashed on Unix. - d->memory = new QSharedMemory( d->blockServerName ); - d->memory->attach(); - delete d->memory; -#endif - // Guarantee thread safe behaviour with a shared memory block. - d->memory = new QSharedMemory( d->blockServerName ); - - // Create a shared memory block - if( d->memory->create( sizeof( InstancesInfo ) ) ) { - // Initialize the shared memory block - d->memory->lock(); - d->initializeMemoryBlock(); - d->memory->unlock(); - } else { - // Attempt to attach to the memory segment - if( ! d->memory->attach() ) { - qCritical() << "SingleApplication: Unable to attach to shared memory block."; - qCritical() << d->memory->errorString(); - delete d; - ::exit( EXIT_FAILURE ); - } - } - - InstancesInfo* inst = static_cast( d->memory->data() ); - QTime time; - time.start(); - - // Make sure the shared memory block is initialised and in consistent state - while( true ) { - d->memory->lock(); - - if( d->blockChecksum() == inst->checksum ) break; - - if( time.elapsed() > 5000 ) { - qWarning() << "SingleApplication: Shared memory block has been in an inconsistent state from more than 5s. Assuming primary instance failure."; - d->initializeMemoryBlock(); - } - - d->memory->unlock(); - - // Random sleep here limits the probability of a collision between two racing apps - qsrand( QDateTime::currentMSecsSinceEpoch() % std::numeric_limits::max() ); - QThread::sleep( 8 + static_cast ( static_cast ( qrand() ) / RAND_MAX * 10 ) ); - } - - if( inst->primary == false) { - d->startPrimary(); - d->memory->unlock(); - return; - } - - // Check if another instance can be started - if( allowSecondary ) { - inst->secondary += 1; - inst->checksum = d->blockChecksum(); - d->instanceNumber = inst->secondary; - d->startSecondary(); - if( d->options & Mode::SecondaryNotification ) { - d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance ); - } - d->memory->unlock(); - return; - } - - d->memory->unlock(); - - d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance ); - - delete d; - - ::exit( EXIT_SUCCESS ); -} - -/** - * @brief Destructor - */ -SingleApplication::~SingleApplication() -{ - Q_D(SingleApplication); - delete d; -} - -bool SingleApplication::isPrimary() -{ - Q_D(SingleApplication); - return d->server != nullptr; -} - -bool SingleApplication::isSecondary() -{ - Q_D(SingleApplication); - return d->server == nullptr; -} - -quint32 SingleApplication::instanceId() -{ - Q_D(SingleApplication); - return d->instanceNumber; -} - -qint64 SingleApplication::primaryPid() -{ - Q_D(SingleApplication); - return d->primaryPid(); -} - -bool SingleApplication::sendMessage( QByteArray message, int timeout ) -{ - Q_D(SingleApplication); - - // Nobody to connect to - if( isPrimary() ) return false; - - // Make sure the socket is connected - d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ); - - d->socket->write( message ); - bool dataWritten = d->socket->waitForBytesWritten( timeout ); - d->socket->flush(); - return dataWritten; -} +// The MIT License (MIT) +// +// Copyright (c) Itay Grudev 2015 - 2018 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include +#include +#include +#include +#include + +#include "SingleApplication.h" +#include "SingleApplication_p.h" +#include + +/** + * @brief Constructor. Checks and fires up LocalServer or closes the program + * if another instance already exists + * @param argc + * @param argv + * @param {bool} allowSecondaryInstances + */ +SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout ) + : app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) ) +{ + Q_D(SingleApplication); + +#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) + // On Android and iOS since the library is not supported fallback to + // standard QApplication behaviour by simply returning at this point. + qWarning() << "SingleApplication is not supported on Android and iOS systems."; + return; +#endif + + // Store the current mode of the program + d->options = options; + + // Generating an application ID used for identifying the shared memory + // block and QLocalServer + d->genBlockServerName(); + +#ifdef Q_OS_UNIX + // By explicitly attaching it and then deleting it we make sure that the + // memory is deleted even after the process has crashed on Unix. + d->memory = new QSharedMemory( d->blockServerName ); + d->memory->attach(); + delete d->memory; +#endif + // Guarantee thread safe behaviour with a shared memory block. + d->memory = new QSharedMemory( d->blockServerName ); + + // Create a shared memory block + if( d->memory->create( sizeof( InstancesInfo ) ) ) { + // Initialize the shared memory block + d->memory->lock(); + d->initializeMemoryBlock(); + d->memory->unlock(); + } else { + // Attempt to attach to the memory segment + if( ! d->memory->attach() ) { + qCritical() << "SingleApplication: Unable to attach to shared memory block."; + qCritical() << d->memory->errorString(); + delete d; + ::exit( EXIT_FAILURE ); + } + } + + InstancesInfo* inst = static_cast( d->memory->data() ); + QTime time; + time.start(); + + // Make sure the shared memory block is initialised and in consistent state + while( true ) { + d->memory->lock(); + + if( d->blockChecksum() == inst->checksum ) break; + + if( time.elapsed() > 5000 ) { + qWarning() << "SingleApplication: Shared memory block has been in an inconsistent state from more than 5s. Assuming primary instance failure."; + d->initializeMemoryBlock(); + } + + d->memory->unlock(); + + // Random sleep here limits the probability of a collision between two racing apps + qsrand( QDateTime::currentMSecsSinceEpoch() % std::numeric_limits::max() ); + QThread::sleep( 8 + static_cast ( static_cast ( qrand() ) / RAND_MAX * 10 ) ); + } + + if( inst->primary == false) { + d->startPrimary(); + d->memory->unlock(); + return; + } + + // Check if another instance can be started + if( allowSecondary ) { + inst->secondary += 1; + inst->checksum = d->blockChecksum(); + d->instanceNumber = inst->secondary; + d->startSecondary(); + if( d->options & Mode::SecondaryNotification ) { + d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance ); + } + d->memory->unlock(); + return; + } + + d->memory->unlock(); + + d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance ); + + delete d; + + ::exit( EXIT_SUCCESS ); +} + +/** + * @brief Destructor + */ +SingleApplication::~SingleApplication() +{ + Q_D(SingleApplication); + delete d; +} + +bool SingleApplication::isPrimary() +{ + Q_D(SingleApplication); + return d->server != nullptr; +} + +bool SingleApplication::isSecondary() +{ + Q_D(SingleApplication); + return d->server == nullptr; +} + +quint32 SingleApplication::instanceId() +{ + Q_D(SingleApplication); + return d->instanceNumber; +} + +qint64 SingleApplication::primaryPid() +{ + Q_D(SingleApplication); + return d->primaryPid(); +} + +bool SingleApplication::sendMessage( QByteArray message, int timeout ) +{ + Q_D(SingleApplication); + + // Nobody to connect to + if( isPrimary() ) return false; + + // Make sure the socket is connected + d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ); + + d->socket->write( message ); + bool dataWritten = d->socket->waitForBytesWritten( timeout ); + d->socket->flush(); + return dataWritten; +} diff --git a/product/src/gui/plugin/ReportApp/SingleApplication.h b/product/src/gui/plugin/ReportApp/SingleApplication.h index 96777900..cb505971 100644 --- a/product/src/gui/plugin/ReportApp/SingleApplication.h +++ b/product/src/gui/plugin/ReportApp/SingleApplication.h @@ -1,135 +1,135 @@ -// The MIT License (MIT) -// -// Copyright (c) Itay Grudev 2015 - 2018 -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef SINGLE_APPLICATION_H -#define SINGLE_APPLICATION_H - -#include -#include - -#ifndef QAPPLICATION_CLASS - #define QAPPLICATION_CLASS QCoreApplication -#endif - -#include QT_STRINGIFY(QAPPLICATION_CLASS) - -class SingleApplicationPrivate; - -/** - * @brief The SingleApplication class handles multiple instances of the same - * Application - * @see QCoreApplication - */ -class SingleApplication : public QAPPLICATION_CLASS -{ - Q_OBJECT - - typedef QAPPLICATION_CLASS app_t; - -public: - /** - * @brief Mode of operation of SingleApplication. - * Whether the block should be user-wide or system-wide and whether the - * primary instance should be notified when a secondary instance had been - * started. - * @note Operating system can restrict the shared memory blocks to the same - * user, in which case the User/System modes will have no effect and the - * block will be user wide. - * @enum - */ - enum Mode { - User = 1 << 0, - System = 1 << 1, - SecondaryNotification = 1 << 2, - ExcludeAppVersion = 1 << 3, - ExcludeAppPath = 1 << 4 - }; - Q_DECLARE_FLAGS(Options, Mode) - - /** - * @brief Intitializes a SingleApplication instance with argc command line - * arguments in argv - * @arg {int &} argc - Number of arguments in argv - * @arg {const char *[]} argv - Supplied command line arguments - * @arg {bool} allowSecondary - Whether to start the instance as secondary - * if there is already a primary instance. - * @arg {Mode} mode - Whether for the SingleApplication block to be applied - * User wide or System wide. - * @arg {int} timeout - Timeout to wait in milliseconds. - * @note argc and argv may be changed as Qt removes arguments that it - * recognizes - * @note Mode::SecondaryNotification only works if set on both the primary - * instance and the secondary instance. - * @note The timeout is just a hint for the maximum time of blocking - * operations. It does not guarantee that the SingleApplication - * initialisation will be completed in given time, though is a good hint. - * Usually 4*timeout would be the worst case (fail) scenario. - * @see See the corresponding QAPPLICATION_CLASS constructor for reference - */ - explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000 ); - ~SingleApplication(); - - /** - * @brief Returns if the instance is the primary instance - * @returns {bool} - */ - bool isPrimary(); - - /** - * @brief Returns if the instance is a secondary instance - * @returns {bool} - */ - bool isSecondary(); - - /** - * @brief Returns a unique identifier for the current instance - * @returns {qint32} - */ - quint32 instanceId(); - - /** - * @brief Returns the process ID (PID) of the primary instance - * @returns {qint64} - */ - qint64 primaryPid(); - - /** - * @brief Sends a message to the primary instance. Returns true on success. - * @param {int} timeout - Timeout for connecting - * @returns {bool} - * @note sendMessage() will return false if invoked from the primary - * instance. - */ - bool sendMessage( QByteArray message, int timeout = 100 ); - -Q_SIGNALS: - void instanceStarted(); - void receivedMessage( quint32 instanceId, QByteArray message ); - -private: - SingleApplicationPrivate *d_ptr; - Q_DECLARE_PRIVATE(SingleApplication) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options) - -#endif // SINGLE_APPLICATION_H +// The MIT License (MIT) +// +// Copyright (c) Itay Grudev 2015 - 2018 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef SINGLE_APPLICATION_H +#define SINGLE_APPLICATION_H + +#include +#include + +#ifndef QAPPLICATION_CLASS + #define QAPPLICATION_CLASS QCoreApplication +#endif + +#include QT_STRINGIFY(QAPPLICATION_CLASS) + +class SingleApplicationPrivate; + +/** + * @brief The SingleApplication class handles multiple instances of the same + * Application + * @see QCoreApplication + */ +class SingleApplication : public QAPPLICATION_CLASS +{ + Q_OBJECT + + typedef QAPPLICATION_CLASS app_t; + +public: + /** + * @brief Mode of operation of SingleApplication. + * Whether the block should be user-wide or system-wide and whether the + * primary instance should be notified when a secondary instance had been + * started. + * @note Operating system can restrict the shared memory blocks to the same + * user, in which case the User/System modes will have no effect and the + * block will be user wide. + * @enum + */ + enum Mode { + User = 1 << 0, + System = 1 << 1, + SecondaryNotification = 1 << 2, + ExcludeAppVersion = 1 << 3, + ExcludeAppPath = 1 << 4 + }; + Q_DECLARE_FLAGS(Options, Mode) + + /** + * @brief Intitializes a SingleApplication instance with argc command line + * arguments in argv + * @arg {int &} argc - Number of arguments in argv + * @arg {const char *[]} argv - Supplied command line arguments + * @arg {bool} allowSecondary - Whether to start the instance as secondary + * if there is already a primary instance. + * @arg {Mode} mode - Whether for the SingleApplication block to be applied + * User wide or System wide. + * @arg {int} timeout - Timeout to wait in milliseconds. + * @note argc and argv may be changed as Qt removes arguments that it + * recognizes + * @note Mode::SecondaryNotification only works if set on both the primary + * instance and the secondary instance. + * @note The timeout is just a hint for the maximum time of blocking + * operations. It does not guarantee that the SingleApplication + * initialisation will be completed in given time, though is a good hint. + * Usually 4*timeout would be the worst case (fail) scenario. + * @see See the corresponding QAPPLICATION_CLASS constructor for reference + */ + explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000 ); + ~SingleApplication(); + + /** + * @brief Returns if the instance is the primary instance + * @returns {bool} + */ + bool isPrimary(); + + /** + * @brief Returns if the instance is a secondary instance + * @returns {bool} + */ + bool isSecondary(); + + /** + * @brief Returns a unique identifier for the current instance + * @returns {qint32} + */ + quint32 instanceId(); + + /** + * @brief Returns the process ID (PID) of the primary instance + * @returns {qint64} + */ + qint64 primaryPid(); + + /** + * @brief Sends a message to the primary instance. Returns true on success. + * @param {int} timeout - Timeout for connecting + * @returns {bool} + * @note sendMessage() will return false if invoked from the primary + * instance. + */ + bool sendMessage( QByteArray message, int timeout = 100 ); + +Q_SIGNALS: + void instanceStarted(); + void receivedMessage( quint32 instanceId, QByteArray message ); + +private: + SingleApplicationPrivate *d_ptr; + Q_DECLARE_PRIVATE(SingleApplication) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options) + +#endif // SINGLE_APPLICATION_H diff --git a/product/src/gui/plugin/ReportApp/SingleApplication_p.cpp b/product/src/gui/plugin/ReportApp/SingleApplication_p.cpp index 6bf58223..90fa199d 100644 --- a/product/src/gui/plugin/ReportApp/SingleApplication_p.cpp +++ b/product/src/gui/plugin/ReportApp/SingleApplication_p.cpp @@ -1,406 +1,406 @@ -// The MIT License (MIT) -// -// Copyright (c) Itay Grudev 2015 - 2018 -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -// -// W A R N I N G !!! -// ----------------- -// -// This file is not part of the SingleApplication API. It is used purely as an -// implementation detail. This header file may change from version to -// version without notice, or may even be removed. -// - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "SingleApplication.h" -#include "SingleApplication_p.h" - -#include -#ifdef Q_OS_UNIX - #include - #include - #include -#endif - -#ifdef Q_OS_WIN - #include - #include -#endif - -SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) - : q_ptr( q_ptr ) -{ - server = nullptr; - socket = nullptr; - memory = nullptr; - instanceNumber = -1; -} - -SingleApplicationPrivate::~SingleApplicationPrivate() -{ - if( socket != nullptr ) { - socket->close(); - delete socket; - } - - memory->lock(); - InstancesInfo* inst = static_cast(memory->data()); - if( server != nullptr ) { - server->close(); - delete server; - inst->primary = false; - inst->primaryPid = -1; - inst->checksum = blockChecksum(); - } - memory->unlock(); - - delete memory; -} - -void SingleApplicationPrivate::genBlockServerName() -{ - QCryptographicHash appData( QCryptographicHash::Sha256 ); - appData.addData( "SingleApplication", 17 ); - appData.addData( SingleApplication::app_t::applicationName().toUtf8() ); - appData.addData( SingleApplication::app_t::organizationName().toUtf8() ); - appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() ); - - if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ) { - appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() ); - } - - if( ! (options & SingleApplication::Mode::ExcludeAppPath) ) { -#ifdef Q_OS_WIN - appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() ); -#else - appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() ); -#endif - } - - // User level block requires a user specific data in the hash - if( options & SingleApplication::Mode::User ) { -#ifdef Q_OS_WIN - wchar_t username [ UNLEN + 1 ]; - // Specifies size of the buffer on input - DWORD usernameLength = UNLEN + 1; - if( GetUserNameW( username, &usernameLength ) ) { - appData.addData( QString::fromWCharArray(username).toUtf8() ); - } else { - appData.addData( qgetenv("USERNAME") ); - } -#endif -#ifdef Q_OS_UNIX - QByteArray username; - uid_t uid = geteuid(); - struct passwd *pw = getpwuid(uid); - if( pw ) { - username = pw->pw_name; - } - if( username.isEmpty() ) { - username = qgetenv("USER"); - } - appData.addData(username); -#endif - } - - // Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with - // server naming requirements. - blockServerName = appData.result().toBase64().replace("/", "_"); -} - -void SingleApplicationPrivate::initializeMemoryBlock() -{ - InstancesInfo* inst = static_cast( memory->data() ); - inst->primary = false; - inst->secondary = 0; - inst->primaryPid = -1; - inst->checksum = blockChecksum(); -} - -void SingleApplicationPrivate::startPrimary() -{ - Q_Q(SingleApplication); - - // Successful creation means that no main process exists - // So we start a QLocalServer to listen for connections - QLocalServer::removeServer( blockServerName ); - server = new QLocalServer(); - - // Restrict access to the socket according to the - // SingleApplication::Mode::User flag on User level or no restrictions - if( options & SingleApplication::Mode::User ) { - server->setSocketOptions( QLocalServer::UserAccessOption ); - } else { - server->setSocketOptions( QLocalServer::WorldAccessOption ); - } - - server->listen( blockServerName ); - QObject::connect( - server, - &QLocalServer::newConnection, - this, - &SingleApplicationPrivate::slotConnectionEstablished - ); - - // Reset the number of connections - InstancesInfo* inst = static_cast ( memory->data() ); - - inst->primary = true; - inst->primaryPid = q->applicationPid(); - inst->checksum = blockChecksum(); - - instanceNumber = 0; -} - -void SingleApplicationPrivate::startSecondary() -{ -} - -void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType ) -{ - // Connect to the Local Server of the Primary Instance if not already - // connected. - if( socket == nullptr ) { - socket = new QLocalSocket(); - } - // If already connected - we are done; - if( socket->state() == QLocalSocket::ConnectedState ) - return; - - // If not connect - if( socket->state() == QLocalSocket::UnconnectedState || - socket->state() == QLocalSocket::ClosingState ) { - socket->connectToServer( blockServerName ); - } - - // Wait for being connected - if( socket->state() == QLocalSocket::ConnectingState ) { - socket->waitForConnected( msecs ); - } - - // Initialisation message according to the SingleApplication protocol - if( socket->state() == QLocalSocket::ConnectedState ) { - // Notify the parent that a new instance had been started; - QByteArray initMsg; - QDataStream writeStream(&initMsg, QIODevice::WriteOnly); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - writeStream.setVersion(QDataStream::Qt_5_6); -#endif - - writeStream << blockServerName.toLatin1(); - writeStream << static_cast(connectionType); - writeStream << instanceNumber; - quint16 checksum = qChecksum(initMsg.constData(), static_cast(initMsg.length())); - writeStream << checksum; - - // The header indicates the message length that follows - QByteArray header; - QDataStream headerStream(&header, QIODevice::WriteOnly); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - headerStream.setVersion(QDataStream::Qt_5_6); -#endif - headerStream << static_cast ( initMsg.length() ); - - socket->write( header ); - socket->write( initMsg ); - socket->flush(); - socket->waitForBytesWritten( msecs ); - qDebug() << "111111111111111111111111111111"; - } -} - -quint16 SingleApplicationPrivate::blockChecksum() -{ - return qChecksum( - static_cast ( memory->data() ), - offsetof( InstancesInfo, checksum ) - ); -} - -qint64 SingleApplicationPrivate::primaryPid() -{ - qint64 pid; - - memory->lock(); - InstancesInfo* inst = static_cast( memory->data() ); - pid = inst->primaryPid; - memory->unlock(); - - return pid; -} - -/** - * @brief Executed when a connection has been made to the LocalServer - */ -void SingleApplicationPrivate::slotConnectionEstablished() -{ - QLocalSocket *nextConnSocket = server->nextPendingConnection(); - connectionMap.insert(nextConnSocket, ConnectionInfo()); - - QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose, - [nextConnSocket, this]() { - auto &info = connectionMap[nextConnSocket]; - Q_EMIT this->slotClientConnectionClosed( nextConnSocket, info.instanceId ); - } - ); - - QObject::connect(nextConnSocket, &QLocalSocket::disconnected, - [nextConnSocket, this](){ - connectionMap.remove(nextConnSocket); - nextConnSocket->deleteLater(); - } - ); - - QObject::connect(nextConnSocket, &QLocalSocket::readyRead, - [nextConnSocket, this]() { - auto &info = connectionMap[nextConnSocket]; - switch(info.stage) { - case StageHeader: - readInitMessageHeader(nextConnSocket); - break; - case StageBody: - readInitMessageBody(nextConnSocket); - break; - case StageConnected: - Q_EMIT this->slotDataAvailable( nextConnSocket, info.instanceId ); - break; - default: - break; - }; - } - ); -} - -void SingleApplicationPrivate::readInitMessageHeader( QLocalSocket *sock ) -{ - if (!connectionMap.contains( sock )) { - return; - } - - if( sock->bytesAvailable() < ( qint64 )sizeof( quint64 ) ) { - return; - } - - QDataStream headerStream( sock ); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - headerStream.setVersion( QDataStream::Qt_5_6 ); -#endif - - // Read the header to know the message length - quint64 msgLen = 0; - headerStream >> msgLen; - ConnectionInfo &info = connectionMap[sock]; - info.stage = StageBody; - info.msgLen = msgLen; - - if ( sock->bytesAvailable() >= (qint64) msgLen ) { - readInitMessageBody( sock ); - } -} - -void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock ) -{ - Q_Q(SingleApplication); - - if (!connectionMap.contains( sock )) { - return; - } - - ConnectionInfo &info = connectionMap[sock]; - if( sock->bytesAvailable() < ( qint64 )info.msgLen ) { - return; - } - - // Read the message body - QByteArray msgBytes = sock->read(info.msgLen); - QDataStream readStream(msgBytes); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - readStream.setVersion( QDataStream::Qt_5_6 ); -#endif - - // server name - QByteArray latin1Name; - readStream >> latin1Name; - - // connection type - ConnectionType connectionType = InvalidConnection; - quint8 connTypeVal = InvalidConnection; - readStream >> connTypeVal; - connectionType = static_cast ( connTypeVal ); - - // instance id - quint32 instanceId = 0; - readStream >> instanceId; - - // checksum - quint16 msgChecksum = 0; - readStream >> msgChecksum; - - const quint16 actualChecksum = qChecksum( msgBytes.constData(), static_cast( msgBytes.length() - sizeof( quint16 ) ) ); - - bool isValid = readStream.status() == QDataStream::Ok && - QLatin1String(latin1Name) == blockServerName && - msgChecksum == actualChecksum; - - if( !isValid ) { - sock->close(); - return; - } - - info.instanceId = instanceId; - info.stage = StageConnected; - - if( connectionType == NewInstance || - ( connectionType == SecondaryInstance && - options & SingleApplication::Mode::SecondaryNotification ) ) - { - Q_EMIT q->instanceStarted(); - } - - if (sock->bytesAvailable() > 0) { - Q_EMIT this->slotDataAvailable( sock, instanceId ); - } -} - -void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId ) -{ - Q_Q(SingleApplication); - Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() ); -} - -void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId ) -{ - if( closedSocket->bytesAvailable() > 0 ) - Q_EMIT slotDataAvailable( closedSocket, instanceId ); -} +// The MIT License (MIT) +// +// Copyright (c) Itay Grudev 2015 - 2018 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// +// W A R N I N G !!! +// ----------------- +// +// This file is not part of the SingleApplication API. It is used purely as an +// implementation detail. This header file may change from version to +// version without notice, or may even be removed. +// + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "SingleApplication.h" +#include "SingleApplication_p.h" + +#include +#ifdef Q_OS_UNIX + #include + #include + #include +#endif + +#ifdef Q_OS_WIN + #include + #include +#endif + +SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) + : q_ptr( q_ptr ) +{ + server = nullptr; + socket = nullptr; + memory = nullptr; + instanceNumber = -1; +} + +SingleApplicationPrivate::~SingleApplicationPrivate() +{ + if( socket != nullptr ) { + socket->close(); + delete socket; + } + + memory->lock(); + InstancesInfo* inst = static_cast(memory->data()); + if( server != nullptr ) { + server->close(); + delete server; + inst->primary = false; + inst->primaryPid = -1; + inst->checksum = blockChecksum(); + } + memory->unlock(); + + delete memory; +} + +void SingleApplicationPrivate::genBlockServerName() +{ + QCryptographicHash appData( QCryptographicHash::Sha256 ); + appData.addData( "SingleApplication", 17 ); + appData.addData( SingleApplication::app_t::applicationName().toUtf8() ); + appData.addData( SingleApplication::app_t::organizationName().toUtf8() ); + appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() ); + + if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ) { + appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() ); + } + + if( ! (options & SingleApplication::Mode::ExcludeAppPath) ) { +#ifdef Q_OS_WIN + appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() ); +#else + appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() ); +#endif + } + + // User level block requires a user specific data in the hash + if( options & SingleApplication::Mode::User ) { +#ifdef Q_OS_WIN + wchar_t username [ UNLEN + 1 ]; + // Specifies size of the buffer on input + DWORD usernameLength = UNLEN + 1; + if( GetUserNameW( username, &usernameLength ) ) { + appData.addData( QString::fromWCharArray(username).toUtf8() ); + } else { + appData.addData( qgetenv("USERNAME") ); + } +#endif +#ifdef Q_OS_UNIX + QByteArray username; + uid_t uid = geteuid(); + struct passwd *pw = getpwuid(uid); + if( pw ) { + username = pw->pw_name; + } + if( username.isEmpty() ) { + username = qgetenv("USER"); + } + appData.addData(username); +#endif + } + + // Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with + // server naming requirements. + blockServerName = appData.result().toBase64().replace("/", "_"); +} + +void SingleApplicationPrivate::initializeMemoryBlock() +{ + InstancesInfo* inst = static_cast( memory->data() ); + inst->primary = false; + inst->secondary = 0; + inst->primaryPid = -1; + inst->checksum = blockChecksum(); +} + +void SingleApplicationPrivate::startPrimary() +{ + Q_Q(SingleApplication); + + // Successful creation means that no main process exists + // So we start a QLocalServer to listen for connections + QLocalServer::removeServer( blockServerName ); + server = new QLocalServer(); + + // Restrict access to the socket according to the + // SingleApplication::Mode::User flag on User level or no restrictions + if( options & SingleApplication::Mode::User ) { + server->setSocketOptions( QLocalServer::UserAccessOption ); + } else { + server->setSocketOptions( QLocalServer::WorldAccessOption ); + } + + server->listen( blockServerName ); + QObject::connect( + server, + &QLocalServer::newConnection, + this, + &SingleApplicationPrivate::slotConnectionEstablished + ); + + // Reset the number of connections + InstancesInfo* inst = static_cast ( memory->data() ); + + inst->primary = true; + inst->primaryPid = q->applicationPid(); + inst->checksum = blockChecksum(); + + instanceNumber = 0; +} + +void SingleApplicationPrivate::startSecondary() +{ +} + +void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType ) +{ + // Connect to the Local Server of the Primary Instance if not already + // connected. + if( socket == nullptr ) { + socket = new QLocalSocket(); + } + // If already connected - we are done; + if( socket->state() == QLocalSocket::ConnectedState ) + return; + + // If not connect + if( socket->state() == QLocalSocket::UnconnectedState || + socket->state() == QLocalSocket::ClosingState ) { + socket->connectToServer( blockServerName ); + } + + // Wait for being connected + if( socket->state() == QLocalSocket::ConnectingState ) { + socket->waitForConnected( msecs ); + } + + // Initialisation message according to the SingleApplication protocol + if( socket->state() == QLocalSocket::ConnectedState ) { + // Notify the parent that a new instance had been started; + QByteArray initMsg; + QDataStream writeStream(&initMsg, QIODevice::WriteOnly); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) + writeStream.setVersion(QDataStream::Qt_5_6); +#endif + + writeStream << blockServerName.toLatin1(); + writeStream << static_cast(connectionType); + writeStream << instanceNumber; + quint16 checksum = qChecksum(initMsg.constData(), static_cast(initMsg.length())); + writeStream << checksum; + + // The header indicates the message length that follows + QByteArray header; + QDataStream headerStream(&header, QIODevice::WriteOnly); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) + headerStream.setVersion(QDataStream::Qt_5_6); +#endif + headerStream << static_cast ( initMsg.length() ); + + socket->write( header ); + socket->write( initMsg ); + socket->flush(); + socket->waitForBytesWritten( msecs ); + qDebug() << "111111111111111111111111111111"; + } +} + +quint16 SingleApplicationPrivate::blockChecksum() +{ + return qChecksum( + static_cast ( memory->data() ), + offsetof( InstancesInfo, checksum ) + ); +} + +qint64 SingleApplicationPrivate::primaryPid() +{ + qint64 pid; + + memory->lock(); + InstancesInfo* inst = static_cast( memory->data() ); + pid = inst->primaryPid; + memory->unlock(); + + return pid; +} + +/** + * @brief Executed when a connection has been made to the LocalServer + */ +void SingleApplicationPrivate::slotConnectionEstablished() +{ + QLocalSocket *nextConnSocket = server->nextPendingConnection(); + connectionMap.insert(nextConnSocket, ConnectionInfo()); + + QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose, + [nextConnSocket, this]() { + auto &info = connectionMap[nextConnSocket]; + Q_EMIT this->slotClientConnectionClosed( nextConnSocket, info.instanceId ); + } + ); + + QObject::connect(nextConnSocket, &QLocalSocket::disconnected, + [nextConnSocket, this](){ + connectionMap.remove(nextConnSocket); + nextConnSocket->deleteLater(); + } + ); + + QObject::connect(nextConnSocket, &QLocalSocket::readyRead, + [nextConnSocket, this]() { + auto &info = connectionMap[nextConnSocket]; + switch(info.stage) { + case StageHeader: + readInitMessageHeader(nextConnSocket); + break; + case StageBody: + readInitMessageBody(nextConnSocket); + break; + case StageConnected: + Q_EMIT this->slotDataAvailable( nextConnSocket, info.instanceId ); + break; + default: + break; + }; + } + ); +} + +void SingleApplicationPrivate::readInitMessageHeader( QLocalSocket *sock ) +{ + if (!connectionMap.contains( sock )) { + return; + } + + if( sock->bytesAvailable() < ( qint64 )sizeof( quint64 ) ) { + return; + } + + QDataStream headerStream( sock ); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) + headerStream.setVersion( QDataStream::Qt_5_6 ); +#endif + + // Read the header to know the message length + quint64 msgLen = 0; + headerStream >> msgLen; + ConnectionInfo &info = connectionMap[sock]; + info.stage = StageBody; + info.msgLen = msgLen; + + if ( sock->bytesAvailable() >= (qint64) msgLen ) { + readInitMessageBody( sock ); + } +} + +void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock ) +{ + Q_Q(SingleApplication); + + if (!connectionMap.contains( sock )) { + return; + } + + ConnectionInfo &info = connectionMap[sock]; + if( sock->bytesAvailable() < ( qint64 )info.msgLen ) { + return; + } + + // Read the message body + QByteArray msgBytes = sock->read(info.msgLen); + QDataStream readStream(msgBytes); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) + readStream.setVersion( QDataStream::Qt_5_6 ); +#endif + + // server name + QByteArray latin1Name; + readStream >> latin1Name; + + // connection type + ConnectionType connectionType = InvalidConnection; + quint8 connTypeVal = InvalidConnection; + readStream >> connTypeVal; + connectionType = static_cast ( connTypeVal ); + + // instance id + quint32 instanceId = 0; + readStream >> instanceId; + + // checksum + quint16 msgChecksum = 0; + readStream >> msgChecksum; + + const quint16 actualChecksum = qChecksum( msgBytes.constData(), static_cast( msgBytes.length() - sizeof( quint16 ) ) ); + + bool isValid = readStream.status() == QDataStream::Ok && + QLatin1String(latin1Name) == blockServerName && + msgChecksum == actualChecksum; + + if( !isValid ) { + sock->close(); + return; + } + + info.instanceId = instanceId; + info.stage = StageConnected; + + if( connectionType == NewInstance || + ( connectionType == SecondaryInstance && + options & SingleApplication::Mode::SecondaryNotification ) ) + { + Q_EMIT q->instanceStarted(); + } + + if (sock->bytesAvailable() > 0) { + Q_EMIT this->slotDataAvailable( sock, instanceId ); + } +} + +void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId ) +{ + Q_Q(SingleApplication); + Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() ); +} + +void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId ) +{ + if( closedSocket->bytesAvailable() > 0 ) + Q_EMIT slotDataAvailable( closedSocket, instanceId ); +} diff --git a/product/src/gui/plugin/ReportApp/SingleApplication_p.h b/product/src/gui/plugin/ReportApp/SingleApplication_p.h index 2282d177..c88a4d6d 100644 --- a/product/src/gui/plugin/ReportApp/SingleApplication_p.h +++ b/product/src/gui/plugin/ReportApp/SingleApplication_p.h @@ -1,99 +1,99 @@ -// The MIT License (MIT) -// -// Copyright (c) Itay Grudev 2015 - 2016 -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -// -// W A R N I N G !!! -// ----------------- -// -// This file is not part of the SingleApplication API. It is used purely as an -// implementation detail. This header file may change from version to -// version without notice, or may even be removed. -// - -#ifndef SINGLEAPPLICATION_P_H -#define SINGLEAPPLICATION_P_H - -#include -#include -#include -#include "SingleApplication.h" - -struct InstancesInfo { - bool primary; - quint32 secondary; - qint64 primaryPid; - quint16 checksum; -}; - -struct ConnectionInfo { - explicit ConnectionInfo() : - msgLen(0), instanceId(0), stage(0) {} - qint64 msgLen; - quint32 instanceId; - quint8 stage; -}; - -class SingleApplicationPrivate : public QObject { -Q_OBJECT -public: - enum ConnectionType : quint8 { - InvalidConnection = 0, - NewInstance = 1, - SecondaryInstance = 2, - Reconnect = 3 - }; - enum ConnectionStage : quint8 { - StageHeader = 0, - StageBody = 1, - StageConnected = 2, - }; - Q_DECLARE_PUBLIC(SingleApplication) - - SingleApplicationPrivate( SingleApplication *q_ptr ); - ~SingleApplicationPrivate(); - - void genBlockServerName(); - void initializeMemoryBlock(); - void startPrimary(); - void startSecondary(); - void connectToPrimary(int msecs, ConnectionType connectionType ); - quint16 blockChecksum(); - qint64 primaryPid(); - void readInitMessageHeader(QLocalSocket *socket); - void readInitMessageBody(QLocalSocket *socket); - - SingleApplication *q_ptr; - QSharedMemory *memory; - QLocalSocket *socket; - QLocalServer *server; - quint32 instanceNumber; - QString blockServerName; - SingleApplication::Options options; - QMap connectionMap; - -public Q_SLOTS: - void slotConnectionEstablished(); - void slotDataAvailable( QLocalSocket*, quint32 ); - void slotClientConnectionClosed( QLocalSocket*, quint32 ); -}; - -#endif // SINGLEAPPLICATION_P_H +// The MIT License (MIT) +// +// Copyright (c) Itay Grudev 2015 - 2016 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// +// W A R N I N G !!! +// ----------------- +// +// This file is not part of the SingleApplication API. It is used purely as an +// implementation detail. This header file may change from version to +// version without notice, or may even be removed. +// + +#ifndef SINGLEAPPLICATION_P_H +#define SINGLEAPPLICATION_P_H + +#include +#include +#include +#include "SingleApplication.h" + +struct InstancesInfo { + bool primary; + quint32 secondary; + qint64 primaryPid; + quint16 checksum; +}; + +struct ConnectionInfo { + explicit ConnectionInfo() : + msgLen(0), instanceId(0), stage(0) {} + qint64 msgLen; + quint32 instanceId; + quint8 stage; +}; + +class SingleApplicationPrivate : public QObject { +Q_OBJECT +public: + enum ConnectionType : quint8 { + InvalidConnection = 0, + NewInstance = 1, + SecondaryInstance = 2, + Reconnect = 3 + }; + enum ConnectionStage : quint8 { + StageHeader = 0, + StageBody = 1, + StageConnected = 2, + }; + Q_DECLARE_PUBLIC(SingleApplication) + + SingleApplicationPrivate( SingleApplication *q_ptr ); + ~SingleApplicationPrivate(); + + void genBlockServerName(); + void initializeMemoryBlock(); + void startPrimary(); + void startSecondary(); + void connectToPrimary(int msecs, ConnectionType connectionType ); + quint16 blockChecksum(); + qint64 primaryPid(); + void readInitMessageHeader(QLocalSocket *socket); + void readInitMessageBody(QLocalSocket *socket); + + SingleApplication *q_ptr; + QSharedMemory *memory; + QLocalSocket *socket; + QLocalServer *server; + quint32 instanceNumber; + QString blockServerName; + SingleApplication::Options options; + QMap connectionMap; + +public Q_SLOTS: + void slotConnectionEstablished(); + void slotDataAvailable( QLocalSocket*, quint32 ); + void slotClientConnectionClosed( QLocalSocket*, quint32 ); +}; + +#endif // SINGLEAPPLICATION_P_H diff --git a/product/src/gui/plugin/ReportApp/main.cpp b/product/src/gui/plugin/ReportApp/main.cpp index 5e82403f..577e0f47 100644 --- a/product/src/gui/plugin/ReportApp/main.cpp +++ b/product/src/gui/plugin/ReportApp/main.cpp @@ -1,56 +1,56 @@ -#include -#include -#include "common/QtAppGlobalSet.h" -#include "SingleApplication.h" -#include "CReportWidget.h" - -class SingleApplication; -int main(int argc, char *argv[]) -{ - kbd_common::doQtAppGlobalSet(); - - SingleApplication app(argc, argv); - - QMap m_mapArgv; - QString strKey; - for (int i = 1; i < argc; ++i) - { - if(i % 2 == 0) - { - m_mapArgv.insert(strKey, argv[i]); - } - else - { - strKey = argv[i]; - } - } - - int offset = 0; - if(m_mapArgv.value("-h") != QString()) - { - offset = m_mapArgv.value("-h").toInt(); - } - QString language = m_mapArgv.value("-l", "zh"); - - CReportWidget w(language); - w.setWindowIcon(QIcon(":/ReportEdit.ico")); - //< 防止多屏时展示到其他屏幕 - w.setFixedSize(QApplication::desktop()->screen(-1)->width(),QApplication::desktop()->screen(-1)->height()-offset); - QObject::connect(&app, &SingleApplication::instanceStarted, [&w]() { - w.printLog("instanceStarted"); -#ifdef Q_OS_WIN - w.showMaximized(); -#else - w.show(); -#endif - w.activateWindow(); - }); - -#ifdef Q_OS_WIN - w.showMaximized(); -#else - w.show(); -#endif - - return app.exec(); -} +#include +#include +#include "common/QtAppGlobalSet.h" +#include "SingleApplication.h" +#include "CReportWidget.h" + +class SingleApplication; +int main(int argc, char *argv[]) +{ + kbd_common::doQtAppGlobalSet(); + + SingleApplication app(argc, argv); + + QMap m_mapArgv; + QString strKey; + for (int i = 1; i < argc; ++i) + { + if(i % 2 == 0) + { + m_mapArgv.insert(strKey, argv[i]); + } + else + { + strKey = argv[i]; + } + } + + int offset = 0; + if(m_mapArgv.value("-h") != QString()) + { + offset = m_mapArgv.value("-h").toInt(); + } + QString language = m_mapArgv.value("-l", "zh"); + + CReportWidget w(language); + w.setWindowIcon(QIcon(":/ReportEdit.ico")); + //< 防止多屏时展示到其他屏幕 + w.setFixedSize(QApplication::desktop()->screen(-1)->width(),QApplication::desktop()->screen(-1)->height()-offset); + QObject::connect(&app, &SingleApplication::instanceStarted, [&w]() { + w.printLog("instanceStarted"); +#ifdef Q_OS_WIN + w.showMaximized(); +#else + w.show(); +#endif + w.activateWindow(); + }); + +#ifdef Q_OS_WIN + w.showMaximized(); +#else + w.show(); +#endif + + return app.exec(); +} diff --git a/product/src/gui/plugin/ReportApp/resource.qrc b/product/src/gui/plugin/ReportApp/resource.qrc index b79568c5..fc6ff93f 100644 --- a/product/src/gui/plugin/ReportApp/resource.qrc +++ b/product/src/gui/plugin/ReportApp/resource.qrc @@ -1,6 +1,6 @@ - - - report.png - ReportEdit.ico - - + + + report.png + ReportEdit.ico + + diff --git a/product/src/gui/plugin/ReportWidget/CReportPluginWidget.cpp b/product/src/gui/plugin/ReportWidget/CReportPluginWidget.cpp index 0fc5be70..9d375667 100644 --- a/product/src/gui/plugin/ReportWidget/CReportPluginWidget.cpp +++ b/product/src/gui/plugin/ReportWidget/CReportPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CReportPluginWidget.h" -#include "CReportWidget.h" - -CReportPluginWidget::CReportPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CReportPluginWidget::~CReportPluginWidget() -{ - -} - -bool CReportPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CReportWidget *pWidget = new CReportWidget(parent,editMode); - *widget = (QWidget *)pWidget; - *reportWidget = (IPluginWidget *)pWidget; - return true; -} - -void CReportPluginWidget::release() -{ - -} +#include +#include "CReportPluginWidget.h" +#include "CReportWidget.h" + +CReportPluginWidget::CReportPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CReportPluginWidget::~CReportPluginWidget() +{ + +} + +bool CReportPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CReportWidget *pWidget = new CReportWidget(parent,editMode); + *widget = (QWidget *)pWidget; + *reportWidget = (IPluginWidget *)pWidget; + return true; +} + +void CReportPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ReportWidget/CReportPluginWidget.h b/product/src/gui/plugin/ReportWidget/CReportPluginWidget.h index af5ba798..c4243eb7 100644 --- a/product/src/gui/plugin/ReportWidget/CReportPluginWidget.h +++ b/product/src/gui/plugin/ReportWidget/CReportPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CREPORTPLUGINWIDGET_H -#define CREPORTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CReportPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CReportPluginWidget(QObject *parent = 0); - ~CReportPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); - void release(); -}; - -#endif // CREPORTPLUGINWIDGET_H +#ifndef CREPORTPLUGINWIDGET_H +#define CREPORTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CReportPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CReportPluginWidget(QObject *parent = 0); + ~CReportPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); + void release(); +}; + +#endif // CREPORTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/ReportWidget/CReportStackedWidget.cpp b/product/src/gui/plugin/ReportWidget/CReportStackedWidget.cpp index eeb664aa..31339ab0 100644 --- a/product/src/gui/plugin/ReportWidget/CReportStackedWidget.cpp +++ b/product/src/gui/plugin/ReportWidget/CReportStackedWidget.cpp @@ -1,73 +1,73 @@ -#include "CReportStackedWidget.h" - -CReportStackedWidget::CReportStackedWidget(QWidget *parent) - : QStackedWidget(parent), - view(Q_NULLPTR), - preview(Q_NULLPTR) -{ - init(); -} - -CReportStackedWidget::~CReportStackedWidget() -{ - realease(); -} - -void CReportStackedWidget::init() -{ - view = new CReportWebView(this); - preview = new CReportWebView(this); - this->addWidget(view); - QWidget *previewWidget = new QWidget(this); - QPushButton *backToViewBtn = new QPushButton(this); - QVBoxLayout* vlay = new QVBoxLayout(this); - backToViewBtn->setText(tr("返回")); - vlay->setMargin(0); - vlay->addWidget(preview); - vlay->addWidget(backToViewBtn); - previewWidget->setLayout(vlay); - this->addWidget(previewWidget); - this->setCurrentIndex(0); - connect(backToViewBtn, &QPushButton::clicked, this, &CReportStackedWidget::slotBackBtnClicked); - - //< 在qApp->quit()调用之前需释放QWebEngineView,否则会触发Check failed: client_map_.empty(). - connect(qApp, &QCoreApplication::aboutToQuit, this, &CReportStackedWidget::realease); -} - -void CReportStackedWidget::slotBackBtnClicked() -{ - this->setCurrentIndex(0); - preview->load(QUrl("about:blank")); -} - -CReportWebView *CReportStackedWidget::getView(int index) -{ - if (index == 0) - { - return view; - } - else if (index == 1) - { - this->setCurrentIndex(1); - return preview; - } - else - { - return NULL; - } -} - -void CReportStackedWidget::realease() -{ - if(view != Q_NULLPTR) - { - delete view; - } - view = Q_NULLPTR; - - if(preview != Q_NULLPTR) - { - delete preview; - } - preview = Q_NULLPTR; -} +#include "CReportStackedWidget.h" + +CReportStackedWidget::CReportStackedWidget(QWidget *parent) + : QStackedWidget(parent), + view(Q_NULLPTR), + preview(Q_NULLPTR) +{ + init(); +} + +CReportStackedWidget::~CReportStackedWidget() +{ + realease(); +} + +void CReportStackedWidget::init() +{ + view = new CReportWebView(this); + preview = new CReportWebView(this); + this->addWidget(view); + QWidget *previewWidget = new QWidget(this); + QPushButton *backToViewBtn = new QPushButton(this); + QVBoxLayout* vlay = new QVBoxLayout(this); + backToViewBtn->setText(tr("返回")); + vlay->setMargin(0); + vlay->addWidget(preview); + vlay->addWidget(backToViewBtn); + previewWidget->setLayout(vlay); + this->addWidget(previewWidget); + this->setCurrentIndex(0); + connect(backToViewBtn, &QPushButton::clicked, this, &CReportStackedWidget::slotBackBtnClicked); + + //< 在qApp->quit()调用之前需释放QWebEngineView,否则会触发Check failed: client_map_.empty(). + connect(qApp, &QCoreApplication::aboutToQuit, this, &CReportStackedWidget::realease); +} + +void CReportStackedWidget::slotBackBtnClicked() +{ + this->setCurrentIndex(0); + preview->load(QUrl("about:blank")); +} + +CReportWebView *CReportStackedWidget::getView(int index) +{ + if (index == 0) + { + return view; + } + else if (index == 1) + { + this->setCurrentIndex(1); + return preview; + } + else + { + return NULL; + } +} + +void CReportStackedWidget::realease() +{ + if(view != Q_NULLPTR) + { + delete view; + } + view = Q_NULLPTR; + + if(preview != Q_NULLPTR) + { + delete preview; + } + preview = Q_NULLPTR; +} diff --git a/product/src/gui/plugin/ReportWidget/CReportStackedWidget.h b/product/src/gui/plugin/ReportWidget/CReportStackedWidget.h index 915ad56d..0eaf354d 100644 --- a/product/src/gui/plugin/ReportWidget/CReportStackedWidget.h +++ b/product/src/gui/plugin/ReportWidget/CReportStackedWidget.h @@ -1,26 +1,26 @@ -#ifndef CREPORTSTACKEDWIDGET_H -#define CREPORTSTACKEDWIDGET_H -#include "CReportWebView.h" -#include "CReportWidget.h" -#include -#include -#include -class CReportWebView; -class CReportStackedWidget: public QStackedWidget -{ - Q_OBJECT -public: - CReportStackedWidget(QWidget *parent = nullptr); - ~CReportStackedWidget(); - CReportWebView *view; - CReportWebView *preview; -public slots: - CReportWebView *getView(int index); -private: - void init(); - void slotBackBtnClicked(); -private slots: - void realease(); -}; - -#endif // CREPORTSTACKEDWIDGET_H +#ifndef CREPORTSTACKEDWIDGET_H +#define CREPORTSTACKEDWIDGET_H +#include "CReportWebView.h" +#include "CReportWidget.h" +#include +#include +#include +class CReportWebView; +class CReportStackedWidget: public QStackedWidget +{ + Q_OBJECT +public: + CReportStackedWidget(QWidget *parent = nullptr); + ~CReportStackedWidget(); + CReportWebView *view; + CReportWebView *preview; +public slots: + CReportWebView *getView(int index); +private: + void init(); + void slotBackBtnClicked(); +private slots: + void realease(); +}; + +#endif // CREPORTSTACKEDWIDGET_H diff --git a/product/src/gui/plugin/ReportWidget/CReportWebView.cpp b/product/src/gui/plugin/ReportWidget/CReportWebView.cpp index f5e7e490..0193d1b3 100644 --- a/product/src/gui/plugin/ReportWidget/CReportWebView.cpp +++ b/product/src/gui/plugin/ReportWidget/CReportWebView.cpp @@ -1,22 +1,22 @@ -#include "CReportWebView.h" - -CReportWebView::CReportWebView(QWidget *parent) - : QWebEngineView(parent) -{ - this->setContextMenuPolicy(Qt::NoContextMenu); - this->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled,false); - this->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); - this->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); -} - -QWebEngineView *CReportWebView::createWindow(QWebEnginePage::WebWindowType type) -{ - Q_UNUSED(type) - CReportStackedWidget *StackedWidget = qobject_cast(parentWidget()); - if (!StackedWidget) - { - return nullptr; - } - return StackedWidget->getView(1); -} - +#include "CReportWebView.h" + +CReportWebView::CReportWebView(QWidget *parent) + : QWebEngineView(parent) +{ + this->setContextMenuPolicy(Qt::NoContextMenu); + this->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled,false); + this->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); + this->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); +} + +QWebEngineView *CReportWebView::createWindow(QWebEnginePage::WebWindowType type) +{ + Q_UNUSED(type) + CReportStackedWidget *StackedWidget = qobject_cast(parentWidget()); + if (!StackedWidget) + { + return nullptr; + } + return StackedWidget->getView(1); +} + diff --git a/product/src/gui/plugin/ReportWidget/CReportWebView.h b/product/src/gui/plugin/ReportWidget/CReportWebView.h index 9d25eac0..fecafd47 100644 --- a/product/src/gui/plugin/ReportWidget/CReportWebView.h +++ b/product/src/gui/plugin/ReportWidget/CReportWebView.h @@ -1,17 +1,17 @@ -#ifndef CREPORTWEBVIEW_H -#define CREPORTWEBVIEW_H - -#include -#include -#include -class CReportWebView : public QWebEngineView -{ - Q_OBJECT -public: - CReportWebView(QWidget *parent = nullptr); - -protected: - QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override; -}; - -#endif // CREPORTWEBVIEW_H +#ifndef CREPORTWEBVIEW_H +#define CREPORTWEBVIEW_H + +#include +#include +#include +class CReportWebView : public QWebEngineView +{ + Q_OBJECT +public: + CReportWebView(QWidget *parent = nullptr); + +protected: + QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override; +}; + +#endif // CREPORTWEBVIEW_H diff --git a/product/src/gui/plugin/ReportWidget/CReportWidget.cpp b/product/src/gui/plugin/ReportWidget/CReportWidget.cpp index 45901a7e..847efcb4 100644 --- a/product/src/gui/plugin/ReportWidget/CReportWidget.cpp +++ b/product/src/gui/plugin/ReportWidget/CReportWidget.cpp @@ -1,381 +1,381 @@ -#include "CReportWidget.h" -#include "QDomDocument" -#include "pub_utility_api/FileStyle.h" - -CReportWidget::CReportWidget(QWidget *parent, bool editMode) - : QWidget(parent) -{ - m_updateTimer = NULL; - stackedWidget = NULL; - m_rtdbAccess = NULL; - if(editMode) - { - QLabel *label = new QLabel(this); - label->setPixmap(QPixmap(":/report")); - label->setScaledContents(true); - QGridLayout *lay = new QGridLayout(this); - lay->addWidget(label); - this->setLayout(lay); - } - else - { - init(); - } -} - -CReportWidget::~CReportWidget() -{ - if(m_updateTimer) - { - m_updateTimer->stop(); - delete m_updateTimer; - m_updateTimer = NULL; - } - if(stackedWidget) - { - QWebEngineProfile * engineProfile = stackedWidget->view->page()->profile(); - engineProfile->clearHttpCache(); - QWebEngineCookieStore *cookie = engineProfile->cookieStore(); - cookie->deleteAllCookies(); - stackedWidget = NULL; - } - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; -} - - -void CReportWidget::init() -{ - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); - stackedWidget = new CReportStackedWidget(this); - QHBoxLayout* hlay = new QHBoxLayout(this); - hlay->addWidget(stackedWidget); - hlay->setMargin(0); - this->setLayout(hlay); - m_updateTimer = new QTimer(); - m_updateTimer->setInterval(5000); - connect(m_updateTimer, &QTimer::timeout, this, &CReportWidget::slotUpdateTime); - connect(stackedWidget->view, &QWebEngineView::loadFinished, this, &CReportWidget::slotLoadFinish); - connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, - this, &CReportWidget::handleDownloadRequest); - m_UsergId = -1; - m_isHTML = false; - m_changeAddr = false; - m_addrNum = 0; - m_strView = ":1120/page/view.html"; - m_strDesign = ":1120/page/design.html"; - initUrl(); - initSysInfo(); -} - -void CReportWidget::initUrl() -{ - QString strFileName = QString("..%1..%1data%1model%1report.xml").arg(QDir::separator()); - - QFile file(strFileName); - if (!file.open(QIODevice::ReadOnly)) - { - return; - } - - QDomDocument document; - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - QDomElement root = document.documentElement(); - if(!root.isNull()) - { - QDomNodeList viewList = root.elementsByTagName("View"); - if(viewList.length() > 0) - { - m_strView = viewList.at(0).toElement().attribute("html", QString()); - } - QDomNodeList designList = root.elementsByTagName("Design"); - if(designList.length() > 0) - { - m_strDesign = designList.at(0).toElement().attribute("html", QString()); - } - } -} - -void CReportWidget::initSysInfo() -{ - if (createSysInfoInstance(m_sysInfoPtr)) - { - SNodeInfo LocalNode,ServerNode1,ServerNode2; - m_sysInfoPtr->getLocalNodeInfo(LocalNode); //获取当前节点信息 - int DomainId=LocalNode.nDomainId; //获取当前节点所属域ID - SAppInfo AppInfo; - m_sysInfoPtr->getAppInfoByName("COMAPP", AppInfo); - int AppId = AppInfo.nId; - SAppDeploy AppDeploy; - m_sysInfoPtr->getAppDeployById(DomainId,AppId,AppDeploy); //获取当前域公共应用部署信息 - std::string ServerNodeName1 = AppDeploy.strNode1; //获取当前域公共应用部署的第一个节点名 - m_sysInfoPtr->getNodeInfoByName(ServerNodeName1,ServerNode1); //获取公共应用部署的节点信息 - m_ServerAddr[0] = ServerNode1.strNic1Addr; //获取公共应用部署的节点IP地址 - m_ServerNode[0] = ServerNodeName1; - if(AppDeploy.strNode2 != "") - { - std::string ServerNodeName2 = AppDeploy.strNode2; - m_sysInfoPtr->getNodeInfoByName(ServerNodeName2,ServerNode2); - m_ServerAddr[1] = ServerNode2.strNic1Addr; - m_ServerNode[1] = ServerNodeName2; - m_changeAddr = true; - } - setNicAddr(AppId); - } -} - -void CReportWidget::setNicAddr(int appId) -{ - std::string ipAddr1 = ""; - std::string ipAddr2 = ""; - std::string node1 = ""; - std::string node2 = ""; - std::vector> vector = getRunRedundancyInfoByAppid(appId); - for(size_t i=0; i vec = vector.at(i); - std::string node_name = vec.at(0).toStdString(); - int is_active = vec.at(1).toInt(); - int is_master = vec.at(2).toInt(); - int is_slave = vec.at(3).toInt(); - std::string ip1 = vec.at(4).toStdString(); - int ip1_active = vec.at(5).toInt(); - std::string ip2 = vec.at(6).toStdString(); - int ip2_active = vec.at(7).toInt(); - - if(is_active != 1) - { - continue; - } - if(is_master == 1) - { - node1 = node_name; - if(ip1_active == 1) - ipAddr1 = ip1; - else if(ip2_active == 1) - ipAddr1 = ip2; - } - else if(is_slave == 1) - { - node2 = node_name; - if(ip1_active == 1) - ipAddr2 = ip1; - else if(ip2_active == 1) - ipAddr2 = ip2; - } - } - if(ipAddr1 == "" && ipAddr2 == "") - {} - else if(ipAddr1 == "") - { - std::string temp = getAnotherIp(node2); - m_ServerAddr[0] = temp; - m_ServerAddr[1] = ipAddr2; - } - else if(ipAddr2 == "") - { - std::string temp = getAnotherIp(node1); - m_ServerAddr[0] = ipAddr1; - m_ServerAddr[1] = temp; - } - else - { - m_ServerAddr[0] = ipAddr1; - m_ServerAddr[1] = ipAddr2; - } -} - -std::string CReportWidget::getAnotherIp(const std::string &node) -{ - std::string ret = ""; - if(node == m_ServerNode[0]) - { - ret = m_ServerAddr[1]; - } - else - { - ret = m_ServerAddr[0]; - } - return ret; -} - -std::vector> CReportWidget::getRunRedundancyInfoByAppid(int appId) -{ - std::vector> vector; - if(m_rtdbAccess->open("base", "sys_run_redundancy_info")) - { - kbd_dbms::CONDINFO condition; - memcpy(condition.name, "app_id", strlen("app_id")); - condition.logicalop = ATTRCOND_AND; - condition.relationop = ATTRCOND_EQU; - condition.conditionval = appId; - - std::vector vecCondInfo; - vecCondInfo.push_back(condition); - - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("node_name"); - columns.push_back("is_active"); - columns.push_back("is_master"); - columns.push_back("is_slave"); - columns.push_back("ip1"); - columns.push_back("ip1_active"); - columns.push_back("ip2"); - columns.push_back("ip2_active"); - - if(m_rtdbAccess->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - std::vector temp; - kbd_dbms::CVarType node_name; - kbd_dbms::CVarType is_active; - kbd_dbms::CVarType is_master; - kbd_dbms::CVarType is_slave; - kbd_dbms::CVarType ip1; - kbd_dbms::CVarType ip1_active; - kbd_dbms::CVarType ip2; - kbd_dbms::CVarType ip2_active; - result.getColumnValue(nIndex, 0, node_name); - result.getColumnValue(nIndex, 1, is_active); - result.getColumnValue(nIndex, 2, is_master); - result.getColumnValue(nIndex, 3, is_slave); - result.getColumnValue(nIndex, 4, ip1); - result.getColumnValue(nIndex, 5, ip1_active); - result.getColumnValue(nIndex, 6, ip2); - result.getColumnValue(nIndex, 7, ip2_active); - temp.push_back(node_name); - temp.push_back(is_active); - temp.push_back(is_master); - temp.push_back(is_slave); - temp.push_back(ip1); - temp.push_back(ip1_active); - temp.push_back(ip2); - temp.push_back(ip2_active); - vector.push_back(temp); - } - } - m_rtdbAccess->close(); - } - return vector; -} - -void CReportWidget::updateUserInfo() -{ - m_permMngPtr = kbd_service::getPermMngInstance("base"); - m_permMngPtr->PermDllInit(); - if (m_permMngPtr != NULL) - { - int UserId,UsergId,Level,LoginSec; - std::string UserName; - m_permMngPtr->CurUser(UserId,UsergId,Level,LoginSec,UserName); //获取当前登陆用户的所属用户组ID - if (UsergId != m_UsergId) - { - m_UsergId = UsergId; - } - loadPage(); - } -} - -void CReportWidget::loadPage() -{ - m_isHTML = true; - std::string style = std::move(kbd_public::CFileStyle::getCurStyle()); - if(m_browserMode == ViewMode) - { - QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum])+m_strView; - QUrl url(urlstr); - QUrlQuery query; - query.addQueryItem("userGroup", QString::number(m_UsergId)); - query.addQueryItem("theme", QString::fromStdString(style)); - url.setQuery(query); - stackedWidget->view->load(url); - } - else if (m_browserMode == EditMode) - { - if(!checkReportEditPerm()) - { - std::string path = kbd_public::CFileUtil::getCurModuleDir(); - stackedWidget->view->load(QUrl::fromLocalFile(QString::fromStdString(path)+"../../data/report/PERM_FORBIT_EDIT.html")); - return; - } - QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum])+m_strDesign; - QUrl url(urlstr); - QUrlQuery query; - query.addQueryItem("theme", QString::fromStdString(style)); - url.setQuery(query); - stackedWidget->view->load(url); - } -} - -void CReportWidget::slotUpdateTime() -{ - m_updateTimer->stop(); - if (m_changeAddr) - { - m_addrNum = 1 - m_addrNum; - } - loadPage(); -} - -void CReportWidget::slotLoadFinish(bool ok) -{ - if(m_isHTML) - { - if (!ok) - { - std::string path = kbd_public::CFileUtil::getCurModuleDir(); - stackedWidget->view->load(QUrl::fromLocalFile(QString::fromStdString(path)+"../../data/report/FAIL_PAGE.html")); - if(m_changeAddr && !m_addrNum) - m_updateTimer->start(); - } - } - m_isHTML = false; -} - -void CReportWidget::handleDownloadRequest(QWebEngineDownloadItem *download) -{ - QString path = QFileDialog::getSaveFileName(this, tr("导出报表"), download->path()); - if (!path.isEmpty()) - { - download->setPath(path); - download->accept(); - } -} - -void CReportWidget::switchMode(int mode) -{ - m_browserMode = (browserMode)mode; - updateUserInfo(); -} - -void CReportWidget::UserChanged() -{ - updateUserInfo(); -} - -bool CReportWidget::checkReportEditPerm() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::string func = "FUNC_NOM_RPT_EDIT"; - if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &func)) - { - return true; - } - } - return false; -} +#include "CReportWidget.h" +#include "QDomDocument" +#include "pub_utility_api/FileStyle.h" + +CReportWidget::CReportWidget(QWidget *parent, bool editMode) + : QWidget(parent) +{ + m_updateTimer = NULL; + stackedWidget = NULL; + m_rtdbAccess = NULL; + if(editMode) + { + QLabel *label = new QLabel(this); + label->setPixmap(QPixmap(":/report")); + label->setScaledContents(true); + QGridLayout *lay = new QGridLayout(this); + lay->addWidget(label); + this->setLayout(lay); + } + else + { + init(); + } +} + +CReportWidget::~CReportWidget() +{ + if(m_updateTimer) + { + m_updateTimer->stop(); + delete m_updateTimer; + m_updateTimer = NULL; + } + if(stackedWidget) + { + QWebEngineProfile * engineProfile = stackedWidget->view->page()->profile(); + engineProfile->clearHttpCache(); + QWebEngineCookieStore *cookie = engineProfile->cookieStore(); + cookie->deleteAllCookies(); + stackedWidget = NULL; + } + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; +} + + +void CReportWidget::init() +{ + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + stackedWidget = new CReportStackedWidget(this); + QHBoxLayout* hlay = new QHBoxLayout(this); + hlay->addWidget(stackedWidget); + hlay->setMargin(0); + this->setLayout(hlay); + m_updateTimer = new QTimer(); + m_updateTimer->setInterval(5000); + connect(m_updateTimer, &QTimer::timeout, this, &CReportWidget::slotUpdateTime); + connect(stackedWidget->view, &QWebEngineView::loadFinished, this, &CReportWidget::slotLoadFinish); + connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, + this, &CReportWidget::handleDownloadRequest); + m_UsergId = -1; + m_isHTML = false; + m_changeAddr = false; + m_addrNum = 0; + m_strView = ":1120/page/view.html"; + m_strDesign = ":1120/page/design.html"; + initUrl(); + initSysInfo(); +} + +void CReportWidget::initUrl() +{ + QString strFileName = QString("..%1..%1data%1model%1report.xml").arg(QDir::separator()); + + QFile file(strFileName); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + + QDomDocument document; + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(!root.isNull()) + { + QDomNodeList viewList = root.elementsByTagName("View"); + if(viewList.length() > 0) + { + m_strView = viewList.at(0).toElement().attribute("html", QString()); + } + QDomNodeList designList = root.elementsByTagName("Design"); + if(designList.length() > 0) + { + m_strDesign = designList.at(0).toElement().attribute("html", QString()); + } + } +} + +void CReportWidget::initSysInfo() +{ + if (createSysInfoInstance(m_sysInfoPtr)) + { + SNodeInfo LocalNode,ServerNode1,ServerNode2; + m_sysInfoPtr->getLocalNodeInfo(LocalNode); //获取当前节点信息 + int DomainId=LocalNode.nDomainId; //获取当前节点所属域ID + SAppInfo AppInfo; + m_sysInfoPtr->getAppInfoByName("COMAPP", AppInfo); + int AppId = AppInfo.nId; + SAppDeploy AppDeploy; + m_sysInfoPtr->getAppDeployById(DomainId,AppId,AppDeploy); //获取当前域公共应用部署信息 + std::string ServerNodeName1 = AppDeploy.strNode1; //获取当前域公共应用部署的第一个节点名 + m_sysInfoPtr->getNodeInfoByName(ServerNodeName1,ServerNode1); //获取公共应用部署的节点信息 + m_ServerAddr[0] = ServerNode1.strNic1Addr; //获取公共应用部署的节点IP地址 + m_ServerNode[0] = ServerNodeName1; + if(AppDeploy.strNode2 != "") + { + std::string ServerNodeName2 = AppDeploy.strNode2; + m_sysInfoPtr->getNodeInfoByName(ServerNodeName2,ServerNode2); + m_ServerAddr[1] = ServerNode2.strNic1Addr; + m_ServerNode[1] = ServerNodeName2; + m_changeAddr = true; + } + setNicAddr(AppId); + } +} + +void CReportWidget::setNicAddr(int appId) +{ + std::string ipAddr1 = ""; + std::string ipAddr2 = ""; + std::string node1 = ""; + std::string node2 = ""; + std::vector> vector = getRunRedundancyInfoByAppid(appId); + for(size_t i=0; i vec = vector.at(i); + std::string node_name = vec.at(0).toStdString(); + int is_active = vec.at(1).toInt(); + int is_master = vec.at(2).toInt(); + int is_slave = vec.at(3).toInt(); + std::string ip1 = vec.at(4).toStdString(); + int ip1_active = vec.at(5).toInt(); + std::string ip2 = vec.at(6).toStdString(); + int ip2_active = vec.at(7).toInt(); + + if(is_active != 1) + { + continue; + } + if(is_master == 1) + { + node1 = node_name; + if(ip1_active == 1) + ipAddr1 = ip1; + else if(ip2_active == 1) + ipAddr1 = ip2; + } + else if(is_slave == 1) + { + node2 = node_name; + if(ip1_active == 1) + ipAddr2 = ip1; + else if(ip2_active == 1) + ipAddr2 = ip2; + } + } + if(ipAddr1 == "" && ipAddr2 == "") + {} + else if(ipAddr1 == "") + { + std::string temp = getAnotherIp(node2); + m_ServerAddr[0] = temp; + m_ServerAddr[1] = ipAddr2; + } + else if(ipAddr2 == "") + { + std::string temp = getAnotherIp(node1); + m_ServerAddr[0] = ipAddr1; + m_ServerAddr[1] = temp; + } + else + { + m_ServerAddr[0] = ipAddr1; + m_ServerAddr[1] = ipAddr2; + } +} + +std::string CReportWidget::getAnotherIp(const std::string &node) +{ + std::string ret = ""; + if(node == m_ServerNode[0]) + { + ret = m_ServerAddr[1]; + } + else + { + ret = m_ServerAddr[0]; + } + return ret; +} + +std::vector> CReportWidget::getRunRedundancyInfoByAppid(int appId) +{ + std::vector> vector; + if(m_rtdbAccess->open("base", "sys_run_redundancy_info")) + { + kbd_dbms::CONDINFO condition; + memcpy(condition.name, "app_id", strlen("app_id")); + condition.logicalop = ATTRCOND_AND; + condition.relationop = ATTRCOND_EQU; + condition.conditionval = appId; + + std::vector vecCondInfo; + vecCondInfo.push_back(condition); + + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("node_name"); + columns.push_back("is_active"); + columns.push_back("is_master"); + columns.push_back("is_slave"); + columns.push_back("ip1"); + columns.push_back("ip1_active"); + columns.push_back("ip2"); + columns.push_back("ip2_active"); + + if(m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + std::vector temp; + kbd_dbms::CVarType node_name; + kbd_dbms::CVarType is_active; + kbd_dbms::CVarType is_master; + kbd_dbms::CVarType is_slave; + kbd_dbms::CVarType ip1; + kbd_dbms::CVarType ip1_active; + kbd_dbms::CVarType ip2; + kbd_dbms::CVarType ip2_active; + result.getColumnValue(nIndex, 0, node_name); + result.getColumnValue(nIndex, 1, is_active); + result.getColumnValue(nIndex, 2, is_master); + result.getColumnValue(nIndex, 3, is_slave); + result.getColumnValue(nIndex, 4, ip1); + result.getColumnValue(nIndex, 5, ip1_active); + result.getColumnValue(nIndex, 6, ip2); + result.getColumnValue(nIndex, 7, ip2_active); + temp.push_back(node_name); + temp.push_back(is_active); + temp.push_back(is_master); + temp.push_back(is_slave); + temp.push_back(ip1); + temp.push_back(ip1_active); + temp.push_back(ip2); + temp.push_back(ip2_active); + vector.push_back(temp); + } + } + m_rtdbAccess->close(); + } + return vector; +} + +void CReportWidget::updateUserInfo() +{ + m_permMngPtr = kbd_service::getPermMngInstance("base"); + m_permMngPtr->PermDllInit(); + if (m_permMngPtr != NULL) + { + int UserId,UsergId,Level,LoginSec; + std::string UserName; + m_permMngPtr->CurUser(UserId,UsergId,Level,LoginSec,UserName); //获取当前登陆用户的所属用户组ID + if (UsergId != m_UsergId) + { + m_UsergId = UsergId; + } + loadPage(); + } +} + +void CReportWidget::loadPage() +{ + m_isHTML = true; + std::string style = std::move(kbd_public::CFileStyle::getCurStyle()); + if(m_browserMode == ViewMode) + { + QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum])+m_strView; + QUrl url(urlstr); + QUrlQuery query; + query.addQueryItem("userGroup", QString::number(m_UsergId)); + query.addQueryItem("theme", QString::fromStdString(style)); + url.setQuery(query); + stackedWidget->view->load(url); + } + else if (m_browserMode == EditMode) + { + if(!checkReportEditPerm()) + { + std::string path = kbd_public::CFileUtil::getCurModuleDir(); + stackedWidget->view->load(QUrl::fromLocalFile(QString::fromStdString(path)+"../../data/report/PERM_FORBIT_EDIT.html")); + return; + } + QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum])+m_strDesign; + QUrl url(urlstr); + QUrlQuery query; + query.addQueryItem("theme", QString::fromStdString(style)); + url.setQuery(query); + stackedWidget->view->load(url); + } +} + +void CReportWidget::slotUpdateTime() +{ + m_updateTimer->stop(); + if (m_changeAddr) + { + m_addrNum = 1 - m_addrNum; + } + loadPage(); +} + +void CReportWidget::slotLoadFinish(bool ok) +{ + if(m_isHTML) + { + if (!ok) + { + std::string path = kbd_public::CFileUtil::getCurModuleDir(); + stackedWidget->view->load(QUrl::fromLocalFile(QString::fromStdString(path)+"../../data/report/FAIL_PAGE.html")); + if(m_changeAddr && !m_addrNum) + m_updateTimer->start(); + } + } + m_isHTML = false; +} + +void CReportWidget::handleDownloadRequest(QWebEngineDownloadItem *download) +{ + QString path = QFileDialog::getSaveFileName(this, tr("导出报表"), download->path()); + if (!path.isEmpty()) + { + download->setPath(path); + download->accept(); + } +} + +void CReportWidget::switchMode(int mode) +{ + m_browserMode = (browserMode)mode; + updateUserInfo(); +} + +void CReportWidget::UserChanged() +{ + updateUserInfo(); +} + +bool CReportWidget::checkReportEditPerm() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::string func = "FUNC_NOM_RPT_EDIT"; + if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &func)) + { + return true; + } + } + return false; +} diff --git a/product/src/gui/plugin/ReportWidget/CReportWidget.h b/product/src/gui/plugin/ReportWidget/CReportWidget.h index 9a49dc70..3daffbb8 100644 --- a/product/src/gui/plugin/ReportWidget/CReportWidget.h +++ b/product/src/gui/plugin/ReportWidget/CReportWidget.h @@ -1,79 +1,79 @@ -#ifndef CREPORTWIDGET_H -#define CREPORTWIDGET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" - -using namespace kbd_service; -using namespace kbd_public; -class CReportWebView; -class CReportStackedWidget; - -class CReportWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CReportWidget(QWidget *parent, bool editMode); - ~CReportWidget(); - enum browserMode - { - ViewMode, - EditMode - }; - -public slots: - void UserChanged(); - void switchMode(int mode); - -private: - void init(); - void initUrl(); - void initSysInfo(); - void setNicAddr(int appId); - std::string getAnotherIp(const std::string &node); - std::vector > getRunRedundancyInfoByAppid(int appId); - void updateUserInfo(); - void loadPage(); - void slotLoadFinish(bool ok); - void slotUpdateTime(); - void handleDownloadRequest(QWebEngineDownloadItem *download); - bool checkReportEditPerm(); - -private: - CReportStackedWidget *stackedWidget; - kbd_dbms::CRdbAccess * m_rtdbAccess; - CPermMngApiPtr m_permMngPtr; - CSysInfoInterfacePtr m_sysInfoPtr; - QTimer * m_updateTimer; - std::string m_ServerNode[2]; - std::string m_ServerAddr[2]; - browserMode m_browserMode; - bool m_isHTML; - bool m_changeAddr; - int m_UsergId; - int m_addrNum; - QString m_strView; - QString m_strDesign; -}; - - - - -#endif // CREPORTWIDGET_H +#ifndef CREPORTWIDGET_H +#define CREPORTWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" + +using namespace kbd_service; +using namespace kbd_public; +class CReportWebView; +class CReportStackedWidget; + +class CReportWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CReportWidget(QWidget *parent, bool editMode); + ~CReportWidget(); + enum browserMode + { + ViewMode, + EditMode + }; + +public slots: + void UserChanged(); + void switchMode(int mode); + +private: + void init(); + void initUrl(); + void initSysInfo(); + void setNicAddr(int appId); + std::string getAnotherIp(const std::string &node); + std::vector > getRunRedundancyInfoByAppid(int appId); + void updateUserInfo(); + void loadPage(); + void slotLoadFinish(bool ok); + void slotUpdateTime(); + void handleDownloadRequest(QWebEngineDownloadItem *download); + bool checkReportEditPerm(); + +private: + CReportStackedWidget *stackedWidget; + kbd_dbms::CRdbAccess * m_rtdbAccess; + CPermMngApiPtr m_permMngPtr; + CSysInfoInterfacePtr m_sysInfoPtr; + QTimer * m_updateTimer; + std::string m_ServerNode[2]; + std::string m_ServerAddr[2]; + browserMode m_browserMode; + bool m_isHTML; + bool m_changeAddr; + int m_UsergId; + int m_addrNum; + QString m_strView; + QString m_strDesign; +}; + + + + +#endif // CREPORTWIDGET_H diff --git a/product/src/gui/plugin/ReportWidget/ReportWidget.pro b/product/src/gui/plugin/ReportWidget/ReportWidget.pro index b9b5740a..b2b78b0a 100644 --- a/product/src/gui/plugin/ReportWidget/ReportWidget.pro +++ b/product/src/gui/plugin/ReportWidget/ReportWidget.pro @@ -1,58 +1,58 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-11-13T14:55:16 -# -#------------------------------------------------- - -QT += core gui webenginewidgets xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = ReportWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CReportWidget.cpp \ - CReportPluginWidget.cpp \ -# main.cpp \ - CReportWebView.cpp \ - CReportStackedWidget.cpp - -HEADERS += \ - CReportWidget.h \ - CReportPluginWidget.h \ - CReportWebView.h \ - CReportStackedWidget.h - -RESOURCES += \ - resource.qrc - -LIBS += \ - -lperm_mng_api \ - -lpub_sysinfo_api \ - -lpub_utility_api \ - -lrdb_api - -#include($$PWD/../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2018-11-13T14:55:16 +# +#------------------------------------------------- + +QT += core gui webenginewidgets xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ReportWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CReportWidget.cpp \ + CReportPluginWidget.cpp \ +# main.cpp \ + CReportWebView.cpp \ + CReportStackedWidget.cpp + +HEADERS += \ + CReportWidget.h \ + CReportPluginWidget.h \ + CReportWebView.h \ + CReportStackedWidget.h + +RESOURCES += \ + resource.qrc + +LIBS += \ + -lperm_mng_api \ + -lpub_sysinfo_api \ + -lpub_utility_api \ + -lrdb_api + +#include($$PWD/../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/ReportWidget/resource.qrc b/product/src/gui/plugin/ReportWidget/resource.qrc index 81d727c0..361a3f26 100644 --- a/product/src/gui/plugin/ReportWidget/resource.qrc +++ b/product/src/gui/plugin/ReportWidget/resource.qrc @@ -1,5 +1,5 @@ - - - report.png - - + + + report.png + + diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.cpp index 55e84ea2..5092d0d6 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.cpp @@ -1,333 +1,333 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CRobotAVWidget.h" -#include "ui_CRobotAVWidget.h" -#include "Slider.h" -#include "Renderer.h" -#include "VoiceSlider.h" -#include "CRobotCommon.h" -using namespace QtAV; -CRobotAVWidget::CRobotAVWidget(QWidget *parent) : - QWidget(parent), - m_path(QString()), - m_preview(NULL), - m_voice(30), - ui(new Ui::CRobotAVWidget) -{ - ui->setupUi(this); - m_player = new AVPlayer(this); - m_player->setSpeed(1); - QVBoxLayout *vl = new QVBoxLayout(); - setLayout(vl); - m_renderer = new Renderer(this); - m_renderer->show(); - m_renderer->setContentsMargins(0,0,0,0); - Widgets::registerRenderers(); - m_player->setRenderer(m_renderer); - vl->setContentsMargins(0,0,0,0); - - QHBoxLayout *controlLayout = new QHBoxLayout(); - controlLayout->setContentsMargins(10,10,10,10); - m_control = new QWidget(this); - m_control->setMaximumHeight(40); - m_timerSlider = new Slider(m_control); - m_timerSlider->setDisabled(true); - m_timerSlider->setTracking(true); - m_timerSlider->setOrientation(Qt::Horizontal); - m_timerSlider->setMinimum(0); - m_current = new QLabel(m_control); - m_current->setToolTip(tr("current time")); - m_current->setContentsMargins(QMargins(10, 2, 10, 2)); - m_current->setText(QString::fromLatin1("00:00:00")); - m_end = new QLabel(m_control); - m_end->setToolTip(tr("duration")); - m_end->setContentsMargins(QMargins(10, 2, 10, 2)); - m_end->setText(QString::fromLatin1("00:00:00")); - m_play = new QPushButton(m_control); - m_play->setObjectName("play"); - m_pause = new QPushButton(m_control); - m_pause->setObjectName("pause"); - m_play->setFixedSize(20,20); - m_pause->setFixedSize(20,20); - m_play->setHidden(false); - m_pause->setHidden(true); - m_cap = new QToolButton(m_control); - m_cap->setObjectName("m_cap"); - m_cap->setFixedSize(26,26); - m_voiceOpen = new QPushButton(m_control); - m_voiceOpen->setObjectName("m_voiceOpen"); - m_voiceOpen->setFixedSize(26,26); - - m_voiceClose = new QPushButton(m_control); - m_voiceClose->setObjectName("m_voiceClose"); - m_voiceClose->setFixedSize(26,26); - - m_control->setLayout(controlLayout); - controlLayout->addWidget(m_play); - controlLayout->addWidget(m_pause); - controlLayout->addWidget(m_current); - controlLayout->addWidget(m_timerSlider); - controlLayout->addWidget(m_end); - controlLayout->addWidget(m_cap); - controlLayout->addWidget(m_voiceOpen); - controlLayout->addWidget(m_voiceClose); - m_voiceOpen->setHidden(false); - m_voiceClose->setHidden(true); - m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); - - vl->addWidget(m_renderer); - vl->addWidget(m_control); - setCaptureConfig(); - connect(m_timerSlider, SIGNAL(sliderMoved(int)), SLOT(seek(int))); - connect(m_timerSlider, SIGNAL(sliderPressed()), SLOT(seek())); - connect(m_timerSlider, SIGNAL(onLeave()), SLOT(onTimeSliderLeave())); - connect(m_timerSlider, SIGNAL(onHover(int,int)), SLOT(onTimeSliderHover(int,int))); - connect(m_player,&AVPlayer::started,this,&CRobotAVWidget::startPlay); - connect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(onPositionChange(qint64))); - connect(m_renderer,&Renderer::click,this,&CRobotAVWidget::playPause); - connect(m_renderer,&Renderer::avPlay,this,&CRobotAVWidget::play); - connect(m_renderer,&Renderer::ccdPlay,this,&CRobotAVWidget::slotCCDPlay); - connect(m_play,&QPushButton::clicked,this,&CRobotAVWidget::playPause); - connect(m_pause,&QPushButton::clicked,this,&CRobotAVWidget::playPause); - connect(m_cap,&QToolButton::clicked,m_player->videoCapture(),&VideoCapture::capture); - connect(m_voiceOpen,&QPushButton::clicked,this,&CRobotAVWidget::voiceSliderShow); - connect(m_voiceClose,&QPushButton::clicked,this,&CRobotAVWidget::voiceSliderShow); - connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&CRobotAVWidget::slotVoiceClose); - connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&CRobotAVWidget::slotVoiceOpen); -} - -CRobotAVWidget::~CRobotAVWidget() -{ - delete ui; -} - -void CRobotAVWidget::setPath(const QString &path) -{ - m_path = path; - QStringList list = m_path.split("/"); - if(list.size() <= 0) - { - m_name = ""; - return ; - } - QString name = list.at(list.size()-1); - m_name = name.split(".").at(0); -} - -void CRobotAVWidget::play(QString path) -{ - if(m_path.compare(path) == 0) - { - if (!m_player->isPlaying()) { - m_player->play(); - setVoiceNum(); - setShowButton(true); - return; - } - if(m_player->isPaused()) - { - m_player->pause(!m_player->isPaused()); - setShowButton(true); - } - }else - { - setPath(path); - m_player->play(m_path); - setVoiceNum(); - setShowButton(true); - } -} - -void CRobotAVWidget::stop() -{ - if(m_player->isPlaying()) - { - setPath(""); - m_player->stop(); - } -} - -bool CRobotAVWidget::isPlaying() -{ - return m_player->isPlaying(); -} - -void CRobotAVWidget::playPause() -{ - if(m_path.isEmpty()) - { - return ; - } - if (!m_player->isPlaying()) { - m_player->play(); - setShowButton(true); - setVoiceNum(); - return; - } - if(m_player->isPaused()) - { - m_player->pause(false); - setShowButton(true); - }else - { - m_player->pause(true); - setShowButton(false); - } -} - -void CRobotAVWidget::slotCCDPlay(QString path) -{ - emit sigCCDPlay(path); -} - -void CRobotAVWidget::seek() -{ - seek(m_timerSlider->value()); -} - -void CRobotAVWidget::seek(int value) -{ - m_player->setSeekType(AccurateSeek); - m_player->seek((qint64)value); - if (!m_preview) - return; - m_preview->setTimestamp(value); - m_preview->preview(); - m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); - m_preview->resize(160, 90); - m_preview->show(); -} - -void CRobotAVWidget::onTimeSliderHover(int pos, int value) -{ - Q_UNUSED(pos); - const QPoint gpos =QCursor::pos(); - QToolTip::showText(gpos, QTime(0, 0, 0).addMSecs(value).toString(QString::fromLatin1("HH:mm:ss"))); - if (!m_preview) - m_preview = new VideoPreviewWidget(); - m_preview->setFile(m_player->file()); - m_preview->setTimestamp(value); - m_preview->preview(); - const int w = 160; - const int h = 90; - m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); - m_preview->resize(w, h); - m_preview->move(gpos - QPoint(w/2, h)); - m_preview->show(); -} - -void CRobotAVWidget::onTimeSliderLeave() -{ - if (m_preview && m_preview->isVisible()) - m_preview->hide(); -} - -void CRobotAVWidget::voiceSliderShow() -{ - if(m_voiceSlider->getStatus() == false) - { - QPoint gpos =mapToGlobal(m_voiceOpen->pos()); - int x= m_control->pos().y()-52; - m_voiceSlider->move(gpos-QPoint(159,0)+QPoint(0,x)); - m_voiceSlider->show(); - m_voiceSlider->setStatus(true); - }else - { - m_voiceSlider->hide(); - m_voiceSlider->setStatus(false); - } -} - -void CRobotAVWidget::slotVoiceClose(int voice) -{ - //声音范围为0-4 - setShowVoice(false); - m_voice = voice; - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void CRobotAVWidget::slotVoiceOpen(int voice) -{ - //声音范围为0-4 - setShowVoice(true); - m_voice = voice; - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void CRobotAVWidget::startPlay() -{ - m_timerSlider->setMinimum(m_player->mediaStartPosition()); - m_timerSlider->setMaximum(m_player->mediaStopPosition()); - m_timerSlider->setValue(0); - m_timerSlider->setEnabled(m_player->isSeekable()); - m_end->setText(QTime(0, 0, 0).addMSecs(m_player->mediaStopPosition()).toString(QString::fromLatin1("HH:mm:ss"))); -} - -void CRobotAVWidget::onPositionChange(qint64 pos) -{ - if (m_player->isSeekable()) - m_timerSlider->setValue(pos); - m_current->setText(QTime(0, 0, 0).addMSecs(pos).toString(QString::fromLatin1("HH:mm:ss"))); -} - -void CRobotAVWidget::setShowButton(bool bo) -{ - if(bo) - { - m_play->setHidden(true); - m_pause->setHidden(false); - }else - { - m_pause->setHidden(true); - m_play->setHidden(false); - } -} - -void CRobotAVWidget::setCaptureConfig() -{ - m_player->videoCapture()->setCaptureDir("../../data/robot/cam"); - m_player->videoCapture()->setQuality(100); - - m_player->videoCapture()->setSaveFormat("jpg"); -} - -void CRobotAVWidget::setShowVoice(bool bo) -{ - if(!bo) - { - m_voiceOpen->setHidden(true); - m_voiceClose->setHidden(false); - }else - { - m_voiceOpen->setHidden(false); - m_voiceClose->setHidden(true); - } -} - -void CRobotAVWidget::setVoiceNum() -{ - //声音范围为0-4 - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(m_voice*0.04); - if (ao) - { - ao->setVolume(v); - } -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CRobotAVWidget.h" +#include "ui_CRobotAVWidget.h" +#include "Slider.h" +#include "Renderer.h" +#include "VoiceSlider.h" +#include "CRobotCommon.h" +using namespace QtAV; +CRobotAVWidget::CRobotAVWidget(QWidget *parent) : + QWidget(parent), + m_path(QString()), + m_preview(NULL), + m_voice(30), + ui(new Ui::CRobotAVWidget) +{ + ui->setupUi(this); + m_player = new AVPlayer(this); + m_player->setSpeed(1); + QVBoxLayout *vl = new QVBoxLayout(); + setLayout(vl); + m_renderer = new Renderer(this); + m_renderer->show(); + m_renderer->setContentsMargins(0,0,0,0); + Widgets::registerRenderers(); + m_player->setRenderer(m_renderer); + vl->setContentsMargins(0,0,0,0); + + QHBoxLayout *controlLayout = new QHBoxLayout(); + controlLayout->setContentsMargins(10,10,10,10); + m_control = new QWidget(this); + m_control->setMaximumHeight(40); + m_timerSlider = new Slider(m_control); + m_timerSlider->setDisabled(true); + m_timerSlider->setTracking(true); + m_timerSlider->setOrientation(Qt::Horizontal); + m_timerSlider->setMinimum(0); + m_current = new QLabel(m_control); + m_current->setToolTip(tr("current time")); + m_current->setContentsMargins(QMargins(10, 2, 10, 2)); + m_current->setText(QString::fromLatin1("00:00:00")); + m_end = new QLabel(m_control); + m_end->setToolTip(tr("duration")); + m_end->setContentsMargins(QMargins(10, 2, 10, 2)); + m_end->setText(QString::fromLatin1("00:00:00")); + m_play = new QPushButton(m_control); + m_play->setObjectName("play"); + m_pause = new QPushButton(m_control); + m_pause->setObjectName("pause"); + m_play->setFixedSize(20,20); + m_pause->setFixedSize(20,20); + m_play->setHidden(false); + m_pause->setHidden(true); + m_cap = new QToolButton(m_control); + m_cap->setObjectName("m_cap"); + m_cap->setFixedSize(26,26); + m_voiceOpen = new QPushButton(m_control); + m_voiceOpen->setObjectName("m_voiceOpen"); + m_voiceOpen->setFixedSize(26,26); + + m_voiceClose = new QPushButton(m_control); + m_voiceClose->setObjectName("m_voiceClose"); + m_voiceClose->setFixedSize(26,26); + + m_control->setLayout(controlLayout); + controlLayout->addWidget(m_play); + controlLayout->addWidget(m_pause); + controlLayout->addWidget(m_current); + controlLayout->addWidget(m_timerSlider); + controlLayout->addWidget(m_end); + controlLayout->addWidget(m_cap); + controlLayout->addWidget(m_voiceOpen); + controlLayout->addWidget(m_voiceClose); + m_voiceOpen->setHidden(false); + m_voiceClose->setHidden(true); + m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); + + vl->addWidget(m_renderer); + vl->addWidget(m_control); + setCaptureConfig(); + connect(m_timerSlider, SIGNAL(sliderMoved(int)), SLOT(seek(int))); + connect(m_timerSlider, SIGNAL(sliderPressed()), SLOT(seek())); + connect(m_timerSlider, SIGNAL(onLeave()), SLOT(onTimeSliderLeave())); + connect(m_timerSlider, SIGNAL(onHover(int,int)), SLOT(onTimeSliderHover(int,int))); + connect(m_player,&AVPlayer::started,this,&CRobotAVWidget::startPlay); + connect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(onPositionChange(qint64))); + connect(m_renderer,&Renderer::click,this,&CRobotAVWidget::playPause); + connect(m_renderer,&Renderer::avPlay,this,&CRobotAVWidget::play); + connect(m_renderer,&Renderer::ccdPlay,this,&CRobotAVWidget::slotCCDPlay); + connect(m_play,&QPushButton::clicked,this,&CRobotAVWidget::playPause); + connect(m_pause,&QPushButton::clicked,this,&CRobotAVWidget::playPause); + connect(m_cap,&QToolButton::clicked,m_player->videoCapture(),&VideoCapture::capture); + connect(m_voiceOpen,&QPushButton::clicked,this,&CRobotAVWidget::voiceSliderShow); + connect(m_voiceClose,&QPushButton::clicked,this,&CRobotAVWidget::voiceSliderShow); + connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&CRobotAVWidget::slotVoiceClose); + connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&CRobotAVWidget::slotVoiceOpen); +} + +CRobotAVWidget::~CRobotAVWidget() +{ + delete ui; +} + +void CRobotAVWidget::setPath(const QString &path) +{ + m_path = path; + QStringList list = m_path.split("/"); + if(list.size() <= 0) + { + m_name = ""; + return ; + } + QString name = list.at(list.size()-1); + m_name = name.split(".").at(0); +} + +void CRobotAVWidget::play(QString path) +{ + if(m_path.compare(path) == 0) + { + if (!m_player->isPlaying()) { + m_player->play(); + setVoiceNum(); + setShowButton(true); + return; + } + if(m_player->isPaused()) + { + m_player->pause(!m_player->isPaused()); + setShowButton(true); + } + }else + { + setPath(path); + m_player->play(m_path); + setVoiceNum(); + setShowButton(true); + } +} + +void CRobotAVWidget::stop() +{ + if(m_player->isPlaying()) + { + setPath(""); + m_player->stop(); + } +} + +bool CRobotAVWidget::isPlaying() +{ + return m_player->isPlaying(); +} + +void CRobotAVWidget::playPause() +{ + if(m_path.isEmpty()) + { + return ; + } + if (!m_player->isPlaying()) { + m_player->play(); + setShowButton(true); + setVoiceNum(); + return; + } + if(m_player->isPaused()) + { + m_player->pause(false); + setShowButton(true); + }else + { + m_player->pause(true); + setShowButton(false); + } +} + +void CRobotAVWidget::slotCCDPlay(QString path) +{ + emit sigCCDPlay(path); +} + +void CRobotAVWidget::seek() +{ + seek(m_timerSlider->value()); +} + +void CRobotAVWidget::seek(int value) +{ + m_player->setSeekType(AccurateSeek); + m_player->seek((qint64)value); + if (!m_preview) + return; + m_preview->setTimestamp(value); + m_preview->preview(); + m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); + m_preview->resize(160, 90); + m_preview->show(); +} + +void CRobotAVWidget::onTimeSliderHover(int pos, int value) +{ + Q_UNUSED(pos); + const QPoint gpos =QCursor::pos(); + QToolTip::showText(gpos, QTime(0, 0, 0).addMSecs(value).toString(QString::fromLatin1("HH:mm:ss"))); + if (!m_preview) + m_preview = new VideoPreviewWidget(); + m_preview->setFile(m_player->file()); + m_preview->setTimestamp(value); + m_preview->preview(); + const int w = 160; + const int h = 90; + m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); + m_preview->resize(w, h); + m_preview->move(gpos - QPoint(w/2, h)); + m_preview->show(); +} + +void CRobotAVWidget::onTimeSliderLeave() +{ + if (m_preview && m_preview->isVisible()) + m_preview->hide(); +} + +void CRobotAVWidget::voiceSliderShow() +{ + if(m_voiceSlider->getStatus() == false) + { + QPoint gpos =mapToGlobal(m_voiceOpen->pos()); + int x= m_control->pos().y()-52; + m_voiceSlider->move(gpos-QPoint(159,0)+QPoint(0,x)); + m_voiceSlider->show(); + m_voiceSlider->setStatus(true); + }else + { + m_voiceSlider->hide(); + m_voiceSlider->setStatus(false); + } +} + +void CRobotAVWidget::slotVoiceClose(int voice) +{ + //声音范围为0-4 + setShowVoice(false); + m_voice = voice; + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void CRobotAVWidget::slotVoiceOpen(int voice) +{ + //声音范围为0-4 + setShowVoice(true); + m_voice = voice; + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void CRobotAVWidget::startPlay() +{ + m_timerSlider->setMinimum(m_player->mediaStartPosition()); + m_timerSlider->setMaximum(m_player->mediaStopPosition()); + m_timerSlider->setValue(0); + m_timerSlider->setEnabled(m_player->isSeekable()); + m_end->setText(QTime(0, 0, 0).addMSecs(m_player->mediaStopPosition()).toString(QString::fromLatin1("HH:mm:ss"))); +} + +void CRobotAVWidget::onPositionChange(qint64 pos) +{ + if (m_player->isSeekable()) + m_timerSlider->setValue(pos); + m_current->setText(QTime(0, 0, 0).addMSecs(pos).toString(QString::fromLatin1("HH:mm:ss"))); +} + +void CRobotAVWidget::setShowButton(bool bo) +{ + if(bo) + { + m_play->setHidden(true); + m_pause->setHidden(false); + }else + { + m_pause->setHidden(true); + m_play->setHidden(false); + } +} + +void CRobotAVWidget::setCaptureConfig() +{ + m_player->videoCapture()->setCaptureDir("../../data/robot/cam"); + m_player->videoCapture()->setQuality(100); + + m_player->videoCapture()->setSaveFormat("jpg"); +} + +void CRobotAVWidget::setShowVoice(bool bo) +{ + if(!bo) + { + m_voiceOpen->setHidden(true); + m_voiceClose->setHidden(false); + }else + { + m_voiceOpen->setHidden(false); + m_voiceClose->setHidden(true); + } +} + +void CRobotAVWidget::setVoiceNum() +{ + //声音范围为0-4 + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(m_voice*0.04); + if (ao) + { + ao->setVolume(v); + } +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.h index 3841c311..cfdf6bd4 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.h @@ -1,89 +1,89 @@ -#ifndef CROBOTAVWIDGET_H -#define CROBOTAVWIDGET_H - -#include -#include -#include -class Slider; -class QPushButton; -class QWidget; -class QLabel; -class QToolButton; -class Renderer; -class VoiceSlider; -namespace Ui { -class CRobotAVWidget; -} - -class CRobotAVWidget : public QWidget -{ - Q_OBJECT - -public: - CRobotAVWidget(QWidget *parent = 0); - ~CRobotAVWidget(); - - bool isPlaying(); - - void setPath(const QString &path); - - void stop(); - - void pause(); -signals: - void sigCCDPlay(QString path); -public slots: - void play(QString path); - void playPause(); - void slotCCDPlay(QString path); - - void seek(); - void seek(int value); - - void onTimeSliderHover(int pos, int value); - void onTimeSliderLeave(); - - void voiceSliderShow(); - - void slotVoiceClose(int voice); - - void slotVoiceOpen(int voice); -private slots: - void startPlay(); - void onPositionChange(qint64 pos); -private: - /** - * @brief setShowButton 设置播放暂停按钮 - * @param bo true-播放状态 false-暂停状态 - */ - void setShowButton(bool bo); - - void setCaptureConfig(); - - void setShowVoice(bool bo); - - void setVoiceNum(); - -private: - Ui::CRobotAVWidget *ui; - Renderer* m_renderer; - QtAV::AVPlayer *m_player; - Slider *m_timerSlider; - QWidget *m_control; - - QString m_path; - QString m_name; - QLabel *m_current, *m_end; - QToolButton *m_cap; //抓图 - - QPushButton *m_play; - QPushButton *m_pause; - QPushButton *m_voiceOpen; - QPushButton *m_voiceClose; - VoiceSlider *m_voiceSlider; - //QPushButton *m_voice_0; - QtAV::VideoPreviewWidget *m_preview; - int m_voice; -}; - -#endif // CROBOTAVWIDGET_H +#ifndef CROBOTAVWIDGET_H +#define CROBOTAVWIDGET_H + +#include +#include +#include +class Slider; +class QPushButton; +class QWidget; +class QLabel; +class QToolButton; +class Renderer; +class VoiceSlider; +namespace Ui { +class CRobotAVWidget; +} + +class CRobotAVWidget : public QWidget +{ + Q_OBJECT + +public: + CRobotAVWidget(QWidget *parent = 0); + ~CRobotAVWidget(); + + bool isPlaying(); + + void setPath(const QString &path); + + void stop(); + + void pause(); +signals: + void sigCCDPlay(QString path); +public slots: + void play(QString path); + void playPause(); + void slotCCDPlay(QString path); + + void seek(); + void seek(int value); + + void onTimeSliderHover(int pos, int value); + void onTimeSliderLeave(); + + void voiceSliderShow(); + + void slotVoiceClose(int voice); + + void slotVoiceOpen(int voice); +private slots: + void startPlay(); + void onPositionChange(qint64 pos); +private: + /** + * @brief setShowButton 设置播放暂停按钮 + * @param bo true-播放状态 false-暂停状态 + */ + void setShowButton(bool bo); + + void setCaptureConfig(); + + void setShowVoice(bool bo); + + void setVoiceNum(); + +private: + Ui::CRobotAVWidget *ui; + Renderer* m_renderer; + QtAV::AVPlayer *m_player; + Slider *m_timerSlider; + QWidget *m_control; + + QString m_path; + QString m_name; + QLabel *m_current, *m_end; + QToolButton *m_cap; //抓图 + + QPushButton *m_play; + QPushButton *m_pause; + QPushButton *m_voiceOpen; + QPushButton *m_voiceClose; + VoiceSlider *m_voiceSlider; + //QPushButton *m_voice_0; + QtAV::VideoPreviewWidget *m_preview; + int m_voice; +}; + +#endif // CROBOTAVWIDGET_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.ui b/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.ui index c81a1230..282d24d8 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.ui +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotAVWidget.ui @@ -1,25 +1,25 @@ - - - CRobotAVWidget - - - - 0 - 0 - 533 - 672 - - - - - 0 - 0 - - - - Form - - - - - + + + CRobotAVWidget + + + + 0 + 0 + 533 + 672 + + + + + 0 + 0 + + + + Form + + + + + diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.cpp index d47fa6a2..db8a5be3 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.cpp @@ -1,78 +1,78 @@ -#include "CRobotCCDVideoForm.h" -#include "ui_CRobotCCDVideoForm.h" -#include -#include "CRobotCCDVideoItemModel.h" -#include -#include -#include -#include -CRobotCCDVideoForm::CRobotCCDVideoForm(QWidget *parent) : - QWidget(parent), - m_model(NULL), - ui(new Ui::CRobotCCDVideoForm) -{ - ui->setupUi(this); - m_searchButton = new QPushButton(this); - m_searchButton->setObjectName("searchButton"); - m_searchButton->setText(""); - m_searchButton->setMaximumSize(20, 20); - m_searchButton->setCursor(QCursor(Qt::ArrowCursor)); - m_searchButton->setShortcut(QKeySequence(QLatin1String("Return"))); - QHBoxLayout * pTimeLayout = new QHBoxLayout(); - pTimeLayout->setContentsMargins(1, 1, 1, 1); - pTimeLayout->addStretch(); - pTimeLayout->addWidget(m_searchButton,2); - ui->keyWordSearch->setLayout(pTimeLayout); - connect(m_searchButton,&QPushButton::clicked,this,&CRobotCCDVideoForm::slotFilte,Qt::QueuedConnection); - ui->keyWordSearch->setPlaceholderText(tr("请输入关键字")); -} - -CRobotCCDVideoForm::~CRobotCCDVideoForm() -{ - delete ui; -} - -void CRobotCCDVideoForm::setItemModel(CRobotCCDVideoItemModel *model) -{ - m_model = model; - ui->ccdVideoView->initialize(); - ui->ccdVideoView->setModel(m_model); - connect(ui->ccdVideoView->horizontalHeader(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),m_model,SLOT(sortColumn(int,Qt::SortOrder))); - connect(ui->ccdVideoView,&CRobotCCDVideoView::clicked,this,&CRobotCCDVideoForm::clicked); - connect(this,&CRobotCCDVideoForm::sigFilte,m_model,&CRobotCCDVideoItemModel::slotFilte,Qt::QueuedConnection); - ui->ccdVideoView->setColumnWidth(0, 77); - ui->ccdVideoView->setColumnWidth(1, 100); - ui->ccdVideoView->setColumnWidth(2, 40); -} - -void CRobotCCDVideoForm::clicked(const QModelIndex &index) -{ - if(m_model == NULL) - { - return ; - } - if(!index.isValid()) - { - return ; - } - QList listInfo = m_model->getShowList(); - if(listInfo.isEmpty()) - { - return ; - } - RobotFilePtr robotInfo = listInfo.at(index.row()); - qDebug()<<"执行路径:"<m_execPath; - if(robotInfo->m_fileType == E_ROBOT_VIDEO) - { - emit sigAvPlay(robotInfo->m_execPath); - }else if(robotInfo->m_fileType == E_ROBOT_CCD || robotInfo->m_fileType == E_ROBOT_CUT_CCD) - { - emit sigCCDPlay(robotInfo->m_execPath); - } -} - -void CRobotCCDVideoForm::slotFilte() -{ - m_searchText = ui->keyWordSearch->text(); - emit sigFilte(m_searchText); -} +#include "CRobotCCDVideoForm.h" +#include "ui_CRobotCCDVideoForm.h" +#include +#include "CRobotCCDVideoItemModel.h" +#include +#include +#include +#include +CRobotCCDVideoForm::CRobotCCDVideoForm(QWidget *parent) : + QWidget(parent), + m_model(NULL), + ui(new Ui::CRobotCCDVideoForm) +{ + ui->setupUi(this); + m_searchButton = new QPushButton(this); + m_searchButton->setObjectName("searchButton"); + m_searchButton->setText(""); + m_searchButton->setMaximumSize(20, 20); + m_searchButton->setCursor(QCursor(Qt::ArrowCursor)); + m_searchButton->setShortcut(QKeySequence(QLatin1String("Return"))); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_searchButton,2); + ui->keyWordSearch->setLayout(pTimeLayout); + connect(m_searchButton,&QPushButton::clicked,this,&CRobotCCDVideoForm::slotFilte,Qt::QueuedConnection); + ui->keyWordSearch->setPlaceholderText(tr("请输入关键字")); +} + +CRobotCCDVideoForm::~CRobotCCDVideoForm() +{ + delete ui; +} + +void CRobotCCDVideoForm::setItemModel(CRobotCCDVideoItemModel *model) +{ + m_model = model; + ui->ccdVideoView->initialize(); + ui->ccdVideoView->setModel(m_model); + connect(ui->ccdVideoView->horizontalHeader(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),m_model,SLOT(sortColumn(int,Qt::SortOrder))); + connect(ui->ccdVideoView,&CRobotCCDVideoView::clicked,this,&CRobotCCDVideoForm::clicked); + connect(this,&CRobotCCDVideoForm::sigFilte,m_model,&CRobotCCDVideoItemModel::slotFilte,Qt::QueuedConnection); + ui->ccdVideoView->setColumnWidth(0, 77); + ui->ccdVideoView->setColumnWidth(1, 100); + ui->ccdVideoView->setColumnWidth(2, 40); +} + +void CRobotCCDVideoForm::clicked(const QModelIndex &index) +{ + if(m_model == NULL) + { + return ; + } + if(!index.isValid()) + { + return ; + } + QList listInfo = m_model->getShowList(); + if(listInfo.isEmpty()) + { + return ; + } + RobotFilePtr robotInfo = listInfo.at(index.row()); + qDebug()<<"执行路径:"<m_execPath; + if(robotInfo->m_fileType == E_ROBOT_VIDEO) + { + emit sigAvPlay(robotInfo->m_execPath); + }else if(robotInfo->m_fileType == E_ROBOT_CCD || robotInfo->m_fileType == E_ROBOT_CUT_CCD) + { + emit sigCCDPlay(robotInfo->m_execPath); + } +} + +void CRobotCCDVideoForm::slotFilte() +{ + m_searchText = ui->keyWordSearch->text(); + emit sigFilte(m_searchText); +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.h index 89f3d90c..deccdb59 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.h @@ -1,35 +1,35 @@ -#ifndef CROBOTCCDVIDEOFORM_H -#define CROBOTCCDVIDEOFORM_H - -#include -#include "CRobotCommon.h" -class QPushButton; -class CRobotCCDVideoItemModel; -namespace Ui { -class CRobotCCDVideoForm; -} - -class CRobotCCDVideoForm : public QWidget -{ - Q_OBJECT - -public: - explicit CRobotCCDVideoForm(QWidget *parent = 0); - ~CRobotCCDVideoForm(); - void setItemModel(CRobotCCDVideoItemModel *model); -signals: - void sigAvPlay(QString path); - void sigCCDPlay(QString path); - - void sigFilte(QString text); -public slots: - void clicked(const QModelIndex &index); - void slotFilte(); -private: - Ui::CRobotCCDVideoForm *ui; - QPushButton * m_searchButton; - CRobotCCDVideoItemModel *m_model; - QString m_searchText; -}; - -#endif // CROBOTCCDVIDEOFORM_H +#ifndef CROBOTCCDVIDEOFORM_H +#define CROBOTCCDVIDEOFORM_H + +#include +#include "CRobotCommon.h" +class QPushButton; +class CRobotCCDVideoItemModel; +namespace Ui { +class CRobotCCDVideoForm; +} + +class CRobotCCDVideoForm : public QWidget +{ + Q_OBJECT + +public: + explicit CRobotCCDVideoForm(QWidget *parent = 0); + ~CRobotCCDVideoForm(); + void setItemModel(CRobotCCDVideoItemModel *model); +signals: + void sigAvPlay(QString path); + void sigCCDPlay(QString path); + + void sigFilte(QString text); +public slots: + void clicked(const QModelIndex &index); + void slotFilte(); +private: + Ui::CRobotCCDVideoForm *ui; + QPushButton * m_searchButton; + CRobotCCDVideoItemModel *m_model; + QString m_searchText; +}; + +#endif // CROBOTCCDVIDEOFORM_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.ui b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.ui index 59462b73..03b04fb2 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.ui +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoForm.ui @@ -1,100 +1,100 @@ - - - CRobotCCDVideoForm - - - - 0 - 0 - 256 - 668 - - - - - 0 - 0 - - - - Form - - - - - - - 0 - - - 10 - - - 0 - - - 0 - - - 0 - - - 10 - - - - - - 0 - 31 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 10 - 20 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 10 - 20 - - - - - - - - - - - - CRobotCCDVideoView - QTableView -
CRobotCCDVideoView.h
-
-
- - -
+ + + CRobotCCDVideoForm + + + + 0 + 0 + 256 + 668 + + + + + 0 + 0 + + + + Form + + + + + + + 0 + + + 10 + + + 0 + + + 0 + + + 0 + + + 10 + + + + + + 0 + 31 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 10 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 10 + 20 + + + + + + + + + + + + CRobotCCDVideoView + QTableView +
CRobotCCDVideoView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoItemModel.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoItemModel.cpp index 82808d42..2189037a 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoItemModel.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoItemModel.cpp @@ -1,351 +1,351 @@ -#include "CRobotCCDVideoItemModel.h" -#include -#include "CRobotFileInfo.h" -#include "CRobotCommon.h" -#include -using namespace std; -typedef QPair > PAIRLISTROBOTINFO; - -CRobotCCDVideoItemModel::CRobotCCDVideoItemModel(QObject *parent) - : QAbstractTableModel(parent), - m_sortKey(E_SORT_TIME), - m_order(Qt::DescendingOrder), - m_searchText(QString()) -{ - m_header < >("ListRobotFilePtr"); -} - -QVariant CRobotCCDVideoItemModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(m_header.at(section)); - } - return QVariant(); -} - -int CRobotCCDVideoItemModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - return m_listShowInfo.count(); -} - -int CRobotCCDVideoItemModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.count(); -} - -QVariant CRobotCCDVideoItemModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - if(Qt::TextAlignmentRole == role) - { - return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); - }else if(Qt::DisplayRole == role) - { - switch(index.column()) - { - case TIME: - { - return QDateTime::fromMSecsSinceEpoch(m_listShowInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd"); - } - case DEVICE: - { - return m_map[m_listShowInfo.at(index.row())->m_devgId]; - } - case TYPE: - { - if(E_ROBOT_CCD == m_listShowInfo.at(index.row())->m_fileType) - { - return tr("照片"); - }else if(E_ROBOT_CUT_CCD == m_listShowInfo.at(index.row())->m_fileType) - { - return tr("截图"); - }else if(E_ROBOT_VIDEO == m_listShowInfo.at(index.row())->m_fileType) - { - return tr("录像"); - } - } - default: - break; - } - } - return QVariant(); -} - -const QList CRobotCCDVideoItemModel::getShowList() const -{ - return m_listShowInfo; -} - -void CRobotCCDVideoItemModel::slotMsgAdd(const QList list) -{ - uint64 month = 3; - uint64 outTime = month*30*60*60*1000*24; - uint64 time = QDateTime::currentMSecsSinceEpoch(); - foreach (RobotFilePtr info,list) { - if(conditionFilter(info)) - { - if((time - outTime) < info->time_stamp) - { - insertMsg(info); - } - } - } -} - -void CRobotCCDVideoItemModel::slotMsgSub(const QList list) -{ - foreach (RobotFilePtr info,list) { - for(int nIndex = m_listShowInfo.size() - 1; nIndex >= 0; --nIndex) - { - if(m_listShowInfo.at(nIndex)->m_execPath == info->m_execPath) - { - beginRemoveRows(QModelIndex(), nIndex, nIndex); - m_listShowInfo.removeAt(nIndex); - endRemoveRows(); - break; - } - } - } -} - -void CRobotCCDVideoItemModel::sortColumn(int column, Qt::SortOrder order) -{ - if(order == Qt::AscendingOrder) - { - m_order = Qt::DescendingOrder; - } - else - { - m_order = Qt::AscendingOrder; - } - - switch ((ColumnField)column) - { - case TIME: - { - m_sortKey = E_SORT_TIME; - break; - } - case DEVICE: - { - m_sortKey = E_SORT_DEV; - break; - } - case TYPE: - { - m_sortKey = E_SORT_TYPE; - break; - } - default: - break; - } - sort(); - beginResetModel(); - endResetModel(); -} - -void CRobotCCDVideoItemModel::slotFilte(QString text) -{ - m_searchText = text; - brush(); -} - -void CRobotCCDVideoItemModel::initialize(QMap devMap) -{ - m_listHorAlignmentFlags.clear(); - for (int nIndex(0); nIndex < m_header.size(); nIndex++) - { - m_listHorAlignmentFlags.append(Qt::AlignHCenter); - } - m_listShowInfo.clear(); - m_map.clear(); - m_map = devMap; -} - -bool CRobotCCDVideoItemModel::conditionFilter(const RobotFilePtr &info) -{ - if(m_searchText.isEmpty()) - { - return true; - } - std::string text =m_searchText.toStdString(); - //判断时间 - - std::string time = QDateTime::fromMSecsSinceEpoch(info->time_stamp).toString("yyyy-MM-dd").toStdString(); - if(time.find(text,0) != -1) - { - return true; - } - //判断设备组 - std::string dev = m_map[info->m_devgId].toStdString(); - - if(dev.find(text,0) != -1) - { - return true; - } - return false; -} - -void CRobotCCDVideoItemModel::insertMsg(const RobotFilePtr &info) -{ - int mid = -1; - int left = 0; - int right = m_listShowInfo.size() - 1; - while (left <= right) { - mid = (left + right) / 2; - if(Qt::AscendingOrder == m_order) - { - if(info->lessThan(m_listShowInfo[mid]),m_sortKey) - { - right = mid -1; - }else - { - left = mid + 1; - } - }else - { - if(m_listShowInfo[mid]->lessThan(info,m_sortKey)) - { - right = mid -1; - }else - { - left = mid + 1; - } - } - } - beginInsertRows(QModelIndex(),left,left); - m_listShowInfo.insert(left,info); - endInsertRows(); -} - -//<归并排序 -void CRobotCCDVideoItemModel::sort() -{ - QMap mapRobotInfo; - for(int nIndex(0); nIndex < m_listShowInfo.count(); nIndex++) - { - RobotFilePtr temp = m_listShowInfo.at(nIndex); - mapRobotInfo[nIndex / 1000].second.append(temp); - } - //<快速排序 - for(int nMapIndex(0); nMapIndex < mapRobotInfo.count(); nMapIndex++) - { - qucikSort(mapRobotInfo[nMapIndex].second, 0, mapRobotInfo[nMapIndex].second.count() - 1); - } - PAIRLISTROBOTINFO tempListInfo = mapRobotInfo[0]; - for(int nPairIndex(1); nPairIndex < mapRobotInfo.count(); nPairIndex++) - { - //<归并 - tempListInfo.first = 0; - mapRobotInfo[nPairIndex].first = 0; - while(mapRobotInfo[nPairIndex].first < mapRobotInfo[nPairIndex].second.count()) - { - if(tempListInfo.first >= tempListInfo.second.count()) - { - tempListInfo.second.append(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); - mapRobotInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListInfo.second[tempListInfo.first]->lessThan(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first), m_sortKey)) - { - tempListInfo.second.insert(tempListInfo.first, mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); - mapRobotInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListInfo.second[tempListInfo.first]->moreThan(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first), m_sortKey)) - { - tempListInfo.second.insert(tempListInfo.first, mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); - mapRobotInfo[nPairIndex].first += 1; - } - } - } - tempListInfo.first += 1; - } - } - m_listShowInfo = tempListInfo.second; -} - -void CRobotCCDVideoItemModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CRobotCCDVideoItemModel::partitionAscendingOrder(QList &list, int start, int last) -{ - RobotFilePtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftlessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CRobotCCDVideoItemModel::partitionDescendingOrder(QList &list, int start, int last) -{ - RobotFilePtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -void CRobotCCDVideoItemModel::brush() -{ - beginResetModel(); - m_listShowInfo.clear(); - endResetModel(); - emit sigAllMsgAdd(); -} +#include "CRobotCCDVideoItemModel.h" +#include +#include "CRobotFileInfo.h" +#include "CRobotCommon.h" +#include +using namespace std; +typedef QPair > PAIRLISTROBOTINFO; + +CRobotCCDVideoItemModel::CRobotCCDVideoItemModel(QObject *parent) + : QAbstractTableModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::DescendingOrder), + m_searchText(QString()) +{ + m_header < >("ListRobotFilePtr"); +} + +QVariant CRobotCCDVideoItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +int CRobotCCDVideoItemModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + return m_listShowInfo.count(); +} + +int CRobotCCDVideoItemModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.count(); +} + +QVariant CRobotCCDVideoItemModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + if(Qt::TextAlignmentRole == role) + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + }else if(Qt::DisplayRole == role) + { + switch(index.column()) + { + case TIME: + { + return QDateTime::fromMSecsSinceEpoch(m_listShowInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd"); + } + case DEVICE: + { + return m_map[m_listShowInfo.at(index.row())->m_devgId]; + } + case TYPE: + { + if(E_ROBOT_CCD == m_listShowInfo.at(index.row())->m_fileType) + { + return tr("照片"); + }else if(E_ROBOT_CUT_CCD == m_listShowInfo.at(index.row())->m_fileType) + { + return tr("截图"); + }else if(E_ROBOT_VIDEO == m_listShowInfo.at(index.row())->m_fileType) + { + return tr("录像"); + } + } + default: + break; + } + } + return QVariant(); +} + +const QList CRobotCCDVideoItemModel::getShowList() const +{ + return m_listShowInfo; +} + +void CRobotCCDVideoItemModel::slotMsgAdd(const QList list) +{ + uint64 month = 3; + uint64 outTime = month*30*60*60*1000*24; + uint64 time = QDateTime::currentMSecsSinceEpoch(); + foreach (RobotFilePtr info,list) { + if(conditionFilter(info)) + { + if((time - outTime) < info->time_stamp) + { + insertMsg(info); + } + } + } +} + +void CRobotCCDVideoItemModel::slotMsgSub(const QList list) +{ + foreach (RobotFilePtr info,list) { + for(int nIndex = m_listShowInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowInfo.at(nIndex)->m_execPath == info->m_execPath) + { + beginRemoveRows(QModelIndex(), nIndex, nIndex); + m_listShowInfo.removeAt(nIndex); + endRemoveRows(); + break; + } + } + } +} + +void CRobotCCDVideoItemModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + + switch ((ColumnField)column) + { + case TIME: + { + m_sortKey = E_SORT_TIME; + break; + } + case DEVICE: + { + m_sortKey = E_SORT_DEV; + break; + } + case TYPE: + { + m_sortKey = E_SORT_TYPE; + break; + } + default: + break; + } + sort(); + beginResetModel(); + endResetModel(); +} + +void CRobotCCDVideoItemModel::slotFilte(QString text) +{ + m_searchText = text; + brush(); +} + +void CRobotCCDVideoItemModel::initialize(QMap devMap) +{ + m_listHorAlignmentFlags.clear(); + for (int nIndex(0); nIndex < m_header.size(); nIndex++) + { + m_listHorAlignmentFlags.append(Qt::AlignHCenter); + } + m_listShowInfo.clear(); + m_map.clear(); + m_map = devMap; +} + +bool CRobotCCDVideoItemModel::conditionFilter(const RobotFilePtr &info) +{ + if(m_searchText.isEmpty()) + { + return true; + } + std::string text =m_searchText.toStdString(); + //判断时间 + + std::string time = QDateTime::fromMSecsSinceEpoch(info->time_stamp).toString("yyyy-MM-dd").toStdString(); + if(time.find(text,0) != -1) + { + return true; + } + //判断设备组 + std::string dev = m_map[info->m_devgId].toStdString(); + + if(dev.find(text,0) != -1) + { + return true; + } + return false; +} + +void CRobotCCDVideoItemModel::insertMsg(const RobotFilePtr &info) +{ + int mid = -1; + int left = 0; + int right = m_listShowInfo.size() - 1; + while (left <= right) { + mid = (left + right) / 2; + if(Qt::AscendingOrder == m_order) + { + if(info->lessThan(m_listShowInfo[mid]),m_sortKey) + { + right = mid -1; + }else + { + left = mid + 1; + } + }else + { + if(m_listShowInfo[mid]->lessThan(info,m_sortKey)) + { + right = mid -1; + }else + { + left = mid + 1; + } + } + } + beginInsertRows(QModelIndex(),left,left); + m_listShowInfo.insert(left,info); + endInsertRows(); +} + +//<归并排序 +void CRobotCCDVideoItemModel::sort() +{ + QMap mapRobotInfo; + for(int nIndex(0); nIndex < m_listShowInfo.count(); nIndex++) + { + RobotFilePtr temp = m_listShowInfo.at(nIndex); + mapRobotInfo[nIndex / 1000].second.append(temp); + } + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapRobotInfo.count(); nMapIndex++) + { + qucikSort(mapRobotInfo[nMapIndex].second, 0, mapRobotInfo[nMapIndex].second.count() - 1); + } + PAIRLISTROBOTINFO tempListInfo = mapRobotInfo[0]; + for(int nPairIndex(1); nPairIndex < mapRobotInfo.count(); nPairIndex++) + { + //<归并 + tempListInfo.first = 0; + mapRobotInfo[nPairIndex].first = 0; + while(mapRobotInfo[nPairIndex].first < mapRobotInfo[nPairIndex].second.count()) + { + if(tempListInfo.first >= tempListInfo.second.count()) + { + tempListInfo.second.append(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); + mapRobotInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListInfo.second[tempListInfo.first]->lessThan(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first), m_sortKey)) + { + tempListInfo.second.insert(tempListInfo.first, mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); + mapRobotInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListInfo.second[tempListInfo.first]->moreThan(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first), m_sortKey)) + { + tempListInfo.second.insert(tempListInfo.first, mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); + mapRobotInfo[nPairIndex].first += 1; + } + } + } + tempListInfo.first += 1; + } + } + m_listShowInfo = tempListInfo.second; +} + +void CRobotCCDVideoItemModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CRobotCCDVideoItemModel::partitionAscendingOrder(QList &list, int start, int last) +{ + RobotFilePtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CRobotCCDVideoItemModel::partitionDescendingOrder(QList &list, int start, int last) +{ + RobotFilePtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CRobotCCDVideoItemModel::brush() +{ + beginResetModel(); + m_listShowInfo.clear(); + endResetModel(); + emit sigAllMsgAdd(); +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoItemModel.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoItemModel.h index 4f50fa95..64827df2 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoItemModel.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoItemModel.h @@ -1,60 +1,60 @@ -#ifndef CROBOTCCDVIDEOITEMMODEL_H -#define CROBOTCCDVIDEOITEMMODEL_H - -#include -#include "CRobotFileInfo.h" -class CRobotCCDVideoItemModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - enum ColumnField - { - TIME = 0, - DEVICE, - TYPE - }; - explicit CRobotCCDVideoItemModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - const QList getShowList() const; - - void initialize(QMap devMap); -signals: - void sigAllMsgAdd(); -public slots: - void slotMsgAdd(const QList list); - void slotMsgSub(const QList list); - - void sortColumn(int column, Qt::SortOrder order); - - void slotFilte(QString text); -private: - - bool conditionFilter(const RobotFilePtr &info); - void insertMsg(const RobotFilePtr &info); - void sort(); - void qucikSort(QList &list, int start, int last); - int partitionAscendingOrder(QList &list, int start, int last); - int partitionDescendingOrder(QList &list, int start, int last); - void brush(); - -private: - QStringList m_header; - QList m_listShowInfo; - QList m_listHorAlignmentFlags; //< 水平对齐方式 - E_ROBOT_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - QString m_searchText; - QMap m_map; -}; - -#endif // CROBOTCCDVIDEOITEMMODEL_H +#ifndef CROBOTCCDVIDEOITEMMODEL_H +#define CROBOTCCDVIDEOITEMMODEL_H + +#include +#include "CRobotFileInfo.h" +class CRobotCCDVideoItemModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + enum ColumnField + { + TIME = 0, + DEVICE, + TYPE + }; + explicit CRobotCCDVideoItemModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + const QList getShowList() const; + + void initialize(QMap devMap); +signals: + void sigAllMsgAdd(); +public slots: + void slotMsgAdd(const QList list); + void slotMsgSub(const QList list); + + void sortColumn(int column, Qt::SortOrder order); + + void slotFilte(QString text); +private: + + bool conditionFilter(const RobotFilePtr &info); + void insertMsg(const RobotFilePtr &info); + void sort(); + void qucikSort(QList &list, int start, int last); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + void brush(); + +private: + QStringList m_header; + QList m_listShowInfo; + QList m_listHorAlignmentFlags; //< 水平对齐方式 + E_ROBOT_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + QString m_searchText; + QMap m_map; +}; + +#endif // CROBOTCCDVIDEOITEMMODEL_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoView.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoView.cpp index e3690a74..43469bce 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoView.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoView.cpp @@ -1,26 +1,26 @@ -#include "CRobotCCDVideoView.h" -#include -#include -#include -CRobotCCDVideoView::CRobotCCDVideoView(QWidget *parent) - :QTableView(parent) -{ - -} - -void CRobotCCDVideoView::initialize() -{ - setSortingEnabled(true); - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - //setSelectionMode(QAbstractItemView::MultiSelection); - setHorizontalScrollMode(ScrollPerPixel); - this->verticalHeader()->hide(); -} - -void CRobotCCDVideoView::mousePressEvent(QMouseEvent *event) -{ - QTableView::mousePressEvent(event); -} +#include "CRobotCCDVideoView.h" +#include +#include +#include +CRobotCCDVideoView::CRobotCCDVideoView(QWidget *parent) + :QTableView(parent) +{ + +} + +void CRobotCCDVideoView::initialize() +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + //setSelectionMode(QAbstractItemView::MultiSelection); + setHorizontalScrollMode(ScrollPerPixel); + this->verticalHeader()->hide(); +} + +void CRobotCCDVideoView::mousePressEvent(QMouseEvent *event) +{ + QTableView::mousePressEvent(event); +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoView.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoView.h index 4fc2352f..31dd7e18 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoView.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCCDVideoView.h @@ -1,17 +1,17 @@ -#ifndef CROBOTCCDVIDEOVIEW_H -#define CROBOTCCDVIDEOVIEW_H -#include - -class CRobotCCDVideoView : public QTableView -{ - Q_OBJECT -public: - CRobotCCDVideoView(QWidget *parent = Q_NULLPTR); - - void initialize(); - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; -}; - -#endif // CROBOTCCDVIDEOVIEW_H +#ifndef CROBOTCCDVIDEOVIEW_H +#define CROBOTCCDVIDEOVIEW_H +#include + +class CRobotCCDVideoView : public QTableView +{ + Q_OBJECT +public: + CRobotCCDVideoView(QWidget *parent = Q_NULLPTR); + + void initialize(); + +protected: + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; +}; + +#endif // CROBOTCCDVIDEOVIEW_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCommon.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotCommon.h index 9b303961..c7a7147d 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCommon.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCommon.h @@ -1,27 +1,27 @@ -#ifndef CROBOTLINKCOMMON_H -#define CROBOTLINKCOMMON_H - -#include -#include "DataType.h" -class CRobotFileInfo; -class CRobotInfo; -typedef QSharedPointer RobotFilePtr; -typedef QSharedPointer RobotInfoPtr; -const std::string CN_RobotCtrlWidget = "CRobotLinkCtrlWidget";//当前进程名 - -#define DEV_TYPE "JQR" //设备类型表 - -enum E_ROBOT_FILE_TYPE -{ - E_ROBOT_CCD = 0, //图片 - E_ROBOT_CUT_CCD = 1, //截图 - E_ROBOT_VIDEO = 2, //视频 - -}; -enum E_ROBOT_SORTKEY -{ - E_SORT_TIME = 0, //< 文件 - E_SORT_DEV, //< 设备 - E_SORT_TYPE, //< 类型 -}; -#endif // CROBOTLINKCOMMON_H +#ifndef CROBOTLINKCOMMON_H +#define CROBOTLINKCOMMON_H + +#include +#include "DataType.h" +class CRobotFileInfo; +class CRobotInfo; +typedef QSharedPointer RobotFilePtr; +typedef QSharedPointer RobotInfoPtr; +const std::string CN_RobotCtrlWidget = "CRobotLinkCtrlWidget";//当前进程名 + +#define DEV_TYPE "JQR" //设备类型表 + +enum E_ROBOT_FILE_TYPE +{ + E_ROBOT_CCD = 0, //图片 + E_ROBOT_CUT_CCD = 1, //截图 + E_ROBOT_VIDEO = 2, //视频 + +}; +enum E_ROBOT_SORTKEY +{ + E_SORT_TIME = 0, //< 文件 + E_SORT_DEV, //< 设备 + E_SORT_TYPE, //< 类型 +}; +#endif // CROBOTLINKCOMMON_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.cpp index acb1ffa2..54772c2e 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.cpp @@ -1,610 +1,610 @@ -#include "CRobotCtrlWidget.h" -#include "SWitchButton.h" -#include "ui_CRobotCtrlWidget.h" -#include -#include -#include "dbms/db_sysinfo_api/CDbSysInfo.h" -#include -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/TimeUtil.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" -#include -#include "operate_server_api/JsonOptCommand.h" - -using namespace kbd_net; -using namespace kbd_idlfile; -using namespace kbd_public; -using namespace std; -CRobotCtrlWidget::CRobotCtrlWidget(QWidget *parent) : - QWidget(parent), - m_needRecv(false), - m_timeOutTimes(0), - m_timer(Q_NULLPTR), - m_statusTimer(Q_NULLPTR), - m_queryThread(Q_NULLPTR), - m_pReadDb(Q_NULLPTR), - m_query(Q_NULLPTR), - ui(new Ui::CRobotCtrlWidget) -{ - ui->setupUi(this); - ui->comboBox->setView(new QListView()); - m_robotid = -1; - m_queryThread = new QThread(this); - m_query = new OnTimeQueryThread(); - m_query->moveToThread(m_queryThread); - connect(m_queryThread,&QThread::started,this,&CRobotCtrlWidget::initOnTime,Qt::QueuedConnection); - connect(m_queryThread,&QThread::finished,m_queryThread,&QThread::deleteLater,Qt::QueuedConnection); - - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - if(!m_pReadDb->open()) - { - LOGERROR("数据库打开失败!"); - } - getSystemInfo(); - m_timer =new QTimer(this); - m_timer->setInterval(1000); - connect(m_timer,&QTimer::timeout,this,&CRobotCtrlWidget::execute,Qt::QueuedConnection); - m_statusTimer = new QTimer(this); - m_statusTimer->setInterval(1000); - connect(m_statusTimer,&QTimer::timeout,this,&CRobotCtrlWidget::onTimeSetRobotStatus,Qt::QueuedConnection); - ui->label_head->setText(tr("机器人状态")); - initGif(); -} - -CRobotCtrlWidget::~CRobotCtrlWidget() -{ - if(m_timer) - { - m_timer->stop(); - m_timer->deleteLater(); - } - if(m_statusTimer) - { - m_statusTimer->stop(); - m_statusTimer->deleteLater(); - } - if(m_queryThread) - { - m_queryThread->quit(); - m_queryThread->wait(); - } - - delete ui; -} - -void CRobotCtrlWidget::initGif() -{ - m_movie_0.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/free.gif").c_str()); - m_movie_1.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/overlook.gif").c_str()); - m_movie_2.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/charge.gif").c_str()); - m_movie_3.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/overhaul.gif").c_str()); - - ui->label_free->setContentsMargins(0,0,0,0); - ui->label_free->setMovie(&m_movie_0); - - ui->label_overlook->setMovie(&m_movie_1); - ui->label_charge->setMovie(&m_movie_2); - ui->label_overhaul->setMovie(&m_movie_3); - m_movie_0.start(); - m_movie_1.start(); - m_movie_2.start(); - m_movie_3.start(); -} - - -void CRobotCtrlWidget::initialize(int domain,int location) -{ - m_domain = domain; - m_location = location; - ui->comboBox->clear(); - //订阅通道 - connect(ui->switchButton,&SWitchButton::sigCtrlResult,this,&CRobotCtrlWidget::showMessDialog,Qt::QueuedConnection); - connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(setRobotStatus(int)),Qt::QueuedConnection); - connect(ui->exetask,&QPushButton::clicked,this,&CRobotCtrlWidget::execTask); - loadData(); - dealData(); - QMap::iterator it = m_diMap.begin(); - while (it != m_diMap.end()) { - ui->comboBox->addItem(it.value(),it.key()); - it++; - } - - m_queryThread->start(); - m_statusTimer->start(); -} - -QMap CRobotCtrlWidget::getDiMap() -{ - return m_numMap; -} - -void CRobotCtrlWidget::initOnTime() -{ - m_query->init(m_robotInfoMap); -} - -void CRobotCtrlWidget::execTask() -{ - if(ui->comboBox->currentIndex() < 0) - { - LOGERROR("机器人控制任务不能为空!"); - return ; - } - QString tag = ui->comboBox->currentData().toString(); - ctrlRobot(tag); -} - -void CRobotCtrlWidget::execute() -{ - if(!m_timer->isActive()) - { - return ; - } - - if(m_timeOutTimes > m_ctrlTimeMap.value(m_tag,30)) - { - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - m_timer->stop(); - m_timeOutTimes = 0; - QString text = tr("执行任务超时!"); - showMessDialog(text); - unSub(); - return ; - } - - CMbMessage objMsg; - - while(m_objCommon.recvMsg(objMsg,0)) - { - switch (objMsg.getChannelID()) { - case CH_OPT_TO_HMI_OPTCMD_UP: - dealOptMsg(objMsg); - break; - default: - break; - } - } - - m_timeOutTimes++; -} - -void CRobotCtrlWidget::loadData() -{ - loadAllLocation(); - loadDevInfo(); - loadDi(); - loadMi(); - loadLocationDomain(); - loadCtrlTime(); -} - -void CRobotCtrlWidget::loadAllLocation() -{ - m_ltnVec.clear(); - if(m_domain != -1 && m_location != -1) - { - m_ltnVec.append(m_location); - }else if(m_domain != -1 &&m_location == -1) - { - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select location_id from %1 where domain_id = %2 order by location_no").arg("sys_model_location_info").arg(m_domain); - QSqlQuery query; - - if(!m_pReadDb->execute(sqlSequenceQuery, query)) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - m_ltnVec.clear(); - return ; - } - - if(query.isActive()) - { - while(query.next()) - { - int location = query.value(0).toInt(); - m_ltnVec.append(location); - } - } - } - }else if(m_domain == -1) - { - m_ltnVec.clear(); - } -} - -void CRobotCtrlWidget::loadDevInfo() -{ - - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select dev_type_id from %1 where tag_name = '%2'").arg("dev_type_def").arg(DEV_TYPE); - QSqlQuery query; - - if(!m_pReadDb->execute(sqlSequenceQuery, query)) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - m_robotid = -1; - return ; - } - - if(query.isActive()) - { - while(query.next()) - { - m_robotid = query.value(0).toInt(); - } - } - } -} - -void CRobotCtrlWidget::loadDi() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select tag_name, description,seq_no from %1 where dev_type = %2 ").arg("digital").arg(m_robotid); - if(m_ltnVec.size() != 0) - { - QString condition = QString(); - for(int index(0);indexexecute(sqlSequenceQuery, query)) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - return ; - } - - if(query.isActive()) - { - while(query.next()) - { - QString tag_name = query.value(0).toString(); - QString desc = query.value(1).toString(); - int devNum = query.value(2).toInt(); - m_diMap[tag_name] = desc; - m_numMap[devNum] = desc; - } - } - } -} - -void CRobotCtrlWidget::loadMi() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select tag_name,location_id,sub_system,value from %1 where dev_type = %2 ").arg("analog").arg(m_robotid); - if(m_ltnVec.size() != 0) - { - QString condition = QString(); - for(int index(0);indexexecute(sqlSequenceQuery, query)) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - return ; - } - - if(query.isActive()) - { - while(query.next()) - { - QString tag_name = query.value(0).toString(); - int location = query.value(1).toInt(); - int sub = query.value(2).toInt(); - int status = query.value(3).toInt(); - RobotInfoPtr robot(new CRobotInfo()); - robot->initialize(tag_name,sub,location,status); - m_robotInfoMap[tag_name] = robot; - } - } - } -} - -void CRobotCtrlWidget::loadLocationDomain() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select location_id,domain_id from %1 order by location_no").arg("sys_model_location_info"); - - QSqlQuery query; - - if(!m_pReadDb->execute(sqlSequenceQuery, query)) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - return ; - } - - if(query.isActive()) - { - while(query.next()) - { - m_ltnDomainMap[query.value(0).toInt()] = query.value(1).toInt(); - } - } - } -} - -void CRobotCtrlWidget::loadCtrlTime() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select tag_name,ctrl_timeout,is_tagt_state from %1 ").arg("digital_control"); - if(m_ltnVec.size() != 0) - { - QString condition = QString(); - for(int index(0);indexexecute(sqlSequenceQuery, query)) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - return ; - } - - if(query.isActive()) - { - while(query.next()) - { - LOGINFO("%s------%d---------%d",query.value(0).toString().toStdString().c_str(),query.value(1).toInt(),query.value(2).toInt()); - m_ctrlTimeMap[query.value(0).toString()] = query.value(1).toInt(); - m_ctrlStateMap[query.value(0).toString()] = query.value(2).toInt(); - } - } - } -} - -void CRobotCtrlWidget::dealData() -{ - QMap::iterator it = m_robotInfoMap.begin(); - while (it != m_robotInfoMap.end()) { - it.value()->m_domain = m_ltnDomainMap[it.value()->m_location]; - it++; - } - foreach (QString di, m_diMap.keys()) { - QStringList listDi =di.split("."); - foreach (QString ai, m_robotInfoMap.keys()) { - QStringList listAi =ai.split("."); - if(listDi.at(0) == listAi.at(0) && listDi.at(1) == listAi.at(1)) - { - m_diaiMap[di] = ai; - break; - } - } - } -} - -void CRobotCtrlWidget::ctrlRobot(QString &pointTag) -{ - LOGDEBUG("开始控制机器人执行任务,点标签为[%s]",pointTag.toStdString().c_str()); - - SOptCtrlRequest stCtrlCmd; - stCtrlCmd.stHead.strSrcTag = CN_RobotCtrlWidget; - QString ai =m_diaiMap.value(pointTag,QString()); - if(ai.isEmpty()) - { - QString text = tr("未找到控制点[%s]").arg(pointTag); - showMessDialog(text); - return ; - } - RobotInfoPtr ptr = m_robotInfoMap.value(ai,NULL); - stCtrlCmd.stHead.nSrcDomainID = m_stLocalNodeInfo.nDomainId; - stCtrlCmd.stHead.nDstDomainID = ptr ? ptr->m_domain : -1; - stCtrlCmd.stHead.nAppID = ptr ? ptr->m_sub : -1; - stCtrlCmd.stHead.strHostName = m_stLocalNodeInfo.strName ; - stCtrlCmd.stHead.strInstName = CN_RobotCtrlWidget; - stCtrlCmd.stHead.strCommName = m_objCommon.getName(); - stCtrlCmd.stHead.nOptTime = getUTCTimeMsec(); - - SOptCtrlReqQueue reqQueue; - QString tag = "digital."+pointTag+".value"; - reqQueue.strKeyIdTag = tag.toStdString(); - reqQueue.nCtrlType = CTRL_MODE_COMMONCTRL; - reqQueue.dTargetValue = 1; - reqQueue.nCtrlActType = -1; - reqQueue.strOffsetNo = "-1"; - reqQueue.bIsDeviceOccupy = false; - reqQueue.bIsGenAlarm = false; - reqQueue.bCheckInterLock = false; - - stCtrlCmd.vecOptCtrlQueue.push_back(reqQueue); - COptCtrlRequest objReq; - std::string strMsg = objReq.generate(stCtrlCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return ; - } - CMbMessage objMsg; - objMsg.setMsgType(MT_OPT_AUTO_CTRL_DOWN); //指定消息类型 - objMsg.setSubject(ptr ? ptr->m_sub : -1,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 - objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff - m_tag = tag; - - if(m_ctrlStateMap.value(pointTag,0) != 0 ) - { - LOGINFO("测点[%s]需要等待返回",m_tag.toStdString().c_str()); - sub(); - m_timer->start(); - ui->exetask->setEnabled(false); - ui->comboBox->setEnabled(false); - } - if(!m_objCommon.sendMsgToDomain(objMsg,ptr ? ptr->m_domain : -1)) - { - unSub(); - m_timer->stop(); - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - LOGERROR("发送消息失败.AppId=[%d],CH=[%d]",ptr ? ptr->m_sub : -1, CH_HMI_TO_OPT_OPTCMD_DOWN); - }else - { - LOGINFO("发送消息成功.AppId=[%d],CH=[%d]",ptr ? ptr->m_sub : -1, CH_HMI_TO_OPT_OPTCMD_DOWN); - } -} - -bool CRobotCtrlWidget::getSystemInfo() -{ - if(!createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("创建系统信息访问库失败"); - return false; - } - if(kbdSuccess != m_ptrSysInfo->getLocalNodeInfo(m_stLocalNodeInfo)) - { - LOGERROR("获取系统信息失败"); - return false; - } - return true; -} - -void CRobotCtrlWidget::sub() -{ - //目前先订阅所有的应用 - if(!m_objCommon.addSub(0,CH_OPT_TO_HMI_OPTCMD_UP)) - { - LOGERROR("通道[CH_OPT_TO_HMI_OPTCMD_UP]订阅失败."); - }else - { - LOGINFO("通道[CH_OPT_TO_HMI_OPTCMD_UP]订阅成功."); - } -} - -void CRobotCtrlWidget::unSub() -{ - std::vector vecSub =m_objCommon.getMySub(); - for(size_t i=0;istop(); - unSub(); - m_timeOutTimes = 0; - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - return; - }else - { - QString text = QString::fromStdString(stOptCtrlReply.stHead.strResultStr); - showMessDialog(text); - m_timer->stop(); - unSub(); - m_timeOutTimes = 0; - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - } -} - -void CRobotCtrlWidget::setRobotStatus(int index) -{ - Q_UNUSED(index) - // 1-- 空闲状态 2--巡检状态 3--充电状态 4-- 检修状态 - - QString tag = ui->comboBox->currentData().toString(); - QString miTag = m_diaiMap.value(tag); - int status = m_query->getStatus(miTag); - if(status >=5 || status < 1 ) - { - LOGERROR("状态[%d]非法!默认为空闲状态!",status); - status = 1; - } - ui->stackedWidget->setCurrentIndex(status-1); -} - -void CRobotCtrlWidget::onTimeSetRobotStatus() -{ - QString tag = ui->comboBox->currentData().toString(); - QString miTag = m_diaiMap.value(tag); - int status = m_query->getStatus(miTag); - if(status >=5 || status < 1 ) - { - LOGERROR("状态[%d]非法!默认为空闲状态!",status); - status = 1; - } - ui->stackedWidget->setCurrentIndex(status-1); -} - -void CRobotCtrlWidget::showMessDialog(QString text) -{ - QMessageBox::warning(this, QObject::tr("警告"), text, QMessageBox::Ok); -} +#include "CRobotCtrlWidget.h" +#include "SWitchButton.h" +#include "ui_CRobotCtrlWidget.h" +#include +#include +#include "dbms/db_sysinfo_api/CDbSysInfo.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/TimeUtil.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include +#include "operate_server_api/JsonOptCommand.h" + +using namespace kbd_net; +using namespace kbd_idlfile; +using namespace kbd_public; +using namespace std; +CRobotCtrlWidget::CRobotCtrlWidget(QWidget *parent) : + QWidget(parent), + m_needRecv(false), + m_timeOutTimes(0), + m_timer(Q_NULLPTR), + m_statusTimer(Q_NULLPTR), + m_queryThread(Q_NULLPTR), + m_pReadDb(Q_NULLPTR), + m_query(Q_NULLPTR), + ui(new Ui::CRobotCtrlWidget) +{ + ui->setupUi(this); + ui->comboBox->setView(new QListView()); + m_robotid = -1; + m_queryThread = new QThread(this); + m_query = new OnTimeQueryThread(); + m_query->moveToThread(m_queryThread); + connect(m_queryThread,&QThread::started,this,&CRobotCtrlWidget::initOnTime,Qt::QueuedConnection); + connect(m_queryThread,&QThread::finished,m_queryThread,&QThread::deleteLater,Qt::QueuedConnection); + + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + LOGERROR("数据库打开失败!"); + } + getSystemInfo(); + m_timer =new QTimer(this); + m_timer->setInterval(1000); + connect(m_timer,&QTimer::timeout,this,&CRobotCtrlWidget::execute,Qt::QueuedConnection); + m_statusTimer = new QTimer(this); + m_statusTimer->setInterval(1000); + connect(m_statusTimer,&QTimer::timeout,this,&CRobotCtrlWidget::onTimeSetRobotStatus,Qt::QueuedConnection); + ui->label_head->setText(tr("机器人状态")); + initGif(); +} + +CRobotCtrlWidget::~CRobotCtrlWidget() +{ + if(m_timer) + { + m_timer->stop(); + m_timer->deleteLater(); + } + if(m_statusTimer) + { + m_statusTimer->stop(); + m_statusTimer->deleteLater(); + } + if(m_queryThread) + { + m_queryThread->quit(); + m_queryThread->wait(); + } + + delete ui; +} + +void CRobotCtrlWidget::initGif() +{ + m_movie_0.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/free.gif").c_str()); + m_movie_1.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/overlook.gif").c_str()); + m_movie_2.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/charge.gif").c_str()); + m_movie_3.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/overhaul.gif").c_str()); + + ui->label_free->setContentsMargins(0,0,0,0); + ui->label_free->setMovie(&m_movie_0); + + ui->label_overlook->setMovie(&m_movie_1); + ui->label_charge->setMovie(&m_movie_2); + ui->label_overhaul->setMovie(&m_movie_3); + m_movie_0.start(); + m_movie_1.start(); + m_movie_2.start(); + m_movie_3.start(); +} + + +void CRobotCtrlWidget::initialize(int domain,int location) +{ + m_domain = domain; + m_location = location; + ui->comboBox->clear(); + //订阅通道 + connect(ui->switchButton,&SWitchButton::sigCtrlResult,this,&CRobotCtrlWidget::showMessDialog,Qt::QueuedConnection); + connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(setRobotStatus(int)),Qt::QueuedConnection); + connect(ui->exetask,&QPushButton::clicked,this,&CRobotCtrlWidget::execTask); + loadData(); + dealData(); + QMap::iterator it = m_diMap.begin(); + while (it != m_diMap.end()) { + ui->comboBox->addItem(it.value(),it.key()); + it++; + } + + m_queryThread->start(); + m_statusTimer->start(); +} + +QMap CRobotCtrlWidget::getDiMap() +{ + return m_numMap; +} + +void CRobotCtrlWidget::initOnTime() +{ + m_query->init(m_robotInfoMap); +} + +void CRobotCtrlWidget::execTask() +{ + if(ui->comboBox->currentIndex() < 0) + { + LOGERROR("机器人控制任务不能为空!"); + return ; + } + QString tag = ui->comboBox->currentData().toString(); + ctrlRobot(tag); +} + +void CRobotCtrlWidget::execute() +{ + if(!m_timer->isActive()) + { + return ; + } + + if(m_timeOutTimes > m_ctrlTimeMap.value(m_tag,30)) + { + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + m_timer->stop(); + m_timeOutTimes = 0; + QString text = tr("执行任务超时!"); + showMessDialog(text); + unSub(); + return ; + } + + CMbMessage objMsg; + + while(m_objCommon.recvMsg(objMsg,0)) + { + switch (objMsg.getChannelID()) { + case CH_OPT_TO_HMI_OPTCMD_UP: + dealOptMsg(objMsg); + break; + default: + break; + } + } + + m_timeOutTimes++; +} + +void CRobotCtrlWidget::loadData() +{ + loadAllLocation(); + loadDevInfo(); + loadDi(); + loadMi(); + loadLocationDomain(); + loadCtrlTime(); +} + +void CRobotCtrlWidget::loadAllLocation() +{ + m_ltnVec.clear(); + if(m_domain != -1 && m_location != -1) + { + m_ltnVec.append(m_location); + }else if(m_domain != -1 &&m_location == -1) + { + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select location_id from %1 where domain_id = %2 order by location_no").arg("sys_model_location_info").arg(m_domain); + QSqlQuery query; + + if(!m_pReadDb->execute(sqlSequenceQuery, query)) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + m_ltnVec.clear(); + return ; + } + + if(query.isActive()) + { + while(query.next()) + { + int location = query.value(0).toInt(); + m_ltnVec.append(location); + } + } + } + }else if(m_domain == -1) + { + m_ltnVec.clear(); + } +} + +void CRobotCtrlWidget::loadDevInfo() +{ + + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select dev_type_id from %1 where tag_name = '%2'").arg("dev_type_def").arg(DEV_TYPE); + QSqlQuery query; + + if(!m_pReadDb->execute(sqlSequenceQuery, query)) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + m_robotid = -1; + return ; + } + + if(query.isActive()) + { + while(query.next()) + { + m_robotid = query.value(0).toInt(); + } + } + } +} + +void CRobotCtrlWidget::loadDi() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select tag_name, description,seq_no from %1 where dev_type = %2 ").arg("digital").arg(m_robotid); + if(m_ltnVec.size() != 0) + { + QString condition = QString(); + for(int index(0);indexexecute(sqlSequenceQuery, query)) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + return ; + } + + if(query.isActive()) + { + while(query.next()) + { + QString tag_name = query.value(0).toString(); + QString desc = query.value(1).toString(); + int devNum = query.value(2).toInt(); + m_diMap[tag_name] = desc; + m_numMap[devNum] = desc; + } + } + } +} + +void CRobotCtrlWidget::loadMi() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select tag_name,location_id,sub_system,value from %1 where dev_type = %2 ").arg("analog").arg(m_robotid); + if(m_ltnVec.size() != 0) + { + QString condition = QString(); + for(int index(0);indexexecute(sqlSequenceQuery, query)) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + return ; + } + + if(query.isActive()) + { + while(query.next()) + { + QString tag_name = query.value(0).toString(); + int location = query.value(1).toInt(); + int sub = query.value(2).toInt(); + int status = query.value(3).toInt(); + RobotInfoPtr robot(new CRobotInfo()); + robot->initialize(tag_name,sub,location,status); + m_robotInfoMap[tag_name] = robot; + } + } + } +} + +void CRobotCtrlWidget::loadLocationDomain() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select location_id,domain_id from %1 order by location_no").arg("sys_model_location_info"); + + QSqlQuery query; + + if(!m_pReadDb->execute(sqlSequenceQuery, query)) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + return ; + } + + if(query.isActive()) + { + while(query.next()) + { + m_ltnDomainMap[query.value(0).toInt()] = query.value(1).toInt(); + } + } + } +} + +void CRobotCtrlWidget::loadCtrlTime() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select tag_name,ctrl_timeout,is_tagt_state from %1 ").arg("digital_control"); + if(m_ltnVec.size() != 0) + { + QString condition = QString(); + for(int index(0);indexexecute(sqlSequenceQuery, query)) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + return ; + } + + if(query.isActive()) + { + while(query.next()) + { + LOGINFO("%s------%d---------%d",query.value(0).toString().toStdString().c_str(),query.value(1).toInt(),query.value(2).toInt()); + m_ctrlTimeMap[query.value(0).toString()] = query.value(1).toInt(); + m_ctrlStateMap[query.value(0).toString()] = query.value(2).toInt(); + } + } + } +} + +void CRobotCtrlWidget::dealData() +{ + QMap::iterator it = m_robotInfoMap.begin(); + while (it != m_robotInfoMap.end()) { + it.value()->m_domain = m_ltnDomainMap[it.value()->m_location]; + it++; + } + foreach (QString di, m_diMap.keys()) { + QStringList listDi =di.split("."); + foreach (QString ai, m_robotInfoMap.keys()) { + QStringList listAi =ai.split("."); + if(listDi.at(0) == listAi.at(0) && listDi.at(1) == listAi.at(1)) + { + m_diaiMap[di] = ai; + break; + } + } + } +} + +void CRobotCtrlWidget::ctrlRobot(QString &pointTag) +{ + LOGDEBUG("开始控制机器人执行任务,点标签为[%s]",pointTag.toStdString().c_str()); + + SOptCtrlRequest stCtrlCmd; + stCtrlCmd.stHead.strSrcTag = CN_RobotCtrlWidget; + QString ai =m_diaiMap.value(pointTag,QString()); + if(ai.isEmpty()) + { + QString text = tr("未找到控制点[%s]").arg(pointTag); + showMessDialog(text); + return ; + } + RobotInfoPtr ptr = m_robotInfoMap.value(ai,NULL); + stCtrlCmd.stHead.nSrcDomainID = m_stLocalNodeInfo.nDomainId; + stCtrlCmd.stHead.nDstDomainID = ptr ? ptr->m_domain : -1; + stCtrlCmd.stHead.nAppID = ptr ? ptr->m_sub : -1; + stCtrlCmd.stHead.strHostName = m_stLocalNodeInfo.strName ; + stCtrlCmd.stHead.strInstName = CN_RobotCtrlWidget; + stCtrlCmd.stHead.strCommName = m_objCommon.getName(); + stCtrlCmd.stHead.nOptTime = getUTCTimeMsec(); + + SOptCtrlReqQueue reqQueue; + QString tag = "digital."+pointTag+".value"; + reqQueue.strKeyIdTag = tag.toStdString(); + reqQueue.nCtrlType = CTRL_MODE_COMMONCTRL; + reqQueue.dTargetValue = 1; + reqQueue.nCtrlActType = -1; + reqQueue.strOffsetNo = "-1"; + reqQueue.bIsDeviceOccupy = false; + reqQueue.bIsGenAlarm = false; + reqQueue.bCheckInterLock = false; + + stCtrlCmd.vecOptCtrlQueue.push_back(reqQueue); + COptCtrlRequest objReq; + std::string strMsg = objReq.generate(stCtrlCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return ; + } + CMbMessage objMsg; + objMsg.setMsgType(MT_OPT_AUTO_CTRL_DOWN); //指定消息类型 + objMsg.setSubject(ptr ? ptr->m_sub : -1,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 + objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff + m_tag = tag; + + if(m_ctrlStateMap.value(pointTag,0) != 0 ) + { + LOGINFO("测点[%s]需要等待返回",m_tag.toStdString().c_str()); + sub(); + m_timer->start(); + ui->exetask->setEnabled(false); + ui->comboBox->setEnabled(false); + } + if(!m_objCommon.sendMsgToDomain(objMsg,ptr ? ptr->m_domain : -1)) + { + unSub(); + m_timer->stop(); + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + LOGERROR("发送消息失败.AppId=[%d],CH=[%d]",ptr ? ptr->m_sub : -1, CH_HMI_TO_OPT_OPTCMD_DOWN); + }else + { + LOGINFO("发送消息成功.AppId=[%d],CH=[%d]",ptr ? ptr->m_sub : -1, CH_HMI_TO_OPT_OPTCMD_DOWN); + } +} + +bool CRobotCtrlWidget::getSystemInfo() +{ + if(!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库失败"); + return false; + } + if(kbdSuccess != m_ptrSysInfo->getLocalNodeInfo(m_stLocalNodeInfo)) + { + LOGERROR("获取系统信息失败"); + return false; + } + return true; +} + +void CRobotCtrlWidget::sub() +{ + //目前先订阅所有的应用 + if(!m_objCommon.addSub(0,CH_OPT_TO_HMI_OPTCMD_UP)) + { + LOGERROR("通道[CH_OPT_TO_HMI_OPTCMD_UP]订阅失败."); + }else + { + LOGINFO("通道[CH_OPT_TO_HMI_OPTCMD_UP]订阅成功."); + } +} + +void CRobotCtrlWidget::unSub() +{ + std::vector vecSub =m_objCommon.getMySub(); + for(size_t i=0;istop(); + unSub(); + m_timeOutTimes = 0; + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + return; + }else + { + QString text = QString::fromStdString(stOptCtrlReply.stHead.strResultStr); + showMessDialog(text); + m_timer->stop(); + unSub(); + m_timeOutTimes = 0; + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + } +} + +void CRobotCtrlWidget::setRobotStatus(int index) +{ + Q_UNUSED(index) + // 1-- 空闲状态 2--巡检状态 3--充电状态 4-- 检修状态 + + QString tag = ui->comboBox->currentData().toString(); + QString miTag = m_diaiMap.value(tag); + int status = m_query->getStatus(miTag); + if(status >=5 || status < 1 ) + { + LOGERROR("状态[%d]非法!默认为空闲状态!",status); + status = 1; + } + ui->stackedWidget->setCurrentIndex(status-1); +} + +void CRobotCtrlWidget::onTimeSetRobotStatus() +{ + QString tag = ui->comboBox->currentData().toString(); + QString miTag = m_diaiMap.value(tag); + int status = m_query->getStatus(miTag); + if(status >=5 || status < 1 ) + { + LOGERROR("状态[%d]非法!默认为空闲状态!",status); + status = 1; + } + ui->stackedWidget->setCurrentIndex(status-1); +} + +void CRobotCtrlWidget::showMessDialog(QString text) +{ + QMessageBox::warning(this, QObject::tr("警告"), text, QMessageBox::Ok); +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.h index 17203a52..543b10ac 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.h @@ -1,113 +1,113 @@ -#ifndef CROBOTCTRLWIDGET_H -#define CROBOTCTRLWIDGET_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "db_api_ex/CDbApi.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include -#include "OnTimeQueryThread.h" -#include "net_msg_bus_api/CMbCommunicator.h" -#include "common/MessageChannel.h" -#include - -class QTimer; -class SWitchButton; - -namespace Ui { -class CRobotCtrlWidget; -} - -class CRobotCtrlWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CRobotCtrlWidget(QWidget *parent = 0); - ~CRobotCtrlWidget(); - - void initGif(); - void initialize(int domain, int location); - /** - * @brief getDiMap 获取数字量map - * @return - */ - QMap getDiMap(); -public slots: - void setRobotStatus(int index); - void onTimeSetRobotStatus(); - /** - * @brief showMessDialog 弹窗提示 - * @param text - */ - void showMessDialog(QString text); -private slots: - /** - * @brief initOnTime 初始化定时采集机器人状态线程 - */ - void initOnTime(); - /** - * @brief execTask 执行任务 - */ - void execTask(); - /** - * @brief checkOutTime 检查执行任务是否超时 - */ - void execute(); - -private: - void loadData(); - void loadAllLocation(); - void loadDevInfo(); - void loadDi(); - void loadMi(); - void loadLocationDomain(); - void loadCtrlTime(); - void dealData(); - void ctrlRobot(QString &pointTag); - bool getSystemInfo(); - void sub(); - void unSub(); - - void dealOptMsg(const kbd_net::CMbMessage &objMsg); - - void parseMsg(const kbd_net::CMbMessage &objMsg); -private: - Ui::CRobotCtrlWidget *ui; - - kbd_dbms::CDbApi * m_pReadDb; - QMap m_diMap; //< - QMap m_numMap; //< <设备点号,描述> - QMap m_robotInfoMap; //< - - QMap m_diaiMap; // - - QMap m_ltnDomainMap; // <车站id,域id> - QMap m_ctrlTimeMap; // - QMap m_ctrlStateMap; // - int m_location; - int m_domain; - bool m_needRecv; - QThread *m_queryThread; - OnTimeQueryThread *m_query; - - kbd_public::SNodeInfo m_stLocalNodeInfo; //本机节点信息 - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; //创建系统信息访问智能库指针 - - kbd_net::CMbCommunicator m_objCommon; - QString m_tag; - int m_timeOutTimes; - QTimer *m_timer; //等待超时定时器 - QTimer *m_statusTimer; //定时更新机器人状态定时器 - - QVector m_ltnVec; - int m_robotid; - - QMovie m_movie_0; - QMovie m_movie_1; - QMovie m_movie_2; - QMovie m_movie_3; - -}; - -#endif // CROBOTCTRLWIDGET_H +#ifndef CROBOTCTRLWIDGET_H +#define CROBOTCTRLWIDGET_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "db_api_ex/CDbApi.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include +#include "OnTimeQueryThread.h" +#include "net_msg_bus_api/CMbCommunicator.h" +#include "common/MessageChannel.h" +#include + +class QTimer; +class SWitchButton; + +namespace Ui { +class CRobotCtrlWidget; +} + +class CRobotCtrlWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CRobotCtrlWidget(QWidget *parent = 0); + ~CRobotCtrlWidget(); + + void initGif(); + void initialize(int domain, int location); + /** + * @brief getDiMap 获取数字量map + * @return + */ + QMap getDiMap(); +public slots: + void setRobotStatus(int index); + void onTimeSetRobotStatus(); + /** + * @brief showMessDialog 弹窗提示 + * @param text + */ + void showMessDialog(QString text); +private slots: + /** + * @brief initOnTime 初始化定时采集机器人状态线程 + */ + void initOnTime(); + /** + * @brief execTask 执行任务 + */ + void execTask(); + /** + * @brief checkOutTime 检查执行任务是否超时 + */ + void execute(); + +private: + void loadData(); + void loadAllLocation(); + void loadDevInfo(); + void loadDi(); + void loadMi(); + void loadLocationDomain(); + void loadCtrlTime(); + void dealData(); + void ctrlRobot(QString &pointTag); + bool getSystemInfo(); + void sub(); + void unSub(); + + void dealOptMsg(const kbd_net::CMbMessage &objMsg); + + void parseMsg(const kbd_net::CMbMessage &objMsg); +private: + Ui::CRobotCtrlWidget *ui; + + kbd_dbms::CDbApi * m_pReadDb; + QMap m_diMap; //< + QMap m_numMap; //< <设备点号,描述> + QMap m_robotInfoMap; //< + + QMap m_diaiMap; // + + QMap m_ltnDomainMap; // <车站id,域id> + QMap m_ctrlTimeMap; // + QMap m_ctrlStateMap; // + int m_location; + int m_domain; + bool m_needRecv; + QThread *m_queryThread; + OnTimeQueryThread *m_query; + + kbd_public::SNodeInfo m_stLocalNodeInfo; //本机节点信息 + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; //创建系统信息访问智能库指针 + + kbd_net::CMbCommunicator m_objCommon; + QString m_tag; + int m_timeOutTimes; + QTimer *m_timer; //等待超时定时器 + QTimer *m_statusTimer; //定时更新机器人状态定时器 + + QVector m_ltnVec; + int m_robotid; + + QMovie m_movie_0; + QMovie m_movie_1; + QMovie m_movie_2; + QMovie m_movie_3; + +}; + +#endif // CROBOTCTRLWIDGET_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.ui b/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.ui index 33de5c08..76cb717c 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.ui +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotCtrlWidget.ui @@ -1,984 +1,984 @@ - - - CRobotCtrlWidget - - - - 0 - 0 - 236 - 705 - - - - - 0 - 0 - - - - Form - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 10 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 50 - 20 - - - - - 50 - 16777215 - - - - - - - - - 0 - - - 13 - - - 0 - - - 0 - - - 0 - - - 10 - - - - - - 0 - 30 - - - - - 请选择设备 - - - - - - - - - 0 - 30 - - - - 执行任务 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 40 - - - - - - - - - - Qt::AlignCenter - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 450 - - - - - 16777215 - 450 - - - - 0 - - - - - 0 - 450 - - - - - 16777215 - 450 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - - - - - - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - 空闲中 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - 巡检中 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - 充电中 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - 检修中 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 0 - 20 - - - - - 16777215 - 16777215 - - - - 告警联动: - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - - Qt::Vertical - - - - 20 - 27 - - - - - - - - - SWitchButton - QWidget -
SWitchButton.h
- 1 -
-
- - -
+ + + CRobotCtrlWidget + + + + 0 + 0 + 236 + 705 + + + + + 0 + 0 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 10 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 50 + 20 + + + + + 50 + 16777215 + + + + + + + + + 0 + + + 13 + + + 0 + + + 0 + + + 0 + + + 10 + + + + + + 0 + 30 + + + + + 请选择设备 + + + + + + + + + 0 + 30 + + + + 执行任务 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 40 + + + + + + + + + + Qt::AlignCenter + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 450 + + + + + 16777215 + 450 + + + + 0 + + + + + 0 + 450 + + + + + 16777215 + 450 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + 空闲中 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 巡检中 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 充电中 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 检修中 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 0 + 20 + + + + + 16777215 + 16777215 + + + + 告警联动: + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 27 + + + + + + + + + SWitchButton + QWidget +
SWitchButton.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.cpp index 08becaae..2b1d1d3f 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.cpp @@ -1,107 +1,107 @@ -#include "CRobotDialog.h" -#include "ui_CRobotDialog.h" -#include "CRobotCCDVideoForm.h" -#include "CRobotAVWidget.h" -#include "CRobotCCDVideoItemModel.h" -#include -#include "CRobotFileCollect.h" -#include "CRobotFileMng.h" -#include -#include -#include -#include -#include -#include -CRobotDialog::CRobotDialog(bool editMode,QWidget *parent) : - QDialog(parent), - m_collect(Q_NULLPTR), - m_mng(Q_NULLPTR), - m_model(Q_NULLPTR), - m_thread(Q_NULLPTR), - m_avWidget(Q_NULLPTR), - m_ccdVideoWidget(Q_NULLPTR), - m_bEditMode(editMode), - ui(new Ui::CRobotDialog) -{ - ui->setupUi(this); - initView(); - - - m_collect = new CRobotFileCollect(); - m_mng = new CRobotFileMng(); - if(!editMode) - { - if(!m_thread) - { - m_thread = new QThread(this); - m_collect->moveToThread(m_thread); - m_mng->moveToThread(m_thread); - connect(m_thread,&QThread::started,m_collect,&CRobotFileCollect::initialize,Qt::QueuedConnection); - connect(m_thread,&QThread::finished,m_thread,&QThread::deleteLater,Qt::QueuedConnection); - } - connect(m_collect,&CRobotFileCollect::sigUpdateFile,m_mng,&CRobotFileMng::slotUpdateFile,Qt::QueuedConnection); - connect(m_ccdVideoWidget,&CRobotCCDVideoForm::sigAvPlay,this,&CRobotDialog::slotAvPlay,Qt::QueuedConnection); - connect(m_ccdVideoWidget,&CRobotCCDVideoForm::sigCCDPlay,this,&CRobotDialog::slotCCDPlay,Qt::QueuedConnection); - connect(m_avWidget,&CRobotAVWidget::sigCCDPlay,this,&CRobotDialog::slotCCDPlay,Qt::QueuedConnection); - connect(ui->label,&Label::avPlay,this,&CRobotDialog::slotAvPlay,Qt::QueuedConnection); - connect(ui->label,&Label::ccdPlay,this,&CRobotDialog::slotCCDPlay,Qt::QueuedConnection); - } - ui->stackedWidget->setCurrentIndex(0); -} - -CRobotDialog::~CRobotDialog() -{ - if(m_thread) - { - m_thread->quit(); - m_thread->wait(); - } - delete ui; -} - -void CRobotDialog::initialize(QMap pointMap) -{ - m_model = new CRobotCCDVideoItemModel(this); - m_ccdVideoWidget->setItemModel(m_model); - m_model->initialize(pointMap); - connect(m_mng,&CRobotFileMng::sigMsgAdd,m_model,&CRobotCCDVideoItemModel::slotMsgAdd,Qt::QueuedConnection); - connect(m_mng,&CRobotFileMng::sigMsgSub,m_model,&CRobotCCDVideoItemModel::slotMsgSub,Qt::QueuedConnection); - connect(m_model,&CRobotCCDVideoItemModel::sigAllMsgAdd,m_mng,&CRobotFileMng::slotAllMsgAdd,Qt::QueuedConnection); - - if(m_thread &&!m_thread->isRunning()) - { - m_thread->start(); - } -} - -void CRobotDialog::slotAvPlay(QString path) -{ - ui->stackedWidget->setCurrentIndex(0); - ui->label->clear(); - m_avWidget->play(path); -} - -void CRobotDialog::slotCCDPlay(QString path) -{ - m_avWidget->stop(); - ui->stackedWidget->setCurrentIndex(1); - ui->label->clear(); - ui->label->setStyleSheet("QLabel{image:url("+path+");}"); -} - -void CRobotDialog::initView() -{ - - QGridLayout *ccdLay = new QGridLayout(ui->ccdVideoWidget); - m_ccdVideoWidget = new CRobotCCDVideoForm(this); - ccdLay->setContentsMargins(0,0,0,0); - ccdLay->addWidget(m_ccdVideoWidget); - - QGridLayout *avLay = new QGridLayout(ui->avWidget); - m_avWidget = new CRobotAVWidget(this); - avLay->setContentsMargins(0,0,0,0); - avLay->addWidget(m_avWidget); - ui->label->setContentsMargins(0,0,0,0); - - setWindowTitle(tr("机器人联动")); -} +#include "CRobotDialog.h" +#include "ui_CRobotDialog.h" +#include "CRobotCCDVideoForm.h" +#include "CRobotAVWidget.h" +#include "CRobotCCDVideoItemModel.h" +#include +#include "CRobotFileCollect.h" +#include "CRobotFileMng.h" +#include +#include +#include +#include +#include +#include +CRobotDialog::CRobotDialog(bool editMode,QWidget *parent) : + QDialog(parent), + m_collect(Q_NULLPTR), + m_mng(Q_NULLPTR), + m_model(Q_NULLPTR), + m_thread(Q_NULLPTR), + m_avWidget(Q_NULLPTR), + m_ccdVideoWidget(Q_NULLPTR), + m_bEditMode(editMode), + ui(new Ui::CRobotDialog) +{ + ui->setupUi(this); + initView(); + + + m_collect = new CRobotFileCollect(); + m_mng = new CRobotFileMng(); + if(!editMode) + { + if(!m_thread) + { + m_thread = new QThread(this); + m_collect->moveToThread(m_thread); + m_mng->moveToThread(m_thread); + connect(m_thread,&QThread::started,m_collect,&CRobotFileCollect::initialize,Qt::QueuedConnection); + connect(m_thread,&QThread::finished,m_thread,&QThread::deleteLater,Qt::QueuedConnection); + } + connect(m_collect,&CRobotFileCollect::sigUpdateFile,m_mng,&CRobotFileMng::slotUpdateFile,Qt::QueuedConnection); + connect(m_ccdVideoWidget,&CRobotCCDVideoForm::sigAvPlay,this,&CRobotDialog::slotAvPlay,Qt::QueuedConnection); + connect(m_ccdVideoWidget,&CRobotCCDVideoForm::sigCCDPlay,this,&CRobotDialog::slotCCDPlay,Qt::QueuedConnection); + connect(m_avWidget,&CRobotAVWidget::sigCCDPlay,this,&CRobotDialog::slotCCDPlay,Qt::QueuedConnection); + connect(ui->label,&Label::avPlay,this,&CRobotDialog::slotAvPlay,Qt::QueuedConnection); + connect(ui->label,&Label::ccdPlay,this,&CRobotDialog::slotCCDPlay,Qt::QueuedConnection); + } + ui->stackedWidget->setCurrentIndex(0); +} + +CRobotDialog::~CRobotDialog() +{ + if(m_thread) + { + m_thread->quit(); + m_thread->wait(); + } + delete ui; +} + +void CRobotDialog::initialize(QMap pointMap) +{ + m_model = new CRobotCCDVideoItemModel(this); + m_ccdVideoWidget->setItemModel(m_model); + m_model->initialize(pointMap); + connect(m_mng,&CRobotFileMng::sigMsgAdd,m_model,&CRobotCCDVideoItemModel::slotMsgAdd,Qt::QueuedConnection); + connect(m_mng,&CRobotFileMng::sigMsgSub,m_model,&CRobotCCDVideoItemModel::slotMsgSub,Qt::QueuedConnection); + connect(m_model,&CRobotCCDVideoItemModel::sigAllMsgAdd,m_mng,&CRobotFileMng::slotAllMsgAdd,Qt::QueuedConnection); + + if(m_thread &&!m_thread->isRunning()) + { + m_thread->start(); + } +} + +void CRobotDialog::slotAvPlay(QString path) +{ + ui->stackedWidget->setCurrentIndex(0); + ui->label->clear(); + m_avWidget->play(path); +} + +void CRobotDialog::slotCCDPlay(QString path) +{ + m_avWidget->stop(); + ui->stackedWidget->setCurrentIndex(1); + ui->label->clear(); + ui->label->setStyleSheet("QLabel{image:url("+path+");}"); +} + +void CRobotDialog::initView() +{ + + QGridLayout *ccdLay = new QGridLayout(ui->ccdVideoWidget); + m_ccdVideoWidget = new CRobotCCDVideoForm(this); + ccdLay->setContentsMargins(0,0,0,0); + ccdLay->addWidget(m_ccdVideoWidget); + + QGridLayout *avLay = new QGridLayout(ui->avWidget); + m_avWidget = new CRobotAVWidget(this); + avLay->setContentsMargins(0,0,0,0); + avLay->addWidget(m_avWidget); + ui->label->setContentsMargins(0,0,0,0); + + setWindowTitle(tr("机器人联动")); +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.h index ec3e849c..4ff9235b 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.h @@ -1,47 +1,47 @@ -#ifndef CROBOTDIALOG_H -#define CROBOTDIALOG_H - -#include - - -class CRobotCCDVideoForm; -class CRobotAVWidget; -class CRobotCCDVideoItemModel; -class QThread; -class CRobotFileCollect; -class CRobotFileMng; -namespace Ui { -class CRobotDialog; -} - -class CRobotDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CRobotDialog(bool editMode = false, QWidget *parent = 0); - ~CRobotDialog(); - - void initialize(QMap pointMap); - -public slots: - void slotAvPlay(QString path); - void slotCCDPlay(QString path); -private: - void initView(); - - -private: - Ui::CRobotDialog *ui; - - CRobotCCDVideoForm * m_ccdVideoWidget; - CRobotAVWidget * m_avWidget; - - QThread *m_thread; - CRobotFileCollect *m_collect; - CRobotFileMng *m_mng; - CRobotCCDVideoItemModel * m_model; - bool m_bEditMode; -}; - -#endif // CROBOTDIALOG_H +#ifndef CROBOTDIALOG_H +#define CROBOTDIALOG_H + +#include + + +class CRobotCCDVideoForm; +class CRobotAVWidget; +class CRobotCCDVideoItemModel; +class QThread; +class CRobotFileCollect; +class CRobotFileMng; +namespace Ui { +class CRobotDialog; +} + +class CRobotDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CRobotDialog(bool editMode = false, QWidget *parent = 0); + ~CRobotDialog(); + + void initialize(QMap pointMap); + +public slots: + void slotAvPlay(QString path); + void slotCCDPlay(QString path); +private: + void initView(); + + +private: + Ui::CRobotDialog *ui; + + CRobotCCDVideoForm * m_ccdVideoWidget; + CRobotAVWidget * m_avWidget; + + QThread *m_thread; + CRobotFileCollect *m_collect; + CRobotFileMng *m_mng; + CRobotCCDVideoItemModel * m_model; + bool m_bEditMode; +}; + +#endif // CROBOTDIALOG_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.ui b/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.ui index c032fc05..d1c70d5a 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.ui +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotDialog.ui @@ -1,136 +1,136 @@ - - - CRobotDialog - - - - 0 - 0 - 1057 - 548 - - - - Dialog - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - 0 - 0 - - - - - 239 - 0 - - - - - 239 - 16777215 - - - - - - - - - 0 - 0 - - - - 0 - - - 0 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - Label - QLabel -
Label.h
-
-
- - -
+ + + CRobotDialog + + + + 0 + 0 + 1057 + 548 + + + + Dialog + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + 0 + + + + + 239 + 0 + + + + + 239 + 16777215 + + + + + + + + + 0 + 0 + + + + 0 + + + 0 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + Label + QLabel +
Label.h
+
+
+ + +
diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileCollect.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileCollect.cpp index abbfd079..e7cec316 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileCollect.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileCollect.cpp @@ -1,120 +1,120 @@ -#include "CRobotFileCollect.h" -#include -#include "Common.h" -#include "pub_logger_api/logger.h" -#include -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CommonConfigParse.h" - -using namespace kbd_public; - -CRobotFileCollect::CRobotFileCollect(QObject *parent): - QObject(parent), - m_time(NULL) -{ - -} - -CRobotFileCollect::~CRobotFileCollect() -{ - release(); -} - -void CRobotFileCollect::initialize() -{ - loadConfig(); - if(!m_time) - { - m_time = new QTimer(); - m_time->setInterval(2000); - connect(this,&CRobotFileCollect::sigTimerShot,this,&CRobotFileCollect::slotTimerShot,Qt::QueuedConnection); - connect(m_time,&QTimer::timeout,this,&CRobotFileCollect::onTimeLoadFile,Qt::QueuedConnection); - } - emit sigTimerShot(true); -} - -void CRobotFileCollect::release() -{ - emit sigTimerShot(false); - if(m_time != Q_NULLPTR) - { - m_time->blockSignals(true); - m_time->stop(); - m_time = Q_NULLPTR; - } -} - -void CRobotFileCollect::loadConfig() -{ - CCommonConfigParse config; - const std::string file = kbd_public::CFileUtil::getPathOfCfgFile("robot_config.xml"); - std::string loadFilePath; - config.load(file); - int error = config.getStringValue("robot_config","loadFilePath",loadFilePath); - if( error != kbdSuccess) - { - m_path = "../../data/test";; - LOGERROR("机器人加载文件路径解析失败!文件[%s],错误码[%d]",file.c_str(),error); - }else - { - m_path = QString::fromStdString(loadFilePath); - } - qDebug()<<"path:"<start(); - }else - { - m_time->stop(); - } - } -} - -void CRobotFileCollect::onTimeLoadFile() -{ - QFileInfoList fileList = getFileList(m_path); - QMap map; - for (int i = 0; i < fileList.size(); ++i) - { - QFileInfo fileInfo = fileList.at(i); - RobotFilePtr robotFile(new CRobotFileInfo()); - if(robotFile->initialize(fileInfo) == kbdSuccess) - { - map.insert(robotFile->m_execPath,robotFile); - - }else - { - LOGERROR("解析文件错误!"); - } - } - if(map.size() > 0) - { - emit sigUpdateFile(map); - } - map.clear(); - //查询内存库 -} - -QFileInfoList CRobotFileCollect::getFileList(const QString &path) -{ - QDir dir(path); - QFileInfoList file_list = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks); - QFileInfoList folder_list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - - for(int i = 0; i != folder_list.size(); i++) - { - QString name = folder_list.at(i).absoluteFilePath(); - - QFileInfoList child_file_list = getFileList(name); - file_list.append(child_file_list); - } - - return file_list; -} - +#include "CRobotFileCollect.h" +#include +#include "Common.h" +#include "pub_logger_api/logger.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CommonConfigParse.h" + +using namespace kbd_public; + +CRobotFileCollect::CRobotFileCollect(QObject *parent): + QObject(parent), + m_time(NULL) +{ + +} + +CRobotFileCollect::~CRobotFileCollect() +{ + release(); +} + +void CRobotFileCollect::initialize() +{ + loadConfig(); + if(!m_time) + { + m_time = new QTimer(); + m_time->setInterval(2000); + connect(this,&CRobotFileCollect::sigTimerShot,this,&CRobotFileCollect::slotTimerShot,Qt::QueuedConnection); + connect(m_time,&QTimer::timeout,this,&CRobotFileCollect::onTimeLoadFile,Qt::QueuedConnection); + } + emit sigTimerShot(true); +} + +void CRobotFileCollect::release() +{ + emit sigTimerShot(false); + if(m_time != Q_NULLPTR) + { + m_time->blockSignals(true); + m_time->stop(); + m_time = Q_NULLPTR; + } +} + +void CRobotFileCollect::loadConfig() +{ + CCommonConfigParse config; + const std::string file = kbd_public::CFileUtil::getPathOfCfgFile("robot_config.xml"); + std::string loadFilePath; + config.load(file); + int error = config.getStringValue("robot_config","loadFilePath",loadFilePath); + if( error != kbdSuccess) + { + m_path = "../../data/test";; + LOGERROR("机器人加载文件路径解析失败!文件[%s],错误码[%d]",file.c_str(),error); + }else + { + m_path = QString::fromStdString(loadFilePath); + } + qDebug()<<"path:"<start(); + }else + { + m_time->stop(); + } + } +} + +void CRobotFileCollect::onTimeLoadFile() +{ + QFileInfoList fileList = getFileList(m_path); + QMap map; + for (int i = 0; i < fileList.size(); ++i) + { + QFileInfo fileInfo = fileList.at(i); + RobotFilePtr robotFile(new CRobotFileInfo()); + if(robotFile->initialize(fileInfo) == kbdSuccess) + { + map.insert(robotFile->m_execPath,robotFile); + + }else + { + LOGERROR("解析文件错误!"); + } + } + if(map.size() > 0) + { + emit sigUpdateFile(map); + } + map.clear(); + //查询内存库 +} + +QFileInfoList CRobotFileCollect::getFileList(const QString &path) +{ + QDir dir(path); + QFileInfoList file_list = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks); + QFileInfoList folder_list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + + for(int i = 0; i != folder_list.size(); i++) + { + QString name = folder_list.at(i).absoluteFilePath(); + + QFileInfoList child_file_list = getFileList(name); + file_list.append(child_file_list); + } + + return file_list; +} + diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileCollect.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileCollect.h index 426a6339..3a523e55 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileCollect.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileCollect.h @@ -1,39 +1,39 @@ -#ifndef CROBOTFILECOLLECT_H -#define CROBOTFILECOLLECT_H - -#include -#include -#include -#include "CRobotFileInfo.h" -#include -class QTimer; -class CRobotFileCollect : public QObject -{ - Q_OBJECT -public: - CRobotFileCollect(QObject *parent = nullptr); - - ~CRobotFileCollect(); - - void initialize(); - - void release(); - void loadConfig(); -signals: - //< 启停定时器 - void sigTimerShot(const bool bStop); - - void sigUpdateFile(const QMap map); -public slots: - void slotTimerShot(const bool start); -private: - void onTimeLoadFile(); - QFileInfoList getFileList(const QString &path); -private: - - QTimer *m_time; - QString m_path; - -}; - -#endif // CROBOTFILECOLLECT_H +#ifndef CROBOTFILECOLLECT_H +#define CROBOTFILECOLLECT_H + +#include +#include +#include +#include "CRobotFileInfo.h" +#include +class QTimer; +class CRobotFileCollect : public QObject +{ + Q_OBJECT +public: + CRobotFileCollect(QObject *parent = nullptr); + + ~CRobotFileCollect(); + + void initialize(); + + void release(); + void loadConfig(); +signals: + //< 启停定时器 + void sigTimerShot(const bool bStop); + + void sigUpdateFile(const QMap map); +public slots: + void slotTimerShot(const bool start); +private: + void onTimeLoadFile(); + QFileInfoList getFileList(const QString &path); +private: + + QTimer *m_time; + QString m_path; + +}; + +#endif // CROBOTFILECOLLECT_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileInfo.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileInfo.cpp index 1c328dce..d0515038 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileInfo.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileInfo.cpp @@ -1,172 +1,172 @@ -#include "CRobotFileInfo.h" -#include "QFileInfo" -#include "pub_logger_api/logger.h" -#include "Common.h" -#include - -CRobotFileInfo::CRobotFileInfo() -{ - m_filePath = QString(); - m_fileName = QString(); - m_fileType = E_ROBOT_CCD; - m_devgId = -1; - m_devgName = QString(); - time_stamp = 0; - -} - -CRobotFileInfo::CRobotFileInfo(const CRobotFileInfo &other) -{ - m_filePath = other.m_filePath; - m_fileName = other.m_fileName; - m_fileType = other.m_fileType; - m_devgId = other.m_devgId; - m_devgName = other.m_devgName; - time_stamp = other.time_stamp; -} - -bool CRobotFileInfo::lessThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_TIME: - if(time_stamp time_stamp) - { - return true; - } - break; - case E_SORT_DEV: - if(m_devgId m_devgId) - { - return true; - } - break; - case E_SORT_TYPE: - if(m_fileType < info->m_fileType) - { - return true; - } - break; - default: - break; - } - return false; -} - -bool CRobotFileInfo::moreThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_TIME: - if(time_stamp >= info->time_stamp) - { - return true; - } - break; - case E_SORT_DEV: - if(m_devgId >= info->m_devgId) - { - return true; - } - break; - case E_SORT_TYPE: - if(m_fileType >= info->m_fileType) - { - return true; - } - break; - default: - break; - } - return false; -} - -quint64 CRobotFileInfo::getTime(const QString time) -{ - QString strTime = time; - strTime.insert(12,":"); - strTime.insert(10,":"); - strTime.insert(8," "); - strTime.insert(6,"-"); - strTime.insert(4,"-"); - strTime = strTime.mid(0,19); - LOGINFO("时间:[%s]",strTime.toStdString().c_str()); - QDateTime dateTime; - return dateTime.fromString(strTime,"yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); -} - -int CRobotFileInfo::initialize(const QFileInfo fileInfo) -{ - QString filePath = fileInfo.absoluteFilePath(); - QString path = fileInfo.absolutePath(); - m_execPath = filePath; - m_filePath = path; // 缺少文件名 - m_fileName = filePath.remove(0,path.length()+1); - // .at(0)--- 设备点位 .at(1)--- 机器人编码 .at(2)--- xxxxxxxxxxxxxx.jpg 或 xxxxxxxxxxxxxx.mp4 - QStringList list = m_fileName.split("_"); - if(list.size() != 3) - { - LOGERROR("文件[%s]命名格式有误!",m_fileName.toStdString().c_str()); - return kbdFailed; - } - QString devInt = list.at(0); - m_devgId = devInt.toInt(); - - QString time = list.at(2); - // .at(0)--- 时间 .at(1)--- jpg 或 mp4 - QStringList timeList = time.split("."); - if(timeList.size() == 2) - { - if(timeList.at(1) == "jpg") - { - m_fileType = E_ROBOT_CCD; - }else if(QString(timeList.at(1)) == "mp4") - { - m_fileType = E_ROBOT_VIDEO; - }else - { - LOGERROR("文件[%s]后缀格式有误!",m_fileName.toStdString().c_str()); - return kbdFailed; - } - }else if(timeList.size() == 3) - { - if(timeList.at(2) == "jpg") - { - m_fileType = E_ROBOT_CUT_CCD; - }else - { - LOGERROR("文件[%s]后缀格式有误!",m_fileName.toStdString().c_str()); - return kbdFailed; - } - }else - { - LOGERROR("文件[%s]命名格式有误!",m_fileName.toStdString().c_str()); - return kbdFailed; - } - time_stamp = getTime(timeList.at(0)); - return kbdSuccess; -} - -CRobotInfo::CRobotInfo() -{ - m_tagName = QString(); - m_sub = -1; - m_status = -1; - m_domain =-1; - m_location = -1; -} - -CRobotInfo::CRobotInfo(const CRobotInfo &other) -{ - m_tagName = other.m_tagName; - m_sub = other.m_sub; - m_status = other.m_status; - m_domain =other.m_domain; - m_location = other.m_location; -} - -void CRobotInfo::initialize(const QString &tag_name,int sub,int location,int status) -{ - m_tagName = tag_name; - m_sub = sub; - m_status = status; - m_location = location; -} +#include "CRobotFileInfo.h" +#include "QFileInfo" +#include "pub_logger_api/logger.h" +#include "Common.h" +#include + +CRobotFileInfo::CRobotFileInfo() +{ + m_filePath = QString(); + m_fileName = QString(); + m_fileType = E_ROBOT_CCD; + m_devgId = -1; + m_devgName = QString(); + time_stamp = 0; + +} + +CRobotFileInfo::CRobotFileInfo(const CRobotFileInfo &other) +{ + m_filePath = other.m_filePath; + m_fileName = other.m_fileName; + m_fileType = other.m_fileType; + m_devgId = other.m_devgId; + m_devgName = other.m_devgName; + time_stamp = other.time_stamp; +} + +bool CRobotFileInfo::lessThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_TIME: + if(time_stamp time_stamp) + { + return true; + } + break; + case E_SORT_DEV: + if(m_devgId m_devgId) + { + return true; + } + break; + case E_SORT_TYPE: + if(m_fileType < info->m_fileType) + { + return true; + } + break; + default: + break; + } + return false; +} + +bool CRobotFileInfo::moreThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_TIME: + if(time_stamp >= info->time_stamp) + { + return true; + } + break; + case E_SORT_DEV: + if(m_devgId >= info->m_devgId) + { + return true; + } + break; + case E_SORT_TYPE: + if(m_fileType >= info->m_fileType) + { + return true; + } + break; + default: + break; + } + return false; +} + +quint64 CRobotFileInfo::getTime(const QString time) +{ + QString strTime = time; + strTime.insert(12,":"); + strTime.insert(10,":"); + strTime.insert(8," "); + strTime.insert(6,"-"); + strTime.insert(4,"-"); + strTime = strTime.mid(0,19); + LOGINFO("时间:[%s]",strTime.toStdString().c_str()); + QDateTime dateTime; + return dateTime.fromString(strTime,"yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); +} + +int CRobotFileInfo::initialize(const QFileInfo fileInfo) +{ + QString filePath = fileInfo.absoluteFilePath(); + QString path = fileInfo.absolutePath(); + m_execPath = filePath; + m_filePath = path; // 缺少文件名 + m_fileName = filePath.remove(0,path.length()+1); + // .at(0)--- 设备点位 .at(1)--- 机器人编码 .at(2)--- xxxxxxxxxxxxxx.jpg 或 xxxxxxxxxxxxxx.mp4 + QStringList list = m_fileName.split("_"); + if(list.size() != 3) + { + LOGERROR("文件[%s]命名格式有误!",m_fileName.toStdString().c_str()); + return kbdFailed; + } + QString devInt = list.at(0); + m_devgId = devInt.toInt(); + + QString time = list.at(2); + // .at(0)--- 时间 .at(1)--- jpg 或 mp4 + QStringList timeList = time.split("."); + if(timeList.size() == 2) + { + if(timeList.at(1) == "jpg") + { + m_fileType = E_ROBOT_CCD; + }else if(QString(timeList.at(1)) == "mp4") + { + m_fileType = E_ROBOT_VIDEO; + }else + { + LOGERROR("文件[%s]后缀格式有误!",m_fileName.toStdString().c_str()); + return kbdFailed; + } + }else if(timeList.size() == 3) + { + if(timeList.at(2) == "jpg") + { + m_fileType = E_ROBOT_CUT_CCD; + }else + { + LOGERROR("文件[%s]后缀格式有误!",m_fileName.toStdString().c_str()); + return kbdFailed; + } + }else + { + LOGERROR("文件[%s]命名格式有误!",m_fileName.toStdString().c_str()); + return kbdFailed; + } + time_stamp = getTime(timeList.at(0)); + return kbdSuccess; +} + +CRobotInfo::CRobotInfo() +{ + m_tagName = QString(); + m_sub = -1; + m_status = -1; + m_domain =-1; + m_location = -1; +} + +CRobotInfo::CRobotInfo(const CRobotInfo &other) +{ + m_tagName = other.m_tagName; + m_sub = other.m_sub; + m_status = other.m_status; + m_domain =other.m_domain; + m_location = other.m_location; +} + +void CRobotInfo::initialize(const QString &tag_name,int sub,int location,int status) +{ + m_tagName = tag_name; + m_sub = sub; + m_status = status; + m_location = location; +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileInfo.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileInfo.h index 4e3fc38f..7497eff4 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileInfo.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileInfo.h @@ -1,42 +1,42 @@ -#ifndef CROBOTFILEINFO_H -#define CROBOTFILEINFO_H - -#include - -#include "CRobotCommon.h" -class QFileInfo; -class CRobotFileInfo -{ -public: - CRobotFileInfo(); - CRobotFileInfo(const CRobotFileInfo &other); - bool lessThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey = E_SORT_TYPE); - bool moreThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey = E_SORT_TYPE); - quint64 getTime(const QString time); - int initialize(const QFileInfo fileInfo); - QString m_execPath; //<执行路径 - QString m_filePath; //<文件路径 - QString m_fileName; //<文件名 - int m_devgId; //<设备id - QString m_devgName; //<设备组名 - E_ROBOT_FILE_TYPE m_fileType; //<文件类型 - quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) - -}; - -class CRobotInfo -{ -public: - CRobotInfo(); - CRobotInfo(const CRobotInfo &other); - void initialize(const QString &tag_name, int sub, int location, int status); - -public: - QString m_tagName; - int m_sub; - int m_domain; - int m_location; - int m_status; -}; - -#endif // CROBOTFILEINFO_H +#ifndef CROBOTFILEINFO_H +#define CROBOTFILEINFO_H + +#include + +#include "CRobotCommon.h" +class QFileInfo; +class CRobotFileInfo +{ +public: + CRobotFileInfo(); + CRobotFileInfo(const CRobotFileInfo &other); + bool lessThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey = E_SORT_TYPE); + bool moreThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey = E_SORT_TYPE); + quint64 getTime(const QString time); + int initialize(const QFileInfo fileInfo); + QString m_execPath; //<执行路径 + QString m_filePath; //<文件路径 + QString m_fileName; //<文件名 + int m_devgId; //<设备id + QString m_devgName; //<设备组名 + E_ROBOT_FILE_TYPE m_fileType; //<文件类型 + quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) + +}; + +class CRobotInfo +{ +public: + CRobotInfo(); + CRobotInfo(const CRobotInfo &other); + void initialize(const QString &tag_name, int sub, int location, int status); + +public: + QString m_tagName; + int m_sub; + int m_domain; + int m_location; + int m_status; +}; + +#endif // CROBOTFILEINFO_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileMng.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileMng.cpp index 0bebcaec..e38e4111 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileMng.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileMng.cpp @@ -1,65 +1,65 @@ -#include "CRobotFileMng.h" - -CRobotFileMng::CRobotFileMng(QObject *parent): - QObject(parent) -{ - -} - -CRobotFileMng::~CRobotFileMng() -{ - m_all.clear(); -} - -void CRobotFileMng::slotUpdateFile(const QMap map) -{ - if(m_all.size() <= 0) - { - m_all = map; - - emit sigMsgAdd(m_all.values()); - }else - { - QList listAdd; - QList listSub; - judge(map,listAdd,listSub); - if(listAdd.size() > 0) - { - foreach (RobotFilePtr ptr, listAdd) { - m_all.insert(ptr->m_execPath,ptr); - } - emit sigMsgAdd(listAdd); - } - if(listSub.size() > 0) - { - foreach (RobotFilePtr ptr, listSub) { - m_all.erase(m_all.find(ptr->m_execPath)); - } - emit sigMsgSub(listSub); - } - listAdd.clear(); - listSub.clear(); - } -} - -void CRobotFileMng::slotAllMsgAdd() -{ - emit sigMsgAdd(m_all.values()); -} - -void CRobotFileMng::judge(const QMap &map, QList &listAdd, QList &listSub) -{ - foreach (RobotFilePtr ptr, map.values()) { - if(!m_all.keys().contains(ptr->m_execPath)) - { - listAdd.append(ptr); - } - } - foreach (RobotFilePtr ptr, m_all.values()) { - if(!map.keys().contains(ptr->m_execPath)) - { - listSub.append(ptr); - } - } -} - +#include "CRobotFileMng.h" + +CRobotFileMng::CRobotFileMng(QObject *parent): + QObject(parent) +{ + +} + +CRobotFileMng::~CRobotFileMng() +{ + m_all.clear(); +} + +void CRobotFileMng::slotUpdateFile(const QMap map) +{ + if(m_all.size() <= 0) + { + m_all = map; + + emit sigMsgAdd(m_all.values()); + }else + { + QList listAdd; + QList listSub; + judge(map,listAdd,listSub); + if(listAdd.size() > 0) + { + foreach (RobotFilePtr ptr, listAdd) { + m_all.insert(ptr->m_execPath,ptr); + } + emit sigMsgAdd(listAdd); + } + if(listSub.size() > 0) + { + foreach (RobotFilePtr ptr, listSub) { + m_all.erase(m_all.find(ptr->m_execPath)); + } + emit sigMsgSub(listSub); + } + listAdd.clear(); + listSub.clear(); + } +} + +void CRobotFileMng::slotAllMsgAdd() +{ + emit sigMsgAdd(m_all.values()); +} + +void CRobotFileMng::judge(const QMap &map, QList &listAdd, QList &listSub) +{ + foreach (RobotFilePtr ptr, map.values()) { + if(!m_all.keys().contains(ptr->m_execPath)) + { + listAdd.append(ptr); + } + } + foreach (RobotFilePtr ptr, m_all.values()) { + if(!map.keys().contains(ptr->m_execPath)) + { + listSub.append(ptr); + } + } +} + diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileMng.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileMng.h index de5887a7..f09466b8 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotFileMng.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotFileMng.h @@ -1,37 +1,37 @@ -#ifndef CROBOTFILEMNG_H -#define CROBOTFILEMNG_H - -#include -#include -#include -class CRobotFileMng : public QObject -{ - Q_OBJECT -public: - CRobotFileMng(QObject *parent = nullptr); - - ~CRobotFileMng(); - -signals: - /** - * @brief sigMsgAdd 通知模型添加数据 - * @param list - */ - void sigMsgAdd(const QList list); - /** - * @brief sigMsgSub 通知模型删除数据 - * @param list - */ - void sigMsgSub(const QList list); -public slots: - void slotUpdateFile(const QMap map); - void slotAllMsgAdd(); -private: - void judge(const QMap& map,QList &listAdd,QList &listSub); -private: - QMap m_all; - - -}; - -#endif // CROBOTFILEMNG_H +#ifndef CROBOTFILEMNG_H +#define CROBOTFILEMNG_H + +#include +#include +#include +class CRobotFileMng : public QObject +{ + Q_OBJECT +public: + CRobotFileMng(QObject *parent = nullptr); + + ~CRobotFileMng(); + +signals: + /** + * @brief sigMsgAdd 通知模型添加数据 + * @param list + */ + void sigMsgAdd(const QList list); + /** + * @brief sigMsgSub 通知模型删除数据 + * @param list + */ + void sigMsgSub(const QList list); +public slots: + void slotUpdateFile(const QMap map); + void slotAllMsgAdd(); +private: + void judge(const QMap& map,QList &listAdd,QList &listSub); +private: + QMap m_all; + + +}; + +#endif // CROBOTFILEMNG_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.cpp index 72734903..7b5f7702 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.cpp @@ -1,25 +1,25 @@ -#include "CRobotPluginWidget.h" -#include "CRobotWidget.h" -#include -CRobotPluginWidget::CRobotPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CRobotPluginWidget::~CRobotPluginWidget() -{ - -} - -bool CRobotPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec) -{ - CRobotWidget *pWidget = new CRobotWidget(editMode,parent); - *widget = (QWidget *)pWidget; - *pluginWidget = (IPluginWidget *)pWidget; - return true; -} - -void CRobotPluginWidget::release() -{ - -} +#include "CRobotPluginWidget.h" +#include "CRobotWidget.h" +#include +CRobotPluginWidget::CRobotPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CRobotPluginWidget::~CRobotPluginWidget() +{ + +} + +bool CRobotPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec) +{ + CRobotWidget *pWidget = new CRobotWidget(editMode,parent); + *widget = (QWidget *)pWidget; + *pluginWidget = (IPluginWidget *)pWidget; + return true; +} + +void CRobotPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.h index 2ff38df5..2f2a30f8 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.h @@ -1,19 +1,19 @@ -#ifndef CROBOTPLUGINWIDGET_H -#define CROBOTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CRobotPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CRobotPluginWidget(QObject *parent = nullptr); - ~CRobotPluginWidget(); - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec); - void release(); -}; - -#endif // CROBOTPLUGINWIDGET_H +#ifndef CROBOTPLUGINWIDGET_H +#define CROBOTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CRobotPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CRobotPluginWidget(QObject *parent = nullptr); + ~CRobotPluginWidget(); + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec); + void release(); +}; + +#endif // CROBOTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.cpp b/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.cpp index 57eb0655..c0eb80b0 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.cpp @@ -1,95 +1,95 @@ -#include "CRobotWidget.h" -#include "ui_CRobotWidget.h" -#include "CRobotCCDVideoForm.h" -#include "CRobotAVWidget.h" -#include "CRobotCtrlWidget.h" -#include "CRobotCCDVideoItemModel.h" -#include -#include "CRobotFileCollect.h" -#include "CRobotFileMng.h" -#include -#include -#include -#include -#include -#include -#include "CRobotDialog.h" -#include "pub_utility_api/FileStyle.h" - -CRobotWidget::CRobotWidget(bool editMode, QWidget *parent) : - QWidget(parent), - m_bEditMode(editMode), - m_ctrlWidget(Q_NULLPTR), - m_location(-1), - ui(new Ui::CRobotWidget) -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("robot.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - ui->setupUi(this); - qRegisterMetaType< QList >("QList"); - qRegisterMetaType >("QMap"); - initView(); - connect(ui->pushButton,&QPushButton::clicked,this,&CRobotWidget::openRobotDialog); - ui->pushButton->setHidden(true); -} - -CRobotWidget::~CRobotWidget() -{ - delete ui; -} - -void CRobotWidget::initView() -{ - QGridLayout *ctrlLay = new QGridLayout(ui->ctrlWidget); - m_ctrlWidget = new CRobotCtrlWidget(this); - ctrlLay->addWidget(m_ctrlWidget); -} - -void CRobotWidget::openRobotDialog() -{ - CRobotDialog dialog(false,this); - dialog.initialize(m_ctrlWidget->getDiMap()); - dialog.exec(); -} - -void CRobotWidget::initialize(int domain, int location) -{ - m_location = location; - m_ctrlWidget->initialize(domain,location); - -} - -void CRobotWidget::setHiddenButton(bool hide) -{ - ui->pushButton->setHidden(hide); - -} - -void CRobotWidget::setButtonText(QString text) -{ - ui->pushButton->setText(text); -} - +#include "CRobotWidget.h" +#include "ui_CRobotWidget.h" +#include "CRobotCCDVideoForm.h" +#include "CRobotAVWidget.h" +#include "CRobotCtrlWidget.h" +#include "CRobotCCDVideoItemModel.h" +#include +#include "CRobotFileCollect.h" +#include "CRobotFileMng.h" +#include +#include +#include +#include +#include +#include +#include "CRobotDialog.h" +#include "pub_utility_api/FileStyle.h" + +CRobotWidget::CRobotWidget(bool editMode, QWidget *parent) : + QWidget(parent), + m_bEditMode(editMode), + m_ctrlWidget(Q_NULLPTR), + m_location(-1), + ui(new Ui::CRobotWidget) +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("robot.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + ui->setupUi(this); + qRegisterMetaType< QList >("QList"); + qRegisterMetaType >("QMap"); + initView(); + connect(ui->pushButton,&QPushButton::clicked,this,&CRobotWidget::openRobotDialog); + ui->pushButton->setHidden(true); +} + +CRobotWidget::~CRobotWidget() +{ + delete ui; +} + +void CRobotWidget::initView() +{ + QGridLayout *ctrlLay = new QGridLayout(ui->ctrlWidget); + m_ctrlWidget = new CRobotCtrlWidget(this); + ctrlLay->addWidget(m_ctrlWidget); +} + +void CRobotWidget::openRobotDialog() +{ + CRobotDialog dialog(false,this); + dialog.initialize(m_ctrlWidget->getDiMap()); + dialog.exec(); +} + +void CRobotWidget::initialize(int domain, int location) +{ + m_location = location; + m_ctrlWidget->initialize(domain,location); + +} + +void CRobotWidget::setHiddenButton(bool hide) +{ + ui->pushButton->setHidden(hide); + +} + +void CRobotWidget::setButtonText(QString text) +{ + ui->pushButton->setText(text); +} + diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.h index 922baa75..a0e18935 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.h @@ -1,51 +1,51 @@ -#ifndef CROBOTLINKCTRLWIDGET_H -#define CROBOTLINKCTRLWIDGET_H - -#include -class CRobotCCDVideoForm; -class CRobotAVWidget; -class CRobotCtrlWidget; -class CRobotCCDVideoItemModel; -class QThread; -class CRobotFileCollect; -class CRobotFileMng; -namespace Ui { -class CRobotWidget; -} - -class CRobotWidget : public QWidget -{ - Q_OBJECT - -public: - CRobotWidget(bool editMode, QWidget *parent = 0); - ~CRobotWidget(); - -public slots: - - /** - * @brief initialize 初始化 - * @param domain 域id -1代表所有域 (当域为-1时,车站无效) - * @param location 车站 id -1代表所有车站 - */ - void initialize(int domain = -1,int location = -1); - - void setHiddenButton(bool hide); - - void setButtonText(QString text); - -private: - void initView(); - -private slots: - void openRobotDialog(); - -private: - Ui::CRobotWidget *ui; -private: - CRobotCtrlWidget * m_ctrlWidget; - int m_location; - bool m_bEditMode; -}; - -#endif // CROBOTLINKCTRLWIDGET_H +#ifndef CROBOTLINKCTRLWIDGET_H +#define CROBOTLINKCTRLWIDGET_H + +#include +class CRobotCCDVideoForm; +class CRobotAVWidget; +class CRobotCtrlWidget; +class CRobotCCDVideoItemModel; +class QThread; +class CRobotFileCollect; +class CRobotFileMng; +namespace Ui { +class CRobotWidget; +} + +class CRobotWidget : public QWidget +{ + Q_OBJECT + +public: + CRobotWidget(bool editMode, QWidget *parent = 0); + ~CRobotWidget(); + +public slots: + + /** + * @brief initialize 初始化 + * @param domain 域id -1代表所有域 (当域为-1时,车站无效) + * @param location 车站 id -1代表所有车站 + */ + void initialize(int domain = -1,int location = -1); + + void setHiddenButton(bool hide); + + void setButtonText(QString text); + +private: + void initView(); + +private slots: + void openRobotDialog(); + +private: + Ui::CRobotWidget *ui; +private: + CRobotCtrlWidget * m_ctrlWidget; + int m_location; + bool m_bEditMode; +}; + +#endif // CROBOTLINKCTRLWIDGET_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.ui b/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.ui index 1ffa8303..20934d03 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.ui +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotWidget.ui @@ -1,75 +1,75 @@ - - - CRobotWidget - - - - 0 - 0 - 259 - 715 - - - - CRobotLinkCtrlWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - 239 - 0 - - - - - 239 - 16777215 - - - - - - - - - - - - - - - - - - - - + + + CRobotWidget + + + + 0 + 0 + 259 + 715 + + + + CRobotLinkCtrlWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 239 + 0 + + + + + 239 + 16777215 + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/RobotCtrlWidget/Label.cpp b/product/src/gui/plugin/RobotCtrlWidget/Label.cpp index e1d3543d..6a90966d 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/Label.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/Label.cpp @@ -1,29 +1,29 @@ -#include "Label.h" -#include -#include -Label::Label(QWidget *parent): - QLabel(parent) -{ - -} - -void Label::contextMenuEvent(QContextMenuEvent *event) -{ - QMenu menu(this); - QAction * openAction = menu.addAction(tr("打开")); - connect(openAction,&QAction::triggered,[=](){ - QString file = QFileDialog::getOpenFileName(0, tr("打开"),"/","JPEG Files(*.jpg);;MP4 Files(*.mp4)"); - if (file.isEmpty()) - return; - QStringList list = file.split("."); - if(list.at(list.size()-1) == "mp4") - { - emit avPlay(file); - }else if(list.at(list.size()-1) == "jpg") - { - emit ccdPlay(file); - } - }); - menu.exec(QCursor::pos()); - QWidget::contextMenuEvent(event); -} +#include "Label.h" +#include +#include +Label::Label(QWidget *parent): + QLabel(parent) +{ + +} + +void Label::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu(this); + QAction * openAction = menu.addAction(tr("打开")); + connect(openAction,&QAction::triggered,[=](){ + QString file = QFileDialog::getOpenFileName(0, tr("打开"),"/","JPEG Files(*.jpg);;MP4 Files(*.mp4)"); + if (file.isEmpty()) + return; + QStringList list = file.split("."); + if(list.at(list.size()-1) == "mp4") + { + emit avPlay(file); + }else if(list.at(list.size()-1) == "jpg") + { + emit ccdPlay(file); + } + }); + menu.exec(QCursor::pos()); + QWidget::contextMenuEvent(event); +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/Label.h b/product/src/gui/plugin/RobotCtrlWidget/Label.h index 9ade896b..5e1b5dc4 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/Label.h +++ b/product/src/gui/plugin/RobotCtrlWidget/Label.h @@ -1,17 +1,17 @@ -#ifndef LABEL_H -#define LABEL_H - -#include -class Label : public QLabel -{ - Q_OBJECT -public: - Label(QWidget *parent = 0); -signals: - void avPlay(QString file); - void ccdPlay(QString file); -protected: - virtual void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // LABEL_H +#ifndef LABEL_H +#define LABEL_H + +#include +class Label : public QLabel +{ + Q_OBJECT +public: + Label(QWidget *parent = 0); +signals: + void avPlay(QString file); + void ccdPlay(QString file); +protected: + virtual void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // LABEL_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/OnTimeQueryThread.cpp b/product/src/gui/plugin/RobotCtrlWidget/OnTimeQueryThread.cpp index b5209a9d..51cb5f55 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/OnTimeQueryThread.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/OnTimeQueryThread.cpp @@ -1,80 +1,80 @@ -#include "OnTimeQueryThread.h" -#include "pub_logger_api/logger.h" -#include -using namespace std; -OnTimeQueryThread::OnTimeQueryThread(QObject *parent) : QObject(parent) -{ - m_outTimeCount = 0; - m_timer = new QTimer(); - m_timer->setInterval(3000); - connect(m_timer,&QTimer::timeout,this,&OnTimeQueryThread::slotQuery); - m_mutex = new QMutex; -} - -OnTimeQueryThread::~OnTimeQueryThread() -{ - if(m_timer) - { - m_timer->stop(); - m_timer->deleteLater(); - } -} - -int OnTimeQueryThread::getStatus(const QString &tag) -{ - QMutexLocker lock(m_mutex); - return m_infoMap.value(tag,1); -} - -void OnTimeQueryThread::init(QMap infoMap) -{ - m_map = infoMap; - m_timer->start(); -} - -void OnTimeQueryThread::slotQuery() -{ - //查询机器人状态 - string table = "analog"; - QMap::iterator it = m_map.begin(); - while (it != m_map.end()) { - vector vecKey; - vecKey.push_back(it.key().toStdString()); - std::vector vecColumn; - vecColumn.push_back("value"); - kbd_idlfile::RdbRet objRet; - rdb_net_api.connect(it.value()->m_domain,it.value()->m_sub); - if(m_outTimeCount > 20) - { - LOGERROR("机器人状态查询出错超过%d次,停止查询!",m_outTimeCount); - m_timer->stop(); - } - if(rdb_net_api.queryByKey(table,vecKey,vecColumn,objRet)) - { - if(objRet.msgrecord(0).msgvaluearray_size() != 1) - { - m_outTimeCount++; - LOGERROR("机器人[%s]状态查询出错!",it.key().toStdString().c_str()); - break; - }else - { - m_outTimeCount = 0; - it.value()->m_status = objRet.msgrecord(0).msgvaluearray(0).dvalue(); - } - //qDebug()<<"type:"<::iterator pos = m_map.begin(); - while (pos != m_map.end()) { - m_infoMap[pos.key()] = pos.value()->m_status; - pos++; - } -} +#include "OnTimeQueryThread.h" +#include "pub_logger_api/logger.h" +#include +using namespace std; +OnTimeQueryThread::OnTimeQueryThread(QObject *parent) : QObject(parent) +{ + m_outTimeCount = 0; + m_timer = new QTimer(); + m_timer->setInterval(3000); + connect(m_timer,&QTimer::timeout,this,&OnTimeQueryThread::slotQuery); + m_mutex = new QMutex; +} + +OnTimeQueryThread::~OnTimeQueryThread() +{ + if(m_timer) + { + m_timer->stop(); + m_timer->deleteLater(); + } +} + +int OnTimeQueryThread::getStatus(const QString &tag) +{ + QMutexLocker lock(m_mutex); + return m_infoMap.value(tag,1); +} + +void OnTimeQueryThread::init(QMap infoMap) +{ + m_map = infoMap; + m_timer->start(); +} + +void OnTimeQueryThread::slotQuery() +{ + //查询机器人状态 + string table = "analog"; + QMap::iterator it = m_map.begin(); + while (it != m_map.end()) { + vector vecKey; + vecKey.push_back(it.key().toStdString()); + std::vector vecColumn; + vecColumn.push_back("value"); + kbd_idlfile::RdbRet objRet; + rdb_net_api.connect(it.value()->m_domain,it.value()->m_sub); + if(m_outTimeCount > 20) + { + LOGERROR("机器人状态查询出错超过%d次,停止查询!",m_outTimeCount); + m_timer->stop(); + } + if(rdb_net_api.queryByKey(table,vecKey,vecColumn,objRet)) + { + if(objRet.msgrecord(0).msgvaluearray_size() != 1) + { + m_outTimeCount++; + LOGERROR("机器人[%s]状态查询出错!",it.key().toStdString().c_str()); + break; + }else + { + m_outTimeCount = 0; + it.value()->m_status = objRet.msgrecord(0).msgvaluearray(0).dvalue(); + } + //qDebug()<<"type:"<::iterator pos = m_map.begin(); + while (pos != m_map.end()) { + m_infoMap[pos.key()] = pos.value()->m_status; + pos++; + } +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/OnTimeQueryThread.h b/product/src/gui/plugin/RobotCtrlWidget/OnTimeQueryThread.h index afdd43af..33af2bb6 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/OnTimeQueryThread.h +++ b/product/src/gui/plugin/RobotCtrlWidget/OnTimeQueryThread.h @@ -1,32 +1,32 @@ -#ifndef ONTIMEQUERYTHREAD_H -#define ONTIMEQUERYTHREAD_H - -#include -#include "CRobotFileInfo.h" -#include -#include -#include "rdb_net_api/CRdbNetApi.h" -#include -class OnTimeQueryThread : public QObject -{ - Q_OBJECT -public: - explicit OnTimeQueryThread(QObject *parent = nullptr); - ~OnTimeQueryThread(); - int getStatus(const QString &tag); -public: - void init(QMap infoMap); -signals: - -public slots: - void slotQuery(); -private: - QMap m_map; - QTimer *m_timer; - kbd_dbms::CRdbNetApi rdb_net_api; - QMap m_infoMap; - QMutex *m_mutex; - int m_outTimeCount; -}; - -#endif // ONTIMEQUERYTHREAD_H +#ifndef ONTIMEQUERYTHREAD_H +#define ONTIMEQUERYTHREAD_H + +#include +#include "CRobotFileInfo.h" +#include +#include +#include "rdb_net_api/CRdbNetApi.h" +#include +class OnTimeQueryThread : public QObject +{ + Q_OBJECT +public: + explicit OnTimeQueryThread(QObject *parent = nullptr); + ~OnTimeQueryThread(); + int getStatus(const QString &tag); +public: + void init(QMap infoMap); +signals: + +public slots: + void slotQuery(); +private: + QMap m_map; + QTimer *m_timer; + kbd_dbms::CRdbNetApi rdb_net_api; + QMap m_infoMap; + QMutex *m_mutex; + int m_outTimeCount; +}; + +#endif // ONTIMEQUERYTHREAD_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/Renderer.cpp b/product/src/gui/plugin/RobotCtrlWidget/Renderer.cpp index cdd1f7e5..593e1d31 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/Renderer.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/Renderer.cpp @@ -1,38 +1,38 @@ -#include "Renderer.h" -#include -#include -Renderer::Renderer(QWidget *parent): - WidgetRenderer(parent) -{ - -} - -void Renderer::mouseReleaseEvent(QMouseEvent *event) -{ - if(event->button() == Qt::LeftButton) - { - emit click(); - } - QWidget::mouseReleaseEvent(event); -} - -void Renderer::contextMenuEvent(QContextMenuEvent *event) -{ - QMenu menu(this); - QAction * openAction = menu.addAction(tr("打开")); - connect(openAction,&QAction::triggered,[=](){ - QString file = QFileDialog::getOpenFileName(0, tr("打开"),"/","JPEG Files(*.jpg);;MP4 Files(*.mp4)"); - if (file.isEmpty()) - return; - QStringList list = file.split("."); - if(list.at(list.size()-1) == "mp4") - { - emit avPlay(file); - }else if(list.at(list.size()-1) == "jpg") - { - emit ccdPlay(file); - } - }); - menu.exec(QCursor::pos()); - QWidget::contextMenuEvent(event); -} +#include "Renderer.h" +#include +#include +Renderer::Renderer(QWidget *parent): + WidgetRenderer(parent) +{ + +} + +void Renderer::mouseReleaseEvent(QMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + emit click(); + } + QWidget::mouseReleaseEvent(event); +} + +void Renderer::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu(this); + QAction * openAction = menu.addAction(tr("打开")); + connect(openAction,&QAction::triggered,[=](){ + QString file = QFileDialog::getOpenFileName(0, tr("打开"),"/","JPEG Files(*.jpg);;MP4 Files(*.mp4)"); + if (file.isEmpty()) + return; + QStringList list = file.split("."); + if(list.at(list.size()-1) == "mp4") + { + emit avPlay(file); + }else if(list.at(list.size()-1) == "jpg") + { + emit ccdPlay(file); + } + }); + menu.exec(QCursor::pos()); + QWidget::contextMenuEvent(event); +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/Renderer.h b/product/src/gui/plugin/RobotCtrlWidget/Renderer.h index 869d4400..86d2a2ef 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/Renderer.h +++ b/product/src/gui/plugin/RobotCtrlWidget/Renderer.h @@ -1,22 +1,22 @@ -#ifndef RENDERER_H -#define RENDERER_H -#include -#include -#include - -class Renderer :public QtAV::WidgetRenderer -{ - Q_OBJECT -public: - Renderer(QWidget *parent = 0); -signals: - void click(); - - void ccdPlay(QString file); - void avPlay(QString file); -protected: - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // RENDERER_H +#ifndef RENDERER_H +#define RENDERER_H +#include +#include +#include + +class Renderer :public QtAV::WidgetRenderer +{ + Q_OBJECT +public: + Renderer(QWidget *parent = 0); +signals: + void click(); + + void ccdPlay(QString file); + void avPlay(QString file); +protected: + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // RENDERER_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/RobotCtrlWidget.pro b/product/src/gui/plugin/RobotCtrlWidget/RobotCtrlWidget.pro index e2575fa9..e46df814 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/RobotCtrlWidget.pro +++ b/product/src/gui/plugin/RobotCtrlWidget/RobotCtrlWidget.pro @@ -1,116 +1,116 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-02-12T08:50:48 -# -#------------------------------------------------- - -QT += core sql printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -TEMPLATE = lib -TARGET = RobotCtrlWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -INCLUDEPATH += $$PWD \ - $$PWD/../../../3rd/include/QTAV/ \ - $$PWD/../../../3rd/include/QtAVWidgets/ \ - - -win32-msvc* { - -CONFIG(debug, debug|release) { - LIBS += -lQtAVd1 -lQtAVWidgetsd1 -} -CONFIG(release, debug|release) { - LIBS += -lQtAV1 -lQtAVWidgets1 -} -} - - -linux-g++*{ - LIBS += -lQtAV -lQtAVWidgets -} - -LIBS += -llog4cplus -lboost_system -lrdb_net_api -lboost_filesystem -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lpub_sysinfo_api -ldb_sysinfo_api -LIBS += -lnet_msg_bus_api -lboost_system -lboost_chrono -SOURCES += \ - # main.cpp \ - CRobotPluginWidget.cpp \ - CRobotCCDVideoForm.cpp \ - CRobotAVWidget.cpp \ - CRobotCtrlWidget.cpp \ - CRobotCCDVideoView.cpp \ - CRobotFileInfo.cpp \ - CRobotCCDVideoItemModel.cpp \ - SWitchButton.cpp \ - CRobotFileCollect.cpp \ - CRobotFileMng.cpp \ - Slider.cpp \ - Renderer.cpp \ - VoiceSlider.cpp \ - OnTimeQueryThread.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - Label.cpp \ - CRobotWidget.cpp \ - CRobotDialog.cpp - -HEADERS += \ - CRobotPluginWidget.h \ - CRobotCCDVideoForm.h \ - CRobotAVWidget.h \ - CRobotCtrlWidget.h \ - CRobotCCDVideoView.h \ - CRobotFileInfo.h \ - CRobotCCDVideoItemModel.h \ - SWitchButton.h \ - CRobotFileCollect.h \ - CRobotFileMng.h \ - Slider.h \ - Renderer.h \ - VoiceSlider.h \ - OnTimeQueryThread.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - Label.h \ - CRobotCommon.h \ - CRobotWidget.h \ - CRobotDialog.h - -FORMS += \ - CRobotCCDVideoForm.ui \ - CRobotAVWidget.ui \ - CRobotCtrlWidget.ui \ - VoiceSlider.ui \ - CRobotWidget.ui \ - CRobotDialog.ui - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -#必须在common.pri之后包含 -#------------------------------------------------------------------- -QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri -exists($$QTAV_PRI) { - include($$QTAV_PRI) -}else { - error("FATAL error: can not find qtav.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2020-02-12T08:50:48 +# +#------------------------------------------------- + +QT += core sql printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +TEMPLATE = lib +TARGET = RobotCtrlWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +INCLUDEPATH += $$PWD \ + $$PWD/../../../3rd/include/QTAV/ \ + $$PWD/../../../3rd/include/QtAVWidgets/ \ + + +win32-msvc* { + +CONFIG(debug, debug|release) { + LIBS += -lQtAVd1 -lQtAVWidgetsd1 +} +CONFIG(release, debug|release) { + LIBS += -lQtAV1 -lQtAVWidgets1 +} +} + + +linux-g++*{ + LIBS += -lQtAV -lQtAVWidgets +} + +LIBS += -llog4cplus -lboost_system -lrdb_net_api -lboost_filesystem -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lpub_sysinfo_api -ldb_sysinfo_api +LIBS += -lnet_msg_bus_api -lboost_system -lboost_chrono +SOURCES += \ + # main.cpp \ + CRobotPluginWidget.cpp \ + CRobotCCDVideoForm.cpp \ + CRobotAVWidget.cpp \ + CRobotCtrlWidget.cpp \ + CRobotCCDVideoView.cpp \ + CRobotFileInfo.cpp \ + CRobotCCDVideoItemModel.cpp \ + SWitchButton.cpp \ + CRobotFileCollect.cpp \ + CRobotFileMng.cpp \ + Slider.cpp \ + Renderer.cpp \ + VoiceSlider.cpp \ + OnTimeQueryThread.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + Label.cpp \ + CRobotWidget.cpp \ + CRobotDialog.cpp + +HEADERS += \ + CRobotPluginWidget.h \ + CRobotCCDVideoForm.h \ + CRobotAVWidget.h \ + CRobotCtrlWidget.h \ + CRobotCCDVideoView.h \ + CRobotFileInfo.h \ + CRobotCCDVideoItemModel.h \ + SWitchButton.h \ + CRobotFileCollect.h \ + CRobotFileMng.h \ + Slider.h \ + Renderer.h \ + VoiceSlider.h \ + OnTimeQueryThread.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + Label.h \ + CRobotCommon.h \ + CRobotWidget.h \ + CRobotDialog.h + +FORMS += \ + CRobotCCDVideoForm.ui \ + CRobotAVWidget.ui \ + CRobotCtrlWidget.ui \ + VoiceSlider.ui \ + CRobotWidget.ui \ + CRobotDialog.ui + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +#必须在common.pri之后包含 +#------------------------------------------------------------------- +QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri +exists($$QTAV_PRI) { + include($$QTAV_PRI) +}else { + error("FATAL error: can not find qtav.pri") +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/SWitchButton.cpp b/product/src/gui/plugin/RobotCtrlWidget/SWitchButton.cpp index 378f45e5..daa37866 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/SWitchButton.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/SWitchButton.cpp @@ -1,263 +1,263 @@ -#include -#include -#include -#include "SWitchButton.h" -#include -#include "pub_logger_api/logger.h" -#include "common/Common.h" - -using namespace kbd_dbms; - -SWitchButton::SWitchButton(QWidget *parent) - : QWidget(parent), - m_nHeight(12), - m_bChecked(false), - m_radius(8.0), - m_nMargin(3), - m_checkedColor(Qt::red), - m_thumbColor(Qt::white), - m_disabledColor(Qt::darkGray), - m_background(Qt::green), - m_load(Q_NULLPTR) -{ - // 鼠标滑过光标形状 - 手型 - setCursor(Qt::PointingHandCursor); - m_pWirteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); - m_rtdbTable = new kbd_dbms::CRdbAccess(); - m_rtdbTable->open(CN_AppId_BASE, "alarm_link_enable_info"); - // 连接信号槽 - m_load = new QTimer(); - m_load->setInterval(1000); - connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); - connect(m_load,&QTimer::timeout,this,&SWitchButton::loadAlmLink); - m_load->start(); -} - -SWitchButton::~SWitchButton() -{ - if(m_rtdbTable) - { - if(m_rtdbTable->isOpen()) - { - m_rtdbTable->close(); - } - m_rtdbTable = NULL; - delete m_rtdbTable; - } - if(m_load) - { - delete m_load; - m_load = NULL; - } -} - -// 绘制开关 -void SWitchButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter painter(this); - painter.setPen(Qt::NoPen); - painter.setRenderHint(QPainter::Antialiasing); - - QPainterPath path; - QColor background; - QColor thumbColor; - qreal dOpacity; - if (isEnabled()) { // 可用状态 - if (m_bChecked) { // 打开状态 - background = m_checkedColor; - thumbColor = m_checkedColor; - dOpacity = 0.600; - } else { //关闭状态 - background = m_background; - thumbColor = m_background; - dOpacity = 0.800; - } - } else { // 不可用状态 - background = m_disabledColor; - dOpacity = 0.260; - thumbColor = m_disabledColor; - } - // 绘制大椭圆 - painter.setBrush(background); - painter.setOpacity(dOpacity); //透明度 - - path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin, height() - 2 * m_nMargin), m_radius, m_radius); - painter.drawPath(path.simplified()); - - // 绘制小椭圆 - painter.setBrush(thumbColor); - painter.setOpacity(1.0); - painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height())); -} - -// 鼠标按下事件 -void SWitchButton::mousePressEvent(QMouseEvent *event) -{ - if (isEnabled()) { - if (event->buttons() & Qt::LeftButton) { - event->accept(); - } else { - event->ignore(); - } - } -} - -// 鼠标释放事件 - 切换开关状态、发射toggled()信号 -void SWitchButton::mouseReleaseEvent(QMouseEvent *event) -{ - - if (isEnabled()) { - if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { - event->accept(); - //发命令 - //emit sigAlmLinkOpen(!m_bChecked); - almLinkOpen(!m_bChecked); - loadAlmLink(); - m_timer.start(10); - } else { - event->ignore(); - } - } -} - -// 大小改变事件 -void SWitchButton::resizeEvent(QResizeEvent *event) -{ - m_nX = m_nHeight / 2; - m_nY = m_nHeight / 2; - QWidget::resizeEvent(event); -} - -// 默认大小 -QSize SWitchButton::sizeHint() const -{ - return minimumSizeHint(); -} - -// 最小大小 -QSize SWitchButton::minimumSizeHint() const -{ - return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); -} - -// 切换状态 - 滑动 -void SWitchButton::onTimeout() -{ - if (m_bChecked) { - m_nX += 3; - if (m_nX >= width() - height()+ m_nHeight / 2) - { - m_nX = width() - height()+ m_nHeight / 2; - m_timer.stop(); - } - } else { - m_nX -= 3; - if (m_nX <= m_nHeight / 2) - { - m_nX = m_nHeight / 2; - m_timer.stop(); - } - } - update(); -} - -void SWitchButton::almLinkOpen(bool open) -{ - m_pWirteDb->open(); - if(m_pWirteDb->isOpen()) - { - if(open) - { - QString sql = QString("update %1 set enable = %2 where tag_name = '%3'").arg("alarm_link_enable_info").arg(1).arg("ALM_ACT_ROBOT_LINK"); - if(!m_pWirteDb->execute(sql)) - { - QString mess = tr("打开告警联动失败!"); - emit sigCtrlResult(mess); - } - }else - { - QString sql = QString("update %1 set enable = %2 where tag_name = '%3'").arg("alarm_link_enable_info").arg(0).arg("ALM_ACT_ROBOT_LINK"); - if(!m_pWirteDb->execute(sql)) - { - QString mess = tr("关闭告警联动失败!"); - emit sigCtrlResult(mess); - } - } - }else - { - QString mess = tr("数据库连接失败!"); - emit sigCtrlResult(mess); - } - m_pWirteDb->close(); -} - -// 返回开关状态 - 打开:true 关闭:false -bool SWitchButton::isToggled() const -{ - return m_bChecked; -} - -// 设置开关状态 -void SWitchButton::setToggle(bool checked) -{ - m_bChecked = checked; - m_timer.start(10); -} - -// 设置背景颜色 -void SWitchButton::setBackgroundColor(QColor color) -{ - m_background = color; -} - -// 设置选中颜色 -void SWitchButton::setCheckedColor(QColor color) -{ - m_checkedColor = color; -} - -// 设置不可用颜色 -void SWitchButton::setDisbaledColor(QColor color) -{ - m_disabledColor = color; -} - -void SWitchButton::loadAlmLink() -{ - std::vector vecCond; - CRdbPublic::addCondInfo(vecCond, "tag_name", "ALM_ACT_ROBOT_LINK"); - CRdbQueryResult oResult; - std::string sSelectColumn = "enable"; - if(m_rtdbTable->select(vecCond,oResult,sSelectColumn)) - { - if(oResult.getRecordCount() != 1) - { - LOGERROR("查询机器人联动是否启用结果集不等于1,错误!"); - }else - { - CVarType var; - if(oResult.getColumnValue(0,0,var)) - { - m_bChecked = (var.toInt() == 1) ? true :false; - }else - { - LOGERROR("查询机器人联动是否启用取值失败!"); - } - } - }else - { - LOGERROR("查询机器人联动是否启用失败!"); - } - m_timer.start(10); -} - -void SWitchButton::slotSwitchButtonUsed(bool enble, bool open) -{ - setEnabled(enble); - if(enble) - { - setToggle(open); - } -} +#include +#include +#include +#include "SWitchButton.h" +#include +#include "pub_logger_api/logger.h" +#include "common/Common.h" + +using namespace kbd_dbms; + +SWitchButton::SWitchButton(QWidget *parent) + : QWidget(parent), + m_nHeight(12), + m_bChecked(false), + m_radius(8.0), + m_nMargin(3), + m_checkedColor(Qt::red), + m_thumbColor(Qt::white), + m_disabledColor(Qt::darkGray), + m_background(Qt::green), + m_load(Q_NULLPTR) +{ + // 鼠标滑过光标形状 - 手型 + setCursor(Qt::PointingHandCursor); + m_pWirteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); + m_rtdbTable = new kbd_dbms::CRdbAccess(); + m_rtdbTable->open(CN_AppId_BASE, "alarm_link_enable_info"); + // 连接信号槽 + m_load = new QTimer(); + m_load->setInterval(1000); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); + connect(m_load,&QTimer::timeout,this,&SWitchButton::loadAlmLink); + m_load->start(); +} + +SWitchButton::~SWitchButton() +{ + if(m_rtdbTable) + { + if(m_rtdbTable->isOpen()) + { + m_rtdbTable->close(); + } + m_rtdbTable = NULL; + delete m_rtdbTable; + } + if(m_load) + { + delete m_load; + m_load = NULL; + } +} + +// 绘制开关 +void SWitchButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + painter.setPen(Qt::NoPen); + painter.setRenderHint(QPainter::Antialiasing); + + QPainterPath path; + QColor background; + QColor thumbColor; + qreal dOpacity; + if (isEnabled()) { // 可用状态 + if (m_bChecked) { // 打开状态 + background = m_checkedColor; + thumbColor = m_checkedColor; + dOpacity = 0.600; + } else { //关闭状态 + background = m_background; + thumbColor = m_background; + dOpacity = 0.800; + } + } else { // 不可用状态 + background = m_disabledColor; + dOpacity = 0.260; + thumbColor = m_disabledColor; + } + // 绘制大椭圆 + painter.setBrush(background); + painter.setOpacity(dOpacity); //透明度 + + path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin, height() - 2 * m_nMargin), m_radius, m_radius); + painter.drawPath(path.simplified()); + + // 绘制小椭圆 + painter.setBrush(thumbColor); + painter.setOpacity(1.0); + painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height())); +} + +// 鼠标按下事件 +void SWitchButton::mousePressEvent(QMouseEvent *event) +{ + if (isEnabled()) { + if (event->buttons() & Qt::LeftButton) { + event->accept(); + } else { + event->ignore(); + } + } +} + +// 鼠标释放事件 - 切换开关状态、发射toggled()信号 +void SWitchButton::mouseReleaseEvent(QMouseEvent *event) +{ + + if (isEnabled()) { + if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { + event->accept(); + //发命令 + //emit sigAlmLinkOpen(!m_bChecked); + almLinkOpen(!m_bChecked); + loadAlmLink(); + m_timer.start(10); + } else { + event->ignore(); + } + } +} + +// 大小改变事件 +void SWitchButton::resizeEvent(QResizeEvent *event) +{ + m_nX = m_nHeight / 2; + m_nY = m_nHeight / 2; + QWidget::resizeEvent(event); +} + +// 默认大小 +QSize SWitchButton::sizeHint() const +{ + return minimumSizeHint(); +} + +// 最小大小 +QSize SWitchButton::minimumSizeHint() const +{ + return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); +} + +// 切换状态 - 滑动 +void SWitchButton::onTimeout() +{ + if (m_bChecked) { + m_nX += 3; + if (m_nX >= width() - height()+ m_nHeight / 2) + { + m_nX = width() - height()+ m_nHeight / 2; + m_timer.stop(); + } + } else { + m_nX -= 3; + if (m_nX <= m_nHeight / 2) + { + m_nX = m_nHeight / 2; + m_timer.stop(); + } + } + update(); +} + +void SWitchButton::almLinkOpen(bool open) +{ + m_pWirteDb->open(); + if(m_pWirteDb->isOpen()) + { + if(open) + { + QString sql = QString("update %1 set enable = %2 where tag_name = '%3'").arg("alarm_link_enable_info").arg(1).arg("ALM_ACT_ROBOT_LINK"); + if(!m_pWirteDb->execute(sql)) + { + QString mess = tr("打开告警联动失败!"); + emit sigCtrlResult(mess); + } + }else + { + QString sql = QString("update %1 set enable = %2 where tag_name = '%3'").arg("alarm_link_enable_info").arg(0).arg("ALM_ACT_ROBOT_LINK"); + if(!m_pWirteDb->execute(sql)) + { + QString mess = tr("关闭告警联动失败!"); + emit sigCtrlResult(mess); + } + } + }else + { + QString mess = tr("数据库连接失败!"); + emit sigCtrlResult(mess); + } + m_pWirteDb->close(); +} + +// 返回开关状态 - 打开:true 关闭:false +bool SWitchButton::isToggled() const +{ + return m_bChecked; +} + +// 设置开关状态 +void SWitchButton::setToggle(bool checked) +{ + m_bChecked = checked; + m_timer.start(10); +} + +// 设置背景颜色 +void SWitchButton::setBackgroundColor(QColor color) +{ + m_background = color; +} + +// 设置选中颜色 +void SWitchButton::setCheckedColor(QColor color) +{ + m_checkedColor = color; +} + +// 设置不可用颜色 +void SWitchButton::setDisbaledColor(QColor color) +{ + m_disabledColor = color; +} + +void SWitchButton::loadAlmLink() +{ + std::vector vecCond; + CRdbPublic::addCondInfo(vecCond, "tag_name", "ALM_ACT_ROBOT_LINK"); + CRdbQueryResult oResult; + std::string sSelectColumn = "enable"; + if(m_rtdbTable->select(vecCond,oResult,sSelectColumn)) + { + if(oResult.getRecordCount() != 1) + { + LOGERROR("查询机器人联动是否启用结果集不等于1,错误!"); + }else + { + CVarType var; + if(oResult.getColumnValue(0,0,var)) + { + m_bChecked = (var.toInt() == 1) ? true :false; + }else + { + LOGERROR("查询机器人联动是否启用取值失败!"); + } + } + }else + { + LOGERROR("查询机器人联动是否启用失败!"); + } + m_timer.start(10); +} + +void SWitchButton::slotSwitchButtonUsed(bool enble, bool open) +{ + setEnabled(enble); + if(enble) + { + setToggle(open); + } +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/SWitchButton.h b/product/src/gui/plugin/RobotCtrlWidget/SWitchButton.h index c49017f8..0769e099 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/SWitchButton.h +++ b/product/src/gui/plugin/RobotCtrlWidget/SWitchButton.h @@ -1,84 +1,84 @@ -#ifndef SWITCHBUTTON_H -#define SWITCHBUTTON_H - -#include -#include -#include "db_api_ex/CDbApi.h" -#include "dbms/rdb_api/CRdbAccess.h" -class SWitchButton : public QWidget -{ - Q_OBJECT - -public: - explicit SWitchButton(QWidget *parent = 0); - - ~SWitchButton(); - // 返回开关状态 - 打开:true 关闭:false - bool isToggled() const; - - // 设置开关状态 - void setToggle(bool checked); - - // 设置背景颜色 - void setBackgroundColor(QColor color); - - // 设置选中颜色 - void setCheckedColor(QColor color); - - // 设置不可用颜色 - void setDisbaledColor(QColor color); - - void loadAlmLink(); - -signals: - void sigCtrlResult(QString text); -public slots: - void slotSwitchButtonUsed(bool enble,bool open); -protected: - // 绘制开关 - void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - - // 鼠标按下事件 - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // 鼠标释放事件 - 切换开关状态、发射toggled()信号 - void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // 大小改变事件 - void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; - - // 缺省大小 - QSize sizeHint() const Q_DECL_OVERRIDE; - QSize minimumSizeHint() const Q_DECL_OVERRIDE; - -signals: - // 状态改变时,发射信号 - void toggled(bool checked); - - void sigAlmLinkOpen(bool bo); - -private slots: - // 状态切换时,用于产生滑动效果 - void onTimeout(); -private : - void almLinkOpen(bool open); -private: - bool m_bChecked; // 是否选中 - QColor m_background; // 背景颜色 - QColor m_checkedColor; // 选中颜色 - QColor m_disabledColor; // 不可用颜色 - QColor m_thumbColor; // - qreal m_radius; // 圆角 - qreal m_nX{}; // x点坐标 - qreal m_nY{}; // y点坐标 - qint16 m_nHeight; // 高度 - qint16 m_nMargin; // 外边距 - QTimer m_timer; // 定时器 - - QTimer *m_load; - - kbd_dbms::CDbApi * m_pWirteDb; - kbd_dbms::CRdbAccess * m_rtdbTable; -}; - -#endif // SWITCHBUTTON_H +#ifndef SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include +#include +#include "db_api_ex/CDbApi.h" +#include "dbms/rdb_api/CRdbAccess.h" +class SWitchButton : public QWidget +{ + Q_OBJECT + +public: + explicit SWitchButton(QWidget *parent = 0); + + ~SWitchButton(); + // 返回开关状态 - 打开:true 关闭:false + bool isToggled() const; + + // 设置开关状态 + void setToggle(bool checked); + + // 设置背景颜色 + void setBackgroundColor(QColor color); + + // 设置选中颜色 + void setCheckedColor(QColor color); + + // 设置不可用颜色 + void setDisbaledColor(QColor color); + + void loadAlmLink(); + +signals: + void sigCtrlResult(QString text); +public slots: + void slotSwitchButtonUsed(bool enble,bool open); +protected: + // 绘制开关 + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + // 鼠标按下事件 + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 鼠标释放事件 - 切换开关状态、发射toggled()信号 + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 大小改变事件 + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + + // 缺省大小 + QSize sizeHint() const Q_DECL_OVERRIDE; + QSize minimumSizeHint() const Q_DECL_OVERRIDE; + +signals: + // 状态改变时,发射信号 + void toggled(bool checked); + + void sigAlmLinkOpen(bool bo); + +private slots: + // 状态切换时,用于产生滑动效果 + void onTimeout(); +private : + void almLinkOpen(bool open); +private: + bool m_bChecked; // 是否选中 + QColor m_background; // 背景颜色 + QColor m_checkedColor; // 选中颜色 + QColor m_disabledColor; // 不可用颜色 + QColor m_thumbColor; // + qreal m_radius; // 圆角 + qreal m_nX{}; // x点坐标 + qreal m_nY{}; // y点坐标 + qint16 m_nHeight; // 高度 + qint16 m_nMargin; // 外边距 + QTimer m_timer; // 定时器 + + QTimer *m_load; + + kbd_dbms::CDbApi * m_pWirteDb; + kbd_dbms::CRdbAccess * m_rtdbTable; +}; + +#endif // SWITCHBUTTON_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/Slider.cpp b/product/src/gui/plugin/RobotCtrlWidget/Slider.cpp index c2ac87fb..13981231 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/Slider.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/Slider.cpp @@ -1,116 +1,116 @@ -#include "Slider.h" -#include -#include -#include -#include -#include -Slider::Slider(QWidget *parent): - QSlider(parent) -{ - setOrientation(Qt::Horizontal); - setMouseTracking(true); - setWindowOpacity(0.7); -} - -Slider::~Slider() -{ - -} - -void Slider::enterEvent(QEvent *event) -{ - emit onEnter(); - QSlider::enterEvent(event); -} - -void Slider::leaveEvent(QEvent *event) -{ - emit onLeave(); - QSlider::leaveEvent(event); -} - -void Slider::mouseMoveEvent(QMouseEvent *event) -{ - const int o = style()->pixelMetric(QStyle::PM_SliderLength ) - 1; - int v = QStyle::sliderValueFromPosition(minimum(), maximum(), event->pos().x()-o/2, width()-o, false); - emit onHover(event->x(), v); - QSlider::mouseMoveEvent(event); -} - -void Slider::mousePressEvent(QMouseEvent *event) -{ - qDebug("pressed (%d, %d)", event->pos().x(), event->pos().y()); - if (event->button() == Qt::LeftButton) { - QStyleOptionSlider opt; - initStyleOption(&opt); - const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); - const QPoint center = sliderRect.center() - sliderRect.topLeft(); - // to take half of the slider off for the setSliderPosition call we use the center - topLeft - - if (!sliderRect.contains(event->pos())) { - qDebug("accept"); - event->accept(); - - int v = pixelPosToRangeValue(pick(event->pos() - center)); - setSliderPosition(v); - triggerAction(SliderMove); - setRepeatAction(SliderNoAction); - emit sliderMoved(v);//TODO: ok? - emit sliderPressed(); //TODO: ok? - } else { - QSlider::mousePressEvent(event); - } - } else { - QSlider::mousePressEvent(event); - } -} - -int Slider::pick(const QPoint &pt) const -{ - return orientation() == Qt::Horizontal ? pt.x() : pt.y(); -} - -int Slider::pixelPosToRangeValue(int pos) const -{ - QStyleOptionSlider opt; - initStyleOption(&opt); - QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); - QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); - int sliderMin, sliderMax, sliderLength; - if (orientation() == Qt::Horizontal) { - sliderLength = sr.width(); - sliderMin = gr.x(); - sliderMax = gr.right() - sliderLength + 1; - } else { - sliderLength = sr.height(); - sliderMin = gr.y(); - sliderMax = gr.bottom() - sliderLength + 1; - } - return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, - sliderMax - sliderMin, opt.upsideDown); -} - -void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const -{ - if (!option) - return; - - option->initFrom(this); - option->subControls = QStyle::SC_None; - option->activeSubControls = QStyle::SC_None; - option->orientation = orientation(); - option->maximum = maximum(); - option->minimum = minimum(); - option->tickPosition = (QSlider::TickPosition) tickPosition(); - option->tickInterval = tickInterval(); - option->upsideDown = (orientation() == Qt::Horizontal) ? - (invertedAppearance() != (option->direction == Qt::RightToLeft)) - : (!invertedAppearance()); - option->direction = Qt::LeftToRight; // we use the upsideDown option instead - option->sliderPosition = sliderPosition(); - option->sliderValue = value(); - option->singleStep = singleStep(); - option->pageStep = pageStep(); - if (orientation() == Qt::Horizontal) - option->state |= QStyle::State_Horizontal; -} +#include "Slider.h" +#include +#include +#include +#include +#include +Slider::Slider(QWidget *parent): + QSlider(parent) +{ + setOrientation(Qt::Horizontal); + setMouseTracking(true); + setWindowOpacity(0.7); +} + +Slider::~Slider() +{ + +} + +void Slider::enterEvent(QEvent *event) +{ + emit onEnter(); + QSlider::enterEvent(event); +} + +void Slider::leaveEvent(QEvent *event) +{ + emit onLeave(); + QSlider::leaveEvent(event); +} + +void Slider::mouseMoveEvent(QMouseEvent *event) +{ + const int o = style()->pixelMetric(QStyle::PM_SliderLength ) - 1; + int v = QStyle::sliderValueFromPosition(minimum(), maximum(), event->pos().x()-o/2, width()-o, false); + emit onHover(event->x(), v); + QSlider::mouseMoveEvent(event); +} + +void Slider::mousePressEvent(QMouseEvent *event) +{ + qDebug("pressed (%d, %d)", event->pos().x(), event->pos().y()); + if (event->button() == Qt::LeftButton) { + QStyleOptionSlider opt; + initStyleOption(&opt); + const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + const QPoint center = sliderRect.center() - sliderRect.topLeft(); + // to take half of the slider off for the setSliderPosition call we use the center - topLeft + + if (!sliderRect.contains(event->pos())) { + qDebug("accept"); + event->accept(); + + int v = pixelPosToRangeValue(pick(event->pos() - center)); + setSliderPosition(v); + triggerAction(SliderMove); + setRepeatAction(SliderNoAction); + emit sliderMoved(v);//TODO: ok? + emit sliderPressed(); //TODO: ok? + } else { + QSlider::mousePressEvent(event); + } + } else { + QSlider::mousePressEvent(event); + } +} + +int Slider::pick(const QPoint &pt) const +{ + return orientation() == Qt::Horizontal ? pt.x() : pt.y(); +} + +int Slider::pixelPosToRangeValue(int pos) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt); + QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); + QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + int sliderMin, sliderMax, sliderLength; + if (orientation() == Qt::Horizontal) { + sliderLength = sr.width(); + sliderMin = gr.x(); + sliderMax = gr.right() - sliderLength + 1; + } else { + sliderLength = sr.height(); + sliderMin = gr.y(); + sliderMax = gr.bottom() - sliderLength + 1; + } + return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, + sliderMax - sliderMin, opt.upsideDown); +} + +void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const +{ + if (!option) + return; + + option->initFrom(this); + option->subControls = QStyle::SC_None; + option->activeSubControls = QStyle::SC_None; + option->orientation = orientation(); + option->maximum = maximum(); + option->minimum = minimum(); + option->tickPosition = (QSlider::TickPosition) tickPosition(); + option->tickInterval = tickInterval(); + option->upsideDown = (orientation() == Qt::Horizontal) ? + (invertedAppearance() != (option->direction == Qt::RightToLeft)) + : (!invertedAppearance()); + option->direction = Qt::LeftToRight; // we use the upsideDown option instead + option->sliderPosition = sliderPosition(); + option->sliderValue = value(); + option->singleStep = singleStep(); + option->pageStep = pageStep(); + if (orientation() == Qt::Horizontal) + option->state |= QStyle::State_Horizontal; +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/Slider.h b/product/src/gui/plugin/RobotCtrlWidget/Slider.h index b72a6f8c..0ce56d6a 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/Slider.h +++ b/product/src/gui/plugin/RobotCtrlWidget/Slider.h @@ -1,27 +1,27 @@ -#ifndef SLIDER_H -#define SLIDER_H -#include - -class Slider : public QSlider -{ - Q_OBJECT -public: - Slider(QWidget *parent = 0); - ~Slider(); - -signals: - void onEnter(); - void onLeave(); - void onHover(int pos, int value); -protected: - virtual void enterEvent(QEvent *event); - virtual void leaveEvent(QEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - - inline int pick(const QPoint &pt) const; - int pixelPosToRangeValue(int pos) const; - void initStyleOption_Qt430(QStyleOptionSlider *option) const; -}; - -#endif // SLIDER_H +#ifndef SLIDER_H +#define SLIDER_H +#include + +class Slider : public QSlider +{ + Q_OBJECT +public: + Slider(QWidget *parent = 0); + ~Slider(); + +signals: + void onEnter(); + void onLeave(); + void onHover(int pos, int value); +protected: + virtual void enterEvent(QEvent *event); + virtual void leaveEvent(QEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + + inline int pick(const QPoint &pt) const; + int pixelPosToRangeValue(int pos) const; + void initStyleOption_Qt430(QStyleOptionSlider *option) const; +}; + +#endif // SLIDER_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.cpp b/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.cpp index 79df3689..5edc7320 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.cpp @@ -1,77 +1,77 @@ -#include "VoiceSlider.h" -#include "ui_VoiceSlider.h" - -VoiceSlider::VoiceSlider(int voice,bool bo, QWidget *parent, Qt::WindowFlags f) : - QWidget(parent,f), - m_bo(bo), - m_isShow(false), - ui(new Ui::VoiceSlider) -{ - ui->setupUi(this); - ui->voiceOpen->setObjectName("m_voiceOpen"); - ui->voiceClose->setObjectName("m_voiceClose"); - m_voice = voice; - setWindowOpacity(0.5); - connect(ui->horizontalSlider,&QSlider::valueChanged,this,&VoiceSlider::slotSetVoice); - connect(ui->voiceOpen,&QPushButton::clicked,this,&VoiceSlider::slotCloseVoice); - connect(ui->voiceClose,&QPushButton::clicked,this,&VoiceSlider::slotOpenVoice); - ui->horizontalSlider->setValue(m_voice); - setButtonShow(m_bo); -} - -VoiceSlider::~VoiceSlider() -{ - delete ui; -} - -void VoiceSlider::slotSetVoice(int value) -{ - ui->label->setText(QString("%1").arg(value)); - m_voice = value; - if(value == 0) - { - setButtonShow(false); - emit sigVoiceClose(value); - }else - { - setButtonShow(true); - emit sigVoiceOpen(value); - } -} - -void VoiceSlider::slotCloseVoice() -{ - setButtonShow(false); - emit sigVoiceClose(0); -} - -void VoiceSlider::slotOpenVoice() -{ - setButtonShow(true); - emit sigVoiceOpen(m_voice); -} - -void VoiceSlider::setStatus(bool show) -{ - m_isShow = show; -} - -bool VoiceSlider::getStatus() -{ - return m_isShow; -} - -void VoiceSlider::setButtonShow(bool show) -{ - if(show) - { - m_bo = show; - ui->voiceOpen->setHidden(false); - ui->voiceClose->setHidden(true); - }else - { - m_bo = !show; - ui->voiceOpen->setHidden(true); - ui->voiceClose->setHidden(false); - } -} +#include "VoiceSlider.h" +#include "ui_VoiceSlider.h" + +VoiceSlider::VoiceSlider(int voice,bool bo, QWidget *parent, Qt::WindowFlags f) : + QWidget(parent,f), + m_bo(bo), + m_isShow(false), + ui(new Ui::VoiceSlider) +{ + ui->setupUi(this); + ui->voiceOpen->setObjectName("m_voiceOpen"); + ui->voiceClose->setObjectName("m_voiceClose"); + m_voice = voice; + setWindowOpacity(0.5); + connect(ui->horizontalSlider,&QSlider::valueChanged,this,&VoiceSlider::slotSetVoice); + connect(ui->voiceOpen,&QPushButton::clicked,this,&VoiceSlider::slotCloseVoice); + connect(ui->voiceClose,&QPushButton::clicked,this,&VoiceSlider::slotOpenVoice); + ui->horizontalSlider->setValue(m_voice); + setButtonShow(m_bo); +} + +VoiceSlider::~VoiceSlider() +{ + delete ui; +} + +void VoiceSlider::slotSetVoice(int value) +{ + ui->label->setText(QString("%1").arg(value)); + m_voice = value; + if(value == 0) + { + setButtonShow(false); + emit sigVoiceClose(value); + }else + { + setButtonShow(true); + emit sigVoiceOpen(value); + } +} + +void VoiceSlider::slotCloseVoice() +{ + setButtonShow(false); + emit sigVoiceClose(0); +} + +void VoiceSlider::slotOpenVoice() +{ + setButtonShow(true); + emit sigVoiceOpen(m_voice); +} + +void VoiceSlider::setStatus(bool show) +{ + m_isShow = show; +} + +bool VoiceSlider::getStatus() +{ + return m_isShow; +} + +void VoiceSlider::setButtonShow(bool show) +{ + if(show) + { + m_bo = show; + ui->voiceOpen->setHidden(false); + ui->voiceClose->setHidden(true); + }else + { + m_bo = !show; + ui->voiceOpen->setHidden(true); + ui->voiceClose->setHidden(false); + } +} diff --git a/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.h b/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.h index c4ac8e66..192c6bec 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.h +++ b/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.h @@ -1,36 +1,36 @@ -#ifndef VOICESLIDER_H -#define VOICESLIDER_H - -#include - -namespace Ui { -class VoiceSlider; -} - -class VoiceSlider : public QWidget -{ - Q_OBJECT - -public: - explicit VoiceSlider(int voice,bool bo,QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); - ~VoiceSlider(); -signals: - void sigVoiceClose(int value); - void sigVoiceOpen(int value); -public: - void slotSetVoice(int value); - void slotCloseVoice(); - void slotOpenVoice(); - void setStatus(bool show); - bool getStatus(); - bool m_isShow; -private: - void setButtonShow(bool show); -private: - - Ui::VoiceSlider *ui; - int m_voice; - bool m_bo; -}; - -#endif // VOICESLIDER_H +#ifndef VOICESLIDER_H +#define VOICESLIDER_H + +#include + +namespace Ui { +class VoiceSlider; +} + +class VoiceSlider : public QWidget +{ + Q_OBJECT + +public: + explicit VoiceSlider(int voice,bool bo,QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); + ~VoiceSlider(); +signals: + void sigVoiceClose(int value); + void sigVoiceOpen(int value); +public: + void slotSetVoice(int value); + void slotCloseVoice(); + void slotOpenVoice(); + void setStatus(bool show); + bool getStatus(); + bool m_isShow; +private: + void setButtonShow(bool show); +private: + + Ui::VoiceSlider *ui; + int m_voice; + bool m_bo; +}; + +#endif // VOICESLIDER_H diff --git a/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.ui b/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.ui index c6c22443..dc2b07a1 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.ui +++ b/product/src/gui/plugin/RobotCtrlWidget/VoiceSlider.ui @@ -1,125 +1,125 @@ - - - VoiceSlider - - - - 0 - 0 - 194 - 34 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - 26 - - - - - 30 - 16777215 - - - - - - - - - - - - 0 - 26 - - - - - 30 - 16777215 - - - - - - - - - - - Qt::Horizontal - - - - - - - - 30 - 0 - - - - Qt::LeftToRight - - - - - - 53 - - - Qt::AlignCenter - - - - - - - - - - - - - + + + VoiceSlider + + + + 0 + 0 + 194 + 34 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 26 + + + + + 30 + 16777215 + + + + + + + + + + + + 0 + 26 + + + + + 30 + 16777215 + + + + + + + + + + + Qt::Horizontal + + + + + + + + 30 + 0 + + + + Qt::LeftToRight + + + + + + 53 + + + Qt::AlignCenter + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/RobotCtrlWidget/main.cpp b/product/src/gui/plugin/RobotCtrlWidget/main.cpp index 54bc2a50..b11740fe 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/main.cpp +++ b/product/src/gui/plugin/RobotCtrlWidget/main.cpp @@ -1,24 +1,24 @@ -#include "CRobotWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - { - CRobotWidget w(false,NULL); - w.initialize(); - w.show(); - a.exec(); - } - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "CRobotWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + { + CRobotWidget w(false,NULL); + w.initialize(); + w.show(); + a.exec(); + } + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/RobotWidget/CRobotAVWidget.cpp b/product/src/gui/plugin/RobotWidget/CRobotAVWidget.cpp index 8231601e..1a865922 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotAVWidget.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotAVWidget.cpp @@ -1,333 +1,333 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CRobotAVWidget.h" -#include "ui_CRobotAVWidget.h" -#include "Slider.h" -#include "Renderer.h" -#include "VoiceSlider.h" -#include "CRobotCommon.h" -using namespace QtAV; -CRobotAVWidget::CRobotAVWidget(QWidget *parent) : - QWidget(parent), - m_path(QString()), - m_preview(NULL), - m_voice(30), - ui(new Ui::CRobotAVWidget) -{ - ui->setupUi(this); - m_player = new AVPlayer(this); - m_player->setSpeed(1); - QVBoxLayout *vl = new QVBoxLayout(); - setLayout(vl); - m_renderer = new Renderer(this); - m_renderer->show(); - m_renderer->setContentsMargins(0,0,0,0); - Widgets::registerRenderers(); - m_player->setRenderer(m_renderer); - vl->setContentsMargins(0,0,0,0); - - QHBoxLayout *controlLayout = new QHBoxLayout(); - controlLayout->setContentsMargins(10,10,10,10); - m_control = new QWidget(this); - m_control->setMaximumHeight(40); - m_timerSlider = new Slider(m_control); - m_timerSlider->setDisabled(true); - m_timerSlider->setTracking(true); - m_timerSlider->setOrientation(Qt::Horizontal); - m_timerSlider->setMinimum(0); - m_current = new QLabel(m_control); - m_current->setToolTip(tr("current time")); - m_current->setContentsMargins(QMargins(10, 2, 10, 2)); - m_current->setText(QString::fromLatin1("00:00:00")); - m_end = new QLabel(m_control); - m_end->setToolTip(tr("duration")); - m_end->setContentsMargins(QMargins(10, 2, 10, 2)); - m_end->setText(QString::fromLatin1("00:00:00")); - m_play = new QPushButton(m_control); - m_play->setObjectName("play"); - m_pause = new QPushButton(m_control); - m_pause->setObjectName("pause"); - m_play->setFixedSize(20,20); - m_pause->setFixedSize(20,20); - m_play->setHidden(false); - m_pause->setHidden(true); - m_cap = new QToolButton(m_control); - m_cap->setObjectName("m_cap"); - m_cap->setFixedSize(26,26); - m_voiceOpen = new QPushButton(m_control); - m_voiceOpen->setObjectName("m_voiceOpen"); - m_voiceOpen->setFixedSize(26,26); - - m_voiceClose = new QPushButton(m_control); - m_voiceClose->setObjectName("m_voiceClose"); - m_voiceClose->setFixedSize(26,26); - - m_control->setLayout(controlLayout); - controlLayout->addWidget(m_play); - controlLayout->addWidget(m_pause); - controlLayout->addWidget(m_current); - controlLayout->addWidget(m_timerSlider); - controlLayout->addWidget(m_end); - controlLayout->addWidget(m_cap); - controlLayout->addWidget(m_voiceOpen); - controlLayout->addWidget(m_voiceClose); - m_voiceOpen->setHidden(false); - m_voiceClose->setHidden(true); - m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); - - vl->addWidget(m_renderer); - vl->addWidget(m_control); - setCaptureConfig(); - connect(m_timerSlider, SIGNAL(sliderMoved(int)), SLOT(seek(int))); - connect(m_timerSlider, SIGNAL(sliderPressed()), SLOT(seek())); - connect(m_timerSlider, SIGNAL(onLeave()), SLOT(onTimeSliderLeave())); - connect(m_timerSlider, SIGNAL(onHover(int,int)), SLOT(onTimeSliderHover(int,int))); - connect(m_player,&AVPlayer::started,this,&CRobotAVWidget::startPlay); - connect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(onPositionChange(qint64))); - connect(m_renderer,&Renderer::click,this,&CRobotAVWidget::playPause); - connect(m_renderer,&Renderer::avPlay,this,&CRobotAVWidget::play); - connect(m_renderer,&Renderer::ccdPlay,this,&CRobotAVWidget::slotCCDPlay); - connect(m_play,&QPushButton::clicked,this,&CRobotAVWidget::playPause); - connect(m_pause,&QPushButton::clicked,this,&CRobotAVWidget::playPause); - connect(m_cap,&QToolButton::clicked,m_player->videoCapture(),&VideoCapture::capture); - connect(m_voiceOpen,&QPushButton::clicked,this,&CRobotAVWidget::voiceSliderShow); - connect(m_voiceClose,&QPushButton::clicked,this,&CRobotAVWidget::voiceSliderShow); - connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&CRobotAVWidget::slotVoiceClose); - connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&CRobotAVWidget::slotVoiceOpen); -} - -CRobotAVWidget::~CRobotAVWidget() -{ - delete ui; -} - -void CRobotAVWidget::setPath(const QString &path) -{ - m_path = path; - QStringList list = m_path.split("/"); - if(list.size() <= 0) - { - m_name = ""; - return ; - } - QString name = list.at(list.size()-1); - m_name = name.split(".").at(0); -} - -void CRobotAVWidget::play(QString path) -{ - if(m_path.compare(path) == 0) - { - if (!m_player->isPlaying()) { - m_player->play(); - setVoiceNum(); - setShowButton(true); - return; - } - if(m_player->isPaused()) - { - m_player->pause(!m_player->isPaused()); - setShowButton(true); - } - }else - { - setPath(path); - m_player->play(m_path); - setVoiceNum(); - setShowButton(true); - } -} - -void CRobotAVWidget::stop() -{ - if(m_player->isPlaying()) - { - setPath(""); - m_player->stop(); - } -} - -bool CRobotAVWidget::isPlaying() -{ - return m_player->isPlaying(); -} - -void CRobotAVWidget::playPause() -{ - if(m_path.isEmpty()) - { - return ; - } - if (!m_player->isPlaying()) { - m_player->play(); - setShowButton(true); - setVoiceNum(); - return; - } - if(m_player->isPaused()) - { - m_player->pause(false); - setShowButton(true); - }else - { - m_player->pause(true); - setShowButton(false); - } -} - -void CRobotAVWidget::slotCCDPlay(QString path) -{ - emit sigCCDPlay(path); -} - -void CRobotAVWidget::seek() -{ - seek(m_timerSlider->value()); -} - -void CRobotAVWidget::seek(int value) -{ - m_player->setSeekType(AccurateSeek); - m_player->seek((qint64)value); - if (!m_preview) - return; - m_preview->setTimestamp(value); - m_preview->preview(); - m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); - m_preview->resize(160, 90); - m_preview->show(); -} - -void CRobotAVWidget::onTimeSliderHover(int pos, int value) -{ - Q_UNUSED(pos); - const QPoint gpos =QCursor::pos(); - QToolTip::showText(gpos, QTime(0, 0, 0).addMSecs(value).toString(QString::fromLatin1("HH:mm:ss"))); - if (!m_preview) - m_preview = new VideoPreviewWidget(); - m_preview->setFile(m_player->file()); - m_preview->setTimestamp(value); - m_preview->preview(); - const int w = 160; - const int h = 90; - m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); - m_preview->resize(w, h); - m_preview->move(gpos - QPoint(w/2, h)); - m_preview->show(); -} - -void CRobotAVWidget::onTimeSliderLeave() -{ - if (m_preview && m_preview->isVisible()) - m_preview->hide(); -} - -void CRobotAVWidget::voiceSliderShow() -{ - if(m_voiceSlider->getStatus() == false) - { - QPoint gpos =mapToGlobal(m_voiceOpen->pos()); - int x= m_control->pos().y()-52; - m_voiceSlider->move(gpos-QPoint(159,0)+QPoint(0,x)); - m_voiceSlider->show(); - m_voiceSlider->setStatus(true); - }else - { - m_voiceSlider->hide(); - m_voiceSlider->setStatus(false); - } -} - -void CRobotAVWidget::slotVoiceClose(int voice) -{ - //声音范围为0-4 - setShowVoice(false); - m_voice = voice; - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void CRobotAVWidget::slotVoiceOpen(int voice) -{ - //声音范围为0-4 - setShowVoice(true); - m_voice = voice; - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(voice*0.04); - if (ao) { - ao->setVolume(v); - } -} - -void CRobotAVWidget::startPlay() -{ - m_timerSlider->setMinimum(m_player->mediaStartPosition()); - m_timerSlider->setMaximum(m_player->mediaStopPosition()); - m_timerSlider->setValue(0); - m_timerSlider->setEnabled(m_player->isSeekable()); - m_end->setText(QTime(0, 0, 0).addMSecs(m_player->mediaStopPosition()).toString(QString::fromLatin1("HH:mm:ss"))); -} - -void CRobotAVWidget::onPositionChange(qint64 pos) -{ - if (m_player->isSeekable()) - m_timerSlider->setValue(pos); - m_current->setText(QTime(0, 0, 0).addMSecs(pos).toString(QString::fromLatin1("HH:mm:ss"))); -} - -void CRobotAVWidget::setShowButton(bool bo) -{ - if(bo) - { - m_play->setHidden(true); - m_pause->setHidden(false); - }else - { - m_pause->setHidden(true); - m_play->setHidden(false); - } -} - -void CRobotAVWidget::setCaptureConfig() -{ - m_player->videoCapture()->setCaptureDir("../../data/test/cut"); - m_player->videoCapture()->setQuality(100); - - m_player->videoCapture()->setSaveFormat("jpg"); -} - -void CRobotAVWidget::setShowVoice(bool bo) -{ - if(!bo) - { - m_voiceOpen->setHidden(true); - m_voiceClose->setHidden(false); - }else - { - m_voiceOpen->setHidden(false); - m_voiceClose->setHidden(true); - } -} - -void CRobotAVWidget::setVoiceNum() -{ - //声音范围为0-4 - AudioOutput *ao = m_player ? m_player->audio() : 0; - qreal v = qreal(m_voice*0.04); - if (ao) - { - ao->setVolume(v); - } -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CRobotAVWidget.h" +#include "ui_CRobotAVWidget.h" +#include "Slider.h" +#include "Renderer.h" +#include "VoiceSlider.h" +#include "CRobotCommon.h" +using namespace QtAV; +CRobotAVWidget::CRobotAVWidget(QWidget *parent) : + QWidget(parent), + m_path(QString()), + m_preview(NULL), + m_voice(30), + ui(new Ui::CRobotAVWidget) +{ + ui->setupUi(this); + m_player = new AVPlayer(this); + m_player->setSpeed(1); + QVBoxLayout *vl = new QVBoxLayout(); + setLayout(vl); + m_renderer = new Renderer(this); + m_renderer->show(); + m_renderer->setContentsMargins(0,0,0,0); + Widgets::registerRenderers(); + m_player->setRenderer(m_renderer); + vl->setContentsMargins(0,0,0,0); + + QHBoxLayout *controlLayout = new QHBoxLayout(); + controlLayout->setContentsMargins(10,10,10,10); + m_control = new QWidget(this); + m_control->setMaximumHeight(40); + m_timerSlider = new Slider(m_control); + m_timerSlider->setDisabled(true); + m_timerSlider->setTracking(true); + m_timerSlider->setOrientation(Qt::Horizontal); + m_timerSlider->setMinimum(0); + m_current = new QLabel(m_control); + m_current->setToolTip(tr("current time")); + m_current->setContentsMargins(QMargins(10, 2, 10, 2)); + m_current->setText(QString::fromLatin1("00:00:00")); + m_end = new QLabel(m_control); + m_end->setToolTip(tr("duration")); + m_end->setContentsMargins(QMargins(10, 2, 10, 2)); + m_end->setText(QString::fromLatin1("00:00:00")); + m_play = new QPushButton(m_control); + m_play->setObjectName("play"); + m_pause = new QPushButton(m_control); + m_pause->setObjectName("pause"); + m_play->setFixedSize(20,20); + m_pause->setFixedSize(20,20); + m_play->setHidden(false); + m_pause->setHidden(true); + m_cap = new QToolButton(m_control); + m_cap->setObjectName("m_cap"); + m_cap->setFixedSize(26,26); + m_voiceOpen = new QPushButton(m_control); + m_voiceOpen->setObjectName("m_voiceOpen"); + m_voiceOpen->setFixedSize(26,26); + + m_voiceClose = new QPushButton(m_control); + m_voiceClose->setObjectName("m_voiceClose"); + m_voiceClose->setFixedSize(26,26); + + m_control->setLayout(controlLayout); + controlLayout->addWidget(m_play); + controlLayout->addWidget(m_pause); + controlLayout->addWidget(m_current); + controlLayout->addWidget(m_timerSlider); + controlLayout->addWidget(m_end); + controlLayout->addWidget(m_cap); + controlLayout->addWidget(m_voiceOpen); + controlLayout->addWidget(m_voiceClose); + m_voiceOpen->setHidden(false); + m_voiceClose->setHidden(true); + m_voiceSlider = new VoiceSlider(m_voice,true,this,QMenu().windowFlags() | Qt::FramelessWindowHint); + + vl->addWidget(m_renderer); + vl->addWidget(m_control); + setCaptureConfig(); + connect(m_timerSlider, SIGNAL(sliderMoved(int)), SLOT(seek(int))); + connect(m_timerSlider, SIGNAL(sliderPressed()), SLOT(seek())); + connect(m_timerSlider, SIGNAL(onLeave()), SLOT(onTimeSliderLeave())); + connect(m_timerSlider, SIGNAL(onHover(int,int)), SLOT(onTimeSliderHover(int,int))); + connect(m_player,&AVPlayer::started,this,&CRobotAVWidget::startPlay); + connect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(onPositionChange(qint64))); + connect(m_renderer,&Renderer::click,this,&CRobotAVWidget::playPause); + connect(m_renderer,&Renderer::avPlay,this,&CRobotAVWidget::play); + connect(m_renderer,&Renderer::ccdPlay,this,&CRobotAVWidget::slotCCDPlay); + connect(m_play,&QPushButton::clicked,this,&CRobotAVWidget::playPause); + connect(m_pause,&QPushButton::clicked,this,&CRobotAVWidget::playPause); + connect(m_cap,&QToolButton::clicked,m_player->videoCapture(),&VideoCapture::capture); + connect(m_voiceOpen,&QPushButton::clicked,this,&CRobotAVWidget::voiceSliderShow); + connect(m_voiceClose,&QPushButton::clicked,this,&CRobotAVWidget::voiceSliderShow); + connect(m_voiceSlider,&VoiceSlider::sigVoiceClose,this,&CRobotAVWidget::slotVoiceClose); + connect(m_voiceSlider,&VoiceSlider::sigVoiceOpen,this,&CRobotAVWidget::slotVoiceOpen); +} + +CRobotAVWidget::~CRobotAVWidget() +{ + delete ui; +} + +void CRobotAVWidget::setPath(const QString &path) +{ + m_path = path; + QStringList list = m_path.split("/"); + if(list.size() <= 0) + { + m_name = ""; + return ; + } + QString name = list.at(list.size()-1); + m_name = name.split(".").at(0); +} + +void CRobotAVWidget::play(QString path) +{ + if(m_path.compare(path) == 0) + { + if (!m_player->isPlaying()) { + m_player->play(); + setVoiceNum(); + setShowButton(true); + return; + } + if(m_player->isPaused()) + { + m_player->pause(!m_player->isPaused()); + setShowButton(true); + } + }else + { + setPath(path); + m_player->play(m_path); + setVoiceNum(); + setShowButton(true); + } +} + +void CRobotAVWidget::stop() +{ + if(m_player->isPlaying()) + { + setPath(""); + m_player->stop(); + } +} + +bool CRobotAVWidget::isPlaying() +{ + return m_player->isPlaying(); +} + +void CRobotAVWidget::playPause() +{ + if(m_path.isEmpty()) + { + return ; + } + if (!m_player->isPlaying()) { + m_player->play(); + setShowButton(true); + setVoiceNum(); + return; + } + if(m_player->isPaused()) + { + m_player->pause(false); + setShowButton(true); + }else + { + m_player->pause(true); + setShowButton(false); + } +} + +void CRobotAVWidget::slotCCDPlay(QString path) +{ + emit sigCCDPlay(path); +} + +void CRobotAVWidget::seek() +{ + seek(m_timerSlider->value()); +} + +void CRobotAVWidget::seek(int value) +{ + m_player->setSeekType(AccurateSeek); + m_player->seek((qint64)value); + if (!m_preview) + return; + m_preview->setTimestamp(value); + m_preview->preview(); + m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); + m_preview->resize(160, 90); + m_preview->show(); +} + +void CRobotAVWidget::onTimeSliderHover(int pos, int value) +{ + Q_UNUSED(pos); + const QPoint gpos =QCursor::pos(); + QToolTip::showText(gpos, QTime(0, 0, 0).addMSecs(value).toString(QString::fromLatin1("HH:mm:ss"))); + if (!m_preview) + m_preview = new VideoPreviewWidget(); + m_preview->setFile(m_player->file()); + m_preview->setTimestamp(value); + m_preview->preview(); + const int w = 160; + const int h = 90; + m_preview->setWindowFlags(m_preview->windowFlags() |Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint); + m_preview->resize(w, h); + m_preview->move(gpos - QPoint(w/2, h)); + m_preview->show(); +} + +void CRobotAVWidget::onTimeSliderLeave() +{ + if (m_preview && m_preview->isVisible()) + m_preview->hide(); +} + +void CRobotAVWidget::voiceSliderShow() +{ + if(m_voiceSlider->getStatus() == false) + { + QPoint gpos =mapToGlobal(m_voiceOpen->pos()); + int x= m_control->pos().y()-52; + m_voiceSlider->move(gpos-QPoint(159,0)+QPoint(0,x)); + m_voiceSlider->show(); + m_voiceSlider->setStatus(true); + }else + { + m_voiceSlider->hide(); + m_voiceSlider->setStatus(false); + } +} + +void CRobotAVWidget::slotVoiceClose(int voice) +{ + //声音范围为0-4 + setShowVoice(false); + m_voice = voice; + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void CRobotAVWidget::slotVoiceOpen(int voice) +{ + //声音范围为0-4 + setShowVoice(true); + m_voice = voice; + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(voice*0.04); + if (ao) { + ao->setVolume(v); + } +} + +void CRobotAVWidget::startPlay() +{ + m_timerSlider->setMinimum(m_player->mediaStartPosition()); + m_timerSlider->setMaximum(m_player->mediaStopPosition()); + m_timerSlider->setValue(0); + m_timerSlider->setEnabled(m_player->isSeekable()); + m_end->setText(QTime(0, 0, 0).addMSecs(m_player->mediaStopPosition()).toString(QString::fromLatin1("HH:mm:ss"))); +} + +void CRobotAVWidget::onPositionChange(qint64 pos) +{ + if (m_player->isSeekable()) + m_timerSlider->setValue(pos); + m_current->setText(QTime(0, 0, 0).addMSecs(pos).toString(QString::fromLatin1("HH:mm:ss"))); +} + +void CRobotAVWidget::setShowButton(bool bo) +{ + if(bo) + { + m_play->setHidden(true); + m_pause->setHidden(false); + }else + { + m_pause->setHidden(true); + m_play->setHidden(false); + } +} + +void CRobotAVWidget::setCaptureConfig() +{ + m_player->videoCapture()->setCaptureDir("../../data/test/cut"); + m_player->videoCapture()->setQuality(100); + + m_player->videoCapture()->setSaveFormat("jpg"); +} + +void CRobotAVWidget::setShowVoice(bool bo) +{ + if(!bo) + { + m_voiceOpen->setHidden(true); + m_voiceClose->setHidden(false); + }else + { + m_voiceOpen->setHidden(false); + m_voiceClose->setHidden(true); + } +} + +void CRobotAVWidget::setVoiceNum() +{ + //声音范围为0-4 + AudioOutput *ao = m_player ? m_player->audio() : 0; + qreal v = qreal(m_voice*0.04); + if (ao) + { + ao->setVolume(v); + } +} diff --git a/product/src/gui/plugin/RobotWidget/CRobotAVWidget.h b/product/src/gui/plugin/RobotWidget/CRobotAVWidget.h index 3841c311..cfdf6bd4 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotAVWidget.h +++ b/product/src/gui/plugin/RobotWidget/CRobotAVWidget.h @@ -1,89 +1,89 @@ -#ifndef CROBOTAVWIDGET_H -#define CROBOTAVWIDGET_H - -#include -#include -#include -class Slider; -class QPushButton; -class QWidget; -class QLabel; -class QToolButton; -class Renderer; -class VoiceSlider; -namespace Ui { -class CRobotAVWidget; -} - -class CRobotAVWidget : public QWidget -{ - Q_OBJECT - -public: - CRobotAVWidget(QWidget *parent = 0); - ~CRobotAVWidget(); - - bool isPlaying(); - - void setPath(const QString &path); - - void stop(); - - void pause(); -signals: - void sigCCDPlay(QString path); -public slots: - void play(QString path); - void playPause(); - void slotCCDPlay(QString path); - - void seek(); - void seek(int value); - - void onTimeSliderHover(int pos, int value); - void onTimeSliderLeave(); - - void voiceSliderShow(); - - void slotVoiceClose(int voice); - - void slotVoiceOpen(int voice); -private slots: - void startPlay(); - void onPositionChange(qint64 pos); -private: - /** - * @brief setShowButton 设置播放暂停按钮 - * @param bo true-播放状态 false-暂停状态 - */ - void setShowButton(bool bo); - - void setCaptureConfig(); - - void setShowVoice(bool bo); - - void setVoiceNum(); - -private: - Ui::CRobotAVWidget *ui; - Renderer* m_renderer; - QtAV::AVPlayer *m_player; - Slider *m_timerSlider; - QWidget *m_control; - - QString m_path; - QString m_name; - QLabel *m_current, *m_end; - QToolButton *m_cap; //抓图 - - QPushButton *m_play; - QPushButton *m_pause; - QPushButton *m_voiceOpen; - QPushButton *m_voiceClose; - VoiceSlider *m_voiceSlider; - //QPushButton *m_voice_0; - QtAV::VideoPreviewWidget *m_preview; - int m_voice; -}; - -#endif // CROBOTAVWIDGET_H +#ifndef CROBOTAVWIDGET_H +#define CROBOTAVWIDGET_H + +#include +#include +#include +class Slider; +class QPushButton; +class QWidget; +class QLabel; +class QToolButton; +class Renderer; +class VoiceSlider; +namespace Ui { +class CRobotAVWidget; +} + +class CRobotAVWidget : public QWidget +{ + Q_OBJECT + +public: + CRobotAVWidget(QWidget *parent = 0); + ~CRobotAVWidget(); + + bool isPlaying(); + + void setPath(const QString &path); + + void stop(); + + void pause(); +signals: + void sigCCDPlay(QString path); +public slots: + void play(QString path); + void playPause(); + void slotCCDPlay(QString path); + + void seek(); + void seek(int value); + + void onTimeSliderHover(int pos, int value); + void onTimeSliderLeave(); + + void voiceSliderShow(); + + void slotVoiceClose(int voice); + + void slotVoiceOpen(int voice); +private slots: + void startPlay(); + void onPositionChange(qint64 pos); +private: + /** + * @brief setShowButton 设置播放暂停按钮 + * @param bo true-播放状态 false-暂停状态 + */ + void setShowButton(bool bo); + + void setCaptureConfig(); + + void setShowVoice(bool bo); + + void setVoiceNum(); + +private: + Ui::CRobotAVWidget *ui; + Renderer* m_renderer; + QtAV::AVPlayer *m_player; + Slider *m_timerSlider; + QWidget *m_control; + + QString m_path; + QString m_name; + QLabel *m_current, *m_end; + QToolButton *m_cap; //抓图 + + QPushButton *m_play; + QPushButton *m_pause; + QPushButton *m_voiceOpen; + QPushButton *m_voiceClose; + VoiceSlider *m_voiceSlider; + //QPushButton *m_voice_0; + QtAV::VideoPreviewWidget *m_preview; + int m_voice; +}; + +#endif // CROBOTAVWIDGET_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotAVWidget.ui b/product/src/gui/plugin/RobotWidget/CRobotAVWidget.ui index c81a1230..282d24d8 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotAVWidget.ui +++ b/product/src/gui/plugin/RobotWidget/CRobotAVWidget.ui @@ -1,25 +1,25 @@ - - - CRobotAVWidget - - - - 0 - 0 - 533 - 672 - - - - - 0 - 0 - - - - Form - - - - - + + + CRobotAVWidget + + + + 0 + 0 + 533 + 672 + + + + + 0 + 0 + + + + Form + + + + + diff --git a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.cpp b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.cpp index d47fa6a2..db8a5be3 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.cpp @@ -1,78 +1,78 @@ -#include "CRobotCCDVideoForm.h" -#include "ui_CRobotCCDVideoForm.h" -#include -#include "CRobotCCDVideoItemModel.h" -#include -#include -#include -#include -CRobotCCDVideoForm::CRobotCCDVideoForm(QWidget *parent) : - QWidget(parent), - m_model(NULL), - ui(new Ui::CRobotCCDVideoForm) -{ - ui->setupUi(this); - m_searchButton = new QPushButton(this); - m_searchButton->setObjectName("searchButton"); - m_searchButton->setText(""); - m_searchButton->setMaximumSize(20, 20); - m_searchButton->setCursor(QCursor(Qt::ArrowCursor)); - m_searchButton->setShortcut(QKeySequence(QLatin1String("Return"))); - QHBoxLayout * pTimeLayout = new QHBoxLayout(); - pTimeLayout->setContentsMargins(1, 1, 1, 1); - pTimeLayout->addStretch(); - pTimeLayout->addWidget(m_searchButton,2); - ui->keyWordSearch->setLayout(pTimeLayout); - connect(m_searchButton,&QPushButton::clicked,this,&CRobotCCDVideoForm::slotFilte,Qt::QueuedConnection); - ui->keyWordSearch->setPlaceholderText(tr("请输入关键字")); -} - -CRobotCCDVideoForm::~CRobotCCDVideoForm() -{ - delete ui; -} - -void CRobotCCDVideoForm::setItemModel(CRobotCCDVideoItemModel *model) -{ - m_model = model; - ui->ccdVideoView->initialize(); - ui->ccdVideoView->setModel(m_model); - connect(ui->ccdVideoView->horizontalHeader(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),m_model,SLOT(sortColumn(int,Qt::SortOrder))); - connect(ui->ccdVideoView,&CRobotCCDVideoView::clicked,this,&CRobotCCDVideoForm::clicked); - connect(this,&CRobotCCDVideoForm::sigFilte,m_model,&CRobotCCDVideoItemModel::slotFilte,Qt::QueuedConnection); - ui->ccdVideoView->setColumnWidth(0, 77); - ui->ccdVideoView->setColumnWidth(1, 100); - ui->ccdVideoView->setColumnWidth(2, 40); -} - -void CRobotCCDVideoForm::clicked(const QModelIndex &index) -{ - if(m_model == NULL) - { - return ; - } - if(!index.isValid()) - { - return ; - } - QList listInfo = m_model->getShowList(); - if(listInfo.isEmpty()) - { - return ; - } - RobotFilePtr robotInfo = listInfo.at(index.row()); - qDebug()<<"执行路径:"<m_execPath; - if(robotInfo->m_fileType == E_ROBOT_VIDEO) - { - emit sigAvPlay(robotInfo->m_execPath); - }else if(robotInfo->m_fileType == E_ROBOT_CCD || robotInfo->m_fileType == E_ROBOT_CUT_CCD) - { - emit sigCCDPlay(robotInfo->m_execPath); - } -} - -void CRobotCCDVideoForm::slotFilte() -{ - m_searchText = ui->keyWordSearch->text(); - emit sigFilte(m_searchText); -} +#include "CRobotCCDVideoForm.h" +#include "ui_CRobotCCDVideoForm.h" +#include +#include "CRobotCCDVideoItemModel.h" +#include +#include +#include +#include +CRobotCCDVideoForm::CRobotCCDVideoForm(QWidget *parent) : + QWidget(parent), + m_model(NULL), + ui(new Ui::CRobotCCDVideoForm) +{ + ui->setupUi(this); + m_searchButton = new QPushButton(this); + m_searchButton->setObjectName("searchButton"); + m_searchButton->setText(""); + m_searchButton->setMaximumSize(20, 20); + m_searchButton->setCursor(QCursor(Qt::ArrowCursor)); + m_searchButton->setShortcut(QKeySequence(QLatin1String("Return"))); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_searchButton,2); + ui->keyWordSearch->setLayout(pTimeLayout); + connect(m_searchButton,&QPushButton::clicked,this,&CRobotCCDVideoForm::slotFilte,Qt::QueuedConnection); + ui->keyWordSearch->setPlaceholderText(tr("请输入关键字")); +} + +CRobotCCDVideoForm::~CRobotCCDVideoForm() +{ + delete ui; +} + +void CRobotCCDVideoForm::setItemModel(CRobotCCDVideoItemModel *model) +{ + m_model = model; + ui->ccdVideoView->initialize(); + ui->ccdVideoView->setModel(m_model); + connect(ui->ccdVideoView->horizontalHeader(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),m_model,SLOT(sortColumn(int,Qt::SortOrder))); + connect(ui->ccdVideoView,&CRobotCCDVideoView::clicked,this,&CRobotCCDVideoForm::clicked); + connect(this,&CRobotCCDVideoForm::sigFilte,m_model,&CRobotCCDVideoItemModel::slotFilte,Qt::QueuedConnection); + ui->ccdVideoView->setColumnWidth(0, 77); + ui->ccdVideoView->setColumnWidth(1, 100); + ui->ccdVideoView->setColumnWidth(2, 40); +} + +void CRobotCCDVideoForm::clicked(const QModelIndex &index) +{ + if(m_model == NULL) + { + return ; + } + if(!index.isValid()) + { + return ; + } + QList listInfo = m_model->getShowList(); + if(listInfo.isEmpty()) + { + return ; + } + RobotFilePtr robotInfo = listInfo.at(index.row()); + qDebug()<<"执行路径:"<m_execPath; + if(robotInfo->m_fileType == E_ROBOT_VIDEO) + { + emit sigAvPlay(robotInfo->m_execPath); + }else if(robotInfo->m_fileType == E_ROBOT_CCD || robotInfo->m_fileType == E_ROBOT_CUT_CCD) + { + emit sigCCDPlay(robotInfo->m_execPath); + } +} + +void CRobotCCDVideoForm::slotFilte() +{ + m_searchText = ui->keyWordSearch->text(); + emit sigFilte(m_searchText); +} diff --git a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.h b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.h index 89f3d90c..deccdb59 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.h +++ b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.h @@ -1,35 +1,35 @@ -#ifndef CROBOTCCDVIDEOFORM_H -#define CROBOTCCDVIDEOFORM_H - -#include -#include "CRobotCommon.h" -class QPushButton; -class CRobotCCDVideoItemModel; -namespace Ui { -class CRobotCCDVideoForm; -} - -class CRobotCCDVideoForm : public QWidget -{ - Q_OBJECT - -public: - explicit CRobotCCDVideoForm(QWidget *parent = 0); - ~CRobotCCDVideoForm(); - void setItemModel(CRobotCCDVideoItemModel *model); -signals: - void sigAvPlay(QString path); - void sigCCDPlay(QString path); - - void sigFilte(QString text); -public slots: - void clicked(const QModelIndex &index); - void slotFilte(); -private: - Ui::CRobotCCDVideoForm *ui; - QPushButton * m_searchButton; - CRobotCCDVideoItemModel *m_model; - QString m_searchText; -}; - -#endif // CROBOTCCDVIDEOFORM_H +#ifndef CROBOTCCDVIDEOFORM_H +#define CROBOTCCDVIDEOFORM_H + +#include +#include "CRobotCommon.h" +class QPushButton; +class CRobotCCDVideoItemModel; +namespace Ui { +class CRobotCCDVideoForm; +} + +class CRobotCCDVideoForm : public QWidget +{ + Q_OBJECT + +public: + explicit CRobotCCDVideoForm(QWidget *parent = 0); + ~CRobotCCDVideoForm(); + void setItemModel(CRobotCCDVideoItemModel *model); +signals: + void sigAvPlay(QString path); + void sigCCDPlay(QString path); + + void sigFilte(QString text); +public slots: + void clicked(const QModelIndex &index); + void slotFilte(); +private: + Ui::CRobotCCDVideoForm *ui; + QPushButton * m_searchButton; + CRobotCCDVideoItemModel *m_model; + QString m_searchText; +}; + +#endif // CROBOTCCDVIDEOFORM_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.ui b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.ui index 59462b73..03b04fb2 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.ui +++ b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoForm.ui @@ -1,100 +1,100 @@ - - - CRobotCCDVideoForm - - - - 0 - 0 - 256 - 668 - - - - - 0 - 0 - - - - Form - - - - - - - 0 - - - 10 - - - 0 - - - 0 - - - 0 - - - 10 - - - - - - 0 - 31 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 10 - 20 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 10 - 20 - - - - - - - - - - - - CRobotCCDVideoView - QTableView -
CRobotCCDVideoView.h
-
-
- - -
+ + + CRobotCCDVideoForm + + + + 0 + 0 + 256 + 668 + + + + + 0 + 0 + + + + Form + + + + + + + 0 + + + 10 + + + 0 + + + 0 + + + 0 + + + 10 + + + + + + 0 + 31 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 10 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 10 + 20 + + + + + + + + + + + + CRobotCCDVideoView + QTableView +
CRobotCCDVideoView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoItemModel.cpp b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoItemModel.cpp index 82808d42..2189037a 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoItemModel.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoItemModel.cpp @@ -1,351 +1,351 @@ -#include "CRobotCCDVideoItemModel.h" -#include -#include "CRobotFileInfo.h" -#include "CRobotCommon.h" -#include -using namespace std; -typedef QPair > PAIRLISTROBOTINFO; - -CRobotCCDVideoItemModel::CRobotCCDVideoItemModel(QObject *parent) - : QAbstractTableModel(parent), - m_sortKey(E_SORT_TIME), - m_order(Qt::DescendingOrder), - m_searchText(QString()) -{ - m_header < >("ListRobotFilePtr"); -} - -QVariant CRobotCCDVideoItemModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role && Qt::Horizontal == orientation) - { - return QVariant(m_header.at(section)); - } - return QVariant(); -} - -int CRobotCCDVideoItemModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - return m_listShowInfo.count(); -} - -int CRobotCCDVideoItemModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.count(); -} - -QVariant CRobotCCDVideoItemModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - if(Qt::TextAlignmentRole == role) - { - return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); - }else if(Qt::DisplayRole == role) - { - switch(index.column()) - { - case TIME: - { - return QDateTime::fromMSecsSinceEpoch(m_listShowInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd"); - } - case DEVICE: - { - return m_map[m_listShowInfo.at(index.row())->m_devgId]; - } - case TYPE: - { - if(E_ROBOT_CCD == m_listShowInfo.at(index.row())->m_fileType) - { - return tr("照片"); - }else if(E_ROBOT_CUT_CCD == m_listShowInfo.at(index.row())->m_fileType) - { - return tr("截图"); - }else if(E_ROBOT_VIDEO == m_listShowInfo.at(index.row())->m_fileType) - { - return tr("录像"); - } - } - default: - break; - } - } - return QVariant(); -} - -const QList CRobotCCDVideoItemModel::getShowList() const -{ - return m_listShowInfo; -} - -void CRobotCCDVideoItemModel::slotMsgAdd(const QList list) -{ - uint64 month = 3; - uint64 outTime = month*30*60*60*1000*24; - uint64 time = QDateTime::currentMSecsSinceEpoch(); - foreach (RobotFilePtr info,list) { - if(conditionFilter(info)) - { - if((time - outTime) < info->time_stamp) - { - insertMsg(info); - } - } - } -} - -void CRobotCCDVideoItemModel::slotMsgSub(const QList list) -{ - foreach (RobotFilePtr info,list) { - for(int nIndex = m_listShowInfo.size() - 1; nIndex >= 0; --nIndex) - { - if(m_listShowInfo.at(nIndex)->m_execPath == info->m_execPath) - { - beginRemoveRows(QModelIndex(), nIndex, nIndex); - m_listShowInfo.removeAt(nIndex); - endRemoveRows(); - break; - } - } - } -} - -void CRobotCCDVideoItemModel::sortColumn(int column, Qt::SortOrder order) -{ - if(order == Qt::AscendingOrder) - { - m_order = Qt::DescendingOrder; - } - else - { - m_order = Qt::AscendingOrder; - } - - switch ((ColumnField)column) - { - case TIME: - { - m_sortKey = E_SORT_TIME; - break; - } - case DEVICE: - { - m_sortKey = E_SORT_DEV; - break; - } - case TYPE: - { - m_sortKey = E_SORT_TYPE; - break; - } - default: - break; - } - sort(); - beginResetModel(); - endResetModel(); -} - -void CRobotCCDVideoItemModel::slotFilte(QString text) -{ - m_searchText = text; - brush(); -} - -void CRobotCCDVideoItemModel::initialize(QMap devMap) -{ - m_listHorAlignmentFlags.clear(); - for (int nIndex(0); nIndex < m_header.size(); nIndex++) - { - m_listHorAlignmentFlags.append(Qt::AlignHCenter); - } - m_listShowInfo.clear(); - m_map.clear(); - m_map = devMap; -} - -bool CRobotCCDVideoItemModel::conditionFilter(const RobotFilePtr &info) -{ - if(m_searchText.isEmpty()) - { - return true; - } - std::string text =m_searchText.toStdString(); - //判断时间 - - std::string time = QDateTime::fromMSecsSinceEpoch(info->time_stamp).toString("yyyy-MM-dd").toStdString(); - if(time.find(text,0) != -1) - { - return true; - } - //判断设备组 - std::string dev = m_map[info->m_devgId].toStdString(); - - if(dev.find(text,0) != -1) - { - return true; - } - return false; -} - -void CRobotCCDVideoItemModel::insertMsg(const RobotFilePtr &info) -{ - int mid = -1; - int left = 0; - int right = m_listShowInfo.size() - 1; - while (left <= right) { - mid = (left + right) / 2; - if(Qt::AscendingOrder == m_order) - { - if(info->lessThan(m_listShowInfo[mid]),m_sortKey) - { - right = mid -1; - }else - { - left = mid + 1; - } - }else - { - if(m_listShowInfo[mid]->lessThan(info,m_sortKey)) - { - right = mid -1; - }else - { - left = mid + 1; - } - } - } - beginInsertRows(QModelIndex(),left,left); - m_listShowInfo.insert(left,info); - endInsertRows(); -} - -//<归并排序 -void CRobotCCDVideoItemModel::sort() -{ - QMap mapRobotInfo; - for(int nIndex(0); nIndex < m_listShowInfo.count(); nIndex++) - { - RobotFilePtr temp = m_listShowInfo.at(nIndex); - mapRobotInfo[nIndex / 1000].second.append(temp); - } - //<快速排序 - for(int nMapIndex(0); nMapIndex < mapRobotInfo.count(); nMapIndex++) - { - qucikSort(mapRobotInfo[nMapIndex].second, 0, mapRobotInfo[nMapIndex].second.count() - 1); - } - PAIRLISTROBOTINFO tempListInfo = mapRobotInfo[0]; - for(int nPairIndex(1); nPairIndex < mapRobotInfo.count(); nPairIndex++) - { - //<归并 - tempListInfo.first = 0; - mapRobotInfo[nPairIndex].first = 0; - while(mapRobotInfo[nPairIndex].first < mapRobotInfo[nPairIndex].second.count()) - { - if(tempListInfo.first >= tempListInfo.second.count()) - { - tempListInfo.second.append(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); - mapRobotInfo[nPairIndex].first += 1; - } - else - { - if(Qt::AscendingOrder == m_order) - { - if(!tempListInfo.second[tempListInfo.first]->lessThan(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first), m_sortKey)) - { - tempListInfo.second.insert(tempListInfo.first, mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); - mapRobotInfo[nPairIndex].first += 1; - } - } - else if(Qt::DescendingOrder == m_order) - { - if(!tempListInfo.second[tempListInfo.first]->moreThan(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first), m_sortKey)) - { - tempListInfo.second.insert(tempListInfo.first, mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); - mapRobotInfo[nPairIndex].first += 1; - } - } - } - tempListInfo.first += 1; - } - } - m_listShowInfo = tempListInfo.second; -} - -void CRobotCCDVideoItemModel::qucikSort(QList &list, int start, int last) -{ - int index; - while(start < last) - { - if(Qt::AscendingOrder == m_order) - { - index = partitionAscendingOrder(list, start, last); - } - else if(Qt::DescendingOrder == m_order) - { - index = partitionDescendingOrder(list, start, last); - } - qucikSort(list, start, index - 1); - start=index+1; //<尾优化 - } -} - -int CRobotCCDVideoItemModel::partitionAscendingOrder(QList &list, int start, int last) -{ - RobotFilePtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->lessThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftlessThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -int CRobotCCDVideoItemModel::partitionDescendingOrder(QList &list, int start, int last) -{ - RobotFilePtr info = list[start]; - int left = start; - int right = last; - while(left < right) - { - while(left < right && !list[right]->moreThan(info, m_sortKey)) - { - --right; - } - list[left] = list[right]; - - while(leftmoreThan(info, m_sortKey)) - { - ++left; - } - list[right] = list[left]; - } - list[left] = info; - return left; -} - -void CRobotCCDVideoItemModel::brush() -{ - beginResetModel(); - m_listShowInfo.clear(); - endResetModel(); - emit sigAllMsgAdd(); -} +#include "CRobotCCDVideoItemModel.h" +#include +#include "CRobotFileInfo.h" +#include "CRobotCommon.h" +#include +using namespace std; +typedef QPair > PAIRLISTROBOTINFO; + +CRobotCCDVideoItemModel::CRobotCCDVideoItemModel(QObject *parent) + : QAbstractTableModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::DescendingOrder), + m_searchText(QString()) +{ + m_header < >("ListRobotFilePtr"); +} + +QVariant CRobotCCDVideoItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +int CRobotCCDVideoItemModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + return m_listShowInfo.count(); +} + +int CRobotCCDVideoItemModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.count(); +} + +QVariant CRobotCCDVideoItemModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + if(Qt::TextAlignmentRole == role) + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + }else if(Qt::DisplayRole == role) + { + switch(index.column()) + { + case TIME: + { + return QDateTime::fromMSecsSinceEpoch(m_listShowInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd"); + } + case DEVICE: + { + return m_map[m_listShowInfo.at(index.row())->m_devgId]; + } + case TYPE: + { + if(E_ROBOT_CCD == m_listShowInfo.at(index.row())->m_fileType) + { + return tr("照片"); + }else if(E_ROBOT_CUT_CCD == m_listShowInfo.at(index.row())->m_fileType) + { + return tr("截图"); + }else if(E_ROBOT_VIDEO == m_listShowInfo.at(index.row())->m_fileType) + { + return tr("录像"); + } + } + default: + break; + } + } + return QVariant(); +} + +const QList CRobotCCDVideoItemModel::getShowList() const +{ + return m_listShowInfo; +} + +void CRobotCCDVideoItemModel::slotMsgAdd(const QList list) +{ + uint64 month = 3; + uint64 outTime = month*30*60*60*1000*24; + uint64 time = QDateTime::currentMSecsSinceEpoch(); + foreach (RobotFilePtr info,list) { + if(conditionFilter(info)) + { + if((time - outTime) < info->time_stamp) + { + insertMsg(info); + } + } + } +} + +void CRobotCCDVideoItemModel::slotMsgSub(const QList list) +{ + foreach (RobotFilePtr info,list) { + for(int nIndex = m_listShowInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowInfo.at(nIndex)->m_execPath == info->m_execPath) + { + beginRemoveRows(QModelIndex(), nIndex, nIndex); + m_listShowInfo.removeAt(nIndex); + endRemoveRows(); + break; + } + } + } +} + +void CRobotCCDVideoItemModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + + switch ((ColumnField)column) + { + case TIME: + { + m_sortKey = E_SORT_TIME; + break; + } + case DEVICE: + { + m_sortKey = E_SORT_DEV; + break; + } + case TYPE: + { + m_sortKey = E_SORT_TYPE; + break; + } + default: + break; + } + sort(); + beginResetModel(); + endResetModel(); +} + +void CRobotCCDVideoItemModel::slotFilte(QString text) +{ + m_searchText = text; + brush(); +} + +void CRobotCCDVideoItemModel::initialize(QMap devMap) +{ + m_listHorAlignmentFlags.clear(); + for (int nIndex(0); nIndex < m_header.size(); nIndex++) + { + m_listHorAlignmentFlags.append(Qt::AlignHCenter); + } + m_listShowInfo.clear(); + m_map.clear(); + m_map = devMap; +} + +bool CRobotCCDVideoItemModel::conditionFilter(const RobotFilePtr &info) +{ + if(m_searchText.isEmpty()) + { + return true; + } + std::string text =m_searchText.toStdString(); + //判断时间 + + std::string time = QDateTime::fromMSecsSinceEpoch(info->time_stamp).toString("yyyy-MM-dd").toStdString(); + if(time.find(text,0) != -1) + { + return true; + } + //判断设备组 + std::string dev = m_map[info->m_devgId].toStdString(); + + if(dev.find(text,0) != -1) + { + return true; + } + return false; +} + +void CRobotCCDVideoItemModel::insertMsg(const RobotFilePtr &info) +{ + int mid = -1; + int left = 0; + int right = m_listShowInfo.size() - 1; + while (left <= right) { + mid = (left + right) / 2; + if(Qt::AscendingOrder == m_order) + { + if(info->lessThan(m_listShowInfo[mid]),m_sortKey) + { + right = mid -1; + }else + { + left = mid + 1; + } + }else + { + if(m_listShowInfo[mid]->lessThan(info,m_sortKey)) + { + right = mid -1; + }else + { + left = mid + 1; + } + } + } + beginInsertRows(QModelIndex(),left,left); + m_listShowInfo.insert(left,info); + endInsertRows(); +} + +//<归并排序 +void CRobotCCDVideoItemModel::sort() +{ + QMap mapRobotInfo; + for(int nIndex(0); nIndex < m_listShowInfo.count(); nIndex++) + { + RobotFilePtr temp = m_listShowInfo.at(nIndex); + mapRobotInfo[nIndex / 1000].second.append(temp); + } + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapRobotInfo.count(); nMapIndex++) + { + qucikSort(mapRobotInfo[nMapIndex].second, 0, mapRobotInfo[nMapIndex].second.count() - 1); + } + PAIRLISTROBOTINFO tempListInfo = mapRobotInfo[0]; + for(int nPairIndex(1); nPairIndex < mapRobotInfo.count(); nPairIndex++) + { + //<归并 + tempListInfo.first = 0; + mapRobotInfo[nPairIndex].first = 0; + while(mapRobotInfo[nPairIndex].first < mapRobotInfo[nPairIndex].second.count()) + { + if(tempListInfo.first >= tempListInfo.second.count()) + { + tempListInfo.second.append(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); + mapRobotInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListInfo.second[tempListInfo.first]->lessThan(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first), m_sortKey)) + { + tempListInfo.second.insert(tempListInfo.first, mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); + mapRobotInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListInfo.second[tempListInfo.first]->moreThan(mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first), m_sortKey)) + { + tempListInfo.second.insert(tempListInfo.first, mapRobotInfo[nPairIndex].second.at(mapRobotInfo[nPairIndex].first)); + mapRobotInfo[nPairIndex].first += 1; + } + } + } + tempListInfo.first += 1; + } + } + m_listShowInfo = tempListInfo.second; +} + +void CRobotCCDVideoItemModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CRobotCCDVideoItemModel::partitionAscendingOrder(QList &list, int start, int last) +{ + RobotFilePtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CRobotCCDVideoItemModel::partitionDescendingOrder(QList &list, int start, int last) +{ + RobotFilePtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CRobotCCDVideoItemModel::brush() +{ + beginResetModel(); + m_listShowInfo.clear(); + endResetModel(); + emit sigAllMsgAdd(); +} diff --git a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoItemModel.h b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoItemModel.h index 4f50fa95..64827df2 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoItemModel.h +++ b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoItemModel.h @@ -1,60 +1,60 @@ -#ifndef CROBOTCCDVIDEOITEMMODEL_H -#define CROBOTCCDVIDEOITEMMODEL_H - -#include -#include "CRobotFileInfo.h" -class CRobotCCDVideoItemModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - enum ColumnField - { - TIME = 0, - DEVICE, - TYPE - }; - explicit CRobotCCDVideoItemModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - const QList getShowList() const; - - void initialize(QMap devMap); -signals: - void sigAllMsgAdd(); -public slots: - void slotMsgAdd(const QList list); - void slotMsgSub(const QList list); - - void sortColumn(int column, Qt::SortOrder order); - - void slotFilte(QString text); -private: - - bool conditionFilter(const RobotFilePtr &info); - void insertMsg(const RobotFilePtr &info); - void sort(); - void qucikSort(QList &list, int start, int last); - int partitionAscendingOrder(QList &list, int start, int last); - int partitionDescendingOrder(QList &list, int start, int last); - void brush(); - -private: - QStringList m_header; - QList m_listShowInfo; - QList m_listHorAlignmentFlags; //< 水平对齐方式 - E_ROBOT_SORTKEY m_sortKey; //排序规则 - Qt::SortOrder m_order; - QString m_searchText; - QMap m_map; -}; - -#endif // CROBOTCCDVIDEOITEMMODEL_H +#ifndef CROBOTCCDVIDEOITEMMODEL_H +#define CROBOTCCDVIDEOITEMMODEL_H + +#include +#include "CRobotFileInfo.h" +class CRobotCCDVideoItemModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + enum ColumnField + { + TIME = 0, + DEVICE, + TYPE + }; + explicit CRobotCCDVideoItemModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + const QList getShowList() const; + + void initialize(QMap devMap); +signals: + void sigAllMsgAdd(); +public slots: + void slotMsgAdd(const QList list); + void slotMsgSub(const QList list); + + void sortColumn(int column, Qt::SortOrder order); + + void slotFilte(QString text); +private: + + bool conditionFilter(const RobotFilePtr &info); + void insertMsg(const RobotFilePtr &info); + void sort(); + void qucikSort(QList &list, int start, int last); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + void brush(); + +private: + QStringList m_header; + QList m_listShowInfo; + QList m_listHorAlignmentFlags; //< 水平对齐方式 + E_ROBOT_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + QString m_searchText; + QMap m_map; +}; + +#endif // CROBOTCCDVIDEOITEMMODEL_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoView.cpp b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoView.cpp index e3690a74..43469bce 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoView.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoView.cpp @@ -1,26 +1,26 @@ -#include "CRobotCCDVideoView.h" -#include -#include -#include -CRobotCCDVideoView::CRobotCCDVideoView(QWidget *parent) - :QTableView(parent) -{ - -} - -void CRobotCCDVideoView::initialize() -{ - setSortingEnabled(true); - setAlternatingRowColors(true); - horizontalHeader()->setStretchLastSection(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); - setSelectionBehavior(QAbstractItemView::SelectRows); - //setSelectionMode(QAbstractItemView::MultiSelection); - setHorizontalScrollMode(ScrollPerPixel); - this->verticalHeader()->hide(); -} - -void CRobotCCDVideoView::mousePressEvent(QMouseEvent *event) -{ - QTableView::mousePressEvent(event); -} +#include "CRobotCCDVideoView.h" +#include +#include +#include +CRobotCCDVideoView::CRobotCCDVideoView(QWidget *parent) + :QTableView(parent) +{ + +} + +void CRobotCCDVideoView::initialize() +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + setSelectionBehavior(QAbstractItemView::SelectRows); + //setSelectionMode(QAbstractItemView::MultiSelection); + setHorizontalScrollMode(ScrollPerPixel); + this->verticalHeader()->hide(); +} + +void CRobotCCDVideoView::mousePressEvent(QMouseEvent *event) +{ + QTableView::mousePressEvent(event); +} diff --git a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoView.h b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoView.h index 4fc2352f..31dd7e18 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCCDVideoView.h +++ b/product/src/gui/plugin/RobotWidget/CRobotCCDVideoView.h @@ -1,17 +1,17 @@ -#ifndef CROBOTCCDVIDEOVIEW_H -#define CROBOTCCDVIDEOVIEW_H -#include - -class CRobotCCDVideoView : public QTableView -{ - Q_OBJECT -public: - CRobotCCDVideoView(QWidget *parent = Q_NULLPTR); - - void initialize(); - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; -}; - -#endif // CROBOTCCDVIDEOVIEW_H +#ifndef CROBOTCCDVIDEOVIEW_H +#define CROBOTCCDVIDEOVIEW_H +#include + +class CRobotCCDVideoView : public QTableView +{ + Q_OBJECT +public: + CRobotCCDVideoView(QWidget *parent = Q_NULLPTR); + + void initialize(); + +protected: + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; +}; + +#endif // CROBOTCCDVIDEOVIEW_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotCommon.h b/product/src/gui/plugin/RobotWidget/CRobotCommon.h index 9b303961..c7a7147d 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCommon.h +++ b/product/src/gui/plugin/RobotWidget/CRobotCommon.h @@ -1,27 +1,27 @@ -#ifndef CROBOTLINKCOMMON_H -#define CROBOTLINKCOMMON_H - -#include -#include "DataType.h" -class CRobotFileInfo; -class CRobotInfo; -typedef QSharedPointer RobotFilePtr; -typedef QSharedPointer RobotInfoPtr; -const std::string CN_RobotCtrlWidget = "CRobotLinkCtrlWidget";//当前进程名 - -#define DEV_TYPE "JQR" //设备类型表 - -enum E_ROBOT_FILE_TYPE -{ - E_ROBOT_CCD = 0, //图片 - E_ROBOT_CUT_CCD = 1, //截图 - E_ROBOT_VIDEO = 2, //视频 - -}; -enum E_ROBOT_SORTKEY -{ - E_SORT_TIME = 0, //< 文件 - E_SORT_DEV, //< 设备 - E_SORT_TYPE, //< 类型 -}; -#endif // CROBOTLINKCOMMON_H +#ifndef CROBOTLINKCOMMON_H +#define CROBOTLINKCOMMON_H + +#include +#include "DataType.h" +class CRobotFileInfo; +class CRobotInfo; +typedef QSharedPointer RobotFilePtr; +typedef QSharedPointer RobotInfoPtr; +const std::string CN_RobotCtrlWidget = "CRobotLinkCtrlWidget";//当前进程名 + +#define DEV_TYPE "JQR" //设备类型表 + +enum E_ROBOT_FILE_TYPE +{ + E_ROBOT_CCD = 0, //图片 + E_ROBOT_CUT_CCD = 1, //截图 + E_ROBOT_VIDEO = 2, //视频 + +}; +enum E_ROBOT_SORTKEY +{ + E_SORT_TIME = 0, //< 文件 + E_SORT_DEV, //< 设备 + E_SORT_TYPE, //< 类型 +}; +#endif // CROBOTLINKCOMMON_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.cpp b/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.cpp index 513f2bcf..9d9a46be 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.cpp @@ -1,631 +1,631 @@ -#include "CRobotCtrlWidget.h" -#include "SWitchButton.h" -#include "ui_CRobotCtrlWidget.h" -#include -#include -#include -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/TimeUtil.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" -#include -#include "operate_server_api/JsonOptCommand.h" - -using namespace kbd_net; -using namespace kbd_idlfile; -using namespace kbd_public; -using namespace std; -CRobotCtrlWidget::CRobotCtrlWidget(QWidget *parent) : - QWidget(parent), - m_needRecv(false), - m_timeOutTimes(0), - m_timer(Q_NULLPTR), - m_statusTimer(Q_NULLPTR), - m_recvThread(Q_NULLPTR), - m_queryThread(Q_NULLPTR), - m_pReadDb(Q_NULLPTR), - m_recv(Q_NULLPTR), - m_query(Q_NULLPTR), - ui(new Ui::CRobotCtrlWidget) -{ - ui->setupUi(this); - - ui->comboBox->setView(new QListView()); - m_robotid = -1; - m_queryThread = new QThread(this); - m_query = new OnTimeQueryThread(); - m_query->moveToThread(m_queryThread); - connect(m_queryThread,&QThread::started,this,&CRobotCtrlWidget::initOnTime,Qt::QueuedConnection); - connect(m_queryThread,&QThread::finished,m_queryThread,&QThread::deleteLater,Qt::QueuedConnection); - - m_recvThread = new QThread(this); - m_recv = new OnTimeRecvThread(); - m_recv->moveToThread(m_recvThread); - //connect(m_recvThread,&QThread::started,m_recv,&OnTimeRecvThread::init,Qt::QueuedConnection); - connect(m_recvThread,&QThread::finished,m_recvThread,&QThread::deleteLater,Qt::QueuedConnection); - connect(m_recv,&OnTimeRecvThread::sigCtrlResult,this,&CRobotCtrlWidget::showMessDialog,Qt::QueuedConnection); - - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - if(!m_pReadDb->open()) - { - LOGERROR("打开数据库失败!error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); - } - getSystemInfo(); - m_timer =new QTimer(this); - m_timer->setInterval(1000); - connect(m_timer,&QTimer::timeout,this,&CRobotCtrlWidget::execute); - m_statusTimer = new QTimer(this); - m_statusTimer->setInterval(2000); - connect(m_statusTimer,&QTimer::timeout,this,&CRobotCtrlWidget::onTimeSetRobotStatus,Qt::QueuedConnection); - ui->label_head->setText(tr("机器人状态")); - initGif(); - -} - -CRobotCtrlWidget::~CRobotCtrlWidget() -{ - if(m_timer) - { - m_timer->stop(); - m_timer->deleteLater(); - } - if(m_statusTimer) - { - m_statusTimer->stop(); - m_statusTimer->deleteLater(); - } - if(m_recvThread) - { - m_recvThread->quit(); - m_recvThread->wait(); - } - if(m_queryThread) - { - m_queryThread->quit(); - m_queryThread->wait(); - } - - delete ui; -} - -void CRobotCtrlWidget::initGif() -{ - m_movie_0.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/free.gif").c_str()); - m_movie_1.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/overlook.gif").c_str()); - m_movie_2.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/charge.gif").c_str()); - m_movie_3.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/overhaul.gif").c_str()); - - ui->label_free->setContentsMargins(0,0,0,0); - ui->label_free->setMovie(&m_movie_0); - ui->label_overlook->setMovie(&m_movie_1); - ui->label_charge->setMovie(&m_movie_2); - ui->label_overhaul->setMovie(&m_movie_3); - m_movie_0.start(); - m_movie_1.start(); - m_movie_2.start(); - m_movie_3.start(); -} - - -void CRobotCtrlWidget::initialize(int domain,int location) -{ - m_domain = domain; - m_location = location; - ui->comboBox->clear(); - //订阅通道 - connect(ui->switchButton,&SWitchButton::sigAlmLinkOpen,m_recv,&OnTimeRecvThread::slotAlmLinkOpen,Qt::QueuedConnection); - connect(m_recv,&OnTimeRecvThread::sigSetSwitchButtonUsed,ui->switchButton,&SWitchButton::slotSwitchButtonUsed,Qt::QueuedConnection); - connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(setRobotStatus(int)),Qt::QueuedConnection); - connect(ui->exetask,&QPushButton::clicked,this,&CRobotCtrlWidget::execTask); - loadData(); - dealData(); - QMap::iterator it = m_diMap.begin(); - while (it != m_diMap.end()) { - ui->comboBox->addItem(it.value(),it.key()); - it++; - } - m_recvThread->start(); - m_queryThread->start(); - m_statusTimer->start(); -} - -QMap CRobotCtrlWidget::getDiMap() -{ - return m_numMap; -} - -void CRobotCtrlWidget::initOnTime() -{ - m_query->init(m_robotInfoMap); -} - -void CRobotCtrlWidget::execTask() -{ - if(ui->comboBox->currentIndex() < 0) - { - LOGERROR("机器人控制任务不能为空!"); - return ; - } - QString tag = ui->comboBox->currentData().toString(); - ctrlRobot(tag); -} - -void CRobotCtrlWidget::execute() -{ - if(!m_timer->isActive()) - { - if(m_timer) - { - m_timer->stop(); - } - unSub(); - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - return ; - } - - if(m_timeOutTimes > m_ctrlTimeMap.value(m_tag,30)) - { - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - m_timer->stop(); - m_timeOutTimes = 0; - QString text = tr("执行任务超时!"); - showMessDialog(text); - unSub(); - return ; - } - - CMbMessage objMsg; - - while(m_objCommon.recvMsg(objMsg,0)) - { - switch (objMsg.getChannelID()) { - case CH_OPT_TO_HMI_OPTCMD_UP: - dealOptMsg(objMsg); - break; - default: - break; - } - } - - m_timeOutTimes++; -} - -void CRobotCtrlWidget::loadData() -{ - loadAllLocation(); - loadDevInfo(); - loadDi(); - loadMi(); - loadLocationDomain(); - loadCtrlTime(); -} - -void CRobotCtrlWidget::loadAllLocation() -{ - m_ltnVec.clear(); - if(m_domain != -1 && m_location != -1) - { - m_ltnVec.append(m_location); - }else if(m_domain != -1 &&m_location == -1) - { - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select location_id from %1 where domain_id = %2 order by location_no").arg("sys_model_location_info").arg(m_domain); - QSqlQuery query; - try - { - m_pReadDb->execute(sqlSequenceQuery, query); - } - catch(...) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - } - if(query.isActive()) - { - while(query.next()) - { - int location = query.value(0).toInt(); - m_ltnVec.append(location); - } - } - } - }else if(m_domain == -1) - { - m_ltnVec.clear(); - } -} - -void CRobotCtrlWidget::loadDevInfo() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select dev_type_id from %1 where tag_name = '%2'").arg("dev_type_def").arg(DEV_TYPE); - QSqlQuery query; - try - { - m_pReadDb->execute(sqlSequenceQuery, query); - } - catch(...) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - } - if(query.isActive()) - { - while(query.next()) - { - m_robotid = query.value(0).toInt(); - } - } - } -} - -void CRobotCtrlWidget::loadDi() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select tag_name, description,seq_no from %1 where dev_type = %2 ").arg("digital").arg(m_robotid); - if(m_ltnVec.size() != 0) - { - QString condition = QString(); - for(int index(0);indexexecute(sqlSequenceQuery, query); - } - catch(...) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - } - if(query.isActive()) - { - while(query.next()) - { - QString tag_name = query.value(0).toString(); - QString desc = query.value(1).toString(); - int devNum = query.value(2).toInt(); - m_diMap[tag_name] = desc; - m_numMap[devNum] = desc; - } - } - } -} - -void CRobotCtrlWidget::loadMi() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select tag_name,location_id,sub_system,value from %1 where dev_type = %2 ").arg("analog").arg(m_robotid); - if(m_ltnVec.size() != 0) - { - QString condition = QString(); - for(int index(0);indexexecute(sqlSequenceQuery, query); - } - catch(...) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - } - if(query.isActive()) - { - while(query.next()) - { - QString tag_name = query.value(0).toString(); - int location = query.value(1).toInt(); - int sub = query.value(2).toInt(); - int status = query.value(3).toInt(); - RobotInfoPtr robot(new CRobotInfo()); - robot->initialize(tag_name,sub,location,status); - m_robotInfoMap[tag_name] = robot; - } - } - } -} - -void CRobotCtrlWidget::loadLocationDomain() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select location_id,domain_id from %1 order by location_no").arg("sys_model_location_info"); - - QSqlQuery query; - try - { - m_pReadDb->execute(sqlSequenceQuery, query); - } - catch(...) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - } - if(query.isActive()) - { - while(query.next()) - { - m_ltnDomainMap[query.value(0).toInt()] = query.value(1).toInt(); - } - } - } -} - -void CRobotCtrlWidget::loadCtrlTime() -{ - if(m_pReadDb->isOpen()) - { - QString sqlSequenceQuery = QString("select tag_name,ctrl_timeout,is_tagt_state from %1 ").arg("digital_control"); - if(m_ltnVec.size() != 0) - { - QString condition = QString(); - for(int index(0);indexexecute(sqlSequenceQuery, query); - } - catch(...) - { - LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); - } - if(query.isActive()) - { - while(query.next()) - { - m_ctrlTimeMap[query.value(0).toString()] = query.value(1).toInt(); - m_ctrlStateMap[query.value(0).toString()] = query.value(2).toInt(); - } - } - } -} - -void CRobotCtrlWidget::dealData() -{ - QMap::iterator it = m_robotInfoMap.begin(); - while (it != m_robotInfoMap.end()) { - it.value()->m_domain = m_ltnDomainMap[it.value()->m_location]; - it++; - } - foreach (QString di, m_diMap.keys()) { - QStringList listDi =di.split("."); - foreach (QString ai, m_robotInfoMap.keys()) { - QStringList listAi =ai.split("."); - if(listDi.at(0) == listAi.at(0) && listDi.at(1) == listAi.at(1)) - { - m_diaiMap[di] = ai; - break; - } - } - } -} - -void CRobotCtrlWidget::ctrlRobot(QString &pointTag) -{ - LOGDEBUG("开始控制机器人执行任务,点标签为[%s]",pointTag.toStdString().c_str()); - - SOptCtrlRequest stCtrlCmd; - stCtrlCmd.stHead.strSrcTag = CN_RobotCtrlWidget; - QString ai =m_diaiMap.value(pointTag,QString()); - if(ai.isEmpty()) - { - QString text = tr("未找到控制点[%s]").arg(pointTag); - showMessDialog(text); - return ; - } - RobotInfoPtr ptr = m_robotInfoMap.value(ai,NULL); - stCtrlCmd.stHead.nSrcDomainID = m_stLocalNodeInfo.nDomainId; - stCtrlCmd.stHead.nDstDomainID = ptr ? ptr->m_domain : -1; - stCtrlCmd.stHead.nAppID = ptr ? ptr->m_sub : -1; - stCtrlCmd.stHead.strHostName = m_stLocalNodeInfo.strName ; - stCtrlCmd.stHead.strInstName = CN_RobotCtrlWidget; - stCtrlCmd.stHead.strCommName = m_objCommon.getName(); - stCtrlCmd.stHead.nOptTime = getUTCTimeMsec(); - - SOptCtrlReqQueue reqQueue; - QString tag = "digital."+pointTag+".value"; - reqQueue.strKeyIdTag = tag.toStdString(); - reqQueue.nCtrlType = CTRL_MODE_COMMONCTRL; - reqQueue.dTargetValue = 0; - reqQueue.nCtrlActType = -1; - reqQueue.strOffsetNo = "-1"; - reqQueue.bIsDeviceOccupy = false; - reqQueue.bIsGenAlarm = false; - reqQueue.bCheckInterLock = false; - - stCtrlCmd.vecOptCtrlQueue.push_back(reqQueue); - COptCtrlRequest objReq; - std::string strMsg = objReq.generate(stCtrlCmd); - if (strMsg.empty()) - { - LOGERROR("生成控制命令失败"); - return ; - } - CMbMessage objMsg; - objMsg.setMsgType(MT_OPT_AUTO_CTRL_DOWN); //指定消息类型 - objMsg.setSubject(ptr ? ptr->m_sub : -1,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 - objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff - m_tag = tag; - - if(m_ctrlStateMap.value(m_tag,1) > 0 ) - { - sub(); - m_timer->start(); - ui->exetask->setEnabled(false); - ui->comboBox->setEnabled(false); - } - if(!m_objCommon.sendMsgToDomain(objMsg,ptr ? ptr->m_domain : -1)) - { - unSub(); - m_timer->stop(); - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - qDebug()<<"发送消息失败.AppId=[%d],CH=[%d]"; - LOGERROR("发送消息失败.AppId=[%d],CH=[%d]",ptr ? ptr->m_sub : -1, CH_HMI_TO_OPT_OPTCMD_DOWN); - return ; - } -} - -bool CRobotCtrlWidget::getSystemInfo() -{ - if(!createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("创建系统信息访问库失败"); - return false; - } - if(kbdSuccess != m_ptrSysInfo->getLocalNodeInfo(m_stLocalNodeInfo)) - { - LOGERROR("获取系统信息失败"); - return false; - } - return true; -} - -void CRobotCtrlWidget::sub() -{ - //目前先订阅所有的应用 - if(!m_objCommon.addSub(0,CH_OPT_TO_HMI_OPTCMD_UP)) - { - LOGERROR("通道[CH_OPT_TO_HMI_OPTCMD_UP]订阅失败."); - }else - { - LOGINFO("通道[CH_OPT_TO_HMI_OPTCMD_UP]订阅成功."); - } -} - -void CRobotCtrlWidget::unSub() -{ - std::vector vecSub =m_objCommon.getMySub(); - for(size_t i=0;istop(); - unSub(); - m_timeOutTimes = 0; - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - return; - }else - { - QString text = QString::fromStdString(stOptCtrlReply.stHead.strResultStr); - showMessDialog(text); - m_timer->stop(); - unSub(); - m_timeOutTimes = 0; - ui->exetask->setEnabled(true); - ui->comboBox->setEnabled(true); - } - return; -} - -void CRobotCtrlWidget::setRobotStatus(int index) -{ - Q_UNUSED(index) - // 5-- 不知到状态 1-- 空闲状态 2--巡检状态 3--充电状态 4-- 检修状态 - - QString tag = ui->comboBox->currentData().toString(); - QString miTag = m_diaiMap.value(tag); - int status = m_query->getStatus(miTag); - if(status >=5 || status < 1 ) - { - LOGERROR("状态[%d]非法!默认为空闲状态!",status); - status = 1; - } - ui->stackedWidget->setCurrentIndex(status-1); -} - -void CRobotCtrlWidget::onTimeSetRobotStatus() -{ - QString tag = ui->comboBox->currentData().toString(); - QString miTag = m_diaiMap.value(tag); - int status = m_query->getStatus(miTag); - if(status >=5 || status < 1 ) - { - LOGERROR("状态[%d]非法!默认为空闲状态!",status); - status = 1; - } - ui->stackedWidget->setCurrentIndex(status-1); -} - -void CRobotCtrlWidget::showMessDialog(QString text) -{ - QMessageBox::warning(this, QObject::tr("警告"), text, QMessageBox::Ok); -} +#include "CRobotCtrlWidget.h" +#include "SWitchButton.h" +#include "ui_CRobotCtrlWidget.h" +#include +#include +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/TimeUtil.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include +#include "operate_server_api/JsonOptCommand.h" + +using namespace kbd_net; +using namespace kbd_idlfile; +using namespace kbd_public; +using namespace std; +CRobotCtrlWidget::CRobotCtrlWidget(QWidget *parent) : + QWidget(parent), + m_needRecv(false), + m_timeOutTimes(0), + m_timer(Q_NULLPTR), + m_statusTimer(Q_NULLPTR), + m_recvThread(Q_NULLPTR), + m_queryThread(Q_NULLPTR), + m_pReadDb(Q_NULLPTR), + m_recv(Q_NULLPTR), + m_query(Q_NULLPTR), + ui(new Ui::CRobotCtrlWidget) +{ + ui->setupUi(this); + + ui->comboBox->setView(new QListView()); + m_robotid = -1; + m_queryThread = new QThread(this); + m_query = new OnTimeQueryThread(); + m_query->moveToThread(m_queryThread); + connect(m_queryThread,&QThread::started,this,&CRobotCtrlWidget::initOnTime,Qt::QueuedConnection); + connect(m_queryThread,&QThread::finished,m_queryThread,&QThread::deleteLater,Qt::QueuedConnection); + + m_recvThread = new QThread(this); + m_recv = new OnTimeRecvThread(); + m_recv->moveToThread(m_recvThread); + //connect(m_recvThread,&QThread::started,m_recv,&OnTimeRecvThread::init,Qt::QueuedConnection); + connect(m_recvThread,&QThread::finished,m_recvThread,&QThread::deleteLater,Qt::QueuedConnection); + connect(m_recv,&OnTimeRecvThread::sigCtrlResult,this,&CRobotCtrlWidget::showMessDialog,Qt::QueuedConnection); + + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + LOGERROR("打开数据库失败!error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); + } + getSystemInfo(); + m_timer =new QTimer(this); + m_timer->setInterval(1000); + connect(m_timer,&QTimer::timeout,this,&CRobotCtrlWidget::execute); + m_statusTimer = new QTimer(this); + m_statusTimer->setInterval(2000); + connect(m_statusTimer,&QTimer::timeout,this,&CRobotCtrlWidget::onTimeSetRobotStatus,Qt::QueuedConnection); + ui->label_head->setText(tr("机器人状态")); + initGif(); + +} + +CRobotCtrlWidget::~CRobotCtrlWidget() +{ + if(m_timer) + { + m_timer->stop(); + m_timer->deleteLater(); + } + if(m_statusTimer) + { + m_statusTimer->stop(); + m_statusTimer->deleteLater(); + } + if(m_recvThread) + { + m_recvThread->quit(); + m_recvThread->wait(); + } + if(m_queryThread) + { + m_queryThread->quit(); + m_queryThread->wait(); + } + + delete ui; +} + +void CRobotCtrlWidget::initGif() +{ + m_movie_0.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/free.gif").c_str()); + m_movie_1.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/overlook.gif").c_str()); + m_movie_2.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/charge.gif").c_str()); + m_movie_3.setFileName(kbd_public::CFileUtil::getPathOfResFile("gui/icon/robot/overhaul.gif").c_str()); + + ui->label_free->setContentsMargins(0,0,0,0); + ui->label_free->setMovie(&m_movie_0); + ui->label_overlook->setMovie(&m_movie_1); + ui->label_charge->setMovie(&m_movie_2); + ui->label_overhaul->setMovie(&m_movie_3); + m_movie_0.start(); + m_movie_1.start(); + m_movie_2.start(); + m_movie_3.start(); +} + + +void CRobotCtrlWidget::initialize(int domain,int location) +{ + m_domain = domain; + m_location = location; + ui->comboBox->clear(); + //订阅通道 + connect(ui->switchButton,&SWitchButton::sigAlmLinkOpen,m_recv,&OnTimeRecvThread::slotAlmLinkOpen,Qt::QueuedConnection); + connect(m_recv,&OnTimeRecvThread::sigSetSwitchButtonUsed,ui->switchButton,&SWitchButton::slotSwitchButtonUsed,Qt::QueuedConnection); + connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(setRobotStatus(int)),Qt::QueuedConnection); + connect(ui->exetask,&QPushButton::clicked,this,&CRobotCtrlWidget::execTask); + loadData(); + dealData(); + QMap::iterator it = m_diMap.begin(); + while (it != m_diMap.end()) { + ui->comboBox->addItem(it.value(),it.key()); + it++; + } + m_recvThread->start(); + m_queryThread->start(); + m_statusTimer->start(); +} + +QMap CRobotCtrlWidget::getDiMap() +{ + return m_numMap; +} + +void CRobotCtrlWidget::initOnTime() +{ + m_query->init(m_robotInfoMap); +} + +void CRobotCtrlWidget::execTask() +{ + if(ui->comboBox->currentIndex() < 0) + { + LOGERROR("机器人控制任务不能为空!"); + return ; + } + QString tag = ui->comboBox->currentData().toString(); + ctrlRobot(tag); +} + +void CRobotCtrlWidget::execute() +{ + if(!m_timer->isActive()) + { + if(m_timer) + { + m_timer->stop(); + } + unSub(); + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + return ; + } + + if(m_timeOutTimes > m_ctrlTimeMap.value(m_tag,30)) + { + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + m_timer->stop(); + m_timeOutTimes = 0; + QString text = tr("执行任务超时!"); + showMessDialog(text); + unSub(); + return ; + } + + CMbMessage objMsg; + + while(m_objCommon.recvMsg(objMsg,0)) + { + switch (objMsg.getChannelID()) { + case CH_OPT_TO_HMI_OPTCMD_UP: + dealOptMsg(objMsg); + break; + default: + break; + } + } + + m_timeOutTimes++; +} + +void CRobotCtrlWidget::loadData() +{ + loadAllLocation(); + loadDevInfo(); + loadDi(); + loadMi(); + loadLocationDomain(); + loadCtrlTime(); +} + +void CRobotCtrlWidget::loadAllLocation() +{ + m_ltnVec.clear(); + if(m_domain != -1 && m_location != -1) + { + m_ltnVec.append(m_location); + }else if(m_domain != -1 &&m_location == -1) + { + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select location_id from %1 where domain_id = %2 order by location_no").arg("sys_model_location_info").arg(m_domain); + QSqlQuery query; + try + { + m_pReadDb->execute(sqlSequenceQuery, query); + } + catch(...) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + } + if(query.isActive()) + { + while(query.next()) + { + int location = query.value(0).toInt(); + m_ltnVec.append(location); + } + } + } + }else if(m_domain == -1) + { + m_ltnVec.clear(); + } +} + +void CRobotCtrlWidget::loadDevInfo() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select dev_type_id from %1 where tag_name = '%2'").arg("dev_type_def").arg(DEV_TYPE); + QSqlQuery query; + try + { + m_pReadDb->execute(sqlSequenceQuery, query); + } + catch(...) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + } + if(query.isActive()) + { + while(query.next()) + { + m_robotid = query.value(0).toInt(); + } + } + } +} + +void CRobotCtrlWidget::loadDi() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select tag_name, description,seq_no from %1 where dev_type = %2 ").arg("digital").arg(m_robotid); + if(m_ltnVec.size() != 0) + { + QString condition = QString(); + for(int index(0);indexexecute(sqlSequenceQuery, query); + } + catch(...) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + } + if(query.isActive()) + { + while(query.next()) + { + QString tag_name = query.value(0).toString(); + QString desc = query.value(1).toString(); + int devNum = query.value(2).toInt(); + m_diMap[tag_name] = desc; + m_numMap[devNum] = desc; + } + } + } +} + +void CRobotCtrlWidget::loadMi() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select tag_name,location_id,sub_system,value from %1 where dev_type = %2 ").arg("analog").arg(m_robotid); + if(m_ltnVec.size() != 0) + { + QString condition = QString(); + for(int index(0);indexexecute(sqlSequenceQuery, query); + } + catch(...) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + } + if(query.isActive()) + { + while(query.next()) + { + QString tag_name = query.value(0).toString(); + int location = query.value(1).toInt(); + int sub = query.value(2).toInt(); + int status = query.value(3).toInt(); + RobotInfoPtr robot(new CRobotInfo()); + robot->initialize(tag_name,sub,location,status); + m_robotInfoMap[tag_name] = robot; + } + } + } +} + +void CRobotCtrlWidget::loadLocationDomain() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select location_id,domain_id from %1 order by location_no").arg("sys_model_location_info"); + + QSqlQuery query; + try + { + m_pReadDb->execute(sqlSequenceQuery, query); + } + catch(...) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + } + if(query.isActive()) + { + while(query.next()) + { + m_ltnDomainMap[query.value(0).toInt()] = query.value(1).toInt(); + } + } + } +} + +void CRobotCtrlWidget::loadCtrlTime() +{ + if(m_pReadDb->isOpen()) + { + QString sqlSequenceQuery = QString("select tag_name,ctrl_timeout,is_tagt_state from %1 ").arg("digital_control"); + if(m_ltnVec.size() != 0) + { + QString condition = QString(); + for(int index(0);indexexecute(sqlSequenceQuery, query); + } + catch(...) + { + LOGERROR("数据库操作失败![%s]",sqlSequenceQuery.toStdString().c_str()); + } + if(query.isActive()) + { + while(query.next()) + { + m_ctrlTimeMap[query.value(0).toString()] = query.value(1).toInt(); + m_ctrlStateMap[query.value(0).toString()] = query.value(2).toInt(); + } + } + } +} + +void CRobotCtrlWidget::dealData() +{ + QMap::iterator it = m_robotInfoMap.begin(); + while (it != m_robotInfoMap.end()) { + it.value()->m_domain = m_ltnDomainMap[it.value()->m_location]; + it++; + } + foreach (QString di, m_diMap.keys()) { + QStringList listDi =di.split("."); + foreach (QString ai, m_robotInfoMap.keys()) { + QStringList listAi =ai.split("."); + if(listDi.at(0) == listAi.at(0) && listDi.at(1) == listAi.at(1)) + { + m_diaiMap[di] = ai; + break; + } + } + } +} + +void CRobotCtrlWidget::ctrlRobot(QString &pointTag) +{ + LOGDEBUG("开始控制机器人执行任务,点标签为[%s]",pointTag.toStdString().c_str()); + + SOptCtrlRequest stCtrlCmd; + stCtrlCmd.stHead.strSrcTag = CN_RobotCtrlWidget; + QString ai =m_diaiMap.value(pointTag,QString()); + if(ai.isEmpty()) + { + QString text = tr("未找到控制点[%s]").arg(pointTag); + showMessDialog(text); + return ; + } + RobotInfoPtr ptr = m_robotInfoMap.value(ai,NULL); + stCtrlCmd.stHead.nSrcDomainID = m_stLocalNodeInfo.nDomainId; + stCtrlCmd.stHead.nDstDomainID = ptr ? ptr->m_domain : -1; + stCtrlCmd.stHead.nAppID = ptr ? ptr->m_sub : -1; + stCtrlCmd.stHead.strHostName = m_stLocalNodeInfo.strName ; + stCtrlCmd.stHead.strInstName = CN_RobotCtrlWidget; + stCtrlCmd.stHead.strCommName = m_objCommon.getName(); + stCtrlCmd.stHead.nOptTime = getUTCTimeMsec(); + + SOptCtrlReqQueue reqQueue; + QString tag = "digital."+pointTag+".value"; + reqQueue.strKeyIdTag = tag.toStdString(); + reqQueue.nCtrlType = CTRL_MODE_COMMONCTRL; + reqQueue.dTargetValue = 0; + reqQueue.nCtrlActType = -1; + reqQueue.strOffsetNo = "-1"; + reqQueue.bIsDeviceOccupy = false; + reqQueue.bIsGenAlarm = false; + reqQueue.bCheckInterLock = false; + + stCtrlCmd.vecOptCtrlQueue.push_back(reqQueue); + COptCtrlRequest objReq; + std::string strMsg = objReq.generate(stCtrlCmd); + if (strMsg.empty()) + { + LOGERROR("生成控制命令失败"); + return ; + } + CMbMessage objMsg; + objMsg.setMsgType(MT_OPT_AUTO_CTRL_DOWN); //指定消息类型 + objMsg.setSubject(ptr ? ptr->m_sub : -1,CH_HMI_TO_OPT_OPTCMD_DOWN); //下发通道 + objMsg.setData(strMsg); //设置需要发送数据 TO Protobuff + m_tag = tag; + + if(m_ctrlStateMap.value(m_tag,1) > 0 ) + { + sub(); + m_timer->start(); + ui->exetask->setEnabled(false); + ui->comboBox->setEnabled(false); + } + if(!m_objCommon.sendMsgToDomain(objMsg,ptr ? ptr->m_domain : -1)) + { + unSub(); + m_timer->stop(); + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + qDebug()<<"发送消息失败.AppId=[%d],CH=[%d]"; + LOGERROR("发送消息失败.AppId=[%d],CH=[%d]",ptr ? ptr->m_sub : -1, CH_HMI_TO_OPT_OPTCMD_DOWN); + return ; + } +} + +bool CRobotCtrlWidget::getSystemInfo() +{ + if(!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库失败"); + return false; + } + if(kbdSuccess != m_ptrSysInfo->getLocalNodeInfo(m_stLocalNodeInfo)) + { + LOGERROR("获取系统信息失败"); + return false; + } + return true; +} + +void CRobotCtrlWidget::sub() +{ + //目前先订阅所有的应用 + if(!m_objCommon.addSub(0,CH_OPT_TO_HMI_OPTCMD_UP)) + { + LOGERROR("通道[CH_OPT_TO_HMI_OPTCMD_UP]订阅失败."); + }else + { + LOGINFO("通道[CH_OPT_TO_HMI_OPTCMD_UP]订阅成功."); + } +} + +void CRobotCtrlWidget::unSub() +{ + std::vector vecSub =m_objCommon.getMySub(); + for(size_t i=0;istop(); + unSub(); + m_timeOutTimes = 0; + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + return; + }else + { + QString text = QString::fromStdString(stOptCtrlReply.stHead.strResultStr); + showMessDialog(text); + m_timer->stop(); + unSub(); + m_timeOutTimes = 0; + ui->exetask->setEnabled(true); + ui->comboBox->setEnabled(true); + } + return; +} + +void CRobotCtrlWidget::setRobotStatus(int index) +{ + Q_UNUSED(index) + // 5-- 不知到状态 1-- 空闲状态 2--巡检状态 3--充电状态 4-- 检修状态 + + QString tag = ui->comboBox->currentData().toString(); + QString miTag = m_diaiMap.value(tag); + int status = m_query->getStatus(miTag); + if(status >=5 || status < 1 ) + { + LOGERROR("状态[%d]非法!默认为空闲状态!",status); + status = 1; + } + ui->stackedWidget->setCurrentIndex(status-1); +} + +void CRobotCtrlWidget::onTimeSetRobotStatus() +{ + QString tag = ui->comboBox->currentData().toString(); + QString miTag = m_diaiMap.value(tag); + int status = m_query->getStatus(miTag); + if(status >=5 || status < 1 ) + { + LOGERROR("状态[%d]非法!默认为空闲状态!",status); + status = 1; + } + ui->stackedWidget->setCurrentIndex(status-1); +} + +void CRobotCtrlWidget::showMessDialog(QString text) +{ + QMessageBox::warning(this, QObject::tr("警告"), text, QMessageBox::Ok); +} diff --git a/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.h b/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.h index 9812c0a0..8ea879e3 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.h +++ b/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.h @@ -1,113 +1,113 @@ -#ifndef CROBOTCTRLWIDGET_H -#define CROBOTCTRLWIDGET_H - -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "db_api_ex/CDbApi.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include -#include "OnTimeQueryThread.h" -#include "OnTimeRecvThread.h" -#include -class QTimer; -class SWitchButton; - -namespace Ui { -class CRobotCtrlWidget; -} - -class CRobotCtrlWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CRobotCtrlWidget(QWidget *parent = 0); - ~CRobotCtrlWidget(); - - void initGif(); - void initialize(int domain, int location); - /** - * @brief getDiMap 获取数字量map - * @return - */ - QMap getDiMap(); -public slots: - void setRobotStatus(int index); - void onTimeSetRobotStatus(); - /** - * @brief showMessDialog 弹窗提示 - * @param text - */ - void showMessDialog(QString text); -private slots: - /** - * @brief initOnTime 初始化定时采集机器人状态线程 - */ - void initOnTime(); - /** - * @brief execTask 执行任务 - */ - void execTask(); - /** - * @brief checkOutTime 检查执行任务是否超时 - */ - void execute(); -private: - void loadData(); - void loadAllLocation(); - void loadDevInfo(); - void loadDi(); - void loadMi(); - void loadLocationDomain(); - void loadCtrlTime(); - void dealData(); - void ctrlRobot(QString &pointTag); - bool getSystemInfo(); - void sub(); - void unSub(); - - void dealOptMsg(const kbd_net::CMbMessage &objMsg); - - void parseMsg(const kbd_net::CMbMessage &objMsg); -private: - Ui::CRobotCtrlWidget *ui; - - kbd_dbms::CDbApi * m_pReadDb; - - QMap m_diMap; //< - QMap m_numMap; //< <设备点号,描述> - QMap m_robotInfoMap; //< - - QMap m_diaiMap; // - - QMap m_ltnDomainMap; // <车站id,域id> - QMap m_ctrlTimeMap; // - QMap m_ctrlStateMap; // - int m_location; - int m_domain; - bool m_needRecv; - QThread *m_queryThread; - QThread *m_recvThread; - OnTimeQueryThread *m_query; - OnTimeRecvThread *m_recv; - - - kbd_public::SNodeInfo m_stLocalNodeInfo; //本机节点信息 - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; //创建系统信息访问智能库指针 - - kbd_net::CMbCommunicator m_objCommon; - QString m_tag; - int m_timeOutTimes; - QTimer *m_timer; //等待超时定时器 - QTimer *m_statusTimer; //定时更新机器人状态定时器 - - QVector m_ltnVec; - int m_robotid; - - QMovie m_movie_0; - QMovie m_movie_1; - QMovie m_movie_2; - QMovie m_movie_3; -}; - -#endif // CROBOTCTRLWIDGET_H +#ifndef CROBOTCTRLWIDGET_H +#define CROBOTCTRLWIDGET_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "db_api_ex/CDbApi.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include +#include "OnTimeQueryThread.h" +#include "OnTimeRecvThread.h" +#include +class QTimer; +class SWitchButton; + +namespace Ui { +class CRobotCtrlWidget; +} + +class CRobotCtrlWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CRobotCtrlWidget(QWidget *parent = 0); + ~CRobotCtrlWidget(); + + void initGif(); + void initialize(int domain, int location); + /** + * @brief getDiMap 获取数字量map + * @return + */ + QMap getDiMap(); +public slots: + void setRobotStatus(int index); + void onTimeSetRobotStatus(); + /** + * @brief showMessDialog 弹窗提示 + * @param text + */ + void showMessDialog(QString text); +private slots: + /** + * @brief initOnTime 初始化定时采集机器人状态线程 + */ + void initOnTime(); + /** + * @brief execTask 执行任务 + */ + void execTask(); + /** + * @brief checkOutTime 检查执行任务是否超时 + */ + void execute(); +private: + void loadData(); + void loadAllLocation(); + void loadDevInfo(); + void loadDi(); + void loadMi(); + void loadLocationDomain(); + void loadCtrlTime(); + void dealData(); + void ctrlRobot(QString &pointTag); + bool getSystemInfo(); + void sub(); + void unSub(); + + void dealOptMsg(const kbd_net::CMbMessage &objMsg); + + void parseMsg(const kbd_net::CMbMessage &objMsg); +private: + Ui::CRobotCtrlWidget *ui; + + kbd_dbms::CDbApi * m_pReadDb; + + QMap m_diMap; //< + QMap m_numMap; //< <设备点号,描述> + QMap m_robotInfoMap; //< + + QMap m_diaiMap; // + + QMap m_ltnDomainMap; // <车站id,域id> + QMap m_ctrlTimeMap; // + QMap m_ctrlStateMap; // + int m_location; + int m_domain; + bool m_needRecv; + QThread *m_queryThread; + QThread *m_recvThread; + OnTimeQueryThread *m_query; + OnTimeRecvThread *m_recv; + + + kbd_public::SNodeInfo m_stLocalNodeInfo; //本机节点信息 + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; //创建系统信息访问智能库指针 + + kbd_net::CMbCommunicator m_objCommon; + QString m_tag; + int m_timeOutTimes; + QTimer *m_timer; //等待超时定时器 + QTimer *m_statusTimer; //定时更新机器人状态定时器 + + QVector m_ltnVec; + int m_robotid; + + QMovie m_movie_0; + QMovie m_movie_1; + QMovie m_movie_2; + QMovie m_movie_3; +}; + +#endif // CROBOTCTRLWIDGET_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.ui b/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.ui index e08efb2e..2c73c4fd 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.ui +++ b/product/src/gui/plugin/RobotWidget/CRobotCtrlWidget.ui @@ -1,960 +1,960 @@ - - - CRobotCtrlWidget - - - - 0 - 0 - 270 - 705 - - - - - 0 - 0 - - - - Form - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 10 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 50 - 20 - - - - - 50 - 16777215 - - - - - - - - - 0 - - - 13 - - - 0 - - - 0 - - - 0 - - - 10 - - - - - - 0 - 30 - - - - - 请选择设备 - - - - - - - - - 0 - 30 - - - - 执行任务 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 40 - - - - - - - - - - Qt::AlignCenter - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 450 - - - - - 16777215 - 450 - - - - 0 - - - - - 0 - 450 - - - - - 16777215 - 450 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - - - - - - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - 空闲中 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - 巡检中 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - 充电中 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 330 - - - - - 16777215 - 330 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - 检修中 - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 0 - 20 - - - - - 16777215 - 16777215 - - - - 告警联动: - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - - Qt::Vertical - - - - 20 - 27 - - - - - - - - - SWitchButton - QWidget -
SWitchButton.h
- 1 -
-
- - -
+ + + CRobotCtrlWidget + + + + 0 + 0 + 270 + 705 + + + + + 0 + 0 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 10 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 50 + 20 + + + + + 50 + 16777215 + + + + + + + + + 0 + + + 13 + + + 0 + + + 0 + + + 0 + + + 10 + + + + + + 0 + 30 + + + + + 请选择设备 + + + + + + + + + 0 + 30 + + + + 执行任务 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 40 + + + + + + + + + + Qt::AlignCenter + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 450 + + + + + 16777215 + 450 + + + + 0 + + + + + 0 + 450 + + + + + 16777215 + 450 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + 空闲中 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 巡检中 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 充电中 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 330 + + + + + 16777215 + 330 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 检修中 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 0 + 20 + + + + + 16777215 + 16777215 + + + + 告警联动: + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 27 + + + + + + + + + SWitchButton + QWidget +
SWitchButton.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/RobotWidget/CRobotFileCollect.cpp b/product/src/gui/plugin/RobotWidget/CRobotFileCollect.cpp index 767797b3..d8b43d34 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotFileCollect.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotFileCollect.cpp @@ -1,120 +1,120 @@ -#include "CRobotFileCollect.h" -#include -#include "Common.h" -#include "pub_logger_api/logger.h" -#include -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CommonConfigParse.h" - -using namespace kbd_public; - -CRobotFileCollect::CRobotFileCollect(QObject *parent): - QObject(parent), - m_time(NULL) -{ - -} - -CRobotFileCollect::~CRobotFileCollect() -{ - release(); -} - -void CRobotFileCollect::initialize() -{ - loadConfig(); - if(!m_time) - { - m_time = new QTimer(); - m_time->setInterval(2000); - connect(this,&CRobotFileCollect::sigTimerShot,this,&CRobotFileCollect::slotTimerShot,Qt::QueuedConnection); - connect(m_time,&QTimer::timeout,this,&CRobotFileCollect::onTimeLoadFile,Qt::QueuedConnection); - } - emit sigTimerShot(true); -} - -void CRobotFileCollect::release() -{ - emit sigTimerShot(false); - m_time->blockSignals(true); - if(m_time != Q_NULLPTR) - { - m_time->stop(); - m_time = Q_NULLPTR; - } -} - -void CRobotFileCollect::loadConfig() -{ - CCommonConfigParse config; - const std::string file = kbd_public::CFileUtil::getPathOfCfgFile("robot_config.xml"); - std::string loadFilePath; - config.load(file); - int error = config.getStringValue("robot_config","loadFilePath",loadFilePath); - if( error != kbdSuccess) - { - m_path = "../../data/test";; - LOGERROR("机器人加载文件路径解析失败!文件[%s],错误码[%d]",file.c_str(),error); - }else - { - m_path = QString::fromStdString(loadFilePath); - } - qDebug()<<"path:"<start(); - }else - { - m_time->stop(); - } - } -} - -void CRobotFileCollect::onTimeLoadFile() -{ - QFileInfoList fileList = getFileList(m_path); - QMap map; - for (int i = 0; i < fileList.size(); ++i) - { - QFileInfo fileInfo = fileList.at(i); - RobotFilePtr robotFile(new CRobotFileInfo()); - if(robotFile->initialize(fileInfo) == kbdSuccess) - { - map.insert(robotFile->m_execPath,robotFile); - - }else - { - LOGERROR("解析文件错误!"); - } - } - if(map.size() > 0) - { - emit sigUpdateFile(map); - } - map.clear(); - //查询内存库 -} - -QFileInfoList CRobotFileCollect::getFileList(const QString &path) -{ - QDir dir(path); - QFileInfoList file_list = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks); - QFileInfoList folder_list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - - for(int i = 0; i != folder_list.size(); i++) - { - QString name = folder_list.at(i).absoluteFilePath(); - - QFileInfoList child_file_list = getFileList(name); - file_list.append(child_file_list); - } - - return file_list; -} - +#include "CRobotFileCollect.h" +#include +#include "Common.h" +#include "pub_logger_api/logger.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CommonConfigParse.h" + +using namespace kbd_public; + +CRobotFileCollect::CRobotFileCollect(QObject *parent): + QObject(parent), + m_time(NULL) +{ + +} + +CRobotFileCollect::~CRobotFileCollect() +{ + release(); +} + +void CRobotFileCollect::initialize() +{ + loadConfig(); + if(!m_time) + { + m_time = new QTimer(); + m_time->setInterval(2000); + connect(this,&CRobotFileCollect::sigTimerShot,this,&CRobotFileCollect::slotTimerShot,Qt::QueuedConnection); + connect(m_time,&QTimer::timeout,this,&CRobotFileCollect::onTimeLoadFile,Qt::QueuedConnection); + } + emit sigTimerShot(true); +} + +void CRobotFileCollect::release() +{ + emit sigTimerShot(false); + m_time->blockSignals(true); + if(m_time != Q_NULLPTR) + { + m_time->stop(); + m_time = Q_NULLPTR; + } +} + +void CRobotFileCollect::loadConfig() +{ + CCommonConfigParse config; + const std::string file = kbd_public::CFileUtil::getPathOfCfgFile("robot_config.xml"); + std::string loadFilePath; + config.load(file); + int error = config.getStringValue("robot_config","loadFilePath",loadFilePath); + if( error != kbdSuccess) + { + m_path = "../../data/test";; + LOGERROR("机器人加载文件路径解析失败!文件[%s],错误码[%d]",file.c_str(),error); + }else + { + m_path = QString::fromStdString(loadFilePath); + } + qDebug()<<"path:"<start(); + }else + { + m_time->stop(); + } + } +} + +void CRobotFileCollect::onTimeLoadFile() +{ + QFileInfoList fileList = getFileList(m_path); + QMap map; + for (int i = 0; i < fileList.size(); ++i) + { + QFileInfo fileInfo = fileList.at(i); + RobotFilePtr robotFile(new CRobotFileInfo()); + if(robotFile->initialize(fileInfo) == kbdSuccess) + { + map.insert(robotFile->m_execPath,robotFile); + + }else + { + LOGERROR("解析文件错误!"); + } + } + if(map.size() > 0) + { + emit sigUpdateFile(map); + } + map.clear(); + //查询内存库 +} + +QFileInfoList CRobotFileCollect::getFileList(const QString &path) +{ + QDir dir(path); + QFileInfoList file_list = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks); + QFileInfoList folder_list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + + for(int i = 0; i != folder_list.size(); i++) + { + QString name = folder_list.at(i).absoluteFilePath(); + + QFileInfoList child_file_list = getFileList(name); + file_list.append(child_file_list); + } + + return file_list; +} + diff --git a/product/src/gui/plugin/RobotWidget/CRobotFileCollect.h b/product/src/gui/plugin/RobotWidget/CRobotFileCollect.h index 426a6339..3a523e55 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotFileCollect.h +++ b/product/src/gui/plugin/RobotWidget/CRobotFileCollect.h @@ -1,39 +1,39 @@ -#ifndef CROBOTFILECOLLECT_H -#define CROBOTFILECOLLECT_H - -#include -#include -#include -#include "CRobotFileInfo.h" -#include -class QTimer; -class CRobotFileCollect : public QObject -{ - Q_OBJECT -public: - CRobotFileCollect(QObject *parent = nullptr); - - ~CRobotFileCollect(); - - void initialize(); - - void release(); - void loadConfig(); -signals: - //< 启停定时器 - void sigTimerShot(const bool bStop); - - void sigUpdateFile(const QMap map); -public slots: - void slotTimerShot(const bool start); -private: - void onTimeLoadFile(); - QFileInfoList getFileList(const QString &path); -private: - - QTimer *m_time; - QString m_path; - -}; - -#endif // CROBOTFILECOLLECT_H +#ifndef CROBOTFILECOLLECT_H +#define CROBOTFILECOLLECT_H + +#include +#include +#include +#include "CRobotFileInfo.h" +#include +class QTimer; +class CRobotFileCollect : public QObject +{ + Q_OBJECT +public: + CRobotFileCollect(QObject *parent = nullptr); + + ~CRobotFileCollect(); + + void initialize(); + + void release(); + void loadConfig(); +signals: + //< 启停定时器 + void sigTimerShot(const bool bStop); + + void sigUpdateFile(const QMap map); +public slots: + void slotTimerShot(const bool start); +private: + void onTimeLoadFile(); + QFileInfoList getFileList(const QString &path); +private: + + QTimer *m_time; + QString m_path; + +}; + +#endif // CROBOTFILECOLLECT_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotFileInfo.cpp b/product/src/gui/plugin/RobotWidget/CRobotFileInfo.cpp index 1c328dce..d0515038 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotFileInfo.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotFileInfo.cpp @@ -1,172 +1,172 @@ -#include "CRobotFileInfo.h" -#include "QFileInfo" -#include "pub_logger_api/logger.h" -#include "Common.h" -#include - -CRobotFileInfo::CRobotFileInfo() -{ - m_filePath = QString(); - m_fileName = QString(); - m_fileType = E_ROBOT_CCD; - m_devgId = -1; - m_devgName = QString(); - time_stamp = 0; - -} - -CRobotFileInfo::CRobotFileInfo(const CRobotFileInfo &other) -{ - m_filePath = other.m_filePath; - m_fileName = other.m_fileName; - m_fileType = other.m_fileType; - m_devgId = other.m_devgId; - m_devgName = other.m_devgName; - time_stamp = other.time_stamp; -} - -bool CRobotFileInfo::lessThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_TIME: - if(time_stamp time_stamp) - { - return true; - } - break; - case E_SORT_DEV: - if(m_devgId m_devgId) - { - return true; - } - break; - case E_SORT_TYPE: - if(m_fileType < info->m_fileType) - { - return true; - } - break; - default: - break; - } - return false; -} - -bool CRobotFileInfo::moreThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey) -{ - switch (sortkey) { - case E_SORT_TIME: - if(time_stamp >= info->time_stamp) - { - return true; - } - break; - case E_SORT_DEV: - if(m_devgId >= info->m_devgId) - { - return true; - } - break; - case E_SORT_TYPE: - if(m_fileType >= info->m_fileType) - { - return true; - } - break; - default: - break; - } - return false; -} - -quint64 CRobotFileInfo::getTime(const QString time) -{ - QString strTime = time; - strTime.insert(12,":"); - strTime.insert(10,":"); - strTime.insert(8," "); - strTime.insert(6,"-"); - strTime.insert(4,"-"); - strTime = strTime.mid(0,19); - LOGINFO("时间:[%s]",strTime.toStdString().c_str()); - QDateTime dateTime; - return dateTime.fromString(strTime,"yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); -} - -int CRobotFileInfo::initialize(const QFileInfo fileInfo) -{ - QString filePath = fileInfo.absoluteFilePath(); - QString path = fileInfo.absolutePath(); - m_execPath = filePath; - m_filePath = path; // 缺少文件名 - m_fileName = filePath.remove(0,path.length()+1); - // .at(0)--- 设备点位 .at(1)--- 机器人编码 .at(2)--- xxxxxxxxxxxxxx.jpg 或 xxxxxxxxxxxxxx.mp4 - QStringList list = m_fileName.split("_"); - if(list.size() != 3) - { - LOGERROR("文件[%s]命名格式有误!",m_fileName.toStdString().c_str()); - return kbdFailed; - } - QString devInt = list.at(0); - m_devgId = devInt.toInt(); - - QString time = list.at(2); - // .at(0)--- 时间 .at(1)--- jpg 或 mp4 - QStringList timeList = time.split("."); - if(timeList.size() == 2) - { - if(timeList.at(1) == "jpg") - { - m_fileType = E_ROBOT_CCD; - }else if(QString(timeList.at(1)) == "mp4") - { - m_fileType = E_ROBOT_VIDEO; - }else - { - LOGERROR("文件[%s]后缀格式有误!",m_fileName.toStdString().c_str()); - return kbdFailed; - } - }else if(timeList.size() == 3) - { - if(timeList.at(2) == "jpg") - { - m_fileType = E_ROBOT_CUT_CCD; - }else - { - LOGERROR("文件[%s]后缀格式有误!",m_fileName.toStdString().c_str()); - return kbdFailed; - } - }else - { - LOGERROR("文件[%s]命名格式有误!",m_fileName.toStdString().c_str()); - return kbdFailed; - } - time_stamp = getTime(timeList.at(0)); - return kbdSuccess; -} - -CRobotInfo::CRobotInfo() -{ - m_tagName = QString(); - m_sub = -1; - m_status = -1; - m_domain =-1; - m_location = -1; -} - -CRobotInfo::CRobotInfo(const CRobotInfo &other) -{ - m_tagName = other.m_tagName; - m_sub = other.m_sub; - m_status = other.m_status; - m_domain =other.m_domain; - m_location = other.m_location; -} - -void CRobotInfo::initialize(const QString &tag_name,int sub,int location,int status) -{ - m_tagName = tag_name; - m_sub = sub; - m_status = status; - m_location = location; -} +#include "CRobotFileInfo.h" +#include "QFileInfo" +#include "pub_logger_api/logger.h" +#include "Common.h" +#include + +CRobotFileInfo::CRobotFileInfo() +{ + m_filePath = QString(); + m_fileName = QString(); + m_fileType = E_ROBOT_CCD; + m_devgId = -1; + m_devgName = QString(); + time_stamp = 0; + +} + +CRobotFileInfo::CRobotFileInfo(const CRobotFileInfo &other) +{ + m_filePath = other.m_filePath; + m_fileName = other.m_fileName; + m_fileType = other.m_fileType; + m_devgId = other.m_devgId; + m_devgName = other.m_devgName; + time_stamp = other.time_stamp; +} + +bool CRobotFileInfo::lessThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_TIME: + if(time_stamp time_stamp) + { + return true; + } + break; + case E_SORT_DEV: + if(m_devgId m_devgId) + { + return true; + } + break; + case E_SORT_TYPE: + if(m_fileType < info->m_fileType) + { + return true; + } + break; + default: + break; + } + return false; +} + +bool CRobotFileInfo::moreThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_TIME: + if(time_stamp >= info->time_stamp) + { + return true; + } + break; + case E_SORT_DEV: + if(m_devgId >= info->m_devgId) + { + return true; + } + break; + case E_SORT_TYPE: + if(m_fileType >= info->m_fileType) + { + return true; + } + break; + default: + break; + } + return false; +} + +quint64 CRobotFileInfo::getTime(const QString time) +{ + QString strTime = time; + strTime.insert(12,":"); + strTime.insert(10,":"); + strTime.insert(8," "); + strTime.insert(6,"-"); + strTime.insert(4,"-"); + strTime = strTime.mid(0,19); + LOGINFO("时间:[%s]",strTime.toStdString().c_str()); + QDateTime dateTime; + return dateTime.fromString(strTime,"yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch(); +} + +int CRobotFileInfo::initialize(const QFileInfo fileInfo) +{ + QString filePath = fileInfo.absoluteFilePath(); + QString path = fileInfo.absolutePath(); + m_execPath = filePath; + m_filePath = path; // 缺少文件名 + m_fileName = filePath.remove(0,path.length()+1); + // .at(0)--- 设备点位 .at(1)--- 机器人编码 .at(2)--- xxxxxxxxxxxxxx.jpg 或 xxxxxxxxxxxxxx.mp4 + QStringList list = m_fileName.split("_"); + if(list.size() != 3) + { + LOGERROR("文件[%s]命名格式有误!",m_fileName.toStdString().c_str()); + return kbdFailed; + } + QString devInt = list.at(0); + m_devgId = devInt.toInt(); + + QString time = list.at(2); + // .at(0)--- 时间 .at(1)--- jpg 或 mp4 + QStringList timeList = time.split("."); + if(timeList.size() == 2) + { + if(timeList.at(1) == "jpg") + { + m_fileType = E_ROBOT_CCD; + }else if(QString(timeList.at(1)) == "mp4") + { + m_fileType = E_ROBOT_VIDEO; + }else + { + LOGERROR("文件[%s]后缀格式有误!",m_fileName.toStdString().c_str()); + return kbdFailed; + } + }else if(timeList.size() == 3) + { + if(timeList.at(2) == "jpg") + { + m_fileType = E_ROBOT_CUT_CCD; + }else + { + LOGERROR("文件[%s]后缀格式有误!",m_fileName.toStdString().c_str()); + return kbdFailed; + } + }else + { + LOGERROR("文件[%s]命名格式有误!",m_fileName.toStdString().c_str()); + return kbdFailed; + } + time_stamp = getTime(timeList.at(0)); + return kbdSuccess; +} + +CRobotInfo::CRobotInfo() +{ + m_tagName = QString(); + m_sub = -1; + m_status = -1; + m_domain =-1; + m_location = -1; +} + +CRobotInfo::CRobotInfo(const CRobotInfo &other) +{ + m_tagName = other.m_tagName; + m_sub = other.m_sub; + m_status = other.m_status; + m_domain =other.m_domain; + m_location = other.m_location; +} + +void CRobotInfo::initialize(const QString &tag_name,int sub,int location,int status) +{ + m_tagName = tag_name; + m_sub = sub; + m_status = status; + m_location = location; +} diff --git a/product/src/gui/plugin/RobotWidget/CRobotFileInfo.h b/product/src/gui/plugin/RobotWidget/CRobotFileInfo.h index 4e3fc38f..7497eff4 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotFileInfo.h +++ b/product/src/gui/plugin/RobotWidget/CRobotFileInfo.h @@ -1,42 +1,42 @@ -#ifndef CROBOTFILEINFO_H -#define CROBOTFILEINFO_H - -#include - -#include "CRobotCommon.h" -class QFileInfo; -class CRobotFileInfo -{ -public: - CRobotFileInfo(); - CRobotFileInfo(const CRobotFileInfo &other); - bool lessThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey = E_SORT_TYPE); - bool moreThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey = E_SORT_TYPE); - quint64 getTime(const QString time); - int initialize(const QFileInfo fileInfo); - QString m_execPath; //<执行路径 - QString m_filePath; //<文件路径 - QString m_fileName; //<文件名 - int m_devgId; //<设备id - QString m_devgName; //<设备组名 - E_ROBOT_FILE_TYPE m_fileType; //<文件类型 - quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) - -}; - -class CRobotInfo -{ -public: - CRobotInfo(); - CRobotInfo(const CRobotInfo &other); - void initialize(const QString &tag_name, int sub, int location, int status); - -public: - QString m_tagName; - int m_sub; - int m_domain; - int m_location; - int m_status; -}; - -#endif // CROBOTFILEINFO_H +#ifndef CROBOTFILEINFO_H +#define CROBOTFILEINFO_H + +#include + +#include "CRobotCommon.h" +class QFileInfo; +class CRobotFileInfo +{ +public: + CRobotFileInfo(); + CRobotFileInfo(const CRobotFileInfo &other); + bool lessThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey = E_SORT_TYPE); + bool moreThan(const RobotFilePtr &info, E_ROBOT_SORTKEY sortkey = E_SORT_TYPE); + quint64 getTime(const QString time); + int initialize(const QFileInfo fileInfo); + QString m_execPath; //<执行路径 + QString m_filePath; //<文件路径 + QString m_fileName; //<文件名 + int m_devgId; //<设备id + QString m_devgName; //<设备组名 + E_ROBOT_FILE_TYPE m_fileType; //<文件类型 + quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) + +}; + +class CRobotInfo +{ +public: + CRobotInfo(); + CRobotInfo(const CRobotInfo &other); + void initialize(const QString &tag_name, int sub, int location, int status); + +public: + QString m_tagName; + int m_sub; + int m_domain; + int m_location; + int m_status; +}; + +#endif // CROBOTFILEINFO_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotFileMng.cpp b/product/src/gui/plugin/RobotWidget/CRobotFileMng.cpp index 0bebcaec..e38e4111 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotFileMng.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotFileMng.cpp @@ -1,65 +1,65 @@ -#include "CRobotFileMng.h" - -CRobotFileMng::CRobotFileMng(QObject *parent): - QObject(parent) -{ - -} - -CRobotFileMng::~CRobotFileMng() -{ - m_all.clear(); -} - -void CRobotFileMng::slotUpdateFile(const QMap map) -{ - if(m_all.size() <= 0) - { - m_all = map; - - emit sigMsgAdd(m_all.values()); - }else - { - QList listAdd; - QList listSub; - judge(map,listAdd,listSub); - if(listAdd.size() > 0) - { - foreach (RobotFilePtr ptr, listAdd) { - m_all.insert(ptr->m_execPath,ptr); - } - emit sigMsgAdd(listAdd); - } - if(listSub.size() > 0) - { - foreach (RobotFilePtr ptr, listSub) { - m_all.erase(m_all.find(ptr->m_execPath)); - } - emit sigMsgSub(listSub); - } - listAdd.clear(); - listSub.clear(); - } -} - -void CRobotFileMng::slotAllMsgAdd() -{ - emit sigMsgAdd(m_all.values()); -} - -void CRobotFileMng::judge(const QMap &map, QList &listAdd, QList &listSub) -{ - foreach (RobotFilePtr ptr, map.values()) { - if(!m_all.keys().contains(ptr->m_execPath)) - { - listAdd.append(ptr); - } - } - foreach (RobotFilePtr ptr, m_all.values()) { - if(!map.keys().contains(ptr->m_execPath)) - { - listSub.append(ptr); - } - } -} - +#include "CRobotFileMng.h" + +CRobotFileMng::CRobotFileMng(QObject *parent): + QObject(parent) +{ + +} + +CRobotFileMng::~CRobotFileMng() +{ + m_all.clear(); +} + +void CRobotFileMng::slotUpdateFile(const QMap map) +{ + if(m_all.size() <= 0) + { + m_all = map; + + emit sigMsgAdd(m_all.values()); + }else + { + QList listAdd; + QList listSub; + judge(map,listAdd,listSub); + if(listAdd.size() > 0) + { + foreach (RobotFilePtr ptr, listAdd) { + m_all.insert(ptr->m_execPath,ptr); + } + emit sigMsgAdd(listAdd); + } + if(listSub.size() > 0) + { + foreach (RobotFilePtr ptr, listSub) { + m_all.erase(m_all.find(ptr->m_execPath)); + } + emit sigMsgSub(listSub); + } + listAdd.clear(); + listSub.clear(); + } +} + +void CRobotFileMng::slotAllMsgAdd() +{ + emit sigMsgAdd(m_all.values()); +} + +void CRobotFileMng::judge(const QMap &map, QList &listAdd, QList &listSub) +{ + foreach (RobotFilePtr ptr, map.values()) { + if(!m_all.keys().contains(ptr->m_execPath)) + { + listAdd.append(ptr); + } + } + foreach (RobotFilePtr ptr, m_all.values()) { + if(!map.keys().contains(ptr->m_execPath)) + { + listSub.append(ptr); + } + } +} + diff --git a/product/src/gui/plugin/RobotWidget/CRobotFileMng.h b/product/src/gui/plugin/RobotWidget/CRobotFileMng.h index de5887a7..f09466b8 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotFileMng.h +++ b/product/src/gui/plugin/RobotWidget/CRobotFileMng.h @@ -1,37 +1,37 @@ -#ifndef CROBOTFILEMNG_H -#define CROBOTFILEMNG_H - -#include -#include -#include -class CRobotFileMng : public QObject -{ - Q_OBJECT -public: - CRobotFileMng(QObject *parent = nullptr); - - ~CRobotFileMng(); - -signals: - /** - * @brief sigMsgAdd 通知模型添加数据 - * @param list - */ - void sigMsgAdd(const QList list); - /** - * @brief sigMsgSub 通知模型删除数据 - * @param list - */ - void sigMsgSub(const QList list); -public slots: - void slotUpdateFile(const QMap map); - void slotAllMsgAdd(); -private: - void judge(const QMap& map,QList &listAdd,QList &listSub); -private: - QMap m_all; - - -}; - -#endif // CROBOTFILEMNG_H +#ifndef CROBOTFILEMNG_H +#define CROBOTFILEMNG_H + +#include +#include +#include +class CRobotFileMng : public QObject +{ + Q_OBJECT +public: + CRobotFileMng(QObject *parent = nullptr); + + ~CRobotFileMng(); + +signals: + /** + * @brief sigMsgAdd 通知模型添加数据 + * @param list + */ + void sigMsgAdd(const QList list); + /** + * @brief sigMsgSub 通知模型删除数据 + * @param list + */ + void sigMsgSub(const QList list); +public slots: + void slotUpdateFile(const QMap map); + void slotAllMsgAdd(); +private: + void judge(const QMap& map,QList &listAdd,QList &listSub); +private: + QMap m_all; + + +}; + +#endif // CROBOTFILEMNG_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.cpp b/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.cpp index 72734903..7b5f7702 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.cpp @@ -1,25 +1,25 @@ -#include "CRobotPluginWidget.h" -#include "CRobotWidget.h" -#include -CRobotPluginWidget::CRobotPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CRobotPluginWidget::~CRobotPluginWidget() -{ - -} - -bool CRobotPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec) -{ - CRobotWidget *pWidget = new CRobotWidget(editMode,parent); - *widget = (QWidget *)pWidget; - *pluginWidget = (IPluginWidget *)pWidget; - return true; -} - -void CRobotPluginWidget::release() -{ - -} +#include "CRobotPluginWidget.h" +#include "CRobotWidget.h" +#include +CRobotPluginWidget::CRobotPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CRobotPluginWidget::~CRobotPluginWidget() +{ + +} + +bool CRobotPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec) +{ + CRobotWidget *pWidget = new CRobotWidget(editMode,parent); + *widget = (QWidget *)pWidget; + *pluginWidget = (IPluginWidget *)pWidget; + return true; +} + +void CRobotPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.h b/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.h index 2ff38df5..2f2a30f8 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.h +++ b/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.h @@ -1,19 +1,19 @@ -#ifndef CROBOTPLUGINWIDGET_H -#define CROBOTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CRobotPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CRobotPluginWidget(QObject *parent = nullptr); - ~CRobotPluginWidget(); - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec); - void release(); -}; - -#endif // CROBOTPLUGINWIDGET_H +#ifndef CROBOTPLUGINWIDGET_H +#define CROBOTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CRobotPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CRobotPluginWidget(QObject *parent = nullptr); + ~CRobotPluginWidget(); + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pluginWidget, QVector ptrVec); + void release(); +}; + +#endif // CROBOTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotWidget.cpp b/product/src/gui/plugin/RobotWidget/CRobotWidget.cpp index b07697a2..5bf2ee53 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotWidget.cpp +++ b/product/src/gui/plugin/RobotWidget/CRobotWidget.cpp @@ -1,147 +1,147 @@ -#include "CRobotWidget.h" -#include "ui_CRobotWidget.h" -#include "CRobotCCDVideoForm.h" -#include "CRobotAVWidget.h" -#include "CRobotCtrlWidget.h" -#include "CRobotCCDVideoItemModel.h" -#include -#include "CRobotFileCollect.h" -#include "CRobotFileMng.h" -#include -#include -#include -#include -#include -#include -#include "pub_utility_api/FileStyle.h" - -CRobotWidget::CRobotWidget(bool editMode, QWidget *parent) : - QWidget(parent), - m_collect(Q_NULLPTR), - m_mng(Q_NULLPTR), - m_model(Q_NULLPTR), - m_thread(Q_NULLPTR), - m_location(-1), - m_ctrlWidget(Q_NULLPTR), - m_avWidget(Q_NULLPTR), - m_ccdVideoWidget(Q_NULLPTR), - ui(new Ui::CRobotWidget) -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("robot.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - ui->setupUi(this); - qRegisterMetaType< QList >("QList"); - qRegisterMetaType >("QMap"); - initView(); - - - m_collect = new CRobotFileCollect(); - m_mng = new CRobotFileMng(); - if(!editMode) - { - if(!m_thread) - { - m_thread = new QThread(this); - m_collect->moveToThread(m_thread); - m_mng->moveToThread(m_thread); - connect(m_thread,&QThread::started,m_collect,&CRobotFileCollect::initialize,Qt::QueuedConnection); - connect(m_thread,&QThread::finished,m_thread,&QThread::deleteLater,Qt::QueuedConnection); - } - connect(m_collect,&CRobotFileCollect::sigUpdateFile,m_mng,&CRobotFileMng::slotUpdateFile,Qt::QueuedConnection); - connect(m_ccdVideoWidget,&CRobotCCDVideoForm::sigAvPlay,this,&CRobotWidget::slotAvPlay,Qt::QueuedConnection); - connect(m_ccdVideoWidget,&CRobotCCDVideoForm::sigCCDPlay,this,&CRobotWidget::slotCCDPlay,Qt::QueuedConnection); - connect(m_avWidget,&CRobotAVWidget::sigCCDPlay,this,&CRobotWidget::slotCCDPlay,Qt::QueuedConnection); - connect(ui->label,&Label::avPlay,this,&CRobotWidget::slotAvPlay,Qt::QueuedConnection); - connect(ui->label,&Label::ccdPlay,this,&CRobotWidget::slotCCDPlay,Qt::QueuedConnection); - } - ui->stackedWidget->setCurrentIndex(0); - -} - -CRobotWidget::~CRobotWidget() -{ - if(m_thread) - { - m_thread->quit(); - m_thread->wait(); - } - - delete ui; -} - -void CRobotWidget::slotAvPlay(QString path) -{ - ui->stackedWidget->setCurrentIndex(0); - ui->label->clear(); - m_avWidget->play(path); -} - -void CRobotWidget::slotCCDPlay(QString path) -{ - m_avWidget->stop(); - ui->stackedWidget->setCurrentIndex(1); - ui->label->clear(); - ui->label->setStyleSheet("QLabel{image:url("+path+");}"); -} - -void CRobotWidget::initView() -{ - //左侧表格 - QGridLayout *ccdLay = new QGridLayout(ui->ccdVideoWidget); - m_ccdVideoWidget = new CRobotCCDVideoForm(this); - ccdLay->setContentsMargins(0,0,0,0); - ccdLay->addWidget(m_ccdVideoWidget); - //中间播放器 - QGridLayout *avLay = new QGridLayout(ui->avWidget); - m_avWidget = new CRobotAVWidget(this); - avLay->setContentsMargins(0,0,0,0); - avLay->addWidget(m_avWidget); - //右侧控制 - QGridLayout *ctrlLay = new QGridLayout(ui->ctrlWidget); - m_ctrlWidget = new CRobotCtrlWidget(this); - //ctrlLay->setContentsMargins(10,0,10,0); - ctrlLay->addWidget(m_ctrlWidget); - - ui->label->setContentsMargins(0,0,0,0); -} - -void CRobotWidget::initialize(int domain, int location) -{ - m_location = location; - m_ctrlWidget->initialize(domain,location); - m_model = new CRobotCCDVideoItemModel(this); - m_ccdVideoWidget->setItemModel(m_model); - m_model->initialize(m_ctrlWidget->getDiMap()); - connect(m_mng,&CRobotFileMng::sigMsgAdd,m_model,&CRobotCCDVideoItemModel::slotMsgAdd,Qt::QueuedConnection); - connect(m_mng,&CRobotFileMng::sigMsgSub,m_model,&CRobotCCDVideoItemModel::slotMsgSub,Qt::QueuedConnection); - connect(m_model,&CRobotCCDVideoItemModel::sigAllMsgAdd,m_mng,&CRobotFileMng::slotAllMsgAdd,Qt::QueuedConnection); - - if(m_thread &&!m_thread->isRunning()) - { - m_thread->start(); - } -} - +#include "CRobotWidget.h" +#include "ui_CRobotWidget.h" +#include "CRobotCCDVideoForm.h" +#include "CRobotAVWidget.h" +#include "CRobotCtrlWidget.h" +#include "CRobotCCDVideoItemModel.h" +#include +#include "CRobotFileCollect.h" +#include "CRobotFileMng.h" +#include +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + +CRobotWidget::CRobotWidget(bool editMode, QWidget *parent) : + QWidget(parent), + m_collect(Q_NULLPTR), + m_mng(Q_NULLPTR), + m_model(Q_NULLPTR), + m_thread(Q_NULLPTR), + m_location(-1), + m_ctrlWidget(Q_NULLPTR), + m_avWidget(Q_NULLPTR), + m_ccdVideoWidget(Q_NULLPTR), + ui(new Ui::CRobotWidget) +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("robot.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + ui->setupUi(this); + qRegisterMetaType< QList >("QList"); + qRegisterMetaType >("QMap"); + initView(); + + + m_collect = new CRobotFileCollect(); + m_mng = new CRobotFileMng(); + if(!editMode) + { + if(!m_thread) + { + m_thread = new QThread(this); + m_collect->moveToThread(m_thread); + m_mng->moveToThread(m_thread); + connect(m_thread,&QThread::started,m_collect,&CRobotFileCollect::initialize,Qt::QueuedConnection); + connect(m_thread,&QThread::finished,m_thread,&QThread::deleteLater,Qt::QueuedConnection); + } + connect(m_collect,&CRobotFileCollect::sigUpdateFile,m_mng,&CRobotFileMng::slotUpdateFile,Qt::QueuedConnection); + connect(m_ccdVideoWidget,&CRobotCCDVideoForm::sigAvPlay,this,&CRobotWidget::slotAvPlay,Qt::QueuedConnection); + connect(m_ccdVideoWidget,&CRobotCCDVideoForm::sigCCDPlay,this,&CRobotWidget::slotCCDPlay,Qt::QueuedConnection); + connect(m_avWidget,&CRobotAVWidget::sigCCDPlay,this,&CRobotWidget::slotCCDPlay,Qt::QueuedConnection); + connect(ui->label,&Label::avPlay,this,&CRobotWidget::slotAvPlay,Qt::QueuedConnection); + connect(ui->label,&Label::ccdPlay,this,&CRobotWidget::slotCCDPlay,Qt::QueuedConnection); + } + ui->stackedWidget->setCurrentIndex(0); + +} + +CRobotWidget::~CRobotWidget() +{ + if(m_thread) + { + m_thread->quit(); + m_thread->wait(); + } + + delete ui; +} + +void CRobotWidget::slotAvPlay(QString path) +{ + ui->stackedWidget->setCurrentIndex(0); + ui->label->clear(); + m_avWidget->play(path); +} + +void CRobotWidget::slotCCDPlay(QString path) +{ + m_avWidget->stop(); + ui->stackedWidget->setCurrentIndex(1); + ui->label->clear(); + ui->label->setStyleSheet("QLabel{image:url("+path+");}"); +} + +void CRobotWidget::initView() +{ + //左侧表格 + QGridLayout *ccdLay = new QGridLayout(ui->ccdVideoWidget); + m_ccdVideoWidget = new CRobotCCDVideoForm(this); + ccdLay->setContentsMargins(0,0,0,0); + ccdLay->addWidget(m_ccdVideoWidget); + //中间播放器 + QGridLayout *avLay = new QGridLayout(ui->avWidget); + m_avWidget = new CRobotAVWidget(this); + avLay->setContentsMargins(0,0,0,0); + avLay->addWidget(m_avWidget); + //右侧控制 + QGridLayout *ctrlLay = new QGridLayout(ui->ctrlWidget); + m_ctrlWidget = new CRobotCtrlWidget(this); + //ctrlLay->setContentsMargins(10,0,10,0); + ctrlLay->addWidget(m_ctrlWidget); + + ui->label->setContentsMargins(0,0,0,0); +} + +void CRobotWidget::initialize(int domain, int location) +{ + m_location = location; + m_ctrlWidget->initialize(domain,location); + m_model = new CRobotCCDVideoItemModel(this); + m_ccdVideoWidget->setItemModel(m_model); + m_model->initialize(m_ctrlWidget->getDiMap()); + connect(m_mng,&CRobotFileMng::sigMsgAdd,m_model,&CRobotCCDVideoItemModel::slotMsgAdd,Qt::QueuedConnection); + connect(m_mng,&CRobotFileMng::sigMsgSub,m_model,&CRobotCCDVideoItemModel::slotMsgSub,Qt::QueuedConnection); + connect(m_model,&CRobotCCDVideoItemModel::sigAllMsgAdd,m_mng,&CRobotFileMng::slotAllMsgAdd,Qt::QueuedConnection); + + if(m_thread &&!m_thread->isRunning()) + { + m_thread->start(); + } +} + diff --git a/product/src/gui/plugin/RobotWidget/CRobotWidget.h b/product/src/gui/plugin/RobotWidget/CRobotWidget.h index ae99fca7..60400b00 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotWidget.h +++ b/product/src/gui/plugin/RobotWidget/CRobotWidget.h @@ -1,49 +1,49 @@ -#ifndef CROBOTLINKCTRLWIDGET_H -#define CROBOTLINKCTRLWIDGET_H - -#include -class CRobotCCDVideoForm; -class CRobotAVWidget; -class CRobotCtrlWidget; -class CRobotCCDVideoItemModel; -class QThread; -class CRobotFileCollect; -class CRobotFileMng; -namespace Ui { -class CRobotWidget; -} - -class CRobotWidget : public QWidget -{ - Q_OBJECT - -public: - CRobotWidget(bool editMode, QWidget *parent = 0); - ~CRobotWidget(); - -public slots: - void slotAvPlay(QString path); - void slotCCDPlay(QString path); - /** - * @brief initialize 初始化 - * @param domain 域id -1代表所有域 (当域为-1时,车站无效) - * @param location 车站 id -1代表所有车站 - */ - void initialize(int domain = -1,int location = -1); -private: - void initView(); - -private: - Ui::CRobotWidget *ui; -private: - CRobotCCDVideoForm * m_ccdVideoWidget; - CRobotAVWidget * m_avWidget; - CRobotCtrlWidget * m_ctrlWidget; - CRobotCCDVideoItemModel * m_model; - QThread *m_thread; - CRobotFileCollect *m_collect; - CRobotFileMng *m_mng; - int m_location; -}; - -#endif // CROBOTLINKCTRLWIDGET_H +#ifndef CROBOTLINKCTRLWIDGET_H +#define CROBOTLINKCTRLWIDGET_H + +#include +class CRobotCCDVideoForm; +class CRobotAVWidget; +class CRobotCtrlWidget; +class CRobotCCDVideoItemModel; +class QThread; +class CRobotFileCollect; +class CRobotFileMng; +namespace Ui { +class CRobotWidget; +} + +class CRobotWidget : public QWidget +{ + Q_OBJECT + +public: + CRobotWidget(bool editMode, QWidget *parent = 0); + ~CRobotWidget(); + +public slots: + void slotAvPlay(QString path); + void slotCCDPlay(QString path); + /** + * @brief initialize 初始化 + * @param domain 域id -1代表所有域 (当域为-1时,车站无效) + * @param location 车站 id -1代表所有车站 + */ + void initialize(int domain = -1,int location = -1); +private: + void initView(); + +private: + Ui::CRobotWidget *ui; +private: + CRobotCCDVideoForm * m_ccdVideoWidget; + CRobotAVWidget * m_avWidget; + CRobotCtrlWidget * m_ctrlWidget; + CRobotCCDVideoItemModel * m_model; + QThread *m_thread; + CRobotFileCollect *m_collect; + CRobotFileMng *m_mng; + int m_location; +}; + +#endif // CROBOTLINKCTRLWIDGET_H diff --git a/product/src/gui/plugin/RobotWidget/CRobotWidget.ui b/product/src/gui/plugin/RobotWidget/CRobotWidget.ui index 7693bc6c..9ec31273 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotWidget.ui +++ b/product/src/gui/plugin/RobotWidget/CRobotWidget.ui @@ -1,177 +1,177 @@ - - - CRobotWidget - - - - 0 - 0 - 1277 - 670 - - - - - 1277 - 0 - - - - CRobotLinkCtrlWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - 0 - 0 - - - - - 239 - 0 - - - - - 239 - 16777215 - - - - - - - - - 0 - 0 - - - - 0 - - - 1 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - - - - - 239 - 643 - - - - - 239 - 16777215 - - - - - - - - - - - - - Label - QLabel -
Label.h
-
-
- - -
+ + + CRobotWidget + + + + 0 + 0 + 1277 + 670 + + + + + 1277 + 0 + + + + CRobotLinkCtrlWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + 0 + + + + + 239 + 0 + + + + + 239 + 16777215 + + + + + + + + + 0 + 0 + + + + 0 + + + 1 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + 239 + 643 + + + + + 239 + 16777215 + + + + + + + + + + + + + Label + QLabel +
Label.h
+
+
+ + +
diff --git a/product/src/gui/plugin/RobotWidget/Label.cpp b/product/src/gui/plugin/RobotWidget/Label.cpp index e1d3543d..6a90966d 100644 --- a/product/src/gui/plugin/RobotWidget/Label.cpp +++ b/product/src/gui/plugin/RobotWidget/Label.cpp @@ -1,29 +1,29 @@ -#include "Label.h" -#include -#include -Label::Label(QWidget *parent): - QLabel(parent) -{ - -} - -void Label::contextMenuEvent(QContextMenuEvent *event) -{ - QMenu menu(this); - QAction * openAction = menu.addAction(tr("打开")); - connect(openAction,&QAction::triggered,[=](){ - QString file = QFileDialog::getOpenFileName(0, tr("打开"),"/","JPEG Files(*.jpg);;MP4 Files(*.mp4)"); - if (file.isEmpty()) - return; - QStringList list = file.split("."); - if(list.at(list.size()-1) == "mp4") - { - emit avPlay(file); - }else if(list.at(list.size()-1) == "jpg") - { - emit ccdPlay(file); - } - }); - menu.exec(QCursor::pos()); - QWidget::contextMenuEvent(event); -} +#include "Label.h" +#include +#include +Label::Label(QWidget *parent): + QLabel(parent) +{ + +} + +void Label::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu(this); + QAction * openAction = menu.addAction(tr("打开")); + connect(openAction,&QAction::triggered,[=](){ + QString file = QFileDialog::getOpenFileName(0, tr("打开"),"/","JPEG Files(*.jpg);;MP4 Files(*.mp4)"); + if (file.isEmpty()) + return; + QStringList list = file.split("."); + if(list.at(list.size()-1) == "mp4") + { + emit avPlay(file); + }else if(list.at(list.size()-1) == "jpg") + { + emit ccdPlay(file); + } + }); + menu.exec(QCursor::pos()); + QWidget::contextMenuEvent(event); +} diff --git a/product/src/gui/plugin/RobotWidget/Label.h b/product/src/gui/plugin/RobotWidget/Label.h index 9ade896b..5e1b5dc4 100644 --- a/product/src/gui/plugin/RobotWidget/Label.h +++ b/product/src/gui/plugin/RobotWidget/Label.h @@ -1,17 +1,17 @@ -#ifndef LABEL_H -#define LABEL_H - -#include -class Label : public QLabel -{ - Q_OBJECT -public: - Label(QWidget *parent = 0); -signals: - void avPlay(QString file); - void ccdPlay(QString file); -protected: - virtual void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // LABEL_H +#ifndef LABEL_H +#define LABEL_H + +#include +class Label : public QLabel +{ + Q_OBJECT +public: + Label(QWidget *parent = 0); +signals: + void avPlay(QString file); + void ccdPlay(QString file); +protected: + virtual void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // LABEL_H diff --git a/product/src/gui/plugin/RobotWidget/OnTimeQueryThread.cpp b/product/src/gui/plugin/RobotWidget/OnTimeQueryThread.cpp index b5209a9d..51cb5f55 100644 --- a/product/src/gui/plugin/RobotWidget/OnTimeQueryThread.cpp +++ b/product/src/gui/plugin/RobotWidget/OnTimeQueryThread.cpp @@ -1,80 +1,80 @@ -#include "OnTimeQueryThread.h" -#include "pub_logger_api/logger.h" -#include -using namespace std; -OnTimeQueryThread::OnTimeQueryThread(QObject *parent) : QObject(parent) -{ - m_outTimeCount = 0; - m_timer = new QTimer(); - m_timer->setInterval(3000); - connect(m_timer,&QTimer::timeout,this,&OnTimeQueryThread::slotQuery); - m_mutex = new QMutex; -} - -OnTimeQueryThread::~OnTimeQueryThread() -{ - if(m_timer) - { - m_timer->stop(); - m_timer->deleteLater(); - } -} - -int OnTimeQueryThread::getStatus(const QString &tag) -{ - QMutexLocker lock(m_mutex); - return m_infoMap.value(tag,1); -} - -void OnTimeQueryThread::init(QMap infoMap) -{ - m_map = infoMap; - m_timer->start(); -} - -void OnTimeQueryThread::slotQuery() -{ - //查询机器人状态 - string table = "analog"; - QMap::iterator it = m_map.begin(); - while (it != m_map.end()) { - vector vecKey; - vecKey.push_back(it.key().toStdString()); - std::vector vecColumn; - vecColumn.push_back("value"); - kbd_idlfile::RdbRet objRet; - rdb_net_api.connect(it.value()->m_domain,it.value()->m_sub); - if(m_outTimeCount > 20) - { - LOGERROR("机器人状态查询出错超过%d次,停止查询!",m_outTimeCount); - m_timer->stop(); - } - if(rdb_net_api.queryByKey(table,vecKey,vecColumn,objRet)) - { - if(objRet.msgrecord(0).msgvaluearray_size() != 1) - { - m_outTimeCount++; - LOGERROR("机器人[%s]状态查询出错!",it.key().toStdString().c_str()); - break; - }else - { - m_outTimeCount = 0; - it.value()->m_status = objRet.msgrecord(0).msgvaluearray(0).dvalue(); - } - //qDebug()<<"type:"<::iterator pos = m_map.begin(); - while (pos != m_map.end()) { - m_infoMap[pos.key()] = pos.value()->m_status; - pos++; - } -} +#include "OnTimeQueryThread.h" +#include "pub_logger_api/logger.h" +#include +using namespace std; +OnTimeQueryThread::OnTimeQueryThread(QObject *parent) : QObject(parent) +{ + m_outTimeCount = 0; + m_timer = new QTimer(); + m_timer->setInterval(3000); + connect(m_timer,&QTimer::timeout,this,&OnTimeQueryThread::slotQuery); + m_mutex = new QMutex; +} + +OnTimeQueryThread::~OnTimeQueryThread() +{ + if(m_timer) + { + m_timer->stop(); + m_timer->deleteLater(); + } +} + +int OnTimeQueryThread::getStatus(const QString &tag) +{ + QMutexLocker lock(m_mutex); + return m_infoMap.value(tag,1); +} + +void OnTimeQueryThread::init(QMap infoMap) +{ + m_map = infoMap; + m_timer->start(); +} + +void OnTimeQueryThread::slotQuery() +{ + //查询机器人状态 + string table = "analog"; + QMap::iterator it = m_map.begin(); + while (it != m_map.end()) { + vector vecKey; + vecKey.push_back(it.key().toStdString()); + std::vector vecColumn; + vecColumn.push_back("value"); + kbd_idlfile::RdbRet objRet; + rdb_net_api.connect(it.value()->m_domain,it.value()->m_sub); + if(m_outTimeCount > 20) + { + LOGERROR("机器人状态查询出错超过%d次,停止查询!",m_outTimeCount); + m_timer->stop(); + } + if(rdb_net_api.queryByKey(table,vecKey,vecColumn,objRet)) + { + if(objRet.msgrecord(0).msgvaluearray_size() != 1) + { + m_outTimeCount++; + LOGERROR("机器人[%s]状态查询出错!",it.key().toStdString().c_str()); + break; + }else + { + m_outTimeCount = 0; + it.value()->m_status = objRet.msgrecord(0).msgvaluearray(0).dvalue(); + } + //qDebug()<<"type:"<::iterator pos = m_map.begin(); + while (pos != m_map.end()) { + m_infoMap[pos.key()] = pos.value()->m_status; + pos++; + } +} diff --git a/product/src/gui/plugin/RobotWidget/OnTimeQueryThread.h b/product/src/gui/plugin/RobotWidget/OnTimeQueryThread.h index afdd43af..33af2bb6 100644 --- a/product/src/gui/plugin/RobotWidget/OnTimeQueryThread.h +++ b/product/src/gui/plugin/RobotWidget/OnTimeQueryThread.h @@ -1,32 +1,32 @@ -#ifndef ONTIMEQUERYTHREAD_H -#define ONTIMEQUERYTHREAD_H - -#include -#include "CRobotFileInfo.h" -#include -#include -#include "rdb_net_api/CRdbNetApi.h" -#include -class OnTimeQueryThread : public QObject -{ - Q_OBJECT -public: - explicit OnTimeQueryThread(QObject *parent = nullptr); - ~OnTimeQueryThread(); - int getStatus(const QString &tag); -public: - void init(QMap infoMap); -signals: - -public slots: - void slotQuery(); -private: - QMap m_map; - QTimer *m_timer; - kbd_dbms::CRdbNetApi rdb_net_api; - QMap m_infoMap; - QMutex *m_mutex; - int m_outTimeCount; -}; - -#endif // ONTIMEQUERYTHREAD_H +#ifndef ONTIMEQUERYTHREAD_H +#define ONTIMEQUERYTHREAD_H + +#include +#include "CRobotFileInfo.h" +#include +#include +#include "rdb_net_api/CRdbNetApi.h" +#include +class OnTimeQueryThread : public QObject +{ + Q_OBJECT +public: + explicit OnTimeQueryThread(QObject *parent = nullptr); + ~OnTimeQueryThread(); + int getStatus(const QString &tag); +public: + void init(QMap infoMap); +signals: + +public slots: + void slotQuery(); +private: + QMap m_map; + QTimer *m_timer; + kbd_dbms::CRdbNetApi rdb_net_api; + QMap m_infoMap; + QMutex *m_mutex; + int m_outTimeCount; +}; + +#endif // ONTIMEQUERYTHREAD_H diff --git a/product/src/gui/plugin/RobotWidget/OnTimeRecvThread.cpp b/product/src/gui/plugin/RobotWidget/OnTimeRecvThread.cpp index bd829e27..90c6d487 100644 --- a/product/src/gui/plugin/RobotWidget/OnTimeRecvThread.cpp +++ b/product/src/gui/plugin/RobotWidget/OnTimeRecvThread.cpp @@ -1,145 +1,145 @@ -#include "OnTimeRecvThread.h" -#include "pub_logger_api/logger.h" -#include -#include "AlarmLinkMessage.pb.h" -#include -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/CommonConfigParse.h" -#include -#include "Common.h" -using namespace kbd_net; -using namespace kbd_idlfile; -using namespace kbd_public; -using namespace std; - -OnTimeRecvThread::OnTimeRecvThread(QObject *parent) : - m_outTime(5), - QObject(parent) -{ - loadConfig(); -} - -OnTimeRecvThread::~OnTimeRecvThread() -{ - unSub(); -} - -void OnTimeRecvThread::loadConfig() -{ - CCommonConfigParse config; - const std::string file = kbd_public::CFileUtil::getPathOfCfgFile("robot_config.xml"); - int error = config.load(file); - if(error != kbdSuccess) - { - LOGERROR("机器人加载文件路径解析失败!文件[%s],错误码[%d]",file.c_str(),error); - return ; - } - error = config.getIntValue("robot_config","outTime",m_outTime); - if( error != kbdSuccess) - { - m_outTime = 5; - LOGERROR("机器人加载文件路径解析失败!文件[%s],错误码[%d]",file.c_str(),error); - } -} - -void OnTimeRecvThread::init() -{ - if(!m_objCommon.addSub(0,CH_AL_TO_HMI_UP)) - { - LOGERROR("通道[CH_AL_TO_HMI_UP]订阅失败."); - }else - { - LOGINFO("通道[CH_AL_TO_HMI_UP]订阅成功."); - } -} - -void OnTimeRecvThread::msgRecv() -{ - CMbMessage objMsg; - if(m_objCommon.recvMsg(objMsg,m_outTime*1000) == true) - { - switch (objMsg.getChannelID()) { - case CH_AL_TO_HMI_UP: - parseMsg(objMsg); - break; - default: - break; - } - }else - { - emit sigSetSwitchButtonUsed(true,m_check); - QString text = tr("告警联动控制返回超时!"); - emit sigCtrlResult(text); - } -} - -void OnTimeRecvThread::slotAlmLinkOpen(bool bo) -{ - m_check = !bo; - bool bRet = false; - //拼凑命令 - ::kbd_idlfile::HmiCtrlRobot ctrlMsg; - ctrlMsg.set_entype(::kbd_idlfile::MT_HMI_CTRL_ROBOT); - ctrlMsg.set_encontent(bo?(::kbd_idlfile::MT_START):(::kbd_idlfile::MT_STOP)); - ctrlMsg.set_ntime(QDateTime::currentMSecsSinceEpoch()); - string msg; - ctrlMsg.SerializeToString(&msg); - //发送命令 - CMbMessage objMsg; - objMsg.setMsgType(::kbd_idlfile::MT_HMI_CTRL_ROBOT); - objMsg.setSubject(CN_AppId_BASE,CH_HMI_TO_ALCMD_DOWN); - objMsg.setData(msg); - init(); - bRet = m_objCommon.sendMsgToDomain(objMsg); - if (bRet == false) - { - QString text = tr("告警联动控制命令下发失败!"); - emit sigCtrlResult(text); - LOGERROR("告警联动控制-Message[MsgType='%d', Channel='%d'] send fail .", - ::kbd_idlfile::MT_HMI_CTRL_ROBOT,CH_HMI_TO_ALCMD_DOWN); - }else - { - emit sigSetSwitchButtonUsed(false,false); - msgRecv(); - } - unSub(); -} - -void OnTimeRecvThread::parseMsg(const CMbMessage &objMsg) -{ - ::kbd_idlfile::HmiCtrlRobot hmiCtrlRobot; - if(hmiCtrlRobot.ParseFromArray(objMsg.getDataPtr(),(int)objMsg.getDataSize())) - { - if(hmiCtrlRobot.encontent() == kbd_idlfile::MT_STOP) - { - emit sigSetSwitchButtonUsed(true,false); - }else - { - emit sigSetSwitchButtonUsed(true,true); - } - } -} - -void OnTimeRecvThread::unSub() -{ - std::vector vecSub =m_objCommon.getMySub(); - for(size_t i=0;i +#include "AlarmLinkMessage.pb.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CommonConfigParse.h" +#include +#include "Common.h" +using namespace kbd_net; +using namespace kbd_idlfile; +using namespace kbd_public; +using namespace std; + +OnTimeRecvThread::OnTimeRecvThread(QObject *parent) : + m_outTime(5), + QObject(parent) +{ + loadConfig(); +} + +OnTimeRecvThread::~OnTimeRecvThread() +{ + unSub(); +} + +void OnTimeRecvThread::loadConfig() +{ + CCommonConfigParse config; + const std::string file = kbd_public::CFileUtil::getPathOfCfgFile("robot_config.xml"); + int error = config.load(file); + if(error != kbdSuccess) + { + LOGERROR("机器人加载文件路径解析失败!文件[%s],错误码[%d]",file.c_str(),error); + return ; + } + error = config.getIntValue("robot_config","outTime",m_outTime); + if( error != kbdSuccess) + { + m_outTime = 5; + LOGERROR("机器人加载文件路径解析失败!文件[%s],错误码[%d]",file.c_str(),error); + } +} + +void OnTimeRecvThread::init() +{ + if(!m_objCommon.addSub(0,CH_AL_TO_HMI_UP)) + { + LOGERROR("通道[CH_AL_TO_HMI_UP]订阅失败."); + }else + { + LOGINFO("通道[CH_AL_TO_HMI_UP]订阅成功."); + } +} + +void OnTimeRecvThread::msgRecv() +{ + CMbMessage objMsg; + if(m_objCommon.recvMsg(objMsg,m_outTime*1000) == true) + { + switch (objMsg.getChannelID()) { + case CH_AL_TO_HMI_UP: + parseMsg(objMsg); + break; + default: + break; + } + }else + { + emit sigSetSwitchButtonUsed(true,m_check); + QString text = tr("告警联动控制返回超时!"); + emit sigCtrlResult(text); + } +} + +void OnTimeRecvThread::slotAlmLinkOpen(bool bo) +{ + m_check = !bo; + bool bRet = false; + //拼凑命令 + ::kbd_idlfile::HmiCtrlRobot ctrlMsg; + ctrlMsg.set_entype(::kbd_idlfile::MT_HMI_CTRL_ROBOT); + ctrlMsg.set_encontent(bo?(::kbd_idlfile::MT_START):(::kbd_idlfile::MT_STOP)); + ctrlMsg.set_ntime(QDateTime::currentMSecsSinceEpoch()); + string msg; + ctrlMsg.SerializeToString(&msg); + //发送命令 + CMbMessage objMsg; + objMsg.setMsgType(::kbd_idlfile::MT_HMI_CTRL_ROBOT); + objMsg.setSubject(CN_AppId_BASE,CH_HMI_TO_ALCMD_DOWN); + objMsg.setData(msg); + init(); + bRet = m_objCommon.sendMsgToDomain(objMsg); + if (bRet == false) + { + QString text = tr("告警联动控制命令下发失败!"); + emit sigCtrlResult(text); + LOGERROR("告警联动控制-Message[MsgType='%d', Channel='%d'] send fail .", + ::kbd_idlfile::MT_HMI_CTRL_ROBOT,CH_HMI_TO_ALCMD_DOWN); + }else + { + emit sigSetSwitchButtonUsed(false,false); + msgRecv(); + } + unSub(); +} + +void OnTimeRecvThread::parseMsg(const CMbMessage &objMsg) +{ + ::kbd_idlfile::HmiCtrlRobot hmiCtrlRobot; + if(hmiCtrlRobot.ParseFromArray(objMsg.getDataPtr(),(int)objMsg.getDataSize())) + { + if(hmiCtrlRobot.encontent() == kbd_idlfile::MT_STOP) + { + emit sigSetSwitchButtonUsed(true,false); + }else + { + emit sigSetSwitchButtonUsed(true,true); + } + } +} + +void OnTimeRecvThread::unSub() +{ + std::vector vecSub =m_objCommon.getMySub(); + for(size_t i=0;i -#include "net_msg_bus_api/CMbCommunicator.h" -#include "common/MessageChannel.h" -class OnTimeRecvThread : public QObject -{ - Q_OBJECT -public: - explicit OnTimeRecvThread(QObject *parent = nullptr); - ~OnTimeRecvThread(); - void loadConfig(); -signals: - void sigSetSwitchButtonUsed(bool enble,bool open); - void sigCtrlResult(QString text); -public slots: - void init(); - - void msgRecv(); - - void slotAlmLinkOpen(bool bo); -private: - void parseMsg(const kbd_net::CMbMessage &objMsg); - - void unSub(); - - void clearMsg(); -private: - kbd_net::CMbCommunicator m_objCommon; - bool m_check; - int m_outTime; -}; - -#endif // ONTIMERECVTHREAD_H +#ifndef ONTIMERECVTHREAD_H +#define ONTIMERECVTHREAD_H + +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "common/MessageChannel.h" +class OnTimeRecvThread : public QObject +{ + Q_OBJECT +public: + explicit OnTimeRecvThread(QObject *parent = nullptr); + ~OnTimeRecvThread(); + void loadConfig(); +signals: + void sigSetSwitchButtonUsed(bool enble,bool open); + void sigCtrlResult(QString text); +public slots: + void init(); + + void msgRecv(); + + void slotAlmLinkOpen(bool bo); +private: + void parseMsg(const kbd_net::CMbMessage &objMsg); + + void unSub(); + + void clearMsg(); +private: + kbd_net::CMbCommunicator m_objCommon; + bool m_check; + int m_outTime; +}; + +#endif // ONTIMERECVTHREAD_H diff --git a/product/src/gui/plugin/RobotWidget/Renderer.cpp b/product/src/gui/plugin/RobotWidget/Renderer.cpp index cdd1f7e5..593e1d31 100644 --- a/product/src/gui/plugin/RobotWidget/Renderer.cpp +++ b/product/src/gui/plugin/RobotWidget/Renderer.cpp @@ -1,38 +1,38 @@ -#include "Renderer.h" -#include -#include -Renderer::Renderer(QWidget *parent): - WidgetRenderer(parent) -{ - -} - -void Renderer::mouseReleaseEvent(QMouseEvent *event) -{ - if(event->button() == Qt::LeftButton) - { - emit click(); - } - QWidget::mouseReleaseEvent(event); -} - -void Renderer::contextMenuEvent(QContextMenuEvent *event) -{ - QMenu menu(this); - QAction * openAction = menu.addAction(tr("打开")); - connect(openAction,&QAction::triggered,[=](){ - QString file = QFileDialog::getOpenFileName(0, tr("打开"),"/","JPEG Files(*.jpg);;MP4 Files(*.mp4)"); - if (file.isEmpty()) - return; - QStringList list = file.split("."); - if(list.at(list.size()-1) == "mp4") - { - emit avPlay(file); - }else if(list.at(list.size()-1) == "jpg") - { - emit ccdPlay(file); - } - }); - menu.exec(QCursor::pos()); - QWidget::contextMenuEvent(event); -} +#include "Renderer.h" +#include +#include +Renderer::Renderer(QWidget *parent): + WidgetRenderer(parent) +{ + +} + +void Renderer::mouseReleaseEvent(QMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + emit click(); + } + QWidget::mouseReleaseEvent(event); +} + +void Renderer::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu(this); + QAction * openAction = menu.addAction(tr("打开")); + connect(openAction,&QAction::triggered,[=](){ + QString file = QFileDialog::getOpenFileName(0, tr("打开"),"/","JPEG Files(*.jpg);;MP4 Files(*.mp4)"); + if (file.isEmpty()) + return; + QStringList list = file.split("."); + if(list.at(list.size()-1) == "mp4") + { + emit avPlay(file); + }else if(list.at(list.size()-1) == "jpg") + { + emit ccdPlay(file); + } + }); + menu.exec(QCursor::pos()); + QWidget::contextMenuEvent(event); +} diff --git a/product/src/gui/plugin/RobotWidget/Renderer.h b/product/src/gui/plugin/RobotWidget/Renderer.h index 869d4400..86d2a2ef 100644 --- a/product/src/gui/plugin/RobotWidget/Renderer.h +++ b/product/src/gui/plugin/RobotWidget/Renderer.h @@ -1,22 +1,22 @@ -#ifndef RENDERER_H -#define RENDERER_H -#include -#include -#include - -class Renderer :public QtAV::WidgetRenderer -{ - Q_OBJECT -public: - Renderer(QWidget *parent = 0); -signals: - void click(); - - void ccdPlay(QString file); - void avPlay(QString file); -protected: - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // RENDERER_H +#ifndef RENDERER_H +#define RENDERER_H +#include +#include +#include + +class Renderer :public QtAV::WidgetRenderer +{ + Q_OBJECT +public: + Renderer(QWidget *parent = 0); +signals: + void click(); + + void ccdPlay(QString file); + void avPlay(QString file); +protected: + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // RENDERER_H diff --git a/product/src/gui/plugin/RobotWidget/RobotWidget.pro b/product/src/gui/plugin/RobotWidget/RobotWidget.pro index ba71f745..25b1c57e 100644 --- a/product/src/gui/plugin/RobotWidget/RobotWidget.pro +++ b/product/src/gui/plugin/RobotWidget/RobotWidget.pro @@ -1,112 +1,112 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-02-12T08:50:48 -# -#------------------------------------------------- - -QT += core sql printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -TEMPLATE = lib -TARGET = RobotWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -INCLUDEPATH += $$PWD \ - $$PWD/../../../3rd/include/QTAV/ \ - $$PWD/../../../3rd/include/QtAVWidgets/ \ - -win32-msvc* { - -CONFIG(debug, debug|release) { - LIBS += -lQtAVd1 -lQtAVWidgetsd1 -} -CONFIG(release, debug|release) { - LIBS += -lQtAV1 -lQtAVWidgets1 -} -} -linux-g++*{ - LIBS += -lQtAV -lQtAVWidgets -} - -LIBS += -llog4cplus -lboost_system -lrdb_net_api -lboost_filesystem -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lpub_sysinfo_api -LIBS += -lnet_msg_bus_api -lboost_system -lboost_chrono -SOURCES += \ - # main.cpp \ - CRobotPluginWidget.cpp \ - CRobotCCDVideoForm.cpp \ - CRobotAVWidget.cpp \ - CRobotCtrlWidget.cpp \ - CRobotCCDVideoView.cpp \ - CRobotFileInfo.cpp \ - CRobotCCDVideoItemModel.cpp \ - SWitchButton.cpp \ - CRobotFileCollect.cpp \ - CRobotFileMng.cpp \ - Slider.cpp \ - Renderer.cpp \ - VoiceSlider.cpp \ - OnTimeQueryThread.cpp \ - OnTimeRecvThread.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - Label.cpp \ - CRobotWidget.cpp - -HEADERS += \ - CRobotPluginWidget.h \ - CRobotCCDVideoForm.h \ - CRobotAVWidget.h \ - CRobotCtrlWidget.h \ - CRobotCCDVideoView.h \ - CRobotFileInfo.h \ - CRobotCCDVideoItemModel.h \ - SWitchButton.h \ - CRobotFileCollect.h \ - CRobotFileMng.h \ - Slider.h \ - Renderer.h \ - VoiceSlider.h \ - OnTimeQueryThread.h \ - OnTimeRecvThread.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - Label.h \ - CRobotCommon.h \ - CRobotWidget.h - -FORMS += \ - CRobotCCDVideoForm.ui \ - CRobotAVWidget.ui \ - CRobotCtrlWidget.ui \ - VoiceSlider.ui \ - CRobotWidget.ui - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -#必须在common.pri之后包含 -#------------------------------------------------------------------- -QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri -exists($$QTAV_PRI) { - include($$QTAV_PRI) -}else { - error("FATAL error: can not find qtav.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2020-02-12T08:50:48 +# +#------------------------------------------------- + +QT += core sql printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +TEMPLATE = lib +TARGET = RobotWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +INCLUDEPATH += $$PWD \ + $$PWD/../../../3rd/include/QTAV/ \ + $$PWD/../../../3rd/include/QtAVWidgets/ \ + +win32-msvc* { + +CONFIG(debug, debug|release) { + LIBS += -lQtAVd1 -lQtAVWidgetsd1 +} +CONFIG(release, debug|release) { + LIBS += -lQtAV1 -lQtAVWidgets1 +} +} +linux-g++*{ + LIBS += -lQtAV -lQtAVWidgets +} + +LIBS += -llog4cplus -lboost_system -lrdb_net_api -lboost_filesystem -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lpub_sysinfo_api +LIBS += -lnet_msg_bus_api -lboost_system -lboost_chrono +SOURCES += \ + # main.cpp \ + CRobotPluginWidget.cpp \ + CRobotCCDVideoForm.cpp \ + CRobotAVWidget.cpp \ + CRobotCtrlWidget.cpp \ + CRobotCCDVideoView.cpp \ + CRobotFileInfo.cpp \ + CRobotCCDVideoItemModel.cpp \ + SWitchButton.cpp \ + CRobotFileCollect.cpp \ + CRobotFileMng.cpp \ + Slider.cpp \ + Renderer.cpp \ + VoiceSlider.cpp \ + OnTimeQueryThread.cpp \ + OnTimeRecvThread.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + Label.cpp \ + CRobotWidget.cpp + +HEADERS += \ + CRobotPluginWidget.h \ + CRobotCCDVideoForm.h \ + CRobotAVWidget.h \ + CRobotCtrlWidget.h \ + CRobotCCDVideoView.h \ + CRobotFileInfo.h \ + CRobotCCDVideoItemModel.h \ + SWitchButton.h \ + CRobotFileCollect.h \ + CRobotFileMng.h \ + Slider.h \ + Renderer.h \ + VoiceSlider.h \ + OnTimeQueryThread.h \ + OnTimeRecvThread.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + Label.h \ + CRobotCommon.h \ + CRobotWidget.h + +FORMS += \ + CRobotCCDVideoForm.ui \ + CRobotAVWidget.ui \ + CRobotCtrlWidget.ui \ + VoiceSlider.ui \ + CRobotWidget.ui + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +#必须在common.pri之后包含 +#------------------------------------------------------------------- +QTAV_PRI=$$SRC_ROOT_PATH/3rd/include/qtav/qtav.pri +exists($$QTAV_PRI) { + include($$QTAV_PRI) +}else { + error("FATAL error: can not find qtav.pri") +} diff --git a/product/src/gui/plugin/RobotWidget/SWitchButton.cpp b/product/src/gui/plugin/RobotWidget/SWitchButton.cpp index e9da1114..07fc49e0 100644 --- a/product/src/gui/plugin/RobotWidget/SWitchButton.cpp +++ b/product/src/gui/plugin/RobotWidget/SWitchButton.cpp @@ -1,209 +1,209 @@ -#include -#include -#include -#include "SWitchButton.h" -#include -SWitchButton::SWitchButton(QWidget *parent) - : QWidget(parent), - m_nHeight(12), - m_bChecked(false), - m_radius(8.0), - m_nMargin(3), - m_checkedColor(Qt::red), - m_thumbColor(Qt::white), - m_disabledColor(Qt::darkGray), - m_background(Qt::green), - m_load(Q_NULLPTR) -{ - // 鼠标滑过光标形状 - 手型 - setCursor(Qt::PointingHandCursor); - - // 连接信号槽 - m_load = new QTimer(); - m_load->setInterval(2000); - connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); - connect(m_load,&QTimer::timeout,this,&SWitchButton::loadAlmLink); - m_load->start(); -} - -// 绘制开关 -void SWitchButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter painter(this); - painter.setPen(Qt::NoPen); - painter.setRenderHint(QPainter::Antialiasing); - - QPainterPath path; - QColor background; - QColor thumbColor; - qreal dOpacity; - if (isEnabled()) { // 可用状态 - if (m_bChecked) { // 打开状态 - background = m_checkedColor; - thumbColor = m_checkedColor; - dOpacity = 0.600; - } else { //关闭状态 - background = m_background; - thumbColor = m_background; - dOpacity = 0.800; - } - } else { // 不可用状态 - background = m_disabledColor; - dOpacity = 0.260; - thumbColor = m_disabledColor; - } - // 绘制大椭圆 - painter.setBrush(background); - painter.setOpacity(dOpacity); //透明度 - - path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin, height() - 2 * m_nMargin), m_radius, m_radius); - painter.drawPath(path.simplified()); - - // 绘制小椭圆 - painter.setBrush(thumbColor); - painter.setOpacity(1.0); - painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height())); -} - -// 鼠标按下事件 -void SWitchButton::mousePressEvent(QMouseEvent *event) -{ - if (isEnabled()) { - if (event->buttons() & Qt::LeftButton) { - event->accept(); - } else { - event->ignore(); - } - } -} - -// 鼠标释放事件 - 切换开关状态、发射toggled()信号 -void SWitchButton::mouseReleaseEvent(QMouseEvent *event) -{ - - if (isEnabled()) { - if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { - event->accept(); - //发命令 - emit sigAlmLinkOpen(!m_bChecked); - //m_timer.start(10); - } else { - event->ignore(); - } - } -} - -// 大小改变事件 -void SWitchButton::resizeEvent(QResizeEvent *event) -{ - m_nX = m_nHeight / 2; - m_nY = m_nHeight / 2; - QWidget::resizeEvent(event); -} - -// 默认大小 -QSize SWitchButton::sizeHint() const -{ - return minimumSizeHint(); -} - -// 最小大小 -QSize SWitchButton::minimumSizeHint() const -{ - return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); -} - -// 切换状态 - 滑动 -void SWitchButton::onTimeout() -{ - if (m_bChecked) { - m_nX += 3; - if (m_nX >= width() - height()+ m_nHeight / 2) - { - m_nX = width() - height()+ m_nHeight / 2; - m_timer.stop(); - } - } else { - m_nX -= 3; - if (m_nX <= m_nHeight / 2) - { - m_nX = m_nHeight / 2; - m_timer.stop(); - } - } - update(); -} - -// 返回开关状态 - 打开:true 关闭:false -bool SWitchButton::isToggled() const -{ - return m_bChecked; -} - -// 设置开关状态 -void SWitchButton::setToggle(bool checked) -{ - m_bChecked = checked; - m_timer.start(10); -} - -// 设置背景颜色 -void SWitchButton::setBackgroundColor(QColor color) -{ - m_background = color; -} - -// 设置选中颜色 -void SWitchButton::setCheckedColor(QColor color) -{ - m_checkedColor = color; -} - -// 设置不可用颜色 -void SWitchButton::setDisbaledColor(QColor color) -{ - m_disabledColor = color; -} - -void SWitchButton::loadAlmLink() -{ - QFile file("robotLinkCtrl.txt"); - QString str; - if(file.exists()) - { - if(file.open(QFile::ReadOnly | QFile::Text)) - { - str = file.readAll(); - file.close(); - } - } - else - { - str = "stop"; - std::string tempStr = str.toStdString(); - if(file.open(QFile::WriteOnly | QFile::Append)) - { - file.write(tempStr.c_str(),tempStr.length()); - file.close(); - } - } - if(str != "start") - { - m_bChecked = false; - }else - { - m_bChecked = true; - } - m_timer.start(10); -} - -void SWitchButton::slotSwitchButtonUsed(bool enble, bool open) -{ - setEnabled(enble); - if(enble) - { - setToggle(open); - } -} +#include +#include +#include +#include "SWitchButton.h" +#include +SWitchButton::SWitchButton(QWidget *parent) + : QWidget(parent), + m_nHeight(12), + m_bChecked(false), + m_radius(8.0), + m_nMargin(3), + m_checkedColor(Qt::red), + m_thumbColor(Qt::white), + m_disabledColor(Qt::darkGray), + m_background(Qt::green), + m_load(Q_NULLPTR) +{ + // 鼠标滑过光标形状 - 手型 + setCursor(Qt::PointingHandCursor); + + // 连接信号槽 + m_load = new QTimer(); + m_load->setInterval(2000); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); + connect(m_load,&QTimer::timeout,this,&SWitchButton::loadAlmLink); + m_load->start(); +} + +// 绘制开关 +void SWitchButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + painter.setPen(Qt::NoPen); + painter.setRenderHint(QPainter::Antialiasing); + + QPainterPath path; + QColor background; + QColor thumbColor; + qreal dOpacity; + if (isEnabled()) { // 可用状态 + if (m_bChecked) { // 打开状态 + background = m_checkedColor; + thumbColor = m_checkedColor; + dOpacity = 0.600; + } else { //关闭状态 + background = m_background; + thumbColor = m_background; + dOpacity = 0.800; + } + } else { // 不可用状态 + background = m_disabledColor; + dOpacity = 0.260; + thumbColor = m_disabledColor; + } + // 绘制大椭圆 + painter.setBrush(background); + painter.setOpacity(dOpacity); //透明度 + + path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin, height() - 2 * m_nMargin), m_radius, m_radius); + painter.drawPath(path.simplified()); + + // 绘制小椭圆 + painter.setBrush(thumbColor); + painter.setOpacity(1.0); + painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height())); +} + +// 鼠标按下事件 +void SWitchButton::mousePressEvent(QMouseEvent *event) +{ + if (isEnabled()) { + if (event->buttons() & Qt::LeftButton) { + event->accept(); + } else { + event->ignore(); + } + } +} + +// 鼠标释放事件 - 切换开关状态、发射toggled()信号 +void SWitchButton::mouseReleaseEvent(QMouseEvent *event) +{ + + if (isEnabled()) { + if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { + event->accept(); + //发命令 + emit sigAlmLinkOpen(!m_bChecked); + //m_timer.start(10); + } else { + event->ignore(); + } + } +} + +// 大小改变事件 +void SWitchButton::resizeEvent(QResizeEvent *event) +{ + m_nX = m_nHeight / 2; + m_nY = m_nHeight / 2; + QWidget::resizeEvent(event); +} + +// 默认大小 +QSize SWitchButton::sizeHint() const +{ + return minimumSizeHint(); +} + +// 最小大小 +QSize SWitchButton::minimumSizeHint() const +{ + return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); +} + +// 切换状态 - 滑动 +void SWitchButton::onTimeout() +{ + if (m_bChecked) { + m_nX += 3; + if (m_nX >= width() - height()+ m_nHeight / 2) + { + m_nX = width() - height()+ m_nHeight / 2; + m_timer.stop(); + } + } else { + m_nX -= 3; + if (m_nX <= m_nHeight / 2) + { + m_nX = m_nHeight / 2; + m_timer.stop(); + } + } + update(); +} + +// 返回开关状态 - 打开:true 关闭:false +bool SWitchButton::isToggled() const +{ + return m_bChecked; +} + +// 设置开关状态 +void SWitchButton::setToggle(bool checked) +{ + m_bChecked = checked; + m_timer.start(10); +} + +// 设置背景颜色 +void SWitchButton::setBackgroundColor(QColor color) +{ + m_background = color; +} + +// 设置选中颜色 +void SWitchButton::setCheckedColor(QColor color) +{ + m_checkedColor = color; +} + +// 设置不可用颜色 +void SWitchButton::setDisbaledColor(QColor color) +{ + m_disabledColor = color; +} + +void SWitchButton::loadAlmLink() +{ + QFile file("robotLinkCtrl.txt"); + QString str; + if(file.exists()) + { + if(file.open(QFile::ReadOnly | QFile::Text)) + { + str = file.readAll(); + file.close(); + } + } + else + { + str = "stop"; + std::string tempStr = str.toStdString(); + if(file.open(QFile::WriteOnly | QFile::Append)) + { + file.write(tempStr.c_str(),tempStr.length()); + file.close(); + } + } + if(str != "start") + { + m_bChecked = false; + }else + { + m_bChecked = true; + } + m_timer.start(10); +} + +void SWitchButton::slotSwitchButtonUsed(bool enble, bool open) +{ + setEnabled(enble); + if(enble) + { + setToggle(open); + } +} diff --git a/product/src/gui/plugin/RobotWidget/SWitchButton.h b/product/src/gui/plugin/RobotWidget/SWitchButton.h index 321b8bf5..e53cc2e8 100644 --- a/product/src/gui/plugin/RobotWidget/SWitchButton.h +++ b/product/src/gui/plugin/RobotWidget/SWitchButton.h @@ -1,75 +1,75 @@ -#ifndef SWITCHBUTTON_H -#define SWITCHBUTTON_H - -#include -#include - -class SWitchButton : public QWidget -{ - Q_OBJECT - -public: - explicit SWitchButton(QWidget *parent = 0); - - // 返回开关状态 - 打开:true 关闭:false - bool isToggled() const; - - // 设置开关状态 - void setToggle(bool checked); - - // 设置背景颜色 - void setBackgroundColor(QColor color); - - // 设置选中颜色 - void setCheckedColor(QColor color); - - // 设置不可用颜色 - void setDisbaledColor(QColor color); - - void loadAlmLink(); -public slots: - void slotSwitchButtonUsed(bool enble,bool open); -protected: - // 绘制开关 - void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - - // 鼠标按下事件 - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // 鼠标释放事件 - 切换开关状态、发射toggled()信号 - void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // 大小改变事件 - void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; - - // 缺省大小 - QSize sizeHint() const Q_DECL_OVERRIDE; - QSize minimumSizeHint() const Q_DECL_OVERRIDE; - -signals: - // 状态改变时,发射信号 - void toggled(bool checked); - - void sigAlmLinkOpen(bool bo); - -private slots: - // 状态切换时,用于产生滑动效果 - void onTimeout(); - -private: - bool m_bChecked; // 是否选中 - QColor m_background; // 背景颜色 - QColor m_checkedColor; // 选中颜色 - QColor m_disabledColor; // 不可用颜色 - QColor m_thumbColor; // - qreal m_radius; // 圆角 - qreal m_nX; // x点坐标 - qreal m_nY; // y点坐标 - qint16 m_nHeight; // 高度 - qint16 m_nMargin; // 外边距 - QTimer m_timer; // 定时器 - - QTimer *m_load; -}; - -#endif // SWITCHBUTTON_H +#ifndef SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include +#include + +class SWitchButton : public QWidget +{ + Q_OBJECT + +public: + explicit SWitchButton(QWidget *parent = 0); + + // 返回开关状态 - 打开:true 关闭:false + bool isToggled() const; + + // 设置开关状态 + void setToggle(bool checked); + + // 设置背景颜色 + void setBackgroundColor(QColor color); + + // 设置选中颜色 + void setCheckedColor(QColor color); + + // 设置不可用颜色 + void setDisbaledColor(QColor color); + + void loadAlmLink(); +public slots: + void slotSwitchButtonUsed(bool enble,bool open); +protected: + // 绘制开关 + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + // 鼠标按下事件 + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 鼠标释放事件 - 切换开关状态、发射toggled()信号 + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 大小改变事件 + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + + // 缺省大小 + QSize sizeHint() const Q_DECL_OVERRIDE; + QSize minimumSizeHint() const Q_DECL_OVERRIDE; + +signals: + // 状态改变时,发射信号 + void toggled(bool checked); + + void sigAlmLinkOpen(bool bo); + +private slots: + // 状态切换时,用于产生滑动效果 + void onTimeout(); + +private: + bool m_bChecked; // 是否选中 + QColor m_background; // 背景颜色 + QColor m_checkedColor; // 选中颜色 + QColor m_disabledColor; // 不可用颜色 + QColor m_thumbColor; // + qreal m_radius; // 圆角 + qreal m_nX; // x点坐标 + qreal m_nY; // y点坐标 + qint16 m_nHeight; // 高度 + qint16 m_nMargin; // 外边距 + QTimer m_timer; // 定时器 + + QTimer *m_load; +}; + +#endif // SWITCHBUTTON_H diff --git a/product/src/gui/plugin/RobotWidget/Slider.cpp b/product/src/gui/plugin/RobotWidget/Slider.cpp index c2ac87fb..13981231 100644 --- a/product/src/gui/plugin/RobotWidget/Slider.cpp +++ b/product/src/gui/plugin/RobotWidget/Slider.cpp @@ -1,116 +1,116 @@ -#include "Slider.h" -#include -#include -#include -#include -#include -Slider::Slider(QWidget *parent): - QSlider(parent) -{ - setOrientation(Qt::Horizontal); - setMouseTracking(true); - setWindowOpacity(0.7); -} - -Slider::~Slider() -{ - -} - -void Slider::enterEvent(QEvent *event) -{ - emit onEnter(); - QSlider::enterEvent(event); -} - -void Slider::leaveEvent(QEvent *event) -{ - emit onLeave(); - QSlider::leaveEvent(event); -} - -void Slider::mouseMoveEvent(QMouseEvent *event) -{ - const int o = style()->pixelMetric(QStyle::PM_SliderLength ) - 1; - int v = QStyle::sliderValueFromPosition(minimum(), maximum(), event->pos().x()-o/2, width()-o, false); - emit onHover(event->x(), v); - QSlider::mouseMoveEvent(event); -} - -void Slider::mousePressEvent(QMouseEvent *event) -{ - qDebug("pressed (%d, %d)", event->pos().x(), event->pos().y()); - if (event->button() == Qt::LeftButton) { - QStyleOptionSlider opt; - initStyleOption(&opt); - const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); - const QPoint center = sliderRect.center() - sliderRect.topLeft(); - // to take half of the slider off for the setSliderPosition call we use the center - topLeft - - if (!sliderRect.contains(event->pos())) { - qDebug("accept"); - event->accept(); - - int v = pixelPosToRangeValue(pick(event->pos() - center)); - setSliderPosition(v); - triggerAction(SliderMove); - setRepeatAction(SliderNoAction); - emit sliderMoved(v);//TODO: ok? - emit sliderPressed(); //TODO: ok? - } else { - QSlider::mousePressEvent(event); - } - } else { - QSlider::mousePressEvent(event); - } -} - -int Slider::pick(const QPoint &pt) const -{ - return orientation() == Qt::Horizontal ? pt.x() : pt.y(); -} - -int Slider::pixelPosToRangeValue(int pos) const -{ - QStyleOptionSlider opt; - initStyleOption(&opt); - QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); - QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); - int sliderMin, sliderMax, sliderLength; - if (orientation() == Qt::Horizontal) { - sliderLength = sr.width(); - sliderMin = gr.x(); - sliderMax = gr.right() - sliderLength + 1; - } else { - sliderLength = sr.height(); - sliderMin = gr.y(); - sliderMax = gr.bottom() - sliderLength + 1; - } - return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, - sliderMax - sliderMin, opt.upsideDown); -} - -void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const -{ - if (!option) - return; - - option->initFrom(this); - option->subControls = QStyle::SC_None; - option->activeSubControls = QStyle::SC_None; - option->orientation = orientation(); - option->maximum = maximum(); - option->minimum = minimum(); - option->tickPosition = (QSlider::TickPosition) tickPosition(); - option->tickInterval = tickInterval(); - option->upsideDown = (orientation() == Qt::Horizontal) ? - (invertedAppearance() != (option->direction == Qt::RightToLeft)) - : (!invertedAppearance()); - option->direction = Qt::LeftToRight; // we use the upsideDown option instead - option->sliderPosition = sliderPosition(); - option->sliderValue = value(); - option->singleStep = singleStep(); - option->pageStep = pageStep(); - if (orientation() == Qt::Horizontal) - option->state |= QStyle::State_Horizontal; -} +#include "Slider.h" +#include +#include +#include +#include +#include +Slider::Slider(QWidget *parent): + QSlider(parent) +{ + setOrientation(Qt::Horizontal); + setMouseTracking(true); + setWindowOpacity(0.7); +} + +Slider::~Slider() +{ + +} + +void Slider::enterEvent(QEvent *event) +{ + emit onEnter(); + QSlider::enterEvent(event); +} + +void Slider::leaveEvent(QEvent *event) +{ + emit onLeave(); + QSlider::leaveEvent(event); +} + +void Slider::mouseMoveEvent(QMouseEvent *event) +{ + const int o = style()->pixelMetric(QStyle::PM_SliderLength ) - 1; + int v = QStyle::sliderValueFromPosition(minimum(), maximum(), event->pos().x()-o/2, width()-o, false); + emit onHover(event->x(), v); + QSlider::mouseMoveEvent(event); +} + +void Slider::mousePressEvent(QMouseEvent *event) +{ + qDebug("pressed (%d, %d)", event->pos().x(), event->pos().y()); + if (event->button() == Qt::LeftButton) { + QStyleOptionSlider opt; + initStyleOption(&opt); + const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + const QPoint center = sliderRect.center() - sliderRect.topLeft(); + // to take half of the slider off for the setSliderPosition call we use the center - topLeft + + if (!sliderRect.contains(event->pos())) { + qDebug("accept"); + event->accept(); + + int v = pixelPosToRangeValue(pick(event->pos() - center)); + setSliderPosition(v); + triggerAction(SliderMove); + setRepeatAction(SliderNoAction); + emit sliderMoved(v);//TODO: ok? + emit sliderPressed(); //TODO: ok? + } else { + QSlider::mousePressEvent(event); + } + } else { + QSlider::mousePressEvent(event); + } +} + +int Slider::pick(const QPoint &pt) const +{ + return orientation() == Qt::Horizontal ? pt.x() : pt.y(); +} + +int Slider::pixelPosToRangeValue(int pos) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt); + QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); + QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + int sliderMin, sliderMax, sliderLength; + if (orientation() == Qt::Horizontal) { + sliderLength = sr.width(); + sliderMin = gr.x(); + sliderMax = gr.right() - sliderLength + 1; + } else { + sliderLength = sr.height(); + sliderMin = gr.y(); + sliderMax = gr.bottom() - sliderLength + 1; + } + return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, + sliderMax - sliderMin, opt.upsideDown); +} + +void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const +{ + if (!option) + return; + + option->initFrom(this); + option->subControls = QStyle::SC_None; + option->activeSubControls = QStyle::SC_None; + option->orientation = orientation(); + option->maximum = maximum(); + option->minimum = minimum(); + option->tickPosition = (QSlider::TickPosition) tickPosition(); + option->tickInterval = tickInterval(); + option->upsideDown = (orientation() == Qt::Horizontal) ? + (invertedAppearance() != (option->direction == Qt::RightToLeft)) + : (!invertedAppearance()); + option->direction = Qt::LeftToRight; // we use the upsideDown option instead + option->sliderPosition = sliderPosition(); + option->sliderValue = value(); + option->singleStep = singleStep(); + option->pageStep = pageStep(); + if (orientation() == Qt::Horizontal) + option->state |= QStyle::State_Horizontal; +} diff --git a/product/src/gui/plugin/RobotWidget/Slider.h b/product/src/gui/plugin/RobotWidget/Slider.h index b72a6f8c..0ce56d6a 100644 --- a/product/src/gui/plugin/RobotWidget/Slider.h +++ b/product/src/gui/plugin/RobotWidget/Slider.h @@ -1,27 +1,27 @@ -#ifndef SLIDER_H -#define SLIDER_H -#include - -class Slider : public QSlider -{ - Q_OBJECT -public: - Slider(QWidget *parent = 0); - ~Slider(); - -signals: - void onEnter(); - void onLeave(); - void onHover(int pos, int value); -protected: - virtual void enterEvent(QEvent *event); - virtual void leaveEvent(QEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - - inline int pick(const QPoint &pt) const; - int pixelPosToRangeValue(int pos) const; - void initStyleOption_Qt430(QStyleOptionSlider *option) const; -}; - -#endif // SLIDER_H +#ifndef SLIDER_H +#define SLIDER_H +#include + +class Slider : public QSlider +{ + Q_OBJECT +public: + Slider(QWidget *parent = 0); + ~Slider(); + +signals: + void onEnter(); + void onLeave(); + void onHover(int pos, int value); +protected: + virtual void enterEvent(QEvent *event); + virtual void leaveEvent(QEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + + inline int pick(const QPoint &pt) const; + int pixelPosToRangeValue(int pos) const; + void initStyleOption_Qt430(QStyleOptionSlider *option) const; +}; + +#endif // SLIDER_H diff --git a/product/src/gui/plugin/RobotWidget/VoiceSlider.cpp b/product/src/gui/plugin/RobotWidget/VoiceSlider.cpp index 79df3689..5edc7320 100644 --- a/product/src/gui/plugin/RobotWidget/VoiceSlider.cpp +++ b/product/src/gui/plugin/RobotWidget/VoiceSlider.cpp @@ -1,77 +1,77 @@ -#include "VoiceSlider.h" -#include "ui_VoiceSlider.h" - -VoiceSlider::VoiceSlider(int voice,bool bo, QWidget *parent, Qt::WindowFlags f) : - QWidget(parent,f), - m_bo(bo), - m_isShow(false), - ui(new Ui::VoiceSlider) -{ - ui->setupUi(this); - ui->voiceOpen->setObjectName("m_voiceOpen"); - ui->voiceClose->setObjectName("m_voiceClose"); - m_voice = voice; - setWindowOpacity(0.5); - connect(ui->horizontalSlider,&QSlider::valueChanged,this,&VoiceSlider::slotSetVoice); - connect(ui->voiceOpen,&QPushButton::clicked,this,&VoiceSlider::slotCloseVoice); - connect(ui->voiceClose,&QPushButton::clicked,this,&VoiceSlider::slotOpenVoice); - ui->horizontalSlider->setValue(m_voice); - setButtonShow(m_bo); -} - -VoiceSlider::~VoiceSlider() -{ - delete ui; -} - -void VoiceSlider::slotSetVoice(int value) -{ - ui->label->setText(QString("%1").arg(value)); - m_voice = value; - if(value == 0) - { - setButtonShow(false); - emit sigVoiceClose(value); - }else - { - setButtonShow(true); - emit sigVoiceOpen(value); - } -} - -void VoiceSlider::slotCloseVoice() -{ - setButtonShow(false); - emit sigVoiceClose(0); -} - -void VoiceSlider::slotOpenVoice() -{ - setButtonShow(true); - emit sigVoiceOpen(m_voice); -} - -void VoiceSlider::setStatus(bool show) -{ - m_isShow = show; -} - -bool VoiceSlider::getStatus() -{ - return m_isShow; -} - -void VoiceSlider::setButtonShow(bool show) -{ - if(show) - { - m_bo = show; - ui->voiceOpen->setHidden(false); - ui->voiceClose->setHidden(true); - }else - { - m_bo = !show; - ui->voiceOpen->setHidden(true); - ui->voiceClose->setHidden(false); - } -} +#include "VoiceSlider.h" +#include "ui_VoiceSlider.h" + +VoiceSlider::VoiceSlider(int voice,bool bo, QWidget *parent, Qt::WindowFlags f) : + QWidget(parent,f), + m_bo(bo), + m_isShow(false), + ui(new Ui::VoiceSlider) +{ + ui->setupUi(this); + ui->voiceOpen->setObjectName("m_voiceOpen"); + ui->voiceClose->setObjectName("m_voiceClose"); + m_voice = voice; + setWindowOpacity(0.5); + connect(ui->horizontalSlider,&QSlider::valueChanged,this,&VoiceSlider::slotSetVoice); + connect(ui->voiceOpen,&QPushButton::clicked,this,&VoiceSlider::slotCloseVoice); + connect(ui->voiceClose,&QPushButton::clicked,this,&VoiceSlider::slotOpenVoice); + ui->horizontalSlider->setValue(m_voice); + setButtonShow(m_bo); +} + +VoiceSlider::~VoiceSlider() +{ + delete ui; +} + +void VoiceSlider::slotSetVoice(int value) +{ + ui->label->setText(QString("%1").arg(value)); + m_voice = value; + if(value == 0) + { + setButtonShow(false); + emit sigVoiceClose(value); + }else + { + setButtonShow(true); + emit sigVoiceOpen(value); + } +} + +void VoiceSlider::slotCloseVoice() +{ + setButtonShow(false); + emit sigVoiceClose(0); +} + +void VoiceSlider::slotOpenVoice() +{ + setButtonShow(true); + emit sigVoiceOpen(m_voice); +} + +void VoiceSlider::setStatus(bool show) +{ + m_isShow = show; +} + +bool VoiceSlider::getStatus() +{ + return m_isShow; +} + +void VoiceSlider::setButtonShow(bool show) +{ + if(show) + { + m_bo = show; + ui->voiceOpen->setHidden(false); + ui->voiceClose->setHidden(true); + }else + { + m_bo = !show; + ui->voiceOpen->setHidden(true); + ui->voiceClose->setHidden(false); + } +} diff --git a/product/src/gui/plugin/RobotWidget/VoiceSlider.h b/product/src/gui/plugin/RobotWidget/VoiceSlider.h index c4ac8e66..192c6bec 100644 --- a/product/src/gui/plugin/RobotWidget/VoiceSlider.h +++ b/product/src/gui/plugin/RobotWidget/VoiceSlider.h @@ -1,36 +1,36 @@ -#ifndef VOICESLIDER_H -#define VOICESLIDER_H - -#include - -namespace Ui { -class VoiceSlider; -} - -class VoiceSlider : public QWidget -{ - Q_OBJECT - -public: - explicit VoiceSlider(int voice,bool bo,QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); - ~VoiceSlider(); -signals: - void sigVoiceClose(int value); - void sigVoiceOpen(int value); -public: - void slotSetVoice(int value); - void slotCloseVoice(); - void slotOpenVoice(); - void setStatus(bool show); - bool getStatus(); - bool m_isShow; -private: - void setButtonShow(bool show); -private: - - Ui::VoiceSlider *ui; - int m_voice; - bool m_bo; -}; - -#endif // VOICESLIDER_H +#ifndef VOICESLIDER_H +#define VOICESLIDER_H + +#include + +namespace Ui { +class VoiceSlider; +} + +class VoiceSlider : public QWidget +{ + Q_OBJECT + +public: + explicit VoiceSlider(int voice,bool bo,QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags()); + ~VoiceSlider(); +signals: + void sigVoiceClose(int value); + void sigVoiceOpen(int value); +public: + void slotSetVoice(int value); + void slotCloseVoice(); + void slotOpenVoice(); + void setStatus(bool show); + bool getStatus(); + bool m_isShow; +private: + void setButtonShow(bool show); +private: + + Ui::VoiceSlider *ui; + int m_voice; + bool m_bo; +}; + +#endif // VOICESLIDER_H diff --git a/product/src/gui/plugin/RobotWidget/VoiceSlider.ui b/product/src/gui/plugin/RobotWidget/VoiceSlider.ui index c6c22443..dc2b07a1 100644 --- a/product/src/gui/plugin/RobotWidget/VoiceSlider.ui +++ b/product/src/gui/plugin/RobotWidget/VoiceSlider.ui @@ -1,125 +1,125 @@ - - - VoiceSlider - - - - 0 - 0 - 194 - 34 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - 26 - - - - - 30 - 16777215 - - - - - - - - - - - - 0 - 26 - - - - - 30 - 16777215 - - - - - - - - - - - Qt::Horizontal - - - - - - - - 30 - 0 - - - - Qt::LeftToRight - - - - - - 53 - - - Qt::AlignCenter - - - - - - - - - - - - - + + + VoiceSlider + + + + 0 + 0 + 194 + 34 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 26 + + + + + 30 + 16777215 + + + + + + + + + + + + 0 + 26 + + + + + 30 + 16777215 + + + + + + + + + + + Qt::Horizontal + + + + + + + + 30 + 0 + + + + Qt::LeftToRight + + + + + + 53 + + + Qt::AlignCenter + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/RobotWidget/main.cpp b/product/src/gui/plugin/RobotWidget/main.cpp index 54bc2a50..b11740fe 100644 --- a/product/src/gui/plugin/RobotWidget/main.cpp +++ b/product/src/gui/plugin/RobotWidget/main.cpp @@ -1,24 +1,24 @@ -#include "CRobotWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - { - CRobotWidget w(false,NULL); - w.initialize(); - w.show(); - a.exec(); - } - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "CRobotWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + { + CRobotWidget w(false,NULL); + w.initialize(); + w.show(); + a.exec(); + } + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/ScheduleWidget/CDragListWidget.cpp b/product/src/gui/plugin/ScheduleWidget/CDragListWidget.cpp index d7739492..0a615a2e 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDragListWidget.cpp +++ b/product/src/gui/plugin/ScheduleWidget/CDragListWidget.cpp @@ -1,46 +1,46 @@ -#include "CDragListWidget.h" - -CDragListWidget::CDragListWidget( QWidget *parent ) - :QListWidget(parent) -{ - this->setDragEnabled( true ); - this->setAcceptDrops( false ); - this->setDragDropMode( QAbstractItemView::DragOnly ); -} - -CDragListWidget::~CDragListWidget() -{ - -} - -void CDragListWidget::mousePressEvent( QMouseEvent *pEvent ) -{ - QListWidget::mousePressEvent( pEvent ); - - QListWidgetItem *pItem = this->currentItem(); - if ( pItem != NULL ) - { - QDrag *drag = new QDrag(this); - QMimeData *data = new QMimeData; - data->setData( "name", pItem->data(Qt::UserRole).toString().toUtf8() ); - data->setData( "alias", pItem->text().toUtf8() ); - drag->setMimeData(data); - - QPixmap drag_img(100, 28); - drag_img.fill( QColor(255,255,0) ); - QPainter painter(&drag_img); - painter.drawText(QRectF(0,0, 100,28), pItem->text(), QTextOption(Qt::AlignVCenter)); - - drag->setPixmap(drag_img); - drag->exec(Qt::MoveAction); - } - pEvent->accept(); -} - - - - - - - - +#include "CDragListWidget.h" + +CDragListWidget::CDragListWidget( QWidget *parent ) + :QListWidget(parent) +{ + this->setDragEnabled( true ); + this->setAcceptDrops( false ); + this->setDragDropMode( QAbstractItemView::DragOnly ); +} + +CDragListWidget::~CDragListWidget() +{ + +} + +void CDragListWidget::mousePressEvent( QMouseEvent *pEvent ) +{ + QListWidget::mousePressEvent( pEvent ); + + QListWidgetItem *pItem = this->currentItem(); + if ( pItem != NULL ) + { + QDrag *drag = new QDrag(this); + QMimeData *data = new QMimeData; + data->setData( "name", pItem->data(Qt::UserRole).toString().toUtf8() ); + data->setData( "alias", pItem->text().toUtf8() ); + drag->setMimeData(data); + + QPixmap drag_img(100, 28); + drag_img.fill( QColor(255,255,0) ); + QPainter painter(&drag_img); + painter.drawText(QRectF(0,0, 100,28), pItem->text(), QTextOption(Qt::AlignVCenter)); + + drag->setPixmap(drag_img); + drag->exec(Qt::MoveAction); + } + pEvent->accept(); +} + + + + + + + + diff --git a/product/src/gui/plugin/ScheduleWidget/CDragListWidget.h b/product/src/gui/plugin/ScheduleWidget/CDragListWidget.h index 4fe6586c..efa9a9bd 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDragListWidget.h +++ b/product/src/gui/plugin/ScheduleWidget/CDragListWidget.h @@ -1,25 +1,25 @@ -#ifndef CDRAGLISTWIDGET_H -#define CDRAGLISTWIDGET_H - -#include -#include -#include -#include -#include -#include -#include - -class CDragListWidget : public QListWidget -{ - Q_OBJECT - -public: - explicit CDragListWidget( QWidget *parent = Q_NULLPTR ); - ~CDragListWidget(); - -protected: - void mousePressEvent( QMouseEvent *pEvent ); -}; - - -#endif // CDRAGLISTWIDGET_H +#ifndef CDRAGLISTWIDGET_H +#define CDRAGLISTWIDGET_H + +#include +#include +#include +#include +#include +#include +#include + +class CDragListWidget : public QListWidget +{ + Q_OBJECT + +public: + explicit CDragListWidget( QWidget *parent = Q_NULLPTR ); + ~CDragListWidget(); + +protected: + void mousePressEvent( QMouseEvent *pEvent ); +}; + + +#endif // CDRAGLISTWIDGET_H diff --git a/product/src/gui/plugin/ScheduleWidget/CDropListWidget.cpp b/product/src/gui/plugin/ScheduleWidget/CDropListWidget.cpp index 93e8ed14..9a47cd27 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDropListWidget.cpp +++ b/product/src/gui/plugin/ScheduleWidget/CDropListWidget.cpp @@ -1,101 +1,101 @@ -#include "CDropListWidget.h" - -CDropListWidget::CDropListWidget() -{ - this->setDragEnabled( false ); - this->setAcceptDrops( true ); - this->setDragDropMode( QAbstractItemView::DropOnly ); - setContextMenuPolicy( Qt::CustomContextMenu ); - connect( this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(slotListWidgetContextMenuRequest(const QPoint&)) ); - m_bModify = false; - - this->setObjectName("dropWidget"); -} - -CDropListWidget::~CDropListWidget() -{ - -} - -void CDropListWidget::dragEnterEvent( QDragEnterEvent *pEvent ) -{ - pEvent->setDropAction(Qt::MoveAction); - pEvent->accept(); -} - -void CDropListWidget::dragMoveEvent( QDragMoveEvent *pEvent ) -{ - pEvent->setDropAction(Qt::MoveAction); - pEvent->accept(); -} - -void CDropListWidget::dropEvent( QDropEvent *pEvent ) -{ - QString sName = pEvent->mimeData()->data("name"); - QString sAlias = pEvent->mimeData()->data("alias"); - - int i = 0; - for ( i=0; idata(Qt::UserRole).toString() == sName ) - break; - } - if ( i >= count() ) - {// 没找到同名的 - QListWidgetItem* pTmpItem = new QListWidgetItem(sAlias); - //pTmpItem->setFlags( pTmpItem->flags()|Qt::ItemIsUserCheckable ); - //pTmpItem->setCheckState( Qt::Unchecked ); - pTmpItem->setData( Qt::UserRole, sName ); - addItem( pTmpItem ); - m_bModify = true; - } - - pEvent->setDropAction(Qt::MoveAction); - pEvent->accept(); -} - -void CDropListWidget::focusInEvent( QFocusEvent* ) -{ - emit focusIn(); -} - -void CDropListWidget::slotListWidgetContextMenuRequest( const QPoint& ) -{ - QListWidgetItem* pItem = currentItem(); - if ( pItem == NULL ) - return; - - QMenu menu; - menu.addAction( tr("删除选中项"), this, SLOT(slotDeleteOneItem()) ); - menu.exec( QCursor::pos() ); -} - -void CDropListWidget::slotDeleteOneItem() -{ -// QListWidgetItem* pItem = currentItem(); -// if ( pItem == NULL ) -// return; - - for ( int i=this->count()-1; i>=0; i-- ) - { - QListWidgetItem*pItem = this->item(i); - if ( pItem->isSelected() ) - { - removeItemWidget( pItem ); - delete pItem; - } - } -} - -bool CDropListWidget::event( QEvent *pEvent ) -{ - //qDebug()<type(); - //qDebug()<type(); - return QListWidget::event( pEvent ); -} - - - - - - +#include "CDropListWidget.h" + +CDropListWidget::CDropListWidget() +{ + this->setDragEnabled( false ); + this->setAcceptDrops( true ); + this->setDragDropMode( QAbstractItemView::DropOnly ); + setContextMenuPolicy( Qt::CustomContextMenu ); + connect( this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(slotListWidgetContextMenuRequest(const QPoint&)) ); + m_bModify = false; + + this->setObjectName("dropWidget"); +} + +CDropListWidget::~CDropListWidget() +{ + +} + +void CDropListWidget::dragEnterEvent( QDragEnterEvent *pEvent ) +{ + pEvent->setDropAction(Qt::MoveAction); + pEvent->accept(); +} + +void CDropListWidget::dragMoveEvent( QDragMoveEvent *pEvent ) +{ + pEvent->setDropAction(Qt::MoveAction); + pEvent->accept(); +} + +void CDropListWidget::dropEvent( QDropEvent *pEvent ) +{ + QString sName = pEvent->mimeData()->data("name"); + QString sAlias = pEvent->mimeData()->data("alias"); + + int i = 0; + for ( i=0; idata(Qt::UserRole).toString() == sName ) + break; + } + if ( i >= count() ) + {// 没找到同名的 + QListWidgetItem* pTmpItem = new QListWidgetItem(sAlias); + //pTmpItem->setFlags( pTmpItem->flags()|Qt::ItemIsUserCheckable ); + //pTmpItem->setCheckState( Qt::Unchecked ); + pTmpItem->setData( Qt::UserRole, sName ); + addItem( pTmpItem ); + m_bModify = true; + } + + pEvent->setDropAction(Qt::MoveAction); + pEvent->accept(); +} + +void CDropListWidget::focusInEvent( QFocusEvent* ) +{ + emit focusIn(); +} + +void CDropListWidget::slotListWidgetContextMenuRequest( const QPoint& ) +{ + QListWidgetItem* pItem = currentItem(); + if ( pItem == NULL ) + return; + + QMenu menu; + menu.addAction( tr("删除选中项"), this, SLOT(slotDeleteOneItem()) ); + menu.exec( QCursor::pos() ); +} + +void CDropListWidget::slotDeleteOneItem() +{ +// QListWidgetItem* pItem = currentItem(); +// if ( pItem == NULL ) +// return; + + for ( int i=this->count()-1; i>=0; i-- ) + { + QListWidgetItem*pItem = this->item(i); + if ( pItem->isSelected() ) + { + removeItemWidget( pItem ); + delete pItem; + } + } +} + +bool CDropListWidget::event( QEvent *pEvent ) +{ + //qDebug()<type(); + //qDebug()<type(); + return QListWidget::event( pEvent ); +} + + + + + + diff --git a/product/src/gui/plugin/ScheduleWidget/CDropListWidget.h b/product/src/gui/plugin/ScheduleWidget/CDropListWidget.h index 0bc65ea2..c76610f6 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDropListWidget.h +++ b/product/src/gui/plugin/ScheduleWidget/CDropListWidget.h @@ -1,45 +1,45 @@ -#ifndef CDROPLISTWIDGET_H -#define CDROPLISTWIDGET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class CDropListWidget : public QListWidget -{ - Q_OBJECT - -public: - CDropListWidget(); - ~CDropListWidget(); - -protected: - void dragEnterEvent( QDragEnterEvent *pEvent ); - void dragMoveEvent( QDragMoveEvent *pEvent ); - void dropEvent( QDropEvent *pEvent ); - void focusInEvent( QFocusEvent* pEvent ); - bool event( QEvent *pEvent ); - -signals: - void focusIn(); - -public slots: - void slotListWidgetContextMenuRequest( const QPoint& ); - void slotDeleteOneItem(); - -public: - bool m_bModify;// 加载过后是否被修改过,保存后需要置false -}; - -#endif // CDROPLISTWIDGET_H +#ifndef CDROPLISTWIDGET_H +#define CDROPLISTWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class CDropListWidget : public QListWidget +{ + Q_OBJECT + +public: + CDropListWidget(); + ~CDropListWidget(); + +protected: + void dragEnterEvent( QDragEnterEvent *pEvent ); + void dragMoveEvent( QDragMoveEvent *pEvent ); + void dropEvent( QDropEvent *pEvent ); + void focusInEvent( QFocusEvent* pEvent ); + bool event( QEvent *pEvent ); + +signals: + void focusIn(); + +public slots: + void slotListWidgetContextMenuRequest( const QPoint& ); + void slotDeleteOneItem(); + +public: + bool m_bModify;// 加载过后是否被修改过,保存后需要置false +}; + +#endif // CDROPLISTWIDGET_H diff --git a/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.cpp b/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.cpp index 2880c9fb..fadcc9d9 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.cpp +++ b/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.cpp @@ -1,252 +1,252 @@ -#include "CDutyDefineDialog.h" -#include "ui_CDutyDefineDialog.h" - -using namespace kbd_public; -using namespace kbd_dbms; -using namespace kbd_service; - -CDutyDefineDialog::CDutyDefineDialog( QWidget *parent ) : - QDialog(parent), - ui(new Ui::CDutyDefineDialog) -{ - ui->setupUi(this); - - setWindowTitle( "班次管理" ); - - //ui->t - QStringList listHeader; - listHeader << "序号" << "班次" << "开始时间" << "结束时间"; - ui->tableWidget->setColumnCount( listHeader.count() ); - ui->tableWidget->setHorizontalHeaderLabels( listHeader ); - ui->tableWidget->setColumnWidth( 0, 50 ); - ui->tableWidget->setColumnWidth( 1, 100 ); - ui->tableWidget->setColumnWidth( 2, 100 ); - ui->tableWidget->horizontalHeader()->setStretchLastSection( true ); - ui->tableWidget->verticalHeader()->hide(); - - loadData(); - - connect( ui->pushButton_add, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonAddClicked(bool)) ); - connect( ui->pushButton_del, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonDelClicked(bool)) ); - connect( ui->pushButton_save, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonSaveClicked(bool)) ); -} - -CDutyDefineDialog::~CDutyDefineDialog() -{ - delete ui; -} - -bool CDutyDefineDialog::checkUserPerm() -{ - CPermMngApiPtr pPermMng = getPermMngInstance("BASE"); - if (pPermMng == NULL) - { - LOGERROR("CDutySetting::checkUserPerm(), getPermMngInstance error"); - return false; - }; - - std::string tmp = "FUNC_NOM_DUTY"; - if ( pPermMng->PermCheck(PERM_NOM_FUNC_DEF,&tmp) == PERM_PERMIT ) - return true; - - return false; -} - -void CDutyDefineDialog::loadData() -{ - kbd_dbms::CDbApi* pDb = new CDbApi(DB_CONN_MODEL_READ); - if ( !pDb->open() ) - { - LOGERROR("initialize or open database failed!"); - delete pDb; - pDb = NULL; - return ; - } - LOGINFO("DatabaseName: [%s]", pDb->getCurrentDbPara().getDatabaseName().toStdString().c_str()); - LOGINFO("HostName: [%s]", pDb->getCurrentDbPara().getHostName().toStdString().c_str()); - LOGINFO("UserName: [%s]", pDb->getCurrentDbPara().getUserName().toStdString().c_str()); - - QSqlQuery query; - QString sSql = QString("select ID,NAME,START_TIME,END_TIME from duty_define order by ID"); - if ( pDb->execute(sSql, query) ) - { - while( query.next() ) - { - int nRow = ui->tableWidget->rowCount(); - ui->tableWidget->insertRow( nRow ); - QTableWidgetItem* pItem0 = new QTableWidgetItem(query.value(0).toString()); - pItem0->setFlags( pItem0->flags() & (~Qt::ItemIsEditable) ); - pItem0->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( nRow, 0, pItem0 ); - QTableWidgetItem* pItem1 = new QTableWidgetItem(query.value(1).toString()); - pItem1->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( nRow, 1, pItem1 ); - QTableWidgetItem* pItem2 = new QTableWidgetItem(query.value(2).toString()); - pItem2->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( nRow, 2, pItem2 ); - QTableWidgetItem* pItem3 = new QTableWidgetItem(query.value(3).toString()); - pItem3->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( nRow, 3, pItem3 ); - } - query.clear(); - } - - pDb->close(); - delete pDb; - pDb = NULL; -} - -void CDutyDefineDialog::slotPushButtonAddClicked( bool ) -{ - int nRow = ui->tableWidget->rowCount(); - ui->tableWidget->insertRow( nRow ); - QTableWidgetItem* pItem0 = new QTableWidgetItem(QString::number(nRow+1)); - pItem0->setFlags( pItem0->flags() & (~Qt::ItemIsEditable) ); - pItem0->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( nRow, 0, pItem0 ); - QTableWidgetItem* pItem1 = new QTableWidgetItem(QString("班次%1").arg(nRow+1)); - pItem1->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( nRow, 1, pItem1 ); - QTableWidgetItem* pItem2 = new QTableWidgetItem("00:00"); - pItem2->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( nRow, 2, pItem2 ); - QTableWidgetItem* pItem3 = new QTableWidgetItem("00:00"); - pItem3->setTextAlignment( Qt::AlignCenter ); - ui->tableWidget->setItem( nRow, 3, pItem3 ); -} - -void CDutyDefineDialog::slotPushButtonDelClicked( bool ) -{ - int nRow = ui->tableWidget->rowCount(); - if ( nRow > 0 ) - ui->tableWidget->removeRow( nRow - 1 ); -} - -void CDutyDefineDialog::slotPushButtonSaveClicked( bool ) -{ - // 判断班次名称是否有重复 - for ( int i=0; itableWidget->rowCount(); i++ ) - { - if ( ui->tableWidget->item(i,1)->text() == "" ) - { - QMessageBox::critical( 0, "错误", "班次名称不能为空" ); - return; - } - - for ( int l=i+1; ltableWidget->rowCount(); l++ ) - { - if ( ui->tableWidget->item(i,1)->text() == ui->tableWidget->item(l,1)->text() ) - { - QMessageBox::critical( 0, "错误", "班次名称不能有重复" ); - return; - } - } - - QTime t1 = QTime::fromString( ui->tableWidget->item(i,2)->text(), "hh:mm" ); - QTime t2 = QTime::fromString( ui->tableWidget->item(i,3)->text(), "hh:mm" ); - if ( !t1.isValid() || !t2.isValid() ) - { - QMessageBox::critical( 0, "错误", QString("第 %1 行时间格式不合法").arg(i+1) ); - return; - } - } - - // 判断用户权限 - if ( checkUserPerm() == false ) - { - QMessageBox::critical( 0, "错误", "用户权限验证失败" ); - return; - } - - // 判断数据是否为空 - if ( ui->tableWidget->rowCount() <= 0 ) - { - QMessageBox::critical( 0, "错误", "班次定义不能为空" ); - return; - } - - // 创建数据库访问对象 - kbd_dbms::CDbApi* pDb = new CDbApi(DB_CONN_MODEL_WRITE); - if ( !pDb->open() ) - { - LOGERROR("initialize or open database failed!"); - delete pDb; - pDb = NULL; - return ; - } - - // 清空表 - QString sSql = QString("truncate table duty_define"); - if ( pDb->execute(sSql) == false ) - { - LOGERROR("CDutyDefineDialog::delete duty_define SQL execute error.%s", sSql.toStdString().c_str()); - QMessageBox::warning( 0, "警告", "保存失败!" ); - } - else - { - // 插入数据 - for ( int i=0; itableWidget->rowCount(); i++ ) - { - sSql = QString("insert into duty_define (ID,NAME,START_TIME,END_TIME) value (%1,'%2','%3','%4')") - .arg(ui->tableWidget->item(i,0)->text()) - .arg(ui->tableWidget->item(i,1)->text()) - .arg(ui->tableWidget->item(i,2)->text()) - .arg(ui->tableWidget->item(i,3)->text()); - if ( pDb->execute(sSql) == false ) - { - LOGERROR("CDutyDefineDialog::save duty_define SQL execute error ."); - QMessageBox::warning( 0, "警告", "保存失败!" ); - break; - } - } - } - - // 删除数据库对象 - pDb->close(); - delete pDb; - pDb = NULL; - - // 发送保存完成信号 - emit signalDutyDefineSaved(); - - // 提示完成 - QMessageBox::information( 0, "提示", "保存完成" ); -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#include "CDutyDefineDialog.h" +#include "ui_CDutyDefineDialog.h" + +using namespace kbd_public; +using namespace kbd_dbms; +using namespace kbd_service; + +CDutyDefineDialog::CDutyDefineDialog( QWidget *parent ) : + QDialog(parent), + ui(new Ui::CDutyDefineDialog) +{ + ui->setupUi(this); + + setWindowTitle( "班次管理" ); + + //ui->t + QStringList listHeader; + listHeader << "序号" << "班次" << "开始时间" << "结束时间"; + ui->tableWidget->setColumnCount( listHeader.count() ); + ui->tableWidget->setHorizontalHeaderLabels( listHeader ); + ui->tableWidget->setColumnWidth( 0, 50 ); + ui->tableWidget->setColumnWidth( 1, 100 ); + ui->tableWidget->setColumnWidth( 2, 100 ); + ui->tableWidget->horizontalHeader()->setStretchLastSection( true ); + ui->tableWidget->verticalHeader()->hide(); + + loadData(); + + connect( ui->pushButton_add, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonAddClicked(bool)) ); + connect( ui->pushButton_del, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonDelClicked(bool)) ); + connect( ui->pushButton_save, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonSaveClicked(bool)) ); +} + +CDutyDefineDialog::~CDutyDefineDialog() +{ + delete ui; +} + +bool CDutyDefineDialog::checkUserPerm() +{ + CPermMngApiPtr pPermMng = getPermMngInstance("BASE"); + if (pPermMng == NULL) + { + LOGERROR("CDutySetting::checkUserPerm(), getPermMngInstance error"); + return false; + }; + + std::string tmp = "FUNC_NOM_DUTY"; + if ( pPermMng->PermCheck(PERM_NOM_FUNC_DEF,&tmp) == PERM_PERMIT ) + return true; + + return false; +} + +void CDutyDefineDialog::loadData() +{ + kbd_dbms::CDbApi* pDb = new CDbApi(DB_CONN_MODEL_READ); + if ( !pDb->open() ) + { + LOGERROR("initialize or open database failed!"); + delete pDb; + pDb = NULL; + return ; + } + LOGINFO("DatabaseName: [%s]", pDb->getCurrentDbPara().getDatabaseName().toStdString().c_str()); + LOGINFO("HostName: [%s]", pDb->getCurrentDbPara().getHostName().toStdString().c_str()); + LOGINFO("UserName: [%s]", pDb->getCurrentDbPara().getUserName().toStdString().c_str()); + + QSqlQuery query; + QString sSql = QString("select ID,NAME,START_TIME,END_TIME from duty_define order by ID"); + if ( pDb->execute(sSql, query) ) + { + while( query.next() ) + { + int nRow = ui->tableWidget->rowCount(); + ui->tableWidget->insertRow( nRow ); + QTableWidgetItem* pItem0 = new QTableWidgetItem(query.value(0).toString()); + pItem0->setFlags( pItem0->flags() & (~Qt::ItemIsEditable) ); + pItem0->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( nRow, 0, pItem0 ); + QTableWidgetItem* pItem1 = new QTableWidgetItem(query.value(1).toString()); + pItem1->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( nRow, 1, pItem1 ); + QTableWidgetItem* pItem2 = new QTableWidgetItem(query.value(2).toString()); + pItem2->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( nRow, 2, pItem2 ); + QTableWidgetItem* pItem3 = new QTableWidgetItem(query.value(3).toString()); + pItem3->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( nRow, 3, pItem3 ); + } + query.clear(); + } + + pDb->close(); + delete pDb; + pDb = NULL; +} + +void CDutyDefineDialog::slotPushButtonAddClicked( bool ) +{ + int nRow = ui->tableWidget->rowCount(); + ui->tableWidget->insertRow( nRow ); + QTableWidgetItem* pItem0 = new QTableWidgetItem(QString::number(nRow+1)); + pItem0->setFlags( pItem0->flags() & (~Qt::ItemIsEditable) ); + pItem0->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( nRow, 0, pItem0 ); + QTableWidgetItem* pItem1 = new QTableWidgetItem(QString("班次%1").arg(nRow+1)); + pItem1->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( nRow, 1, pItem1 ); + QTableWidgetItem* pItem2 = new QTableWidgetItem("00:00"); + pItem2->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( nRow, 2, pItem2 ); + QTableWidgetItem* pItem3 = new QTableWidgetItem("00:00"); + pItem3->setTextAlignment( Qt::AlignCenter ); + ui->tableWidget->setItem( nRow, 3, pItem3 ); +} + +void CDutyDefineDialog::slotPushButtonDelClicked( bool ) +{ + int nRow = ui->tableWidget->rowCount(); + if ( nRow > 0 ) + ui->tableWidget->removeRow( nRow - 1 ); +} + +void CDutyDefineDialog::slotPushButtonSaveClicked( bool ) +{ + // 判断班次名称是否有重复 + for ( int i=0; itableWidget->rowCount(); i++ ) + { + if ( ui->tableWidget->item(i,1)->text() == "" ) + { + QMessageBox::critical( 0, "错误", "班次名称不能为空" ); + return; + } + + for ( int l=i+1; ltableWidget->rowCount(); l++ ) + { + if ( ui->tableWidget->item(i,1)->text() == ui->tableWidget->item(l,1)->text() ) + { + QMessageBox::critical( 0, "错误", "班次名称不能有重复" ); + return; + } + } + + QTime t1 = QTime::fromString( ui->tableWidget->item(i,2)->text(), "hh:mm" ); + QTime t2 = QTime::fromString( ui->tableWidget->item(i,3)->text(), "hh:mm" ); + if ( !t1.isValid() || !t2.isValid() ) + { + QMessageBox::critical( 0, "错误", QString("第 %1 行时间格式不合法").arg(i+1) ); + return; + } + } + + // 判断用户权限 + if ( checkUserPerm() == false ) + { + QMessageBox::critical( 0, "错误", "用户权限验证失败" ); + return; + } + + // 判断数据是否为空 + if ( ui->tableWidget->rowCount() <= 0 ) + { + QMessageBox::critical( 0, "错误", "班次定义不能为空" ); + return; + } + + // 创建数据库访问对象 + kbd_dbms::CDbApi* pDb = new CDbApi(DB_CONN_MODEL_WRITE); + if ( !pDb->open() ) + { + LOGERROR("initialize or open database failed!"); + delete pDb; + pDb = NULL; + return ; + } + + // 清空表 + QString sSql = QString("truncate table duty_define"); + if ( pDb->execute(sSql) == false ) + { + LOGERROR("CDutyDefineDialog::delete duty_define SQL execute error.%s", sSql.toStdString().c_str()); + QMessageBox::warning( 0, "警告", "保存失败!" ); + } + else + { + // 插入数据 + for ( int i=0; itableWidget->rowCount(); i++ ) + { + sSql = QString("insert into duty_define (ID,NAME,START_TIME,END_TIME) value (%1,'%2','%3','%4')") + .arg(ui->tableWidget->item(i,0)->text()) + .arg(ui->tableWidget->item(i,1)->text()) + .arg(ui->tableWidget->item(i,2)->text()) + .arg(ui->tableWidget->item(i,3)->text()); + if ( pDb->execute(sSql) == false ) + { + LOGERROR("CDutyDefineDialog::save duty_define SQL execute error ."); + QMessageBox::warning( 0, "警告", "保存失败!" ); + break; + } + } + } + + // 删除数据库对象 + pDb->close(); + delete pDb; + pDb = NULL; + + // 发送保存完成信号 + emit signalDutyDefineSaved(); + + // 提示完成 + QMessageBox::information( 0, "提示", "保存完成" ); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.h b/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.h index 60d7cfd8..55f2acfd 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.h +++ b/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.h @@ -1,38 +1,38 @@ -#ifndef CDUTYDEFINEDIALOG_H -#define CDUTYDEFINEDIALOG_H - -#include -#include -#include "db_api_ex/CDbApi.h" -#include "pub_logger_api/logger.h" -#include "service/perm_mng_api/PermMngApi.h" - -namespace Ui { -class CDutyDefineDialog; -} - -class CDutyDefineDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CDutyDefineDialog(QWidget *parent = 0); - ~CDutyDefineDialog(); - -public: - void loadData(); - bool checkUserPerm(); - -signals: - void signalDutyDefineSaved(); - -public slots: - void slotPushButtonAddClicked( bool bChecked ); - void slotPushButtonDelClicked( bool bChecked ); - void slotPushButtonSaveClicked( bool bChecked ); - -private: - Ui::CDutyDefineDialog *ui; -}; - -#endif // CDUTYDEFINEDIALOG_H +#ifndef CDUTYDEFINEDIALOG_H +#define CDUTYDEFINEDIALOG_H + +#include +#include +#include "db_api_ex/CDbApi.h" +#include "pub_logger_api/logger.h" +#include "service/perm_mng_api/PermMngApi.h" + +namespace Ui { +class CDutyDefineDialog; +} + +class CDutyDefineDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CDutyDefineDialog(QWidget *parent = 0); + ~CDutyDefineDialog(); + +public: + void loadData(); + bool checkUserPerm(); + +signals: + void signalDutyDefineSaved(); + +public slots: + void slotPushButtonAddClicked( bool bChecked ); + void slotPushButtonDelClicked( bool bChecked ); + void slotPushButtonSaveClicked( bool bChecked ); + +private: + Ui::CDutyDefineDialog *ui; +}; + +#endif // CDUTYDEFINEDIALOG_H diff --git a/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.ui b/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.ui index 8ddfaed1..01dac1e4 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.ui +++ b/product/src/gui/plugin/ScheduleWidget/CDutyDefineDialog.ui @@ -1,75 +1,75 @@ - - - CDutyDefineDialog - - - - 0 - 0 - 448 - 330 - - - - Dialog - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 添加一行 - - - - - - - 删除最后一行 - - - - - - - 保存 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - + + + CDutyDefineDialog + + + + 0 + 0 + 448 + 330 + + + + Dialog + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 添加一行 + + + + + + + 删除最后一行 + + + + + + + 保存 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/product/src/gui/plugin/ScheduleWidget/CDutySetting.cpp b/product/src/gui/plugin/ScheduleWidget/CDutySetting.cpp index da46e20f..dd7e80cc 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutySetting.cpp +++ b/product/src/gui/plugin/ScheduleWidget/CDutySetting.cpp @@ -1,708 +1,708 @@ -#include "CDutySetting.h" -#include "ui_CDutySetting.h" -#include -#include "pub_utility_api/FileStyle.h" - -using namespace kbd_public; -using namespace kbd_dbms; -using namespace kbd_service; - -CDutySetting::CDutySetting(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CDutySetting), - m_bEditMode( editMode ) -{ - ui->setupUi(this); - - m_pAlmApiForApp = NULL; - m_pDb = NULL; - m_chkUserTimer = NULL; - m_pDragWdiget = NULL; - - if ( !m_bEditMode ) - { - initQSS(); - ui->comboBox_userGroup->setView(new QListView()); - initDate(); - if ( false == loadData() ) - { - LOGERROR("加载数据失败"); - QMessageBox::critical( 0, "错误", "从首链接加载数据失败,此应用不可用"); - return; - } - initUi(); - initDuty(); - initAlarmApi(); - loadSetting( m_startDate ); - initUserPerm(); - } - else - { - initQSS(); - } -} - -CDutySetting::~CDutySetting() -{ - checkSave(); - - delete ui; - - if ( !m_bEditMode ) - { - if ( m_pAlmApiForApp != NULL ) - { - m_pAlmApiForApp->suspendThread(); - delete m_pAlmApiForApp; - m_pAlmApiForApp = NULL; - } - - qDeleteAll( m_listDutyDefine ); - m_listDutyDefine.clear(); - qDeleteAll( m_listDropListWidget ); - m_listDropListWidget.clear(); - - if ( m_pDb != NULL ) - { - delete m_pDb; - m_pDb = NULL; - } - - if ( m_chkUserTimer != NULL ) - { - m_chkUserTimer->stop(); - delete m_chkUserTimer; - m_chkUserTimer = NULL; - } - } -} - -bool CDutySetting::loadData() -{ - m_pDb = new CDbApi(DB_CONN_MODEL_WRITE); - if ( m_pDb->open() ) - { - LOGINFO("initialize and open database success!"); - } - else - { - LOGERROR("initialize or open database failed!"); - return false; - } - LOGINFO("DatabaseName: [%s]", m_pDb->getCurrentDbPara().getDatabaseName().toStdString().c_str()); - LOGINFO("HostName: [%s]", m_pDb->getCurrentDbPara().getHostName().toStdString().c_str()); - LOGINFO("UserName: [%s]", m_pDb->getCurrentDbPara().getUserName().toStdString().c_str()); - - ui->comboBox_userGroup->addItem( "全部", 0 ); - QSqlQuery query; - QString sSql = "select PERM_ID,PERM_NAME from rm_userg_def order by PERM_ID"; - if ( !m_pDb->execute(sSql, query) ) - { - return false; - } - while( query.next() ) - { - ui->comboBox_userGroup->addItem( query.value(1).toString(), query.value(0).toInt() ); - } - query.clear(); - - m_pDragWdiget = new CDragListWidget; - m_pDragWdiget->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding ); - m_pDragWdiget->setObjectName( "userList" ); - ui->verticalLayout_2->insertWidget( 1, m_pDragWdiget ); - ui->verticalLayout_2->removeItem(ui->verticalSpacer_2); - if ( ui->comboBox_userGroup->count() > 0 ) - slotComboBoxUserGroupIndexChanged( 0 ); - - return true; -} - -void CDutySetting::initQSS() -{ - // 加载qss文件 - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("duty_setting.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CDutySetting::initUi() -{ - ui->comboBox_userGroup->setView(new QListView()); - ui->splitter->setStretchFactor( 0, 0 ); - ui->splitter->setStretchFactor( 1, 1 ); - - ui->label_1->setAlignment( Qt::AlignCenter ); - ui->label_2->setAlignment( Qt::AlignCenter ); - ui->label_3->setAlignment( Qt::AlignCenter ); - ui->label_4->setAlignment( Qt::AlignCenter ); - ui->label_5->setAlignment( Qt::AlignCenter ); - ui->label_6->setAlignment( Qt::AlignCenter ); - ui->label_7->setAlignment( Qt::AlignCenter ); - - connect( ui->comboBox_userGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(slotComboBoxUserGroupIndexChanged(int)) ); - connect( ui->pushButton_save, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonSaveClicked(bool)) ); - connect( ui->pushButton_lastWeek, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonLastWeekClicked(bool)) ); - connect( ui->pushButton_thisWeek, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonThisWeekClicked(bool)) ); - connect( ui->pushButton_nextWeek, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonNextWeekClicked(bool)) ); - connect( ui->pushButton_useLastWeekSetting, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonUseLastWeekSettingClicked(bool)) ); - connect( m_pDragWdiget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotDragListWidgetDoubleClicked(QListWidgetItem*)) ); - connect( ui->pushButton_dutyDefine, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonDutyDefineClicked(bool)) ); - connect( ui->pushButton_export, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonExportClicked(bool)) ); - - m_chkUserTimer = new QTimer; - m_chkUserTimer->setInterval(1000); - connect(m_chkUserTimer,&QTimer::timeout,this,&CDutySetting::checkUserTimer); - m_chkUserTimer->start(); - - // 判断用户权限 - if ( checkUserPerm() == false ) - { - ui->pushButton_dutyDefine->setEnabled( false ); - ui->pushButton_save->setEnabled( false ); - } - return; -} - -void CDutySetting::checkUserTimer() -{ - // 判断用户权限 - if ( checkUserPerm() == false ) - { - ui->pushButton_dutyDefine->setEnabled( false ); - ui->pushButton_save->setEnabled( false ); - } - else - { - ui->pushButton_dutyDefine->setEnabled( true ); - ui->pushButton_save->setEnabled( true ); - } - return; -} - -void CDutySetting::initDuty() -{ - // 清空 - for ( int i=0; igridLayout->removeWidget( pLabel ); - delete pLabel; - } - m_listDutyDefine.clear(); - for ( int i=0; igridLayout->removeWidget( pWidget ); - delete pWidget; - } - m_listDropListWidget.clear(); - - // 新增 - QSqlQuery query; - QString sSql = "select ID,NAME,START_TIME,END_TIME from duty_define order by ID"; - if ( !m_pDb->execute(sSql, query) ) - { - return; - } - int nRowIndex = 1; - while( query.next() ) - { - QLabel* pLabel = new QLabel(query.value(1).toString()); - pLabel->setProperty( "id", query.value(0).toString() ); - pLabel->setAlignment( Qt::AlignCenter ); - m_listDutyDefine.append( pLabel ); - ui->gridLayout->addWidget( pLabel, nRowIndex, 0 ); - - for ( int i=1; i<=7; i++ ) - { - CDropListWidget* pListWidget = new CDropListWidget; - pListWidget->setSelectionMode(QAbstractItemView::MultiSelection); - pListWidget->setAcceptDrops( true ); - connect( pListWidget, SIGNAL(focusIn()), this, SLOT(slotDropListWidgetFocusIn()) ); - m_listDropListWidget.append( pListWidget ); - ui->gridLayout->addWidget( pListWidget, nRowIndex, i ); - } - - nRowIndex++; - } - query.clear(); -} - -void CDutySetting::initAlarmApi() -{ - m_pAlmApiForApp = NULL; - m_nLocationId = 0; - - CSysInfoInterfacePtr sysInfoPtr; - if ( createSysInfoInstance( sysInfoPtr ) == false ) - { - LOGERROR( "CDutySetting::initAlarmApi(), createSysInfoInstance fail!" ); - return; - } - if ( sysInfoPtr == NULL ) - { - LOGERROR( "CDutySetting::initAlarmApi(), Get System Info fail!" ); - return; - } - SNodeInfo stNodeInfo; - sysInfoPtr->getLocalNodeInfo(stNodeInfo); - SAppInfo stAppInfo; - sysInfoPtr->getAppInfoByName("BASE", stAppInfo); - - m_nLocationId = stNodeInfo.nLocationId; - - m_pAlmApiForApp = new CAlmApiForApp(stNodeInfo.nDomainId, stAppInfo.nId); - m_pAlmApiForApp->resumeThread(); -} - -void CDutySetting::initDate( QDate date ) -{ - while ( date.dayOfWeek() != 1 ) - date = date.addDays( -1 ); - - m_startDate = date; - - ui->label_1->setText( "周一\n" + date.toString("(MM-dd)") ); - date = date.addDays( 1 ); - ui->label_2->setText( "周二\n" + date.toString("(MM-dd)") ); - date = date.addDays( 1 ); - ui->label_3->setText( "周三\n" + date.toString("(MM-dd)") ); - date = date.addDays( 1 ); - ui->label_4->setText( "周四\n" + date.toString("(MM-dd)") ); - date = date.addDays( 1 ); - ui->label_5->setText( "周五\n" + date.toString("(MM-dd)") ); - date = date.addDays( 1 ); - ui->label_6->setText( "周六\n" + date.toString("(MM-dd)") ); - date = date.addDays( 1 ); - ui->label_7->setText( "周日\n" + date.toString("(MM-dd)") ); - date = date.addDays( 1 ); -} - -void CDutySetting::loadSetting( QDate date ) -{ - for ( int i=0; iproperty("id").toInt(); - for ( int l=0; l<7; l++ ) - { - QDate tmpDate = date.addDays(l); - QSqlQuery query; - QString sSql = QString("select USERS from duty_setting where DUTY_DEFINE_ID=%1 and DATE='%2'") - .arg(nDutyDefineId) - .arg(tmpDate.toString("yyyy-MM-dd")); - if ( !m_pDb->execute(sSql, query) ) - { - return; - } - m_listDropListWidget[i*7+l]->clear(); - m_listDropListWidget[i*7+l]->m_bModify = false; - if ( query.next() ) - { - QString sNames = query.value(0).toString(); - if ( sNames == "" ) - continue; - QStringList listName = sNames.split(","); - for ( int m=0; msetFlags( pItem->flags()|Qt::ItemIsUserCheckable ); -// pItem->setCheckState( Qt::Unchecked ); - QString sAlias = m_mapName.contains(listName.at(m)) ? m_mapName[listName.at(m)] : listName.at(m); - pItem->setText( sAlias ); - pItem->setData( Qt::UserRole, listName.at(m) ); - m_listDropListWidget[i*7+l]->addItem( pItem ); - } - } - query.clear(); - } - } -} - -bool CDutySetting::initUserPerm() -{ - m_ptrPermMng = getPermMngInstance("BASE"); - if (m_ptrPermMng == NULL) - { - LOGERROR("CDutySetting::initUserPerm(), getPermMngInstance error"); - return false; - } - - return true; -} - -bool CDutySetting::checkUserPerm() -{ - if (m_ptrPermMng == NULL) - { - LOGERROR("CDutySetting::checkUserPerm(), m_ptrPermMng=NULL error"); - return false; - }; - - // 自己登录,用于测试 - //pPermMng->SysLogin("1","1",1,1000,"111"); - - std::string tmp = "FUNC_NOM_DUTY"; - if ( m_ptrPermMng->PermCheck(PERM_NOM_FUNC_DEF,&tmp) == PERM_PERMIT ) - return true; - - return false; -} - -void CDutySetting::checkSave() -{ - if ( checkUserPerm() == false ) - return; - - for ( int i=0; im_bModify == true ) - { - int nRet = QMessageBox::information( 0, "提示", "当前修改未保存,是否保存?", QMessageBox::Yes, QMessageBox::No ); - if ( nRet == QMessageBox::Yes ) - slotPushButtonSaveClicked( false ); - break; - } - } -} - -void CDutySetting::slotComboBoxUserGroupIndexChanged( int ) -{ - m_pDragWdiget->clear(); - - int nId = ui->comboBox_userGroup->currentData().toInt(); - if ( nId < 0 ) - return; - - QSqlQuery query; - QString sSql = QString("select PERM_ID,PERM_NAME,PERM_USER_GROUP1,PERM_ALIAS from rm_user_def where PERM_ID>10"); - if ( !m_pDb->execute(sSql, query) ) - { - return; - } - while( query.next() ) - { - m_mapName[query.value(1).toString()] = query.value(3).toString(); - quint64 nUserGroup = query.value(2).toULongLong(); - if ( nId != 0 && !(nUserGroup & (quint64(1)<<(nId-1))) ) - continue; - QListWidgetItem* pItem = new QListWidgetItem; - pItem->setText( query.value(3).toString() ); - pItem->setData( Qt::UserRole, query.value(1).toString() ); - m_pDragWdiget->addItem( pItem ); - } - query.clear(); -} - -void CDutySetting::slotPushButtonSaveClicked( bool ) -{ - // 判断用户权限 - if ( checkUserPerm() == false ) - { - QMessageBox::critical( 0, "错误", "用户权限验证失败,请检查用户权限!" ); - return; - } - - QString sSql = "";// 待执行的sql语句 - - // 删除这一周的记录 - for ( int i=0; i<7; i++ ) - { - QDate tmpDate = m_startDate.addDays(i); - sSql += QString("delete from duty_setting where date='%1';").arg(tmpDate.toString("yyyy-MM-dd")); - } - - // 排班定义的行数,不包括第0行列名 - int nRow = m_listDropListWidget.count()/7; - for ( int i=0; iproperty("id").toInt(); - if ( nDutyDefineId <= 0 ) - continue; - for ( int l=i*7; l<(i+1)*7; l++ ) - { - QString sName = ""; - CDropListWidget* pListWidget = m_listDropListWidget.at(l); - pListWidget->m_bModify = false; - for ( int m=0; mcount(); m++ ) - { - if ( sName == "" ) - sName = pListWidget->item(m)->data(Qt::UserRole).toString(); - else - sName = sName + "," + pListWidget->item(m)->data(Qt::UserRole).toString(); - } - QDate tmpDate = m_startDate.addDays(l%7); - sSql += QString("insert into duty_setting (DATE,DUTY_DEFINE_ID,USERS) value ('%1',%2,'%3');") - .arg(tmpDate.toString("yyyy-MM-dd")).arg(nDutyDefineId).arg(sName); - } - } - if( false == m_pDb->execute(sSql) ) //模型提交 - { - LOGERROR("CDutySetting:: insert SQL execute error ."); - QMessageBox::critical( 0, "错误", "保存失败" ); - return; - } - - // 发送事件信息 - sendOptEvent( "修改排班设置" ); - - // 弹出提示窗 - QMessageBox::information( 0, "提示", "保存完成" ); -} - -void CDutySetting::slotPushButtonLastWeekClicked( bool ) -{ - checkSave(); - - m_startDate = m_startDate.addDays( -7 ); - initDate( m_startDate ); - loadSetting( m_startDate ); -} - -void CDutySetting::slotPushButtonThisWeekClicked( bool ) -{ - checkSave(); - - initDate(); - loadSetting( m_startDate ); -} - -void CDutySetting::slotPushButtonNextWeekClicked( bool ) -{ - checkSave(); - - m_startDate = m_startDate.addDays( 7 ); - initDate( m_startDate ); - loadSetting( m_startDate ); -} - -void CDutySetting::slotPushButtonUseLastWeekSettingClicked( bool ) -{ - loadSetting( m_startDate.addDays(-7) ); - if ( m_listDropListWidget.count() > 0 ) - m_listDropListWidget[0]->m_bModify = true; -} - -void CDutySetting::slotDropListWidgetFocusIn() -{ - for ( int i=0; isetProperty( "focusIn", 1 ); - } - - CDropListWidget* pDropListWidget = qobject_cast(sender()); - if ( pDropListWidget == NULL ) - return; - - pDropListWidget->setProperty( "focusIn", 2 ); -} - -void CDutySetting::slotDragListWidgetDoubleClicked( QListWidgetItem* pItem) -{ - bool bFind = false; - for ( int i=0; iproperty("focusIn").toInt(); - if ( nMark == 2 ) - { - // 判断是否已添加,没添加才添加 - bool bAdd = false; - for ( int l=0; lcount(); l++ ) - { - if ( pDropListWidget->item(l)->text() == pItem->text() ) - { - bAdd = true; - break; - } - } - if ( bAdd == false ) - { - QListWidgetItem* pTmpItem = new QListWidgetItem(pItem->text()); -// pTmpItem->setFlags( pTmpItem->flags()|Qt::ItemIsUserCheckable ); -// pTmpItem->setCheckState( Qt::Unchecked ); - pTmpItem->setData(Qt::UserRole, pItem->data(Qt::UserRole)); - pDropListWidget->addItem( pTmpItem ); - pDropListWidget->m_bModify = true; - } - - bFind = true; - break; - } - } - - if ( bFind == false ) - { - QMessageBox::warning( 0, "警告", "请先选择右侧目标班" ); - } -} - -void CDutySetting::slotPushButtonDutyDefineClicked( bool ) -{ - if ( checkUserPerm() == false ) - { - QMessageBox::critical( 0, "错误", "用户权限验证失败,请检查用户权限!" ); - return; - } - CDutyDefineDialog* pDialog = new CDutyDefineDialog( this ); - connect( pDialog, SIGNAL(signalDutyDefineSaved()), this, SLOT(slotDutyDefineSaved()) ); - pDialog->exec(); - delete pDialog; - pDialog = NULL; -} - -void CDutySetting::slotDutyDefineSaved() -{ - QSqlQuery query; - QString sSql = QString("select max(ID) as id from duty_define;"); - if ( !m_pDb->execute(sSql, query) ) - { - return; - } - int nMaxDutyDefineId = 10000; - if ( query.next() ) - nMaxDutyDefineId = query.value(0).toInt(); - - sSql = QString("delete from duty_setting where DUTY_DEFINE_ID > %1").arg(nMaxDutyDefineId); - if ( false == m_pDb->execute(sSql) ) //模型提交 - { - LOGERROR("CDutySetting::CDutySetting delete SQL execute error."); - return; - } - - // 重新初始化 - initDuty(); - initDate( m_startDate ); - loadSetting( m_startDate ); - - // 发送事件信息 - sendOptEvent( "修改排班定义" ); -} - -void CDutySetting::slotPushButtonExportClicked( bool ) -{ - checkSave(); - - QDir dir(QCoreApplication::applicationDirPath()); - dir.cdUp(); - dir.cdUp(); - - QString sPath = QFileDialog::getExistingDirectory(this, tr("选择导出目录"), - dir.absolutePath(), - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - - if ( sPath == "" ) - return; - - QString sExcelFileName = QString("排班管理(%1~%2).xlsx") - .arg(m_startDate.toString("yyyyMMdd")) - .arg(m_startDate.addDays(6).toString("yyyyMMdd")); - QXlsx::Document xlsx; - xlsx.addSheet( "sheet1" ); - - // 设置列宽 - xlsx.setColumnWidth( 1, 10 ); - xlsx.setColumnWidth( 2, 20 ); - xlsx.setColumnWidth( 3, 20 ); - xlsx.setColumnWidth( 4, 20 ); - xlsx.setColumnWidth( 5, 20 ); - xlsx.setColumnWidth( 6, 20 ); - xlsx.setColumnWidth( 7, 20 ); - xlsx.setColumnWidth( 8, 20 ); - - // 设置行高 - xlsx.setRowHeight( 1, 40); - - // 写横向表头 - xlsx.write( 1, 1, ui->label_0->text() ); - xlsx.write( 1, 2, ui->label_1->text() ); - xlsx.write( 1, 3, ui->label_2->text() ); - xlsx.write( 1, 4, ui->label_3->text() ); - xlsx.write( 1, 5, ui->label_4->text() ); - xlsx.write( 1, 6, ui->label_5->text() ); - xlsx.write( 1, 7, ui->label_6->text() ); - xlsx.write( 1, 8, ui->label_7->text() ); - - // 写纵向表头 - for ( int i=0; itext() ); - } - - // 写内容 - for ( int i=0; icount(); l++ ) - { - if ( l != 0 ) - sText += "\n"; - sText = sText + pWidget->item(l)->text() + ","; - } - xlsx.write( i/7+2, i%7+2, sText ); - xlsx.setRowHeight( i/7+2, 40); - } - - // 保存到文件 - xlsx.saveAs( sPath+"/"+sExcelFileName ); - - // 提示导出路径 - QMessageBox::information( 0, "提示", "导出完成\n文件为:"+sPath+"/" +sExcelFileName); -} - -void CDutySetting::sendOptEvent( QString sMsg ) -{ - if ( m_pAlmApiForApp == NULL ) - return; - - kbd_idlfile::SAppAddAlm stAppAddAlarm; - kbd_idlfile::SAlmInfoFromApp &stAlmInfoFromApp = *(stAppAddAlarm.add_alm_info()); - stAlmInfoFromApp.set_alm_type(ALM_TYPE_OPERATE); - stAlmInfoFromApp.set_time_stamp( QDateTime::currentMSecsSinceEpoch() ); - stAlmInfoFromApp.set_status(ALM_STAT_OPT_DUTY); - stAlmInfoFromApp.set_location_id(m_nLocationId); - stAlmInfoFromApp.set_alm_style(::kbd_idlfile::enAlmStyle::AS_EVENT_ONLY); - - kbd_idlfile::SAlmKeyword stAlmKeyword; - stAlmKeyword.set_id(ALM_KEY_ALM_DESC); - stAlmKeyword.set_value( sMsg.toStdString().c_str() ); - stAlmInfoFromApp.add_alm_keyword()->CopyFrom(stAlmKeyword); - m_pAlmApiForApp->addAlarm(stAppAddAlarm); - -} - - - - - - - - - - - - - - +#include "CDutySetting.h" +#include "ui_CDutySetting.h" +#include +#include "pub_utility_api/FileStyle.h" + +using namespace kbd_public; +using namespace kbd_dbms; +using namespace kbd_service; + +CDutySetting::CDutySetting(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CDutySetting), + m_bEditMode( editMode ) +{ + ui->setupUi(this); + + m_pAlmApiForApp = NULL; + m_pDb = NULL; + m_chkUserTimer = NULL; + m_pDragWdiget = NULL; + + if ( !m_bEditMode ) + { + initQSS(); + ui->comboBox_userGroup->setView(new QListView()); + initDate(); + if ( false == loadData() ) + { + LOGERROR("加载数据失败"); + QMessageBox::critical( 0, "错误", "从首链接加载数据失败,此应用不可用"); + return; + } + initUi(); + initDuty(); + initAlarmApi(); + loadSetting( m_startDate ); + initUserPerm(); + } + else + { + initQSS(); + } +} + +CDutySetting::~CDutySetting() +{ + checkSave(); + + delete ui; + + if ( !m_bEditMode ) + { + if ( m_pAlmApiForApp != NULL ) + { + m_pAlmApiForApp->suspendThread(); + delete m_pAlmApiForApp; + m_pAlmApiForApp = NULL; + } + + qDeleteAll( m_listDutyDefine ); + m_listDutyDefine.clear(); + qDeleteAll( m_listDropListWidget ); + m_listDropListWidget.clear(); + + if ( m_pDb != NULL ) + { + delete m_pDb; + m_pDb = NULL; + } + + if ( m_chkUserTimer != NULL ) + { + m_chkUserTimer->stop(); + delete m_chkUserTimer; + m_chkUserTimer = NULL; + } + } +} + +bool CDutySetting::loadData() +{ + m_pDb = new CDbApi(DB_CONN_MODEL_WRITE); + if ( m_pDb->open() ) + { + LOGINFO("initialize and open database success!"); + } + else + { + LOGERROR("initialize or open database failed!"); + return false; + } + LOGINFO("DatabaseName: [%s]", m_pDb->getCurrentDbPara().getDatabaseName().toStdString().c_str()); + LOGINFO("HostName: [%s]", m_pDb->getCurrentDbPara().getHostName().toStdString().c_str()); + LOGINFO("UserName: [%s]", m_pDb->getCurrentDbPara().getUserName().toStdString().c_str()); + + ui->comboBox_userGroup->addItem( "全部", 0 ); + QSqlQuery query; + QString sSql = "select PERM_ID,PERM_NAME from rm_userg_def order by PERM_ID"; + if ( !m_pDb->execute(sSql, query) ) + { + return false; + } + while( query.next() ) + { + ui->comboBox_userGroup->addItem( query.value(1).toString(), query.value(0).toInt() ); + } + query.clear(); + + m_pDragWdiget = new CDragListWidget; + m_pDragWdiget->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding ); + m_pDragWdiget->setObjectName( "userList" ); + ui->verticalLayout_2->insertWidget( 1, m_pDragWdiget ); + ui->verticalLayout_2->removeItem(ui->verticalSpacer_2); + if ( ui->comboBox_userGroup->count() > 0 ) + slotComboBoxUserGroupIndexChanged( 0 ); + + return true; +} + +void CDutySetting::initQSS() +{ + // 加载qss文件 + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("duty_setting.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CDutySetting::initUi() +{ + ui->comboBox_userGroup->setView(new QListView()); + ui->splitter->setStretchFactor( 0, 0 ); + ui->splitter->setStretchFactor( 1, 1 ); + + ui->label_1->setAlignment( Qt::AlignCenter ); + ui->label_2->setAlignment( Qt::AlignCenter ); + ui->label_3->setAlignment( Qt::AlignCenter ); + ui->label_4->setAlignment( Qt::AlignCenter ); + ui->label_5->setAlignment( Qt::AlignCenter ); + ui->label_6->setAlignment( Qt::AlignCenter ); + ui->label_7->setAlignment( Qt::AlignCenter ); + + connect( ui->comboBox_userGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(slotComboBoxUserGroupIndexChanged(int)) ); + connect( ui->pushButton_save, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonSaveClicked(bool)) ); + connect( ui->pushButton_lastWeek, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonLastWeekClicked(bool)) ); + connect( ui->pushButton_thisWeek, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonThisWeekClicked(bool)) ); + connect( ui->pushButton_nextWeek, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonNextWeekClicked(bool)) ); + connect( ui->pushButton_useLastWeekSetting, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonUseLastWeekSettingClicked(bool)) ); + connect( m_pDragWdiget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotDragListWidgetDoubleClicked(QListWidgetItem*)) ); + connect( ui->pushButton_dutyDefine, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonDutyDefineClicked(bool)) ); + connect( ui->pushButton_export, SIGNAL(clicked(bool)), this, SLOT(slotPushButtonExportClicked(bool)) ); + + m_chkUserTimer = new QTimer; + m_chkUserTimer->setInterval(1000); + connect(m_chkUserTimer,&QTimer::timeout,this,&CDutySetting::checkUserTimer); + m_chkUserTimer->start(); + + // 判断用户权限 + if ( checkUserPerm() == false ) + { + ui->pushButton_dutyDefine->setEnabled( false ); + ui->pushButton_save->setEnabled( false ); + } + return; +} + +void CDutySetting::checkUserTimer() +{ + // 判断用户权限 + if ( checkUserPerm() == false ) + { + ui->pushButton_dutyDefine->setEnabled( false ); + ui->pushButton_save->setEnabled( false ); + } + else + { + ui->pushButton_dutyDefine->setEnabled( true ); + ui->pushButton_save->setEnabled( true ); + } + return; +} + +void CDutySetting::initDuty() +{ + // 清空 + for ( int i=0; igridLayout->removeWidget( pLabel ); + delete pLabel; + } + m_listDutyDefine.clear(); + for ( int i=0; igridLayout->removeWidget( pWidget ); + delete pWidget; + } + m_listDropListWidget.clear(); + + // 新增 + QSqlQuery query; + QString sSql = "select ID,NAME,START_TIME,END_TIME from duty_define order by ID"; + if ( !m_pDb->execute(sSql, query) ) + { + return; + } + int nRowIndex = 1; + while( query.next() ) + { + QLabel* pLabel = new QLabel(query.value(1).toString()); + pLabel->setProperty( "id", query.value(0).toString() ); + pLabel->setAlignment( Qt::AlignCenter ); + m_listDutyDefine.append( pLabel ); + ui->gridLayout->addWidget( pLabel, nRowIndex, 0 ); + + for ( int i=1; i<=7; i++ ) + { + CDropListWidget* pListWidget = new CDropListWidget; + pListWidget->setSelectionMode(QAbstractItemView::MultiSelection); + pListWidget->setAcceptDrops( true ); + connect( pListWidget, SIGNAL(focusIn()), this, SLOT(slotDropListWidgetFocusIn()) ); + m_listDropListWidget.append( pListWidget ); + ui->gridLayout->addWidget( pListWidget, nRowIndex, i ); + } + + nRowIndex++; + } + query.clear(); +} + +void CDutySetting::initAlarmApi() +{ + m_pAlmApiForApp = NULL; + m_nLocationId = 0; + + CSysInfoInterfacePtr sysInfoPtr; + if ( createSysInfoInstance( sysInfoPtr ) == false ) + { + LOGERROR( "CDutySetting::initAlarmApi(), createSysInfoInstance fail!" ); + return; + } + if ( sysInfoPtr == NULL ) + { + LOGERROR( "CDutySetting::initAlarmApi(), Get System Info fail!" ); + return; + } + SNodeInfo stNodeInfo; + sysInfoPtr->getLocalNodeInfo(stNodeInfo); + SAppInfo stAppInfo; + sysInfoPtr->getAppInfoByName("BASE", stAppInfo); + + m_nLocationId = stNodeInfo.nLocationId; + + m_pAlmApiForApp = new CAlmApiForApp(stNodeInfo.nDomainId, stAppInfo.nId); + m_pAlmApiForApp->resumeThread(); +} + +void CDutySetting::initDate( QDate date ) +{ + while ( date.dayOfWeek() != 1 ) + date = date.addDays( -1 ); + + m_startDate = date; + + ui->label_1->setText( "周一\n" + date.toString("(MM-dd)") ); + date = date.addDays( 1 ); + ui->label_2->setText( "周二\n" + date.toString("(MM-dd)") ); + date = date.addDays( 1 ); + ui->label_3->setText( "周三\n" + date.toString("(MM-dd)") ); + date = date.addDays( 1 ); + ui->label_4->setText( "周四\n" + date.toString("(MM-dd)") ); + date = date.addDays( 1 ); + ui->label_5->setText( "周五\n" + date.toString("(MM-dd)") ); + date = date.addDays( 1 ); + ui->label_6->setText( "周六\n" + date.toString("(MM-dd)") ); + date = date.addDays( 1 ); + ui->label_7->setText( "周日\n" + date.toString("(MM-dd)") ); + date = date.addDays( 1 ); +} + +void CDutySetting::loadSetting( QDate date ) +{ + for ( int i=0; iproperty("id").toInt(); + for ( int l=0; l<7; l++ ) + { + QDate tmpDate = date.addDays(l); + QSqlQuery query; + QString sSql = QString("select USERS from duty_setting where DUTY_DEFINE_ID=%1 and DATE='%2'") + .arg(nDutyDefineId) + .arg(tmpDate.toString("yyyy-MM-dd")); + if ( !m_pDb->execute(sSql, query) ) + { + return; + } + m_listDropListWidget[i*7+l]->clear(); + m_listDropListWidget[i*7+l]->m_bModify = false; + if ( query.next() ) + { + QString sNames = query.value(0).toString(); + if ( sNames == "" ) + continue; + QStringList listName = sNames.split(","); + for ( int m=0; msetFlags( pItem->flags()|Qt::ItemIsUserCheckable ); +// pItem->setCheckState( Qt::Unchecked ); + QString sAlias = m_mapName.contains(listName.at(m)) ? m_mapName[listName.at(m)] : listName.at(m); + pItem->setText( sAlias ); + pItem->setData( Qt::UserRole, listName.at(m) ); + m_listDropListWidget[i*7+l]->addItem( pItem ); + } + } + query.clear(); + } + } +} + +bool CDutySetting::initUserPerm() +{ + m_ptrPermMng = getPermMngInstance("BASE"); + if (m_ptrPermMng == NULL) + { + LOGERROR("CDutySetting::initUserPerm(), getPermMngInstance error"); + return false; + } + + return true; +} + +bool CDutySetting::checkUserPerm() +{ + if (m_ptrPermMng == NULL) + { + LOGERROR("CDutySetting::checkUserPerm(), m_ptrPermMng=NULL error"); + return false; + }; + + // 自己登录,用于测试 + //pPermMng->SysLogin("1","1",1,1000,"111"); + + std::string tmp = "FUNC_NOM_DUTY"; + if ( m_ptrPermMng->PermCheck(PERM_NOM_FUNC_DEF,&tmp) == PERM_PERMIT ) + return true; + + return false; +} + +void CDutySetting::checkSave() +{ + if ( checkUserPerm() == false ) + return; + + for ( int i=0; im_bModify == true ) + { + int nRet = QMessageBox::information( 0, "提示", "当前修改未保存,是否保存?", QMessageBox::Yes, QMessageBox::No ); + if ( nRet == QMessageBox::Yes ) + slotPushButtonSaveClicked( false ); + break; + } + } +} + +void CDutySetting::slotComboBoxUserGroupIndexChanged( int ) +{ + m_pDragWdiget->clear(); + + int nId = ui->comboBox_userGroup->currentData().toInt(); + if ( nId < 0 ) + return; + + QSqlQuery query; + QString sSql = QString("select PERM_ID,PERM_NAME,PERM_USER_GROUP1,PERM_ALIAS from rm_user_def where PERM_ID>10"); + if ( !m_pDb->execute(sSql, query) ) + { + return; + } + while( query.next() ) + { + m_mapName[query.value(1).toString()] = query.value(3).toString(); + quint64 nUserGroup = query.value(2).toULongLong(); + if ( nId != 0 && !(nUserGroup & (quint64(1)<<(nId-1))) ) + continue; + QListWidgetItem* pItem = new QListWidgetItem; + pItem->setText( query.value(3).toString() ); + pItem->setData( Qt::UserRole, query.value(1).toString() ); + m_pDragWdiget->addItem( pItem ); + } + query.clear(); +} + +void CDutySetting::slotPushButtonSaveClicked( bool ) +{ + // 判断用户权限 + if ( checkUserPerm() == false ) + { + QMessageBox::critical( 0, "错误", "用户权限验证失败,请检查用户权限!" ); + return; + } + + QString sSql = "";// 待执行的sql语句 + + // 删除这一周的记录 + for ( int i=0; i<7; i++ ) + { + QDate tmpDate = m_startDate.addDays(i); + sSql += QString("delete from duty_setting where date='%1';").arg(tmpDate.toString("yyyy-MM-dd")); + } + + // 排班定义的行数,不包括第0行列名 + int nRow = m_listDropListWidget.count()/7; + for ( int i=0; iproperty("id").toInt(); + if ( nDutyDefineId <= 0 ) + continue; + for ( int l=i*7; l<(i+1)*7; l++ ) + { + QString sName = ""; + CDropListWidget* pListWidget = m_listDropListWidget.at(l); + pListWidget->m_bModify = false; + for ( int m=0; mcount(); m++ ) + { + if ( sName == "" ) + sName = pListWidget->item(m)->data(Qt::UserRole).toString(); + else + sName = sName + "," + pListWidget->item(m)->data(Qt::UserRole).toString(); + } + QDate tmpDate = m_startDate.addDays(l%7); + sSql += QString("insert into duty_setting (DATE,DUTY_DEFINE_ID,USERS) value ('%1',%2,'%3');") + .arg(tmpDate.toString("yyyy-MM-dd")).arg(nDutyDefineId).arg(sName); + } + } + if( false == m_pDb->execute(sSql) ) //模型提交 + { + LOGERROR("CDutySetting:: insert SQL execute error ."); + QMessageBox::critical( 0, "错误", "保存失败" ); + return; + } + + // 发送事件信息 + sendOptEvent( "修改排班设置" ); + + // 弹出提示窗 + QMessageBox::information( 0, "提示", "保存完成" ); +} + +void CDutySetting::slotPushButtonLastWeekClicked( bool ) +{ + checkSave(); + + m_startDate = m_startDate.addDays( -7 ); + initDate( m_startDate ); + loadSetting( m_startDate ); +} + +void CDutySetting::slotPushButtonThisWeekClicked( bool ) +{ + checkSave(); + + initDate(); + loadSetting( m_startDate ); +} + +void CDutySetting::slotPushButtonNextWeekClicked( bool ) +{ + checkSave(); + + m_startDate = m_startDate.addDays( 7 ); + initDate( m_startDate ); + loadSetting( m_startDate ); +} + +void CDutySetting::slotPushButtonUseLastWeekSettingClicked( bool ) +{ + loadSetting( m_startDate.addDays(-7) ); + if ( m_listDropListWidget.count() > 0 ) + m_listDropListWidget[0]->m_bModify = true; +} + +void CDutySetting::slotDropListWidgetFocusIn() +{ + for ( int i=0; isetProperty( "focusIn", 1 ); + } + + CDropListWidget* pDropListWidget = qobject_cast(sender()); + if ( pDropListWidget == NULL ) + return; + + pDropListWidget->setProperty( "focusIn", 2 ); +} + +void CDutySetting::slotDragListWidgetDoubleClicked( QListWidgetItem* pItem) +{ + bool bFind = false; + for ( int i=0; iproperty("focusIn").toInt(); + if ( nMark == 2 ) + { + // 判断是否已添加,没添加才添加 + bool bAdd = false; + for ( int l=0; lcount(); l++ ) + { + if ( pDropListWidget->item(l)->text() == pItem->text() ) + { + bAdd = true; + break; + } + } + if ( bAdd == false ) + { + QListWidgetItem* pTmpItem = new QListWidgetItem(pItem->text()); +// pTmpItem->setFlags( pTmpItem->flags()|Qt::ItemIsUserCheckable ); +// pTmpItem->setCheckState( Qt::Unchecked ); + pTmpItem->setData(Qt::UserRole, pItem->data(Qt::UserRole)); + pDropListWidget->addItem( pTmpItem ); + pDropListWidget->m_bModify = true; + } + + bFind = true; + break; + } + } + + if ( bFind == false ) + { + QMessageBox::warning( 0, "警告", "请先选择右侧目标班" ); + } +} + +void CDutySetting::slotPushButtonDutyDefineClicked( bool ) +{ + if ( checkUserPerm() == false ) + { + QMessageBox::critical( 0, "错误", "用户权限验证失败,请检查用户权限!" ); + return; + } + CDutyDefineDialog* pDialog = new CDutyDefineDialog( this ); + connect( pDialog, SIGNAL(signalDutyDefineSaved()), this, SLOT(slotDutyDefineSaved()) ); + pDialog->exec(); + delete pDialog; + pDialog = NULL; +} + +void CDutySetting::slotDutyDefineSaved() +{ + QSqlQuery query; + QString sSql = QString("select max(ID) as id from duty_define;"); + if ( !m_pDb->execute(sSql, query) ) + { + return; + } + int nMaxDutyDefineId = 10000; + if ( query.next() ) + nMaxDutyDefineId = query.value(0).toInt(); + + sSql = QString("delete from duty_setting where DUTY_DEFINE_ID > %1").arg(nMaxDutyDefineId); + if ( false == m_pDb->execute(sSql) ) //模型提交 + { + LOGERROR("CDutySetting::CDutySetting delete SQL execute error."); + return; + } + + // 重新初始化 + initDuty(); + initDate( m_startDate ); + loadSetting( m_startDate ); + + // 发送事件信息 + sendOptEvent( "修改排班定义" ); +} + +void CDutySetting::slotPushButtonExportClicked( bool ) +{ + checkSave(); + + QDir dir(QCoreApplication::applicationDirPath()); + dir.cdUp(); + dir.cdUp(); + + QString sPath = QFileDialog::getExistingDirectory(this, tr("选择导出目录"), + dir.absolutePath(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + if ( sPath == "" ) + return; + + QString sExcelFileName = QString("排班管理(%1~%2).xlsx") + .arg(m_startDate.toString("yyyyMMdd")) + .arg(m_startDate.addDays(6).toString("yyyyMMdd")); + QXlsx::Document xlsx; + xlsx.addSheet( "sheet1" ); + + // 设置列宽 + xlsx.setColumnWidth( 1, 10 ); + xlsx.setColumnWidth( 2, 20 ); + xlsx.setColumnWidth( 3, 20 ); + xlsx.setColumnWidth( 4, 20 ); + xlsx.setColumnWidth( 5, 20 ); + xlsx.setColumnWidth( 6, 20 ); + xlsx.setColumnWidth( 7, 20 ); + xlsx.setColumnWidth( 8, 20 ); + + // 设置行高 + xlsx.setRowHeight( 1, 40); + + // 写横向表头 + xlsx.write( 1, 1, ui->label_0->text() ); + xlsx.write( 1, 2, ui->label_1->text() ); + xlsx.write( 1, 3, ui->label_2->text() ); + xlsx.write( 1, 4, ui->label_3->text() ); + xlsx.write( 1, 5, ui->label_4->text() ); + xlsx.write( 1, 6, ui->label_5->text() ); + xlsx.write( 1, 7, ui->label_6->text() ); + xlsx.write( 1, 8, ui->label_7->text() ); + + // 写纵向表头 + for ( int i=0; itext() ); + } + + // 写内容 + for ( int i=0; icount(); l++ ) + { + if ( l != 0 ) + sText += "\n"; + sText = sText + pWidget->item(l)->text() + ","; + } + xlsx.write( i/7+2, i%7+2, sText ); + xlsx.setRowHeight( i/7+2, 40); + } + + // 保存到文件 + xlsx.saveAs( sPath+"/"+sExcelFileName ); + + // 提示导出路径 + QMessageBox::information( 0, "提示", "导出完成\n文件为:"+sPath+"/" +sExcelFileName); +} + +void CDutySetting::sendOptEvent( QString sMsg ) +{ + if ( m_pAlmApiForApp == NULL ) + return; + + kbd_idlfile::SAppAddAlm stAppAddAlarm; + kbd_idlfile::SAlmInfoFromApp &stAlmInfoFromApp = *(stAppAddAlarm.add_alm_info()); + stAlmInfoFromApp.set_alm_type(ALM_TYPE_OPERATE); + stAlmInfoFromApp.set_time_stamp( QDateTime::currentMSecsSinceEpoch() ); + stAlmInfoFromApp.set_status(ALM_STAT_OPT_DUTY); + stAlmInfoFromApp.set_location_id(m_nLocationId); + stAlmInfoFromApp.set_alm_style(::kbd_idlfile::enAlmStyle::AS_EVENT_ONLY); + + kbd_idlfile::SAlmKeyword stAlmKeyword; + stAlmKeyword.set_id(ALM_KEY_ALM_DESC); + stAlmKeyword.set_value( sMsg.toStdString().c_str() ); + stAlmInfoFromApp.add_alm_keyword()->CopyFrom(stAlmKeyword); + m_pAlmApiForApp->addAlarm(stAppAddAlarm); + +} + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ScheduleWidget/CDutySetting.h b/product/src/gui/plugin/ScheduleWidget/CDutySetting.h index 85f2c405..8cc6927d 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutySetting.h +++ b/product/src/gui/plugin/ScheduleWidget/CDutySetting.h @@ -1,81 +1,81 @@ -#ifndef CDUTYSETTING_H -#define CDUTYSETTING_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "db_api_ex/CDbApi.h" -#include "pub_utility_api/I18N.h" -#include "pub_logger_api/logger.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "CDragListWidget.h" -#include "CDropListWidget.h" -#include "CDutyDefineDialog.h" -#include "model_excel/xlsx/xlsxdocument.h" -#include "perm_mng_api/PermMngApi.h" -#include "alarm_server_api/CAlmApiForApp.h" -#include "alarm_server_api/AlarmCommonDef.h" -#include "../idl_files/AlarmMessage.pb.h" -#include "db_api_ex/CDbApi.h" - -namespace Ui { -class CDutySetting; -} - -class CDutySetting : public QWidget -{ - Q_OBJECT - -public: - explicit CDutySetting(QWidget *parent = 0, bool editMode = true); - ~CDutySetting(); - -public: - bool loadData(); - void initQSS(); - void initUi(); - void initDuty(); - void initAlarmApi(); - bool initUserPerm(); - void initDate( QDate date = QDate::currentDate() ); - void loadSetting( QDate date ); - bool checkUserPerm();// 验证用户权限 - void sendOptEvent( QString sMsg ); - void checkUserTimer();// 验证用户权限定时器 - void checkSave();// 判断修改之后是否保存过 - -public slots: - void slotComboBoxUserGroupIndexChanged( int nIndex ); - void slotPushButtonSaveClicked( bool bChecked ); - void slotPushButtonLastWeekClicked( bool bChecked ); - void slotPushButtonThisWeekClicked( bool bChecked ); - void slotPushButtonNextWeekClicked( bool bChecked ); - void slotPushButtonUseLastWeekSettingClicked( bool bChecked ); - void slotDropListWidgetFocusIn(); - void slotDragListWidgetDoubleClicked( QListWidgetItem* pItem); - void slotPushButtonDutyDefineClicked( bool bChecked ); - void slotDutyDefineSaved(); - void slotPushButtonExportClicked( bool bChecked ); - -private: - Ui::CDutySetting *ui; - kbd_dbms::CDbApi* m_pDb; // 数据库接口 - QDate m_startDate; - CDragListWidget* m_pDragWdiget; - QList m_listDutyDefine; - QList m_listDropListWidget; - kbd_service::CAlmApiForApp* m_pAlmApiForApp; - kbd_service::CPermMngApiPtr m_ptrPermMng; - int m_nLocationId; - bool m_bEditMode;// 是否编辑态 - QTimer *m_chkUserTimer; - QMap m_mapName;// rm_user_def表name和alias的对照表 -}; - -#endif // CDUTYSETTING_H +#ifndef CDUTYSETTING_H +#define CDUTYSETTING_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "db_api_ex/CDbApi.h" +#include "pub_utility_api/I18N.h" +#include "pub_logger_api/logger.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "CDragListWidget.h" +#include "CDropListWidget.h" +#include "CDutyDefineDialog.h" +#include "model_excel/xlsx/xlsxdocument.h" +#include "perm_mng_api/PermMngApi.h" +#include "alarm_server_api/CAlmApiForApp.h" +#include "alarm_server_api/AlarmCommonDef.h" +#include "../idl_files/AlarmMessage.pb.h" +#include "db_api_ex/CDbApi.h" + +namespace Ui { +class CDutySetting; +} + +class CDutySetting : public QWidget +{ + Q_OBJECT + +public: + explicit CDutySetting(QWidget *parent = 0, bool editMode = true); + ~CDutySetting(); + +public: + bool loadData(); + void initQSS(); + void initUi(); + void initDuty(); + void initAlarmApi(); + bool initUserPerm(); + void initDate( QDate date = QDate::currentDate() ); + void loadSetting( QDate date ); + bool checkUserPerm();// 验证用户权限 + void sendOptEvent( QString sMsg ); + void checkUserTimer();// 验证用户权限定时器 + void checkSave();// 判断修改之后是否保存过 + +public slots: + void slotComboBoxUserGroupIndexChanged( int nIndex ); + void slotPushButtonSaveClicked( bool bChecked ); + void slotPushButtonLastWeekClicked( bool bChecked ); + void slotPushButtonThisWeekClicked( bool bChecked ); + void slotPushButtonNextWeekClicked( bool bChecked ); + void slotPushButtonUseLastWeekSettingClicked( bool bChecked ); + void slotDropListWidgetFocusIn(); + void slotDragListWidgetDoubleClicked( QListWidgetItem* pItem); + void slotPushButtonDutyDefineClicked( bool bChecked ); + void slotDutyDefineSaved(); + void slotPushButtonExportClicked( bool bChecked ); + +private: + Ui::CDutySetting *ui; + kbd_dbms::CDbApi* m_pDb; // 数据库接口 + QDate m_startDate; + CDragListWidget* m_pDragWdiget; + QList m_listDutyDefine; + QList m_listDropListWidget; + kbd_service::CAlmApiForApp* m_pAlmApiForApp; + kbd_service::CPermMngApiPtr m_ptrPermMng; + int m_nLocationId; + bool m_bEditMode;// 是否编辑态 + QTimer *m_chkUserTimer; + QMap m_mapName;// rm_user_def表name和alias的对照表 +}; + +#endif // CDUTYSETTING_H diff --git a/product/src/gui/plugin/ScheduleWidget/CDutySetting.ui b/product/src/gui/plugin/ScheduleWidget/CDutySetting.ui index 5b7b1fa8..f42b2e3a 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutySetting.ui +++ b/product/src/gui/plugin/ScheduleWidget/CDutySetting.ui @@ -1,288 +1,288 @@ - - - CDutySetting - - - - 0 - 0 - 1043 - 638 - - - - CDutySetting - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - 用户组 - - - - - - - - 0 - 0 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 0 - - - - - - - - - - - - - - 上一周 - - - - - - - 本周 - - - - - - - 下一周 - - - - - - - 引用上周 - - - - - - - 班次管理 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 导出 - - - - - - - 保存 - - - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 50 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - - - - - + + + CDutySetting + + + + 0 + 0 + 1043 + 638 + + + + CDutySetting + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + 用户组 + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 0 + + + + + + + + + + + + + + 上一周 + + + + + + + 本周 + + + + + + + 下一周 + + + + + + + 引用上周 + + + + + + + 班次管理 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 导出 + + + + + + + 保存 + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.cpp b/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.cpp index 622892f5..d09438d4 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.cpp +++ b/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.cpp @@ -1,27 +1,27 @@ -#include "CDutySettingPluginWidget.h" -#include "CDutySetting.h" - -CDutySettingPluginWidget::CDutySettingPluginWidget() -{ - -} - -CDutySettingPluginWidget::~CDutySettingPluginWidget() -{ - -} - -bool CDutySettingPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CDutySetting *pWidget = new CDutySetting(parent, editMode); - //pWidget->initialize((int)E_Alarm_Dock); - *widget = (QWidget *)pWidget; - *alarmWidget = (IPluginWidget *)pWidget; - return true; -} - -void CDutySettingPluginWidget::release() -{ - -} +#include "CDutySettingPluginWidget.h" +#include "CDutySetting.h" + +CDutySettingPluginWidget::CDutySettingPluginWidget() +{ + +} + +CDutySettingPluginWidget::~CDutySettingPluginWidget() +{ + +} + +bool CDutySettingPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CDutySetting *pWidget = new CDutySetting(parent, editMode); + //pWidget->initialize((int)E_Alarm_Dock); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + return true; +} + +void CDutySettingPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.h b/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.h index 0e9a1354..fda950c6 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.h +++ b/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CDUTYSETTINGPLUGINWIDGET_H -#define CDUTYSETTINGPLUGINWIDGET_H - -#include -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CDutySettingPluginWidget : public QWidget, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CDutySettingPluginWidget(); - ~CDutySettingPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); - void release(); -}; - -#endif // CDUTYSETTINGPLUGINWIDGET_H +#ifndef CDUTYSETTINGPLUGINWIDGET_H +#define CDUTYSETTINGPLUGINWIDGET_H + +#include +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CDutySettingPluginWidget : public QWidget, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CDutySettingPluginWidget(); + ~CDutySettingPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif // CDUTYSETTINGPLUGINWIDGET_H diff --git a/product/src/gui/plugin/ScheduleWidget/ScheduleWidget.pro b/product/src/gui/plugin/ScheduleWidget/ScheduleWidget.pro index acf00fbf..58ffb3f6 100644 --- a/product/src/gui/plugin/ScheduleWidget/ScheduleWidget.pro +++ b/product/src/gui/plugin/ScheduleWidget/ScheduleWidget.pro @@ -1,69 +1,69 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-12-16T15:45:54 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = ScheduleWidget -TEMPLATE = lib -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CDutySetting.cpp \ - CDragListWidget.cpp \ - CDropListWidget.cpp \ - CDutyDefineDialog.cpp \ - CDutySettingPluginWidget.cpp - -HEADERS += \ - CDutySetting.h \ - CDragListWidget.h \ - CDropListWidget.h \ - CDutyDefineDialog.h \ - CDutySettingPluginWidget.h - -FORMS += \ - CDutySetting.ui \ - CDutyDefineDialog.ui - -LIBS += -llog4cplus \ - -lpub_logger_api \ - -ldb_base_api \ - -ldb_api_ex \ - -lboost_system \ - -lboost_thread \ - -lboost_chrono \ - -lpub_utility_api \ - -lmodel_excel \ - -lperm_mng_api \ - -lalarm_server_api \ - -lprotobuf \ - -lpub_sysinfo_api \ - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -RESOURCES += \ - resource.qrc +#------------------------------------------------- +# +# Project created by QtCreator 2019-12-16T15:45:54 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ScheduleWidget +TEMPLATE = lib +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CDutySetting.cpp \ + CDragListWidget.cpp \ + CDropListWidget.cpp \ + CDutyDefineDialog.cpp \ + CDutySettingPluginWidget.cpp + +HEADERS += \ + CDutySetting.h \ + CDragListWidget.h \ + CDropListWidget.h \ + CDutyDefineDialog.h \ + CDutySettingPluginWidget.h + +FORMS += \ + CDutySetting.ui \ + CDutyDefineDialog.ui + +LIBS += -llog4cplus \ + -lpub_logger_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lboost_system \ + -lboost_thread \ + -lboost_chrono \ + -lpub_utility_api \ + -lmodel_excel \ + -lperm_mng_api \ + -lalarm_server_api \ + -lprotobuf \ + -lpub_sysinfo_api \ + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +RESOURCES += \ + resource.qrc diff --git a/product/src/gui/plugin/ScheduleWidget/main.cpp b/product/src/gui/plugin/ScheduleWidget/main.cpp index 1ead4c1f..b11b1049 100644 --- a/product/src/gui/plugin/ScheduleWidget/main.cpp +++ b/product/src/gui/plugin/ScheduleWidget/main.cpp @@ -1,22 +1,22 @@ -#include "CDutySetting.h" -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - - - kbd_public::StartLogSystem( "", "" ); - kbd_net::initMsgBus("duty_setting","duty_setting xxx"); - - CDutySetting w( 0, false ); - w.show(); - - int nRet = a.exec(); - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return nRet; -} +#include "CDutySetting.h" +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + + kbd_public::StartLogSystem( "", "" ); + kbd_net::initMsgBus("duty_setting","duty_setting xxx"); + + CDutySetting w( 0, false ); + w.show(); + + int nRet = a.exec(); + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return nRet; +} diff --git a/product/src/gui/plugin/ScheduleWidget/resource.qrc b/product/src/gui/plugin/ScheduleWidget/resource.qrc index c426b06a..10d7f518 100644 --- a/product/src/gui/plugin/ScheduleWidget/resource.qrc +++ b/product/src/gui/plugin/ScheduleWidget/resource.qrc @@ -1,6 +1,6 @@ - - - - resource/combobox-drop-down.png - - + + + + resource/combobox-drop-down.png + + diff --git a/product/src/gui/plugin/SequenceManageWidget/CHistoryActionModel.cpp b/product/src/gui/plugin/SequenceManageWidget/CHistoryActionModel.cpp index f49f461a..0b891be0 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CHistoryActionModel.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CHistoryActionModel.cpp @@ -1,288 +1,288 @@ -#include "CHistoryActionModel.h" - -CHistoryActionTreeModelItem::CHistoryActionTreeModelItem(CHistoryActionTreeModelItem *parent) - : m_parent(parent) -{ - m_listChild.clear(); - if(Q_NULLPTR != m_parent) - { - m_parent->appendChild(this); - } -} - -CHistoryActionTreeModelItem::CHistoryActionTreeModelItem(const QList &data, CHistoryActionTreeModelItem *parent) - : m_parent(parent), - m_data(data) -{ - m_listChild.clear(); - if(Q_NULLPTR != m_parent) - { - m_parent->appendChild(this); - } -} - -CHistoryActionTreeModelItem::~CHistoryActionTreeModelItem() -{ - qDeleteAll(m_listChild); - if (Q_NULLPTR != m_parent) - { - m_parent->removeChild(this); - } -} - -bool CHistoryActionTreeModelItem::isRootItem() -{ - if (m_parent == Q_NULLPTR) - { - return true; - } - return false; -} - -CHistoryActionTreeModelItem *CHistoryActionTreeModelItem::parent() -{ - return m_parent; -} - -CHistoryActionTreeModelItem *CHistoryActionTreeModelItem::child(const int row) -{ - if(row < m_listChild.size()) - { - return m_listChild.value(row); - } - - return Q_NULLPTR; -} - -void CHistoryActionTreeModelItem::appendChild(CHistoryActionTreeModelItem *child) -{ - m_listChild.append(child); -} - -void CHistoryActionTreeModelItem::removeChild(CHistoryActionTreeModelItem *child) -{ - m_listChild.removeOne(child); -} - -void CHistoryActionTreeModelItem::clear() -{ - if (!m_listChild.isEmpty()) - { - QList::iterator it = m_listChild.begin(); - while (it != m_listChild.end()) - { - CHistoryActionTreeModelItem * item = *it; - it = m_listChild.erase(it); - item->clear(); - delete item; - } - } -} - -int CHistoryActionTreeModelItem::row() -{ - if(m_parent) - { - return m_parent->m_listChild.indexOf(this); - } - return 0; -} - -int CHistoryActionTreeModelItem::childCount() -{ - if (m_listChild.isEmpty()) - { - return 0; - } - - return m_listChild.size(); -} - -int CHistoryActionTreeModelItem::columnCount() -{ - return m_data.size(); -} - -QVariant CHistoryActionTreeModelItem::data(QModelIndex index) -{ - return m_data.value(index.column()); -} - -bool CHistoryActionTreeModelItem::setData(QModelIndex index, const QVariant &value) -{ - if(!index.isValid() || !value.isValid()) - { - return false; - } - if(index.column() >= m_data.size()) - { - return false; - } - - m_data[index.column()] = value; - return true; -} - -CHistoryActionModel::CHistoryActionModel(QObject *parent) - : QAbstractItemModel(parent), - m_rootItem(Q_NULLPTR) -{ - m_header << tr("动作") << tr("位置") << tr("描述") << tr("执行结果"); -} - -void CHistoryActionModel::updateModelFunctionData(const QList &listFuncInfo) -{ - beginResetModel(); - if(Q_NULLPTR != m_rootItem) - { - m_rootItem->clear(); - delete m_rootItem; - } - m_rootItem = new CHistoryActionTreeModelItem(); - for(int nIndx(0); nIndx < listFuncInfo.size(); nIndx++) - { - QList values; - values.append(listFuncInfo[nIndx].funcDescription); - values.append(QVariant()); - values.append(QVariant()); - values.append(QVariant()); - CHistoryActionTreeModelItem * item = new CHistoryActionTreeModelItem(values, m_rootItem); - Q_UNUSED(item) - } - endResetModel(); -} - -void CHistoryActionModel::updateModelActionData(const QList &listActionInfo) -{ - beginResetModel(); - for(int nIndex(0); nIndex < m_rootItem->childCount(); nIndex++) - { - CHistoryActionTreeModelItem * parent = m_rootItem->child(nIndex); - QString funcDescription = parent->data(createIndex(nIndex, History_Action_Column::nameColumn)).toString(); - for(int nActionIndex(0); nActionIndex < listActionInfo.size(); nActionIndex++) - { - if(listActionInfo[nActionIndex].functionDescription == funcDescription) - { - QList values; - values.append(listActionInfo[nActionIndex].actionDescription); - values.append(listActionInfo[nActionIndex].location); - values.append(listActionInfo[nActionIndex].description); - values.append(listActionInfo[nActionIndex].status); - CHistoryActionTreeModelItem * item = new CHistoryActionTreeModelItem(values, parent); - Q_UNUSED(item) - } - } - } - endResetModel(); -} - -QVariant CHistoryActionModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(orientation) - if(Qt::DisplayRole == role) - { - return m_header[section]; - } - if (Qt::TextAlignmentRole == role) - { - return Qt::AlignCenter; - } - return QVariant(); -} - -QModelIndex CHistoryActionModel::index(int row, int column, const QModelIndex &parent) const -{ - if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) - { - return QModelIndex(); - } - - CHistoryActionTreeModelItem * parentItem; - if(!parent.isValid()) - { - parentItem = m_rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - if(parentItem) - { - CHistoryActionTreeModelItem *childItem = parentItem->child(row); - if(childItem) - { - return createIndex(row,column,childItem); - } - } - return QModelIndex(); -} - -QModelIndex CHistoryActionModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - CHistoryActionTreeModelItem *childItem = static_cast(index.internalPointer()); - if (!childItem) - { - return QModelIndex(); - } - - CHistoryActionTreeModelItem *parentItem = childItem->parent(); - - if (parentItem == m_rootItem) - { - return QModelIndex(); - } - - return createIndex(parentItem->row(), index.column(), parentItem); -} - -int CHistoryActionModel::rowCount(const QModelIndex &parent) const -{ - if(!parent.isValid()) - { - if (NULL != m_rootItem) - { - return m_rootItem->childCount(); - } - else - { - return 0; - } - } - else - { - CHistoryActionTreeModelItem * parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); - } -} - -int CHistoryActionModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return m_header.size(); -} - -QVariant CHistoryActionModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - { - return QVariant(); - } - if(Qt::TextAlignmentRole == role && index.column() != History_Action_Column::nameColumn) - { - return Qt::AlignHCenter; - } - - if(Qt::DisplayRole == role) - { - CHistoryActionTreeModelItem * item = static_cast(index.internalPointer()); - return item->data(index); - } - return QVariant(); -} - +#include "CHistoryActionModel.h" + +CHistoryActionTreeModelItem::CHistoryActionTreeModelItem(CHistoryActionTreeModelItem *parent) + : m_parent(parent) +{ + m_listChild.clear(); + if(Q_NULLPTR != m_parent) + { + m_parent->appendChild(this); + } +} + +CHistoryActionTreeModelItem::CHistoryActionTreeModelItem(const QList &data, CHistoryActionTreeModelItem *parent) + : m_parent(parent), + m_data(data) +{ + m_listChild.clear(); + if(Q_NULLPTR != m_parent) + { + m_parent->appendChild(this); + } +} + +CHistoryActionTreeModelItem::~CHistoryActionTreeModelItem() +{ + qDeleteAll(m_listChild); + if (Q_NULLPTR != m_parent) + { + m_parent->removeChild(this); + } +} + +bool CHistoryActionTreeModelItem::isRootItem() +{ + if (m_parent == Q_NULLPTR) + { + return true; + } + return false; +} + +CHistoryActionTreeModelItem *CHistoryActionTreeModelItem::parent() +{ + return m_parent; +} + +CHistoryActionTreeModelItem *CHistoryActionTreeModelItem::child(const int row) +{ + if(row < m_listChild.size()) + { + return m_listChild.value(row); + } + + return Q_NULLPTR; +} + +void CHistoryActionTreeModelItem::appendChild(CHistoryActionTreeModelItem *child) +{ + m_listChild.append(child); +} + +void CHistoryActionTreeModelItem::removeChild(CHistoryActionTreeModelItem *child) +{ + m_listChild.removeOne(child); +} + +void CHistoryActionTreeModelItem::clear() +{ + if (!m_listChild.isEmpty()) + { + QList::iterator it = m_listChild.begin(); + while (it != m_listChild.end()) + { + CHistoryActionTreeModelItem * item = *it; + it = m_listChild.erase(it); + item->clear(); + delete item; + } + } +} + +int CHistoryActionTreeModelItem::row() +{ + if(m_parent) + { + return m_parent->m_listChild.indexOf(this); + } + return 0; +} + +int CHistoryActionTreeModelItem::childCount() +{ + if (m_listChild.isEmpty()) + { + return 0; + } + + return m_listChild.size(); +} + +int CHistoryActionTreeModelItem::columnCount() +{ + return m_data.size(); +} + +QVariant CHistoryActionTreeModelItem::data(QModelIndex index) +{ + return m_data.value(index.column()); +} + +bool CHistoryActionTreeModelItem::setData(QModelIndex index, const QVariant &value) +{ + if(!index.isValid() || !value.isValid()) + { + return false; + } + if(index.column() >= m_data.size()) + { + return false; + } + + m_data[index.column()] = value; + return true; +} + +CHistoryActionModel::CHistoryActionModel(QObject *parent) + : QAbstractItemModel(parent), + m_rootItem(Q_NULLPTR) +{ + m_header << tr("动作") << tr("位置") << tr("描述") << tr("执行结果"); +} + +void CHistoryActionModel::updateModelFunctionData(const QList &listFuncInfo) +{ + beginResetModel(); + if(Q_NULLPTR != m_rootItem) + { + m_rootItem->clear(); + delete m_rootItem; + } + m_rootItem = new CHistoryActionTreeModelItem(); + for(int nIndx(0); nIndx < listFuncInfo.size(); nIndx++) + { + QList values; + values.append(listFuncInfo[nIndx].funcDescription); + values.append(QVariant()); + values.append(QVariant()); + values.append(QVariant()); + CHistoryActionTreeModelItem * item = new CHistoryActionTreeModelItem(values, m_rootItem); + Q_UNUSED(item) + } + endResetModel(); +} + +void CHistoryActionModel::updateModelActionData(const QList &listActionInfo) +{ + beginResetModel(); + for(int nIndex(0); nIndex < m_rootItem->childCount(); nIndex++) + { + CHistoryActionTreeModelItem * parent = m_rootItem->child(nIndex); + QString funcDescription = parent->data(createIndex(nIndex, History_Action_Column::nameColumn)).toString(); + for(int nActionIndex(0); nActionIndex < listActionInfo.size(); nActionIndex++) + { + if(listActionInfo[nActionIndex].functionDescription == funcDescription) + { + QList values; + values.append(listActionInfo[nActionIndex].actionDescription); + values.append(listActionInfo[nActionIndex].location); + values.append(listActionInfo[nActionIndex].description); + values.append(listActionInfo[nActionIndex].status); + CHistoryActionTreeModelItem * item = new CHistoryActionTreeModelItem(values, parent); + Q_UNUSED(item) + } + } + } + endResetModel(); +} + +QVariant CHistoryActionModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(orientation) + if(Qt::DisplayRole == role) + { + return m_header[section]; + } + if (Qt::TextAlignmentRole == role) + { + return Qt::AlignCenter; + } + return QVariant(); +} + +QModelIndex CHistoryActionModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) + { + return QModelIndex(); + } + + CHistoryActionTreeModelItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + CHistoryActionTreeModelItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,column,childItem); + } + } + return QModelIndex(); +} + +QModelIndex CHistoryActionModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CHistoryActionTreeModelItem *childItem = static_cast(index.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + CHistoryActionTreeModelItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + { + return QModelIndex(); + } + + return createIndex(parentItem->row(), index.column(), parentItem); +} + +int CHistoryActionModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (NULL != m_rootItem) + { + return m_rootItem->childCount(); + } + else + { + return 0; + } + } + else + { + CHistoryActionTreeModelItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int CHistoryActionModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_header.size(); +} + +QVariant CHistoryActionModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + if(Qt::TextAlignmentRole == role && index.column() != History_Action_Column::nameColumn) + { + return Qt::AlignHCenter; + } + + if(Qt::DisplayRole == role) + { + CHistoryActionTreeModelItem * item = static_cast(index.internalPointer()); + return item->data(index); + } + return QVariant(); +} + diff --git a/product/src/gui/plugin/SequenceManageWidget/CHistoryActionModel.h b/product/src/gui/plugin/SequenceManageWidget/CHistoryActionModel.h index 74818266..e27d330d 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CHistoryActionModel.h +++ b/product/src/gui/plugin/SequenceManageWidget/CHistoryActionModel.h @@ -1,71 +1,71 @@ -#ifndef CHISTORYACTIONMODEL_H -#define CHISTORYACTIONMODEL_H - -#include -#include "sequence_history_def.h" - -namespace History_Action_Column -{ - const int nameColumn = 0; - const int locationColumn = 1; - const int descriptColumn = 2; - const int resultColumn = 3; -} - -class CHistoryActionTreeModelItem : public QObject -{ - Q_OBJECT - friend class CHistoryActionModel; - -public: - CHistoryActionTreeModelItem(CHistoryActionTreeModelItem * parent = Q_NULLPTR); - CHistoryActionTreeModelItem(const QList &data, CHistoryActionTreeModelItem * parent = Q_NULLPTR); - ~CHistoryActionTreeModelItem(); - - bool isRootItem(); - CHistoryActionTreeModelItem * parent(); - CHistoryActionTreeModelItem * child(const int row); - void appendChild(CHistoryActionTreeModelItem *child); - void removeChild(CHistoryActionTreeModelItem *child); - void clear(); - - int row(); - int childCount(); - int columnCount(); - QVariant data(QModelIndex index); - bool setData(QModelIndex index, const QVariant &value); - -private: - CHistoryActionTreeModelItem * m_parent; - QList m_data; - QList m_listChild; -}; - -class CHistoryActionModel : public QAbstractItemModel -{ - Q_OBJECT -public: - explicit CHistoryActionModel(QObject *parent = nullptr); - - void updateModelFunctionData(const QList &listFuncInfo); - - void updateModelActionData(const QList &listActionInfo); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: - QStringList m_header; - CHistoryActionTreeModelItem * m_rootItem; -}; - -#endif // CHISTORYACTIONMODEL_H +#ifndef CHISTORYACTIONMODEL_H +#define CHISTORYACTIONMODEL_H + +#include +#include "sequence_history_def.h" + +namespace History_Action_Column +{ + const int nameColumn = 0; + const int locationColumn = 1; + const int descriptColumn = 2; + const int resultColumn = 3; +} + +class CHistoryActionTreeModelItem : public QObject +{ + Q_OBJECT + friend class CHistoryActionModel; + +public: + CHistoryActionTreeModelItem(CHistoryActionTreeModelItem * parent = Q_NULLPTR); + CHistoryActionTreeModelItem(const QList &data, CHistoryActionTreeModelItem * parent = Q_NULLPTR); + ~CHistoryActionTreeModelItem(); + + bool isRootItem(); + CHistoryActionTreeModelItem * parent(); + CHistoryActionTreeModelItem * child(const int row); + void appendChild(CHistoryActionTreeModelItem *child); + void removeChild(CHistoryActionTreeModelItem *child); + void clear(); + + int row(); + int childCount(); + int columnCount(); + QVariant data(QModelIndex index); + bool setData(QModelIndex index, const QVariant &value); + +private: + CHistoryActionTreeModelItem * m_parent; + QList m_data; + QList m_listChild; +}; + +class CHistoryActionModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit CHistoryActionModel(QObject *parent = nullptr); + + void updateModelFunctionData(const QList &listFuncInfo); + + void updateModelActionData(const QList &listActionInfo); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QStringList m_header; + CHistoryActionTreeModelItem * m_rootItem; +}; + +#endif // CHISTORYACTIONMODEL_H diff --git a/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.cpp b/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.cpp index 05f19abe..f1eb4ba6 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.cpp @@ -1,139 +1,139 @@ -#include "CHistorySequenceFilterDialog.h" -#include "ui_CHistorySequenceFilterDialog.h" - -CHistorySequenceFilterDialog::CHistorySequenceFilterDialog(QStringList locationList, QStringList userNameList, QWidget *parent) : - QDialog(parent), - ui(new Ui::CHistorySequenceFilterDialog) -{ - ui->setupUi(this); - ui->locationListWidget->insertItems(0, locationList); - ui->userListWidget->insertItems(0, userNameList); - - QStringList resultList; - resultList << tr("执行成功") << tr("执行失败") << tr("执行终止") << tr("执行跳过"); - ui->resultListWidget->insertItems(0, resultList); - connect(this, &CHistorySequenceFilterDialog::accepted, this, &CHistorySequenceFilterDialog::updateFilter); -} - -CHistorySequenceFilterDialog::~CHistorySequenceFilterDialog() -{ - delete ui; -} - -void CHistorySequenceFilterDialog::initialize(const History_Filter_Condition &condition) -{ - m_seqFilterCondition = condition; - ui->locationFilter->setChecked(m_seqFilterCondition.locationFilter); - ui->userFilter->setChecked(m_seqFilterCondition.userFilter); - ui->resultFilter->setChecked(m_seqFilterCondition.resultFilter); - ui->typeFilter->setChecked(m_seqFilterCondition.typeFilter); - ui->timeFilter->setChecked(m_seqFilterCondition.timeFilter); - - for(int nIndex(0); nIndex < ui->locationListWidget->count(); nIndex++) - { - QString locationName = ui->locationListWidget->item(nIndex)->text(); - if(m_seqFilterCondition.locationList.contains(locationName)) - { - ui->locationListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); - } - } - - for(int nIndex(0); nIndex < ui->userListWidget->count(); nIndex++) - { - QString userName = ui->userListWidget->item(nIndex)->text(); - if(m_seqFilterCondition.userList.contains(userName)) - { - ui->userListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); - } - } - - for(int nIndex(0); nIndex < ui->resultListWidget->count(); nIndex++) - { - QString result = ui->resultListWidget->item(nIndex)->text(); - if(m_seqFilterCondition.resultList.contains(result)) - { - ui->resultListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); - } - } - - if(m_seqFilterCondition.isStandardType) - { - ui->standardSequence->setChecked(true); - } - else - { - ui->customSequence->setChecked(true); - } - - ui->startTime->blockSignals(true); - ui->endTime->blockSignals(true); - ui->startTime->setDateTime(m_seqFilterCondition.startTime); - ui->endTime->setDateTime(m_seqFilterCondition.endTime); - ui->startTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); - ui->endTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); - ui->startTime->blockSignals(false); - ui->endTime->blockSignals(false); -} - -History_Filter_Condition CHistorySequenceFilterDialog::sequenceFilterCondition() -{ - return m_seqFilterCondition; -} - -void CHistorySequenceFilterDialog::updateFilter() -{ - m_seqFilterCondition.locationFilter = ui->locationFilter->isChecked(); - m_seqFilterCondition.userFilter = ui->userFilter->isChecked(); - m_seqFilterCondition.resultFilter = ui->resultFilter->isChecked(); - m_seqFilterCondition.typeFilter = ui->typeFilter->isChecked(); - m_seqFilterCondition.timeFilter = ui->timeFilter->isChecked(); - - m_seqFilterCondition.locationList.clear(); - foreach (QListWidgetItem* item, ui->locationListWidget->selectedItems()) - { - m_seqFilterCondition.locationList.append(item->text()); - } - - m_seqFilterCondition.userList.clear(); - foreach (QListWidgetItem* item, ui->userListWidget->selectedItems()) - { - m_seqFilterCondition.userList.append(item->text()); - } - - m_seqFilterCondition.resultList.clear(); - foreach (QListWidgetItem* item, ui->resultListWidget->selectedItems()) - { - m_seqFilterCondition.resultList.append(item->text()); - } - - m_seqFilterCondition.isStandardType = ui->standardSequence->isChecked(); - - m_seqFilterCondition.startTime = ui->startTime->dateTime(); - m_seqFilterCondition.endTime = ui->endTime->dateTime(); -} - -void CHistorySequenceFilterDialog::on_startTime_dateTimeChanged(const QDateTime &dateTime) -{ - qint64 endTime = ui->endTime->dateTime().toMSecsSinceEpoch(); - if(dateTime.toMSecsSinceEpoch() > endTime) - { - QDateTime startTime = QDateTime::fromMSecsSinceEpoch(endTime); - QTime time = startTime.time(); - time.setHMS(time.hour(), time.minute(), time.second(), 0); - startTime.setTime(time); - ui->startTime->setDateTime(startTime); - } -} - -void CHistorySequenceFilterDialog::on_endTime_dateTimeChanged(const QDateTime &dateTime) -{ - qint64 startTime = ui->startTime->dateTime().toMSecsSinceEpoch(); - if(dateTime.toMSecsSinceEpoch() < startTime) - { - QDateTime endTime = QDateTime::fromMSecsSinceEpoch(startTime); - QTime time = endTime.time(); - time.setHMS(time.hour(), time.minute(), time.second(), 999); - endTime.setTime(time); - ui->endTime->setDateTime(endTime); - } -} +#include "CHistorySequenceFilterDialog.h" +#include "ui_CHistorySequenceFilterDialog.h" + +CHistorySequenceFilterDialog::CHistorySequenceFilterDialog(QStringList locationList, QStringList userNameList, QWidget *parent) : + QDialog(parent), + ui(new Ui::CHistorySequenceFilterDialog) +{ + ui->setupUi(this); + ui->locationListWidget->insertItems(0, locationList); + ui->userListWidget->insertItems(0, userNameList); + + QStringList resultList; + resultList << tr("执行成功") << tr("执行失败") << tr("执行终止") << tr("执行跳过"); + ui->resultListWidget->insertItems(0, resultList); + connect(this, &CHistorySequenceFilterDialog::accepted, this, &CHistorySequenceFilterDialog::updateFilter); +} + +CHistorySequenceFilterDialog::~CHistorySequenceFilterDialog() +{ + delete ui; +} + +void CHistorySequenceFilterDialog::initialize(const History_Filter_Condition &condition) +{ + m_seqFilterCondition = condition; + ui->locationFilter->setChecked(m_seqFilterCondition.locationFilter); + ui->userFilter->setChecked(m_seqFilterCondition.userFilter); + ui->resultFilter->setChecked(m_seqFilterCondition.resultFilter); + ui->typeFilter->setChecked(m_seqFilterCondition.typeFilter); + ui->timeFilter->setChecked(m_seqFilterCondition.timeFilter); + + for(int nIndex(0); nIndex < ui->locationListWidget->count(); nIndex++) + { + QString locationName = ui->locationListWidget->item(nIndex)->text(); + if(m_seqFilterCondition.locationList.contains(locationName)) + { + ui->locationListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); + } + } + + for(int nIndex(0); nIndex < ui->userListWidget->count(); nIndex++) + { + QString userName = ui->userListWidget->item(nIndex)->text(); + if(m_seqFilterCondition.userList.contains(userName)) + { + ui->userListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); + } + } + + for(int nIndex(0); nIndex < ui->resultListWidget->count(); nIndex++) + { + QString result = ui->resultListWidget->item(nIndex)->text(); + if(m_seqFilterCondition.resultList.contains(result)) + { + ui->resultListWidget->setCurrentRow(nIndex, QItemSelectionModel::Select); + } + } + + if(m_seqFilterCondition.isStandardType) + { + ui->standardSequence->setChecked(true); + } + else + { + ui->customSequence->setChecked(true); + } + + ui->startTime->blockSignals(true); + ui->endTime->blockSignals(true); + ui->startTime->setDateTime(m_seqFilterCondition.startTime); + ui->endTime->setDateTime(m_seqFilterCondition.endTime); + ui->startTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); + ui->endTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); + ui->startTime->blockSignals(false); + ui->endTime->blockSignals(false); +} + +History_Filter_Condition CHistorySequenceFilterDialog::sequenceFilterCondition() +{ + return m_seqFilterCondition; +} + +void CHistorySequenceFilterDialog::updateFilter() +{ + m_seqFilterCondition.locationFilter = ui->locationFilter->isChecked(); + m_seqFilterCondition.userFilter = ui->userFilter->isChecked(); + m_seqFilterCondition.resultFilter = ui->resultFilter->isChecked(); + m_seqFilterCondition.typeFilter = ui->typeFilter->isChecked(); + m_seqFilterCondition.timeFilter = ui->timeFilter->isChecked(); + + m_seqFilterCondition.locationList.clear(); + foreach (QListWidgetItem* item, ui->locationListWidget->selectedItems()) + { + m_seqFilterCondition.locationList.append(item->text()); + } + + m_seqFilterCondition.userList.clear(); + foreach (QListWidgetItem* item, ui->userListWidget->selectedItems()) + { + m_seqFilterCondition.userList.append(item->text()); + } + + m_seqFilterCondition.resultList.clear(); + foreach (QListWidgetItem* item, ui->resultListWidget->selectedItems()) + { + m_seqFilterCondition.resultList.append(item->text()); + } + + m_seqFilterCondition.isStandardType = ui->standardSequence->isChecked(); + + m_seqFilterCondition.startTime = ui->startTime->dateTime(); + m_seqFilterCondition.endTime = ui->endTime->dateTime(); +} + +void CHistorySequenceFilterDialog::on_startTime_dateTimeChanged(const QDateTime &dateTime) +{ + qint64 endTime = ui->endTime->dateTime().toMSecsSinceEpoch(); + if(dateTime.toMSecsSinceEpoch() > endTime) + { + QDateTime startTime = QDateTime::fromMSecsSinceEpoch(endTime); + QTime time = startTime.time(); + time.setHMS(time.hour(), time.minute(), time.second(), 0); + startTime.setTime(time); + ui->startTime->setDateTime(startTime); + } +} + +void CHistorySequenceFilterDialog::on_endTime_dateTimeChanged(const QDateTime &dateTime) +{ + qint64 startTime = ui->startTime->dateTime().toMSecsSinceEpoch(); + if(dateTime.toMSecsSinceEpoch() < startTime) + { + QDateTime endTime = QDateTime::fromMSecsSinceEpoch(startTime); + QTime time = endTime.time(); + time.setHMS(time.hour(), time.minute(), time.second(), 999); + endTime.setTime(time); + ui->endTime->setDateTime(endTime); + } +} diff --git a/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.h b/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.h index 165d8d15..413200fc 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.h +++ b/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.h @@ -1,67 +1,67 @@ -#ifndef CHISTORYSEQUENCEFILTERDIALOG_H -#define CHISTORYSEQUENCEFILTERDIALOG_H - -#include -#include - -namespace Ui { -class CHistorySequenceFilterDialog; -} - -struct History_Filter_Condition -{ - History_Filter_Condition() - { - locationFilter = false; - locationList = QStringList(); - userFilter = false; - userList = QStringList(); - resultFilter = false; - resultList = QStringList(); - typeFilter = false; - isStandardType = true; - timeFilter = false; - startTime = QDateTime(QDate::currentDate()); - endTime = QDateTime::currentDateTime(); - } - - bool locationFilter; - QStringList locationList; - bool userFilter; - QStringList userList; - bool resultFilter; - QStringList resultList; - bool typeFilter; - bool isStandardType; - bool timeFilter; - QDateTime startTime; - QDateTime endTime; -}; - -class CHistorySequenceFilterDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CHistorySequenceFilterDialog(QStringList locationList, QStringList userNameList, QWidget *parent = 0); - ~CHistorySequenceFilterDialog(); - - void initialize(const History_Filter_Condition &condition); - - History_Filter_Condition sequenceFilterCondition(); - -protected slots: - void updateFilter(); - -private slots: - void on_startTime_dateTimeChanged(const QDateTime &dateTime); - - void on_endTime_dateTimeChanged(const QDateTime &dateTime); - -private: - Ui::CHistorySequenceFilterDialog *ui; - - History_Filter_Condition m_seqFilterCondition; -}; - -#endif // CHISTORYSEQUENCEFILTERDIALOG_H +#ifndef CHISTORYSEQUENCEFILTERDIALOG_H +#define CHISTORYSEQUENCEFILTERDIALOG_H + +#include +#include + +namespace Ui { +class CHistorySequenceFilterDialog; +} + +struct History_Filter_Condition +{ + History_Filter_Condition() + { + locationFilter = false; + locationList = QStringList(); + userFilter = false; + userList = QStringList(); + resultFilter = false; + resultList = QStringList(); + typeFilter = false; + isStandardType = true; + timeFilter = false; + startTime = QDateTime(QDate::currentDate()); + endTime = QDateTime::currentDateTime(); + } + + bool locationFilter; + QStringList locationList; + bool userFilter; + QStringList userList; + bool resultFilter; + QStringList resultList; + bool typeFilter; + bool isStandardType; + bool timeFilter; + QDateTime startTime; + QDateTime endTime; +}; + +class CHistorySequenceFilterDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CHistorySequenceFilterDialog(QStringList locationList, QStringList userNameList, QWidget *parent = 0); + ~CHistorySequenceFilterDialog(); + + void initialize(const History_Filter_Condition &condition); + + History_Filter_Condition sequenceFilterCondition(); + +protected slots: + void updateFilter(); + +private slots: + void on_startTime_dateTimeChanged(const QDateTime &dateTime); + + void on_endTime_dateTimeChanged(const QDateTime &dateTime); + +private: + Ui::CHistorySequenceFilterDialog *ui; + + History_Filter_Condition m_seqFilterCondition; +}; + +#endif // CHISTORYSEQUENCEFILTERDIALOG_H diff --git a/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.ui b/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.ui index fa6f419f..df62bcc9 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.ui +++ b/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceFilterDialog.ui @@ -1,236 +1,236 @@ - - - CHistorySequenceFilterDialog - - - - 0 - 0 - 537 - 418 - - - - 过滤 - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - - - - - 位置 - - - true - - - false - - - - - - QAbstractItemView::MultiSelection - - - - - - - - - - 用户 - - - true - - - false - - - - - - QAbstractItemView::MultiSelection - - - - - - - - - - 结果 - - - true - - - false - - - - - - QAbstractItemView::MultiSelection - - - - - - - - - - - - 9 - - - - - 类型 - - - true - - - false - - - - - - 标准顺控 - - - true - - - - - - - 自定义顺控 - - - - - - - - - - 时间 - - - true - - - false - - - - - - - - 起始时间: - - - - - - - - - - 结束时间: - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - CHistorySequenceFilterDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - CHistorySequenceFilterDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - + + + CHistorySequenceFilterDialog + + + + 0 + 0 + 537 + 418 + + + + 过滤 + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + + 位置 + + + true + + + false + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + + 用户 + + + true + + + false + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + + 结果 + + + true + + + false + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + + + + 9 + + + + + 类型 + + + true + + + false + + + + + + 标准顺控 + + + true + + + + + + + 自定义顺控 + + + + + + + + + + 时间 + + + true + + + false + + + + + + + + 起始时间: + + + + + + + + + + 结束时间: + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + CHistorySequenceFilterDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CHistorySequenceFilterDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceModel.h b/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceModel.h index 6184c8c4..4ad79469 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceModel.h +++ b/product/src/gui/plugin/SequenceManageWidget/CHistorySequenceModel.h @@ -1,47 +1,47 @@ -#ifndef CHISTORYSEQUENCEMODEL_H -#define CHISTORYSEQUENCEMODEL_H - -#include -#include "sequence_history_def.h" - -namespace History_Sequence_Column -{ - const int sequenceColumn = 0; - const int locationColumn = 1; - const int timeColumn = 2; - const int userColumn = 3; - const int typeColumn = 4; - const int resultColumn = 5; -} - -class CHistorySequenceModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - explicit CHistorySequenceModel(QObject *parent = nullptr); - - void setHistorySequenceData(QList listSequence); - - QString sequenceName(const QModelIndex &index); - - quint64 sequenceTime(const QModelIndex &index); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &child) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: - QStringList m_header; - QList m_data; -}; - -#endif // CHISTORYSEQUENCEMODEL_H +#ifndef CHISTORYSEQUENCEMODEL_H +#define CHISTORYSEQUENCEMODEL_H + +#include +#include "sequence_history_def.h" + +namespace History_Sequence_Column +{ + const int sequenceColumn = 0; + const int locationColumn = 1; + const int timeColumn = 2; + const int userColumn = 3; + const int typeColumn = 4; + const int resultColumn = 5; +} + +class CHistorySequenceModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CHistorySequenceModel(QObject *parent = nullptr); + + void setHistorySequenceData(QList listSequence); + + QString sequenceName(const QModelIndex &index); + + quint64 sequenceTime(const QModelIndex &index); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QStringList m_header; + QList m_data; +}; + +#endif // CHISTORYSEQUENCEMODEL_H diff --git a/product/src/gui/plugin/SequenceManageWidget/CHistroySequenceModel.cpp b/product/src/gui/plugin/SequenceManageWidget/CHistroySequenceModel.cpp index c10c33d1..9c1158aa 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CHistroySequenceModel.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CHistroySequenceModel.cpp @@ -1,129 +1,129 @@ -#include "CHistorySequenceModel.h" -#include - -CHistorySequenceModel::CHistorySequenceModel(QObject *parent) - : QAbstractItemModel(parent) -{ - m_header << tr("名称") << tr("位置") << tr("时间") << tr("用户") << tr("类型") << tr("执行结果"); -} - -void CHistorySequenceModel::setHistorySequenceData(QList listSequence) -{ - beginResetModel(); - m_data.clear(); - m_data = listSequence; - endResetModel(); -} - -QString CHistorySequenceModel::sequenceName(const QModelIndex &index) -{ - if(!index.isValid()) - { - return QString(); - } - return m_data[index.row()].seqName; -} - -quint64 CHistorySequenceModel::sequenceTime(const QModelIndex &index) -{ - if(!index.isValid()) - { - return 0; - } - return m_data[index.row()].time; -} - -QVariant CHistorySequenceModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::Horizontal != orientation || Qt::DisplayRole != role) - { - return QVariant(); - } - return m_header[section]; -} - -QModelIndex CHistorySequenceModel::index(int row, int column, const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return createIndex(row, column); -} - -QModelIndex CHistorySequenceModel::parent(const QModelIndex &child) const -{ - Q_UNUSED(child) - return QModelIndex(); -} - -int CHistorySequenceModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_data.size(); -} - -int CHistorySequenceModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.size(); -} - -QVariant CHistorySequenceModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || (Qt::DisplayRole != role && Qt::TextAlignmentRole != role)) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - - - switch (index.column()) - { - case History_Sequence_Column::sequenceColumn: - { - return m_data[index.row()].seqDescription; - } - case History_Sequence_Column::locationColumn: - { - return m_data[index.row()].location; - } - case History_Sequence_Column::timeColumn: - { - QDateTime dt = QDateTime::fromSecsSinceEpoch(m_data[index.row()].time); - dt.setTimeSpec(Qt::LocalTime); - return dt.toString("yyyy-MM-dd hh:mm:ss"); - } - case History_Sequence_Column::userColumn: - { - return m_data[index.row()].userName; - } - case History_Sequence_Column::typeColumn: - { - if(0 == m_data[index.row()].seqType) - { - return tr("标准顺控"); - } - else if(1 == m_data[index.row()].seqType) - { - return tr("自定义顺控"); - } - return m_data[index.row()].seqType; - } - case History_Sequence_Column::resultColumn: - { - return m_data[index.row()].status; - } - default: - { - break; - } - } - - return QVariant(); -} +#include "CHistorySequenceModel.h" +#include + +CHistorySequenceModel::CHistorySequenceModel(QObject *parent) + : QAbstractItemModel(parent) +{ + m_header << tr("名称") << tr("位置") << tr("时间") << tr("用户") << tr("类型") << tr("执行结果"); +} + +void CHistorySequenceModel::setHistorySequenceData(QList listSequence) +{ + beginResetModel(); + m_data.clear(); + m_data = listSequence; + endResetModel(); +} + +QString CHistorySequenceModel::sequenceName(const QModelIndex &index) +{ + if(!index.isValid()) + { + return QString(); + } + return m_data[index.row()].seqName; +} + +quint64 CHistorySequenceModel::sequenceTime(const QModelIndex &index) +{ + if(!index.isValid()) + { + return 0; + } + return m_data[index.row()].time; +} + +QVariant CHistorySequenceModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::Horizontal != orientation || Qt::DisplayRole != role) + { + return QVariant(); + } + return m_header[section]; +} + +QModelIndex CHistorySequenceModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return createIndex(row, column); +} + +QModelIndex CHistorySequenceModel::parent(const QModelIndex &child) const +{ + Q_UNUSED(child) + return QModelIndex(); +} + +int CHistorySequenceModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_data.size(); +} + +int CHistorySequenceModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.size(); +} + +QVariant CHistorySequenceModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || (Qt::DisplayRole != role && Qt::TextAlignmentRole != role)) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + + switch (index.column()) + { + case History_Sequence_Column::sequenceColumn: + { + return m_data[index.row()].seqDescription; + } + case History_Sequence_Column::locationColumn: + { + return m_data[index.row()].location; + } + case History_Sequence_Column::timeColumn: + { + QDateTime dt = QDateTime::fromSecsSinceEpoch(m_data[index.row()].time); + dt.setTimeSpec(Qt::LocalTime); + return dt.toString("yyyy-MM-dd hh:mm:ss"); + } + case History_Sequence_Column::userColumn: + { + return m_data[index.row()].userName; + } + case History_Sequence_Column::typeColumn: + { + if(0 == m_data[index.row()].seqType) + { + return tr("标准顺控"); + } + else if(1 == m_data[index.row()].seqType) + { + return tr("自定义顺控"); + } + return m_data[index.row()].seqType; + } + case History_Sequence_Column::resultColumn: + { + return m_data[index.row()].status; + } + default: + { + break; + } + } + + return QVariant(); +} diff --git a/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.cpp b/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.cpp index cbdeeff5..a120aeab 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.cpp @@ -1,45 +1,45 @@ -#include "CRunSequenceFilterDialog.h" -#include "ui_CRunSequenceFilterDialog.h" - -CRunSequenceFilterDialog::CRunSequenceFilterDialog(QStringList locationList, QWidget *parent) : - QDialog(parent), - ui(new Ui::CRunSequenceFilterDialog) -{ - ui->setupUi(this); - ui->locationName->addItems(locationList); - connect(this, &CRunSequenceFilterDialog::accepted, this, &CRunSequenceFilterDialog::updateFilter); -} - -CRunSequenceFilterDialog::~CRunSequenceFilterDialog() -{ - delete ui; -} - -void CRunSequenceFilterDialog::initialize(const Run_Filter_Condition &condition) -{ - m_seqFilterCondition = condition; - ui->seqNameFilter->setChecked(condition.seqNameFilter); - ui->locationFilter->setChecked(condition.locationFilter); - ui->typeFilter->setChecked(condition.typeFilter); - - ui->sequenceName->setText(condition.seqName); - ui->locationName->setCurrentText(condition.locationName); - ui->standardSequence->setChecked(condition.isStandardType); - ui->customSequence->setChecked(!condition.isStandardType); -} - -Run_Filter_Condition CRunSequenceFilterDialog::sequenceFilterCondition() -{ - return m_seqFilterCondition; -} - -void CRunSequenceFilterDialog::updateFilter() -{ - m_seqFilterCondition.seqNameFilter = ui->seqNameFilter->isChecked(); - m_seqFilterCondition.locationFilter = ui->locationFilter->isChecked(); - m_seqFilterCondition.typeFilter = ui->typeFilter->isChecked(); - m_seqFilterCondition.seqName = ui->sequenceName->text(); - m_seqFilterCondition.locationName = ui->locationName->currentText(); - m_seqFilterCondition.isStandardType = ui->standardSequence->isChecked(); -} - +#include "CRunSequenceFilterDialog.h" +#include "ui_CRunSequenceFilterDialog.h" + +CRunSequenceFilterDialog::CRunSequenceFilterDialog(QStringList locationList, QWidget *parent) : + QDialog(parent), + ui(new Ui::CRunSequenceFilterDialog) +{ + ui->setupUi(this); + ui->locationName->addItems(locationList); + connect(this, &CRunSequenceFilterDialog::accepted, this, &CRunSequenceFilterDialog::updateFilter); +} + +CRunSequenceFilterDialog::~CRunSequenceFilterDialog() +{ + delete ui; +} + +void CRunSequenceFilterDialog::initialize(const Run_Filter_Condition &condition) +{ + m_seqFilterCondition = condition; + ui->seqNameFilter->setChecked(condition.seqNameFilter); + ui->locationFilter->setChecked(condition.locationFilter); + ui->typeFilter->setChecked(condition.typeFilter); + + ui->sequenceName->setText(condition.seqName); + ui->locationName->setCurrentText(condition.locationName); + ui->standardSequence->setChecked(condition.isStandardType); + ui->customSequence->setChecked(!condition.isStandardType); +} + +Run_Filter_Condition CRunSequenceFilterDialog::sequenceFilterCondition() +{ + return m_seqFilterCondition; +} + +void CRunSequenceFilterDialog::updateFilter() +{ + m_seqFilterCondition.seqNameFilter = ui->seqNameFilter->isChecked(); + m_seqFilterCondition.locationFilter = ui->locationFilter->isChecked(); + m_seqFilterCondition.typeFilter = ui->typeFilter->isChecked(); + m_seqFilterCondition.seqName = ui->sequenceName->text(); + m_seqFilterCondition.locationName = ui->locationName->currentText(); + m_seqFilterCondition.isStandardType = ui->standardSequence->isChecked(); +} + diff --git a/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.h b/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.h index 8e1701b2..d9eedd4d 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.h +++ b/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.h @@ -1,51 +1,51 @@ -#ifndef CRUNSEQUENCEFILTERDIALOG_H -#define CRUNSEQUENCEFILTERDIALOG_H - -#include - -namespace Ui { -class CRunSequenceFilterDialog; -} - -struct Run_Filter_Condition -{ - Run_Filter_Condition() - { - seqNameFilter = false; - seqName = QString(); - locationFilter = false; - locationName = QString(); - typeFilter = false; - isStandardType = true; - } - - bool seqNameFilter; - QString seqName; - bool locationFilter; - QString locationName; - bool typeFilter; - bool isStandardType; -}; - -class CRunSequenceFilterDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CRunSequenceFilterDialog(QStringList locationList, QWidget *parent = 0); - ~CRunSequenceFilterDialog(); - - void initialize(const Run_Filter_Condition &condition); - - Run_Filter_Condition sequenceFilterCondition(); - -protected slots: - void updateFilter(); - -private: - Ui::CRunSequenceFilterDialog *ui; - - Run_Filter_Condition m_seqFilterCondition; -}; - -#endif // CRUNSEQUENCEFILTERDIALOG_H +#ifndef CRUNSEQUENCEFILTERDIALOG_H +#define CRUNSEQUENCEFILTERDIALOG_H + +#include + +namespace Ui { +class CRunSequenceFilterDialog; +} + +struct Run_Filter_Condition +{ + Run_Filter_Condition() + { + seqNameFilter = false; + seqName = QString(); + locationFilter = false; + locationName = QString(); + typeFilter = false; + isStandardType = true; + } + + bool seqNameFilter; + QString seqName; + bool locationFilter; + QString locationName; + bool typeFilter; + bool isStandardType; +}; + +class CRunSequenceFilterDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CRunSequenceFilterDialog(QStringList locationList, QWidget *parent = 0); + ~CRunSequenceFilterDialog(); + + void initialize(const Run_Filter_Condition &condition); + + Run_Filter_Condition sequenceFilterCondition(); + +protected slots: + void updateFilter(); + +private: + Ui::CRunSequenceFilterDialog *ui; + + Run_Filter_Condition m_seqFilterCondition; +}; + +#endif // CRUNSEQUENCEFILTERDIALOG_H diff --git a/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.ui b/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.ui index efc52bdc..a8efb4ff 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.ui +++ b/product/src/gui/plugin/SequenceManageWidget/CRunSequenceFilterDialog.ui @@ -1,150 +1,150 @@ - - - CRunSequenceFilterDialog - - - - 0 - 0 - 390 - 159 - - - - 过滤 - - - - - - - - 关键字 - - - true - - - false - - - - - - 顺控名称: - - - - - - - - - - - - - 类型 - - - true - - - false - - - - - - 标准顺控 - - - true - - - - - - - 自定义顺控 - - - - - - - - - - 位置 - - - true - - - false - - - - - - 位置名称: - - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - CRunSequenceFilterDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - CRunSequenceFilterDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - + + + CRunSequenceFilterDialog + + + + 0 + 0 + 390 + 159 + + + + 过滤 + + + + + + + + 关键字 + + + true + + + false + + + + + + 顺控名称: + + + + + + + + + + + + + 类型 + + + true + + + false + + + + + + 标准顺控 + + + true + + + + + + + 自定义顺控 + + + + + + + + + + 位置 + + + true + + + false + + + + + + 位置名称: + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + CRunSequenceFilterDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CRunSequenceFilterDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/product/src/gui/plugin/SequenceManageWidget/CRunningSequenceModel.cpp b/product/src/gui/plugin/SequenceManageWidget/CRunningSequenceModel.cpp index 34ccb4c2..686d0b7c 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CRunningSequenceModel.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CRunningSequenceModel.cpp @@ -1,163 +1,163 @@ -#include "CRunningSequenceModel.h" -#include - -CRunningSequenceModel::CRunningSequenceModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header << tr("名称") << tr("位置") << tr("类型") << tr("执行结果"); -} - -void CRunningSequenceModel::runStatusFilter(bool statusFilter) -{ - beginResetModel(); - m_data.clear(); - if(!statusFilter) - { - m_data = m_allListSequence; - } - else - { - foreach (Sequence sequence, m_allListSequence) - { - if(sequence.executeState == E_Exec_Run || sequence.executeState == E_Exec_Pause) - { - m_data.append(sequence); - } - } - } - endResetModel(); -} - -void CRunningSequenceModel::updateSequenceData(QList listSequence) -{ - beginResetModel(); - m_data.clear(); - m_data = listSequence; - m_allListSequence.clear(); - m_allListSequence = m_data; - endResetModel(); -} - -QString CRunningSequenceModel::sequenceName(const QModelIndex &index) -{ - if(!index.isValid()) - { - return QString(); - } - - return m_data.at(index.row()).seqName; -} - -void CRunningSequenceModel::updateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state) -{ - for(int nIndex(0); nIndex < m_allListSequence.size(); nIndex++) - { - if(m_allListSequence[nIndex].seqName == seqName) - { - m_allListSequence[nIndex].executeState = state; - } - } - - for(int nIndex(0); nIndex < m_data.size(); nIndex++) - { - if(m_data.at(nIndex).seqName == seqName) - { - m_data[nIndex].executeState = state; - QModelIndex modelIndex = createIndex(nIndex, Running_Sequence_Column::statusColumn); - emit dataChanged(modelIndex, modelIndex); - return; - } - } -} - -QVariant CRunningSequenceModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::Horizontal != orientation || Qt::DisplayRole != role) - { - return QVariant(); - } - return m_header[section]; -} - -int CRunningSequenceModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return 0; - } - - return m_data.size(); -} - -int CRunningSequenceModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return 0; - } - return m_header.size(); -} - -QVariant CRunningSequenceModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - if(Qt::DisplayRole == role) - { - switch (index.column()) - { - case Running_Sequence_Column::nameColumn: - { - return m_data[index.row()].seqDescription; - } - case Running_Sequence_Column::locationColumn: - { - return m_data[index.row()].location; - } - case Running_Sequence_Column::typeColumn: - { - if(m_data[index.row()].seqType == 0) - { - return tr("标准顺控"); - } - else if(m_data[index.row()].seqType == 1) - { - return tr("自定义顺控"); - } - break; - } - case Running_Sequence_Column::statusColumn: - { - switch (m_data.at(index.row()).executeState) - { - case E_Exec_Reset: - return tr("未执行"); - case E_Exec_Run: - return tr("正在执行"); - case E_Exec_Triggered: - return tr("已触发"); - case E_Exec_Failed: - return tr("执行失败"); - case E_Exec_Success: - return tr("执行成功"); - case E_Exec_Stop: - return tr("执行终止"); - case E_Exec_Pause: - return tr("执行暂停"); - case E_Exec_Skip: - return tr("执行跳过"); - default: - break; - } - } - default: - break; - } - } - return QVariant(); -} +#include "CRunningSequenceModel.h" +#include + +CRunningSequenceModel::CRunningSequenceModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header << tr("名称") << tr("位置") << tr("类型") << tr("执行结果"); +} + +void CRunningSequenceModel::runStatusFilter(bool statusFilter) +{ + beginResetModel(); + m_data.clear(); + if(!statusFilter) + { + m_data = m_allListSequence; + } + else + { + foreach (Sequence sequence, m_allListSequence) + { + if(sequence.executeState == E_Exec_Run || sequence.executeState == E_Exec_Pause) + { + m_data.append(sequence); + } + } + } + endResetModel(); +} + +void CRunningSequenceModel::updateSequenceData(QList listSequence) +{ + beginResetModel(); + m_data.clear(); + m_data = listSequence; + m_allListSequence.clear(); + m_allListSequence = m_data; + endResetModel(); +} + +QString CRunningSequenceModel::sequenceName(const QModelIndex &index) +{ + if(!index.isValid()) + { + return QString(); + } + + return m_data.at(index.row()).seqName; +} + +void CRunningSequenceModel::updateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state) +{ + for(int nIndex(0); nIndex < m_allListSequence.size(); nIndex++) + { + if(m_allListSequence[nIndex].seqName == seqName) + { + m_allListSequence[nIndex].executeState = state; + } + } + + for(int nIndex(0); nIndex < m_data.size(); nIndex++) + { + if(m_data.at(nIndex).seqName == seqName) + { + m_data[nIndex].executeState = state; + QModelIndex modelIndex = createIndex(nIndex, Running_Sequence_Column::statusColumn); + emit dataChanged(modelIndex, modelIndex); + return; + } + } +} + +QVariant CRunningSequenceModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::Horizontal != orientation || Qt::DisplayRole != role) + { + return QVariant(); + } + return m_header[section]; +} + +int CRunningSequenceModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return 0; + } + + return m_data.size(); +} + +int CRunningSequenceModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return 0; + } + return m_header.size(); +} + +QVariant CRunningSequenceModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + if(Qt::DisplayRole == role) + { + switch (index.column()) + { + case Running_Sequence_Column::nameColumn: + { + return m_data[index.row()].seqDescription; + } + case Running_Sequence_Column::locationColumn: + { + return m_data[index.row()].location; + } + case Running_Sequence_Column::typeColumn: + { + if(m_data[index.row()].seqType == 0) + { + return tr("标准顺控"); + } + else if(m_data[index.row()].seqType == 1) + { + return tr("自定义顺控"); + } + break; + } + case Running_Sequence_Column::statusColumn: + { + switch (m_data.at(index.row()).executeState) + { + case E_Exec_Reset: + return tr("未执行"); + case E_Exec_Run: + return tr("正在执行"); + case E_Exec_Triggered: + return tr("已触发"); + case E_Exec_Failed: + return tr("执行失败"); + case E_Exec_Success: + return tr("执行成功"); + case E_Exec_Stop: + return tr("执行终止"); + case E_Exec_Pause: + return tr("执行暂停"); + case E_Exec_Skip: + return tr("执行跳过"); + default: + break; + } + } + default: + break; + } + } + return QVariant(); +} diff --git a/product/src/gui/plugin/SequenceManageWidget/CRunningSequenceModel.h b/product/src/gui/plugin/SequenceManageWidget/CRunningSequenceModel.h index 3b4f088c..93fe9313 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CRunningSequenceModel.h +++ b/product/src/gui/plugin/SequenceManageWidget/CRunningSequenceModel.h @@ -1,43 +1,43 @@ -#ifndef CRUNNINGSEQUENCEMODEL_H -#define CRUNNINGSEQUENCEMODEL_H - -#include -#include "../SequenceWidget/sequence_def.h" - -namespace Running_Sequence_Column -{ - const int nameColumn = 0; - const int locationColumn = 1; - const int typeColumn = 2; - const int statusColumn = 3; -} - -class CRunningSequenceModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CRunningSequenceModel(QObject *parent = nullptr); - - void runStatusFilter(bool statusFilter); - - void updateSequenceData(QList listSequence); - - QString sequenceName(const QModelIndex &index); - - void updateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: - QStringList m_header; - QList m_data; - QList m_allListSequence; -}; - -#endif // CRUNNINGSEQUENCEMODEL_H +#ifndef CRUNNINGSEQUENCEMODEL_H +#define CRUNNINGSEQUENCEMODEL_H + +#include +#include "../SequenceWidget/sequence_def.h" + +namespace Running_Sequence_Column +{ + const int nameColumn = 0; + const int locationColumn = 1; + const int typeColumn = 2; + const int statusColumn = 3; +} + +class CRunningSequenceModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CRunningSequenceModel(QObject *parent = nullptr); + + void runStatusFilter(bool statusFilter); + + void updateSequenceData(QList listSequence); + + QString sequenceName(const QModelIndex &index); + + void updateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QStringList m_header; + QList m_data; + QList m_allListSequence; +}; + +#endif // CRUNNINGSEQUENCEMODEL_H diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.cpp b/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.cpp index 16944030..c71b0e44 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.cpp @@ -1,618 +1,618 @@ -#include "CSequenceDBInterface.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "../../idl_files/SequenceMessage.pb.h" -#include "../../idl_files/RdbServerMessage.pb.h" - -using namespace kbd_dbms; -using namespace kbd_idlfile; - -CSequenceDBInterface::CSequenceDBInterface(CDbApi *dbRead) - : m_timer(NULL), - m_pReadDb(dbRead), m_rtdbAccessEx(nullptr), m_rdbNetApi(nullptr) -{ -} - -CSequenceDBInterface::~CSequenceDBInterface() -{ - slotUnSubScribeSequenceList(); - - m_pReadDb = NULL; - - if(NULL != m_rtdbAccessEx) - { - delete m_rtdbAccessEx; - } - m_rtdbAccessEx = NULL; - - if(NULL != m_rdbNetApi) - { - delete m_rdbNetApi; - } - m_rdbNetApi = NULL; -} - -void CSequenceDBInterface::initDataBase() -{ - //实时库 - m_rtdbAccessEx = new CRdbAccessEx(); - - //网络实时库 - m_rdbNetApi = new CRdbNetApi(); -} - -QString CSequenceDBInterface::queryLocationName(const int nLocationID) -{ - QMutexLocker locker(&mutex); - QString locationName = QString(); - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("description"); - - CONDINFO conditionName; - conditionName.logicalop = ATTRCOND_AND; - conditionName.relationop = ATTRCOND_EQU; - memcpy(conditionName.name, "location_id", strlen("location_id")); - conditionName.conditionval = (int32_t)nLocationID; - - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccessEx->select(conditionName, result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - locationName = QString::fromStdString(value.toStdString()); - break; - } - } - } - m_rtdbAccessEx->close(); - return locationName; -} - -QString CSequenceDBInterface::queryUserName(const int nUserID) -{ - QMutexLocker locker(&mutex); - QString userName; - std::string strApplicationName = "base"; - std::string strTableName = "rm_user_def"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("perm_alias"); - - CONDINFO conditionName; - conditionName.logicalop = ATTRCOND_AND; - conditionName.relationop = ATTRCOND_EQU; - memcpy(conditionName.name, "perm_id", strlen("perm_id")); - conditionName.conditionval = nUserID; - - if(m_rtdbAccessEx->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - userName = QString::fromStdString(value.toStdString()); - break; - } - } - } - m_rtdbAccessEx->close(); - return userName; -} - -QStringList CSequenceDBInterface::queryAllLocationName() -{ - QMutexLocker locker(&mutex); - QStringList locationNameList; - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("description"); - - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccessEx->select(result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - locationNameList.append(QString::fromStdString(value.toStdString())); - } - } - } - m_rtdbAccessEx->close(); - return locationNameList; -} - -QMap CSequenceDBInterface::queryUserIDMap() -{ - QMutexLocker locker(&mutex); - QMap userNameMap; - std::string strApplicationName = "base"; - std::string strTableName = "rm_user_def"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("perm_id"); - columns.push_back("perm_alias"); - - if(m_rtdbAccessEx->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType id; - CVarType name; - result.getColumnValue(nIndex, 0, id); - result.getColumnValue(nIndex, 1, name); - userNameMap.insert(id, QString::fromStdString(name.toStdString())); - } - } - } - m_rtdbAccessEx->close(); - return userNameMap; -} - -QString CSequenceDBInterface::queryTagName(const QString &strTableName, const QString &strTaginfo) -{ - if(strTaginfo.isEmpty()) - { - return QString(); - } - - QString strTagName; - if(!m_pReadDb->isOpen()) - { - return QString(); - } - QSqlQuery query; - QString sqlQuery = QString("select description from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - strTagName = query.value(0).toString(); - } - } - return strTagName; -} - -QString CSequenceDBInterface::queryTagTextName(const QString &strTableName, const QString &strTaginfo) -{ - if(strTaginfo.isEmpty()) - { - return QString(); - } - - QString strTagTextName; - if(!m_pReadDb->isOpen()) - { - return QString(); - } - QSqlQuery query; - QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - strTagTextName = query.value(0).toString(); - } - } - return strTagTextName; -} - -QString CSequenceDBInterface::queryStateName(const QString &strStateTextName, const int &nActualValue) -{ - QMutexLocker locker(&mutex); - QString strStateName; - std::string strApplicationName = "base"; - std::string strTableName = "dict_state_text_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - - std::vector vecCondInfo; - CONDINFO conditionName; - conditionName.logicalop = ATTRCOND_AND; - conditionName.relationop = ATTRCOND_EQU; - memcpy(conditionName.name, "state_text_name", strlen("state_text_name")); - conditionName.conditionval = strStateTextName.toStdString(); - vecCondInfo.push_back(conditionName); - - CONDINFO conditionState; - conditionState.logicalop = ATTRCOND_AND; - conditionState.relationop = ATTRCOND_EQU; - memcpy(conditionState.name, "actual_value", strlen("actual_value")); - conditionState.conditionval = nActualValue; - vecCondInfo.push_back(conditionState); - - - kbd_dbms::CRdbQueryResult result; - - std::vector columns; - columns.push_back("display_value"); - - if(m_rtdbAccessEx->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - strStateName = QString::fromStdString(value.toStdString()); - } - } - } - m_rtdbAccessEx->close(); - return strStateName; -} - -QList CSequenceDBInterface::queryRunSequenceNodeList() -{ - QList sequenceList; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - return sequenceList; - } - - kbd_public::SNodeInfo stNodeInfo; - spSysInfo->getLocalNodeInfo(stNodeInfo); - if(!m_pReadDb->isOpen()) - { - return sequenceList; - } - //<查询顺控 - QSqlQuery query; - QString sqlSequenceQuery = QString("select name, description, seq_type, location_id, timeflag from %1").arg(SEQUENCE_SETTING); - m_pReadDb->execute(sqlSequenceQuery, query); - if(query.isActive()) - { - while(query.next()) - { - QString seqName = query.value(0).toString(); - Sequence sequence; - sequence.seqName = seqName; - sequence.seqDescription = query.value(1).toString(); - sequence.seqType = query.value(2).toInt(); - sequence.locationID = query.value(3).toInt(); - sequence.location = queryLocationName(sequence.locationID); - sequence.timeFlag = query.value(4).toULongLong(); - sequence.nodeType = E_Node_Sequence; - sequenceList.append(sequence); - } - } - - return sequenceList; -} - -QList CSequenceDBInterface::queryHistorySequenceNodeList(const QDateTime &start, const QDateTime &end) -{ - QMap userMap = queryUserIDMap(); - - QList sequenceHistoryList; - if(!m_pReadDb->isOpen()) - { - return sequenceHistoryList; - } - QSqlQuery query; - QString sqlQuery = QString( "select " - "%1.seq_name, " - "%1.time, " - "%1.status, " - "%1.location_id, " - "%1.user_id, " - "%1.seq_type, " - "%2.description " - "from %1, %2 " - "where %1.seq_name = %2.name " - "and %1.time >= %3 and %1.time <= %4 " - "order by %1.time desc" ) - .arg(SEQUENCE_HISTORY).arg(SEQUENCE_SETTING) - .arg( start.toSecsSinceEpoch()).arg( end.toSecsSinceEpoch()); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - SequenceHistory info; - info.seqName = query.value(0).toString(); - info.time = query.value(1).toULongLong(); - info.status = query.value(2).toString(); - info.location = queryLocationName(query.value(3).toInt()); - info.userID = query.value(4).toString(); - info.userName = userMap.value(QString(info.userID).toInt()); - info.seqType = query.value(5).toInt(); - info.seqDescription = query.value(6).toString(); - sequenceHistoryList.append(info); - } - } - return sequenceHistoryList; -} - -QList CSequenceDBInterface::queryHistoryFunctionNodeList(const QString &sequenceName, const quint64 &sequenceTime) -{ - QList functionHistoryList; - if(!m_pReadDb->isOpen()) - { - return functionHistoryList; - } - QSqlQuery query; - QString sqlQuery = QString( "select DISTINCT " - "%1.seq_name, " - "%1.time, " - "%1.func_name, " - "%1.func_no, " - "%1.relation, " - "%1.status, " - "%1.location_id, " - "%2.description " - "from %1, %2 " - "where %1.func_name = %2.name " - "and %1.seq_name = '%3' and %1.time = %4 " - "order by %1.time asc" ) - .arg(SEQUENCE_FUNCTION_HISTORY).arg(SEQUENCE_FUNCTION) - .arg( sequenceName ).arg( sequenceTime ); - - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - FunctionHistory info; - info.seqName = query.value(0).toString(); - info.time = query.value(1).toULongLong(); - info.funcName = query.value(2).toString(); - info.funcNO = query.value(3).toInt(); - info.relation = query.value(4).toInt(); - info.status = query.value(5).toString(); - info.location = queryLocationName(query.value(6).toInt()); - info.funcDescription = query.value(7).toString(); - functionHistoryList.append(info); - } - } - return functionHistoryList; -} - -QList CSequenceDBInterface::queryHistoryActionNodeList(const QString &sequenceName, const QString &functionName, const quint64 &sequenceTime) -{ - QList actionHistoryList; - if(!m_pReadDb->isOpen()) - { - return actionHistoryList; - } - QSqlQuery query; - QString sqlQuery = QString("select DISTINCT \ - %1.seq_name, \ - %1.time, \ - %1.func_name, \ - %2.description, \ - %1.action_no, \ - %1.action_name, \ - %3.description, \ - %1.status, \ - %1.starttime, \ - %1.stoptime, \ - %1.key_id_tag, \ - %1.targetvalue, \ - %1.location_id, \ - %1.discribe \ - from %1, %2, %3 \ - where %1.seq_name = '%4' \ - and %1.func_name = '%5' \ - and %1.func_name = %2.name \ - and %1.action_name = %3.name \ - and %1.time = %6 \ - order by %1.starttime asc") - .arg(SEQUENCE_ACTION_HISTORY).arg(SEQUENCE_FUNCTION).arg(SEQUENCE_ACTION).arg(sequenceName).arg(functionName).arg(sequenceTime); - - m_pReadDb->execute(sqlQuery, query); - - if(query.isActive()) - { - while(query.next()) - { - ActionHistory info; - info.seqName = query.value(0).toString(); - info.time = query.value(1).toULongLong(); - info.funcName = query.value(2).toString(); - info.functionDescription = query.value(3).toString(); - info.actionNO = query.value(4).toInt(); - info.actionName = query.value(5).toString(); - info.actionDescription = query.value(6).toString(); - info.status = query.value(7).toString(); - info.startTime = query.value(8).toULongLong(); - info.stopTime = query.value(9).toULongLong(); - info.KeyIdTag = query.value(10).toString(); - info.targetValue = query.value(11).toInt(); - info.location = queryLocationName(query.value(12).toInt()); - info.description = query.value(13).toString(); - actionHistoryList.append(info); - } - } - return actionHistoryList; -} - - -void CSequenceDBInterface::slotSubScribeSequenceList(QList listSequence) -{ - QMutexLocker locker(&mutex); - if(m_timer != NULL) - { - m_timer->stop(); - } - delete m_timer; - - m_listSequence.append(listSequence); - m_timer = new QTimer(); - m_timer->setInterval(1000); - connect(m_timer, SIGNAL(timeout()), this, SLOT(updataSequenceExecuteState())); - m_timer->start(); -} - -void CSequenceDBInterface::slotUnSubScribeSequenceList() -{ - QMutexLocker locker(&mutex); - if(m_timer != NULL) - { - m_timer->stop(); - delete m_timer; - } - m_timer = NULL; - m_listSequence.clear(); -} - -void CSequenceDBInterface::updataSequenctState(QList &listSequence) -{ - //query state - QMutexLocker locker(&mutex); - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - kbd_public::SAppInfo appInfo; - spSysInfo->getAppInfoByName(COMAPP, appInfo); - for(int nIndex(0); nIndex < listSequence.size(); nIndex++) - { - if(E_Node_Sequence == listSequence.at(nIndex).nodeType) - { - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(listSequence.at(nIndex).locationID, stLocationInfo); - m_rdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); - - try - { - kbd_idlfile::RdbQuery query; - query.set_strtablename("sequence_running"); - std::string *pStatusColName = query.add_strselectcolnamearr(); - *pStatusColName = "status"; - - kbd_idlfile::RdbCondition *pSequenceNodeTypeCondtion = query.add_msgcondition(); - pSequenceNodeTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pSequenceNodeTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pSequenceNodeTypeCondtion->set_strcolumnname("node_type"); - - SVariable *pSeqNodeTypeCondValue = pSequenceNodeTypeCondtion->mutable_msgvalue(); - pSeqNodeTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); - pSeqNodeTypeCondValue->set_nvalue((int)E_Node_Sequence); - - kbd_idlfile::RdbCondition *pSequenceNameCondtion = query.add_msgcondition(); - pSequenceNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pSequenceNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pSequenceNameCondtion->set_strcolumnname("seq_name"); - - SVariable *pSeqNameCondValue = pSequenceNameCondtion->mutable_msgvalue(); - pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pSeqNameCondValue->set_strvalue(listSequence.at(nIndex).seqName.toStdString()); - - kbd_idlfile::RdbRet retMsg; - if (m_rdbNetApi->query(query, retMsg)) - { - if(retMsg.msgrecord_size() != 0) - { - - E_EXECUTING_STATE state = (E_EXECUTING_STATE)retMsg.msgrecord(0).msgvaluearray(0).nvalue(); - listSequence[nIndex].executeState = state; - } - } - } - catch(...) - { - LOGERROR("updataSequenctState [rdbNetApi query exception!]"); - } - } - } - } -} - -void CSequenceDBInterface::updataSequenceExecuteState() -{ - QMutexLocker locker(&mutex); - if(m_timer) - { - m_timer->stop(); - } - - while(m_rdbNetApi->checkStatus()) - { - kbd_idlfile::RdbRet retMsg; - if (m_rdbNetApi->getRet(&retMsg)) - { - if(retMsg.msgrecord_size() != 0) - { - QString seqName = QString::fromStdString(retMsg.msgrecord(0).msgvaluearray(0).strvalue()); - E_EXECUTING_STATE state = (E_EXECUTING_STATE)retMsg.msgrecord(0).msgvaluearray(1).nvalue(); - emit sigUpdateSequenceState(seqName, state); - } - } - } - - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - for(int nIndex(0); nIndex < m_listSequence.size(); nIndex++) - { - if(E_Node_Sequence == m_listSequence.at(nIndex).nodeType) - { - - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(m_listSequence.at(nIndex).locationID, stLocationInfo); - kbd_public::SAppInfo appInfo; - spSysInfo->getAppInfoByName(COMAPP, appInfo); - m_rdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); - - kbd_idlfile::RdbQuery query; - query.set_strtablename("sequence_running"); - - std::string *pSeqColName = query.add_strselectcolnamearr(); - *pSeqColName = "seq_name"; - - std::string *pStatusColName = query.add_strselectcolnamearr(); - *pStatusColName = "status"; - - kbd_idlfile::RdbCondition *pSequenceNodeTypeCondtion = query.add_msgcondition(); - pSequenceNodeTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pSequenceNodeTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pSequenceNodeTypeCondtion->set_strcolumnname("node_type"); - - SVariable *pSeqNodeTypeCondValue = pSequenceNodeTypeCondtion->mutable_msgvalue(); - pSeqNodeTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); - pSeqNodeTypeCondValue->set_nvalue((int)E_Node_Sequence); - - kbd_idlfile::RdbCondition *pSequenceNameCondtion = query.add_msgcondition(); - pSequenceNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pSequenceNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pSequenceNameCondtion->set_strcolumnname("seq_name"); - - SVariable *pSeqNameCondValue = pSequenceNameCondtion->mutable_msgvalue(); - pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pSeqNameCondValue->set_strvalue(m_listSequence.at(nIndex).seqName.toStdString()); - - kbd_idlfile::RdbRet retMsg; - m_rdbNetApi->query(query, retMsg, true); - } - } - } - if(m_timer) - { - m_timer->start(); - } -} - - +#include "CSequenceDBInterface.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "../../idl_files/SequenceMessage.pb.h" +#include "../../idl_files/RdbServerMessage.pb.h" + +using namespace kbd_dbms; +using namespace kbd_idlfile; + +CSequenceDBInterface::CSequenceDBInterface(CDbApi *dbRead) + : m_timer(NULL), + m_pReadDb(dbRead), m_rtdbAccessEx(nullptr), m_rdbNetApi(nullptr) +{ +} + +CSequenceDBInterface::~CSequenceDBInterface() +{ + slotUnSubScribeSequenceList(); + + m_pReadDb = NULL; + + if(NULL != m_rtdbAccessEx) + { + delete m_rtdbAccessEx; + } + m_rtdbAccessEx = NULL; + + if(NULL != m_rdbNetApi) + { + delete m_rdbNetApi; + } + m_rdbNetApi = NULL; +} + +void CSequenceDBInterface::initDataBase() +{ + //实时库 + m_rtdbAccessEx = new CRdbAccessEx(); + + //网络实时库 + m_rdbNetApi = new CRdbNetApi(); +} + +QString CSequenceDBInterface::queryLocationName(const int nLocationID) +{ + QMutexLocker locker(&mutex); + QString locationName = QString(); + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("description"); + + CONDINFO conditionName; + conditionName.logicalop = ATTRCOND_AND; + conditionName.relationop = ATTRCOND_EQU; + memcpy(conditionName.name, "location_id", strlen("location_id")); + conditionName.conditionval = (int32_t)nLocationID; + + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccessEx->select(conditionName, result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + locationName = QString::fromStdString(value.toStdString()); + break; + } + } + } + m_rtdbAccessEx->close(); + return locationName; +} + +QString CSequenceDBInterface::queryUserName(const int nUserID) +{ + QMutexLocker locker(&mutex); + QString userName; + std::string strApplicationName = "base"; + std::string strTableName = "rm_user_def"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_alias"); + + CONDINFO conditionName; + conditionName.logicalop = ATTRCOND_AND; + conditionName.relationop = ATTRCOND_EQU; + memcpy(conditionName.name, "perm_id", strlen("perm_id")); + conditionName.conditionval = nUserID; + + if(m_rtdbAccessEx->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + userName = QString::fromStdString(value.toStdString()); + break; + } + } + } + m_rtdbAccessEx->close(); + return userName; +} + +QStringList CSequenceDBInterface::queryAllLocationName() +{ + QMutexLocker locker(&mutex); + QStringList locationNameList; + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("description"); + + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccessEx->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + locationNameList.append(QString::fromStdString(value.toStdString())); + } + } + } + m_rtdbAccessEx->close(); + return locationNameList; +} + +QMap CSequenceDBInterface::queryUserIDMap() +{ + QMutexLocker locker(&mutex); + QMap userNameMap; + std::string strApplicationName = "base"; + std::string strTableName = "rm_user_def"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_id"); + columns.push_back("perm_alias"); + + if(m_rtdbAccessEx->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType id; + CVarType name; + result.getColumnValue(nIndex, 0, id); + result.getColumnValue(nIndex, 1, name); + userNameMap.insert(id, QString::fromStdString(name.toStdString())); + } + } + } + m_rtdbAccessEx->close(); + return userNameMap; +} + +QString CSequenceDBInterface::queryTagName(const QString &strTableName, const QString &strTaginfo) +{ + if(strTaginfo.isEmpty()) + { + return QString(); + } + + QString strTagName; + if(!m_pReadDb->isOpen()) + { + return QString(); + } + QSqlQuery query; + QString sqlQuery = QString("select description from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + strTagName = query.value(0).toString(); + } + } + return strTagName; +} + +QString CSequenceDBInterface::queryTagTextName(const QString &strTableName, const QString &strTaginfo) +{ + if(strTaginfo.isEmpty()) + { + return QString(); + } + + QString strTagTextName; + if(!m_pReadDb->isOpen()) + { + return QString(); + } + QSqlQuery query; + QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + strTagTextName = query.value(0).toString(); + } + } + return strTagTextName; +} + +QString CSequenceDBInterface::queryStateName(const QString &strStateTextName, const int &nActualValue) +{ + QMutexLocker locker(&mutex); + QString strStateName; + std::string strApplicationName = "base"; + std::string strTableName = "dict_state_text_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + + std::vector vecCondInfo; + CONDINFO conditionName; + conditionName.logicalop = ATTRCOND_AND; + conditionName.relationop = ATTRCOND_EQU; + memcpy(conditionName.name, "state_text_name", strlen("state_text_name")); + conditionName.conditionval = strStateTextName.toStdString(); + vecCondInfo.push_back(conditionName); + + CONDINFO conditionState; + conditionState.logicalop = ATTRCOND_AND; + conditionState.relationop = ATTRCOND_EQU; + memcpy(conditionState.name, "actual_value", strlen("actual_value")); + conditionState.conditionval = nActualValue; + vecCondInfo.push_back(conditionState); + + + kbd_dbms::CRdbQueryResult result; + + std::vector columns; + columns.push_back("display_value"); + + if(m_rtdbAccessEx->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + strStateName = QString::fromStdString(value.toStdString()); + } + } + } + m_rtdbAccessEx->close(); + return strStateName; +} + +QList CSequenceDBInterface::queryRunSequenceNodeList() +{ + QList sequenceList; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + return sequenceList; + } + + kbd_public::SNodeInfo stNodeInfo; + spSysInfo->getLocalNodeInfo(stNodeInfo); + if(!m_pReadDb->isOpen()) + { + return sequenceList; + } + //<查询顺控 + QSqlQuery query; + QString sqlSequenceQuery = QString("select name, description, seq_type, location_id, timeflag from %1").arg(SEQUENCE_SETTING); + m_pReadDb->execute(sqlSequenceQuery, query); + if(query.isActive()) + { + while(query.next()) + { + QString seqName = query.value(0).toString(); + Sequence sequence; + sequence.seqName = seqName; + sequence.seqDescription = query.value(1).toString(); + sequence.seqType = query.value(2).toInt(); + sequence.locationID = query.value(3).toInt(); + sequence.location = queryLocationName(sequence.locationID); + sequence.timeFlag = query.value(4).toULongLong(); + sequence.nodeType = E_Node_Sequence; + sequenceList.append(sequence); + } + } + + return sequenceList; +} + +QList CSequenceDBInterface::queryHistorySequenceNodeList(const QDateTime &start, const QDateTime &end) +{ + QMap userMap = queryUserIDMap(); + + QList sequenceHistoryList; + if(!m_pReadDb->isOpen()) + { + return sequenceHistoryList; + } + QSqlQuery query; + QString sqlQuery = QString( "select " + "%1.seq_name, " + "%1.time, " + "%1.status, " + "%1.location_id, " + "%1.user_id, " + "%1.seq_type, " + "%2.description " + "from %1, %2 " + "where %1.seq_name = %2.name " + "and %1.time >= %3 and %1.time <= %4 " + "order by %1.time desc" ) + .arg(SEQUENCE_HISTORY).arg(SEQUENCE_SETTING) + .arg( start.toSecsSinceEpoch()).arg( end.toSecsSinceEpoch()); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + SequenceHistory info; + info.seqName = query.value(0).toString(); + info.time = query.value(1).toULongLong(); + info.status = query.value(2).toString(); + info.location = queryLocationName(query.value(3).toInt()); + info.userID = query.value(4).toString(); + info.userName = userMap.value(QString(info.userID).toInt()); + info.seqType = query.value(5).toInt(); + info.seqDescription = query.value(6).toString(); + sequenceHistoryList.append(info); + } + } + return sequenceHistoryList; +} + +QList CSequenceDBInterface::queryHistoryFunctionNodeList(const QString &sequenceName, const quint64 &sequenceTime) +{ + QList functionHistoryList; + if(!m_pReadDb->isOpen()) + { + return functionHistoryList; + } + QSqlQuery query; + QString sqlQuery = QString( "select DISTINCT " + "%1.seq_name, " + "%1.time, " + "%1.func_name, " + "%1.func_no, " + "%1.relation, " + "%1.status, " + "%1.location_id, " + "%2.description " + "from %1, %2 " + "where %1.func_name = %2.name " + "and %1.seq_name = '%3' and %1.time = %4 " + "order by %1.time asc" ) + .arg(SEQUENCE_FUNCTION_HISTORY).arg(SEQUENCE_FUNCTION) + .arg( sequenceName ).arg( sequenceTime ); + + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + FunctionHistory info; + info.seqName = query.value(0).toString(); + info.time = query.value(1).toULongLong(); + info.funcName = query.value(2).toString(); + info.funcNO = query.value(3).toInt(); + info.relation = query.value(4).toInt(); + info.status = query.value(5).toString(); + info.location = queryLocationName(query.value(6).toInt()); + info.funcDescription = query.value(7).toString(); + functionHistoryList.append(info); + } + } + return functionHistoryList; +} + +QList CSequenceDBInterface::queryHistoryActionNodeList(const QString &sequenceName, const QString &functionName, const quint64 &sequenceTime) +{ + QList actionHistoryList; + if(!m_pReadDb->isOpen()) + { + return actionHistoryList; + } + QSqlQuery query; + QString sqlQuery = QString("select DISTINCT \ + %1.seq_name, \ + %1.time, \ + %1.func_name, \ + %2.description, \ + %1.action_no, \ + %1.action_name, \ + %3.description, \ + %1.status, \ + %1.starttime, \ + %1.stoptime, \ + %1.key_id_tag, \ + %1.targetvalue, \ + %1.location_id, \ + %1.discribe \ + from %1, %2, %3 \ + where %1.seq_name = '%4' \ + and %1.func_name = '%5' \ + and %1.func_name = %2.name \ + and %1.action_name = %3.name \ + and %1.time = %6 \ + order by %1.starttime asc") + .arg(SEQUENCE_ACTION_HISTORY).arg(SEQUENCE_FUNCTION).arg(SEQUENCE_ACTION).arg(sequenceName).arg(functionName).arg(sequenceTime); + + m_pReadDb->execute(sqlQuery, query); + + if(query.isActive()) + { + while(query.next()) + { + ActionHistory info; + info.seqName = query.value(0).toString(); + info.time = query.value(1).toULongLong(); + info.funcName = query.value(2).toString(); + info.functionDescription = query.value(3).toString(); + info.actionNO = query.value(4).toInt(); + info.actionName = query.value(5).toString(); + info.actionDescription = query.value(6).toString(); + info.status = query.value(7).toString(); + info.startTime = query.value(8).toULongLong(); + info.stopTime = query.value(9).toULongLong(); + info.KeyIdTag = query.value(10).toString(); + info.targetValue = query.value(11).toInt(); + info.location = queryLocationName(query.value(12).toInt()); + info.description = query.value(13).toString(); + actionHistoryList.append(info); + } + } + return actionHistoryList; +} + + +void CSequenceDBInterface::slotSubScribeSequenceList(QList listSequence) +{ + QMutexLocker locker(&mutex); + if(m_timer != NULL) + { + m_timer->stop(); + } + delete m_timer; + + m_listSequence.append(listSequence); + m_timer = new QTimer(); + m_timer->setInterval(1000); + connect(m_timer, SIGNAL(timeout()), this, SLOT(updataSequenceExecuteState())); + m_timer->start(); +} + +void CSequenceDBInterface::slotUnSubScribeSequenceList() +{ + QMutexLocker locker(&mutex); + if(m_timer != NULL) + { + m_timer->stop(); + delete m_timer; + } + m_timer = NULL; + m_listSequence.clear(); +} + +void CSequenceDBInterface::updataSequenctState(QList &listSequence) +{ + //query state + QMutexLocker locker(&mutex); + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + kbd_public::SAppInfo appInfo; + spSysInfo->getAppInfoByName(COMAPP, appInfo); + for(int nIndex(0); nIndex < listSequence.size(); nIndex++) + { + if(E_Node_Sequence == listSequence.at(nIndex).nodeType) + { + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(listSequence.at(nIndex).locationID, stLocationInfo); + m_rdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); + + try + { + kbd_idlfile::RdbQuery query; + query.set_strtablename("sequence_running"); + std::string *pStatusColName = query.add_strselectcolnamearr(); + *pStatusColName = "status"; + + kbd_idlfile::RdbCondition *pSequenceNodeTypeCondtion = query.add_msgcondition(); + pSequenceNodeTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pSequenceNodeTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pSequenceNodeTypeCondtion->set_strcolumnname("node_type"); + + SVariable *pSeqNodeTypeCondValue = pSequenceNodeTypeCondtion->mutable_msgvalue(); + pSeqNodeTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); + pSeqNodeTypeCondValue->set_nvalue((int)E_Node_Sequence); + + kbd_idlfile::RdbCondition *pSequenceNameCondtion = query.add_msgcondition(); + pSequenceNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pSequenceNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pSequenceNameCondtion->set_strcolumnname("seq_name"); + + SVariable *pSeqNameCondValue = pSequenceNameCondtion->mutable_msgvalue(); + pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pSeqNameCondValue->set_strvalue(listSequence.at(nIndex).seqName.toStdString()); + + kbd_idlfile::RdbRet retMsg; + if (m_rdbNetApi->query(query, retMsg)) + { + if(retMsg.msgrecord_size() != 0) + { + + E_EXECUTING_STATE state = (E_EXECUTING_STATE)retMsg.msgrecord(0).msgvaluearray(0).nvalue(); + listSequence[nIndex].executeState = state; + } + } + } + catch(...) + { + LOGERROR("updataSequenctState [rdbNetApi query exception!]"); + } + } + } + } +} + +void CSequenceDBInterface::updataSequenceExecuteState() +{ + QMutexLocker locker(&mutex); + if(m_timer) + { + m_timer->stop(); + } + + while(m_rdbNetApi->checkStatus()) + { + kbd_idlfile::RdbRet retMsg; + if (m_rdbNetApi->getRet(&retMsg)) + { + if(retMsg.msgrecord_size() != 0) + { + QString seqName = QString::fromStdString(retMsg.msgrecord(0).msgvaluearray(0).strvalue()); + E_EXECUTING_STATE state = (E_EXECUTING_STATE)retMsg.msgrecord(0).msgvaluearray(1).nvalue(); + emit sigUpdateSequenceState(seqName, state); + } + } + } + + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + for(int nIndex(0); nIndex < m_listSequence.size(); nIndex++) + { + if(E_Node_Sequence == m_listSequence.at(nIndex).nodeType) + { + + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(m_listSequence.at(nIndex).locationID, stLocationInfo); + kbd_public::SAppInfo appInfo; + spSysInfo->getAppInfoByName(COMAPP, appInfo); + m_rdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); + + kbd_idlfile::RdbQuery query; + query.set_strtablename("sequence_running"); + + std::string *pSeqColName = query.add_strselectcolnamearr(); + *pSeqColName = "seq_name"; + + std::string *pStatusColName = query.add_strselectcolnamearr(); + *pStatusColName = "status"; + + kbd_idlfile::RdbCondition *pSequenceNodeTypeCondtion = query.add_msgcondition(); + pSequenceNodeTypeCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pSequenceNodeTypeCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pSequenceNodeTypeCondtion->set_strcolumnname("node_type"); + + SVariable *pSeqNodeTypeCondValue = pSequenceNodeTypeCondtion->mutable_msgvalue(); + pSeqNodeTypeCondValue->set_edatatype(DataType::CN_DATATYPE_INT32); + pSeqNodeTypeCondValue->set_nvalue((int)E_Node_Sequence); + + kbd_idlfile::RdbCondition *pSequenceNameCondtion = query.add_msgcondition(); + pSequenceNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pSequenceNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pSequenceNameCondtion->set_strcolumnname("seq_name"); + + SVariable *pSeqNameCondValue = pSequenceNameCondtion->mutable_msgvalue(); + pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pSeqNameCondValue->set_strvalue(m_listSequence.at(nIndex).seqName.toStdString()); + + kbd_idlfile::RdbRet retMsg; + m_rdbNetApi->query(query, retMsg, true); + } + } + } + if(m_timer) + { + m_timer->start(); + } +} + + diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.h b/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.h index 689c4cb1..d389e708 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.h +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.h @@ -1,72 +1,72 @@ -#ifndef CSEQUENCEDBINTERFACE_H -#define CSEQUENCEDBINTERFACE_H - -#include "sequence_history_def.h" -#include "../SequenceWidget/sequence_def.h" -#include "dbms/db_api_ex/CDbApi.h" -#include "dbms/rdb_api/CRdbAccessEx.h" -#include "../dbms/rdb_net_api/CRdbNetApi.h" - -#define COMAPP ("comapp") -#define SEQUENCE_SETTING ("sequence_setting") -#define SEQUENCE_DEFINE ("sequence_define") -#define SEQUENCE_FUNCTION ("sequence_function") -#define SEQUENCE_ACTION ("sequence_action") -#define SEQUENCE_HISTORY ("sequence_history") -#define SEQUENCE_FUNCTION_HISTORY ("sequence_function_history") -#define SEQUENCE_ACTION_HISTORY ("sequence_action_event") - -class CSequenceDBInterface : public QObject -{ - Q_OBJECT -public: - CSequenceDBInterface(kbd_dbms::CDbApi *dbRead); - - ~CSequenceDBInterface(); - - void initDataBase(); - - QString queryLocationName(const int nLocationID); - - QString queryUserName(const int nUserID); - - QStringList queryAllLocationName(); - - QMap queryUserIDMap(); - - QString queryTagName(const QString &strTableName, const QString &strTaginfo); - - QString queryTagTextName(const QString &strTableName, const QString &strTaginfo); - - QString queryStateName(const QString &strStateTextName, const int &nActualValue); - - QList queryRunSequenceNodeList(); - - QList queryHistorySequenceNodeList(const QDateTime &start, const QDateTime &end); - - QList queryHistoryFunctionNodeList(const QString &sequenceName, const quint64 &sequenceTime); - - QList queryHistoryActionNodeList(const QString &sequenceName, const QString &functionName, const quint64 &sequenceTime); - - void slotSubScribeSequenceList(QList listSequence); - void slotUnSubScribeSequenceList(); - -signals: - void sigUpdateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); - -protected: - void updataSequenctState(QList &listSequence); - -protected slots: - void updataSequenceExecuteState(); - -private: - QMutex mutex; - QTimer * m_timer; - QList m_listSequence; - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccessEx * m_rtdbAccessEx; - kbd_dbms::CRdbNetApi * m_rdbNetApi; -}; - -#endif // CSEQUENCEDBINTERFACE_H +#ifndef CSEQUENCEDBINTERFACE_H +#define CSEQUENCEDBINTERFACE_H + +#include "sequence_history_def.h" +#include "../SequenceWidget/sequence_def.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "../dbms/rdb_net_api/CRdbNetApi.h" + +#define COMAPP ("comapp") +#define SEQUENCE_SETTING ("sequence_setting") +#define SEQUENCE_DEFINE ("sequence_define") +#define SEQUENCE_FUNCTION ("sequence_function") +#define SEQUENCE_ACTION ("sequence_action") +#define SEQUENCE_HISTORY ("sequence_history") +#define SEQUENCE_FUNCTION_HISTORY ("sequence_function_history") +#define SEQUENCE_ACTION_HISTORY ("sequence_action_event") + +class CSequenceDBInterface : public QObject +{ + Q_OBJECT +public: + CSequenceDBInterface(kbd_dbms::CDbApi *dbRead); + + ~CSequenceDBInterface(); + + void initDataBase(); + + QString queryLocationName(const int nLocationID); + + QString queryUserName(const int nUserID); + + QStringList queryAllLocationName(); + + QMap queryUserIDMap(); + + QString queryTagName(const QString &strTableName, const QString &strTaginfo); + + QString queryTagTextName(const QString &strTableName, const QString &strTaginfo); + + QString queryStateName(const QString &strStateTextName, const int &nActualValue); + + QList queryRunSequenceNodeList(); + + QList queryHistorySequenceNodeList(const QDateTime &start, const QDateTime &end); + + QList queryHistoryFunctionNodeList(const QString &sequenceName, const quint64 &sequenceTime); + + QList queryHistoryActionNodeList(const QString &sequenceName, const QString &functionName, const quint64 &sequenceTime); + + void slotSubScribeSequenceList(QList listSequence); + void slotUnSubScribeSequenceList(); + +signals: + void sigUpdateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); + +protected: + void updataSequenctState(QList &listSequence); + +protected slots: + void updataSequenceExecuteState(); + +private: + QMutex mutex; + QTimer * m_timer; + QList m_listSequence; + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccessEx * m_rtdbAccessEx; + kbd_dbms::CRdbNetApi * m_rdbNetApi; +}; + +#endif // CSEQUENCEDBINTERFACE_H diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.cpp b/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.cpp index e57e5bb8..aa5d8b9a 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CSequenceManagePluginWidget.h" -#include "CSequenceManageWidget.h" - -CSequenceManagePluginWidget::CSequenceManagePluginWidget(QObject *parent): QObject(parent) -{ - -} - -CSequenceManagePluginWidget::~CSequenceManagePluginWidget() -{ - -} - -bool CSequenceManagePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **sequenceWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CSequenceManageWidget *pWidget = new CSequenceManageWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *sequenceWidget = (IPluginWidget *)pWidget; - return true; -} - -void CSequenceManagePluginWidget::release() -{ - -} +#include +#include "CSequenceManagePluginWidget.h" +#include "CSequenceManageWidget.h" + +CSequenceManagePluginWidget::CSequenceManagePluginWidget(QObject *parent): QObject(parent) +{ + +} + +CSequenceManagePluginWidget::~CSequenceManagePluginWidget() +{ + +} + +bool CSequenceManagePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **sequenceWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CSequenceManageWidget *pWidget = new CSequenceManageWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *sequenceWidget = (IPluginWidget *)pWidget; + return true; +} + +void CSequenceManagePluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.h b/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.h index 43fbe1c5..3ada2956 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.h +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CSEQUENCEMANAGEPLUGINWIDGET_H -#define CSEQUENCEMANAGEPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CSequenceManagePluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CSequenceManagePluginWidget(QObject *parent = 0); - ~CSequenceManagePluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **sequenceWidget, QVector ptrVec); - void release(); -}; - -#endif //CSEQUENCEMANAGEPLUGINWIDGET_H - +#ifndef CSEQUENCEMANAGEPLUGINWIDGET_H +#define CSEQUENCEMANAGEPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CSequenceManagePluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CSequenceManagePluginWidget(QObject *parent = 0); + ~CSequenceManagePluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **sequenceWidget, QVector ptrVec); + void release(); +}; + +#endif //CSEQUENCEMANAGEPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.cpp b/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.cpp index 357a1388..dda46307 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.cpp @@ -1,466 +1,466 @@ -#include -#include -#include -#include -#include -#include "CSequenceManageWidget.h" -#include "ui_CSequenceManageWidget.h" -#include "CSequenceDBInterface.h" -#include "CRunningSequenceModel.h" -#include "CHistorySequenceModel.h" -#include "CHistoryActionModel.h" -#include "CRunSequenceFilterDialog.h" -#include "CHistorySequenceFilterDialog.h" -#include "CTableViewPrinter.h" -#include "tools/model_common/common.h" -#include "../SequenceWidget/CSequenceWidget.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_utility_api/FileStyle.h" -#include - -using namespace kbd_dbms; -CSequenceManageWidget::CSequenceManageWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CSequenceManageWidget), - m_seqDBInterface(NULL), - m_runningSequenceModel(NULL), - m_historySequenceModel(NULL), - m_historyActionModel(NULL), - m_pReadDb(NULL), - m_isGuard(true) -{ - setupUI(); - if(!editMode) - { - initialize(); - ui->listWidget->setCurrentRow(1); - } - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("sequence.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -CSequenceManageWidget::~CSequenceManageWidget() -{ - if(m_seqDBInterface) - { - m_seqDBInterface->slotUnSubScribeSequenceList(); - delete m_seqDBInterface; - } - m_seqDBInterface = NULL; - - if(m_runningSequenceModel) - { - delete m_runningSequenceModel; - } - m_runningSequenceModel = NULL; - - if(m_historySequenceModel) - { - delete m_historySequenceModel; - } - m_historySequenceModel = NULL; - - if(m_historyActionModel) - { - delete m_historyActionModel; - } - m_historyActionModel = NULL; - - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - delete ui; - qDebug() << "~CSequenceManageWidget()"; -} - -void CSequenceManageWidget::login() -{ - ui->listWidget->setCurrentRow(1); - ui->seqActionWidget->login(); -} - -void CSequenceManageWidget::logout() -{ - ui->seqActionWidget->logout(); -} - -void CSequenceManageWidget::setupUI() -{ - ui->setupUi(this); - - connect(ui->listWidget, &QListWidget::currentRowChanged, this, &CSequenceManageWidget::updateRunSequence); - - //<顺控配置界面 - QVector ptrVec; - QWidget *widget = Common::createPluginWidget(this, "model_sequence", ptrVec); - QHBoxLayout * configLayout = new QHBoxLayout(); - configLayout->setContentsMargins(9,0,0,0); - configLayout->addWidget(widget); - ui->seqConfig->setLayout(configLayout); - - //<顺控运行界面 - m_runningSequenceModel = new CRunningSequenceModel(this); - ui->seqTableView->setModel(m_runningSequenceModel); - ui->seqTableView->setColumnWidth(0, 300); - connect(ui->excute, &QPushButton::clicked, this, &CSequenceManageWidget::updateSequenceRunStatusFilter); - connect(ui->allSeq, &QPushButton::clicked, this, &CSequenceManageWidget::updateSequenceRunStatusFilter); - connect(ui->seqTableView, &QTableView::clicked, this, &CSequenceManageWidget::updateActionRunData); - connect(ui->filter, &QPushButton::clicked, this, &CSequenceManageWidget::filterRunSequence); - connect(ui->seqActionWidget, &CSequenceWidget::sigSequenceStateChanged, this, &CSequenceManageWidget::slotUpdateSequenceState); - ui->seqTableView->setColumnWidth(Running_Sequence_Column::nameColumn, 250); - ui->seqTableView->setColumnWidth(Running_Sequence_Column::locationColumn, 200); - ui->seqTableView->setColumnWidth(Running_Sequence_Column::typeColumn, 200); - - //<顺控报告界面 - m_historySequenceModel = new CHistorySequenceModel(this); - ui->historySequenceView->setModel(m_historySequenceModel); - ui->historySequenceView->setColumnWidth(History_Sequence_Column::timeColumn, 150); - ui->exportSequence->setVisible(false); - - m_historyActionModel = new CHistoryActionModel(this); - ui->historyActionView->setModel(m_historyActionModel); - connect(ui->historySequenceView, &QTableView::clicked, this, &CSequenceManageWidget::updateHistoryActionData); - ui->historyActionView->setColumnWidth(History_Action_Column::nameColumn, 180); - ui->historyActionView->setColumnWidth(History_Action_Column::descriptColumn, 250); - connect(ui->historyFilter, &QPushButton::clicked, this, &CSequenceManageWidget::filterHistorySequence); - connect(ui->printSequence, &QPushButton::clicked, this, &CSequenceManageWidget::print); -} - -void CSequenceManageWidget::initialize() -{ - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - - m_seqDBInterface = new CSequenceDBInterface(m_pReadDb); - m_seqDBInterface->initDataBase(); - - ui->seqActionWidget->setEditMode(false); - ui->seqActionWidget->initialize(E_Mode_Action, QStringList() << "", m_pReadDb); - ui->seqActionWidget->setGuard(m_isGuard); - ui->seqActionWidget->setTitleVisable(false); -} - -void CSequenceManageWidget::setGuard(bool guard) -{ - if(ui->seqActionWidget) - { - ui->seqActionWidget->setGuard(guard); - } - m_isGuard = guard; -} - -/*********************************Run UI CONFIG START*************************************/ -void CSequenceManageWidget::updateSequenceRunData() -{ - m_seqDBInterface->slotUnSubScribeSequenceList(); -// bool bIsExcute = ui->excute->isChecked(); - QList listSequence = m_seqDBInterface->queryRunSequenceNodeList(); -// m_seqDBInterface->updataSequenctState(listSequence); - //< Filter Execute State - QList::iterator it = listSequence.begin(); - while (it != listSequence.end()) - { -// if(bIsExcute) -// { -// if(it->executeState != E_Exec_Run && it->executeState != E_Exec_Pause) -// { -// it = listSequence.erase(it); -// continue; -// } -// } -// else -// { -// if(it->executeState == E_Exec_Run || it->executeState == E_Exec_Pause) -// { -// it = listSequence.erase(it); -// continue; -// } -// } - - if(m_runningCondition.locationFilter) - { - if(it->location != m_runningCondition.locationName) - { - it = listSequence.erase(it); - continue; - } - } - if(m_runningCondition.seqNameFilter) - { - if(!it->seqDescription.contains(m_runningCondition.seqName)) - { - it = listSequence.erase(it); - continue; - } - } - if(m_runningCondition.typeFilter) - { - if((m_runningCondition.isStandardType && 0 != it->seqType) || (!m_runningCondition.isStandardType && 1 != it->seqType)) - { - it = listSequence.erase(it); - continue; - } - } - it++; - } - m_runningSequenceModel->updateSequenceData(listSequence); - ui->seqTableView->selectRow(0); - updateActionRunData(); - connect(m_seqDBInterface, &CSequenceDBInterface::sigUpdateSequenceState, this, &CSequenceManageWidget::slotUpdateSequenceState); - m_seqDBInterface->slotSubScribeSequenceList(listSequence); -} - -void CSequenceManageWidget::updateActionRunData() -{ - QModelIndex index = ui->seqTableView->currentIndex(); - QString sequenceName = m_runningSequenceModel->sequenceName(index); -// 需要实时读取状态 -// if(ui->seqActionWidget->currentSequenceName().contains(sequenceName)) -// { -// return; -// } - ui->seqActionWidget->loadSequenceData(QStringList() << sequenceName); -} - -bool CSequenceManageWidget::getSeqCtrlPerm() -{ - //<权限处理 - kbd_service::CPermMngApiPtr permManage = kbd_service::getPermMngInstance("base"); - permManage->PermDllInit(); - - int nLevel; - int nLoginSec; - std::string instanceName; - int nUserId; - std::string strUsrName; - int m_nUserGrpId; - if(0 == permManage->CurUser(nUserId, m_nUserGrpId, nLevel, nLoginSec, instanceName)) - { - permManage->GetUserAliasByUserId(nUserId, strUsrName); - std::string tmp = FUNC_NOM_PSCADA_SEQ_CTRL; - if (PERM_PERMIT == permManage->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) - { - return true; - } - } - return false; -} - -void CSequenceManageWidget::updateRunSequence(int index) -{ - if(index == 1) - { - updateSequenceRunData(); - ui->stackedWidget->setCurrentIndex(index); - return ; - } - if(getSeqCtrlPerm() == true) - { - ui->stackedWidget->setCurrentIndex(index); - if(index == 0) - { - - } - else if(index == 2) - { - loadSequenceReport(); - } - }else{ - QMessageBox::information(this,tr("提示"),tr("无顺控操作权限!")); - ui->listWidget->setCurrentRow(1); - qDebug()<<"item:"<listWidget->currentRow(); - } - -} - -void CSequenceManageWidget::updateSequenceRunStatusFilter() -{ - QPushButton * btn = static_cast(sender()); - if(btn == ui->excute) - { - ui->excute->setChecked(true); - ui->allSeq->setChecked(false); - m_runningSequenceModel->runStatusFilter(true); - } - else if(btn == ui->allSeq) - { - ui->excute->setChecked(false); - ui->allSeq->setChecked(true); - m_runningSequenceModel->runStatusFilter(false); - } - if(m_runningSequenceModel->rowCount()) - { - ui->seqTableView->selectRow(0); - } - updateActionRunData(); -} - -void CSequenceManageWidget::filterRunSequence() -{ - QStringList locationList = m_seqDBInterface->queryAllLocationName(); - CRunSequenceFilterDialog seqFilterDlg(locationList, this); - seqFilterDlg.initialize(m_runningCondition); - if(QDialog::Accepted != seqFilterDlg.exec()) - { - return; - } - - m_runningCondition = seqFilterDlg.sequenceFilterCondition(); - updateSequenceRunData(); -} - -void CSequenceManageWidget::slotUpdateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state) -{ - m_runningSequenceModel->updateSequenceState(seqName, state); -} - -/*********************************Run UI CONFIG END*************************************/ - - - -/*********************************Report UI CONFIG BEGIN*************************************/ -void CSequenceManageWidget::loadSequenceReport() -{ - QDateTime end = QDateTime::currentDateTime(); - end.setTimeSpec(Qt::UTC); - QDateTime start = end.addDays(-30); - m_listHistroySequence = m_seqDBInterface->queryHistorySequenceNodeList(start, end); - QList::iterator it = m_listHistroySequence.begin(); - while (it != m_listHistroySequence.end()) - { - if(m_historyCondition.locationFilter) - { - if(!m_historyCondition.locationList.contains(it->location)) - { - it = m_listHistroySequence.erase(it); - continue; - } - } - if(m_historyCondition.userFilter) - { - if(!m_historyCondition.userList.contains(it->userName)) - { - it = m_listHistroySequence.erase(it); - continue; - } - } - if(m_historyCondition.resultFilter) - { - if(!m_historyCondition.resultList.contains(it->status)) - { - it = m_listHistroySequence.erase(it); - continue; - } - } - if(m_historyCondition.typeFilter) - { - if((m_historyCondition.isStandardType && 0 != it->seqType) || (!m_historyCondition.isStandardType && 1 != it->seqType)) - { - it = m_listHistroySequence.erase(it); - continue; - } - } - - if(m_historyCondition.timeFilter) - { - QDateTime time = QDateTime::fromSecsSinceEpoch(it->time); - if(m_historyCondition.startTime > time || m_historyCondition.endTime < time) - { - it = m_listHistroySequence.erase(it); - continue; - } - } - it++; - } - m_historySequenceModel->setHistorySequenceData(m_listHistroySequence); - if(!m_listHistroySequence.isEmpty()) - { - ui->historySequenceView->selectRow(0); - updateHistoryActionData(); - } - else - { - QList listFunctionHistory; - m_historyActionModel->updateModelFunctionData(listFunctionHistory); - } -} - -void CSequenceManageWidget::updateHistoryActionData() -{ - QModelIndex modelIndex = ui->historySequenceView->currentIndex(); - - QString currentSquenceName = m_historySequenceModel->sequenceName(modelIndex); - quint64 currentSquenceTime = m_historySequenceModel->sequenceTime(modelIndex); - QList listFunctionHistory = m_seqDBInterface->queryHistoryFunctionNodeList(currentSquenceName, currentSquenceTime); - QList listActionHistory; - foreach (FunctionHistory funcHistory, listFunctionHistory) - { - listActionHistory.append(m_seqDBInterface->queryHistoryActionNodeList(funcHistory.seqName, funcHistory.funcName, funcHistory.time)); - } - m_historyActionModel->updateModelFunctionData(listFunctionHistory); - m_historyActionModel->updateModelActionData(listActionHistory); - ui->historyActionView->expandAll(); -} - -void CSequenceManageWidget::filterHistorySequence() -{ - QStringList locationList = m_seqDBInterface->queryAllLocationName(); - QStringList userNameList = m_seqDBInterface->queryUserIDMap().values(); - CHistorySequenceFilterDialog seqFilterDlg(locationList, userNameList, this); - seqFilterDlg.initialize(m_historyCondition); - if(QDialog::Accepted != seqFilterDlg.exec()) - { - return; - } - - m_historyCondition = seqFilterDlg.sequenceFilterCondition(); - loadSequenceReport(); -} - -void CSequenceManageWidget::print() -{ - QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); - if(!fileName.isEmpty()) - { - QTableView view(ui->historySequenceView); - view.setModel(ui->historySequenceView->model()); - view.horizontalHeader()->resizeSection(2, 250); - - QPrinter printer; - printer.setPageSize(QPagedPaintDevice::A4); - printer.setPageOrientation(QPageLayout::Landscape); - - printer.setOutputFileName(fileName); - printer.setOutputFormat(QPrinter::PdfFormat); - - CTableViewPrinter viewPrinter(&view); - viewPrinter.print(&printer); - } -} - -/*********************************Report UI CONFIG END*************************************/ +#include +#include +#include +#include +#include +#include "CSequenceManageWidget.h" +#include "ui_CSequenceManageWidget.h" +#include "CSequenceDBInterface.h" +#include "CRunningSequenceModel.h" +#include "CHistorySequenceModel.h" +#include "CHistoryActionModel.h" +#include "CRunSequenceFilterDialog.h" +#include "CHistorySequenceFilterDialog.h" +#include "CTableViewPrinter.h" +#include "tools/model_common/common.h" +#include "../SequenceWidget/CSequenceWidget.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_utility_api/FileStyle.h" +#include + +using namespace kbd_dbms; +CSequenceManageWidget::CSequenceManageWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CSequenceManageWidget), + m_seqDBInterface(NULL), + m_runningSequenceModel(NULL), + m_historySequenceModel(NULL), + m_historyActionModel(NULL), + m_pReadDb(NULL), + m_isGuard(true) +{ + setupUI(); + if(!editMode) + { + initialize(); + ui->listWidget->setCurrentRow(1); + } + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("sequence.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +CSequenceManageWidget::~CSequenceManageWidget() +{ + if(m_seqDBInterface) + { + m_seqDBInterface->slotUnSubScribeSequenceList(); + delete m_seqDBInterface; + } + m_seqDBInterface = NULL; + + if(m_runningSequenceModel) + { + delete m_runningSequenceModel; + } + m_runningSequenceModel = NULL; + + if(m_historySequenceModel) + { + delete m_historySequenceModel; + } + m_historySequenceModel = NULL; + + if(m_historyActionModel) + { + delete m_historyActionModel; + } + m_historyActionModel = NULL; + + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + delete ui; + qDebug() << "~CSequenceManageWidget()"; +} + +void CSequenceManageWidget::login() +{ + ui->listWidget->setCurrentRow(1); + ui->seqActionWidget->login(); +} + +void CSequenceManageWidget::logout() +{ + ui->seqActionWidget->logout(); +} + +void CSequenceManageWidget::setupUI() +{ + ui->setupUi(this); + + connect(ui->listWidget, &QListWidget::currentRowChanged, this, &CSequenceManageWidget::updateRunSequence); + + //<顺控配置界面 + QVector ptrVec; + QWidget *widget = Common::createPluginWidget(this, "model_sequence", ptrVec); + QHBoxLayout * configLayout = new QHBoxLayout(); + configLayout->setContentsMargins(9,0,0,0); + configLayout->addWidget(widget); + ui->seqConfig->setLayout(configLayout); + + //<顺控运行界面 + m_runningSequenceModel = new CRunningSequenceModel(this); + ui->seqTableView->setModel(m_runningSequenceModel); + ui->seqTableView->setColumnWidth(0, 300); + connect(ui->excute, &QPushButton::clicked, this, &CSequenceManageWidget::updateSequenceRunStatusFilter); + connect(ui->allSeq, &QPushButton::clicked, this, &CSequenceManageWidget::updateSequenceRunStatusFilter); + connect(ui->seqTableView, &QTableView::clicked, this, &CSequenceManageWidget::updateActionRunData); + connect(ui->filter, &QPushButton::clicked, this, &CSequenceManageWidget::filterRunSequence); + connect(ui->seqActionWidget, &CSequenceWidget::sigSequenceStateChanged, this, &CSequenceManageWidget::slotUpdateSequenceState); + ui->seqTableView->setColumnWidth(Running_Sequence_Column::nameColumn, 250); + ui->seqTableView->setColumnWidth(Running_Sequence_Column::locationColumn, 200); + ui->seqTableView->setColumnWidth(Running_Sequence_Column::typeColumn, 200); + + //<顺控报告界面 + m_historySequenceModel = new CHistorySequenceModel(this); + ui->historySequenceView->setModel(m_historySequenceModel); + ui->historySequenceView->setColumnWidth(History_Sequence_Column::timeColumn, 150); + ui->exportSequence->setVisible(false); + + m_historyActionModel = new CHistoryActionModel(this); + ui->historyActionView->setModel(m_historyActionModel); + connect(ui->historySequenceView, &QTableView::clicked, this, &CSequenceManageWidget::updateHistoryActionData); + ui->historyActionView->setColumnWidth(History_Action_Column::nameColumn, 180); + ui->historyActionView->setColumnWidth(History_Action_Column::descriptColumn, 250); + connect(ui->historyFilter, &QPushButton::clicked, this, &CSequenceManageWidget::filterHistorySequence); + connect(ui->printSequence, &QPushButton::clicked, this, &CSequenceManageWidget::print); +} + +void CSequenceManageWidget::initialize() +{ + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + m_seqDBInterface = new CSequenceDBInterface(m_pReadDb); + m_seqDBInterface->initDataBase(); + + ui->seqActionWidget->setEditMode(false); + ui->seqActionWidget->initialize(E_Mode_Action, QStringList() << "", m_pReadDb); + ui->seqActionWidget->setGuard(m_isGuard); + ui->seqActionWidget->setTitleVisable(false); +} + +void CSequenceManageWidget::setGuard(bool guard) +{ + if(ui->seqActionWidget) + { + ui->seqActionWidget->setGuard(guard); + } + m_isGuard = guard; +} + +/*********************************Run UI CONFIG START*************************************/ +void CSequenceManageWidget::updateSequenceRunData() +{ + m_seqDBInterface->slotUnSubScribeSequenceList(); +// bool bIsExcute = ui->excute->isChecked(); + QList listSequence = m_seqDBInterface->queryRunSequenceNodeList(); +// m_seqDBInterface->updataSequenctState(listSequence); + //< Filter Execute State + QList::iterator it = listSequence.begin(); + while (it != listSequence.end()) + { +// if(bIsExcute) +// { +// if(it->executeState != E_Exec_Run && it->executeState != E_Exec_Pause) +// { +// it = listSequence.erase(it); +// continue; +// } +// } +// else +// { +// if(it->executeState == E_Exec_Run || it->executeState == E_Exec_Pause) +// { +// it = listSequence.erase(it); +// continue; +// } +// } + + if(m_runningCondition.locationFilter) + { + if(it->location != m_runningCondition.locationName) + { + it = listSequence.erase(it); + continue; + } + } + if(m_runningCondition.seqNameFilter) + { + if(!it->seqDescription.contains(m_runningCondition.seqName)) + { + it = listSequence.erase(it); + continue; + } + } + if(m_runningCondition.typeFilter) + { + if((m_runningCondition.isStandardType && 0 != it->seqType) || (!m_runningCondition.isStandardType && 1 != it->seqType)) + { + it = listSequence.erase(it); + continue; + } + } + it++; + } + m_runningSequenceModel->updateSequenceData(listSequence); + ui->seqTableView->selectRow(0); + updateActionRunData(); + connect(m_seqDBInterface, &CSequenceDBInterface::sigUpdateSequenceState, this, &CSequenceManageWidget::slotUpdateSequenceState); + m_seqDBInterface->slotSubScribeSequenceList(listSequence); +} + +void CSequenceManageWidget::updateActionRunData() +{ + QModelIndex index = ui->seqTableView->currentIndex(); + QString sequenceName = m_runningSequenceModel->sequenceName(index); +// 需要实时读取状态 +// if(ui->seqActionWidget->currentSequenceName().contains(sequenceName)) +// { +// return; +// } + ui->seqActionWidget->loadSequenceData(QStringList() << sequenceName); +} + +bool CSequenceManageWidget::getSeqCtrlPerm() +{ + //<权限处理 + kbd_service::CPermMngApiPtr permManage = kbd_service::getPermMngInstance("base"); + permManage->PermDllInit(); + + int nLevel; + int nLoginSec; + std::string instanceName; + int nUserId; + std::string strUsrName; + int m_nUserGrpId; + if(0 == permManage->CurUser(nUserId, m_nUserGrpId, nLevel, nLoginSec, instanceName)) + { + permManage->GetUserAliasByUserId(nUserId, strUsrName); + std::string tmp = FUNC_NOM_PSCADA_SEQ_CTRL; + if (PERM_PERMIT == permManage->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) + { + return true; + } + } + return false; +} + +void CSequenceManageWidget::updateRunSequence(int index) +{ + if(index == 1) + { + updateSequenceRunData(); + ui->stackedWidget->setCurrentIndex(index); + return ; + } + if(getSeqCtrlPerm() == true) + { + ui->stackedWidget->setCurrentIndex(index); + if(index == 0) + { + + } + else if(index == 2) + { + loadSequenceReport(); + } + }else{ + QMessageBox::information(this,tr("提示"),tr("无顺控操作权限!")); + ui->listWidget->setCurrentRow(1); + qDebug()<<"item:"<listWidget->currentRow(); + } + +} + +void CSequenceManageWidget::updateSequenceRunStatusFilter() +{ + QPushButton * btn = static_cast(sender()); + if(btn == ui->excute) + { + ui->excute->setChecked(true); + ui->allSeq->setChecked(false); + m_runningSequenceModel->runStatusFilter(true); + } + else if(btn == ui->allSeq) + { + ui->excute->setChecked(false); + ui->allSeq->setChecked(true); + m_runningSequenceModel->runStatusFilter(false); + } + if(m_runningSequenceModel->rowCount()) + { + ui->seqTableView->selectRow(0); + } + updateActionRunData(); +} + +void CSequenceManageWidget::filterRunSequence() +{ + QStringList locationList = m_seqDBInterface->queryAllLocationName(); + CRunSequenceFilterDialog seqFilterDlg(locationList, this); + seqFilterDlg.initialize(m_runningCondition); + if(QDialog::Accepted != seqFilterDlg.exec()) + { + return; + } + + m_runningCondition = seqFilterDlg.sequenceFilterCondition(); + updateSequenceRunData(); +} + +void CSequenceManageWidget::slotUpdateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state) +{ + m_runningSequenceModel->updateSequenceState(seqName, state); +} + +/*********************************Run UI CONFIG END*************************************/ + + + +/*********************************Report UI CONFIG BEGIN*************************************/ +void CSequenceManageWidget::loadSequenceReport() +{ + QDateTime end = QDateTime::currentDateTime(); + end.setTimeSpec(Qt::UTC); + QDateTime start = end.addDays(-30); + m_listHistroySequence = m_seqDBInterface->queryHistorySequenceNodeList(start, end); + QList::iterator it = m_listHistroySequence.begin(); + while (it != m_listHistroySequence.end()) + { + if(m_historyCondition.locationFilter) + { + if(!m_historyCondition.locationList.contains(it->location)) + { + it = m_listHistroySequence.erase(it); + continue; + } + } + if(m_historyCondition.userFilter) + { + if(!m_historyCondition.userList.contains(it->userName)) + { + it = m_listHistroySequence.erase(it); + continue; + } + } + if(m_historyCondition.resultFilter) + { + if(!m_historyCondition.resultList.contains(it->status)) + { + it = m_listHistroySequence.erase(it); + continue; + } + } + if(m_historyCondition.typeFilter) + { + if((m_historyCondition.isStandardType && 0 != it->seqType) || (!m_historyCondition.isStandardType && 1 != it->seqType)) + { + it = m_listHistroySequence.erase(it); + continue; + } + } + + if(m_historyCondition.timeFilter) + { + QDateTime time = QDateTime::fromSecsSinceEpoch(it->time); + if(m_historyCondition.startTime > time || m_historyCondition.endTime < time) + { + it = m_listHistroySequence.erase(it); + continue; + } + } + it++; + } + m_historySequenceModel->setHistorySequenceData(m_listHistroySequence); + if(!m_listHistroySequence.isEmpty()) + { + ui->historySequenceView->selectRow(0); + updateHistoryActionData(); + } + else + { + QList listFunctionHistory; + m_historyActionModel->updateModelFunctionData(listFunctionHistory); + } +} + +void CSequenceManageWidget::updateHistoryActionData() +{ + QModelIndex modelIndex = ui->historySequenceView->currentIndex(); + + QString currentSquenceName = m_historySequenceModel->sequenceName(modelIndex); + quint64 currentSquenceTime = m_historySequenceModel->sequenceTime(modelIndex); + QList listFunctionHistory = m_seqDBInterface->queryHistoryFunctionNodeList(currentSquenceName, currentSquenceTime); + QList listActionHistory; + foreach (FunctionHistory funcHistory, listFunctionHistory) + { + listActionHistory.append(m_seqDBInterface->queryHistoryActionNodeList(funcHistory.seqName, funcHistory.funcName, funcHistory.time)); + } + m_historyActionModel->updateModelFunctionData(listFunctionHistory); + m_historyActionModel->updateModelActionData(listActionHistory); + ui->historyActionView->expandAll(); +} + +void CSequenceManageWidget::filterHistorySequence() +{ + QStringList locationList = m_seqDBInterface->queryAllLocationName(); + QStringList userNameList = m_seqDBInterface->queryUserIDMap().values(); + CHistorySequenceFilterDialog seqFilterDlg(locationList, userNameList, this); + seqFilterDlg.initialize(m_historyCondition); + if(QDialog::Accepted != seqFilterDlg.exec()) + { + return; + } + + m_historyCondition = seqFilterDlg.sequenceFilterCondition(); + loadSequenceReport(); +} + +void CSequenceManageWidget::print() +{ + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); + if(!fileName.isEmpty()) + { + QTableView view(ui->historySequenceView); + view.setModel(ui->historySequenceView->model()); + view.horizontalHeader()->resizeSection(2, 250); + + QPrinter printer; + printer.setPageSize(QPagedPaintDevice::A4); + printer.setPageOrientation(QPageLayout::Landscape); + + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + + CTableViewPrinter viewPrinter(&view); + viewPrinter.print(&printer); + } +} + +/*********************************Report UI CONFIG END*************************************/ diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.h b/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.h index 97fea62d..87c4498d 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.h +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.h @@ -1,68 +1,68 @@ -#ifndef CSEQUENCEMANAGEWIDGET_H -#define CSEQUENCEMANAGEWIDGET_H - -#include "CRunSequenceFilterDialog.h" -#include "CHistorySequenceFilterDialog.h" -#include "../SequenceWidget/sequence_def.h" -#include "db_api_ex/CDbApi.h" - -//< 顺控执行权限定义 -#define FUNC_NOM_PSCADA_SEQ_CTRL ("FUNC_NOM_PSCADA_SEQ_CTRL") - -namespace Ui { -class CSequenceManageWidget; -} - -struct SequenceHistory; -class CSequenceDBInterface; -class CRunningSequenceModel; -class CHistorySequenceModel; -class CHistoryActionModel; - -class CSequenceManageWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CSequenceManageWidget(QWidget *parent = 0, bool editMode = true); - ~CSequenceManageWidget(); - -public slots: - void login(); - - void logout(); - - void initialize(); - - void setGuard(bool guard = true); - -private: - void setupUI(); - void updateSequenceRunData(); - void loadSequenceReport(); - void updateHistoryActionData(); - void updateActionRunData(); - bool getSeqCtrlPerm(); -private slots: - void updateRunSequence(int index); - void updateSequenceRunStatusFilter(); - void filterRunSequence(); - void filterHistorySequence(); - void slotUpdateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); - void print(); - -private: - Ui::CSequenceManageWidget *ui; - CSequenceDBInterface * m_seqDBInterface; - CRunningSequenceModel * m_runningSequenceModel; - Run_Filter_Condition m_runningCondition; - - CHistorySequenceModel * m_historySequenceModel; - CHistoryActionModel * m_historyActionModel; - kbd_dbms::CDbApi * m_pReadDb; - QList m_listHistroySequence; - History_Filter_Condition m_historyCondition; - bool m_isGuard; -}; - -#endif // CSEQUENCEMANAGEWIDGET_H +#ifndef CSEQUENCEMANAGEWIDGET_H +#define CSEQUENCEMANAGEWIDGET_H + +#include "CRunSequenceFilterDialog.h" +#include "CHistorySequenceFilterDialog.h" +#include "../SequenceWidget/sequence_def.h" +#include "db_api_ex/CDbApi.h" + +//< 顺控执行权限定义 +#define FUNC_NOM_PSCADA_SEQ_CTRL ("FUNC_NOM_PSCADA_SEQ_CTRL") + +namespace Ui { +class CSequenceManageWidget; +} + +struct SequenceHistory; +class CSequenceDBInterface; +class CRunningSequenceModel; +class CHistorySequenceModel; +class CHistoryActionModel; + +class CSequenceManageWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CSequenceManageWidget(QWidget *parent = 0, bool editMode = true); + ~CSequenceManageWidget(); + +public slots: + void login(); + + void logout(); + + void initialize(); + + void setGuard(bool guard = true); + +private: + void setupUI(); + void updateSequenceRunData(); + void loadSequenceReport(); + void updateHistoryActionData(); + void updateActionRunData(); + bool getSeqCtrlPerm(); +private slots: + void updateRunSequence(int index); + void updateSequenceRunStatusFilter(); + void filterRunSequence(); + void filterHistorySequence(); + void slotUpdateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); + void print(); + +private: + Ui::CSequenceManageWidget *ui; + CSequenceDBInterface * m_seqDBInterface; + CRunningSequenceModel * m_runningSequenceModel; + Run_Filter_Condition m_runningCondition; + + CHistorySequenceModel * m_historySequenceModel; + CHistoryActionModel * m_historyActionModel; + kbd_dbms::CDbApi * m_pReadDb; + QList m_listHistroySequence; + History_Filter_Condition m_historyCondition; + bool m_isGuard; +}; + +#endif // CSEQUENCEMANAGEWIDGET_H diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.ui b/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.ui index 4b89eeed..98a303d4 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.ui +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceManageWidget.ui @@ -1,421 +1,421 @@ - - - CSequenceManageWidget - - - - 0 - 0 - 1368 - 628 - - - - CSequenceManageWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 9 - - - 9 - - - 9 - - - 9 - - - 0 - - - - - QListWidget{ - outline:0px; -} -QListView::item{ - height: 40px; -} - - - 0 - - - - 顺控配置 - - - - 10 - - - - AlignCenter - - - - - 顺控执行 - - - - 10 - - - - AlignCenter - - - - - 顺控报告 - - - - 10 - - - - AlignCenter - - - - - - - - QFrame::NoFrame - - - 2 - - - - - - 0 - - - 0 - - - 0 - - - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - - - 所有顺控 - - - true - - - true - - - false - - - - - - - true - - - 正在执行 - - - true - - - false - - - - - - - Qt::Vertical - - - - 20 - 101 - - - - - - - - 过滤 - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - 9 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 6 - - - 3 - - - 6 - - - 6 - - - 3 - - - - - 历史列表 - - - - - - - Qt::Horizontal - - - - 639 - 20 - - - - - - - - 过滤 - - - - - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 6 - - - 3 - - - 6 - - - 6 - - - 3 - - - - - 执行详情 - - - - - - - Qt::Horizontal - - - - 720 - 20 - - - - - - - - - - Qt::Horizontal - - - - 258 - 20 - - - - - - - - 导出 - - - - - - - 打印 - - - - - - - - - - - - - - - - - - - - - - - - CSequenceWidget - QWidget -
../SequenceWidget/CSequenceWidget.h
- 1 -
-
- - -
+ + + CSequenceManageWidget + + + + 0 + 0 + 1368 + 628 + + + + CSequenceManageWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 9 + + + 9 + + + 9 + + + 9 + + + 0 + + + + + QListWidget{ + outline:0px; +} +QListView::item{ + height: 40px; +} + + + 0 + + + + 顺控配置 + + + + 10 + + + + AlignCenter + + + + + 顺控执行 + + + + 10 + + + + AlignCenter + + + + + 顺控报告 + + + + 10 + + + + AlignCenter + + + + + + + + QFrame::NoFrame + + + 2 + + + + + + 0 + + + 0 + + + 0 + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + 所有顺控 + + + true + + + true + + + false + + + + + + + true + + + 正在执行 + + + true + + + false + + + + + + + Qt::Vertical + + + + 20 + 101 + + + + + + + + 过滤 + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + 9 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 6 + + + 3 + + + 6 + + + 6 + + + 3 + + + + + 历史列表 + + + + + + + Qt::Horizontal + + + + 639 + 20 + + + + + + + + 过滤 + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 6 + + + 3 + + + 6 + + + 6 + + + 3 + + + + + 执行详情 + + + + + + + Qt::Horizontal + + + + 720 + 20 + + + + + + + + + + Qt::Horizontal + + + + 258 + 20 + + + + + + + + 导出 + + + + + + + 打印 + + + + + + + + + + + + + + + + + + + + + + + + CSequenceWidget + QWidget +
../SequenceWidget/CSequenceWidget.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/SequenceManageWidget/CTableViewPrinter.cpp b/product/src/gui/plugin/SequenceManageWidget/CTableViewPrinter.cpp index e8d0b703..afbf955c 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CTableViewPrinter.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CTableViewPrinter.cpp @@ -1,122 +1,122 @@ -#include "CTableViewPrinter.h" -#include -#include -#include -#include -#include - -CTableViewPrinter::CTableViewPrinter(QTableView *view) - : m_pView(view) -{ - m_pModel = view->model(); -} - -void CTableViewPrinter::print(QPrinter * printer) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - - qreal marginHorizontal = 20; - qreal marginVertical = 20; - - QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); - printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); - - int length = 0; - horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); - for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) - { - length += horizontalHeader->sectionSize(nSection); - } - horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); - - QPainter painter(printer); - - renderHeader(painter); - - int offset = 0; - int currentPage = 0; - int horizontalHeaderHeight = horizontalHeader->height(); - for(int row(0); row < m_pModel->rowCount(); row++) - { - if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) - { - horizontalHeaderHeight = 0; - } - - - if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) - { - printer->newPage(); - currentPage++; - offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - } - - for(int column(0); column < m_pModel->columnCount(); column++) - { - int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - int rowHeight = m_pView->rowHeight(row); - int columnWidth = m_pView->columnWidth(column); - - //< draw item - QStyleOptionViewItem opt; - opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); - painter.save(); - painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); - painter.restore(); - - //< Vertical Line - if(column == 0) - { - QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); - QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); - drawGridLine(&painter, top, bottom); - } - //< Horizontal Line - int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; - QPoint left(verticalHeader->width(), rowPosition); - QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); - drawGridLine(&painter, left, right); - - } -} - -void CTableViewPrinter::renderHeader(QPainter &painter) -{ - QHeaderView * horizontalHeader = m_pView->horizontalHeader(); - QHeaderView * verticalHeader = m_pView->verticalHeader(); - for(int column(0); column < horizontalHeader->count(); column++) - { - painter.save(); - int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); - painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); - painter.restore(); - } - int columnPosition = horizontalHeader->width() + verticalHeader->width(); - QPoint top(columnPosition, 0); - QPoint bottom(columnPosition, horizontalHeader->height()); - drawGridLine(&painter, top, bottom); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); - drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); -} - -void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) -{ - painter->save(); - QStyleOptionViewItem opt; - const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); - const QColor gridColor = static_cast(gridHint); - painter->setPen(gridColor); - painter->drawLine(p1, p2); - painter->restore(); -} +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include + +CTableViewPrinter::CTableViewPrinter(QTableView *view) + : m_pView(view) +{ + m_pModel = view->model(); +} + +void CTableViewPrinter::print(QPrinter * printer) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); + printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + + int length = 0; + horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); + for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) + { + length += horizontalHeader->sectionSize(nSection); + } + horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); + + QPainter painter(printer); + + renderHeader(painter); + + int offset = 0; + int currentPage = 0; + int horizontalHeaderHeight = horizontalHeader->height(); + for(int row(0); row < m_pModel->rowCount(); row++) + { + if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) + { + horizontalHeaderHeight = 0; + } + + + if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) + { + printer->newPage(); + currentPage++; + offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + } + + for(int column(0); column < m_pModel->columnCount(); column++) + { + int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + int rowHeight = m_pView->rowHeight(row); + int columnWidth = m_pView->columnWidth(column); + + //< draw item + QStyleOptionViewItem opt; + opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); + painter.save(); + painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); + painter.restore(); + + //< Vertical Line + if(column == 0) + { + QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + //< Horizontal Line + int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; + QPoint left(verticalHeader->width(), rowPosition); + QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); + drawGridLine(&painter, left, right); + + } +} + +void CTableViewPrinter::renderHeader(QPainter &painter) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + for(int column(0); column < horizontalHeader->count(); column++) + { + painter.save(); + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); + painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); + painter.restore(); + } + int columnPosition = horizontalHeader->width() + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); +} + +void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + QStyleOptionViewItem opt; + const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); + const QColor gridColor = static_cast(gridHint); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} diff --git a/product/src/gui/plugin/SequenceManageWidget/CTableViewPrinter.h b/product/src/gui/plugin/SequenceManageWidget/CTableViewPrinter.h index 82304f16..839198f2 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CTableViewPrinter.h +++ b/product/src/gui/plugin/SequenceManageWidget/CTableViewPrinter.h @@ -1,24 +1,24 @@ -#ifndef CTABLEVIEWPRINTER_H -#define CTABLEVIEWPRINTER_H - -class QPointF; -class QPainter; -class QPrinter; -class QTableView; -class QAbstractItemModel; - -class CTableViewPrinter -{ -public: - explicit CTableViewPrinter(QTableView * view); - - void print(QPrinter *printer); - void renderHeader(QPainter &painter); - void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); - -private: - QTableView * m_pView; - QAbstractItemModel * m_pModel; -}; - -#endif // CTABLEVIEWPRINTER_H +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H + +class QPointF; +class QPainter; +class QPrinter; +class QTableView; +class QAbstractItemModel; + +class CTableViewPrinter +{ +public: + explicit CTableViewPrinter(QTableView * view); + + void print(QPrinter *printer); + void renderHeader(QPainter &painter); + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + +private: + QTableView * m_pView; + QAbstractItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/SequenceManageWidget/SequenceManageWidget.pro b/product/src/gui/plugin/SequenceManageWidget/SequenceManageWidget.pro index a17b3a3a..0f36c687 100644 --- a/product/src/gui/plugin/SequenceManageWidget/SequenceManageWidget.pro +++ b/product/src/gui/plugin/SequenceManageWidget/SequenceManageWidget.pro @@ -1,54 +1,54 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-06-08T11:53:52 -# -#------------------------------------------------- - -QT += core gui sql xml printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = SequenceManageWidget - -CONFIG += plugin - -SOURCES += \ - CSequenceManageWidget.cpp \ - CSequenceDBInterface.cpp \ - CHistroySequenceModel.cpp \ - CHistoryActionModel.cpp \ - CHistorySequenceFilterDialog.cpp \ - CRunningSequenceModel.cpp \ - CRunSequenceFilterDialog.cpp \ - CSequenceManagePluginWidget.cpp \ - CTableViewPrinter.cpp - -HEADERS += \ - CSequenceManageWidget.h \ - CSequenceDBInterface.h \ - CHistorySequenceModel.h \ - sequence_history_def.h \ - CHistoryActionModel.h \ - CHistorySequenceFilterDialog.h \ - CRunningSequenceModel.h \ - CRunSequenceFilterDialog.h \ - CSequenceManagePluginWidget.h \ - CTableViewPrinter.h - -FORMS += \ - CSequenceManageWidget.ui \ - CHistorySequenceFilterDialog.ui \ - CRunSequenceFilterDialog.ui - -LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -lrdb_net_api -lpub_sysinfo_api -lnet_msg_bus_api -LIBS += -lmodel_common -lSequenceWidget - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2018-06-08T11:53:52 +# +#------------------------------------------------- + +QT += core gui sql xml printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = SequenceManageWidget + +CONFIG += plugin + +SOURCES += \ + CSequenceManageWidget.cpp \ + CSequenceDBInterface.cpp \ + CHistroySequenceModel.cpp \ + CHistoryActionModel.cpp \ + CHistorySequenceFilterDialog.cpp \ + CRunningSequenceModel.cpp \ + CRunSequenceFilterDialog.cpp \ + CSequenceManagePluginWidget.cpp \ + CTableViewPrinter.cpp + +HEADERS += \ + CSequenceManageWidget.h \ + CSequenceDBInterface.h \ + CHistorySequenceModel.h \ + sequence_history_def.h \ + CHistoryActionModel.h \ + CHistorySequenceFilterDialog.h \ + CRunningSequenceModel.h \ + CRunSequenceFilterDialog.h \ + CSequenceManagePluginWidget.h \ + CTableViewPrinter.h + +FORMS += \ + CSequenceManageWidget.ui \ + CHistorySequenceFilterDialog.ui \ + CRunSequenceFilterDialog.ui + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api -lrdb_net_api -lpub_sysinfo_api -lnet_msg_bus_api +LIBS += -lmodel_common -lSequenceWidget + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/SequenceManageWidget/main.cpp b/product/src/gui/plugin/SequenceManageWidget/main.cpp index 6a59b4b4..35158c28 100644 --- a/product/src/gui/plugin/SequenceManageWidget/main.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/main.cpp @@ -1,24 +1,24 @@ -#include "CSequenceManageWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - - kbd_public::StartLogSystem(QString("log_hmi.properties").toUtf8().data(), - "hmi", "sequence"); - kbd_net::initMsgBus("Sequence", "1", true); - - { - CSequenceManageWidget w; - w.show(); - a.exec(); - } - - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "CSequenceManageWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + kbd_public::StartLogSystem(QString("log_hmi.properties").toUtf8().data(), + "hmi", "sequence"); + kbd_net::initMsgBus("Sequence", "1", true); + + { + CSequenceManageWidget w; + w.show(); + a.exec(); + } + + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/SequenceManageWidget/sequence_history_def.h b/product/src/gui/plugin/SequenceManageWidget/sequence_history_def.h index 55cfd866..d7ffdd95 100644 --- a/product/src/gui/plugin/SequenceManageWidget/sequence_history_def.h +++ b/product/src/gui/plugin/SequenceManageWidget/sequence_history_def.h @@ -1,50 +1,50 @@ -#ifndef SEQUENCE_HISTORY_DEF_H -#define SEQUENCE_HISTORY_DEF_H - -#include - -struct SequenceHistory -{ - QString seqName; - QString seqDescription; - quint64 time; - QString status; - QString location; - QString userID; - QString userName; - QString userGroup; - QString hostName; - int seqType; -}; - -struct FunctionHistory -{ - QString seqName; - quint64 time; - QString funcName; - QString funcDescription; - int funcNO; - int relation; - QString status; - QString location; -}; - -struct ActionHistory -{ - QString seqName; - quint64 time; - QString funcName; - QString functionDescription; - int actionNO; - QString actionName; - QString actionDescription; - QString status; - quint64 startTime; - quint64 stopTime; - QString KeyIdTag; - int targetValue; - QString location; - QString description; -}; - -#endif +#ifndef SEQUENCE_HISTORY_DEF_H +#define SEQUENCE_HISTORY_DEF_H + +#include + +struct SequenceHistory +{ + QString seqName; + QString seqDescription; + quint64 time; + QString status; + QString location; + QString userID; + QString userName; + QString userGroup; + QString hostName; + int seqType; +}; + +struct FunctionHistory +{ + QString seqName; + quint64 time; + QString funcName; + QString funcDescription; + int funcNO; + int relation; + QString status; + QString location; +}; + +struct ActionHistory +{ + QString seqName; + quint64 time; + QString funcName; + QString functionDescription; + int actionNO; + QString actionName; + QString actionDescription; + QString status; + quint64 startTime; + quint64 stopTime; + QString KeyIdTag; + int targetValue; + QString location; + QString description; +}; + +#endif diff --git a/product/src/gui/plugin/SequenceWidget/CActionSequModel.cpp b/product/src/gui/plugin/SequenceWidget/CActionSequModel.cpp index 8ab15aae..f927c6de 100644 --- a/product/src/gui/plugin/SequenceWidget/CActionSequModel.cpp +++ b/product/src/gui/plugin/SequenceWidget/CActionSequModel.cpp @@ -1,183 +1,183 @@ -#include "CActionSequModel.h" - -CActionSequModel::CActionSequModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header << tr("标记") << tr("开关名称") << tr("延时") << tr("目标状态") << tr("执行状态") << tr("实际状态"); -} - -void CActionSequModel::initSequenceData(const QList listSequence) -{ - beginResetModel(); - m_data.clear(); - m_data = listSequence; - endResetModel(); -} - -QList CActionSequModel::sequenceData() -{ - return m_data; -} - -void CActionSequModel::updateSequenceExecState(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state) -{ - for(int nIndex(0); nIndex < m_data.size(); nIndex++) - { - if(E_Node_Action == m_data[nIndex].nodeType && - m_data[nIndex].seqName == seqName && - m_data[nIndex].funcName == funcName && - m_data[nIndex].actionName == actionName) - { - m_data[nIndex].executeState = state; - QModelIndex modelIndex = createIndex(nIndex, act_column::Column_ExecuteState); - emit dataChanged(modelIndex, modelIndex); - } - } -} - -void CActionSequModel::updateSequenceActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state) -{ - for(int nIndex(0); nIndex < m_data.size(); nIndex++) - { - if(E_Node_Action == m_data[nIndex].nodeType && - m_data[nIndex].seqName == seqName && - m_data[nIndex].funcName == funcName && - m_data[nIndex].actionName == actionName) - { - m_data[nIndex].actualState = state; - QModelIndex modelIndex = createIndex(nIndex, act_column::Column_ActualState); - emit dataChanged(modelIndex, modelIndex); - } - } -} - -QVariant CActionSequModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::Horizontal != orientation || Qt::DisplayRole != role) - { - return QVariant(); - } - return m_header.at(section); -} - -int CActionSequModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return 0; - } - return m_data.size(); -} - -int CActionSequModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - { - return 0; - } - - return m_header.size(); -} - -bool CActionSequModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid()) - return false; - - if(Qt::CheckStateRole == role && act_column::Column_CheckState == index.column()) - { - m_data[index.row()].checkState = (E_CHECK_STATE)value.toInt(); - return true; - } - return false; -} - -QVariant CActionSequModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - else if(Qt::CheckStateRole == role) - { - if(act_column::Column_CheckState == index.column()) - { - return m_data.at(index.row()).checkState; - } - } - else if(Qt::DisplayRole == role) - { - switch (index.column()) - { - case act_column::Column_TagName: - { - return m_data.at(index.row()).actionDescription; - } - case act_column::Column_Delay: - { - return QString("%1s").arg(m_data.at(index.row()).delay); - } - case act_column::Column_TargetState: - { - return m_data.at(index.row()).targetState; - } - case act_column::Column_ExecuteState: - { - switch (m_data.at(index.row()).executeState) - { - case E_Exec_Reset: - return tr("未执行"); - case E_Exec_Run: - return tr("正在执行"); - case E_Exec_Triggered: - return tr("已触发"); - case E_Exec_Failed: - return tr("执行失败"); - case E_Exec_Success: - return tr("执行成功"); - case E_Exec_Stop: - return tr("执行终止"); - case E_Exec_Pause: - return tr("执行暂停"); - case E_Exec_Skip: - return tr("执行跳过"); - default: - break; - } - } - case act_column::Column_ActualState: - { - return m_data.at(index.row()).actualState; - } - default: - break; - } - } - else if(Qt::UserRole == role) - { - if(act_column::Column_ExecuteState == index.column()) - { - return m_data.at(index.row()).executeState; - } - } - return QVariant(); -} - -Qt::ItemFlags CActionSequModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - if(act_column::Column_CheckState == index.column()) - { - return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; - } - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} +#include "CActionSequModel.h" + +CActionSequModel::CActionSequModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header << tr("标记") << tr("开关名称") << tr("延时") << tr("目标状态") << tr("执行状态") << tr("实际状态"); +} + +void CActionSequModel::initSequenceData(const QList listSequence) +{ + beginResetModel(); + m_data.clear(); + m_data = listSequence; + endResetModel(); +} + +QList CActionSequModel::sequenceData() +{ + return m_data; +} + +void CActionSequModel::updateSequenceExecState(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state) +{ + for(int nIndex(0); nIndex < m_data.size(); nIndex++) + { + if(E_Node_Action == m_data[nIndex].nodeType && + m_data[nIndex].seqName == seqName && + m_data[nIndex].funcName == funcName && + m_data[nIndex].actionName == actionName) + { + m_data[nIndex].executeState = state; + QModelIndex modelIndex = createIndex(nIndex, act_column::Column_ExecuteState); + emit dataChanged(modelIndex, modelIndex); + } + } +} + +void CActionSequModel::updateSequenceActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state) +{ + for(int nIndex(0); nIndex < m_data.size(); nIndex++) + { + if(E_Node_Action == m_data[nIndex].nodeType && + m_data[nIndex].seqName == seqName && + m_data[nIndex].funcName == funcName && + m_data[nIndex].actionName == actionName) + { + m_data[nIndex].actualState = state; + QModelIndex modelIndex = createIndex(nIndex, act_column::Column_ActualState); + emit dataChanged(modelIndex, modelIndex); + } + } +} + +QVariant CActionSequModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::Horizontal != orientation || Qt::DisplayRole != role) + { + return QVariant(); + } + return m_header.at(section); +} + +int CActionSequModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return 0; + } + return m_data.size(); +} + +int CActionSequModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return 0; + } + + return m_header.size(); +} + +bool CActionSequModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid()) + return false; + + if(Qt::CheckStateRole == role && act_column::Column_CheckState == index.column()) + { + m_data[index.row()].checkState = (E_CHECK_STATE)value.toInt(); + return true; + } + return false; +} + +QVariant CActionSequModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + else if(Qt::CheckStateRole == role) + { + if(act_column::Column_CheckState == index.column()) + { + return m_data.at(index.row()).checkState; + } + } + else if(Qt::DisplayRole == role) + { + switch (index.column()) + { + case act_column::Column_TagName: + { + return m_data.at(index.row()).actionDescription; + } + case act_column::Column_Delay: + { + return QString("%1s").arg(m_data.at(index.row()).delay); + } + case act_column::Column_TargetState: + { + return m_data.at(index.row()).targetState; + } + case act_column::Column_ExecuteState: + { + switch (m_data.at(index.row()).executeState) + { + case E_Exec_Reset: + return tr("未执行"); + case E_Exec_Run: + return tr("正在执行"); + case E_Exec_Triggered: + return tr("已触发"); + case E_Exec_Failed: + return tr("执行失败"); + case E_Exec_Success: + return tr("执行成功"); + case E_Exec_Stop: + return tr("执行终止"); + case E_Exec_Pause: + return tr("执行暂停"); + case E_Exec_Skip: + return tr("执行跳过"); + default: + break; + } + } + case act_column::Column_ActualState: + { + return m_data.at(index.row()).actualState; + } + default: + break; + } + } + else if(Qt::UserRole == role) + { + if(act_column::Column_ExecuteState == index.column()) + { + return m_data.at(index.row()).executeState; + } + } + return QVariant(); +} + +Qt::ItemFlags CActionSequModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + if(act_column::Column_CheckState == index.column()) + { + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} diff --git a/product/src/gui/plugin/SequenceWidget/CActionSequModel.h b/product/src/gui/plugin/SequenceWidget/CActionSequModel.h index 027f9cf3..b65745aa 100644 --- a/product/src/gui/plugin/SequenceWidget/CActionSequModel.h +++ b/product/src/gui/plugin/SequenceWidget/CActionSequModel.h @@ -1,49 +1,49 @@ -#ifndef CACTIONSEQUMODEL_H -#define CACTIONSEQUMODEL_H - -#include -#include "sequence_def.h" - -namespace act_column -{ - const int Column_CheckState = 0; - const int Column_TagName = 1; - const int Column_Delay = 2; - const int Column_TargetState = 3; - const int Column_ExecuteState = 4; - const int Column_ActualState = 5; -} - -class CActionSequModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CActionSequModel(QObject *parent = nullptr); - - void initSequenceData(const QList listSequence); - - QList sequenceData(); - - void updateSequenceExecState(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state); - - void updateSequenceActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - bool setData(const QModelIndex &index, const QVariant &value, int role) override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - -private: - QStringList m_header; - QList m_data; -}; - -#endif // CACTIONSEQUMODEL_H +#ifndef CACTIONSEQUMODEL_H +#define CACTIONSEQUMODEL_H + +#include +#include "sequence_def.h" + +namespace act_column +{ + const int Column_CheckState = 0; + const int Column_TagName = 1; + const int Column_Delay = 2; + const int Column_TargetState = 3; + const int Column_ExecuteState = 4; + const int Column_ActualState = 5; +} + +class CActionSequModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CActionSequModel(QObject *parent = nullptr); + + void initSequenceData(const QList listSequence); + + QList sequenceData(); + + void updateSequenceExecState(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state); + + void updateSequenceActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + +private: + QStringList m_header; + QList m_data; +}; + +#endif // CACTIONSEQUMODEL_H diff --git a/product/src/gui/plugin/SequenceWidget/CLocationSequModel.cpp b/product/src/gui/plugin/SequenceWidget/CLocationSequModel.cpp index 06c4dca4..85c5a56e 100644 --- a/product/src/gui/plugin/SequenceWidget/CLocationSequModel.cpp +++ b/product/src/gui/plugin/SequenceWidget/CLocationSequModel.cpp @@ -1,153 +1,153 @@ -#include "CLocationSequModel.h" - -CLocationSequModel::CLocationSequModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header << tr("标记") << tr("场站") << tr("顺控名称") << tr("执行状态"); -} - -void CLocationSequModel::initSequenceData(const QList listSequence) -{ - beginResetModel(); - m_data.clear(); - m_data = listSequence; - endResetModel(); -} - -QList CLocationSequModel::sequenceData() -{ - return m_data; -} - -void CLocationSequModel::updateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state) -{ - for(int nIndex(0); nIndex < m_data.size(); nIndex++) - { - if(E_Node_Sequence == m_data[nIndex].nodeType && m_data[nIndex].seqName == seqName) - { - m_data[nIndex].executeState = state; - QModelIndex modelIndex = createIndex(nIndex, seq_column::Column_State); - emit dataChanged(modelIndex, modelIndex); - } - } -} - -QVariant CLocationSequModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::Horizontal != orientation || Qt::DisplayRole != role) - { - return QVariant(); - } - return m_header.at(section); -} - -int CLocationSequModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_data.size(); -} - -int CLocationSequModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return m_header.size(); -} - -bool CLocationSequModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid()) - return false; - - if(Qt::CheckStateRole == role && seq_column::Column_CheckState == index.column()) - { - m_data[index.row()].checkState = (E_CHECK_STATE)value.toInt(); - return true; - } - return false; -} - -QVariant CLocationSequModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if(Qt::TextAlignmentRole == role) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - else if(Qt::CheckStateRole == role) - { - if(seq_column::Column_CheckState == index.column()) - { - return m_data.at(index.row()).checkState; - } - } - else if(Qt::DisplayRole == role) - { - switch (index.column()) - { - case seq_column::Column_Location: - { - return m_data.at(index.row()).location; - } - case seq_column::Column_SeqName: - { - return m_data.at(index.row()).seqDescription; - } - case seq_column::Column_State: - { - switch (m_data.at(index.row()).executeState) - { - case E_Exec_Reset: - return tr("未执行"); - case E_Exec_Run: - return tr("正在执行"); - case E_Exec_Triggered: - return tr("已触发"); - case E_Exec_Failed: - return tr("执行失败"); - case E_Exec_Success: - return tr("执行成功"); - case E_Exec_Stop: - return tr("执行终止"); - case E_Exec_Pause: - return tr("执行暂停"); - case E_Exec_Skip: - return tr("执行跳过"); - default: - break; - } - } - default: - break; - } - } - else if(Qt::UserRole == role) - { - if(seq_column::Column_State == index.column()) - { - m_data.at(index.row()).executeState; - } - } - return QVariant(); -} - -Qt::ItemFlags CLocationSequModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - if(seq_column::Column_CheckState == index.column()) - { - return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; - } - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} - - +#include "CLocationSequModel.h" + +CLocationSequModel::CLocationSequModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header << tr("标记") << tr("场站") << tr("顺控名称") << tr("执行状态"); +} + +void CLocationSequModel::initSequenceData(const QList listSequence) +{ + beginResetModel(); + m_data.clear(); + m_data = listSequence; + endResetModel(); +} + +QList CLocationSequModel::sequenceData() +{ + return m_data; +} + +void CLocationSequModel::updateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state) +{ + for(int nIndex(0); nIndex < m_data.size(); nIndex++) + { + if(E_Node_Sequence == m_data[nIndex].nodeType && m_data[nIndex].seqName == seqName) + { + m_data[nIndex].executeState = state; + QModelIndex modelIndex = createIndex(nIndex, seq_column::Column_State); + emit dataChanged(modelIndex, modelIndex); + } + } +} + +QVariant CLocationSequModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::Horizontal != orientation || Qt::DisplayRole != role) + { + return QVariant(); + } + return m_header.at(section); +} + +int CLocationSequModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_data.size(); +} + +int CLocationSequModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_header.size(); +} + +bool CLocationSequModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid()) + return false; + + if(Qt::CheckStateRole == role && seq_column::Column_CheckState == index.column()) + { + m_data[index.row()].checkState = (E_CHECK_STATE)value.toInt(); + return true; + } + return false; +} + +QVariant CLocationSequModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if(Qt::TextAlignmentRole == role) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + else if(Qt::CheckStateRole == role) + { + if(seq_column::Column_CheckState == index.column()) + { + return m_data.at(index.row()).checkState; + } + } + else if(Qt::DisplayRole == role) + { + switch (index.column()) + { + case seq_column::Column_Location: + { + return m_data.at(index.row()).location; + } + case seq_column::Column_SeqName: + { + return m_data.at(index.row()).seqDescription; + } + case seq_column::Column_State: + { + switch (m_data.at(index.row()).executeState) + { + case E_Exec_Reset: + return tr("未执行"); + case E_Exec_Run: + return tr("正在执行"); + case E_Exec_Triggered: + return tr("已触发"); + case E_Exec_Failed: + return tr("执行失败"); + case E_Exec_Success: + return tr("执行成功"); + case E_Exec_Stop: + return tr("执行终止"); + case E_Exec_Pause: + return tr("执行暂停"); + case E_Exec_Skip: + return tr("执行跳过"); + default: + break; + } + } + default: + break; + } + } + else if(Qt::UserRole == role) + { + if(seq_column::Column_State == index.column()) + { + m_data.at(index.row()).executeState; + } + } + return QVariant(); +} + +Qt::ItemFlags CLocationSequModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + if(seq_column::Column_CheckState == index.column()) + { + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + + diff --git a/product/src/gui/plugin/SequenceWidget/CLocationSequModel.h b/product/src/gui/plugin/SequenceWidget/CLocationSequModel.h index 7ed587e1..0ebac724 100644 --- a/product/src/gui/plugin/SequenceWidget/CLocationSequModel.h +++ b/product/src/gui/plugin/SequenceWidget/CLocationSequModel.h @@ -1,44 +1,44 @@ -#ifndef CLOCATIONSEQUMODEL_H -#define CLOCATIONSEQUMODEL_H - -#include -#include "sequence_def.h" - -namespace seq_column -{ - const int Column_CheckState = 0; - const int Column_Location = 1; - const int Column_SeqName = 2; - const int Column_State = 3; -} - -class CLocationSequModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CLocationSequModel(QObject *parent = nullptr); - - void initSequenceData(const QList listSequence); - - QList sequenceData(); - - void updateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - -private: - QStringList m_header; - QList m_data; -}; - -#endif // CLOCATIONSEQUMODEL_H +#ifndef CLOCATIONSEQUMODEL_H +#define CLOCATIONSEQUMODEL_H + +#include +#include "sequence_def.h" + +namespace seq_column +{ + const int Column_CheckState = 0; + const int Column_Location = 1; + const int Column_SeqName = 2; + const int Column_State = 3; +} + +class CLocationSequModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CLocationSequModel(QObject *parent = nullptr); + + void initSequenceData(const QList listSequence); + + QList sequenceData(); + + void updateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + +private: + QStringList m_header; + QList m_data; +}; + +#endif // CLOCATIONSEQUMODEL_H diff --git a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApi.cpp b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApi.cpp index ce1f3b3e..e7365d44 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApi.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApi.cpp @@ -1,40 +1,40 @@ -#include "application/sequence_server_api/CSeqForHmiApi.h" -#include "CSeqForHmiApiImpl.h" - -using namespace kbd_application; -using namespace kbd_idlfile::sequence; -CSeqForHmiApi::CSeqForHmiApi(int appid) -{ - m_pImpl = new CSeqForHmiApiImpl(appid, this); -} - -CSeqForHmiApi::~CSeqForHmiApi() -{ - if (m_pImpl) - { - delete m_pImpl; - m_pImpl = NULL; - } -} - -bool CSeqForHmiApi::start() -{ - return m_pImpl->start(); -} - -bool CSeqForHmiApi::stop() -{ - return m_pImpl->stop(); -} - -bool CSeqForHmiApi::seqOperateRequest( - SeqOperateMessage& msg) -{ - return m_pImpl->seqOperateRequest(msg); -} - -bool CSeqForHmiApi::userInterveneResponse( - UiRequestMessageAck& msg) -{ - return m_pImpl->userInterveneResponse(msg); -} +#include "application/sequence_server_api/CSeqForHmiApi.h" +#include "CSeqForHmiApiImpl.h" + +using namespace kbd_application; +using namespace kbd_idlfile::sequence; +CSeqForHmiApi::CSeqForHmiApi(int appid) +{ + m_pImpl = new CSeqForHmiApiImpl(appid, this); +} + +CSeqForHmiApi::~CSeqForHmiApi() +{ + if (m_pImpl) + { + delete m_pImpl; + m_pImpl = NULL; + } +} + +bool CSeqForHmiApi::start() +{ + return m_pImpl->start(); +} + +bool CSeqForHmiApi::stop() +{ + return m_pImpl->stop(); +} + +bool CSeqForHmiApi::seqOperateRequest( + SeqOperateMessage& msg) +{ + return m_pImpl->seqOperateRequest(msg); +} + +bool CSeqForHmiApi::userInterveneResponse( + UiRequestMessageAck& msg) +{ + return m_pImpl->userInterveneResponse(msg); +} diff --git a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.cpp b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.cpp index c120169d..2e6dfde4 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.cpp @@ -1,182 +1,182 @@ -#include "public/pub_logger_api/logger.h" -#include "MessageChannel.h" -#include "Common.h" - -#include "CSeqForHmiApiImpl.h" - -using namespace kbd_application; -using namespace kbd_idlfile::sequence; -kbd_application::CSeqForHmiApiImpl::CSeqForHmiApiImpl( - int appid, - CSeqForHmiApi* api) : - CTimerThreadBase("CSeqForHmiApiImpl thread", 100), - m_ptrInterface(api), - m_nServerAppid(appid) -{ -} - -CSeqForHmiApiImpl::~CSeqForHmiApiImpl() -{ - this->quit(); -} - -bool CSeqForHmiApiImpl::start() -{ - this->resume(); - return true; -} - -bool CSeqForHmiApiImpl::stop() -{ - this->suspend(); - return true; -} - -void CSeqForHmiApiImpl::afterResume() -{ - LOGINFO("订阅顺控服务通道 appid[%d] channel[%d]", - m_nServerAppid, - CH_LINK_TO_HMI_CTRL_UP); - - m_objRecvSeqCMb.addSub( - m_nServerAppid, - CH_SEQ_TO_HMI_SEQCTRL_UP); -} - -void CSeqForHmiApiImpl::afterSuspend() -{ - m_objRecvSeqCMb.delSub( - m_nServerAppid, - CH_SEQ_TO_HMI_SEQCTRL_UP); - - LOGINFO("取消订阅顺控服务通道 appid[%d] channel[%d]", - m_nServerAppid, - CH_SEQ_TO_HMI_SEQCTRL_UP); -} -void CSeqForHmiApiImpl::execute() -{ - using namespace kbd_idlfile; - if (!m_objRecvSeqCMb.recvMsg(m_objRecvMsg)) - { - return; - } - - recvMsgSeq(m_objRecvMsg); -} - -bool CSeqForHmiApiImpl::recvMsgSeq( - kbd_net::CMbMessage& msg) -{ - try { - using namespace kbd_idlfile; - - if (msg.getMsgType() != MT_SEQAGE_CTRL_HMI_UP) - { - LOGERROR("在CH_HMI_TO_SEQ_CTRL_DOWN 这个通道中收到 其他类型的消息:[%d]", - msg.getMsgType()); - return false; - } - - LOGINFO("recvMsgSeq msgType[%d]", - msg.getMsgType()); - - int msgType = msg.getPara1(); - switch (msgType) - { - case enumStatusMessage: - { - StatusChangeMessage dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - (int)msg.getDataSize())) - { - BOOST_ASSERT(false); - return false; - } - return handleSeqStateChange(dataMsg); - } - break; - case enumSeqOperateMessageAck: - { - SeqOperateMessageAck dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - (int)msg.getDataSize())) - { - BOOST_ASSERT(false); - } - return handleSeqOperateResponse(dataMsg); - } - break; - case enumUiRequestMessage: - { - UiRequestMessage dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - (int)msg.getDataSize())) - { - BOOST_ASSERT(false); - } - return handleUserInterveneRequest(dataMsg); - } - break; - default: - BOOST_ASSERT(false); - break; - } - } - catch (std::exception &ex) - { - LOGERROR(ex.what()); - } - - return false; -} - -bool CSeqForHmiApiImpl::sendToSeq(kbd_net::CMbMessage& msg, int domain) -{ - LOGINFO("sendMsgToDomain domain[%d] appid[%d] msgType[%d] Subject[%d]", - domain, - m_nServerAppid, - MT_SEQAGE_CTRL_HMI_DOWN, - CH_HMI_TO_SEQ_SEQCTRL_DOWN); - - msg.setMsgType(MT_SEQAGE_CTRL_HMI_DOWN); - msg.setSubject(m_nServerAppid, CH_HMI_TO_SEQ_SEQCTRL_DOWN); - return m_objSendSeqCMb.sendMsgToDomain(msg, domain); -} - -bool CSeqForHmiApiImpl::seqOperateRequest( - SeqOperateMessage& msg) -{ - int domain = msg.pkg_head().target_domain(); - kbd_net::CMbMessage objMessage; - objMessage.setPara1(enumSeqOperateMessage); - objMessage.setData(msg.SerializeAsString()); - return sendToSeq(objMessage, domain); -} - -bool CSeqForHmiApiImpl::userInterveneResponse( - UiRequestMessageAck& msg) -{ - int domain = msg.pkg_head().target_domain(); - kbd_net::CMbMessage objMessage; - objMessage.setPara1(enumUiRequestMessageAck); - objMessage.setData(msg.SerializeAsString()); - return sendToSeq(objMessage, domain); -} - -bool CSeqForHmiApiImpl::handleSeqOperateResponse( - SeqOperateMessageAck& msg) -{ - return m_ptrInterface->handleSeqOperateResponse(msg); -} - -bool CSeqForHmiApiImpl::handleUserInterveneRequest( - UiRequestMessage& msg) -{ - return m_ptrInterface->handleUserInterveneRequest(msg); -} - -bool CSeqForHmiApiImpl::handleSeqStateChange( - StatusChangeMessage& msg) -{ - return m_ptrInterface->handleSeqStateChange(msg); -} +#include "public/pub_logger_api/logger.h" +#include "MessageChannel.h" +#include "Common.h" + +#include "CSeqForHmiApiImpl.h" + +using namespace kbd_application; +using namespace kbd_idlfile::sequence; +kbd_application::CSeqForHmiApiImpl::CSeqForHmiApiImpl( + int appid, + CSeqForHmiApi* api) : + CTimerThreadBase("CSeqForHmiApiImpl thread", 100), + m_ptrInterface(api), + m_nServerAppid(appid) +{ +} + +CSeqForHmiApiImpl::~CSeqForHmiApiImpl() +{ + this->quit(); +} + +bool CSeqForHmiApiImpl::start() +{ + this->resume(); + return true; +} + +bool CSeqForHmiApiImpl::stop() +{ + this->suspend(); + return true; +} + +void CSeqForHmiApiImpl::afterResume() +{ + LOGINFO("订阅顺控服务通道 appid[%d] channel[%d]", + m_nServerAppid, + CH_LINK_TO_HMI_CTRL_UP); + + m_objRecvSeqCMb.addSub( + m_nServerAppid, + CH_SEQ_TO_HMI_SEQCTRL_UP); +} + +void CSeqForHmiApiImpl::afterSuspend() +{ + m_objRecvSeqCMb.delSub( + m_nServerAppid, + CH_SEQ_TO_HMI_SEQCTRL_UP); + + LOGINFO("取消订阅顺控服务通道 appid[%d] channel[%d]", + m_nServerAppid, + CH_SEQ_TO_HMI_SEQCTRL_UP); +} +void CSeqForHmiApiImpl::execute() +{ + using namespace kbd_idlfile; + if (!m_objRecvSeqCMb.recvMsg(m_objRecvMsg)) + { + return; + } + + recvMsgSeq(m_objRecvMsg); +} + +bool CSeqForHmiApiImpl::recvMsgSeq( + kbd_net::CMbMessage& msg) +{ + try { + using namespace kbd_idlfile; + + if (msg.getMsgType() != MT_SEQAGE_CTRL_HMI_UP) + { + LOGERROR("在CH_HMI_TO_SEQ_CTRL_DOWN 这个通道中收到 其他类型的消息:[%d]", + msg.getMsgType()); + return false; + } + + LOGINFO("recvMsgSeq msgType[%d]", + msg.getMsgType()); + + int msgType = msg.getPara1(); + switch (msgType) + { + case enumStatusMessage: + { + StatusChangeMessage dataMsg; + if (!dataMsg.ParseFromArray(msg.getDataPtr(), + (int)msg.getDataSize())) + { + BOOST_ASSERT(false); + return false; + } + return handleSeqStateChange(dataMsg); + } + break; + case enumSeqOperateMessageAck: + { + SeqOperateMessageAck dataMsg; + if (!dataMsg.ParseFromArray(msg.getDataPtr(), + (int)msg.getDataSize())) + { + BOOST_ASSERT(false); + } + return handleSeqOperateResponse(dataMsg); + } + break; + case enumUiRequestMessage: + { + UiRequestMessage dataMsg; + if (!dataMsg.ParseFromArray(msg.getDataPtr(), + (int)msg.getDataSize())) + { + BOOST_ASSERT(false); + } + return handleUserInterveneRequest(dataMsg); + } + break; + default: + BOOST_ASSERT(false); + break; + } + } + catch (std::exception &ex) + { + LOGERROR(ex.what()); + } + + return false; +} + +bool CSeqForHmiApiImpl::sendToSeq(kbd_net::CMbMessage& msg, int domain) +{ + LOGINFO("sendMsgToDomain domain[%d] appid[%d] msgType[%d] Subject[%d]", + domain, + m_nServerAppid, + MT_SEQAGE_CTRL_HMI_DOWN, + CH_HMI_TO_SEQ_SEQCTRL_DOWN); + + msg.setMsgType(MT_SEQAGE_CTRL_HMI_DOWN); + msg.setSubject(m_nServerAppid, CH_HMI_TO_SEQ_SEQCTRL_DOWN); + return m_objSendSeqCMb.sendMsgToDomain(msg, domain); +} + +bool CSeqForHmiApiImpl::seqOperateRequest( + SeqOperateMessage& msg) +{ + int domain = msg.pkg_head().target_domain(); + kbd_net::CMbMessage objMessage; + objMessage.setPara1(enumSeqOperateMessage); + objMessage.setData(msg.SerializeAsString()); + return sendToSeq(objMessage, domain); +} + +bool CSeqForHmiApiImpl::userInterveneResponse( + UiRequestMessageAck& msg) +{ + int domain = msg.pkg_head().target_domain(); + kbd_net::CMbMessage objMessage; + objMessage.setPara1(enumUiRequestMessageAck); + objMessage.setData(msg.SerializeAsString()); + return sendToSeq(objMessage, domain); +} + +bool CSeqForHmiApiImpl::handleSeqOperateResponse( + SeqOperateMessageAck& msg) +{ + return m_ptrInterface->handleSeqOperateResponse(msg); +} + +bool CSeqForHmiApiImpl::handleUserInterveneRequest( + UiRequestMessage& msg) +{ + return m_ptrInterface->handleUserInterveneRequest(msg); +} + +bool CSeqForHmiApiImpl::handleSeqStateChange( + StatusChangeMessage& msg) +{ + return m_ptrInterface->handleSeqStateChange(msg); +} diff --git a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.h b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.h index ca2fe5b6..71248357 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.h +++ b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.h @@ -1,59 +1,59 @@ -#ifndef CSEQUENCEFORHMIAPIIMPL_H -#define CSEQUENCEFORHMIAPIIMPL_H - -#include -#include "pub_utility_api/TimerThreadBase.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "application/sequence_server_api/CSeqForHmiApi.h" - -namespace kbd_application { - using namespace kbd_idlfile::sequence; - class CSeqForHmiApiImpl - : public kbd_public::CTimerThreadBase - { - public: - CSeqForHmiApiImpl(int appid, CSeqForHmiApi* api); - ~CSeqForHmiApiImpl(); - - //开启线程 - bool start(); - - //停止线程 - bool stop(); - - //1 hmi->server 发起的请求顺控操作 - bool seqOperateRequest( - SeqOperateMessage& msg); - //2 hmi ->server 人工干预应答 - bool userInterveneResponse( - UiRequestMessageAck& msg); - - protected: - void afterSuspend(); - void afterResume(); - void execute(); - private: - //2 server->hmi 请求顺控操作 的 应答 - bool handleSeqOperateResponse( - SeqOperateMessageAck& msg); - //1 server->hmi 发起的人工干预 请求 - bool handleUserInterveneRequest( - UiRequestMessage& msg); - //server->hmi 顺控状态更新 - bool handleSeqStateChange( - StatusChangeMessage& msg); - - bool sendToSeq(kbd_net::CMbMessage& msg, int domain); - - bool recvMsgSeq(kbd_net::CMbMessage& msg); - private: - CSeqForHmiApi* m_ptrInterface; - kbd_net::CMbMessage m_objRecvMsg; - - kbd_net::CMbCommunicator m_objSendSeqCMb;//发送 sequence - kbd_net::CMbCommunicator m_objRecvSeqCMb;//接收 sequence - - const int m_nServerAppid; - }; -} -#endif // CSEQUENCEFORHMIAPIIMPL_H +#ifndef CSEQUENCEFORHMIAPIIMPL_H +#define CSEQUENCEFORHMIAPIIMPL_H + +#include +#include "pub_utility_api/TimerThreadBase.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "application/sequence_server_api/CSeqForHmiApi.h" + +namespace kbd_application { + using namespace kbd_idlfile::sequence; + class CSeqForHmiApiImpl + : public kbd_public::CTimerThreadBase + { + public: + CSeqForHmiApiImpl(int appid, CSeqForHmiApi* api); + ~CSeqForHmiApiImpl(); + + //开启线程 + bool start(); + + //停止线程 + bool stop(); + + //1 hmi->server 发起的请求顺控操作 + bool seqOperateRequest( + SeqOperateMessage& msg); + //2 hmi ->server 人工干预应答 + bool userInterveneResponse( + UiRequestMessageAck& msg); + + protected: + void afterSuspend(); + void afterResume(); + void execute(); + private: + //2 server->hmi 请求顺控操作 的 应答 + bool handleSeqOperateResponse( + SeqOperateMessageAck& msg); + //1 server->hmi 发起的人工干预 请求 + bool handleUserInterveneRequest( + UiRequestMessage& msg); + //server->hmi 顺控状态更新 + bool handleSeqStateChange( + StatusChangeMessage& msg); + + bool sendToSeq(kbd_net::CMbMessage& msg, int domain); + + bool recvMsgSeq(kbd_net::CMbMessage& msg); + private: + CSeqForHmiApi* m_ptrInterface; + kbd_net::CMbMessage m_objRecvMsg; + + kbd_net::CMbCommunicator m_objSendSeqCMb;//发送 sequence + kbd_net::CMbCommunicator m_objRecvSeqCMb;//接收 sequence + + const int m_nServerAppid; + }; +} +#endif // CSEQUENCEFORHMIAPIIMPL_H diff --git a/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.cpp b/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.cpp index c5439627..c52c434f 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.cpp @@ -1,368 +1,368 @@ -#include "CSeqPermDialog.h" -#include "ui_CSeqPermDialog.h" -#include -#include - -CSeqPermDialog::CSeqPermDialog(QWidget *parent, bool gurad) : - QDialog(parent), - ui(new Ui::CSeqPermDialog), - m_ptrPermMng(NULL), - m_isGuard(true), - m_nUserId(-1), - m_strUsrName(""), - m_nUserGrpId(-1) -{ - ui->setupUi(this); - - initView(gurad); - - if(initPermMng()) - { - initUserGroup(); - } -} - -CSeqPermDialog::~CSeqPermDialog() -{ - delete ui; -} - -int CSeqPermDialog::getUserId() -{ - return m_nUserId; -} - -std::string CSeqPermDialog::getUserName() -{ - return m_strUsrName; -} - -int CSeqPermDialog::getUserGrpId() -{ - return m_nUserGrpId; -} - -void CSeqPermDialog::initView(bool guard) -{ - m_isGuard = guard; - ui->m_optUserGroup->setEnabled(false); - ui->m_optUserName->setEnabled(false); - ui->m_optUserName->setEditable(true); - ui->m_optUserAlias->setReadOnly(true); - ui->m_optPassword->setEchoMode(QLineEdit::Password); - ui->m_guardUserName->setEditable(true); - ui->m_guardUserAlias->setReadOnly(true); - ui->m_guardPassword->setEchoMode(QLineEdit::Password); - ui->m_guardFrame->setVisible(guard); - guard ? resize(400,230) : resize(240,230); - - connect(ui->m_optUserGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(slotOptUserGrpChange(int))); - connect(ui->m_optUserName, SIGNAL(currentIndexChanged(int)), this, SLOT(slotOptUserChange(int))); - connect(ui->m_guardUserGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(slotGuardUserGrpChange(int))); - connect(ui->m_guardUserName, SIGNAL(currentIndexChanged(int)), this, SLOT(slotGuardUserChange(int))); - connect(ui->m_guardUserName, SIGNAL(currentTextChanged(QString)), this, SLOT(slotGuardUserChange(QString))); - connect(ui->m_login, SIGNAL(clicked()), this, SLOT(slotLogin())); - connect(ui->m_cancel, SIGNAL(clicked()), this, SLOT(slotCancel())); -} - -bool CSeqPermDialog::initPermMng() -{ - m_ptrPermMng = kbd_service::getPermMngInstance("base"); - int result = m_ptrPermMng->PermDllInit(); - if(result < 0) - { - setEnabled(false); - return false; - } - return true; -} - -void CSeqPermDialog::initUserGroup() -{ - if(m_ptrPermMng == NULL) - { - return; - } - std::vector vecUsergId; - m_ptrPermMng->getAllUsergID(vecUsergId); - std::vector::iterator iter = vecUsergId.begin(); - for(; iter != vecUsergId.end(); iter++) - { - ui->m_optUserGroup->addItem(QString::fromStdString(iter->userg_name), iter->userg_id); - ui->m_guardUserGroup->addItem(QString::fromStdString(iter->userg_name), iter->userg_id); - } - - int nUserId; - int nUserGrpId; - int nLevel; - int nLoginSec; - std::string instanceName; - if(PERM_NORMAL == m_ptrPermMng->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, instanceName)) - { - int userGrpIndex = ui->m_optUserGroup->findData(nUserGrpId); - ui->m_optUserGroup->setCurrentIndex(userGrpIndex); - - int userNameIndex = ui->m_optUserName->findData(nUserId); - ui->m_optUserName->setCurrentIndex(userNameIndex); - } -} - -bool CSeqPermDialog::getSeqCtrlPerm(int usergId) -{ - if(m_ptrPermMng == NULL) - { - return false; - } - std::string tmp = FUNC_NOM_PSCADA_SEQ_CTRL; - if (PERM_PERMIT == m_ptrPermMng->PermCheck(PERM_NOM_FUNC_DEF, &tmp, usergId)) - { - return true; - } - return false; -} - -bool CSeqPermDialog::getGuardPerm(int usergId) -{ - if(m_ptrPermMng == NULL) - { - return false; - } - std::string tmp = FUNC_NOM_GUARD_CTRL; - if (PERM_PERMIT == m_ptrPermMng->PermCheck(PERM_NOM_FUNC_DEF, &tmp, usergId)) - { - return true; - } - return false; -} - -bool CSeqPermDialog::checkLogin(const std::string &userName, const std::string &password, int usergId, int userId, bool guard) -{ - if(m_ptrPermMng == NULL) - { - return false; - } - QString str; - if(guard){ - str = tr("监护验证: "); - }else{ - str = tr("操作验证: "); - } - - std::vector vecUserId; - m_ptrPermMng->GetUsersByUserg(usergId, vecUserId); - std::vector::const_iterator iter = vecUserId.cbegin(); - for(; iter != vecUserId.cend(); iter++) - { - if(*iter == userId) - { - break; - } - } - if(iter == vecUserId.cend()) - { - showWarning(tr("%1输入名称不存在!").arg(str)); - return false; - } - - if(guard && !getGuardPerm(usergId)) - { - showWarning(tr("%1无遥控监护权限!").arg(str)); - return false; - } - else if(!guard && !getSeqCtrlPerm(usergId)) - { - showWarning(tr("%1无顺控执行权限!").arg(str)); - return false; - } - - int valid = m_ptrPermMng->CheckUserValid(userName, password); - switch (valid) { - case PERM_NO_NAME: - { - showWarning(tr("%1输入名称不存在!").arg(str)); - return false; - } - case PERM_NODE_DENY: - { - showWarning(tr("%1不允许在该节点登录!").arg(str)); - return false; - } - case PERM_PASSWORD_ERROR: - { - showWarning(tr("%1用户口令错误!").arg(str)); - return false; - } - case PERM_USER_EXPIRED: - { - showWarning(tr("%1用户已失效!").arg(str)); - return false; - } - case PERM_USER_LOCKED: - { - showWarning(tr("%1用户已锁定!").arg(str)); - return false; - } - case PERM_USERG_ERROR: - { - showWarning(tr("%1用户不属于所选用户组!").arg(str)); - return false; - } - default: - break; - } - - if(valid < 0) - { - showWarning(tr("%1用户权限检查出错!").arg(str)); - return false; - } - return true; -} - -void CSeqPermDialog::showWarning(const QString &text) -{ - QMessageBox::warning(this, tr("提示"), text, QMessageBox::Ok); -} - -void CSeqPermDialog::slotOptUserGrpChange(int index) -{ - if(m_ptrPermMng == NULL) - { - return; - } - ui->m_optUserName->clear(); - int usergId = ui->m_optUserGroup->itemData(index).toInt(); - std::vector vecUserId; - m_ptrPermMng->GetUsersByUserg(usergId, vecUserId); - std::vector::iterator iter = vecUserId.begin(); - for(; iter != vecUserId.end(); iter++) - { - std::string strUserName; - m_ptrPermMng->GetUserNameByUserId(*iter, strUserName); - ui->m_optUserName->addItem(QString::fromStdString(strUserName), *iter); - } -} - -void CSeqPermDialog::slotOptUserChange(int index) -{ - if(m_ptrPermMng == NULL) - { - return; - } - ui->m_optPassword->clear(); - ui->m_optUserAlias->clear(); - int userId = ui->m_optUserName->itemData(index).toInt(); - std::string strUserAlias; - m_ptrPermMng->GetUserAliasByUserId(userId, strUserAlias); - ui->m_optUserAlias->setText(QString::fromStdString(strUserAlias)); -} - -void CSeqPermDialog::slotGuardUserGrpChange(int index) -{ - m_vecUserId.clear(); - if(m_ptrPermMng == NULL) - { - return; - } - ui->m_guardUserName->clear(); - int usergId = ui->m_guardUserGroup->itemData(index).toInt(); - m_ptrPermMng->GetUsersByUserg(usergId, m_vecUserId); - std::vector::iterator iter = m_vecUserId.begin(); - for(; iter != m_vecUserId.end(); iter++) - { - if(*iter <= 10) - { - continue; - } - std::string strUserName; - m_ptrPermMng->GetUserNameByUserId(*iter, strUserName); - ui->m_guardUserName->addItem(QString::fromStdString(strUserName), *iter); - } -} - -void CSeqPermDialog::slotGuardUserChange(int index) -{ - slotGuardUserChange(); -} - -void CSeqPermDialog::slotGuardUserChange(QString text) -{ - slotGuardUserChange(); -} - -void CSeqPermDialog::slotGuardUserChange() -{ - if(m_ptrPermMng == NULL) - { - return; - } - ui->m_guardPassword->clear(); - ui->m_guardUserAlias->clear(); - std::string strPermName = ui->m_guardUserName->currentText().toStdString(); - int nPermId; - if(PERM_NORMAL != m_ptrPermMng->GetUserIdByUserName(strPermName, nPermId)) - { - return; - } - std::vector::const_iterator iter = m_vecUserId.cbegin(); - for(; iter != m_vecUserId.cend(); iter++) - { - if(*iter == nPermId) - { - std::string strUserAlias; - m_ptrPermMng->GetUserAliasByUserId(nPermId, strUserAlias); - ui->m_guardUserAlias->setText(QString::fromStdString(strUserAlias)); - break; - } - } -} - -void CSeqPermDialog::slotLogin() -{ - std::string strOptUserName = ui->m_optUserName->currentText().toStdString(); - std::string strOptPassword = ui->m_optPassword->text().toStdString(); - int optUsergId = ui->m_optUserGroup->currentData().toInt(); - int optUserId = ui->m_optUserName->currentData().toInt(); - std::string strOptUserAlias = ui->m_optUserAlias->text().toStdString(); - - if(!checkLogin(strOptUserName, strOptPassword, optUsergId, optUserId, false)) - { - return; - } - - m_nUserId = optUserId; - m_strUsrName = strOptUserAlias; - m_nUserGrpId = optUsergId; - - if(!m_isGuard) - { - accept(); - return; - } - - std::string strGuardUserName = ui->m_guardUserName->currentText().toStdString(); - std::string strGuardPassword = ui->m_guardPassword->text().toStdString(); - int guardUsergId = ui->m_guardUserGroup->currentData().toInt(); - int guardUserId; - if(PERM_NORMAL != m_ptrPermMng->GetUserIdByUserName(strGuardUserName, guardUserId)) - { - showWarning(tr("监护验证: 输入账号有误!")); - return; - } - if(optUserId == guardUserId) - { - showWarning(tr("监护人和操作人不能为同一人!")); - return; - } - if(!checkLogin(strGuardUserName, strGuardPassword, guardUsergId, guardUserId, true)) - { - return; - } - accept(); -} - -void CSeqPermDialog::slotCancel() -{ - reject(); -} - +#include "CSeqPermDialog.h" +#include "ui_CSeqPermDialog.h" +#include +#include + +CSeqPermDialog::CSeqPermDialog(QWidget *parent, bool gurad) : + QDialog(parent), + ui(new Ui::CSeqPermDialog), + m_ptrPermMng(NULL), + m_isGuard(true), + m_nUserId(-1), + m_strUsrName(""), + m_nUserGrpId(-1) +{ + ui->setupUi(this); + + initView(gurad); + + if(initPermMng()) + { + initUserGroup(); + } +} + +CSeqPermDialog::~CSeqPermDialog() +{ + delete ui; +} + +int CSeqPermDialog::getUserId() +{ + return m_nUserId; +} + +std::string CSeqPermDialog::getUserName() +{ + return m_strUsrName; +} + +int CSeqPermDialog::getUserGrpId() +{ + return m_nUserGrpId; +} + +void CSeqPermDialog::initView(bool guard) +{ + m_isGuard = guard; + ui->m_optUserGroup->setEnabled(false); + ui->m_optUserName->setEnabled(false); + ui->m_optUserName->setEditable(true); + ui->m_optUserAlias->setReadOnly(true); + ui->m_optPassword->setEchoMode(QLineEdit::Password); + ui->m_guardUserName->setEditable(true); + ui->m_guardUserAlias->setReadOnly(true); + ui->m_guardPassword->setEchoMode(QLineEdit::Password); + ui->m_guardFrame->setVisible(guard); + guard ? resize(400,230) : resize(240,230); + + connect(ui->m_optUserGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(slotOptUserGrpChange(int))); + connect(ui->m_optUserName, SIGNAL(currentIndexChanged(int)), this, SLOT(slotOptUserChange(int))); + connect(ui->m_guardUserGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(slotGuardUserGrpChange(int))); + connect(ui->m_guardUserName, SIGNAL(currentIndexChanged(int)), this, SLOT(slotGuardUserChange(int))); + connect(ui->m_guardUserName, SIGNAL(currentTextChanged(QString)), this, SLOT(slotGuardUserChange(QString))); + connect(ui->m_login, SIGNAL(clicked()), this, SLOT(slotLogin())); + connect(ui->m_cancel, SIGNAL(clicked()), this, SLOT(slotCancel())); +} + +bool CSeqPermDialog::initPermMng() +{ + m_ptrPermMng = kbd_service::getPermMngInstance("base"); + int result = m_ptrPermMng->PermDllInit(); + if(result < 0) + { + setEnabled(false); + return false; + } + return true; +} + +void CSeqPermDialog::initUserGroup() +{ + if(m_ptrPermMng == NULL) + { + return; + } + std::vector vecUsergId; + m_ptrPermMng->getAllUsergID(vecUsergId); + std::vector::iterator iter = vecUsergId.begin(); + for(; iter != vecUsergId.end(); iter++) + { + ui->m_optUserGroup->addItem(QString::fromStdString(iter->userg_name), iter->userg_id); + ui->m_guardUserGroup->addItem(QString::fromStdString(iter->userg_name), iter->userg_id); + } + + int nUserId; + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string instanceName; + if(PERM_NORMAL == m_ptrPermMng->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, instanceName)) + { + int userGrpIndex = ui->m_optUserGroup->findData(nUserGrpId); + ui->m_optUserGroup->setCurrentIndex(userGrpIndex); + + int userNameIndex = ui->m_optUserName->findData(nUserId); + ui->m_optUserName->setCurrentIndex(userNameIndex); + } +} + +bool CSeqPermDialog::getSeqCtrlPerm(int usergId) +{ + if(m_ptrPermMng == NULL) + { + return false; + } + std::string tmp = FUNC_NOM_PSCADA_SEQ_CTRL; + if (PERM_PERMIT == m_ptrPermMng->PermCheck(PERM_NOM_FUNC_DEF, &tmp, usergId)) + { + return true; + } + return false; +} + +bool CSeqPermDialog::getGuardPerm(int usergId) +{ + if(m_ptrPermMng == NULL) + { + return false; + } + std::string tmp = FUNC_NOM_GUARD_CTRL; + if (PERM_PERMIT == m_ptrPermMng->PermCheck(PERM_NOM_FUNC_DEF, &tmp, usergId)) + { + return true; + } + return false; +} + +bool CSeqPermDialog::checkLogin(const std::string &userName, const std::string &password, int usergId, int userId, bool guard) +{ + if(m_ptrPermMng == NULL) + { + return false; + } + QString str; + if(guard){ + str = tr("监护验证: "); + }else{ + str = tr("操作验证: "); + } + + std::vector vecUserId; + m_ptrPermMng->GetUsersByUserg(usergId, vecUserId); + std::vector::const_iterator iter = vecUserId.cbegin(); + for(; iter != vecUserId.cend(); iter++) + { + if(*iter == userId) + { + break; + } + } + if(iter == vecUserId.cend()) + { + showWarning(tr("%1输入名称不存在!").arg(str)); + return false; + } + + if(guard && !getGuardPerm(usergId)) + { + showWarning(tr("%1无遥控监护权限!").arg(str)); + return false; + } + else if(!guard && !getSeqCtrlPerm(usergId)) + { + showWarning(tr("%1无顺控执行权限!").arg(str)); + return false; + } + + int valid = m_ptrPermMng->CheckUserValid(userName, password); + switch (valid) { + case PERM_NO_NAME: + { + showWarning(tr("%1输入名称不存在!").arg(str)); + return false; + } + case PERM_NODE_DENY: + { + showWarning(tr("%1不允许在该节点登录!").arg(str)); + return false; + } + case PERM_PASSWORD_ERROR: + { + showWarning(tr("%1用户口令错误!").arg(str)); + return false; + } + case PERM_USER_EXPIRED: + { + showWarning(tr("%1用户已失效!").arg(str)); + return false; + } + case PERM_USER_LOCKED: + { + showWarning(tr("%1用户已锁定!").arg(str)); + return false; + } + case PERM_USERG_ERROR: + { + showWarning(tr("%1用户不属于所选用户组!").arg(str)); + return false; + } + default: + break; + } + + if(valid < 0) + { + showWarning(tr("%1用户权限检查出错!").arg(str)); + return false; + } + return true; +} + +void CSeqPermDialog::showWarning(const QString &text) +{ + QMessageBox::warning(this, tr("提示"), text, QMessageBox::Ok); +} + +void CSeqPermDialog::slotOptUserGrpChange(int index) +{ + if(m_ptrPermMng == NULL) + { + return; + } + ui->m_optUserName->clear(); + int usergId = ui->m_optUserGroup->itemData(index).toInt(); + std::vector vecUserId; + m_ptrPermMng->GetUsersByUserg(usergId, vecUserId); + std::vector::iterator iter = vecUserId.begin(); + for(; iter != vecUserId.end(); iter++) + { + std::string strUserName; + m_ptrPermMng->GetUserNameByUserId(*iter, strUserName); + ui->m_optUserName->addItem(QString::fromStdString(strUserName), *iter); + } +} + +void CSeqPermDialog::slotOptUserChange(int index) +{ + if(m_ptrPermMng == NULL) + { + return; + } + ui->m_optPassword->clear(); + ui->m_optUserAlias->clear(); + int userId = ui->m_optUserName->itemData(index).toInt(); + std::string strUserAlias; + m_ptrPermMng->GetUserAliasByUserId(userId, strUserAlias); + ui->m_optUserAlias->setText(QString::fromStdString(strUserAlias)); +} + +void CSeqPermDialog::slotGuardUserGrpChange(int index) +{ + m_vecUserId.clear(); + if(m_ptrPermMng == NULL) + { + return; + } + ui->m_guardUserName->clear(); + int usergId = ui->m_guardUserGroup->itemData(index).toInt(); + m_ptrPermMng->GetUsersByUserg(usergId, m_vecUserId); + std::vector::iterator iter = m_vecUserId.begin(); + for(; iter != m_vecUserId.end(); iter++) + { + if(*iter <= 10) + { + continue; + } + std::string strUserName; + m_ptrPermMng->GetUserNameByUserId(*iter, strUserName); + ui->m_guardUserName->addItem(QString::fromStdString(strUserName), *iter); + } +} + +void CSeqPermDialog::slotGuardUserChange(int index) +{ + slotGuardUserChange(); +} + +void CSeqPermDialog::slotGuardUserChange(QString text) +{ + slotGuardUserChange(); +} + +void CSeqPermDialog::slotGuardUserChange() +{ + if(m_ptrPermMng == NULL) + { + return; + } + ui->m_guardPassword->clear(); + ui->m_guardUserAlias->clear(); + std::string strPermName = ui->m_guardUserName->currentText().toStdString(); + int nPermId; + if(PERM_NORMAL != m_ptrPermMng->GetUserIdByUserName(strPermName, nPermId)) + { + return; + } + std::vector::const_iterator iter = m_vecUserId.cbegin(); + for(; iter != m_vecUserId.cend(); iter++) + { + if(*iter == nPermId) + { + std::string strUserAlias; + m_ptrPermMng->GetUserAliasByUserId(nPermId, strUserAlias); + ui->m_guardUserAlias->setText(QString::fromStdString(strUserAlias)); + break; + } + } +} + +void CSeqPermDialog::slotLogin() +{ + std::string strOptUserName = ui->m_optUserName->currentText().toStdString(); + std::string strOptPassword = ui->m_optPassword->text().toStdString(); + int optUsergId = ui->m_optUserGroup->currentData().toInt(); + int optUserId = ui->m_optUserName->currentData().toInt(); + std::string strOptUserAlias = ui->m_optUserAlias->text().toStdString(); + + if(!checkLogin(strOptUserName, strOptPassword, optUsergId, optUserId, false)) + { + return; + } + + m_nUserId = optUserId; + m_strUsrName = strOptUserAlias; + m_nUserGrpId = optUsergId; + + if(!m_isGuard) + { + accept(); + return; + } + + std::string strGuardUserName = ui->m_guardUserName->currentText().toStdString(); + std::string strGuardPassword = ui->m_guardPassword->text().toStdString(); + int guardUsergId = ui->m_guardUserGroup->currentData().toInt(); + int guardUserId; + if(PERM_NORMAL != m_ptrPermMng->GetUserIdByUserName(strGuardUserName, guardUserId)) + { + showWarning(tr("监护验证: 输入账号有误!")); + return; + } + if(optUserId == guardUserId) + { + showWarning(tr("监护人和操作人不能为同一人!")); + return; + } + if(!checkLogin(strGuardUserName, strGuardPassword, guardUsergId, guardUserId, true)) + { + return; + } + accept(); +} + +void CSeqPermDialog::slotCancel() +{ + reject(); +} + diff --git a/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.h b/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.h index f3b4a031..23bd274e 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.h +++ b/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.h @@ -1,57 +1,57 @@ -#ifndef CSEQPERMDIALOG_H -#define CSEQPERMDIALOG_H - -#include -#include "perm_mng_api/PermMngApi.h" - -//< 顺控执行权限定义 -#define FUNC_NOM_PSCADA_SEQ_CTRL ("FUNC_NOM_PSCADA_SEQ_CTRL") -//< 遥控监护权限定义 -#define FUNC_NOM_GUARD_CTRL ("FUNC_NOM_GUARD_CTRL") - -namespace Ui { -class CSeqPermDialog; -} - -class CSeqPermDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CSeqPermDialog(QWidget *parent = 0, bool guard = true); - ~CSeqPermDialog(); - - int getUserId(); - std::string getUserName(); - int getUserGrpId(); - -private: - void initView(bool guard = true); - bool initPermMng(); - void initUserGroup(); - bool getSeqCtrlPerm(int usergId); - bool getGuardPerm(int usergId); - bool checkLogin(const std::string &userName, const std::string &password, int usergId, int userId, bool guard); - void showWarning(const QString &text); - -private slots: - void slotOptUserGrpChange(int index); - void slotOptUserChange(int index); - void slotGuardUserGrpChange(int index); - void slotGuardUserChange(int index); - void slotGuardUserChange(QString text); - void slotGuardUserChange(); - void slotLogin(); - void slotCancel(); - -private: - Ui::CSeqPermDialog * ui; - kbd_service::CPermMngApiPtr m_ptrPermMng; - bool m_isGuard; - int m_nUserId; - std::string m_strUsrName; - int m_nUserGrpId; - std::vector m_vecUserId; -}; - -#endif // CSEQPERMDIALOG_H +#ifndef CSEQPERMDIALOG_H +#define CSEQPERMDIALOG_H + +#include +#include "perm_mng_api/PermMngApi.h" + +//< 顺控执行权限定义 +#define FUNC_NOM_PSCADA_SEQ_CTRL ("FUNC_NOM_PSCADA_SEQ_CTRL") +//< 遥控监护权限定义 +#define FUNC_NOM_GUARD_CTRL ("FUNC_NOM_GUARD_CTRL") + +namespace Ui { +class CSeqPermDialog; +} + +class CSeqPermDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CSeqPermDialog(QWidget *parent = 0, bool guard = true); + ~CSeqPermDialog(); + + int getUserId(); + std::string getUserName(); + int getUserGrpId(); + +private: + void initView(bool guard = true); + bool initPermMng(); + void initUserGroup(); + bool getSeqCtrlPerm(int usergId); + bool getGuardPerm(int usergId); + bool checkLogin(const std::string &userName, const std::string &password, int usergId, int userId, bool guard); + void showWarning(const QString &text); + +private slots: + void slotOptUserGrpChange(int index); + void slotOptUserChange(int index); + void slotGuardUserGrpChange(int index); + void slotGuardUserChange(int index); + void slotGuardUserChange(QString text); + void slotGuardUserChange(); + void slotLogin(); + void slotCancel(); + +private: + Ui::CSeqPermDialog * ui; + kbd_service::CPermMngApiPtr m_ptrPermMng; + bool m_isGuard; + int m_nUserId; + std::string m_strUsrName; + int m_nUserGrpId; + std::vector m_vecUserId; +}; + +#endif // CSEQPERMDIALOG_H diff --git a/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.ui b/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.ui index 099a259c..f6eaeb6d 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.ui +++ b/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.ui @@ -1,296 +1,296 @@ - - - CSeqPermDialog - - - - 0 - 0 - 389 - 205 - - - - 验证 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - - - - 16777215 - 25 - - - - 操作验证 - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 138 - 20 - - - - - - - - - - - - - - 用户组 - - - - - - - 姓名 - - - - - - - 密码 - - - - - - - 账号 - - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - - - 账号 - - - - - - - 姓名 - - - - - - - 密码 - - - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 138 - 20 - - - - - - - - - 16777215 - 25 - - - - 监护验证 - - - - - - - - - - 用户组 - - - - - - - - - - - - - 6 - - - 0 - - - 0 - - - 6 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 验证 - - - - - - - 取消 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - + + + CSeqPermDialog + + + + 0 + 0 + 389 + 205 + + + + 验证 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + + + + 16777215 + 25 + + + + 操作验证 + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 138 + 20 + + + + + + + + + + + + + + 用户组 + + + + + + + 姓名 + + + + + + + 密码 + + + + + + + 账号 + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + + + 账号 + + + + + + + 姓名 + + + + + + + 密码 + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 138 + 20 + + + + + + + + + 16777215 + 25 + + + + 监护验证 + + + + + + + + + + 用户组 + + + + + + + + + + + + + 6 + + + 0 + + + 0 + + + 6 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 验证 + + + + + + + 取消 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.cpp b/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.cpp index 42964980..9596291a 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.cpp @@ -1,421 +1,421 @@ -#include "CSequenceDataManage.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "../../idl_files/SequenceMessage.pb.h" -#include "../../idl_files/RdbServerMessage.pb.h" - -using namespace kbd_dbms; -using namespace kbd_idlfile; - -CSequenceDataManage::CSequenceDataManage(QObject *parent, CDbApi *dbRead) - : QObject(parent), - m_pReadDb(dbRead), - m_rtdbAccessEx(NULL), - m_isInitDb(false) -{ - if(m_pReadDb == NULL) - { - initDataBase(); - } - initRdbDataBase(); -} - -CSequenceDataManage::~CSequenceDataManage() -{ - QMutexLocker locker(&mutex); - if(m_pReadDb && m_isInitDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(m_rtdbAccessEx) - { - delete m_rtdbAccessEx; - } - m_rtdbAccessEx = NULL; -} - -void CSequenceDataManage::initDataBase() -{ - m_isInitDb = true; - //关系库 - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); -} - -void CSequenceDataManage::initRdbDataBase() -{ - //实时库 - m_rtdbAccessEx = new CRdbAccessEx(); -} - -void CSequenceDataManage::recvSequenceResponse(kbd_idlfile::sequence::SeqOperateMessageAck &msg) -{ - if(msg.has_seq_node()) - { - kbd_idlfile::sequence::SeqNodeStatusParameter* sequenceNode = msg.mutable_seq_node(); - QString seqName = QString::fromStdString(sequenceNode->seq_name()); - E_SEQ_OPERATE type = (E_SEQ_OPERATE)msg.opreate_type(); - kbd_idlfile::sequence::ExecuteStatusParameter * status = msg.mutable_execute_status(); - - //< status->statuscode() 状态码 0为成功 非零为错误状态 - if(!status->statuscode()) - { - emit sigRecvSequenceResponse(seqName, type); - } - else - { - if(status->has_erro_param()) - { - kbd_idlfile::sequence::ErrorParameter * error = status->mutable_erro_param(); - QString strErrorInfo = QString::fromStdString(error->errordescription()); - emit sigRecvSequenceResponseErrorMsg(seqName, type, strErrorInfo); - } - } - } -} - -void CSequenceDataManage::recvUserInterveneRequest(kbd_idlfile::sequence::UiRequestMessage &msg) -{ - kbd_idlfile::sequence::UiRequestMessage * requestMessage = new kbd_idlfile::sequence::UiRequestMessage(msg); - emit sigRecvUserInterveneRequest(requestMessage); -} - -void CSequenceDataManage::recvSeqStateChange(kbd_idlfile::sequence::StatusChangeMessage &msg) -{ - for(int nIndex(0); nIndex < msg.execute_status_size(); nIndex++) - { - kbd_idlfile::sequence::ExecuteStatusParameter statusParameter = msg.execute_status(nIndex); - if(statusParameter.statuscode() != 0) - { - QString strSeqName = QString::fromStdString(msg.mutable_nodelist()->seq_name()); - int nErrorCode = statusParameter.erro_param().errorcode(); - QString strErrorDecription = QString::fromStdString(statusParameter.erro_param().errordescription()); - emit sigRecvSequenceStateError(strSeqName, nErrorCode, strErrorDecription); - } - } - - kbd_idlfile::sequence::SeqNodeStatusParameter sequence = msg.nodelist(); - QString strSeqName = QString::fromStdString(sequence.seq_name()); - if(sequence.nodelist_size() == 0) - { - E_EXECUTING_STATE state = (E_EXECUTING_STATE)sequence.node_state(); - emit sigRecvSequenceStateChanged(strSeqName, state); - } - else - { - for(int nIndex(0); nIndex < sequence.nodelist_size(); nIndex++) - { - kbd_idlfile::sequence::FucNodeStatusParameter funcNode = sequence.nodelist(nIndex); - QString strFuncName = QString::fromStdString(funcNode.fuc_name()); - if(funcNode.nodelist_size() == 0) - { - E_EXECUTING_STATE state = (E_EXECUTING_STATE)funcNode.node_state(); - emit sigRecvFunctionStateChanged(strSeqName, strFuncName, state); - } - else - { - for(int nActionIndex(0); nActionIndex < funcNode.nodelist_size(); nActionIndex++) - { - kbd_idlfile::sequence::ActionNodeStatusParameter actionNode = funcNode.nodelist(nActionIndex); - QString strActionName = QString::fromStdString(actionNode.action_name()); - E_EXECUTING_STATE actionState = (E_EXECUTING_STATE)actionNode.node_state(); - emit sigRecvActionStateChanged(strSeqName, strFuncName, strActionName,actionState); - } - } - } - } -} - -QString CSequenceDataManage::queryLocationName(const int &nLocationID) -{ - QMutexLocker locker(&mutex); - QString locationName = QString(); - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("description"); - - CONDINFO conditionName; - conditionName.logicalop = ATTRCOND_AND; - conditionName.relationop = ATTRCOND_EQU; - memcpy(conditionName.name, "location_id",strlen("location_id") ); - conditionName.conditionval = nLocationID; - - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccessEx->select(conditionName, result, columns, sOrderColumn)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - locationName = QString::fromStdString(value.toStdString()); - } - } - } - m_rtdbAccessEx->close(); - return locationName; -} - -QString CSequenceDataManage::queryTagName(const QString &strTableName, const QString &strTaginfo) -{ - QMutexLocker locker(&mutex); - if(strTaginfo.isEmpty()) - { - return QString(); - } - - QString strTagName; - if(!m_pReadDb->isOpen()) - { - return QString(); - } - QSqlQuery query; - QString sqlQuery = QString("select description from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - strTagName = query.value(0).toString(); - } - } - return strTagName; -} - -QString CSequenceDataManage::queryTagTextName(const QString &strTableName, const QString &strTaginfo) -{ - QMutexLocker locker(&mutex); - if(strTaginfo.isEmpty()) - { - return QString(); - } - - QString strTagTextName; - if(!m_pReadDb->isOpen()) - { - return QString(); - } - QSqlQuery query; - QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName.toLower()).arg(strTaginfo.toLower()); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - strTagTextName = query.value(0).toString(); - } - } - return strTagTextName; -} - -QString CSequenceDataManage::queryStateName(const QString &strStateTextName, const int &nActualValue) -{ - QMutexLocker locker(&mutex); - QString strStateName; - std::string strApplicationName = "base"; - std::string strTableName = "dict_state_text_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - - std::vector vecCondInfo; - CONDINFO conditionName; - conditionName.logicalop = ATTRCOND_AND; - conditionName.relationop = ATTRCOND_EQU; - memcpy(conditionName.name, "state_text_name", strlen("state_text_name")); - conditionName.conditionval = strStateTextName.toStdString(); - vecCondInfo.push_back(conditionName); - - CONDINFO conditionState; - conditionState.logicalop = ATTRCOND_AND; - conditionState.relationop = ATTRCOND_EQU; - memcpy(conditionState.name, "actual_value", strlen("actual_value") ); - conditionState.conditionval = nActualValue; - vecCondInfo.push_back(conditionState); - - - kbd_dbms::CRdbQueryResult result; - - std::vector columns; - columns.push_back("display_value"); - - if(m_rtdbAccessEx->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType value; - result.getColumnValue(nIndex, 0, value); - strStateName = QString::fromStdString(value.toStdString()); - } - } - } - m_rtdbAccessEx->close(); - return strStateName; -} - -QList CSequenceDataManage::querySequenceList(const QStringList &seqNameList) -{ - QList sequenceList; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - return sequenceList; - } - - QStringList strLoaclDomainSequenceName; - if(!m_pReadDb->isOpen()) - { - return sequenceList; - } - //<查询顺控 - QSqlQuery query; - QString sqlSequenceQuery = QString("select name, description, seq_type, location_id, timeflag from %1").arg(SEQUENCE_SETTING); - m_pReadDb->execute(sqlSequenceQuery, query); - if(query.isActive()) - { - while(query.next()) - { - QString seqName = query.value(0).toString(); - if(seqNameList.contains(seqName)) - { - Sequence sequence; - sequence.seqName = seqName; - sequence.seqDescription = query.value(1).toString(); - sequence.seqType = query.value(2).toInt(); - sequence.locationID = query.value(3).toInt(); - sequence.location = queryLocationName(sequence.locationID); - sequence.timeFlag = query.value(4).toULongLong(); - sequence.nodeType = E_Node_Sequence; - sequenceList.append(sequence); - strLoaclDomainSequenceName.append(seqName); - } - } - } - - //<查询功能 - QList functionList; - QString sqlFunctionQuery = QString("SELECT DISTINCT\ - %1.seq_name, \ - %1.func_name, \ - %2.description, \ - %1.func_no, \ - %1.timeflag \ - FROM \ - %1 LEFT JOIN %2 ON \ - %1.func_name = %2.name").arg(SEQUENCE_DEFINE).arg(SEQUENCE_FUNCTION); - m_pReadDb->execute(sqlFunctionQuery, query); - if(query.isActive()) - { - while(query.next()) - { - QString seqName = query.value(0).toString(); - if(seqNameList.contains(seqName) && strLoaclDomainSequenceName.contains(seqName)) - { - Sequence function; - function.seqName = seqName; - function.funcName = query.value(1).toString(); - function.funcDescription = query.value(2).toString(); - function.funcNo = query.value(3).toInt(); - function.timeFlag = query.value(4).toULongLong(); - function.nodeType = E_Node_Function; - - bool result = false; - for (int nIndex(0); nIndex < functionList.size(); nIndex++) - { - if (function.funcNo < functionList[nIndex].funcNo) - { - functionList.insert(nIndex, function); - result = true; - break; - } - } - if (!result) - { - functionList.append(function); - } - } - } - sequenceList.append(functionList); - } - - //<查询动作 - for(int functionIndex(0); functionIndex < functionList.size(); functionIndex++) - { - QList actionList; - QString sqlActionQuery = QString("SELECT \ - %1.seq_name, \ - %1.func_name, \ - %1.func_no, \ - %2.action_name, \ - %2.action_no, \ - %2.delaytime, \ - %3.key_id_tag, \ - %3.timeflag, \ - %3.target_value, \ - %3.location_id, \ - %3.sub_system, \ - %3.description \ - FROM \ - %1, %2, %3 \ - WHERE \ - %1.func_name = '%4' \ - AND %1.func_name = %2.name \ - AND %2.action_name = %3.name").arg(SEQUENCE_DEFINE).arg(SEQUENCE_FUNCTION).arg(SEQUENCE_ACTION).arg(functionList[functionIndex].funcName); - - m_pReadDb->execute(sqlActionQuery, query); - if(query.isActive()) - { - while(query.next()) - { - QString seqName = query.value(0).toString(); - if(seqNameList.contains(seqName) && strLoaclDomainSequenceName.contains(seqName)) - { - Sequence action; - action.seqName = seqName; - action.funcName = query.value(1).toString(); - action.funcNo = query.value(2).toInt(); - action.actionName = query.value(3).toString(); - action.actionNo = query.value(4).toInt(); - action.delay = query.value(5).toInt(); - action.tagInfo = query.value(6).toString(); - QStringList strListTagInfo = action.tagInfo.split("."); - action.tagName = queryTagName(strListTagInfo.first(), action.tagInfo.section(".", 1, strListTagInfo.size() - 2)); - action.timeFlag = query.value(7).toULongLong(); - QString strTagTextName = queryTagTextName(strListTagInfo.first(), action.tagInfo.section(".", 1, strListTagInfo.size() - 2)); - action.targetState = queryStateName(strTagTextName, query.value(8).toInt()); - action.locationID = query.value(9).toInt(); - action.location = queryLocationName(action.locationID); - action.subSystemID = query.value(10).toInt(); - action.actionDescription = query.value(11).toString(); - action.nodeType = E_Node_Action; - - bool result = false; - for (int nIndex(0); nIndex < actionList.size(); nIndex++) - { - if (action.actionNo < actionList[nIndex].actionNo) - { - actionList.insert(nIndex, action); - result = true; - break; - } - } - if (!result) - { - actionList.append(action); - } - } - } - sequenceList.append(actionList); - } - } - return sequenceList; -} - - +#include "CSequenceDataManage.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "../../idl_files/SequenceMessage.pb.h" +#include "../../idl_files/RdbServerMessage.pb.h" + +using namespace kbd_dbms; +using namespace kbd_idlfile; + +CSequenceDataManage::CSequenceDataManage(QObject *parent, CDbApi *dbRead) + : QObject(parent), + m_pReadDb(dbRead), + m_rtdbAccessEx(NULL), + m_isInitDb(false) +{ + if(m_pReadDb == NULL) + { + initDataBase(); + } + initRdbDataBase(); +} + +CSequenceDataManage::~CSequenceDataManage() +{ + QMutexLocker locker(&mutex); + if(m_pReadDb && m_isInitDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbAccessEx) + { + delete m_rtdbAccessEx; + } + m_rtdbAccessEx = NULL; +} + +void CSequenceDataManage::initDataBase() +{ + m_isInitDb = true; + //关系库 + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); +} + +void CSequenceDataManage::initRdbDataBase() +{ + //实时库 + m_rtdbAccessEx = new CRdbAccessEx(); +} + +void CSequenceDataManage::recvSequenceResponse(kbd_idlfile::sequence::SeqOperateMessageAck &msg) +{ + if(msg.has_seq_node()) + { + kbd_idlfile::sequence::SeqNodeStatusParameter* sequenceNode = msg.mutable_seq_node(); + QString seqName = QString::fromStdString(sequenceNode->seq_name()); + E_SEQ_OPERATE type = (E_SEQ_OPERATE)msg.opreate_type(); + kbd_idlfile::sequence::ExecuteStatusParameter * status = msg.mutable_execute_status(); + + //< status->statuscode() 状态码 0为成功 非零为错误状态 + if(!status->statuscode()) + { + emit sigRecvSequenceResponse(seqName, type); + } + else + { + if(status->has_erro_param()) + { + kbd_idlfile::sequence::ErrorParameter * error = status->mutable_erro_param(); + QString strErrorInfo = QString::fromStdString(error->errordescription()); + emit sigRecvSequenceResponseErrorMsg(seqName, type, strErrorInfo); + } + } + } +} + +void CSequenceDataManage::recvUserInterveneRequest(kbd_idlfile::sequence::UiRequestMessage &msg) +{ + kbd_idlfile::sequence::UiRequestMessage * requestMessage = new kbd_idlfile::sequence::UiRequestMessage(msg); + emit sigRecvUserInterveneRequest(requestMessage); +} + +void CSequenceDataManage::recvSeqStateChange(kbd_idlfile::sequence::StatusChangeMessage &msg) +{ + for(int nIndex(0); nIndex < msg.execute_status_size(); nIndex++) + { + kbd_idlfile::sequence::ExecuteStatusParameter statusParameter = msg.execute_status(nIndex); + if(statusParameter.statuscode() != 0) + { + QString strSeqName = QString::fromStdString(msg.mutable_nodelist()->seq_name()); + int nErrorCode = statusParameter.erro_param().errorcode(); + QString strErrorDecription = QString::fromStdString(statusParameter.erro_param().errordescription()); + emit sigRecvSequenceStateError(strSeqName, nErrorCode, strErrorDecription); + } + } + + kbd_idlfile::sequence::SeqNodeStatusParameter sequence = msg.nodelist(); + QString strSeqName = QString::fromStdString(sequence.seq_name()); + if(sequence.nodelist_size() == 0) + { + E_EXECUTING_STATE state = (E_EXECUTING_STATE)sequence.node_state(); + emit sigRecvSequenceStateChanged(strSeqName, state); + } + else + { + for(int nIndex(0); nIndex < sequence.nodelist_size(); nIndex++) + { + kbd_idlfile::sequence::FucNodeStatusParameter funcNode = sequence.nodelist(nIndex); + QString strFuncName = QString::fromStdString(funcNode.fuc_name()); + if(funcNode.nodelist_size() == 0) + { + E_EXECUTING_STATE state = (E_EXECUTING_STATE)funcNode.node_state(); + emit sigRecvFunctionStateChanged(strSeqName, strFuncName, state); + } + else + { + for(int nActionIndex(0); nActionIndex < funcNode.nodelist_size(); nActionIndex++) + { + kbd_idlfile::sequence::ActionNodeStatusParameter actionNode = funcNode.nodelist(nActionIndex); + QString strActionName = QString::fromStdString(actionNode.action_name()); + E_EXECUTING_STATE actionState = (E_EXECUTING_STATE)actionNode.node_state(); + emit sigRecvActionStateChanged(strSeqName, strFuncName, strActionName,actionState); + } + } + } + } +} + +QString CSequenceDataManage::queryLocationName(const int &nLocationID) +{ + QMutexLocker locker(&mutex); + QString locationName = QString(); + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("description"); + + CONDINFO conditionName; + conditionName.logicalop = ATTRCOND_AND; + conditionName.relationop = ATTRCOND_EQU; + memcpy(conditionName.name, "location_id",strlen("location_id") ); + conditionName.conditionval = nLocationID; + + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccessEx->select(conditionName, result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + locationName = QString::fromStdString(value.toStdString()); + } + } + } + m_rtdbAccessEx->close(); + return locationName; +} + +QString CSequenceDataManage::queryTagName(const QString &strTableName, const QString &strTaginfo) +{ + QMutexLocker locker(&mutex); + if(strTaginfo.isEmpty()) + { + return QString(); + } + + QString strTagName; + if(!m_pReadDb->isOpen()) + { + return QString(); + } + QSqlQuery query; + QString sqlQuery = QString("select description from %1 where tag_name = '%2'").arg(strTableName).arg(strTaginfo); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + strTagName = query.value(0).toString(); + } + } + return strTagName; +} + +QString CSequenceDataManage::queryTagTextName(const QString &strTableName, const QString &strTaginfo) +{ + QMutexLocker locker(&mutex); + if(strTaginfo.isEmpty()) + { + return QString(); + } + + QString strTagTextName; + if(!m_pReadDb->isOpen()) + { + return QString(); + } + QSqlQuery query; + QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName.toLower()).arg(strTaginfo.toLower()); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + strTagTextName = query.value(0).toString(); + } + } + return strTagTextName; +} + +QString CSequenceDataManage::queryStateName(const QString &strStateTextName, const int &nActualValue) +{ + QMutexLocker locker(&mutex); + QString strStateName; + std::string strApplicationName = "base"; + std::string strTableName = "dict_state_text_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + + std::vector vecCondInfo; + CONDINFO conditionName; + conditionName.logicalop = ATTRCOND_AND; + conditionName.relationop = ATTRCOND_EQU; + memcpy(conditionName.name, "state_text_name", strlen("state_text_name")); + conditionName.conditionval = strStateTextName.toStdString(); + vecCondInfo.push_back(conditionName); + + CONDINFO conditionState; + conditionState.logicalop = ATTRCOND_AND; + conditionState.relationop = ATTRCOND_EQU; + memcpy(conditionState.name, "actual_value", strlen("actual_value") ); + conditionState.conditionval = nActualValue; + vecCondInfo.push_back(conditionState); + + + kbd_dbms::CRdbQueryResult result; + + std::vector columns; + columns.push_back("display_value"); + + if(m_rtdbAccessEx->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + strStateName = QString::fromStdString(value.toStdString()); + } + } + } + m_rtdbAccessEx->close(); + return strStateName; +} + +QList CSequenceDataManage::querySequenceList(const QStringList &seqNameList) +{ + QList sequenceList; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + return sequenceList; + } + + QStringList strLoaclDomainSequenceName; + if(!m_pReadDb->isOpen()) + { + return sequenceList; + } + //<查询顺控 + QSqlQuery query; + QString sqlSequenceQuery = QString("select name, description, seq_type, location_id, timeflag from %1").arg(SEQUENCE_SETTING); + m_pReadDb->execute(sqlSequenceQuery, query); + if(query.isActive()) + { + while(query.next()) + { + QString seqName = query.value(0).toString(); + if(seqNameList.contains(seqName)) + { + Sequence sequence; + sequence.seqName = seqName; + sequence.seqDescription = query.value(1).toString(); + sequence.seqType = query.value(2).toInt(); + sequence.locationID = query.value(3).toInt(); + sequence.location = queryLocationName(sequence.locationID); + sequence.timeFlag = query.value(4).toULongLong(); + sequence.nodeType = E_Node_Sequence; + sequenceList.append(sequence); + strLoaclDomainSequenceName.append(seqName); + } + } + } + + //<查询功能 + QList functionList; + QString sqlFunctionQuery = QString("SELECT DISTINCT\ + %1.seq_name, \ + %1.func_name, \ + %2.description, \ + %1.func_no, \ + %1.timeflag \ + FROM \ + %1 LEFT JOIN %2 ON \ + %1.func_name = %2.name").arg(SEQUENCE_DEFINE).arg(SEQUENCE_FUNCTION); + m_pReadDb->execute(sqlFunctionQuery, query); + if(query.isActive()) + { + while(query.next()) + { + QString seqName = query.value(0).toString(); + if(seqNameList.contains(seqName) && strLoaclDomainSequenceName.contains(seqName)) + { + Sequence function; + function.seqName = seqName; + function.funcName = query.value(1).toString(); + function.funcDescription = query.value(2).toString(); + function.funcNo = query.value(3).toInt(); + function.timeFlag = query.value(4).toULongLong(); + function.nodeType = E_Node_Function; + + bool result = false; + for (int nIndex(0); nIndex < functionList.size(); nIndex++) + { + if (function.funcNo < functionList[nIndex].funcNo) + { + functionList.insert(nIndex, function); + result = true; + break; + } + } + if (!result) + { + functionList.append(function); + } + } + } + sequenceList.append(functionList); + } + + //<查询动作 + for(int functionIndex(0); functionIndex < functionList.size(); functionIndex++) + { + QList actionList; + QString sqlActionQuery = QString("SELECT \ + %1.seq_name, \ + %1.func_name, \ + %1.func_no, \ + %2.action_name, \ + %2.action_no, \ + %2.delaytime, \ + %3.key_id_tag, \ + %3.timeflag, \ + %3.target_value, \ + %3.location_id, \ + %3.sub_system, \ + %3.description \ + FROM \ + %1, %2, %3 \ + WHERE \ + %1.func_name = '%4' \ + AND %1.func_name = %2.name \ + AND %2.action_name = %3.name").arg(SEQUENCE_DEFINE).arg(SEQUENCE_FUNCTION).arg(SEQUENCE_ACTION).arg(functionList[functionIndex].funcName); + + m_pReadDb->execute(sqlActionQuery, query); + if(query.isActive()) + { + while(query.next()) + { + QString seqName = query.value(0).toString(); + if(seqNameList.contains(seqName) && strLoaclDomainSequenceName.contains(seqName)) + { + Sequence action; + action.seqName = seqName; + action.funcName = query.value(1).toString(); + action.funcNo = query.value(2).toInt(); + action.actionName = query.value(3).toString(); + action.actionNo = query.value(4).toInt(); + action.delay = query.value(5).toInt(); + action.tagInfo = query.value(6).toString(); + QStringList strListTagInfo = action.tagInfo.split("."); + action.tagName = queryTagName(strListTagInfo.first(), action.tagInfo.section(".", 1, strListTagInfo.size() - 2)); + action.timeFlag = query.value(7).toULongLong(); + QString strTagTextName = queryTagTextName(strListTagInfo.first(), action.tagInfo.section(".", 1, strListTagInfo.size() - 2)); + action.targetState = queryStateName(strTagTextName, query.value(8).toInt()); + action.locationID = query.value(9).toInt(); + action.location = queryLocationName(action.locationID); + action.subSystemID = query.value(10).toInt(); + action.actionDescription = query.value(11).toString(); + action.nodeType = E_Node_Action; + + bool result = false; + for (int nIndex(0); nIndex < actionList.size(); nIndex++) + { + if (action.actionNo < actionList[nIndex].actionNo) + { + actionList.insert(nIndex, action); + result = true; + break; + } + } + if (!result) + { + actionList.append(action); + } + } + } + sequenceList.append(actionList); + } + } + return sequenceList; +} + + diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.h b/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.h index ff5d727c..34ed08ba 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.h +++ b/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.h @@ -1,62 +1,62 @@ -#ifndef CSEQUENCEDATAMANAGE_H -#define CSEQUENCEDATAMANAGE_H - -#include -#include -#include "sequence_def.h" -#include "db_api_ex/CDbApi.h" -#include "dbms/rdb_api/CRdbAccessEx.h" -#include "../dbms/rdb_net_api/CRdbNetApi.h" -#include "CSequenceMsgHandle.h" - -#define SEQUENCE_SETTING ("sequence_setting") -#define SEQUENCE_DEFINE ("sequence_define") -#define SEQUENCE_FUNCTION ("sequence_function") -#define SEQUENCE_ACTION ("sequence_action") -#define COMAPP ("comapp") - -class CSequenceDataManage : public QObject -{ - Q_OBJECT - -public: - explicit CSequenceDataManage(QObject *parent = nullptr, kbd_dbms::CDbApi *dbRead = NULL); - ~CSequenceDataManage(); - - void initDataBase(); - - void initRdbDataBase(); - - void recvSequenceResponse(kbd_idlfile::sequence::SeqOperateMessageAck &msg); - - void recvUserInterveneRequest(kbd_idlfile::sequence::UiRequestMessage &msg); - - void recvSeqStateChange(kbd_idlfile::sequence::StatusChangeMessage &msg); - - QString queryLocationName(const int &nLocationID); - - QString queryTagName(const QString &strTableName, const QString &strTaginfo); - - QString queryTagTextName(const QString &strTableName, const QString &strTaginfo); - - QString queryStateName(const QString &strStateTextName, const int &nActualValue); - - QList querySequenceList(const QStringList &seqNameList); - -signals: - void sigRecvSequenceResponse(const QString &seqName, const E_SEQ_OPERATE &type); - void sigRecvSequenceResponseErrorMsg(const QString &seqName, const E_SEQ_OPERATE &type, const QString &errorInfo); - void sigRecvSequenceStateError(const QString &seqName, const int &errorCode, const QString &errorDescription); - void sigRecvSequenceStateChanged(const QString &seqName, const E_EXECUTING_STATE &state); - void sigRecvFunctionStateChanged(const QString &seqName, const QString &funcName, const E_EXECUTING_STATE &state); - void sigRecvActionStateChanged(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state); - void sigRecvUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage *msg); - -private: - QMutex mutex; - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccessEx * m_rtdbAccessEx; - bool m_isInitDb; -}; - -#endif // CSEQUENCEDATAMANAGE_H +#ifndef CSEQUENCEDATAMANAGE_H +#define CSEQUENCEDATAMANAGE_H + +#include +#include +#include "sequence_def.h" +#include "db_api_ex/CDbApi.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "../dbms/rdb_net_api/CRdbNetApi.h" +#include "CSequenceMsgHandle.h" + +#define SEQUENCE_SETTING ("sequence_setting") +#define SEQUENCE_DEFINE ("sequence_define") +#define SEQUENCE_FUNCTION ("sequence_function") +#define SEQUENCE_ACTION ("sequence_action") +#define COMAPP ("comapp") + +class CSequenceDataManage : public QObject +{ + Q_OBJECT + +public: + explicit CSequenceDataManage(QObject *parent = nullptr, kbd_dbms::CDbApi *dbRead = NULL); + ~CSequenceDataManage(); + + void initDataBase(); + + void initRdbDataBase(); + + void recvSequenceResponse(kbd_idlfile::sequence::SeqOperateMessageAck &msg); + + void recvUserInterveneRequest(kbd_idlfile::sequence::UiRequestMessage &msg); + + void recvSeqStateChange(kbd_idlfile::sequence::StatusChangeMessage &msg); + + QString queryLocationName(const int &nLocationID); + + QString queryTagName(const QString &strTableName, const QString &strTaginfo); + + QString queryTagTextName(const QString &strTableName, const QString &strTaginfo); + + QString queryStateName(const QString &strStateTextName, const int &nActualValue); + + QList querySequenceList(const QStringList &seqNameList); + +signals: + void sigRecvSequenceResponse(const QString &seqName, const E_SEQ_OPERATE &type); + void sigRecvSequenceResponseErrorMsg(const QString &seqName, const E_SEQ_OPERATE &type, const QString &errorInfo); + void sigRecvSequenceStateError(const QString &seqName, const int &errorCode, const QString &errorDescription); + void sigRecvSequenceStateChanged(const QString &seqName, const E_EXECUTING_STATE &state); + void sigRecvFunctionStateChanged(const QString &seqName, const QString &funcName, const E_EXECUTING_STATE &state); + void sigRecvActionStateChanged(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state); + void sigRecvUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage *msg); + +private: + QMutex mutex; + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccessEx * m_rtdbAccessEx; + bool m_isInitDb; +}; + +#endif // CSEQUENCEDATAMANAGE_H diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.cpp b/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.cpp index 619ba2a5..419baf04 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.cpp @@ -1,48 +1,48 @@ -#include "CSequenceMsgHandle.h" -#include "CSequenceDataManage.h" -#include "../../idl_files/SequenceMessage.pb.h" - -CSequenceMsgHandle::CSequenceMsgHandle() - : m_seqDataManage(NULL) -{ -} - -CSequenceMsgHandle::~CSequenceMsgHandle() -{ -} - -void CSequenceMsgHandle::setDataManager(CSequenceDataManage *mng) -{ - m_seqDataManage = mng; -} - -bool CSequenceMsgHandle::handleSeqOperateResponse(kbd_idlfile::sequence::SeqOperateMessageAck &msg) -{ - if(NULL != m_seqDataManage) - { - m_seqDataManage->recvSequenceResponse(msg); - } - return true; -} - -bool CSequenceMsgHandle::handleUserInterveneRequest(kbd_idlfile::sequence::UiRequestMessage &msg) -{ - if(NULL != m_seqDataManage) - { - m_seqDataManage->recvUserInterveneRequest(msg); - } - return true; -} - -bool CSequenceMsgHandle::handleSeqStateChange(kbd_idlfile::sequence::StatusChangeMessage &msg) -{ - //< 不再接收顺控状态变化消息 - Q_UNUSED(msg) - return true; -// if(NULL != m_seqDataManage) -// { -// m_seqDataManage->recvSeqStateChange(msg); -// } -// return true; -} - +#include "CSequenceMsgHandle.h" +#include "CSequenceDataManage.h" +#include "../../idl_files/SequenceMessage.pb.h" + +CSequenceMsgHandle::CSequenceMsgHandle() + : m_seqDataManage(NULL) +{ +} + +CSequenceMsgHandle::~CSequenceMsgHandle() +{ +} + +void CSequenceMsgHandle::setDataManager(CSequenceDataManage *mng) +{ + m_seqDataManage = mng; +} + +bool CSequenceMsgHandle::handleSeqOperateResponse(kbd_idlfile::sequence::SeqOperateMessageAck &msg) +{ + if(NULL != m_seqDataManage) + { + m_seqDataManage->recvSequenceResponse(msg); + } + return true; +} + +bool CSequenceMsgHandle::handleUserInterveneRequest(kbd_idlfile::sequence::UiRequestMessage &msg) +{ + if(NULL != m_seqDataManage) + { + m_seqDataManage->recvUserInterveneRequest(msg); + } + return true; +} + +bool CSequenceMsgHandle::handleSeqStateChange(kbd_idlfile::sequence::StatusChangeMessage &msg) +{ + //< 不再接收顺控状态变化消息 + Q_UNUSED(msg) + return true; +// if(NULL != m_seqDataManage) +// { +// m_seqDataManage->recvSeqStateChange(msg); +// } +// return true; +} + diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.h b/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.h index f83af3ab..c4e28177 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.h +++ b/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.h @@ -1,35 +1,35 @@ -#ifndef CSEQUENCEMSGHANDLE_H -#define CSEQUENCEMSGHANDLE_H - -#include "application/sequence_server_api/CSeqForHmiApi.h" - -class CSequenceDataManage; - -class CSequenceMsgHandle : public kbd_application::CSeqForHmiApi -{ -public: - CSequenceMsgHandle(); - ~CSequenceMsgHandle(); - - void setDataManager(CSequenceDataManage * mng); - - //<1 hmi->server 发起的请求顺控操作 - //bool seqOperateRequest(kbd_idlfile::SeqOperateMessage& msg); - - //<2 server->hmi 请求顺控操作 的 应答 - virtual bool handleSeqOperateResponse(kbd_idlfile::sequence::SeqOperateMessageAck& msg); - - //<1 server->hmi 发起的人工干预 请求 - virtual bool handleUserInterveneRequest(kbd_idlfile::sequence::UiRequestMessage& msg); - - //<2 hmi ->server 人工干预应答 - //bool userInterveneResponse(kbd_idlfile::sequence::UiRequestMessageAck& msg); - - - //server->hmi 顺控状态更新 - virtual bool handleSeqStateChange(kbd_idlfile::sequence::StatusChangeMessage& msg); - -private: - CSequenceDataManage * m_seqDataManage; -}; -#endif // CSEQUENCEMSGHANDLE_H +#ifndef CSEQUENCEMSGHANDLE_H +#define CSEQUENCEMSGHANDLE_H + +#include "application/sequence_server_api/CSeqForHmiApi.h" + +class CSequenceDataManage; + +class CSequenceMsgHandle : public kbd_application::CSeqForHmiApi +{ +public: + CSequenceMsgHandle(); + ~CSequenceMsgHandle(); + + void setDataManager(CSequenceDataManage * mng); + + //<1 hmi->server 发起的请求顺控操作 + //bool seqOperateRequest(kbd_idlfile::SeqOperateMessage& msg); + + //<2 server->hmi 请求顺控操作 的 应答 + virtual bool handleSeqOperateResponse(kbd_idlfile::sequence::SeqOperateMessageAck& msg); + + //<1 server->hmi 发起的人工干预 请求 + virtual bool handleUserInterveneRequest(kbd_idlfile::sequence::UiRequestMessage& msg); + + //<2 hmi ->server 人工干预应答 + //bool userInterveneResponse(kbd_idlfile::sequence::UiRequestMessageAck& msg); + + + //server->hmi 顺控状态更新 + virtual bool handleSeqStateChange(kbd_idlfile::sequence::StatusChangeMessage& msg); + +private: + CSequenceDataManage * m_seqDataManage; +}; +#endif // CSEQUENCEMSGHANDLE_H diff --git a/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.cpp b/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.cpp index 77cc76e6..7b9a3ea3 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.cpp @@ -1,28 +1,28 @@ -#include -#include "CSequencePluginWidget.h" -#include "CSequenceWidget.h" - -CSequencePluginWidget::CSequencePluginWidget(QObject *parent): QObject(parent) -{ - -} - -CSequencePluginWidget::~CSequencePluginWidget() -{ - -} - -bool CSequencePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **sequenceWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CSequenceWidget *pWidget = new CSequenceWidget(parent, editMode); - pWidget->initialize(E_Mode_Action, QStringList() << "", NULL); - *widget = (QWidget *)pWidget; - *sequenceWidget = (IPluginWidget *)pWidget; - return true; -} - -void CSequencePluginWidget::release() -{ - -} +#include +#include "CSequencePluginWidget.h" +#include "CSequenceWidget.h" + +CSequencePluginWidget::CSequencePluginWidget(QObject *parent): QObject(parent) +{ + +} + +CSequencePluginWidget::~CSequencePluginWidget() +{ + +} + +bool CSequencePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **sequenceWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CSequenceWidget *pWidget = new CSequenceWidget(parent, editMode); + pWidget->initialize(E_Mode_Action, QStringList() << "", NULL); + *widget = (QWidget *)pWidget; + *sequenceWidget = (IPluginWidget *)pWidget; + return true; +} + +void CSequencePluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.h b/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.h index c177861b..6546287b 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.h +++ b/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CSEQUENCEPLUGINWIDGET_H -#define CSEQUENCEPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CSequencePluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CSequencePluginWidget(QObject *parent = 0); - ~CSequencePluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **sequenceWidget, QVector ptrVec); - void release(); -}; - -#endif //CSEQUENCEPLUGINWIDGET_H - +#ifndef CSEQUENCEPLUGINWIDGET_H +#define CSEQUENCEPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CSequencePluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CSequencePluginWidget(QObject *parent = 0); + ~CSequencePluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **sequenceWidget, QVector ptrVec); + void release(); +}; + +#endif //CSEQUENCEPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.cpp b/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.cpp index e3530f1f..537a2079 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.cpp @@ -1,352 +1,352 @@ -#include "CSequenceStateManage.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "../../idl_files/SequenceMessage.pb.h" -#include "../../idl_files/RdbServerMessage.pb.h" -#include - -using namespace kbd_dbms; -using namespace kbd_idlfile; - -CSequenceStateManage::CSequenceStateManage(QObject *parent, CDbApi *dbRead) - : QObject(parent), - m_timer(NULL), - m_pReadDb(dbRead), - m_rtdbAccessEx(NULL), - m_tagRdbNetApi(NULL), - m_seqRdbNetApi(NULL), - m_isInitDb(false) -{ - if(m_pReadDb == NULL) - { - m_isInitDb = true; - //关系库 - m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - } - - //实时库 - m_rtdbAccessEx = new CRdbAccessEx(); - - //网络实时库 - m_tagRdbNetApi = new CRdbNetApi(); - m_seqRdbNetApi = new CRdbNetApi(); - - loadStateNameMap(); -} - -CSequenceStateManage::~CSequenceStateManage() -{ - slotUnSubScribeSequenceList(); - - if(m_pReadDb && m_isInitDb) - { - m_pReadDb->close(); - delete m_pReadDb; - } - m_pReadDb = NULL; - - if(m_rtdbAccessEx) - { - delete m_rtdbAccessEx; - } - m_rtdbAccessEx = NULL; - - if(m_tagRdbNetApi) - { - m_tagRdbNetApi->clearAsynRequest(); - delete m_tagRdbNetApi; - } - m_tagRdbNetApi = NULL; - - if(m_seqRdbNetApi) - { - m_seqRdbNetApi->clearAsynRequest(); - delete m_seqRdbNetApi; - } - m_seqRdbNetApi = NULL; -} - -void CSequenceStateManage::slotSubScribeSequenceList(QList listSequence) -{ - QMutexLocker locker(&mutex); - if(m_timer != NULL) - { - m_timer->stop(); - } - delete m_timer; - - m_listSequence.append(listSequence); - foreach (Sequence sequence, m_listSequence) - { - if(E_Node_Action == sequence.nodeType) - { - QStringList strListTagInfo = sequence.tagInfo.split("."); - QString tagName = sequence.tagInfo.section(".", 1, strListTagInfo.size() - 2); - m_tagSeqMap.insert(tagName, sequence); - } - } - m_timer = new QTimer(); - m_timer->setInterval(1000); - connect(m_timer, SIGNAL(timeout()), this, SLOT(updataSequenceState())); - connect(m_timer, SIGNAL(timeout()), this, SLOT(updataSequenceExecuteState())); - m_timer->start(); -} - -void CSequenceStateManage::slotUnSubScribeSequenceList() -{ - QMutexLocker locker(&mutex); - if(m_timer != NULL) - { - m_timer->stop(); - delete m_timer; - } - m_timer = NULL; - m_listSequence.clear(); - m_tagSeqMap.clear(); -} - -void CSequenceStateManage::updataSequence() -{ - { - QMutexLocker locker(&mutex); - if(m_timer) - { - m_timer->stop(); - } - } - - updataSequenceState(); - updataSequenceExecuteState(); - - { - QMutexLocker locker(&mutex); - if(m_timer) - { - m_timer->start(); - } - } -} - -void CSequenceStateManage::updataSequenceState() -{ - //query state - QMutexLocker locker(&mutex); - while(m_tagRdbNetApi->checkStatus()) - { - kbd_idlfile::RdbRet retMsg; - if (m_tagRdbNetApi->getRet(&retMsg)) - { - for (int nIndex(0); nIndex < retMsg.msgrecord_size(); nIndex++) - { - QString strTagName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(0).strvalue()); - if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(1).edatatype()) - { - QList listSequence = m_tagSeqMap.values(strTagName); - foreach (Sequence sequence, listSequence) - { - int value = retMsg.msgrecord(nIndex).msgvaluearray(1).nvalue(); - QStringList strListTagInfo = sequence.tagInfo.split("."); - QString strTagTextName = queryTagTextName(strListTagInfo.first(), sequence.tagInfo.section(".", 1, strListTagInfo.size() - 2)); - QString state = m_stateDescript.value(strTagTextName).value(value); - emit sigUpdateActionActualState(sequence.seqName, sequence.funcName, sequence.actionName, state); - } - } - } - } - } - - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - foreach (Sequence sequence, m_listSequence) - { - if(!m_timer) - { - return; - } - if(E_Node_Action != sequence.nodeType) - { - continue; - } - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(sequence.locationID, stLocationInfo); - kbd_public::SAppInfo appInfo; - spSysInfo->getAppInfoBySubsystemId(sequence.subSystemID, appInfo); - m_tagRdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); - - QString strTableName = sequence.tagInfo.section(".", 0, 0); - - kbd_idlfile::RdbQuery query; - query.set_strtablename(strTableName.toStdString()); - - std::string *pTagColName = query.add_strselectcolnamearr(); - *pTagColName = "tag_name"; - std::string *pValColName = query.add_strselectcolnamearr(); - *pValColName = "value"; - - kbd_idlfile::RdbCondition *pCondtion = query.add_msgcondition(); - pCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pCondtion->set_strcolumnname("tag_name"); - - QStringList strListTagInfo = sequence.tagInfo.split("."); - QString tagName = sequence.tagInfo.section(".", 1, strListTagInfo.size() - 2); - SVariable *pCondValue = pCondtion->mutable_msgvalue(); - pCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pCondValue->set_strvalue(tagName.toStdString()); - - kbd_idlfile::RdbRet retMsg; - m_tagRdbNetApi->query(query, retMsg, true); - } - } -} - -void CSequenceStateManage::updataSequenceExecuteState() -{ - QMutexLocker locker(&mutex); - - while(m_seqRdbNetApi->checkStatus()) - { - kbd_idlfile::RdbRet retMsg; - if (m_seqRdbNetApi->getRet(&retMsg)) - { - for (int nIndex(0); nIndex < retMsg.msgrecord_size(); nIndex++) - { - QString seqName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(0).strvalue()); - if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(1).edatatype()) - { - E_NODE_TYPE nodeType = (E_NODE_TYPE)retMsg.msgrecord(nIndex).msgvaluearray(1).nvalue(); - if(E_Node_Sequence == nodeType) - { - E_EXECUTING_STATE value = (E_EXECUTING_STATE)retMsg.msgrecord(nIndex).msgvaluearray(2).nvalue(); - int64 timeFlag = (int64)retMsg.msgrecord(nIndex).msgvaluearray(5).ulvalue(); - emit sigUpdateSequenceState(seqName, value); - emit sigUpdateSequenceTimeFlag(seqName, timeFlag); - } - else if(E_Node_Function == nodeType) - { - E_EXECUTING_STATE value = (E_EXECUTING_STATE)retMsg.msgrecord(nIndex).msgvaluearray(2).nvalue(); - QString funcName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(3).strvalue()); - emit sigUpdateFunctionState(seqName, funcName, value); - } - else if(E_Node_Action == nodeType) - { - E_EXECUTING_STATE value = (E_EXECUTING_STATE)retMsg.msgrecord(nIndex).msgvaluearray(2).nvalue(); - QString funcName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(3).strvalue()); - QString actionName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(4).strvalue()); - emit sigUpdateActionState(seqName, funcName, actionName, value); - } - } - } - } - } - - QString strSeqName; - int nLocationID = -1; - foreach (Sequence sequence, m_listSequence) - { - if(E_Node_Sequence == sequence.nodeType) - { - strSeqName = sequence.seqName; - nLocationID= sequence.locationID; - } - } - if(strSeqName.isEmpty() || -1 == nLocationID) - { - return; - } - - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(nLocationID, stLocationInfo); - kbd_public::SAppInfo appInfo; - spSysInfo->getAppInfoByName(COMAPP, appInfo); - m_seqRdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); - - kbd_idlfile::RdbQuery query; - query.set_strtablename("sequence_running"); - - std::string *pSeqColName = query.add_strselectcolnamearr(); - *pSeqColName = "seq_name"; - std::string *pNodeTypeColName = query.add_strselectcolnamearr(); - *pNodeTypeColName = "node_type"; - std::string *pStatusColName = query.add_strselectcolnamearr(); - *pStatusColName = "status"; - std::string *pFuncColName = query.add_strselectcolnamearr(); - *pFuncColName = "func_name"; - std::string *pActionColName = query.add_strselectcolnamearr(); - *pActionColName = "action_name"; - std::string *pTimeFlagColName = query.add_strselectcolnamearr(); - *pTimeFlagColName = "timeflag"; - - kbd_idlfile::RdbCondition *pSequenceNameCondtion = query.add_msgcondition(); - pSequenceNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); - pSequenceNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); - pSequenceNameCondtion->set_strcolumnname("seq_name"); - - SVariable *pSeqNameCondValue = pSequenceNameCondtion->mutable_msgvalue(); - pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); - pSeqNameCondValue->set_strvalue(strSeqName.toStdString()); - - kbd_idlfile::RdbRet retMsg; - m_seqRdbNetApi->query(query, retMsg, true); - } -} - -QString CSequenceStateManage::queryTagTextName(const QString &strTableName, const QString &strTaginfo) -{ - if(strTaginfo.isEmpty()) - { - return QString(); - } - - QString strTagTextName; - if(!m_pReadDb->isOpen()) - { - return QString(); - } - QSqlQuery query; - QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName.toLower()).arg(strTaginfo.toLower()); - m_pReadDb->execute(sqlQuery, query); - if(query.isActive()) - { - while(query.next()) - { - strTagTextName = query.value(0).toString(); - } - } - return strTagTextName; -} - -void CSequenceStateManage::loadStateNameMap() -{ - QMutexLocker locker(&mutex); - std::string strApplicationName = "base"; - std::string strTableName = "dict_state_text_info"; - if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("state_text_name"); - columns.push_back("actual_value"); - columns.push_back("display_value"); - - if(m_rtdbAccessEx->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType state_text_name; - result.getColumnValue(nIndex, 0, state_text_name); - CVarType actual_value; - result.getColumnValue(nIndex, 1, actual_value); - CVarType display_value; - result.getColumnValue(nIndex, 2, display_value); - m_stateDescript[QString::fromStdString(state_text_name.toStdString())].insert(actual_value.toInt(), QString::fromStdString(display_value.toStdString())); - } - } - } - m_rtdbAccessEx->close(); -} +#include "CSequenceStateManage.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "../../idl_files/SequenceMessage.pb.h" +#include "../../idl_files/RdbServerMessage.pb.h" +#include + +using namespace kbd_dbms; +using namespace kbd_idlfile; + +CSequenceStateManage::CSequenceStateManage(QObject *parent, CDbApi *dbRead) + : QObject(parent), + m_timer(NULL), + m_pReadDb(dbRead), + m_rtdbAccessEx(NULL), + m_tagRdbNetApi(NULL), + m_seqRdbNetApi(NULL), + m_isInitDb(false) +{ + if(m_pReadDb == NULL) + { + m_isInitDb = true; + //关系库 + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + } + + //实时库 + m_rtdbAccessEx = new CRdbAccessEx(); + + //网络实时库 + m_tagRdbNetApi = new CRdbNetApi(); + m_seqRdbNetApi = new CRdbNetApi(); + + loadStateNameMap(); +} + +CSequenceStateManage::~CSequenceStateManage() +{ + slotUnSubScribeSequenceList(); + + if(m_pReadDb && m_isInitDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbAccessEx) + { + delete m_rtdbAccessEx; + } + m_rtdbAccessEx = NULL; + + if(m_tagRdbNetApi) + { + m_tagRdbNetApi->clearAsynRequest(); + delete m_tagRdbNetApi; + } + m_tagRdbNetApi = NULL; + + if(m_seqRdbNetApi) + { + m_seqRdbNetApi->clearAsynRequest(); + delete m_seqRdbNetApi; + } + m_seqRdbNetApi = NULL; +} + +void CSequenceStateManage::slotSubScribeSequenceList(QList listSequence) +{ + QMutexLocker locker(&mutex); + if(m_timer != NULL) + { + m_timer->stop(); + } + delete m_timer; + + m_listSequence.append(listSequence); + foreach (Sequence sequence, m_listSequence) + { + if(E_Node_Action == sequence.nodeType) + { + QStringList strListTagInfo = sequence.tagInfo.split("."); + QString tagName = sequence.tagInfo.section(".", 1, strListTagInfo.size() - 2); + m_tagSeqMap.insert(tagName, sequence); + } + } + m_timer = new QTimer(); + m_timer->setInterval(1000); + connect(m_timer, SIGNAL(timeout()), this, SLOT(updataSequenceState())); + connect(m_timer, SIGNAL(timeout()), this, SLOT(updataSequenceExecuteState())); + m_timer->start(); +} + +void CSequenceStateManage::slotUnSubScribeSequenceList() +{ + QMutexLocker locker(&mutex); + if(m_timer != NULL) + { + m_timer->stop(); + delete m_timer; + } + m_timer = NULL; + m_listSequence.clear(); + m_tagSeqMap.clear(); +} + +void CSequenceStateManage::updataSequence() +{ + { + QMutexLocker locker(&mutex); + if(m_timer) + { + m_timer->stop(); + } + } + + updataSequenceState(); + updataSequenceExecuteState(); + + { + QMutexLocker locker(&mutex); + if(m_timer) + { + m_timer->start(); + } + } +} + +void CSequenceStateManage::updataSequenceState() +{ + //query state + QMutexLocker locker(&mutex); + while(m_tagRdbNetApi->checkStatus()) + { + kbd_idlfile::RdbRet retMsg; + if (m_tagRdbNetApi->getRet(&retMsg)) + { + for (int nIndex(0); nIndex < retMsg.msgrecord_size(); nIndex++) + { + QString strTagName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(0).strvalue()); + if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(1).edatatype()) + { + QList listSequence = m_tagSeqMap.values(strTagName); + foreach (Sequence sequence, listSequence) + { + int value = retMsg.msgrecord(nIndex).msgvaluearray(1).nvalue(); + QStringList strListTagInfo = sequence.tagInfo.split("."); + QString strTagTextName = queryTagTextName(strListTagInfo.first(), sequence.tagInfo.section(".", 1, strListTagInfo.size() - 2)); + QString state = m_stateDescript.value(strTagTextName).value(value); + emit sigUpdateActionActualState(sequence.seqName, sequence.funcName, sequence.actionName, state); + } + } + } + } + } + + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + foreach (Sequence sequence, m_listSequence) + { + if(!m_timer) + { + return; + } + if(E_Node_Action != sequence.nodeType) + { + continue; + } + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(sequence.locationID, stLocationInfo); + kbd_public::SAppInfo appInfo; + spSysInfo->getAppInfoBySubsystemId(sequence.subSystemID, appInfo); + m_tagRdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); + + QString strTableName = sequence.tagInfo.section(".", 0, 0); + + kbd_idlfile::RdbQuery query; + query.set_strtablename(strTableName.toStdString()); + + std::string *pTagColName = query.add_strselectcolnamearr(); + *pTagColName = "tag_name"; + std::string *pValColName = query.add_strselectcolnamearr(); + *pValColName = "value"; + + kbd_idlfile::RdbCondition *pCondtion = query.add_msgcondition(); + pCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pCondtion->set_strcolumnname("tag_name"); + + QStringList strListTagInfo = sequence.tagInfo.split("."); + QString tagName = sequence.tagInfo.section(".", 1, strListTagInfo.size() - 2); + SVariable *pCondValue = pCondtion->mutable_msgvalue(); + pCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pCondValue->set_strvalue(tagName.toStdString()); + + kbd_idlfile::RdbRet retMsg; + m_tagRdbNetApi->query(query, retMsg, true); + } + } +} + +void CSequenceStateManage::updataSequenceExecuteState() +{ + QMutexLocker locker(&mutex); + + while(m_seqRdbNetApi->checkStatus()) + { + kbd_idlfile::RdbRet retMsg; + if (m_seqRdbNetApi->getRet(&retMsg)) + { + for (int nIndex(0); nIndex < retMsg.msgrecord_size(); nIndex++) + { + QString seqName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(0).strvalue()); + if(DataType::CN_DATATYPE_INT32 == retMsg.msgrecord(nIndex).msgvaluearray(1).edatatype()) + { + E_NODE_TYPE nodeType = (E_NODE_TYPE)retMsg.msgrecord(nIndex).msgvaluearray(1).nvalue(); + if(E_Node_Sequence == nodeType) + { + E_EXECUTING_STATE value = (E_EXECUTING_STATE)retMsg.msgrecord(nIndex).msgvaluearray(2).nvalue(); + int64 timeFlag = (int64)retMsg.msgrecord(nIndex).msgvaluearray(5).ulvalue(); + emit sigUpdateSequenceState(seqName, value); + emit sigUpdateSequenceTimeFlag(seqName, timeFlag); + } + else if(E_Node_Function == nodeType) + { + E_EXECUTING_STATE value = (E_EXECUTING_STATE)retMsg.msgrecord(nIndex).msgvaluearray(2).nvalue(); + QString funcName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(3).strvalue()); + emit sigUpdateFunctionState(seqName, funcName, value); + } + else if(E_Node_Action == nodeType) + { + E_EXECUTING_STATE value = (E_EXECUTING_STATE)retMsg.msgrecord(nIndex).msgvaluearray(2).nvalue(); + QString funcName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(3).strvalue()); + QString actionName = QString::fromStdString(retMsg.msgrecord(nIndex).msgvaluearray(4).strvalue()); + emit sigUpdateActionState(seqName, funcName, actionName, value); + } + } + } + } + } + + QString strSeqName; + int nLocationID = -1; + foreach (Sequence sequence, m_listSequence) + { + if(E_Node_Sequence == sequence.nodeType) + { + strSeqName = sequence.seqName; + nLocationID= sequence.locationID; + } + } + if(strSeqName.isEmpty() || -1 == nLocationID) + { + return; + } + + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(nLocationID, stLocationInfo); + kbd_public::SAppInfo appInfo; + spSysInfo->getAppInfoByName(COMAPP, appInfo); + m_seqRdbNetApi->connect(stLocationInfo.nDomainId, appInfo.nId); + + kbd_idlfile::RdbQuery query; + query.set_strtablename("sequence_running"); + + std::string *pSeqColName = query.add_strselectcolnamearr(); + *pSeqColName = "seq_name"; + std::string *pNodeTypeColName = query.add_strselectcolnamearr(); + *pNodeTypeColName = "node_type"; + std::string *pStatusColName = query.add_strselectcolnamearr(); + *pStatusColName = "status"; + std::string *pFuncColName = query.add_strselectcolnamearr(); + *pFuncColName = "func_name"; + std::string *pActionColName = query.add_strselectcolnamearr(); + *pActionColName = "action_name"; + std::string *pTimeFlagColName = query.add_strselectcolnamearr(); + *pTimeFlagColName = "timeflag"; + + kbd_idlfile::RdbCondition *pSequenceNameCondtion = query.add_msgcondition(); + pSequenceNameCondtion->set_enlogic(ENConditionLogic::enumCondAnd); + pSequenceNameCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pSequenceNameCondtion->set_strcolumnname("seq_name"); + + SVariable *pSeqNameCondValue = pSequenceNameCondtion->mutable_msgvalue(); + pSeqNameCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pSeqNameCondValue->set_strvalue(strSeqName.toStdString()); + + kbd_idlfile::RdbRet retMsg; + m_seqRdbNetApi->query(query, retMsg, true); + } +} + +QString CSequenceStateManage::queryTagTextName(const QString &strTableName, const QString &strTaginfo) +{ + if(strTaginfo.isEmpty()) + { + return QString(); + } + + QString strTagTextName; + if(!m_pReadDb->isOpen()) + { + return QString(); + } + QSqlQuery query; + QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName.toLower()).arg(strTaginfo.toLower()); + m_pReadDb->execute(sqlQuery, query); + if(query.isActive()) + { + while(query.next()) + { + strTagTextName = query.value(0).toString(); + } + } + return strTagTextName; +} + +void CSequenceStateManage::loadStateNameMap() +{ + QMutexLocker locker(&mutex); + std::string strApplicationName = "base"; + std::string strTableName = "dict_state_text_info"; + if(m_rtdbAccessEx->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccessEx); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("state_text_name"); + columns.push_back("actual_value"); + columns.push_back("display_value"); + + if(m_rtdbAccessEx->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType state_text_name; + result.getColumnValue(nIndex, 0, state_text_name); + CVarType actual_value; + result.getColumnValue(nIndex, 1, actual_value); + CVarType display_value; + result.getColumnValue(nIndex, 2, display_value); + m_stateDescript[QString::fromStdString(state_text_name.toStdString())].insert(actual_value.toInt(), QString::fromStdString(display_value.toStdString())); + } + } + } + m_rtdbAccessEx->close(); +} diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.h b/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.h index a5de85b7..88ff2a43 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.h +++ b/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.h @@ -1,61 +1,61 @@ -#ifndef CSEQUENCESTATEMANAGE_H -#define CSEQUENCESTATEMANAGE_H - -#include -#include -#include -#include -#include -#include "sequence_def.h" -#include "sequence_global.h" -#include "db_api_ex/CDbApi.h" -#include "dbms/rdb_api/CRdbAccessEx.h" -#include "../dbms/rdb_net_api/CRdbNetApi.h" - -#define COMAPP ("comapp") - -class CSequenceStateManage : public QObject -{ - Q_OBJECT -public: - explicit CSequenceStateManage(QObject *parent = nullptr, kbd_dbms::CDbApi *dbRead = NULL); - ~CSequenceStateManage(); - -signals: - void sigUpdateActionActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state); - void sigUpdateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); - void sigUpdateFunctionState(const QString &seqName, const QString &funcName, const E_EXECUTING_STATE &state); - void sigUpdateActionState(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state); - void sigUpdateSequenceTimeFlag(const QString &seqName, const int &timeFlag); - -public slots: - void slotSubScribeSequenceList(QList listSequence); - void slotUnSubScribeSequenceList(); - - void updataSequence(); - -private: - QString queryTagTextName(const QString &strTableName, const QString &strTaginfo); - void loadStateNameMap(); - -private slots: - void updataSequenceState(); - void updataSequenceExecuteState(); - -private: - QMutex mutex; - QTimer * m_timer; - - kbd_dbms::CDbApi * m_pReadDb; - kbd_dbms::CRdbAccessEx * m_rtdbAccessEx; - kbd_dbms::CRdbNetApi * m_tagRdbNetApi; - kbd_dbms::CRdbNetApi * m_seqRdbNetApi; - - QList m_listSequence; - QHash< QString, QMap > m_stateDescript; - QMultiHash< QString, Sequence> m_tagSeqMap; - - bool m_isInitDb; -}; - -#endif // CSEQUENCESTATEMANAGE_H +#ifndef CSEQUENCESTATEMANAGE_H +#define CSEQUENCESTATEMANAGE_H + +#include +#include +#include +#include +#include +#include "sequence_def.h" +#include "sequence_global.h" +#include "db_api_ex/CDbApi.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "../dbms/rdb_net_api/CRdbNetApi.h" + +#define COMAPP ("comapp") + +class CSequenceStateManage : public QObject +{ + Q_OBJECT +public: + explicit CSequenceStateManage(QObject *parent = nullptr, kbd_dbms::CDbApi *dbRead = NULL); + ~CSequenceStateManage(); + +signals: + void sigUpdateActionActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state); + void sigUpdateSequenceState(const QString &seqName, const E_EXECUTING_STATE &state); + void sigUpdateFunctionState(const QString &seqName, const QString &funcName, const E_EXECUTING_STATE &state); + void sigUpdateActionState(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state); + void sigUpdateSequenceTimeFlag(const QString &seqName, const int &timeFlag); + +public slots: + void slotSubScribeSequenceList(QList listSequence); + void slotUnSubScribeSequenceList(); + + void updataSequence(); + +private: + QString queryTagTextName(const QString &strTableName, const QString &strTaginfo); + void loadStateNameMap(); + +private slots: + void updataSequenceState(); + void updataSequenceExecuteState(); + +private: + QMutex mutex; + QTimer * m_timer; + + kbd_dbms::CDbApi * m_pReadDb; + kbd_dbms::CRdbAccessEx * m_rtdbAccessEx; + kbd_dbms::CRdbNetApi * m_tagRdbNetApi; + kbd_dbms::CRdbNetApi * m_seqRdbNetApi; + + QList m_listSequence; + QHash< QString, QMap > m_stateDescript; + QMultiHash< QString, Sequence> m_tagSeqMap; + + bool m_isInitDb; +}; + +#endif // CSEQUENCESTATEMANAGE_H diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceWidget.cpp b/product/src/gui/plugin/SequenceWidget/CSequenceWidget.cpp index a7dae94b..bdcb6770 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceWidget.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSequenceWidget.cpp @@ -1,984 +1,984 @@ -#include "CSequenceWidget.h" -#include "ui_CSequenceWidget.h" -#include -#include -#include "CLocationSequModel.h" -#include "CActionSequModel.h" -#include "CSequenceDataManage.h" -#include "CSequenceStateManage.h" -#include "CSequenceMsgHandle.h" -#include "sequence_def.h" -#include "perm_mng_api/PermMngApi.h" -#include "public/pub_sysinfo_api/SysInfoApi.h" -#include "pub_utility_api/FileStyle.h" -#include "CSeqPermDialog.h" - -CSequenceWidget::CSequenceWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CSequenceWidget), - m_seqMode(E_Mode_Invalid), - m_permTimer(NULL), - m_pTableModel(NULL), - m_seqDataManage(NULL), - m_seqStateManage(NULL), - m_seqMsgHandle(NULL), - m_userInterveneRequestDialog(NULL), - m_editMode(editMode), - m_isOwnerPerm(false), - m_isGuard(true) -{ - ui->setupUi(this); - qRegisterMetaType("E_SEQ_OPERATE"); - qRegisterMetaType("E_EXECUTING_STATE"); - qRegisterMetaType("kbd_idlfile::sequence::UiRequestMessage"); - qRegisterMetaType >("SEQUENCELIST"); - - m_nUserId = -1; - m_strUsrName = ""; - m_nUserGrpId = -1; - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("sequence.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -CSequenceWidget::~CSequenceWidget() -{ - if(m_seqMsgHandle) - { - m_seqMsgHandle->stop(); - delete m_seqMsgHandle; - } - m_seqMsgHandle = NULL; - - if(m_pTableModel) - { - delete m_pTableModel; - } - m_pTableModel = NULL; - - if(m_seqDataManage) - { - delete m_seqDataManage; - } - m_seqDataManage = NULL; - - if(m_seqStateManage) - { - delete m_seqStateManage; - } - m_seqStateManage = NULL; - - if(m_userInterveneRequestDialog) - { - delete m_userInterveneRequestDialog; - } - m_userInterveneRequestDialog = NULL; - - delete ui; - qDebug() << "~CSequenceWidget()"; -} - -void CSequenceWidget::login() -{ - updatePerm(); - if(m_seqMsgHandle) - { - m_seqMsgHandle->start(); - } - if(E_Mode_Sequence == m_seqMode) - { - loadSequenceData(m_seqNameList); - notify(tr("")); - } -} - -void CSequenceWidget::logout() -{ - updatePerm(); - if(m_seqMsgHandle) - { - m_seqMsgHandle->stop(); - } - - if(m_seqStateManage) - { - m_seqStateManage->slotUnSubScribeSequenceList(); - } -} - -void CSequenceWidget::setEditMode(bool editMode) -{ - m_editMode = editMode; -} - -void CSequenceWidget::setTitleVisable(bool bEnable) -{ - ui->seqTitlelabel->setVisible(bEnable); - ui->seqNameLabel->setVisible(bEnable); -// ui->sequenceTitle->setVisible(bEnable); -} - -QStringList CSequenceWidget::currentSequenceName() -{ - return m_seqNameList; -} - -void CSequenceWidget::release() -{ - if(m_seqMsgHandle) - { - m_seqMsgHandle->stop(); - } - - if(m_seqStateManage) - { - m_seqStateManage->slotUnSubScribeSequenceList(); - } - - if(m_pTableModel) - { - delete m_pTableModel; - } - m_pTableModel = NULL; - -} - -void CSequenceWidget::initialize(int seqMode, QStringList listSequenceName, kbd_dbms::CDbApi *dbRead) -{ - if(m_editMode) - { - return; - } - - m_seqMode = (E_MODE_TYPE)seqMode; - - //<无效判断 - if(E_Mode_Sequence != seqMode && E_Mode_Action != seqMode) - { - return; - } - - //<初始化 - if(E_Mode_Sequence == m_seqMode) - { - m_pTableModel = new CLocationSequModel(this); - } - else - { - m_pTableModel = new CActionSequModel(this); - } -// QItemSelectionModel * oldModel = ui->view->selectionModel(); - ui->view->setModel(m_pTableModel); -// if(oldModel) -// { -// oldModel->deleteLater(); -// } - - if(m_seqNameList.isEmpty()) - { - ui->view->setColumnWidth(0,50); - ui->view->setColumnWidth(1,200); - - connect(ui->execute, &QPushButton::clicked, this, &CSequenceWidget::slotExecute); - connect(ui->pause, &QPushButton::clicked, this, &CSequenceWidget::slotPause); - connect(ui->stop, &QPushButton::clicked, this, &CSequenceWidget::slotStop); - - - m_seqDataManage = new CSequenceDataManage(NULL, dbRead); - m_seqMsgHandle = new CSequenceMsgHandle(); - m_seqStateManage = new CSequenceStateManage(NULL, dbRead); - m_seqMsgHandle->setDataManager(m_seqDataManage); - connect(m_seqDataManage, &CSequenceDataManage::sigRecvSequenceResponse, this, &CSequenceWidget::slotRecvSeqOperateResponse, Qt::QueuedConnection); - connect(m_seqDataManage, &CSequenceDataManage::sigRecvSequenceResponseErrorMsg, this, &CSequenceWidget::slotRecvSeqOperateResponseErrorMsg, Qt::QueuedConnection); - connect(m_seqDataManage, &CSequenceDataManage::sigRecvSequenceStateError, this, &CSequenceWidget::slotRecvSequenceStateError, Qt::QueuedConnection); - connect(m_seqDataManage, &CSequenceDataManage::sigRecvSequenceStateChanged, this, &CSequenceWidget::slotRecvSequenceStateChanged, Qt::QueuedConnection); - connect(m_seqDataManage, &CSequenceDataManage::sigRecvFunctionStateChanged, this, &CSequenceWidget::slotRecvFunctionStateChanged, Qt::QueuedConnection); - connect(m_seqDataManage, &CSequenceDataManage::sigRecvActionStateChanged, this, &CSequenceWidget::slotRecvActionStateChanged, Qt::QueuedConnection); - connect(m_seqDataManage, &CSequenceDataManage::sigRecvUserInterveneRequest, this, &CSequenceWidget::slotRecvUserInterveneRequest, Qt::QueuedConnection); - - connect(m_seqStateManage, &CSequenceStateManage::sigUpdateSequenceState, this, &CSequenceWidget::slotRecvSequenceStateChanged, Qt::QueuedConnection); - connect(m_seqStateManage, &CSequenceStateManage::sigUpdateFunctionState, this, &CSequenceWidget::slotRecvFunctionStateChanged, Qt::QueuedConnection); - connect(m_seqStateManage, &CSequenceStateManage::sigUpdateActionState, this, &CSequenceWidget::slotRecvActionStateChanged, Qt::QueuedConnection); - connect(m_seqStateManage, &CSequenceStateManage::sigUpdateActionActualState, this, &CSequenceWidget::slotUpdateActionActualState, Qt::QueuedConnection); - connect(m_seqStateManage, &CSequenceStateManage::sigUpdateSequenceTimeFlag, this, &CSequenceWidget::slotUpdateSequenceTimeFlag, Qt::QueuedConnection); - - connect(this, &CSequenceWidget::sigSubScribeSequenceList, m_seqStateManage, &CSequenceStateManage::slotSubScribeSequenceList, Qt::QueuedConnection); - connect(this, &CSequenceWidget::sigUnSubScribeSequence, m_seqStateManage, &CSequenceStateManage::slotUnSubScribeSequenceList, Qt::QueuedConnection); - - m_permTimer = new QTimer(); - m_permTimer->setInterval(1000); - connect(m_permTimer, &QTimer::timeout, this, &CSequenceWidget::updatePerm); - m_permTimer->start(); - } - m_seqMsgHandle->start(); - loadSequenceData(listSequenceName); - notify(tr("")); - ui->view->setColumnWidth(1, 300); -} - -void CSequenceWidget::loadSequenceData(QStringList listSequenceName) -{ - if(listSequenceName.isEmpty()) - { - return; - } - - emit sigUnSubScribeSequence(); - notify(""); - - ui->execute->setEnabled(false); - ui->pause->setText(tr("暂停")); - notify(tr("正在查询...")); - ui->pause->setEnabled(false); - ui->stop->setEnabled(false); - - m_seqNameList = listSequenceName; - ui->seqNameLabel->setText(m_seqNameList.first()); - - m_listSequence.clear(); - QList listSequence; - m_listSequence = m_seqDataManage->querySequenceList(m_seqNameList); - - emit sigSubScribeSequenceList(m_listSequence); - - if(E_Mode_Sequence == m_seqMode) - { - foreach (Sequence item, m_listSequence) - { - if(E_Node_Action != item.nodeType) - { - if(E_Node_Sequence == item.nodeType) - { - listSequence.append(item); - } - } - } - CLocationSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - model->initSequenceData(listSequence); - } - } - else if(E_Mode_Action == m_seqMode) - { - - foreach (Sequence item, m_listSequence) - { - if(E_Node_Action == item.nodeType) - { - listSequence.append(item); - } - } - CActionSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - model->initSequenceData(listSequence); - } - } - - if(!listSequence.isEmpty()) - { - ui->view->selectRow(0); - } -} - -void CSequenceWidget::updatePerm() -{ - bool isPerm = getSeqCtrlPerm(); - ui->execute->setVisible(isPerm); - ui->pause->setVisible(isPerm); - ui->stop->setVisible(isPerm); -} - -void CSequenceWidget::setGuard(bool guard) -{ - m_isGuard = guard; -} - -void CSequenceWidget::slotRecvSeqOperateResponse(const QString &seqName, const E_SEQ_OPERATE &type) -{ - QString content = tr("服务应答 [%1]:%2").arg(seqName).arg(operateDescription(type)); - notify(content); -} - -void CSequenceWidget::slotRecvSeqOperateResponseErrorMsg(const QString &seqName, const E_SEQ_OPERATE &type, const QString &errorInfo) -{ - Q_UNUSED(seqName) - Q_UNUSED(type) - QString content = tr("服务应答-错误 [%1]").arg(errorInfo); - notify(content); -} - -void CSequenceWidget::slotRecvSequenceStateError(const QString &seqName, const int &errorCode, const QString &errorDescription) -{ - Q_UNUSED(seqName) - Q_UNUSED(errorCode) - Q_UNUSED(errorDescription) - QString content = tr("%1[%2]\n%3%4\n%5%6\n").arg(tr("顺控名称: ")).arg(seqName).arg(tr("错误代码: ")).arg(errorCode).arg(tr("错误描述: ")).arg(errorDescription); - notify(content); - // QMessageBox::warning(NULL, tr("执行出错"), content); -} - -void CSequenceWidget::slotRecvSequenceStateChanged(const QString &seqName, const E_EXECUTING_STATE &state) -{ - emit sigSequenceStateChanged(seqName, state); - for(int nIndex(0); nIndex < m_listSequence.size(); nIndex++) - { - if(E_Node_Sequence == m_listSequence[nIndex].nodeType && m_listSequence[nIndex].seqName == seqName) - { - if(m_listSequence[nIndex].executeState != state) - { - m_listSequence[nIndex].executeState = state; - QString content = tr("状态变化 [顺控-%1]:%2").arg(m_listSequence[nIndex].seqDescription).arg(stateDescription(state)); - notify(content); - } - } - } - - if(E_Mode_Sequence == m_seqMode && m_seqNameList.contains(seqName)) - { - CLocationSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - model->updateSequenceState(seqName, state); - } - bool isFinish = true; - QList listSequence = model->sequenceData(); - for(int nIndex(0); nIndex < listSequence.size(); nIndex++) - { - if(E_Check_Checked == listSequence[nIndex].checkState && ( - E_Exec_Success != listSequence[nIndex].executeState && - E_Exec_Stop != listSequence[nIndex].executeState && - E_Exec_Skip != listSequence[nIndex].executeState)) - { - isFinish = false; - break; - } - } - if(isFinish) - { - ui->execute->setEnabled(true); - ui->pause->setText(tr("暂停")); - ui->pause->setEnabled(false); - ui->stop->setEnabled(false); - } - } - else if(E_Mode_Action == m_seqMode && m_seqNameList.contains(seqName)) - { - if(E_Exec_Run == state) - { - updateUiRun(); - } - else if(E_Exec_Pause == state) - { - updateUiPause(); - } - else if(E_Exec_Reset == state) - { - updateUiStop(); - } - else if(E_Exec_Success == state || E_Exec_Stop == state || E_Exec_Failed == state) - { - updateUiFinish(); - } - } -} - -void CSequenceWidget::slotRecvFunctionStateChanged(const QString &seqName, const QString &funcName, const E_EXECUTING_STATE &state) -{ - if(E_Mode_Action == m_seqMode) - { - QString seqDesc; - foreach (Sequence sequence, m_listSequence) - { - if(sequence.seqName == seqName && sequence.nodeType == E_Node_Sequence) - { - seqDesc = sequence.seqDescription; - } - } - - foreach (Sequence sequence, m_listSequence) - { - if(sequence.seqName == seqName && sequence.funcName == funcName) - { - if(sequence.executeState != state) - { - QString content = tr("状态变化 [顺控-%1] [功能-%2]:%3").arg(seqDesc).arg(sequence.funcDescription).arg(stateDescription(state)); - notify(content); - break; - } - } - } - } -} - -void CSequenceWidget::slotRecvActionStateChanged(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state) -{ - QString seqDesc; - QString funcDesc; - foreach (Sequence sequence, m_listSequence) - { - if(sequence.seqName == seqName && sequence.nodeType == E_Node_Sequence) - { - seqDesc = sequence.seqDescription; - } - if(sequence.seqName == seqName && sequence.funcName == funcName && sequence.nodeType == E_Node_Function) - { - funcDesc = sequence.funcDescription; - } - } - - for(int nIndex(0); nIndex < m_listSequence.size(); nIndex++) - { - if(E_Node_Action == m_listSequence[nIndex].nodeType && - m_listSequence[nIndex].seqName == seqName && - m_listSequence[nIndex].funcName == funcName && - m_listSequence[nIndex].actionName == actionName) - { - if(m_listSequence[nIndex].executeState != state) - { - m_listSequence[nIndex].executeState = state; - QString content = tr("状态变化 [顺控-%1] [功能-%2] [动作-%3]:%4").arg(seqDesc).arg(funcDesc).arg(m_listSequence[nIndex].actionDescription).arg(stateDescription(state)); - notify(content); - - if(E_Mode_Action == m_seqMode) - { - CActionSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - model->updateSequenceExecState(seqName, funcName, actionName, state); - } - } - } - } - } -} - - - -void CSequenceWidget::slotRecvUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage *msg) -{ - if(!getSeqCtrlPerm()) - { - return; - } - handleUserInterveneRequest(*msg); - delete msg; -} - -void CSequenceWidget::handleUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage &msg) -{ - if(NULL != m_userInterveneRequestDialog) - { - return; - } - std::string strErrorDescription = ""; - kbd_idlfile::sequence::ExecuteStatusParameter executeStatueParameter = msg.execute_status(); - if(0 != executeStatueParameter.statuscode() && executeStatueParameter.has_erro_param()) - { - kbd_idlfile::sequence::ErrorParameter paramter = executeStatueParameter.erro_param(); - strErrorDescription = paramter.errordescription(); - } - - kbd_idlfile::sequence::SeqNodeStatusParameter sequence = msg.nodelist(); - QString sequenceDescription = QString::fromStdString(sequence.seq_desc()); -// foreach (Sequence locatSequence, m_listSequence) -// { -// if(E_Node_Sequence == locatSequence.nodeType && locatSequence.seqName == sequenceName) -// { -// if(locatSequence.timeFlag != sequence.timeflag()) -// { -// return; -// } -// } -// } - - for(int nSeqIndex(0); nSeqIndex < sequence.nodelist_size(); nSeqIndex++) - { - kbd_idlfile::sequence::FucNodeStatusParameter function = sequence.nodelist(nSeqIndex); - QString functionDescription = QString::fromStdString(function.fuc_desc()); - for(int nFuncIndex(0); nFuncIndex < function.nodelist_size(); nFuncIndex++) - { - kbd_idlfile::sequence::ActionNodeStatusParameter action = function.nodelist(nFuncIndex); - QString actionDescription = QString::fromStdString(action.action_desc()); - QString content = QString("%1: [%2]\n%3: [%4]\n%5: [%6]\n").arg(tr("顺控名称")).arg(sequenceDescription).arg(tr("功能名称")).arg(functionDescription).arg(tr("动作名称")).arg(actionDescription); - QString description = QString("%1 %2").arg(QString::fromStdString(strErrorDescription)).arg(tr("请求人工干预!")); - - m_userInterveneRequestDialog = new QMessageBox(QMessageBox::Question, tr("人工干预请求"), QString("%1\n%2").arg(content).arg(description)); - QAbstractButton * retry = m_userInterveneRequestDialog->addButton(tr("重试"), QMessageBox::AcceptRole); - QAbstractButton * stop = m_userInterveneRequestDialog->addButton(tr("终止"), QMessageBox::RejectRole); - QAbstractButton * skip = m_userInterveneRequestDialog->addButton(tr("跳过"), QMessageBox::NoRole); - m_userInterveneRequestDialog->exec(); - E_ACTION_TYPE type; - if (m_userInterveneRequestDialog->clickedButton() == retry) - { - type = E_Action_Retry; - } - else if (m_userInterveneRequestDialog->clickedButton() == stop) - { - type = E_Action_Stop; - } - else if (m_userInterveneRequestDialog->clickedButton() == skip) - { - type = E_Action_Skip; - } - kbd_idlfile::sequence::UiRequestMessageAck uiRequestMessageAck; - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - spSysInfo->getLocalNodeInfo(stNodeInfo); - } - - kbd_idlfile::sequence::SeqPkgHead * head = uiRequestMessageAck.mutable_pkg_head(); - head->set_source_tag("hmi"); - head->set_msg_type(kbd_idlfile::sequence::enumSeqOperateMessage); - head->set_source_domain(stNodeInfo.nDomainId); - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(msg.pkg_head().source_domain(), stLocationInfo); - head->set_target_domain(stLocationInfo.nDomainId); - head->set_para1(0); - head->set_para2(0); - - kbd_idlfile::sequence::ActorParameter* actor = uiRequestMessageAck.mutable_actor(); - actor->set_user_id(m_nUserId); - actor->set_user_groupid(m_nUserGrpId); - actor->set_host_name(stNodeInfo.strName); - actor->set_user_name(m_strUsrName); - kbd_idlfile::sequence::SeqNodeStatusParameter msgNodeParameter = msg.nodelist(); - kbd_idlfile::sequence::SeqNodeStatusParameter* seqNodeStatusParameter = uiRequestMessageAck.mutable_nodelist(); - *seqNodeStatusParameter = msgNodeParameter; - uiRequestMessageAck.set_optype((kbd_idlfile::sequence::ENUiOperateType)type); - m_seqMsgHandle->userInterveneResponse(uiRequestMessageAck); - } - } - if(m_userInterveneRequestDialog != NULL) - { - delete m_userInterveneRequestDialog; - } - m_userInterveneRequestDialog = NULL; -} - -void CSequenceWidget::slotUpdateActionActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state) -{ - if(E_Mode_Action == m_seqMode) - { - CActionSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - model->updateSequenceActualState(seqName, funcName, actionName, state); - } - } -} - -void CSequenceWidget::slotUpdateSequenceTimeFlag(const QString &seqName, const int &time) -{ - Q_UNUSED(seqName) - Q_UNUSED(time) -// for(int nIndex(0); nIndex < m_listSequence.size(); nIndex++) -// { -// if(E_Node_Sequence == m_listSequence[nIndex].nodeType && m_listSequence[nIndex].seqName == seqName) -// { -// if(m_listSequence[nIndex].timeFlag != time) -// { -// kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(m_listSequence[nIndex], E_Seq_Stop); -// msg.mutable_seq_node()->set_timeflag(time); -// m_seqMsgHandle->seqOperateRequest(msg); -// } -// } -// } -} - -void CSequenceWidget::seqExecute() -{ - if(m_pTableModel->rowCount() != 0) - { - if(E_Mode_Sequence == m_seqMode) - { - CLocationSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - QList sequenceList = model->sequenceData(); - foreach (Sequence sequence, sequenceList) - { - if(E_Node_Sequence == sequence.nodeType) - { - model->updateSequenceState(sequence.seqName, E_Exec_Reset); - kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, E_Seq_Start); - m_seqMsgHandle->seqOperateRequest(msg); - LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: E_Seq_Start", sequence.seqName.toStdString().c_str()); - } - } - } - } - else if(E_Mode_Action == m_seqMode) - { - E_SEQ_OPERATE type = E_Seq_Start; - if(ui->singleRadio->isChecked()) - { - type = E_Ses_Start; - } - - CActionSequModel * model = dynamic_cast(m_pTableModel); - QList sequenceList = model->sequenceData(); - foreach (Sequence sequence, sequenceList) - { - model->updateSequenceExecState(sequence.seqName, sequence.funcName, sequence.actionName, E_Exec_Reset); - } - - - foreach (Sequence sequence, m_listSequence) - { - if(E_Node_Sequence == sequence.nodeType) - { - kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, type); - m_seqMsgHandle->seqOperateRequest(msg); - LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: E_Seq_Start", sequence.seqName.toStdString().c_str()); - } - } - } - } - notify(tr("等待执行...")); -} - -void CSequenceWidget::slotExecute() -{ - CSeqPermDialog *dialog = new CSeqPermDialog(this, m_isGuard); - int ret = dialog->exec(); - if(ret == QDialog::Accepted) - { - seqExecute(); - } - delete dialog; - dialog = NULL; -} - -void CSequenceWidget::slotPause() -{ - if(m_pTableModel->rowCount() != 0) - { - E_SEQ_OPERATE type; - if(tr("暂停") == ui->pause->text()) - { - type = E_Seq_Pause; - } - else - { - type = E_Seq_Continue; - } - if(E_Mode_Sequence == m_seqMode) - { - CLocationSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - QList sequenceList = model->sequenceData(); - foreach (Sequence sequence, sequenceList) - { - if(E_Node_Sequence == sequence.nodeType) - { - kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, type); - m_seqMsgHandle->seqOperateRequest(msg); - LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: Pause/Continue", sequence.seqName.toStdString().c_str()); - } - } - } - } - else if(E_Mode_Action == m_seqMode) - { - E_SEQ_OPERATE type = E_Seq_Continue; - if(tr("暂停") == ui->pause->text()) - { - type = E_Seq_Pause; - } - else - { - type = E_Seq_Continue; - if(ui->singleRadio->isChecked()) - { - type = E_Ses_Continue; - } - } - - foreach (Sequence sequence, m_listSequence) - { - if(E_Node_Sequence == sequence.nodeType) - { - - kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, type); - m_seqMsgHandle->seqOperateRequest(msg); - LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: Pause/Continue", sequence.seqName.toStdString().c_str()); - - } - } - } - } - ui->execute->setEnabled(false); - if(tr("暂停") == ui->pause->text()) - { - notify(tr("等待暂停...")); - } - else - { - notify(tr("等待继续...")); - } -} - -void CSequenceWidget::slotStop() -{ - if(m_pTableModel->rowCount() != 0) - { - if(E_Mode_Sequence == m_seqMode) - { - CLocationSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - QList sequenceList = model->sequenceData(); - foreach (Sequence sequence, sequenceList) - { - if(E_Node_Sequence == sequence.nodeType) - { - kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, E_Seq_Stop); - m_seqMsgHandle->seqOperateRequest(msg); - LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: E_Seq_Stop", sequence.seqName.toStdString().c_str()); - } - } - } - } - else if(E_Mode_Action == m_seqMode) - { - foreach (Sequence sequence, m_listSequence) - { - if(E_Node_Sequence == sequence.nodeType) - { - - kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, E_Seq_Stop); - m_seqMsgHandle->seqOperateRequest(msg); - LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: E_Seq_Stop", sequence.seqName.toStdString().c_str()); - - } - } - } - } - notify(tr("等待终止...")); -} - -kbd_idlfile::sequence::SeqOperateMessage CSequenceWidget::buildSequenceRequest(const Sequence &sequence, const E_SEQ_OPERATE &type) -{ - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (kbd_public::createSysInfoInstance(spSysInfo)) - { - spSysInfo->getLocalNodeInfo(stNodeInfo); - } - - kbd_idlfile::sequence::SeqOperateMessage sequenceRequestMsg; - kbd_idlfile::sequence::SeqPkgHead * head = sequenceRequestMsg.mutable_pkg_head(); - head->set_source_tag("hmi"); - head->set_msg_type(kbd_idlfile::sequence::enumSeqOperateMessage); - head->set_source_domain(stNodeInfo.nDomainId); - - kbd_public::SLocationInfo stLocationInfo; - spSysInfo->getLocationInfoById(sequence.locationID, stLocationInfo); - head->set_target_domain(stLocationInfo.nDomainId); - - LOGINFO("Build Sequence Request[name: %s, source_domain: %d, target_domain: %d]", sequence.seqName.toStdString().c_str(), stNodeInfo.nDomainId, stLocationInfo.nDomainId); - - head->set_para1(0); - head->set_para2(0); - - kbd_idlfile::sequence::SeqNodeStatusParameter* node = sequenceRequestMsg.mutable_seq_node(); - node->set_seq_name(sequence.seqName.toStdString()); - node->set_seq_desc(sequence.seqDescription.toStdString()); - kbd_idlfile::sequence::ENSeqNodeCheckStatus checkState = (E_Mode_Action == m_seqMode) ? kbd_idlfile::sequence::enumnodePartiallyChecked : kbd_idlfile::sequence::enumNodeChecked; - node->set_check_state(checkState); - node->set_timeflag(sequence.timeFlag); - node->set_node_state((kbd_idlfile::sequence::ENSeqStatus)sequence.executeState); - - if(E_Mode_Action == m_seqMode) - { - CActionSequModel * model = dynamic_cast(m_pTableModel); - if(model) - { - foreach(Sequence sequenceFunc, m_listSequence) - { - if(E_Node_Function == sequenceFunc.nodeType) - { - kbd_idlfile::sequence::FucNodeStatusParameter* func = node->add_nodelist(); - func->set_fuc_name(sequenceFunc.funcName.toStdString()); - func->set_fuc_desc(sequenceFunc.funcDescription.toStdString()); - func->set_check_state(kbd_idlfile::sequence::enumnodePartiallyChecked); - func->set_timeflag(sequenceFunc.timeFlag); - func->set_node_state((kbd_idlfile::sequence::ENSeqStatus)sequenceFunc.executeState); - QList listSequence = model->sequenceData(); - foreach (Sequence sequenceAction, listSequence) - { - if(E_Node_Action == sequenceAction.nodeType && sequenceFunc.funcName == sequenceAction.funcName) - { - kbd_idlfile::sequence::ActionNodeStatusParameter* action = func->add_nodelist(); - action->set_action_name(sequenceAction.actionName.toStdString()); - action->set_action_desc(sequenceAction.actionDescription.toStdString()); - action->set_check_state((kbd_idlfile::sequence::ENSeqNodeCheckStatus)sequenceAction.checkState); - action->set_timeflag(sequenceAction.timeFlag); - action->set_node_state((kbd_idlfile::sequence::ENSeqStatus)sequenceAction.executeState); - } - } - } - } - } - } - - kbd_idlfile::sequence::ActorParameter* actor = sequenceRequestMsg.mutable_actor(); - actor->set_user_id(m_nUserId); - actor->set_user_groupid(m_nUserGrpId); - actor->set_host_name(stNodeInfo.strName); - actor->set_user_name(m_strUsrName); - sequenceRequestMsg.set_opreate_type((kbd_idlfile::sequence::ENSeqOperateType)type); - return sequenceRequestMsg; -} - -QString CSequenceWidget::operateDescription(const E_SEQ_OPERATE &type) -{ - switch (type) - { - case E_Seq_Start: - return tr("顺控开始"); - case E_Seq_Stop: - return tr("顺控终止"); - case E_Seq_Pause: - return tr("顺控暂停"); - case E_Seq_Continue: - return tr("顺控继续"); - case E_Ses_Start: - return tr("单步开始"); - case E_Ses_Continue: - return tr("单步继续"); - default: - return QString(); - } - return QString(); -} - -QString CSequenceWidget::stateDescription(const E_EXECUTING_STATE &state) -{ - switch (state) - { - case E_Exec_Reset: - return tr("未执行"); - case E_Exec_Run: - return tr("正在执行"); - case E_Exec_Triggered: - return tr("已触发"); - case E_Exec_Failed: - return tr("执行失败"); - case E_Exec_Success: - return tr("执行成功"); - case E_Exec_Stop: - return tr("执行终止"); - case E_Exec_Pause: - return tr("执行暂停"); - case E_Exec_Skip: - return tr("执行跳过"); - default: - return QString(); - } - return QString(); -} - -void CSequenceWidget::notify(const QString &strTips) -{ - ui->toolTipsLabel->clear(); - ui->toolTipsLabel->setText(strTips); -} - -bool CSequenceWidget::getSeqCtrlPerm() -{ - //<权限处理 - kbd_service::CPermMngApiPtr permManage = kbd_service::getPermMngInstance("base"); - permManage->PermDllInit(); - - int nLevel; - int nLoginSec; - std::string instanceName; - if(0 == permManage->CurUser(m_nUserId, m_nUserGrpId, nLevel, nLoginSec, instanceName)) - { - permManage->GetUserAliasByUserId(m_nUserId, m_strUsrName); - std::string tmp = FUNC_NOM_PSCADA_SEQ_CTRL; - if (PERM_PERMIT == permManage->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) - { - return true; - } - } - return false; -} - -void CSequenceWidget::updateUiVisible(bool bEnable) -{ - ui->execute->setVisible(bEnable); - ui->pause->setVisible(bEnable); - ui->stop->setVisible(bEnable); -} - -void CSequenceWidget::updateUiEnable(bool bEnable) -{ - if(!bEnable) - { - ui->execute->setEnabled(false); - ui->pause->setText(tr("暂停")); - ui->pause->setEnabled(false); - ui->stop->setEnabled(false); - } -} - -void CSequenceWidget::updateUiRun() -{ - ui->execute->setEnabled(false); - ui->pause->setText(tr("暂停")); - ui->pause->setEnabled(true); - ui->stop->setEnabled(true); -} - -void CSequenceWidget::updateUiPause() -{ - ui->execute->setEnabled(false); - ui->pause->setText(tr("继续")); - ui->pause->setEnabled(true); - ui->stop->setEnabled(true); -} - -void CSequenceWidget::updateUiStop() -{ - ui->execute->setEnabled(true); - notify(tr("")); - ui->pause->setText(tr("暂停")); - ui->pause->setEnabled(false); - ui->stop->setEnabled(false); -} - -void CSequenceWidget::updateUiFinish() -{ - ui->execute->setEnabled(false); - ui->pause->setText(tr("暂停")); - ui->pause->setEnabled(false); - ui->stop->setEnabled(false); -} +#include "CSequenceWidget.h" +#include "ui_CSequenceWidget.h" +#include +#include +#include "CLocationSequModel.h" +#include "CActionSequModel.h" +#include "CSequenceDataManage.h" +#include "CSequenceStateManage.h" +#include "CSequenceMsgHandle.h" +#include "sequence_def.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_utility_api/FileStyle.h" +#include "CSeqPermDialog.h" + +CSequenceWidget::CSequenceWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CSequenceWidget), + m_seqMode(E_Mode_Invalid), + m_permTimer(NULL), + m_pTableModel(NULL), + m_seqDataManage(NULL), + m_seqStateManage(NULL), + m_seqMsgHandle(NULL), + m_userInterveneRequestDialog(NULL), + m_editMode(editMode), + m_isOwnerPerm(false), + m_isGuard(true) +{ + ui->setupUi(this); + qRegisterMetaType("E_SEQ_OPERATE"); + qRegisterMetaType("E_EXECUTING_STATE"); + qRegisterMetaType("kbd_idlfile::sequence::UiRequestMessage"); + qRegisterMetaType >("SEQUENCELIST"); + + m_nUserId = -1; + m_strUsrName = ""; + m_nUserGrpId = -1; + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("sequence.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +CSequenceWidget::~CSequenceWidget() +{ + if(m_seqMsgHandle) + { + m_seqMsgHandle->stop(); + delete m_seqMsgHandle; + } + m_seqMsgHandle = NULL; + + if(m_pTableModel) + { + delete m_pTableModel; + } + m_pTableModel = NULL; + + if(m_seqDataManage) + { + delete m_seqDataManage; + } + m_seqDataManage = NULL; + + if(m_seqStateManage) + { + delete m_seqStateManage; + } + m_seqStateManage = NULL; + + if(m_userInterveneRequestDialog) + { + delete m_userInterveneRequestDialog; + } + m_userInterveneRequestDialog = NULL; + + delete ui; + qDebug() << "~CSequenceWidget()"; +} + +void CSequenceWidget::login() +{ + updatePerm(); + if(m_seqMsgHandle) + { + m_seqMsgHandle->start(); + } + if(E_Mode_Sequence == m_seqMode) + { + loadSequenceData(m_seqNameList); + notify(tr("")); + } +} + +void CSequenceWidget::logout() +{ + updatePerm(); + if(m_seqMsgHandle) + { + m_seqMsgHandle->stop(); + } + + if(m_seqStateManage) + { + m_seqStateManage->slotUnSubScribeSequenceList(); + } +} + +void CSequenceWidget::setEditMode(bool editMode) +{ + m_editMode = editMode; +} + +void CSequenceWidget::setTitleVisable(bool bEnable) +{ + ui->seqTitlelabel->setVisible(bEnable); + ui->seqNameLabel->setVisible(bEnable); +// ui->sequenceTitle->setVisible(bEnable); +} + +QStringList CSequenceWidget::currentSequenceName() +{ + return m_seqNameList; +} + +void CSequenceWidget::release() +{ + if(m_seqMsgHandle) + { + m_seqMsgHandle->stop(); + } + + if(m_seqStateManage) + { + m_seqStateManage->slotUnSubScribeSequenceList(); + } + + if(m_pTableModel) + { + delete m_pTableModel; + } + m_pTableModel = NULL; + +} + +void CSequenceWidget::initialize(int seqMode, QStringList listSequenceName, kbd_dbms::CDbApi *dbRead) +{ + if(m_editMode) + { + return; + } + + m_seqMode = (E_MODE_TYPE)seqMode; + + //<无效判断 + if(E_Mode_Sequence != seqMode && E_Mode_Action != seqMode) + { + return; + } + + //<初始化 + if(E_Mode_Sequence == m_seqMode) + { + m_pTableModel = new CLocationSequModel(this); + } + else + { + m_pTableModel = new CActionSequModel(this); + } +// QItemSelectionModel * oldModel = ui->view->selectionModel(); + ui->view->setModel(m_pTableModel); +// if(oldModel) +// { +// oldModel->deleteLater(); +// } + + if(m_seqNameList.isEmpty()) + { + ui->view->setColumnWidth(0,50); + ui->view->setColumnWidth(1,200); + + connect(ui->execute, &QPushButton::clicked, this, &CSequenceWidget::slotExecute); + connect(ui->pause, &QPushButton::clicked, this, &CSequenceWidget::slotPause); + connect(ui->stop, &QPushButton::clicked, this, &CSequenceWidget::slotStop); + + + m_seqDataManage = new CSequenceDataManage(NULL, dbRead); + m_seqMsgHandle = new CSequenceMsgHandle(); + m_seqStateManage = new CSequenceStateManage(NULL, dbRead); + m_seqMsgHandle->setDataManager(m_seqDataManage); + connect(m_seqDataManage, &CSequenceDataManage::sigRecvSequenceResponse, this, &CSequenceWidget::slotRecvSeqOperateResponse, Qt::QueuedConnection); + connect(m_seqDataManage, &CSequenceDataManage::sigRecvSequenceResponseErrorMsg, this, &CSequenceWidget::slotRecvSeqOperateResponseErrorMsg, Qt::QueuedConnection); + connect(m_seqDataManage, &CSequenceDataManage::sigRecvSequenceStateError, this, &CSequenceWidget::slotRecvSequenceStateError, Qt::QueuedConnection); + connect(m_seqDataManage, &CSequenceDataManage::sigRecvSequenceStateChanged, this, &CSequenceWidget::slotRecvSequenceStateChanged, Qt::QueuedConnection); + connect(m_seqDataManage, &CSequenceDataManage::sigRecvFunctionStateChanged, this, &CSequenceWidget::slotRecvFunctionStateChanged, Qt::QueuedConnection); + connect(m_seqDataManage, &CSequenceDataManage::sigRecvActionStateChanged, this, &CSequenceWidget::slotRecvActionStateChanged, Qt::QueuedConnection); + connect(m_seqDataManage, &CSequenceDataManage::sigRecvUserInterveneRequest, this, &CSequenceWidget::slotRecvUserInterveneRequest, Qt::QueuedConnection); + + connect(m_seqStateManage, &CSequenceStateManage::sigUpdateSequenceState, this, &CSequenceWidget::slotRecvSequenceStateChanged, Qt::QueuedConnection); + connect(m_seqStateManage, &CSequenceStateManage::sigUpdateFunctionState, this, &CSequenceWidget::slotRecvFunctionStateChanged, Qt::QueuedConnection); + connect(m_seqStateManage, &CSequenceStateManage::sigUpdateActionState, this, &CSequenceWidget::slotRecvActionStateChanged, Qt::QueuedConnection); + connect(m_seqStateManage, &CSequenceStateManage::sigUpdateActionActualState, this, &CSequenceWidget::slotUpdateActionActualState, Qt::QueuedConnection); + connect(m_seqStateManage, &CSequenceStateManage::sigUpdateSequenceTimeFlag, this, &CSequenceWidget::slotUpdateSequenceTimeFlag, Qt::QueuedConnection); + + connect(this, &CSequenceWidget::sigSubScribeSequenceList, m_seqStateManage, &CSequenceStateManage::slotSubScribeSequenceList, Qt::QueuedConnection); + connect(this, &CSequenceWidget::sigUnSubScribeSequence, m_seqStateManage, &CSequenceStateManage::slotUnSubScribeSequenceList, Qt::QueuedConnection); + + m_permTimer = new QTimer(); + m_permTimer->setInterval(1000); + connect(m_permTimer, &QTimer::timeout, this, &CSequenceWidget::updatePerm); + m_permTimer->start(); + } + m_seqMsgHandle->start(); + loadSequenceData(listSequenceName); + notify(tr("")); + ui->view->setColumnWidth(1, 300); +} + +void CSequenceWidget::loadSequenceData(QStringList listSequenceName) +{ + if(listSequenceName.isEmpty()) + { + return; + } + + emit sigUnSubScribeSequence(); + notify(""); + + ui->execute->setEnabled(false); + ui->pause->setText(tr("暂停")); + notify(tr("正在查询...")); + ui->pause->setEnabled(false); + ui->stop->setEnabled(false); + + m_seqNameList = listSequenceName; + ui->seqNameLabel->setText(m_seqNameList.first()); + + m_listSequence.clear(); + QList listSequence; + m_listSequence = m_seqDataManage->querySequenceList(m_seqNameList); + + emit sigSubScribeSequenceList(m_listSequence); + + if(E_Mode_Sequence == m_seqMode) + { + foreach (Sequence item, m_listSequence) + { + if(E_Node_Action != item.nodeType) + { + if(E_Node_Sequence == item.nodeType) + { + listSequence.append(item); + } + } + } + CLocationSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + model->initSequenceData(listSequence); + } + } + else if(E_Mode_Action == m_seqMode) + { + + foreach (Sequence item, m_listSequence) + { + if(E_Node_Action == item.nodeType) + { + listSequence.append(item); + } + } + CActionSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + model->initSequenceData(listSequence); + } + } + + if(!listSequence.isEmpty()) + { + ui->view->selectRow(0); + } +} + +void CSequenceWidget::updatePerm() +{ + bool isPerm = getSeqCtrlPerm(); + ui->execute->setVisible(isPerm); + ui->pause->setVisible(isPerm); + ui->stop->setVisible(isPerm); +} + +void CSequenceWidget::setGuard(bool guard) +{ + m_isGuard = guard; +} + +void CSequenceWidget::slotRecvSeqOperateResponse(const QString &seqName, const E_SEQ_OPERATE &type) +{ + QString content = tr("服务应答 [%1]:%2").arg(seqName).arg(operateDescription(type)); + notify(content); +} + +void CSequenceWidget::slotRecvSeqOperateResponseErrorMsg(const QString &seqName, const E_SEQ_OPERATE &type, const QString &errorInfo) +{ + Q_UNUSED(seqName) + Q_UNUSED(type) + QString content = tr("服务应答-错误 [%1]").arg(errorInfo); + notify(content); +} + +void CSequenceWidget::slotRecvSequenceStateError(const QString &seqName, const int &errorCode, const QString &errorDescription) +{ + Q_UNUSED(seqName) + Q_UNUSED(errorCode) + Q_UNUSED(errorDescription) + QString content = tr("%1[%2]\n%3%4\n%5%6\n").arg(tr("顺控名称: ")).arg(seqName).arg(tr("错误代码: ")).arg(errorCode).arg(tr("错误描述: ")).arg(errorDescription); + notify(content); + // QMessageBox::warning(NULL, tr("执行出错"), content); +} + +void CSequenceWidget::slotRecvSequenceStateChanged(const QString &seqName, const E_EXECUTING_STATE &state) +{ + emit sigSequenceStateChanged(seqName, state); + for(int nIndex(0); nIndex < m_listSequence.size(); nIndex++) + { + if(E_Node_Sequence == m_listSequence[nIndex].nodeType && m_listSequence[nIndex].seqName == seqName) + { + if(m_listSequence[nIndex].executeState != state) + { + m_listSequence[nIndex].executeState = state; + QString content = tr("状态变化 [顺控-%1]:%2").arg(m_listSequence[nIndex].seqDescription).arg(stateDescription(state)); + notify(content); + } + } + } + + if(E_Mode_Sequence == m_seqMode && m_seqNameList.contains(seqName)) + { + CLocationSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + model->updateSequenceState(seqName, state); + } + bool isFinish = true; + QList listSequence = model->sequenceData(); + for(int nIndex(0); nIndex < listSequence.size(); nIndex++) + { + if(E_Check_Checked == listSequence[nIndex].checkState && ( + E_Exec_Success != listSequence[nIndex].executeState && + E_Exec_Stop != listSequence[nIndex].executeState && + E_Exec_Skip != listSequence[nIndex].executeState)) + { + isFinish = false; + break; + } + } + if(isFinish) + { + ui->execute->setEnabled(true); + ui->pause->setText(tr("暂停")); + ui->pause->setEnabled(false); + ui->stop->setEnabled(false); + } + } + else if(E_Mode_Action == m_seqMode && m_seqNameList.contains(seqName)) + { + if(E_Exec_Run == state) + { + updateUiRun(); + } + else if(E_Exec_Pause == state) + { + updateUiPause(); + } + else if(E_Exec_Reset == state) + { + updateUiStop(); + } + else if(E_Exec_Success == state || E_Exec_Stop == state || E_Exec_Failed == state) + { + updateUiFinish(); + } + } +} + +void CSequenceWidget::slotRecvFunctionStateChanged(const QString &seqName, const QString &funcName, const E_EXECUTING_STATE &state) +{ + if(E_Mode_Action == m_seqMode) + { + QString seqDesc; + foreach (Sequence sequence, m_listSequence) + { + if(sequence.seqName == seqName && sequence.nodeType == E_Node_Sequence) + { + seqDesc = sequence.seqDescription; + } + } + + foreach (Sequence sequence, m_listSequence) + { + if(sequence.seqName == seqName && sequence.funcName == funcName) + { + if(sequence.executeState != state) + { + QString content = tr("状态变化 [顺控-%1] [功能-%2]:%3").arg(seqDesc).arg(sequence.funcDescription).arg(stateDescription(state)); + notify(content); + break; + } + } + } + } +} + +void CSequenceWidget::slotRecvActionStateChanged(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state) +{ + QString seqDesc; + QString funcDesc; + foreach (Sequence sequence, m_listSequence) + { + if(sequence.seqName == seqName && sequence.nodeType == E_Node_Sequence) + { + seqDesc = sequence.seqDescription; + } + if(sequence.seqName == seqName && sequence.funcName == funcName && sequence.nodeType == E_Node_Function) + { + funcDesc = sequence.funcDescription; + } + } + + for(int nIndex(0); nIndex < m_listSequence.size(); nIndex++) + { + if(E_Node_Action == m_listSequence[nIndex].nodeType && + m_listSequence[nIndex].seqName == seqName && + m_listSequence[nIndex].funcName == funcName && + m_listSequence[nIndex].actionName == actionName) + { + if(m_listSequence[nIndex].executeState != state) + { + m_listSequence[nIndex].executeState = state; + QString content = tr("状态变化 [顺控-%1] [功能-%2] [动作-%3]:%4").arg(seqDesc).arg(funcDesc).arg(m_listSequence[nIndex].actionDescription).arg(stateDescription(state)); + notify(content); + + if(E_Mode_Action == m_seqMode) + { + CActionSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + model->updateSequenceExecState(seqName, funcName, actionName, state); + } + } + } + } + } +} + + + +void CSequenceWidget::slotRecvUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage *msg) +{ + if(!getSeqCtrlPerm()) + { + return; + } + handleUserInterveneRequest(*msg); + delete msg; +} + +void CSequenceWidget::handleUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage &msg) +{ + if(NULL != m_userInterveneRequestDialog) + { + return; + } + std::string strErrorDescription = ""; + kbd_idlfile::sequence::ExecuteStatusParameter executeStatueParameter = msg.execute_status(); + if(0 != executeStatueParameter.statuscode() && executeStatueParameter.has_erro_param()) + { + kbd_idlfile::sequence::ErrorParameter paramter = executeStatueParameter.erro_param(); + strErrorDescription = paramter.errordescription(); + } + + kbd_idlfile::sequence::SeqNodeStatusParameter sequence = msg.nodelist(); + QString sequenceDescription = QString::fromStdString(sequence.seq_desc()); +// foreach (Sequence locatSequence, m_listSequence) +// { +// if(E_Node_Sequence == locatSequence.nodeType && locatSequence.seqName == sequenceName) +// { +// if(locatSequence.timeFlag != sequence.timeflag()) +// { +// return; +// } +// } +// } + + for(int nSeqIndex(0); nSeqIndex < sequence.nodelist_size(); nSeqIndex++) + { + kbd_idlfile::sequence::FucNodeStatusParameter function = sequence.nodelist(nSeqIndex); + QString functionDescription = QString::fromStdString(function.fuc_desc()); + for(int nFuncIndex(0); nFuncIndex < function.nodelist_size(); nFuncIndex++) + { + kbd_idlfile::sequence::ActionNodeStatusParameter action = function.nodelist(nFuncIndex); + QString actionDescription = QString::fromStdString(action.action_desc()); + QString content = QString("%1: [%2]\n%3: [%4]\n%5: [%6]\n").arg(tr("顺控名称")).arg(sequenceDescription).arg(tr("功能名称")).arg(functionDescription).arg(tr("动作名称")).arg(actionDescription); + QString description = QString("%1 %2").arg(QString::fromStdString(strErrorDescription)).arg(tr("请求人工干预!")); + + m_userInterveneRequestDialog = new QMessageBox(QMessageBox::Question, tr("人工干预请求"), QString("%1\n%2").arg(content).arg(description)); + QAbstractButton * retry = m_userInterveneRequestDialog->addButton(tr("重试"), QMessageBox::AcceptRole); + QAbstractButton * stop = m_userInterveneRequestDialog->addButton(tr("终止"), QMessageBox::RejectRole); + QAbstractButton * skip = m_userInterveneRequestDialog->addButton(tr("跳过"), QMessageBox::NoRole); + m_userInterveneRequestDialog->exec(); + E_ACTION_TYPE type; + if (m_userInterveneRequestDialog->clickedButton() == retry) + { + type = E_Action_Retry; + } + else if (m_userInterveneRequestDialog->clickedButton() == stop) + { + type = E_Action_Stop; + } + else if (m_userInterveneRequestDialog->clickedButton() == skip) + { + type = E_Action_Skip; + } + kbd_idlfile::sequence::UiRequestMessageAck uiRequestMessageAck; + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + spSysInfo->getLocalNodeInfo(stNodeInfo); + } + + kbd_idlfile::sequence::SeqPkgHead * head = uiRequestMessageAck.mutable_pkg_head(); + head->set_source_tag("hmi"); + head->set_msg_type(kbd_idlfile::sequence::enumSeqOperateMessage); + head->set_source_domain(stNodeInfo.nDomainId); + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(msg.pkg_head().source_domain(), stLocationInfo); + head->set_target_domain(stLocationInfo.nDomainId); + head->set_para1(0); + head->set_para2(0); + + kbd_idlfile::sequence::ActorParameter* actor = uiRequestMessageAck.mutable_actor(); + actor->set_user_id(m_nUserId); + actor->set_user_groupid(m_nUserGrpId); + actor->set_host_name(stNodeInfo.strName); + actor->set_user_name(m_strUsrName); + kbd_idlfile::sequence::SeqNodeStatusParameter msgNodeParameter = msg.nodelist(); + kbd_idlfile::sequence::SeqNodeStatusParameter* seqNodeStatusParameter = uiRequestMessageAck.mutable_nodelist(); + *seqNodeStatusParameter = msgNodeParameter; + uiRequestMessageAck.set_optype((kbd_idlfile::sequence::ENUiOperateType)type); + m_seqMsgHandle->userInterveneResponse(uiRequestMessageAck); + } + } + if(m_userInterveneRequestDialog != NULL) + { + delete m_userInterveneRequestDialog; + } + m_userInterveneRequestDialog = NULL; +} + +void CSequenceWidget::slotUpdateActionActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state) +{ + if(E_Mode_Action == m_seqMode) + { + CActionSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + model->updateSequenceActualState(seqName, funcName, actionName, state); + } + } +} + +void CSequenceWidget::slotUpdateSequenceTimeFlag(const QString &seqName, const int &time) +{ + Q_UNUSED(seqName) + Q_UNUSED(time) +// for(int nIndex(0); nIndex < m_listSequence.size(); nIndex++) +// { +// if(E_Node_Sequence == m_listSequence[nIndex].nodeType && m_listSequence[nIndex].seqName == seqName) +// { +// if(m_listSequence[nIndex].timeFlag != time) +// { +// kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(m_listSequence[nIndex], E_Seq_Stop); +// msg.mutable_seq_node()->set_timeflag(time); +// m_seqMsgHandle->seqOperateRequest(msg); +// } +// } +// } +} + +void CSequenceWidget::seqExecute() +{ + if(m_pTableModel->rowCount() != 0) + { + if(E_Mode_Sequence == m_seqMode) + { + CLocationSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + QList sequenceList = model->sequenceData(); + foreach (Sequence sequence, sequenceList) + { + if(E_Node_Sequence == sequence.nodeType) + { + model->updateSequenceState(sequence.seqName, E_Exec_Reset); + kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, E_Seq_Start); + m_seqMsgHandle->seqOperateRequest(msg); + LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: E_Seq_Start", sequence.seqName.toStdString().c_str()); + } + } + } + } + else if(E_Mode_Action == m_seqMode) + { + E_SEQ_OPERATE type = E_Seq_Start; + if(ui->singleRadio->isChecked()) + { + type = E_Ses_Start; + } + + CActionSequModel * model = dynamic_cast(m_pTableModel); + QList sequenceList = model->sequenceData(); + foreach (Sequence sequence, sequenceList) + { + model->updateSequenceExecState(sequence.seqName, sequence.funcName, sequence.actionName, E_Exec_Reset); + } + + + foreach (Sequence sequence, m_listSequence) + { + if(E_Node_Sequence == sequence.nodeType) + { + kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, type); + m_seqMsgHandle->seqOperateRequest(msg); + LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: E_Seq_Start", sequence.seqName.toStdString().c_str()); + } + } + } + } + notify(tr("等待执行...")); +} + +void CSequenceWidget::slotExecute() +{ + CSeqPermDialog *dialog = new CSeqPermDialog(this, m_isGuard); + int ret = dialog->exec(); + if(ret == QDialog::Accepted) + { + seqExecute(); + } + delete dialog; + dialog = NULL; +} + +void CSequenceWidget::slotPause() +{ + if(m_pTableModel->rowCount() != 0) + { + E_SEQ_OPERATE type; + if(tr("暂停") == ui->pause->text()) + { + type = E_Seq_Pause; + } + else + { + type = E_Seq_Continue; + } + if(E_Mode_Sequence == m_seqMode) + { + CLocationSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + QList sequenceList = model->sequenceData(); + foreach (Sequence sequence, sequenceList) + { + if(E_Node_Sequence == sequence.nodeType) + { + kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, type); + m_seqMsgHandle->seqOperateRequest(msg); + LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: Pause/Continue", sequence.seqName.toStdString().c_str()); + } + } + } + } + else if(E_Mode_Action == m_seqMode) + { + E_SEQ_OPERATE type = E_Seq_Continue; + if(tr("暂停") == ui->pause->text()) + { + type = E_Seq_Pause; + } + else + { + type = E_Seq_Continue; + if(ui->singleRadio->isChecked()) + { + type = E_Ses_Continue; + } + } + + foreach (Sequence sequence, m_listSequence) + { + if(E_Node_Sequence == sequence.nodeType) + { + + kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, type); + m_seqMsgHandle->seqOperateRequest(msg); + LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: Pause/Continue", sequence.seqName.toStdString().c_str()); + + } + } + } + } + ui->execute->setEnabled(false); + if(tr("暂停") == ui->pause->text()) + { + notify(tr("等待暂停...")); + } + else + { + notify(tr("等待继续...")); + } +} + +void CSequenceWidget::slotStop() +{ + if(m_pTableModel->rowCount() != 0) + { + if(E_Mode_Sequence == m_seqMode) + { + CLocationSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + QList sequenceList = model->sequenceData(); + foreach (Sequence sequence, sequenceList) + { + if(E_Node_Sequence == sequence.nodeType) + { + kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, E_Seq_Stop); + m_seqMsgHandle->seqOperateRequest(msg); + LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: E_Seq_Stop", sequence.seqName.toStdString().c_str()); + } + } + } + } + else if(E_Mode_Action == m_seqMode) + { + foreach (Sequence sequence, m_listSequence) + { + if(E_Node_Sequence == sequence.nodeType) + { + + kbd_idlfile::sequence::SeqOperateMessage msg = buildSequenceRequest(sequence, E_Seq_Stop); + m_seqMsgHandle->seqOperateRequest(msg); + LOGINFO("SequenceMsgHandle send sequence OperateRequest! msgName: %s, msgType: E_Seq_Stop", sequence.seqName.toStdString().c_str()); + + } + } + } + } + notify(tr("等待终止...")); +} + +kbd_idlfile::sequence::SeqOperateMessage CSequenceWidget::buildSequenceRequest(const Sequence &sequence, const E_SEQ_OPERATE &type) +{ + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (kbd_public::createSysInfoInstance(spSysInfo)) + { + spSysInfo->getLocalNodeInfo(stNodeInfo); + } + + kbd_idlfile::sequence::SeqOperateMessage sequenceRequestMsg; + kbd_idlfile::sequence::SeqPkgHead * head = sequenceRequestMsg.mutable_pkg_head(); + head->set_source_tag("hmi"); + head->set_msg_type(kbd_idlfile::sequence::enumSeqOperateMessage); + head->set_source_domain(stNodeInfo.nDomainId); + + kbd_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(sequence.locationID, stLocationInfo); + head->set_target_domain(stLocationInfo.nDomainId); + + LOGINFO("Build Sequence Request[name: %s, source_domain: %d, target_domain: %d]", sequence.seqName.toStdString().c_str(), stNodeInfo.nDomainId, stLocationInfo.nDomainId); + + head->set_para1(0); + head->set_para2(0); + + kbd_idlfile::sequence::SeqNodeStatusParameter* node = sequenceRequestMsg.mutable_seq_node(); + node->set_seq_name(sequence.seqName.toStdString()); + node->set_seq_desc(sequence.seqDescription.toStdString()); + kbd_idlfile::sequence::ENSeqNodeCheckStatus checkState = (E_Mode_Action == m_seqMode) ? kbd_idlfile::sequence::enumnodePartiallyChecked : kbd_idlfile::sequence::enumNodeChecked; + node->set_check_state(checkState); + node->set_timeflag(sequence.timeFlag); + node->set_node_state((kbd_idlfile::sequence::ENSeqStatus)sequence.executeState); + + if(E_Mode_Action == m_seqMode) + { + CActionSequModel * model = dynamic_cast(m_pTableModel); + if(model) + { + foreach(Sequence sequenceFunc, m_listSequence) + { + if(E_Node_Function == sequenceFunc.nodeType) + { + kbd_idlfile::sequence::FucNodeStatusParameter* func = node->add_nodelist(); + func->set_fuc_name(sequenceFunc.funcName.toStdString()); + func->set_fuc_desc(sequenceFunc.funcDescription.toStdString()); + func->set_check_state(kbd_idlfile::sequence::enumnodePartiallyChecked); + func->set_timeflag(sequenceFunc.timeFlag); + func->set_node_state((kbd_idlfile::sequence::ENSeqStatus)sequenceFunc.executeState); + QList listSequence = model->sequenceData(); + foreach (Sequence sequenceAction, listSequence) + { + if(E_Node_Action == sequenceAction.nodeType && sequenceFunc.funcName == sequenceAction.funcName) + { + kbd_idlfile::sequence::ActionNodeStatusParameter* action = func->add_nodelist(); + action->set_action_name(sequenceAction.actionName.toStdString()); + action->set_action_desc(sequenceAction.actionDescription.toStdString()); + action->set_check_state((kbd_idlfile::sequence::ENSeqNodeCheckStatus)sequenceAction.checkState); + action->set_timeflag(sequenceAction.timeFlag); + action->set_node_state((kbd_idlfile::sequence::ENSeqStatus)sequenceAction.executeState); + } + } + } + } + } + } + + kbd_idlfile::sequence::ActorParameter* actor = sequenceRequestMsg.mutable_actor(); + actor->set_user_id(m_nUserId); + actor->set_user_groupid(m_nUserGrpId); + actor->set_host_name(stNodeInfo.strName); + actor->set_user_name(m_strUsrName); + sequenceRequestMsg.set_opreate_type((kbd_idlfile::sequence::ENSeqOperateType)type); + return sequenceRequestMsg; +} + +QString CSequenceWidget::operateDescription(const E_SEQ_OPERATE &type) +{ + switch (type) + { + case E_Seq_Start: + return tr("顺控开始"); + case E_Seq_Stop: + return tr("顺控终止"); + case E_Seq_Pause: + return tr("顺控暂停"); + case E_Seq_Continue: + return tr("顺控继续"); + case E_Ses_Start: + return tr("单步开始"); + case E_Ses_Continue: + return tr("单步继续"); + default: + return QString(); + } + return QString(); +} + +QString CSequenceWidget::stateDescription(const E_EXECUTING_STATE &state) +{ + switch (state) + { + case E_Exec_Reset: + return tr("未执行"); + case E_Exec_Run: + return tr("正在执行"); + case E_Exec_Triggered: + return tr("已触发"); + case E_Exec_Failed: + return tr("执行失败"); + case E_Exec_Success: + return tr("执行成功"); + case E_Exec_Stop: + return tr("执行终止"); + case E_Exec_Pause: + return tr("执行暂停"); + case E_Exec_Skip: + return tr("执行跳过"); + default: + return QString(); + } + return QString(); +} + +void CSequenceWidget::notify(const QString &strTips) +{ + ui->toolTipsLabel->clear(); + ui->toolTipsLabel->setText(strTips); +} + +bool CSequenceWidget::getSeqCtrlPerm() +{ + //<权限处理 + kbd_service::CPermMngApiPtr permManage = kbd_service::getPermMngInstance("base"); + permManage->PermDllInit(); + + int nLevel; + int nLoginSec; + std::string instanceName; + if(0 == permManage->CurUser(m_nUserId, m_nUserGrpId, nLevel, nLoginSec, instanceName)) + { + permManage->GetUserAliasByUserId(m_nUserId, m_strUsrName); + std::string tmp = FUNC_NOM_PSCADA_SEQ_CTRL; + if (PERM_PERMIT == permManage->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) + { + return true; + } + } + return false; +} + +void CSequenceWidget::updateUiVisible(bool bEnable) +{ + ui->execute->setVisible(bEnable); + ui->pause->setVisible(bEnable); + ui->stop->setVisible(bEnable); +} + +void CSequenceWidget::updateUiEnable(bool bEnable) +{ + if(!bEnable) + { + ui->execute->setEnabled(false); + ui->pause->setText(tr("暂停")); + ui->pause->setEnabled(false); + ui->stop->setEnabled(false); + } +} + +void CSequenceWidget::updateUiRun() +{ + ui->execute->setEnabled(false); + ui->pause->setText(tr("暂停")); + ui->pause->setEnabled(true); + ui->stop->setEnabled(true); +} + +void CSequenceWidget::updateUiPause() +{ + ui->execute->setEnabled(false); + ui->pause->setText(tr("继续")); + ui->pause->setEnabled(true); + ui->stop->setEnabled(true); +} + +void CSequenceWidget::updateUiStop() +{ + ui->execute->setEnabled(true); + notify(tr("")); + ui->pause->setText(tr("暂停")); + ui->pause->setEnabled(false); + ui->stop->setEnabled(false); +} + +void CSequenceWidget::updateUiFinish() +{ + ui->execute->setEnabled(false); + ui->pause->setText(tr("暂停")); + ui->pause->setEnabled(false); + ui->stop->setEnabled(false); +} diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceWidget.h b/product/src/gui/plugin/SequenceWidget/CSequenceWidget.h index c9233865..1063165a 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceWidget.h +++ b/product/src/gui/plugin/SequenceWidget/CSequenceWidget.h @@ -1,118 +1,118 @@ -#ifndef CSEQUENCEWIDGET_H -#define CSEQUENCEWIDGET_H - -#include -#include "sequence_global.h" -#include "sequence_def.h" -#include "../../idl_files/SequenceMessage.pb.h" -#include "db_api_ex/CDbApi.h" - -//<顺控界面展示模式 -enum E_MODE_TYPE -{ - E_Mode_Invalid = -1, //<缺省无效模式 - E_Mode_Sequence, //<展示顺控 - E_Mode_Action //<展示动作 -}; - -namespace Ui { -class CSequenceWidget; -} - -struct Sequence; -class QThread; -class QMessageBox; -class QAbstractTableModel; -class CSequenceDataManage; -class CSequenceStateManage; -class CSequenceMsgHandle; - -class SEQUENCESHARED_EXPORT CSequenceWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CSequenceWidget(QWidget *parent, bool editMode = true); - ~CSequenceWidget(); - - void login(); - - void logout(); - - void setEditMode(bool editMode); - - void setTitleVisable(bool bEnable); - - QStringList currentSequenceName(); - - void release(); - -public slots: - void initialize(int seqMode = -1, QStringList listSequenceName = QStringList(), kbd_dbms::CDbApi *dbRead = NULL); - - void loadSequenceData(QStringList listSequenceName); - - void setGuard(bool guard = true); - -signals: - void sigSequenceStateChanged(const QString &seqName, const E_EXECUTING_STATE &state); - void sigSubScribeSequenceList(QList sequenceList); - void sigUnSubScribeSequence(); - -protected slots: - void updatePerm(); - void slotExecute(); - void slotPause(); - void slotStop(); - - void slotRecvSeqOperateResponse(const QString &seqName, const E_SEQ_OPERATE &type); - void slotRecvSeqOperateResponseErrorMsg(const QString &seqName, const E_SEQ_OPERATE &type, const QString &errorInfo); - void slotRecvSequenceStateError(const QString &seqName, const int &errorCode, const QString &errorDescription); - void slotRecvSequenceStateChanged(const QString &seqName, const E_EXECUTING_STATE &state); - void slotRecvFunctionStateChanged(const QString &seqName, const QString &funcName, const E_EXECUTING_STATE &state); - void slotRecvActionStateChanged(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state); - void slotRecvUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage *msg); - void slotUpdateActionActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state); - void slotUpdateSequenceTimeFlag(const QString &seqName, const int &time); - -private: - void seqExecute(); - kbd_idlfile::sequence::SeqOperateMessage buildSequenceRequest(const Sequence &sequence, const E_SEQ_OPERATE &type); - void handleUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage &msg); - QString operateDescription(const E_SEQ_OPERATE &type); - QString stateDescription(const E_EXECUTING_STATE &state); - void notify(const QString &strTips); - - bool getSeqCtrlPerm(); - void updateUiVisible(bool bEnable); - void updateUiEnable(bool bEnable); - void updateUiRun(); - void updateUiPause(); - void updateUiStop(); - void updateUiFinish(); - -private: - Ui::CSequenceWidget *ui; - E_MODE_TYPE m_seqMode; - QTimer * m_permTimer; - QAbstractTableModel * m_pTableModel; - - QStringList m_seqNameList; - QList m_listSequence; - CSequenceDataManage * m_seqDataManage; - CSequenceStateManage * m_seqStateManage; - CSequenceMsgHandle * m_seqMsgHandle; - - QMessageBox *m_userInterveneRequestDialog; - bool m_editMode; - bool m_isOwnerPerm; - int m_nUserId; - std::string m_strUsrName; - int m_nUserGrpId; - bool m_isGuard; -}; - -Q_DECLARE_METATYPE(kbd_idlfile::sequence::UiRequestMessage) -Q_DECLARE_METATYPE(QList) - -#endif // CSEQUENCEWIDGET_H +#ifndef CSEQUENCEWIDGET_H +#define CSEQUENCEWIDGET_H + +#include +#include "sequence_global.h" +#include "sequence_def.h" +#include "../../idl_files/SequenceMessage.pb.h" +#include "db_api_ex/CDbApi.h" + +//<顺控界面展示模式 +enum E_MODE_TYPE +{ + E_Mode_Invalid = -1, //<缺省无效模式 + E_Mode_Sequence, //<展示顺控 + E_Mode_Action //<展示动作 +}; + +namespace Ui { +class CSequenceWidget; +} + +struct Sequence; +class QThread; +class QMessageBox; +class QAbstractTableModel; +class CSequenceDataManage; +class CSequenceStateManage; +class CSequenceMsgHandle; + +class SEQUENCESHARED_EXPORT CSequenceWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CSequenceWidget(QWidget *parent, bool editMode = true); + ~CSequenceWidget(); + + void login(); + + void logout(); + + void setEditMode(bool editMode); + + void setTitleVisable(bool bEnable); + + QStringList currentSequenceName(); + + void release(); + +public slots: + void initialize(int seqMode = -1, QStringList listSequenceName = QStringList(), kbd_dbms::CDbApi *dbRead = NULL); + + void loadSequenceData(QStringList listSequenceName); + + void setGuard(bool guard = true); + +signals: + void sigSequenceStateChanged(const QString &seqName, const E_EXECUTING_STATE &state); + void sigSubScribeSequenceList(QList sequenceList); + void sigUnSubScribeSequence(); + +protected slots: + void updatePerm(); + void slotExecute(); + void slotPause(); + void slotStop(); + + void slotRecvSeqOperateResponse(const QString &seqName, const E_SEQ_OPERATE &type); + void slotRecvSeqOperateResponseErrorMsg(const QString &seqName, const E_SEQ_OPERATE &type, const QString &errorInfo); + void slotRecvSequenceStateError(const QString &seqName, const int &errorCode, const QString &errorDescription); + void slotRecvSequenceStateChanged(const QString &seqName, const E_EXECUTING_STATE &state); + void slotRecvFunctionStateChanged(const QString &seqName, const QString &funcName, const E_EXECUTING_STATE &state); + void slotRecvActionStateChanged(const QString &seqName, const QString &funcName, const QString &actionName, const E_EXECUTING_STATE &state); + void slotRecvUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage *msg); + void slotUpdateActionActualState(const QString &seqName, const QString &funcName, const QString &actionName, const QString &state); + void slotUpdateSequenceTimeFlag(const QString &seqName, const int &time); + +private: + void seqExecute(); + kbd_idlfile::sequence::SeqOperateMessage buildSequenceRequest(const Sequence &sequence, const E_SEQ_OPERATE &type); + void handleUserInterveneRequest(const kbd_idlfile::sequence::UiRequestMessage &msg); + QString operateDescription(const E_SEQ_OPERATE &type); + QString stateDescription(const E_EXECUTING_STATE &state); + void notify(const QString &strTips); + + bool getSeqCtrlPerm(); + void updateUiVisible(bool bEnable); + void updateUiEnable(bool bEnable); + void updateUiRun(); + void updateUiPause(); + void updateUiStop(); + void updateUiFinish(); + +private: + Ui::CSequenceWidget *ui; + E_MODE_TYPE m_seqMode; + QTimer * m_permTimer; + QAbstractTableModel * m_pTableModel; + + QStringList m_seqNameList; + QList m_listSequence; + CSequenceDataManage * m_seqDataManage; + CSequenceStateManage * m_seqStateManage; + CSequenceMsgHandle * m_seqMsgHandle; + + QMessageBox *m_userInterveneRequestDialog; + bool m_editMode; + bool m_isOwnerPerm; + int m_nUserId; + std::string m_strUsrName; + int m_nUserGrpId; + bool m_isGuard; +}; + +Q_DECLARE_METATYPE(kbd_idlfile::sequence::UiRequestMessage) +Q_DECLARE_METATYPE(QList) + +#endif // CSEQUENCEWIDGET_H diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceWidget.ui b/product/src/gui/plugin/SequenceWidget/CSequenceWidget.ui index 704cde89..4ada4887 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceWidget.ui +++ b/product/src/gui/plugin/SequenceWidget/CSequenceWidget.ui @@ -1,200 +1,200 @@ - - - CSequenceWidget - - - - 0 - 0 - 738 - 529 - - - - 顺控 - - - - 6 - - - 6 - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - - 顺控名称: - - - - - - - - 200 - 0 - - - - - - - - - - - - - - - Qt::Horizontal - - - - 264 - 20 - - - - - - - - - - 执行方式: - - - - - - - 自动 - - - true - - - - - - - 单步 - - - false - - - - - - - - - - - - - - - 300 - 0 - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - true - - - 执行 - - - - - - - false - - - 暂停 - - - - - - - false - - - 终止 - - - - - - - - - - - - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - true - - - - - - - - - + + + CSequenceWidget + + + + 0 + 0 + 738 + 529 + + + + 顺控 + + + + 6 + + + 6 + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + 顺控名称: + + + + + + + + 200 + 0 + + + + - - + + + + + + + + + Qt::Horizontal + + + + 264 + 20 + + + + + + + + + + 执行方式: + + + + + + + 自动 + + + true + + + + + + + 单步 + + + false + + + + + + + + + + + + + + + 300 + 0 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + true + + + 执行 + + + + + + + false + + + 暂停 + + + + + + + false + + + 终止 + + + + + + + + + + + + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + true + + + + + + + + + diff --git a/product/src/gui/plugin/SequenceWidget/SequenceWidget.pro b/product/src/gui/plugin/SequenceWidget/SequenceWidget.pro index b0025628..c3b90e2a 100644 --- a/product/src/gui/plugin/SequenceWidget/SequenceWidget.pro +++ b/product/src/gui/plugin/SequenceWidget/SequenceWidget.pro @@ -1,59 +1,59 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-06-04T14:56:27 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib -TARGET = SequenceWidget - -CONFIG += plugin - -DEFINES += SEQUENCE_LIBRARY -DEFINES += SEQUENCE_SERVER_API_EXPORT - -SOURCES += \ - CSequenceWidget.cpp \ - CLocationSequModel.cpp \ - CActionSequModel.cpp \ - CSequenceMsgHandle.cpp \ - CSequenceDataManage.cpp \ - CSequencePluginWidget.cpp \ - CSequenceStateManage.cpp \ - CSeqForHmiApi.cpp \ - CSeqForHmiApiImpl.cpp \ - CSeqPermDialog.cpp - -HEADERS += \ - CSequenceWidget.h \ - CLocationSequModel.h \ - CActionSequModel.h \ - CSequenceMsgHandle.h \ - CSequenceDataManage.h \ - sequence_def.h \ - sequence_global.h \ - CSequencePluginWidget.h \ - CSequenceStateManage.h \ - CSeqForHmiApiImpl.h \ - ../../../include/application/sequence_server_api/CSeqForHmiApi.h \ - ../../../include/application/sequence_server_api/CSeqApiExport.h \ - CSeqPermDialog.h - -FORMS += \ - CSequenceWidget.ui \ - CSeqPermDialog.ui - -LIBS += -llog4cplus -lboost_system -lboost_thread -lboost_date_time -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lrdb_net_api -lperm_mng_api -lpub_sysinfo_api -lnet_msg_bus_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2018-06-04T14:56:27 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = SequenceWidget + +CONFIG += plugin + +DEFINES += SEQUENCE_LIBRARY +DEFINES += SEQUENCE_SERVER_API_EXPORT + +SOURCES += \ + CSequenceWidget.cpp \ + CLocationSequModel.cpp \ + CActionSequModel.cpp \ + CSequenceMsgHandle.cpp \ + CSequenceDataManage.cpp \ + CSequencePluginWidget.cpp \ + CSequenceStateManage.cpp \ + CSeqForHmiApi.cpp \ + CSeqForHmiApiImpl.cpp \ + CSeqPermDialog.cpp + +HEADERS += \ + CSequenceWidget.h \ + CLocationSequModel.h \ + CActionSequModel.h \ + CSequenceMsgHandle.h \ + CSequenceDataManage.h \ + sequence_def.h \ + sequence_global.h \ + CSequencePluginWidget.h \ + CSequenceStateManage.h \ + CSeqForHmiApiImpl.h \ + ../../../include/application/sequence_server_api/CSeqForHmiApi.h \ + ../../../include/application/sequence_server_api/CSeqApiExport.h \ + CSeqPermDialog.h + +FORMS += \ + CSequenceWidget.ui \ + CSeqPermDialog.ui + +LIBS += -llog4cplus -lboost_system -lboost_thread -lboost_date_time -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lrdb_net_api -lperm_mng_api -lpub_sysinfo_api -lnet_msg_bus_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/SequenceWidget/main.cpp b/product/src/gui/plugin/SequenceWidget/main.cpp index 87bf01ee..7b799427 100644 --- a/product/src/gui/plugin/SequenceWidget/main.cpp +++ b/product/src/gui/plugin/SequenceWidget/main.cpp @@ -1,27 +1,27 @@ -#include "CSequenceWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - - kbd_public::StartLogSystem(QString("log_hmi.properties").toUtf8().data(), - "hmi", "sequence"); - - kbd_net::initMsgBus("Sequence", "1", true); - LOGINFO("kbd_net::initMsgBus"); - { - CSequenceWidget w(0, false); - w.initialize(E_Mode_Action, QStringList() << "dfzsd"); - LOGINFO("CSequenceWidget::initialize"); - w.show(); - a.exec(); - } - - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "CSequenceWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + kbd_public::StartLogSystem(QString("log_hmi.properties").toUtf8().data(), + "hmi", "sequence"); + + kbd_net::initMsgBus("Sequence", "1", true); + LOGINFO("kbd_net::initMsgBus"); + { + CSequenceWidget w(0, false); + w.initialize(E_Mode_Action, QStringList() << "dfzsd"); + LOGINFO("CSequenceWidget::initialize"); + w.show(); + a.exec(); + } + + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/SequenceWidget/sequence_def.h b/product/src/gui/plugin/SequenceWidget/sequence_def.h index 662fe118..78a4ccbf 100644 --- a/product/src/gui/plugin/SequenceWidget/sequence_def.h +++ b/product/src/gui/plugin/SequenceWidget/sequence_def.h @@ -1,117 +1,117 @@ -#ifndef SEQUENCE_DEF_H -#define SEQUENCE_DEF_H - -#include - -#define INT_INVALID (-1) - -//<勾选状态 -enum E_CHECK_STATE -{ - E_Check_Unchecked, //<不勾选 - E_Check_Partially, //<部分勾选 - E_Check_Checked //<勾选 -}; - -//节点类型 -enum E_NODE_TYPE -{ - E_Node_Invalid = -1, //<无效 - E_Node_Sequence, //<顺控 - E_Node_Function, //<功能 - E_Node_Action //<动作 -}; - -//<错误码 -enum E_CODE_ERROR -{ - E_Code_Invalid = -1, //<无效位 - E_Code_Success, //<正常 - E_Code_Unknow, //<未知错误 - E_Code_Timeflag, //<时标不一致 - E_Code_Nofound, //<没有找到该顺控 - E_Code_Timeout, //<动作执行超时 - E_Code_Recover, //<主备切换\顺控恢复 导致的顺控失败 - E_Code_Faile, //<动作执行失败 - E_Code_UITimeout, //<动作执行人工干预超时 - E_Code_SendFaile //<发送动作操作失败 -}; - -//<操作动作类型 -enum E_ACTION_TYPE -{ - E_Action_Retry = 1, //<重试 - E_Action_Stop, //<终止 - E_Action_Skip //<跳过 -}; - -//顺控操作类型 -enum E_SEQ_OPERATE -{ - E_Seq_Start, //<顺控开始 - E_Seq_Stop, //<顺控终止 - E_Seq_Pause, //<顺控暂停 - E_Seq_Continue, //<顺控继续 - E_Ses_Start, //<单步开始 - E_Ses_Continue //<单步继续 -}; - -//<执行状态 -enum E_EXECUTING_STATE -{ - E_Exec_Reset, //<未执行 - E_Exec_Run, //<正在执行 - E_Exec_Triggered, //<已触发 - E_Exec_Failed, //<执行失败 - E_Exec_Success, //<执行成功 - E_Exec_Stop, //<执行终止 - E_Exec_Pause, //<执行暂停 - E_Exec_Skip //<执行跳过 -}; - -//<顺控结构定义 -struct Sequence -{ - Sequence(): locationID(0), subSystemID(0) - { - seqName = QString(); - funcName = QString(); - funcNo = INT_INVALID; - actionName = QString(); - actionNo = INT_INVALID; - location = QString(); - tagName = QString(); - nodeType = E_Node_Invalid; - checkState = E_Check_Checked; - timeFlag = 0; - delay = INT_INVALID; - seqType = INT_INVALID; - targetState = QString(); - executeState = E_Exec_Reset; - actualState = QString(); - } - - QString seqName; //<顺控名称 - QString seqDescription; //<顺控描述 - QString funcName; //<功能名称 - QString funcDescription; //<功能描述 - int funcNo; //功能序号 - QString actionName; //<动作名称 - QString actionDescription; //<动作描述 - int actionNo; //动作序号 - int locationID; //<车站ID - QString location; //<车站名 - int subSystemID; //<所属子系统ID - QString tagInfo; //<测点信息 - QString tagName; //<测点描述 - E_NODE_TYPE nodeType; //<类型 - E_CHECK_STATE checkState; //<勾选 - quint64 timeFlag; //<时标 - int delay; //<延时 - int seqType; //<顺控类型 - QString targetState; //<目标状态 - E_EXECUTING_STATE executeState; //<执行状态 - QString actualState; //<实际状态 -}; - -#endif // SEQUENCE_DEF_H +#ifndef SEQUENCE_DEF_H +#define SEQUENCE_DEF_H + +#include + +#define INT_INVALID (-1) + +//<勾选状态 +enum E_CHECK_STATE +{ + E_Check_Unchecked, //<不勾选 + E_Check_Partially, //<部分勾选 + E_Check_Checked //<勾选 +}; + +//节点类型 +enum E_NODE_TYPE +{ + E_Node_Invalid = -1, //<无效 + E_Node_Sequence, //<顺控 + E_Node_Function, //<功能 + E_Node_Action //<动作 +}; + +//<错误码 +enum E_CODE_ERROR +{ + E_Code_Invalid = -1, //<无效位 + E_Code_Success, //<正常 + E_Code_Unknow, //<未知错误 + E_Code_Timeflag, //<时标不一致 + E_Code_Nofound, //<没有找到该顺控 + E_Code_Timeout, //<动作执行超时 + E_Code_Recover, //<主备切换\顺控恢复 导致的顺控失败 + E_Code_Faile, //<动作执行失败 + E_Code_UITimeout, //<动作执行人工干预超时 + E_Code_SendFaile //<发送动作操作失败 +}; + +//<操作动作类型 +enum E_ACTION_TYPE +{ + E_Action_Retry = 1, //<重试 + E_Action_Stop, //<终止 + E_Action_Skip //<跳过 +}; + +//顺控操作类型 +enum E_SEQ_OPERATE +{ + E_Seq_Start, //<顺控开始 + E_Seq_Stop, //<顺控终止 + E_Seq_Pause, //<顺控暂停 + E_Seq_Continue, //<顺控继续 + E_Ses_Start, //<单步开始 + E_Ses_Continue //<单步继续 +}; + +//<执行状态 +enum E_EXECUTING_STATE +{ + E_Exec_Reset, //<未执行 + E_Exec_Run, //<正在执行 + E_Exec_Triggered, //<已触发 + E_Exec_Failed, //<执行失败 + E_Exec_Success, //<执行成功 + E_Exec_Stop, //<执行终止 + E_Exec_Pause, //<执行暂停 + E_Exec_Skip //<执行跳过 +}; + +//<顺控结构定义 +struct Sequence +{ + Sequence(): locationID(0), subSystemID(0) + { + seqName = QString(); + funcName = QString(); + funcNo = INT_INVALID; + actionName = QString(); + actionNo = INT_INVALID; + location = QString(); + tagName = QString(); + nodeType = E_Node_Invalid; + checkState = E_Check_Checked; + timeFlag = 0; + delay = INT_INVALID; + seqType = INT_INVALID; + targetState = QString(); + executeState = E_Exec_Reset; + actualState = QString(); + } + + QString seqName; //<顺控名称 + QString seqDescription; //<顺控描述 + QString funcName; //<功能名称 + QString funcDescription; //<功能描述 + int funcNo; //功能序号 + QString actionName; //<动作名称 + QString actionDescription; //<动作描述 + int actionNo; //动作序号 + int locationID; //<车站ID + QString location; //<车站名 + int subSystemID; //<所属子系统ID + QString tagInfo; //<测点信息 + QString tagName; //<测点描述 + E_NODE_TYPE nodeType; //<类型 + E_CHECK_STATE checkState; //<勾选 + quint64 timeFlag; //<时标 + int delay; //<延时 + int seqType; //<顺控类型 + QString targetState; //<目标状态 + E_EXECUTING_STATE executeState; //<执行状态 + QString actualState; //<实际状态 +}; + +#endif // SEQUENCE_DEF_H diff --git a/product/src/gui/plugin/SequenceWidget/sequence_global.h b/product/src/gui/plugin/SequenceWidget/sequence_global.h index 5d8d64a0..0f5c2e65 100644 --- a/product/src/gui/plugin/SequenceWidget/sequence_global.h +++ b/product/src/gui/plugin/SequenceWidget/sequence_global.h @@ -1,10 +1,10 @@ -#ifndef SEQUENCE_GLOBAL_H -#define SEQUENCE_GLOBAL_H - -#if defined(SEQUENCE_LIBRARY) -# define SEQUENCESHARED_EXPORT Q_DECL_EXPORT -#else -# define SEQUENCESHARED_EXPORT Q_DECL_IMPORT -#endif - -#endif // SEQUENCE_GLOBAL_H +#ifndef SEQUENCE_GLOBAL_H +#define SEQUENCE_GLOBAL_H + +#if defined(SEQUENCE_LIBRARY) +# define SEQUENCESHARED_EXPORT Q_DECL_EXPORT +#else +# define SEQUENCESHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // SEQUENCE_GLOBAL_H diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CDataManage.cpp b/product/src/gui/plugin/SerialDevStatusWidget/CDataManage.cpp index 31a20265..e3b580ed 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CDataManage.cpp +++ b/product/src/gui/plugin/SerialDevStatusWidget/CDataManage.cpp @@ -1,282 +1,282 @@ -#include "CDataManage.h" -#include "pub_logger_api/logger.h" - -CDataManage *CDataManage::m_pInstance = NULL; - -CDataManage *CDataManage::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CDataManage(); - } - return m_pInstance; -} - -void CDataManage::destory() -{ - m_locMap.clear(); - m_chanMap.clear(); - m_rtuMap.clear(); - m_rtuChanMap.clear(); - m_fesDevMap.clear(); - m_fesDevGroupMap.clear(); - m_rtuSerialMap.clear(); - m_serialDevMap.clear(); - m_rtuDevMap.clear(); - - m_pInstance = NULL; - delete this; -} - -const QStringList &CDataManage::getRtuOrderList() const -{ - return m_rtuOrderList; -} - -const QMap &CDataManage::getRtuMap() const -{ - return m_rtuMap; -} - -const QMap > &CDataManage::getRtuSerialMap() const -{ - return m_rtuSerialMap; -} - -const QMap > &CDataManage::getSerialDevMap() const -{ - return m_serialDevMap; -} - -const QMap > &CDataManage::getRtuDevMap() const -{ - return m_rtuDevMap; -} - -QString CDataManage::getRtuName(const QString &rtuTag) -{ - QMap::const_iterator iter = m_rtuMap.find(rtuTag); - if(iter != m_rtuMap.cend()) - { - return iter.value(); - } - return QString(); -} - -QList CDataManage::getSerialByRtu(const QString &rtuTag) -{ - QMap>::const_iterator iter = m_rtuSerialMap.find(rtuTag); - if(iter != m_rtuSerialMap.cend()) - { - return iter.value(); - } - return QList(); -} - -QList CDataManage::getDevInfoByRtu(const QString &rtuTag) -{ - QMap>::const_iterator iter = m_rtuDevMap.find(rtuTag); - if(iter != m_rtuDevMap.cend()) - { - return iter.value(); - } - return QList(); -} - -QList CDataManage::getDevInfoBySerial(const QString &serial) -{ - QMap>::const_iterator iter = m_serialDevMap.find(serial); - if(iter != m_serialDevMap.cend()) - { - return iter.value(); - } - return QList(); -} - -CDataManage::CDataManage() -{ - kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); - if(!objReadDb.open()) - { - return; - } - - loadLocation(&objReadDb); - loadChan(&objReadDb); - loadRtu(&objReadDb); - loadFesDevInfo(&objReadDb); - loadFesDigitalTx(&objReadDb); -} - -void CDataManage::loadLocation(kbd_dbms::CDbApi *pReadDb) -{ - QSqlQuery objQuery; - QList listColName; - listColName << "LOCATION_ID"; - listColName << "DESCRIPTION"; - if(!pReadDb->select("sys_model_location_info", listColName, objQuery)) - { - LOGERROR("查询位置信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); - return; - } - while(objQuery.next()) - { - m_locMap[objQuery.value(0).toInt()] = objQuery.value(1).toString(); - } -} - -void CDataManage::loadChan(kbd_dbms::CDbApi *pReadDb) -{ - QSqlQuery objQuery; - QList listColName; - listColName << "TAG_NAME"; - listColName << "DESCRIPTION"; - if(!pReadDb->select("fes_channel_para", listColName, objQuery)) - { - LOGERROR("查询通道信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); - return; - } - while(objQuery.next()) - { - m_chanMap[objQuery.value(0).toString()] = objQuery.value(1).toString(); - } -} - -void CDataManage::loadRtu(kbd_dbms::CDbApi *pReadDb) -{ - QSqlQuery objQuery; - QList listColName; - listColName << "TAG_NAME"; - listColName << "DESCRIPTION"; - listColName << "CHAN_TAG"; - QList listOrderBy; - listOrderBy << kbd_dbms::CDbOrder("RTU_NO", kbd_dbms::CDbOrder::ORDER_ASC); - - if(!pReadDb->select("fes_rtu_para", listColName, listOrderBy, objQuery)) - { - LOGERROR("查询RTU信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); - return; - } - while(objQuery.next()) - { - QMap::iterator iter = m_chanMap.find(objQuery.value(2).toString()); - if(iter == m_chanMap.end()) - { - LOGINFO("%s 不属于任何通道", objQuery.value(0).toString().toStdString().c_str()); - continue; - } - - m_rtuOrderList.append(objQuery.value(0).toString()); - m_rtuMap[objQuery.value(0).toString()] = objQuery.value(1).toString(); - m_rtuChanMap[objQuery.value(0).toString()] = iter.value(); - } -} - -void CDataManage::loadFesDevInfo(kbd_dbms::CDbApi *pReadDb) -{ - QSqlQuery objQuery; - QList listColName; - listColName << "TAG_NAME"; - listColName << "DEV_DESC"; - listColName << "DEV_PORT"; - listColName << "DEV_ID"; - if(!pReadDb->select("fes_dev_info", listColName, objQuery)) - { - LOGERROR("查询前置设备信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); - return; - } - while(objQuery.next()) - { - QString tagName = objQuery.value(0).toString(); - QString devName = objQuery.value(1).toString(); - QString devGroup = objQuery.value(2).toString(); - int devId = objQuery.value(3).toInt(); - m_fesDevMap[tagName] = qMakePair(devId, devName); - if(!devGroup.isEmpty()) - { - m_fesDevGroupMap[tagName] = devGroup; - } - } -} - -void CDataManage::loadFesDigitalTx(kbd_dbms::CDbApi *pReadDb) -{ - QSqlQuery objQuery; - - QString sql = "select TAG_NAME,LOCATION_ID,DEV_TAG,RTU_TAG,APP_TAG_NAME from fes_digital where APP_TAG_NAME like '%.TX'"; - - if(!pReadDb->execute(sql, objQuery)) - { - LOGERROR("查询通讯状态点信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); - return; - } - while(objQuery.next()) - { - QString tagName = objQuery.value(0).toString(); - int locationID = objQuery.value(1).toInt(); - QString devTag = objQuery.value(2).toString(); - QString rtuTag = objQuery.value(3).toString(); - QString appTag = objQuery.value(4).toString(); - - if(appTag.isEmpty()) - { - LOGINFO("%s 未关联后台测点", tagName.toStdString().c_str()); - continue; - } - - QMap::iterator locIter = m_locMap.find(locationID); - if(locIter == m_locMap.end()) - { - LOGINFO("%s 不属于任何位置", tagName.toStdString().c_str()); - continue; - } - - QMap::iterator rtuIter = m_rtuMap.find(rtuTag); - if(rtuIter == m_rtuMap.end()) - { - LOGINFO("%s 不属于任何RTU", tagName.toStdString().c_str()); - continue; - } - - QMap>::iterator devIter = m_fesDevMap.find(devTag); - if(devIter == m_fesDevMap.end()) - { - LOGINFO("%s 不属于任何前置设备", tagName.toStdString().c_str()); - continue; - } - - SerialStatus serialStatus; - serialStatus.strChan = m_rtuChanMap[rtuTag]; - serialStatus.strDesc = m_fesDevMap[devTag].second; - serialStatus.strLoc = m_locMap[locationID]; - serialStatus.strRtu = m_rtuMap[rtuTag]; - serialStatus.strTag = appTag; - serialStatus.nDevID = m_fesDevMap[devTag].first; - - QMap::iterator devgIter = m_fesDevGroupMap.find(devTag); - if(devgIter == m_fesDevGroupMap.end()) - { - //< 不属于任何前置设备组 - serialStatus.strSerial = ""; - - m_rtuDevMap[rtuTag].append(serialStatus); - } - else - { - serialStatus.strSerial = devgIter.value(); - - SerialSort serialSort; - serialSort.nDevID = serialStatus.nDevID; - serialSort.strSerial = serialStatus.strSerial; - - m_rtuSerialMap[rtuTag].append(serialSort); - m_serialDevMap[rtuTag+"."+serialStatus.strSerial].append(serialStatus); - } - } - //< 按设备ID排序 - QMap>::iterator sortIter = m_rtuSerialMap.begin(); - for(; sortIter != m_rtuSerialMap.end(); sortIter++) - { - qSort(sortIter.value()); - } -} +#include "CDataManage.h" +#include "pub_logger_api/logger.h" + +CDataManage *CDataManage::m_pInstance = NULL; + +CDataManage *CDataManage::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDataManage(); + } + return m_pInstance; +} + +void CDataManage::destory() +{ + m_locMap.clear(); + m_chanMap.clear(); + m_rtuMap.clear(); + m_rtuChanMap.clear(); + m_fesDevMap.clear(); + m_fesDevGroupMap.clear(); + m_rtuSerialMap.clear(); + m_serialDevMap.clear(); + m_rtuDevMap.clear(); + + m_pInstance = NULL; + delete this; +} + +const QStringList &CDataManage::getRtuOrderList() const +{ + return m_rtuOrderList; +} + +const QMap &CDataManage::getRtuMap() const +{ + return m_rtuMap; +} + +const QMap > &CDataManage::getRtuSerialMap() const +{ + return m_rtuSerialMap; +} + +const QMap > &CDataManage::getSerialDevMap() const +{ + return m_serialDevMap; +} + +const QMap > &CDataManage::getRtuDevMap() const +{ + return m_rtuDevMap; +} + +QString CDataManage::getRtuName(const QString &rtuTag) +{ + QMap::const_iterator iter = m_rtuMap.find(rtuTag); + if(iter != m_rtuMap.cend()) + { + return iter.value(); + } + return QString(); +} + +QList CDataManage::getSerialByRtu(const QString &rtuTag) +{ + QMap>::const_iterator iter = m_rtuSerialMap.find(rtuTag); + if(iter != m_rtuSerialMap.cend()) + { + return iter.value(); + } + return QList(); +} + +QList CDataManage::getDevInfoByRtu(const QString &rtuTag) +{ + QMap>::const_iterator iter = m_rtuDevMap.find(rtuTag); + if(iter != m_rtuDevMap.cend()) + { + return iter.value(); + } + return QList(); +} + +QList CDataManage::getDevInfoBySerial(const QString &serial) +{ + QMap>::const_iterator iter = m_serialDevMap.find(serial); + if(iter != m_serialDevMap.cend()) + { + return iter.value(); + } + return QList(); +} + +CDataManage::CDataManage() +{ + kbd_dbms::CDbApi objReadDb(DB_CONN_MODEL_READ); + if(!objReadDb.open()) + { + return; + } + + loadLocation(&objReadDb); + loadChan(&objReadDb); + loadRtu(&objReadDb); + loadFesDevInfo(&objReadDb); + loadFesDigitalTx(&objReadDb); +} + +void CDataManage::loadLocation(kbd_dbms::CDbApi *pReadDb) +{ + QSqlQuery objQuery; + QList listColName; + listColName << "LOCATION_ID"; + listColName << "DESCRIPTION"; + if(!pReadDb->select("sys_model_location_info", listColName, objQuery)) + { + LOGERROR("查询位置信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); + return; + } + while(objQuery.next()) + { + m_locMap[objQuery.value(0).toInt()] = objQuery.value(1).toString(); + } +} + +void CDataManage::loadChan(kbd_dbms::CDbApi *pReadDb) +{ + QSqlQuery objQuery; + QList listColName; + listColName << "TAG_NAME"; + listColName << "DESCRIPTION"; + if(!pReadDb->select("fes_channel_para", listColName, objQuery)) + { + LOGERROR("查询通道信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); + return; + } + while(objQuery.next()) + { + m_chanMap[objQuery.value(0).toString()] = objQuery.value(1).toString(); + } +} + +void CDataManage::loadRtu(kbd_dbms::CDbApi *pReadDb) +{ + QSqlQuery objQuery; + QList listColName; + listColName << "TAG_NAME"; + listColName << "DESCRIPTION"; + listColName << "CHAN_TAG"; + QList listOrderBy; + listOrderBy << kbd_dbms::CDbOrder("RTU_NO", kbd_dbms::CDbOrder::ORDER_ASC); + + if(!pReadDb->select("fes_rtu_para", listColName, listOrderBy, objQuery)) + { + LOGERROR("查询RTU信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); + return; + } + while(objQuery.next()) + { + QMap::iterator iter = m_chanMap.find(objQuery.value(2).toString()); + if(iter == m_chanMap.end()) + { + LOGINFO("%s 不属于任何通道", objQuery.value(0).toString().toStdString().c_str()); + continue; + } + + m_rtuOrderList.append(objQuery.value(0).toString()); + m_rtuMap[objQuery.value(0).toString()] = objQuery.value(1).toString(); + m_rtuChanMap[objQuery.value(0).toString()] = iter.value(); + } +} + +void CDataManage::loadFesDevInfo(kbd_dbms::CDbApi *pReadDb) +{ + QSqlQuery objQuery; + QList listColName; + listColName << "TAG_NAME"; + listColName << "DEV_DESC"; + listColName << "DEV_PORT"; + listColName << "DEV_ID"; + if(!pReadDb->select("fes_dev_info", listColName, objQuery)) + { + LOGERROR("查询前置设备信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); + return; + } + while(objQuery.next()) + { + QString tagName = objQuery.value(0).toString(); + QString devName = objQuery.value(1).toString(); + QString devGroup = objQuery.value(2).toString(); + int devId = objQuery.value(3).toInt(); + m_fesDevMap[tagName] = qMakePair(devId, devName); + if(!devGroup.isEmpty()) + { + m_fesDevGroupMap[tagName] = devGroup; + } + } +} + +void CDataManage::loadFesDigitalTx(kbd_dbms::CDbApi *pReadDb) +{ + QSqlQuery objQuery; + + QString sql = "select TAG_NAME,LOCATION_ID,DEV_TAG,RTU_TAG,APP_TAG_NAME from fes_digital where APP_TAG_NAME like '%.TX'"; + + if(!pReadDb->execute(sql, objQuery)) + { + LOGERROR("查询通讯状态点信息失败 %s", pReadDb->getLastErrorString().toStdString().c_str()); + return; + } + while(objQuery.next()) + { + QString tagName = objQuery.value(0).toString(); + int locationID = objQuery.value(1).toInt(); + QString devTag = objQuery.value(2).toString(); + QString rtuTag = objQuery.value(3).toString(); + QString appTag = objQuery.value(4).toString(); + + if(appTag.isEmpty()) + { + LOGINFO("%s 未关联后台测点", tagName.toStdString().c_str()); + continue; + } + + QMap::iterator locIter = m_locMap.find(locationID); + if(locIter == m_locMap.end()) + { + LOGINFO("%s 不属于任何位置", tagName.toStdString().c_str()); + continue; + } + + QMap::iterator rtuIter = m_rtuMap.find(rtuTag); + if(rtuIter == m_rtuMap.end()) + { + LOGINFO("%s 不属于任何RTU", tagName.toStdString().c_str()); + continue; + } + + QMap>::iterator devIter = m_fesDevMap.find(devTag); + if(devIter == m_fesDevMap.end()) + { + LOGINFO("%s 不属于任何前置设备", tagName.toStdString().c_str()); + continue; + } + + SerialStatus serialStatus; + serialStatus.strChan = m_rtuChanMap[rtuTag]; + serialStatus.strDesc = m_fesDevMap[devTag].second; + serialStatus.strLoc = m_locMap[locationID]; + serialStatus.strRtu = m_rtuMap[rtuTag]; + serialStatus.strTag = appTag; + serialStatus.nDevID = m_fesDevMap[devTag].first; + + QMap::iterator devgIter = m_fesDevGroupMap.find(devTag); + if(devgIter == m_fesDevGroupMap.end()) + { + //< 不属于任何前置设备组 + serialStatus.strSerial = ""; + + m_rtuDevMap[rtuTag].append(serialStatus); + } + else + { + serialStatus.strSerial = devgIter.value(); + + SerialSort serialSort; + serialSort.nDevID = serialStatus.nDevID; + serialSort.strSerial = serialStatus.strSerial; + + m_rtuSerialMap[rtuTag].append(serialSort); + m_serialDevMap[rtuTag+"."+serialStatus.strSerial].append(serialStatus); + } + } + //< 按设备ID排序 + QMap>::iterator sortIter = m_rtuSerialMap.begin(); + for(; sortIter != m_rtuSerialMap.end(); sortIter++) + { + qSort(sortIter.value()); + } +} diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CDataManage.h b/product/src/gui/plugin/SerialDevStatusWidget/CDataManage.h index d3363c3d..3acbd2e0 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CDataManage.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CDataManage.h @@ -1,49 +1,49 @@ -#ifndef CDATAMANAGE_H -#define CDATAMANAGE_H - -#include -#include "db_api_ex/CDbApi.h" -#include "CSeriaCommon.h" - -class CDataManage -{ -public: - static CDataManage * instance(); - - void destory(); - - const QStringList &getRtuOrderList() const; - const QMap &getRtuMap() const; - const QMap>& getRtuSerialMap() const; - const QMap>& getSerialDevMap() const; - const QMap>& getRtuDevMap() const; - QString getRtuName(const QString& rtuTag); - QList getSerialByRtu(const QString &rtuTag); - QList getDevInfoByRtu(const QString &rtuTag); - QList getDevInfoBySerial(const QString &serial); - -private: - CDataManage(); - - void loadLocation(kbd_dbms::CDbApi *pReadDb); - void loadChan(kbd_dbms::CDbApi *pReadDb); - void loadRtu(kbd_dbms::CDbApi *pReadDb); - void loadFesDevInfo(kbd_dbms::CDbApi *pReadDb); - void loadFesDigitalTx(kbd_dbms::CDbApi *pReadDb); - -private: - static CDataManage * m_pInstance; - - QMap m_locMap; //< 车站ID-车站描述 - QMap m_chanMap; //< 通道标签-通道名称 - QMap m_rtuMap; //< RTU标签-RTU名称 - QMap m_rtuChanMap; //< RTU标签-通道名称 - QMap> m_fesDevMap; //< 前置设备标签-<前置设备ID-前置设备名称> - QMap m_fesDevGroupMap; //< 前置设备标签-DEV_PORT - QMap> m_rtuSerialMap; //< RTU标签-DEV_PORT - QMap> m_serialDevMap; //< RTU.DEV_PORT-设备 - QMap> m_rtuDevMap; //< RTU-设备 (DEV_PORT为空的设备) - QStringList m_rtuOrderList; //< RTU排序 -}; - -#endif // CDATAMANAGE_H +#ifndef CDATAMANAGE_H +#define CDATAMANAGE_H + +#include +#include "db_api_ex/CDbApi.h" +#include "CSeriaCommon.h" + +class CDataManage +{ +public: + static CDataManage * instance(); + + void destory(); + + const QStringList &getRtuOrderList() const; + const QMap &getRtuMap() const; + const QMap>& getRtuSerialMap() const; + const QMap>& getSerialDevMap() const; + const QMap>& getRtuDevMap() const; + QString getRtuName(const QString& rtuTag); + QList getSerialByRtu(const QString &rtuTag); + QList getDevInfoByRtu(const QString &rtuTag); + QList getDevInfoBySerial(const QString &serial); + +private: + CDataManage(); + + void loadLocation(kbd_dbms::CDbApi *pReadDb); + void loadChan(kbd_dbms::CDbApi *pReadDb); + void loadRtu(kbd_dbms::CDbApi *pReadDb); + void loadFesDevInfo(kbd_dbms::CDbApi *pReadDb); + void loadFesDigitalTx(kbd_dbms::CDbApi *pReadDb); + +private: + static CDataManage * m_pInstance; + + QMap m_locMap; //< 车站ID-车站描述 + QMap m_chanMap; //< 通道标签-通道名称 + QMap m_rtuMap; //< RTU标签-RTU名称 + QMap m_rtuChanMap; //< RTU标签-通道名称 + QMap> m_fesDevMap; //< 前置设备标签-<前置设备ID-前置设备名称> + QMap m_fesDevGroupMap; //< 前置设备标签-DEV_PORT + QMap> m_rtuSerialMap; //< RTU标签-DEV_PORT + QMap> m_serialDevMap; //< RTU.DEV_PORT-设备 + QMap> m_rtuDevMap; //< RTU-设备 (DEV_PORT为空的设备) + QStringList m_rtuOrderList; //< RTU排序 +}; + +#endif // CDATAMANAGE_H diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CRealDataCollect.cpp b/product/src/gui/plugin/SerialDevStatusWidget/CRealDataCollect.cpp index 4f138918..1ddfabee 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CRealDataCollect.cpp +++ b/product/src/gui/plugin/SerialDevStatusWidget/CRealDataCollect.cpp @@ -1,299 +1,299 @@ -#include "CRealDataCollect.h" -#include -#include - -CRealDataCollect* CRealDataCollect::m_pInstance = NULL; - -CRealDataCollect::CRealDataCollect() - : m_pMbComm(NULL), - m_pTimer(NULL), - m_nTimeCount(0) -{ - initMsg(); - if(!addSub()) - { - return; - } - - m_pTimer = new QTimer(this); - connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); - m_pTimer->start(100); -} - -CRealDataCollect *CRealDataCollect::instance() -{ - if(m_pInstance == NULL) - { - m_pInstance = new CRealDataCollect(); - } - return m_pInstance; -} - -void CRealDataCollect::release() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = NULL; - - delSub(); - closeMsg(); - m_pInstance = NULL; - delete this; -} - -void CRealDataCollect::initMsg() -{ - if(m_pMbComm == NULL) - { - m_pMbComm = new kbd_net::CMbCommunicator("SerialDevStatusWidget"); - } -} - -void CRealDataCollect::closeMsg() -{ - if(m_pMbComm != NULL) - { - delete m_pMbComm; - } - m_pMbComm = NULL; -} - -void CRealDataCollect::clearMsg() -{ - if(m_pMbComm) - { - kbd_net::CMbMessage objMsg; - while(m_pMbComm->recvMsg(objMsg, 0)) - {} - } -} - -bool CRealDataCollect::addSub() -{ - if(m_pMbComm) - { - return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else - { - return false; - } -} - -bool CRealDataCollect::delSub() -{ - if(m_pMbComm) - { - return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - } - else - { - return false; - } -} - -void CRealDataCollect::recvMessage() -{ - m_nTimeCount = (m_nTimeCount + 1) % 36000; - - if(m_nTimeCount % 10 == 0) - { - processChangeData(); - } - - try - { - kbd_net::CMbMessage objMsg; - for(int i = 0; i < 6; i++) - { - if(m_pMbComm->recvMsg(objMsg, 0)) - { - if(objMsg.isValid()) - { - if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) - { - continue; - } - if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) - { - continue; - } - parserMsg(objMsg); - } - } - } - } - catch(...) - { - - } -} - -void CRealDataCollect::processChangeData() -{ - if(!m_aiMap.isEmpty()) - { - emit signal_updateAi(m_aiMap); - m_aiMap.clear(); - } - - if(!m_diMap.isEmpty()) - { - emit signal_updateDi(m_diMap); - m_diMap.clear(); - } - - if(!m_piMap.isEmpty()) - { - emit signal_updatePi(m_piMap); - m_piMap.clear(); - } - - if(!m_miMap.isEmpty()) - { - emit signal_updateMi(m_miMap); - m_miMap.clear(); - } - - if(!m_uiMap.isEmpty()) - { - emit signal_updateUi(m_uiMap); - m_uiMap.clear(); - } -} - -int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) -{ - kbd_idlfile::SRealTimeDataPkg changeDataPackage; - try - { - changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); - int aiSize = changeDataPackage.stairtd_size(); - if(aiSize > 0) - { - kbd_idlfile::SAiRealTimeData aiStru; - QString tagName; - float value; - uint status; - for(int i = 0; i < aiSize;++i) - { - aiStru = changeDataPackage.stairtd(i); - tagName = QString::fromStdString(aiStru.strtagname()); - value = aiStru.fvalue(); - status = aiStru.ustatus(); - m_aiMap[tagName] = qMakePair(value, status); - } - } - - int diSize = changeDataPackage.stdirtd_size(); - if(diSize > 0) - { - kbd_idlfile::SDiRealTimeData diStu; - QString tagName; - int value; - uint status; - for(int i = 0; i < diSize; ++i) - { - diStu = changeDataPackage.stdirtd(i); - tagName = QString::fromStdString(diStu.strtagname()); - value = diStu.nvalue(); - status = diStu.ustatus(); - m_diMap[tagName] = qMakePair(value, status); - } - } - - int piSize = changeDataPackage.stpirtd_size(); - if(piSize > 0) - { - kbd_idlfile::SPiRealTimeData piStu; - QString tagName; - double value; - uint status; - for(int i = 0 ; i < piSize; ++i) - { - piStu = changeDataPackage.stpirtd(i); - tagName = QString::fromStdString(piStu.strtagname()); - value = piStu.dvalue(); - status = piStu.ustatus(); - m_piMap[tagName] = qMakePair(value, status); - } - } - - int miSize = changeDataPackage.stmirtd_size(); - if(miSize > 0) - { - kbd_idlfile::SMiRealTimeData miStu; - QString tagName; - int value; - uint status; - for(int i = 0 ; i < miSize ; ++i) - { - miStu = changeDataPackage.stmirtd(i); - tagName = QString::fromStdString(miStu.strtagname()); - value = miStu.nvalue(); - status = miStu.ustatus(); - m_miMap[tagName] = qMakePair(value, status); - } - } - - int utSize = changeDataPackage.sttblrtd_size(); - if(utSize > 0) - { - kbd_idlfile::STableRealTimeData uiStu; - QString tagName; - QVariant value; - for(int i = 0;i < utSize; i++) - { - uiStu = changeDataPackage.sttblrtd(i); - tagName = QString::fromStdString(uiStu.strtagname()); - kbd_idlfile::SVariable temp = uiStu.varvalue(); - if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_BOOL) - { - value = QVariant::fromValue(temp.bvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_UINT32) - { - value = QVariant::fromValue(temp.uvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_INT32) - { - value = QVariant::fromValue(temp.nvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_UINT64) - { - value = QVariant::fromValue(temp.ulvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_INT64) - { - value = QVariant::fromValue(temp.lvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_FLOAT) - { - value = QVariant::fromValue(temp.fvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_DOUBLE) - { - value = QVariant::fromValue(temp.dvalue()); - } - else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_STRING || - temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_BYTES) - { - QString str = QString::fromStdString(temp.strvalue()); - value = QVariant::fromValue(str); - } - else - {} - - m_uiMap[tagName] = value; - } - } - } - catch(...) - { - return 0; - } - return 1; -} +#include "CRealDataCollect.h" +#include +#include + +CRealDataCollect* CRealDataCollect::m_pInstance = NULL; + +CRealDataCollect::CRealDataCollect() + : m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0) +{ + initMsg(); + if(!addSub()) + { + return; + } + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CRealDataCollect *CRealDataCollect::instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CRealDataCollect(); + } + return m_pInstance; +} + +void CRealDataCollect::release() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(); + closeMsg(); + m_pInstance = NULL; + delete this; +} + +void CRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new kbd_net::CMbCommunicator("SerialDevStatusWidget"); + } +} + +void CRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +void CRealDataCollect::clearMsg() +{ + if(m_pMbComm) + { + kbd_net::CMbMessage objMsg; + while(m_pMbComm->recvMsg(objMsg, 0)) + {} + } +} + +bool CRealDataCollect::addSub() +{ + if(m_pMbComm) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +bool CRealDataCollect::delSub() +{ + if(m_pMbComm) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +void CRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { + processChangeData(); + } + + try + { + kbd_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getMsgType() != kbd_idlfile::MT_DP_CHANGE_DATA) + { + continue; + } + if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) + { + continue; + } + parserMsg(objMsg); + } + } + } + } + catch(...) + { + + } +} + +void CRealDataCollect::processChangeData() +{ + if(!m_aiMap.isEmpty()) + { + emit signal_updateAi(m_aiMap); + m_aiMap.clear(); + } + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + + if(!m_piMap.isEmpty()) + { + emit signal_updatePi(m_piMap); + m_piMap.clear(); + } + + if(!m_miMap.isEmpty()) + { + emit signal_updateMi(m_miMap); + m_miMap.clear(); + } + + if(!m_uiMap.isEmpty()) + { + emit signal_updateUi(m_uiMap); + m_uiMap.clear(); + } +} + +int CRealDataCollect::parserMsg(const kbd_net::CMbMessage &msg) +{ + kbd_idlfile::SRealTimeDataPkg changeDataPackage; + try + { + changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); + int aiSize = changeDataPackage.stairtd_size(); + if(aiSize > 0) + { + kbd_idlfile::SAiRealTimeData aiStru; + QString tagName; + float value; + uint status; + for(int i = 0; i < aiSize;++i) + { + aiStru = changeDataPackage.stairtd(i); + tagName = QString::fromStdString(aiStru.strtagname()); + value = aiStru.fvalue(); + status = aiStru.ustatus(); + m_aiMap[tagName] = qMakePair(value, status); + } + } + + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + kbd_idlfile::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); + m_diMap[tagName] = qMakePair(value, status); + } + } + + int piSize = changeDataPackage.stpirtd_size(); + if(piSize > 0) + { + kbd_idlfile::SPiRealTimeData piStu; + QString tagName; + double value; + uint status; + for(int i = 0 ; i < piSize; ++i) + { + piStu = changeDataPackage.stpirtd(i); + tagName = QString::fromStdString(piStu.strtagname()); + value = piStu.dvalue(); + status = piStu.ustatus(); + m_piMap[tagName] = qMakePair(value, status); + } + } + + int miSize = changeDataPackage.stmirtd_size(); + if(miSize > 0) + { + kbd_idlfile::SMiRealTimeData miStu; + QString tagName; + int value; + uint status; + for(int i = 0 ; i < miSize ; ++i) + { + miStu = changeDataPackage.stmirtd(i); + tagName = QString::fromStdString(miStu.strtagname()); + value = miStu.nvalue(); + status = miStu.ustatus(); + m_miMap[tagName] = qMakePair(value, status); + } + } + + int utSize = changeDataPackage.sttblrtd_size(); + if(utSize > 0) + { + kbd_idlfile::STableRealTimeData uiStu; + QString tagName; + QVariant value; + for(int i = 0;i < utSize; i++) + { + uiStu = changeDataPackage.sttblrtd(i); + tagName = QString::fromStdString(uiStu.strtagname()); + kbd_idlfile::SVariable temp = uiStu.varvalue(); + if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_BOOL) + { + value = QVariant::fromValue(temp.bvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_UINT32) + { + value = QVariant::fromValue(temp.uvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_INT32) + { + value = QVariant::fromValue(temp.nvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_UINT64) + { + value = QVariant::fromValue(temp.ulvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_INT64) + { + value = QVariant::fromValue(temp.lvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_FLOAT) + { + value = QVariant::fromValue(temp.fvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_DOUBLE) + { + value = QVariant::fromValue(temp.dvalue()); + } + else if(temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_STRING || + temp.edatatype() == kbd_idlfile::DataType::CN_DATATYPE_BYTES) + { + QString str = QString::fromStdString(temp.strvalue()); + value = QVariant::fromValue(str); + } + else + {} + + m_uiMap[tagName] = value; + } + } + } + catch(...) + { + return 0; + } + return 1; +} diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CRealDataCollect.h b/product/src/gui/plugin/SerialDevStatusWidget/CRealDataCollect.h index 0dec53e6..d8f1bea9 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CRealDataCollect.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CRealDataCollect.h @@ -1,55 +1,55 @@ -#ifndef CREALDATACOLLECT_H -#define CREALDATACOLLECT_H - -#include -#include -#include -#include "net_msg_bus_api/CMbCommunicator.h" -#include "MessageChannel.h" -#include "DataProcMessage.pb.h" - -class QTimer; -class CRealDataCollect : public QObject -{ - Q_OBJECT -public: - static CRealDataCollect * instance(); - - void release(); - -private: - CRealDataCollect(); - - void initMsg(); - void closeMsg(); - void clearMsg(); - bool addSub(); - bool delSub(); - - int parserMsg(const kbd_net::CMbMessage &); - -private slots: - void recvMessage(); - void processChangeData(); - -signals: - void signal_updateAi(QMap> aiMap); - void signal_updateDi(QMap> diMap); - void signal_updatePi(QMap> piMap); - void signal_updateMi(QMap> miMap); - void signal_updateUi(QMap uiMap); - -private: - kbd_net::CMbCommunicator *m_pMbComm; - QTimer * m_pTimer; - int m_nTimeCount; - QMap> m_aiMap; - QMap> m_diMap; - QMap> m_piMap; - QMap> m_miMap; - QMap m_uiMap; - - static CRealDataCollect * m_pInstance; -}; - -#endif // CREALDATACOLLECT_H +#ifndef CREALDATACOLLECT_H +#define CREALDATACOLLECT_H + +#include +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" + +class QTimer; +class CRealDataCollect : public QObject +{ + Q_OBJECT +public: + static CRealDataCollect * instance(); + + void release(); + +private: + CRealDataCollect(); + + void initMsg(); + void closeMsg(); + void clearMsg(); + bool addSub(); + bool delSub(); + + int parserMsg(const kbd_net::CMbMessage &); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateAi(QMap> aiMap); + void signal_updateDi(QMap> diMap); + void signal_updatePi(QMap> piMap); + void signal_updateMi(QMap> miMap); + void signal_updateUi(QMap uiMap); + +private: + kbd_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + QMap> m_aiMap; + QMap> m_diMap; + QMap> m_piMap; + QMap> m_miMap; + QMap m_uiMap; + + static CRealDataCollect * m_pInstance; +}; + +#endif // CREALDATACOLLECT_H diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaCommon.h b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaCommon.h index 60877023..3f701890 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaCommon.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaCommon.h @@ -1,66 +1,66 @@ -#ifndef CSERIACOMMON_H -#define CSERIACOMMON_H - -#include - -//通道状态 -const int CN_Communication_Interrupte = 0; //通讯中断 -const int CN_Communication_Normal = 1; //通讯正常 - -//树节点 -enum EN_Tree_Node -{ - Node_Rtu = 0, - Node_Serial = 1 -}; - -struct SerialStatus -{ - QString strTag; - QString strDesc; - QString strLoc; - QString strChan; - QString strRtu; - QString strSerial; - int nDevID; - int nStatus; - bool isInit; - - bool operator <(const SerialStatus &t1) const - { - return nDevID < t1.nDevID; - } - - SerialStatus(){ - strTag = ""; - strDesc = ""; - strLoc = ""; - strChan = ""; - strRtu = ""; - strSerial = ""; - nDevID = 0; - nStatus = CN_Communication_Interrupte; - isInit = false; - } -}; - -struct SerialSort -{ - int nDevID; - QString strSerial; - - bool operator <(const SerialSort &t1) const - { - return nDevID < t1.nDevID; - } - bool operator ==(const SerialSort &t1) const - { - return strSerial == t1.strSerial; - } - SerialSort(){ - nDevID = 0; - strSerial = ""; - } -}; - -#endif // CSERIACOMMON_H +#ifndef CSERIACOMMON_H +#define CSERIACOMMON_H + +#include + +//通道状态 +const int CN_Communication_Interrupte = 0; //通讯中断 +const int CN_Communication_Normal = 1; //通讯正常 + +//树节点 +enum EN_Tree_Node +{ + Node_Rtu = 0, + Node_Serial = 1 +}; + +struct SerialStatus +{ + QString strTag; + QString strDesc; + QString strLoc; + QString strChan; + QString strRtu; + QString strSerial; + int nDevID; + int nStatus; + bool isInit; + + bool operator <(const SerialStatus &t1) const + { + return nDevID < t1.nDevID; + } + + SerialStatus(){ + strTag = ""; + strDesc = ""; + strLoc = ""; + strChan = ""; + strRtu = ""; + strSerial = ""; + nDevID = 0; + nStatus = CN_Communication_Interrupte; + isInit = false; + } +}; + +struct SerialSort +{ + int nDevID; + QString strSerial; + + bool operator <(const SerialSort &t1) const + { + return nDevID < t1.nDevID; + } + bool operator ==(const SerialSort &t1) const + { + return strSerial == t1.strSerial; + } + SerialSort(){ + nDevID = 0; + strSerial = ""; + } +}; + +#endif // CSERIACOMMON_H diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.cpp b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.cpp index 7eba878c..3a25eef2 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.cpp +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.cpp @@ -1,25 +1,25 @@ -#include "CSeriaDevPluginWidget.h" -#include "CSerialDevStatusWidget.h" - -CSeriaDevPluginWidget::CSeriaDevPluginWidget(QObject *parent) : QObject(parent) -{ - -} - -CSeriaDevPluginWidget::~CSeriaDevPluginWidget() -{ - -} - -bool CSeriaDevPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CSerialDevStatusWidget *pWidget = new CSerialDevStatusWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CSeriaDevPluginWidget::release() -{ - -} +#include "CSeriaDevPluginWidget.h" +#include "CSerialDevStatusWidget.h" + +CSeriaDevPluginWidget::CSeriaDevPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +CSeriaDevPluginWidget::~CSeriaDevPluginWidget() +{ + +} + +bool CSeriaDevPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CSerialDevStatusWidget *pWidget = new CSerialDevStatusWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CSeriaDevPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.h b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.h index 5b8ad392..d9b6ca4f 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CSERIADEVPLUGINWIDGET_H -#define CSERIADEVPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CSeriaDevPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CSeriaDevPluginWidget(QObject *parent = 0); - ~CSeriaDevPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CSERIADEVPLUGINWIDGET_H +#ifndef CSERIADEVPLUGINWIDGET_H +#define CSERIADEVPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CSeriaDevPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CSeriaDevPluginWidget(QObject *parent = 0); + ~CSeriaDevPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CSERIADEVPLUGINWIDGET_H diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.cpp b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.cpp index bdd24da5..b382b8f9 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.cpp +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.cpp @@ -1,169 +1,169 @@ -#include "CSeriaDevTableModel.h" -#include - -CSeriaDevTableModel::CSeriaDevTableModel(QObject *parent) - : QAbstractTableModel(parent) -{ - m_header << tr("序号") << tr("位置") << tr("通道描述") << tr("RTU描述") << tr("设备描述") << tr("端口名") << tr("设备ID") << tr("通讯状态"); - - m_strInterrupte = tr("通讯中断"); - m_strNormal = tr("通讯正常"); -} - -CSeriaDevTableModel::~CSeriaDevTableModel() -{ - m_dataList.clear(); -} - -void CSeriaDevTableModel::updateRealData(const QList &dataList) -{ - beginResetModel(); - m_dataList.clear(); - m_dataList = dataList; - qSort(m_dataList.begin(), m_dataList.end()); - endResetModel(); -} - -void CSeriaDevTableModel::updateRealValue(QList &dataList) -{ - m_dataList.swap(dataList); - qSort(m_dataList.begin(), m_dataList.end()); - update(); -} - -void CSeriaDevTableModel::setInterrupteDesc(const QString &text) -{ - m_strInterrupte = text; -} - -void CSeriaDevTableModel::setNormalDesc(const QString &text) -{ - m_strNormal = text; -} - -void CSeriaDevTableModel::update() -{ - QModelIndex topLeft = createIndex(0, 7); - QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount()); - emit dataChanged(topLeft, bottomRight); -} - -QVariant CSeriaDevTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_header.at(section); - } - } - return QVariant(); -} - -int CSeriaDevTableModel::rowCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_dataList.size(); -} - -int CSeriaDevTableModel::columnCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return 0; - - return m_header.size(); -} - -QVariant CSeriaDevTableModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - return Qt::AlignCenter; - } - - if(Qt::TextColorRole == role && index.column() == 7) - { - if(!m_dataList.at(index.row()).isInit) - { - return QVariant(); - } - if(m_dataList.at(index.row()).nStatus == CN_Communication_Interrupte) - { - return QVariant(QBrush(QColor(255,0,0))); - } - return QVariant(); - } - - if(Qt::DisplayRole != role) - { - return QVariant(); - } - - switch (index.column()) { - case 0: - { - return index.row()+1; - } - case 1: - { - return m_dataList.at(index.row()).strLoc; - } - case 2: - { - return m_dataList.at(index.row()).strChan; - } - case 3: - { - return m_dataList.at(index.row()).strRtu; - } - case 4: - { - return m_dataList.at(index.row()).strDesc; - } - case 5: - { - return m_dataList.at(index.row()).strSerial; - } - case 6: - { - return m_dataList.at(index.row()).nDevID; - } - case 7: - { - if(!m_dataList.at(index.row()).isInit) - { - return QVariant(); - } - return getComStatusDesc(m_dataList.at(index.row()).nStatus); - } - default: - break; - } - - return QVariant(); -} - -QString CSeriaDevTableModel::getComStatusDesc(const int &status) const -{ - switch (status) { - case CN_Communication_Interrupte: - { - return m_strInterrupte; - } - case CN_Communication_Normal: - { - return m_strNormal; - } - default: - break; - } - - return QString(); -} +#include "CSeriaDevTableModel.h" +#include + +CSeriaDevTableModel::CSeriaDevTableModel(QObject *parent) + : QAbstractTableModel(parent) +{ + m_header << tr("序号") << tr("位置") << tr("通道描述") << tr("RTU描述") << tr("设备描述") << tr("端口名") << tr("设备ID") << tr("通讯状态"); + + m_strInterrupte = tr("通讯中断"); + m_strNormal = tr("通讯正常"); +} + +CSeriaDevTableModel::~CSeriaDevTableModel() +{ + m_dataList.clear(); +} + +void CSeriaDevTableModel::updateRealData(const QList &dataList) +{ + beginResetModel(); + m_dataList.clear(); + m_dataList = dataList; + qSort(m_dataList.begin(), m_dataList.end()); + endResetModel(); +} + +void CSeriaDevTableModel::updateRealValue(QList &dataList) +{ + m_dataList.swap(dataList); + qSort(m_dataList.begin(), m_dataList.end()); + update(); +} + +void CSeriaDevTableModel::setInterrupteDesc(const QString &text) +{ + m_strInterrupte = text; +} + +void CSeriaDevTableModel::setNormalDesc(const QString &text) +{ + m_strNormal = text; +} + +void CSeriaDevTableModel::update() +{ + QModelIndex topLeft = createIndex(0, 7); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount()); + emit dataChanged(topLeft, bottomRight); +} + +QVariant CSeriaDevTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); +} + +int CSeriaDevTableModel::rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_dataList.size(); +} + +int CSeriaDevTableModel::columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return m_header.size(); +} + +QVariant CSeriaDevTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + return Qt::AlignCenter; + } + + if(Qt::TextColorRole == role && index.column() == 7) + { + if(!m_dataList.at(index.row()).isInit) + { + return QVariant(); + } + if(m_dataList.at(index.row()).nStatus == CN_Communication_Interrupte) + { + return QVariant(QBrush(QColor(255,0,0))); + } + return QVariant(); + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + switch (index.column()) { + case 0: + { + return index.row()+1; + } + case 1: + { + return m_dataList.at(index.row()).strLoc; + } + case 2: + { + return m_dataList.at(index.row()).strChan; + } + case 3: + { + return m_dataList.at(index.row()).strRtu; + } + case 4: + { + return m_dataList.at(index.row()).strDesc; + } + case 5: + { + return m_dataList.at(index.row()).strSerial; + } + case 6: + { + return m_dataList.at(index.row()).nDevID; + } + case 7: + { + if(!m_dataList.at(index.row()).isInit) + { + return QVariant(); + } + return getComStatusDesc(m_dataList.at(index.row()).nStatus); + } + default: + break; + } + + return QVariant(); +} + +QString CSeriaDevTableModel::getComStatusDesc(const int &status) const +{ + switch (status) { + case CN_Communication_Interrupte: + { + return m_strInterrupte; + } + case CN_Communication_Normal: + { + return m_strNormal; + } + default: + break; + } + + return QString(); +} diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.h b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.h index 34bc3585..92577db5 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.h @@ -1,39 +1,39 @@ -#ifndef CSERIADEVTABLEMODEL_H -#define CSERIADEVTABLEMODEL_H - -#include -#include "CSeriaCommon.h" - -class CSeriaDevTableModel : public QAbstractTableModel -{ -public: - CSeriaDevTableModel(QObject *parent = Q_NULLPTR); - ~CSeriaDevTableModel(); - - void updateRealData(const QList &dataList); - - void updateRealValue(QList &dataList); - - void setInterrupteDesc(const QString &text); - - void setNormalDesc(const QString &text); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - -private: - void update(); - -private: - QString getComStatusDesc(const int &status) const; - -private: - QStringList m_header; - QList m_dataList; - QString m_strInterrupte; - QString m_strNormal; -}; - -#endif // CSERIADEVTABLEMODEL_H +#ifndef CSERIADEVTABLEMODEL_H +#define CSERIADEVTABLEMODEL_H + +#include +#include "CSeriaCommon.h" + +class CSeriaDevTableModel : public QAbstractTableModel +{ +public: + CSeriaDevTableModel(QObject *parent = Q_NULLPTR); + ~CSeriaDevTableModel(); + + void updateRealData(const QList &dataList); + + void updateRealValue(QList &dataList); + + void setInterrupteDesc(const QString &text); + + void setNormalDesc(const QString &text); + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +private: + void update(); + +private: + QString getComStatusDesc(const int &status) const; + +private: + QStringList m_header; + QList m_dataList; + QString m_strInterrupte; + QString m_strNormal; +}; + +#endif // CSERIADEVTABLEMODEL_H diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.cpp b/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.cpp index 29cc89d6..0832ed6a 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.cpp +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.cpp @@ -1,324 +1,324 @@ -#include "CSerialDevStatusWidget.h" -#include "CSeriaDevTableModel.h" -#include "CDataManage.h" -#include "CRealDataCollect.h" -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include -#include -#include -#include -#include -#include "model_excel/xlsx/xlsxdocument.h" -#include - -CSerialDevStatusWidget::CSerialDevStatusWidget(QWidget *parent, bool editMode) - : QWidget(parent), - m_pTableModel(Q_NULLPTR), - m_pDpcdaForApp(Q_NULLPTR) -{ - initStyle(); - initView(); - if(!editMode) - { - initData(); - initConnect(); - } -} - -CSerialDevStatusWidget::~CSerialDevStatusWidget() -{ - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - delete m_pDpcdaForApp; - } - m_pDpcdaForApp = NULL; - - if(m_pTableModel) - { - delete m_pTableModel; - } - m_pTableModel = Q_NULLPTR; - - m_serialStatusMap.clear(); - - CDataManage::instance()->destory(); -} - -void CSerialDevStatusWidget::setRtu(const QString &rtuTags) -{ - emit m_pTreeWidget->itemClicked(Q_NULLPTR, 0); - - QStringList rtuList = rtuTags.split(","); - if(rtuList.isEmpty()) - { - return; - } - - bool isClick = false; - for(int nIndex(0); nIndextopLevelItemCount(); nIndex++) - { - QTreeWidgetItem * item = m_pTreeWidget->topLevelItem(nIndex); - if(!rtuList.contains(item->data(0, Qt::UserRole).toString(), Qt::CaseSensitive)) - { - item->setHidden(true); - } - else - { - item->setHidden(false); - if(!isClick) - { - emit m_pTreeWidget->itemClicked(item, 0); - m_pTreeWidget->setCurrentItem(item); - isClick = true; - } - } - } -} - -void CSerialDevStatusWidget::setColumnWidth(int column, int width) -{ - if(m_pTableView) - { - m_pTableView->setColumnWidth(column, width); - } -} - -void CSerialDevStatusWidget::setInterrupteDesc(const QString &text) -{ - if(m_pTableModel) - { - m_pTableModel->setInterrupteDesc(text); - } -} - -void CSerialDevStatusWidget::setNormalDesc(const QString &text) -{ - if(m_pTableModel) - { - m_pTableModel->setNormalDesc(text); - } -} - -void CSerialDevStatusWidget::soltExportExcel() -{ - - QString sExcelFileName = QFileDialog::getSaveFileName(this, tr("保存"), QString(""), "*.xlsx"); - if(sExcelFileName.isEmpty()) - return; - - QXlsx::Document xlsx; - - int rowcount=m_pTableModel->rowCount(); - int colcount=m_pTableModel->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - // 写内容 - for ( int i=0; idata(m_pTableModel->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText ); - } - } - // 保存到文件 - if(xlsx.saveAs(sExcelFileName)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!")); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } -} - -void CSerialDevStatusWidget::initStyle() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("serialStatus.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CSerialDevStatusWidget::initView() -{ - QSplitter * splitter = new QSplitter(Qt::Horizontal); - QWidget *rightwidget = new QWidget(splitter); - m_btnExport = new QPushButton(tr("导出"), rightwidget); - - m_pTreeWidget = new QTreeWidget; - m_pTreeWidget->setColumnCount(1); - m_pTreeWidget->setHeaderLabel(tr("RTU/端口")); - - m_pTableView = new QTableView(rightwidget); - m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_pTableView->setSelectionMode(QAbstractItemView::NoSelection); - m_pTableView->horizontalHeader()->setStretchLastSection(true); - - m_pTableModel = new CSeriaDevTableModel; - m_pTableView->setModel(m_pTableModel); - - splitter->addWidget(m_pTreeWidget); - // splitter->addWidget(m_pTableView); - - QVBoxLayout *rightLayout = new QVBoxLayout(rightwidget); - rightLayout->addWidget(m_pTableView); - rightLayout->addWidget(m_btnExport); - - splitter->addWidget(rightwidget); - - splitter->setStretchFactor(0, 1); - splitter->setStretchFactor(1, 3); - QHBoxLayout * layout = new QHBoxLayout; - layout->addWidget(splitter); - setLayout(layout); -} - -void CSerialDevStatusWidget::initData() -{ - //< 初始化RTU-串口设备 - const QMap> &rtuSerialMap = CDataManage::instance()->getRtuSerialMap(); - QMap>::const_iterator rtuIter = rtuSerialMap.constBegin(); - for(; rtuIter != rtuSerialMap.constEnd(); rtuIter++) - { - QTreeWidgetItem * item = new QTreeWidgetItem; - item->setText(0, CDataManage::instance()->getRtuName(rtuIter.key())); - item->setData(0, Qt::UserRole, rtuIter.key()); - item->setData(0, Qt::UserRole+1, Node_Rtu); - m_pTreeWidget->addTopLevelItem(item); - - QStringList uniList; - const QList &serialList = rtuIter.value(); - for(int nIndex(0); nIndexsetText(0, serialList[nIndex].strSerial); - sItem->setData(0, Qt::UserRole+1, Node_Serial); - item->addChild(sItem); - uniList.append(serialList[nIndex].strSerial); - } - } - } - - //< 初始化无串口设备RTU - const QStringList &rtuSerialList = rtuSerialMap.keys(); - const QStringList &rtuDevList = CDataManage::instance()->getRtuDevMap().keys(); - for(int nIndex(0); nIndexsetText(0, CDataManage::instance()->getRtuName(rtuDevList[nIndex])); - item->setData(0, Qt::UserRole, rtuDevList[nIndex]); - item->setData(0, Qt::UserRole+1, Node_Rtu); - m_pTreeWidget->addTopLevelItem(item); - } - -} - -void CSerialDevStatusWidget::initConnect() -{ - m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); - - connect(m_pTreeWidget, &QTreeWidget::itemClicked, this, &CSerialDevStatusWidget::slotItemClicked); - connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CSerialDevStatusWidget::slotUpdateDi); - - connect(m_btnExport, &QPushButton::clicked, this, &CSerialDevStatusWidget::soltExportExcel); - if(m_pTreeWidget->topLevelItem(0)) - { - m_pTreeWidget->setCurrentItem(m_pTreeWidget->topLevelItem(0)); - emit m_pTreeWidget->itemClicked(m_pTreeWidget->topLevelItem(0), 0); - } -} - -void CSerialDevStatusWidget::slotItemClicked(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column) - m_pDpcdaForApp->unsubscribeAll(); - m_serialStatusMap.clear(); - - QList serialStatusList; - if(item == Q_NULLPTR) - { - m_pTableModel->updateRealData(serialStatusList); - return; - } - - EN_Tree_Node node = (EN_Tree_Node)item->data(0, Qt::UserRole+1).toInt(); - if(node == Node_Rtu) - { - QString rtuTag = item->data(0, Qt::UserRole).toString(); - serialStatusList.append(CDataManage::instance()->getDevInfoByRtu(rtuTag)); - - for(int nIndex(0); nIndexchildCount(); nIndex++) - { - QString serialTag = item->child(nIndex)->data(0, Qt::DisplayRole).toString(); - serialStatusList.append(CDataManage::instance()->getDevInfoBySerial(rtuTag+"."+serialTag)); - } - } - else if(node == Node_Serial) - { - QString rtuTag = item->parent()->data(0, Qt::UserRole).toString(); - QString serialTag = item->data(0, Qt::DisplayRole).toString(); - serialStatusList.append(CDataManage::instance()->getDevInfoBySerial(rtuTag+"."+serialTag)); - } - - foreach (const SerialStatus& sSerialStatus, serialStatusList) { - m_serialStatusMap[sSerialStatus.strTag] = sSerialStatus; - m_pDpcdaForApp->subscribe("digital", sSerialStatus.strTag.toStdString(), "value"); - } - - m_pTableModel->updateRealData(m_serialStatusMap.values()); -} - -void CSerialDevStatusWidget::slotUpdateDi(QMap > diMap) -{ - bool isChange = false; - QMap>::iterator iter = diMap.begin(); - for(; iter != diMap.end(); iter++) - { - QMap::iterator sIter = m_serialStatusMap.find(iter.key()); - if(sIter != m_serialStatusMap.end()) - { - SerialStatus &serialStatus = sIter.value(); - serialStatus.isInit = true; - serialStatus.nStatus = iter.value().first; - if(isChange == false) - { - isChange = true; - } - } - } - if(isChange) - { - QList serialStatusList = m_serialStatusMap.values(); - m_pTableModel->updateRealValue(serialStatusList); - } -} +#include "CSerialDevStatusWidget.h" +#include "CSeriaDevTableModel.h" +#include "CDataManage.h" +#include "CRealDataCollect.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include +#include +#include +#include +#include +#include "model_excel/xlsx/xlsxdocument.h" +#include + +CSerialDevStatusWidget::CSerialDevStatusWidget(QWidget *parent, bool editMode) + : QWidget(parent), + m_pTableModel(Q_NULLPTR), + m_pDpcdaForApp(Q_NULLPTR) +{ + initStyle(); + initView(); + if(!editMode) + { + initData(); + initConnect(); + } +} + +CSerialDevStatusWidget::~CSerialDevStatusWidget() +{ + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = NULL; + + if(m_pTableModel) + { + delete m_pTableModel; + } + m_pTableModel = Q_NULLPTR; + + m_serialStatusMap.clear(); + + CDataManage::instance()->destory(); +} + +void CSerialDevStatusWidget::setRtu(const QString &rtuTags) +{ + emit m_pTreeWidget->itemClicked(Q_NULLPTR, 0); + + QStringList rtuList = rtuTags.split(","); + if(rtuList.isEmpty()) + { + return; + } + + bool isClick = false; + for(int nIndex(0); nIndextopLevelItemCount(); nIndex++) + { + QTreeWidgetItem * item = m_pTreeWidget->topLevelItem(nIndex); + if(!rtuList.contains(item->data(0, Qt::UserRole).toString(), Qt::CaseSensitive)) + { + item->setHidden(true); + } + else + { + item->setHidden(false); + if(!isClick) + { + emit m_pTreeWidget->itemClicked(item, 0); + m_pTreeWidget->setCurrentItem(item); + isClick = true; + } + } + } +} + +void CSerialDevStatusWidget::setColumnWidth(int column, int width) +{ + if(m_pTableView) + { + m_pTableView->setColumnWidth(column, width); + } +} + +void CSerialDevStatusWidget::setInterrupteDesc(const QString &text) +{ + if(m_pTableModel) + { + m_pTableModel->setInterrupteDesc(text); + } +} + +void CSerialDevStatusWidget::setNormalDesc(const QString &text) +{ + if(m_pTableModel) + { + m_pTableModel->setNormalDesc(text); + } +} + +void CSerialDevStatusWidget::soltExportExcel() +{ + + QString sExcelFileName = QFileDialog::getSaveFileName(this, tr("保存"), QString(""), "*.xlsx"); + if(sExcelFileName.isEmpty()) + return; + + QXlsx::Document xlsx; + + int rowcount=m_pTableModel->rowCount(); + int colcount=m_pTableModel->columnCount(); + for(int i=0;iheaderData(i, Qt::Horizontal).toString()); + } + // 写内容 + for ( int i=0; idata(m_pTableModel->index(i, j)).toString(); + xlsx.write( i+2, j+1, sText ); + } + } + // 保存到文件 + if(xlsx.saveAs(sExcelFileName)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!")); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } +} + +void CSerialDevStatusWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("serialStatus.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CSerialDevStatusWidget::initView() +{ + QSplitter * splitter = new QSplitter(Qt::Horizontal); + QWidget *rightwidget = new QWidget(splitter); + m_btnExport = new QPushButton(tr("导出"), rightwidget); + + m_pTreeWidget = new QTreeWidget; + m_pTreeWidget->setColumnCount(1); + m_pTreeWidget->setHeaderLabel(tr("RTU/端口")); + + m_pTableView = new QTableView(rightwidget); + m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pTableView->setSelectionMode(QAbstractItemView::NoSelection); + m_pTableView->horizontalHeader()->setStretchLastSection(true); + + m_pTableModel = new CSeriaDevTableModel; + m_pTableView->setModel(m_pTableModel); + + splitter->addWidget(m_pTreeWidget); + // splitter->addWidget(m_pTableView); + + QVBoxLayout *rightLayout = new QVBoxLayout(rightwidget); + rightLayout->addWidget(m_pTableView); + rightLayout->addWidget(m_btnExport); + + splitter->addWidget(rightwidget); + + splitter->setStretchFactor(0, 1); + splitter->setStretchFactor(1, 3); + QHBoxLayout * layout = new QHBoxLayout; + layout->addWidget(splitter); + setLayout(layout); +} + +void CSerialDevStatusWidget::initData() +{ + //< 初始化RTU-串口设备 + const QMap> &rtuSerialMap = CDataManage::instance()->getRtuSerialMap(); + QMap>::const_iterator rtuIter = rtuSerialMap.constBegin(); + for(; rtuIter != rtuSerialMap.constEnd(); rtuIter++) + { + QTreeWidgetItem * item = new QTreeWidgetItem; + item->setText(0, CDataManage::instance()->getRtuName(rtuIter.key())); + item->setData(0, Qt::UserRole, rtuIter.key()); + item->setData(0, Qt::UserRole+1, Node_Rtu); + m_pTreeWidget->addTopLevelItem(item); + + QStringList uniList; + const QList &serialList = rtuIter.value(); + for(int nIndex(0); nIndexsetText(0, serialList[nIndex].strSerial); + sItem->setData(0, Qt::UserRole+1, Node_Serial); + item->addChild(sItem); + uniList.append(serialList[nIndex].strSerial); + } + } + } + + //< 初始化无串口设备RTU + const QStringList &rtuSerialList = rtuSerialMap.keys(); + const QStringList &rtuDevList = CDataManage::instance()->getRtuDevMap().keys(); + for(int nIndex(0); nIndexsetText(0, CDataManage::instance()->getRtuName(rtuDevList[nIndex])); + item->setData(0, Qt::UserRole, rtuDevList[nIndex]); + item->setData(0, Qt::UserRole+1, Node_Rtu); + m_pTreeWidget->addTopLevelItem(item); + } + +} + +void CSerialDevStatusWidget::initConnect() +{ + m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); + + connect(m_pTreeWidget, &QTreeWidget::itemClicked, this, &CSerialDevStatusWidget::slotItemClicked); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CSerialDevStatusWidget::slotUpdateDi); + + connect(m_btnExport, &QPushButton::clicked, this, &CSerialDevStatusWidget::soltExportExcel); + if(m_pTreeWidget->topLevelItem(0)) + { + m_pTreeWidget->setCurrentItem(m_pTreeWidget->topLevelItem(0)); + emit m_pTreeWidget->itemClicked(m_pTreeWidget->topLevelItem(0), 0); + } +} + +void CSerialDevStatusWidget::slotItemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column) + m_pDpcdaForApp->unsubscribeAll(); + m_serialStatusMap.clear(); + + QList serialStatusList; + if(item == Q_NULLPTR) + { + m_pTableModel->updateRealData(serialStatusList); + return; + } + + EN_Tree_Node node = (EN_Tree_Node)item->data(0, Qt::UserRole+1).toInt(); + if(node == Node_Rtu) + { + QString rtuTag = item->data(0, Qt::UserRole).toString(); + serialStatusList.append(CDataManage::instance()->getDevInfoByRtu(rtuTag)); + + for(int nIndex(0); nIndexchildCount(); nIndex++) + { + QString serialTag = item->child(nIndex)->data(0, Qt::DisplayRole).toString(); + serialStatusList.append(CDataManage::instance()->getDevInfoBySerial(rtuTag+"."+serialTag)); + } + } + else if(node == Node_Serial) + { + QString rtuTag = item->parent()->data(0, Qt::UserRole).toString(); + QString serialTag = item->data(0, Qt::DisplayRole).toString(); + serialStatusList.append(CDataManage::instance()->getDevInfoBySerial(rtuTag+"."+serialTag)); + } + + foreach (const SerialStatus& sSerialStatus, serialStatusList) { + m_serialStatusMap[sSerialStatus.strTag] = sSerialStatus; + m_pDpcdaForApp->subscribe("digital", sSerialStatus.strTag.toStdString(), "value"); + } + + m_pTableModel->updateRealData(m_serialStatusMap.values()); +} + +void CSerialDevStatusWidget::slotUpdateDi(QMap > diMap) +{ + bool isChange = false; + QMap>::iterator iter = diMap.begin(); + for(; iter != diMap.end(); iter++) + { + QMap::iterator sIter = m_serialStatusMap.find(iter.key()); + if(sIter != m_serialStatusMap.end()) + { + SerialStatus &serialStatus = sIter.value(); + serialStatus.isInit = true; + serialStatus.nStatus = iter.value().first; + if(isChange == false) + { + isChange = true; + } + } + } + if(isChange) + { + QList serialStatusList = m_serialStatusMap.values(); + m_pTableModel->updateRealValue(serialStatusList); + } +} diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.h b/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.h index a8877d89..a7442eea 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.h @@ -1,55 +1,55 @@ -#ifndef CSERIALDEVSTATUSWIDGET_H -#define CSERIALDEVSTATUSWIDGET_H - -#include -#include -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "CSeriaCommon.h" -#include - -class QTreeWidget; -class QTableView; -class QTreeWidgetItem; -class CSeriaDevTableModel; -class CSerialDevStatusWidget : public QWidget -{ - Q_OBJECT - -public: - CSerialDevStatusWidget(QWidget *parent = 0, bool editMode = true); - ~CSerialDevStatusWidget(); - -public slots: - /** - * @brief setRtu 设置显示的RTU - * @param rtuTags station2.PSCADA.ch-G04.rtu-G04 多个RTU以“,”分隔 - */ - void setRtu(const QString &rtuTags); - - void setColumnWidth(int column, int width); - - void setInterrupteDesc(const QString &text); - - void setNormalDesc(const QString &text); - - void soltExportExcel(); -private: - void initStyle(); - void initView(); - void initData(); - void initConnect(); - -private slots: - void slotItemClicked(QTreeWidgetItem *item, int column); - void slotUpdateDi(QMap> diMap); - -private: - QTreeWidget * m_pTreeWidget; - QTableView * m_pTableView; - CSeriaDevTableModel * m_pTableModel; - QPushButton * m_btnExport; - kbd_service::CDpcdaForApp *m_pDpcdaForApp; - QMap m_serialStatusMap; -}; - -#endif // CSERIALDEVSTATUSWIDGET_H +#ifndef CSERIALDEVSTATUSWIDGET_H +#define CSERIALDEVSTATUSWIDGET_H + +#include +#include +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "CSeriaCommon.h" +#include + +class QTreeWidget; +class QTableView; +class QTreeWidgetItem; +class CSeriaDevTableModel; +class CSerialDevStatusWidget : public QWidget +{ + Q_OBJECT + +public: + CSerialDevStatusWidget(QWidget *parent = 0, bool editMode = true); + ~CSerialDevStatusWidget(); + +public slots: + /** + * @brief setRtu 设置显示的RTU + * @param rtuTags station2.PSCADA.ch-G04.rtu-G04 多个RTU以“,”分隔 + */ + void setRtu(const QString &rtuTags); + + void setColumnWidth(int column, int width); + + void setInterrupteDesc(const QString &text); + + void setNormalDesc(const QString &text); + + void soltExportExcel(); +private: + void initStyle(); + void initView(); + void initData(); + void initConnect(); + +private slots: + void slotItemClicked(QTreeWidgetItem *item, int column); + void slotUpdateDi(QMap> diMap); + +private: + QTreeWidget * m_pTreeWidget; + QTableView * m_pTableView; + CSeriaDevTableModel * m_pTableModel; + QPushButton * m_btnExport; + kbd_service::CDpcdaForApp *m_pDpcdaForApp; + QMap m_serialStatusMap; +}; + +#endif // CSERIALDEVSTATUSWIDGET_H diff --git a/product/src/gui/plugin/SerialDevStatusWidget/SerialDevStatusWidget.pro b/product/src/gui/plugin/SerialDevStatusWidget/SerialDevStatusWidget.pro index 00838293..b7cd949f 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/SerialDevStatusWidget.pro +++ b/product/src/gui/plugin/SerialDevStatusWidget/SerialDevStatusWidget.pro @@ -1,60 +1,60 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2022-02-22T16:33:27 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = SerialDevStatusWidget -TEMPLATE = lib - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CSeriaDevTableModel.cpp \ - CSerialDevStatusWidget.cpp \ - CDataManage.cpp \ - CRealDataCollect.cpp \ - CSeriaDevPluginWidget.cpp - -HEADERS += \ - CSeriaDevTableModel.h \ - CSerialDevStatusWidget.h \ - CSeriaCommon.h \ - CDataManage.h \ - CRealDataCollect.h \ - CSeriaDevPluginWidget.h - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lrdb_api \ - -ldb_base_api \ - -ldb_api_ex \ - -lprotobuf \ - -lnet_msg_bus_api \ - -ldp_chg_data_api \ - -lpub_utility_api \ - -lmodel_excel - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2022-02-22T16:33:27 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = SerialDevStatusWidget +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CSeriaDevTableModel.cpp \ + CSerialDevStatusWidget.cpp \ + CDataManage.cpp \ + CRealDataCollect.cpp \ + CSeriaDevPluginWidget.cpp + +HEADERS += \ + CSeriaDevTableModel.h \ + CSerialDevStatusWidget.h \ + CSeriaCommon.h \ + CDataManage.h \ + CRealDataCollect.h \ + CSeriaDevPluginWidget.h + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lrdb_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lprotobuf \ + -lnet_msg_bus_api \ + -ldp_chg_data_api \ + -lpub_utility_api \ + -lmodel_excel + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/SerialDevStatusWidget/main.cpp b/product/src/gui/plugin/SerialDevStatusWidget/main.cpp index ffe036ab..b6be7c08 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/main.cpp +++ b/product/src/gui/plugin/SerialDevStatusWidget/main.cpp @@ -1,31 +1,31 @@ -#include "CSerialDevStatusWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "net/net_msg_bus_api/MsgBusApi.h" - -int main(int argc, char *argv[]) -{ - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - - kbd_service::CDpcdaForApp::initGlobalThread(); - - { - QApplication a(argc, argv); - CSerialDevStatusWidget w; - w.show(); - - a.exec(); - } - - kbd_service::CDpcdaForApp::releaseGlobalThread(); - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include "CSerialDevStatusWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" + +int main(int argc, char *argv[]) +{ + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + + kbd_service::CDpcdaForApp::initGlobalThread(); + + { + QApplication a(argc, argv); + CSerialDevStatusWidget w; + w.show(); + + a.exec(); + } + + kbd_service::CDpcdaForApp::releaseGlobalThread(); + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/ShiftWidget/CMyCalendar.cpp b/product/src/gui/plugin/ShiftWidget/CMyCalendar.cpp index fbdd3ef2..c7fb5b33 100644 --- a/product/src/gui/plugin/ShiftWidget/CMyCalendar.cpp +++ b/product/src/gui/plugin/ShiftWidget/CMyCalendar.cpp @@ -1,47 +1,47 @@ -#include "CMyCalendar.h" -#include "ui_CMyCalendar.h" -#include -#include -CMyCalendar::CMyCalendar(QWidget *parent) : - QWidget(parent), - ui(new Ui::CMyCalendar) -{ - ui->setupUi(this); - connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); - connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); - connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); - m_startTime = QDate::currentDate(); - m_endTime = QDate::currentDate(); - ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); - ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); - ui->lineEdit->setReadOnly(true); - ui->lineEdit_2->setReadOnly(true); -} - -CMyCalendar::~CMyCalendar() -{ - delete ui; -} - -void CMyCalendar::slot_endTime(QDate date) -{ - ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); - m_endTime = date; - if(m_startTime.isNull() || m_endTime < m_startTime) - { - //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); - return; - } - emit sig_endTimeClick(m_startTime,m_endTime); -} - -void CMyCalendar::slot_startTime(QDate date) -{ - m_startTime = date; - ui->lineEdit->setText(date.toString("yyyy-MM-dd")); -} - -void CMyCalendar::slot_cancle() -{ - emit sig_cancle(); -} +#include "CMyCalendar.h" +#include "ui_CMyCalendar.h" +#include +#include +CMyCalendar::CMyCalendar(QWidget *parent) : + QWidget(parent), + ui(new Ui::CMyCalendar) +{ + ui->setupUi(this); + connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); + connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); + connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); + m_startTime = QDate::currentDate(); + m_endTime = QDate::currentDate(); + ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); + ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit_2->setReadOnly(true); +} + +CMyCalendar::~CMyCalendar() +{ + delete ui; +} + +void CMyCalendar::slot_endTime(QDate date) +{ + ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); + m_endTime = date; + if(m_startTime.isNull() || m_endTime < m_startTime) + { + //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); + return; + } + emit sig_endTimeClick(m_startTime,m_endTime); +} + +void CMyCalendar::slot_startTime(QDate date) +{ + m_startTime = date; + ui->lineEdit->setText(date.toString("yyyy-MM-dd")); +} + +void CMyCalendar::slot_cancle() +{ + emit sig_cancle(); +} diff --git a/product/src/gui/plugin/ShiftWidget/CMyCalendar.h b/product/src/gui/plugin/ShiftWidget/CMyCalendar.h index a3f65632..0f9997a1 100644 --- a/product/src/gui/plugin/ShiftWidget/CMyCalendar.h +++ b/product/src/gui/plugin/ShiftWidget/CMyCalendar.h @@ -1,30 +1,30 @@ -#ifndef CMYCALENDAR_H -#define CMYCALENDAR_H - -#include -#include -namespace Ui { -class CMyCalendar; -} - -class CMyCalendar : public QWidget -{ - Q_OBJECT -signals: - void sig_endTimeClick(QDate startDate,QDate endDate); - void sig_startTimeClick(QDate date); - void sig_cancle(); -public: - explicit CMyCalendar(QWidget *parent = 0); - ~CMyCalendar(); -public slots: - void slot_endTime(QDate date); - void slot_startTime(QDate date); - void slot_cancle(); -private: - Ui::CMyCalendar *ui; - QDate m_startTime; - QDate m_endTime; -}; - -#endif // CMYCALENDAR_H +#ifndef CMYCALENDAR_H +#define CMYCALENDAR_H + +#include +#include +namespace Ui { +class CMyCalendar; +} + +class CMyCalendar : public QWidget +{ + Q_OBJECT +signals: + void sig_endTimeClick(QDate startDate,QDate endDate); + void sig_startTimeClick(QDate date); + void sig_cancle(); +public: + explicit CMyCalendar(QWidget *parent = 0); + ~CMyCalendar(); +public slots: + void slot_endTime(QDate date); + void slot_startTime(QDate date); + void slot_cancle(); +private: + Ui::CMyCalendar *ui; + QDate m_startTime; + QDate m_endTime; +}; + +#endif // CMYCALENDAR_H diff --git a/product/src/gui/plugin/ShiftWidget/CMyCalendar.ui b/product/src/gui/plugin/ShiftWidget/CMyCalendar.ui index 3cfb549d..98fb3b2c 100644 --- a/product/src/gui/plugin/ShiftWidget/CMyCalendar.ui +++ b/product/src/gui/plugin/ShiftWidget/CMyCalendar.ui @@ -1,119 +1,119 @@ - - - CMyCalendar - - - - 0 - 0 - 538 - 264 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 20 - 0 - - - - - - - Qt::AlignCenter - - - - - - - - - - 取消 - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - + + + CMyCalendar + + + + 0 + 0 + 538 + 264 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 20 + 0 + + + + + + + Qt::AlignCenter + + + + + + + + + + 取消 + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ShiftWidget/CRecordWidget.cpp b/product/src/gui/plugin/ShiftWidget/CRecordWidget.cpp index 7327bd15..8c526ffe 100644 --- a/product/src/gui/plugin/ShiftWidget/CRecordWidget.cpp +++ b/product/src/gui/plugin/ShiftWidget/CRecordWidget.cpp @@ -1,93 +1,93 @@ -#include "CRecordWidget.h" -#include "ui_CRecordWidget.h" -#include - -CRecordWidget::CRecordWidget(QWidget *parent, kbd_dbms::CDbApi *dbRead, kbd_dbms::CDbApi *dbWrite) : - QDialog(parent), - ui(new Ui::CRecordWidget), - m_pReadDb(dbRead), - m_pWriteDb(dbWrite) -{ - ui->setupUi(this); - this->setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); - Init(); -} - -CRecordWidget::~CRecordWidget() -{ - delete ui; -} - -void CRecordWidget::Init() -{ - if(!m_pReadDb || !m_pReadDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - close(); - } - ui->textEdit1->setReadOnly(true); - QString strSql; - QSqlQuery objRet; - - Records.clear(); - DUTY_INFO Record; - strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info order by ID desc limit 2"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Record.ID=objRet.value(0).toInt(); - Record.GROUP_NAME=objRet.value(1).toString().toStdString(); - Record.USERS=objRet.value(2).toString().toStdString(); - Record.USERS_STATUS=objRet.value(3).toString().toStdString(); - Record.START_TIME=objRet.value(4).toString().toStdString(); - Record.END_TIME=objRet.value(5).toString().toStdString(); - Record.NOTE1=objRet.value(6).toString().toStdString(); - Record.NOTE2=objRet.value(7).toString().toStdString(); - Record.NOTE3=objRet.value(8).toString().toStdString(); - Records.push_back(Record); - } - } - if(Records.size()==0) - { - return; - } - else if(Records.size()==2) - { - ui->textEdit1->setText(Records.at(1).NOTE2.c_str()); - } - else - { - ui->textEdit1->setText("无"); - } - ui->textEdit2->setText(Records.at(0).NOTE1.c_str()); - ui->textEdit3->setText(Records.at(0).NOTE2.c_str()); - ui->textEdit4->setText(Records.at(0).NOTE3.c_str()); - -} - -void CRecordWidget::on_SaveButton_clicked() -{ - if(ui->textEdit2->toPlainText().toLocal8Bit().length()>1024||ui->textEdit3->toPlainText().toLocal8Bit().length()>1024||ui->textEdit4->toPlainText().toLocal8Bit().length()>1024) - { - QMessageBox::critical(this,"提示","内容太长,无法保存完整!"); - return; - } - - if(!m_pWriteDb || !m_pWriteDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - close(); - } - QString strSql; - - strSql="update duty_info set NOTE1='"+ui->textEdit2->toPlainText()+"',NOTE2='"+ui->textEdit3->toPlainText()+"',NOTE3='" - +ui->textEdit4->toPlainText()+"' where ID="+QString::number(Records.at(0).ID,10); - - if(!m_pWriteDb->execute(strSql)) - { - QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); - } - close(); -} +#include "CRecordWidget.h" +#include "ui_CRecordWidget.h" +#include + +CRecordWidget::CRecordWidget(QWidget *parent, kbd_dbms::CDbApi *dbRead, kbd_dbms::CDbApi *dbWrite) : + QDialog(parent), + ui(new Ui::CRecordWidget), + m_pReadDb(dbRead), + m_pWriteDb(dbWrite) +{ + ui->setupUi(this); + this->setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); + Init(); +} + +CRecordWidget::~CRecordWidget() +{ + delete ui; +} + +void CRecordWidget::Init() +{ + if(!m_pReadDb || !m_pReadDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + close(); + } + ui->textEdit1->setReadOnly(true); + QString strSql; + QSqlQuery objRet; + + Records.clear(); + DUTY_INFO Record; + strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info order by ID desc limit 2"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Record.ID=objRet.value(0).toInt(); + Record.GROUP_NAME=objRet.value(1).toString().toStdString(); + Record.USERS=objRet.value(2).toString().toStdString(); + Record.USERS_STATUS=objRet.value(3).toString().toStdString(); + Record.START_TIME=objRet.value(4).toString().toStdString(); + Record.END_TIME=objRet.value(5).toString().toStdString(); + Record.NOTE1=objRet.value(6).toString().toStdString(); + Record.NOTE2=objRet.value(7).toString().toStdString(); + Record.NOTE3=objRet.value(8).toString().toStdString(); + Records.push_back(Record); + } + } + if(Records.size()==0) + { + return; + } + else if(Records.size()==2) + { + ui->textEdit1->setText(Records.at(1).NOTE2.c_str()); + } + else + { + ui->textEdit1->setText("无"); + } + ui->textEdit2->setText(Records.at(0).NOTE1.c_str()); + ui->textEdit3->setText(Records.at(0).NOTE2.c_str()); + ui->textEdit4->setText(Records.at(0).NOTE3.c_str()); + +} + +void CRecordWidget::on_SaveButton_clicked() +{ + if(ui->textEdit2->toPlainText().toLocal8Bit().length()>1024||ui->textEdit3->toPlainText().toLocal8Bit().length()>1024||ui->textEdit4->toPlainText().toLocal8Bit().length()>1024) + { + QMessageBox::critical(this,"提示","内容太长,无法保存完整!"); + return; + } + + if(!m_pWriteDb || !m_pWriteDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + close(); + } + QString strSql; + + strSql="update duty_info set NOTE1='"+ui->textEdit2->toPlainText()+"',NOTE2='"+ui->textEdit3->toPlainText()+"',NOTE3='" + +ui->textEdit4->toPlainText()+"' where ID="+QString::number(Records.at(0).ID,10); + + if(!m_pWriteDb->execute(strSql)) + { + QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); + } + close(); +} diff --git a/product/src/gui/plugin/ShiftWidget/CRecordWidget.h b/product/src/gui/plugin/ShiftWidget/CRecordWidget.h index 4e5ff65a..8a8771f6 100644 --- a/product/src/gui/plugin/ShiftWidget/CRecordWidget.h +++ b/product/src/gui/plugin/ShiftWidget/CRecordWidget.h @@ -1,32 +1,32 @@ -#ifndef CRECORDWIDGET_H -#define CRECORDWIDGET_H - -#include -#include "db_api_ex/CDbApi.h" -#include "ShiftCommon.h" - -namespace Ui { -class CRecordWidget; -} - -class CRecordWidget : public QDialog -{ - Q_OBJECT - -public: - explicit CRecordWidget(QWidget *parent = 0, kbd_dbms::CDbApi *dbRead = NULL, kbd_dbms::CDbApi *dbWrite = NULL); - ~CRecordWidget(); - void Init(); - -private slots: - void on_SaveButton_clicked(); - -private: - Ui::CRecordWidget *ui; - - kbd_dbms::CDbApi *m_pReadDb; - kbd_dbms::CDbApi *m_pWriteDb; - std::vector Records; -}; - -#endif // CRECORDWIDGET_H +#ifndef CRECORDWIDGET_H +#define CRECORDWIDGET_H + +#include +#include "db_api_ex/CDbApi.h" +#include "ShiftCommon.h" + +namespace Ui { +class CRecordWidget; +} + +class CRecordWidget : public QDialog +{ + Q_OBJECT + +public: + explicit CRecordWidget(QWidget *parent = 0, kbd_dbms::CDbApi *dbRead = NULL, kbd_dbms::CDbApi *dbWrite = NULL); + ~CRecordWidget(); + void Init(); + +private slots: + void on_SaveButton_clicked(); + +private: + Ui::CRecordWidget *ui; + + kbd_dbms::CDbApi *m_pReadDb; + kbd_dbms::CDbApi *m_pWriteDb; + std::vector Records; +}; + +#endif // CRECORDWIDGET_H diff --git a/product/src/gui/plugin/ShiftWidget/CRecordWidget.ui b/product/src/gui/plugin/ShiftWidget/CRecordWidget.ui index 1d52953c..8aa8018c 100644 --- a/product/src/gui/plugin/ShiftWidget/CRecordWidget.ui +++ b/product/src/gui/plugin/ShiftWidget/CRecordWidget.ui @@ -1,170 +1,170 @@ - - - CRecordWidget - - - - 0 - 0 - 914 - 518 - - - - 处理问题 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - 上班遗留问题 - - - - - - - Qt::Horizontal - - - - 129 - 20 - - - - - - - - 当班处理问题 - - - - - - - Qt::Horizontal - - - - 123 - 20 - - - - - - - - 当班遗留问题 - - - - - - - Qt::Horizontal - - - - 129 - 20 - - - - - - - - 关键信息备注 - - - - - - - Qt::Horizontal - - - - 129 - 20 - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 417 - 20 - - - - - - - - 保存 - - - - - - - Qt::Horizontal - - - - 384 - 20 - - - - - - - - - - - - + + + CRecordWidget + + + + 0 + 0 + 914 + 518 + + + + 处理问题 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 上班遗留问题 + + + + + + + Qt::Horizontal + + + + 129 + 20 + + + + + + + + 当班处理问题 + + + + + + + Qt::Horizontal + + + + 123 + 20 + + + + + + + + 当班遗留问题 + + + + + + + Qt::Horizontal + + + + 129 + 20 + + + + + + + + 关键信息备注 + + + + + + + Qt::Horizontal + + + + 129 + 20 + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 417 + 20 + + + + + + + + 保存 + + + + + + + Qt::Horizontal + + + + 384 + 20 + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.cpp b/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.cpp index 565f1a19..4b2aed26 100644 --- a/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.cpp +++ b/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CShiftPluginWidget.h" -#include "CShiftWidget.h" - -CShiftPluginWidget::CShiftPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CShiftPluginWidget::~CShiftPluginWidget() -{ - -} - -bool CShiftPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **ShiftWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CShiftWidget *pWidget = new CShiftWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *ShiftWidget = (IPluginWidget *)pWidget; - return true; -} - -void CShiftPluginWidget::release() -{ - -} +#include "CShiftPluginWidget.h" +#include "CShiftWidget.h" + +CShiftPluginWidget::CShiftPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CShiftPluginWidget::~CShiftPluginWidget() +{ + +} + +bool CShiftPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **ShiftWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CShiftWidget *pWidget = new CShiftWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *ShiftWidget = (IPluginWidget *)pWidget; + return true; +} + +void CShiftPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.h b/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.h index 6d5be129..6b323688 100644 --- a/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.h +++ b/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.h @@ -1,19 +1,19 @@ -#ifndef CSHIFTPLUGINWIDGET_H -#define CSHIFTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape -class CShiftPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CShiftPluginWidget(QObject *parent = 0); - ~CShiftPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **ShiftWidget, QVector ptrVec); - void release(); -}; - -#endif // CSHIFTPLUGINWIDGET_H +#ifndef CSHIFTPLUGINWIDGET_H +#define CSHIFTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape +class CShiftPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CShiftPluginWidget(QObject *parent = 0); + ~CShiftPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **ShiftWidget, QVector ptrVec); + void release(); +}; + +#endif // CSHIFTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/ShiftWidget/CShiftWidget.cpp b/product/src/gui/plugin/ShiftWidget/CShiftWidget.cpp index 44c8f0bd..f1433d2c 100644 --- a/product/src/gui/plugin/ShiftWidget/CShiftWidget.cpp +++ b/product/src/gui/plugin/ShiftWidget/CShiftWidget.cpp @@ -1,577 +1,577 @@ -#include "CShiftWidget.h" -#include "ui_CShiftWidget.h" -#include -#include -#include -#include -#include -#include "pub_utility_api/FileStyle.h" -//using namespace kbd_dbms; - -CShiftWidget::CShiftWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CShiftWidget), - m_isEditMode(editMode), - m_pReadDb(Q_NULLPTR), - m_pWriteDb(Q_NULLPTR) -{ - ui->setupUi(this); - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("shift.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - if(!m_isEditMode) - { - ui->lineEdit->setReadOnly(true); - - InitDb(); - InitData(); - InitTableWidget(); - - m_timeIcon = new QPushButton(this); - m_myCalendar = new CMyCalendar(this); - QWidgetAction *widgetAction=new QWidgetAction(this); - m_timeMenu = new QMenu(this); - widgetAction->setDefaultWidget(m_myCalendar); - m_timeMenu->addAction(widgetAction); - m_timeIcon->setObjectName("iconButton"); - m_timeIcon->setText(""); - m_timeIcon->setMaximumSize(21, 22); - m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); - QHBoxLayout * pTimeLayout = new QHBoxLayout(); - pTimeLayout->setContentsMargins(1, 1, 1, 1); - pTimeLayout->addStretch(); - pTimeLayout->addWidget(m_timeIcon); - ui->DateTimeEdit->setLayout(pTimeLayout); - connect(m_timeIcon,&QPushButton::clicked,this,&CShiftWidget::myCalendarShow); - connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CShiftWidget::myCalendarHide); - connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CShiftWidget::cancleTimeFilter); - ui->DateTimeEdit->setReadOnly(true); - ui->DateTimeEdit->setObjectName("iconLineEdit"); - - myCalendarHide(QDate::currentDate(),QDate::currentDate()); - m_start=QDate::currentDate(); - m_end=QDate::currentDate(); - on_QueryButton_clicked(); - } -} - -CShiftWidget::~CShiftWidget() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - m_pReadDb=NULL; - } - if(m_pWriteDb) - { - m_pWriteDb->close(); - delete m_pWriteDb; - m_pWriteDb=NULL; - } - delete ui; -} - -void CShiftWidget::InitDb() -{ - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); - m_pReadDb->open(); - - m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); - m_pWriteDb->open(); -} - -void CShiftWidget::InitData() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QString strSql; - QSqlQuery objRet; - - m_Users.clear(); - RM_USER_DEF User; - strSql = "select PERM_ID,PERM_NAME,PERM_ALIAS from rm_user_def"; - m_pReadDb->execute(strSql,objRet); - ui->comboBox->clear(); - ui->comboBox->addItem("所有"); - if(objRet.isActive()) - { - while(objRet.next()) - { - User.PERM_ID=objRet.value(0).toInt(); - User.PERM_NAME=objRet.value(1).toString().toStdString(); - User.PERM_ALIAS=objRet.value(2).toString().toStdString(); - m_Users.push_back(User); - if(objRet.value(0).toInt() > 10) - { - ui->comboBox->addItem(User.PERM_ALIAS.c_str()); - } - } - } - - m_Groups.clear(); - DUTY_DEFINE Group; - strSql = "select ID,NAME,START_TIME,END_TIME from duty_define"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Group.ID=objRet.value(0).toInt(); - Group.NAME=objRet.value(1).toString().toStdString(); - Group.START_TIME=objRet.value(2).toString().toStdString(); - Group.END_TIME=objRet.value(3).toString().toStdString(); - m_Groups.push_back(Group); - } - } - - QString str=QDate::currentDate().toString("yyyy-MM-dd"); - m_Date_Groups.clear(); - DUTY_SETTING Date_Group; - strSql = "select DATE,DUTY_DEFINE_ID,USERS from duty_setting where USERS!='' and DATE='"+str+"'"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Date_Group.DATE=objRet.value(0).toString().toStdString(); - Date_Group.DUTY_DEFINE_ID=objRet.value(1).toInt(); - Date_Group.USERS=objRet.value(2).toString().toStdString(); - m_Date_Groups.push_back(Date_Group); - } - } - - for(size_t i=0;iexecute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Record.ID=objRet.value(0).toInt(); - Record.GROUP_NAME=objRet.value(1).toString().toStdString(); - Record.USERS=objRet.value(2).toString().toStdString(); - Record.USERS_STATUS=objRet.value(3).toString().toStdString(); - Record.START_TIME=objRet.value(4).toString().toStdString(); - Record.END_TIME=objRet.value(5).toString().toStdString(); - Record.NOTE1=objRet.value(6).toString().toStdString(); - Record.NOTE2=objRet.value(7).toString().toStdString(); - Record.NOTE3=objRet.value(8).toString().toStdString(); - Records.push_back(Record); - } - } - if(Records.size()>0) - { - ui->SelectGroupBox->setVisible(false); - ui->lineEdit->setText(Records.at(0).GROUP_NAME.c_str()); - } - else - { - ui->lineEdit->setVisible(false); - ui->SelectGroupBox->clear(); - ui->SelectGroupBox->addItem("请选择当前班组"); - for(size_t i=0;iSelectGroupBox->addItem(m_Date_Groups.at(i).NAME.c_str()); - } - } -} - -void CShiftWidget::InitTableWidget() -{ - ui->TableWidget->setColumnCount(6); - QStringList header; - header<<"序号"<<"班次"<<"值班员"<<"接班时间"<<"交班时间"<<"操作"; - ui->TableWidget->setHorizontalHeaderLabels(header); - ui->TableWidget->verticalHeader()->setVisible(false); - ui->TableWidget->horizontalHeader()->setStretchLastSection(true); - ui->TableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->TableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->TableWidget->setFocusPolicy(Qt::NoFocus); - ui->TableWidget->setColumnWidth(0,50); - ui->TableWidget->setColumnWidth(1,150); - ui->TableWidget->setColumnWidth(2,350); - ui->TableWidget->setColumnWidth(3,200); - ui->TableWidget->setColumnWidth(4,200); - //ui->TableWidget->setColumnWidth(5,50); -} - -void CShiftWidget::AddFirstRecord() -{ - if(!m_pWriteDb->isOpen()) - { - return; - } - for(size_t i=0;iSelectGroupBox->currentText()==m_Date_Groups.at(i).NAME.c_str()) - { - QString strSql; - QString Now_time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); - QString strlist=m_Date_Groups.at(i).USERS.c_str(); - QStringList list_alias=strlist.split(","); - QString Users=""; - for(int x=0;xSelectGroupBox->currentText()+"','"+Users+"','"+Name+"','"+Now_time+"')"; - - if(!m_pWriteDb->execute(strSql)) - { - QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); - } - } - } - InitData(); -} - -void CShiftWidget::on_HandoverButton_clicked() -{ - if(m_Groups.size()==0||m_Date_Groups.size()==0) - { - QMessageBox::critical(this,"提示","请进行排班以后再操作"); - return; - } - - if(ui->SelectGroupBox->isVisible()==true&&ui->SelectGroupBox->currentIndex()==0) - { - QMessageBox::critical(this,"提示","请选择当前班组"); - return; - } - - if(Records.size()==0) - { - AddFirstRecord(); - ui->SelectGroupBox->setVisible(false); - ui->lineEdit->setVisible(true); - ui->lineEdit->setText(ui->SelectGroupBox->currentText()); - } - - HandoverWidget dlg(this,m_pReadDb,m_pWriteDb); - dlg.exec(); - InitData(); - - //myCalendarHide(m_start,m_end); - on_QueryButton_clicked(); - -} - -void CShiftWidget::on_FillRecordButton_clicked() -{ - if(m_Groups.size()==0||m_Date_Groups.size()==0) - { - QMessageBox::critical(this,"提示","请进行排班以后再操作"); - return; - } - - if(ui->SelectGroupBox->isVisible()==true&&ui->SelectGroupBox->currentIndex()==0) - { - QMessageBox::critical(this,"提示","请选择当前班组"); - return; - } - - if(Records.size()==0) - { - AddFirstRecord(); - ui->SelectGroupBox->setVisible(false); - ui->lineEdit->setVisible(true); - ui->lineEdit->setText(ui->SelectGroupBox->currentText()); - } - - CRecordWidget dlg(this,m_pReadDb,m_pWriteDb); - dlg.exec(); -} - -void CShiftWidget::on_comboBox_currentIndexChanged(const QString &arg1) -{ - ui->TableWidget->setRowCount(0); - for(size_t i=0;icomboBox->currentIndex()>0&&Name.indexOf(arg1)==-1) - continue; - ui->TableWidget->insertRow(0); - ui->TableWidget->setItem(0,0,new QTableWidgetItem(QString::number(Records_Inquire.size()-i,10))); - ui->TableWidget->setItem(0,1,new QTableWidgetItem(Records_Inquire.at(i).GROUP_NAME.c_str())); - ui->TableWidget->setItem(0,2,new QTableWidgetItem(Records_Inquire.at(i).USERS.c_str())); - ui->TableWidget->setItem(0,3,new QTableWidgetItem(Records_Inquire.at(i).START_TIME.c_str())); - ui->TableWidget->setItem(0,4,new QTableWidgetItem(Records_Inquire.at(i).END_TIME.c_str())); - ui->TableWidget->setItem(0,5,new QTableWidgetItem("详细")); - QFont font; - font.setUnderline(true); - ui->TableWidget->item(0,5)->setFont(font); - ui->TableWidget->item(0,0)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,1)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,2)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,3)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,4)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,5)->setTextAlignment(Qt::AlignCenter); - } -} - -void CShiftWidget::on_TableWidget_cellClicked(int row, int column) -{ - if(row>-1&&column==5) - { - HandoverWidget dlg(this,m_pReadDb,m_pWriteDb,false,ui->TableWidget->item(row,3)->text()); - dlg.exec(); - } -} - -void CShiftWidget::on_ReportButton_clicked() -{ - if(ui->TableWidget->rowCount()<0) - { - QMessageBox::critical(this,"提示","没有记录,无法导出"); - return; - } - if(!m_pReadDb->isOpen()) - { - return; - } - QString strExcelName = QString("Shift(%1~%2).xlsx") - .arg(m_start.toString("yyyyMMdd")) - .arg(m_end.toString("yyyyMMdd")); - QString fileName=QFileDialog::getSaveFileName(this,tr("保存"),strExcelName,"Excel 文件(*.xlsx)");//获取保存路径*.xls - if(!fileName.isEmpty()) - { - QString sExcelFileName = fileName; - QXlsx::Document xlsx; - xlsx.addSheet( "交接班记录" ); - - // 写横向表头 - QStringList header; - header<TableWidget->rowCount(); - int colcount=ui->TableWidget->columnCount()-1; - - // 写内容 - for ( int i=0; iTableWidget->item(i,3)->text()+"'"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Record.ID=objRet.value(0).toInt(); - Record.GROUP_NAME=objRet.value(1).toString().toStdString(); - Record.USERS=objRet.value(2).toString().toStdString(); - Record.USERS_STATUS=objRet.value(3).toString().toStdString(); - Record.START_TIME=objRet.value(4).toString().toStdString(); - Record.END_TIME=objRet.value(5).toString().toStdString(); - Record.NOTE1=objRet.value(6).toString().toStdString(); - Record.NOTE2=objRet.value(7).toString().toStdString(); - Record.NOTE3=objRet.value(8).toString().toStdString(); - } - } - for (int j=0;jTableWidget->item(i,j)->text(); - xlsx.write( i+2, j+1, sText ); - } - xlsx.write( i+2, colcount+1, Record.NOTE1.c_str() ); - xlsx.write( i+2, colcount+2, Record.NOTE2.c_str() ); - xlsx.write( i+2, colcount+3, Record.NOTE3.c_str() ); - } - - // 保存到文件 - xlsx.saveAs( sExcelFileName ); - - // 提示导出路径 - QMessageBox::information( 0, "提示", "导出完成\n文件为:"+sExcelFileName); - } -} - -void CShiftWidget::myCalendarHide(QDate startTime, QDate endTime) -{ - m_start=startTime; - m_end=endTime; - - m_timeMenu->hide(); - //ui->comboBox->setCurrentIndex(0); - ui->DateTimeEdit->setText(startTime.toString("yyyy-MM-dd") +" ~ "+endTime.toString("yyyy-MM-dd")); - //开始查询 - /*Records_Inquire.clear(); - - QString strSql; - QSqlQuery objRet; - - DUTY_INFO Record; - strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where START_TIME>='" - +startTime.toString("yyyy-MM-dd 00:00:00")+"' and END_TIME<'"+endTime.addDays(1).toString("yyyy-MM-dd 00:00:00")+"'"; - m_DbInterface->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Record.ID=objRet.value(0).toInt(); - Record.GROUP_NAME=objRet.value(1).toString().toStdString(); - Record.USERS=objRet.value(2).toString().toStdString(); - Record.USERS_STATUS=objRet.value(3).toString().toStdString(); - Record.START_TIME=objRet.value(4).toString().toStdString(); - Record.END_TIME=objRet.value(5).toString().toStdString(); - Record.NOTE1=objRet.value(6).toString().toStdString(); - Record.NOTE2=objRet.value(7).toString().toStdString(); - Record.NOTE3=objRet.value(8).toString().toStdString(); - Records_Inquire.push_back(Record); - } - } - ui->TableWidget->setRowCount(0); - for(int i=0;iTableWidget->insertRow(0); - ui->TableWidget->setItem(0,0,new QTableWidgetItem(QString::number(Records_Inquire.size()-i,10))); - ui->TableWidget->setItem(0,1,new QTableWidgetItem(Records_Inquire.at(i).GROUP_NAME.c_str())); - ui->TableWidget->setItem(0,2,new QTableWidgetItem(Records_Inquire.at(i).USERS.c_str())); - ui->TableWidget->setItem(0,3,new QTableWidgetItem(Records_Inquire.at(i).START_TIME.c_str())); - ui->TableWidget->setItem(0,4,new QTableWidgetItem(Records_Inquire.at(i).END_TIME.c_str())); - ui->TableWidget->setItem(0,5,new QTableWidgetItem("详细")); - QFont font; - font.setUnderline(true); - ui->TableWidget->item(0,5)->setFont(font); - ui->TableWidget->item(0,0)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,1)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,2)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,3)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,4)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,5)->setTextAlignment(Qt::AlignCenter); - }*/ -} - -void CShiftWidget::myCalendarShow() -{ - QPoint point(QCursor::pos().x()-200,QCursor::pos().y()+15); - m_timeMenu->move(point); - m_timeMenu->show(); -} - -void CShiftWidget::cancleTimeFilter() -{ - m_timeMenu->hide(); -} - -void CShiftWidget::on_QueryButton_clicked() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - ui->comboBox->setCurrentIndex(0); - Records_Inquire.clear(); - - QString strSql; - QSqlQuery objRet; - - DUTY_INFO Record; - strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where END_TIME>='" - +m_start.toString("yyyy-MM-dd 00:00:00")+"' and END_TIME<='"+m_end.addDays(1).toString("yyyy-MM-dd 00:00:00")+"'"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Record.ID=objRet.value(0).toInt(); - Record.GROUP_NAME=objRet.value(1).toString().toStdString(); - Record.USERS=objRet.value(2).toString().toStdString(); - Record.USERS_STATUS=objRet.value(3).toString().toStdString(); - Record.START_TIME=objRet.value(4).toString().toStdString(); - Record.END_TIME=objRet.value(5).toString().toStdString(); - Record.NOTE1=objRet.value(6).toString().toStdString(); - Record.NOTE2=objRet.value(7).toString().toStdString(); - Record.NOTE3=objRet.value(8).toString().toStdString(); - Records_Inquire.push_back(Record); - } - } - ui->TableWidget->setRowCount(0); - for(size_t i=0;iTableWidget->insertRow(0); - ui->TableWidget->setItem(0,0,new QTableWidgetItem(QString::number(Records_Inquire.size()-i,10))); - ui->TableWidget->setItem(0,1,new QTableWidgetItem(Records_Inquire.at(i).GROUP_NAME.c_str())); - ui->TableWidget->setItem(0,2,new QTableWidgetItem(Records_Inquire.at(i).USERS.c_str())); - ui->TableWidget->setItem(0,3,new QTableWidgetItem(Records_Inquire.at(i).START_TIME.c_str())); - ui->TableWidget->setItem(0,4,new QTableWidgetItem(Records_Inquire.at(i).END_TIME.c_str())); - ui->TableWidget->setItem(0,5,new QTableWidgetItem("详细")); - QFont font; - font.setUnderline(true); - ui->TableWidget->item(0,5)->setFont(font); - ui->TableWidget->item(0,0)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,1)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,2)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,3)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,4)->setTextAlignment(Qt::AlignCenter); - ui->TableWidget->item(0,5)->setTextAlignment(Qt::AlignCenter); - } -} +#include "CShiftWidget.h" +#include "ui_CShiftWidget.h" +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" +//using namespace kbd_dbms; + +CShiftWidget::CShiftWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CShiftWidget), + m_isEditMode(editMode), + m_pReadDb(Q_NULLPTR), + m_pWriteDb(Q_NULLPTR) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("shift.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + if(!m_isEditMode) + { + ui->lineEdit->setReadOnly(true); + + InitDb(); + InitData(); + InitTableWidget(); + + m_timeIcon = new QPushButton(this); + m_myCalendar = new CMyCalendar(this); + QWidgetAction *widgetAction=new QWidgetAction(this); + m_timeMenu = new QMenu(this); + widgetAction->setDefaultWidget(m_myCalendar); + m_timeMenu->addAction(widgetAction); + m_timeIcon->setObjectName("iconButton"); + m_timeIcon->setText(""); + m_timeIcon->setMaximumSize(21, 22); + m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_timeIcon); + ui->DateTimeEdit->setLayout(pTimeLayout); + connect(m_timeIcon,&QPushButton::clicked,this,&CShiftWidget::myCalendarShow); + connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CShiftWidget::myCalendarHide); + connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CShiftWidget::cancleTimeFilter); + ui->DateTimeEdit->setReadOnly(true); + ui->DateTimeEdit->setObjectName("iconLineEdit"); + + myCalendarHide(QDate::currentDate(),QDate::currentDate()); + m_start=QDate::currentDate(); + m_end=QDate::currentDate(); + on_QueryButton_clicked(); + } +} + +CShiftWidget::~CShiftWidget() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + m_pReadDb=NULL; + } + if(m_pWriteDb) + { + m_pWriteDb->close(); + delete m_pWriteDb; + m_pWriteDb=NULL; + } + delete ui; +} + +void CShiftWidget::InitDb() +{ + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + m_pWriteDb = new kbd_dbms::CDbApi(DB_CONN_MODEL_WRITE); + m_pWriteDb->open(); +} + +void CShiftWidget::InitData() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QString strSql; + QSqlQuery objRet; + + m_Users.clear(); + RM_USER_DEF User; + strSql = "select PERM_ID,PERM_NAME,PERM_ALIAS from rm_user_def"; + m_pReadDb->execute(strSql,objRet); + ui->comboBox->clear(); + ui->comboBox->addItem("所有"); + if(objRet.isActive()) + { + while(objRet.next()) + { + User.PERM_ID=objRet.value(0).toInt(); + User.PERM_NAME=objRet.value(1).toString().toStdString(); + User.PERM_ALIAS=objRet.value(2).toString().toStdString(); + m_Users.push_back(User); + if(objRet.value(0).toInt() > 10) + { + ui->comboBox->addItem(User.PERM_ALIAS.c_str()); + } + } + } + + m_Groups.clear(); + DUTY_DEFINE Group; + strSql = "select ID,NAME,START_TIME,END_TIME from duty_define"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Group.ID=objRet.value(0).toInt(); + Group.NAME=objRet.value(1).toString().toStdString(); + Group.START_TIME=objRet.value(2).toString().toStdString(); + Group.END_TIME=objRet.value(3).toString().toStdString(); + m_Groups.push_back(Group); + } + } + + QString str=QDate::currentDate().toString("yyyy-MM-dd"); + m_Date_Groups.clear(); + DUTY_SETTING Date_Group; + strSql = "select DATE,DUTY_DEFINE_ID,USERS from duty_setting where USERS!='' and DATE='"+str+"'"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Date_Group.DATE=objRet.value(0).toString().toStdString(); + Date_Group.DUTY_DEFINE_ID=objRet.value(1).toInt(); + Date_Group.USERS=objRet.value(2).toString().toStdString(); + m_Date_Groups.push_back(Date_Group); + } + } + + for(size_t i=0;iexecute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Record.ID=objRet.value(0).toInt(); + Record.GROUP_NAME=objRet.value(1).toString().toStdString(); + Record.USERS=objRet.value(2).toString().toStdString(); + Record.USERS_STATUS=objRet.value(3).toString().toStdString(); + Record.START_TIME=objRet.value(4).toString().toStdString(); + Record.END_TIME=objRet.value(5).toString().toStdString(); + Record.NOTE1=objRet.value(6).toString().toStdString(); + Record.NOTE2=objRet.value(7).toString().toStdString(); + Record.NOTE3=objRet.value(8).toString().toStdString(); + Records.push_back(Record); + } + } + if(Records.size()>0) + { + ui->SelectGroupBox->setVisible(false); + ui->lineEdit->setText(Records.at(0).GROUP_NAME.c_str()); + } + else + { + ui->lineEdit->setVisible(false); + ui->SelectGroupBox->clear(); + ui->SelectGroupBox->addItem("请选择当前班组"); + for(size_t i=0;iSelectGroupBox->addItem(m_Date_Groups.at(i).NAME.c_str()); + } + } +} + +void CShiftWidget::InitTableWidget() +{ + ui->TableWidget->setColumnCount(6); + QStringList header; + header<<"序号"<<"班次"<<"值班员"<<"接班时间"<<"交班时间"<<"操作"; + ui->TableWidget->setHorizontalHeaderLabels(header); + ui->TableWidget->verticalHeader()->setVisible(false); + ui->TableWidget->horizontalHeader()->setStretchLastSection(true); + ui->TableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->TableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->TableWidget->setFocusPolicy(Qt::NoFocus); + ui->TableWidget->setColumnWidth(0,50); + ui->TableWidget->setColumnWidth(1,150); + ui->TableWidget->setColumnWidth(2,350); + ui->TableWidget->setColumnWidth(3,200); + ui->TableWidget->setColumnWidth(4,200); + //ui->TableWidget->setColumnWidth(5,50); +} + +void CShiftWidget::AddFirstRecord() +{ + if(!m_pWriteDb->isOpen()) + { + return; + } + for(size_t i=0;iSelectGroupBox->currentText()==m_Date_Groups.at(i).NAME.c_str()) + { + QString strSql; + QString Now_time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + QString strlist=m_Date_Groups.at(i).USERS.c_str(); + QStringList list_alias=strlist.split(","); + QString Users=""; + for(int x=0;xSelectGroupBox->currentText()+"','"+Users+"','"+Name+"','"+Now_time+"')"; + + if(!m_pWriteDb->execute(strSql)) + { + QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); + } + } + } + InitData(); +} + +void CShiftWidget::on_HandoverButton_clicked() +{ + if(m_Groups.size()==0||m_Date_Groups.size()==0) + { + QMessageBox::critical(this,"提示","请进行排班以后再操作"); + return; + } + + if(ui->SelectGroupBox->isVisible()==true&&ui->SelectGroupBox->currentIndex()==0) + { + QMessageBox::critical(this,"提示","请选择当前班组"); + return; + } + + if(Records.size()==0) + { + AddFirstRecord(); + ui->SelectGroupBox->setVisible(false); + ui->lineEdit->setVisible(true); + ui->lineEdit->setText(ui->SelectGroupBox->currentText()); + } + + HandoverWidget dlg(this,m_pReadDb,m_pWriteDb); + dlg.exec(); + InitData(); + + //myCalendarHide(m_start,m_end); + on_QueryButton_clicked(); + +} + +void CShiftWidget::on_FillRecordButton_clicked() +{ + if(m_Groups.size()==0||m_Date_Groups.size()==0) + { + QMessageBox::critical(this,"提示","请进行排班以后再操作"); + return; + } + + if(ui->SelectGroupBox->isVisible()==true&&ui->SelectGroupBox->currentIndex()==0) + { + QMessageBox::critical(this,"提示","请选择当前班组"); + return; + } + + if(Records.size()==0) + { + AddFirstRecord(); + ui->SelectGroupBox->setVisible(false); + ui->lineEdit->setVisible(true); + ui->lineEdit->setText(ui->SelectGroupBox->currentText()); + } + + CRecordWidget dlg(this,m_pReadDb,m_pWriteDb); + dlg.exec(); +} + +void CShiftWidget::on_comboBox_currentIndexChanged(const QString &arg1) +{ + ui->TableWidget->setRowCount(0); + for(size_t i=0;icomboBox->currentIndex()>0&&Name.indexOf(arg1)==-1) + continue; + ui->TableWidget->insertRow(0); + ui->TableWidget->setItem(0,0,new QTableWidgetItem(QString::number(Records_Inquire.size()-i,10))); + ui->TableWidget->setItem(0,1,new QTableWidgetItem(Records_Inquire.at(i).GROUP_NAME.c_str())); + ui->TableWidget->setItem(0,2,new QTableWidgetItem(Records_Inquire.at(i).USERS.c_str())); + ui->TableWidget->setItem(0,3,new QTableWidgetItem(Records_Inquire.at(i).START_TIME.c_str())); + ui->TableWidget->setItem(0,4,new QTableWidgetItem(Records_Inquire.at(i).END_TIME.c_str())); + ui->TableWidget->setItem(0,5,new QTableWidgetItem("详细")); + QFont font; + font.setUnderline(true); + ui->TableWidget->item(0,5)->setFont(font); + ui->TableWidget->item(0,0)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,1)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,2)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,3)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,4)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,5)->setTextAlignment(Qt::AlignCenter); + } +} + +void CShiftWidget::on_TableWidget_cellClicked(int row, int column) +{ + if(row>-1&&column==5) + { + HandoverWidget dlg(this,m_pReadDb,m_pWriteDb,false,ui->TableWidget->item(row,3)->text()); + dlg.exec(); + } +} + +void CShiftWidget::on_ReportButton_clicked() +{ + if(ui->TableWidget->rowCount()<0) + { + QMessageBox::critical(this,"提示","没有记录,无法导出"); + return; + } + if(!m_pReadDb->isOpen()) + { + return; + } + QString strExcelName = QString("Shift(%1~%2).xlsx") + .arg(m_start.toString("yyyyMMdd")) + .arg(m_end.toString("yyyyMMdd")); + QString fileName=QFileDialog::getSaveFileName(this,tr("保存"),strExcelName,"Excel 文件(*.xlsx)");//获取保存路径*.xls + if(!fileName.isEmpty()) + { + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "交接班记录" ); + + // 写横向表头 + QStringList header; + header<TableWidget->rowCount(); + int colcount=ui->TableWidget->columnCount()-1; + + // 写内容 + for ( int i=0; iTableWidget->item(i,3)->text()+"'"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Record.ID=objRet.value(0).toInt(); + Record.GROUP_NAME=objRet.value(1).toString().toStdString(); + Record.USERS=objRet.value(2).toString().toStdString(); + Record.USERS_STATUS=objRet.value(3).toString().toStdString(); + Record.START_TIME=objRet.value(4).toString().toStdString(); + Record.END_TIME=objRet.value(5).toString().toStdString(); + Record.NOTE1=objRet.value(6).toString().toStdString(); + Record.NOTE2=objRet.value(7).toString().toStdString(); + Record.NOTE3=objRet.value(8).toString().toStdString(); + } + } + for (int j=0;jTableWidget->item(i,j)->text(); + xlsx.write( i+2, j+1, sText ); + } + xlsx.write( i+2, colcount+1, Record.NOTE1.c_str() ); + xlsx.write( i+2, colcount+2, Record.NOTE2.c_str() ); + xlsx.write( i+2, colcount+3, Record.NOTE3.c_str() ); + } + + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + + // 提示导出路径 + QMessageBox::information( 0, "提示", "导出完成\n文件为:"+sExcelFileName); + } +} + +void CShiftWidget::myCalendarHide(QDate startTime, QDate endTime) +{ + m_start=startTime; + m_end=endTime; + + m_timeMenu->hide(); + //ui->comboBox->setCurrentIndex(0); + ui->DateTimeEdit->setText(startTime.toString("yyyy-MM-dd") +" ~ "+endTime.toString("yyyy-MM-dd")); + //开始查询 + /*Records_Inquire.clear(); + + QString strSql; + QSqlQuery objRet; + + DUTY_INFO Record; + strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where START_TIME>='" + +startTime.toString("yyyy-MM-dd 00:00:00")+"' and END_TIME<'"+endTime.addDays(1).toString("yyyy-MM-dd 00:00:00")+"'"; + m_DbInterface->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Record.ID=objRet.value(0).toInt(); + Record.GROUP_NAME=objRet.value(1).toString().toStdString(); + Record.USERS=objRet.value(2).toString().toStdString(); + Record.USERS_STATUS=objRet.value(3).toString().toStdString(); + Record.START_TIME=objRet.value(4).toString().toStdString(); + Record.END_TIME=objRet.value(5).toString().toStdString(); + Record.NOTE1=objRet.value(6).toString().toStdString(); + Record.NOTE2=objRet.value(7).toString().toStdString(); + Record.NOTE3=objRet.value(8).toString().toStdString(); + Records_Inquire.push_back(Record); + } + } + ui->TableWidget->setRowCount(0); + for(int i=0;iTableWidget->insertRow(0); + ui->TableWidget->setItem(0,0,new QTableWidgetItem(QString::number(Records_Inquire.size()-i,10))); + ui->TableWidget->setItem(0,1,new QTableWidgetItem(Records_Inquire.at(i).GROUP_NAME.c_str())); + ui->TableWidget->setItem(0,2,new QTableWidgetItem(Records_Inquire.at(i).USERS.c_str())); + ui->TableWidget->setItem(0,3,new QTableWidgetItem(Records_Inquire.at(i).START_TIME.c_str())); + ui->TableWidget->setItem(0,4,new QTableWidgetItem(Records_Inquire.at(i).END_TIME.c_str())); + ui->TableWidget->setItem(0,5,new QTableWidgetItem("详细")); + QFont font; + font.setUnderline(true); + ui->TableWidget->item(0,5)->setFont(font); + ui->TableWidget->item(0,0)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,1)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,2)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,3)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,4)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,5)->setTextAlignment(Qt::AlignCenter); + }*/ +} + +void CShiftWidget::myCalendarShow() +{ + QPoint point(QCursor::pos().x()-200,QCursor::pos().y()+15); + m_timeMenu->move(point); + m_timeMenu->show(); +} + +void CShiftWidget::cancleTimeFilter() +{ + m_timeMenu->hide(); +} + +void CShiftWidget::on_QueryButton_clicked() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + ui->comboBox->setCurrentIndex(0); + Records_Inquire.clear(); + + QString strSql; + QSqlQuery objRet; + + DUTY_INFO Record; + strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where END_TIME>='" + +m_start.toString("yyyy-MM-dd 00:00:00")+"' and END_TIME<='"+m_end.addDays(1).toString("yyyy-MM-dd 00:00:00")+"'"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Record.ID=objRet.value(0).toInt(); + Record.GROUP_NAME=objRet.value(1).toString().toStdString(); + Record.USERS=objRet.value(2).toString().toStdString(); + Record.USERS_STATUS=objRet.value(3).toString().toStdString(); + Record.START_TIME=objRet.value(4).toString().toStdString(); + Record.END_TIME=objRet.value(5).toString().toStdString(); + Record.NOTE1=objRet.value(6).toString().toStdString(); + Record.NOTE2=objRet.value(7).toString().toStdString(); + Record.NOTE3=objRet.value(8).toString().toStdString(); + Records_Inquire.push_back(Record); + } + } + ui->TableWidget->setRowCount(0); + for(size_t i=0;iTableWidget->insertRow(0); + ui->TableWidget->setItem(0,0,new QTableWidgetItem(QString::number(Records_Inquire.size()-i,10))); + ui->TableWidget->setItem(0,1,new QTableWidgetItem(Records_Inquire.at(i).GROUP_NAME.c_str())); + ui->TableWidget->setItem(0,2,new QTableWidgetItem(Records_Inquire.at(i).USERS.c_str())); + ui->TableWidget->setItem(0,3,new QTableWidgetItem(Records_Inquire.at(i).START_TIME.c_str())); + ui->TableWidget->setItem(0,4,new QTableWidgetItem(Records_Inquire.at(i).END_TIME.c_str())); + ui->TableWidget->setItem(0,5,new QTableWidgetItem("详细")); + QFont font; + font.setUnderline(true); + ui->TableWidget->item(0,5)->setFont(font); + ui->TableWidget->item(0,0)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,1)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,2)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,3)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,4)->setTextAlignment(Qt::AlignCenter); + ui->TableWidget->item(0,5)->setTextAlignment(Qt::AlignCenter); + } +} diff --git a/product/src/gui/plugin/ShiftWidget/CShiftWidget.h b/product/src/gui/plugin/ShiftWidget/CShiftWidget.h index f97968f4..1dd68196 100644 --- a/product/src/gui/plugin/ShiftWidget/CShiftWidget.h +++ b/product/src/gui/plugin/ShiftWidget/CShiftWidget.h @@ -1,69 +1,69 @@ -#ifndef CSHIFTWIDGET_H -#define CSHIFTWIDGET_H - -#include -#include "db_api_ex/CDbApi.h" -#include "HandoverWidget.h" -#include "ShiftCommon.h" -#include "CRecordWidget.h" -#include "CMyCalendar.h" -#include "model_excel/xlsx/xlsxdocument.h" - -namespace Ui { -class CShiftWidget; -} - -class CShiftWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CShiftWidget(QWidget *parent = 0, bool editMode = false); - ~CShiftWidget(); - - void InitDb(); - void InitData(); - void InitTableWidget(); - void AddFirstRecord(); - -private slots: - void on_HandoverButton_clicked(); - - void on_FillRecordButton_clicked(); - - void on_comboBox_currentIndexChanged(const QString &arg1); - - void on_TableWidget_cellClicked(int row, int column); - - void on_ReportButton_clicked(); - - void on_QueryButton_clicked(); - -protected slots: - void myCalendarHide(QDate startTime, QDate endTime); - void myCalendarShow(); - void cancleTimeFilter(); - - -private: - Ui::CShiftWidget *ui; - - bool m_isEditMode; - - kbd_dbms::CDbApi *m_pReadDb; - kbd_dbms::CDbApi *m_pWriteDb; - - std::vector Records; - std::vector Records_Inquire; - std::vector m_Groups; - std::vector m_Date_Groups; - std::vector m_Users; - - QPushButton *m_timeIcon; - CMyCalendar * m_myCalendar; - QMenu *m_timeMenu; - QDate m_start; - QDate m_end; -}; - -#endif // CSHIFTWIDGET_H +#ifndef CSHIFTWIDGET_H +#define CSHIFTWIDGET_H + +#include +#include "db_api_ex/CDbApi.h" +#include "HandoverWidget.h" +#include "ShiftCommon.h" +#include "CRecordWidget.h" +#include "CMyCalendar.h" +#include "model_excel/xlsx/xlsxdocument.h" + +namespace Ui { +class CShiftWidget; +} + +class CShiftWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CShiftWidget(QWidget *parent = 0, bool editMode = false); + ~CShiftWidget(); + + void InitDb(); + void InitData(); + void InitTableWidget(); + void AddFirstRecord(); + +private slots: + void on_HandoverButton_clicked(); + + void on_FillRecordButton_clicked(); + + void on_comboBox_currentIndexChanged(const QString &arg1); + + void on_TableWidget_cellClicked(int row, int column); + + void on_ReportButton_clicked(); + + void on_QueryButton_clicked(); + +protected slots: + void myCalendarHide(QDate startTime, QDate endTime); + void myCalendarShow(); + void cancleTimeFilter(); + + +private: + Ui::CShiftWidget *ui; + + bool m_isEditMode; + + kbd_dbms::CDbApi *m_pReadDb; + kbd_dbms::CDbApi *m_pWriteDb; + + std::vector Records; + std::vector Records_Inquire; + std::vector m_Groups; + std::vector m_Date_Groups; + std::vector m_Users; + + QPushButton *m_timeIcon; + CMyCalendar * m_myCalendar; + QMenu *m_timeMenu; + QDate m_start; + QDate m_end; +}; + +#endif // CSHIFTWIDGET_H diff --git a/product/src/gui/plugin/ShiftWidget/CShiftWidget.ui b/product/src/gui/plugin/ShiftWidget/CShiftWidget.ui index 4c58d8d5..453ec747 100644 --- a/product/src/gui/plugin/ShiftWidget/CShiftWidget.ui +++ b/product/src/gui/plugin/ShiftWidget/CShiftWidget.ui @@ -1,171 +1,171 @@ - - - CShiftWidget - - - - 0 - 0 - 1080 - 552 - - - - 交接班管理 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - 当前值班组 - - - - - - - - 100 - 16777215 - - - - - - - - - - - 填写记录 - - - - - - - 交接班 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 查询时间 - - - - - - - - 220 - 0 - - - - - 220 - 16777215 - - - - - - - - 查询 - - - - - - - 按值班员过滤 - - - - - - - - - - 导出记录 - - - - - - - - - - - - - - - - - - - - + + + CShiftWidget + + + + 0 + 0 + 1080 + 552 + + + + 交接班管理 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 当前值班组 + + + + + + + + 100 + 16777215 + + + + + + + + + + + 填写记录 + + + + + + + 交接班 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 查询时间 + + + + + + + + 220 + 0 + + + + + 220 + 16777215 + + + + + + + + 查询 + + + + + + + 按值班员过滤 + + + + + + + + + + 导出记录 + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ShiftWidget/HandoverWidget.cpp b/product/src/gui/plugin/ShiftWidget/HandoverWidget.cpp index 6aa64019..4c90cc75 100644 --- a/product/src/gui/plugin/ShiftWidget/HandoverWidget.cpp +++ b/product/src/gui/plugin/ShiftWidget/HandoverWidget.cpp @@ -1,1069 +1,1069 @@ -#include "HandoverWidget.h" -#include "ui_HandoverWidget.h" -#include -#include "QueryThread.h" -#include -#include -#include -#include "pub_utility_api/CommonConfigParse.h" -#include "Common.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_public; - -HandoverWidget::HandoverWidget(QWidget *parent,kbd_dbms::CDbApi *dbRead,kbd_dbms::CDbApi *dbWrite,bool isFarm,QString begin_time) : - QDialog(parent), - ui(new Ui::HandoverWidget), - m_pReadDb(dbRead), - m_pWriteDb(dbWrite), - m_isFarm(isFarm), - m_begin_time(begin_time) -{ - m_thread_Events = NULL; - m_thread_Events_Operates = NULL; - ui->setupUi(this); - this->setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); - Init(); - loadXml(); - if(m_isFarm==true) - { - InitFarm(); - } - else - { - InitNoFarm(); - } - InitData(); -} - -HandoverWidget::~HandoverWidget() -{ - delete ui; -} - -void HandoverWidget::Init() -{ - if(!m_pReadDb || !m_pReadDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - close(); - } - QString strSql; - QSqlQuery objRet; - - m_Users.clear(); - RM_USER_DEF User; - strSql = "select PERM_ID,PERM_NAME,PERM_ALIAS from rm_user_def"; - m_pReadDb->execute(strSql,objRet); - //ui->comboBox->clear(); - //ui->comboBox->addItem("所有"); - if(objRet.isActive()) - { - while(objRet.next()) - { - User.PERM_ID=objRet.value(0).toInt(); - User.PERM_NAME=objRet.value(1).toString().toStdString(); - User.PERM_ALIAS=objRet.value(2).toString().toStdString(); - m_Users.push_back(User); - m_mapUser[User.PERM_NAME] = User ; - } - } - - ui->ListWidget1->setFocusPolicy(Qt::NoFocus); - ui->ListWidget1->setSelectionMode(QAbstractItemView::NoSelection); - ui->ListWidget2->setFocusPolicy(Qt::NoFocus); - ui->ListWidget2->setSelectionMode(QAbstractItemView::NoSelection); - ui->ListWidget3->setFocusPolicy(Qt::NoFocus); - ui->ListWidget3->setSelectionMode(QAbstractItemView::NoSelection); - ui->ListWidget4->setFocusPolicy(Qt::NoFocus); - ui->ListWidget4->setSelectionMode(QAbstractItemView::NoSelection); - ui->ListWidget2->setVisible(false); - ui->ListWidget3->setVisible(false); - ui->ListWidget4->setVisible(false); - - ui->scrollArea->setBackgroundRole(QPalette::Dark); - - ui->PasswordEdit->setEchoMode(QLineEdit::EchoMode::Password); -} - -void HandoverWidget::InitFarm() -{ - qDebug() << "InitFarm-------------------"; - ui->NowGroupWidget->setColumnCount(2); - QStringList header1; - header1<<"班组成员"<<"状态"; - ui->NowGroupWidget->setHorizontalHeaderLabels(header1); - ui->NowGroupWidget->verticalHeader()->setVisible(false); - //ui->NowGroupWidget->horizontalHeader()->setStretchLastSection(true); - ui->NowGroupWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - ui->NowGroupWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->NowGroupWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->NowGroupWidget->setFocusPolicy(Qt::NoFocus); - - - ui->NextGroupWidget->setColumnCount(2); - QStringList header2; - header2<<"班组成员"<<"状态"; - ui->NextGroupWidget->setHorizontalHeaderLabels(header2); - ui->NextGroupWidget->verticalHeader()->setVisible(false); - //ui->NextGroupWidget->horizontalHeader()->setStretchLastSection(true); - ui->NextGroupWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - ui->NextGroupWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->NextGroupWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->NextGroupWidget->setFocusPolicy(Qt::NoFocus); - - connect(ui->NextGroupWidget,&QTableWidget::cellClicked,this,&HandoverWidget::on_NextGroupWidget_cellClicked); - - ui->NameEdit->setReadOnly(true); - - QString strSql; - QSqlQuery objRet; - - Records.clear(); - DUTY_INFO Record; - strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where START_TIME>'0' order by ID desc limit 2"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Record.ID=objRet.value(0).toInt(); - Record.GROUP_NAME=objRet.value(1).toString().toStdString(); - Record.USERS=objRet.value(2).toString().toStdString(); - Record.USERS_STATUS=objRet.value(3).toString().toStdString(); - Record.START_TIME=objRet.value(4).toString().toStdString(); - Record.END_TIME=objRet.value(5).toString().toStdString(); - Record.NOTE1=objRet.value(6).toString().toStdString(); - Record.NOTE2=objRet.value(7).toString().toStdString(); - Record.NOTE3=objRet.value(8).toString().toStdString(); - Records.push_back(Record); - } - } - QString prefix_str=""; - QString strlist; - QStringList list; - - if(Records.size()<2) - { - ui->ListWidget1->addItem("上班起始时间:无"); - ui->ListWidget1->addItem("上班结束时间:无"); - ui->ListWidget1->addItem("上班班组:无"); - ui->ListWidget1->addItem("上班值班人:无"); - ui->ListWidget1->addItem(prefix_str+"本班班组:"+Records.at(0).GROUP_NAME.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班值班人:"+Records.at(0).USERS.c_str()); - ui->ListWidget1->addItem("上班遗留问题:无"); - ui->ListWidget1->addItem(prefix_str+"本班处理问题:\n"+Records.at(0).NOTE1.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班遗留问题:\n"+Records.at(0).NOTE2.c_str()); - ui->ListWidget1->addItem(prefix_str+"关键信息备注:\n"+Records.at(0).NOTE3.c_str()); - } - else - { - ui->ListWidget1->addItem(prefix_str+"上班起始时间:"+Records.at(1).START_TIME.c_str()); - ui->ListWidget1->addItem(prefix_str+"上班结束时间:"+Records.at(1).END_TIME.c_str()); - ui->ListWidget1->addItem(prefix_str+"上班班组:"+Records.at(1).GROUP_NAME.c_str()); - ui->ListWidget1->addItem(prefix_str+"上班值班人:"+Records.at(1).USERS.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班班组:"+Records.at(0).GROUP_NAME.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班值班人:"+Records.at(0).USERS.c_str()); - ui->ListWidget1->addItem(prefix_str+"上班遗留问题:\n"+Records.at(1).NOTE2.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班处理问题:\n"+Records.at(0).NOTE1.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班遗留问题:\n"+Records.at(0).NOTE2.c_str()); - ui->ListWidget1->addItem(prefix_str+"关键信息备注:\n"+Records.at(0).NOTE3.c_str()); - } - //ui->ListWidget1->setMinimumHeight(ui->ListWidget1->sizeHintForRow(0)*10+4); - - m_Groups.clear(); - DUTY_DEFINE Group; - strSql = "select ID,NAME,START_TIME,END_TIME from duty_define"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Group.ID=objRet.value(0).toInt(); - Group.NAME=objRet.value(1).toString().toStdString(); - Group.START_TIME=objRet.value(2).toString().toStdString(); - Group.END_TIME=objRet.value(3).toString().toStdString(); - m_Groups.push_back(Group); - } - } - - QString str; - - str=QDate::currentDate().toString("yyyy-MM-dd"); - m_Date_Groups.clear(); - DUTY_SETTING Date_Group; - strSql = "select DATE,DUTY_DEFINE_ID,USERS from duty_setting where USERS!='' and DATE='"+str+"'"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Date_Group.DATE=objRet.value(0).toString().toStdString(); - Date_Group.DUTY_DEFINE_ID=objRet.value(1).toInt(); - Date_Group.USERS=objRet.value(2).toString().toStdString(); - m_Date_Groups.push_back(Date_Group); - } - } - - for(size_t i=0;icomboBox->addItem(m_Date_Groups.at(i).NAME.c_str()); - } - - str="交班班组:"; - str=str+Records.at(0).GROUP_NAME.c_str(); - ui->label1->setText(str); - - ui->NowGroupWidget->setRowCount(0); - for(size_t i=0;iNowGroupWidget->insertRow(ui->NowGroupWidget->rowCount()); - ui->NowGroupWidget->setItem(j,0,new QTableWidgetItem(list.at(j))); - ui->NowGroupWidget->item(j,0)->setTextAlignment(Qt::AlignCenter); - } - } - } - - int num=list.count(); - strlist=Records.at(0).USERS_STATUS.c_str(); - list=strlist.split(","); - - for(int j=0;jNowGroupWidget->setItem(j,1,new QTableWidgetItem(tr("未签到"))); - ui->NowGroupWidget->item(j,1)->setTextAlignment(Qt::AlignCenter); - } - else - { - ui->NowGroupWidget->setItem(j,1,new QTableWidgetItem(tr("已签到"))); - ui->NowGroupWidget->item(j,1)->setTextAlignment(Qt::AlignCenter); - } - } - - emit ui->comboBox->currentIndexChanged(ui->comboBox->currentText()); -} - -void HandoverWidget::InitNoFarm() -{ - ui->Frame->setVisible(false); - ui->scrollArea->resize(ui->scrollArea->rect().width(),this->rect().height()-ui->scrollArea->y()*2); - - QString strSql; - QSqlQuery objRet; - - Records.clear(); - DUTY_INFO Record; - strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where START_TIME<='"+m_begin_time+"' and START_TIME>'0' order by ID desc limit 2"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Record.ID=objRet.value(0).toInt(); - Record.GROUP_NAME=objRet.value(1).toString().toStdString(); - Record.USERS=objRet.value(2).toString().toStdString(); - Record.USERS_STATUS=objRet.value(3).toString().toStdString(); - Record.START_TIME=objRet.value(4).toString().toStdString(); - Record.END_TIME=objRet.value(5).toString().toStdString(); - Record.NOTE1=objRet.value(6).toString().toStdString(); - Record.NOTE2=objRet.value(7).toString().toStdString(); - Record.NOTE3=objRet.value(8).toString().toStdString(); - Records.push_back(Record); - } - } - QString prefix_str=""; - - if(Records.size()<2) - { - ui->ListWidget1->addItem(prefix_str+"本班起始时间:"+Records.at(0).START_TIME.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班结束时间:"+Records.at(0).END_TIME.c_str()); - ui->ListWidget1->addItem("上班班组:无"); - ui->ListWidget1->addItem("上班值班人:无"); - ui->ListWidget1->addItem(prefix_str+"本班班组:"+Records.at(0).GROUP_NAME.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班值班人:"+Records.at(0).USERS.c_str()); - ui->ListWidget1->addItem("上班遗留问题:无"); - ui->ListWidget1->addItem(prefix_str+"本班处理问题:\n"+Records.at(0).NOTE1.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班遗留问题:\n"+Records.at(0).NOTE2.c_str()); - ui->ListWidget1->addItem(prefix_str+"关键信息备注:\n"+Records.at(0).NOTE3.c_str()); - } - else - { - ui->ListWidget1->addItem(prefix_str+"本班起始时间:"+Records.at(0).START_TIME.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班结束时间:"+Records.at(0).END_TIME.c_str()); - ui->ListWidget1->addItem(prefix_str+"上班班组:"+Records.at(1).GROUP_NAME.c_str()); - ui->ListWidget1->addItem(prefix_str+"上班值班人:"+Records.at(1).USERS.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班班组:"+Records.at(0).GROUP_NAME.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班值班人:"+Records.at(0).USERS.c_str()); - ui->ListWidget1->addItem(prefix_str+"上班遗留问题:\n"+Records.at(1).NOTE2.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班处理问题:\n"+Records.at(0).NOTE1.c_str()); - ui->ListWidget1->addItem(prefix_str+"本班遗留问题:\n"+Records.at(0).NOTE2.c_str()); - ui->ListWidget1->addItem(prefix_str+"关键信息备注:\n"+Records.at(0).NOTE3.c_str()); - } - //ui->ListWidget1->setMinimumHeight(ui->ListWidget1->sizeHintForRow(0)*10+4); -} - -void HandoverWidget::InitData() -{ - QString strSql; - QSqlQuery objRet; - - if(m_isFarm==true) - { - QDateTime start_time=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - qint64 msecTime_start=start_time.toMSecsSinceEpoch(); - qint64 msecTime_end=QDateTime::currentDateTime().toMSecsSinceEpoch(); - - strSql = "select CREATE_TIME,REQUESTER,FILE_PATH from his_work_ticket where CREATE_TIME>"+QString::number(msecTime_start/1000,10); - m_pReadDb->execute(strSql,objRet); - ui->PushButton2->setText("工作票-"+QString::number(objRet.size(),10)); - - QString strCondition = bulidCondition(); - if(strCondition.isEmpty()) - { - strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; - }else - { - strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" and "+strCondition+" order by TIME_STAMP desc limit 1000"; - } - LOGDEBUG("alm-sql1:%s",strSql.toStdString().c_str()); - m_pReadDb->execute(strSql,objRet); - ui->PushButton3->setText("关键告警-"+QString::number(objRet.size(),10)); - - strSql = "select TIME_STAMP,CONTENT from his_event where ALM_TYPE=4 and TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; - m_pReadDb->execute(strSql,objRet); - ui->PushButton4->setText("操作记录-"+QString::number(objRet.size(),10)); - } - else - { - QDateTime start_time=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - qint64 msecTime_start=start_time.toMSecsSinceEpoch(); - QDateTime end_time=QDateTime::fromString(Records.at(0).END_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - qint64 msecTime_end=end_time.toMSecsSinceEpoch(); - - strSql = "select CREATE_TIME,REQUESTER,FILE_PATH from his_work_ticket where CREATE_TIME>="+QString::number(msecTime_start/1000,10)+" and CREATE_TIME<"+QString::number(msecTime_end/1000,10); - m_pReadDb->execute(strSql,objRet); - ui->PushButton2->setText("工作票-"+QString::number(objRet.size(),10)); - - QString strCondition = bulidCondition(); - if(strCondition.isEmpty()) - { - strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; - }else - { - strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" and "+strCondition+" order by TIME_STAMP desc limit 1000"; - } - LOGDEBUG("alm-sql2:%s",strSql.toStdString().c_str()); - m_pReadDb->execute(strSql,objRet); - ui->PushButton3->setText("关键告警-"+QString::number(objRet.size(),10)); - - strSql = "select TIME_STAMP,CONTENT from his_event where ALM_TYPE=4 and TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; - m_pReadDb->execute(strSql,objRet); - ui->PushButton4->setText("操作记录-"+QString::number(objRet.size(),10)); - } -} - -void HandoverWidget::loadXml() -{ - m_keyAlmLevelList.clear(); - CCommonConfigParse configParse; - std::string strFilePath = "../../common/sysconfig/"; - std::string strFileName = "shiftWidget.xml"; - if(kbdSuccess == configParse.load(strFilePath,strFileName)) - { - int num = 0; - if(kbdSuccess == configParse.getIntValue("shiftWidget","levelNum",num)) - { - - for(int index(1);index<=num;index++) - { - QString name = QString("level%1").arg(QString::number(index)); - int value = 0; - if(kbdSuccess == configParse.getIntValue("shiftWidget",name.toStdString(),value)) - { - m_keyAlmLevelList.append(value); - LOGDEBUG("loadXml() index:%d name:%s value:%d",index,name.toStdString().c_str(),value); - } - } - } - } -} - -QString HandoverWidget::bulidCondition() -{ - QString strFilter; - for(int nIndex = 0; nIndex < m_keyAlmLevelList.size(); nIndex++) - { - strFilter.append(QString::number(m_keyAlmLevelList.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); - } - return strFilter; -} - -void HandoverWidget::on_ConfirmButton_clicked() -{ - if(ui->comboBox->currentIndex()<0) - { - QMessageBox::critical(this,"提示","请选择接班班次"); - return; - } - - if(ui->NextGroupWidget->currentRow()<0) - { - QMessageBox::critical(this,"提示","请选择交班人员"); - return; - } - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - if(PERM_NORMAL>permMngPtr->CheckUserValid(ui->NameEdit->text().toStdString().data(),ui->PasswordEdit->text().toStdString().data())) - { - QMessageBox::critical(this,"用户验证错误","用户名或者密码错误"); - return; - } - } - - if(!m_pReadDb || !m_pReadDb->isOpen() - || !m_pWriteDb || !m_pWriteDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - return; - } - - QString strSql; - QSqlQuery objRet; - - DUTY_INFO Record; - strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where START_TIME>'0' order by ID desc limit 1"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Record.ID=objRet.value(0).toInt(); - Record.GROUP_NAME=objRet.value(1).toString().toStdString(); - Record.USERS=objRet.value(2).toString().toStdString(); - Record.USERS_STATUS=objRet.value(3).toString().toStdString(); - Record.START_TIME=objRet.value(4).toString().toStdString(); - Record.END_TIME=objRet.value(5).toString().toStdString(); - Record.NOTE1=objRet.value(6).toString().toStdString(); - Record.NOTE2=objRet.value(7).toString().toStdString(); - Record.NOTE3=objRet.value(8).toString().toStdString(); - } - } - - QString Now_time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); - strSql="update duty_info set END_TIME='"+Now_time+"' where ID="+QString::number(Record.ID,10); - if(!m_pWriteDb->execute(strSql)) - { - QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); - } - QString Users=""; - QString Name=""; - for(int i=0; iNextGroupWidget->rowCount(); i++) - { - Users += ui->NextGroupWidget->item(i, 0)->text(); - if(tr("已签到") == ui->NextGroupWidget->item(i, 1)->text()) - { - Name += "1"; - } - else - { - Name += "0"; - } - if(i != ui->NextGroupWidget->rowCount()-1) - { - Users += ","; - Name += ","; - } - } - - DUTY_INFO signIn; - strSql = QString("select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where ID>%1" - " and GROUP_NAME='%2' order by ID desc limit 1").arg(Record.ID).arg(ui->comboBox->currentText()); - m_pReadDb->execute(strSql,objRet); - bool isRet = false; - if(objRet.isActive()) - { - while(objRet.next()) - { - signIn.ID=objRet.value(0).toInt(); - signIn.GROUP_NAME=objRet.value(1).toString().toStdString(); - signIn.USERS=objRet.value(2).toString().toStdString(); - signIn.USERS_STATUS=objRet.value(3).toString().toStdString(); - signIn.START_TIME=objRet.value(4).toString().toStdString(); - signIn.END_TIME=objRet.value(5).toString().toStdString(); - signIn.NOTE1=objRet.value(6).toString().toStdString(); - signIn.NOTE2=objRet.value(7).toString().toStdString(); - signIn.NOTE3=objRet.value(8).toString().toStdString(); - isRet = true; - } - } - - if(isRet) - { - strSql=QString("update duty_info set START_TIME='%1' where ID=%2").arg(Now_time).arg(signIn.ID); - qDebug() << strSql; - if(!m_pWriteDb->execute(strSql)) - { - QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); - } - } - else - { - strSql="insert into duty_info (ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME) values (" - +QString::number((Record.ID+1),10)+",'"+ui->comboBox->currentText()+"','"+Users+"','"+Name+"','"+Now_time+"')"; - if(!m_pWriteDb->execute(strSql)) - { - QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); - } - } - - close(); -} - -void HandoverWidget::on_SignInButton_clicked() -{ - if(ui->NextGroupWidget->currentRow()<0) - { - QMessageBox::critical(this,"提示","请选择签到人员"); - return; - } - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - if(PERM_NORMAL != permMngPtr->CheckUserValid(ui->NameEdit->text().toStdString().data(),ui->PasswordEdit->text().toStdString().data())) - { - QMessageBox::critical(this,"用户验证错误","用户名或者密码错误"); - return; - } - - if(!m_pReadDb || !m_pReadDb->isOpen() - || !m_pWriteDb || !m_pWriteDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - return; - } - - QString strSql = "select ID from duty_info where START_TIME>'0' order by ID desc limit 1"; - QSqlQuery objRet; - int RecordMaxId = 0; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - RecordMaxId = objRet.value(0).toInt(); - } - } - - DUTY_INFO record; - strSql = QString("select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where ID>%1" - " and GROUP_NAME='%2' order by ID desc limit 1").arg(RecordMaxId).arg(ui->comboBox->currentText()); - m_pReadDb->execute(strSql,objRet); - bool isRet = false; - if(objRet.isActive()) - { - while(objRet.next()) - { - record.ID=objRet.value(0).toInt(); - record.GROUP_NAME=objRet.value(1).toString().toStdString(); - record.USERS=objRet.value(2).toString().toStdString(); - record.USERS_STATUS=objRet.value(3).toString().toStdString(); - record.START_TIME=objRet.value(4).toString().toStdString(); - record.END_TIME=objRet.value(5).toString().toStdString(); - record.NOTE1=objRet.value(6).toString().toStdString(); - record.NOTE2=objRet.value(7).toString().toStdString(); - record.NOTE3=objRet.value(8).toString().toStdString(); - isRet = true; - } - } - - QString Users=""; - QString Name=""; - QString curText; - for(int i=0; iNextGroupWidget->rowCount(); i++) - { - curText = ui->NextGroupWidget->item(i, 0)->text(); - Users += curText; - if(curText == ui->NextGroupWidget->item(ui->NextGroupWidget->currentRow(), 0)->text() - || tr("已签到") == ui->NextGroupWidget->item(i, 1)->text()) - { - Name += "1"; - } - else - { - Name += "0"; - } - if(i != ui->NextGroupWidget->rowCount()-1) - { - Users += ","; - Name += ","; - } - } - - if(isRet) - { - strSql = QString("update duty_info set USERS_STATUS='%1' where ID=%2").arg(Name).arg(record.ID); - if(!m_pWriteDb->execute(strSql)) - { - QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); - return; - } - } - else - { - int MaxId = 0; - strSql = "select ID from duty_info order by ID desc limit 1"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - MaxId = objRet.value(0).toInt(); - } - } - - strSql="insert into duty_info (ID,GROUP_NAME,USERS,USERS_STATUS) values (" - +QString::number((MaxId+1),10)+",'"+ui->comboBox->currentText()+"','"+Users+"','"+Name+"')"; - if(!m_pWriteDb->execute(strSql)) - { - QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); - return; - } - } - - ui->NextGroupWidget->setItem(ui->NextGroupWidget->currentRow(),1,new QTableWidgetItem(tr("已签到"))); - ui->NextGroupWidget->item(ui->NextGroupWidget->currentRow(),1)->setTextAlignment(Qt::AlignCenter); - } -} - -void HandoverWidget::on_comboBox_currentIndexChanged(const QString &arg1) -{ - ui->NextGroupWidget->setRowCount(0); - ui->NameEdit->setText(""); - - if(!m_pReadDb || !m_pReadDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - return; - } - - QString strSql = "select ID from duty_info where START_TIME>'0' order by ID desc limit 1"; - QSqlQuery objRet; - int RecordMaxId = 0; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - RecordMaxId = objRet.value(0).toInt(); - } - } - - QString strlist; - QStringList aliaslist; - DUTY_INFO record; - strSql = QString("select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where ID>%1" - " and GROUP_NAME='%2' order by ID desc limit 1").arg(RecordMaxId).arg(arg1); - m_pReadDb->execute(strSql,objRet); - bool isRet = false; - if(objRet.isActive()) - { - while(objRet.next()) - { - record.ID=objRet.value(0).toInt(); - record.GROUP_NAME=objRet.value(1).toString().toStdString(); - record.USERS=objRet.value(2).toString().toStdString(); - record.USERS_STATUS=objRet.value(3).toString().toStdString(); - record.START_TIME=objRet.value(4).toString().toStdString(); - record.END_TIME=objRet.value(5).toString().toStdString(); - record.NOTE1=objRet.value(6).toString().toStdString(); - record.NOTE2=objRet.value(7).toString().toStdString(); - record.NOTE3=objRet.value(8).toString().toStdString(); - isRet = true; - } - } - if(isRet) - { - aliaslist=QString::fromStdString(record.USERS).split(","); - QStringList statusList=QString::fromStdString(record.USERS_STATUS).split(","); - - for(int j=0;jNextGroupWidget->insertRow(ui->NextGroupWidget->rowCount()); - ui->NextGroupWidget->setItem(j,0,new QTableWidgetItem(aliaslist[j])); - if(statusList.value(j,"0") == "1") - { - ui->NextGroupWidget->setItem(j,1,new QTableWidgetItem(tr("已签到"))); - } - else - { - ui->NextGroupWidget->setItem(j,1,new QTableWidgetItem(tr("未签到"))); - } - ui->NextGroupWidget->item(j,0)->setTextAlignment(Qt::AlignCenter); - ui->NextGroupWidget->item(j,1)->setTextAlignment(Qt::AlignCenter); - } - } - else - { - for(size_t i=0;i::iterator it = m_mapUser.find(strUserAlias.toStdString()); - if (it != m_mapUser.end())//找到 - { - strUserAlias = QString(it->second.PERM_ALIAS.c_str()); - } - ui->NextGroupWidget->insertRow(ui->NextGroupWidget->rowCount()); - ui->NextGroupWidget->setItem(j,0,new QTableWidgetItem(strUserAlias)); - ui->NextGroupWidget->item(j,0)->setTextAlignment(Qt::AlignCenter); - ui->NextGroupWidget->setItem(j,1,new QTableWidgetItem(tr("未签到"))); - ui->NextGroupWidget->item(j,1)->setTextAlignment(Qt::AlignCenter); - } - } - } - } -} - -void HandoverWidget::on_NextGroupWidget_cellClicked(int row, int column) -{ - Q_UNUSED(column) - //ui->NameEdit->setText(ui->NextGroupWidget->item(row,0)->text()); - ui->NameEdit->clear(); - for(size_t i=0;iNextGroupWidget->item(row,0)->text()) - { - ui->NameEdit->setText(m_Users.at(i).PERM_NAME.c_str()); - } - } - ui->PasswordEdit->setText(""); -} - -void HandoverWidget::on_PushButton1_clicked() -{ - if(ui->ListWidget1->isVisible()==false) - { - ui->ListWidget1->setVisible(true); - } - else if(ui->ListWidget1->isVisible()==true) - { - ui->ListWidget1->setVisible(false); - } -} - -void HandoverWidget::on_PushButton2_clicked() -{ - if(!m_pReadDb || !m_pReadDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - return; - } - - if(ui->ListWidget2->isVisible()==false) - { - ui->ListWidget2->setVisible(true); - ui->ListWidget2->clear(); - - QString strSql; - QSqlQuery objRet; - - if(m_isFarm==true) - { - QDateTime date_time=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - qint64 msecTime=date_time.toSecsSinceEpoch(); - - std::vector Tickets; - HIS_WORK_TICKET Ticket; - strSql = "select CREATE_TIME,REQUESTER,FILE_PATH from his_work_ticket where CREATE_TIME>"+QString::number(msecTime,10); - qDebug() << strSql; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Ticket.CREATE_TIME=objRet.value(0).toInt(); - Ticket.REQUESTER=objRet.value(1).toString().toStdString(); - QString strTemp = objRet.value(2).toString(); - QStringList sList = strTemp.split("/data/"); - if(sList.count()>0) - { - Ticket.FILE_PATH = sList.at(sList.count()-1).toStdString(); - } - else - { - Ticket.FILE_PATH=objRet.value(2).toString().toStdString(); - } - - Tickets.push_back(Ticket); - } - } - ui->PushButton2->setText("工作票-"+QString::number(Tickets.size(),10)); - QString create_time; - QDateTime Ticket_date_time; - for(size_t i=0;iListWidget2->addItem(create_time+" 申请人:"+Tickets.at(i).REQUESTER.c_str()+" 文件路径:data/"+Tickets.at(i).FILE_PATH.c_str()); - } - ui->ListWidget2->setMinimumHeight(ui->ListWidget2->sizeHintForRow(0)*(int)Tickets.size()+4); - } - else - { - QDateTime date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - qint64 msecTime_start=date_time_start.toSecsSinceEpoch(); - - QDateTime date_time_end=QDateTime::fromString(Records.at(0).END_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - qint64 msecTime_end=date_time_end.toSecsSinceEpoch(); - - std::vector Tickets; - HIS_WORK_TICKET Ticket; - strSql = "select CREATE_TIME,REQUESTER,FILE_PATH from his_work_ticket where CREATE_TIME>="+QString::number(msecTime_start,10)+" and CREATE_TIME<"+QString::number(msecTime_end,10); - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Ticket.CREATE_TIME=objRet.value(0).toInt(); - Ticket.REQUESTER=objRet.value(1).toString().toStdString(); - Ticket.FILE_PATH=objRet.value(2).toString().toStdString(); - QString strTemp = objRet.value(2).toString(); - QStringList sList = strTemp.split("/data/"); - if(sList.count()>0) - { - Ticket.FILE_PATH = sList.at(sList.count()-1).toStdString(); - } - else - { - Ticket.FILE_PATH=objRet.value(2).toString().toStdString(); - } - Tickets.push_back(Ticket); - } - } - ui->PushButton2->setText("工作票-"+QString::number(Tickets.size(),10)); - QString create_time; - QDateTime Ticket_date_time; - for(size_t i=0;iListWidget2->addItem(create_time+" 申请人:"+Tickets.at(i).REQUESTER.c_str()+" 文件路径:data/"+Tickets.at(i).FILE_PATH.c_str()); - } - ui->ListWidget2->setMinimumHeight(ui->ListWidget2->sizeHintForRow(0)*(int)Tickets.size()+4); - } - } - else if(ui->ListWidget2->isVisible()==true) - { - ui->ListWidget2->setVisible(false); - } -} - -void HandoverWidget::on_PushButton3_clicked() -{ - if(ui->ListWidget3->isVisible()==false) - { - //ui->ListWidget3->setVisible(true); - //ui->ListWidget3->clear(); - - QDateTime date_time_start; - QDateTime date_time_end; - - if(m_isFarm==true) - { - date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - date_time_end=QDateTime::currentDateTime(); - - //QueryThread *m_thread; - if(m_thread_Events) - { - delete m_thread_Events; - m_thread_Events=NULL; - } - m_thread_Events=new QueryThread(); - m_thread_Events->start_time=date_time_start; - m_thread_Events->end_time=date_time_end; - m_thread_Events->isEvent=true; - - qRegisterMetaType>("std::vector"); - connect(m_thread_Events,&QueryThread::signal_QueryEnd_Event,this,&HandoverWidget::slot_QueryEnd_Event); - - m_thread_Events->start(); - } - else - { - date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - date_time_end=QDateTime::fromString(Records.at(0).END_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - - //QueryThread *m_thread; - if(m_thread_Events_Operates) - { - delete m_thread_Events_Operates; - m_thread_Events_Operates=NULL; - } - m_thread_Events_Operates=new QueryThread(); - m_thread_Events_Operates->start_time=date_time_start; - m_thread_Events_Operates->end_time=date_time_end; - m_thread_Events_Operates->isEvent=true; - - qRegisterMetaType>("std::vector"); - connect(m_thread_Events_Operates,&QueryThread::signal_QueryEnd_Event,this,&HandoverWidget::slot_QueryEnd_Event); - - m_thread_Events_Operates->start(); - } - } - else if(ui->ListWidget3->isVisible()==true) - { - ui->ListWidget3->setVisible(false); - } -} - -void HandoverWidget::on_PushButton4_clicked() -{ - if(ui->ListWidget4->isVisible()==false) - { - //ui->ListWidget4->setVisible(true); - //ui->ListWidget4->clear(); - - QDateTime date_time_start; - QDateTime date_time_end; - - if(m_isFarm==true) - { - date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - date_time_end=QDateTime::currentDateTime(); - - //QueryThread *m_thread; - if(m_thread_Events) - { - delete m_thread_Events; - m_thread_Events=NULL; - } - m_thread_Events=new QueryThread(); - m_thread_Events->start_time=date_time_start; - m_thread_Events->end_time=date_time_end; - m_thread_Events->isEvent_Operate=true; - - qRegisterMetaType>("std::vector"); - connect(m_thread_Events,&QueryThread::signal_QueryEnd_Event_Operate,this,&HandoverWidget::slot_QueryEnd_Event_Operate); - - m_thread_Events->start(); - } - else - { - date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - date_time_end=QDateTime::fromString(Records.at(0).END_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); - - //QueryThread *m_thread; - if(m_thread_Events_Operates) - { - delete m_thread_Events_Operates; - m_thread_Events_Operates=NULL; - } - m_thread_Events_Operates=new QueryThread(); - m_thread_Events_Operates->start_time=date_time_start; - m_thread_Events_Operates->end_time=date_time_end; - m_thread_Events_Operates->isEvent_Operate=true; - - qRegisterMetaType>("std::vector"); - connect(m_thread_Events_Operates,&QueryThread::signal_QueryEnd_Event_Operate,this,&HandoverWidget::slot_QueryEnd_Event_Operate); - - m_thread_Events_Operates->start(); - } - } - else if(ui->ListWidget4->isVisible()==true) - { - ui->ListWidget4->setVisible(false); - } -} - -void HandoverWidget::slot_QueryEnd_Event(std::vector m_Events) -{ - ui->ListWidget3->setVisible(true); - ui->ListWidget3->clear(); - - QDateTime date_time; - QString time; - ui->PushButton3->setText("关键告警-"+QString::number(m_Events.size(),10)); - for(size_t i=0;iListWidget3->addItem(time+" "+m_Events.at(i).CONTENT.c_str()); - } - ui->ListWidget3->setMinimumHeight(ui->ListWidget3->sizeHintForRow(0)*(int)m_Events.size()+4); - - if(m_thread_Events) - { - delete m_thread_Events; - m_thread_Events=NULL; - } - //QApplication::restoreOverrideCursor(); -} - -void HandoverWidget::slot_QueryEnd_Event_Operate(std::vector m_Events_Operates) -{ - ui->ListWidget4->setVisible(true); - ui->ListWidget4->clear(); - - QDateTime date_time; - QString time; - ui->PushButton4->setText("操作记录-"+QString::number(m_Events_Operates.size(),10)); - for(size_t i=0;iListWidget4->addItem(time+" "+m_Events_Operates.at(i).CONTENT.c_str()); - } - ui->ListWidget4->setMinimumHeight(ui->ListWidget4->sizeHintForRow(0)*(int)m_Events_Operates.size()+4); - - if(m_thread_Events_Operates) - { - delete m_thread_Events_Operates; - m_thread_Events_Operates=NULL; - } - //QApplication::restoreOverrideCursor(); -} +#include "HandoverWidget.h" +#include "ui_HandoverWidget.h" +#include +#include "QueryThread.h" +#include +#include +#include +#include "pub_utility_api/CommonConfigParse.h" +#include "Common.h" +#include "pub_logger_api/logger.h" + +using namespace kbd_public; + +HandoverWidget::HandoverWidget(QWidget *parent,kbd_dbms::CDbApi *dbRead,kbd_dbms::CDbApi *dbWrite,bool isFarm,QString begin_time) : + QDialog(parent), + ui(new Ui::HandoverWidget), + m_pReadDb(dbRead), + m_pWriteDb(dbWrite), + m_isFarm(isFarm), + m_begin_time(begin_time) +{ + m_thread_Events = NULL; + m_thread_Events_Operates = NULL; + ui->setupUi(this); + this->setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); + Init(); + loadXml(); + if(m_isFarm==true) + { + InitFarm(); + } + else + { + InitNoFarm(); + } + InitData(); +} + +HandoverWidget::~HandoverWidget() +{ + delete ui; +} + +void HandoverWidget::Init() +{ + if(!m_pReadDb || !m_pReadDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + close(); + } + QString strSql; + QSqlQuery objRet; + + m_Users.clear(); + RM_USER_DEF User; + strSql = "select PERM_ID,PERM_NAME,PERM_ALIAS from rm_user_def"; + m_pReadDb->execute(strSql,objRet); + //ui->comboBox->clear(); + //ui->comboBox->addItem("所有"); + if(objRet.isActive()) + { + while(objRet.next()) + { + User.PERM_ID=objRet.value(0).toInt(); + User.PERM_NAME=objRet.value(1).toString().toStdString(); + User.PERM_ALIAS=objRet.value(2).toString().toStdString(); + m_Users.push_back(User); + m_mapUser[User.PERM_NAME] = User ; + } + } + + ui->ListWidget1->setFocusPolicy(Qt::NoFocus); + ui->ListWidget1->setSelectionMode(QAbstractItemView::NoSelection); + ui->ListWidget2->setFocusPolicy(Qt::NoFocus); + ui->ListWidget2->setSelectionMode(QAbstractItemView::NoSelection); + ui->ListWidget3->setFocusPolicy(Qt::NoFocus); + ui->ListWidget3->setSelectionMode(QAbstractItemView::NoSelection); + ui->ListWidget4->setFocusPolicy(Qt::NoFocus); + ui->ListWidget4->setSelectionMode(QAbstractItemView::NoSelection); + ui->ListWidget2->setVisible(false); + ui->ListWidget3->setVisible(false); + ui->ListWidget4->setVisible(false); + + ui->scrollArea->setBackgroundRole(QPalette::Dark); + + ui->PasswordEdit->setEchoMode(QLineEdit::EchoMode::Password); +} + +void HandoverWidget::InitFarm() +{ + qDebug() << "InitFarm-------------------"; + ui->NowGroupWidget->setColumnCount(2); + QStringList header1; + header1<<"班组成员"<<"状态"; + ui->NowGroupWidget->setHorizontalHeaderLabels(header1); + ui->NowGroupWidget->verticalHeader()->setVisible(false); + //ui->NowGroupWidget->horizontalHeader()->setStretchLastSection(true); + ui->NowGroupWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + ui->NowGroupWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->NowGroupWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->NowGroupWidget->setFocusPolicy(Qt::NoFocus); + + + ui->NextGroupWidget->setColumnCount(2); + QStringList header2; + header2<<"班组成员"<<"状态"; + ui->NextGroupWidget->setHorizontalHeaderLabels(header2); + ui->NextGroupWidget->verticalHeader()->setVisible(false); + //ui->NextGroupWidget->horizontalHeader()->setStretchLastSection(true); + ui->NextGroupWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + ui->NextGroupWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->NextGroupWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->NextGroupWidget->setFocusPolicy(Qt::NoFocus); + + connect(ui->NextGroupWidget,&QTableWidget::cellClicked,this,&HandoverWidget::on_NextGroupWidget_cellClicked); + + ui->NameEdit->setReadOnly(true); + + QString strSql; + QSqlQuery objRet; + + Records.clear(); + DUTY_INFO Record; + strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where START_TIME>'0' order by ID desc limit 2"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Record.ID=objRet.value(0).toInt(); + Record.GROUP_NAME=objRet.value(1).toString().toStdString(); + Record.USERS=objRet.value(2).toString().toStdString(); + Record.USERS_STATUS=objRet.value(3).toString().toStdString(); + Record.START_TIME=objRet.value(4).toString().toStdString(); + Record.END_TIME=objRet.value(5).toString().toStdString(); + Record.NOTE1=objRet.value(6).toString().toStdString(); + Record.NOTE2=objRet.value(7).toString().toStdString(); + Record.NOTE3=objRet.value(8).toString().toStdString(); + Records.push_back(Record); + } + } + QString prefix_str=""; + QString strlist; + QStringList list; + + if(Records.size()<2) + { + ui->ListWidget1->addItem("上班起始时间:无"); + ui->ListWidget1->addItem("上班结束时间:无"); + ui->ListWidget1->addItem("上班班组:无"); + ui->ListWidget1->addItem("上班值班人:无"); + ui->ListWidget1->addItem(prefix_str+"本班班组:"+Records.at(0).GROUP_NAME.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班值班人:"+Records.at(0).USERS.c_str()); + ui->ListWidget1->addItem("上班遗留问题:无"); + ui->ListWidget1->addItem(prefix_str+"本班处理问题:\n"+Records.at(0).NOTE1.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班遗留问题:\n"+Records.at(0).NOTE2.c_str()); + ui->ListWidget1->addItem(prefix_str+"关键信息备注:\n"+Records.at(0).NOTE3.c_str()); + } + else + { + ui->ListWidget1->addItem(prefix_str+"上班起始时间:"+Records.at(1).START_TIME.c_str()); + ui->ListWidget1->addItem(prefix_str+"上班结束时间:"+Records.at(1).END_TIME.c_str()); + ui->ListWidget1->addItem(prefix_str+"上班班组:"+Records.at(1).GROUP_NAME.c_str()); + ui->ListWidget1->addItem(prefix_str+"上班值班人:"+Records.at(1).USERS.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班班组:"+Records.at(0).GROUP_NAME.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班值班人:"+Records.at(0).USERS.c_str()); + ui->ListWidget1->addItem(prefix_str+"上班遗留问题:\n"+Records.at(1).NOTE2.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班处理问题:\n"+Records.at(0).NOTE1.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班遗留问题:\n"+Records.at(0).NOTE2.c_str()); + ui->ListWidget1->addItem(prefix_str+"关键信息备注:\n"+Records.at(0).NOTE3.c_str()); + } + //ui->ListWidget1->setMinimumHeight(ui->ListWidget1->sizeHintForRow(0)*10+4); + + m_Groups.clear(); + DUTY_DEFINE Group; + strSql = "select ID,NAME,START_TIME,END_TIME from duty_define"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Group.ID=objRet.value(0).toInt(); + Group.NAME=objRet.value(1).toString().toStdString(); + Group.START_TIME=objRet.value(2).toString().toStdString(); + Group.END_TIME=objRet.value(3).toString().toStdString(); + m_Groups.push_back(Group); + } + } + + QString str; + + str=QDate::currentDate().toString("yyyy-MM-dd"); + m_Date_Groups.clear(); + DUTY_SETTING Date_Group; + strSql = "select DATE,DUTY_DEFINE_ID,USERS from duty_setting where USERS!='' and DATE='"+str+"'"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Date_Group.DATE=objRet.value(0).toString().toStdString(); + Date_Group.DUTY_DEFINE_ID=objRet.value(1).toInt(); + Date_Group.USERS=objRet.value(2).toString().toStdString(); + m_Date_Groups.push_back(Date_Group); + } + } + + for(size_t i=0;icomboBox->addItem(m_Date_Groups.at(i).NAME.c_str()); + } + + str="交班班组:"; + str=str+Records.at(0).GROUP_NAME.c_str(); + ui->label1->setText(str); + + ui->NowGroupWidget->setRowCount(0); + for(size_t i=0;iNowGroupWidget->insertRow(ui->NowGroupWidget->rowCount()); + ui->NowGroupWidget->setItem(j,0,new QTableWidgetItem(list.at(j))); + ui->NowGroupWidget->item(j,0)->setTextAlignment(Qt::AlignCenter); + } + } + } + + int num=list.count(); + strlist=Records.at(0).USERS_STATUS.c_str(); + list=strlist.split(","); + + for(int j=0;jNowGroupWidget->setItem(j,1,new QTableWidgetItem(tr("未签到"))); + ui->NowGroupWidget->item(j,1)->setTextAlignment(Qt::AlignCenter); + } + else + { + ui->NowGroupWidget->setItem(j,1,new QTableWidgetItem(tr("已签到"))); + ui->NowGroupWidget->item(j,1)->setTextAlignment(Qt::AlignCenter); + } + } + + emit ui->comboBox->currentIndexChanged(ui->comboBox->currentText()); +} + +void HandoverWidget::InitNoFarm() +{ + ui->Frame->setVisible(false); + ui->scrollArea->resize(ui->scrollArea->rect().width(),this->rect().height()-ui->scrollArea->y()*2); + + QString strSql; + QSqlQuery objRet; + + Records.clear(); + DUTY_INFO Record; + strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where START_TIME<='"+m_begin_time+"' and START_TIME>'0' order by ID desc limit 2"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Record.ID=objRet.value(0).toInt(); + Record.GROUP_NAME=objRet.value(1).toString().toStdString(); + Record.USERS=objRet.value(2).toString().toStdString(); + Record.USERS_STATUS=objRet.value(3).toString().toStdString(); + Record.START_TIME=objRet.value(4).toString().toStdString(); + Record.END_TIME=objRet.value(5).toString().toStdString(); + Record.NOTE1=objRet.value(6).toString().toStdString(); + Record.NOTE2=objRet.value(7).toString().toStdString(); + Record.NOTE3=objRet.value(8).toString().toStdString(); + Records.push_back(Record); + } + } + QString prefix_str=""; + + if(Records.size()<2) + { + ui->ListWidget1->addItem(prefix_str+"本班起始时间:"+Records.at(0).START_TIME.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班结束时间:"+Records.at(0).END_TIME.c_str()); + ui->ListWidget1->addItem("上班班组:无"); + ui->ListWidget1->addItem("上班值班人:无"); + ui->ListWidget1->addItem(prefix_str+"本班班组:"+Records.at(0).GROUP_NAME.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班值班人:"+Records.at(0).USERS.c_str()); + ui->ListWidget1->addItem("上班遗留问题:无"); + ui->ListWidget1->addItem(prefix_str+"本班处理问题:\n"+Records.at(0).NOTE1.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班遗留问题:\n"+Records.at(0).NOTE2.c_str()); + ui->ListWidget1->addItem(prefix_str+"关键信息备注:\n"+Records.at(0).NOTE3.c_str()); + } + else + { + ui->ListWidget1->addItem(prefix_str+"本班起始时间:"+Records.at(0).START_TIME.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班结束时间:"+Records.at(0).END_TIME.c_str()); + ui->ListWidget1->addItem(prefix_str+"上班班组:"+Records.at(1).GROUP_NAME.c_str()); + ui->ListWidget1->addItem(prefix_str+"上班值班人:"+Records.at(1).USERS.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班班组:"+Records.at(0).GROUP_NAME.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班值班人:"+Records.at(0).USERS.c_str()); + ui->ListWidget1->addItem(prefix_str+"上班遗留问题:\n"+Records.at(1).NOTE2.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班处理问题:\n"+Records.at(0).NOTE1.c_str()); + ui->ListWidget1->addItem(prefix_str+"本班遗留问题:\n"+Records.at(0).NOTE2.c_str()); + ui->ListWidget1->addItem(prefix_str+"关键信息备注:\n"+Records.at(0).NOTE3.c_str()); + } + //ui->ListWidget1->setMinimumHeight(ui->ListWidget1->sizeHintForRow(0)*10+4); +} + +void HandoverWidget::InitData() +{ + QString strSql; + QSqlQuery objRet; + + if(m_isFarm==true) + { + QDateTime start_time=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + qint64 msecTime_start=start_time.toMSecsSinceEpoch(); + qint64 msecTime_end=QDateTime::currentDateTime().toMSecsSinceEpoch(); + + strSql = "select CREATE_TIME,REQUESTER,FILE_PATH from his_work_ticket where CREATE_TIME>"+QString::number(msecTime_start/1000,10); + m_pReadDb->execute(strSql,objRet); + ui->PushButton2->setText("工作票-"+QString::number(objRet.size(),10)); + + QString strCondition = bulidCondition(); + if(strCondition.isEmpty()) + { + strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; + }else + { + strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" and "+strCondition+" order by TIME_STAMP desc limit 1000"; + } + LOGDEBUG("alm-sql1:%s",strSql.toStdString().c_str()); + m_pReadDb->execute(strSql,objRet); + ui->PushButton3->setText("关键告警-"+QString::number(objRet.size(),10)); + + strSql = "select TIME_STAMP,CONTENT from his_event where ALM_TYPE=4 and TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; + m_pReadDb->execute(strSql,objRet); + ui->PushButton4->setText("操作记录-"+QString::number(objRet.size(),10)); + } + else + { + QDateTime start_time=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + qint64 msecTime_start=start_time.toMSecsSinceEpoch(); + QDateTime end_time=QDateTime::fromString(Records.at(0).END_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + qint64 msecTime_end=end_time.toMSecsSinceEpoch(); + + strSql = "select CREATE_TIME,REQUESTER,FILE_PATH from his_work_ticket where CREATE_TIME>="+QString::number(msecTime_start/1000,10)+" and CREATE_TIME<"+QString::number(msecTime_end/1000,10); + m_pReadDb->execute(strSql,objRet); + ui->PushButton2->setText("工作票-"+QString::number(objRet.size(),10)); + + QString strCondition = bulidCondition(); + if(strCondition.isEmpty()) + { + strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; + }else + { + strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" and "+strCondition+" order by TIME_STAMP desc limit 1000"; + } + LOGDEBUG("alm-sql2:%s",strSql.toStdString().c_str()); + m_pReadDb->execute(strSql,objRet); + ui->PushButton3->setText("关键告警-"+QString::number(objRet.size(),10)); + + strSql = "select TIME_STAMP,CONTENT from his_event where ALM_TYPE=4 and TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; + m_pReadDb->execute(strSql,objRet); + ui->PushButton4->setText("操作记录-"+QString::number(objRet.size(),10)); + } +} + +void HandoverWidget::loadXml() +{ + m_keyAlmLevelList.clear(); + CCommonConfigParse configParse; + std::string strFilePath = "../../common/sysconfig/"; + std::string strFileName = "shiftWidget.xml"; + if(kbdSuccess == configParse.load(strFilePath,strFileName)) + { + int num = 0; + if(kbdSuccess == configParse.getIntValue("shiftWidget","levelNum",num)) + { + + for(int index(1);index<=num;index++) + { + QString name = QString("level%1").arg(QString::number(index)); + int value = 0; + if(kbdSuccess == configParse.getIntValue("shiftWidget",name.toStdString(),value)) + { + m_keyAlmLevelList.append(value); + LOGDEBUG("loadXml() index:%d name:%s value:%d",index,name.toStdString().c_str(),value); + } + } + } + } +} + +QString HandoverWidget::bulidCondition() +{ + QString strFilter; + for(int nIndex = 0; nIndex < m_keyAlmLevelList.size(); nIndex++) + { + strFilter.append(QString::number(m_keyAlmLevelList.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); + } + return strFilter; +} + +void HandoverWidget::on_ConfirmButton_clicked() +{ + if(ui->comboBox->currentIndex()<0) + { + QMessageBox::critical(this,"提示","请选择接班班次"); + return; + } + + if(ui->NextGroupWidget->currentRow()<0) + { + QMessageBox::critical(this,"提示","请选择交班人员"); + return; + } + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + if(PERM_NORMAL>permMngPtr->CheckUserValid(ui->NameEdit->text().toStdString().data(),ui->PasswordEdit->text().toStdString().data())) + { + QMessageBox::critical(this,"用户验证错误","用户名或者密码错误"); + return; + } + } + + if(!m_pReadDb || !m_pReadDb->isOpen() + || !m_pWriteDb || !m_pWriteDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + return; + } + + QString strSql; + QSqlQuery objRet; + + DUTY_INFO Record; + strSql = "select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where START_TIME>'0' order by ID desc limit 1"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Record.ID=objRet.value(0).toInt(); + Record.GROUP_NAME=objRet.value(1).toString().toStdString(); + Record.USERS=objRet.value(2).toString().toStdString(); + Record.USERS_STATUS=objRet.value(3).toString().toStdString(); + Record.START_TIME=objRet.value(4).toString().toStdString(); + Record.END_TIME=objRet.value(5).toString().toStdString(); + Record.NOTE1=objRet.value(6).toString().toStdString(); + Record.NOTE2=objRet.value(7).toString().toStdString(); + Record.NOTE3=objRet.value(8).toString().toStdString(); + } + } + + QString Now_time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + strSql="update duty_info set END_TIME='"+Now_time+"' where ID="+QString::number(Record.ID,10); + if(!m_pWriteDb->execute(strSql)) + { + QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); + } + QString Users=""; + QString Name=""; + for(int i=0; iNextGroupWidget->rowCount(); i++) + { + Users += ui->NextGroupWidget->item(i, 0)->text(); + if(tr("已签到") == ui->NextGroupWidget->item(i, 1)->text()) + { + Name += "1"; + } + else + { + Name += "0"; + } + if(i != ui->NextGroupWidget->rowCount()-1) + { + Users += ","; + Name += ","; + } + } + + DUTY_INFO signIn; + strSql = QString("select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where ID>%1" + " and GROUP_NAME='%2' order by ID desc limit 1").arg(Record.ID).arg(ui->comboBox->currentText()); + m_pReadDb->execute(strSql,objRet); + bool isRet = false; + if(objRet.isActive()) + { + while(objRet.next()) + { + signIn.ID=objRet.value(0).toInt(); + signIn.GROUP_NAME=objRet.value(1).toString().toStdString(); + signIn.USERS=objRet.value(2).toString().toStdString(); + signIn.USERS_STATUS=objRet.value(3).toString().toStdString(); + signIn.START_TIME=objRet.value(4).toString().toStdString(); + signIn.END_TIME=objRet.value(5).toString().toStdString(); + signIn.NOTE1=objRet.value(6).toString().toStdString(); + signIn.NOTE2=objRet.value(7).toString().toStdString(); + signIn.NOTE3=objRet.value(8).toString().toStdString(); + isRet = true; + } + } + + if(isRet) + { + strSql=QString("update duty_info set START_TIME='%1' where ID=%2").arg(Now_time).arg(signIn.ID); + qDebug() << strSql; + if(!m_pWriteDb->execute(strSql)) + { + QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); + } + } + else + { + strSql="insert into duty_info (ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME) values (" + +QString::number((Record.ID+1),10)+",'"+ui->comboBox->currentText()+"','"+Users+"','"+Name+"','"+Now_time+"')"; + if(!m_pWriteDb->execute(strSql)) + { + QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); + } + } + + close(); +} + +void HandoverWidget::on_SignInButton_clicked() +{ + if(ui->NextGroupWidget->currentRow()<0) + { + QMessageBox::critical(this,"提示","请选择签到人员"); + return; + } + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + if(PERM_NORMAL != permMngPtr->CheckUserValid(ui->NameEdit->text().toStdString().data(),ui->PasswordEdit->text().toStdString().data())) + { + QMessageBox::critical(this,"用户验证错误","用户名或者密码错误"); + return; + } + + if(!m_pReadDb || !m_pReadDb->isOpen() + || !m_pWriteDb || !m_pWriteDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + return; + } + + QString strSql = "select ID from duty_info where START_TIME>'0' order by ID desc limit 1"; + QSqlQuery objRet; + int RecordMaxId = 0; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + RecordMaxId = objRet.value(0).toInt(); + } + } + + DUTY_INFO record; + strSql = QString("select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where ID>%1" + " and GROUP_NAME='%2' order by ID desc limit 1").arg(RecordMaxId).arg(ui->comboBox->currentText()); + m_pReadDb->execute(strSql,objRet); + bool isRet = false; + if(objRet.isActive()) + { + while(objRet.next()) + { + record.ID=objRet.value(0).toInt(); + record.GROUP_NAME=objRet.value(1).toString().toStdString(); + record.USERS=objRet.value(2).toString().toStdString(); + record.USERS_STATUS=objRet.value(3).toString().toStdString(); + record.START_TIME=objRet.value(4).toString().toStdString(); + record.END_TIME=objRet.value(5).toString().toStdString(); + record.NOTE1=objRet.value(6).toString().toStdString(); + record.NOTE2=objRet.value(7).toString().toStdString(); + record.NOTE3=objRet.value(8).toString().toStdString(); + isRet = true; + } + } + + QString Users=""; + QString Name=""; + QString curText; + for(int i=0; iNextGroupWidget->rowCount(); i++) + { + curText = ui->NextGroupWidget->item(i, 0)->text(); + Users += curText; + if(curText == ui->NextGroupWidget->item(ui->NextGroupWidget->currentRow(), 0)->text() + || tr("已签到") == ui->NextGroupWidget->item(i, 1)->text()) + { + Name += "1"; + } + else + { + Name += "0"; + } + if(i != ui->NextGroupWidget->rowCount()-1) + { + Users += ","; + Name += ","; + } + } + + if(isRet) + { + strSql = QString("update duty_info set USERS_STATUS='%1' where ID=%2").arg(Name).arg(record.ID); + if(!m_pWriteDb->execute(strSql)) + { + QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); + return; + } + } + else + { + int MaxId = 0; + strSql = "select ID from duty_info order by ID desc limit 1"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + MaxId = objRet.value(0).toInt(); + } + } + + strSql="insert into duty_info (ID,GROUP_NAME,USERS,USERS_STATUS) values (" + +QString::number((MaxId+1),10)+",'"+ui->comboBox->currentText()+"','"+Users+"','"+Name+"')"; + if(!m_pWriteDb->execute(strSql)) + { + QMessageBox::critical(this,"提示",m_pWriteDb->getLastErrorString()); + return; + } + } + + ui->NextGroupWidget->setItem(ui->NextGroupWidget->currentRow(),1,new QTableWidgetItem(tr("已签到"))); + ui->NextGroupWidget->item(ui->NextGroupWidget->currentRow(),1)->setTextAlignment(Qt::AlignCenter); + } +} + +void HandoverWidget::on_comboBox_currentIndexChanged(const QString &arg1) +{ + ui->NextGroupWidget->setRowCount(0); + ui->NameEdit->setText(""); + + if(!m_pReadDb || !m_pReadDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + return; + } + + QString strSql = "select ID from duty_info where START_TIME>'0' order by ID desc limit 1"; + QSqlQuery objRet; + int RecordMaxId = 0; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + RecordMaxId = objRet.value(0).toInt(); + } + } + + QString strlist; + QStringList aliaslist; + DUTY_INFO record; + strSql = QString("select ID,GROUP_NAME,USERS,USERS_STATUS,START_TIME,END_TIME,NOTE1,NOTE2,NOTE3 from duty_info where ID>%1" + " and GROUP_NAME='%2' order by ID desc limit 1").arg(RecordMaxId).arg(arg1); + m_pReadDb->execute(strSql,objRet); + bool isRet = false; + if(objRet.isActive()) + { + while(objRet.next()) + { + record.ID=objRet.value(0).toInt(); + record.GROUP_NAME=objRet.value(1).toString().toStdString(); + record.USERS=objRet.value(2).toString().toStdString(); + record.USERS_STATUS=objRet.value(3).toString().toStdString(); + record.START_TIME=objRet.value(4).toString().toStdString(); + record.END_TIME=objRet.value(5).toString().toStdString(); + record.NOTE1=objRet.value(6).toString().toStdString(); + record.NOTE2=objRet.value(7).toString().toStdString(); + record.NOTE3=objRet.value(8).toString().toStdString(); + isRet = true; + } + } + if(isRet) + { + aliaslist=QString::fromStdString(record.USERS).split(","); + QStringList statusList=QString::fromStdString(record.USERS_STATUS).split(","); + + for(int j=0;jNextGroupWidget->insertRow(ui->NextGroupWidget->rowCount()); + ui->NextGroupWidget->setItem(j,0,new QTableWidgetItem(aliaslist[j])); + if(statusList.value(j,"0") == "1") + { + ui->NextGroupWidget->setItem(j,1,new QTableWidgetItem(tr("已签到"))); + } + else + { + ui->NextGroupWidget->setItem(j,1,new QTableWidgetItem(tr("未签到"))); + } + ui->NextGroupWidget->item(j,0)->setTextAlignment(Qt::AlignCenter); + ui->NextGroupWidget->item(j,1)->setTextAlignment(Qt::AlignCenter); + } + } + else + { + for(size_t i=0;i::iterator it = m_mapUser.find(strUserAlias.toStdString()); + if (it != m_mapUser.end())//找到 + { + strUserAlias = QString(it->second.PERM_ALIAS.c_str()); + } + ui->NextGroupWidget->insertRow(ui->NextGroupWidget->rowCount()); + ui->NextGroupWidget->setItem(j,0,new QTableWidgetItem(strUserAlias)); + ui->NextGroupWidget->item(j,0)->setTextAlignment(Qt::AlignCenter); + ui->NextGroupWidget->setItem(j,1,new QTableWidgetItem(tr("未签到"))); + ui->NextGroupWidget->item(j,1)->setTextAlignment(Qt::AlignCenter); + } + } + } + } +} + +void HandoverWidget::on_NextGroupWidget_cellClicked(int row, int column) +{ + Q_UNUSED(column) + //ui->NameEdit->setText(ui->NextGroupWidget->item(row,0)->text()); + ui->NameEdit->clear(); + for(size_t i=0;iNextGroupWidget->item(row,0)->text()) + { + ui->NameEdit->setText(m_Users.at(i).PERM_NAME.c_str()); + } + } + ui->PasswordEdit->setText(""); +} + +void HandoverWidget::on_PushButton1_clicked() +{ + if(ui->ListWidget1->isVisible()==false) + { + ui->ListWidget1->setVisible(true); + } + else if(ui->ListWidget1->isVisible()==true) + { + ui->ListWidget1->setVisible(false); + } +} + +void HandoverWidget::on_PushButton2_clicked() +{ + if(!m_pReadDb || !m_pReadDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + return; + } + + if(ui->ListWidget2->isVisible()==false) + { + ui->ListWidget2->setVisible(true); + ui->ListWidget2->clear(); + + QString strSql; + QSqlQuery objRet; + + if(m_isFarm==true) + { + QDateTime date_time=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + qint64 msecTime=date_time.toSecsSinceEpoch(); + + std::vector Tickets; + HIS_WORK_TICKET Ticket; + strSql = "select CREATE_TIME,REQUESTER,FILE_PATH from his_work_ticket where CREATE_TIME>"+QString::number(msecTime,10); + qDebug() << strSql; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Ticket.CREATE_TIME=objRet.value(0).toInt(); + Ticket.REQUESTER=objRet.value(1).toString().toStdString(); + QString strTemp = objRet.value(2).toString(); + QStringList sList = strTemp.split("/data/"); + if(sList.count()>0) + { + Ticket.FILE_PATH = sList.at(sList.count()-1).toStdString(); + } + else + { + Ticket.FILE_PATH=objRet.value(2).toString().toStdString(); + } + + Tickets.push_back(Ticket); + } + } + ui->PushButton2->setText("工作票-"+QString::number(Tickets.size(),10)); + QString create_time; + QDateTime Ticket_date_time; + for(size_t i=0;iListWidget2->addItem(create_time+" 申请人:"+Tickets.at(i).REQUESTER.c_str()+" 文件路径:data/"+Tickets.at(i).FILE_PATH.c_str()); + } + ui->ListWidget2->setMinimumHeight(ui->ListWidget2->sizeHintForRow(0)*(int)Tickets.size()+4); + } + else + { + QDateTime date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + qint64 msecTime_start=date_time_start.toSecsSinceEpoch(); + + QDateTime date_time_end=QDateTime::fromString(Records.at(0).END_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + qint64 msecTime_end=date_time_end.toSecsSinceEpoch(); + + std::vector Tickets; + HIS_WORK_TICKET Ticket; + strSql = "select CREATE_TIME,REQUESTER,FILE_PATH from his_work_ticket where CREATE_TIME>="+QString::number(msecTime_start,10)+" and CREATE_TIME<"+QString::number(msecTime_end,10); + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Ticket.CREATE_TIME=objRet.value(0).toInt(); + Ticket.REQUESTER=objRet.value(1).toString().toStdString(); + Ticket.FILE_PATH=objRet.value(2).toString().toStdString(); + QString strTemp = objRet.value(2).toString(); + QStringList sList = strTemp.split("/data/"); + if(sList.count()>0) + { + Ticket.FILE_PATH = sList.at(sList.count()-1).toStdString(); + } + else + { + Ticket.FILE_PATH=objRet.value(2).toString().toStdString(); + } + Tickets.push_back(Ticket); + } + } + ui->PushButton2->setText("工作票-"+QString::number(Tickets.size(),10)); + QString create_time; + QDateTime Ticket_date_time; + for(size_t i=0;iListWidget2->addItem(create_time+" 申请人:"+Tickets.at(i).REQUESTER.c_str()+" 文件路径:data/"+Tickets.at(i).FILE_PATH.c_str()); + } + ui->ListWidget2->setMinimumHeight(ui->ListWidget2->sizeHintForRow(0)*(int)Tickets.size()+4); + } + } + else if(ui->ListWidget2->isVisible()==true) + { + ui->ListWidget2->setVisible(false); + } +} + +void HandoverWidget::on_PushButton3_clicked() +{ + if(ui->ListWidget3->isVisible()==false) + { + //ui->ListWidget3->setVisible(true); + //ui->ListWidget3->clear(); + + QDateTime date_time_start; + QDateTime date_time_end; + + if(m_isFarm==true) + { + date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + date_time_end=QDateTime::currentDateTime(); + + //QueryThread *m_thread; + if(m_thread_Events) + { + delete m_thread_Events; + m_thread_Events=NULL; + } + m_thread_Events=new QueryThread(); + m_thread_Events->start_time=date_time_start; + m_thread_Events->end_time=date_time_end; + m_thread_Events->isEvent=true; + + qRegisterMetaType>("std::vector"); + connect(m_thread_Events,&QueryThread::signal_QueryEnd_Event,this,&HandoverWidget::slot_QueryEnd_Event); + + m_thread_Events->start(); + } + else + { + date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + date_time_end=QDateTime::fromString(Records.at(0).END_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + + //QueryThread *m_thread; + if(m_thread_Events_Operates) + { + delete m_thread_Events_Operates; + m_thread_Events_Operates=NULL; + } + m_thread_Events_Operates=new QueryThread(); + m_thread_Events_Operates->start_time=date_time_start; + m_thread_Events_Operates->end_time=date_time_end; + m_thread_Events_Operates->isEvent=true; + + qRegisterMetaType>("std::vector"); + connect(m_thread_Events_Operates,&QueryThread::signal_QueryEnd_Event,this,&HandoverWidget::slot_QueryEnd_Event); + + m_thread_Events_Operates->start(); + } + } + else if(ui->ListWidget3->isVisible()==true) + { + ui->ListWidget3->setVisible(false); + } +} + +void HandoverWidget::on_PushButton4_clicked() +{ + if(ui->ListWidget4->isVisible()==false) + { + //ui->ListWidget4->setVisible(true); + //ui->ListWidget4->clear(); + + QDateTime date_time_start; + QDateTime date_time_end; + + if(m_isFarm==true) + { + date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + date_time_end=QDateTime::currentDateTime(); + + //QueryThread *m_thread; + if(m_thread_Events) + { + delete m_thread_Events; + m_thread_Events=NULL; + } + m_thread_Events=new QueryThread(); + m_thread_Events->start_time=date_time_start; + m_thread_Events->end_time=date_time_end; + m_thread_Events->isEvent_Operate=true; + + qRegisterMetaType>("std::vector"); + connect(m_thread_Events,&QueryThread::signal_QueryEnd_Event_Operate,this,&HandoverWidget::slot_QueryEnd_Event_Operate); + + m_thread_Events->start(); + } + else + { + date_time_start=QDateTime::fromString(Records.at(0).START_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + date_time_end=QDateTime::fromString(Records.at(0).END_TIME.c_str(),"yyyy-MM-dd hh:mm:ss"); + + //QueryThread *m_thread; + if(m_thread_Events_Operates) + { + delete m_thread_Events_Operates; + m_thread_Events_Operates=NULL; + } + m_thread_Events_Operates=new QueryThread(); + m_thread_Events_Operates->start_time=date_time_start; + m_thread_Events_Operates->end_time=date_time_end; + m_thread_Events_Operates->isEvent_Operate=true; + + qRegisterMetaType>("std::vector"); + connect(m_thread_Events_Operates,&QueryThread::signal_QueryEnd_Event_Operate,this,&HandoverWidget::slot_QueryEnd_Event_Operate); + + m_thread_Events_Operates->start(); + } + } + else if(ui->ListWidget4->isVisible()==true) + { + ui->ListWidget4->setVisible(false); + } +} + +void HandoverWidget::slot_QueryEnd_Event(std::vector m_Events) +{ + ui->ListWidget3->setVisible(true); + ui->ListWidget3->clear(); + + QDateTime date_time; + QString time; + ui->PushButton3->setText("关键告警-"+QString::number(m_Events.size(),10)); + for(size_t i=0;iListWidget3->addItem(time+" "+m_Events.at(i).CONTENT.c_str()); + } + ui->ListWidget3->setMinimumHeight(ui->ListWidget3->sizeHintForRow(0)*(int)m_Events.size()+4); + + if(m_thread_Events) + { + delete m_thread_Events; + m_thread_Events=NULL; + } + //QApplication::restoreOverrideCursor(); +} + +void HandoverWidget::slot_QueryEnd_Event_Operate(std::vector m_Events_Operates) +{ + ui->ListWidget4->setVisible(true); + ui->ListWidget4->clear(); + + QDateTime date_time; + QString time; + ui->PushButton4->setText("操作记录-"+QString::number(m_Events_Operates.size(),10)); + for(size_t i=0;iListWidget4->addItem(time+" "+m_Events_Operates.at(i).CONTENT.c_str()); + } + ui->ListWidget4->setMinimumHeight(ui->ListWidget4->sizeHintForRow(0)*(int)m_Events_Operates.size()+4); + + if(m_thread_Events_Operates) + { + delete m_thread_Events_Operates; + m_thread_Events_Operates=NULL; + } + //QApplication::restoreOverrideCursor(); +} diff --git a/product/src/gui/plugin/ShiftWidget/HandoverWidget.h b/product/src/gui/plugin/ShiftWidget/HandoverWidget.h index 87299b80..b7af3efc 100644 --- a/product/src/gui/plugin/ShiftWidget/HandoverWidget.h +++ b/product/src/gui/plugin/ShiftWidget/HandoverWidget.h @@ -1,80 +1,80 @@ -#ifndef HANDOVERWIDGET_H -#define HANDOVERWIDGET_H - -#include -#include "db_api_ex/CDbApi.h" -#include "ShiftCommon.h" -#include "perm_mng_api/PermMngApi.h" -#include "QueryThread.h" - -using namespace kbd_service; - -namespace Ui { -class HandoverWidget; -} - -class HandoverWidget : public QDialog -{ - Q_OBJECT - -public: - explicit HandoverWidget(QWidget *parent = 0,kbd_dbms::CDbApi *dbRead = NULL,kbd_dbms::CDbApi *dbWrite = NULL,bool isFarm = true,QString begin_time=""); - ~HandoverWidget(); - - void Init(); - - void InitFarm(); - - void InitNoFarm(); - - void InitData(); - - void loadXml(); - - QString bulidCondition(); - -private slots: - - - void on_ConfirmButton_clicked(); - - void on_SignInButton_clicked(); - - void on_comboBox_currentIndexChanged(const QString &arg1); - - void on_NextGroupWidget_cellClicked(int row, int column); - - void on_PushButton3_clicked(); - - void on_PushButton1_clicked(); - - void on_PushButton2_clicked(); - - void on_PushButton4_clicked(); -protected slots: - void slot_QueryEnd_Event(std::vector m_Events); - void slot_QueryEnd_Event_Operate(std::vector m_Events_Operates); - - -private: - Ui::HandoverWidget *ui; - - kbd_dbms::CDbApi *m_pReadDb; - kbd_dbms::CDbApi *m_pWriteDb; - - bool m_isFarm; - QString m_begin_time; - - QueryThread *m_thread_Events; - QueryThread *m_thread_Events_Operates; - - std::vector Records; - std::vector m_Groups; - std::vector m_Date_Groups; - std::vector m_Users; - std::map m_mapUser; - QList m_keyAlmLevelList; - -}; - -#endif // HANDOVERWIDGET_H +#ifndef HANDOVERWIDGET_H +#define HANDOVERWIDGET_H + +#include +#include "db_api_ex/CDbApi.h" +#include "ShiftCommon.h" +#include "perm_mng_api/PermMngApi.h" +#include "QueryThread.h" + +using namespace kbd_service; + +namespace Ui { +class HandoverWidget; +} + +class HandoverWidget : public QDialog +{ + Q_OBJECT + +public: + explicit HandoverWidget(QWidget *parent = 0,kbd_dbms::CDbApi *dbRead = NULL,kbd_dbms::CDbApi *dbWrite = NULL,bool isFarm = true,QString begin_time=""); + ~HandoverWidget(); + + void Init(); + + void InitFarm(); + + void InitNoFarm(); + + void InitData(); + + void loadXml(); + + QString bulidCondition(); + +private slots: + + + void on_ConfirmButton_clicked(); + + void on_SignInButton_clicked(); + + void on_comboBox_currentIndexChanged(const QString &arg1); + + void on_NextGroupWidget_cellClicked(int row, int column); + + void on_PushButton3_clicked(); + + void on_PushButton1_clicked(); + + void on_PushButton2_clicked(); + + void on_PushButton4_clicked(); +protected slots: + void slot_QueryEnd_Event(std::vector m_Events); + void slot_QueryEnd_Event_Operate(std::vector m_Events_Operates); + + +private: + Ui::HandoverWidget *ui; + + kbd_dbms::CDbApi *m_pReadDb; + kbd_dbms::CDbApi *m_pWriteDb; + + bool m_isFarm; + QString m_begin_time; + + QueryThread *m_thread_Events; + QueryThread *m_thread_Events_Operates; + + std::vector Records; + std::vector m_Groups; + std::vector m_Date_Groups; + std::vector m_Users; + std::map m_mapUser; + QList m_keyAlmLevelList; + +}; + +#endif // HANDOVERWIDGET_H diff --git a/product/src/gui/plugin/ShiftWidget/HandoverWidget.ui b/product/src/gui/plugin/ShiftWidget/HandoverWidget.ui index 03bea2c0..e2678a3c 100644 --- a/product/src/gui/plugin/ShiftWidget/HandoverWidget.ui +++ b/product/src/gui/plugin/ShiftWidget/HandoverWidget.ui @@ -1,427 +1,427 @@ - - - HandoverWidget - - - - 0 - 0 - 849 - 609 - - - - 交接班 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - - 0 - 0 - 845 - 405 - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::ElideRight - - - QAbstractItemView::ScrollPerPixel - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - 操作记录 - - - - - - - 值班信息 - - - - - - - 关键告警 - - - - - - - 工作票 - - - - - - - - - - - - - - - - - - - - - 16777215 - 200 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 6 - - - 6 - - - 6 - - - 6 - - - 6 - - - - - 交班班组: - - - - - - - Qt::Horizontal - - - - 120 - 20 - - - - - - - - - - - - - 6 - - - 6 - - - 6 - - - 6 - - - 6 - - - - - 接班班组: - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 20 - - - - - - - - Qt::Horizontal - - - - 20 - 20 - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 55 - - - - - - - - Qt::Horizontal - - - - 92 - 20 - - - - - - - - 15 - - - - - - - 接班员 - - - - - - - - - - 密码 - - - - - - - - - - - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - 接班签到 - - - - - - - - 80 - 0 - - - - - 80 - 16777215 - - - - 确认交接 - - - - - - - - - - - Qt::Horizontal - - - - 91 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 56 - - - - - - - - - - - - - - - + + + HandoverWidget + + + + 0 + 0 + 849 + 609 + + + + 交接班 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 845 + 405 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::ElideRight + + + QAbstractItemView::ScrollPerPixel + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 操作记录 + + + + + + + 值班信息 + + + + + + + 关键告警 + + + + + + + 工作票 + + + + + + + + + + + + + + + + + + + + + 16777215 + 200 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + 6 + + + 6 + + + 6 + + + 6 + + + + + 交班班组: + + + + + + + Qt::Horizontal + + + + 120 + 20 + + + + + + + + + + + + + 6 + + + 6 + + + 6 + + + 6 + + + 6 + + + + + 接班班组: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 20 + + + + + + + + Qt::Horizontal + + + + 20 + 20 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 55 + + + + + + + + Qt::Horizontal + + + + 92 + 20 + + + + + + + + 15 + + + + + + + 接班员 + + + + + + + + + + 密码 + + + + + + + + + + + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + 接班签到 + + + + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + 确认交接 + + + + + + + + + + + Qt::Horizontal + + + + 91 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 56 + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/ShiftWidget/QueryThread.cpp b/product/src/gui/plugin/ShiftWidget/QueryThread.cpp index 4b53fb06..828c8125 100644 --- a/product/src/gui/plugin/ShiftWidget/QueryThread.cpp +++ b/product/src/gui/plugin/ShiftWidget/QueryThread.cpp @@ -1,126 +1,126 @@ -#include "QueryThread.h" -#include "pub_utility_api/CommonConfigParse.h" -#include "Common.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_public; - -QueryThread::QueryThread() -{ - isStop=false; - isEvent=false; - isEvent_Operate=false; - loadXml(); - m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); - m_pReadDb->open(); -} - -void QueryThread::closeThread() -{ - if(m_pReadDb) - { - m_pReadDb->close(); - delete m_pReadDb; - m_pReadDb=NULL; - } - isStop=true; -} - -void QueryThread::loadXml() -{ - m_keyAlmLevelList.clear(); - CCommonConfigParse configParse; - std::string strFilePath = "../../common/sysconfig/"; - std::string strFileName = "shiftWidget.xml"; - if(kbdSuccess == configParse.load(strFilePath,strFileName)) - { - int num = 0; - if(kbdSuccess == configParse.getIntValue("shiftWidget","levelNum",num)) - { - - for(int index(1);index<=num;index++) - { - QString name = QString("level%1").arg(QString::number(index)); - int value = 0; - if(kbdSuccess == configParse.getIntValue("shiftWidget",name.toStdString(),value)) - { - m_keyAlmLevelList.append(value); - LOGDEBUG("loadXml() index:%d name:%s value:%d",index,name.toStdString().c_str(),value); - } - } - } - } -} - -QString QueryThread::bulidCondition() -{ - QString strFilter; - for(int nIndex = 0; nIndex < m_keyAlmLevelList.size(); nIndex++) - { - strFilter.append(QString::number(m_keyAlmLevelList.at(nIndex)) + ", "); - } - - if(!strFilter.isEmpty()) - { - strFilter.resize(strFilter.size() - 2); - strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); - } - return strFilter; -} - -void QueryThread::run() -{ - if(!m_pReadDb->isOpen()) - { - return; - } - QString strSql; - QSqlQuery objRet; - qint64 msecTime_start=start_time.toMSecsSinceEpoch(); - qint64 msecTime_end=end_time.toMSecsSinceEpoch(); - - HIS_EVENT Event; - - if(isEvent==true) - { - m_Events.clear(); - - QString strCondition = bulidCondition(); - if(strCondition.isEmpty()) - { - strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; - }else - { - strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" and "+strCondition+" order by TIME_STAMP desc limit 1000"; - } - LOGDEBUG("alm-sql3:%s",strSql.toStdString().c_str()); - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Event.TIME_STAMP=objRet.value(0).toLongLong(); - Event.CONTENT=objRet.value(1).toString().toStdString(); - m_Events.push_back(Event); - } - } - emit signal_QueryEnd_Event(m_Events); - } - - if(isEvent_Operate==true) - { - m_Events_Operates.clear(); - strSql = "select TIME_STAMP,CONTENT from his_event where ALM_TYPE=4 and TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Event.TIME_STAMP=objRet.value(0).toLongLong(); - Event.CONTENT=objRet.value(1).toString().toStdString(); - m_Events_Operates.push_back(Event); - } - } - } - emit signal_QueryEnd_Event_Operate(m_Events_Operates); -} +#include "QueryThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "Common.h" +#include "pub_logger_api/logger.h" + +using namespace kbd_public; + +QueryThread::QueryThread() +{ + isStop=false; + isEvent=false; + isEvent_Operate=false; + loadXml(); + m_pReadDb = new kbd_dbms::CDbApi(DB_CONN_HIS_READ); + m_pReadDb->open(); +} + +void QueryThread::closeThread() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + m_pReadDb=NULL; + } + isStop=true; +} + +void QueryThread::loadXml() +{ + m_keyAlmLevelList.clear(); + CCommonConfigParse configParse; + std::string strFilePath = "../../common/sysconfig/"; + std::string strFileName = "shiftWidget.xml"; + if(kbdSuccess == configParse.load(strFilePath,strFileName)) + { + int num = 0; + if(kbdSuccess == configParse.getIntValue("shiftWidget","levelNum",num)) + { + + for(int index(1);index<=num;index++) + { + QString name = QString("level%1").arg(QString::number(index)); + int value = 0; + if(kbdSuccess == configParse.getIntValue("shiftWidget",name.toStdString(),value)) + { + m_keyAlmLevelList.append(value); + LOGDEBUG("loadXml() index:%d name:%s value:%d",index,name.toStdString().c_str(),value); + } + } + } + } +} + +QString QueryThread::bulidCondition() +{ + QString strFilter; + for(int nIndex = 0; nIndex < m_keyAlmLevelList.size(); nIndex++) + { + strFilter.append(QString::number(m_keyAlmLevelList.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); + } + return strFilter; +} + +void QueryThread::run() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QString strSql; + QSqlQuery objRet; + qint64 msecTime_start=start_time.toMSecsSinceEpoch(); + qint64 msecTime_end=end_time.toMSecsSinceEpoch(); + + HIS_EVENT Event; + + if(isEvent==true) + { + m_Events.clear(); + + QString strCondition = bulidCondition(); + if(strCondition.isEmpty()) + { + strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; + }else + { + strSql = "select TIME_STAMP,CONTENT from his_intelli_alm where TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" and "+strCondition+" order by TIME_STAMP desc limit 1000"; + } + LOGDEBUG("alm-sql3:%s",strSql.toStdString().c_str()); + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Event.TIME_STAMP=objRet.value(0).toLongLong(); + Event.CONTENT=objRet.value(1).toString().toStdString(); + m_Events.push_back(Event); + } + } + emit signal_QueryEnd_Event(m_Events); + } + + if(isEvent_Operate==true) + { + m_Events_Operates.clear(); + strSql = "select TIME_STAMP,CONTENT from his_event where ALM_TYPE=4 and TIME_STAMP>="+QString::number(msecTime_start,10)+" and TIME_STAMP<"+QString::number(msecTime_end,10)+" order by TIME_STAMP desc limit 1000"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Event.TIME_STAMP=objRet.value(0).toLongLong(); + Event.CONTENT=objRet.value(1).toString().toStdString(); + m_Events_Operates.push_back(Event); + } + } + } + emit signal_QueryEnd_Event_Operate(m_Events_Operates); +} diff --git a/product/src/gui/plugin/ShiftWidget/QueryThread.h b/product/src/gui/plugin/ShiftWidget/QueryThread.h index 498d8f59..dc70dbba 100644 --- a/product/src/gui/plugin/ShiftWidget/QueryThread.h +++ b/product/src/gui/plugin/ShiftWidget/QueryThread.h @@ -1,42 +1,42 @@ -#ifndef QUERYTHREAD_H -#define QUERYTHREAD_H - -#include -#include "db_api_ex/CDbApi.h" -#include "ShiftCommon.h" - -class QueryThread : public QThread -{ - Q_OBJECT -public: - QueryThread(); - - void closeThread(); - - QDateTime start_time; - QDateTime end_time; - - bool isEvent; - bool isEvent_Operate; - - void loadXml(); - - QString bulidCondition(); - -signals: - void signal_QueryEnd_Event(std::vector m_Events); - void signal_QueryEnd_Event_Operate(std::vector m_Events_Operates); - -protected: - virtual void run(); -private: - volatile bool isStop; - - std::vector m_Events; - std::vector m_Events_Operates; - - kbd_dbms::CDbApi *m_pReadDb; - QList m_keyAlmLevelList; -}; - -#endif // QUERYTHREAD_H +#ifndef QUERYTHREAD_H +#define QUERYTHREAD_H + +#include +#include "db_api_ex/CDbApi.h" +#include "ShiftCommon.h" + +class QueryThread : public QThread +{ + Q_OBJECT +public: + QueryThread(); + + void closeThread(); + + QDateTime start_time; + QDateTime end_time; + + bool isEvent; + bool isEvent_Operate; + + void loadXml(); + + QString bulidCondition(); + +signals: + void signal_QueryEnd_Event(std::vector m_Events); + void signal_QueryEnd_Event_Operate(std::vector m_Events_Operates); + +protected: + virtual void run(); +private: + volatile bool isStop; + + std::vector m_Events; + std::vector m_Events_Operates; + + kbd_dbms::CDbApi *m_pReadDb; + QList m_keyAlmLevelList; +}; + +#endif // QUERYTHREAD_H diff --git a/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.cpp b/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.cpp index 3dbca3fd..228355fb 100644 --- a/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.cpp +++ b/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.cpp @@ -1,127 +1,127 @@ -#include "SelectGroupWidget.h" -#include "ui_SelectGroupWidget.h" -#include - -SelectGroupWidget::SelectGroupWidget(QWidget *parent, kbd_dbms::CDbApi *dbRead, kbd_dbms::CDbApi *dbWrite) : - QDialog(parent), - m_pReadDb(dbRead), - m_pWriteDb(dbWrite), - ui(new Ui::SelectGroupWidget) -{ - ui->setupUi(this); - this->setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); - Init(); -} - -SelectGroupWidget::~SelectGroupWidget() -{ - delete ui; -} - -void SelectGroupWidget::Init() -{ - if(!m_pReadDb || !m_pReadDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - close(); - } - - QString strSql; - QSqlQuery objRet; - - Users.clear(); - RM_USER_DEF User; - strSql = "select PERM_ID,PERM_NAME,PERM_ALIAS from rm_user_def"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - User.PERM_ID=objRet.value(0).toInt(); - User.PERM_NAME=objRet.value(1).toString().toStdString(); - User.PERM_ALIAS=objRet.value(2).toString().toStdString(); - Users.push_back(User); - } - } - - m_Groups.clear(); - DUTY_DEFINE Group; - strSql = "select ID,NAME,START_TIME,END_TIME from duty_define"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Group.ID=objRet.value(0).toInt(); - Group.GROUP_NAME=objRet.value(1).toString().toStdString(); - Group.START_TIME=objRet.value(2).toString().toStdString(); - Group.END_TIME=objRet.value(3).toString().toStdString(); - m_Groups.push_back(Group); - } - } - - QString str=QDate::currentDate().toString("yyyy-MM-dd"); - m_Date_Groups.clear(); - DUTY_SETTING Date_Group; - strSql = "select DATE,DUTY_DEFINE_ID,USERS from duty_setting where DATE='"+str+"'"; - m_pReadDb->execute(strSql,objRet); - if(objRet.isActive()) - { - while(objRet.next()) - { - Date_Group.DATE=objRet.value(0).toString().toStdString(); - Date_Group.DUTY_DEFINE_ID=objRet.value(1).toString().toStdString(); - Date_Group.USERS=objRet.value(2).toString().toStdString(); - m_Date_Groups.push_back(Date_Group); - } - } - - for(int i=0;iComboBox->addItem(m_Groups.at(j).NAME.c_str()); - } - } -} - -void SelectGroupWidget::on_OkButton_clicked() -{ - if(!m_pWriteDb || !m_pWriteDb->isOpen()) - { - QMessageBox::critical(this,"提示","数据库接口未打开"); - close(); - } - - for(int i=0;iComboBox->currentText()) - { - QString strSql; - - QString Now_time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); - QString strlist=Groups.at(i).USERS.c_str(); - QStringList list=strlist.split(","); - QString Name=""; - for(int j=0;jComboBox->currentText()+"','"+Groups.at(i).USERS.c_str()+"','"+Name+"','"+Now_time+"')"; - m_pWriteDb->execute(strSql); - } - } - close(); -} +#include "SelectGroupWidget.h" +#include "ui_SelectGroupWidget.h" +#include + +SelectGroupWidget::SelectGroupWidget(QWidget *parent, kbd_dbms::CDbApi *dbRead, kbd_dbms::CDbApi *dbWrite) : + QDialog(parent), + m_pReadDb(dbRead), + m_pWriteDb(dbWrite), + ui(new Ui::SelectGroupWidget) +{ + ui->setupUi(this); + this->setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); + Init(); +} + +SelectGroupWidget::~SelectGroupWidget() +{ + delete ui; +} + +void SelectGroupWidget::Init() +{ + if(!m_pReadDb || !m_pReadDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + close(); + } + + QString strSql; + QSqlQuery objRet; + + Users.clear(); + RM_USER_DEF User; + strSql = "select PERM_ID,PERM_NAME,PERM_ALIAS from rm_user_def"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + User.PERM_ID=objRet.value(0).toInt(); + User.PERM_NAME=objRet.value(1).toString().toStdString(); + User.PERM_ALIAS=objRet.value(2).toString().toStdString(); + Users.push_back(User); + } + } + + m_Groups.clear(); + DUTY_DEFINE Group; + strSql = "select ID,NAME,START_TIME,END_TIME from duty_define"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Group.ID=objRet.value(0).toInt(); + Group.GROUP_NAME=objRet.value(1).toString().toStdString(); + Group.START_TIME=objRet.value(2).toString().toStdString(); + Group.END_TIME=objRet.value(3).toString().toStdString(); + m_Groups.push_back(Group); + } + } + + QString str=QDate::currentDate().toString("yyyy-MM-dd"); + m_Date_Groups.clear(); + DUTY_SETTING Date_Group; + strSql = "select DATE,DUTY_DEFINE_ID,USERS from duty_setting where DATE='"+str+"'"; + m_pReadDb->execute(strSql,objRet); + if(objRet.isActive()) + { + while(objRet.next()) + { + Date_Group.DATE=objRet.value(0).toString().toStdString(); + Date_Group.DUTY_DEFINE_ID=objRet.value(1).toString().toStdString(); + Date_Group.USERS=objRet.value(2).toString().toStdString(); + m_Date_Groups.push_back(Date_Group); + } + } + + for(int i=0;iComboBox->addItem(m_Groups.at(j).NAME.c_str()); + } + } +} + +void SelectGroupWidget::on_OkButton_clicked() +{ + if(!m_pWriteDb || !m_pWriteDb->isOpen()) + { + QMessageBox::critical(this,"提示","数据库接口未打开"); + close(); + } + + for(int i=0;iComboBox->currentText()) + { + QString strSql; + + QString Now_time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); + QString strlist=Groups.at(i).USERS.c_str(); + QStringList list=strlist.split(","); + QString Name=""; + for(int j=0;jComboBox->currentText()+"','"+Groups.at(i).USERS.c_str()+"','"+Name+"','"+Now_time+"')"; + m_pWriteDb->execute(strSql); + } + } + close(); +} diff --git a/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.h b/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.h index 74475969..8815a22e 100644 --- a/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.h +++ b/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.h @@ -1,35 +1,35 @@ -#ifndef SELECTGROUPWIDGET_H -#define SELECTGROUPWIDGET_H - -#include -#include "db_api_ex/CDbApi.h" -#include "ShiftCommon.h" - -namespace Ui { -class SelectGroupWidget; -} - -class SelectGroupWidget : public QDialog -{ - Q_OBJECT - -public: - explicit SelectGroupWidget(QWidget *parent = 0,kbd_dbms::CDbApi *dbRead = NULL,kbd_dbms::CDbApi *dbWrite = NULL); - ~SelectGroupWidget(); -private slots: - void on_OkButton_clicked(); - -private: - void Init(); - -private: - Ui::SelectGroupWidget *ui; - - kbd_dbms::CDbApi *m_pReadDb; - kbd_dbms::CDbApi *m_pWriteDb; - std::vector m_Groups; - std::vector m_Date_Groups; - std::vector Users; -}; - -#endif // SELECTGROUPWIDGET_H +#ifndef SELECTGROUPWIDGET_H +#define SELECTGROUPWIDGET_H + +#include +#include "db_api_ex/CDbApi.h" +#include "ShiftCommon.h" + +namespace Ui { +class SelectGroupWidget; +} + +class SelectGroupWidget : public QDialog +{ + Q_OBJECT + +public: + explicit SelectGroupWidget(QWidget *parent = 0,kbd_dbms::CDbApi *dbRead = NULL,kbd_dbms::CDbApi *dbWrite = NULL); + ~SelectGroupWidget(); +private slots: + void on_OkButton_clicked(); + +private: + void Init(); + +private: + Ui::SelectGroupWidget *ui; + + kbd_dbms::CDbApi *m_pReadDb; + kbd_dbms::CDbApi *m_pWriteDb; + std::vector m_Groups; + std::vector m_Date_Groups; + std::vector Users; +}; + +#endif // SELECTGROUPWIDGET_H diff --git a/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.ui b/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.ui index 19e90975..bcca02d2 100644 --- a/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.ui +++ b/product/src/gui/plugin/ShiftWidget/SelectGroupWidget.ui @@ -1,55 +1,55 @@ - - - SelectGroupWidget - - - - 0 - 0 - 149 - 88 - - - - 请选择当前班组 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - 确定 - - - - - - - - - - - + + + SelectGroupWidget + + + + 0 + 0 + 149 + 88 + + + + 请选择当前班组 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + 确定 + + + + + + + + + + + diff --git a/product/src/gui/plugin/ShiftWidget/ShiftCommon.h b/product/src/gui/plugin/ShiftWidget/ShiftCommon.h index baceecb9..08c16c0d 100644 --- a/product/src/gui/plugin/ShiftWidget/ShiftCommon.h +++ b/product/src/gui/plugin/ShiftWidget/ShiftCommon.h @@ -1,55 +1,55 @@ -#ifndef SHIFTCOMMON_H -#define SHIFTCOMMON_H - -typedef struct -{ - int ID; - std::string NAME; - std::string START_TIME; - std::string END_TIME; -}DUTY_DEFINE; - -typedef struct -{ - std::string DATE; - int DUTY_DEFINE_ID; - std::string USERS; - std::string NAME; - std::string START_TIME; - std::string END_TIME; -}DUTY_SETTING; - -typedef struct -{ - int PERM_ID; - std::string PERM_NAME; - std::string PERM_ALIAS; -}RM_USER_DEF; - -typedef struct -{ - int ID; - std::string GROUP_NAME; - std::string USERS; - std::string USERS_STATUS; - std::string START_TIME; - std::string END_TIME; - std::string NOTE1; - std::string NOTE2; - std::string NOTE3; -}DUTY_INFO; - -typedef struct -{ - qint64 CREATE_TIME; - std::string REQUESTER; - std::string FILE_PATH; -}HIS_WORK_TICKET; - -typedef struct -{ - qint64 TIME_STAMP; - std::string CONTENT; -}HIS_EVENT; - -#endif // SHIFTCOMMON_H +#ifndef SHIFTCOMMON_H +#define SHIFTCOMMON_H + +typedef struct +{ + int ID; + std::string NAME; + std::string START_TIME; + std::string END_TIME; +}DUTY_DEFINE; + +typedef struct +{ + std::string DATE; + int DUTY_DEFINE_ID; + std::string USERS; + std::string NAME; + std::string START_TIME; + std::string END_TIME; +}DUTY_SETTING; + +typedef struct +{ + int PERM_ID; + std::string PERM_NAME; + std::string PERM_ALIAS; +}RM_USER_DEF; + +typedef struct +{ + int ID; + std::string GROUP_NAME; + std::string USERS; + std::string USERS_STATUS; + std::string START_TIME; + std::string END_TIME; + std::string NOTE1; + std::string NOTE2; + std::string NOTE3; +}DUTY_INFO; + +typedef struct +{ + qint64 CREATE_TIME; + std::string REQUESTER; + std::string FILE_PATH; +}HIS_WORK_TICKET; + +typedef struct +{ + qint64 TIME_STAMP; + std::string CONTENT; +}HIS_EVENT; + +#endif // SHIFTCOMMON_H diff --git a/product/src/gui/plugin/ShiftWidget/ShiftWidget.pro b/product/src/gui/plugin/ShiftWidget/ShiftWidget.pro index be21921e..34baaa0d 100644 --- a/product/src/gui/plugin/ShiftWidget/ShiftWidget.pro +++ b/product/src/gui/plugin/ShiftWidget/ShiftWidget.pro @@ -1,60 +1,60 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-11-05T14:34:41 -# -#------------------------------------------------- - -QT += core gui sql printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = ShiftWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -#include($$PWD/../../../idl_files/idl_files.pri) -#------------------------------------------------------------------- -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - -LIBS += -ldb_base_api -ldb_api_ex -lpub_utility_api -lperm_mng_api -lmodel_excel -llog4cplus -lpub_logger_api - -SOURCES += \ - main.cpp \ - CShiftWidget.cpp \ - CRecordWidget.cpp \ - HandoverWidget.cpp \ - CShiftPluginWidget.cpp \ - QueryThread.cpp \ - CMyCalendar.cpp - -HEADERS += \ - CShiftWidget.h \ - CRecordWidget.h \ - HandoverWidget.h \ - ShiftCommon.h \ - CShiftPluginWidget.h \ - QueryThread.h \ - CMyCalendar.h - -FORMS += \ - CShiftWidget.ui \ - CRecordWidget.ui \ - HandoverWidget.ui \ - CMyCalendar.ui +#------------------------------------------------- +# +# Project created by QtCreator 2019-11-05T14:34:41 +# +#------------------------------------------------- + +QT += core gui sql printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ShiftWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +#include($$PWD/../../../idl_files/idl_files.pri) +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +LIBS += -ldb_base_api -ldb_api_ex -lpub_utility_api -lperm_mng_api -lmodel_excel -llog4cplus -lpub_logger_api + +SOURCES += \ + main.cpp \ + CShiftWidget.cpp \ + CRecordWidget.cpp \ + HandoverWidget.cpp \ + CShiftPluginWidget.cpp \ + QueryThread.cpp \ + CMyCalendar.cpp + +HEADERS += \ + CShiftWidget.h \ + CRecordWidget.h \ + HandoverWidget.h \ + ShiftCommon.h \ + CShiftPluginWidget.h \ + QueryThread.h \ + CMyCalendar.h + +FORMS += \ + CShiftWidget.ui \ + CRecordWidget.ui \ + HandoverWidget.ui \ + CMyCalendar.ui diff --git a/product/src/gui/plugin/ShiftWidget/main.cpp b/product/src/gui/plugin/ShiftWidget/main.cpp index f25ac3d5..3457adfa 100644 --- a/product/src/gui/plugin/ShiftWidget/main.cpp +++ b/product/src/gui/plugin/ShiftWidget/main.cpp @@ -1,11 +1,11 @@ -#include "CShiftWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CShiftWidget w; - w.show(); - - return a.exec(); -} +#include "CShiftWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CShiftWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/SimOptWidget/CSimOptCommon.h b/product/src/gui/plugin/SimOptWidget/CSimOptCommon.h index e8b0cdb7..62190716 100644 --- a/product/src/gui/plugin/SimOptWidget/CSimOptCommon.h +++ b/product/src/gui/plugin/SimOptWidget/CSimOptCommon.h @@ -1,6 +1,6 @@ -#ifndef CSIMOPTCOMMON_H -#define CSIMOPTCOMMON_H - -#include - -#endif // CSIMOPTCOMMON_H +#ifndef CSIMOPTCOMMON_H +#define CSIMOPTCOMMON_H + +#include + +#endif // CSIMOPTCOMMON_H diff --git a/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.cpp b/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.cpp index 2c6ceea7..ec2fe03e 100644 --- a/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.cpp +++ b/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.cpp @@ -1,24 +1,24 @@ -#include "CSimOptPluginWidget.h" -#include "CSimOptWidget.h" -CSimOptPluginWidget::CSimOptPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CSimOptPluginWidget::~CSimOptPluginWidget() -{ - -} - -bool CSimOptPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CSimOptWidget *pWidget = new CSimOptWidget(editMode, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CSimOptPluginWidget::release() -{ - -} +#include "CSimOptPluginWidget.h" +#include "CSimOptWidget.h" +CSimOptPluginWidget::CSimOptPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CSimOptPluginWidget::~CSimOptPluginWidget() +{ + +} + +bool CSimOptPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CSimOptWidget *pWidget = new CSimOptWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CSimOptPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.h b/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.h index 01637119..47e79bc1 100644 --- a/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.h +++ b/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CSIMOPTPLUGINWIDGET_H -#define CSIMOPTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CSimOptPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CSimOptPluginWidget(QObject *parent = 0); - - ~CSimOptPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); - -}; - -#endif // CSIMOPTPLUGINWIDGET_H +#ifndef CSIMOPTPLUGINWIDGET_H +#define CSIMOPTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CSimOptPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CSimOptPluginWidget(QObject *parent = 0); + + ~CSimOptPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); + +}; + +#endif // CSIMOPTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/SimOptWidget/CSimOptWidget.cpp b/product/src/gui/plugin/SimOptWidget/CSimOptWidget.cpp index 6c739433..3c6facce 100644 --- a/product/src/gui/plugin/SimOptWidget/CSimOptWidget.cpp +++ b/product/src/gui/plugin/SimOptWidget/CSimOptWidget.cpp @@ -1,249 +1,249 @@ -#include "CSimOptWidget.h" -#include "ui_CSimOptWidget.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include -#include -#include "Common.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "dbms/db_api_ex/CDbApi.h" - -using namespace kbd_dbms; -using namespace kbd_public; -using namespace kbd_service; - -CSimOptWidget::CSimOptWidget(bool editMode, QWidget *parent) - : QWidget(parent), - ui(new Ui::CSimOptWidget), - m_editMode(editMode) -{ - ui->setupUi(this); - - initStyleSheet(); - initView(); - if(!m_editMode) - { - connect(ui->startBtn,&QPushButton::clicked,this,&CSimOptWidget::slotStartBtn); - connect(ui->m_treeWidget,&QTreeWidget::itemDoubleClicked,this,&CSimOptWidget::slotItemDoubleClicked); - - refeshTree(); - - } -} - -CSimOptWidget::~CSimOptWidget() -{ - delete ui; -} - - -void CSimOptWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - -// strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; -// QFile qssfile2(QString::fromStdString(strFullPath)); -// qssfile2.open(QFile::ReadOnly); -// if (qssfile2.isOpen()) -// { -// qss += QLatin1String(qssfile2.readAll()); -// qssfile2.close(); -// } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -void CSimOptWidget::initView() -{ - -} - -bool CSimOptWidget::permCheck(int location, int region) -{ -// kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); -// QString mess; -// if(permMngPtr != NULL) -// { -// permMngPtr->PermDllInit(); -// int nUserGrpId; -// int nLevel; -// int nLoginSec; -// std::string strInstanceName; -// int userId; -// if(PERM_NORMAL != permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) -// { -// userId = -1; -// return false; -// } -// std::vector vecRegionOptId; -// QList regList; -// QList locList; -// std::vector vecLocationOptId; -// if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) -// { - -// std::vector ::iterator region = vecRegionOptId.begin(); -// while (region != vecRegionOptId.end()) -// { -// regList.append(*region++); -// } - -// std::vector ::iterator location = vecLocationOptId.begin(); -// while (location != vecLocationOptId.end()) -// { -// locList.append(*location++); -// } -// } -// if(locList.contains(location) && regList.contains(region)) -// { -// return true; -// }else -// { -// mess = QString(tr("无取消人工置数权限!")); -// slotShowMess(mess); -// return false; -// } -// } -// mess = QString(tr("初始化权限失败!")); -// slotShowMess(mess); - return false; -} - -bool CSimOptWidget::checkFilterFilePath(const QString &file) -{ - if(m_filterList.isEmpty()) - { - return true; - } - - if(file.isEmpty()) - { - return true; - } - - foreach (const QString &str, m_filterList) { - if (file.contains(str)) - { - return true; - } - } - - return false; -} - -void CSimOptWidget::refeshTree() -{ - kbd_dbms::CDbApi * m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); - if(! m_pReadDb->open()) - { - delete m_pReadDb; - m_pReadDb = NULL; - return ; - } - QSqlQuery query; - QString sqlQuery = QString("SELECT HMI_ID,HMI_NAME,HMI_DESC FROM hmi_type_info where HMI_TYPE=0 order by HMI_ID"); - - m_pReadDb->execute(sqlQuery, query); - - while(query.next()) - { - int no = query.value(0).toInt(); - QString data = query.value(1).toString(); - QString display = query.value(2).toString(); - QTreeWidgetItem* item = new QTreeWidgetItem(ui->m_treeWidget); - item->setText(0,QString::number(no)); - item->setTextAlignment(0,Qt::AlignCenter); - item->setText(1,display); - item->setData(1,Qt::UserRole+1,data); - item->setTextAlignment(1,Qt::AlignCenter); - } - m_pReadDb->close(); - delete m_pReadDb; - m_pReadDb = NULL; -} - -bool CSimOptWidget::checkUserPerm() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - std::string tmpStr = "FUNC_NOM_OM"; - if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) - { - return false; - } - return true; -} - -void CSimOptWidget::slotShowMess(const QString &mess) -{ - QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); -} - - -void CSimOptWidget::slotStartBtn() -{ - if ( checkUserPerm() == false ) - { - QMessageBox::critical( 0, tr("提示"), tr("当前登录用户无运维管理功能权限!")); - return; - } - QString fileStr; - QString descStr; - QList list = ui->m_treeWidget->selectedItems(); - if(list.count() < 1) - { - slotShowMess(tr("请选择一张图形!")); - return; - } - QTreeWidgetItem* item = list.at(0); - fileStr = item->data(1,Qt::UserRole+1).toString(); - descStr = item->text(1); - - - QString msgStr = QString(tr("确定打开图形:\"%1\",开始模拟操作?")).arg(descStr); - int ret = QMessageBox::question(this, tr("提示"),msgStr); - if(ret == QMessageBox::Yes) - { - emit sigStartSim(fileStr); - } - -} - -void CSimOptWidget::slotAddFilter(const QString &path) -{ - m_filterList.push_back(path); -} - -void CSimOptWidget::slotItemDoubleClicked(QTreeWidgetItem *item, int cl) -{ - slotStartBtn(); -} - -void CSimOptWidget::setColumnHidden(int column, bool hide) -{ - ui->m_treeWidget->setColumnHidden(column,hide); -} - -void CSimOptWidget::setColumnWidth(int column, int width) -{ - ui->m_treeWidget->setColumnWidth(column,width); -} - - +#include "CSimOptWidget.h" +#include "ui_CSimOptWidget.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include +#include +#include "Common.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "dbms/db_api_ex/CDbApi.h" + +using namespace kbd_dbms; +using namespace kbd_public; +using namespace kbd_service; + +CSimOptWidget::CSimOptWidget(bool editMode, QWidget *parent) + : QWidget(parent), + ui(new Ui::CSimOptWidget), + m_editMode(editMode) +{ + ui->setupUi(this); + + initStyleSheet(); + initView(); + if(!m_editMode) + { + connect(ui->startBtn,&QPushButton::clicked,this,&CSimOptWidget::slotStartBtn); + connect(ui->m_treeWidget,&QTreeWidget::itemDoubleClicked,this,&CSimOptWidget::slotItemDoubleClicked); + + refeshTree(); + + } +} + +CSimOptWidget::~CSimOptWidget() +{ + delete ui; +} + + +void CSimOptWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + +// strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; +// QFile qssfile2(QString::fromStdString(strFullPath)); +// qssfile2.open(QFile::ReadOnly); +// if (qssfile2.isOpen()) +// { +// qss += QLatin1String(qssfile2.readAll()); +// qssfile2.close(); +// } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CSimOptWidget::initView() +{ + +} + +bool CSimOptWidget::permCheck(int location, int region) +{ +// kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); +// QString mess; +// if(permMngPtr != NULL) +// { +// permMngPtr->PermDllInit(); +// int nUserGrpId; +// int nLevel; +// int nLoginSec; +// std::string strInstanceName; +// int userId; +// if(PERM_NORMAL != permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) +// { +// userId = -1; +// return false; +// } +// std::vector vecRegionOptId; +// QList regList; +// QList locList; +// std::vector vecLocationOptId; +// if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) +// { + +// std::vector ::iterator region = vecRegionOptId.begin(); +// while (region != vecRegionOptId.end()) +// { +// regList.append(*region++); +// } + +// std::vector ::iterator location = vecLocationOptId.begin(); +// while (location != vecLocationOptId.end()) +// { +// locList.append(*location++); +// } +// } +// if(locList.contains(location) && regList.contains(region)) +// { +// return true; +// }else +// { +// mess = QString(tr("无取消人工置数权限!")); +// slotShowMess(mess); +// return false; +// } +// } +// mess = QString(tr("初始化权限失败!")); +// slotShowMess(mess); + return false; +} + +bool CSimOptWidget::checkFilterFilePath(const QString &file) +{ + if(m_filterList.isEmpty()) + { + return true; + } + + if(file.isEmpty()) + { + return true; + } + + foreach (const QString &str, m_filterList) { + if (file.contains(str)) + { + return true; + } + } + + return false; +} + +void CSimOptWidget::refeshTree() +{ + kbd_dbms::CDbApi * m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(! m_pReadDb->open()) + { + delete m_pReadDb; + m_pReadDb = NULL; + return ; + } + QSqlQuery query; + QString sqlQuery = QString("SELECT HMI_ID,HMI_NAME,HMI_DESC FROM hmi_type_info where HMI_TYPE=0 order by HMI_ID"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int no = query.value(0).toInt(); + QString data = query.value(1).toString(); + QString display = query.value(2).toString(); + QTreeWidgetItem* item = new QTreeWidgetItem(ui->m_treeWidget); + item->setText(0,QString::number(no)); + item->setTextAlignment(0,Qt::AlignCenter); + item->setText(1,display); + item->setData(1,Qt::UserRole+1,data); + item->setTextAlignment(1,Qt::AlignCenter); + } + m_pReadDb->close(); + delete m_pReadDb; + m_pReadDb = NULL; +} + +bool CSimOptWidget::checkUserPerm() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string tmpStr = "FUNC_NOM_OM"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + return false; + } + return true; +} + +void CSimOptWidget::slotShowMess(const QString &mess) +{ + QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); +} + + +void CSimOptWidget::slotStartBtn() +{ + if ( checkUserPerm() == false ) + { + QMessageBox::critical( 0, tr("提示"), tr("当前登录用户无运维管理功能权限!")); + return; + } + QString fileStr; + QString descStr; + QList list = ui->m_treeWidget->selectedItems(); + if(list.count() < 1) + { + slotShowMess(tr("请选择一张图形!")); + return; + } + QTreeWidgetItem* item = list.at(0); + fileStr = item->data(1,Qt::UserRole+1).toString(); + descStr = item->text(1); + + + QString msgStr = QString(tr("确定打开图形:\"%1\",开始模拟操作?")).arg(descStr); + int ret = QMessageBox::question(this, tr("提示"),msgStr); + if(ret == QMessageBox::Yes) + { + emit sigStartSim(fileStr); + } + +} + +void CSimOptWidget::slotAddFilter(const QString &path) +{ + m_filterList.push_back(path); +} + +void CSimOptWidget::slotItemDoubleClicked(QTreeWidgetItem *item, int cl) +{ + slotStartBtn(); +} + +void CSimOptWidget::setColumnHidden(int column, bool hide) +{ + ui->m_treeWidget->setColumnHidden(column,hide); +} + +void CSimOptWidget::setColumnWidth(int column, int width) +{ + ui->m_treeWidget->setColumnWidth(column,width); +} + + diff --git a/product/src/gui/plugin/SimOptWidget/CSimOptWidget.h b/product/src/gui/plugin/SimOptWidget/CSimOptWidget.h index c737c132..6060b1cb 100644 --- a/product/src/gui/plugin/SimOptWidget/CSimOptWidget.h +++ b/product/src/gui/plugin/SimOptWidget/CSimOptWidget.h @@ -1,60 +1,60 @@ -#ifndef CSIMOPTWIDGET_H -#define CSIMOPTWIDGET_H - -#include -#include -#include -#include "CSimOptCommon.h" -#include - -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" -#include - -QT_BEGIN_NAMESPACE -namespace Ui { class CSimOptWidget; } -QT_END_NAMESPACE - -class CSimOptWidget : public QWidget -{ - Q_OBJECT - -public: - CSimOptWidget(bool editMode,QWidget *parent = nullptr); - ~CSimOptWidget(); - -private: - void initStyleSheet(); - void initView(); - - bool permCheck(int location ,int region); - - bool checkFilterFilePath(const QString& file); - - void refeshTree(); - bool checkUserPerm(); - -public slots: - void slotShowMess(const QString &mess); - void slotStartBtn(); - void slotAddFilter(const QString& path); - void slotItemDoubleClicked(QTreeWidgetItem *item, int cl); - - void setColumnHidden(int column,bool hide); - - void setColumnWidth(int column,int width); - -signals: - void sigStartSim(const QString& file); - -private: - Ui::CSimOptWidget *ui; - - QStringList m_filterList; - QMap m_mapType; - - bool m_editMode; - - -}; -#endif // CSIMOPTWIDGET_H +#ifndef CSIMOPTWIDGET_H +#define CSIMOPTWIDGET_H + +#include +#include +#include +#include "CSimOptCommon.h" +#include + +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class CSimOptWidget; } +QT_END_NAMESPACE + +class CSimOptWidget : public QWidget +{ + Q_OBJECT + +public: + CSimOptWidget(bool editMode,QWidget *parent = nullptr); + ~CSimOptWidget(); + +private: + void initStyleSheet(); + void initView(); + + bool permCheck(int location ,int region); + + bool checkFilterFilePath(const QString& file); + + void refeshTree(); + bool checkUserPerm(); + +public slots: + void slotShowMess(const QString &mess); + void slotStartBtn(); + void slotAddFilter(const QString& path); + void slotItemDoubleClicked(QTreeWidgetItem *item, int cl); + + void setColumnHidden(int column,bool hide); + + void setColumnWidth(int column,int width); + +signals: + void sigStartSim(const QString& file); + +private: + Ui::CSimOptWidget *ui; + + QStringList m_filterList; + QMap m_mapType; + + bool m_editMode; + + +}; +#endif // CSIMOPTWIDGET_H diff --git a/product/src/gui/plugin/SimOptWidget/CSimOptWidget.ui b/product/src/gui/plugin/SimOptWidget/CSimOptWidget.ui index 8d6c98a8..b74ea779 100644 --- a/product/src/gui/plugin/SimOptWidget/CSimOptWidget.ui +++ b/product/src/gui/plugin/SimOptWidget/CSimOptWidget.ui @@ -1,98 +1,98 @@ - - - CSimOptWidget - - - - 0 - 0 - 800 - 600 - - - - CSimOptWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 开始模拟操作 - - - - - - - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - - 序号 - - - AlignCenter - - - - - 图形列表 - - - AlignCenter - - - - - - - - - - - - + + + CSimOptWidget + + + + 0 + 0 + 800 + 600 + + + + CSimOptWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 开始模拟操作 + + + + + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + 序号 + + + AlignCenter + + + + + 图形列表 + + + AlignCenter + + + + + + + + + + + + diff --git a/product/src/gui/plugin/SimOptWidget/SimOptWidget.pro b/product/src/gui/plugin/SimOptWidget/SimOptWidget.pro index 1201800d..e3043957 100644 --- a/product/src/gui/plugin/SimOptWidget/SimOptWidget.pro +++ b/product/src/gui/plugin/SimOptWidget/SimOptWidget.pro @@ -1,51 +1,51 @@ -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib - -TARGET = SimOptWidget - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any Qt feature that has been marked deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if it uses deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - CSimOptPluginWidget.cpp \ -# main.cpp \ - CSimOptWidget.cpp - -HEADERS += \ - CSimOptCommon.h \ - CSimOptPluginWidget.h \ - CSimOptWidget.h - -FORMS += \ - CSimOptWidget.ui - -LIBS += \ - -llog4cplus \ - -ldb_base_api \ - -ldb_api_ex \ - -lpub_logger_api \ - -lpub_utility_api \ - -lperm_mng_api \ - -lsys_login_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib + +TARGET = SimOptWidget + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + CSimOptPluginWidget.cpp \ +# main.cpp \ + CSimOptWidget.cpp + +HEADERS += \ + CSimOptCommon.h \ + CSimOptPluginWidget.h \ + CSimOptWidget.h + +FORMS += \ + CSimOptWidget.ui + +LIBS += \ + -llog4cplus \ + -ldb_base_api \ + -ldb_api_ex \ + -lpub_logger_api \ + -lpub_utility_api \ + -lperm_mng_api \ + -lsys_login_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/SimOptWidget/main.cpp b/product/src/gui/plugin/SimOptWidget/main.cpp index 97f0cbe5..4efa32b0 100644 --- a/product/src/gui/plugin/SimOptWidget/main.cpp +++ b/product/src/gui/plugin/SimOptWidget/main.cpp @@ -1,37 +1,37 @@ - -#include - -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "CSimOptWidget.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); -// kbd_public::StartLogSystem("HMI", "hmi"); -// if (!(kbd_net::initMsgBus("HMI", "HMI"))) -// { -// return -1; -// } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - { - CSimOptWidget w(false,NULL); - w.slotAddFilter("接线图"); - w.show(); - a.exec(); - } - //<释放消息总线 -// kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} + +#include + +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "CSimOptWidget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); +// kbd_public::StartLogSystem("HMI", "hmi"); +// if (!(kbd_net::initMsgBus("HMI", "HMI"))) +// { +// return -1; +// } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + { + CSimOptWidget w(false,NULL); + w.slotAddFilter("接线图"); + w.show(); + a.exec(); + } + //<释放消息总线 +// kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/TelBookWidget/CLogMng.cpp b/product/src/gui/plugin/TelBookWidget/CLogMng.cpp index 051e273c..b6eba262 100644 --- a/product/src/gui/plugin/TelBookWidget/CLogMng.cpp +++ b/product/src/gui/plugin/TelBookWidget/CLogMng.cpp @@ -1,69 +1,69 @@ -#include "CLogMng.h" -#include -#include -#include -#include - -CLogMng *CLogMng::m_pInstance = NULL; - -CLogMng *CLogMng::Instance() -{ - if(m_pInstance == NULL) - { - m_pInstance = new CLogMng(); - } - return m_pInstance; -} - -void CLogMng::Destory() -{ - m_pInstance = NULL; - deleteLater(); -} - -void CLogMng::WriteLog(const QString &log) -{ - if(!m_bEnableWrite) - { - return ; - } - - QString filePath = QString("%1/%2").arg(m_strLogPath).arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")); - int first = filePath.lastIndexOf("/"); - //QString name = filePath.right(filePath.length()-first-1); - QString path = filePath.left(first); - QDir dir; - if(!dir.exists(path)) - { - dir.mkpath(path); - } - QFile file(filePath); - QString mes =QString("%1 %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(log); - - if(file.open(QIODevice::WriteOnly | QIODevice::Append )) - { - QTextStream textStream(&file); - textStream << mes << "\r\n"; - // file.write(mes.toStdString().c_str(),mes.size()); - - file.close(); - } - -} - -CLogMng::CLogMng(): QObject() -{ - m_bEnableWrite = true; - m_strLogPath =QDir::currentPath()+"/ProtectLog"; -} - -void CLogMng::saveStatusChange(int status) -{ - if(status) - { - m_bEnableWrite = true; - }else - { - m_bEnableWrite = false; - } -} +#include "CLogMng.h" +#include +#include +#include +#include + +CLogMng *CLogMng::m_pInstance = NULL; + +CLogMng *CLogMng::Instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CLogMng(); + } + return m_pInstance; +} + +void CLogMng::Destory() +{ + m_pInstance = NULL; + deleteLater(); +} + +void CLogMng::WriteLog(const QString &log) +{ + if(!m_bEnableWrite) + { + return ; + } + + QString filePath = QString("%1/%2").arg(m_strLogPath).arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")); + int first = filePath.lastIndexOf("/"); + //QString name = filePath.right(filePath.length()-first-1); + QString path = filePath.left(first); + QDir dir; + if(!dir.exists(path)) + { + dir.mkpath(path); + } + QFile file(filePath); + QString mes =QString("%1 %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(log); + + if(file.open(QIODevice::WriteOnly | QIODevice::Append )) + { + QTextStream textStream(&file); + textStream << mes << "\r\n"; + // file.write(mes.toStdString().c_str(),mes.size()); + + file.close(); + } + +} + +CLogMng::CLogMng(): QObject() +{ + m_bEnableWrite = true; + m_strLogPath =QDir::currentPath()+"/ProtectLog"; +} + +void CLogMng::saveStatusChange(int status) +{ + if(status) + { + m_bEnableWrite = true; + }else + { + m_bEnableWrite = false; + } +} diff --git a/product/src/gui/plugin/TelBookWidget/CLogMng.h b/product/src/gui/plugin/TelBookWidget/CLogMng.h index 65a4db4c..2e019438 100644 --- a/product/src/gui/plugin/TelBookWidget/CLogMng.h +++ b/product/src/gui/plugin/TelBookWidget/CLogMng.h @@ -1,33 +1,33 @@ -#ifndef CLOGMNG_H -#define CLOGMNG_H - -#include - -class CLogMng : public QObject -{ - Q_OBJECT -public: - static CLogMng *Instance(); - - void Destory(); - - void WriteLog(const QString &log); - -private: - CLogMng(); - -signals: - -public slots: - void saveStatusChange(int status); - -private: - - static CLogMng * m_pInstance; - - bool m_bEnableWrite; - QString m_strLogPath; - -}; - -#endif // CLOGMNG_H +#ifndef CLOGMNG_H +#define CLOGMNG_H + +#include + +class CLogMng : public QObject +{ + Q_OBJECT +public: + static CLogMng *Instance(); + + void Destory(); + + void WriteLog(const QString &log); + +private: + CLogMng(); + +signals: + +public slots: + void saveStatusChange(int status); + +private: + + static CLogMng * m_pInstance; + + bool m_bEnableWrite; + QString m_strLogPath; + +}; + +#endif // CLOGMNG_H diff --git a/product/src/gui/plugin/TelBookWidget/CRelayCommon.h b/product/src/gui/plugin/TelBookWidget/CRelayCommon.h index 39732b15..103c8543 100644 --- a/product/src/gui/plugin/TelBookWidget/CRelayCommon.h +++ b/product/src/gui/plugin/TelBookWidget/CRelayCommon.h @@ -1,77 +1,77 @@ -#ifndef CRELAYCOMMON_H -#define CRELAYCOMMON_H - -#include - -struct SUserTelInfo -{ - - QString code; - QString name; - - QString phone; - - QString tel; - QString company; - QString remark; - SUserTelInfo(){ - - } -}; - -struct SRelayGroup -{ - int id; //< 组id - QString desc; //< 组描述 - SRelayGroup(){ - - } -}; - -struct SRelayBlock -{ - int funcNo; //< 功能码 - ushort startAddr; //< 寄存器起始地址 - ushort registerLen; //< 寄存器个数 - bool blockChangeFlag; - bool isFlag; - SRelayBlock(){ - blockChangeFlag = false; - isFlag = false; - } -}; - -struct SRelayPara -{ - float fValue; //< 值 - int pAddr; //< 寄存器地址 - float modulus; //< 系数 - int revise; //< 附加值 - int boardNo; //< 定值组号 - int pointNo; //< 定值点号 - int valueType; //< 值类型 - QString name; //< 名称 - bool isFlag; - int glFlag; //< 过流标示 - int timeFlag; //< 延迟标示 - SRelayPara(){ - fValue = 0.0; - isFlag = false; - glFlag = false; - timeFlag = false; - } -}; - -struct SRelayData -{ - QString chanName; - QString name; - float value; - SRelayData(){ - - } -}; - - - -#endif // CRELAYCOMMON_H +#ifndef CRELAYCOMMON_H +#define CRELAYCOMMON_H + +#include + +struct SUserTelInfo +{ + + QString code; + QString name; + + QString phone; + + QString tel; + QString company; + QString remark; + SUserTelInfo(){ + + } +}; + +struct SRelayGroup +{ + int id; //< 组id + QString desc; //< 组描述 + SRelayGroup(){ + + } +}; + +struct SRelayBlock +{ + int funcNo; //< 功能码 + ushort startAddr; //< 寄存器起始地址 + ushort registerLen; //< 寄存器个数 + bool blockChangeFlag; + bool isFlag; + SRelayBlock(){ + blockChangeFlag = false; + isFlag = false; + } +}; + +struct SRelayPara +{ + float fValue; //< 值 + int pAddr; //< 寄存器地址 + float modulus; //< 系数 + int revise; //< 附加值 + int boardNo; //< 定值组号 + int pointNo; //< 定值点号 + int valueType; //< 值类型 + QString name; //< 名称 + bool isFlag; + int glFlag; //< 过流标示 + int timeFlag; //< 延迟标示 + SRelayPara(){ + fValue = 0.0; + isFlag = false; + glFlag = false; + timeFlag = false; + } +}; + +struct SRelayData +{ + QString chanName; + QString name; + float value; + SRelayData(){ + + } +}; + + + +#endif // CRELAYCOMMON_H diff --git a/product/src/gui/plugin/TelBookWidget/CRelayFile.cpp b/product/src/gui/plugin/TelBookWidget/CRelayFile.cpp index b6f3d1da..5b1571ea 100644 --- a/product/src/gui/plugin/TelBookWidget/CRelayFile.cpp +++ b/product/src/gui/plugin/TelBookWidget/CRelayFile.cpp @@ -1,82 +1,82 @@ -#include "CRelayFile.h" -#include -#include -#include -#include -CRelayFile::CRelayFile() -{ - QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); - -} - -QList CRelayFile::getTelList() -{ - QList chanList; - QDir dir = QDir::current(); - QFile file(dir.filePath("../../data/TelBookWidget/TelBookWidget.csv")); - - if(!file.open(QIODevice::ReadOnly)) - { - return chanList; - } - QTextStream *out = new QTextStream(&file); - out->setCodec(QTextCodec::codecForName("GBK")); - QString ss = out->readLine(); - while(!out->atEnd()) - { - ss = out->readLine(); - QStringList tempbar = ss.split(","); - if(tempbar.size() < 5) - { - continue; - } - SUserTelInfo relayChanl; - relayChanl.code = tempbar[0]; - relayChanl.name = tempbar[1]; - relayChanl.phone = tempbar[2]; - relayChanl.tel = tempbar[3]; - relayChanl.company = tempbar[4]; - relayChanl.remark = tempbar[5]; - - chanList.append(relayChanl); - } - file.close(); - return chanList; -} - -int CRelayFile::setTelList(QList chanList ) -{ - - QDir dir = QDir::current(); - QFile file(dir.filePath("../../data/TelBookWidget/TelBookWidget.csv")); - - if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate )) - { - return -1; - } - file.size(); - QTextStream *out = new QTextStream(&file); - out->setCodec(QTextCodec::codecForName("GBK")); - - QString info="代码,姓名,手机,电话,单位,备注"; - // QString ss = out->readLine(); - // while(!out->atEnd()) - - - *out << info << "\r\n" ; - for(int index(0);index +#include +#include +#include +CRelayFile::CRelayFile() +{ + QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); + +} + +QList CRelayFile::getTelList() +{ + QList chanList; + QDir dir = QDir::current(); + QFile file(dir.filePath("../../data/TelBookWidget/TelBookWidget.csv")); + + if(!file.open(QIODevice::ReadOnly)) + { + return chanList; + } + QTextStream *out = new QTextStream(&file); + out->setCodec(QTextCodec::codecForName("GBK")); + QString ss = out->readLine(); + while(!out->atEnd()) + { + ss = out->readLine(); + QStringList tempbar = ss.split(","); + if(tempbar.size() < 5) + { + continue; + } + SUserTelInfo relayChanl; + relayChanl.code = tempbar[0]; + relayChanl.name = tempbar[1]; + relayChanl.phone = tempbar[2]; + relayChanl.tel = tempbar[3]; + relayChanl.company = tempbar[4]; + relayChanl.remark = tempbar[5]; + + chanList.append(relayChanl); + } + file.close(); + return chanList; +} + +int CRelayFile::setTelList(QList chanList ) +{ + + QDir dir = QDir::current(); + QFile file(dir.filePath("../../data/TelBookWidget/TelBookWidget.csv")); + + if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate )) + { + return -1; + } + file.size(); + QTextStream *out = new QTextStream(&file); + out->setCodec(QTextCodec::codecForName("GBK")); + + QString info="代码,姓名,手机,电话,单位,备注"; + // QString ss = out->readLine(); + // while(!out->atEnd()) + + + *out << info << "\r\n" ; + for(int index(0);index - -class CRelayFile -{ -public: - CRelayFile(); - - QList getTelList(); - int setTelList(QList chanList ); - -}; - -#endif // CRELAYFILE_H +#ifndef CRELAYFILE_H +#define CRELAYFILE_H + +#include "CRelayCommon.h" +#include + +class CRelayFile +{ +public: + CRelayFile(); + + QList getTelList(); + int setTelList(QList chanList ); + +}; + +#endif // CRELAYFILE_H diff --git a/product/src/gui/plugin/TelBookWidget/CRelaySettingCommon.h b/product/src/gui/plugin/TelBookWidget/CRelaySettingCommon.h index 8b781f70..5648ded1 100644 --- a/product/src/gui/plugin/TelBookWidget/CRelaySettingCommon.h +++ b/product/src/gui/plugin/TelBookWidget/CRelaySettingCommon.h @@ -1,93 +1,93 @@ -#ifndef CRELAYSETTINGCOMMON_H -#define CRELAYSETTINGCOMMON_H - -#include - -struct RelayLoc -{ - int id; //< 位置id <主> - QString name; //< 位置标签 - QString desc; //< 位置描述 - int domainId; //< 域id - RelayLoc() {} -}; - -struct RelayRtu -{ - QString name; //< rtu标签 <主> - QString desc; //< rtu描述 - int locId; //< 位置id - int subId; //< 应用id - RelayRtu() {} -}; - -struct RelayDev -{ - int id; //< 设备id - QString name; //< 设备标签 <主> - QString desc; //< 设备描述 - int locId; //< 位置id - int subId; //< 应用id - QString rtuName; //< rtu标签 - RelayDev() {} -}; - -struct RelayUnit -{ - int id; //< 单位id - QString name; //< 单位标签 - RelayUnit() {} -}; - -struct RelayDictState -{ - QString name; //< dict 标签 - int value; //< 值 - QString displayName; -}; -struct RelaySetting -{ - QString tagName; - QString desc; - int groupNo; - QString rtuTag; - int rtuNo; - int dotNo; - int seqNo; - int subSystem; - int nAppId; - int locId; - QString devTag; - float value; - int valueType; - int unitId; - QString valueText; - float valueRatio; - float valueAdded; - float valueMax; - float valueMin; - float valueDefault; - float valueVerify; - QString exInfo; - int domainId; - QString locDesc; - QString keyIdTag; - RelaySetting() { - value = -1; - } -}; - -struct RelayCmdReply -{ - QString rtu_tag; - int isSuccess; - QString resultStr; - int dev_id; - int cur_group; - QList dotList; - QList valueList; - RelayCmdReply() {} -}; - - -#endif // CRELAYSETTINGCOMMON_H +#ifndef CRELAYSETTINGCOMMON_H +#define CRELAYSETTINGCOMMON_H + +#include + +struct RelayLoc +{ + int id; //< 位置id <主> + QString name; //< 位置标签 + QString desc; //< 位置描述 + int domainId; //< 域id + RelayLoc() {} +}; + +struct RelayRtu +{ + QString name; //< rtu标签 <主> + QString desc; //< rtu描述 + int locId; //< 位置id + int subId; //< 应用id + RelayRtu() {} +}; + +struct RelayDev +{ + int id; //< 设备id + QString name; //< 设备标签 <主> + QString desc; //< 设备描述 + int locId; //< 位置id + int subId; //< 应用id + QString rtuName; //< rtu标签 + RelayDev() {} +}; + +struct RelayUnit +{ + int id; //< 单位id + QString name; //< 单位标签 + RelayUnit() {} +}; + +struct RelayDictState +{ + QString name; //< dict 标签 + int value; //< 值 + QString displayName; +}; +struct RelaySetting +{ + QString tagName; + QString desc; + int groupNo; + QString rtuTag; + int rtuNo; + int dotNo; + int seqNo; + int subSystem; + int nAppId; + int locId; + QString devTag; + float value; + int valueType; + int unitId; + QString valueText; + float valueRatio; + float valueAdded; + float valueMax; + float valueMin; + float valueDefault; + float valueVerify; + QString exInfo; + int domainId; + QString locDesc; + QString keyIdTag; + RelaySetting() { + value = -1; + } +}; + +struct RelayCmdReply +{ + QString rtu_tag; + int isSuccess; + QString resultStr; + int dev_id; + int cur_group; + QList dotList; + QList valueList; + RelayCmdReply() {} +}; + + +#endif // CRELAYSETTINGCOMMON_H diff --git a/product/src/gui/plugin/TelBookWidget/CRelaySettingDelegate.h b/product/src/gui/plugin/TelBookWidget/CRelaySettingDelegate.h index 764489e7..d4ebf515 100644 --- a/product/src/gui/plugin/TelBookWidget/CRelaySettingDelegate.h +++ b/product/src/gui/plugin/TelBookWidget/CRelaySettingDelegate.h @@ -1,38 +1,38 @@ -#ifndef CRELAYSETTINGDELEGATE_H -#define CRELAYSETTINGDELEGATE_H - -#include -#include -#include -#include -#include - - -#define COMBOXCOL1 3 -#define COMBOXCOL2 4 -#define COMBOXCOL3 5 -class CRelaySettingDelegate : public QStyledItemDelegate -{ - Q_OBJECT - -public: - CRelaySettingDelegate(QObject *parent = Q_NULLPTR); - ~CRelaySettingDelegate(); - -public: - void paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const ; - - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; - - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; - - void setEditorData(QWidget *editor, const QModelIndex &index) const ; - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const ; - -private: - QMap > m_dictMap; -}; - -#endif // CRELAYSETTINGDELEGATE_H +#ifndef CRELAYSETTINGDELEGATE_H +#define CRELAYSETTINGDELEGATE_H + +#include +#include +#include +#include +#include + + +#define COMBOXCOL1 3 +#define COMBOXCOL2 4 +#define COMBOXCOL3 5 +class CRelaySettingDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + CRelaySettingDelegate(QObject *parent = Q_NULLPTR); + ~CRelaySettingDelegate(); + +public: + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const ; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const ; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const ; + +private: + QMap > m_dictMap; +}; + +#endif // CRELAYSETTINGDELEGATE_H diff --git a/product/src/gui/plugin/TelBookWidget/CRelaySettingMsgMng.cpp b/product/src/gui/plugin/TelBookWidget/CRelaySettingMsgMng.cpp index c7231efa..0013ac58 100644 --- a/product/src/gui/plugin/TelBookWidget/CRelaySettingMsgMng.cpp +++ b/product/src/gui/plugin/TelBookWidget/CRelaySettingMsgMng.cpp @@ -1,474 +1,474 @@ -#include "CRelaySettingMsgMng.h" -#include "pub_logger_api/logger.h" -#include -#include "CDbMng.h" - -int CUST_CMD_OUT_TIME = 35; - -CRelaySettingMsgMng::CRelaySettingMsgMng(QObject *parent) : QObject(parent), - m_communicator(Q_NULLPTR), - m_timer(Q_NULLPTR) -{ - init(); -} - -CRelaySettingMsgMng::~CRelaySettingMsgMng() -{ - if(m_timer) - { - m_timer->stop(); - delete m_timer; - } - m_timer = Q_NULLPTR; - - delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); - - if(m_communicator != Q_NULLPTR) - { - delete m_communicator; - } - m_communicator = Q_NULLPTR; -} - -void CRelaySettingMsgMng::slotcmd(const QList &keyList, const QList &valueList, const RelaySetting &relaySetting, const QString &cmd) -{ -// { -// /** -// * @brief test 仅测试代码使用 -// */ -// test(cmd,1); -// return ; -// } - addSub(); - m_requestCmd = cmd; - kbd_net::CMbMessage msg; - msg.setMsgType(MT_OPT_COMMON_DOWN); - msg.setSubject(relaySetting.nAppId, CH_HMI_TO_OPT_OPTCMD_DOWN); - COptCustCtrlRequest cOptCustCtrlRequest; - SOptCustCtrlRequest sOptCustCtrlRequest; - sOptCustCtrlRequest.stHead = createReqHead(relaySetting); - sOptCustCtrlRequest.strKeyIdTag = relaySetting.keyIdTag.toStdString(); - sOptCustCtrlRequest.strRtuTag = relaySetting.rtuTag.toStdString(); - sOptCustCtrlRequest.vecOptCustCtrlQueue = createCtrlQueue(keyList,valueList); - - std::string content = cOptCustCtrlRequest.generate(sOptCustCtrlRequest); - msg.setData(content); - if(!m_communicator->sendMsgToDomain(msg, relaySetting.domainId)) - { - emit sendError(); - delSub(); - return ; - }else - { - m_timer->start(500); - } - - m_curRtu = sOptCustCtrlRequest.strRtuTag; - m_strHostName = sOptCustCtrlRequest.stHead.strHostName; - m_strInstName = sOptCustCtrlRequest.stHead.strInstName; - m_nOptTime = sOptCustCtrlRequest.stHead.nOptTime; -} - -void CRelaySettingMsgMng::recvMessage() -{ - kbd_net::CMbMessage msg; - if(m_communicator->recvMsg(msg, 50)) - { - if(msg.getMsgType() != MT_OPT_COMMON_UP) - { - return; - } - - COptCustCtrlReply cOptCustCtrlReply; - SOptCustCtrlReply sOptCustCtrlReply; - std::string str((const char*)msg.getDataPtr(), msg.getDataSize()); - cOptCustCtrlReply.parse(str, sOptCustCtrlReply); - - if(parseMsg(sOptCustCtrlReply)) - { - m_timer->stop(); - delSub(); - return ; - } - } - int64 nTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - if(nTime -m_nOptTime > CUST_CMD_OUT_TIME*1000) - { - m_timer->stop(); - delSub(); - emit recvOuttime(); - } -} - -void CRelaySettingMsgMng::init() -{ - if(!createSysInfoInstance(m_ptrSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - } - - m_permMng = getPermMngInstance("base"); - if(m_permMng != NULL) - { - if(m_permMng->PermDllInit() != PERM_NORMAL) - { - LOGERROR("权限接口初始化失败!"); - } - } - initMsg(); - if(!addSub(0, CH_OPT_TO_HMI_OPTCMD_UP)) - { - return; - } - m_timer = new QTimer(this); - connect(m_timer, SIGNAL(timeout()), this, SLOT(recvMessage())); - -} - -void CRelaySettingMsgMng::initMsg() -{ - if(m_communicator == Q_NULLPTR) - { - m_communicator = new kbd_net::CMbCommunicator(); - } -} - -void CRelaySettingMsgMng::closeMsg() -{ - if(m_communicator != NULL) - { - delete m_communicator; - } - m_communicator = NULL; -} - -bool CRelaySettingMsgMng::addSub(int appID, int channel) -{ - if(m_communicator) - { - m_communicator->addSub(appID, channel); - } - return true; -} - -bool CRelaySettingMsgMng::delSub(int appID, int channel) -{ - if(m_communicator) - { - m_communicator->delSub(appID, channel); - } - kbd_net::CMbMessage msg; - while (m_communicator->recvMsg(msg, 0)) { - - } - return true; -} - -bool CRelaySettingMsgMng::addSub() -{ - return addSub(0, CH_OPT_TO_HMI_OPTCMD_UP); -} - -bool CRelaySettingMsgMng::delSub() -{ - return delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); -} - -SOptReqHead CRelaySettingMsgMng::createReqHead(const RelaySetting &relaySetting) -{ - SOptReqHead head; - SNodeInfo nodeInfo; - int userID; - int usergID; - int level; - int loginSec; - std::string instanceName; - - m_ptrSysInfo->getLocalNodeInfo(nodeInfo); - if(m_permMng) - { - m_permMng->CurUser(userID, usergID, level, loginSec, instanceName); - } - - head.strSrcTag = "hmi"; - head.nSrcDomainID = nodeInfo.nDomainId; - head.nDstDomainID = relaySetting.domainId; - head.nAppID = relaySetting.nAppId; - head.strHostName = nodeInfo.strName; - head.strInstName = instanceName; - head.strCommName = m_communicator->getName(); - head.nUserID = userID; - head.nUserGroupID = usergID; - head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); - - return head; -} - -std::vector CRelaySettingMsgMng::createCtrlQueue(const QList &keyList,const QList &valueList) -{ - std::vector queueVec; - for(int index(0);index::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - - if(iter->strKeyName == "cmd_type") - { - cmdType = iter->strKeyValue; - break; - } - ++iter; - } - if(QString::fromStdString(cmdType) != m_requestCmd) - { - return false; - } - if(cmdType == "const_value_read") - { - return parseReadMsg(sOptCustCtrlReply); - }else if(cmdType == "const_value_edit") - { - return parseEditMsg(sOptCustCtrlReply); - }else if(cmdType == "const_value_affirm") - { - return parseAffirmMsg(sOptCustCtrlReply); - }else if(cmdType == "const_group_edit") - { - return parseGEditMsg(sOptCustCtrlReply); - }else - { - return false; - } -} - -bool CRelaySettingMsgMng::checkMsg(std::string strHostName, std::string strInstName, int64 nOptTime) -{ - if(m_strHostName != strHostName) - { - return false; - } - if(m_strInstName != strInstName) - { - return false; - } - if(m_nOptTime != nOptTime) - { - return false; - } - return true; -} - -bool CRelaySettingMsgMng::parseReadMsg(const SOptCustCtrlReply &sOptCustCtrlReply) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "dev_id") - { - relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - else if(iter->strKeyName == "cur_value") - { - relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); - } - ++iter; - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,m_requestCmd); - return true; -} - -bool CRelaySettingMsgMng::parseEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "dev_id") - { - relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - else if(iter->strKeyName == "ack_value")//ack_value cur_value - { - relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); - } - - - - ++iter; - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,m_requestCmd); - return true; -} - -bool CRelaySettingMsgMng::parseAffirmMsg(const SOptCustCtrlReply &sOptCustCtrlReply) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "dev_id") - { - relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - else if(iter->strKeyName == "cur_value") - { - relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); - } - ++iter; - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,m_requestCmd); - return true; -} - -bool CRelaySettingMsgMng::parseGEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; - relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); - std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); - while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) - { - if(iter->strKeyName == "dev_id") - { - relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "cur_group") - { - relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); - } - else if(iter->strKeyName == "dot_no") - { - relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); - } - ++iter; - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,m_requestCmd); - return true; -} - -void CRelaySettingMsgMng::test(const QString &cmd,int isSuccess) -{ - RelayCmdReply relayCmdReply; - relayCmdReply.isSuccess = isSuccess; - if(isSuccess == 1) - { - relayCmdReply.resultStr = "成功"; - }else - { - relayCmdReply.resultStr = "失败"; - } - if(cmd == "const_value_read") - { - readTest(relayCmdReply,cmd); - }else if(cmd == "const_value_edit") - { - editTest(relayCmdReply,cmd); - }else if(cmd == "const_value_affirm") - { - affirmTest(relayCmdReply,cmd); - }else if(cmd == "const_group_edit") - { - editGroupTest(relayCmdReply,cmd); - } -} - -void CRelaySettingMsgMng::readTest(RelayCmdReply &relayCmdReply, const QString &cmd) -{ - relayCmdReply.dev_id = 0; - relayCmdReply.cur_group = 0; - for(int index(0);index<3;index++) - { - relayCmdReply.dotList.append(index); - relayCmdReply.valueList.append(0); - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,cmd); -} - -void CRelaySettingMsgMng::editTest(RelayCmdReply &relayCmdReply, const QString &cmd) -{ - relayCmdReply.dev_id = 0; - relayCmdReply.cur_group = 0; - for(int index(0);index<3;index++) - { - relayCmdReply.dotList.append(index); - relayCmdReply.valueList.append(1); - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,cmd); -} - -void CRelaySettingMsgMng::affirmTest(RelayCmdReply &relayCmdReply, const QString &cmd) -{ - relayCmdReply.dev_id = 0; - relayCmdReply.cur_group = 0; - for(int index(0);index<3;index++) - { - relayCmdReply.dotList.append(index); - relayCmdReply.valueList.append(1); - } - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,cmd); -} - -void CRelaySettingMsgMng::editGroupTest(RelayCmdReply &relayCmdReply, const QString &cmd) -{ - relayCmdReply.dev_id = 0; - relayCmdReply.cur_group = 1; - - relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); - emit dataChanged(relayCmdReply,cmd); -} +#include "CRelaySettingMsgMng.h" +#include "pub_logger_api/logger.h" +#include +#include "CDbMng.h" + +int CUST_CMD_OUT_TIME = 35; + +CRelaySettingMsgMng::CRelaySettingMsgMng(QObject *parent) : QObject(parent), + m_communicator(Q_NULLPTR), + m_timer(Q_NULLPTR) +{ + init(); +} + +CRelaySettingMsgMng::~CRelaySettingMsgMng() +{ + if(m_timer) + { + m_timer->stop(); + delete m_timer; + } + m_timer = Q_NULLPTR; + + delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); + + if(m_communicator != Q_NULLPTR) + { + delete m_communicator; + } + m_communicator = Q_NULLPTR; +} + +void CRelaySettingMsgMng::slotcmd(const QList &keyList, const QList &valueList, const RelaySetting &relaySetting, const QString &cmd) +{ +// { +// /** +// * @brief test 仅测试代码使用 +// */ +// test(cmd,1); +// return ; +// } + addSub(); + m_requestCmd = cmd; + kbd_net::CMbMessage msg; + msg.setMsgType(MT_OPT_COMMON_DOWN); + msg.setSubject(relaySetting.nAppId, CH_HMI_TO_OPT_OPTCMD_DOWN); + COptCustCtrlRequest cOptCustCtrlRequest; + SOptCustCtrlRequest sOptCustCtrlRequest; + sOptCustCtrlRequest.stHead = createReqHead(relaySetting); + sOptCustCtrlRequest.strKeyIdTag = relaySetting.keyIdTag.toStdString(); + sOptCustCtrlRequest.strRtuTag = relaySetting.rtuTag.toStdString(); + sOptCustCtrlRequest.vecOptCustCtrlQueue = createCtrlQueue(keyList,valueList); + + std::string content = cOptCustCtrlRequest.generate(sOptCustCtrlRequest); + msg.setData(content); + if(!m_communicator->sendMsgToDomain(msg, relaySetting.domainId)) + { + emit sendError(); + delSub(); + return ; + }else + { + m_timer->start(500); + } + + m_curRtu = sOptCustCtrlRequest.strRtuTag; + m_strHostName = sOptCustCtrlRequest.stHead.strHostName; + m_strInstName = sOptCustCtrlRequest.stHead.strInstName; + m_nOptTime = sOptCustCtrlRequest.stHead.nOptTime; +} + +void CRelaySettingMsgMng::recvMessage() +{ + kbd_net::CMbMessage msg; + if(m_communicator->recvMsg(msg, 50)) + { + if(msg.getMsgType() != MT_OPT_COMMON_UP) + { + return; + } + + COptCustCtrlReply cOptCustCtrlReply; + SOptCustCtrlReply sOptCustCtrlReply; + std::string str((const char*)msg.getDataPtr(), msg.getDataSize()); + cOptCustCtrlReply.parse(str, sOptCustCtrlReply); + + if(parseMsg(sOptCustCtrlReply)) + { + m_timer->stop(); + delSub(); + return ; + } + } + int64 nTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + if(nTime -m_nOptTime > CUST_CMD_OUT_TIME*1000) + { + m_timer->stop(); + delSub(); + emit recvOuttime(); + } +} + +void CRelaySettingMsgMng::init() +{ + if(!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + + m_permMng = getPermMngInstance("base"); + if(m_permMng != NULL) + { + if(m_permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + } + } + initMsg(); + if(!addSub(0, CH_OPT_TO_HMI_OPTCMD_UP)) + { + return; + } + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(recvMessage())); + +} + +void CRelaySettingMsgMng::initMsg() +{ + if(m_communicator == Q_NULLPTR) + { + m_communicator = new kbd_net::CMbCommunicator(); + } +} + +void CRelaySettingMsgMng::closeMsg() +{ + if(m_communicator != NULL) + { + delete m_communicator; + } + m_communicator = NULL; +} + +bool CRelaySettingMsgMng::addSub(int appID, int channel) +{ + if(m_communicator) + { + m_communicator->addSub(appID, channel); + } + return true; +} + +bool CRelaySettingMsgMng::delSub(int appID, int channel) +{ + if(m_communicator) + { + m_communicator->delSub(appID, channel); + } + kbd_net::CMbMessage msg; + while (m_communicator->recvMsg(msg, 0)) { + + } + return true; +} + +bool CRelaySettingMsgMng::addSub() +{ + return addSub(0, CH_OPT_TO_HMI_OPTCMD_UP); +} + +bool CRelaySettingMsgMng::delSub() +{ + return delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); +} + +SOptReqHead CRelaySettingMsgMng::createReqHead(const RelaySetting &relaySetting) +{ + SOptReqHead head; + SNodeInfo nodeInfo; + int userID; + int usergID; + int level; + int loginSec; + std::string instanceName; + + m_ptrSysInfo->getLocalNodeInfo(nodeInfo); + if(m_permMng) + { + m_permMng->CurUser(userID, usergID, level, loginSec, instanceName); + } + + head.strSrcTag = "hmi"; + head.nSrcDomainID = nodeInfo.nDomainId; + head.nDstDomainID = relaySetting.domainId; + head.nAppID = relaySetting.nAppId; + head.strHostName = nodeInfo.strName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = userID; + head.nUserGroupID = usergID; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + return head; +} + +std::vector CRelaySettingMsgMng::createCtrlQueue(const QList &keyList,const QList &valueList) +{ + std::vector queueVec; + for(int index(0);index::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + + if(iter->strKeyName == "cmd_type") + { + cmdType = iter->strKeyValue; + break; + } + ++iter; + } + if(QString::fromStdString(cmdType) != m_requestCmd) + { + return false; + } + if(cmdType == "const_value_read") + { + return parseReadMsg(sOptCustCtrlReply); + }else if(cmdType == "const_value_edit") + { + return parseEditMsg(sOptCustCtrlReply); + }else if(cmdType == "const_value_affirm") + { + return parseAffirmMsg(sOptCustCtrlReply); + }else if(cmdType == "const_group_edit") + { + return parseGEditMsg(sOptCustCtrlReply); + }else + { + return false; + } +} + +bool CRelaySettingMsgMng::checkMsg(std::string strHostName, std::string strInstName, int64 nOptTime) +{ + if(m_strHostName != strHostName) + { + return false; + } + if(m_strInstName != strInstName) + { + return false; + } + if(m_nOptTime != nOptTime) + { + return false; + } + return true; +} + +bool CRelaySettingMsgMng::parseReadMsg(const SOptCustCtrlReply &sOptCustCtrlReply) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "dev_id") + { + relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + else if(iter->strKeyName == "cur_value") + { + relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); + } + ++iter; + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,m_requestCmd); + return true; +} + +bool CRelaySettingMsgMng::parseEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "dev_id") + { + relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + else if(iter->strKeyName == "ack_value")//ack_value cur_value + { + relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); + } + + + + ++iter; + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,m_requestCmd); + return true; +} + +bool CRelaySettingMsgMng::parseAffirmMsg(const SOptCustCtrlReply &sOptCustCtrlReply) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "dev_id") + { + relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + else if(iter->strKeyName == "cur_value") + { + relayCmdReply.valueList.append(QString::fromStdString(iter->strKeyValue).toFloat()); + } + ++iter; + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,m_requestCmd); + return true; +} + +bool CRelaySettingMsgMng::parseGEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = sOptCustCtrlReply.stHead.nIsSuccess; + relayCmdReply.resultStr = QString::fromStdString(sOptCustCtrlReply.stHead.strResultStr); + std::vector::const_iterator iter = sOptCustCtrlReply.vecOptCustCtrlQueue.begin(); + while(iter != sOptCustCtrlReply.vecOptCustCtrlQueue.end()) + { + if(iter->strKeyName == "dev_id") + { + relayCmdReply.dev_id = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "cur_group") + { + relayCmdReply.cur_group = QString::fromStdString(iter->strKeyValue).toInt(); + } + else if(iter->strKeyName == "dot_no") + { + relayCmdReply.dotList.append(QString::fromStdString(iter->strKeyValue).toInt()); + } + ++iter; + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,m_requestCmd); + return true; +} + +void CRelaySettingMsgMng::test(const QString &cmd,int isSuccess) +{ + RelayCmdReply relayCmdReply; + relayCmdReply.isSuccess = isSuccess; + if(isSuccess == 1) + { + relayCmdReply.resultStr = "成功"; + }else + { + relayCmdReply.resultStr = "失败"; + } + if(cmd == "const_value_read") + { + readTest(relayCmdReply,cmd); + }else if(cmd == "const_value_edit") + { + editTest(relayCmdReply,cmd); + }else if(cmd == "const_value_affirm") + { + affirmTest(relayCmdReply,cmd); + }else if(cmd == "const_group_edit") + { + editGroupTest(relayCmdReply,cmd); + } +} + +void CRelaySettingMsgMng::readTest(RelayCmdReply &relayCmdReply, const QString &cmd) +{ + relayCmdReply.dev_id = 0; + relayCmdReply.cur_group = 0; + for(int index(0);index<3;index++) + { + relayCmdReply.dotList.append(index); + relayCmdReply.valueList.append(0); + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,cmd); +} + +void CRelaySettingMsgMng::editTest(RelayCmdReply &relayCmdReply, const QString &cmd) +{ + relayCmdReply.dev_id = 0; + relayCmdReply.cur_group = 0; + for(int index(0);index<3;index++) + { + relayCmdReply.dotList.append(index); + relayCmdReply.valueList.append(1); + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,cmd); +} + +void CRelaySettingMsgMng::affirmTest(RelayCmdReply &relayCmdReply, const QString &cmd) +{ + relayCmdReply.dev_id = 0; + relayCmdReply.cur_group = 0; + for(int index(0);index<3;index++) + { + relayCmdReply.dotList.append(index); + relayCmdReply.valueList.append(1); + } + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,cmd); +} + +void CRelaySettingMsgMng::editGroupTest(RelayCmdReply &relayCmdReply, const QString &cmd) +{ + relayCmdReply.dev_id = 0; + relayCmdReply.cur_group = 1; + + relayCmdReply.rtu_tag = QString::fromStdString(m_curRtu); + emit dataChanged(relayCmdReply,cmd); +} diff --git a/product/src/gui/plugin/TelBookWidget/CRelaySettingMsgMng.h b/product/src/gui/plugin/TelBookWidget/CRelaySettingMsgMng.h index 5f1c78b8..97dca3e5 100644 --- a/product/src/gui/plugin/TelBookWidget/CRelaySettingMsgMng.h +++ b/product/src/gui/plugin/TelBookWidget/CRelaySettingMsgMng.h @@ -1,82 +1,82 @@ -#ifndef CRELAYSETTINGMSGMNG_H -#define CRELAYSETTINGMSGMNG_H - -#include -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "net/net_msg_bus_api/CMbCommunicator.h" -#include "service/operate_server_api/JsonMessageStruct.h" -#include "service/operate_server_api/JsonOptCommand.h" -#include "common/MessageChannel.h" -#include -#include "CRelaySettingCommon.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" - -using namespace kbd_public; -using namespace kbd_service; - -class CRelaySettingMsgMng : public QObject -{ - Q_OBJECT -public: - explicit CRelaySettingMsgMng(QObject *parent = nullptr); - virtual ~CRelaySettingMsgMng(); -signals: - - void recvOuttime(); - - void dataChanged(const RelayCmdReply &reply,const QString &cmd); - - void sendError(); - -public slots: - void slotcmd(const QList &keyList, const QList &valueList, const RelaySetting &relaySetting,const QString & cmd); - void recvMessage(); - -private: - void init(); - void initMsg(); - void closeMsg(); - - bool addSub(int appID, int channel); - bool delSub(int appID, int channel); - - bool addSub(); - bool delSub(); - SOptReqHead createReqHead(const RelaySetting &relaySetting); - std::vector createCtrlQueue(const QList &keyList, const QList &valueList); - - bool parseMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - bool checkMsg(std::string strHostName, std::string strInstName, int64 nOptTime); - - bool parseReadMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - bool parseEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - bool parseAffirmMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - bool parseGEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply); - - void test(const QString & cmd, int isSuccess); - - void readTest(RelayCmdReply &relayCmdReply,const QString &cmd); - void editTest(RelayCmdReply &relayCmdReply,const QString &cmd); - void affirmTest(RelayCmdReply &relayCmdReply,const QString &cmd); - void editGroupTest(RelayCmdReply &relayCmdReply,const QString &cmd); -private: - kbd_net::CMbCommunicator *m_communicator; - QTimer *m_timer; - - kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; - CPermMngApiPtr m_permMng; - - std::string m_curRtu; - std::string m_strHostName; - std::string m_strInstName; - int64 m_nOptTime; - - QString m_requestCmd; -}; - -#endif // CRELAYSETTINGMSGMNG_H +#ifndef CRELAYSETTINGMSGMNG_H +#define CRELAYSETTINGMSGMNG_H + +#include +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "common/MessageChannel.h" +#include +#include "CRelaySettingCommon.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" + +using namespace kbd_public; +using namespace kbd_service; + +class CRelaySettingMsgMng : public QObject +{ + Q_OBJECT +public: + explicit CRelaySettingMsgMng(QObject *parent = nullptr); + virtual ~CRelaySettingMsgMng(); +signals: + + void recvOuttime(); + + void dataChanged(const RelayCmdReply &reply,const QString &cmd); + + void sendError(); + +public slots: + void slotcmd(const QList &keyList, const QList &valueList, const RelaySetting &relaySetting,const QString & cmd); + void recvMessage(); + +private: + void init(); + void initMsg(); + void closeMsg(); + + bool addSub(int appID, int channel); + bool delSub(int appID, int channel); + + bool addSub(); + bool delSub(); + SOptReqHead createReqHead(const RelaySetting &relaySetting); + std::vector createCtrlQueue(const QList &keyList, const QList &valueList); + + bool parseMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + bool checkMsg(std::string strHostName, std::string strInstName, int64 nOptTime); + + bool parseReadMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + bool parseEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + bool parseAffirmMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + bool parseGEditMsg(const SOptCustCtrlReply &sOptCustCtrlReply); + + void test(const QString & cmd, int isSuccess); + + void readTest(RelayCmdReply &relayCmdReply,const QString &cmd); + void editTest(RelayCmdReply &relayCmdReply,const QString &cmd); + void affirmTest(RelayCmdReply &relayCmdReply,const QString &cmd); + void editGroupTest(RelayCmdReply &relayCmdReply,const QString &cmd); +private: + kbd_net::CMbCommunicator *m_communicator; + QTimer *m_timer; + + kbd_public::CSysInfoInterfacePtr m_ptrSysInfo; + CPermMngApiPtr m_permMng; + + std::string m_curRtu; + std::string m_strHostName; + std::string m_strInstName; + int64 m_nOptTime; + + QString m_requestCmd; +}; + +#endif // CRELAYSETTINGMSGMNG_H diff --git a/product/src/gui/plugin/TelBookWidget/CRelaySettingPluginWidget.cpp b/product/src/gui/plugin/TelBookWidget/CRelaySettingPluginWidget.cpp index 5a81468a..7f5536d1 100644 --- a/product/src/gui/plugin/TelBookWidget/CRelaySettingPluginWidget.cpp +++ b/product/src/gui/plugin/TelBookWidget/CRelaySettingPluginWidget.cpp @@ -1,26 +1,26 @@ -#include "CRelaySettingPluginWidget.h" -#include "CTelBookWidget.h" -#include - -CRelaySettingPluginWidget::CRelaySettingPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CRelaySettingPluginWidget::~CRelaySettingPluginWidget() -{ - -} - -bool CRelaySettingPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CTelBookWidget *pWidget = new CTelBookWidget(editMode, parent); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CRelaySettingPluginWidget::release() -{ - -} +#include "CRelaySettingPluginWidget.h" +#include "CTelBookWidget.h" +#include + +CRelaySettingPluginWidget::CRelaySettingPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CRelaySettingPluginWidget::~CRelaySettingPluginWidget() +{ + +} + +bool CRelaySettingPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CTelBookWidget *pWidget = new CTelBookWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CRelaySettingPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/TelBookWidget/CRelaySettingPluginWidget.h b/product/src/gui/plugin/TelBookWidget/CRelaySettingPluginWidget.h index 48b99129..793d1a75 100644 --- a/product/src/gui/plugin/TelBookWidget/CRelaySettingPluginWidget.h +++ b/product/src/gui/plugin/TelBookWidget/CRelaySettingPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CRELAYSETTINGPLUGINWIDGET_H -#define CRELAYSETTINGPLUGINWIDGET_H - - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CRelaySettingPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) -public: - CRelaySettingPluginWidget(QObject *parent = 0); - ~CRelaySettingPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif // CRELAYSETTINGPLUGINWIDGET_H +#ifndef CRELAYSETTINGPLUGINWIDGET_H +#define CRELAYSETTINGPLUGINWIDGET_H + + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CRelaySettingPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) +public: + CRelaySettingPluginWidget(QObject *parent = 0); + ~CRelaySettingPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CRELAYSETTINGPLUGINWIDGET_H diff --git a/product/src/gui/plugin/TelBookWidget/CTelBookWidget.cpp b/product/src/gui/plugin/TelBookWidget/CTelBookWidget.cpp index bf548678..eafa2422 100644 --- a/product/src/gui/plugin/TelBookWidget/CTelBookWidget.cpp +++ b/product/src/gui/plugin/TelBookWidget/CTelBookWidget.cpp @@ -1,297 +1,297 @@ -/** -*@file ConstWidget -*@brief 保护定值插件 -*@author jxd -*@date 2021-05-12 -*/ -#include "CTelBookWidget.h" -#include "ui_CTelBookWidget.h" -#include "pub_utility_api/FileStyle.h" -#include -#include -#include "pub_logger_api/logger.h" - -#include -#include "CRelaySettingDelegate.h" -#include "cuserdialog.h" - - -CTelBookWidget::CTelBookWidget(bool editMode, QWidget *parent) : - QWidget(parent), - ui(new Ui::CTelBookWidge) -{ - ui->setupUi(this); - - initStyleSheet(); - - if(!editMode) - { - initialize(); - } -} - -CTelBookWidget::~CTelBookWidget() -{ - - delete ui; -} - -void CTelBookWidget::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - -} - -void CTelBookWidget::initialize() -{ - /* m_enableList<getLocalNodeInfo(m_nodeInfo) == kbdSuccess) - { - LOGINFO("获取节点信息成功!"); - }else - { - LOGINFO("获取节点信息失败!"); - } - //3. - m_permMng = getPermMngInstance("base"); - if(m_permMng != NULL) - { - if(m_permMng->PermDllInit() != PERM_NORMAL) - { - LOGERROR("权限接口初始化失败!"); - } - } - - //4.获取位置 - loadLoc(); - //5.获取rtu - loadRtu(); - //6.获取前置设备 - loadDev(); - //7.获取位置rtu设备 - loadLocRtuDev(); - //8.获取unit - loadUnit(); - //9.获取dict - loadDict(); - //10.获取保护定值 - loadSetting(); -;*/ - //获取modbus - loadConfig(); - - initView(); - initConn(); -} - -//loadModbus -void CTelBookWidget::loadConfig() -{ - m_telList = relayFile.getTelList(); - updateTable(); -} - -void CTelBookWidget::updateTable() -{ - ui->tableWidget->setRowCount(0); - for(int index(0);indextableWidget->rowCount(); - ui->tableWidget->insertRow(rowCount); - - QTableWidgetItem *item = new QTableWidgetItem(); - item->setText(QString::number(index)); - item->setData(Qt::UserRole,index); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,0,item); - - item = new QTableWidgetItem(); - item->setText(relaySetting.code); - item->setData(Qt::UserRole,relaySetting.code); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,1,item); - - item = new QTableWidgetItem(); - item->setText(relaySetting.name); - item->setData(Qt::UserRole,relaySetting.name); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,2,item); - - item = new QTableWidgetItem(); - item->setText(relaySetting.phone); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,3,item); - - item = new QTableWidgetItem(); - item->setText(relaySetting.tel); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,4,item); - - item = new QTableWidgetItem(); - item->setText(relaySetting.company); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,5,item); - - item = new QTableWidgetItem(); - item->setText(relaySetting.remark); - item->setData(Qt::UserRole,""); - item->setTextAlignment(Qt::AlignCenter); - ui->tableWidget->setItem(rowCount,6,item); - -} - -void CTelBookWidget::initView() -{ - ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - - //设置只能单选 - ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); - //设置选择行 - ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - - QHeaderView* headerView = ui->tableWidget->verticalHeader(); - headerView->setHidden(false); -} - -void CTelBookWidget::initConn() -{ - connect(ui->tableWidget,&QTableWidget::itemDoubleClicked,this,&CTelBookWidget::tableItemDoubleClicked); - connect(ui->add,&QPushButton::clicked,this,&CTelBookWidget::addBtnClicked); - connect(ui->edit,&QPushButton::clicked,this,&CTelBookWidget::editBtnClicked); - connect(ui->del,&QPushButton::clicked,this,&CTelBookWidget::delBtnClicked); -} - -void CTelBookWidget::brush() -{ - - -} - -void CTelBookWidget::tableItemDoubleClicked(QTableWidgetItem *item) -{ - editBtnClicked(); - -} - -void CTelBookWidget::addBtnClicked() -{ - - CUserDialog dlg; - dlg.m_telList =m_telList; - dlg.m_operType = 1; - int ret = dlg.exec(); - if(ret >0) - { - m_telList = dlg.m_telList; - saveFile(); - } -} - -void CTelBookWidget::editBtnClicked() -{ - int currentRow = ui->tableWidget->currentIndex().row(); - if(currentRow <0) - { - QMessageBox::information(this,"","请选择!",QMessageBox::Ok); - return; - } - QString code =ui->tableWidget->item(currentRow,1)->text(); - - CUserDialog dlg; - dlg.m_telList =m_telList; - dlg.m_operType = 2; - dlg.SetUser(code); - - int ret = dlg.exec(); - if(ret >0) - { - m_telList = dlg.m_telList; - saveFile(); - } -} - -void CTelBookWidget::delBtnClicked() -{ - - int currentRow = ui->tableWidget->currentIndex().row(); - if(currentRow <0) - { - QMessageBox::information(this,"","请选择!",QMessageBox::Ok); - return; - } - - QString code =ui->tableWidget->item(currentRow,1)->text(); - QString name =ui->tableWidget->item(currentRow,2)->text(); - QString str= QString("确认删除联系人 %1?").arg(name); - if(QMessageBox::information(this,"确认",str,QMessageBox::Ok | QMessageBox::Cancel) ==QMessageBox::Ok) - { - for(int index(0);index +#include +#include "pub_logger_api/logger.h" + +#include +#include "CRelaySettingDelegate.h" +#include "cuserdialog.h" + + +CTelBookWidget::CTelBookWidget(bool editMode, QWidget *parent) : + QWidget(parent), + ui(new Ui::CTelBookWidge) +{ + ui->setupUi(this); + + initStyleSheet(); + + if(!editMode) + { + initialize(); + } +} + +CTelBookWidget::~CTelBookWidget() +{ + + delete ui; +} + +void CTelBookWidget::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("relaySetting.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + +} + +void CTelBookWidget::initialize() +{ + /* m_enableList<getLocalNodeInfo(m_nodeInfo) == kbdSuccess) + { + LOGINFO("获取节点信息成功!"); + }else + { + LOGINFO("获取节点信息失败!"); + } + //3. + m_permMng = getPermMngInstance("base"); + if(m_permMng != NULL) + { + if(m_permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + } + } + + //4.获取位置 + loadLoc(); + //5.获取rtu + loadRtu(); + //6.获取前置设备 + loadDev(); + //7.获取位置rtu设备 + loadLocRtuDev(); + //8.获取unit + loadUnit(); + //9.获取dict + loadDict(); + //10.获取保护定值 + loadSetting(); +;*/ + //获取modbus + loadConfig(); + + initView(); + initConn(); +} + +//loadModbus +void CTelBookWidget::loadConfig() +{ + m_telList = relayFile.getTelList(); + updateTable(); +} + +void CTelBookWidget::updateTable() +{ + ui->tableWidget->setRowCount(0); + for(int index(0);indextableWidget->rowCount(); + ui->tableWidget->insertRow(rowCount); + + QTableWidgetItem *item = new QTableWidgetItem(); + item->setText(QString::number(index)); + item->setData(Qt::UserRole,index); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,0,item); + + item = new QTableWidgetItem(); + item->setText(relaySetting.code); + item->setData(Qt::UserRole,relaySetting.code); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,1,item); + + item = new QTableWidgetItem(); + item->setText(relaySetting.name); + item->setData(Qt::UserRole,relaySetting.name); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,2,item); + + item = new QTableWidgetItem(); + item->setText(relaySetting.phone); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,3,item); + + item = new QTableWidgetItem(); + item->setText(relaySetting.tel); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,4,item); + + item = new QTableWidgetItem(); + item->setText(relaySetting.company); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,5,item); + + item = new QTableWidgetItem(); + item->setText(relaySetting.remark); + item->setData(Qt::UserRole,""); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(rowCount,6,item); + +} + +void CTelBookWidget::initView() +{ + ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + + //设置只能单选 + ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); + //设置选择行 + ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + + QHeaderView* headerView = ui->tableWidget->verticalHeader(); + headerView->setHidden(false); +} + +void CTelBookWidget::initConn() +{ + connect(ui->tableWidget,&QTableWidget::itemDoubleClicked,this,&CTelBookWidget::tableItemDoubleClicked); + connect(ui->add,&QPushButton::clicked,this,&CTelBookWidget::addBtnClicked); + connect(ui->edit,&QPushButton::clicked,this,&CTelBookWidget::editBtnClicked); + connect(ui->del,&QPushButton::clicked,this,&CTelBookWidget::delBtnClicked); +} + +void CTelBookWidget::brush() +{ + + +} + +void CTelBookWidget::tableItemDoubleClicked(QTableWidgetItem *item) +{ + editBtnClicked(); + +} + +void CTelBookWidget::addBtnClicked() +{ + + CUserDialog dlg; + dlg.m_telList =m_telList; + dlg.m_operType = 1; + int ret = dlg.exec(); + if(ret >0) + { + m_telList = dlg.m_telList; + saveFile(); + } +} + +void CTelBookWidget::editBtnClicked() +{ + int currentRow = ui->tableWidget->currentIndex().row(); + if(currentRow <0) + { + QMessageBox::information(this,"","请选择!",QMessageBox::Ok); + return; + } + QString code =ui->tableWidget->item(currentRow,1)->text(); + + CUserDialog dlg; + dlg.m_telList =m_telList; + dlg.m_operType = 2; + dlg.SetUser(code); + + int ret = dlg.exec(); + if(ret >0) + { + m_telList = dlg.m_telList; + saveFile(); + } +} + +void CTelBookWidget::delBtnClicked() +{ + + int currentRow = ui->tableWidget->currentIndex().row(); + if(currentRow <0) + { + QMessageBox::information(this,"","请选择!",QMessageBox::Ok); + return; + } + + QString code =ui->tableWidget->item(currentRow,1)->text(); + QString name =ui->tableWidget->item(currentRow,2)->text(); + QString str= QString("确认删除联系人 %1?").arg(name); + if(QMessageBox::information(this,"确认",str,QMessageBox::Ok | QMessageBox::Cancel) ==QMessageBox::Ok) + { + for(int index(0);index -#include "pub_sysinfo_api/SysInfoApi.h" -#include "perm_mng_api/PermMngApi.h" -#include "CRelaySettingCommon.h" -#include -#include "CRelaySettingMsgMng.h" -#include -#include "sys/sys_login_api/CLoginDlg.h" - - -#include "CRelayFile.h" -#include "CRelayCommon.h" - -namespace Ui { -class CTelBookWidge; -} - -enum EN_RELAY_TYPE -{ - EN_RELAY_LOC = 1001, - EN_RELAY_RTU = 1002, - EN_RELAY_DEV = 1003 -}; - -enum EN_RELAY_TREE_TYPE -{ - EN_RELAY_TREE_LOC = 2001, - EN_RELAY_TREE_CHANL = 20002 -}; - -using namespace kbd_public; -using namespace kbd_service; - -class CTelBookWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CTelBookWidget(bool editMode, QWidget *parent = 0); - ~CTelBookWidget(); - -private: - void initStyleSheet(); - - void initView(); - - void initConn(); - - void brush(); - - void loadConfig(); - - void insertToTable(SUserTelInfo relaySetting, int index); - - void updateTable(); - -private slots: - - void tableItemDoubleClicked(QTableWidgetItem *item); - - void addBtnClicked(); - - void editBtnClicked(); - - void delBtnClicked(); - void saveFile(); - -public slots: - void initialize(); - -private: - Ui::CTelBookWidge *ui; - - CRelayFile relayFile; - - QList m_telList; - -}; - -#endif // CRELAYSETTINGWIDGET_H +#ifndef CRELAYSETTINGWIDGET_H +#define CRELAYSETTINGWIDGET_H + +#include +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "CRelaySettingCommon.h" +#include +#include "CRelaySettingMsgMng.h" +#include +#include "sys/sys_login_api/CLoginDlg.h" + + +#include "CRelayFile.h" +#include "CRelayCommon.h" + +namespace Ui { +class CTelBookWidge; +} + +enum EN_RELAY_TYPE +{ + EN_RELAY_LOC = 1001, + EN_RELAY_RTU = 1002, + EN_RELAY_DEV = 1003 +}; + +enum EN_RELAY_TREE_TYPE +{ + EN_RELAY_TREE_LOC = 2001, + EN_RELAY_TREE_CHANL = 20002 +}; + +using namespace kbd_public; +using namespace kbd_service; + +class CTelBookWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CTelBookWidget(bool editMode, QWidget *parent = 0); + ~CTelBookWidget(); + +private: + void initStyleSheet(); + + void initView(); + + void initConn(); + + void brush(); + + void loadConfig(); + + void insertToTable(SUserTelInfo relaySetting, int index); + + void updateTable(); + +private slots: + + void tableItemDoubleClicked(QTableWidgetItem *item); + + void addBtnClicked(); + + void editBtnClicked(); + + void delBtnClicked(); + void saveFile(); + +public slots: + void initialize(); + +private: + Ui::CTelBookWidge *ui; + + CRelayFile relayFile; + + QList m_telList; + +}; + +#endif // CRELAYSETTINGWIDGET_H diff --git a/product/src/gui/plugin/TelBookWidget/CTelBookWidget.ui b/product/src/gui/plugin/TelBookWidget/CTelBookWidget.ui index ff3eb0f6..f2b83a35 100644 --- a/product/src/gui/plugin/TelBookWidget/CTelBookWidget.ui +++ b/product/src/gui/plugin/TelBookWidget/CTelBookWidget.ui @@ -1,112 +1,112 @@ - - - CTelBookWidge - - - - 0 - 0 - 819 - 619 - - - - 保护定值管理 - - - - - - - 0 - 0 - - - - QAbstractItemView::SelectRows - - - - 序号 - - - - - 用户代码 - - - - - 姓名 - - - - - 手机 - - - - - 电话 - - - - - 单位 - - - - - 备注 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 添加 - - - - - - - 修改 - - - - - - - 删除 - - - - - - - - - - - - - + + + CTelBookWidge + + + + 0 + 0 + 819 + 619 + + + + 保护定值管理 + + + + + + + 0 + 0 + + + + QAbstractItemView::SelectRows + + + + 序号 + + + + + 用户代码 + + + + + 姓名 + + + + + 手机 + + + + + 电话 + + + + + 单位 + + + + + 备注 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 添加 + + + + + + + 修改 + + + + + + + 删除 + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/TelBookWidget/TelBookWidget.pro b/product/src/gui/plugin/TelBookWidget/TelBookWidget.pro index da45505a..cc0f0633 100644 --- a/product/src/gui/plugin/TelBookWidget/TelBookWidget.pro +++ b/product/src/gui/plugin/TelBookWidget/TelBookWidget.pro @@ -1,81 +1,81 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-05-07T14:09:49 -# -#------------------------------------------------- - -QT += core gui sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TEMPLATE = lib - -TARGET = TelBookWidget - -CONFIG += plugin -CONFIG += c++11 -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ -# main.cpp \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ - CRelaySettingMsgMng.cpp \ - CRelaySettingPluginWidget.cpp \ - CLogMng.cpp \ - CRelayFile.cpp \ - CTelBookWidget.cpp \ - cuserdialog.cpp - -HEADERS += \ - ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ - ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ - CRelaySettingCommon.h \ - CRelaySettingMsgMng.h \ - CRelaySettingPluginWidget.h \ - CLogMng.h \ - CRelayCommon.h \ - CRelayFile.h \ - publicpara.h \ - CTelBookWidget.h \ - cuserdialog.h - -FORMS += \ - CTelBookWidget.ui \ - cuserdialog.ui - -LIBS += \ - -lprotobuf \ - -ldb_base_api \ - -ldb_api_ex \ - -lnet_msg_bus_api \ - -lpub_sysinfo_api \ - -lperm_mng_api \ - -llog4cplus \ - -lpub_logger_api \ - -ldp_chg_data_api \ - -lrdb_api \ - -lrdb_net_api \ - -lpub_utility_api \ - -lpub_sysinfo_api \ - -lsys_login_api - - - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-05-07T14:09:49 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib + +TARGET = TelBookWidget + +CONFIG += plugin +CONFIG += c++11 +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ +# main.cpp \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + CRelaySettingMsgMng.cpp \ + CRelaySettingPluginWidget.cpp \ + CLogMng.cpp \ + CRelayFile.cpp \ + CTelBookWidget.cpp \ + cuserdialog.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CRelaySettingCommon.h \ + CRelaySettingMsgMng.h \ + CRelaySettingPluginWidget.h \ + CLogMng.h \ + CRelayCommon.h \ + CRelayFile.h \ + publicpara.h \ + CTelBookWidget.h \ + cuserdialog.h + +FORMS += \ + CTelBookWidget.ui \ + cuserdialog.ui + +LIBS += \ + -lprotobuf \ + -ldb_base_api \ + -ldb_api_ex \ + -lnet_msg_bus_api \ + -lpub_sysinfo_api \ + -lperm_mng_api \ + -llog4cplus \ + -lpub_logger_api \ + -ldp_chg_data_api \ + -lrdb_api \ + -lrdb_net_api \ + -lpub_utility_api \ + -lpub_sysinfo_api \ + -lsys_login_api + + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/TelBookWidget/cuserdialog.cpp b/product/src/gui/plugin/TelBookWidget/cuserdialog.cpp index a212c50f..6858c7e0 100644 --- a/product/src/gui/plugin/TelBookWidget/cuserdialog.cpp +++ b/product/src/gui/plugin/TelBookWidget/cuserdialog.cpp @@ -1,89 +1,89 @@ -#include "cuserdialog.h" -#include "ui_cuserdialog.h" - -#include - -CUserDialog::CUserDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CUserDialog) -{ - ui->setupUi(this); - -} - - -CUserDialog::~CUserDialog() -{ - delete ui; -} - -void CUserDialog::SetUser(QString code) -{ - if(m_operType ==2) - { - for(int index(0);indexlineEdit_code->setEnabled(false); - ui->lineEdit_code->setText(tel.code); - ui->lineEdit_name->setText(tel.name); - ui->lineEdit_phone->setText(tel.phone); - ui->lineEdit_Tel->setText(tel.tel); - ui->lineEdit_cpmpany->setText(tel.company); - ui->lineEdit_remark->setText(tel.remark); - - } - } - } -} - -void CUserDialog::on_buttonBox_accepted() -{ - QString code = ui->lineEdit_code->text(); - if(m_operType ==1) - { - if(code =="") - { - QMessageBox::warning(this,"","用户代码不能为空"); - return; - } - - for(int index(0);indexlineEdit_code->text(); - info.name = ui->lineEdit_name->text(); - info.phone = ui->lineEdit_phone->text(); - info.tel = ui->lineEdit_Tel->text(); - info.company = ui->lineEdit_cpmpany->text(); - info.remark = ui->lineEdit_remark->text(); - m_telList.append(info); - - }else if(m_operType ==2) - { - - for(int index(0);indexlineEdit_name->text(); - m_telList[index].phone = ui->lineEdit_phone->text(); - m_telList[index].tel = ui->lineEdit_Tel->text(); - m_telList[index].company = ui->lineEdit_cpmpany->text(); - m_telList[index].remark = ui->lineEdit_remark->text(); - } - } - - } -} +#include "cuserdialog.h" +#include "ui_cuserdialog.h" + +#include + +CUserDialog::CUserDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CUserDialog) +{ + ui->setupUi(this); + +} + + +CUserDialog::~CUserDialog() +{ + delete ui; +} + +void CUserDialog::SetUser(QString code) +{ + if(m_operType ==2) + { + for(int index(0);indexlineEdit_code->setEnabled(false); + ui->lineEdit_code->setText(tel.code); + ui->lineEdit_name->setText(tel.name); + ui->lineEdit_phone->setText(tel.phone); + ui->lineEdit_Tel->setText(tel.tel); + ui->lineEdit_cpmpany->setText(tel.company); + ui->lineEdit_remark->setText(tel.remark); + + } + } + } +} + +void CUserDialog::on_buttonBox_accepted() +{ + QString code = ui->lineEdit_code->text(); + if(m_operType ==1) + { + if(code =="") + { + QMessageBox::warning(this,"","用户代码不能为空"); + return; + } + + for(int index(0);indexlineEdit_code->text(); + info.name = ui->lineEdit_name->text(); + info.phone = ui->lineEdit_phone->text(); + info.tel = ui->lineEdit_Tel->text(); + info.company = ui->lineEdit_cpmpany->text(); + info.remark = ui->lineEdit_remark->text(); + m_telList.append(info); + + }else if(m_operType ==2) + { + + for(int index(0);indexlineEdit_name->text(); + m_telList[index].phone = ui->lineEdit_phone->text(); + m_telList[index].tel = ui->lineEdit_Tel->text(); + m_telList[index].company = ui->lineEdit_cpmpany->text(); + m_telList[index].remark = ui->lineEdit_remark->text(); + } + } + + } +} diff --git a/product/src/gui/plugin/TelBookWidget/cuserdialog.h b/product/src/gui/plugin/TelBookWidget/cuserdialog.h index f74a5ab3..6c1c2839 100644 --- a/product/src/gui/plugin/TelBookWidget/cuserdialog.h +++ b/product/src/gui/plugin/TelBookWidget/cuserdialog.h @@ -1,31 +1,31 @@ -#ifndef CUSERDIALOG_H -#define CUSERDIALOG_H - -#include -#include "CRelayCommon.h" - -namespace Ui { -class CUserDialog; -} - -class CUserDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CUserDialog(QWidget *parent = 0); - ~CUserDialog(); - int m_operType; - - QList m_telList; - QString m_code; - - void SetUser(QString code); -private slots: - void on_buttonBox_accepted(); - -private: - Ui::CUserDialog *ui; -}; - -#endif // CUSERDIALOG_H +#ifndef CUSERDIALOG_H +#define CUSERDIALOG_H + +#include +#include "CRelayCommon.h" + +namespace Ui { +class CUserDialog; +} + +class CUserDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CUserDialog(QWidget *parent = 0); + ~CUserDialog(); + int m_operType; + + QList m_telList; + QString m_code; + + void SetUser(QString code); +private slots: + void on_buttonBox_accepted(); + +private: + Ui::CUserDialog *ui; +}; + +#endif // CUSERDIALOG_H diff --git a/product/src/gui/plugin/TelBookWidget/cuserdialog.ui b/product/src/gui/plugin/TelBookWidget/cuserdialog.ui index 1164d74d..103c85bb 100644 --- a/product/src/gui/plugin/TelBookWidget/cuserdialog.ui +++ b/product/src/gui/plugin/TelBookWidget/cuserdialog.ui @@ -1,177 +1,177 @@ - - - CUserDialog - - - - 0 - 0 - 288 - 305 - - - - - - - - - 70 - 260 - 156 - 23 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 120 - 30 - 81 - 21 - - - - 联系人信息 - - - - - - 61 - 71 - 179 - 164 - - - - - - - - - 代码: - - - - - - - - - - - - - - 姓名: - - - - - - - - - - - - - - 手机: - - - - - - - - - - - - - - 电话: - - - - - - - - - - - - - - 单位: - - - - - - - - - - - - - - 备注: - - - - - - - - - - - - - - - buttonBox - accepted() - CUserDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - CUserDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - + + + CUserDialog + + + + 0 + 0 + 288 + 305 + + + + + + + + + 70 + 260 + 156 + 23 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 120 + 30 + 81 + 21 + + + + 联系人信息 + + + + + + 61 + 71 + 179 + 164 + + + + + + + + + 代码: + + + + + + + + + + + + + + 姓名: + + + + + + + + + + + + + + 手机: + + + + + + + + + + + + + + 电话: + + + + + + + + + + + + + + 单位: + + + + + + + + + + + + + + 备注: + + + + + + + + + + + + + + + buttonBox + accepted() + CUserDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CUserDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/product/src/gui/plugin/TelBookWidget/main.cpp b/product/src/gui/plugin/TelBookWidget/main.cpp index 143f4e0a..b6f90ce9 100644 --- a/product/src/gui/plugin/TelBookWidget/main.cpp +++ b/product/src/gui/plugin/TelBookWidget/main.cpp @@ -1,40 +1,40 @@ -#include "CRelaySettingWidget.h" -#include -#include "pub_logger_api/logger.h" -#include "net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - kbd_public::StartLogSystem("HMI", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - { - CRelaySettingWidget w(false); - //设置过滤条件 - w.setFilterGroup("station1.PSCADA.digital.station1.NQ-G14_dlq.Pos.value,station1.PSCADA.digital.station1.NQ-G16_dlq.Pos.value"); - w.setTreeHidden(true);//隐藏左侧设备树 - - w.show(); - app.exec(); - } - - //<释放消息总线 - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "CRelaySettingWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + kbd_public::StartLogSystem("HMI", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + { + CRelaySettingWidget w(false); + //设置过滤条件 + w.setFilterGroup("station1.PSCADA.digital.station1.NQ-G14_dlq.Pos.value,station1.PSCADA.digital.station1.NQ-G16_dlq.Pos.value"); + w.setTreeHidden(true);//隐藏左侧设备树 + + w.show(); + app.exec(); + } + + //<释放消息总线 + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/TelBookWidget/publicpara.h b/product/src/gui/plugin/TelBookWidget/publicpara.h index 8891d66a..7c93d7e6 100644 --- a/product/src/gui/plugin/TelBookWidget/publicpara.h +++ b/product/src/gui/plugin/TelBookWidget/publicpara.h @@ -1,64 +1,64 @@ -#ifndef PUBLICPARA_H -#define PUBLICPARA_H - -#define CHAN_MAX_NUM 256 //通道数 -#define DZ_DATA_MAX_NUM 50 //点数 -#define BLOCK_MAX_NUM 40 //点数 -#define DZ_NAME_LEN 40 -#define MAX_PATH 260 - -typedef unsigned char BYTE; -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; - - - -typedef struct -{ - int chNo; - float fValue; //值 - int pAddr; //寄存器地址 - float Modulus; //系数 - int Revise; //附加值 - int BoardNo; //定值组号 - int PointNo; //定值点号 - int ValueType; //值类型 - char dzName[DZ_NAME_LEN]; //定值名称 - bool isFlag; - int glFlag; //过流标示 - int timeFlag; //延迟标示 -}DZSTR; - -typedef struct -{ - int chNo; - BYTE FunCode; - ushort StartAddr; - ushort RegisterLen; - bool DzBlockChagFlag; - bool isFlag; -}DZ_BLOCK_STR; - -typedef struct -{ - int chNo; - int dzNo; - int DzBlockNo; - int DzModFlag; - float fValue; //值 -}MOD_DZ_STR; - -typedef struct CHANPARA{ - int chNo; //通道序号 - int checkFlag; - DZSTR dzstr[DZ_DATA_MAX_NUM]; - int readNum; - CHANPARA(){ - - } -}CHANPARA_; - - -#endif // PUBLICPARA_H +#ifndef PUBLICPARA_H +#define PUBLICPARA_H + +#define CHAN_MAX_NUM 256 //通道数 +#define DZ_DATA_MAX_NUM 50 //点数 +#define BLOCK_MAX_NUM 40 //点数 +#define DZ_NAME_LEN 40 +#define MAX_PATH 260 + +typedef unsigned char BYTE; +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + + + +typedef struct +{ + int chNo; + float fValue; //值 + int pAddr; //寄存器地址 + float Modulus; //系数 + int Revise; //附加值 + int BoardNo; //定值组号 + int PointNo; //定值点号 + int ValueType; //值类型 + char dzName[DZ_NAME_LEN]; //定值名称 + bool isFlag; + int glFlag; //过流标示 + int timeFlag; //延迟标示 +}DZSTR; + +typedef struct +{ + int chNo; + BYTE FunCode; + ushort StartAddr; + ushort RegisterLen; + bool DzBlockChagFlag; + bool isFlag; +}DZ_BLOCK_STR; + +typedef struct +{ + int chNo; + int dzNo; + int DzBlockNo; + int DzModFlag; + float fValue; //值 +}MOD_DZ_STR; + +typedef struct CHANPARA{ + int chNo; //通道序号 + int checkFlag; + DZSTR dzstr[DZ_DATA_MAX_NUM]; + int readNum; + CHANPARA(){ + + } +}CHANPARA_; + + +#endif // PUBLICPARA_H diff --git a/product/src/gui/plugin/TrendCurves/CCurveLegendModel.cpp b/product/src/gui/plugin/TrendCurves/CCurveLegendModel.cpp index 39150208..276bc1d7 100644 --- a/product/src/gui/plugin/TrendCurves/CCurveLegendModel.cpp +++ b/product/src/gui/plugin/TrendCurves/CCurveLegendModel.cpp @@ -1,579 +1,579 @@ -#include "CCurveLegendModel.h" -#include "CTrendGraph.h" -#include -#include -#include -#include -#include -#include - -ColorWidget::ColorWidget(QWidget *parent) - : QWidget(parent) -{ - setStyleSheet(""); -} - -ColorWidget::~ColorWidget() -{ -} - -void ColorWidget::setColor(const QColor &color) -{ - this->m_color = color; - emit colorChanged(); -} - -QColor ColorWidget::color() const -{ - return m_color; -} - -void ColorWidget::updateCurrentColor() -{ - QColorDialog dlg(this); - dlg.setOption(QColorDialog::DontUseNativeDialog); - dlg.setWindowFlag(Qt::FramelessWindowHint); - dlg.setCurrentColor(m_color); - dlg.exec(); - if(dlg.selectedColor().isValid()) - { - setColor(dlg.selectedColor()); - } -} - -void ColorWidget::paintEvent(QPaintEvent *event) -{ - QPainter p(this); - p.setPen(Qt::white); - p.setBrush(m_color); - p.drawRect(rect().adjusted(4, 7, -4, -7)); - QWidget::paintEvent(event); -} - -void ColorWidget::mousePressEvent(QMouseEvent *event) -{ - QWidget::mousePressEvent(event); - updateCurrentColor(); -} - - -CCurveLegnedDelegate::CCurveLegnedDelegate(QObject *parent) - : QStyledItemDelegate(parent) -{ - -} - -void CCurveLegnedDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QStyleOptionViewItem viewOption(option); - initStyleOption(&viewOption, index); - if (option.state.testFlag(QStyle::State_HasFocus)) - { - viewOption.state = viewOption.state ^ QStyle::State_HasFocus; - } - QStyledItemDelegate::paint(painter, viewOption, index); - - if(!index.isValid() || !const_cast(index.model())) - { - return; - } - CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); - if(!model) - { - return; - } - - if(CCurveLegendModel::COLOR == index.column()) - { - painter->save(); - painter->fillRect(option.rect.adjusted(4, 7, -4, -7), QBrush(Qt::white)); - painter->fillRect(option.rect.adjusted(4, 7, -4, -7), QBrush(model->data(index).value())); - painter->restore(); - } -} - -QWidget *CCurveLegnedDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(option) - if(!index.isValid() || !const_cast(index.model())) - { - return Q_NULLPTR; - } - CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); - if(!model) - { - return Q_NULLPTR; - } - - if(CCurveLegendModel::COLOR == index.column()) - { - ColorWidget * colorWidget = new ColorWidget(parent); - connect(colorWidget, &ColorWidget::colorChanged, this, &CCurveLegnedDelegate::slotColorChangde); - return colorWidget; - } - if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) - { - QDoubleSpinBox * spinBox = new QDoubleSpinBox(parent); - return spinBox; - } - - return Q_NULLPTR; -} - -void CCurveLegnedDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - if(!index.isValid() || Q_NULLPTR == editor) - { - return; - } - - CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); - if(!model) - { - return; - } - - if(CCurveLegendModel::COLOR == index.column()) - { - ColorWidget * colorWidget = dynamic_cast(editor); - if(colorWidget) - { - colorWidget->setColor(model->data(index).value()); - } - return; - } - if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) - { - QDoubleSpinBox * spinBox = dynamic_cast(editor); - if(spinBox) - { - spinBox->setValue(model->data(index).toDouble()); - spinBox->setSingleStep(1.); - spinBox->setMaximum(10000); - spinBox->setMinimum(-10000); - } - return; - } - return; -} - -void CCurveLegnedDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - if(!index.isValid() || !const_cast(index.model())) - { - return; - } - if(!model) - { - return; - } - - if(dynamic_cast(editor)) - { - model->setData(index, dynamic_cast(editor)->value()); - return; - } - else if(dynamic_cast(editor)) - { - model->setData(index, dynamic_cast(editor)->color()); - return; - } - -} - -bool CCurveLegnedDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ -// if(index.column() == 0 && event->type() == QEvent::MouseButtonPress) -// { -// QMouseEvent *mouseEvent = static_cast(event); -// if(mouseEvent->button() == Qt::LeftButton && option.rect.contains(mouseEvent->pos())) -// { -// if(const_cast(index.model())) -// { -// CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); -// if(!model) -// { -// return QStyledItemDelegate::editorEvent(event, model, option, index); -// } -// } -// } -// } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} - -void CCurveLegnedDelegate::slotColorChangde() -{ - QWidget * pWidget = dynamic_cast(sender()); - if(pWidget) - { - emit commitData(pWidget); - emit closeEditor(pWidget); - } -} - -CCurveLegendModel::CCurveLegendModel(QObject *parent) - : QAbstractTableModel(parent), m_lengedMode(), - m_graph(Q_NULLPTR) -{ - m_header << tr("设备组-测点") << tr("颜色") << tr("值") << tr("最大值") << tr("最大值时间") << tr("最小值") << tr("最小值时间") << tr("平均值") - << tr("单位") << tr("Y轴缩放系数") << tr("Y轴偏移系数"); -} - -void CCurveLegendModel::setMode(const CCurveLegendModel::LengedMode &mode) -{ - m_lengedMode = mode; - update(); -} - -CCurveLegendModel::LengedMode CCurveLegendModel::getMode() -{ - return m_lengedMode; -} - -void CCurveLegendModel::setTrendGraph(CTrendGraph *graph) -{ - if(nullptr == graph) - { - return; - } - - beginResetModel(); - m_graph = graph; - endResetModel(); -} - -void CCurveLegendModel::setTrendCurrentValues(QList list) -{ - m_currentValue.swap(list); - update(); -} - -void CCurveLegendModel::update() -{ - QModelIndex topLeft = createIndex(0, VALUE); - QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); - emit dataChanged(topLeft, bottomRight); -} - -void CCurveLegendModel::clear() -{ - beginResetModel(); - m_graph = Q_NULLPTR; - m_currentValue.clear(); - endResetModel(); -} - -QVariant CCurveLegendModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_header.at(section); - } - } - return QVariant(); -} - -int CCurveLegendModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid() || Q_NULLPTR == m_graph) - return 0; - - return m_graph->curves().count(); -} - -int CCurveLegendModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid() || Q_NULLPTR == m_graph) - return 0; - - return m_header.count(); -} - -QVariant CCurveLegendModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid() || Q_NULLPTR == m_graph) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == NAME) - { - return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - } - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - - if(Qt::CheckStateRole == role && NAME == index.column()) - { - if(m_graph->curves().at(index.row()).visible) - { - return Qt::Checked; - } - else - { - return Qt::Unchecked; - } - } - - if(Qt::DisplayRole != role) - { - return QVariant(); - } - - Curve curve = m_graph->curves().at(index.row()); - switch (index.column()) - { - case NAME: - { - return curve.desc; - } - break; - case COLOR: - { - return curve.color; - } - break; - case VALUE: - { - if(qIsNaN(m_currentValue.value(index.row()))) - { - return QString("NaN"); - } - else - { - return QString::number(m_currentValue.value(index.row()), 'f', 2); - } - } - break; - case MAX: - { - if(LENGED_RT_MODE == m_lengedMode) - { - if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMax) < _EPSILON_) - { - return QString("--"); - } - return QString::number(curve.rtMax, 'f', 2); - } - else - { - if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.sHisMax) < _EPSILON_) - { - return QString("--"); - } - return QString::number(curve.sHisMax, 'f', 2); - } - } - break; - case MAXTIME: - { - if(LENGED_RT_MODE == m_lengedMode) - { - if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMaxTime) < _EPSILON_) - { - return QString("--"); - } - return QDateTime::fromMSecsSinceEpoch(curve.rtMaxTime).toString("hh:mm:ss"); - } - else - { - if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.sHisMaxTime) < _EPSILON_) - { - return QString("--"); - } - return QDateTime::fromMSecsSinceEpoch(curve.sHisMaxTime).toString("yyyy-MM-dd hh:mm:ss"); - } - } - break; - case MIN: - { - if(LENGED_RT_MODE == m_lengedMode) - { - if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.rtMin) < _EPSILON_) - { - return QString("--"); - } - return QString::number(curve.rtMin, 'f', 2); - } - else - { - if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.sHisMin) < _EPSILON_) - { - return QString("--"); - } - return QString::number(curve.sHisMin, 'f', 2); - } - } - break; - case MINTIME: - { - if(LENGED_RT_MODE == m_lengedMode) - { - if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.rtMinTime) < _EPSILON_) - { - return QString("--"); - } - return QDateTime::fromMSecsSinceEpoch(curve.rtMinTime).toString("hh:mm:ss"); - } - else - { - if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.sHisMinTime) < _EPSILON_) - { - return QString("--"); - } - return QDateTime::fromMSecsSinceEpoch(curve.sHisMinTime).toString("yyyy-MM-dd hh:mm:ss"); - } - } - break; - case AVE: - { - - if(LENGED_RT_MODE == m_lengedMode) - { - if("analog" != curve.type || qAbs((-DBL_MAX) - curve.rtAverage) < _EPSILON_ || qIsNaN(curve.rtAverage)) - { - return QString("--"); - } - return QString::number(curve.rtAverage, 'f', 2); - } - else - { - if("analog" != curve.type || qAbs((-DBL_MAX) - curve.hisAverage) < _EPSILON_ || qIsNaN(curve.hisAverage)) - { - return QString("--"); - } - return QString::number(curve.hisAverage, 'f', 2); - } - } - break; - case UNIT: - { - if(curve.unit.isEmpty()) - { - return QString("--"); - } - return curve.unit; - } - break; - case FACTOR: - { - return curve.factor; - } - break; - case OFFSET: - { - return curve.offset; - } - break; - default: - break; - } - - return QVariant(); -} - -bool CCurveLegendModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if(!index.isValid()) - { - return false; - } - if(Qt::CheckStateRole == role && NAME == index.column()) - { - m_graph->setCurveVisible(index.row(), value.toBool()); - emit graphVisibleChanged(value.toBool()); - return true; - } - if(Qt::EditRole != role) - { - return false; - } - - if(COLOR == index.column()) - { - m_graph->setCurveColor(index.row(), value.value()); - } - if(FACTOR == index.column()) - { - m_graph->setCurveFactor(index.row(), value.toDouble()); - } - else if(OFFSET == index.column()) - { - m_graph->setCurveOffset(index.row(), value.toDouble()); - } - emit graphPropertyChanged(); - - QModelIndex topLeft = createIndex(0, 0); - QModelIndex bottomright = createIndex(rowCount() - 1, columnCount() - 1); - emit dataChanged(topLeft, bottomright); - - return true; -} - -Qt::ItemFlags CCurveLegendModel::flags(const QModelIndex &index) const -{ - if(!index.isValid()) - { - return Qt::NoItemFlags; - } - - Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - if(COLOR == index.column() || FACTOR == index.column() || OFFSET == index.column()) - { - itemFlags |= Qt::ItemIsEditable; - } - else if(NAME == index.column()) - { - itemFlags |= Qt::ItemIsUserCheckable; - } - - return itemFlags; -} - -void CCurveLegendModel::setChildrenCheckState(const Qt::CheckState &state) -{ - for(int nChildIndex(0); nChildIndex < rowCount(); nChildIndex++) - { - m_graph->setCurveVisible(nChildIndex, state); - } - emit graphVisibleChanged(state == Qt::Checked ? true : false); -} - -void CCurveLegendModel::deleteSelectGraph() -{ - emit deleteCurrentGraph(); -} - -void CCurveLegendModel::jumpToMaxTime(const QModelIndex &index) -{ - if(!index.isValid()) - { - return; - } - - Curve curve = m_graph->curves().at(index.row()); - if(qAbs((-DBL_MAX) - curve.sHisMaxTime) < _EPSILON_) - { - return; - } - emit sigJumpToMaxTime(curve.sHisMaxTime); -} - -void CCurveLegendModel::jumpToMinTime(const QModelIndex &index) -{ - if(!index.isValid()) - { - return; - } - - Curve curve = m_graph->curves().at(index.row()); - if(qAbs((DBL_MAX) - curve.sHisMinTime) < _EPSILON_) - { - return; - } - emit sigJumpToMinTime(curve.sHisMinTime); -} +#include "CCurveLegendModel.h" +#include "CTrendGraph.h" +#include +#include +#include +#include +#include +#include + +ColorWidget::ColorWidget(QWidget *parent) + : QWidget(parent) +{ + setStyleSheet(""); +} + +ColorWidget::~ColorWidget() +{ +} + +void ColorWidget::setColor(const QColor &color) +{ + this->m_color = color; + emit colorChanged(); +} + +QColor ColorWidget::color() const +{ + return m_color; +} + +void ColorWidget::updateCurrentColor() +{ + QColorDialog dlg(this); + dlg.setOption(QColorDialog::DontUseNativeDialog); + dlg.setWindowFlag(Qt::FramelessWindowHint); + dlg.setCurrentColor(m_color); + dlg.exec(); + if(dlg.selectedColor().isValid()) + { + setColor(dlg.selectedColor()); + } +} + +void ColorWidget::paintEvent(QPaintEvent *event) +{ + QPainter p(this); + p.setPen(Qt::white); + p.setBrush(m_color); + p.drawRect(rect().adjusted(4, 7, -4, -7)); + QWidget::paintEvent(event); +} + +void ColorWidget::mousePressEvent(QMouseEvent *event) +{ + QWidget::mousePressEvent(event); + updateCurrentColor(); +} + + +CCurveLegnedDelegate::CCurveLegnedDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ + +} + +void CCurveLegnedDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem viewOption(option); + initStyleOption(&viewOption, index); + if (option.state.testFlag(QStyle::State_HasFocus)) + { + viewOption.state = viewOption.state ^ QStyle::State_HasFocus; + } + QStyledItemDelegate::paint(painter, viewOption, index); + + if(!index.isValid() || !const_cast(index.model())) + { + return; + } + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + painter->save(); + painter->fillRect(option.rect.adjusted(4, 7, -4, -7), QBrush(Qt::white)); + painter->fillRect(option.rect.adjusted(4, 7, -4, -7), QBrush(model->data(index).value())); + painter->restore(); + } +} + +QWidget *CCurveLegnedDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid() || !const_cast(index.model())) + { + return Q_NULLPTR; + } + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return Q_NULLPTR; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + ColorWidget * colorWidget = new ColorWidget(parent); + connect(colorWidget, &ColorWidget::colorChanged, this, &CCurveLegnedDelegate::slotColorChangde); + return colorWidget; + } + if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) + { + QDoubleSpinBox * spinBox = new QDoubleSpinBox(parent); + return spinBox; + } + + return Q_NULLPTR; +} + +void CCurveLegnedDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if(!index.isValid() || Q_NULLPTR == editor) + { + return; + } + + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + ColorWidget * colorWidget = dynamic_cast(editor); + if(colorWidget) + { + colorWidget->setColor(model->data(index).value()); + } + return; + } + if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) + { + QDoubleSpinBox * spinBox = dynamic_cast(editor); + if(spinBox) + { + spinBox->setValue(model->data(index).toDouble()); + spinBox->setSingleStep(1.); + spinBox->setMaximum(10000); + spinBox->setMinimum(-10000); + } + return; + } + return; +} + +void CCurveLegnedDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + if(!index.isValid() || !const_cast(index.model())) + { + return; + } + if(!model) + { + return; + } + + if(dynamic_cast(editor)) + { + model->setData(index, dynamic_cast(editor)->value()); + return; + } + else if(dynamic_cast(editor)) + { + model->setData(index, dynamic_cast(editor)->color()); + return; + } + +} + +bool CCurveLegnedDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ +// if(index.column() == 0 && event->type() == QEvent::MouseButtonPress) +// { +// QMouseEvent *mouseEvent = static_cast(event); +// if(mouseEvent->button() == Qt::LeftButton && option.rect.contains(mouseEvent->pos())) +// { +// if(const_cast(index.model())) +// { +// CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); +// if(!model) +// { +// return QStyledItemDelegate::editorEvent(event, model, option, index); +// } +// } +// } +// } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +void CCurveLegnedDelegate::slotColorChangde() +{ + QWidget * pWidget = dynamic_cast(sender()); + if(pWidget) + { + emit commitData(pWidget); + emit closeEditor(pWidget); + } +} + +CCurveLegendModel::CCurveLegendModel(QObject *parent) + : QAbstractTableModel(parent), m_lengedMode(), + m_graph(Q_NULLPTR) +{ + m_header << tr("设备组-测点") << tr("颜色") << tr("值") << tr("最大值") << tr("最大值时间") << tr("最小值") << tr("最小值时间") << tr("平均值") + << tr("单位") << tr("Y轴缩放系数") << tr("Y轴偏移系数"); +} + +void CCurveLegendModel::setMode(const CCurveLegendModel::LengedMode &mode) +{ + m_lengedMode = mode; + update(); +} + +CCurveLegendModel::LengedMode CCurveLegendModel::getMode() +{ + return m_lengedMode; +} + +void CCurveLegendModel::setTrendGraph(CTrendGraph *graph) +{ + if(nullptr == graph) + { + return; + } + + beginResetModel(); + m_graph = graph; + endResetModel(); +} + +void CCurveLegendModel::setTrendCurrentValues(QList list) +{ + m_currentValue.swap(list); + update(); +} + +void CCurveLegendModel::update() +{ + QModelIndex topLeft = createIndex(0, VALUE); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); + emit dataChanged(topLeft, bottomRight); +} + +void CCurveLegendModel::clear() +{ + beginResetModel(); + m_graph = Q_NULLPTR; + m_currentValue.clear(); + endResetModel(); +} + +QVariant CCurveLegendModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); +} + +int CCurveLegendModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid() || Q_NULLPTR == m_graph) + return 0; + + return m_graph->curves().count(); +} + +int CCurveLegendModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid() || Q_NULLPTR == m_graph) + return 0; + + return m_header.count(); +} + +QVariant CCurveLegendModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || Q_NULLPTR == m_graph) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == NAME) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + } + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + if(Qt::CheckStateRole == role && NAME == index.column()) + { + if(m_graph->curves().at(index.row()).visible) + { + return Qt::Checked; + } + else + { + return Qt::Unchecked; + } + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + Curve curve = m_graph->curves().at(index.row()); + switch (index.column()) + { + case NAME: + { + return curve.desc; + } + break; + case COLOR: + { + return curve.color; + } + break; + case VALUE: + { + if(qIsNaN(m_currentValue.value(index.row()))) + { + return QString("NaN"); + } + else + { + return QString::number(m_currentValue.value(index.row()), 'f', 2); + } + } + break; + case MAX: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMax) < _EPSILON_) + { + return QString("--"); + } + return QString::number(curve.rtMax, 'f', 2); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.sHisMax) < _EPSILON_) + { + return QString("--"); + } + return QString::number(curve.sHisMax, 'f', 2); + } + } + break; + case MAXTIME: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMaxTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.rtMaxTime).toString("hh:mm:ss"); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.sHisMaxTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.sHisMaxTime).toString("yyyy-MM-dd hh:mm:ss"); + } + } + break; + case MIN: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.rtMin) < _EPSILON_) + { + return QString("--"); + } + return QString::number(curve.rtMin, 'f', 2); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.sHisMin) < _EPSILON_) + { + return QString("--"); + } + return QString::number(curve.sHisMin, 'f', 2); + } + } + break; + case MINTIME: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.rtMinTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.rtMinTime).toString("hh:mm:ss"); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.sHisMinTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.sHisMinTime).toString("yyyy-MM-dd hh:mm:ss"); + } + } + break; + case AVE: + { + + if(LENGED_RT_MODE == m_lengedMode) + { + if("analog" != curve.type || qAbs((-DBL_MAX) - curve.rtAverage) < _EPSILON_ || qIsNaN(curve.rtAverage)) + { + return QString("--"); + } + return QString::number(curve.rtAverage, 'f', 2); + } + else + { + if("analog" != curve.type || qAbs((-DBL_MAX) - curve.hisAverage) < _EPSILON_ || qIsNaN(curve.hisAverage)) + { + return QString("--"); + } + return QString::number(curve.hisAverage, 'f', 2); + } + } + break; + case UNIT: + { + if(curve.unit.isEmpty()) + { + return QString("--"); + } + return curve.unit; + } + break; + case FACTOR: + { + return curve.factor; + } + break; + case OFFSET: + { + return curve.offset; + } + break; + default: + break; + } + + return QVariant(); +} + +bool CCurveLegendModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid()) + { + return false; + } + if(Qt::CheckStateRole == role && NAME == index.column()) + { + m_graph->setCurveVisible(index.row(), value.toBool()); + emit graphVisibleChanged(value.toBool()); + return true; + } + if(Qt::EditRole != role) + { + return false; + } + + if(COLOR == index.column()) + { + m_graph->setCurveColor(index.row(), value.value()); + } + if(FACTOR == index.column()) + { + m_graph->setCurveFactor(index.row(), value.toDouble()); + } + else if(OFFSET == index.column()) + { + m_graph->setCurveOffset(index.row(), value.toDouble()); + } + emit graphPropertyChanged(); + + QModelIndex topLeft = createIndex(0, 0); + QModelIndex bottomright = createIndex(rowCount() - 1, columnCount() - 1); + emit dataChanged(topLeft, bottomright); + + return true; +} + +Qt::ItemFlags CCurveLegendModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + { + return Qt::NoItemFlags; + } + + Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + if(COLOR == index.column() || FACTOR == index.column() || OFFSET == index.column()) + { + itemFlags |= Qt::ItemIsEditable; + } + else if(NAME == index.column()) + { + itemFlags |= Qt::ItemIsUserCheckable; + } + + return itemFlags; +} + +void CCurveLegendModel::setChildrenCheckState(const Qt::CheckState &state) +{ + for(int nChildIndex(0); nChildIndex < rowCount(); nChildIndex++) + { + m_graph->setCurveVisible(nChildIndex, state); + } + emit graphVisibleChanged(state == Qt::Checked ? true : false); +} + +void CCurveLegendModel::deleteSelectGraph() +{ + emit deleteCurrentGraph(); +} + +void CCurveLegendModel::jumpToMaxTime(const QModelIndex &index) +{ + if(!index.isValid()) + { + return; + } + + Curve curve = m_graph->curves().at(index.row()); + if(qAbs((-DBL_MAX) - curve.sHisMaxTime) < _EPSILON_) + { + return; + } + emit sigJumpToMaxTime(curve.sHisMaxTime); +} + +void CCurveLegendModel::jumpToMinTime(const QModelIndex &index) +{ + if(!index.isValid()) + { + return; + } + + Curve curve = m_graph->curves().at(index.row()); + if(qAbs((DBL_MAX) - curve.sHisMinTime) < _EPSILON_) + { + return; + } + emit sigJumpToMinTime(curve.sHisMinTime); +} diff --git a/product/src/gui/plugin/TrendCurves/CCurveLegendModel.h b/product/src/gui/plugin/TrendCurves/CCurveLegendModel.h index f03aad2a..da41db03 100644 --- a/product/src/gui/plugin/TrendCurves/CCurveLegendModel.h +++ b/product/src/gui/plugin/TrendCurves/CCurveLegendModel.h @@ -1,124 +1,124 @@ -#ifndef CCURVELEGENDMODEL_H -#define CCURVELEGENDMODEL_H - -#include -#include -#include - - -class CTrendGraph; - -class ColorWidget : public QWidget -{ - Q_OBJECT -public: - explicit ColorWidget(QWidget *parent=Q_NULLPTR); - ~ColorWidget(); - - void setColor(const QColor &color); - QColor color() const; - - void updateCurrentColor(); - -signals: - void colorChanged(); - -protected: - void paintEvent(QPaintEvent * event); - void mousePressEvent(QMouseEvent *event); - -private: - QColor m_color; -}; - -class CCurveLegnedDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CCurveLegnedDelegate(QObject *parent = nullptr); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - - QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; - - void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; - - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; - -protected: - bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); - -private slots: - void slotColorChangde(); -}; - -class CCurveLegendModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - enum LengedMode - { - LENGED_RT_MODE = 0, - LENGED_HIS_MODE - }; - - enum ColumnField - { - NAME = 0, - COLOR, - VALUE, - MAX, - MAXTIME, - MIN, - MINTIME, - AVE, - UNIT, - FACTOR, - OFFSET - }; - - - explicit CCurveLegendModel(QObject *parent = nullptr); - - void setMode(const LengedMode &mode); - LengedMode getMode(); - - void setTrendGraph(CTrendGraph * graph); - - void setTrendCurrentValues(QList list); - - void update(); - - void clear(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - - Qt::ItemFlags flags(const QModelIndex &index) const; - - void setChildrenCheckState(const Qt::CheckState &state); - void deleteSelectGraph(); - void jumpToMaxTime(const QModelIndex &index); - void jumpToMinTime(const QModelIndex &index); - -signals: - void graphVisibleChanged(const bool &check); - void graphPropertyChanged(); - void deleteCurrentGraph(); - void sigJumpToMaxTime(const double &time); - void sigJumpToMinTime(const double &time); - -private: - LengedMode m_lengedMode; - QStringList m_header; - CTrendGraph * m_graph; - QList m_currentValue; -}; - -#endif // CCURVELEGENDMODEL_H +#ifndef CCURVELEGENDMODEL_H +#define CCURVELEGENDMODEL_H + +#include +#include +#include + + +class CTrendGraph; + +class ColorWidget : public QWidget +{ + Q_OBJECT +public: + explicit ColorWidget(QWidget *parent=Q_NULLPTR); + ~ColorWidget(); + + void setColor(const QColor &color); + QColor color() const; + + void updateCurrentColor(); + +signals: + void colorChanged(); + +protected: + void paintEvent(QPaintEvent * event); + void mousePressEvent(QMouseEvent *event); + +private: + QColor m_color; +}; + +class CCurveLegnedDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CCurveLegnedDelegate(QObject *parent = nullptr); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + +protected: + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); + +private slots: + void slotColorChangde(); +}; + +class CCurveLegendModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + enum LengedMode + { + LENGED_RT_MODE = 0, + LENGED_HIS_MODE + }; + + enum ColumnField + { + NAME = 0, + COLOR, + VALUE, + MAX, + MAXTIME, + MIN, + MINTIME, + AVE, + UNIT, + FACTOR, + OFFSET + }; + + + explicit CCurveLegendModel(QObject *parent = nullptr); + + void setMode(const LengedMode &mode); + LengedMode getMode(); + + void setTrendGraph(CTrendGraph * graph); + + void setTrendCurrentValues(QList list); + + void update(); + + void clear(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const; + + void setChildrenCheckState(const Qt::CheckState &state); + void deleteSelectGraph(); + void jumpToMaxTime(const QModelIndex &index); + void jumpToMinTime(const QModelIndex &index); + +signals: + void graphVisibleChanged(const bool &check); + void graphPropertyChanged(); + void deleteCurrentGraph(); + void sigJumpToMaxTime(const double &time); + void sigJumpToMinTime(const double &time); + +private: + LengedMode m_lengedMode; + QStringList m_header; + CTrendGraph * m_graph; + QList m_currentValue; +}; + +#endif // CCURVELEGENDMODEL_H diff --git a/product/src/gui/plugin/TrendCurves/CCurveLegendView.cpp b/product/src/gui/plugin/TrendCurves/CCurveLegendView.cpp index a20c0cfd..4d91a875 100644 --- a/product/src/gui/plugin/TrendCurves/CCurveLegendView.cpp +++ b/product/src/gui/plugin/TrendCurves/CCurveLegendView.cpp @@ -1,29 +1,29 @@ -#include "CCurveLegendView.h" -#include "CCurveLegendModel.h" -#include -#include - -CCurveLegendView::CCurveLegendView(QWidget *parent) - : CTableView(parent) -{ - -} - -void CCurveLegendView::contextMenuEvent(QContextMenuEvent *event) -{ - CCurveLegendModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR != pModel) - { - QMenu menu; - menu.addAction(tr("全不选"), [=](){ pModel->setChildrenCheckState(Qt::Unchecked); }); - menu.addAction(tr("删除"),[=](){ pModel->deleteSelectGraph(); }); - if(pModel->getMode() != CCurveLegendModel::LENGED_RT_MODE) - { - menu.addAction(tr("查看最大值"),[=](){ pModel->jumpToMaxTime(currentIndex()); }); - menu.addAction(tr("查看最小值"),[=](){ pModel->jumpToMinTime(currentIndex()); }); - } - menu.exec(event->globalPos()); - } - return; -} - +#include "CCurveLegendView.h" +#include "CCurveLegendModel.h" +#include +#include + +CCurveLegendView::CCurveLegendView(QWidget *parent) + : CTableView(parent) +{ + +} + +void CCurveLegendView::contextMenuEvent(QContextMenuEvent *event) +{ + CCurveLegendModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QMenu menu; + menu.addAction(tr("全不选"), [=](){ pModel->setChildrenCheckState(Qt::Unchecked); }); + menu.addAction(tr("删除"),[=](){ pModel->deleteSelectGraph(); }); + if(pModel->getMode() != CCurveLegendModel::LENGED_RT_MODE) + { + menu.addAction(tr("查看最大值"),[=](){ pModel->jumpToMaxTime(currentIndex()); }); + menu.addAction(tr("查看最小值"),[=](){ pModel->jumpToMinTime(currentIndex()); }); + } + menu.exec(event->globalPos()); + } + return; +} + diff --git a/product/src/gui/plugin/TrendCurves/CCurveLegendView.h b/product/src/gui/plugin/TrendCurves/CCurveLegendView.h index 12936dd3..832dc223 100644 --- a/product/src/gui/plugin/TrendCurves/CCurveLegendView.h +++ b/product/src/gui/plugin/TrendCurves/CCurveLegendView.h @@ -1,16 +1,16 @@ -#ifndef CCURVELEGENDVIEW_H -#define CCURVELEGENDVIEW_H - -#include "CTableView.h" - -class CCurveLegendView : public CTableView -{ - Q_OBJECT -public: - CCurveLegendView(QWidget *parent = Q_NULLPTR); - -protected: - void contextMenuEvent(QContextMenuEvent *event); -}; - -#endif // CCURVELEGENDVIEW_H +#ifndef CCURVELEGENDVIEW_H +#define CCURVELEGENDVIEW_H + +#include "CTableView.h" + +class CCurveLegendView : public CTableView +{ + Q_OBJECT +public: + CCurveLegendView(QWidget *parent = Q_NULLPTR); + +protected: + void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // CCURVELEGENDVIEW_H diff --git a/product/src/gui/plugin/TrendCurves/CHisDataManage.cpp b/product/src/gui/plugin/TrendCurves/CHisDataManage.cpp index 11281f0f..89ae3420 100644 --- a/product/src/gui/plugin/TrendCurves/CHisDataManage.cpp +++ b/product/src/gui/plugin/TrendCurves/CHisDataManage.cpp @@ -1,347 +1,347 @@ -#include "CHisDataManage.h" -#include "db_his_query_api/DbHisQueryApi.h" -#include "sample_server_api/SampleDefine.h" -#include "CTrendInfoManage.h" -#include "pub_logger_api/logger.h" -using namespace kbd_dbms; - -int CHisDataManage::m_nProcessNumber = 0; - -CHisDataManage::CHisDataManage(QObject *parent) - : QObject(parent), - m_TsdbExcuting(false), - m_bHasPendingCommandCurve(false), - m_bHasPendingCommandEvent(false), - m_bHasPendingCommandCompute(false), - m_tsdbConnPtr((CTsdbConn*)nullptr) -{ - initTsdbApi(); - m_nProcessNumber++; -} - -CHisDataManage::~CHisDataManage() -{ - QMutexLocker locker(&m_mutex); - m_tsdbConnPtr = boost::shared_ptr(Q_NULLPTR); - if(--m_nProcessNumber == 0) - { - releaseTsdbApi(); - } - - foreach (TsdbCommand cmd, m_listCommandCurve) - { - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; - } - m_listCommandCurve.clear(); - - foreach (TsdbCommand cmd, m_listCommandEvent) - { - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; - } - m_listCommandEvent.clear(); - - foreach (TsdbCommand cmd, m_listCommandCompute) - { - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; - } - m_listCommandCompute.clear(); -} - -bool CHisDataManage::isTsdbExuting() -{ - QMutexLocker locker(&m_mutex); - return m_TsdbExcuting; -} - -void CHisDataManage::postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, double lower, double upper, int nGroupBySec, std::vector vecCM) -{ - QMutexLocker locker(&m_mutex); - TsdbCommand cmd; - cmd.type = type; - cmd.pVecMpKey = vecMpKey; - cmd.lower = lower; - cmd.upper = upper; - cmd.nGroupBySec = nGroupBySec; - cmd.vecMethod = vecCM; - - switch(type) - { - case E_ORIGINAL: - case E_POLYMERIC: - { - m_bHasPendingCommandCurve = true; - m_listCommandCurve.push_back(cmd); - break; - } - case E_EVENTPOINT: - { - m_bHasPendingCommandEvent = true; - m_listCommandEvent.push_back(cmd); - break; - } - case E_COMPUTER: - { - m_bHasPendingCommandCompute = true; - m_listCommandCompute.push_back(cmd); - break; - } - default: - break; - } -} - -void CHisDataManage::release() -{ - delete this; -} - -bool CHisDataManage::getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr) -{ - //< 不使用getOneUseableConn()返回的正式库测试 - // ptr.reset(new kbd_dbms::CTsdbConn("127.0.0.1", -1, "iscs6000", "", "")); - // return true; - if(m_tsdbConnPtr != NULL) - { - if(m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - } - else - { - m_tsdbConnPtr = getOneUseableConn(true); - if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - else - { - m_tsdbConnPtr = getOneUseableConn(false); - if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) - { - ptr = m_tsdbConnPtr; - return true; - } - } - } - return false; -} - -void CHisDataManage::checkTsdbCommandQueue() -{ - checkTsdbCommandQueue(m_bHasPendingCommandCurve, m_listCommandCurve); - checkTsdbCommandQueue(m_bHasPendingCommandEvent, m_listCommandEvent); - checkTsdbCommandQueue(m_bHasPendingCommandCompute, m_listCommandCompute); -} - -void CHisDataManage::checkTsdbCommandQueue(bool &bHasPend, QList &listCommand) -{ - if(bHasPend) - { - bHasPend = false; - TsdbCommand cmd; - { - QMutexLocker locker(&m_mutex); - if(!listCommand.isEmpty()) - { - cmd = listCommand.takeLast(); - } - } - if(E_ORIGINAL == cmd.type) - { - queryHistoryOriginalData(cmd.pVecMpKey, cmd.lower, cmd.upper); - } - else if(E_POLYMERIC == cmd.type) - { - queryHistoryPolymericData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.nGroupBySec, cmd.vecMethod.front()); - } - else if(E_EVENTPOINT == cmd.type) - { - queryHistoryEvents(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod.front(), cmd.nGroupBySec); - } - else if(E_COMPUTER == cmd.type) - { - queryHistoryComputeData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod); - } - } - else - { - foreach (TsdbCommand cmd, listCommand) - { - std::vector::iterator it = cmd.pVecMpKey->begin(); - while(it != cmd.pVecMpKey->end()) - { - free( (char*)it->m_pszTagName ); - ++it; - } - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; - } - listCommand.clear(); - } -} - -void CHisDataManage::queryHistoryOriginalData(std::vector *vecMpKey, double lower, double upper, E_Data_Type type) -{ - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - - double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; - std::vector *> *vecResult = new std::vector *>(); - - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - if(getValidTsdbConnPtr(tsdbConnPtr)) - { - for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) - { - vecResult->push_back(new std::vector()); - } - emit sigHisSearch(true); - if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, - NULL, NULL, CM_NULL, 0, FM_NULL_METHOD, *vecResult)) - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 查询超时!"); - } - emit sigHisSearch(false); - } - else - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 未获取到有效的TSDB连接!"); - } - - emit sigupdateHisOriginalData(vecMpKey, vecResult, type); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); -} - -void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, double lower, double upper, int nGroupBySec, const EnComputeMethod &enCm) -{ - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - - double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; - std::vector *> *vecResult = new std::vector *>(); - - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - if(getValidTsdbConnPtr(tsdbConnPtr)) - { - for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) - { - vecResult->push_back(new std::vector()); - } - emit sigHisSearch(true); - if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, - NULL, NULL, enCm, nGroupBySec * 1000, FM_NULL_METHOD, *vecResult)) - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!"); - } - emit sigHisSearch(false); - } - else - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); - } - - emit sigHistoryPolymericData(vecMpKey, vecResult, nGroupBySec); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); -} - -void CHisDataManage::queryHistoryComputeData(std::vector *vecMpKey, double lower, double upper, const std::vector &vecCM) -{ - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - - std::vector *> *> > cmResult; - - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - if(getValidTsdbConnPtr(tsdbConnPtr)) - { - for(size_t nCmIndex(0); nCmIndex < vecCM.size(); nCmIndex++) - { - std::vector *> *vecResult = new std::vector *>(); - for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) - { - vecResult->push_back(new std::vector()); - } - emit sigHisSearch(true); - if(!getHisValue(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, - NULL, NULL, NULL, NULL, NULL, vecCM[nCmIndex], 0, FM_NULL_METHOD, *vecResult)) - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryComputeData: 查询超时!"); - } - std::pair *> *> tmp; - tmp.first = vecCM[nCmIndex]; - tmp.second = vecResult; - cmResult.push_back(tmp); - emit sigHisSearch(false); - } - } - else - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryComputeData: 未获取到有效的TSDB连接!"); - } - - emit sigHistoryComputeData(vecMpKey, cmResult); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); -} - -void CHisDataManage::queryHistoryEvents(std::vector *vecMpKey, double lower, double upper, const EnComputeMethod &enCM, int nGroupBySec) -{ - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - - std::vector *> *vecResult = new std::vector *>(); - - kbd_dbms::CTsdbConnPtr tsdbConnPtr; - if(getValidTsdbConnPtr(tsdbConnPtr)) - { - for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) - { - vecResult->push_back(new std::vector()); - } - emit sigHisSearch(true); - if(!getHisEventPoint(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, enCM, nGroupBySec * 1000, *vecResult)) - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!Lower: %f, Upper: %f, GroupByMs: %d", lower, upper, nGroupBySec); - } - emit sigHisSearch(false); - } - else - { - LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); - } - emit sigHistoryEvent(vecMpKey, vecResult); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); -} +#include "CHisDataManage.h" +#include "db_his_query_api/DbHisQueryApi.h" +#include "sample_server_api/SampleDefine.h" +#include "CTrendInfoManage.h" +#include "pub_logger_api/logger.h" +using namespace kbd_dbms; + +int CHisDataManage::m_nProcessNumber = 0; + +CHisDataManage::CHisDataManage(QObject *parent) + : QObject(parent), + m_TsdbExcuting(false), + m_bHasPendingCommandCurve(false), + m_bHasPendingCommandEvent(false), + m_bHasPendingCommandCompute(false), + m_tsdbConnPtr((CTsdbConn*)nullptr) +{ + initTsdbApi(); + m_nProcessNumber++; +} + +CHisDataManage::~CHisDataManage() +{ + QMutexLocker locker(&m_mutex); + m_tsdbConnPtr = boost::shared_ptr(Q_NULLPTR); + if(--m_nProcessNumber == 0) + { + releaseTsdbApi(); + } + + foreach (TsdbCommand cmd, m_listCommandCurve) + { + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + m_listCommandCurve.clear(); + + foreach (TsdbCommand cmd, m_listCommandEvent) + { + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + m_listCommandEvent.clear(); + + foreach (TsdbCommand cmd, m_listCommandCompute) + { + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + m_listCommandCompute.clear(); +} + +bool CHisDataManage::isTsdbExuting() +{ + QMutexLocker locker(&m_mutex); + return m_TsdbExcuting; +} + +void CHisDataManage::postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, double lower, double upper, int nGroupBySec, std::vector vecCM) +{ + QMutexLocker locker(&m_mutex); + TsdbCommand cmd; + cmd.type = type; + cmd.pVecMpKey = vecMpKey; + cmd.lower = lower; + cmd.upper = upper; + cmd.nGroupBySec = nGroupBySec; + cmd.vecMethod = vecCM; + + switch(type) + { + case E_ORIGINAL: + case E_POLYMERIC: + { + m_bHasPendingCommandCurve = true; + m_listCommandCurve.push_back(cmd); + break; + } + case E_EVENTPOINT: + { + m_bHasPendingCommandEvent = true; + m_listCommandEvent.push_back(cmd); + break; + } + case E_COMPUTER: + { + m_bHasPendingCommandCompute = true; + m_listCommandCompute.push_back(cmd); + break; + } + default: + break; + } +} + +void CHisDataManage::release() +{ + delete this; +} + +bool CHisDataManage::getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr) +{ + //< 不使用getOneUseableConn()返回的正式库测试 + // ptr.reset(new kbd_dbms::CTsdbConn("127.0.0.1", -1, "iscs6000", "", "")); + // return true; + if(m_tsdbConnPtr != NULL) + { + if(m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + else + { + m_tsdbConnPtr = getOneUseableConn(true); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + else + { + m_tsdbConnPtr = getOneUseableConn(false); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + } + return false; +} + +void CHisDataManage::checkTsdbCommandQueue() +{ + checkTsdbCommandQueue(m_bHasPendingCommandCurve, m_listCommandCurve); + checkTsdbCommandQueue(m_bHasPendingCommandEvent, m_listCommandEvent); + checkTsdbCommandQueue(m_bHasPendingCommandCompute, m_listCommandCompute); +} + +void CHisDataManage::checkTsdbCommandQueue(bool &bHasPend, QList &listCommand) +{ + if(bHasPend) + { + bHasPend = false; + TsdbCommand cmd; + { + QMutexLocker locker(&m_mutex); + if(!listCommand.isEmpty()) + { + cmd = listCommand.takeLast(); + } + } + if(E_ORIGINAL == cmd.type) + { + queryHistoryOriginalData(cmd.pVecMpKey, cmd.lower, cmd.upper); + } + else if(E_POLYMERIC == cmd.type) + { + queryHistoryPolymericData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.nGroupBySec, cmd.vecMethod.front()); + } + else if(E_EVENTPOINT == cmd.type) + { + queryHistoryEvents(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod.front(), cmd.nGroupBySec); + } + else if(E_COMPUTER == cmd.type) + { + queryHistoryComputeData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod); + } + } + else + { + foreach (TsdbCommand cmd, listCommand) + { + std::vector::iterator it = cmd.pVecMpKey->begin(); + while(it != cmd.pVecMpKey->end()) + { + free( (char*)it->m_pszTagName ); + ++it; + } + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + listCommand.clear(); + } +} + +void CHisDataManage::queryHistoryOriginalData(std::vector *vecMpKey, double lower, double upper, E_Data_Type type) +{ + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = true; + } + + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + std::vector *> *vecResult = new std::vector *>(); + + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + emit sigHisSearch(true); + if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, + NULL, NULL, CM_NULL, 0, FM_NULL_METHOD, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 查询超时!"); + } + emit sigHisSearch(false); + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 未获取到有效的TSDB连接!"); + } + + emit sigupdateHisOriginalData(vecMpKey, vecResult, type); + + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = false; + } + checkTsdbCommandQueue(); +} + +void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, double lower, double upper, int nGroupBySec, const EnComputeMethod &enCm) +{ + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = true; + } + + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + std::vector *> *vecResult = new std::vector *>(); + + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + emit sigHisSearch(true); + if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, + NULL, NULL, enCm, nGroupBySec * 1000, FM_NULL_METHOD, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!"); + } + emit sigHisSearch(false); + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); + } + + emit sigHistoryPolymericData(vecMpKey, vecResult, nGroupBySec); + + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = false; + } + checkTsdbCommandQueue(); +} + +void CHisDataManage::queryHistoryComputeData(std::vector *vecMpKey, double lower, double upper, const std::vector &vecCM) +{ + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = true; + } + + std::vector *> *> > cmResult; + + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nCmIndex(0); nCmIndex < vecCM.size(); nCmIndex++) + { + std::vector *> *vecResult = new std::vector *>(); + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + emit sigHisSearch(true); + if(!getHisValue(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, + NULL, NULL, NULL, NULL, NULL, vecCM[nCmIndex], 0, FM_NULL_METHOD, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryComputeData: 查询超时!"); + } + std::pair *> *> tmp; + tmp.first = vecCM[nCmIndex]; + tmp.second = vecResult; + cmResult.push_back(tmp); + emit sigHisSearch(false); + } + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryComputeData: 未获取到有效的TSDB连接!"); + } + + emit sigHistoryComputeData(vecMpKey, cmResult); + + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = false; + } + checkTsdbCommandQueue(); +} + +void CHisDataManage::queryHistoryEvents(std::vector *vecMpKey, double lower, double upper, const EnComputeMethod &enCM, int nGroupBySec) +{ + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = true; + } + + std::vector *> *vecResult = new std::vector *>(); + + kbd_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + emit sigHisSearch(true); + if(!getHisEventPoint(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, enCM, nGroupBySec * 1000, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!Lower: %f, Upper: %f, GroupByMs: %d", lower, upper, nGroupBySec); + } + emit sigHisSearch(false); + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); + } + emit sigHistoryEvent(vecMpKey, vecResult); + + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = false; + } + checkTsdbCommandQueue(); +} diff --git a/product/src/gui/plugin/TrendCurves/CHisDataManage.h b/product/src/gui/plugin/TrendCurves/CHisDataManage.h index 909d82c0..5e672711 100644 --- a/product/src/gui/plugin/TrendCurves/CHisDataManage.h +++ b/product/src/gui/plugin/TrendCurves/CHisDataManage.h @@ -1,126 +1,126 @@ -#ifndef CHISDATAMANAGE_H -#define CHISDATAMANAGE_H - -#include -#include -#include "CTrendGraph.h" -#include "plot/qcustomplot.h" -#include "tsdb_api/TsdbApi.h" -#include "db_his_query_api/DbHisQueryBase.h" - -enum E_Data_Type -{ - E_REALTIME, - E_HISTORY -}; - -enum E_His_Type -{ - E_Invalid = -1, - E_ORIGINAL, - E_POLYMERIC, - E_EVENTPOINT, - E_COMPUTER -}; - -struct MeasurementPoint -{ - kbd_dbms::EnMeasPiontType type; //< 测点类型 - const QString strTagName; //< 测点TAG名 -}; - -struct TsdbCommand -{ - TsdbCommand() - { - type = E_Invalid; - pVecMpKey = nullptr; - lower = -1.; - upper = -1.; - nGroupBySec = -1; - vecMethod = std::vector{kbd_dbms::CM_NULL}; - } - E_His_Type type; - std::vector * pVecMpKey; - double lower; - double upper; - int nGroupBySec; - std::vector vecMethod; -}; - -class CHisDataManage : public QObject -{ - Q_OBJECT -public: - explicit CHisDataManage(QObject *parent = nullptr); - ~CHisDataManage(); - - bool isTsdbExuting(); - -signals: - void sigupdateHisOriginalData(std::vector *vecMpKey, - std::vector *> *vecResult, - E_Data_Type type = E_HISTORY); - - void sigHistoryPolymericData(std::vector *vecMpKey, - std::vector *> *vecResult, - int nGroupBySec); - - void sigHistoryComputeData(std::vector *vecMpKey, - std::vector *> *> > cmResult); - - void sigHistoryEvent(std::vector *vecMpKey, - std::vector *> *vecResult); - - void sigHisSearch(bool enable); - -public slots: - void release(); - - void postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, - double lower, double upper, - int nGroupBySec = -1, - std::vector vecCM = std::vector{kbd_dbms::CM_NULL}); - - void queryHistoryOriginalData(std::vector *vecMpKey, - double lower, double upper, - E_Data_Type type = E_HISTORY); - - void queryHistoryPolymericData(std::vector *vecMpKey, - double lower, double upper, - int nGroupBySec, - const kbd_dbms::EnComputeMethod &enCm); - - void queryHistoryComputeData(std::vector *vecMpKey, - double lower, double upper, - const std::vector &vecCM); - - void queryHistoryEvents(std::vector *vecMpKey, - double lower, double upper, - const kbd_dbms::EnComputeMethod &enCM, - int nGroupBySec); - -protected: - bool getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr); - void checkTsdbCommandQueue(); - void checkTsdbCommandQueue(bool &bHasPend, QList &listCommand); - -private: - bool m_TsdbExcuting; - bool m_bHasPendingCommandCurve; - bool m_bHasPendingCommandEvent; - bool m_bHasPendingCommandCompute; - kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; - - QList m_listCommandCurve; - QList m_listCommandEvent; - QList m_listCommandCompute; - QMutex m_mutex; - static int m_nProcessNumber; -}; - - -template -inline bool compareVarPoint(const T &a, const T &b) { return a.m_nTime < b.m_nTime; } - -#endif // CHISDATAMANAGE_H +#ifndef CHISDATAMANAGE_H +#define CHISDATAMANAGE_H + +#include +#include +#include "CTrendGraph.h" +#include "plot/qcustomplot.h" +#include "tsdb_api/TsdbApi.h" +#include "db_his_query_api/DbHisQueryBase.h" + +enum E_Data_Type +{ + E_REALTIME, + E_HISTORY +}; + +enum E_His_Type +{ + E_Invalid = -1, + E_ORIGINAL, + E_POLYMERIC, + E_EVENTPOINT, + E_COMPUTER +}; + +struct MeasurementPoint +{ + kbd_dbms::EnMeasPiontType type; //< 测点类型 + const QString strTagName; //< 测点TAG名 +}; + +struct TsdbCommand +{ + TsdbCommand() + { + type = E_Invalid; + pVecMpKey = nullptr; + lower = -1.; + upper = -1.; + nGroupBySec = -1; + vecMethod = std::vector{kbd_dbms::CM_NULL}; + } + E_His_Type type; + std::vector * pVecMpKey; + double lower; + double upper; + int nGroupBySec; + std::vector vecMethod; +}; + +class CHisDataManage : public QObject +{ + Q_OBJECT +public: + explicit CHisDataManage(QObject *parent = nullptr); + ~CHisDataManage(); + + bool isTsdbExuting(); + +signals: + void sigupdateHisOriginalData(std::vector *vecMpKey, + std::vector *> *vecResult, + E_Data_Type type = E_HISTORY); + + void sigHistoryPolymericData(std::vector *vecMpKey, + std::vector *> *vecResult, + int nGroupBySec); + + void sigHistoryComputeData(std::vector *vecMpKey, + std::vector *> *> > cmResult); + + void sigHistoryEvent(std::vector *vecMpKey, + std::vector *> *vecResult); + + void sigHisSearch(bool enable); + +public slots: + void release(); + + void postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, + double lower, double upper, + int nGroupBySec = -1, + std::vector vecCM = std::vector{kbd_dbms::CM_NULL}); + + void queryHistoryOriginalData(std::vector *vecMpKey, + double lower, double upper, + E_Data_Type type = E_HISTORY); + + void queryHistoryPolymericData(std::vector *vecMpKey, + double lower, double upper, + int nGroupBySec, + const kbd_dbms::EnComputeMethod &enCm); + + void queryHistoryComputeData(std::vector *vecMpKey, + double lower, double upper, + const std::vector &vecCM); + + void queryHistoryEvents(std::vector *vecMpKey, + double lower, double upper, + const kbd_dbms::EnComputeMethod &enCM, + int nGroupBySec); + +protected: + bool getValidTsdbConnPtr(kbd_dbms::CTsdbConnPtr &ptr); + void checkTsdbCommandQueue(); + void checkTsdbCommandQueue(bool &bHasPend, QList &listCommand); + +private: + bool m_TsdbExcuting; + bool m_bHasPendingCommandCurve; + bool m_bHasPendingCommandEvent; + bool m_bHasPendingCommandCompute; + kbd_dbms::CTsdbConnPtr m_tsdbConnPtr; + + QList m_listCommandCurve; + QList m_listCommandEvent; + QList m_listCommandCompute; + QMutex m_mutex; + static int m_nProcessNumber; +}; + + +template +inline bool compareVarPoint(const T &a, const T &b) { return a.m_nTime < b.m_nTime; } + +#endif // CHISDATAMANAGE_H diff --git a/product/src/gui/plugin/TrendCurves/CHisEventManage.cpp b/product/src/gui/plugin/TrendCurves/CHisEventManage.cpp index 78a52776..e1a32a2a 100644 --- a/product/src/gui/plugin/TrendCurves/CHisEventManage.cpp +++ b/product/src/gui/plugin/TrendCurves/CHisEventManage.cpp @@ -1,86 +1,86 @@ -#include "CHisEventManage.h" -#include "service/alarm_server_api/AlarmCommonDef.h" -#include -#include "pub_logger_api/logger.h" - -CHisEventManage::CHisEventManage(QObject *parent) - : QObject(parent) -{ - -} - -CHisEventManage::~CHisEventManage() -{ - -} - -void CHisEventManage::release() -{ - delete this; -} - -void CHisEventManage::queryHisEvent(const qint64 &time, const QMap &timeTag, const QList &alarmStatusList) -{ - QList timeList = timeTag.keys(); - QStringList tagList = timeTag.values(); - if(timeList.isEmpty() || tagList.isEmpty()) - { - emit updateHisEvent(time, QStringList() << tr("未查询到该设备相关事件!")); - return; - } - - CDbApi objReadDb(DB_CONN_HIS_READ); - if(!objReadDb.open()) - { - return; - } - - QString timeFirst = QString::number(timeList.first()); - QString timeEnd = QString::number(timeList.last()); - QString keyTagStr = ""; - foreach (QString tag, tagList) { - QString temp = " key_id_tag like '%" + tag + "%' or"; - keyTagStr += temp; - } - keyTagStr.remove(-2,2); - - QString sqlSequenceQuery = QString("select " - "alm_status," - "time_stamp," - "content " - "from HIS_EVENT " - "where time_stamp >= %1 " - "and time_stamp <= %2 " - "and (%3) " - "order by time_stamp asc").arg(timeFirst).arg(timeEnd).arg(keyTagStr); - LOGINFO("queryHisEvent Query: %s", sqlSequenceQuery.toStdString().c_str()); - - QSqlQuery query; - try - { - objReadDb.execute(sqlSequenceQuery, query); - } - catch(...) - { - qDebug() << "Query Error!"; - } - if(query.isActive()) - { - QStringList contents; - while(query.next()) - { - int status = query.value(0).toInt(); - if(alarmStatusList.contains(status)) - { - contents << QDateTime::fromMSecsSinceEpoch(query.value(1).toDouble()).toString("yyyy-MM-dd hh:mm:ss zzz\n") + query.value(2).toString(); - } - } - if(contents.isEmpty()) - { - contents << tr("未查询到该设备相关事件!"); - } - - emit updateHisEvent(time, contents); - } - objReadDb.close(); -} +#include "CHisEventManage.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include +#include "pub_logger_api/logger.h" + +CHisEventManage::CHisEventManage(QObject *parent) + : QObject(parent) +{ + +} + +CHisEventManage::~CHisEventManage() +{ + +} + +void CHisEventManage::release() +{ + delete this; +} + +void CHisEventManage::queryHisEvent(const qint64 &time, const QMap &timeTag, const QList &alarmStatusList) +{ + QList timeList = timeTag.keys(); + QStringList tagList = timeTag.values(); + if(timeList.isEmpty() || tagList.isEmpty()) + { + emit updateHisEvent(time, QStringList() << tr("未查询到该设备相关事件!")); + return; + } + + CDbApi objReadDb(DB_CONN_HIS_READ); + if(!objReadDb.open()) + { + return; + } + + QString timeFirst = QString::number(timeList.first()); + QString timeEnd = QString::number(timeList.last()); + QString keyTagStr = ""; + foreach (QString tag, tagList) { + QString temp = " key_id_tag like '%" + tag + "%' or"; + keyTagStr += temp; + } + keyTagStr.remove(-2,2); + + QString sqlSequenceQuery = QString("select " + "alm_status," + "time_stamp," + "content " + "from HIS_EVENT " + "where time_stamp >= %1 " + "and time_stamp <= %2 " + "and (%3) " + "order by time_stamp asc").arg(timeFirst).arg(timeEnd).arg(keyTagStr); + LOGINFO("queryHisEvent Query: %s", sqlSequenceQuery.toStdString().c_str()); + + QSqlQuery query; + try + { + objReadDb.execute(sqlSequenceQuery, query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + if(query.isActive()) + { + QStringList contents; + while(query.next()) + { + int status = query.value(0).toInt(); + if(alarmStatusList.contains(status)) + { + contents << QDateTime::fromMSecsSinceEpoch(query.value(1).toDouble()).toString("yyyy-MM-dd hh:mm:ss zzz\n") + query.value(2).toString(); + } + } + if(contents.isEmpty()) + { + contents << tr("未查询到该设备相关事件!"); + } + + emit updateHisEvent(time, contents); + } + objReadDb.close(); +} diff --git a/product/src/gui/plugin/TrendCurves/CHisEventManage.h b/product/src/gui/plugin/TrendCurves/CHisEventManage.h index 6ec2dbe8..4008b8b1 100644 --- a/product/src/gui/plugin/TrendCurves/CHisEventManage.h +++ b/product/src/gui/plugin/TrendCurves/CHisEventManage.h @@ -1,23 +1,23 @@ -#ifndef CHISEVENTMANAGE_H -#define CHISEVENTMANAGE_H - -#include "dbms/db_api_ex/CDbApi.h" - -using namespace kbd_dbms; -class CHisEventManage : public QObject -{ - Q_OBJECT -public: - CHisEventManage(QObject *parent = Q_NULLPTR); - - ~CHisEventManage(); - - void release(); - - void queryHisEvent(const qint64 &time, const QMap& timeTag, const QList &alarmStatusList); - -signals: - void updateHisEvent(const qint64 &time, QStringList contents); -}; - -#endif // CHISEVENTMANAGE_H +#ifndef CHISEVENTMANAGE_H +#define CHISEVENTMANAGE_H + +#include "dbms/db_api_ex/CDbApi.h" + +using namespace kbd_dbms; +class CHisEventManage : public QObject +{ + Q_OBJECT +public: + CHisEventManage(QObject *parent = Q_NULLPTR); + + ~CHisEventManage(); + + void release(); + + void queryHisEvent(const qint64 &time, const QMap& timeTag, const QList &alarmStatusList); + +signals: + void updateHisEvent(const qint64 &time, QStringList contents); +}; + +#endif // CHISEVENTMANAGE_H diff --git a/product/src/gui/plugin/TrendCurves/CMyCheckBox.cpp b/product/src/gui/plugin/TrendCurves/CMyCheckBox.cpp index ff2755f4..888168ca 100644 --- a/product/src/gui/plugin/TrendCurves/CMyCheckBox.cpp +++ b/product/src/gui/plugin/TrendCurves/CMyCheckBox.cpp @@ -1,21 +1,21 @@ -#include "CMyCheckBox.h" -#include - -CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) - :QCheckBox(text,parent) -{ - -} - -CMyCheckBox::CMyCheckBox(QWidget *parent) - :QCheckBox(parent) -{ - -} - -void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) -{ - Q_UNUSED(e) - setChecked(!isChecked()); - emit clicked(isChecked()); -} +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e) + setChecked(!isChecked()); + emit clicked(isChecked()); +} diff --git a/product/src/gui/plugin/TrendCurves/CMyCheckBox.h b/product/src/gui/plugin/TrendCurves/CMyCheckBox.h index 36947db5..bdba8dbc 100644 --- a/product/src/gui/plugin/TrendCurves/CMyCheckBox.h +++ b/product/src/gui/plugin/TrendCurves/CMyCheckBox.h @@ -1,16 +1,16 @@ -#ifndef MYCHECKBOX_H -#define MYCHECKBOX_H - -#include - -class CMyCheckBox : public QCheckBox -{ -public: - CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); - CMyCheckBox(QWidget *parent = Q_NULLPTR); - -protected: - void mouseReleaseEvent(QMouseEvent *e); -}; - -#endif // MYCHECKBOX_H +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/TrendCurves/CMyListWidget.cpp b/product/src/gui/plugin/TrendCurves/CMyListWidget.cpp index 3b542202..ded92615 100644 --- a/product/src/gui/plugin/TrendCurves/CMyListWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/CMyListWidget.cpp @@ -1,12 +1,12 @@ -#include "CMyListWidget.h" - -CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) -{ - -} - -void CMyListWidget::showEvent(QShowEvent *event) -{ - this->updateGeometries(); - QListWidget::showEvent(event); -} +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/TrendCurves/CMyListWidget.h b/product/src/gui/plugin/TrendCurves/CMyListWidget.h index 9fc4491f..3e92461e 100644 --- a/product/src/gui/plugin/TrendCurves/CMyListWidget.h +++ b/product/src/gui/plugin/TrendCurves/CMyListWidget.h @@ -1,15 +1,15 @@ -#ifndef CMYLISTWIDGET_H -#define CMYLISTWIDGET_H - -#include - -class CMyListWidget : public QListWidget -{ -public: - explicit CMyListWidget(QWidget *parent = 0); - -protected: - void showEvent(QShowEvent *event); -}; - -#endif // CMYLISTWIDGET_H +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves/CPlotWidget.cpp b/product/src/gui/plugin/TrendCurves/CPlotWidget.cpp index 7c192f22..42041b21 100644 --- a/product/src/gui/plugin/TrendCurves/CPlotWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/CPlotWidget.cpp @@ -1,3581 +1,3581 @@ -#include "CPlotWidget.h" -#include "ui_CPlotWidget.h" -#include "CCurveLegendModel.h" -#include "CTableDataModel.h" -#include "CHisEventManage.h" -#include "CRealTimeDataCollect.h" -#include "sample_server_api/SampleDefine.h" -#include "pub_logger_api/logger.h" -#include "./widgets/CEditCollectWidget.h" -#include "./widgets/CSWitchButton.h" -#include "./widgets/CToolTip.h" -#include "CMyCheckBox.h" -#include "CMyListWidget.h" -#include "model_excel/xlsx/xlsxdocument.h" - -using namespace kbd_dbms; - -CPlotWidget::CPlotWidget(QWidget *parent) : - QWidget(parent), - ui(new Ui::CPlotWidget), - m_type(E_Trend_Invalid), - m_showType(E_Show_Curve), - m_bHisAdaption(false), - m_TrendTypeButton(Q_NULLPTR), - m_pLengedModel(Q_NULLPTR), - m_pTableDataModel(Q_NULLPTR), - m_pTimer(Q_NULLPTR), - m_pTrendGraph(Q_NULLPTR), - m_trendTitle(Q_NULLPTR), - m_pDpcdaForApp(Q_NULLPTR), - m_rtDataCollect(Q_NULLPTR), - m_pHisDataThread(Q_NULLPTR), - m_pHisDataManage(Q_NULLPTR), - m_pHisEventThread(Q_NULLPTR), - m_pHisEventManage(Q_NULLPTR), - m_horizontalGraph(Q_NULLPTR), - m_numWarnFlag(true), - m_isWindowMode(true), - m_isSetSliderValue(false), - m_isTooltip(true), - m_isAdaptShow(true), - m_isAlarmShow(true) -{ - ui->setupUi(this); - setContentsMargins(1, 1, 1, 1); - qRegisterMetaType< E_Point_Type >("E_Point_Type"); - qRegisterMetaType< E_Data_Type >("E_Data_Type"); - qRegisterMetaType< kbd_dbms::EnComputeMethod >("kbd_dbms::EnComputeMethod"); - qRegisterMetaType< std::vector >("std::vector"); - qRegisterMetaType< std::vector >("std::vector"); - qRegisterMetaType< std::vector *> >("std::vector *>"); - qRegisterMetaType< std::vector *> *> > >( - "std::vector *> *> >"); -} - -CPlotWidget::~CPlotWidget() -{ - if(m_pTimer) - { - m_pTimer->stop(); - delete m_pTimer; - } - m_pTimer = Q_NULLPTR; - - if(m_pHisEventManage) - { - emit releaseHisEventThread(); - m_pHisEventManage = Q_NULLPTR; - } - - if(m_pHisEventThread) - { - m_pHisEventThread->quit(); - m_pHisEventThread->wait(); - } - m_pHisEventThread = Q_NULLPTR; - - if(m_pHisDataManage) - { - emit releaseHisDataThread(); - m_pHisDataManage = Q_NULLPTR; - } - if(m_pHisDataThread) - { - m_pHisDataThread->quit(); - m_pHisDataThread->wait(); - } - m_pHisDataThread = Q_NULLPTR; - - if(m_pTrendGraph) - { - delete m_pTrendGraph; - } - m_pTrendGraph = Q_NULLPTR; - - if(m_pDpcdaForApp) - { - m_pDpcdaForApp->unsubscribeAll(); - delete m_pDpcdaForApp; - } - m_pDpcdaForApp = Q_NULLPTR; - - if(m_rtDataCollect->isRunning()) - { - m_rtDataCollect->disconnect(this); - m_rtDataCollect->requestInterruption(); - m_rtDataCollect->wait(); - } - m_rtDataCollect = Q_NULLPTR; - delete ui; -} - -/************************************************************************ - * - * 1、初始化界面 - * 2、初始化实时数据采集 - * - ************************************************************************/ -void CPlotWidget::initialize() -{ - m_pTrendGraph = new CTrendGraph(); - m_rtRange = 10 * 60 * 1000; //< second - - //< GroupButton - m_TrendTypeButton = new QButtonGroup(this); - m_TrendTypeButton->addButton(ui->realTime, E_Trend_RealTime); - m_TrendTypeButton->addButton(ui->sec, E_Trend_His_Minute); - m_TrendTypeButton->addButton(ui->day, E_Trend_His_Day); - m_TrendTypeButton->addButton(ui->week, E_Trend_His_Week); - m_TrendTypeButton->addButton(ui->month, E_Trend_His_Month); - m_TrendTypeButton->addButton(ui->quarter, E_Trend_His_Quarter); - m_TrendTypeButton->addButton(ui->year, E_Trend_His_Year); - m_TrendTypeButton->addButton(ui->custom, E_Trend_His_Custom); - connect(m_TrendTypeButton, SIGNAL(buttonClicked(int)), this, SLOT(updateTrendShowMode(int))); - - connect(ui->prePage, &QPushButton::clicked, this, &CPlotWidget::prePage); - connect(ui->nextPage, &QPushButton::clicked, this, &CPlotWidget::nextPage); - connect(ui->date, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotDateTimeChanged); - ui->date->setCalendarPopup(true); - ui->date->setButtonSymbols(QAbstractSpinBox::NoButtons); - ui->date->setDateTime(QDateTime::currentDateTime()); - - ui->customWidget->setVisible(false); - ui->customSearch->setVisible(false); - ui->startData->setCalendarPopup(true); - ui->endData->setCalendarPopup(true); - ui->startData->setButtonSymbols(QAbstractSpinBox::NoButtons); - ui->endData->setButtonSymbols(QAbstractSpinBox::NoButtons); - ui->startData->setMinimumWidth(150); - ui->endData->setMinimumWidth(150); - QDateTime curDateTime = QDateTime::currentDateTime(); - curDateTime.setTime(QTime(curDateTime.time().hour(), - curDateTime.time().minute(),0,0)); - ui->endData->setDateTime(curDateTime); - QDateTime preDateTime = curDateTime.addSecs(-600); - ui->startData->setDateTime(preDateTime); - ui->interval->setView(new QListView()); - ui->interval->addItem(tr("一秒钟"), 1); - ui->interval->addItem(tr("一分钟"), 1*60); - ui->interval->addItem(tr("十分钟"), 10*60); - ui->interval->addItem(tr("一小时"), 60*60); - ui->interval->addItem(tr("八小时"), 8*60*60); - ui->interval->addItem(tr("一天"), 24*60*60); - connect(ui->interval, &QComboBox::currentTextChanged, this, &CPlotWidget::slotIntervalChanged); - connect(ui->customSearch, &QPushButton::clicked, this, &CPlotWidget::slotCustomSearch); - connect(ui->startData, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotStartDateChanged); - connect(ui->endData, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotEndDateChanged); - - //< initPlot - ui->plot->setEnabled(true); - ui->plot->setSymbolPos(QPoint(width() / 2, 0)); - ui->plot->setNoAntialiasingOnDrag(true); - ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //<水平拖拽 - ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //<水平缩放 - ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); - QSharedPointer ticker(new QCPAxisTickerDateTime()); - ui->plot->xAxis->setTicker(ticker); - ui->plot->yAxis->setRange(-1, 1); - ui->plot->yAxis->scaleRange(1.02); - ui->plot->yAxis2->setVisible(true); - ui->plot->xAxis->setScaleType(QCPAxis::stLinear); - ui->plot->xAxis->rescale(true); - m_ptrPlotTricker = ui->plot->yAxis->ticker(); - - connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->yAxis2, SLOT(setRange(QCPRange))); - connect(ui->plot->xAxis, SIGNAL(rangeChanged(const QCPRange &,const QCPRange &)), this, SLOT(plotAxisRangeChanged(const QCPRange &,const QCPRange &))); - connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeDraged, this, &CPlotWidget::updateCurves); - connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeScaled, this, &CPlotWidget::updateCurves); - connect(ui->plot, &QCustomPlot::symbolPosChanged, this, &CPlotWidget::updateLengedValue); - - //< initTitle - m_trendTitle = new QCPItemText(ui->plot); - m_trendTitle->setObjectName("m_trendTitle"); - m_trendTitle->setPositionAlignment(Qt::AlignCenter); - m_trendTitle->position->setType(QCPItemPosition::ptAxisRectRatio); - m_trendTitle->position->setCoords(0.03, 0.01); - m_trendTitle->setColor(QColor(255,255,255)); - m_trendTitle->setFont(QFont("Microsoft YaHei", 10)); - m_trendTitle->setText("实时趋势"); - m_trendTitle->setVisible(false); - - m_pTableDataModel = new CTableDataModel(ui->m_dataView); - ui->m_dataView->setModel(m_pTableDataModel); - ui->m_dataView->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->m_dataView->verticalHeader()->setVisible(false); - ui->m_dataView->setAlternatingRowColors(true); - ui->m_dataView->horizontalHeader()->setObjectName("m_dataView"); - ui->m_dataView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); - ui->m_dataView->setSelectionBehavior(QAbstractItemView::SelectRows); -// ui->m_dataView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); -// ui->m_dataView->horizontalHeader()->setMinimumSectionSize(200); - ui->m_dataView->horizontalHeader()->setDefaultSectionSize(200); - connect(ui->m_dataView, SIGNAL(clicked(QModelIndex)), this, SLOT(tableSelectionChanged(QModelIndex))); - - //< initTableView - m_pLengedModel = new CCurveLegendModel(ui->lengedView); - ui->lengedView->setModel(m_pLengedModel); - ui->lengedView->setItemDelegate(new CCurveLegnedDelegate(ui->lengedView)); - ui->lengedView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked); - ui->lengedView->verticalHeader()->setVisible(false); - ui->lengedView->setAlternatingRowColors(true); - ui->lengedView->horizontalHeader()->setStretchLastSection(true); - ui->lengedView->horizontalHeader()->setObjectName("m_legendHeader"); - ui->lengedView->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->lengedView->setSelectionMode(QAbstractItemView::SingleSelection); - ui->lengedView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->lengedView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); - - connect(m_pLengedModel, &CCurveLegendModel::graphVisibleChanged, this, &CPlotWidget::graphVisibleChanged); - connect(m_pLengedModel, &CCurveLegendModel::graphPropertyChanged, this, &CPlotWidget::graphPropertyChanged); - connect(m_pLengedModel, &CCurveLegendModel::deleteCurrentGraph, this, &CPlotWidget::deleteCurrentGraph); - connect(m_pLengedModel, &CCurveLegendModel::sigJumpToMaxTime, this, &CPlotWidget::jumpToMaxTime); - connect(m_pLengedModel, &CCurveLegendModel::sigJumpToMinTime, this, &CPlotWidget::jumpToMinTime); - connect(ui->lengedView, &QTableView::clicked, this, &CPlotWidget::updateGraphSelection); - - ui->plotExport->setVisible(false); - ui->clear->setEnabled(false); - ui->collectCurve->setVisible(false); - ui->switchBtn->setToggle(false); - ui->switchBtn->setText(tr("曲线")); - ui->switchBtn->setCheckedText(tr("表格")); - ui->m_dataView->setVisible(false); - connect(ui->adapt, &QCheckBox::toggled, this, &CPlotWidget::updateAdaptState); - connect(ui->collectCurve, &QPushButton::clicked, this, &CPlotWidget::addCollect); - connect(ui->plotPrint, &QPushButton::clicked, this, &CPlotWidget::slotPrint); - connect(ui->plotExport, &QPushButton::clicked, this, &CPlotWidget::slotExport); - connect(ui->clear, &QPushButton::clicked, this, &CPlotWidget::clear); - connect(ui->switchBtn, &CSWitchButton::toggled, this, &CPlotWidget::showTypeChanged); - if(Q_NULLPTR == m_pTimer) - { - m_pTimer = new QTimer(this); - m_pTimer->setInterval(1000); - connect(m_pTimer, &QTimer::timeout, this, &CPlotWidget::realTimeElapsed); - } - - m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); - m_rtDataCollect = new CRealTimeDataCollect(this); - connect(m_rtDataCollect, &CRealTimeDataCollect::finished, m_rtDataCollect, &CRealTimeDataCollect::deleteLater); - connect(m_rtDataCollect, &CRealTimeDataCollect::realTimeTrendDataArrived, this, &CPlotWidget::recvRealTimeTrendData, Qt::QueuedConnection); - m_rtDataCollect->start(); - - m_pHisDataManage = new CHisDataManage(); - m_pHisDataThread = new QThread(this); - m_pHisDataManage->moveToThread(m_pHisDataThread); - connect(m_pHisDataThread, &QThread::finished, m_pHisDataThread, &QObject::deleteLater); - connect(this, &CPlotWidget::releaseHisDataThread, m_pHisDataManage, &CHisDataManage::release, Qt::BlockingQueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryOriginalData, m_pHisDataManage, &CHisDataManage::queryHistoryOriginalData, Qt::QueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryPolymericData, m_pHisDataManage, &CHisDataManage::queryHistoryPolymericData, Qt::QueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryComputeData, m_pHisDataManage, &CHisDataManage::queryHistoryComputeData, Qt::QueuedConnection); - connect(m_pHisDataManage, &CHisDataManage::sigupdateHisOriginalData, this, &CPlotWidget::updateHisOriginalData, Qt::QueuedConnection); - connect(m_pHisDataManage, &CHisDataManage::sigHistoryPolymericData, this, &CPlotWidget::updateHisPolymericData, Qt::QueuedConnection); - connect(m_pHisDataManage, &CHisDataManage::sigHistoryComputeData, this, &CPlotWidget::updateHisComputeData, Qt::QueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryEvent, m_pHisDataManage, &CHisDataManage::queryHistoryEvents, Qt::QueuedConnection); - connect(m_pHisDataManage, &CHisDataManage::sigHistoryEvent, this, &CPlotWidget::updatePhaseTracer, Qt::QueuedConnection); - connect(m_pHisDataManage, &CHisDataManage::sigHisSearch, this, &CPlotWidget::slotEnableSearch, Qt::QueuedConnection); - m_pHisDataThread->start(); - - m_pHisEventManage = new CHisEventManage(); - m_pHisEventThread = new QThread(this); - m_pHisEventManage->moveToThread(m_pHisEventThread); - connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); - connect(this, &CPlotWidget::releaseHisEventThread, m_pHisEventManage, &CHisEventManage::release, Qt::BlockingQueuedConnection); - connect(m_pHisEventManage, &CHisEventManage::updateHisEvent, this, &CPlotWidget::updateGraphEvent ,Qt::QueuedConnection); - m_pHisEventThread->start(); - - ui->scaleSlider->setMouseTracking(true); - ui->scaleSlider->setHandleMovementMode(QxtSpanSlider::NoCrossing); - ui->scaleSlider->setMinimum(-100000); - ui->scaleSlider->setMaximum(100000); - ui->scaleSlider->setLowerValue(0); - ui->scaleSlider->setUpperValue(0); - connect(ui->scaleSlider, &QxtSpanSlider::lowerValueChanged, this, &CPlotWidget::setYAxisRange); - connect(ui->scaleSlider, &QxtSpanSlider::upperValueChanged, this, &CPlotWidget::setYAxisRange); - connect(ui->scaleSlider, &QxtSpanSlider::sliderPressed, this, &CPlotWidget::sliderPressed); - connect(ui->scaleSlider, &QxtSpanSlider::sliderDoubleClick, this, &CPlotWidget::sliderDoubleClick); - - initAlarmStatusFilter(); - connect(ui->checkBox_alarmPoint, &QCheckBox::clicked, this, &CPlotWidget::alarmPointCheckStateChanged); - - installMousePressEventFilter(); - - QMetaObject::invokeMethod(ui->realTime, "click"); -} - -void CPlotWidget::resizeEvent(QResizeEvent *event) -{ - QSize size = parentWidget()->size(); - int offset = 2; - if(m_isWindowMode) - offset = 15; - if(ui->titleFrame->isVisible()) - { - size.setHeight(size.height() - (ui->titleFrame->height() + ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + offset)); - } - else - { - size.setHeight(size.height() - (ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + offset)); - } - size.setWidth(ui->lengedView->width() - 20); - ui->plot->resize(size); - ui->plot->replot(); - - updateLengedColumnWidth(); - QWidget::resizeEvent(event); -} - -bool CPlotWidget::eventFilter(QObject *object, QEvent *event) -{ - if (QEvent::MouseButtonPress == event->type()) - { - emit sigHideCollect(); - emit sigHideSliderSet(); - if(object == ui->scaleSlider) - { - m_isTooltip = false; - QToolTip::hideText(); - } - } - else if(QEvent::MouseButtonRelease == event->type()) - { - if(object == ui->scaleSlider) - { - m_isTooltip = true; - } - } - else if(QEvent::MouseMove == event->type()) - { - if(object == ui->scaleSlider && m_isTooltip) - { - QMouseEvent *mouse = dynamic_cast(event); - QToolTip::showText(mouse->globalPos(), tr("双击输入值")); - } - } - - return QWidget::eventFilter(object, event); -} - -void CPlotWidget::updateLengedColumnWidth() -{ - int nLengedWidth = ui->lengedView->width(); - ui->lengedView->setColumnWidth(CCurveLegendModel::NAME, nLengedWidth / 12. * 3); - ui->lengedView->setColumnWidth(CCurveLegendModel::COLOR, nLengedWidth / 12. * 0.5); - ui->lengedView->setColumnWidth(CCurveLegendModel::VALUE, nLengedWidth / 12.); - ui->lengedView->setColumnWidth(CCurveLegendModel::MAX, nLengedWidth / 12.); - ui->lengedView->setColumnWidth(CCurveLegendModel::MAXTIME, nLengedWidth / 12. * 1.5); - ui->lengedView->setColumnWidth(CCurveLegendModel::MIN, nLengedWidth / 12.); - ui->lengedView->setColumnWidth(CCurveLegendModel::MINTIME, nLengedWidth / 12. * 1.5); - ui->lengedView->setColumnWidth(CCurveLegendModel::AVE, nLengedWidth / 12.); - //单位目前未查询处理为空,屏蔽显示 - ui->lengedView->setColumnWidth(CCurveLegendModel::UNIT, nLengedWidth / 12. * 1.5); - // ui->lengedView->setColumnWidth(CCurveLegendModel::FACTOR, nLengedWidth / 12.); - // ui->lengedView->setColumnWidth(CCurveLegendModel::OFFSET, nLengedWidth / 12.); -} - -void CPlotWidget::updateCurveSelectionColor(QCPGraph *graph) -{ - if(!graph) - { - return; - } - QPen selectedPen = graph->selectionDecorator()->pen(); - selectedPen.setWidth(1); - QColor color; - QColor graphColor = graph->pen().color(); - int r = graphColor.red() > 225 ? graphColor.red() - 30 : graphColor.red() + 30; - int g = graphColor.green() > 225 ? graphColor.green() - 30 : graphColor.green() + 30; - int b = graphColor.blue() > 225 ? graphColor.blue() - 30 : graphColor.blue() + 30; - color.setRgb(r, g, b); - selectedPen.setColor(color); - graph->selectionDecorator()->setPen(selectedPen); -} - -E_Trend_Type CPlotWidget::getRangeType(const QCPRange &range) -{ - if(range.size() <= 0) - { - return E_Trend_Invalid; - } - - QDateTime upper = QDateTime::fromMSecsSinceEpoch(range.upper); - - if(range.lower >= upper.addSecs(-10).toMSecsSinceEpoch()) - { - return E_Trend_RealTime; - } - else if(range.lower >= upper.addSecs(-600).toMSecsSinceEpoch()) - { - return E_Trend_His_Minute; - } - else if(range.lower >= upper.addSecs(-3600).toMSecsSinceEpoch()) - { - return E_Trend_His_Hour; - } - else if(range.lower >= upper.addDays(-1).toMSecsSinceEpoch()) - { - return E_Trend_His_Day; - } - else if(range.lower >= upper.addDays(-7).toMSecsSinceEpoch()) - { - return E_Trend_His_Week; - } - else if(range.lower >= upper.addMonths(-1).toMSecsSinceEpoch()) - { - return E_Trend_His_Month; - } - else if(range.lower >= upper.addMonths(-3).toMSecsSinceEpoch()) - { - return E_Trend_His_Quarter; - } - else if(range.lower >= upper.addYears(-1).toMSecsSinceEpoch()) - { - return E_Trend_His_Year; - } - - return E_Trend_His_Year; -} - -int CPlotWidget::currentGroupByMinute() -{ - int nGroupByMinute = 0; - switch (m_type) - { - case E_Trend_RealTime: - { - //< Error - } - break; - case E_Trend_His_Minute: - { - //< Error - } - break; - case E_Trend_His_Hour: - { - //< Error - } - break; - case E_Trend_His_Day: - { - nGroupByMinute = 1; - } - break; - case E_Trend_His_Week: - { - nGroupByMinute = 7; - } - break; - case E_Trend_His_Month: - { - nGroupByMinute = 30; - } - break; - case E_Trend_His_Quarter: - { - nGroupByMinute = 90; - } - break; - case E_Trend_His_Year: - { - nGroupByMinute = 365; - } - break; - default: - break; - } - return nGroupByMinute; -} - -/************************************************************************ - * - * 接口 - * - ************************************************************************/ -void CPlotWidget::setTitle(const QString &title) -{ - ui->title->setText(title); -} - -void CPlotWidget::setTitleVisible(bool visible) -{ - ui->titleFrame->setVisible(visible); -} - -void CPlotWidget::setTickCount(const int &count) -{ - QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); - ticker->setTickCount(count); -} - -void CPlotWidget::insertTag(const QString &tag, const bool &resetTitle) -{ - if(resetTitle) - { - setTitle(tr("趋势图")); - } - Curve curve; - curve.tag = tag; - QList list = m_pTrendGraph->curveColors(); - int index = 0; - for(int nIndex=0; nIndexindex("curve.tag"); - if(mIndex != -1) - { - ui->lengedView->setRowHidden(mIndex,true); - } -} - -void CPlotWidget::insertTag(const QStringList &listTag, const bool &resetTitle) -{ - m_pTrendGraph->clear(); - foreach (QString tag, listTag) - { - insertTag(tag, resetTitle); - } -} - -void CPlotWidget::removeTag(const QString &tag, const bool &resetTitle) -{ - if(resetTitle) - { - setTitle(tr("趋势图")); - } - m_isSetSliderValue = false; - setAllLengedShow(); - int nIndex = m_pTrendGraph->removeCurve(tag); - if(nIndex != -1) - { - if(m_showType == E_Show_Table) - { - m_pTableDataModel->removeCurveData(ui->plot->graph(nIndex)->desc()); - } - ui->plot->removeGraph(nIndex); - } - - m_pLengedModel->setTrendGraph(m_pTrendGraph); - int mIndex = m_pTrendGraph->index("curve.tag"); - if(mIndex != -1) - { - ui->lengedView->setRowHidden(mIndex,true); - } - updateLengedColumnWidth(); - if(!m_pTrendGraph->curves().size()) - { - ui->plot->yAxis->setRange(QCPRange(-1, 1)); - - if(m_isWindowMode) - { - ui->collectCurve->setVisible(false); - } - ui->clear->setEnabled(false); - }else{ - removeCurvesGroupQuery(); - if(m_horizontalGraph) - { - groupQueryHistoryEvent(); - } - } - rescaleYAxisRange(); - ui->plot->replot(); -} - -void CPlotWidget::setDisplayTime(const int &trendType, const double &dateTime, const bool &alarm) -{ - QAbstractButton* Button = m_TrendTypeButton->button(trendType); - if(Button) - { - ui->date->blockSignals(true); - QMetaObject::invokeMethod(Button, "click"); - ui->date->blockSignals(false); - - QDateTime nDateTime = QDateTime::fromMSecsSinceEpoch(dateTime); - ui->date->setDateTime(nDateTime); - if(E_Trend_His_Day == trendType) - { - ui->plot->xAxis->blockSignals(true); - ui->plot->xAxis->setRange(dateTime - 600000, dateTime + 600000); - ui->plot->xAxis->blockSignals(false); - } - - ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(dateTime), 0)); - if(alarm) - { - ui->checkBox_alarmPoint->setChecked(true); - alarmPointCheckStateChanged(); - } - } -} - -void CPlotWidget::setTagVisible(const QString &tag, const bool &visible) -{ - setAllLengedShow(); - int nIndex = m_pTrendGraph->index(tag); - if(nIndex != -1) - { - m_pLengedModel->setData(m_pLengedModel->index(nIndex, 0), visible, Qt::CheckStateRole); - ui->plot->replot(); - } - int mIndex = m_pTrendGraph->index("curve.tag"); - if(mIndex != -1) - { - ui->lengedView->setRowHidden(mIndex,true); - } -} - -void CPlotWidget::setDateButtonVisible(const int &button, const bool &visible) -{ - QAbstractButton* Button = m_TrendTypeButton->button(button); - if(Button) - { - Button->setVisible(visible); - } -} - -void CPlotWidget::setClearVisible(bool visible) -{ - if(visible) - { - ui->clear->show(); - } - else - { - ui->clear->hide(); - } -} - -void CPlotWidget::setAdaptVisible(bool visible) -{ - m_isAdaptShow = false; - - ui->adapt->setVisible(visible); -} - -void CPlotWidget::setAlarmPointVisible(bool visible) -{ - m_isAlarmShow = false; - - ui->checkBox_alarmPoint->setVisible(visible); - ui->comboBox_alarmStatus->setVisible(visible); -} - -void CPlotWidget::insertCurve(Curve curve) -{ - m_isSetSliderValue = true; - if((NULL != m_horizontalGraph && ui->plot->graphCount() >= 65) || - (NULL == m_horizontalGraph && ui->plot->graphCount() >= 64)) - { - if(m_numWarnFlag) - { - QMessageBox::warning(this, tr("错误"), tr("当前趋势曲线已达最大支持数量[64]!"), QMessageBox::Ok); - m_numWarnFlag = false; - } - emit updateTagCheckState(curve.tag, false); - return; - } - - m_numWarnFlag = true; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - if(curve.tag == ui->plot->graph(nIndex)->name()) - { - LOGINFO("趋势曲线[%s]已存在", curve.tag.toStdString().c_str()); - return; - } - } - - curve.type = CTrendInfoManage::instance()->getTagType(curve.tag); - curve.unit = CTrendInfoManage::instance()->getTagUnit(curve.tag); - if(curve.type.isEmpty()) - { - LOGINFO("趋势曲线[%s]类型不存在", curve.tag.toStdString().c_str()); - return; - } - - curve.desc = CTrendInfoManage::instance()->getTagDescription(curve.tag); - if(curve.desc.isEmpty()) - { - LOGINFO("趋势曲线[%s]描述不存在", curve.tag.toStdString().c_str()); - return; - } - - m_pDpcdaForApp->subscribe(curve.type.toStdString(), curve.tag.toStdString(), "value"); - - //< 添加曲线 - m_pTrendGraph->addCurve(curve); - QCPGraph * graph = ui->plot->addGraph(); - graph->setName(curve.tag); - graph->setDesc(curve.desc); - QPen pen; - pen.setWidth(1); - pen.setColor(curve.color); - graph->setPen(pen); - updateCurveSelectionColor(graph); - - updateGroupQuery(curve.tag); - - connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); - - //< 方波 - QString type = CTrendInfoManage::instance()->getTagType(curve.tag); - if(type == "digital" || type == "mix") - { - graph->setLineStyle(QCPGraph::lsStepLeft); - } - - //< 查询最新十分钟数据 -// double upper = QDateTime::currentMSecsSinceEpoch(); -// double lower = upper - (10 * 60 * 1000); -// SMeasPointKey key; -// std::string tmp = curve.tag.toStdString(); -// char * tag = (char*)malloc(tmp.size() + 1); -// memset(tag, 0, tmp.size() + 1); -// memcpy(tag, tmp.c_str(), tmp.size()); -// key.m_pszTagName = tag; -// key.m_enType = getMeasType(curve.type); -// std::vector * vecMpKey = new std::vector(); -// vecMpKey->push_back(key); -// emit sigQueryHistoryOriginalData(vecMpKey, lower, upper, E_REALTIME); - - updateCurves(); - - m_pLengedModel->setTrendGraph(m_pTrendGraph); - updateLengedColumnWidth(); - - ui->clear->setEnabled(true); - - if(m_isWindowMode) - { - ui->collectCurve->setVisible(true); - emit updateTagCheckState(curve.tag, true); - } - setLegendCurveTransformColumnVisible(true); -} - -void CPlotWidget::clear(bool clearTitle) -{ - if(!m_pTrendGraph->curves().size()) - { - ui->clear->setEnabled(false); - } - m_pTrendGraph->clear(); - m_pLengedModel->clear(); - m_pLengedModel->update(); - m_pTableDataModel->clear(); - m_horizontalGraph = NULL; - m_groupTagMap.clear(); - - ui->plot->yAxis->setRange(QCPRange(-1, 1)); - ui->plot->clearItems(clearTitle); - ui->plot->clearGraphs(); - ui->plot->replot(); - ui->checkBox_alarmPoint->setCheckState(Qt::Unchecked); - ui->adapt->setCheckState(Qt::Unchecked); - setTitle(tr("趋势图")); - if(m_isWindowMode) - { - ui->collectCurve->setVisible(false); - } - emit clearCurve(); -} - -void CPlotWidget::setWindowMode(const bool &isWindowMode) -{ - m_isWindowMode = isWindowMode; -} - -void CPlotWidget::setColorList(const QStringList &listColor) -{ - foreach (QString c, listColor) - { - c.replace("\r", ""); - m_listColor.append(QColor(c)); - } -} - -/****************************** 图表颜色 **************************************/ -QColor CPlotWidget::plotBackgroundColor() -{ - return m_plotBackgroundColor; -} - -void CPlotWidget::setPlotBackgroundColor(const QColor &color) -{ - m_plotBackgroundColor = color; - - ui->plot->setBackground(m_plotBackgroundColor); -} - -QPixmap CPlotWidget::plotBackImage() -{ - return m_plotBackImage; -} - -void CPlotWidget::setPlotBackImage(const QPixmap &pm) -{ - m_plotBackImage = pm; - - ui->plot->setBackgroundScaled(false); - ui->plot->setBackground(pm); -} - -QColor CPlotWidget::plotTickColor() -{ - return m_plotTickColor; -} - -void CPlotWidget::setPlotTickColor(const QColor &color) -{ - m_plotTickColor = color; - - ui->plot->xAxis->setTickLabelColor(color); - ui->plot->yAxis->setTickLabelColor(color); - ui->plot->yAxis2->setTickLabelColor(color); -} - -QColor CPlotWidget::plotGridColor() -{ - return m_plotGridColor; -} - -void CPlotWidget::setPlotGridColor(const QColor &color) -{ - m_plotGridColor = color; - - ui->plot->xAxis->grid()->setPen(color); - ui->plot->yAxis->grid()->setPen(color); - - ui->plot->xAxis->grid()->setSubGridPen(color); - ui->plot->yAxis->grid()->setSubGridPen(color); -} - -QColor CPlotWidget::plotZeroLineColor() -{ - return m_plotZeroLineColor; -} - -void CPlotWidget::setPlotZeroLineColor(const QColor &color) -{ - m_plotZeroLineColor = color; - - ui->plot->xAxis->grid()->setZeroLinePen(QPen(color)); - ui->plot->yAxis->grid()->setZeroLinePen(QPen(color)); -} - -QColor CPlotWidget::plotTickPen() -{ - return m_plotTickPen; -} - -void CPlotWidget::setPlotTickPen(const QColor &color) -{ - m_plotTickPen = color; - - ui->plot->xAxis->setBasePen(color); - ui->plot->yAxis->setBasePen(color); - ui->plot->yAxis2->setBasePen(color); - ui->plot->xAxis->setTickPen(color); - ui->plot->yAxis->setTickPen(color); - ui->plot->yAxis2->setTickPen(color); - ui->plot->xAxis->setSubTickPen(color); - ui->plot->yAxis->setSubTickPen(color); - ui->plot->yAxis2->setSubTickPen(color); -} - -void CPlotWidget::realTimeElapsed() -{ - //< 刷新X轴 - const QCPRange &range = ui->plot->xAxis->range(); - double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); - double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); - ui->plot->xAxis->setRange(upper, range.size(), Qt::AlignRight); - - QList listVal; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - m_pTrendGraph->updateRTCurveStatisticsInfo(graph->name()); - QVector * pCPGraphData = graph->data()->data(); - - if(pCPGraphData->isEmpty()) - { - listVal.append(qSqrt(-1.)); - } - else - { - listVal.append((*(pCPGraphData->end() - 2)).value); - - //< set virtual point value - if(limit == pCPGraphData->last().key) - { - pCPGraphData->last().value = (*(pCPGraphData->end() - 2)).value; - } - } - } - - if(E_Show_Table == m_showType) - { - updateRealTimeTableData(); - } - m_pLengedModel->setTrendCurrentValues(listVal); - rescaleYAxisRange(); - ui->plot->replot(); -} - -void CPlotWidget::recvRealTimeTrendData(const QString &tagName, QVariant value, int status, E_Point_Type pointType) -{ -// LOGINFO("Recv RealTime Trend Data-[Tag Name: %s, value: %f] ", tagName.toStdString().c_str(), value.toDouble()); - double key = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); - int validStatus = CTrendInfoManage::instance()->getInvalidStatus(pointType, status); - m_pTrendGraph->pushCurveRTDataValue(tagName, key, value.toDouble(), validStatus); - - if(E_Trend_RealTime != m_type) - { - return; - } - - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - if(graph->name() == tagName) - { - QVector * pCPGraphData = graph->data()->data(); - - if(pCPGraphData->size() > 1 && qAbs(((*(pCPGraphData->end() - 2)).value - value.toDouble())) < _EPSILON_) - { - return; - } - graph->addData(key, value.toDouble(), validStatus); - if( pCPGraphData->first().key < ( key - (20 * 60 * 1000) ) ) - { - graph->data()->removeBefore( key - (20 * 60 * 1000) ); - } - return; - } - } -} - -void CPlotWidget::updateRealTimeTableData() -{ - QMap> curveData; - QStringList headerList; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - if(ui->plot->graph(nIndex)->name() == "curve.tag") - { - continue; - } - const QVector< QPair > > &values = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()).values; - QVector vecGraphData; - double preValue = DBL_MAX; - QVector< QPair > >::const_iterator iter = values.constBegin(); - for(; iter != values.constEnd(); iter++) - { - if(qAbs((iter->second.first)-preValue) < _EPSILON_) - { - continue; - } - QCPGraphData graphData; - graphData.key = iter->first; - graphData.value = iter->second.first; - graphData.status = iter->second.second; - vecGraphData.push_back(graphData); - preValue = iter->second.first; - } - curveData.insert(ui->plot->graph(nIndex)->desc(), vecGraphData); - headerList.append(ui->plot->graph(nIndex)->desc()); - } - resetCurveData(curveData, headerList, false); - - - graphVisibleChanged(true); -} - -void CPlotWidget::plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange) -{ - Q_UNUSED(oldRange) - if(E_Show_Table == m_showType) - { - return; - } - - QDateTime upper = QDateTime::fromMSecsSinceEpoch(newRange.upper); - double midValue = (newRange.upper + newRange.lower) / 2; - - if(m_type == E_Trend_RealTime) - { - m_rtRange = newRange.size(); - if(m_rtRange > 10 * 60 * 1000) - { - m_rtRange = 10 * 60 * 1000; - } - else if(m_rtRange < 10 * 1000) - { - m_rtRange = 10 * 1000; - } - - double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); - ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); - return; - } - else if(m_type == E_Trend_His_Minute || m_type == E_Trend_His_Day || m_type == E_Trend_His_Week || m_type == E_Trend_His_Month || m_type == E_Trend_His_Quarter || m_type == E_Trend_His_Year) - { - QPair dateTime = getFatureDataTime(m_type, ui->date->dateTime()); - double range = newRange.size() > (dateTime.second - dateTime.first)?(dateTime.second - dateTime.first):newRange.size(); - if(newRange.lower < dateTime.first) - { - ui->plot->xAxis->setRange(dateTime.first, range, Qt::AlignLeft); - return; - } - else if(newRange.upper > dateTime.second) - { - ui->plot->xAxis->setRange(dateTime.second, range, Qt::AlignRight); - return; - } - } - else if(m_type == E_Trend_His_Custom) - { - double lower = ui->startData->dateTime().toMSecsSinceEpoch(); - double upper = ui->endData->dateTime().toMSecsSinceEpoch(); - double range = newRange.size() > (upper - lower)?(upper - lower):newRange.size(); - if(newRange.lower < lower) - { - ui->plot->xAxis->setRange(lower, range, Qt::AlignLeft); - return; - } - else if(newRange.upper > upper) - { - ui->plot->xAxis->setRange(upper, range, Qt::AlignRight); - return; - } - } - - QList listToolTip= findChildren(); - foreach (CToolTip * pToolTip, listToolTip) - { - pToolTip->close(); - } - - if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) - { - updateYAxisTicker(); - } - - E_Trend_Type rangeType = getRangeType(newRange); - if(m_type == rangeType) - { - return; - } - - if(m_type == E_Trend_His_Minute) - { - if(rangeType == E_Trend_RealTime) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-10).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Hour) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Day) - { - if(rangeType == E_Trend_His_Minute) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Week) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Week) - { - if(rangeType == E_Trend_His_Day) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Month) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Month) - { - if(rangeType == E_Trend_His_Week) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Quarter) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Quarter) - { - if(rangeType == E_Trend_His_Month) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Year) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Year) - { - if(rangeType == E_Trend_His_Quarter) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - else if(m_type == E_Trend_His_Custom) - { - if(rangeType == E_Trend_RealTime) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-10).toMSecsSinceEpoch(), Qt::AlignCenter); - } - else if(rangeType == E_Trend_His_Year) - { - ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); - } - } - -// if(rangeType != E_Trend_Invalid && rangeType != E_Trend_His_Minute && rangeType != E_Trend_His_Hour) -// { -// m_TrendTypeButton->button((int)rangeType)->setChecked(true); -// } -// updateTrendShowMode(rangeType, false); -} - -void CPlotWidget::updateTrendShowMode(int nIndex, bool updateXAxisRange) -{ - m_type = (E_Trend_Type)nIndex; - - m_isSetSliderValue = true; - updateGraphTitle(nIndex); - - if(Q_NULLPTR != m_pTimer && m_pTimer->isActive()) - { - m_pTimer->stop(); - } - m_pLengedModel->setMode(CCurveLegendModel::LENGED_HIS_MODE); - if(m_isWindowMode) - { - setLegendCurveTransformColumnVisible(false); - } - //< default setting - ui->prePage->setEnabled(true); - ui->nextPage->setEnabled(true); - ui->date->setEnabled(true); - ui->plot->axisRect()->setScaleRight(false); - ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //< 水平拖拽 - ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //< 水平缩放 - ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); - ui->plot->xAxis->setScaleType(QCPAxis::stLinear); - - int count = ui->plot->graphCount(); - for(int n(0); nplot->graph(n); - graph->data()->clear(); - } - - ui->plot->clearItems(); - m_listTracer.clear(); - - updateAxisFormat(updateXAxisRange); - - if (m_type == E_Trend_RealTime || m_type == E_Trend_Invalid) - { - ui->dataWidget->setVisible(false); - ui->customWidget->setVisible(false); - ui->adapt->setVisible(false); - ui->checkBox_alarmPoint->setVisible(false); - ui->comboBox_alarmStatus->setVisible(false); - } - else if (m_type == E_Trend_His_Custom) - { - ui->customWidget->setVisible(true); - ui->dataWidget->setVisible(false); - slotCustomSearch(); - } - else - { - ui->dataWidget->setVisible(true); - ui->customWidget->setVisible(false); - if(m_isAdaptShow) - { - ui->adapt->setVisible(true); - } - if(m_isAlarmShow) - { - ui->checkBox_alarmPoint->setVisible(true); - ui->comboBox_alarmStatus->setVisible(true); - } - ui->date->setDateTime(QDateTime::currentDateTime()); - } - if(m_showType == E_Show_Table) - { - ui->adapt->setVisible(false); - ui->checkBox_alarmPoint->setVisible(false); - ui->comboBox_alarmStatus->setVisible(false); - m_pTableDataModel->clear(); - } - - // if(m_type == E_Trend_RealTime) - { - if(E_Show_Table == m_showType) - { - updateRealTimeTableData(); - } - updateCurves(); - } -} - -void CPlotWidget::updateComputeValue(double lower, double upper, std::vector vecMethod) -{ - if(!ui->plot->graphCount()) - { - return; - } - - std::vector * vecMpKey = new std::vector(); - for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) - { - const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); - SMeasPointKey key; - std::string tmp = curve.tag.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(curve.type); - vecMpKey->push_back(key); - } - - if(!m_pHisDataManage->isTsdbExuting()) - { - emit sigQueryHistoryComputeData(vecMpKey, lower, upper, vecMethod); - } - else - { - m_pHisDataManage->postTsdbCommandQueue(E_COMPUTER, vecMpKey, lower, upper, -1, vecMethod); - } -} - -void CPlotWidget::updateGraphTitle(int nIndex) -{ - m_type = (E_Trend_Type)nIndex; - - if(m_type == E_Trend_RealTime) - { - m_trendTitle->setText(tr("实时趋势")); - } - else if(m_type == E_Trend_His_Minute) - { - m_trendTitle->setText(tr("秒趋势")); - } - else if(m_type == E_Trend_His_Day) - { - m_trendTitle->setText(tr("日趋势")); - } - else if(m_type == E_Trend_His_Week) - { - m_trendTitle->setText(tr("周趋势")); - } - else if(m_type == E_Trend_His_Month) - { - m_trendTitle->setText(tr("月趋势")); - } - else if(m_type == E_Trend_His_Quarter) - { - m_trendTitle->setText(tr("季度趋势")); - } - else if(m_type == E_Trend_His_Year) - { - m_trendTitle->setText(tr("年趋势")); - } - else if(m_type == E_Trend_His_Custom) - { - m_trendTitle->setText(tr("自定义趋势")); - } -} - -void CPlotWidget::updateCurves() -{ - if(E_Trend_RealTime == m_type) - { - updateRealTimeCurveRecord(); - rescaleYAxisRange(); - ui->plot->replot(); - } - else - { - updateHistoryCurveRecord(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper); - } -} - -void CPlotWidget::updateRealTimeCurveRecord() -{ - if(Q_NULLPTR == m_pTrendGraph) - { - return; - } - double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - //< 清空数据 - QSharedPointer container(new QCPGraphDataContainer()); - - const QVector< QPair > > &values = m_pTrendGraph->curve(graph->name()).values; - QVector< QPair > >::const_iterator it = values.constBegin(); - double preValue = DBL_MAX; - while (it != values.constEnd()) - { - //< LOGINFO("Update RealTime Trend Data-----------------[Time: %f, value: %f] ", it->first, it->second); - if(qAbs((it->second.first)-preValue) < _EPSILON_) - { - ++it; - continue; - } - container->add(QCPGraphData(it->first, it->second.first, it->second.second)); - preValue = it->second.first; - ++it; - } - - //< virtual point - if(container->data()->size() > 0) - { - container->add(QCPGraphData(limit, container->data()->last().value, container->data()->last().status)); - } - else - { - container->add(QCPGraphData(limit, qSqrt(-1.))); - } - graph->setData(container); - } - ui->plot->replot(); -} - -void CPlotWidget::updateHistoryCurveRecord(double lower, double upper) -{ - if(!ui->plot->graphCount()) - { - return; - } - if(E_Trend_His_Custom == m_type) - { - slotCustomSearch(true); - return; - } - - std::vector * vecMpKey = new std::vector(); - for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) - { - const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); - SMeasPointKey key; - std::string tmp = curve.tag.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(curve.type); - vecMpKey->push_back(key); - } - - if(!m_pHisDataManage->isTsdbExuting()) - { - if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) - { - emit sigQueryHistoryOriginalData(vecMpKey, lower, upper); - } - else - { - emit sigQueryHistoryPolymericData(vecMpKey, lower, upper, currentGroupByMinute() * 60, kbd_dbms::CM_FIRST); - } - } - else - { - if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) - { - m_pHisDataManage->postTsdbCommandQueue(E_ORIGINAL, vecMpKey, lower, upper); - } - else - { - m_pHisDataManage->postTsdbCommandQueue(E_POLYMERIC, vecMpKey, lower, upper, currentGroupByMinute() * 60, std::vector{kbd_dbms::CM_FIRST}); - } - } - - QPair range = getFatureDataTime(m_type, ui->date->dateTime()); - std::vector vecMethod{kbd_dbms::CM_MAX, kbd_dbms::CM_MIN}; - updateComputeValue(range.first, range.second, vecMethod); -} - -void CPlotWidget::updateHisOriginalData(std::vector *vecMpKey, std::vector *> *vecResult, E_Data_Type type) -{ - std::vector< QSharedPointer > vecRange; - std::vector< QSharedPointer > vecContainer; - - bool isAddVirtualPoint = true; - double lower = ui->plot->xAxis->range().lower; - double upper = ui->plot->xAxis->range().upper; - if(m_showType == E_Show_Table) - { - isAddVirtualPoint = false; - if(m_type == E_Trend_His_Custom) - { - lower = ui->startData->dateTime().toMSecsSinceEpoch(); - upper = ui->endData->dateTime().toMSecsSinceEpoch(); - } - } - updateHisData(vecMpKey, vecResult, vecRange, vecContainer, lower, upper, isAddVirtualPoint); - - if(E_REALTIME == type) - { - for(size_t nIndex(0); nIndex < vecContainer.size(); ++nIndex) - { - QCPGraphDataContainer::iterator it = vecContainer.at(nIndex)->begin(); - while(it != vecContainer.at(nIndex)->end()) - { - m_pTrendGraph->pushCurveRTDataValue(vecMpKey->at(nIndex).m_pszTagName, it->key, it->value, it->status); - ++it; - } - } - updateCurves(); - } - else if(E_HISTORY == type) - { - if(m_showType == E_Show_Curve) - { - updateHistoryGraph(vecMpKey, vecContainer, vecRange); - } - else if(m_showType == E_Show_Table) - { - updateHistoryData(vecMpKey, vecContainer, vecRange); - } - } - m_pLengedModel->update(); - - //< 释放结果集 - std::vector *>::iterator res = vecResult->begin(); - while(vecResult->end() != res) - { - delete (*res); - ++res; - } - vecResult->clear(); - delete vecResult; - - //< 释放测点信息 - std::vector::iterator key = vecMpKey->begin(); - while(vecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - - } - vecMpKey->clear(); - delete vecMpKey; -} - -void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, int nGroupBySec) -{ - std::vector< QSharedPointer > vecRange; - std::vector< QSharedPointer > vecContainer; - - if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) - { - if(m_showType == E_Show_Curve) - { - updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, - ui->plot->xAxis->range().upper, true, nGroupBySec); - - updateHistoryGraph(vecMpKey, vecContainer, vecRange); - } - else if(m_showType == E_Show_Table) - { - if(m_type == E_Trend_His_Custom) - { - updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->startData->dateTime().toMSecsSinceEpoch(), - ui->endData->dateTime().toMSecsSinceEpoch(), false, nGroupBySec); - } - else - { - updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, - ui->plot->xAxis->range().upper, false, nGroupBySec); - } - - updateHistoryData(vecMpKey, vecContainer, vecRange); - } - } - m_pLengedModel->update(); - - //< 释放结果集 - std::vector *>::iterator res = vecResult->begin(); - while(vecResult->end() != res) - { - delete (*res); - ++res; - } - vecResult->clear(); - delete vecResult; - - //< 释放测点信息 - std::vector::iterator key = vecMpKey->begin(); - while(vecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - } - vecMpKey->clear(); - delete vecMpKey; -} - -void CPlotWidget::updateHisComputeData(std::vector *vecMpKey, std::vector *> *> > cmResult) -{ - typename std::vector *> *> >::const_iterator resultIter = cmResult.begin(); - while(resultIter != cmResult.end()) - { - EnComputeMethod method = resultIter->first; - typename std::vector *>::const_iterator it = resultIter->second->begin(); - while(it != resultIter->second->end()) - { - int nIndex = it - resultIter->second->begin(); - if(nIndex > ui->plot->graphCount()-1) - { - ++it; - continue; - } - QCPGraph * graph = ui->plot->graph(nIndex); - if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) - { - ++it; - continue; - } - std::vector * vecPoint = *it; - if(vecPoint->empty()) - { - ++it; - setCurveStatisData(graph->name(), method, true); - continue; - } - - typename std::vector::const_iterator pt = vecPoint->begin(); - while(pt != vecPoint->end()) - { - double value = qSqrt(-1.); - if (typeid(boost::int32_t) == pt->m_varValue.type()) - { - value = (double)boost::get(pt->m_varValue); - } - else if (typeid(boost::float64_t) == pt->m_varValue.type()) - { - value = (double)boost::get(pt->m_varValue); - } - - if(std::isnan(value)) - { - ++pt; - setCurveStatisData(graph->name(), method, true); - continue; - } - setCurveStatisData(graph->name(), method, false, value, pt->m_nTime); - ++pt; - } - ++it; - } - //< 释放结果集 - std::vector *>::iterator res = resultIter->second->begin(); - while(resultIter->second->end() != res) - { - delete (*res); - ++res; - } - resultIter->second->clear(); - delete resultIter->second; - resultIter++; - } - m_pLengedModel->update(); - - //< 释放测点信息 - std::vector::iterator key = vecMpKey->begin(); - while(vecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - } - vecMpKey->clear(); - delete vecMpKey; -} - -void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange) -{ - double lower = ui->plot->xAxis->range().lower; - double upper = ui->plot->xAxis->range().upper; - - if(vecContainer.size() == 0) - { - int count = ui->plot->graphCount(); - for(int n(0); nplot->graph(n); - graph->data()->clear(); - } - ui->plot->replot(); - } - - for(int nIndex(0); nIndex < (int)vecContainer.size(); ++nIndex) - { - if(nIndex > ui->plot->graphCount()-1) - { - continue; - } - QCPGraph * graph = ui->plot->graph(nIndex); - { - if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) - { - continue; - } - } - updateCurveHisData(lower, upper, graph, nIndex, vecContainer.at(nIndex), vecRange.at(nIndex)); - graph->data()->clear(); - graph->setData(vecContainer.at(nIndex)); - } - - updateLengedValue(ui->plot->xAxis->pixelToCoord(ui->plot->symbolPos().x())); - rescaleYAxisRange(); - ui->plot->replot(); -} - -void CPlotWidget::updateHistoryData(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange) -{ - double lower,upper; - if(m_type == E_Trend_His_Custom) - { - lower = ui->startData->dateTime().toMSecsSinceEpoch(); - upper = ui->endData->dateTime().toMSecsSinceEpoch(); - } - else - { - lower = ui->plot->xAxis->range().lower; - upper = ui->plot->xAxis->range().upper; - } - - QMap> curveData; - QStringList headerList; - for(int nIndex(0); nIndex < (int)vecContainer.size(); ++nIndex) - { - if(nIndex > ui->plot->graphCount()-1) - { - continue; - } - QCPGraph * graph = ui->plot->graph(nIndex); - { - if(graph->name() == "curve.tag") - { - continue; - } - if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) - { - continue; - } - } - updateCurveHisData(lower, upper, graph, nIndex, vecContainer.at(nIndex), vecRange.at(nIndex)); - - QVector vecGraphData; - QCPGraphDataContainer::const_iterator iter = vecContainer.at(nIndex)->constBegin(); - while(iter != vecContainer.at(nIndex)->end()) - { - QCPGraphData graphData; - graphData.key = iter->key; - graphData.value = iter->value; - graphData.status = iter->status; - vecGraphData.push_back(graphData); - iter++; - } - curveData.insert(graph->desc(), vecGraphData); - headerList.append(graph->desc()); - } - resetCurveData(curveData, headerList, true); - enableSearch(true); -} - -void CPlotWidget::updateCurveHisData(double lower, double upper, QCPGraph *graph, int index, QSharedPointer container, QSharedPointer range) -{ - int count = 0; //< accuml size - double offset = 0.; - double factor = 1.; - double accuml = 0.; - - const Curve &curve = m_pTrendGraph->curve(graph->name()); - if(m_bHisAdaption && m_type != E_Trend_RealTime) - { - double maxVal = range->max; - double minVal = range->min; - if(maxVal == minVal) - { - factor = maxVal == 0 ? 0 : 50. / maxVal; - offset = maxVal == 0 ? 50 : 0; - } - else - { - factor = 100. / (maxVal - minVal); - offset = -factor * minVal; - } - m_pTrendGraph->setCurveGraphFactor(index, factor); - m_pTrendGraph->setCurveGraphOffset(index, offset); - } - else - { - factor = curve.factor; - offset = curve.offset; - } - - //< 此设计考虑自定义缩放【已实现,暂未开放】扩展 - double max = -DBL_MAX; - double min = DBL_MAX; - double maxTime = -DBL_MAX; - double minTime = DBL_MAX; - double average = qSqrt(-1.); - QCPGraphDataContainer::iterator iter = container->begin(); - while(iter != container->end()) - { - if(qIsNaN(iter->value)) - { - ++iter; - continue; - } - - //< 统计值 - if(iter->key >= lower && iter->key <= upper) - { - ++count; - if(iter->value > max) - { - max = iter->value; - maxTime = iter->key; - } - if(iter->value < min) - { - min = iter->value; - minTime = iter->key; - } - - accuml += iter->value; - } - - //< 缩放数据 - if(m_bHisAdaption && m_type != E_Trend_RealTime - && m_showType != E_Show_Table) - { - iter->value *= factor; - iter->value += offset; - } - ++iter; - } - if(!container->isEmpty()) - { - if(count) - { - average = accuml / count; - } - } - m_pTrendGraph->setCurveHisDataValue(graph->name(), max, min, maxTime, minTime, average, accuml, *range); -} - -void CPlotWidget::updatePhaseTracer(std::vector *vecMpKey, std::vector *> *vecResult) -{ - ui->plot->clearItems(); - m_listTracer.clear(); - QMultiMap< double, QStringList > map; - if(ui->checkBox_alarmPoint->isChecked()) - { - for(size_t tagIndex(0); tagIndex < vecResult->size(); tagIndex++) - { - std::vector *evetVector = vecResult->at(tagIndex); - std::vector::iterator iter = evetVector->begin(); - for(; iter != evetVector->end(); iter++) - { - if(m_alarmStatusList.contains(iter->m_nAlmStatus)) - { - QStringList list; - list.append(vecMpKey->at(tagIndex).m_pszTagName); - list.append(QString::number(iter->m_nAlmType)); - map.insert(iter->m_nTime, list); - } - } - } - } - QPointF prePt(-1000., -1000.); - - //< 1min 显示所有事件 - bool bMinRange = ui->plot->xAxis->range().size() > 60; - QMultiMap< double, QStringList >::iterator rIter = map.begin(); - QMultiMap hidePoint; - for(; rIter != map.end(); rIter++) - { - double key = rIter.key(); - if(bMinRange) - { - double curX = ui->plot->xAxis->coordToPixel(key); - double curY = 0; - if( m_horizontalGraph ) - { - curY = ui->plot->yAxis->coordToPixel(m_horizontalGraph->value(key)); - } - QPointF pt = QPointF(curX, curY) - prePt; - if(pt.manhattanLength() < 8) - { - hidePoint.insert(key, rIter.value()[0]); - continue; - } - prePt = QPointF(curX, curY); - } - QStringList value = rIter.value(); - QCPItemTracer *phaseTracer = new QCPItemTracer(ui->plot, key, QString(value[1]).toInt(), QPen(Qt::red), QBrush(Qt::red), m_alarmStatusList); - phaseTracer->setGraphKey(key); - if(m_horizontalGraph!=NULL && m_type != E_Trend_RealTime) - { - phaseTracer->setGraph(m_horizontalGraph); - } - phaseTracer->addHidePoint(key, value[0]); - phaseTracer->setInterpolating(true); - if(m_listTracer.length() > 0) - m_listTracer.last()->setHidePoint(hidePoint); - m_listTracer.append(phaseTracer); - - connect(phaseTracer, &QCPItemTracer::itemTracerHoverd, m_pHisEventManage, &CHisEventManage::queryHisEvent, Qt::BlockingQueuedConnection); - hidePoint.clear(); - hidePoint.insert(key, value[0]); - } - if(m_listTracer.length() > 0 && !hidePoint.isEmpty()) - { - m_listTracer.last()->setHidePoint(hidePoint); - hidePoint.clear(); - } - //< 释放结果集 - std::vector *>::iterator res = vecResult->begin(); - while(res != vecResult->end()) - { - delete (*res); - ++res; - } - delete vecResult; - - //< 释放测点信息 - std::vector::iterator key = vecMpKey->begin(); - while(vecMpKey->end() != key) - { - free( (char*)key->m_pszTagName ); - ++key; - } - vecMpKey->clear(); - delete vecMpKey; - ui->plot->replot(); -} - -void CPlotWidget::updateGraphEvent(const qint64 &time, QStringList contents) -{ - foreach (QCPItemTracer *phaseTracer, m_listTracer) - { - if(phaseTracer->timeStamp() == time) - { - phaseTracer->setInfo(contents); - phaseTracer->showTips(); - } - } -} - -void CPlotWidget::updateAxisFormat(bool updateXAxisRange) -{ -// ui->plot->xAxis->blockSignals(true); - QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); - double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); - switch (m_type) - { - case E_Trend_RealTime: - { - //< 10 min - ui->prePage->setEnabled(false); - ui->nextPage->setEnabled(false); - ui->date->setEnabled(false); - ui->plot->setInteractions(QCP::iRangeZoom | QCP::iSelectPlottables); - ui->plot->axisRect()->setScaleRight(true); - ticker->setDateTimeFormat("hh:mm:ss"); - ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); - if(Q_NULLPTR != m_pTimer) - { - m_pTimer->start(); - } - if(m_isWindowMode) - { - ticker->setTickCount(11); - setLegendCurveTransformColumnVisible(true); - } - else - { - ticker->setTickCount(6); - } - - m_pLengedModel->setMode(CCurveLegendModel::LENGED_RT_MODE); - ui->plot->yAxis->setTicker(m_ptrPlotTricker); - ui->plot->yAxis2->setTicker(m_ptrPlotTricker); - } - break; - case E_Trend_His_Minute: - { - if(m_isWindowMode) - { - ticker->setTickCount(12); - } - else - { - ticker->setTickCount(6); - } - ticker->setDateTimeFormat("hh:mm:ss"); - ui->date->setMinimumWidth(170); - ui->date->setDisplayFormat("yyyy-MM-dd hh:mm"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Minute); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Hour: - { - if(m_isWindowMode) - { - ticker->setTickCount(11); - } - else - { - ticker->setTickCount(6); - } - ticker->setDateTimeFormat("hh:mm:ss"); - } - break; - case E_Trend_His_Day: - { - if(m_isWindowMode) - { - ticker->setTickCount(12); - } - else - { - ticker->setTickCount(6); - } - ticker->setDateTimeFormat("hh:mm:ss"); - ui->date->setMinimumWidth(120); - ui->date->setDisplayFormat("yyyy-MM-dd"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Day); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Week: - { - if(m_isWindowMode) - { - ticker->setTickCount(8); - } - else - { - ticker->setTickCount(6); - } - ticker->setDateTimeFormat("MM-dd hh ddd"); - ui->date->setMinimumWidth(120); - ui->date->setDisplayFormat("yyyy-MM-dd"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Week); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Month: - { - if(m_isWindowMode) - { - ticker->setTickCount(11); - } - else - { - ticker->setTickCount(10); - } - ticker->setDateTimeFormat("dd hh"); - ui->date->setMinimumWidth(120); - ui->date->setDisplayFormat("yyyy-MM"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Month); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Quarter: - { - if(m_isWindowMode) - { - ticker->setTickCount(10); - } - else - { - ticker->setTickCount(10); - } - ticker->setDateTimeFormat("MM-dd"); - ui->date->setMinimumWidth(120); - ui->date->setDisplayFormat("yyyy-MM"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Quarter); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Year: - { - if(m_isWindowMode) - { - ticker->setTickCount(13); - } - else - { - ticker->setTickCount(10); - } - ticker->setDateTimeFormat("MM-dd"); - ui->date->setMinimumWidth(120); - ui->date->setDisplayFormat("yyyy"); - if(updateXAxisRange) - { - QPair range = getFatureDataTime(E_Trend_His_Year); - ui->plot->xAxis->setRange(range.first, range.second); - } - } - break; - case E_Trend_His_Custom: - { - ticker->setTickCount(5); - - ticker->setDateTimeFormat("MM-dd hh:mm:ss"); - if(updateXAxisRange) - { - ui->plot->xAxis->setRange(ui->startData->dateTime().toMSecsSinceEpoch(), - ui->endData->dateTime().toMSecsSinceEpoch()); - } - } - break; - default: - break; - } -// ui->plot->xAxis->blockSignals(false); -} - -QPair CPlotWidget::getFatureDataTime(E_Trend_Type type, QDateTime curTime) -{ - QDateTime low; - QDateTime up; - QPair range; - if(!curTime.isValid()) - { - low = QDateTime::currentDateTime(); - up = QDateTime::currentDateTime(); - } - else - { - low = curTime; - up = curTime; - } - - switch (type) { - case E_Trend_His_Day: - { - break; - } - case E_Trend_His_Minute: - { - int minute = up.time().minute(); - up.setTime(QTime(up.time().hour(), (minute/10)*10+9, 59, 999)); - low.setTime(QTime(low.time().hour(), (minute/10)*10)); - range.first = low.toMSecsSinceEpoch(); - range.second = up.toMSecsSinceEpoch(); - return range; - } - case E_Trend_His_Week: - { - up = up.addDays(7-low.date().dayOfWeek()); - low = low.addDays(-low.date().dayOfWeek()+1); - break; - } - case E_Trend_His_Month: - { - up.setDate(QDate(low.date().year(), low.date().month(), low.date().daysInMonth())); - low.setDate(QDate(low.date().year(), low.date().month(), 1)); - break; - } - case E_Trend_His_Quarter: - { - QString month = QString::number(low.date().month()); - if(QString("1,2,3").split(",").indexOf(month) != -1) - { - up.setDate(QDate(low.date().year(), 3, 31)); - low.setDate(QDate(low.date().year(), 1, 1)); - } - else if(QString("4,5,6").split(",").indexOf(month) != -1) - { - up.setDate(QDate(low.date().year(), 6, 30)); - low.setDate(QDate(low.date().year(), 4, 1)); - } - else if(QString("7,8,9").split(",").indexOf(month) != -1) - { - up.setDate(QDate(low.date().year(), 9, 30)); - low.setDate(QDate(low.date().year(), 7, 1)); - } - else if(QString("10,11,12").split(",").indexOf(month) != -1) - { - up.setDate(QDate(low.date().year(), 12, 31)); - low.setDate(QDate(low.date().year(), 10, 1)); - } - break; - } - case E_Trend_His_Year: - { - up.setDate(QDate(low.date().year(), 12, 31)); - low.setDate(QDate(low.date().year(), 1, 1)); - break; - } - default: - break; - } - low.setTime(QTime(0,0,0)); - up.setTime(QTime(23,59,59)); - range.first = low.toMSecsSinceEpoch(); - range.second = up.toMSecsSinceEpoch(); - return range; -} - -void CPlotWidget::updateAdaptState(bool isAdapt) -{ - m_isSetSliderValue = true; - m_bHisAdaption = isAdapt; - if(m_isWindowMode) - { - setLegendCurveTransformColumnVisible(isAdapt); - } - updateCurves(); - - updateYAxisTicker(); -} - -void CPlotWidget::slotCollectGraph(const QString &text) -{ - emit collectGraph(text, *m_pTrendGraph); -} - -void CPlotWidget::slotSliderRangeChange(int lower, int upper) -{ - m_isSetSliderValue = false; - if(lower <= upper) - { - ui->scaleSlider->setLowerValue(lower); - ui->scaleSlider->setUpperValue(upper); - } -} - -void CPlotWidget::addCollect() -{ - QPoint pt = ui->collectCurve->mapToGlobal(QPoint()); - int x = pt.x() + ui->collectCurve->width(); - int y = pt.y() + ui->collectCurve->height(); - emit sigAddCollect(x, y); -} - -void CPlotWidget::slotPrint() -{ - QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/%1.jpg").arg(ui->title->text()), tr("(*.jpg)"), - Q_NULLPTR, QFileDialog::DontUseNativeDialog); - - if(strFileName.isEmpty()) - { - return; - } - ui->plot->legend->setVisible(true); - m_trendTitle->setVisible(true); - ui->plot->replot(QCustomPlot::rpImmediateRefresh); - bool ret = ui->plot->saveJpg(strFileName, 1600, 800); - ui->plot->legend->setVisible(false); - m_trendTitle->setVisible(false); - ui->plot->replot(QCustomPlot::rpImmediateRefresh); - if(ret) - { - QMessageBox::information(this,tr("提示"),tr("保存成功"),QMessageBox::Ok); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败"),QMessageBox::Ok); - } -} - -void CPlotWidget::slotExport() -{ - QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/%1.xlsx").arg(ui->title->text()), tr("(*.xlsx)"), - Q_NULLPTR, QFileDialog::DontUseNativeDialog); - if(strFileName.isEmpty()) - return; - - QXlsx::Document xlsx; - - for(int col = 0; col < m_pTableDataModel->columnCount(); col++) - { - xlsx.write(hexTo26(col)+"1", m_pTableDataModel->headerData(col, Qt::Horizontal, Qt::ToolTipRole)); - xlsx.setColumnWidth(col+1, 35); - } - - QXlsx::Format format; - QColor lastColor, curColor; - for(int row = 0; row < m_pTableDataModel->rowCount(); row++) - { - for(int col = 0; col < m_pTableDataModel->columnCount(); col++) - { - QModelIndex index = m_pTableDataModel->index(row, col); - curColor = QColor(m_pTableDataModel->data(index, Qt::UserRole).toInt() * 4288716964); - if(lastColor != curColor) - { - format.setFontColor(curColor); - lastColor = curColor; - } - xlsx.write(hexTo26(col)+QString::number(row+2), m_pTableDataModel->data(index), format); - } - } - //m_pTrendGraph - int curRow = xlsx.dimension().lastRow(); - xlsx.write(hexTo26(0)+QString::number(curRow+1) , "最大值" ,format); - xlsx.write(hexTo26(0)+QString::number(curRow+2) , "最大值时间" ,format); - xlsx.write(hexTo26(0)+QString::number(curRow+3) , "最小值" ,format); - xlsx.write(hexTo26(0)+QString::number(curRow+4) , "最小值时间" ,format); - xlsx.write(hexTo26(0)+QString::number(curRow+5) , "平均值" ,format); - for(int col = 1,r = 0; col <= m_pTableDataModel->rowCount(); col++,r++) - { - xlsx.write(hexTo26(col)+QString::number(curRow+1) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MAX) , - Qt::DisplayRole) ,format); - xlsx.write(hexTo26(col)+QString::number(curRow+2) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MAXTIME) , - Qt::DisplayRole) ,format); - - xlsx.write(hexTo26(col)+QString::number(curRow+3) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MIN) , - Qt::DisplayRole) ,format); - - xlsx.write(hexTo26(col)+QString::number(curRow+4) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MINTIME) , - Qt::DisplayRole) ,format); - xlsx.write(hexTo26(col)+QString::number(curRow+5) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::AVE) , - Qt::DisplayRole) ,format); - } - - if(xlsx.saveAs(strFileName)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+strFileName); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } -} - -void CPlotWidget::prePage() -{ - m_isSetSliderValue = true; - QDateTime dateTime = ui->date->dateTime(); - switch(m_type) - { - case E_Trend_His_Minute: - { - ui->date->setDateTime(dateTime.addSecs(-600)); - break; - } - case E_Trend_His_Hour: - case E_Trend_His_Day: - { - ui->date->setDateTime(dateTime.addDays(-1)); - break; - } - case E_Trend_His_Week: - { - ui->date->setDateTime(dateTime.addDays(-7)); - break; - } - case E_Trend_His_Month: - { - ui->date->setDateTime(dateTime.addMonths(-1)); - break; - } - case E_Trend_His_Quarter: - { - ui->date->setDateTime(dateTime.addMonths(-3)); - break; - } - case E_Trend_His_Year: - { - ui->date->setDateTime(dateTime.addYears(-1)); - break; - } - default: - return; - } - - QPair range = getFatureDataTime(m_type, ui->date->dateTime()); - ui->plot->xAxis->blockSignals(true); - ui->plot->xAxis->setRange(range.first, range.second); - ui->plot->xAxis->blockSignals(false); - updateCurves(); -} - -void CPlotWidget::nextPage() -{ - m_isSetSliderValue = true; - QDateTime dateTime = ui->date->dateTime(); - switch(m_type) - { - case E_Trend_His_Minute: - { - ui->date->setDateTime(dateTime.addSecs(600)); - break; - } - case E_Trend_His_Hour: - case E_Trend_His_Day: - { - ui->date->setDateTime(dateTime.addDays(1)); - break; - } - case E_Trend_His_Week: - { - ui->date->setDateTime(dateTime.addDays(7)); - break; - } - case E_Trend_His_Month: - { - ui->date->setDateTime(dateTime.addMonths(1)); - break; - } - case E_Trend_His_Quarter: - { - ui->date->setDateTime(dateTime.addMonths(3)); - break; - } - case E_Trend_His_Year: - { - ui->date->setDateTime(dateTime.addYears(1)); - break; - } - default: - return; - } - - QPair range = getFatureDataTime(m_type, ui->date->dateTime()); - ui->plot->xAxis->blockSignals(true); - ui->plot->xAxis->setRange(range.first, range.second); - ui->plot->xAxis->blockSignals(false); - updateCurves(); -} - -void CPlotWidget::graphVisibleChanged(const bool &check) -{ - //< 脚本调用setTagVisible导致无法自适应 -// m_isSetSliderValue = check; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - const Curve &curve = m_pTrendGraph->curve(graph->name()); - graph->setVisible(curve.visible); - if(!curve.visible || curve.tag == "curve.tag") - { - graph->removeFromLegend(ui->plot->legend); - m_pTableDataModel->setColumnHidden(graph->desc(), true); - } - else - { - graph->addToLegend(ui->plot->legend); - m_pTableDataModel->setColumnHidden(graph->desc(), false); - } - } - ui->plot->clearItems(); - m_listTracer.clear(); - removeCurvesGroupQuery(); - rescaleYAxisRange(); - ui->plot->replot(); -} - -void CPlotWidget::graphPropertyChanged() -{ - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - const Curve &curve = m_pTrendGraph->curve(graph->name()); - graph->setPen(curve.color); - updateCurveSelectionColor(graph); - } - ui->lengedView->setCurrentIndex(ui->lengedView->model()->index(ui->lengedView->currentIndex().row(), 0)); - updateCurves(); -} - -void CPlotWidget::deleteCurrentGraph() -{ - int index = ui->lengedView->currentIndex().row(); - if(m_pTrendGraph->curves().size() > 0 && index >= 0) - { - QCPGraph * graph = ui->plot->graph(index); - const Curve &curve = m_pTrendGraph->curve(graph->name()); - QString tag = curve.tag; - if(tag != "curve.tag") - { - removeTag(tag); - emit updateTagCheckState(tag,false); - } - } -} - -void CPlotWidget::jumpToMaxTime(const double &time) -{ - if(m_type == E_Trend_His_Minute) - { - double range = ui->plot->xAxis->range().size() / 2.0; - ui->plot->xAxis->setRange(time - range, time + range); - updateCurves(); - ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(time), 0)); - } - else - { - setDisplayTime(E_Trend_His_Minute, time, false); - } -} - -void CPlotWidget::jumpToMinTime(const double &time) -{ - if(m_type == E_Trend_His_Minute) - { - double range = ui->plot->xAxis->range().size() / 2.0; - ui->plot->xAxis->setRange(time - range, time + range); - updateCurves(); - ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(time), 0)); - } - else - { - setDisplayTime(E_Trend_His_Minute, time, false); - } -} - -void CPlotWidget::updateLengedValue(const double &dateTime) -{ - QList listVal; - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - QCPGraph * graph = ui->plot->graph(nIndex); - double graphValue = graph->value(dateTime); - const Curve &curve = m_pTrendGraph->curve(graph->name()); - double value = graphValue; - - if(m_bHisAdaption && m_type != E_Trend_RealTime) - { - value = (graphValue - curve.graphOffset) / curve.graphFactor; - } - listVal.append(value); - } - m_pLengedModel->setTrendCurrentValues(listVal); -} - -void CPlotWidget::graphSelectionChanged(bool select) -{ - ui->lengedView->selectionModel()->clear(); - updateYAxisTicker(); - - QCPGraph * graph = dynamic_cast(sender()); - if(Q_NULLPTR != graph && select) - { - ui->lengedView->selectRow(m_pTrendGraph->index(graph->name())); - } - ui->plot->replot(QCustomPlot::rpQueuedRefresh); -} - -void CPlotWidget::tableSelectionChanged(const QModelIndex &index) -{ - ui->lengedView->selectRow(index.column()-1); -} - -void CPlotWidget::updateGraphSelection() -{ - ui->plot->blockSignals(true); -// ui->plot->clearItems(); - ui->plot->deselectAll(); - ui->plot->blockSignals(false); - int index = ui->lengedView->currentIndex().row(); - QCPGraph * graph = ui->plot->graph(index); - if(graph) - { - if(E_Show_Table == m_showType) - { - int column = m_pTableDataModel->getHeaderIndex(graph->desc()); - if(column < 0) - { - ui->m_dataView->clearSelection(); - } - else - { - ui->m_dataView->selectColumn(column+1); - } - } - else if(E_Show_Curve == m_showType) - { - QCPDataSelection selection(QCPDataRange(0, 1)); - graph->setSelection(selection); - } - } - ui->plot->replot(); -} - -void CPlotWidget::updateYAxisTicker() -{ - QList graphs = ui->plot->selectedGraphs(); - if(graphs.isEmpty()) - { - if(m_bHisAdaption && m_type != E_Trend_RealTime) - { - QSharedPointer ticker(new QCPAxisTickerText); - for(int nIndex(0); nIndex <= 100; nIndex+= 20) - { - ticker->addTick(nIndex, " "); - } - ui->plot->yAxis->setTicker(ticker); - ui->plot->yAxis2->setTicker(ticker); - ui->plot->replot(QCustomPlot::rpQueuedRefresh); - return; - } - } - else - { - if(m_bHisAdaption && m_type != E_Trend_RealTime) - { - QSharedPointer ticker(new QCPAxisTickerText); - const Curve &curve = m_pTrendGraph->curve(graphs.first()->name()); - if(!curve.visible) - { - return; - } - QString strUnit = QString(); - if(!curve.unit.isEmpty()) - { - strUnit = QString("\n%1").arg(curve.unit); - } - double min = curve.hisPlotRange.min; - double max = curve.hisPlotRange.max; - double range = max - min; - int lower = ui->scaleSlider->lowerValue(); - int upper = ui->scaleSlider->upperValue(); - if(range != 0 && min == 0) - { - min -= range * abs(upper / (max * 5)); - max += range * abs(lower / (min * 5)); - } - else if(range != 0 && max == 0) - { - max += range * abs(lower / (min * 5)); - min -= range * abs(upper / (max * 5)); - } - if(range == 0) - { - ticker->addTick(50, QString::number(curve.hisPlotRange.max, 'f', 1) + strUnit); - ui->plot->yAxis->setTicker(ticker); - ui->plot->yAxis2->setTicker(ticker); - }else - { - QList ticks = regulate(min, max, 11); - if(!ticks.isEmpty()) - { - double range = curve.hisPlotRange.max - curve.hisPlotRange.min; - for(int nIndex(0); nIndex < ticks.size(); nIndex += 2) - { - ticker->addTick((ticks.at(nIndex) - curve.hisPlotRange.min) / range * 100, QString::number((ticks.at(nIndex)), 'f', 1) + strUnit); - } - ui->plot->yAxis->setTicker(ticker); - ui->plot->yAxis2->setTicker(ticker); - } - } - ui->plot->replot(QCustomPlot::rpQueuedRefresh); - return; - } - } - ui->plot->yAxis->setTicker(m_ptrPlotTricker); - ui->plot->yAxis2->setTicker(m_ptrPlotTricker); - ui->plot->replot(QCustomPlot::rpQueuedRefresh); -} - -void CPlotWidget::installMousePressEventFilter() -{ - ui->plot->installEventFilter(this); - - ui->realTime->installEventFilter(this); - ui->sec->installEventFilter(this); - ui->day->installEventFilter(this); - ui->week->installEventFilter(this); - ui->month->installEventFilter(this); - ui->quarter->installEventFilter(this); - ui->year->installEventFilter(this); - ui->adapt->installEventFilter(this); - ui->checkBox_alarmPoint->installEventFilter(this); - ui->comboBox_alarmStatus->installEventFilter(this); - ui->plotExport->installEventFilter(this); - ui->plotPrint->installEventFilter(this); - ui->prePage->installEventFilter(this); - ui->nextPage->installEventFilter(this); - ui->date->installEventFilter(this); - ui->clear->installEventFilter(this); - ui->scaleSlider->installEventFilter(this); - ui->switchBtn->installEventFilter(this); - ui->m_dataView->viewport()->installEventFilter(this); - ui->m_dataView->horizontalHeader()->viewport()->installEventFilter(this); - ui->lengedView->viewport()->installEventFilter(this); - ui->lengedView->horizontalHeader()->viewport()->installEventFilter(this); -} - -EnMeasPiontType CPlotWidget::getMeasType(const QString &type) -{ - if ("analog" == type) - { - return MPT_AI; //< 模拟量 - } - else if ("digital" == type) - { - return MPT_DI; //< 数字量 - } - else if ("mix" == type) - { - return MPT_MIX; //< 混合量 - } - else if ("accuml" == type) - { - return MPT_ACC; //< 累计(电度)量 - } - return MPT_AI; //< INVALID -} - -void CPlotWidget::setLegendCurveTransformColumnVisible(const bool &visible) -{ - Q_UNUSED(visible) - //单位未赋值,隐藏 - //ui->lengedView->setColumnHidden(CCurveLegendModel::UNIT, true); - - ui->lengedView->setColumnHidden(CCurveLegendModel::FACTOR, true); - ui->lengedView->setColumnHidden(CCurveLegendModel::OFFSET, true); -} - -QList CPlotWidget::regulate(double min, double max, int tickCount) -{ - QList ticks; - if (tickCount < 1 || max < min) - { - return ticks; - } - - double delta = max - min; - if (delta < 1.0) - { - max += (1.0 - delta) / 2.0; - min -= (1.0 - delta) / 2.0; - } - delta = max - min; - - int exp = (int)(log(delta) / log(10.0)) - 2; - double multiplier = pow(10, exp); - const double solutions[] = { 1, 2, 2.5, 5, 10, 20, 25, 50, 100, 200, 250, 500 }; - - int nIndex = 0; - for (; nIndex < (int)(sizeof(solutions) / sizeof(double)); ++nIndex) - { - double multiCal = multiplier * solutions[nIndex]; - if (((int)(delta / multiCal) + 1) <= tickCount) - { - break; - } - } - - double interval = multiplier * solutions[nIndex]; - - double startPoint = ((int)ceil(min / interval) - 1) * interval; - for (int axisIndex = 0; startPoint + interval*axisIndex <= max; axisIndex++) - { - ticks.append(startPoint + interval*axisIndex); - } - return ticks; -} - -void CPlotWidget::rescaleYAxisRange() -{ - QPair range = regulateYAxisRange(); - if(range.first == DBL_MAX || range.second == -DBL_MAX) - { -// ui->plot->yAxis->setRange(-1, 1); -// ui->plot->yAxis->rescale(true); - } - else - { - if(m_bHisAdaption && m_type != E_Trend_RealTime) - { - double factor = (range.second == range.first) ? 0 : 100. / (range.second - range.first); - double offset = -factor * range.first; - range.first = range.first * factor + offset - 1.0; - range.second = range.second * factor + offset + 1.0; - } - setSliderRange(range.first, range.second, m_isSetSliderValue); - ui->plot->yAxis->setRange(ui->scaleSlider->lowerValue(), ui->scaleSlider->upperValue()); - } - - if(m_bHisAdaption && m_type != E_Trend_RealTime) - { - updateYAxisTicker(); - } - else - { - ui->plot->replot(); - } - if(m_horizontalGraph) - { - updateHorizontalLine(); - } -} - -QPair CPlotWidget::regulateYAxisRange() -{ - const QList &curveList = m_pTrendGraph->curves(); - QPair range(DBL_MAX,-DBL_MAX); - for(int nIndex=0; nIndex max) - qSwap(min, max); - - double center = (max + min) / 2; - double offset1 = max - center; - double offset2 = center - min; - double offset = offset1 > offset2 ? offset1 : offset2; - int bs = 4; - if(offset < 1) - offset = 1; - - int low = center - bs * offset; - int up = center + bs * offset; - if(low == 0) - low = -2.0; - if(up == 0) - up = 2.0; - - if(low < range.first) - range.first = low; - if(up > range.second) - range.second = up; - } - return range; -} - -void CPlotWidget::setSliderRange(double lower, double upper, bool setValue) -{ - if(lower > upper) - qSwap(lower, upper); - - int range = upper - lower; - int lastUpper = ui->scaleSlider->upperValue(); - int lastLower = ui->scaleSlider->lowerValue(); - - int minimum; - int maximum; - if(lower == 0 && upper == 0) - { - minimum = -10; - maximum = 10; - } - else if(lower >= 0) - { - minimum = lower / 2 - range/5; - maximum = upper * 2 + range/5; - } - else if(upper <= 0) - { - minimum = lower * 2 - range/5; - maximum = upper / 2 + range/5; - } - else if(upper > 0 && lower < 0) - { - minimum = lower * 2 - range/5; - maximum = upper * 2 + range/5; - } - - if(setValue) - { - ui->scaleSlider->setMinimum(minimum); - ui->scaleSlider->setMaximum(maximum); - ui->scaleSlider->setLowerValue(lower - range/5); - ui->scaleSlider->setUpperValue(upper + range/5); - } - else - { - if(lastLower > minimum) - { - ui->scaleSlider->setMinimum(minimum); - } - if(lastUpper < maximum) - { - ui->scaleSlider->setMaximum(maximum); - } - } -} - -void CPlotWidget::setCurveStatisData(const QString &tag, EnComputeMethod method, bool reset, const double &value, const double &time) -{ - switch (method) { - case CM_MAX: - { - if(reset) - { - m_pTrendGraph->resetCurveStatisMax(tag); - } - else - { - m_pTrendGraph->setCurveStatisMax(tag, value, time); - } - break; - } - case CM_MIN: - { - if(reset) - { - m_pTrendGraph->resetCurveStatisMin(tag); - } - else - { - m_pTrendGraph->setCurveStatisMin(tag, value, time); - } - break; - } - default: - break; - } -} - -void CPlotWidget::setYAxisRange() -{ - int lower = ui->scaleSlider->lowerValue(); - int upper = ui->scaleSlider->upperValue(); - QCPRange range(lower, upper); - ui->plot->yAxis->setRange(range); - - if(m_bHisAdaption && m_type != E_Trend_RealTime) - { - updateYAxisTicker(); - } - else - { - ui->plot->replot(); - } - if(m_horizontalGraph) - { - updateHorizontalLine(); - } -} - -void CPlotWidget::sliderPressed() -{ - m_isSetSliderValue = false; -} - -void CPlotWidget::sliderDoubleClick(int x, int y) -{ - emit sigSliderRangeSet(x, y, - ui->scaleSlider->lowerValue(), - ui->scaleSlider->upperValue(), - ui->scaleSlider->minimum(), - ui->scaleSlider->maximum()); -} - -bool CPlotWidget::isMutation(const double &preValue, const double &curValue) -{ - if(preValue == 0) - { - return true; - } - - double coeff = qAbs(0.5 * preValue); - - if(qAbs(curValue-preValue) > coeff) - { - return true; - } - return false; -} - -template -void CPlotWidget::updateHisData(std::vector *vecMpKey, std::vector*> *vecResult, - std::vector > &vecRange, std::vector< QSharedPointer > &vecContainer, - double lower, double upper, - bool isAddVirtualPoint, int nGroupBySec) -{ - int nMaxIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000 + nGroupBySec * 1000; - typename std::vector *>::const_iterator it = vecResult->begin(); - while(it != vecResult->end()) - { - QSharedPointer range(new Range()); - QSharedPointer container(new QCPGraphDataContainer()); - vecRange.push_back(range); - vecContainer.push_back(container); - - //< Valid Check - std::vector<_Tp> * vecPoint = *it; - if(vecPoint->empty()) - { - ++it; - continue; - } - - //< Graph Bound - _Tp left; - left.m_nTime = lower; - typename std::vector<_Tp>::const_iterator varHisLeft = std::upper_bound((*vecPoint).begin(), (*vecPoint).end(), left, compareVarPoint<_Tp>); - if(varHisLeft != (*vecPoint).begin() && varHisLeft != (*vecPoint).end()) - { - --varHisLeft; - } - - _Tp right; - right.m_nTime = upper; - typename std::vector<_Tp>::const_iterator varHisRight = std::lower_bound((*vecPoint).begin(), (*vecPoint).end(), right, compareVarPoint<_Tp>); - if(varHisRight == (*vecPoint).end()) - { - varHisRight = (*vecPoint).end() - 1; - } - ++varHisRight; - - //< Prepare Work(used: record Interval) - E_Point_Type pointType; - switch (vecMpKey->at(it - vecResult->begin()).m_enType) - { - case MPT_AI:{ - pointType = E_ANALOG; - break; - } - case MPT_DI:{ - pointType = E_DIGITAL; - break; - } - case MPT_MIX:{ - pointType = E_MIX; - break; - } - case MPT_ACC:{ - pointType = E_ACCUML; - break; - } - default: - break; - } - qint64 lastTimeStamp = -1; - double lastValue = qSqrt(-1.); - int lastStatus = 0; - - //< Handle Data - typename std::vector<_Tp>::const_iterator pt = varHisLeft; - while(pt != varHisRight) - { - double value = qSqrt(-1.); - if (typeid(boost::int32_t) == pt->m_varValue.type()) - { - value = (double)boost::get(pt->m_varValue); - } - else if (typeid(boost::float64_t) == pt->m_varValue.type()) - { - value = (double)boost::get(pt->m_varValue); - } - - if(std::isnan(value)) - { - ++pt; - continue; - } - - if(value > range->max) - { - range->max = value; - } - if(value < range->min) - { - range->min = value; - } - - qint64 timeStamp = pt->m_nTime; - int status = CTrendInfoManage::instance()->getInvalidStatus(pointType, pt->m_nStatus); - if(lastTimeStamp > 0 && lastTimeStamp + nMaxIntervalSecs < timeStamp) - { - container->add(QCPGraphData(lastTimeStamp+nGroupBySec*1000, qSqrt(-1.), lastStatus)); - } - else if(lastTimeStamp > 0 && isMutation(lastValue, value) && isAddVirtualPoint) - { - container->add(QCPGraphData(timeStamp, lastValue, lastStatus)); - } - container->add(QCPGraphData(timeStamp, value, status)); - lastTimeStamp = timeStamp; - lastValue = value; - lastStatus = status; - ++pt; - } - ++it; - } -} - -template -bool CPlotWidget::checkStatus(const _Tp &var, const int &nInvalid) -{ - Q_UNUSED(var); - Q_UNUSED(nInvalid); - return true; -} - -template -bool CPlotWidget::checkStatus(const SVarHisSamplePoint &var, const int &nInvalid) -{ - return nInvalid == (var.m_nStatus & nInvalid); -} - -void CPlotWidget::slotDateTimeChanged(const QDateTime &dateTime) -{ - m_isSetSliderValue = true; - QPair range = getFatureDataTime(m_type, dateTime); - ui->plot->xAxis->blockSignals(true); - ui->plot->xAxis->setRange(range.first, range.second); - ui->plot->xAxis->blockSignals(false); - - updateCurves(); -} - -void CPlotWidget::updateGroupQuery(const QString &tag) -{ - if(tag == "curve.tag") - return; - - QMap::iterator iter = m_groupTagMap.begin(); - while(iter != m_groupTagMap.end()) - { - if(iter.value().contains(tag)) - return; - iter++; - } - QString device = tag.section(".", 0, 1); - QString deviceGroup = CTrendInfoManage::instance()->queryDeviceGroup(device); - if(deviceGroup.isEmpty()) - { - ui->plot->replot(QCustomPlot::rpQueuedReplot); - return; - } - QStringList tagList = CTrendInfoManage::instance()->queryTagListDevGroup(deviceGroup); - if(!m_groupTagMap.keys().contains(deviceGroup)) - { - m_groupTagMap.insert(deviceGroup,tagList); - groupQueryHistoryEvent(); - } -} - -void CPlotWidget::removeCurvesGroupQuery() -{ - m_groupTagMap.clear(); - for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) - { - if(ui->plot->graph(nIndex)->visible() == true) - { - updateGroupQuery(ui->plot->graph(nIndex)->name()); - } - } -} - -void CPlotWidget::groupQueryHistoryEvent() -{ - if(m_type == E_Trend_RealTime || m_groupTagMap.isEmpty() || NULL == m_horizontalGraph) - { - ui->plot->clearItems(); - m_listTracer.clear(); - return; - } - - std::vector * vecMpKey = new std::vector(); - QMap::iterator iter = m_groupTagMap.begin(); - while(iter != m_groupTagMap.end()) - { - foreach (QString tagName, iter.value()) { - SMeasPointKey key; - std::string tmp = tagName.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(CTrendInfoManage::instance()->getTagType(tagName)); - vecMpKey->push_back(key); - } - iter++; - } - - int ByMinute = currentGroupByMinute(); - int g_groupByDuration = ByMinute * 60; - - if(!m_pHisDataManage->isTsdbExuting()) - { - if(g_groupByDuration == 0) - { - emit sigQueryHistoryEvent(vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, kbd_dbms::CM_NULL, g_groupByDuration); - } - else - { - emit sigQueryHistoryEvent(vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, kbd_dbms::CM_SAMPLE, g_groupByDuration); - } - } - else - { - if(g_groupByDuration == 0) - { - m_pHisDataManage->postTsdbCommandQueue(E_EVENTPOINT, vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, g_groupByDuration, - std::vector{kbd_dbms::CM_NULL}); - } - else - { - m_pHisDataManage->postTsdbCommandQueue(E_EVENTPOINT, vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, g_groupByDuration, - std::vector{kbd_dbms::CM_SAMPLE}); - } - } - - ui->plot->replot(); -} - -void CPlotWidget::initAlarmStatusFilter() -{ - m_pListWidget = new CMyListWidget(this); - m_pLineEdit = new QLineEdit(this); - QMap > m_alarmShowStatus = CTrendInfoManage::instance()->getAlarmShowStatus(); - m_strText = ""; - for(QMap >::const_iterator it = m_alarmShowStatus.constBegin();it != m_alarmShowStatus.constEnd();++it) - { - QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget); - pItem->setData(Qt::UserRole, it.key()); - CMyCheckBox *pCheckBox = new CMyCheckBox(this); - pCheckBox->setText(it.value().first); - m_pListWidget->addItem(pItem); - m_pListWidget->setItemWidget(pItem, pCheckBox); - if(it.value().second) - { - pCheckBox->setCheckState(Qt::Checked); - m_alarmStatusList.append(it.key()); - m_strText += pCheckBox->text(); - m_strText += " "; - } - connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(alarmStatusChanged(int))); - } - ui->comboBox_alarmStatus->setModel(m_pListWidget->model()); - ui->comboBox_alarmStatus->setView(m_pListWidget); - ui->comboBox_alarmStatus->setLineEdit(m_pLineEdit); - if(m_strText == "") - { - m_strText = tr("请选择告警状态"); - } - m_pLineEdit->setText(m_strText); - m_pLineEdit->setReadOnly(true); - connect(m_pLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(alarmTextChanged(const QString &))); -} - -void CPlotWidget::addHorizontalLine() -{ - if(m_horizontalGraph) - { - m_horizontalGraph = NULL; - m_pTrendGraph->removeCurve("curve.tag"); - } - QRect rect = ui->plot->axisRect()->rect(); - double lower = ui->plot->yAxis->pixelToCoord(rect.y() + rect.height() - 6); - double first = ui->plot->xAxis->range().lower; - double final = ui->plot->xAxis->range().upper; - QVector xLineVector,yLineVector; - QVector statusVector; - xLineVector.append(first); - xLineVector.append(final); - yLineVector.append(lower); - yLineVector.append(lower); - statusVector.append(1); - statusVector.append(1); - m_horizontalGraph = ui->plot->addGraph(); - m_horizontalGraph->setData(xLineVector,yLineVector,statusVector); - - m_horizontalGraph->setName("curve.tag"); - m_horizontalGraph->removeFromLegend(); - horizontalCurve.tag = "curve.tag"; - horizontalCurve.visible = false; - m_pTrendGraph->addCurve(horizontalCurve); - m_horizontalGraph->setVisible(false); - - groupQueryHistoryEvent(); - ui->plot->replot(); -} - -void CPlotWidget::updateHorizontalLine() -{ - if(m_type == E_Trend_RealTime) - { - return; - } - QRect rect = ui->plot->axisRect()->rect(); - double lower = ui->plot->yAxis->pixelToCoord(rect.y() + rect.height() - 6); - double first = ui->plot->xAxis->range().lower; - double final = ui->plot->xAxis->range().upper; - QVector xLineVector,yLineVector; - QVector statusVector; - xLineVector.append(first); - xLineVector.append(final); - yLineVector.append(lower); - yLineVector.append(lower); - statusVector.append(1); - statusVector.append(1); - m_horizontalGraph->setData(xLineVector,yLineVector,statusVector); - m_horizontalGraph->setVisible(false); - groupQueryHistoryEvent(); - m_horizontalGraph->removeFromLegend(ui->plot->legend); - ui->plot->replot(); -} - -void CPlotWidget::setAllLengedShow() -{ - int count = ui->lengedView->model()->rowCount(); - for(int nIndex=0; nIndexlengedView->setRowHidden(nIndex, false); - } -} - -QString CPlotWidget::hexTo26(int number) -{ - int p = 26; //进制 - int c = 0; //取余后的数字 - QString temp; - - while (true) { - c = number % p; - number = number / p; - if(number != 0) - { - temp.prepend(QString(QChar(0x41 + c))); - } - else - { - temp.prepend(QString(QChar(0x41 + c))); - break; - } - number--; - } - - return temp; -} - -void CPlotWidget::resetCurveData(const QMap > &dataMap, const QStringList &headerList, bool ascs) -{ - if(E_Show_Table != m_showType) - { - return; - } - int limit = 0; - if(E_Trend_His_Custom == m_type) - { - limit = CUSTOM_MAX_RECORD; - } - m_pTableDataModel->setCurveData(dataMap, headerList, ascs, limit); -} - -void CPlotWidget::enableSearch(bool enable) -{ - if(enable) - { - ui->customSearch->setEnabled(true); - ui->customSearch->setText(tr("查询")); - } - else - { - ui->customSearch->setEnabled(false); - ui->customSearch->setText(tr("查询中")); - } -} - -void CPlotWidget::alarmTextChanged(const QString &text) -{ - Q_UNUSED(text) - m_pLineEdit->setText(m_strText); -} - -void CPlotWidget::alarmStatusChanged(int state) -{ - Q_UNUSED(state) - QString strText(""); - m_alarmStatusList.clear(); - int nCount = m_pListWidget->count(); - for (int i = 0; i < nCount; ++i) - { - QListWidgetItem *pItem = m_pListWidget->item(i); - QWidget *pWidget = m_pListWidget->itemWidget(pItem); - CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; - if (pCheckBox->isChecked()) - { - if(pCheckBox->text() == QObject::tr("其他")) - { - QMap m_alarmOtherStatus = CTrendInfoManage::instance()->getAlarmOtherStatus(); - for(QMap::iterator it = m_alarmOtherStatus.begin();it != m_alarmOtherStatus.end();++it) - { - int nData = it.key(); - m_alarmStatusList.append(nData); - } - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - } - else - { - int nData = pItem->data(Qt::UserRole).toInt(); - QString strtext = pCheckBox->text(); - strText.append(strtext).append(" "); - m_alarmStatusList.append(nData); - } - } - } - if (!strText.isEmpty()) - { - m_strText = strText; - m_pLineEdit->setText(strText); - } - else - { - m_pLineEdit->clear(); - m_strText = tr("请选择告警状态"); - m_pLineEdit->setText(tr("请选择告警状态")); - } - groupQueryHistoryEvent(); -} - -void CPlotWidget::alarmPointCheckStateChanged() -{ - setAllLengedShow(); - if(ui->checkBox_alarmPoint->isChecked()) - { - addHorizontalLine(); - m_pLengedModel->setTrendGraph(m_pTrendGraph); - int mIndex = m_pTrendGraph->index("curve.tag"); - if(mIndex != -1) - { - ui->lengedView->setRowHidden(mIndex,true); - } - }else - { - if(m_horizontalGraph) - { - m_pTrendGraph->removeCurve("curve.tag"); - ui->plot->clearItems(); - m_listTracer.clear(); - ui->plot->removeGraph(m_horizontalGraph); - m_horizontalGraph = NULL; - m_pLengedModel->setTrendGraph(m_pTrendGraph); - ui->plot->replot(); - } - } -} - -void CPlotWidget::showTypeChanged(bool checked) -{ - m_pTableDataModel->clear(); - if(checked) - { - m_showType = E_Show_Table; - - } - else - { - m_showType = E_Show_Curve; - } - ui->plot->setVisible(!checked); - ui->widget->setVisible(!checked); - ui->m_dataView->setVisible(checked); - ui->plotExport->setVisible(checked); - ui->plotPrint->setVisible(!checked); - ui->customSearch->setVisible(checked); - - if(m_type == E_Trend_RealTime) - { - ui->adapt->setVisible(false); - ui->checkBox_alarmPoint->setVisible(false); - ui->comboBox_alarmStatus->setVisible(false); - /*if(E_Show_Table == m_showType) - { - updateRealTimeTableData(); - }*/ - } - else - { - if(m_isAdaptShow) - { - ui->adapt->setVisible(!checked); - } - if(m_isAlarmShow) - { - ui->checkBox_alarmPoint->setVisible(!checked); - ui->comboBox_alarmStatus->setVisible(!checked); - } - } - - - updateRealTimeTableData(); - - updateCurves(); - - -} - -void CPlotWidget::slotStartDateChanged(const QDateTime &dateTime) -{ - if(ui->endData->dateTime() > dateTime) - { - ui->plot->xAxis->setRangeLower(dateTime.toMSecsSinceEpoch()); - } - else - { - int sec = ui->interval->currentData().toInt(); - if(sec < 600) - { - sec = 600; - } - ui->startData->setDateTime(ui->endData->dateTime().addSecs(-sec)); - } - - if(E_Show_Curve == m_showType) - { - slotCustomSearch(); - } -} - -void CPlotWidget::slotEndDateChanged(const QDateTime &dateTime) -{ - if(ui->startData->dateTime() < dateTime) - { - ui->plot->xAxis->setRangeUpper(dateTime.toMSecsSinceEpoch()); - } - else - { - int sec = ui->interval->currentData().toInt(); - if(sec < 600) - { - sec = 600; - } - ui->endData->setDateTime(ui->startData->dateTime().addSecs(sec)); - } - - if(E_Show_Curve == m_showType) - { - slotCustomSearch(); - } -} - -void CPlotWidget::slotIntervalChanged(const QString &text) -{ - Q_UNUSED(text) - - if(E_Show_Curve == m_showType) - { - slotCustomSearch(); - } -} - -void CPlotWidget::slotCustomSearch(bool isForce) -{ - if(!ui->plot->graphCount()) - { - return; - } - if(!isForce && !ui->customSearch->isEnabled()) - { - return; - } - - double lower = ui->startData->dateTime().toMSecsSinceEpoch(); - double upper = ui->endData->dateTime().toMSecsSinceEpoch(); - if(lower > upper) - { - QMessageBox::information(this,tr("提示"),tr("查询开始时间不能大于结束时间!"),QMessageBox::Ok); - return; - } - int sec = ui->interval->currentData().toInt(); - if((upper - lower) < sec*1000) - { - QMessageBox::information(this,tr("提示"),tr("开始时间和结束时间之差不能小于查询时间间隔!"),QMessageBox::Ok); - return; - } - - enableSearch(false); - std::vector vecMethod{kbd_dbms::CM_MAX, kbd_dbms::CM_MIN}; - updateComputeValue(lower, upper, vecMethod); - std::vector * vecMpKey = new std::vector(); - for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) - { - const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); - SMeasPointKey key; - std::string tmp = curve.tag.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(curve.type); - vecMpKey->push_back(key); - } - - double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; -// if(!m_pHisDataManage->isTsdbExuting()) -// { -// emit sigQueryHistoryPolymericData(vecMpKey, lower + nIntervalSecs, upper - nIntervalSecs, sec, kbd_dbms::CM_FIRST); -// } -// else - { - //< 添加多条曲线时,可能存在顺序混乱,导致显示列缺失,因此都使用post的方式查询 - m_pHisDataManage->postTsdbCommandQueue(E_POLYMERIC, vecMpKey, lower + nIntervalSecs, upper - nIntervalSecs, sec, std::vector{kbd_dbms::CM_FIRST}); - } -} - -void CPlotWidget::slotEnableSearch(bool enable) -{ - enableSearch(!enable); -} +#include "CPlotWidget.h" +#include "ui_CPlotWidget.h" +#include "CCurveLegendModel.h" +#include "CTableDataModel.h" +#include "CHisEventManage.h" +#include "CRealTimeDataCollect.h" +#include "sample_server_api/SampleDefine.h" +#include "pub_logger_api/logger.h" +#include "./widgets/CEditCollectWidget.h" +#include "./widgets/CSWitchButton.h" +#include "./widgets/CToolTip.h" +#include "CMyCheckBox.h" +#include "CMyListWidget.h" +#include "model_excel/xlsx/xlsxdocument.h" + +using namespace kbd_dbms; + +CPlotWidget::CPlotWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::CPlotWidget), + m_type(E_Trend_Invalid), + m_showType(E_Show_Curve), + m_bHisAdaption(false), + m_TrendTypeButton(Q_NULLPTR), + m_pLengedModel(Q_NULLPTR), + m_pTableDataModel(Q_NULLPTR), + m_pTimer(Q_NULLPTR), + m_pTrendGraph(Q_NULLPTR), + m_trendTitle(Q_NULLPTR), + m_pDpcdaForApp(Q_NULLPTR), + m_rtDataCollect(Q_NULLPTR), + m_pHisDataThread(Q_NULLPTR), + m_pHisDataManage(Q_NULLPTR), + m_pHisEventThread(Q_NULLPTR), + m_pHisEventManage(Q_NULLPTR), + m_horizontalGraph(Q_NULLPTR), + m_numWarnFlag(true), + m_isWindowMode(true), + m_isSetSliderValue(false), + m_isTooltip(true), + m_isAdaptShow(true), + m_isAlarmShow(true) +{ + ui->setupUi(this); + setContentsMargins(1, 1, 1, 1); + qRegisterMetaType< E_Point_Type >("E_Point_Type"); + qRegisterMetaType< E_Data_Type >("E_Data_Type"); + qRegisterMetaType< kbd_dbms::EnComputeMethod >("kbd_dbms::EnComputeMethod"); + qRegisterMetaType< std::vector >("std::vector"); + qRegisterMetaType< std::vector >("std::vector"); + qRegisterMetaType< std::vector *> >("std::vector *>"); + qRegisterMetaType< std::vector *> *> > >( + "std::vector *> *> >"); +} + +CPlotWidget::~CPlotWidget() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = Q_NULLPTR; + + if(m_pHisEventManage) + { + emit releaseHisEventThread(); + m_pHisEventManage = Q_NULLPTR; + } + + if(m_pHisEventThread) + { + m_pHisEventThread->quit(); + m_pHisEventThread->wait(); + } + m_pHisEventThread = Q_NULLPTR; + + if(m_pHisDataManage) + { + emit releaseHisDataThread(); + m_pHisDataManage = Q_NULLPTR; + } + if(m_pHisDataThread) + { + m_pHisDataThread->quit(); + m_pHisDataThread->wait(); + } + m_pHisDataThread = Q_NULLPTR; + + if(m_pTrendGraph) + { + delete m_pTrendGraph; + } + m_pTrendGraph = Q_NULLPTR; + + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = Q_NULLPTR; + + if(m_rtDataCollect->isRunning()) + { + m_rtDataCollect->disconnect(this); + m_rtDataCollect->requestInterruption(); + m_rtDataCollect->wait(); + } + m_rtDataCollect = Q_NULLPTR; + delete ui; +} + +/************************************************************************ + * + * 1、初始化界面 + * 2、初始化实时数据采集 + * + ************************************************************************/ +void CPlotWidget::initialize() +{ + m_pTrendGraph = new CTrendGraph(); + m_rtRange = 10 * 60 * 1000; //< second + + //< GroupButton + m_TrendTypeButton = new QButtonGroup(this); + m_TrendTypeButton->addButton(ui->realTime, E_Trend_RealTime); + m_TrendTypeButton->addButton(ui->sec, E_Trend_His_Minute); + m_TrendTypeButton->addButton(ui->day, E_Trend_His_Day); + m_TrendTypeButton->addButton(ui->week, E_Trend_His_Week); + m_TrendTypeButton->addButton(ui->month, E_Trend_His_Month); + m_TrendTypeButton->addButton(ui->quarter, E_Trend_His_Quarter); + m_TrendTypeButton->addButton(ui->year, E_Trend_His_Year); + m_TrendTypeButton->addButton(ui->custom, E_Trend_His_Custom); + connect(m_TrendTypeButton, SIGNAL(buttonClicked(int)), this, SLOT(updateTrendShowMode(int))); + + connect(ui->prePage, &QPushButton::clicked, this, &CPlotWidget::prePage); + connect(ui->nextPage, &QPushButton::clicked, this, &CPlotWidget::nextPage); + connect(ui->date, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotDateTimeChanged); + ui->date->setCalendarPopup(true); + ui->date->setButtonSymbols(QAbstractSpinBox::NoButtons); + ui->date->setDateTime(QDateTime::currentDateTime()); + + ui->customWidget->setVisible(false); + ui->customSearch->setVisible(false); + ui->startData->setCalendarPopup(true); + ui->endData->setCalendarPopup(true); + ui->startData->setButtonSymbols(QAbstractSpinBox::NoButtons); + ui->endData->setButtonSymbols(QAbstractSpinBox::NoButtons); + ui->startData->setMinimumWidth(150); + ui->endData->setMinimumWidth(150); + QDateTime curDateTime = QDateTime::currentDateTime(); + curDateTime.setTime(QTime(curDateTime.time().hour(), + curDateTime.time().minute(),0,0)); + ui->endData->setDateTime(curDateTime); + QDateTime preDateTime = curDateTime.addSecs(-600); + ui->startData->setDateTime(preDateTime); + ui->interval->setView(new QListView()); + ui->interval->addItem(tr("一秒钟"), 1); + ui->interval->addItem(tr("一分钟"), 1*60); + ui->interval->addItem(tr("十分钟"), 10*60); + ui->interval->addItem(tr("一小时"), 60*60); + ui->interval->addItem(tr("八小时"), 8*60*60); + ui->interval->addItem(tr("一天"), 24*60*60); + connect(ui->interval, &QComboBox::currentTextChanged, this, &CPlotWidget::slotIntervalChanged); + connect(ui->customSearch, &QPushButton::clicked, this, &CPlotWidget::slotCustomSearch); + connect(ui->startData, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotStartDateChanged); + connect(ui->endData, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotEndDateChanged); + + //< initPlot + ui->plot->setEnabled(true); + ui->plot->setSymbolPos(QPoint(width() / 2, 0)); + ui->plot->setNoAntialiasingOnDrag(true); + ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //<水平拖拽 + ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //<水平缩放 + ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); + QSharedPointer ticker(new QCPAxisTickerDateTime()); + ui->plot->xAxis->setTicker(ticker); + ui->plot->yAxis->setRange(-1, 1); + ui->plot->yAxis->scaleRange(1.02); + ui->plot->yAxis2->setVisible(true); + ui->plot->xAxis->setScaleType(QCPAxis::stLinear); + ui->plot->xAxis->rescale(true); + m_ptrPlotTricker = ui->plot->yAxis->ticker(); + + connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->yAxis2, SLOT(setRange(QCPRange))); + connect(ui->plot->xAxis, SIGNAL(rangeChanged(const QCPRange &,const QCPRange &)), this, SLOT(plotAxisRangeChanged(const QCPRange &,const QCPRange &))); + connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeDraged, this, &CPlotWidget::updateCurves); + connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeScaled, this, &CPlotWidget::updateCurves); + connect(ui->plot, &QCustomPlot::symbolPosChanged, this, &CPlotWidget::updateLengedValue); + + //< initTitle + m_trendTitle = new QCPItemText(ui->plot); + m_trendTitle->setObjectName("m_trendTitle"); + m_trendTitle->setPositionAlignment(Qt::AlignCenter); + m_trendTitle->position->setType(QCPItemPosition::ptAxisRectRatio); + m_trendTitle->position->setCoords(0.03, 0.01); + m_trendTitle->setColor(QColor(255,255,255)); + m_trendTitle->setFont(QFont("Microsoft YaHei", 10)); + m_trendTitle->setText("实时趋势"); + m_trendTitle->setVisible(false); + + m_pTableDataModel = new CTableDataModel(ui->m_dataView); + ui->m_dataView->setModel(m_pTableDataModel); + ui->m_dataView->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->m_dataView->verticalHeader()->setVisible(false); + ui->m_dataView->setAlternatingRowColors(true); + ui->m_dataView->horizontalHeader()->setObjectName("m_dataView"); + ui->m_dataView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + ui->m_dataView->setSelectionBehavior(QAbstractItemView::SelectRows); +// ui->m_dataView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); +// ui->m_dataView->horizontalHeader()->setMinimumSectionSize(200); + ui->m_dataView->horizontalHeader()->setDefaultSectionSize(200); + connect(ui->m_dataView, SIGNAL(clicked(QModelIndex)), this, SLOT(tableSelectionChanged(QModelIndex))); + + //< initTableView + m_pLengedModel = new CCurveLegendModel(ui->lengedView); + ui->lengedView->setModel(m_pLengedModel); + ui->lengedView->setItemDelegate(new CCurveLegnedDelegate(ui->lengedView)); + ui->lengedView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked); + ui->lengedView->verticalHeader()->setVisible(false); + ui->lengedView->setAlternatingRowColors(true); + ui->lengedView->horizontalHeader()->setStretchLastSection(true); + ui->lengedView->horizontalHeader()->setObjectName("m_legendHeader"); + ui->lengedView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->lengedView->setSelectionMode(QAbstractItemView::SingleSelection); + ui->lengedView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->lengedView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + + connect(m_pLengedModel, &CCurveLegendModel::graphVisibleChanged, this, &CPlotWidget::graphVisibleChanged); + connect(m_pLengedModel, &CCurveLegendModel::graphPropertyChanged, this, &CPlotWidget::graphPropertyChanged); + connect(m_pLengedModel, &CCurveLegendModel::deleteCurrentGraph, this, &CPlotWidget::deleteCurrentGraph); + connect(m_pLengedModel, &CCurveLegendModel::sigJumpToMaxTime, this, &CPlotWidget::jumpToMaxTime); + connect(m_pLengedModel, &CCurveLegendModel::sigJumpToMinTime, this, &CPlotWidget::jumpToMinTime); + connect(ui->lengedView, &QTableView::clicked, this, &CPlotWidget::updateGraphSelection); + + ui->plotExport->setVisible(false); + ui->clear->setEnabled(false); + ui->collectCurve->setVisible(false); + ui->switchBtn->setToggle(false); + ui->switchBtn->setText(tr("曲线")); + ui->switchBtn->setCheckedText(tr("表格")); + ui->m_dataView->setVisible(false); + connect(ui->adapt, &QCheckBox::toggled, this, &CPlotWidget::updateAdaptState); + connect(ui->collectCurve, &QPushButton::clicked, this, &CPlotWidget::addCollect); + connect(ui->plotPrint, &QPushButton::clicked, this, &CPlotWidget::slotPrint); + connect(ui->plotExport, &QPushButton::clicked, this, &CPlotWidget::slotExport); + connect(ui->clear, &QPushButton::clicked, this, &CPlotWidget::clear); + connect(ui->switchBtn, &CSWitchButton::toggled, this, &CPlotWidget::showTypeChanged); + if(Q_NULLPTR == m_pTimer) + { + m_pTimer = new QTimer(this); + m_pTimer->setInterval(1000); + connect(m_pTimer, &QTimer::timeout, this, &CPlotWidget::realTimeElapsed); + } + + m_pDpcdaForApp = new kbd_service::CDpcdaForApp(); + m_rtDataCollect = new CRealTimeDataCollect(this); + connect(m_rtDataCollect, &CRealTimeDataCollect::finished, m_rtDataCollect, &CRealTimeDataCollect::deleteLater); + connect(m_rtDataCollect, &CRealTimeDataCollect::realTimeTrendDataArrived, this, &CPlotWidget::recvRealTimeTrendData, Qt::QueuedConnection); + m_rtDataCollect->start(); + + m_pHisDataManage = new CHisDataManage(); + m_pHisDataThread = new QThread(this); + m_pHisDataManage->moveToThread(m_pHisDataThread); + connect(m_pHisDataThread, &QThread::finished, m_pHisDataThread, &QObject::deleteLater); + connect(this, &CPlotWidget::releaseHisDataThread, m_pHisDataManage, &CHisDataManage::release, Qt::BlockingQueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryOriginalData, m_pHisDataManage, &CHisDataManage::queryHistoryOriginalData, Qt::QueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryPolymericData, m_pHisDataManage, &CHisDataManage::queryHistoryPolymericData, Qt::QueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryComputeData, m_pHisDataManage, &CHisDataManage::queryHistoryComputeData, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigupdateHisOriginalData, this, &CPlotWidget::updateHisOriginalData, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHistoryPolymericData, this, &CPlotWidget::updateHisPolymericData, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHistoryComputeData, this, &CPlotWidget::updateHisComputeData, Qt::QueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryEvent, m_pHisDataManage, &CHisDataManage::queryHistoryEvents, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHistoryEvent, this, &CPlotWidget::updatePhaseTracer, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHisSearch, this, &CPlotWidget::slotEnableSearch, Qt::QueuedConnection); + m_pHisDataThread->start(); + + m_pHisEventManage = new CHisEventManage(); + m_pHisEventThread = new QThread(this); + m_pHisEventManage->moveToThread(m_pHisEventThread); + connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); + connect(this, &CPlotWidget::releaseHisEventThread, m_pHisEventManage, &CHisEventManage::release, Qt::BlockingQueuedConnection); + connect(m_pHisEventManage, &CHisEventManage::updateHisEvent, this, &CPlotWidget::updateGraphEvent ,Qt::QueuedConnection); + m_pHisEventThread->start(); + + ui->scaleSlider->setMouseTracking(true); + ui->scaleSlider->setHandleMovementMode(QxtSpanSlider::NoCrossing); + ui->scaleSlider->setMinimum(-100000); + ui->scaleSlider->setMaximum(100000); + ui->scaleSlider->setLowerValue(0); + ui->scaleSlider->setUpperValue(0); + connect(ui->scaleSlider, &QxtSpanSlider::lowerValueChanged, this, &CPlotWidget::setYAxisRange); + connect(ui->scaleSlider, &QxtSpanSlider::upperValueChanged, this, &CPlotWidget::setYAxisRange); + connect(ui->scaleSlider, &QxtSpanSlider::sliderPressed, this, &CPlotWidget::sliderPressed); + connect(ui->scaleSlider, &QxtSpanSlider::sliderDoubleClick, this, &CPlotWidget::sliderDoubleClick); + + initAlarmStatusFilter(); + connect(ui->checkBox_alarmPoint, &QCheckBox::clicked, this, &CPlotWidget::alarmPointCheckStateChanged); + + installMousePressEventFilter(); + + QMetaObject::invokeMethod(ui->realTime, "click"); +} + +void CPlotWidget::resizeEvent(QResizeEvent *event) +{ + QSize size = parentWidget()->size(); + int offset = 2; + if(m_isWindowMode) + offset = 15; + if(ui->titleFrame->isVisible()) + { + size.setHeight(size.height() - (ui->titleFrame->height() + ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + offset)); + } + else + { + size.setHeight(size.height() - (ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + offset)); + } + size.setWidth(ui->lengedView->width() - 20); + ui->plot->resize(size); + ui->plot->replot(); + + updateLengedColumnWidth(); + QWidget::resizeEvent(event); +} + +bool CPlotWidget::eventFilter(QObject *object, QEvent *event) +{ + if (QEvent::MouseButtonPress == event->type()) + { + emit sigHideCollect(); + emit sigHideSliderSet(); + if(object == ui->scaleSlider) + { + m_isTooltip = false; + QToolTip::hideText(); + } + } + else if(QEvent::MouseButtonRelease == event->type()) + { + if(object == ui->scaleSlider) + { + m_isTooltip = true; + } + } + else if(QEvent::MouseMove == event->type()) + { + if(object == ui->scaleSlider && m_isTooltip) + { + QMouseEvent *mouse = dynamic_cast(event); + QToolTip::showText(mouse->globalPos(), tr("双击输入值")); + } + } + + return QWidget::eventFilter(object, event); +} + +void CPlotWidget::updateLengedColumnWidth() +{ + int nLengedWidth = ui->lengedView->width(); + ui->lengedView->setColumnWidth(CCurveLegendModel::NAME, nLengedWidth / 12. * 3); + ui->lengedView->setColumnWidth(CCurveLegendModel::COLOR, nLengedWidth / 12. * 0.5); + ui->lengedView->setColumnWidth(CCurveLegendModel::VALUE, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MAX, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MAXTIME, nLengedWidth / 12. * 1.5); + ui->lengedView->setColumnWidth(CCurveLegendModel::MIN, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MINTIME, nLengedWidth / 12. * 1.5); + ui->lengedView->setColumnWidth(CCurveLegendModel::AVE, nLengedWidth / 12.); + //单位目前未查询处理为空,屏蔽显示 + ui->lengedView->setColumnWidth(CCurveLegendModel::UNIT, nLengedWidth / 12. * 1.5); + // ui->lengedView->setColumnWidth(CCurveLegendModel::FACTOR, nLengedWidth / 12.); + // ui->lengedView->setColumnWidth(CCurveLegendModel::OFFSET, nLengedWidth / 12.); +} + +void CPlotWidget::updateCurveSelectionColor(QCPGraph *graph) +{ + if(!graph) + { + return; + } + QPen selectedPen = graph->selectionDecorator()->pen(); + selectedPen.setWidth(1); + QColor color; + QColor graphColor = graph->pen().color(); + int r = graphColor.red() > 225 ? graphColor.red() - 30 : graphColor.red() + 30; + int g = graphColor.green() > 225 ? graphColor.green() - 30 : graphColor.green() + 30; + int b = graphColor.blue() > 225 ? graphColor.blue() - 30 : graphColor.blue() + 30; + color.setRgb(r, g, b); + selectedPen.setColor(color); + graph->selectionDecorator()->setPen(selectedPen); +} + +E_Trend_Type CPlotWidget::getRangeType(const QCPRange &range) +{ + if(range.size() <= 0) + { + return E_Trend_Invalid; + } + + QDateTime upper = QDateTime::fromMSecsSinceEpoch(range.upper); + + if(range.lower >= upper.addSecs(-10).toMSecsSinceEpoch()) + { + return E_Trend_RealTime; + } + else if(range.lower >= upper.addSecs(-600).toMSecsSinceEpoch()) + { + return E_Trend_His_Minute; + } + else if(range.lower >= upper.addSecs(-3600).toMSecsSinceEpoch()) + { + return E_Trend_His_Hour; + } + else if(range.lower >= upper.addDays(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Day; + } + else if(range.lower >= upper.addDays(-7).toMSecsSinceEpoch()) + { + return E_Trend_His_Week; + } + else if(range.lower >= upper.addMonths(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Month; + } + else if(range.lower >= upper.addMonths(-3).toMSecsSinceEpoch()) + { + return E_Trend_His_Quarter; + } + else if(range.lower >= upper.addYears(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Year; + } + + return E_Trend_His_Year; +} + +int CPlotWidget::currentGroupByMinute() +{ + int nGroupByMinute = 0; + switch (m_type) + { + case E_Trend_RealTime: + { + //< Error + } + break; + case E_Trend_His_Minute: + { + //< Error + } + break; + case E_Trend_His_Hour: + { + //< Error + } + break; + case E_Trend_His_Day: + { + nGroupByMinute = 1; + } + break; + case E_Trend_His_Week: + { + nGroupByMinute = 7; + } + break; + case E_Trend_His_Month: + { + nGroupByMinute = 30; + } + break; + case E_Trend_His_Quarter: + { + nGroupByMinute = 90; + } + break; + case E_Trend_His_Year: + { + nGroupByMinute = 365; + } + break; + default: + break; + } + return nGroupByMinute; +} + +/************************************************************************ + * + * 接口 + * + ************************************************************************/ +void CPlotWidget::setTitle(const QString &title) +{ + ui->title->setText(title); +} + +void CPlotWidget::setTitleVisible(bool visible) +{ + ui->titleFrame->setVisible(visible); +} + +void CPlotWidget::setTickCount(const int &count) +{ + QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); + ticker->setTickCount(count); +} + +void CPlotWidget::insertTag(const QString &tag, const bool &resetTitle) +{ + if(resetTitle) + { + setTitle(tr("趋势图")); + } + Curve curve; + curve.tag = tag; + QList list = m_pTrendGraph->curveColors(); + int index = 0; + for(int nIndex=0; nIndexindex("curve.tag"); + if(mIndex != -1) + { + ui->lengedView->setRowHidden(mIndex,true); + } +} + +void CPlotWidget::insertTag(const QStringList &listTag, const bool &resetTitle) +{ + m_pTrendGraph->clear(); + foreach (QString tag, listTag) + { + insertTag(tag, resetTitle); + } +} + +void CPlotWidget::removeTag(const QString &tag, const bool &resetTitle) +{ + if(resetTitle) + { + setTitle(tr("趋势图")); + } + m_isSetSliderValue = false; + setAllLengedShow(); + int nIndex = m_pTrendGraph->removeCurve(tag); + if(nIndex != -1) + { + if(m_showType == E_Show_Table) + { + m_pTableDataModel->removeCurveData(ui->plot->graph(nIndex)->desc()); + } + ui->plot->removeGraph(nIndex); + } + + m_pLengedModel->setTrendGraph(m_pTrendGraph); + int mIndex = m_pTrendGraph->index("curve.tag"); + if(mIndex != -1) + { + ui->lengedView->setRowHidden(mIndex,true); + } + updateLengedColumnWidth(); + if(!m_pTrendGraph->curves().size()) + { + ui->plot->yAxis->setRange(QCPRange(-1, 1)); + + if(m_isWindowMode) + { + ui->collectCurve->setVisible(false); + } + ui->clear->setEnabled(false); + }else{ + removeCurvesGroupQuery(); + if(m_horizontalGraph) + { + groupQueryHistoryEvent(); + } + } + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::setDisplayTime(const int &trendType, const double &dateTime, const bool &alarm) +{ + QAbstractButton* Button = m_TrendTypeButton->button(trendType); + if(Button) + { + ui->date->blockSignals(true); + QMetaObject::invokeMethod(Button, "click"); + ui->date->blockSignals(false); + + QDateTime nDateTime = QDateTime::fromMSecsSinceEpoch(dateTime); + ui->date->setDateTime(nDateTime); + if(E_Trend_His_Day == trendType) + { + ui->plot->xAxis->blockSignals(true); + ui->plot->xAxis->setRange(dateTime - 600000, dateTime + 600000); + ui->plot->xAxis->blockSignals(false); + } + + ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(dateTime), 0)); + if(alarm) + { + ui->checkBox_alarmPoint->setChecked(true); + alarmPointCheckStateChanged(); + } + } +} + +void CPlotWidget::setTagVisible(const QString &tag, const bool &visible) +{ + setAllLengedShow(); + int nIndex = m_pTrendGraph->index(tag); + if(nIndex != -1) + { + m_pLengedModel->setData(m_pLengedModel->index(nIndex, 0), visible, Qt::CheckStateRole); + ui->plot->replot(); + } + int mIndex = m_pTrendGraph->index("curve.tag"); + if(mIndex != -1) + { + ui->lengedView->setRowHidden(mIndex,true); + } +} + +void CPlotWidget::setDateButtonVisible(const int &button, const bool &visible) +{ + QAbstractButton* Button = m_TrendTypeButton->button(button); + if(Button) + { + Button->setVisible(visible); + } +} + +void CPlotWidget::setClearVisible(bool visible) +{ + if(visible) + { + ui->clear->show(); + } + else + { + ui->clear->hide(); + } +} + +void CPlotWidget::setAdaptVisible(bool visible) +{ + m_isAdaptShow = false; + + ui->adapt->setVisible(visible); +} + +void CPlotWidget::setAlarmPointVisible(bool visible) +{ + m_isAlarmShow = false; + + ui->checkBox_alarmPoint->setVisible(visible); + ui->comboBox_alarmStatus->setVisible(visible); +} + +void CPlotWidget::insertCurve(Curve curve) +{ + m_isSetSliderValue = true; + if((NULL != m_horizontalGraph && ui->plot->graphCount() >= 65) || + (NULL == m_horizontalGraph && ui->plot->graphCount() >= 64)) + { + if(m_numWarnFlag) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势曲线已达最大支持数量[64]!"), QMessageBox::Ok); + m_numWarnFlag = false; + } + emit updateTagCheckState(curve.tag, false); + return; + } + + m_numWarnFlag = true; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(curve.tag == ui->plot->graph(nIndex)->name()) + { + LOGINFO("趋势曲线[%s]已存在", curve.tag.toStdString().c_str()); + return; + } + } + + curve.type = CTrendInfoManage::instance()->getTagType(curve.tag); + curve.unit = CTrendInfoManage::instance()->getTagUnit(curve.tag); + if(curve.type.isEmpty()) + { + LOGINFO("趋势曲线[%s]类型不存在", curve.tag.toStdString().c_str()); + return; + } + + curve.desc = CTrendInfoManage::instance()->getTagDescription(curve.tag); + if(curve.desc.isEmpty()) + { + LOGINFO("趋势曲线[%s]描述不存在", curve.tag.toStdString().c_str()); + return; + } + + m_pDpcdaForApp->subscribe(curve.type.toStdString(), curve.tag.toStdString(), "value"); + + //< 添加曲线 + m_pTrendGraph->addCurve(curve); + QCPGraph * graph = ui->plot->addGraph(); + graph->setName(curve.tag); + graph->setDesc(curve.desc); + QPen pen; + pen.setWidth(1); + pen.setColor(curve.color); + graph->setPen(pen); + updateCurveSelectionColor(graph); + + updateGroupQuery(curve.tag); + + connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); + + //< 方波 + QString type = CTrendInfoManage::instance()->getTagType(curve.tag); + if(type == "digital" || type == "mix") + { + graph->setLineStyle(QCPGraph::lsStepLeft); + } + + //< 查询最新十分钟数据 +// double upper = QDateTime::currentMSecsSinceEpoch(); +// double lower = upper - (10 * 60 * 1000); +// SMeasPointKey key; +// std::string tmp = curve.tag.toStdString(); +// char * tag = (char*)malloc(tmp.size() + 1); +// memset(tag, 0, tmp.size() + 1); +// memcpy(tag, tmp.c_str(), tmp.size()); +// key.m_pszTagName = tag; +// key.m_enType = getMeasType(curve.type); +// std::vector * vecMpKey = new std::vector(); +// vecMpKey->push_back(key); +// emit sigQueryHistoryOriginalData(vecMpKey, lower, upper, E_REALTIME); + + updateCurves(); + + m_pLengedModel->setTrendGraph(m_pTrendGraph); + updateLengedColumnWidth(); + + ui->clear->setEnabled(true); + + if(m_isWindowMode) + { + ui->collectCurve->setVisible(true); + emit updateTagCheckState(curve.tag, true); + } + setLegendCurveTransformColumnVisible(true); +} + +void CPlotWidget::clear(bool clearTitle) +{ + if(!m_pTrendGraph->curves().size()) + { + ui->clear->setEnabled(false); + } + m_pTrendGraph->clear(); + m_pLengedModel->clear(); + m_pLengedModel->update(); + m_pTableDataModel->clear(); + m_horizontalGraph = NULL; + m_groupTagMap.clear(); + + ui->plot->yAxis->setRange(QCPRange(-1, 1)); + ui->plot->clearItems(clearTitle); + ui->plot->clearGraphs(); + ui->plot->replot(); + ui->checkBox_alarmPoint->setCheckState(Qt::Unchecked); + ui->adapt->setCheckState(Qt::Unchecked); + setTitle(tr("趋势图")); + if(m_isWindowMode) + { + ui->collectCurve->setVisible(false); + } + emit clearCurve(); +} + +void CPlotWidget::setWindowMode(const bool &isWindowMode) +{ + m_isWindowMode = isWindowMode; +} + +void CPlotWidget::setColorList(const QStringList &listColor) +{ + foreach (QString c, listColor) + { + c.replace("\r", ""); + m_listColor.append(QColor(c)); + } +} + +/****************************** 图表颜色 **************************************/ +QColor CPlotWidget::plotBackgroundColor() +{ + return m_plotBackgroundColor; +} + +void CPlotWidget::setPlotBackgroundColor(const QColor &color) +{ + m_plotBackgroundColor = color; + + ui->plot->setBackground(m_plotBackgroundColor); +} + +QPixmap CPlotWidget::plotBackImage() +{ + return m_plotBackImage; +} + +void CPlotWidget::setPlotBackImage(const QPixmap &pm) +{ + m_plotBackImage = pm; + + ui->plot->setBackgroundScaled(false); + ui->plot->setBackground(pm); +} + +QColor CPlotWidget::plotTickColor() +{ + return m_plotTickColor; +} + +void CPlotWidget::setPlotTickColor(const QColor &color) +{ + m_plotTickColor = color; + + ui->plot->xAxis->setTickLabelColor(color); + ui->plot->yAxis->setTickLabelColor(color); + ui->plot->yAxis2->setTickLabelColor(color); +} + +QColor CPlotWidget::plotGridColor() +{ + return m_plotGridColor; +} + +void CPlotWidget::setPlotGridColor(const QColor &color) +{ + m_plotGridColor = color; + + ui->plot->xAxis->grid()->setPen(color); + ui->plot->yAxis->grid()->setPen(color); + + ui->plot->xAxis->grid()->setSubGridPen(color); + ui->plot->yAxis->grid()->setSubGridPen(color); +} + +QColor CPlotWidget::plotZeroLineColor() +{ + return m_plotZeroLineColor; +} + +void CPlotWidget::setPlotZeroLineColor(const QColor &color) +{ + m_plotZeroLineColor = color; + + ui->plot->xAxis->grid()->setZeroLinePen(QPen(color)); + ui->plot->yAxis->grid()->setZeroLinePen(QPen(color)); +} + +QColor CPlotWidget::plotTickPen() +{ + return m_plotTickPen; +} + +void CPlotWidget::setPlotTickPen(const QColor &color) +{ + m_plotTickPen = color; + + ui->plot->xAxis->setBasePen(color); + ui->plot->yAxis->setBasePen(color); + ui->plot->yAxis2->setBasePen(color); + ui->plot->xAxis->setTickPen(color); + ui->plot->yAxis->setTickPen(color); + ui->plot->yAxis2->setTickPen(color); + ui->plot->xAxis->setSubTickPen(color); + ui->plot->yAxis->setSubTickPen(color); + ui->plot->yAxis2->setSubTickPen(color); +} + +void CPlotWidget::realTimeElapsed() +{ + //< 刷新X轴 + const QCPRange &range = ui->plot->xAxis->range(); + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); + ui->plot->xAxis->setRange(upper, range.size(), Qt::AlignRight); + + QList listVal; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + m_pTrendGraph->updateRTCurveStatisticsInfo(graph->name()); + QVector * pCPGraphData = graph->data()->data(); + + if(pCPGraphData->isEmpty()) + { + listVal.append(qSqrt(-1.)); + } + else + { + listVal.append((*(pCPGraphData->end() - 2)).value); + + //< set virtual point value + if(limit == pCPGraphData->last().key) + { + pCPGraphData->last().value = (*(pCPGraphData->end() - 2)).value; + } + } + } + + if(E_Show_Table == m_showType) + { + updateRealTimeTableData(); + } + m_pLengedModel->setTrendCurrentValues(listVal); + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::recvRealTimeTrendData(const QString &tagName, QVariant value, int status, E_Point_Type pointType) +{ +// LOGINFO("Recv RealTime Trend Data-[Tag Name: %s, value: %f] ", tagName.toStdString().c_str(), value.toDouble()); + double key = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + int validStatus = CTrendInfoManage::instance()->getInvalidStatus(pointType, status); + m_pTrendGraph->pushCurveRTDataValue(tagName, key, value.toDouble(), validStatus); + + if(E_Trend_RealTime != m_type) + { + return; + } + + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + if(graph->name() == tagName) + { + QVector * pCPGraphData = graph->data()->data(); + + if(pCPGraphData->size() > 1 && qAbs(((*(pCPGraphData->end() - 2)).value - value.toDouble())) < _EPSILON_) + { + return; + } + graph->addData(key, value.toDouble(), validStatus); + if( pCPGraphData->first().key < ( key - (20 * 60 * 1000) ) ) + { + graph->data()->removeBefore( key - (20 * 60 * 1000) ); + } + return; + } + } +} + +void CPlotWidget::updateRealTimeTableData() +{ + QMap> curveData; + QStringList headerList; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(ui->plot->graph(nIndex)->name() == "curve.tag") + { + continue; + } + const QVector< QPair > > &values = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()).values; + QVector vecGraphData; + double preValue = DBL_MAX; + QVector< QPair > >::const_iterator iter = values.constBegin(); + for(; iter != values.constEnd(); iter++) + { + if(qAbs((iter->second.first)-preValue) < _EPSILON_) + { + continue; + } + QCPGraphData graphData; + graphData.key = iter->first; + graphData.value = iter->second.first; + graphData.status = iter->second.second; + vecGraphData.push_back(graphData); + preValue = iter->second.first; + } + curveData.insert(ui->plot->graph(nIndex)->desc(), vecGraphData); + headerList.append(ui->plot->graph(nIndex)->desc()); + } + resetCurveData(curveData, headerList, false); + + + graphVisibleChanged(true); +} + +void CPlotWidget::plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange) +{ + Q_UNUSED(oldRange) + if(E_Show_Table == m_showType) + { + return; + } + + QDateTime upper = QDateTime::fromMSecsSinceEpoch(newRange.upper); + double midValue = (newRange.upper + newRange.lower) / 2; + + if(m_type == E_Trend_RealTime) + { + m_rtRange = newRange.size(); + if(m_rtRange > 10 * 60 * 1000) + { + m_rtRange = 10 * 60 * 1000; + } + else if(m_rtRange < 10 * 1000) + { + m_rtRange = 10 * 1000; + } + + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); + return; + } + else if(m_type == E_Trend_His_Minute || m_type == E_Trend_His_Day || m_type == E_Trend_His_Week || m_type == E_Trend_His_Month || m_type == E_Trend_His_Quarter || m_type == E_Trend_His_Year) + { + QPair dateTime = getFatureDataTime(m_type, ui->date->dateTime()); + double range = newRange.size() > (dateTime.second - dateTime.first)?(dateTime.second - dateTime.first):newRange.size(); + if(newRange.lower < dateTime.first) + { + ui->plot->xAxis->setRange(dateTime.first, range, Qt::AlignLeft); + return; + } + else if(newRange.upper > dateTime.second) + { + ui->plot->xAxis->setRange(dateTime.second, range, Qt::AlignRight); + return; + } + } + else if(m_type == E_Trend_His_Custom) + { + double lower = ui->startData->dateTime().toMSecsSinceEpoch(); + double upper = ui->endData->dateTime().toMSecsSinceEpoch(); + double range = newRange.size() > (upper - lower)?(upper - lower):newRange.size(); + if(newRange.lower < lower) + { + ui->plot->xAxis->setRange(lower, range, Qt::AlignLeft); + return; + } + else if(newRange.upper > upper) + { + ui->plot->xAxis->setRange(upper, range, Qt::AlignRight); + return; + } + } + + QList listToolTip= findChildren(); + foreach (CToolTip * pToolTip, listToolTip) + { + pToolTip->close(); + } + + if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) + { + updateYAxisTicker(); + } + + E_Trend_Type rangeType = getRangeType(newRange); + if(m_type == rangeType) + { + return; + } + + if(m_type == E_Trend_His_Minute) + { + if(rangeType == E_Trend_RealTime) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-10).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Hour) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Day) + { + if(rangeType == E_Trend_His_Minute) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Week) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Week) + { + if(rangeType == E_Trend_His_Day) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Month) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Month) + { + if(rangeType == E_Trend_His_Week) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Quarter) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Quarter) + { + if(rangeType == E_Trend_His_Month) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Year) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Year) + { + if(rangeType == E_Trend_His_Quarter) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Custom) + { + if(rangeType == E_Trend_RealTime) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-10).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Year) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + +// if(rangeType != E_Trend_Invalid && rangeType != E_Trend_His_Minute && rangeType != E_Trend_His_Hour) +// { +// m_TrendTypeButton->button((int)rangeType)->setChecked(true); +// } +// updateTrendShowMode(rangeType, false); +} + +void CPlotWidget::updateTrendShowMode(int nIndex, bool updateXAxisRange) +{ + m_type = (E_Trend_Type)nIndex; + + m_isSetSliderValue = true; + updateGraphTitle(nIndex); + + if(Q_NULLPTR != m_pTimer && m_pTimer->isActive()) + { + m_pTimer->stop(); + } + m_pLengedModel->setMode(CCurveLegendModel::LENGED_HIS_MODE); + if(m_isWindowMode) + { + setLegendCurveTransformColumnVisible(false); + } + //< default setting + ui->prePage->setEnabled(true); + ui->nextPage->setEnabled(true); + ui->date->setEnabled(true); + ui->plot->axisRect()->setScaleRight(false); + ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //< 水平拖拽 + ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //< 水平缩放 + ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); + ui->plot->xAxis->setScaleType(QCPAxis::stLinear); + + int count = ui->plot->graphCount(); + for(int n(0); nplot->graph(n); + graph->data()->clear(); + } + + ui->plot->clearItems(); + m_listTracer.clear(); + + updateAxisFormat(updateXAxisRange); + + if (m_type == E_Trend_RealTime || m_type == E_Trend_Invalid) + { + ui->dataWidget->setVisible(false); + ui->customWidget->setVisible(false); + ui->adapt->setVisible(false); + ui->checkBox_alarmPoint->setVisible(false); + ui->comboBox_alarmStatus->setVisible(false); + } + else if (m_type == E_Trend_His_Custom) + { + ui->customWidget->setVisible(true); + ui->dataWidget->setVisible(false); + slotCustomSearch(); + } + else + { + ui->dataWidget->setVisible(true); + ui->customWidget->setVisible(false); + if(m_isAdaptShow) + { + ui->adapt->setVisible(true); + } + if(m_isAlarmShow) + { + ui->checkBox_alarmPoint->setVisible(true); + ui->comboBox_alarmStatus->setVisible(true); + } + ui->date->setDateTime(QDateTime::currentDateTime()); + } + if(m_showType == E_Show_Table) + { + ui->adapt->setVisible(false); + ui->checkBox_alarmPoint->setVisible(false); + ui->comboBox_alarmStatus->setVisible(false); + m_pTableDataModel->clear(); + } + + // if(m_type == E_Trend_RealTime) + { + if(E_Show_Table == m_showType) + { + updateRealTimeTableData(); + } + updateCurves(); + } +} + +void CPlotWidget::updateComputeValue(double lower, double upper, std::vector vecMethod) +{ + if(!ui->plot->graphCount()) + { + return; + } + + std::vector * vecMpKey = new std::vector(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) + { + const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); + SMeasPointKey key; + std::string tmp = curve.tag.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(curve.type); + vecMpKey->push_back(key); + } + + if(!m_pHisDataManage->isTsdbExuting()) + { + emit sigQueryHistoryComputeData(vecMpKey, lower, upper, vecMethod); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(E_COMPUTER, vecMpKey, lower, upper, -1, vecMethod); + } +} + +void CPlotWidget::updateGraphTitle(int nIndex) +{ + m_type = (E_Trend_Type)nIndex; + + if(m_type == E_Trend_RealTime) + { + m_trendTitle->setText(tr("实时趋势")); + } + else if(m_type == E_Trend_His_Minute) + { + m_trendTitle->setText(tr("秒趋势")); + } + else if(m_type == E_Trend_His_Day) + { + m_trendTitle->setText(tr("日趋势")); + } + else if(m_type == E_Trend_His_Week) + { + m_trendTitle->setText(tr("周趋势")); + } + else if(m_type == E_Trend_His_Month) + { + m_trendTitle->setText(tr("月趋势")); + } + else if(m_type == E_Trend_His_Quarter) + { + m_trendTitle->setText(tr("季度趋势")); + } + else if(m_type == E_Trend_His_Year) + { + m_trendTitle->setText(tr("年趋势")); + } + else if(m_type == E_Trend_His_Custom) + { + m_trendTitle->setText(tr("自定义趋势")); + } +} + +void CPlotWidget::updateCurves() +{ + if(E_Trend_RealTime == m_type) + { + updateRealTimeCurveRecord(); + rescaleYAxisRange(); + ui->plot->replot(); + } + else + { + updateHistoryCurveRecord(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper); + } +} + +void CPlotWidget::updateRealTimeCurveRecord() +{ + if(Q_NULLPTR == m_pTrendGraph) + { + return; + } + double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + //< 清空数据 + QSharedPointer container(new QCPGraphDataContainer()); + + const QVector< QPair > > &values = m_pTrendGraph->curve(graph->name()).values; + QVector< QPair > >::const_iterator it = values.constBegin(); + double preValue = DBL_MAX; + while (it != values.constEnd()) + { + //< LOGINFO("Update RealTime Trend Data-----------------[Time: %f, value: %f] ", it->first, it->second); + if(qAbs((it->second.first)-preValue) < _EPSILON_) + { + ++it; + continue; + } + container->add(QCPGraphData(it->first, it->second.first, it->second.second)); + preValue = it->second.first; + ++it; + } + + //< virtual point + if(container->data()->size() > 0) + { + container->add(QCPGraphData(limit, container->data()->last().value, container->data()->last().status)); + } + else + { + container->add(QCPGraphData(limit, qSqrt(-1.))); + } + graph->setData(container); + } + ui->plot->replot(); +} + +void CPlotWidget::updateHistoryCurveRecord(double lower, double upper) +{ + if(!ui->plot->graphCount()) + { + return; + } + if(E_Trend_His_Custom == m_type) + { + slotCustomSearch(true); + return; + } + + std::vector * vecMpKey = new std::vector(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) + { + const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); + SMeasPointKey key; + std::string tmp = curve.tag.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(curve.type); + vecMpKey->push_back(key); + } + + if(!m_pHisDataManage->isTsdbExuting()) + { + if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) + { + emit sigQueryHistoryOriginalData(vecMpKey, lower, upper); + } + else + { + emit sigQueryHistoryPolymericData(vecMpKey, lower, upper, currentGroupByMinute() * 60, kbd_dbms::CM_FIRST); + } + } + else + { + if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) + { + m_pHisDataManage->postTsdbCommandQueue(E_ORIGINAL, vecMpKey, lower, upper); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(E_POLYMERIC, vecMpKey, lower, upper, currentGroupByMinute() * 60, std::vector{kbd_dbms::CM_FIRST}); + } + } + + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + std::vector vecMethod{kbd_dbms::CM_MAX, kbd_dbms::CM_MIN}; + updateComputeValue(range.first, range.second, vecMethod); +} + +void CPlotWidget::updateHisOriginalData(std::vector *vecMpKey, std::vector *> *vecResult, E_Data_Type type) +{ + std::vector< QSharedPointer > vecRange; + std::vector< QSharedPointer > vecContainer; + + bool isAddVirtualPoint = true; + double lower = ui->plot->xAxis->range().lower; + double upper = ui->plot->xAxis->range().upper; + if(m_showType == E_Show_Table) + { + isAddVirtualPoint = false; + if(m_type == E_Trend_His_Custom) + { + lower = ui->startData->dateTime().toMSecsSinceEpoch(); + upper = ui->endData->dateTime().toMSecsSinceEpoch(); + } + } + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, lower, upper, isAddVirtualPoint); + + if(E_REALTIME == type) + { + for(size_t nIndex(0); nIndex < vecContainer.size(); ++nIndex) + { + QCPGraphDataContainer::iterator it = vecContainer.at(nIndex)->begin(); + while(it != vecContainer.at(nIndex)->end()) + { + m_pTrendGraph->pushCurveRTDataValue(vecMpKey->at(nIndex).m_pszTagName, it->key, it->value, it->status); + ++it; + } + } + updateCurves(); + } + else if(E_HISTORY == type) + { + if(m_showType == E_Show_Curve) + { + updateHistoryGraph(vecMpKey, vecContainer, vecRange); + } + else if(m_showType == E_Show_Table) + { + updateHistoryData(vecMpKey, vecContainer, vecRange); + } + } + m_pLengedModel->update(); + + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(vecResult->end() != res) + { + delete (*res); + ++res; + } + vecResult->clear(); + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + + } + vecMpKey->clear(); + delete vecMpKey; +} + +void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, int nGroupBySec) +{ + std::vector< QSharedPointer > vecRange; + std::vector< QSharedPointer > vecContainer; + + if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) + { + if(m_showType == E_Show_Curve) + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, + ui->plot->xAxis->range().upper, true, nGroupBySec); + + updateHistoryGraph(vecMpKey, vecContainer, vecRange); + } + else if(m_showType == E_Show_Table) + { + if(m_type == E_Trend_His_Custom) + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->startData->dateTime().toMSecsSinceEpoch(), + ui->endData->dateTime().toMSecsSinceEpoch(), false, nGroupBySec); + } + else + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, + ui->plot->xAxis->range().upper, false, nGroupBySec); + } + + updateHistoryData(vecMpKey, vecContainer, vecRange); + } + } + m_pLengedModel->update(); + + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(vecResult->end() != res) + { + delete (*res); + ++res; + } + vecResult->clear(); + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; +} + +void CPlotWidget::updateHisComputeData(std::vector *vecMpKey, std::vector *> *> > cmResult) +{ + typename std::vector *> *> >::const_iterator resultIter = cmResult.begin(); + while(resultIter != cmResult.end()) + { + EnComputeMethod method = resultIter->first; + typename std::vector *>::const_iterator it = resultIter->second->begin(); + while(it != resultIter->second->end()) + { + int nIndex = it - resultIter->second->begin(); + if(nIndex > ui->plot->graphCount()-1) + { + ++it; + continue; + } + QCPGraph * graph = ui->plot->graph(nIndex); + if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) + { + ++it; + continue; + } + std::vector * vecPoint = *it; + if(vecPoint->empty()) + { + ++it; + setCurveStatisData(graph->name(), method, true); + continue; + } + + typename std::vector::const_iterator pt = vecPoint->begin(); + while(pt != vecPoint->end()) + { + double value = qSqrt(-1.); + if (typeid(boost::int32_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + else if (typeid(boost::float64_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + + if(std::isnan(value)) + { + ++pt; + setCurveStatisData(graph->name(), method, true); + continue; + } + setCurveStatisData(graph->name(), method, false, value, pt->m_nTime); + ++pt; + } + ++it; + } + //< 释放结果集 + std::vector *>::iterator res = resultIter->second->begin(); + while(resultIter->second->end() != res) + { + delete (*res); + ++res; + } + resultIter->second->clear(); + delete resultIter->second; + resultIter++; + } + m_pLengedModel->update(); + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; +} + +void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange) +{ + double lower = ui->plot->xAxis->range().lower; + double upper = ui->plot->xAxis->range().upper; + + if(vecContainer.size() == 0) + { + int count = ui->plot->graphCount(); + for(int n(0); nplot->graph(n); + graph->data()->clear(); + } + ui->plot->replot(); + } + + for(int nIndex(0); nIndex < (int)vecContainer.size(); ++nIndex) + { + if(nIndex > ui->plot->graphCount()-1) + { + continue; + } + QCPGraph * graph = ui->plot->graph(nIndex); + { + if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) + { + continue; + } + } + updateCurveHisData(lower, upper, graph, nIndex, vecContainer.at(nIndex), vecRange.at(nIndex)); + graph->data()->clear(); + graph->setData(vecContainer.at(nIndex)); + } + + updateLengedValue(ui->plot->xAxis->pixelToCoord(ui->plot->symbolPos().x())); + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::updateHistoryData(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange) +{ + double lower,upper; + if(m_type == E_Trend_His_Custom) + { + lower = ui->startData->dateTime().toMSecsSinceEpoch(); + upper = ui->endData->dateTime().toMSecsSinceEpoch(); + } + else + { + lower = ui->plot->xAxis->range().lower; + upper = ui->plot->xAxis->range().upper; + } + + QMap> curveData; + QStringList headerList; + for(int nIndex(0); nIndex < (int)vecContainer.size(); ++nIndex) + { + if(nIndex > ui->plot->graphCount()-1) + { + continue; + } + QCPGraph * graph = ui->plot->graph(nIndex); + { + if(graph->name() == "curve.tag") + { + continue; + } + if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) + { + continue; + } + } + updateCurveHisData(lower, upper, graph, nIndex, vecContainer.at(nIndex), vecRange.at(nIndex)); + + QVector vecGraphData; + QCPGraphDataContainer::const_iterator iter = vecContainer.at(nIndex)->constBegin(); + while(iter != vecContainer.at(nIndex)->end()) + { + QCPGraphData graphData; + graphData.key = iter->key; + graphData.value = iter->value; + graphData.status = iter->status; + vecGraphData.push_back(graphData); + iter++; + } + curveData.insert(graph->desc(), vecGraphData); + headerList.append(graph->desc()); + } + resetCurveData(curveData, headerList, true); + enableSearch(true); +} + +void CPlotWidget::updateCurveHisData(double lower, double upper, QCPGraph *graph, int index, QSharedPointer container, QSharedPointer range) +{ + int count = 0; //< accuml size + double offset = 0.; + double factor = 1.; + double accuml = 0.; + + const Curve &curve = m_pTrendGraph->curve(graph->name()); + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + double maxVal = range->max; + double minVal = range->min; + if(maxVal == minVal) + { + factor = maxVal == 0 ? 0 : 50. / maxVal; + offset = maxVal == 0 ? 50 : 0; + } + else + { + factor = 100. / (maxVal - minVal); + offset = -factor * minVal; + } + m_pTrendGraph->setCurveGraphFactor(index, factor); + m_pTrendGraph->setCurveGraphOffset(index, offset); + } + else + { + factor = curve.factor; + offset = curve.offset; + } + + //< 此设计考虑自定义缩放【已实现,暂未开放】扩展 + double max = -DBL_MAX; + double min = DBL_MAX; + double maxTime = -DBL_MAX; + double minTime = DBL_MAX; + double average = qSqrt(-1.); + QCPGraphDataContainer::iterator iter = container->begin(); + while(iter != container->end()) + { + if(qIsNaN(iter->value)) + { + ++iter; + continue; + } + + //< 统计值 + if(iter->key >= lower && iter->key <= upper) + { + ++count; + if(iter->value > max) + { + max = iter->value; + maxTime = iter->key; + } + if(iter->value < min) + { + min = iter->value; + minTime = iter->key; + } + + accuml += iter->value; + } + + //< 缩放数据 + if(m_bHisAdaption && m_type != E_Trend_RealTime + && m_showType != E_Show_Table) + { + iter->value *= factor; + iter->value += offset; + } + ++iter; + } + if(!container->isEmpty()) + { + if(count) + { + average = accuml / count; + } + } + m_pTrendGraph->setCurveHisDataValue(graph->name(), max, min, maxTime, minTime, average, accuml, *range); +} + +void CPlotWidget::updatePhaseTracer(std::vector *vecMpKey, std::vector *> *vecResult) +{ + ui->plot->clearItems(); + m_listTracer.clear(); + QMultiMap< double, QStringList > map; + if(ui->checkBox_alarmPoint->isChecked()) + { + for(size_t tagIndex(0); tagIndex < vecResult->size(); tagIndex++) + { + std::vector *evetVector = vecResult->at(tagIndex); + std::vector::iterator iter = evetVector->begin(); + for(; iter != evetVector->end(); iter++) + { + if(m_alarmStatusList.contains(iter->m_nAlmStatus)) + { + QStringList list; + list.append(vecMpKey->at(tagIndex).m_pszTagName); + list.append(QString::number(iter->m_nAlmType)); + map.insert(iter->m_nTime, list); + } + } + } + } + QPointF prePt(-1000., -1000.); + + //< 1min 显示所有事件 + bool bMinRange = ui->plot->xAxis->range().size() > 60; + QMultiMap< double, QStringList >::iterator rIter = map.begin(); + QMultiMap hidePoint; + for(; rIter != map.end(); rIter++) + { + double key = rIter.key(); + if(bMinRange) + { + double curX = ui->plot->xAxis->coordToPixel(key); + double curY = 0; + if( m_horizontalGraph ) + { + curY = ui->plot->yAxis->coordToPixel(m_horizontalGraph->value(key)); + } + QPointF pt = QPointF(curX, curY) - prePt; + if(pt.manhattanLength() < 8) + { + hidePoint.insert(key, rIter.value()[0]); + continue; + } + prePt = QPointF(curX, curY); + } + QStringList value = rIter.value(); + QCPItemTracer *phaseTracer = new QCPItemTracer(ui->plot, key, QString(value[1]).toInt(), QPen(Qt::red), QBrush(Qt::red), m_alarmStatusList); + phaseTracer->setGraphKey(key); + if(m_horizontalGraph!=NULL && m_type != E_Trend_RealTime) + { + phaseTracer->setGraph(m_horizontalGraph); + } + phaseTracer->addHidePoint(key, value[0]); + phaseTracer->setInterpolating(true); + if(m_listTracer.length() > 0) + m_listTracer.last()->setHidePoint(hidePoint); + m_listTracer.append(phaseTracer); + + connect(phaseTracer, &QCPItemTracer::itemTracerHoverd, m_pHisEventManage, &CHisEventManage::queryHisEvent, Qt::BlockingQueuedConnection); + hidePoint.clear(); + hidePoint.insert(key, value[0]); + } + if(m_listTracer.length() > 0 && !hidePoint.isEmpty()) + { + m_listTracer.last()->setHidePoint(hidePoint); + hidePoint.clear(); + } + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(res != vecResult->end()) + { + delete (*res); + ++res; + } + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; + ui->plot->replot(); +} + +void CPlotWidget::updateGraphEvent(const qint64 &time, QStringList contents) +{ + foreach (QCPItemTracer *phaseTracer, m_listTracer) + { + if(phaseTracer->timeStamp() == time) + { + phaseTracer->setInfo(contents); + phaseTracer->showTips(); + } + } +} + +void CPlotWidget::updateAxisFormat(bool updateXAxisRange) +{ +// ui->plot->xAxis->blockSignals(true); + QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + switch (m_type) + { + case E_Trend_RealTime: + { + //< 10 min + ui->prePage->setEnabled(false); + ui->nextPage->setEnabled(false); + ui->date->setEnabled(false); + ui->plot->setInteractions(QCP::iRangeZoom | QCP::iSelectPlottables); + ui->plot->axisRect()->setScaleRight(true); + ticker->setDateTimeFormat("hh:mm:ss"); + ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); + if(Q_NULLPTR != m_pTimer) + { + m_pTimer->start(); + } + if(m_isWindowMode) + { + ticker->setTickCount(11); + setLegendCurveTransformColumnVisible(true); + } + else + { + ticker->setTickCount(6); + } + + m_pLengedModel->setMode(CCurveLegendModel::LENGED_RT_MODE); + ui->plot->yAxis->setTicker(m_ptrPlotTricker); + ui->plot->yAxis2->setTicker(m_ptrPlotTricker); + } + break; + case E_Trend_His_Minute: + { + if(m_isWindowMode) + { + ticker->setTickCount(12); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + ui->date->setMinimumWidth(170); + ui->date->setDisplayFormat("yyyy-MM-dd hh:mm"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Minute); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Hour: + { + if(m_isWindowMode) + { + ticker->setTickCount(11); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + } + break; + case E_Trend_His_Day: + { + if(m_isWindowMode) + { + ticker->setTickCount(12); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy-MM-dd"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Day); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Week: + { + if(m_isWindowMode) + { + ticker->setTickCount(8); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("MM-dd hh ddd"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy-MM-dd"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Week); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Month: + { + if(m_isWindowMode) + { + ticker->setTickCount(11); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("dd hh"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy-MM"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Month); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Quarter: + { + if(m_isWindowMode) + { + ticker->setTickCount(10); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("MM-dd"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy-MM"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Quarter); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Year: + { + if(m_isWindowMode) + { + ticker->setTickCount(13); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("MM-dd"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Year); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Custom: + { + ticker->setTickCount(5); + + ticker->setDateTimeFormat("MM-dd hh:mm:ss"); + if(updateXAxisRange) + { + ui->plot->xAxis->setRange(ui->startData->dateTime().toMSecsSinceEpoch(), + ui->endData->dateTime().toMSecsSinceEpoch()); + } + } + break; + default: + break; + } +// ui->plot->xAxis->blockSignals(false); +} + +QPair CPlotWidget::getFatureDataTime(E_Trend_Type type, QDateTime curTime) +{ + QDateTime low; + QDateTime up; + QPair range; + if(!curTime.isValid()) + { + low = QDateTime::currentDateTime(); + up = QDateTime::currentDateTime(); + } + else + { + low = curTime; + up = curTime; + } + + switch (type) { + case E_Trend_His_Day: + { + break; + } + case E_Trend_His_Minute: + { + int minute = up.time().minute(); + up.setTime(QTime(up.time().hour(), (minute/10)*10+9, 59, 999)); + low.setTime(QTime(low.time().hour(), (minute/10)*10)); + range.first = low.toMSecsSinceEpoch(); + range.second = up.toMSecsSinceEpoch(); + return range; + } + case E_Trend_His_Week: + { + up = up.addDays(7-low.date().dayOfWeek()); + low = low.addDays(-low.date().dayOfWeek()+1); + break; + } + case E_Trend_His_Month: + { + up.setDate(QDate(low.date().year(), low.date().month(), low.date().daysInMonth())); + low.setDate(QDate(low.date().year(), low.date().month(), 1)); + break; + } + case E_Trend_His_Quarter: + { + QString month = QString::number(low.date().month()); + if(QString("1,2,3").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 3, 31)); + low.setDate(QDate(low.date().year(), 1, 1)); + } + else if(QString("4,5,6").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 6, 30)); + low.setDate(QDate(low.date().year(), 4, 1)); + } + else if(QString("7,8,9").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 9, 30)); + low.setDate(QDate(low.date().year(), 7, 1)); + } + else if(QString("10,11,12").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 12, 31)); + low.setDate(QDate(low.date().year(), 10, 1)); + } + break; + } + case E_Trend_His_Year: + { + up.setDate(QDate(low.date().year(), 12, 31)); + low.setDate(QDate(low.date().year(), 1, 1)); + break; + } + default: + break; + } + low.setTime(QTime(0,0,0)); + up.setTime(QTime(23,59,59)); + range.first = low.toMSecsSinceEpoch(); + range.second = up.toMSecsSinceEpoch(); + return range; +} + +void CPlotWidget::updateAdaptState(bool isAdapt) +{ + m_isSetSliderValue = true; + m_bHisAdaption = isAdapt; + if(m_isWindowMode) + { + setLegendCurveTransformColumnVisible(isAdapt); + } + updateCurves(); + + updateYAxisTicker(); +} + +void CPlotWidget::slotCollectGraph(const QString &text) +{ + emit collectGraph(text, *m_pTrendGraph); +} + +void CPlotWidget::slotSliderRangeChange(int lower, int upper) +{ + m_isSetSliderValue = false; + if(lower <= upper) + { + ui->scaleSlider->setLowerValue(lower); + ui->scaleSlider->setUpperValue(upper); + } +} + +void CPlotWidget::addCollect() +{ + QPoint pt = ui->collectCurve->mapToGlobal(QPoint()); + int x = pt.x() + ui->collectCurve->width(); + int y = pt.y() + ui->collectCurve->height(); + emit sigAddCollect(x, y); +} + +void CPlotWidget::slotPrint() +{ + QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/%1.jpg").arg(ui->title->text()), tr("(*.jpg)"), + Q_NULLPTR, QFileDialog::DontUseNativeDialog); + + if(strFileName.isEmpty()) + { + return; + } + ui->plot->legend->setVisible(true); + m_trendTitle->setVisible(true); + ui->plot->replot(QCustomPlot::rpImmediateRefresh); + bool ret = ui->plot->saveJpg(strFileName, 1600, 800); + ui->plot->legend->setVisible(false); + m_trendTitle->setVisible(false); + ui->plot->replot(QCustomPlot::rpImmediateRefresh); + if(ret) + { + QMessageBox::information(this,tr("提示"),tr("保存成功"),QMessageBox::Ok); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败"),QMessageBox::Ok); + } +} + +void CPlotWidget::slotExport() +{ + QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/%1.xlsx").arg(ui->title->text()), tr("(*.xlsx)"), + Q_NULLPTR, QFileDialog::DontUseNativeDialog); + if(strFileName.isEmpty()) + return; + + QXlsx::Document xlsx; + + for(int col = 0; col < m_pTableDataModel->columnCount(); col++) + { + xlsx.write(hexTo26(col)+"1", m_pTableDataModel->headerData(col, Qt::Horizontal, Qt::ToolTipRole)); + xlsx.setColumnWidth(col+1, 35); + } + + QXlsx::Format format; + QColor lastColor, curColor; + for(int row = 0; row < m_pTableDataModel->rowCount(); row++) + { + for(int col = 0; col < m_pTableDataModel->columnCount(); col++) + { + QModelIndex index = m_pTableDataModel->index(row, col); + curColor = QColor(m_pTableDataModel->data(index, Qt::UserRole).toInt() * 4288716964); + if(lastColor != curColor) + { + format.setFontColor(curColor); + lastColor = curColor; + } + xlsx.write(hexTo26(col)+QString::number(row+2), m_pTableDataModel->data(index), format); + } + } + //m_pTrendGraph + int curRow = xlsx.dimension().lastRow(); + xlsx.write(hexTo26(0)+QString::number(curRow+1) , "最大值" ,format); + xlsx.write(hexTo26(0)+QString::number(curRow+2) , "最大值时间" ,format); + xlsx.write(hexTo26(0)+QString::number(curRow+3) , "最小值" ,format); + xlsx.write(hexTo26(0)+QString::number(curRow+4) , "最小值时间" ,format); + xlsx.write(hexTo26(0)+QString::number(curRow+5) , "平均值" ,format); + for(int col = 1,r = 0; col <= m_pTableDataModel->rowCount(); col++,r++) + { + xlsx.write(hexTo26(col)+QString::number(curRow+1) , + m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MAX) , + Qt::DisplayRole) ,format); + xlsx.write(hexTo26(col)+QString::number(curRow+2) , + m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MAXTIME) , + Qt::DisplayRole) ,format); + + xlsx.write(hexTo26(col)+QString::number(curRow+3) , + m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MIN) , + Qt::DisplayRole) ,format); + + xlsx.write(hexTo26(col)+QString::number(curRow+4) , + m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MINTIME) , + Qt::DisplayRole) ,format); + xlsx.write(hexTo26(col)+QString::number(curRow+5) , + m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::AVE) , + Qt::DisplayRole) ,format); + } + + if(xlsx.saveAs(strFileName)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+strFileName); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } +} + +void CPlotWidget::prePage() +{ + m_isSetSliderValue = true; + QDateTime dateTime = ui->date->dateTime(); + switch(m_type) + { + case E_Trend_His_Minute: + { + ui->date->setDateTime(dateTime.addSecs(-600)); + break; + } + case E_Trend_His_Hour: + case E_Trend_His_Day: + { + ui->date->setDateTime(dateTime.addDays(-1)); + break; + } + case E_Trend_His_Week: + { + ui->date->setDateTime(dateTime.addDays(-7)); + break; + } + case E_Trend_His_Month: + { + ui->date->setDateTime(dateTime.addMonths(-1)); + break; + } + case E_Trend_His_Quarter: + { + ui->date->setDateTime(dateTime.addMonths(-3)); + break; + } + case E_Trend_His_Year: + { + ui->date->setDateTime(dateTime.addYears(-1)); + break; + } + default: + return; + } + + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + ui->plot->xAxis->blockSignals(true); + ui->plot->xAxis->setRange(range.first, range.second); + ui->plot->xAxis->blockSignals(false); + updateCurves(); +} + +void CPlotWidget::nextPage() +{ + m_isSetSliderValue = true; + QDateTime dateTime = ui->date->dateTime(); + switch(m_type) + { + case E_Trend_His_Minute: + { + ui->date->setDateTime(dateTime.addSecs(600)); + break; + } + case E_Trend_His_Hour: + case E_Trend_His_Day: + { + ui->date->setDateTime(dateTime.addDays(1)); + break; + } + case E_Trend_His_Week: + { + ui->date->setDateTime(dateTime.addDays(7)); + break; + } + case E_Trend_His_Month: + { + ui->date->setDateTime(dateTime.addMonths(1)); + break; + } + case E_Trend_His_Quarter: + { + ui->date->setDateTime(dateTime.addMonths(3)); + break; + } + case E_Trend_His_Year: + { + ui->date->setDateTime(dateTime.addYears(1)); + break; + } + default: + return; + } + + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + ui->plot->xAxis->blockSignals(true); + ui->plot->xAxis->setRange(range.first, range.second); + ui->plot->xAxis->blockSignals(false); + updateCurves(); +} + +void CPlotWidget::graphVisibleChanged(const bool &check) +{ + //< 脚本调用setTagVisible导致无法自适应 +// m_isSetSliderValue = check; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + const Curve &curve = m_pTrendGraph->curve(graph->name()); + graph->setVisible(curve.visible); + if(!curve.visible || curve.tag == "curve.tag") + { + graph->removeFromLegend(ui->plot->legend); + m_pTableDataModel->setColumnHidden(graph->desc(), true); + } + else + { + graph->addToLegend(ui->plot->legend); + m_pTableDataModel->setColumnHidden(graph->desc(), false); + } + } + ui->plot->clearItems(); + m_listTracer.clear(); + removeCurvesGroupQuery(); + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::graphPropertyChanged() +{ + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + const Curve &curve = m_pTrendGraph->curve(graph->name()); + graph->setPen(curve.color); + updateCurveSelectionColor(graph); + } + ui->lengedView->setCurrentIndex(ui->lengedView->model()->index(ui->lengedView->currentIndex().row(), 0)); + updateCurves(); +} + +void CPlotWidget::deleteCurrentGraph() +{ + int index = ui->lengedView->currentIndex().row(); + if(m_pTrendGraph->curves().size() > 0 && index >= 0) + { + QCPGraph * graph = ui->plot->graph(index); + const Curve &curve = m_pTrendGraph->curve(graph->name()); + QString tag = curve.tag; + if(tag != "curve.tag") + { + removeTag(tag); + emit updateTagCheckState(tag,false); + } + } +} + +void CPlotWidget::jumpToMaxTime(const double &time) +{ + if(m_type == E_Trend_His_Minute) + { + double range = ui->plot->xAxis->range().size() / 2.0; + ui->plot->xAxis->setRange(time - range, time + range); + updateCurves(); + ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(time), 0)); + } + else + { + setDisplayTime(E_Trend_His_Minute, time, false); + } +} + +void CPlotWidget::jumpToMinTime(const double &time) +{ + if(m_type == E_Trend_His_Minute) + { + double range = ui->plot->xAxis->range().size() / 2.0; + ui->plot->xAxis->setRange(time - range, time + range); + updateCurves(); + ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(time), 0)); + } + else + { + setDisplayTime(E_Trend_His_Minute, time, false); + } +} + +void CPlotWidget::updateLengedValue(const double &dateTime) +{ + QList listVal; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + double graphValue = graph->value(dateTime); + const Curve &curve = m_pTrendGraph->curve(graph->name()); + double value = graphValue; + + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + value = (graphValue - curve.graphOffset) / curve.graphFactor; + } + listVal.append(value); + } + m_pLengedModel->setTrendCurrentValues(listVal); +} + +void CPlotWidget::graphSelectionChanged(bool select) +{ + ui->lengedView->selectionModel()->clear(); + updateYAxisTicker(); + + QCPGraph * graph = dynamic_cast(sender()); + if(Q_NULLPTR != graph && select) + { + ui->lengedView->selectRow(m_pTrendGraph->index(graph->name())); + } + ui->plot->replot(QCustomPlot::rpQueuedRefresh); +} + +void CPlotWidget::tableSelectionChanged(const QModelIndex &index) +{ + ui->lengedView->selectRow(index.column()-1); +} + +void CPlotWidget::updateGraphSelection() +{ + ui->plot->blockSignals(true); +// ui->plot->clearItems(); + ui->plot->deselectAll(); + ui->plot->blockSignals(false); + int index = ui->lengedView->currentIndex().row(); + QCPGraph * graph = ui->plot->graph(index); + if(graph) + { + if(E_Show_Table == m_showType) + { + int column = m_pTableDataModel->getHeaderIndex(graph->desc()); + if(column < 0) + { + ui->m_dataView->clearSelection(); + } + else + { + ui->m_dataView->selectColumn(column+1); + } + } + else if(E_Show_Curve == m_showType) + { + QCPDataSelection selection(QCPDataRange(0, 1)); + graph->setSelection(selection); + } + } + ui->plot->replot(); +} + +void CPlotWidget::updateYAxisTicker() +{ + QList graphs = ui->plot->selectedGraphs(); + if(graphs.isEmpty()) + { + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + QSharedPointer ticker(new QCPAxisTickerText); + for(int nIndex(0); nIndex <= 100; nIndex+= 20) + { + ticker->addTick(nIndex, " "); + } + ui->plot->yAxis->setTicker(ticker); + ui->plot->yAxis2->setTicker(ticker); + ui->plot->replot(QCustomPlot::rpQueuedRefresh); + return; + } + } + else + { + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + QSharedPointer ticker(new QCPAxisTickerText); + const Curve &curve = m_pTrendGraph->curve(graphs.first()->name()); + if(!curve.visible) + { + return; + } + QString strUnit = QString(); + if(!curve.unit.isEmpty()) + { + strUnit = QString("\n%1").arg(curve.unit); + } + double min = curve.hisPlotRange.min; + double max = curve.hisPlotRange.max; + double range = max - min; + int lower = ui->scaleSlider->lowerValue(); + int upper = ui->scaleSlider->upperValue(); + if(range != 0 && min == 0) + { + min -= range * abs(upper / (max * 5)); + max += range * abs(lower / (min * 5)); + } + else if(range != 0 && max == 0) + { + max += range * abs(lower / (min * 5)); + min -= range * abs(upper / (max * 5)); + } + if(range == 0) + { + ticker->addTick(50, QString::number(curve.hisPlotRange.max, 'f', 1) + strUnit); + ui->plot->yAxis->setTicker(ticker); + ui->plot->yAxis2->setTicker(ticker); + }else + { + QList ticks = regulate(min, max, 11); + if(!ticks.isEmpty()) + { + double range = curve.hisPlotRange.max - curve.hisPlotRange.min; + for(int nIndex(0); nIndex < ticks.size(); nIndex += 2) + { + ticker->addTick((ticks.at(nIndex) - curve.hisPlotRange.min) / range * 100, QString::number((ticks.at(nIndex)), 'f', 1) + strUnit); + } + ui->plot->yAxis->setTicker(ticker); + ui->plot->yAxis2->setTicker(ticker); + } + } + ui->plot->replot(QCustomPlot::rpQueuedRefresh); + return; + } + } + ui->plot->yAxis->setTicker(m_ptrPlotTricker); + ui->plot->yAxis2->setTicker(m_ptrPlotTricker); + ui->plot->replot(QCustomPlot::rpQueuedRefresh); +} + +void CPlotWidget::installMousePressEventFilter() +{ + ui->plot->installEventFilter(this); + + ui->realTime->installEventFilter(this); + ui->sec->installEventFilter(this); + ui->day->installEventFilter(this); + ui->week->installEventFilter(this); + ui->month->installEventFilter(this); + ui->quarter->installEventFilter(this); + ui->year->installEventFilter(this); + ui->adapt->installEventFilter(this); + ui->checkBox_alarmPoint->installEventFilter(this); + ui->comboBox_alarmStatus->installEventFilter(this); + ui->plotExport->installEventFilter(this); + ui->plotPrint->installEventFilter(this); + ui->prePage->installEventFilter(this); + ui->nextPage->installEventFilter(this); + ui->date->installEventFilter(this); + ui->clear->installEventFilter(this); + ui->scaleSlider->installEventFilter(this); + ui->switchBtn->installEventFilter(this); + ui->m_dataView->viewport()->installEventFilter(this); + ui->m_dataView->horizontalHeader()->viewport()->installEventFilter(this); + ui->lengedView->viewport()->installEventFilter(this); + ui->lengedView->horizontalHeader()->viewport()->installEventFilter(this); +} + +EnMeasPiontType CPlotWidget::getMeasType(const QString &type) +{ + if ("analog" == type) + { + return MPT_AI; //< 模拟量 + } + else if ("digital" == type) + { + return MPT_DI; //< 数字量 + } + else if ("mix" == type) + { + return MPT_MIX; //< 混合量 + } + else if ("accuml" == type) + { + return MPT_ACC; //< 累计(电度)量 + } + return MPT_AI; //< INVALID +} + +void CPlotWidget::setLegendCurveTransformColumnVisible(const bool &visible) +{ + Q_UNUSED(visible) + //单位未赋值,隐藏 + //ui->lengedView->setColumnHidden(CCurveLegendModel::UNIT, true); + + ui->lengedView->setColumnHidden(CCurveLegendModel::FACTOR, true); + ui->lengedView->setColumnHidden(CCurveLegendModel::OFFSET, true); +} + +QList CPlotWidget::regulate(double min, double max, int tickCount) +{ + QList ticks; + if (tickCount < 1 || max < min) + { + return ticks; + } + + double delta = max - min; + if (delta < 1.0) + { + max += (1.0 - delta) / 2.0; + min -= (1.0 - delta) / 2.0; + } + delta = max - min; + + int exp = (int)(log(delta) / log(10.0)) - 2; + double multiplier = pow(10, exp); + const double solutions[] = { 1, 2, 2.5, 5, 10, 20, 25, 50, 100, 200, 250, 500 }; + + int nIndex = 0; + for (; nIndex < (int)(sizeof(solutions) / sizeof(double)); ++nIndex) + { + double multiCal = multiplier * solutions[nIndex]; + if (((int)(delta / multiCal) + 1) <= tickCount) + { + break; + } + } + + double interval = multiplier * solutions[nIndex]; + + double startPoint = ((int)ceil(min / interval) - 1) * interval; + for (int axisIndex = 0; startPoint + interval*axisIndex <= max; axisIndex++) + { + ticks.append(startPoint + interval*axisIndex); + } + return ticks; +} + +void CPlotWidget::rescaleYAxisRange() +{ + QPair range = regulateYAxisRange(); + if(range.first == DBL_MAX || range.second == -DBL_MAX) + { +// ui->plot->yAxis->setRange(-1, 1); +// ui->plot->yAxis->rescale(true); + } + else + { + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + double factor = (range.second == range.first) ? 0 : 100. / (range.second - range.first); + double offset = -factor * range.first; + range.first = range.first * factor + offset - 1.0; + range.second = range.second * factor + offset + 1.0; + } + setSliderRange(range.first, range.second, m_isSetSliderValue); + ui->plot->yAxis->setRange(ui->scaleSlider->lowerValue(), ui->scaleSlider->upperValue()); + } + + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + updateYAxisTicker(); + } + else + { + ui->plot->replot(); + } + if(m_horizontalGraph) + { + updateHorizontalLine(); + } +} + +QPair CPlotWidget::regulateYAxisRange() +{ + const QList &curveList = m_pTrendGraph->curves(); + QPair range(DBL_MAX,-DBL_MAX); + for(int nIndex=0; nIndex max) + qSwap(min, max); + + double center = (max + min) / 2; + double offset1 = max - center; + double offset2 = center - min; + double offset = offset1 > offset2 ? offset1 : offset2; + int bs = 4; + if(offset < 1) + offset = 1; + + int low = center - bs * offset; + int up = center + bs * offset; + if(low == 0) + low = -2.0; + if(up == 0) + up = 2.0; + + if(low < range.first) + range.first = low; + if(up > range.second) + range.second = up; + } + return range; +} + +void CPlotWidget::setSliderRange(double lower, double upper, bool setValue) +{ + if(lower > upper) + qSwap(lower, upper); + + int range = upper - lower; + int lastUpper = ui->scaleSlider->upperValue(); + int lastLower = ui->scaleSlider->lowerValue(); + + int minimum; + int maximum; + if(lower == 0 && upper == 0) + { + minimum = -10; + maximum = 10; + } + else if(lower >= 0) + { + minimum = lower / 2 - range/5; + maximum = upper * 2 + range/5; + } + else if(upper <= 0) + { + minimum = lower * 2 - range/5; + maximum = upper / 2 + range/5; + } + else if(upper > 0 && lower < 0) + { + minimum = lower * 2 - range/5; + maximum = upper * 2 + range/5; + } + + if(setValue) + { + ui->scaleSlider->setMinimum(minimum); + ui->scaleSlider->setMaximum(maximum); + ui->scaleSlider->setLowerValue(lower - range/5); + ui->scaleSlider->setUpperValue(upper + range/5); + } + else + { + if(lastLower > minimum) + { + ui->scaleSlider->setMinimum(minimum); + } + if(lastUpper < maximum) + { + ui->scaleSlider->setMaximum(maximum); + } + } +} + +void CPlotWidget::setCurveStatisData(const QString &tag, EnComputeMethod method, bool reset, const double &value, const double &time) +{ + switch (method) { + case CM_MAX: + { + if(reset) + { + m_pTrendGraph->resetCurveStatisMax(tag); + } + else + { + m_pTrendGraph->setCurveStatisMax(tag, value, time); + } + break; + } + case CM_MIN: + { + if(reset) + { + m_pTrendGraph->resetCurveStatisMin(tag); + } + else + { + m_pTrendGraph->setCurveStatisMin(tag, value, time); + } + break; + } + default: + break; + } +} + +void CPlotWidget::setYAxisRange() +{ + int lower = ui->scaleSlider->lowerValue(); + int upper = ui->scaleSlider->upperValue(); + QCPRange range(lower, upper); + ui->plot->yAxis->setRange(range); + + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + updateYAxisTicker(); + } + else + { + ui->plot->replot(); + } + if(m_horizontalGraph) + { + updateHorizontalLine(); + } +} + +void CPlotWidget::sliderPressed() +{ + m_isSetSliderValue = false; +} + +void CPlotWidget::sliderDoubleClick(int x, int y) +{ + emit sigSliderRangeSet(x, y, + ui->scaleSlider->lowerValue(), + ui->scaleSlider->upperValue(), + ui->scaleSlider->minimum(), + ui->scaleSlider->maximum()); +} + +bool CPlotWidget::isMutation(const double &preValue, const double &curValue) +{ + if(preValue == 0) + { + return true; + } + + double coeff = qAbs(0.5 * preValue); + + if(qAbs(curValue-preValue) > coeff) + { + return true; + } + return false; +} + +template +void CPlotWidget::updateHisData(std::vector *vecMpKey, std::vector*> *vecResult, + std::vector > &vecRange, std::vector< QSharedPointer > &vecContainer, + double lower, double upper, + bool isAddVirtualPoint, int nGroupBySec) +{ + int nMaxIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000 + nGroupBySec * 1000; + typename std::vector *>::const_iterator it = vecResult->begin(); + while(it != vecResult->end()) + { + QSharedPointer range(new Range()); + QSharedPointer container(new QCPGraphDataContainer()); + vecRange.push_back(range); + vecContainer.push_back(container); + + //< Valid Check + std::vector<_Tp> * vecPoint = *it; + if(vecPoint->empty()) + { + ++it; + continue; + } + + //< Graph Bound + _Tp left; + left.m_nTime = lower; + typename std::vector<_Tp>::const_iterator varHisLeft = std::upper_bound((*vecPoint).begin(), (*vecPoint).end(), left, compareVarPoint<_Tp>); + if(varHisLeft != (*vecPoint).begin() && varHisLeft != (*vecPoint).end()) + { + --varHisLeft; + } + + _Tp right; + right.m_nTime = upper; + typename std::vector<_Tp>::const_iterator varHisRight = std::lower_bound((*vecPoint).begin(), (*vecPoint).end(), right, compareVarPoint<_Tp>); + if(varHisRight == (*vecPoint).end()) + { + varHisRight = (*vecPoint).end() - 1; + } + ++varHisRight; + + //< Prepare Work(used: record Interval) + E_Point_Type pointType; + switch (vecMpKey->at(it - vecResult->begin()).m_enType) + { + case MPT_AI:{ + pointType = E_ANALOG; + break; + } + case MPT_DI:{ + pointType = E_DIGITAL; + break; + } + case MPT_MIX:{ + pointType = E_MIX; + break; + } + case MPT_ACC:{ + pointType = E_ACCUML; + break; + } + default: + break; + } + qint64 lastTimeStamp = -1; + double lastValue = qSqrt(-1.); + int lastStatus = 0; + + //< Handle Data + typename std::vector<_Tp>::const_iterator pt = varHisLeft; + while(pt != varHisRight) + { + double value = qSqrt(-1.); + if (typeid(boost::int32_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + else if (typeid(boost::float64_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + + if(std::isnan(value)) + { + ++pt; + continue; + } + + if(value > range->max) + { + range->max = value; + } + if(value < range->min) + { + range->min = value; + } + + qint64 timeStamp = pt->m_nTime; + int status = CTrendInfoManage::instance()->getInvalidStatus(pointType, pt->m_nStatus); + if(lastTimeStamp > 0 && lastTimeStamp + nMaxIntervalSecs < timeStamp) + { + container->add(QCPGraphData(lastTimeStamp+nGroupBySec*1000, qSqrt(-1.), lastStatus)); + } + else if(lastTimeStamp > 0 && isMutation(lastValue, value) && isAddVirtualPoint) + { + container->add(QCPGraphData(timeStamp, lastValue, lastStatus)); + } + container->add(QCPGraphData(timeStamp, value, status)); + lastTimeStamp = timeStamp; + lastValue = value; + lastStatus = status; + ++pt; + } + ++it; + } +} + +template +bool CPlotWidget::checkStatus(const _Tp &var, const int &nInvalid) +{ + Q_UNUSED(var); + Q_UNUSED(nInvalid); + return true; +} + +template +bool CPlotWidget::checkStatus(const SVarHisSamplePoint &var, const int &nInvalid) +{ + return nInvalid == (var.m_nStatus & nInvalid); +} + +void CPlotWidget::slotDateTimeChanged(const QDateTime &dateTime) +{ + m_isSetSliderValue = true; + QPair range = getFatureDataTime(m_type, dateTime); + ui->plot->xAxis->blockSignals(true); + ui->plot->xAxis->setRange(range.first, range.second); + ui->plot->xAxis->blockSignals(false); + + updateCurves(); +} + +void CPlotWidget::updateGroupQuery(const QString &tag) +{ + if(tag == "curve.tag") + return; + + QMap::iterator iter = m_groupTagMap.begin(); + while(iter != m_groupTagMap.end()) + { + if(iter.value().contains(tag)) + return; + iter++; + } + QString device = tag.section(".", 0, 1); + QString deviceGroup = CTrendInfoManage::instance()->queryDeviceGroup(device); + if(deviceGroup.isEmpty()) + { + ui->plot->replot(QCustomPlot::rpQueuedReplot); + return; + } + QStringList tagList = CTrendInfoManage::instance()->queryTagListDevGroup(deviceGroup); + if(!m_groupTagMap.keys().contains(deviceGroup)) + { + m_groupTagMap.insert(deviceGroup,tagList); + groupQueryHistoryEvent(); + } +} + +void CPlotWidget::removeCurvesGroupQuery() +{ + m_groupTagMap.clear(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(ui->plot->graph(nIndex)->visible() == true) + { + updateGroupQuery(ui->plot->graph(nIndex)->name()); + } + } +} + +void CPlotWidget::groupQueryHistoryEvent() +{ + if(m_type == E_Trend_RealTime || m_groupTagMap.isEmpty() || NULL == m_horizontalGraph) + { + ui->plot->clearItems(); + m_listTracer.clear(); + return; + } + + std::vector * vecMpKey = new std::vector(); + QMap::iterator iter = m_groupTagMap.begin(); + while(iter != m_groupTagMap.end()) + { + foreach (QString tagName, iter.value()) { + SMeasPointKey key; + std::string tmp = tagName.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(CTrendInfoManage::instance()->getTagType(tagName)); + vecMpKey->push_back(key); + } + iter++; + } + + int ByMinute = currentGroupByMinute(); + int g_groupByDuration = ByMinute * 60; + + if(!m_pHisDataManage->isTsdbExuting()) + { + if(g_groupByDuration == 0) + { + emit sigQueryHistoryEvent(vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, kbd_dbms::CM_NULL, g_groupByDuration); + } + else + { + emit sigQueryHistoryEvent(vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, kbd_dbms::CM_SAMPLE, g_groupByDuration); + } + } + else + { + if(g_groupByDuration == 0) + { + m_pHisDataManage->postTsdbCommandQueue(E_EVENTPOINT, vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, g_groupByDuration, + std::vector{kbd_dbms::CM_NULL}); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(E_EVENTPOINT, vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, g_groupByDuration, + std::vector{kbd_dbms::CM_SAMPLE}); + } + } + + ui->plot->replot(); +} + +void CPlotWidget::initAlarmStatusFilter() +{ + m_pListWidget = new CMyListWidget(this); + m_pLineEdit = new QLineEdit(this); + QMap > m_alarmShowStatus = CTrendInfoManage::instance()->getAlarmShowStatus(); + m_strText = ""; + for(QMap >::const_iterator it = m_alarmShowStatus.constBegin();it != m_alarmShowStatus.constEnd();++it) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget); + pItem->setData(Qt::UserRole, it.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it.value().first); + m_pListWidget->addItem(pItem); + m_pListWidget->setItemWidget(pItem, pCheckBox); + if(it.value().second) + { + pCheckBox->setCheckState(Qt::Checked); + m_alarmStatusList.append(it.key()); + m_strText += pCheckBox->text(); + m_strText += " "; + } + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(alarmStatusChanged(int))); + } + ui->comboBox_alarmStatus->setModel(m_pListWidget->model()); + ui->comboBox_alarmStatus->setView(m_pListWidget); + ui->comboBox_alarmStatus->setLineEdit(m_pLineEdit); + if(m_strText == "") + { + m_strText = tr("请选择告警状态"); + } + m_pLineEdit->setText(m_strText); + m_pLineEdit->setReadOnly(true); + connect(m_pLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(alarmTextChanged(const QString &))); +} + +void CPlotWidget::addHorizontalLine() +{ + if(m_horizontalGraph) + { + m_horizontalGraph = NULL; + m_pTrendGraph->removeCurve("curve.tag"); + } + QRect rect = ui->plot->axisRect()->rect(); + double lower = ui->plot->yAxis->pixelToCoord(rect.y() + rect.height() - 6); + double first = ui->plot->xAxis->range().lower; + double final = ui->plot->xAxis->range().upper; + QVector xLineVector,yLineVector; + QVector statusVector; + xLineVector.append(first); + xLineVector.append(final); + yLineVector.append(lower); + yLineVector.append(lower); + statusVector.append(1); + statusVector.append(1); + m_horizontalGraph = ui->plot->addGraph(); + m_horizontalGraph->setData(xLineVector,yLineVector,statusVector); + + m_horizontalGraph->setName("curve.tag"); + m_horizontalGraph->removeFromLegend(); + horizontalCurve.tag = "curve.tag"; + horizontalCurve.visible = false; + m_pTrendGraph->addCurve(horizontalCurve); + m_horizontalGraph->setVisible(false); + + groupQueryHistoryEvent(); + ui->plot->replot(); +} + +void CPlotWidget::updateHorizontalLine() +{ + if(m_type == E_Trend_RealTime) + { + return; + } + QRect rect = ui->plot->axisRect()->rect(); + double lower = ui->plot->yAxis->pixelToCoord(rect.y() + rect.height() - 6); + double first = ui->plot->xAxis->range().lower; + double final = ui->plot->xAxis->range().upper; + QVector xLineVector,yLineVector; + QVector statusVector; + xLineVector.append(first); + xLineVector.append(final); + yLineVector.append(lower); + yLineVector.append(lower); + statusVector.append(1); + statusVector.append(1); + m_horizontalGraph->setData(xLineVector,yLineVector,statusVector); + m_horizontalGraph->setVisible(false); + groupQueryHistoryEvent(); + m_horizontalGraph->removeFromLegend(ui->plot->legend); + ui->plot->replot(); +} + +void CPlotWidget::setAllLengedShow() +{ + int count = ui->lengedView->model()->rowCount(); + for(int nIndex=0; nIndexlengedView->setRowHidden(nIndex, false); + } +} + +QString CPlotWidget::hexTo26(int number) +{ + int p = 26; //进制 + int c = 0; //取余后的数字 + QString temp; + + while (true) { + c = number % p; + number = number / p; + if(number != 0) + { + temp.prepend(QString(QChar(0x41 + c))); + } + else + { + temp.prepend(QString(QChar(0x41 + c))); + break; + } + number--; + } + + return temp; +} + +void CPlotWidget::resetCurveData(const QMap > &dataMap, const QStringList &headerList, bool ascs) +{ + if(E_Show_Table != m_showType) + { + return; + } + int limit = 0; + if(E_Trend_His_Custom == m_type) + { + limit = CUSTOM_MAX_RECORD; + } + m_pTableDataModel->setCurveData(dataMap, headerList, ascs, limit); +} + +void CPlotWidget::enableSearch(bool enable) +{ + if(enable) + { + ui->customSearch->setEnabled(true); + ui->customSearch->setText(tr("查询")); + } + else + { + ui->customSearch->setEnabled(false); + ui->customSearch->setText(tr("查询中")); + } +} + +void CPlotWidget::alarmTextChanged(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit->setText(m_strText); +} + +void CPlotWidget::alarmStatusChanged(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_alarmStatusList.clear(); + int nCount = m_pListWidget->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget->item(i); + QWidget *pWidget = m_pListWidget->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + if(pCheckBox->text() == QObject::tr("其他")) + { + QMap m_alarmOtherStatus = CTrendInfoManage::instance()->getAlarmOtherStatus(); + for(QMap::iterator it = m_alarmOtherStatus.begin();it != m_alarmOtherStatus.end();++it) + { + int nData = it.key(); + m_alarmStatusList.append(nData); + } + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + } + else + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_alarmStatusList.append(nData); + } + } + } + if (!strText.isEmpty()) + { + m_strText = strText; + m_pLineEdit->setText(strText); + } + else + { + m_pLineEdit->clear(); + m_strText = tr("请选择告警状态"); + m_pLineEdit->setText(tr("请选择告警状态")); + } + groupQueryHistoryEvent(); +} + +void CPlotWidget::alarmPointCheckStateChanged() +{ + setAllLengedShow(); + if(ui->checkBox_alarmPoint->isChecked()) + { + addHorizontalLine(); + m_pLengedModel->setTrendGraph(m_pTrendGraph); + int mIndex = m_pTrendGraph->index("curve.tag"); + if(mIndex != -1) + { + ui->lengedView->setRowHidden(mIndex,true); + } + }else + { + if(m_horizontalGraph) + { + m_pTrendGraph->removeCurve("curve.tag"); + ui->plot->clearItems(); + m_listTracer.clear(); + ui->plot->removeGraph(m_horizontalGraph); + m_horizontalGraph = NULL; + m_pLengedModel->setTrendGraph(m_pTrendGraph); + ui->plot->replot(); + } + } +} + +void CPlotWidget::showTypeChanged(bool checked) +{ + m_pTableDataModel->clear(); + if(checked) + { + m_showType = E_Show_Table; + + } + else + { + m_showType = E_Show_Curve; + } + ui->plot->setVisible(!checked); + ui->widget->setVisible(!checked); + ui->m_dataView->setVisible(checked); + ui->plotExport->setVisible(checked); + ui->plotPrint->setVisible(!checked); + ui->customSearch->setVisible(checked); + + if(m_type == E_Trend_RealTime) + { + ui->adapt->setVisible(false); + ui->checkBox_alarmPoint->setVisible(false); + ui->comboBox_alarmStatus->setVisible(false); + /*if(E_Show_Table == m_showType) + { + updateRealTimeTableData(); + }*/ + } + else + { + if(m_isAdaptShow) + { + ui->adapt->setVisible(!checked); + } + if(m_isAlarmShow) + { + ui->checkBox_alarmPoint->setVisible(!checked); + ui->comboBox_alarmStatus->setVisible(!checked); + } + } + + + updateRealTimeTableData(); + + updateCurves(); + + +} + +void CPlotWidget::slotStartDateChanged(const QDateTime &dateTime) +{ + if(ui->endData->dateTime() > dateTime) + { + ui->plot->xAxis->setRangeLower(dateTime.toMSecsSinceEpoch()); + } + else + { + int sec = ui->interval->currentData().toInt(); + if(sec < 600) + { + sec = 600; + } + ui->startData->setDateTime(ui->endData->dateTime().addSecs(-sec)); + } + + if(E_Show_Curve == m_showType) + { + slotCustomSearch(); + } +} + +void CPlotWidget::slotEndDateChanged(const QDateTime &dateTime) +{ + if(ui->startData->dateTime() < dateTime) + { + ui->plot->xAxis->setRangeUpper(dateTime.toMSecsSinceEpoch()); + } + else + { + int sec = ui->interval->currentData().toInt(); + if(sec < 600) + { + sec = 600; + } + ui->endData->setDateTime(ui->startData->dateTime().addSecs(sec)); + } + + if(E_Show_Curve == m_showType) + { + slotCustomSearch(); + } +} + +void CPlotWidget::slotIntervalChanged(const QString &text) +{ + Q_UNUSED(text) + + if(E_Show_Curve == m_showType) + { + slotCustomSearch(); + } +} + +void CPlotWidget::slotCustomSearch(bool isForce) +{ + if(!ui->plot->graphCount()) + { + return; + } + if(!isForce && !ui->customSearch->isEnabled()) + { + return; + } + + double lower = ui->startData->dateTime().toMSecsSinceEpoch(); + double upper = ui->endData->dateTime().toMSecsSinceEpoch(); + if(lower > upper) + { + QMessageBox::information(this,tr("提示"),tr("查询开始时间不能大于结束时间!"),QMessageBox::Ok); + return; + } + int sec = ui->interval->currentData().toInt(); + if((upper - lower) < sec*1000) + { + QMessageBox::information(this,tr("提示"),tr("开始时间和结束时间之差不能小于查询时间间隔!"),QMessageBox::Ok); + return; + } + + enableSearch(false); + std::vector vecMethod{kbd_dbms::CM_MAX, kbd_dbms::CM_MIN}; + updateComputeValue(lower, upper, vecMethod); + std::vector * vecMpKey = new std::vector(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) + { + const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); + SMeasPointKey key; + std::string tmp = curve.tag.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(curve.type); + vecMpKey->push_back(key); + } + + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; +// if(!m_pHisDataManage->isTsdbExuting()) +// { +// emit sigQueryHistoryPolymericData(vecMpKey, lower + nIntervalSecs, upper - nIntervalSecs, sec, kbd_dbms::CM_FIRST); +// } +// else + { + //< 添加多条曲线时,可能存在顺序混乱,导致显示列缺失,因此都使用post的方式查询 + m_pHisDataManage->postTsdbCommandQueue(E_POLYMERIC, vecMpKey, lower + nIntervalSecs, upper - nIntervalSecs, sec, std::vector{kbd_dbms::CM_FIRST}); + } +} + +void CPlotWidget::slotEnableSearch(bool enable) +{ + enableSearch(!enable); +} diff --git a/product/src/gui/plugin/TrendCurves/CPlotWidget.h b/product/src/gui/plugin/TrendCurves/CPlotWidget.h index 98a1ab75..c3ce1a66 100644 --- a/product/src/gui/plugin/TrendCurves/CPlotWidget.h +++ b/product/src/gui/plugin/TrendCurves/CPlotWidget.h @@ -1,336 +1,336 @@ -#ifndef CPLOTWIDGET_H -#define CPLOTWIDGET_H - -#include -#include "CTrendGraph.h" -#include "CHisDataManage.h" -#include "plot/qcustomplot.h" -#include "CTrendInfoManage.h" -#include "dbms/tsdb_api/TsdbApi.h" -#include "dbms/tsdb_api/CTsdbConn.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "dbms/db_his_query_api/DbHisQueryApi.h" - -#define CUSTOM_MAX_RECORD 10000; - -namespace Ui { -class CPlotWidget; -} - -class QTimer; -class CToolTip; -class QCustomPlot; -class QCPItemText; -class QCPItemTracer; -class QAbstractButton; -class CHisDataManage; -class CHisEventManage; -class CCurveLegendModel; -class CTableDataModel; -class CRealTimeDataCollect; - -enum E_Trend_Type -{ - E_Trend_Invalid = 0, - E_Trend_RealTime = 1, - E_Trend_His_Minute = 2, - E_Trend_His_Hour = 3, - E_Trend_His_Day = 4, - E_Trend_His_Week = 5, - E_Trend_His_Month = 6, - E_Trend_His_Quarter = 7, - E_Trend_His_Year = 8, - E_Trend_His_Custom = 9 -}; - -enum E_Show_Type -{ - E_Show_Curve = 0, - E_Show_Table = 1 -}; - -class CPlotWidget : public QWidget -{ - Q_OBJECT - Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) - Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) - Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) - Q_PROPERTY(QColor plotZeroLineColor READ plotZeroLineColor WRITE setPlotZeroLineColor) - Q_PROPERTY(QColor plotTickPen READ plotTickPen WRITE setPlotTickPen) - Q_PROPERTY(QPixmap plotBackImage READ plotBackImage WRITE setPlotBackImage) - -public: - explicit CPlotWidget(QWidget *parent = 0); - ~CPlotWidget(); - - void initialize(); - - void setTitle(const QString &title); - - void setTitleVisible(bool visible); - - void setTickCount(const int &count); - - void insertTag(const QString &tag, const bool &resetTitle = true); - - void insertTag(const QStringList &listTag, const bool &resetTitle = true); - - void removeTag(const QString &tag, const bool &resetTitle = true); - - void setDisplayTime(const int &trendType, const double &dateTime, const bool &alarm = true); - - void setTagVisible(const QString &tag, const bool &visible); - - void setDateButtonVisible(const int &button, const bool &visible); - - void setClearVisible(bool visible); - - void setAdaptVisible(bool visible); - - void setAlarmPointVisible(bool visible); - - void insertCurve(Curve curve); - - void clear(bool clearTitle = false); - - void setWindowMode(const bool &isWindowMode); - - void setColorList(const QStringList &listColor); - - QColor plotBackgroundColor(); - void setPlotBackgroundColor(const QColor &color); - - QPixmap plotBackImage(); - void setPlotBackImage(const QPixmap &pm); - - QColor plotTickColor(); - void setPlotTickColor(const QColor &color); - - QColor plotGridColor(); - void setPlotGridColor(const QColor &color); - - QColor plotZeroLineColor(); - void setPlotZeroLineColor(const QColor &color); - - QColor plotTickPen(); - void setPlotTickPen(const QColor &color); - -signals: - void clearCurve(); - void queryHisEvent(const QString &tag, const int &type, const qint64 &time); - void collectGraph(const QString &title, const CTrendGraph &graph); - void updateTagCheckState(const QString &tag, const bool &outOfRange); - void releaseHisDataThread(); - void releaseHisEventThread(); - - void sigQueryHistoryOriginalData(std::vector *vecMpKey, - double lower, double upper, - E_Data_Type type = E_HISTORY); - - void sigQueryHistoryPolymericData(std::vector *vecMpKey, - double lower, double upper, int nGroupByMinute, kbd_dbms::EnComputeMethod method); - - void sigQueryHistoryComputeData(std::vector *vecMpKey, - double lower, double upper, - std::vector method); - - void sigQueryHistoryEvent(std::vector *vecMpKey, - double lower, double upper, - kbd_dbms::EnComputeMethod enCM, - int nGroupByMinute); - void sigAddCollect(int x, int y); - void sigHideCollect(); - - void sigSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum); - void sigHideSliderSet(); - -protected: - void resizeEvent(QResizeEvent *event); - bool eventFilter(QObject *object, QEvent *event); - void updateLengedColumnWidth(); - void updateCurveSelectionColor(QCPGraph * graph); - -public slots: - void slotCollectGraph(const QString &text); - void slotSliderRangeChange(int lower, int upper); - -private slots: - void realTimeElapsed(); - - void recvRealTimeTrendData(const QString &tagName, QVariant value, int status, E_Point_Type pointType); - - void updateRealTimeTableData(); - - void plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange); - - void updateTrendShowMode(int nIndex, bool updateXAxisRange = true); - - void updateComputeValue(double lower, double upper, std::vector vecMethod); - - void updateCurves(); - - void updateRealTimeCurveRecord(); - - void updateHistoryCurveRecord(double lower, double upper); - - void updateHisOriginalData(std::vector *vecMpKey, - std::vector *> *vecResult, - E_Data_Type type = E_HISTORY); - - void updateHisPolymericData(std::vector *vecMpKey, - std::vector *> *vecResult, - int nGroupBySec); - - void updateHisComputeData(std::vector *vecMpKey, - std::vector *> *> > cmResult); - - void updateHistoryGraph(std::vector *vecMpKey, - std::vector< QSharedPointer > &vecContainer, - std::vector< QSharedPointer > &vecRange); - - void updateHistoryData(std::vector *vecMpKey, - std::vector< QSharedPointer > &vecContainer, - std::vector< QSharedPointer > &vecRange); - - void updateCurveHisData(double lower, double upper, - QCPGraph * graph, int index, - QSharedPointer container, - QSharedPointer range); - - void updatePhaseTracer(std::vector *vecMpKey, - std::vector *> *vecResult); - void updateGraphEvent(const qint64 &time, QStringList contents); - - void updateAxisFormat(bool updateXAxisRange); - QPair getFatureDataTime(E_Trend_Type type, QDateTime curTime = QDateTime()); - void updateAdaptState(bool isAdapt); - void addCollect(); - void slotPrint(); - void slotExport(); - void prePage(); - void nextPage(); - - void graphVisibleChanged(const bool &check); - void graphPropertyChanged(); - void deleteCurrentGraph(); - void jumpToMaxTime(const double &time); - void jumpToMinTime(const double &time); - void updateLengedValue(const double &dateTime); - void graphSelectionChanged(bool select); - void tableSelectionChanged(const QModelIndex &index); - void updateGraphSelection(); - void updateYAxisTicker(); - void setYAxisRange(); - void sliderPressed(); - void sliderDoubleClick(int x, int y); - - void slotDateTimeChanged(const QDateTime &dateTime); - - void alarmTextChanged(const QString &text); - void alarmStatusChanged(int state); - void alarmPointCheckStateChanged(); - - void showTypeChanged(bool checked); - - void slotStartDateChanged(const QDateTime &dateTime); - void slotEndDateChanged(const QDateTime &dateTime); - void slotIntervalChanged(const QString &text); - void slotCustomSearch(bool isForce = false); - void slotEnableSearch(bool enable); - -private: - void installMousePressEventFilter(); - - kbd_dbms::EnMeasPiontType getMeasType(const QString &type); - - E_Trend_Type getRangeType(const QCPRange &range); - - void updateGraphTitle(int nIndex); - - int currentGroupByMinute(); - - void setLegendCurveTransformColumnVisible(const bool &visible); - - QList regulate(double min, double max, int tickCount); - - void rescaleYAxisRange(); - QPair regulateYAxisRange(); - void setSliderRange(double lower, double upper, bool setValue = false); - - template - void updateHisData(std::vector *vecMpKey, - std::vector*> *vecResult, - std::vector< QSharedPointer > &vecRange, - std::vector< QSharedPointer > &vecContainer, - double lower, double upper, - bool isAddVirtualPoint = false, - int nGroupBySec = 0); - - template - bool checkStatus(const _Tp &var, const int &nInvalid); - - template - bool checkStatus(const kbd_dbms::SVarHisSamplePoint &var, const int &nInvalid); - - void setCurveStatisData(const QString &tag, kbd_dbms::EnComputeMethod method, bool reset, const double &value = 0, const double &time = 0); - - bool isMutation(const double &preValue, const double &curValue); - - void updateGroupQuery(const QString &tag); - void groupQueryHistoryEvent(); - void removeCurvesGroupQuery(); - - void initAlarmStatusFilter(); - void addHorizontalLine(); - void updateHorizontalLine(); - void setAllLengedShow(); - - QString hexTo26(int number); - void resetCurveData(const QMap>& dataMap, const QStringList& headerList, bool ascs = true); - void enableSearch(bool enable); - -private: - Ui::CPlotWidget *ui; - E_Trend_Type m_type; - E_Show_Type m_showType; - bool m_bHisAdaption; - QButtonGroup * m_TrendTypeButton; - CCurveLegendModel * m_pLengedModel; - CTableDataModel * m_pTableDataModel; - QTimer * m_pTimer; - CTrendGraph * m_pTrendGraph; - QCPItemText * m_trendTitle; - double m_rtRange; - kbd_service::CDpcdaForApp * m_pDpcdaForApp; - CRealTimeDataCollect * m_rtDataCollect; - QSharedPointer m_ptrPlotTricker; - QThread * m_pHisDataThread; - CHisDataManage * m_pHisDataManage; - QThread * m_pHisEventThread; - CHisEventManage * m_pHisEventManage; - - QPixmap m_plotBackImage; - QColor m_plotBackgroundColor; - QColor m_plotTickColor; - QColor m_plotGridColor; - QColor m_plotZeroLineColor; - QColor m_plotTickPen; - QList m_listTracer; - QList m_listColor; - - QListWidget *m_pListWidget; - QLineEdit *m_pLineEdit; - QList m_alarmStatusList; - QString m_strText; - Curve horizontalCurve; - QCPGraph * m_horizontalGraph; - QMap m_groupTagMap; - bool m_numWarnFlag; - bool m_isWindowMode; - bool m_isSetSliderValue; - bool m_isTooltip; - bool m_isAdaptShow; - bool m_isAlarmShow; -}; - -#endif // CPLOTWIDGET_H +#ifndef CPLOTWIDGET_H +#define CPLOTWIDGET_H + +#include +#include "CTrendGraph.h" +#include "CHisDataManage.h" +#include "plot/qcustomplot.h" +#include "CTrendInfoManage.h" +#include "dbms/tsdb_api/TsdbApi.h" +#include "dbms/tsdb_api/CTsdbConn.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "dbms/db_his_query_api/DbHisQueryApi.h" + +#define CUSTOM_MAX_RECORD 10000; + +namespace Ui { +class CPlotWidget; +} + +class QTimer; +class CToolTip; +class QCustomPlot; +class QCPItemText; +class QCPItemTracer; +class QAbstractButton; +class CHisDataManage; +class CHisEventManage; +class CCurveLegendModel; +class CTableDataModel; +class CRealTimeDataCollect; + +enum E_Trend_Type +{ + E_Trend_Invalid = 0, + E_Trend_RealTime = 1, + E_Trend_His_Minute = 2, + E_Trend_His_Hour = 3, + E_Trend_His_Day = 4, + E_Trend_His_Week = 5, + E_Trend_His_Month = 6, + E_Trend_His_Quarter = 7, + E_Trend_His_Year = 8, + E_Trend_His_Custom = 9 +}; + +enum E_Show_Type +{ + E_Show_Curve = 0, + E_Show_Table = 1 +}; + +class CPlotWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) + Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) + Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) + Q_PROPERTY(QColor plotZeroLineColor READ plotZeroLineColor WRITE setPlotZeroLineColor) + Q_PROPERTY(QColor plotTickPen READ plotTickPen WRITE setPlotTickPen) + Q_PROPERTY(QPixmap plotBackImage READ plotBackImage WRITE setPlotBackImage) + +public: + explicit CPlotWidget(QWidget *parent = 0); + ~CPlotWidget(); + + void initialize(); + + void setTitle(const QString &title); + + void setTitleVisible(bool visible); + + void setTickCount(const int &count); + + void insertTag(const QString &tag, const bool &resetTitle = true); + + void insertTag(const QStringList &listTag, const bool &resetTitle = true); + + void removeTag(const QString &tag, const bool &resetTitle = true); + + void setDisplayTime(const int &trendType, const double &dateTime, const bool &alarm = true); + + void setTagVisible(const QString &tag, const bool &visible); + + void setDateButtonVisible(const int &button, const bool &visible); + + void setClearVisible(bool visible); + + void setAdaptVisible(bool visible); + + void setAlarmPointVisible(bool visible); + + void insertCurve(Curve curve); + + void clear(bool clearTitle = false); + + void setWindowMode(const bool &isWindowMode); + + void setColorList(const QStringList &listColor); + + QColor plotBackgroundColor(); + void setPlotBackgroundColor(const QColor &color); + + QPixmap plotBackImage(); + void setPlotBackImage(const QPixmap &pm); + + QColor plotTickColor(); + void setPlotTickColor(const QColor &color); + + QColor plotGridColor(); + void setPlotGridColor(const QColor &color); + + QColor plotZeroLineColor(); + void setPlotZeroLineColor(const QColor &color); + + QColor plotTickPen(); + void setPlotTickPen(const QColor &color); + +signals: + void clearCurve(); + void queryHisEvent(const QString &tag, const int &type, const qint64 &time); + void collectGraph(const QString &title, const CTrendGraph &graph); + void updateTagCheckState(const QString &tag, const bool &outOfRange); + void releaseHisDataThread(); + void releaseHisEventThread(); + + void sigQueryHistoryOriginalData(std::vector *vecMpKey, + double lower, double upper, + E_Data_Type type = E_HISTORY); + + void sigQueryHistoryPolymericData(std::vector *vecMpKey, + double lower, double upper, int nGroupByMinute, kbd_dbms::EnComputeMethod method); + + void sigQueryHistoryComputeData(std::vector *vecMpKey, + double lower, double upper, + std::vector method); + + void sigQueryHistoryEvent(std::vector *vecMpKey, + double lower, double upper, + kbd_dbms::EnComputeMethod enCM, + int nGroupByMinute); + void sigAddCollect(int x, int y); + void sigHideCollect(); + + void sigSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum); + void sigHideSliderSet(); + +protected: + void resizeEvent(QResizeEvent *event); + bool eventFilter(QObject *object, QEvent *event); + void updateLengedColumnWidth(); + void updateCurveSelectionColor(QCPGraph * graph); + +public slots: + void slotCollectGraph(const QString &text); + void slotSliderRangeChange(int lower, int upper); + +private slots: + void realTimeElapsed(); + + void recvRealTimeTrendData(const QString &tagName, QVariant value, int status, E_Point_Type pointType); + + void updateRealTimeTableData(); + + void plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + + void updateTrendShowMode(int nIndex, bool updateXAxisRange = true); + + void updateComputeValue(double lower, double upper, std::vector vecMethod); + + void updateCurves(); + + void updateRealTimeCurveRecord(); + + void updateHistoryCurveRecord(double lower, double upper); + + void updateHisOriginalData(std::vector *vecMpKey, + std::vector *> *vecResult, + E_Data_Type type = E_HISTORY); + + void updateHisPolymericData(std::vector *vecMpKey, + std::vector *> *vecResult, + int nGroupBySec); + + void updateHisComputeData(std::vector *vecMpKey, + std::vector *> *> > cmResult); + + void updateHistoryGraph(std::vector *vecMpKey, + std::vector< QSharedPointer > &vecContainer, + std::vector< QSharedPointer > &vecRange); + + void updateHistoryData(std::vector *vecMpKey, + std::vector< QSharedPointer > &vecContainer, + std::vector< QSharedPointer > &vecRange); + + void updateCurveHisData(double lower, double upper, + QCPGraph * graph, int index, + QSharedPointer container, + QSharedPointer range); + + void updatePhaseTracer(std::vector *vecMpKey, + std::vector *> *vecResult); + void updateGraphEvent(const qint64 &time, QStringList contents); + + void updateAxisFormat(bool updateXAxisRange); + QPair getFatureDataTime(E_Trend_Type type, QDateTime curTime = QDateTime()); + void updateAdaptState(bool isAdapt); + void addCollect(); + void slotPrint(); + void slotExport(); + void prePage(); + void nextPage(); + + void graphVisibleChanged(const bool &check); + void graphPropertyChanged(); + void deleteCurrentGraph(); + void jumpToMaxTime(const double &time); + void jumpToMinTime(const double &time); + void updateLengedValue(const double &dateTime); + void graphSelectionChanged(bool select); + void tableSelectionChanged(const QModelIndex &index); + void updateGraphSelection(); + void updateYAxisTicker(); + void setYAxisRange(); + void sliderPressed(); + void sliderDoubleClick(int x, int y); + + void slotDateTimeChanged(const QDateTime &dateTime); + + void alarmTextChanged(const QString &text); + void alarmStatusChanged(int state); + void alarmPointCheckStateChanged(); + + void showTypeChanged(bool checked); + + void slotStartDateChanged(const QDateTime &dateTime); + void slotEndDateChanged(const QDateTime &dateTime); + void slotIntervalChanged(const QString &text); + void slotCustomSearch(bool isForce = false); + void slotEnableSearch(bool enable); + +private: + void installMousePressEventFilter(); + + kbd_dbms::EnMeasPiontType getMeasType(const QString &type); + + E_Trend_Type getRangeType(const QCPRange &range); + + void updateGraphTitle(int nIndex); + + int currentGroupByMinute(); + + void setLegendCurveTransformColumnVisible(const bool &visible); + + QList regulate(double min, double max, int tickCount); + + void rescaleYAxisRange(); + QPair regulateYAxisRange(); + void setSliderRange(double lower, double upper, bool setValue = false); + + template + void updateHisData(std::vector *vecMpKey, + std::vector*> *vecResult, + std::vector< QSharedPointer > &vecRange, + std::vector< QSharedPointer > &vecContainer, + double lower, double upper, + bool isAddVirtualPoint = false, + int nGroupBySec = 0); + + template + bool checkStatus(const _Tp &var, const int &nInvalid); + + template + bool checkStatus(const kbd_dbms::SVarHisSamplePoint &var, const int &nInvalid); + + void setCurveStatisData(const QString &tag, kbd_dbms::EnComputeMethod method, bool reset, const double &value = 0, const double &time = 0); + + bool isMutation(const double &preValue, const double &curValue); + + void updateGroupQuery(const QString &tag); + void groupQueryHistoryEvent(); + void removeCurvesGroupQuery(); + + void initAlarmStatusFilter(); + void addHorizontalLine(); + void updateHorizontalLine(); + void setAllLengedShow(); + + QString hexTo26(int number); + void resetCurveData(const QMap>& dataMap, const QStringList& headerList, bool ascs = true); + void enableSearch(bool enable); + +private: + Ui::CPlotWidget *ui; + E_Trend_Type m_type; + E_Show_Type m_showType; + bool m_bHisAdaption; + QButtonGroup * m_TrendTypeButton; + CCurveLegendModel * m_pLengedModel; + CTableDataModel * m_pTableDataModel; + QTimer * m_pTimer; + CTrendGraph * m_pTrendGraph; + QCPItemText * m_trendTitle; + double m_rtRange; + kbd_service::CDpcdaForApp * m_pDpcdaForApp; + CRealTimeDataCollect * m_rtDataCollect; + QSharedPointer m_ptrPlotTricker; + QThread * m_pHisDataThread; + CHisDataManage * m_pHisDataManage; + QThread * m_pHisEventThread; + CHisEventManage * m_pHisEventManage; + + QPixmap m_plotBackImage; + QColor m_plotBackgroundColor; + QColor m_plotTickColor; + QColor m_plotGridColor; + QColor m_plotZeroLineColor; + QColor m_plotTickPen; + QList m_listTracer; + QList m_listColor; + + QListWidget *m_pListWidget; + QLineEdit *m_pLineEdit; + QList m_alarmStatusList; + QString m_strText; + Curve horizontalCurve; + QCPGraph * m_horizontalGraph; + QMap m_groupTagMap; + bool m_numWarnFlag; + bool m_isWindowMode; + bool m_isSetSliderValue; + bool m_isTooltip; + bool m_isAdaptShow; + bool m_isAlarmShow; +}; + +#endif // CPLOTWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves/CPlotWidget.ui b/product/src/gui/plugin/TrendCurves/CPlotWidget.ui index a2451f02..82ecce4d 100644 --- a/product/src/gui/plugin/TrendCurves/CPlotWidget.ui +++ b/product/src/gui/plugin/TrendCurves/CPlotWidget.ui @@ -1,768 +1,768 @@ - - - CPlotWidget - - - - 0 - 0 - 1469 - 558 - - - - Form - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 16777215 - 150 - - - - false - - - false - - - - - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 3 - - - 0 - - - - - - 0 - 0 - - - - - 42 - 24 - - - - 对比 - - - true - - - - - - - - 0 - 0 - - - - - 0 - 24 - - - - 告警描点 - - - - - - - - 130 - 0 - - - - - - - - 收藏 - - - - - - - 导出 - - - - - - - Qt::Horizontal - - - QSizePolicy::MinimumExpanding - - - - 20 - 20 - - - - - - - - 打印 - - - - - - - 0 - - - 0 - - - 5 - - - 5 - - - 5 - - - 0 - - - - - - - - - - - - 实时 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 自定义 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - 0 - 35 - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 359 - 20 - - - - - - - - Qt::Horizontal - - - - 359 - 20 - - - - - - - - - Microsoft YaHei - 20 - 50 - false - - - - - - - 趋势图 - - - - - - - - - - - 0 - 0 - - - - - 20 - 0 - - - - - 20 - 16777215 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 20 - 0 - - - - - 20 - 16777215 - - - - - - - Qt::Vertical - - - - - - - - - - false - - - - 480 - 240 - - - - - - - - - - - - - - 0 - 32 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 2 - - - 0 - - - 2 - - - 6 - - - 0 - - - - - Qt::Horizontal - - - - 50 - 20 - - - - - - - - false - - - 清空 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 58 - 0 - - - - - 58 - 16777215 - - - - border:none; -background:transparent; - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 23 - 59 - 59 - 2037 - 12 - 31 - - - - - 0 - 0 - 0 - 1970 - 1 - 1 - - - - - 2037 - 12 - 31 - - - - yyyy/MM/dd HH:mm - - - - - - - 开始时间 - - - - - - - - - - 结束时间 - - - - - - - - 0 - 0 - - - - - 23 - 59 - 59 - 2037 - 12 - 31 - - - - - 0 - 0 - 0 - 1970 - 1 - 1 - - - - - 2037 - 12 - 31 - - - - yyyy/MM/dd HH:mm - - - - - - - 查询 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 23 - 59 - 59 - 2037 - 12 - 31 - - - - - 0 - 0 - 0 - 1970 - 1 - 1 - - - - - 2037 - 12 - 31 - - - - yyyy/MM/dd HH:mm - - - - - - - 上一页 - - - - - - - 下一页 - - - - - - - - - - - - - - CSWitchButton - QWidget -
./widgets/CSWitchButton.h
- 1 -
- - QCustomPlot - QWidget -
./plot/qcustomplot.h
- 1 -
- - CTabButton - QPushButton -
./widgets/CTabButton.h
-
- - CCurveLegendView - QTableView -
CCurveLegendView.h
-
- - QxtSpanSlider - QSlider -
./widgets/QxtSpanSlider.h
-
- - CTableView - QTableView -
CTableView.h
-
-
- - -
+ + + CPlotWidget + + + + 0 + 0 + 1469 + 558 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 16777215 + 150 + + + + false + + + false + + + + + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 3 + + + 0 + + + + + + 0 + 0 + + + + + 42 + 24 + + + + 对比 + + + true + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 告警描点 + + + + + + + + 130 + 0 + + + + + + + + 收藏 + + + + + + + 导出 + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 20 + 20 + + + + + + + + 打印 + + + + + + + 0 + + + 0 + + + 5 + + + 5 + + + 5 + + + 0 + + + + + + + + + + + + 实时 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 自定义 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + 0 + 35 + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 359 + 20 + + + + + + + + Qt::Horizontal + + + + 359 + 20 + + + + + + + + + Microsoft YaHei + 20 + 50 + false + + + + + + + 趋势图 + + + + + + + + + + + 0 + 0 + + + + + 20 + 0 + + + + + 20 + 16777215 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 20 + 0 + + + + + 20 + 16777215 + + + + + + + Qt::Vertical + + + + + + + + + + false + + + + 480 + 240 + + + + + + + + + + + + + + 0 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 2 + + + 0 + + + 2 + + + 6 + + + 0 + + + + + Qt::Horizontal + + + + 50 + 20 + + + + + + + + false + + + 清空 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 58 + 0 + + + + + 58 + 16777215 + + + + border:none; +background:transparent; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 23 + 59 + 59 + 2037 + 12 + 31 + + + + + 0 + 0 + 0 + 1970 + 1 + 1 + + + + + 2037 + 12 + 31 + + + + yyyy/MM/dd HH:mm + + + + + + + 开始时间 + + + + + + + + + + 结束时间 + + + + + + + + 0 + 0 + + + + + 23 + 59 + 59 + 2037 + 12 + 31 + + + + + 0 + 0 + 0 + 1970 + 1 + 1 + + + + + 2037 + 12 + 31 + + + + yyyy/MM/dd HH:mm + + + + + + + 查询 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 23 + 59 + 59 + 2037 + 12 + 31 + + + + + 0 + 0 + 0 + 1970 + 1 + 1 + + + + + 2037 + 12 + 31 + + + + yyyy/MM/dd HH:mm + + + + + + + 上一页 + + + + + + + 下一页 + + + + + + + + + + + + + + CSWitchButton + QWidget +
./widgets/CSWitchButton.h
+ 1 +
+ + QCustomPlot + QWidget +
./plot/qcustomplot.h
+ 1 +
+ + CTabButton + QPushButton +
./widgets/CTabButton.h
+
+ + CCurveLegendView + QTableView +
CCurveLegendView.h
+
+ + QxtSpanSlider + QSlider +
./widgets/QxtSpanSlider.h
+
+ + CTableView + QTableView +
CTableView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/TrendCurves/CRealTimeDataCollect.cpp b/product/src/gui/plugin/TrendCurves/CRealTimeDataCollect.cpp index d776c2bc..68ecffbf 100644 --- a/product/src/gui/plugin/TrendCurves/CRealTimeDataCollect.cpp +++ b/product/src/gui/plugin/TrendCurves/CRealTimeDataCollect.cpp @@ -1,97 +1,97 @@ -#include "CRealTimeDataCollect.h" -#include "MessageChannel.h" -#include "DataProcMessage.pb.h" -#include "pub_logger_api/logger.h" -#include - -using namespace kbd_net; -using namespace kbd_public; -using namespace kbd_idlfile; - -CRealTimeDataCollect::CRealTimeDataCollect(QObject *parent) - : QThread(parent) -{ - -} - -CRealTimeDataCollect::~CRealTimeDataCollect() -{ - -} - -void CRealTimeDataCollect::run() -{ - kbd_public::CSysInfoInterfacePtr sysInfo; - kbd_public::createSysInfoInstance(sysInfo); - - // 初始化通讯器 - CMbCommunicator * pCommunicator = new CMbCommunicator(); - pCommunicator->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - while(!isInterruptionRequested()) - { - kbd_net::CMbMessage msg; - if (pCommunicator && pCommunicator->recvMsg(msg, 100) && !isInterruptionRequested()) - { - parseTrendDataMessage(msg); - } - } - if (pCommunicator != NULL) - { - pCommunicator->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); - delete pCommunicator; - } - pCommunicator = NULL; -} - -void CRealTimeDataCollect::parseTrendDataMessage(const CMbMessage &msg) -{ - int msgType = msg.getMsgType(); - if(MT_DP_CHANGE_DATA == msgType) - { - kbd_idlfile::SRealTimeDataPkg chgDataPkg; - try - { - chgDataPkg.ParseFromArray(msg.getDataPtr(), (int)msg.getDataSize()); - int aiSize = chgDataPkg.stairtd_size(); - for(int i = 0;i < aiSize; i++) - { - const kbd_idlfile::SAiRealTimeData &aiStru = chgDataPkg.stairtd(i); - msgNotify(aiStru.strtagname(), aiStru.fvalue(), aiStru.ustatus(), E_ANALOG); - } - - int diSize = chgDataPkg.stdirtd_size(); - for(int i = 0;i < diSize; i++) - { - const kbd_idlfile::SDiRealTimeData &diStru = chgDataPkg.stdirtd(i); - msgNotify(diStru.strtagname(), diStru.nvalue(), diStru.ustatus(), E_DIGITAL); - } - - int piSize = chgDataPkg.stpirtd_size(); - for(int i = 0;i < piSize; i++) - { - const kbd_idlfile::SPiRealTimeData &piStru = chgDataPkg.stpirtd(i); - msgNotify(piStru.strtagname(), (qint64)piStru.dvalue(), piStru.ustatus(), E_ACCUML); - } - - int miSize = chgDataPkg.stmirtd_size(); - for(int i = 0;i < miSize; i++) - { - const kbd_idlfile::SMiRealTimeData &miStru = chgDataPkg.stmirtd(i); - msgNotify(miStru.strtagname(), miStru.nvalue(), miStru.ustatus(), E_MIX); - } - } - catch (...) - { - LOGERROR("TrendPlugin ParseTrendDataMessage ! MsgType: %d", msgType); - } - } -} - -void CRealTimeDataCollect::msgNotify(const std::string &strTagName, const QVariant &value, const int &status, E_Point_Type pointType) -{ - if((!isInterruptionRequested())) - { - emit realTimeTrendDataArrived(QString::fromStdString(strTagName), value, status, pointType); - } -} - +#include "CRealTimeDataCollect.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" +#include "pub_logger_api/logger.h" +#include + +using namespace kbd_net; +using namespace kbd_public; +using namespace kbd_idlfile; + +CRealTimeDataCollect::CRealTimeDataCollect(QObject *parent) + : QThread(parent) +{ + +} + +CRealTimeDataCollect::~CRealTimeDataCollect() +{ + +} + +void CRealTimeDataCollect::run() +{ + kbd_public::CSysInfoInterfacePtr sysInfo; + kbd_public::createSysInfoInstance(sysInfo); + + // 初始化通讯器 + CMbCommunicator * pCommunicator = new CMbCommunicator(); + pCommunicator->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + while(!isInterruptionRequested()) + { + kbd_net::CMbMessage msg; + if (pCommunicator && pCommunicator->recvMsg(msg, 100) && !isInterruptionRequested()) + { + parseTrendDataMessage(msg); + } + } + if (pCommunicator != NULL) + { + pCommunicator->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + delete pCommunicator; + } + pCommunicator = NULL; +} + +void CRealTimeDataCollect::parseTrendDataMessage(const CMbMessage &msg) +{ + int msgType = msg.getMsgType(); + if(MT_DP_CHANGE_DATA == msgType) + { + kbd_idlfile::SRealTimeDataPkg chgDataPkg; + try + { + chgDataPkg.ParseFromArray(msg.getDataPtr(), (int)msg.getDataSize()); + int aiSize = chgDataPkg.stairtd_size(); + for(int i = 0;i < aiSize; i++) + { + const kbd_idlfile::SAiRealTimeData &aiStru = chgDataPkg.stairtd(i); + msgNotify(aiStru.strtagname(), aiStru.fvalue(), aiStru.ustatus(), E_ANALOG); + } + + int diSize = chgDataPkg.stdirtd_size(); + for(int i = 0;i < diSize; i++) + { + const kbd_idlfile::SDiRealTimeData &diStru = chgDataPkg.stdirtd(i); + msgNotify(diStru.strtagname(), diStru.nvalue(), diStru.ustatus(), E_DIGITAL); + } + + int piSize = chgDataPkg.stpirtd_size(); + for(int i = 0;i < piSize; i++) + { + const kbd_idlfile::SPiRealTimeData &piStru = chgDataPkg.stpirtd(i); + msgNotify(piStru.strtagname(), (qint64)piStru.dvalue(), piStru.ustatus(), E_ACCUML); + } + + int miSize = chgDataPkg.stmirtd_size(); + for(int i = 0;i < miSize; i++) + { + const kbd_idlfile::SMiRealTimeData &miStru = chgDataPkg.stmirtd(i); + msgNotify(miStru.strtagname(), miStru.nvalue(), miStru.ustatus(), E_MIX); + } + } + catch (...) + { + LOGERROR("TrendPlugin ParseTrendDataMessage ! MsgType: %d", msgType); + } + } +} + +void CRealTimeDataCollect::msgNotify(const std::string &strTagName, const QVariant &value, const int &status, E_Point_Type pointType) +{ + if((!isInterruptionRequested())) + { + emit realTimeTrendDataArrived(QString::fromStdString(strTagName), value, status, pointType); + } +} + diff --git a/product/src/gui/plugin/TrendCurves/CRealTimeDataCollect.h b/product/src/gui/plugin/TrendCurves/CRealTimeDataCollect.h index 67292ef1..7447c4fc 100644 --- a/product/src/gui/plugin/TrendCurves/CRealTimeDataCollect.h +++ b/product/src/gui/plugin/TrendCurves/CRealTimeDataCollect.h @@ -1,46 +1,46 @@ -#ifndef CREALTIMEDATACOLLECT_H -#define CREALTIMEDATACOLLECT_H - -#include -#include -#include -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "../../include/net/net_msg_bus_api/CMbMessage.h" -#include "../../include/public/pub_sysinfo_api/SysInfoApi.h" -#include "CTrendInfoManage.h" - -struct ChgDataStru -{ - QVariant value; - unsigned int status; -}; - -class CRealTimeDataCollect : public QThread -{ - Q_OBJECT - -public: - CRealTimeDataCollect(QObject *parent = Q_NULLPTR); - ~CRealTimeDataCollect(); - -signals: - void realTimeTrendDataArrived(const QString &tagName, QVariant value, int status, E_Point_Type pointType); - -protected: - /** - * 消息接收线程 - * @brief run - */ - void run(); - -private: - /** - * @brief parseTrendDataMessage 解析实时数据 - * @param msg - */ - void parseTrendDataMessage(const kbd_net::CMbMessage &msg); - - void msgNotify(const std::string &strTagName, const QVariant &value, const int &status, E_Point_Type pointType); -}; - -#endif // CREALTIMEDATACOLLECT_H +#ifndef CREALTIMEDATACOLLECT_H +#define CREALTIMEDATACOLLECT_H + +#include +#include +#include +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "../../include/net/net_msg_bus_api/CMbMessage.h" +#include "../../include/public/pub_sysinfo_api/SysInfoApi.h" +#include "CTrendInfoManage.h" + +struct ChgDataStru +{ + QVariant value; + unsigned int status; +}; + +class CRealTimeDataCollect : public QThread +{ + Q_OBJECT + +public: + CRealTimeDataCollect(QObject *parent = Q_NULLPTR); + ~CRealTimeDataCollect(); + +signals: + void realTimeTrendDataArrived(const QString &tagName, QVariant value, int status, E_Point_Type pointType); + +protected: + /** + * 消息接收线程 + * @brief run + */ + void run(); + +private: + /** + * @brief parseTrendDataMessage 解析实时数据 + * @param msg + */ + void parseTrendDataMessage(const kbd_net::CMbMessage &msg); + + void msgNotify(const std::string &strTagName, const QVariant &value, const int &status, E_Point_Type pointType); +}; + +#endif // CREALTIMEDATACOLLECT_H diff --git a/product/src/gui/plugin/TrendCurves/CTableDataModel.cpp b/product/src/gui/plugin/TrendCurves/CTableDataModel.cpp index 3a6aff59..4db96557 100644 --- a/product/src/gui/plugin/TrendCurves/CTableDataModel.cpp +++ b/product/src/gui/plugin/TrendCurves/CTableDataModel.cpp @@ -1,229 +1,229 @@ -#include "CTableDataModel.h" - -CTableDataModel::CTableDataModel(QObject *parent) - : QAbstractTableModel(parent), - m_pView(static_cast(parent)), - m_bAscs(true) -{ - -} - -CTableDataModel::~CTableDataModel() -{ - m_curveDataMap.clear(); - m_header.clear(); - m_timeList.clear(); - m_pView = nullptr; -} - -void CTableDataModel::clear() -{ - beginResetModel(); - m_curveDataMap.clear(); - m_header.clear(); - m_timeList.clear(); - m_bAscs = true; - endResetModel(); -} - -void CTableDataModel::setCurveData(const QMap > &curveDataMap, const QStringList &headerList, bool ascs, int limit) -{ - beginResetModel(); - m_curveDataMap = curveDataMap; - m_header = headerList; - m_bAscs = ascs; - - m_timeList.clear(); - bool isLimit = false; - foreach (QString curveName, m_header) - { - QVector curveData = curveDataMap[curveName]; - QVector::const_iterator iter = curveData.constBegin(); - while (iter != curveData.constEnd()) - { - if(limit != 0 && m_timeList.count() >= limit) - { - isLimit = true; - break; - } - if(!m_timeList.contains(iter->key)) - { - m_timeList.append(iter->key); - } - iter++; - } - } - std::sort(m_timeList.begin(), m_timeList.end()); - if(isLimit) - { - QMessageBox::information(m_pView, tr("提示"), tr("只显示前%1条记录!").arg(limit), QMessageBox::Ok); - } - endResetModel(); -} - -void CTableDataModel::removeCurveData(const QString &desc) -{ - bool bRet = m_header.removeOne(desc); - int nRet = m_curveDataMap.remove(desc); - if(bRet || nRet > 0) - { - setCurveData(m_curveDataMap, m_header); - } -} - -bool CTableDataModel::setColumnHidden(const QString &desc, bool hide) -{ - int index = m_header.indexOf(desc); - if(index < 0) - { - return false; - } - m_pView->setColumnHidden(index+1, hide); - return true; -} - -int CTableDataModel::getHeaderIndex(const QString &desc) -{ - int index = m_header.indexOf(desc); - if(index < 0) - { - return -1; - } - if(m_pView->isColumnHidden(index+1)) - { - return -1; - } - return index; -} - -QVariant CTableDataModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - if(0 == section) - { - return tr("时间"); - } - else - { - return QString(m_header.at(section - 1)).section(".", 1); - } - } - } - else if(Qt::ToolTipRole == role) - { - if(Qt::Horizontal == orientation) - { - if(0 == section) - { - return tr("时间"); - } - else - { - return m_header.at(section - 1); - } - } - } - return QVariant(); -} - -int CTableDataModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid() || m_header.isEmpty() || m_timeList.isEmpty()) - return 0; - return m_timeList.count(); -} - -int CTableDataModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid() || m_header.isEmpty()) - return 0; - return m_header.count() + 1; -} - -QVariant CTableDataModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid()) - { - return QVariant(); - } - - if(Qt::TextAlignmentRole == role) - { - if(index.column() == 0) - { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); - } - - if(Qt::DisplayRole != role && Qt::ForegroundRole != role && Qt::UserRole != role) - { - return QVariant(); - } - - double time = m_timeList.at(index.row()); - if(!m_bAscs) - { - time = m_timeList.at(rowCount() - index.row() - 1); - } - - if(0 < index.column()) - { - QCPGraphData data(time, 0); - - const QVector &vecData = m_curveDataMap[m_header[index.column() - 1]]; - QCPDataContainer::const_reverse_iterator iter = std::find_if(vecData.crbegin(), - vecData.crend(), [=](QCPGraphData const& obj){ return data.sortKey() == obj.sortKey(); }); - if(iter != vecData.crend()) - { - if(Qt::ForegroundRole == role) - { - if(iter->status == 1) - { - return QVariant(QColor(Qt::gray)); - } - } - else if(Qt::UserRole == role) - { - return QVariant(iter->status); - } - else if(Qt::DisplayRole == role) - { - if(qIsNaN(iter->value)) - return "NaN"; - else - return QString::number(iter->value, 'f', 2); - } - } - } - - if(Qt::DisplayRole != role) - { - return QVariant(); - } - - if(0 == index.column()) - { - return QCPAxisTickerDateTime::keyToDateTime(time).toString("yyyy-MM-dd hh:mm:ss.zzz"); - } - - if(m_bAscs) - { - if((index.row()-1) >= 0 && (index.row()-1) < rowCount()) - { - return createIndex(index.row()-1, index.column()).data(); - } - } - else - { - if((index.row()+1) >= 0 && (index.row()+1) < rowCount()) - { - return createIndex(index.row()+1, index.column()).data(); - } - } - - return QVariant(); -} +#include "CTableDataModel.h" + +CTableDataModel::CTableDataModel(QObject *parent) + : QAbstractTableModel(parent), + m_pView(static_cast(parent)), + m_bAscs(true) +{ + +} + +CTableDataModel::~CTableDataModel() +{ + m_curveDataMap.clear(); + m_header.clear(); + m_timeList.clear(); + m_pView = nullptr; +} + +void CTableDataModel::clear() +{ + beginResetModel(); + m_curveDataMap.clear(); + m_header.clear(); + m_timeList.clear(); + m_bAscs = true; + endResetModel(); +} + +void CTableDataModel::setCurveData(const QMap > &curveDataMap, const QStringList &headerList, bool ascs, int limit) +{ + beginResetModel(); + m_curveDataMap = curveDataMap; + m_header = headerList; + m_bAscs = ascs; + + m_timeList.clear(); + bool isLimit = false; + foreach (QString curveName, m_header) + { + QVector curveData = curveDataMap[curveName]; + QVector::const_iterator iter = curveData.constBegin(); + while (iter != curveData.constEnd()) + { + if(limit != 0 && m_timeList.count() >= limit) + { + isLimit = true; + break; + } + if(!m_timeList.contains(iter->key)) + { + m_timeList.append(iter->key); + } + iter++; + } + } + std::sort(m_timeList.begin(), m_timeList.end()); + if(isLimit) + { + QMessageBox::information(m_pView, tr("提示"), tr("只显示前%1条记录!").arg(limit), QMessageBox::Ok); + } + endResetModel(); +} + +void CTableDataModel::removeCurveData(const QString &desc) +{ + bool bRet = m_header.removeOne(desc); + int nRet = m_curveDataMap.remove(desc); + if(bRet || nRet > 0) + { + setCurveData(m_curveDataMap, m_header); + } +} + +bool CTableDataModel::setColumnHidden(const QString &desc, bool hide) +{ + int index = m_header.indexOf(desc); + if(index < 0) + { + return false; + } + m_pView->setColumnHidden(index+1, hide); + return true; +} + +int CTableDataModel::getHeaderIndex(const QString &desc) +{ + int index = m_header.indexOf(desc); + if(index < 0) + { + return -1; + } + if(m_pView->isColumnHidden(index+1)) + { + return -1; + } + return index; +} + +QVariant CTableDataModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + if(0 == section) + { + return tr("时间"); + } + else + { + return QString(m_header.at(section - 1)).section(".", 1); + } + } + } + else if(Qt::ToolTipRole == role) + { + if(Qt::Horizontal == orientation) + { + if(0 == section) + { + return tr("时间"); + } + else + { + return m_header.at(section - 1); + } + } + } + return QVariant(); +} + +int CTableDataModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid() || m_header.isEmpty() || m_timeList.isEmpty()) + return 0; + return m_timeList.count(); +} + +int CTableDataModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid() || m_header.isEmpty()) + return 0; + return m_header.count() + 1; +} + +QVariant CTableDataModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == 0) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + if(Qt::DisplayRole != role && Qt::ForegroundRole != role && Qt::UserRole != role) + { + return QVariant(); + } + + double time = m_timeList.at(index.row()); + if(!m_bAscs) + { + time = m_timeList.at(rowCount() - index.row() - 1); + } + + if(0 < index.column()) + { + QCPGraphData data(time, 0); + + const QVector &vecData = m_curveDataMap[m_header[index.column() - 1]]; + QCPDataContainer::const_reverse_iterator iter = std::find_if(vecData.crbegin(), + vecData.crend(), [=](QCPGraphData const& obj){ return data.sortKey() == obj.sortKey(); }); + if(iter != vecData.crend()) + { + if(Qt::ForegroundRole == role) + { + if(iter->status == 1) + { + return QVariant(QColor(Qt::gray)); + } + } + else if(Qt::UserRole == role) + { + return QVariant(iter->status); + } + else if(Qt::DisplayRole == role) + { + if(qIsNaN(iter->value)) + return "NaN"; + else + return QString::number(iter->value, 'f', 2); + } + } + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + if(0 == index.column()) + { + return QCPAxisTickerDateTime::keyToDateTime(time).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + + if(m_bAscs) + { + if((index.row()-1) >= 0 && (index.row()-1) < rowCount()) + { + return createIndex(index.row()-1, index.column()).data(); + } + } + else + { + if((index.row()+1) >= 0 && (index.row()+1) < rowCount()) + { + return createIndex(index.row()+1, index.column()).data(); + } + } + + return QVariant(); +} diff --git a/product/src/gui/plugin/TrendCurves/CTableDataModel.h b/product/src/gui/plugin/TrendCurves/CTableDataModel.h index eb973853..f78e7282 100644 --- a/product/src/gui/plugin/TrendCurves/CTableDataModel.h +++ b/product/src/gui/plugin/TrendCurves/CTableDataModel.h @@ -1,41 +1,41 @@ -#ifndef CTABLEDATAMODEL_H -#define CTABLEDATAMODEL_H - -#include -#include "plot/qcustomplot.h" - -class CTableDataModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit CTableDataModel(QObject * parent = nullptr); - - ~CTableDataModel(); - - void clear(); - - void setCurveData(const QMap > &curveDataMap, const QStringList &headerList, bool ascs = true, int limit = 0); - - void removeCurveData(const QString &desc); - - bool setColumnHidden(const QString& desc, bool hide); - - int getHeaderIndex(const QString &desc); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - -private: - QTableView * m_pView; - QStringList m_header; - QMap > m_curveDataMap; - QList m_timeList; - bool m_bAscs; -}; - -#endif // CTABLEDATAMODEL_H +#ifndef CTABLEDATAMODEL_H +#define CTABLEDATAMODEL_H + +#include +#include "plot/qcustomplot.h" + +class CTableDataModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CTableDataModel(QObject * parent = nullptr); + + ~CTableDataModel(); + + void clear(); + + void setCurveData(const QMap > &curveDataMap, const QStringList &headerList, bool ascs = true, int limit = 0); + + void removeCurveData(const QString &desc); + + bool setColumnHidden(const QString& desc, bool hide); + + int getHeaderIndex(const QString &desc); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QTableView * m_pView; + QStringList m_header; + QMap > m_curveDataMap; + QList m_timeList; + bool m_bAscs; +}; + +#endif // CTABLEDATAMODEL_H diff --git a/product/src/gui/plugin/TrendCurves/CTableView.cpp b/product/src/gui/plugin/TrendCurves/CTableView.cpp index 5102d89d..5a5658ac 100644 --- a/product/src/gui/plugin/TrendCurves/CTableView.cpp +++ b/product/src/gui/plugin/TrendCurves/CTableView.cpp @@ -1,32 +1,32 @@ -#include "CTableView.h" -#include - -CTableView::CTableView(QWidget *parent) - : QTableView(parent) -{ - -} - -int CTableView::tableColumnWidth() -{ - return m_nTableColWidth; -} - -void CTableView::setTableColumnWidth(const int &nWidth) -{ - m_nTableColWidth = nWidth; - - horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); -} - -int CTableView::tableRowHeight() -{ - return m_nTableRowHeight; -} - -void CTableView::setTableRowHeight(const int &nHeight) -{ - m_nTableRowHeight = nHeight; - - verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); -} +#include "CTableView.h" +#include + +CTableView::CTableView(QWidget *parent) + : QTableView(parent) +{ + +} + +int CTableView::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CTableView::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CTableView::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CTableView::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} diff --git a/product/src/gui/plugin/TrendCurves/CTableView.h b/product/src/gui/plugin/TrendCurves/CTableView.h index 8b457048..6335001f 100644 --- a/product/src/gui/plugin/TrendCurves/CTableView.h +++ b/product/src/gui/plugin/TrendCurves/CTableView.h @@ -1,26 +1,26 @@ -#ifndef CTABLEVIEW_H -#define CTABLEVIEW_H - -#include - -class CTableView : public QTableView -{ - Q_OBJECT - Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) - Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) - -public: - CTableView(QWidget *parent = Q_NULLPTR); - - int tableColumnWidth(); - void setTableColumnWidth(const int &nWidth); - - int tableRowHeight(); - void setTableRowHeight(const int &nHeight); - -private: - int m_nTableColWidth; - int m_nTableRowHeight; -}; - -#endif // CTABLEVIEW_H +#ifndef CTABLEVIEW_H +#define CTABLEVIEW_H + +#include + +class CTableView : public QTableView +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + CTableView(QWidget *parent = Q_NULLPTR); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + +private: + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +#endif // CTABLEVIEW_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.cpp b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.cpp index 465c9edc..33bd2237 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.cpp @@ -1,149 +1,149 @@ -#include -#include "CTrendEditDialog.h" -#include "ui_CTrendEditDialog.h" -#include "CTrendEditModel.h" -#include "GraphTool/Retriever/CRetriever.h" -#include "pub_utility_api/FileUtil.h" - -using namespace kbd_dbms; - -CTrendEditDialog::CTrendEditDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CTrendEditDialog), - m_graph(nullptr), - m_pRretriever(nullptr) -{ - ui->setupUi(this); - ui->m_retrieverWidget->setWindowFlags(Qt::Widget); - ui->m_retrieverWidget->setMultVisible(false); - //setWindowModality(Qt::WindowModal); - initialize(); - connect(ui->addCurve, SIGNAL(clicked()), this, SLOT(slot_addCureve())); - connect(ui->removeCurve, SIGNAL(clicked()), this, SLOT(slot_removeCureve())); - connect(ui->clearCurve, SIGNAL(clicked()), this, SLOT(slot_clearCureve())); - connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateTrend())); - connect(ui->cancle, SIGNAL(clicked()), this, SLOT(close())); -} - -CTrendEditDialog::~CTrendEditDialog() -{ - if(m_pRretriever != NULL) - { - delete m_pRretriever; - } - m_pRretriever = NULL; - delete ui; -} - -void CTrendEditDialog::initialize() -{ - - initTrendView(); - - m_pRretriever = new CRetriever(this); -} - -void CTrendEditDialog::initTrendView() -{ - m_model = new CTrendEditModel(this); - ui->trendView->setModel(m_model); - ui->trendView->horizontalHeader()->setStretchLastSection(true); - CTrendDelegate * delegate = new CTrendDelegate(this); - ui->trendView->setItemDelegate(delegate); - ui->trendView->setAlternatingRowColors(true); - ui->trendView->horizontalHeader()->setStretchLastSection(true); - - connect(ui->m_retrieverWidget, &CRetriever::itemTagTriggered, ui->trendView, &CTrendEditView::appendTagName); -} - -void CTrendEditDialog::showEvent(QShowEvent *event) -{ - QDialog::showEvent(event); - updateTrendViewColumnWidth(); -} - -void CTrendEditDialog::resizeEvent(QResizeEvent *event) -{ - QDialog::resizeEvent(event); - updateTrendViewColumnWidth(); -} - - -void CTrendEditDialog::updateTrendViewColumnWidth() -{ - int nTrendViewWidth = ui->trendView->width(); - ui->trendView->setColumnWidth(0, nTrendViewWidth / 3 * 2); -} - - -void CTrendEditDialog::setTrendGraph(CTrendGraph *graph) -{ - if( Q_NULLPTR == graph ) - { - return; - } - m_graph = graph; - m_model->setTrendCurves(m_graph->curves()); -} - -CTrendGraph *CTrendEditDialog::trendGraph() const -{ - return m_graph; -} - -void CTrendEditDialog::slot_updateTrend() -{ - if(m_model->rowCount() == 0) - { - QMessageBox::warning(this, tr("警告"), tr("测点数量不允许为空!")); - return; - } - - for(int nIndex(0); nIndex < m_model->rowCount(); ++nIndex) - { - if(m_model->curves().at(nIndex).tag == "") - { - QMessageBox::warning(this, tr("警告"), tr("测点名称不允许存在空值!")); - return; - } - } - if(nullptr == m_graph) - { - m_graph = new CTrendGraph(); - } - m_graph->setCurves(m_model->curves()); - accept(); -} - -void CTrendEditDialog::slot_addCureve() -{ - m_model->addTrendCurve(); -} - -void CTrendEditDialog::slot_removeCureve() -{ - if(!ui->trendView->currentIndex().isValid()) - { - QMessageBox::information(this, tr("提示"), tr("当前未选中行!")); - return; - } - QItemSelectionModel *itemSelection = ui->trendView->selectionModel(); - QModelIndexList indexList = itemSelection->selectedRows(); - m_model->removeTrendCurve(indexList); -} - -void CTrendEditDialog::slot_clearCureve() -{ - m_model->clearTrendCurves(); -} - -void CTrendEditDialog::slot_showRetriever() -{ - if(nullptr == m_pRretriever) - { - m_pRretriever = new CRetriever(this); - } - m_pRretriever->show(); -} - - +#include +#include "CTrendEditDialog.h" +#include "ui_CTrendEditDialog.h" +#include "CTrendEditModel.h" +#include "GraphTool/Retriever/CRetriever.h" +#include "pub_utility_api/FileUtil.h" + +using namespace kbd_dbms; + +CTrendEditDialog::CTrendEditDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CTrendEditDialog), + m_graph(nullptr), + m_pRretriever(nullptr) +{ + ui->setupUi(this); + ui->m_retrieverWidget->setWindowFlags(Qt::Widget); + ui->m_retrieverWidget->setMultVisible(false); + //setWindowModality(Qt::WindowModal); + initialize(); + connect(ui->addCurve, SIGNAL(clicked()), this, SLOT(slot_addCureve())); + connect(ui->removeCurve, SIGNAL(clicked()), this, SLOT(slot_removeCureve())); + connect(ui->clearCurve, SIGNAL(clicked()), this, SLOT(slot_clearCureve())); + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateTrend())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(close())); +} + +CTrendEditDialog::~CTrendEditDialog() +{ + if(m_pRretriever != NULL) + { + delete m_pRretriever; + } + m_pRretriever = NULL; + delete ui; +} + +void CTrendEditDialog::initialize() +{ + + initTrendView(); + + m_pRretriever = new CRetriever(this); +} + +void CTrendEditDialog::initTrendView() +{ + m_model = new CTrendEditModel(this); + ui->trendView->setModel(m_model); + ui->trendView->horizontalHeader()->setStretchLastSection(true); + CTrendDelegate * delegate = new CTrendDelegate(this); + ui->trendView->setItemDelegate(delegate); + ui->trendView->setAlternatingRowColors(true); + ui->trendView->horizontalHeader()->setStretchLastSection(true); + + connect(ui->m_retrieverWidget, &CRetriever::itemTagTriggered, ui->trendView, &CTrendEditView::appendTagName); +} + +void CTrendEditDialog::showEvent(QShowEvent *event) +{ + QDialog::showEvent(event); + updateTrendViewColumnWidth(); +} + +void CTrendEditDialog::resizeEvent(QResizeEvent *event) +{ + QDialog::resizeEvent(event); + updateTrendViewColumnWidth(); +} + + +void CTrendEditDialog::updateTrendViewColumnWidth() +{ + int nTrendViewWidth = ui->trendView->width(); + ui->trendView->setColumnWidth(0, nTrendViewWidth / 3 * 2); +} + + +void CTrendEditDialog::setTrendGraph(CTrendGraph *graph) +{ + if( Q_NULLPTR == graph ) + { + return; + } + m_graph = graph; + m_model->setTrendCurves(m_graph->curves()); +} + +CTrendGraph *CTrendEditDialog::trendGraph() const +{ + return m_graph; +} + +void CTrendEditDialog::slot_updateTrend() +{ + if(m_model->rowCount() == 0) + { + QMessageBox::warning(this, tr("警告"), tr("测点数量不允许为空!")); + return; + } + + for(int nIndex(0); nIndex < m_model->rowCount(); ++nIndex) + { + if(m_model->curves().at(nIndex).tag == "") + { + QMessageBox::warning(this, tr("警告"), tr("测点名称不允许存在空值!")); + return; + } + } + if(nullptr == m_graph) + { + m_graph = new CTrendGraph(); + } + m_graph->setCurves(m_model->curves()); + accept(); +} + +void CTrendEditDialog::slot_addCureve() +{ + m_model->addTrendCurve(); +} + +void CTrendEditDialog::slot_removeCureve() +{ + if(!ui->trendView->currentIndex().isValid()) + { + QMessageBox::information(this, tr("提示"), tr("当前未选中行!")); + return; + } + QItemSelectionModel *itemSelection = ui->trendView->selectionModel(); + QModelIndexList indexList = itemSelection->selectedRows(); + m_model->removeTrendCurve(indexList); +} + +void CTrendEditDialog::slot_clearCureve() +{ + m_model->clearTrendCurves(); +} + +void CTrendEditDialog::slot_showRetriever() +{ + if(nullptr == m_pRretriever) + { + m_pRretriever = new CRetriever(this); + } + m_pRretriever->show(); +} + + diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.h b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.h index 23d1107d..39153e53 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.h +++ b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.h @@ -1,49 +1,49 @@ -#ifndef CTRENDEDITDIALOG_H -#define CTRENDEDITDIALOG_H - -#include -#include "CTrendGraph.h" - -namespace Ui { -class CTrendEditDialog; -} - -class CRetriever; -class CTrendEditModel; - -class CTrendEditDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CTrendEditDialog(QWidget *parent = 0); - ~CTrendEditDialog(); - - void initialize(); - void initTrendView(); - - void setTrendGraph(CTrendGraph * data); - CTrendGraph * trendGraph() const; - -protected: - void showEvent(QShowEvent *event); - void resizeEvent(QResizeEvent *event); - -protected slots: - void slot_updateTrend(); - void slot_addCureve(); - void slot_removeCureve(); - void slot_clearCureve(); - void slot_showRetriever(); - -private: - void updateTrendViewColumnWidth(); - -private: - Ui::CTrendEditDialog *ui; - CTrendGraph * m_graph; - CTrendEditModel * m_model; - CRetriever * m_pRretriever; -}; - -#endif // CTRENDEDITDIALOG_H +#ifndef CTRENDEDITDIALOG_H +#define CTRENDEDITDIALOG_H + +#include +#include "CTrendGraph.h" + +namespace Ui { +class CTrendEditDialog; +} + +class CRetriever; +class CTrendEditModel; + +class CTrendEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CTrendEditDialog(QWidget *parent = 0); + ~CTrendEditDialog(); + + void initialize(); + void initTrendView(); + + void setTrendGraph(CTrendGraph * data); + CTrendGraph * trendGraph() const; + +protected: + void showEvent(QShowEvent *event); + void resizeEvent(QResizeEvent *event); + +protected slots: + void slot_updateTrend(); + void slot_addCureve(); + void slot_removeCureve(); + void slot_clearCureve(); + void slot_showRetriever(); + +private: + void updateTrendViewColumnWidth(); + +private: + Ui::CTrendEditDialog *ui; + CTrendGraph * m_graph; + CTrendEditModel * m_model; + CRetriever * m_pRretriever; +}; + +#endif // CTRENDEDITDIALOG_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.ui b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.ui index 30b390a9..16901664 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.ui +++ b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.ui @@ -1,193 +1,193 @@ - - - CTrendEditDialog - - - - 0 - 0 - 1047 - 566 - - - - 趋势编辑 - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 取消 - - - - - - - 确定 - - - - - - - Qt::Horizontal - - - - 500 - 20 - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - - - QFrame::NoFrame - - - QFrame::Sunken - - - 1 - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 3 - - - - - 2 - - - 0 - - - - - 添加 - - - - - - - 删除 - - - - - - - 清空 - - - - - - - Qt::Horizontal - - - - 408 - 20 - - - - - - - - - - - - - - - - - - - - - - CTrendEditView - QTableView -
CTrendEditView.h
-
- - CRetriever - QWidget -
GraphTool/Retriever/CRetriever.h
- 1 -
-
- - - - onAddCureve() - -
+ + + CTrendEditDialog + + + + 0 + 0 + 1047 + 566 + + + + 趋势编辑 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 取消 + + + + + + + 确定 + + + + + + + Qt::Horizontal + + + + 500 + 20 + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + QFrame::NoFrame + + + QFrame::Sunken + + + 1 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 3 + + + + + 2 + + + 0 + + + + + 添加 + + + + + + + 删除 + + + + + + + 清空 + + + + + + + Qt::Horizontal + + + + 408 + 20 + + + + + + + + + + + + + + + + + + + + + + CTrendEditView + QTableView +
CTrendEditView.h
+
+ + CRetriever + QWidget +
GraphTool/Retriever/CRetriever.h
+ 1 +
+
+ + + + onAddCureve() + +
diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditModel.cpp b/product/src/gui/plugin/TrendCurves/CTrendEditModel.cpp index 2e07d0ac..a46deb26 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditModel.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendEditModel.cpp @@ -1,267 +1,267 @@ -#include -#include -#include -#include "CTrendGraph.h" -#include "CTrendEditModel.h" - -CTrendDelegate::CTrendDelegate(QWidget *parent) - : QStyledItemDelegate(parent), - m_parent(parent) -{ - -} - -QWidget *CTrendDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(option) - if(!index.isValid() || !const_cast(index.model())) - { - return parent; - } - if( 2 == index.column() ) - { - QSpinBox * spin = new QSpinBox(parent); - spin->setMinimum(1); - spin->setMaximum(10); - spin->setSingleStep(1); - return spin; - } - return Q_NULLPTR; -} - -void CTrendDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - QStyledItemDelegate::paint(painter, option, index); - if (!index.isValid()) - { - return; - } - if (!const_cast(index.model())) - { - return; - } - CTrendEditModel * model = dynamic_cast(const_cast(index.model())); - if (!model) - { - return; - } - if (1 == index.column()) - { - painter->save(); - painter->fillRect(option.rect.adjusted(2,1,-2,-1), model->color(index)); - painter->restore(); - } -} - -void CTrendDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - QStyledItemDelegate::setEditorData(editor, index); -} - -void CTrendDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const -{ - QStyledItemDelegate::setModelData(editor, model, index); -} - -void CTrendDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - Q_UNUSED(index) - editor->setGeometry(option.rect.adjusted(3,3,-3,-3)); -} - -bool CTrendDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - if(1 == index.column()) - { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == Qt::LeftButton) - { - if(const_cast(index.model())) - { - CTrendEditModel * dataModel = dynamic_cast(model); - if(dataModel) - { - QColor color = dataModel->color(index); - color = QColorDialog::getColor(color, m_parent, tr("颜色选择"), QColorDialog::DontUseNativeDialog); - if(color.isValid()) - { - dataModel->setData(index, color); - } - } - } - } - } - return QStyledItemDelegate::editorEvent(event, model, option, index); -} - -CTrendEditModel::CTrendEditModel(QObject *parent) - :QAbstractTableModel(parent) -{ - m_header << tr("测点名称") << tr("颜色"); -} - -CTrendEditModel::~CTrendEditModel() -{ - m_listCurve.clear(); -} - -void CTrendEditModel::addTrendCurve() -{ - beginResetModel(); - Curve curve; - curve.tag = QString(""); - curve.desc = QString(""); - curve.color = QColor(qrand() % 255, qrand() % 255, qrand() % 255); - m_listCurve.append(curve); - endResetModel(); -} - -void CTrendEditModel::removeTrendCurve(const QModelIndexList & indexList) -{ - beginResetModel(); - int cof = 0; - foreach (QModelIndex index, indexList) { - m_listCurve.removeAt(index.row() - cof); - cof++; - } - endResetModel(); -} - -void CTrendEditModel::clearTrendCurves() -{ - beginResetModel(); - m_listCurve.clear(); - endResetModel(); -} - -void CTrendEditModel::setTrendCurves(QList curves) -{ - beginResetModel(); - m_listCurve = curves; - endResetModel(); -} - -QList CTrendEditModel::curves() -{ - return m_listCurve; -} - -QColor CTrendEditModel::color(const QModelIndex &index) const -{ - if(index.isValid() && 1 == index.column() ) - { - return m_listCurve.at(index.row()).color; - } - return QColor(); -} - -QVariant CTrendEditModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if(Qt::DisplayRole == role) - { - if(Qt::Horizontal == orientation) - { - return m_header.at(section); - } - } - return QVariant(); - -} - -QVariant CTrendEditModel::data(const QModelIndex &index, int role) const -{ - if(Qt::DisplayRole != role || !index.isValid()) - { - return QVariant(); - } - Curve curve = m_listCurve.at(index.row()); - switch (index.column()) - { - case 0: - { - return QString("%1").arg(curve.tag); - } - case 1: - { - return curve.color; - } - default: - break; - } - return QVariant(); -} - -bool CTrendEditModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_UNUSED(role) - if(!index.isValid()) - { - return false; - } - switch (index.column()) - { - case 0: - { - QStringList list = value.toString().split("."); - m_listCurve[index.row()].tag = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); - m_listCurve[index.row()].type = list.at(2); - break; - } - case 1: - { - m_listCurve[index.row()].color = value.value(); - break; - } - default: - break; - } - emit dataChanged(index, index); - return true; -} - -int CTrendEditModel::columnCount(const QModelIndex &index) const -{ - if (index.isValid()) - return 0; - return m_header.size(); -} - -int CTrendEditModel::rowCount(const QModelIndex &index) const -{ - if (index.isValid()) - return 0; - return m_listCurve.count(); -} - -Qt::ItemFlags CTrendEditModel::flags(const QModelIndex &index) const -{ - if(!index.isValid()) - { - return Qt::NoItemFlags; - } - return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; -} - -QString CTrendEditModel::checkAppendData(const QString &tag) -{ - QStringList list = tag.split("."); - if(list.length() != 7) - { - return tr("点标签非法"); - } - QString tagName = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); - QString type = list.at(2); - if(type != "analog" && type != "accuml") - { - return tr("只能添加模拟量和累积量!"); - } - - foreach (Curve curve, m_listCurve) { - if(curve.tag == tagName) - { - return tr("该测点已存在!"); - } - } - return ""; -} - +#include +#include +#include +#include "CTrendGraph.h" +#include "CTrendEditModel.h" + +CTrendDelegate::CTrendDelegate(QWidget *parent) + : QStyledItemDelegate(parent), + m_parent(parent) +{ + +} + +QWidget *CTrendDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid() || !const_cast(index.model())) + { + return parent; + } + if( 2 == index.column() ) + { + QSpinBox * spin = new QSpinBox(parent); + spin->setMinimum(1); + spin->setMaximum(10); + spin->setSingleStep(1); + return spin; + } + return Q_NULLPTR; +} + +void CTrendDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter, option, index); + if (!index.isValid()) + { + return; + } + if (!const_cast(index.model())) + { + return; + } + CTrendEditModel * model = dynamic_cast(const_cast(index.model())); + if (!model) + { + return; + } + if (1 == index.column()) + { + painter->save(); + painter->fillRect(option.rect.adjusted(2,1,-2,-1), model->color(index)); + painter->restore(); + } +} + +void CTrendDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QStyledItemDelegate::setEditorData(editor, index); +} + +void CTrendDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + QStyledItemDelegate::setModelData(editor, model, index); +} + +void CTrendDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect.adjusted(3,3,-3,-3)); +} + +bool CTrendDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(1 == index.column()) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + if(const_cast(index.model())) + { + CTrendEditModel * dataModel = dynamic_cast(model); + if(dataModel) + { + QColor color = dataModel->color(index); + color = QColorDialog::getColor(color, m_parent, tr("颜色选择"), QColorDialog::DontUseNativeDialog); + if(color.isValid()) + { + dataModel->setData(index, color); + } + } + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +CTrendEditModel::CTrendEditModel(QObject *parent) + :QAbstractTableModel(parent) +{ + m_header << tr("测点名称") << tr("颜色"); +} + +CTrendEditModel::~CTrendEditModel() +{ + m_listCurve.clear(); +} + +void CTrendEditModel::addTrendCurve() +{ + beginResetModel(); + Curve curve; + curve.tag = QString(""); + curve.desc = QString(""); + curve.color = QColor(qrand() % 255, qrand() % 255, qrand() % 255); + m_listCurve.append(curve); + endResetModel(); +} + +void CTrendEditModel::removeTrendCurve(const QModelIndexList & indexList) +{ + beginResetModel(); + int cof = 0; + foreach (QModelIndex index, indexList) { + m_listCurve.removeAt(index.row() - cof); + cof++; + } + endResetModel(); +} + +void CTrendEditModel::clearTrendCurves() +{ + beginResetModel(); + m_listCurve.clear(); + endResetModel(); +} + +void CTrendEditModel::setTrendCurves(QList curves) +{ + beginResetModel(); + m_listCurve = curves; + endResetModel(); +} + +QList CTrendEditModel::curves() +{ + return m_listCurve; +} + +QColor CTrendEditModel::color(const QModelIndex &index) const +{ + if(index.isValid() && 1 == index.column() ) + { + return m_listCurve.at(index.row()).color; + } + return QColor(); +} + +QVariant CTrendEditModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); + +} + +QVariant CTrendEditModel::data(const QModelIndex &index, int role) const +{ + if(Qt::DisplayRole != role || !index.isValid()) + { + return QVariant(); + } + Curve curve = m_listCurve.at(index.row()); + switch (index.column()) + { + case 0: + { + return QString("%1").arg(curve.tag); + } + case 1: + { + return curve.color; + } + default: + break; + } + return QVariant(); +} + +bool CTrendEditModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(role) + if(!index.isValid()) + { + return false; + } + switch (index.column()) + { + case 0: + { + QStringList list = value.toString().split("."); + m_listCurve[index.row()].tag = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); + m_listCurve[index.row()].type = list.at(2); + break; + } + case 1: + { + m_listCurve[index.row()].color = value.value(); + break; + } + default: + break; + } + emit dataChanged(index, index); + return true; +} + +int CTrendEditModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + return 0; + return m_header.size(); +} + +int CTrendEditModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + return 0; + return m_listCurve.count(); +} + +Qt::ItemFlags CTrendEditModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + { + return Qt::NoItemFlags; + } + return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; +} + +QString CTrendEditModel::checkAppendData(const QString &tag) +{ + QStringList list = tag.split("."); + if(list.length() != 7) + { + return tr("点标签非法"); + } + QString tagName = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); + QString type = list.at(2); + if(type != "analog" && type != "accuml") + { + return tr("只能添加模拟量和累积量!"); + } + + foreach (Curve curve, m_listCurve) { + if(curve.tag == tagName) + { + return tr("该测点已存在!"); + } + } + return ""; +} + diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditModel.h b/product/src/gui/plugin/TrendCurves/CTrendEditModel.h index 7e43f9f3..93c9367f 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditModel.h +++ b/product/src/gui/plugin/TrendCurves/CTrendEditModel.h @@ -1,99 +1,99 @@ -#ifndef CTRENDEDITMODEL_H -#define CTRENDEDITMODEL_H - -/***************************************** -/ * - * 趋势曲线设置视图模型 - * - * ***************************************/ - -#include -#include -#include -#include -#include -#include -#include "CTrendGraph.h" - -//Delegate Label -class CColorLabel : public QLabel -{ - Q_OBJECT -public: - CColorLabel(QWidget * parent = Q_NULLPTR) : QLabel(parent){} - - void setColor(const QColor &color) { m_color = color; } - QColor color() const { return m_color; } - -protected: - virtual void mousePressEvent(QMouseEvent *event) - { - QLabel::mousePressEvent(event); - QColor color = QColorDialog::getColor(m_color, this, tr("颜色选择"), QColorDialog::DontUseNativeDialog); - if(color.isValid()) - { - m_color = color; - } - } - - virtual void paintEvent(QPaintEvent * event) - { - QPainter p(this); - p.fillRect(rect(), QBrush(m_color)); - QLabel::paintEvent(event); - } - -private: - QColor m_color; -}; - -class CTrendDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - CTrendDelegate(QWidget *parent = 0); - - virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - virtual void setEditorData(QWidget *editor, const QModelIndex &index) const; - virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; - void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; - -protected: - bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); - -private: - QWidget * m_parent; -}; - -class CTrendEditModel : public QAbstractTableModel -{ - Q_OBJECT -public: - CTrendEditModel(QObject *parent = Q_NULLPTR); - ~CTrendEditModel(); - - void addTrendCurve(); - void removeTrendCurve(const QModelIndexList &indexList); - void clearTrendCurves(); - - void setTrendCurves(QList curves); - QList curves(); - - QColor color(const QModelIndex &index) const; - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual int columnCount(const QModelIndex &index = QModelIndex()) const; - virtual int rowCount(const QModelIndex &index = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - - QString checkAppendData(const QString& tag); - -private: - QStringList m_header; - QList m_listCurve; -}; - -#endif // CTRENDEDITMODEL_H +#ifndef CTRENDEDITMODEL_H +#define CTRENDEDITMODEL_H + +/***************************************** +/ * + * 趋势曲线设置视图模型 + * + * ***************************************/ + +#include +#include +#include +#include +#include +#include +#include "CTrendGraph.h" + +//Delegate Label +class CColorLabel : public QLabel +{ + Q_OBJECT +public: + CColorLabel(QWidget * parent = Q_NULLPTR) : QLabel(parent){} + + void setColor(const QColor &color) { m_color = color; } + QColor color() const { return m_color; } + +protected: + virtual void mousePressEvent(QMouseEvent *event) + { + QLabel::mousePressEvent(event); + QColor color = QColorDialog::getColor(m_color, this, tr("颜色选择"), QColorDialog::DontUseNativeDialog); + if(color.isValid()) + { + m_color = color; + } + } + + virtual void paintEvent(QPaintEvent * event) + { + QPainter p(this); + p.fillRect(rect(), QBrush(m_color)); + QLabel::paintEvent(event); + } + +private: + QColor m_color; +}; + +class CTrendDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CTrendDelegate(QWidget *parent = 0); + + virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual void setEditorData(QWidget *editor, const QModelIndex &index) const; + virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +protected: + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); + +private: + QWidget * m_parent; +}; + +class CTrendEditModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CTrendEditModel(QObject *parent = Q_NULLPTR); + ~CTrendEditModel(); + + void addTrendCurve(); + void removeTrendCurve(const QModelIndexList &indexList); + void clearTrendCurves(); + + void setTrendCurves(QList curves); + QList curves(); + + QColor color(const QModelIndex &index) const; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + QString checkAppendData(const QString& tag); + +private: + QStringList m_header; + QList m_listCurve; +}; + +#endif // CTRENDEDITMODEL_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditView.cpp b/product/src/gui/plugin/TrendCurves/CTrendEditView.cpp index 5fb3cf61..d6425e44 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditView.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendEditView.cpp @@ -1,98 +1,98 @@ -#include "CTrendEditView.h" -#include -#include -#include -#include -#include -#include -#include "CTrendEditModel.h" - -CTrendEditView::CTrendEditView(QWidget *parent) - : CTableView(parent) -{ - setAcceptDrops(true); - setDropIndicatorShown(true); - setDragEnabled(true); - setDragDropMode(QAbstractItemView::DragDrop); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setSelectionBehavior(QAbstractItemView::SelectRows); -} - -void CTrendEditView::appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti) -{ - Q_UNUSED(strTagDesc); - if(dynamic_cast(model())) - { - CTrendEditModel * curveDataModel = dynamic_cast(model()); - - QString ret = curveDataModel->checkAppendData(strTagName); - if(ret != "") - { - QMessageBox::warning(this, tr("提示"), ret); - return; - } - - if(!isMulti) - { - if(currentIndex() == QModelIndex()) - { - QMessageBox::warning(this, tr("提示"), tr("请选中一行!")); - return; - } - - curveDataModel->setData(currentIndex().sibling(currentIndex().row(), 0), strTagName); - } - else - { - curveDataModel->addTrendCurve(); - curveDataModel->setData(model()->sibling(model()->rowCount()-1, 0, currentIndex()), strTagName); - } - } -} - -void CTrendEditView::dragEnterEvent(QDragEnterEvent *event) -{ - if (event->mimeData()->hasText()) - { - event->acceptProposedAction(); - event->setDropAction(Qt::CopyAction); - } - else - { - event->setAccepted(false); - } -} - -void CTrendEditView::dragMoveEvent(QDragMoveEvent *event) -{ - if (event->mimeData()->hasText()) - { - event->acceptProposedAction(); - event->setDropAction(Qt::CopyAction); - } - else - { - event->setAccepted(false); - } -} - -void CTrendEditView::dropEvent(QDropEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasText()) - { - QString content = mimeData->text(); - if(dynamic_cast(model())) - { - CTrendEditModel * curveDataModel = dynamic_cast(model()); - QPoint pt = mapFromGlobal(QCursor::pos()); - pt.setY(pt.y() - horizontalHeader()->height()); - QModelIndex index = indexAt(pt); - if(!curveDataModel->setData(index.sibling(index.row(), 0), content)) - { - QMessageBox::warning(this, tr("警告"), tr("该测点已存在!")); - } - } - } - event->accept(); -} +#include "CTrendEditView.h" +#include +#include +#include +#include +#include +#include +#include "CTrendEditModel.h" + +CTrendEditView::CTrendEditView(QWidget *parent) + : CTableView(parent) +{ + setAcceptDrops(true); + setDropIndicatorShown(true); + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DragDrop); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); +} + +void CTrendEditView::appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti) +{ + Q_UNUSED(strTagDesc); + if(dynamic_cast(model())) + { + CTrendEditModel * curveDataModel = dynamic_cast(model()); + + QString ret = curveDataModel->checkAppendData(strTagName); + if(ret != "") + { + QMessageBox::warning(this, tr("提示"), ret); + return; + } + + if(!isMulti) + { + if(currentIndex() == QModelIndex()) + { + QMessageBox::warning(this, tr("提示"), tr("请选中一行!")); + return; + } + + curveDataModel->setData(currentIndex().sibling(currentIndex().row(), 0), strTagName); + } + else + { + curveDataModel->addTrendCurve(); + curveDataModel->setData(model()->sibling(model()->rowCount()-1, 0, currentIndex()), strTagName); + } + } +} + +void CTrendEditView::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + event->setDropAction(Qt::CopyAction); + } + else + { + event->setAccepted(false); + } +} + +void CTrendEditView::dragMoveEvent(QDragMoveEvent *event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + event->setDropAction(Qt::CopyAction); + } + else + { + event->setAccepted(false); + } +} + +void CTrendEditView::dropEvent(QDropEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + if (mimeData->hasText()) + { + QString content = mimeData->text(); + if(dynamic_cast(model())) + { + CTrendEditModel * curveDataModel = dynamic_cast(model()); + QPoint pt = mapFromGlobal(QCursor::pos()); + pt.setY(pt.y() - horizontalHeader()->height()); + QModelIndex index = indexAt(pt); + if(!curveDataModel->setData(index.sibling(index.row(), 0), content)) + { + QMessageBox::warning(this, tr("警告"), tr("该测点已存在!")); + } + } + } + event->accept(); +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditView.h b/product/src/gui/plugin/TrendCurves/CTrendEditView.h index 5f51d83e..313e06a4 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditView.h +++ b/product/src/gui/plugin/TrendCurves/CTrendEditView.h @@ -1,21 +1,21 @@ -#ifndef CTRENDEDITVIEW_H -#define CTRENDEDITVIEW_H - -#include "CTableView.h" - -class CTrendEditView : public CTableView -{ - Q_OBJECT -public: - CTrendEditView(QWidget *parent = Q_NULLPTR); - -public slots: - void appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti); - -protected: - void dragEnterEvent(QDragEnterEvent *event); - void dragMoveEvent(QDragMoveEvent *event); - void dropEvent(QDropEvent *event); -}; - -#endif // CTRENDEDITVIEW_H +#ifndef CTRENDEDITVIEW_H +#define CTRENDEDITVIEW_H + +#include "CTableView.h" + +class CTrendEditView : public CTableView +{ + Q_OBJECT +public: + CTrendEditView(QWidget *parent = Q_NULLPTR); + +public slots: + void appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); +}; + +#endif // CTRENDEDITVIEW_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.cpp b/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.cpp index 8b3fc271..0c60912c 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.cpp @@ -1,366 +1,366 @@ -#include "CTrendFavTreeWidget.h" -#include "CTrendEditDialog.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "perm_mng_api/PermMngApi.h" -#include "pub_utility_api/FileUtil.h" - -//< 趋势编辑 权限定义 -#define FUNC_NOM_TREND_EDIT ("FUNC_NOM_TREND_EDIT") - -CTrendFavTreeWidget::CTrendFavTreeWidget(QWidget *parent) - : QTreeWidget(parent) -{ - setColumnCount(1); - setHeaderLabel(tr("收藏夹")); - setSelectionMode(QAbstractItemView::ExtendedSelection); - setEditTriggers(EditKeyPressed); - connect(this, &CTrendFavTreeWidget::doubleClicked, this, &CTrendFavTreeWidget::slotShowTrendGraph); - connect(this, &CTrendFavTreeWidget::itemChanged, this, &CTrendFavTreeWidget::slotItemChanged); - setObjectName("CTrendFavTreeWidget"); - loadTrendGraph(); - setEditTriggers(NoEditTriggers); -} - -CTrendFavTreeWidget::~CTrendFavTreeWidget() -{ - savaTrendGraph(); - qDeleteAll(m_trendGraphMap); - m_trendGraphMap.clear(); -} - -void CTrendFavTreeWidget::collectGraph(const QString &title, const CTrendGraph &graph) -{ - for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) - { - if(topLevelItem(nIndex)->text(0) == title ) - { - QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); - return; - } - } - - QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << title, Item_GRAPH_Type); - item->setFlags(item->flags() | Qt::ItemIsEditable); - addTopLevelItem(item); - CTrendGraph * tmp = new CTrendGraph(); - tmp->setCurves(graph.curves()); - tmp->removeCurve("curve.tag"); - m_trendGraphMap.insert(item, tmp); - savaTrendGraph(); -} - - -void CTrendFavTreeWidget::contextMenuEvent(QContextMenuEvent *event) -{ - //< 权限处理--暂不处理 -// bool bIsEditable = false; -// kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); -// if(permMngPtr == NULL) -// { -// return; -// } - -// permMngPtr->PermDllInit(); -// std::string tmp = FUNC_NOM_TREND_EDIT; -// if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) -// { -// bIsEditable = true; -// } - - QMenu menu; - QTreeWidgetItem * item = itemAt(event->pos()); - - if(!item) - { - QAction * newAction = new QAction(tr("添加趋势"), &menu); - menu.addAction(newAction); - connect(newAction, SIGNAL(triggered()), this, SLOT(slotNewTrendEdit())); - - QAction * importAction = new QAction(tr("导入"), &menu); - menu.addAction(importAction); - connect(importAction, SIGNAL(triggered()), this, SLOT(slotImport())); - } - else - { - if(Item_GRAPH_Type == item->type()) - { - QAction * showAction = new QAction(tr("显示"), &menu); - menu.addAction(showAction); - connect(showAction, SIGNAL(triggered()), this, SLOT(slotShowTrendGraph())); - - QAction * editAction = new QAction(tr("编辑"), &menu); - menu.addAction(editAction); - connect(editAction, SIGNAL(triggered()), this, SLOT(slotEditTrendEdit())); - - QAction * renameAction = new QAction(tr("重命名"), &menu); - menu.addAction(renameAction); - connect(renameAction, &QAction::triggered, this, [&]() { - m_strEditItemContent = item->text(0); - editItem(item);}); - - QAction * deleteAction = new QAction(tr("删除"), &menu); - menu.addAction(deleteAction); - connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotRemoveTrendEdit())); - - QAction * exportAction = new QAction(tr("导出"), &menu); - menu.addAction(exportAction); - connect(exportAction, SIGNAL(triggered()), this, SLOT(slotExport())); - } - } - - menu.exec(event->globalPos()); -} - -void CTrendFavTreeWidget::slotNewTrendEdit() -{ - QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << getNewValidTitle(), Item_GRAPH_Type); - item->setFlags(item->flags() | Qt::ItemIsEditable); - addTopLevelItem(item); - editItem(item); -} - -void CTrendFavTreeWidget::slotShowTrendGraph() -{ - if(!m_trendGraphMap.contains(currentItem())) - { - CTrendGraph * graph = new CTrendGraph; - m_trendGraphMap.insert(currentItem(), graph); - } - emit showTrendGraph(m_trendGraphMap.value(currentItem()), currentItem()->text(0)); -} - -void CTrendFavTreeWidget::slotEditTrendEdit() -{ - CTrendEditDialog *dlg = new CTrendEditDialog(this); - - if(m_trendGraphMap.contains(currentItem())) - { - dlg->setTrendGraph(m_trendGraphMap.value(currentItem())); - } - if(QDialog::Accepted == dlg->exec()) - { - CTrendGraph * graph = dlg->trendGraph(); - - m_trendGraphMap.insert(currentItem(), graph); - savaTrendGraph(); - } - - delete dlg; - dlg = NULL; -} - -void CTrendFavTreeWidget::slotRemoveTrendEdit() -{ - QList selectItem = selectedItems(); - foreach (QTreeWidgetItem *item, selectItem) { - int index = indexOfTopLevelItem(item); - takeTopLevelItem(index); - } - savaTrendGraph(); -} - -void CTrendFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) -{ - Q_UNUSED(column) - QString content = item->text(0); - for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) - { - QTreeWidgetItem *temp = topLevelItem(nIndex); - if( temp != item && temp->text(0) == content ) - { - QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); - item->setText(0, m_strEditItemContent); - return; - } - } -} - -void CTrendFavTreeWidget::slotImport() -{ - QString filePath = QFileDialog::getOpenFileName(this, tr("选择趋势收藏文件"), QString(), "*.xml"); - if(filePath.isEmpty()) - { - return; - } - loadTrendGraph(filePath); - savaTrendGraph(); -} - -void CTrendFavTreeWidget::slotExport() -{ - QString filePath = QFileDialog::getSaveFileName(this, tr("保存趋势收藏文件"), QString("trendFav.xml"), "*.xml"); - if(filePath.isEmpty()) - { - return; - } - - QList selectItem = selectedItems(); - if(selectItem.isEmpty()) - { - return; - } - - savaTrendGraph(filePath, selectItem); -} - -QString CTrendFavTreeWidget::getNewValidTitle() -{ - QString title = QString("自定义趋势_"); - QStringList listItemText; - for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) - { - listItemText << topLevelItem(nIndex)->text(0); - } - int serial = 0; - while(listItemText.contains(title + QString::number(serial))) - { - serial++; - } - return title + QString::number(serial); -} - -void CTrendFavTreeWidget::loadTrendGraph(const QString &filePath) -{ - QDomDocument document; - QString strFileName; - if(filePath.isEmpty()) - { - strFileName = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); - } - else - { - strFileName = filePath; - } - QFile file(strFileName); - if (!file.open(QIODevice::ReadOnly)) - { - return; - } - if (!document.setContent(&file)) - { - file.close(); - return; - } - file.close(); - - QDomElement root = document.documentElement(); - if(!root.isNull()) - { - QDomNodeList graphNodeList = root.elementsByTagName("graph"); - for(int graphIndex(0); graphIndex < graphNodeList.size(); graphIndex++) - { - QDomNode graphNode = graphNodeList.at(graphIndex); - if(!graphNode.isNull()) - { - QDomElement graphElement = graphNode.toElement(); - if(!graphElement.isNull()) - { - QString name = graphElement.attribute("name", QString()); - QTreeWidgetItem * graphItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); - graphItem->setFlags(graphItem->flags() | Qt::ItemIsEditable); - - QList curves; - QDomNodeList curveNodeList = graphElement.elementsByTagName("curve"); - for(int nCurveIndex(0); nCurveIndex < curveNodeList.size(); nCurveIndex++) - { - QDomNode curveNode = curveNodeList.at(nCurveIndex); - QDomElement curveElement = curveNode.toElement(); - if(!curveElement.isNull()) - { - QDomNodeList itemList = curveElement.elementsByTagName("item"); - for(int itemIndex(0); itemIndex < itemList.size(); itemIndex++) - { - QDomNode itemNode = itemList.at(itemIndex); - - if(!itemNode.isNull()) - { - while(!itemNode.isNull()) - { - QDomElement item = itemNode.toElement(); - if(!item.isNull()) - { - Curve curve; - curve.tag = item.attribute("tag"); - curve.color = QColor(item.attribute("color").toUInt() & 0x00ffffff); - curves.append(curve); - } - itemNode = curveNode.nextSibling(); - } - } - } - } - } - CTrendGraph * graph = new CTrendGraph(); - graph->setCurves(curves); - m_trendGraphMap.insert(graphItem, graph); - addTopLevelItem(graphItem); - } - } - } - } -} - -void CTrendFavTreeWidget::savaTrendGraph(const QString &filePath, const QList &itemList) -{ - QFile file; - if(!filePath.isEmpty()) - { - file.setFileName(filePath); - } - else - { - QString strTrendDir = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model"); - QDir dir; - if(!dir.exists(strTrendDir)) - { - dir.mkdir(strTrendDir); - } - QString strTrendFile = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); - file.setFileName(strTrendFile); - } - - if(file.open(QIODevice::WriteOnly | QIODevice::Text)) - { - QDomDocument document; - - QString strHeader("version='1.0' encoding='utf-8'"); - document.appendChild(document.createProcessingInstruction("xml", strHeader)); - QDomElement root = document.createElement("Profile"); - int nCount = itemList.isEmpty()? topLevelItemCount():itemList.length(); - for(int nIndex(0); nIndex < nCount; nIndex++) - { - QTreeWidgetItem * item = itemList.isEmpty()? topLevelItem(nIndex):itemList.at(nIndex); - QDomElement graphNode = document.createElement("graph"); - graphNode.setAttribute("name", item->text(0)); - - QDomElement curveNode = document.createElement("curve"); - if(m_trendGraphMap.contains(item)) - { - const QList listCurve = m_trendGraphMap.value(item)->curves(); - for(int nCurveIndex(0); nCurveIndex < listCurve.size(); nCurveIndex++) - { - Curve curve = listCurve.at(nCurveIndex); - QDomElement item = document.createElement("item"); - item.setAttribute("tag", curve.tag); - item.setAttribute("color", curve.color.rgb()); - curveNode.appendChild(item); - } - } - graphNode.appendChild(curveNode); - root.appendChild(graphNode); - } - document.appendChild(root); - - QTextStream content(&file); - document.save(content, 4); - } - file.close(); -} +#include "CTrendFavTreeWidget.h" +#include "CTrendEditDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "perm_mng_api/PermMngApi.h" +#include "pub_utility_api/FileUtil.h" + +//< 趋势编辑 权限定义 +#define FUNC_NOM_TREND_EDIT ("FUNC_NOM_TREND_EDIT") + +CTrendFavTreeWidget::CTrendFavTreeWidget(QWidget *parent) + : QTreeWidget(parent) +{ + setColumnCount(1); + setHeaderLabel(tr("收藏夹")); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setEditTriggers(EditKeyPressed); + connect(this, &CTrendFavTreeWidget::doubleClicked, this, &CTrendFavTreeWidget::slotShowTrendGraph); + connect(this, &CTrendFavTreeWidget::itemChanged, this, &CTrendFavTreeWidget::slotItemChanged); + setObjectName("CTrendFavTreeWidget"); + loadTrendGraph(); + setEditTriggers(NoEditTriggers); +} + +CTrendFavTreeWidget::~CTrendFavTreeWidget() +{ + savaTrendGraph(); + qDeleteAll(m_trendGraphMap); + m_trendGraphMap.clear(); +} + +void CTrendFavTreeWidget::collectGraph(const QString &title, const CTrendGraph &graph) +{ + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->text(0) == title ) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + return; + } + } + + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << title, Item_GRAPH_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + CTrendGraph * tmp = new CTrendGraph(); + tmp->setCurves(graph.curves()); + tmp->removeCurve("curve.tag"); + m_trendGraphMap.insert(item, tmp); + savaTrendGraph(); +} + + +void CTrendFavTreeWidget::contextMenuEvent(QContextMenuEvent *event) +{ + //< 权限处理--暂不处理 +// bool bIsEditable = false; +// kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); +// if(permMngPtr == NULL) +// { +// return; +// } + +// permMngPtr->PermDllInit(); +// std::string tmp = FUNC_NOM_TREND_EDIT; +// if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) +// { +// bIsEditable = true; +// } + + QMenu menu; + QTreeWidgetItem * item = itemAt(event->pos()); + + if(!item) + { + QAction * newAction = new QAction(tr("添加趋势"), &menu); + menu.addAction(newAction); + connect(newAction, SIGNAL(triggered()), this, SLOT(slotNewTrendEdit())); + + QAction * importAction = new QAction(tr("导入"), &menu); + menu.addAction(importAction); + connect(importAction, SIGNAL(triggered()), this, SLOT(slotImport())); + } + else + { + if(Item_GRAPH_Type == item->type()) + { + QAction * showAction = new QAction(tr("显示"), &menu); + menu.addAction(showAction); + connect(showAction, SIGNAL(triggered()), this, SLOT(slotShowTrendGraph())); + + QAction * editAction = new QAction(tr("编辑"), &menu); + menu.addAction(editAction); + connect(editAction, SIGNAL(triggered()), this, SLOT(slotEditTrendEdit())); + + QAction * renameAction = new QAction(tr("重命名"), &menu); + menu.addAction(renameAction); + connect(renameAction, &QAction::triggered, this, [&]() { + m_strEditItemContent = item->text(0); + editItem(item);}); + + QAction * deleteAction = new QAction(tr("删除"), &menu); + menu.addAction(deleteAction); + connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotRemoveTrendEdit())); + + QAction * exportAction = new QAction(tr("导出"), &menu); + menu.addAction(exportAction); + connect(exportAction, SIGNAL(triggered()), this, SLOT(slotExport())); + } + } + + menu.exec(event->globalPos()); +} + +void CTrendFavTreeWidget::slotNewTrendEdit() +{ + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << getNewValidTitle(), Item_GRAPH_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + editItem(item); +} + +void CTrendFavTreeWidget::slotShowTrendGraph() +{ + if(!m_trendGraphMap.contains(currentItem())) + { + CTrendGraph * graph = new CTrendGraph; + m_trendGraphMap.insert(currentItem(), graph); + } + emit showTrendGraph(m_trendGraphMap.value(currentItem()), currentItem()->text(0)); +} + +void CTrendFavTreeWidget::slotEditTrendEdit() +{ + CTrendEditDialog *dlg = new CTrendEditDialog(this); + + if(m_trendGraphMap.contains(currentItem())) + { + dlg->setTrendGraph(m_trendGraphMap.value(currentItem())); + } + if(QDialog::Accepted == dlg->exec()) + { + CTrendGraph * graph = dlg->trendGraph(); + + m_trendGraphMap.insert(currentItem(), graph); + savaTrendGraph(); + } + + delete dlg; + dlg = NULL; +} + +void CTrendFavTreeWidget::slotRemoveTrendEdit() +{ + QList selectItem = selectedItems(); + foreach (QTreeWidgetItem *item, selectItem) { + int index = indexOfTopLevelItem(item); + takeTopLevelItem(index); + } + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column) + QString content = item->text(0); + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + QTreeWidgetItem *temp = topLevelItem(nIndex); + if( temp != item && temp->text(0) == content ) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + item->setText(0, m_strEditItemContent); + return; + } + } +} + +void CTrendFavTreeWidget::slotImport() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("选择趋势收藏文件"), QString(), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + loadTrendGraph(filePath); + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotExport() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("保存趋势收藏文件"), QString("trendFav.xml"), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + + QList selectItem = selectedItems(); + if(selectItem.isEmpty()) + { + return; + } + + savaTrendGraph(filePath, selectItem); +} + +QString CTrendFavTreeWidget::getNewValidTitle() +{ + QString title = QString("自定义趋势_"); + QStringList listItemText; + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + listItemText << topLevelItem(nIndex)->text(0); + } + int serial = 0; + while(listItemText.contains(title + QString::number(serial))) + { + serial++; + } + return title + QString::number(serial); +} + +void CTrendFavTreeWidget::loadTrendGraph(const QString &filePath) +{ + QDomDocument document; + QString strFileName; + if(filePath.isEmpty()) + { + strFileName = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); + } + else + { + strFileName = filePath; + } + QFile file(strFileName); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(!root.isNull()) + { + QDomNodeList graphNodeList = root.elementsByTagName("graph"); + for(int graphIndex(0); graphIndex < graphNodeList.size(); graphIndex++) + { + QDomNode graphNode = graphNodeList.at(graphIndex); + if(!graphNode.isNull()) + { + QDomElement graphElement = graphNode.toElement(); + if(!graphElement.isNull()) + { + QString name = graphElement.attribute("name", QString()); + QTreeWidgetItem * graphItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); + graphItem->setFlags(graphItem->flags() | Qt::ItemIsEditable); + + QList curves; + QDomNodeList curveNodeList = graphElement.elementsByTagName("curve"); + for(int nCurveIndex(0); nCurveIndex < curveNodeList.size(); nCurveIndex++) + { + QDomNode curveNode = curveNodeList.at(nCurveIndex); + QDomElement curveElement = curveNode.toElement(); + if(!curveElement.isNull()) + { + QDomNodeList itemList = curveElement.elementsByTagName("item"); + for(int itemIndex(0); itemIndex < itemList.size(); itemIndex++) + { + QDomNode itemNode = itemList.at(itemIndex); + + if(!itemNode.isNull()) + { + while(!itemNode.isNull()) + { + QDomElement item = itemNode.toElement(); + if(!item.isNull()) + { + Curve curve; + curve.tag = item.attribute("tag"); + curve.color = QColor(item.attribute("color").toUInt() & 0x00ffffff); + curves.append(curve); + } + itemNode = curveNode.nextSibling(); + } + } + } + } + } + CTrendGraph * graph = new CTrendGraph(); + graph->setCurves(curves); + m_trendGraphMap.insert(graphItem, graph); + addTopLevelItem(graphItem); + } + } + } + } +} + +void CTrendFavTreeWidget::savaTrendGraph(const QString &filePath, const QList &itemList) +{ + QFile file; + if(!filePath.isEmpty()) + { + file.setFileName(filePath); + } + else + { + QString strTrendDir = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model"); + QDir dir; + if(!dir.exists(strTrendDir)) + { + dir.mkdir(strTrendDir); + } + QString strTrendFile = QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); + file.setFileName(strTrendFile); + } + + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QDomDocument document; + + QString strHeader("version='1.0' encoding='utf-8'"); + document.appendChild(document.createProcessingInstruction("xml", strHeader)); + QDomElement root = document.createElement("Profile"); + int nCount = itemList.isEmpty()? topLevelItemCount():itemList.length(); + for(int nIndex(0); nIndex < nCount; nIndex++) + { + QTreeWidgetItem * item = itemList.isEmpty()? topLevelItem(nIndex):itemList.at(nIndex); + QDomElement graphNode = document.createElement("graph"); + graphNode.setAttribute("name", item->text(0)); + + QDomElement curveNode = document.createElement("curve"); + if(m_trendGraphMap.contains(item)) + { + const QList listCurve = m_trendGraphMap.value(item)->curves(); + for(int nCurveIndex(0); nCurveIndex < listCurve.size(); nCurveIndex++) + { + Curve curve = listCurve.at(nCurveIndex); + QDomElement item = document.createElement("item"); + item.setAttribute("tag", curve.tag); + item.setAttribute("color", curve.color.rgb()); + curveNode.appendChild(item); + } + } + graphNode.appendChild(curveNode); + root.appendChild(graphNode); + } + document.appendChild(root); + + QTextStream content(&file); + document.save(content, 4); + } + file.close(); +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.h b/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.h index 4a4feed1..a17332b9 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.h +++ b/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.h @@ -1,49 +1,49 @@ -#ifndef CTRENDFAVTREEWIDGET_H -#define CTRENDFAVTREEWIDGET_H - -#include - -enum E_Tree_ItemType -{ - Item_GRAPH_Type = QTreeWidgetItem::UserType + 1, - Item_TAG_Type, -}; - -class CTrendGraph; - -class CTrendFavTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - explicit CTrendFavTreeWidget(QWidget *parent = nullptr); - ~CTrendFavTreeWidget(); - -signals: - void showTrendGraph(CTrendGraph * graph, QString name); - -public slots: - void collectGraph(const QString &title, const CTrendGraph &graph); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - -protected slots: - void slotNewTrendEdit(); - void slotShowTrendGraph(); - void slotEditTrendEdit(); - void slotRemoveTrendEdit(); - void slotItemChanged(QTreeWidgetItem *item, int column); - void slotImport(); - void slotExport(); - -private: - QString getNewValidTitle(); - void loadTrendGraph(const QString& filePath = QString()); - void savaTrendGraph(const QString& filePath = QString(), const QList& itemList = QList()); - -private: - QMap m_trendGraphMap; - QString m_strEditItemContent; -}; - -#endif // CTRENDFAVTREEWIDGET_H +#ifndef CTRENDFAVTREEWIDGET_H +#define CTRENDFAVTREEWIDGET_H + +#include + +enum E_Tree_ItemType +{ + Item_GRAPH_Type = QTreeWidgetItem::UserType + 1, + Item_TAG_Type, +}; + +class CTrendGraph; + +class CTrendFavTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + explicit CTrendFavTreeWidget(QWidget *parent = nullptr); + ~CTrendFavTreeWidget(); + +signals: + void showTrendGraph(CTrendGraph * graph, QString name); + +public slots: + void collectGraph(const QString &title, const CTrendGraph &graph); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +protected slots: + void slotNewTrendEdit(); + void slotShowTrendGraph(); + void slotEditTrendEdit(); + void slotRemoveTrendEdit(); + void slotItemChanged(QTreeWidgetItem *item, int column); + void slotImport(); + void slotExport(); + +private: + QString getNewValidTitle(); + void loadTrendGraph(const QString& filePath = QString()); + void savaTrendGraph(const QString& filePath = QString(), const QList& itemList = QList()); + +private: + QMap m_trendGraphMap; + QString m_strEditItemContent; +}; + +#endif // CTRENDFAVTREEWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendGraph.cpp b/product/src/gui/plugin/TrendCurves/CTrendGraph.cpp index 3ea861ab..cd61158b 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendGraph.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendGraph.cpp @@ -1,242 +1,242 @@ -#include "CTrendGraph.h" -#include -#include "plot/qcustomplot.h" - -const double _EPSILON_ = 1e-5; - -CTrendGraph::CTrendGraph() -{ - -} - -CTrendGraph::~CTrendGraph() -{ - clear(); -} - -const QList CTrendGraph::curves() const -{ - return m_listCurve; -} - -void CTrendGraph::setCurves(QList listCurve) -{ - m_listCurve.swap(listCurve); -} - -const QList CTrendGraph::curveColors() const -{ - QList list; - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - list.append(m_listCurve[nIndex].color); - } - return list; -} - -const Curve &CTrendGraph::curve(const QString &tag) const -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - return m_listCurve.at(nIndex); - } - } - - Q_ASSERT_X(false, "CTrendGraph::curve", "curve is not exists"); -} - -int CTrendGraph::index(const QString &tag) const -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - return nIndex; - } - } - return -1; -} - -void CTrendGraph::clear() -{ - m_listCurve.clear(); -} - -void CTrendGraph::addCurve(const Curve &curve) -{ - m_listCurve.append(curve); -} - -int CTrendGraph::removeCurve(const QString &tag) -{ - for(int nIndex(m_listCurve.size() - 1); nIndex >= 0; nIndex--) - { - if(m_listCurve.at(nIndex).tag == tag) - { - m_listCurve.removeAt(nIndex); - return nIndex; - } - } - return -1; -} - -void CTrendGraph::setCurveVisible(const int &nIndex, const bool &visible) -{ - m_listCurve[nIndex].visible = visible; -} - -void CTrendGraph::setCurveColor(const int &nIndex, const QColor &color) -{ - m_listCurve[nIndex].color = color; -} - -void CTrendGraph::setCurveFactor(const int &nIndex, const double &factor) -{ - m_listCurve[nIndex].factor = factor; -} - -void CTrendGraph::setCurveOffset(const int &nIndex, const double &offset) -{ - m_listCurve[nIndex].offset = offset; -} - -void CTrendGraph::setCurveGraphFactor(const int &nIndex, const double &factor) -{ - m_listCurve[nIndex].graphFactor = factor; -} - -void CTrendGraph::setCurveGraphOffset(const int &nIndex, const double &offset) -{ - m_listCurve[nIndex].graphOffset = offset; -} - -void CTrendGraph::setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range) -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - m_listCurve[nIndex].hisMax = max; - m_listCurve[nIndex].hisMin = min; - m_listCurve[nIndex].hisAverage = average; - m_listCurve[nIndex].hisAccuml = accuml; - m_listCurve[nIndex].hisPlotRange = range; - m_listCurve[nIndex].hisMaxTime = maxTime; - m_listCurve[nIndex].hisMinTime = minTime; - } - } -} - -void CTrendGraph::pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status) -{ - //< 保留20min实时数据 - int nIndex = m_listCurve.indexOf(tag); - if (-1 == nIndex || qIsNaN(value)) - { - return; - } - - Curve &curve = m_listCurve[nIndex]; - curve.values.append(qMakePair>( - key, qMakePair(value, status))); - QVector< QPair > > &values = curve.values; - if (values.first().first < (key - (20 * 60 * 1000))) - { - values.removeFirst(); - } -} - -void CTrendGraph::setCurveStatisMax(const QString &tag, const double &max, const double &maxTime) -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - m_listCurve[nIndex].sHisMax = max; - m_listCurve[nIndex].sHisMaxTime = maxTime; - } - } -} - -void CTrendGraph::setCurveStatisMin(const QString &tag, const double &min, const double &minTime) -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - m_listCurve[nIndex].sHisMin = min; - m_listCurve[nIndex].sHisMinTime = minTime; - } - } -} - -void CTrendGraph::resetCurveStatisMax(const QString &tag) -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - m_listCurve[nIndex].sHisMax = -DBL_MAX; - m_listCurve[nIndex].sHisMaxTime = -DBL_MAX; - } - } -} - -void CTrendGraph::resetCurveStatisMin(const QString &tag) -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == tag) - { - m_listCurve[nIndex].sHisMin = DBL_MAX; - m_listCurve[nIndex].sHisMinTime = DBL_MAX; - } - } -} - -void CTrendGraph::updateRTCurveStatisticsInfo(const QString &strTagName) -{ - for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) - { - if(m_listCurve.at(nIndex).tag == strTagName) - { - updateRTCurveStatisticsInfo(m_listCurve[nIndex]); - return; - } - } -} - -void CTrendGraph::updateRTCurveStatisticsInfo(Curve &curve) -{ - //< 计算10min内实时数据最大值、最小值、累计值、平均值 - qreal rtMax = -DBL_MAX; - qreal rtMin = DBL_MAX; - qreal rtMaxTime = -DBL_MAX; - qreal rtMinTime = DBL_MAX; - qreal rtAccuml = 0; - int nIndex = curve.values.size(); - double validKey = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()) - (10 * 60 * 1000); - while (--nIndex >= 0 && curve.values.at(nIndex).first >= validKey) - { - if (curve.values.at(nIndex).second.first <= rtMin) - { - rtMin = curve.values.at(nIndex).second.first; - rtMinTime = curve.values.at(nIndex).first; - } - if(curve.values.at(nIndex).second.first >= rtMax) - { - rtMax = curve.values.at(nIndex).second.first; - rtMaxTime = curve.values.at(nIndex).first; - } - rtAccuml += curve.values.at(nIndex).second.first; - } - - curve.rtMin = rtMin; - curve.rtMax = rtMax; - curve.rtMinTime = rtMinTime; - curve.rtMaxTime = rtMaxTime; - curve.rtAccuml = rtAccuml; - curve.rtAverage = rtAccuml / (curve.values.size() - (nIndex + 1)); -} +#include "CTrendGraph.h" +#include +#include "plot/qcustomplot.h" + +const double _EPSILON_ = 1e-5; + +CTrendGraph::CTrendGraph() +{ + +} + +CTrendGraph::~CTrendGraph() +{ + clear(); +} + +const QList CTrendGraph::curves() const +{ + return m_listCurve; +} + +void CTrendGraph::setCurves(QList listCurve) +{ + m_listCurve.swap(listCurve); +} + +const QList CTrendGraph::curveColors() const +{ + QList list; + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + list.append(m_listCurve[nIndex].color); + } + return list; +} + +const Curve &CTrendGraph::curve(const QString &tag) const +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + return m_listCurve.at(nIndex); + } + } + + Q_ASSERT_X(false, "CTrendGraph::curve", "curve is not exists"); +} + +int CTrendGraph::index(const QString &tag) const +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + return nIndex; + } + } + return -1; +} + +void CTrendGraph::clear() +{ + m_listCurve.clear(); +} + +void CTrendGraph::addCurve(const Curve &curve) +{ + m_listCurve.append(curve); +} + +int CTrendGraph::removeCurve(const QString &tag) +{ + for(int nIndex(m_listCurve.size() - 1); nIndex >= 0; nIndex--) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve.removeAt(nIndex); + return nIndex; + } + } + return -1; +} + +void CTrendGraph::setCurveVisible(const int &nIndex, const bool &visible) +{ + m_listCurve[nIndex].visible = visible; +} + +void CTrendGraph::setCurveColor(const int &nIndex, const QColor &color) +{ + m_listCurve[nIndex].color = color; +} + +void CTrendGraph::setCurveFactor(const int &nIndex, const double &factor) +{ + m_listCurve[nIndex].factor = factor; +} + +void CTrendGraph::setCurveOffset(const int &nIndex, const double &offset) +{ + m_listCurve[nIndex].offset = offset; +} + +void CTrendGraph::setCurveGraphFactor(const int &nIndex, const double &factor) +{ + m_listCurve[nIndex].graphFactor = factor; +} + +void CTrendGraph::setCurveGraphOffset(const int &nIndex, const double &offset) +{ + m_listCurve[nIndex].graphOffset = offset; +} + +void CTrendGraph::setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve[nIndex].hisMax = max; + m_listCurve[nIndex].hisMin = min; + m_listCurve[nIndex].hisAverage = average; + m_listCurve[nIndex].hisAccuml = accuml; + m_listCurve[nIndex].hisPlotRange = range; + m_listCurve[nIndex].hisMaxTime = maxTime; + m_listCurve[nIndex].hisMinTime = minTime; + } + } +} + +void CTrendGraph::pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status) +{ + //< 保留20min实时数据 + int nIndex = m_listCurve.indexOf(tag); + if (-1 == nIndex || qIsNaN(value)) + { + return; + } + + Curve &curve = m_listCurve[nIndex]; + curve.values.append(qMakePair>( + key, qMakePair(value, status))); + QVector< QPair > > &values = curve.values; + if (values.first().first < (key - (20 * 60 * 1000))) + { + values.removeFirst(); + } +} + +void CTrendGraph::setCurveStatisMax(const QString &tag, const double &max, const double &maxTime) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve[nIndex].sHisMax = max; + m_listCurve[nIndex].sHisMaxTime = maxTime; + } + } +} + +void CTrendGraph::setCurveStatisMin(const QString &tag, const double &min, const double &minTime) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve[nIndex].sHisMin = min; + m_listCurve[nIndex].sHisMinTime = minTime; + } + } +} + +void CTrendGraph::resetCurveStatisMax(const QString &tag) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve[nIndex].sHisMax = -DBL_MAX; + m_listCurve[nIndex].sHisMaxTime = -DBL_MAX; + } + } +} + +void CTrendGraph::resetCurveStatisMin(const QString &tag) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve[nIndex].sHisMin = DBL_MAX; + m_listCurve[nIndex].sHisMinTime = DBL_MAX; + } + } +} + +void CTrendGraph::updateRTCurveStatisticsInfo(const QString &strTagName) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == strTagName) + { + updateRTCurveStatisticsInfo(m_listCurve[nIndex]); + return; + } + } +} + +void CTrendGraph::updateRTCurveStatisticsInfo(Curve &curve) +{ + //< 计算10min内实时数据最大值、最小值、累计值、平均值 + qreal rtMax = -DBL_MAX; + qreal rtMin = DBL_MAX; + qreal rtMaxTime = -DBL_MAX; + qreal rtMinTime = DBL_MAX; + qreal rtAccuml = 0; + int nIndex = curve.values.size(); + double validKey = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()) - (10 * 60 * 1000); + while (--nIndex >= 0 && curve.values.at(nIndex).first >= validKey) + { + if (curve.values.at(nIndex).second.first <= rtMin) + { + rtMin = curve.values.at(nIndex).second.first; + rtMinTime = curve.values.at(nIndex).first; + } + if(curve.values.at(nIndex).second.first >= rtMax) + { + rtMax = curve.values.at(nIndex).second.first; + rtMaxTime = curve.values.at(nIndex).first; + } + rtAccuml += curve.values.at(nIndex).second.first; + } + + curve.rtMin = rtMin; + curve.rtMax = rtMax; + curve.rtMinTime = rtMinTime; + curve.rtMaxTime = rtMaxTime; + curve.rtAccuml = rtAccuml; + curve.rtAverage = rtAccuml / (curve.values.size() - (nIndex + 1)); +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendGraph.h b/product/src/gui/plugin/TrendCurves/CTrendGraph.h index e83ba74f..f17e5ee8 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendGraph.h +++ b/product/src/gui/plugin/TrendCurves/CTrendGraph.h @@ -1,152 +1,152 @@ -#ifndef CTRENDGRAPH_H -#define CTRENDGRAPH_H - -#include -#include -#include -#include -#include -#include - -/******************************趋势图形************************** - * 此类包含趋势静态配置属性 - **************************************************************/ -extern const double _EPSILON_; - -struct Range -{ - Range() - : min(DBL_MAX), - max(-DBL_MAX) - {} - - Range(double _min, double _max) - : min(_min), - max(_max) - {} - double min; - double max; -}; - -struct Curve -{ - Curve(const QString &strTagName = QString()) - : visible(true), - rtMax(-DBL_MAX), - rtMin(DBL_MAX), - rtAverage(-DBL_MAX), - rtAccuml(0), - hisMax(-DBL_MAX), - hisMin(DBL_MAX), - hisAverage(-DBL_MAX), - hisAccuml(0), - graphFactor(1.), - graphOffset(0.), - factor(1.), - offset(0.), - rtMaxTime(-DBL_MAX), - rtMinTime(DBL_MAX), - hisMaxTime(-DBL_MAX), - hisMinTime(DBL_MAX), - sHisMax(-DBL_MAX), - sHisMin(DBL_MAX), - sHisMaxTime(-DBL_MAX), - sHisMinTime(DBL_MAX), - tag(strTagName), - desc(QString()), - type(QString()), - unit(QString()), - color(QColor()){} - - inline bool operator==(const Curve &curve) const - { - return tag == curve.tag; - } - - inline bool operator==(const QString &strTagName) const - { - return tag == strTagName; - } - - bool visible; - double rtMax; - double rtMin; - double rtAverage; - double rtAccuml; - double hisMax; - double hisMin; - double hisAverage; - double hisAccuml; - double graphFactor; - double graphOffset; - double factor; - double offset; - double rtMaxTime; - double rtMinTime; - double hisMaxTime; - double hisMinTime; - double sHisMax; //< 实际的最大值(influx统计),仅用于显示 - double sHisMin; //< 实际的最小值(influx统计),仅用于显示 - double sHisMaxTime; //< 实际的最大值时间(influx统计),仅用于显示 - double sHisMinTime; //< 实际的最小值时间(influx统计),仅用于显示 - - Range hisPlotRange; //< hisPlotRange > Range(hisMin, hisMax) [趋势对比计算刻度] - - QString tag; - QString desc; - QString type; - QString unit; - QColor color; - - QVector< QPair > > values; -}; - -class CTrendGraph -{ -public: - CTrendGraph(); - - ~CTrendGraph(); - - const QList curves() const; - void setCurves(QList listCurve); - - const QList curveColors() const; - - const Curve &curve(const QString &tag) const; - int index(const QString &tag) const; - - void clear(); - - void addCurve(const Curve &curve); - int removeCurve(const QString &tag); - - void setCurveVisible(const int &nIndex, const bool &visible); - - void setCurveColor(const int &nIndex, const QColor &color); - void setCurveFactor(const int &nIndex, const double &factor); - void setCurveOffset(const int &nIndex, const double &offset); - - void setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range); - void pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status); - - void setCurveStatisMax(const QString &tag, const double &max, const double &maxTime); - void setCurveStatisMin(const QString &tag, const double &min, const double &minTime); - - void resetCurveStatisMax(const QString &tag); - void resetCurveStatisMin(const QString &tag); - - void setCurveGraphFactor(const int &nIndex, const double &factor); - void setCurveGraphOffset(const int &nIndex, const double &offset); - - //< 更新实时曲线统计信息 - void updateRTCurveStatisticsInfo(const QString &strTagName); - void updateRTCurveStatisticsInfo(Curve &curve); - -private: - QList m_listCurve; -}; - -#endif // CTRENDGRAPH_H - - +#ifndef CTRENDGRAPH_H +#define CTRENDGRAPH_H + +#include +#include +#include +#include +#include +#include + +/******************************趋势图形************************** + * 此类包含趋势静态配置属性 + **************************************************************/ +extern const double _EPSILON_; + +struct Range +{ + Range() + : min(DBL_MAX), + max(-DBL_MAX) + {} + + Range(double _min, double _max) + : min(_min), + max(_max) + {} + double min; + double max; +}; + +struct Curve +{ + Curve(const QString &strTagName = QString()) + : visible(true), + rtMax(-DBL_MAX), + rtMin(DBL_MAX), + rtAverage(-DBL_MAX), + rtAccuml(0), + hisMax(-DBL_MAX), + hisMin(DBL_MAX), + hisAverage(-DBL_MAX), + hisAccuml(0), + graphFactor(1.), + graphOffset(0.), + factor(1.), + offset(0.), + rtMaxTime(-DBL_MAX), + rtMinTime(DBL_MAX), + hisMaxTime(-DBL_MAX), + hisMinTime(DBL_MAX), + sHisMax(-DBL_MAX), + sHisMin(DBL_MAX), + sHisMaxTime(-DBL_MAX), + sHisMinTime(DBL_MAX), + tag(strTagName), + desc(QString()), + type(QString()), + unit(QString()), + color(QColor()){} + + inline bool operator==(const Curve &curve) const + { + return tag == curve.tag; + } + + inline bool operator==(const QString &strTagName) const + { + return tag == strTagName; + } + + bool visible; + double rtMax; + double rtMin; + double rtAverage; + double rtAccuml; + double hisMax; + double hisMin; + double hisAverage; + double hisAccuml; + double graphFactor; + double graphOffset; + double factor; + double offset; + double rtMaxTime; + double rtMinTime; + double hisMaxTime; + double hisMinTime; + double sHisMax; //< 实际的最大值(influx统计),仅用于显示 + double sHisMin; //< 实际的最小值(influx统计),仅用于显示 + double sHisMaxTime; //< 实际的最大值时间(influx统计),仅用于显示 + double sHisMinTime; //< 实际的最小值时间(influx统计),仅用于显示 + + Range hisPlotRange; //< hisPlotRange > Range(hisMin, hisMax) [趋势对比计算刻度] + + QString tag; + QString desc; + QString type; + QString unit; + QColor color; + + QVector< QPair > > values; +}; + +class CTrendGraph +{ +public: + CTrendGraph(); + + ~CTrendGraph(); + + const QList curves() const; + void setCurves(QList listCurve); + + const QList curveColors() const; + + const Curve &curve(const QString &tag) const; + int index(const QString &tag) const; + + void clear(); + + void addCurve(const Curve &curve); + int removeCurve(const QString &tag); + + void setCurveVisible(const int &nIndex, const bool &visible); + + void setCurveColor(const int &nIndex, const QColor &color); + void setCurveFactor(const int &nIndex, const double &factor); + void setCurveOffset(const int &nIndex, const double &offset); + + void setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range); + void pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status); + + void setCurveStatisMax(const QString &tag, const double &max, const double &maxTime); + void setCurveStatisMin(const QString &tag, const double &min, const double &minTime); + + void resetCurveStatisMax(const QString &tag); + void resetCurveStatisMin(const QString &tag); + + void setCurveGraphFactor(const int &nIndex, const double &factor); + void setCurveGraphOffset(const int &nIndex, const double &offset); + + //< 更新实时曲线统计信息 + void updateRTCurveStatisticsInfo(const QString &strTagName); + void updateRTCurveStatisticsInfo(Curve &curve); + +private: + QList m_listCurve; +}; + +#endif // CTRENDGRAPH_H + + diff --git a/product/src/gui/plugin/TrendCurves/CTrendInfoManage.cpp b/product/src/gui/plugin/TrendCurves/CTrendInfoManage.cpp index bda4f967..20ec86c7 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendInfoManage.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendInfoManage.cpp @@ -1,610 +1,610 @@ -#include "CTrendInfoManage.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "pub_sysinfo_api/SysInfoApi.h" -#include "pub_utility_api/CharUtil.h" -#include "pub_utility_api/FileUtil.h" -#include "perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" - -using namespace kbd_dbms; -using namespace kbd_public; -using namespace std; - -CTrendInfoManage *CTrendInfoManage::m_pInstance = NULL; - -CTrendInfoManage *CTrendInfoManage::instance() -{ - if(NULL == m_pInstance) - { - m_pInstance = new CTrendInfoManage(); - } - return m_pInstance; -} - -CTrendInfoManage::CTrendInfoManage() -{ - //< 实时库 - m_rtdbAccess = new kbd_dbms::CRdbAccess(); - - m_listTagInfo.reserve(30097); // 保证三万点测试的素数 - - CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); - if(!pReadDb->open()) - { - delete pReadDb; - pReadDb = Q_NULLPTR; - return; - } - - loadUnit(pReadDb); - loadRTLocation(); - loadDevGroupInfo(pReadDb); - loadDeviceInfo(pReadDb); - loadTagInfo(pReadDb); - loadStateDefine(); - loadAlarmStatusDefine(); - loadAlarmStatus(); - loadAlarmOtherStatus(); - initInvalidStatus(); - - delete pReadDb; - pReadDb = Q_NULLPTR; -} - -void CTrendInfoManage::destory() -{ - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; - - m_locationInfo.clear(); - m_devGroupInfo.clear(); - m_devLocation.clear(); - m_deviceInfo.clear(); - m_listTagName.clear(); - m_listTagInfo.clear(); - m_listTagUnit.clear(); - m_menuState.clear(); - m_alarmShowStatus.clear(); - m_alarmOtherStatus.clear(); - m_alarmStatusDefineMap.clear(); - m_locationOrderList.clear(); - m_pInstance = NULL; - delete this; -} - -QMap CTrendInfoManage::locationInfo() -{ - return m_locationInfo; -} - -QString CTrendInfoManage::getLocationDesc(const int &locId) -{ - return m_locationInfo.value(locId); -} - -QList CTrendInfoManage::locationOrderList() -{ - return m_locationOrderList; -} - -QMap CTrendInfoManage::devGroupInfo(const int &location) -{ - return m_devGroupInfo.value(location, QMap()); -} - -QList > CTrendInfoManage::devGroupInfoList(const int &location) -{ - return m_devGroupInfoMap.value(location, QList >()); -} - -QMap CTrendInfoManage::deviceInfo(const QString &devGroupName) -{ - return m_deviceInfo.value(devGroupName, QMap()); -} - -QStringList CTrendInfoManage::queryTagListDevGroup(const QString &devGroup) -{ - QStringList tagList = QStringList(); - QMap devMap = m_deviceInfo.value(devGroup); - if(devMap.isEmpty()) - { - return tagList; - } - QStringList deviceList = devMap.keys(); - foreach (QString device, deviceList) { - tagList.append(m_listTagName.value(device, QStringList())); - } - return tagList; -} - -QStringList CTrendInfoManage::queryTagList(const QString &device) -{ - QStringList result = m_listTagName.value(device, QStringList()); - for(int nIndex = 0; nIndex < result.length(); ++nIndex) - { - if(getTagType(result.at(nIndex)) == "digital") - { - result.removeAt(nIndex); - nIndex--; - } - } - return result; -} - -QString CTrendInfoManage::queryDeviceGroup(const QString &device) -{ - QMap >::const_iterator iter = m_deviceInfo.begin(); - for(; iter != m_deviceInfo.end(); ++iter) - { - QStringList deviceList = iter.value().keys(); - if(deviceList.indexOf(device) != -1) - { - return iter.key(); - } - } - return QString(); -} - -QString CTrendInfoManage::getTagDescription(const QString &tag) -{ - QStringList values = m_listTagInfo.value(tag, QStringList()); - if(values.isEmpty()) - { - return QString(); - } - return values.at(0); -} - -QString CTrendInfoManage::getTagType(const QString &tag) -{ - QStringList values = m_listTagInfo.value(tag, QStringList()); - if(values.isEmpty()) - { - return QString(); - } - return values.at(1); -} - -QString CTrendInfoManage::getTagUnit(const QString &tag) -{ - QStringList values = m_listTagInfo.value(tag, QStringList()); - if(values.isEmpty()) - { - return QString(); - } - return values.at(2); -} - -bool CTrendInfoManage::checkTrendEditPerm() -{ - kbd_public::SNodeInfo stNodeInfo; - kbd_public::CSysInfoInterfacePtr spSysInfo; - if (!kbd_public::createSysInfoInstance(spSysInfo)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return false; - } - spSysInfo->getLocalNodeInfo(stNodeInfo); - - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - if(0 == permMngPtr->PermDllInit()) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - std::string strTendEdit = FUNC_NOM_TREND_EDIT; - if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &strTendEdit)) - { - return true; - } - } - return false; -} - -int CTrendInfoManage::getStateActualValue(const QString &state) -{ - if(state.isEmpty()) - { - return 0; - } - return m_menuState.value(state); -} - -int CTrendInfoManage::getInvalidStatus(E_Point_Type pointType, int status) -{ - switch (pointType) - { - case E_ANALOG:{ - if(0 != (status & m_nInvalidAnalog)) - { - return 1; - } - break; - } - case E_DIGITAL:{ - if(0 != (status & m_nInvalidDigital)) - { - return 1; - } - break; - } - case E_MIX:{ - break; - } - case E_ACCUML:{ - break; - } - default: - break; - } - return 0; -} - -QMap > CTrendInfoManage::getAlarmShowStatus() -{ - return m_alarmShowStatus; -} - -QMap CTrendInfoManage::getAlarmOtherStatus() -{ - return m_alarmOtherStatus; -} - -void CTrendInfoManage::loadRTLocation() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return; - } - int level; - std::vector vecLocationId; - std::vector vecPermPic; - if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) - { - LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); - return; - } - - std::string strApplicationName = "base"; - std::string strTableName = "sys_model_location_info"; - QPair id_value; - id_value.first = "location_id"; - id_value.second = "description"; - if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back(id_value.first); - columns.push_back(id_value.second); - - std::string sOrderColumn = "location_no"; - - if(m_rtdbAccess->select(result, columns, sOrderColumn)) - { - m_locationInfo.clear(); - m_locationOrderList.clear(); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - - std::vector ::const_iterator it = vecLocationId.cbegin(); - while (it != vecLocationId.cend()) - { - if(key.toInt() == *it) - { - m_locationInfo[key.toInt()] = value.toStdString().c_str(); - m_locationOrderList << key.toInt(); - } - ++it; - } - } - } - } - m_rtdbAccess->close(); -} - -void CTrendInfoManage::loadDevGroupInfo(CDbApi *pReadDb) -{ - QSqlQuery query; - - QString strLoctionFilter; - if(!m_locationInfo.keys().isEmpty()) - { - QStringList listLocation; - foreach (int nLocationID, m_locationInfo.keys()) - { - listLocation.append(QString::number(nLocationID)); - } - strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); - }else - { - return ; - } - QString sqlSequenceQuery = QStringLiteral("select tag_name, description, location_id from dev_group where sub_system > 3 "); - if(!strLoctionFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); - }else - { - sqlSequenceQuery.append(QStringLiteral(" order by dev_group_no asc;")); - } - query.setForwardOnly(true); - pReadDb->execute(sqlSequenceQuery, query); - - while(query.next()) - { - const QString &tag_name = query.value(0).toString(); - const QString &description = query.value(1).toString(); - const int location_id = query.value(2).toInt(); - - m_devGroupInfoMap[location_id].append(QPair(tag_name,description)); - m_devGroupInfo[location_id].insert(tag_name, description); - } -} - -void CTrendInfoManage::loadDeviceInfo(CDbApi *pReadDb) -{ - QSqlQuery query; - - QString strLoctionFilter; - QList > listDevGroup = m_devGroupInfo.values(); - if(!listDevGroup.isEmpty()) - { - QStringList listLocation; - for(int i=0; iexecute(sqlSequenceQuery, query); - while(query.next()) - { - const QString &tag_name = query.value(0).toString(); - const QString &description = query.value(1).toString(); - const QString &group_tag_name = query.value(2).toString(); - const int location_id = query.value(0).toInt(); - - m_deviceInfo[group_tag_name].insert(tag_name, description); - m_devLocation[location_id].insert(tag_name, description); - } -} - -void CTrendInfoManage::loadTagInfo(CDbApi *pReadDb) -{ - QSqlQuery query; - QStringList listType; - listType.append(QStringLiteral("analog")); - listType.append(QStringLiteral("digital")); - listType.append(QStringLiteral("accuml")); - // listType.append(QString("mix")); - - QString strDeviceFilter; - if(!m_deviceInfo.isEmpty()) - { - QStringList listDevice; - QMap >::const_iterator iter = m_deviceInfo.constBegin(); - while (iter != m_deviceInfo.constEnd()) - { - listDevice.append(iter.value().keys()); - ++iter; - } - strDeviceFilter = "'" % listDevice.join("', '") % "'"; - strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); - } - - query.setForwardOnly(true); - for(int nIndex(0); nIndex < listType.size(); nIndex++) - { - const QString strCurType = listType.at(nIndex); - QString strUnitField; - if(QStringLiteral("analog") == strCurType || QStringLiteral("accuml") == strCurType) - { - strUnitField = QStringLiteral(", t1.unit_id "); - } - QString sqlSequenceQuery = QString("SELECT t2.group_tag_name, t1.tag_name, t1.description, t1.device, t1.location_id, t2.DESCRIPTION %1 \ -FROM %2 as t1 left join dev_info as t2 on t1.device = t2.tag_name").arg(strUnitField).arg(strCurType); - if(!strDeviceFilter.isEmpty()) - { - sqlSequenceQuery.append(QString(" WHERE %1 ORDER BY SEQ_NO asc;").arg(strDeviceFilter)); - } - pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - //const QString group = query.value(0).toString(); - const QString &tagName = query.value(1).toString(); - //const QString tagDesc = query.value(2).toString(); - const QString &device = query.value(3).toString(); - const int location = query.value(4).toInt(); - //const QString devDesc = query.value(5).toString(); - const QString strDescription = m_locationInfo[location] % QChar('.') % m_devGroupInfo[location][query.value(0).toString()] % QChar('.') % query.value(5).toString() % QChar('.') % query.value(2).toString(); - m_listTagName[device] << tagName; - - - //QString strUnitDesc = m_listTagUnit.value(query.value(5).toInt(), QString()); - // m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << m_listTagUnit.value(query.value(5).toInt(), QString()); - QString strUnitDesc =""; - if(QStringLiteral("analog") == strCurType || QStringLiteral("accuml") == strCurType) - { - strUnitDesc = m_listTagUnit.value(query.value(6).toInt(), QString()); - } - m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << strUnitDesc; - } - } -} - -void CTrendInfoManage::loadUnit(CDbApi *pReadDb) -{ - QSqlQuery query; - QString sqlSequenceQuery = QStringLiteral("select unit_id, unit_name from dict_unit_info"); - query.setForwardOnly(true); - pReadDb->execute(sqlSequenceQuery, query); - while(query.next()) - { - m_listTagUnit[query.value(0).toInt()] = query.value(1).toString(); - } -} - -void CTrendInfoManage::loadStateDefine() -{ - if(m_rtdbAccess->open("base", "dict_menu_info")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - - CRdbQueryResult result; - std::vector columns; - columns.emplace_back("menu_macro_name"); - columns.emplace_back("actual_value"); - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType name; - CVarType value; - result.getColumnValue(nIndex, 0, name); - result.getColumnValue(nIndex, 1, value); - m_menuState.insert(name.toStdString().c_str(), value.toInt()); - } - } - } - m_rtdbAccess->close(); -} - -void CTrendInfoManage::loadAlarmStatusDefine() -{ - if(m_rtdbAccess->open("base", "alarm_status_define")) - { - kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.emplace_back("status_value"); - columns.emplace_back("display_name"); - - if(m_rtdbAccess->select(result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - kbd_dbms::CVarType key; - kbd_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_alarmStatusDefineMap[key.toInt()] = QString::fromStdString(value.toStdString()); - } - } - } - m_rtdbAccess->close(); -} - -void CTrendInfoManage::loadAlarmStatus() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - string strCheck = pParamIter->second.get(".check"); - QPair value; - if(StringToInt(strKey) != 9999) - { - value.first = m_alarmStatusDefineMap[StringToInt(strKey)]; - }else - { - value.first = QObject::tr("其他"); - } - value.second = StringToInt(strCheck); - m_alarmShowStatus[StringToInt(strKey)] = value; - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -void CTrendInfoManage::loadAlarmOtherStatus() -{ - const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); - boost::property_tree::ptree pt; - namespace xml = boost::property_tree::xml_parser; - try - { - xml::read_xml(strConfFullPath, pt, xml::no_comments); - BOOST_AUTO(module, pt.get_child("root")); - for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) - { - boost::property_tree::ptree ptParam = pModuleIter->second; - for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) - { - if (pParamIter->first == "param") - { - string strKey = pParamIter->second.get(".key"); - m_alarmOtherStatus[StringToInt(strKey)] = m_alarmStatusDefineMap[StringToInt(strKey)]; - } - } - } - } - catch (std::exception &ex) - { - LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); - } -} - -void CTrendInfoManage::initInvalidStatus() -{ - int temp = 0x01; - m_nInvalidAnalog = 0; - m_nInvalidDigital = 0; - - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_INVALID")); //< 无效 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_GK_OFF")); //< 工况退出 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_CHANGE")); //< 不刷新 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_BAD_DATA")); //< 坏数据 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_TB")); //< 突变 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_GET_CAL")); //< 计算值 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_REAL")); //< 非实测值 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_INIT")); //< 未初始化 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_SET_DATA")); //< 人工置数 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_PINHIBIT_REF")); //< 点禁止刷新 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_DINHIBIT_REF")); //< 挂牌禁止刷新 - m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_SINHIBIT_REF")); //< 屏蔽禁止刷新 - - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_GK_OFF")); //< 工况退出 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_INVALID")); //< 无效 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_NOT_REAL")); //< 非实测值 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_GET_CAL")); //< 计算值 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_PART_ABNORMAL")); //< 分量不正常 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SET_DATA")); //< 人工置数 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_PINHIBIT_REF")); //< 点禁止刷新 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_DINHIBIT_REF")); //< 挂牌禁止刷新 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SINHIBIT_REF")); //< 屏蔽禁止刷新 - m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SOURCE_ABNORMAL"));//< 数据来源不正常 -} +#include "CTrendInfoManage.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_utility_api/FileUtil.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" + +using namespace kbd_dbms; +using namespace kbd_public; +using namespace std; + +CTrendInfoManage *CTrendInfoManage::m_pInstance = NULL; + +CTrendInfoManage *CTrendInfoManage::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CTrendInfoManage(); + } + return m_pInstance; +} + +CTrendInfoManage::CTrendInfoManage() +{ + //< 实时库 + m_rtdbAccess = new kbd_dbms::CRdbAccess(); + + m_listTagInfo.reserve(30097); // 保证三万点测试的素数 + + CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(!pReadDb->open()) + { + delete pReadDb; + pReadDb = Q_NULLPTR; + return; + } + + loadUnit(pReadDb); + loadRTLocation(); + loadDevGroupInfo(pReadDb); + loadDeviceInfo(pReadDb); + loadTagInfo(pReadDb); + loadStateDefine(); + loadAlarmStatusDefine(); + loadAlarmStatus(); + loadAlarmOtherStatus(); + initInvalidStatus(); + + delete pReadDb; + pReadDb = Q_NULLPTR; +} + +void CTrendInfoManage::destory() +{ + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_locationInfo.clear(); + m_devGroupInfo.clear(); + m_devLocation.clear(); + m_deviceInfo.clear(); + m_listTagName.clear(); + m_listTagInfo.clear(); + m_listTagUnit.clear(); + m_menuState.clear(); + m_alarmShowStatus.clear(); + m_alarmOtherStatus.clear(); + m_alarmStatusDefineMap.clear(); + m_locationOrderList.clear(); + m_pInstance = NULL; + delete this; +} + +QMap CTrendInfoManage::locationInfo() +{ + return m_locationInfo; +} + +QString CTrendInfoManage::getLocationDesc(const int &locId) +{ + return m_locationInfo.value(locId); +} + +QList CTrendInfoManage::locationOrderList() +{ + return m_locationOrderList; +} + +QMap CTrendInfoManage::devGroupInfo(const int &location) +{ + return m_devGroupInfo.value(location, QMap()); +} + +QList > CTrendInfoManage::devGroupInfoList(const int &location) +{ + return m_devGroupInfoMap.value(location, QList >()); +} + +QMap CTrendInfoManage::deviceInfo(const QString &devGroupName) +{ + return m_deviceInfo.value(devGroupName, QMap()); +} + +QStringList CTrendInfoManage::queryTagListDevGroup(const QString &devGroup) +{ + QStringList tagList = QStringList(); + QMap devMap = m_deviceInfo.value(devGroup); + if(devMap.isEmpty()) + { + return tagList; + } + QStringList deviceList = devMap.keys(); + foreach (QString device, deviceList) { + tagList.append(m_listTagName.value(device, QStringList())); + } + return tagList; +} + +QStringList CTrendInfoManage::queryTagList(const QString &device) +{ + QStringList result = m_listTagName.value(device, QStringList()); + for(int nIndex = 0; nIndex < result.length(); ++nIndex) + { + if(getTagType(result.at(nIndex)) == "digital") + { + result.removeAt(nIndex); + nIndex--; + } + } + return result; +} + +QString CTrendInfoManage::queryDeviceGroup(const QString &device) +{ + QMap >::const_iterator iter = m_deviceInfo.begin(); + for(; iter != m_deviceInfo.end(); ++iter) + { + QStringList deviceList = iter.value().keys(); + if(deviceList.indexOf(device) != -1) + { + return iter.key(); + } + } + return QString(); +} + +QString CTrendInfoManage::getTagDescription(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(0); +} + +QString CTrendInfoManage::getTagType(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(1); +} + +QString CTrendInfoManage::getTagUnit(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(2); +} + +bool CTrendInfoManage::checkTrendEditPerm() +{ + kbd_public::SNodeInfo stNodeInfo; + kbd_public::CSysInfoInterfacePtr spSysInfo; + if (!kbd_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + if(0 == permMngPtr->PermDllInit()) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string strTendEdit = FUNC_NOM_TREND_EDIT; + if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &strTendEdit)) + { + return true; + } + } + return false; +} + +int CTrendInfoManage::getStateActualValue(const QString &state) +{ + if(state.isEmpty()) + { + return 0; + } + return m_menuState.value(state); +} + +int CTrendInfoManage::getInvalidStatus(E_Point_Type pointType, int status) +{ + switch (pointType) + { + case E_ANALOG:{ + if(0 != (status & m_nInvalidAnalog)) + { + return 1; + } + break; + } + case E_DIGITAL:{ + if(0 != (status & m_nInvalidDigital)) + { + return 1; + } + break; + } + case E_MIX:{ + break; + } + case E_ACCUML:{ + break; + } + default: + break; + } + return 0; +} + +QMap > CTrendInfoManage::getAlarmShowStatus() +{ + return m_alarmShowStatus; +} + +QMap CTrendInfoManage::getAlarmOtherStatus() +{ + return m_alarmOtherStatus; +} + +void CTrendInfoManage::loadRTLocation() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + int level; + std::vector vecLocationId; + std::vector vecPermPic; + if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) + { + LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); + return; + } + + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + QPair id_value; + id_value.first = "location_id"; + id_value.second = "description"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back(id_value.first); + columns.push_back(id_value.second); + + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + m_locationInfo.clear(); + m_locationOrderList.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + std::vector ::const_iterator it = vecLocationId.cbegin(); + while (it != vecLocationId.cend()) + { + if(key.toInt() == *it) + { + m_locationInfo[key.toInt()] = value.toStdString().c_str(); + m_locationOrderList << key.toInt(); + } + ++it; + } + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadDevGroupInfo(CDbApi *pReadDb) +{ + QSqlQuery query; + + QString strLoctionFilter; + if(!m_locationInfo.keys().isEmpty()) + { + QStringList listLocation; + foreach (int nLocationID, m_locationInfo.keys()) + { + listLocation.append(QString::number(nLocationID)); + } + strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); + }else + { + return ; + } + QString sqlSequenceQuery = QStringLiteral("select tag_name, description, location_id from dev_group where sub_system > 3 "); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); + }else + { + sqlSequenceQuery.append(QStringLiteral(" order by dev_group_no asc;")); + } + query.setForwardOnly(true); + pReadDb->execute(sqlSequenceQuery, query); + + while(query.next()) + { + const QString &tag_name = query.value(0).toString(); + const QString &description = query.value(1).toString(); + const int location_id = query.value(2).toInt(); + + m_devGroupInfoMap[location_id].append(QPair(tag_name,description)); + m_devGroupInfo[location_id].insert(tag_name, description); + } +} + +void CTrendInfoManage::loadDeviceInfo(CDbApi *pReadDb) +{ + QSqlQuery query; + + QString strLoctionFilter; + QList > listDevGroup = m_devGroupInfo.values(); + if(!listDevGroup.isEmpty()) + { + QStringList listLocation; + for(int i=0; iexecute(sqlSequenceQuery, query); + while(query.next()) + { + const QString &tag_name = query.value(0).toString(); + const QString &description = query.value(1).toString(); + const QString &group_tag_name = query.value(2).toString(); + const int location_id = query.value(0).toInt(); + + m_deviceInfo[group_tag_name].insert(tag_name, description); + m_devLocation[location_id].insert(tag_name, description); + } +} + +void CTrendInfoManage::loadTagInfo(CDbApi *pReadDb) +{ + QSqlQuery query; + QStringList listType; + listType.append(QStringLiteral("analog")); + listType.append(QStringLiteral("digital")); + listType.append(QStringLiteral("accuml")); + // listType.append(QString("mix")); + + QString strDeviceFilter; + if(!m_deviceInfo.isEmpty()) + { + QStringList listDevice; + QMap >::const_iterator iter = m_deviceInfo.constBegin(); + while (iter != m_deviceInfo.constEnd()) + { + listDevice.append(iter.value().keys()); + ++iter; + } + strDeviceFilter = "'" % listDevice.join("', '") % "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); + } + + query.setForwardOnly(true); + for(int nIndex(0); nIndex < listType.size(); nIndex++) + { + const QString strCurType = listType.at(nIndex); + QString strUnitField; + if(QStringLiteral("analog") == strCurType || QStringLiteral("accuml") == strCurType) + { + strUnitField = QStringLiteral(", t1.unit_id "); + } + QString sqlSequenceQuery = QString("SELECT t2.group_tag_name, t1.tag_name, t1.description, t1.device, t1.location_id, t2.DESCRIPTION %1 \ +FROM %2 as t1 left join dev_info as t2 on t1.device = t2.tag_name").arg(strUnitField).arg(strCurType); + if(!strDeviceFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" WHERE %1 ORDER BY SEQ_NO asc;").arg(strDeviceFilter)); + } + pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + //const QString group = query.value(0).toString(); + const QString &tagName = query.value(1).toString(); + //const QString tagDesc = query.value(2).toString(); + const QString &device = query.value(3).toString(); + const int location = query.value(4).toInt(); + //const QString devDesc = query.value(5).toString(); + const QString strDescription = m_locationInfo[location] % QChar('.') % m_devGroupInfo[location][query.value(0).toString()] % QChar('.') % query.value(5).toString() % QChar('.') % query.value(2).toString(); + m_listTagName[device] << tagName; + + + //QString strUnitDesc = m_listTagUnit.value(query.value(5).toInt(), QString()); + // m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << m_listTagUnit.value(query.value(5).toInt(), QString()); + QString strUnitDesc =""; + if(QStringLiteral("analog") == strCurType || QStringLiteral("accuml") == strCurType) + { + strUnitDesc = m_listTagUnit.value(query.value(6).toInt(), QString()); + } + m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << strUnitDesc; + } + } +} + +void CTrendInfoManage::loadUnit(CDbApi *pReadDb) +{ + QSqlQuery query; + QString sqlSequenceQuery = QStringLiteral("select unit_id, unit_name from dict_unit_info"); + query.setForwardOnly(true); + pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + m_listTagUnit[query.value(0).toInt()] = query.value(1).toString(); + } +} + +void CTrendInfoManage::loadStateDefine() +{ + if(m_rtdbAccess->open("base", "dict_menu_info")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + + CRdbQueryResult result; + std::vector columns; + columns.emplace_back("menu_macro_name"); + columns.emplace_back("actual_value"); + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType name; + CVarType value; + result.getColumnValue(nIndex, 0, name); + result.getColumnValue(nIndex, 1, value); + m_menuState.insert(name.toStdString().c_str(), value.toInt()); + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadAlarmStatusDefine() +{ + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + kbd_dbms::CTableLockGuard locker(*m_rtdbAccess); + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.emplace_back("status_value"); + columns.emplace_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + kbd_dbms::CVarType key; + kbd_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusDefineMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadAlarmStatus() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + string strCheck = pParamIter->second.get(".check"); + QPair value; + if(StringToInt(strKey) != 9999) + { + value.first = m_alarmStatusDefineMap[StringToInt(strKey)]; + }else + { + value.first = QObject::tr("其他"); + } + value.second = StringToInt(strCheck); + m_alarmShowStatus[StringToInt(strKey)] = value; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CTrendInfoManage::loadAlarmOtherStatus() +{ + const std::string strConfFullPath = kbd_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + m_alarmOtherStatus[StringToInt(strKey)] = m_alarmStatusDefineMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CTrendInfoManage::initInvalidStatus() +{ + int temp = 0x01; + m_nInvalidAnalog = 0; + m_nInvalidDigital = 0; + + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_INVALID")); //< 无效 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_GK_OFF")); //< 工况退出 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_CHANGE")); //< 不刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_BAD_DATA")); //< 坏数据 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_TB")); //< 突变 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_GET_CAL")); //< 计算值 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_REAL")); //< 非实测值 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_INIT")); //< 未初始化 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_SET_DATA")); //< 人工置数 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_PINHIBIT_REF")); //< 点禁止刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_DINHIBIT_REF")); //< 挂牌禁止刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_SINHIBIT_REF")); //< 屏蔽禁止刷新 + + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_GK_OFF")); //< 工况退出 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_INVALID")); //< 无效 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_NOT_REAL")); //< 非实测值 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_GET_CAL")); //< 计算值 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_PART_ABNORMAL")); //< 分量不正常 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SET_DATA")); //< 人工置数 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_PINHIBIT_REF")); //< 点禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_DINHIBIT_REF")); //< 挂牌禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SINHIBIT_REF")); //< 屏蔽禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SOURCE_ABNORMAL"));//< 数据来源不正常 +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendInfoManage.h b/product/src/gui/plugin/TrendCurves/CTrendInfoManage.h index fe3c1d53..5c0a724e 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendInfoManage.h +++ b/product/src/gui/plugin/TrendCurves/CTrendInfoManage.h @@ -1,100 +1,100 @@ -#ifndef CTRENDINFOMANAGE_H -#define CTRENDINFOMANAGE_H - -#include -#include -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "dbms/db_api_ex/CDbApi.h" -#include "boost/property_tree/xml_parser.hpp" -#include "boost/typeof/typeof.hpp" -#include "boost/filesystem.hpp" - -#define FUNC_NOM_TREND_EDIT "FUNC_NOM_TREND_EDIT" - -enum E_Point_Type -{ - E_ANALOG, //< 模拟量 - E_DIGITAL, //< 数字量 - E_MIX, //< 混合量 - E_ACCUML, //< 累计量 -}; - -class CTrendInfoManage -{ -public: - static CTrendInfoManage * instance(); - - void destory(); - - QMap locationInfo(); - - QString getLocationDesc(const int &locId); - - QList locationOrderList(); - - QMap devGroupInfo(const int& location); //新增设备组 - - QList > devGroupInfoList(const int& location); - - QMap deviceInfo(const QString &devGroupName); //新增设备组时修改 - - QStringList queryTagListDevGroup(const QString &devGroup); - - QStringList queryTagList(const QString &device); - - QString queryDeviceGroup(const QString &device); - - QString getTagDescription(const QString &tag); - - QString getTagType(const QString &tag); - - QString getTagUnit(const QString &tag); - - bool checkTrendEditPerm(); - - int getStateActualValue(const QString &state); - - int getInvalidStatus(E_Point_Type pointType, int status); - - QMap > getAlarmShowStatus(); - - QMap getAlarmOtherStatus(); - -private: - CTrendInfoManage(); - - void loadRTLocation(); - void loadDevGroupInfo(kbd_dbms::CDbApi *pReadDb); //新增设备组 - void loadDeviceInfo(kbd_dbms::CDbApi *pReadDb); //新增设备组时修改 - void loadTagInfo(kbd_dbms::CDbApi *pReadDb); - void loadUnit(kbd_dbms::CDbApi *pReadDb); - void loadStateDefine(); - void loadAlarmStatusDefine(); - void loadAlarmStatus(); - void loadAlarmOtherStatus(); - void initInvalidStatus(); - -private: - kbd_dbms::CRdbAccess * m_rtdbAccess; - QMap m_locationInfo; //< LocationID-LocationDesc - QMap > m_devGroupInfo; //< LocationID- 新增设备组 - QMap > > m_devGroupInfoMap; - QMap > m_devLocation; //< LocationID- 新增设备组 - QMap > m_deviceInfo; //< DevGroupName- 新增设备组时修改 - QMap m_listTagName; //< DeviceName-list - QHash m_listTagInfo; //< TagName-TagInfo - QMap m_listTagUnit; - QMap m_menuState; - QMap > m_alarmShowStatus; - QMap m_alarmOtherStatus; - QMap m_alarmStatusDefineMap; - QList m_locationOrderList; //< location_id: 按location_no排序 - int m_nInvalidAnalog; - int m_nInvalidDigital; - - static CTrendInfoManage * m_pInstance; -}; - -#endif // CTRENDINFOMANAGE_H +#ifndef CTRENDINFOMANAGE_H +#define CTRENDINFOMANAGE_H + +#include +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" + +#define FUNC_NOM_TREND_EDIT "FUNC_NOM_TREND_EDIT" + +enum E_Point_Type +{ + E_ANALOG, //< 模拟量 + E_DIGITAL, //< 数字量 + E_MIX, //< 混合量 + E_ACCUML, //< 累计量 +}; + +class CTrendInfoManage +{ +public: + static CTrendInfoManage * instance(); + + void destory(); + + QMap locationInfo(); + + QString getLocationDesc(const int &locId); + + QList locationOrderList(); + + QMap devGroupInfo(const int& location); //新增设备组 + + QList > devGroupInfoList(const int& location); + + QMap deviceInfo(const QString &devGroupName); //新增设备组时修改 + + QStringList queryTagListDevGroup(const QString &devGroup); + + QStringList queryTagList(const QString &device); + + QString queryDeviceGroup(const QString &device); + + QString getTagDescription(const QString &tag); + + QString getTagType(const QString &tag); + + QString getTagUnit(const QString &tag); + + bool checkTrendEditPerm(); + + int getStateActualValue(const QString &state); + + int getInvalidStatus(E_Point_Type pointType, int status); + + QMap > getAlarmShowStatus(); + + QMap getAlarmOtherStatus(); + +private: + CTrendInfoManage(); + + void loadRTLocation(); + void loadDevGroupInfo(kbd_dbms::CDbApi *pReadDb); //新增设备组 + void loadDeviceInfo(kbd_dbms::CDbApi *pReadDb); //新增设备组时修改 + void loadTagInfo(kbd_dbms::CDbApi *pReadDb); + void loadUnit(kbd_dbms::CDbApi *pReadDb); + void loadStateDefine(); + void loadAlarmStatusDefine(); + void loadAlarmStatus(); + void loadAlarmOtherStatus(); + void initInvalidStatus(); + +private: + kbd_dbms::CRdbAccess * m_rtdbAccess; + QMap m_locationInfo; //< LocationID-LocationDesc + QMap > m_devGroupInfo; //< LocationID- 新增设备组 + QMap > > m_devGroupInfoMap; + QMap > m_devLocation; //< LocationID- 新增设备组 + QMap > m_deviceInfo; //< DevGroupName- 新增设备组时修改 + QMap m_listTagName; //< DeviceName-list + QHash m_listTagInfo; //< TagName-TagInfo + QMap m_listTagUnit; + QMap m_menuState; + QMap > m_alarmShowStatus; + QMap m_alarmOtherStatus; + QMap m_alarmStatusDefineMap; + QList m_locationOrderList; //< location_id: 按location_no排序 + int m_nInvalidAnalog; + int m_nInvalidDigital; + + static CTrendInfoManage * m_pInstance; +}; + +#endif // CTRENDINFOMANAGE_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.cpp b/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.cpp index b009975b..b857fe30 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CTrendPluginWidget.h" -#include "CTrendWindow.h" - -CTrendPluginWidget::CTrendPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CTrendPluginWidget::~CTrendPluginWidget() -{ - -} - -bool CTrendPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) -{ - CTrendWindow *pWidget = new CTrendWindow(editMode, ptrVec, parent); - pWidget->initialize(E_Trend_Window); - *widget = (QWidget *)pWidget; - *pTrendWindow = (IPluginWidget *)pWidget; - return true; -} - -void CTrendPluginWidget::release() -{ - -} +#include +#include "CTrendPluginWidget.h" +#include "CTrendWindow.h" + +CTrendPluginWidget::CTrendPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CTrendPluginWidget::~CTrendPluginWidget() +{ + +} + +bool CTrendPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CTrendWindow *pWidget = new CTrendWindow(editMode, ptrVec, parent); + pWidget->initialize(E_Trend_Window); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CTrendPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.h b/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.h index f469158c..620317a8 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.h +++ b/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CTRENDPLUGINWIDGET_H -#define CTRENDPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CTrendPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CTrendPluginWidget(QObject *parent = 0); - ~CTrendPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); - void release(); -}; - -#endif //CTRENDPLUGINWIDGET_H - +#ifndef CTRENDPLUGINWIDGET_H +#define CTRENDPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CTrendPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CTrendPluginWidget(QObject *parent = 0); + ~CTrendPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif //CTRENDPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeItem.cpp b/product/src/gui/plugin/TrendCurves/CTrendTreeItem.cpp index 7b41fa9e..a4946827 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeItem.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeItem.cpp @@ -1,114 +1,114 @@ -#include -#include "CTrendTreeItem.h" - -CTrendTreeItem::CTrendTreeItem(int type) - : m_parentItem(Q_NULLPTR), - m_data(QString()), - m_tag(QString()), - m_type(type), - m_checkState(Qt::Unchecked) -{ - -} - -CTrendTreeItem::CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type) - : m_parentItem(parent), - m_data(data), - m_tag(QString()), - m_type(type), - m_checkState(Qt::Unchecked) -{ - if(m_parentItem) - { - m_parentItem->m_childItems.append(this); - } -} - -CTrendTreeItem::~CTrendTreeItem() -{ - qDeleteAll(m_childItems); - m_childItems.clear(); -} - -int CTrendTreeItem::type() const -{ - return m_type; -} - -int CTrendTreeItem::indexOfChild(const CTrendTreeItem *item) const -{ - for(int nIndex(0); nIndex < m_childItems.size(); ++nIndex) - { - if(item == m_childItems[nIndex]) - { - return nIndex; - } - } - return -1; -} - -CTrendTreeItem *CTrendTreeItem::child(int row) const -{ - return m_childItems.value(row); -} - -CTrendTreeItem *CTrendTreeItem::parent() const -{ - return m_parentItem; -} - -int CTrendTreeItem::row() const -{ - if (m_parentItem) - { - return m_parentItem->m_childItems.indexOf(const_cast(this)); - } - - return 0; -} - -int CTrendTreeItem::childCount() const -{ - return m_childItems.count(); -} - -int CTrendTreeItem::columnCount() const -{ - return 1; -} - -QVariant CTrendTreeItem::data(Qt::ItemDataRole role) const -{ - if(Qt::DisplayRole == role) - { - return m_data; - } - else if(Qt::UserRole == role) - { - return m_tag; - } - else if(Qt::CheckStateRole == role) - { - return m_checkState; - } -} - -bool CTrendTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) -{ - if(Qt::DisplayRole == role) - { - m_data = value.toString(); - return true; - } - else if(Qt::UserRole == role) - { - m_tag = value.toString(); - return true; - } - else if(Qt::CheckStateRole == role) - { - m_checkState = (Qt::CheckState)value.toInt(); - return true; - } - return false; -} +#include +#include "CTrendTreeItem.h" + +CTrendTreeItem::CTrendTreeItem(int type) + : m_parentItem(Q_NULLPTR), + m_data(QString()), + m_tag(QString()), + m_type(type), + m_checkState(Qt::Unchecked) +{ + +} + +CTrendTreeItem::CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type) + : m_parentItem(parent), + m_data(data), + m_tag(QString()), + m_type(type), + m_checkState(Qt::Unchecked) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } +} + +CTrendTreeItem::~CTrendTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +int CTrendTreeItem::type() const +{ + return m_type; +} + +int CTrendTreeItem::indexOfChild(const CTrendTreeItem *item) const +{ + for(int nIndex(0); nIndex < m_childItems.size(); ++nIndex) + { + if(item == m_childItems[nIndex]) + { + return nIndex; + } + } + return -1; +} + +CTrendTreeItem *CTrendTreeItem::child(int row) const +{ + return m_childItems.value(row); +} + +CTrendTreeItem *CTrendTreeItem::parent() const +{ + return m_parentItem; +} + +int CTrendTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CTrendTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CTrendTreeItem::columnCount() const +{ + return 1; +} + +QVariant CTrendTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::UserRole == role) + { + return m_tag; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } +} + +bool CTrendTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::UserRole == role) + { + m_tag = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + return false; +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeItem.h b/product/src/gui/plugin/TrendCurves/CTrendTreeItem.h index 4c9fb606..b172400a 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeItem.h +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeItem.h @@ -1,98 +1,98 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CTRENDTREEITEM_H -#define CTRENDTREEITEM_H - -#include -#include - -enum NodeType -{ - ROOT_TYPE = 10000, - LOCATION_TYPE, - DEV_TYPE, - TAG_TYPE -}; - -class CTrendTreeItem -{ -public: - CTrendTreeItem(int type); - CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type); - ~CTrendTreeItem(); - - int type() const; - - int indexOfChild(const CTrendTreeItem * item) const; - - CTrendTreeItem *child(int row) const; - CTrendTreeItem *parent() const; - - int row() const; - - int childCount() const; - int columnCount() const; - - QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; - bool setData(const QVariant &value, Qt::ItemDataRole role); - -private: - CTrendTreeItem *m_parentItem; - QString m_data; - QString m_tag; - int m_type; - Qt::CheckState m_checkState; - - QList m_childItems; - -}; - -#endif // CTRENDTREEITEM_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CTRENDTREEITEM_H +#define CTRENDTREEITEM_H + +#include +#include + +enum NodeType +{ + ROOT_TYPE = 10000, + LOCATION_TYPE, + DEV_TYPE, + TAG_TYPE +}; + +class CTrendTreeItem +{ +public: + CTrendTreeItem(int type); + CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type); + ~CTrendTreeItem(); + + int type() const; + + int indexOfChild(const CTrendTreeItem * item) const; + + CTrendTreeItem *child(int row) const; + CTrendTreeItem *parent() const; + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + +private: + CTrendTreeItem *m_parentItem; + QString m_data; + QString m_tag; + int m_type; + Qt::CheckState m_checkState; + + QList m_childItems; + +}; + +#endif // CTRENDTREEITEM_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeModel.cpp b/product/src/gui/plugin/TrendCurves/CTrendTreeModel.cpp index f65b875c..343a9228 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeModel.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeModel.cpp @@ -1,415 +1,415 @@ -#include "CTrendTreeModel.h" -#include "CTrendInfoManage.h" -#include -#include "pub_logger_api/logger.h" -const int ItemTagRole = Qt::UserRole + 1; - -CTrendTreeModel::CTrendTreeModel(QObject *parent, QTreeView *view) - : QAbstractItemModel(parent), - m_pView(view), - m_rootItem(Q_NULLPTR) -{ - QTimer::singleShot(300, this, [=](){initTrendTagInfo();}); -} - -CTrendTreeModel::~CTrendTreeModel() -{ - if(Q_NULLPTR != m_rootItem) - { - delete m_rootItem; - } - m_rootItem = Q_NULLPTR; -} - - -void CTrendTreeModel::initTrendTagInfo() -{ - beginResetModel(); - - if(Q_NULLPTR != m_rootItem) - { - delete m_rootItem; - } - m_rootItem = new QTreeWidgetItem(ROOT_TYPE); - - //< load location - QList locList = CTrendInfoManage::instance()->locationOrderList(); - foreach (const int &locId, locList) { - QString desc = CTrendInfoManage::instance()->getLocationDesc(locId); - QList > devGroupInfoList = CTrendInfoManage::instance()->devGroupInfoList(locId); - if(devGroupInfoList.isEmpty()) - { - continue; - } - QTreeWidgetItem * locationItem = new QTreeWidgetItem(m_rootItem, QStringList() << desc, LOCATION_TYPE); - locationItem->setData(0, ItemTagRole, locId); - QList >::const_iterator iter_devGroup = devGroupInfoList.constBegin(); - while (iter_devGroup != devGroupInfoList.constEnd()) - { - //< load device - QMap devInfo = CTrendInfoManage::instance()->deviceInfo((*iter_devGroup).first); - if(devInfo.isEmpty()) - { - ++iter_devGroup; - continue; - } - QTreeWidgetItem * devGroupItem = new QTreeWidgetItem(locationItem, QStringList() << (*iter_devGroup).second, DEV_GROUP_TYPE); - devGroupItem->setData(0, ItemTagRole, (*iter_devGroup).first); - QMap::const_iterator iter_device = devInfo.constBegin(); - while (iter_device != devInfo.constEnd()) - { - //< load tag - QStringList listTagName = CTrendInfoManage::instance()->queryTagList(iter_device.key()); - if(listTagName.isEmpty()) - { - ++iter_device; - continue; - } -// QTreeWidgetItem * devItem = new QTreeWidgetItem(devGroupItem, QStringList() << iter_device.value(), DEV_TYPE); -// devItem->setData(0, ItemTagRole, iter_device.key()); - QStringList::const_iterator iter_tag = listTagName.constBegin(); - while (iter_tag != listTagName.constEnd()) - { -// QTreeWidgetItem * tagItem = new QTreeWidgetItem(devItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); - QTreeWidgetItem * tagItem = new QTreeWidgetItem(devGroupItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); - tagItem->setData(0, ItemTagRole, *iter_tag); - tagItem->setToolTip(0, *iter_tag); - ++iter_tag; - } - ++iter_device; - } - ++iter_devGroup; - } - } - endResetModel(); - if(m_pView == Q_NULLPTR) - { - return; - } - for(int n=0; nchildCount(); n++) - { - m_pView->expand(index(n,0)); - } -} - -void CTrendTreeModel::clearTrendTagInfo() -{ - CTrendInfoManage::instance()->destory(); - beginResetModel(); - if(Q_NULLPTR != m_rootItem) - { - delete m_rootItem; - } - m_rootItem = Q_NULLPTR; - endResetModel(); -} - -QVariant CTrendTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(section) - Q_UNUSED(orientation) - Q_UNUSED(role) - return QVariant(); -} - -QModelIndex CTrendTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) - { - return QModelIndex(); - } - - QTreeWidgetItem * parentItem; - if(!parent.isValid()) - { - parentItem = m_rootItem; - } - else - { - parentItem = static_cast(parent.internalPointer()); - } - - if(parentItem) - { - QTreeWidgetItem *childItem = parentItem->child(row); - if(childItem) - { - return createIndex(row,0,childItem); - } - } - - return QModelIndex(); -} - -QModelIndex CTrendTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return QModelIndex(); - } - - QTreeWidgetItem *childItem = static_cast(index.internalPointer()); - if (!childItem) - { - return QModelIndex(); - } - - QTreeWidgetItem *parentItem = childItem->parent(); - - if (parentItem == m_rootItem) - { - return QModelIndex(); - } - - int row = parentItem->parent()->indexOfChild(parentItem); - return createIndex(row, 0, parentItem); -} - -int CTrendTreeModel::rowCount(const QModelIndex &parent) const -{ - if(!parent.isValid()) - { - if (NULL != m_rootItem) - { - return m_rootItem->childCount(); - } - else - { - return 0; - } - } - else - { - QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); - } -} - -int CTrendTreeModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return 1; -} - -QVariant CTrendTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item) - { - if(TAG_TYPE == item->type() && Qt::CheckStateRole == role && 0 == index.column()) - { - return item->checkState(index.column()); - } - return item->data(index.column(), role); - } - return QVariant(); -} - -bool CTrendTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - - if(!index.isValid()) - { - return false; - } - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item) - { - if(Qt::CheckStateRole == role) - { - emit itemCheckStateChanged(item->data(0, ItemTagRole).toString(), value.toInt()); - } - item->setData(index.column(), role, value); - } - - return true; -} - -Qt::ItemFlags CTrendTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(item && TAG_TYPE == item->type()) - { - return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; - } - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} - -void CTrendTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state) -{ - if(!index.isValid()) - { - return; - } - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(!item) - { - return; - } -// if(DEV_TYPE == item->type()) - if(DEV_GROUP_TYPE == item->type()) - { - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - if(m_pView->isRowHidden(nChildIndex, index)) - { - continue; - } - setData(index.child(nChildIndex, 0), state, Qt::CheckStateRole); - } - m_pView->update(); - } -} - -void CTrendTreeModel::updateNodeVisualState(const QString &content, QItemSelection &selection) -{ - for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) - { - QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); - bool hit = traverNode(content, topLevelIndex, selection); - m_pView->setRowHidden(topLevelIndex.row(), topLevelIndex.parent(), !hit); - } -} - -bool CTrendTreeModel::traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection) -{ - if(!index.isValid()) - { - return false; - } - - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(!item) - { - return false; - } - - bool isContains = false; - if(content.isEmpty()) - { - isContains = true; - } - else - { - isContains = item->text(index.column()).contains(content); - if(isContains) - { - selection.append(QItemSelectionRange(index)); - } - } - - if(TAG_TYPE == item->type()) - { - m_pView->setRowHidden(index.row(), index.parent(), !isContains); - return isContains; - } - - bool hasHit = false; - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - if(traverNode(content, index.child(nChildIndex, 0), selection)) - { - hasHit = true; - } - } - - if(DEV_TYPE == item->type()) - { - if(isContains) - { - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - m_pView->setRowHidden(nChildIndex, index, false); - } - } - m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); - } - - if(DEV_GROUP_TYPE == item->type()) - { - if(isContains) - { - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - m_pView->setRowHidden(nChildIndex, index, false); - for(int n(0); n < item->child(nChildIndex)->childCount(); n++) - { - m_pView->setRowHidden(n, createIndex(n, 0, item->child(nChildIndex)), false); - } - } - } - m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); - } - - return hasHit | isContains; -} - -void CTrendTreeModel::clearCheckState() -{ - if(!m_rootItem) - { - return; - } - blockSignals(true); - for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) - { - QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); - updateChildCheckState(topLevelIndex, Qt::Unchecked); - } - blockSignals(false); - m_pView->update(); -} - -void CTrendTreeModel::updateTagCheckState(const QString &tag, const bool &checked) -{ - for(int nLocationRow(0); nLocationRow < m_rootItem->childCount(); nLocationRow++) - { - QTreeWidgetItem * locationItem = m_rootItem->child(nLocationRow); - for(int nDeviceGroupRow(0); nDeviceGroupRow < locationItem->childCount(); nDeviceGroupRow++) - { - QTreeWidgetItem * deviceGroupItem = locationItem->child(nDeviceGroupRow); - for(int nDeviceRow(0); nDeviceRow < deviceGroupItem->childCount(); nDeviceRow++) - { -// QTreeWidgetItem * deviceItem = deviceGroupItem->child(nDeviceRow); -// for(int nTagRow(0); nTagRow < deviceItem->childCount(); nTagRow++) -// { - QTreeWidgetItem * tagItem = deviceGroupItem->child(nDeviceRow); - if(tag == tagItem->data(0, ItemTagRole).toString()) - { - tagItem->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); - return; - } -// } - } - } - } -} - -void CTrendTreeModel::updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state) -{ - if(!index.isValid()) - { - return; - } - QTreeWidgetItem * item = static_cast(index.internalPointer()); - if(!item) - { - return; - } - if(TAG_TYPE == item->type()) - { - item->setCheckState(0, state); - } - for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) - { - updateChildCheckState(index.child(nChildIndex, 0), state); - } -} +#include "CTrendTreeModel.h" +#include "CTrendInfoManage.h" +#include +#include "pub_logger_api/logger.h" +const int ItemTagRole = Qt::UserRole + 1; + +CTrendTreeModel::CTrendTreeModel(QObject *parent, QTreeView *view) + : QAbstractItemModel(parent), + m_pView(view), + m_rootItem(Q_NULLPTR) +{ + QTimer::singleShot(300, this, [=](){initTrendTagInfo();}); +} + +CTrendTreeModel::~CTrendTreeModel() +{ + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = Q_NULLPTR; +} + + +void CTrendTreeModel::initTrendTagInfo() +{ + beginResetModel(); + + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = new QTreeWidgetItem(ROOT_TYPE); + + //< load location + QList locList = CTrendInfoManage::instance()->locationOrderList(); + foreach (const int &locId, locList) { + QString desc = CTrendInfoManage::instance()->getLocationDesc(locId); + QList > devGroupInfoList = CTrendInfoManage::instance()->devGroupInfoList(locId); + if(devGroupInfoList.isEmpty()) + { + continue; + } + QTreeWidgetItem * locationItem = new QTreeWidgetItem(m_rootItem, QStringList() << desc, LOCATION_TYPE); + locationItem->setData(0, ItemTagRole, locId); + QList >::const_iterator iter_devGroup = devGroupInfoList.constBegin(); + while (iter_devGroup != devGroupInfoList.constEnd()) + { + //< load device + QMap devInfo = CTrendInfoManage::instance()->deviceInfo((*iter_devGroup).first); + if(devInfo.isEmpty()) + { + ++iter_devGroup; + continue; + } + QTreeWidgetItem * devGroupItem = new QTreeWidgetItem(locationItem, QStringList() << (*iter_devGroup).second, DEV_GROUP_TYPE); + devGroupItem->setData(0, ItemTagRole, (*iter_devGroup).first); + QMap::const_iterator iter_device = devInfo.constBegin(); + while (iter_device != devInfo.constEnd()) + { + //< load tag + QStringList listTagName = CTrendInfoManage::instance()->queryTagList(iter_device.key()); + if(listTagName.isEmpty()) + { + ++iter_device; + continue; + } +// QTreeWidgetItem * devItem = new QTreeWidgetItem(devGroupItem, QStringList() << iter_device.value(), DEV_TYPE); +// devItem->setData(0, ItemTagRole, iter_device.key()); + QStringList::const_iterator iter_tag = listTagName.constBegin(); + while (iter_tag != listTagName.constEnd()) + { +// QTreeWidgetItem * tagItem = new QTreeWidgetItem(devItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); + QTreeWidgetItem * tagItem = new QTreeWidgetItem(devGroupItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); + tagItem->setData(0, ItemTagRole, *iter_tag); + tagItem->setToolTip(0, *iter_tag); + ++iter_tag; + } + ++iter_device; + } + ++iter_devGroup; + } + } + endResetModel(); + if(m_pView == Q_NULLPTR) + { + return; + } + for(int n=0; nchildCount(); n++) + { + m_pView->expand(index(n,0)); + } +} + +void CTrendTreeModel::clearTrendTagInfo() +{ + CTrendInfoManage::instance()->destory(); + beginResetModel(); + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = Q_NULLPTR; + endResetModel(); +} + +QVariant CTrendTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CTrendTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) + { + return QModelIndex(); + } + + QTreeWidgetItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + QTreeWidgetItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,0,childItem); + } + } + + return QModelIndex(); +} + +QModelIndex CTrendTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + QTreeWidgetItem *childItem = static_cast(index.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + QTreeWidgetItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + { + return QModelIndex(); + } + + int row = parentItem->parent()->indexOfChild(parentItem); + return createIndex(row, 0, parentItem); +} + +int CTrendTreeModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (NULL != m_rootItem) + { + return m_rootItem->childCount(); + } + else + { + return 0; + } + } + else + { + QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int CTrendTreeModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant CTrendTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(TAG_TYPE == item->type() && Qt::CheckStateRole == role && 0 == index.column()) + { + return item->checkState(index.column()); + } + return item->data(index.column(), role); + } + return QVariant(); +} + +bool CTrendTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + + if(!index.isValid()) + { + return false; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(item->data(0, ItemTagRole).toString(), value.toInt()); + } + item->setData(index.column(), role, value); + } + + return true; +} + +Qt::ItemFlags CTrendTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item && TAG_TYPE == item->type()) + { + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +void CTrendTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } +// if(DEV_TYPE == item->type()) + if(DEV_GROUP_TYPE == item->type()) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + if(m_pView->isRowHidden(nChildIndex, index)) + { + continue; + } + setData(index.child(nChildIndex, 0), state, Qt::CheckStateRole); + } + m_pView->update(); + } +} + +void CTrendTreeModel::updateNodeVisualState(const QString &content, QItemSelection &selection) +{ + for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) + { + QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); + bool hit = traverNode(content, topLevelIndex, selection); + m_pView->setRowHidden(topLevelIndex.row(), topLevelIndex.parent(), !hit); + } +} + +bool CTrendTreeModel::traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection) +{ + if(!index.isValid()) + { + return false; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return false; + } + + bool isContains = false; + if(content.isEmpty()) + { + isContains = true; + } + else + { + isContains = item->text(index.column()).contains(content); + if(isContains) + { + selection.append(QItemSelectionRange(index)); + } + } + + if(TAG_TYPE == item->type()) + { + m_pView->setRowHidden(index.row(), index.parent(), !isContains); + return isContains; + } + + bool hasHit = false; + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + if(traverNode(content, index.child(nChildIndex, 0), selection)) + { + hasHit = true; + } + } + + if(DEV_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + if(DEV_GROUP_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + for(int n(0); n < item->child(nChildIndex)->childCount(); n++) + { + m_pView->setRowHidden(n, createIndex(n, 0, item->child(nChildIndex)), false); + } + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + return hasHit | isContains; +} + +void CTrendTreeModel::clearCheckState() +{ + if(!m_rootItem) + { + return; + } + blockSignals(true); + for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) + { + QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); + updateChildCheckState(topLevelIndex, Qt::Unchecked); + } + blockSignals(false); + m_pView->update(); +} + +void CTrendTreeModel::updateTagCheckState(const QString &tag, const bool &checked) +{ + for(int nLocationRow(0); nLocationRow < m_rootItem->childCount(); nLocationRow++) + { + QTreeWidgetItem * locationItem = m_rootItem->child(nLocationRow); + for(int nDeviceGroupRow(0); nDeviceGroupRow < locationItem->childCount(); nDeviceGroupRow++) + { + QTreeWidgetItem * deviceGroupItem = locationItem->child(nDeviceGroupRow); + for(int nDeviceRow(0); nDeviceRow < deviceGroupItem->childCount(); nDeviceRow++) + { +// QTreeWidgetItem * deviceItem = deviceGroupItem->child(nDeviceRow); +// for(int nTagRow(0); nTagRow < deviceItem->childCount(); nTagRow++) +// { + QTreeWidgetItem * tagItem = deviceGroupItem->child(nDeviceRow); + if(tag == tagItem->data(0, ItemTagRole).toString()) + { + tagItem->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); + return; + } +// } + } + } + } +} + +void CTrendTreeModel::updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } + if(TAG_TYPE == item->type()) + { + item->setCheckState(0, state); + } + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + updateChildCheckState(index.child(nChildIndex, 0), state); + } +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeModel.h b/product/src/gui/plugin/TrendCurves/CTrendTreeModel.h index 08d82f69..6240ebe1 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeModel.h +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeModel.h @@ -1,66 +1,66 @@ -#ifndef CTRENDTREEMODEL_H -#define CTRENDTREEMODEL_H - -#include -#include - -enum NodeType -{ - ROOT_TYPE = 10000, - LOCATION_TYPE, - DEV_GROUP_TYPE, - DEV_TYPE, - TAG_TYPE -}; - -extern const int ItemTagRole; - -class CTrendTreeModel : public QAbstractItemModel -{ - Q_OBJECT -public: - CTrendTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR); - - ~CTrendTreeModel(); - - void initTrendTagInfo(); - - void clearTrendTagInfo(); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - - void setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state); - - void updateNodeVisualState(const QString &content, QItemSelection &selection); - -signals: - void itemCheckStateChanged(const QString &strTagName, const int &checkedState); - -public slots: - void clearCheckState(); - void updateTagCheckState(const QString &tag, const bool &checked); - -protected: - bool traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection); - - void updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state); - -private: - QTreeView * m_pView; - QStringList m_header; - QTreeWidgetItem * m_rootItem; -}; - -#endif // CTRENDTREEMODEL_H +#ifndef CTRENDTREEMODEL_H +#define CTRENDTREEMODEL_H + +#include +#include + +enum NodeType +{ + ROOT_TYPE = 10000, + LOCATION_TYPE, + DEV_GROUP_TYPE, + DEV_TYPE, + TAG_TYPE +}; + +extern const int ItemTagRole; + +class CTrendTreeModel : public QAbstractItemModel +{ + Q_OBJECT +public: + CTrendTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR); + + ~CTrendTreeModel(); + + void initTrendTagInfo(); + + void clearTrendTagInfo(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void updateNodeVisualState(const QString &content, QItemSelection &selection); + +signals: + void itemCheckStateChanged(const QString &strTagName, const int &checkedState); + +public slots: + void clearCheckState(); + void updateTagCheckState(const QString &tag, const bool &checked); + +protected: + bool traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection); + + void updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state); + +private: + QTreeView * m_pView; + QStringList m_header; + QTreeWidgetItem * m_rootItem; +}; + +#endif // CTRENDTREEMODEL_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeView.cpp b/product/src/gui/plugin/TrendCurves/CTrendTreeView.cpp index acfc9f7d..7429b244 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeView.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeView.cpp @@ -1,60 +1,60 @@ -#include "CTrendTreeView.h" -#include "CTrendTreeModel.h" -#include -#include -#include - -CTrendTreeView::CTrendTreeView(QWidget *parent) - : QTreeView(parent) -{ - -} - -void CTrendTreeView::contextMenuEvent(QContextMenuEvent *event) -{ - CTrendTreeModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR != pModel) - { - QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); - if(Q_NULLPTR != pItem) - { -// if(DEV_TYPE == pItem->type()) - if(DEV_GROUP_TYPE == pItem->type()) - { - QMenu menu; - menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); - menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Unchecked); }); - menu.exec(event->globalPos()); - } - } - } - return; -} - -void CTrendTreeView::mouseDoubleClickEvent(QMouseEvent *event) -{ - CTrendTreeModel * pModel = dynamic_cast(model()); - if(Q_NULLPTR != pModel) - { - QModelIndex index = indexAt(event->pos()); - QTreeWidgetItem * pItem = static_cast(index.internalPointer()); - if(Q_NULLPTR != pItem) - { - if(TAG_TYPE == pItem->type()) - { - Qt::CheckState state = pItem->data(0, Qt::CheckStateRole).value(); - if (Qt::Checked == state) - { - state = Qt::Unchecked; - } - else - { - state = Qt::Checked; - } - pModel->setData(index, state, Qt::CheckStateRole); - update(); - } - } - } - return QTreeView::mouseDoubleClickEvent(event); -} +#include "CTrendTreeView.h" +#include "CTrendTreeModel.h" +#include +#include +#include + +CTrendTreeView::CTrendTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} + +void CTrendTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CTrendTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if(Q_NULLPTR != pItem) + { +// if(DEV_TYPE == pItem->type()) + if(DEV_GROUP_TYPE == pItem->type()) + { + QMenu menu; + menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); + menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Unchecked); }); + menu.exec(event->globalPos()); + } + } + } + return; +} + +void CTrendTreeView::mouseDoubleClickEvent(QMouseEvent *event) +{ + CTrendTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QModelIndex index = indexAt(event->pos()); + QTreeWidgetItem * pItem = static_cast(index.internalPointer()); + if(Q_NULLPTR != pItem) + { + if(TAG_TYPE == pItem->type()) + { + Qt::CheckState state = pItem->data(0, Qt::CheckStateRole).value(); + if (Qt::Checked == state) + { + state = Qt::Unchecked; + } + else + { + state = Qt::Checked; + } + pModel->setData(index, state, Qt::CheckStateRole); + update(); + } + } + } + return QTreeView::mouseDoubleClickEvent(event); +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeView.h b/product/src/gui/plugin/TrendCurves/CTrendTreeView.h index c3e3e4c3..2fb82d37 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeView.h +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeView.h @@ -1,17 +1,17 @@ -#ifndef CTRENDTREEVIEW_H -#define CTRENDTREEVIEW_H - -#include - -class CTrendTreeView : public QTreeView -{ - Q_OBJECT -public: - CTrendTreeView(QWidget *parent = Q_NULLPTR); - -protected: - void contextMenuEvent(QContextMenuEvent *event); - void mouseDoubleClickEvent(QMouseEvent *event); -}; - -#endif // CTRENDTREEVIEW_H +#ifndef CTRENDTREEVIEW_H +#define CTRENDTREEVIEW_H + +#include + +class CTrendTreeView : public QTreeView +{ + Q_OBJECT +public: + CTrendTreeView(QWidget *parent = Q_NULLPTR); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); +}; + +#endif // CTRENDTREEVIEW_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendWindow.cpp b/product/src/gui/plugin/TrendCurves/CTrendWindow.cpp index 34893ca5..6928e868 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendWindow.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendWindow.cpp @@ -1,543 +1,543 @@ -#include "CTrendWindow.h" -#include -#include -#include -#include -#include -#include "CPlotWidget.h" -#include -#include -#include "CTrendTreeView.h" -#include "CTrendTreeModel.h" -#include "CTrendInfoManage.h" -#include "CTrendFavTreeWidget.h" -#include "pub_utility_api/FileUtil.h" -#include "./widgets/CEditCollectWidget.h" -#include "./widgets/CSliderRangeWidget.h" -#include "pub_utility_api/FileStyle.h" - -CTrendWindow::CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent) - : QWidget(parent), - m_isEditMode(editMode), - m_pTagWidget(Q_NULLPTR), - m_plotWidget(Q_NULLPTR), - m_pTagTreeView(Q_NULLPTR), - m_pTrendTreeModel(Q_NULLPTR), - m_pSearchButton(Q_NULLPTR), - m_pSearchTextEdit(Q_NULLPTR), - m_pSplitter(Q_NULLPTR), - m_pCollectWidget(Q_NULLPTR), - m_pSliderRangeWidget(Q_NULLPTR) -{ - Q_UNUSED(ptrVec) - - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("trendCurves.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} - -CTrendWindow::~CTrendWindow() -{ - CTrendInfoManage::instance()->destory(); -} - -void CTrendWindow::initialize(const int &mode) -{ - clearChildren(); - - if(m_isEditMode) - { - initWindow(); - return; - } - - if(E_Trend_Window == (E_Trend_Mode)mode) - { - initWindow(); - } - else if(E_Trend_Widget == (E_Trend_Mode)mode) - { - initWidget(); - } - - if(m_plotWidget) - { - QString strColorConfig; - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("curveColor.cfg") ; - QFile colorFile(QString::fromStdString(strFullPath)); - if (colorFile.open(QIODevice::ReadOnly)) - { - QTextStream colorStream(&colorFile); - strColorConfig= colorStream.readAll(); - } - QStringList listColor = strColorConfig.split("\n"); - m_plotWidget->setColorList(listColor); - - m_pCollectWidget = new CEditCollectWidget(this); - connect(m_pCollectWidget, &CEditCollectWidget::acceptedInput, this, &CTrendWindow::slotCollectGraph); - connect(this, &CTrendWindow::sigCollectGraph, m_plotWidget, &CPlotWidget::slotCollectGraph); - connect(m_plotWidget, &CPlotWidget::sigAddCollect, this, &CTrendWindow::slotAddCollect); - connect(m_plotWidget, &CPlotWidget::sigHideCollect, this, &CTrendWindow::slotHideCollect); - - m_pSliderRangeWidget = new CSliderRangeWidget(this); - connect(m_pSliderRangeWidget, &CSliderRangeWidget::acceptedInput, this, &CTrendWindow::slotSliderChange); - connect(this, &CTrendWindow::sigSliderRangeChange, m_plotWidget, &CPlotWidget::slotSliderRangeChange); - connect(m_plotWidget, &CPlotWidget::sigSliderRangeSet, this, &CTrendWindow::slotSliderRangeSet); - connect(m_plotWidget, &CPlotWidget::sigHideSliderSet, this, &CTrendWindow::slotHideSliderSet); - - } -} - -void CTrendWindow::setTitle(const QString &title) -{ - if(m_plotWidget) - { - m_plotWidget->setTitle(title); - } -} - -void CTrendWindow::setTitleVisible(bool visible) -{ - if(m_plotWidget) - { - m_plotWidget->setTitleVisible(visible); - } -} - -void CTrendWindow::setTickCount(const int &count) -{ - if(m_plotWidget) - { - m_plotWidget->setTickCount(count); - } -} - -void CTrendWindow::insertTag(const QString &tag, const bool &resetTitle) -{ - if(m_plotWidget) - { - m_plotWidget->insertTag(tag,resetTitle); - } -} - -void CTrendWindow::insertTag(const QStringList &listTag, const bool &resetTitle) -{ - if(m_plotWidget) - { - m_plotWidget->insertTag(listTag,resetTitle); - } -} - -void CTrendWindow::removeTag(const QString &tag, const bool &resetTitle) -{ - if(m_plotWidget) - { - m_plotWidget->removeTag(tag,resetTitle); - } -} - -void CTrendWindow::setDisplayTime(const int &trendType, const double &dateTime) -{ - if(m_plotWidget) - { - m_plotWidget->setDisplayTime(trendType, dateTime); - } -} - -void CTrendWindow::setTagVisible(const QString &tag, const bool &visible) -{ - if(m_plotWidget) - { - m_plotWidget->setTagVisible(tag, visible); - } -} - -void CTrendWindow::clearTag() -{ - if(m_plotWidget) - { - m_plotWidget->clear(); - } -} - -void CTrendWindow::setDateButtonVisible(const int &button, const bool &visible) -{ - if(m_plotWidget) - { - m_plotWidget->setDateButtonVisible(button, visible); - } -} - -void CTrendWindow::setClearVisible(bool visible) -{ - if(m_plotWidget) - { - m_plotWidget->setClearVisible(visible); - } -} - -void CTrendWindow::setDevTreeVisible(bool visible) -{ - m_pTagWidget->setVisible(visible); -} - -void CTrendWindow::setAdaptVisible(bool visible) -{ - if(m_plotWidget) - { - m_plotWidget->setAdaptVisible(visible); - } -} - -void CTrendWindow::setAlarmPointVisible(bool visible) -{ - if(m_plotWidget) - { - m_plotWidget->setAlarmPointVisible(visible); - } -} - -void CTrendWindow::initWindow() -{ - m_pTagWidget = new QTabWidget(this); - m_pTagWidget->setTabPosition(QTabWidget::North); - m_pTagTreeView = new CTrendTreeView(this); - m_pTrendTreeModel = new CTrendTreeModel(this, m_pTagTreeView); - m_pTagTreeView->setModel(m_pTrendTreeModel); - m_pTagTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_pTagTreeView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); - - QHBoxLayout * pHBoxLayout = new QHBoxLayout(m_pTagTreeView->header()); - m_pSearchTextEdit = new QLineEdit(m_pTagTreeView->header()); - m_pSearchTextEdit->setObjectName("searchTextEdit"); - m_pSearchButton = new QPushButton(m_pTagTreeView->header()); - m_pSearchButton->setObjectName("searchButton"); - connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CTrendWindow::FindTagName); - connect(m_pSearchButton, &QPushButton::clicked, this, &CTrendWindow::FindTagName); - pHBoxLayout->addWidget(m_pSearchTextEdit, 1); - pHBoxLayout->addWidget(m_pSearchButton, 0); - pHBoxLayout->setContentsMargins(5,0,5,0); - pHBoxLayout->setSpacing(0); - m_pTagTreeView->header()->setLayout(pHBoxLayout); - m_pTagWidget->addTab(m_pTagTreeView, tr("设备/点")); - CTrendFavTreeWidget * pFavoritesTreeWidget = new CTrendFavTreeWidget(m_pTagWidget); - pFavoritesTreeWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); - m_pTagWidget->addTab(pFavoritesTreeWidget, tr("收藏夹")); - m_pTagWidget->setContentsMargins(1,1,1,1); - m_pTagWidget->setCurrentIndex(1); - m_plotWidget = new CPlotWidget(this); - m_plotWidget->initialize(); - m_pSplitter = new QSplitter(this); - m_pSplitter->addWidget(m_pTagWidget); - m_pSplitter->addWidget(m_plotWidget); - m_pSplitter->setStretchFactor(0, 2); - m_pSplitter->setStretchFactor(1, 3); - m_pSplitter->setContentsMargins(6, 6, 6, 6); - m_pSplitter->setHandleWidth(10); - QHBoxLayout * layout = new QHBoxLayout(this); - layout->addWidget(m_pSplitter); - layout->setContentsMargins(0, 0, 0, 0); - setLayout(layout); - connect(m_plotWidget, &CPlotWidget::clearCurve, m_pTrendTreeModel, &CTrendTreeModel::clearCheckState); - connect(m_plotWidget, &CPlotWidget::collectGraph, pFavoritesTreeWidget, &CTrendFavTreeWidget::collectGraph); - connect(m_plotWidget, &CPlotWidget::updateTagCheckState, m_pTrendTreeModel, &CTrendTreeModel::updateTagCheckState, Qt::QueuedConnection); - connect(m_pTrendTreeModel, &CTrendTreeModel::itemCheckStateChanged, this, &CTrendWindow::itemCheckStateChanged); - connect(pFavoritesTreeWidget, &CTrendFavTreeWidget::showTrendGraph, this, &CTrendWindow::showTrendGraph); - - if(!m_isEditMode) - { - m_pTagWidget->installEventFilter(this); - m_pTagWidget->tabBar()->installEventFilter(this); - m_pTagTreeView->viewport()->installEventFilter(this); - m_pTagTreeView->header()->viewport()->installEventFilter(this); - m_pSearchTextEdit->installEventFilter(this); - m_pSearchButton->installEventFilter(this); - pFavoritesTreeWidget->viewport()->installEventFilter(this); - pFavoritesTreeWidget->header()->viewport()->installEventFilter(this); - } -} - -void CTrendWindow::initWidget() -{ - m_plotWidget = new CPlotWidget(this); - m_plotWidget->initialize(); - m_plotWidget->setTickCount(5); - m_plotWidget->setWindowMode(false); - QHBoxLayout * layout = new QHBoxLayout(this); - layout->addWidget(m_plotWidget); - layout->setMargin(3); - setLayout(layout); -} - -void CTrendWindow::clearChildren() -{ - if(m_pSearchButton) - { - delete m_pSearchButton; - } - m_pSearchButton = Q_NULLPTR; - - if(m_pSearchTextEdit) - { - delete m_pSearchTextEdit; - } - m_pSearchTextEdit = Q_NULLPTR; - - if(m_pTagTreeView) - { - delete m_pTagTreeView; - } - m_pTagTreeView = Q_NULLPTR; - - if(m_pTagWidget) - { - delete m_pTagWidget; - } - m_pTagWidget = Q_NULLPTR; - - if(m_pCollectWidget) - { - m_pCollectWidget->close(); - delete m_pCollectWidget; - } - m_pCollectWidget = Q_NULLPTR; - - if(m_pSliderRangeWidget) - { - m_pSliderRangeWidget->close(); - delete m_pSliderRangeWidget; - } - m_pSliderRangeWidget = Q_NULLPTR; - - if(m_plotWidget) - { - delete m_plotWidget; - } - m_plotWidget = Q_NULLPTR; - - if(m_pTrendTreeModel) - { - delete m_pTrendTreeModel; - } - m_pTrendTreeModel = Q_NULLPTR; - - if(m_pSplitter) - { - delete m_pSplitter; - } - m_pSplitter = Q_NULLPTR; - - if(layout()) - { - delete layout(); - } -} - -void CTrendWindow::login() -{ - if(m_pTrendTreeModel) - { - m_pTrendTreeModel->initTrendTagInfo(); - } -} - -void CTrendWindow::logout() -{ - if(m_pTrendTreeModel) - { - m_pTrendTreeModel->clearTrendTagInfo(); - } - - if(m_plotWidget) - { - m_plotWidget->clear(true); - } -} - -void CTrendWindow::slotCollectGraph() -{ - if(!m_pCollectWidget) - { - return; - } - if(!m_pCollectWidget->text().isEmpty()) - { - emit sigCollectGraph(m_pCollectWidget->text()); - m_pCollectWidget->hide(); - } - else - { - m_pCollectWidget->hide(); - QMessageBox::warning(this, tr("错误"), tr("趋势名称不允许为空!"), - QMessageBox::Ok); - } -} - -void CTrendWindow::slotAddCollect(int x, int y) -{ - m_pCollectWidget->show(); - m_pCollectWidget->clear(); - m_pCollectWidget->setEditFocus(); - QPoint pt; - pt.setX(x - m_pCollectWidget->width()); - pt.setY(y); - m_pCollectWidget->move(pt); -} - -void CTrendWindow::slotHideCollect() -{ - if(!m_pCollectWidget) - { - return; - } - if(!m_pCollectWidget->isHidden()) - { - m_pCollectWidget->hide(); - } -} - -void CTrendWindow::slotSliderChange() -{ - if(!m_pSliderRangeWidget) - { - return; - } - int lower = m_pSliderRangeWidget->lowValue(); - int upper = m_pSliderRangeWidget->upValue(); - if(lower > upper) - { - QMessageBox::warning(this, tr("错误"), tr("最小值不能大于最大值!"), QMessageBox::Ok); - } - else - { - emit sigSliderRangeChange(lower, upper); - m_pSliderRangeWidget->hide(); - } -} - -void CTrendWindow::slotSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum) -{ - m_pSliderRangeWidget->setSpinRange(minimum, maximum); - m_pSliderRangeWidget->setLowValue(lower); - m_pSliderRangeWidget->setUpValue(upper); - m_pSliderRangeWidget->show(); - m_pSliderRangeWidget->setEditFocus(); - QPoint pt; - pt.setX(x - m_pSliderRangeWidget->width()); - pt.setY(y); - m_pSliderRangeWidget->move(pt); -} - -void CTrendWindow::slotHideSliderSet() -{ - if(!m_pSliderRangeWidget) - { - return; - } - if(!m_pSliderRangeWidget->isHidden()) - { - m_pSliderRangeWidget->hide(); - } -} - -void CTrendWindow::itemCheckStateChanged(const QString &strTagName, const int &checkedState) -{ - if(Qt::Checked == (Qt::CheckState)checkedState) - { - m_plotWidget->insertTag(strTagName); - } - else if(Qt::Unchecked == (Qt::CheckState)checkedState) - { - m_plotWidget->removeTag(strTagName); - } -} - -void CTrendWindow::updateTrendName(const QString &title) -{ - m_plotWidget->setTitle(title); -} - -void CTrendWindow::showTrendGraph(CTrendGraph *graph, const QString &name) -{ - m_plotWidget->clear(); - if(!name.isEmpty()) - { - updateTrendName(name); - } - foreach (Curve curve, graph->curves()) - { - m_plotWidget->insertCurve(curve); - } -} - -void CTrendWindow::FindTagName() -{ - QString content = m_pSearchTextEdit->text(); - m_pTagTreeView->collapseAll(); - m_pTagTreeView->selectionModel()->clear(); - QItemSelection selection; - m_pTrendTreeModel->updateNodeVisualState(content, selection); - m_pTagTreeView->selectionModel()->select(selection, QItemSelectionModel::Select); - - if(content.isEmpty()) - { - m_pTagTreeView->collapseAll(); - } - else - { - m_pTagTreeView->expandAll(); - } -} - -void CTrendWindow::mousePressEvent(QMouseEvent *event) -{ - if(!m_pCollectWidget->isHidden()) - { - m_pCollectWidget->hide(); - } - if(!m_pSliderRangeWidget->isHidden()) - { - m_pSliderRangeWidget->hide(); - } - return QWidget::mousePressEvent(event); -} - -bool CTrendWindow::eventFilter(QObject *watched, QEvent *event) -{ - if (QEvent::MouseButtonPress == event->type()) - { - if(!m_pCollectWidget->isHidden()) - { - m_pCollectWidget->hide(); - } - if(!m_pSliderRangeWidget->isHidden()) - { - m_pSliderRangeWidget->hide(); - } - return false; - } - - return QWidget::eventFilter(watched, event); -} - +#include "CTrendWindow.h" +#include +#include +#include +#include +#include +#include "CPlotWidget.h" +#include +#include +#include "CTrendTreeView.h" +#include "CTrendTreeModel.h" +#include "CTrendInfoManage.h" +#include "CTrendFavTreeWidget.h" +#include "pub_utility_api/FileUtil.h" +#include "./widgets/CEditCollectWidget.h" +#include "./widgets/CSliderRangeWidget.h" +#include "pub_utility_api/FileStyle.h" + +CTrendWindow::CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent) + : QWidget(parent), + m_isEditMode(editMode), + m_pTagWidget(Q_NULLPTR), + m_plotWidget(Q_NULLPTR), + m_pTagTreeView(Q_NULLPTR), + m_pTrendTreeModel(Q_NULLPTR), + m_pSearchButton(Q_NULLPTR), + m_pSearchTextEdit(Q_NULLPTR), + m_pSplitter(Q_NULLPTR), + m_pCollectWidget(Q_NULLPTR), + m_pSliderRangeWidget(Q_NULLPTR) +{ + Q_UNUSED(ptrVec) + + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("trendCurves.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +CTrendWindow::~CTrendWindow() +{ + CTrendInfoManage::instance()->destory(); +} + +void CTrendWindow::initialize(const int &mode) +{ + clearChildren(); + + if(m_isEditMode) + { + initWindow(); + return; + } + + if(E_Trend_Window == (E_Trend_Mode)mode) + { + initWindow(); + } + else if(E_Trend_Widget == (E_Trend_Mode)mode) + { + initWidget(); + } + + if(m_plotWidget) + { + QString strColorConfig; + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("curveColor.cfg") ; + QFile colorFile(QString::fromStdString(strFullPath)); + if (colorFile.open(QIODevice::ReadOnly)) + { + QTextStream colorStream(&colorFile); + strColorConfig= colorStream.readAll(); + } + QStringList listColor = strColorConfig.split("\n"); + m_plotWidget->setColorList(listColor); + + m_pCollectWidget = new CEditCollectWidget(this); + connect(m_pCollectWidget, &CEditCollectWidget::acceptedInput, this, &CTrendWindow::slotCollectGraph); + connect(this, &CTrendWindow::sigCollectGraph, m_plotWidget, &CPlotWidget::slotCollectGraph); + connect(m_plotWidget, &CPlotWidget::sigAddCollect, this, &CTrendWindow::slotAddCollect); + connect(m_plotWidget, &CPlotWidget::sigHideCollect, this, &CTrendWindow::slotHideCollect); + + m_pSliderRangeWidget = new CSliderRangeWidget(this); + connect(m_pSliderRangeWidget, &CSliderRangeWidget::acceptedInput, this, &CTrendWindow::slotSliderChange); + connect(this, &CTrendWindow::sigSliderRangeChange, m_plotWidget, &CPlotWidget::slotSliderRangeChange); + connect(m_plotWidget, &CPlotWidget::sigSliderRangeSet, this, &CTrendWindow::slotSliderRangeSet); + connect(m_plotWidget, &CPlotWidget::sigHideSliderSet, this, &CTrendWindow::slotHideSliderSet); + + } +} + +void CTrendWindow::setTitle(const QString &title) +{ + if(m_plotWidget) + { + m_plotWidget->setTitle(title); + } +} + +void CTrendWindow::setTitleVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setTitleVisible(visible); + } +} + +void CTrendWindow::setTickCount(const int &count) +{ + if(m_plotWidget) + { + m_plotWidget->setTickCount(count); + } +} + +void CTrendWindow::insertTag(const QString &tag, const bool &resetTitle) +{ + if(m_plotWidget) + { + m_plotWidget->insertTag(tag,resetTitle); + } +} + +void CTrendWindow::insertTag(const QStringList &listTag, const bool &resetTitle) +{ + if(m_plotWidget) + { + m_plotWidget->insertTag(listTag,resetTitle); + } +} + +void CTrendWindow::removeTag(const QString &tag, const bool &resetTitle) +{ + if(m_plotWidget) + { + m_plotWidget->removeTag(tag,resetTitle); + } +} + +void CTrendWindow::setDisplayTime(const int &trendType, const double &dateTime) +{ + if(m_plotWidget) + { + m_plotWidget->setDisplayTime(trendType, dateTime); + } +} + +void CTrendWindow::setTagVisible(const QString &tag, const bool &visible) +{ + if(m_plotWidget) + { + m_plotWidget->setTagVisible(tag, visible); + } +} + +void CTrendWindow::clearTag() +{ + if(m_plotWidget) + { + m_plotWidget->clear(); + } +} + +void CTrendWindow::setDateButtonVisible(const int &button, const bool &visible) +{ + if(m_plotWidget) + { + m_plotWidget->setDateButtonVisible(button, visible); + } +} + +void CTrendWindow::setClearVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setClearVisible(visible); + } +} + +void CTrendWindow::setDevTreeVisible(bool visible) +{ + m_pTagWidget->setVisible(visible); +} + +void CTrendWindow::setAdaptVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setAdaptVisible(visible); + } +} + +void CTrendWindow::setAlarmPointVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setAlarmPointVisible(visible); + } +} + +void CTrendWindow::initWindow() +{ + m_pTagWidget = new QTabWidget(this); + m_pTagWidget->setTabPosition(QTabWidget::North); + m_pTagTreeView = new CTrendTreeView(this); + m_pTrendTreeModel = new CTrendTreeModel(this, m_pTagTreeView); + m_pTagTreeView->setModel(m_pTrendTreeModel); + m_pTagTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_pTagTreeView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + + QHBoxLayout * pHBoxLayout = new QHBoxLayout(m_pTagTreeView->header()); + m_pSearchTextEdit = new QLineEdit(m_pTagTreeView->header()); + m_pSearchTextEdit->setObjectName("searchTextEdit"); + m_pSearchButton = new QPushButton(m_pTagTreeView->header()); + m_pSearchButton->setObjectName("searchButton"); + connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CTrendWindow::FindTagName); + connect(m_pSearchButton, &QPushButton::clicked, this, &CTrendWindow::FindTagName); + pHBoxLayout->addWidget(m_pSearchTextEdit, 1); + pHBoxLayout->addWidget(m_pSearchButton, 0); + pHBoxLayout->setContentsMargins(5,0,5,0); + pHBoxLayout->setSpacing(0); + m_pTagTreeView->header()->setLayout(pHBoxLayout); + m_pTagWidget->addTab(m_pTagTreeView, tr("设备/点")); + CTrendFavTreeWidget * pFavoritesTreeWidget = new CTrendFavTreeWidget(m_pTagWidget); + pFavoritesTreeWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + m_pTagWidget->addTab(pFavoritesTreeWidget, tr("收藏夹")); + m_pTagWidget->setContentsMargins(1,1,1,1); + m_pTagWidget->setCurrentIndex(1); + m_plotWidget = new CPlotWidget(this); + m_plotWidget->initialize(); + m_pSplitter = new QSplitter(this); + m_pSplitter->addWidget(m_pTagWidget); + m_pSplitter->addWidget(m_plotWidget); + m_pSplitter->setStretchFactor(0, 2); + m_pSplitter->setStretchFactor(1, 3); + m_pSplitter->setContentsMargins(6, 6, 6, 6); + m_pSplitter->setHandleWidth(10); + QHBoxLayout * layout = new QHBoxLayout(this); + layout->addWidget(m_pSplitter); + layout->setContentsMargins(0, 0, 0, 0); + setLayout(layout); + connect(m_plotWidget, &CPlotWidget::clearCurve, m_pTrendTreeModel, &CTrendTreeModel::clearCheckState); + connect(m_plotWidget, &CPlotWidget::collectGraph, pFavoritesTreeWidget, &CTrendFavTreeWidget::collectGraph); + connect(m_plotWidget, &CPlotWidget::updateTagCheckState, m_pTrendTreeModel, &CTrendTreeModel::updateTagCheckState, Qt::QueuedConnection); + connect(m_pTrendTreeModel, &CTrendTreeModel::itemCheckStateChanged, this, &CTrendWindow::itemCheckStateChanged); + connect(pFavoritesTreeWidget, &CTrendFavTreeWidget::showTrendGraph, this, &CTrendWindow::showTrendGraph); + + if(!m_isEditMode) + { + m_pTagWidget->installEventFilter(this); + m_pTagWidget->tabBar()->installEventFilter(this); + m_pTagTreeView->viewport()->installEventFilter(this); + m_pTagTreeView->header()->viewport()->installEventFilter(this); + m_pSearchTextEdit->installEventFilter(this); + m_pSearchButton->installEventFilter(this); + pFavoritesTreeWidget->viewport()->installEventFilter(this); + pFavoritesTreeWidget->header()->viewport()->installEventFilter(this); + } +} + +void CTrendWindow::initWidget() +{ + m_plotWidget = new CPlotWidget(this); + m_plotWidget->initialize(); + m_plotWidget->setTickCount(5); + m_plotWidget->setWindowMode(false); + QHBoxLayout * layout = new QHBoxLayout(this); + layout->addWidget(m_plotWidget); + layout->setMargin(3); + setLayout(layout); +} + +void CTrendWindow::clearChildren() +{ + if(m_pSearchButton) + { + delete m_pSearchButton; + } + m_pSearchButton = Q_NULLPTR; + + if(m_pSearchTextEdit) + { + delete m_pSearchTextEdit; + } + m_pSearchTextEdit = Q_NULLPTR; + + if(m_pTagTreeView) + { + delete m_pTagTreeView; + } + m_pTagTreeView = Q_NULLPTR; + + if(m_pTagWidget) + { + delete m_pTagWidget; + } + m_pTagWidget = Q_NULLPTR; + + if(m_pCollectWidget) + { + m_pCollectWidget->close(); + delete m_pCollectWidget; + } + m_pCollectWidget = Q_NULLPTR; + + if(m_pSliderRangeWidget) + { + m_pSliderRangeWidget->close(); + delete m_pSliderRangeWidget; + } + m_pSliderRangeWidget = Q_NULLPTR; + + if(m_plotWidget) + { + delete m_plotWidget; + } + m_plotWidget = Q_NULLPTR; + + if(m_pTrendTreeModel) + { + delete m_pTrendTreeModel; + } + m_pTrendTreeModel = Q_NULLPTR; + + if(m_pSplitter) + { + delete m_pSplitter; + } + m_pSplitter = Q_NULLPTR; + + if(layout()) + { + delete layout(); + } +} + +void CTrendWindow::login() +{ + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->initTrendTagInfo(); + } +} + +void CTrendWindow::logout() +{ + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->clearTrendTagInfo(); + } + + if(m_plotWidget) + { + m_plotWidget->clear(true); + } +} + +void CTrendWindow::slotCollectGraph() +{ + if(!m_pCollectWidget) + { + return; + } + if(!m_pCollectWidget->text().isEmpty()) + { + emit sigCollectGraph(m_pCollectWidget->text()); + m_pCollectWidget->hide(); + } + else + { + m_pCollectWidget->hide(); + QMessageBox::warning(this, tr("错误"), tr("趋势名称不允许为空!"), + QMessageBox::Ok); + } +} + +void CTrendWindow::slotAddCollect(int x, int y) +{ + m_pCollectWidget->show(); + m_pCollectWidget->clear(); + m_pCollectWidget->setEditFocus(); + QPoint pt; + pt.setX(x - m_pCollectWidget->width()); + pt.setY(y); + m_pCollectWidget->move(pt); +} + +void CTrendWindow::slotHideCollect() +{ + if(!m_pCollectWidget) + { + return; + } + if(!m_pCollectWidget->isHidden()) + { + m_pCollectWidget->hide(); + } +} + +void CTrendWindow::slotSliderChange() +{ + if(!m_pSliderRangeWidget) + { + return; + } + int lower = m_pSliderRangeWidget->lowValue(); + int upper = m_pSliderRangeWidget->upValue(); + if(lower > upper) + { + QMessageBox::warning(this, tr("错误"), tr("最小值不能大于最大值!"), QMessageBox::Ok); + } + else + { + emit sigSliderRangeChange(lower, upper); + m_pSliderRangeWidget->hide(); + } +} + +void CTrendWindow::slotSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum) +{ + m_pSliderRangeWidget->setSpinRange(minimum, maximum); + m_pSliderRangeWidget->setLowValue(lower); + m_pSliderRangeWidget->setUpValue(upper); + m_pSliderRangeWidget->show(); + m_pSliderRangeWidget->setEditFocus(); + QPoint pt; + pt.setX(x - m_pSliderRangeWidget->width()); + pt.setY(y); + m_pSliderRangeWidget->move(pt); +} + +void CTrendWindow::slotHideSliderSet() +{ + if(!m_pSliderRangeWidget) + { + return; + } + if(!m_pSliderRangeWidget->isHidden()) + { + m_pSliderRangeWidget->hide(); + } +} + +void CTrendWindow::itemCheckStateChanged(const QString &strTagName, const int &checkedState) +{ + if(Qt::Checked == (Qt::CheckState)checkedState) + { + m_plotWidget->insertTag(strTagName); + } + else if(Qt::Unchecked == (Qt::CheckState)checkedState) + { + m_plotWidget->removeTag(strTagName); + } +} + +void CTrendWindow::updateTrendName(const QString &title) +{ + m_plotWidget->setTitle(title); +} + +void CTrendWindow::showTrendGraph(CTrendGraph *graph, const QString &name) +{ + m_plotWidget->clear(); + if(!name.isEmpty()) + { + updateTrendName(name); + } + foreach (Curve curve, graph->curves()) + { + m_plotWidget->insertCurve(curve); + } +} + +void CTrendWindow::FindTagName() +{ + QString content = m_pSearchTextEdit->text(); + m_pTagTreeView->collapseAll(); + m_pTagTreeView->selectionModel()->clear(); + QItemSelection selection; + m_pTrendTreeModel->updateNodeVisualState(content, selection); + m_pTagTreeView->selectionModel()->select(selection, QItemSelectionModel::Select); + + if(content.isEmpty()) + { + m_pTagTreeView->collapseAll(); + } + else + { + m_pTagTreeView->expandAll(); + } +} + +void CTrendWindow::mousePressEvent(QMouseEvent *event) +{ + if(!m_pCollectWidget->isHidden()) + { + m_pCollectWidget->hide(); + } + if(!m_pSliderRangeWidget->isHidden()) + { + m_pSliderRangeWidget->hide(); + } + return QWidget::mousePressEvent(event); +} + +bool CTrendWindow::eventFilter(QObject *watched, QEvent *event) +{ + if (QEvent::MouseButtonPress == event->type()) + { + if(!m_pCollectWidget->isHidden()) + { + m_pCollectWidget->hide(); + } + if(!m_pSliderRangeWidget->isHidden()) + { + m_pSliderRangeWidget->hide(); + } + return false; + } + + return QWidget::eventFilter(watched, event); +} + diff --git a/product/src/gui/plugin/TrendCurves/CTrendWindow.h b/product/src/gui/plugin/TrendCurves/CTrendWindow.h index 4b80c846..452d9201 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendWindow.h +++ b/product/src/gui/plugin/TrendCurves/CTrendWindow.h @@ -1,95 +1,95 @@ -#ifndef CTRENDWINDOW_H -#define CTRENDWINDOW_H - -#include -#include - -class QSplitter; -class QTreeView; -class QLineEdit; -class QTabWidget; -class CPlotWidget; -class CTrendGraph; -class QPushButton; -class CTrendTreeView; -class CTrendTreeModel; -class CEditCollectWidget; -class CSliderRangeWidget; - -enum E_Trend_Mode -{ - E_Trend_Window = 0, - E_Trend_Widget = 1 -}; - -class CTrendWindow : public QWidget -{ - Q_OBJECT -public: - explicit CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent = 0); - ~CTrendWindow(); - -public slots: - void initialize(const int &mode); - - void setTitle(const QString &title); - void setTitleVisible(bool visible); - void setTickCount(const int &count); - - void insertTag(const QString &tag, const bool &resetTitle = true); - void insertTag(const QStringList &listTag, const bool &resetTitle = true); - void removeTag(const QString &tag, const bool &resetTitle = true); - void setDisplayTime(const int &trendType, const double &dateTime); - void setTagVisible(const QString &tag, const bool &visible = false); - void clearTag(); - void setDateButtonVisible(const int &button, const bool &visible = false); - - void setClearVisible(bool visible); - void setDevTreeVisible(bool visible); - void setAdaptVisible(bool visible); - void setAlarmPointVisible(bool visible); - - void login(); - void logout(); - -signals: - void sigCollectGraph(const QString &text); - void sigSliderRangeChange(int lower, int upper); - -private slots: - void slotCollectGraph(); - void slotAddCollect(int x, int y); - void slotHideCollect(); - - void slotSliderChange(); - void slotSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum); - void slotHideSliderSet(); - -protected: - void initWindow(); - void initWidget(); - - void clearChildren(); - - void itemCheckStateChanged(const QString &strTagName, const int &checkedState); - void updateTrendName(const QString &title); - void showTrendGraph(CTrendGraph * graph, const QString &name = QString()); - void FindTagName(); - - void mousePressEvent(QMouseEvent *event); - bool eventFilter(QObject *watched, QEvent *event); - -private: - bool m_isEditMode; - QTabWidget * m_pTagWidget; - CPlotWidget * m_plotWidget; - CTrendTreeView * m_pTagTreeView; - CTrendTreeModel * m_pTrendTreeModel; - QPushButton * m_pSearchButton; - QLineEdit * m_pSearchTextEdit; - QSplitter * m_pSplitter; - CEditCollectWidget * m_pCollectWidget; - CSliderRangeWidget * m_pSliderRangeWidget; -}; - -#endif // CTRENDWINDOW_H +#ifndef CTRENDWINDOW_H +#define CTRENDWINDOW_H + +#include +#include + +class QSplitter; +class QTreeView; +class QLineEdit; +class QTabWidget; +class CPlotWidget; +class CTrendGraph; +class QPushButton; +class CTrendTreeView; +class CTrendTreeModel; +class CEditCollectWidget; +class CSliderRangeWidget; + +enum E_Trend_Mode +{ + E_Trend_Window = 0, + E_Trend_Widget = 1 +}; + +class CTrendWindow : public QWidget +{ + Q_OBJECT +public: + explicit CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent = 0); + ~CTrendWindow(); + +public slots: + void initialize(const int &mode); + + void setTitle(const QString &title); + void setTitleVisible(bool visible); + void setTickCount(const int &count); + + void insertTag(const QString &tag, const bool &resetTitle = true); + void insertTag(const QStringList &listTag, const bool &resetTitle = true); + void removeTag(const QString &tag, const bool &resetTitle = true); + void setDisplayTime(const int &trendType, const double &dateTime); + void setTagVisible(const QString &tag, const bool &visible = false); + void clearTag(); + void setDateButtonVisible(const int &button, const bool &visible = false); + + void setClearVisible(bool visible); + void setDevTreeVisible(bool visible); + void setAdaptVisible(bool visible); + void setAlarmPointVisible(bool visible); + + void login(); + void logout(); + +signals: + void sigCollectGraph(const QString &text); + void sigSliderRangeChange(int lower, int upper); + +private slots: + void slotCollectGraph(); + void slotAddCollect(int x, int y); + void slotHideCollect(); + + void slotSliderChange(); + void slotSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum); + void slotHideSliderSet(); + +protected: + void initWindow(); + void initWidget(); + + void clearChildren(); + + void itemCheckStateChanged(const QString &strTagName, const int &checkedState); + void updateTrendName(const QString &title); + void showTrendGraph(CTrendGraph * graph, const QString &name = QString()); + void FindTagName(); + + void mousePressEvent(QMouseEvent *event); + bool eventFilter(QObject *watched, QEvent *event); + +private: + bool m_isEditMode; + QTabWidget * m_pTagWidget; + CPlotWidget * m_plotWidget; + CTrendTreeView * m_pTagTreeView; + CTrendTreeModel * m_pTrendTreeModel; + QPushButton * m_pSearchButton; + QLineEdit * m_pSearchTextEdit; + QSplitter * m_pSplitter; + CEditCollectWidget * m_pCollectWidget; + CSliderRangeWidget * m_pSliderRangeWidget; +}; + +#endif // CTRENDWINDOW_H diff --git a/product/src/gui/plugin/TrendCurves/TrendCurves.pro b/product/src/gui/plugin/TrendCurves/TrendCurves.pro index 51db3bc1..64b6db69 100644 --- a/product/src/gui/plugin/TrendCurves/TrendCurves.pro +++ b/product/src/gui/plugin/TrendCurves/TrendCurves.pro @@ -1,97 +1,97 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-11-09T10:35:55 -# -#------------------------------------------------- - - -QT += core gui widgets sql xml printsupport - -TARGET = TrendCurves -TEMPLATE = lib - -CONFIG += plugin - -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/plot/qcustomplot.cpp \ - $$PWD/widgets/CTabButton.cpp \ - $$PWD/widgets/CToolTip.cpp \ - $$PWD/widgets/CEditCollectWidget.cpp \ - $$PWD/widgets/CCalendarWidget.cpp \ - $$PWD/widgets/QxtSpanSlider.cpp \ - $$PWD/widgets/CSWitchButton.cpp \ - $$PWD/widgets/CSliderRangeWidget.cpp \ - CTrendWindow.cpp \ - CTrendGraph.cpp \ - CPlotWidget.cpp \ - CCurveLegendModel.cpp \ - CTrendTreeModel.cpp \ - CTrendInfoManage.cpp \ - CRealTimeDataCollect.cpp \ - CHisEventManage.cpp \ - CTrendFavTreeWidget.cpp \ - CTrendEditDialog.cpp \ - CTrendEditView.cpp \ - CTrendEditModel.cpp \ - CTrendPluginWidget.cpp \ - CTrendTreeView.cpp \ - CHisDataManage.cpp \ - CCurveLegendView.cpp \ - CMyCheckBox.cpp \ - CMyListWidget.cpp \ - CTableDataModel.cpp \ - CTableView.cpp -# main.cpp - -HEADERS += \ - $$PWD/plot/qcustomplot.h \ - $$PWD/widgets/CTabButton.h \ - $$PWD/widgets/CToolTip.h \ - $$PWD/widgets/CEditCollectWidget.h \ - $$PWD/widgets/CCalendarWidget.h \ - $$PWD/widgets/QxtSpanSlider.h \ - $$PWD/widgets/QxtSpanSlider_p.h \ - $$PWD/widgets/CSWitchButton.h \ - $$PWD/widgets/CSliderRangeWidget.h \ - CTrendWindow.h \ - CTrendGraph.h \ - CPlotWidget.h \ - CCurveLegendModel.h \ - CTrendTreeModel.h \ - CTrendInfoManage.h \ - CRealTimeDataCollect.h \ - CHisEventManage.h \ - CTrendFavTreeWidget.h \ - CTrendEditDialog.h \ - CTrendEditView.h \ - CTrendEditModel.h \ - CTrendPluginWidget.h \ - CTrendTreeView.h \ - CHisDataManage.h \ - CCurveLegendView.h \ - CMyCheckBox.h \ - CMyListWidget.h \ - CTableDataModel.h \ - CTableView.h - -FORMS += \ - CPlotWidget.ui \ - CTrendEditDialog.ui - -LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -lmodel_excel -LIBS += -lpub_utility_api -lpub_sysinfo_api -LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api -ldb_his_query_api -LIBS += -lnet_msg_bus_api -lperm_mng_api -ldp_chg_data_api -lRetriever - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - - +#------------------------------------------------- +# +# Project created by QtCreator 2018-11-09T10:35:55 +# +#------------------------------------------------- + + +QT += core gui widgets sql xml printsupport + +TARGET = TrendCurves +TEMPLATE = lib + +CONFIG += plugin + +INCLUDEPATH += $$PWD + +SOURCES += \ + $$PWD/plot/qcustomplot.cpp \ + $$PWD/widgets/CTabButton.cpp \ + $$PWD/widgets/CToolTip.cpp \ + $$PWD/widgets/CEditCollectWidget.cpp \ + $$PWD/widgets/CCalendarWidget.cpp \ + $$PWD/widgets/QxtSpanSlider.cpp \ + $$PWD/widgets/CSWitchButton.cpp \ + $$PWD/widgets/CSliderRangeWidget.cpp \ + CTrendWindow.cpp \ + CTrendGraph.cpp \ + CPlotWidget.cpp \ + CCurveLegendModel.cpp \ + CTrendTreeModel.cpp \ + CTrendInfoManage.cpp \ + CRealTimeDataCollect.cpp \ + CHisEventManage.cpp \ + CTrendFavTreeWidget.cpp \ + CTrendEditDialog.cpp \ + CTrendEditView.cpp \ + CTrendEditModel.cpp \ + CTrendPluginWidget.cpp \ + CTrendTreeView.cpp \ + CHisDataManage.cpp \ + CCurveLegendView.cpp \ + CMyCheckBox.cpp \ + CMyListWidget.cpp \ + CTableDataModel.cpp \ + CTableView.cpp +# main.cpp + +HEADERS += \ + $$PWD/plot/qcustomplot.h \ + $$PWD/widgets/CTabButton.h \ + $$PWD/widgets/CToolTip.h \ + $$PWD/widgets/CEditCollectWidget.h \ + $$PWD/widgets/CCalendarWidget.h \ + $$PWD/widgets/QxtSpanSlider.h \ + $$PWD/widgets/QxtSpanSlider_p.h \ + $$PWD/widgets/CSWitchButton.h \ + $$PWD/widgets/CSliderRangeWidget.h \ + CTrendWindow.h \ + CTrendGraph.h \ + CPlotWidget.h \ + CCurveLegendModel.h \ + CTrendTreeModel.h \ + CTrendInfoManage.h \ + CRealTimeDataCollect.h \ + CHisEventManage.h \ + CTrendFavTreeWidget.h \ + CTrendEditDialog.h \ + CTrendEditView.h \ + CTrendEditModel.h \ + CTrendPluginWidget.h \ + CTrendTreeView.h \ + CHisDataManage.h \ + CCurveLegendView.h \ + CMyCheckBox.h \ + CMyListWidget.h \ + CTableDataModel.h \ + CTableView.h + +FORMS += \ + CPlotWidget.ui \ + CTrendEditDialog.ui + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -lmodel_excel +LIBS += -lpub_utility_api -lpub_sysinfo_api +LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api -ldb_his_query_api +LIBS += -lnet_msg_bus_api -lperm_mng_api -ldp_chg_data_api -lRetriever + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + + diff --git a/product/src/gui/plugin/TrendCurves/main.cpp b/product/src/gui/plugin/TrendCurves/main.cpp index 37f03d68..789f8667 100644 --- a/product/src/gui/plugin/TrendCurves/main.cpp +++ b/product/src/gui/plugin/TrendCurves/main.cpp @@ -1,46 +1,46 @@ -#include -#include "CTrendWindow.h" -#include "pub_logger_api/logger.h" -#include "dp_chg_data_api/CDpcdaForApp.h" -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" - -int main(int argc, char *argv[]) -{ - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - kbd_service::CDpcdaForApp::initGlobalThread(); - - { - LOGINFO("===========================Trend Curve==========================="); - QApplication app(argc, argv); - - QVector ptrVec; - CTrendWindow w(false, ptrVec); - w.initialize(E_Trend_Window); - w.show(); - - app.exec(); - } - - kbd_service::CDpcdaForApp::releaseGlobalThread(); - - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include +#include "CTrendWindow.h" +#include "pub_logger_api/logger.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + kbd_service::CDpcdaForApp::initGlobalThread(); + + { + LOGINFO("===========================Trend Curve==========================="); + QApplication app(argc, argv); + + QVector ptrVec; + CTrendWindow w(false, ptrVec); + w.initialize(E_Trend_Window); + w.show(); + + app.exec(); + } + + kbd_service::CDpcdaForApp::releaseGlobalThread(); + + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/TrendCurves/plot/qcustomplot.cpp b/product/src/gui/plugin/TrendCurves/plot/qcustomplot.cpp index 9cafd22c..b23489a2 100644 --- a/product/src/gui/plugin/TrendCurves/plot/qcustomplot.cpp +++ b/product/src/gui/plugin/TrendCurves/plot/qcustomplot.cpp @@ -1,30463 +1,30463 @@ -/*************************************************************************** -** ** -** QCustomPlot, an easy to use, modern plotting widget for Qt ** -** Copyright (C) 2011-2017 Emanuel Eichhammer ** -** ** -** This program is free software: you can redistribute it and/or modify ** -** it under the terms of the GNU General Public License as published by ** -** the Free Software Foundation, either version 3 of the License, or ** -** (at your option) any later version. ** -** ** -** This program is distributed in the hope that it will be useful, ** -** but WITHOUT ANY WARRANTY; without even the implied warranty of ** -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** -** GNU General Public License for more details. ** -** ** -** You should have received a copy of the GNU General Public License ** -** along with this program. If not, see http://www.gnu.org/licenses/. ** -** ** -**************************************************************************** -** Author: Emanuel Eichhammer ** -** Website/Contact: http://www.qcustomplot.com/ ** -** Date: 04.09.17 ** -** Version: 2.0.0 ** -****************************************************************************/ - -#include "qcustomplot.h" -#include "../widgets/CToolTip.h" - -/* including file 'src/vector2d.cpp', size 7340 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPVector2D -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPVector2D - \brief Represents two doubles as a mathematical 2D vector - - This class acts as a replacement for QVector2D with the advantage of double precision instead of - single, and some convenience methods tailored for the QCustomPlot library. -*/ - -/* start documentation of inline functions */ - -/*! \fn void QCPVector2D::setX(double x) - - Sets the x coordinate of this vector to \a x. - - \see setY -*/ - -/*! \fn void QCPVector2D::setY(double y) - - Sets the y coordinate of this vector to \a y. - - \see setX -*/ - -/*! \fn double QCPVector2D::length() const - - Returns the length of this vector. - - \see lengthSquared -*/ - -/*! \fn double QCPVector2D::lengthSquared() const - - Returns the squared length of this vector. In some situations, e.g. when just trying to find the - shortest vector of a group, this is faster than calculating \ref length, because it avoids - calculation of a square root. - - \see length -*/ - -/*! \fn QPoint QCPVector2D::toPoint() const - - Returns a QPoint which has the x and y coordinates of this vector, truncating any floating point - information. - - \see toPointF -*/ - -/*! \fn QPointF QCPVector2D::toPointF() const - - Returns a QPointF which has the x and y coordinates of this vector. - - \see toPoint -*/ - -/*! \fn bool QCPVector2D::isNull() const - - Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y - coordinates, i.e. if both are binary equal to 0. -*/ - -/*! \fn QCPVector2D QCPVector2D::perpendicular() const - - Returns a vector perpendicular to this vector, with the same length. -*/ - -/*! \fn double QCPVector2D::dot() const - - Returns the dot/scalar product of this vector with the specified vector \a vec. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a QCPVector2D object and initializes the x and y coordinates to 0. -*/ -QCPVector2D::QCPVector2D() : - mX(0), - mY(0) -{ -} - -/*! - Creates a QCPVector2D object and initializes the \a x and \a y coordinates with the specified - values. -*/ -QCPVector2D::QCPVector2D(double x, double y) : - mX(x), - mY(y) -{ -} - -/*! - Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of - the specified \a point. -*/ -QCPVector2D::QCPVector2D(const QPoint &point) : - mX(point.x()), - mY(point.y()) -{ -} - -/*! - Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of - the specified \a point. -*/ -QCPVector2D::QCPVector2D(const QPointF &point) : - mX(point.x()), - mY(point.y()) -{ -} - -/*! - Normalizes this vector. After this operation, the length of the vector is equal to 1. - - \see normalized, length, lengthSquared -*/ -void QCPVector2D::normalize() -{ - double len = length(); - mX /= len; - mY /= len; -} - -/*! - Returns a normalized version of this vector. The length of the returned vector is equal to 1. - - \see normalize, length, lengthSquared -*/ -QCPVector2D QCPVector2D::normalized() const -{ - QCPVector2D result(mX, mY); - result.normalize(); - return result; -} - -/*! \overload - - Returns the squared shortest distance of this vector (interpreted as a point) to the finite line - segment given by \a start and \a end. - - \see distanceToStraightLine -*/ -double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const -{ - QCPVector2D v(end-start); - double vLengthSqr = v.lengthSquared(); - if (!qFuzzyIsNull(vLengthSqr)) - { - double mu = v.dot(*this-start)/vLengthSqr; - if (mu < 0) - return (*this-start).lengthSquared(); - else if (mu > 1) - return (*this-end).lengthSquared(); - else - return ((start + mu*v)-*this).lengthSquared(); - } else - return (*this-start).lengthSquared(); -} - -/*! \overload - - Returns the squared shortest distance of this vector (interpreted as a point) to the finite line - segment given by \a line. - - \see distanceToStraightLine -*/ -double QCPVector2D::distanceSquaredToLine(const QLineF &line) const -{ - return distanceSquaredToLine(QCPVector2D(line.p1()), QCPVector2D(line.p2())); -} - -/*! - Returns the shortest distance of this vector (interpreted as a point) to the infinite straight - line given by a \a base point and a \a direction vector. - - \see distanceSquaredToLine -*/ -double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const -{ - return qAbs((*this-base).dot(direction.perpendicular()))/direction.length(); -} - -/*! - Scales this vector by the given \a factor, i.e. the x and y components are multiplied by \a - factor. -*/ -QCPVector2D &QCPVector2D::operator*=(double factor) -{ - mX *= factor; - mY *= factor; - return *this; -} - -/*! - Scales this vector by the given \a divisor, i.e. the x and y components are divided by \a - divisor. -*/ -QCPVector2D &QCPVector2D::operator/=(double divisor) -{ - mX /= divisor; - mY /= divisor; - return *this; -} - -/*! - Adds the given \a vector to this vector component-wise. -*/ -QCPVector2D &QCPVector2D::operator+=(const QCPVector2D &vector) -{ - mX += vector.mX; - mY += vector.mY; - return *this; -} - -/*! - subtracts the given \a vector from this vector component-wise. -*/ -QCPVector2D &QCPVector2D::operator-=(const QCPVector2D &vector) -{ - mX -= vector.mX; - mY -= vector.mY; - return *this; -} -/* end of 'src/vector2d.cpp' */ - - -/* including file 'src/painter.cpp', size 8670 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPainter -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPainter - \brief QPainter subclass used internally - - This QPainter subclass is used to provide some extended functionality e.g. for tweaking position - consistency between antialiased and non-antialiased painting. Further it provides workarounds - for QPainter quirks. - - \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and - restore. So while it is possible to pass a QCPPainter instance to a function that expects a - QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because - it will call the base class implementations of the functions actually hidden by QCPPainter). -*/ - -/*! - Creates a new QCPPainter instance and sets default values -*/ -QCPPainter::QCPPainter() : - QPainter(), - mModes(pmDefault), - mIsAntialiasing(false) -{ - // don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and - // a call to begin() will follow -} - -/*! - Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just - like the analogous QPainter constructor, begins painting on \a device immediately. - - Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. -*/ -QCPPainter::QCPPainter(QPaintDevice *device) : - QPainter(device), - mModes(pmDefault), - mIsAntialiasing(false) -{ -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. - if (isActive()) - setRenderHint(QPainter::NonCosmeticDefaultPen); -#endif -} - -/*! - Sets the pen of the painter and applies certain fixes to it, depending on the mode of this - QCPPainter. - - \note this function hides the non-virtual base class implementation. -*/ -void QCPPainter::setPen(const QPen &pen) -{ - QPainter::setPen(pen); - if (mModes.testFlag(pmNonCosmetic)) - makeNonCosmetic(); -} - -/*! \overload - - Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of - this QCPPainter. - - \note this function hides the non-virtual base class implementation. -*/ -void QCPPainter::setPen(const QColor &color) -{ - QPainter::setPen(color); - if (mModes.testFlag(pmNonCosmetic)) - makeNonCosmetic(); -} - -/*! \overload - - Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of - this QCPPainter. - - \note this function hides the non-virtual base class implementation. -*/ -void QCPPainter::setPen(Qt::PenStyle penStyle) -{ - QPainter::setPen(penStyle); - if (mModes.testFlag(pmNonCosmetic)) - makeNonCosmetic(); -} - -/*! \overload - - Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when - antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to - integer coordinates and then passes it to the original drawLine. - - \note this function hides the non-virtual base class implementation. -*/ -void QCPPainter::drawLine(const QLineF &line) -{ - if (mIsAntialiasing || mModes.testFlag(pmVectorized)) - QPainter::drawLine(line); - else - QPainter::drawLine(line.toLine()); -} - -/*! - Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint - with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between - antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for - AA/Non-AA painting). -*/ -void QCPPainter::setAntialiasing(bool enabled) -{ - setRenderHint(QPainter::Antialiasing, enabled); - if (mIsAntialiasing != enabled) - { - mIsAntialiasing = enabled; - if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs - { - if (mIsAntialiasing) - translate(0.5, 0.5); - else - translate(-0.5, -0.5); - } - } -} - -/*! - Sets the mode of the painter. This controls whether the painter shall adjust its - fixes/workarounds optimized for certain output devices. -*/ -void QCPPainter::setModes(QCPPainter::PainterModes modes) -{ - mModes = modes; -} - -/*! - Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a - device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, - all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that - behaviour. - - The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets - the render hint as appropriate. - - \note this function hides the non-virtual base class implementation. -*/ -bool QCPPainter::begin(QPaintDevice *device) -{ - bool result = QPainter::begin(device); -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. - if (result) - setRenderHint(QPainter::NonCosmeticDefaultPen); -#endif - return result; -} - -/*! \overload - - Sets the mode of the painter. This controls whether the painter shall adjust its - fixes/workarounds optimized for certain output devices. -*/ -void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) -{ - if (!enabled && mModes.testFlag(mode)) - mModes &= ~mode; - else if (enabled && !mModes.testFlag(mode)) - mModes |= mode; -} - -/*! - Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to - QPainter, the save/restore functions are reimplemented to also save/restore those members. - - \note this function hides the non-virtual base class implementation. - - \see restore -*/ -void QCPPainter::save() -{ - mAntialiasingStack.push(mIsAntialiasing); - QPainter::save(); -} - -/*! - Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to - QPainter, the save/restore functions are reimplemented to also save/restore those members. - - \note this function hides the non-virtual base class implementation. - - \see save -*/ -void QCPPainter::restore() -{ - if (!mAntialiasingStack.isEmpty()) - mIsAntialiasing = mAntialiasingStack.pop(); - else - qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; - QPainter::restore(); -} - -/*! - Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen - overrides when the \ref pmNonCosmetic mode is set. -*/ -void QCPPainter::makeNonCosmetic() -{ - if (qFuzzyIsNull(pen().widthF())) - { - QPen p = pen(); - p.setWidth(1); - QPainter::setPen(p); - } -} -/* end of 'src/painter.cpp' */ - - -/* including file 'src/paintbuffer.cpp', size 18502 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractPaintBuffer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractPaintBuffer - \brief The abstract base class for paint buffers, which define the rendering backend - - This abstract base class defines the basic interface that a paint buffer needs to provide in - order to be usable by QCustomPlot. - - A paint buffer manages both a surface to draw onto, and the matching paint device. The size of - the surface can be changed via \ref setSize. External classes (\ref QCustomPlot and \ref - QCPLayer) request a painter via \ref startPainting and then perform the draw calls. Once the - painting is complete, \ref donePainting is called, so the paint buffer implementation can do - clean up if necessary. Before rendering a frame, each paint buffer is usually filled with a color - using \ref clear (usually the color is \c Qt::transparent), to remove the contents of the - previous frame. - - The simplest paint buffer implementation is \ref QCPPaintBufferPixmap which allows regular - software rendering via the raster engine. Hardware accelerated rendering via pixel buffers and - frame buffer objects is provided by \ref QCPPaintBufferGlPbuffer and \ref QCPPaintBufferGlFbo. - They are used automatically if \ref QCustomPlot::setOpenGl is enabled. -*/ - -/* start documentation of pure virtual functions */ - -/*! \fn virtual QCPPainter *QCPAbstractPaintBuffer::startPainting() = 0 - - Returns a \ref QCPPainter which is ready to draw to this buffer. The ownership and thus the - responsibility to delete the painter after the painting operations are complete is given to the - caller of this method. - - Once you are done using the painter, delete the painter and call \ref donePainting. - - While a painter generated with this method is active, you must not call \ref setSize, \ref - setDevicePixelRatio or \ref clear. - - This method may return 0, if a painter couldn't be activated on the buffer. This usually - indicates a problem with the respective painting backend. -*/ - -/*! \fn virtual void QCPAbstractPaintBuffer::draw(QCPPainter *painter) const = 0 - - Draws the contents of this buffer with the provided \a painter. This is the method that is used - to finally join all paint buffers and draw them onto the screen. -*/ - -/*! \fn virtual void QCPAbstractPaintBuffer::clear(const QColor &color) = 0 - - Fills the entire buffer with the provided \a color. To have an empty transparent buffer, use the - named color \c Qt::transparent. - - This method must not be called if there is currently a painter (acquired with \ref startPainting) - active. -*/ - -/*! \fn virtual void QCPAbstractPaintBuffer::reallocateBuffer() = 0 - - Reallocates the internal buffer with the currently configured size (\ref setSize) and device - pixel ratio, if applicable (\ref setDevicePixelRatio). It is called as soon as any of those - properties are changed on this paint buffer. - - \note Subclasses of \ref QCPAbstractPaintBuffer must call their reimplementation of this method - in their constructor, to perform the first allocation (this can not be done by the base class - because calling pure virtual methods in base class constructors is not possible). -*/ - -/* end documentation of pure virtual functions */ -/* start documentation of inline functions */ - -/*! \fn virtual void QCPAbstractPaintBuffer::donePainting() - - If you have acquired a \ref QCPPainter to paint onto this paint buffer via \ref startPainting, - call this method as soon as you are done with the painting operations and have deleted the - painter. - - paint buffer subclasses may use this method to perform any type of cleanup that is necessary. The - default implementation does nothing. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a paint buffer and initializes it with the provided \a size and \a devicePixelRatio. - - Subclasses must call their \ref reallocateBuffer implementation in their respective constructors. -*/ -QCPAbstractPaintBuffer::QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio) : - mSize(size), - mDevicePixelRatio(devicePixelRatio), - mInvalidated(true) -{ -} - -QCPAbstractPaintBuffer::~QCPAbstractPaintBuffer() -{ -} - -/*! - Sets the paint buffer size. - - The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained - by \ref startPainting are invalidated and must not be used after calling this method. - - If \a size is already the current buffer size, this method does nothing. -*/ -void QCPAbstractPaintBuffer::setSize(const QSize &size) -{ - if (mSize != size) - { - mSize = size; - reallocateBuffer(); - } -} - -/*! - Sets the invalidated flag to \a invalidated. - - This mechanism is used internally in conjunction with isolated replotting of \ref QCPLayer - instances (in \ref QCPLayer::lmBuffered mode). If \ref QCPLayer::replot is called on a buffered - layer, i.e. an isolated repaint of only that layer (and its dedicated paint buffer) is requested, - QCustomPlot will decide depending on the invalidated flags of other paint buffers whether it also - replots them, instead of only the layer on which the replot was called. - - The invalidated flag is set to true when \ref QCPLayer association has changed, i.e. if layers - were added or removed from this buffer, or if they were reordered. It is set to false as soon as - all associated \ref QCPLayer instances are drawn onto the buffer. - - Under normal circumstances, it is not necessary to manually call this method. -*/ -void QCPAbstractPaintBuffer::setInvalidated(bool invalidated) -{ - mInvalidated = invalidated; -} - -/*! - Sets the the device pixel ratio to \a ratio. This is useful to render on high-DPI output devices. - The ratio is automatically set to the device pixel ratio used by the parent QCustomPlot instance. - - The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained - by \ref startPainting are invalidated and must not be used after calling this method. - - \note This method is only available for Qt versions 5.4 and higher. -*/ -void QCPAbstractPaintBuffer::setDevicePixelRatio(double ratio) -{ - if (!qFuzzyCompare(ratio, mDevicePixelRatio)) - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mDevicePixelRatio = ratio; - reallocateBuffer(); -#else - qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; - mDevicePixelRatio = 1.0; -#endif - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPaintBufferPixmap -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPaintBufferPixmap - \brief A paint buffer based on QPixmap, using software raster rendering - - This paint buffer is the default and fall-back paint buffer which uses software rendering and - QPixmap as internal buffer. It is used if \ref QCustomPlot::setOpenGl is false. -*/ - -/*! - Creates a pixmap paint buffer instancen with the specified \a size and \a devicePixelRatio, if - applicable. -*/ -QCPPaintBufferPixmap::QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio) : - QCPAbstractPaintBuffer(size, devicePixelRatio) -{ - QCPPaintBufferPixmap::reallocateBuffer(); -} - -QCPPaintBufferPixmap::~QCPPaintBufferPixmap() -{ -} - -/* inherits documentation from base class */ -QCPPainter *QCPPaintBufferPixmap::startPainting() -{ - QCPPainter *result = new QCPPainter(&mBuffer); - result->setRenderHint(QPainter::HighQualityAntialiasing); - return result; -} - -/* inherits documentation from base class */ -void QCPPaintBufferPixmap::draw(QCPPainter *painter) const -{ - if (painter && painter->isActive()) - painter->drawPixmap(0, 0, mBuffer); - else - qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; -} - -/* inherits documentation from base class */ -void QCPPaintBufferPixmap::clear(const QColor &color) -{ - mBuffer.fill(color); -} - -/* inherits documentation from base class */ -void QCPPaintBufferPixmap::reallocateBuffer() -{ - setInvalidated(); - if (!qFuzzyCompare(1.0, mDevicePixelRatio)) - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mBuffer = QPixmap(mSize*mDevicePixelRatio); - mBuffer.setDevicePixelRatio(mDevicePixelRatio); -#else - qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; - mDevicePixelRatio = 1.0; - mBuffer = QPixmap(mSize); -#endif - } else - { - mBuffer = QPixmap(mSize); - } -} - - -#ifdef QCP_OPENGL_PBUFFER -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPaintBufferGlPbuffer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPaintBufferGlPbuffer - \brief A paint buffer based on OpenGL pixel buffers, using hardware accelerated rendering - - This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot - rendering. It is based on OpenGL pixel buffers (pbuffer) and is used in Qt versions before 5.0. - (See \ref QCPPaintBufferGlFbo used in newer Qt versions.) - - The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are - supported by the system. -*/ - -/*! - Creates a \ref QCPPaintBufferGlPbuffer instance with the specified \a size and \a - devicePixelRatio, if applicable. - - The parameter \a multisamples defines how many samples are used per pixel. Higher values thus - result in higher quality antialiasing. If the specified \a multisamples value exceeds the - capability of the graphics hardware, the highest supported multisampling is used. -*/ -QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples) : - QCPAbstractPaintBuffer(size, devicePixelRatio), - mGlPBuffer(0), - mMultisamples(qMax(0, multisamples)) -{ - QCPPaintBufferGlPbuffer::reallocateBuffer(); -} - -QCPPaintBufferGlPbuffer::~QCPPaintBufferGlPbuffer() -{ - if (mGlPBuffer) - delete mGlPBuffer; -} - -/* inherits documentation from base class */ -QCPPainter *QCPPaintBufferGlPbuffer::startPainting() -{ - if (!mGlPBuffer->isValid()) - { - qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; - return 0; - } - - QCPPainter *result = new QCPPainter(mGlPBuffer); - result->setRenderHint(QPainter::HighQualityAntialiasing); - return result; -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlPbuffer::draw(QCPPainter *painter) const -{ - if (!painter || !painter->isActive()) - { - qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; - return; - } - if (!mGlPBuffer->isValid()) - { - qDebug() << Q_FUNC_INFO << "OpenGL pbuffer isn't valid, reallocateBuffer was not called?"; - return; - } - painter->drawImage(0, 0, mGlPBuffer->toImage()); -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlPbuffer::clear(const QColor &color) -{ - if (mGlPBuffer->isValid()) - { - mGlPBuffer->makeCurrent(); - glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - mGlPBuffer->doneCurrent(); - } else - qDebug() << Q_FUNC_INFO << "OpenGL pbuffer invalid or context not current"; -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlPbuffer::reallocateBuffer() -{ - if (mGlPBuffer) - delete mGlPBuffer; - - QGLFormat format; - format.setAlpha(true); - format.setSamples(mMultisamples); - mGlPBuffer = new QGLPixelBuffer(mSize, format); -} -#endif // QCP_OPENGL_PBUFFER - - -#ifdef QCP_OPENGL_FBO -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPaintBufferGlFbo -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPaintBufferGlFbo - \brief A paint buffer based on OpenGL frame buffers objects, using hardware accelerated rendering - - This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot - rendering. It is based on OpenGL frame buffer objects (fbo) and is used in Qt versions 5.0 and - higher. (See \ref QCPPaintBufferGlPbuffer used in older Qt versions.) - - The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are - supported by the system. -*/ - -/*! - Creates a \ref QCPPaintBufferGlFbo instance with the specified \a size and \a devicePixelRatio, - if applicable. - - All frame buffer objects shall share one OpenGL context and paint device, which need to be set up - externally and passed via \a glContext and \a glPaintDevice. The set-up is done in \ref - QCustomPlot::setupOpenGl and the context and paint device are managed by the parent QCustomPlot - instance. -*/ -QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice) : - QCPAbstractPaintBuffer(size, devicePixelRatio), - mGlContext(glContext), - mGlPaintDevice(glPaintDevice), - mGlFrameBuffer(0) -{ - QCPPaintBufferGlFbo::reallocateBuffer(); -} - -QCPPaintBufferGlFbo::~QCPPaintBufferGlFbo() -{ - if (mGlFrameBuffer) - delete mGlFrameBuffer; -} - -/* inherits documentation from base class */ -QCPPainter *QCPPaintBufferGlFbo::startPainting() -{ - if (mGlPaintDevice.isNull()) - { - qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; - return 0; - } - if (!mGlFrameBuffer) - { - qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; - return 0; - } - - if (QOpenGLContext::currentContext() != mGlContext.data()) - mGlContext.data()->makeCurrent(mGlContext.data()->surface()); - mGlFrameBuffer->bind(); - QCPPainter *result = new QCPPainter(mGlPaintDevice.data()); - result->setRenderHint(QPainter::HighQualityAntialiasing); - return result; -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlFbo::donePainting() -{ - if (mGlFrameBuffer && mGlFrameBuffer->isBound()) - mGlFrameBuffer->release(); - else - qDebug() << Q_FUNC_INFO << "Either OpenGL frame buffer not valid or was not bound"; -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlFbo::draw(QCPPainter *painter) const -{ - if (!painter || !painter->isActive()) - { - qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; - return; - } - if (!mGlFrameBuffer) - { - qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; - return; - } - painter->drawImage(0, 0, mGlFrameBuffer->toImage()); -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlFbo::clear(const QColor &color) -{ - if (mGlContext.isNull()) - { - qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; - return; - } - if (!mGlFrameBuffer) - { - qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; - return; - } - - if (QOpenGLContext::currentContext() != mGlContext.data()) - mGlContext.data()->makeCurrent(mGlContext.data()->surface()); - mGlFrameBuffer->bind(); - glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - mGlFrameBuffer->release(); -} - -/* inherits documentation from base class */ -void QCPPaintBufferGlFbo::reallocateBuffer() -{ - // release and delete possibly existing framebuffer: - if (mGlFrameBuffer) - { - if (mGlFrameBuffer->isBound()) - mGlFrameBuffer->release(); - delete mGlFrameBuffer; - mGlFrameBuffer = 0; - } - - if (mGlContext.isNull()) - { - qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; - return; - } - if (mGlPaintDevice.isNull()) - { - qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; - return; - } - - // create new fbo with appropriate size: - mGlContext.data()->makeCurrent(mGlContext.data()->surface()); - QOpenGLFramebufferObjectFormat frameBufferFormat; - frameBufferFormat.setSamples(mGlContext.data()->format().samples()); - frameBufferFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - mGlFrameBuffer = new QOpenGLFramebufferObject(mSize*mDevicePixelRatio, frameBufferFormat); - if (mGlPaintDevice.data()->size() != mSize*mDevicePixelRatio) - mGlPaintDevice.data()->setSize(mSize*mDevicePixelRatio); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mGlPaintDevice.data()->setDevicePixelRatio(mDevicePixelRatio); -#endif -} -#endif // QCP_OPENGL_FBO -/* end of 'src/paintbuffer.cpp' */ - - -/* including file 'src/layer.cpp', size 37064 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayer - \brief A layer that may contain objects, to control the rendering order - - The Layering system of QCustomPlot is the mechanism to control the rendering order of the - elements inside the plot. - - It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of - one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, - QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers - bottom to top and successively draws the layerables of the layers into the paint buffer(s). - - A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base - class from which almost all visible objects derive, like axes, grids, graphs, items, etc. - - \section qcplayer-defaultlayers Default layers - - Initially, QCustomPlot has six layers: "background", "grid", "main", "axes", "legend" and - "overlay" (in that order). On top is the "overlay" layer, which only contains the QCustomPlot's - selection rect (\ref QCustomPlot::selectionRect). The next two layers "axes" and "legend" contain - the default axes and legend, so they will be drawn above plottables. In the middle, there is the - "main" layer. It is initially empty and set as the current layer (see - QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. are created on this - layer by default. Then comes the "grid" layer which contains the QCPGrid instances (which belong - tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background shall be drawn behind - everything else, thus the default QCPAxisRect instance is placed on the "background" layer. Of - course, the layer affiliation of the individual objects can be changed as required (\ref - QCPLayerable::setLayer). - - \section qcplayer-ordering Controlling the rendering order via layers - - Controlling the ordering of layerables in the plot is easy: Create a new layer in the position - you want the layerable to be in, e.g. above "main", with \ref QCustomPlot::addLayer. Then set the - current layer with \ref QCustomPlot::setCurrentLayer to that new layer and finally create the - objects normally. They will be placed on the new layer automatically, due to the current layer - setting. Alternatively you could have also ignored the current layer setting and just moved the - objects with \ref QCPLayerable::setLayer to the desired layer after creating them. - - It is also possible to move whole layers. For example, If you want the grid to be shown in front - of all plottables/items on the "main" layer, just move it above "main" with - QCustomPlot::moveLayer. - - The rendering order within one layer is simply by order of creation or insertion. The item - created last (or added last to the layer), is drawn on top of all other objects on that layer. - - When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below - the deleted layer, see QCustomPlot::removeLayer. - - \section qcplayer-buffering Replotting only a specific layer - - If the layer mode (\ref setMode) is set to \ref lmBuffered, you can replot only this specific - layer by calling \ref replot. In certain situations this can provide better replot performance, - compared with a full replot of all layers. Upon creation of a new layer, the layer mode is - initialized to \ref lmLogical. The only layer that is set to \ref lmBuffered in a new \ref - QCustomPlot instance is the "overlay" layer, containing the selection rect. -*/ - -/* start documentation of inline functions */ - -/*! \fn QList QCPLayer::children() const - - Returns a list of all layerables on this layer. The order corresponds to the rendering order: - layerables with higher indices are drawn above layerables with lower indices. -*/ - -/*! \fn int QCPLayer::index() const - - Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be - accessed via \ref QCustomPlot::layer. - - Layers with higher indices will be drawn above layers with lower indices. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPLayer instance. - - Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. - - \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. - This check is only performed by \ref QCustomPlot::addLayer. -*/ -QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : - QObject(parentPlot), - mParentPlot(parentPlot), - mName(layerName), - mIndex(-1), // will be set to a proper value by the QCustomPlot layer creation function - mVisible(true), - mMode(lmLogical) -{ - // Note: no need to make sure layerName is unique, because layer - // management is done with QCustomPlot functions. -} - -QCPLayer::~QCPLayer() -{ - // If child layerables are still on this layer, detach them, so they don't try to reach back to this - // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted - // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to - // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) - - while (!mChildren.isEmpty()) - mChildren.last()->setLayer(0); // removes itself from mChildren via removeChild() - - if (mParentPlot->currentLayer() == this) - qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand."; -} - -/*! - Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this - layer will be invisible. - - This function doesn't change the visibility property of the layerables (\ref - QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the - visibility of the parent layer into account. -*/ -void QCPLayer::setVisible(bool visible) -{ - mVisible = visible; -} - -/*! - Sets the rendering mode of this layer. - - If \a mode is set to \ref lmBuffered for a layer, it will be given a dedicated paint buffer by - the parent QCustomPlot instance. This means it may be replotted individually by calling \ref - QCPLayer::replot, without needing to replot all other layers. - - Layers which are set to \ref lmLogical (the default) are used only to define the rendering order - and can't be replotted individually. - - Note that each layer which is set to \ref lmBuffered requires additional paint buffers for the - layers below, above and for the layer itself. This increases the memory consumption and - (slightly) decreases the repainting speed because multiple paint buffers need to be joined. So - you should carefully choose which layers benefit from having their own paint buffer. A typical - example would be a layer which contains certain layerables (e.g. items) that need to be changed - and thus replotted regularly, while all other layerables on other layers stay static. By default, - only the topmost layer called "overlay" is in mode \ref lmBuffered, and contains the selection - rect. - - \see replot -*/ -void QCPLayer::setMode(QCPLayer::LayerMode mode) -{ - if (mMode != mode) - { - mMode = mode; - if (!mPaintBuffer.isNull()) - mPaintBuffer.data()->setInvalidated(); - } -} - -/*! \internal - - Draws the contents of this layer with the provided \a painter. - - \see replot, drawToPaintBuffer -*/ -void QCPLayer::draw(QCPPainter *painter) -{ - foreach (QCPLayerable *child, mChildren) - { - if (child->realVisibility()) - { - painter->save(); - painter->setClipRect(child->clipRect().translated(0, -1)); - child->applyDefaultAntialiasingHint(painter); - child->draw(painter); - painter->restore(); - } - } -} - -/*! \internal - - Draws the contents of this layer into the paint buffer which is associated with this layer. The - association is established by the parent QCustomPlot, which manages all paint buffers (see \ref - QCustomPlot::setupPaintBuffers). - - \see draw -*/ -void QCPLayer::drawToPaintBuffer() -{ - if (!mPaintBuffer.isNull()) - { - if (QCPPainter *painter = mPaintBuffer.data()->startPainting()) - { - if (painter->isActive()) - draw(painter); - else - qDebug() << Q_FUNC_INFO << "paint buffer returned inactive painter"; - delete painter; - mPaintBuffer.data()->donePainting(); - } else - qDebug() << Q_FUNC_INFO << "paint buffer returned zero painter"; - } else - qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; -} - -/*! - If the layer mode (\ref setMode) is set to \ref lmBuffered, this method allows replotting only - the layerables on this specific layer, without the need to replot all other layers (as a call to - \ref QCustomPlot::replot would do). - - If the layer mode is \ref lmLogical however, this method simply calls \ref QCustomPlot::replot on - the parent QCustomPlot instance. - - QCustomPlot also makes sure to replot all layers instead of only this one, if the layer ordering - has changed since the last full replot and the other paint buffers were thus invalidated. - - \see draw -*/ -void QCPLayer::replot() -{ - if (mMode == lmBuffered && !mParentPlot->hasInvalidatedPaintBuffers()) - { - if (!mPaintBuffer.isNull()) - { - mPaintBuffer.data()->clear(Qt::transparent); - drawToPaintBuffer(); - mPaintBuffer.data()->setInvalidated(false); - mParentPlot->update(); - } else - qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; - } else if (mMode == lmLogical) - mParentPlot->replot(); -} - -/*! \internal - - Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will - be prepended to the list, i.e. be drawn beneath the other layerables already in the list. - - This function does not change the \a mLayer member of \a layerable to this layer. (Use - QCPLayerable::setLayer to change the layer of an object, not this function.) - - \see removeChild -*/ -void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) -{ - if (!mChildren.contains(layerable)) - { - if (prepend) - mChildren.prepend(layerable); - else - mChildren.append(layerable); - if (!mPaintBuffer.isNull()) - mPaintBuffer.data()->setInvalidated(); - } else - qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); -} - -/*! \internal - - Removes the \a layerable from the list of this layer. - - This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer - to change the layer of an object, not this function.) - - \see addChild -*/ -void QCPLayer::removeChild(QCPLayerable *layerable) -{ - if (mChildren.removeOne(layerable)) - { - if (!mPaintBuffer.isNull()) - mPaintBuffer.data()->setInvalidated(); - } else - qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayerable -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayerable - \brief Base class for all drawable objects - - This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid - etc. - - Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking - the layers accordingly. - - For details about the layering mechanism, see the QCPLayer documentation. -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPLayerable *QCPLayerable::parentLayerable() const - - Returns the parent layerable of this layerable. The parent layerable is used to provide - visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables - only get drawn if their parent layerables are visible, too. - - Note that a parent layerable is not necessarily also the QObject parent for memory management. - Further, a layerable doesn't always have a parent layerable, so this function may return 0. - - A parent layerable is set implicitly when placed inside layout elements and doesn't need to be - set manually by the user. -*/ - -/* end documentation of inline functions */ -/* start documentation of pure virtual functions */ - -/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 - \internal - - This function applies the default antialiasing setting to the specified \a painter, using the - function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when - \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing - setting may be specified individually, this function should set the antialiasing state of the - most prominent entity. In this case however, the \ref draw function usually calls the specialized - versions of this function before drawing each entity, effectively overriding the setting of the - default antialiasing hint. - - First example: QCPGraph has multiple entities that have an antialiasing setting: The graph - line, fills and scatters. Those can be configured via QCPGraph::setAntialiased, - QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only - the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's - antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and - QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw - calls the respective specialized applyAntialiasingHint function. - - Second example: QCPItemLine consists only of a line so there is only one antialiasing - setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by - all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the - respective layerable subclass.) Consequently it only has the normal - QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to - care about setting any antialiasing states, because the default antialiasing hint is already set - on the painter when the \ref draw function is called, and that's the state it wants to draw the - line with. -*/ - -/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 - \internal - - This function draws the layerable with the specified \a painter. It is only called by - QCustomPlot, if the layerable is visible (\ref setVisible). - - Before this function is called, the painter's antialiasing state is set via \ref - applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was - set to \ref clipRect. -*/ - -/* end documentation of pure virtual functions */ -/* start documentation of signals */ - -/*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); - - This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to - a different layer. - - \see setLayer -*/ - -/* end documentation of signals */ - -/*! - Creates a new QCPLayerable instance. - - Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the - derived classes. - - If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a - targetLayer is an empty string, it places itself on the current layer of the plot (see \ref - QCustomPlot::setCurrentLayer). - - It is possible to provide 0 as \a plot. In that case, you should assign a parent plot at a later - time with \ref initializeParentPlot. - - The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable - parents are mainly used to control visibility in a hierarchy of layerables. This means a - layerable is only drawn, if all its ancestor layerables are also visible. Note that \a - parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a - plot does. It is not uncommon to set the QObject-parent to something else in the constructors of - QCPLayerable subclasses, to guarantee a working destruction hierarchy. -*/ -QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) : - QObject(plot), - mVisible(true), - mParentPlot(plot), - mParentLayerable(parentLayerable), - mLayer(0), - mAntialiased(true) -{ - if (mParentPlot) - { - if (targetLayer.isEmpty()) - setLayer(mParentPlot->currentLayer()); - else if (!setLayer(targetLayer)) - qDebug() << Q_FUNC_INFO << "setting QCPlayerable initial layer to" << targetLayer << "failed."; - } -} - -QCPLayerable::~QCPLayerable() -{ - if (mLayer) - { - mLayer->removeChild(this); - mLayer = 0; - } -} - -/*! - Sets the visibility of this layerable object. If an object is not visible, it will not be drawn - on the QCustomPlot surface, and user interaction with it (e.g. click and selection) is not - possible. -*/ -void QCPLayerable::setVisible(bool on) -{ - mVisible = on; -} - -/*! - Sets the \a layer of this layerable object. The object will be placed on top of the other objects - already on \a layer. - - If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or - interact/receive events). - - Returns true if the layer of this layerable was successfully changed to \a layer. -*/ -bool QCPLayerable::setLayer(QCPLayer *layer) -{ - return moveToLayer(layer, false); -} - -/*! \overload - Sets the layer of this layerable object by name - - Returns true on success, i.e. if \a layerName is a valid layer name. -*/ -bool QCPLayerable::setLayer(const QString &layerName) -{ - if (!mParentPlot) - { - qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; - return false; - } - if (QCPLayer *layer = mParentPlot->layer(layerName)) - { - return setLayer(layer); - } else - { - qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; - return false; - } -} - -/*! - Sets whether this object will be drawn antialiased or not. - - Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and - QCustomPlot::setNotAntialiasedElements. -*/ -void QCPLayerable::setAntialiased(bool enabled) -{ - mAntialiased = enabled; -} - -/*! - Returns whether this layerable is visible, taking the visibility of the layerable parent and the - visibility of this layerable's layer into account. This is the method that is consulted to decide - whether a layerable shall be drawn or not. - - If this layerable has a direct layerable parent (usually set via hierarchies implemented in - subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this - layerable has its visibility set to true and the parent layerable's \ref realVisibility returns - true. -*/ -bool QCPLayerable::realVisibility() const -{ - return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility()); -} - -/*! - This function is used to decide whether a click hits a layerable object or not. - - \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the - shortest pixel distance of this point to the object. If the object is either invisible or the - distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the - object is not selectable, -1.0 is returned, too. - - If the object is represented not by single lines but by an area like a \ref QCPItemText or the - bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In - these cases this function thus returns a constant value greater zero but still below the parent - plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). - - Providing a constant value for area objects allows selecting line objects even when they are - obscured by such area objects, by clicking close to the lines (i.e. closer than - 0.99*selectionTolerance). - - The actual setting of the selection state is not done by this function. This is handled by the - parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified - via the \ref selectEvent/\ref deselectEvent methods. - - \a details is an optional output parameter. Every layerable subclass may place any information - in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot - decides on the basis of this selectTest call, that the object was successfully selected. The - subsequent call to \ref selectEvent will carry the \a details. This is useful for multi-part - objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked - is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be - placed in \a details. So in the subsequent \ref selectEvent, the decision which part was - selected doesn't have to be done a second time for a single selection operation. - - You may pass 0 as \a details to indicate that you are not interested in those selection details. - - \see selectEvent, deselectEvent, mousePressEvent, wheelEvent, QCustomPlot::setInteractions -*/ -double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(pos) - Q_UNUSED(onlySelectable) - Q_UNUSED(details) - return -1.0; -} - -/*! \internal - - Sets the parent plot of this layerable. Use this function once to set the parent plot if you have - passed 0 in the constructor. It can not be used to move a layerable from one QCustomPlot to - another one. - - Note that, unlike when passing a non-null parent plot in the constructor, this function does not - make \a parentPlot the QObject-parent of this layerable. If you want this, call - QObject::setParent(\a parentPlot) in addition to this function. - - Further, you will probably want to set a layer (\ref setLayer) after calling this function, to - make the layerable appear on the QCustomPlot. - - The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized - so they can react accordingly (e.g. also initialize the parent plot of child layerables, like - QCPLayout does). -*/ -void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) -{ - if (mParentPlot) - { - qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; - return; - } - - if (!parentPlot) - qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; - - mParentPlot = parentPlot; - parentPlotInitialized(mParentPlot); -} - -/*! \internal - - Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not - become the QObject-parent (for memory management) of this layerable. - - The parent layerable has influence on the return value of the \ref realVisibility method. Only - layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be - drawn. - - \see realVisibility -*/ -void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) -{ - mParentLayerable = parentLayerable; -} - -/*! \internal - - Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to - the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is - false, the object will be appended. - - Returns true on success, i.e. if \a layer is a valid layer. -*/ -bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) -{ - if (layer && !mParentPlot) - { - qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; - return false; - } - if (layer && layer->parentPlot() != mParentPlot) - { - qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; - return false; - } - - QCPLayer *oldLayer = mLayer; - if (mLayer) - mLayer->removeChild(this); - mLayer = layer; - if (mLayer) - mLayer->addChild(this, prepend); - if (mLayer != oldLayer) - emit layerChanged(mLayer); - return true; -} - -/*! \internal - - Sets the QCPainter::setAntialiasing state on the provided \a painter, depending on the \a - localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is - controlled via \a overrideElement. -*/ -void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const -{ - if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) - painter->setAntialiasing(false); - else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) - painter->setAntialiasing(true); - else - painter->setAntialiasing(localAntialiased); -} - -/*! \internal - - This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting - of a parent plot. This is the case when 0 was passed as parent plot in the constructor, and the - parent plot is set at a later time. - - For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any - QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level - element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To - propagate the parent plot to all the children of the hierarchy, the top level element then uses - this function to pass the parent plot on to its child elements. - - The default implementation does nothing. - - \see initializeParentPlot -*/ -void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) -{ - Q_UNUSED(parentPlot) -} - -/*! \internal - - Returns the selection category this layerable shall belong to. The selection category is used in - conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and - which aren't. - - Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref - QCP::iSelectOther. This is what the default implementation returns. - - \see QCustomPlot::setInteractions -*/ -QCP::Interaction QCPLayerable::selectionCategory() const -{ - return QCP::iSelectOther; -} - -/*! \internal - - Returns the clipping rectangle of this layerable object. By default, this is the viewport of the - parent QCustomPlot. Specific subclasses may reimplement this function to provide different - clipping rects. - - The returned clipping rect is set on the painter before the draw function of the respective - object is called. -*/ -QRect QCPLayerable::clipRect() const -{ - if (mParentPlot) - return mParentPlot->viewport(); - else - return QRect(); -} - -/*! \internal - - This event is called when the layerable shall be selected, as a consequence of a click by the - user. Subclasses should react to it by setting their selection state appropriately. The default - implementation does nothing. - - \a event is the mouse event that caused the selection. \a additive indicates, whether the user - was holding the multi-select-modifier while performing the selection (see \ref - QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled - (i.e. become selected when unselected and unselected when selected). - - Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. - returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). - The \a details data you output from \ref selectTest is fed back via \a details here. You may - use it to transport any kind of information from the selectTest to the possibly subsequent - selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable - that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need - to do the calculation again to find out which part was actually clicked. - - \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must - set the value either to true or false, depending on whether the selection state of this layerable - was actually changed. For layerables that only are selectable as a whole and not in parts, this - is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the - selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the - layerable was previously unselected and now is switched to the selected state. - - \see selectTest, deselectEvent -*/ -void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - Q_UNUSED(additive) - Q_UNUSED(details) - Q_UNUSED(selectionStateChanged) -} - -/*! \internal - - This event is called when the layerable shall be deselected, either as consequence of a user - interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by - unsetting their selection appropriately. - - just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must - return true or false when the selection state of this layerable has changed or not changed, - respectively. - - \see selectTest, selectEvent -*/ -void QCPLayerable::deselectEvent(bool *selectionStateChanged) -{ - Q_UNUSED(selectionStateChanged) -} - -/*! - This event gets called when the user presses a mouse button while the cursor is over the - layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref - selectTest. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). The parameter \a details contains layerable-specific details about the hit, which - were generated in the previous call to \ref selectTest. For example, One-dimensional plottables - like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as - \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c - SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). - - QCustomPlot uses an event propagation system that works the same as Qt's system. If your - layerable doesn't reimplement the \ref mousePressEvent or explicitly calls \c event->ignore() in - its reimplementation, the event will be propagated to the next layerable in the stacking order. - - Once a layerable has accepted the \ref mousePressEvent, it is considered the mouse grabber and - will receive all following calls to \ref mouseMoveEvent or \ref mouseReleaseEvent for this mouse - interaction (a "mouse interaction" in this context ends with the release). - - The default implementation does nothing except explicitly ignoring the event with \c - event->ignore(). - - \see mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent -*/ -void QCPLayerable::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - event->ignore(); -} - -/*! - This event gets called when the user moves the mouse while holding a mouse button, after this - layerable has become the mouse grabber by accepting the preceding \ref mousePressEvent. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). The parameter \a startPos indicates the position where the initial \ref - mousePressEvent occured, that started the mouse interaction. - - The default implementation does nothing. - - \see mousePressEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent -*/ -void QCPLayerable::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(startPos) - event->ignore(); -} - -/*! - This event gets called when the user releases the mouse button, after this layerable has become - the mouse grabber by accepting the preceding \ref mousePressEvent. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). The parameter \a startPos indicates the position where the initial \ref - mousePressEvent occured, that started the mouse interaction. - - The default implementation does nothing. - - \see mousePressEvent, mouseMoveEvent, mouseDoubleClickEvent, wheelEvent -*/ -void QCPLayerable::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(startPos) - event->ignore(); -} - -/*! - This event gets called when the user presses the mouse button a second time in a double-click, - while the cursor is over the layerable. Whether a cursor is over the layerable is decided by a - preceding call to \ref selectTest. - - The \ref mouseDoubleClickEvent is called instead of the second \ref mousePressEvent. So in the - case of a double-click, the event succession is - pressEvent – releaseEvent – doubleClickEvent – releaseEvent. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). The parameter \a details contains layerable-specific details about the hit, which - were generated in the previous call to \ref selectTest. For example, One-dimensional plottables - like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as - \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c - SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). - - Similarly to \ref mousePressEvent, once a layerable has accepted the \ref mouseDoubleClickEvent, - it is considered the mouse grabber and will receive all following calls to \ref mouseMoveEvent - and \ref mouseReleaseEvent for this mouse interaction (a "mouse interaction" in this context ends - with the release). - - The default implementation does nothing except explicitly ignoring the event with \c - event->ignore(). - - \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, wheelEvent -*/ -void QCPLayerable::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - event->ignore(); -} - -/*! - This event gets called when the user turns the mouse scroll wheel while the cursor is over the - layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref - selectTest. - - The current pixel position of the cursor on the QCustomPlot widget is accessible via \c - event->pos(). - - The \c event->delta() indicates how far the mouse wheel was turned, which is usually +/- 120 for - single rotation steps. However, if the mouse wheel is turned rapidly, multiple steps may - accumulate to one event, making \c event->delta() larger. On the other hand, if the wheel has - very smooth steps or none at all, the delta may be smaller. - - The default implementation does nothing. - - \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent -*/ -void QCPLayerable::wheelEvent(QWheelEvent *event) -{ - event->ignore(); -} -/* end of 'src/layer.cpp' */ - - -/* including file 'src/axis/range.cpp', size 12221 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPRange -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPRange - \brief Represents the range an axis is encompassing. - - contains a \a lower and \a upper double value and provides convenience input, output and - modification functions. - - \see QCPAxis::setRange -*/ - -/* start of documentation of inline functions */ - -/*! \fn double QCPRange::size() const - - Returns the size of the range, i.e. \a upper-\a lower -*/ - -/*! \fn double QCPRange::center() const - - Returns the center of the range, i.e. (\a upper+\a lower)*0.5 -*/ - -/*! \fn void QCPRange::normalize() - - Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values are - swapped. -*/ - -/*! \fn bool QCPRange::contains(double value) const - - Returns true when \a value lies within or exactly on the borders of the range. -*/ - -/*! \fn QCPRange &QCPRange::operator+=(const double& value) - - Adds \a value to both boundaries of the range. -*/ - -/*! \fn QCPRange &QCPRange::operator-=(const double& value) - - Subtracts \a value from both boundaries of the range. -*/ - -/*! \fn QCPRange &QCPRange::operator*=(const double& value) - - Multiplies both boundaries of the range by \a value. -*/ - -/*! \fn QCPRange &QCPRange::operator/=(const double& value) - - Divides both boundaries of the range by \a value. -*/ - -/* end of documentation of inline functions */ - -/*! - Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller - intervals would cause errors due to the 11-bit exponent of double precision numbers, - corresponding to a minimum magnitude of roughly 1e-308. - - \warning Do not use this constant to indicate "arbitrarily small" values in plotting logic (as - values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to - prevent axis ranges from obtaining underflowing ranges. - - \see validRange, maxRange -*/ -const double QCPRange::minRange = 1e-280; -//const double QCPRange::minRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(1970, 0, 0)); - -/*! - Maximum values (negative and positive) the range will accept in range-changing functions. - Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, - corresponding to a maximum magnitude of roughly 1e308. - - \warning Do not use this constant to indicate "arbitrarily large" values in plotting logic (as - values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to - prevent axis ranges from obtaining overflowing ranges. - - \see validRange, minRange -*/ -const double QCPRange::maxRange = 1e250; -//const double QCPRange::maxRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 12, 31)); - -/*! - Constructs a range with \a lower and \a upper set to zero. -*/ -QCPRange::QCPRange() : - lower(0), - upper(0) -{ -} - -/*! \overload - - Constructs a range with the specified \a lower and \a upper values. - - The resulting range will be normalized (see \ref normalize), so if \a lower is not numerically - smaller than \a upper, they will be swapped. -*/ -QCPRange::QCPRange(double lower, double upper) : - lower(lower), - upper(upper) -{ - normalize(); -} - -/*! \overload - - Expands this range such that \a otherRange is contained in the new range. It is assumed that both - this range and \a otherRange are normalized (see \ref normalize). - - If this range contains NaN as lower or upper bound, it will be replaced by the respective bound - of \a otherRange. - - If \a otherRange is already inside the current range, this function does nothing. - - \see expanded -*/ -void QCPRange::expand(const QCPRange &otherRange) -{ - if (lower > otherRange.lower || qIsNaN(lower)) - lower = otherRange.lower; - if (upper < otherRange.upper || qIsNaN(upper)) - upper = otherRange.upper; -} - -/*! \overload - - Expands this range such that \a includeCoord is contained in the new range. It is assumed that - this range is normalized (see \ref normalize). - - If this range contains NaN as lower or upper bound, the respective bound will be set to \a - includeCoord. - - If \a includeCoord is already inside the current range, this function does nothing. - - \see expand -*/ -void QCPRange::expand(double includeCoord) -{ - if (lower > includeCoord || qIsNaN(lower)) - lower = includeCoord; - if (upper < includeCoord || qIsNaN(upper)) - upper = includeCoord; -} - - -/*! \overload - - Returns an expanded range that contains this and \a otherRange. It is assumed that both this - range and \a otherRange are normalized (see \ref normalize). - - If this range contains NaN as lower or upper bound, the returned range's bound will be taken from - \a otherRange. - - \see expand -*/ -QCPRange QCPRange::expanded(const QCPRange &otherRange) const -{ - QCPRange result = *this; - result.expand(otherRange); - return result; -} - -/*! \overload - - Returns an expanded range that includes the specified \a includeCoord. It is assumed that this - range is normalized (see \ref normalize). - - If this range contains NaN as lower or upper bound, the returned range's bound will be set to \a - includeCoord. - - \see expand -*/ -QCPRange QCPRange::expanded(double includeCoord) const -{ - QCPRange result = *this; - result.expand(includeCoord); - return result; -} - -/*! - Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a - upperBound. If possible, the size of the current range is preserved in the process. - - If the range shall only be bounded at the lower side, you can set \a upperBound to \ref - QCPRange::maxRange. If it shall only be bounded at the upper side, set \a lowerBound to -\ref - QCPRange::maxRange. -*/ -QCPRange QCPRange::bounded(double lowerBound, double upperBound) const -{ - if (lowerBound > upperBound) - qSwap(lowerBound, upperBound); - - QCPRange result(lower, upper); - if (result.lower < lowerBound) - { - result.lower = lowerBound; - result.upper = lowerBound + size(); - if (result.upper > upperBound || qFuzzyCompare(size(), upperBound-lowerBound)) - result.upper = upperBound; - } else if (result.upper > upperBound) - { - result.upper = upperBound; - result.lower = upperBound - size(); - if (result.lower < lowerBound || qFuzzyCompare(size(), upperBound-lowerBound)) - result.lower = lowerBound; - } - - return result; -} - -/*! - Returns a sanitized version of the range. Sanitized means for logarithmic scales, that - the range won't span the positive and negative sign domain, i.e. contain zero. Further - \a lower will always be numerically smaller (or equal) to \a upper. - - If the original range does span positive and negative sign domains or contains zero, - the returned range will try to approximate the original range as good as possible. - If the positive interval of the original range is wider than the negative interval, the - returned range will only contain the positive interval, with lower bound set to \a rangeFac or - \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval - is wider than the positive interval, this time by changing the \a upper bound. -*/ -QCPRange QCPRange::sanitizedForLogScale() const -{ - double rangeFac = 1e-3; - QCPRange sanitizedRange(lower, upper); - sanitizedRange.normalize(); - // can't have range spanning negative and positive values in log plot, so change range to fix it - //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) - if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) - { - // case lower is 0 - if (rangeFac < sanitizedRange.upper*rangeFac) - sanitizedRange.lower = rangeFac; - else - sanitizedRange.lower = sanitizedRange.upper*rangeFac; - } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) - else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) - { - // case upper is 0 - if (-rangeFac > sanitizedRange.lower*rangeFac) - sanitizedRange.upper = -rangeFac; - else - sanitizedRange.upper = sanitizedRange.lower*rangeFac; - } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) - { - // find out whether negative or positive interval is wider to decide which sign domain will be chosen - if (-sanitizedRange.lower > sanitizedRange.upper) - { - // negative is wider, do same as in case upper is 0 - if (-rangeFac > sanitizedRange.lower*rangeFac) - sanitizedRange.upper = -rangeFac; - else - sanitizedRange.upper = sanitizedRange.lower*rangeFac; - } else - { - // positive is wider, do same as in case lower is 0 - if (rangeFac < sanitizedRange.upper*rangeFac) - sanitizedRange.lower = rangeFac; - else - sanitizedRange.lower = sanitizedRange.upper*rangeFac; - } - } - // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper -maxRange && - upper < maxRange && - qAbs(lower-upper) >= 1 && - qAbs(lower-upper) < 2 * maxRange); - -// return (lower > -maxRange && -// upper < maxRange && -// qAbs(lower-upper) > minRange && -// qAbs(lower-upper) < maxRange && -// !(lower > 0 && qIsInf(upper/lower)) && -// !(upper < 0 && qIsInf(lower/upper))); -} - -/*! - \overload - Checks, whether the specified range is within valid bounds, which are defined - as QCPRange::maxRange and QCPRange::minRange. - A valid range means: - \li range bounds within -maxRange and maxRange - \li range size above minRange - \li range size below maxRange -*/ -bool QCPRange::validRange(const QCPRange &range) -{ - return validRange(range.lower, range.upper); -// return (range.lower > -maxRange && -// range.upper < maxRange && -// qAbs(range.lower-range.upper) > minRange && -// qAbs(range.lower-range.upper) < maxRange && -// !(range.lower > 0 && qIsInf(range.upper/range.lower)) && -// !(range.upper < 0 && qIsInf(range.lower/range.upper))); -} -/* end of 'src/axis/range.cpp' */ - - -/* including file 'src/selection.cpp', size 21906 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPDataRange -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPDataRange - \brief Describes a data range given by begin and end index - - QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index - of a contiguous set of data points. The end index points to the data point above the last data point that's part of - the data range, similarly to the nomenclature used in standard iterators. - - Data Ranges are not bound to a certain plottable, thus they can be freely exchanged, created and - modified. If a non-contiguous data set shall be described, the class \ref QCPDataSelection is - used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref - QCPDataSelection is thus used. - - Both \ref QCPDataRange and \ref QCPDataSelection offer convenience methods to work with them, - e.g. \ref bounded, \ref expanded, \ref intersects, \ref intersection, \ref adjusted, \ref - contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be - used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding - \ref QCPDataSelection. - - %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and - QCPDataRange. - - \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval - in floating point plot coordinates, e.g. the current axis range. -*/ - -/* start documentation of inline functions */ - -/*! \fn int QCPDataRange::size() const - - Returns the number of data points described by this data range. This is equal to the end index - minus the begin index. - - \see length -*/ - -/*! \fn int QCPDataRange::length() const - - Returns the number of data points described by this data range. Equivalent to \ref size. -*/ - -/*! \fn void QCPDataRange::setBegin(int begin) - - Sets the begin of this data range. The \a begin index points to the first data point that is part - of the data range. - - No checks or corrections are made to ensure the resulting range is valid (\ref isValid). - - \see setEnd -*/ - -/*! \fn void QCPDataRange::setEnd(int end) - - Sets the end of this data range. The \a end index points to the data point just above the last - data point that is part of the data range. - - No checks or corrections are made to ensure the resulting range is valid (\ref isValid). - - \see setBegin -*/ - -/*! \fn bool QCPDataRange::isValid() const - - Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and - an end index greater or equal to the begin index. - - \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods - (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's - methods. The invalid range is not inherently prevented in QCPDataRange, to allow temporary - invalid begin/end values while manipulating the range. An invalid range is not necessarily empty - (\ref isEmpty), since its \ref length can be negative and thus non-zero. -*/ - -/*! \fn bool QCPDataRange::isEmpty() const - - Returns whether this range is empty, i.e. whether its begin index equals its end index. - - \see size, length -*/ - -/*! \fn QCPDataRange QCPDataRange::adjusted(int changeBegin, int changeEnd) const - - Returns a data range where \a changeBegin and \a changeEnd were added to the begin and end - indices, respectively. -*/ - -/* end documentation of inline functions */ - -/*! - Creates an empty QCPDataRange, with begin and end set to 0. -*/ -QCPDataRange::QCPDataRange() : - mBegin(0), - mEnd(0) -{ -} - -/*! - Creates a QCPDataRange, initialized with the specified \a begin and \a end. - - No checks or corrections are made to ensure the resulting range is valid (\ref isValid). -*/ -QCPDataRange::QCPDataRange(int begin, int end) : - mBegin(begin), - mEnd(end) -{ -} - -/*! - Returns a data range that matches this data range, except that parts exceeding \a other are - excluded. - - This method is very similar to \ref intersection, with one distinction: If this range and the \a - other range share no intersection, the returned data range will be empty with begin and end set - to the respective boundary side of \a other, at which this range is residing. (\ref intersection - would just return a range with begin and end set to 0.) -*/ -QCPDataRange QCPDataRange::bounded(const QCPDataRange &other) const -{ - QCPDataRange result(intersection(other)); - if (result.isEmpty()) // no intersection, preserve respective bounding side of otherRange as both begin and end of return value - { - if (mEnd <= other.mBegin) - result = QCPDataRange(other.mBegin, other.mBegin); - else - result = QCPDataRange(other.mEnd, other.mEnd); - } - return result; -} - -/*! - Returns a data range that contains both this data range as well as \a other. -*/ -QCPDataRange QCPDataRange::expanded(const QCPDataRange &other) const -{ - return QCPDataRange(qMin(mBegin, other.mBegin), qMax(mEnd, other.mEnd)); -} - -/*! - Returns the data range which is contained in both this data range and \a other. - - This method is very similar to \ref bounded, with one distinction: If this range and the \a other - range share no intersection, the returned data range will be empty with begin and end set to 0. - (\ref bounded would return a range with begin and end set to one of the boundaries of \a other, - depending on which side this range is on.) - - \see QCPDataSelection::intersection -*/ -QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const -{ - QCPDataRange result(qMax(mBegin, other.mBegin), qMin(mEnd, other.mEnd)); - if (result.isValid()) - return result; - else - return QCPDataRange(); -} - -/*! - Returns whether this data range and \a other share common data points. - - \see intersection, contains -*/ -bool QCPDataRange::intersects(const QCPDataRange &other) const -{ - return !( (mBegin > other.mBegin && mBegin >= other.mEnd) || - (mEnd <= other.mBegin && mEnd < other.mEnd) ); -} - -/*! - Returns whether all data points described by this data range are also in \a other. - - \see intersects -*/ -bool QCPDataRange::contains(const QCPDataRange &other) const -{ - return mBegin <= other.mBegin && mEnd >= other.mEnd; -} - - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPDataSelection -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPDataSelection - \brief Describes a data set by holding multiple QCPDataRange instances - - QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly - disjoint) set of data selection. - - The data selection can be modified with addition and subtraction operators which take - QCPDataSelection and QCPDataRange instances, as well as methods such as \ref addDataRange and - \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc. - - The method \ref simplify is used to join directly adjacent or even overlapping QCPDataRange - instances. QCPDataSelection automatically simplifies when using the addition/subtraction - operators. The only case when \ref simplify is left to the user, is when calling \ref - addDataRange, with the parameter \a simplify explicitly set to false. This is useful if many data - ranges will be added to the selection successively and the overhead for simplifying after each - iteration shall be avoided. In this case, you should make sure to call \ref simplify after - completing the operation. - - Use \ref enforceType to bring the data selection into a state complying with the constraints for - selections defined in \ref QCP::SelectionType. - - %QCustomPlot's \ref dataselection "data selection mechanism" is based on QCPDataSelection and - QCPDataRange. - - \section qcpdataselection-iterating Iterating over a data selection - - As an example, the following code snippet calculates the average value of a graph's data - \ref QCPAbstractPlottable::selection "selection": - - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpdataselection-iterating-1 - -*/ - -/* start documentation of inline functions */ - -/*! \fn int QCPDataSelection::dataRangeCount() const - - Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref - dataRange via their index. - - \see dataRange, dataPointCount -*/ - -/*! \fn QList QCPDataSelection::dataRanges() const - - Returns all data ranges that make up the data selection. If the data selection is simplified (the - usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point - index. - - \see dataRange -*/ - -/*! \fn bool QCPDataSelection::isEmpty() const - - Returns true if there are no data ranges, and thus no data points, in this QCPDataSelection - instance. - - \see dataRangeCount -*/ - -/* end documentation of inline functions */ - -/*! - Creates an empty QCPDataSelection. -*/ -QCPDataSelection::QCPDataSelection() -{ -} - -/*! - Creates a QCPDataSelection containing the provided \a range. -*/ -QCPDataSelection::QCPDataSelection(const QCPDataRange &range) -{ - mDataRanges.append(range); -} - -/*! - Returns true if this selection is identical (contains the same data ranges with the same begin - and end indices) to \a other. - - Note that both data selections must be in simplified state (the usual state of the selection, see - \ref simplify) for this operator to return correct results. -*/ -bool QCPDataSelection::operator==(const QCPDataSelection &other) const -{ - if (mDataRanges.size() != other.mDataRanges.size()) - return false; - for (int i=0; i= other.end()) - break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this - - if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored - { - if (thisBegin >= other.begin()) // range leading segment is encompassed - { - if (thisEnd <= other.end()) // range fully encompassed, remove completely - { - mDataRanges.removeAt(i); - continue; - } else // only leading segment is encompassed, trim accordingly - mDataRanges[i].setBegin(other.end()); - } else // leading segment is not encompassed - { - if (thisEnd <= other.end()) // only trailing segment is encompassed, trim accordingly - { - mDataRanges[i].setEnd(other.begin()); - } else // other lies inside this range, so split range - { - mDataRanges[i].setEnd(other.begin()); - mDataRanges.insert(i+1, QCPDataRange(other.end(), thisEnd)); - break; // since data ranges are sorted (and don't overlap) after simplify() call, we're done here - } - } - } - ++i; - } - - return *this; -} - -/*! - Returns the total number of data points contained in all data ranges that make up this data - selection. -*/ -int QCPDataSelection::dataPointCount() const -{ - int result = 0; - for (int i=0; i= 0 && index < mDataRanges.size()) - { - return mDataRanges.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of range:" << index; - return QCPDataRange(); - } -} - -/*! - Returns a \ref QCPDataRange which spans the entire data selection, including possible - intermediate segments which are not part of the original data selection. -*/ -QCPDataRange QCPDataSelection::span() const -{ - if (isEmpty()) - return QCPDataRange(); - else - return QCPDataRange(mDataRanges.first().begin(), mDataRanges.last().end()); -} - -/*! - Adds the given \a dataRange to this data selection. This is equivalent to the += operator but - allows disabling immediate simplification by setting \a simplify to false. This can improve - performance if adding a very large amount of data ranges successively. In this case, make sure to - call \ref simplify manually, after the operation. -*/ -void QCPDataSelection::addDataRange(const QCPDataRange &dataRange, bool simplify) -{ - mDataRanges.append(dataRange); - if (simplify) - this->simplify(); -} - -/*! - Removes all data ranges. The data selection then contains no data points. - - \ref isEmpty -*/ -void QCPDataSelection::clear() -{ - mDataRanges.clear(); -} - -/*! - Sorts all data ranges by range begin index in ascending order, and then joins directly adjacent - or overlapping ranges. This can reduce the number of individual data ranges in the selection, and - prevents possible double-counting when iterating over the data points held by the data ranges. - - This method is automatically called when using the addition/subtraction operators. The only case - when \ref simplify is left to the user, is when calling \ref addDataRange, with the parameter \a - simplify explicitly set to false. -*/ -void QCPDataSelection::simplify() -{ - // remove any empty ranges: - for (int i=mDataRanges.size()-1; i>=0; --i) - { - if (mDataRanges.at(i).isEmpty()) - mDataRanges.removeAt(i); - } - if (mDataRanges.isEmpty()) - return; - - // sort ranges by starting value, ascending: - std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin); - - // join overlapping/contiguous ranges: - int i = 1; - while (i < mDataRanges.size()) - { - if (mDataRanges.at(i-1).end() >= mDataRanges.at(i).begin()) // range i overlaps/joins with i-1, so expand range i-1 appropriately and remove range i from list - { - mDataRanges[i-1].setEnd(qMax(mDataRanges.at(i-1).end(), mDataRanges.at(i).end())); - mDataRanges.removeAt(i); - } else - ++i; - } -} - -/*! - Makes sure this data selection conforms to the specified \a type selection type. Before the type - is enforced, \ref simplify is called. - - Depending on \a type, enforcing means adding new data points that were previously not part of the - selection, or removing data points from the selection. If the current selection already conforms - to \a type, the data selection is not changed. - - \see QCP::SelectionType -*/ -void QCPDataSelection::enforceType(QCP::SelectionType type) -{ - simplify(); - switch (type) - { - case QCP::stNone: - { - mDataRanges.clear(); - break; - } - case QCP::stWhole: - { - // whole selection isn't defined by data range, so don't change anything (is handled in plottable methods) - break; - } - case QCP::stSingleData: - { - // reduce all data ranges to the single first data point: - if (!mDataRanges.isEmpty()) - { - if (mDataRanges.size() > 1) - mDataRanges = QList() << mDataRanges.first(); - if (mDataRanges.first().length() > 1) - mDataRanges.first().setEnd(mDataRanges.first().begin()+1); - } - break; - } - case QCP::stDataRange: - { - mDataRanges = QList() << span(); - break; - } - case QCP::stMultipleDataRanges: - { - // this is the selection type that allows all concievable combinations of ranges, so do nothing - break; - } - } -} - -/*! - Returns true if the data selection \a other is contained entirely in this data selection, i.e. - all data point indices that are in \a other are also in this data selection. - - \see QCPDataRange::contains -*/ -bool QCPDataSelection::contains(const QCPDataSelection &other) const -{ - if (other.isEmpty()) return false; - - int otherIndex = 0; - int thisIndex = 0; - while (thisIndex < mDataRanges.size() && otherIndex < other.mDataRanges.size()) - { - if (mDataRanges.at(thisIndex).contains(other.mDataRanges.at(otherIndex))) - ++otherIndex; - else - ++thisIndex; - } - return thisIndex < mDataRanges.size(); // if thisIndex ran all the way to the end to find a containing range for the current otherIndex, other is not contained in this -} - -/*! - Returns a data selection containing the points which are both in this data selection and in the - data range \a other. - - A common use case is to limit an unknown data selection to the valid range of a data container, - using \ref QCPDataContainer::dataRange as \a other. One can then safely iterate over the returned - data selection without exceeding the data container's bounds. -*/ -QCPDataSelection QCPDataSelection::intersection(const QCPDataRange &other) const -{ - QCPDataSelection result; - for (int i=0; iorientation() == Qt::Horizontal) - return QCPRange(axis->pixelToCoord(mRect.left()), axis->pixelToCoord(mRect.left()+mRect.width())); - else - return QCPRange(axis->pixelToCoord(mRect.top()+mRect.height()), axis->pixelToCoord(mRect.top())); - } else - { - qDebug() << Q_FUNC_INFO << "called with axis zero"; - return QCPRange(); - } -} - -/*! - Sets the pen that will be used to draw the selection rect outline. - - \see setBrush -*/ -void QCPSelectionRect::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the brush that will be used to fill the selection rect. By default the selection rect is not - filled, i.e. \a brush is Qt::NoBrush. - - \see setPen -*/ -void QCPSelectionRect::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - If there is currently a selection interaction going on (\ref isActive), the interaction is - canceled. The selection rect will emit the \ref canceled signal. -*/ -void QCPSelectionRect::cancel() -{ - if (mActive) - { - mActive = false; - emit canceled(mRect, 0); - } -} - -/*! \internal - - This method is called by QCustomPlot to indicate that a selection rect interaction was initiated. - The default implementation sets the selection rect to active, initializes the selection rect - geometry and emits the \ref started signal. -*/ -void QCPSelectionRect::startSelection(QMouseEvent *event) -{ - mActive = true; - mRect = QRect(event->pos(), event->pos()); - emit started(event); -} - -/*! \internal - - This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs - to update its geometry. The default implementation updates the rect and emits the \ref changed - signal. -*/ -void QCPSelectionRect::moveSelection(QMouseEvent *event) -{ - mRect.setBottomRight(event->pos()); - emit changed(mRect, event); - layer()->replot(); -} - -/*! \internal - - This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has - finished by the user releasing the mouse button. The default implementation deactivates the - selection rect and emits the \ref accepted signal. -*/ -void QCPSelectionRect::endSelection(QMouseEvent *event) -{ - mRect.setBottomRight(event->pos()); - mActive = false; - emit accepted(mRect, event); -} - -/*! \internal - - This method is called by QCustomPlot when a key has been pressed by the user while the selection - rect interaction is active. The default implementation allows to \ref cancel the interaction by - hitting the escape key. -*/ -void QCPSelectionRect::keyPressEvent(QKeyEvent *event) -{ - if (event->key() == Qt::Key_Escape && mActive) - { - mActive = false; - emit canceled(mRect, event); - } -} - -/* inherits documentation from base class */ -void QCPSelectionRect::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); -} - -/*! \internal - - If the selection rect is active (\ref isActive), draws the selection rect defined by \a mRect. - - \seebaseclassmethod -*/ -void QCPSelectionRect::draw(QCPPainter *painter) -{ - if (mActive) - { - painter->setPen(mPen); - painter->setBrush(mBrush); - painter->drawRect(mRect); - } -} -/* end of 'src/selectionrect.cpp' */ - - -/* including file 'src/layout.cpp', size 79064 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPMarginGroup -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPMarginGroup - \brief A margin group allows synchronization of margin sides if working with multiple layout elements. - - QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that - they will all have the same size, based on the largest required margin in the group. - - \n - \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" - \n - - In certain situations it is desirable that margins at specific sides are synchronized across - layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will - provide a cleaner look to the user if the left and right margins of the two axis rects are of the - same size. The left axis of the top axis rect will then be at the same horizontal position as the - left axis of the lower axis rect, making them appear aligned. The same applies for the right - axes. This is what QCPMarginGroup makes possible. - - To add/remove a specific side of a layout element to/from a margin group, use the \ref - QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call - \ref clear, or just delete the margin group. - - \section QCPMarginGroup-example Example - - First create a margin group: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 - Then set this group on the layout element sides: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-2 - Here, we've used the first two axis rects of the plot and synchronized their left margins with - each other and their right margins with each other. -*/ - -/* start documentation of inline functions */ - -/*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const - - Returns a list of all layout elements that have their margin \a side associated with this margin - group. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPMarginGroup instance in \a parentPlot. -*/ -QCPMarginGroup::QCPMarginGroup(QCustomPlot *parentPlot) : - QObject(parentPlot), - mParentPlot(parentPlot) -{ - mChildren.insert(QCP::msLeft, QList()); - mChildren.insert(QCP::msRight, QList()); - mChildren.insert(QCP::msTop, QList()); - mChildren.insert(QCP::msBottom, QList()); -} - -QCPMarginGroup::~QCPMarginGroup() -{ - clear(); -} - -/*! - Returns whether this margin group is empty. If this function returns true, no layout elements use - this margin group to synchronize margin sides. -*/ -bool QCPMarginGroup::isEmpty() const -{ - QHashIterator > it(mChildren); - while (it.hasNext()) - { - it.next(); - if (!it.value().isEmpty()) - return false; - } - return true; -} - -/*! - Clears this margin group. The synchronization of the margin sides that use this margin group is - lifted and they will use their individual margin sizes again. -*/ -void QCPMarginGroup::clear() -{ - // make all children remove themselves from this margin group: - QHashIterator > it(mChildren); - while (it.hasNext()) - { - it.next(); - const QList elements = it.value(); - for (int i=elements.size()-1; i>=0; --i) - elements.at(i)->setMarginGroup(it.key(), 0); // removes itself from mChildren via removeChild - } -} - -/*! \internal - - Returns the synchronized common margin for \a side. This is the margin value that will be used by - the layout element on the respective side, if it is part of this margin group. - - The common margin is calculated by requesting the automatic margin (\ref - QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin - group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into - account, too.) -*/ -int QCPMarginGroup::commonMargin(QCP::MarginSide side) const -{ - // query all automatic margins of the layout elements in this margin group side and find maximum: - int result = 0; - const QList elements = mChildren.value(side); - for (int i=0; iautoMargins().testFlag(side)) - continue; - int m = qMax(elements.at(i)->calculateAutoMargin(side), QCP::getMarginValue(elements.at(i)->minimumMargins(), side)); - if (m > result) - result = m; - } - return result; -} - -/*! \internal - - Adds \a element to the internal list of child elements, for the margin \a side. - - This function does not modify the margin group property of \a element. -*/ -void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) -{ - if (!mChildren[side].contains(element)) - mChildren[side].append(element); - else - qDebug() << Q_FUNC_INFO << "element is already child of this margin group side" << reinterpret_cast(element); -} - -/*! \internal - - Removes \a element from the internal list of child elements, for the margin \a side. - - This function does not modify the margin group property of \a element. -*/ -void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) -{ - if (!mChildren[side].removeOne(element)) - qDebug() << Q_FUNC_INFO << "element is not child of this margin group side" << reinterpret_cast(element); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayoutElement -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayoutElement - \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". - - This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. - - A Layout element is a rectangular object which can be placed in layouts. It has an outer rect - (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference - between outer and inner rect is called its margin. The margin can either be set to automatic or - manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be - set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, - the layout element subclass will control the value itself (via \ref calculateAutoMargin). - - Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level - layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref - QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. - - Thus in QCustomPlot one can divide layout elements into two categories: The ones that are - invisible by themselves, because they don't draw anything. Their only purpose is to manage the - position and size of other layout elements. This category of layout elements usually use - QCPLayout as base class. Then there is the category of layout elements which actually draw - something. For example, QCPAxisRect, QCPLegend and QCPTextElement are of this category. This does - not necessarily mean that the latter category can't have child layout elements. QCPLegend for - instance, actually derives from QCPLayoutGrid and the individual legend items are child layout - elements in the grid layout. -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPLayout *QCPLayoutElement::layout() const - - Returns the parent layout of this layout element. -*/ - -/*! \fn QRect QCPLayoutElement::rect() const - - Returns the inner rect of this layout element. The inner rect is the outer rect (\ref outerRect, \ref - setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). - - In some cases, the area between outer and inner rect is left blank. In other cases the margin - area is used to display peripheral graphics while the main content is in the inner rect. This is - where automatic margin calculation becomes interesting because it allows the layout element to - adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect - draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if - \ref setAutoMargins is enabled) according to the space required by the labels of the axes. - - \see outerRect -*/ - -/*! \fn QRect QCPLayoutElement::outerRect() const - - Returns the outer rect of this layout element. The outer rect is the inner rect expanded by the - margins (\ref setMargins, \ref setAutoMargins). The outer rect is used (and set via \ref - setOuterRect) by the parent \ref QCPLayout to control the size of this layout element. - - \see rect -*/ - -/* end documentation of inline functions */ - -/*! - Creates an instance of QCPLayoutElement and sets default values. -*/ -QCPLayoutElement::QCPLayoutElement(QCustomPlot *parentPlot) : - QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout) - mParentLayout(0), - mMinimumSize(), - mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), - mSizeConstraintRect(scrInnerRect), - mRect(0, 0, 0, 0), - mOuterRect(0, 0, 0, 0), - mMargins(0, 0, 0, 0), - mMinimumMargins(0, 0, 0, 0), - mAutoMargins(QCP::msAll) -{ -} - -QCPLayoutElement::~QCPLayoutElement() -{ - setMarginGroup(QCP::msAll, 0); // unregister at margin groups, if there are any - // unregister at layout: - if (qobject_cast(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor - mParentLayout->take(this); -} - -/*! - Sets the outer rect of this layout element. If the layout element is inside a layout, the layout - sets the position and size of this layout element using this function. - - Calling this function externally has no effect, since the layout will overwrite any changes to - the outer rect upon the next replot. - - The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. - - \see rect -*/ -void QCPLayoutElement::setOuterRect(const QRect &rect) -{ - if (mOuterRect != rect) - { - mOuterRect = rect; - mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); - } -} - -/*! - Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all - sides, this function is used to manually set the margin on those sides. Sides that are still set - to be handled automatically are ignored and may have any value in \a margins. - - The margin is the distance between the outer rect (controlled by the parent layout via \ref - setOuterRect) and the inner \ref rect (which usually contains the main content of this layout - element). - - \see setAutoMargins -*/ -void QCPLayoutElement::setMargins(const QMargins &margins) -{ - if (mMargins != margins) - { - mMargins = margins; - mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); - } -} - -/*! - If \ref setAutoMargins is enabled on some or all margins, this function is used to provide - minimum values for those margins. - - The minimum values are not enforced on margin sides that were set to be under manual control via - \ref setAutoMargins. - - \see setAutoMargins -*/ -void QCPLayoutElement::setMinimumMargins(const QMargins &margins) -{ - if (mMinimumMargins != margins) - { - mMinimumMargins = margins; - } -} - -/*! - Sets on which sides the margin shall be calculated automatically. If a side is calculated - automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is - set to be controlled manually, the value may be specified with \ref setMargins. - - Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref - setMarginGroup), to synchronize (align) it with other layout elements in the plot. - - \see setMinimumMargins, setMargins, QCP::MarginSide -*/ -void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) -{ - mAutoMargins = sides; -} - -/*! - Sets the minimum size of this layout element. A parent layout tries to respect the \a size here - by changing row/column sizes in the layout accordingly. - - If the parent layout size is not sufficient to satisfy all minimum size constraints of its child - layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot - propagates the layout's size constraints to the outside by setting its own minimum QWidget size - accordingly, so violations of \a size should be exceptions. - - Whether this constraint applies to the inner or the outer rect can be specified with \ref - setSizeConstraintRect (see \ref rect and \ref outerRect). -*/ -void QCPLayoutElement::setMinimumSize(const QSize &size) -{ - if (mMinimumSize != size) - { - mMinimumSize = size; - if (mParentLayout) - mParentLayout->sizeConstraintsChanged(); - } -} - -/*! \overload - - Sets the minimum size of this layout element. - - Whether this constraint applies to the inner or the outer rect can be specified with \ref - setSizeConstraintRect (see \ref rect and \ref outerRect). -*/ -void QCPLayoutElement::setMinimumSize(int width, int height) -{ - setMinimumSize(QSize(width, height)); -} - -/*! - Sets the maximum size of this layout element. A parent layout tries to respect the \a size here - by changing row/column sizes in the layout accordingly. - - Whether this constraint applies to the inner or the outer rect can be specified with \ref - setSizeConstraintRect (see \ref rect and \ref outerRect). -*/ -void QCPLayoutElement::setMaximumSize(const QSize &size) -{ - if (mMaximumSize != size) - { - mMaximumSize = size; - if (mParentLayout) - mParentLayout->sizeConstraintsChanged(); - } -} - -/*! \overload - - Sets the maximum size of this layout element. - - Whether this constraint applies to the inner or the outer rect can be specified with \ref - setSizeConstraintRect (see \ref rect and \ref outerRect). -*/ -void QCPLayoutElement::setMaximumSize(int width, int height) -{ - setMaximumSize(QSize(width, height)); -} - -/*! - Sets to which rect of a layout element the size constraints apply. Size constraints can be set - via \ref setMinimumSize and \ref setMaximumSize. - - The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis - labels), whereas the inner rect (\ref rect) does not. - - \see setMinimumSize, setMaximumSize -*/ -void QCPLayoutElement::setSizeConstraintRect(SizeConstraintRect constraintRect) -{ - if (mSizeConstraintRect != constraintRect) - { - mSizeConstraintRect = constraintRect; - if (mParentLayout) - mParentLayout->sizeConstraintsChanged(); - } -} - -/*! - Sets the margin \a group of the specified margin \a sides. - - Margin groups allow synchronizing specified margins across layout elements, see the documentation - of \ref QCPMarginGroup. - - To unset the margin group of \a sides, set \a group to 0. - - Note that margin groups only work for margin sides that are set to automatic (\ref - setAutoMargins). - - \see QCP::MarginSide -*/ -void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) -{ - QVector sideVector; - if (sides.testFlag(QCP::msLeft)) sideVector.append(QCP::msLeft); - if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); - if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); - if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); - - for (int i=0; iremoveChild(side, this); - - if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there - { - mMarginGroups.remove(side); - } else // setting to a new group - { - mMarginGroups[side] = group; - group->addChild(side, this); - } - } - } -} - -/*! - Updates the layout element and sub-elements. This function is automatically called before every - replot by the parent layout element. It is called multiple times, once for every \ref - UpdatePhase. The phases are run through in the order of the enum values. For details about what - happens at the different phases, see the documentation of \ref UpdatePhase. - - Layout elements that have child elements should call the \ref update method of their child - elements, and pass the current \a phase unchanged. - - The default implementation executes the automatic margin mechanism in the \ref upMargins phase. - Subclasses should make sure to call the base class implementation. -*/ -void QCPLayoutElement::update(UpdatePhase phase) -{ - if (phase == upMargins) - { - if (mAutoMargins != QCP::msNone) - { - // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group: - QMargins newMargins = mMargins; - QList allMarginSides = QList() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom; - foreach (QCP::MarginSide side, allMarginSides) - { - if (mAutoMargins.testFlag(side)) // this side's margin shall be calculated automatically - { - if (mMarginGroups.contains(side)) - QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group - else - QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly - // apply minimum margin restrictions: - if (QCP::getMarginValue(newMargins, side) < QCP::getMarginValue(mMinimumMargins, side)) - QCP::setMarginValue(newMargins, side, QCP::getMarginValue(mMinimumMargins, side)); - } - } - setMargins(newMargins); - } - } -} - -/*! - Returns the suggested minimum size this layout element (the \ref outerRect) may be compressed to, - if no manual minimum size is set. - - if a minimum size (\ref setMinimumSize) was not set manually, parent layouts use the returned size - (usually indirectly through \ref QCPLayout::getFinalMinimumOuterSize) to determine the minimum - allowed size of this layout element. - - A manual minimum size is considered set if it is non-zero. - - The default implementation simply returns the sum of the horizontal margins for the width and the - sum of the vertical margins for the height. Reimplementations may use their detailed knowledge - about the layout element's content to provide size hints. -*/ -QSize QCPLayoutElement::minimumOuterSizeHint() const -{ - return QSize(mMargins.left()+mMargins.right(), mMargins.top()+mMargins.bottom()); -} - -/*! - Returns the suggested maximum size this layout element (the \ref outerRect) may be expanded to, - if no manual maximum size is set. - - if a maximum size (\ref setMaximumSize) was not set manually, parent layouts use the returned - size (usually indirectly through \ref QCPLayout::getFinalMaximumOuterSize) to determine the - maximum allowed size of this layout element. - - A manual maximum size is considered set if it is smaller than Qt's \c QWIDGETSIZE_MAX. - - The default implementation simply returns \c QWIDGETSIZE_MAX for both width and height, implying - no suggested maximum size. Reimplementations may use their detailed knowledge about the layout - element's content to provide size hints. -*/ -QSize QCPLayoutElement::maximumOuterSizeHint() const -{ - return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); -} - -/*! - Returns a list of all child elements in this layout element. If \a recursive is true, all - sub-child elements are included in the list, too. - - \warning There may be entries with value 0 in the returned list. (For example, QCPLayoutGrid may have - empty cells which yield 0 at the respective index.) -*/ -QList QCPLayoutElement::elements(bool recursive) const -{ - Q_UNUSED(recursive) - return QList(); -} - -/*! - Layout elements are sensitive to events inside their outer rect. If \a pos is within the outer - rect, this method returns a value corresponding to 0.99 times the parent plot's selection - tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is - true, -1.0 is returned. - - See \ref QCPLayerable::selectTest for a general explanation of this virtual method. - - QCPLayoutElement subclasses may reimplement this method to provide more specific selection test - behaviour. -*/ -double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - - if (onlySelectable) - return -1; - - if (QRectF(mOuterRect).contains(pos)) - { - if (mParentPlot) - return mParentPlot->selectionTolerance()*0.99; - else - { - qDebug() << Q_FUNC_INFO << "parent plot not defined"; - return -1; - } - } else - return -1; -} - -/*! \internal - - propagates the parent plot initialization to all child elements, by calling \ref - QCPLayerable::initializeParentPlot on them. -*/ -void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) -{ - foreach (QCPLayoutElement* el, elements(false)) - { - if (!el->parentPlot()) - el->initializeParentPlot(parentPlot); - } -} - -/*! \internal - - Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a - side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the - returned value will not be smaller than the specified minimum margin. - - The default implementation just returns the respective manual margin (\ref setMargins) or the - minimum margin, whichever is larger. -*/ -int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) -{ - return qMax(QCP::getMarginValue(mMargins, side), QCP::getMarginValue(mMinimumMargins, side)); -} - -/*! \internal - - This virtual method is called when this layout element was moved to a different QCPLayout, or - when this layout element has changed its logical position (e.g. row and/or column) within the - same QCPLayout. Subclasses may use this to react accordingly. - - Since this method is called after the completion of the move, you can access the new parent - layout via \ref layout(). - - The default implementation does nothing. -*/ -void QCPLayoutElement::layoutChanged() -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayout -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayout - \brief The abstract base class for layouts - - This is an abstract base class for layout elements whose main purpose is to define the position - and size of other child layout elements. In most cases, layouts don't draw anything themselves - (but there are exceptions to this, e.g. QCPLegend). - - QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. - - QCPLayout introduces a common interface for accessing and manipulating the child elements. Those - functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref - simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions - to this interface which are more specialized to the form of the layout. For example, \ref - QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid - more conveniently. - - Since this is an abstract base class, you can't instantiate it directly. Rather use one of its - subclasses like QCPLayoutGrid or QCPLayoutInset. - - For a general introduction to the layout system, see the dedicated documentation page \ref - thelayoutsystem "The Layout System". -*/ - -/* start documentation of pure virtual functions */ - -/*! \fn virtual int QCPLayout::elementCount() const = 0 - - Returns the number of elements/cells in the layout. - - \see elements, elementAt -*/ - -/*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 - - Returns the element in the cell with the given \a index. If \a index is invalid, returns 0. - - Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. - QCPLayoutGrid), so this function may return 0 in those cases. You may use this function to check - whether a cell is empty or not. - - \see elements, elementCount, takeAt -*/ - -/*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 - - Removes the element with the given \a index from the layout and returns it. - - If the \a index is invalid or the cell with that index is empty, returns 0. - - Note that some layouts don't remove the respective cell right away but leave an empty cell after - successful removal of the layout element. To collapse empty cells, use \ref simplify. - - \see elementAt, take -*/ - -/*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 - - Removes the specified \a element from the layout and returns true on success. - - If the \a element isn't in this layout, returns false. - - Note that some layouts don't remove the respective cell right away but leave an empty cell after - successful removal of the layout element. To collapse empty cells, use \ref simplify. - - \see takeAt -*/ - -/* end documentation of pure virtual functions */ - -/*! - Creates an instance of QCPLayout and sets default values. Note that since QCPLayout - is an abstract base class, it can't be instantiated directly. -*/ -QCPLayout::QCPLayout() -{ -} - -/*! - If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to - reposition and resize their cells. - - Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements". - - For details about this method and the update phases, see the documentation of \ref - QCPLayoutElement::update. -*/ -void QCPLayout::update(UpdatePhase phase) -{ - QCPLayoutElement::update(phase); - - // set child element rects according to layout: - if (phase == upLayout) - updateLayout(); - - // propagate update call to child elements: - const int elCount = elementCount(); - for (int i=0; iupdate(phase); - } -} - -/* inherits documentation from base class */ -QList QCPLayout::elements(bool recursive) const -{ - const int c = elementCount(); - QList result; -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - result.reserve(c); -#endif - for (int i=0; ielements(recursive); - } - } - return result; -} - -/*! - Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the - default implementation does nothing. - - Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit - simplification while QCPLayoutGrid does. -*/ -void QCPLayout::simplify() -{ -} - -/*! - Removes and deletes the element at the provided \a index. Returns true on success. If \a index is - invalid or points to an empty cell, returns false. - - This function internally uses \ref takeAt to remove the element from the layout and then deletes - the returned element. Note that some layouts don't remove the respective cell right away but leave an - empty cell after successful removal of the layout element. To collapse empty cells, use \ref - simplify. - - \see remove, takeAt -*/ -bool QCPLayout::removeAt(int index) -{ - if (QCPLayoutElement *el = takeAt(index)) - { - delete el; - return true; - } else - return false; -} - -/*! - Removes and deletes the provided \a element. Returns true on success. If \a element is not in the - layout, returns false. - - This function internally uses \ref takeAt to remove the element from the layout and then deletes - the element. Note that some layouts don't remove the respective cell right away but leave an - empty cell after successful removal of the layout element. To collapse empty cells, use \ref - simplify. - - \see removeAt, take -*/ -bool QCPLayout::remove(QCPLayoutElement *element) -{ - if (take(element)) - { - delete element; - return true; - } else - return false; -} - -/*! - Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure - all empty cells are collapsed. - - \see remove, removeAt -*/ -void QCPLayout::clear() -{ - for (int i=elementCount()-1; i>=0; --i) - { - if (elementAt(i)) - removeAt(i); - } - simplify(); -} - -/*! - Subclasses call this method to report changed (minimum/maximum) size constraints. - - If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref - sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of - QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, - it may update itself and resize cells accordingly. -*/ -void QCPLayout::sizeConstraintsChanged() const -{ - if (QWidget *w = qobject_cast(parent())) - w->updateGeometry(); - else if (QCPLayout *l = qobject_cast(parent())) - l->sizeConstraintsChanged(); -} - -/*! \internal - - Subclasses reimplement this method to update the position and sizes of the child elements/cells - via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. - - The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay - within that rect. - - \ref getSectionSizes may help with the reimplementation of this function. - - \see update -*/ -void QCPLayout::updateLayout() -{ -} - - -/*! \internal - - Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the - \ref QCPLayerable::parentLayerable and the QObject parent to this layout. - - Further, if \a el didn't previously have a parent plot, calls \ref - QCPLayerable::initializeParentPlot on \a el to set the paret plot. - - This method is used by subclass specific methods that add elements to the layout. Note that this - method only changes properties in \a el. The removal from the old layout and the insertion into - the new layout must be done additionally. -*/ -void QCPLayout::adoptElement(QCPLayoutElement *el) -{ - if (el) - { - el->mParentLayout = this; - el->setParentLayerable(this); - el->setParent(this); - if (!el->parentPlot()) - el->initializeParentPlot(mParentPlot); - el->layoutChanged(); - } else - qDebug() << Q_FUNC_INFO << "Null element passed"; -} - -/*! \internal - - Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout - and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent - QCustomPlot. - - This method is used by subclass specific methods that remove elements from the layout (e.g. \ref - take or \ref takeAt). Note that this method only changes properties in \a el. The removal from - the old layout must be done additionally. -*/ -void QCPLayout::releaseElement(QCPLayoutElement *el) -{ - if (el) - { - el->mParentLayout = 0; - el->setParentLayerable(0); - el->setParent(mParentPlot); - // Note: Don't initializeParentPlot(0) here, because layout element will stay in same parent plot - } else - qDebug() << Q_FUNC_INFO << "Null element passed"; -} - -/*! \internal - - This is a helper function for the implementation of \ref updateLayout in subclasses. - - It calculates the sizes of one-dimensional sections with provided constraints on maximum section - sizes, minimum section sizes, relative stretch factors and the final total size of all sections. - - The QVector entries refer to the sections. Thus all QVectors must have the same size. - - \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size - imposed, set all vector values to Qt's QWIDGETSIZE_MAX. - - \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size - imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than - \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, - not exceeding the allowed total size is taken to be more important than not going below minimum - section sizes.) - - \a stretchFactors give the relative proportions of the sections to each other. If all sections - shall be scaled equally, set all values equal. If the first section shall be double the size of - each individual other section, set the first number of \a stretchFactors to double the value of - the other individual values (e.g. {2, 1, 1, 1}). - - \a totalSize is the value that the final section sizes will add up to. Due to rounding, the - actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, - you could distribute the remaining difference on the sections. - - The return value is a QVector containing the section sizes. -*/ -QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const -{ - if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) - { - qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; - return QVector(); - } - if (stretchFactors.isEmpty()) - return QVector(); - int sectionCount = stretchFactors.size(); - QVector sectionSizes(sectionCount); - // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): - int minSizeSum = 0; - for (int i=0; i minimumLockedSections; - QList unfinishedSections; - for (int i=0; i result(sectionCount); - for (int i=0; iminimumOuterSizeHint(); - QSize minOuter = el->minimumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset minimum of 0) - if (minOuter.width() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) - minOuter.rwidth() += el->margins().left() + el->margins().right(); - if (minOuter.height() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) - minOuter.rheight() += el->margins().top() + el->margins().bottom(); - - return QSize(minOuter.width() > 0 ? minOuter.width() : minOuterHint.width(), - minOuter.height() > 0 ? minOuter.height() : minOuterHint.height());; -} - -/*! \internal - - This is a helper function for the implementation of subclasses. - - It returns the maximum size that should finally be used for the outer rect of the passed layout - element \a el. - - It takes into account whether a manual maximum size is set (\ref - QCPLayoutElement::setMaximumSize), which size constraint is set (\ref - QCPLayoutElement::setSizeConstraintRect), as well as the maximum size hint, if no manual maximum - size was set (\ref QCPLayoutElement::maximumOuterSizeHint). -*/ -QSize QCPLayout::getFinalMaximumOuterSize(const QCPLayoutElement *el) -{ - QSize maxOuterHint = el->maximumOuterSizeHint(); - QSize maxOuter = el->maximumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset maximum of QWIDGETSIZE_MAX) - if (maxOuter.width() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) - maxOuter.rwidth() += el->margins().left() + el->margins().right(); - if (maxOuter.height() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) - maxOuter.rheight() += el->margins().top() + el->margins().bottom(); - - return QSize(maxOuter.width() < QWIDGETSIZE_MAX ? maxOuter.width() : maxOuterHint.width(), - maxOuter.height() < QWIDGETSIZE_MAX ? maxOuter.height() : maxOuterHint.height()); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayoutGrid -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLayoutGrid - \brief A layout that arranges child elements in a grid - - Elements are laid out in a grid with configurable stretch factors (\ref setColumnStretchFactor, - \ref setRowStretchFactor) and spacing (\ref setColumnSpacing, \ref setRowSpacing). - - Elements can be added to cells via \ref addElement. The grid is expanded if the specified row or - column doesn't exist yet. Whether a cell contains a valid layout element can be checked with \ref - hasElement, that element can be retrieved with \ref element. If rows and columns that only have - empty cells shall be removed, call \ref simplify. Removal of elements is either done by just - adding the element to a different layout or by using the QCPLayout interface \ref take or \ref - remove. - - If you use \ref addElement(QCPLayoutElement*) without explicit parameters for \a row and \a - column, the grid layout will choose the position according to the current \ref setFillOrder and - the wrapping (\ref setWrap). - - Row and column insertion can be performed with \ref insertRow and \ref insertColumn. -*/ - -/* start documentation of inline functions */ - -/*! \fn int QCPLayoutGrid::rowCount() const - - Returns the number of rows in the layout. - - \see columnCount -*/ - -/*! \fn int QCPLayoutGrid::columnCount() const - - Returns the number of columns in the layout. - - \see rowCount -*/ - -/* end documentation of inline functions */ - -/*! - Creates an instance of QCPLayoutGrid and sets default values. -*/ -QCPLayoutGrid::QCPLayoutGrid() : - mColumnSpacing(5), - mRowSpacing(5), - mWrap(0), - mFillOrder(foRowsFirst) -{ -} - -QCPLayoutGrid::~QCPLayoutGrid() -{ - // clear all child layout elements. This is important because only the specific layouts know how - // to handle removing elements (clear calls virtual removeAt method to do that). - clear(); -} - -/*! - Returns the element in the cell in \a row and \a column. - - Returns 0 if either the row/column is invalid or if the cell is empty. In those cases, a qDebug - message is printed. To check whether a cell exists and isn't empty, use \ref hasElement. - - \see addElement, hasElement -*/ -QCPLayoutElement *QCPLayoutGrid::element(int row, int column) const -{ - if (row >= 0 && row < mElements.size()) - { - if (column >= 0 && column < mElements.first().size()) - { - if (QCPLayoutElement *result = mElements.at(row).at(column)) - return result; - else - qDebug() << Q_FUNC_INFO << "Requested cell is empty. Row:" << row << "Column:" << column; - } else - qDebug() << Q_FUNC_INFO << "Invalid column. Row:" << row << "Column:" << column; - } else - qDebug() << Q_FUNC_INFO << "Invalid row. Row:" << row << "Column:" << column; - return 0; -} - - -/*! \overload - - Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it - is first removed from there. If \a row or \a column don't exist yet, the layout is expanded - accordingly. - - Returns true if the element was added successfully, i.e. if the cell at \a row and \a column - didn't already have an element. - - Use the overload of this method without explicit row/column index to place the element according - to the configured fill order and wrapping settings. - - \see element, hasElement, take, remove -*/ -bool QCPLayoutGrid::addElement(int row, int column, QCPLayoutElement *element) -{ - if (!hasElement(row, column)) - { - if (element && element->layout()) // remove from old layout first - element->layout()->take(element); - expandTo(row+1, column+1); - mElements[row][column] = element; - if (element) - adoptElement(element); - return true; - } else - qDebug() << Q_FUNC_INFO << "There is already an element in the specified row/column:" << row << column; - return false; -} - -/*! \overload - - Adds the \a element to the next empty cell according to the current fill order (\ref - setFillOrder) and wrapping (\ref setWrap). If \a element is already in a layout, it is first - removed from there. If necessary, the layout is expanded to hold the new element. - - Returns true if the element was added successfully. - - \see setFillOrder, setWrap, element, hasElement, take, remove -*/ -bool QCPLayoutGrid::addElement(QCPLayoutElement *element) -{ - int rowIndex = 0; - int colIndex = 0; - if (mFillOrder == foColumnsFirst) - { - while (hasElement(rowIndex, colIndex)) - { - ++colIndex; - if (colIndex >= mWrap && mWrap > 0) - { - colIndex = 0; - ++rowIndex; - } - } - } else - { - while (hasElement(rowIndex, colIndex)) - { - ++rowIndex; - if (rowIndex >= mWrap && mWrap > 0) - { - rowIndex = 0; - ++colIndex; - } - } - } - return addElement(rowIndex, colIndex, element); -} - -/*! - Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't - empty. - - \see element -*/ -bool QCPLayoutGrid::hasElement(int row, int column) -{ - if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) - return mElements.at(row).at(column); - else - return false; -} - -/*! - Sets the stretch \a factor of \a column. - - Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond - their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref - QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref - QCPLayoutElement::setSizeConstraintRect.) - - The default stretch factor of newly created rows/columns is 1. - - \see setColumnStretchFactors, setRowStretchFactor -*/ -void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) -{ - if (column >= 0 && column < columnCount()) - { - if (factor > 0) - mColumnStretchFactors[column] = factor; - else - qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; - } else - qDebug() << Q_FUNC_INFO << "Invalid column:" << column; -} - -/*! - Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. - - Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond - their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref - QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref - QCPLayoutElement::setSizeConstraintRect.) - - The default stretch factor of newly created rows/columns is 1. - - \see setColumnStretchFactor, setRowStretchFactors -*/ -void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) -{ - if (factors.size() == mColumnStretchFactors.size()) - { - mColumnStretchFactors = factors; - for (int i=0; i= 0 && row < rowCount()) - { - if (factor > 0) - mRowStretchFactors[row] = factor; - else - qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; - } else - qDebug() << Q_FUNC_INFO << "Invalid row:" << row; -} - -/*! - Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. - - Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond - their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref - QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref - QCPLayoutElement::setSizeConstraintRect.) - - The default stretch factor of newly created rows/columns is 1. - - \see setRowStretchFactor, setColumnStretchFactors -*/ -void QCPLayoutGrid::setRowStretchFactors(const QList &factors) -{ - if (factors.size() == mRowStretchFactors.size()) - { - mRowStretchFactors = factors; - for (int i=0; i tempElements; - if (rearrange) - { - tempElements.reserve(elCount); - for (int i=0; i()); - mRowStretchFactors.append(1); - } - // go through rows and expand columns as necessary: - int newColCount = qMax(columnCount(), newColumnCount); - for (int i=0; i rowCount()) - newIndex = rowCount(); - - mRowStretchFactors.insert(newIndex, 1); - QList newRow; - for (int col=0; col columnCount()) - newIndex = columnCount(); - - mColumnStretchFactors.insert(newIndex, 1); - for (int row=0; row= 0 && row < rowCount()) - { - if (column >= 0 && column < columnCount()) - { - switch (mFillOrder) - { - case foRowsFirst: return column*rowCount() + row; - case foColumnsFirst: return row*columnCount() + column; - } - } else - qDebug() << Q_FUNC_INFO << "row index out of bounds:" << row; - } else - qDebug() << Q_FUNC_INFO << "column index out of bounds:" << column; - return 0; -} - -/*! - Converts the linear index to row and column indices and writes the result to \a row and \a - column. - - The way the cells are indexed depends on \ref setFillOrder. If it is \ref foRowsFirst, the - indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices - increase top to bottom and then left to right. - - If there are no cells (i.e. column or row count is zero), sets \a row and \a column to -1. - - For the retrieved \a row and \a column to be valid, the passed \a index must be valid itself, - i.e. greater or equal to zero and smaller than the current \ref elementCount. - - \see rowColToIndex -*/ -void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const -{ - row = -1; - column = -1; - const int nCols = columnCount(); - const int nRows = rowCount(); - if (nCols == 0 || nRows == 0) - return; - if (index < 0 || index >= elementCount()) - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return; - } - - switch (mFillOrder) - { - case foRowsFirst: - { - column = index / nRows; - row = index % nRows; - break; - } - case foColumnsFirst: - { - row = index / nCols; - column = index % nCols; - break; - } - } -} - -/* inherits documentation from base class */ -void QCPLayoutGrid::updateLayout() -{ - QVector minColWidths, minRowHeights, maxColWidths, maxRowHeights; - getMinimumRowColSizes(&minColWidths, &minRowHeights); - getMaximumRowColSizes(&maxColWidths, &maxRowHeights); - - int totalRowSpacing = (rowCount()-1) * mRowSpacing; - int totalColSpacing = (columnCount()-1) * mColumnSpacing; - QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); - QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); - - // go through cells and set rects accordingly: - int yOffset = mRect.top(); - for (int row=0; row 0) - yOffset += rowHeights.at(row-1)+mRowSpacing; - int xOffset = mRect.left(); - for (int col=0; col 0) - xOffset += colWidths.at(col-1)+mColumnSpacing; - if (mElements.at(row).at(col)) - mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row))); - } - } -} - -/*! - \seebaseclassmethod - - Note that the association of the linear \a index to the row/column based cells depends on the - current setting of \ref setFillOrder. - - \see rowColToIndex -*/ -QCPLayoutElement *QCPLayoutGrid::elementAt(int index) const -{ - if (index >= 0 && index < elementCount()) - { - int row, col; - indexToRowCol(index, row, col); - return mElements.at(row).at(col); - } else - return 0; -} - -/*! - \seebaseclassmethod - - Note that the association of the linear \a index to the row/column based cells depends on the - current setting of \ref setFillOrder. - - \see rowColToIndex -*/ -QCPLayoutElement *QCPLayoutGrid::takeAt(int index) -{ - if (QCPLayoutElement *el = elementAt(index)) - { - releaseElement(el); - int row, col; - indexToRowCol(index, row, col); - mElements[row][col] = 0; - return el; - } else - { - qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; - return 0; - } -} - -/* inherits documentation from base class */ -bool QCPLayoutGrid::take(QCPLayoutElement *element) -{ - if (element) - { - for (int i=0; i QCPLayoutGrid::elements(bool recursive) const -{ - QList result; - const int elCount = elementCount(); -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - result.reserve(elCount); -#endif - for (int i=0; ielements(recursive); - } - } - return result; -} - -/*! - Simplifies the layout by collapsing rows and columns which only contain empty cells. -*/ -void QCPLayoutGrid::simplify() -{ - // remove rows with only empty cells: - for (int row=rowCount()-1; row>=0; --row) - { - bool hasElements = false; - for (int col=0; col=0; --col) - { - bool hasElements = false; - for (int row=0; row minColWidths, minRowHeights; - getMinimumRowColSizes(&minColWidths, &minRowHeights); - QSize result(0, 0); - for (int i=0; i maxColWidths, maxRowHeights; - getMaximumRowColSizes(&maxColWidths, &maxRowHeights); - - QSize result(0, 0); - for (int i=0; i QWIDGETSIZE_MAX) - result.setHeight(QWIDGETSIZE_MAX); - if (result.width() > QWIDGETSIZE_MAX) - result.setWidth(QWIDGETSIZE_MAX); - return result; -} - -/*! \internal - - Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights - respectively. - - The minimum height of a row is the largest minimum height of any element's outer rect in that - row. The minimum width of a column is the largest minimum width of any element's outer rect in - that column. - - This is a helper function for \ref updateLayout. - - \see getMaximumRowColSizes -*/ -void QCPLayoutGrid::getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const -{ - *minColWidths = QVector(columnCount(), 0); - *minRowHeights = QVector(rowCount(), 0); - for (int row=0; rowat(col) < minSize.width()) - (*minColWidths)[col] = minSize.width(); - if (minRowHeights->at(row) < minSize.height()) - (*minRowHeights)[row] = minSize.height(); - } - } - } -} - -/*! \internal - - Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights - respectively. - - The maximum height of a row is the smallest maximum height of any element's outer rect in that - row. The maximum width of a column is the smallest maximum width of any element's outer rect in - that column. - - This is a helper function for \ref updateLayout. - - \see getMinimumRowColSizes -*/ -void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const -{ - *maxColWidths = QVector(columnCount(), QWIDGETSIZE_MAX); - *maxRowHeights = QVector(rowCount(), QWIDGETSIZE_MAX); - for (int row=0; rowat(col) > maxSize.width()) - (*maxColWidths)[col] = maxSize.width(); - if (maxRowHeights->at(row) > maxSize.height()) - (*maxRowHeights)[row] = maxSize.height(); - } - } - } -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLayoutInset -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPLayoutInset - \brief A layout that places child elements aligned to the border or arbitrarily positioned - - Elements are placed either aligned to the border or at arbitrary position in the area of the - layout. Which placement applies is controlled with the \ref InsetPlacement (\ref - setInsetPlacement). - - Elements are added via \ref addElement(QCPLayoutElement *element, Qt::Alignment alignment) or - addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset - placement will default to \ref ipBorderAligned and the element will be aligned according to the - \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at - arbitrary position and size, defined by \a rect. - - The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively. - - This is the layout that every QCPAxisRect has as \ref QCPAxisRect::insetLayout. -*/ - -/* start documentation of inline functions */ - -/*! \fn virtual void QCPLayoutInset::simplify() - - The QCPInsetLayout does not need simplification since it can never have empty cells due to its - linear index structure. This method does nothing. -*/ - -/* end documentation of inline functions */ - -/*! - Creates an instance of QCPLayoutInset and sets default values. -*/ -QCPLayoutInset::QCPLayoutInset() -{ -} - -QCPLayoutInset::~QCPLayoutInset() -{ - // clear all child layout elements. This is important because only the specific layouts know how - // to handle removing elements (clear calls virtual removeAt method to do that). - clear(); -} - -/*! - Returns the placement type of the element with the specified \a index. -*/ -QCPLayoutInset::InsetPlacement QCPLayoutInset::insetPlacement(int index) const -{ - if (elementAt(index)) - return mInsetPlacement.at(index); - else - { - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; - return ipFree; - } -} - -/*! - Returns the alignment of the element with the specified \a index. The alignment only has a - meaning, if the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned. -*/ -Qt::Alignment QCPLayoutInset::insetAlignment(int index) const -{ - if (elementAt(index)) - return mInsetAlignment.at(index); - else - { - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; - return 0; - } -} - -/*! - Returns the rect of the element with the specified \a index. The rect only has a - meaning, if the inset placement (\ref setInsetPlacement) is \ref ipFree. -*/ -QRectF QCPLayoutInset::insetRect(int index) const -{ - if (elementAt(index)) - return mInsetRect.at(index); - else - { - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; - return QRectF(); - } -} - -/*! - Sets the inset placement type of the element with the specified \a index to \a placement. - - \see InsetPlacement -*/ -void QCPLayoutInset::setInsetPlacement(int index, QCPLayoutInset::InsetPlacement placement) -{ - if (elementAt(index)) - mInsetPlacement[index] = placement; - else - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; -} - -/*! - If the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned, this function - is used to set the alignment of the element with the specified \a index to \a alignment. - - \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, - Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other - alignment flags will be ignored. -*/ -void QCPLayoutInset::setInsetAlignment(int index, Qt::Alignment alignment) -{ - if (elementAt(index)) - mInsetAlignment[index] = alignment; - else - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; -} - -/*! - If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the - position and size of the element with the specified \a index to \a rect. - - \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) - will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right - corner of the layout, with 35% width and height of the parent layout. - - Note that the minimum and maximum sizes of the embedded element (\ref - QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize) are enforced. -*/ -void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) -{ - if (elementAt(index)) - mInsetRect[index] = rect; - else - qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; -} - -/* inherits documentation from base class */ -void QCPLayoutInset::updateLayout() -{ - for (int i=0; i finalMaxSize.width()) - insetRect.setWidth(finalMaxSize.width()); - if (insetRect.size().height() > finalMaxSize.height()) - insetRect.setHeight(finalMaxSize.height()); - } else if (mInsetPlacement.at(i) == ipBorderAligned) - { - insetRect.setSize(finalMinSize); - Qt::Alignment al = mInsetAlignment.at(i); - if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(rect().x()); - else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(rect().x()+rect().width()); - else insetRect.moveLeft(rect().x()+rect().width()*0.5-finalMinSize.width()*0.5); // default to Qt::AlignHCenter - if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(rect().y()); - else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(rect().y()+rect().height()); - else insetRect.moveTop(rect().y()+rect().height()*0.5-finalMinSize.height()*0.5); // default to Qt::AlignVCenter - } - mElements.at(i)->setOuterRect(insetRect); - } -} - -/* inherits documentation from base class */ -int QCPLayoutInset::elementCount() const -{ - return mElements.size(); -} - -/* inherits documentation from base class */ -QCPLayoutElement *QCPLayoutInset::elementAt(int index) const -{ - if (index >= 0 && index < mElements.size()) - return mElements.at(index); - else - return 0; -} - -/* inherits documentation from base class */ -QCPLayoutElement *QCPLayoutInset::takeAt(int index) -{ - if (QCPLayoutElement *el = elementAt(index)) - { - releaseElement(el); - mElements.removeAt(index); - mInsetPlacement.removeAt(index); - mInsetAlignment.removeAt(index); - mInsetRect.removeAt(index); - return el; - } else - { - qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; - return 0; - } -} - -/* inherits documentation from base class */ -bool QCPLayoutInset::take(QCPLayoutElement *element) -{ - if (element) - { - for (int i=0; irealVisibility() && mElements.at(i)->selectTest(pos, onlySelectable) >= 0) - return mParentPlot->selectionTolerance()*0.99; - } - return -1; -} - -/*! - Adds the specified \a element to the layout as an inset aligned at the border (\ref - setInsetAlignment is initialized with \ref ipBorderAligned). The alignment is set to \a - alignment. - - \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, - Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other - alignment flags will be ignored. - - \see addElement(QCPLayoutElement *element, const QRectF &rect) -*/ -void QCPLayoutInset::addElement(QCPLayoutElement *element, Qt::Alignment alignment) -{ - if (element) - { - if (element->layout()) // remove from old layout first - element->layout()->take(element); - mElements.append(element); - mInsetPlacement.append(ipBorderAligned); - mInsetAlignment.append(alignment); - mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4)); - adoptElement(element); - } else - qDebug() << Q_FUNC_INFO << "Can't add null element"; -} - -/*! - Adds the specified \a element to the layout as an inset with free positioning/sizing (\ref - setInsetAlignment is initialized with \ref ipFree). The position and size is set to \a - rect. - - \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) - will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right - corner of the layout, with 35% width and height of the parent layout. - - \see addElement(QCPLayoutElement *element, Qt::Alignment alignment) -*/ -void QCPLayoutInset::addElement(QCPLayoutElement *element, const QRectF &rect) -{ - if (element) - { - if (element->layout()) // remove from old layout first - element->layout()->take(element); - mElements.append(element); - mInsetPlacement.append(ipFree); - mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop); - mInsetRect.append(rect); - adoptElement(element); - } else - qDebug() << Q_FUNC_INFO << "Can't add null element"; -} -/* end of 'src/layout.cpp' */ - - -/* including file 'src/lineending.cpp', size 11536 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLineEnding -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLineEnding - \brief Handles the different ending decorations for line-like items - - \image html QCPLineEnding.png "The various ending styles currently supported" - - For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine - has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. - - The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can - be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of - the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. - For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite - directions, e.g. "outward". This can be changed by \ref setInverted, which would make the - respective arrow point inward. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify a - QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. - \snippet documentation/doc-code-snippets/mainwindow.cpp qcplineending-sethead -*/ - -/*! - Creates a QCPLineEnding instance with default values (style \ref esNone). -*/ -QCPLineEnding::QCPLineEnding() : - mStyle(esNone), - mWidth(8), - mLength(10), - mInverted(false) -{ -} - -/*! - Creates a QCPLineEnding instance with the specified values. -*/ -QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : - mStyle(style), - mWidth(width), - mLength(length), - mInverted(inverted) -{ -} - -/*! - Sets the style of the ending decoration. -*/ -void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) -{ - mStyle = style; -} - -/*! - Sets the width of the ending decoration, if the style supports it. On arrows, for example, the - width defines the size perpendicular to the arrow's pointing direction. - - \see setLength -*/ -void QCPLineEnding::setWidth(double width) -{ - mWidth = width; -} - -/*! - Sets the length of the ending decoration, if the style supports it. On arrows, for example, the - length defines the size in pointing direction. - - \see setWidth -*/ -void QCPLineEnding::setLength(double length) -{ - mLength = length; -} - -/*! - Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point - inward when \a inverted is set to true. - - Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or - discs, this doesn't make a difference. However, asymmetric styles like \ref esHalfBar are - affected by it, which can be used to control to which side the half bar points to. -*/ -void QCPLineEnding::setInverted(bool inverted) -{ - mInverted = inverted; -} - -/*! \internal - - Returns the maximum pixel radius the ending decoration might cover, starting from the position - the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). - - This is relevant for clipping. Only omit painting of the decoration when the position where the - decoration is supposed to be drawn is farther away from the clipping rect than the returned - distance. -*/ -double QCPLineEnding::boundingDistance() const -{ - switch (mStyle) - { - case esNone: - return 0; - - case esFlatArrow: - case esSpikeArrow: - case esLineArrow: - case esSkewedBar: - return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length - - case esDisc: - case esSquare: - case esDiamond: - case esBar: - case esHalfBar: - return mWidth*1.42; // items that only have a width -> width*sqrt(2) - - } - return 0; -} - -/*! - Starting from the origin of this line ending (which is style specific), returns the length - covered by the line ending symbol, in backward direction. - - For example, the \ref esSpikeArrow has a shorter real length than a \ref esFlatArrow, even if - both have the same \ref setLength value, because the spike arrow has an inward curved back, which - reduces the length along its center axis (the drawing origin for arrows is at the tip). - - This function is used for precise, style specific placement of line endings, for example in - QCPAxes. -*/ -double QCPLineEnding::realLength() const -{ - switch (mStyle) - { - case esNone: - case esLineArrow: - case esSkewedBar: - case esBar: - case esHalfBar: - return 0; - - case esFlatArrow: - return mLength; - - case esDisc: - case esSquare: - case esDiamond: - return mWidth*0.5; - - case esSpikeArrow: - return mLength*0.8; - } - return 0; -} - -/*! \internal - - Draws the line ending with the specified \a painter at the position \a pos. The direction of the - line ending is controlled with \a dir. -*/ -void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const -{ - if (mStyle == esNone) - return; - - QCPVector2D lengthVec = dir.normalized() * mLength*(mInverted ? -1 : 1); - if (lengthVec.isNull()) - lengthVec = QCPVector2D(1, 0); - QCPVector2D widthVec = dir.normalized().perpendicular() * mWidth*0.5*(mInverted ? -1 : 1); - - QPen penBackup = painter->pen(); - QBrush brushBackup = painter->brush(); - QPen miterPen = penBackup; - miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey - QBrush brush(painter->pen().color(), Qt::SolidPattern); - switch (mStyle) - { - case esNone: break; - case esFlatArrow: - { - QPointF points[3] = {pos.toPointF(), - (pos-lengthVec+widthVec).toPointF(), - (pos-lengthVec-widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->setBrush(brush); - painter->drawConvexPolygon(points, 3); - painter->setBrush(brushBackup); - painter->setPen(penBackup); - break; - } - case esSpikeArrow: - { - QPointF points[4] = {pos.toPointF(), - (pos-lengthVec+widthVec).toPointF(), - (pos-lengthVec*0.8).toPointF(), - (pos-lengthVec-widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->setBrush(brush); - painter->drawConvexPolygon(points, 4); - painter->setBrush(brushBackup); - painter->setPen(penBackup); - break; - } - case esLineArrow: - { - QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), - pos.toPointF(), - (pos-lengthVec-widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->drawPolyline(points, 3); - painter->setPen(penBackup); - break; - } - case esDisc: - { - painter->setBrush(brush); - painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); - painter->setBrush(brushBackup); - break; - } - case esSquare: - { - QCPVector2D widthVecPerp = widthVec.perpendicular(); - QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), - (pos-widthVecPerp-widthVec).toPointF(), - (pos+widthVecPerp-widthVec).toPointF(), - (pos+widthVecPerp+widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->setBrush(brush); - painter->drawConvexPolygon(points, 4); - painter->setBrush(brushBackup); - painter->setPen(penBackup); - break; - } - case esDiamond: - { - QCPVector2D widthVecPerp = widthVec.perpendicular(); - QPointF points[4] = {(pos-widthVecPerp).toPointF(), - (pos-widthVec).toPointF(), - (pos+widthVecPerp).toPointF(), - (pos+widthVec).toPointF() - }; - painter->setPen(miterPen); - painter->setBrush(brush); - painter->drawConvexPolygon(points, 4); - painter->setBrush(brushBackup); - painter->setPen(penBackup); - break; - } - case esBar: - { - painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); - break; - } - case esHalfBar: - { - painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); - break; - } - case esSkewedBar: - { - if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic)) - { - // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line - painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)).toPointF(), - (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)).toPointF()); - } else - { - // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly - painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(), - (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF()); - } - break; - } - } -} - -/*! \internal - \overload - - Draws the line ending. The direction is controlled with the \a angle parameter in radians. -*/ -void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const -{ - draw(painter, pos, QCPVector2D(qCos(angle), qSin(angle))); -} -/* end of 'src/lineending.cpp' */ - - -/* including file 'src/axis/axisticker.cpp', size 18664 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTicker -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTicker - \brief The base class tick generator used by QCPAxis to create tick positions and tick labels - - Each QCPAxis has an internal QCPAxisTicker (or a subclass) in order to generate tick positions - and tick labels for the current axis range. The ticker of an axis can be set via \ref - QCPAxis::setTicker. Since that method takes a QSharedPointer, multiple - axes can share the same ticker instance. - - This base class generates normal tick coordinates and numeric labels for linear axes. It picks a - reasonable tick step (the separation between ticks) which results in readable tick labels. The - number of ticks that should be approximately generated can be set via \ref setTickCount. - Depending on the current tick step strategy (\ref setTickStepStrategy), the algorithm either - sacrifices readability to better match the specified tick count (\ref - QCPAxisTicker::tssMeetTickCount) or relaxes the tick count in favor of better tick steps (\ref - QCPAxisTicker::tssReadability), which is the default. - - The following more specialized axis ticker subclasses are available, see details in the - respective class documentation: - -
- - - - - - - -
QCPAxisTickerFixed\image html axisticker-fixed.png
QCPAxisTickerLog\image html axisticker-log.png
QCPAxisTickerPi\image html axisticker-pi.png
QCPAxisTickerText\image html axisticker-text.png
QCPAxisTickerDateTime\image html axisticker-datetime.png
QCPAxisTickerTime\image html axisticker-time.png - \image html axisticker-time2.png
-
- - \section axisticker-subclassing Creating own axis tickers - - Creating own axis tickers can be achieved very easily by sublassing QCPAxisTicker and - reimplementing some or all of the available virtual methods. - - In the simplest case you might wish to just generate different tick steps than the other tickers, - so you only reimplement the method \ref getTickStep. If you additionally want control over the - string that will be shown as tick label, reimplement \ref getTickLabel. - - If you wish to have complete control, you can generate the tick vectors and tick label vectors - yourself by reimplementing \ref createTickVector and \ref createLabelVector. The default - implementations use the previously mentioned virtual methods \ref getTickStep and \ref - getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case - of unequal tick steps, the method \ref getTickStep loses its usefulness and can be ignored. - - The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick - placement control is obtained by reimplementing \ref createSubTickVector. - - See the documentation of all these virtual methods in QCPAxisTicker for detailed information - about the parameters and expected return values. -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTicker::QCPAxisTicker() : - mTickStepStrategy(tssReadability), - mTickCount(5), - mTickOrigin(0) -{ -} - -QCPAxisTicker::~QCPAxisTicker() -{ - -} - -/*! - Sets which strategy the axis ticker follows when choosing the size of the tick step. For the - available strategies, see \ref TickStepStrategy. -*/ -void QCPAxisTicker::setTickStepStrategy(QCPAxisTicker::TickStepStrategy strategy) -{ - mTickStepStrategy = strategy; -} - -/*! - Sets how many ticks this ticker shall aim to generate across the axis range. Note that \a count - is not guaranteed to be matched exactly, as generating readable tick intervals may conflict with - the requested number of ticks. - - Whether the readability has priority over meeting the requested \a count can be specified with - \ref setTickStepStrategy. -*/ -void QCPAxisTicker::setTickCount(int count) -{ - if (count > 0) - mTickCount = count; - else - qDebug() << Q_FUNC_INFO << "tick count must be greater than zero:" << count; -} - -/*! - Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a - concept and doesn't need to be inside the currently visible axis range. - - By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick - step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be - {-4, 1, 6, 11, 16,...}. -*/ -void QCPAxisTicker::setTickOrigin(double origin) -{ - mTickOrigin = origin; -} - -/*! - This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks), - tick label strings (\a tickLabels) and sub tick coordinates (\a subTicks). - - The ticks are generated for the specified \a range. The generated labels typically follow the - specified \a locale, \a formatChar and number \a precision, however this might be different (or - even irrelevant) for certain QCPAxisTicker subclasses. - - The output parameter \a ticks is filled with the generated tick positions in axis coordinates. - The output parameters \a subTicks and \a tickLabels are optional (set them to 0 if not needed) - and are respectively filled with sub tick coordinates, and tick label strings belonging to \a - ticks by index. -*/ -void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels) -{ - // generate (major) ticks: - double tickStep = getTickStep(range); - ticks = createTickVector(tickStep, range); - trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more) - - // generate sub ticks between major ticks: - if (subTicks) - { - if (ticks.size() > 0) - { - *subTicks = createSubTickVector(getSubTickCount(tickStep), ticks); - trimTicks(range, *subTicks, false); - } else - *subTicks = QVector(); - } - - // finally trim also outliers (no further clipping happens in axis drawing): - trimTicks(range, ticks, false); - // generate labels for visible ticks if requested: - if (tickLabels) - *tickLabels = createLabelVector(ticks, locale, formatChar, precision); -} - -/*! \internal - - Takes the entire currently visible axis range and returns a sensible tick step in - order to provide readable tick labels as well as a reasonable number of tick counts (see \ref - setTickCount, \ref setTickStepStrategy). - - If a QCPAxisTicker subclass only wants a different tick step behaviour than the default - implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper - function. -*/ -double QCPAxisTicker::getTickStep(const QCPRange &range) -{ - double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - return cleanMantissa(exactStep); -} - -/*! \internal - - Takes the \a tickStep, i.e. the distance between two consecutive ticks, and returns - an appropriate number of sub ticks for that specific tick step. - - Note that a returned sub tick count of e.g. 4 will split each tick interval into 5 sections. -*/ -int QCPAxisTicker::getSubTickCount(double tickStep) -{ - int result = 1; // default to 1, if no proper value can be found - - // separate integer and fractional part of mantissa: - double epsilon = 0.01; - double intPartf; - int intPart; - double fracPart = modf(getMantissa(tickStep), &intPartf); - intPart = intPartf; - - // handle cases with (almost) integer mantissa: - if (fracPart < epsilon || 1.0-fracPart < epsilon) - { - if (1.0-fracPart < epsilon) - ++intPart; - switch (intPart) - { - case 1: result = 4; break; // 1.0 -> 0.2 substep - case 2: result = 3; break; // 2.0 -> 0.5 substep - case 3: result = 2; break; // 3.0 -> 1.0 substep - case 4: result = 3; break; // 4.0 -> 1.0 substep - case 5: result = 4; break; // 5.0 -> 1.0 substep - case 6: result = 2; break; // 6.0 -> 2.0 substep - case 7: result = 6; break; // 7.0 -> 1.0 substep - case 8: result = 3; break; // 8.0 -> 2.0 substep - case 9: result = 2; break; // 9.0 -> 3.0 substep - } - } else - { - // handle cases with significantly fractional mantissa: - if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa - { - switch (intPart) - { - case 1: result = 2; break; // 1.5 -> 0.5 substep - case 2: result = 4; break; // 2.5 -> 0.5 substep - case 3: result = 4; break; // 3.5 -> 0.7 substep - case 4: result = 2; break; // 4.5 -> 1.5 substep - case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with default getTickStep from here on) - case 6: result = 4; break; // 6.5 -> 1.3 substep - case 7: result = 2; break; // 7.5 -> 2.5 substep - case 8: result = 4; break; // 8.5 -> 1.7 substep - case 9: result = 4; break; // 9.5 -> 1.9 substep - } - } - // if mantissa fraction isn't 0.0 or 0.5, don't bother finding good sub tick marks, leave default - } - - return result; -} - -/*! \internal - - This method returns the tick label string as it should be printed under the \a tick coordinate. - If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a - precision. - - If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is - enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will - be formatted accordingly using multiplication symbol and superscript during rendering of the - label automatically. -*/ -QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) -{ - return locale.toString(tick, formatChar.toLatin1(), precision); -} - -/*! \internal - - Returns a vector containing all coordinates of sub ticks that should be drawn. It generates \a - subTickCount sub ticks between each tick pair given in \a ticks. - - If a QCPAxisTicker subclass needs maximal control over the generated sub ticks, it should - reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to - base its result on \a subTickCount or \a ticks. -*/ -QVector QCPAxisTicker::createSubTickVector(int subTickCount, const QVector &ticks) -{ - QVector result; - if (subTickCount <= 0 || ticks.size() < 2) - return result; - - result.reserve((ticks.size()-1)*subTickCount); - for (int i=1; i QCPAxisTicker::createTickVector(double tickStep, const QCPRange &range) -{ - QVector result; - // Generate tick positions according to tickStep: - qint64 firstStep = floor((range.lower-mTickOrigin)/tickStep); // do not use qFloor here, or we'll lose 64 bit precision - qint64 lastStep = ceil((range.upper-mTickOrigin)/tickStep); // do not use qCeil here, or we'll lose 64 bit precision - int tickcount = lastStep-firstStep+1; - if (tickcount < 0) tickcount = 0; - result.resize(tickcount); - for (int i=0; i QCPAxisTicker::createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision) -{ - QVector result; - result.reserve(ticks.size()); - for (int i=0; i &ticks, bool keepOneOutlier) const -{ - bool lowFound = false; - bool highFound = false; - int lowIndex = 0; - int highIndex = -1; - - for (int i=0; i < ticks.size(); ++i) - { - if (ticks.at(i) >= range.lower) - { - lowFound = true; - lowIndex = i; - break; - } - } - for (int i=ticks.size()-1; i >= 0; --i) - { - if (ticks.at(i) <= range.upper) - { - highFound = true; - highIndex = i; - break; - } - } - - if (highFound && lowFound) - { - int trimFront = qMax(0, lowIndex-(keepOneOutlier ? 1 : 0)); - int trimBack = qMax(0, ticks.size()-(keepOneOutlier ? 2 : 1)-highIndex); - if (trimFront > 0 || trimBack > 0) - ticks = ticks.mid(trimFront, ticks.size()-trimFront-trimBack); - } else // all ticks are either all below or all above the range - ticks.clear(); -} - -/*! \internal - - Returns the coordinate contained in \a candidates which is closest to the provided \a target. - - This method assumes \a candidates is not empty and sorted in ascending order. -*/ -double QCPAxisTicker::pickClosest(double target, const QVector &candidates) const -{ - if (candidates.size() == 1) - return candidates.first(); - QVector::const_iterator it = std::lower_bound(candidates.constBegin(), candidates.constEnd(), target); - if (it == candidates.constEnd()) - return *(it-1); - else if (it == candidates.constBegin()) - return *it; - else - return target-*(it-1) < *it-target ? *(it-1) : *it; -} - -/*! \internal - - Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also - returns the magnitude of \a input as a power of 10. - - For example, an input of 142.6 will return a mantissa of 1.426 and a magnitude of 100. -*/ -double QCPAxisTicker::getMantissa(double input, double *magnitude) const -{ - const double mag = qPow(10.0, qFloor(qLn(input)/qLn(10.0))); - if (magnitude) *magnitude = mag; - return input/mag; -} - -/*! \internal - - Returns a number that is close to \a input but has a clean, easier human readable mantissa. How - strongly the mantissa is altered, and thus how strong the result deviates from the original \a - input, depends on the current tick step strategy (see \ref setTickStepStrategy). -*/ -double QCPAxisTicker::cleanMantissa(double input) const -{ - double magnitude; - const double mantissa = getMantissa(input, &magnitude); - switch (mTickStepStrategy) - { - case tssReadability: - { - return pickClosest(mantissa, QVector() << 1.0 << 2.0 << 2.5 << 5.0 << 10.0)*magnitude; - } - case tssMeetTickCount: - { - // this gives effectively a mantissa of 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0 - if (mantissa <= 5.0) - return (int)(mantissa*2)/2.0*magnitude; // round digit after decimal point to 0.5 - else - return (int)(mantissa/2.0)*2.0*magnitude; // round to first digit in multiples of 2 - } - } - return input; -} -/* end of 'src/axis/axisticker.cpp' */ - - -/* including file 'src/axis/axistickerdatetime.cpp', size 14443 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerDateTime -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerDateTime - \brief Specialized axis ticker for calendar dates and times as axis ticks - - \image html axisticker-datetime.png - - This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The - plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00 - UTC). This is also used for example by QDateTime in the toTime_t()/setTime_t() methods - with a precision of one second. Since Qt 4.7, millisecond accuracy can be obtained from QDateTime - by using QDateTime::fromMSecsSinceEpoch()/1000.0. The static methods \ref dateTimeToKey - and \ref keyToDateTime conveniently perform this conversion achieving a precision of one - millisecond on all Qt versions. - - The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat. - If a different time spec (time zone) shall be used, see \ref setDateTimeSpec. - - This ticker produces unequal tick spacing in order to provide intuitive date and time-of-day - ticks. For example, if the axis range spans a few years such that there is one tick per year, - ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years, - will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in - the image above: even though the number of days varies month by month, this ticker generates - ticks on the same day of each month. - - If you would like to change the date/time that is used as a (mathematical) starting date for the - ticks, use the \ref setTickOrigin(const QDateTime &origin) method overload, which takes a - QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at - 9:45 of every year. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickerdatetime-creation - - \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and - milliseconds, and are not interested in the intricacies of real calendar dates with months and - (leap) years, have a look at QCPAxisTickerTime instead. -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerDateTime::QCPAxisTickerDateTime() : - mDateTimeFormat(QLatin1String("hh:mm:ss\ndd.MM.yy")), - mDateTimeSpec(Qt::LocalTime), - mDateStrategy(dsNone) -{ - setTickCount(4); -} - -/*! - Sets the format in which dates and times are displayed as tick labels. For details about the \a - format string, see the documentation of QDateTime::toString(). - - Newlines can be inserted with "\n". - - \see setDateTimeSpec -*/ -void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) -{ - mDateTimeFormat = format; -} - -/*! - Sets the time spec that is used for creating the tick labels from corresponding dates/times. - - The default value of QDateTime objects (and also QCPAxisTickerDateTime) is - Qt::LocalTime. However, if the date time values passed to QCustomPlot (e.g. in the form - of axis ranges or keys of a plottable) are given in the UTC spec, set \a spec to Qt::UTC - to get the correct axis labels. - - \see setDateTimeFormat -*/ -void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) -{ - mDateTimeSpec = spec; -} - -/*! - Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970, - 00:00 UTC). For the date time ticker it might be more intuitive to use the overload which - directly takes a QDateTime, see \ref setTickOrigin(const QDateTime &origin). - - This is useful to define the month/day/time recurring at greater tick interval steps. For - example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick - per year, the ticks will end up on 15. July at 9:45 of every year. -*/ -void QCPAxisTickerDateTime::setTickOrigin(double origin) -{ - QCPAxisTicker::setTickOrigin(origin); -} - -/*! - Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) as a QDateTime \a origin. - - This is useful to define the month/day/time recurring at greater tick interval steps. For - example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick - per year, the ticks will end up on 15. July at 9:45 of every year. -*/ -void QCPAxisTickerDateTime::setTickOrigin(const QDateTime &origin) -{ - setTickOrigin(dateTimeToKey(origin)); -} - -/*! \internal - - Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly, - monthly, bi-monthly, etc. - - Note that this tick step isn't used exactly when generating the tick vector in \ref - createTickVector, but only as a guiding value requiring some correction for each individual tick - interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day - in the month to the last day in the previous month from tick to tick, due to the non-uniform - length of months. The same problem arises with leap years. - - \seebaseclassmethod -*/ -double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) -{ - double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - - mDateStrategy = dsNone; - if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds - { - result = cleanMantissa(result); - } else if (result < 86400*30437.5*12) // below a year - { -// result = pickClosest(result, QVector() -// << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5*60 << 5*60 << 10*60 << 15*60 << 30*60 << 60*60 // second, minute, hour range -// << 3600*2 << 3600*3 << 3600*6 << 3600*12 << 3600*24 // hour to day range -// << 86400*2 << 86400*5 << 86400*7 << 86400*14 << 86400*30.4375 << 86400*30.4375*2 << 86400*30.4375*3 << 86400*30.4375*6 << 86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) - result = pickClosest(result, QVector() - << 1000 << 1000*2.5 << 1000*5 << 1000*10 << 1000*15 << 1000*30 << 1000*60 << 1000*2.5*60 << 1000*5*60 << 1000*10*60 << 1000*15*60 << 1000*30*60 << 1000*60*60 // second, minute, hour range - << 1000*3600*2 << 1000*3600*3 << 1000*3600*6 << 1000*3600*12 << 1000*3600*24 // hour to day range - << 1000*86400*2 << 1000*86400*5 << 1000*86400*7 << 1000*86400*14 << 1000*86400*30.4375 << 1000*86400*30.4375*2 << 1000*86400*30.4375*3 << 1000*86400*30.4375*6 << 1000*86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) - if (result > 86400*30437.5-1) // month tick intervals or larger - mDateStrategy = dsUniformDayInMonth; - else if (result > 3600*24*1000-1) // day tick intervals or larger - mDateStrategy = dsUniformTimeInDay; - } else // more than a year, go back to normal clean mantissa algorithm but in units of years - { - const double secondsPerYear = 86400*30437.5*12; // average including leap years - result = cleanMantissa(result/secondsPerYear)*secondsPerYear; - mDateStrategy = dsUniformDayInMonth; - } - return result; -} - -/*! \internal - - Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly, - monthly, bi-monthly, etc. - - \seebaseclassmethod -*/ -int QCPAxisTickerDateTime::getSubTickCount(double tickStep) -{ - int result = QCPAxisTicker::getSubTickCount(tickStep); - switch (qRound64(tickStep)) // hand chosen subticks for specific minute/hour/day/week/month range (as specified in getTickStep) - { - case 5*1000*60: result = 4; break; - case 10*1000*60: result = 1; break; - case 15*1000*60: result = 2; break; - case 30*1000*60: result = 1; break; - case 60*1000*60: result = 3; break; - case 3600*1000*2: result = 3; break; - case 3600*1000*3: result = 2; break; - case 3600*1000*6: result = 1; break; - case 3600*1000*12: result = 3; break; - case 3600*1000*24: result = 3; break; - case 86400*1000*2: result = 1; break; - case 86400*1000*5: result = 4; break; - case 86400*1000*7: result = 6; break; - case 86400*1000*14: result = 1; break; - case (qint64)(86400*1000*30.4375+0.5): result = 3; break; - case (qint64)(86400*1000*30.4375*2+0.5): result = 1; break; - case (qint64)(86400*1000*30.4375*3+0.5): result = 2; break; - case (qint64)(86400*1000*30.4375*6+0.5): result = 5; break; - case (qint64)(86400*1000*30.4375*12+0.5): result = 3; break; - } - return result; -} - -/*! \internal - - Generates a date/time tick label for tick coordinate \a tick, based on the currently set format - (\ref setDateTimeFormat) and time spec (\ref setDateTimeSpec). - - \seebaseclassmethod -*/ -QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) -{ - Q_UNUSED(precision) - Q_UNUSED(formatChar) - return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); -} - -/*! \internal - - Uses the passed \a tickStep as a guiding value and applies corrections in order to obtain - non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month. - - \seebaseclassmethod -*/ -QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) -{ - QVector result = QCPAxisTicker::createTickVector(tickStep, range); - if (!result.isEmpty()) - { - if (mDateStrategy == dsUniformTimeInDay) - { - QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible - QDateTime tickDateTime; - for (int i=0; i 15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day - tickDateTime = tickDateTime.addMonths(-1); - tickDateTime.setDate(QDate(tickDateTime.date().year(), tickDateTime.date().month(), thisUniformDay)); - result[i] = dateTimeToKey(tickDateTime); - } - } - } - return result; -} - -/*! - A convenience method which turns \a key (in seconds since Epoch 1. Jan 1970, 00:00 UTC) into a - QDateTime object. This can be used to turn axis coordinates to actual QDateTimes. - - The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it - works around the lack of a QDateTime::fromMSecsSinceEpoch in Qt 4.6) - - \see dateTimeToKey -*/ -QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) -{ - return QDateTime::fromMSecsSinceEpoch(key); -} - -/*! \overload - - A convenience method which turns a QDateTime object into a double value that corresponds to - seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by - QCPAxisTickerDateTime. - - The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it - works around the lack of a QDateTime::toMSecsSinceEpoch in Qt 4.6) - - \see keyToDateTime -*/ -double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime dateTime) -{ - return dateTime.toMSecsSinceEpoch(); -} - -/*! \overload - - A convenience method which turns a QDate object into a double value that corresponds to - seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by - QCPAxisTickerDateTime. - - \see keyToDateTime -*/ -double QCPAxisTickerDateTime::dateTimeToKey(const QDate date) -{ - return QDateTime(date).toMSecsSinceEpoch(); -} -/* end of 'src/axis/axistickerdatetime.cpp' */ - - -/* including file 'src/axis/axistickertime.cpp', size 11747 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerTime -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerTime - \brief Specialized axis ticker for time spans in units of milliseconds to days - - \image html axisticker-time.png - - This QCPAxisTicker subclass generates ticks that corresponds to time intervals. - - The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref - setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate - zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date - and time. - - The time can be displayed in milliseconds, seconds, minutes, hours and days. Depending on the - largest available unit in the format specified with \ref setTimeFormat, any time spans above will - be carried in that largest unit. So for example if the format string is "%m:%s" and a tick at - coordinate value 7815 (being 2 hours, 10 minutes and 15 seconds) is created, the resulting tick - label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour - unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis - zero will carry a leading minus sign. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation - - Here is an example of a time axis providing time information in days, hours and minutes. Due to - the axis range spanning a few days and the wanted tick count (\ref setTickCount), the ticker - decided to use tick steps of 12 hours: - - \image html axisticker-time2.png - - The format string for this example is - \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation-2 - - \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime - instead. -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerTime::QCPAxisTickerTime() : - mTimeFormat(QLatin1String("%h:%m:%s")), - mSmallestUnit(tuSeconds), - mBiggestUnit(tuHours) -{ - setTickCount(4); - mFieldWidth[tuMilliseconds] = 3; - mFieldWidth[tuSeconds] = 2; - mFieldWidth[tuMinutes] = 2; - mFieldWidth[tuHours] = 2; - mFieldWidth[tuDays] = 1; - - mFormatPattern[tuMilliseconds] = QLatin1String("%z"); - mFormatPattern[tuSeconds] = QLatin1String("%s"); - mFormatPattern[tuMinutes] = QLatin1String("%m"); - mFormatPattern[tuHours] = QLatin1String("%h"); - mFormatPattern[tuDays] = QLatin1String("%d"); -} - -/*! - Sets the format that will be used to display time in the tick labels. - - The available patterns are: - - %%z for milliseconds - - %%s for seconds - - %%m for minutes - - %%h for hours - - %%d for days - - The field width (zero padding) can be controlled for each unit with \ref setFieldWidth. - - The largest unit that appears in \a format will carry all the remaining time of a certain tick - coordinate, even if it overflows the natural limit of the unit. For example, if %%m is the - largest unit it might become larger than 59 in order to consume larger time values. If on the - other hand %%h is available, the minutes will wrap around to zero after 59 and the time will - carry to the hour digit. -*/ -void QCPAxisTickerTime::setTimeFormat(const QString &format) -{ - mTimeFormat = format; - - // determine smallest and biggest unit in format, to optimize unit replacement and allow biggest - // unit to consume remaining time of a tick value and grow beyond its modulo (e.g. min > 59) - mSmallestUnit = tuMilliseconds; - mBiggestUnit = tuMilliseconds; - bool hasSmallest = false; - for (int i = tuMilliseconds; i <= tuDays; ++i) - { - TimeUnit unit = static_cast(i); - if (mTimeFormat.contains(mFormatPattern.value(unit))) - { - if (!hasSmallest) - { - mSmallestUnit = unit; - hasSmallest = true; - } - mBiggestUnit = unit; - } - } -} - -/*! - Sets the field widh of the specified \a unit to be \a width digits, when displayed in the tick - label. If the number for the specific unit is shorter than \a width, it will be padded with an - according number of zeros to the left in order to reach the field width. - - \see setTimeFormat -*/ -void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int width) -{ - mFieldWidth[unit] = qMax(width, 1); -} - -/*! \internal - - Returns the tick step appropriate for time displays, depending on the provided \a range and the - smallest available time unit in the current format (\ref setTimeFormat). For example if the unit - of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes) - that require sub-minute precision to be displayed correctly. - - \seebaseclassmethod -*/ -double QCPAxisTickerTime::getTickStep(const QCPRange &range) -{ - double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - - if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds - { - if (mSmallestUnit == tuMilliseconds) - result = qMax(cleanMantissa(result), 0.001); // smallest tick step is 1 millisecond - else // have no milliseconds available in format, so stick with 1 second tickstep - result = 1.0; - } else if (result < 3600*24) // below a day - { - // the filling of availableSteps seems a bit contorted but it fills in a sorted fashion and thus saves a post-fill sorting run - QVector availableSteps; - // seconds range: - if (mSmallestUnit <= tuSeconds) - availableSteps << 1; - if (mSmallestUnit == tuMilliseconds) - availableSteps << 2.5; // only allow half second steps if milliseconds are there to display it - else if (mSmallestUnit == tuSeconds) - availableSteps << 2; - if (mSmallestUnit <= tuSeconds) - availableSteps << 5 << 10 << 15 << 30; - // minutes range: - if (mSmallestUnit <= tuMinutes) - availableSteps << 1*60; - if (mSmallestUnit <= tuSeconds) - availableSteps << 2.5*60; // only allow half minute steps if seconds are there to display it - else if (mSmallestUnit == tuMinutes) - availableSteps << 2*60; - if (mSmallestUnit <= tuMinutes) - availableSteps << 5*60 << 10*60 << 15*60 << 30*60; - // hours range: - if (mSmallestUnit <= tuHours) - availableSteps << 1*3600 << 2*3600 << 3*3600 << 6*3600 << 12*3600 << 24*3600; - // pick available step that is most appropriate to approximate ideal step: - result = pickClosest(result, availableSteps); - } else // more than a day, go back to normal clean mantissa algorithm but in units of days - { - const double secondsPerDay = 3600*24; - result = cleanMantissa(result/secondsPerDay)*secondsPerDay; - } - return result; -} - -/*! \internal - - Returns the sub tick count appropriate for the provided \a tickStep and time displays. - - \seebaseclassmethod -*/ -int QCPAxisTickerTime::getSubTickCount(double tickStep) -{ - int result = QCPAxisTicker::getSubTickCount(tickStep); - switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day range (as specified in getTickStep) - { - case 5*60: result = 4; break; - case 10*60: result = 1; break; - case 15*60: result = 2; break; - case 30*60: result = 1; break; - case 60*60: result = 3; break; - case 3600*2: result = 3; break; - case 3600*3: result = 2; break; - case 3600*6: result = 1; break; - case 3600*12: result = 3; break; - case 3600*24: result = 3; break; - } - return result; -} - -/*! \internal - - Returns the tick label corresponding to the provided \a tick and the configured format and field - widths (\ref setTimeFormat, \ref setFieldWidth). - - \seebaseclassmethod -*/ -QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) -{ - Q_UNUSED(precision) - Q_UNUSED(formatChar) - Q_UNUSED(locale) - bool negative = tick < 0; - if (negative) tick *= -1; - double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59) - double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time - - restValues[tuMilliseconds] = tick*1000; - values[tuMilliseconds] = modf(restValues[tuMilliseconds]/1000, &restValues[tuSeconds])*1000; - values[tuSeconds] = modf(restValues[tuSeconds]/60, &restValues[tuMinutes])*60; - values[tuMinutes] = modf(restValues[tuMinutes]/60, &restValues[tuHours])*60; - values[tuHours] = modf(restValues[tuHours]/24, &restValues[tuDays])*24; - // no need to set values[tuDays] because days are always a rest value (there is no higher unit so it consumes all remaining time) - - QString result = mTimeFormat; - for (int i = mSmallestUnit; i <= mBiggestUnit; ++i) - { - TimeUnit iUnit = static_cast(i); - replaceUnit(result, iUnit, qRound(iUnit == mBiggestUnit ? restValues[iUnit] : values[iUnit])); - } - if (negative) - result.prepend(QLatin1Char('-')); - return result; -} - -/*! \internal - - Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified - \a value, using the field width as specified with \ref setFieldWidth for the \a unit. -*/ -void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit unit, int value) const -{ - QString valueStr = QString::number(value); - while (valueStr.size() < mFieldWidth.value(unit)) - valueStr.prepend(QLatin1Char('0')); - - text.replace(mFormatPattern.value(unit), valueStr); -} -/* end of 'src/axis/axistickertime.cpp' */ - - -/* including file 'src/axis/axistickerfixed.cpp', size 5583 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerFixed -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerFixed - \brief Specialized axis ticker with a fixed tick step - - \image html axisticker-fixed.png - - This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It - is also possible to allow integer multiples and integer powers of the specified tick step with - \ref setScaleStrategy. - - A typical application of this ticker is to make an axis only display integers, by setting the - tick step of the ticker to 1.0 and the scale strategy to \ref ssMultiples. - - Another case is when a certain number has a special meaning and axis ticks should only appear at - multiples of that value. In this case you might also want to consider \ref QCPAxisTickerPi - because despite the name it is not limited to only pi symbols/values. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickerfixed-creation -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerFixed::QCPAxisTickerFixed() : - mTickStep(1.0), - mScaleStrategy(ssNone) -{ -} - -/*! - Sets the fixed tick interval to \a step. - - The axis ticker will only use this tick step when generating axis ticks. This might cause a very - high tick density and overlapping labels if the axis range is zoomed out. Using \ref - setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a - step. This will enable the ticker to reduce the number of ticks to a reasonable amount (see \ref - setTickCount). -*/ -void QCPAxisTickerFixed::setTickStep(double step) -{ - if (step > 0) - mTickStep = step; - else - qDebug() << Q_FUNC_INFO << "tick step must be greater than zero:" << step; -} - -/*! - Sets whether the specified tick step (\ref setTickStep) is absolutely fixed or whether - modifications may be applied to it before calculating the finally used tick step, such as - permitting multiples or powers. See \ref ScaleStrategy for details. - - The default strategy is \ref ssNone, which means the tick step is absolutely fixed. -*/ -void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy strategy) -{ - mScaleStrategy = strategy; -} - -/*! \internal - - Determines the actually used tick step from the specified tick step and scale strategy (\ref - setTickStep, \ref setScaleStrategy). - - This method either returns the specified tick step exactly, or, if the scale strategy is not \ref - ssNone, a modification of it to allow varying the number of ticks in the current axis range. - - \seebaseclassmethod -*/ -double QCPAxisTickerFixed::getTickStep(const QCPRange &range) -{ - switch (mScaleStrategy) - { - case ssNone: - { - return mTickStep; - } - case ssMultiples: - { - double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - if (exactStep < mTickStep) - return mTickStep; - else - return (qint64)(cleanMantissa(exactStep/mTickStep)+0.5)*mTickStep; - } - case ssPowers: - { - double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - return qPow(mTickStep, (int)(qLn(exactStep)/qLn(mTickStep)+0.5)); - } - } - return mTickStep; -} -/* end of 'src/axis/axistickerfixed.cpp' */ - - -/* including file 'src/axis/axistickertext.cpp', size 8653 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerText -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerText - \brief Specialized axis ticker which allows arbitrary labels at specified coordinates - - \image html axisticker-text.png - - This QCPAxisTicker subclass generates ticks which can be directly specified by the user as - coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a - time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks - and modify the tick/label data there. - - This is useful for cases where the axis represents categories rather than numerical values. - - If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on - the axis range), it is a sign that you should probably create an own ticker by subclassing - QCPAxisTicker, instead of using this one. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickertext-creation -*/ - -/* start of documentation of inline functions */ - -/*! \fn QMap &QCPAxisTickerText::ticks() - - Returns a non-const reference to the internal map which stores the tick coordinates and their - labels. - - You can access the map directly in order to add, remove or manipulate ticks, as an alternative to - using the methods provided by QCPAxisTickerText, such as \ref setTicks and \ref addTick. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerText::QCPAxisTickerText() : - mSubTickCount(0) -{ -} - -/*! \overload - - Sets the ticks that shall appear on the axis. The map key of \a ticks corresponds to the axis - coordinate, and the map value is the string that will appear as tick label. - - An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks - getter. - - \see addTicks, addTick, clear -*/ -void QCPAxisTickerText::setTicks(const QMap &ticks) -{ - mTicks = ticks; -} - -/*! \overload - - Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis - coordinates, and the entries of \a labels are the respective strings that will appear as tick - labels. - - \see addTicks, addTick, clear -*/ -void QCPAxisTickerText::setTicks(const QVector &positions, const QVector labels) -{ - clear(); - addTicks(positions, labels); -} - -/*! - Sets the number of sub ticks that shall appear between ticks. For QCPAxisTickerText, there is no - automatic sub tick count calculation. So if sub ticks are needed, they must be configured with this - method. -*/ -void QCPAxisTickerText::setSubTickCount(int subTicks) -{ - if (subTicks >= 0) - mSubTickCount = subTicks; - else - qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; -} - -/*! - Clears all ticks. - - An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks - getter. - - \see setTicks, addTicks, addTick -*/ -void QCPAxisTickerText::clear() -{ - mTicks.clear(); -} - -/*! - Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a - label. - - \see addTicks, setTicks, clear -*/ -void QCPAxisTickerText::addTick(double position, QString label) -{ - mTicks.insert(position, label); -} - -/*! \overload - - Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to - the axis coordinate, and the map value is the string that will appear as tick label. - - An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks - getter. - - \see addTick, setTicks, clear -*/ -void QCPAxisTickerText::addTicks(const QMap &ticks) -{ - mTicks.unite(ticks); -} - -/*! \overload - - Adds the provided ticks to the ones already existing. The entries of \a positions correspond to - the axis coordinates, and the entries of \a labels are the respective strings that will appear as - tick labels. - - An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks - getter. - - \see addTick, setTicks, clear -*/ -void QCPAxisTickerText::addTicks(const QVector &positions, const QVector &labels) -{ - if (positions.size() != labels.size()) - qDebug() << Q_FUNC_INFO << "passed unequal length vectors for positions and labels:" << positions.size() << labels.size(); - int n = qMin(positions.size(), labels.size()); - for (int i=0; i QCPAxisTickerText::createTickVector(double tickStep, const QCPRange &range) -{ - Q_UNUSED(tickStep) - QVector result; - if (mTicks.isEmpty()) - return result; - - QMap::const_iterator start = mTicks.lowerBound(range.lower); - QMap::const_iterator end = mTicks.upperBound(range.upper); - // this method should try to give one tick outside of range so proper subticks can be generated: - if (start != mTicks.constBegin()) --start; - if (end != mTicks.constEnd()) ++end; - for (QMap::const_iterator it = start; it != end; ++it) - result.append(it.key()); - - return result; -} -/* end of 'src/axis/axistickertext.cpp' */ - - -/* including file 'src/axis/axistickerpi.cpp', size 11170 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerPi -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerPi - \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi - - \image html axisticker-pi.png - - This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic - constant with a numerical value specified with \ref setPiValue and an appearance in the tick - labels specified with \ref setPiSymbol. - - Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the - tick label can be configured with \ref setFractionStyle. - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickerpi-creation -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerPi::QCPAxisTickerPi() : - mPiSymbol(QLatin1String(" ")+QChar(0x03C0)), - mPiValue(M_PI), - mPeriodicity(0), - mFractionStyle(fsUnicodeFractions), - mPiTickStep(0) -{ - setTickCount(4); -} - -/*! - Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick - label. - - If a space shall appear between the number and the symbol, make sure the space is contained in \a - symbol. -*/ -void QCPAxisTickerPi::setPiSymbol(QString symbol) -{ - mPiSymbol = symbol; -} - -/*! - Sets the numerical value that the symbolic constant has. - - This will be used to place the appropriate fractions of the symbol at the respective axis - coordinates. -*/ -void QCPAxisTickerPi::setPiValue(double pi) -{ - mPiValue = pi; -} - -/*! - Sets whether the axis labels shall appear periodicly and if so, at which multiplicity of the - symbolic constant. - - To disable periodicity, set \a multiplesOfPi to zero. - - For example, an axis that identifies 0 with 2pi would set \a multiplesOfPi to two. -*/ -void QCPAxisTickerPi::setPeriodicity(int multiplesOfPi) -{ - mPeriodicity = qAbs(multiplesOfPi); -} - -/*! - Sets how the numerical/fractional part preceding the symbolic constant is displayed in tick - labels. See \ref FractionStyle for the various options. -*/ -void QCPAxisTickerPi::setFractionStyle(QCPAxisTickerPi::FractionStyle style) -{ - mFractionStyle = style; -} - -/*! \internal - - Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence - the numerical/fractional part preceding the symbolic constant is made to have a readable - mantissa. - - \seebaseclassmethod -*/ -double QCPAxisTickerPi::getTickStep(const QCPRange &range) -{ - mPiTickStep = range.size()/mPiValue/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers - mPiTickStep = cleanMantissa(mPiTickStep); - return mPiTickStep*mPiValue; -} - -/*! \internal - - Returns the sub tick count, using the constant's value (\ref setPiValue) as base unit. In - consequence the sub ticks divide the numerical/fractional part preceding the symbolic constant - reasonably, and not the total tick coordinate. - - \seebaseclassmethod -*/ -int QCPAxisTickerPi::getSubTickCount(double tickStep) -{ - return QCPAxisTicker::getSubTickCount(tickStep/mPiValue); -} - -/*! \internal - - Returns the tick label as a fractional/numerical part and a symbolic string as suffix. The - formatting of the fraction is done according to the specified \ref setFractionStyle. The appended - symbol is specified with \ref setPiSymbol. - - \seebaseclassmethod -*/ -QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) -{ - double tickInPis = tick/mPiValue; - if (mPeriodicity > 0) - tickInPis = fmod(tickInPis, mPeriodicity); - - if (mFractionStyle != fsFloatingPoint && mPiTickStep > 0.09 && mPiTickStep < 50) - { - // simply construct fraction from decimal like 1.234 -> 1234/1000 and then simplify fraction, smaller digits are irrelevant due to mPiTickStep conditional above - int denominator = 1000; - int numerator = qRound(tickInPis*denominator); - simplifyFraction(numerator, denominator); - if (qAbs(numerator) == 1 && denominator == 1) - return (numerator < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); - else if (numerator == 0) - return QLatin1String("0"); - else - return fractionToString(numerator, denominator) + mPiSymbol; - } else - { - if (qFuzzyIsNull(tickInPis)) - return QLatin1String("0"); - else if (qFuzzyCompare(qAbs(tickInPis), 1.0)) - return (tickInPis < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); - else - return QCPAxisTicker::getTickLabel(tickInPis, locale, formatChar, precision) + mPiSymbol; - } -} - -/*! \internal - - Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure - the fraction is in irreducible form, i.e. numerator and denominator don't share any common - factors which could be cancelled. -*/ -void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const -{ - if (numerator == 0 || denominator == 0) - return; - - int num = numerator; - int denom = denominator; - while (denom != 0) // euclidean gcd algorithm - { - int oldDenom = denom; - denom = num % denom; - num = oldDenom; - } - // num is now gcd of numerator and denominator - numerator /= num; - denominator /= num; -} - -/*! \internal - - Takes the fraction given by \a numerator and \a denominator and returns a string representation. - The result depends on the configured fraction style (\ref setFractionStyle). - - This method is used to format the numerical/fractional part when generating tick labels. It - simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out - any integer parts of the fraction (e.g. "10/4" becomes "2 1/2"). -*/ -QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const -{ - if (denominator == 0) - { - qDebug() << Q_FUNC_INFO << "called with zero denominator"; - return QString(); - } - if (mFractionStyle == fsFloatingPoint) // should never be the case when calling this function - { - qDebug() << Q_FUNC_INFO << "shouldn't be called with fraction style fsDecimal"; - return QString::number(numerator/(double)denominator); // failsafe - } - int sign = numerator*denominator < 0 ? -1 : 1; - numerator = qAbs(numerator); - denominator = qAbs(denominator); - - if (denominator == 1) - { - return QString::number(sign*numerator); - } else - { - int integerPart = numerator/denominator; - int remainder = numerator%denominator; - if (remainder == 0) - { - return QString::number(sign*integerPart); - } else - { - if (mFractionStyle == fsAsciiFractions) - { - return QString(QLatin1String("%1%2%3/%4")) - .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) - .arg(integerPart > 0 ? QString::number(integerPart)+QLatin1String(" ") : QLatin1String("")) - .arg(remainder) - .arg(denominator); - } else if (mFractionStyle == fsUnicodeFractions) - { - return QString(QLatin1String("%1%2%3")) - .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) - .arg(integerPart > 0 ? QString::number(integerPart) : QLatin1String("")) - .arg(unicodeFraction(remainder, denominator)); - } - } - } - return QString(); -} - -/*! \internal - - Returns the unicode string representation of the fraction given by \a numerator and \a - denominator. This is the representation used in \ref fractionToString when the fraction style - (\ref setFractionStyle) is \ref fsUnicodeFractions. - - This method doesn't use the single-character common fractions but builds each fraction from a - superscript unicode number, the unicode fraction character, and a subscript unicode number. -*/ -QString QCPAxisTickerPi::unicodeFraction(int numerator, int denominator) const -{ - return unicodeSuperscript(numerator)+QChar(0x2044)+unicodeSubscript(denominator); -} - -/*! \internal - - Returns the unicode string representing \a number as superscript. This is used to build - unicode fractions in \ref unicodeFraction. -*/ -QString QCPAxisTickerPi::unicodeSuperscript(int number) const -{ - if (number == 0) - return QString(QChar(0x2070)); - - QString result; - while (number > 0) - { - const int digit = number%10; - switch (digit) - { - case 1: { result.prepend(QChar(0x00B9)); break; } - case 2: { result.prepend(QChar(0x00B2)); break; } - case 3: { result.prepend(QChar(0x00B3)); break; } - default: { result.prepend(QChar(0x2070+digit)); break; } - } - number /= 10; - } - return result; -} - -/*! \internal - - Returns the unicode string representing \a number as subscript. This is used to build unicode - fractions in \ref unicodeFraction. -*/ -QString QCPAxisTickerPi::unicodeSubscript(int number) const -{ - if (number == 0) - return QString(QChar(0x2080)); - - QString result; - while (number > 0) - { - result.prepend(QChar(0x2080+number%10)); - number /= 10; - } - return result; -} -/* end of 'src/axis/axistickerpi.cpp' */ - - -/* including file 'src/axis/axistickerlog.cpp', size 7106 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisTickerLog -//////////////////////////////////////////////////////////////////////////////////////////////////// -/*! \class QCPAxisTickerLog - \brief Specialized axis ticker suited for logarithmic axes - - \image html axisticker-log.png - - This QCPAxisTicker subclass generates ticks with unequal tick intervals suited for logarithmic - axis scales. The ticks are placed at powers of the specified log base (\ref setLogBase). - - Especially in the case of a log base equal to 10 (the default), it might be desirable to have - tick labels in the form of powers of ten without mantissa display. To achieve this, set the - number precision (\ref QCPAxis::setNumberPrecision) to zero and the number format (\ref - QCPAxis::setNumberFormat) to scientific (exponential) display with beautifully typeset decimal - powers, so a format string of "eb". This will result in the following axis tick labels: - - \image html axisticker-log-powers.png - - The ticker can be created and assigned to an axis like this: - \snippet documentation/doc-image-generator/mainwindow.cpp axistickerlog-creation -*/ - -/*! - Constructs the ticker and sets reasonable default values. Axis tickers are commonly created - managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. -*/ -QCPAxisTickerLog::QCPAxisTickerLog() : - mLogBase(10.0), - mSubTickCount(8), // generates 10 intervals - mLogBaseLnInv(1.0/qLn(mLogBase)) -{ -} - -/*! - Sets the logarithm base used for tick coordinate generation. The ticks will be placed at integer - powers of \a base. -*/ -void QCPAxisTickerLog::setLogBase(double base) -{ - if (base > 0) - { - mLogBase = base; - mLogBaseLnInv = 1.0/qLn(mLogBase); - } else - qDebug() << Q_FUNC_INFO << "log base has to be greater than zero:" << base; -} - -/*! - Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced - linearly to provide a better visual guide, so the sub tick density increases toward the higher - tick. - - Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in - the case of logarithm base 10 an intuitive sub tick spacing would be achieved with eight sub - ticks (the default). This means e.g. between the ticks 10 and 100 there will be eight ticks, - namely at 20, 30, 40, 50, 60, 70, 80 and 90. -*/ -void QCPAxisTickerLog::setSubTickCount(int subTicks) -{ - if (subTicks >= 0) - mSubTickCount = subTicks; - else - qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; -} - -/*! \internal - - Since logarithmic tick steps are necessarily different for each tick interval, this method does - nothing in the case of QCPAxisTickerLog - - \seebaseclassmethod -*/ -double QCPAxisTickerLog::getTickStep(const QCPRange &range) -{ - // Logarithmic axis ticker has unequal tick spacing, so doesn't need this method - Q_UNUSED(range) - return 1.0; -} - -/*! \internal - - Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no - automatic sub tick count calculation necessary. - - \seebaseclassmethod -*/ -int QCPAxisTickerLog::getSubTickCount(double tickStep) -{ - Q_UNUSED(tickStep) - return mSubTickCount; -} - -/*! \internal - - Creates ticks with a spacing given by the logarithm base and an increasing integer power in the - provided \a range. The step in which the power increases tick by tick is chosen in order to keep - the total number of ticks as close as possible to the tick count (\ref setTickCount). The - parameter \a tickStep is ignored for QCPAxisTickerLog - - \seebaseclassmethod -*/ -QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRange &range) -{ - Q_UNUSED(tickStep) - QVector result; - if (range.lower > 0 && range.upper > 0) // positive range - { - double exactPowerStep = qLn(range.upper/range.lower)*mLogBaseLnInv/(double)(mTickCount+1e-10); - double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); - double currentTick = qPow(newLogBase, qFloor(qLn(range.lower)/qLn(newLogBase))); - result.append(currentTick); - while (currentTick < range.upper && currentTick > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case - { - currentTick *= newLogBase; - result.append(currentTick); - } - } else if (range.lower < 0 && range.upper < 0) // negative range - { - double exactPowerStep = qLn(range.lower/range.upper)*mLogBaseLnInv/(double)(mTickCount+1e-10); - double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); - double currentTick = -qPow(newLogBase, qCeil(qLn(-range.lower)/qLn(newLogBase))); - result.append(currentTick); - while (currentTick < range.upper && currentTick < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case - { - currentTick /= newLogBase; - result.append(currentTick); - } - } else // invalid range for logarithmic scale, because lower and upper have different sign - { - qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << range.lower << ".." << range.upper; - } - - return result; -} -/* end of 'src/axis/axistickerlog.cpp' */ - - -/* including file 'src/axis/axis.cpp', size 99397 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPGrid -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPGrid - \brief Responsible for drawing the grid of a QCPAxis. - - This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the - grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref - QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. - - The axis and grid drawing was split into two classes to allow them to be placed on different - layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid - in the background and the axes in the foreground, and any plottables/items in between. This - described situation is the default setup, see the QCPLayer documentation. -*/ - -/*! - Creates a QCPGrid instance and sets default values. - - You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. -*/ -QCPGrid::QCPGrid(QCPAxis *parentAxis) : - QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), - mParentAxis(parentAxis) -{ - // warning: this is called in QCPAxis constructor, so parentAxis members should not be accessed/called - setParent(parentAxis); - setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); - setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); - setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); - setSubGridVisible(false); - setAntialiased(false); - setAntialiasedSubGrid(false); - setAntialiasedZeroLine(false); -} - -/*! - Sets whether grid lines at sub tick marks are drawn. - - \see setSubGridPen -*/ -void QCPGrid::setSubGridVisible(bool visible) -{ - mSubGridVisible = visible; -} - -/*! - Sets whether sub grid lines are drawn antialiased. -*/ -void QCPGrid::setAntialiasedSubGrid(bool enabled) -{ - mAntialiasedSubGrid = enabled; -} - -/*! - Sets whether zero lines are drawn antialiased. -*/ -void QCPGrid::setAntialiasedZeroLine(bool enabled) -{ - mAntialiasedZeroLine = enabled; -} - -/*! - Sets the pen with which (major) grid lines are drawn. -*/ -void QCPGrid::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen with which sub grid lines are drawn. -*/ -void QCPGrid::setSubGridPen(const QPen &pen) -{ - mSubGridPen = pen; -} - -/*! - Sets the pen with which zero lines are drawn. - - Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid - lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. -*/ -void QCPGrid::setZeroLinePen(const QPen &pen) -{ - mZeroLinePen = pen; -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing the major grid lines. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \see setAntialiased -*/ -void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); -} - -/*! \internal - - Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning - over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). -*/ -void QCPGrid::draw(QCPPainter *painter) -{ - if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - - if (mParentAxis->subTicks() && mSubGridVisible) - drawSubGridLines(painter); - drawGridLines(painter); -} - -/*! \internal - - Draws the main grid lines and possibly a zero line with the specified painter. - - This is a helper function called by \ref draw. -*/ -void QCPGrid::drawGridLines(QCPPainter *painter) const -{ - if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - - const int tickCount = mParentAxis->mTickVector.size(); - double t; // helper variable, result of coordinate-to-pixel transforms - if (mParentAxis->orientation() == Qt::Horizontal) - { - // draw zeroline: - int zeroLineIndex = -1; - if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) - { - applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); - painter->setPen(mZeroLinePen); - double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero - for (int i=0; imTickVector.at(i)) < epsilon) - { - zeroLineIndex = i; - t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x - painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); - break; - } - } - } - // draw grid lines: - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // x - painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); - } - } else - { - // draw zeroline: - int zeroLineIndex = -1; - if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) - { - applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); - painter->setPen(mZeroLinePen); - double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero - for (int i=0; imTickVector.at(i)) < epsilon) - { - zeroLineIndex = i; - t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y - painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); - break; - } - } - } - // draw grid lines: - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // y - painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); - } - } -} - -/*! \internal - - Draws the sub grid lines with the specified painter. - - This is a helper function called by \ref draw. -*/ -void QCPGrid::drawSubGridLines(QCPPainter *painter) const -{ - if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } - - applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); - double t; // helper variable, result of coordinate-to-pixel transforms - painter->setPen(mSubGridPen); - if (mParentAxis->orientation() == Qt::Horizontal) - { - for (int i=0; imSubTickVector.size(); ++i) - { - t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // x - painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); - } - } else - { - for (int i=0; imSubTickVector.size(); ++i) - { - t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // y - painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); - } - } -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxis -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAxis - \brief Manages a single axis inside a QCustomPlot. - - Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via - QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and - QCustomPlot::yAxis2 (right). - - Axes are always part of an axis rect, see QCPAxisRect. - \image html AxisNamesOverview.png -
Naming convention of axis parts
- \n - - \image html AxisRectSpacingOverview.png -
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line - on the left represents the QCustomPlot widget border.
- - Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and - tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of - the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the - documentation of QCPAxisTicker. -*/ - -/* start of documentation of inline functions */ - -/*! \fn Qt::Orientation QCPAxis::orientation() const - - Returns the orientation of this axis. The axis orientation (horizontal or vertical) is deduced - from the axis type (left, top, right or bottom). - - \see orientation(AxisType type), pixelOrientation -*/ - -/*! \fn QCPGrid *QCPAxis::grid() const - - Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the - grid is displayed. -*/ - -/*! \fn static Qt::Orientation QCPAxis::orientation(AxisType type) - - Returns the orientation of the specified axis type - - \see orientation(), pixelOrientation -*/ - -/*! \fn int QCPAxis::pixelOrientation() const - - Returns which direction points towards higher coordinate values/keys, in pixel space. - - This method returns either 1 or -1. If it returns 1, then going in the positive direction along - the orientation of the axis in pixels corresponds to going from lower to higher axis coordinates. - On the other hand, if this method returns -1, going to smaller pixel values corresponds to going - from lower to higher axis coordinates. - - For example, this is useful to easily shift axis coordinates by a certain amount given in pixels, - without having to care about reversed or vertically aligned axes: - - \code - double newKey = keyAxis->pixelToCoord(keyAxis->coordToPixel(oldKey)+10*keyAxis->pixelOrientation()); - \endcode - - \a newKey will then contain a key that is ten pixels towards higher keys, starting from \a oldKey. -*/ - -/*! \fn QSharedPointer QCPAxis::ticker() const - - Returns a modifiable shared pointer to the currently installed axis ticker. The axis ticker is - responsible for generating the tick positions and tick labels of this axis. You can access the - \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count - (\ref QCPAxisTicker::setTickCount). - - You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see - the documentation there. A new axis ticker can be set with \ref setTicker. - - Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis - ticker simply by passing the same shared pointer to multiple axes. - - \see setTicker -*/ - -/* end of documentation of inline functions */ -/* start of documentation of signals */ - -/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) - - This signal is emitted when the range of this axis has changed. You can connect it to the \ref - setRange slot of another axis to communicate the new range to the other axis, in order for it to - be synchronized. - - You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. - This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper - range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following - slot would limit the x axis to ranges between 0 and 10: - \code - customPlot->xAxis->setRange(newRange.bounded(0, 10)) - \endcode -*/ - -/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) - \overload - - Additionally to the new range, this signal also provides the previous range held by the axis as - \a oldRange. -*/ - -/*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); - - This signal is emitted when the scale type changes, by calls to \ref setScaleType -*/ - -/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) - - This signal is emitted when the selection state of this axis has changed, either by user interaction - or by a direct call to \ref setSelectedParts. -*/ - -/*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); - - This signal is emitted when the selectability changes, by calls to \ref setSelectableParts -*/ - -/* end of documentation of signals */ - -/*! - Constructs an Axis instance of Type \a type for the axis rect \a parent. - - Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create - them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, - create them manually and then inject them also via \ref QCPAxisRect::addAxis. -*/ -QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : - QCPLayerable(parent->parentPlot(), QString(), parent), - // axis base: - mAxisType(type), - mAxisRect(parent), - mPadding(5), - mOrientation(orientation(type)), - mSelectableParts(spAxis | spTickLabels | spAxisLabel), - mSelectedParts(spNone), - mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - mSelectedBasePen(QPen(Qt::blue, 2)), - // axis label: - mLabel(), - mLabelFont(mParentPlot->font()), - mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), - mLabelColor(Qt::black), - mSelectedLabelColor(Qt::blue), - // tick labels: - mTickLabels(true), - mTickLabelFont(mParentPlot->font()), - mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), - mTickLabelColor(Qt::black), - mSelectedTickLabelColor(Qt::blue), - mNumberPrecision(6), - mNumberFormatChar('g'), - mNumberBeautifulPowers(true), - // ticks and subticks: - mTicks(true), - mSubTicks(true), - mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - mSelectedTickPen(QPen(Qt::blue, 2)), - mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - mSelectedSubTickPen(QPen(Qt::blue, 2)), - // scale and range: - mRange(0, 5), - mRangeReversed(false), - mScaleType(stLinear), - // internal members: - mGrid(new QCPGrid(this)), - mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())), - mTicker(new QCPAxisTicker), - mCachedMarginValid(false), - mCachedMargin(0) -{ - setParent(parent); - mGrid->setVisible(false); - setAntialiased(false); - setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again - - if (type == atTop) - { - setTickLabelPadding(3); - setLabelPadding(6); - } else if (type == atRight) - { - setTickLabelPadding(7); - setLabelPadding(12); - } else if (type == atBottom) - { - setTickLabelPadding(3); - setLabelPadding(3); - } else if (type == atLeft) - { - setTickLabelPadding(5); - setLabelPadding(10); - } -} - -QCPAxis::~QCPAxis() -{ - delete mAxisPainter; - delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order -} - -/* No documentation as it is a property getter */ -int QCPAxis::tickLabelPadding() const -{ - return mAxisPainter->tickLabelPadding; -} - -/* No documentation as it is a property getter */ -double QCPAxis::tickLabelRotation() const -{ - return mAxisPainter->tickLabelRotation; -} - -/* No documentation as it is a property getter */ -QCPAxis::LabelSide QCPAxis::tickLabelSide() const -{ - return mAxisPainter->tickLabelSide; -} - -/* No documentation as it is a property getter */ -QString QCPAxis::numberFormat() const -{ - QString result; - result.append(mNumberFormatChar); - if (mNumberBeautifulPowers) - { - result.append(QLatin1Char('b')); - if (mAxisPainter->numberMultiplyCross) - result.append(QLatin1Char('c')); - } - return result; -} - -/* No documentation as it is a property getter */ -int QCPAxis::tickLengthIn() const -{ - return mAxisPainter->tickLengthIn; -} - -/* No documentation as it is a property getter */ -int QCPAxis::tickLengthOut() const -{ - return mAxisPainter->tickLengthOut; -} - -/* No documentation as it is a property getter */ -int QCPAxis::subTickLengthIn() const -{ - return mAxisPainter->subTickLengthIn; -} - -/* No documentation as it is a property getter */ -int QCPAxis::subTickLengthOut() const -{ - return mAxisPainter->subTickLengthOut; -} - -/* No documentation as it is a property getter */ -int QCPAxis::labelPadding() const -{ - return mAxisPainter->labelPadding; -} - -/* No documentation as it is a property getter */ -int QCPAxis::offset() const -{ - return mAxisPainter->offset; -} - -/* No documentation as it is a property getter */ -QCPLineEnding QCPAxis::lowerEnding() const -{ - return mAxisPainter->lowerEnding; -} - -/* No documentation as it is a property getter */ -QCPLineEnding QCPAxis::upperEnding() const -{ - return mAxisPainter->upperEnding; -} - -/*! - Sets whether the axis uses a linear scale or a logarithmic scale. - - Note that this method controls the coordinate transformation. You will likely also want to use a - logarithmic tick spacing and labeling, which can be achieved by setting an instance of \ref - QCPAxisTickerLog via \ref setTicker. See the documentation of \ref QCPAxisTickerLog about the - details of logarithmic axis tick creation. - - \ref setNumberPrecision -*/ -void QCPAxis::setScaleType(QCPAxis::ScaleType type) -{ - if (mScaleType != type) - { - mScaleType = type; - if (mScaleType == stLogarithmic) - setRange(mRange.sanitizedForLogScale()); - mCachedMarginValid = false; - emit scaleTypeChanged(mScaleType); - } -} - -/*! - Sets the range of the axis. - - This slot may be connected with the \ref rangeChanged signal of another axis so this axis - is always synchronized with the other axis range, when it changes. - - To invert the direction of an axis, use \ref setRangeReversed. -*/ -void QCPAxis::setRange(const QCPRange &range) -{ - if (range.lower == mRange.lower && range.upper == mRange.upper) - return; - - if (!QCPRange::validRange(range)) return; - QCPRange oldRange = mRange; - if (mScaleType == stLogarithmic) - { - mRange = range.sanitizedForLogScale(); - } else - { - mRange = range.sanitizedForLinScale(); - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. - (When \ref QCustomPlot::setInteractions contains iSelectAxes.) - - However, even when \a selectable is set to a value not allowing the selection of a specific part, - it is still possible to set the selection of this part manually, by calling \ref setSelectedParts - directly. - - \see SelectablePart, setSelectedParts -*/ -void QCPAxis::setSelectableParts(const SelectableParts &selectable) -{ - if (mSelectableParts != selectable) - { - mSelectableParts = selectable; - emit selectableChanged(mSelectableParts); - } -} - -/*! - Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part - is selected, it uses a different pen/font. - - The entire selection mechanism for axes is handled automatically when \ref - QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you - wish to change the selection state manually. - - This function can change the selection state of a part, independent of the \ref setSelectableParts setting. - - emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - - \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, - setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor -*/ -void QCPAxis::setSelectedParts(const SelectableParts &selected) -{ - if (mSelectedParts != selected) - { - mSelectedParts = selected; - emit selectionChanged(mSelectedParts); - } -} - -/*! - \overload - - Sets the lower and upper bound of the axis range. - - To invert the direction of an axis, use \ref setRangeReversed. - - There is also a slot to set a range, see \ref setRange(const QCPRange &range). -*/ -void QCPAxis::setRange(double lower, double upper) -{ - if (lower == mRange.lower && upper == mRange.upper) - return; - - if (!QCPRange::validRange(lower, upper)) return; - QCPRange oldRange = mRange; - mRange.lower = lower; - mRange.upper = upper; - if (mScaleType == stLogarithmic) - { - mRange = mRange.sanitizedForLogScale(); - } else - { - mRange = mRange.sanitizedForLinScale(); - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - \overload - - Sets the range of the axis. - - The \a position coordinate indicates together with the \a alignment parameter, where the new - range will be positioned. \a size defines the size of the new axis range. \a alignment may be - Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, - or center of the range to be aligned with \a position. Any other values of \a alignment will - default to Qt::AlignCenter. -*/ -void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) -{ - if (alignment == Qt::AlignLeft) - setRange(position, position+size); - else if (alignment == Qt::AlignRight) - setRange(position-size, position); - else // alignment == Qt::AlignCenter - setRange(position-size/2.0, position+size/2.0); -} - -/*! - Sets the lower bound of the axis range. The upper bound is not changed. - \see setRange -*/ -void QCPAxis::setRangeLower(double lower) -{ - if (mRange.lower == lower) - return; - - QCPRange oldRange = mRange; - mRange.lower = lower; - if (mScaleType == stLogarithmic) - { - mRange = mRange.sanitizedForLogScale(); - } else - { - mRange = mRange.sanitizedForLinScale(); - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Sets the upper bound of the axis range. The lower bound is not changed. - \see setRange -*/ -void QCPAxis::setRangeUpper(double upper) -{ - if (mRange.upper == upper) - return; - - QCPRange oldRange = mRange; - mRange.upper = upper; - if (mScaleType == stLogarithmic) - { - mRange = mRange.sanitizedForLogScale(); - } else - { - mRange = mRange.sanitizedForLinScale(); - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal - axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the - direction of increasing values is inverted. - - Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part - of the \ref setRange interface will still reference the mathematically smaller number than the \a - upper part. -*/ -void QCPAxis::setRangeReversed(bool reversed) -{ - mRangeReversed = reversed; -} - -/*! - The axis ticker is responsible for generating the tick positions and tick labels. See the - documentation of QCPAxisTicker for details on how to work with axis tickers. - - You can change the tick positioning/labeling behaviour of this axis by setting a different - QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis - ticker, access it via \ref ticker. - - Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis - ticker simply by passing the same shared pointer to multiple axes. - - \see ticker -*/ -void QCPAxis::setTicker(QSharedPointer ticker) -{ - if (ticker) - mTicker = ticker; - else - qDebug() << Q_FUNC_INFO << "can not set 0 as axis ticker"; - // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector -} - -/*! - Sets whether tick marks are displayed. - - Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve - that, see \ref setTickLabels. - - \see setSubTicks -*/ -void QCPAxis::setTicks(bool show) -{ - if (mTicks != show) - { - mTicks = show; - mCachedMarginValid = false; - } -} - -/*! - Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. -*/ -void QCPAxis::setTickLabels(bool show) -{ - if (mTickLabels != show) - { - mTickLabels = show; - mCachedMarginValid = false; - if (!mTickLabels) - mTickVectorLabels.clear(); - } -} - -/*! - Sets the distance between the axis base line (including any outward ticks) and the tick labels. - \see setLabelPadding, setPadding -*/ -void QCPAxis::setTickLabelPadding(int padding) -{ - if (mAxisPainter->tickLabelPadding != padding) - { - mAxisPainter->tickLabelPadding = padding; - mCachedMarginValid = false; - } -} - -/*! - Sets the font of the tick labels. - - \see setTickLabels, setTickLabelColor -*/ -void QCPAxis::setTickLabelFont(const QFont &font) -{ - if (font != mTickLabelFont) - { - mTickLabelFont = font; - mCachedMarginValid = false; - } -} - -/*! - Sets the color of the tick labels. - - \see setTickLabels, setTickLabelFont -*/ -void QCPAxis::setTickLabelColor(const QColor &color) -{ - mTickLabelColor = color; -} - -/*! - Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, - the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values - from -90 to 90 degrees. - - If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For - other angles, the label is drawn with an offset such that it seems to point toward or away from - the tick mark. -*/ -void QCPAxis::setTickLabelRotation(double degrees) -{ - if (!qFuzzyIsNull(degrees-mAxisPainter->tickLabelRotation)) - { - mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0); - mCachedMarginValid = false; - } -} - -/*! - Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. - - The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels - to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels - appear on the inside are additionally clipped to the axis rect. -*/ -void QCPAxis::setTickLabelSide(LabelSide side) -{ - mAxisPainter->tickLabelSide = side; - mCachedMarginValid = false; -} - -/*! - Sets the number format for the numbers in tick labels. This \a formatCode is an extended version - of the format code used e.g. by QString::number() and QLocale::toString(). For reference about - that, see the "Argument Formats" section in the detailed description of the QString class. - - \a formatCode is a string of one, two or three characters. The first character is identical to - the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed - format, 'g'/'G' scientific or fixed, whichever is shorter. - - The second and third characters are optional and specific to QCustomPlot:\n - If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. - "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for - "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 - [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. - If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can - be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the - cross and 183 (0xB7) for the dot. - - Examples for \a formatCode: - \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, - normal scientific format is used - \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with - beautifully typeset decimal powers and a dot as multiplication sign - \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as - multiplication sign - \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal - powers. Format code will be reduced to 'f'. - \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format - code will not be changed. -*/ -void QCPAxis::setNumberFormat(const QString &formatCode) -{ - if (formatCode.isEmpty()) - { - qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; - return; - } - mCachedMarginValid = false; - - // interpret first char as number format char: - QString allowedFormatChars(QLatin1String("eEfgG")); - if (allowedFormatChars.contains(formatCode.at(0))) - { - mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); - } else - { - qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; - return; - } - if (formatCode.length() < 2) - { - mNumberBeautifulPowers = false; - mAxisPainter->numberMultiplyCross = false; - return; - } - - // interpret second char as indicator for beautiful decimal powers: - if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) - { - mNumberBeautifulPowers = true; - } else - { - qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; - return; - } - if (formatCode.length() < 3) - { - mAxisPainter->numberMultiplyCross = false; - return; - } - - // interpret third char as indicator for dot or cross multiplication symbol: - if (formatCode.at(2) == QLatin1Char('c')) - { - mAxisPainter->numberMultiplyCross = true; - } else if (formatCode.at(2) == QLatin1Char('d')) - { - mAxisPainter->numberMultiplyCross = false; - } else - { - qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; - return; - } -} - -/*! - Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) - for details. The effect of precisions are most notably for number Formats starting with 'e', see - \ref setNumberFormat -*/ -void QCPAxis::setNumberPrecision(int precision) -{ - if (mNumberPrecision != precision) - { - mNumberPrecision = precision; - mCachedMarginValid = false; - } -} - -/*! - Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the - plot and \a outside is the length they will reach outside the plot. If \a outside is greater than - zero, the tick labels and axis label will increase their distance to the axis accordingly, so - they won't collide with the ticks. - - \see setSubTickLength, setTickLengthIn, setTickLengthOut -*/ -void QCPAxis::setTickLength(int inside, int outside) -{ - setTickLengthIn(inside); - setTickLengthOut(outside); -} - -/*! - Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach - inside the plot. - - \see setTickLengthOut, setTickLength, setSubTickLength -*/ -void QCPAxis::setTickLengthIn(int inside) -{ - if (mAxisPainter->tickLengthIn != inside) - { - mAxisPainter->tickLengthIn = inside; - } -} - -/*! - Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach - outside the plot. If \a outside is greater than zero, the tick labels and axis label will - increase their distance to the axis accordingly, so they won't collide with the ticks. - - \see setTickLengthIn, setTickLength, setSubTickLength -*/ -void QCPAxis::setTickLengthOut(int outside) -{ - if (mAxisPainter->tickLengthOut != outside) - { - mAxisPainter->tickLengthOut = outside; - mCachedMarginValid = false; // only outside tick length can change margin - } -} - -/*! - Sets whether sub tick marks are displayed. - - Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) - - \see setTicks -*/ -void QCPAxis::setSubTicks(bool show) -{ - if (mSubTicks != show) - { - mSubTicks = show; - mCachedMarginValid = false; - } -} - -/*! - Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside - the plot and \a outside is the length they will reach outside the plot. If \a outside is greater - than zero, the tick labels and axis label will increase their distance to the axis accordingly, - so they won't collide with the ticks. - - \see setTickLength, setSubTickLengthIn, setSubTickLengthOut -*/ -void QCPAxis::setSubTickLength(int inside, int outside) -{ - setSubTickLengthIn(inside); - setSubTickLengthOut(outside); -} - -/*! - Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside - the plot. - - \see setSubTickLengthOut, setSubTickLength, setTickLength -*/ -void QCPAxis::setSubTickLengthIn(int inside) -{ - if (mAxisPainter->subTickLengthIn != inside) - { - mAxisPainter->subTickLengthIn = inside; - } -} - -/*! - Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach - outside the plot. If \a outside is greater than zero, the tick labels will increase their - distance to the axis accordingly, so they won't collide with the ticks. - - \see setSubTickLengthIn, setSubTickLength, setTickLength -*/ -void QCPAxis::setSubTickLengthOut(int outside) -{ - if (mAxisPainter->subTickLengthOut != outside) - { - mAxisPainter->subTickLengthOut = outside; - mCachedMarginValid = false; // only outside tick length can change margin - } -} - -/*! - Sets the pen, the axis base line is drawn with. - - \see setTickPen, setSubTickPen -*/ -void QCPAxis::setBasePen(const QPen &pen) -{ - mBasePen = pen; -} - -/*! - Sets the pen, tick marks will be drawn with. - - \see setTickLength, setBasePen -*/ -void QCPAxis::setTickPen(const QPen &pen) -{ - mTickPen = pen; -} - -/*! - Sets the pen, subtick marks will be drawn with. - - \see setSubTickCount, setSubTickLength, setBasePen -*/ -void QCPAxis::setSubTickPen(const QPen &pen) -{ - mSubTickPen = pen; -} - -/*! - Sets the font of the axis label. - - \see setLabelColor -*/ -void QCPAxis::setLabelFont(const QFont &font) -{ - if (mLabelFont != font) - { - mLabelFont = font; - mCachedMarginValid = false; - } -} - -/*! - Sets the color of the axis label. - - \see setLabelFont -*/ -void QCPAxis::setLabelColor(const QColor &color) -{ - mLabelColor = color; -} - -/*! - Sets the text of the axis label that will be shown below/above or next to the axis, depending on - its orientation. To disable axis labels, pass an empty string as \a str. -*/ -void QCPAxis::setLabel(const QString &str) -{ - if (mLabel != str) - { - mLabel = str; - mCachedMarginValid = false; - } -} - -/*! - Sets the distance between the tick labels and the axis label. - - \see setTickLabelPadding, setPadding -*/ -void QCPAxis::setLabelPadding(int padding) -{ - if (mAxisPainter->labelPadding != padding) - { - mAxisPainter->labelPadding = padding; - mCachedMarginValid = false; - } -} - -/*! - Sets the padding of the axis. - - When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, - that is left blank. - - The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. - - \see setLabelPadding, setTickLabelPadding -*/ -void QCPAxis::setPadding(int padding) -{ - if (mPadding != padding) - { - mPadding = padding; - mCachedMarginValid = false; - } -} - -/*! - Sets the offset the axis has to its axis rect side. - - If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, - only the offset of the inner most axis has meaning (even if it is set to be invisible). The - offset of the other, outer axes is controlled automatically, to place them at appropriate - positions. -*/ -void QCPAxis::setOffset(int offset) -{ - mAxisPainter->offset = offset; -} - -/*! - Sets the font that is used for tick labels when they are selected. - - \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedTickLabelFont(const QFont &font) -{ - if (font != mSelectedTickLabelFont) - { - mSelectedTickLabelFont = font; - // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts - } -} - -/*! - Sets the font that is used for the axis label when it is selected. - - \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedLabelFont(const QFont &font) -{ - mSelectedLabelFont = font; - // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts -} - -/*! - Sets the color that is used for tick labels when they are selected. - - \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedTickLabelColor(const QColor &color) -{ - if (color != mSelectedTickLabelColor) - { - mSelectedTickLabelColor = color; - } -} - -/*! - Sets the color that is used for the axis label when it is selected. - - \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedLabelColor(const QColor &color) -{ - mSelectedLabelColor = color; -} - -/*! - Sets the pen that is used to draw the axis base line when selected. - - \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedBasePen(const QPen &pen) -{ - mSelectedBasePen = pen; -} - -/*! - Sets the pen that is used to draw the (major) ticks when selected. - - \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedTickPen(const QPen &pen) -{ - mSelectedTickPen = pen; -} - -/*! - Sets the pen that is used to draw the subticks when selected. - - \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAxis::setSelectedSubTickPen(const QPen &pen) -{ - mSelectedSubTickPen = pen; -} - -/*! - Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available - styles. - - For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. - Note that this meaning does not change when the axis range is reversed with \ref - setRangeReversed. - - \see setUpperEnding -*/ -void QCPAxis::setLowerEnding(const QCPLineEnding &ending) -{ - mAxisPainter->lowerEnding = ending; -} - -/*! - Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available - styles. - - For horizontal axes, this method refers to the right ending, for vertical axes the top ending. - Note that this meaning does not change when the axis range is reversed with \ref - setRangeReversed. - - \see setLowerEnding -*/ -void QCPAxis::setUpperEnding(const QCPLineEnding &ending) -{ - mAxisPainter->upperEnding = ending; -} - -/*! - If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper - bounds of the range. The range is simply moved by \a diff. - - If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This - corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). -*/ -void QCPAxis::moveRange(double diff) -{ - QCPRange oldRange = mRange; - if (mScaleType == stLinear) - { - mRange.lower += diff; - mRange.upper += diff; - } else // mScaleType == stLogarithmic - { - mRange.lower *= diff; - mRange.upper *= diff; - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Scales the range of this axis by \a factor around the center of the current axis range. For - example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis - range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around - the center will have moved symmetrically closer). - - If you wish to scale around a different coordinate than the current axis range center, use the - overload \ref scaleRange(double factor, double center). -*/ -void QCPAxis::scaleRange(double factor) -{ - scaleRange(factor, range().center()); -} - -/*! \overload - - Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a - factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at - coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates - around 1.0 will have moved symmetrically closer to 1.0). - - \see scaleRange(double factor) -*/ -void QCPAxis::scaleRange(double factor, double center) -{ - QCPRange oldRange = mRange; - if (mScaleType == stLinear) - { - QCPRange newRange; - newRange.lower = (mRange.lower-center)*factor + center; - newRange.upper = (mRange.upper-center)*factor + center; - if (QCPRange::validRange(newRange)) - mRange = newRange.sanitizedForLinScale(); - } else // mScaleType == stLogarithmic - { - if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range - { - QCPRange newRange; - newRange.lower = qPow(mRange.lower/center, factor)*center; - newRange.upper = qPow(mRange.upper/center, factor)*center; - if (QCPRange::validRange(newRange)) - mRange = newRange.sanitizedForLogScale(); - } else - qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; - } - emit rangeChanged(mRange); - emit rangeChanged(mRange, oldRange); -} - -/*! - Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will - be done around the center of the current axis range. - - For example, if \a ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs - plotted with those axes will appear in a 1:1 aspect ratio, independent of the aspect ratio the - axis rect has. - - This is an operation that changes the range of this axis once, it doesn't fix the scale ratio - indefinitely. Note that calling this function in the constructor of the QCustomPlot's parent - won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent - will follow. -*/ -void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) -{ - int otherPixelSize, ownPixelSize; - - if (otherAxis->orientation() == Qt::Horizontal) - otherPixelSize = otherAxis->axisRect()->width(); - else - otherPixelSize = otherAxis->axisRect()->height(); - - if (orientation() == Qt::Horizontal) - ownPixelSize = axisRect()->width(); - else - ownPixelSize = axisRect()->height(); - - double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/(double)otherPixelSize; - setRange(range().center(), newRangeSize, Qt::AlignCenter); -} - -/*! - Changes the axis range such that all plottables associated with this axis are fully visible in - that dimension. - - \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes -*/ -void QCPAxis::rescale(bool onlyVisiblePlottables) -{ - QList p = plottables(); - QCPRange newRange; - bool haveRange = false; - for (int i=0; irealVisibility() && onlyVisiblePlottables) - continue; - QCPRange plottableRange; - bool currentFoundRange; - QCP::SignDomain signDomain = QCP::sdBoth; - if (mScaleType == stLogarithmic) - signDomain = (mRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); - if (p.at(i)->keyAxis() == this) - plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain); - else - plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain); - if (currentFoundRange) - { - if (!haveRange) - newRange = plottableRange; - else - newRange.expand(plottableRange); - haveRange = true; - } - } - if (haveRange) - { - if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable - { - double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason - if (mScaleType == stLinear) - { - newRange.lower = center-mRange.size()/2.0; - newRange.upper = center+mRange.size()/2.0; - } else // mScaleType == stLogarithmic - { - newRange.lower = center/qSqrt(mRange.upper/mRange.lower); - newRange.upper = center*qSqrt(mRange.upper/mRange.lower); - } - } - setRange(newRange); - } -} - -/*! - Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. -*/ -double QCPAxis::pixelToCoord(double value) const -{ - if (orientation() == Qt::Horizontal) - { - if (mScaleType == stLinear) - { - if (!mRangeReversed) - return (value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.lower; - else - return -(value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.upper; - } else // mScaleType == stLogarithmic - { - if (!mRangeReversed) - return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/(double)mAxisRect->width())*mRange.lower; - else - return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/(double)mAxisRect->width())*mRange.upper; - } - } else // orientation() == Qt::Vertical - { - if (mScaleType == stLinear) - { - if (!mRangeReversed) - return (mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.lower; - else - return -(mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.upper; - } else // mScaleType == stLogarithmic - { - if (!mRangeReversed) - return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/(double)mAxisRect->height())*mRange.lower; - else - return qPow(mRange.upper/mRange.lower, (value-mAxisRect->bottom())/(double)mAxisRect->height())*mRange.upper; - } - } -} - -/*! - Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. -*/ -double QCPAxis::coordToPixel(double value) const -{ - if (orientation() == Qt::Horizontal) - { - if (mScaleType == stLinear) - { - if (!mRangeReversed) - return (value-mRange.lower)/mRange.size()*mAxisRect->width()+mAxisRect->left(); - else - return (mRange.upper-value)/mRange.size()*mAxisRect->width()+mAxisRect->left(); - } else // mScaleType == stLogarithmic - { - if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range - return !mRangeReversed ? mAxisRect->right()+200 : mAxisRect->left()-200; - else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range - return !mRangeReversed ? mAxisRect->left()-200 : mAxisRect->right()+200; - else - { - if (!mRangeReversed) - return qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); - else - return qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); - } - } - } else // orientation() == Qt::Vertical - { - if (mScaleType == stLinear) - { - if (!mRangeReversed) - return mAxisRect->bottom()-(value-mRange.lower)/mRange.size()*mAxisRect->height(); - else - return mAxisRect->bottom()-(mRange.upper-value)/mRange.size()*mAxisRect->height(); - } else // mScaleType == stLogarithmic - { - if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range - return !mRangeReversed ? mAxisRect->top()-200 : mAxisRect->bottom()+200; - else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range - return !mRangeReversed ? mAxisRect->bottom()+200 : mAxisRect->top()-200; - else - { - if (!mRangeReversed) - return mAxisRect->bottom()-qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); - else - return mAxisRect->bottom()-qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); - } - } - } -} - -/*! - Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function - is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this - function does not change the current selection state of the axis. - - If the axis is not visible (\ref setVisible), this function always returns \ref spNone. - - \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions -*/ -QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const -{ - if (!mVisible) - return spNone; - - if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) - return spAxis; - else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) - return spTickLabels; - else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) - return spAxisLabel; - else - return spNone; -} - -/* inherits documentation from base class */ -double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if (!mParentPlot) return -1; - SelectablePart part = getPartAt(pos); - if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) - return -1; - - if (details) - details->setValue(part); - return mParentPlot->selectionTolerance()*0.99; -} - -/*! - Returns a list of all the plottables that have this axis as key or value axis. - - If you are only interested in plottables of type QCPGraph, see \ref graphs. - - \see graphs, items -*/ -QList QCPAxis::plottables() const -{ - QList result; - if (!mParentPlot) return result; - - for (int i=0; imPlottables.size(); ++i) - { - if (mParentPlot->mPlottables.at(i)->keyAxis() == this ||mParentPlot->mPlottables.at(i)->valueAxis() == this) - result.append(mParentPlot->mPlottables.at(i)); - } - return result; -} - -/*! - Returns a list of all the graphs that have this axis as key or value axis. - - \see plottables, items -*/ -QList QCPAxis::graphs() const -{ - QList result; - if (!mParentPlot) return result; - - for (int i=0; imGraphs.size(); ++i) - { - if (mParentPlot->mGraphs.at(i)->keyAxis() == this || mParentPlot->mGraphs.at(i)->valueAxis() == this) - result.append(mParentPlot->mGraphs.at(i)); - } - return result; -} - -/*! - Returns a list of all the items that are associated with this axis. An item is considered - associated with an axis if at least one of its positions uses the axis as key or value axis. - - \see plottables, graphs -*/ -QList QCPAxis::items() const -{ - QList result; - if (!mParentPlot) return result; - - for (int itemId=0; itemIdmItems.size(); ++itemId) - { - QList positions = mParentPlot->mItems.at(itemId)->positions(); - for (int posId=0; posIdkeyAxis() == this || positions.at(posId)->valueAxis() == this) - { - result.append(mParentPlot->mItems.at(itemId)); - break; - } - } - } - return result; -} - -/*! - Transforms a margin side to the logically corresponding axis type. (QCP::msLeft to - QCPAxis::atLeft, QCP::msRight to QCPAxis::atRight, etc.) -*/ -QCPAxis::AxisType QCPAxis::marginSideToAxisType(QCP::MarginSide side) -{ - switch (side) - { - case QCP::msLeft: return atLeft; - case QCP::msRight: return atRight; - case QCP::msTop: return atTop; - case QCP::msBottom: return atBottom; - default: break; - } - qDebug() << Q_FUNC_INFO << "Invalid margin side passed:" << (int)side; - return atLeft; -} - -/*! - Returns the axis type that describes the opposite axis of an axis with the specified \a type. -*/ -QCPAxis::AxisType QCPAxis::opposite(QCPAxis::AxisType type) -{ - switch (type) - { - case atLeft: return atRight; break; - case atRight: return atLeft; break; - case atBottom: return atTop; break; - case atTop: return atBottom; break; - default: qDebug() << Q_FUNC_INFO << "invalid axis type"; return atLeft; break; - } -} - -/* inherits documentation from base class */ -void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - SelectablePart part = details.value(); - if (mSelectableParts.testFlag(part)) - { - SelectableParts selBefore = mSelectedParts; - setSelectedParts(additive ? mSelectedParts^part : part); - if (selectionStateChanged) - *selectionStateChanged = mSelectedParts != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPAxis::deselectEvent(bool *selectionStateChanged) -{ - SelectableParts selBefore = mSelectedParts; - setSelectedParts(mSelectedParts & ~mSelectableParts); - if (selectionStateChanged) - *selectionStateChanged = mSelectedParts != selBefore; -} - -/*! \internal - - This mouse event reimplementation provides the functionality to let the user drag individual axes - exclusively, by startig the drag on top of the axis. - - For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect - must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis - (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref - QCPAxisRect::setRangeDragAxes) - - \seebaseclassmethod - - \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis - rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. -*/ -void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag) || - !mAxisRect->rangeDrag().testFlag(orientation()) || - !mAxisRect->rangeDragAxes(orientation()).contains(this)) - { - event->ignore(); - return; - } - - if (event->buttons() & Qt::LeftButton) - { - mDragging = true; - // initialize antialiasing backup in case we start dragging: - if (mParentPlot->noAntialiasingOnDrag()) - { - mAADragBackup = mParentPlot->antialiasedElements(); - mNotAADragBackup = mParentPlot->notAntialiasedElements(); - } - // Mouse range dragging interaction: - if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) - mDragStartRange = mRange; - } -} - -/*! \internal - - This mouse event reimplementation provides the functionality to let the user drag individual axes - exclusively, by startig the drag on top of the axis. - - \seebaseclassmethod - - \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis - rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. - - \see QCPAxis::mousePressEvent -*/ -void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - if (mDragging) - { - const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y(); - const double currentPixel = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y(); - if (mScaleType == QCPAxis::stLinear) - { - const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel); - setRange(mDragStartRange.lower+diff, mDragStartRange.upper+diff); - } else if (mScaleType == QCPAxis::stLogarithmic) - { - const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); - setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); - } - - if (mParentPlot->noAntialiasingOnDrag()) - mParentPlot->setNotAntialiasedElements(QCP::aeAll); - mParentPlot->replot(QCustomPlot::rpQueuedReplot); - } -} - -/*! \internal - - This mouse event reimplementation provides the functionality to let the user drag individual axes - exclusively, by startig the drag on top of the axis. - - \seebaseclassmethod - - \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis - rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. - - \see QCPAxis::mousePressEvent -*/ -void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(event) - Q_UNUSED(startPos) - mDragging = false; - if (mParentPlot->noAntialiasingOnDrag()) - { - mParentPlot->setAntialiasedElements(mAADragBackup); - mParentPlot->setNotAntialiasedElements(mNotAADragBackup); - } -} - -/*! \internal - - This mouse event reimplementation provides the functionality to let the user zoom individual axes - exclusively, by performing the wheel event on top of the axis. - - For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect - must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis - (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref - QCPAxisRect::setRangeZoomAxes) - - \seebaseclassmethod - - \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the - axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. -*/ -void QCPAxis::wheelEvent(QWheelEvent *event) -{ - // Mouse range zooming interaction: - if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom) || - !mAxisRect->rangeZoom().testFlag(orientation()) || - !mAxisRect->rangeZoomAxes(orientation()).contains(this)) - { - event->ignore(); - return; - } - - const double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually - const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps); - scaleRange(factor, pixelToCoord(orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y())); - mParentPlot->replot(); -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing axis lines. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \seebaseclassmethod - - \see setAntialiased -*/ -void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); -} - -/*! \internal - - Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. - - \seebaseclassmethod -*/ -void QCPAxis::draw(QCPPainter *painter) -{ - QVector subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter - QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter - QVector tickLabels; // the final vector passed to QCPAxisPainter - tickPositions.reserve(mTickVector.size()); - tickLabels.reserve(mTickVector.size()); - subTickPositions.reserve(mSubTickVector.size()); - - if (mTicks) - { - for (int i=0; itype = mAxisType; - mAxisPainter->basePen = getBasePen(); - mAxisPainter->labelFont = getLabelFont(); - mAxisPainter->labelColor = getLabelColor(); - mAxisPainter->label = mLabel; - mAxisPainter->substituteExponent = mNumberBeautifulPowers; - mAxisPainter->tickPen = getTickPen(); - mAxisPainter->subTickPen = getSubTickPen(); - mAxisPainter->tickLabelFont = getTickLabelFont(); - mAxisPainter->tickLabelColor = getTickLabelColor(); - mAxisPainter->axisRect = mAxisRect->rect(); - mAxisPainter->viewportRect = mParentPlot->viewport(); - mAxisPainter->abbreviateDecimalPowers = mScaleType == stLogarithmic; - mAxisPainter->reversedEndings = mRangeReversed; - mAxisPainter->tickPositions = tickPositions; - mAxisPainter->tickLabels = tickLabels; - mAxisPainter->subTickPositions = subTickPositions; - mAxisPainter->draw(painter); -} - -/*! \internal - - Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling - QCPAxisTicker::generate on the currently installed ticker. - - If a change in the label text/count is detected, the cached axis margin is invalidated to make - sure the next margin calculation recalculates the label sizes and returns an up-to-date value. -*/ -void QCPAxis::setupTickVectors() -{ - if (!mParentPlot) return; - if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; - - QVector oldLabels = mTickVectorLabels; - mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); - mCachedMarginValid &= mTickVectorLabels == oldLabels; // if labels have changed, margin might have changed, too -} - -/*! \internal - - Returns the pen that is used to draw the axis base line. Depending on the selection state, this - is either mSelectedBasePen or mBasePen. -*/ -QPen QCPAxis::getBasePen() const -{ - return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; -} - -/*! \internal - - Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this - is either mSelectedTickPen or mTickPen. -*/ -QPen QCPAxis::getTickPen() const -{ - return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; -} - -/*! \internal - - Returns the pen that is used to draw the subticks. Depending on the selection state, this - is either mSelectedSubTickPen or mSubTickPen. -*/ -QPen QCPAxis::getSubTickPen() const -{ - return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; -} - -/*! \internal - - Returns the font that is used to draw the tick labels. Depending on the selection state, this - is either mSelectedTickLabelFont or mTickLabelFont. -*/ -QFont QCPAxis::getTickLabelFont() const -{ - return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; -} - -/*! \internal - - Returns the font that is used to draw the axis label. Depending on the selection state, this - is either mSelectedLabelFont or mLabelFont. -*/ -QFont QCPAxis::getLabelFont() const -{ - return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; -} - -/*! \internal - - Returns the color that is used to draw the tick labels. Depending on the selection state, this - is either mSelectedTickLabelColor or mTickLabelColor. -*/ -QColor QCPAxis::getTickLabelColor() const -{ - return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; -} - -/*! \internal - - Returns the color that is used to draw the axis label. Depending on the selection state, this - is either mSelectedLabelColor or mLabelColor. -*/ -QColor QCPAxis::getLabelColor() const -{ - return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; -} - -/*! \internal - - Returns the appropriate outward margin for this axis. It is needed if \ref - QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref - atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom - margin and so forth. For the calculation, this function goes through similar steps as \ref draw, - so changing one function likely requires the modification of the other one as well. - - The margin consists of the outward tick length, tick label padding, tick label size, label - padding, label size, and padding. - - The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. - unchanged are very fast. -*/ -int QCPAxis::calculateMargin() -{ - if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis - return 0; - - if (mCachedMarginValid) - return mCachedMargin; - - // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels - int margin = 0; - - QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter - QVector tickLabels; // the final vector passed to QCPAxisPainter - tickPositions.reserve(mTickVector.size()); - tickLabels.reserve(mTickVector.size()); - - if (mTicks) - { - for (int i=0; itype = mAxisType; - mAxisPainter->labelFont = getLabelFont(); - mAxisPainter->label = mLabel; - mAxisPainter->tickLabelFont = mTickLabelFont; - mAxisPainter->axisRect = mAxisRect->rect(); - mAxisPainter->viewportRect = mParentPlot->viewport(); - mAxisPainter->tickPositions = tickPositions; - mAxisPainter->tickLabels = tickLabels; - margin += mAxisPainter->size(); - margin += mPadding; - - mCachedMargin = margin; - mCachedMarginValid = true; - return margin; -} - -/* inherits documentation from base class */ -QCP::Interaction QCPAxis::selectionCategory() const -{ - return QCP::iSelectAxes; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisPainterPrivate -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAxisPainterPrivate - - \internal - \brief (Private) - - This is a private class and not part of the public QCustomPlot interface. - - It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and - axis label. It also buffers the labels to reduce replot times. The parameters are configured by - directly accessing the public member variables. -*/ - -/*! - Constructs a QCPAxisPainterPrivate instance. Make sure to not create a new instance on every - redraw, to utilize the caching mechanisms. -*/ -QCPAxisPainterPrivate::QCPAxisPainterPrivate(QCustomPlot *parentPlot) : - type(QCPAxis::atLeft), - basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - lowerEnding(QCPLineEnding::esNone), - upperEnding(QCPLineEnding::esNone), - labelPadding(0), - tickLabelPadding(0), - tickLabelRotation(0), - tickLabelSide(QCPAxis::lsOutside), - substituteExponent(true), - numberMultiplyCross(false), - tickLengthIn(5), - tickLengthOut(0), - subTickLengthIn(2), - subTickLengthOut(0), - tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), - offset(0), - abbreviateDecimalPowers(false), - reversedEndings(false), - mParentPlot(parentPlot), - mLabelCache(16) // cache at most 16 (tick) labels -{ -} - -QCPAxisPainterPrivate::~QCPAxisPainterPrivate() -{ -} - -/*! \internal - - Draws the axis with the specified \a painter. - - The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set - here, too. -*/ -void QCPAxisPainterPrivate::draw(QCPPainter *painter) -{ - QByteArray newHash = generateLabelParameterHash(); - if (newHash != mLabelParameterHash) - { - mLabelCache.clear(); - mLabelParameterHash = newHash; - } - - QPoint origin; - switch (type) - { - case QCPAxis::atLeft: origin = axisRect.bottomLeft() +QPoint(-offset, 0); break; - case QCPAxis::atRight: origin = axisRect.bottomRight()+QPoint(+offset, 0); break; - case QCPAxis::atTop: origin = axisRect.topLeft() +QPoint(0, -offset); break; - case QCPAxis::atBottom: origin = axisRect.bottomLeft() +QPoint(0, +offset); break; - } - - double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) - switch (type) - { - case QCPAxis::atTop: yCor = -1; break; - case QCPAxis::atRight: xCor = 1; break; - default: break; - } - int margin = 0; - // draw baseline: - QLineF baseLine; - painter->setPen(basePen); - if (QCPAxis::orientation(type) == Qt::Horizontal) - baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(axisRect.width()+xCor, yCor)); - else - baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -axisRect.height()+yCor)); - if (reversedEndings) - baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later - painter->drawLine(baseLine); - - // draw ticks: - if (!tickPositions.isEmpty()) - { - painter->setPen(tickPen); - int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis) - if (QCPAxis::orientation(type) == Qt::Horizontal) - { - for (int i=0; idrawLine(QLineF(tickPositions.at(i)+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPositions.at(i)+xCor, origin.y()+tickLengthIn*tickDir+yCor)); - } else - { - for (int i=0; idrawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPositions.at(i)+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPositions.at(i)+yCor)); - } - } - - // draw subticks: - if (!subTickPositions.isEmpty()) - { - painter->setPen(subTickPen); - // direction of ticks ("inward" is right for left axis and left for right axis) - int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; - if (QCPAxis::orientation(type) == Qt::Horizontal) - { - for (int i=0; idrawLine(QLineF(subTickPositions.at(i)+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPositions.at(i)+xCor, origin.y()+subTickLengthIn*tickDir+yCor)); - } else - { - for (int i=0; idrawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPositions.at(i)+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPositions.at(i)+yCor)); - } - } - margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); - - // draw axis base endings: - bool antialiasingBackup = painter->antialiasing(); - painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't - painter->setBrush(QBrush(basePen.color())); - QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); - if (lowerEnding.style() != QCPLineEnding::esNone) - lowerEnding.draw(painter, QCPVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector); - if (upperEnding.style() != QCPLineEnding::esNone) - upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); - painter->setAntialiasing(antialiasingBackup); - - // tick labels: - QRect oldClipRect; - if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect - { - oldClipRect = painter->clipRegion().boundingRect(); - painter->setClipRect(axisRect); - } - QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label - if (!tickLabels.isEmpty()) - { - if (tickLabelSide == QCPAxis::lsOutside) - margin += tickLabelPadding; - painter->setFont(tickLabelFont); - painter->setPen(QPen(tickLabelColor)); - const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size()); - int distanceToAxis = margin; - if (tickLabelSide == QCPAxis::lsInside) - distanceToAxis = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); - for (int i=0; isetClipRect(oldClipRect); - - // axis label: - QRect labelBounds; - if (!label.isEmpty()) - { - margin += labelPadding; - painter->setFont(labelFont); - painter->setPen(QPen(labelColor)); - labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, label); - if (type == QCPAxis::atLeft) - { - QTransform oldTransform = painter->transform(); - painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); - painter->rotate(-90); - painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); - painter->setTransform(oldTransform); - } - else if (type == QCPAxis::atRight) - { - QTransform oldTransform = painter->transform(); - painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-axisRect.height()); - painter->rotate(90); - painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); - painter->setTransform(oldTransform); - } - else if (type == QCPAxis::atTop) - painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); - else if (type == QCPAxis::atBottom) - painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); - } - - // set selection boxes: - int selectionTolerance = 0; - if (mParentPlot) - selectionTolerance = mParentPlot->selectionTolerance(); - else - qDebug() << Q_FUNC_INFO << "mParentPlot is null"; - int selAxisOutSize = qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance); - int selAxisInSize = selectionTolerance; - int selTickLabelSize; - int selTickLabelOffset; - if (tickLabelSide == QCPAxis::lsOutside) - { - selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); - selTickLabelOffset = qMax(tickLengthOut, subTickLengthOut)+tickLabelPadding; - } else - { - selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); - selTickLabelOffset = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); - } - int selLabelSize = labelBounds.height(); - int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding; - if (type == QCPAxis::atLeft) - { - mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom()); - mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom()); - mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom()); - } else if (type == QCPAxis::atRight) - { - mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom()); - mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom()); - mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom()); - } else if (type == QCPAxis::atTop) - { - mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize); - mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset); - mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset); - } else if (type == QCPAxis::atBottom) - { - mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize); - mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset); - mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset); - } - mAxisSelectionBox = mAxisSelectionBox.normalized(); - mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized(); - mLabelSelectionBox = mLabelSelectionBox.normalized(); - // draw hitboxes for debug purposes: - //painter->setBrush(Qt::NoBrush); - //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); -} - -/*! \internal - - Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone - direction) needed to fit the axis. -*/ -int QCPAxisPainterPrivate::size() const -{ - int result = 0; - - // get length of tick marks pointing outwards: - if (!tickPositions.isEmpty()) - result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); - - // calculate size of tick labels: - if (tickLabelSide == QCPAxis::lsOutside) - { - QSize tickLabelsSize(0, 0); - if (!tickLabels.isEmpty()) - { - for (int i=0; ibufferDevicePixelRatio())); - result.append(QByteArray::number(tickLabelRotation)); - result.append(QByteArray::number((int)tickLabelSide)); - result.append(QByteArray::number((int)substituteExponent)); - result.append(QByteArray::number((int)numberMultiplyCross)); - result.append(tickLabelColor.name().toLatin1()+QByteArray::number(tickLabelColor.alpha(), 16)); - result.append(tickLabelFont.toString().toLatin1()); - return result; -} - -/*! \internal - - Draws a single tick label with the provided \a painter, utilizing the internal label cache to - significantly speed up drawing of labels that were drawn in previous calls. The tick label is - always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in - pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence - for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), - at which the label should be drawn. - - In order to later draw the axis label in a place that doesn't overlap with the tick labels, the - largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref - drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a - tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently - holds. - - The label is drawn with the font and pen that are currently set on the \a painter. To draw - superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref - getTickLabelData). -*/ -void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize) -{ - // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! - if (text.isEmpty()) return; - QSize finalSize; - QPointF labelAnchor; - switch (type) - { - case QCPAxis::atLeft: labelAnchor = QPointF(axisRect.left()-distanceToAxis-offset, position); break; - case QCPAxis::atRight: labelAnchor = QPointF(axisRect.right()+distanceToAxis+offset, position); break; - case QCPAxis::atTop: labelAnchor = QPointF(position, axisRect.top()-distanceToAxis-offset); break; - case QCPAxis::atBottom: labelAnchor = QPointF(position, axisRect.bottom()+distanceToAxis+offset); break; - } - if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled - { - CachedLabel *cachedLabel = mLabelCache.take(text); // attempt to get label from cache - if (!cachedLabel) // no cached label existed, create it - { - cachedLabel = new CachedLabel; - TickLabelData labelData = getTickLabelData(painter->font(), text); - cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft(); - if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) - { - cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio()); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED -# ifdef QCP_DEVICEPIXELRATIO_FLOAT - cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF()); -# else - cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); -# endif -#endif - } else - cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); - cachedLabel->pixmap.fill(Qt::transparent); - QCPPainter cachePainter(&cachedLabel->pixmap); - cachePainter.setPen(painter->pen()); - drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData); - } - // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): - bool labelClippedByBorder = false; - if (tickLabelSide == QCPAxis::lsOutside) - { - if (QCPAxis::orientation(type) == Qt::Horizontal) - labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); - else - labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); - } - if (!labelClippedByBorder) - { - painter->drawPixmap(labelAnchor+cachedLabel->offset, cachedLabel->pixmap); - finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); - } - mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created - } else // label caching disabled, draw text directly on surface: - { - TickLabelData labelData = getTickLabelData(painter->font(), text); - QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData); - // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): - bool labelClippedByBorder = false; - if (tickLabelSide == QCPAxis::lsOutside) - { - if (QCPAxis::orientation(type) == Qt::Horizontal) - labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); - else - labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); - } - if (!labelClippedByBorder) - { - drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData); - finalSize = labelData.rotatedTotalBounds.size(); - } - } - - // expand passed tickLabelsSize if current tick label is larger: - if (finalSize.width() > tickLabelsSize->width()) - tickLabelsSize->setWidth(finalSize.width()); - if (finalSize.height() > tickLabelsSize->height()) - tickLabelsSize->setHeight(finalSize.height()); -} - -/*! \internal - - This is a \ref placeTickLabel helper function. - - Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a - y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to - directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when - QCP::phCacheLabels plotting hint is not set. -*/ -void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const -{ - // backup painter settings that we're about to change: - QTransform oldTransform = painter->transform(); - QFont oldFont = painter->font(); - - // transform painter to position/rotation: - painter->translate(x, y); - if (!qFuzzyIsNull(tickLabelRotation)) - painter->rotate(tickLabelRotation); - - // draw text: - if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used - { - painter->setFont(labelData.baseFont); - painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); - if (!labelData.suffixPart.isEmpty()) - painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart); - painter->setFont(labelData.expFont); - painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); - } else - { - painter->setFont(labelData.baseFont); - painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); - } - - // reset painter settings to what it was before: - painter->setTransform(oldTransform); - painter->setFont(oldFont); -} - -/*! \internal - - This is a \ref placeTickLabel helper function. - - Transforms the passed \a text and \a font to a tickLabelData structure that can then be further - processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and - exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. -*/ -QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const -{ - TickLabelData result; - - // determine whether beautiful decimal powers should be used - bool useBeautifulPowers = false; - int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart - int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart - if (substituteExponent) - { - ePos = text.indexOf(QLatin1Char('e')); - if (ePos > 0 && text.at(ePos-1).isDigit()) - { - eLast = ePos; - while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) - ++eLast; - if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power - useBeautifulPowers = true; - } - } - - // calculate text bounding rects and do string preparation for beautiful decimal powers: - result.baseFont = font; - if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line - result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding - if (useBeautifulPowers) - { - // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: - result.basePart = text.left(ePos); - result.suffixPart = text.mid(eLast+1); // also drawn normally but after exponent - // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: - if (abbreviateDecimalPowers && result.basePart == QLatin1String("1")) - result.basePart = QLatin1String("10"); - else - result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10"); - result.expPart = text.mid(ePos+1, eLast-ePos); - // clip "+" and leading zeros off expPart: - while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' - result.expPart.remove(1, 1); - if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) - result.expPart.remove(0, 1); - // prepare smaller font for exponent: - result.expFont = font; - if (result.expFont.pointSize() > 0) - result.expFont.setPointSize(result.expFont.pointSize()*0.75); - else - result.expFont.setPixelSize(result.expFont.pixelSize()*0.75); - // calculate bounding rects of base part(s), exponent part and total one: - result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); - result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); - if (!result.suffixPart.isEmpty()) - result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart); - result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA - } else // useBeautifulPowers == false - { - result.basePart = text; - result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); - } - result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler - - // calculate possibly different bounding rect after rotation: - result.rotatedTotalBounds = result.totalBounds; - if (!qFuzzyIsNull(tickLabelRotation)) - { - QTransform transform; - transform.rotate(tickLabelRotation); - result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); - } - - return result; -} - -/*! \internal - - This is a \ref placeTickLabel helper function. - - Calculates the offset at which the top left corner of the specified tick label shall be drawn. - The offset is relative to a point right next to the tick the label belongs to. - - This function is thus responsible for e.g. centering tick labels under ticks and positioning them - appropriately when they are rotated. -*/ -QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &labelData) const -{ - /* - calculate label offset from base point at tick (non-trivial, for best visual appearance): short - explanation for bottom axis: The anchor, i.e. the point in the label that is placed - horizontally under the corresponding tick is always on the label side that is closer to the - axis (e.g. the left side of the text when we're rotating clockwise). On that side, the height - is halved and the resulting point is defined the anchor. This way, a 90 degree rotated text - will be centered under the tick (i.e. displaced horizontally by half its height). At the same - time, a 45 degree rotated text will "point toward" its tick, as is typical for rotated tick - labels. - */ - bool doRotation = !qFuzzyIsNull(tickLabelRotation); - bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes. - double radians = tickLabelRotation/180.0*M_PI; - int x=0, y=0; - if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label - { - if (doRotation) - { - if (tickLabelRotation > 0) - { - x = -qCos(radians)*labelData.totalBounds.width(); - y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0; - } else - { - x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height(); - y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0; - } - } else - { - x = -labelData.totalBounds.width(); - y = -labelData.totalBounds.height()/2.0; - } - } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label - { - if (doRotation) - { - if (tickLabelRotation > 0) - { - x = +qSin(radians)*labelData.totalBounds.height(); - y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0; - } else - { - x = 0; - y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0; - } - } else - { - x = 0; - y = -labelData.totalBounds.height()/2.0; - } - } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label - { - if (doRotation) - { - if (tickLabelRotation > 0) - { - x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0; - y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height(); - } else - { - x = -qSin(-radians)*labelData.totalBounds.height()/2.0; - y = -qCos(-radians)*labelData.totalBounds.height(); - } - } else - { - x = -labelData.totalBounds.width()/2.0; - y = -labelData.totalBounds.height(); - } - } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label - { - if (doRotation) - { - if (tickLabelRotation > 0) - { - x = +qSin(radians)*labelData.totalBounds.height()/2.0; - y = 0; - } else - { - x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height()/2.0; - y = +qSin(-radians)*labelData.totalBounds.width(); - } - } else - { - x = -labelData.totalBounds.width()/2.0; - y = 0; - } - } - - return QPointF(x, y); -} - -/*! \internal - - Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label - to be drawn, depending on number format etc. Since only the largest tick label is wanted for the - margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a - smaller width/height. -*/ -void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const -{ - // note: this function must return the same tick label sizes as the placeTickLabel function. - QSize finalSize; - if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label - { - const CachedLabel *cachedLabel = mLabelCache.object(text); - finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); - } else // label caching disabled or no label with this text cached: - { - TickLabelData labelData = getTickLabelData(font, text); - finalSize = labelData.rotatedTotalBounds.size(); - } - - // expand passed tickLabelsSize if current tick label is larger: - if (finalSize.width() > tickLabelsSize->width()) - tickLabelsSize->setWidth(finalSize.width()); - if (finalSize.height() > tickLabelsSize->height()) - tickLabelsSize->setHeight(finalSize.height()); -} -/* end of 'src/axis/axis.cpp' */ - - -/* including file 'src/scatterstyle.cpp', size 17450 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPScatterStyle -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPScatterStyle - \brief Represents the visual appearance of scatter points - - This class holds information about shape, color and size of scatter points. In plottables like - QCPGraph it is used to store how scatter points shall be drawn. For example, \ref - QCPGraph::setScatterStyle takes a QCPScatterStyle instance. - - A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a - fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can - be controlled with \ref setSize. - - \section QCPScatterStyle-defining Specifying a scatter style - - You can set all these configurations either by calling the respective functions on an instance: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 - - Or you can use one of the various constructors that take different parameter combinations, making - it easy to specify a scatter style in a single call, like so: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 - - \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable - - There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref - QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref - isPenDefined will return false. It leads to scatter points that inherit the pen from the - plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line - color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes - it very convenient to set up typical scatter settings: - - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation - - Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works - because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly - into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) - constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref - ScatterShape, where actually a QCPScatterStyle is expected. - - \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps - - QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. - - For custom shapes, you can provide a QPainterPath with the desired shape to the \ref - setCustomPath function or call the constructor that takes a painter path. The scatter shape will - automatically be set to \ref ssCustom. - - For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the - constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. - Note that \ref setSize does not influence the appearance of the pixmap. -*/ - -/* start documentation of inline functions */ - -/*! \fn bool QCPScatterStyle::isNone() const - - Returns whether the scatter shape is \ref ssNone. - - \see setShape -*/ - -/*! \fn bool QCPScatterStyle::isPenDefined() const - - Returns whether a pen has been defined for this scatter style. - - The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those - are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen - is undefined, the pen of the respective plottable will be used for drawing scatters. - - If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call - \ref undefinePen. - - \see setPen -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. - - Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited - from the plottable that uses this scatter style. -*/ -QCPScatterStyle::QCPScatterStyle() : - mSize(6), - mShape(ssNone), - mPen(Qt::NoPen), - mBrush(Qt::NoBrush), - mPenDefined(false) -{ -} - -/*! - Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or - brush is defined. - - Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited - from the plottable that uses this scatter style. -*/ -QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) : - mSize(size), - mShape(shape), - mPen(Qt::NoPen), - mBrush(Qt::NoBrush), - mPenDefined(false) -{ -} - -/*! - Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, - and size to \a size. No brush is defined, i.e. the scatter point will not be filled. -*/ -QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) : - mSize(size), - mShape(shape), - mPen(QPen(color)), - mBrush(Qt::NoBrush), - mPenDefined(true) -{ -} - -/*! - Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, - the brush color to \a fill (with a solid pattern), and size to \a size. -*/ -QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) : - mSize(size), - mShape(shape), - mPen(QPen(color)), - mBrush(QBrush(fill)), - mPenDefined(true) -{ -} - -/*! - Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the - brush to \a brush, and size to \a size. - - \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen - and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n - QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n - doesn't necessarily lead C++ to use this constructor in some cases, but might mistake - Qt::NoPen for a QColor and use the - \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) - constructor instead (which will lead to an unexpected look of the scatter points). To prevent - this, be more explicit with the parameter types. For example, use QBrush(Qt::blue) - instead of just Qt::blue, to clearly point out to the compiler that this constructor is - wanted. -*/ -QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) : - mSize(size), - mShape(shape), - mPen(pen), - mBrush(brush), - mPenDefined(pen.style() != Qt::NoPen) -{ -} - -/*! - Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape - is set to \ref ssPixmap. -*/ -QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : - mSize(5), - mShape(ssPixmap), - mPen(Qt::NoPen), - mBrush(Qt::NoBrush), - mPixmap(pixmap), - mPenDefined(false) -{ -} - -/*! - Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The - scatter shape is set to \ref ssCustom. - - The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly - different meaning than for built-in scatter points: The custom path will be drawn scaled by a - factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its - original size by default. To for example double the size of the path, set \a size to 12. -*/ -QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) : - mSize(size), - mShape(ssCustom), - mPen(pen), - mBrush(brush), - mCustomPath(customPath), - mPenDefined(pen.style() != Qt::NoPen) -{ -} - -/*! - Copies the specified \a properties from the \a other scatter style to this scatter style. -*/ -void QCPScatterStyle::setFromOther(const QCPScatterStyle &other, ScatterProperties properties) -{ - if (properties.testFlag(spPen)) - { - setPen(other.pen()); - if (!other.isPenDefined()) - undefinePen(); - } - if (properties.testFlag(spBrush)) - setBrush(other.brush()); - if (properties.testFlag(spSize)) - setSize(other.size()); - if (properties.testFlag(spShape)) - { - setShape(other.shape()); - if (other.shape() == ssPixmap) - setPixmap(other.pixmap()); - else if (other.shape() == ssCustom) - setCustomPath(other.customPath()); - } -} - -/*! - Sets the size (pixel diameter) of the drawn scatter points to \a size. - - \see setShape -*/ -void QCPScatterStyle::setSize(double size) -{ - mSize = size; -} - -/*! - Sets the shape to \a shape. - - Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref - ssPixmap and \ref ssCustom, respectively. - - \see setSize -*/ -void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) -{ - mShape = shape; -} - -/*! - Sets the pen that will be used to draw scatter points to \a pen. - - If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after - a call to this function, even if \a pen is Qt::NoPen. If you have defined a pen - previously by calling this function and now wish to undefine the pen, call \ref undefinePen. - - \see setBrush -*/ -void QCPScatterStyle::setPen(const QPen &pen) -{ - mPenDefined = true; - mPen = pen; -} - -/*! - Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter - shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. - - \see setPen -*/ -void QCPScatterStyle::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the pixmap that will be drawn as scatter point to \a pixmap. - - Note that \ref setSize does not influence the appearance of the pixmap. - - The scatter shape is automatically set to \ref ssPixmap. -*/ -void QCPScatterStyle::setPixmap(const QPixmap &pixmap) -{ - setShape(ssPixmap); - mPixmap = pixmap; -} - -/*! - Sets the custom shape that will be drawn as scatter point to \a customPath. - - The scatter shape is automatically set to \ref ssCustom. -*/ -void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) -{ - setShape(ssCustom); - mCustomPath = customPath; -} - -/*! - Sets this scatter style to have an undefined pen (see \ref isPenDefined for what an undefined pen - implies). - - A call to \ref setPen will define a pen. -*/ -void QCPScatterStyle::undefinePen() -{ - mPenDefined = false; -} - -/*! - Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an - undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. - - This function is used by plottables (or any class that wants to draw scatters) just before a - number of scatters with this style shall be drawn with the \a painter. - - \see drawShape -*/ -void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const -{ - painter->setPen(mPenDefined ? mPen : defaultPen); - painter->setBrush(mBrush); -} - -/*! - Draws the scatter shape with \a painter at position \a pos. - - This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be - called before scatter points are drawn with \ref drawShape. - - \see applyTo -*/ -void QCPScatterStyle::drawShape(QCPPainter *painter, const QPointF &pos) const -{ - drawShape(painter, pos.x(), pos.y()); -} - -/*! \overload - Draws the scatter shape with \a painter at position \a x and \a y. -*/ -void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const -{ - double w = mSize/2.0; - switch (mShape) - { - case ssNone: break; - case ssDot: - { - painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y)); - break; - } - case ssCross: - { - painter->drawLine(QLineF(x-w, y-w, x+w, y+w)); - painter->drawLine(QLineF(x-w, y+w, x+w, y-w)); - break; - } - case ssPlus: - { - painter->drawLine(QLineF(x-w, y, x+w, y)); - painter->drawLine(QLineF( x, y+w, x, y-w)); - break; - } - case ssCircle: - { - painter->drawEllipse(QPointF(x , y), w, w); - break; - } - case ssDisc: - { - QBrush b = painter->brush(); - painter->setBrush(painter->pen().color()); - painter->drawEllipse(QPointF(x , y), w, w); - painter->setBrush(b); - break; - } - case ssSquare: - { - painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); - break; - } - case ssDiamond: - { - QPointF lineArray[4] = {QPointF(x-w, y), - QPointF( x, y-w), - QPointF(x+w, y), - QPointF( x, y+w)}; - painter->drawPolygon(lineArray, 4); - break; - } - case ssStar: - { - painter->drawLine(QLineF(x-w, y, x+w, y)); - painter->drawLine(QLineF( x, y+w, x, y-w)); - painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); - painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); - break; - } - case ssTriangle: - { - QPointF lineArray[3] = {QPointF(x-w, y+0.755*w), - QPointF(x+w, y+0.755*w), - QPointF( x, y-0.977*w)}; - painter->drawPolygon(lineArray, 3); - break; - } - case ssTriangleInverted: - { - QPointF lineArray[3] = {QPointF(x-w, y-0.755*w), - QPointF(x+w, y-0.755*w), - QPointF( x, y+0.977*w)}; - painter->drawPolygon(lineArray, 3); - break; - } - case ssCrossSquare: - { - painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); - painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); - painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); - break; - } - case ssPlusSquare: - { - painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); - painter->drawLine(QLineF(x-w, y, x+w*0.95, y)); - painter->drawLine(QLineF( x, y+w, x, y-w)); - break; - } - case ssCrossCircle: - { - painter->drawEllipse(QPointF(x, y), w, w); - painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670)); - painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707)); - break; - } - case ssPlusCircle: - { - painter->drawEllipse(QPointF(x, y), w, w); - painter->drawLine(QLineF(x-w, y, x+w, y)); - painter->drawLine(QLineF( x, y+w, x, y-w)); - break; - } - case ssPeace: - { - painter->drawEllipse(QPointF(x, y), w, w); - painter->drawLine(QLineF(x, y-w, x, y+w)); - painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); - painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); - break; - } - case ssPixmap: - { - const double widthHalf = mPixmap.width()*0.5; - const double heightHalf = mPixmap.height()*0.5; -#if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) - const QRectF clipRect = painter->clipRegion().boundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); -#else - const QRectF clipRect = painter->clipBoundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); -#endif - if (clipRect.contains(x, y)) - painter->drawPixmap(x-widthHalf, y-heightHalf, mPixmap); - break; - } - case ssCustom: - { - QTransform oldTransform = painter->transform(); - painter->translate(x, y); - painter->scale(mSize/6.0, mSize/6.0); - painter->drawPath(mCustomPath); - painter->setTransform(oldTransform); - break; - } - } -} -/* end of 'src/scatterstyle.cpp' */ - -//amalgamation: add datacontainer.cpp - -/* including file 'src/plottable.cpp', size 38845 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPSelectionDecorator -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPSelectionDecorator - \brief Controls how a plottable's data selection is drawn - - Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref - QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data. - - The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the - scatter style (\ref setScatterStyle) if the plottable draws scatters. Since a \ref - QCPScatterStyle is itself composed of different properties such as color shape and size, the - decorator allows specifying exactly which of those properties shall be used for the selected data - point, via \ref setUsedScatterProperties. - - A \ref QCPSelectionDecorator subclass instance can be passed to a plottable via \ref - QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance - of selected segments. - - Use \ref copyFrom to easily transfer the settings of one decorator to another one. This is - especially useful since plottables take ownership of the passed selection decorator, and thus the - same decorator instance can not be passed to multiple plottables. - - Selection decorators can also themselves perform drawing operations by reimplementing \ref - drawDecoration, which is called by the plottable's draw method. The base class \ref - QCPSelectionDecorator does not make use of this however. For example, \ref - QCPSelectionDecoratorBracket draws brackets around selected data segments. -*/ - -/*! - Creates a new QCPSelectionDecorator instance with default values -*/ -QCPSelectionDecorator::QCPSelectionDecorator() : - mPen(QColor(80, 80, 255), 2.5), - mBrush(Qt::NoBrush), - mScatterStyle(), - mUsedScatterProperties(QCPScatterStyle::spNone), - mPlottable(0) -{ -} - -QCPSelectionDecorator::~QCPSelectionDecorator() -{ -} - -/*! - Sets the pen that will be used by the parent plottable to draw selected data segments. -*/ -void QCPSelectionDecorator::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the brush that will be used by the parent plottable to draw selected data segments. -*/ -void QCPSelectionDecorator::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the scatter style that will be used by the parent plottable to draw scatters in selected - data segments. - - \a usedProperties specifies which parts of the passed \a scatterStyle will be used by the - plottable. The used properties can also be changed via \ref setUsedScatterProperties. -*/ -void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties) -{ - mScatterStyle = scatterStyle; - setUsedScatterProperties(usedProperties); -} - -/*! - Use this method to define which properties of the scatter style (set via \ref setScatterStyle) - will be used for selected data segments. All properties of the scatter style that are not - specified in \a properties will remain as specified in the plottable's original scatter style. - - \see QCPScatterStyle::ScatterProperty -*/ -void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties) -{ - mUsedScatterProperties = properties; -} - -/*! - Sets the pen of \a painter to the pen of this selection decorator. - - \see applyBrush, getFinalScatterStyle -*/ -void QCPSelectionDecorator::applyPen(QCPPainter *painter) const -{ - painter->setPen(mPen); -} - -/*! - Sets the brush of \a painter to the brush of this selection decorator. - - \see applyPen, getFinalScatterStyle -*/ -void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const -{ - painter->setBrush(mBrush); -} - -/*! - Returns the scatter style that the parent plottable shall use for selected scatter points. The - plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending - on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this - selecion decorator's scatter style (\ref setScatterStyle), and \a unselectedStyle. - - \see applyPen, applyBrush, setScatterStyle -*/ -QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const -{ - QCPScatterStyle result(unselectedStyle); - result.setFromOther(mScatterStyle, mUsedScatterProperties); - - // if style shall inherit pen from plottable (has no own pen defined), give it the selected - // plottable pen explicitly, so it doesn't use the unselected plottable pen when used in the - // plottable: - if (!result.isPenDefined()) - result.setPen(mPen); - - return result; -} - -/*! - Copies all properties (e.g. color, fill, scatter style) of the \a other selection decorator to - this selection decorator. -*/ -void QCPSelectionDecorator::copyFrom(const QCPSelectionDecorator *other) -{ - setPen(other->pen()); - setBrush(other->brush()); - setScatterStyle(other->scatterStyle(), other->usedScatterProperties()); -} - -/*! - This method is called by all plottables' draw methods to allow custom selection decorations to be - drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data - selection for which the decoration shall be drawn. - - The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so - this method does nothing. -*/ -void QCPSelectionDecorator::drawDecoration(QCPPainter *painter, QCPDataSelection selection) -{ - Q_UNUSED(painter) - Q_UNUSED(selection) -} - -/*! \internal - - This method is called as soon as a selection decorator is associated with a plottable, by a call - to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access - data points via the \ref QCPAbstractPlottable::interface1D interface). - - If the selection decorator was already added to a different plottable before, this method aborts - the registration and returns false. -*/ -bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottable) -{ - if (!mPlottable) - { - mPlottable = plottable; - return true; - } else - { - qDebug() << Q_FUNC_INFO << "This selection decorator is already registered with plottable:" << reinterpret_cast(mPlottable); - return false; - } -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractPlottable -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractPlottable - \brief The abstract base class for all data representing objects in a plot. - - It defines a very basic interface like name, pen, brush, visibility etc. Since this class is - abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to - create new ways of displaying data (see "Creating own plottables" below). Plottables that display - one-dimensional data (i.e. data points have a single key dimension and one or multiple values at - each key) are based off of the template subclass \ref QCPAbstractPlottable1D, see details - there. - - All further specifics are in the subclasses, for example: - \li A normal graph with possibly a line and/or scatter points \ref QCPGraph - (typically created with \ref QCustomPlot::addGraph) - \li A parametric curve: \ref QCPCurve - \li A bar chart: \ref QCPBars - \li A statistical box plot: \ref QCPStatisticalBox - \li A color encoded two-dimensional map: \ref QCPColorMap - \li An OHLC/Candlestick chart: \ref QCPFinancial - - \section plottables-subclassing Creating own plottables - - Subclassing directly from QCPAbstractPlottable is only recommended if you wish to display - two-dimensional data like \ref QCPColorMap, i.e. two logical key dimensions and one (or more) - data dimensions. If you want to display data with only one logical key dimension, you should - rather derive from \ref QCPAbstractPlottable1D. - - If subclassing QCPAbstractPlottable directly, these are the pure virtual functions you must - implement: - \li \ref selectTest - \li \ref draw - \li \ref drawLegendIcon - \li \ref getKeyRange - \li \ref getValueRange - - See the documentation of those functions for what they need to do. - - For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot - coordinates to pixel coordinates. This function is quite convenient, because it takes the - orientation of the key and value axes into account for you (x and y are swapped when the key axis - is vertical and the value axis horizontal). If you are worried about performance (i.e. you need - to translate many points in a loop like QCPGraph), you can directly use \ref - QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis - yourself. - - Here are some important members you inherit from QCPAbstractPlottable: - - - - - - - - - - - - - - - - - - - - - - - - - - -
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable - (e.g QCPGraph uses this pen for its graph lines and scatters)
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable - (e.g. QCPGraph uses this brush to control filling under the graph)
QPointer<\ref QCPAxis> \b mKeyAxis, \b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates - to pixels in either the key or value dimension. Make sure to check whether the pointer is null before using it. If one of - the axes is null, don't draw the plottable.
\ref QCPSelectionDecorator \b mSelectionDecoratorThe currently set selection decorator which specifies how selected data of the plottable shall be drawn and decorated. - When drawing your data, you must consult this decorator for the appropriate pen/brush before drawing unselected/selected data segments. - Finally, you should call its \ref QCPSelectionDecorator::drawDecoration method at the end of your \ref draw implementation.
\ref QCP::SelectionType \b mSelectableIn which composition, if at all, this plottable's data may be selected. Enforcing this setting on the data selection is done - by QCPAbstractPlottable automatically.
\ref QCPDataSelection \b mSelectionHolds the current selection state of the plottable's data, i.e. the selected data ranges (\ref QCPDataRange).
-*/ - -/* start of documentation of inline functions */ - -/*! \fn QCPSelectionDecorator *QCPAbstractPlottable::selectionDecorator() const - - Provides access to the selection decorator of this plottable. The selection decorator controls - how selected data ranges are drawn (e.g. their pen color and fill), see \ref - QCPSelectionDecorator for details. - - If you wish to use an own \ref QCPSelectionDecorator subclass, pass an instance of it to \ref - setSelectionDecorator. -*/ - -/*! \fn bool QCPAbstractPlottable::selected() const - - Returns true if there are any data points of the plottable currently selected. Use \ref selection - to retrieve the current \ref QCPDataSelection. -*/ - -/*! \fn QCPDataSelection QCPAbstractPlottable::selection() const - - Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on - this plottable. - - \see selected, setSelection, setSelectable -*/ - -/*! \fn virtual QCPPlottableInterface1D *QCPAbstractPlottable::interface1D() - - If this plottable is a one-dimensional plottable, i.e. it implements the \ref - QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case - of a \ref QCPColorMap) returns zero. - - You can use this method to gain read access to data coordinates while holding a pointer to the - abstract base class only. -*/ - -/* end of documentation of inline functions */ -/* start of documentation of pure virtual functions */ - -/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 - \internal - - called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation - of this plottable inside \a rect, next to the plottable name. - - The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't - appear outside the legend icon border. -*/ - -/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0 - - Returns the coordinate range that all data in this plottable span in the key axis dimension. For - logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref - QCP::sdPositive in order to restrict the returned range to that sign domain. E.g. when only - negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and all positive points - will be ignored for range calculation. For no restriction, just set \a inSignDomain to \ref - QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could - be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data). - - Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by - this function may have size zero (e.g. when there is only one data point). In this case \a - foundRange would return true, but the returned range is not a valid range in terms of \ref - QCPRange::validRange. - - \see rescaleAxes, getValueRange -*/ - -/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0 - - Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span - in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref - QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign - domain. E.g. when only negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and - all positive points will be ignored for range calculation. For no restriction, just set \a - inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates - whether a range could be found or not. If this is false, you shouldn't use the returned range - (e.g. no points in data). - - If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), - all data points are considered, without any restriction on the keys. - - Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by - this function may have size zero (e.g. when there is only one data point). In this case \a - foundRange would return true, but the returned range is not a valid range in terms of \ref - QCPRange::validRange. - - \see rescaleAxes, getKeyRange -*/ - -/* end of documentation of pure virtual functions */ -/* start of documentation of signals */ - -/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) - - This signal is emitted when the selection state of this plottable has changed, either by user - interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether - there are any points selected or not. - - \see selectionChanged(const QCPDataSelection &selection) -*/ - -/*! \fn void QCPAbstractPlottable::selectionChanged(const QCPDataSelection &selection) - - This signal is emitted when the selection state of this plottable has changed, either by user - interaction or by a direct call to \ref setSelection. The parameter \a selection holds the - currently selected data ranges. - - \see selectionChanged(bool selected) -*/ - -/*! \fn void QCPAbstractPlottable::selectableChanged(QCP::SelectionType selectable); - - This signal is emitted when the selectability of this plottable has changed. - - \see setSelectable -*/ - -/* end of documentation of signals */ - -/*! - Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as - its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance - and have perpendicular orientations. If either of these restrictions is violated, a corresponding - message is printed to the debug output (qDebug), the construction is not aborted, though. - - Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, - it can't be directly instantiated. - - You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. -*/ -QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()), - mName(), - mDesc(), - mAntialiasedFill(true), - mAntialiasedScatters(true), - mPen(Qt::black), - mBrush(Qt::NoBrush), - mKeyAxis(keyAxis), - mValueAxis(valueAxis), - mSelectable(QCP::stWhole), - mSelectionDecorator(0) -{ - if (keyAxis->parentPlot() != valueAxis->parentPlot()) - qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; - if (keyAxis->orientation() == valueAxis->orientation()) - qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; - - mParentPlot->registerPlottable(this); - setSelectionDecorator(new QCPSelectionDecorator); -} - -QCPAbstractPlottable::~QCPAbstractPlottable() -{ - if (mSelectionDecorator) - { - delete mSelectionDecorator; - mSelectionDecorator = 0; - } -} - -/*! - The name is the textual representation of this plottable as it is displayed in the legend - (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. -*/ -void QCPAbstractPlottable::setName(const QString &name) -{ - mName = name; -} - -void QCPAbstractPlottable::setDesc(const QString &desc) -{ - mDesc = desc; -} - -/*! - Sets whether fills of this plottable are drawn antialiased or not. - - Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. -*/ -void QCPAbstractPlottable::setAntialiasedFill(bool enabled) -{ - mAntialiasedFill = enabled; -} - -/*! - Sets whether the scatter symbols of this plottable are drawn antialiased or not. - - Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. -*/ -void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) -{ - mAntialiasedScatters = enabled; -} - -/*! - The pen is used to draw basic lines that make up the plottable representation in the - plot. - - For example, the \ref QCPGraph subclass draws its graph lines with this pen. - - \see setBrush -*/ -void QCPAbstractPlottable::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - The brush is used to draw basic fills of the plottable representation in the - plot. The Fill can be a color, gradient or texture, see the usage of QBrush. - - For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when - it's not set to Qt::NoBrush. - - \see setPen -*/ -void QCPAbstractPlottable::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal - to the plottable's value axis. This function performs no checks to make sure this is the case. - The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the - y-axis (QCustomPlot::yAxis) as value axis. - - Normally, the key and value axes are set in the constructor of the plottable (or \ref - QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). - - \see setValueAxis -*/ -void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) -{ - mKeyAxis = axis; -} - -/*! - The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is - orthogonal to the plottable's key axis. This function performs no checks to make sure this is the - case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and - the y-axis (QCustomPlot::yAxis) as value axis. - - Normally, the key and value axes are set in the constructor of the plottable (or \ref - QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). - - \see setKeyAxis -*/ -void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) -{ - mValueAxis = axis; -} - - -/*! - Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently - (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref - selectionDecorator). - - The entire selection mechanism for plottables is handled automatically when \ref - QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when - you wish to change the selection state programmatically. - - Using \ref setSelectable you can further specify for each plottable whether and to which - granularity it is selectable. If \a selection is not compatible with the current \ref - QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted - accordingly (see \ref QCPDataSelection::enforceType). - - emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - - \see setSelectable, selectTest -*/ -void QCPAbstractPlottable::setSelection(QCPDataSelection selection) -{ - selection.enforceType(mSelectable); - if (mSelection != selection) - { - mSelection = selection; - emit selectionChanged(selected()); - emit selectionChanged(mSelection); - } -} - -/*! - Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to - customize the visual representation of selected data ranges further than by using the default - QCPSelectionDecorator. - - The plottable takes ownership of the \a decorator. - - The currently set decorator can be accessed via \ref selectionDecorator. -*/ -void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorator) -{ - if (decorator) - { - if (decorator->registerWithPlottable(this)) - { - if (mSelectionDecorator) // delete old decorator if necessary - delete mSelectionDecorator; - mSelectionDecorator = decorator; - } - } else if (mSelectionDecorator) // just clear decorator - { - delete mSelectionDecorator; - mSelectionDecorator = 0; - } -} - -/*! - Sets whether and to which granularity this plottable can be selected. - - A selection can happen by clicking on the QCustomPlot surface (When \ref - QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect - (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by - calling \ref setSelection. - - \see setSelection, QCP::SelectionType -*/ -void QCPAbstractPlottable::setSelectable(QCP::SelectionType selectable) -{ - if (mSelectable != selectable) - { - mSelectable = selectable; - QCPDataSelection oldSelection = mSelection; - mSelection.enforceType(mSelectable); - emit selectableChanged(mSelectable); - if (mSelection != oldSelection) - { - emit selectionChanged(selected()); - emit selectionChanged(mSelection); - } - } -} - - -/*! - Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, - taking the orientations of the axes associated with this plottable into account (e.g. whether key - represents x or y). - - \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. - - \see pixelsToCoords, QCPAxis::coordToPixel -*/ -void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - if (keyAxis->orientation() == Qt::Horizontal) - { - x = keyAxis->coordToPixel(key); - y = valueAxis->coordToPixel(value); - } else - { - y = keyAxis->coordToPixel(key); - x = valueAxis->coordToPixel(value); - } -} - -/*! \overload - - Transforms the given \a key and \a value to pixel coordinates and returns them in a QPointF. -*/ -const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } - - if (keyAxis->orientation() == Qt::Horizontal) - return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); - else - return QPointF(valueAxis->coordToPixel(value), keyAxis->coordToPixel(key)); -} - -/*! - Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, - taking the orientations of the axes associated with this plottable into account (e.g. whether key - represents x or y). - - \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. - - \see coordsToPixels, QCPAxis::coordToPixel -*/ -void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - if (keyAxis->orientation() == Qt::Horizontal) - { - key = keyAxis->pixelToCoord(x); - value = valueAxis->pixelToCoord(y); - } else - { - key = keyAxis->pixelToCoord(y); - value = valueAxis->pixelToCoord(x); - } -} - -/*! \overload - - Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. -*/ -void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const -{ - pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); -} - -/*! - Rescales the key and value axes associated with this plottable to contain all displayed data, so - the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make - sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. - Instead it will stay in the current sign domain and ignore all parts of the plottable that lie - outside of that domain. - - \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show - multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has - \a onlyEnlarge set to false (the default), and all subsequent set to true. - - \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale -*/ -void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const -{ - rescaleKeyAxis(onlyEnlarge); - rescaleValueAxis(onlyEnlarge); -} - -/*! - Rescales the key axis of the plottable so the whole plottable is visible. - - See \ref rescaleAxes for detailed behaviour. -*/ -void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } - - QCP::SignDomain signDomain = QCP::sdBoth; - if (keyAxis->scaleType() == QCPAxis::stLogarithmic) - signDomain = (keyAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); - - bool foundRange; - QCPRange newRange = getKeyRange(foundRange, signDomain); - if (foundRange) - { - if (onlyEnlarge) - newRange.expand(keyAxis->range()); - if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable - { - double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason - if (keyAxis->scaleType() == QCPAxis::stLinear) - { - newRange.lower = center-keyAxis->range().size()/2.0; - newRange.upper = center+keyAxis->range().size()/2.0; - } else // scaleType() == stLogarithmic - { - newRange.lower = center/qSqrt(keyAxis->range().upper/keyAxis->range().lower); - newRange.upper = center*qSqrt(keyAxis->range().upper/keyAxis->range().lower); - } - } - keyAxis->setRange(newRange); - } -} - -/*! - Rescales the value axis of the plottable so the whole plottable is visible. If \a inKeyRange is - set to true, only the data points which are in the currently visible key axis range are - considered. - - Returns true if the axis was actually scaled. This might not be the case if this plottable has an - invalid range, e.g. because it has no data points. - - See \ref rescaleAxes for detailed behaviour. -*/ -void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - QCP::SignDomain signDomain = QCP::sdBoth; - if (valueAxis->scaleType() == QCPAxis::stLogarithmic) - signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); - - bool foundRange; - QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); - if (foundRange) - { - if (onlyEnlarge) - newRange.expand(valueAxis->range()); - if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable - { - double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason - if (valueAxis->scaleType() == QCPAxis::stLinear) - { - newRange.lower = center-valueAxis->range().size()/2.0; - newRange.upper = center+valueAxis->range().size()/2.0; - } else // scaleType() == stLogarithmic - { - newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); - newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); - } - } - valueAxis->setRange(newRange); - } -} - -/*! \overload - - Adds this plottable to the specified \a legend. - - Creates a QCPPlottableLegendItem which is inserted into the legend. Returns true on success, i.e. - when the legend exists and a legend item associated with this plottable isn't already in the - legend. - - If the plottable needs a more specialized representation in the legend, you can create a - corresponding subclass of \ref QCPPlottableLegendItem and add it to the legend manually instead - of calling this method. - - \see removeFromLegend, QCPLegend::addItem -*/ -bool QCPAbstractPlottable::addToLegend(QCPLegend *legend) -{ - if (!legend) - { - qDebug() << Q_FUNC_INFO << "passed legend is null"; - return false; - } - if (legend->parentPlot() != mParentPlot) - { - qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; - return false; - } - - if (!legend->hasItemWithPlottable(this)) - { - legend->addItem(new QCPPlottableLegendItem(legend, this)); - return true; - } else - return false; -} - -/*! \overload - - Adds this plottable to the legend of the parent QCustomPlot (\ref QCustomPlot::legend). - - \see removeFromLegend -*/ -bool QCPAbstractPlottable::addToLegend() -{ - if (!mParentPlot || !mParentPlot->legend) - return false; - else - return addToLegend(mParentPlot->legend); -} - -/*! \overload - - Removes the plottable from the specifed \a legend. This means the \ref QCPPlottableLegendItem - that is associated with this plottable is removed. - - Returns true on success, i.e. if the legend exists and a legend item associated with this - plottable was found and removed. - - \see addToLegend, QCPLegend::removeItem -*/ -bool QCPAbstractPlottable::removeFromLegend(QCPLegend *legend) const -{ - if (!legend) - { - qDebug() << Q_FUNC_INFO << "passed legend is null"; - return false; - } - - if (QCPPlottableLegendItem *lip = legend->itemWithPlottable(this)) - return legend->removeItem(lip); - else - return false; -} - -/*! \overload - - Removes the plottable from the legend of the parent QCustomPlot. - - \see addToLegend -*/ -bool QCPAbstractPlottable::removeFromLegend() const -{ - if (!mParentPlot || !mParentPlot->legend) - return false; - else - return removeFromLegend(mParentPlot->legend); -} - -/* inherits documentation from base class */ -QRect QCPAbstractPlottable::clipRect() const -{ - if (mKeyAxis && mValueAxis) - return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect(); - else - return QRect(); -} - -/* inherits documentation from base class */ -QCP::Interaction QCPAbstractPlottable::selectionCategory() const -{ - return QCP::iSelectPlottables; -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing plottable lines. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \seebaseclassmethod - - \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint -*/ -void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing plottable fills. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint -*/ -void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing plottable scatter points. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint -*/ -void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); -} - -/* inherits documentation from base class */ -void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - - if (mSelectable != QCP::stNone) - { - QCPDataSelection newSelection = details.value(); - QCPDataSelection selectionBefore = mSelection; - if (additive) - { - if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit - { - if (selected()) - setSelection(QCPDataSelection()); - else - setSelection(newSelection); - } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments - { - if (mSelection.contains(newSelection)) // if entire newSelection is already selected, toggle selection - setSelection(mSelection-newSelection); - else - setSelection(mSelection+newSelection); - } - } else - setSelection(newSelection); - if (selectionStateChanged) - *selectionStateChanged = mSelection != selectionBefore; - } -} - -/* inherits documentation from base class */ -void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) -{ - if (mSelectable != QCP::stNone) - { - QCPDataSelection selectionBefore = mSelection; - setSelection(QCPDataSelection()); - if (selectionStateChanged) - *selectionStateChanged = mSelection != selectionBefore; - } -} -/* end of 'src/plottable.cpp' */ - - -/* including file 'src/item.cpp', size 49269 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemAnchor -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemAnchor - \brief An anchor of an item to which positions can be attached to. - - An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't - control anything on its item, but provides a way to tie other items via their positions to the - anchor. - - For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. - Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can - attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by - calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the - QCPItemRect. This way the start of the line will now always follow the respective anchor location - on the rect item. - - Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an - anchor to other positions. - - To learn how to provide anchors in your own item subclasses, see the subclassing section of the - QCPAbstractItem documentation. -*/ - -/* start documentation of inline functions */ - -/*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() - - Returns 0 if this instance is merely a QCPItemAnchor, and a valid pointer of type QCPItemPosition* if - it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). - - This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids - dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with - gcc compiler). -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if - you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as - explained in the subclassing section of the QCPAbstractItem documentation. -*/ -QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId) : - mName(name), - mParentPlot(parentPlot), - mParentItem(parentItem), - mAnchorId(anchorId) -{ -} - -QCPItemAnchor::~QCPItemAnchor() -{ - // unregister as parent at children: - foreach (QCPItemPosition *child, mChildrenX.toList()) - { - if (child->parentAnchorX() == this) - child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX - } - foreach (QCPItemPosition *child, mChildrenY.toList()) - { - if (child->parentAnchorY() == this) - child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY - } -} - -/*! - Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. - - The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the - parent item, QCPItemAnchor is just an intermediary. -*/ -QPointF QCPItemAnchor::pixelPosition() const -{ - if (mParentItem) - { - if (mAnchorId > -1) - { - return mParentItem->anchorPixelPosition(mAnchorId); - } else - { - qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; - return QPointF(); - } - } else - { - qDebug() << Q_FUNC_INFO << "no parent item set"; - return QPointF(); - } -} - -/*! \internal - - Adds \a pos to the childX list of this anchor, which keeps track of which children use this - anchor as parent anchor for the respective coordinate. This is necessary to notify the children - prior to destruction of the anchor. - - Note that this function does not change the parent setting in \a pos. -*/ -void QCPItemAnchor::addChildX(QCPItemPosition *pos) -{ - if (!mChildrenX.contains(pos)) - mChildrenX.insert(pos); - else - qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); -} - -/*! \internal - - Removes \a pos from the childX list of this anchor. - - Note that this function does not change the parent setting in \a pos. -*/ -void QCPItemAnchor::removeChildX(QCPItemPosition *pos) -{ - if (!mChildrenX.remove(pos)) - qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); -} - -/*! \internal - - Adds \a pos to the childY list of this anchor, which keeps track of which children use this - anchor as parent anchor for the respective coordinate. This is necessary to notify the children - prior to destruction of the anchor. - - Note that this function does not change the parent setting in \a pos. -*/ -void QCPItemAnchor::addChildY(QCPItemPosition *pos) -{ - if (!mChildrenY.contains(pos)) - mChildrenY.insert(pos); - else - qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); -} - -/*! \internal - - Removes \a pos from the childY list of this anchor. - - Note that this function does not change the parent setting in \a pos. -*/ -void QCPItemAnchor::removeChildY(QCPItemPosition *pos) -{ - if (!mChildrenY.remove(pos)) - qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemPosition -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemPosition - \brief Manages the position of an item. - - Every item has at least one public QCPItemPosition member pointer which provides ways to position the - item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: - \a topLeft and \a bottomRight. - - QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type - defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel - coordinates, as plot coordinates of certain axes, etc. For more advanced plots it is also - possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref - setTypeY). This way an item could be positioned at a fixed pixel distance from the top in the Y - direction, while following a plot coordinate in the X direction. - - A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie - multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords) - are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0) - means directly ontop of the parent anchor. For example, You could attach the \a start position of - a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting point of the line - always be centered under the text label, no matter where the text is moved to. For more advanced - plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see - \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X - direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B - in Y. - - Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent - anchor for other positions. - - To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPosition. This - works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref - setPixelPosition transforms the coordinates appropriately, to make the position appear at the specified - pixel values. -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const - - Returns the current position type. - - If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the - type of the X coordinate. In that case rather use \a typeX() and \a typeY(). - - \see setType -*/ - -/*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const - - Returns the current parent anchor. - - If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), - this method returns the parent anchor of the Y coordinate. In that case rather use \a - parentAnchorX() and \a parentAnchorY(). - - \see setParentAnchor -*/ - -/* end documentation of inline functions */ - -/*! - Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if - you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as - explained in the subclassing section of the QCPAbstractItem documentation. -*/ -QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name) : - QCPItemAnchor(parentPlot, parentItem, name), - mPositionTypeX(ptAbsolute), - mPositionTypeY(ptAbsolute), - mKey(0), - mValue(0), - mParentAnchorX(0), - mParentAnchorY(0) -{ -} - -QCPItemPosition::~QCPItemPosition() -{ - // unregister as parent at children: - // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then - // the setParentAnchor(0) call the correct QCPItemPosition::pixelPosition function instead of QCPItemAnchor::pixelPosition - foreach (QCPItemPosition *child, mChildrenX.toList()) - { - if (child->parentAnchorX() == this) - child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX - } - foreach (QCPItemPosition *child, mChildrenY.toList()) - { - if (child->parentAnchorY() == this) - child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY - } - // unregister as child in parent: - if (mParentAnchorX) - mParentAnchorX->removeChildX(this); - if (mParentAnchorY) - mParentAnchorY->removeChildY(this); -} - -/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ -QCPAxisRect *QCPItemPosition::axisRect() const -{ - return mAxisRect.data(); -} - -/*! - Sets the type of the position. The type defines how the coordinates passed to \ref setCoords - should be handled and how the QCPItemPosition should behave in the plot. - - The possible values for \a type can be separated in two main categories: - - \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords - and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. - By default, the QCustomPlot's x- and yAxis are used. - - \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This - corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref - ptAxisRectRatio. They differ only in the way the absolute position is described, see the - documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify - the axis rect with \ref setAxisRect. By default this is set to the main axis rect. - - Note that the position type \ref ptPlotCoords is only available (and sensible) when the position - has no parent anchor (\ref setParentAnchor). - - If the type is changed, the apparent pixel position on the plot is preserved. This means - the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. - - This method sets the type for both X and Y directions. It is also possible to set different types - for X and Y, see \ref setTypeX, \ref setTypeY. -*/ -void QCPItemPosition::setType(QCPItemPosition::PositionType type) -{ - setTypeX(type); - setTypeY(type); -} - -/*! - This method sets the position type of the X coordinate to \a type. - - For a detailed description of what a position type is, see the documentation of \ref setType. - - \see setType, setTypeY -*/ -void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) -{ - if (mPositionTypeX != type) - { - // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect - // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. - bool retainPixelPosition = true; - if ((mPositionTypeX == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) - retainPixelPosition = false; - if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) - retainPixelPosition = false; - - QPointF pixel; - if (retainPixelPosition) - pixel = pixelPosition(); - - mPositionTypeX = type; - - if (retainPixelPosition) - setPixelPosition(pixel); - } -} - -/*! - This method sets the position type of the Y coordinate to \a type. - - For a detailed description of what a position type is, see the documentation of \ref setType. - - \see setType, setTypeX -*/ -void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) -{ - if (mPositionTypeY != type) - { - // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect - // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. - bool retainPixelPosition = true; - if ((mPositionTypeY == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) - retainPixelPosition = false; - if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) - retainPixelPosition = false; - - QPointF pixel; - if (retainPixelPosition) - pixel = pixelPosition(); - - mPositionTypeY = type; - - if (retainPixelPosition) - setPixelPosition(pixel); - } -} - -/*! - Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now - follow any position changes of the anchor. The local coordinate system of positions with a parent - anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence - the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) - - if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved - during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position - will be exactly on top of the parent anchor. - - To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to 0. - - If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is - set to \ref ptAbsolute, to keep the position in a valid state. - - This method sets the parent anchor for both X and Y directions. It is also possible to set - different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. -*/ -bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) -{ - bool successX = setParentAnchorX(parentAnchor, keepPixelPosition); - bool successY = setParentAnchorY(parentAnchor, keepPixelPosition); - return successX && successY; -} - -/*! - This method sets the parent anchor of the X coordinate to \a parentAnchor. - - For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. - - \see setParentAnchor, setParentAnchorY -*/ -bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) -{ - // make sure self is not assigned as parent: - if (parentAnchor == this) - { - qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); - return false; - } - // make sure no recursive parent-child-relationships are created: - QCPItemAnchor *currentParent = parentAnchor; - while (currentParent) - { - if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) - { - // is a QCPItemPosition, might have further parent, so keep iterating - if (currentParentPos == this) - { - qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); - return false; - } - currentParent = currentParentPos->parentAnchorX(); - } else - { - // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the - // same, to prevent a position being child of an anchor which itself depends on the position, - // because they're both on the same item: - if (currentParent->mParentItem == mParentItem) - { - qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); - return false; - } - break; - } - } - - // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: - if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) - setTypeX(ptAbsolute); - - // save pixel position: - QPointF pixelP; - if (keepPixelPosition) - pixelP = pixelPosition(); - // unregister at current parent anchor: - if (mParentAnchorX) - mParentAnchorX->removeChildX(this); - // register at new parent anchor: - if (parentAnchor) - parentAnchor->addChildX(this); - mParentAnchorX = parentAnchor; - // restore pixel position under new parent: - if (keepPixelPosition) - setPixelPosition(pixelP); - else - setCoords(0, coords().y()); - return true; -} - -/*! - This method sets the parent anchor of the Y coordinate to \a parentAnchor. - - For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. - - \see setParentAnchor, setParentAnchorX -*/ -bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) -{ - // make sure self is not assigned as parent: - if (parentAnchor == this) - { - qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); - return false; - } - // make sure no recursive parent-child-relationships are created: - QCPItemAnchor *currentParent = parentAnchor; - while (currentParent) - { - if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) - { - // is a QCPItemPosition, might have further parent, so keep iterating - if (currentParentPos == this) - { - qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); - return false; - } - currentParent = currentParentPos->parentAnchorY(); - } else - { - // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the - // same, to prevent a position being child of an anchor which itself depends on the position, - // because they're both on the same item: - if (currentParent->mParentItem == mParentItem) - { - qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); - return false; - } - break; - } - } - - // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: - if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) - setTypeY(ptAbsolute); - - // save pixel position: - QPointF pixelP; - if (keepPixelPosition) - pixelP = pixelPosition(); - // unregister at current parent anchor: - if (mParentAnchorY) - mParentAnchorY->removeChildY(this); - // register at new parent anchor: - if (parentAnchor) - parentAnchor->addChildY(this); - mParentAnchorY = parentAnchor; - // restore pixel position under new parent: - if (keepPixelPosition) - setPixelPosition(pixelP); - else - setCoords(coords().x(), 0); - return true; -} - -/*! - Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type - (\ref setType, \ref setTypeX, \ref setTypeY). - - For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position - on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the - QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the - plot coordinate system defined by the axes set by \ref setAxes. By default those are the - QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available - coordinate types and their meaning. - - If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a - value must also be provided in the different coordinate systems. Here, the X type refers to \a - key, and the Y type refers to \a value. - - \see setPixelPosition -*/ -void QCPItemPosition::setCoords(double key, double value) -{ - mKey = key; - mValue = value; -} - -/*! \overload - - Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the - meaning of \a value of the \ref setCoords(double key, double value) method. -*/ -void QCPItemPosition::setCoords(const QPointF &pos) -{ - setCoords(pos.x(), pos.y()); -} - -/*! - Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It - includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). - - \see setPixelPosition -*/ -QPointF QCPItemPosition::pixelPosition() const -{ - QPointF result; - - // determine X: - switch (mPositionTypeX) - { - case ptAbsolute: - { - result.rx() = mKey; - if (mParentAnchorX) - result.rx() += mParentAnchorX->pixelPosition().x(); - break; - } - case ptViewportRatio: - { - result.rx() = mKey*mParentPlot->viewport().width(); - if (mParentAnchorX) - result.rx() += mParentAnchorX->pixelPosition().x(); - else - result.rx() += mParentPlot->viewport().left(); - break; - } - case ptAxisRectRatio: - { - if (mAxisRect) - { - result.rx() = mKey*mAxisRect.data()->width(); - if (mParentAnchorX) - result.rx() += mParentAnchorX->pixelPosition().x(); - else - result.rx() += mAxisRect.data()->left(); - } else - qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; - break; - } - case ptPlotCoords: - { - if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) - result.rx() = mKeyAxis.data()->coordToPixel(mKey); - else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) - result.rx() = mValueAxis.data()->coordToPixel(mValue); - else - qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; - break; - } - } - - // determine Y: - switch (mPositionTypeY) - { - case ptAbsolute: - { - result.ry() = mValue; - if (mParentAnchorY) - result.ry() += mParentAnchorY->pixelPosition().y(); - break; - } - case ptViewportRatio: - { - result.ry() = mValue*mParentPlot->viewport().height(); - if (mParentAnchorY) - result.ry() += mParentAnchorY->pixelPosition().y(); - else - result.ry() += mParentPlot->viewport().top(); - break; - } - case ptAxisRectRatio: - { - if (mAxisRect) - { - result.ry() = mValue*mAxisRect.data()->height(); - if (mParentAnchorY) - result.ry() += mParentAnchorY->pixelPosition().y(); - else - result.ry() += mAxisRect.data()->top(); - } else - qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; - break; - } - case ptPlotCoords: - { - if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) - result.ry() = mKeyAxis.data()->coordToPixel(mKey); - else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) - result.ry() = mValueAxis.data()->coordToPixel(mValue); - else - qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; - break; - } - } - - return result; -} - -/*! - When \ref setType is \ref ptPlotCoords, this function may be used to specify the axes the - coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and - yAxis of the QCustomPlot. -*/ -void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) -{ - mKeyAxis = keyAxis; - mValueAxis = valueAxis; -} - -/*! - When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the - coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of - the QCustomPlot. -*/ -void QCPItemPosition::setAxisRect(QCPAxisRect *axisRect) -{ - mAxisRect = axisRect; -} - -/*! - Sets the apparent pixel position. This works no matter what type (\ref setType) this - QCPItemPosition is or what parent-child situation it is in, as coordinates are transformed - appropriately, to make the position finally appear at the specified pixel values. - - Only if the type is \ref ptAbsolute and no parent anchor is set, this function's effect is - identical to that of \ref setCoords. - - \see pixelPosition, setCoords -*/ -void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) -{ - double x = pixelPosition.x(); - double y = pixelPosition.y(); - - switch (mPositionTypeX) - { - case ptAbsolute: - { - if (mParentAnchorX) - x -= mParentAnchorX->pixelPosition().x(); - break; - } - case ptViewportRatio: - { - if (mParentAnchorX) - x -= mParentAnchorX->pixelPosition().x(); - else - x -= mParentPlot->viewport().left(); - x /= (double)mParentPlot->viewport().width(); - break; - } - case ptAxisRectRatio: - { - if (mAxisRect) - { - if (mParentAnchorX) - x -= mParentAnchorX->pixelPosition().x(); - else - x -= mAxisRect.data()->left(); - x /= (double)mAxisRect.data()->width(); - } else - qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; - break; - } - case ptPlotCoords: - { - if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) - x = mKeyAxis.data()->pixelToCoord(x); - else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) - y = mValueAxis.data()->pixelToCoord(x); - else - qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; - break; - } - } - - switch (mPositionTypeY) - { - case ptAbsolute: - { - if (mParentAnchorY) - y -= mParentAnchorY->pixelPosition().y(); - break; - } - case ptViewportRatio: - { - if (mParentAnchorY) - y -= mParentAnchorY->pixelPosition().y(); - else - y -= mParentPlot->viewport().top(); - y /= (double)mParentPlot->viewport().height(); - break; - } - case ptAxisRectRatio: - { - if (mAxisRect) - { - if (mParentAnchorY) - y -= mParentAnchorY->pixelPosition().y(); - else - y -= mAxisRect.data()->top(); - y /= (double)mAxisRect.data()->height(); - } else - qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; - break; - } - case ptPlotCoords: - { - if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) - x = mKeyAxis.data()->pixelToCoord(y); - else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) - y = mValueAxis.data()->pixelToCoord(y); - else - qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; - break; - } - } - - setCoords(x, y); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractItem -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractItem - \brief The abstract base class for all items in a plot. - - In QCustomPlot, items are supplemental graphical elements that are neither plottables - (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus - plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each - specific item has at least one QCPItemPosition member which controls the positioning. Some items - are defined by more than one coordinate and thus have two or more QCPItemPosition members (For - example, QCPItemRect has \a topLeft and \a bottomRight). - - This abstract base class defines a very basic interface like visibility and clipping. Since this - class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass - yourself to create new items. - - The built-in items are: - - - - - - - - - - -
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
- - \section items-clipping Clipping - - Items are by default clipped to the main axis rect (they are only visible inside the axis rect). - To make an item visible outside that axis rect, disable clipping via \ref setClipToAxisRect - "setClipToAxisRect(false)". - - On the other hand if you want the item to be clipped to a different axis rect, specify it via - \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and - in principle is independent of the coordinate axes the item might be tied to via its position - members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping - also contains the axes used for the item positions. - - \section items-using Using items - - First you instantiate the item you want to use and add it to the plot: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 - by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just - set the plot coordinates where the line should start/end: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-2 - If we don't want the line to be positioned in plot coordinates but a different coordinate system, - e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-3 - Then we can set the coordinates, this time in pixels: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 - and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 - - For more advanced plots, it is even possible to set different types and parent anchors per X/Y - coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref - QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. - - \section items-subclassing Creating own items - - To create an own item, you implement a subclass of QCPAbstractItem. These are the pure - virtual functions, you must implement: - \li \ref selectTest - \li \ref draw - - See the documentation of those functions for what they need to do. - - \subsection items-positioning Allowing the item to be positioned - - As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall - have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add - a public member of type QCPItemPosition like so: - - \code QCPItemPosition * const myPosition;\endcode - - the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition - instance it points to, can be modified, of course). - The initialization of this pointer is made easy with the \ref createPosition function. Just assign - the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition - takes a string which is the name of the position, typically this is identical to the variable name. - For example, the constructor of QCPItemExample could look like this: - - \code - QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - myPosition(createPosition("myPosition")) - { - // other constructor code - } - \endcode - - \subsection items-drawing The draw function - - To give your item a visual representation, reimplement the \ref draw function and use the passed - QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the - position member(s) via \ref QCPItemPosition::pixelPosition. - - To optimize performance you should calculate a bounding rect first (don't forget to take the pen - width into account), check whether it intersects the \ref clipRect, and only draw the item at all - if this is the case. - - \subsection items-selection The selectTest function - - Your implementation of the \ref selectTest function may use the helpers \ref - QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the - selection test becomes significantly simpler for most items. See the documentation of \ref - selectTest for what the function parameters mean and what the function should return. - - \subsection anchors Providing anchors - - Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public - member, e.g. - - \code QCPItemAnchor * const bottom;\endcode - - and create it in the constructor with the \ref createAnchor function, assigning it a name and an - anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). - Since anchors can be placed anywhere, relative to the item's position(s), your item needs to - provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int - anchorId) function. - - In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel - position when anything attached to the anchor needs to know the coordinates. -*/ - -/* start of documentation of inline functions */ - -/*! \fn QList QCPAbstractItem::positions() const - - Returns all positions of the item in a list. - - \see anchors, position -*/ - -/*! \fn QList QCPAbstractItem::anchors() const - - Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always - also an anchor, the list will also contain the positions of this item. - - \see positions, anchor -*/ - -/* end of documentation of inline functions */ -/* start documentation of pure virtual functions */ - -/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 - \internal - - Draws this item with the provided \a painter. - - The cliprect of the provided painter is set to the rect returned by \ref clipRect before this - function is called. The clipRect depends on the clipping settings defined by \ref - setClipToAxisRect and \ref setClipAxisRect. -*/ - -/* end documentation of pure virtual functions */ -/* start documentation of signals */ - -/*! \fn void QCPAbstractItem::selectionChanged(bool selected) - This signal is emitted when the selection state of this item has changed, either by user interaction - or by a direct call to \ref setSelected. -*/ - -/* end documentation of signals */ - -/*! - Base class constructor which initializes base class members. -*/ -QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : - QCPLayerable(parentPlot), - mClipToAxisRect(false), - mSelectable(true), - mSelected(false) -{ - parentPlot->registerItem(this); - - QList rects = parentPlot->axisRects(); - if (rects.size() > 0) - { - setClipToAxisRect(true); - setClipAxisRect(rects.first()); - } -} - -QCPAbstractItem::~QCPAbstractItem() -{ - // don't delete mPositions because every position is also an anchor and thus in mAnchors - qDeleteAll(mAnchors); -} - -/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ -QCPAxisRect *QCPAbstractItem::clipAxisRect() const -{ - return mClipAxisRect.data(); -} - -/*! - Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the - entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. - - \see setClipAxisRect -*/ -void QCPAbstractItem::setClipToAxisRect(bool clip) -{ - mClipToAxisRect = clip; - if (mClipToAxisRect) - setParentLayerable(mClipAxisRect.data()); -} - -/*! - Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref - setClipToAxisRect is set to true. - - \see setClipToAxisRect -*/ -void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) -{ - mClipAxisRect = rect; - if (mClipToAxisRect) - setParentLayerable(mClipAxisRect.data()); -} - -/*! - Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. - (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) - - However, even when \a selectable was set to false, it is possible to set the selection manually, - by calling \ref setSelected. - - \see QCustomPlot::setInteractions, setSelected -*/ -void QCPAbstractItem::setSelectable(bool selectable) -{ - if (mSelectable != selectable) - { - mSelectable = selectable; - emit selectableChanged(mSelectable); - } -} - -/*! - Sets whether this item is selected or not. When selected, it might use a different visual - appearance (e.g. pen and brush), this depends on the specific item though. - - The entire selection mechanism for items is handled automatically when \ref - QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this - function when you wish to change the selection state manually. - - This function can change the selection state even when \ref setSelectable was set to false. - - emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - - \see setSelectable, selectTest -*/ -void QCPAbstractItem::setSelected(bool selected) -{ - if (mSelected != selected) - { - mSelected = selected; - emit selectionChanged(mSelected); - } -} - -/*! - Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by - that name, returns 0. - - This function provides an alternative way to access item positions. Normally, you access - positions direcly by their member pointers (which typically have the same variable name as \a - name). - - \see positions, anchor -*/ -QCPItemPosition *QCPAbstractItem::position(const QString &name) const -{ - for (int i=0; iname() == name) - return mPositions.at(i); - } - qDebug() << Q_FUNC_INFO << "position with name not found:" << name; - return 0; -} - -/*! - Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by - that name, returns 0. - - This function provides an alternative way to access item anchors. Normally, you access - anchors direcly by their member pointers (which typically have the same variable name as \a - name). - - \see anchors, position -*/ -QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const -{ - for (int i=0; iname() == name) - return mAnchors.at(i); - } - qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; - return 0; -} - -/*! - Returns whether this item has an anchor with the specified \a name. - - Note that you can check for positions with this function, too. This is because every position is - also an anchor (QCPItemPosition inherits from QCPItemAnchor). - - \see anchor, position -*/ -bool QCPAbstractItem::hasAnchor(const QString &name) const -{ - for (int i=0; iname() == name) - return true; - } - return false; -} - -/*! \internal - - Returns the rect the visual representation of this item is clipped to. This depends on the - current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. - - If the item is not clipped to an axis rect, QCustomPlot's viewport rect is returned. - - \see draw -*/ -QRect QCPAbstractItem::clipRect() const -{ - if (mClipToAxisRect && mClipAxisRect) - return mClipAxisRect.data()->rect(); - else - return mParentPlot->viewport(); -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing item lines. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \see setAntialiased -*/ -void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); -} - -/*! \internal - - A convenience function which returns the selectTest value for a specified \a rect and a specified - click position \a pos. \a filledRect defines whether a click inside the rect should also be - considered a hit or whether only the rect border is sensitive to hits. - - This function may be used to help with the implementation of the \ref selectTest function for - specific items. - - For example, if your item consists of four rects, call this function four times, once for each - rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four - returned values. -*/ -double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const -{ - double result = -1; - - // distance to border: - QList lines; - lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) - << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); - double minDistSqr = std::numeric_limits::max(); - for (int i=0; i mParentPlot->selectionTolerance()*0.99) - { - if (rect.contains(pos)) - result = mParentPlot->selectionTolerance()*0.99; - } - return result; -} - -/*! \internal - - Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in - item subclasses if they want to provide anchors (QCPItemAnchor). - - For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor - ids and returns the respective pixel points of the specified anchor. - - \see createAnchor -*/ -QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const -{ - qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified - \a name must be a unique string that is usually identical to the variable name of the position - member (This is needed to provide the name-based \ref position access to positions). - - Don't delete positions created by this function manually, as the item will take care of it. - - Use this function in the constructor (initialization list) of the specific item subclass to - create each position member. Don't create QCPItemPositions with \b new yourself, because they - won't be registered with the item properly. - - \see createAnchor -*/ -QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) -{ - if (hasAnchor(name)) - qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; - QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); - mPositions.append(newPosition); - mAnchors.append(newPosition); // every position is also an anchor - newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); - newPosition->setType(QCPItemPosition::ptPlotCoords); - if (mParentPlot->axisRect()) - newPosition->setAxisRect(mParentPlot->axisRect()); - newPosition->setCoords(0, 0); - return newPosition; -} - -/*! \internal - - Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified - \a name must be a unique string that is usually identical to the variable name of the anchor - member (This is needed to provide the name based \ref anchor access to anchors). - - The \a anchorId must be a number identifying the created anchor. It is recommended to create an - enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor - to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns - the correct pixel coordinates for the passed anchor id. - - Don't delete anchors created by this function manually, as the item will take care of it. - - Use this function in the constructor (initialization list) of the specific item subclass to - create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they - won't be registered with the item properly. - - \see createPosition -*/ -QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) -{ - if (hasAnchor(name)) - qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; - QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); - mAnchors.append(newAnchor); - return newAnchor; -} - -/* inherits documentation from base class */ -void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - Q_UNUSED(details) - if (mSelectable) - { - bool selBefore = mSelected; - setSelected(additive ? !mSelected : true); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPAbstractItem::deselectEvent(bool *selectionStateChanged) -{ - if (mSelectable) - { - bool selBefore = mSelected; - setSelected(false); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/* inherits documentation from base class */ -QCP::Interaction QCPAbstractItem::selectionCategory() const -{ - return QCP::iSelectItems; -} -/* end of 'src/item.cpp' */ - - -/* including file 'src/core.cpp', size 125037 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCustomPlot -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCustomPlot - - \brief The central class of the library. This is the QWidget which displays the plot and - interacts with the user. - - For tutorials on how to use QCustomPlot, see the website\n - http://www.qcustomplot.com/ -*/ - -/* start of documentation of inline functions */ - -/*! \fn QCPSelectionRect *QCustomPlot::selectionRect() const - - Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used - to handle and draw selection rect interactions (see \ref setSelectionRectMode). - - \see setSelectionRect -*/ - -/*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const - - Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just - one cell with the main QCPAxisRect inside. -*/ - -/* end of documentation of inline functions */ -/* start of documentation of signals */ - -/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse double click event. -*/ - -/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse press event. - - It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot - connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref - QCPAxisRect::setRangeDragAxes. -*/ - -/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse move event. - - It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot - connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref - QCPAxisRect::setRangeDragAxes. - - \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, - because the dragging starting point was saved the moment the mouse was pressed. Thus it only has - a meaning for the range drag axes that were set at that moment. If you want to change the drag - axes, consider doing this in the \ref mousePress signal instead. -*/ - -/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse release event. - - It is emitted before QCustomPlot handles any other mechanisms like object selection. So a - slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or - \ref QCPAbstractPlottable::setSelectable. -*/ - -/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) - - This signal is emitted when the QCustomPlot receives a mouse wheel event. - - It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot - connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref - QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. -*/ - -/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) - - This signal is emitted when a plottable is clicked. - - \a event is the mouse event that caused the click and \a plottable is the plottable that received - the click. The parameter \a dataIndex indicates the data point that was closest to the click - position. - - \see plottableDoubleClick -*/ - -/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) - - This signal is emitted when a plottable is double clicked. - - \a event is the mouse event that caused the click and \a plottable is the plottable that received - the click. The parameter \a dataIndex indicates the data point that was closest to the click - position. - - \see plottableClick -*/ - -/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) - - This signal is emitted when an item is clicked. - - \a event is the mouse event that caused the click and \a item is the item that received the - click. - - \see itemDoubleClick -*/ - -/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) - - This signal is emitted when an item is double clicked. - - \a event is the mouse event that caused the click and \a item is the item that received the - click. - - \see itemClick -*/ - -/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) - - This signal is emitted when an axis is clicked. - - \a event is the mouse event that caused the click, \a axis is the axis that received the click and - \a part indicates the part of the axis that was clicked. - - \see axisDoubleClick -*/ - -/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) - - This signal is emitted when an axis is double clicked. - - \a event is the mouse event that caused the click, \a axis is the axis that received the click and - \a part indicates the part of the axis that was clicked. - - \see axisClick -*/ - -/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) - - This signal is emitted when a legend (item) is clicked. - - \a event is the mouse event that caused the click, \a legend is the legend that received the - click and \a item is the legend item that received the click. If only the legend and no item is - clicked, \a item is 0. This happens for a click inside the legend padding or the space between - two items. - - \see legendDoubleClick -*/ - -/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) - - This signal is emitted when a legend (item) is double clicked. - - \a event is the mouse event that caused the click, \a legend is the legend that received the - click and \a item is the legend item that received the click. If only the legend and no item is - clicked, \a item is 0. This happens for a click inside the legend padding or the space between - two items. - - \see legendClick -*/ - -/*! \fn void QCustomPlot::selectionChangedByUser() - - This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by - clicking. It is not emitted when the selection state of an object has changed programmatically by - a direct call to setSelected()/setSelection() on an object or by calling \ref - deselectAll. - - In addition to this signal, selectable objects also provide individual signals, for example \ref - QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals - are emitted even if the selection state is changed programmatically. - - See the documentation of \ref setInteractions for details about the selection mechanism. - - \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends -*/ - -/*! \fn void QCustomPlot::beforeReplot() - - This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref - replot). - - It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them - replot synchronously, it won't cause an infinite recursion. - - \see replot, afterReplot -*/ - -/*! \fn void QCustomPlot::afterReplot() - - This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref - replot). - - It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them - replot synchronously, it won't cause an infinite recursion. - - \see replot, beforeReplot -*/ - -/* end of documentation of signals */ -/* start of documentation of public members */ - -/*! \var QCPAxis *QCustomPlot::xAxis - - A pointer to the primary x Axis (bottom) of the main axis rect of the plot. - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref - QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the - default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointers become 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/*! \var QCPAxis *QCustomPlot::yAxis - - A pointer to the primary y Axis (left) of the main axis rect of the plot. - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref - QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the - default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointers become 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/*! \var QCPAxis *QCustomPlot::xAxis2 - - A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are - invisible by default. Use QCPAxis::setVisible to change this (or use \ref - QCPAxisRect::setupFullAxesBox). - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref - QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the - default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointers become 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/*! \var QCPAxis *QCustomPlot::yAxis2 - - A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are - invisible by default. Use QCPAxis::setVisible to change this (or use \ref - QCPAxisRect::setupFullAxesBox). - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref - QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the - default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointers become 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/*! \var QCPLegend *QCustomPlot::legend - - A pointer to the default legend of the main axis rect. The legend is invisible by default. Use - QCPLegend::setVisible to change this. - - QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref - yAxis2) and the \ref legend. They make it very easy working with plots that only have a single - axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the - layout system\endlink to add multiple legends to the plot, use the layout system interface to - access the new legend. For example, legends can be placed inside an axis rect's \ref - QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If - the default legend is removed due to manipulation of the layout system (e.g. by removing the main - axis rect), the corresponding pointer becomes 0. - - If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is - added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the - according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is - added after the main legend was removed before. -*/ - -/* end of documentation of public members */ - -/*! - Constructs a QCustomPlot and sets reasonable default values. -*/ -QCustomPlot::QCustomPlot(QWidget *parent) : - QWidget(parent), - xAxis(0), - yAxis(0), - xAxis2(0), - yAxis2(0), - legend(0), - mBufferDevicePixelRatio(1.0), // will be adapted to primary screen below - mPlotLayout(0), - mAutoAddPlottableToLegend(true), - mAntialiasedElements(QCP::aeNone), - mNotAntialiasedElements(QCP::aeNone), - mInteractions(0), - mSelectionTolerance(8), - mNoAntialiasingOnDrag(false), - mBackgroundBrush(Qt::white, Qt::SolidPattern), - mBackgroundScaled(true), - mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), - mCurrentLayer(0), - mPlottingHints(QCP::phCacheLabels|QCP::phImmediateRefresh), - mMultiSelectModifier(Qt::ControlModifier), - mSelectionRectMode(QCP::srmNone), - mSelectionRect(0), - mOpenGl(false), - mSymbolPressed(false), - mMouseHasMoved(false), - mMouseEventLayerable(0), - mMouseSignalLayerable(0), - mReplotting(false), - mReplotQueued(false), - mOpenGlMultisamples(16), - mOpenGlAntialiasedElementsBackup(QCP::aeNone), - mOpenGlCacheLabelsBackup(true) -{ - setAttribute(Qt::WA_NoMousePropagation); - setAttribute(Qt::WA_OpaquePaintEvent); - setFocusPolicy(Qt::ClickFocus); - setMouseTracking(true); - QLocale currentLocale = locale(); - currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); - setLocale(currentLocale); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED -# ifdef QCP_DEVICEPIXELRATIO_FLOAT - setBufferDevicePixelRatio(QWidget::devicePixelRatioF()); -# else - setBufferDevicePixelRatio(QWidget::devicePixelRatio()); -# endif -#endif - - mOpenGlAntialiasedElementsBackup = mAntialiasedElements; - mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); - // create initial layers: - mLayers.append(new QCPLayer(this, QLatin1String("background"))); - mLayers.append(new QCPLayer(this, QLatin1String("grid"))); - mLayers.append(new QCPLayer(this, QLatin1String("main"))); - mLayers.append(new QCPLayer(this, QLatin1String("axes"))); - mLayers.append(new QCPLayer(this, QLatin1String("legend"))); - mLayers.append(new QCPLayer(this, QLatin1String("overlay"))); - updateLayerIndices(); - setCurrentLayer(QLatin1String("main")); - layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered); - - // create initial layout, axis rect and legend: - mPlotLayout = new QCPLayoutGrid; - mPlotLayout->initializeParentPlot(this); - mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry - mPlotLayout->setLayer(QLatin1String("main")); - QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true); - mPlotLayout->addElement(0, 0, defaultAxisRect); - xAxis = defaultAxisRect->axis(QCPAxis::atBottom); - yAxis = defaultAxisRect->axis(QCPAxis::atLeft); - xAxis2 = defaultAxisRect->axis(QCPAxis::atTop); - yAxis2 = defaultAxisRect->axis(QCPAxis::atRight); - legend = new QCPLegend; - legend->setVisible(false); - defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); - defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); - - defaultAxisRect->setLayer(QLatin1String("background")); - xAxis->setLayer(QLatin1String("axes")); - yAxis->setLayer(QLatin1String("axes")); - xAxis2->setLayer(QLatin1String("axes")); - yAxis2->setLayer(QLatin1String("axes")); - xAxis->grid()->setLayer(QLatin1String("grid")); - yAxis->grid()->setLayer(QLatin1String("grid")); - xAxis2->grid()->setLayer(QLatin1String("grid")); - yAxis2->grid()->setLayer(QLatin1String("grid")); - legend->setLayer(QLatin1String("legend")); - - // create selection rect instance: - mSelectionRect = new QCPSelectionRect(this); - mSelectionRect->setLayer(QLatin1String("overlay")); - - setViewport(rect()); // needs to be called after mPlotLayout has been created - - replot(rpQueuedReplot); -} - -QCustomPlot::~QCustomPlot() -{ - clearPlottables(); - clearItems(true); - - if (mPlotLayout) - { - delete mPlotLayout; - mPlotLayout = 0; - } - - mCurrentLayer = 0; - qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed - mLayers.clear(); -} - -void QCustomPlot::setSymbolPos(const QPoint pos) -{ - mSymbolPos = QPoint(pos.x(), 0); -} - -/*! - Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. - - This overrides the antialiasing settings for whole element groups, normally controlled with the - \a setAntialiasing function on the individual elements. If an element is neither specified in - \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on - each individual element instance is used. - - For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be - drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set - to. - - if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is - removed from there. - - \see setNotAntialiasedElements -*/ -void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) -{ - mAntialiasedElements = antialiasedElements; - - // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: - if ((mNotAntialiasedElements & mAntialiasedElements) != 0) - mNotAntialiasedElements |= ~mAntialiasedElements; -} - -/*! - Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. - - See \ref setAntialiasedElements for details. - - \see setNotAntialiasedElement -*/ -void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) -{ - if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) - mAntialiasedElements &= ~antialiasedElement; - else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) - mAntialiasedElements |= antialiasedElement; - - // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: - if ((mNotAntialiasedElements & mAntialiasedElements) != 0) - mNotAntialiasedElements |= ~mAntialiasedElements; -} - -/*! - Sets which elements are forcibly drawn not antialiased as an \a or combination of - QCP::AntialiasedElement. - - This overrides the antialiasing settings for whole element groups, normally controlled with the - \a setAntialiasing function on the individual elements. If an element is neither specified in - \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on - each individual element instance is used. - - For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be - drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set - to. - - if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is - removed from there. - - \see setAntialiasedElements -*/ -void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) -{ - mNotAntialiasedElements = notAntialiasedElements; - - // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: - if ((mNotAntialiasedElements & mAntialiasedElements) != 0) - mAntialiasedElements |= ~mNotAntialiasedElements; -} - -/*! - Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. - - See \ref setNotAntialiasedElements for details. - - \see setAntialiasedElement -*/ -void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) -{ - if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) - mNotAntialiasedElements &= ~notAntialiasedElement; - else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) - mNotAntialiasedElements |= notAntialiasedElement; - - // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: - if ((mNotAntialiasedElements & mAntialiasedElements) != 0) - mAntialiasedElements |= ~mNotAntialiasedElements; -} - -/*! - If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the - plottable to the legend (QCustomPlot::legend). - - \see addGraph, QCPLegend::addItem -*/ -void QCustomPlot::setAutoAddPlottableToLegend(bool on) -{ - mAutoAddPlottableToLegend = on; -} - -/*! - Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction - enums. There are the following types of interactions: - - Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the - respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. - For details how to control which axes the user may drag/zoom and in what orientations, see \ref - QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, - \ref QCPAxisRect::setRangeZoomAxes. - - Plottable data selection is controlled by \ref QCP::iSelectPlottables. If \ref - QCP::iSelectPlottables is set, the user may select plottables (graphs, curves, bars,...) and - their data by clicking on them or in their vicinity (\ref setSelectionTolerance). Whether the - user can actually select a plottable and its data can further be restricted with the \ref - QCPAbstractPlottable::setSelectable method on the specific plottable. For details, see the - special page about the \ref dataselection "data selection mechanism". To retrieve a list of all - currently selected plottables, call \ref selectedPlottables. If you're only interested in - QCPGraphs, you may use the convenience function \ref selectedGraphs. - - Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user - may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find - out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of - all currently selected items, call \ref selectedItems. - - Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user - may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick - labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for - each axis. To retrieve a list of all axes that currently contain selected parts, call \ref - selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). - - Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may - select the legend itself or individual items by clicking on them. What parts exactly are - selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the - legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To - find out which child items are selected, call \ref QCPLegend::selectedItems. - - All other selectable elements The selection of all other selectable objects (e.g. - QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the - user may select those objects by clicking on them. To find out which are currently selected, you - need to check their selected state explicitly. - - If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is - emitted. Each selectable object additionally emits an individual selectionChanged signal whenever - their selection state has changed, i.e. not only by user interaction. - - To allow multiple objects to be selected by holding the selection modifier (\ref - setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. - - \note In addition to the selection mechanism presented here, QCustomPlot always emits - corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and - \ref plottableDoubleClick for example. - - \see setInteraction, setSelectionTolerance -*/ -void QCustomPlot::setInteractions(const QCP::Interactions &interactions) -{ - mInteractions = interactions; -} - -/*! - Sets the single \a interaction of this QCustomPlot to \a enabled. - - For details about the interaction system, see \ref setInteractions. - - \see setInteractions -*/ -void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) -{ - if (!enabled && mInteractions.testFlag(interaction)) - mInteractions &= ~interaction; - else if (enabled && !mInteractions.testFlag(interaction)) - mInteractions |= interaction; -} - -/*! - Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or - not. - - If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a - potential selection when the minimum distance between the click position and the graph line is - smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks - directly inside the area and ignore this selection tolerance. In other words, it only has meaning - for parts of objects that are too thin to exactly hit with a click and thus need such a - tolerance. - - \see setInteractions, QCPLayerable::selectTest -*/ -void QCustomPlot::setSelectionTolerance(int pixels) -{ - mSelectionTolerance = pixels; -} - -/*! - Sets whether antialiasing is disabled for this QCustomPlot while the user is dragging axes - ranges. If many objects, especially plottables, are drawn antialiased, this greatly improves - performance during dragging. Thus it creates a more responsive user experience. As soon as the - user stops dragging, the last replot is done with normal antialiasing, to restore high image - quality. - - \see setAntialiasedElements, setNotAntialiasedElements -*/ -void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) -{ - mNoAntialiasingOnDrag = enabled; -} - -/*! - Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. - - \see setPlottingHint -*/ -void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) -{ - mPlottingHints = hints; -} - -/*! - Sets the specified plotting \a hint to \a enabled. - - \see setPlottingHints -*/ -void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) -{ - QCP::PlottingHints newHints = mPlottingHints; - if (!enabled) - newHints &= ~hint; - else - newHints |= hint; - - if (newHints != mPlottingHints) - setPlottingHints(newHints); -} - -/*! - Sets the keyboard modifier that will be recognized as multi-select-modifier. - - If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple - objects (or data points) by clicking on them one after the other while holding down \a modifier. - - By default the multi-select-modifier is set to Qt::ControlModifier. - - \see setInteractions -*/ -void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) -{ - mMultiSelectModifier = modifier; -} - -/*! - Sets how QCustomPlot processes mouse click-and-drag interactions by the user. - - If \a mode is \ref QCP::srmNone, the mouse drag is forwarded to the underlying objects. For - example, QCPAxisRect may process a mouse drag by dragging axis ranges, see \ref - QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref - selectionRect) becomes activated and allows e.g. rect zooming and data point selection. - - If you wish to provide your user both with axis range dragging and data selection/range zooming, - use this method to switch between the modes just before the interaction is processed, e.g. in - reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether - the user is holding a certain keyboard modifier, and then decide which \a mode shall be set. - - If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the - interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes - will keep the selection rect active. Upon completion of the interaction, the behaviour is as - defined by the currently set \a mode, not the mode that was set when the interaction started. - - \see setInteractions, setSelectionRect, QCPSelectionRect -*/ -void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) -{ - if (mSelectionRect) - { - if (mode == QCP::srmNone) - mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect - - // disconnect old connections: - if (mSelectionRectMode == QCP::srmSelect) - disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); - else if (mSelectionRectMode == QCP::srmZoom) - disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); - - // establish new ones: - if (mode == QCP::srmSelect) - connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); - else if (mode == QCP::srmZoom) - connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); - } - - mSelectionRectMode = mode; -} - -/*! - Sets the \ref QCPSelectionRect instance that QCustomPlot will use if \a mode is not \ref - QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of - the passed \a selectionRect. It can be accessed later via \ref selectionRect. - - This method is useful if you wish to replace the default QCPSelectionRect instance with an - instance of a QCPSelectionRect subclass, to introduce custom behaviour of the selection rect. - - \see setSelectionRectMode -*/ -void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) -{ - if (mSelectionRect) - delete mSelectionRect; - - mSelectionRect = selectionRect; - - if (mSelectionRect) - { - // establish connections with new selection rect: - if (mSelectionRectMode == QCP::srmSelect) - connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); - else if (mSelectionRectMode == QCP::srmZoom) - connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); - } -} - -/*! - \warning This is still an experimental feature and its performance depends on the system that it - runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering - might cause context conflicts on some systems. - - This method allows to enable OpenGL plot rendering, for increased plotting performance of - graphically demanding plots (thick lines, translucent fills, etc.). - - If \a enabled is set to true, QCustomPlot will try to initialize OpenGL and, if successful, - continue plotting with hardware acceleration. The parameter \a multisampling controls how many - samples will be used per pixel, it essentially controls the antialiasing quality. If \a - multisampling is set too high for the current graphics hardware, the maximum allowed value will - be used. - - You can test whether switching to OpenGL rendering was successful by checking whether the - according getter \a QCustomPlot::openGl() returns true. If the OpenGL initialization fails, - rendering continues with the regular software rasterizer, and an according qDebug output is - generated. - - If switching to OpenGL was successful, this method disables label caching (\ref setPlottingHint - "setPlottingHint(QCP::phCacheLabels, false)") and turns on QCustomPlot's antialiasing override - for all elements (\ref setAntialiasedElements "setAntialiasedElements(QCP::aeAll)"), leading to a - higher quality output. The antialiasing override allows for pixel-grid aligned drawing in the - OpenGL paint device. As stated before, in OpenGL rendering the actual antialiasing of the plot is - controlled with \a multisampling. If \a enabled is set to false, the antialiasing/label caching - settings are restored to what they were before OpenGL was enabled, if they weren't altered in the - meantime. - - \note OpenGL support is only enabled if QCustomPlot is compiled with the macro \c QCUSTOMPLOT_USE_OPENGL - defined. This define must be set before including the QCustomPlot header both during compilation - of the QCustomPlot library as well as when compiling your application. It is best to just include - the line DEFINES += QCUSTOMPLOT_USE_OPENGL in the respective qmake project files. - \note If you are using a Qt version before 5.0, you must also add the module "opengl" to your \c - QT variable in the qmake project files. For Qt versions 5.0 and higher, QCustomPlot switches to a - newer OpenGL interface which is already in the "gui" module. -*/ -void QCustomPlot::setOpenGl(bool enabled, int multisampling) -{ - mOpenGlMultisamples = qMax(0, multisampling); -#ifdef QCUSTOMPLOT_USE_OPENGL - mOpenGl = enabled; - if (mOpenGl) - { - if (setupOpenGl()) - { - // backup antialiasing override and labelcaching setting so we can restore upon disabling OpenGL - mOpenGlAntialiasedElementsBackup = mAntialiasedElements; - mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); - // set antialiasing override to antialias all (aligns gl pixel grid properly), and disable label caching (would use software rasterizer for pixmap caches): - setAntialiasedElements(QCP::aeAll); - setPlottingHint(QCP::phCacheLabels, false); - } else - { - qDebug() << Q_FUNC_INFO << "Failed to enable OpenGL, continuing plotting without hardware acceleration."; - mOpenGl = false; - } - } else - { - // restore antialiasing override and labelcaching to what it was before enabling OpenGL, if nobody changed it in the meantime: - if (mAntialiasedElements == QCP::aeAll) - setAntialiasedElements(mOpenGlAntialiasedElementsBackup); - if (!mPlottingHints.testFlag(QCP::phCacheLabels)) - setPlottingHint(QCP::phCacheLabels, mOpenGlCacheLabelsBackup); - freeOpenGl(); - } - // recreate all paint buffers: - mPaintBuffers.clear(); - setupPaintBuffers(); -#else - Q_UNUSED(enabled) - qDebug() << Q_FUNC_INFO << "QCustomPlot can't use OpenGL because QCUSTOMPLOT_USE_OPENGL was not defined during compilation (add 'DEFINES += QCUSTOMPLOT_USE_OPENGL' to your qmake .pro file)"; -#endif -} - -/*! - Sets the viewport of this QCustomPlot. Usually users of QCustomPlot don't need to change the - viewport manually. - - The viewport is the area in which the plot is drawn. All mechanisms, e.g. margin caluclation take - the viewport to be the outer border of the plot. The viewport normally is the rect() of the - QCustomPlot widget, i.e. a rect with top left (0, 0) and size of the QCustomPlot widget. - - Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically - an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger - and contains also the axes themselves, their tick numbers, their labels, or even additional axis - rects, color scales and other layout elements. - - This function is used to allow arbitrary size exports with \ref toPixmap, \ref savePng, \ref - savePdf, etc. by temporarily changing the viewport size. -*/ -void QCustomPlot::setViewport(const QRect &rect) -{ - mViewport = rect; - if (mPlotLayout) - mPlotLayout->setOuterRect(mViewport); -} - -/*! - Sets the device pixel ratio used by the paint buffers of this QCustomPlot instance. - - Normally, this doesn't need to be set manually, because it is initialized with the regular \a - QWidget::devicePixelRatio which is configured by Qt to fit the display device (e.g. 1 for normal - displays, 2 for High-DPI displays). - - Device pixel ratios are supported by Qt only for Qt versions since 5.4. If this method is called - when QCustomPlot is being used with older Qt versions, outputs an according qDebug message and - leaves the internal buffer device pixel ratio at 1.0. -*/ -void QCustomPlot::setBufferDevicePixelRatio(double ratio) -{ - if (!qFuzzyCompare(ratio, mBufferDevicePixelRatio)) - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mBufferDevicePixelRatio = ratio; - for (int i=0; isetDevicePixelRatio(mBufferDevicePixelRatio); - // Note: axis label cache has devicePixelRatio as part of cache hash, so no need to manually clear cache here -#else - qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; - mBufferDevicePixelRatio = 1.0; -#endif - } -} - -/*! - Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn - below all other objects in the plot. - - For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be - enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is - preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, - consider using the overloaded version of this function. - - If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will - first be filled with that brush, before drawing the background pixmap. This can be useful for - background pixmaps with translucent areas. - - \see setBackgroundScaled, setBackgroundScaledMode -*/ -void QCustomPlot::setBackground(const QPixmap &pm) -{ - mBackgroundPixmap = pm; - mScaledBackgroundPixmap = QPixmap(); -} - -/*! - Sets the background brush of the viewport (see \ref setViewport). - - Before drawing everything else, the background is filled with \a brush. If a background pixmap - was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport - before the background pixmap is drawn. This can be useful for background pixmaps with translucent - areas. - - Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be - useful for exporting to image formats which support transparency, e.g. \ref savePng. - - \see setBackgroundScaled, setBackgroundScaledMode -*/ -void QCustomPlot::setBackground(const QBrush &brush) -{ - mBackgroundBrush = brush; -} - -/*! \overload - - Allows setting the background pixmap of the viewport, whether it shall be scaled and how it - shall be scaled in one call. - - \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode -*/ -void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) -{ - mBackgroundPixmap = pm; - mScaledBackgroundPixmap = QPixmap(); - mBackgroundScaled = scaled; - mBackgroundScaledMode = mode; -} - -/*! - Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is - set to true, control whether and how the aspect ratio of the original pixmap is preserved with - \ref setBackgroundScaledMode. - - Note that the scaled version of the original pixmap is buffered, so there is no performance - penalty on replots. (Except when the viewport dimensions are changed continuously.) - - \see setBackground, setBackgroundScaledMode -*/ -void QCustomPlot::setBackgroundScaled(bool scaled) -{ - mBackgroundScaled = scaled; -} - -/*! - If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this - function to define whether and how the aspect ratio of the original pixmap is preserved. - - \see setBackground, setBackgroundScaled -*/ -void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) -{ - mBackgroundScaledMode = mode; -} - -/*! - Returns the plottable with \a index. If the index is invalid, returns 0. - - There is an overloaded version of this function with no parameter which returns the last added - plottable, see QCustomPlot::plottable() - - \see plottableCount -*/ -QCPAbstractPlottable *QCustomPlot::plottable(int index) -{ - if (index >= 0 && index < mPlottables.size()) - { - return mPlottables.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! \overload - - Returns the last plottable that was added to the plot. If there are no plottables in the plot, - returns 0. - - \see plottableCount -*/ -QCPAbstractPlottable *QCustomPlot::plottable() -{ - if (!mPlottables.isEmpty()) - { - return mPlottables.last(); - } else - return 0; -} - -/*! - Removes the specified plottable from the plot and deletes it. If necessary, the corresponding - legend item is also removed from the default legend (QCustomPlot::legend). - - Returns true on success. - - \see clearPlottables -*/ -bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) -{ - if (!mPlottables.contains(plottable)) - { - qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); - return false; - } - - // remove plottable from legend: - plottable->removeFromLegend(); - // special handling for QCPGraphs to maintain the simple graph interface: - if (QCPGraph *graph = qobject_cast(plottable)) - mGraphs.removeOne(graph); - // remove plottable: - delete plottable; - mPlottables.removeOne(plottable); - return true; -} - -/*! \overload - - Removes and deletes the plottable by its \a index. -*/ -bool QCustomPlot::removePlottable(int index) -{ - if (index >= 0 && index < mPlottables.size()) - return removePlottable(mPlottables[index]); - else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return false; - } -} - -/*! - Removes all plottables from the plot and deletes them. Corresponding legend items are also - removed from the default legend (QCustomPlot::legend). - - Returns the number of plottables removed. - - \see removePlottable -*/ -int QCustomPlot::clearPlottables() -{ - int c = mPlottables.size(); - for (int i=c-1; i >= 0; --i) - removePlottable(mPlottables[i]); - return c; -} - -/*! - Returns the number of currently existing plottables in the plot - - \see plottable -*/ -int QCustomPlot::plottableCount() const -{ - return mPlottables.size(); -} - -/*! - Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. - - There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. - - \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection -*/ -QList QCustomPlot::selectedPlottables() const -{ - QList result; - foreach (QCPAbstractPlottable *plottable, mPlottables) - { - if (plottable->selected()) - result.append(plottable); - } - return result; -} - -/*! - Returns the plottable at the pixel position \a pos. Plottables that only consist of single lines - (like graphs) have a tolerance band around them, see \ref setSelectionTolerance. If multiple - plottables come into consideration, the one closest to \a pos is returned. - - If \a onlySelectable is true, only plottables that are selectable - (QCPAbstractPlottable::setSelectable) are considered. - - If there is no plottable at \a pos, the return value is 0. - - \see itemAt, layoutElementAt -*/ -QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable) const -{ - QCPAbstractPlottable *resultPlottable = 0; - double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value - - foreach (QCPAbstractPlottable *plottable, mPlottables) - { - if (onlySelectable && !plottable->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPabstractPlottable::selectable - continue; - if ((plottable->keyAxis()->axisRect()->rect() & plottable->valueAxis()->axisRect()->rect()).contains(pos.toPoint())) // only consider clicks inside the rect that is spanned by the plottable's key/value axes - { - double currentDistance = plottable->selectTest(pos, false); - if (currentDistance >= 0 && currentDistance < resultDistance) - { - resultPlottable = plottable; - resultDistance = currentDistance; - } - } - } - - return resultPlottable; -} - -/*! - Returns whether this QCustomPlot instance contains the \a plottable. -*/ -bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const -{ - return mPlottables.contains(plottable); -} - -/*! - Returns the graph with \a index. If the index is invalid, returns 0. - - There is an overloaded version of this function with no parameter which returns the last created - graph, see QCustomPlot::graph() - - \see graphCount, addGraph -*/ -QCPGraph *QCustomPlot::graph(int index) const -{ - if (index >= 0 && index < mGraphs.size()) - { - return mGraphs.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! \overload - - Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, - returns 0. - - \see graphCount, addGraph -*/ -QCPGraph *QCustomPlot::graph() const -{ - if (!mGraphs.isEmpty()) - { - return mGraphs.last(); - } else - return 0; -} - -/*! - Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the - bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a - keyAxis and \a valueAxis must reside in this QCustomPlot. - - \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically - "y") for the graph. - - Returns a pointer to the newly created graph, or 0 if adding the graph failed. - - \see graph, graphCount, removeGraph, clearGraphs -*/ -QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) -{ - if (!keyAxis) keyAxis = xAxis; - if (!valueAxis) valueAxis = yAxis; - if (!keyAxis || !valueAxis) - { - qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)"; - return 0; - } - if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) - { - qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; - return 0; - } - - QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); - newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); - return newGraph; -} - -/*! - Removes the specified \a graph from the plot and deletes it. If necessary, the corresponding - legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in - the plot have a channel fill set towards the removed graph, the channel fill property of those - graphs is reset to zero (no channel fill). - - Returns true on success. - - \see clearGraphs -*/ -bool QCustomPlot::removeGraph(QCPGraph *graph) -{ - return removePlottable(graph); -} - -/*! \overload - - Removes and deletes the graph by its \a index. -*/ -bool QCustomPlot::removeGraph(int index) -{ - if (index >= 0 && index < mGraphs.size()) - return removeGraph(mGraphs[index]); - else - return false; -} - -/*! - Removes all graphs from the plot and deletes them. Corresponding legend items are also removed - from the default legend (QCustomPlot::legend). - - Returns the number of graphs removed. - - \see removeGraph -*/ -int QCustomPlot::clearGraphs() -{ - int c = mGraphs.size(); - for (int i=c-1; i >= 0; --i) - removeGraph(mGraphs[i]); - return c; -} - -/*! - Returns the number of currently existing graphs in the plot - - \see graph, addGraph -*/ -int QCustomPlot::graphCount() const -{ - return mGraphs.size(); -} - -/*! - Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. - - If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, - etc., use \ref selectedPlottables. - - \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection -*/ -QList QCustomPlot::selectedGraphs() const -{ - QList result; - foreach (QCPGraph *graph, mGraphs) - { - if (graph->selected()) - result.append(graph); - } - return result; -} - -/*! - Returns the item with \a index. If the index is invalid, returns 0. - - There is an overloaded version of this function with no parameter which returns the last added - item, see QCustomPlot::item() - - \see itemCount -*/ -QCPAbstractItem *QCustomPlot::item(int index) const -{ - if (index >= 0 && index < mItems.size()) - { - return mItems.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! \overload - - Returns the last item that was added to this plot. If there are no items in the plot, - returns 0. - - \see itemCount -*/ -QCPAbstractItem *QCustomPlot::item() const -{ - if (!mItems.isEmpty()) - { - return mItems.last(); - } else - return 0; -} - -/*! - Removes the specified item from the plot and deletes it. - - Returns true on success. - - \see clearItems -*/ -bool QCustomPlot::removeItem(QCPAbstractItem *item) -{ - if (mItems.contains(item)) - { - delete item; - mItems.removeOne(item); - return true; - } else - { - qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); - return false; - } -} - -/*! \overload - - Removes and deletes the item by its \a index. -*/ -bool QCustomPlot::removeItem(int index) -{ - if (index >= 0 && index < mItems.size()) - return removeItem(mItems[index]); - else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return false; - } -} - -/*! - Removes all items from the plot and deletes them. - - Returns the number of items removed. - - \see removeItem -*/ -int QCustomPlot::clearItems(bool clearTitle) -{ - int c = mItems.size(); - for (int i=c-1; i >= 0; --i) - { - if(mItems[i]->objectName() == "m_trendTitle") - { - if(!clearTitle) - { - continue; - } - } - removeItem(mItems[i]); - } - return c; -} - -/*! - Returns the number of currently existing items in the plot - - \see item -*/ -int QCustomPlot::itemCount() const -{ - return mItems.size(); -} - -/*! - Returns a list of the selected items. If no items are currently selected, the list is empty. - - \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected -*/ -QList QCustomPlot::selectedItems() const -{ - QList result; - foreach (QCPAbstractItem *item, mItems) - { - if (item->selected()) - result.append(item); - } - return result; -} - -/*! - Returns the item at the pixel position \a pos. Items that only consist of single lines (e.g. \ref - QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref - setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is - returned. - - If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are - considered. - - If there is no item at \a pos, the return value is 0. - - \see plottableAt, layoutElementAt -*/ -QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const -{ - QCPAbstractItem *resultItem = 0; - double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value - - foreach (QCPAbstractItem *item, mItems) - { - if (onlySelectable && !item->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable - continue; - if (!item->clipToAxisRect() || item->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it - { - double currentDistance = item->selectTest(pos, false); - if (currentDistance >= 0 && currentDistance < resultDistance) - { - resultItem = item; - resultDistance = currentDistance; - } - } - } - - return resultItem; -} - -/*! - Returns whether this QCustomPlot contains the \a item. - - \see item -*/ -bool QCustomPlot::hasItem(QCPAbstractItem *item) const -{ - return mItems.contains(item); -} - -/*! - Returns the layer with the specified \a name. If there is no layer with the specified name, 0 is - returned. - - Layer names are case-sensitive. - - \see addLayer, moveLayer, removeLayer -*/ -QCPLayer *QCustomPlot::layer(const QString &name) const -{ - foreach (QCPLayer *layer, mLayers) - { - if (layer->name() == name) - return layer; - } - return 0; -} - -/*! \overload - - Returns the layer by \a index. If the index is invalid, 0 is returned. - - \see addLayer, moveLayer, removeLayer -*/ -QCPLayer *QCustomPlot::layer(int index) const -{ - if (index >= 0 && index < mLayers.size()) - { - return mLayers.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! - Returns the layer that is set as current layer (see \ref setCurrentLayer). -*/ -QCPLayer *QCustomPlot::currentLayer() const -{ - return mCurrentLayer; -} - -/*! - Sets the layer with the specified \a name to be the current layer. All layerables (\ref - QCPLayerable), e.g. plottables and items, are created on the current layer. - - Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. - - Layer names are case-sensitive. - - \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer -*/ -bool QCustomPlot::setCurrentLayer(const QString &name) -{ - if (QCPLayer *newCurrentLayer = layer(name)) - { - return setCurrentLayer(newCurrentLayer); - } else - { - qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; - return false; - } -} - -/*! \overload - - Sets the provided \a layer to be the current layer. - - Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. - - \see addLayer, moveLayer, removeLayer -*/ -bool QCustomPlot::setCurrentLayer(QCPLayer *layer) -{ - if (!mLayers.contains(layer)) - { - qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); - return false; - } - - mCurrentLayer = layer; - return true; -} - -/*! - Returns the number of currently existing layers in the plot - - \see layer, addLayer -*/ -int QCustomPlot::layerCount() const -{ - return mLayers.size(); -} - -/*! - Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which - must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. - - Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a - valid layer inside this QCustomPlot. - - If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. - - For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. - - \see layer, moveLayer, removeLayer -*/ -bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) -{ - if (!otherLayer) - otherLayer = mLayers.last(); - if (!mLayers.contains(otherLayer)) - { - qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); - return false; - } - if (layer(name)) - { - qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; - return false; - } - - QCPLayer *newLayer = new QCPLayer(this, name); - mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); - updateLayerIndices(); - setupPaintBuffers(); // associates new layer with the appropriate paint buffer - return true; -} - -/*! - Removes the specified \a layer and returns true on success. - - All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below - \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both - cases, the total rendering order of all layerables in the QCustomPlot is preserved. - - If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom - layer) becomes the new current layer. - - It is not possible to remove the last layer of the plot. - - \see layer, addLayer, moveLayer -*/ -bool QCustomPlot::removeLayer(QCPLayer *layer) -{ - if (!mLayers.contains(layer)) - { - qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); - return false; - } - if (mLayers.size() < 2) - { - qDebug() << Q_FUNC_INFO << "can't remove last layer"; - return false; - } - - // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) - int removedIndex = layer->index(); - bool isFirstLayer = removedIndex==0; - QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); - QList children = layer->children(); - if (isFirstLayer) // prepend in reverse order (so order relative to each other stays the same) - { - for (int i=children.size()-1; i>=0; --i) - children.at(i)->moveToLayer(targetLayer, true); - } else // append normally - { - for (int i=0; imoveToLayer(targetLayer, false); - } - // if removed layer is current layer, change current layer to layer below/above: - if (layer == mCurrentLayer) - setCurrentLayer(targetLayer); - // invalidate the paint buffer that was responsible for this layer: - if (!layer->mPaintBuffer.isNull()) - layer->mPaintBuffer.data()->setInvalidated(); - // remove layer: - delete layer; - mLayers.removeOne(layer); - updateLayerIndices(); - return true; -} - -/*! - Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or - below is controlled with \a insertMode. - - Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the - QCustomPlot. - - \see layer, addLayer, moveLayer -*/ -bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) -{ - if (!mLayers.contains(layer)) - { - qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); - return false; - } - if (!mLayers.contains(otherLayer)) - { - qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); - return false; - } - - if (layer->index() > otherLayer->index()) - mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); - else if (layer->index() < otherLayer->index()) - mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); - - // invalidate the paint buffers that are responsible for the layers: - if (!layer->mPaintBuffer.isNull()) - layer->mPaintBuffer.data()->setInvalidated(); - if (!otherLayer->mPaintBuffer.isNull()) - otherLayer->mPaintBuffer.data()->setInvalidated(); - - updateLayerIndices(); - return true; -} - -/*! - Returns the number of axis rects in the plot. - - All axis rects can be accessed via QCustomPlot::axisRect(). - - Initially, only one axis rect exists in the plot. - - \see axisRect, axisRects -*/ -int QCustomPlot::axisRectCount() const -{ - return axisRects().size(); -} - -/*! - Returns the axis rect with \a index. - - Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were - added, all of them may be accessed with this function in a linear fashion (even when they are - nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). - - \see axisRectCount, axisRects -*/ -QCPAxisRect *QCustomPlot::axisRect(int index) const -{ - const QList rectList = axisRects(); - if (index >= 0 && index < rectList.size()) - { - return rectList.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "invalid axis rect index" << index; - return 0; - } -} - -/*! - Returns all axis rects in the plot. - - \see axisRectCount, axisRect -*/ -QList QCustomPlot::axisRects() const -{ - QList result; - QStack elementStack; - if (mPlotLayout) - elementStack.push(mPlotLayout); - - while (!elementStack.isEmpty()) - { - foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) - { - if (element) - { - elementStack.push(element); - if (QCPAxisRect *ar = qobject_cast(element)) - result.append(ar); - } - } - } - - return result; -} - -/*! - Returns the layout element at pixel position \a pos. If there is no element at that position, - returns 0. - - Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on - any of its parent elements is set to false, it will not be considered. - - \see itemAt, plottableAt -*/ -QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const -{ - QCPLayoutElement *currentElement = mPlotLayout; - bool searchSubElements = true; - while (searchSubElements && currentElement) - { - searchSubElements = false; - foreach (QCPLayoutElement *subElement, currentElement->elements(false)) - { - if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) - { - currentElement = subElement; - searchSubElements = true; - break; - } - } - } - return currentElement; -} - -/*! - Returns the layout element of type \ref QCPAxisRect at pixel position \a pos. This method ignores - other layout elements even if they are visually in front of the axis rect (e.g. a \ref - QCPLegend). If there is no axis rect at that position, returns 0. - - Only visible axis rects are used. If \ref QCPLayoutElement::setVisible on the axis rect itself or - on any of its parent elements is set to false, it will not be considered. - - \see layoutElementAt -*/ -QCPAxisRect *QCustomPlot::axisRectAt(const QPointF &pos) const -{ - QCPAxisRect *result = 0; - QCPLayoutElement *currentElement = mPlotLayout; - bool searchSubElements = true; - while (searchSubElements && currentElement) - { - searchSubElements = false; - foreach (QCPLayoutElement *subElement, currentElement->elements(false)) - { - if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) - { - currentElement = subElement; - searchSubElements = true; - if (QCPAxisRect *ar = qobject_cast(currentElement)) - result = ar; - break; - } - } - } - return result; -} - -/*! - Returns the axes that currently have selected parts, i.e. whose selection state is not \ref - QCPAxis::spNone. - - \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, - QCPAxis::setSelectableParts -*/ -QList QCustomPlot::selectedAxes() const -{ - QList result, allAxes; - foreach (QCPAxisRect *rect, axisRects()) - allAxes << rect->axes(); - - foreach (QCPAxis *axis, allAxes) - { - if (axis->selectedParts() != QCPAxis::spNone) - result.append(axis); - } - - return result; -} - -/*! - Returns the legends that currently have selected parts, i.e. whose selection state is not \ref - QCPLegend::spNone. - - \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, - QCPLegend::setSelectableParts, QCPLegend::selectedItems -*/ -QList QCustomPlot::selectedLegends() const -{ - QList result; - - QStack elementStack; - if (mPlotLayout) - elementStack.push(mPlotLayout); - - while (!elementStack.isEmpty()) - { - foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) - { - if (subElement) - { - elementStack.push(subElement); - if (QCPLegend *leg = qobject_cast(subElement)) - { - if (leg->selectedParts() != QCPLegend::spNone) - result.append(leg); - } - } - } - } - - return result; -} - -/*! - Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. - - Since calling this function is not a user interaction, this does not emit the \ref - selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the - objects were previously selected. - - \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends -*/ -void QCustomPlot::deselectAll() -{ - foreach (QCPLayer *layer, mLayers) - { - foreach (QCPLayerable *layerable, layer->children()) - layerable->deselectEvent(0); - } -} - -/*! - Causes a complete replot into the internal paint buffer(s). Finally, the widget surface is - refreshed with the new buffer contents. This is the method that must be called to make changes to - the plot, e.g. on the axis ranges or data points of graphs, visible. - - The parameter \a refreshPriority can be used to fine-tune the timing of the replot. For example - if your application calls \ref replot very quickly in succession (e.g. multiple independent - functions change some aspects of the plot and each wants to make sure the change gets replotted), - it is advisable to set \a refreshPriority to \ref QCustomPlot::rpQueuedReplot. This way, the - actual replotting is deferred to the next event loop iteration. Multiple successive calls of \ref - replot with this priority will only cause a single replot, avoiding redundant replots and - improving performance. - - Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the - QCustomPlot widget and user interactions (object selection and range dragging/zooming). - - Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref - afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two - signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite - recursion. - - If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to - replot only that specific layer via \ref QCPLayer::replot. See the documentation there for - details. -*/ -void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) -{ - if (refreshPriority == QCustomPlot::rpQueuedReplot) - { - if (!mReplotQueued) - { - mReplotQueued = true; - QTimer::singleShot(0, this, SLOT(replot())); - } - return; - } - - if (mReplotting) // incase signals loop back to replot slot - return; - mReplotting = true; - mReplotQueued = false; - emit beforeReplot(); - - updateLayout(); - // draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers: - setupPaintBuffers(); - foreach (QCPLayer *layer, mLayers) - layer->drawToPaintBuffer(); - for (int i=0; isetInvalidated(false); - - if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh) - repaint(); - else - update(); - - emit afterReplot(); - mReplotting = false; -} - -/*! - Rescales the axes such that all plottables (like graphs) in the plot are fully visible. - - if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true - (QCPLayerable::setVisible), will be used to rescale the axes. - - \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale -*/ -void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) -{ - QList allAxes; - foreach (QCPAxisRect *rect, axisRects()) - allAxes << rect->axes(); - - foreach (QCPAxis *axis, allAxes) - axis->rescale(onlyVisiblePlottables); -} - -/*! - Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale - of texts and lines will be derived from the specified \a width and \a height. This means, the - output will look like the normal on-screen output of a QCustomPlot widget with the corresponding - pixel width and height. If either \a width or \a height is zero, the exported image will have the - same dimensions as the QCustomPlot widget currently has. - - Setting \a exportPen to \ref QCP::epNoCosmetic allows to disable the use of cosmetic pens when - drawing to the PDF file. Cosmetic pens are pens with numerical width 0, which are always drawn as - a one pixel wide line, no matter what zoom factor is set in the PDF-Viewer. For more information - about cosmetic pens, see the QPainter and QPen documentation. - - The objects of the plot will appear in the current selection state. If you don't want any - selected objects to be painted in their selected look, deselect everything with \ref deselectAll - before calling this function. - - Returns true on success. - - \warning - \li If you plan on editing the exported PDF file with a vector graphics editor like Inkscape, it - is advised to set \a exportPen to \ref QCP::epNoCosmetic to avoid losing those cosmetic lines - (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). - \li If calling this function inside the constructor of the parent of the QCustomPlot widget - (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide - explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this - function uses the current width and height of the QCustomPlot widget. However, in Qt, these - aren't defined yet inside the constructor, so you would get an image that has strange - widths/heights. - - \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting - PDF file. - - \note On Android systems, this method does nothing and issues an according qDebug warning - message. This is also the case if for other reasons the define flag \c QT_NO_PRINTER is set. - - \see savePng, saveBmp, saveJpg, saveRastered -*/ -bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::ExportPen exportPen, const QString &pdfCreator, const QString &pdfTitle) -{ - bool success = false; -#ifdef QT_NO_PRINTER - Q_UNUSED(fileName) - Q_UNUSED(exportPen) - Q_UNUSED(width) - Q_UNUSED(height) - Q_UNUSED(pdfCreator) - Q_UNUSED(pdfTitle) - qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created."; -#else - int newWidth, newHeight; - if (width == 0 || height == 0) - { - newWidth = this->width(); - newHeight = this->height(); - } else - { - newWidth = width; - newHeight = height; - } - - QPrinter printer(QPrinter::ScreenResolution); - printer.setOutputFileName(fileName); - printer.setOutputFormat(QPrinter::PdfFormat); - printer.setColorMode(QPrinter::Color); - printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator); - printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle); - QRect oldViewport = viewport(); - setViewport(QRect(0, 0, newWidth, newHeight)); -#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) - printer.setFullPage(true); - printer.setPaperSize(viewport().size(), QPrinter::DevicePixel); -#else - QPageLayout pageLayout; - pageLayout.setMode(QPageLayout::FullPageMode); - pageLayout.setOrientation(QPageLayout::Portrait); - pageLayout.setMargins(QMarginsF(0, 0, 0, 0)); - pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch)); - printer.setPageLayout(pageLayout); -#endif - QCPPainter printpainter; - if (printpainter.begin(&printer)) - { - printpainter.setMode(QCPPainter::pmVectorized); - printpainter.setMode(QCPPainter::pmNoCaching); - printpainter.setMode(QCPPainter::pmNonCosmetic, exportPen==QCP::epNoCosmetic); - printpainter.setWindow(mViewport); - if (mBackgroundBrush.style() != Qt::NoBrush && - mBackgroundBrush.color() != Qt::white && - mBackgroundBrush.color() != Qt::transparent && - mBackgroundBrush.color().alpha() > 0) // draw pdf background color if not white/transparent - printpainter.fillRect(viewport(), mBackgroundBrush); - draw(&printpainter); - printpainter.end(); - success = true; - } - setViewport(oldViewport); -#endif // QT_NO_PRINTER - return success; -} - -/*! - Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width - and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the - current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. - are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale - parameter. - - For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an - image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, - texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full - 200*200 pixel resolution. - - If you use a high scaling factor, it is recommended to enable antialiasing for all elements by - temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows - QCustomPlot to place objects with sub-pixel accuracy. - - image compression can be controlled with the \a quality parameter which must be between 0 and 100 - or -1 to use the default setting. - - The \a resolution will be written to the image file header and has no direct consequence for the - quality or the pixel size. However, if opening the image with a tool which respects the metadata, - it will be able to scale the image to match either a given size in real units of length (inch, - centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is - given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected - resolution unit internally. - - Returns true on success. If this function fails, most likely the PNG format isn't supported by - the system, see Qt docs about QImageWriter::supportedImageFormats(). - - The objects of the plot will appear in the current selection state. If you don't want any selected - objects to be painted in their selected look, deselect everything with \ref deselectAll before calling - this function. - - If you want the PNG to have a transparent background, call \ref setBackground(const QBrush &brush) - with no brush (Qt::NoBrush) or a transparent color (Qt::transparent), before saving. - - \warning If calling this function inside the constructor of the parent of the QCustomPlot widget - (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide - explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this - function uses the current width and height of the QCustomPlot widget. However, in Qt, these - aren't defined yet inside the constructor, so you would get an image that has strange - widths/heights. - - \see savePdf, saveBmp, saveJpg, saveRastered -*/ -bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) -{ - return saveRastered(fileName, width, height, scale, "PNG", quality, resolution, resolutionUnit); -} - -/*! - Saves a JPEG image file to \a fileName on disc. The output plot will have the dimensions \a width - and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the - current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. - are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale - parameter. - - For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an - image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, - texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full - 200*200 pixel resolution. - - If you use a high scaling factor, it is recommended to enable antialiasing for all elements by - temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows - QCustomPlot to place objects with sub-pixel accuracy. - - image compression can be controlled with the \a quality parameter which must be between 0 and 100 - or -1 to use the default setting. - - The \a resolution will be written to the image file header and has no direct consequence for the - quality or the pixel size. However, if opening the image with a tool which respects the metadata, - it will be able to scale the image to match either a given size in real units of length (inch, - centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is - given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected - resolution unit internally. - - Returns true on success. If this function fails, most likely the JPEG format isn't supported by - the system, see Qt docs about QImageWriter::supportedImageFormats(). - - The objects of the plot will appear in the current selection state. If you don't want any selected - objects to be painted in their selected look, deselect everything with \ref deselectAll before calling - this function. - - \warning If calling this function inside the constructor of the parent of the QCustomPlot widget - (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide - explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this - function uses the current width and height of the QCustomPlot widget. However, in Qt, these - aren't defined yet inside the constructor, so you would get an image that has strange - widths/heights. - - \see savePdf, savePng, saveBmp, saveRastered -*/ -bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) -{ - return saveRastered(fileName, width, height, scale, "JPG", quality, resolution, resolutionUnit); -} - -/*! - Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width - and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the - current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. - are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale - parameter. - - For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an - image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, - texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full - 200*200 pixel resolution. - - If you use a high scaling factor, it is recommended to enable antialiasing for all elements by - temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows - QCustomPlot to place objects with sub-pixel accuracy. - - The \a resolution will be written to the image file header and has no direct consequence for the - quality or the pixel size. However, if opening the image with a tool which respects the metadata, - it will be able to scale the image to match either a given size in real units of length (inch, - centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is - given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected - resolution unit internally. - - Returns true on success. If this function fails, most likely the BMP format isn't supported by - the system, see Qt docs about QImageWriter::supportedImageFormats(). - - The objects of the plot will appear in the current selection state. If you don't want any selected - objects to be painted in their selected look, deselect everything with \ref deselectAll before calling - this function. - - \warning If calling this function inside the constructor of the parent of the QCustomPlot widget - (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide - explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this - function uses the current width and height of the QCustomPlot widget. However, in Qt, these - aren't defined yet inside the constructor, so you would get an image that has strange - widths/heights. - - \see savePdf, savePng, saveJpg, saveRastered -*/ -bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale, int resolution, QCP::ResolutionUnit resolutionUnit) -{ - return saveRastered(fileName, width, height, scale, "BMP", -1, resolution, resolutionUnit); -} - -/*! \internal - - Returns a minimum size hint that corresponds to the minimum size of the top level layout - (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum - size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. - This is especially important, when placed in a QLayout where other components try to take in as - much space as possible (e.g. QMdiArea). -*/ -QSize QCustomPlot::minimumSizeHint() const -{ - return mPlotLayout->minimumOuterSizeHint(); -} - -/*! \internal - - Returns a size hint that is the same as \ref minimumSizeHint. - -*/ -QSize QCustomPlot::sizeHint() const -{ - return mPlotLayout->minimumOuterSizeHint(); -} - -/*! \internal - - Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but - draws the internal buffer on the widget surface. -*/ -void QCustomPlot::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QCPPainter painter(this); - if (!painter.isActive()) - { - return; - } - painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem - if (mBackgroundBrush.style() != Qt::NoBrush) - painter.fillRect(mViewport, mBackgroundBrush); - drawBackground(&painter); - for (int bufferIndex = 0; bufferIndex < mPaintBuffers.size(); ++bufferIndex) - mPaintBuffers.at(bufferIndex)->draw(&painter); - - if(!axisRect()->isScaleRight()) - { - //< 横坐标有效值 - int x = mSymbolPos.x() >= yAxis->axisRect()->left() ? mSymbolPos.x() : yAxis->axisRect()->left(); - x = x <= yAxis->axisRect()->right() ? x : yAxis->axisRect()->right(); - //< 纵坐标 - int y = yAxis->axisRect()->top(); - - painter.save(); - painter.setPen(QColor(182, 194, 205)); - painter.setBrush(QColor(182, 194, 205)); - painter.setAntialiasing(true); - QPolygon polygon; - polygon.append(QPoint(x, y)); - polygon.append(QPoint(x + 3, y - 5)); - polygon.append(QPoint(x + 3, 0)); - polygon.append(QPoint(x - 3, 0)); - polygon.append(QPoint(x - 3, y - 5)); - painter.drawPolygon(polygon); - painter.drawLine(QPoint(x, y), QPoint(x, yAxis->axisRect()->bottom())); - painter.restore(); - } -} - -/*! \internal - - Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect - of mPlotLayout) is resized appropriately. Finally a \ref replot is performed. -*/ -void QCustomPlot::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event) - // resize and repaint the buffer: - setViewport(rect()); - replot(rpQueuedRefresh); // queued refresh is important here, to prevent painting issues in some contexts (e.g. MDI subwindow) -} - -/*! \internal - - Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then - determines the layerable under the cursor and forwards the event to it. Finally, emits the - specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref - axisDoubleClick, etc.). - - \see mousePressEvent, mouseReleaseEvent -*/ -void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) -{ - emit mouseDoubleClick(event); - mMouseHasMoved = false; - mMousePressPos = event->pos(); - - // determine layerable under the cursor (this event is called instead of the second press event in a double-click): - QList details; - QList candidates = layerableListAt(mMousePressPos, false, &details); - for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list - candidates.at(i)->mouseDoubleClickEvent(event, details.at(i)); - if (event->isAccepted()) - { - mMouseEventLayerable = candidates.at(i); - mMouseEventLayerableDetails = details.at(i); - break; - } - } - - // emit specialized object double click signals: - if (!candidates.isEmpty()) - { - if (QCPAbstractPlottable *ap = qobject_cast(candidates.first())) - { - int dataIndex = 0; - if (!details.first().value().isEmpty()) - dataIndex = details.first().value().dataRange().begin(); - emit plottableDoubleClick(ap, dataIndex, event); - } else if (QCPAxis *ax = qobject_cast(candidates.first())) - emit axisDoubleClick(ax, details.first().value(), event); - else if (QCPAbstractItem *ai = qobject_cast(candidates.first())) - emit itemDoubleClick(ai, event); - else if (QCPLegend *lg = qobject_cast(candidates.first())) - emit legendDoubleClick(lg, 0, event); - else if (QCPAbstractLegendItem *li = qobject_cast(candidates.first())) - emit legendDoubleClick(li->parentLegend(), li, event); - } - - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. -} - -/*! \internal - - Event handler for when a mouse button is pressed. Emits the mousePress signal. - - If the current \ref setSelectionRectMode is not \ref QCP::srmNone, passes the event to the - selection rect. Otherwise determines the layerable under the cursor and forwards the event to it. - - \see mouseMoveEvent, mouseReleaseEvent -*/ -void QCustomPlot::mousePressEvent(QMouseEvent *event) -{ - if(cursor().shape() == Qt::SizeHorCursor && event->button() == Qt::LeftButton) - { - mSymbolPos = event->pos(); - mSymbolPressed = true; - return; - } - - emit mousePress(event); - // save some state to tell in releaseEvent whether it was a click: - - - mMouseHasMoved = false; - mMousePressPos = event->pos(); - - if (mSelectionRect && mSelectionRectMode != QCP::srmNone) - { - if (mSelectionRectMode != QCP::srmZoom || qobject_cast(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect - mSelectionRect->startSelection(event); - } else - { - // no selection rect interaction, prepare for click signal emission and forward event to layerable under the cursor: - QList details; - QList candidates = layerableListAt(mMousePressPos, false, &details); - if (!candidates.isEmpty()) - { - mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always topmost hit layerable (signal emitted in release event) - mMouseSignalLayerableDetails = details.first(); - } - // forward event to topmost candidate which accepts the event: - for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events call ignore() on the event, in that case propagate to next candidate in list - candidates.at(i)->mousePressEvent(event, details.at(i)); - if (event->isAccepted()) - { - mMouseEventLayerable = candidates.at(i); - mMouseEventLayerableDetails = details.at(i); - break; - } - } - } - - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. - update(); -} - -/*! \internal - - Event handler for when the cursor is moved. Emits the \ref mouseMove signal. - - If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it - in order to update the rect geometry. - - Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the - layout element before), the mouseMoveEvent is forwarded to that element. - - \see mousePressEvent, mouseReleaseEvent -*/ -void QCustomPlot::mouseMoveEvent(QMouseEvent *event) -{ - //< time tip - if(!axisRect()->isScaleRight() && !mSymbolPressed && qAbs(mSymbolPos.x() - event->pos().x()) < 5) - { - if(event->pos().y() > yAxis->axisRect()->top()) - { - if(Qt::SizeHorCursor != cursor().shape()) - { - setCursor(QCursor(Qt::SizeHorCursor)); - } - } - static QString preTipsContent = QString(); - QString strTime = QDateTime::fromMSecsSinceEpoch(xAxis->pixelToCoord(mSymbolPos.x())).toString("yyyy-MM-dd hh:mm:ss zzz"); - if(preTipsContent == strTime && findChild("ToolTip")) - { - return; - } - preTipsContent = strTime; - QFontMetrics metrics(QToolTip::font()); - int pixelsWide = metrics.width(strTime); - int pixelsHigh = metrics.height(); - QPoint position = mapToGlobal(QPoint(event->pos().x() - (pixelsWide / 2), -(pixelsHigh / 2))); - CToolTip::popup(position, strTime, this); - return; - } - - if(mSymbolPressed && event->pos().x() >= yAxis->mAxisRect->left() &&event->pos().x() <= yAxis->mAxisRect->right()) - { - setCursor(QCursor(Qt::SizeHorCursor)); - mSymbolPos = event->pos(); - emit symbolPosChanged(xAxis->pixelToCoord(mSymbolPos.x())); - update(); - return; - } - setCursor(QCursor(Qt::ArrowCursor)); - - - emit mouseMove(event); - if (!mMouseHasMoved && (mMousePressPos-event->pos()).manhattanLength() > 3) - mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release - - if (mSelectionRect && mSelectionRect->isActive()) - mSelectionRect->moveSelection(event); - else if (mMouseEventLayerable) // call event of affected layerable: - mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos); - - //< Extra By ZH - QList details; - QList candidates = layerableListAt(event->pos(), false, &details); - for (int i = 0; i < candidates.size(); ++i) - { - if(dynamic_cast(candidates.at(i))) - { - event->accept(); - candidates.at(i)->mouseMoveEvent(event, mMousePressPos); - } - } - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. -} - -/*! \internal - - Event handler for when a mouse button is released. Emits the \ref mouseRelease signal. - - If the mouse was moved less than a certain threshold in any direction since the \ref - mousePressEvent, it is considered a click which causes the selection mechanism (if activated via - \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse - click signals are emitted (e.g. \ref plottableClick, \ref axisClick, etc.) - - If a layerable is the mouse capturer (a \ref mousePressEvent happened on top of the layerable - before), the \ref mouseReleaseEvent is forwarded to that element. - - \see mousePressEvent, mouseMoveEvent -*/ -void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) -{ - emit mouseRelease(event); - - mSymbolPressed = false; - if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click - { - if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here - mSelectionRect->cancel(); - if (event->button() == Qt::LeftButton) - processPointSelection(event); - - // emit specialized click signals of QCustomPlot instance: - if (QCPAbstractPlottable *ap = qobject_cast(mMouseSignalLayerable)) - { - int dataIndex = 0; - if (!mMouseSignalLayerableDetails.value().isEmpty()) - dataIndex = mMouseSignalLayerableDetails.value().dataRange().begin(); - emit plottableClick(ap, dataIndex, event); - } else if (QCPAxis *ax = qobject_cast(mMouseSignalLayerable)) - emit axisClick(ax, mMouseSignalLayerableDetails.value(), event); - else if (QCPAbstractItem *ai = qobject_cast(mMouseSignalLayerable)) - emit itemClick(ai, event); - else if (QCPLegend *lg = qobject_cast(mMouseSignalLayerable)) - emit legendClick(lg, 0, event); - else if (QCPAbstractLegendItem *li = qobject_cast(mMouseSignalLayerable)) - emit legendClick(li->parentLegend(), li, event); - mMouseSignalLayerable = 0; - } - - if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there - { - // finish selection rect, the appropriate action will be taken via signal-slot connection: - mSelectionRect->endSelection(event); - } else - { - // call event of affected layerable: - if (mMouseEventLayerable) - { - mMouseEventLayerable->mouseReleaseEvent(event, mMousePressPos); - mMouseEventLayerable = 0; - } - } - - if (noAntialiasingOnDrag()) - replot(rpQueuedReplot); - - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. -} - -/*! \internal - - Event handler for mouse wheel events. First, the \ref mouseWheel signal is emitted. Then - determines the affected layerable and forwards the event to it. -*/ -void QCustomPlot::wheelEvent(QWheelEvent *event) -{ - QRect rt = axisRect()->mRect; - if(event->pos().x() < rt.left() || event->pos().x() > rt.right() || event->pos().y() < rt.top() || event->pos().y() > rt.bottom()) - { - return; - } - - emit mouseWheel(event); - // forward event to layerable under cursor: - QList candidates = layerableListAt(event->pos(), false); - - - for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list - candidates.at(i)->wheelEvent(event); - if (event->isAccepted()) - break; - } - event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. -} - -bool QCustomPlot::eventFilter(QObject *object, QEvent *event) -{ - QLabel * pLabel = dynamic_cast(object); - if (pLabel) - { - if(event->type() == QEvent::Wheel) - { - QWheelEvent * pWheelEvent = dynamic_cast(event); - QWheelEvent e(mapFromGlobal(pWheelEvent->globalPos()), - pWheelEvent->globalPos(), - pWheelEvent->pixelDelta(), - pWheelEvent->angleDelta(), - pWheelEvent->delta(), - pWheelEvent->orientation(), - pWheelEvent->buttons(), - pWheelEvent->modifiers()); - - wheelEvent(&e); - return true; - } - else if(event->type() == QEvent::MouseMove) - { - QMouseEvent *pMouseEvent = dynamic_cast(event); - QPoint pt = mapFromGlobal(pMouseEvent->globalPos()); - QMouseEvent e(pMouseEvent->type(), - pt, pt, - pMouseEvent->screenPos(), - pMouseEvent->button(), - pMouseEvent->buttons(), - pMouseEvent->modifiers(), - pMouseEvent->source()); - mouseMoveEvent(&e); - return true; - } - } - return QWidget::eventFilter(object, event); -} - -/*! \internal - - This function draws the entire plot, including background pixmap, with the specified \a painter. - It does not make use of the paint buffers like \ref replot, so this is the function typically - used by saving/exporting methods such as \ref savePdf or \ref toPainter. - - Note that it does not fill the background with the background brush (as the user may specify with - \ref setBackground(const QBrush &brush)), this is up to the respective functions calling this - method. -*/ -void QCustomPlot::draw(QCPPainter *painter) -{ - updateLayout(); - - // draw viewport background pixmap: - drawBackground(painter); - - // draw all layered objects (grid, axes, plottables, items, legend,...): - foreach (QCPLayer *layer, mLayers) - layer->draw(painter); - - /* Debug code to draw all layout element rects - foreach (QCPLayoutElement* el, findChildren()) - { - painter->setBrush(Qt::NoBrush); - painter->setPen(QPen(QColor(0, 0, 0, 100), 0, Qt::DashLine)); - painter->drawRect(el->rect()); - painter->setPen(QPen(QColor(255, 0, 0, 100), 0, Qt::DashLine)); - painter->drawRect(el->outerRect()); - } - */ -} - -/*! \internal - - Performs the layout update steps defined by \ref QCPLayoutElement::UpdatePhase, by calling \ref - QCPLayoutElement::update on the main plot layout. - - Here, the layout elements calculate their positions and margins, and prepare for the following - draw call. -*/ -void QCustomPlot::updateLayout() -{ - // run through layout phases: - mPlotLayout->update(QCPLayoutElement::upPreparation); - mPlotLayout->update(QCPLayoutElement::upMargins); - mPlotLayout->update(QCPLayoutElement::upLayout); -} - -/*! \internal - - Draws the viewport background pixmap of the plot. - - If a pixmap was provided via \ref setBackground, this function buffers the scaled version - depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside - the viewport with the provided \a painter. The scaled version is buffered in - mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when - the axis rect has changed in a way that requires a rescale of the background pixmap (this is - dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was - set. - - Note that this function does not draw a fill with the background brush - (\ref setBackground(const QBrush &brush)) beneath the pixmap. - - \see setBackground, setBackgroundScaled, setBackgroundScaledMode -*/ -void QCustomPlot::drawBackground(QCPPainter *painter) -{ - // Note: background color is handled in individual replot/save functions - - // draw background pixmap (on top of fill, if brush specified): - if (!mBackgroundPixmap.isNull()) - { - if (mBackgroundScaled) - { - // check whether mScaledBackground needs to be updated: - QSize scaledSize(mBackgroundPixmap.size()); - scaledSize.scale(mViewport.size(), mBackgroundScaledMode); - if (mScaledBackgroundPixmap.size() != scaledSize) - mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation); - painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect()); - } else - { - painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height())); - } - } -} - -/*! \internal - - Goes through the layers and makes sure this QCustomPlot instance holds the correct number of - paint buffers and that they have the correct configuration (size, pixel ratio, etc.). - Allocations, reallocations and deletions of paint buffers are performed as necessary. It also - associates the paint buffers with the layers, so they draw themselves into the right buffer when - \ref QCPLayer::drawToPaintBuffer is called. This means it associates adjacent \ref - QCPLayer::lmLogical layers to a mutual paint buffer and creates dedicated paint buffers for - layers in \ref QCPLayer::lmBuffered mode. - - This method uses \ref createPaintBuffer to create new paint buffers. - - After this method, the paint buffers are empty (filled with \c Qt::transparent) and invalidated - (so an attempt to replot only a single buffered layer causes a full replot). - - This method is called in every \ref replot call, prior to actually drawing the layers (into their - associated paint buffer). If the paint buffers don't need changing/reallocating, this method - basically leaves them alone and thus finishes very fast. -*/ -void QCustomPlot::setupPaintBuffers() -{ - int bufferIndex = 0; - if (mPaintBuffers.isEmpty()) - mPaintBuffers.append(QSharedPointer(createPaintBuffer())); - - for (int layerIndex = 0; layerIndex < mLayers.size(); ++layerIndex) - { - QCPLayer *layer = mLayers.at(layerIndex); - if (layer->mode() == QCPLayer::lmLogical) - { - layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); - } else if (layer->mode() == QCPLayer::lmBuffered) - { - ++bufferIndex; - if (bufferIndex >= mPaintBuffers.size()) - mPaintBuffers.append(QSharedPointer(createPaintBuffer())); - layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); - if (layerIndex < mLayers.size()-1 && mLayers.at(layerIndex+1)->mode() == QCPLayer::lmLogical) // not last layer, and next one is logical, so prepare another buffer for next layerables - { - ++bufferIndex; - if (bufferIndex >= mPaintBuffers.size()) - mPaintBuffers.append(QSharedPointer(createPaintBuffer())); - } - } - } - // remove unneeded buffers: - while (mPaintBuffers.size()-1 > bufferIndex) - mPaintBuffers.removeLast(); - // resize buffers to viewport size and clear contents: - for (int i=0; isetSize(viewport().size()); // won't do anything if already correct size - mPaintBuffers.at(i)->clear(Qt::transparent); - mPaintBuffers.at(i)->setInvalidated(); - } -} - -/*! \internal - - This method is used by \ref setupPaintBuffers when it needs to create new paint buffers. - - Depending on the current setting of \ref setOpenGl, and the current Qt version, different - backends (subclasses of \ref QCPAbstractPaintBuffer) are created, initialized with the proper - size and device pixel ratio, and returned. -*/ -QCPAbstractPaintBuffer *QCustomPlot::createPaintBuffer() -{ - if (mOpenGl) - { -#if defined(QCP_OPENGL_FBO) - return new QCPPaintBufferGlFbo(viewport().size(), mBufferDevicePixelRatio, mGlContext, mGlPaintDevice); -#elif defined(QCP_OPENGL_PBUFFER) - return new QCPPaintBufferGlPbuffer(viewport().size(), mBufferDevicePixelRatio, mOpenGlMultisamples); -#else - qDebug() << Q_FUNC_INFO << "OpenGL enabled even though no support for it compiled in, this shouldn't have happened. Falling back to pixmap paint buffer."; - return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); -#endif - } else - return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); -} - -/*! - This method returns whether any of the paint buffers held by this QCustomPlot instance are - invalidated. - - If any buffer is invalidated, a partial replot (\ref QCPLayer::replot) is not allowed and always - causes a full replot (\ref QCustomPlot::replot) of all layers. This is the case when for example - the layer order has changed, new layers were added, layers were removed, or layer modes were - changed (\ref QCPLayer::setMode). - - \see QCPAbstractPaintBuffer::setInvalidated -*/ -bool QCustomPlot::hasInvalidatedPaintBuffers() -{ - for (int i=0; iinvalidated()) - return true; - } - return false; -} - -/*! \internal - - When \ref setOpenGl is set to true, this method is used to initialize OpenGL (create a context, - surface, paint device). - - Returns true on success. - - If this method is successful, all paint buffers should be deleted and then reallocated by calling - \ref setupPaintBuffers, so the OpenGL-based paint buffer subclasses (\ref - QCPPaintBufferGlPbuffer, \ref QCPPaintBufferGlFbo) are used for subsequent replots. - - \see freeOpenGl -*/ -bool QCustomPlot::setupOpenGl() -{ -#ifdef QCP_OPENGL_FBO - freeOpenGl(); - QSurfaceFormat proposedSurfaceFormat; - proposedSurfaceFormat.setSamples(mOpenGlMultisamples); -#ifdef QCP_OPENGL_OFFSCREENSURFACE - QOffscreenSurface *surface = new QOffscreenSurface; -#else - QWindow *surface = new QWindow; - surface->setSurfaceType(QSurface::OpenGLSurface); -#endif - surface->setFormat(proposedSurfaceFormat); - surface->create(); - mGlSurface = QSharedPointer(surface); - mGlContext = QSharedPointer(new QOpenGLContext); - mGlContext->setFormat(mGlSurface->format()); - if (!mGlContext->create()) - { - qDebug() << Q_FUNC_INFO << "Failed to create OpenGL context"; - mGlContext.clear(); - mGlSurface.clear(); - return false; - } - if (!mGlContext->makeCurrent(mGlSurface.data())) // context needs to be current to create paint device - { - qDebug() << Q_FUNC_INFO << "Failed to make opengl context current"; - mGlContext.clear(); - mGlSurface.clear(); - return false; - } - if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) - { - qDebug() << Q_FUNC_INFO << "OpenGL of this system doesn't support frame buffer objects"; - mGlContext.clear(); - mGlSurface.clear(); - return false; - } - mGlPaintDevice = QSharedPointer(new QOpenGLPaintDevice); - return true; -#elif defined(QCP_OPENGL_PBUFFER) - return QGLFormat::hasOpenGL(); -#else - return false; -#endif -} - -/*! \internal - - When \ref setOpenGl is set to false, this method is used to deinitialize OpenGL (releases the - context and frees resources). - - After OpenGL is disabled, all paint buffers should be deleted and then reallocated by calling - \ref setupPaintBuffers, so the standard software rendering paint buffer subclass (\ref - QCPPaintBufferPixmap) is used for subsequent replots. - - \see setupOpenGl -*/ -void QCustomPlot::freeOpenGl() -{ -#ifdef QCP_OPENGL_FBO - mGlPaintDevice.clear(); - mGlContext.clear(); - mGlSurface.clear(); -#endif -} - -/*! \internal - - This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot - so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. -*/ -void QCustomPlot::axisRemoved(QCPAxis *axis) -{ - if (xAxis == axis) - xAxis = 0; - if (xAxis2 == axis) - xAxis2 = 0; - if (yAxis == axis) - yAxis = 0; - if (yAxis2 == axis) - yAxis2 = 0; - - // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers -} - -/*! \internal - - This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so - it may clear its QCustomPlot::legend member accordingly. -*/ -void QCustomPlot::legendRemoved(QCPLegend *legend) -{ - if (this->legend == legend) - this->legend = 0; -} - -/*! \internal - - This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref - setSelectionRectMode is set to \ref QCP::srmSelect. - - First, it determines which axis rect was the origin of the selection rect judging by the starting - point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be - precise) associated with that axis rect and finds the data points that are in \a rect. It does - this by querying their \ref QCPAbstractPlottable1D::selectTestRect method. - - Then, the actual selection is done by calling the plottables' \ref - QCPAbstractPlottable::selectEvent, placing the found selected data points in the \a details - parameter as QVariant(\ref QCPDataSelection). All plottables that weren't touched by \a - rect receive a \ref QCPAbstractPlottable::deselectEvent. - - \see processRectZoom -*/ -void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) -{ - bool selectionStateChanged = false; - - if (mInteractions.testFlag(QCP::iSelectPlottables)) - { - QMap > potentialSelections; // map key is number of selected data points, so we have selections sorted by size - QRectF rectF(rect.normalized()); - if (QCPAxisRect *affectedAxisRect = axisRectAt(rectF.topLeft())) - { - // determine plottables that were hit by the rect and thus are candidates for selection: - foreach (QCPAbstractPlottable *plottable, affectedAxisRect->plottables()) - { - if (QCPPlottableInterface1D *plottableInterface = plottable->interface1D()) - { - QCPDataSelection dataSel = plottableInterface->selectTestRect(rectF, true); - if (!dataSel.isEmpty()) - potentialSelections.insertMulti(dataSel.dataPointCount(), QPair(plottable, dataSel)); - } - } - - if (!mInteractions.testFlag(QCP::iMultiSelect)) - { - // only leave plottable with most selected points in map, since we will only select a single plottable: - if (!potentialSelections.isEmpty()) - { - QMap >::iterator it = potentialSelections.begin(); - while (it != potentialSelections.end()-1) // erase all except last element - it = potentialSelections.erase(it); - } - } - - bool additive = event->modifiers().testFlag(mMultiSelectModifier); - // deselect all other layerables if not additive selection: - if (!additive) - { - // emit deselection except to those plottables who will be selected afterwards: - foreach (QCPLayer *layer, mLayers) - { - foreach (QCPLayerable *layerable, layer->children()) - { - if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory())) - { - bool selChanged = false; - layerable->deselectEvent(&selChanged); - selectionStateChanged |= selChanged; - } - } - } - } - - // go through selections in reverse (largest selection first) and emit select events: - QMap >::const_iterator it = potentialSelections.constEnd(); - while (it != potentialSelections.constBegin()) - { - --it; - if (mInteractions.testFlag(it.value().first->selectionCategory())) - { - bool selChanged = false; - it.value().first->selectEvent(event, additive, QVariant::fromValue(it.value().second), &selChanged); - selectionStateChanged |= selChanged; - } - } - } - } - - if (selectionStateChanged) - { - emit selectionChangedByUser(); - replot(rpQueuedReplot); - } else if (mSelectionRect) - mSelectionRect->layer()->replot(); -} - -/*! \internal - - This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref - setSelectionRectMode is set to \ref QCP::srmZoom. - - It determines which axis rect was the origin of the selection rect judging by the starting point - of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the - provided \a rect (see \ref QCPAxisRect::zoom). - - \see processRectSelection -*/ -void QCustomPlot::processRectZoom(QRect rect, QMouseEvent *event) -{ - Q_UNUSED(event) - if (QCPAxisRect *axisRect = axisRectAt(rect.topLeft())) - { - QList affectedAxes = QList() << axisRect->rangeZoomAxes(Qt::Horizontal) << axisRect->rangeZoomAxes(Qt::Vertical); - affectedAxes.removeAll(static_cast(0)); - axisRect->zoom(QRectF(rect), affectedAxes); - } - replot(rpQueuedReplot); // always replot to make selection rect disappear -} - -/*! \internal - - This method is called when a simple left mouse click was detected on the QCustomPlot surface. - - It first determines the layerable that was hit by the click, and then calls its \ref - QCPLayerable::selectEvent. All other layerables receive a QCPLayerable::deselectEvent (unless the - multi-select modifier was pressed, see \ref setMultiSelectModifier). - - In this method the hit layerable is determined a second time using \ref layerableAt (after the - one in \ref mousePressEvent), because we want \a onlySelectable set to true this time. This - implies that the mouse event grabber (mMouseEventLayerable) may be a different one from the - clicked layerable determined here. For example, if a non-selectable layerable is in front of a - selectable layerable at the click position, the front layerable will receive mouse events but the - selectable one in the back will receive the \ref QCPLayerable::selectEvent. - - \see processRectSelection, QCPLayerable::selectTest -*/ -void QCustomPlot::processPointSelection(QMouseEvent *event) -{ - QVariant details; - QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details); - bool selectionStateChanged = false; - bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); - // deselect all other layerables if not additive selection: - if (!additive) - { - foreach (QCPLayer *layer, mLayers) - { - foreach (QCPLayerable *layerable, layer->children()) - { - if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory())) - { - bool selChanged = false; - layerable->deselectEvent(&selChanged); - selectionStateChanged |= selChanged; - } - } - } - } - if (clickedLayerable && mInteractions.testFlag(clickedLayerable->selectionCategory())) - { - // a layerable was actually clicked, call its selectEvent: - bool selChanged = false; - clickedLayerable->selectEvent(event, additive, details, &selChanged); - selectionStateChanged |= selChanged; - } - if (selectionStateChanged) - { - emit selectionChangedByUser(); - replot(rpQueuedReplot); - } -} - -/*! \internal - - Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend - is enabled, adds it to the legend (QCustomPlot::legend). QCustomPlot takes ownership of the - plottable. - - Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of - \a plottable is this QCustomPlot. - - This method is called automatically in the QCPAbstractPlottable base class constructor. -*/ -bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) -{ - if (mPlottables.contains(plottable)) - { - qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); - return false; - } - if (plottable->parentPlot() != this) - { - qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); - return false; - } - - mPlottables.append(plottable); - // possibly add plottable to legend: - if (mAutoAddPlottableToLegend) - plottable->addToLegend(); - if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) - plottable->setLayer(currentLayer()); - return true; -} - -/*! \internal - - In order to maintain the simplified graph interface of QCustomPlot, this method is called by the - QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true - on success, i.e. if \a graph is valid and wasn't already registered with this QCustomPlot. - - This graph specific registration happens in addition to the call to \ref registerPlottable by the - QCPAbstractPlottable base class. -*/ -bool QCustomPlot::registerGraph(QCPGraph *graph) -{ - if (!graph) - { - qDebug() << Q_FUNC_INFO << "passed graph is zero"; - return false; - } - if (mGraphs.contains(graph)) - { - qDebug() << Q_FUNC_INFO << "graph already registered with this QCustomPlot"; - return false; - } - - mGraphs.append(graph); - return true; -} - - -/*! \internal - - Registers the specified item with this QCustomPlot. QCustomPlot takes ownership of the item. - - Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a - item is this QCustomPlot. - - This method is called automatically in the QCPAbstractItem base class constructor. -*/ -bool QCustomPlot::registerItem(QCPAbstractItem *item) -{ - if (mItems.contains(item)) - { - qDebug() << Q_FUNC_INFO << "item already added to this QCustomPlot:" << reinterpret_cast(item); - return false; - } - if (item->parentPlot() != this) - { - qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast(item); - return false; - } - - mItems.append(item); - if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor) - item->setLayer(currentLayer()); - return true; -} - -/*! \internal - - Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called - after every operation that changes the layer indices, like layer removal, layer creation, layer - moving. -*/ -void QCustomPlot::updateLayerIndices() const -{ - for (int i=0; imIndex = i; -} - -/*! \internal - - Returns the top-most layerable at pixel position \a pos. If \a onlySelectable is set to true, - only those layerables that are selectable will be considered. (Layerable subclasses communicate - their selectability via the QCPLayerable::selectTest method, by returning -1.) - - \a selectionDetails is an output parameter that contains selection specifics of the affected - layerable. This is useful if the respective layerable shall be given a subsequent - QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains - information about which part of the layerable was hit, in multi-part layerables (e.g. - QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref - QCPDataSelection instance with the single data point which is closest to \a pos. - - \see layerableListAt, layoutElementAt, axisRectAt -*/ -QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const -{ - QList details; - QList candidates = layerableListAt(pos, onlySelectable, selectionDetails ? &details : 0); - if (selectionDetails && !details.isEmpty()) - *selectionDetails = details.first(); - if (!candidates.isEmpty()) - return candidates.first(); - else - return 0; -} - -/*! \internal - - Returns the layerables at pixel position \a pos. If \a onlySelectable is set to true, only those - layerables that are selectable will be considered. (Layerable subclasses communicate their - selectability via the QCPLayerable::selectTest method, by returning -1.) - - The returned list is sorted by the layerable/drawing order. If you only need to know the top-most - layerable, rather use \ref layerableAt. - - \a selectionDetails is an output parameter that contains selection specifics of the affected - layerable. This is useful if the respective layerable shall be given a subsequent - QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains - information about which part of the layerable was hit, in multi-part layerables (e.g. - QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref - QCPDataSelection instance with the single data point which is closest to \a pos. - - \see layerableAt, layoutElementAt, axisRectAt -*/ -QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails) const -{ - QList result; - for (int layerIndex=mLayers.size()-1; layerIndex>=0; --layerIndex) - { - const QList layerables = mLayers.at(layerIndex)->children(); - for (int i=layerables.size()-1; i>=0; --i) - { - if (!layerables.at(i)->realVisibility()) - continue; - QVariant details; - double dist = layerables.at(i)->selectTest(pos, onlySelectable, selectionDetails ? &details : 0); - if (dist >= 0 && dist < selectionTolerance()) - { - result.append(layerables.at(i)); - if (selectionDetails) - selectionDetails->append(details); - } - } - } - return result; -} - -/*! - Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is - sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead - to a full resolution file with width 200.) If the \a format supports compression, \a quality may - be between 0 and 100 to control it. - - Returns true on success. If this function fails, most likely the given \a format isn't supported - by the system, see Qt docs about QImageWriter::supportedImageFormats(). - - The \a resolution will be written to the image file header (if the file format supports this) and - has no direct consequence for the quality or the pixel size. However, if opening the image with a - tool which respects the metadata, it will be able to scale the image to match either a given size - in real units of length (inch, centimeters, etc.), or the target display DPI. You can specify in - which units \a resolution is given, by setting \a resolutionUnit. The \a resolution is converted - to the format's expected resolution unit internally. - - \see saveBmp, saveJpg, savePng, savePdf -*/ -bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) -{ - QImage buffer = toPixmap(width, height, scale).toImage(); - - int dotsPerMeter = 0; - switch (resolutionUnit) - { - case QCP::ruDotsPerMeter: dotsPerMeter = resolution; break; - case QCP::ruDotsPerCentimeter: dotsPerMeter = resolution*100; break; - case QCP::ruDotsPerInch: dotsPerMeter = resolution/0.0254; break; - } - buffer.setDotsPerMeterX(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools - buffer.setDotsPerMeterY(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools - if (!buffer.isNull()) - return buffer.save(fileName, format, quality); - else - return false; -} - -/*! - Renders the plot to a pixmap and returns it. - - The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and - scale 2.0 lead to a full resolution pixmap with width 200.) - - \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf -*/ -QPixmap QCustomPlot::toPixmap(int width, int height, double scale) -{ - // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too. - int newWidth, newHeight; - if (width == 0 || height == 0) - { - newWidth = this->width(); - newHeight = this->height(); - } else - { - newWidth = width; - newHeight = height; - } - int scaledWidth = qRound(scale*newWidth); - int scaledHeight = qRound(scale*newHeight); - - QPixmap result(scaledWidth, scaledHeight); - result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later - QCPPainter painter; - painter.begin(&result); - if (painter.isActive()) - { - QRect oldViewport = viewport(); - setViewport(QRect(0, 0, newWidth, newHeight)); - painter.setMode(QCPPainter::pmNoCaching); - if (!qFuzzyCompare(scale, 1.0)) - { - if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales - painter.setMode(QCPPainter::pmNonCosmetic); - painter.scale(scale, scale); - } - if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill - painter.fillRect(mViewport, mBackgroundBrush); - draw(&painter); - setViewport(oldViewport); - painter.end(); - } else // might happen if pixmap has width or height zero - { - qDebug() << Q_FUNC_INFO << "Couldn't activate painter on pixmap"; - return QPixmap(); - } - return result; -} - -/*! - Renders the plot using the passed \a painter. - - The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will - appear scaled accordingly. - - \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter - on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with - the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. - - \see toPixmap -*/ -void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) -{ - // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too. - int newWidth, newHeight; - if (width == 0 || height == 0) - { - newWidth = this->width(); - newHeight = this->height(); - } else - { - newWidth = width; - newHeight = height; - } - - if (painter->isActive()) - { - QRect oldViewport = viewport(); - setViewport(QRect(0, 0, newWidth, newHeight)); - painter->setMode(QCPPainter::pmNoCaching); - if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here - painter->fillRect(mViewport, mBackgroundBrush); - draw(painter); - setViewport(oldViewport); - } else - qDebug() << Q_FUNC_INFO << "Passed painter is not active"; -} -/* end of 'src/core.cpp' */ - -//amalgamation: add plottable1d.cpp - -/* including file 'src/colorgradient.cpp', size 24646 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPColorGradient -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPColorGradient - \brief Defines a color gradient for use with e.g. \ref QCPColorMap - - This class describes a color gradient which can be used to encode data with color. For example, - QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which - take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) - with a \a position from 0 to 1. In between these defined color positions, the - color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation. - - Alternatively, load one of the preset color gradients shown in the image below, with \ref - loadPreset, or by directly specifying the preset in the constructor. - - Apart from red, green and blue components, the gradient also interpolates the alpha values of the - configured color stops. This allows to display some portions of the data range as transparent in - the plot. - - \image html QCPColorGradient.png - - The \ref QCPColorGradient(GradientPreset preset) constructor allows directly converting a \ref - GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset - to all the \a setGradient methods, e.g.: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient - - The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the - color gradient shall be applied periodically (wrapping around) to data values that lie outside - the data range specified on the plottable instance can be controlled with \ref setPeriodic. -*/ - -/*! - Constructs a new, empty QCPColorGradient with no predefined color stops. You can add own color - stops with \ref setColorStopAt. - - The color level count is initialized to 350. -*/ -QCPColorGradient::QCPColorGradient() : - mLevelCount(350), - mColorInterpolation(ciRGB), - mPeriodic(false), - mColorBufferInvalidated(true) -{ - mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); -} - -/*! - Constructs a new QCPColorGradient initialized with the colors and color interpolation according - to \a preset. - - The color level count is initialized to 350. -*/ -QCPColorGradient::QCPColorGradient(GradientPreset preset) : - mLevelCount(350), - mColorInterpolation(ciRGB), - mPeriodic(false), - mColorBufferInvalidated(true) -{ - mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); - loadPreset(preset); -} - -/* undocumented operator */ -bool QCPColorGradient::operator==(const QCPColorGradient &other) const -{ - return ((other.mLevelCount == this->mLevelCount) && - (other.mColorInterpolation == this->mColorInterpolation) && - (other.mPeriodic == this->mPeriodic) && - (other.mColorStops == this->mColorStops)); -} - -/*! - Sets the number of discretization levels of the color gradient to \a n. The default is 350 which - is typically enough to create a smooth appearance. The minimum number of levels is 2. - - \image html QCPColorGradient-levelcount.png -*/ -void QCPColorGradient::setLevelCount(int n) -{ - if (n < 2) - { - qDebug() << Q_FUNC_INFO << "n must be greater or equal 2 but was" << n; - n = 2; - } - if (n != mLevelCount) - { - mLevelCount = n; - mColorBufferInvalidated = true; - } -} - -/*! - Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the - colors are the values of the passed QMap \a colorStops. In between these color stops, the color - is interpolated according to \ref setColorInterpolation. - - A more convenient way to create a custom gradient may be to clear all color stops with \ref - clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with - \ref setColorStopAt. - - \see clearColorStops -*/ -void QCPColorGradient::setColorStops(const QMap &colorStops) -{ - mColorStops = colorStops; - mColorBufferInvalidated = true; -} - -/*! - Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between - these color stops, the color is interpolated according to \ref setColorInterpolation. - - \see setColorStops, clearColorStops -*/ -void QCPColorGradient::setColorStopAt(double position, const QColor &color) -{ - mColorStops.insert(position, color); - mColorBufferInvalidated = true; -} - -/*! - Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be - interpolated linearly in RGB or in HSV color space. - - For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, - whereas in HSV space the intermediate color is yellow. -*/ -void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation) -{ - if (interpolation != mColorInterpolation) - { - mColorInterpolation = interpolation; - mColorBufferInvalidated = true; - } -} - -/*! - Sets whether data points that are outside the configured data range (e.g. \ref - QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether - they all have the same color, corresponding to the respective gradient boundary color. - - \image html QCPColorGradient-periodic.png - - As shown in the image above, gradients that have the same start and end color are especially - suitable for a periodic gradient mapping, since they produce smooth color transitions throughout - the color map. A preset that has this property is \ref gpHues. - - In practice, using periodic color gradients makes sense when the data corresponds to a periodic - dimension, such as an angle or a phase. If this is not the case, the color encoding might become - ambiguous, because multiple different data values are shown as the same color. -*/ -void QCPColorGradient::setPeriodic(bool enabled) -{ - mPeriodic = enabled; -} - -/*! \overload - - This method is used to quickly convert a \a data array to colors. The colors will be output in - the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this - function. The data range that shall be used for mapping the data value to the gradient is passed - in \a range. \a logarithmic indicates whether the data values shall be mapped to colors - logarithmically. - - if \a data actually contains 2D-data linearized via [row*columnCount + column], you can - set \a dataIndexFactor to columnCount to convert a column instead of a row of the data - array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data - is addressed data[i*dataIndexFactor]. - - Use the overloaded method to additionally provide alpha map data. - - The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied - with alpha (see QImage::Format_ARGB32_Premultiplied). -*/ -void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) -{ - // If you change something here, make sure to also adapt color() and the other colorize() overload - if (!data) - { - qDebug() << Q_FUNC_INFO << "null pointer given as data"; - return; - } - if (!scanLine) - { - qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; - return; - } - if (mColorBufferInvalidated) - updateColorBuffer(); - - if (!logarithmic) - { - const double posToIndexFactor = (mLevelCount-1)/range.size(); - if (mPeriodic) - { - for (int i=0; i= mLevelCount) - index = mLevelCount-1; - scanLine[i] = mColorBuffer.at(index); - } - } - } else // logarithmic == true - { - if (mPeriodic) - { - for (int i=0; i= mLevelCount) - index = mLevelCount-1; - scanLine[i] = mColorBuffer.at(index); - } - } - } -} - -/*! \overload - - Additionally to the other overload of \ref colorize, this method takes the array \a alpha, which - has the same size and structure as \a data and encodes the alpha information per data point. - - The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied - with alpha (see QImage::Format_ARGB32_Premultiplied). -*/ -void QCPColorGradient::colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) -{ - // If you change something here, make sure to also adapt color() and the other colorize() overload - if (!data) - { - qDebug() << Q_FUNC_INFO << "null pointer given as data"; - return; - } - if (!alpha) - { - qDebug() << Q_FUNC_INFO << "null pointer given as alpha"; - return; - } - if (!scanLine) - { - qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; - return; - } - if (mColorBufferInvalidated) - updateColorBuffer(); - - if (!logarithmic) - { - const double posToIndexFactor = (mLevelCount-1)/range.size(); - if (mPeriodic) - { - for (int i=0; i= mLevelCount) - index = mLevelCount-1; - if (alpha[dataIndexFactor*i] == 255) - { - scanLine[i] = mColorBuffer.at(index); - } else - { - const QRgb rgb = mColorBuffer.at(index); - const float alphaF = alpha[dataIndexFactor*i]/255.0f; - scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); - } - } - } - } else // logarithmic == true - { - if (mPeriodic) - { - for (int i=0; i= mLevelCount) - index = mLevelCount-1; - if (alpha[dataIndexFactor*i] == 255) - { - scanLine[i] = mColorBuffer.at(index); - } else - { - const QRgb rgb = mColorBuffer.at(index); - const float alphaF = alpha[dataIndexFactor*i]/255.0f; - scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); - } - } - } - } -} - -/*! \internal - - This method is used to colorize a single data value given in \a position, to colors. The data - range that shall be used for mapping the data value to the gradient is passed in \a range. \a - logarithmic indicates whether the data value shall be mapped to a color logarithmically. - - If an entire array of data values shall be converted, rather use \ref colorize, for better - performance. - - The returned QRgb has its r, g and b components premultiplied with alpha (see - QImage::Format_ARGB32_Premultiplied). -*/ -QRgb QCPColorGradient::color(double position, const QCPRange &range, bool logarithmic) -{ - // If you change something here, make sure to also adapt ::colorize() - if (mColorBufferInvalidated) - updateColorBuffer(); - int index = 0; - if (!logarithmic) - index = (position-range.lower)*(mLevelCount-1)/range.size(); - else - index = qLn(position/range.lower)/qLn(range.upper/range.lower)*(mLevelCount-1); - if (mPeriodic) - { - index = index % mLevelCount; - if (index < 0) - index += mLevelCount; - } else - { - if (index < 0) - index = 0; - else if (index >= mLevelCount) - index = mLevelCount-1; - } - return mColorBuffer.at(index); -} - -/*! - Clears the current color stops and loads the specified \a preset. A preset consists of predefined - color stops and the corresponding color interpolation method. - - The available presets are: - \image html QCPColorGradient.png -*/ -void QCPColorGradient::loadPreset(GradientPreset preset) -{ - clearColorStops(); - switch (preset) - { - case gpGrayscale: - setColorInterpolation(ciRGB); - setColorStopAt(0, Qt::black); - setColorStopAt(1, Qt::white); - break; - case gpHot: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(50, 0, 0)); - setColorStopAt(0.2, QColor(180, 10, 0)); - setColorStopAt(0.4, QColor(245, 50, 0)); - setColorStopAt(0.6, QColor(255, 150, 10)); - setColorStopAt(0.8, QColor(255, 255, 50)); - setColorStopAt(1, QColor(255, 255, 255)); - break; - case gpCold: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(0, 0, 50)); - setColorStopAt(0.2, QColor(0, 10, 180)); - setColorStopAt(0.4, QColor(0, 50, 245)); - setColorStopAt(0.6, QColor(10, 150, 255)); - setColorStopAt(0.8, QColor(50, 255, 255)); - setColorStopAt(1, QColor(255, 255, 255)); - break; - case gpNight: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(10, 20, 30)); - setColorStopAt(1, QColor(250, 255, 250)); - break; - case gpCandy: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(0, 0, 255)); - setColorStopAt(1, QColor(255, 250, 250)); - break; - case gpGeography: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(70, 170, 210)); - setColorStopAt(0.20, QColor(90, 160, 180)); - setColorStopAt(0.25, QColor(45, 130, 175)); - setColorStopAt(0.30, QColor(100, 140, 125)); - setColorStopAt(0.5, QColor(100, 140, 100)); - setColorStopAt(0.6, QColor(130, 145, 120)); - setColorStopAt(0.7, QColor(140, 130, 120)); - setColorStopAt(0.9, QColor(180, 190, 190)); - setColorStopAt(1, QColor(210, 210, 230)); - break; - case gpIon: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(50, 10, 10)); - setColorStopAt(0.45, QColor(0, 0, 255)); - setColorStopAt(0.8, QColor(0, 255, 255)); - setColorStopAt(1, QColor(0, 255, 0)); - break; - case gpThermal: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(0, 0, 50)); - setColorStopAt(0.15, QColor(20, 0, 120)); - setColorStopAt(0.33, QColor(200, 30, 140)); - setColorStopAt(0.6, QColor(255, 100, 0)); - setColorStopAt(0.85, QColor(255, 255, 40)); - setColorStopAt(1, QColor(255, 255, 255)); - break; - case gpPolar: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(50, 255, 255)); - setColorStopAt(0.18, QColor(10, 70, 255)); - setColorStopAt(0.28, QColor(10, 10, 190)); - setColorStopAt(0.5, QColor(0, 0, 0)); - setColorStopAt(0.72, QColor(190, 10, 10)); - setColorStopAt(0.82, QColor(255, 70, 10)); - setColorStopAt(1, QColor(255, 255, 50)); - break; - case gpSpectrum: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(50, 0, 50)); - setColorStopAt(0.15, QColor(0, 0, 255)); - setColorStopAt(0.35, QColor(0, 255, 255)); - setColorStopAt(0.6, QColor(255, 255, 0)); - setColorStopAt(0.75, QColor(255, 30, 0)); - setColorStopAt(1, QColor(50, 0, 0)); - break; - case gpJet: - setColorInterpolation(ciRGB); - setColorStopAt(0, QColor(0, 0, 100)); - setColorStopAt(0.15, QColor(0, 50, 255)); - setColorStopAt(0.35, QColor(0, 255, 255)); - setColorStopAt(0.65, QColor(255, 255, 0)); - setColorStopAt(0.85, QColor(255, 30, 0)); - setColorStopAt(1, QColor(100, 0, 0)); - break; - case gpHues: - setColorInterpolation(ciHSV); - setColorStopAt(0, QColor(255, 0, 0)); - setColorStopAt(1.0/3.0, QColor(0, 0, 255)); - setColorStopAt(2.0/3.0, QColor(0, 255, 0)); - setColorStopAt(1, QColor(255, 0, 0)); - break; - } -} - -/*! - Clears all color stops. - - \see setColorStops, setColorStopAt -*/ -void QCPColorGradient::clearColorStops() -{ - mColorStops.clear(); - mColorBufferInvalidated = true; -} - -/*! - Returns an inverted gradient. The inverted gradient has all properties as this \ref - QCPColorGradient, but the order of the color stops is inverted. - - \see setColorStops, setColorStopAt -*/ -QCPColorGradient QCPColorGradient::inverted() const -{ - QCPColorGradient result(*this); - result.clearColorStops(); - for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) - result.setColorStopAt(1.0-it.key(), it.value()); - return result; -} - -/*! \internal - - Returns true if the color gradient uses transparency, i.e. if any of the configured color stops - has an alpha value below 255. -*/ -bool QCPColorGradient::stopsUseAlpha() const -{ - for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) - { - if (it.value().alpha() < 255) - return true; - } - return false; -} - -/*! \internal - - Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly - convert positions to colors. This is where the interpolation between color stops is calculated. -*/ -void QCPColorGradient::updateColorBuffer() -{ - if (mColorBuffer.size() != mLevelCount) - mColorBuffer.resize(mLevelCount); - if (mColorStops.size() > 1) - { - double indexToPosFactor = 1.0/(double)(mLevelCount-1); - const bool useAlpha = stopsUseAlpha(); - for (int i=0; i::const_iterator it = mColorStops.lowerBound(position); - if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop - { - mColorBuffer[i] = (it-1).value().rgba(); - } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop - { - mColorBuffer[i] = it.value().rgba(); - } else // position is in between stops (or on an intermediate stop), interpolate color - { - QMap::const_iterator high = it; - QMap::const_iterator low = it-1; - double t = (position-low.key())/(high.key()-low.key()); // interpolation factor 0..1 - switch (mColorInterpolation) - { - case ciRGB: - { - if (useAlpha) - { - const int alpha = (1-t)*low.value().alpha() + t*high.value().alpha(); - const float alphaPremultiplier = alpha/255.0f; // since we use QImage::Format_ARGB32_Premultiplied - mColorBuffer[i] = qRgba(((1-t)*low.value().red() + t*high.value().red())*alphaPremultiplier, - ((1-t)*low.value().green() + t*high.value().green())*alphaPremultiplier, - ((1-t)*low.value().blue() + t*high.value().blue())*alphaPremultiplier, - alpha); - } else - { - mColorBuffer[i] = qRgb(((1-t)*low.value().red() + t*high.value().red()), - ((1-t)*low.value().green() + t*high.value().green()), - ((1-t)*low.value().blue() + t*high.value().blue())); - } - break; - } - case ciHSV: - { - QColor lowHsv = low.value().toHsv(); - QColor highHsv = high.value().toHsv(); - double hue = 0; - double hueDiff = highHsv.hueF()-lowHsv.hueF(); - if (hueDiff > 0.5) - hue = lowHsv.hueF() - t*(1.0-hueDiff); - else if (hueDiff < -0.5) - hue = lowHsv.hueF() + t*(1.0+hueDiff); - else - hue = lowHsv.hueF() + t*hueDiff; - if (hue < 0) hue += 1.0; - else if (hue >= 1.0) hue -= 1.0; - if (useAlpha) - { - const QRgb rgb = QColor::fromHsvF(hue, - (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), - (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); - const float alpha = (1-t)*lowHsv.alphaF() + t*highHsv.alphaF(); - mColorBuffer[i] = qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha); - } - else - { - mColorBuffer[i] = QColor::fromHsvF(hue, - (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), - (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); - } - break; - } - } - } - } - } else if (mColorStops.size() == 1) - { - const QRgb rgb = mColorStops.constBegin().value().rgb(); - const float alpha = mColorStops.constBegin().value().alphaF(); - mColorBuffer.fill(qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha)); - } else // mColorStops is empty, fill color buffer with black - { - mColorBuffer.fill(qRgb(0, 0, 0)); - } - mColorBufferInvalidated = false; -} -/* end of 'src/colorgradient.cpp' */ - - -/* including file 'src/selectiondecorator-bracket.cpp', size 12313 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPSelectionDecoratorBracket -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPSelectionDecoratorBracket - \brief A selection decorator which draws brackets around each selected data segment - - Additionally to the regular highlighting of selected segments via color, fill and scatter style, - this \ref QCPSelectionDecorator subclass draws markers at the begin and end of each selected data - segment of the plottable. - - The shape of the markers can be controlled with \ref setBracketStyle, \ref setBracketWidth and - \ref setBracketHeight. The color/fill can be controlled with \ref setBracketPen and \ref - setBracketBrush. - - To introduce custom bracket styles, it is only necessary to sublcass \ref - QCPSelectionDecoratorBracket and reimplement \ref drawBracket. The rest will be managed by the - base class. -*/ - -/*! - Creates a new QCPSelectionDecoratorBracket instance with default values. -*/ -QCPSelectionDecoratorBracket::QCPSelectionDecoratorBracket() : - mBracketPen(QPen(Qt::black)), - mBracketBrush(Qt::NoBrush), - mBracketWidth(5), - mBracketHeight(50), - mBracketStyle(bsSquareBracket), - mTangentToData(false), - mTangentAverage(2) -{ - -} - -QCPSelectionDecoratorBracket::~QCPSelectionDecoratorBracket() -{ -} - -/*! - Sets the pen that will be used to draw the brackets at the beginning and end of each selected - data segment. -*/ -void QCPSelectionDecoratorBracket::setBracketPen(const QPen &pen) -{ - mBracketPen = pen; -} - -/*! - Sets the brush that will be used to draw the brackets at the beginning and end of each selected - data segment. -*/ -void QCPSelectionDecoratorBracket::setBracketBrush(const QBrush &brush) -{ - mBracketBrush = brush; -} - -/*! - Sets the width of the drawn bracket. The width dimension is always parallel to the key axis of - the data, or the tangent direction of the current data slope, if \ref setTangentToData is - enabled. -*/ -void QCPSelectionDecoratorBracket::setBracketWidth(int width) -{ - mBracketWidth = width; -} - -/*! - Sets the height of the drawn bracket. The height dimension is always perpendicular to the key axis - of the data, or the tangent direction of the current data slope, if \ref setTangentToData is - enabled. -*/ -void QCPSelectionDecoratorBracket::setBracketHeight(int height) -{ - mBracketHeight = height; -} - -/*! - Sets the shape that the bracket/marker will have. - - \see setBracketWidth, setBracketHeight -*/ -void QCPSelectionDecoratorBracket::setBracketStyle(QCPSelectionDecoratorBracket::BracketStyle style) -{ - mBracketStyle = style; -} - -/*! - Sets whether the brackets will be rotated such that they align with the slope of the data at the - position that they appear in. - - For noisy data, it might be more visually appealing to average the slope over multiple data - points. This can be configured via \ref setTangentAverage. -*/ -void QCPSelectionDecoratorBracket::setTangentToData(bool enabled) -{ - mTangentToData = enabled; -} - -/*! - Controls over how many data points the slope shall be averaged, when brackets shall be aligned - with the data (if \ref setTangentToData is true). - - From the position of the bracket, \a pointCount points towards the selected data range will be - taken into account. The smallest value of \a pointCount is 1, which is effectively equivalent to - disabling \ref setTangentToData. -*/ -void QCPSelectionDecoratorBracket::setTangentAverage(int pointCount) -{ - mTangentAverage = pointCount; - if (mTangentAverage < 1) - mTangentAverage = 1; -} - -/*! - Draws the bracket shape with \a painter. The parameter \a direction is either -1 or 1 and - indicates whether the bracket shall point to the left or the right (i.e. is a closing or opening - bracket, respectively). - - The passed \a painter already contains all transformations that are necessary to position and - rotate the bracket appropriately. Painting operations can be performed as if drawing upright - brackets on flat data with horizontal key axis, with (0, 0) being the center of the bracket. - - If you wish to sublcass \ref QCPSelectionDecoratorBracket in order to provide custom bracket - shapes (see \ref QCPSelectionDecoratorBracket::bsUserStyle), this is the method you should - reimplement. -*/ -void QCPSelectionDecoratorBracket::drawBracket(QCPPainter *painter, int direction) const -{ - switch (mBracketStyle) - { - case bsSquareBracket: - { - painter->drawLine(QLineF(mBracketWidth*direction, -mBracketHeight*0.5, 0, -mBracketHeight*0.5)); - painter->drawLine(QLineF(mBracketWidth*direction, mBracketHeight*0.5, 0, mBracketHeight*0.5)); - painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); - break; - } - case bsHalfEllipse: - { - painter->drawArc(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight, -90*16, -180*16*direction); - break; - } - case bsEllipse: - { - painter->drawEllipse(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight); - break; - } - case bsPlus: - { - painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); - painter->drawLine(QLineF(-mBracketWidth*0.5, 0, mBracketWidth*0.5, 0)); - break; - } - default: - { - qDebug() << Q_FUNC_INFO << "unknown/custom bracket style can't be handeld by default implementation:" << static_cast(mBracketStyle); - break; - } - } -} - -/*! - Draws the bracket decoration on the data points at the begin and end of each selected data - segment given in \a seletion. - - It uses the method \ref drawBracket to actually draw the shapes. - - \seebaseclassmethod -*/ -void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSelection selection) -{ - if (!mPlottable || selection.isEmpty()) return; - - if (QCPPlottableInterface1D *interface1d = mPlottable->interface1D()) - { - foreach (const QCPDataRange &dataRange, selection.dataRanges()) - { - // determine position and (if tangent mode is enabled) angle of brackets: - int openBracketDir = (mPlottable->keyAxis() && !mPlottable->keyAxis()->rangeReversed()) ? 1 : -1; - int closeBracketDir = -openBracketDir; - QPointF openBracketPos = getPixelCoordinates(interface1d, dataRange.begin()); - QPointF closeBracketPos = getPixelCoordinates(interface1d, dataRange.end()-1); - double openBracketAngle = 0; - double closeBracketAngle = 0; - if (mTangentToData) - { - openBracketAngle = getTangentAngle(interface1d, dataRange.begin(), openBracketDir); - closeBracketAngle = getTangentAngle(interface1d, dataRange.end()-1, closeBracketDir); - } - // draw opening bracket: - QTransform oldTransform = painter->transform(); - painter->setPen(mBracketPen); - painter->setBrush(mBracketBrush); - painter->translate(openBracketPos); - painter->rotate(openBracketAngle/M_PI*180.0); - drawBracket(painter, openBracketDir); - painter->setTransform(oldTransform); - // draw closing bracket: - painter->setPen(mBracketPen); - painter->setBrush(mBracketBrush); - painter->translate(closeBracketPos); - painter->rotate(closeBracketAngle/M_PI*180.0); - drawBracket(painter, closeBracketDir); - painter->setTransform(oldTransform); - } - } -} - -/*! \internal - - If \ref setTangentToData is enabled, brackets need to be rotated according to the data slope. - This method returns the angle in radians by which a bracket at the given \a dataIndex must be - rotated. - - The parameter \a direction must be set to either -1 or 1, representing whether it is an opening - or closing bracket. Since for slope calculation multiple data points are required, this defines - the direction in which the algorithm walks, starting at \a dataIndex, to average those data - points. (see \ref setTangentToData and \ref setTangentAverage) - - \a interface1d is the interface to the plottable's data which is used to query data coordinates. -*/ -double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const -{ - if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->dataCount()) - return 0; - direction = direction < 0 ? -1 : 1; // enforce direction is either -1 or 1 - - // how many steps we can actually go from index in the given direction without exceeding data bounds: - int averageCount; - if (direction < 0) - averageCount = qMin(mTangentAverage, dataIndex); - else - averageCount = qMin(mTangentAverage, interface1d->dataCount()-1-dataIndex); - qDebug() << averageCount; - // calculate point average of averageCount points: - QVector points(averageCount); - QPointF pointsAverage; - int currentIndex = dataIndex; - for (int i=0; ikeyAxis(); - QCPAxis *valueAxis = mPlottable->valueAxis(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(0, 0); } - - if (keyAxis->orientation() == Qt::Horizontal) - return QPointF(keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))); - else - return QPointF(valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex)), keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex))); -} -/* end of 'src/selectiondecorator-bracket.cpp' */ - - -/* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47584 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAxisRect -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAxisRect - \brief Holds multiple axes and arranges them in a rectangular shape. - - This class represents an axis rect, a rectangular area that is bounded on all sides with an - arbitrary number of axes. - - Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the - layout system allows to have multiple axis rects, e.g. arranged in a grid layout - (QCustomPlot::plotLayout). - - By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be - accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. - If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be - invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref - addAxes. To remove an axis, use \ref removeAxis. - - The axis rect layerable itself only draws a background pixmap or color, if specified (\ref - setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an - explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be - placed on other layers, independently of the axis rect. - - Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref - insetLayout and can be used to have other layout elements (or even other layouts with multiple - elements) hovering inside the axis rect. - - If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The - behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel - is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable - via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are - only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref - QCP::iRangeZoom. - - \image html AxisRectSpacingOverview.png -
Overview of the spacings and paddings that define the geometry of an axis. The dashed - line on the far left indicates the viewport/widget border.
-*/ - -/* start documentation of inline functions */ - -/*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const - - Returns the inset layout of this axis rect. It can be used to place other layout elements (or - even layouts with multiple other elements) inside/on top of an axis rect. - - \see QCPLayoutInset -*/ - -/*! \fn int QCPAxisRect::left() const - - Returns the pixel position of the left border of this axis rect. Margins are not taken into - account here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::right() const - - Returns the pixel position of the right border of this axis rect. Margins are not taken into - account here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::top() const - - Returns the pixel position of the top border of this axis rect. Margins are not taken into - account here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::bottom() const - - Returns the pixel position of the bottom border of this axis rect. Margins are not taken into - account here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::width() const - - Returns the pixel width of this axis rect. Margins are not taken into account here, so the - returned value is with respect to the inner \ref rect. -*/ - -/*! \fn int QCPAxisRect::height() const - - Returns the pixel height of this axis rect. Margins are not taken into account here, so the - returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QSize QCPAxisRect::size() const - - Returns the pixel size of this axis rect. Margins are not taken into account here, so the - returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::topLeft() const - - Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, - so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::topRight() const - - Returns the top right corner of this axis rect in pixels. Margins are not taken into account - here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::bottomLeft() const - - Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account - here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::bottomRight() const - - Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account - here, so the returned value is with respect to the inner \ref rect. -*/ - -/*! \fn QPoint QCPAxisRect::center() const - - Returns the center of this axis rect in pixels. Margins are not taken into account here, so the - returned value is with respect to the inner \ref rect. -*/ - -/* end documentation of inline functions */ - -/*! - Creates a QCPAxisRect instance and sets default values. An axis is added for each of the four - sides, the top and right axes are set invisible initially. -*/ -QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : - QCPLayoutElement(parentPlot), - mBackgroundBrush(Qt::NoBrush), - mBackgroundScaled(true), - mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), - mInsetLayout(new QCPLayoutInset), - mRangeDrag(Qt::Horizontal|Qt::Vertical), - mRangeZoom(Qt::Horizontal|Qt::Vertical), - mRangeZoomFactorHorz(0.85), - mRangeZoomFactorVert(0.85), - mDragging(false), - mIsScaleRight(false) -{ - mInsetLayout->initializeParentPlot(mParentPlot); - mInsetLayout->setParentLayerable(this); - mInsetLayout->setParent(this); - - setMinimumSize(50, 50); - setMinimumMargins(QMargins(15, 15, 15, 15)); - mAxes.insert(QCPAxis::atLeft, QList()); - mAxes.insert(QCPAxis::atRight, QList()); - mAxes.insert(QCPAxis::atTop, QList()); - mAxes.insert(QCPAxis::atBottom, QList()); - - if (setupDefaultAxes) - { - QCPAxis *xAxis = addAxis(QCPAxis::atBottom); - QCPAxis *yAxis = addAxis(QCPAxis::atLeft); - QCPAxis *xAxis2 = addAxis(QCPAxis::atTop); - QCPAxis *yAxis2 = addAxis(QCPAxis::atRight); - setRangeDragAxes(xAxis, yAxis); - setRangeZoomAxes(xAxis, yAxis); - xAxis2->setVisible(false); - yAxis2->setVisible(false); - xAxis->grid()->setVisible(true); - yAxis->grid()->setVisible(true); - xAxis2->grid()->setVisible(false); - yAxis2->grid()->setVisible(false); - xAxis2->grid()->setZeroLinePen(Qt::NoPen); - yAxis2->grid()->setZeroLinePen(Qt::NoPen); - xAxis2->grid()->setVisible(false); - yAxis2->grid()->setVisible(false); - } -} - -QCPAxisRect::~QCPAxisRect() -{ - delete mInsetLayout; - mInsetLayout = 0; - - QList axesList = axes(); - for (int i=0; i ax(mAxes.value(type)); - if (index >= 0 && index < ax.size()) - { - return ax.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; - return 0; - } -} - -/*! - Returns all axes on the axis rect sides specified with \a types. - - \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of - multiple sides. - - \see axis -*/ -QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const -{ - QList result; - if (types.testFlag(QCPAxis::atLeft)) - result << mAxes.value(QCPAxis::atLeft); - if (types.testFlag(QCPAxis::atRight)) - result << mAxes.value(QCPAxis::atRight); - if (types.testFlag(QCPAxis::atTop)) - result << mAxes.value(QCPAxis::atTop); - if (types.testFlag(QCPAxis::atBottom)) - result << mAxes.value(QCPAxis::atBottom); - return result; -} - -/*! \overload - - Returns all axes of this axis rect. -*/ -QList QCPAxisRect::axes() const -{ - QList result; - QHashIterator > it(mAxes); - while (it.hasNext()) - { - it.next(); - result << it.value(); - } - return result; -} - -/*! - Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a - new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to - remove an axis, use \ref removeAxis instead of deleting it manually. - - You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was - previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership - of the axis, so you may not delete it afterwards. Further, the \a axis must have been created - with this axis rect as parent and with the same axis type as specified in \a type. If this is not - the case, a debug output is generated, the axis is not added, and the method returns 0. - - This method can not be used to move \a axis between axis rects. The same \a axis instance must - not be added multiple times to the same or different axis rects. - - If an axis rect side already contains one or more axes, the lower and upper endings of the new - axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref - QCPLineEnding::esHalfBar. - - \see addAxes, setupFullAxesBox -*/ -QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) -{ - QCPAxis *newAxis = axis; - if (!newAxis) - { - newAxis = new QCPAxis(this, type); - } else // user provided existing axis instance, do some sanity checks - { - if (newAxis->axisType() != type) - { - qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter"; - return 0; - } - if (newAxis->axisRect() != this) - { - qDebug() << Q_FUNC_INFO << "passed axis doesn't have this axis rect as parent axis rect"; - return 0; - } - if (axes().contains(newAxis)) - { - qDebug() << Q_FUNC_INFO << "passed axis is already owned by this axis rect"; - return 0; - } - } - if (mAxes[type].size() > 0) // multiple axes on one side, add half-bar axis ending to additional axes with offset - { - bool invert = (type == QCPAxis::atRight) || (type == QCPAxis::atBottom); - newAxis->setLowerEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, !invert)); - newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); - } - mAxes[type].append(newAxis); - - // reset convenience axis pointers on parent QCustomPlot if they are unset: - if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) - { - switch (type) - { - case QCPAxis::atBottom: { if (!mParentPlot->xAxis) mParentPlot->xAxis = newAxis; break; } - case QCPAxis::atLeft: { if (!mParentPlot->yAxis) mParentPlot->yAxis = newAxis; break; } - case QCPAxis::atTop: { if (!mParentPlot->xAxis2) mParentPlot->xAxis2 = newAxis; break; } - case QCPAxis::atRight: { if (!mParentPlot->yAxis2) mParentPlot->yAxis2 = newAxis; break; } - } - } - - return newAxis; -} - -/*! - Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an - or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. - - Returns a list of the added axes. - - \see addAxis, setupFullAxesBox -*/ -QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) -{ - QList result; - if (types.testFlag(QCPAxis::atLeft)) - result << addAxis(QCPAxis::atLeft); - if (types.testFlag(QCPAxis::atRight)) - result << addAxis(QCPAxis::atRight); - if (types.testFlag(QCPAxis::atTop)) - result << addAxis(QCPAxis::atTop); - if (types.testFlag(QCPAxis::atBottom)) - result << addAxis(QCPAxis::atBottom); - return result; -} - -/*! - Removes the specified \a axis from the axis rect and deletes it. - - Returns true on success, i.e. if \a axis was a valid axis in this axis rect. - - \see addAxis -*/ -bool QCPAxisRect::removeAxis(QCPAxis *axis) -{ - // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers: - QHashIterator > it(mAxes); - while (it.hasNext()) - { - it.next(); - if (it.value().contains(axis)) - { - if (it.value().first() == axis && it.value().size() > 1) // if removing first axis, transfer axis offset to the new first axis (which at this point is the second axis, if it exists) - it.value()[1]->setOffset(axis->offset()); - mAxes[it.key()].removeOne(axis); - if (qobject_cast(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot) - parentPlot()->axisRemoved(axis); - delete axis; - return true; - } - } - qDebug() << Q_FUNC_INFO << "Axis isn't in axis rect:" << reinterpret_cast(axis); - return false; -} - -/*! - Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. - - All axes of this axis rect will have their range zoomed accordingly. If you only wish to zoom - specific axes, use the overloaded version of this method. - - \see QCustomPlot::setSelectionRectMode -*/ -void QCPAxisRect::zoom(const QRectF &pixelRect) -{ - zoom(pixelRect, axes()); -} - -/*! \overload - - Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. - - Only the axes passed in \a affectedAxes will have their ranges zoomed accordingly. - - \see QCustomPlot::setSelectionRectMode -*/ -void QCPAxisRect::zoom(const QRectF &pixelRect, const QList &affectedAxes) -{ - foreach (QCPAxis *axis, affectedAxes) - { - if (!axis) - { - qDebug() << Q_FUNC_INFO << "a passed axis was zero"; - continue; - } - QCPRange pixelRange; - if (axis->orientation() == Qt::Horizontal) - pixelRange = QCPRange(pixelRect.left(), pixelRect.right()); - else - pixelRange = QCPRange(pixelRect.top(), pixelRect.bottom()); - axis->setRange(axis->pixelToCoord(pixelRange.lower), axis->pixelToCoord(pixelRange.upper)); - } -} - -/*! - Convenience function to create an axis on each side that doesn't have any axes yet and set their - visibility to true. Further, the top/right axes are assigned the following properties of the - bottom/left axes: - - \li range (\ref QCPAxis::setRange) - \li range reversed (\ref QCPAxis::setRangeReversed) - \li scale type (\ref QCPAxis::setScaleType) - \li tick visibility (\ref QCPAxis::setTicks) - \li number format (\ref QCPAxis::setNumberFormat) - \li number precision (\ref QCPAxis::setNumberPrecision) - \li tick count of ticker (\ref QCPAxisTicker::setTickCount) - \li tick origin of ticker (\ref QCPAxisTicker::setTickOrigin) - - Tick label visibility (\ref QCPAxis::setTickLabels) of the right and top axes are set to false. - - If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom - and left axes are connected to the \ref QCPAxis::setRange slots of the top and right axes. -*/ -void QCPAxisRect::setupFullAxesBox(bool connectRanges) -{ - QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; - if (axisCount(QCPAxis::atBottom) == 0) - xAxis = addAxis(QCPAxis::atBottom); - else - xAxis = axis(QCPAxis::atBottom); - - if (axisCount(QCPAxis::atLeft) == 0) - yAxis = addAxis(QCPAxis::atLeft); - else - yAxis = axis(QCPAxis::atLeft); - - if (axisCount(QCPAxis::atTop) == 0) - xAxis2 = addAxis(QCPAxis::atTop); - else - xAxis2 = axis(QCPAxis::atTop); - - if (axisCount(QCPAxis::atRight) == 0) - yAxis2 = addAxis(QCPAxis::atRight); - else - yAxis2 = axis(QCPAxis::atRight); - - xAxis->setVisible(true); - yAxis->setVisible(true); - xAxis2->setVisible(true); - yAxis2->setVisible(true); - xAxis2->setTickLabels(false); - yAxis2->setTickLabels(false); - - xAxis2->setRange(xAxis->range()); - xAxis2->setRangeReversed(xAxis->rangeReversed()); - xAxis2->setScaleType(xAxis->scaleType()); - xAxis2->setTicks(xAxis->ticks()); - xAxis2->setNumberFormat(xAxis->numberFormat()); - xAxis2->setNumberPrecision(xAxis->numberPrecision()); - xAxis2->ticker()->setTickCount(xAxis->ticker()->tickCount()); - xAxis2->ticker()->setTickOrigin(xAxis->ticker()->tickOrigin()); - - yAxis2->setRange(yAxis->range()); - yAxis2->setRangeReversed(yAxis->rangeReversed()); - yAxis2->setScaleType(yAxis->scaleType()); - yAxis2->setTicks(yAxis->ticks()); - yAxis2->setNumberFormat(yAxis->numberFormat()); - yAxis2->setNumberPrecision(yAxis->numberPrecision()); - yAxis2->ticker()->setTickCount(yAxis->ticker()->tickCount()); - yAxis2->ticker()->setTickOrigin(yAxis->ticker()->tickOrigin()); - - if (connectRanges) - { - connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); - connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); - } -} - -/*! - Returns a list of all the plottables that are associated with this axis rect. - - A plottable is considered associated with an axis rect if its key or value axis (or both) is in - this axis rect. - - \see graphs, items -*/ -QList QCPAxisRect::plottables() const -{ - // Note: don't append all QCPAxis::plottables() into a list, because we might get duplicate entries - QList result; - for (int i=0; imPlottables.size(); ++i) - { - if (mParentPlot->mPlottables.at(i)->keyAxis()->axisRect() == this || mParentPlot->mPlottables.at(i)->valueAxis()->axisRect() == this) - result.append(mParentPlot->mPlottables.at(i)); - } - return result; -} - -/*! - Returns a list of all the graphs that are associated with this axis rect. - - A graph is considered associated with an axis rect if its key or value axis (or both) is in - this axis rect. - - \see plottables, items -*/ -QList QCPAxisRect::graphs() const -{ - // Note: don't append all QCPAxis::graphs() into a list, because we might get duplicate entries - QList result; - for (int i=0; imGraphs.size(); ++i) - { - if (mParentPlot->mGraphs.at(i)->keyAxis()->axisRect() == this || mParentPlot->mGraphs.at(i)->valueAxis()->axisRect() == this) - result.append(mParentPlot->mGraphs.at(i)); - } - return result; -} - -/*! - Returns a list of all the items that are associated with this axis rect. - - An item is considered associated with an axis rect if any of its positions has key or value axis - set to an axis that is in this axis rect, or if any of its positions has \ref - QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref - QCPAbstractItem::setClipAxisRect) is set to this axis rect. - - \see plottables, graphs -*/ -QList QCPAxisRect::items() const -{ - // Note: don't just append all QCPAxis::items() into a list, because we might get duplicate entries - // and miss those items that have this axis rect as clipAxisRect. - QList result; - for (int itemId=0; itemIdmItems.size(); ++itemId) - { - if (mParentPlot->mItems.at(itemId)->clipAxisRect() == this) - { - result.append(mParentPlot->mItems.at(itemId)); - continue; - } - QList positions = mParentPlot->mItems.at(itemId)->positions(); - for (int posId=0; posIdaxisRect() == this || - positions.at(posId)->keyAxis()->axisRect() == this || - positions.at(posId)->valueAxis()->axisRect() == this) - { - result.append(mParentPlot->mItems.at(itemId)); - break; - } - } - } - return result; -} - -/*! - This method is called automatically upon replot and doesn't need to be called by users of - QCPAxisRect. - - Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), - and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its - QCPInsetLayout::update function. - - \seebaseclassmethod -*/ -void QCPAxisRect::update(UpdatePhase phase) -{ - QCPLayoutElement::update(phase); - - switch (phase) - { - case upPreparation: - { - QList allAxes = axes(); - for (int i=0; isetupTickVectors(); - break; - } - case upLayout: - { - mInsetLayout->setOuterRect(rect()); - break; - } - default: break; - } - - // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): - mInsetLayout->update(phase); -} - -/* inherits documentation from base class */ -QList QCPAxisRect::elements(bool recursive) const -{ - QList result; - if (mInsetLayout) - { - result << mInsetLayout; - if (recursive) - result << mInsetLayout->elements(recursive); - } - return result; -} - -/* inherits documentation from base class */ -void QCPAxisRect::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - painter->setAntialiasing(false); -} - -/* inherits documentation from base class */ -void QCPAxisRect::draw(QCPPainter *painter) -{ - drawBackground(painter); -} - -/*! - Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the - axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect - backgrounds are usually drawn below everything else. - - For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be - enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio - is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, - consider using the overloaded version of this function. - - Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref - setBackground(const QBrush &brush). - - \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) -*/ -void QCPAxisRect::setBackground(const QPixmap &pm) -{ - mBackgroundPixmap = pm; - mScaledBackgroundPixmap = QPixmap(); -} - -/*! \overload - - Sets \a brush as the background brush. The axis rect background will be filled with this brush. - Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds - are usually drawn below everything else. - - The brush will be drawn before (under) any background pixmap, which may be specified with \ref - setBackground(const QPixmap &pm). - - To disable drawing of a background brush, set \a brush to Qt::NoBrush. - - \see setBackground(const QPixmap &pm) -*/ -void QCPAxisRect::setBackground(const QBrush &brush) -{ - mBackgroundBrush = brush; -} - -/*! \overload - - Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it - shall be scaled in one call. - - \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode -*/ -void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) -{ - mBackgroundPixmap = pm; - mScaledBackgroundPixmap = QPixmap(); - mBackgroundScaled = scaled; - mBackgroundScaledMode = mode; -} - -/*! - Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled - is set to true, you may control whether and how the aspect ratio of the original pixmap is - preserved with \ref setBackgroundScaledMode. - - Note that the scaled version of the original pixmap is buffered, so there is no performance - penalty on replots. (Except when the axis rect dimensions are changed continuously.) - - \see setBackground, setBackgroundScaledMode -*/ -void QCPAxisRect::setBackgroundScaled(bool scaled) -{ - mBackgroundScaled = scaled; -} - -/*! - If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to - define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. - \see setBackground, setBackgroundScaled -*/ -void QCPAxisRect::setBackgroundScaledMode(Qt::AspectRatioMode mode) -{ - mBackgroundScaledMode = mode; -} - -/*! - Returns the range drag axis of the \a orientation provided. If multiple axes were set, returns - the first one (use \ref rangeDragAxes to retrieve a list with all set axes). - - \see setRangeDragAxes -*/ -QCPAxis *QCPAxisRect::rangeDragAxis(Qt::Orientation orientation) -{ - if (orientation == Qt::Horizontal) - return mRangeDragHorzAxis.isEmpty() ? 0 : mRangeDragHorzAxis.first().data(); - else - return mRangeDragVertAxis.isEmpty() ? 0 : mRangeDragVertAxis.first().data(); -} - -/*! - Returns the range zoom axis of the \a orientation provided. If multiple axes were set, returns - the first one (use \ref rangeZoomAxes to retrieve a list with all set axes). - - \see setRangeZoomAxes -*/ -QCPAxis *QCPAxisRect::rangeZoomAxis(Qt::Orientation orientation) -{ - if (orientation == Qt::Horizontal) - return mRangeZoomHorzAxis.isEmpty() ? 0 : mRangeZoomHorzAxis.first().data(); - else - return mRangeZoomVertAxis.isEmpty() ? 0 : mRangeZoomVertAxis.first().data(); -} - -/*! - Returns all range drag axes of the \a orientation provided. - - \see rangeZoomAxis, setRangeZoomAxes -*/ -QList QCPAxisRect::rangeDragAxes(Qt::Orientation orientation) -{ - QList result; - if (orientation == Qt::Horizontal) - { - for (int i=0; i QCPAxisRect::rangeZoomAxes(Qt::Orientation orientation) -{ - QList result; - if (orientation == Qt::Horizontal) - { - for (int i=0; iQt::Horizontal | - Qt::Vertical as \a orientations. - - In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions - contains \ref QCP::iRangeDrag to enable the range dragging interaction. - - \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag -*/ -void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) -{ - mRangeDrag = orientations; -} - -/*! - Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation - corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, - QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical - axis is the left axis (yAxis). - - To disable range zooming entirely, pass 0 as \a orientations or remove \ref QCP::iRangeZoom from \ref - QCustomPlot::setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | - Qt::Vertical as \a orientations. - - In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions - contains \ref QCP::iRangeZoom to enable the range zooming interaction. - - \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag -*/ -void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) -{ - mRangeZoom = orientations; -} - -/*! \overload - - Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on - the QCustomPlot widget. Pass 0 if no axis shall be dragged in the respective orientation. - - Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall - react to dragging interactions. - - \see setRangeZoomAxes -*/ -void QCPAxisRect::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) -{ - QList horz, vert; - if (horizontal) - horz.append(horizontal); - if (vertical) - vert.append(vertical); - setRangeDragAxes(horz, vert); -} - -/*! \overload - - This method allows to set up multiple axes to react to horizontal and vertical dragging. The drag - orientation that the respective axis will react to is deduced from its orientation (\ref - QCPAxis::orientation). - - In the unusual case that you wish to e.g. drag a vertically oriented axis with a horizontal drag - motion, use the overload taking two separate lists for horizontal and vertical dragging. -*/ -void QCPAxisRect::setRangeDragAxes(QList axes) -{ - QList horz, vert; - foreach (QCPAxis *ax, axes) - { - if (ax->orientation() == Qt::Horizontal) - horz.append(ax); - else - vert.append(ax); - } - setRangeDragAxes(horz, vert); -} - -/*! \overload - - This method allows to set multiple axes up to react to horizontal and vertical dragging, and - define specifically which axis reacts to which drag orientation (irrespective of the axis - orientation). -*/ -void QCPAxisRect::setRangeDragAxes(QList horizontal, QList vertical) -{ - mRangeDragHorzAxis.clear(); - foreach (QCPAxis *ax, horizontal) - { - QPointer axPointer(ax); - if (!axPointer.isNull()) - mRangeDragHorzAxis.append(axPointer); - else - qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); - } - mRangeDragVertAxis.clear(); - foreach (QCPAxis *ax, vertical) - { - QPointer axPointer(ax); - if (!axPointer.isNull()) - mRangeDragVertAxis.append(axPointer); - else - qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); - } -} - -/*! - Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on - the QCustomPlot widget. Pass 0 if no axis shall be zoomed in the respective orientation. - - The two axes can be zoomed with different strengths, when different factors are passed to \ref - setRangeZoomFactor(double horizontalFactor, double verticalFactor). - - Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall - react to zooming interactions. - - \see setRangeDragAxes -*/ -void QCPAxisRect::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) -{ - QList horz, vert; - if (horizontal) - horz.append(horizontal); - if (vertical) - vert.append(vertical); - setRangeZoomAxes(horz, vert); -} - -/*! \overload - - This method allows to set up multiple axes to react to horizontal and vertical range zooming. The - zoom orientation that the respective axis will react to is deduced from its orientation (\ref - QCPAxis::orientation). - - In the unusual case that you wish to e.g. zoom a vertically oriented axis with a horizontal zoom - interaction, use the overload taking two separate lists for horizontal and vertical zooming. -*/ -void QCPAxisRect::setRangeZoomAxes(QList axes) -{ - QList horz, vert; - foreach (QCPAxis *ax, axes) - { - if (ax->orientation() == Qt::Horizontal) - horz.append(ax); - else - vert.append(ax); - } - setRangeZoomAxes(horz, vert); -} - -/*! \overload - - This method allows to set multiple axes up to react to horizontal and vertical zooming, and - define specifically which axis reacts to which zoom orientation (irrespective of the axis - orientation). -*/ -void QCPAxisRect::setRangeZoomAxes(QList horizontal, QList vertical) -{ - mRangeZoomHorzAxis.clear(); - foreach (QCPAxis *ax, horizontal) - { - QPointer axPointer(ax); - if (!axPointer.isNull()) - mRangeZoomHorzAxis.append(axPointer); - else - qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); - } - mRangeZoomVertAxis.clear(); - foreach (QCPAxis *ax, vertical) - { - QPointer axPointer(ax); - if (!axPointer.isNull()) - mRangeZoomVertAxis.append(axPointer); - else - qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); - } -} - -/*! - Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with - \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to - let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal - and which is vertical, can be set with \ref setRangeZoomAxes. - - When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) - will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the - same scrolling direction will zoom out. -*/ -void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFactor) -{ - mRangeZoomFactorHorz = horizontalFactor; - mRangeZoomFactorVert = verticalFactor; -} - -/*! \overload - - Sets both the horizontal and vertical zoom \a factor. -*/ -void QCPAxisRect::setRangeZoomFactor(double factor) -{ - mRangeZoomFactorHorz = factor; - mRangeZoomFactorVert = factor; -} - -/*! \internal - - Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a - pixmap. - - If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an - according filling inside the axis rect with the provided \a painter. - - Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version - depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside - the axis rect with the provided \a painter. The scaled version is buffered in - mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when - the axis rect has changed in a way that requires a rescale of the background pixmap (this is - dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was - set. - - \see setBackground, setBackgroundScaled, setBackgroundScaledMode -*/ -void QCPAxisRect::drawBackground(QCPPainter *painter) -{ - // draw background fill: - if (mBackgroundBrush != Qt::NoBrush) - painter->fillRect(mRect, mBackgroundBrush); - - // draw background pixmap (on top of fill, if brush specified): - if (!mBackgroundPixmap.isNull()) - { - if (mBackgroundScaled) - { - // check whether mScaledBackground needs to be updated: - QSize scaledSize(mBackgroundPixmap.size()); - scaledSize.scale(mRect.size(), mBackgroundScaledMode); - if (mScaledBackgroundPixmap.size() != scaledSize) - mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); - painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); - } else - { - painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); - } - } -} - -/*! \internal - - This function makes sure multiple axes on the side specified with \a type don't collide, but are - distributed according to their respective space requirement (QCPAxis::calculateMargin). - - It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the - one with index zero. - - This function is called by \ref calculateAutoMargin. -*/ -void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) -{ - const QList axesList = mAxes.value(type); - if (axesList.isEmpty()) - return; - - bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false - for (int i=1; ioffset() + axesList.at(i-1)->calculateMargin(); - if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible) - { - if (!isFirstVisible) - offset += axesList.at(i)->tickLengthIn(); - isFirstVisible = false; - } - axesList.at(i)->setOffset(offset); - } -} - -/* inherits documentation from base class */ -int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) -{ - if (!mAutoMargins.testFlag(side)) - qDebug() << Q_FUNC_INFO << "Called with side that isn't specified as auto margin"; - - updateAxesOffset(QCPAxis::marginSideToAxisType(side)); - - // note: only need to look at the last (outer most) axis to determine the total margin, due to updateAxisOffset call - const QList axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); - if (axesList.size() > 0) - return axesList.last()->offset() + axesList.last()->calculateMargin(); - else - return 0; -} - -/*! \internal - - Reacts to a change in layout to potentially set the convenience axis pointers \ref - QCustomPlot::xAxis, \ref QCustomPlot::yAxis, etc. of the parent QCustomPlot to the respective - axes of this axis rect. This is only done if the respective convenience pointer is currently zero - and if there is no QCPAxisRect at position (0, 0) of the plot layout. - - This automation makes it simpler to replace the main axis rect with a newly created one, without - the need to manually reset the convenience pointers. -*/ -void QCPAxisRect::layoutChanged() -{ - if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) - { - if (axisCount(QCPAxis::atBottom) > 0 && !mParentPlot->xAxis) - mParentPlot->xAxis = axis(QCPAxis::atBottom); - if (axisCount(QCPAxis::atLeft) > 0 && !mParentPlot->yAxis) - mParentPlot->yAxis = axis(QCPAxis::atLeft); - if (axisCount(QCPAxis::atTop) > 0 && !mParentPlot->xAxis2) - mParentPlot->xAxis2 = axis(QCPAxis::atTop); - if (axisCount(QCPAxis::atRight) > 0 && !mParentPlot->yAxis2) - mParentPlot->yAxis2 = axis(QCPAxis::atRight); - } -} - -/*! \internal - - Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is - pressed, the range dragging interaction is initialized (the actual range manipulation happens in - the \ref mouseMoveEvent). - - The mDragging flag is set to true and some anchor points are set that are needed to determine the - distance the mouse was dragged in the mouse move/release events later. - - \see mouseMoveEvent, mouseReleaseEvent -*/ -void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - if (event->buttons() & Qt::LeftButton) - { - mDragging = true; - // initialize antialiasing backup in case we start dragging: - if (mParentPlot->noAntialiasingOnDrag()) - { - mAADragBackup = mParentPlot->antialiasedElements(); - mNotAADragBackup = mParentPlot->notAntialiasedElements(); - } - // Mouse range dragging interaction: - if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) - { - mDragStartHorzRange.clear(); - for (int i=0; irange()); - mDragStartVertRange.clear(); - for (int i=0; irange()); - } - } -} - -/*! \internal - - Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a - preceding \ref mousePressEvent, the range is moved accordingly. - - \see mousePressEvent, mouseReleaseEvent -*/ -void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(startPos) - // Mouse range dragging interaction: - if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) - { - - if (mRangeDrag.testFlag(Qt::Horizontal)) - { - for (int i=0; i= mDragStartHorzRange.size()) - break; - - //< Drag - if (ax->mScaleType == QCPAxis::stLinear) - { - double diff = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x()); - ax->setRange(mDragStartHorzRange.at(i).lower+diff, mDragStartHorzRange.at(i).upper+diff); - - if(diff != 0) - { - mIsDragMove = true; - } - } - //< Scale - else if (ax->mScaleType == QCPAxis::stLogarithmic) - { - double diff = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x()); - ax->setRange(mDragStartHorzRange.at(i).lower*diff, mDragStartHorzRange.at(i).upper*diff); - if(diff != 0) - { - mIsDragMove = true; - } - } - } - } - - if (mRangeDrag.testFlag(Qt::Vertical)) - { - for (int i=0; i= mDragStartVertRange.size()) - break; - if (ax->mScaleType == QCPAxis::stLinear) - { - double diff = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y()); - ax->setRange(mDragStartVertRange.at(i).lower+diff, mDragStartVertRange.at(i).upper+diff); - } else if (ax->mScaleType == QCPAxis::stLogarithmic) - { - double diff = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y()); - ax->setRange(mDragStartVertRange.at(i).lower*diff, mDragStartVertRange.at(i).upper*diff); - } - } - } - - if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot - { - if (mParentPlot->noAntialiasingOnDrag()) - mParentPlot->setNotAntialiasedElements(QCP::aeAll); - mParentPlot->replot(QCustomPlot::rpQueuedReplot); - } - - } -} - -/* inherits documentation from base class */ -void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - Q_UNUSED(event) - Q_UNUSED(startPos) - - //< Note: update His Date - - if(mIsDragMove) - { - emit rangeDraged(); - mIsDragMove = false; - } - - mDragging = false; - if (mParentPlot->noAntialiasingOnDrag()) - { - mParentPlot->setAntialiasedElements(mAADragBackup); - mParentPlot->setNotAntialiasedElements(mNotAADragBackup); - } -} - -/*! \internal - - Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the - ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of - the scaling operation is the current cursor position inside the axis rect. The scaling factor is - dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural - zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. - - Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse - wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be - multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as - exponent of the range zoom factor. This takes care of the wheel direction automatically, by - inverting the factor, when the wheel step is negative (f^-1 = 1/f). -*/ -void QCPAxisRect::wheelEvent(QWheelEvent *event) -{ - // Mouse range zooming interaction: - if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) - { - if (mRangeZoom != 0) - { - double factor; - double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually - if (mRangeZoom.testFlag(Qt::Horizontal)) - { - factor = qPow(mRangeZoomFactorHorz, wheelSteps); - for (int i=0; iscaleRange(factor,mRangeZoomHorzAxis.at(i)->range().upper); - } - else - { - mRangeZoomHorzAxis.at(i)->scaleRange(factor, mRangeZoomHorzAxis.at(i)->pixelToCoord(event->pos().x())); - } - emit rangeScaled(); - } - } - } - if (mRangeZoom.testFlag(Qt::Vertical)) - { - factor = qPow(mRangeZoomFactorVert, wheelSteps); - for (int i=0; iscaleRange(factor, mRangeZoomVertAxis.at(i)->pixelToCoord(event->pos().y())); - } - } - mParentPlot->replot(); - } - } -} -/* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ - - -/* including file 'src/layoutelements/layoutelement-legend.cpp', size 31097 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractLegendItem -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractLegendItem - \brief The abstract base class for all entries in a QCPLegend. - - It defines a very basic interface for entries in a QCPLegend. For representing plottables in the - legend, the subclass \ref QCPPlottableLegendItem is more suitable. - - Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry - that's not even associated with a plottable). - - You must implement the following pure virtual functions: - \li \ref draw (from QCPLayerable) - - You inherit the following members you may use: - - - - - - - - -
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
-*/ - -/* start of documentation of signals */ - -/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) - - This signal is emitted when the selection state of this legend item has changed, either by user - interaction or by a direct call to \ref setSelected. -*/ - -/* end of documentation of signals */ - -/*! - Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not - cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. -*/ -QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : - QCPLayoutElement(parent->parentPlot()), - mParentLegend(parent), - mFont(parent->font()), - mTextColor(parent->textColor()), - mSelectedFont(parent->selectedFont()), - mSelectedTextColor(parent->selectedTextColor()), - mSelectable(true), - mSelected(false) -{ - setLayer(QLatin1String("legend")); - setMargins(QMargins(0, 0, 0, 0)); -} - -/*! - Sets the default font of this specific legend item to \a font. - - \see setTextColor, QCPLegend::setFont -*/ -void QCPAbstractLegendItem::setFont(const QFont &font) -{ - mFont = font; -} - -/*! - Sets the default text color of this specific legend item to \a color. - - \see setFont, QCPLegend::setTextColor -*/ -void QCPAbstractLegendItem::setTextColor(const QColor &color) -{ - mTextColor = color; -} - -/*! - When this legend item is selected, \a font is used to draw generic text, instead of the normal - font set with \ref setFont. - - \see setFont, QCPLegend::setSelectedFont -*/ -void QCPAbstractLegendItem::setSelectedFont(const QFont &font) -{ - mSelectedFont = font; -} - -/*! - When this legend item is selected, \a color is used to draw generic text, instead of the normal - color set with \ref setTextColor. - - \see setTextColor, QCPLegend::setSelectedTextColor -*/ -void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) -{ - mSelectedTextColor = color; -} - -/*! - Sets whether this specific legend item is selectable. - - \see setSelectedParts, QCustomPlot::setInteractions -*/ -void QCPAbstractLegendItem::setSelectable(bool selectable) -{ - if (mSelectable != selectable) - { - mSelectable = selectable; - emit selectableChanged(mSelectable); - } -} - -/*! - Sets whether this specific legend item is selected. - - It is possible to set the selection state of this item by calling this function directly, even if - setSelectable is set to false. - - \see setSelectableParts, QCustomPlot::setInteractions -*/ -void QCPAbstractLegendItem::setSelected(bool selected) -{ - if (mSelected != selected) - { - mSelected = selected; - emit selectionChanged(mSelected); - } -} - -/* inherits documentation from base class */ -double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (!mParentPlot) return -1; - if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) - return -1; - - if (mRect.contains(pos.toPoint())) - return mParentPlot->selectionTolerance()*0.99; - else - return -1; -} - -/* inherits documentation from base class */ -void QCPAbstractLegendItem::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeLegendItems); -} - -/* inherits documentation from base class */ -QRect QCPAbstractLegendItem::clipRect() const -{ - return mOuterRect; -} - -/* inherits documentation from base class */ -void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - Q_UNUSED(details) - if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) - { - bool selBefore = mSelected; - setSelected(additive ? !mSelected : true); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) -{ - if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) - { - bool selBefore = mSelected; - setSelected(false); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPlottableLegendItem -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPlottableLegendItem - \brief A legend item representing a plottable with an icon and the plottable name. - - This is the standard legend item for plottables. It displays an icon of the plottable next to the - plottable name. The icon is drawn by the respective plottable itself (\ref - QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. - For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the - middle. - - Legend items of this type are always associated with one plottable (retrievable via the - plottable() function and settable with the constructor). You may change the font of the plottable - name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref - QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. - - The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend - creates/removes legend items of this type. - - Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of - QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout - interface, QCPLegend has specialized functions for handling legend items conveniently, see the - documentation of \ref QCPLegend. -*/ - -/*! - Creates a new legend item associated with \a plottable. - - Once it's created, it can be added to the legend via \ref QCPLegend::addItem. - - A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref - QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. -*/ -QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : - QCPAbstractLegendItem(parent), - mPlottable(plottable) -{ - setAntialiased(false); -} - -/*! \internal - - Returns the pen that shall be used to draw the icon border, taking into account the selection - state of this item. -*/ -QPen QCPPlottableLegendItem::getIconBorderPen() const -{ - return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); -} - -/*! \internal - - Returns the text color that shall be used to draw text, taking into account the selection state - of this item. -*/ -QColor QCPPlottableLegendItem::getTextColor() const -{ - return mSelected ? mSelectedTextColor : mTextColor; -} - -/*! \internal - - Returns the font that shall be used to draw text, taking into account the selection state of this - item. -*/ -QFont QCPPlottableLegendItem::getFont() const -{ - return mSelected ? mSelectedFont : mFont; -} - -/*! \internal - - Draws the item with \a painter. The size and position of the drawn legend item is defined by the - parent layout (typically a \ref QCPLegend) and the \ref minimumOuterSizeHint and \ref - maximumOuterSizeHint of this legend item. -*/ -void QCPPlottableLegendItem::draw(QCPPainter *painter) -{ - if (!mPlottable) return; - painter->setFont(getFont()); - painter->setPen(QPen(getTextColor())); - QSizeF iconSize = mParentLegend->iconSize(); - QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); - QRectF iconRect(mRect.topLeft(), iconSize); - int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops - painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->desc()); - // draw icon: - painter->save(); - painter->setClipRect(iconRect, Qt::IntersectClip); - mPlottable->drawLegendIcon(painter, iconRect); - painter->restore(); - // draw icon border: - if (getIconBorderPen().style() != Qt::NoPen) - { - painter->setPen(getIconBorderPen()); - painter->setBrush(Qt::NoBrush); - int halfPen = qCeil(painter->pen().widthF()*0.5)+1; - painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped - painter->drawRect(iconRect); - } -} - -/*! \internal - - Calculates and returns the size of this item. This includes the icon, the text and the padding in - between. - - \seebaseclassmethod -*/ -QSize QCPPlottableLegendItem::minimumOuterSizeHint() const -{ - if (!mPlottable) return QSize(); - QSize result(0, 0); - QRect textRect; - QFontMetrics fontMetrics(getFont()); - QSize iconSize = mParentLegend->iconSize(); - textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); - result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); - result.setHeight(qMax(textRect.height(), iconSize.height())); - result.rwidth() += mMargins.left()+mMargins.right(); - result.rheight() += mMargins.top()+mMargins.bottom(); - return result; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPLegend -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPLegend - \brief Manages a legend inside a QCustomPlot. - - A legend is a small box somewhere in the plot which lists plottables with their name and icon. - - A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the - plottable, for which a legend item shall be created. In the case of the main legend (\ref - QCustomPlot::legend), simply adding plottables to the plot while \ref - QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding - legend items. The legend item associated with a certain plottable can be removed with \ref - QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and - manipulate legend items directly: \ref item, \ref itemWithPlottable, \ref itemCount, \ref - addItem, \ref removeItem, etc. - - Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref - QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement - "QCPLayoutElements" which are placed in the grid layout of the legend. \ref QCPLegend only adds - an interface specialized for handling child elements of type \ref QCPAbstractLegendItem, as - mentioned above. In principle, any other layout elements may also be added to a legend via the - normal \ref QCPLayoutGrid interface. See the special page about \link thelayoutsystem The Layout - System\endlink for examples on how to add other elements to the legend and move it outside the axis - rect. - - Use the methods \ref setFillOrder and \ref setWrap inherited from \ref QCPLayoutGrid to control - in which order (column first or row first) the legend is filled up when calling \ref addItem, and - at which column or row wrapping occurs. - - By default, every QCustomPlot has one legend (\ref QCustomPlot::legend) which is placed in the - inset layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another - position inside the axis rect, use the methods of the \ref QCPLayoutInset. To move the legend - outside of the axis rect, place it anywhere else with the \ref QCPLayout/\ref QCPLayoutElement - interface. -*/ - -/* start of documentation of signals */ - -/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); - - This signal is emitted when the selection state of this legend has changed. - - \see setSelectedParts, setSelectableParts -*/ - -/* end of documentation of signals */ - -/*! - Constructs a new QCPLegend instance with default values. - - Note that by default, QCustomPlot already contains a legend ready to be used as \ref - QCustomPlot::legend -*/ -QCPLegend::QCPLegend() -{ - setFillOrder(QCPLayoutGrid::foRowsFirst); - setWrap(0); - - setRowSpacing(3); - setColumnSpacing(8); - setMargins(QMargins(7, 5, 7, 4)); - setAntialiased(false); - setIconSize(32, 18); - - setIconTextPadding(7); - - setSelectableParts(spLegendBox | spItems); - setSelectedParts(spNone); - - setBorderPen(QPen(Qt::black, 0)); - setSelectedBorderPen(QPen(Qt::blue, 2)); - setIconBorderPen(Qt::NoPen); - setSelectedIconBorderPen(QPen(Qt::blue, 2)); - setBrush(Qt::white); - setSelectedBrush(Qt::white); - setTextColor(Qt::black); - setSelectedTextColor(Qt::blue); -} - -QCPLegend::~QCPLegend() -{ - clearItems(); - if (qobject_cast(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot) - mParentPlot->legendRemoved(this); -} - -/* no doc for getter, see setSelectedParts */ -QCPLegend::SelectableParts QCPLegend::selectedParts() const -{ - // check whether any legend elements selected, if yes, add spItems to return value - bool hasSelectedItems = false; - for (int i=0; iselected()) - { - hasSelectedItems = true; - break; - } - } - if (hasSelectedItems) - return mSelectedParts | spItems; - else - return mSelectedParts & ~spItems; -} - -/*! - Sets the pen, the border of the entire legend is drawn with. -*/ -void QCPLegend::setBorderPen(const QPen &pen) -{ - mBorderPen = pen; -} - -/*! - Sets the brush of the legend background. -*/ -void QCPLegend::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will - use this font by default. However, a different font can be specified on a per-item-basis by - accessing the specific legend item. - - This function will also set \a font on all already existing legend items. - - \see QCPAbstractLegendItem::setFont -*/ -void QCPLegend::setFont(const QFont &font) -{ - mFont = font; - for (int i=0; isetFont(mFont); - } -} - -/*! - Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) - will use this color by default. However, a different colors can be specified on a per-item-basis - by accessing the specific legend item. - - This function will also set \a color on all already existing legend items. - - \see QCPAbstractLegendItem::setTextColor -*/ -void QCPLegend::setTextColor(const QColor &color) -{ - mTextColor = color; - for (int i=0; isetTextColor(color); - } -} - -/*! - Sets the size of legend icons. Legend items that draw an icon (e.g. a visual - representation of the graph) will use this size by default. -*/ -void QCPLegend::setIconSize(const QSize &size) -{ - mIconSize = size; -} - -/*! \overload -*/ -void QCPLegend::setIconSize(int width, int height) -{ - mIconSize.setWidth(width); - mIconSize.setHeight(height); -} - -/*! - Sets the horizontal space in pixels between the legend icon and the text next to it. - Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the - name of the graph) will use this space by default. -*/ -void QCPLegend::setIconTextPadding(int padding) -{ - mIconTextPadding = padding; -} - -/*! - Sets the pen used to draw a border around each legend icon. Legend items that draw an - icon (e.g. a visual representation of the graph) will use this pen by default. - - If no border is wanted, set this to \a Qt::NoPen. -*/ -void QCPLegend::setIconBorderPen(const QPen &pen) -{ - mIconBorderPen = pen; -} - -/*! - Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. - (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) - - However, even when \a selectable is set to a value not allowing the selection of a specific part, - it is still possible to set the selection of this part manually, by calling \ref setSelectedParts - directly. - - \see SelectablePart, setSelectedParts -*/ -void QCPLegend::setSelectableParts(const SelectableParts &selectable) -{ - if (mSelectableParts != selectable) - { - mSelectableParts = selectable; - emit selectableChanged(mSelectableParts); - } -} - -/*! - Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part - is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected - doesn't contain \ref spItems, those items become deselected. - - The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions - contains iSelectLegend. You only need to call this function when you wish to change the selection - state manually. - - This function can change the selection state of a part even when \ref setSelectableParts was set to a - value that actually excludes the part. - - emits the \ref selectionChanged signal when \a selected is different from the previous selection state. - - Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set - before, because there's no way to specify which exact items to newly select. Do this by calling - \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. - - \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, - setSelectedFont -*/ -void QCPLegend::setSelectedParts(const SelectableParts &selected) -{ - SelectableParts newSelected = selected; - mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed - - if (mSelectedParts != newSelected) - { - if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that) - { - qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function"; - newSelected &= ~spItems; - } - if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems)) // spItems flag was unset, so clear item selection - { - for (int i=0; isetSelected(false); - } - } - mSelectedParts = newSelected; - emit selectionChanged(mSelectedParts); - } -} - -/*! - When the legend box is selected, this pen is used to draw the border instead of the normal pen - set via \ref setBorderPen. - - \see setSelectedParts, setSelectableParts, setSelectedBrush -*/ -void QCPLegend::setSelectedBorderPen(const QPen &pen) -{ - mSelectedBorderPen = pen; -} - -/*! - Sets the pen legend items will use to draw their icon borders, when they are selected. - - \see setSelectedParts, setSelectableParts, setSelectedFont -*/ -void QCPLegend::setSelectedIconBorderPen(const QPen &pen) -{ - mSelectedIconBorderPen = pen; -} - -/*! - When the legend box is selected, this brush is used to draw the legend background instead of the normal brush - set via \ref setBrush. - - \see setSelectedParts, setSelectableParts, setSelectedBorderPen -*/ -void QCPLegend::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/*! - Sets the default font that is used by legend items when they are selected. - - This function will also set \a font on all already existing legend items. - - \see setFont, QCPAbstractLegendItem::setSelectedFont -*/ -void QCPLegend::setSelectedFont(const QFont &font) -{ - mSelectedFont = font; - for (int i=0; isetSelectedFont(font); - } -} - -/*! - Sets the default text color that is used by legend items when they are selected. - - This function will also set \a color on all already existing legend items. - - \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor -*/ -void QCPLegend::setSelectedTextColor(const QColor &color) -{ - mSelectedTextColor = color; - for (int i=0; isetSelectedTextColor(color); - } -} - -/*! - Returns the item with index \a i. - - Note that the linear index depends on the current fill order (\ref setFillOrder). - - \see itemCount, addItem, itemWithPlottable -*/ -QCPAbstractLegendItem *QCPLegend::item(int index) const -{ - return qobject_cast(elementAt(index)); -} - -/*! - Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). - If such an item isn't in the legend, returns 0. - - \see hasItemWithPlottable -*/ -QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const -{ - for (int i=0; i(item(i))) - { - if (pli->plottable() == plottable) - return pli; - } - } - return 0; -} - -/*! - Returns the number of items currently in the legend. - - Note that if empty cells are in the legend (e.g. by calling methods of the \ref QCPLayoutGrid - base class which allows creating empty cells), they are included in the returned count. - - \see item -*/ -int QCPLegend::itemCount() const -{ - return elementCount(); -} - -/*! - Returns whether the legend contains \a item. - - \see hasItemWithPlottable -*/ -bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const -{ - for (int i=0; iitem(i)) - return true; - } - return false; -} - -/*! - Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). - If such an item isn't in the legend, returns false. - - \see itemWithPlottable -*/ -bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const -{ - return itemWithPlottable(plottable); -} - -/*! - Adds \a item to the legend, if it's not present already. The element is arranged according to the - current fill order (\ref setFillOrder) and wrapping (\ref setWrap). - - Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. - - The legend takes ownership of the item. - - \see removeItem, item, hasItem -*/ -bool QCPLegend::addItem(QCPAbstractLegendItem *item) -{ - return addElement(item); -} - -/*! \overload - - Removes the item with the specified \a index from the legend and deletes it. - - After successful removal, the legend is reordered according to the current fill order (\ref - setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item - was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. - - Returns true, if successful. Unlike \ref QCPLayoutGrid::removeAt, this method only removes - elements derived from \ref QCPAbstractLegendItem. - - \see itemCount, clearItems -*/ -bool QCPLegend::removeItem(int index) -{ - if (QCPAbstractLegendItem *ali = item(index)) - { - bool success = remove(ali); - if (success) - setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering - return success; - } else - return false; -} - -/*! \overload - - Removes \a item from the legend and deletes it. - - After successful removal, the legend is reordered according to the current fill order (\ref - setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item - was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. - - Returns true, if successful. - - \see clearItems -*/ -bool QCPLegend::removeItem(QCPAbstractLegendItem *item) -{ - bool success = remove(item); - if (success) - setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering - return success; -} - -/*! - Removes all items from the legend. -*/ -void QCPLegend::clearItems() -{ - for (int i=itemCount()-1; i>=0; --i) - removeItem(i); -} - -/*! - Returns the legend items that are currently selected. If no items are selected, - the list is empty. - - \see QCPAbstractLegendItem::setSelected, setSelectable -*/ -QList QCPLegend::selectedItems() const -{ - QList result; - for (int i=0; iselected()) - result.append(ali); - } - } - return result; -} - -/*! \internal - - A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter - before drawing main legend elements. - - This is the antialiasing state the painter passed to the \ref draw method is in by default. - - This function takes into account the local setting of the antialiasing flag as well as the - overrides set with \ref QCustomPlot::setAntialiasedElements and \ref - QCustomPlot::setNotAntialiasedElements. - - \seebaseclassmethod - - \see setAntialiased -*/ -void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); -} - -/*! \internal - - Returns the pen used to paint the border of the legend, taking into account the selection state - of the legend box. -*/ -QPen QCPLegend::getBorderPen() const -{ - return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; -} - -/*! \internal - - Returns the brush used to paint the background of the legend, taking into account the selection - state of the legend box. -*/ -QBrush QCPLegend::getBrush() const -{ - return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush; -} - -/*! \internal - - Draws the legend box with the provided \a painter. The individual legend items are layerables - themselves, thus are drawn independently. -*/ -void QCPLegend::draw(QCPPainter *painter) -{ - // draw background rect: - painter->setBrush(getBrush()); - painter->setPen(getBorderPen()); - painter->drawRect(mOuterRect); -} - -/* inherits documentation from base class */ -double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if (!mParentPlot) return -1; - if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) - return -1; - - if (mOuterRect.contains(pos.toPoint())) - { - if (details) details->setValue(spLegendBox); - return mParentPlot->selectionTolerance()*0.99; - } - return -1; -} - -/* inherits documentation from base class */ -void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - mSelectedParts = selectedParts(); // in case item selection has changed - if (details.value() == spLegendBox && mSelectableParts.testFlag(spLegendBox)) - { - SelectableParts selBefore = mSelectedParts; - setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent) - if (selectionStateChanged) - *selectionStateChanged = mSelectedParts != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPLegend::deselectEvent(bool *selectionStateChanged) -{ - mSelectedParts = selectedParts(); // in case item selection has changed - if (mSelectableParts.testFlag(spLegendBox)) - { - SelectableParts selBefore = mSelectedParts; - setSelectedParts(selectedParts() & ~spLegendBox); - if (selectionStateChanged) - *selectionStateChanged = mSelectedParts != selBefore; - } -} - -/* inherits documentation from base class */ -QCP::Interaction QCPLegend::selectionCategory() const -{ - return QCP::iSelectLegend; -} - -/* inherits documentation from base class */ -QCP::Interaction QCPAbstractLegendItem::selectionCategory() const -{ - return QCP::iSelectLegend; -} - -/* inherits documentation from base class */ -void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) -{ - if (parentPlot && !parentPlot->legend) - parentPlot->legend = this; -} -/* end of 'src/layoutelements/layoutelement-legend.cpp' */ - - -/* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12761 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPTextElement -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPTextElement - \brief A layout element displaying a text - - The text may be specified with \ref setText, the formatting can be controlled with \ref setFont, - \ref setTextColor, and \ref setTextFlags. - - A text element can be added as follows: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcptextelement-creation -*/ - -/* start documentation of signals */ - -/*! \fn void QCPTextElement::selectionChanged(bool selected) - - This signal is emitted when the selection state has changed to \a selected, either by user - interaction or by a direct call to \ref setSelected. - - \see setSelected, setSelectable -*/ - -/*! \fn void QCPTextElement::clicked(QMouseEvent *event) - - This signal is emitted when the text element is clicked. - - \see doubleClicked, selectTest -*/ - -/*! \fn void QCPTextElement::doubleClicked(QMouseEvent *event) - - This signal is emitted when the text element is double clicked. - - \see clicked, selectTest -*/ - -/* end documentation of signals */ - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref - setText). -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot) : - QCPLayoutElement(parentPlot), - mText(), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below - mTextColor(Qt::black), - mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - if (parentPlot) - { - mFont = parentPlot->font(); - mSelectedFont = parentPlot->font(); - } - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. - - The initial text is set to \a text. -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text) : - QCPLayoutElement(parentPlot), - mText(text), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below - mTextColor(Qt::black), - mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - if (parentPlot) - { - mFont = parentPlot->font(); - mSelectedFont = parentPlot->font(); - } - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. - - The initial text is set to \a text with \a pointSize. -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize) : - QCPLayoutElement(parentPlot), - mText(text), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below - mTextColor(Qt::black), - mSelectedFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - if (parentPlot) - { - mFont = parentPlot->font(); - mFont.setPointSizeF(pointSize); - mSelectedFont = parentPlot->font(); - mSelectedFont.setPointSizeF(pointSize); - } - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. - - The initial text is set to \a text with \a pointSize and the specified \a fontFamily. -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize) : - QCPLayoutElement(parentPlot), - mText(text), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(QFont(fontFamily, pointSize)), - mTextColor(Qt::black), - mSelectedFont(QFont(fontFamily, pointSize)), - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! \overload - - Creates a new QCPTextElement instance and sets default values. - - The initial text is set to \a text with the specified \a font. -*/ -QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font) : - QCPLayoutElement(parentPlot), - mText(text), - mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), - mFont(font), - mTextColor(Qt::black), - mSelectedFont(font), - mSelectedTextColor(Qt::blue), - mSelectable(false), - mSelected(false) -{ - setMargins(QMargins(2, 2, 2, 2)); -} - -/*! - Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". - - \see setFont, setTextColor, setTextFlags -*/ -void QCPTextElement::setText(const QString &text) -{ - mText = text; -} - -/*! - Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of - \c Qt::AlignmentFlag and \c Qt::TextFlag enums. - - Possible enums are: - - Qt::AlignLeft - - Qt::AlignRight - - Qt::AlignHCenter - - Qt::AlignJustify - - Qt::AlignTop - - Qt::AlignBottom - - Qt::AlignVCenter - - Qt::AlignCenter - - Qt::TextDontClip - - Qt::TextSingleLine - - Qt::TextExpandTabs - - Qt::TextShowMnemonic - - Qt::TextWordWrap - - Qt::TextIncludeTrailingSpaces -*/ -void QCPTextElement::setTextFlags(int flags) -{ - mTextFlags = flags; -} - -/*! - Sets the \a font of the text. - - \see setTextColor, setSelectedFont -*/ -void QCPTextElement::setFont(const QFont &font) -{ - mFont = font; -} - -/*! - Sets the \a color of the text. - - \see setFont, setSelectedTextColor -*/ -void QCPTextElement::setTextColor(const QColor &color) -{ - mTextColor = color; -} - -/*! - Sets the \a font of the text that will be used if the text element is selected (\ref setSelected). - - \see setFont -*/ -void QCPTextElement::setSelectedFont(const QFont &font) -{ - mSelectedFont = font; -} - -/*! - Sets the \a color of the text that will be used if the text element is selected (\ref setSelected). - - \see setTextColor -*/ -void QCPTextElement::setSelectedTextColor(const QColor &color) -{ - mSelectedTextColor = color; -} - -/*! - Sets whether the user may select this text element. - - Note that even when \a selectable is set to false, the selection state may be changed - programmatically via \ref setSelected. -*/ -void QCPTextElement::setSelectable(bool selectable) -{ - if (mSelectable != selectable) - { - mSelectable = selectable; - emit selectableChanged(mSelectable); - } -} - -/*! - Sets the selection state of this text element to \a selected. If the selection has changed, \ref - selectionChanged is emitted. - - Note that this function can change the selection state independently of the current \ref - setSelectable state. -*/ -void QCPTextElement::setSelected(bool selected) -{ - if (mSelected != selected) - { - mSelected = selected; - emit selectionChanged(mSelected); - } -} - -/* inherits documentation from base class */ -void QCPTextElement::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); -} - -/* inherits documentation from base class */ -void QCPTextElement::draw(QCPPainter *painter) -{ - painter->setFont(mainFont()); - painter->setPen(QPen(mainTextColor())); - painter->drawText(mRect, Qt::AlignCenter, mText, &mTextBoundingRect); -} - -/* inherits documentation from base class */ -QSize QCPTextElement::minimumOuterSizeHint() const -{ - QFontMetrics metrics(mFont); - QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); - result.rwidth() += mMargins.left()+mMargins.right(); - result.rheight() += mMargins.top()+mMargins.bottom(); - return result; -} - -/* inherits documentation from base class */ -QSize QCPTextElement::maximumOuterSizeHint() const -{ - QFontMetrics metrics(mFont); - QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); - result.setWidth(QWIDGETSIZE_MAX); - result.rheight() += mMargins.top()+mMargins.bottom(); - return result; -} - -/* inherits documentation from base class */ -void QCPTextElement::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) -{ - Q_UNUSED(event) - Q_UNUSED(details) - if (mSelectable) - { - bool selBefore = mSelected; - setSelected(additive ? !mSelected : true); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/* inherits documentation from base class */ -void QCPTextElement::deselectEvent(bool *selectionStateChanged) -{ - if (mSelectable) - { - bool selBefore = mSelected; - setSelected(false); - if (selectionStateChanged) - *selectionStateChanged = mSelected != selBefore; - } -} - -/*! - Returns 0.99*selectionTolerance (see \ref QCustomPlot::setSelectionTolerance) when \a pos is - within the bounding box of the text element's text. Note that this bounding box is updated in the - draw call. - - If \a pos is outside the text's bounding box or if \a onlySelectable is true and this text - element is not selectable (\ref setSelectable), returns -1. - - \seebaseclassmethod -*/ -double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - if (mTextBoundingRect.contains(pos.toPoint())) - return mParentPlot->selectionTolerance()*0.99; - else - return -1; -} - -/*! - Accepts the mouse event in order to emit the according click signal in the \ref - mouseReleaseEvent. - - \seebaseclassmethod -*/ -void QCPTextElement::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - event->accept(); -} - -/*! - Emits the \ref clicked signal if the cursor hasn't moved by more than a few pixels since the \ref - mousePressEvent. - - \seebaseclassmethod -*/ -void QCPTextElement::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - if ((QPointF(event->pos())-startPos).manhattanLength() <= 3) - emit clicked(event); -} - -/*! - Emits the \ref doubleClicked signal. - - \seebaseclassmethod -*/ -void QCPTextElement::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) -{ - Q_UNUSED(details) - emit doubleClicked(event); -} - -/*! \internal - - Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to - true, else mFont is returned. -*/ -QFont QCPTextElement::mainFont() const -{ - return mSelected ? mSelectedFont : mFont; -} - -/*! \internal - - Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to - true, else mTextColor is returned. -*/ -QColor QCPTextElement::mainTextColor() const -{ - return mSelected ? mSelectedTextColor : mTextColor; -} -/* end of 'src/layoutelements/layoutelement-textelement.cpp' */ - - -/* including file 'src/layoutelements/layoutelement-colorscale.cpp', size 25770 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPColorScale -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPColorScale - \brief A color scale for use with color coding data such as QCPColorMap - - This layout element can be placed on the plot to correlate a color gradient with data values. It - is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". - - \image html QCPColorScale.png - - The color scale can be either horizontal or vertical, as shown in the image above. The - orientation and the side where the numbers appear is controlled with \ref setType. - - Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are - connected, they share their gradient, data range and data scale type (\ref setGradient, \ref - setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color - scale, to make them all synchronize these properties. - - To have finer control over the number display and axis behaviour, you can directly access the - \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if - you want to change the number of automatically generated ticks, call - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-tickcount - - Placing a color scale next to the main axis rect works like with any other layout element: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation - In this case we have placed it to the right of the default axis rect, so it wasn't necessary to - call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color - scale can be set with \ref setLabel. - - For optimum appearance (like in the image above), it may be desirable to line up the axis rect and - the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup - - Color scales are initialized with a non-zero minimum top and bottom margin (\ref - setMinimumMargins), because vertical color scales are most common and the minimum top/bottom - margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a - horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you - might want to also change the minimum margins accordingly, e.g. setMinimumMargins(QMargins(6, 0, 6, 0)). -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPAxis *QCPColorScale::axis() const - - Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the - appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its - interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref - setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref - QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on - the QCPColorScale or on its QCPAxis. - - If the type of the color scale is changed with \ref setType, the axis returned by this method - will change, too, to either the left, right, bottom or top axis, depending on which type was set. -*/ - -/* end documentation of signals */ -/* start documentation of signals */ - -/*! \fn void QCPColorScale::dataRangeChanged(const QCPRange &newRange); - - This signal is emitted when the data range changes. - - \see setDataRange -*/ - -/*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); - - This signal is emitted when the data scale type changes. - - \see setDataScaleType -*/ - -/*! \fn void QCPColorScale::gradientChanged(const QCPColorGradient &newGradient); - - This signal is emitted when the gradient changes. - - \see setGradient -*/ - -/* end documentation of signals */ - -/*! - Constructs a new QCPColorScale. -*/ -QCPColorScale::QCPColorScale(QCustomPlot *parentPlot) : - QCPLayoutElement(parentPlot), - mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight - mDataScaleType(QCPAxis::stLinear), - mBarWidth(20), - mAxisRect(new QCPColorScaleAxisRectPrivate(this)) -{ - setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used) - setType(QCPAxis::atRight); - setDataRange(QCPRange(0, 6)); -} - -QCPColorScale::~QCPColorScale() -{ - delete mAxisRect; -} - -/* undocumented getter */ -QString QCPColorScale::label() const -{ - if (!mColorAxis) - { - qDebug() << Q_FUNC_INFO << "internal color axis undefined"; - return QString(); - } - - return mColorAxis.data()->label(); -} - -/* undocumented getter */ -bool QCPColorScale::rangeDrag() const -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return false; - } - - return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && - mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && - mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); -} - -/* undocumented getter */ -bool QCPColorScale::rangeZoom() const -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return false; - } - - return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && - mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && - mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); -} - -/*! - Sets at which side of the color scale the axis is placed, and thus also its orientation. - - Note that after setting \a type to a different value, the axis returned by \ref axis() will - be a different one. The new axis will adopt the following properties from the previous axis: The - range, scale type, label and ticker (the latter will be shared and not copied). -*/ -void QCPColorScale::setType(QCPAxis::AxisType type) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - if (mType != type) - { - mType = type; - QCPRange rangeTransfer(0, 6); - QString labelTransfer; - QSharedPointer tickerTransfer; - // transfer/revert some settings on old axis if it exists: - bool doTransfer = (bool)mColorAxis; - if (doTransfer) - { - rangeTransfer = mColorAxis.data()->range(); - labelTransfer = mColorAxis.data()->label(); - tickerTransfer = mColorAxis.data()->ticker(); - mColorAxis.data()->setLabel(QString()); - disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); - disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); - } - QList allAxisTypes = QList() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop; - foreach (QCPAxis::AxisType atype, allAxisTypes) - { - mAxisRect.data()->axis(atype)->setTicks(atype == mType); - mAxisRect.data()->axis(atype)->setTickLabels(atype== mType); - } - // set new mColorAxis pointer: - mColorAxis = mAxisRect.data()->axis(mType); - // transfer settings to new axis: - if (doTransfer) - { - mColorAxis.data()->setRange(rangeTransfer); // range transfer necessary if axis changes from vertical to horizontal or vice versa (axes with same orientation are synchronized via signals) - mColorAxis.data()->setLabel(labelTransfer); - mColorAxis.data()->setTicker(tickerTransfer); - } - connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); - connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); - mAxisRect.data()->setRangeDragAxes(QList() << mColorAxis.data()); - } -} - -/*! - Sets the range spanned by the color gradient and that is shown by the axis in the color scale. - - It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is - also equivalent to directly accessing the \ref axis and setting its range with \ref - QCPAxis::setRange. - - \see setDataScaleType, setGradient, rescaleDataRange -*/ -void QCPColorScale::setDataRange(const QCPRange &dataRange) -{ - if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) - { - mDataRange = dataRange; - if (mColorAxis) - mColorAxis.data()->setRange(mDataRange); - emit dataRangeChanged(mDataRange); - } -} - -/*! - Sets the scale type of the color scale, i.e. whether values are linearly associated with colors - or logarithmically. - - It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is - also equivalent to directly accessing the \ref axis and setting its scale type with \ref - QCPAxis::setScaleType. - - \see setDataRange, setGradient -*/ -void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) -{ - if (mDataScaleType != scaleType) - { - mDataScaleType = scaleType; - if (mColorAxis) - mColorAxis.data()->setScaleType(mDataScaleType); - if (mDataScaleType == QCPAxis::stLogarithmic) - setDataRange(mDataRange.sanitizedForLogScale()); - emit dataScaleTypeChanged(mDataScaleType); - } -} - -/*! - Sets the color gradient that will be used to represent data values. - - It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. - - \see setDataRange, setDataScaleType -*/ -void QCPColorScale::setGradient(const QCPColorGradient &gradient) -{ - if (mGradient != gradient) - { - mGradient = gradient; - if (mAxisRect) - mAxisRect.data()->mGradientImageInvalidated = true; - emit gradientChanged(mGradient); - } -} - -/*! - Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on - the internal \ref axis. -*/ -void QCPColorScale::setLabel(const QString &str) -{ - if (!mColorAxis) - { - qDebug() << Q_FUNC_INFO << "internal color axis undefined"; - return; - } - - mColorAxis.data()->setLabel(str); -} - -/*! - Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed - will have. -*/ -void QCPColorScale::setBarWidth(int width) -{ - mBarWidth = width; -} - -/*! - Sets whether the user can drag the data range (\ref setDataRange). - - Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref - QCustomPlot::setInteractions) to allow range dragging. -*/ -void QCPColorScale::setRangeDrag(bool enabled) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - - if (enabled) - mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); - else - mAxisRect.data()->setRangeDrag(0); -} - -/*! - Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. - - Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref - QCustomPlot::setInteractions) to allow range dragging. -*/ -void QCPColorScale::setRangeZoom(bool enabled) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - - if (enabled) - mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); - else - mAxisRect.data()->setRangeZoom(0); -} - -/*! - Returns a list of all the color maps associated with this color scale. -*/ -QList QCPColorScale::colorMaps() const -{ - QList result; - for (int i=0; iplottableCount(); ++i) - { - if (QCPColorMap *cm = qobject_cast(mParentPlot->plottable(i))) - if (cm->colorScale() == this) - result.append(cm); - } - return result; -} - -/*! - Changes the data range such that all color maps associated with this color scale are fully mapped - to the gradient in the data dimension. - - \see setDataRange -*/ -void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) -{ - QList maps = colorMaps(); - QCPRange newRange; - bool haveRange = false; - QCP::SignDomain sign = QCP::sdBoth; - if (mDataScaleType == QCPAxis::stLogarithmic) - sign = (mDataRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); - for (int i=0; irealVisibility() && onlyVisibleMaps) - continue; - QCPRange mapRange; - if (maps.at(i)->colorScale() == this) - { - bool currentFoundRange = true; - mapRange = maps.at(i)->data()->dataBounds(); - if (sign == QCP::sdPositive) - { - if (mapRange.lower <= 0 && mapRange.upper > 0) - mapRange.lower = mapRange.upper*1e-3; - else if (mapRange.lower <= 0 && mapRange.upper <= 0) - currentFoundRange = false; - } else if (sign == QCP::sdNegative) - { - if (mapRange.upper >= 0 && mapRange.lower < 0) - mapRange.upper = mapRange.lower*1e-3; - else if (mapRange.upper >= 0 && mapRange.lower >= 0) - currentFoundRange = false; - } - if (currentFoundRange) - { - if (!haveRange) - newRange = mapRange; - else - newRange.expand(mapRange); - haveRange = true; - } - } - } - if (haveRange) - { - if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data - { - double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason - if (mDataScaleType == QCPAxis::stLinear) - { - newRange.lower = center-mDataRange.size()/2.0; - newRange.upper = center+mDataRange.size()/2.0; - } else // mScaleType == stLogarithmic - { - newRange.lower = center/qSqrt(mDataRange.upper/mDataRange.lower); - newRange.upper = center*qSqrt(mDataRange.upper/mDataRange.lower); - } - } - setDataRange(newRange); - } -} - -/* inherits documentation from base class */ -void QCPColorScale::update(UpdatePhase phase) -{ - QCPLayoutElement::update(phase); - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - - mAxisRect.data()->update(phase); - - switch (phase) - { - case upMargins: - { - if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) - { - setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); - setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); - } else - { - setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), QWIDGETSIZE_MAX); - setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), 0); - } - break; - } - case upLayout: - { - mAxisRect.data()->setOuterRect(rect()); - break; - } - default: break; - } -} - -/* inherits documentation from base class */ -void QCPColorScale::applyDefaultAntialiasingHint(QCPPainter *painter) const -{ - painter->setAntialiasing(false); -} - -/* inherits documentation from base class */ -void QCPColorScale::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - mAxisRect.data()->mousePressEvent(event, details); -} - -/* inherits documentation from base class */ -void QCPColorScale::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - mAxisRect.data()->mouseMoveEvent(event, startPos); -} - -/* inherits documentation from base class */ -void QCPColorScale::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - mAxisRect.data()->mouseReleaseEvent(event, startPos); -} - -/* inherits documentation from base class */ -void QCPColorScale::wheelEvent(QWheelEvent *event) -{ - if (!mAxisRect) - { - qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; - return; - } - mAxisRect.data()->wheelEvent(event); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPColorScaleAxisRectPrivate -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPColorScaleAxisRectPrivate - - \internal - \brief An axis rect subclass for use in a QCPColorScale - - This is a private class and not part of the public QCustomPlot interface. - - It provides the axis rect functionality for the QCPColorScale class. -*/ - - -/*! - Creates a new instance, as a child of \a parentColorScale. -*/ -QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale) : - QCPAxisRect(parentColorScale->parentPlot(), true), - mParentColorScale(parentColorScale), - mGradientImageInvalidated(true) -{ - setParentLayerable(parentColorScale); - setMinimumMargins(QMargins(0, 0, 0, 0)); - QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; - foreach (QCPAxis::AxisType type, allAxisTypes) - { - axis(type)->setVisible(true); - axis(type)->grid()->setVisible(false); - axis(type)->setPadding(0); - connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts))); - connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts))); - } - - connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange))); - connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange))); - connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange))); - connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))); - connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType))); - connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); - connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); - connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); - - // make layer transfers of color scale transfer to axis rect and axes - // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: - connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); - foreach (QCPAxis::AxisType type, allAxisTypes) - connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), axis(type), SLOT(setLayer(QCPLayer*))); -} - -/*! \internal - - Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws - it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. - - \seebaseclassmethod -*/ -void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) -{ - if (mGradientImageInvalidated) - updateGradientImage(); - - bool mirrorHorz = false; - bool mirrorVert = false; - if (mParentColorScale->mColorAxis) - { - mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); - mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); - } - - painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); - QCPAxisRect::draw(painter); -} - -/*! \internal - - Uses the current gradient of the parent \ref QCPColorScale (specified in the constructor) to - generate a gradient image. This gradient image will be used in the \ref draw method. -*/ -void QCPColorScaleAxisRectPrivate::updateGradientImage() -{ - if (rect().isEmpty()) - return; - - const QImage::Format format = QImage::Format_ARGB32_Premultiplied; - int n = mParentColorScale->mGradient.levelCount(); - int w, h; - QVector data(n); - for (int i=0; imType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop) - { - w = n; - h = rect().height(); - mGradientImage = QImage(w, h, format); - QVector pixels; - for (int y=0; y(mGradientImage.scanLine(y))); - mParentColorScale->mGradient.colorize(data.constData(), QCPRange(0, n-1), pixels.first(), n); - for (int y=1; y(mGradientImage.scanLine(y)); - const QRgb lineColor = mParentColorScale->mGradient.color(data[h-1-y], QCPRange(0, n-1)); - for (int x=0; x allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; - foreach (QCPAxis::AxisType type, allAxisTypes) - { - if (QCPAxis *senderAxis = qobject_cast(sender())) - if (senderAxis->axisType() == type) - continue; - - if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) - { - if (selectedParts.testFlag(QCPAxis::spAxis)) - axis(type)->setSelectedParts(axis(type)->selectedParts() | QCPAxis::spAxis); - else - axis(type)->setSelectedParts(axis(type)->selectedParts() & ~QCPAxis::spAxis); - } - } -} - -/*! \internal - - This slot is connected to the selectableChanged signals of the four axes in the constructor. It - synchronizes the selectability of the axes. -*/ -void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts) -{ - // synchronize axis base selectability: - QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; - foreach (QCPAxis::AxisType type, allAxisTypes) - { - if (QCPAxis *senderAxis = qobject_cast(sender())) - if (senderAxis->axisType() == type) - continue; - - if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) - { - if (selectableParts.testFlag(QCPAxis::spAxis)) - axis(type)->setSelectableParts(axis(type)->selectableParts() | QCPAxis::spAxis); - else - axis(type)->setSelectableParts(axis(type)->selectableParts() & ~QCPAxis::spAxis); - } - } -} -/* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ - - -/* including file 'src/plottables/plottable-graph.cpp', size 73960 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPGraphData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPGraphData - \brief Holds the data of one single data point for QCPGraph. - - The stored data is: - \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) - \li \a value: coordinate on the value axis of this data point (this is the \a mainValue) - - The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for - \ref QCPDataContainer with \ref QCPGraphData as the DataType template parameter. See the - documentation there for an explanation regarding the data type's generic methods. - - \see QCPGraphDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPGraphData::sortKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPGraphData QCPGraphData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey. All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPGraphData::sortKeyIsMainKey() - - Since the member \a key is both the data point key coordinate and the data ordering parameter, - this method returns true. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPGraphData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPGraphData::mainValue() const - - Returns the \a value member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPGraphData::valueRange() const - - Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a data point with key and value set to zero. -*/ -QCPGraphData::QCPGraphData() : - key(0), - value(0) -{ -} - -/*! - Constructs a data point with the specified \a key and \a value. -*/ -QCPGraphData::QCPGraphData(double key, double value, int status) : - key(key), - value(value), - status(status) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPGraph -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPGraph - \brief A plottable representing a graph in a plot. - - \image html QCPGraph.png - - Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be - accessed via QCustomPlot::graph. - - To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can - also access and modify the data via the \ref data method, which returns a pointer to the internal - \ref QCPGraphDataContainer. - - Graphs are used to display single-valued data. Single-valued means that there should only be one - data point per unique key coordinate. In other words, the graph can't have \a loops. If you do - want to plot non-single-valued curves, rather use the QCPCurve plottable. - - Gaps in the graph line can be created by adding data points with NaN as value - (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be - separated. - - \section qcpgraph-appearance Changing the appearance - - The appearance of the graph is mainly determined by the line style, scatter style, brush and pen - of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). - - \subsection filling Filling under or between graphs - - QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to - the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, - just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. - - By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill - between this graph and another one, call \ref setChannelFillGraph with the other graph as - parameter. - - \see QCustomPlot::addGraph, QCustomPlot::graph -*/ - -/* start of documentation of inline functions */ - -/*! \fn QSharedPointer QCPGraph::data() const - - Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may - use it to directly manipulate the data, which may be more convenient and faster than using the - regular \ref setData or \ref addData methods. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a - keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually - but use QCustomPlot::removePlottable() instead. - - To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. -*/ -QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis) -{ - // special handling for QCPGraphs to maintain the simple graph interface: - mParentPlot->registerGraph(this); - - setPen(QPen(Qt::blue, 0)); - setBrush(Qt::NoBrush); - - setLineStyle(lsLine); - setScatterSkip(0); - setChannelFillGraph(0); - setAdaptiveSampling(true); -} - -QCPGraph::~QCPGraph() -{ -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPGraphs may share the same data container safely. - Modifying the data in the container will then affect all graphs that share the container. Sharing - can be achieved by simply exchanging the data containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the graph's data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-2 - - \see addData -*/ -void QCPGraph::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Replaces the current data with the provided points in \a keys and \a values. The provided - vectors should have equal length. Else, the number of added points will be the size of the - smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData -*/ -void QCPGraph::setData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted) -{ - mDataContainer->clear(); - addData(keys, values, status, alreadySorted); -} - -/*! - Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to - \ref lsNone and \ref setScatterStyle to the desired scatter style. - - \see setScatterStyle -*/ -void QCPGraph::setLineStyle(LineStyle ls) -{ - mLineStyle = ls; -} - -/*! - Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points - are drawn (e.g. for line-only-plots with appropriate line style). - - \see QCPScatterStyle, setLineStyle -*/ -void QCPGraph::setScatterStyle(const QCPScatterStyle &style) -{ - mScatterStyle = style; -} - -/*! - If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of - scatter points are skipped/not drawn after every drawn scatter point. - - This can be used to make the data appear sparser while for example still having a smooth line, - and to improve performance for very high density plots. - - If \a skip is set to 0 (default), all scatter points are drawn. - - \see setScatterStyle -*/ -void QCPGraph::setScatterSkip(int skip) -{ - mScatterSkip = qMax(0, skip); -} - -/*! - Sets the target graph for filling the area between this graph and \a targetGraph with the current - brush (\ref setBrush). - - When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To - disable any filling, set the brush to Qt::NoBrush. - - \see setBrush -*/ -void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) -{ - // prevent setting channel target to this graph itself: - if (targetGraph == this) - { - qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; - mChannelFillGraph = 0; - return; - } - // prevent setting channel target to a graph not in the plot: - if (targetGraph && targetGraph->mParentPlot != mParentPlot) - { - qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; - mChannelFillGraph = 0; - return; - } - - mChannelFillGraph = targetGraph; -} - -/*! - Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive - sampling technique can drastically improve the replot performance for graphs with a larger number - of points (e.g. above 10,000), without notably changing the appearance of the graph. - - By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive - sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no - disadvantage in almost all cases. - - \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" - - As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are - reproduced reliably, as well as the overall shape of the data set. The replot time reduces - dramatically though. This allows QCustomPlot to display large amounts of data in realtime. - - \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" - - Care must be taken when using high-density scatter plots in combination with adaptive sampling. - The adaptive sampling algorithm treats scatter plots more carefully than line plots which still - gives a significant reduction of replot times, but not quite as much as for line plots. This is - because scatter plots inherently need more data points to be preserved in order to still resemble - the original, non-adaptive-sampling plot. As shown above, the results still aren't quite - identical, as banding occurs for the outer data points. This is in fact intentional, such that - the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, - depends on the point density, i.e. the number of points in the plot. - - For some situations with scatter plots it might thus be desirable to manually turn adaptive - sampling off. For example, when saving the plot to disk. This can be achieved by setting \a - enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled - back to true afterwards. -*/ -void QCPGraph::setAdaptiveSampling(bool enabled) -{ - mAdaptiveSampling = enabled; -} - -/*! \overload - - Adds the provided points in \a keys and \a values to the current data. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPGraph::addData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted) -{ - if (keys.size() != values.size()) - qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); - int n = qMin(keys.size(), values.size()); - if (keys.size() != status.size()) - qDebug() << Q_FUNC_INFO << "keys and status have different sizes:" << keys.size() << status.size(); - n = qMin(n, status.size()); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->key = keys[i]; - it->value = values[i]; - it->status = status[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - - Adds the provided data point as \a key and \a value to the current data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPGraph::addData(double key, double value, int status) -{ - mDataContainer->add(QCPGraphData(key, value, status)); -} - -double QCPGraph::value(const double &key) -{ - QCPDataContainer::const_iterator lower = mDataContainer->findBegin(key, true); - if(lower == mDataContainer->constEnd()) - { - return qSqrt(-1.); - } - - if(lsStepLeft == mLineStyle) - { - return lower->value; - } - - QCPDataContainer::const_iterator upper = mDataContainer->findEnd(key, false); - if(upper == mDataContainer->constEnd() || upper == mDataContainer->constBegin()) - { - return qSqrt(-1.); - } - - if(upper->key == lower->key) - { - return lower->value; - } - - double rate = (upper->value - lower->value) / (upper->key - lower->key); - return rate * (key - lower->key) + lower->value; -} - -/* inherits documentation from base class */ -double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - double result = pointDistance(pos, closestDataPoint); - if (details) - { - int pointIndex = closestDataPoint-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return result; - } else - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPGraph::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - return mDataContainer->keyRange(foundRange, inSignDomain); -} - -/* inherits documentation from base class */ -QCPRange QCPGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); -} - -/* inherits documentation from base class */ -void QCPGraph::draw(QCPPainter *painter) -{ - if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; - if (mLineStyle == lsNone && mScatterStyle.isNone()) return; - - QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments - QVector status; - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - // get line pixel points appropriate to line style: - QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) - getLines(&lines, lineDataRange, &status); - - // check data validity if flag set: -#ifdef QCUSTOMPLOT_CHECK_DATA - QCPGraphDataContainer::const_iterator it; - for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) - { - if (QCP::isInvalidData(it->key, it->value)) - qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); - } -#endif - - // draw fill of graph: - if (isSelectedSegment && mSelectionDecorator) - mSelectionDecorator->applyBrush(painter); - else - painter->setBrush(mBrush); - painter->setPen(Qt::NoPen); - drawFill(painter, &lines); - - // draw line: - if (mLineStyle != lsNone) - { - if (isSelectedSegment && mSelectionDecorator) - mSelectionDecorator->applyPen(painter); - else - painter->setPen(mPen); - painter->setBrush(Qt::NoBrush); - if (mLineStyle == lsImpulse) - drawImpulsePlot(painter, lines); - else - drawLinePlot(painter, lines, status); // also step plots can be drawn as a line plot - } - - // draw scatters: - QCPScatterStyle finalScatterStyle = mScatterStyle; - if (isSelectedSegment && mSelectionDecorator) - finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); - if (!finalScatterStyle.isNone()) - { - getScatters(&scatters, allSegments.at(i)); - drawScatterPlot(painter, scatters, finalScatterStyle); - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - // draw fill: - if (mBrush.style() != Qt::NoBrush) - { - applyFillAntialiasingHint(painter); - painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); - } - // draw line vertically centered: - if (mLineStyle != lsNone) - { - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens - } - // draw scatter symbol: - if (!mScatterStyle.isNone()) - { - applyScattersAntialiasingHint(painter); - // scale scatter pixmap if it's too large to fit in legend icon rect: - if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) - { - QCPScatterStyle scaledStyle(mScatterStyle); - scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); - scaledStyle.applyTo(painter, mPen); - scaledStyle.drawShape(painter, QRectF(rect).center()); - } else - { - mScatterStyle.applyTo(painter, mPen); - mScatterStyle.drawShape(painter, QRectF(rect).center()); - } - } -} - -/*! \internal - - This method retrieves an optimized set of data points via \ref getOptimizedLineData, an branches - out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc. - according to the line style of the graph. - - \a lines will be filled with points in pixel coordinates, that can be drawn with the according - draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines - aren't necessarily the original data points. For example, step line styles require additional - points to form the steps when drawn. If the line style of the graph is \ref lsNone, the \a - lines vector will be empty. - - \a dataRange specifies the beginning and ending data indices that will be taken into account for - conversion. In this function, the specified range may exceed the total data bounds without harm: - a correspondingly trimmed data range will be used. This takes the burden off the user of this - function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref - getDataSegments. - - \see getScatters -*/ -void QCPGraph::getLines(QVector *lines, const QCPDataRange &dataRange, QVector *status) const -{ - if (!lines || !status) return; - QCPGraphDataContainer::const_iterator begin, end; - getVisibleDataBounds(begin, end, dataRange); - if (begin == end) - { - lines->clear(); - status->clear(); - return; - } - - QVector lineData; - if (mLineStyle != lsNone) - getOptimizedLineData(&lineData, begin, end); - - if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in lineData (significantly simplifies following processing) - std::reverse(lineData.begin(), lineData.end()); - - switch (mLineStyle) - { - case lsNone: lines->clear();status->clear(); break; - case lsLine: dataToLines(lineData, *lines, *status); break; - case lsStepLeft: dataToStepLeftLines(lineData, *lines, *status); break; - case lsStepRight: dataToStepRightLines(lineData, *lines, *status); break; - case lsStepCenter: dataToStepCenterLines(lineData, *lines, *status); break; - case lsImpulse: dataToImpulseLines(lineData, *lines, *status); break; - } -} - -/*! \internal - - This method retrieves an optimized set of data points via \ref getOptimizedScatterData and then - converts them to pixel coordinates. The resulting points are returned in \a scatters, and can be - passed to \ref drawScatterPlot. - - \a dataRange specifies the beginning and ending data indices that will be taken into account for - conversion. In this function, the specified range may exceed the total data bounds without harm: - a correspondingly trimmed data range will be used. This takes the burden off the user of this - function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref - getDataSegments. -*/ -void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataRange) const -{ - if (!scatters) return; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; } - - QCPGraphDataContainer::const_iterator begin, end; - getVisibleDataBounds(begin, end, dataRange); - if (begin == end) - { - scatters->clear(); - return; - } - - QVector data; - getOptimizedScatterData(&data, begin, end); - - if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in data (significantly simplifies following processing) - std::reverse(data.begin(), data.end()); - - scatters->resize(data.size()); - if (keyAxis->orientation() == Qt::Vertical) - { - for (int i=0; icoordToPixel(data.at(i).value)); - (*scatters)[i].setY(keyAxis->coordToPixel(data.at(i).key)); - } - } - } else - { - for (int i=0; icoordToPixel(data.at(i).key)); - (*scatters)[i].setY(valueAxis->coordToPixel(data.at(i).value)); - } - } - } -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsLine. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot -*/ -void QCPGraph::dataToLines(const QVector &data, QVector &lines, QVector &status) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - lines.resize(data.size()); - status.resize(data.size()); - - // transform data points to pixels: - if (keyAxis->orientation() == Qt::Vertical) - { - for (int i=0; icoordToPixel(data.at(i).value)); - lines[i].setY(keyAxis->coordToPixel(data.at(i).key)); - status[i] = data.at(i).status; - } - } else // key axis is horizontal - { - for (int i=0; icoordToPixel(data.at(i).key)); - lines[i].setY(valueAxis->coordToPixel(data.at(i).value)); - status[i] = data.at(i).status; - } - } -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsStepLeft. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot -*/ -void QCPGraph::dataToStepLeftLines(const QVector &data, QVector &lines, QVector &status) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - lines.resize(data.size()*2); - status.resize(data.size()*2); - - // calculate steps from data and transform to pixel coordinates: - if (keyAxis->orientation() == Qt::Vertical) - { - double lastValue = valueAxis->coordToPixel(data.first().value); - int lastStatus = data.first().status; - for (int i=0; icoordToPixel(data.at(i).key); - lines[i*2+0].setX(lastValue); - lines[i*2+0].setY(key); - status[i*2+0] = lastStatus; - lastValue = valueAxis->coordToPixel(data.at(i).value); - lastStatus = data.at(i).status; - lines[i*2+1].setX(lastValue); - lines[i*2+1].setY(key); - status[i*2+1] = lastStatus; - } - } else // key axis is horizontal - { - double lastValue = valueAxis->coordToPixel(data.first().value); - int lastStatus = data.first().status; - for (int i=0; icoordToPixel(data.at(i).key); - lines[i*2+0].setX(key); - lines[i*2+0].setY(lastValue); - status[i*2+0] = lastStatus; - lastValue = valueAxis->coordToPixel(data.at(i).value); - lastStatus = data.at(i).status; - lines[i*2+1].setX(key); - lines[i*2+1].setY(lastValue); - status[i*2+1] = lastStatus; - } - } -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsStepRight. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToLines, dataToStepLeftLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot -*/ -void QCPGraph::dataToStepRightLines(const QVector &data, QVector &lines, QVector &status) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - lines.resize(data.size()*2); - status.resize(data.size()*2); - - // calculate steps from data and transform to pixel coordinates: - if (keyAxis->orientation() == Qt::Vertical) - { - double lastKey = keyAxis->coordToPixel(data.first().key); - for (int i=0; icoordToPixel(data.at(i).value); - const int curStatus = data.at(i).status; - lines[i*2+0].setX(value); - lines[i*2+0].setY(lastKey); - status[i*2+0] = curStatus; - lastKey = keyAxis->coordToPixel(data.at(i).key); - lines[i*2+1].setX(value); - lines[i*2+1].setY(lastKey); - status[i*2+1] = curStatus; - } - } else // key axis is horizontal - { - double lastKey = keyAxis->coordToPixel(data.first().key); - for (int i=0; icoordToPixel(data.at(i).value); - const int curStatus = data.at(i).status; - lines[i*2+0].setX(lastKey); - lines[i*2+0].setY(value); - status[i*2+0] = curStatus; - lastKey = keyAxis->coordToPixel(data.at(i).key); - lines[i*2+1].setX(lastKey); - lines[i*2+1].setY(value); - status[i*2+1] = curStatus; - } - } -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsStepCenter. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToImpulseLines, getLines, drawLinePlot -*/ -void QCPGraph::dataToStepCenterLines(const QVector &data, QVector &lines, QVector &status) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - lines.resize(data.size()*2); - status.resize(data.size()*2); - - // calculate steps from data and transform to pixel coordinates: - if (keyAxis->orientation() == Qt::Vertical) - { - double lastKey = keyAxis->coordToPixel(data.first().key); - double lastValue = valueAxis->coordToPixel(data.first().value); - int lastStatus = data.first().status; - lines[0].setX(lastValue); - lines[0].setY(lastKey); - status[0] = lastStatus; - for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; - lines[i*2-1].setX(lastValue); - lines[i*2-1].setY(key); - status[i*2-1] = lastStatus; - lastValue = valueAxis->coordToPixel(data.at(i).value); - lastKey = keyAxis->coordToPixel(data.at(i).key); - lastStatus = data.at(i).status; - lines[i*2+0].setX(lastValue); - lines[i*2+0].setY(key); - status[i*2+0] = lastStatus; - } - lines[data.size()*2-1].setX(lastValue); - lines[data.size()*2-1].setY(lastKey); - status[data.size()*2-1] = lastStatus; - } else // key axis is horizontal - { - double lastKey = keyAxis->coordToPixel(data.first().key); - double lastValue = valueAxis->coordToPixel(data.first().value); - int lastStatus = data.first().status; - lines[0].setX(lastKey); - lines[0].setY(lastValue); - status[0] = lastStatus; - for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; - lines[i*2-1].setX(key); - lines[i*2-1].setY(lastValue); - status[i*2-1] = lastStatus; - lastValue = valueAxis->coordToPixel(data.at(i).value); - lastKey = keyAxis->coordToPixel(data.at(i).key); - lastStatus = data.at(i).status; - lines[i*2+0].setX(key); - lines[i*2+0].setY(lastValue); - status[i*2+0] = lastStatus; - } - lines[data.size()*2-1].setX(lastKey); - lines[data.size()*2-1].setY(lastValue); - status[data.size()*2-1] = lastStatus; - } -} - -/*! \internal - - Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel - coordinate points which are suitable for drawing the line style \ref lsImpulse. - - The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a - getLines if the line style is set accordingly. - - \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, getLines, drawImpulsePlot -*/ -void QCPGraph::dataToImpulseLines(const QVector &data, QVector &lines, QVector &status) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - lines.resize(data.size()*2); - status.resize(data.size()*2); - - // transform data points to pixels: - if (keyAxis->orientation() == Qt::Vertical) - { - for (int i=0; icoordToPixel(data.at(i).key); - const int curStatus = data.at(i).status; - lines[i*2+0].setX(valueAxis->coordToPixel(0)); - lines[i*2+0].setY(key); - status[i*2+0] = curStatus; - lines[i*2+1].setX(valueAxis->coordToPixel(data.at(i).value)); - lines[i*2+1].setY(key); - status[i*2+1] = curStatus; - } - } else // key axis is horizontal - { - for (int i=0; icoordToPixel(data.at(i).key); - const int curStatus = data.at(i).status; - lines[i*2+0].setX(key); - lines[i*2+0].setY(valueAxis->coordToPixel(0)); - status[i*2+0] = curStatus; - lines[i*2+1].setX(key); - lines[i*2+1].setY(valueAxis->coordToPixel(data.at(i).value)); - status[i*2+1] = curStatus; - } - } -} - -/*! \internal - - Draws the fill of the graph using the specified \a painter, with the currently set brush. - - Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref - getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. - - In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), - this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to - operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN - segments of the two involved graphs, before passing the overlapping pairs to \ref - getChannelFillPolygon. - - Pass the points of this graph's line as \a lines, in pixel coordinates. - - \see drawLinePlot, drawImpulsePlot, drawScatterPlot -*/ -void QCPGraph::drawFill(QCPPainter *painter, QVector *lines) const -{ - if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot - if (painter->brush().style() == Qt::NoBrush || painter->brush().color().alpha() == 0) return; - - applyFillAntialiasingHint(painter); - QVector segments = getNonNanSegments(lines, keyAxis()->orientation()); - if (!mChannelFillGraph) - { - // draw base fill under graph, fill goes all the way to the zero-value-line: - for (int i=0; idrawPolygon(getFillPolygon(lines, segments.at(i))); - } else - { - // draw fill between this graph and mChannelFillGraph: - QVector otherLines; - QVector status; - mChannelFillGraph->getLines(&otherLines, QCPDataRange(0, mChannelFillGraph->dataCount()), &status); - if (!otherLines.isEmpty()) - { - QVector otherSegments = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation()); - QVector > segmentPairs = getOverlappingSegments(segments, lines, otherSegments, &otherLines); - for (int i=0; idrawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first, &otherLines, segmentPairs.at(i).second)); - } - } -} - -/*! \internal - - Draws scatter symbols at every point passed in \a scatters, given in pixel coordinates. The - scatters will be drawn with \a painter and have the appearance as specified in \a style. - - \see drawLinePlot, drawImpulsePlot -*/ -void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const -{ - applyScattersAntialiasingHint(painter); - style.applyTo(painter, mPen); - for (int i=0; i &lines, const QVector &status) const -{ - if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) - { - applyDefaultAntialiasingHint(painter); - drawPolyline(painter, lines, status); - } -} - -/*! \internal - - Draws impulses from the provided data, i.e. it connects all line pairs in \a lines, given in - pixel coordinates. The \a lines necessary for impulses are generated by \ref dataToImpulseLines - from the regular graph data points. - - \see drawLinePlot, drawScatterPlot -*/ -void QCPGraph::drawImpulsePlot(QCPPainter *painter, const QVector &lines) const -{ - if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) - { - applyDefaultAntialiasingHint(painter); - QPen oldPen = painter->pen(); - QPen newPen = painter->pen(); - newPen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line - painter->setPen(newPen); - painter->drawLines(lines); - painter->setPen(oldPen); - } -} - -/*! \internal - - Returns via \a lineData the data points that need to be visualized for this graph when plotting - graph lines, taking into consideration the currently visible axis ranges and, if \ref - setAdaptiveSampling is enabled, local point densities. The considered data can be restricted - further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref - getDataSegments). - - This method is used by \ref getLines to retrieve the basic working set of data. - - \see getOptimizedScatterData -*/ -void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const -{ - if (!lineData) return; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - if (begin == end) return; - - int dataCount = end-begin; - int maxCount = std::numeric_limits::max(); - if (mAdaptiveSampling) - { - double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); - if (2*keyPixelSpan+2 < (double)std::numeric_limits::max()) - maxCount = 2*keyPixelSpan+2; - } - - if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average - { - QCPGraphDataContainer::const_iterator it = begin; - double minValue = it->value; - double maxValue = it->value; - QCPGraphDataContainer::const_iterator currentIntervalFirstPoint = it; - int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction - int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey - double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); - double lastIntervalEndKey = currentIntervalStartKey; - double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates - bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) - int intervalDataCount = 1; - ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect - while (it != end) - { - if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary - { - if (it->value < minValue) - minValue = it->value; - else if (it->value > maxValue) - maxValue = it->value; - ++intervalDataCount; - } else // new pixel interval started - { - if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster - { - if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); - if (it->key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.8, (it-1)->value)); - } else - lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); - lastIntervalEndKey = (it-1)->key; - minValue = it->value; - maxValue = it->value; - currentIntervalFirstPoint = it; - currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); - if (keyEpsilonVariable) - keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); - intervalDataCount = 1; - } - ++it; - } - // handle last interval: - if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster - { - if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); - lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); - } else - lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); - - } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output - { - lineData->resize(dataCount); - std::copy(begin, end, lineData->begin()); - } -} - -/*! \internal - - Returns via \a scatterData the data points that need to be visualized for this graph when - plotting scatter points, taking into consideration the currently visible axis ranges and, if \ref - setAdaptiveSampling is enabled, local point densities. The considered data can be restricted - further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref - getDataSegments). - - This method is used by \ref getScatters to retrieve the basic working set of data. - - \see getOptimizedLineData -*/ -void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const -{ - if (!scatterData) return; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - const int scatterModulo = mScatterSkip+1; - const bool doScatterSkip = mScatterSkip > 0; - int beginIndex = begin-mDataContainer->constBegin(); - int endIndex = end-mDataContainer->constBegin(); - while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter - { - ++beginIndex; - ++begin; - } - if (begin == end) return; - int dataCount = end-begin; - int maxCount = std::numeric_limits::max(); - if (mAdaptiveSampling) - { - int keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); - maxCount = 2*keyPixelSpan+2; - } - - if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average - { - double valueMaxRange = valueAxis->range().upper; - double valueMinRange = valueAxis->range().lower; - QCPGraphDataContainer::const_iterator it = begin; - int itIndex = beginIndex; - double minValue = it->value; - double maxValue = it->value; - QCPGraphDataContainer::const_iterator minValueIt = it; - QCPGraphDataContainer::const_iterator maxValueIt = it; - QCPGraphDataContainer::const_iterator currentIntervalStart = it; - int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction - int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey - double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); - double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates - bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) - int intervalDataCount = 1; - // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) // make sure we didn't jump over end - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - // main loop over data points: - while (it != end) - { - if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary - { - if (it->value < minValue && it->value > valueMinRange && it->value < valueMaxRange) - { - minValue = it->value; - minValueIt = it; - } else if (it->value > maxValue && it->value > valueMinRange && it->value < valueMaxRange) - { - maxValue = it->value; - maxValueIt = it; - } - ++intervalDataCount; - } else // new pixel started - { - if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them - { - // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): - double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); - int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average - QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; - int c = 0; - while (intervalIt != it) - { - if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) - scatterData->append(*intervalIt); - ++c; - if (!doScatterSkip) - ++intervalIt; - else - intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here - } - } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) - scatterData->append(*currentIntervalStart); - minValue = it->value; - maxValue = it->value; - currentIntervalStart = it; - currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); - if (keyEpsilonVariable) - keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); - intervalDataCount = 1; - } - // advance to next data point: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) // make sure we didn't jump over end - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - } - // handle last interval: - if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them - { - // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): - double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); - int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average - QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; - int intervalItIndex = intervalIt-mDataContainer->constBegin(); - int c = 0; - while (intervalIt != it) - { - if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) - scatterData->append(*intervalIt); - ++c; - if (!doScatterSkip) - ++intervalIt; - else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison: - { - intervalItIndex += scatterModulo; - if (intervalItIndex < itIndex) - intervalIt += scatterModulo; - else - { - intervalIt = it; - intervalItIndex = itIndex; - } - } - } - } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) - scatterData->append(*currentIntervalStart); - - } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output - { - QCPGraphDataContainer::const_iterator it = begin; - int itIndex = beginIndex; - scatterData->reserve(dataCount); - while (it != end) - { - scatterData->append(*it); - // advance to next data point: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - } - } -} - -/*! - This method outputs the currently visible data range via \a begin and \a end. The returned range - will also never exceed \a rangeRestriction. - - This method takes into account that the drawing of data lines at the axis rect border always - requires the points just outside the visible axis range. So \a begin and \a end may actually - indicate a range that contains one additional data point to the left and right of the visible - axis range. -*/ -void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const -{ - if (rangeRestriction.isEmpty()) - { - end = mDataContainer->constEnd(); - begin = end; - } else - { - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - // get visible data range: - begin = mDataContainer->findBegin(keyAxis->range().lower); - end = mDataContainer->findEnd(keyAxis->range().upper); - // limit lower/upperEnd to rangeRestriction: - mDataContainer->limitIteratorsToDataRange(begin, end, rangeRestriction); // this also ensures rangeRestriction outside data bounds doesn't break anything - } -} - -/*! \internal - - This method goes through the passed points in \a lineData and returns a list of the segments - which don't contain NaN data points. - - \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check - for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c - Qt::Vertical, the \a x member is checked. - - \see getOverlappingSegments, drawFill -*/ -QVector QCPGraph::getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const -{ - QVector result; - const int n = lineData->size(); - - QCPDataRange currentSegment(-1, -1); - int i = 0; - - if (keyOrientation == Qt::Horizontal) - { - while (i < n) - { - while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point - ++i; - if (i == n) - break; - currentSegment.setBegin(i++); - while (i < n && !qIsNaN(lineData->at(i).y())) // seek next NaN data point or end of data - ++i; - currentSegment.setEnd(i++); - result.append(currentSegment); - } - } else // keyOrientation == Qt::Vertical - { - while (i < n) - { - while (i < n && qIsNaN(lineData->at(i).x())) // seek next non-NaN data point - ++i; - if (i == n) - break; - currentSegment.setBegin(i++); - while (i < n && !qIsNaN(lineData->at(i).x())) // seek next NaN data point or end of data - ++i; - currentSegment.setEnd(i++); - result.append(currentSegment); - } - } - return result; -} - -/*! \internal - - This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and - \a otherSegments, and their associated point data \a thisData and \a otherData. - - It returns all pairs of segments (the first from \a thisSegments, the second from \a - otherSegments), which overlap in plot coordinates. - - This method is useful in the case of a channel fill between two graphs, when only those non-NaN - segments which actually overlap in their key coordinate shall be considered for drawing a channel - fill polygon. - - It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and - that the segments don't overlap themselves. The same is assumed for the segments in \a - otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments. - - \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon -*/ -QVector > QCPGraph::getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const -{ - QVector > result; - if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() || otherSegments.isEmpty()) - return result; - - int thisIndex = 0; - int otherIndex = 0; - const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical; - while (thisIndex < thisSegments.size() && otherIndex < otherSegments.size()) - { - if (thisSegments.at(thisIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow - { - ++thisIndex; - continue; - } - if (otherSegments.at(otherIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow - { - ++otherIndex; - continue; - } - double thisLower, thisUpper, otherLower, otherUpper; - if (!verticalKey) - { - thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x(); - thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).x(); - otherLower = otherData->at(otherSegments.at(otherIndex).begin()).x(); - otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).x(); - } else - { - thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y(); - thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).y(); - otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y(); - otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).y(); - } - - int bPrecedence; - if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence)) - result.append(QPair(thisSegments.at(thisIndex), otherSegments.at(otherIndex))); - - if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with next otherSegment, keeping current thisSegment - ++otherIndex; - else // otherSegment reaches further than thisSegment, so continue with next thisSegment, keeping current otherSegment - ++thisIndex; - } - - return result; -} - -/*! \internal - - Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper) - have overlap. - - The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the - \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher - coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if - both segment's upper bounds are identical, 0 is returned as \a bPrecedence. - - It is assumed that the lower bounds always have smaller or equal values than the upper bounds. - - \see getOverlappingSegments -*/ -bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const -{ - bPrecedence = 0; - if (aLower > bUpper) - { - bPrecedence = -1; - return false; - } else if (bLower > aUpper) - { - bPrecedence = 1; - return false; - } else - { - if (aUpper > bUpper) - bPrecedence = -1; - else if (aUpper < bUpper) - bPrecedence = 1; - - return true; - } -} - -/*! \internal - - Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis. - The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates - is in positive or negative infinity. So this case is handled separately by just closing the fill - polygon on the axis which lies in the direction towards the zero value. - - \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether - the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or - y value of the returned point, respectively. -*/ -QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } - - QPointF result; - if (valueAxis->scaleType() == QCPAxis::stLinear) - { - if (keyAxis->orientation() == Qt::Horizontal) - { - result.setX(matchingDataPoint.x()); - result.setY(valueAxis->coordToPixel(0)); - } else // keyAxis->orientation() == Qt::Vertical - { - result.setX(valueAxis->coordToPixel(0)); - result.setY(matchingDataPoint.y()); - } - } else // valueAxis->mScaleType == QCPAxis::stLogarithmic - { - // In logarithmic scaling we can't just draw to value 0 so we just fill all the way - // to the axis which is in the direction towards 0 - if (keyAxis->orientation() == Qt::Vertical) - { - if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || - (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis - result.setX(keyAxis->axisRect()->right()); - else - result.setX(keyAxis->axisRect()->left()); - result.setY(matchingDataPoint.y()); - } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) - { - result.setX(matchingDataPoint.x()); - if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || - (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis - result.setY(keyAxis->axisRect()->top()); - else - result.setY(keyAxis->axisRect()->bottom()); - } - } - return result; -} - -/*! \internal - - Returns the polygon needed for drawing normal fills between this graph and the key axis. - - Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment - which shall be used for the fill. The collection of \a lineData points described by \a segment - must not contain NaN data points (see \ref getNonNanSegments). - - The returned fill polygon will be closed at the key axis (the zero-value line) for linear value - axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect - side (see \ref getFillBasePoint). - - For increased performance (due to implicit sharing), keep the returned QPolygonF const. - - \see drawFill, getNonNanSegments -*/ -const QPolygonF QCPGraph::getFillPolygon(const QVector *lineData, QCPDataRange segment) const -{ - if (segment.size() < 2) - return QPolygonF(); - QPolygonF result(segment.size()+2); - - result[0] = getFillBasePoint(lineData->at(segment.begin())); - std::copy(lineData->constBegin()+segment.begin(), lineData->constBegin()+segment.end(), result.begin()+1); - result[result.size()-1] = getFillBasePoint(lineData->at(segment.end()-1)); - - return result; -} - -/*! \internal - - Returns the polygon needed for drawing (partial) channel fills between this graph and the graph - specified by \ref setChannelFillGraph. - - The data points of this graph are passed as pixel coordinates via \a thisData, the data of the - other graph as \a otherData. The returned polygon will be calculated for the specified data - segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a - otherData, respectively. - - The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by - \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap - need to be processed here. - - For increased performance due to implicit sharing, keep the returned QPolygonF const. - - \see drawFill, getOverlappingSegments, getNonNanSegments -*/ -const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const -{ - if (!mChannelFillGraph) - return QPolygonF(); - - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } - if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } - - if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) - return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) - - if (thisData->isEmpty()) return QPolygonF(); - QVector thisSegmentData(thisSegment.size()); - QVector otherSegmentData(otherSegment.size()); - std::copy(thisData->constBegin()+thisSegment.begin(), thisData->constBegin()+thisSegment.end(), thisSegmentData.begin()); - std::copy(otherData->constBegin()+otherSegment.begin(), otherData->constBegin()+otherSegment.end(), otherSegmentData.begin()); - // pointers to be able to swap them, depending which data range needs cropping: - QVector *staticData = &thisSegmentData; - QVector *croppedData = &otherSegmentData; - - // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): - if (keyAxis->orientation() == Qt::Horizontal) - { - // x is key - // crop lower bound: - if (staticData->first().x() < croppedData->first().x()) // other one must be cropped - qSwap(staticData, croppedData); - const int lowBound = findIndexBelowX(croppedData, staticData->first().x()); - if (lowBound == -1) return QPolygonF(); // key ranges have no overlap - croppedData->remove(0, lowBound); - // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: - if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation - double slope; - if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x())) - slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); - else - slope = 0; - (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); - (*croppedData)[0].setX(staticData->first().x()); - - // crop upper bound: - if (staticData->last().x() > croppedData->last().x()) // other one must be cropped - qSwap(staticData, croppedData); - int highBound = findIndexAboveX(croppedData, staticData->last().x()); - if (highBound == -1) return QPolygonF(); // key ranges have no overlap - croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); - // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: - if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation - const int li = croppedData->size()-1; // last index - if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li-1).x())) - slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); - else - slope = 0; - (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); - (*croppedData)[li].setX(staticData->last().x()); - } else // mKeyAxis->orientation() == Qt::Vertical - { - // y is key - // crop lower bound: - if (staticData->first().y() < croppedData->first().y()) // other one must be cropped - qSwap(staticData, croppedData); - int lowBound = findIndexBelowY(croppedData, staticData->first().y()); - if (lowBound == -1) return QPolygonF(); // key ranges have no overlap - croppedData->remove(0, lowBound); - // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: - if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation - double slope; - if (!qFuzzyCompare(croppedData->at(1).y(), croppedData->at(0).y())) // avoid division by zero in step plots - slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); - else - slope = 0; - (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); - (*croppedData)[0].setY(staticData->first().y()); - - // crop upper bound: - if (staticData->last().y() > croppedData->last().y()) // other one must be cropped - qSwap(staticData, croppedData); - int highBound = findIndexAboveY(croppedData, staticData->last().y()); - if (highBound == -1) return QPolygonF(); // key ranges have no overlap - croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); - // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: - if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation - int li = croppedData->size()-1; // last index - if (!qFuzzyCompare(croppedData->at(li).y(), croppedData->at(li-1).y())) // avoid division by zero in step plots - slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); - else - slope = 0; - (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); - (*croppedData)[li].setY(staticData->last().y()); - } - - // return joined: - for (int i=otherSegmentData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted - thisSegmentData << otherSegmentData.at(i); - return QPolygonF(thisSegmentData); -} - -/*! \internal - - Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in - \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key - axis is horizontal. - - Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. -*/ -int QCPGraph::findIndexAboveX(const QVector *data, double x) const -{ - for (int i=data->size()-1; i>=0; --i) - { - if (data->at(i).x() < x) - { - if (isize()-1) - return i+1; - else - return data->size()-1; - } - } - return -1; -} - -/*! \internal - - Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in - \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key - axis is horizontal. - - Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. -*/ -int QCPGraph::findIndexBelowX(const QVector *data, double x) const -{ - for (int i=0; isize(); ++i) - { - if (data->at(i).x() > x) - { - if (i>0) - return i-1; - else - return 0; - } - } - return -1; -} - -/*! \internal - - Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in - \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key - axis is vertical. - - Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. -*/ -int QCPGraph::findIndexAboveY(const QVector *data, double y) const -{ - for (int i=data->size()-1; i>=0; --i) - { - if (data->at(i).y() < y) - { - if (isize()-1) - return i+1; - else - return data->size()-1; - } - } - return -1; -} - -/*! \internal - - Calculates the minimum distance in pixels the graph's representation has from the given \a - pixelPoint. This is used to determine whether the graph was clicked or not, e.g. in \ref - selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if - the graph has a line representation, the returned distance may be smaller than the distance to - the \a closestData point, since the distance to the graph line is also taken into account. - - If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape - is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. -*/ -double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const -{ - closestData = mDataContainer->constEnd(); - if (mDataContainer->isEmpty()) - return -1.0; - if (mLineStyle == lsNone && mScatterStyle.isNone()) - return -1.0; - - // calculate minimum distances to graph data points and find closestData iterator: - double minDistSqr = std::numeric_limits::max(); - // determine which key range comes into question, taking selection tolerance around pos into account: - double posKeyMin, posKeyMax, dummy; - pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); - pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); - if (posKeyMin > posKeyMax) - qSwap(posKeyMin, posKeyMax); - // iterate over found data points and then choose the one with the shortest distance to pos: - QCPGraphDataContainer::const_iterator begin = mDataContainer->findBegin(posKeyMin, true); - QCPGraphDataContainer::const_iterator end = mDataContainer->findEnd(posKeyMax, true); - for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) - { - const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestData = it; - } - } - - // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): - if (mLineStyle != lsNone) - { - // line displayed, calculate distance to line segments: - QVector lineData; - QVector status; - getLines(&lineData, QCPDataRange(0, dataCount()), &status); - QCPVector2D p(pixelPoint); - const int step = mLineStyle==lsImpulse ? 2 : 1; // impulse plot differs from other line styles in that the lineData points are only pairwise connected - for (int i=0; i *data, double y) const -{ - for (int i=0; isize(); ++i) - { - if (data->at(i).y() > y) - { - if (i>0) - return i-1; - else - return 0; - } - } - return -1; -} -/* end of 'src/plottables/plottable-graph.cpp' */ - - -/* including file 'src/plottables/plottable-curve.cpp', size 63527 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPCurveData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPCurveData - \brief Holds the data of one single data point for QCPCurve. - - The stored data is: - \li \a t: the free ordering parameter of this curve point, like in the mathematical vector (x(t), y(t)). (This is the \a sortKey) - \li \a key: coordinate on the key axis of this curve point (this is the \a mainKey) - \li \a value: coordinate on the value axis of this curve point (this is the \a mainValue) - - The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for - \ref QCPDataContainer with \ref QCPCurveData as the DataType template parameter. See the - documentation there for an explanation regarding the data type's generic methods. - - \see QCPCurveDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPCurveData::sortKey() const - - Returns the \a t member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPCurveData QCPCurveData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey (assigned to the data point's \a t member). - All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPCurveData::sortKeyIsMainKey() - - Since the member \a key is the data point key coordinate and the member \a t is the data ordering - parameter, this method returns false. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPCurveData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPCurveData::mainValue() const - - Returns the \a value member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPCurveData::valueRange() const - - Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a curve data point with t, key and value set to zero. -*/ -QCPCurveData::QCPCurveData() : - t(0), - key(0), - value(0) -{ -} - -/*! - Constructs a curve data point with the specified \a t, \a key and \a value. -*/ -QCPCurveData::QCPCurveData(double t, double key, double value) : - t(t), - key(key), - value(value) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPCurve -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPCurve - \brief A plottable representing a parametric curve in a plot. - - \image html QCPCurve.png - - Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, - so their visual representation can have \a loops. This is realized by introducing a third - coordinate \a t, which defines the order of the points described by the other two coordinates \a - x and \a y. - - To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can - also access and modify the curve's data via the \ref data method, which returns a pointer to the - internal \ref QCPCurveDataContainer. - - Gaps in the curve can be created by adding data points with NaN as key and value - (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be - separated. - - \section qcpcurve-appearance Changing the appearance - - The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). - - \section qcpcurve-usage Usage - - Like all data representing objects in QCustomPlot, the QCPCurve is a plottable - (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies - (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - - Usually, you first create an instance: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 - which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes - ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. - The newly created plottable can be modified, e.g.: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-2 -*/ - -/* start of documentation of inline functions */ - -/*! \fn QSharedPointer QCPCurve::data() const - - Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may - use it to directly manipulate the data, which may be more convenient and faster than using the - regular \ref setData or \ref addData methods. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a - keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually - but use QCustomPlot::removePlottable() instead. -*/ -QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis) -{ - // modify inherited properties from abstract plottable: - setPen(QPen(Qt::blue, 0)); - setBrush(Qt::NoBrush); - - setScatterStyle(QCPScatterStyle()); - setLineStyle(lsLine); - setScatterSkip(0); -} - -QCPCurve::~QCPCurve() -{ -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPCurves may share the same data container safely. - Modifying the data in the container will then affect all curves that share the container. Sharing - can be achieved by simply exchanging the data containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the curve's data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-2 - - \see addData -*/ -void QCPCurve::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Replaces the current data with the provided points in \a t, \a keys and \a values. The provided - vectors should have equal length. Else, the number of added points will be the size of the - smallest vector. - - If you can guarantee that the passed data points are sorted by \a t in ascending order, you can - set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData -*/ -void QCPCurve::setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) -{ - mDataContainer->clear(); - addData(t, keys, values, alreadySorted); -} - - -/*! \overload - - Replaces the current data with the provided points in \a keys and \a values. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - The t parameter of each data point will be set to the integer index of the respective key/value - pair. - - \see addData -*/ -void QCPCurve::setData(const QVector &keys, const QVector &values) -{ - mDataContainer->clear(); - addData(keys, values); -} - -/*! - Sets the visual appearance of single data points in the plot. If set to \ref - QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate - line style). - - \see QCPScatterStyle, setLineStyle -*/ -void QCPCurve::setScatterStyle(const QCPScatterStyle &style) -{ - mScatterStyle = style; -} - -/*! - If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of - scatter points are skipped/not drawn after every drawn scatter point. - - This can be used to make the data appear sparser while for example still having a smooth line, - and to improve performance for very high density plots. - - If \a skip is set to 0 (default), all scatter points are drawn. - - \see setScatterStyle -*/ -void QCPCurve::setScatterSkip(int skip) -{ - mScatterSkip = qMax(0, skip); -} - -/*! - Sets how the single data points are connected in the plot or how they are represented visually - apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref - setScatterStyle to the desired scatter style. - - \see setScatterStyle -*/ -void QCPCurve::setLineStyle(QCPCurve::LineStyle style) -{ - mLineStyle = style; -} - -/*! \overload - - Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPCurve::addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) -{ - if (t.size() != keys.size() || t.size() != values.size()) - qDebug() << Q_FUNC_INFO << "ts, keys and values have different sizes:" << t.size() << keys.size() << values.size(); - const int n = qMin(qMin(t.size(), keys.size()), values.size()); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->t = t[i]; - it->key = keys[i]; - it->value = values[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - - Adds the provided points in \a keys and \a values to the current data. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - The t parameter of each data point will be set to the integer index of the respective key/value - pair. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPCurve::addData(const QVector &keys, const QVector &values) -{ - if (keys.size() != values.size()) - qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); - const int n = qMin(keys.size(), values.size()); - double tStart; - if (!mDataContainer->isEmpty()) - tStart = (mDataContainer->constEnd()-1)->t + 1.0; - else - tStart = 0; - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->t = tStart + i; - it->key = keys[i]; - it->value = values[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, true); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - Adds the provided data point as \a t, \a key and \a value to the current data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPCurve::addData(double t, double key, double value) -{ - mDataContainer->add(QCPCurveData(t, key, value)); -} - -/*! \overload - - Adds the provided data point as \a key and \a value to the current data. - - The t parameter is generated automatically by increments of 1 for each point, starting at the - highest t of previously existing data or 0, if the curve data is empty. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPCurve::addData(double key, double value) -{ - if (!mDataContainer->isEmpty()) - mDataContainer->add(QCPCurveData((mDataContainer->constEnd()-1)->t + 1.0, key, value)); - else - mDataContainer->add(QCPCurveData(0.0, key, value)); -} - -/* inherits documentation from base class */ -double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - QCPCurveDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - double result = pointDistance(pos, closestDataPoint); - if (details) - { - int pointIndex = closestDataPoint-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return result; - } else - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPCurve::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - return mDataContainer->keyRange(foundRange, inSignDomain); -} - -/* inherits documentation from base class */ -QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); -} - -/* inherits documentation from base class */ -void QCPCurve::draw(QCPPainter *painter) -{ - if (mDataContainer->isEmpty()) return; - - // allocate line vector: - QVector lines, scatters; - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - - // fill with curve data: - QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width - if (isSelectedSegment && mSelectionDecorator) - finalCurvePen = mSelectionDecorator->pen(); - - QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care) - getCurveLines(&lines, lineDataRange, finalCurvePen.widthF()); - - // check data validity if flag set: - #ifdef QCUSTOMPLOT_CHECK_DATA - for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) - { - if (QCP::isInvalidData(it->t) || - QCP::isInvalidData(it->key, it->value)) - qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); - } - #endif - - // draw curve fill: - applyFillAntialiasingHint(painter); - if (isSelectedSegment && mSelectionDecorator) - mSelectionDecorator->applyBrush(painter); - else - painter->setBrush(mBrush); - painter->setPen(Qt::NoPen); - if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) - painter->drawPolygon(QPolygonF(lines)); - - // draw curve line: - if (mLineStyle != lsNone) - { - painter->setPen(finalCurvePen); - painter->setBrush(Qt::NoBrush); - drawCurveLine(painter, lines); - } - - // draw scatters: - QCPScatterStyle finalScatterStyle = mScatterStyle; - if (isSelectedSegment && mSelectionDecorator) - finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); - if (!finalScatterStyle.isNone()) - { - getScatters(&scatters, allSegments.at(i), finalScatterStyle.size()); - drawScatterPlot(painter, scatters, finalScatterStyle); - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - // draw fill: - if (mBrush.style() != Qt::NoBrush) - { - applyFillAntialiasingHint(painter); - painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); - } - // draw line vertically centered: - if (mLineStyle != lsNone) - { - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens - } - // draw scatter symbol: - if (!mScatterStyle.isNone()) - { - applyScattersAntialiasingHint(painter); - // scale scatter pixmap if it's too large to fit in legend icon rect: - if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) - { - QCPScatterStyle scaledStyle(mScatterStyle); - scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); - scaledStyle.applyTo(painter, mPen); - scaledStyle.drawShape(painter, QRectF(rect).center()); - } else - { - mScatterStyle.applyTo(painter, mPen); - mScatterStyle.drawShape(painter, QRectF(rect).center()); - } - } -} - -/*! \internal - - Draws lines between the points in \a lines, given in pixel coordinates. - - \see drawScatterPlot, getCurveLines -*/ -void QCPCurve::drawCurveLine(QCPPainter *painter, const QVector &lines) const -{ - if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) - { - applyDefaultAntialiasingHint(painter); - drawPolyline(painter, lines); - } -} - -/*! \internal - - Draws scatter symbols at every point passed in \a points, given in pixel coordinates. The - scatters will be drawn with \a painter and have the appearance as specified in \a style. - - \see drawCurveLine, getCurveLines -*/ -void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const -{ - // draw scatter point symbols: - applyScattersAntialiasingHint(painter); - style.applyTo(painter, mPen); - for (int i=0; i *lines, const QCPDataRange &dataRange, double penWidth) const -{ - if (!lines) return; - lines->clear(); - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - // add margins to rect to compensate for stroke width - const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety - const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation()); - const double keyMax = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*keyAxis->pixelOrientation()); - const double valueMin = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)-strokeMargin*valueAxis->pixelOrientation()); - const double valueMax = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)+strokeMargin*valueAxis->pixelOrientation()); - QCPCurveDataContainer::const_iterator itBegin = mDataContainer->constBegin(); - QCPCurveDataContainer::const_iterator itEnd = mDataContainer->constEnd(); - mDataContainer->limitIteratorsToDataRange(itBegin, itEnd, dataRange); - if (itBegin == itEnd) - return; - QCPCurveDataContainer::const_iterator it = itBegin; - QCPCurveDataContainer::const_iterator prevIt = itEnd-1; - int prevRegion = getRegion(prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin); - QVector trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right) - while (it != itEnd) - { - const int currentRegion = getRegion(it->key, it->value, keyMin, valueMax, keyMax, valueMin); - if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R - { - if (currentRegion != 5) // segment doesn't end in R, so it's a candidate for removal - { - QPointF crossA, crossB; - if (prevRegion == 5) // we're coming from R, so add this point optimized - { - lines->append(getOptimizedPoint(currentRegion, it->key, it->value, prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin)); - // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point - *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); - } else if (mayTraverse(prevRegion, currentRegion) && - getTraverse(prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin, crossA, crossB)) - { - // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point: - QVector beforeTraverseCornerPoints, afterTraverseCornerPoints; - getTraverseCornerPoints(prevRegion, currentRegion, keyMin, valueMax, keyMax, valueMin, beforeTraverseCornerPoints, afterTraverseCornerPoints); - if (it != itBegin) - { - *lines << beforeTraverseCornerPoints; - lines->append(crossA); - lines->append(crossB); - *lines << afterTraverseCornerPoints; - } else - { - lines->append(crossB); - *lines << afterTraverseCornerPoints; - trailingPoints << beforeTraverseCornerPoints << crossA ; - } - } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s) - { - *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); - } - } else // segment does end in R, so we add previous point optimized and this point at original position - { - if (it == itBegin) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end - trailingPoints << getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); - else - lines->append(getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin)); - lines->append(coordsToPixels(it->key, it->value)); - } - } else // region didn't change - { - if (currentRegion == 5) // still in R, keep adding original points - { - lines->append(coordsToPixels(it->key, it->value)); - } else // still outside R, no need to add anything - { - // see how this is not doing anything? That's the main optimization... - } - } - prevIt = it; - prevRegion = currentRegion; - ++it; - } - *lines << trailingPoints; -} - -/*! \internal - - Called by \ref draw to generate points in pixel coordinates which represent the scatters of the - curve. If a scatter skip is configured (\ref setScatterSkip), the returned points are accordingly - sparser. - - Scatters that aren't visible in the current axis rect are optimized away. - - \a scatters will be filled with points in pixel coordinates, that can be drawn with \ref - drawScatterPlot. - - \a dataRange specifies the beginning and ending data indices that will be taken into account for - conversion. - - \a scatterWidth specifies the scatter width that will be used to later draw the scatters at pixel - coordinates generated by this function. This is needed here to calculate an accordingly wider - margin around the axis rect when performing the data point reduction. - - \see draw, drawScatterPlot -*/ -void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const -{ - if (!scatters) return; - scatters->clear(); - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); - QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); - mDataContainer->limitIteratorsToDataRange(begin, end, dataRange); - if (begin == end) - return; - const int scatterModulo = mScatterSkip+1; - const bool doScatterSkip = mScatterSkip > 0; - int endIndex = end-mDataContainer->constBegin(); - - QCPRange keyRange = keyAxis->range(); - QCPRange valueRange = valueAxis->range(); - // extend range to include width of scatter symbols: - keyRange.lower = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.lower)-scatterWidth*keyAxis->pixelOrientation()); - keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation()); - valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation()); - valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation()); - - QCPCurveDataContainer::const_iterator it = begin; - int itIndex = begin-mDataContainer->constBegin(); - while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter - { - ++itIndex; - ++it; - } - if (keyAxis->orientation() == Qt::Vertical) - { - while (it != end) - { - if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) - scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key))); - - // advance iterator to next (non-skipped) data point: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) // make sure we didn't jump over end - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - } - } else - { - while (it != end) - { - if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) - scatters->append(QPointF(keyAxis->coordToPixel(it->key), valueAxis->coordToPixel(it->value))); - - // advance iterator to next (non-skipped) data point: - if (!doScatterSkip) - ++it; - else - { - itIndex += scatterModulo; - if (itIndex < endIndex) // make sure we didn't jump over end - it += scatterModulo; - else - { - it = end; - itIndex = endIndex; - } - } - } - } -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - It returns the region of the given point (\a key, \a value) with respect to a rectangle defined - by \a keyMin, \a keyMax, \a valueMin, and \a valueMax. - - The regions are enumerated from top to bottom (\a valueMin to \a valueMax) and left to right (\a - keyMin to \a keyMax): - - - - - -
147
258
369
- - With the rectangle being region 5, and the outer regions extending infinitely outwards. In the - curve optimization algorithm, region 5 is considered to be the visible portion of the plot. -*/ -int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const -{ - if (key < keyMin) // region 123 - { - if (value > valueMax) - return 1; - else if (value < valueMin) - return 3; - else - return 2; - } else if (key > keyMax) // region 789 - { - if (value > valueMax) - return 7; - else if (value < valueMin) - return 9; - else - return 8; - } else // region 456 - { - if (value > valueMax) - return 4; - else if (value < valueMin) - return 6; - else - return 5; - } -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - This method is used in case the current segment passes from inside the visible rect (region 5, - see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by - the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). - - It returns the intersection point of the segment with the border of region 5. - - For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or - whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or - leaving it. It is important though that \a otherRegion correctly identifies the other region not - equal to 5. -*/ -QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const -{ - // The intersection point interpolation here is done in pixel coordinates, so we don't need to - // differentiate between different axis scale types. Note that the nomenclature - // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be - // different in pixel coordinates (horz/vert key axes, reversed ranges) - - const double keyMinPx = mKeyAxis->coordToPixel(keyMin); - const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); - const double valueMinPx = mValueAxis->coordToPixel(valueMin); - const double valueMaxPx = mValueAxis->coordToPixel(valueMax); - const double otherValuePx = mValueAxis->coordToPixel(otherValue); - const double valuePx = mValueAxis->coordToPixel(value); - const double otherKeyPx = mKeyAxis->coordToPixel(otherKey); - const double keyPx = mKeyAxis->coordToPixel(key); - double intersectKeyPx = keyMinPx; // initial key just a fail-safe - double intersectValuePx = valueMinPx; // initial value just a fail-safe - switch (otherRegion) - { - case 1: // top and left edge - { - intersectValuePx = valueMaxPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) - { - intersectKeyPx = keyMinPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - } - break; - } - case 2: // left edge - { - intersectKeyPx = keyMinPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - break; - } - case 3: // bottom and left edge - { - intersectValuePx = valueMinPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) - { - intersectKeyPx = keyMinPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - } - break; - } - case 4: // top edge - { - intersectValuePx = valueMaxPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - break; - } - case 5: - { - break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table - } - case 6: // bottom edge - { - intersectValuePx = valueMinPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - break; - } - case 7: // top and right edge - { - intersectValuePx = valueMaxPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) - { - intersectKeyPx = keyMaxPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - } - break; - } - case 8: // right edge - { - intersectKeyPx = keyMaxPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - break; - } - case 9: // bottom and right edge - { - intersectValuePx = valueMinPx; - intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); - if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) - { - intersectKeyPx = keyMaxPx; - intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); - } - break; - } - } - if (mKeyAxis->orientation() == Qt::Horizontal) - return QPointF(intersectKeyPx, intersectValuePx); - else - return QPointF(intersectValuePx, intersectKeyPx); -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - In situations where a single segment skips over multiple regions it might become necessary to add - extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment - doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. - This method provides these points that must be added, assuming the original segment doesn't - start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by - \ref getTraverseCornerPoints.) - - For example, consider a segment which directly goes from region 4 to 2 but originally is far out - to the top left such that it doesn't cross region 5. Naively optimizing these points by - projecting them on the top and left borders of region 5 will create a segment that surely crosses - 5, creating a visual artifact in the plot. This method prevents this by providing extra points at - the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without - traversing 5. -*/ -QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const -{ - QVector result; - switch (prevRegion) - { - case 1: - { - switch (currentRegion) - { - case 2: { result << coordsToPixels(keyMin, valueMax); break; } - case 4: { result << coordsToPixels(keyMin, valueMax); break; } - case 3: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); break; } - case 7: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); break; } - case 6: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } - case 8: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } - case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points - if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R - { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } - else - { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } - break; - } - } - break; - } - case 2: - { - switch (currentRegion) - { - case 1: { result << coordsToPixels(keyMin, valueMax); break; } - case 3: { result << coordsToPixels(keyMin, valueMin); break; } - case 4: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } - case 6: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } - case 7: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } - case 9: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - case 3: - { - switch (currentRegion) - { - case 2: { result << coordsToPixels(keyMin, valueMin); break; } - case 6: { result << coordsToPixels(keyMin, valueMin); break; } - case 1: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); break; } - case 9: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); break; } - case 4: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } - case 8: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } - case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points - if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R - { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } - else - { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } - break; - } - } - break; - } - case 4: - { - switch (currentRegion) - { - case 1: { result << coordsToPixels(keyMin, valueMax); break; } - case 7: { result << coordsToPixels(keyMax, valueMax); break; } - case 2: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } - case 8: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } - case 3: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } - case 9: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - case 5: - { - switch (currentRegion) - { - case 1: { result << coordsToPixels(keyMin, valueMax); break; } - case 7: { result << coordsToPixels(keyMax, valueMax); break; } - case 9: { result << coordsToPixels(keyMax, valueMin); break; } - case 3: { result << coordsToPixels(keyMin, valueMin); break; } - } - break; - } - case 6: - { - switch (currentRegion) - { - case 3: { result << coordsToPixels(keyMin, valueMin); break; } - case 9: { result << coordsToPixels(keyMax, valueMin); break; } - case 2: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } - case 8: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } - case 1: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } - case 7: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } - } - break; - } - case 7: - { - switch (currentRegion) - { - case 4: { result << coordsToPixels(keyMax, valueMax); break; } - case 8: { result << coordsToPixels(keyMax, valueMax); break; } - case 1: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); break; } - case 9: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); break; } - case 2: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } - case 6: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } - case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points - if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R - { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } - else - { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } - break; - } - } - break; - } - case 8: - { - switch (currentRegion) - { - case 7: { result << coordsToPixels(keyMax, valueMax); break; } - case 9: { result << coordsToPixels(keyMax, valueMin); break; } - case 4: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } - case 6: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } - case 1: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } - case 3: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } - } - break; - } - case 9: - { - switch (currentRegion) - { - case 6: { result << coordsToPixels(keyMax, valueMin); break; } - case 8: { result << coordsToPixels(keyMax, valueMin); break; } - case 3: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); break; } - case 7: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); break; } - case 2: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } - case 4: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } - case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points - if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R - { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } - else - { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } - break; - } - } - break; - } - } - return result; -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref - getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion - nor \a currentRegion is 5 itself. - - If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the - segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref - getTraverse). -*/ -bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const -{ - switch (prevRegion) - { - case 1: - { - switch (currentRegion) - { - case 4: - case 7: - case 2: - case 3: return false; - default: return true; - } - } - case 2: - { - switch (currentRegion) - { - case 1: - case 3: return false; - default: return true; - } - } - case 3: - { - switch (currentRegion) - { - case 1: - case 2: - case 6: - case 9: return false; - default: return true; - } - } - case 4: - { - switch (currentRegion) - { - case 1: - case 7: return false; - default: return true; - } - } - case 5: return false; // should never occur - case 6: - { - switch (currentRegion) - { - case 3: - case 9: return false; - default: return true; - } - } - case 7: - { - switch (currentRegion) - { - case 1: - case 4: - case 8: - case 9: return false; - default: return true; - } - } - case 8: - { - switch (currentRegion) - { - case 7: - case 9: return false; - default: return true; - } - } - case 9: - { - switch (currentRegion) - { - case 3: - case 6: - case 8: - case 7: return false; - default: return true; - } - } - default: return true; - } -} - - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - This method assumes that the \ref mayTraverse test has returned true, so there is a chance the - segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible - region 5. - - The return value of this method indicates whether the segment actually traverses region 5 or not. - - If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and - exit points of region 5. They will become the optimized points for that segment. -*/ -bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const -{ - // The intersection point interpolation here is done in pixel coordinates, so we don't need to - // differentiate between different axis scale types. Note that the nomenclature - // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be - // different in pixel coordinates (horz/vert key axes, reversed ranges) - - QList intersections; - const double valueMinPx = mValueAxis->coordToPixel(valueMin); - const double valueMaxPx = mValueAxis->coordToPixel(valueMax); - const double keyMinPx = mKeyAxis->coordToPixel(keyMin); - const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); - const double keyPx = mKeyAxis->coordToPixel(key); - const double valuePx = mValueAxis->coordToPixel(value); - const double prevKeyPx = mKeyAxis->coordToPixel(prevKey); - const double prevValuePx = mValueAxis->coordToPixel(prevValue); - if (qFuzzyIsNull(key-prevKey)) // line is parallel to value axis - { - // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMinPx) : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMaxPx) : QPointF(valueMaxPx, keyPx)); - } else if (qFuzzyIsNull(value-prevValue)) // line is parallel to key axis - { - // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, valuePx) : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, valuePx) : QPointF(valuePx, keyMaxPx)); - } else // line is skewed - { - double gamma; - double keyPerValuePx = (keyPx-prevKeyPx)/(valuePx-prevValuePx); - // check top of rect: - gamma = prevKeyPx + (valueMaxPx-prevValuePx)*keyPerValuePx; - if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMaxPx) : QPointF(valueMaxPx, gamma)); - // check bottom of rect: - gamma = prevKeyPx + (valueMinPx-prevValuePx)*keyPerValuePx; - if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMinPx) : QPointF(valueMinPx, gamma)); - const double valuePerKeyPx = 1.0/keyPerValuePx; - // check left of rect: - gamma = prevValuePx + (keyMinPx-prevKeyPx)*valuePerKeyPx; - if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, gamma) : QPointF(gamma, keyMinPx)); - // check right of rect: - gamma = prevValuePx + (keyMaxPx-prevKeyPx)*valuePerKeyPx; - if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed - intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, gamma) : QPointF(gamma, keyMaxPx)); - } - - // handle cases where found points isn't exactly 2: - if (intersections.size() > 2) - { - // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between: - double distSqrMax = 0; - QPointF pv1, pv2; - for (int i=0; i distSqrMax) - { - pv1 = intersections.at(i); - pv2 = intersections.at(k); - distSqrMax = distSqr; - } - } - } - intersections = QList() << pv1 << pv2; - } else if (intersections.size() != 2) - { - // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment - return false; - } - - // possibly re-sort points so optimized point segment has same direction as original segment: - double xDelta = keyPx-prevKeyPx; - double yDelta = valuePx-prevValuePx; - if (mKeyAxis->orientation() != Qt::Horizontal) - qSwap(xDelta, yDelta); - if (xDelta*(intersections.at(1).x()-intersections.at(0).x()) + yDelta*(intersections.at(1).y()-intersections.at(0).y()) < 0) // scalar product of both segments < 0 -> opposite direction - intersections.move(0, 1); - crossA = intersections.at(0); - crossB = intersections.at(1); - return true; -} - -/*! \internal - - This function is part of the curve optimization algorithm of \ref getCurveLines. - - This method assumes that the \ref getTraverse test has returned true, so the segment definitely - traverses the visible region 5 when going from \a prevRegion to \a currentRegion. - - In certain situations it is not sufficient to merely generate the entry and exit points of the - segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in - addition to traversing region 5, skips another region outside of region 5, which makes it - necessary to add an optimized corner point there (very similar to the job \ref - getOptimizedCornerPoints does for segments that are completely in outside regions and don't - traverse 5). - - As an example, consider a segment going from region 1 to region 6, traversing the lower left - corner of region 5. In this configuration, the segment additionally crosses the border between - region 1 and 2 before entering region 5. This makes it necessary to add an additional point in - the top left corner, before adding the optimized traverse points. So in this case, the output - parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be - empty. - - In some cases, such as when going from region 1 to 9, it may even be necessary to add additional - corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse - return the respective corner points. -*/ -void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const -{ - switch (prevRegion) - { - case 1: - { - switch (currentRegion) - { - case 6: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } - case 9: { beforeTraverse << coordsToPixels(keyMin, valueMax); afterTraverse << coordsToPixels(keyMax, valueMin); break; } - case 8: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } - } - break; - } - case 2: - { - switch (currentRegion) - { - case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } - case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - case 3: - { - switch (currentRegion) - { - case 4: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } - case 7: { beforeTraverse << coordsToPixels(keyMin, valueMin); afterTraverse << coordsToPixels(keyMax, valueMax); break; } - case 8: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } - } - break; - } - case 4: - { - switch (currentRegion) - { - case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } - case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - case 5: { break; } // shouldn't happen because this method only handles full traverses - case 6: - { - switch (currentRegion) - { - case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } - case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } - } - break; - } - case 7: - { - switch (currentRegion) - { - case 2: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } - case 3: { beforeTraverse << coordsToPixels(keyMax, valueMax); afterTraverse << coordsToPixels(keyMin, valueMin); break; } - case 6: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } - } - break; - } - case 8: - { - switch (currentRegion) - { - case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } - case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } - } - break; - } - case 9: - { - switch (currentRegion) - { - case 2: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } - case 1: { beforeTraverse << coordsToPixels(keyMax, valueMin); afterTraverse << coordsToPixels(keyMin, valueMax); break; } - case 4: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } - } - break; - } - } -} - -/*! \internal - - Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a - pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in - \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that - if the curve has a line representation, the returned distance may be smaller than the distance to - the \a closestData point, since the distance to the curve line is also taken into account. - - If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape - is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns - -1.0. -*/ -double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const -{ - closestData = mDataContainer->constEnd(); - if (mDataContainer->isEmpty()) - return -1.0; - if (mLineStyle == lsNone && mScatterStyle.isNone()) - return -1.0; - - if (mDataContainer->size() == 1) - { - QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value); - closestData = mDataContainer->constBegin(); - return QCPVector2D(dataPoint-pixelPoint).length(); - } - - // calculate minimum distances to curve data points and find closestData iterator: - double minDistSqr = std::numeric_limits::max(); - // iterate over found data points and then choose the one with the shortest distance to pos: - QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); - QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); - for (QCPCurveDataContainer::const_iterator it=begin; it!=end; ++it) - { - const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestData = it; - } - } - - // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point): - if (mLineStyle != lsNone) - { - QVector lines; - getCurveLines(&lines, QCPDataRange(0, dataCount()), mParentPlot->selectionTolerance()*1.2); // optimized lines outside axis rect shouldn't respond to clicks at the edge, so use 1.2*tolerance as pen width - for (int i=0; i QCPBarsGroup::bars() const - - Returns all bars currently in this group. - - \see bars(int index) -*/ - -/*! \fn int QCPBarsGroup::size() const - - Returns the number of QCPBars plottables that are part of this group. - -*/ - -/*! \fn bool QCPBarsGroup::isEmpty() const - - Returns whether this bars group is empty. - - \see size -*/ - -/*! \fn bool QCPBarsGroup::contains(QCPBars *bars) - - Returns whether the specified \a bars plottable is part of this group. - -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a new bars group for the specified QCustomPlot instance. -*/ -QCPBarsGroup::QCPBarsGroup(QCustomPlot *parentPlot) : - QObject(parentPlot), - mParentPlot(parentPlot), - mSpacingType(stAbsolute), - mSpacing(4) -{ -} - -QCPBarsGroup::~QCPBarsGroup() -{ - clear(); -} - -/*! - Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. - - The actual spacing can then be specified with \ref setSpacing. - - \see setSpacing -*/ -void QCPBarsGroup::setSpacingType(SpacingType spacingType) -{ - mSpacingType = spacingType; -} - -/*! - Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is - defined by the current \ref SpacingType, which can be set with \ref setSpacingType. - - \see setSpacingType -*/ -void QCPBarsGroup::setSpacing(double spacing) -{ - mSpacing = spacing; -} - -/*! - Returns the QCPBars instance with the specified \a index in this group. If no such QCPBars - exists, returns 0. - - \see bars(), size -*/ -QCPBars *QCPBarsGroup::bars(int index) const -{ - if (index >= 0 && index < mBars.size()) - { - return mBars.at(index); - } else - { - qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; - return 0; - } -} - -/*! - Removes all QCPBars plottables from this group. - - \see isEmpty -*/ -void QCPBarsGroup::clear() -{ - foreach (QCPBars *bars, mBars) // since foreach takes a copy, removing bars in the loop is okay - bars->setBarsGroup(0); // removes itself via removeBars -} - -/*! - Adds the specified \a bars plottable to this group. Alternatively, you can also use \ref - QCPBars::setBarsGroup on the \a bars instance. - - \see insert, remove -*/ -void QCPBarsGroup::append(QCPBars *bars) -{ - if (!bars) - { - qDebug() << Q_FUNC_INFO << "bars is 0"; - return; - } - - if (!mBars.contains(bars)) - bars->setBarsGroup(this); - else - qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast(bars); -} - -/*! - Inserts the specified \a bars plottable into this group at the specified index position \a i. - This gives you full control over the ordering of the bars. - - \a bars may already be part of this group. In that case, \a bars is just moved to the new index - position. - - \see append, remove -*/ -void QCPBarsGroup::insert(int i, QCPBars *bars) -{ - if (!bars) - { - qDebug() << Q_FUNC_INFO << "bars is 0"; - return; - } - - // first append to bars list normally: - if (!mBars.contains(bars)) - bars->setBarsGroup(this); - // then move to according position: - mBars.move(mBars.indexOf(bars), qBound(0, i, mBars.size()-1)); -} - -/*! - Removes the specified \a bars plottable from this group. - - \see contains, clear -*/ -void QCPBarsGroup::remove(QCPBars *bars) -{ - if (!bars) - { - qDebug() << Q_FUNC_INFO << "bars is 0"; - return; - } - - if (mBars.contains(bars)) - bars->setBarsGroup(0); - else - qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast(bars); -} - -/*! \internal - - Adds the specified \a bars to the internal mBars list of bars. This method does not change the - barsGroup property on \a bars. - - \see unregisterBars -*/ -void QCPBarsGroup::registerBars(QCPBars *bars) -{ - if (!mBars.contains(bars)) - mBars.append(bars); -} - -/*! \internal - - Removes the specified \a bars from the internal mBars list of bars. This method does not change - the barsGroup property on \a bars. - - \see registerBars -*/ -void QCPBarsGroup::unregisterBars(QCPBars *bars) -{ - mBars.removeOne(bars); -} - -/*! \internal - - Returns the pixel offset in the key dimension the specified \a bars plottable should have at the - given key coordinate \a keyCoord. The offset is relative to the pixel position of the key - coordinate \a keyCoord. -*/ -double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) -{ - // find list of all base bars in case some mBars are stacked: - QList baseBars; - foreach (const QCPBars *b, mBars) - { - while (b->barBelow()) - b = b->barBelow(); - if (!baseBars.contains(b)) - baseBars.append(b); - } - // find base bar this "bars" is stacked on: - const QCPBars *thisBase = bars; - while (thisBase->barBelow()) - thisBase = thisBase->barBelow(); - - // determine key pixel offset of this base bars considering all other base bars in this barsgroup: - double result = 0; - int index = baseBars.indexOf(thisBase); - if (index >= 0) - { - if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose) - { - return result; - } else - { - double lowerPixelWidth, upperPixelWidth; - int startIndex; - int dir = (index <= (baseBars.size()-1)/2) ? -1 : 1; // if bar is to lower keys of center, dir is negative - if (baseBars.size() % 2 == 0) // even number of bars - { - startIndex = baseBars.size()/2 + (dir < 0 ? -1 : 0); - result += getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing - } else // uneven number of bars - { - startIndex = (baseBars.size()-1)/2+dir; - baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); - result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar - result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing - } - for (int i = startIndex; i != index; i += dir) // add widths and spacings of bars in between center and our bars - { - baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); - result += qAbs(upperPixelWidth-lowerPixelWidth); - result += getPixelSpacing(baseBars.at(i), keyCoord); - } - // finally half of our bars width: - baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); - result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; - // correct sign of result depending on orientation and direction of key axis: - result *= dir*thisBase->keyAxis()->pixelOrientation(); - } - } - return result; -} - -/*! \internal - - Returns the spacing in pixels which is between this \a bars and the following one, both at the - key coordinate \a keyCoord. - - \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only - needed to get access to the key axis transformation and axis rect for the modes \ref - stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in - \ref stPlotCoords on a logarithmic axis. -*/ -double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) -{ - switch (mSpacingType) - { - case stAbsolute: - { - return mSpacing; - } - case stAxisRectRatio: - { - if (bars->keyAxis()->orientation() == Qt::Horizontal) - return bars->keyAxis()->axisRect()->width()*mSpacing; - else - return bars->keyAxis()->axisRect()->height()*mSpacing; - } - case stPlotCoords: - { - double keyPixel = bars->keyAxis()->coordToPixel(keyCoord); - return qAbs(bars->keyAxis()->coordToPixel(keyCoord+mSpacing)-keyPixel); - } - } - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPBarsData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPBarsData - \brief Holds the data of one single data point (one bar) for QCPBars. - - The stored data is: - \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey) - \li \a value: height coordinate on the value axis of this bar (this is the \a mainValue) - - The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for - \ref QCPDataContainer with \ref QCPBarsData as the DataType template parameter. See the - documentation there for an explanation regarding the data type's generic methods. - - \see QCPBarsDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPBarsData::sortKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPBarsData QCPBarsData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey. All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPBarsData::sortKeyIsMainKey() - - Since the member \a key is both the data point key coordinate and the data ordering parameter, - this method returns true. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPBarsData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPBarsData::mainValue() const - - Returns the \a value member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPBarsData::valueRange() const - - Returns a QCPRange with both lower and upper boundary set to \a value of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a bar data point with key and value set to zero. -*/ -QCPBarsData::QCPBarsData() : - key(0), - value(0) -{ -} - -/*! - Constructs a bar data point with the specified \a key and \a value. -*/ -QCPBarsData::QCPBarsData(double key, double value) : - key(key), - value(value) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPBars -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPBars - \brief A plottable representing a bar chart in a plot. - - \image html QCPBars.png - - To plot data, assign it with the \ref setData or \ref addData functions. - - \section qcpbars-appearance Changing the appearance - - The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). - The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. - - Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other - (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear - stacked. - - If you would like to group multiple QCPBars plottables together so they appear side by side as - shown below, use QCPBarsGroup. - - \image html QCPBarsGroup.png - - \section qcpbars-usage Usage - - Like all data representing objects in QCustomPlot, the QCPBars is a plottable - (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies - (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - - Usually, you first create an instance: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 - which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes - ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. - The newly created plottable can be modified, e.g.: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-2 -*/ - -/* start of documentation of inline functions */ - -/*! \fn QSharedPointer QCPBars::data() const - - Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may - use it to directly manipulate the data, which may be more convenient and faster than using the - regular \ref setData or \ref addData methods. -*/ - -/*! \fn QCPBars *QCPBars::barBelow() const - Returns the bars plottable that is directly below this bars plottable. - If there is no such plottable, returns 0. - - \see barAbove, moveBelow, moveAbove -*/ - -/*! \fn QCPBars *QCPBars::barAbove() const - Returns the bars plottable that is directly above this bars plottable. - If there is no such plottable, returns 0. - - \see barBelow, moveBelow, moveAbove -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a - keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually - but use QCustomPlot::removePlottable() instead. -*/ -QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis), - mWidth(0.75), - mWidthType(wtPlotCoords), - mBarsGroup(0), - mBaseValue(0), - mStackingGap(0) -{ - // modify inherited properties from abstract plottable: - mPen.setColor(Qt::blue); - mPen.setStyle(Qt::SolidLine); - mBrush.setColor(QColor(40, 50, 255, 30)); - mBrush.setStyle(Qt::SolidPattern); - mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); -} - -QCPBars::~QCPBars() -{ - setBarsGroup(0); - if (mBarBelow || mBarAbove) - connectBars(mBarBelow.data(), mBarAbove.data()); // take this bar out of any stacking -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPBars may share the same data container safely. - Modifying the data in the container will then affect all bars that share the container. Sharing - can be achieved by simply exchanging the data containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the bar's data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-2 - - \see addData -*/ -void QCPBars::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Replaces the current data with the provided points in \a keys and \a values. The provided - vectors should have equal length. Else, the number of added points will be the size of the - smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData -*/ -void QCPBars::setData(const QVector &keys, const QVector &values, bool alreadySorted) -{ - mDataContainer->clear(); - addData(keys, values, alreadySorted); -} - -/*! - Sets the width of the bars. - - How the number passed as \a width is interpreted (e.g. screen pixels, plot coordinates,...), - depends on the currently set width type, see \ref setWidthType and \ref WidthType. -*/ -void QCPBars::setWidth(double width) -{ - mWidth = width; -} - -/*! - Sets how the width of the bars is defined. See the documentation of \ref WidthType for an - explanation of the possible values for \a widthType. - - The default value is \ref wtPlotCoords. - - \see setWidth -*/ -void QCPBars::setWidthType(QCPBars::WidthType widthType) -{ - mWidthType = widthType; -} - -/*! - Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref - QCPBarsGroup::append. - - To remove this QCPBars from any group, set \a barsGroup to 0. -*/ -void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) -{ - // deregister at old group: - if (mBarsGroup) - mBarsGroup->unregisterBars(this); - mBarsGroup = barsGroup; - // register at new group: - if (mBarsGroup) - mBarsGroup->registerBars(this); -} - -/*! - Sets the base value of this bars plottable. - - The base value defines where on the value coordinate the bars start. How far the bars extend from - the base value is given by their individual value data. For example, if the base value is set to - 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at - 3. - - For stacked bars, only the base value of the bottom-most QCPBars has meaning. - - The default base value is 0. -*/ -void QCPBars::setBaseValue(double baseValue) -{ - mBaseValue = baseValue; -} - -/*! - If this bars plottable is stacked on top of another bars plottable (\ref moveAbove), this method - allows specifying a distance in \a pixels, by which the drawn bar rectangles will be separated by - the bars below it. -*/ -void QCPBars::setStackingGap(double pixels) -{ - mStackingGap = pixels; -} - -/*! \overload - - Adds the provided points in \a keys and \a values to the current data. The provided vectors - should have equal length. Else, the number of added points will be the size of the smallest - vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPBars::addData(const QVector &keys, const QVector &values, bool alreadySorted) -{ - if (keys.size() != values.size()) - qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); - const int n = qMin(keys.size(), values.size()); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->key = keys[i]; - it->value = values[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - Adds the provided data point as \a key and \a value to the current data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPBars::addData(double key, double value) -{ - mDataContainer->add(QCPBarsData(key, value)); -} - -/*! - Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear - below the bars of \a bars. The move target \a bars must use the same key and value axis as this - plottable. - - Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already - has a bars object below itself, this bars object is inserted between the two. If this bars object - is already between two other bars, the two other bars will be stacked on top of each other after - the operation. - - To remove this bars plottable from any stacking, set \a bars to 0. - - \see moveBelow, barAbove, barBelow -*/ -void QCPBars::moveBelow(QCPBars *bars) -{ - if (bars == this) return; - if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) - { - qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; - return; - } - // remove from stacking: - connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 - // if new bar given, insert this bar below it: - if (bars) - { - if (bars->mBarBelow) - connectBars(bars->mBarBelow.data(), this); - connectBars(this, bars); - } -} - -/*! - Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear - above the bars of \a bars. The move target \a bars must use the same key and value axis as this - plottable. - - Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already - has a bars object above itself, this bars object is inserted between the two. If this bars object - is already between two other bars, the two other bars will be stacked on top of each other after - the operation. - - To remove this bars plottable from any stacking, set \a bars to 0. - - \see moveBelow, barBelow, barAbove -*/ -void QCPBars::moveAbove(QCPBars *bars) -{ - if (bars == this) return; - if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) - { - qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; - return; - } - // remove from stacking: - connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 - // if new bar given, insert this bar above it: - if (bars) - { - if (bars->mBarAbove) - connectBars(this, bars->mBarAbove.data()); - connectBars(bars, this); - } -} - -/*! - \copydoc QCPPlottableInterface1D::selectTestRect -*/ -QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (rect.intersects(getBarRect(it->key, it->value))) - result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); - } - result.simplify(); - return result; -} - -/* inherits documentation from base class */ -double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - // get visible data range: - QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (getBarRect(it->key, it->value).contains(pos)) - { - if (details) - { - int pointIndex = it-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return mParentPlot->selectionTolerance()*0.99; - } - } - } - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - /* Note: If this QCPBars uses absolute pixels as width (or is in a QCPBarsGroup with spacing in - absolute pixels), using this method to adapt the key axis range to fit the bars into the - currently visible axis range will not work perfectly. Because in the moment the axis range is - changed to the new range, the fixed pixel widths/spacings will represent different coordinate - spans than before, which in turn would require a different key range to perfectly fit, and so on. - The only solution would be to iteratively approach the perfect fitting axis range, but the - mismatch isn't large enough in most applications, to warrant this here. If a user does need a - better fit, he should call the corresponding axis rescale multiple times in a row. - */ - QCPRange range; - range = mDataContainer->keyRange(foundRange, inSignDomain); - - // determine exact range of bars by including bar width and barsgroup offset: - if (foundRange && mKeyAxis) - { - double lowerPixelWidth, upperPixelWidth, keyPixel; - // lower range bound: - getPixelWidth(range.lower, lowerPixelWidth, upperPixelWidth); - keyPixel = mKeyAxis.data()->coordToPixel(range.lower) + lowerPixelWidth; - if (mBarsGroup) - keyPixel += mBarsGroup->keyPixelOffset(this, range.lower); - const double lowerCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); - if (!qIsNaN(lowerCorrected) && qIsFinite(lowerCorrected) && range.lower > lowerCorrected) - range.lower = lowerCorrected; - // upper range bound: - getPixelWidth(range.upper, lowerPixelWidth, upperPixelWidth); - keyPixel = mKeyAxis.data()->coordToPixel(range.upper) + upperPixelWidth; - if (mBarsGroup) - keyPixel += mBarsGroup->keyPixelOffset(this, range.upper); - const double upperCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); - if (!qIsNaN(upperCorrected) && qIsFinite(upperCorrected) && range.upper < upperCorrected) - range.upper = upperCorrected; - } - return range; -} - -/* inherits documentation from base class */ -QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - // Note: can't simply use mDataContainer->valueRange here because we need to - // take into account bar base value and possible stacking of multiple bars - QCPRange range; - range.lower = mBaseValue; - range.upper = mBaseValue; - bool haveLower = true; // set to true, because baseValue should always be visible in bar charts - bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts - QCPBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); - QCPBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); - if (inKeyRange != QCPRange()) - { - itBegin = mDataContainer->findBegin(inKeyRange.lower); - itEnd = mDataContainer->findEnd(inKeyRange.upper); - } - for (QCPBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - const double current = it->value + getStackedBaseValue(it->key, it->value >= 0); - if (qIsNaN(current)) continue; - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - } - - foundRange = true; // return true because bar charts always have the 0-line visible - return range; -} - -/* inherits documentation from base class */ -QPointF QCPBars::dataPixelPosition(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } - - const QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; - const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value); - const double keyPixel = keyAxis->coordToPixel(it->key) + (mBarsGroup ? mBarsGroup->keyPixelOffset(this, it->key) : 0); - if (keyAxis->orientation() == Qt::Horizontal) - return QPointF(keyPixel, valuePixel); - else - return QPointF(valuePixel, keyPixel); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return QPointF(); - } -} - -/* inherits documentation from base class */ -void QCPBars::draw(QCPPainter *painter) -{ - if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - if (mDataContainer->isEmpty()) return; - - QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - QCPBarsDataContainer::const_iterator begin = visibleBegin; - QCPBarsDataContainer::const_iterator end = visibleEnd; - mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); - if (begin == end) - continue; - - for (QCPBarsDataContainer::const_iterator it=begin; it!=end; ++it) - { - // check data validity if flag set: -#ifdef QCUSTOMPLOT_CHECK_DATA - if (QCP::isInvalidData(it->key, it->value)) - qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); -#endif - // draw bar: - if (isSelectedSegment && mSelectionDecorator) - { - mSelectionDecorator->applyBrush(painter); - mSelectionDecorator->applyPen(painter); - } else - { - painter->setBrush(mBrush); - painter->setPen(mPen); - } - applyDefaultAntialiasingHint(painter); - painter->drawPolygon(getBarRect(it->key, it->value)); - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - // draw filled rect: - applyDefaultAntialiasingHint(painter); - painter->setBrush(mBrush); - painter->setPen(mPen); - QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); - r.moveCenter(rect.center()); - painter->drawRect(r); -} - -/*! \internal - - called by \ref draw to determine which data (key) range is visible at the current key axis range - setting, so only that needs to be processed. It also takes into account the bar width. - - \a begin returns an iterator to the lowest data point that needs to be taken into account when - plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a - lower may still be just outside the visible range. - - \a end returns an iterator one higher than the highest visible data point. Same as before, \a end - may also lie just outside of the visible range. - - if the plottable contains no data, both \a begin and \a end point to constEnd. -*/ -void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const -{ - if (!mKeyAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key axis"; - begin = mDataContainer->constEnd(); - end = mDataContainer->constEnd(); - return; - } - if (mDataContainer->isEmpty()) - { - begin = mDataContainer->constEnd(); - end = mDataContainer->constEnd(); - return; - } - - // get visible data range as QMap iterators - begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower); - end = mDataContainer->findEnd(mKeyAxis.data()->range().upper); - double lowerPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().lower); - double upperPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().upper); - bool isVisible = false; - // walk left from begin to find lower bar that actually is completely outside visible pixel range: - QCPBarsDataContainer::const_iterator it = begin; - while (it != mDataContainer->constBegin()) - { - --it; - const QRectF barRect = getBarRect(it->key, it->value); - if (mKeyAxis.data()->orientation() == Qt::Horizontal) - isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.left() <= lowerPixelBound)); - else // keyaxis is vertical - isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.bottom() >= lowerPixelBound)); - if (isVisible) - begin = it; - else - break; - } - // walk right from ubound to find upper bar that actually is completely outside visible pixel range: - it = end; - while (it != mDataContainer->constEnd()) - { - const QRectF barRect = getBarRect(it->key, it->value); - if (mKeyAxis.data()->orientation() == Qt::Horizontal) - isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.right() >= upperPixelBound)); - else // keyaxis is vertical - isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.bottom() >= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.top() <= upperPixelBound)); - if (isVisible) - end = it+1; - else - break; - ++it; - } -} - -/*! \internal - - Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The - rect is shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref - setBaseValue), and to have non-overlapping border lines with the bars stacked below. -*/ -QRectF QCPBars::getBarRect(double key, double value) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } - - double lowerPixelWidth, upperPixelWidth; - getPixelWidth(key, lowerPixelWidth, upperPixelWidth); - double base = getStackedBaseValue(key, value >= 0); - double basePixel = valueAxis->coordToPixel(base); - double valuePixel = valueAxis->coordToPixel(base+value); - double keyPixel = keyAxis->coordToPixel(key); - if (mBarsGroup) - keyPixel += mBarsGroup->keyPixelOffset(this, key); - double bottomOffset = (mBarBelow && mPen != Qt::NoPen ? 1 : 0)*(mPen.isCosmetic() ? 1 : mPen.widthF()); - bottomOffset += mBarBelow ? mStackingGap : 0; - bottomOffset *= (value<0 ? -1 : 1)*valueAxis->pixelOrientation(); - if (qAbs(valuePixel-basePixel) <= qAbs(bottomOffset)) - bottomOffset = valuePixel-basePixel; - if (keyAxis->orientation() == Qt::Horizontal) - { - return QRectF(QPointF(keyPixel+lowerPixelWidth, valuePixel), QPointF(keyPixel+upperPixelWidth, basePixel+bottomOffset)).normalized(); - } else - { - return QRectF(QPointF(basePixel+bottomOffset, keyPixel+lowerPixelWidth), QPointF(valuePixel, keyPixel+upperPixelWidth)).normalized(); - } -} - -/*! \internal - - This function is used to determine the width of the bar at coordinate \a key, according to the - specified width (\ref setWidth) and width type (\ref setWidthType). - - The output parameters \a lower and \a upper return the number of pixels the bar extends to lower - and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a - lower is negative and \a upper positive). -*/ -void QCPBars::getPixelWidth(double key, double &lower, double &upper) const -{ - lower = 0; - upper = 0; - switch (mWidthType) - { - case wtAbsolute: - { - upper = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - lower = -upper; - break; - } - case wtAxisRectRatio: - { - if (mKeyAxis && mKeyAxis.data()->axisRect()) - { - if (mKeyAxis.data()->orientation() == Qt::Horizontal) - upper = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - else - upper = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - lower = -upper; - } else - qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; - break; - } - case wtPlotCoords: - { - if (mKeyAxis) - { - double keyPixel = mKeyAxis.data()->coordToPixel(key); - upper = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; - lower = mKeyAxis.data()->coordToPixel(key-mWidth*0.5)-keyPixel; - // no need to qSwap(lower, higher) when range reversed, because higher/lower are gained by - // coordinate transform which includes range direction - } else - qDebug() << Q_FUNC_INFO << "No key axis defined"; - break; - } - } -} - -/*! \internal - - This function is called to find at which value to start drawing the base of a bar at \a key, when - it is stacked on top of another QCPBars (e.g. with \ref moveAbove). - - positive and negative bars are separated per stack (positive are stacked above baseValue upwards, - negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the - bar for which we need the base value is negative, set \a positive to false. -*/ -double QCPBars::getStackedBaseValue(double key, bool positive) const -{ - if (mBarBelow) - { - double max = 0; // don't initialize with mBaseValue here because only base value of bottom-most bar has meaning in a bar stack - // find bars of mBarBelow that are approximately at key and find largest one: - double epsilon = qAbs(key)*(sizeof(key)==4 ? 1e-6 : 1e-14); // should be safe even when changed to use float at some point - if (key == 0) - epsilon = (sizeof(key)==4 ? 1e-6 : 1e-14); - QCPBarsDataContainer::const_iterator it = mBarBelow.data()->mDataContainer->findBegin(key-epsilon); - QCPBarsDataContainer::const_iterator itEnd = mBarBelow.data()->mDataContainer->findEnd(key+epsilon); - while (it != itEnd) - { - if (it->key > key-epsilon && it->key < key+epsilon) - { - if ((positive && it->value > max) || - (!positive && it->value < max)) - max = it->value; - } - ++it; - } - // recurse down the bar-stack to find the total height: - return max + mBarBelow.data()->getStackedBaseValue(key, positive); - } else - return mBaseValue; -} - -/*! \internal - - Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) - currently above lower and below upper will become disconnected to lower/upper. - - If lower is zero, upper will be disconnected at the bottom. - If upper is zero, lower will be disconnected at the top. -*/ -void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) -{ - if (!lower && !upper) return; - - if (!lower) // disconnect upper at bottom - { - // disconnect old bar below upper: - if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) - upper->mBarBelow.data()->mBarAbove = 0; - upper->mBarBelow = 0; - } else if (!upper) // disconnect lower at top - { - // disconnect old bar above lower: - if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) - lower->mBarAbove.data()->mBarBelow = 0; - lower->mBarAbove = 0; - } else // connect lower and upper - { - // disconnect old bar above lower: - if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) - lower->mBarAbove.data()->mBarBelow = 0; - // disconnect old bar below upper: - if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) - upper->mBarBelow.data()->mBarAbove = 0; - lower->mBarAbove = upper; - upper->mBarBelow = lower; - } -} -/* end of 'src/plottables/plottable-bars.cpp' */ - - -/* including file 'src/plottables/plottable-statisticalbox.cpp', size 28622 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPStatisticalBoxData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPStatisticalBoxData - \brief Holds the data of one single data point for QCPStatisticalBox. - - The stored data is: - - \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) - - \li \a minimum: the position of the lower whisker, typically the minimum measurement of the - sample that's not considered an outlier. - - \li \a lowerQuartile: the lower end of the box. The lower and the upper quartiles are the two - statistical quartiles around the median of the sample, they should contain 50% of the sample - data. - - \li \a median: the value of the median mark inside the quartile box. The median separates the - sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue) - - \li \a upperQuartile: the upper end of the box. The lower and the upper quartiles are the two - statistical quartiles around the median of the sample, they should contain 50% of the sample - data. - - \li \a maximum: the position of the upper whisker, typically the maximum measurement of the - sample that's not considered an outlier. - - \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key - coordinate of this data point (see \ref QCPStatisticalBox::setOutlierStyle) - - The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a - typedef for \ref QCPDataContainer with \ref QCPStatisticalBoxData as the DataType template - parameter. See the documentation there for an explanation regarding the data type's generic - methods. - - \see QCPStatisticalBoxDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPStatisticalBoxData::sortKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPStatisticalBoxData QCPStatisticalBoxData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey. All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPStatisticalBoxData::sortKeyIsMainKey() - - Since the member \a key is both the data point key coordinate and the data ordering parameter, - this method returns true. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPStatisticalBoxData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPStatisticalBoxData::mainValue() const - - Returns the \a median member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPStatisticalBoxData::valueRange() const - - Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box - data point, possibly further expanded by outliers. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a data point with key and all values set to zero. -*/ -QCPStatisticalBoxData::QCPStatisticalBoxData() : - key(0), - minimum(0), - lowerQuartile(0), - median(0), - upperQuartile(0), - maximum(0) -{ -} - -/*! - Constructs a data point with the specified \a key, \a minimum, \a lowerQuartile, \a median, \a - upperQuartile, \a maximum and optionally a number of \a outliers. -*/ -QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) : - key(key), - minimum(minimum), - lowerQuartile(lowerQuartile), - median(median), - upperQuartile(upperQuartile), - maximum(maximum), - outliers(outliers) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPStatisticalBox -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPStatisticalBox - \brief A plottable representing a single statistical box in a plot. - - \image html QCPStatisticalBox.png - - To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can - also access and modify the data via the \ref data method, which returns a pointer to the internal - \ref QCPStatisticalBoxDataContainer. - - Additionally each data point can itself have a list of outliers, drawn as scatter points at the - key coordinate of the respective statistical box data point. They can either be set by using the - respective \ref addData(double,double,double,double,double,double,const QVector&) - "addData" method or accessing the individual data points through \ref data, and setting the - QVector outliers of the data points directly. - - \section qcpstatisticalbox-appearance Changing the appearance - - The appearance of each data point box, ranging from the lower to the upper quartile, is - controlled via \ref setPen and \ref setBrush. You may change the width of the boxes with \ref - setWidth in plot coordinates. - - Each data point's visual representation also consists of two whiskers. Whiskers are the lines - which reach from the upper quartile to the maximum, and from the lower quartile to the minimum. - The appearance of the whiskers can be modified with: \ref setWhiskerPen, \ref setWhiskerBarPen, - \ref setWhiskerWidth. The whisker width is the width of the bar perpendicular to the whisker at - the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set - the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a - few pixels due to the pen cap being not perfectly flat. - - The median indicator line inside the box has its own pen, \ref setMedianPen. - - The outlier data points are drawn as normal scatter points. Their look can be controlled with - \ref setOutlierStyle - - \section qcpstatisticalbox-usage Usage - - Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable - (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies - (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - - Usually, you first create an instance: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 - which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes - ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. - The newly created plottable can be modified, e.g.: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-2 -*/ - -/* start documentation of inline functions */ - -/*! \fn QSharedPointer QCPStatisticalBox::data() const - - Returns a shared pointer to the internal data storage of type \ref - QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more - convenient and faster than using the regular \ref setData or \ref addData methods. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its - value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and - not have the same orientation. If either of these restrictions is violated, a corresponding - message is printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred - from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not - delete it manually but use QCustomPlot::removePlottable() instead. -*/ -QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis), - mWidth(0.5), - mWhiskerWidth(0.2), - mWhiskerPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap), - mWhiskerBarPen(Qt::black), - mWhiskerAntialiased(false), - mMedianPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap), - mOutlierStyle(QCPScatterStyle::ssCircle, Qt::blue, 6) -{ - setPen(QPen(Qt::black)); - setBrush(Qt::NoBrush); -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container - safely. Modifying the data in the container will then affect all statistical boxes that share the - container. Sharing can be achieved by simply exchanging the data containers wrapped in shared - pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the statistical box data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-2 - - \see addData -*/ -void QCPStatisticalBox::setData(QSharedPointer data) -{ - mDataContainer = data; -} -/*! \overload - - Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a - median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the - number of added points will be the size of the smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData -*/ -void QCPStatisticalBox::setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) -{ - mDataContainer->clear(); - addData(keys, minimum, lowerQuartile, median, upperQuartile, maximum, alreadySorted); -} - -/*! - Sets the width of the boxes in key coordinates. - - \see setWhiskerWidth -*/ -void QCPStatisticalBox::setWidth(double width) -{ - mWidth = width; -} - -/*! - Sets the width of the whiskers in key coordinates. - - Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower - quartile to the minimum. - - \see setWidth -*/ -void QCPStatisticalBox::setWhiskerWidth(double width) -{ - mWhiskerWidth = width; -} - -/*! - Sets the pen used for drawing the whisker backbone. - - Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower - quartile to the minimum. - - Make sure to set the \c capStyle of the passed \a pen to \c Qt::FlatCap. Otherwise the backbone - line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat. - - \see setWhiskerBarPen -*/ -void QCPStatisticalBox::setWhiskerPen(const QPen &pen) -{ - mWhiskerPen = pen; -} - -/*! - Sets the pen used for drawing the whisker bars. Those are the lines parallel to the key axis at - each end of the whisker backbone. - - Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower - quartile to the minimum. - - \see setWhiskerPen -*/ -void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) -{ - mWhiskerBarPen = pen; -} - -/*! - Sets whether the statistical boxes whiskers are drawn with antialiasing or not. - - Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and - QCustomPlot::setNotAntialiasedElements. -*/ -void QCPStatisticalBox::setWhiskerAntialiased(bool enabled) -{ - mWhiskerAntialiased = enabled; -} - -/*! - Sets the pen used for drawing the median indicator line inside the statistical boxes. -*/ -void QCPStatisticalBox::setMedianPen(const QPen &pen) -{ - mMedianPen = pen; -} - -/*! - Sets the appearance of the outlier data points. - - Outliers can be specified with the method - \ref addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) -*/ -void QCPStatisticalBox::setOutlierStyle(const QCPScatterStyle &style) -{ - mOutlierStyle = style; -} - -/*! \overload - - Adds the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and - \a maximum to the current data. The provided vectors should have equal length. Else, the number - of added points will be the size of the smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPStatisticalBox::addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) -{ - if (keys.size() != minimum.size() || minimum.size() != lowerQuartile.size() || lowerQuartile.size() != median.size() || - median.size() != upperQuartile.size() || upperQuartile.size() != maximum.size() || maximum.size() != keys.size()) - qDebug() << Q_FUNC_INFO << "keys, minimum, lowerQuartile, median, upperQuartile, maximum have different sizes:" - << keys.size() << minimum.size() << lowerQuartile.size() << median.size() << upperQuartile.size() << maximum.size(); - const int n = qMin(keys.size(), qMin(minimum.size(), qMin(lowerQuartile.size(), qMin(median.size(), qMin(upperQuartile.size(), maximum.size()))))); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->key = keys[i]; - it->minimum = minimum[i]; - it->lowerQuartile = lowerQuartile[i]; - it->median = median[i]; - it->upperQuartile = upperQuartile[i]; - it->maximum = maximum[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - - Adds the provided data point as \a key, \a minimum, \a lowerQuartile, \a median, \a upperQuartile - and \a maximum to the current data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. -*/ -void QCPStatisticalBox::addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) -{ - mDataContainer->add(QCPStatisticalBoxData(key, minimum, lowerQuartile, median, upperQuartile, maximum, outliers)); -} - -/*! - \copydoc QCPPlottableInterface1D::selectTestRect -*/ -QCPDataSelection QCPStatisticalBox::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (rect.intersects(getQuartileBox(it))) - result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); - } - result.simplify(); - return result; -} - -/* inherits documentation from base class */ -double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis->axisRect()->rect().contains(pos.toPoint())) - { - // get visible data range: - QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; - QCPStatisticalBoxDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - getVisibleDataBounds(visibleBegin, visibleEnd); - double minDistSqr = std::numeric_limits::max(); - for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (getQuartileBox(it).contains(pos)) // quartile box - { - double currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } else // whiskers - { - const QVector whiskerBackbones(getWhiskerBackboneLines(it)); - for (int i=0; iconstBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return qSqrt(minDistSqr); - } - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPStatisticalBox::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); - // determine exact range by including width of bars/flags: - if (foundRange) - { - if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) - range.lower -= mWidth*0.5; - if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) - range.upper += mWidth*0.5; - } - return range; -} - -/* inherits documentation from base class */ -QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); -} - -/* inherits documentation from base class */ -void QCPStatisticalBox::draw(QCPPainter *painter) -{ - if (mDataContainer->isEmpty()) return; - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - QCPStatisticalBoxDataContainer::const_iterator begin = visibleBegin; - QCPStatisticalBoxDataContainer::const_iterator end = visibleEnd; - mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); - if (begin == end) - continue; - - for (QCPStatisticalBoxDataContainer::const_iterator it=begin; it!=end; ++it) - { - // check data validity if flag set: -# ifdef QCUSTOMPLOT_CHECK_DATA - if (QCP::isInvalidData(it->key, it->minimum) || - QCP::isInvalidData(it->lowerQuartile, it->median) || - QCP::isInvalidData(it->upperQuartile, it->maximum)) - qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range has invalid data." << "Plottable name:" << name(); - for (int i=0; ioutliers.size(); ++i) - if (QCP::isInvalidData(it->outliers.at(i))) - qDebug() << Q_FUNC_INFO << "Data point outlier at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); -# endif - - if (isSelectedSegment && mSelectionDecorator) - { - mSelectionDecorator->applyPen(painter); - mSelectionDecorator->applyBrush(painter); - } else - { - painter->setPen(mPen); - painter->setBrush(mBrush); - } - QCPScatterStyle finalOutlierStyle = mOutlierStyle; - if (isSelectedSegment && mSelectionDecorator) - finalOutlierStyle = mSelectionDecorator->getFinalScatterStyle(mOutlierStyle); - drawStatisticalBox(painter, it, finalOutlierStyle); - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - // draw filled rect: - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - painter->setBrush(mBrush); - QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); - r.moveCenter(rect.center()); - painter->drawRect(r); -} - -/*! - Draws the graphical representation of a single statistical box with the data given by the - iterator \a it with the provided \a painter. - - If the statistical box has a set of outlier data points, they are drawn with \a outlierStyle. - - \see getQuartileBox, getWhiskerBackboneLines, getWhiskerBarLines -*/ -void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const -{ - // draw quartile box: - applyDefaultAntialiasingHint(painter); - const QRectF quartileBox = getQuartileBox(it); - painter->drawRect(quartileBox); - // draw median line with cliprect set to quartile box: - painter->save(); - painter->setClipRect(quartileBox, Qt::IntersectClip); - painter->setPen(mMedianPen); - painter->drawLine(QLineF(coordsToPixels(it->key-mWidth*0.5, it->median), coordsToPixels(it->key+mWidth*0.5, it->median))); - painter->restore(); - // draw whisker lines: - applyAntialiasingHint(painter, mWhiskerAntialiased, QCP::aePlottables); - painter->setPen(mWhiskerPen); - painter->drawLines(getWhiskerBackboneLines(it)); - painter->setPen(mWhiskerBarPen); - painter->drawLines(getWhiskerBarLines(it)); - // draw outliers: - applyScattersAntialiasingHint(painter); - outlierStyle.applyTo(painter, mPen); - for (int i=0; ioutliers.size(); ++i) - outlierStyle.drawShape(painter, coordsToPixels(it->key, it->outliers.at(i))); -} - -/*! \internal - - called by \ref draw to determine which data (key) range is visible at the current key axis range - setting, so only that needs to be processed. It also takes into account the bar width. - - \a begin returns an iterator to the lowest data point that needs to be taken into account when - plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a - lower may still be just outside the visible range. - - \a end returns an iterator one higher than the highest visible data point. Same as before, \a end - may also lie just outside of the visible range. - - if the plottable contains no data, both \a begin and \a end point to constEnd. -*/ -void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const -{ - if (!mKeyAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key axis"; - begin = mDataContainer->constEnd(); - end = mDataContainer->constEnd(); - return; - } - begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of box to include partially visible data points - end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of box to include partially visible data points -} - -/*! \internal - - Returns the box in plot coordinates (keys in x, values in y of the returned rect) that covers the - value range from the lower to the upper quartile, of the data given by \a it. - - \see drawStatisticalBox, getWhiskerBackboneLines, getWhiskerBarLines -*/ -QRectF QCPStatisticalBox::getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const -{ - QRectF result; - result.setTopLeft(coordsToPixels(it->key-mWidth*0.5, it->upperQuartile)); - result.setBottomRight(coordsToPixels(it->key+mWidth*0.5, it->lowerQuartile)); - return result; -} - -/*! \internal - - Returns the whisker backbones (keys in x, values in y of the returned lines) that cover the value - range from the minimum to the lower quartile, and from the upper quartile to the maximum of the - data given by \a it. - - \see drawStatisticalBox, getQuartileBox, getWhiskerBarLines -*/ -QVector QCPStatisticalBox::getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const -{ - QVector result(2); - result[0].setPoints(coordsToPixels(it->key, it->lowerQuartile), coordsToPixels(it->key, it->minimum)); // min backbone - result[1].setPoints(coordsToPixels(it->key, it->upperQuartile), coordsToPixels(it->key, it->maximum)); // max backbone - return result; -} - -/*! \internal - - Returns the whisker bars (keys in x, values in y of the returned lines) that are placed at the - end of the whisker backbones, at the minimum and maximum of the data given by \a it. - - \see drawStatisticalBox, getQuartileBox, getWhiskerBackboneLines -*/ -QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const -{ - QVector result(2); - result[0].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->minimum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->minimum)); // min bar - result[1].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->maximum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->maximum)); // max bar - return result; -} -/* end of 'src/plottables/plottable-statisticalbox.cpp' */ - - -/* including file 'src/plottables/plottable-colormap.cpp', size 47881 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPColorMapData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPColorMapData - \brief Holds the two-dimensional data of a QCPColorMap plottable. - - This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref - QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a - color, depending on the value. - - The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). - Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref - setKeyRange, \ref setValueRange). - - The data cells can be accessed in two ways: They can be directly addressed by an integer index - with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot - coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are - provided by the functions \ref coordToCell and \ref cellToCoord. - - A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if - allocated) has the same size as the data map. It can be accessed via \ref setAlpha, \ref - fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on - the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map. - - This class also buffers the minimum and maximum values that are in the data set, to provide - QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value - that is greater than the current maximum increases this maximum to the new value. However, - setting the cell that currently holds the maximum value to a smaller value doesn't decrease the - maximum again, because finding the true new maximum would require going through the entire data - array, which might be time consuming. The same holds for the data minimum. This functionality is - given by \ref recalculateDataBounds, such that you can decide when it is sensible to find the - true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience - parameter \a recalculateDataBounds which may be set to true to automatically call \ref - recalculateDataBounds internally. -*/ - -/* start of documentation of inline functions */ - -/*! \fn bool QCPColorMapData::isEmpty() const - - Returns whether this instance carries no data. This is equivalent to having a size where at least - one of the dimensions is 0 (see \ref setSize). -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction - and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap - at the coordinates \a keyRange and \a valueRange. - - \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange -*/ -QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : - mKeySize(0), - mValueSize(0), - mKeyRange(keyRange), - mValueRange(valueRange), - mIsEmpty(true), - mData(0), - mAlpha(0), - mDataModified(true) -{ - setSize(keySize, valueSize); - fill(0); -} - -QCPColorMapData::~QCPColorMapData() -{ - if (mData) - delete[] mData; - if (mAlpha) - delete[] mAlpha; -} - -/*! - Constructs a new QCPColorMapData instance copying the data and range of \a other. -*/ -QCPColorMapData::QCPColorMapData(const QCPColorMapData &other) : - mKeySize(0), - mValueSize(0), - mIsEmpty(true), - mData(0), - mAlpha(0), - mDataModified(true) -{ - *this = other; -} - -/*! - Overwrites this color map data instance with the data stored in \a other. The alpha map state is - transferred, too. -*/ -QCPColorMapData &QCPColorMapData::operator=(const QCPColorMapData &other) -{ - if (&other != this) - { - const int keySize = other.keySize(); - const int valueSize = other.valueSize(); - if (!other.mAlpha && mAlpha) - clearAlpha(); - setSize(keySize, valueSize); - if (other.mAlpha && !mAlpha) - createAlpha(false); - setRange(other.keyRange(), other.valueRange()); - if (!isEmpty()) - { - memcpy(mData, other.mData, sizeof(mData[0])*keySize*valueSize); - if (mAlpha) - memcpy(mAlpha, other.mAlpha, sizeof(mAlpha[0])*keySize*valueSize); - } - mDataBounds = other.mDataBounds; - mDataModified = true; - } - return *this; -} - -/* undocumented getter */ -double QCPColorMapData::data(double key, double value) -{ - int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; - int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; - if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) - return mData[valueCell*mKeySize + keyCell]; - else - return 0; -} - -/* undocumented getter */ -double QCPColorMapData::cell(int keyIndex, int valueIndex) -{ - if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) - return mData[valueIndex*mKeySize + keyIndex]; - else - return 0; -} - -/*! - Returns the alpha map value of the cell with the indices \a keyIndex and \a valueIndex. - - If this color map data doesn't have an alpha map (because \ref setAlpha was never called after - creation or after a call to \ref clearAlpha), returns 255, which corresponds to full opacity. - - \see setAlpha -*/ -unsigned char QCPColorMapData::alpha(int keyIndex, int valueIndex) -{ - if (mAlpha && keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) - return mAlpha[valueIndex*mKeySize + keyIndex]; - else - return 255; -} - -/*! - Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in - the value dimension. - - The current data is discarded and the map cells are set to 0, unless the map had already the - requested size. - - Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref - isEmpty returns true. - - \see setRange, setKeySize, setValueSize -*/ -void QCPColorMapData::setSize(int keySize, int valueSize) -{ - if (keySize != mKeySize || valueSize != mValueSize) - { - mKeySize = keySize; - mValueSize = valueSize; - if (mData) - delete[] mData; - mIsEmpty = mKeySize == 0 || mValueSize == 0; - if (!mIsEmpty) - { -#ifdef __EXCEPTIONS - try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message -#endif - mData = new double[mKeySize*mValueSize]; -#ifdef __EXCEPTIONS - } catch (...) { mData = 0; } -#endif - if (mData) - fill(0); - else - qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; - } else - mData = 0; - - if (mAlpha) // if we had an alpha map, recreate it with new size - createAlpha(); - - mDataModified = true; - } -} - -/*! - Resizes the data array to have \a keySize cells in the key dimension. - - The current data is discarded and the map cells are set to 0, unless the map had already the - requested size. - - Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. - - \see setKeyRange, setSize, setValueSize -*/ -void QCPColorMapData::setKeySize(int keySize) -{ - setSize(keySize, mValueSize); -} - -/*! - Resizes the data array to have \a valueSize cells in the value dimension. - - The current data is discarded and the map cells are set to 0, unless the map had already the - requested size. - - Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. - - \see setValueRange, setSize, setKeySize -*/ -void QCPColorMapData::setValueSize(int valueSize) -{ - setSize(mKeySize, valueSize); -} - -/*! - Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area - covered by the color map in plot coordinates. - - The outer cells will be centered on the range boundaries given to this function. For example, if - the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will - be cells centered on the key coordinates 2, 2.5 and 3. - - \see setSize -*/ -void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) -{ - setKeyRange(keyRange); - setValueRange(valueRange); -} - -/*! - Sets the coordinate range the data shall be distributed over in the key dimension. Together with - the value range, This defines the rectangular area covered by the color map in plot coordinates. - - The outer cells will be centered on the range boundaries given to this function. For example, if - the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will - be cells centered on the key coordinates 2, 2.5 and 3. - - \see setRange, setValueRange, setSize -*/ -void QCPColorMapData::setKeyRange(const QCPRange &keyRange) -{ - mKeyRange = keyRange; -} - -/*! - Sets the coordinate range the data shall be distributed over in the value dimension. Together with - the key range, This defines the rectangular area covered by the color map in plot coordinates. - - The outer cells will be centered on the range boundaries given to this function. For example, if - the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there - will be cells centered on the value coordinates 2, 2.5 and 3. - - \see setRange, setKeyRange, setSize -*/ -void QCPColorMapData::setValueRange(const QCPRange &valueRange) -{ - mValueRange = valueRange; -} - -/*! - Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a - z. - - \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or - value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, - you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to - determine the cell index. Rather directly access the cell index with \ref - QCPColorMapData::setCell. - - \see setCell, setRange -*/ -void QCPColorMapData::setData(double key, double value, double z) -{ - int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; - int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; - if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) - { - mData[valueCell*mKeySize + keyCell] = z; - if (z < mDataBounds.lower) - mDataBounds.lower = z; - if (z > mDataBounds.upper) - mDataBounds.upper = z; - mDataModified = true; - } -} - -/*! - Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices - enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see - \ref setSize). - - In the standard plot configuration (horizontal key axis and vertical value axis, both not - range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with - indices (keySize-1, valueSize-1) is in the top right corner of the color map. - - \see setData, setSize -*/ -void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) -{ - if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) - { - mData[valueIndex*mKeySize + keyIndex] = z; - if (z < mDataBounds.lower) - mDataBounds.lower = z; - if (z > mDataBounds.upper) - mDataBounds.upper = z; - mDataModified = true; - } else - qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; -} - -/*! - Sets the alpha of the color map cell given by \a keyIndex and \a valueIndex to \a alpha. A value - of 0 for \a alpha results in a fully transparent cell, and a value of 255 results in a fully - opaque cell. - - If an alpha map doesn't exist yet for this color map data, it will be created here. If you wish - to restore full opacity and free any allocated memory of the alpha map, call \ref clearAlpha. - - Note that the cell-wise alpha which can be configured here is independent of any alpha configured - in the color map's gradient (\ref QCPColorGradient). If a cell is affected both by the cell-wise - and gradient alpha, the alpha values will be blended accordingly during rendering of the color - map. - - \see fillAlpha, clearAlpha -*/ -void QCPColorMapData::setAlpha(int keyIndex, int valueIndex, unsigned char alpha) -{ - if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) - { - if (mAlpha || createAlpha()) - { - mAlpha[valueIndex*mKeySize + keyIndex] = alpha; - mDataModified = true; - } - } else - qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; -} - -/*! - Goes through the data and updates the buffered minimum and maximum data values. - - Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange - and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten - with a smaller or larger value respectively, since the buffered maximum/minimum values have been - updated the last time. Why this is the case is explained in the class description (\ref - QCPColorMapData). - - Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a - recalculateDataBounds for convenience. Setting this to true will call this method for you, before - doing the rescale. -*/ -void QCPColorMapData::recalculateDataBounds() -{ - if (mKeySize > 0 && mValueSize > 0) - { - double minHeight = mData[0]; - double maxHeight = mData[0]; - const int dataCount = mValueSize*mKeySize; - for (int i=0; i maxHeight) - maxHeight = mData[i]; - if (mData[i] < minHeight) - minHeight = mData[i]; - } - mDataBounds.lower = minHeight; - mDataBounds.upper = maxHeight; - } -} - -/*! - Frees the internal data memory. - - This is equivalent to calling \ref setSize "setSize(0, 0)". -*/ -void QCPColorMapData::clear() -{ - setSize(0, 0); -} - -/*! - Frees the internal alpha map. The color map will have full opacity again. -*/ -void QCPColorMapData::clearAlpha() -{ - if (mAlpha) - { - delete[] mAlpha; - mAlpha = 0; - mDataModified = true; - } -} - -/*! - Sets all cells to the value \a z. -*/ -void QCPColorMapData::fill(double z) -{ - const int dataCount = mValueSize*mKeySize; - for (int i=0; i(data); - return; - } - if (copy) - { - *mMapData = *data; - } else - { - delete mMapData; - mMapData = data; - } - mMapImageInvalidated = true; -} - -/*! - Sets the data range of this color map to \a dataRange. The data range defines which data values - are mapped to the color gradient. - - To make the data range span the full range of the data set, use \ref rescaleDataRange. - - \see QCPColorScale::setDataRange -*/ -void QCPColorMap::setDataRange(const QCPRange &dataRange) -{ - if (!QCPRange::validRange(dataRange)) return; - if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) - { - if (mDataScaleType == QCPAxis::stLogarithmic) - mDataRange = dataRange.sanitizedForLogScale(); - else - mDataRange = dataRange.sanitizedForLinScale(); - mMapImageInvalidated = true; - emit dataRangeChanged(mDataRange); - } -} - -/*! - Sets whether the data is correlated with the color gradient linearly or logarithmically. - - \see QCPColorScale::setDataScaleType -*/ -void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) -{ - if (mDataScaleType != scaleType) - { - mDataScaleType = scaleType; - mMapImageInvalidated = true; - emit dataScaleTypeChanged(mDataScaleType); - if (mDataScaleType == QCPAxis::stLogarithmic) - setDataRange(mDataRange.sanitizedForLogScale()); - } -} - -/*! - Sets the color gradient that is used to represent the data. For more details on how to create an - own gradient or use one of the preset gradients, see \ref QCPColorGradient. - - The colors defined by the gradient will be used to represent data values in the currently set - data range, see \ref setDataRange. Data points that are outside this data range will either be - colored uniformly with the respective gradient boundary color, or the gradient will repeat, - depending on \ref QCPColorGradient::setPeriodic. - - \see QCPColorScale::setGradient -*/ -void QCPColorMap::setGradient(const QCPColorGradient &gradient) -{ - if (mGradient != gradient) - { - mGradient = gradient; - mMapImageInvalidated = true; - emit gradientChanged(mGradient); - } -} - -/*! - Sets whether the color map image shall use bicubic interpolation when displaying the color map - shrinked or expanded, and not at a 1:1 pixel-to-data scale. - - \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" -*/ -void QCPColorMap::setInterpolate(bool enabled) -{ - mInterpolate = enabled; - mMapImageInvalidated = true; // because oversampling factors might need to change -} - -/*! - Sets whether the outer most data rows and columns are clipped to the specified key and value - range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). - - if \a enabled is set to false, the data points at the border of the color map are drawn with the - same width and height as all other data points. Since the data points are represented by - rectangles of one color centered on the data coordinate, this means that the shown color map - extends by half a data point over the specified key/value range in each direction. - - \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" -*/ -void QCPColorMap::setTightBoundary(bool enabled) -{ - mTightBoundary = enabled; -} - -/*! - Associates the color scale \a colorScale with this color map. - - This means that both the color scale and the color map synchronize their gradient, data range and - data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps - can be associated with one single color scale. This causes the color maps to also synchronize - those properties, via the mutual color scale. - - This function causes the color map to adopt the current color gradient, data range and data scale - type of \a colorScale. After this call, you may change these properties at either the color map - or the color scale, and the setting will be applied to both. - - Pass 0 as \a colorScale to disconnect the color scale from this color map again. -*/ -void QCPColorMap::setColorScale(QCPColorScale *colorScale) -{ - if (mColorScale) // unconnect signals from old color scale - { - disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); - disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); - disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); - disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); - disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); - disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); - } - mColorScale = colorScale; - if (mColorScale) // connect signals to new color scale - { - setGradient(mColorScale.data()->gradient()); - setDataRange(mColorScale.data()->dataRange()); - setDataScaleType(mColorScale.data()->dataScaleType()); - connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); - connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); - connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); - connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); - connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); - connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); - } -} - -/*! - Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the - current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, - only for the third data dimension of the color map. - - The minimum and maximum values of the data set are buffered in the internal QCPColorMapData - instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref - QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For - performance reasons, however, they are only updated in an expanding fashion. So the buffered - maximum can only increase and the buffered minimum can only decrease. In consequence, changes to - the data that actually lower the maximum of the data set (by overwriting the cell holding the - current maximum with a smaller value), aren't recognized and the buffered maximum overestimates - the true maximum of the data set. The same happens for the buffered minimum. To recalculate the - true minimum and maximum by explicitly looking at each cell, the method - QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a - recalculateDataBounds calls this method before setting the data range to the buffered minimum and - maximum. - - \see setDataRange -*/ -void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) -{ - if (recalculateDataBounds) - mMapData->recalculateDataBounds(); - setDataRange(mMapData->dataBounds()); -} - -/*! - Takes the current appearance of the color map and updates the legend icon, which is used to - represent this color map in the legend (see \ref QCPLegend). - - The \a transformMode specifies whether the rescaling is done by a faster, low quality image - scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm - (Qt::SmoothTransformation). - - The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to - the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured - legend icon size, the thumb will be rescaled during drawing of the legend item. - - \see setDataRange -*/ -void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) -{ - if (mMapImage.isNull() && !data()->isEmpty()) - updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) - - if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again - { - bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); - bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); - mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); - } -} - -/* inherits documentation from base class */ -double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if ((onlySelectable && mSelectable == QCP::stNone) || mMapData->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - double posKey, posValue; - pixelsToCoords(pos, posKey, posValue); - if (mMapData->keyRange().contains(posKey) && mMapData->valueRange().contains(posValue)) - { - if (details) - details->setValue(QCPDataSelection(QCPDataRange(0, 1))); // temporary solution, to facilitate whole-plottable selection. Replace in future version with segmented 2D selection. - return mParentPlot->selectionTolerance()*0.99; - } - } - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPColorMap::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - foundRange = true; - QCPRange result = mMapData->keyRange(); - result.normalize(); - if (inSignDomain == QCP::sdPositive) - { - if (result.lower <= 0 && result.upper > 0) - result.lower = result.upper*1e-3; - else if (result.lower <= 0 && result.upper <= 0) - foundRange = false; - } else if (inSignDomain == QCP::sdNegative) - { - if (result.upper >= 0 && result.lower < 0) - result.upper = result.lower*1e-3; - else if (result.upper >= 0 && result.lower >= 0) - foundRange = false; - } - return result; -} - -/* inherits documentation from base class */ -QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - if (inKeyRange != QCPRange()) - { - if (mMapData->keyRange().upper < inKeyRange.lower || mMapData->keyRange().lower > inKeyRange.upper) - { - foundRange = false; - return QCPRange(); - } - } - - foundRange = true; - QCPRange result = mMapData->valueRange(); - result.normalize(); - if (inSignDomain == QCP::sdPositive) - { - if (result.lower <= 0 && result.upper > 0) - result.lower = result.upper*1e-3; - else if (result.lower <= 0 && result.upper <= 0) - foundRange = false; - } else if (inSignDomain == QCP::sdNegative) - { - if (result.upper >= 0 && result.lower < 0) - result.upper = result.lower*1e-3; - else if (result.upper >= 0 && result.lower >= 0) - foundRange = false; - } - return result; -} - -/*! \internal - - Updates the internal map image buffer by going through the internal \ref QCPColorMapData and - turning the data values into color pixels with \ref QCPColorGradient::colorize. - - This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image - has been invalidated for a different reason (e.g. a change of the data range with \ref - setDataRange). - - If the map cell count is low, the image created will be oversampled in order to avoid a - QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images - without smooth transform enabled. Accordingly, oversampling isn't performed if \ref - setInterpolate is true. -*/ -void QCPColorMap::updateMapImage() -{ - QCPAxis *keyAxis = mKeyAxis.data(); - if (!keyAxis) return; - if (mMapData->isEmpty()) return; - - const QImage::Format format = QImage::Format_ARGB32_Premultiplied; - const int keySize = mMapData->keySize(); - const int valueSize = mMapData->valueSize(); - int keyOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)keySize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on - int valueOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)valueSize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on - - // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: - if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) - mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); - else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) - mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); - - if (mMapImage.isNull()) - { - qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; - mMapImage = QImage(QSize(10, 10), format); - mMapImage.fill(Qt::black); - } else - { - QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage - if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) - { - // resize undersampled map image to actual key/value cell sizes: - if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) - mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); - else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) - mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); - localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image - } else if (!mUndersampledMapImage.isNull()) - mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it - - const double *rawData = mMapData->mData; - const unsigned char *rawAlpha = mMapData->mAlpha; - if (keyAxis->orientation() == Qt::Horizontal) - { - const int lineCount = valueSize; - const int rowCount = keySize; - for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) - if (rawAlpha) - mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); - else - mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); - } - } else // keyAxis->orientation() == Qt::Vertical - { - const int lineCount = keySize; - const int rowCount = valueSize; - for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) - if (rawAlpha) - mGradient.colorize(rawData+line, rawAlpha+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); - else - mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); - } - } - - if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) - { - if (keyAxis->orientation() == Qt::Horizontal) - mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); - else - mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); - } - } - mMapData->mDataModified = false; - mMapImageInvalidated = false; -} - -/* inherits documentation from base class */ -void QCPColorMap::draw(QCPPainter *painter) -{ - if (mMapData->isEmpty()) return; - if (!mKeyAxis || !mValueAxis) return; - applyDefaultAntialiasingHint(painter); - - if (mMapData->mDataModified || mMapImageInvalidated) - updateMapImage(); - - // use buffer if painting vectorized (PDF): - const bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); - QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized - QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in - QPixmap mapBuffer; - if (useBuffer) - { - const double mapBufferPixelRatio = 3; // factor by which DPI is increased in embedded bitmaps - mapBufferTarget = painter->clipRegion().boundingRect(); - mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize()); - mapBuffer.fill(Qt::transparent); - localPainter = new QCPPainter(&mapBuffer); - localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); - localPainter->translate(-mapBufferTarget.topLeft()); - } - - QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), - coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); - // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): - double halfCellWidth = 0; // in pixels - double halfCellHeight = 0; // in pixels - if (keyAxis()->orientation() == Qt::Horizontal) - { - if (mMapData->keySize() > 1) - halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->keySize()-1); - if (mMapData->valueSize() > 1) - halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->valueSize()-1); - } else // keyAxis orientation is Qt::Vertical - { - if (mMapData->keySize() > 1) - halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->keySize()-1); - if (mMapData->valueSize() > 1) - halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->valueSize()-1); - } - imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight); - const bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); - const bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); - const bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform); - localPainter->setRenderHint(QPainter::SmoothPixmapTransform, mInterpolate); - QRegion clipBackup; - if (mTightBoundary) - { - clipBackup = localPainter->clipRegion(); - QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), - coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); - localPainter->setClipRect(tightClipRect, Qt::IntersectClip); - } - localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); - if (mTightBoundary) - localPainter->setClipRegion(clipBackup); - localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); - - if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter - { - delete localPainter; - painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer); - } -} - -/* inherits documentation from base class */ -void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - applyDefaultAntialiasingHint(painter); - // draw map thumbnail: - if (!mLegendIcon.isNull()) - { - QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation); - QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height()); - iconRect.moveCenter(rect.center()); - painter->drawPixmap(iconRect.topLeft(), scaledIcon); - } - /* - // draw frame: - painter->setBrush(Qt::NoBrush); - painter->setPen(Qt::black); - painter->drawRect(rect.adjusted(1, 1, 0, 0)); - */ -} -/* end of 'src/plottables/plottable-colormap.cpp' */ - - -/* including file 'src/plottables/plottable-financial.cpp', size 42610 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPFinancialData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPFinancialData - \brief Holds the data of one single data point for QCPFinancial. - - The stored data is: - \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) - \li \a open: The opening value at the data point (this is the \a mainValue) - \li \a high: The high/maximum value at the data point - \li \a low: The low/minimum value at the data point - \li \a close: The closing value at the data point - - The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef - for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the - documentation there for an explanation regarding the data type's generic methods. - - \see QCPFinancialDataContainer -*/ - -/* start documentation of inline functions */ - -/*! \fn double QCPFinancialData::sortKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static QCPFinancialData QCPFinancialData::fromSortKey(double sortKey) - - Returns a data point with the specified \a sortKey. All other members are set to zero. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn static static bool QCPFinancialData::sortKeyIsMainKey() - - Since the member \a key is both the data point key coordinate and the data ordering parameter, - this method returns true. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPFinancialData::mainKey() const - - Returns the \a key member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn double QCPFinancialData::mainValue() const - - Returns the \a open member of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/*! \fn QCPRange QCPFinancialData::valueRange() const - - Returns a QCPRange spanning from the \a low to the \a high value of this data point. - - For a general explanation of what this method is good for in the context of the data container, - see the documentation of \ref QCPDataContainer. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a data point with key and all values set to zero. -*/ -QCPFinancialData::QCPFinancialData() : - key(0), - open(0), - high(0), - low(0), - close(0) -{ -} - -/*! - Constructs a data point with the specified \a key and OHLC values. -*/ -QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) : - key(key), - open(open), - high(high), - low(low), - close(close) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPFinancial -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPFinancial - \brief A plottable representing a financial stock chart - - \image html QCPFinancial.png - - This plottable represents time series data binned to certain intervals, mainly used for stock - charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be - set via \ref setChartStyle. - - The data is passed via \ref setData as a set of open/high/low/close values at certain keys - (typically times). This means the data must be already binned appropriately. If data is only - available as a series of values (e.g. \a price against \a time), you can use the static - convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed - to \ref setData. - - The width of the OHLC bars/candlesticks can be controlled with \ref setWidth and \ref - setWidthType. A typical choice is to set the width type to \ref wtPlotCoords (the default) and - the width to (or slightly less than) one time bin interval width. - - \section qcpfinancial-appearance Changing the appearance - - Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored, - lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush). - - If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are - represented with a different pen and brush than negative changes (\a close < \a open). These can - be configured with \ref setPenPositive, \ref setPenNegative, \ref setBrushPositive, and \ref - setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection - however, the normal selected pen/brush (provided by the \ref selectionDecorator) is used, - irrespective of whether the chart is single- or two-colored. - - \section qcpfinancial-usage Usage - - Like all data representing objects in QCustomPlot, the QCPFinancial is a plottable - (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies - (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) - - Usually, you first create an instance: - - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-1 - which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot - instance takes ownership of the plottable, so do not delete it manually but use - QCustomPlot::removePlottable() instead. The newly created plottable can be modified, e.g.: - - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-2 - Here we have used the static helper method \ref timeSeriesToOhlc, to turn a time-price data - series into a 24-hour binned open-high-low-close data series as QCPFinancial uses. -*/ - -/* start of documentation of inline functions */ - -/*! \fn QCPFinancialDataContainer *QCPFinancial::data() const - - Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may - use it to directly manipulate the data, which may be more convenient and faster than using the - regular \ref setData or \ref addData methods, in certain situations. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a - keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually - but use QCustomPlot::removePlottable() instead. -*/ -QCPFinancial::QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable1D(keyAxis, valueAxis), - mChartStyle(csCandlestick), - mWidth(0.5), - mWidthType(wtPlotCoords), - mTwoColored(true), - mBrushPositive(QBrush(QColor(50, 160, 0))), - mBrushNegative(QBrush(QColor(180, 0, 15))), - mPenPositive(QPen(QColor(40, 150, 0))), - mPenNegative(QPen(QColor(170, 5, 5))) -{ - mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); -} - -QCPFinancial::~QCPFinancial() -{ -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely. - Modifying the data in the container will then affect all financials that share the container. - Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, rather use - the \ref QCPDataContainer::set method on the financial's data container directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-2 - - \see addData, timeSeriesToOhlc -*/ -void QCPFinancial::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a - close. The provided vectors should have equal length. Else, the number of added points will be - the size of the smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - \see addData, timeSeriesToOhlc -*/ -void QCPFinancial::setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) -{ - mDataContainer->clear(); - addData(keys, open, high, low, close, alreadySorted); -} - -/*! - Sets which representation style shall be used to display the OHLC data. -*/ -void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) -{ - mChartStyle = style; -} - -/*! - Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. - - A typical choice is to set it to (or slightly less than) one bin interval width. -*/ -void QCPFinancial::setWidth(double width) -{ - mWidth = width; -} - -/*! - Sets how the width of the financial bars is defined. See the documentation of \ref WidthType for - an explanation of the possible values for \a widthType. - - The default value is \ref wtPlotCoords. - - \see setWidth -*/ -void QCPFinancial::setWidthType(QCPFinancial::WidthType widthType) -{ - mWidthType = widthType; -} - -/*! - Sets whether this chart shall contrast positive from negative trends per data point by using two - separate colors to draw the respective bars/candlesticks. - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative -*/ -void QCPFinancial::setTwoColored(bool twoColored) -{ - mTwoColored = twoColored; -} - -/*! - If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills - of data points with a positive trend (i.e. bars/candlesticks with close >= open). - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setBrushNegative, setPenPositive, setPenNegative -*/ -void QCPFinancial::setBrushPositive(const QBrush &brush) -{ - mBrushPositive = brush; -} - -/*! - If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills - of data points with a negative trend (i.e. bars/candlesticks with close < open). - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setBrushPositive, setPenNegative, setPenPositive -*/ -void QCPFinancial::setBrushNegative(const QBrush &brush) -{ - mBrushNegative = brush; -} - -/*! - If \ref setTwoColored is set to true, this function controls the pen that is used to draw - outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setPenNegative, setBrushPositive, setBrushNegative -*/ -void QCPFinancial::setPenPositive(const QPen &pen) -{ - mPenPositive = pen; -} - -/*! - If \ref setTwoColored is set to true, this function controls the pen that is used to draw - outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). - - If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref - setBrush). - - \see setPenPositive, setBrushNegative, setBrushPositive -*/ -void QCPFinancial::setPenNegative(const QPen &pen) -{ - mPenNegative = pen; -} - -/*! \overload - - Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data. - The provided vectors should have equal length. Else, the number of added points will be the size - of the smallest vector. - - If you can guarantee that the passed data points are sorted by \a keys in ascending order, you - can set \a alreadySorted to true, to improve performance by saving a sorting run. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. - - \see timeSeriesToOhlc -*/ -void QCPFinancial::addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) -{ - if (keys.size() != open.size() || open.size() != high.size() || high.size() != low.size() || low.size() != close.size() || close.size() != keys.size()) - qDebug() << Q_FUNC_INFO << "keys, open, high, low, close have different sizes:" << keys.size() << open.size() << high.size() << low.size() << close.size(); - const int n = qMin(keys.size(), qMin(open.size(), qMin(high.size(), qMin(low.size(), close.size())))); - QVector tempData(n); - QVector::iterator it = tempData.begin(); - const QVector::iterator itEnd = tempData.end(); - int i = 0; - while (it != itEnd) - { - it->key = keys[i]; - it->open = open[i]; - it->high = high[i]; - it->low = low[i]; - it->close = close[i]; - ++it; - ++i; - } - mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write -} - -/*! \overload - - Adds the provided data point as \a key, \a open, \a high, \a low and \a close to the current - data. - - Alternatively, you can also access and modify the data directly via the \ref data method, which - returns a pointer to the internal data container. - - \see timeSeriesToOhlc -*/ -void QCPFinancial::addData(double key, double open, double high, double low, double close) -{ - mDataContainer->add(QCPFinancialData(key, open, high, low, close)); -} - -/*! - \copydoc QCPPlottableInterface1D::selectTestRect -*/ -QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - for (QCPFinancialDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - if (rect.intersects(selectionHitBox(it))) - result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); - } - result.simplify(); - return result; -} - -/* inherits documentation from base class */ -double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - // get visible data range: - QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; - QCPFinancialDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - getVisibleDataBounds(visibleBegin, visibleEnd); - // perform select test according to configured style: - double result = -1; - switch (mChartStyle) - { - case QCPFinancial::csOhlc: - result = ohlcSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; - case QCPFinancial::csCandlestick: - result = candlestickSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; - } - if (details) - { - int pointIndex = closestDataPoint-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return result; - } - - return -1; -} - -/* inherits documentation from base class */ -QCPRange QCPFinancial::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); - // determine exact range by including width of bars/flags: - if (foundRange) - { - if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) - range.lower -= mWidth*0.5; - if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) - range.upper += mWidth*0.5; - } - return range; -} - -/* inherits documentation from base class */ -QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); -} - -/*! - A convenience function that converts time series data (\a value against \a time) to OHLC binned - data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const - QCPFinancialDataContainer&). - - The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. - For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour - each, set \a timeBinSize to 3600. - - \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The - value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. - It merely defines the mathematical offset/phase of the bins that will be used to process the - data. -*/ -QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset) -{ - QCPFinancialDataContainer data; - int count = qMin(time.size(), value.size()); - if (count == 0) - return QCPFinancialDataContainer(); - - QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); - int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); - for (int i=0; i currentBinData.high) currentBinData.high = value.at(i); - if (i == count-1) // last data point is in current bin, finalize bin: - { - currentBinData.close = value.at(i); - currentBinData.key = timeBinOffset+(index)*timeBinSize; - data.add(currentBinData); - } - } else // data point not anymore in current bin, set close of old and open of new bin, and add old to map: - { - // finalize current bin: - currentBinData.close = value.at(i-1); - currentBinData.key = timeBinOffset+(index-1)*timeBinSize; - data.add(currentBinData); - // start next bin: - currentBinIndex = index; - currentBinData.open = value.at(i); - currentBinData.high = value.at(i); - currentBinData.low = value.at(i); - } - } - - return data; -} - -/* inherits documentation from base class */ -void QCPFinancial::draw(QCPPainter *painter) -{ - // get visible data range: - QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd); - - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - for (int i=0; i= unselectedSegments.size(); - QCPFinancialDataContainer::const_iterator begin = visibleBegin; - QCPFinancialDataContainer::const_iterator end = visibleEnd; - mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); - if (begin == end) - continue; - - // draw data segment according to configured style: - switch (mChartStyle) - { - case QCPFinancial::csOhlc: - drawOhlcPlot(painter, begin, end, isSelectedSegment); break; - case QCPFinancial::csCandlestick: - drawCandlestickPlot(painter, begin, end, isSelectedSegment); break; - } - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing - if (mChartStyle == csOhlc) - { - if (mTwoColored) - { - // draw upper left half icon with positive color: - painter->setBrush(mBrushPositive); - painter->setPen(mPenPositive); - painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); - // draw bottom right half icon with negative color: - painter->setBrush(mBrushNegative); - painter->setPen(mPenNegative); - painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); - } else - { - painter->setBrush(mBrush); - painter->setPen(mPen); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); - } - } else if (mChartStyle == csCandlestick) - { - if (mTwoColored) - { - // draw upper left half icon with positive color: - painter->setBrush(mBrushPositive); - painter->setPen(mPenPositive); - painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); - // draw bottom right half icon with negative color: - painter->setBrush(mBrushNegative); - painter->setPen(mPenNegative); - painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); - } else - { - painter->setBrush(mBrush); - painter->setPen(mPen); - painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); - painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); - painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); - } - } -} - -/*! \internal - - Draws the data from \a begin to \a end-1 as OHLC bars with the provided \a painter. - - This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. -*/ -void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - if (keyAxis->orientation() == Qt::Horizontal) - { - for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) - { - if (isSelected && mSelectionDecorator) - mSelectionDecorator->applyPen(painter); - else if (mTwoColored) - painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); - else - painter->setPen(mPen); - double keyPixel = keyAxis->coordToPixel(it->key); - double openPixel = valueAxis->coordToPixel(it->open); - double closePixel = valueAxis->coordToPixel(it->close); - // draw backbone: - painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(it->low))); - // draw open: - double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides - painter->drawLine(QPointF(keyPixel-pixelWidth, openPixel), QPointF(keyPixel, openPixel)); - // draw close: - painter->drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+pixelWidth, closePixel)); - } - } else - { - for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) - { - if (isSelected && mSelectionDecorator) - mSelectionDecorator->applyPen(painter); - else if (mTwoColored) - painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); - else - painter->setPen(mPen); - double keyPixel = keyAxis->coordToPixel(it->key); - double openPixel = valueAxis->coordToPixel(it->open); - double closePixel = valueAxis->coordToPixel(it->close); - // draw backbone: - painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(it->low), keyPixel)); - // draw open: - double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides - painter->drawLine(QPointF(openPixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel)); - // draw close: - painter->drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+pixelWidth)); - } - } -} - -/*! \internal - - Draws the data from \a begin to \a end-1 as Candlesticks with the provided \a painter. - - This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. -*/ -void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - - if (keyAxis->orientation() == Qt::Horizontal) - { - for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) - { - if (isSelected && mSelectionDecorator) - { - mSelectionDecorator->applyPen(painter); - mSelectionDecorator->applyBrush(painter); - } else if (mTwoColored) - { - painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); - painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); - } else - { - painter->setPen(mPen); - painter->setBrush(mBrush); - } - double keyPixel = keyAxis->coordToPixel(it->key); - double openPixel = valueAxis->coordToPixel(it->open); - double closePixel = valueAxis->coordToPixel(it->close); - // draw high: - painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); - // draw low: - painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); - // draw open-close box: - double pixelWidth = getPixelWidth(it->key, keyPixel); - painter->drawRect(QRectF(QPointF(keyPixel-pixelWidth, closePixel), QPointF(keyPixel+pixelWidth, openPixel))); - } - } else // keyAxis->orientation() == Qt::Vertical - { - for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) - { - if (isSelected && mSelectionDecorator) - { - mSelectionDecorator->applyPen(painter); - mSelectionDecorator->applyBrush(painter); - } else if (mTwoColored) - { - painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); - painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); - } else - { - painter->setPen(mPen); - painter->setBrush(mBrush); - } - double keyPixel = keyAxis->coordToPixel(it->key); - double openPixel = valueAxis->coordToPixel(it->open); - double closePixel = valueAxis->coordToPixel(it->close); - // draw high: - painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); - // draw low: - painter->drawLine(QPointF(valueAxis->coordToPixel(it->low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); - // draw open-close box: - double pixelWidth = getPixelWidth(it->key, keyPixel); - painter->drawRect(QRectF(QPointF(closePixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel+pixelWidth))); - } - } -} - -/*! \internal - - This function is used to determine the width of the bar at coordinate \a key, according to the - specified width (\ref setWidth) and width type (\ref setWidthType). Provide the pixel position of - \a key in \a keyPixel (because usually this was already calculated via \ref QCPAxis::coordToPixel - when this function is called). - - It returns the number of pixels the bar extends to higher keys, relative to the \a key - coordinate. So with a non-reversed horizontal axis, the return value is positive. With a reversed - horizontal axis, the return value is negative. This is important so the open/close flags on the - \ref csOhlc bar are drawn to the correct side. -*/ -double QCPFinancial::getPixelWidth(double key, double keyPixel) const -{ - double result = 0; - switch (mWidthType) - { - case wtAbsolute: - { - if (mKeyAxis) - result = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - break; - } - case wtAxisRectRatio: - { - if (mKeyAxis && mKeyAxis.data()->axisRect()) - { - if (mKeyAxis.data()->orientation() == Qt::Horizontal) - result = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - else - result = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); - } else - qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; - break; - } - case wtPlotCoords: - { - if (mKeyAxis) - result = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; - else - qDebug() << Q_FUNC_INFO << "No key axis defined"; - break; - } - } - return result; -} - -/*! \internal - - This method is a helper function for \ref selectTest. It is used to test for selection when the - chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. - - Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical - representation of the plottable, and \a closestDataPoint will point to the respective data point. -*/ -double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const -{ - closestDataPoint = mDataContainer->constEnd(); - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } - - double minDistSqr = std::numeric_limits::max(); - if (keyAxis->orientation() == Qt::Horizontal) - { - for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) - { - double keyPixel = keyAxis->coordToPixel(it->key); - // calculate distance to backbone: - double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low))); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } - } else // keyAxis->orientation() == Qt::Vertical - { - for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) - { - double keyPixel = keyAxis->coordToPixel(it->key); - // calculate distance to backbone: - double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel)); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } - } - return qSqrt(minDistSqr); -} - -/*! \internal - - This method is a helper function for \ref selectTest. It is used to test for selection when the - chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a - end. - - Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical - representation of the plottable, and \a closestDataPoint will point to the respective data point. -*/ -double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const -{ - closestDataPoint = mDataContainer->constEnd(); - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } - - double minDistSqr = std::numeric_limits::max(); - if (keyAxis->orientation() == Qt::Horizontal) - { - for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) - { - double currentDistSqr; - // determine whether pos is in open-close-box: - QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); - QCPRange boxValueRange(it->close, it->open); - double posKey, posValue; - pixelsToCoords(pos, posKey, posValue); - if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box - { - currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; - } else - { - // calculate distance to high/low lines: - double keyPixel = keyAxis->coordToPixel(it->key); - double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); - double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); - currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); - } - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } - } else // keyAxis->orientation() == Qt::Vertical - { - for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) - { - double currentDistSqr; - // determine whether pos is in open-close-box: - QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); - QCPRange boxValueRange(it->close, it->open); - double posKey, posValue; - pixelsToCoords(pos, posKey, posValue); - if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box - { - currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; - } else - { - // calculate distance to high/low lines: - double keyPixel = keyAxis->coordToPixel(it->key); - double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); - double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); - currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); - } - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - closestDataPoint = it; - } - } - } - return qSqrt(minDistSqr); -} - -/*! \internal - - called by the drawing methods to determine which data (key) range is visible at the current key - axis range setting, so only that needs to be processed. - - \a begin returns an iterator to the lowest data point that needs to be taken into account when - plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a - begin may still be just outside the visible range. - - \a end returns the iterator just above the highest data point that needs to be taken into - account. Same as before, \a end may also lie just outside of the visible range - - if the plottable contains no data, both \a begin and \a end point to \c constEnd. -*/ -void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const -{ - if (!mKeyAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key axis"; - begin = mDataContainer->constEnd(); - end = mDataContainer->constEnd(); - return; - } - begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of ohlc/candlestick to include partially visible data points - end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of ohlc/candlestick to include partially visible data points -} - -/*! \internal - - Returns the hit box in pixel coordinates that will be used for data selection with the selection - rect (\ref selectTestRect), of the data point given by \a it. -*/ -QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator it) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } - - double keyPixel = keyAxis->coordToPixel(it->key); - double highPixel = valueAxis->coordToPixel(it->high); - double lowPixel = valueAxis->coordToPixel(it->low); - double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it->key-mWidth*0.5); - if (keyAxis->orientation() == Qt::Horizontal) - return QRectF(keyPixel-keyWidthPixels, highPixel, keyWidthPixels*2, lowPixel-highPixel).normalized(); - else - return QRectF(highPixel, keyPixel-keyWidthPixels, lowPixel-highPixel, keyWidthPixels*2).normalized(); -} -/* end of 'src/plottables/plottable-financial.cpp' */ - - -/* including file 'src/plottables/plottable-errorbar.cpp', size 37355 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPErrorBarsData -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPErrorBarsData - \brief Holds the data of one single error bar for QCPErrorBars. - - The stored data is: - \li \a errorMinus: how much the error bar extends towards negative coordinates from the data - point position - \li \a errorPlus: how much the error bar extends towards positive coordinates from the data point - position - - The container for storing the error bar information is \ref QCPErrorBarsDataContainer. It is a - typedef for QVector<\ref QCPErrorBarsData>. - - \see QCPErrorBarsDataContainer -*/ - -/*! - Constructs an error bar with errors set to zero. -*/ -QCPErrorBarsData::QCPErrorBarsData() : - errorMinus(0), - errorPlus(0) -{ -} - -/*! - Constructs an error bar with equal \a error in both negative and positive direction. -*/ -QCPErrorBarsData::QCPErrorBarsData(double error) : - errorMinus(error), - errorPlus(error) -{ -} - -/*! - Constructs an error bar with negative and positive errors set to \a errorMinus and \a errorPlus, - respectively. -*/ -QCPErrorBarsData::QCPErrorBarsData(double errorMinus, double errorPlus) : - errorMinus(errorMinus), - errorPlus(errorPlus) -{ -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPErrorBars -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPErrorBars - \brief A plottable that adds a set of error bars to other plottables. - - \image html QCPErrorBars.png - - The \ref QCPErrorBars plottable can be attached to other one-dimensional plottables (e.g. \ref - QCPGraph, \ref QCPCurve, \ref QCPBars, etc.) and equips them with error bars. - - Use \ref setDataPlottable to define for which plottable the \ref QCPErrorBars shall display the - error bars. The orientation of the error bars can be controlled with \ref setErrorType. - - By using \ref setData, you can supply the actual error data, either as symmetric error or - plus/minus asymmetric errors. \ref QCPErrorBars only stores the error data. The absolute - key/value position of each error bar will be adopted from the configured data plottable. The - error data of the \ref QCPErrorBars are associated one-to-one via their index to the data points - of the data plottable. You can directly access and manipulate the error bar data via \ref data. - - Set either of the plus/minus errors to NaN (qQNaN() or - std::numeric_limits::quiet_NaN()) to not show the respective error bar on the data point at - that index. - - \section qcperrorbars-appearance Changing the appearance - - The appearance of the error bars is defined by the pen (\ref setPen), and the width of the - whiskers (\ref setWhiskerWidth). Further, the error bar backbones may leave a gap around the data - point center to prevent that error bars are drawn too close to or even through scatter points. - This gap size can be controlled via \ref setSymbolGap. -*/ - -/* start of documentation of inline functions */ - -/*! \fn QSharedPointer QCPErrorBars::data() const - - Returns a shared pointer to the internal data storage of type \ref QCPErrorBarsDataContainer. You - may use it to directly manipulate the error values, which may be more convenient and faster than - using the regular \ref setData methods. -*/ - -/* end of documentation of inline functions */ - -/*! - Constructs an error bars plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value - axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have - the same orientation. If either of these restrictions is violated, a corresponding message is - printed to the debug output (qDebug), the construction is not aborted, though. - - It is also important that the \a keyAxis and \a valueAxis are the same for the error bars - plottable and the data plottable that the error bars shall be drawn on (\ref setDataPlottable). - - The created \ref QCPErrorBars is automatically registered with the QCustomPlot instance inferred - from \a keyAxis. This QCustomPlot instance takes ownership of the \ref QCPErrorBars, so do not - delete it manually but use \ref QCustomPlot::removePlottable() instead. -*/ -QCPErrorBars::QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable(keyAxis, valueAxis), - mDataContainer(new QVector), - mErrorType(etValueError), - mWhiskerWidth(9), - mSymbolGap(10) -{ - setPen(QPen(Qt::black, 0)); - setBrush(Qt::NoBrush); -} - -QCPErrorBars::~QCPErrorBars() -{ -} - -/*! \overload - - Replaces the current data container with the provided \a data container. - - Since a QSharedPointer is used, multiple \ref QCPErrorBars instances may share the same data - container safely. Modifying the data in the container will then affect all \ref QCPErrorBars - instances that share the container. Sharing can be achieved by simply exchanging the data - containers wrapped in shared pointers: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-1 - - If you do not wish to share containers, but create a copy from an existing container, assign the - data containers directly: - \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-2 - (This uses different notation compared with other plottables, because the \ref QCPErrorBars - uses a \c QVector as its data container, instead of a \ref QCPDataContainer.) - - \see addData -*/ -void QCPErrorBars::setData(QSharedPointer data) -{ - mDataContainer = data; -} - -/*! \overload - - Sets symmetrical error values as specified in \a error. The errors will be associated one-to-one - by the data point index to the associated data plottable (\ref setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see addData -*/ -void QCPErrorBars::setData(const QVector &error) -{ - mDataContainer->clear(); - addData(error); -} - -/*! \overload - - Sets asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be - associated one-to-one by the data point index to the associated data plottable (\ref - setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see addData -*/ -void QCPErrorBars::setData(const QVector &errorMinus, const QVector &errorPlus) -{ - mDataContainer->clear(); - addData(errorMinus, errorPlus); -} - -/*! - Sets the data plottable to which the error bars will be applied. The error values specified e.g. - via \ref setData will be associated one-to-one by the data point index to the data points of \a - plottable. This means that the error bars will adopt the key/value coordinates of the data point - with the same index. - - The passed \a plottable must be a one-dimensional plottable, i.e. it must implement the \ref - QCPPlottableInterface1D. Further, it must not be a \ref QCPErrorBars instance itself. If either - of these restrictions is violated, a corresponding qDebug output is generated, and the data - plottable of this \ref QCPErrorBars instance is set to zero. - - For proper display, care must also be taken that the key and value axes of the \a plottable match - those configured for this \ref QCPErrorBars instance. -*/ -void QCPErrorBars::setDataPlottable(QCPAbstractPlottable *plottable) -{ - if (plottable && qobject_cast(plottable)) - { - mDataPlottable = 0; - qDebug() << Q_FUNC_INFO << "can't set another QCPErrorBars instance as data plottable"; - return; - } - if (plottable && !plottable->interface1D()) - { - mDataPlottable = 0; - qDebug() << Q_FUNC_INFO << "passed plottable doesn't implement 1d interface, can't associate with QCPErrorBars"; - return; - } - - mDataPlottable = plottable; -} - -/*! - Sets in which orientation the error bars shall appear on the data points. If your data needs both - error dimensions, create two \ref QCPErrorBars with different \a type. -*/ -void QCPErrorBars::setErrorType(ErrorType type) -{ - mErrorType = type; -} - -/*! - Sets the width of the whiskers (the short bars at the end of the actual error bar backbones) to - \a pixels. -*/ -void QCPErrorBars::setWhiskerWidth(double pixels) -{ - mWhiskerWidth = pixels; -} - -/*! - Sets the gap diameter around the data points that will be left out when drawing the error bar - backbones. This gap prevents that error bars are drawn too close to or even through scatter - points. -*/ -void QCPErrorBars::setSymbolGap(double pixels) -{ - mSymbolGap = pixels; -} - -/*! \overload - - Adds symmetrical error values as specified in \a error. The errors will be associated one-to-one - by the data point index to the associated data plottable (\ref setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see setData -*/ -void QCPErrorBars::addData(const QVector &error) -{ - addData(error, error); -} - -/*! \overload - - Adds asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be - associated one-to-one by the data point index to the associated data plottable (\ref - setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see setData -*/ -void QCPErrorBars::addData(const QVector &errorMinus, const QVector &errorPlus) -{ - if (errorMinus.size() != errorPlus.size()) - qDebug() << Q_FUNC_INFO << "minus and plus error vectors have different sizes:" << errorMinus.size() << errorPlus.size(); - const int n = qMin(errorMinus.size(), errorPlus.size()); - mDataContainer->reserve(n); - for (int i=0; iappend(QCPErrorBarsData(errorMinus.at(i), errorPlus.at(i))); -} - -/*! \overload - - Adds a single symmetrical error bar as specified in \a error. The errors will be associated - one-to-one by the data point index to the associated data plottable (\ref setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see setData -*/ -void QCPErrorBars::addData(double error) -{ - mDataContainer->append(QCPErrorBarsData(error)); -} - -/*! \overload - - Adds a single asymmetrical error bar as specified in \a errorMinus and \a errorPlus. The errors - will be associated one-to-one by the data point index to the associated data plottable (\ref - setDataPlottable). - - You can directly access and manipulate the error bar data via \ref data. - - \see setData -*/ -void QCPErrorBars::addData(double errorMinus, double errorPlus) -{ - mDataContainer->append(QCPErrorBarsData(errorMinus, errorPlus)); -} - -/* inherits documentation from base class */ -int QCPErrorBars::dataCount() const -{ - return mDataContainer->size(); -} - -/* inherits documentation from base class */ -double QCPErrorBars::dataMainKey(int index) const -{ - if (mDataPlottable) - return mDataPlottable->interface1D()->dataMainKey(index); - else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -double QCPErrorBars::dataSortKey(int index) const -{ - if (mDataPlottable) - return mDataPlottable->interface1D()->dataSortKey(index); - else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -double QCPErrorBars::dataMainValue(int index) const -{ - if (mDataPlottable) - return mDataPlottable->interface1D()->dataMainValue(index); - else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -QCPRange QCPErrorBars::dataValueRange(int index) const -{ - if (mDataPlottable) - { - const double value = mDataPlottable->interface1D()->dataMainValue(index); - if (index >= 0 && index < mDataContainer->size() && mErrorType == etValueError) - return QCPRange(value-mDataContainer->at(index).errorMinus, value+mDataContainer->at(index).errorPlus); - else - return QCPRange(value, value); - } else - { - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return QCPRange(); - } -} - -/* inherits documentation from base class */ -QPointF QCPErrorBars::dataPixelPosition(int index) const -{ - if (mDataPlottable) - return mDataPlottable->interface1D()->dataPixelPosition(index); - else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return QPointF(); -} - -/* inherits documentation from base class */ -bool QCPErrorBars::sortKeyIsMainKey() const -{ - if (mDataPlottable) - { - return mDataPlottable->interface1D()->sortKeyIsMainKey(); - } else - { - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return true; - } -} - -/*! - \copydoc QCPPlottableInterface1D::selectTestRect -*/ -QCPDataSelection QCPErrorBars::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if (!mDataPlottable) - return result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd; - getVisibleDataBounds(visibleBegin, visibleEnd, QCPDataRange(0, dataCount())); - - QVector backbones, whiskers; - for (QCPErrorBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) - { - backbones.clear(); - whiskers.clear(); - getErrorBarLines(it, backbones, whiskers); - for (int i=0; iconstBegin(), it-mDataContainer->constBegin()+1), false); - break; - } - } - } - result.simplify(); - return result; -} - -/* inherits documentation from base class */ -int QCPErrorBars::findBegin(double sortKey, bool expandedRange) const -{ - if (mDataPlottable) - { - if (mDataContainer->isEmpty()) - return 0; - int beginIndex = mDataPlottable->interface1D()->findBegin(sortKey, expandedRange); - if (beginIndex >= mDataContainer->size()) - beginIndex = mDataContainer->size()-1; - return beginIndex; - } else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -int QCPErrorBars::findEnd(double sortKey, bool expandedRange) const -{ - if (mDataPlottable) - { - if (mDataContainer->isEmpty()) - return 0; - int endIndex = mDataPlottable->interface1D()->findEnd(sortKey, expandedRange); - if (endIndex > mDataContainer->size()) - endIndex = mDataContainer->size(); - return endIndex; - } else - qDebug() << Q_FUNC_INFO << "no data plottable set"; - return 0; -} - -/* inherits documentation from base class */ -double QCPErrorBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if (!mDataPlottable) return -1; - - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) - { - QCPErrorBarsDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); - double result = pointDistance(pos, closestDataPoint); - if (details) - { - int pointIndex = closestDataPoint-mDataContainer->constBegin(); - details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); - } - return result; - } else - return -1; -} - -/* inherits documentation from base class */ -void QCPErrorBars::draw(QCPPainter *painter) -{ - if (!mDataPlottable) return; - if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } - if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; - - // if the sort key isn't the main key, we must check the visibility for each data point/error bar individually - // (getVisibleDataBounds applies range restriction, but otherwise can only return full data range): - bool checkPointVisibility = !mDataPlottable->interface1D()->sortKeyIsMainKey(); - - // check data validity if flag set: -#ifdef QCUSTOMPLOT_CHECK_DATA - QCPErrorBarsDataContainer::const_iterator it; - for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) - { - if (QCP::isInvalidData(it->errorMinus, it->errorPlus)) - qDebug() << Q_FUNC_INFO << "Data point at index" << it-mDataContainer->constBegin() << "invalid." << "Plottable name:" << name(); - } -#endif - - applyDefaultAntialiasingHint(painter); - painter->setBrush(Qt::NoBrush); - // loop over and draw segments of unselected/selected data: - QList selectedSegments, unselectedSegments, allSegments; - getDataSegments(selectedSegments, unselectedSegments); - allSegments << unselectedSegments << selectedSegments; - QVector backbones, whiskers; - for (int i=0; i= unselectedSegments.size(); - if (isSelectedSegment && mSelectionDecorator) - mSelectionDecorator->applyPen(painter); - else - painter->setPen(mPen); - if (painter->pen().capStyle() == Qt::SquareCap) - { - QPen capFixPen(painter->pen()); - capFixPen.setCapStyle(Qt::FlatCap); - painter->setPen(capFixPen); - } - backbones.clear(); - whiskers.clear(); - for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) - { - if (!checkPointVisibility || errorBarVisible(it-mDataContainer->constBegin())) - getErrorBarLines(it, backbones, whiskers); - } - painter->drawLines(backbones); - painter->drawLines(whiskers); - } - - // draw other selection decoration that isn't just line/scatter pens and brushes: - if (mSelectionDecorator) - mSelectionDecorator->drawDecoration(painter, selection()); -} - -/* inherits documentation from base class */ -void QCPErrorBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const -{ - applyDefaultAntialiasingHint(painter); - painter->setPen(mPen); - if (mErrorType == etValueError && mValueAxis && mValueAxis->orientation() == Qt::Vertical) - { - painter->drawLine(QLineF(rect.center().x(), rect.top()+2, rect.center().x(), rect.bottom()-1)); - painter->drawLine(QLineF(rect.center().x()-4, rect.top()+2, rect.center().x()+4, rect.top()+2)); - painter->drawLine(QLineF(rect.center().x()-4, rect.bottom()-1, rect.center().x()+4, rect.bottom()-1)); - } else - { - painter->drawLine(QLineF(rect.left()+2, rect.center().y(), rect.right()-2, rect.center().y())); - painter->drawLine(QLineF(rect.left()+2, rect.center().y()-4, rect.left()+2, rect.center().y()+4)); - painter->drawLine(QLineF(rect.right()-2, rect.center().y()-4, rect.right()-2, rect.center().y()+4)); - } -} - -/* inherits documentation from base class */ -QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const -{ - if (!mDataPlottable) - { - foundRange = false; - return QCPRange(); - } - - QCPRange range; - bool haveLower = false; - bool haveUpper = false; - QCPErrorBarsDataContainer::const_iterator it; - for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) - { - if (mErrorType == etValueError) - { - // error bar doesn't extend in key dimension (except whisker but we ignore that here), so only use data point center - const double current = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); - if (qIsNaN(current)) continue; - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - } else // mErrorType == etKeyError - { - const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); - if (qIsNaN(dataKey)) continue; - // plus error: - double current = dataKey + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - // minus error: - current = dataKey - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - } - } - } - - if (haveUpper && !haveLower) - { - range.lower = range.upper; - haveLower = true; - } else if (haveLower && !haveUpper) - { - range.upper = range.lower; - haveUpper = true; - } - - foundRange = haveLower && haveUpper; - return range; -} - -/* inherits documentation from base class */ -QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const -{ - if (!mDataPlottable) - { - foundRange = false; - return QCPRange(); - } - - QCPRange range; - const bool restrictKeyRange = inKeyRange != QCPRange(); - bool haveLower = false; - bool haveUpper = false; - QCPErrorBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); - QCPErrorBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); - if (mDataPlottable->interface1D()->sortKeyIsMainKey() && restrictKeyRange) - { - itBegin = mDataContainer->constBegin()+findBegin(inKeyRange.lower); - itEnd = mDataContainer->constBegin()+findEnd(inKeyRange.upper); - } - for (QCPErrorBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - if (restrictKeyRange) - { - const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); - if (dataKey < inKeyRange.lower || dataKey > inKeyRange.upper) - continue; - } - if (mErrorType == etValueError) - { - const double dataValue = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); - if (qIsNaN(dataValue)) continue; - // plus error: - double current = dataValue + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - // minus error: - current = dataValue - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - } - } else // mErrorType == etKeyError - { - // error bar doesn't extend in value dimension (except whisker but we ignore that here), so only use data point center - const double current = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); - if (qIsNaN(current)) continue; - if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) - { - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - } - } - - if (haveUpper && !haveLower) - { - range.lower = range.upper; - haveLower = true; - } else if (haveLower && !haveUpper) - { - range.upper = range.lower; - haveUpper = true; - } - - foundRange = haveLower && haveUpper; - return range; -} - -/*! \internal - - Calculates the lines that make up the error bar belonging to the data point \a it. - - The resulting lines are added to \a backbones and \a whiskers. The vectors are not cleared, so - calling this method with different \a it but the same \a backbones and \a whiskers allows to - accumulate lines for multiple data points. - - This method assumes that \a it is a valid iterator within the bounds of this \ref QCPErrorBars - instance and within the bounds of the associated data plottable. -*/ -void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const -{ - if (!mDataPlottable) return; - - int index = it-mDataContainer->constBegin(); - QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); - if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) - return; - QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data(); - QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data(); - const double centerErrorAxisPixel = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); - const double centerOrthoAxisPixel = orthoAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); - const double centerErrorAxisCoord = errorAxis->pixelToCoord(centerErrorAxisPixel); // depending on plottable, this might be different from just mDataPlottable->interface1D()->dataMainKey/Value - const double symbolGap = mSymbolGap*0.5*errorAxis->pixelOrientation(); - // plus error: - double errorStart, errorEnd; - if (!qIsNaN(it->errorPlus)) - { - errorStart = centerErrorAxisPixel+symbolGap; - errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord+it->errorPlus); - if (errorAxis->orientation() == Qt::Vertical) - { - if ((errorStart > errorEnd) != errorAxis->rangeReversed()) - backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); - whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); - } else - { - if ((errorStart < errorEnd) != errorAxis->rangeReversed()) - backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); - whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); - } - } - // minus error: - if (!qIsNaN(it->errorMinus)) - { - errorStart = centerErrorAxisPixel-symbolGap; - errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord-it->errorMinus); - if (errorAxis->orientation() == Qt::Vertical) - { - if ((errorStart < errorEnd) != errorAxis->rangeReversed()) - backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); - whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); - } else - { - if ((errorStart > errorEnd) != errorAxis->rangeReversed()) - backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); - whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); - } - } -} - -/*! \internal - - This method outputs the currently visible data range via \a begin and \a end. The returned range - will also never exceed \a rangeRestriction. - - Since error bars with type \ref etKeyError may extend to arbitrarily positive and negative key - coordinates relative to their data point key, this method checks all outer error bars whether - they truly don't reach into the visible portion of the axis rect, by calling \ref - errorBarVisible. On the other hand error bars with type \ref etValueError that are associated - with data plottables whose sort key is equal to the main key (see \ref qcpdatacontainer-datatype - "QCPDataContainer DataType") can be handled very efficiently by finding the visible range of - error bars through binary search (\ref QCPPlottableInterface1D::findBegin and \ref - QCPPlottableInterface1D::findEnd). - - If the plottable's sort key is not equal to the main key, this method returns the full data - range, only restricted by \a rangeRestriction. Drawing optimization then has to be done on a - point-by-point basis in the \ref draw method. -*/ -void QCPErrorBars::getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const -{ - QCPAxis *keyAxis = mKeyAxis.data(); - QCPAxis *valueAxis = mValueAxis.data(); - if (!keyAxis || !valueAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key or value axis"; - end = mDataContainer->constEnd(); - begin = end; - return; - } - if (!mDataPlottable || rangeRestriction.isEmpty()) - { - end = mDataContainer->constEnd(); - begin = end; - return; - } - if (!mDataPlottable->interface1D()->sortKeyIsMainKey()) - { - // if the sort key isn't the main key, it's not possible to find a contiguous range of visible - // data points, so this method then only applies the range restriction and otherwise returns - // the full data range. Visibility checks must be done on a per-datapoin-basis during drawing - QCPDataRange dataRange(0, mDataContainer->size()); - dataRange = dataRange.bounded(rangeRestriction); - begin = mDataContainer->constBegin()+dataRange.begin(); - end = mDataContainer->constBegin()+dataRange.end(); - return; - } - - // get visible data range via interface from data plottable, and then restrict to available error data points: - const int n = qMin(mDataContainer->size(), mDataPlottable->interface1D()->dataCount()); - int beginIndex = mDataPlottable->interface1D()->findBegin(keyAxis->range().lower); - int endIndex = mDataPlottable->interface1D()->findEnd(keyAxis->range().upper); - int i = beginIndex; - while (i > 0 && i < n && i > rangeRestriction.begin()) - { - if (errorBarVisible(i)) - beginIndex = i; - --i; - } - i = endIndex; - while (i >= 0 && i < n && i < rangeRestriction.end()) - { - if (errorBarVisible(i)) - endIndex = i+1; - ++i; - } - QCPDataRange dataRange(beginIndex, endIndex); - dataRange = dataRange.bounded(rangeRestriction.bounded(QCPDataRange(0, mDataContainer->size()))); - begin = mDataContainer->constBegin()+dataRange.begin(); - end = mDataContainer->constBegin()+dataRange.end(); -} - -/*! \internal - - Calculates the minimum distance in pixels the error bars' representation has from the given \a - pixelPoint. This is used to determine whether the error bar was clicked or not, e.g. in \ref - selectTest. The closest data point to \a pixelPoint is returned in \a closestData. -*/ -double QCPErrorBars::pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const -{ - closestData = mDataContainer->constEnd(); - if (!mDataPlottable || mDataContainer->isEmpty()) - return -1.0; - if (!mKeyAxis || !mValueAxis) - { - qDebug() << Q_FUNC_INFO << "invalid key or value axis"; - return -1.0; - } - - QCPErrorBarsDataContainer::const_iterator begin, end; - getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); - - // calculate minimum distances to error backbones (whiskers are ignored for speed) and find closestData iterator: - double minDistSqr = std::numeric_limits::max(); - QVector backbones, whiskers; - for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) - { - getErrorBarLines(it, backbones, whiskers); - for (int i=0; i &selectedSegments, QList &unselectedSegments) const -{ - selectedSegments.clear(); - unselectedSegments.clear(); - if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty - { - if (selected()) - selectedSegments << QCPDataRange(0, dataCount()); - else - unselectedSegments << QCPDataRange(0, dataCount()); - } else - { - QCPDataSelection sel(selection()); - sel.simplify(); - selectedSegments = sel.dataRanges(); - unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); - } -} - -/*! \internal - - Returns whether the error bar at the specified \a index is visible within the current key axis - range. - - This method assumes for performance reasons without checking that the key axis, the value axis, - and the data plottable (\ref setDataPlottable) are not zero and that \a index is within valid - bounds of this \ref QCPErrorBars instance and the bounds of the data plottable. -*/ -bool QCPErrorBars::errorBarVisible(int index) const -{ - QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); - const double centerKeyPixel = mKeyAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); - if (qIsNaN(centerKeyPixel)) - return false; - - double keyMin, keyMax; - if (mErrorType == etKeyError) - { - const double centerKey = mKeyAxis->pixelToCoord(centerKeyPixel); - const double errorPlus = mDataContainer->at(index).errorPlus; - const double errorMinus = mDataContainer->at(index).errorMinus; - keyMax = centerKey+(qIsNaN(errorPlus) ? 0 : errorPlus); - keyMin = centerKey-(qIsNaN(errorMinus) ? 0 : errorMinus); - } else // mErrorType == etValueError - { - keyMax = mKeyAxis->pixelToCoord(centerKeyPixel+mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); - keyMin = mKeyAxis->pixelToCoord(centerKeyPixel-mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); - } - return ((keyMax > mKeyAxis->range().lower) && (keyMin < mKeyAxis->range().upper)); -} - -/*! \internal - - Returns whether \a line intersects (or is contained in) \a pixelRect. - - \a line is assumed to be either perfectly horizontal or perfectly vertical, as is the case for - error bar lines. -*/ -bool QCPErrorBars::rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const -{ - if (pixelRect.left() > line.x1() && pixelRect.left() > line.x2()) - return false; - else if (pixelRect.right() < line.x1() && pixelRect.right() < line.x2()) - return false; - else if (pixelRect.top() > line.y1() && pixelRect.top() > line.y2()) - return false; - else if (pixelRect.bottom() < line.y1() && pixelRect.bottom() < line.y2()) - return false; - else - return true; -} -/* end of 'src/plottables/plottable-errorbar.cpp' */ - - -/* including file 'src/items/item-straightline.cpp', size 7592 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemStraightLine -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemStraightLine - \brief A straight line that spans infinitely in both directions - - \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a point1 and \a point2, which define the straight line. -*/ - -/*! - Creates a straight line item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - point1(createPosition(QLatin1String("point1"))), - point2(createPosition(QLatin1String("point2"))) -{ - point1->setCoords(0, 0); - point2->setCoords(1, 1); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue,2)); -} - -QCPItemStraightLine::~QCPItemStraightLine() -{ -} - -/*! - Sets the pen that will be used to draw the line - - \see setSelectedPen -*/ -void QCPItemStraightLine::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line when selected - - \see setPen, setSelected -*/ -void QCPItemStraightLine::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/* inherits documentation from base class */ -double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - return QCPVector2D(pos).distanceToStraightLine(point1->pixelPosition(), point2->pixelPosition()-point1->pixelPosition()); -} - -/* inherits documentation from base class */ -void QCPItemStraightLine::draw(QCPPainter *painter) -{ - QCPVector2D start(point1->pixelPosition()); - QCPVector2D end(point2->pixelPosition()); - // get visible segment of straight line inside clipRect: - double clipPad = mainPen().widthF(); - QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); - // paint visible segment, if existent: - if (!line.isNull()) - { - painter->setPen(mainPen()); - painter->drawLine(line); - } -} - -/*! \internal - - Returns the section of the straight line defined by \a base and direction vector \a - vec, that is visible in the specified \a rect. - - This is a helper function for \ref draw. -*/ -QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const -{ - double bx, by; - double gamma; - QLineF result; - if (vec.x() == 0 && vec.y() == 0) - return result; - if (qFuzzyIsNull(vec.x())) // line is vertical - { - // check top of rect: - bx = rect.left(); - by = rect.top(); - gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); - if (gamma >= 0 && gamma <= rect.width()) - result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical - } else if (qFuzzyIsNull(vec.y())) // line is horizontal - { - // check left of rect: - bx = rect.left(); - by = rect.top(); - gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); - if (gamma >= 0 && gamma <= rect.height()) - result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal - } else // line is skewed - { - QList pointVectors; - // check top of rect: - bx = rect.left(); - by = rect.top(); - gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); - if (gamma >= 0 && gamma <= rect.width()) - pointVectors.append(QCPVector2D(bx+gamma, by)); - // check bottom of rect: - bx = rect.left(); - by = rect.bottom(); - gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); - if (gamma >= 0 && gamma <= rect.width()) - pointVectors.append(QCPVector2D(bx+gamma, by)); - // check left of rect: - bx = rect.left(); - by = rect.top(); - gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); - if (gamma >= 0 && gamma <= rect.height()) - pointVectors.append(QCPVector2D(bx, by+gamma)); - // check right of rect: - bx = rect.right(); - by = rect.top(); - gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); - if (gamma >= 0 && gamma <= rect.height()) - pointVectors.append(QCPVector2D(bx, by+gamma)); - - // evaluate points: - if (pointVectors.size() == 2) - { - result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); - } else if (pointVectors.size() > 2) - { - // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: - double distSqrMax = 0; - QCPVector2D pv1, pv2; - for (int i=0; i distSqrMax) - { - pv1 = pointVectors.at(i); - pv2 = pointVectors.at(k); - distSqrMax = distSqr; - } - } - } - result.setPoints(pv1.toPointF(), pv2.toPointF()); - } - } - return result; -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the - item is not selected and mSelectedPen when it is. -*/ -QPen QCPItemStraightLine::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-straightline.cpp' */ - - -/* including file 'src/items/item-line.cpp', size 8498 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemLine -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemLine - \brief A line from one point to another - - \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a start and \a end, which define the end points of the line. - - With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. -*/ - -/*! - Creates a line item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - start(createPosition(QLatin1String("start"))), - end(createPosition(QLatin1String("end"))) -{ - start->setCoords(0, 0); - end->setCoords(1, 1); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue,2)); -} - -QCPItemLine::~QCPItemLine() -{ -} - -/*! - Sets the pen that will be used to draw the line - - \see setSelectedPen -*/ -void QCPItemLine::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line when selected - - \see setPen, setSelected -*/ -void QCPItemLine::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the line ending style of the head. The head corresponds to the \a end position. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify - a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode - - \see setTail -*/ -void QCPItemLine::setHead(const QCPLineEnding &head) -{ - mHead = head; -} - -/*! - Sets the line ending style of the tail. The tail corresponds to the \a start position. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify - a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode - - \see setHead -*/ -void QCPItemLine::setTail(const QCPLineEnding &tail) -{ - mTail = tail; -} - -/* inherits documentation from base class */ -double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - return qSqrt(QCPVector2D(pos).distanceSquaredToLine(start->pixelPosition(), end->pixelPosition())); -} - -/* inherits documentation from base class */ -void QCPItemLine::draw(QCPPainter *painter) -{ - QCPVector2D startVec(start->pixelPosition()); - QCPVector2D endVec(end->pixelPosition()); - if (qFuzzyIsNull((startVec-endVec).lengthSquared())) - return; - // get visible segment of straight line inside clipRect: - double clipPad = qMax(mHead.boundingDistance(), mTail.boundingDistance()); - clipPad = qMax(clipPad, (double)mainPen().widthF()); - QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); - // paint visible segment, if existent: - if (!line.isNull()) - { - painter->setPen(mainPen()); - painter->drawLine(line); - painter->setBrush(Qt::SolidPattern); - if (mTail.style() != QCPLineEnding::esNone) - mTail.draw(painter, startVec, startVec-endVec); - if (mHead.style() != QCPLineEnding::esNone) - mHead.draw(painter, endVec, endVec-startVec); - } -} - -/*! \internal - - Returns the section of the line defined by \a start and \a end, that is visible in the specified - \a rect. - - This is a helper function for \ref draw. -*/ -QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const -{ - bool containsStart = rect.contains(start.x(), start.y()); - bool containsEnd = rect.contains(end.x(), end.y()); - if (containsStart && containsEnd) - return QLineF(start.toPointF(), end.toPointF()); - - QCPVector2D base = start; - QCPVector2D vec = end-start; - double bx, by; - double gamma, mu; - QLineF result; - QList pointVectors; - - if (!qFuzzyIsNull(vec.y())) // line is not horizontal - { - // check top of rect: - bx = rect.left(); - by = rect.top(); - mu = (by-base.y())/vec.y(); - if (mu >= 0 && mu <= 1) - { - gamma = base.x()-bx + mu*vec.x(); - if (gamma >= 0 && gamma <= rect.width()) - pointVectors.append(QCPVector2D(bx+gamma, by)); - } - // check bottom of rect: - bx = rect.left(); - by = rect.bottom(); - mu = (by-base.y())/vec.y(); - if (mu >= 0 && mu <= 1) - { - gamma = base.x()-bx + mu*vec.x(); - if (gamma >= 0 && gamma <= rect.width()) - pointVectors.append(QCPVector2D(bx+gamma, by)); - } - } - if (!qFuzzyIsNull(vec.x())) // line is not vertical - { - // check left of rect: - bx = rect.left(); - by = rect.top(); - mu = (bx-base.x())/vec.x(); - if (mu >= 0 && mu <= 1) - { - gamma = base.y()-by + mu*vec.y(); - if (gamma >= 0 && gamma <= rect.height()) - pointVectors.append(QCPVector2D(bx, by+gamma)); - } - // check right of rect: - bx = rect.right(); - by = rect.top(); - mu = (bx-base.x())/vec.x(); - if (mu >= 0 && mu <= 1) - { - gamma = base.y()-by + mu*vec.y(); - if (gamma >= 0 && gamma <= rect.height()) - pointVectors.append(QCPVector2D(bx, by+gamma)); - } - } - - if (containsStart) - pointVectors.append(start); - if (containsEnd) - pointVectors.append(end); - - // evaluate points: - if (pointVectors.size() == 2) - { - result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); - } else if (pointVectors.size() > 2) - { - // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: - double distSqrMax = 0; - QCPVector2D pv1, pv2; - for (int i=0; i distSqrMax) - { - pv1 = pointVectors.at(i); - pv2 = pointVectors.at(k); - distSqrMax = distSqr; - } - } - } - result.setPoints(pv1.toPointF(), pv2.toPointF()); - } - return result; -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the - item is not selected and mSelectedPen when it is. -*/ -QPen QCPItemLine::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-line.cpp' */ - - -/* including file 'src/items/item-curve.cpp', size 7159 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemCurve -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemCurve - \brief A curved line from one point to another - - \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." - - It has four positions, \a start and \a end, which define the end points of the line, and two - control points which define the direction the line exits from the start and the direction from - which it approaches the end: \a startDir and \a endDir. - - With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an - arrow. - - Often it is desirable for the control points to stay at fixed relative positions to the start/end - point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, - and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. -*/ - -/*! - Creates a curve item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - start(createPosition(QLatin1String("start"))), - startDir(createPosition(QLatin1String("startDir"))), - endDir(createPosition(QLatin1String("endDir"))), - end(createPosition(QLatin1String("end"))) -{ - start->setCoords(0, 0); - startDir->setCoords(0.5, 0); - endDir->setCoords(0, 0.5); - end->setCoords(1, 1); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue,2)); -} - -QCPItemCurve::~QCPItemCurve() -{ -} - -/*! - Sets the pen that will be used to draw the line - - \see setSelectedPen -*/ -void QCPItemCurve::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line when selected - - \see setPen, setSelected -*/ -void QCPItemCurve::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the line ending style of the head. The head corresponds to the \a end position. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify - a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode - - \see setTail -*/ -void QCPItemCurve::setHead(const QCPLineEnding &head) -{ - mHead = head; -} - -/*! - Sets the line ending style of the tail. The tail corresponds to the \a start position. - - Note that due to the overloaded QCPLineEnding constructor, you may directly specify - a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode - - \see setHead -*/ -void QCPItemCurve::setTail(const QCPLineEnding &tail) -{ - mTail = tail; -} - -/* inherits documentation from base class */ -double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QPointF startVec(start->pixelPosition()); - QPointF startDirVec(startDir->pixelPosition()); - QPointF endDirVec(endDir->pixelPosition()); - QPointF endVec(end->pixelPosition()); - - QPainterPath cubicPath(startVec); - cubicPath.cubicTo(startDirVec, endDirVec, endVec); - - QPolygonF polygon = cubicPath.toSubpathPolygons().first(); - QCPVector2D p(pos); - double minDistSqr = std::numeric_limits::max(); - for (int i=1; ipixelPosition()); - QCPVector2D startDirVec(startDir->pixelPosition()); - QCPVector2D endDirVec(endDir->pixelPosition()); - QCPVector2D endVec(end->pixelPosition()); - if ((endVec-startVec).length() > 1e10) // too large curves cause crash - return; - - QPainterPath cubicPath(startVec.toPointF()); - cubicPath.cubicTo(startDirVec.toPointF(), endDirVec.toPointF(), endVec.toPointF()); - - // paint visible segment, if existent: - QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); - QRect cubicRect = cubicPath.controlPointRect().toRect(); - if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position - cubicRect.adjust(0, 0, 1, 1); - if (clip.intersects(cubicRect)) - { - painter->setPen(mainPen()); - painter->drawPath(cubicPath); - painter->setBrush(Qt::SolidPattern); - if (mTail.style() != QCPLineEnding::esNone) - mTail.draw(painter, startVec, M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); - if (mHead.style() != QCPLineEnding::esNone) - mHead.draw(painter, endVec, -cubicPath.angleAtPercent(1)/180.0*M_PI); - } -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the - item is not selected and mSelectedPen when it is. -*/ -QPen QCPItemCurve::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-curve.cpp' */ - - -/* including file 'src/items/item-rect.cpp', size 6479 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemRect -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemRect - \brief A rectangle - - \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a topLeft and \a bottomRight, which define the rectangle. -*/ - -/*! - Creates a rectangle item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - topLeft(createPosition(QLatin1String("topLeft"))), - bottomRight(createPosition(QLatin1String("bottomRight"))), - top(createAnchor(QLatin1String("top"), aiTop)), - topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), - right(createAnchor(QLatin1String("right"), aiRight)), - bottom(createAnchor(QLatin1String("bottom"), aiBottom)), - bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), - left(createAnchor(QLatin1String("left"), aiLeft)) -{ - topLeft->setCoords(0, 1); - bottomRight->setCoords(1, 0); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue,2)); - setBrush(Qt::NoBrush); - setSelectedBrush(Qt::NoBrush); -} - -QCPItemRect::~QCPItemRect() -{ -} - -/*! - Sets the pen that will be used to draw the line of the rectangle - - \see setSelectedPen, setBrush -*/ -void QCPItemRect::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line of the rectangle when selected - - \see setPen, setSelected -*/ -void QCPItemRect::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to - Qt::NoBrush. - - \see setSelectedBrush, setPen -*/ -void QCPItemRect::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a - brush to Qt::NoBrush. - - \see setBrush -*/ -void QCPItemRect::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/* inherits documentation from base class */ -double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()).normalized(); - bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; - return rectDistance(rect, pos, filledRect); -} - -/* inherits documentation from base class */ -void QCPItemRect::draw(QCPPainter *painter) -{ - QPointF p1 = topLeft->pixelPosition(); - QPointF p2 = bottomRight->pixelPosition(); - if (p1.toPoint() == p2.toPoint()) - return; - QRectF rect = QRectF(p1, p2).normalized(); - double clipPad = mainPen().widthF(); - QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); - if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect - { - painter->setPen(mainPen()); - painter->setBrush(mainBrush()); - painter->drawRect(rect); - } -} - -/* inherits documentation from base class */ -QPointF QCPItemRect::anchorPixelPosition(int anchorId) const -{ - QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); - switch (anchorId) - { - case aiTop: return (rect.topLeft()+rect.topRight())*0.5; - case aiTopRight: return rect.topRight(); - case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; - case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; - case aiBottomLeft: return rect.bottomLeft(); - case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; - } - - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemRect::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} - -/*! \internal - - Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item - is not selected and mSelectedBrush when it is. -*/ -QBrush QCPItemRect::mainBrush() const -{ - return mSelected ? mSelectedBrush : mBrush; -} -/* end of 'src/items/item-rect.cpp' */ - - -/* including file 'src/items/item-text.cpp', size 13338 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemText -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemText - \brief A text label - - \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." - - Its position is defined by the member \a position and the setting of \ref setPositionAlignment. - The latter controls which part of the text rect shall be aligned with \a position. - - The text alignment itself (i.e. left, center, right) can be controlled with \ref - setTextAlignment. - - The text may be rotated around the \a position point with \ref setRotation. -*/ - -/*! - Creates a text item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemText::QCPItemText(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - position(createPosition(QLatin1String("position"))), - topLeft(createAnchor(QLatin1String("topLeft"), aiTopLeft)), - top(createAnchor(QLatin1String("top"), aiTop)), - topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), - right(createAnchor(QLatin1String("right"), aiRight)), - bottomRight(createAnchor(QLatin1String("bottomRight"), aiBottomRight)), - bottom(createAnchor(QLatin1String("bottom"), aiBottom)), - bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), - left(createAnchor(QLatin1String("left"), aiLeft)), - mText(QLatin1String("text")), - mPositionAlignment(Qt::AlignCenter), - mTextAlignment(Qt::AlignTop|Qt::AlignHCenter), - mRotation(0) -{ - position->setCoords(0, 0); - - setPen(Qt::NoPen); - setSelectedPen(Qt::NoPen); - setBrush(Qt::NoBrush); - setSelectedBrush(Qt::NoBrush); - setColor(Qt::black); - setSelectedColor(Qt::blue); -} - -QCPItemText::~QCPItemText() -{ -} - -/*! - Sets the color of the text. -*/ -void QCPItemText::setColor(const QColor &color) -{ - mColor = color; -} - -/*! - Sets the color of the text that will be used when the item is selected. -*/ -void QCPItemText::setSelectedColor(const QColor &color) -{ - mSelectedColor = color; -} - -/*! - Sets the pen that will be used do draw a rectangular border around the text. To disable the - border, set \a pen to Qt::NoPen. - - \see setSelectedPen, setBrush, setPadding -*/ -void QCPItemText::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used do draw a rectangular border around the text, when the item is - selected. To disable the border, set \a pen to Qt::NoPen. - - \see setPen -*/ -void QCPItemText::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the brush that will be used do fill the background of the text. To disable the - background, set \a brush to Qt::NoBrush. - - \see setSelectedBrush, setPen, setPadding -*/ -void QCPItemText::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the - background, set \a brush to Qt::NoBrush. - - \see setBrush -*/ -void QCPItemText::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/*! - Sets the font of the text. - - \see setSelectedFont, setColor -*/ -void QCPItemText::setFont(const QFont &font) -{ - mFont = font; -} - -/*! - Sets the font of the text that will be used when the item is selected. - - \see setFont -*/ -void QCPItemText::setSelectedFont(const QFont &font) -{ - mSelectedFont = font; -} - -/*! - Sets the text that will be displayed. Multi-line texts are supported by inserting a line break - character, e.g. '\n'. - - \see setFont, setColor, setTextAlignment -*/ -void QCPItemText::setText(const QString &text) -{ - mText = text; -} - -/*! - Sets which point of the text rect shall be aligned with \a position. - - Examples: - \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such - that the top of the text rect will be horizontally centered on \a position. - \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the - bottom left corner of the text rect. - - If you want to control the alignment of (multi-lined) text within the text rect, use \ref - setTextAlignment. -*/ -void QCPItemText::setPositionAlignment(Qt::Alignment alignment) -{ - mPositionAlignment = alignment; -} - -/*! - Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). -*/ -void QCPItemText::setTextAlignment(Qt::Alignment alignment) -{ - mTextAlignment = alignment; -} - -/*! - Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated - around \a position. -*/ -void QCPItemText::setRotation(double degrees) -{ - mRotation = degrees; -} - -/*! - Sets the distance between the border of the text rectangle and the text. The appearance (and - visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. -*/ -void QCPItemText::setPadding(const QMargins &padding) -{ - mPadding = padding; -} - -/* inherits documentation from base class */ -double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - // The rect may be rotated, so we transform the actual clicked pos to the rotated - // coordinate system, so we can use the normal rectDistance function for non-rotated rects: - QPointF positionPixels(position->pixelPosition()); - QTransform inputTransform; - inputTransform.translate(positionPixels.x(), positionPixels.y()); - inputTransform.rotate(-mRotation); - inputTransform.translate(-positionPixels.x(), -positionPixels.y()); - QPointF rotatedPos = inputTransform.map(pos); - QFontMetrics fontMetrics(mFont); - QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); - QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); - QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); - textBoxRect.moveTopLeft(textPos.toPoint()); - - return rectDistance(textBoxRect, rotatedPos, true); -} - -/* inherits documentation from base class */ -void QCPItemText::draw(QCPPainter *painter) -{ - QPointF pos(position->pixelPosition()); - QTransform transform = painter->transform(); - transform.translate(pos.x(), pos.y()); - if (!qFuzzyIsNull(mRotation)) - transform.rotate(mRotation); - painter->setFont(mainFont()); - QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); - QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); - QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation - textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); - textBoxRect.moveTopLeft(textPos.toPoint()); - double clipPad = mainPen().widthF(); - QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); - if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect()))) - { - painter->setTransform(transform); - if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || - (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) - { - painter->setPen(mainPen()); - painter->setBrush(mainBrush()); - painter->drawRect(textBoxRect); - } - painter->setBrush(Qt::NoBrush); - painter->setPen(QPen(mainColor())); - painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); - } -} - -/* inherits documentation from base class */ -QPointF QCPItemText::anchorPixelPosition(int anchorId) const -{ - // get actual rect points (pretty much copied from draw function): - QPointF pos(position->pixelPosition()); - QTransform transform; - transform.translate(pos.x(), pos.y()); - if (!qFuzzyIsNull(mRotation)) - transform.rotate(mRotation); - QFontMetrics fontMetrics(mainFont()); - QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); - QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); - QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation - textBoxRect.moveTopLeft(textPos.toPoint()); - QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); - - switch (anchorId) - { - case aiTopLeft: return rectPoly.at(0); - case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; - case aiTopRight: return rectPoly.at(1); - case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; - case aiBottomRight: return rectPoly.at(2); - case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; - case aiBottomLeft: return rectPoly.at(3); - case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; - } - - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Returns the point that must be given to the QPainter::drawText function (which expects the top - left point of the text rect), according to the position \a pos, the text bounding box \a rect and - the requested \a positionAlignment. - - For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point - will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally - drawn at that point, the lower left corner of the resulting text rect is at \a pos. -*/ -QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const -{ - if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) - return pos; - - QPointF result = pos; // start at top left - if (positionAlignment.testFlag(Qt::AlignHCenter)) - result.rx() -= rect.width()/2.0; - else if (positionAlignment.testFlag(Qt::AlignRight)) - result.rx() -= rect.width(); - if (positionAlignment.testFlag(Qt::AlignVCenter)) - result.ry() -= rect.height()/2.0; - else if (positionAlignment.testFlag(Qt::AlignBottom)) - result.ry() -= rect.height(); - return result; -} - -/*! \internal - - Returns the font that should be used for drawing text. Returns mFont when the item is not selected - and mSelectedFont when it is. -*/ -QFont QCPItemText::mainFont() const -{ - return mSelected ? mSelectedFont : mFont; -} - -/*! \internal - - Returns the color that should be used for drawing text. Returns mColor when the item is not - selected and mSelectedColor when it is. -*/ -QColor QCPItemText::mainColor() const -{ - return mSelected ? mSelectedColor : mColor; -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemText::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} - -/*! \internal - - Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item - is not selected and mSelectedBrush when it is. -*/ -QBrush QCPItemText::mainBrush() const -{ - return mSelected ? mSelectedBrush : mBrush; -} -/* end of 'src/items/item-text.cpp' */ - - -/* including file 'src/items/item-ellipse.cpp', size 7863 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemEllipse -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemEllipse - \brief An ellipse - - \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. -*/ - -/*! - Creates an ellipse item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - topLeft(createPosition(QLatin1String("topLeft"))), - bottomRight(createPosition(QLatin1String("bottomRight"))), - topLeftRim(createAnchor(QLatin1String("topLeftRim"), aiTopLeftRim)), - top(createAnchor(QLatin1String("top"), aiTop)), - topRightRim(createAnchor(QLatin1String("topRightRim"), aiTopRightRim)), - right(createAnchor(QLatin1String("right"), aiRight)), - bottomRightRim(createAnchor(QLatin1String("bottomRightRim"), aiBottomRightRim)), - bottom(createAnchor(QLatin1String("bottom"), aiBottom)), - bottomLeftRim(createAnchor(QLatin1String("bottomLeftRim"), aiBottomLeftRim)), - left(createAnchor(QLatin1String("left"), aiLeft)), - center(createAnchor(QLatin1String("center"), aiCenter)) -{ - topLeft->setCoords(0, 1); - bottomRight->setCoords(1, 0); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue, 2)); - setBrush(Qt::NoBrush); - setSelectedBrush(Qt::NoBrush); -} - -QCPItemEllipse::~QCPItemEllipse() -{ -} - -/*! - Sets the pen that will be used to draw the line of the ellipse - - \see setSelectedPen, setBrush -*/ -void QCPItemEllipse::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line of the ellipse when selected - - \see setPen, setSelected -*/ -void QCPItemEllipse::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to - Qt::NoBrush. - - \see setSelectedBrush, setPen -*/ -void QCPItemEllipse::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a - brush to Qt::NoBrush. - - \see setBrush -*/ -void QCPItemEllipse::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/* inherits documentation from base class */ -double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QPointF p1 = topLeft->pixelPosition(); - QPointF p2 = bottomRight->pixelPosition(); - QPointF center((p1+p2)/2.0); - double a = qAbs(p1.x()-p2.x())/2.0; - double b = qAbs(p1.y()-p2.y())/2.0; - double x = pos.x()-center.x(); - double y = pos.y()-center.y(); - - // distance to border: - double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); - double result = qAbs(c-1)*qSqrt(x*x+y*y); - // filled ellipse, allow click inside to count as hit: - if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) - { - if (x*x/(a*a) + y*y/(b*b) <= 1) - result = mParentPlot->selectionTolerance()*0.99; - } - return result; -} - -/* inherits documentation from base class */ -void QCPItemEllipse::draw(QCPPainter *painter) -{ - QPointF p1 = topLeft->pixelPosition(); - QPointF p2 = bottomRight->pixelPosition(); - if (p1.toPoint() == p2.toPoint()) - return; - QRectF ellipseRect = QRectF(p1, p2).normalized(); - QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); - if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect - { - painter->setPen(mainPen()); - painter->setBrush(mainBrush()); -#ifdef __EXCEPTIONS - try // drawEllipse sometimes throws exceptions if ellipse is too big - { -#endif - painter->drawEllipse(ellipseRect); -#ifdef __EXCEPTIONS - } catch (...) - { - qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; - setVisible(false); - } -#endif - } -} - -/* inherits documentation from base class */ -QPointF QCPItemEllipse::anchorPixelPosition(int anchorId) const -{ - QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); - switch (anchorId) - { - case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); - case aiTop: return (rect.topLeft()+rect.topRight())*0.5; - case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); - case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; - case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); - case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; - case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); - case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; - case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; - } - - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemEllipse::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} - -/*! \internal - - Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item - is not selected and mSelectedBrush when it is. -*/ -QBrush QCPItemEllipse::mainBrush() const -{ - return mSelected ? mSelectedBrush : mBrush; -} -/* end of 'src/items/item-ellipse.cpp' */ - - -/* including file 'src/items/item-pixmap.cpp', size 10615 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemPixmap -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemPixmap - \brief An arbitrary pixmap - - \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will - be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to - fit the rectangle or be drawn aligned to the topLeft position. - - If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown - on the right side of the example image), the pixmap will be flipped in the respective - orientations. -*/ - -/*! - Creates a rectangle item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - topLeft(createPosition(QLatin1String("topLeft"))), - bottomRight(createPosition(QLatin1String("bottomRight"))), - top(createAnchor(QLatin1String("top"), aiTop)), - topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), - right(createAnchor(QLatin1String("right"), aiRight)), - bottom(createAnchor(QLatin1String("bottom"), aiBottom)), - bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), - left(createAnchor(QLatin1String("left"), aiLeft)), - mScaled(false), - mScaledPixmapInvalidated(true), - mAspectRatioMode(Qt::KeepAspectRatio), - mTransformationMode(Qt::SmoothTransformation) -{ - topLeft->setCoords(0, 1); - bottomRight->setCoords(1, 0); - - setPen(Qt::NoPen); - setSelectedPen(QPen(Qt::blue)); -} - -QCPItemPixmap::~QCPItemPixmap() -{ -} - -/*! - Sets the pixmap that will be displayed. -*/ -void QCPItemPixmap::setPixmap(const QPixmap &pixmap) -{ - mPixmap = pixmap; - mScaledPixmapInvalidated = true; - if (mPixmap.isNull()) - qDebug() << Q_FUNC_INFO << "pixmap is null"; -} - -/*! - Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a - bottomRight positions. -*/ -void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode) -{ - mScaled = scaled; - mAspectRatioMode = aspectRatioMode; - mTransformationMode = transformationMode; - mScaledPixmapInvalidated = true; -} - -/*! - Sets the pen that will be used to draw a border around the pixmap. - - \see setSelectedPen, setBrush -*/ -void QCPItemPixmap::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw a border around the pixmap when selected - - \see setPen, setSelected -*/ -void QCPItemPixmap::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/* inherits documentation from base class */ -double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - return rectDistance(getFinalRect(), pos, true); -} - -/* inherits documentation from base class */ -void QCPItemPixmap::draw(QCPPainter *painter) -{ - bool flipHorz = false; - bool flipVert = false; - QRect rect = getFinalRect(&flipHorz, &flipVert); - double clipPad = mainPen().style() == Qt::NoPen ? 0 : mainPen().widthF(); - QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); - if (boundingRect.intersects(clipRect())) - { - updateScaledPixmap(rect, flipHorz, flipVert); - painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); - QPen pen = mainPen(); - if (pen.style() != Qt::NoPen) - { - painter->setPen(pen); - painter->setBrush(Qt::NoBrush); - painter->drawRect(rect); - } - } -} - -/* inherits documentation from base class */ -QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const -{ - bool flipHorz; - bool flipVert; - QRect rect = getFinalRect(&flipHorz, &flipVert); - // we actually want denormal rects (negative width/height) here, so restore - // the flipped state: - if (flipHorz) - rect.adjust(rect.width(), 0, -rect.width(), 0); - if (flipVert) - rect.adjust(0, rect.height(), 0, -rect.height()); - - switch (anchorId) - { - case aiTop: return (rect.topLeft()+rect.topRight())*0.5; - case aiTopRight: return rect.topRight(); - case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; - case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; - case aiBottomLeft: return rect.bottomLeft(); - case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; - } - - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The - parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped - horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a - bottomRight.) - - This function only creates the scaled pixmap when the buffered pixmap has a different size than - the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does - not cause expensive rescaling every time. - - If scaling is disabled, sets mScaledPixmap to a null QPixmap. -*/ -void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) -{ - if (mPixmap.isNull()) - return; - - if (mScaled) - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - double devicePixelRatio = mPixmap.devicePixelRatio(); -#else - double devicePixelRatio = 1.0; -#endif - if (finalRect.isNull()) - finalRect = getFinalRect(&flipHorz, &flipVert); - if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()/devicePixelRatio) - { - mScaledPixmap = mPixmap.scaled(finalRect.size()*devicePixelRatio, mAspectRatioMode, mTransformationMode); - if (flipHorz || flipVert) - mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - mScaledPixmap.setDevicePixelRatio(devicePixelRatio); -#endif - } - } else if (!mScaledPixmap.isNull()) - mScaledPixmap = QPixmap(); - mScaledPixmapInvalidated = false; -} - -/*! \internal - - Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions - and scaling settings. - - The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn - flipped horizontally or vertically in the returned rect. (The returned rect itself is always - normalized, i.e. the top left corner of the rect is actually further to the top/left than the - bottom right corner). This is the case when the item position \a topLeft is further to the - bottom/right than \a bottomRight. - - If scaling is disabled, returns a rect with size of the original pixmap and the top left corner - aligned with the item position \a topLeft. The position \a bottomRight is ignored. -*/ -QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const -{ - QRect result; - bool flipHorz = false; - bool flipVert = false; - QPoint p1 = topLeft->pixelPosition().toPoint(); - QPoint p2 = bottomRight->pixelPosition().toPoint(); - if (p1 == p2) - return QRect(p1, QSize(0, 0)); - if (mScaled) - { - QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); - QPoint topLeft = p1; - if (newSize.width() < 0) - { - flipHorz = true; - newSize.rwidth() *= -1; - topLeft.setX(p2.x()); - } - if (newSize.height() < 0) - { - flipVert = true; - newSize.rheight() *= -1; - topLeft.setY(p2.y()); - } - QSize scaledSize = mPixmap.size(); -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - scaledSize /= mPixmap.devicePixelRatio(); - scaledSize.scale(newSize*mPixmap.devicePixelRatio(), mAspectRatioMode); -#else - scaledSize.scale(newSize, mAspectRatioMode); -#endif - result = QRect(topLeft, scaledSize); - } else - { -#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED - result = QRect(p1, mPixmap.size()/mPixmap.devicePixelRatio()); -#else - result = QRect(p1, mPixmap.size()); -#endif - } - if (flippedHorz) - *flippedHorz = flipHorz; - if (flippedVert) - *flippedVert = flipVert; - return result; -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemPixmap::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-pixmap.cpp' */ - - -/* including file 'src/items/item-tracer.cpp', size 14624 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemTracer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemTracer - \brief Item that sticks to QCPGraph data points - - \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." - - The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt - the coordinate axes of the graph and update its \a position to be on the graph's data. This means - the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a - QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a - position will have no effect because they will be overriden in the next redraw (this is when the - coordinate update happens). - - If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will - stay at the corresponding end of the graph. - - With \ref setInterpolating you may specify whether the tracer may only stay exactly on data - points or whether it interpolates data points linearly, if given a key that lies between two data - points of the graph. - - The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer - have no own visual appearance (set the style to \ref tsNone), and just connect other item - positions to the tracer \a position (used as an anchor) via \ref - QCPItemPosition::setParentAnchor. - - \note The tracer position is only automatically updated upon redraws. So when the data of the - graph changes and immediately afterwards (without a redraw) the position coordinates of the - tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref - updatePosition must be called manually, prior to reading the tracer coordinates. -*/ - -/*! - Creates a tracer item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - position(createPosition(QLatin1String("position"))), - mSize(6), - mStyle(tsCrosshair), - mGraph(0), - mGraphKey(0), - mInterpolating(false), - mType(-1) -{ - position->setCoords(0, 0); - - setBrush(Qt::NoBrush); - setSelectedBrush(Qt::NoBrush); - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue, 2)); -} - -QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush, const QList &alarmStatusList) - : QCPAbstractItem(parentPlot), - position(createPosition(QLatin1String("position"))), - mPen(pen), - mBrush(brush), - mSize(5), - mStyle(tsCircle), - mGraph(0), - mGraphKey(0), - mInterpolating(true), - mType(type), - mTimeStamp(timeStamp), - m_alarmStatusList(alarmStatusList) -{ - position->setCoords(0, 0); - setSelectedBrush(Qt::NoBrush); - setSelectedPen(QPen(Qt::blue, 2)); -} - -QCPItemTracer::~QCPItemTracer() -{ -} - -/*! - Sets the pen that will be used to draw the line of the tracer - - \see setSelectedPen, setBrush -*/ -void QCPItemTracer::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the line of the tracer when selected - - \see setPen, setSelected -*/ -void QCPItemTracer::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the brush that will be used to draw any fills of the tracer - - \see setSelectedBrush, setPen -*/ -void QCPItemTracer::setBrush(const QBrush &brush) -{ - mBrush = brush; -} - -/*! - Sets the brush that will be used to draw any fills of the tracer, when selected. - - \see setBrush, setSelected -*/ -void QCPItemTracer::setSelectedBrush(const QBrush &brush) -{ - mSelectedBrush = brush; -} - -/*! - Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare - does, \ref tsCrosshair does not). -*/ -void QCPItemTracer::setSize(double size) -{ - mSize = size; -} - -/*! - Sets the style/visual appearance of the tracer. - - If you only want to use the tracer \a position as an anchor for other items, set \a style to - \ref tsNone. -*/ -void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) -{ - mStyle = style; -} - -/*! - Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type - QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. - - To free the tracer from any graph, set \a graph to 0. The tracer \a position can then be placed - freely like any other item position. This is the state the tracer will assume when its graph gets - deleted while still attached to it. - - \see setGraphKey -*/ -void QCPItemTracer::setGraph(QCPGraph *graph) -{ - if (graph) - { - if (graph->parentPlot() == mParentPlot) - { - position->setType(QCPItemPosition::ptPlotCoords); - position->setAxes(graph->keyAxis(), graph->valueAxis()); - mGraph = graph; - updatePosition(); - } else - qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; - } else - { - mGraph = 0; - } -} - -/*! - Sets the key of the graph's data point the tracer will be positioned at. This is the only free - coordinate of a tracer when attached to a graph. - - Depending on \ref setInterpolating, the tracer will be either positioned on the data point - closest to \a key, or will stay exactly at \a key and interpolate the value linearly. - - \see setGraph, setInterpolating -*/ -void QCPItemTracer::setGraphKey(double key) -{ - mGraphKey = key; -} - -void QCPItemTracer::setHidePoint(const QMultiMap &hidePoint) -{ - m_hidePoint = hidePoint; -} - -void QCPItemTracer::addHidePoint(const qint64 &time, const QString &tag) -{ - m_hidePoint.insert(time, tag); -} - -/*! - Sets whether the value of the graph's data points shall be interpolated, when positioning the - tracer. - - If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on - the data point of the graph which is closest to the key, but which is not necessarily exactly - there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and - the appropriate value will be interpolated from the graph's data points linearly. - - \see setGraph, setGraphKey -*/ -void QCPItemTracer::setInterpolating(bool enabled) -{ - mInterpolating = enabled; -} - -void QCPItemTracer::setType(const int &type) -{ - mType = type; -} - -void QCPItemTracer::setTimeStamp(const qint64 &timeStamp) -{ - mTimeStamp = timeStamp; -} - -void QCPItemTracer::setInfo(const QStringList infos) -{ - m_infos = infos; -} - -void QCPItemTracer::showTips() -{ - QString tips; - tips += m_infos.join("\n\n"); - CToolTip::popup(mParentPlot->mapToGlobal(position->pixelPosition().toPoint()), tips, this->parentPlot()); -} - -/* inherits documentation from base class */ -double QCPItemTracer::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QPointF center(position->pixelPosition()); - double w = mSize/2.0; - QRect clip = clipRect(); - switch (mStyle) - { - case tsNone: return -1; - case tsPlus: - { - if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(center+QPointF(-w, 0), center+QPointF(w, 0)), - QCPVector2D(pos).distanceSquaredToLine(center+QPointF(0, -w), center+QPointF(0, w)))); - break; - } - case tsCrosshair: - { - return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(clip.left(), center.y()), QCPVector2D(clip.right(), center.y())), - QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(center.x(), clip.top()), QCPVector2D(center.x(), clip.bottom())))); - } - case tsCircle: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - { - // distance to border: - double centerDist = QCPVector2D(center-pos).length(); - double circleLine = w; - double result = qAbs(centerDist-circleLine); - // filled ellipse, allow click inside to count as hit: - if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) - { - if (centerDist <= circleLine) - result = mParentPlot->selectionTolerance()*0.99; - } - return result; - } - break; - } - case tsSquare: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - { - QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); - bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; - return rectDistance(rect, pos, filledRect); - } - break; - } - } - return -1; -} - -/* inherits documentation from base class */ -void QCPItemTracer::draw(QCPPainter *painter) -{ - updatePosition(); - if (mStyle == tsNone) - return; - - painter->setPen(mainPen()); - painter->setBrush(mainBrush()); - QPointF center(position->pixelPosition()); - double w = mSize/2.0; - QRect clip = clipRect(); - switch (mStyle) - { - case tsNone: return; - case tsPlus: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - { - painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); - painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); - } - break; - } - case tsCrosshair: - { - if (center.y() > clip.top() && center.y() < clip.bottom()) - painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); - if (center.x() > clip.left() && center.x() < clip.right()) - painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); - break; - } - case tsCircle: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - painter->drawEllipse(center, w, w); - break; - } - case tsSquare: - { - if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) - painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); - break; - } - } -} - -void QCPItemTracer::mousePressEvent(QMouseEvent *event, const QVariant &details) -{ - QCPAbstractItem::mousePressEvent(event, details); -} - -void QCPItemTracer::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) -{ - QCPAbstractItem::mouseMoveEvent(event, startPos); - - if(QPoint(event->pos() - position->pixelPosition().toPoint()).manhattanLength() > 8) - { - hovFlag = 0; - return; - } - else if(QPoint(event->pos() - position->pixelPosition().toPoint()).manhattanLength() < 8) - { - if(hovFlag == 0) - hovFlag = 1; - } - if(hovFlag == 1) - { - emit itemTracerHoverd(mTimeStamp, m_hidePoint, m_alarmStatusList); - hovFlag = 2; - } -} - -/*! - If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a - position to reside on the graph data, depending on the configured key (\ref setGraphKey). - - It is called automatically on every redraw and normally doesn't need to be called manually. One - exception is when you want to read the tracer coordinates via \a position and are not sure that - the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. - In that situation, call this function before accessing \a position, to make sure you don't get - out-of-date coordinates. - - If there is no graph set on this tracer, this function does nothing. -*/ -void QCPItemTracer::updatePosition() -{ - if (mGraph) - { - if (mParentPlot->hasPlottable(mGraph)) - { - if (mGraph->data()->size() > 1) - { - QCPGraphDataContainer::const_iterator first = mGraph->data()->constBegin(); - QCPGraphDataContainer::const_iterator last = mGraph->data()->constEnd()-1; - if (mGraphKey <= first->key) - position->setCoords(first->key, first->value); - else if (mGraphKey >= last->key) - position->setCoords(last->key, last->value); - else - { - if(QCPGraph::lsStepLeft == mGraph->lineStyle()) - { - QCPGraphDataContainer::const_iterator it = mGraph->data()->findEnd(mGraphKey, false); - if(it != mGraph->data()->constBegin()) - { - --it; - } - if (mInterpolating) - { - position->setCoords(mGraphKey, it->value); - } - else - { - position->setCoords(it->key, it->value); - } - } - else - { - QCPGraphDataContainer::const_iterator it = mGraph->data()->findBegin(mGraphKey); - if (it != mGraph->data()->constEnd()) // mGraphKey is not exactly on last iterator, but somewhere between iterators - { - QCPGraphDataContainer::const_iterator prevIt = it; - ++it; // won't advance to constEnd because we handled that case (mGraphKey >= last->key) before - if (mInterpolating) - { - // interpolate between iterators around mGraphKey: - double slope = 0; - if (!qFuzzyCompare((double)it->key, (double)prevIt->key)) - slope = (it->value-prevIt->value)/(it->key-prevIt->key); - position->setCoords(mGraphKey, (mGraphKey-prevIt->key)*slope+prevIt->value); - } else - { - // find iterator with key closest to mGraphKey: - if (mGraphKey < (prevIt->key+it->key)*0.5) - position->setCoords(prevIt->key, prevIt->value); - else - position->setCoords(it->key, it->value); - } - } else // mGraphKey is exactly on last iterator (should actually be caught when comparing first/last keys, but this is a failsafe for fp uncertainty) - position->setCoords(it->key, it->value); - } - } - } else if (mGraph->data()->size() == 1) - { - QCPGraphDataContainer::const_iterator it = mGraph->data()->constBegin(); - position->setCoords(it->key, it->value); - } else - qDebug() << Q_FUNC_INFO << "graph has no data"; - } else - qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; - } -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected - and mSelectedPen when it is. -*/ -QPen QCPItemTracer::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} - -/*! \internal - - Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item - is not selected and mSelectedBrush when it is. -*/ -QBrush QCPItemTracer::mainBrush() const -{ - return mSelected ? mSelectedBrush : mBrush; -} -/* end of 'src/items/item-tracer.cpp' */ - - -/* including file 'src/items/item-bracket.cpp', size 10687 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPItemBracket -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPItemBracket - \brief A bracket for referencing/highlighting certain parts in the plot. - - \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." - - It has two positions, \a left and \a right, which define the span of the bracket. If \a left is - actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the - example image. - - The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket - stretches away from the embraced span, can be controlled with \ref setLength. - - \image html QCPItemBracket-length.png -
Demonstrating the effect of different values for \ref setLength, for styles \ref - bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
- - It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine - or QCPItemCurve) or a text label (QCPItemText), to the bracket. -*/ - -/*! - Creates a bracket item and sets default values. - - The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes - ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. -*/ -QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : - QCPAbstractItem(parentPlot), - left(createPosition(QLatin1String("left"))), - right(createPosition(QLatin1String("right"))), - center(createAnchor(QLatin1String("center"), aiCenter)), - mLength(8), - mStyle(bsCalligraphic) -{ - left->setCoords(0, 0); - right->setCoords(1, 1); - - setPen(QPen(Qt::black)); - setSelectedPen(QPen(Qt::blue, 2)); -} - -QCPItemBracket::~QCPItemBracket() -{ -} - -/*! - Sets the pen that will be used to draw the bracket. - - Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the - stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use - \ref setLength, which has a similar effect. - - \see setSelectedPen -*/ -void QCPItemBracket::setPen(const QPen &pen) -{ - mPen = pen; -} - -/*! - Sets the pen that will be used to draw the bracket when selected - - \see setPen, setSelected -*/ -void QCPItemBracket::setSelectedPen(const QPen &pen) -{ - mSelectedPen = pen; -} - -/*! - Sets the \a length in pixels how far the bracket extends in the direction towards the embraced - span of the bracket (i.e. perpendicular to the left-right-direction) - - \image html QCPItemBracket-length.png -
Demonstrating the effect of different values for \ref setLength, for styles \ref - bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
-*/ -void QCPItemBracket::setLength(double length) -{ - mLength = length; -} - -/*! - Sets the style of the bracket, i.e. the shape/visual appearance. - - \see setPen -*/ -void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) -{ - mStyle = style; -} - -/* inherits documentation from base class */ -double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - Q_UNUSED(details) - if (onlySelectable && !mSelectable) - return -1; - - QCPVector2D p(pos); - QCPVector2D leftVec(left->pixelPosition()); - QCPVector2D rightVec(right->pixelPosition()); - if (leftVec.toPoint() == rightVec.toPoint()) - return -1; - - QCPVector2D widthVec = (rightVec-leftVec)*0.5; - QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; - QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; - - switch (mStyle) - { - case QCPItemBracket::bsSquare: - case QCPItemBracket::bsRound: - { - double a = p.distanceSquaredToLine(centerVec-widthVec, centerVec+widthVec); - double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec, centerVec-widthVec); - double c = p.distanceSquaredToLine(centerVec+widthVec+lengthVec, centerVec+widthVec); - return qSqrt(qMin(qMin(a, b), c)); - } - case QCPItemBracket::bsCurly: - case QCPItemBracket::bsCalligraphic: - { - double a = p.distanceSquaredToLine(centerVec-widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); - double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec*0.7, centerVec-widthVec*0.75+lengthVec*0.15); - double c = p.distanceSquaredToLine(centerVec+widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); - double d = p.distanceSquaredToLine(centerVec+widthVec+lengthVec*0.7, centerVec+widthVec*0.75+lengthVec*0.15); - return qSqrt(qMin(qMin(a, b), qMin(c, d))); - } - } - return -1; -} - -/* inherits documentation from base class */ -void QCPItemBracket::draw(QCPPainter *painter) -{ - QCPVector2D leftVec(left->pixelPosition()); - QCPVector2D rightVec(right->pixelPosition()); - if (leftVec.toPoint() == rightVec.toPoint()) - return; - - QCPVector2D widthVec = (rightVec-leftVec)*0.5; - QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; - QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; - - QPolygon boundingPoly; - boundingPoly << leftVec.toPoint() << rightVec.toPoint() - << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); - QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); - if (clip.intersects(boundingPoly.boundingRect())) - { - painter->setPen(mainPen()); - switch (mStyle) - { - case bsSquare: - { - painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); - painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); - painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - break; - } - case bsRound: - { - painter->setBrush(Qt::NoBrush); - QPainterPath path; - path.moveTo((centerVec+widthVec+lengthVec).toPointF()); - path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); - path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - painter->drawPath(path); - break; - } - case bsCurly: - { - painter->setBrush(Qt::NoBrush); - QPainterPath path; - path.moveTo((centerVec+widthVec+lengthVec).toPointF()); - path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+lengthVec).toPointF(), centerVec.toPointF()); - path.cubicTo((centerVec-0.4*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - painter->drawPath(path); - break; - } - case bsCalligraphic: - { - painter->setPen(Qt::NoPen); - painter->setBrush(QBrush(mainPen().color())); - QPainterPath path; - path.moveTo((centerVec+widthVec+lengthVec).toPointF()); - - path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); - path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); - - path.cubicTo((centerVec-widthVec-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); - path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); - - painter->drawPath(path); - break; - } - } - } -} - -/* inherits documentation from base class */ -QPointF QCPItemBracket::anchorPixelPosition(int anchorId) const -{ - QCPVector2D leftVec(left->pixelPosition()); - QCPVector2D rightVec(right->pixelPosition()); - if (leftVec.toPoint() == rightVec.toPoint()) - return leftVec.toPointF(); - - QCPVector2D widthVec = (rightVec-leftVec)*0.5; - QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; - QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; - - switch (anchorId) - { - case aiCenter: - return centerVec.toPointF(); - } - qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; - return QPointF(); -} - -/*! \internal - - Returns the pen that should be used for drawing lines. Returns mPen when the - item is not selected and mSelectedPen when it is. -*/ -QPen QCPItemBracket::mainPen() const -{ - return mSelected ? mSelectedPen : mPen; -} -/* end of 'src/items/item-bracket.cpp' */ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2017 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 04.09.17 ** +** Version: 2.0.0 ** +****************************************************************************/ + +#include "qcustomplot.h" +#include "../widgets/CToolTip.h" + +/* including file 'src/vector2d.cpp', size 7340 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPVector2D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPVector2D + \brief Represents two doubles as a mathematical 2D vector + + This class acts as a replacement for QVector2D with the advantage of double precision instead of + single, and some convenience methods tailored for the QCustomPlot library. +*/ + +/* start documentation of inline functions */ + +/*! \fn void QCPVector2D::setX(double x) + + Sets the x coordinate of this vector to \a x. + + \see setY +*/ + +/*! \fn void QCPVector2D::setY(double y) + + Sets the y coordinate of this vector to \a y. + + \see setX +*/ + +/*! \fn double QCPVector2D::length() const + + Returns the length of this vector. + + \see lengthSquared +*/ + +/*! \fn double QCPVector2D::lengthSquared() const + + Returns the squared length of this vector. In some situations, e.g. when just trying to find the + shortest vector of a group, this is faster than calculating \ref length, because it avoids + calculation of a square root. + + \see length +*/ + +/*! \fn QPoint QCPVector2D::toPoint() const + + Returns a QPoint which has the x and y coordinates of this vector, truncating any floating point + information. + + \see toPointF +*/ + +/*! \fn QPointF QCPVector2D::toPointF() const + + Returns a QPointF which has the x and y coordinates of this vector. + + \see toPoint +*/ + +/*! \fn bool QCPVector2D::isNull() const + + Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y + coordinates, i.e. if both are binary equal to 0. +*/ + +/*! \fn QCPVector2D QCPVector2D::perpendicular() const + + Returns a vector perpendicular to this vector, with the same length. +*/ + +/*! \fn double QCPVector2D::dot() const + + Returns the dot/scalar product of this vector with the specified vector \a vec. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates to 0. +*/ +QCPVector2D::QCPVector2D() : + mX(0), + mY(0) +{ +} + +/*! + Creates a QCPVector2D object and initializes the \a x and \a y coordinates with the specified + values. +*/ +QCPVector2D::QCPVector2D(double x, double y) : + mX(x), + mY(y) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPoint &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPointF &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Normalizes this vector. After this operation, the length of the vector is equal to 1. + + \see normalized, length, lengthSquared +*/ +void QCPVector2D::normalize() +{ + double len = length(); + mX /= len; + mY /= len; +} + +/*! + Returns a normalized version of this vector. The length of the returned vector is equal to 1. + + \see normalize, length, lengthSquared +*/ +QCPVector2D QCPVector2D::normalized() const +{ + QCPVector2D result(mX, mY); + result.normalize(); + return result; +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a start and \a end. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const +{ + QCPVector2D v(end-start); + double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + double mu = v.dot(*this-start)/vLengthSqr; + if (mu < 0) + return (*this-start).lengthSquared(); + else if (mu > 1) + return (*this-end).lengthSquared(); + else + return ((start + mu*v)-*this).lengthSquared(); + } else + return (*this-start).lengthSquared(); +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a line. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QLineF &line) const +{ + return distanceSquaredToLine(QCPVector2D(line.p1()), QCPVector2D(line.p2())); +} + +/*! + Returns the shortest distance of this vector (interpreted as a point) to the infinite straight + line given by a \a base point and a \a direction vector. + + \see distanceSquaredToLine +*/ +double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const +{ + return qAbs((*this-base).dot(direction.perpendicular()))/direction.length(); +} + +/*! + Scales this vector by the given \a factor, i.e. the x and y components are multiplied by \a + factor. +*/ +QCPVector2D &QCPVector2D::operator*=(double factor) +{ + mX *= factor; + mY *= factor; + return *this; +} + +/*! + Scales this vector by the given \a divisor, i.e. the x and y components are divided by \a + divisor. +*/ +QCPVector2D &QCPVector2D::operator/=(double divisor) +{ + mX /= divisor; + mY /= divisor; + return *this; +} + +/*! + Adds the given \a vector to this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator+=(const QCPVector2D &vector) +{ + mX += vector.mX; + mY += vector.mY; + return *this; +} + +/*! + subtracts the given \a vector from this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator-=(const QCPVector2D &vector) +{ + mX -= vector.mX; + mY -= vector.mY; + return *this; +} +/* end of 'src/vector2d.cpp' */ + + +/* including file 'src/painter.cpp', size 8670 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPainter +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPainter + \brief QPainter subclass used internally + + This QPainter subclass is used to provide some extended functionality e.g. for tweaking position + consistency between antialiased and non-antialiased painting. Further it provides workarounds + for QPainter quirks. + + \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and + restore. So while it is possible to pass a QCPPainter instance to a function that expects a + QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because + it will call the base class implementations of the functions actually hidden by QCPPainter). +*/ + +/*! + Creates a new QCPPainter instance and sets default values +*/ +QCPPainter::QCPPainter() : + QPainter(), + mModes(pmDefault), + mIsAntialiasing(false) +{ + // don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and + // a call to begin() will follow +} + +/*! + Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just + like the analogous QPainter constructor, begins painting on \a device immediately. + + Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. +*/ +QCPPainter::QCPPainter(QPaintDevice *device) : + QPainter(device), + mModes(pmDefault), + mIsAntialiasing(false) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (isActive()) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif +} + +/*! + Sets the pen of the painter and applies certain fixes to it, depending on the mode of this + QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QPen &pen) +{ + QPainter::setPen(pen); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QColor &color) +{ + QPainter::setPen(color); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(Qt::PenStyle penStyle) +{ + QPainter::setPen(penStyle); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when + antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to + integer coordinates and then passes it to the original drawLine. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::drawLine(const QLineF &line) +{ + if (mIsAntialiasing || mModes.testFlag(pmVectorized)) + QPainter::drawLine(line); + else + QPainter::drawLine(line.toLine()); +} + +/*! + Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint + with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between + antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for + AA/Non-AA painting). +*/ +void QCPPainter::setAntialiasing(bool enabled) +{ + setRenderHint(QPainter::Antialiasing, enabled); + if (mIsAntialiasing != enabled) + { + mIsAntialiasing = enabled; + if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs + { + if (mIsAntialiasing) + translate(0.5, 0.5); + else + translate(-0.5, -0.5); + } + } +} + +/*! + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setModes(QCPPainter::PainterModes modes) +{ + mModes = modes; +} + +/*! + Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a + device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, + all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that + behaviour. + + The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets + the render hint as appropriate. + + \note this function hides the non-virtual base class implementation. +*/ +bool QCPPainter::begin(QPaintDevice *device) +{ + bool result = QPainter::begin(device); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (result) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif + return result; +} + +/*! \overload + + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) +{ + if (!enabled && mModes.testFlag(mode)) + mModes &= ~mode; + else if (enabled && !mModes.testFlag(mode)) + mModes |= mode; +} + +/*! + Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see restore +*/ +void QCPPainter::save() +{ + mAntialiasingStack.push(mIsAntialiasing); + QPainter::save(); +} + +/*! + Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see save +*/ +void QCPPainter::restore() +{ + if (!mAntialiasingStack.isEmpty()) + mIsAntialiasing = mAntialiasingStack.pop(); + else + qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; + QPainter::restore(); +} + +/*! + Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen + overrides when the \ref pmNonCosmetic mode is set. +*/ +void QCPPainter::makeNonCosmetic() +{ + if (qFuzzyIsNull(pen().widthF())) + { + QPen p = pen(); + p.setWidth(1); + QPainter::setPen(p); + } +} +/* end of 'src/painter.cpp' */ + + +/* including file 'src/paintbuffer.cpp', size 18502 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPaintBuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPaintBuffer + \brief The abstract base class for paint buffers, which define the rendering backend + + This abstract base class defines the basic interface that a paint buffer needs to provide in + order to be usable by QCustomPlot. + + A paint buffer manages both a surface to draw onto, and the matching paint device. The size of + the surface can be changed via \ref setSize. External classes (\ref QCustomPlot and \ref + QCPLayer) request a painter via \ref startPainting and then perform the draw calls. Once the + painting is complete, \ref donePainting is called, so the paint buffer implementation can do + clean up if necessary. Before rendering a frame, each paint buffer is usually filled with a color + using \ref clear (usually the color is \c Qt::transparent), to remove the contents of the + previous frame. + + The simplest paint buffer implementation is \ref QCPPaintBufferPixmap which allows regular + software rendering via the raster engine. Hardware accelerated rendering via pixel buffers and + frame buffer objects is provided by \ref QCPPaintBufferGlPbuffer and \ref QCPPaintBufferGlFbo. + They are used automatically if \ref QCustomPlot::setOpenGl is enabled. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual QCPPainter *QCPAbstractPaintBuffer::startPainting() = 0 + + Returns a \ref QCPPainter which is ready to draw to this buffer. The ownership and thus the + responsibility to delete the painter after the painting operations are complete is given to the + caller of this method. + + Once you are done using the painter, delete the painter and call \ref donePainting. + + While a painter generated with this method is active, you must not call \ref setSize, \ref + setDevicePixelRatio or \ref clear. + + This method may return 0, if a painter couldn't be activated on the buffer. This usually + indicates a problem with the respective painting backend. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::draw(QCPPainter *painter) const = 0 + + Draws the contents of this buffer with the provided \a painter. This is the method that is used + to finally join all paint buffers and draw them onto the screen. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::clear(const QColor &color) = 0 + + Fills the entire buffer with the provided \a color. To have an empty transparent buffer, use the + named color \c Qt::transparent. + + This method must not be called if there is currently a painter (acquired with \ref startPainting) + active. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::reallocateBuffer() = 0 + + Reallocates the internal buffer with the currently configured size (\ref setSize) and device + pixel ratio, if applicable (\ref setDevicePixelRatio). It is called as soon as any of those + properties are changed on this paint buffer. + + \note Subclasses of \ref QCPAbstractPaintBuffer must call their reimplementation of this method + in their constructor, to perform the first allocation (this can not be done by the base class + because calling pure virtual methods in base class constructors is not possible). +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of inline functions */ + +/*! \fn virtual void QCPAbstractPaintBuffer::donePainting() + + If you have acquired a \ref QCPPainter to paint onto this paint buffer via \ref startPainting, + call this method as soon as you are done with the painting operations and have deleted the + painter. + + paint buffer subclasses may use this method to perform any type of cleanup that is necessary. The + default implementation does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a paint buffer and initializes it with the provided \a size and \a devicePixelRatio. + + Subclasses must call their \ref reallocateBuffer implementation in their respective constructors. +*/ +QCPAbstractPaintBuffer::QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio) : + mSize(size), + mDevicePixelRatio(devicePixelRatio), + mInvalidated(true) +{ +} + +QCPAbstractPaintBuffer::~QCPAbstractPaintBuffer() +{ +} + +/*! + Sets the paint buffer size. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + If \a size is already the current buffer size, this method does nothing. +*/ +void QCPAbstractPaintBuffer::setSize(const QSize &size) +{ + if (mSize != size) + { + mSize = size; + reallocateBuffer(); + } +} + +/*! + Sets the invalidated flag to \a invalidated. + + This mechanism is used internally in conjunction with isolated replotting of \ref QCPLayer + instances (in \ref QCPLayer::lmBuffered mode). If \ref QCPLayer::replot is called on a buffered + layer, i.e. an isolated repaint of only that layer (and its dedicated paint buffer) is requested, + QCustomPlot will decide depending on the invalidated flags of other paint buffers whether it also + replots them, instead of only the layer on which the replot was called. + + The invalidated flag is set to true when \ref QCPLayer association has changed, i.e. if layers + were added or removed from this buffer, or if they were reordered. It is set to false as soon as + all associated \ref QCPLayer instances are drawn onto the buffer. + + Under normal circumstances, it is not necessary to manually call this method. +*/ +void QCPAbstractPaintBuffer::setInvalidated(bool invalidated) +{ + mInvalidated = invalidated; +} + +/*! + Sets the the device pixel ratio to \a ratio. This is useful to render on high-DPI output devices. + The ratio is automatically set to the device pixel ratio used by the parent QCustomPlot instance. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + \note This method is only available for Qt versions 5.4 and higher. +*/ +void QCPAbstractPaintBuffer::setDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mDevicePixelRatio = ratio; + reallocateBuffer(); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; +#endif + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferPixmap + \brief A paint buffer based on QPixmap, using software raster rendering + + This paint buffer is the default and fall-back paint buffer which uses software rendering and + QPixmap as internal buffer. It is used if \ref QCustomPlot::setOpenGl is false. +*/ + +/*! + Creates a pixmap paint buffer instancen with the specified \a size and \a devicePixelRatio, if + applicable. +*/ +QCPPaintBufferPixmap::QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio) : + QCPAbstractPaintBuffer(size, devicePixelRatio) +{ + QCPPaintBufferPixmap::reallocateBuffer(); +} + +QCPPaintBufferPixmap::~QCPPaintBufferPixmap() +{ +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferPixmap::startPainting() +{ + QCPPainter *result = new QCPPainter(&mBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::draw(QCPPainter *painter) const +{ + if (painter && painter->isActive()) + painter->drawPixmap(0, 0, mBuffer); + else + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::clear(const QColor &color) +{ + mBuffer.fill(color); +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::reallocateBuffer() +{ + setInvalidated(); + if (!qFuzzyCompare(1.0, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBuffer = QPixmap(mSize*mDevicePixelRatio); + mBuffer.setDevicePixelRatio(mDevicePixelRatio); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; + mBuffer = QPixmap(mSize); +#endif + } else + { + mBuffer = QPixmap(mSize); + } +} + + +#ifdef QCP_OPENGL_PBUFFER +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlPbuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlPbuffer + \brief A paint buffer based on OpenGL pixel buffers, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL pixel buffers (pbuffer) and is used in Qt versions before 5.0. + (See \ref QCPPaintBufferGlFbo used in newer Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlPbuffer instance with the specified \a size and \a + devicePixelRatio, if applicable. + + The parameter \a multisamples defines how many samples are used per pixel. Higher values thus + result in higher quality antialiasing. If the specified \a multisamples value exceeds the + capability of the graphics hardware, the highest supported multisampling is used. +*/ +QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlPBuffer(0), + mMultisamples(qMax(0, multisamples)) +{ + QCPPaintBufferGlPbuffer::reallocateBuffer(); +} + +QCPPaintBufferGlPbuffer::~QCPPaintBufferGlPbuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlPbuffer::startPainting() +{ + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + QCPPainter *result = new QCPPainter(mGlPBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer isn't valid, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlPBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::clear(const QColor &color) +{ + if (mGlPBuffer->isValid()) + { + mGlPBuffer->makeCurrent(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlPBuffer->doneCurrent(); + } else + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer invalid or context not current"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::reallocateBuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; + + QGLFormat format; + format.setAlpha(true); + format.setSamples(mMultisamples); + mGlPBuffer = new QGLPixelBuffer(mSize, format); +} +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlFbo +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlFbo + \brief A paint buffer based on OpenGL frame buffers objects, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL frame buffer objects (fbo) and is used in Qt versions 5.0 and + higher. (See \ref QCPPaintBufferGlPbuffer used in older Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlFbo instance with the specified \a size and \a devicePixelRatio, + if applicable. + + All frame buffer objects shall share one OpenGL context and paint device, which need to be set up + externally and passed via \a glContext and \a glPaintDevice. The set-up is done in \ref + QCustomPlot::setupOpenGl and the context and paint device are managed by the parent QCustomPlot + instance. +*/ +QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlContext(glContext), + mGlPaintDevice(glPaintDevice), + mGlFrameBuffer(0) +{ + QCPPaintBufferGlFbo::reallocateBuffer(); +} + +QCPPaintBufferGlFbo::~QCPPaintBufferGlFbo() +{ + if (mGlFrameBuffer) + delete mGlFrameBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlFbo::startPainting() +{ + if (mGlPaintDevice.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return 0; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + if (QOpenGLContext::currentContext() != mGlContext.data()) + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + mGlFrameBuffer->bind(); + QCPPainter *result = new QCPPainter(mGlPaintDevice.data()); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::donePainting() +{ + if (mGlFrameBuffer && mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + else + qDebug() << Q_FUNC_INFO << "Either OpenGL frame buffer not valid or was not bound"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlFrameBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::clear(const QColor &color) +{ + if (mGlContext.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + + if (QOpenGLContext::currentContext() != mGlContext.data()) + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + mGlFrameBuffer->bind(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlFrameBuffer->release(); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::reallocateBuffer() +{ + // release and delete possibly existing framebuffer: + if (mGlFrameBuffer) + { + if (mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + delete mGlFrameBuffer; + mGlFrameBuffer = 0; + } + + if (mGlContext.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (mGlPaintDevice.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return; + } + + // create new fbo with appropriate size: + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + QOpenGLFramebufferObjectFormat frameBufferFormat; + frameBufferFormat.setSamples(mGlContext.data()->format().samples()); + frameBufferFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + mGlFrameBuffer = new QOpenGLFramebufferObject(mSize*mDevicePixelRatio, frameBufferFormat); + if (mGlPaintDevice.data()->size() != mSize*mDevicePixelRatio) + mGlPaintDevice.data()->setSize(mSize*mDevicePixelRatio); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mGlPaintDevice.data()->setDevicePixelRatio(mDevicePixelRatio); +#endif +} +#endif // QCP_OPENGL_FBO +/* end of 'src/paintbuffer.cpp' */ + + +/* including file 'src/layer.cpp', size 37064 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayer + \brief A layer that may contain objects, to control the rendering order + + The Layering system of QCustomPlot is the mechanism to control the rendering order of the + elements inside the plot. + + It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of + one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, + QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers + bottom to top and successively draws the layerables of the layers into the paint buffer(s). + + A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base + class from which almost all visible objects derive, like axes, grids, graphs, items, etc. + + \section qcplayer-defaultlayers Default layers + + Initially, QCustomPlot has six layers: "background", "grid", "main", "axes", "legend" and + "overlay" (in that order). On top is the "overlay" layer, which only contains the QCustomPlot's + selection rect (\ref QCustomPlot::selectionRect). The next two layers "axes" and "legend" contain + the default axes and legend, so they will be drawn above plottables. In the middle, there is the + "main" layer. It is initially empty and set as the current layer (see + QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. are created on this + layer by default. Then comes the "grid" layer which contains the QCPGrid instances (which belong + tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background shall be drawn behind + everything else, thus the default QCPAxisRect instance is placed on the "background" layer. Of + course, the layer affiliation of the individual objects can be changed as required (\ref + QCPLayerable::setLayer). + + \section qcplayer-ordering Controlling the rendering order via layers + + Controlling the ordering of layerables in the plot is easy: Create a new layer in the position + you want the layerable to be in, e.g. above "main", with \ref QCustomPlot::addLayer. Then set the + current layer with \ref QCustomPlot::setCurrentLayer to that new layer and finally create the + objects normally. They will be placed on the new layer automatically, due to the current layer + setting. Alternatively you could have also ignored the current layer setting and just moved the + objects with \ref QCPLayerable::setLayer to the desired layer after creating them. + + It is also possible to move whole layers. For example, If you want the grid to be shown in front + of all plottables/items on the "main" layer, just move it above "main" with + QCustomPlot::moveLayer. + + The rendering order within one layer is simply by order of creation or insertion. The item + created last (or added last to the layer), is drawn on top of all other objects on that layer. + + When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below + the deleted layer, see QCustomPlot::removeLayer. + + \section qcplayer-buffering Replotting only a specific layer + + If the layer mode (\ref setMode) is set to \ref lmBuffered, you can replot only this specific + layer by calling \ref replot. In certain situations this can provide better replot performance, + compared with a full replot of all layers. Upon creation of a new layer, the layer mode is + initialized to \ref lmLogical. The only layer that is set to \ref lmBuffered in a new \ref + QCustomPlot instance is the "overlay" layer, containing the selection rect. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPLayer::children() const + + Returns a list of all layerables on this layer. The order corresponds to the rendering order: + layerables with higher indices are drawn above layerables with lower indices. +*/ + +/*! \fn int QCPLayer::index() const + + Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be + accessed via \ref QCustomPlot::layer. + + Layers with higher indices will be drawn above layers with lower indices. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPLayer instance. + + Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. + + \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. + This check is only performed by \ref QCustomPlot::addLayer. +*/ +QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : + QObject(parentPlot), + mParentPlot(parentPlot), + mName(layerName), + mIndex(-1), // will be set to a proper value by the QCustomPlot layer creation function + mVisible(true), + mMode(lmLogical) +{ + // Note: no need to make sure layerName is unique, because layer + // management is done with QCustomPlot functions. +} + +QCPLayer::~QCPLayer() +{ + // If child layerables are still on this layer, detach them, so they don't try to reach back to this + // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted + // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to + // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) + + while (!mChildren.isEmpty()) + mChildren.last()->setLayer(0); // removes itself from mChildren via removeChild() + + if (mParentPlot->currentLayer() == this) + qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand."; +} + +/*! + Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this + layer will be invisible. + + This function doesn't change the visibility property of the layerables (\ref + QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the + visibility of the parent layer into account. +*/ +void QCPLayer::setVisible(bool visible) +{ + mVisible = visible; +} + +/*! + Sets the rendering mode of this layer. + + If \a mode is set to \ref lmBuffered for a layer, it will be given a dedicated paint buffer by + the parent QCustomPlot instance. This means it may be replotted individually by calling \ref + QCPLayer::replot, without needing to replot all other layers. + + Layers which are set to \ref lmLogical (the default) are used only to define the rendering order + and can't be replotted individually. + + Note that each layer which is set to \ref lmBuffered requires additional paint buffers for the + layers below, above and for the layer itself. This increases the memory consumption and + (slightly) decreases the repainting speed because multiple paint buffers need to be joined. So + you should carefully choose which layers benefit from having their own paint buffer. A typical + example would be a layer which contains certain layerables (e.g. items) that need to be changed + and thus replotted regularly, while all other layerables on other layers stay static. By default, + only the topmost layer called "overlay" is in mode \ref lmBuffered, and contains the selection + rect. + + \see replot +*/ +void QCPLayer::setMode(QCPLayer::LayerMode mode) +{ + if (mMode != mode) + { + mMode = mode; + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } +} + +/*! \internal + + Draws the contents of this layer with the provided \a painter. + + \see replot, drawToPaintBuffer +*/ +void QCPLayer::draw(QCPPainter *painter) +{ + foreach (QCPLayerable *child, mChildren) + { + if (child->realVisibility()) + { + painter->save(); + painter->setClipRect(child->clipRect().translated(0, -1)); + child->applyDefaultAntialiasingHint(painter); + child->draw(painter); + painter->restore(); + } + } +} + +/*! \internal + + Draws the contents of this layer into the paint buffer which is associated with this layer. The + association is established by the parent QCustomPlot, which manages all paint buffers (see \ref + QCustomPlot::setupPaintBuffers). + + \see draw +*/ +void QCPLayer::drawToPaintBuffer() +{ + if (!mPaintBuffer.isNull()) + { + if (QCPPainter *painter = mPaintBuffer.data()->startPainting()) + { + if (painter->isActive()) + draw(painter); + else + qDebug() << Q_FUNC_INFO << "paint buffer returned inactive painter"; + delete painter; + mPaintBuffer.data()->donePainting(); + } else + qDebug() << Q_FUNC_INFO << "paint buffer returned zero painter"; + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; +} + +/*! + If the layer mode (\ref setMode) is set to \ref lmBuffered, this method allows replotting only + the layerables on this specific layer, without the need to replot all other layers (as a call to + \ref QCustomPlot::replot would do). + + If the layer mode is \ref lmLogical however, this method simply calls \ref QCustomPlot::replot on + the parent QCustomPlot instance. + + QCustomPlot also makes sure to replot all layers instead of only this one, if the layer ordering + has changed since the last full replot and the other paint buffers were thus invalidated. + + \see draw +*/ +void QCPLayer::replot() +{ + if (mMode == lmBuffered && !mParentPlot->hasInvalidatedPaintBuffers()) + { + if (!mPaintBuffer.isNull()) + { + mPaintBuffer.data()->clear(Qt::transparent); + drawToPaintBuffer(); + mPaintBuffer.data()->setInvalidated(false); + mParentPlot->update(); + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; + } else if (mMode == lmLogical) + mParentPlot->replot(); +} + +/*! \internal + + Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will + be prepended to the list, i.e. be drawn beneath the other layerables already in the list. + + This function does not change the \a mLayer member of \a layerable to this layer. (Use + QCPLayerable::setLayer to change the layer of an object, not this function.) + + \see removeChild +*/ +void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) +{ + if (!mChildren.contains(layerable)) + { + if (prepend) + mChildren.prepend(layerable); + else + mChildren.append(layerable); + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); +} + +/*! \internal + + Removes the \a layerable from the list of this layer. + + This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer + to change the layer of an object, not this function.) + + \see addChild +*/ +void QCPLayer::removeChild(QCPLayerable *layerable) +{ + if (mChildren.removeOne(layerable)) + { + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayerable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayerable + \brief Base class for all drawable objects + + This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid + etc. + + Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking + the layers accordingly. + + For details about the layering mechanism, see the QCPLayer documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayerable *QCPLayerable::parentLayerable() const + + Returns the parent layerable of this layerable. The parent layerable is used to provide + visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables + only get drawn if their parent layerables are visible, too. + + Note that a parent layerable is not necessarily also the QObject parent for memory management. + Further, a layerable doesn't always have a parent layerable, so this function may return 0. + + A parent layerable is set implicitly when placed inside layout elements and doesn't need to be + set manually by the user. +*/ + +/* end documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 + \internal + + This function applies the default antialiasing setting to the specified \a painter, using the + function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when + \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing + setting may be specified individually, this function should set the antialiasing state of the + most prominent entity. In this case however, the \ref draw function usually calls the specialized + versions of this function before drawing each entity, effectively overriding the setting of the + default antialiasing hint. + + First example: QCPGraph has multiple entities that have an antialiasing setting: The graph + line, fills and scatters. Those can be configured via QCPGraph::setAntialiased, + QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only + the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's + antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and + QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw + calls the respective specialized applyAntialiasingHint function. + + Second example: QCPItemLine consists only of a line so there is only one antialiasing + setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by + all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the + respective layerable subclass.) Consequently it only has the normal + QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to + care about setting any antialiasing states, because the default antialiasing hint is already set + on the painter when the \ref draw function is called, and that's the state it wants to draw the + line with. +*/ + +/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 + \internal + + This function draws the layerable with the specified \a painter. It is only called by + QCustomPlot, if the layerable is visible (\ref setVisible). + + Before this function is called, the painter's antialiasing state is set via \ref + applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was + set to \ref clipRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); + + This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to + a different layer. + + \see setLayer +*/ + +/* end documentation of signals */ + +/*! + Creates a new QCPLayerable instance. + + Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the + derived classes. + + If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a + targetLayer is an empty string, it places itself on the current layer of the plot (see \ref + QCustomPlot::setCurrentLayer). + + It is possible to provide 0 as \a plot. In that case, you should assign a parent plot at a later + time with \ref initializeParentPlot. + + The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable + parents are mainly used to control visibility in a hierarchy of layerables. This means a + layerable is only drawn, if all its ancestor layerables are also visible. Note that \a + parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a + plot does. It is not uncommon to set the QObject-parent to something else in the constructors of + QCPLayerable subclasses, to guarantee a working destruction hierarchy. +*/ +QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) : + QObject(plot), + mVisible(true), + mParentPlot(plot), + mParentLayerable(parentLayerable), + mLayer(0), + mAntialiased(true) +{ + if (mParentPlot) + { + if (targetLayer.isEmpty()) + setLayer(mParentPlot->currentLayer()); + else if (!setLayer(targetLayer)) + qDebug() << Q_FUNC_INFO << "setting QCPlayerable initial layer to" << targetLayer << "failed."; + } +} + +QCPLayerable::~QCPLayerable() +{ + if (mLayer) + { + mLayer->removeChild(this); + mLayer = 0; + } +} + +/*! + Sets the visibility of this layerable object. If an object is not visible, it will not be drawn + on the QCustomPlot surface, and user interaction with it (e.g. click and selection) is not + possible. +*/ +void QCPLayerable::setVisible(bool on) +{ + mVisible = on; +} + +/*! + Sets the \a layer of this layerable object. The object will be placed on top of the other objects + already on \a layer. + + If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or + interact/receive events). + + Returns true if the layer of this layerable was successfully changed to \a layer. +*/ +bool QCPLayerable::setLayer(QCPLayer *layer) +{ + return moveToLayer(layer, false); +} + +/*! \overload + Sets the layer of this layerable object by name + + Returns true on success, i.e. if \a layerName is a valid layer name. +*/ +bool QCPLayerable::setLayer(const QString &layerName) +{ + if (!mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (QCPLayer *layer = mParentPlot->layer(layerName)) + { + return setLayer(layer); + } else + { + qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; + return false; + } +} + +/*! + Sets whether this object will be drawn antialiased or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPLayerable::setAntialiased(bool enabled) +{ + mAntialiased = enabled; +} + +/*! + Returns whether this layerable is visible, taking the visibility of the layerable parent and the + visibility of this layerable's layer into account. This is the method that is consulted to decide + whether a layerable shall be drawn or not. + + If this layerable has a direct layerable parent (usually set via hierarchies implemented in + subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this + layerable has its visibility set to true and the parent layerable's \ref realVisibility returns + true. +*/ +bool QCPLayerable::realVisibility() const +{ + return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility()); +} + +/*! + This function is used to decide whether a click hits a layerable object or not. + + \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the + shortest pixel distance of this point to the object. If the object is either invisible or the + distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the + object is not selectable, -1.0 is returned, too. + + If the object is represented not by single lines but by an area like a \ref QCPItemText or the + bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In + these cases this function thus returns a constant value greater zero but still below the parent + plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). + + Providing a constant value for area objects allows selecting line objects even when they are + obscured by such area objects, by clicking close to the lines (i.e. closer than + 0.99*selectionTolerance). + + The actual setting of the selection state is not done by this function. This is handled by the + parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified + via the \ref selectEvent/\ref deselectEvent methods. + + \a details is an optional output parameter. Every layerable subclass may place any information + in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot + decides on the basis of this selectTest call, that the object was successfully selected. The + subsequent call to \ref selectEvent will carry the \a details. This is useful for multi-part + objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked + is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be + placed in \a details. So in the subsequent \ref selectEvent, the decision which part was + selected doesn't have to be done a second time for a single selection operation. + + You may pass 0 as \a details to indicate that you are not interested in those selection details. + + \see selectEvent, deselectEvent, mousePressEvent, wheelEvent, QCustomPlot::setInteractions +*/ +double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(pos) + Q_UNUSED(onlySelectable) + Q_UNUSED(details) + return -1.0; +} + +/*! \internal + + Sets the parent plot of this layerable. Use this function once to set the parent plot if you have + passed 0 in the constructor. It can not be used to move a layerable from one QCustomPlot to + another one. + + Note that, unlike when passing a non-null parent plot in the constructor, this function does not + make \a parentPlot the QObject-parent of this layerable. If you want this, call + QObject::setParent(\a parentPlot) in addition to this function. + + Further, you will probably want to set a layer (\ref setLayer) after calling this function, to + make the layerable appear on the QCustomPlot. + + The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized + so they can react accordingly (e.g. also initialize the parent plot of child layerables, like + QCPLayout does). +*/ +void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) +{ + if (mParentPlot) + { + qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; + return; + } + + if (!parentPlot) + qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; + + mParentPlot = parentPlot; + parentPlotInitialized(mParentPlot); +} + +/*! \internal + + Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not + become the QObject-parent (for memory management) of this layerable. + + The parent layerable has influence on the return value of the \ref realVisibility method. Only + layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be + drawn. + + \see realVisibility +*/ +void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) +{ + mParentLayerable = parentLayerable; +} + +/*! \internal + + Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to + the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is + false, the object will be appended. + + Returns true on success, i.e. if \a layer is a valid layer. +*/ +bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) +{ + if (layer && !mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (layer && layer->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; + return false; + } + + QCPLayer *oldLayer = mLayer; + if (mLayer) + mLayer->removeChild(this); + mLayer = layer; + if (mLayer) + mLayer->addChild(this, prepend); + if (mLayer != oldLayer) + emit layerChanged(mLayer); + return true; +} + +/*! \internal + + Sets the QCPainter::setAntialiasing state on the provided \a painter, depending on the \a + localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is + controlled via \a overrideElement. +*/ +void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const +{ + if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(false); + else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(true); + else + painter->setAntialiasing(localAntialiased); +} + +/*! \internal + + This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting + of a parent plot. This is the case when 0 was passed as parent plot in the constructor, and the + parent plot is set at a later time. + + For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any + QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level + element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To + propagate the parent plot to all the children of the hierarchy, the top level element then uses + this function to pass the parent plot on to its child elements. + + The default implementation does nothing. + + \see initializeParentPlot +*/ +void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) +{ + Q_UNUSED(parentPlot) +} + +/*! \internal + + Returns the selection category this layerable shall belong to. The selection category is used in + conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and + which aren't. + + Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref + QCP::iSelectOther. This is what the default implementation returns. + + \see QCustomPlot::setInteractions +*/ +QCP::Interaction QCPLayerable::selectionCategory() const +{ + return QCP::iSelectOther; +} + +/*! \internal + + Returns the clipping rectangle of this layerable object. By default, this is the viewport of the + parent QCustomPlot. Specific subclasses may reimplement this function to provide different + clipping rects. + + The returned clipping rect is set on the painter before the draw function of the respective + object is called. +*/ +QRect QCPLayerable::clipRect() const +{ + if (mParentPlot) + return mParentPlot->viewport(); + else + return QRect(); +} + +/*! \internal + + This event is called when the layerable shall be selected, as a consequence of a click by the + user. Subclasses should react to it by setting their selection state appropriately. The default + implementation does nothing. + + \a event is the mouse event that caused the selection. \a additive indicates, whether the user + was holding the multi-select-modifier while performing the selection (see \ref + QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled + (i.e. become selected when unselected and unselected when selected). + + Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. + returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). + The \a details data you output from \ref selectTest is fed back via \a details here. You may + use it to transport any kind of information from the selectTest to the possibly subsequent + selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable + that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need + to do the calculation again to find out which part was actually clicked. + + \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must + set the value either to true or false, depending on whether the selection state of this layerable + was actually changed. For layerables that only are selectable as a whole and not in parts, this + is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the + selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the + layerable was previously unselected and now is switched to the selected state. + + \see selectTest, deselectEvent +*/ +void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(additive) + Q_UNUSED(details) + Q_UNUSED(selectionStateChanged) +} + +/*! \internal + + This event is called when the layerable shall be deselected, either as consequence of a user + interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by + unsetting their selection appropriately. + + just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must + return true or false when the selection state of this layerable has changed or not changed, + respectively. + + \see selectTest, selectEvent +*/ +void QCPLayerable::deselectEvent(bool *selectionStateChanged) +{ + Q_UNUSED(selectionStateChanged) +} + +/*! + This event gets called when the user presses a mouse button while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + QCustomPlot uses an event propagation system that works the same as Qt's system. If your + layerable doesn't reimplement the \ref mousePressEvent or explicitly calls \c event->ignore() in + its reimplementation, the event will be propagated to the next layerable in the stacking order. + + Once a layerable has accepted the \ref mousePressEvent, it is considered the mouse grabber and + will receive all following calls to \ref mouseMoveEvent or \ref mouseReleaseEvent for this mouse + interaction (a "mouse interaction" in this context ends with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user moves the mouse while holding a mouse button, after this + layerable has become the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occured, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user releases the mouse button, after this layerable has become + the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occured, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user presses the mouse button a second time in a double-click, + while the cursor is over the layerable. Whether a cursor is over the layerable is decided by a + preceding call to \ref selectTest. + + The \ref mouseDoubleClickEvent is called instead of the second \ref mousePressEvent. So in the + case of a double-click, the event succession is + pressEvent – releaseEvent – doubleClickEvent – releaseEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + Similarly to \ref mousePressEvent, once a layerable has accepted the \ref mouseDoubleClickEvent, + it is considered the mouse grabber and will receive all following calls to \ref mouseMoveEvent + and \ref mouseReleaseEvent for this mouse interaction (a "mouse interaction" in this context ends + with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, wheelEvent +*/ +void QCPLayerable::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user turns the mouse scroll wheel while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). + + The \c event->delta() indicates how far the mouse wheel was turned, which is usually +/- 120 for + single rotation steps. However, if the mouse wheel is turned rapidly, multiple steps may + accumulate to one event, making \c event->delta() larger. On the other hand, if the wheel has + very smooth steps or none at all, the delta may be smaller. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent +*/ +void QCPLayerable::wheelEvent(QWheelEvent *event) +{ + event->ignore(); +} +/* end of 'src/layer.cpp' */ + + +/* including file 'src/axis/range.cpp', size 12221 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPRange +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPRange + \brief Represents the range an axis is encompassing. + + contains a \a lower and \a upper double value and provides convenience input, output and + modification functions. + + \see QCPAxis::setRange +*/ + +/* start of documentation of inline functions */ + +/*! \fn double QCPRange::size() const + + Returns the size of the range, i.e. \a upper-\a lower +*/ + +/*! \fn double QCPRange::center() const + + Returns the center of the range, i.e. (\a upper+\a lower)*0.5 +*/ + +/*! \fn void QCPRange::normalize() + + Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values are + swapped. +*/ + +/*! \fn bool QCPRange::contains(double value) const + + Returns true when \a value lies within or exactly on the borders of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator+=(const double& value) + + Adds \a value to both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator-=(const double& value) + + Subtracts \a value from both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator*=(const double& value) + + Multiplies both boundaries of the range by \a value. +*/ + +/*! \fn QCPRange &QCPRange::operator/=(const double& value) + + Divides both boundaries of the range by \a value. +*/ + +/* end of documentation of inline functions */ + +/*! + Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller + intervals would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a minimum magnitude of roughly 1e-308. + + \warning Do not use this constant to indicate "arbitrarily small" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining underflowing ranges. + + \see validRange, maxRange +*/ +const double QCPRange::minRange = 1e-280; +//const double QCPRange::minRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(1970, 0, 0)); + +/*! + Maximum values (negative and positive) the range will accept in range-changing functions. + Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a maximum magnitude of roughly 1e308. + + \warning Do not use this constant to indicate "arbitrarily large" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining overflowing ranges. + + \see validRange, minRange +*/ +const double QCPRange::maxRange = 1e250; +//const double QCPRange::maxRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 12, 31)); + +/*! + Constructs a range with \a lower and \a upper set to zero. +*/ +QCPRange::QCPRange() : + lower(0), + upper(0) +{ +} + +/*! \overload + + Constructs a range with the specified \a lower and \a upper values. + + The resulting range will be normalized (see \ref normalize), so if \a lower is not numerically + smaller than \a upper, they will be swapped. +*/ +QCPRange::QCPRange(double lower, double upper) : + lower(lower), + upper(upper) +{ + normalize(); +} + +/*! \overload + + Expands this range such that \a otherRange is contained in the new range. It is assumed that both + this range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, it will be replaced by the respective bound + of \a otherRange. + + If \a otherRange is already inside the current range, this function does nothing. + + \see expanded +*/ +void QCPRange::expand(const QCPRange &otherRange) +{ + if (lower > otherRange.lower || qIsNaN(lower)) + lower = otherRange.lower; + if (upper < otherRange.upper || qIsNaN(upper)) + upper = otherRange.upper; +} + +/*! \overload + + Expands this range such that \a includeCoord is contained in the new range. It is assumed that + this range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the respective bound will be set to \a + includeCoord. + + If \a includeCoord is already inside the current range, this function does nothing. + + \see expand +*/ +void QCPRange::expand(double includeCoord) +{ + if (lower > includeCoord || qIsNaN(lower)) + lower = includeCoord; + if (upper < includeCoord || qIsNaN(upper)) + upper = includeCoord; +} + + +/*! \overload + + Returns an expanded range that contains this and \a otherRange. It is assumed that both this + range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be taken from + \a otherRange. + + \see expand +*/ +QCPRange QCPRange::expanded(const QCPRange &otherRange) const +{ + QCPRange result = *this; + result.expand(otherRange); + return result; +} + +/*! \overload + + Returns an expanded range that includes the specified \a includeCoord. It is assumed that this + range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be set to \a + includeCoord. + + \see expand +*/ +QCPRange QCPRange::expanded(double includeCoord) const +{ + QCPRange result = *this; + result.expand(includeCoord); + return result; +} + +/*! + Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a + upperBound. If possible, the size of the current range is preserved in the process. + + If the range shall only be bounded at the lower side, you can set \a upperBound to \ref + QCPRange::maxRange. If it shall only be bounded at the upper side, set \a lowerBound to -\ref + QCPRange::maxRange. +*/ +QCPRange QCPRange::bounded(double lowerBound, double upperBound) const +{ + if (lowerBound > upperBound) + qSwap(lowerBound, upperBound); + + QCPRange result(lower, upper); + if (result.lower < lowerBound) + { + result.lower = lowerBound; + result.upper = lowerBound + size(); + if (result.upper > upperBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.upper = upperBound; + } else if (result.upper > upperBound) + { + result.upper = upperBound; + result.lower = upperBound - size(); + if (result.lower < lowerBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.lower = lowerBound; + } + + return result; +} + +/*! + Returns a sanitized version of the range. Sanitized means for logarithmic scales, that + the range won't span the positive and negative sign domain, i.e. contain zero. Further + \a lower will always be numerically smaller (or equal) to \a upper. + + If the original range does span positive and negative sign domains or contains zero, + the returned range will try to approximate the original range as good as possible. + If the positive interval of the original range is wider than the negative interval, the + returned range will only contain the positive interval, with lower bound set to \a rangeFac or + \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval + is wider than the positive interval, this time by changing the \a upper bound. +*/ +QCPRange QCPRange::sanitizedForLogScale() const +{ + double rangeFac = 1e-3; + QCPRange sanitizedRange(lower, upper); + sanitizedRange.normalize(); + // can't have range spanning negative and positive values in log plot, so change range to fix it + //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) + if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) + { + // case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) + else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) + { + // case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) + { + // find out whether negative or positive interval is wider to decide which sign domain will be chosen + if (-sanitizedRange.lower > sanitizedRange.upper) + { + // negative is wider, do same as in case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else + { + // positive is wider, do same as in case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } + } + // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper -maxRange && + upper < maxRange && + qAbs(lower-upper) >= 1 && + qAbs(lower-upper) < 2 * maxRange); + +// return (lower > -maxRange && +// upper < maxRange && +// qAbs(lower-upper) > minRange && +// qAbs(lower-upper) < maxRange && +// !(lower > 0 && qIsInf(upper/lower)) && +// !(upper < 0 && qIsInf(lower/upper))); +} + +/*! + \overload + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(const QCPRange &range) +{ + return validRange(range.lower, range.upper); +// return (range.lower > -maxRange && +// range.upper < maxRange && +// qAbs(range.lower-range.upper) > minRange && +// qAbs(range.lower-range.upper) < maxRange && +// !(range.lower > 0 && qIsInf(range.upper/range.lower)) && +// !(range.upper < 0 && qIsInf(range.lower/range.upper))); +} +/* end of 'src/axis/range.cpp' */ + + +/* including file 'src/selection.cpp', size 21906 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataRange +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataRange + \brief Describes a data range given by begin and end index + + QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index + of a contiguous set of data points. The end index points to the data point above the last data point that's part of + the data range, similarly to the nomenclature used in standard iterators. + + Data Ranges are not bound to a certain plottable, thus they can be freely exchanged, created and + modified. If a non-contiguous data set shall be described, the class \ref QCPDataSelection is + used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref + QCPDataSelection is thus used. + + Both \ref QCPDataRange and \ref QCPDataSelection offer convenience methods to work with them, + e.g. \ref bounded, \ref expanded, \ref intersects, \ref intersection, \ref adjusted, \ref + contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be + used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding + \ref QCPDataSelection. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and + QCPDataRange. + + \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval + in floating point plot coordinates, e.g. the current axis range. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataRange::size() const + + Returns the number of data points described by this data range. This is equal to the end index + minus the begin index. + + \see length +*/ + +/*! \fn int QCPDataRange::length() const + + Returns the number of data points described by this data range. Equivalent to \ref size. +*/ + +/*! \fn void QCPDataRange::setBegin(int begin) + + Sets the begin of this data range. The \a begin index points to the first data point that is part + of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setEnd +*/ + +/*! \fn void QCPDataRange::setEnd(int end) + + Sets the end of this data range. The \a end index points to the data point just above the last + data point that is part of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setBegin +*/ + +/*! \fn bool QCPDataRange::isValid() const + + Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and + an end index greater or equal to the begin index. + + \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods + (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's + methods. The invalid range is not inherently prevented in QCPDataRange, to allow temporary + invalid begin/end values while manipulating the range. An invalid range is not necessarily empty + (\ref isEmpty), since its \ref length can be negative and thus non-zero. +*/ + +/*! \fn bool QCPDataRange::isEmpty() const + + Returns whether this range is empty, i.e. whether its begin index equals its end index. + + \see size, length +*/ + +/*! \fn QCPDataRange QCPDataRange::adjusted(int changeBegin, int changeEnd) const + + Returns a data range where \a changeBegin and \a changeEnd were added to the begin and end + indices, respectively. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataRange, with begin and end set to 0. +*/ +QCPDataRange::QCPDataRange() : + mBegin(0), + mEnd(0) +{ +} + +/*! + Creates a QCPDataRange, initialized with the specified \a begin and \a end. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). +*/ +QCPDataRange::QCPDataRange(int begin, int end) : + mBegin(begin), + mEnd(end) +{ +} + +/*! + Returns a data range that matches this data range, except that parts exceeding \a other are + excluded. + + This method is very similar to \ref intersection, with one distinction: If this range and the \a + other range share no intersection, the returned data range will be empty with begin and end set + to the respective boundary side of \a other, at which this range is residing. (\ref intersection + would just return a range with begin and end set to 0.) +*/ +QCPDataRange QCPDataRange::bounded(const QCPDataRange &other) const +{ + QCPDataRange result(intersection(other)); + if (result.isEmpty()) // no intersection, preserve respective bounding side of otherRange as both begin and end of return value + { + if (mEnd <= other.mBegin) + result = QCPDataRange(other.mBegin, other.mBegin); + else + result = QCPDataRange(other.mEnd, other.mEnd); + } + return result; +} + +/*! + Returns a data range that contains both this data range as well as \a other. +*/ +QCPDataRange QCPDataRange::expanded(const QCPDataRange &other) const +{ + return QCPDataRange(qMin(mBegin, other.mBegin), qMax(mEnd, other.mEnd)); +} + +/*! + Returns the data range which is contained in both this data range and \a other. + + This method is very similar to \ref bounded, with one distinction: If this range and the \a other + range share no intersection, the returned data range will be empty with begin and end set to 0. + (\ref bounded would return a range with begin and end set to one of the boundaries of \a other, + depending on which side this range is on.) + + \see QCPDataSelection::intersection +*/ +QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const +{ + QCPDataRange result(qMax(mBegin, other.mBegin), qMin(mEnd, other.mEnd)); + if (result.isValid()) + return result; + else + return QCPDataRange(); +} + +/*! + Returns whether this data range and \a other share common data points. + + \see intersection, contains +*/ +bool QCPDataRange::intersects(const QCPDataRange &other) const +{ + return !( (mBegin > other.mBegin && mBegin >= other.mEnd) || + (mEnd <= other.mBegin && mEnd < other.mEnd) ); +} + +/*! + Returns whether all data points described by this data range are also in \a other. + + \see intersects +*/ +bool QCPDataRange::contains(const QCPDataRange &other) const +{ + return mBegin <= other.mBegin && mEnd >= other.mEnd; +} + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataSelection +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataSelection + \brief Describes a data set by holding multiple QCPDataRange instances + + QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly + disjoint) set of data selection. + + The data selection can be modified with addition and subtraction operators which take + QCPDataSelection and QCPDataRange instances, as well as methods such as \ref addDataRange and + \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc. + + The method \ref simplify is used to join directly adjacent or even overlapping QCPDataRange + instances. QCPDataSelection automatically simplifies when using the addition/subtraction + operators. The only case when \ref simplify is left to the user, is when calling \ref + addDataRange, with the parameter \a simplify explicitly set to false. This is useful if many data + ranges will be added to the selection successively and the overhead for simplifying after each + iteration shall be avoided. In this case, you should make sure to call \ref simplify after + completing the operation. + + Use \ref enforceType to bring the data selection into a state complying with the constraints for + selections defined in \ref QCP::SelectionType. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on QCPDataSelection and + QCPDataRange. + + \section qcpdataselection-iterating Iterating over a data selection + + As an example, the following code snippet calculates the average value of a graph's data + \ref QCPAbstractPlottable::selection "selection": + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpdataselection-iterating-1 + +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataSelection::dataRangeCount() const + + Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref + dataRange via their index. + + \see dataRange, dataPointCount +*/ + +/*! \fn QList QCPDataSelection::dataRanges() const + + Returns all data ranges that make up the data selection. If the data selection is simplified (the + usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point + index. + + \see dataRange +*/ + +/*! \fn bool QCPDataSelection::isEmpty() const + + Returns true if there are no data ranges, and thus no data points, in this QCPDataSelection + instance. + + \see dataRangeCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataSelection. +*/ +QCPDataSelection::QCPDataSelection() +{ +} + +/*! + Creates a QCPDataSelection containing the provided \a range. +*/ +QCPDataSelection::QCPDataSelection(const QCPDataRange &range) +{ + mDataRanges.append(range); +} + +/*! + Returns true if this selection is identical (contains the same data ranges with the same begin + and end indices) to \a other. + + Note that both data selections must be in simplified state (the usual state of the selection, see + \ref simplify) for this operator to return correct results. +*/ +bool QCPDataSelection::operator==(const QCPDataSelection &other) const +{ + if (mDataRanges.size() != other.mDataRanges.size()) + return false; + for (int i=0; i= other.end()) + break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this + + if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored + { + if (thisBegin >= other.begin()) // range leading segment is encompassed + { + if (thisEnd <= other.end()) // range fully encompassed, remove completely + { + mDataRanges.removeAt(i); + continue; + } else // only leading segment is encompassed, trim accordingly + mDataRanges[i].setBegin(other.end()); + } else // leading segment is not encompassed + { + if (thisEnd <= other.end()) // only trailing segment is encompassed, trim accordingly + { + mDataRanges[i].setEnd(other.begin()); + } else // other lies inside this range, so split range + { + mDataRanges[i].setEnd(other.begin()); + mDataRanges.insert(i+1, QCPDataRange(other.end(), thisEnd)); + break; // since data ranges are sorted (and don't overlap) after simplify() call, we're done here + } + } + } + ++i; + } + + return *this; +} + +/*! + Returns the total number of data points contained in all data ranges that make up this data + selection. +*/ +int QCPDataSelection::dataPointCount() const +{ + int result = 0; + for (int i=0; i= 0 && index < mDataRanges.size()) + { + return mDataRanges.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of range:" << index; + return QCPDataRange(); + } +} + +/*! + Returns a \ref QCPDataRange which spans the entire data selection, including possible + intermediate segments which are not part of the original data selection. +*/ +QCPDataRange QCPDataSelection::span() const +{ + if (isEmpty()) + return QCPDataRange(); + else + return QCPDataRange(mDataRanges.first().begin(), mDataRanges.last().end()); +} + +/*! + Adds the given \a dataRange to this data selection. This is equivalent to the += operator but + allows disabling immediate simplification by setting \a simplify to false. This can improve + performance if adding a very large amount of data ranges successively. In this case, make sure to + call \ref simplify manually, after the operation. +*/ +void QCPDataSelection::addDataRange(const QCPDataRange &dataRange, bool simplify) +{ + mDataRanges.append(dataRange); + if (simplify) + this->simplify(); +} + +/*! + Removes all data ranges. The data selection then contains no data points. + + \ref isEmpty +*/ +void QCPDataSelection::clear() +{ + mDataRanges.clear(); +} + +/*! + Sorts all data ranges by range begin index in ascending order, and then joins directly adjacent + or overlapping ranges. This can reduce the number of individual data ranges in the selection, and + prevents possible double-counting when iterating over the data points held by the data ranges. + + This method is automatically called when using the addition/subtraction operators. The only case + when \ref simplify is left to the user, is when calling \ref addDataRange, with the parameter \a + simplify explicitly set to false. +*/ +void QCPDataSelection::simplify() +{ + // remove any empty ranges: + for (int i=mDataRanges.size()-1; i>=0; --i) + { + if (mDataRanges.at(i).isEmpty()) + mDataRanges.removeAt(i); + } + if (mDataRanges.isEmpty()) + return; + + // sort ranges by starting value, ascending: + std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin); + + // join overlapping/contiguous ranges: + int i = 1; + while (i < mDataRanges.size()) + { + if (mDataRanges.at(i-1).end() >= mDataRanges.at(i).begin()) // range i overlaps/joins with i-1, so expand range i-1 appropriately and remove range i from list + { + mDataRanges[i-1].setEnd(qMax(mDataRanges.at(i-1).end(), mDataRanges.at(i).end())); + mDataRanges.removeAt(i); + } else + ++i; + } +} + +/*! + Makes sure this data selection conforms to the specified \a type selection type. Before the type + is enforced, \ref simplify is called. + + Depending on \a type, enforcing means adding new data points that were previously not part of the + selection, or removing data points from the selection. If the current selection already conforms + to \a type, the data selection is not changed. + + \see QCP::SelectionType +*/ +void QCPDataSelection::enforceType(QCP::SelectionType type) +{ + simplify(); + switch (type) + { + case QCP::stNone: + { + mDataRanges.clear(); + break; + } + case QCP::stWhole: + { + // whole selection isn't defined by data range, so don't change anything (is handled in plottable methods) + break; + } + case QCP::stSingleData: + { + // reduce all data ranges to the single first data point: + if (!mDataRanges.isEmpty()) + { + if (mDataRanges.size() > 1) + mDataRanges = QList() << mDataRanges.first(); + if (mDataRanges.first().length() > 1) + mDataRanges.first().setEnd(mDataRanges.first().begin()+1); + } + break; + } + case QCP::stDataRange: + { + mDataRanges = QList() << span(); + break; + } + case QCP::stMultipleDataRanges: + { + // this is the selection type that allows all concievable combinations of ranges, so do nothing + break; + } + } +} + +/*! + Returns true if the data selection \a other is contained entirely in this data selection, i.e. + all data point indices that are in \a other are also in this data selection. + + \see QCPDataRange::contains +*/ +bool QCPDataSelection::contains(const QCPDataSelection &other) const +{ + if (other.isEmpty()) return false; + + int otherIndex = 0; + int thisIndex = 0; + while (thisIndex < mDataRanges.size() && otherIndex < other.mDataRanges.size()) + { + if (mDataRanges.at(thisIndex).contains(other.mDataRanges.at(otherIndex))) + ++otherIndex; + else + ++thisIndex; + } + return thisIndex < mDataRanges.size(); // if thisIndex ran all the way to the end to find a containing range for the current otherIndex, other is not contained in this +} + +/*! + Returns a data selection containing the points which are both in this data selection and in the + data range \a other. + + A common use case is to limit an unknown data selection to the valid range of a data container, + using \ref QCPDataContainer::dataRange as \a other. One can then safely iterate over the returned + data selection without exceeding the data container's bounds. +*/ +QCPDataSelection QCPDataSelection::intersection(const QCPDataRange &other) const +{ + QCPDataSelection result; + for (int i=0; iorientation() == Qt::Horizontal) + return QCPRange(axis->pixelToCoord(mRect.left()), axis->pixelToCoord(mRect.left()+mRect.width())); + else + return QCPRange(axis->pixelToCoord(mRect.top()+mRect.height()), axis->pixelToCoord(mRect.top())); + } else + { + qDebug() << Q_FUNC_INFO << "called with axis zero"; + return QCPRange(); + } +} + +/*! + Sets the pen that will be used to draw the selection rect outline. + + \see setBrush +*/ +void QCPSelectionRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used to fill the selection rect. By default the selection rect is not + filled, i.e. \a brush is Qt::NoBrush. + + \see setPen +*/ +void QCPSelectionRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + If there is currently a selection interaction going on (\ref isActive), the interaction is + canceled. The selection rect will emit the \ref canceled signal. +*/ +void QCPSelectionRect::cancel() +{ + if (mActive) + { + mActive = false; + emit canceled(mRect, 0); + } +} + +/*! \internal + + This method is called by QCustomPlot to indicate that a selection rect interaction was initiated. + The default implementation sets the selection rect to active, initializes the selection rect + geometry and emits the \ref started signal. +*/ +void QCPSelectionRect::startSelection(QMouseEvent *event) +{ + mActive = true; + mRect = QRect(event->pos(), event->pos()); + emit started(event); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs + to update its geometry. The default implementation updates the rect and emits the \ref changed + signal. +*/ +void QCPSelectionRect::moveSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + emit changed(mRect, event); + layer()->replot(); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has + finished by the user releasing the mouse button. The default implementation deactivates the + selection rect and emits the \ref accepted signal. +*/ +void QCPSelectionRect::endSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + mActive = false; + emit accepted(mRect, event); +} + +/*! \internal + + This method is called by QCustomPlot when a key has been pressed by the user while the selection + rect interaction is active. The default implementation allows to \ref cancel the interaction by + hitting the escape key. +*/ +void QCPSelectionRect::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape && mActive) + { + mActive = false; + emit canceled(mRect, event); + } +} + +/* inherits documentation from base class */ +void QCPSelectionRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/*! \internal + + If the selection rect is active (\ref isActive), draws the selection rect defined by \a mRect. + + \seebaseclassmethod +*/ +void QCPSelectionRect::draw(QCPPainter *painter) +{ + if (mActive) + { + painter->setPen(mPen); + painter->setBrush(mBrush); + painter->drawRect(mRect); + } +} +/* end of 'src/selectionrect.cpp' */ + + +/* including file 'src/layout.cpp', size 79064 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPMarginGroup +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPMarginGroup + \brief A margin group allows synchronization of margin sides if working with multiple layout elements. + + QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that + they will all have the same size, based on the largest required margin in the group. + + \n + \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" + \n + + In certain situations it is desirable that margins at specific sides are synchronized across + layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will + provide a cleaner look to the user if the left and right margins of the two axis rects are of the + same size. The left axis of the top axis rect will then be at the same horizontal position as the + left axis of the lower axis rect, making them appear aligned. The same applies for the right + axes. This is what QCPMarginGroup makes possible. + + To add/remove a specific side of a layout element to/from a margin group, use the \ref + QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call + \ref clear, or just delete the margin group. + + \section QCPMarginGroup-example Example + + First create a margin group: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 + Then set this group on the layout element sides: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-2 + Here, we've used the first two axis rects of the plot and synchronized their left margins with + each other and their right margins with each other. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const + + Returns a list of all layout elements that have their margin \a side associated with this margin + group. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPMarginGroup instance in \a parentPlot. +*/ +QCPMarginGroup::QCPMarginGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot) +{ + mChildren.insert(QCP::msLeft, QList()); + mChildren.insert(QCP::msRight, QList()); + mChildren.insert(QCP::msTop, QList()); + mChildren.insert(QCP::msBottom, QList()); +} + +QCPMarginGroup::~QCPMarginGroup() +{ + clear(); +} + +/*! + Returns whether this margin group is empty. If this function returns true, no layout elements use + this margin group to synchronize margin sides. +*/ +bool QCPMarginGroup::isEmpty() const +{ + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + if (!it.value().isEmpty()) + return false; + } + return true; +} + +/*! + Clears this margin group. The synchronization of the margin sides that use this margin group is + lifted and they will use their individual margin sizes again. +*/ +void QCPMarginGroup::clear() +{ + // make all children remove themselves from this margin group: + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + const QList elements = it.value(); + for (int i=elements.size()-1; i>=0; --i) + elements.at(i)->setMarginGroup(it.key(), 0); // removes itself from mChildren via removeChild + } +} + +/*! \internal + + Returns the synchronized common margin for \a side. This is the margin value that will be used by + the layout element on the respective side, if it is part of this margin group. + + The common margin is calculated by requesting the automatic margin (\ref + QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin + group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into + account, too.) +*/ +int QCPMarginGroup::commonMargin(QCP::MarginSide side) const +{ + // query all automatic margins of the layout elements in this margin group side and find maximum: + int result = 0; + const QList elements = mChildren.value(side); + for (int i=0; iautoMargins().testFlag(side)) + continue; + int m = qMax(elements.at(i)->calculateAutoMargin(side), QCP::getMarginValue(elements.at(i)->minimumMargins(), side)); + if (m > result) + result = m; + } + return result; +} + +/*! \internal + + Adds \a element to the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].contains(element)) + mChildren[side].append(element); + else + qDebug() << Q_FUNC_INFO << "element is already child of this margin group side" << reinterpret_cast(element); +} + +/*! \internal + + Removes \a element from the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].removeOne(element)) + qDebug() << Q_FUNC_INFO << "element is not child of this margin group side" << reinterpret_cast(element); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutElement + \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". + + This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. + + A Layout element is a rectangular object which can be placed in layouts. It has an outer rect + (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference + between outer and inner rect is called its margin. The margin can either be set to automatic or + manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be + set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, + the layout element subclass will control the value itself (via \ref calculateAutoMargin). + + Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level + layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref + QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. + + Thus in QCustomPlot one can divide layout elements into two categories: The ones that are + invisible by themselves, because they don't draw anything. Their only purpose is to manage the + position and size of other layout elements. This category of layout elements usually use + QCPLayout as base class. Then there is the category of layout elements which actually draw + something. For example, QCPAxisRect, QCPLegend and QCPTextElement are of this category. This does + not necessarily mean that the latter category can't have child layout elements. QCPLegend for + instance, actually derives from QCPLayoutGrid and the individual legend items are child layout + elements in the grid layout. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayout *QCPLayoutElement::layout() const + + Returns the parent layout of this layout element. +*/ + +/*! \fn QRect QCPLayoutElement::rect() const + + Returns the inner rect of this layout element. The inner rect is the outer rect (\ref outerRect, \ref + setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). + + In some cases, the area between outer and inner rect is left blank. In other cases the margin + area is used to display peripheral graphics while the main content is in the inner rect. This is + where automatic margin calculation becomes interesting because it allows the layout element to + adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect + draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if + \ref setAutoMargins is enabled) according to the space required by the labels of the axes. + + \see outerRect +*/ + +/*! \fn QRect QCPLayoutElement::outerRect() const + + Returns the outer rect of this layout element. The outer rect is the inner rect expanded by the + margins (\ref setMargins, \ref setAutoMargins). The outer rect is used (and set via \ref + setOuterRect) by the parent \ref QCPLayout to control the size of this layout element. + + \see rect +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutElement and sets default values. +*/ +QCPLayoutElement::QCPLayoutElement(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout) + mParentLayout(0), + mMinimumSize(), + mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), + mSizeConstraintRect(scrInnerRect), + mRect(0, 0, 0, 0), + mOuterRect(0, 0, 0, 0), + mMargins(0, 0, 0, 0), + mMinimumMargins(0, 0, 0, 0), + mAutoMargins(QCP::msAll) +{ +} + +QCPLayoutElement::~QCPLayoutElement() +{ + setMarginGroup(QCP::msAll, 0); // unregister at margin groups, if there are any + // unregister at layout: + if (qobject_cast(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor + mParentLayout->take(this); +} + +/*! + Sets the outer rect of this layout element. If the layout element is inside a layout, the layout + sets the position and size of this layout element using this function. + + Calling this function externally has no effect, since the layout will overwrite any changes to + the outer rect upon the next replot. + + The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. + + \see rect +*/ +void QCPLayoutElement::setOuterRect(const QRect &rect) +{ + if (mOuterRect != rect) + { + mOuterRect = rect; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all + sides, this function is used to manually set the margin on those sides. Sides that are still set + to be handled automatically are ignored and may have any value in \a margins. + + The margin is the distance between the outer rect (controlled by the parent layout via \ref + setOuterRect) and the inner \ref rect (which usually contains the main content of this layout + element). + + \see setAutoMargins +*/ +void QCPLayoutElement::setMargins(const QMargins &margins) +{ + if (mMargins != margins) + { + mMargins = margins; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + If \ref setAutoMargins is enabled on some or all margins, this function is used to provide + minimum values for those margins. + + The minimum values are not enforced on margin sides that were set to be under manual control via + \ref setAutoMargins. + + \see setAutoMargins +*/ +void QCPLayoutElement::setMinimumMargins(const QMargins &margins) +{ + if (mMinimumMargins != margins) + { + mMinimumMargins = margins; + } +} + +/*! + Sets on which sides the margin shall be calculated automatically. If a side is calculated + automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is + set to be controlled manually, the value may be specified with \ref setMargins. + + Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref + setMarginGroup), to synchronize (align) it with other layout elements in the plot. + + \see setMinimumMargins, setMargins, QCP::MarginSide +*/ +void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) +{ + mAutoMargins = sides; +} + +/*! + Sets the minimum size of this layout element. A parent layout tries to respect the \a size here + by changing row/column sizes in the layout accordingly. + + If the parent layout size is not sufficient to satisfy all minimum size constraints of its child + layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot + propagates the layout's size constraints to the outside by setting its own minimum QWidget size + accordingly, so violations of \a size should be exceptions. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMinimumSize(const QSize &size) +{ + if (mMinimumSize != size) + { + mMinimumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the minimum size of this layout element. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMinimumSize(int width, int height) +{ + setMinimumSize(QSize(width, height)); +} + +/*! + Sets the maximum size of this layout element. A parent layout tries to respect the \a size here + by changing row/column sizes in the layout accordingly. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMaximumSize(const QSize &size) +{ + if (mMaximumSize != size) + { + mMaximumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the maximum size of this layout element. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMaximumSize(int width, int height) +{ + setMaximumSize(QSize(width, height)); +} + +/*! + Sets to which rect of a layout element the size constraints apply. Size constraints can be set + via \ref setMinimumSize and \ref setMaximumSize. + + The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis + labels), whereas the inner rect (\ref rect) does not. + + \see setMinimumSize, setMaximumSize +*/ +void QCPLayoutElement::setSizeConstraintRect(SizeConstraintRect constraintRect) +{ + if (mSizeConstraintRect != constraintRect) + { + mSizeConstraintRect = constraintRect; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! + Sets the margin \a group of the specified margin \a sides. + + Margin groups allow synchronizing specified margins across layout elements, see the documentation + of \ref QCPMarginGroup. + + To unset the margin group of \a sides, set \a group to 0. + + Note that margin groups only work for margin sides that are set to automatic (\ref + setAutoMargins). + + \see QCP::MarginSide +*/ +void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) +{ + QVector sideVector; + if (sides.testFlag(QCP::msLeft)) sideVector.append(QCP::msLeft); + if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); + if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); + if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); + + for (int i=0; iremoveChild(side, this); + + if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there + { + mMarginGroups.remove(side); + } else // setting to a new group + { + mMarginGroups[side] = group; + group->addChild(side, this); + } + } + } +} + +/*! + Updates the layout element and sub-elements. This function is automatically called before every + replot by the parent layout element. It is called multiple times, once for every \ref + UpdatePhase. The phases are run through in the order of the enum values. For details about what + happens at the different phases, see the documentation of \ref UpdatePhase. + + Layout elements that have child elements should call the \ref update method of their child + elements, and pass the current \a phase unchanged. + + The default implementation executes the automatic margin mechanism in the \ref upMargins phase. + Subclasses should make sure to call the base class implementation. +*/ +void QCPLayoutElement::update(UpdatePhase phase) +{ + if (phase == upMargins) + { + if (mAutoMargins != QCP::msNone) + { + // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group: + QMargins newMargins = mMargins; + QList allMarginSides = QList() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom; + foreach (QCP::MarginSide side, allMarginSides) + { + if (mAutoMargins.testFlag(side)) // this side's margin shall be calculated automatically + { + if (mMarginGroups.contains(side)) + QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group + else + QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly + // apply minimum margin restrictions: + if (QCP::getMarginValue(newMargins, side) < QCP::getMarginValue(mMinimumMargins, side)) + QCP::setMarginValue(newMargins, side, QCP::getMarginValue(mMinimumMargins, side)); + } + } + setMargins(newMargins); + } + } +} + +/*! + Returns the suggested minimum size this layout element (the \ref outerRect) may be compressed to, + if no manual minimum size is set. + + if a minimum size (\ref setMinimumSize) was not set manually, parent layouts use the returned size + (usually indirectly through \ref QCPLayout::getFinalMinimumOuterSize) to determine the minimum + allowed size of this layout element. + + A manual minimum size is considered set if it is non-zero. + + The default implementation simply returns the sum of the horizontal margins for the width and the + sum of the vertical margins for the height. Reimplementations may use their detailed knowledge + about the layout element's content to provide size hints. +*/ +QSize QCPLayoutElement::minimumOuterSizeHint() const +{ + return QSize(mMargins.left()+mMargins.right(), mMargins.top()+mMargins.bottom()); +} + +/*! + Returns the suggested maximum size this layout element (the \ref outerRect) may be expanded to, + if no manual maximum size is set. + + if a maximum size (\ref setMaximumSize) was not set manually, parent layouts use the returned + size (usually indirectly through \ref QCPLayout::getFinalMaximumOuterSize) to determine the + maximum allowed size of this layout element. + + A manual maximum size is considered set if it is smaller than Qt's \c QWIDGETSIZE_MAX. + + The default implementation simply returns \c QWIDGETSIZE_MAX for both width and height, implying + no suggested maximum size. Reimplementations may use their detailed knowledge about the layout + element's content to provide size hints. +*/ +QSize QCPLayoutElement::maximumOuterSizeHint() const +{ + return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); +} + +/*! + Returns a list of all child elements in this layout element. If \a recursive is true, all + sub-child elements are included in the list, too. + + \warning There may be entries with value 0 in the returned list. (For example, QCPLayoutGrid may have + empty cells which yield 0 at the respective index.) +*/ +QList QCPLayoutElement::elements(bool recursive) const +{ + Q_UNUSED(recursive) + return QList(); +} + +/*! + Layout elements are sensitive to events inside their outer rect. If \a pos is within the outer + rect, this method returns a value corresponding to 0.99 times the parent plot's selection + tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is + true, -1.0 is returned. + + See \ref QCPLayerable::selectTest for a general explanation of this virtual method. + + QCPLayoutElement subclasses may reimplement this method to provide more specific selection test + behaviour. +*/ +double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + + if (onlySelectable) + return -1; + + if (QRectF(mOuterRect).contains(pos)) + { + if (mParentPlot) + return mParentPlot->selectionTolerance()*0.99; + else + { + qDebug() << Q_FUNC_INFO << "parent plot not defined"; + return -1; + } + } else + return -1; +} + +/*! \internal + + propagates the parent plot initialization to all child elements, by calling \ref + QCPLayerable::initializeParentPlot on them. +*/ +void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) +{ + foreach (QCPLayoutElement* el, elements(false)) + { + if (!el->parentPlot()) + el->initializeParentPlot(parentPlot); + } +} + +/*! \internal + + Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a + side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the + returned value will not be smaller than the specified minimum margin. + + The default implementation just returns the respective manual margin (\ref setMargins) or the + minimum margin, whichever is larger. +*/ +int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) +{ + return qMax(QCP::getMarginValue(mMargins, side), QCP::getMarginValue(mMinimumMargins, side)); +} + +/*! \internal + + This virtual method is called when this layout element was moved to a different QCPLayout, or + when this layout element has changed its logical position (e.g. row and/or column) within the + same QCPLayout. Subclasses may use this to react accordingly. + + Since this method is called after the completion of the move, you can access the new parent + layout via \ref layout(). + + The default implementation does nothing. +*/ +void QCPLayoutElement::layoutChanged() +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayout +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayout + \brief The abstract base class for layouts + + This is an abstract base class for layout elements whose main purpose is to define the position + and size of other child layout elements. In most cases, layouts don't draw anything themselves + (but there are exceptions to this, e.g. QCPLegend). + + QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. + + QCPLayout introduces a common interface for accessing and manipulating the child elements. Those + functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref + simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions + to this interface which are more specialized to the form of the layout. For example, \ref + QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid + more conveniently. + + Since this is an abstract base class, you can't instantiate it directly. Rather use one of its + subclasses like QCPLayoutGrid or QCPLayoutInset. + + For a general introduction to the layout system, see the dedicated documentation page \ref + thelayoutsystem "The Layout System". +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPLayout::elementCount() const = 0 + + Returns the number of elements/cells in the layout. + + \see elements, elementAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 + + Returns the element in the cell with the given \a index. If \a index is invalid, returns 0. + + Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. + QCPLayoutGrid), so this function may return 0 in those cases. You may use this function to check + whether a cell is empty or not. + + \see elements, elementCount, takeAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 + + Removes the element with the given \a index from the layout and returns it. + + If the \a index is invalid or the cell with that index is empty, returns 0. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see elementAt, take +*/ + +/*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 + + Removes the specified \a element from the layout and returns true on success. + + If the \a element isn't in this layout, returns false. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see takeAt +*/ + +/* end documentation of pure virtual functions */ + +/*! + Creates an instance of QCPLayout and sets default values. Note that since QCPLayout + is an abstract base class, it can't be instantiated directly. +*/ +QCPLayout::QCPLayout() +{ +} + +/*! + If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to + reposition and resize their cells. + + Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements". + + For details about this method and the update phases, see the documentation of \ref + QCPLayoutElement::update. +*/ +void QCPLayout::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + // set child element rects according to layout: + if (phase == upLayout) + updateLayout(); + + // propagate update call to child elements: + const int elCount = elementCount(); + for (int i=0; iupdate(phase); + } +} + +/* inherits documentation from base class */ +QList QCPLayout::elements(bool recursive) const +{ + const int c = elementCount(); + QList result; +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(c); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the + default implementation does nothing. + + Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit + simplification while QCPLayoutGrid does. +*/ +void QCPLayout::simplify() +{ +} + +/*! + Removes and deletes the element at the provided \a index. Returns true on success. If \a index is + invalid or points to an empty cell, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the returned element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see remove, takeAt +*/ +bool QCPLayout::removeAt(int index) +{ + if (QCPLayoutElement *el = takeAt(index)) + { + delete el; + return true; + } else + return false; +} + +/*! + Removes and deletes the provided \a element. Returns true on success. If \a element is not in the + layout, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see removeAt, take +*/ +bool QCPLayout::remove(QCPLayoutElement *element) +{ + if (take(element)) + { + delete element; + return true; + } else + return false; +} + +/*! + Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure + all empty cells are collapsed. + + \see remove, removeAt +*/ +void QCPLayout::clear() +{ + for (int i=elementCount()-1; i>=0; --i) + { + if (elementAt(i)) + removeAt(i); + } + simplify(); +} + +/*! + Subclasses call this method to report changed (minimum/maximum) size constraints. + + If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref + sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of + QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, + it may update itself and resize cells accordingly. +*/ +void QCPLayout::sizeConstraintsChanged() const +{ + if (QWidget *w = qobject_cast(parent())) + w->updateGeometry(); + else if (QCPLayout *l = qobject_cast(parent())) + l->sizeConstraintsChanged(); +} + +/*! \internal + + Subclasses reimplement this method to update the position and sizes of the child elements/cells + via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. + + The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay + within that rect. + + \ref getSectionSizes may help with the reimplementation of this function. + + \see update +*/ +void QCPLayout::updateLayout() +{ +} + + +/*! \internal + + Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the + \ref QCPLayerable::parentLayerable and the QObject parent to this layout. + + Further, if \a el didn't previously have a parent plot, calls \ref + QCPLayerable::initializeParentPlot on \a el to set the paret plot. + + This method is used by subclass specific methods that add elements to the layout. Note that this + method only changes properties in \a el. The removal from the old layout and the insertion into + the new layout must be done additionally. +*/ +void QCPLayout::adoptElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = this; + el->setParentLayerable(this); + el->setParent(this); + if (!el->parentPlot()) + el->initializeParentPlot(mParentPlot); + el->layoutChanged(); + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout + and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent + QCustomPlot. + + This method is used by subclass specific methods that remove elements from the layout (e.g. \ref + take or \ref takeAt). Note that this method only changes properties in \a el. The removal from + the old layout must be done additionally. +*/ +void QCPLayout::releaseElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = 0; + el->setParentLayerable(0); + el->setParent(mParentPlot); + // Note: Don't initializeParentPlot(0) here, because layout element will stay in same parent plot + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + This is a helper function for the implementation of \ref updateLayout in subclasses. + + It calculates the sizes of one-dimensional sections with provided constraints on maximum section + sizes, minimum section sizes, relative stretch factors and the final total size of all sections. + + The QVector entries refer to the sections. Thus all QVectors must have the same size. + + \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size + imposed, set all vector values to Qt's QWIDGETSIZE_MAX. + + \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size + imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than + \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, + not exceeding the allowed total size is taken to be more important than not going below minimum + section sizes.) + + \a stretchFactors give the relative proportions of the sections to each other. If all sections + shall be scaled equally, set all values equal. If the first section shall be double the size of + each individual other section, set the first number of \a stretchFactors to double the value of + the other individual values (e.g. {2, 1, 1, 1}). + + \a totalSize is the value that the final section sizes will add up to. Due to rounding, the + actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, + you could distribute the remaining difference on the sections. + + The return value is a QVector containing the section sizes. +*/ +QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const +{ + if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) + { + qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; + return QVector(); + } + if (stretchFactors.isEmpty()) + return QVector(); + int sectionCount = stretchFactors.size(); + QVector sectionSizes(sectionCount); + // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): + int minSizeSum = 0; + for (int i=0; i minimumLockedSections; + QList unfinishedSections; + for (int i=0; i result(sectionCount); + for (int i=0; iminimumOuterSizeHint(); + QSize minOuter = el->minimumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset minimum of 0) + if (minOuter.width() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + minOuter.rwidth() += el->margins().left() + el->margins().right(); + if (minOuter.height() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + minOuter.rheight() += el->margins().top() + el->margins().bottom(); + + return QSize(minOuter.width() > 0 ? minOuter.width() : minOuterHint.width(), + minOuter.height() > 0 ? minOuter.height() : minOuterHint.height());; +} + +/*! \internal + + This is a helper function for the implementation of subclasses. + + It returns the maximum size that should finally be used for the outer rect of the passed layout + element \a el. + + It takes into account whether a manual maximum size is set (\ref + QCPLayoutElement::setMaximumSize), which size constraint is set (\ref + QCPLayoutElement::setSizeConstraintRect), as well as the maximum size hint, if no manual maximum + size was set (\ref QCPLayoutElement::maximumOuterSizeHint). +*/ +QSize QCPLayout::getFinalMaximumOuterSize(const QCPLayoutElement *el) +{ + QSize maxOuterHint = el->maximumOuterSizeHint(); + QSize maxOuter = el->maximumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset maximum of QWIDGETSIZE_MAX) + if (maxOuter.width() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + maxOuter.rwidth() += el->margins().left() + el->margins().right(); + if (maxOuter.height() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + maxOuter.rheight() += el->margins().top() + el->margins().bottom(); + + return QSize(maxOuter.width() < QWIDGETSIZE_MAX ? maxOuter.width() : maxOuterHint.width(), + maxOuter.height() < QWIDGETSIZE_MAX ? maxOuter.height() : maxOuterHint.height()); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutGrid + \brief A layout that arranges child elements in a grid + + Elements are laid out in a grid with configurable stretch factors (\ref setColumnStretchFactor, + \ref setRowStretchFactor) and spacing (\ref setColumnSpacing, \ref setRowSpacing). + + Elements can be added to cells via \ref addElement. The grid is expanded if the specified row or + column doesn't exist yet. Whether a cell contains a valid layout element can be checked with \ref + hasElement, that element can be retrieved with \ref element. If rows and columns that only have + empty cells shall be removed, call \ref simplify. Removal of elements is either done by just + adding the element to a different layout or by using the QCPLayout interface \ref take or \ref + remove. + + If you use \ref addElement(QCPLayoutElement*) without explicit parameters for \a row and \a + column, the grid layout will choose the position according to the current \ref setFillOrder and + the wrapping (\ref setWrap). + + Row and column insertion can be performed with \ref insertRow and \ref insertColumn. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPLayoutGrid::rowCount() const + + Returns the number of rows in the layout. + + \see columnCount +*/ + +/*! \fn int QCPLayoutGrid::columnCount() const + + Returns the number of columns in the layout. + + \see rowCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutGrid and sets default values. +*/ +QCPLayoutGrid::QCPLayoutGrid() : + mColumnSpacing(5), + mRowSpacing(5), + mWrap(0), + mFillOrder(foRowsFirst) +{ +} + +QCPLayoutGrid::~QCPLayoutGrid() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the element in the cell in \a row and \a column. + + Returns 0 if either the row/column is invalid or if the cell is empty. In those cases, a qDebug + message is printed. To check whether a cell exists and isn't empty, use \ref hasElement. + + \see addElement, hasElement +*/ +QCPLayoutElement *QCPLayoutGrid::element(int row, int column) const +{ + if (row >= 0 && row < mElements.size()) + { + if (column >= 0 && column < mElements.first().size()) + { + if (QCPLayoutElement *result = mElements.at(row).at(column)) + return result; + else + qDebug() << Q_FUNC_INFO << "Requested cell is empty. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid column. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid row. Row:" << row << "Column:" << column; + return 0; +} + + +/*! \overload + + Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it + is first removed from there. If \a row or \a column don't exist yet, the layout is expanded + accordingly. + + Returns true if the element was added successfully, i.e. if the cell at \a row and \a column + didn't already have an element. + + Use the overload of this method without explicit row/column index to place the element according + to the configured fill order and wrapping settings. + + \see element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(int row, int column, QCPLayoutElement *element) +{ + if (!hasElement(row, column)) + { + if (element && element->layout()) // remove from old layout first + element->layout()->take(element); + expandTo(row+1, column+1); + mElements[row][column] = element; + if (element) + adoptElement(element); + return true; + } else + qDebug() << Q_FUNC_INFO << "There is already an element in the specified row/column:" << row << column; + return false; +} + +/*! \overload + + Adds the \a element to the next empty cell according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap). If \a element is already in a layout, it is first + removed from there. If necessary, the layout is expanded to hold the new element. + + Returns true if the element was added successfully. + + \see setFillOrder, setWrap, element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(QCPLayoutElement *element) +{ + int rowIndex = 0; + int colIndex = 0; + if (mFillOrder == foColumnsFirst) + { + while (hasElement(rowIndex, colIndex)) + { + ++colIndex; + if (colIndex >= mWrap && mWrap > 0) + { + colIndex = 0; + ++rowIndex; + } + } + } else + { + while (hasElement(rowIndex, colIndex)) + { + ++rowIndex; + if (rowIndex >= mWrap && mWrap > 0) + { + rowIndex = 0; + ++colIndex; + } + } + } + return addElement(rowIndex, colIndex, element); +} + +/*! + Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't + empty. + + \see element +*/ +bool QCPLayoutGrid::hasElement(int row, int column) +{ + if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) + return mElements.at(row).at(column); + else + return false; +} + +/*! + Sets the stretch \a factor of \a column. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactors, setRowStretchFactor +*/ +void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) +{ + if (column >= 0 && column < columnCount()) + { + if (factor > 0) + mColumnStretchFactors[column] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid column:" << column; +} + +/*! + Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactor, setRowStretchFactors +*/ +void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) +{ + if (factors.size() == mColumnStretchFactors.size()) + { + mColumnStretchFactors = factors; + for (int i=0; i= 0 && row < rowCount()) + { + if (factor > 0) + mRowStretchFactors[row] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid row:" << row; +} + +/*! + Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setRowStretchFactor, setColumnStretchFactors +*/ +void QCPLayoutGrid::setRowStretchFactors(const QList &factors) +{ + if (factors.size() == mRowStretchFactors.size()) + { + mRowStretchFactors = factors; + for (int i=0; i tempElements; + if (rearrange) + { + tempElements.reserve(elCount); + for (int i=0; i()); + mRowStretchFactors.append(1); + } + // go through rows and expand columns as necessary: + int newColCount = qMax(columnCount(), newColumnCount); + for (int i=0; i rowCount()) + newIndex = rowCount(); + + mRowStretchFactors.insert(newIndex, 1); + QList newRow; + for (int col=0; col columnCount()) + newIndex = columnCount(); + + mColumnStretchFactors.insert(newIndex, 1); + for (int row=0; row= 0 && row < rowCount()) + { + if (column >= 0 && column < columnCount()) + { + switch (mFillOrder) + { + case foRowsFirst: return column*rowCount() + row; + case foColumnsFirst: return row*columnCount() + column; + } + } else + qDebug() << Q_FUNC_INFO << "row index out of bounds:" << row; + } else + qDebug() << Q_FUNC_INFO << "column index out of bounds:" << column; + return 0; +} + +/*! + Converts the linear index to row and column indices and writes the result to \a row and \a + column. + + The way the cells are indexed depends on \ref setFillOrder. If it is \ref foRowsFirst, the + indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices + increase top to bottom and then left to right. + + If there are no cells (i.e. column or row count is zero), sets \a row and \a column to -1. + + For the retrieved \a row and \a column to be valid, the passed \a index must be valid itself, + i.e. greater or equal to zero and smaller than the current \ref elementCount. + + \see rowColToIndex +*/ +void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const +{ + row = -1; + column = -1; + const int nCols = columnCount(); + const int nRows = rowCount(); + if (nCols == 0 || nRows == 0) + return; + if (index < 0 || index >= elementCount()) + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return; + } + + switch (mFillOrder) + { + case foRowsFirst: + { + column = index / nRows; + row = index % nRows; + break; + } + case foColumnsFirst: + { + row = index / nCols; + column = index % nCols; + break; + } + } +} + +/* inherits documentation from base class */ +void QCPLayoutGrid::updateLayout() +{ + QVector minColWidths, minRowHeights, maxColWidths, maxRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + int totalRowSpacing = (rowCount()-1) * mRowSpacing; + int totalColSpacing = (columnCount()-1) * mColumnSpacing; + QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); + QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); + + // go through cells and set rects accordingly: + int yOffset = mRect.top(); + for (int row=0; row 0) + yOffset += rowHeights.at(row-1)+mRowSpacing; + int xOffset = mRect.left(); + for (int col=0; col 0) + xOffset += colWidths.at(col-1)+mColumnSpacing; + if (mElements.at(row).at(col)) + mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row))); + } + } +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::elementAt(int index) const +{ + if (index >= 0 && index < elementCount()) + { + int row, col; + indexToRowCol(index, row, col); + return mElements.at(row).at(col); + } else + return 0; +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + int row, col; + indexToRowCol(index, row, col); + mElements[row][col] = 0; + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutGrid::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; i QCPLayoutGrid::elements(bool recursive) const +{ + QList result; + const int elCount = elementCount(); +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(elCount); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing rows and columns which only contain empty cells. +*/ +void QCPLayoutGrid::simplify() +{ + // remove rows with only empty cells: + for (int row=rowCount()-1; row>=0; --row) + { + bool hasElements = false; + for (int col=0; col=0; --col) + { + bool hasElements = false; + for (int row=0; row minColWidths, minRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + QSize result(0, 0); + for (int i=0; i maxColWidths, maxRowHeights; + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + QSize result(0, 0); + for (int i=0; i QWIDGETSIZE_MAX) + result.setHeight(QWIDGETSIZE_MAX); + if (result.width() > QWIDGETSIZE_MAX) + result.setWidth(QWIDGETSIZE_MAX); + return result; +} + +/*! \internal + + Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights + respectively. + + The minimum height of a row is the largest minimum height of any element's outer rect in that + row. The minimum width of a column is the largest minimum width of any element's outer rect in + that column. + + This is a helper function for \ref updateLayout. + + \see getMaximumRowColSizes +*/ +void QCPLayoutGrid::getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const +{ + *minColWidths = QVector(columnCount(), 0); + *minRowHeights = QVector(rowCount(), 0); + for (int row=0; rowat(col) < minSize.width()) + (*minColWidths)[col] = minSize.width(); + if (minRowHeights->at(row) < minSize.height()) + (*minRowHeights)[row] = minSize.height(); + } + } + } +} + +/*! \internal + + Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights + respectively. + + The maximum height of a row is the smallest maximum height of any element's outer rect in that + row. The maximum width of a column is the smallest maximum width of any element's outer rect in + that column. + + This is a helper function for \ref updateLayout. + + \see getMinimumRowColSizes +*/ +void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const +{ + *maxColWidths = QVector(columnCount(), QWIDGETSIZE_MAX); + *maxRowHeights = QVector(rowCount(), QWIDGETSIZE_MAX); + for (int row=0; rowat(col) > maxSize.width()) + (*maxColWidths)[col] = maxSize.width(); + if (maxRowHeights->at(row) > maxSize.height()) + (*maxRowHeights)[row] = maxSize.height(); + } + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutInset +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPLayoutInset + \brief A layout that places child elements aligned to the border or arbitrarily positioned + + Elements are placed either aligned to the border or at arbitrary position in the area of the + layout. Which placement applies is controlled with the \ref InsetPlacement (\ref + setInsetPlacement). + + Elements are added via \ref addElement(QCPLayoutElement *element, Qt::Alignment alignment) or + addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset + placement will default to \ref ipBorderAligned and the element will be aligned according to the + \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at + arbitrary position and size, defined by \a rect. + + The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively. + + This is the layout that every QCPAxisRect has as \ref QCPAxisRect::insetLayout. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual void QCPLayoutInset::simplify() + + The QCPInsetLayout does not need simplification since it can never have empty cells due to its + linear index structure. This method does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutInset and sets default values. +*/ +QCPLayoutInset::QCPLayoutInset() +{ +} + +QCPLayoutInset::~QCPLayoutInset() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the placement type of the element with the specified \a index. +*/ +QCPLayoutInset::InsetPlacement QCPLayoutInset::insetPlacement(int index) const +{ + if (elementAt(index)) + return mInsetPlacement.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return ipFree; + } +} + +/*! + Returns the alignment of the element with the specified \a index. The alignment only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned. +*/ +Qt::Alignment QCPLayoutInset::insetAlignment(int index) const +{ + if (elementAt(index)) + return mInsetAlignment.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return 0; + } +} + +/*! + Returns the rect of the element with the specified \a index. The rect only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipFree. +*/ +QRectF QCPLayoutInset::insetRect(int index) const +{ + if (elementAt(index)) + return mInsetRect.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return QRectF(); + } +} + +/*! + Sets the inset placement type of the element with the specified \a index to \a placement. + + \see InsetPlacement +*/ +void QCPLayoutInset::setInsetPlacement(int index, QCPLayoutInset::InsetPlacement placement) +{ + if (elementAt(index)) + mInsetPlacement[index] = placement; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned, this function + is used to set the alignment of the element with the specified \a index to \a alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. +*/ +void QCPLayoutInset::setInsetAlignment(int index, Qt::Alignment alignment) +{ + if (elementAt(index)) + mInsetAlignment[index] = alignment; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the + position and size of the element with the specified \a index to \a rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + Note that the minimum and maximum sizes of the embedded element (\ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize) are enforced. +*/ +void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) +{ + if (elementAt(index)) + mInsetRect[index] = rect; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/* inherits documentation from base class */ +void QCPLayoutInset::updateLayout() +{ + for (int i=0; i finalMaxSize.width()) + insetRect.setWidth(finalMaxSize.width()); + if (insetRect.size().height() > finalMaxSize.height()) + insetRect.setHeight(finalMaxSize.height()); + } else if (mInsetPlacement.at(i) == ipBorderAligned) + { + insetRect.setSize(finalMinSize); + Qt::Alignment al = mInsetAlignment.at(i); + if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(rect().x()); + else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(rect().x()+rect().width()); + else insetRect.moveLeft(rect().x()+rect().width()*0.5-finalMinSize.width()*0.5); // default to Qt::AlignHCenter + if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(rect().y()); + else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(rect().y()+rect().height()); + else insetRect.moveTop(rect().y()+rect().height()*0.5-finalMinSize.height()*0.5); // default to Qt::AlignVCenter + } + mElements.at(i)->setOuterRect(insetRect); + } +} + +/* inherits documentation from base class */ +int QCPLayoutInset::elementCount() const +{ + return mElements.size(); +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::elementAt(int index) const +{ + if (index >= 0 && index < mElements.size()) + return mElements.at(index); + else + return 0; +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + mElements.removeAt(index); + mInsetPlacement.removeAt(index); + mInsetAlignment.removeAt(index); + mInsetRect.removeAt(index); + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutInset::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; irealVisibility() && mElements.at(i)->selectTest(pos, onlySelectable) >= 0) + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/*! + Adds the specified \a element to the layout as an inset aligned at the border (\ref + setInsetAlignment is initialized with \ref ipBorderAligned). The alignment is set to \a + alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. + + \see addElement(QCPLayoutElement *element, const QRectF &rect) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, Qt::Alignment alignment) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipBorderAligned); + mInsetAlignment.append(alignment); + mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4)); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} + +/*! + Adds the specified \a element to the layout as an inset with free positioning/sizing (\ref + setInsetAlignment is initialized with \ref ipFree). The position and size is set to \a + rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + \see addElement(QCPLayoutElement *element, Qt::Alignment alignment) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, const QRectF &rect) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipFree); + mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop); + mInsetRect.append(rect); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} +/* end of 'src/layout.cpp' */ + + +/* including file 'src/lineending.cpp', size 11536 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLineEnding +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLineEnding + \brief Handles the different ending decorations for line-like items + + \image html QCPLineEnding.png "The various ending styles currently supported" + + For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine + has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. + + The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can + be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of + the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. + For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite + directions, e.g. "outward". This can be changed by \ref setInverted, which would make the + respective arrow point inward. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a + QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. + \snippet documentation/doc-code-snippets/mainwindow.cpp qcplineending-sethead +*/ + +/*! + Creates a QCPLineEnding instance with default values (style \ref esNone). +*/ +QCPLineEnding::QCPLineEnding() : + mStyle(esNone), + mWidth(8), + mLength(10), + mInverted(false) +{ +} + +/*! + Creates a QCPLineEnding instance with the specified values. +*/ +QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : + mStyle(style), + mWidth(width), + mLength(length), + mInverted(inverted) +{ +} + +/*! + Sets the style of the ending decoration. +*/ +void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) +{ + mStyle = style; +} + +/*! + Sets the width of the ending decoration, if the style supports it. On arrows, for example, the + width defines the size perpendicular to the arrow's pointing direction. + + \see setLength +*/ +void QCPLineEnding::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the length of the ending decoration, if the style supports it. On arrows, for example, the + length defines the size in pointing direction. + + \see setWidth +*/ +void QCPLineEnding::setLength(double length) +{ + mLength = length; +} + +/*! + Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point + inward when \a inverted is set to true. + + Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or + discs, this doesn't make a difference. However, asymmetric styles like \ref esHalfBar are + affected by it, which can be used to control to which side the half bar points to. +*/ +void QCPLineEnding::setInverted(bool inverted) +{ + mInverted = inverted; +} + +/*! \internal + + Returns the maximum pixel radius the ending decoration might cover, starting from the position + the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). + + This is relevant for clipping. Only omit painting of the decoration when the position where the + decoration is supposed to be drawn is farther away from the clipping rect than the returned + distance. +*/ +double QCPLineEnding::boundingDistance() const +{ + switch (mStyle) + { + case esNone: + return 0; + + case esFlatArrow: + case esSpikeArrow: + case esLineArrow: + case esSkewedBar: + return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length + + case esDisc: + case esSquare: + case esDiamond: + case esBar: + case esHalfBar: + return mWidth*1.42; // items that only have a width -> width*sqrt(2) + + } + return 0; +} + +/*! + Starting from the origin of this line ending (which is style specific), returns the length + covered by the line ending symbol, in backward direction. + + For example, the \ref esSpikeArrow has a shorter real length than a \ref esFlatArrow, even if + both have the same \ref setLength value, because the spike arrow has an inward curved back, which + reduces the length along its center axis (the drawing origin for arrows is at the tip). + + This function is used for precise, style specific placement of line endings, for example in + QCPAxes. +*/ +double QCPLineEnding::realLength() const +{ + switch (mStyle) + { + case esNone: + case esLineArrow: + case esSkewedBar: + case esBar: + case esHalfBar: + return 0; + + case esFlatArrow: + return mLength; + + case esDisc: + case esSquare: + case esDiamond: + return mWidth*0.5; + + case esSpikeArrow: + return mLength*0.8; + } + return 0; +} + +/*! \internal + + Draws the line ending with the specified \a painter at the position \a pos. The direction of the + line ending is controlled with \a dir. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const +{ + if (mStyle == esNone) + return; + + QCPVector2D lengthVec = dir.normalized() * mLength*(mInverted ? -1 : 1); + if (lengthVec.isNull()) + lengthVec = QCPVector2D(1, 0); + QCPVector2D widthVec = dir.normalized().perpendicular() * mWidth*0.5*(mInverted ? -1 : 1); + + QPen penBackup = painter->pen(); + QBrush brushBackup = painter->brush(); + QPen miterPen = penBackup; + miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey + QBrush brush(painter->pen().color(), Qt::SolidPattern); + switch (mStyle) + { + case esNone: break; + case esFlatArrow: + { + QPointF points[3] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 3); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esSpikeArrow: + { + QPointF points[4] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec*0.8).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esLineArrow: + { + QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), + pos.toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawPolyline(points, 3); + painter->setPen(penBackup); + break; + } + case esDisc: + { + painter->setBrush(brush); + painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); + painter->setBrush(brushBackup); + break; + } + case esSquare: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), + (pos-widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esDiamond: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp).toPointF(), + (pos-widthVec).toPointF(), + (pos+widthVecPerp).toPointF(), + (pos+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esBar: + { + painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); + break; + } + case esHalfBar: + { + painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); + break; + } + case esSkewedBar: + { + if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic)) + { + // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)).toPointF()); + } else + { + // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF()); + } + break; + } + } +} + +/*! \internal + \overload + + Draws the line ending. The direction is controlled with the \a angle parameter in radians. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const +{ + draw(painter, pos, QCPVector2D(qCos(angle), qSin(angle))); +} +/* end of 'src/lineending.cpp' */ + + +/* including file 'src/axis/axisticker.cpp', size 18664 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTicker +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTicker + \brief The base class tick generator used by QCPAxis to create tick positions and tick labels + + Each QCPAxis has an internal QCPAxisTicker (or a subclass) in order to generate tick positions + and tick labels for the current axis range. The ticker of an axis can be set via \ref + QCPAxis::setTicker. Since that method takes a QSharedPointer, multiple + axes can share the same ticker instance. + + This base class generates normal tick coordinates and numeric labels for linear axes. It picks a + reasonable tick step (the separation between ticks) which results in readable tick labels. The + number of ticks that should be approximately generated can be set via \ref setTickCount. + Depending on the current tick step strategy (\ref setTickStepStrategy), the algorithm either + sacrifices readability to better match the specified tick count (\ref + QCPAxisTicker::tssMeetTickCount) or relaxes the tick count in favor of better tick steps (\ref + QCPAxisTicker::tssReadability), which is the default. + + The following more specialized axis ticker subclasses are available, see details in the + respective class documentation: + +
+ + + + + + + +
QCPAxisTickerFixed\image html axisticker-fixed.png
QCPAxisTickerLog\image html axisticker-log.png
QCPAxisTickerPi\image html axisticker-pi.png
QCPAxisTickerText\image html axisticker-text.png
QCPAxisTickerDateTime\image html axisticker-datetime.png
QCPAxisTickerTime\image html axisticker-time.png + \image html axisticker-time2.png
+
+ + \section axisticker-subclassing Creating own axis tickers + + Creating own axis tickers can be achieved very easily by sublassing QCPAxisTicker and + reimplementing some or all of the available virtual methods. + + In the simplest case you might wish to just generate different tick steps than the other tickers, + so you only reimplement the method \ref getTickStep. If you additionally want control over the + string that will be shown as tick label, reimplement \ref getTickLabel. + + If you wish to have complete control, you can generate the tick vectors and tick label vectors + yourself by reimplementing \ref createTickVector and \ref createLabelVector. The default + implementations use the previously mentioned virtual methods \ref getTickStep and \ref + getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case + of unequal tick steps, the method \ref getTickStep loses its usefulness and can be ignored. + + The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick + placement control is obtained by reimplementing \ref createSubTickVector. + + See the documentation of all these virtual methods in QCPAxisTicker for detailed information + about the parameters and expected return values. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTicker::QCPAxisTicker() : + mTickStepStrategy(tssReadability), + mTickCount(5), + mTickOrigin(0) +{ +} + +QCPAxisTicker::~QCPAxisTicker() +{ + +} + +/*! + Sets which strategy the axis ticker follows when choosing the size of the tick step. For the + available strategies, see \ref TickStepStrategy. +*/ +void QCPAxisTicker::setTickStepStrategy(QCPAxisTicker::TickStepStrategy strategy) +{ + mTickStepStrategy = strategy; +} + +/*! + Sets how many ticks this ticker shall aim to generate across the axis range. Note that \a count + is not guaranteed to be matched exactly, as generating readable tick intervals may conflict with + the requested number of ticks. + + Whether the readability has priority over meeting the requested \a count can be specified with + \ref setTickStepStrategy. +*/ +void QCPAxisTicker::setTickCount(int count) +{ + if (count > 0) + mTickCount = count; + else + qDebug() << Q_FUNC_INFO << "tick count must be greater than zero:" << count; +} + +/*! + Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a + concept and doesn't need to be inside the currently visible axis range. + + By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick + step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be + {-4, 1, 6, 11, 16,...}. +*/ +void QCPAxisTicker::setTickOrigin(double origin) +{ + mTickOrigin = origin; +} + +/*! + This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks), + tick label strings (\a tickLabels) and sub tick coordinates (\a subTicks). + + The ticks are generated for the specified \a range. The generated labels typically follow the + specified \a locale, \a formatChar and number \a precision, however this might be different (or + even irrelevant) for certain QCPAxisTicker subclasses. + + The output parameter \a ticks is filled with the generated tick positions in axis coordinates. + The output parameters \a subTicks and \a tickLabels are optional (set them to 0 if not needed) + and are respectively filled with sub tick coordinates, and tick label strings belonging to \a + ticks by index. +*/ +void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels) +{ + // generate (major) ticks: + double tickStep = getTickStep(range); + ticks = createTickVector(tickStep, range); + trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more) + + // generate sub ticks between major ticks: + if (subTicks) + { + if (ticks.size() > 0) + { + *subTicks = createSubTickVector(getSubTickCount(tickStep), ticks); + trimTicks(range, *subTicks, false); + } else + *subTicks = QVector(); + } + + // finally trim also outliers (no further clipping happens in axis drawing): + trimTicks(range, ticks, false); + // generate labels for visible ticks if requested: + if (tickLabels) + *tickLabels = createLabelVector(ticks, locale, formatChar, precision); +} + +/*! \internal + + Takes the entire currently visible axis range and returns a sensible tick step in + order to provide readable tick labels as well as a reasonable number of tick counts (see \ref + setTickCount, \ref setTickStepStrategy). + + If a QCPAxisTicker subclass only wants a different tick step behaviour than the default + implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper + function. +*/ +double QCPAxisTicker::getTickStep(const QCPRange &range) +{ + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return cleanMantissa(exactStep); +} + +/*! \internal + + Takes the \a tickStep, i.e. the distance between two consecutive ticks, and returns + an appropriate number of sub ticks for that specific tick step. + + Note that a returned sub tick count of e.g. 4 will split each tick interval into 5 sections. +*/ +int QCPAxisTicker::getSubTickCount(double tickStep) +{ + int result = 1; // default to 1, if no proper value can be found + + // separate integer and fractional part of mantissa: + double epsilon = 0.01; + double intPartf; + int intPart; + double fracPart = modf(getMantissa(tickStep), &intPartf); + intPart = intPartf; + + // handle cases with (almost) integer mantissa: + if (fracPart < epsilon || 1.0-fracPart < epsilon) + { + if (1.0-fracPart < epsilon) + ++intPart; + switch (intPart) + { + case 1: result = 4; break; // 1.0 -> 0.2 substep + case 2: result = 3; break; // 2.0 -> 0.5 substep + case 3: result = 2; break; // 3.0 -> 1.0 substep + case 4: result = 3; break; // 4.0 -> 1.0 substep + case 5: result = 4; break; // 5.0 -> 1.0 substep + case 6: result = 2; break; // 6.0 -> 2.0 substep + case 7: result = 6; break; // 7.0 -> 1.0 substep + case 8: result = 3; break; // 8.0 -> 2.0 substep + case 9: result = 2; break; // 9.0 -> 3.0 substep + } + } else + { + // handle cases with significantly fractional mantissa: + if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa + { + switch (intPart) + { + case 1: result = 2; break; // 1.5 -> 0.5 substep + case 2: result = 4; break; // 2.5 -> 0.5 substep + case 3: result = 4; break; // 3.5 -> 0.7 substep + case 4: result = 2; break; // 4.5 -> 1.5 substep + case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with default getTickStep from here on) + case 6: result = 4; break; // 6.5 -> 1.3 substep + case 7: result = 2; break; // 7.5 -> 2.5 substep + case 8: result = 4; break; // 8.5 -> 1.7 substep + case 9: result = 4; break; // 9.5 -> 1.9 substep + } + } + // if mantissa fraction isn't 0.0 or 0.5, don't bother finding good sub tick marks, leave default + } + + return result; +} + +/*! \internal + + This method returns the tick label string as it should be printed under the \a tick coordinate. + If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a + precision. + + If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is + enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will + be formatted accordingly using multiplication symbol and superscript during rendering of the + label automatically. +*/ +QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + return locale.toString(tick, formatChar.toLatin1(), precision); +} + +/*! \internal + + Returns a vector containing all coordinates of sub ticks that should be drawn. It generates \a + subTickCount sub ticks between each tick pair given in \a ticks. + + If a QCPAxisTicker subclass needs maximal control over the generated sub ticks, it should + reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to + base its result on \a subTickCount or \a ticks. +*/ +QVector QCPAxisTicker::createSubTickVector(int subTickCount, const QVector &ticks) +{ + QVector result; + if (subTickCount <= 0 || ticks.size() < 2) + return result; + + result.reserve((ticks.size()-1)*subTickCount); + for (int i=1; i QCPAxisTicker::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result; + // Generate tick positions according to tickStep: + qint64 firstStep = floor((range.lower-mTickOrigin)/tickStep); // do not use qFloor here, or we'll lose 64 bit precision + qint64 lastStep = ceil((range.upper-mTickOrigin)/tickStep); // do not use qCeil here, or we'll lose 64 bit precision + int tickcount = lastStep-firstStep+1; + if (tickcount < 0) tickcount = 0; + result.resize(tickcount); + for (int i=0; i QCPAxisTicker::createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision) +{ + QVector result; + result.reserve(ticks.size()); + for (int i=0; i &ticks, bool keepOneOutlier) const +{ + bool lowFound = false; + bool highFound = false; + int lowIndex = 0; + int highIndex = -1; + + for (int i=0; i < ticks.size(); ++i) + { + if (ticks.at(i) >= range.lower) + { + lowFound = true; + lowIndex = i; + break; + } + } + for (int i=ticks.size()-1; i >= 0; --i) + { + if (ticks.at(i) <= range.upper) + { + highFound = true; + highIndex = i; + break; + } + } + + if (highFound && lowFound) + { + int trimFront = qMax(0, lowIndex-(keepOneOutlier ? 1 : 0)); + int trimBack = qMax(0, ticks.size()-(keepOneOutlier ? 2 : 1)-highIndex); + if (trimFront > 0 || trimBack > 0) + ticks = ticks.mid(trimFront, ticks.size()-trimFront-trimBack); + } else // all ticks are either all below or all above the range + ticks.clear(); +} + +/*! \internal + + Returns the coordinate contained in \a candidates which is closest to the provided \a target. + + This method assumes \a candidates is not empty and sorted in ascending order. +*/ +double QCPAxisTicker::pickClosest(double target, const QVector &candidates) const +{ + if (candidates.size() == 1) + return candidates.first(); + QVector::const_iterator it = std::lower_bound(candidates.constBegin(), candidates.constEnd(), target); + if (it == candidates.constEnd()) + return *(it-1); + else if (it == candidates.constBegin()) + return *it; + else + return target-*(it-1) < *it-target ? *(it-1) : *it; +} + +/*! \internal + + Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also + returns the magnitude of \a input as a power of 10. + + For example, an input of 142.6 will return a mantissa of 1.426 and a magnitude of 100. +*/ +double QCPAxisTicker::getMantissa(double input, double *magnitude) const +{ + const double mag = qPow(10.0, qFloor(qLn(input)/qLn(10.0))); + if (magnitude) *magnitude = mag; + return input/mag; +} + +/*! \internal + + Returns a number that is close to \a input but has a clean, easier human readable mantissa. How + strongly the mantissa is altered, and thus how strong the result deviates from the original \a + input, depends on the current tick step strategy (see \ref setTickStepStrategy). +*/ +double QCPAxisTicker::cleanMantissa(double input) const +{ + double magnitude; + const double mantissa = getMantissa(input, &magnitude); + switch (mTickStepStrategy) + { + case tssReadability: + { + return pickClosest(mantissa, QVector() << 1.0 << 2.0 << 2.5 << 5.0 << 10.0)*magnitude; + } + case tssMeetTickCount: + { + // this gives effectively a mantissa of 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0 + if (mantissa <= 5.0) + return (int)(mantissa*2)/2.0*magnitude; // round digit after decimal point to 0.5 + else + return (int)(mantissa/2.0)*2.0*magnitude; // round to first digit in multiples of 2 + } + } + return input; +} +/* end of 'src/axis/axisticker.cpp' */ + + +/* including file 'src/axis/axistickerdatetime.cpp', size 14443 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerDateTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerDateTime + \brief Specialized axis ticker for calendar dates and times as axis ticks + + \image html axisticker-datetime.png + + This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The + plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00 + UTC). This is also used for example by QDateTime in the toTime_t()/setTime_t() methods + with a precision of one second. Since Qt 4.7, millisecond accuracy can be obtained from QDateTime + by using QDateTime::fromMSecsSinceEpoch()/1000.0. The static methods \ref dateTimeToKey + and \ref keyToDateTime conveniently perform this conversion achieving a precision of one + millisecond on all Qt versions. + + The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat. + If a different time spec (time zone) shall be used, see \ref setDateTimeSpec. + + This ticker produces unequal tick spacing in order to provide intuitive date and time-of-day + ticks. For example, if the axis range spans a few years such that there is one tick per year, + ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years, + will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in + the image above: even though the number of days varies month by month, this ticker generates + ticks on the same day of each month. + + If you would like to change the date/time that is used as a (mathematical) starting date for the + ticks, use the \ref setTickOrigin(const QDateTime &origin) method overload, which takes a + QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at + 9:45 of every year. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerdatetime-creation + + \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and + milliseconds, and are not interested in the intricacies of real calendar dates with months and + (leap) years, have a look at QCPAxisTickerTime instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerDateTime::QCPAxisTickerDateTime() : + mDateTimeFormat(QLatin1String("hh:mm:ss\ndd.MM.yy")), + mDateTimeSpec(Qt::LocalTime), + mDateStrategy(dsNone) +{ + setTickCount(4); +} + +/*! + Sets the format in which dates and times are displayed as tick labels. For details about the \a + format string, see the documentation of QDateTime::toString(). + + Newlines can be inserted with "\n". + + \see setDateTimeSpec +*/ +void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) +{ + mDateTimeFormat = format; +} + +/*! + Sets the time spec that is used for creating the tick labels from corresponding dates/times. + + The default value of QDateTime objects (and also QCPAxisTickerDateTime) is + Qt::LocalTime. However, if the date time values passed to QCustomPlot (e.g. in the form + of axis ranges or keys of a plottable) are given in the UTC spec, set \a spec to Qt::UTC + to get the correct axis labels. + + \see setDateTimeFormat +*/ +void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) +{ + mDateTimeSpec = spec; +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970, + 00:00 UTC). For the date time ticker it might be more intuitive to use the overload which + directly takes a QDateTime, see \ref setTickOrigin(const QDateTime &origin). + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(double origin) +{ + QCPAxisTicker::setTickOrigin(origin); +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) as a QDateTime \a origin. + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(const QDateTime &origin) +{ + setTickOrigin(dateTimeToKey(origin)); +} + +/*! \internal + + Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + Note that this tick step isn't used exactly when generating the tick vector in \ref + createTickVector, but only as a guiding value requiring some correction for each individual tick + interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day + in the month to the last day in the previous month from tick to tick, due to the non-uniform + length of months. The same problem arises with leap years. + + \seebaseclassmethod +*/ +double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + mDateStrategy = dsNone; + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + result = cleanMantissa(result); + } else if (result < 86400*30437.5*12) // below a year + { +// result = pickClosest(result, QVector() +// << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5*60 << 5*60 << 10*60 << 15*60 << 30*60 << 60*60 // second, minute, hour range +// << 3600*2 << 3600*3 << 3600*6 << 3600*12 << 3600*24 // hour to day range +// << 86400*2 << 86400*5 << 86400*7 << 86400*14 << 86400*30.4375 << 86400*30.4375*2 << 86400*30.4375*3 << 86400*30.4375*6 << 86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) + result = pickClosest(result, QVector() + << 1000 << 1000*2.5 << 1000*5 << 1000*10 << 1000*15 << 1000*30 << 1000*60 << 1000*2.5*60 << 1000*5*60 << 1000*10*60 << 1000*15*60 << 1000*30*60 << 1000*60*60 // second, minute, hour range + << 1000*3600*2 << 1000*3600*3 << 1000*3600*6 << 1000*3600*12 << 1000*3600*24 // hour to day range + << 1000*86400*2 << 1000*86400*5 << 1000*86400*7 << 1000*86400*14 << 1000*86400*30.4375 << 1000*86400*30.4375*2 << 1000*86400*30.4375*3 << 1000*86400*30.4375*6 << 1000*86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) + if (result > 86400*30437.5-1) // month tick intervals or larger + mDateStrategy = dsUniformDayInMonth; + else if (result > 3600*24*1000-1) // day tick intervals or larger + mDateStrategy = dsUniformTimeInDay; + } else // more than a year, go back to normal clean mantissa algorithm but in units of years + { + const double secondsPerYear = 86400*30437.5*12; // average including leap years + result = cleanMantissa(result/secondsPerYear)*secondsPerYear; + mDateStrategy = dsUniformDayInMonth; + } + return result; +} + +/*! \internal + + Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + \seebaseclassmethod +*/ +int QCPAxisTickerDateTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound64(tickStep)) // hand chosen subticks for specific minute/hour/day/week/month range (as specified in getTickStep) + { + case 5*1000*60: result = 4; break; + case 10*1000*60: result = 1; break; + case 15*1000*60: result = 2; break; + case 30*1000*60: result = 1; break; + case 60*1000*60: result = 3; break; + case 3600*1000*2: result = 3; break; + case 3600*1000*3: result = 2; break; + case 3600*1000*6: result = 1; break; + case 3600*1000*12: result = 3; break; + case 3600*1000*24: result = 3; break; + case 86400*1000*2: result = 1; break; + case 86400*1000*5: result = 4; break; + case 86400*1000*7: result = 6; break; + case 86400*1000*14: result = 1; break; + case (qint64)(86400*1000*30.4375+0.5): result = 3; break; + case (qint64)(86400*1000*30.4375*2+0.5): result = 1; break; + case (qint64)(86400*1000*30.4375*3+0.5): result = 2; break; + case (qint64)(86400*1000*30.4375*6+0.5): result = 5; break; + case (qint64)(86400*1000*30.4375*12+0.5): result = 3; break; + } + return result; +} + +/*! \internal + + Generates a date/time tick label for tick coordinate \a tick, based on the currently set format + (\ref setDateTimeFormat) and time spec (\ref setDateTimeSpec). + + \seebaseclassmethod +*/ +QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +} + +/*! \internal + + Uses the passed \a tickStep as a guiding value and applies corrections in order to obtain + non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month. + + \seebaseclassmethod +*/ +QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result = QCPAxisTicker::createTickVector(tickStep, range); + if (!result.isEmpty()) + { + if (mDateStrategy == dsUniformTimeInDay) + { + QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible + QDateTime tickDateTime; + for (int i=0; i 15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day + tickDateTime = tickDateTime.addMonths(-1); + tickDateTime.setDate(QDate(tickDateTime.date().year(), tickDateTime.date().month(), thisUniformDay)); + result[i] = dateTimeToKey(tickDateTime); + } + } + } + return result; +} + +/*! + A convenience method which turns \a key (in seconds since Epoch 1. Jan 1970, 00:00 UTC) into a + QDateTime object. This can be used to turn axis coordinates to actual QDateTimes. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::fromMSecsSinceEpoch in Qt 4.6) + + \see dateTimeToKey +*/ +QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) +{ + return QDateTime::fromMSecsSinceEpoch(key); +} + +/*! \overload + + A convenience method which turns a QDateTime object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::toMSecsSinceEpoch in Qt 4.6) + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime dateTime) +{ + return dateTime.toMSecsSinceEpoch(); +} + +/*! \overload + + A convenience method which turns a QDate object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDate date) +{ + return QDateTime(date).toMSecsSinceEpoch(); +} +/* end of 'src/axis/axistickerdatetime.cpp' */ + + +/* including file 'src/axis/axistickertime.cpp', size 11747 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerTime + \brief Specialized axis ticker for time spans in units of milliseconds to days + + \image html axisticker-time.png + + This QCPAxisTicker subclass generates ticks that corresponds to time intervals. + + The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref + setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate + zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date + and time. + + The time can be displayed in milliseconds, seconds, minutes, hours and days. Depending on the + largest available unit in the format specified with \ref setTimeFormat, any time spans above will + be carried in that largest unit. So for example if the format string is "%m:%s" and a tick at + coordinate value 7815 (being 2 hours, 10 minutes and 15 seconds) is created, the resulting tick + label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour + unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis + zero will carry a leading minus sign. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation + + Here is an example of a time axis providing time information in days, hours and minutes. Due to + the axis range spanning a few days and the wanted tick count (\ref setTickCount), the ticker + decided to use tick steps of 12 hours: + + \image html axisticker-time2.png + + The format string for this example is + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation-2 + + \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime + instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerTime::QCPAxisTickerTime() : + mTimeFormat(QLatin1String("%h:%m:%s")), + mSmallestUnit(tuSeconds), + mBiggestUnit(tuHours) +{ + setTickCount(4); + mFieldWidth[tuMilliseconds] = 3; + mFieldWidth[tuSeconds] = 2; + mFieldWidth[tuMinutes] = 2; + mFieldWidth[tuHours] = 2; + mFieldWidth[tuDays] = 1; + + mFormatPattern[tuMilliseconds] = QLatin1String("%z"); + mFormatPattern[tuSeconds] = QLatin1String("%s"); + mFormatPattern[tuMinutes] = QLatin1String("%m"); + mFormatPattern[tuHours] = QLatin1String("%h"); + mFormatPattern[tuDays] = QLatin1String("%d"); +} + +/*! + Sets the format that will be used to display time in the tick labels. + + The available patterns are: + - %%z for milliseconds + - %%s for seconds + - %%m for minutes + - %%h for hours + - %%d for days + + The field width (zero padding) can be controlled for each unit with \ref setFieldWidth. + + The largest unit that appears in \a format will carry all the remaining time of a certain tick + coordinate, even if it overflows the natural limit of the unit. For example, if %%m is the + largest unit it might become larger than 59 in order to consume larger time values. If on the + other hand %%h is available, the minutes will wrap around to zero after 59 and the time will + carry to the hour digit. +*/ +void QCPAxisTickerTime::setTimeFormat(const QString &format) +{ + mTimeFormat = format; + + // determine smallest and biggest unit in format, to optimize unit replacement and allow biggest + // unit to consume remaining time of a tick value and grow beyond its modulo (e.g. min > 59) + mSmallestUnit = tuMilliseconds; + mBiggestUnit = tuMilliseconds; + bool hasSmallest = false; + for (int i = tuMilliseconds; i <= tuDays; ++i) + { + TimeUnit unit = static_cast(i); + if (mTimeFormat.contains(mFormatPattern.value(unit))) + { + if (!hasSmallest) + { + mSmallestUnit = unit; + hasSmallest = true; + } + mBiggestUnit = unit; + } + } +} + +/*! + Sets the field widh of the specified \a unit to be \a width digits, when displayed in the tick + label. If the number for the specific unit is shorter than \a width, it will be padded with an + according number of zeros to the left in order to reach the field width. + + \see setTimeFormat +*/ +void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int width) +{ + mFieldWidth[unit] = qMax(width, 1); +} + +/*! \internal + + Returns the tick step appropriate for time displays, depending on the provided \a range and the + smallest available time unit in the current format (\ref setTimeFormat). For example if the unit + of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes) + that require sub-minute precision to be displayed correctly. + + \seebaseclassmethod +*/ +double QCPAxisTickerTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + if (mSmallestUnit == tuMilliseconds) + result = qMax(cleanMantissa(result), 0.001); // smallest tick step is 1 millisecond + else // have no milliseconds available in format, so stick with 1 second tickstep + result = 1.0; + } else if (result < 3600*24) // below a day + { + // the filling of availableSteps seems a bit contorted but it fills in a sorted fashion and thus saves a post-fill sorting run + QVector availableSteps; + // seconds range: + if (mSmallestUnit <= tuSeconds) + availableSteps << 1; + if (mSmallestUnit == tuMilliseconds) + availableSteps << 2.5; // only allow half second steps if milliseconds are there to display it + else if (mSmallestUnit == tuSeconds) + availableSteps << 2; + if (mSmallestUnit <= tuSeconds) + availableSteps << 5 << 10 << 15 << 30; + // minutes range: + if (mSmallestUnit <= tuMinutes) + availableSteps << 1*60; + if (mSmallestUnit <= tuSeconds) + availableSteps << 2.5*60; // only allow half minute steps if seconds are there to display it + else if (mSmallestUnit == tuMinutes) + availableSteps << 2*60; + if (mSmallestUnit <= tuMinutes) + availableSteps << 5*60 << 10*60 << 15*60 << 30*60; + // hours range: + if (mSmallestUnit <= tuHours) + availableSteps << 1*3600 << 2*3600 << 3*3600 << 6*3600 << 12*3600 << 24*3600; + // pick available step that is most appropriate to approximate ideal step: + result = pickClosest(result, availableSteps); + } else // more than a day, go back to normal clean mantissa algorithm but in units of days + { + const double secondsPerDay = 3600*24; + result = cleanMantissa(result/secondsPerDay)*secondsPerDay; + } + return result; +} + +/*! \internal + + Returns the sub tick count appropriate for the provided \a tickStep and time displays. + + \seebaseclassmethod +*/ +int QCPAxisTickerTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day range (as specified in getTickStep) + { + case 5*60: result = 4; break; + case 10*60: result = 1; break; + case 15*60: result = 2; break; + case 30*60: result = 1; break; + case 60*60: result = 3; break; + case 3600*2: result = 3; break; + case 3600*3: result = 2; break; + case 3600*6: result = 1; break; + case 3600*12: result = 3; break; + case 3600*24: result = 3; break; + } + return result; +} + +/*! \internal + + Returns the tick label corresponding to the provided \a tick and the configured format and field + widths (\ref setTimeFormat, \ref setFieldWidth). + + \seebaseclassmethod +*/ +QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + Q_UNUSED(locale) + bool negative = tick < 0; + if (negative) tick *= -1; + double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59) + double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time + + restValues[tuMilliseconds] = tick*1000; + values[tuMilliseconds] = modf(restValues[tuMilliseconds]/1000, &restValues[tuSeconds])*1000; + values[tuSeconds] = modf(restValues[tuSeconds]/60, &restValues[tuMinutes])*60; + values[tuMinutes] = modf(restValues[tuMinutes]/60, &restValues[tuHours])*60; + values[tuHours] = modf(restValues[tuHours]/24, &restValues[tuDays])*24; + // no need to set values[tuDays] because days are always a rest value (there is no higher unit so it consumes all remaining time) + + QString result = mTimeFormat; + for (int i = mSmallestUnit; i <= mBiggestUnit; ++i) + { + TimeUnit iUnit = static_cast(i); + replaceUnit(result, iUnit, qRound(iUnit == mBiggestUnit ? restValues[iUnit] : values[iUnit])); + } + if (negative) + result.prepend(QLatin1Char('-')); + return result; +} + +/*! \internal + + Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified + \a value, using the field width as specified with \ref setFieldWidth for the \a unit. +*/ +void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit unit, int value) const +{ + QString valueStr = QString::number(value); + while (valueStr.size() < mFieldWidth.value(unit)) + valueStr.prepend(QLatin1Char('0')); + + text.replace(mFormatPattern.value(unit), valueStr); +} +/* end of 'src/axis/axistickertime.cpp' */ + + +/* including file 'src/axis/axistickerfixed.cpp', size 5583 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerFixed +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerFixed + \brief Specialized axis ticker with a fixed tick step + + \image html axisticker-fixed.png + + This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It + is also possible to allow integer multiples and integer powers of the specified tick step with + \ref setScaleStrategy. + + A typical application of this ticker is to make an axis only display integers, by setting the + tick step of the ticker to 1.0 and the scale strategy to \ref ssMultiples. + + Another case is when a certain number has a special meaning and axis ticks should only appear at + multiples of that value. In this case you might also want to consider \ref QCPAxisTickerPi + because despite the name it is not limited to only pi symbols/values. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerfixed-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerFixed::QCPAxisTickerFixed() : + mTickStep(1.0), + mScaleStrategy(ssNone) +{ +} + +/*! + Sets the fixed tick interval to \a step. + + The axis ticker will only use this tick step when generating axis ticks. This might cause a very + high tick density and overlapping labels if the axis range is zoomed out. Using \ref + setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a + step. This will enable the ticker to reduce the number of ticks to a reasonable amount (see \ref + setTickCount). +*/ +void QCPAxisTickerFixed::setTickStep(double step) +{ + if (step > 0) + mTickStep = step; + else + qDebug() << Q_FUNC_INFO << "tick step must be greater than zero:" << step; +} + +/*! + Sets whether the specified tick step (\ref setTickStep) is absolutely fixed or whether + modifications may be applied to it before calculating the finally used tick step, such as + permitting multiples or powers. See \ref ScaleStrategy for details. + + The default strategy is \ref ssNone, which means the tick step is absolutely fixed. +*/ +void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy strategy) +{ + mScaleStrategy = strategy; +} + +/*! \internal + + Determines the actually used tick step from the specified tick step and scale strategy (\ref + setTickStep, \ref setScaleStrategy). + + This method either returns the specified tick step exactly, or, if the scale strategy is not \ref + ssNone, a modification of it to allow varying the number of ticks in the current axis range. + + \seebaseclassmethod +*/ +double QCPAxisTickerFixed::getTickStep(const QCPRange &range) +{ + switch (mScaleStrategy) + { + case ssNone: + { + return mTickStep; + } + case ssMultiples: + { + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + if (exactStep < mTickStep) + return mTickStep; + else + return (qint64)(cleanMantissa(exactStep/mTickStep)+0.5)*mTickStep; + } + case ssPowers: + { + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return qPow(mTickStep, (int)(qLn(exactStep)/qLn(mTickStep)+0.5)); + } + } + return mTickStep; +} +/* end of 'src/axis/axistickerfixed.cpp' */ + + +/* including file 'src/axis/axistickertext.cpp', size 8653 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerText +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerText + \brief Specialized axis ticker which allows arbitrary labels at specified coordinates + + \image html axisticker-text.png + + This QCPAxisTicker subclass generates ticks which can be directly specified by the user as + coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a + time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks + and modify the tick/label data there. + + This is useful for cases where the axis represents categories rather than numerical values. + + If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on + the axis range), it is a sign that you should probably create an own ticker by subclassing + QCPAxisTicker, instead of using this one. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertext-creation +*/ + +/* start of documentation of inline functions */ + +/*! \fn QMap &QCPAxisTickerText::ticks() + + Returns a non-const reference to the internal map which stores the tick coordinates and their + labels. + + You can access the map directly in order to add, remove or manipulate ticks, as an alternative to + using the methods provided by QCPAxisTickerText, such as \ref setTicks and \ref addTick. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerText::QCPAxisTickerText() : + mSubTickCount(0) +{ +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The map key of \a ticks corresponds to the axis + coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QMap &ticks) +{ + mTicks = ticks; +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis + coordinates, and the entries of \a labels are the respective strings that will appear as tick + labels. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QVector &positions, const QVector labels) +{ + clear(); + addTicks(positions, labels); +} + +/*! + Sets the number of sub ticks that shall appear between ticks. For QCPAxisTickerText, there is no + automatic sub tick count calculation. So if sub ticks are needed, they must be configured with this + method. +*/ +void QCPAxisTickerText::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! + Clears all ticks. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see setTicks, addTicks, addTick +*/ +void QCPAxisTickerText::clear() +{ + mTicks.clear(); +} + +/*! + Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a + label. + + \see addTicks, setTicks, clear +*/ +void QCPAxisTickerText::addTick(double position, QString label) +{ + mTicks.insert(position, label); +} + +/*! \overload + + Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to + the axis coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QMap &ticks) +{ + mTicks.unite(ticks); +} + +/*! \overload + + Adds the provided ticks to the ones already existing. The entries of \a positions correspond to + the axis coordinates, and the entries of \a labels are the respective strings that will appear as + tick labels. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QVector &positions, const QVector &labels) +{ + if (positions.size() != labels.size()) + qDebug() << Q_FUNC_INFO << "passed unequal length vectors for positions and labels:" << positions.size() << labels.size(); + int n = qMin(positions.size(), labels.size()); + for (int i=0; i QCPAxisTickerText::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (mTicks.isEmpty()) + return result; + + QMap::const_iterator start = mTicks.lowerBound(range.lower); + QMap::const_iterator end = mTicks.upperBound(range.upper); + // this method should try to give one tick outside of range so proper subticks can be generated: + if (start != mTicks.constBegin()) --start; + if (end != mTicks.constEnd()) ++end; + for (QMap::const_iterator it = start; it != end; ++it) + result.append(it.key()); + + return result; +} +/* end of 'src/axis/axistickertext.cpp' */ + + +/* including file 'src/axis/axistickerpi.cpp', size 11170 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerPi +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerPi + \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi + + \image html axisticker-pi.png + + This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic + constant with a numerical value specified with \ref setPiValue and an appearance in the tick + labels specified with \ref setPiSymbol. + + Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the + tick label can be configured with \ref setFractionStyle. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerpi-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerPi::QCPAxisTickerPi() : + mPiSymbol(QLatin1String(" ")+QChar(0x03C0)), + mPiValue(M_PI), + mPeriodicity(0), + mFractionStyle(fsUnicodeFractions), + mPiTickStep(0) +{ + setTickCount(4); +} + +/*! + Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick + label. + + If a space shall appear between the number and the symbol, make sure the space is contained in \a + symbol. +*/ +void QCPAxisTickerPi::setPiSymbol(QString symbol) +{ + mPiSymbol = symbol; +} + +/*! + Sets the numerical value that the symbolic constant has. + + This will be used to place the appropriate fractions of the symbol at the respective axis + coordinates. +*/ +void QCPAxisTickerPi::setPiValue(double pi) +{ + mPiValue = pi; +} + +/*! + Sets whether the axis labels shall appear periodicly and if so, at which multiplicity of the + symbolic constant. + + To disable periodicity, set \a multiplesOfPi to zero. + + For example, an axis that identifies 0 with 2pi would set \a multiplesOfPi to two. +*/ +void QCPAxisTickerPi::setPeriodicity(int multiplesOfPi) +{ + mPeriodicity = qAbs(multiplesOfPi); +} + +/*! + Sets how the numerical/fractional part preceding the symbolic constant is displayed in tick + labels. See \ref FractionStyle for the various options. +*/ +void QCPAxisTickerPi::setFractionStyle(QCPAxisTickerPi::FractionStyle style) +{ + mFractionStyle = style; +} + +/*! \internal + + Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence + the numerical/fractional part preceding the symbolic constant is made to have a readable + mantissa. + + \seebaseclassmethod +*/ +double QCPAxisTickerPi::getTickStep(const QCPRange &range) +{ + mPiTickStep = range.size()/mPiValue/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + mPiTickStep = cleanMantissa(mPiTickStep); + return mPiTickStep*mPiValue; +} + +/*! \internal + + Returns the sub tick count, using the constant's value (\ref setPiValue) as base unit. In + consequence the sub ticks divide the numerical/fractional part preceding the symbolic constant + reasonably, and not the total tick coordinate. + + \seebaseclassmethod +*/ +int QCPAxisTickerPi::getSubTickCount(double tickStep) +{ + return QCPAxisTicker::getSubTickCount(tickStep/mPiValue); +} + +/*! \internal + + Returns the tick label as a fractional/numerical part and a symbolic string as suffix. The + formatting of the fraction is done according to the specified \ref setFractionStyle. The appended + symbol is specified with \ref setPiSymbol. + + \seebaseclassmethod +*/ +QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + double tickInPis = tick/mPiValue; + if (mPeriodicity > 0) + tickInPis = fmod(tickInPis, mPeriodicity); + + if (mFractionStyle != fsFloatingPoint && mPiTickStep > 0.09 && mPiTickStep < 50) + { + // simply construct fraction from decimal like 1.234 -> 1234/1000 and then simplify fraction, smaller digits are irrelevant due to mPiTickStep conditional above + int denominator = 1000; + int numerator = qRound(tickInPis*denominator); + simplifyFraction(numerator, denominator); + if (qAbs(numerator) == 1 && denominator == 1) + return (numerator < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else if (numerator == 0) + return QLatin1String("0"); + else + return fractionToString(numerator, denominator) + mPiSymbol; + } else + { + if (qFuzzyIsNull(tickInPis)) + return QLatin1String("0"); + else if (qFuzzyCompare(qAbs(tickInPis), 1.0)) + return (tickInPis < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else + return QCPAxisTicker::getTickLabel(tickInPis, locale, formatChar, precision) + mPiSymbol; + } +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure + the fraction is in irreducible form, i.e. numerator and denominator don't share any common + factors which could be cancelled. +*/ +void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const +{ + if (numerator == 0 || denominator == 0) + return; + + int num = numerator; + int denom = denominator; + while (denom != 0) // euclidean gcd algorithm + { + int oldDenom = denom; + denom = num % denom; + num = oldDenom; + } + // num is now gcd of numerator and denominator + numerator /= num; + denominator /= num; +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and returns a string representation. + The result depends on the configured fraction style (\ref setFractionStyle). + + This method is used to format the numerical/fractional part when generating tick labels. It + simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out + any integer parts of the fraction (e.g. "10/4" becomes "2 1/2"). +*/ +QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const +{ + if (denominator == 0) + { + qDebug() << Q_FUNC_INFO << "called with zero denominator"; + return QString(); + } + if (mFractionStyle == fsFloatingPoint) // should never be the case when calling this function + { + qDebug() << Q_FUNC_INFO << "shouldn't be called with fraction style fsDecimal"; + return QString::number(numerator/(double)denominator); // failsafe + } + int sign = numerator*denominator < 0 ? -1 : 1; + numerator = qAbs(numerator); + denominator = qAbs(denominator); + + if (denominator == 1) + { + return QString::number(sign*numerator); + } else + { + int integerPart = numerator/denominator; + int remainder = numerator%denominator; + if (remainder == 0) + { + return QString::number(sign*integerPart); + } else + { + if (mFractionStyle == fsAsciiFractions) + { + return QString(QLatin1String("%1%2%3/%4")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart)+QLatin1String(" ") : QLatin1String("")) + .arg(remainder) + .arg(denominator); + } else if (mFractionStyle == fsUnicodeFractions) + { + return QString(QLatin1String("%1%2%3")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart) : QLatin1String("")) + .arg(unicodeFraction(remainder, denominator)); + } + } + } + return QString(); +} + +/*! \internal + + Returns the unicode string representation of the fraction given by \a numerator and \a + denominator. This is the representation used in \ref fractionToString when the fraction style + (\ref setFractionStyle) is \ref fsUnicodeFractions. + + This method doesn't use the single-character common fractions but builds each fraction from a + superscript unicode number, the unicode fraction character, and a subscript unicode number. +*/ +QString QCPAxisTickerPi::unicodeFraction(int numerator, int denominator) const +{ + return unicodeSuperscript(numerator)+QChar(0x2044)+unicodeSubscript(denominator); +} + +/*! \internal + + Returns the unicode string representing \a number as superscript. This is used to build + unicode fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSuperscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2070)); + + QString result; + while (number > 0) + { + const int digit = number%10; + switch (digit) + { + case 1: { result.prepend(QChar(0x00B9)); break; } + case 2: { result.prepend(QChar(0x00B2)); break; } + case 3: { result.prepend(QChar(0x00B3)); break; } + default: { result.prepend(QChar(0x2070+digit)); break; } + } + number /= 10; + } + return result; +} + +/*! \internal + + Returns the unicode string representing \a number as subscript. This is used to build unicode + fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSubscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2080)); + + QString result; + while (number > 0) + { + result.prepend(QChar(0x2080+number%10)); + number /= 10; + } + return result; +} +/* end of 'src/axis/axistickerpi.cpp' */ + + +/* including file 'src/axis/axistickerlog.cpp', size 7106 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerLog +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerLog + \brief Specialized axis ticker suited for logarithmic axes + + \image html axisticker-log.png + + This QCPAxisTicker subclass generates ticks with unequal tick intervals suited for logarithmic + axis scales. The ticks are placed at powers of the specified log base (\ref setLogBase). + + Especially in the case of a log base equal to 10 (the default), it might be desirable to have + tick labels in the form of powers of ten without mantissa display. To achieve this, set the + number precision (\ref QCPAxis::setNumberPrecision) to zero and the number format (\ref + QCPAxis::setNumberFormat) to scientific (exponential) display with beautifully typeset decimal + powers, so a format string of "eb". This will result in the following axis tick labels: + + \image html axisticker-log-powers.png + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerlog-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerLog::QCPAxisTickerLog() : + mLogBase(10.0), + mSubTickCount(8), // generates 10 intervals + mLogBaseLnInv(1.0/qLn(mLogBase)) +{ +} + +/*! + Sets the logarithm base used for tick coordinate generation. The ticks will be placed at integer + powers of \a base. +*/ +void QCPAxisTickerLog::setLogBase(double base) +{ + if (base > 0) + { + mLogBase = base; + mLogBaseLnInv = 1.0/qLn(mLogBase); + } else + qDebug() << Q_FUNC_INFO << "log base has to be greater than zero:" << base; +} + +/*! + Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced + linearly to provide a better visual guide, so the sub tick density increases toward the higher + tick. + + Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in + the case of logarithm base 10 an intuitive sub tick spacing would be achieved with eight sub + ticks (the default). This means e.g. between the ticks 10 and 100 there will be eight ticks, + namely at 20, 30, 40, 50, 60, 70, 80 and 90. +*/ +void QCPAxisTickerLog::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! \internal + + Since logarithmic tick steps are necessarily different for each tick interval, this method does + nothing in the case of QCPAxisTickerLog + + \seebaseclassmethod +*/ +double QCPAxisTickerLog::getTickStep(const QCPRange &range) +{ + // Logarithmic axis ticker has unequal tick spacing, so doesn't need this method + Q_UNUSED(range) + return 1.0; +} + +/*! \internal + + Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no + automatic sub tick count calculation necessary. + + \seebaseclassmethod +*/ +int QCPAxisTickerLog::getSubTickCount(double tickStep) +{ + Q_UNUSED(tickStep) + return mSubTickCount; +} + +/*! \internal + + Creates ticks with a spacing given by the logarithm base and an increasing integer power in the + provided \a range. The step in which the power increases tick by tick is chosen in order to keep + the total number of ticks as close as possible to the tick count (\ref setTickCount). The + parameter \a tickStep is ignored for QCPAxisTickerLog + + \seebaseclassmethod +*/ +QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (range.lower > 0 && range.upper > 0) // positive range + { + double exactPowerStep = qLn(range.upper/range.lower)*mLogBaseLnInv/(double)(mTickCount+1e-10); + double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); + double currentTick = qPow(newLogBase, qFloor(qLn(range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick *= newLogBase; + result.append(currentTick); + } + } else if (range.lower < 0 && range.upper < 0) // negative range + { + double exactPowerStep = qLn(range.lower/range.upper)*mLogBaseLnInv/(double)(mTickCount+1e-10); + double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); + double currentTick = -qPow(newLogBase, qCeil(qLn(-range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick /= newLogBase; + result.append(currentTick); + } + } else // invalid range for logarithmic scale, because lower and upper have different sign + { + qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << range.lower << ".." << range.upper; + } + + return result; +} +/* end of 'src/axis/axistickerlog.cpp' */ + + +/* including file 'src/axis/axis.cpp', size 99397 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGrid + \brief Responsible for drawing the grid of a QCPAxis. + + This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the + grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref + QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. + + The axis and grid drawing was split into two classes to allow them to be placed on different + layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid + in the background and the axes in the foreground, and any plottables/items in between. This + described situation is the default setup, see the QCPLayer documentation. +*/ + +/*! + Creates a QCPGrid instance and sets default values. + + You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. +*/ +QCPGrid::QCPGrid(QCPAxis *parentAxis) : + QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), + mParentAxis(parentAxis) +{ + // warning: this is called in QCPAxis constructor, so parentAxis members should not be accessed/called + setParent(parentAxis); + setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); + setSubGridVisible(false); + setAntialiased(false); + setAntialiasedSubGrid(false); + setAntialiasedZeroLine(false); +} + +/*! + Sets whether grid lines at sub tick marks are drawn. + + \see setSubGridPen +*/ +void QCPGrid::setSubGridVisible(bool visible) +{ + mSubGridVisible = visible; +} + +/*! + Sets whether sub grid lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedSubGrid(bool enabled) +{ + mAntialiasedSubGrid = enabled; +} + +/*! + Sets whether zero lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedZeroLine(bool enabled) +{ + mAntialiasedZeroLine = enabled; +} + +/*! + Sets the pen with which (major) grid lines are drawn. +*/ +void QCPGrid::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen with which sub grid lines are drawn. +*/ +void QCPGrid::setSubGridPen(const QPen &pen) +{ + mSubGridPen = pen; +} + +/*! + Sets the pen with which zero lines are drawn. + + Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid + lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. +*/ +void QCPGrid::setZeroLinePen(const QPen &pen) +{ + mZeroLinePen = pen; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing the major grid lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); +} + +/*! \internal + + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning + over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). +*/ +void QCPGrid::draw(QCPPainter *painter) +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + if (mParentAxis->subTicks() && mSubGridVisible) + drawSubGridLines(painter); + drawGridLines(painter); +} + +/*! \internal + + Draws the main grid lines and possibly a zero line with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + const int tickCount = mParentAxis->mTickVector.size(); + double t; // helper variable, result of coordinate-to-pixel transforms + if (mParentAxis->orientation() == Qt::Horizontal) + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + +/*! \internal + + Draws the sub grid lines with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawSubGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); + double t; // helper variable, result of coordinate-to-pixel transforms + painter->setPen(mSubGridPen); + if (mParentAxis->orientation() == Qt::Horizontal) + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxis +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxis + \brief Manages a single axis inside a QCustomPlot. + + Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via + QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and + QCustomPlot::yAxis2 (right). + + Axes are always part of an axis rect, see QCPAxisRect. + \image html AxisNamesOverview.png +
Naming convention of axis parts
+ \n + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line + on the left represents the QCustomPlot widget border.
+ + Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and + tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of + the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the + documentation of QCPAxisTicker. +*/ + +/* start of documentation of inline functions */ + +/*! \fn Qt::Orientation QCPAxis::orientation() const + + Returns the orientation of this axis. The axis orientation (horizontal or vertical) is deduced + from the axis type (left, top, right or bottom). + + \see orientation(AxisType type), pixelOrientation +*/ + +/*! \fn QCPGrid *QCPAxis::grid() const + + Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the + grid is displayed. +*/ + +/*! \fn static Qt::Orientation QCPAxis::orientation(AxisType type) + + Returns the orientation of the specified axis type + + \see orientation(), pixelOrientation +*/ + +/*! \fn int QCPAxis::pixelOrientation() const + + Returns which direction points towards higher coordinate values/keys, in pixel space. + + This method returns either 1 or -1. If it returns 1, then going in the positive direction along + the orientation of the axis in pixels corresponds to going from lower to higher axis coordinates. + On the other hand, if this method returns -1, going to smaller pixel values corresponds to going + from lower to higher axis coordinates. + + For example, this is useful to easily shift axis coordinates by a certain amount given in pixels, + without having to care about reversed or vertically aligned axes: + + \code + double newKey = keyAxis->pixelToCoord(keyAxis->coordToPixel(oldKey)+10*keyAxis->pixelOrientation()); + \endcode + + \a newKey will then contain a key that is ten pixels towards higher keys, starting from \a oldKey. +*/ + +/*! \fn QSharedPointer QCPAxis::ticker() const + + Returns a modifiable shared pointer to the currently installed axis ticker. The axis ticker is + responsible for generating the tick positions and tick labels of this axis. You can access the + \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count + (\ref QCPAxisTicker::setTickCount). + + You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see + the documentation there. A new axis ticker can be set with \ref setTicker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see setTicker +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) + + This signal is emitted when the range of this axis has changed. You can connect it to the \ref + setRange slot of another axis to communicate the new range to the other axis, in order for it to + be synchronized. + + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. + This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper + range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following + slot would limit the x axis to ranges between 0 and 10: + \code + customPlot->xAxis->setRange(newRange.bounded(0, 10)) + \endcode +*/ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) + \overload + + Additionally to the new range, this signal also provides the previous range held by the axis as + \a oldRange. +*/ + +/*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the scale type changes, by calls to \ref setScaleType +*/ + +/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) + + This signal is emitted when the selection state of this axis has changed, either by user interaction + or by a direct call to \ref setSelectedParts. +*/ + +/*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); + + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs an Axis instance of Type \a type for the axis rect \a parent. + + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create + them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, + create them manually and then inject them also via \ref QCPAxisRect::addAxis. +*/ +QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : + QCPLayerable(parent->parentPlot(), QString(), parent), + // axis base: + mAxisType(type), + mAxisRect(parent), + mPadding(5), + mOrientation(orientation(type)), + mSelectableParts(spAxis | spTickLabels | spAxisLabel), + mSelectedParts(spNone), + mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedBasePen(QPen(Qt::blue, 2)), + // axis label: + mLabel(), + mLabelFont(mParentPlot->font()), + mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), + mLabelColor(Qt::black), + mSelectedLabelColor(Qt::blue), + // tick labels: + mTickLabels(true), + mTickLabelFont(mParentPlot->font()), + mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), + mTickLabelColor(Qt::black), + mSelectedTickLabelColor(Qt::blue), + mNumberPrecision(6), + mNumberFormatChar('g'), + mNumberBeautifulPowers(true), + // ticks and subticks: + mTicks(true), + mSubTicks(true), + mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedTickPen(QPen(Qt::blue, 2)), + mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedSubTickPen(QPen(Qt::blue, 2)), + // scale and range: + mRange(0, 5), + mRangeReversed(false), + mScaleType(stLinear), + // internal members: + mGrid(new QCPGrid(this)), + mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())), + mTicker(new QCPAxisTicker), + mCachedMarginValid(false), + mCachedMargin(0) +{ + setParent(parent); + mGrid->setVisible(false); + setAntialiased(false); + setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again + + if (type == atTop) + { + setTickLabelPadding(3); + setLabelPadding(6); + } else if (type == atRight) + { + setTickLabelPadding(7); + setLabelPadding(12); + } else if (type == atBottom) + { + setTickLabelPadding(3); + setLabelPadding(3); + } else if (type == atLeft) + { + setTickLabelPadding(5); + setLabelPadding(10); + } +} + +QCPAxis::~QCPAxis() +{ + delete mAxisPainter; + delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLabelPadding() const +{ + return mAxisPainter->tickLabelPadding; +} + +/* No documentation as it is a property getter */ +double QCPAxis::tickLabelRotation() const +{ + return mAxisPainter->tickLabelRotation; +} + +/* No documentation as it is a property getter */ +QCPAxis::LabelSide QCPAxis::tickLabelSide() const +{ + return mAxisPainter->tickLabelSide; +} + +/* No documentation as it is a property getter */ +QString QCPAxis::numberFormat() const +{ + QString result; + result.append(mNumberFormatChar); + if (mNumberBeautifulPowers) + { + result.append(QLatin1Char('b')); + if (mAxisPainter->numberMultiplyCross) + result.append(QLatin1Char('c')); + } + return result; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthIn() const +{ + return mAxisPainter->tickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthOut() const +{ + return mAxisPainter->tickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthIn() const +{ + return mAxisPainter->subTickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthOut() const +{ + return mAxisPainter->subTickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::labelPadding() const +{ + return mAxisPainter->labelPadding; +} + +/* No documentation as it is a property getter */ +int QCPAxis::offset() const +{ + return mAxisPainter->offset; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::lowerEnding() const +{ + return mAxisPainter->lowerEnding; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::upperEnding() const +{ + return mAxisPainter->upperEnding; +} + +/*! + Sets whether the axis uses a linear scale or a logarithmic scale. + + Note that this method controls the coordinate transformation. You will likely also want to use a + logarithmic tick spacing and labeling, which can be achieved by setting an instance of \ref + QCPAxisTickerLog via \ref setTicker. See the documentation of \ref QCPAxisTickerLog about the + details of logarithmic axis tick creation. + + \ref setNumberPrecision +*/ +void QCPAxis::setScaleType(QCPAxis::ScaleType type) +{ + if (mScaleType != type) + { + mScaleType = type; + if (mScaleType == stLogarithmic) + setRange(mRange.sanitizedForLogScale()); + mCachedMarginValid = false; + emit scaleTypeChanged(mScaleType); + } +} + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis, use \ref setRangeReversed. +*/ +void QCPAxis::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + QCPRange oldRange = mRange; + if (mScaleType == stLogarithmic) + { + mRange = range.sanitizedForLogScale(); + } else + { + mRange = range.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPAxis::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPAxis::setSelectedParts(const SelectableParts &selected) +{ + if (mSelectedParts != selected) + { + mSelectedParts = selected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + \overload + + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPAxis::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + \overload + + Sets the range of the axis. + + The \a position coordinate indicates together with the \a alignment parameter, where the new + range will be positioned. \a size defines the size of the new axis range. \a alignment may be + Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, + or center of the range to be aligned with \a position. Any other values of \a alignment will + default to Qt::AlignCenter. +*/ +void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range. The upper bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + QCPRange oldRange = mRange; + mRange.lower = lower; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets the upper bound of the axis range. The lower bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + QCPRange oldRange = mRange; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. + + Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part + of the \ref setRange interface will still reference the mathematically smaller number than the \a + upper part. +*/ +void QCPAxis::setRangeReversed(bool reversed) +{ + mRangeReversed = reversed; +} + +/*! + The axis ticker is responsible for generating the tick positions and tick labels. See the + documentation of QCPAxisTicker for details on how to work with axis tickers. + + You can change the tick positioning/labeling behaviour of this axis by setting a different + QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis + ticker, access it via \ref ticker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see ticker +*/ +void QCPAxis::setTicker(QSharedPointer ticker) +{ + if (ticker) + mTicker = ticker; + else + qDebug() << Q_FUNC_INFO << "can not set 0 as axis ticker"; + // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector +} + +/*! + Sets whether tick marks are displayed. + + Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve + that, see \ref setTickLabels. + + \see setSubTicks +*/ +void QCPAxis::setTicks(bool show) +{ + if (mTicks != show) + { + mTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. +*/ +void QCPAxis::setTickLabels(bool show) +{ + if (mTickLabels != show) + { + mTickLabels = show; + mCachedMarginValid = false; + if (!mTickLabels) + mTickVectorLabels.clear(); + } +} + +/*! + Sets the distance between the axis base line (including any outward ticks) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPAxis::setTickLabelPadding(int padding) +{ + if (mAxisPainter->tickLabelPadding != padding) + { + mAxisPainter->tickLabelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the font of the tick labels. + + \see setTickLabels, setTickLabelColor +*/ +void QCPAxis::setTickLabelFont(const QFont &font) +{ + if (font != mTickLabelFont) + { + mTickLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the tick labels. + + \see setTickLabels, setTickLabelFont +*/ +void QCPAxis::setTickLabelColor(const QColor &color) +{ + mTickLabelColor = color; +} + +/*! + Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, + the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values + from -90 to 90 degrees. + + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For + other angles, the label is drawn with an offset such that it seems to point toward or away from + the tick mark. +*/ +void QCPAxis::setTickLabelRotation(double degrees) +{ + if (!qFuzzyIsNull(degrees-mAxisPainter->tickLabelRotation)) + { + mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0); + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. + + The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels + to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels + appear on the inside are additionally clipped to the axis rect. +*/ +void QCPAxis::setTickLabelSide(LabelSide side) +{ + mAxisPainter->tickLabelSide = side; + mCachedMarginValid = false; +} + +/*! + Sets the number format for the numbers in tick labels. This \a formatCode is an extended version + of the format code used e.g. by QString::number() and QLocale::toString(). For reference about + that, see the "Argument Formats" section in the detailed description of the QString class. + + \a formatCode is a string of one, two or three characters. The first character is identical to + the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed + format, 'g'/'G' scientific or fixed, whichever is shorter. + + The second and third characters are optional and specific to QCustomPlot:\n + If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. + "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPAxis::setNumberFormat(const QString &formatCode) +{ + if (formatCode.isEmpty()) + { + qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; + return; + } + mCachedMarginValid = false; + + // interpret first char as number format char: + QString allowedFormatChars(QLatin1String("eEfgG")); + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) + { + mNumberBeautifulPowers = true; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + return; + } + if (formatCode.length() < 3) + { + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == QLatin1Char('c')) + { + mAxisPainter->numberMultiplyCross = true; + } else if (formatCode.at(2) == QLatin1Char('d')) + { + mAxisPainter->numberMultiplyCross = false; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + return; + } +} + +/*! + Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) + for details. The effect of precisions are most notably for number Formats starting with 'e', see + \ref setNumberFormat +*/ +void QCPAxis::setNumberPrecision(int precision) +{ + if (mNumberPrecision != precision) + { + mNumberPrecision = precision; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels and axis label will increase their distance to the axis accordingly, so + they won't collide with the ticks. + + \see setSubTickLength, setTickLengthIn, setTickLengthOut +*/ +void QCPAxis::setTickLength(int inside, int outside) +{ + setTickLengthIn(inside); + setTickLengthOut(outside); +} + +/*! + Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach + inside the plot. + + \see setTickLengthOut, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthIn(int inside) +{ + if (mAxisPainter->tickLengthIn != inside) + { + mAxisPainter->tickLengthIn = inside; + } +} + +/*! + Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach + outside the plot. If \a outside is greater than zero, the tick labels and axis label will + increase their distance to the axis accordingly, so they won't collide with the ticks. + + \see setTickLengthIn, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthOut(int outside) +{ + if (mAxisPainter->tickLengthOut != outside) + { + mAxisPainter->tickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets whether sub tick marks are displayed. + + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) + + \see setTicks +*/ +void QCPAxis::setSubTicks(bool show) +{ + if (mSubTicks != show) + { + mSubTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside + the plot and \a outside is the length they will reach outside the plot. If \a outside is greater + than zero, the tick labels and axis label will increase their distance to the axis accordingly, + so they won't collide with the ticks. + + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut +*/ +void QCPAxis::setSubTickLength(int inside, int outside) +{ + setSubTickLengthIn(inside); + setSubTickLengthOut(outside); +} + +/*! + Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside + the plot. + + \see setSubTickLengthOut, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthIn(int inside) +{ + if (mAxisPainter->subTickLengthIn != inside) + { + mAxisPainter->subTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach + outside the plot. If \a outside is greater than zero, the tick labels will increase their + distance to the axis accordingly, so they won't collide with the ticks. + + \see setSubTickLengthIn, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthOut(int outside) +{ + if (mAxisPainter->subTickLengthOut != outside) + { + mAxisPainter->subTickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPAxis::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, tick marks will be drawn with. + + \see setTickLength, setBasePen +*/ +void QCPAxis::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPAxis::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPAxis::setLabelFont(const QFont &font) +{ + if (mLabelFont != font) + { + mLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPAxis::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the text of the axis label that will be shown below/above or next to the axis, depending on + its orientation. To disable axis labels, pass an empty string as \a str. +*/ +void QCPAxis::setLabel(const QString &str) +{ + if (mLabel != str) + { + mLabel = str; + mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the tick labels and the axis label. + + \see setTickLabelPadding, setPadding +*/ +void QCPAxis::setLabelPadding(int padding) +{ + if (mAxisPainter->labelPadding != padding) + { + mAxisPainter->labelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the padding of the axis. + + When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, + that is left blank. + + The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. + + \see setLabelPadding, setTickLabelPadding +*/ +void QCPAxis::setPadding(int padding) +{ + if (mPadding != padding) + { + mPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the offset the axis has to its axis rect side. + + If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, + only the offset of the inner most axis has meaning (even if it is set to be invisible). The + offset of the other, outer axes is controlled automatically, to place them at appropriate + positions. +*/ +void QCPAxis::setOffset(int offset) +{ + mAxisPainter->offset = offset; +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelFont(const QFont &font) +{ + if (font != mSelectedTickLabelFont) + { + mSelectedTickLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts + } +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelColor(const QColor &color) +{ + if (color != mSelectedTickLabelColor) + { + mSelectedTickLabelColor = color; + } +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! + Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setUpperEnding +*/ +void QCPAxis::setLowerEnding(const QCPLineEnding &ending) +{ + mAxisPainter->lowerEnding = ending; +} + +/*! + Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the right ending, for vertical axes the top ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setLowerEnding +*/ +void QCPAxis::setUpperEnding(const QCPLineEnding &ending) +{ + mAxisPainter->upperEnding = ending; +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPAxis::moveRange(double diff) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + mRange.lower += diff; + mRange.upper += diff; + } else // mScaleType == stLogarithmic + { + mRange.lower *= diff; + mRange.upper *= diff; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis by \a factor around the center of the current axis range. For + example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis + range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around + the center will have moved symmetrically closer). + + If you wish to scale around a different coordinate than the current axis range center, use the + overload \ref scaleRange(double factor, double center). +*/ +void QCPAxis::scaleRange(double factor) +{ + scaleRange(factor, range().center()); +} + +/*! \overload + + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). + + \see scaleRange(double factor) +*/ +void QCPAxis::scaleRange(double factor, double center) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + } else // mScaleType == stLogarithmic + { + if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range + { + QCPRange newRange; + newRange.lower = qPow(mRange.lower/center, factor)*center; + newRange.upper = qPow(mRange.upper/center, factor)*center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLogScale(); + } else + qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will + be done around the center of the current axis range. + + For example, if \a ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs + plotted with those axes will appear in a 1:1 aspect ratio, independent of the aspect ratio the + axis rect has. + + This is an operation that changes the range of this axis once, it doesn't fix the scale ratio + indefinitely. Note that calling this function in the constructor of the QCustomPlot's parent + won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent + will follow. +*/ +void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) +{ + int otherPixelSize, ownPixelSize; + + if (otherAxis->orientation() == Qt::Horizontal) + otherPixelSize = otherAxis->axisRect()->width(); + else + otherPixelSize = otherAxis->axisRect()->height(); + + if (orientation() == Qt::Horizontal) + ownPixelSize = axisRect()->width(); + else + ownPixelSize = axisRect()->height(); + + double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/(double)otherPixelSize; + setRange(range().center(), newRangeSize, Qt::AlignCenter); +} + +/*! + Changes the axis range such that all plottables associated with this axis are fully visible in + that dimension. + + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPAxis::rescale(bool onlyVisiblePlottables) +{ + QList p = plottables(); + QCPRange newRange; + bool haveRange = false; + for (int i=0; irealVisibility() && onlyVisiblePlottables) + continue; + QCPRange plottableRange; + bool currentFoundRange; + QCP::SignDomain signDomain = QCP::sdBoth; + if (mScaleType == stLogarithmic) + signDomain = (mRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + if (p.at(i)->keyAxis() == this) + plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain); + else + plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain); + if (currentFoundRange) + { + if (!haveRange) + newRange = plottableRange; + else + newRange.expand(plottableRange); + haveRange = true; + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mScaleType == stLinear) + { + newRange.lower = center-mRange.size()/2.0; + newRange.upper = center+mRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mRange.upper/mRange.lower); + newRange.upper = center*qSqrt(mRange.upper/mRange.lower); + } + } + setRange(newRange); + } +} + +/*! + Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. +*/ +double QCPAxis::pixelToCoord(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.lower; + else + return -(value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/(double)mAxisRect->width())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/(double)mAxisRect->width())*mRange.upper; + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.lower; + else + return -(mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/(double)mAxisRect->height())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->bottom())/(double)mAxisRect->height())*mRange.upper; + } + } +} + +/*! + Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. +*/ +double QCPAxis::coordToPixel(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mRange.lower)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + else + return (mRange.upper-value)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + } else // mScaleType == stLogarithmic + { + if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->right()+200 : mAxisRect->left()-200; + else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->left()-200 : mAxisRect->right()+200; + else + { + if (!mRangeReversed) + return qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + else + return qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + } + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return mAxisRect->bottom()-(value-mRange.lower)/mRange.size()*mAxisRect->height(); + else + return mAxisRect->bottom()-(mRange.upper-value)/mRange.size()*mAxisRect->height(); + } else // mScaleType == stLogarithmic + { + if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->top()-200 : mAxisRect->bottom()+200; + else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->bottom()+200 : mAxisRect->top()-200; + else + { + if (!mRangeReversed) + return mAxisRect->bottom()-qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + else + return mAxisRect->bottom()-qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + } + } + } +} + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions +*/ +QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const +{ + if (!mVisible) + return spNone; + + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) + return spAxis; + else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) + return spTickLabels; + else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) + return spAxisLabel; + else + return spNone; +} + +/* inherits documentation from base class */ +double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + SelectablePart part = getPartAt(pos); + if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) + return -1; + + if (details) + details->setValue(part); + return mParentPlot->selectionTolerance()*0.99; +} + +/*! + Returns a list of all the plottables that have this axis as key or value axis. + + If you are only interested in plottables of type QCPGraph, see \ref graphs. + + \see graphs, items +*/ +QList QCPAxis::plottables() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis() == this ||mParentPlot->mPlottables.at(i)->valueAxis() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that have this axis as key or value axis. + + \see plottables, items +*/ +QList QCPAxis::graphs() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis() == this || mParentPlot->mGraphs.at(i)->valueAxis() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis. An item is considered + associated with an axis if at least one of its positions uses the axis as key or value axis. + + \see plottables, graphs +*/ +QList QCPAxis::items() const +{ + QList result; + if (!mParentPlot) return result; + + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdkeyAxis() == this || positions.at(posId)->valueAxis() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + Transforms a margin side to the logically corresponding axis type. (QCP::msLeft to + QCPAxis::atLeft, QCP::msRight to QCPAxis::atRight, etc.) +*/ +QCPAxis::AxisType QCPAxis::marginSideToAxisType(QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return atLeft; + case QCP::msRight: return atRight; + case QCP::msTop: return atTop; + case QCP::msBottom: return atBottom; + default: break; + } + qDebug() << Q_FUNC_INFO << "Invalid margin side passed:" << (int)side; + return atLeft; +} + +/*! + Returns the axis type that describes the opposite axis of an axis with the specified \a type. +*/ +QCPAxis::AxisType QCPAxis::opposite(QCPAxis::AxisType type) +{ + switch (type) + { + case atLeft: return atRight; break; + case atRight: return atLeft; break; + case atBottom: return atTop; break; + case atTop: return atBottom; break; + default: qDebug() << Q_FUNC_INFO << "invalid axis type"; return atLeft; break; + } +} + +/* inherits documentation from base class */ +void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + SelectablePart part = details.value(); + if (mSelectableParts.testFlag(part)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^part : part); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAxis::deselectEvent(bool *selectionStateChanged) +{ + SelectableParts selBefore = mSelectedParts; + setSelectedParts(mSelectedParts & ~mSelectableParts); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis + (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref + QCPAxisRect::setRangeDragAxes) + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. +*/ +void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag) || + !mAxisRect->rangeDrag().testFlag(orientation()) || + !mAxisRect->rangeDragAxes(orientation()).contains(this)) + { + event->ignore(); + return; + } + + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + mDragStartRange = mRange; + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (mDragging) + { + const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y(); + const double currentPixel = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y(); + if (mScaleType == QCPAxis::stLinear) + { + const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel); + setRange(mDragStartRange.lower+diff, mDragStartRange.upper+diff); + } else if (mScaleType == QCPAxis::stLogarithmic) + { + const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); + setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); + } + + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user zoom individual axes + exclusively, by performing the wheel event on top of the axis. + + For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis + (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref + QCPAxisRect::setRangeZoomAxes) + + \seebaseclassmethod + + \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the + axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. +*/ +void QCPAxis::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom) || + !mAxisRect->rangeZoom().testFlag(orientation()) || + !mAxisRect->rangeZoomAxes(orientation()).contains(this)) + { + event->ignore(); + return; + } + + const double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps); + scaleRange(factor, pixelToCoord(orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y())); + mParentPlot->replot(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing axis lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/*! \internal + + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. + + \seebaseclassmethod +*/ +void QCPAxis::draw(QCPPainter *painter) +{ + QVector subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + subTickPositions.reserve(mSubTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->basePen = getBasePen(); + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->labelColor = getLabelColor(); + mAxisPainter->label = mLabel; + mAxisPainter->substituteExponent = mNumberBeautifulPowers; + mAxisPainter->tickPen = getTickPen(); + mAxisPainter->subTickPen = getSubTickPen(); + mAxisPainter->tickLabelFont = getTickLabelFont(); + mAxisPainter->tickLabelColor = getTickLabelColor(); + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->abbreviateDecimalPowers = mScaleType == stLogarithmic; + mAxisPainter->reversedEndings = mRangeReversed; + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + mAxisPainter->subTickPositions = subTickPositions; + mAxisPainter->draw(painter); +} + +/*! \internal + + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling + QCPAxisTicker::generate on the currently installed ticker. + + If a change in the label text/count is detected, the cached axis margin is invalidated to make + sure the next margin calculation recalculates the label sizes and returns an up-to-date value. +*/ +void QCPAxis::setupTickVectors() +{ + if (!mParentPlot) return; + if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; + + QVector oldLabels = mTickVectorLabels; + mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); + mCachedMarginValid &= mTickVectorLabels == oldLabels; // if labels have changed, margin might have changed, too +} + +/*! \internal + + Returns the pen that is used to draw the axis base line. Depending on the selection state, this + is either mSelectedBasePen or mBasePen. +*/ +QPen QCPAxis::getBasePen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; +} + +/*! \internal + + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this + is either mSelectedTickPen or mTickPen. +*/ +QPen QCPAxis::getTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; +} + +/*! \internal + + Returns the pen that is used to draw the subticks. Depending on the selection state, this + is either mSelectedSubTickPen or mSubTickPen. +*/ +QPen QCPAxis::getSubTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; +} + +/*! \internal + + Returns the font that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelFont or mTickLabelFont. +*/ +QFont QCPAxis::getTickLabelFont() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; +} + +/*! \internal + + Returns the font that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelFont or mLabelFont. +*/ +QFont QCPAxis::getLabelFont() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; +} + +/*! \internal + + Returns the color that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelColor or mTickLabelColor. +*/ +QColor QCPAxis::getTickLabelColor() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; +} + +/*! \internal + + Returns the color that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelColor or mLabelColor. +*/ +QColor QCPAxis::getLabelColor() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; +} + +/*! \internal + + Returns the appropriate outward margin for this axis. It is needed if \ref + QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref + atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom + margin and so forth. For the calculation, this function goes through similar steps as \ref draw, + so changing one function likely requires the modification of the other one as well. + + The margin consists of the outward tick length, tick label padding, tick label size, label + padding, label size, and padding. + + The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. + unchanged are very fast. +*/ +int QCPAxis::calculateMargin() +{ + if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis + return 0; + + if (mCachedMarginValid) + return mCachedMargin; + + // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels + int margin = 0; + + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->label = mLabel; + mAxisPainter->tickLabelFont = mTickLabelFont; + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + margin += mAxisPainter->size(); + margin += mPadding; + + mCachedMargin = margin; + mCachedMarginValid = true; + return margin; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAxis::selectionCategory() const +{ + return QCP::iSelectAxes; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisPainterPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisPainterPrivate + + \internal + \brief (Private) + + This is a private class and not part of the public QCustomPlot interface. + + It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and + axis label. It also buffers the labels to reduce replot times. The parameters are configured by + directly accessing the public member variables. +*/ + +/*! + Constructs a QCPAxisPainterPrivate instance. Make sure to not create a new instance on every + redraw, to utilize the caching mechanisms. +*/ +QCPAxisPainterPrivate::QCPAxisPainterPrivate(QCustomPlot *parentPlot) : + type(QCPAxis::atLeft), + basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + lowerEnding(QCPLineEnding::esNone), + upperEnding(QCPLineEnding::esNone), + labelPadding(0), + tickLabelPadding(0), + tickLabelRotation(0), + tickLabelSide(QCPAxis::lsOutside), + substituteExponent(true), + numberMultiplyCross(false), + tickLengthIn(5), + tickLengthOut(0), + subTickLengthIn(2), + subTickLengthOut(0), + tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + offset(0), + abbreviateDecimalPowers(false), + reversedEndings(false), + mParentPlot(parentPlot), + mLabelCache(16) // cache at most 16 (tick) labels +{ +} + +QCPAxisPainterPrivate::~QCPAxisPainterPrivate() +{ +} + +/*! \internal + + Draws the axis with the specified \a painter. + + The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set + here, too. +*/ +void QCPAxisPainterPrivate::draw(QCPPainter *painter) +{ + QByteArray newHash = generateLabelParameterHash(); + if (newHash != mLabelParameterHash) + { + mLabelCache.clear(); + mLabelParameterHash = newHash; + } + + QPoint origin; + switch (type) + { + case QCPAxis::atLeft: origin = axisRect.bottomLeft() +QPoint(-offset, 0); break; + case QCPAxis::atRight: origin = axisRect.bottomRight()+QPoint(+offset, 0); break; + case QCPAxis::atTop: origin = axisRect.topLeft() +QPoint(0, -offset); break; + case QCPAxis::atBottom: origin = axisRect.bottomLeft() +QPoint(0, +offset); break; + } + + double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) + switch (type) + { + case QCPAxis::atTop: yCor = -1; break; + case QCPAxis::atRight: xCor = 1; break; + default: break; + } + int margin = 0; + // draw baseline: + QLineF baseLine; + painter->setPen(basePen); + if (QCPAxis::orientation(type) == Qt::Horizontal) + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(axisRect.width()+xCor, yCor)); + else + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -axisRect.height()+yCor)); + if (reversedEndings) + baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later + painter->drawLine(baseLine); + + // draw ticks: + if (!tickPositions.isEmpty()) + { + painter->setPen(tickPen); + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis) + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(tickPositions.at(i)+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPositions.at(i)+xCor, origin.y()+tickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPositions.at(i)+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPositions.at(i)+yCor)); + } + } + + // draw subticks: + if (!subTickPositions.isEmpty()) + { + painter->setPen(subTickPen); + // direction of ticks ("inward" is right for left axis and left for right axis) + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(subTickPositions.at(i)+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPositions.at(i)+xCor, origin.y()+subTickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPositions.at(i)+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPositions.at(i)+yCor)); + } + } + margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // draw axis base endings: + bool antialiasingBackup = painter->antialiasing(); + painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't + painter->setBrush(QBrush(basePen.color())); + QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); + if (lowerEnding.style() != QCPLineEnding::esNone) + lowerEnding.draw(painter, QCPVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector); + if (upperEnding.style() != QCPLineEnding::esNone) + upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); + painter->setAntialiasing(antialiasingBackup); + + // tick labels: + QRect oldClipRect; + if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect + { + oldClipRect = painter->clipRegion().boundingRect(); + painter->setClipRect(axisRect); + } + QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label + if (!tickLabels.isEmpty()) + { + if (tickLabelSide == QCPAxis::lsOutside) + margin += tickLabelPadding; + painter->setFont(tickLabelFont); + painter->setPen(QPen(tickLabelColor)); + const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size()); + int distanceToAxis = margin; + if (tickLabelSide == QCPAxis::lsInside) + distanceToAxis = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + for (int i=0; isetClipRect(oldClipRect); + + // axis label: + QRect labelBounds; + if (!label.isEmpty()) + { + margin += labelPadding; + painter->setFont(labelFont); + painter->setPen(QPen(labelColor)); + labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, label); + if (type == QCPAxis::atLeft) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); + painter->rotate(-90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atRight) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-axisRect.height()); + painter->rotate(90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atTop) + painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + else if (type == QCPAxis::atBottom) + painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + } + + // set selection boxes: + int selectionTolerance = 0; + if (mParentPlot) + selectionTolerance = mParentPlot->selectionTolerance(); + else + qDebug() << Q_FUNC_INFO << "mParentPlot is null"; + int selAxisOutSize = qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance); + int selAxisInSize = selectionTolerance; + int selTickLabelSize; + int selTickLabelOffset; + if (tickLabelSide == QCPAxis::lsOutside) + { + selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = qMax(tickLengthOut, subTickLengthOut)+tickLabelPadding; + } else + { + selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + } + int selLabelSize = labelBounds.height(); + int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding; + if (type == QCPAxis::atLeft) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atRight) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atTop) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset); + } else if (type == QCPAxis::atBottom) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset); + } + mAxisSelectionBox = mAxisSelectionBox.normalized(); + mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized(); + mLabelSelectionBox = mLabelSelectionBox.normalized(); + // draw hitboxes for debug purposes: + //painter->setBrush(Qt::NoBrush); + //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); +} + +/*! \internal + + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone + direction) needed to fit the axis. +*/ +int QCPAxisPainterPrivate::size() const +{ + int result = 0; + + // get length of tick marks pointing outwards: + if (!tickPositions.isEmpty()) + result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // calculate size of tick labels: + if (tickLabelSide == QCPAxis::lsOutside) + { + QSize tickLabelsSize(0, 0); + if (!tickLabels.isEmpty()) + { + for (int i=0; ibufferDevicePixelRatio())); + result.append(QByteArray::number(tickLabelRotation)); + result.append(QByteArray::number((int)tickLabelSide)); + result.append(QByteArray::number((int)substituteExponent)); + result.append(QByteArray::number((int)numberMultiplyCross)); + result.append(tickLabelColor.name().toLatin1()+QByteArray::number(tickLabelColor.alpha(), 16)); + result.append(tickLabelFont.toString().toLatin1()); + return result; +} + +/*! \internal + + Draws a single tick label with the provided \a painter, utilizing the internal label cache to + significantly speed up drawing of labels that were drawn in previous calls. The tick label is + always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in + pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence + for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), + at which the label should be drawn. + + In order to later draw the axis label in a place that doesn't overlap with the tick labels, the + largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref + drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a + tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently + holds. + + The label is drawn with the font and pen that are currently set on the \a painter. To draw + superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref + getTickLabelData). +*/ +void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize) +{ + // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! + if (text.isEmpty()) return; + QSize finalSize; + QPointF labelAnchor; + switch (type) + { + case QCPAxis::atLeft: labelAnchor = QPointF(axisRect.left()-distanceToAxis-offset, position); break; + case QCPAxis::atRight: labelAnchor = QPointF(axisRect.right()+distanceToAxis+offset, position); break; + case QCPAxis::atTop: labelAnchor = QPointF(position, axisRect.top()-distanceToAxis-offset); break; + case QCPAxis::atBottom: labelAnchor = QPointF(position, axisRect.bottom()+distanceToAxis+offset); break; + } + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled + { + CachedLabel *cachedLabel = mLabelCache.take(text); // attempt to get label from cache + if (!cachedLabel) // no cached label existed, create it + { + cachedLabel = new CachedLabel; + TickLabelData labelData = getTickLabelData(painter->font(), text); + cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft(); + if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) + { + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio()); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF()); +# else + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); +# endif +#endif + } else + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); + cachedLabel->pixmap.fill(Qt::transparent); + QCPPainter cachePainter(&cachedLabel->pixmap); + cachePainter.setPen(painter->pen()); + drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData); + } + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); + else + labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + painter->drawPixmap(labelAnchor+cachedLabel->offset, cachedLabel->pixmap); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } + mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created + } else // label caching disabled, draw text directly on surface: + { + TickLabelData labelData = getTickLabelData(painter->font(), text); + QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData); + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); + else + labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData); + finalSize = labelData.rotatedTotalBounds.size(); + } + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a + y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to + directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when + QCP::phCacheLabels plotting hint is not set. +*/ +void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const +{ + // backup painter settings that we're about to change: + QTransform oldTransform = painter->transform(); + QFont oldFont = painter->font(); + + // transform painter to position/rotation: + painter->translate(x, y); + if (!qFuzzyIsNull(tickLabelRotation)) + painter->rotate(tickLabelRotation); + + // draw text: + if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); + if (!labelData.suffixPart.isEmpty()) + painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart); + painter->setFont(labelData.expFont); + painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); + } else + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); + } + + // reset painter settings to what it was before: + painter->setTransform(oldTransform); + painter->setFont(oldFont); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further + processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and + exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. +*/ +QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const +{ + TickLabelData result; + + // determine whether beautiful decimal powers should be used + bool useBeautifulPowers = false; + int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart + int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart + if (substituteExponent) + { + ePos = text.indexOf(QLatin1Char('e')); + if (ePos > 0 && text.at(ePos-1).isDigit()) + { + eLast = ePos; + while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) + ++eLast; + if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power + useBeautifulPowers = true; + } + } + + // calculate text bounding rects and do string preparation for beautiful decimal powers: + result.baseFont = font; + if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line + result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + if (useBeautifulPowers) + { + // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: + result.basePart = text.left(ePos); + result.suffixPart = text.mid(eLast+1); // also drawn normally but after exponent + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (abbreviateDecimalPowers && result.basePart == QLatin1String("1")) + result.basePart = QLatin1String("10"); + else + result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10"); + result.expPart = text.mid(ePos+1, eLast-ePos); + // clip "+" and leading zeros off expPart: + while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' + result.expPart.remove(1, 1); + if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) + result.expPart.remove(0, 1); + // prepare smaller font for exponent: + result.expFont = font; + if (result.expFont.pointSize() > 0) + result.expFont.setPointSize(result.expFont.pointSize()*0.75); + else + result.expFont.setPixelSize(result.expFont.pixelSize()*0.75); + // calculate bounding rects of base part(s), exponent part and total one: + result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); + result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); + if (!result.suffixPart.isEmpty()) + result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart); + result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA + } else // useBeautifulPowers == false + { + result.basePart = text; + result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); + } + result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler + + // calculate possibly different bounding rect after rotation: + result.rotatedTotalBounds = result.totalBounds; + if (!qFuzzyIsNull(tickLabelRotation)) + { + QTransform transform; + transform.rotate(tickLabelRotation); + result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); + } + + return result; +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Calculates the offset at which the top left corner of the specified tick label shall be drawn. + The offset is relative to a point right next to the tick the label belongs to. + + This function is thus responsible for e.g. centering tick labels under ticks and positioning them + appropriately when they are rotated. +*/ +QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &labelData) const +{ + /* + calculate label offset from base point at tick (non-trivial, for best visual appearance): short + explanation for bottom axis: The anchor, i.e. the point in the label that is placed + horizontally under the corresponding tick is always on the label side that is closer to the + axis (e.g. the left side of the text when we're rotating clockwise). On that side, the height + is halved and the resulting point is defined the anchor. This way, a 90 degree rotated text + will be centered under the tick (i.e. displaced horizontally by half its height). At the same + time, a 45 degree rotated text will "point toward" its tick, as is typical for rotated tick + labels. + */ + bool doRotation = !qFuzzyIsNull(tickLabelRotation); + bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes. + double radians = tickLabelRotation/180.0*M_PI; + int x=0, y=0; + if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height(); + y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = -labelData.totalBounds.width(); + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = 0; + y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = 0; + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0; + y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height(); + } else + { + x = -qSin(-radians)*labelData.totalBounds.height()/2.0; + y = -qCos(-radians)*labelData.totalBounds.height(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = -labelData.totalBounds.height(); + } + } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height()/2.0; + y = 0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height()/2.0; + y = +qSin(-radians)*labelData.totalBounds.width(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = 0; + } + } + + return QPointF(x, y); +} + +/*! \internal + + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label + to be drawn, depending on number format etc. Since only the largest tick label is wanted for the + margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a + smaller width/height. +*/ +void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const +{ + // note: this function must return the same tick label sizes as the placeTickLabel function. + QSize finalSize; + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label + { + const CachedLabel *cachedLabel = mLabelCache.object(text); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } else // label caching disabled or no label with this text cached: + { + TickLabelData labelData = getTickLabelData(font, text); + finalSize = labelData.rotatedTotalBounds.size(); + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} +/* end of 'src/axis/axis.cpp' */ + + +/* including file 'src/scatterstyle.cpp', size 17450 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPScatterStyle +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPScatterStyle + \brief Represents the visual appearance of scatter points + + This class holds information about shape, color and size of scatter points. In plottables like + QCPGraph it is used to store how scatter points shall be drawn. For example, \ref + QCPGraph::setScatterStyle takes a QCPScatterStyle instance. + + A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a + fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can + be controlled with \ref setSize. + + \section QCPScatterStyle-defining Specifying a scatter style + + You can set all these configurations either by calling the respective functions on an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 + + Or you can use one of the various constructors that take different parameter combinations, making + it easy to specify a scatter style in a single call, like so: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 + + \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable + + There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref + QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref + isPenDefined will return false. It leads to scatter points that inherit the pen from the + plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line + color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes + it very convenient to set up typical scatter settings: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation + + Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works + because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly + into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) + constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref + ScatterShape, where actually a QCPScatterStyle is expected. + + \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps + + QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. + + For custom shapes, you can provide a QPainterPath with the desired shape to the \ref + setCustomPath function or call the constructor that takes a painter path. The scatter shape will + automatically be set to \ref ssCustom. + + For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the + constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. + Note that \ref setSize does not influence the appearance of the pixmap. +*/ + +/* start documentation of inline functions */ + +/*! \fn bool QCPScatterStyle::isNone() const + + Returns whether the scatter shape is \ref ssNone. + + \see setShape +*/ + +/*! \fn bool QCPScatterStyle::isPenDefined() const + + Returns whether a pen has been defined for this scatter style. + + The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those + are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen + is undefined, the pen of the respective plottable will be used for drawing scatters. + + If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call + \ref undefinePen. + + \see setPen +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle() : + mSize(6), + mShape(ssNone), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or + brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) : + mSize(size), + mShape(shape), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + and size to \a size. No brush is defined, i.e. the scatter point will not be filled. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(Qt::NoBrush), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + the brush color to \a fill (with a solid pattern), and size to \a size. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(QBrush(fill)), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the + brush to \a brush, and size to \a size. + + \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen + and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n + QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n + doesn't necessarily lead C++ to use this constructor in some cases, but might mistake + Qt::NoPen for a QColor and use the + \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) + constructor instead (which will lead to an unexpected look of the scatter points). To prevent + this, be more explicit with the parameter types. For example, use QBrush(Qt::blue) + instead of just Qt::blue, to clearly point out to the compiler that this constructor is + wanted. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(shape), + mPen(pen), + mBrush(brush), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape + is set to \ref ssPixmap. +*/ +QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : + mSize(5), + mShape(ssPixmap), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPixmap(pixmap), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The + scatter shape is set to \ref ssCustom. + + The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly + different meaning than for built-in scatter points: The custom path will be drawn scaled by a + factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its + original size by default. To for example double the size of the path, set \a size to 12. +*/ +QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(ssCustom), + mPen(pen), + mBrush(brush), + mCustomPath(customPath), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Copies the specified \a properties from the \a other scatter style to this scatter style. +*/ +void QCPScatterStyle::setFromOther(const QCPScatterStyle &other, ScatterProperties properties) +{ + if (properties.testFlag(spPen)) + { + setPen(other.pen()); + if (!other.isPenDefined()) + undefinePen(); + } + if (properties.testFlag(spBrush)) + setBrush(other.brush()); + if (properties.testFlag(spSize)) + setSize(other.size()); + if (properties.testFlag(spShape)) + { + setShape(other.shape()); + if (other.shape() == ssPixmap) + setPixmap(other.pixmap()); + else if (other.shape() == ssCustom) + setCustomPath(other.customPath()); + } +} + +/*! + Sets the size (pixel diameter) of the drawn scatter points to \a size. + + \see setShape +*/ +void QCPScatterStyle::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the shape to \a shape. + + Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref + ssPixmap and \ref ssCustom, respectively. + + \see setSize +*/ +void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) +{ + mShape = shape; +} + +/*! + Sets the pen that will be used to draw scatter points to \a pen. + + If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after + a call to this function, even if \a pen is Qt::NoPen. If you have defined a pen + previously by calling this function and now wish to undefine the pen, call \ref undefinePen. + + \see setBrush +*/ +void QCPScatterStyle::setPen(const QPen &pen) +{ + mPenDefined = true; + mPen = pen; +} + +/*! + Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter + shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. + + \see setPen +*/ +void QCPScatterStyle::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the pixmap that will be drawn as scatter point to \a pixmap. + + Note that \ref setSize does not influence the appearance of the pixmap. + + The scatter shape is automatically set to \ref ssPixmap. +*/ +void QCPScatterStyle::setPixmap(const QPixmap &pixmap) +{ + setShape(ssPixmap); + mPixmap = pixmap; +} + +/*! + Sets the custom shape that will be drawn as scatter point to \a customPath. + + The scatter shape is automatically set to \ref ssCustom. +*/ +void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) +{ + setShape(ssCustom); + mCustomPath = customPath; +} + +/*! + Sets this scatter style to have an undefined pen (see \ref isPenDefined for what an undefined pen + implies). + + A call to \ref setPen will define a pen. +*/ +void QCPScatterStyle::undefinePen() +{ + mPenDefined = false; +} + +/*! + Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an + undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. + + This function is used by plottables (or any class that wants to draw scatters) just before a + number of scatters with this style shall be drawn with the \a painter. + + \see drawShape +*/ +void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const +{ + painter->setPen(mPenDefined ? mPen : defaultPen); + painter->setBrush(mBrush); +} + +/*! + Draws the scatter shape with \a painter at position \a pos. + + This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be + called before scatter points are drawn with \ref drawShape. + + \see applyTo +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, const QPointF &pos) const +{ + drawShape(painter, pos.x(), pos.y()); +} + +/*! \overload + Draws the scatter shape with \a painter at position \a x and \a y. +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const +{ + double w = mSize/2.0; + switch (mShape) + { + case ssNone: break; + case ssDot: + { + painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y)); + break; + } + case ssCross: + { + painter->drawLine(QLineF(x-w, y-w, x+w, y+w)); + painter->drawLine(QLineF(x-w, y+w, x+w, y-w)); + break; + } + case ssPlus: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCircle: + { + painter->drawEllipse(QPointF(x , y), w, w); + break; + } + case ssDisc: + { + QBrush b = painter->brush(); + painter->setBrush(painter->pen().color()); + painter->drawEllipse(QPointF(x , y), w, w); + painter->setBrush(b); + break; + } + case ssSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssDiamond: + { + QPointF lineArray[4] = {QPointF(x-w, y), + QPointF( x, y-w), + QPointF(x+w, y), + QPointF( x, y+w)}; + painter->drawPolygon(lineArray, 4); + break; + } + case ssStar: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); + break; + } + case ssTriangle: + { + QPointF lineArray[3] = {QPointF(x-w, y+0.755*w), + QPointF(x+w, y+0.755*w), + QPointF( x, y-0.977*w)}; + painter->drawPolygon(lineArray, 3); + break; + } + case ssTriangleInverted: + { + QPointF lineArray[3] = {QPointF(x-w, y-0.755*w), + QPointF(x+w, y-0.755*w), + QPointF( x, y+0.977*w)}; + painter->drawPolygon(lineArray, 3); + break; + } + case ssCrossSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); + painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); + break; + } + case ssPlusSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + painter->drawLine(QLineF(x-w, y, x+w*0.95, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCrossCircle: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707)); + break; + } + case ssPlusCircle: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssPeace: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x, y-w, x, y+w)); + painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); + break; + } + case ssPixmap: + { + const double widthHalf = mPixmap.width()*0.5; + const double heightHalf = mPixmap.height()*0.5; +#if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) + const QRectF clipRect = painter->clipRegion().boundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#else + const QRectF clipRect = painter->clipBoundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#endif + if (clipRect.contains(x, y)) + painter->drawPixmap(x-widthHalf, y-heightHalf, mPixmap); + break; + } + case ssCustom: + { + QTransform oldTransform = painter->transform(); + painter->translate(x, y); + painter->scale(mSize/6.0, mSize/6.0); + painter->drawPath(mCustomPath); + painter->setTransform(oldTransform); + break; + } + } +} +/* end of 'src/scatterstyle.cpp' */ + +//amalgamation: add datacontainer.cpp + +/* including file 'src/plottable.cpp', size 38845 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecorator +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecorator + \brief Controls how a plottable's data selection is drawn + + Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref + QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data. + + The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the + scatter style (\ref setScatterStyle) if the plottable draws scatters. Since a \ref + QCPScatterStyle is itself composed of different properties such as color shape and size, the + decorator allows specifying exactly which of those properties shall be used for the selected data + point, via \ref setUsedScatterProperties. + + A \ref QCPSelectionDecorator subclass instance can be passed to a plottable via \ref + QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance + of selected segments. + + Use \ref copyFrom to easily transfer the settings of one decorator to another one. This is + especially useful since plottables take ownership of the passed selection decorator, and thus the + same decorator instance can not be passed to multiple plottables. + + Selection decorators can also themselves perform drawing operations by reimplementing \ref + drawDecoration, which is called by the plottable's draw method. The base class \ref + QCPSelectionDecorator does not make use of this however. For example, \ref + QCPSelectionDecoratorBracket draws brackets around selected data segments. +*/ + +/*! + Creates a new QCPSelectionDecorator instance with default values +*/ +QCPSelectionDecorator::QCPSelectionDecorator() : + mPen(QColor(80, 80, 255), 2.5), + mBrush(Qt::NoBrush), + mScatterStyle(), + mUsedScatterProperties(QCPScatterStyle::spNone), + mPlottable(0) +{ +} + +QCPSelectionDecorator::~QCPSelectionDecorator() +{ +} + +/*! + Sets the pen that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the scatter style that will be used by the parent plottable to draw scatters in selected + data segments. + + \a usedProperties specifies which parts of the passed \a scatterStyle will be used by the + plottable. The used properties can also be changed via \ref setUsedScatterProperties. +*/ +void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties) +{ + mScatterStyle = scatterStyle; + setUsedScatterProperties(usedProperties); +} + +/*! + Use this method to define which properties of the scatter style (set via \ref setScatterStyle) + will be used for selected data segments. All properties of the scatter style that are not + specified in \a properties will remain as specified in the plottable's original scatter style. + + \see QCPScatterStyle::ScatterProperty +*/ +void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties) +{ + mUsedScatterProperties = properties; +} + +/*! + Sets the pen of \a painter to the pen of this selection decorator. + + \see applyBrush, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyPen(QCPPainter *painter) const +{ + painter->setPen(mPen); +} + +/*! + Sets the brush of \a painter to the brush of this selection decorator. + + \see applyPen, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const +{ + painter->setBrush(mBrush); +} + +/*! + Returns the scatter style that the parent plottable shall use for selected scatter points. The + plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending + on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this + selecion decorator's scatter style (\ref setScatterStyle), and \a unselectedStyle. + + \see applyPen, applyBrush, setScatterStyle +*/ +QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const +{ + QCPScatterStyle result(unselectedStyle); + result.setFromOther(mScatterStyle, mUsedScatterProperties); + + // if style shall inherit pen from plottable (has no own pen defined), give it the selected + // plottable pen explicitly, so it doesn't use the unselected plottable pen when used in the + // plottable: + if (!result.isPenDefined()) + result.setPen(mPen); + + return result; +} + +/*! + Copies all properties (e.g. color, fill, scatter style) of the \a other selection decorator to + this selection decorator. +*/ +void QCPSelectionDecorator::copyFrom(const QCPSelectionDecorator *other) +{ + setPen(other->pen()); + setBrush(other->brush()); + setScatterStyle(other->scatterStyle(), other->usedScatterProperties()); +} + +/*! + This method is called by all plottables' draw methods to allow custom selection decorations to be + drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data + selection for which the decoration shall be drawn. + + The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so + this method does nothing. +*/ +void QCPSelectionDecorator::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + Q_UNUSED(painter) + Q_UNUSED(selection) +} + +/*! \internal + + This method is called as soon as a selection decorator is associated with a plottable, by a call + to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access + data points via the \ref QCPAbstractPlottable::interface1D interface). + + If the selection decorator was already added to a different plottable before, this method aborts + the registration and returns false. +*/ +bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottable) + { + mPlottable = plottable; + return true; + } else + { + qDebug() << Q_FUNC_INFO << "This selection decorator is already registered with plottable:" << reinterpret_cast(mPlottable); + return false; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable + \brief The abstract base class for all data representing objects in a plot. + + It defines a very basic interface like name, pen, brush, visibility etc. Since this class is + abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to + create new ways of displaying data (see "Creating own plottables" below). Plottables that display + one-dimensional data (i.e. data points have a single key dimension and one or multiple values at + each key) are based off of the template subclass \ref QCPAbstractPlottable1D, see details + there. + + All further specifics are in the subclasses, for example: + \li A normal graph with possibly a line and/or scatter points \ref QCPGraph + (typically created with \ref QCustomPlot::addGraph) + \li A parametric curve: \ref QCPCurve + \li A bar chart: \ref QCPBars + \li A statistical box plot: \ref QCPStatisticalBox + \li A color encoded two-dimensional map: \ref QCPColorMap + \li An OHLC/Candlestick chart: \ref QCPFinancial + + \section plottables-subclassing Creating own plottables + + Subclassing directly from QCPAbstractPlottable is only recommended if you wish to display + two-dimensional data like \ref QCPColorMap, i.e. two logical key dimensions and one (or more) + data dimensions. If you want to display data with only one logical key dimension, you should + rather derive from \ref QCPAbstractPlottable1D. + + If subclassing QCPAbstractPlottable directly, these are the pure virtual functions you must + implement: + \li \ref selectTest + \li \ref draw + \li \ref drawLegendIcon + \li \ref getKeyRange + \li \ref getValueRange + + See the documentation of those functions for what they need to do. + + For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot + coordinates to pixel coordinates. This function is quite convenient, because it takes the + orientation of the key and value axes into account for you (x and y are swapped when the key axis + is vertical and the value axis horizontal). If you are worried about performance (i.e. you need + to translate many points in a loop like QCPGraph), you can directly use \ref + QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis + yourself. + + Here are some important members you inherit from QCPAbstractPlottable: + + + + + + + + + + + + + + + + + + + + + + + + + + +
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable + (e.g QCPGraph uses this pen for its graph lines and scatters)
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable + (e.g. QCPGraph uses this brush to control filling under the graph)
QPointer<\ref QCPAxis> \b mKeyAxis, \b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates + to pixels in either the key or value dimension. Make sure to check whether the pointer is null before using it. If one of + the axes is null, don't draw the plottable.
\ref QCPSelectionDecorator \b mSelectionDecoratorThe currently set selection decorator which specifies how selected data of the plottable shall be drawn and decorated. + When drawing your data, you must consult this decorator for the appropriate pen/brush before drawing unselected/selected data segments. + Finally, you should call its \ref QCPSelectionDecorator::drawDecoration method at the end of your \ref draw implementation.
\ref QCP::SelectionType \b mSelectableIn which composition, if at all, this plottable's data may be selected. Enforcing this setting on the data selection is done + by QCPAbstractPlottable automatically.
\ref QCPDataSelection \b mSelectionHolds the current selection state of the plottable's data, i.e. the selected data ranges (\ref QCPDataRange).
+*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionDecorator *QCPAbstractPlottable::selectionDecorator() const + + Provides access to the selection decorator of this plottable. The selection decorator controls + how selected data ranges are drawn (e.g. their pen color and fill), see \ref + QCPSelectionDecorator for details. + + If you wish to use an own \ref QCPSelectionDecorator subclass, pass an instance of it to \ref + setSelectionDecorator. +*/ + +/*! \fn bool QCPAbstractPlottable::selected() const + + Returns true if there are any data points of the plottable currently selected. Use \ref selection + to retrieve the current \ref QCPDataSelection. +*/ + +/*! \fn QCPDataSelection QCPAbstractPlottable::selection() const + + Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on + this plottable. + + \see selected, setSelection, setSelectable +*/ + +/*! \fn virtual QCPPlottableInterface1D *QCPAbstractPlottable::interface1D() + + If this plottable is a one-dimensional plottable, i.e. it implements the \ref + QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case + of a \ref QCPColorMap) returns zero. + + You can use this method to gain read access to data coordinates while holding a pointer to the + abstract base class only. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of pure virtual functions */ + +/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 + \internal + + called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation + of this plottable inside \a rect, next to the plottable name. + + The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't + appear outside the legend icon border. +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0 + + Returns the coordinate range that all data in this plottable span in the key axis dimension. For + logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref + QCP::sdPositive in order to restrict the returned range to that sign domain. E.g. when only + negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and all positive points + will be ignored for range calculation. For no restriction, just set \a inSignDomain to \ref + QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could + be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data). + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getValueRange +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0 + + Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span + in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref + QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign + domain. E.g. when only negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and + all positive points will be ignored for range calculation. For no restriction, just set \a + inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates + whether a range could be found or not. If this is false, you shouldn't use the returned range + (e.g. no points in data). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getKeyRange +*/ + +/* end of documentation of pure virtual functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether + there are any points selected or not. + + \see selectionChanged(const QCPDataSelection &selection) +*/ + +/*! \fn void QCPAbstractPlottable::selectionChanged(const QCPDataSelection &selection) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selection holds the + currently selected data ranges. + + \see selectionChanged(bool selected) +*/ + +/*! \fn void QCPAbstractPlottable::selectableChanged(QCP::SelectionType selectable); + + This signal is emitted when the selectability of this plottable has changed. + + \see setSelectable +*/ + +/* end of documentation of signals */ + +/*! + Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as + its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance + and have perpendicular orientations. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, + it can't be directly instantiated. + + You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. +*/ +QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()), + mName(), + mDesc(), + mAntialiasedFill(true), + mAntialiasedScatters(true), + mPen(Qt::black), + mBrush(Qt::NoBrush), + mKeyAxis(keyAxis), + mValueAxis(valueAxis), + mSelectable(QCP::stWhole), + mSelectionDecorator(0) +{ + if (keyAxis->parentPlot() != valueAxis->parentPlot()) + qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; + if (keyAxis->orientation() == valueAxis->orientation()) + qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; + + mParentPlot->registerPlottable(this); + setSelectionDecorator(new QCPSelectionDecorator); +} + +QCPAbstractPlottable::~QCPAbstractPlottable() +{ + if (mSelectionDecorator) + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} + +/*! + The name is the textual representation of this plottable as it is displayed in the legend + (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. +*/ +void QCPAbstractPlottable::setName(const QString &name) +{ + mName = name; +} + +void QCPAbstractPlottable::setDesc(const QString &desc) +{ + mDesc = desc; +} + +/*! + Sets whether fills of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedFill(bool enabled) +{ + mAntialiasedFill = enabled; +} + +/*! + Sets whether the scatter symbols of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) +{ + mAntialiasedScatters = enabled; +} + +/*! + The pen is used to draw basic lines that make up the plottable representation in the + plot. + + For example, the \ref QCPGraph subclass draws its graph lines with this pen. + + \see setBrush +*/ +void QCPAbstractPlottable::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + The brush is used to draw basic fills of the plottable representation in the + plot. The Fill can be a color, gradient or texture, see the usage of QBrush. + + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when + it's not set to Qt::NoBrush. + + \see setPen +*/ +void QCPAbstractPlottable::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal + to the plottable's value axis. This function performs no checks to make sure this is the case. + The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the + y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setValueAxis +*/ +void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) +{ + mKeyAxis = axis; +} + +/*! + The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is + orthogonal to the plottable's key axis. This function performs no checks to make sure this is the + case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and + the y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setKeyAxis +*/ +void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) +{ + mValueAxis = axis; +} + + +/*! + Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently + (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref + selectionDecorator). + + The entire selection mechanism for plottables is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when + you wish to change the selection state programmatically. + + Using \ref setSelectable you can further specify for each plottable whether and to which + granularity it is selectable. If \a selection is not compatible with the current \ref + QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted + accordingly (see \ref QCPDataSelection::enforceType). + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractPlottable::setSelection(QCPDataSelection selection) +{ + selection.enforceType(mSelectable); + if (mSelection != selection) + { + mSelection = selection; + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } +} + +/*! + Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to + customize the visual representation of selected data ranges further than by using the default + QCPSelectionDecorator. + + The plottable takes ownership of the \a decorator. + + The currently set decorator can be accessed via \ref selectionDecorator. +*/ +void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorator) +{ + if (decorator) + { + if (decorator->registerWithPlottable(this)) + { + if (mSelectionDecorator) // delete old decorator if necessary + delete mSelectionDecorator; + mSelectionDecorator = decorator; + } + } else if (mSelectionDecorator) // just clear decorator + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} + +/*! + Sets whether and to which granularity this plottable can be selected. + + A selection can happen by clicking on the QCustomPlot surface (When \ref + QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect + (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by + calling \ref setSelection. + + \see setSelection, QCP::SelectionType +*/ +void QCPAbstractPlottable::setSelectable(QCP::SelectionType selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + QCPDataSelection oldSelection = mSelection; + mSelection.enforceType(mSelectable); + emit selectableChanged(mSelectable); + if (mSelection != oldSelection) + { + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } + } +} + + +/*! + Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. + + \see pixelsToCoords, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + x = keyAxis->coordToPixel(key); + y = valueAxis->coordToPixel(value); + } else + { + y = keyAxis->coordToPixel(key); + x = valueAxis->coordToPixel(value); + } +} + +/*! \overload + + Transforms the given \a key and \a value to pixel coordinates and returns them in a QPointF. +*/ +const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); + else + return QPointF(valueAxis->coordToPixel(value), keyAxis->coordToPixel(key)); +} + +/*! + Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. + + \see coordsToPixels, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + key = keyAxis->pixelToCoord(x); + value = valueAxis->pixelToCoord(y); + } else + { + key = keyAxis->pixelToCoord(y); + value = valueAxis->pixelToCoord(x); + } +} + +/*! \overload + + Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. +*/ +void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const +{ + pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); +} + +/*! + Rescales the key and value axes associated with this plottable to contain all displayed data, so + the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make + sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. + Instead it will stay in the current sign domain and ignore all parts of the plottable that lie + outside of that domain. + + \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show + multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has + \a onlyEnlarge set to false (the default), and all subsequent set to true. + + \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale +*/ +void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const +{ + rescaleKeyAxis(onlyEnlarge); + rescaleValueAxis(onlyEnlarge); +} + +/*! + Rescales the key axis of the plottable so the whole plottable is visible. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (keyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (keyAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getKeyRange(foundRange, signDomain); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(keyAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (keyAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-keyAxis->range().size()/2.0; + newRange.upper = center+keyAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(keyAxis->range().upper/keyAxis->range().lower); + newRange.upper = center*qSqrt(keyAxis->range().upper/keyAxis->range().lower); + } + } + keyAxis->setRange(newRange); + } +} + +/*! + Rescales the value axis of the plottable so the whole plottable is visible. If \a inKeyRange is + set to true, only the data points which are in the currently visible key axis range are + considered. + + Returns true if the axis was actually scaled. This might not be the case if this plottable has an + invalid range, e.g. because it has no data points. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (valueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(valueAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-valueAxis->range().size()/2.0; + newRange.upper = center+valueAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); + newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); + } + } + valueAxis->setRange(newRange); + } +} + +/*! \overload + + Adds this plottable to the specified \a legend. + + Creates a QCPPlottableLegendItem which is inserted into the legend. Returns true on success, i.e. + when the legend exists and a legend item associated with this plottable isn't already in the + legend. + + If the plottable needs a more specialized representation in the legend, you can create a + corresponding subclass of \ref QCPPlottableLegendItem and add it to the legend manually instead + of calling this method. + + \see removeFromLegend, QCPLegend::addItem +*/ +bool QCPAbstractPlottable::addToLegend(QCPLegend *legend) +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + if (legend->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; + return false; + } + + if (!legend->hasItemWithPlottable(this)) + { + legend->addItem(new QCPPlottableLegendItem(legend, this)); + return true; + } else + return false; +} + +/*! \overload + + Adds this plottable to the legend of the parent QCustomPlot (\ref QCustomPlot::legend). + + \see removeFromLegend +*/ +bool QCPAbstractPlottable::addToLegend() +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return addToLegend(mParentPlot->legend); +} + +/*! \overload + + Removes the plottable from the specifed \a legend. This means the \ref QCPPlottableLegendItem + that is associated with this plottable is removed. + + Returns true on success, i.e. if the legend exists and a legend item associated with this + plottable was found and removed. + + \see addToLegend, QCPLegend::removeItem +*/ +bool QCPAbstractPlottable::removeFromLegend(QCPLegend *legend) const +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + + if (QCPPlottableLegendItem *lip = legend->itemWithPlottable(this)) + return legend->removeItem(lip); + else + return false; +} + +/*! \overload + + Removes the plottable from the legend of the parent QCustomPlot. + + \see addToLegend +*/ +bool QCPAbstractPlottable::removeFromLegend() const +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return removeFromLegend(mParentPlot->legend); +} + +/* inherits documentation from base class */ +QRect QCPAbstractPlottable::clipRect() const +{ + if (mKeyAxis && mValueAxis) + return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect(); + else + return QRect(); +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractPlottable::selectionCategory() const +{ + return QCP::iSelectPlottables; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable fills. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable scatter points. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint +*/ +void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + + if (mSelectable != QCP::stNone) + { + QCPDataSelection newSelection = details.value(); + QCPDataSelection selectionBefore = mSelection; + if (additive) + { + if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit + { + if (selected()) + setSelection(QCPDataSelection()); + else + setSelection(newSelection); + } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments + { + if (mSelection.contains(newSelection)) // if entire newSelection is already selected, toggle selection + setSelection(mSelection-newSelection); + else + setSelection(mSelection+newSelection); + } + } else + setSelection(newSelection); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable != QCP::stNone) + { + QCPDataSelection selectionBefore = mSelection; + setSelection(QCPDataSelection()); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} +/* end of 'src/plottable.cpp' */ + + +/* including file 'src/item.cpp', size 49269 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemAnchor +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemAnchor + \brief An anchor of an item to which positions can be attached to. + + An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't + control anything on its item, but provides a way to tie other items via their positions to the + anchor. + + For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. + Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can + attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by + calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the + QCPItemRect. This way the start of the line will now always follow the respective anchor location + on the rect item. + + Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an + anchor to other positions. + + To learn how to provide anchors in your own item subclasses, see the subclassing section of the + QCPAbstractItem documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() + + Returns 0 if this instance is merely a QCPItemAnchor, and a valid pointer of type QCPItemPosition* if + it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). + + This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids + dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with + gcc compiler). +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId) : + mName(name), + mParentPlot(parentPlot), + mParentItem(parentItem), + mAnchorId(anchorId) +{ +} + +QCPItemAnchor::~QCPItemAnchor() +{ + // unregister as parent at children: + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } +} + +/*! + Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. + + The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the + parent item, QCPItemAnchor is just an intermediary. +*/ +QPointF QCPItemAnchor::pixelPosition() const +{ + if (mParentItem) + { + if (mAnchorId > -1) + { + return mParentItem->anchorPixelPosition(mAnchorId); + } else + { + qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; + return QPointF(); + } + } else + { + qDebug() << Q_FUNC_INFO << "no parent item set"; + return QPointF(); + } +} + +/*! \internal + + Adds \a pos to the childX list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.contains(pos)) + mChildrenX.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childX list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + +/*! \internal + + Adds \a pos to the childY list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.contains(pos)) + mChildrenY.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childY list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPosition +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPosition + \brief Manages the position of an item. + + Every item has at least one public QCPItemPosition member pointer which provides ways to position the + item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: + \a topLeft and \a bottomRight. + + QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type + defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel + coordinates, as plot coordinates of certain axes, etc. For more advanced plots it is also + possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref + setTypeY). This way an item could be positioned at a fixed pixel distance from the top in the Y + direction, while following a plot coordinate in the X direction. + + A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie + multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords) + are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0) + means directly ontop of the parent anchor. For example, You could attach the \a start position of + a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting point of the line + always be centered under the text label, no matter where the text is moved to. For more advanced + plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see + \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X + direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B + in Y. + + Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent + anchor for other positions. + + To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPosition. This + works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref + setPixelPosition transforms the coordinates appropriately, to make the position appear at the specified + pixel values. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const + + Returns the current position type. + + If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the + type of the X coordinate. In that case rather use \a typeX() and \a typeY(). + + \see setType +*/ + +/*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const + + Returns the current parent anchor. + + If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), + this method returns the parent anchor of the Y coordinate. In that case rather use \a + parentAnchorX() and \a parentAnchorY(). + + \see setParentAnchor +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name) : + QCPItemAnchor(parentPlot, parentItem, name), + mPositionTypeX(ptAbsolute), + mPositionTypeY(ptAbsolute), + mKey(0), + mValue(0), + mParentAnchorX(0), + mParentAnchorY(0) +{ +} + +QCPItemPosition::~QCPItemPosition() +{ + // unregister as parent at children: + // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then + // the setParentAnchor(0) call the correct QCPItemPosition::pixelPosition function instead of QCPItemAnchor::pixelPosition + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } + // unregister as child in parent: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPItemPosition::axisRect() const +{ + return mAxisRect.data(); +} + +/*! + Sets the type of the position. The type defines how the coordinates passed to \ref setCoords + should be handled and how the QCPItemPosition should behave in the plot. + + The possible values for \a type can be separated in two main categories: + + \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords + and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. + By default, the QCustomPlot's x- and yAxis are used. + + \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This + corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref + ptAxisRectRatio. They differ only in the way the absolute position is described, see the + documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify + the axis rect with \ref setAxisRect. By default this is set to the main axis rect. + + Note that the position type \ref ptPlotCoords is only available (and sensible) when the position + has no parent anchor (\ref setParentAnchor). + + If the type is changed, the apparent pixel position on the plot is preserved. This means + the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. + + This method sets the type for both X and Y directions. It is also possible to set different types + for X and Y, see \ref setTypeX, \ref setTypeY. +*/ +void QCPItemPosition::setType(QCPItemPosition::PositionType type) +{ + setTypeX(type); + setTypeY(type); +} + +/*! + This method sets the position type of the X coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeY +*/ +void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) +{ + if (mPositionTypeX != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeX == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeX = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + This method sets the position type of the Y coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeX +*/ +void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) +{ + if (mPositionTypeY != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeY == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeY = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now + follow any position changes of the anchor. The local coordinate system of positions with a parent + anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence + the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) + + if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved + during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position + will be exactly on top of the parent anchor. + + To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to 0. + + If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is + set to \ref ptAbsolute, to keep the position in a valid state. + + This method sets the parent anchor for both X and Y directions. It is also possible to set + different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. +*/ +bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + bool successX = setParentAnchorX(parentAnchor, keepPixelPosition); + bool successY = setParentAnchorY(parentAnchor, keepPixelPosition); + return successX && successY; +} + +/*! + This method sets the parent anchor of the X coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorY +*/ +bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorX(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) + setTypeX(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildX(this); + mParentAnchorX = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(0, coords().y()); + return true; +} + +/*! + This method sets the parent anchor of the Y coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorX +*/ +bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorY(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) + setTypeY(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildY(this); + mParentAnchorY = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(coords().x(), 0); + return true; +} + +/*! + Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type + (\ref setType, \ref setTypeX, \ref setTypeY). + + For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position + on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the + QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the + plot coordinate system defined by the axes set by \ref setAxes. By default those are the + QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available + coordinate types and their meaning. + + If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a + value must also be provided in the different coordinate systems. Here, the X type refers to \a + key, and the Y type refers to \a value. + + \see setPixelPosition +*/ +void QCPItemPosition::setCoords(double key, double value) +{ + mKey = key; + mValue = value; +} + +/*! \overload + + Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the + meaning of \a value of the \ref setCoords(double key, double value) method. +*/ +void QCPItemPosition::setCoords(const QPointF &pos) +{ + setCoords(pos.x(), pos.y()); +} + +/*! + Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It + includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). + + \see setPixelPosition +*/ +QPointF QCPItemPosition::pixelPosition() const +{ + QPointF result; + + // determine X: + switch (mPositionTypeX) + { + case ptAbsolute: + { + result.rx() = mKey; + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + result.rx() = mKey*mParentPlot->viewport().width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mParentPlot->viewport().left(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.rx() = mKey*mAxisRect.data()->width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mAxisRect.data()->left(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + // determine Y: + switch (mPositionTypeY) + { + case ptAbsolute: + { + result.ry() = mValue; + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + result.ry() = mValue*mParentPlot->viewport().height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mParentPlot->viewport().top(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.ry() = mValue*mAxisRect.data()->height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mAxisRect.data()->top(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + result.ry() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + result.ry() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + return result; +} + +/*! + When \ref setType is \ref ptPlotCoords, this function may be used to specify the axes the + coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and + yAxis of the QCustomPlot. +*/ +void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + mKeyAxis = keyAxis; + mValueAxis = valueAxis; +} + +/*! + When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the + coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of + the QCustomPlot. +*/ +void QCPItemPosition::setAxisRect(QCPAxisRect *axisRect) +{ + mAxisRect = axisRect; +} + +/*! + Sets the apparent pixel position. This works no matter what type (\ref setType) this + QCPItemPosition is or what parent-child situation it is in, as coordinates are transformed + appropriately, to make the position finally appear at the specified pixel values. + + Only if the type is \ref ptAbsolute and no parent anchor is set, this function's effect is + identical to that of \ref setCoords. + + \see pixelPosition, setCoords +*/ +void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) +{ + double x = pixelPosition.x(); + double y = pixelPosition.y(); + + switch (mPositionTypeX) + { + case ptAbsolute: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mParentPlot->viewport().left(); + x /= (double)mParentPlot->viewport().width(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mAxisRect.data()->left(); + x /= (double)mAxisRect.data()->width(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + x = mKeyAxis.data()->pixelToCoord(x); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + y = mValueAxis.data()->pixelToCoord(x); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + switch (mPositionTypeY) + { + case ptAbsolute: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mParentPlot->viewport().top(); + y /= (double)mParentPlot->viewport().height(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mAxisRect.data()->top(); + y /= (double)mAxisRect.data()->height(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + x = mKeyAxis.data()->pixelToCoord(y); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + y = mValueAxis.data()->pixelToCoord(y); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + setCoords(x, y); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractItem + \brief The abstract base class for all items in a plot. + + In QCustomPlot, items are supplemental graphical elements that are neither plottables + (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus + plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each + specific item has at least one QCPItemPosition member which controls the positioning. Some items + are defined by more than one coordinate and thus have two or more QCPItemPosition members (For + example, QCPItemRect has \a topLeft and \a bottomRight). + + This abstract base class defines a very basic interface like visibility and clipping. Since this + class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass + yourself to create new items. + + The built-in items are: + + + + + + + + + + +
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
+ + \section items-clipping Clipping + + Items are by default clipped to the main axis rect (they are only visible inside the axis rect). + To make an item visible outside that axis rect, disable clipping via \ref setClipToAxisRect + "setClipToAxisRect(false)". + + On the other hand if you want the item to be clipped to a different axis rect, specify it via + \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and + in principle is independent of the coordinate axes the item might be tied to via its position + members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping + also contains the axes used for the item positions. + + \section items-using Using items + + First you instantiate the item you want to use and add it to the plot: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 + by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just + set the plot coordinates where the line should start/end: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-2 + If we don't want the line to be positioned in plot coordinates but a different coordinate system, + e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-3 + Then we can set the coordinates, this time in pixels: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 + and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 + + For more advanced plots, it is even possible to set different types and parent anchors per X/Y + coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref + QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. + + \section items-subclassing Creating own items + + To create an own item, you implement a subclass of QCPAbstractItem. These are the pure + virtual functions, you must implement: + \li \ref selectTest + \li \ref draw + + See the documentation of those functions for what they need to do. + + \subsection items-positioning Allowing the item to be positioned + + As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall + have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add + a public member of type QCPItemPosition like so: + + \code QCPItemPosition * const myPosition;\endcode + + the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition + instance it points to, can be modified, of course). + The initialization of this pointer is made easy with the \ref createPosition function. Just assign + the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition + takes a string which is the name of the position, typically this is identical to the variable name. + For example, the constructor of QCPItemExample could look like this: + + \code + QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + myPosition(createPosition("myPosition")) + { + // other constructor code + } + \endcode + + \subsection items-drawing The draw function + + To give your item a visual representation, reimplement the \ref draw function and use the passed + QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the + position member(s) via \ref QCPItemPosition::pixelPosition. + + To optimize performance you should calculate a bounding rect first (don't forget to take the pen + width into account), check whether it intersects the \ref clipRect, and only draw the item at all + if this is the case. + + \subsection items-selection The selectTest function + + Your implementation of the \ref selectTest function may use the helpers \ref + QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the + selection test becomes significantly simpler for most items. See the documentation of \ref + selectTest for what the function parameters mean and what the function should return. + + \subsection anchors Providing anchors + + Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public + member, e.g. + + \code QCPItemAnchor * const bottom;\endcode + + and create it in the constructor with the \ref createAnchor function, assigning it a name and an + anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). + Since anchors can be placed anywhere, relative to the item's position(s), your item needs to + provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int + anchorId) function. + + In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel + position when anything attached to the anchor needs to know the coordinates. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QList QCPAbstractItem::positions() const + + Returns all positions of the item in a list. + + \see anchors, position +*/ + +/*! \fn QList QCPAbstractItem::anchors() const + + Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always + also an anchor, the list will also contain the positions of this item. + + \see positions, anchor +*/ + +/* end of documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 + \internal + + Draws this item with the provided \a painter. + + The cliprect of the provided painter is set to the rect returned by \ref clipRect before this + function is called. The clipRect depends on the clipping settings defined by \ref + setClipToAxisRect and \ref setClipAxisRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPAbstractItem::selectionChanged(bool selected) + This signal is emitted when the selection state of this item has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end documentation of signals */ + +/*! + Base class constructor which initializes base class members. +*/ +QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), + mClipToAxisRect(false), + mSelectable(true), + mSelected(false) +{ + parentPlot->registerItem(this); + + QList rects = parentPlot->axisRects(); + if (rects.size() > 0) + { + setClipToAxisRect(true); + setClipAxisRect(rects.first()); + } +} + +QCPAbstractItem::~QCPAbstractItem() +{ + // don't delete mPositions because every position is also an anchor and thus in mAnchors + qDeleteAll(mAnchors); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPAbstractItem::clipAxisRect() const +{ + return mClipAxisRect.data(); +} + +/*! + Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the + entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. + + \see setClipAxisRect +*/ +void QCPAbstractItem::setClipToAxisRect(bool clip) +{ + mClipToAxisRect = clip; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref + setClipToAxisRect is set to true. + + \see setClipToAxisRect +*/ +void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) +{ + mClipAxisRect = rect; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected. + + \see QCustomPlot::setInteractions, setSelected +*/ +void QCPAbstractItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this item is selected or not. When selected, it might use a different visual + appearance (e.g. pen and brush), this depends on the specific item though. + + The entire selection mechanism for items is handled automatically when \ref + QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this + function when you wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by + that name, returns 0. + + This function provides an alternative way to access item positions. Normally, you access + positions direcly by their member pointers (which typically have the same variable name as \a + name). + + \see positions, anchor +*/ +QCPItemPosition *QCPAbstractItem::position(const QString &name) const +{ + for (int i=0; iname() == name) + return mPositions.at(i); + } + qDebug() << Q_FUNC_INFO << "position with name not found:" << name; + return 0; +} + +/*! + Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by + that name, returns 0. + + This function provides an alternative way to access item anchors. Normally, you access + anchors direcly by their member pointers (which typically have the same variable name as \a + name). + + \see anchors, position +*/ +QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const +{ + for (int i=0; iname() == name) + return mAnchors.at(i); + } + qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; + return 0; +} + +/*! + Returns whether this item has an anchor with the specified \a name. + + Note that you can check for positions with this function, too. This is because every position is + also an anchor (QCPItemPosition inherits from QCPItemAnchor). + + \see anchor, position +*/ +bool QCPAbstractItem::hasAnchor(const QString &name) const +{ + for (int i=0; iname() == name) + return true; + } + return false; +} + +/*! \internal + + Returns the rect the visual representation of this item is clipped to. This depends on the + current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. + + If the item is not clipped to an axis rect, QCustomPlot's viewport rect is returned. + + \see draw +*/ +QRect QCPAbstractItem::clipRect() const +{ + if (mClipToAxisRect && mClipAxisRect) + return mClipAxisRect.data()->rect(); + else + return mParentPlot->viewport(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing item lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); +} + +/*! \internal + + A convenience function which returns the selectTest value for a specified \a rect and a specified + click position \a pos. \a filledRect defines whether a click inside the rect should also be + considered a hit or whether only the rect border is sensitive to hits. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + For example, if your item consists of four rects, call this function four times, once for each + rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four + returned values. +*/ +double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const +{ + double result = -1; + + // distance to border: + QList lines; + lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) + << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); + double minDistSqr = std::numeric_limits::max(); + for (int i=0; i mParentPlot->selectionTolerance()*0.99) + { + if (rect.contains(pos)) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/*! \internal + + Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in + item subclasses if they want to provide anchors (QCPItemAnchor). + + For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor + ids and returns the respective pixel points of the specified anchor. + + \see createAnchor +*/ +QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const +{ + qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the position + member (This is needed to provide the name-based \ref position access to positions). + + Don't delete positions created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each position member. Don't create QCPItemPositions with \b new yourself, because they + won't be registered with the item properly. + + \see createAnchor +*/ +QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); + mPositions.append(newPosition); + mAnchors.append(newPosition); // every position is also an anchor + newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); + newPosition->setType(QCPItemPosition::ptPlotCoords); + if (mParentPlot->axisRect()) + newPosition->setAxisRect(mParentPlot->axisRect()); + newPosition->setCoords(0, 0); + return newPosition; +} + +/*! \internal + + Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the anchor + member (This is needed to provide the name based \ref anchor access to anchors). + + The \a anchorId must be a number identifying the created anchor. It is recommended to create an + enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor + to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns + the correct pixel coordinates for the passed anchor id. + + Don't delete anchors created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they + won't be registered with the item properly. + + \see createPosition +*/ +QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); + mAnchors.append(newAnchor); + return newAnchor; +} + +/* inherits documentation from base class */ +void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractItem::selectionCategory() const +{ + return QCP::iSelectItems; +} +/* end of 'src/item.cpp' */ + + +/* including file 'src/core.cpp', size 125037 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCustomPlot +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCustomPlot + + \brief The central class of the library. This is the QWidget which displays the plot and + interacts with the user. + + For tutorials on how to use QCustomPlot, see the website\n + http://www.qcustomplot.com/ +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionRect *QCustomPlot::selectionRect() const + + Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used + to handle and draw selection rect interactions (see \ref setSelectionRectMode). + + \see setSelectionRect +*/ + +/*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const + + Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just + one cell with the main QCPAxisRect inside. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse double click event. +*/ + +/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse press event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. +*/ + +/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse move event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. + + \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, + because the dragging starting point was saved the moment the mouse was pressed. Thus it only has + a meaning for the range drag axes that were set at that moment. If you want to change the drag + axes, consider doing this in the \ref mousePress signal instead. +*/ + +/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse release event. + + It is emitted before QCustomPlot handles any other mechanisms like object selection. So a + slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or + \ref QCPAbstractPlottable::setSelectable. +*/ + +/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse wheel event. + + It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref + QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. +*/ + +/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableDoubleClick +*/ + +/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is double clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableClick +*/ + +/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemDoubleClick +*/ + +/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is double clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemClick +*/ + +/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisDoubleClick +*/ + +/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is double clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisClick +*/ + +/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendDoubleClick +*/ + +/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is double clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendClick +*/ + +/*! \fn void QCustomPlot::selectionChangedByUser() + + This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by + clicking. It is not emitted when the selection state of an object has changed programmatically by + a direct call to setSelected()/setSelection() on an object or by calling \ref + deselectAll. + + In addition to this signal, selectable objects also provide individual signals, for example \ref + QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals + are emitted even if the selection state is changed programmatically. + + See the documentation of \ref setInteractions for details about the selection mechanism. + + \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends +*/ + +/*! \fn void QCustomPlot::beforeReplot() + + This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, afterReplot +*/ + +/*! \fn void QCustomPlot::afterReplot() + + This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, beforeReplot +*/ + +/* end of documentation of signals */ +/* start of documentation of public members */ + +/*! \var QCPAxis *QCustomPlot::xAxis + + A pointer to the primary x Axis (bottom) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis + + A pointer to the primary y Axis (left) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::xAxis2 + + A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis2 + + A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPLegend *QCustomPlot::legend + + A pointer to the default legend of the main axis rect. The legend is invisible by default. Use + QCPLegend::setVisible to change this. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple legends to the plot, use the layout system interface to + access the new legend. For example, legends can be placed inside an axis rect's \ref + QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If + the default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointer becomes 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/* end of documentation of public members */ + +/*! + Constructs a QCustomPlot and sets reasonable default values. +*/ +QCustomPlot::QCustomPlot(QWidget *parent) : + QWidget(parent), + xAxis(0), + yAxis(0), + xAxis2(0), + yAxis2(0), + legend(0), + mBufferDevicePixelRatio(1.0), // will be adapted to primary screen below + mPlotLayout(0), + mAutoAddPlottableToLegend(true), + mAntialiasedElements(QCP::aeNone), + mNotAntialiasedElements(QCP::aeNone), + mInteractions(0), + mSelectionTolerance(8), + mNoAntialiasingOnDrag(false), + mBackgroundBrush(Qt::white, Qt::SolidPattern), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mCurrentLayer(0), + mPlottingHints(QCP::phCacheLabels|QCP::phImmediateRefresh), + mMultiSelectModifier(Qt::ControlModifier), + mSelectionRectMode(QCP::srmNone), + mSelectionRect(0), + mOpenGl(false), + mSymbolPressed(false), + mMouseHasMoved(false), + mMouseEventLayerable(0), + mMouseSignalLayerable(0), + mReplotting(false), + mReplotQueued(false), + mOpenGlMultisamples(16), + mOpenGlAntialiasedElementsBackup(QCP::aeNone), + mOpenGlCacheLabelsBackup(true) +{ + setAttribute(Qt::WA_NoMousePropagation); + setAttribute(Qt::WA_OpaquePaintEvent); + setFocusPolicy(Qt::ClickFocus); + setMouseTracking(true); + QLocale currentLocale = locale(); + currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); + setLocale(currentLocale); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + setBufferDevicePixelRatio(QWidget::devicePixelRatioF()); +# else + setBufferDevicePixelRatio(QWidget::devicePixelRatio()); +# endif +#endif + + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // create initial layers: + mLayers.append(new QCPLayer(this, QLatin1String("background"))); + mLayers.append(new QCPLayer(this, QLatin1String("grid"))); + mLayers.append(new QCPLayer(this, QLatin1String("main"))); + mLayers.append(new QCPLayer(this, QLatin1String("axes"))); + mLayers.append(new QCPLayer(this, QLatin1String("legend"))); + mLayers.append(new QCPLayer(this, QLatin1String("overlay"))); + updateLayerIndices(); + setCurrentLayer(QLatin1String("main")); + layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered); + + // create initial layout, axis rect and legend: + mPlotLayout = new QCPLayoutGrid; + mPlotLayout->initializeParentPlot(this); + mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry + mPlotLayout->setLayer(QLatin1String("main")); + QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true); + mPlotLayout->addElement(0, 0, defaultAxisRect); + xAxis = defaultAxisRect->axis(QCPAxis::atBottom); + yAxis = defaultAxisRect->axis(QCPAxis::atLeft); + xAxis2 = defaultAxisRect->axis(QCPAxis::atTop); + yAxis2 = defaultAxisRect->axis(QCPAxis::atRight); + legend = new QCPLegend; + legend->setVisible(false); + defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); + defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); + + defaultAxisRect->setLayer(QLatin1String("background")); + xAxis->setLayer(QLatin1String("axes")); + yAxis->setLayer(QLatin1String("axes")); + xAxis2->setLayer(QLatin1String("axes")); + yAxis2->setLayer(QLatin1String("axes")); + xAxis->grid()->setLayer(QLatin1String("grid")); + yAxis->grid()->setLayer(QLatin1String("grid")); + xAxis2->grid()->setLayer(QLatin1String("grid")); + yAxis2->grid()->setLayer(QLatin1String("grid")); + legend->setLayer(QLatin1String("legend")); + + // create selection rect instance: + mSelectionRect = new QCPSelectionRect(this); + mSelectionRect->setLayer(QLatin1String("overlay")); + + setViewport(rect()); // needs to be called after mPlotLayout has been created + + replot(rpQueuedReplot); +} + +QCustomPlot::~QCustomPlot() +{ + clearPlottables(); + clearItems(true); + + if (mPlotLayout) + { + delete mPlotLayout; + mPlotLayout = 0; + } + + mCurrentLayer = 0; + qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed + mLayers.clear(); +} + +void QCustomPlot::setSymbolPos(const QPoint pos) +{ + mSymbolPos = QPoint(pos.x(), 0); +} + +/*! + Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is + removed from there. + + \see setNotAntialiasedElements +*/ +void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) +{ + mAntialiasedElements = antialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. + + See \ref setAntialiasedElements for details. + + \see setNotAntialiasedElement +*/ +void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) +{ + if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements &= ~antialiasedElement; + else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements |= antialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets which elements are forcibly drawn not antialiased as an \a or combination of + QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is + removed from there. + + \see setAntialiasedElements +*/ +void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) +{ + mNotAntialiasedElements = notAntialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. + + See \ref setNotAntialiasedElements for details. + + \see setAntialiasedElement +*/ +void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) +{ + if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements &= ~notAntialiasedElement; + else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements |= notAntialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the + plottable to the legend (QCustomPlot::legend). + + \see addGraph, QCPLegend::addItem +*/ +void QCustomPlot::setAutoAddPlottableToLegend(bool on) +{ + mAutoAddPlottableToLegend = on; +} + +/*! + Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction + enums. There are the following types of interactions: + + Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the + respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. + For details how to control which axes the user may drag/zoom and in what orientations, see \ref + QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, + \ref QCPAxisRect::setRangeZoomAxes. + + Plottable data selection is controlled by \ref QCP::iSelectPlottables. If \ref + QCP::iSelectPlottables is set, the user may select plottables (graphs, curves, bars,...) and + their data by clicking on them or in their vicinity (\ref setSelectionTolerance). Whether the + user can actually select a plottable and its data can further be restricted with the \ref + QCPAbstractPlottable::setSelectable method on the specific plottable. For details, see the + special page about the \ref dataselection "data selection mechanism". To retrieve a list of all + currently selected plottables, call \ref selectedPlottables. If you're only interested in + QCPGraphs, you may use the convenience function \ref selectedGraphs. + + Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user + may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find + out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of + all currently selected items, call \ref selectedItems. + + Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user + may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick + labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for + each axis. To retrieve a list of all axes that currently contain selected parts, call \ref + selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). + + Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may + select the legend itself or individual items by clicking on them. What parts exactly are + selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the + legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To + find out which child items are selected, call \ref QCPLegend::selectedItems. + + All other selectable elements The selection of all other selectable objects (e.g. + QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the + user may select those objects by clicking on them. To find out which are currently selected, you + need to check their selected state explicitly. + + If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is + emitted. Each selectable object additionally emits an individual selectionChanged signal whenever + their selection state has changed, i.e. not only by user interaction. + + To allow multiple objects to be selected by holding the selection modifier (\ref + setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. + + \note In addition to the selection mechanism presented here, QCustomPlot always emits + corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and + \ref plottableDoubleClick for example. + + \see setInteraction, setSelectionTolerance +*/ +void QCustomPlot::setInteractions(const QCP::Interactions &interactions) +{ + mInteractions = interactions; +} + +/*! + Sets the single \a interaction of this QCustomPlot to \a enabled. + + For details about the interaction system, see \ref setInteractions. + + \see setInteractions +*/ +void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) +{ + if (!enabled && mInteractions.testFlag(interaction)) + mInteractions &= ~interaction; + else if (enabled && !mInteractions.testFlag(interaction)) + mInteractions |= interaction; +} + +/*! + Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or + not. + + If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a + potential selection when the minimum distance between the click position and the graph line is + smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks + directly inside the area and ignore this selection tolerance. In other words, it only has meaning + for parts of objects that are too thin to exactly hit with a click and thus need such a + tolerance. + + \see setInteractions, QCPLayerable::selectTest +*/ +void QCustomPlot::setSelectionTolerance(int pixels) +{ + mSelectionTolerance = pixels; +} + +/*! + Sets whether antialiasing is disabled for this QCustomPlot while the user is dragging axes + ranges. If many objects, especially plottables, are drawn antialiased, this greatly improves + performance during dragging. Thus it creates a more responsive user experience. As soon as the + user stops dragging, the last replot is done with normal antialiasing, to restore high image + quality. + + \see setAntialiasedElements, setNotAntialiasedElements +*/ +void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) +{ + mNoAntialiasingOnDrag = enabled; +} + +/*! + Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. + + \see setPlottingHint +*/ +void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) +{ + mPlottingHints = hints; +} + +/*! + Sets the specified plotting \a hint to \a enabled. + + \see setPlottingHints +*/ +void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) +{ + QCP::PlottingHints newHints = mPlottingHints; + if (!enabled) + newHints &= ~hint; + else + newHints |= hint; + + if (newHints != mPlottingHints) + setPlottingHints(newHints); +} + +/*! + Sets the keyboard modifier that will be recognized as multi-select-modifier. + + If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple + objects (or data points) by clicking on them one after the other while holding down \a modifier. + + By default the multi-select-modifier is set to Qt::ControlModifier. + + \see setInteractions +*/ +void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) +{ + mMultiSelectModifier = modifier; +} + +/*! + Sets how QCustomPlot processes mouse click-and-drag interactions by the user. + + If \a mode is \ref QCP::srmNone, the mouse drag is forwarded to the underlying objects. For + example, QCPAxisRect may process a mouse drag by dragging axis ranges, see \ref + QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref + selectionRect) becomes activated and allows e.g. rect zooming and data point selection. + + If you wish to provide your user both with axis range dragging and data selection/range zooming, + use this method to switch between the modes just before the interaction is processed, e.g. in + reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether + the user is holding a certain keyboard modifier, and then decide which \a mode shall be set. + + If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the + interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes + will keep the selection rect active. Upon completion of the interaction, the behaviour is as + defined by the currently set \a mode, not the mode that was set when the interaction started. + + \see setInteractions, setSelectionRect, QCPSelectionRect +*/ +void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) +{ + if (mSelectionRect) + { + if (mode == QCP::srmNone) + mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect + + // disconnect old connections: + if (mSelectionRectMode == QCP::srmSelect) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + + // establish new ones: + if (mode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } + + mSelectionRectMode = mode; +} + +/*! + Sets the \ref QCPSelectionRect instance that QCustomPlot will use if \a mode is not \ref + QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of + the passed \a selectionRect. It can be accessed later via \ref selectionRect. + + This method is useful if you wish to replace the default QCPSelectionRect instance with an + instance of a QCPSelectionRect subclass, to introduce custom behaviour of the selection rect. + + \see setSelectionRectMode +*/ +void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) +{ + if (mSelectionRect) + delete mSelectionRect; + + mSelectionRect = selectionRect; + + if (mSelectionRect) + { + // establish connections with new selection rect: + if (mSelectionRectMode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } +} + +/*! + \warning This is still an experimental feature and its performance depends on the system that it + runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering + might cause context conflicts on some systems. + + This method allows to enable OpenGL plot rendering, for increased plotting performance of + graphically demanding plots (thick lines, translucent fills, etc.). + + If \a enabled is set to true, QCustomPlot will try to initialize OpenGL and, if successful, + continue plotting with hardware acceleration. The parameter \a multisampling controls how many + samples will be used per pixel, it essentially controls the antialiasing quality. If \a + multisampling is set too high for the current graphics hardware, the maximum allowed value will + be used. + + You can test whether switching to OpenGL rendering was successful by checking whether the + according getter \a QCustomPlot::openGl() returns true. If the OpenGL initialization fails, + rendering continues with the regular software rasterizer, and an according qDebug output is + generated. + + If switching to OpenGL was successful, this method disables label caching (\ref setPlottingHint + "setPlottingHint(QCP::phCacheLabels, false)") and turns on QCustomPlot's antialiasing override + for all elements (\ref setAntialiasedElements "setAntialiasedElements(QCP::aeAll)"), leading to a + higher quality output. The antialiasing override allows for pixel-grid aligned drawing in the + OpenGL paint device. As stated before, in OpenGL rendering the actual antialiasing of the plot is + controlled with \a multisampling. If \a enabled is set to false, the antialiasing/label caching + settings are restored to what they were before OpenGL was enabled, if they weren't altered in the + meantime. + + \note OpenGL support is only enabled if QCustomPlot is compiled with the macro \c QCUSTOMPLOT_USE_OPENGL + defined. This define must be set before including the QCustomPlot header both during compilation + of the QCustomPlot library as well as when compiling your application. It is best to just include + the line DEFINES += QCUSTOMPLOT_USE_OPENGL in the respective qmake project files. + \note If you are using a Qt version before 5.0, you must also add the module "opengl" to your \c + QT variable in the qmake project files. For Qt versions 5.0 and higher, QCustomPlot switches to a + newer OpenGL interface which is already in the "gui" module. +*/ +void QCustomPlot::setOpenGl(bool enabled, int multisampling) +{ + mOpenGlMultisamples = qMax(0, multisampling); +#ifdef QCUSTOMPLOT_USE_OPENGL + mOpenGl = enabled; + if (mOpenGl) + { + if (setupOpenGl()) + { + // backup antialiasing override and labelcaching setting so we can restore upon disabling OpenGL + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // set antialiasing override to antialias all (aligns gl pixel grid properly), and disable label caching (would use software rasterizer for pixmap caches): + setAntialiasedElements(QCP::aeAll); + setPlottingHint(QCP::phCacheLabels, false); + } else + { + qDebug() << Q_FUNC_INFO << "Failed to enable OpenGL, continuing plotting without hardware acceleration."; + mOpenGl = false; + } + } else + { + // restore antialiasing override and labelcaching to what it was before enabling OpenGL, if nobody changed it in the meantime: + if (mAntialiasedElements == QCP::aeAll) + setAntialiasedElements(mOpenGlAntialiasedElementsBackup); + if (!mPlottingHints.testFlag(QCP::phCacheLabels)) + setPlottingHint(QCP::phCacheLabels, mOpenGlCacheLabelsBackup); + freeOpenGl(); + } + // recreate all paint buffers: + mPaintBuffers.clear(); + setupPaintBuffers(); +#else + Q_UNUSED(enabled) + qDebug() << Q_FUNC_INFO << "QCustomPlot can't use OpenGL because QCUSTOMPLOT_USE_OPENGL was not defined during compilation (add 'DEFINES += QCUSTOMPLOT_USE_OPENGL' to your qmake .pro file)"; +#endif +} + +/*! + Sets the viewport of this QCustomPlot. Usually users of QCustomPlot don't need to change the + viewport manually. + + The viewport is the area in which the plot is drawn. All mechanisms, e.g. margin caluclation take + the viewport to be the outer border of the plot. The viewport normally is the rect() of the + QCustomPlot widget, i.e. a rect with top left (0, 0) and size of the QCustomPlot widget. + + Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically + an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger + and contains also the axes themselves, their tick numbers, their labels, or even additional axis + rects, color scales and other layout elements. + + This function is used to allow arbitrary size exports with \ref toPixmap, \ref savePng, \ref + savePdf, etc. by temporarily changing the viewport size. +*/ +void QCustomPlot::setViewport(const QRect &rect) +{ + mViewport = rect; + if (mPlotLayout) + mPlotLayout->setOuterRect(mViewport); +} + +/*! + Sets the device pixel ratio used by the paint buffers of this QCustomPlot instance. + + Normally, this doesn't need to be set manually, because it is initialized with the regular \a + QWidget::devicePixelRatio which is configured by Qt to fit the display device (e.g. 1 for normal + displays, 2 for High-DPI displays). + + Device pixel ratios are supported by Qt only for Qt versions since 5.4. If this method is called + when QCustomPlot is being used with older Qt versions, outputs an according qDebug message and + leaves the internal buffer device pixel ratio at 1.0. +*/ +void QCustomPlot::setBufferDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mBufferDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBufferDevicePixelRatio = ratio; + for (int i=0; isetDevicePixelRatio(mBufferDevicePixelRatio); + // Note: axis label cache has devicePixelRatio as part of cache hash, so no need to manually clear cache here +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mBufferDevicePixelRatio = 1.0; +#endif + } +} + +/*! + Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn + below all other objects in the plot. + + For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is + preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will + first be filled with that brush, before drawing the background pixmap. This can be useful for + background pixmaps with translucent areas. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! + Sets the background brush of the viewport (see \ref setViewport). + + Before drawing everything else, the background is filled with \a brush. If a background pixmap + was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport + before the background pixmap is drawn. This can be useful for background pixmaps with translucent + areas. + + Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be + useful for exporting to image formats which support transparency, e.g. \ref savePng. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the viewport, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is + set to true, control whether and how the aspect ratio of the original pixmap is preserved with + \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the viewport dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCustomPlot::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this + function to define whether and how the aspect ratio of the original pixmap is preserved. + + \see setBackground, setBackgroundScaled +*/ +void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the plottable with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + plottable, see QCustomPlot::plottable() + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + { + return mPlottables.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last plottable that was added to the plot. If there are no plottables in the plot, + returns 0. + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable() +{ + if (!mPlottables.isEmpty()) + { + return mPlottables.last(); + } else + return 0; +} + +/*! + Removes the specified plottable from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). + + Returns true on success. + + \see clearPlottables +*/ +bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); + return false; + } + + // remove plottable from legend: + plottable->removeFromLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.removeOne(graph); + // remove plottable: + delete plottable; + mPlottables.removeOne(plottable); + return true; +} + +/*! \overload + + Removes and deletes the plottable by its \a index. +*/ +bool QCustomPlot::removePlottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + return removePlottable(mPlottables[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all plottables from the plot and deletes them. Corresponding legend items are also + removed from the default legend (QCustomPlot::legend). + + Returns the number of plottables removed. + + \see removePlottable +*/ +int QCustomPlot::clearPlottables() +{ + int c = mPlottables.size(); + for (int i=c-1; i >= 0; --i) + removePlottable(mPlottables[i]); + return c; +} + +/*! + Returns the number of currently existing plottables in the plot + + \see plottable +*/ +int QCustomPlot::plottableCount() const +{ + return mPlottables.size(); +} + +/*! + Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. + + There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. + + \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedPlottables() const +{ + QList result; + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (plottable->selected()) + result.append(plottable); + } + return result; +} + +/*! + Returns the plottable at the pixel position \a pos. Plottables that only consist of single lines + (like graphs) have a tolerance band around them, see \ref setSelectionTolerance. If multiple + plottables come into consideration, the one closest to \a pos is returned. + + If \a onlySelectable is true, only plottables that are selectable + (QCPAbstractPlottable::setSelectable) are considered. + + If there is no plottable at \a pos, the return value is 0. + + \see itemAt, layoutElementAt +*/ +QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractPlottable *resultPlottable = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (onlySelectable && !plottable->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPabstractPlottable::selectable + continue; + if ((plottable->keyAxis()->axisRect()->rect() & plottable->valueAxis()->axisRect()->rect()).contains(pos.toPoint())) // only consider clicks inside the rect that is spanned by the plottable's key/value axes + { + double currentDistance = plottable->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultPlottable = plottable; + resultDistance = currentDistance; + } + } + } + + return resultPlottable; +} + +/*! + Returns whether this QCustomPlot instance contains the \a plottable. +*/ +bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const +{ + return mPlottables.contains(plottable); +} + +/*! + Returns the graph with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last created + graph, see QCustomPlot::graph() + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph(int index) const +{ + if (index >= 0 && index < mGraphs.size()) + { + return mGraphs.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, + returns 0. + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph() const +{ + if (!mGraphs.isEmpty()) + { + return mGraphs.last(); + } else + return 0; +} + +/*! + Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the + bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a + keyAxis and \a valueAxis must reside in this QCustomPlot. + + \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically + "y") for the graph. + + Returns a pointer to the newly created graph, or 0 if adding the graph failed. + + \see graph, graphCount, removeGraph, clearGraphs +*/ +QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + if (!keyAxis) keyAxis = xAxis; + if (!valueAxis) valueAxis = yAxis; + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)"; + return 0; + } + if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; + return 0; + } + + QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); + newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); + return newGraph; +} + +/*! + Removes the specified \a graph from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in + the plot have a channel fill set towards the removed graph, the channel fill property of those + graphs is reset to zero (no channel fill). + + Returns true on success. + + \see clearGraphs +*/ +bool QCustomPlot::removeGraph(QCPGraph *graph) +{ + return removePlottable(graph); +} + +/*! \overload + + Removes and deletes the graph by its \a index. +*/ +bool QCustomPlot::removeGraph(int index) +{ + if (index >= 0 && index < mGraphs.size()) + return removeGraph(mGraphs[index]); + else + return false; +} + +/*! + Removes all graphs from the plot and deletes them. Corresponding legend items are also removed + from the default legend (QCustomPlot::legend). + + Returns the number of graphs removed. + + \see removeGraph +*/ +int QCustomPlot::clearGraphs() +{ + int c = mGraphs.size(); + for (int i=c-1; i >= 0; --i) + removeGraph(mGraphs[i]); + return c; +} + +/*! + Returns the number of currently existing graphs in the plot + + \see graph, addGraph +*/ +int QCustomPlot::graphCount() const +{ + return mGraphs.size(); +} + +/*! + Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. + + If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, + etc., use \ref selectedPlottables. + + \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedGraphs() const +{ + QList result; + foreach (QCPGraph *graph, mGraphs) + { + if (graph->selected()) + result.append(graph); + } + return result; +} + +/*! + Returns the item with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + item, see QCustomPlot::item() + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item(int index) const +{ + if (index >= 0 && index < mItems.size()) + { + return mItems.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last item that was added to this plot. If there are no items in the plot, + returns 0. + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item() const +{ + if (!mItems.isEmpty()) + { + return mItems.last(); + } else + return 0; +} + +/*! + Removes the specified item from the plot and deletes it. + + Returns true on success. + + \see clearItems +*/ +bool QCustomPlot::removeItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + delete item; + mItems.removeOne(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); + return false; + } +} + +/*! \overload + + Removes and deletes the item by its \a index. +*/ +bool QCustomPlot::removeItem(int index) +{ + if (index >= 0 && index < mItems.size()) + return removeItem(mItems[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all items from the plot and deletes them. + + Returns the number of items removed. + + \see removeItem +*/ +int QCustomPlot::clearItems(bool clearTitle) +{ + int c = mItems.size(); + for (int i=c-1; i >= 0; --i) + { + if(mItems[i]->objectName() == "m_trendTitle") + { + if(!clearTitle) + { + continue; + } + } + removeItem(mItems[i]); + } + return c; +} + +/*! + Returns the number of currently existing items in the plot + + \see item +*/ +int QCustomPlot::itemCount() const +{ + return mItems.size(); +} + +/*! + Returns a list of the selected items. If no items are currently selected, the list is empty. + + \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected +*/ +QList QCustomPlot::selectedItems() const +{ + QList result; + foreach (QCPAbstractItem *item, mItems) + { + if (item->selected()) + result.append(item); + } + return result; +} + +/*! + Returns the item at the pixel position \a pos. Items that only consist of single lines (e.g. \ref + QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref + setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is + returned. + + If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are + considered. + + If there is no item at \a pos, the return value is 0. + + \see plottableAt, layoutElementAt +*/ +QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractItem *resultItem = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractItem *item, mItems) + { + if (onlySelectable && !item->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable + continue; + if (!item->clipToAxisRect() || item->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it + { + double currentDistance = item->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultItem = item; + resultDistance = currentDistance; + } + } + } + + return resultItem; +} + +/*! + Returns whether this QCustomPlot contains the \a item. + + \see item +*/ +bool QCustomPlot::hasItem(QCPAbstractItem *item) const +{ + return mItems.contains(item); +} + +/*! + Returns the layer with the specified \a name. If there is no layer with the specified name, 0 is + returned. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(const QString &name) const +{ + foreach (QCPLayer *layer, mLayers) + { + if (layer->name() == name) + return layer; + } + return 0; +} + +/*! \overload + + Returns the layer by \a index. If the index is invalid, 0 is returned. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(int index) const +{ + if (index >= 0 && index < mLayers.size()) + { + return mLayers.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Returns the layer that is set as current layer (see \ref setCurrentLayer). +*/ +QCPLayer *QCustomPlot::currentLayer() const +{ + return mCurrentLayer; +} + +/*! + Sets the layer with the specified \a name to be the current layer. All layerables (\ref + QCPLayerable), e.g. plottables and items, are created on the current layer. + + Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer +*/ +bool QCustomPlot::setCurrentLayer(const QString &name) +{ + if (QCPLayer *newCurrentLayer = layer(name)) + { + return setCurrentLayer(newCurrentLayer); + } else + { + qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; + return false; + } +} + +/*! \overload + + Sets the provided \a layer to be the current layer. + + Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. + + \see addLayer, moveLayer, removeLayer +*/ +bool QCustomPlot::setCurrentLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + + mCurrentLayer = layer; + return true; +} + +/*! + Returns the number of currently existing layers in the plot + + \see layer, addLayer +*/ +int QCustomPlot::layerCount() const +{ + return mLayers.size(); +} + +/*! + Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which + must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. + + Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a + valid layer inside this QCustomPlot. + + If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. + + For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. + + \see layer, moveLayer, removeLayer +*/ +bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!otherLayer) + otherLayer = mLayers.last(); + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + if (layer(name)) + { + qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; + return false; + } + + QCPLayer *newLayer = new QCPLayer(this, name); + mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); + updateLayerIndices(); + setupPaintBuffers(); // associates new layer with the appropriate paint buffer + return true; +} + +/*! + Removes the specified \a layer and returns true on success. + + All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below + \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both + cases, the total rendering order of all layerables in the QCustomPlot is preserved. + + If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom + layer) becomes the new current layer. + + It is not possible to remove the last layer of the plot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::removeLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (mLayers.size() < 2) + { + qDebug() << Q_FUNC_INFO << "can't remove last layer"; + return false; + } + + // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) + int removedIndex = layer->index(); + bool isFirstLayer = removedIndex==0; + QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); + QList children = layer->children(); + if (isFirstLayer) // prepend in reverse order (so order relative to each other stays the same) + { + for (int i=children.size()-1; i>=0; --i) + children.at(i)->moveToLayer(targetLayer, true); + } else // append normally + { + for (int i=0; imoveToLayer(targetLayer, false); + } + // if removed layer is current layer, change current layer to layer below/above: + if (layer == mCurrentLayer) + setCurrentLayer(targetLayer); + // invalidate the paint buffer that was responsible for this layer: + if (!layer->mPaintBuffer.isNull()) + layer->mPaintBuffer.data()->setInvalidated(); + // remove layer: + delete layer; + mLayers.removeOne(layer); + updateLayerIndices(); + return true; +} + +/*! + Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or + below is controlled with \a insertMode. + + Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the + QCustomPlot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + + if (layer->index() > otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); + else if (layer->index() < otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); + + // invalidate the paint buffers that are responsible for the layers: + if (!layer->mPaintBuffer.isNull()) + layer->mPaintBuffer.data()->setInvalidated(); + if (!otherLayer->mPaintBuffer.isNull()) + otherLayer->mPaintBuffer.data()->setInvalidated(); + + updateLayerIndices(); + return true; +} + +/*! + Returns the number of axis rects in the plot. + + All axis rects can be accessed via QCustomPlot::axisRect(). + + Initially, only one axis rect exists in the plot. + + \see axisRect, axisRects +*/ +int QCustomPlot::axisRectCount() const +{ + return axisRects().size(); +} + +/*! + Returns the axis rect with \a index. + + Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were + added, all of them may be accessed with this function in a linear fashion (even when they are + nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). + + \see axisRectCount, axisRects +*/ +QCPAxisRect *QCustomPlot::axisRect(int index) const +{ + const QList rectList = axisRects(); + if (index >= 0 && index < rectList.size()) + { + return rectList.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "invalid axis rect index" << index; + return 0; + } +} + +/*! + Returns all axis rects in the plot. + + \see axisRectCount, axisRect +*/ +QList QCustomPlot::axisRects() const +{ + QList result; + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) + { + if (element) + { + elementStack.push(element); + if (QCPAxisRect *ar = qobject_cast(element)) + result.append(ar); + } + } + } + + return result; +} + +/*! + Returns the layout element at pixel position \a pos. If there is no element at that position, + returns 0. + + Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on + any of its parent elements is set to false, it will not be considered. + + \see itemAt, plottableAt +*/ +QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const +{ + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + break; + } + } + } + return currentElement; +} + +/*! + Returns the layout element of type \ref QCPAxisRect at pixel position \a pos. This method ignores + other layout elements even if they are visually in front of the axis rect (e.g. a \ref + QCPLegend). If there is no axis rect at that position, returns 0. + + Only visible axis rects are used. If \ref QCPLayoutElement::setVisible on the axis rect itself or + on any of its parent elements is set to false, it will not be considered. + + \see layoutElementAt +*/ +QCPAxisRect *QCustomPlot::axisRectAt(const QPointF &pos) const +{ + QCPAxisRect *result = 0; + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + if (QCPAxisRect *ar = qobject_cast(currentElement)) + result = ar; + break; + } + } + } + return result; +} + +/*! + Returns the axes that currently have selected parts, i.e. whose selection state is not \ref + QCPAxis::spNone. + + \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, + QCPAxis::setSelectableParts +*/ +QList QCustomPlot::selectedAxes() const +{ + QList result, allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + { + if (axis->selectedParts() != QCPAxis::spNone) + result.append(axis); + } + + return result; +} + +/*! + Returns the legends that currently have selected parts, i.e. whose selection state is not \ref + QCPLegend::spNone. + + \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, + QCPLegend::setSelectableParts, QCPLegend::selectedItems +*/ +QList QCustomPlot::selectedLegends() const +{ + QList result; + + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) + { + if (subElement) + { + elementStack.push(subElement); + if (QCPLegend *leg = qobject_cast(subElement)) + { + if (leg->selectedParts() != QCPLegend::spNone) + result.append(leg); + } + } + } + } + + return result; +} + +/*! + Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. + + Since calling this function is not a user interaction, this does not emit the \ref + selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the + objects were previously selected. + + \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends +*/ +void QCustomPlot::deselectAll() +{ + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + layerable->deselectEvent(0); + } +} + +/*! + Causes a complete replot into the internal paint buffer(s). Finally, the widget surface is + refreshed with the new buffer contents. This is the method that must be called to make changes to + the plot, e.g. on the axis ranges or data points of graphs, visible. + + The parameter \a refreshPriority can be used to fine-tune the timing of the replot. For example + if your application calls \ref replot very quickly in succession (e.g. multiple independent + functions change some aspects of the plot and each wants to make sure the change gets replotted), + it is advisable to set \a refreshPriority to \ref QCustomPlot::rpQueuedReplot. This way, the + actual replotting is deferred to the next event loop iteration. Multiple successive calls of \ref + replot with this priority will only cause a single replot, avoiding redundant replots and + improving performance. + + Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the + QCustomPlot widget and user interactions (object selection and range dragging/zooming). + + Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref + afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two + signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite + recursion. + + If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to + replot only that specific layer via \ref QCPLayer::replot. See the documentation there for + details. +*/ +void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) +{ + if (refreshPriority == QCustomPlot::rpQueuedReplot) + { + if (!mReplotQueued) + { + mReplotQueued = true; + QTimer::singleShot(0, this, SLOT(replot())); + } + return; + } + + if (mReplotting) // incase signals loop back to replot slot + return; + mReplotting = true; + mReplotQueued = false; + emit beforeReplot(); + + updateLayout(); + // draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers: + setupPaintBuffers(); + foreach (QCPLayer *layer, mLayers) + layer->drawToPaintBuffer(); + for (int i=0; isetInvalidated(false); + + if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh) + repaint(); + else + update(); + + emit afterReplot(); + mReplotting = false; +} + +/*! + Rescales the axes such that all plottables (like graphs) in the plot are fully visible. + + if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true + (QCPLayerable::setVisible), will be used to rescale the axes. + + \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale +*/ +void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) +{ + QList allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + axis->rescale(onlyVisiblePlottables); +} + +/*! + Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale + of texts and lines will be derived from the specified \a width and \a height. This means, the + output will look like the normal on-screen output of a QCustomPlot widget with the corresponding + pixel width and height. If either \a width or \a height is zero, the exported image will have the + same dimensions as the QCustomPlot widget currently has. + + Setting \a exportPen to \ref QCP::epNoCosmetic allows to disable the use of cosmetic pens when + drawing to the PDF file. Cosmetic pens are pens with numerical width 0, which are always drawn as + a one pixel wide line, no matter what zoom factor is set in the PDF-Viewer. For more information + about cosmetic pens, see the QPainter and QPen documentation. + + The objects of the plot will appear in the current selection state. If you don't want any + selected objects to be painted in their selected look, deselect everything with \ref deselectAll + before calling this function. + + Returns true on success. + + \warning + \li If you plan on editing the exported PDF file with a vector graphics editor like Inkscape, it + is advised to set \a exportPen to \ref QCP::epNoCosmetic to avoid losing those cosmetic lines + (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). + \li If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting + PDF file. + + \note On Android systems, this method does nothing and issues an according qDebug warning + message. This is also the case if for other reasons the define flag \c QT_NO_PRINTER is set. + + \see savePng, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::ExportPen exportPen, const QString &pdfCreator, const QString &pdfTitle) +{ + bool success = false; +#ifdef QT_NO_PRINTER + Q_UNUSED(fileName) + Q_UNUSED(exportPen) + Q_UNUSED(width) + Q_UNUSED(height) + Q_UNUSED(pdfCreator) + Q_UNUSED(pdfTitle) + qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created."; +#else + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + QPrinter printer(QPrinter::ScreenResolution); + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setColorMode(QPrinter::Color); + printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator); + printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle); + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + printer.setFullPage(true); + printer.setPaperSize(viewport().size(), QPrinter::DevicePixel); +#else + QPageLayout pageLayout; + pageLayout.setMode(QPageLayout::FullPageMode); + pageLayout.setOrientation(QPageLayout::Portrait); + pageLayout.setMargins(QMarginsF(0, 0, 0, 0)); + pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch)); + printer.setPageLayout(pageLayout); +#endif + QCPPainter printpainter; + if (printpainter.begin(&printer)) + { + printpainter.setMode(QCPPainter::pmVectorized); + printpainter.setMode(QCPPainter::pmNoCaching); + printpainter.setMode(QCPPainter::pmNonCosmetic, exportPen==QCP::epNoCosmetic); + printpainter.setWindow(mViewport); + if (mBackgroundBrush.style() != Qt::NoBrush && + mBackgroundBrush.color() != Qt::white && + mBackgroundBrush.color() != Qt::transparent && + mBackgroundBrush.color().alpha() > 0) // draw pdf background color if not white/transparent + printpainter.fillRect(viewport(), mBackgroundBrush); + draw(&printpainter); + printpainter.end(); + success = true; + } + setViewport(oldViewport); +#endif // QT_NO_PRINTER + return success; +} + +/*! + Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the PNG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + If you want the PNG to have a transparent background, call \ref setBackground(const QBrush &brush) + with no brush (Qt::NoBrush) or a transparent color (Qt::transparent), before saving. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "PNG", quality, resolution, resolutionUnit); +} + +/*! + Saves a JPEG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the JPEG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveBmp, saveRastered +*/ +bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "JPG", quality, resolution, resolutionUnit); +} + +/*! + Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the BMP format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveJpg, saveRastered +*/ +bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "BMP", -1, resolution, resolutionUnit); +} + +/*! \internal + + Returns a minimum size hint that corresponds to the minimum size of the top level layout + (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum + size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. + This is especially important, when placed in a QLayout where other components try to take in as + much space as possible (e.g. QMdiArea). +*/ +QSize QCustomPlot::minimumSizeHint() const +{ + return mPlotLayout->minimumOuterSizeHint(); +} + +/*! \internal + + Returns a size hint that is the same as \ref minimumSizeHint. + +*/ +QSize QCustomPlot::sizeHint() const +{ + return mPlotLayout->minimumOuterSizeHint(); +} + +/*! \internal + + Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but + draws the internal buffer on the widget surface. +*/ +void QCustomPlot::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QCPPainter painter(this); + if (!painter.isActive()) + { + return; + } + painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem + if (mBackgroundBrush.style() != Qt::NoBrush) + painter.fillRect(mViewport, mBackgroundBrush); + drawBackground(&painter); + for (int bufferIndex = 0; bufferIndex < mPaintBuffers.size(); ++bufferIndex) + mPaintBuffers.at(bufferIndex)->draw(&painter); + + if(!axisRect()->isScaleRight()) + { + //< 横坐标有效值 + int x = mSymbolPos.x() >= yAxis->axisRect()->left() ? mSymbolPos.x() : yAxis->axisRect()->left(); + x = x <= yAxis->axisRect()->right() ? x : yAxis->axisRect()->right(); + //< 纵坐标 + int y = yAxis->axisRect()->top(); + + painter.save(); + painter.setPen(QColor(182, 194, 205)); + painter.setBrush(QColor(182, 194, 205)); + painter.setAntialiasing(true); + QPolygon polygon; + polygon.append(QPoint(x, y)); + polygon.append(QPoint(x + 3, y - 5)); + polygon.append(QPoint(x + 3, 0)); + polygon.append(QPoint(x - 3, 0)); + polygon.append(QPoint(x - 3, y - 5)); + painter.drawPolygon(polygon); + painter.drawLine(QPoint(x, y), QPoint(x, yAxis->axisRect()->bottom())); + painter.restore(); + } +} + +/*! \internal + + Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect + of mPlotLayout) is resized appropriately. Finally a \ref replot is performed. +*/ +void QCustomPlot::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + // resize and repaint the buffer: + setViewport(rect()); + replot(rpQueuedRefresh); // queued refresh is important here, to prevent painting issues in some contexts (e.g. MDI subwindow) +} + +/*! \internal + + Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then + determines the layerable under the cursor and forwards the event to it. Finally, emits the + specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref + axisDoubleClick, etc.). + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit mouseDoubleClick(event); + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + // determine layerable under the cursor (this event is called instead of the second press event in a double-click): + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->mouseDoubleClickEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + + // emit specialized object double click signals: + if (!candidates.isEmpty()) + { + if (QCPAbstractPlottable *ap = qobject_cast(candidates.first())) + { + int dataIndex = 0; + if (!details.first().value().isEmpty()) + dataIndex = details.first().value().dataRange().begin(); + emit plottableDoubleClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(candidates.first())) + emit axisDoubleClick(ax, details.first().value(), event); + else if (QCPAbstractItem *ai = qobject_cast(candidates.first())) + emit itemDoubleClick(ai, event); + else if (QCPLegend *lg = qobject_cast(candidates.first())) + emit legendDoubleClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(candidates.first())) + emit legendDoubleClick(li->parentLegend(), li, event); + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is pressed. Emits the mousePress signal. + + If the current \ref setSelectionRectMode is not \ref QCP::srmNone, passes the event to the + selection rect. Otherwise determines the layerable under the cursor and forwards the event to it. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCustomPlot::mousePressEvent(QMouseEvent *event) +{ + if(cursor().shape() == Qt::SizeHorCursor && event->button() == Qt::LeftButton) + { + mSymbolPos = event->pos(); + mSymbolPressed = true; + return; + } + + emit mousePress(event); + // save some state to tell in releaseEvent whether it was a click: + + + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + if (mSelectionRect && mSelectionRectMode != QCP::srmNone) + { + if (mSelectionRectMode != QCP::srmZoom || qobject_cast(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect + mSelectionRect->startSelection(event); + } else + { + // no selection rect interaction, prepare for click signal emission and forward event to layerable under the cursor: + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + if (!candidates.isEmpty()) + { + mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always topmost hit layerable (signal emitted in release event) + mMouseSignalLayerableDetails = details.first(); + } + // forward event to topmost candidate which accepts the event: + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events call ignore() on the event, in that case propagate to next candidate in list + candidates.at(i)->mousePressEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. + update(); +} + +/*! \internal + + Event handler for when the cursor is moved. Emits the \ref mouseMove signal. + + If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it + in order to update the rect geometry. + + Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the + layout element before), the mouseMoveEvent is forwarded to that element. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseMoveEvent(QMouseEvent *event) +{ + //< time tip + if(!axisRect()->isScaleRight() && !mSymbolPressed && qAbs(mSymbolPos.x() - event->pos().x()) < 5) + { + if(event->pos().y() > yAxis->axisRect()->top()) + { + if(Qt::SizeHorCursor != cursor().shape()) + { + setCursor(QCursor(Qt::SizeHorCursor)); + } + } + static QString preTipsContent = QString(); + QString strTime = QDateTime::fromMSecsSinceEpoch(xAxis->pixelToCoord(mSymbolPos.x())).toString("yyyy-MM-dd hh:mm:ss zzz"); + if(preTipsContent == strTime && findChild("ToolTip")) + { + return; + } + preTipsContent = strTime; + QFontMetrics metrics(QToolTip::font()); + int pixelsWide = metrics.width(strTime); + int pixelsHigh = metrics.height(); + QPoint position = mapToGlobal(QPoint(event->pos().x() - (pixelsWide / 2), -(pixelsHigh / 2))); + CToolTip::popup(position, strTime, this); + return; + } + + if(mSymbolPressed && event->pos().x() >= yAxis->mAxisRect->left() &&event->pos().x() <= yAxis->mAxisRect->right()) + { + setCursor(QCursor(Qt::SizeHorCursor)); + mSymbolPos = event->pos(); + emit symbolPosChanged(xAxis->pixelToCoord(mSymbolPos.x())); + update(); + return; + } + setCursor(QCursor(Qt::ArrowCursor)); + + + emit mouseMove(event); + if (!mMouseHasMoved && (mMousePressPos-event->pos()).manhattanLength() > 3) + mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release + + if (mSelectionRect && mSelectionRect->isActive()) + mSelectionRect->moveSelection(event); + else if (mMouseEventLayerable) // call event of affected layerable: + mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos); + + //< Extra By ZH + QList details; + QList candidates = layerableListAt(event->pos(), false, &details); + for (int i = 0; i < candidates.size(); ++i) + { + if(dynamic_cast(candidates.at(i))) + { + event->accept(); + candidates.at(i)->mouseMoveEvent(event, mMousePressPos); + } + } + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is released. Emits the \ref mouseRelease signal. + + If the mouse was moved less than a certain threshold in any direction since the \ref + mousePressEvent, it is considered a click which causes the selection mechanism (if activated via + \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse + click signals are emitted (e.g. \ref plottableClick, \ref axisClick, etc.) + + If a layerable is the mouse capturer (a \ref mousePressEvent happened on top of the layerable + before), the \ref mouseReleaseEvent is forwarded to that element. + + \see mousePressEvent, mouseMoveEvent +*/ +void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) +{ + emit mouseRelease(event); + + mSymbolPressed = false; + if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click + { + if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here + mSelectionRect->cancel(); + if (event->button() == Qt::LeftButton) + processPointSelection(event); + + // emit specialized click signals of QCustomPlot instance: + if (QCPAbstractPlottable *ap = qobject_cast(mMouseSignalLayerable)) + { + int dataIndex = 0; + if (!mMouseSignalLayerableDetails.value().isEmpty()) + dataIndex = mMouseSignalLayerableDetails.value().dataRange().begin(); + emit plottableClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(mMouseSignalLayerable)) + emit axisClick(ax, mMouseSignalLayerableDetails.value(), event); + else if (QCPAbstractItem *ai = qobject_cast(mMouseSignalLayerable)) + emit itemClick(ai, event); + else if (QCPLegend *lg = qobject_cast(mMouseSignalLayerable)) + emit legendClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(mMouseSignalLayerable)) + emit legendClick(li->parentLegend(), li, event); + mMouseSignalLayerable = 0; + } + + if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there + { + // finish selection rect, the appropriate action will be taken via signal-slot connection: + mSelectionRect->endSelection(event); + } else + { + // call event of affected layerable: + if (mMouseEventLayerable) + { + mMouseEventLayerable->mouseReleaseEvent(event, mMousePressPos); + mMouseEventLayerable = 0; + } + } + + if (noAntialiasingOnDrag()) + replot(rpQueuedReplot); + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for mouse wheel events. First, the \ref mouseWheel signal is emitted. Then + determines the affected layerable and forwards the event to it. +*/ +void QCustomPlot::wheelEvent(QWheelEvent *event) +{ + QRect rt = axisRect()->mRect; + if(event->pos().x() < rt.left() || event->pos().x() > rt.right() || event->pos().y() < rt.top() || event->pos().y() > rt.bottom()) + { + return; + } + + emit mouseWheel(event); + // forward event to layerable under cursor: + QList candidates = layerableListAt(event->pos(), false); + + + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->wheelEvent(event); + if (event->isAccepted()) + break; + } + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +bool QCustomPlot::eventFilter(QObject *object, QEvent *event) +{ + QLabel * pLabel = dynamic_cast(object); + if (pLabel) + { + if(event->type() == QEvent::Wheel) + { + QWheelEvent * pWheelEvent = dynamic_cast(event); + QWheelEvent e(mapFromGlobal(pWheelEvent->globalPos()), + pWheelEvent->globalPos(), + pWheelEvent->pixelDelta(), + pWheelEvent->angleDelta(), + pWheelEvent->delta(), + pWheelEvent->orientation(), + pWheelEvent->buttons(), + pWheelEvent->modifiers()); + + wheelEvent(&e); + return true; + } + else if(event->type() == QEvent::MouseMove) + { + QMouseEvent *pMouseEvent = dynamic_cast(event); + QPoint pt = mapFromGlobal(pMouseEvent->globalPos()); + QMouseEvent e(pMouseEvent->type(), + pt, pt, + pMouseEvent->screenPos(), + pMouseEvent->button(), + pMouseEvent->buttons(), + pMouseEvent->modifiers(), + pMouseEvent->source()); + mouseMoveEvent(&e); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +/*! \internal + + This function draws the entire plot, including background pixmap, with the specified \a painter. + It does not make use of the paint buffers like \ref replot, so this is the function typically + used by saving/exporting methods such as \ref savePdf or \ref toPainter. + + Note that it does not fill the background with the background brush (as the user may specify with + \ref setBackground(const QBrush &brush)), this is up to the respective functions calling this + method. +*/ +void QCustomPlot::draw(QCPPainter *painter) +{ + updateLayout(); + + // draw viewport background pixmap: + drawBackground(painter); + + // draw all layered objects (grid, axes, plottables, items, legend,...): + foreach (QCPLayer *layer, mLayers) + layer->draw(painter); + + /* Debug code to draw all layout element rects + foreach (QCPLayoutElement* el, findChildren()) + { + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(QColor(0, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->rect()); + painter->setPen(QPen(QColor(255, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->outerRect()); + } + */ +} + +/*! \internal + + Performs the layout update steps defined by \ref QCPLayoutElement::UpdatePhase, by calling \ref + QCPLayoutElement::update on the main plot layout. + + Here, the layout elements calculate their positions and margins, and prepare for the following + draw call. +*/ +void QCustomPlot::updateLayout() +{ + // run through layout phases: + mPlotLayout->update(QCPLayoutElement::upPreparation); + mPlotLayout->update(QCPLayoutElement::upMargins); + mPlotLayout->update(QCPLayoutElement::upLayout); +} + +/*! \internal + + Draws the viewport background pixmap of the plot. + + If a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the viewport with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + Note that this function does not draw a fill with the background brush + (\ref setBackground(const QBrush &brush)) beneath the pixmap. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::drawBackground(QCPPainter *painter) +{ + // Note: background color is handled in individual replot/save functions + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mViewport.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height())); + } + } +} + +/*! \internal + + Goes through the layers and makes sure this QCustomPlot instance holds the correct number of + paint buffers and that they have the correct configuration (size, pixel ratio, etc.). + Allocations, reallocations and deletions of paint buffers are performed as necessary. It also + associates the paint buffers with the layers, so they draw themselves into the right buffer when + \ref QCPLayer::drawToPaintBuffer is called. This means it associates adjacent \ref + QCPLayer::lmLogical layers to a mutual paint buffer and creates dedicated paint buffers for + layers in \ref QCPLayer::lmBuffered mode. + + This method uses \ref createPaintBuffer to create new paint buffers. + + After this method, the paint buffers are empty (filled with \c Qt::transparent) and invalidated + (so an attempt to replot only a single buffered layer causes a full replot). + + This method is called in every \ref replot call, prior to actually drawing the layers (into their + associated paint buffer). If the paint buffers don't need changing/reallocating, this method + basically leaves them alone and thus finishes very fast. +*/ +void QCustomPlot::setupPaintBuffers() +{ + int bufferIndex = 0; + if (mPaintBuffers.isEmpty()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + + for (int layerIndex = 0; layerIndex < mLayers.size(); ++layerIndex) + { + QCPLayer *layer = mLayers.at(layerIndex); + if (layer->mode() == QCPLayer::lmLogical) + { + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + } else if (layer->mode() == QCPLayer::lmBuffered) + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + if (layerIndex < mLayers.size()-1 && mLayers.at(layerIndex+1)->mode() == QCPLayer::lmLogical) // not last layer, and next one is logical, so prepare another buffer for next layerables + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + } + } + } + // remove unneeded buffers: + while (mPaintBuffers.size()-1 > bufferIndex) + mPaintBuffers.removeLast(); + // resize buffers to viewport size and clear contents: + for (int i=0; isetSize(viewport().size()); // won't do anything if already correct size + mPaintBuffers.at(i)->clear(Qt::transparent); + mPaintBuffers.at(i)->setInvalidated(); + } +} + +/*! \internal + + This method is used by \ref setupPaintBuffers when it needs to create new paint buffers. + + Depending on the current setting of \ref setOpenGl, and the current Qt version, different + backends (subclasses of \ref QCPAbstractPaintBuffer) are created, initialized with the proper + size and device pixel ratio, and returned. +*/ +QCPAbstractPaintBuffer *QCustomPlot::createPaintBuffer() +{ + if (mOpenGl) + { +#if defined(QCP_OPENGL_FBO) + return new QCPPaintBufferGlFbo(viewport().size(), mBufferDevicePixelRatio, mGlContext, mGlPaintDevice); +#elif defined(QCP_OPENGL_PBUFFER) + return new QCPPaintBufferGlPbuffer(viewport().size(), mBufferDevicePixelRatio, mOpenGlMultisamples); +#else + qDebug() << Q_FUNC_INFO << "OpenGL enabled even though no support for it compiled in, this shouldn't have happened. Falling back to pixmap paint buffer."; + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +#endif + } else + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +} + +/*! + This method returns whether any of the paint buffers held by this QCustomPlot instance are + invalidated. + + If any buffer is invalidated, a partial replot (\ref QCPLayer::replot) is not allowed and always + causes a full replot (\ref QCustomPlot::replot) of all layers. This is the case when for example + the layer order has changed, new layers were added, layers were removed, or layer modes were + changed (\ref QCPLayer::setMode). + + \see QCPAbstractPaintBuffer::setInvalidated +*/ +bool QCustomPlot::hasInvalidatedPaintBuffers() +{ + for (int i=0; iinvalidated()) + return true; + } + return false; +} + +/*! \internal + + When \ref setOpenGl is set to true, this method is used to initialize OpenGL (create a context, + surface, paint device). + + Returns true on success. + + If this method is successful, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the OpenGL-based paint buffer subclasses (\ref + QCPPaintBufferGlPbuffer, \ref QCPPaintBufferGlFbo) are used for subsequent replots. + + \see freeOpenGl +*/ +bool QCustomPlot::setupOpenGl() +{ +#ifdef QCP_OPENGL_FBO + freeOpenGl(); + QSurfaceFormat proposedSurfaceFormat; + proposedSurfaceFormat.setSamples(mOpenGlMultisamples); +#ifdef QCP_OPENGL_OFFSCREENSURFACE + QOffscreenSurface *surface = new QOffscreenSurface; +#else + QWindow *surface = new QWindow; + surface->setSurfaceType(QSurface::OpenGLSurface); +#endif + surface->setFormat(proposedSurfaceFormat); + surface->create(); + mGlSurface = QSharedPointer(surface); + mGlContext = QSharedPointer(new QOpenGLContext); + mGlContext->setFormat(mGlSurface->format()); + if (!mGlContext->create()) + { + qDebug() << Q_FUNC_INFO << "Failed to create OpenGL context"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!mGlContext->makeCurrent(mGlSurface.data())) // context needs to be current to create paint device + { + qDebug() << Q_FUNC_INFO << "Failed to make opengl context current"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) + { + qDebug() << Q_FUNC_INFO << "OpenGL of this system doesn't support frame buffer objects"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + mGlPaintDevice = QSharedPointer(new QOpenGLPaintDevice); + return true; +#elif defined(QCP_OPENGL_PBUFFER) + return QGLFormat::hasOpenGL(); +#else + return false; +#endif +} + +/*! \internal + + When \ref setOpenGl is set to false, this method is used to deinitialize OpenGL (releases the + context and frees resources). + + After OpenGL is disabled, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the standard software rendering paint buffer subclass (\ref + QCPPaintBufferPixmap) is used for subsequent replots. + + \see setupOpenGl +*/ +void QCustomPlot::freeOpenGl() +{ +#ifdef QCP_OPENGL_FBO + mGlPaintDevice.clear(); + mGlContext.clear(); + mGlSurface.clear(); +#endif +} + +/*! \internal + + This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot + so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. +*/ +void QCustomPlot::axisRemoved(QCPAxis *axis) +{ + if (xAxis == axis) + xAxis = 0; + if (xAxis2 == axis) + xAxis2 = 0; + if (yAxis == axis) + yAxis = 0; + if (yAxis2 == axis) + yAxis2 = 0; + + // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers +} + +/*! \internal + + This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so + it may clear its QCustomPlot::legend member accordingly. +*/ +void QCustomPlot::legendRemoved(QCPLegend *legend) +{ + if (this->legend == legend) + this->legend = 0; +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmSelect. + + First, it determines which axis rect was the origin of the selection rect judging by the starting + point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be + precise) associated with that axis rect and finds the data points that are in \a rect. It does + this by querying their \ref QCPAbstractPlottable1D::selectTestRect method. + + Then, the actual selection is done by calling the plottables' \ref + QCPAbstractPlottable::selectEvent, placing the found selected data points in the \a details + parameter as QVariant(\ref QCPDataSelection). All plottables that weren't touched by \a + rect receive a \ref QCPAbstractPlottable::deselectEvent. + + \see processRectZoom +*/ +void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) +{ + bool selectionStateChanged = false; + + if (mInteractions.testFlag(QCP::iSelectPlottables)) + { + QMap > potentialSelections; // map key is number of selected data points, so we have selections sorted by size + QRectF rectF(rect.normalized()); + if (QCPAxisRect *affectedAxisRect = axisRectAt(rectF.topLeft())) + { + // determine plottables that were hit by the rect and thus are candidates for selection: + foreach (QCPAbstractPlottable *plottable, affectedAxisRect->plottables()) + { + if (QCPPlottableInterface1D *plottableInterface = plottable->interface1D()) + { + QCPDataSelection dataSel = plottableInterface->selectTestRect(rectF, true); + if (!dataSel.isEmpty()) + potentialSelections.insertMulti(dataSel.dataPointCount(), QPair(plottable, dataSel)); + } + } + + if (!mInteractions.testFlag(QCP::iMultiSelect)) + { + // only leave plottable with most selected points in map, since we will only select a single plottable: + if (!potentialSelections.isEmpty()) + { + QMap >::iterator it = potentialSelections.begin(); + while (it != potentialSelections.end()-1) // erase all except last element + it = potentialSelections.erase(it); + } + } + + bool additive = event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + // emit deselection except to those plottables who will be selected afterwards: + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + // go through selections in reverse (largest selection first) and emit select events: + QMap >::const_iterator it = potentialSelections.constEnd(); + while (it != potentialSelections.constBegin()) + { + --it; + if (mInteractions.testFlag(it.value().first->selectionCategory())) + { + bool selChanged = false; + it.value().first->selectEvent(event, additive, QVariant::fromValue(it.value().second), &selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } else if (mSelectionRect) + mSelectionRect->layer()->replot(); +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmZoom. + + It determines which axis rect was the origin of the selection rect judging by the starting point + of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the + provided \a rect (see \ref QCPAxisRect::zoom). + + \see processRectSelection +*/ +void QCustomPlot::processRectZoom(QRect rect, QMouseEvent *event) +{ + Q_UNUSED(event) + if (QCPAxisRect *axisRect = axisRectAt(rect.topLeft())) + { + QList affectedAxes = QList() << axisRect->rangeZoomAxes(Qt::Horizontal) << axisRect->rangeZoomAxes(Qt::Vertical); + affectedAxes.removeAll(static_cast(0)); + axisRect->zoom(QRectF(rect), affectedAxes); + } + replot(rpQueuedReplot); // always replot to make selection rect disappear +} + +/*! \internal + + This method is called when a simple left mouse click was detected on the QCustomPlot surface. + + It first determines the layerable that was hit by the click, and then calls its \ref + QCPLayerable::selectEvent. All other layerables receive a QCPLayerable::deselectEvent (unless the + multi-select modifier was pressed, see \ref setMultiSelectModifier). + + In this method the hit layerable is determined a second time using \ref layerableAt (after the + one in \ref mousePressEvent), because we want \a onlySelectable set to true this time. This + implies that the mouse event grabber (mMouseEventLayerable) may be a different one from the + clicked layerable determined here. For example, if a non-selectable layerable is in front of a + selectable layerable at the click position, the front layerable will receive mouse events but the + selectable one in the back will receive the \ref QCPLayerable::selectEvent. + + \see processRectSelection, QCPLayerable::selectTest +*/ +void QCustomPlot::processPointSelection(QMouseEvent *event) +{ + QVariant details; + QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details); + bool selectionStateChanged = false; + bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + if (clickedLayerable && mInteractions.testFlag(clickedLayerable->selectionCategory())) + { + // a layerable was actually clicked, call its selectEvent: + bool selChanged = false; + clickedLayerable->selectEvent(event, additive, details, &selChanged); + selectionStateChanged |= selChanged; + } + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } +} + +/*! \internal + + Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend + is enabled, adds it to the legend (QCustomPlot::legend). QCustomPlot takes ownership of the + plottable. + + Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of + \a plottable is this QCustomPlot. + + This method is called automatically in the QCPAbstractPlottable base class constructor. +*/ +bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) +{ + if (mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); + return false; + } + if (plottable->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); + return false; + } + + mPlottables.append(plottable); + // possibly add plottable to legend: + if (mAutoAddPlottableToLegend) + plottable->addToLegend(); + if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) + plottable->setLayer(currentLayer()); + return true; +} + +/*! \internal + + In order to maintain the simplified graph interface of QCustomPlot, this method is called by the + QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true + on success, i.e. if \a graph is valid and wasn't already registered with this QCustomPlot. + + This graph specific registration happens in addition to the call to \ref registerPlottable by the + QCPAbstractPlottable base class. +*/ +bool QCustomPlot::registerGraph(QCPGraph *graph) +{ + if (!graph) + { + qDebug() << Q_FUNC_INFO << "passed graph is zero"; + return false; + } + if (mGraphs.contains(graph)) + { + qDebug() << Q_FUNC_INFO << "graph already registered with this QCustomPlot"; + return false; + } + + mGraphs.append(graph); + return true; +} + + +/*! \internal + + Registers the specified item with this QCustomPlot. QCustomPlot takes ownership of the item. + + Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a + item is this QCustomPlot. + + This method is called automatically in the QCPAbstractItem base class constructor. +*/ +bool QCustomPlot::registerItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + qDebug() << Q_FUNC_INFO << "item already added to this QCustomPlot:" << reinterpret_cast(item); + return false; + } + if (item->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast(item); + return false; + } + + mItems.append(item); + if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor) + item->setLayer(currentLayer()); + return true; +} + +/*! \internal + + Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called + after every operation that changes the layer indices, like layer removal, layer creation, layer + moving. +*/ +void QCustomPlot::updateLayerIndices() const +{ + for (int i=0; imIndex = i; +} + +/*! \internal + + Returns the top-most layerable at pixel position \a pos. If \a onlySelectable is set to true, + only those layerables that are selectable will be considered. (Layerable subclasses communicate + their selectability via the QCPLayerable::selectTest method, by returning -1.) + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableListAt, layoutElementAt, axisRectAt +*/ +QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const +{ + QList details; + QList candidates = layerableListAt(pos, onlySelectable, selectionDetails ? &details : 0); + if (selectionDetails && !details.isEmpty()) + *selectionDetails = details.first(); + if (!candidates.isEmpty()) + return candidates.first(); + else + return 0; +} + +/*! \internal + + Returns the layerables at pixel position \a pos. If \a onlySelectable is set to true, only those + layerables that are selectable will be considered. (Layerable subclasses communicate their + selectability via the QCPLayerable::selectTest method, by returning -1.) + + The returned list is sorted by the layerable/drawing order. If you only need to know the top-most + layerable, rather use \ref layerableAt. + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableAt, layoutElementAt, axisRectAt +*/ +QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails) const +{ + QList result; + for (int layerIndex=mLayers.size()-1; layerIndex>=0; --layerIndex) + { + const QList layerables = mLayers.at(layerIndex)->children(); + for (int i=layerables.size()-1; i>=0; --i) + { + if (!layerables.at(i)->realVisibility()) + continue; + QVariant details; + double dist = layerables.at(i)->selectTest(pos, onlySelectable, selectionDetails ? &details : 0); + if (dist >= 0 && dist < selectionTolerance()) + { + result.append(layerables.at(i)); + if (selectionDetails) + selectionDetails->append(details); + } + } + } + return result; +} + +/*! + Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is + sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead + to a full resolution file with width 200.) If the \a format supports compression, \a quality may + be between 0 and 100 to control it. + + Returns true on success. If this function fails, most likely the given \a format isn't supported + by the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The \a resolution will be written to the image file header (if the file format supports this) and + has no direct consequence for the quality or the pixel size. However, if opening the image with a + tool which respects the metadata, it will be able to scale the image to match either a given size + in real units of length (inch, centimeters, etc.), or the target display DPI. You can specify in + which units \a resolution is given, by setting \a resolutionUnit. The \a resolution is converted + to the format's expected resolution unit internally. + + \see saveBmp, saveJpg, savePng, savePdf +*/ +bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + QImage buffer = toPixmap(width, height, scale).toImage(); + + int dotsPerMeter = 0; + switch (resolutionUnit) + { + case QCP::ruDotsPerMeter: dotsPerMeter = resolution; break; + case QCP::ruDotsPerCentimeter: dotsPerMeter = resolution*100; break; + case QCP::ruDotsPerInch: dotsPerMeter = resolution/0.0254; break; + } + buffer.setDotsPerMeterX(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + buffer.setDotsPerMeterY(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + if (!buffer.isNull()) + return buffer.save(fileName, format, quality); + else + return false; +} + +/*! + Renders the plot to a pixmap and returns it. + + The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and + scale 2.0 lead to a full resolution pixmap with width 200.) + + \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf +*/ +QPixmap QCustomPlot::toPixmap(int width, int height, double scale) +{ + // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + int scaledWidth = qRound(scale*newWidth); + int scaledHeight = qRound(scale*newHeight); + + QPixmap result(scaledWidth, scaledHeight); + result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later + QCPPainter painter; + painter.begin(&result); + if (painter.isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter.setMode(QCPPainter::pmNoCaching); + if (!qFuzzyCompare(scale, 1.0)) + { + if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales + painter.setMode(QCPPainter::pmNonCosmetic); + painter.scale(scale, scale); + } + if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill + painter.fillRect(mViewport, mBackgroundBrush); + draw(&painter); + setViewport(oldViewport); + painter.end(); + } else // might happen if pixmap has width or height zero + { + qDebug() << Q_FUNC_INFO << "Couldn't activate painter on pixmap"; + return QPixmap(); + } + return result; +} + +/*! + Renders the plot using the passed \a painter. + + The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will + appear scaled accordingly. + + \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter + on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with + the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. + + \see toPixmap +*/ +void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) +{ + // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + if (painter->isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter->setMode(QCPPainter::pmNoCaching); + if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here + painter->fillRect(mViewport, mBackgroundBrush); + draw(painter); + setViewport(oldViewport); + } else + qDebug() << Q_FUNC_INFO << "Passed painter is not active"; +} +/* end of 'src/core.cpp' */ + +//amalgamation: add plottable1d.cpp + +/* including file 'src/colorgradient.cpp', size 24646 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorGradient +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorGradient + \brief Defines a color gradient for use with e.g. \ref QCPColorMap + + This class describes a color gradient which can be used to encode data with color. For example, + QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which + take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) + with a \a position from 0 to 1. In between these defined color positions, the + color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation. + + Alternatively, load one of the preset color gradients shown in the image below, with \ref + loadPreset, or by directly specifying the preset in the constructor. + + Apart from red, green and blue components, the gradient also interpolates the alpha values of the + configured color stops. This allows to display some portions of the data range as transparent in + the plot. + + \image html QCPColorGradient.png + + The \ref QCPColorGradient(GradientPreset preset) constructor allows directly converting a \ref + GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset + to all the \a setGradient methods, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient + + The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the + color gradient shall be applied periodically (wrapping around) to data values that lie outside + the data range specified on the plottable instance can be controlled with \ref setPeriodic. +*/ + +/*! + Constructs a new, empty QCPColorGradient with no predefined color stops. You can add own color + stops with \ref setColorStopAt. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient() : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); +} + +/*! + Constructs a new QCPColorGradient initialized with the colors and color interpolation according + to \a preset. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient(GradientPreset preset) : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); + loadPreset(preset); +} + +/* undocumented operator */ +bool QCPColorGradient::operator==(const QCPColorGradient &other) const +{ + return ((other.mLevelCount == this->mLevelCount) && + (other.mColorInterpolation == this->mColorInterpolation) && + (other.mPeriodic == this->mPeriodic) && + (other.mColorStops == this->mColorStops)); +} + +/*! + Sets the number of discretization levels of the color gradient to \a n. The default is 350 which + is typically enough to create a smooth appearance. The minimum number of levels is 2. + + \image html QCPColorGradient-levelcount.png +*/ +void QCPColorGradient::setLevelCount(int n) +{ + if (n < 2) + { + qDebug() << Q_FUNC_INFO << "n must be greater or equal 2 but was" << n; + n = 2; + } + if (n != mLevelCount) + { + mLevelCount = n; + mColorBufferInvalidated = true; + } +} + +/*! + Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the + colors are the values of the passed QMap \a colorStops. In between these color stops, the color + is interpolated according to \ref setColorInterpolation. + + A more convenient way to create a custom gradient may be to clear all color stops with \ref + clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with + \ref setColorStopAt. + + \see clearColorStops +*/ +void QCPColorGradient::setColorStops(const QMap &colorStops) +{ + mColorStops = colorStops; + mColorBufferInvalidated = true; +} + +/*! + Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between + these color stops, the color is interpolated according to \ref setColorInterpolation. + + \see setColorStops, clearColorStops +*/ +void QCPColorGradient::setColorStopAt(double position, const QColor &color) +{ + mColorStops.insert(position, color); + mColorBufferInvalidated = true; +} + +/*! + Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be + interpolated linearly in RGB or in HSV color space. + + For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, + whereas in HSV space the intermediate color is yellow. +*/ +void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation) +{ + if (interpolation != mColorInterpolation) + { + mColorInterpolation = interpolation; + mColorBufferInvalidated = true; + } +} + +/*! + Sets whether data points that are outside the configured data range (e.g. \ref + QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether + they all have the same color, corresponding to the respective gradient boundary color. + + \image html QCPColorGradient-periodic.png + + As shown in the image above, gradients that have the same start and end color are especially + suitable for a periodic gradient mapping, since they produce smooth color transitions throughout + the color map. A preset that has this property is \ref gpHues. + + In practice, using periodic color gradients makes sense when the data corresponds to a periodic + dimension, such as an angle or a phase. If this is not the case, the color encoding might become + ambiguous, because multiple different data values are shown as the same color. +*/ +void QCPColorGradient::setPeriodic(bool enabled) +{ + mPeriodic = enabled; +} + +/*! \overload + + This method is used to quickly convert a \a data array to colors. The colors will be output in + the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this + function. The data range that shall be used for mapping the data value to the gradient is passed + in \a range. \a logarithmic indicates whether the data values shall be mapped to colors + logarithmically. + + if \a data actually contains 2D-data linearized via [row*columnCount + column], you can + set \a dataIndexFactor to columnCount to convert a column instead of a row of the data + array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data + is addressed data[i*dataIndexFactor]. + + Use the overloaded method to additionally provide alpha map data. + + The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } +} + +/*! \overload + + Additionally to the other overload of \ref colorize, this method takes the array \a alpha, which + has the same size and structure as \a data and encodes the alpha information per data point. + + The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!alpha) + { + qDebug() << Q_FUNC_INFO << "null pointer given as alpha"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + if (alpha[dataIndexFactor*i] == 255) + { + scanLine[i] = mColorBuffer.at(index); + } else + { + const QRgb rgb = mColorBuffer.at(index); + const float alphaF = alpha[dataIndexFactor*i]/255.0f; + scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); + } + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + if (alpha[dataIndexFactor*i] == 255) + { + scanLine[i] = mColorBuffer.at(index); + } else + { + const QRgb rgb = mColorBuffer.at(index); + const float alphaF = alpha[dataIndexFactor*i]/255.0f; + scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); + } + } + } + } +} + +/*! \internal + + This method is used to colorize a single data value given in \a position, to colors. The data + range that shall be used for mapping the data value to the gradient is passed in \a range. \a + logarithmic indicates whether the data value shall be mapped to a color logarithmically. + + If an entire array of data values shall be converted, rather use \ref colorize, for better + performance. + + The returned QRgb has its r, g and b components premultiplied with alpha (see + QImage::Format_ARGB32_Premultiplied). +*/ +QRgb QCPColorGradient::color(double position, const QCPRange &range, bool logarithmic) +{ + // If you change something here, make sure to also adapt ::colorize() + if (mColorBufferInvalidated) + updateColorBuffer(); + int index = 0; + if (!logarithmic) + index = (position-range.lower)*(mLevelCount-1)/range.size(); + else + index = qLn(position/range.lower)/qLn(range.upper/range.lower)*(mLevelCount-1); + if (mPeriodic) + { + index = index % mLevelCount; + if (index < 0) + index += mLevelCount; + } else + { + if (index < 0) + index = 0; + else if (index >= mLevelCount) + index = mLevelCount-1; + } + return mColorBuffer.at(index); +} + +/*! + Clears the current color stops and loads the specified \a preset. A preset consists of predefined + color stops and the corresponding color interpolation method. + + The available presets are: + \image html QCPColorGradient.png +*/ +void QCPColorGradient::loadPreset(GradientPreset preset) +{ + clearColorStops(); + switch (preset) + { + case gpGrayscale: + setColorInterpolation(ciRGB); + setColorStopAt(0, Qt::black); + setColorStopAt(1, Qt::white); + break; + case gpHot: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 0, 0)); + setColorStopAt(0.2, QColor(180, 10, 0)); + setColorStopAt(0.4, QColor(245, 50, 0)); + setColorStopAt(0.6, QColor(255, 150, 10)); + setColorStopAt(0.8, QColor(255, 255, 50)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpCold: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.2, QColor(0, 10, 180)); + setColorStopAt(0.4, QColor(0, 50, 245)); + setColorStopAt(0.6, QColor(10, 150, 255)); + setColorStopAt(0.8, QColor(50, 255, 255)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpNight: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(10, 20, 30)); + setColorStopAt(1, QColor(250, 255, 250)); + break; + case gpCandy: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(0, 0, 255)); + setColorStopAt(1, QColor(255, 250, 250)); + break; + case gpGeography: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(70, 170, 210)); + setColorStopAt(0.20, QColor(90, 160, 180)); + setColorStopAt(0.25, QColor(45, 130, 175)); + setColorStopAt(0.30, QColor(100, 140, 125)); + setColorStopAt(0.5, QColor(100, 140, 100)); + setColorStopAt(0.6, QColor(130, 145, 120)); + setColorStopAt(0.7, QColor(140, 130, 120)); + setColorStopAt(0.9, QColor(180, 190, 190)); + setColorStopAt(1, QColor(210, 210, 230)); + break; + case gpIon: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 10, 10)); + setColorStopAt(0.45, QColor(0, 0, 255)); + setColorStopAt(0.8, QColor(0, 255, 255)); + setColorStopAt(1, QColor(0, 255, 0)); + break; + case gpThermal: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.15, QColor(20, 0, 120)); + setColorStopAt(0.33, QColor(200, 30, 140)); + setColorStopAt(0.6, QColor(255, 100, 0)); + setColorStopAt(0.85, QColor(255, 255, 40)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpPolar: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 255, 255)); + setColorStopAt(0.18, QColor(10, 70, 255)); + setColorStopAt(0.28, QColor(10, 10, 190)); + setColorStopAt(0.5, QColor(0, 0, 0)); + setColorStopAt(0.72, QColor(190, 10, 10)); + setColorStopAt(0.82, QColor(255, 70, 10)); + setColorStopAt(1, QColor(255, 255, 50)); + break; + case gpSpectrum: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 0, 50)); + setColorStopAt(0.15, QColor(0, 0, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.6, QColor(255, 255, 0)); + setColorStopAt(0.75, QColor(255, 30, 0)); + setColorStopAt(1, QColor(50, 0, 0)); + break; + case gpJet: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 100)); + setColorStopAt(0.15, QColor(0, 50, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.65, QColor(255, 255, 0)); + setColorStopAt(0.85, QColor(255, 30, 0)); + setColorStopAt(1, QColor(100, 0, 0)); + break; + case gpHues: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(255, 0, 0)); + setColorStopAt(1.0/3.0, QColor(0, 0, 255)); + setColorStopAt(2.0/3.0, QColor(0, 255, 0)); + setColorStopAt(1, QColor(255, 0, 0)); + break; + } +} + +/*! + Clears all color stops. + + \see setColorStops, setColorStopAt +*/ +void QCPColorGradient::clearColorStops() +{ + mColorStops.clear(); + mColorBufferInvalidated = true; +} + +/*! + Returns an inverted gradient. The inverted gradient has all properties as this \ref + QCPColorGradient, but the order of the color stops is inverted. + + \see setColorStops, setColorStopAt +*/ +QCPColorGradient QCPColorGradient::inverted() const +{ + QCPColorGradient result(*this); + result.clearColorStops(); + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + result.setColorStopAt(1.0-it.key(), it.value()); + return result; +} + +/*! \internal + + Returns true if the color gradient uses transparency, i.e. if any of the configured color stops + has an alpha value below 255. +*/ +bool QCPColorGradient::stopsUseAlpha() const +{ + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + { + if (it.value().alpha() < 255) + return true; + } + return false; +} + +/*! \internal + + Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly + convert positions to colors. This is where the interpolation between color stops is calculated. +*/ +void QCPColorGradient::updateColorBuffer() +{ + if (mColorBuffer.size() != mLevelCount) + mColorBuffer.resize(mLevelCount); + if (mColorStops.size() > 1) + { + double indexToPosFactor = 1.0/(double)(mLevelCount-1); + const bool useAlpha = stopsUseAlpha(); + for (int i=0; i::const_iterator it = mColorStops.lowerBound(position); + if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop + { + mColorBuffer[i] = (it-1).value().rgba(); + } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop + { + mColorBuffer[i] = it.value().rgba(); + } else // position is in between stops (or on an intermediate stop), interpolate color + { + QMap::const_iterator high = it; + QMap::const_iterator low = it-1; + double t = (position-low.key())/(high.key()-low.key()); // interpolation factor 0..1 + switch (mColorInterpolation) + { + case ciRGB: + { + if (useAlpha) + { + const int alpha = (1-t)*low.value().alpha() + t*high.value().alpha(); + const float alphaPremultiplier = alpha/255.0f; // since we use QImage::Format_ARGB32_Premultiplied + mColorBuffer[i] = qRgba(((1-t)*low.value().red() + t*high.value().red())*alphaPremultiplier, + ((1-t)*low.value().green() + t*high.value().green())*alphaPremultiplier, + ((1-t)*low.value().blue() + t*high.value().blue())*alphaPremultiplier, + alpha); + } else + { + mColorBuffer[i] = qRgb(((1-t)*low.value().red() + t*high.value().red()), + ((1-t)*low.value().green() + t*high.value().green()), + ((1-t)*low.value().blue() + t*high.value().blue())); + } + break; + } + case ciHSV: + { + QColor lowHsv = low.value().toHsv(); + QColor highHsv = high.value().toHsv(); + double hue = 0; + double hueDiff = highHsv.hueF()-lowHsv.hueF(); + if (hueDiff > 0.5) + hue = lowHsv.hueF() - t*(1.0-hueDiff); + else if (hueDiff < -0.5) + hue = lowHsv.hueF() + t*(1.0+hueDiff); + else + hue = lowHsv.hueF() + t*hueDiff; + if (hue < 0) hue += 1.0; + else if (hue >= 1.0) hue -= 1.0; + if (useAlpha) + { + const QRgb rgb = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + const float alpha = (1-t)*lowHsv.alphaF() + t*highHsv.alphaF(); + mColorBuffer[i] = qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha); + } + else + { + mColorBuffer[i] = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + } + break; + } + } + } + } + } else if (mColorStops.size() == 1) + { + const QRgb rgb = mColorStops.constBegin().value().rgb(); + const float alpha = mColorStops.constBegin().value().alphaF(); + mColorBuffer.fill(qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha)); + } else // mColorStops is empty, fill color buffer with black + { + mColorBuffer.fill(qRgb(0, 0, 0)); + } + mColorBufferInvalidated = false; +} +/* end of 'src/colorgradient.cpp' */ + + +/* including file 'src/selectiondecorator-bracket.cpp', size 12313 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecoratorBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecoratorBracket + \brief A selection decorator which draws brackets around each selected data segment + + Additionally to the regular highlighting of selected segments via color, fill and scatter style, + this \ref QCPSelectionDecorator subclass draws markers at the begin and end of each selected data + segment of the plottable. + + The shape of the markers can be controlled with \ref setBracketStyle, \ref setBracketWidth and + \ref setBracketHeight. The color/fill can be controlled with \ref setBracketPen and \ref + setBracketBrush. + + To introduce custom bracket styles, it is only necessary to sublcass \ref + QCPSelectionDecoratorBracket and reimplement \ref drawBracket. The rest will be managed by the + base class. +*/ + +/*! + Creates a new QCPSelectionDecoratorBracket instance with default values. +*/ +QCPSelectionDecoratorBracket::QCPSelectionDecoratorBracket() : + mBracketPen(QPen(Qt::black)), + mBracketBrush(Qt::NoBrush), + mBracketWidth(5), + mBracketHeight(50), + mBracketStyle(bsSquareBracket), + mTangentToData(false), + mTangentAverage(2) +{ + +} + +QCPSelectionDecoratorBracket::~QCPSelectionDecoratorBracket() +{ +} + +/*! + Sets the pen that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketPen(const QPen &pen) +{ + mBracketPen = pen; +} + +/*! + Sets the brush that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketBrush(const QBrush &brush) +{ + mBracketBrush = brush; +} + +/*! + Sets the width of the drawn bracket. The width dimension is always parallel to the key axis of + the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketWidth(int width) +{ + mBracketWidth = width; +} + +/*! + Sets the height of the drawn bracket. The height dimension is always perpendicular to the key axis + of the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketHeight(int height) +{ + mBracketHeight = height; +} + +/*! + Sets the shape that the bracket/marker will have. + + \see setBracketWidth, setBracketHeight +*/ +void QCPSelectionDecoratorBracket::setBracketStyle(QCPSelectionDecoratorBracket::BracketStyle style) +{ + mBracketStyle = style; +} + +/*! + Sets whether the brackets will be rotated such that they align with the slope of the data at the + position that they appear in. + + For noisy data, it might be more visually appealing to average the slope over multiple data + points. This can be configured via \ref setTangentAverage. +*/ +void QCPSelectionDecoratorBracket::setTangentToData(bool enabled) +{ + mTangentToData = enabled; +} + +/*! + Controls over how many data points the slope shall be averaged, when brackets shall be aligned + with the data (if \ref setTangentToData is true). + + From the position of the bracket, \a pointCount points towards the selected data range will be + taken into account. The smallest value of \a pointCount is 1, which is effectively equivalent to + disabling \ref setTangentToData. +*/ +void QCPSelectionDecoratorBracket::setTangentAverage(int pointCount) +{ + mTangentAverage = pointCount; + if (mTangentAverage < 1) + mTangentAverage = 1; +} + +/*! + Draws the bracket shape with \a painter. The parameter \a direction is either -1 or 1 and + indicates whether the bracket shall point to the left or the right (i.e. is a closing or opening + bracket, respectively). + + The passed \a painter already contains all transformations that are necessary to position and + rotate the bracket appropriately. Painting operations can be performed as if drawing upright + brackets on flat data with horizontal key axis, with (0, 0) being the center of the bracket. + + If you wish to sublcass \ref QCPSelectionDecoratorBracket in order to provide custom bracket + shapes (see \ref QCPSelectionDecoratorBracket::bsUserStyle), this is the method you should + reimplement. +*/ +void QCPSelectionDecoratorBracket::drawBracket(QCPPainter *painter, int direction) const +{ + switch (mBracketStyle) + { + case bsSquareBracket: + { + painter->drawLine(QLineF(mBracketWidth*direction, -mBracketHeight*0.5, 0, -mBracketHeight*0.5)); + painter->drawLine(QLineF(mBracketWidth*direction, mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + break; + } + case bsHalfEllipse: + { + painter->drawArc(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight, -90*16, -180*16*direction); + break; + } + case bsEllipse: + { + painter->drawEllipse(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight); + break; + } + case bsPlus: + { + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(-mBracketWidth*0.5, 0, mBracketWidth*0.5, 0)); + break; + } + default: + { + qDebug() << Q_FUNC_INFO << "unknown/custom bracket style can't be handeld by default implementation:" << static_cast(mBracketStyle); + break; + } + } +} + +/*! + Draws the bracket decoration on the data points at the begin and end of each selected data + segment given in \a seletion. + + It uses the method \ref drawBracket to actually draw the shapes. + + \seebaseclassmethod +*/ +void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + if (!mPlottable || selection.isEmpty()) return; + + if (QCPPlottableInterface1D *interface1d = mPlottable->interface1D()) + { + foreach (const QCPDataRange &dataRange, selection.dataRanges()) + { + // determine position and (if tangent mode is enabled) angle of brackets: + int openBracketDir = (mPlottable->keyAxis() && !mPlottable->keyAxis()->rangeReversed()) ? 1 : -1; + int closeBracketDir = -openBracketDir; + QPointF openBracketPos = getPixelCoordinates(interface1d, dataRange.begin()); + QPointF closeBracketPos = getPixelCoordinates(interface1d, dataRange.end()-1); + double openBracketAngle = 0; + double closeBracketAngle = 0; + if (mTangentToData) + { + openBracketAngle = getTangentAngle(interface1d, dataRange.begin(), openBracketDir); + closeBracketAngle = getTangentAngle(interface1d, dataRange.end()-1, closeBracketDir); + } + // draw opening bracket: + QTransform oldTransform = painter->transform(); + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(openBracketPos); + painter->rotate(openBracketAngle/M_PI*180.0); + drawBracket(painter, openBracketDir); + painter->setTransform(oldTransform); + // draw closing bracket: + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(closeBracketPos); + painter->rotate(closeBracketAngle/M_PI*180.0); + drawBracket(painter, closeBracketDir); + painter->setTransform(oldTransform); + } + } +} + +/*! \internal + + If \ref setTangentToData is enabled, brackets need to be rotated according to the data slope. + This method returns the angle in radians by which a bracket at the given \a dataIndex must be + rotated. + + The parameter \a direction must be set to either -1 or 1, representing whether it is an opening + or closing bracket. Since for slope calculation multiple data points are required, this defines + the direction in which the algorithm walks, starting at \a dataIndex, to average those data + points. (see \ref setTangentToData and \ref setTangentAverage) + + \a interface1d is the interface to the plottable's data which is used to query data coordinates. +*/ +double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const +{ + if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->dataCount()) + return 0; + direction = direction < 0 ? -1 : 1; // enforce direction is either -1 or 1 + + // how many steps we can actually go from index in the given direction without exceeding data bounds: + int averageCount; + if (direction < 0) + averageCount = qMin(mTangentAverage, dataIndex); + else + averageCount = qMin(mTangentAverage, interface1d->dataCount()-1-dataIndex); + qDebug() << averageCount; + // calculate point average of averageCount points: + QVector points(averageCount); + QPointF pointsAverage; + int currentIndex = dataIndex; + for (int i=0; ikeyAxis(); + QCPAxis *valueAxis = mPlottable->valueAxis(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(0, 0); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))); + else + return QPointF(valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex)), keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex))); +} +/* end of 'src/selectiondecorator-bracket.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47584 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisRect + \brief Holds multiple axes and arranges them in a rectangular shape. + + This class represents an axis rect, a rectangular area that is bounded on all sides with an + arbitrary number of axes. + + Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the + layout system allows to have multiple axis rects, e.g. arranged in a grid layout + (QCustomPlot::plotLayout). + + By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be + accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. + If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be + invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref + addAxes. To remove an axis, use \ref removeAxis. + + The axis rect layerable itself only draws a background pixmap or color, if specified (\ref + setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an + explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be + placed on other layers, independently of the axis rect. + + Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref + insetLayout and can be used to have other layout elements (or even other layouts with multiple + elements) hovering inside the axis rect. + + If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The + behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel + is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable + via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are + only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref + QCP::iRangeZoom. + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed + line on the far left indicates the viewport/widget border.
+*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const + + Returns the inset layout of this axis rect. It can be used to place other layout elements (or + even layouts with multiple other elements) inside/on top of an axis rect. + + \see QCPLayoutInset +*/ + +/*! \fn int QCPAxisRect::left() const + + Returns the pixel position of the left border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::right() const + + Returns the pixel position of the right border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::top() const + + Returns the pixel position of the top border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::bottom() const + + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::width() const + + Returns the pixel width of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::height() const + + Returns the pixel height of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QSize QCPAxisRect::size() const + + Returns the pixel size of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topLeft() const + + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, + so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topRight() const + + Returns the top right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomLeft() const + + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomRight() const + + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::center() const + + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPAxisRect instance and sets default values. An axis is added for each of the four + sides, the top and right axes are set invisible initially. +*/ +QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : + QCPLayoutElement(parentPlot), + mBackgroundBrush(Qt::NoBrush), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mInsetLayout(new QCPLayoutInset), + mRangeDrag(Qt::Horizontal|Qt::Vertical), + mRangeZoom(Qt::Horizontal|Qt::Vertical), + mRangeZoomFactorHorz(0.85), + mRangeZoomFactorVert(0.85), + mDragging(false), + mIsScaleRight(false) +{ + mInsetLayout->initializeParentPlot(mParentPlot); + mInsetLayout->setParentLayerable(this); + mInsetLayout->setParent(this); + + setMinimumSize(50, 50); + setMinimumMargins(QMargins(15, 15, 15, 15)); + mAxes.insert(QCPAxis::atLeft, QList()); + mAxes.insert(QCPAxis::atRight, QList()); + mAxes.insert(QCPAxis::atTop, QList()); + mAxes.insert(QCPAxis::atBottom, QList()); + + if (setupDefaultAxes) + { + QCPAxis *xAxis = addAxis(QCPAxis::atBottom); + QCPAxis *yAxis = addAxis(QCPAxis::atLeft); + QCPAxis *xAxis2 = addAxis(QCPAxis::atTop); + QCPAxis *yAxis2 = addAxis(QCPAxis::atRight); + setRangeDragAxes(xAxis, yAxis); + setRangeZoomAxes(xAxis, yAxis); + xAxis2->setVisible(false); + yAxis2->setVisible(false); + xAxis->grid()->setVisible(true); + yAxis->grid()->setVisible(true); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + xAxis2->grid()->setZeroLinePen(Qt::NoPen); + yAxis2->grid()->setZeroLinePen(Qt::NoPen); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + } +} + +QCPAxisRect::~QCPAxisRect() +{ + delete mInsetLayout; + mInsetLayout = 0; + + QList axesList = axes(); + for (int i=0; i ax(mAxes.value(type)); + if (index >= 0 && index < ax.size()) + { + return ax.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; + return 0; + } +} + +/*! + Returns all axes on the axis rect sides specified with \a types. + + \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of + multiple sides. + + \see axis +*/ +QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << mAxes.value(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << mAxes.value(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << mAxes.value(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << mAxes.value(QCPAxis::atBottom); + return result; +} + +/*! \overload + + Returns all axes of this axis rect. +*/ +QList QCPAxisRect::axes() const +{ + QList result; + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + result << it.value(); + } + return result; +} + +/*! + Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a + new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to + remove an axis, use \ref removeAxis instead of deleting it manually. + + You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was + previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership + of the axis, so you may not delete it afterwards. Further, the \a axis must have been created + with this axis rect as parent and with the same axis type as specified in \a type. If this is not + the case, a debug output is generated, the axis is not added, and the method returns 0. + + This method can not be used to move \a axis between axis rects. The same \a axis instance must + not be added multiple times to the same or different axis rects. + + If an axis rect side already contains one or more axes, the lower and upper endings of the new + axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref + QCPLineEnding::esHalfBar. + + \see addAxes, setupFullAxesBox +*/ +QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) +{ + QCPAxis *newAxis = axis; + if (!newAxis) + { + newAxis = new QCPAxis(this, type); + } else // user provided existing axis instance, do some sanity checks + { + if (newAxis->axisType() != type) + { + qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter"; + return 0; + } + if (newAxis->axisRect() != this) + { + qDebug() << Q_FUNC_INFO << "passed axis doesn't have this axis rect as parent axis rect"; + return 0; + } + if (axes().contains(newAxis)) + { + qDebug() << Q_FUNC_INFO << "passed axis is already owned by this axis rect"; + return 0; + } + } + if (mAxes[type].size() > 0) // multiple axes on one side, add half-bar axis ending to additional axes with offset + { + bool invert = (type == QCPAxis::atRight) || (type == QCPAxis::atBottom); + newAxis->setLowerEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, !invert)); + newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); + } + mAxes[type].append(newAxis); + + // reset convenience axis pointers on parent QCustomPlot if they are unset: + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + switch (type) + { + case QCPAxis::atBottom: { if (!mParentPlot->xAxis) mParentPlot->xAxis = newAxis; break; } + case QCPAxis::atLeft: { if (!mParentPlot->yAxis) mParentPlot->yAxis = newAxis; break; } + case QCPAxis::atTop: { if (!mParentPlot->xAxis2) mParentPlot->xAxis2 = newAxis; break; } + case QCPAxis::atRight: { if (!mParentPlot->yAxis2) mParentPlot->yAxis2 = newAxis; break; } + } + } + + return newAxis; +} + +/*! + Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an + or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. + + Returns a list of the added axes. + + \see addAxis, setupFullAxesBox +*/ +QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << addAxis(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << addAxis(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << addAxis(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << addAxis(QCPAxis::atBottom); + return result; +} + +/*! + Removes the specified \a axis from the axis rect and deletes it. + + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. + + \see addAxis +*/ +bool QCPAxisRect::removeAxis(QCPAxis *axis) +{ + // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers: + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(axis)) + { + if (it.value().first() == axis && it.value().size() > 1) // if removing first axis, transfer axis offset to the new first axis (which at this point is the second axis, if it exists) + it.value()[1]->setOffset(axis->offset()); + mAxes[it.key()].removeOne(axis); + if (qobject_cast(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot) + parentPlot()->axisRemoved(axis); + delete axis; + return true; + } + } + qDebug() << Q_FUNC_INFO << "Axis isn't in axis rect:" << reinterpret_cast(axis); + return false; +} + +/*! + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + All axes of this axis rect will have their range zoomed accordingly. If you only wish to zoom + specific axes, use the overloaded version of this method. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect) +{ + zoom(pixelRect, axes()); +} + +/*! \overload + + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + Only the axes passed in \a affectedAxes will have their ranges zoomed accordingly. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect, const QList &affectedAxes) +{ + foreach (QCPAxis *axis, affectedAxes) + { + if (!axis) + { + qDebug() << Q_FUNC_INFO << "a passed axis was zero"; + continue; + } + QCPRange pixelRange; + if (axis->orientation() == Qt::Horizontal) + pixelRange = QCPRange(pixelRect.left(), pixelRect.right()); + else + pixelRange = QCPRange(pixelRect.top(), pixelRect.bottom()); + axis->setRange(axis->pixelToCoord(pixelRange.lower), axis->pixelToCoord(pixelRange.upper)); + } +} + +/*! + Convenience function to create an axis on each side that doesn't have any axes yet and set their + visibility to true. Further, the top/right axes are assigned the following properties of the + bottom/left axes: + + \li range (\ref QCPAxis::setRange) + \li range reversed (\ref QCPAxis::setRangeReversed) + \li scale type (\ref QCPAxis::setScaleType) + \li tick visibility (\ref QCPAxis::setTicks) + \li number format (\ref QCPAxis::setNumberFormat) + \li number precision (\ref QCPAxis::setNumberPrecision) + \li tick count of ticker (\ref QCPAxisTicker::setTickCount) + \li tick origin of ticker (\ref QCPAxisTicker::setTickOrigin) + + Tick label visibility (\ref QCPAxis::setTickLabels) of the right and top axes are set to false. + + If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom + and left axes are connected to the \ref QCPAxis::setRange slots of the top and right axes. +*/ +void QCPAxisRect::setupFullAxesBox(bool connectRanges) +{ + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + if (axisCount(QCPAxis::atBottom) == 0) + xAxis = addAxis(QCPAxis::atBottom); + else + xAxis = axis(QCPAxis::atBottom); + + if (axisCount(QCPAxis::atLeft) == 0) + yAxis = addAxis(QCPAxis::atLeft); + else + yAxis = axis(QCPAxis::atLeft); + + if (axisCount(QCPAxis::atTop) == 0) + xAxis2 = addAxis(QCPAxis::atTop); + else + xAxis2 = axis(QCPAxis::atTop); + + if (axisCount(QCPAxis::atRight) == 0) + yAxis2 = addAxis(QCPAxis::atRight); + else + yAxis2 = axis(QCPAxis::atRight); + + xAxis->setVisible(true); + yAxis->setVisible(true); + xAxis2->setVisible(true); + yAxis2->setVisible(true); + xAxis2->setTickLabels(false); + yAxis2->setTickLabels(false); + + xAxis2->setRange(xAxis->range()); + xAxis2->setRangeReversed(xAxis->rangeReversed()); + xAxis2->setScaleType(xAxis->scaleType()); + xAxis2->setTicks(xAxis->ticks()); + xAxis2->setNumberFormat(xAxis->numberFormat()); + xAxis2->setNumberPrecision(xAxis->numberPrecision()); + xAxis2->ticker()->setTickCount(xAxis->ticker()->tickCount()); + xAxis2->ticker()->setTickOrigin(xAxis->ticker()->tickOrigin()); + + yAxis2->setRange(yAxis->range()); + yAxis2->setRangeReversed(yAxis->rangeReversed()); + yAxis2->setScaleType(yAxis->scaleType()); + yAxis2->setTicks(yAxis->ticks()); + yAxis2->setNumberFormat(yAxis->numberFormat()); + yAxis2->setNumberPrecision(yAxis->numberPrecision()); + yAxis2->ticker()->setTickCount(yAxis->ticker()->tickCount()); + yAxis2->ticker()->setTickOrigin(yAxis->ticker()->tickOrigin()); + + if (connectRanges) + { + connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); + connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); + } +} + +/*! + Returns a list of all the plottables that are associated with this axis rect. + + A plottable is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see graphs, items +*/ +QList QCPAxisRect::plottables() const +{ + // Note: don't append all QCPAxis::plottables() into a list, because we might get duplicate entries + QList result; + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis()->axisRect() == this || mParentPlot->mPlottables.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that are associated with this axis rect. + + A graph is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see plottables, items +*/ +QList QCPAxisRect::graphs() const +{ + // Note: don't append all QCPAxis::graphs() into a list, because we might get duplicate entries + QList result; + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis()->axisRect() == this || mParentPlot->mGraphs.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis rect. + + An item is considered associated with an axis rect if any of its positions has key or value axis + set to an axis that is in this axis rect, or if any of its positions has \ref + QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref + QCPAbstractItem::setClipAxisRect) is set to this axis rect. + + \see plottables, graphs +*/ +QList QCPAxisRect::items() const +{ + // Note: don't just append all QCPAxis::items() into a list, because we might get duplicate entries + // and miss those items that have this axis rect as clipAxisRect. + QList result; + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + if (mParentPlot->mItems.at(itemId)->clipAxisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + continue; + } + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdaxisRect() == this || + positions.at(posId)->keyAxis()->axisRect() == this || + positions.at(posId)->valueAxis()->axisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + This method is called automatically upon replot and doesn't need to be called by users of + QCPAxisRect. + + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), + and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its + QCPInsetLayout::update function. + + \seebaseclassmethod +*/ +void QCPAxisRect::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + switch (phase) + { + case upPreparation: + { + QList allAxes = axes(); + for (int i=0; isetupTickVectors(); + break; + } + case upLayout: + { + mInsetLayout->setOuterRect(rect()); + break; + } + default: break; + } + + // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): + mInsetLayout->update(phase); +} + +/* inherits documentation from base class */ +QList QCPAxisRect::elements(bool recursive) const +{ + QList result; + if (mInsetLayout) + { + result << mInsetLayout; + if (recursive) + result << mInsetLayout->elements(recursive); + } + return result; +} + +/* inherits documentation from base class */ +void QCPAxisRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPAxisRect::draw(QCPPainter *painter) +{ + drawBackground(painter); +} + +/*! + Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the + axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect + backgrounds are usually drawn below everything else. + + For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio + is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref + setBackground(const QBrush &brush). + + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) +*/ +void QCPAxisRect::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! \overload + + Sets \a brush as the background brush. The axis rect background will be filled with this brush. + Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds + are usually drawn below everything else. + + The brush will be drawn before (under) any background pixmap, which may be specified with \ref + setBackground(const QPixmap &pm). + + To disable drawing of a background brush, set \a brush to Qt::NoBrush. + + \see setBackground(const QPixmap &pm) +*/ +void QCPAxisRect::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled + is set to true, you may control whether and how the aspect ratio of the original pixmap is + preserved with \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the axis rect dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to + define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. + \see setBackground, setBackgroundScaled +*/ +void QCPAxisRect::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the range drag axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeDragAxes to retrieve a list with all set axes). + + \see setRangeDragAxes +*/ +QCPAxis *QCPAxisRect::rangeDragAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeDragHorzAxis.isEmpty() ? 0 : mRangeDragHorzAxis.first().data(); + else + return mRangeDragVertAxis.isEmpty() ? 0 : mRangeDragVertAxis.first().data(); +} + +/*! + Returns the range zoom axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeZoomAxes to retrieve a list with all set axes). + + \see setRangeZoomAxes +*/ +QCPAxis *QCPAxisRect::rangeZoomAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeZoomHorzAxis.isEmpty() ? 0 : mRangeZoomHorzAxis.first().data(); + else + return mRangeZoomVertAxis.isEmpty() ? 0 : mRangeZoomVertAxis.first().data(); +} + +/*! + Returns all range drag axes of the \a orientation provided. + + \see rangeZoomAxis, setRangeZoomAxes +*/ +QList QCPAxisRect::rangeDragAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + for (int i=0; i QCPAxisRect::rangeZoomAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + for (int i=0; iQt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeDrag to enable the range dragging interaction. + + \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag +*/ +void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) +{ + mRangeDrag = orientations; +} + +/*! + Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation + corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, + QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical + axis is the left axis (yAxis). + + To disable range zooming entirely, pass 0 as \a orientations or remove \ref QCP::iRangeZoom from \ref + QCustomPlot::setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeZoom to enable the range zooming interaction. + + \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag +*/ +void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) +{ + mRangeZoom = orientations; +} + +/*! \overload + + Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on + the QCustomPlot widget. Pass 0 if no axis shall be dragged in the respective orientation. + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to dragging interactions. + + \see setRangeZoomAxes +*/ +void QCPAxisRect::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical dragging. The drag + orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. drag a vertically oriented axis with a horizontal drag + motion, use the overload taking two separate lists for horizontal and vertical dragging. +*/ +void QCPAxisRect::setRangeDragAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical dragging, and + define specifically which axis reacts to which drag orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeDragAxes(QList horizontal, QList vertical) +{ + mRangeDragHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeDragVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on + the QCustomPlot widget. Pass 0 if no axis shall be zoomed in the respective orientation. + + The two axes can be zoomed with different strengths, when different factors are passed to \ref + setRangeZoomFactor(double horizontalFactor, double verticalFactor). + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to zooming interactions. + + \see setRangeDragAxes +*/ +void QCPAxisRect::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical range zooming. The + zoom orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. zoom a vertically oriented axis with a horizontal zoom + interaction, use the overload taking two separate lists for horizontal and vertical zooming. +*/ +void QCPAxisRect::setRangeZoomAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical zooming, and + define specifically which axis reacts to which zoom orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeZoomAxes(QList horizontal, QList vertical) +{ + mRangeZoomHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeZoomVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with + \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to + let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal + and which is vertical, can be set with \ref setRangeZoomAxes. + + When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) + will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the + same scrolling direction will zoom out. +*/ +void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFactor) +{ + mRangeZoomFactorHorz = horizontalFactor; + mRangeZoomFactorVert = verticalFactor; +} + +/*! \overload + + Sets both the horizontal and vertical zoom \a factor. +*/ +void QCPAxisRect::setRangeZoomFactor(double factor) +{ + mRangeZoomFactorHorz = factor; + mRangeZoomFactorVert = factor; +} + +/*! \internal + + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a + pixmap. + + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an + according filling inside the axis rect with the provided \a painter. + + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the axis rect with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::drawBackground(QCPPainter *painter) +{ + // draw background fill: + if (mBackgroundBrush != Qt::NoBrush) + painter->fillRect(mRect, mBackgroundBrush); + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mRect.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); + } + } +} + +/*! \internal + + This function makes sure multiple axes on the side specified with \a type don't collide, but are + distributed according to their respective space requirement (QCPAxis::calculateMargin). + + It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the + one with index zero. + + This function is called by \ref calculateAutoMargin. +*/ +void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) +{ + const QList axesList = mAxes.value(type); + if (axesList.isEmpty()) + return; + + bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false + for (int i=1; ioffset() + axesList.at(i-1)->calculateMargin(); + if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible) + { + if (!isFirstVisible) + offset += axesList.at(i)->tickLengthIn(); + isFirstVisible = false; + } + axesList.at(i)->setOffset(offset); + } +} + +/* inherits documentation from base class */ +int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) +{ + if (!mAutoMargins.testFlag(side)) + qDebug() << Q_FUNC_INFO << "Called with side that isn't specified as auto margin"; + + updateAxesOffset(QCPAxis::marginSideToAxisType(side)); + + // note: only need to look at the last (outer most) axis to determine the total margin, due to updateAxisOffset call + const QList axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); + if (axesList.size() > 0) + return axesList.last()->offset() + axesList.last()->calculateMargin(); + else + return 0; +} + +/*! \internal + + Reacts to a change in layout to potentially set the convenience axis pointers \ref + QCustomPlot::xAxis, \ref QCustomPlot::yAxis, etc. of the parent QCustomPlot to the respective + axes of this axis rect. This is only done if the respective convenience pointer is currently zero + and if there is no QCPAxisRect at position (0, 0) of the plot layout. + + This automation makes it simpler to replace the main axis rect with a newly created one, without + the need to manually reset the convenience pointers. +*/ +void QCPAxisRect::layoutChanged() +{ + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + if (axisCount(QCPAxis::atBottom) > 0 && !mParentPlot->xAxis) + mParentPlot->xAxis = axis(QCPAxis::atBottom); + if (axisCount(QCPAxis::atLeft) > 0 && !mParentPlot->yAxis) + mParentPlot->yAxis = axis(QCPAxis::atLeft); + if (axisCount(QCPAxis::atTop) > 0 && !mParentPlot->xAxis2) + mParentPlot->xAxis2 = axis(QCPAxis::atTop); + if (axisCount(QCPAxis::atRight) > 0 && !mParentPlot->yAxis2) + mParentPlot->yAxis2 = axis(QCPAxis::atRight); + } +} + +/*! \internal + + Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is + pressed, the range dragging interaction is initialized (the actual range manipulation happens in + the \ref mouseMoveEvent). + + The mDragging flag is set to true and some anchor points are set that are needed to determine the + distance the mouse was dragged in the mouse move/release events later. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + mDragStartHorzRange.clear(); + for (int i=0; irange()); + mDragStartVertRange.clear(); + for (int i=0; irange()); + } + } +} + +/*! \internal + + Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a + preceding \ref mousePressEvent, the range is moved accordingly. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + // Mouse range dragging interaction: + if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + + if (mRangeDrag.testFlag(Qt::Horizontal)) + { + for (int i=0; i= mDragStartHorzRange.size()) + break; + + //< Drag + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower+diff, mDragStartHorzRange.at(i).upper+diff); + + if(diff != 0) + { + mIsDragMove = true; + } + } + //< Scale + else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower*diff, mDragStartHorzRange.at(i).upper*diff); + if(diff != 0) + { + mIsDragMove = true; + } + } + } + } + + if (mRangeDrag.testFlag(Qt::Vertical)) + { + for (int i=0; i= mDragStartVertRange.size()) + break; + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower+diff, mDragStartVertRange.at(i).upper+diff); + } else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower*diff, mDragStartVertRange.at(i).upper*diff); + } + } + } + + if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot + { + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } + + } +} + +/* inherits documentation from base class */ +void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + + //< Note: update His Date + + if(mIsDragMove) + { + emit rangeDraged(); + mIsDragMove = false; + } + + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the + ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of + the scaling operation is the current cursor position inside the axis rect. The scaling factor is + dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural + zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. + + Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse + wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be + multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as + exponent of the range zoom factor. This takes care of the wheel direction automatically, by + inverting the factor, when the wheel step is negative (f^-1 = 1/f). +*/ +void QCPAxisRect::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) + { + if (mRangeZoom != 0) + { + double factor; + double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + if (mRangeZoom.testFlag(Qt::Horizontal)) + { + factor = qPow(mRangeZoomFactorHorz, wheelSteps); + for (int i=0; iscaleRange(factor,mRangeZoomHorzAxis.at(i)->range().upper); + } + else + { + mRangeZoomHorzAxis.at(i)->scaleRange(factor, mRangeZoomHorzAxis.at(i)->pixelToCoord(event->pos().x())); + } + emit rangeScaled(); + } + } + } + if (mRangeZoom.testFlag(Qt::Vertical)) + { + factor = qPow(mRangeZoomFactorVert, wheelSteps); + for (int i=0; iscaleRange(factor, mRangeZoomVertAxis.at(i)->pixelToCoord(event->pos().y())); + } + } + mParentPlot->replot(); + } + } +} +/* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-legend.cpp', size 31097 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractLegendItem + \brief The abstract base class for all entries in a QCPLegend. + + It defines a very basic interface for entries in a QCPLegend. For representing plottables in the + legend, the subclass \ref QCPPlottableLegendItem is more suitable. + + Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry + that's not even associated with a plottable). + + You must implement the following pure virtual functions: + \li \ref draw (from QCPLayerable) + + You inherit the following members you may use: + + + + + + + + +
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
+*/ + +/* start of documentation of signals */ + +/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) + + This signal is emitted when the selection state of this legend item has changed, either by user + interaction or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not + cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. +*/ +QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : + QCPLayoutElement(parent->parentPlot()), + mParentLegend(parent), + mFont(parent->font()), + mTextColor(parent->textColor()), + mSelectedFont(parent->selectedFont()), + mSelectedTextColor(parent->selectedTextColor()), + mSelectable(true), + mSelected(false) +{ + setLayer(QLatin1String("legend")); + setMargins(QMargins(0, 0, 0, 0)); +} + +/*! + Sets the default font of this specific legend item to \a font. + + \see setTextColor, QCPLegend::setFont +*/ +void QCPAbstractLegendItem::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the default text color of this specific legend item to \a color. + + \see setFont, QCPLegend::setTextColor +*/ +void QCPAbstractLegendItem::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + When this legend item is selected, \a font is used to draw generic text, instead of the normal + font set with \ref setFont. + + \see setFont, QCPLegend::setSelectedFont +*/ +void QCPAbstractLegendItem::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + When this legend item is selected, \a color is used to draw generic text, instead of the normal + color set with \ref setTextColor. + + \see setTextColor, QCPLegend::setSelectedTextColor +*/ +void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether this specific legend item is selectable. + + \see setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this specific legend item is selected. + + It is possible to set the selection state of this item by calling this function directly, even if + setSelectable is set to false. + + \see setSelectableParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (!mParentPlot) return -1; + if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) + return -1; + + if (mRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegendItems); +} + +/* inherits documentation from base class */ +QRect QCPAbstractLegendItem::clipRect() const +{ + return mOuterRect; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableLegendItem + \brief A legend item representing a plottable with an icon and the plottable name. + + This is the standard legend item for plottables. It displays an icon of the plottable next to the + plottable name. The icon is drawn by the respective plottable itself (\ref + QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. + For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the + middle. + + Legend items of this type are always associated with one plottable (retrievable via the + plottable() function and settable with the constructor). You may change the font of the plottable + name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref + QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. + + The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend + creates/removes legend items of this type. + + Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of + QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout + interface, QCPLegend has specialized functions for handling legend items conveniently, see the + documentation of \ref QCPLegend. +*/ + +/*! + Creates a new legend item associated with \a plottable. + + Once it's created, it can be added to the legend via \ref QCPLegend::addItem. + + A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref + QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. +*/ +QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : + QCPAbstractLegendItem(parent), + mPlottable(plottable) +{ + setAntialiased(false); +} + +/*! \internal + + Returns the pen that shall be used to draw the icon border, taking into account the selection + state of this item. +*/ +QPen QCPPlottableLegendItem::getIconBorderPen() const +{ + return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); +} + +/*! \internal + + Returns the text color that shall be used to draw text, taking into account the selection state + of this item. +*/ +QColor QCPPlottableLegendItem::getTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + +/*! \internal + + Returns the font that shall be used to draw text, taking into account the selection state of this + item. +*/ +QFont QCPPlottableLegendItem::getFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Draws the item with \a painter. The size and position of the drawn legend item is defined by the + parent layout (typically a \ref QCPLegend) and the \ref minimumOuterSizeHint and \ref + maximumOuterSizeHint of this legend item. +*/ +void QCPPlottableLegendItem::draw(QCPPainter *painter) +{ + if (!mPlottable) return; + painter->setFont(getFont()); + painter->setPen(QPen(getTextColor())); + QSizeF iconSize = mParentLegend->iconSize(); + QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); + QRectF iconRect(mRect.topLeft(), iconSize); + int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops + painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->desc()); + // draw icon: + painter->save(); + painter->setClipRect(iconRect, Qt::IntersectClip); + mPlottable->drawLegendIcon(painter, iconRect); + painter->restore(); + // draw icon border: + if (getIconBorderPen().style() != Qt::NoPen) + { + painter->setPen(getIconBorderPen()); + painter->setBrush(Qt::NoBrush); + int halfPen = qCeil(painter->pen().widthF()*0.5)+1; + painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped + painter->drawRect(iconRect); + } +} + +/*! \internal + + Calculates and returns the size of this item. This includes the icon, the text and the padding in + between. + + \seebaseclassmethod +*/ +QSize QCPPlottableLegendItem::minimumOuterSizeHint() const +{ + if (!mPlottable) return QSize(); + QSize result(0, 0); + QRect textRect; + QFontMetrics fontMetrics(getFont()); + QSize iconSize = mParentLegend->iconSize(); + textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); + result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); + result.setHeight(qMax(textRect.height(), iconSize.height())); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLegend +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLegend + \brief Manages a legend inside a QCustomPlot. + + A legend is a small box somewhere in the plot which lists plottables with their name and icon. + + A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the + plottable, for which a legend item shall be created. In the case of the main legend (\ref + QCustomPlot::legend), simply adding plottables to the plot while \ref + QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding + legend items. The legend item associated with a certain plottable can be removed with \ref + QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and + manipulate legend items directly: \ref item, \ref itemWithPlottable, \ref itemCount, \ref + addItem, \ref removeItem, etc. + + Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref + QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement + "QCPLayoutElements" which are placed in the grid layout of the legend. \ref QCPLegend only adds + an interface specialized for handling child elements of type \ref QCPAbstractLegendItem, as + mentioned above. In principle, any other layout elements may also be added to a legend via the + normal \ref QCPLayoutGrid interface. See the special page about \link thelayoutsystem The Layout + System\endlink for examples on how to add other elements to the legend and move it outside the axis + rect. + + Use the methods \ref setFillOrder and \ref setWrap inherited from \ref QCPLayoutGrid to control + in which order (column first or row first) the legend is filled up when calling \ref addItem, and + at which column or row wrapping occurs. + + By default, every QCustomPlot has one legend (\ref QCustomPlot::legend) which is placed in the + inset layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another + position inside the axis rect, use the methods of the \ref QCPLayoutInset. To move the legend + outside of the axis rect, place it anywhere else with the \ref QCPLayout/\ref QCPLayoutElement + interface. +*/ + +/* start of documentation of signals */ + +/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); + + This signal is emitted when the selection state of this legend has changed. + + \see setSelectedParts, setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs a new QCPLegend instance with default values. + + Note that by default, QCustomPlot already contains a legend ready to be used as \ref + QCustomPlot::legend +*/ +QCPLegend::QCPLegend() +{ + setFillOrder(QCPLayoutGrid::foRowsFirst); + setWrap(0); + + setRowSpacing(3); + setColumnSpacing(8); + setMargins(QMargins(7, 5, 7, 4)); + setAntialiased(false); + setIconSize(32, 18); + + setIconTextPadding(7); + + setSelectableParts(spLegendBox | spItems); + setSelectedParts(spNone); + + setBorderPen(QPen(Qt::black, 0)); + setSelectedBorderPen(QPen(Qt::blue, 2)); + setIconBorderPen(Qt::NoPen); + setSelectedIconBorderPen(QPen(Qt::blue, 2)); + setBrush(Qt::white); + setSelectedBrush(Qt::white); + setTextColor(Qt::black); + setSelectedTextColor(Qt::blue); +} + +QCPLegend::~QCPLegend() +{ + clearItems(); + if (qobject_cast(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot) + mParentPlot->legendRemoved(this); +} + +/* no doc for getter, see setSelectedParts */ +QCPLegend::SelectableParts QCPLegend::selectedParts() const +{ + // check whether any legend elements selected, if yes, add spItems to return value + bool hasSelectedItems = false; + for (int i=0; iselected()) + { + hasSelectedItems = true; + break; + } + } + if (hasSelectedItems) + return mSelectedParts | spItems; + else + return mSelectedParts & ~spItems; +} + +/*! + Sets the pen, the border of the entire legend is drawn with. +*/ +void QCPLegend::setBorderPen(const QPen &pen) +{ + mBorderPen = pen; +} + +/*! + Sets the brush of the legend background. +*/ +void QCPLegend::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will + use this font by default. However, a different font can be specified on a per-item-basis by + accessing the specific legend item. + + This function will also set \a font on all already existing legend items. + + \see QCPAbstractLegendItem::setFont +*/ +void QCPLegend::setFont(const QFont &font) +{ + mFont = font; + for (int i=0; isetFont(mFont); + } +} + +/*! + Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) + will use this color by default. However, a different colors can be specified on a per-item-basis + by accessing the specific legend item. + + This function will also set \a color on all already existing legend items. + + \see QCPAbstractLegendItem::setTextColor +*/ +void QCPLegend::setTextColor(const QColor &color) +{ + mTextColor = color; + for (int i=0; isetTextColor(color); + } +} + +/*! + Sets the size of legend icons. Legend items that draw an icon (e.g. a visual + representation of the graph) will use this size by default. +*/ +void QCPLegend::setIconSize(const QSize &size) +{ + mIconSize = size; +} + +/*! \overload +*/ +void QCPLegend::setIconSize(int width, int height) +{ + mIconSize.setWidth(width); + mIconSize.setHeight(height); +} + +/*! + Sets the horizontal space in pixels between the legend icon and the text next to it. + Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the + name of the graph) will use this space by default. +*/ +void QCPLegend::setIconTextPadding(int padding) +{ + mIconTextPadding = padding; +} + +/*! + Sets the pen used to draw a border around each legend icon. Legend items that draw an + icon (e.g. a visual representation of the graph) will use this pen by default. + + If no border is wanted, set this to \a Qt::NoPen. +*/ +void QCPLegend::setIconBorderPen(const QPen &pen) +{ + mIconBorderPen = pen; +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPLegend::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected + doesn't contain \ref spItems, those items become deselected. + + The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions + contains iSelectLegend. You only need to call this function when you wish to change the selection + state manually. + + This function can change the selection state of a part even when \ref setSelectableParts was set to a + value that actually excludes the part. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set + before, because there's no way to specify which exact items to newly select. Do this by calling + \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, + setSelectedFont +*/ +void QCPLegend::setSelectedParts(const SelectableParts &selected) +{ + SelectableParts newSelected = selected; + mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed + + if (mSelectedParts != newSelected) + { + if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that) + { + qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function"; + newSelected &= ~spItems; + } + if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems)) // spItems flag was unset, so clear item selection + { + for (int i=0; isetSelected(false); + } + } + mSelectedParts = newSelected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + When the legend box is selected, this pen is used to draw the border instead of the normal pen + set via \ref setBorderPen. + + \see setSelectedParts, setSelectableParts, setSelectedBrush +*/ +void QCPLegend::setSelectedBorderPen(const QPen &pen) +{ + mSelectedBorderPen = pen; +} + +/*! + Sets the pen legend items will use to draw their icon borders, when they are selected. + + \see setSelectedParts, setSelectableParts, setSelectedFont +*/ +void QCPLegend::setSelectedIconBorderPen(const QPen &pen) +{ + mSelectedIconBorderPen = pen; +} + +/*! + When the legend box is selected, this brush is used to draw the legend background instead of the normal brush + set via \ref setBrush. + + \see setSelectedParts, setSelectableParts, setSelectedBorderPen +*/ +void QCPLegend::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the default font that is used by legend items when they are selected. + + This function will also set \a font on all already existing legend items. + + \see setFont, QCPAbstractLegendItem::setSelectedFont +*/ +void QCPLegend::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; + for (int i=0; isetSelectedFont(font); + } +} + +/*! + Sets the default text color that is used by legend items when they are selected. + + This function will also set \a color on all already existing legend items. + + \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor +*/ +void QCPLegend::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; + for (int i=0; isetSelectedTextColor(color); + } +} + +/*! + Returns the item with index \a i. + + Note that the linear index depends on the current fill order (\ref setFillOrder). + + \see itemCount, addItem, itemWithPlottable +*/ +QCPAbstractLegendItem *QCPLegend::item(int index) const +{ + return qobject_cast(elementAt(index)); +} + +/*! + Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns 0. + + \see hasItemWithPlottable +*/ +QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + for (int i=0; i(item(i))) + { + if (pli->plottable() == plottable) + return pli; + } + } + return 0; +} + +/*! + Returns the number of items currently in the legend. + + Note that if empty cells are in the legend (e.g. by calling methods of the \ref QCPLayoutGrid + base class which allows creating empty cells), they are included in the returned count. + + \see item +*/ +int QCPLegend::itemCount() const +{ + return elementCount(); +} + +/*! + Returns whether the legend contains \a item. + + \see hasItemWithPlottable +*/ +bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const +{ + for (int i=0; iitem(i)) + return true; + } + return false; +} + +/*! + Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns false. + + \see itemWithPlottable +*/ +bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + return itemWithPlottable(plottable); +} + +/*! + Adds \a item to the legend, if it's not present already. The element is arranged according to the + current fill order (\ref setFillOrder) and wrapping (\ref setWrap). + + Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. + + The legend takes ownership of the item. + + \see removeItem, item, hasItem +*/ +bool QCPLegend::addItem(QCPAbstractLegendItem *item) +{ + return addElement(item); +} + +/*! \overload + + Removes the item with the specified \a index from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. Unlike \ref QCPLayoutGrid::removeAt, this method only removes + elements derived from \ref QCPAbstractLegendItem. + + \see itemCount, clearItems +*/ +bool QCPLegend::removeItem(int index) +{ + if (QCPAbstractLegendItem *ali = item(index)) + { + bool success = remove(ali); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; + } else + return false; +} + +/*! \overload + + Removes \a item from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. + + \see clearItems +*/ +bool QCPLegend::removeItem(QCPAbstractLegendItem *item) +{ + bool success = remove(item); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; +} + +/*! + Removes all items from the legend. +*/ +void QCPLegend::clearItems() +{ + for (int i=itemCount()-1; i>=0; --i) + removeItem(i); +} + +/*! + Returns the legend items that are currently selected. If no items are selected, + the list is empty. + + \see QCPAbstractLegendItem::setSelected, setSelectable +*/ +QList QCPLegend::selectedItems() const +{ + QList result; + for (int i=0; iselected()) + result.append(ali); + } + } + return result; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing main legend elements. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); +} + +/*! \internal + + Returns the pen used to paint the border of the legend, taking into account the selection state + of the legend box. +*/ +QPen QCPLegend::getBorderPen() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; +} + +/*! \internal + + Returns the brush used to paint the background of the legend, taking into account the selection + state of the legend box. +*/ +QBrush QCPLegend::getBrush() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush; +} + +/*! \internal + + Draws the legend box with the provided \a painter. The individual legend items are layerables + themselves, thus are drawn independently. +*/ +void QCPLegend::draw(QCPPainter *painter) +{ + // draw background rect: + painter->setBrush(getBrush()); + painter->setPen(getBorderPen()); + painter->drawRect(mOuterRect); +} + +/* inherits documentation from base class */ +double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) + return -1; + + if (mOuterRect.contains(pos.toPoint())) + { + if (details) details->setValue(spLegendBox); + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/* inherits documentation from base class */ +void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + mSelectedParts = selectedParts(); // in case item selection has changed + if (details.value() == spLegendBox && mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent) + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPLegend::deselectEvent(bool *selectionStateChanged) +{ + mSelectedParts = selectedParts(); // in case item selection has changed + if (mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(selectedParts() & ~spLegendBox); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPLegend::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractLegendItem::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) +{ + if (parentPlot && !parentPlot->legend) + parentPlot->legend = this; +} +/* end of 'src/layoutelements/layoutelement-legend.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12761 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPTextElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPTextElement + \brief A layout element displaying a text + + The text may be specified with \ref setText, the formatting can be controlled with \ref setFont, + \ref setTextColor, and \ref setTextFlags. + + A text element can be added as follows: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcptextelement-creation +*/ + +/* start documentation of signals */ + +/*! \fn void QCPTextElement::selectionChanged(bool selected) + + This signal is emitted when the selection state has changed to \a selected, either by user + interaction or by a direct call to \ref setSelected. + + \see setSelected, setSelectable +*/ + +/*! \fn void QCPTextElement::clicked(QMouseEvent *event) + + This signal is emitted when the text element is clicked. + + \see doubleClicked, selectTest +*/ + +/*! \fn void QCPTextElement::doubleClicked(QMouseEvent *event) + + This signal is emitted when the text element is double clicked. + + \see clicked, selectTest +*/ + +/* end documentation of signals */ + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref + setText). +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mText(), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mFont.setPointSizeF(pointSize); + mSelectedFont = parentPlot->font(); + mSelectedFont.setPointSizeF(pointSize); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize and the specified \a fontFamily. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(fontFamily, pointSize)), + mTextColor(Qt::black), + mSelectedFont(QFont(fontFamily, pointSize)), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with the specified \a font. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(font), + mTextColor(Qt::black), + mSelectedFont(font), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! + Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". + + \see setFont, setTextColor, setTextFlags +*/ +void QCPTextElement::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of + \c Qt::AlignmentFlag and \c Qt::TextFlag enums. + + Possible enums are: + - Qt::AlignLeft + - Qt::AlignRight + - Qt::AlignHCenter + - Qt::AlignJustify + - Qt::AlignTop + - Qt::AlignBottom + - Qt::AlignVCenter + - Qt::AlignCenter + - Qt::TextDontClip + - Qt::TextSingleLine + - Qt::TextExpandTabs + - Qt::TextShowMnemonic + - Qt::TextWordWrap + - Qt::TextIncludeTrailingSpaces +*/ +void QCPTextElement::setTextFlags(int flags) +{ + mTextFlags = flags; +} + +/*! + Sets the \a font of the text. + + \see setTextColor, setSelectedFont +*/ +void QCPTextElement::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the \a color of the text. + + \see setFont, setSelectedTextColor +*/ +void QCPTextElement::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + Sets the \a font of the text that will be used if the text element is selected (\ref setSelected). + + \see setFont +*/ +void QCPTextElement::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the \a color of the text that will be used if the text element is selected (\ref setSelected). + + \see setTextColor +*/ +void QCPTextElement::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether the user may select this text element. + + Note that even when \a selectable is set to false, the selection state may be changed + programmatically via \ref setSelected. +*/ +void QCPTextElement::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets the selection state of this text element to \a selected. If the selection has changed, \ref + selectionChanged is emitted. + + Note that this function can change the selection state independently of the current \ref + setSelectable state. +*/ +void QCPTextElement::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +void QCPTextElement::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/* inherits documentation from base class */ +void QCPTextElement::draw(QCPPainter *painter) +{ + painter->setFont(mainFont()); + painter->setPen(QPen(mainTextColor())); + painter->drawText(mRect, Qt::AlignCenter, mText, &mTextBoundingRect); +} + +/* inherits documentation from base class */ +QSize QCPTextElement::minimumOuterSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +QSize QCPTextElement::maximumOuterSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); + result.setWidth(QWIDGETSIZE_MAX); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +void QCPTextElement::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPTextElement::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/*! + Returns 0.99*selectionTolerance (see \ref QCustomPlot::setSelectionTolerance) when \a pos is + within the bounding box of the text element's text. Note that this bounding box is updated in the + draw call. + + If \a pos is outside the text's bounding box or if \a onlySelectable is true and this text + element is not selectable (\ref setSelectable), returns -1. + + \seebaseclassmethod +*/ +double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + if (mTextBoundingRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/*! + Accepts the mouse event in order to emit the according click signal in the \ref + mouseReleaseEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->accept(); +} + +/*! + Emits the \ref clicked signal if the cursor hasn't moved by more than a few pixels since the \ref + mousePressEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if ((QPointF(event->pos())-startPos).manhattanLength() <= 3) + emit clicked(event); +} + +/*! + Emits the \ref doubleClicked signal. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + emit doubleClicked(event); +} + +/*! \internal + + Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to + true, else mFont is returned. +*/ +QFont QCPTextElement::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to + true, else mTextColor is returned. +*/ +QColor QCPTextElement::mainTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} +/* end of 'src/layoutelements/layoutelement-textelement.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.cpp', size 25770 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScale +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScale + \brief A color scale for use with color coding data such as QCPColorMap + + This layout element can be placed on the plot to correlate a color gradient with data values. It + is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". + + \image html QCPColorScale.png + + The color scale can be either horizontal or vertical, as shown in the image above. The + orientation and the side where the numbers appear is controlled with \ref setType. + + Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are + connected, they share their gradient, data range and data scale type (\ref setGradient, \ref + setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color + scale, to make them all synchronize these properties. + + To have finer control over the number display and axis behaviour, you can directly access the + \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if + you want to change the number of automatically generated ticks, call + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-tickcount + + Placing a color scale next to the main axis rect works like with any other layout element: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation + In this case we have placed it to the right of the default axis rect, so it wasn't necessary to + call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color + scale can be set with \ref setLabel. + + For optimum appearance (like in the image above), it may be desirable to line up the axis rect and + the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup + + Color scales are initialized with a non-zero minimum top and bottom margin (\ref + setMinimumMargins), because vertical color scales are most common and the minimum top/bottom + margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a + horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you + might want to also change the minimum margins accordingly, e.g. setMinimumMargins(QMargins(6, 0, 6, 0)). +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPAxis *QCPColorScale::axis() const + + Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the + appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its + interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref + setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref + QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on + the QCPColorScale or on its QCPAxis. + + If the type of the color scale is changed with \ref setType, the axis returned by this method + will change, too, to either the left, right, bottom or top axis, depending on which type was set. +*/ + +/* end documentation of signals */ +/* start documentation of signals */ + +/*! \fn void QCPColorScale::dataRangeChanged(const QCPRange &newRange); + + This signal is emitted when the data range changes. + + \see setDataRange +*/ + +/*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the data scale type changes. + + \see setDataScaleType +*/ + +/*! \fn void QCPColorScale::gradientChanged(const QCPColorGradient &newGradient); + + This signal is emitted when the gradient changes. + + \see setGradient +*/ + +/* end documentation of signals */ + +/*! + Constructs a new QCPColorScale. +*/ +QCPColorScale::QCPColorScale(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight + mDataScaleType(QCPAxis::stLinear), + mBarWidth(20), + mAxisRect(new QCPColorScaleAxisRectPrivate(this)) +{ + setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used) + setType(QCPAxis::atRight); + setDataRange(QCPRange(0, 6)); +} + +QCPColorScale::~QCPColorScale() +{ + delete mAxisRect; +} + +/* undocumented getter */ +QString QCPColorScale::label() const +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return QString(); + } + + return mColorAxis.data()->label(); +} + +/* undocumented getter */ +bool QCPColorScale::rangeDrag() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/* undocumented getter */ +bool QCPColorScale::rangeZoom() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/*! + Sets at which side of the color scale the axis is placed, and thus also its orientation. + + Note that after setting \a type to a different value, the axis returned by \ref axis() will + be a different one. The new axis will adopt the following properties from the previous axis: The + range, scale type, label and ticker (the latter will be shared and not copied). +*/ +void QCPColorScale::setType(QCPAxis::AxisType type) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + if (mType != type) + { + mType = type; + QCPRange rangeTransfer(0, 6); + QString labelTransfer; + QSharedPointer tickerTransfer; + // transfer/revert some settings on old axis if it exists: + bool doTransfer = (bool)mColorAxis; + if (doTransfer) + { + rangeTransfer = mColorAxis.data()->range(); + labelTransfer = mColorAxis.data()->label(); + tickerTransfer = mColorAxis.data()->ticker(); + mColorAxis.data()->setLabel(QString()); + disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + QList allAxisTypes = QList() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop; + foreach (QCPAxis::AxisType atype, allAxisTypes) + { + mAxisRect.data()->axis(atype)->setTicks(atype == mType); + mAxisRect.data()->axis(atype)->setTickLabels(atype== mType); + } + // set new mColorAxis pointer: + mColorAxis = mAxisRect.data()->axis(mType); + // transfer settings to new axis: + if (doTransfer) + { + mColorAxis.data()->setRange(rangeTransfer); // range transfer necessary if axis changes from vertical to horizontal or vice versa (axes with same orientation are synchronized via signals) + mColorAxis.data()->setLabel(labelTransfer); + mColorAxis.data()->setTicker(tickerTransfer); + } + connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + mAxisRect.data()->setRangeDragAxes(QList() << mColorAxis.data()); + } +} + +/*! + Sets the range spanned by the color gradient and that is shown by the axis in the color scale. + + It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its range with \ref + QCPAxis::setRange. + + \see setDataScaleType, setGradient, rescaleDataRange +*/ +void QCPColorScale::setDataRange(const QCPRange &dataRange) +{ + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + mDataRange = dataRange; + if (mColorAxis) + mColorAxis.data()->setRange(mDataRange); + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets the scale type of the color scale, i.e. whether values are linearly associated with colors + or logarithmically. + + It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its scale type with \ref + QCPAxis::setScaleType. + + \see setDataRange, setGradient +*/ +void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + if (mColorAxis) + mColorAxis.data()->setScaleType(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + emit dataScaleTypeChanged(mDataScaleType); + } +} + +/*! + Sets the color gradient that will be used to represent data values. + + It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. + + \see setDataRange, setDataScaleType +*/ +void QCPColorScale::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + if (mAxisRect) + mAxisRect.data()->mGradientImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on + the internal \ref axis. +*/ +void QCPColorScale::setLabel(const QString &str) +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return; + } + + mColorAxis.data()->setLabel(str); +} + +/*! + Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed + will have. +*/ +void QCPColorScale::setBarWidth(int width) +{ + mBarWidth = width; +} + +/*! + Sets whether the user can drag the data range (\ref setDataRange). + + Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeDrag(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeDrag(0); +} + +/*! + Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. + + Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeZoom(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeZoom(0); +} + +/*! + Returns a list of all the color maps associated with this color scale. +*/ +QList QCPColorScale::colorMaps() const +{ + QList result; + for (int i=0; iplottableCount(); ++i) + { + if (QCPColorMap *cm = qobject_cast(mParentPlot->plottable(i))) + if (cm->colorScale() == this) + result.append(cm); + } + return result; +} + +/*! + Changes the data range such that all color maps associated with this color scale are fully mapped + to the gradient in the data dimension. + + \see setDataRange +*/ +void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) +{ + QList maps = colorMaps(); + QCPRange newRange; + bool haveRange = false; + QCP::SignDomain sign = QCP::sdBoth; + if (mDataScaleType == QCPAxis::stLogarithmic) + sign = (mDataRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + for (int i=0; irealVisibility() && onlyVisibleMaps) + continue; + QCPRange mapRange; + if (maps.at(i)->colorScale() == this) + { + bool currentFoundRange = true; + mapRange = maps.at(i)->data()->dataBounds(); + if (sign == QCP::sdPositive) + { + if (mapRange.lower <= 0 && mapRange.upper > 0) + mapRange.lower = mapRange.upper*1e-3; + else if (mapRange.lower <= 0 && mapRange.upper <= 0) + currentFoundRange = false; + } else if (sign == QCP::sdNegative) + { + if (mapRange.upper >= 0 && mapRange.lower < 0) + mapRange.upper = mapRange.lower*1e-3; + else if (mapRange.upper >= 0 && mapRange.lower >= 0) + currentFoundRange = false; + } + if (currentFoundRange) + { + if (!haveRange) + newRange = mapRange; + else + newRange.expand(mapRange); + haveRange = true; + } + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mDataScaleType == QCPAxis::stLinear) + { + newRange.lower = center-mDataRange.size()/2.0; + newRange.upper = center+mDataRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mDataRange.upper/mDataRange.lower); + newRange.upper = center*qSqrt(mDataRange.upper/mDataRange.lower); + } + } + setDataRange(newRange); + } +} + +/* inherits documentation from base class */ +void QCPColorScale::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + mAxisRect.data()->update(phase); + + switch (phase) + { + case upMargins: + { + if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) + { + setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); + setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); + } else + { + setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), QWIDGETSIZE_MAX); + setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), 0); + } + break; + } + case upLayout: + { + mAxisRect.data()->setOuterRect(rect()); + break; + } + default: break; + } +} + +/* inherits documentation from base class */ +void QCPColorScale::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPColorScale::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mousePressEvent(event, details); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseMoveEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseReleaseEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::wheelEvent(QWheelEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->wheelEvent(event); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScaleAxisRectPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScaleAxisRectPrivate + + \internal + \brief An axis rect subclass for use in a QCPColorScale + + This is a private class and not part of the public QCustomPlot interface. + + It provides the axis rect functionality for the QCPColorScale class. +*/ + + +/*! + Creates a new instance, as a child of \a parentColorScale. +*/ +QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale) : + QCPAxisRect(parentColorScale->parentPlot(), true), + mParentColorScale(parentColorScale), + mGradientImageInvalidated(true) +{ + setParentLayerable(parentColorScale); + setMinimumMargins(QMargins(0, 0, 0, 0)); + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + axis(type)->setVisible(true); + axis(type)->grid()->setVisible(false); + axis(type)->setPadding(0); + connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts))); + connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts))); + } + + connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); + + // make layer transfers of color scale transfer to axis rect and axes + // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); + foreach (QCPAxis::AxisType type, allAxisTypes) + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), axis(type), SLOT(setLayer(QCPLayer*))); +} + +/*! \internal + + Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws + it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. + + \seebaseclassmethod +*/ +void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) +{ + if (mGradientImageInvalidated) + updateGradientImage(); + + bool mirrorHorz = false; + bool mirrorVert = false; + if (mParentColorScale->mColorAxis) + { + mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); + mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); + } + + painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); + QCPAxisRect::draw(painter); +} + +/*! \internal + + Uses the current gradient of the parent \ref QCPColorScale (specified in the constructor) to + generate a gradient image. This gradient image will be used in the \ref draw method. +*/ +void QCPColorScaleAxisRectPrivate::updateGradientImage() +{ + if (rect().isEmpty()) + return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + int n = mParentColorScale->mGradient.levelCount(); + int w, h; + QVector data(n); + for (int i=0; imType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop) + { + w = n; + h = rect().height(); + mGradientImage = QImage(w, h, format); + QVector pixels; + for (int y=0; y(mGradientImage.scanLine(y))); + mParentColorScale->mGradient.colorize(data.constData(), QCPRange(0, n-1), pixels.first(), n); + for (int y=1; y(mGradientImage.scanLine(y)); + const QRgb lineColor = mParentColorScale->mGradient.color(data[h-1-y], QCPRange(0, n-1)); + for (int x=0; x allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectedParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectedParts(axis(type)->selectedParts() | QCPAxis::spAxis); + else + axis(type)->setSelectedParts(axis(type)->selectedParts() & ~QCPAxis::spAxis); + } + } +} + +/*! \internal + + This slot is connected to the selectableChanged signals of the four axes in the constructor. It + synchronizes the selectability of the axes. +*/ +void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts) +{ + // synchronize axis base selectability: + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectableParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectableParts(axis(type)->selectableParts() | QCPAxis::spAxis); + else + axis(type)->setSelectableParts(axis(type)->selectableParts() & ~QCPAxis::spAxis); + } + } +} +/* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ + + +/* including file 'src/plottables/plottable-graph.cpp', size 73960 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraphData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraphData + \brief Holds the data of one single data point for QCPGraph. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a value: coordinate on the value axis of this data point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPGraphData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPGraphDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPGraphData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPGraphData QCPGraphData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPGraphData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPGraphData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and value set to zero. +*/ +QCPGraphData::QCPGraphData() : + key(0), + value(0) +{ +} + +/*! + Constructs a data point with the specified \a key and \a value. +*/ +QCPGraphData::QCPGraphData(double key, double value, int status) : + key(key), + value(value), + status(status) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraph +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraph + \brief A plottable representing a graph in a plot. + + \image html QCPGraph.png + + Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be + accessed via QCustomPlot::graph. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPGraphDataContainer. + + Graphs are used to display single-valued data. Single-valued means that there should only be one + data point per unique key coordinate. In other words, the graph can't have \a loops. If you do + want to plot non-single-valued curves, rather use the QCPCurve plottable. + + Gaps in the graph line can be created by adding data points with NaN as value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpgraph-appearance Changing the appearance + + The appearance of the graph is mainly determined by the line style, scatter style, brush and pen + of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). + + \subsection filling Filling under or between graphs + + QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to + the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, + just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. + + By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill + between this graph and another one, call \ref setChannelFillGraph with the other graph as + parameter. + + \see QCustomPlot::addGraph, QCustomPlot::graph +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPGraph::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually + but use QCustomPlot::removePlottable() instead. + + To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. +*/ +QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis) +{ + // special handling for QCPGraphs to maintain the simple graph interface: + mParentPlot->registerGraph(this); + + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setLineStyle(lsLine); + setScatterSkip(0); + setChannelFillGraph(0); + setAdaptiveSampling(true); +} + +QCPGraph::~QCPGraph() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPGraphs may share the same data container safely. + Modifying the data in the container will then affect all graphs that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the graph's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-2 + + \see addData +*/ +void QCPGraph::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPGraph::setData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, status, alreadySorted); +} + +/*! + Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to + \ref lsNone and \ref setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPGraph::setLineStyle(LineStyle ls) +{ + mLineStyle = ls; +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPGraph::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPGraph::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets the target graph for filling the area between this graph and \a targetGraph with the current + brush (\ref setBrush). + + When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To + disable any filling, set the brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) +{ + // prevent setting channel target to this graph itself: + if (targetGraph == this) + { + qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; + mChannelFillGraph = 0; + return; + } + // prevent setting channel target to a graph not in the plot: + if (targetGraph && targetGraph->mParentPlot != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; + mChannelFillGraph = 0; + return; + } + + mChannelFillGraph = targetGraph; +} + +/*! + Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive + sampling technique can drastically improve the replot performance for graphs with a larger number + of points (e.g. above 10,000), without notably changing the appearance of the graph. + + By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive + sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no + disadvantage in almost all cases. + + \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" + + As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are + reproduced reliably, as well as the overall shape of the data set. The replot time reduces + dramatically though. This allows QCustomPlot to display large amounts of data in realtime. + + \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" + + Care must be taken when using high-density scatter plots in combination with adaptive sampling. + The adaptive sampling algorithm treats scatter plots more carefully than line plots which still + gives a significant reduction of replot times, but not quite as much as for line plots. This is + because scatter plots inherently need more data points to be preserved in order to still resemble + the original, non-adaptive-sampling plot. As shown above, the results still aren't quite + identical, as banding occurs for the outer data points. This is in fact intentional, such that + the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, + depends on the point density, i.e. the number of points in the plot. + + For some situations with scatter plots it might thus be desirable to manually turn adaptive + sampling off. For example, when saving the plot to disk. This can be achieved by setting \a + enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled + back to true afterwards. +*/ +void QCPGraph::setAdaptiveSampling(bool enabled) +{ + mAdaptiveSampling = enabled; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + int n = qMin(keys.size(), values.size()); + if (keys.size() != status.size()) + qDebug() << Q_FUNC_INFO << "keys and status have different sizes:" << keys.size() << status.size(); + n = qMin(n, status.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + it->status = status[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(double key, double value, int status) +{ + mDataContainer->add(QCPGraphData(key, value, status)); +} + +double QCPGraph::value(const double &key) +{ + QCPDataContainer::const_iterator lower = mDataContainer->findBegin(key, true); + if(lower == mDataContainer->constEnd()) + { + return qSqrt(-1.); + } + + if(lsStepLeft == mLineStyle) + { + return lower->value; + } + + QCPDataContainer::const_iterator upper = mDataContainer->findEnd(key, false); + if(upper == mDataContainer->constEnd() || upper == mDataContainer->constBegin()) + { + return qSqrt(-1.); + } + + if(upper->key == lower->key) + { + return lower->value; + } + + double rate = (upper->value - lower->value) / (upper->key - lower->key); + return rate * (key - lower->key) + lower->value; +} + +/* inherits documentation from base class */ +double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPGraph::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + if (mLineStyle == lsNone && mScatterStyle.isNone()) return; + + QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments + QVector status; + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + // get line pixel points appropriate to line style: + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) + getLines(&lines, lineDataRange, &status); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPGraphDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } +#endif + + // draw fill of graph: + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + drawFill(painter, &lines); + + // draw line: + if (mLineStyle != lsNone) + { + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + painter->setBrush(Qt::NoBrush); + if (mLineStyle == lsImpulse) + drawImpulsePlot(painter, lines); + else + drawLinePlot(painter, lines, status); // also step plots can be drawn as a line plot + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i)); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedLineData, an branches + out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc. + according to the line style of the graph. + + \a lines will be filled with points in pixel coordinates, that can be drawn with the according + draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines + aren't necessarily the original data points. For example, step line styles require additional + points to form the steps when drawn. If the line style of the graph is \ref lsNone, the \a + lines vector will be empty. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. + + \see getScatters +*/ +void QCPGraph::getLines(QVector *lines, const QCPDataRange &dataRange, QVector *status) const +{ + if (!lines || !status) return; + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + lines->clear(); + status->clear(); + return; + } + + QVector lineData; + if (mLineStyle != lsNone) + getOptimizedLineData(&lineData, begin, end); + + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in lineData (significantly simplifies following processing) + std::reverse(lineData.begin(), lineData.end()); + + switch (mLineStyle) + { + case lsNone: lines->clear();status->clear(); break; + case lsLine: dataToLines(lineData, *lines, *status); break; + case lsStepLeft: dataToStepLeftLines(lineData, *lines, *status); break; + case lsStepRight: dataToStepRightLines(lineData, *lines, *status); break; + case lsStepCenter: dataToStepCenterLines(lineData, *lines, *status); break; + case lsImpulse: dataToImpulseLines(lineData, *lines, *status); break; + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedScatterData and then + converts them to pixel coordinates. The resulting points are returned in \a scatters, and can be + passed to \ref drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. +*/ +void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataRange) const +{ + if (!scatters) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; } + + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + scatters->clear(); + return; + } + + QVector data; + getOptimizedScatterData(&data, begin, end); + + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in data (significantly simplifies following processing) + std::reverse(data.begin(), data.end()); + + scatters->resize(data.size()); + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + (*scatters)[i].setY(keyAxis->coordToPixel(data.at(i).key)); + } + } + } else + { + for (int i=0; icoordToPixel(data.at(i).key)); + (*scatters)[i].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsLine. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +void QCPGraph::dataToLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()); + status.resize(data.size()); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + lines[i].setY(keyAxis->coordToPixel(data.at(i).key)); + status[i] = data.at(i).status; + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key)); + lines[i].setY(valueAxis->coordToPixel(data.at(i).value)); + status[i] = data.at(i).status; + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepLeft. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +void QCPGraph::dataToStepLeftLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()*2); + status.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastValue = valueAxis->coordToPixel(data.first().value); + int lastStatus = data.first().status; + for (int i=0; icoordToPixel(data.at(i).key); + lines[i*2+0].setX(lastValue); + lines[i*2+0].setY(key); + status[i*2+0] = lastStatus; + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastStatus = data.at(i).status; + lines[i*2+1].setX(lastValue); + lines[i*2+1].setY(key); + status[i*2+1] = lastStatus; + } + } else // key axis is horizontal + { + double lastValue = valueAxis->coordToPixel(data.first().value); + int lastStatus = data.first().status; + for (int i=0; icoordToPixel(data.at(i).key); + lines[i*2+0].setX(key); + lines[i*2+0].setY(lastValue); + status[i*2+0] = lastStatus; + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastStatus = data.at(i).status; + lines[i*2+1].setX(key); + lines[i*2+1].setY(lastValue); + status[i*2+1] = lastStatus; + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepRight. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +void QCPGraph::dataToStepRightLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()*2); + status.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + const int curStatus = data.at(i).status; + lines[i*2+0].setX(value); + lines[i*2+0].setY(lastKey); + status[i*2+0] = curStatus; + lastKey = keyAxis->coordToPixel(data.at(i).key); + lines[i*2+1].setX(value); + lines[i*2+1].setY(lastKey); + status[i*2+1] = curStatus; + } + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + const int curStatus = data.at(i).status; + lines[i*2+0].setX(lastKey); + lines[i*2+0].setY(value); + status[i*2+0] = curStatus; + lastKey = keyAxis->coordToPixel(data.at(i).key); + lines[i*2+1].setX(lastKey); + lines[i*2+1].setY(value); + status[i*2+1] = curStatus; + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepCenter. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToImpulseLines, getLines, drawLinePlot +*/ +void QCPGraph::dataToStepCenterLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()*2); + status.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + int lastStatus = data.first().status; + lines[0].setX(lastValue); + lines[0].setY(lastKey); + status[0] = lastStatus; + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + lines[i*2-1].setX(lastValue); + lines[i*2-1].setY(key); + status[i*2-1] = lastStatus; + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + lastStatus = data.at(i).status; + lines[i*2+0].setX(lastValue); + lines[i*2+0].setY(key); + status[i*2+0] = lastStatus; + } + lines[data.size()*2-1].setX(lastValue); + lines[data.size()*2-1].setY(lastKey); + status[data.size()*2-1] = lastStatus; + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + int lastStatus = data.first().status; + lines[0].setX(lastKey); + lines[0].setY(lastValue); + status[0] = lastStatus; + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + lines[i*2-1].setX(key); + lines[i*2-1].setY(lastValue); + status[i*2-1] = lastStatus; + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + lastStatus = data.at(i).status; + lines[i*2+0].setX(key); + lines[i*2+0].setY(lastValue); + status[i*2+0] = lastStatus; + } + lines[data.size()*2-1].setX(lastKey); + lines[data.size()*2-1].setY(lastValue); + status[data.size()*2-1] = lastStatus; + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsImpulse. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, getLines, drawImpulsePlot +*/ +void QCPGraph::dataToImpulseLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()*2); + status.resize(data.size()*2); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).key); + const int curStatus = data.at(i).status; + lines[i*2+0].setX(valueAxis->coordToPixel(0)); + lines[i*2+0].setY(key); + status[i*2+0] = curStatus; + lines[i*2+1].setX(valueAxis->coordToPixel(data.at(i).value)); + lines[i*2+1].setY(key); + status[i*2+1] = curStatus; + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key); + const int curStatus = data.at(i).status; + lines[i*2+0].setX(key); + lines[i*2+0].setY(valueAxis->coordToPixel(0)); + status[i*2+0] = curStatus; + lines[i*2+1].setX(key); + lines[i*2+1].setY(valueAxis->coordToPixel(data.at(i).value)); + status[i*2+1] = curStatus; + } + } +} + +/*! \internal + + Draws the fill of the graph using the specified \a painter, with the currently set brush. + + Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref + getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. + + In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), + this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to + operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN + segments of the two involved graphs, before passing the overlapping pairs to \ref + getChannelFillPolygon. + + Pass the points of this graph's line as \a lines, in pixel coordinates. + + \see drawLinePlot, drawImpulsePlot, drawScatterPlot +*/ +void QCPGraph::drawFill(QCPPainter *painter, QVector *lines) const +{ + if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot + if (painter->brush().style() == Qt::NoBrush || painter->brush().color().alpha() == 0) return; + + applyFillAntialiasingHint(painter); + QVector segments = getNonNanSegments(lines, keyAxis()->orientation()); + if (!mChannelFillGraph) + { + // draw base fill under graph, fill goes all the way to the zero-value-line: + for (int i=0; idrawPolygon(getFillPolygon(lines, segments.at(i))); + } else + { + // draw fill between this graph and mChannelFillGraph: + QVector otherLines; + QVector status; + mChannelFillGraph->getLines(&otherLines, QCPDataRange(0, mChannelFillGraph->dataCount()), &status); + if (!otherLines.isEmpty()) + { + QVector otherSegments = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation()); + QVector > segmentPairs = getOverlappingSegments(segments, lines, otherSegments, &otherLines); + for (int i=0; idrawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first, &otherLines, segmentPairs.at(i).second)); + } + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a scatters, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawLinePlot, drawImpulsePlot +*/ +void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const +{ + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; i &lines, const QVector &status) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines, status); + } +} + +/*! \internal + + Draws impulses from the provided data, i.e. it connects all line pairs in \a lines, given in + pixel coordinates. The \a lines necessary for impulses are generated by \ref dataToImpulseLines + from the regular graph data points. + + \see drawLinePlot, drawScatterPlot +*/ +void QCPGraph::drawImpulsePlot(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + QPen oldPen = painter->pen(); + QPen newPen = painter->pen(); + newPen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line + painter->setPen(newPen); + painter->drawLines(lines); + painter->setPen(oldPen); + } +} + +/*! \internal + + Returns via \a lineData the data points that need to be visualized for this graph when plotting + graph lines, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getLines to retrieve the basic working set of data. + + \see getOptimizedScatterData +*/ +void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const +{ + if (!lineData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (begin == end) return; + + int dataCount = end-begin; + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + if (2*keyPixelSpan+2 < (double)std::numeric_limits::max()) + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + QCPGraphDataContainer::const_iterator it = begin; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator currentIntervalFirstPoint = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); + double lastIntervalEndKey = currentIntervalStartKey; + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary + { + if (it->value < minValue) + minValue = it->value; + else if (it->value > maxValue) + maxValue = it->value; + ++intervalDataCount; + } else // new pixel interval started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + if (it->key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.8, (it-1)->value)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + lastIntervalEndKey = (it-1)->key; + minValue = it->value; + maxValue = it->value; + currentIntervalFirstPoint = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + ++it; + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + lineData->resize(dataCount); + std::copy(begin, end, lineData->begin()); + } +} + +/*! \internal + + Returns via \a scatterData the data points that need to be visualized for this graph when + plotting scatter points, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getScatters to retrieve the basic working set of data. + + \see getOptimizedLineData +*/ +void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const +{ + if (!scatterData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int beginIndex = begin-mDataContainer->constBegin(); + int endIndex = end-mDataContainer->constBegin(); + while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++beginIndex; + ++begin; + } + if (begin == end) return; + int dataCount = end-begin; + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + int keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + double valueMaxRange = valueAxis->range().upper; + double valueMinRange = valueAxis->range().lower; + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator minValueIt = it; + QCPGraphDataContainer::const_iterator maxValueIt = it; + QCPGraphDataContainer::const_iterator currentIntervalStart = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + // main loop over data points: + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary + { + if (it->value < minValue && it->value > valueMinRange && it->value < valueMaxRange) + { + minValue = it->value; + minValueIt = it; + } else if (it->value > maxValue && it->value > valueMinRange && it->value < valueMaxRange) + { + maxValue = it->value; + maxValueIt = it; + } + ++intervalDataCount; + } else // new pixel started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else + intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + minValue = it->value; + maxValue = it->value; + currentIntervalStart = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int intervalItIndex = intervalIt-mDataContainer->constBegin(); + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison: + { + intervalItIndex += scatterModulo; + if (intervalItIndex < itIndex) + intervalIt += scatterModulo; + else + { + intervalIt = it; + intervalItIndex = itIndex; + } + } + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + scatterData->reserve(dataCount); + while (it != end) + { + scatterData->append(*it); + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + This method takes into account that the drawing of data lines at the axis rect border always + requires the points just outside the visible axis range. So \a begin and \a end may actually + indicate a range that contains one additional data point to the left and right of the visible + axis range. +*/ +void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + if (rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + } else + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + // get visible data range: + begin = mDataContainer->findBegin(keyAxis->range().lower); + end = mDataContainer->findEnd(keyAxis->range().upper); + // limit lower/upperEnd to rangeRestriction: + mDataContainer->limitIteratorsToDataRange(begin, end, rangeRestriction); // this also ensures rangeRestriction outside data bounds doesn't break anything + } +} + +/*! \internal + + This method goes through the passed points in \a lineData and returns a list of the segments + which don't contain NaN data points. + + \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check + for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c + Qt::Vertical, the \a x member is checked. + + \see getOverlappingSegments, drawFill +*/ +QVector QCPGraph::getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const +{ + QVector result; + const int n = lineData->size(); + + QCPDataRange currentSegment(-1, -1); + int i = 0; + + if (keyOrientation == Qt::Horizontal) + { + while (i < n) + { + while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point + ++i; + if (i == n) + break; + currentSegment.setBegin(i++); + while (i < n && !qIsNaN(lineData->at(i).y())) // seek next NaN data point or end of data + ++i; + currentSegment.setEnd(i++); + result.append(currentSegment); + } + } else // keyOrientation == Qt::Vertical + { + while (i < n) + { + while (i < n && qIsNaN(lineData->at(i).x())) // seek next non-NaN data point + ++i; + if (i == n) + break; + currentSegment.setBegin(i++); + while (i < n && !qIsNaN(lineData->at(i).x())) // seek next NaN data point or end of data + ++i; + currentSegment.setEnd(i++); + result.append(currentSegment); + } + } + return result; +} + +/*! \internal + + This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and + \a otherSegments, and their associated point data \a thisData and \a otherData. + + It returns all pairs of segments (the first from \a thisSegments, the second from \a + otherSegments), which overlap in plot coordinates. + + This method is useful in the case of a channel fill between two graphs, when only those non-NaN + segments which actually overlap in their key coordinate shall be considered for drawing a channel + fill polygon. + + It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and + that the segments don't overlap themselves. The same is assumed for the segments in \a + otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments. + + \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon +*/ +QVector > QCPGraph::getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const +{ + QVector > result; + if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() || otherSegments.isEmpty()) + return result; + + int thisIndex = 0; + int otherIndex = 0; + const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical; + while (thisIndex < thisSegments.size() && otherIndex < otherSegments.size()) + { + if (thisSegments.at(thisIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow + { + ++thisIndex; + continue; + } + if (otherSegments.at(otherIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow + { + ++otherIndex; + continue; + } + double thisLower, thisUpper, otherLower, otherUpper; + if (!verticalKey) + { + thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x(); + thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).x(); + otherLower = otherData->at(otherSegments.at(otherIndex).begin()).x(); + otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).x(); + } else + { + thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y(); + thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).y(); + otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y(); + otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).y(); + } + + int bPrecedence; + if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence)) + result.append(QPair(thisSegments.at(thisIndex), otherSegments.at(otherIndex))); + + if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with next otherSegment, keeping current thisSegment + ++otherIndex; + else // otherSegment reaches further than thisSegment, so continue with next thisSegment, keeping current otherSegment + ++thisIndex; + } + + return result; +} + +/*! \internal + + Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper) + have overlap. + + The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the + \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher + coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if + both segment's upper bounds are identical, 0 is returned as \a bPrecedence. + + It is assumed that the lower bounds always have smaller or equal values than the upper bounds. + + \see getOverlappingSegments +*/ +bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const +{ + bPrecedence = 0; + if (aLower > bUpper) + { + bPrecedence = -1; + return false; + } else if (bLower > aUpper) + { + bPrecedence = 1; + return false; + } else + { + if (aUpper > bUpper) + bPrecedence = -1; + else if (aUpper < bUpper) + bPrecedence = 1; + + return true; + } +} + +/*! \internal + + Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis. + The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates + is in positive or negative infinity. So this case is handled separately by just closing the fill + polygon on the axis which lies in the direction towards the zero value. + + \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether + the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or + y value of the returned point, respectively. +*/ +QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + QPointF result; + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + if (keyAxis->orientation() == Qt::Horizontal) + { + result.setX(matchingDataPoint.x()); + result.setY(valueAxis->coordToPixel(0)); + } else // keyAxis->orientation() == Qt::Vertical + { + result.setX(valueAxis->coordToPixel(0)); + result.setY(matchingDataPoint.y()); + } + } else // valueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value 0 so we just fill all the way + // to the axis which is in the direction towards 0 + if (keyAxis->orientation() == Qt::Vertical) + { + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + result.setX(keyAxis->axisRect()->right()); + else + result.setX(keyAxis->axisRect()->left()); + result.setY(matchingDataPoint.y()); + } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) + { + result.setX(matchingDataPoint.x()); + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + result.setY(keyAxis->axisRect()->top()); + else + result.setY(keyAxis->axisRect()->bottom()); + } + } + return result; +} + +/*! \internal + + Returns the polygon needed for drawing normal fills between this graph and the key axis. + + Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment + which shall be used for the fill. The collection of \a lineData points described by \a segment + must not contain NaN data points (see \ref getNonNanSegments). + + The returned fill polygon will be closed at the key axis (the zero-value line) for linear value + axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect + side (see \ref getFillBasePoint). + + For increased performance (due to implicit sharing), keep the returned QPolygonF const. + + \see drawFill, getNonNanSegments +*/ +const QPolygonF QCPGraph::getFillPolygon(const QVector *lineData, QCPDataRange segment) const +{ + if (segment.size() < 2) + return QPolygonF(); + QPolygonF result(segment.size()+2); + + result[0] = getFillBasePoint(lineData->at(segment.begin())); + std::copy(lineData->constBegin()+segment.begin(), lineData->constBegin()+segment.end(), result.begin()+1); + result[result.size()-1] = getFillBasePoint(lineData->at(segment.end()-1)); + + return result; +} + +/*! \internal + + Returns the polygon needed for drawing (partial) channel fills between this graph and the graph + specified by \ref setChannelFillGraph. + + The data points of this graph are passed as pixel coordinates via \a thisData, the data of the + other graph as \a otherData. The returned polygon will be calculated for the specified data + segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a + otherData, respectively. + + The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by + \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap + need to be processed here. + + For increased performance due to implicit sharing, keep the returned QPolygonF const. + + \see drawFill, getOverlappingSegments, getNonNanSegments +*/ +const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const +{ + if (!mChannelFillGraph) + return QPolygonF(); + + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } + if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } + + if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) + return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) + + if (thisData->isEmpty()) return QPolygonF(); + QVector thisSegmentData(thisSegment.size()); + QVector otherSegmentData(otherSegment.size()); + std::copy(thisData->constBegin()+thisSegment.begin(), thisData->constBegin()+thisSegment.end(), thisSegmentData.begin()); + std::copy(otherData->constBegin()+otherSegment.begin(), otherData->constBegin()+otherSegment.end(), otherSegmentData.begin()); + // pointers to be able to swap them, depending which data range needs cropping: + QVector *staticData = &thisSegmentData; + QVector *croppedData = &otherSegmentData; + + // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): + if (keyAxis->orientation() == Qt::Horizontal) + { + // x is key + // crop lower bound: + if (staticData->first().x() < croppedData->first().x()) // other one must be cropped + qSwap(staticData, croppedData); + const int lowBound = findIndexBelowX(croppedData, staticData->first().x()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x())) + slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); + else + slope = 0; + (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); + (*croppedData)[0].setX(staticData->first().x()); + + // crop upper bound: + if (staticData->last().x() > croppedData->last().x()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveX(croppedData, staticData->last().x()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + const int li = croppedData->size()-1; // last index + if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li-1).x())) + slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); + else + slope = 0; + (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); + (*croppedData)[li].setX(staticData->last().x()); + } else // mKeyAxis->orientation() == Qt::Vertical + { + // y is key + // crop lower bound: + if (staticData->first().y() < croppedData->first().y()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexBelowY(croppedData, staticData->first().y()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (!qFuzzyCompare(croppedData->at(1).y(), croppedData->at(0).y())) // avoid division by zero in step plots + slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); + else + slope = 0; + (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); + (*croppedData)[0].setY(staticData->first().y()); + + // crop upper bound: + if (staticData->last().y() > croppedData->last().y()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveY(croppedData, staticData->last().y()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (!qFuzzyCompare(croppedData->at(li).y(), croppedData->at(li-1).y())) // avoid division by zero in step plots + slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); + else + slope = 0; + (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); + (*croppedData)[li].setY(staticData->last().y()); + } + + // return joined: + for (int i=otherSegmentData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted + thisSegmentData << otherSegmentData.at(i); + return QPolygonF(thisSegmentData); +} + +/*! \internal + + Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is horizontal. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveX(const QVector *data, double x) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).x() < x) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is horizontal. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowX(const QVector *data, double x) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).x() > x) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is vertical. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveY(const QVector *data, double y) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).y() < y) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Calculates the minimum distance in pixels the graph's representation has from the given \a + pixelPoint. This is used to determine whether the graph was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if + the graph has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the graph line is also taken into account. + + If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. +*/ +double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + // calculate minimum distances to graph data points and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPGraphDataContainer::const_iterator begin = mDataContainer->findBegin(posKeyMin, true); + QCPGraphDataContainer::const_iterator end = mDataContainer->findEnd(posKeyMax, true); + for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + // line displayed, calculate distance to line segments: + QVector lineData; + QVector status; + getLines(&lineData, QCPDataRange(0, dataCount()), &status); + QCPVector2D p(pixelPoint); + const int step = mLineStyle==lsImpulse ? 2 : 1; // impulse plot differs from other line styles in that the lineData points are only pairwise connected + for (int i=0; i *data, double y) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).y() > y) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} +/* end of 'src/plottables/plottable-graph.cpp' */ + + +/* including file 'src/plottables/plottable-curve.cpp', size 63527 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurveData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurveData + \brief Holds the data of one single data point for QCPCurve. + + The stored data is: + \li \a t: the free ordering parameter of this curve point, like in the mathematical vector (x(t), y(t)). (This is the \a sortKey) + \li \a key: coordinate on the key axis of this curve point (this is the \a mainKey) + \li \a value: coordinate on the value axis of this curve point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPCurveData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPCurveDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPCurveData::sortKey() const + + Returns the \a t member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPCurveData QCPCurveData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey (assigned to the data point's \a t member). + All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPCurveData::sortKeyIsMainKey() + + Since the member \a key is the data point key coordinate and the member \a t is the data ordering + parameter, this method returns false. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPCurveData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a curve data point with t, key and value set to zero. +*/ +QCPCurveData::QCPCurveData() : + t(0), + key(0), + value(0) +{ +} + +/*! + Constructs a curve data point with the specified \a t, \a key and \a value. +*/ +QCPCurveData::QCPCurveData(double t, double key, double value) : + t(t), + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurve + \brief A plottable representing a parametric curve in a plot. + + \image html QCPCurve.png + + Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, + so their visual representation can have \a loops. This is realized by introducing a third + coordinate \a t, which defines the order of the points described by the other two coordinates \a + x and \a y. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the curve's data via the \ref data method, which returns a pointer to the + internal \ref QCPCurveDataContainer. + + Gaps in the curve can be created by adding data points with NaN as key and value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpcurve-appearance Changing the appearance + + The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). + + \section qcpcurve-usage Usage + + Like all data representing objects in QCustomPlot, the QCPCurve is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPCurve::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis) +{ + // modify inherited properties from abstract plottable: + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setScatterStyle(QCPScatterStyle()); + setLineStyle(lsLine); + setScatterSkip(0); +} + +QCPCurve::~QCPCurve() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPCurves may share the same data container safely. + Modifying the data in the container will then affect all curves that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the curve's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-2 + + \see addData +*/ +void QCPCurve::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a t, \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a t in ascending order, you can + set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPCurve::setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(t, keys, values, alreadySorted); +} + + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + \see addData +*/ +void QCPCurve::setData(const QVector &keys, const QVector &values) +{ + mDataContainer->clear(); + addData(keys, values); +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref + QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate + line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPCurve::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPCurve::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets how the single data points are connected in the plot or how they are represented visually + apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref + setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPCurve::setLineStyle(QCPCurve::LineStyle style) +{ + mLineStyle = style; +} + +/*! \overload + + Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (t.size() != keys.size() || t.size() != values.size()) + qDebug() << Q_FUNC_INFO << "ts, keys and values have different sizes:" << t.size() << keys.size() << values.size(); + const int n = qMin(qMin(t.size(), keys.size()), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = t[i]; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &keys, const QVector &values) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + double tStart; + if (!mDataContainer->isEmpty()) + tStart = (mDataContainer->constEnd()-1)->t + 1.0; + else + tStart = 0; + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = tStart + i; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, true); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a t, \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double t, double key, double value) +{ + mDataContainer->add(QCPCurveData(t, key, value)); +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + The t parameter is generated automatically by increments of 1 for each point, starting at the + highest t of previously existing data or 0, if the curve data is empty. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double key, double value) +{ + if (!mDataContainer->isEmpty()) + mDataContainer->add(QCPCurveData((mDataContainer->constEnd()-1)->t + 1.0, key, value)); + else + mDataContainer->add(QCPCurveData(0.0, key, value)); +} + +/* inherits documentation from base class */ +double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPCurveDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPCurve::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + + // allocate line vector: + QVector lines, scatters; + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + + // fill with curve data: + QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width + if (isSelectedSegment && mSelectionDecorator) + finalCurvePen = mSelectionDecorator->pen(); + + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care) + getCurveLines(&lines, lineDataRange, finalCurvePen.widthF()); + + // check data validity if flag set: + #ifdef QCUSTOMPLOT_CHECK_DATA + for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->t) || + QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } + #endif + + // draw curve fill: + applyFillAntialiasingHint(painter); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) + painter->drawPolygon(QPolygonF(lines)); + + // draw curve line: + if (mLineStyle != lsNone) + { + painter->setPen(finalCurvePen); + painter->setBrush(Qt::NoBrush); + drawCurveLine(painter, lines); + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i), finalScatterStyle.size()); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + Draws lines between the points in \a lines, given in pixel coordinates. + + \see drawScatterPlot, getCurveLines +*/ +void QCPCurve::drawCurveLine(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a points, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawCurveLine, getCurveLines +*/ +void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const +{ + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; i *lines, const QCPDataRange &dataRange, double penWidth) const +{ + if (!lines) return; + lines->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + // add margins to rect to compensate for stroke width + const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety + const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation()); + const double keyMax = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*keyAxis->pixelOrientation()); + const double valueMin = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)-strokeMargin*valueAxis->pixelOrientation()); + const double valueMax = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)+strokeMargin*valueAxis->pixelOrientation()); + QCPCurveDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(itBegin, itEnd, dataRange); + if (itBegin == itEnd) + return; + QCPCurveDataContainer::const_iterator it = itBegin; + QCPCurveDataContainer::const_iterator prevIt = itEnd-1; + int prevRegion = getRegion(prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin); + QVector trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right) + while (it != itEnd) + { + const int currentRegion = getRegion(it->key, it->value, keyMin, valueMax, keyMax, valueMin); + if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R + { + if (currentRegion != 5) // segment doesn't end in R, so it's a candidate for removal + { + QPointF crossA, crossB; + if (prevRegion == 5) // we're coming from R, so add this point optimized + { + lines->append(getOptimizedPoint(currentRegion, it->key, it->value, prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin)); + // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } else if (mayTraverse(prevRegion, currentRegion) && + getTraverse(prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin, crossA, crossB)) + { + // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point: + QVector beforeTraverseCornerPoints, afterTraverseCornerPoints; + getTraverseCornerPoints(prevRegion, currentRegion, keyMin, valueMax, keyMax, valueMin, beforeTraverseCornerPoints, afterTraverseCornerPoints); + if (it != itBegin) + { + *lines << beforeTraverseCornerPoints; + lines->append(crossA); + lines->append(crossB); + *lines << afterTraverseCornerPoints; + } else + { + lines->append(crossB); + *lines << afterTraverseCornerPoints; + trailingPoints << beforeTraverseCornerPoints << crossA ; + } + } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s) + { + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } + } else // segment does end in R, so we add previous point optimized and this point at original position + { + if (it == itBegin) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end + trailingPoints << getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + else + lines->append(getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin)); + lines->append(coordsToPixels(it->key, it->value)); + } + } else // region didn't change + { + if (currentRegion == 5) // still in R, keep adding original points + { + lines->append(coordsToPixels(it->key, it->value)); + } else // still outside R, no need to add anything + { + // see how this is not doing anything? That's the main optimization... + } + } + prevIt = it; + prevRegion = currentRegion; + ++it; + } + *lines << trailingPoints; +} + +/*! \internal + + Called by \ref draw to generate points in pixel coordinates which represent the scatters of the + curve. If a scatter skip is configured (\ref setScatterSkip), the returned points are accordingly + sparser. + + Scatters that aren't visible in the current axis rect are optimized away. + + \a scatters will be filled with points in pixel coordinates, that can be drawn with \ref + drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. + + \a scatterWidth specifies the scatter width that will be used to later draw the scatters at pixel + coordinates generated by this function. This is needed here to calculate an accordingly wider + margin around the axis rect when performing the data point reduction. + + \see draw, drawScatterPlot +*/ +void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const +{ + if (!scatters) return; + scatters->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(begin, end, dataRange); + if (begin == end) + return; + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int endIndex = end-mDataContainer->constBegin(); + + QCPRange keyRange = keyAxis->range(); + QCPRange valueRange = valueAxis->range(); + // extend range to include width of scatter symbols: + keyRange.lower = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.lower)-scatterWidth*keyAxis->pixelOrientation()); + keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation()); + valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation()); + valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation()); + + QCPCurveDataContainer::const_iterator it = begin; + int itIndex = begin-mDataContainer->constBegin(); + while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++itIndex; + ++it; + } + if (keyAxis->orientation() == Qt::Vertical) + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } else + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(keyAxis->coordToPixel(it->key), valueAxis->coordToPixel(it->value))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + It returns the region of the given point (\a key, \a value) with respect to a rectangle defined + by \a keyMin, \a keyMax, \a valueMin, and \a valueMax. + + The regions are enumerated from top to bottom (\a valueMin to \a valueMax) and left to right (\a + keyMin to \a keyMax): + + + + + +
147
258
369
+ + With the rectangle being region 5, and the outer regions extending infinitely outwards. In the + curve optimization algorithm, region 5 is considered to be the visible portion of the plot. +*/ +int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + if (key < keyMin) // region 123 + { + if (value > valueMax) + return 1; + else if (value < valueMin) + return 3; + else + return 2; + } else if (key > keyMax) // region 789 + { + if (value > valueMax) + return 7; + else if (value < valueMin) + return 9; + else + return 8; + } else // region 456 + { + if (value > valueMax) + return 4; + else if (value < valueMin) + return 6; + else + return 5; + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method is used in case the current segment passes from inside the visible rect (region 5, + see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by + the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). + + It returns the intersection point of the segment with the border of region 5. + + For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or + whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or + leaving it. It is important though that \a otherRegion correctly identifies the other region not + equal to 5. +*/ +QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + // The intersection point interpolation here is done in pixel coordinates, so we don't need to + // differentiate between different axis scale types. Note that the nomenclature + // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be + // different in pixel coordinates (horz/vert key axes, reversed ranges) + + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); + const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); + const double valueMinPx = mValueAxis->coordToPixel(valueMin); + const double valueMaxPx = mValueAxis->coordToPixel(valueMax); + const double otherValuePx = mValueAxis->coordToPixel(otherValue); + const double valuePx = mValueAxis->coordToPixel(value); + const double otherKeyPx = mKeyAxis->coordToPixel(otherKey); + const double keyPx = mKeyAxis->coordToPixel(key); + double intersectKeyPx = keyMinPx; // initial key just a fail-safe + double intersectValuePx = valueMinPx; // initial value just a fail-safe + switch (otherRegion) + { + case 1: // top and left edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 2: // left edge + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + break; + } + case 3: // bottom and left edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 4: // top edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + break; + } + case 5: + { + break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table + } + case 6: // bottom edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + break; + } + case 7: // top and right edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 8: // right edge + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + break; + } + case 9: // bottom and right edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + } + if (mKeyAxis->orientation() == Qt::Horizontal) + return QPointF(intersectKeyPx, intersectValuePx); + else + return QPointF(intersectValuePx, intersectKeyPx); +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + In situations where a single segment skips over multiple regions it might become necessary to add + extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment + doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. + This method provides these points that must be added, assuming the original segment doesn't + start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by + \ref getTraverseCornerPoints.) + + For example, consider a segment which directly goes from region 4 to 2 but originally is far out + to the top left such that it doesn't cross region 5. Naively optimizing these points by + projecting them on the top and left borders of region 5 will create a segment that surely crosses + 5, creating a visual artifact in the plot. This method prevents this by providing extra points at + the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without + traversing 5. +*/ +QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + QVector result; + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMax); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); break; } + case 6: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + else + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + break; + } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 7: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMin); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); break; } + case 1: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + else + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + break; + } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 3: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 6: + { + switch (currentRegion) + { + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 4: { result << coordsToPixels(keyMax, valueMax); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); break; } + case 1: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + else + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + break; + } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 6: { result << coordsToPixels(keyMax, valueMin); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 4: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + else + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + break; + } + } + break; + } + } + return result; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref + getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion + nor \a currentRegion is 5 itself. + + If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the + segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref + getTraverse). +*/ +bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 4: + case 7: + case 2: + case 3: return false; + default: return true; + } + } + case 2: + { + switch (currentRegion) + { + case 1: + case 3: return false; + default: return true; + } + } + case 3: + { + switch (currentRegion) + { + case 1: + case 2: + case 6: + case 9: return false; + default: return true; + } + } + case 4: + { + switch (currentRegion) + { + case 1: + case 7: return false; + default: return true; + } + } + case 5: return false; // should never occur + case 6: + { + switch (currentRegion) + { + case 3: + case 9: return false; + default: return true; + } + } + case 7: + { + switch (currentRegion) + { + case 1: + case 4: + case 8: + case 9: return false; + default: return true; + } + } + case 8: + { + switch (currentRegion) + { + case 7: + case 9: return false; + default: return true; + } + } + case 9: + { + switch (currentRegion) + { + case 3: + case 6: + case 8: + case 7: return false; + default: return true; + } + } + default: return true; + } +} + + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref mayTraverse test has returned true, so there is a chance the + segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible + region 5. + + The return value of this method indicates whether the segment actually traverses region 5 or not. + + If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and + exit points of region 5. They will become the optimized points for that segment. +*/ +bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const +{ + // The intersection point interpolation here is done in pixel coordinates, so we don't need to + // differentiate between different axis scale types. Note that the nomenclature + // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be + // different in pixel coordinates (horz/vert key axes, reversed ranges) + + QList intersections; + const double valueMinPx = mValueAxis->coordToPixel(valueMin); + const double valueMaxPx = mValueAxis->coordToPixel(valueMax); + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); + const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); + const double keyPx = mKeyAxis->coordToPixel(key); + const double valuePx = mValueAxis->coordToPixel(value); + const double prevKeyPx = mKeyAxis->coordToPixel(prevKey); + const double prevValuePx = mValueAxis->coordToPixel(prevValue); + if (qFuzzyIsNull(key-prevKey)) // line is parallel to value axis + { + // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMinPx) : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMaxPx) : QPointF(valueMaxPx, keyPx)); + } else if (qFuzzyIsNull(value-prevValue)) // line is parallel to key axis + { + // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, valuePx) : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, valuePx) : QPointF(valuePx, keyMaxPx)); + } else // line is skewed + { + double gamma; + double keyPerValuePx = (keyPx-prevKeyPx)/(valuePx-prevValuePx); + // check top of rect: + gamma = prevKeyPx + (valueMaxPx-prevValuePx)*keyPerValuePx; + if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMaxPx) : QPointF(valueMaxPx, gamma)); + // check bottom of rect: + gamma = prevKeyPx + (valueMinPx-prevValuePx)*keyPerValuePx; + if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMinPx) : QPointF(valueMinPx, gamma)); + const double valuePerKeyPx = 1.0/keyPerValuePx; + // check left of rect: + gamma = prevValuePx + (keyMinPx-prevKeyPx)*valuePerKeyPx; + if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, gamma) : QPointF(gamma, keyMinPx)); + // check right of rect: + gamma = prevValuePx + (keyMaxPx-prevKeyPx)*valuePerKeyPx; + if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, gamma) : QPointF(gamma, keyMaxPx)); + } + + // handle cases where found points isn't exactly 2: + if (intersections.size() > 2) + { + // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between: + double distSqrMax = 0; + QPointF pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = intersections.at(i); + pv2 = intersections.at(k); + distSqrMax = distSqr; + } + } + } + intersections = QList() << pv1 << pv2; + } else if (intersections.size() != 2) + { + // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment + return false; + } + + // possibly re-sort points so optimized point segment has same direction as original segment: + double xDelta = keyPx-prevKeyPx; + double yDelta = valuePx-prevValuePx; + if (mKeyAxis->orientation() != Qt::Horizontal) + qSwap(xDelta, yDelta); + if (xDelta*(intersections.at(1).x()-intersections.at(0).x()) + yDelta*(intersections.at(1).y()-intersections.at(0).y()) < 0) // scalar product of both segments < 0 -> opposite direction + intersections.move(0, 1); + crossA = intersections.at(0); + crossB = intersections.at(1); + return true; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref getTraverse test has returned true, so the segment definitely + traverses the visible region 5 when going from \a prevRegion to \a currentRegion. + + In certain situations it is not sufficient to merely generate the entry and exit points of the + segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in + addition to traversing region 5, skips another region outside of region 5, which makes it + necessary to add an optimized corner point there (very similar to the job \ref + getOptimizedCornerPoints does for segments that are completely in outside regions and don't + traverse 5). + + As an example, consider a segment going from region 1 to region 6, traversing the lower left + corner of region 5. In this configuration, the segment additionally crosses the border between + region 1 and 2 before entering region 5. This makes it necessary to add an additional point in + the top left corner, before adding the optimized traverse points. So in this case, the output + parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be + empty. + + In some cases, such as when going from region 1 to 9, it may even be necessary to add additional + corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse + return the respective corner points. +*/ +void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 6: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + case 9: { beforeTraverse << coordsToPixels(keyMin, valueMax); afterTraverse << coordsToPixels(keyMax, valueMin); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 4: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + case 7: { beforeTraverse << coordsToPixels(keyMin, valueMin); afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: { break; } // shouldn't happen because this method only handles full traverses + case 6: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + case 3: { beforeTraverse << coordsToPixels(keyMax, valueMax); afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 6: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + case 1: { beforeTraverse << coordsToPixels(keyMax, valueMin); afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 4: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + } +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in + \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that + if the curve has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the curve line is also taken into account. + + If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns + -1.0. +*/ +double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + if (mDataContainer->size() == 1) + { + QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value); + closestData = mDataContainer->constBegin(); + return QCPVector2D(dataPoint-pixelPoint).length(); + } + + // calculate minimum distances to curve data points and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + for (QCPCurveDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + QVector lines; + getCurveLines(&lines, QCPDataRange(0, dataCount()), mParentPlot->selectionTolerance()*1.2); // optimized lines outside axis rect shouldn't respond to clicks at the edge, so use 1.2*tolerance as pen width + for (int i=0; i QCPBarsGroup::bars() const + + Returns all bars currently in this group. + + \see bars(int index) +*/ + +/*! \fn int QCPBarsGroup::size() const + + Returns the number of QCPBars plottables that are part of this group. + +*/ + +/*! \fn bool QCPBarsGroup::isEmpty() const + + Returns whether this bars group is empty. + + \see size +*/ + +/*! \fn bool QCPBarsGroup::contains(QCPBars *bars) + + Returns whether the specified \a bars plottable is part of this group. + +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new bars group for the specified QCustomPlot instance. +*/ +QCPBarsGroup::QCPBarsGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot), + mSpacingType(stAbsolute), + mSpacing(4) +{ +} + +QCPBarsGroup::~QCPBarsGroup() +{ + clear(); +} + +/*! + Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. + + The actual spacing can then be specified with \ref setSpacing. + + \see setSpacing +*/ +void QCPBarsGroup::setSpacingType(SpacingType spacingType) +{ + mSpacingType = spacingType; +} + +/*! + Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is + defined by the current \ref SpacingType, which can be set with \ref setSpacingType. + + \see setSpacingType +*/ +void QCPBarsGroup::setSpacing(double spacing) +{ + mSpacing = spacing; +} + +/*! + Returns the QCPBars instance with the specified \a index in this group. If no such QCPBars + exists, returns 0. + + \see bars(), size +*/ +QCPBars *QCPBarsGroup::bars(int index) const +{ + if (index >= 0 && index < mBars.size()) + { + return mBars.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Removes all QCPBars plottables from this group. + + \see isEmpty +*/ +void QCPBarsGroup::clear() +{ + foreach (QCPBars *bars, mBars) // since foreach takes a copy, removing bars in the loop is okay + bars->setBarsGroup(0); // removes itself via removeBars +} + +/*! + Adds the specified \a bars plottable to this group. Alternatively, you can also use \ref + QCPBars::setBarsGroup on the \a bars instance. + + \see insert, remove +*/ +void QCPBarsGroup::append(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + else + qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast(bars); +} + +/*! + Inserts the specified \a bars plottable into this group at the specified index position \a i. + This gives you full control over the ordering of the bars. + + \a bars may already be part of this group. In that case, \a bars is just moved to the new index + position. + + \see append, remove +*/ +void QCPBarsGroup::insert(int i, QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + // first append to bars list normally: + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + // then move to according position: + mBars.move(mBars.indexOf(bars), qBound(0, i, mBars.size()-1)); +} + +/*! + Removes the specified \a bars plottable from this group. + + \see contains, clear +*/ +void QCPBarsGroup::remove(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (mBars.contains(bars)) + bars->setBarsGroup(0); + else + qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast(bars); +} + +/*! \internal + + Adds the specified \a bars to the internal mBars list of bars. This method does not change the + barsGroup property on \a bars. + + \see unregisterBars +*/ +void QCPBarsGroup::registerBars(QCPBars *bars) +{ + if (!mBars.contains(bars)) + mBars.append(bars); +} + +/*! \internal + + Removes the specified \a bars from the internal mBars list of bars. This method does not change + the barsGroup property on \a bars. + + \see registerBars +*/ +void QCPBarsGroup::unregisterBars(QCPBars *bars) +{ + mBars.removeOne(bars); +} + +/*! \internal + + Returns the pixel offset in the key dimension the specified \a bars plottable should have at the + given key coordinate \a keyCoord. The offset is relative to the pixel position of the key + coordinate \a keyCoord. +*/ +double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) +{ + // find list of all base bars in case some mBars are stacked: + QList baseBars; + foreach (const QCPBars *b, mBars) + { + while (b->barBelow()) + b = b->barBelow(); + if (!baseBars.contains(b)) + baseBars.append(b); + } + // find base bar this "bars" is stacked on: + const QCPBars *thisBase = bars; + while (thisBase->barBelow()) + thisBase = thisBase->barBelow(); + + // determine key pixel offset of this base bars considering all other base bars in this barsgroup: + double result = 0; + int index = baseBars.indexOf(thisBase); + if (index >= 0) + { + if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose) + { + return result; + } else + { + double lowerPixelWidth, upperPixelWidth; + int startIndex; + int dir = (index <= (baseBars.size()-1)/2) ? -1 : 1; // if bar is to lower keys of center, dir is negative + if (baseBars.size() % 2 == 0) // even number of bars + { + startIndex = baseBars.size()/2 + (dir < 0 ? -1 : 0); + result += getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing + } else // uneven number of bars + { + startIndex = (baseBars.size()-1)/2+dir; + baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar + result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing + } + for (int i = startIndex; i != index; i += dir) // add widths and spacings of bars in between center and our bars + { + baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth); + result += getPixelSpacing(baseBars.at(i), keyCoord); + } + // finally half of our bars width: + baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; + // correct sign of result depending on orientation and direction of key axis: + result *= dir*thisBase->keyAxis()->pixelOrientation(); + } + } + return result; +} + +/*! \internal + + Returns the spacing in pixels which is between this \a bars and the following one, both at the + key coordinate \a keyCoord. + + \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only + needed to get access to the key axis transformation and axis rect for the modes \ref + stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in + \ref stPlotCoords on a logarithmic axis. +*/ +double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) +{ + switch (mSpacingType) + { + case stAbsolute: + { + return mSpacing; + } + case stAxisRectRatio: + { + if (bars->keyAxis()->orientation() == Qt::Horizontal) + return bars->keyAxis()->axisRect()->width()*mSpacing; + else + return bars->keyAxis()->axisRect()->height()*mSpacing; + } + case stPlotCoords: + { + double keyPixel = bars->keyAxis()->coordToPixel(keyCoord); + return qAbs(bars->keyAxis()->coordToPixel(keyCoord+mSpacing)-keyPixel); + } + } + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBarsData + \brief Holds the data of one single data point (one bar) for QCPBars. + + The stored data is: + \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey) + \li \a value: height coordinate on the value axis of this bar (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPBarsData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPBarsDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPBarsData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPBarsData QCPBarsData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPBarsData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPBarsData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a bar data point with key and value set to zero. +*/ +QCPBarsData::QCPBarsData() : + key(0), + value(0) +{ +} + +/*! + Constructs a bar data point with the specified \a key and \a value. +*/ +QCPBarsData::QCPBarsData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBars + \brief A plottable representing a bar chart in a plot. + + \image html QCPBars.png + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section qcpbars-appearance Changing the appearance + + The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). + The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. + + Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other + (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear + stacked. + + If you would like to group multiple QCPBars plottables together so they appear side by side as + shown below, use QCPBarsGroup. + + \image html QCPBarsGroup.png + + \section qcpbars-usage Usage + + Like all data representing objects in QCustomPlot, the QCPBars is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/*! \fn QCPBars *QCPBars::barBelow() const + Returns the bars plottable that is directly below this bars plottable. + If there is no such plottable, returns 0. + + \see barAbove, moveBelow, moveAbove +*/ + +/*! \fn QCPBars *QCPBars::barAbove() const + Returns the bars plottable that is directly above this bars plottable. + If there is no such plottable, returns 0. + + \see barBelow, moveBelow, moveAbove +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.75), + mWidthType(wtPlotCoords), + mBarsGroup(0), + mBaseValue(0), + mStackingGap(0) +{ + // modify inherited properties from abstract plottable: + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(QColor(40, 50, 255, 30)); + mBrush.setStyle(Qt::SolidPattern); + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPBars::~QCPBars() +{ + setBarsGroup(0); + if (mBarBelow || mBarAbove) + connectBars(mBarBelow.data(), mBarAbove.data()); // take this bar out of any stacking +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPBars may share the same data container safely. + Modifying the data in the container will then affect all bars that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the bar's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-2 + + \see addData +*/ +void QCPBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPBars::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets the width of the bars. + + How the number passed as \a width is interpreted (e.g. screen pixels, plot coordinates,...), + depends on the currently set width type, see \ref setWidthType and \ref WidthType. +*/ +void QCPBars::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the bars is defined. See the documentation of \ref WidthType for an + explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPBars::setWidthType(QCPBars::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref + QCPBarsGroup::append. + + To remove this QCPBars from any group, set \a barsGroup to 0. +*/ +void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) +{ + // deregister at old group: + if (mBarsGroup) + mBarsGroup->unregisterBars(this); + mBarsGroup = barsGroup; + // register at new group: + if (mBarsGroup) + mBarsGroup->registerBars(this); +} + +/*! + Sets the base value of this bars plottable. + + The base value defines where on the value coordinate the bars start. How far the bars extend from + the base value is given by their individual value data. For example, if the base value is set to + 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at + 3. + + For stacked bars, only the base value of the bottom-most QCPBars has meaning. + + The default base value is 0. +*/ +void QCPBars::setBaseValue(double baseValue) +{ + mBaseValue = baseValue; +} + +/*! + If this bars plottable is stacked on top of another bars plottable (\ref moveAbove), this method + allows specifying a distance in \a pixels, by which the drawn bar rectangles will be separated by + the bars below it. +*/ +void QCPBars::setStackingGap(double pixels) +{ + mStackingGap = pixels; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(double key, double value) +{ + mDataContainer->add(QCPBarsData(key, value)); +} + +/*! + Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear + below the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object below itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barAbove, barBelow +*/ +void QCPBars::moveBelow(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar below it: + if (bars) + { + if (bars->mBarBelow) + connectBars(bars->mBarBelow.data(), this); + connectBars(this, bars); + } +} + +/*! + Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear + above the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object above itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barBelow, barAbove +*/ +void QCPBars::moveAbove(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar above it: + if (bars) + { + if (bars->mBarAbove) + connectBars(this, bars->mBarAbove.data()); + connectBars(bars, this); + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getBarRect(it->key, it->value))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getBarRect(it->key, it->value).contains(pos)) + { + if (details) + { + int pointIndex = it-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return mParentPlot->selectionTolerance()*0.99; + } + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + /* Note: If this QCPBars uses absolute pixels as width (or is in a QCPBarsGroup with spacing in + absolute pixels), using this method to adapt the key axis range to fit the bars into the + currently visible axis range will not work perfectly. Because in the moment the axis range is + changed to the new range, the fixed pixel widths/spacings will represent different coordinate + spans than before, which in turn would require a different key range to perfectly fit, and so on. + The only solution would be to iteratively approach the perfect fitting axis range, but the + mismatch isn't large enough in most applications, to warrant this here. If a user does need a + better fit, he should call the corresponding axis rescale multiple times in a row. + */ + QCPRange range; + range = mDataContainer->keyRange(foundRange, inSignDomain); + + // determine exact range of bars by including bar width and barsgroup offset: + if (foundRange && mKeyAxis) + { + double lowerPixelWidth, upperPixelWidth, keyPixel; + // lower range bound: + getPixelWidth(range.lower, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.lower) + lowerPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.lower); + const double lowerCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(lowerCorrected) && qIsFinite(lowerCorrected) && range.lower > lowerCorrected) + range.lower = lowerCorrected; + // upper range bound: + getPixelWidth(range.upper, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.upper) + upperPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.upper); + const double upperCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(upperCorrected) && qIsFinite(upperCorrected) && range.upper < upperCorrected) + range.upper = upperCorrected; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + // Note: can't simply use mDataContainer->valueRange here because we need to + // take into account bar base value and possible stacking of multiple bars + QCPRange range; + range.lower = mBaseValue; + range.upper = mBaseValue; + bool haveLower = true; // set to true, because baseValue should always be visible in bar charts + bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts + QCPBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (inKeyRange != QCPRange()) + { + itBegin = mDataContainer->findBegin(inKeyRange.lower); + itEnd = mDataContainer->findEnd(inKeyRange.upper); + } + for (QCPBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + const double current = it->value + getStackedBaseValue(it->key, it->value >= 0); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + + foundRange = true; // return true because bar charts always have the 0-line visible + return range; +} + +/* inherits documentation from base class */ +QPointF QCPBars::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + const QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value); + const double keyPixel = keyAxis->coordToPixel(it->key) + (mBarsGroup ? mBarsGroup->keyPixelOffset(this, it->key) : 0); + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyPixel, valuePixel); + else + return QPointF(valuePixel, keyPixel); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/* inherits documentation from base class */ +void QCPBars::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mDataContainer->isEmpty()) return; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPBarsDataContainer::const_iterator begin = visibleBegin; + QCPBarsDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +#endif + // draw bar: + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyBrush(painter); + mSelectionDecorator->applyPen(painter); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + } + applyDefaultAntialiasingHint(painter); + painter->drawPolygon(getBarRect(it->key, it->value)); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setBrush(mBrush); + painter->setPen(mPen); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + if (mDataContainer->isEmpty()) + { + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + + // get visible data range as QMap iterators + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower); + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper); + double lowerPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().lower); + double upperPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().upper); + bool isVisible = false; + // walk left from begin to find lower bar that actually is completely outside visible pixel range: + QCPBarsDataContainer::const_iterator it = begin; + while (it != mDataContainer->constBegin()) + { + --it; + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.left() <= lowerPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.bottom() >= lowerPixelBound)); + if (isVisible) + begin = it; + else + break; + } + // walk right from ubound to find upper bar that actually is completely outside visible pixel range: + it = end; + while (it != mDataContainer->constEnd()) + { + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.right() >= upperPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.bottom() >= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.top() <= upperPixelBound)); + if (isVisible) + end = it+1; + else + break; + ++it; + } +} + +/*! \internal + + Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The + rect is shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref + setBaseValue), and to have non-overlapping border lines with the bars stacked below. +*/ +QRectF QCPBars::getBarRect(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } + + double lowerPixelWidth, upperPixelWidth; + getPixelWidth(key, lowerPixelWidth, upperPixelWidth); + double base = getStackedBaseValue(key, value >= 0); + double basePixel = valueAxis->coordToPixel(base); + double valuePixel = valueAxis->coordToPixel(base+value); + double keyPixel = keyAxis->coordToPixel(key); + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, key); + double bottomOffset = (mBarBelow && mPen != Qt::NoPen ? 1 : 0)*(mPen.isCosmetic() ? 1 : mPen.widthF()); + bottomOffset += mBarBelow ? mStackingGap : 0; + bottomOffset *= (value<0 ? -1 : 1)*valueAxis->pixelOrientation(); + if (qAbs(valuePixel-basePixel) <= qAbs(bottomOffset)) + bottomOffset = valuePixel-basePixel; + if (keyAxis->orientation() == Qt::Horizontal) + { + return QRectF(QPointF(keyPixel+lowerPixelWidth, valuePixel), QPointF(keyPixel+upperPixelWidth, basePixel+bottomOffset)).normalized(); + } else + { + return QRectF(QPointF(basePixel+bottomOffset, keyPixel+lowerPixelWidth), QPointF(valuePixel, keyPixel+upperPixelWidth)).normalized(); + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). + + The output parameters \a lower and \a upper return the number of pixels the bar extends to lower + and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a + lower is negative and \a upper positive). +*/ +void QCPBars::getPixelWidth(double key, double &lower, double &upper) const +{ + lower = 0; + upper = 0; + switch (mWidthType) + { + case wtAbsolute: + { + upper = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + upper = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + upper = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + { + double keyPixel = mKeyAxis.data()->coordToPixel(key); + upper = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + lower = mKeyAxis.data()->coordToPixel(key-mWidth*0.5)-keyPixel; + // no need to qSwap(lower, higher) when range reversed, because higher/lower are gained by + // coordinate transform which includes range direction + } else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } +} + +/*! \internal + + This function is called to find at which value to start drawing the base of a bar at \a key, when + it is stacked on top of another QCPBars (e.g. with \ref moveAbove). + + positive and negative bars are separated per stack (positive are stacked above baseValue upwards, + negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the + bar for which we need the base value is negative, set \a positive to false. +*/ +double QCPBars::getStackedBaseValue(double key, bool positive) const +{ + if (mBarBelow) + { + double max = 0; // don't initialize with mBaseValue here because only base value of bottom-most bar has meaning in a bar stack + // find bars of mBarBelow that are approximately at key and find largest one: + double epsilon = qAbs(key)*(sizeof(key)==4 ? 1e-6 : 1e-14); // should be safe even when changed to use float at some point + if (key == 0) + epsilon = (sizeof(key)==4 ? 1e-6 : 1e-14); + QCPBarsDataContainer::const_iterator it = mBarBelow.data()->mDataContainer->findBegin(key-epsilon); + QCPBarsDataContainer::const_iterator itEnd = mBarBelow.data()->mDataContainer->findEnd(key+epsilon); + while (it != itEnd) + { + if (it->key > key-epsilon && it->key < key+epsilon) + { + if ((positive && it->value > max) || + (!positive && it->value < max)) + max = it->value; + } + ++it; + } + // recurse down the bar-stack to find the total height: + return max + mBarBelow.data()->getStackedBaseValue(key, positive); + } else + return mBaseValue; +} + +/*! \internal + + Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) + currently above lower and below upper will become disconnected to lower/upper. + + If lower is zero, upper will be disconnected at the bottom. + If upper is zero, lower will be disconnected at the top. +*/ +void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) +{ + if (!lower && !upper) return; + + if (!lower) // disconnect upper at bottom + { + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + upper->mBarBelow = 0; + } else if (!upper) // disconnect lower at top + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + lower->mBarAbove = 0; + } else // connect lower and upper + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + lower->mBarAbove = upper; + upper->mBarBelow = lower; + } +} +/* end of 'src/plottables/plottable-bars.cpp' */ + + +/* including file 'src/plottables/plottable-statisticalbox.cpp', size 28622 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBoxData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBoxData + \brief Holds the data of one single data point for QCPStatisticalBox. + + The stored data is: + + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + + \li \a minimum: the position of the lower whisker, typically the minimum measurement of the + sample that's not considered an outlier. + + \li \a lowerQuartile: the lower end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a median: the value of the median mark inside the quartile box. The median separates the + sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue) + + \li \a upperQuartile: the upper end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a maximum: the position of the upper whisker, typically the maximum measurement of the + sample that's not considered an outlier. + + \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key + coordinate of this data point (see \ref QCPStatisticalBox::setOutlierStyle) + + The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a + typedef for \ref QCPDataContainer with \ref QCPStatisticalBoxData as the DataType template + parameter. See the documentation there for an explanation regarding the data type's generic + methods. + + \see QCPStatisticalBoxDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPStatisticalBoxData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPStatisticalBoxData QCPStatisticalBoxData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPStatisticalBoxData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainValue() const + + Returns the \a median member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPStatisticalBoxData::valueRange() const + + Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box + data point, possibly further expanded by outliers. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData() : + key(0), + minimum(0), + lowerQuartile(0), + median(0), + upperQuartile(0), + maximum(0) +{ +} + +/*! + Constructs a data point with the specified \a key, \a minimum, \a lowerQuartile, \a median, \a + upperQuartile, \a maximum and optionally a number of \a outliers. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) : + key(key), + minimum(minimum), + lowerQuartile(lowerQuartile), + median(median), + upperQuartile(upperQuartile), + maximum(maximum), + outliers(outliers) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBox +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBox + \brief A plottable representing a single statistical box in a plot. + + \image html QCPStatisticalBox.png + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPStatisticalBoxDataContainer. + + Additionally each data point can itself have a list of outliers, drawn as scatter points at the + key coordinate of the respective statistical box data point. They can either be set by using the + respective \ref addData(double,double,double,double,double,double,const QVector&) + "addData" method or accessing the individual data points through \ref data, and setting the + QVector outliers of the data points directly. + + \section qcpstatisticalbox-appearance Changing the appearance + + The appearance of each data point box, ranging from the lower to the upper quartile, is + controlled via \ref setPen and \ref setBrush. You may change the width of the boxes with \ref + setWidth in plot coordinates. + + Each data point's visual representation also consists of two whiskers. Whiskers are the lines + which reach from the upper quartile to the maximum, and from the lower quartile to the minimum. + The appearance of the whiskers can be modified with: \ref setWhiskerPen, \ref setWhiskerBarPen, + \ref setWhiskerWidth. The whisker width is the width of the bar perpendicular to the whisker at + the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set + the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a + few pixels due to the pen cap being not perfectly flat. + + The median indicator line inside the box has its own pen, \ref setMedianPen. + + The outlier data points are drawn as normal scatter points. Their look can be controlled with + \ref setOutlierStyle + + \section qcpstatisticalbox-usage Usage + + Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-2 +*/ + +/* start documentation of inline functions */ + +/*! \fn QSharedPointer QCPStatisticalBox::data() const + + Returns a shared pointer to the internal data storage of type \ref + QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more + convenient and faster than using the regular \ref setData or \ref addData methods. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its + value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and + not have the same orientation. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not + delete it manually but use QCustomPlot::removePlottable() instead. +*/ +QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.5), + mWhiskerWidth(0.2), + mWhiskerPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap), + mWhiskerBarPen(Qt::black), + mWhiskerAntialiased(false), + mMedianPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap), + mOutlierStyle(QCPScatterStyle::ssCircle, Qt::blue, 6) +{ + setPen(QPen(Qt::black)); + setBrush(Qt::NoBrush); +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container + safely. Modifying the data in the container will then affect all statistical boxes that share the + container. Sharing can be achieved by simply exchanging the data containers wrapped in shared + pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the statistical box data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-2 + + \see addData +*/ +void QCPStatisticalBox::setData(QSharedPointer data) +{ + mDataContainer = data; +} +/*! \overload + + Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a + median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the + number of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPStatisticalBox::setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, minimum, lowerQuartile, median, upperQuartile, maximum, alreadySorted); +} + +/*! + Sets the width of the boxes in key coordinates. + + \see setWhiskerWidth +*/ +void QCPStatisticalBox::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the width of the whiskers in key coordinates. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWidth +*/ +void QCPStatisticalBox::setWhiskerWidth(double width) +{ + mWhiskerWidth = width; +} + +/*! + Sets the pen used for drawing the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + Make sure to set the \c capStyle of the passed \a pen to \c Qt::FlatCap. Otherwise the backbone + line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat. + + \see setWhiskerBarPen +*/ +void QCPStatisticalBox::setWhiskerPen(const QPen &pen) +{ + mWhiskerPen = pen; +} + +/*! + Sets the pen used for drawing the whisker bars. Those are the lines parallel to the key axis at + each end of the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWhiskerPen +*/ +void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) +{ + mWhiskerBarPen = pen; +} + +/*! + Sets whether the statistical boxes whiskers are drawn with antialiasing or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPStatisticalBox::setWhiskerAntialiased(bool enabled) +{ + mWhiskerAntialiased = enabled; +} + +/*! + Sets the pen used for drawing the median indicator line inside the statistical boxes. +*/ +void QCPStatisticalBox::setMedianPen(const QPen &pen) +{ + mMedianPen = pen; +} + +/*! + Sets the appearance of the outlier data points. + + Outliers can be specified with the method + \ref addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +*/ +void QCPStatisticalBox::setOutlierStyle(const QCPScatterStyle &style) +{ + mOutlierStyle = style; +} + +/*! \overload + + Adds the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and + \a maximum to the current data. The provided vectors should have equal length. Else, the number + of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + if (keys.size() != minimum.size() || minimum.size() != lowerQuartile.size() || lowerQuartile.size() != median.size() || + median.size() != upperQuartile.size() || upperQuartile.size() != maximum.size() || maximum.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, minimum, lowerQuartile, median, upperQuartile, maximum have different sizes:" + << keys.size() << minimum.size() << lowerQuartile.size() << median.size() << upperQuartile.size() << maximum.size(); + const int n = qMin(keys.size(), qMin(minimum.size(), qMin(lowerQuartile.size(), qMin(median.size(), qMin(upperQuartile.size(), maximum.size()))))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->minimum = minimum[i]; + it->lowerQuartile = lowerQuartile[i]; + it->median = median[i]; + it->upperQuartile = upperQuartile[i]; + it->maximum = maximum[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a minimum, \a lowerQuartile, \a median, \a upperQuartile + and \a maximum to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +{ + mDataContainer->add(QCPStatisticalBoxData(key, minimum, lowerQuartile, median, upperQuartile, maximum, outliers)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPStatisticalBox::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getQuartileBox(it))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + QCPStatisticalBoxDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + double minDistSqr = std::numeric_limits::max(); + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getQuartileBox(it).contains(pos)) // quartile box + { + double currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } else // whiskers + { + const QVector whiskerBackbones(getWhiskerBackboneLines(it)); + for (int i=0; iconstBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return qSqrt(minDistSqr); + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPStatisticalBoxDataContainer::const_iterator begin = visibleBegin; + QCPStatisticalBoxDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPStatisticalBoxDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +# ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->minimum) || + QCP::isInvalidData(it->lowerQuartile, it->median) || + QCP::isInvalidData(it->upperQuartile, it->maximum)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range has invalid data." << "Plottable name:" << name(); + for (int i=0; ioutliers.size(); ++i) + if (QCP::isInvalidData(it->outliers.at(i))) + qDebug() << Q_FUNC_INFO << "Data point outlier at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +# endif + + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + QCPScatterStyle finalOutlierStyle = mOutlierStyle; + if (isSelectedSegment && mSelectionDecorator) + finalOutlierStyle = mSelectionDecorator->getFinalScatterStyle(mOutlierStyle); + drawStatisticalBox(painter, it, finalOutlierStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->setBrush(mBrush); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! + Draws the graphical representation of a single statistical box with the data given by the + iterator \a it with the provided \a painter. + + If the statistical box has a set of outlier data points, they are drawn with \a outlierStyle. + + \see getQuartileBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const +{ + // draw quartile box: + applyDefaultAntialiasingHint(painter); + const QRectF quartileBox = getQuartileBox(it); + painter->drawRect(quartileBox); + // draw median line with cliprect set to quartile box: + painter->save(); + painter->setClipRect(quartileBox, Qt::IntersectClip); + painter->setPen(mMedianPen); + painter->drawLine(QLineF(coordsToPixels(it->key-mWidth*0.5, it->median), coordsToPixels(it->key+mWidth*0.5, it->median))); + painter->restore(); + // draw whisker lines: + applyAntialiasingHint(painter, mWhiskerAntialiased, QCP::aePlottables); + painter->setPen(mWhiskerPen); + painter->drawLines(getWhiskerBackboneLines(it)); + painter->setPen(mWhiskerBarPen); + painter->drawLines(getWhiskerBarLines(it)); + // draw outliers: + applyScattersAntialiasingHint(painter); + outlierStyle.applyTo(painter, mPen); + for (int i=0; ioutliers.size(); ++i) + outlierStyle.drawShape(painter, coordsToPixels(it->key, it->outliers.at(i))); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of box to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of box to include partially visible data points +} + +/*! \internal + + Returns the box in plot coordinates (keys in x, values in y of the returned rect) that covers the + value range from the lower to the upper quartile, of the data given by \a it. + + \see drawStatisticalBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +QRectF QCPStatisticalBox::getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QRectF result; + result.setTopLeft(coordsToPixels(it->key-mWidth*0.5, it->upperQuartile)); + result.setBottomRight(coordsToPixels(it->key+mWidth*0.5, it->lowerQuartile)); + return result; +} + +/*! \internal + + Returns the whisker backbones (keys in x, values in y of the returned lines) that cover the value + range from the minimum to the lower quartile, and from the upper quartile to the maximum of the + data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBarLines +*/ +QVector QCPStatisticalBox::getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key, it->lowerQuartile), coordsToPixels(it->key, it->minimum)); // min backbone + result[1].setPoints(coordsToPixels(it->key, it->upperQuartile), coordsToPixels(it->key, it->maximum)); // max backbone + return result; +} + +/*! \internal + + Returns the whisker bars (keys in x, values in y of the returned lines) that are placed at the + end of the whisker backbones, at the minimum and maximum of the data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBackboneLines +*/ +QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->minimum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->minimum)); // min bar + result[1].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->maximum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->maximum)); // max bar + return result; +} +/* end of 'src/plottables/plottable-statisticalbox.cpp' */ + + +/* including file 'src/plottables/plottable-colormap.cpp', size 47881 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorMapData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorMapData + \brief Holds the two-dimensional data of a QCPColorMap plottable. + + This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref + QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a + color, depending on the value. + + The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). + Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref + setKeyRange, \ref setValueRange). + + The data cells can be accessed in two ways: They can be directly addressed by an integer index + with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot + coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are + provided by the functions \ref coordToCell and \ref cellToCoord. + + A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if + allocated) has the same size as the data map. It can be accessed via \ref setAlpha, \ref + fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on + the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map. + + This class also buffers the minimum and maximum values that are in the data set, to provide + QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value + that is greater than the current maximum increases this maximum to the new value. However, + setting the cell that currently holds the maximum value to a smaller value doesn't decrease the + maximum again, because finding the true new maximum would require going through the entire data + array, which might be time consuming. The same holds for the data minimum. This functionality is + given by \ref recalculateDataBounds, such that you can decide when it is sensible to find the + true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience + parameter \a recalculateDataBounds which may be set to true to automatically call \ref + recalculateDataBounds internally. +*/ + +/* start of documentation of inline functions */ + +/*! \fn bool QCPColorMapData::isEmpty() const + + Returns whether this instance carries no data. This is equivalent to having a size where at least + one of the dimensions is 0 (see \ref setSize). +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction + and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap + at the coordinates \a keyRange and \a valueRange. + + \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange +*/ +QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : + mKeySize(0), + mValueSize(0), + mKeyRange(keyRange), + mValueRange(valueRange), + mIsEmpty(true), + mData(0), + mAlpha(0), + mDataModified(true) +{ + setSize(keySize, valueSize); + fill(0); +} + +QCPColorMapData::~QCPColorMapData() +{ + if (mData) + delete[] mData; + if (mAlpha) + delete[] mAlpha; +} + +/*! + Constructs a new QCPColorMapData instance copying the data and range of \a other. +*/ +QCPColorMapData::QCPColorMapData(const QCPColorMapData &other) : + mKeySize(0), + mValueSize(0), + mIsEmpty(true), + mData(0), + mAlpha(0), + mDataModified(true) +{ + *this = other; +} + +/*! + Overwrites this color map data instance with the data stored in \a other. The alpha map state is + transferred, too. +*/ +QCPColorMapData &QCPColorMapData::operator=(const QCPColorMapData &other) +{ + if (&other != this) + { + const int keySize = other.keySize(); + const int valueSize = other.valueSize(); + if (!other.mAlpha && mAlpha) + clearAlpha(); + setSize(keySize, valueSize); + if (other.mAlpha && !mAlpha) + createAlpha(false); + setRange(other.keyRange(), other.valueRange()); + if (!isEmpty()) + { + memcpy(mData, other.mData, sizeof(mData[0])*keySize*valueSize); + if (mAlpha) + memcpy(mAlpha, other.mAlpha, sizeof(mAlpha[0])*keySize*valueSize); + } + mDataBounds = other.mDataBounds; + mDataModified = true; + } + return *this; +} + +/* undocumented getter */ +double QCPColorMapData::data(double key, double value) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + return mData[valueCell*mKeySize + keyCell]; + else + return 0; +} + +/* undocumented getter */ +double QCPColorMapData::cell(int keyIndex, int valueIndex) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mData[valueIndex*mKeySize + keyIndex]; + else + return 0; +} + +/*! + Returns the alpha map value of the cell with the indices \a keyIndex and \a valueIndex. + + If this color map data doesn't have an alpha map (because \ref setAlpha was never called after + creation or after a call to \ref clearAlpha), returns 255, which corresponds to full opacity. + + \see setAlpha +*/ +unsigned char QCPColorMapData::alpha(int keyIndex, int valueIndex) +{ + if (mAlpha && keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mAlpha[valueIndex*mKeySize + keyIndex]; + else + return 255; +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in + the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref + isEmpty returns true. + + \see setRange, setKeySize, setValueSize +*/ +void QCPColorMapData::setSize(int keySize, int valueSize) +{ + if (keySize != mKeySize || valueSize != mValueSize) + { + mKeySize = keySize; + mValueSize = valueSize; + if (mData) + delete[] mData; + mIsEmpty = mKeySize == 0 || mValueSize == 0; + if (!mIsEmpty) + { +#ifdef __EXCEPTIONS + try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message +#endif + mData = new double[mKeySize*mValueSize]; +#ifdef __EXCEPTIONS + } catch (...) { mData = 0; } +#endif + if (mData) + fill(0); + else + qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; + } else + mData = 0; + + if (mAlpha) // if we had an alpha map, recreate it with new size + createAlpha(); + + mDataModified = true; + } +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. + + \see setKeyRange, setSize, setValueSize +*/ +void QCPColorMapData::setKeySize(int keySize) +{ + setSize(keySize, mValueSize); +} + +/*! + Resizes the data array to have \a valueSize cells in the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. + + \see setValueRange, setSize, setKeySize +*/ +void QCPColorMapData::setValueSize(int valueSize) +{ + setSize(mKeySize, valueSize); +} + +/*! + Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area + covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setSize +*/ +void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) +{ + setKeyRange(keyRange); + setValueRange(valueRange); +} + +/*! + Sets the coordinate range the data shall be distributed over in the key dimension. Together with + the value range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setRange, setValueRange, setSize +*/ +void QCPColorMapData::setKeyRange(const QCPRange &keyRange) +{ + mKeyRange = keyRange; +} + +/*! + Sets the coordinate range the data shall be distributed over in the value dimension. Together with + the key range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there + will be cells centered on the value coordinates 2, 2.5 and 3. + + \see setRange, setKeyRange, setSize +*/ +void QCPColorMapData::setValueRange(const QCPRange &valueRange) +{ + mValueRange = valueRange; +} + +/*! + Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a + z. + + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or + value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, + you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to + determine the cell index. Rather directly access the cell index with \ref + QCPColorMapData::setCell. + + \see setCell, setRange +*/ +void QCPColorMapData::setData(double key, double value, double z) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + { + mData[valueCell*mKeySize + keyCell] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } +} + +/*! + Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices + enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see + \ref setSize). + + In the standard plot configuration (horizontal key axis and vertical value axis, both not + range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with + indices (keySize-1, valueSize-1) is in the top right corner of the color map. + + \see setData, setSize +*/ +void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + mData[valueIndex*mKeySize + keyIndex] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Sets the alpha of the color map cell given by \a keyIndex and \a valueIndex to \a alpha. A value + of 0 for \a alpha results in a fully transparent cell, and a value of 255 results in a fully + opaque cell. + + If an alpha map doesn't exist yet for this color map data, it will be created here. If you wish + to restore full opacity and free any allocated memory of the alpha map, call \ref clearAlpha. + + Note that the cell-wise alpha which can be configured here is independent of any alpha configured + in the color map's gradient (\ref QCPColorGradient). If a cell is affected both by the cell-wise + and gradient alpha, the alpha values will be blended accordingly during rendering of the color + map. + + \see fillAlpha, clearAlpha +*/ +void QCPColorMapData::setAlpha(int keyIndex, int valueIndex, unsigned char alpha) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + if (mAlpha || createAlpha()) + { + mAlpha[valueIndex*mKeySize + keyIndex] = alpha; + mDataModified = true; + } + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Goes through the data and updates the buffered minimum and maximum data values. + + Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange + and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten + with a smaller or larger value respectively, since the buffered maximum/minimum values have been + updated the last time. Why this is the case is explained in the class description (\ref + QCPColorMapData). + + Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a + recalculateDataBounds for convenience. Setting this to true will call this method for you, before + doing the rescale. +*/ +void QCPColorMapData::recalculateDataBounds() +{ + if (mKeySize > 0 && mValueSize > 0) + { + double minHeight = mData[0]; + double maxHeight = mData[0]; + const int dataCount = mValueSize*mKeySize; + for (int i=0; i maxHeight) + maxHeight = mData[i]; + if (mData[i] < minHeight) + minHeight = mData[i]; + } + mDataBounds.lower = minHeight; + mDataBounds.upper = maxHeight; + } +} + +/*! + Frees the internal data memory. + + This is equivalent to calling \ref setSize "setSize(0, 0)". +*/ +void QCPColorMapData::clear() +{ + setSize(0, 0); +} + +/*! + Frees the internal alpha map. The color map will have full opacity again. +*/ +void QCPColorMapData::clearAlpha() +{ + if (mAlpha) + { + delete[] mAlpha; + mAlpha = 0; + mDataModified = true; + } +} + +/*! + Sets all cells to the value \a z. +*/ +void QCPColorMapData::fill(double z) +{ + const int dataCount = mValueSize*mKeySize; + for (int i=0; i(data); + return; + } + if (copy) + { + *mMapData = *data; + } else + { + delete mMapData; + mMapData = data; + } + mMapImageInvalidated = true; +} + +/*! + Sets the data range of this color map to \a dataRange. The data range defines which data values + are mapped to the color gradient. + + To make the data range span the full range of the data set, use \ref rescaleDataRange. + + \see QCPColorScale::setDataRange +*/ +void QCPColorMap::setDataRange(const QCPRange &dataRange) +{ + if (!QCPRange::validRange(dataRange)) return; + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + if (mDataScaleType == QCPAxis::stLogarithmic) + mDataRange = dataRange.sanitizedForLogScale(); + else + mDataRange = dataRange.sanitizedForLinScale(); + mMapImageInvalidated = true; + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets whether the data is correlated with the color gradient linearly or logarithmically. + + \see QCPColorScale::setDataScaleType +*/ +void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + mMapImageInvalidated = true; + emit dataScaleTypeChanged(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + } +} + +/*! + Sets the color gradient that is used to represent the data. For more details on how to create an + own gradient or use one of the preset gradients, see \ref QCPColorGradient. + + The colors defined by the gradient will be used to represent data values in the currently set + data range, see \ref setDataRange. Data points that are outside this data range will either be + colored uniformly with the respective gradient boundary color, or the gradient will repeat, + depending on \ref QCPColorGradient::setPeriodic. + + \see QCPColorScale::setGradient +*/ +void QCPColorMap::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + mMapImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets whether the color map image shall use bicubic interpolation when displaying the color map + shrinked or expanded, and not at a 1:1 pixel-to-data scale. + + \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" +*/ +void QCPColorMap::setInterpolate(bool enabled) +{ + mInterpolate = enabled; + mMapImageInvalidated = true; // because oversampling factors might need to change +} + +/*! + Sets whether the outer most data rows and columns are clipped to the specified key and value + range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). + + if \a enabled is set to false, the data points at the border of the color map are drawn with the + same width and height as all other data points. Since the data points are represented by + rectangles of one color centered on the data coordinate, this means that the shown color map + extends by half a data point over the specified key/value range in each direction. + + \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" +*/ +void QCPColorMap::setTightBoundary(bool enabled) +{ + mTightBoundary = enabled; +} + +/*! + Associates the color scale \a colorScale with this color map. + + This means that both the color scale and the color map synchronize their gradient, data range and + data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps + can be associated with one single color scale. This causes the color maps to also synchronize + those properties, via the mutual color scale. + + This function causes the color map to adopt the current color gradient, data range and data scale + type of \a colorScale. After this call, you may change these properties at either the color map + or the color scale, and the setting will be applied to both. + + Pass 0 as \a colorScale to disconnect the color scale from this color map again. +*/ +void QCPColorMap::setColorScale(QCPColorScale *colorScale) +{ + if (mColorScale) // unconnect signals from old color scale + { + disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + mColorScale = colorScale; + if (mColorScale) // connect signals to new color scale + { + setGradient(mColorScale.data()->gradient()); + setDataRange(mColorScale.data()->dataRange()); + setDataScaleType(mColorScale.data()->dataScaleType()); + connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } +} + +/*! + Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the + current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, + only for the third data dimension of the color map. + + The minimum and maximum values of the data set are buffered in the internal QCPColorMapData + instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref + QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For + performance reasons, however, they are only updated in an expanding fashion. So the buffered + maximum can only increase and the buffered minimum can only decrease. In consequence, changes to + the data that actually lower the maximum of the data set (by overwriting the cell holding the + current maximum with a smaller value), aren't recognized and the buffered maximum overestimates + the true maximum of the data set. The same happens for the buffered minimum. To recalculate the + true minimum and maximum by explicitly looking at each cell, the method + QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a + recalculateDataBounds calls this method before setting the data range to the buffered minimum and + maximum. + + \see setDataRange +*/ +void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) +{ + if (recalculateDataBounds) + mMapData->recalculateDataBounds(); + setDataRange(mMapData->dataBounds()); +} + +/*! + Takes the current appearance of the color map and updates the legend icon, which is used to + represent this color map in the legend (see \ref QCPLegend). + + The \a transformMode specifies whether the rescaling is done by a faster, low quality image + scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm + (Qt::SmoothTransformation). + + The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to + the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured + legend icon size, the thumb will be rescaled during drawing of the legend item. + + \see setDataRange +*/ +void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) +{ + if (mMapImage.isNull() && !data()->isEmpty()) + updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) + + if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again + { + bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + } +} + +/* inherits documentation from base class */ +double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mMapData->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (mMapData->keyRange().contains(posKey) && mMapData->valueRange().contains(posValue)) + { + if (details) + details->setValue(QCPDataSelection(QCPDataRange(0, 1))); // temporary solution, to facilitate whole-plottable selection. Replace in future version with segmented 2D selection. + return mParentPlot->selectionTolerance()*0.99; + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + foundRange = true; + QCPRange result = mMapData->keyRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (inKeyRange != QCPRange()) + { + if (mMapData->keyRange().upper < inKeyRange.lower || mMapData->keyRange().lower > inKeyRange.upper) + { + foundRange = false; + return QCPRange(); + } + } + + foundRange = true; + QCPRange result = mMapData->valueRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/*! \internal + + Updates the internal map image buffer by going through the internal \ref QCPColorMapData and + turning the data values into color pixels with \ref QCPColorGradient::colorize. + + This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image + has been invalidated for a different reason (e.g. a change of the data range with \ref + setDataRange). + + If the map cell count is low, the image created will be oversampled in order to avoid a + QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images + without smooth transform enabled. Accordingly, oversampling isn't performed if \ref + setInterpolate is true. +*/ +void QCPColorMap::updateMapImage() +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) return; + if (mMapData->isEmpty()) return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + const int keySize = mMapData->keySize(); + const int valueSize = mMapData->valueSize(); + int keyOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)keySize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + int valueOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)valueSize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + + // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: + if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) + mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); + else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) + mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); + + if (mMapImage.isNull()) + { + qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; + mMapImage = QImage(QSize(10, 10), format); + mMapImage.fill(Qt::black); + } else + { + QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + // resize undersampled map image to actual key/value cell sizes: + if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) + mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); + else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) + mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); + localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image + } else if (!mUndersampledMapImage.isNull()) + mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it + + const double *rawData = mMapData->mData; + const unsigned char *rawAlpha = mMapData->mAlpha; + if (keyAxis->orientation() == Qt::Horizontal) + { + const int lineCount = valueSize; + const int rowCount = keySize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + } + } else // keyAxis->orientation() == Qt::Vertical + { + const int lineCount = keySize; + const int rowCount = valueSize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line, rawAlpha+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + } + } + + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + if (keyAxis->orientation() == Qt::Horizontal) + mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + else + mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + } + } + mMapData->mDataModified = false; + mMapImageInvalidated = false; +} + +/* inherits documentation from base class */ +void QCPColorMap::draw(QCPPainter *painter) +{ + if (mMapData->isEmpty()) return; + if (!mKeyAxis || !mValueAxis) return; + applyDefaultAntialiasingHint(painter); + + if (mMapData->mDataModified || mMapImageInvalidated) + updateMapImage(); + + // use buffer if painting vectorized (PDF): + const bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); + QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized + QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in + QPixmap mapBuffer; + if (useBuffer) + { + const double mapBufferPixelRatio = 3; // factor by which DPI is increased in embedded bitmaps + mapBufferTarget = painter->clipRegion().boundingRect(); + mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize()); + mapBuffer.fill(Qt::transparent); + localPainter = new QCPPainter(&mapBuffer); + localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); + localPainter->translate(-mapBufferTarget.topLeft()); + } + + QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): + double halfCellWidth = 0; // in pixels + double halfCellHeight = 0; // in pixels + if (keyAxis()->orientation() == Qt::Horizontal) + { + if (mMapData->keySize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->valueSize()-1); + } else // keyAxis orientation is Qt::Vertical + { + if (mMapData->keySize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->valueSize()-1); + } + imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight); + const bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + const bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + const bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, mInterpolate); + QRegion clipBackup; + if (mTightBoundary) + { + clipBackup = localPainter->clipRegion(); + QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + localPainter->setClipRect(tightClipRect, Qt::IntersectClip); + } + localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); + if (mTightBoundary) + localPainter->setClipRegion(clipBackup); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); + + if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter + { + delete localPainter; + painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer); + } +} + +/* inherits documentation from base class */ +void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + // draw map thumbnail: + if (!mLegendIcon.isNull()) + { + QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation); + QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height()); + iconRect.moveCenter(rect.center()); + painter->drawPixmap(iconRect.topLeft(), scaledIcon); + } + /* + // draw frame: + painter->setBrush(Qt::NoBrush); + painter->setPen(Qt::black); + painter->drawRect(rect.adjusted(1, 1, 0, 0)); + */ +} +/* end of 'src/plottables/plottable-colormap.cpp' */ + + +/* including file 'src/plottables/plottable-financial.cpp', size 42610 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancialData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancialData + \brief Holds the data of one single data point for QCPFinancial. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a open: The opening value at the data point (this is the \a mainValue) + \li \a high: The high/maximum value at the data point + \li \a low: The low/minimum value at the data point + \li \a close: The closing value at the data point + + The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef + for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPFinancialDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPFinancialData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPFinancialData QCPFinancialData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPFinancialData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainValue() const + + Returns the \a open member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPFinancialData::valueRange() const + + Returns a QCPRange spanning from the \a low to the \a high value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPFinancialData::QCPFinancialData() : + key(0), + open(0), + high(0), + low(0), + close(0) +{ +} + +/*! + Constructs a data point with the specified \a key and OHLC values. +*/ +QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) : + key(key), + open(open), + high(high), + low(low), + close(close) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancial +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancial + \brief A plottable representing a financial stock chart + + \image html QCPFinancial.png + + This plottable represents time series data binned to certain intervals, mainly used for stock + charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be + set via \ref setChartStyle. + + The data is passed via \ref setData as a set of open/high/low/close values at certain keys + (typically times). This means the data must be already binned appropriately. If data is only + available as a series of values (e.g. \a price against \a time), you can use the static + convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed + to \ref setData. + + The width of the OHLC bars/candlesticks can be controlled with \ref setWidth and \ref + setWidthType. A typical choice is to set the width type to \ref wtPlotCoords (the default) and + the width to (or slightly less than) one time bin interval width. + + \section qcpfinancial-appearance Changing the appearance + + Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored, + lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush). + + If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are + represented with a different pen and brush than negative changes (\a close < \a open). These can + be configured with \ref setPenPositive, \ref setPenNegative, \ref setBrushPositive, and \ref + setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection + however, the normal selected pen/brush (provided by the \ref selectionDecorator) is used, + irrespective of whether the chart is single- or two-colored. + + \section qcpfinancial-usage Usage + + Like all data representing objects in QCustomPlot, the QCPFinancial is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot + instance takes ownership of the plottable, so do not delete it manually but use + QCustomPlot::removePlottable() instead. The newly created plottable can be modified, e.g.: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-2 + Here we have used the static helper method \ref timeSeriesToOhlc, to turn a time-price data + series into a 24-hour binned open-high-low-close data series as QCPFinancial uses. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPFinancialDataContainer *QCPFinancial::data() const + + Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods, in certain situations. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPFinancial::QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mChartStyle(csCandlestick), + mWidth(0.5), + mWidthType(wtPlotCoords), + mTwoColored(true), + mBrushPositive(QBrush(QColor(50, 160, 0))), + mBrushNegative(QBrush(QColor(180, 0, 15))), + mPenPositive(QPen(QColor(40, 150, 0))), + mPenNegative(QPen(QColor(170, 5, 5))) +{ + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPFinancial::~QCPFinancial() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely. + Modifying the data in the container will then affect all financials that share the container. + Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the financial's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-2 + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a + close. The provided vectors should have equal length. Else, the number of added points will be + the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, open, high, low, close, alreadySorted); +} + +/*! + Sets which representation style shall be used to display the OHLC data. +*/ +void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) +{ + mChartStyle = style; +} + +/*! + Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. + + A typical choice is to set it to (or slightly less than) one bin interval width. +*/ +void QCPFinancial::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the financial bars is defined. See the documentation of \ref WidthType for + an explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPFinancial::setWidthType(QCPFinancial::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets whether this chart shall contrast positive from negative trends per data point by using two + separate colors to draw the respective bars/candlesticks. + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setTwoColored(bool twoColored) +{ + mTwoColored = twoColored; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushNegative, setPenPositive, setPenNegative +*/ +void QCPFinancial::setBrushPositive(const QBrush &brush) +{ + mBrushPositive = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushPositive, setPenNegative, setPenPositive +*/ +void QCPFinancial::setBrushNegative(const QBrush &brush) +{ + mBrushNegative = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setPenPositive(const QPen &pen) +{ + mPenPositive = pen; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setBrushNegative, setBrushPositive +*/ +void QCPFinancial::setPenNegative(const QPen &pen) +{ + mPenNegative = pen; +} + +/*! \overload + + Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data. + The provided vectors should have equal length. Else, the number of added points will be the size + of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + if (keys.size() != open.size() || open.size() != high.size() || high.size() != low.size() || low.size() != close.size() || close.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, open, high, low, close have different sizes:" << keys.size() << open.size() << high.size() << low.size() << close.size(); + const int n = qMin(keys.size(), qMin(open.size(), qMin(high.size(), qMin(low.size(), close.size())))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->open = open[i]; + it->high = high[i]; + it->low = low[i]; + it->close = close[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a open, \a high, \a low and \a close to the current + data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(double key, double open, double high, double low, double close) +{ + mDataContainer->add(QCPFinancialData(key, open, high, low, close)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPFinancialDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(selectionHitBox(it))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + QCPFinancialDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + // perform select test according to configured style: + double result = -1; + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + result = ohlcSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + case QCPFinancial::csCandlestick: + result = candlestickSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + } + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } + + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/*! + A convenience function that converts time series data (\a value against \a time) to OHLC binned + data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const + QCPFinancialDataContainer&). + + The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. + For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour + each, set \a timeBinSize to 3600. + + \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The + value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. + It merely defines the mathematical offset/phase of the bins that will be used to process the + data. +*/ +QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset) +{ + QCPFinancialDataContainer data; + int count = qMin(time.size(), value.size()); + if (count == 0) + return QCPFinancialDataContainer(); + + QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); + int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); + for (int i=0; i currentBinData.high) currentBinData.high = value.at(i); + if (i == count-1) // last data point is in current bin, finalize bin: + { + currentBinData.close = value.at(i); + currentBinData.key = timeBinOffset+(index)*timeBinSize; + data.add(currentBinData); + } + } else // data point not anymore in current bin, set close of old and open of new bin, and add old to map: + { + // finalize current bin: + currentBinData.close = value.at(i-1); + currentBinData.key = timeBinOffset+(index-1)*timeBinSize; + data.add(currentBinData); + // start next bin: + currentBinIndex = index; + currentBinData.open = value.at(i); + currentBinData.high = value.at(i); + currentBinData.low = value.at(i); + } + } + + return data; +} + +/* inherits documentation from base class */ +void QCPFinancial::draw(QCPPainter *painter) +{ + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPFinancialDataContainer::const_iterator begin = visibleBegin; + QCPFinancialDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + // draw data segment according to configured style: + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + drawOhlcPlot(painter, begin, end, isSelectedSegment); break; + case QCPFinancial::csCandlestick: + drawCandlestickPlot(painter, begin, end, isSelectedSegment); break; + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing + if (mChartStyle == csOhlc) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } + } else if (mChartStyle == csCandlestick) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as OHLC bars with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. +*/ +void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(it->low))); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(keyPixel-pixelWidth, openPixel), QPointF(keyPixel, openPixel)); + // draw close: + painter->drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+pixelWidth, closePixel)); + } + } else + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(it->low), keyPixel)); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(openPixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel)); + // draw close: + painter->drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+pixelWidth)); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as Candlesticks with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. +*/ +void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + // draw low: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(keyPixel-pixelWidth, closePixel), QPointF(keyPixel+pixelWidth, openPixel))); + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + // draw low: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(closePixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel+pixelWidth))); + } + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). Provide the pixel position of + \a key in \a keyPixel (because usually this was already calculated via \ref QCPAxis::coordToPixel + when this function is called). + + It returns the number of pixels the bar extends to higher keys, relative to the \a key + coordinate. So with a non-reversed horizontal axis, the return value is positive. With a reversed + horizontal axis, the return value is negative. This is important so the open/close flags on the + \ref csOhlc bar are drawn to the correct side. +*/ +double QCPFinancial::getPixelWidth(double key, double keyPixel) const +{ + double result = 0; + switch (mWidthType) + { + case wtAbsolute: + { + if (mKeyAxis) + result = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + result = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + result = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + result = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } + return result; +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low))); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel)); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a + end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + called by the drawing methods to determine which data (key) range is visible at the current key + axis range setting, so only that needs to be processed. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + begin may still be just outside the visible range. + + \a end returns the iterator just above the highest data point that needs to be taken into + account. Same as before, \a end may also lie just outside of the visible range + + if the plottable contains no data, both \a begin and \a end point to \c constEnd. +*/ +void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of ohlc/candlestick to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of ohlc/candlestick to include partially visible data points +} + +/*! \internal + + Returns the hit box in pixel coordinates that will be used for data selection with the selection + rect (\ref selectTestRect), of the data point given by \a it. +*/ +QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator it) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } + + double keyPixel = keyAxis->coordToPixel(it->key); + double highPixel = valueAxis->coordToPixel(it->high); + double lowPixel = valueAxis->coordToPixel(it->low); + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it->key-mWidth*0.5); + if (keyAxis->orientation() == Qt::Horizontal) + return QRectF(keyPixel-keyWidthPixels, highPixel, keyWidthPixels*2, lowPixel-highPixel).normalized(); + else + return QRectF(highPixel, keyPixel-keyWidthPixels, lowPixel-highPixel, keyWidthPixels*2).normalized(); +} +/* end of 'src/plottables/plottable-financial.cpp' */ + + +/* including file 'src/plottables/plottable-errorbar.cpp', size 37355 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBarsData + \brief Holds the data of one single error bar for QCPErrorBars. + + The stored data is: + \li \a errorMinus: how much the error bar extends towards negative coordinates from the data + point position + \li \a errorPlus: how much the error bar extends towards positive coordinates from the data point + position + + The container for storing the error bar information is \ref QCPErrorBarsDataContainer. It is a + typedef for QVector<\ref QCPErrorBarsData>. + + \see QCPErrorBarsDataContainer +*/ + +/*! + Constructs an error bar with errors set to zero. +*/ +QCPErrorBarsData::QCPErrorBarsData() : + errorMinus(0), + errorPlus(0) +{ +} + +/*! + Constructs an error bar with equal \a error in both negative and positive direction. +*/ +QCPErrorBarsData::QCPErrorBarsData(double error) : + errorMinus(error), + errorPlus(error) +{ +} + +/*! + Constructs an error bar with negative and positive errors set to \a errorMinus and \a errorPlus, + respectively. +*/ +QCPErrorBarsData::QCPErrorBarsData(double errorMinus, double errorPlus) : + errorMinus(errorMinus), + errorPlus(errorPlus) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBars + \brief A plottable that adds a set of error bars to other plottables. + + \image html QCPErrorBars.png + + The \ref QCPErrorBars plottable can be attached to other one-dimensional plottables (e.g. \ref + QCPGraph, \ref QCPCurve, \ref QCPBars, etc.) and equips them with error bars. + + Use \ref setDataPlottable to define for which plottable the \ref QCPErrorBars shall display the + error bars. The orientation of the error bars can be controlled with \ref setErrorType. + + By using \ref setData, you can supply the actual error data, either as symmetric error or + plus/minus asymmetric errors. \ref QCPErrorBars only stores the error data. The absolute + key/value position of each error bar will be adopted from the configured data plottable. The + error data of the \ref QCPErrorBars are associated one-to-one via their index to the data points + of the data plottable. You can directly access and manipulate the error bar data via \ref data. + + Set either of the plus/minus errors to NaN (qQNaN() or + std::numeric_limits::quiet_NaN()) to not show the respective error bar on the data point at + that index. + + \section qcperrorbars-appearance Changing the appearance + + The appearance of the error bars is defined by the pen (\ref setPen), and the width of the + whiskers (\ref setWhiskerWidth). Further, the error bar backbones may leave a gap around the data + point center to prevent that error bars are drawn too close to or even through scatter points. + This gap size can be controlled via \ref setSymbolGap. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPErrorBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPErrorBarsDataContainer. You + may use it to directly manipulate the error values, which may be more convenient and faster than + using the regular \ref setData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs an error bars plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + It is also important that the \a keyAxis and \a valueAxis are the same for the error bars + plottable and the data plottable that the error bars shall be drawn on (\ref setDataPlottable). + + The created \ref QCPErrorBars is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the \ref QCPErrorBars, so do not + delete it manually but use \ref QCustomPlot::removePlottable() instead. +*/ +QCPErrorBars::QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QVector), + mErrorType(etValueError), + mWhiskerWidth(9), + mSymbolGap(10) +{ + setPen(QPen(Qt::black, 0)); + setBrush(Qt::NoBrush); +} + +QCPErrorBars::~QCPErrorBars() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple \ref QCPErrorBars instances may share the same data + container safely. Modifying the data in the container will then affect all \ref QCPErrorBars + instances that share the container. Sharing can be achieved by simply exchanging the data + containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, assign the + data containers directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-2 + (This uses different notation compared with other plottables, because the \ref QCPErrorBars + uses a \c QVector as its data container, instead of a \ref QCPDataContainer.) + + \see addData +*/ +void QCPErrorBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Sets symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &error) +{ + mDataContainer->clear(); + addData(error); +} + +/*! \overload + + Sets asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &errorMinus, const QVector &errorPlus) +{ + mDataContainer->clear(); + addData(errorMinus, errorPlus); +} + +/*! + Sets the data plottable to which the error bars will be applied. The error values specified e.g. + via \ref setData will be associated one-to-one by the data point index to the data points of \a + plottable. This means that the error bars will adopt the key/value coordinates of the data point + with the same index. + + The passed \a plottable must be a one-dimensional plottable, i.e. it must implement the \ref + QCPPlottableInterface1D. Further, it must not be a \ref QCPErrorBars instance itself. If either + of these restrictions is violated, a corresponding qDebug output is generated, and the data + plottable of this \ref QCPErrorBars instance is set to zero. + + For proper display, care must also be taken that the key and value axes of the \a plottable match + those configured for this \ref QCPErrorBars instance. +*/ +void QCPErrorBars::setDataPlottable(QCPAbstractPlottable *plottable) +{ + if (plottable && qobject_cast(plottable)) + { + mDataPlottable = 0; + qDebug() << Q_FUNC_INFO << "can't set another QCPErrorBars instance as data plottable"; + return; + } + if (plottable && !plottable->interface1D()) + { + mDataPlottable = 0; + qDebug() << Q_FUNC_INFO << "passed plottable doesn't implement 1d interface, can't associate with QCPErrorBars"; + return; + } + + mDataPlottable = plottable; +} + +/*! + Sets in which orientation the error bars shall appear on the data points. If your data needs both + error dimensions, create two \ref QCPErrorBars with different \a type. +*/ +void QCPErrorBars::setErrorType(ErrorType type) +{ + mErrorType = type; +} + +/*! + Sets the width of the whiskers (the short bars at the end of the actual error bar backbones) to + \a pixels. +*/ +void QCPErrorBars::setWhiskerWidth(double pixels) +{ + mWhiskerWidth = pixels; +} + +/*! + Sets the gap diameter around the data points that will be left out when drawing the error bar + backbones. This gap prevents that error bars are drawn too close to or even through scatter + points. +*/ +void QCPErrorBars::setSymbolGap(double pixels) +{ + mSymbolGap = pixels; +} + +/*! \overload + + Adds symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &error) +{ + addData(error, error); +} + +/*! \overload + + Adds asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &errorMinus, const QVector &errorPlus) +{ + if (errorMinus.size() != errorPlus.size()) + qDebug() << Q_FUNC_INFO << "minus and plus error vectors have different sizes:" << errorMinus.size() << errorPlus.size(); + const int n = qMin(errorMinus.size(), errorPlus.size()); + mDataContainer->reserve(n); + for (int i=0; iappend(QCPErrorBarsData(errorMinus.at(i), errorPlus.at(i))); +} + +/*! \overload + + Adds a single symmetrical error bar as specified in \a error. The errors will be associated + one-to-one by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double error) +{ + mDataContainer->append(QCPErrorBarsData(error)); +} + +/*! \overload + + Adds a single asymmetrical error bar as specified in \a errorMinus and \a errorPlus. The errors + will be associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double errorMinus, double errorPlus) +{ + mDataContainer->append(QCPErrorBarsData(errorMinus, errorPlus)); +} + +/* inherits documentation from base class */ +int QCPErrorBars::dataCount() const +{ + return mDataContainer->size(); +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataSortKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataSortKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainValue(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainValue(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::dataValueRange(int index) const +{ + if (mDataPlottable) + { + const double value = mDataPlottable->interface1D()->dataMainValue(index); + if (index >= 0 && index < mDataContainer->size() && mErrorType == etValueError) + return QCPRange(value-mDataContainer->at(index).errorMinus, value+mDataContainer->at(index).errorPlus); + else + return QCPRange(value, value); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return QCPRange(); + } +} + +/* inherits documentation from base class */ +QPointF QCPErrorBars::dataPixelPosition(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataPixelPosition(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return QPointF(); +} + +/* inherits documentation from base class */ +bool QCPErrorBars::sortKeyIsMainKey() const +{ + if (mDataPlottable) + { + return mDataPlottable->interface1D()->sortKeyIsMainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return true; + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPErrorBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if (!mDataPlottable) + return result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd, QCPDataRange(0, dataCount())); + + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + backbones.clear(); + whiskers.clear(); + getErrorBarLines(it, backbones, whiskers); + for (int i=0; iconstBegin(), it-mDataContainer->constBegin()+1), false); + break; + } + } + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findBegin(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int beginIndex = mDataPlottable->interface1D()->findBegin(sortKey, expandedRange); + if (beginIndex >= mDataContainer->size()) + beginIndex = mDataContainer->size()-1; + return beginIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findEnd(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int endIndex = mDataPlottable->interface1D()->findEnd(sortKey, expandedRange); + if (endIndex > mDataContainer->size()) + endIndex = mDataContainer->size(); + return endIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mDataPlottable) return -1; + + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPErrorBarsDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +void QCPErrorBars::draw(QCPPainter *painter) +{ + if (!mDataPlottable) return; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + + // if the sort key isn't the main key, we must check the visibility for each data point/error bar individually + // (getVisibleDataBounds applies range restriction, but otherwise can only return full data range): + bool checkPointVisibility = !mDataPlottable->interface1D()->sortKeyIsMainKey(); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->errorMinus, it->errorPlus)) + qDebug() << Q_FUNC_INFO << "Data point at index" << it-mDataContainer->constBegin() << "invalid." << "Plottable name:" << name(); + } +#endif + + applyDefaultAntialiasingHint(painter); + painter->setBrush(Qt::NoBrush); + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + QVector backbones, whiskers; + for (int i=0; i= unselectedSegments.size(); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + if (painter->pen().capStyle() == Qt::SquareCap) + { + QPen capFixPen(painter->pen()); + capFixPen.setCapStyle(Qt::FlatCap); + painter->setPen(capFixPen); + } + backbones.clear(); + whiskers.clear(); + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (!checkPointVisibility || errorBarVisible(it-mDataContainer->constBegin())) + getErrorBarLines(it, backbones, whiskers); + } + painter->drawLines(backbones); + painter->drawLines(whiskers); + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPErrorBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + if (mErrorType == etValueError && mValueAxis && mValueAxis->orientation() == Qt::Vertical) + { + painter->drawLine(QLineF(rect.center().x(), rect.top()+2, rect.center().x(), rect.bottom()-1)); + painter->drawLine(QLineF(rect.center().x()-4, rect.top()+2, rect.center().x()+4, rect.top()+2)); + painter->drawLine(QLineF(rect.center().x()-4, rect.bottom()-1, rect.center().x()+4, rect.bottom()-1)); + } else + { + painter->drawLine(QLineF(rect.left()+2, rect.center().y(), rect.right()-2, rect.center().y())); + painter->drawLine(QLineF(rect.left()+2, rect.center().y()-4, rect.left()+2, rect.center().y()+4)); + painter->drawLine(QLineF(rect.right()-2, rect.center().y()-4, rect.right()-2, rect.center().y()+4)); + } +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + if (!mDataPlottable) + { + foundRange = false; + return QCPRange(); + } + + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (mErrorType == etValueError) + { + // error bar doesn't extend in key dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } else // mErrorType == etKeyError + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (qIsNaN(dataKey)) continue; + // plus error: + double current = dataKey + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataKey - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (!mDataPlottable) + { + foundRange = false; + return QCPRange(); + } + + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPErrorBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (mDataPlottable->interface1D()->sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = mDataContainer->constBegin()+findBegin(inKeyRange.lower); + itEnd = mDataContainer->constBegin()+findEnd(inKeyRange.upper); + } + for (QCPErrorBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange) + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (dataKey < inKeyRange.lower || dataKey > inKeyRange.upper) + continue; + } + if (mErrorType == etValueError) + { + const double dataValue = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); + if (qIsNaN(dataValue)) continue; + // plus error: + double current = dataValue + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataValue - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } else // mErrorType == etKeyError + { + // error bar doesn't extend in value dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! \internal + + Calculates the lines that make up the error bar belonging to the data point \a it. + + The resulting lines are added to \a backbones and \a whiskers. The vectors are not cleared, so + calling this method with different \a it but the same \a backbones and \a whiskers allows to + accumulate lines for multiple data points. + + This method assumes that \a it is a valid iterator within the bounds of this \ref QCPErrorBars + instance and within the bounds of the associated data plottable. +*/ +void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const +{ + if (!mDataPlottable) return; + + int index = it-mDataContainer->constBegin(); + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) + return; + QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data(); + QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data(); + const double centerErrorAxisPixel = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerOrthoAxisPixel = orthoAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerErrorAxisCoord = errorAxis->pixelToCoord(centerErrorAxisPixel); // depending on plottable, this might be different from just mDataPlottable->interface1D()->dataMainKey/Value + const double symbolGap = mSymbolGap*0.5*errorAxis->pixelOrientation(); + // plus error: + double errorStart, errorEnd; + if (!qIsNaN(it->errorPlus)) + { + errorStart = centerErrorAxisPixel+symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord+it->errorPlus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } + // minus error: + if (!qIsNaN(it->errorMinus)) + { + errorStart = centerErrorAxisPixel-symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord-it->errorMinus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } +} + +/*! \internal + + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + Since error bars with type \ref etKeyError may extend to arbitrarily positive and negative key + coordinates relative to their data point key, this method checks all outer error bars whether + they truly don't reach into the visible portion of the axis rect, by calling \ref + errorBarVisible. On the other hand error bars with type \ref etValueError that are associated + with data plottables whose sort key is equal to the main key (see \ref qcpdatacontainer-datatype + "QCPDataContainer DataType") can be handled very efficiently by finding the visible range of + error bars through binary search (\ref QCPPlottableInterface1D::findBegin and \ref + QCPPlottableInterface1D::findEnd). + + If the plottable's sort key is not equal to the main key, this method returns the full data + range, only restricted by \a rangeRestriction. Drawing optimization then has to be done on a + point-by-point basis in the \ref draw method. +*/ +void QCPErrorBars::getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable || rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable->interface1D()->sortKeyIsMainKey()) + { + // if the sort key isn't the main key, it's not possible to find a contiguous range of visible + // data points, so this method then only applies the range restriction and otherwise returns + // the full data range. Visibility checks must be done on a per-datapoin-basis during drawing + QCPDataRange dataRange(0, mDataContainer->size()); + dataRange = dataRange.bounded(rangeRestriction); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); + return; + } + + // get visible data range via interface from data plottable, and then restrict to available error data points: + const int n = qMin(mDataContainer->size(), mDataPlottable->interface1D()->dataCount()); + int beginIndex = mDataPlottable->interface1D()->findBegin(keyAxis->range().lower); + int endIndex = mDataPlottable->interface1D()->findEnd(keyAxis->range().upper); + int i = beginIndex; + while (i > 0 && i < n && i > rangeRestriction.begin()) + { + if (errorBarVisible(i)) + beginIndex = i; + --i; + } + i = endIndex; + while (i >= 0 && i < n && i < rangeRestriction.end()) + { + if (errorBarVisible(i)) + endIndex = i+1; + ++i; + } + QCPDataRange dataRange(beginIndex, endIndex); + dataRange = dataRange.bounded(rangeRestriction.bounded(QCPDataRange(0, mDataContainer->size()))); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); +} + +/*! \internal + + Calculates the minimum distance in pixels the error bars' representation has from the given \a + pixelPoint. This is used to determine whether the error bar was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. +*/ +double QCPErrorBars::pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (!mDataPlottable || mDataContainer->isEmpty()) + return -1.0; + if (!mKeyAxis || !mValueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + return -1.0; + } + + QCPErrorBarsDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); + + // calculate minimum distances to error backbones (whiskers are ignored for speed) and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + getErrorBarLines(it, backbones, whiskers); + for (int i=0; i &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! \internal + + Returns whether the error bar at the specified \a index is visible within the current key axis + range. + + This method assumes for performance reasons without checking that the key axis, the value axis, + and the data plottable (\ref setDataPlottable) are not zero and that \a index is within valid + bounds of this \ref QCPErrorBars instance and the bounds of the data plottable. +*/ +bool QCPErrorBars::errorBarVisible(int index) const +{ + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + const double centerKeyPixel = mKeyAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + if (qIsNaN(centerKeyPixel)) + return false; + + double keyMin, keyMax; + if (mErrorType == etKeyError) + { + const double centerKey = mKeyAxis->pixelToCoord(centerKeyPixel); + const double errorPlus = mDataContainer->at(index).errorPlus; + const double errorMinus = mDataContainer->at(index).errorMinus; + keyMax = centerKey+(qIsNaN(errorPlus) ? 0 : errorPlus); + keyMin = centerKey-(qIsNaN(errorMinus) ? 0 : errorMinus); + } else // mErrorType == etValueError + { + keyMax = mKeyAxis->pixelToCoord(centerKeyPixel+mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + keyMin = mKeyAxis->pixelToCoord(centerKeyPixel-mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + } + return ((keyMax > mKeyAxis->range().lower) && (keyMin < mKeyAxis->range().upper)); +} + +/*! \internal + + Returns whether \a line intersects (or is contained in) \a pixelRect. + + \a line is assumed to be either perfectly horizontal or perfectly vertical, as is the case for + error bar lines. +*/ +bool QCPErrorBars::rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const +{ + if (pixelRect.left() > line.x1() && pixelRect.left() > line.x2()) + return false; + else if (pixelRect.right() < line.x1() && pixelRect.right() < line.x2()) + return false; + else if (pixelRect.top() > line.y1() && pixelRect.top() > line.y2()) + return false; + else if (pixelRect.bottom() < line.y1() && pixelRect.bottom() < line.y2()) + return false; + else + return true; +} +/* end of 'src/plottables/plottable-errorbar.cpp' */ + + +/* including file 'src/items/item-straightline.cpp', size 7592 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemStraightLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemStraightLine + \brief A straight line that spans infinitely in both directions + + \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a point1 and \a point2, which define the straight line. +*/ + +/*! + Creates a straight line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + point1(createPosition(QLatin1String("point1"))), + point2(createPosition(QLatin1String("point2"))) +{ + point1->setCoords(0, 0); + point2->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemStraightLine::~QCPItemStraightLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemStraightLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemStraightLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return QCPVector2D(pos).distanceToStraightLine(point1->pixelPosition(), point2->pixelPosition()-point1->pixelPosition()); +} + +/* inherits documentation from base class */ +void QCPItemStraightLine::draw(QCPPainter *painter) +{ + QCPVector2D start(point1->pixelPosition()); + QCPVector2D end(point2->pixelPosition()); + // get visible segment of straight line inside clipRect: + double clipPad = mainPen().widthF(); + QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + } +} + +/*! \internal + + Returns the section of the straight line defined by \a base and direction vector \a + vec, that is visible in the specified \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const +{ + double bx, by; + double gamma; + QLineF result; + if (vec.x() == 0 && vec.y() == 0) + return result; + if (qFuzzyIsNull(vec.x())) // line is vertical + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical + } else if (qFuzzyIsNull(vec.y())) // line is horizontal + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal + } else // line is skewed + { + QList pointVectors; + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + // check right of rect: + bx = rect.right(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemStraightLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-straightline.cpp' */ + + +/* including file 'src/items/item-line.cpp', size 8498 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemLine + \brief A line from one point to another + + \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a start and \a end, which define the end points of the line. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. +*/ + +/*! + Creates a line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemLine::~QCPItemLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemLine::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemLine::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return qSqrt(QCPVector2D(pos).distanceSquaredToLine(start->pixelPosition(), end->pixelPosition())); +} + +/* inherits documentation from base class */ +void QCPItemLine::draw(QCPPainter *painter) +{ + QCPVector2D startVec(start->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if (qFuzzyIsNull((startVec-endVec).lengthSquared())) + return; + // get visible segment of straight line inside clipRect: + double clipPad = qMax(mHead.boundingDistance(), mTail.boundingDistance()); + clipPad = qMax(clipPad, (double)mainPen().widthF()); + QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, startVec-endVec); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, endVec-startVec); + } +} + +/*! \internal + + Returns the section of the line defined by \a start and \a end, that is visible in the specified + \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const +{ + bool containsStart = rect.contains(start.x(), start.y()); + bool containsEnd = rect.contains(end.x(), end.y()); + if (containsStart && containsEnd) + return QLineF(start.toPointF(), end.toPointF()); + + QCPVector2D base = start; + QCPVector2D vec = end-start; + double bx, by; + double gamma, mu; + QLineF result; + QList pointVectors; + + if (!qFuzzyIsNull(vec.y())) // line is not horizontal + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + } + if (!qFuzzyIsNull(vec.x())) // line is not vertical + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + // check right of rect: + bx = rect.right(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + } + + if (containsStart) + pointVectors.append(start); + if (containsEnd) + pointVectors.append(end); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-line.cpp' */ + + +/* including file 'src/items/item-curve.cpp', size 7159 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemCurve + \brief A curved line from one point to another + + \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." + + It has four positions, \a start and \a end, which define the end points of the line, and two + control points which define the direction the line exits from the start and the direction from + which it approaches the end: \a startDir and \a endDir. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an + arrow. + + Often it is desirable for the control points to stay at fixed relative positions to the start/end + point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, + and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. +*/ + +/*! + Creates a curve item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + startDir(createPosition(QLatin1String("startDir"))), + endDir(createPosition(QLatin1String("endDir"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + startDir->setCoords(0.5, 0); + endDir->setCoords(0, 0.5); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemCurve::~QCPItemCurve() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemCurve::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemCurve::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemCurve::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemCurve::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF startVec(start->pixelPosition()); + QPointF startDirVec(startDir->pixelPosition()); + QPointF endDirVec(endDir->pixelPosition()); + QPointF endVec(end->pixelPosition()); + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + QPolygonF polygon = cubicPath.toSubpathPolygons().first(); + QCPVector2D p(pos); + double minDistSqr = std::numeric_limits::max(); + for (int i=1; ipixelPosition()); + QCPVector2D startDirVec(startDir->pixelPosition()); + QCPVector2D endDirVec(endDir->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if ((endVec-startVec).length() > 1e10) // too large curves cause crash + return; + + QPainterPath cubicPath(startVec.toPointF()); + cubicPath.cubicTo(startDirVec.toPointF(), endDirVec.toPointF(), endVec.toPointF()); + + // paint visible segment, if existent: + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + QRect cubicRect = cubicPath.controlPointRect().toRect(); + if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position + cubicRect.adjust(0, 0, 1, 1); + if (clip.intersects(cubicRect)) + { + painter->setPen(mainPen()); + painter->drawPath(cubicPath); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, -cubicPath.angleAtPercent(1)/180.0*M_PI); + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemCurve::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-curve.cpp' */ + + +/* including file 'src/items/item-rect.cpp', size 6479 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemRect + \brief A rectangle + + \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemRect::~QCPItemRect() +{ +} + +/*! + Sets the pen that will be used to draw the line of the rectangle + + \see setSelectedPen, setBrush +*/ +void QCPItemRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the rectangle when selected + + \see setPen, setSelected +*/ +void QCPItemRect::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemRect::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()).normalized(); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); +} + +/* inherits documentation from base class */ +void QCPItemRect::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF rect = QRectF(p1, p2).normalized(); + double clipPad = mainPen().widthF(); + QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(rect); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemRect::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemRect::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemRect::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-rect.cpp' */ + + +/* including file 'src/items/item-text.cpp', size 13338 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemText +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemText + \brief A text label + + \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." + + Its position is defined by the member \a position and the setting of \ref setPositionAlignment. + The latter controls which part of the text rect shall be aligned with \a position. + + The text alignment itself (i.e. left, center, right) can be controlled with \ref + setTextAlignment. + + The text may be rotated around the \a position point with \ref setRotation. +*/ + +/*! + Creates a text item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemText::QCPItemText(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + topLeft(createAnchor(QLatin1String("topLeft"), aiTopLeft)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRight(createAnchor(QLatin1String("bottomRight"), aiBottomRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mText(QLatin1String("text")), + mPositionAlignment(Qt::AlignCenter), + mTextAlignment(Qt::AlignTop|Qt::AlignHCenter), + mRotation(0) +{ + position->setCoords(0, 0); + + setPen(Qt::NoPen); + setSelectedPen(Qt::NoPen); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setColor(Qt::black); + setSelectedColor(Qt::blue); +} + +QCPItemText::~QCPItemText() +{ +} + +/*! + Sets the color of the text. +*/ +void QCPItemText::setColor(const QColor &color) +{ + mColor = color; +} + +/*! + Sets the color of the text that will be used when the item is selected. +*/ +void QCPItemText::setSelectedColor(const QColor &color) +{ + mSelectedColor = color; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text. To disable the + border, set \a pen to Qt::NoPen. + + \see setSelectedPen, setBrush, setPadding +*/ +void QCPItemText::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text, when the item is + selected. To disable the border, set \a pen to Qt::NoPen. + + \see setPen +*/ +void QCPItemText::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used do fill the background of the text. To disable the + background, set \a brush to Qt::NoBrush. + + \see setSelectedBrush, setPen, setPadding +*/ +void QCPItemText::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the + background, set \a brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemText::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the font of the text. + + \see setSelectedFont, setColor +*/ +void QCPItemText::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the font of the text that will be used when the item is selected. + + \see setFont +*/ +void QCPItemText::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the text that will be displayed. Multi-line texts are supported by inserting a line break + character, e.g. '\n'. + + \see setFont, setColor, setTextAlignment +*/ +void QCPItemText::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets which point of the text rect shall be aligned with \a position. + + Examples: + \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such + that the top of the text rect will be horizontally centered on \a position. + \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the + bottom left corner of the text rect. + + If you want to control the alignment of (multi-lined) text within the text rect, use \ref + setTextAlignment. +*/ +void QCPItemText::setPositionAlignment(Qt::Alignment alignment) +{ + mPositionAlignment = alignment; +} + +/*! + Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). +*/ +void QCPItemText::setTextAlignment(Qt::Alignment alignment) +{ + mTextAlignment = alignment; +} + +/*! + Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated + around \a position. +*/ +void QCPItemText::setRotation(double degrees) +{ + mRotation = degrees; +} + +/*! + Sets the distance between the border of the text rectangle and the text. The appearance (and + visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. +*/ +void QCPItemText::setPadding(const QMargins &padding) +{ + mPadding = padding; +} + +/* inherits documentation from base class */ +double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + // The rect may be rotated, so we transform the actual clicked pos to the rotated + // coordinate system, so we can use the normal rectDistance function for non-rotated rects: + QPointF positionPixels(position->pixelPosition()); + QTransform inputTransform; + inputTransform.translate(positionPixels.x(), positionPixels.y()); + inputTransform.rotate(-mRotation); + inputTransform.translate(-positionPixels.x(), -positionPixels.y()); + QPointF rotatedPos = inputTransform.map(pos); + QFontMetrics fontMetrics(mFont); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); + textBoxRect.moveTopLeft(textPos.toPoint()); + + return rectDistance(textBoxRect, rotatedPos, true); +} + +/* inherits documentation from base class */ +void QCPItemText::draw(QCPPainter *painter) +{ + QPointF pos(position->pixelPosition()); + QTransform transform = painter->transform(); + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + painter->setFont(mainFont()); + QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); + textBoxRect.moveTopLeft(textPos.toPoint()); + double clipPad = mainPen().widthF(); + QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect()))) + { + painter->setTransform(transform); + if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || + (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(textBoxRect); + } + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(mainColor())); + painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemText::anchorPixelPosition(int anchorId) const +{ + // get actual rect points (pretty much copied from draw function): + QPointF pos(position->pixelPosition()); + QTransform transform; + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + QFontMetrics fontMetrics(mainFont()); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textBoxRect.moveTopLeft(textPos.toPoint()); + QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); + + switch (anchorId) + { + case aiTopLeft: return rectPoly.at(0); + case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; + case aiTopRight: return rectPoly.at(1); + case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; + case aiBottomRight: return rectPoly.at(2); + case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; + case aiBottomLeft: return rectPoly.at(3); + case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the point that must be given to the QPainter::drawText function (which expects the top + left point of the text rect), according to the position \a pos, the text bounding box \a rect and + the requested \a positionAlignment. + + For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point + will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally + drawn at that point, the lower left corner of the resulting text rect is at \a pos. +*/ +QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const +{ + if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) + return pos; + + QPointF result = pos; // start at top left + if (positionAlignment.testFlag(Qt::AlignHCenter)) + result.rx() -= rect.width()/2.0; + else if (positionAlignment.testFlag(Qt::AlignRight)) + result.rx() -= rect.width(); + if (positionAlignment.testFlag(Qt::AlignVCenter)) + result.ry() -= rect.height()/2.0; + else if (positionAlignment.testFlag(Qt::AlignBottom)) + result.ry() -= rect.height(); + return result; +} + +/*! \internal + + Returns the font that should be used for drawing text. Returns mFont when the item is not selected + and mSelectedFont when it is. +*/ +QFont QCPItemText::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the color that should be used for drawing text. Returns mColor when the item is not + selected and mSelectedColor when it is. +*/ +QColor QCPItemText::mainColor() const +{ + return mSelected ? mSelectedColor : mColor; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemText::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemText::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-text.cpp' */ + + +/* including file 'src/items/item-ellipse.cpp', size 7863 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemEllipse +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemEllipse + \brief An ellipse + + \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. +*/ + +/*! + Creates an ellipse item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + topLeftRim(createAnchor(QLatin1String("topLeftRim"), aiTopLeftRim)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRightRim(createAnchor(QLatin1String("topRightRim"), aiTopRightRim)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRightRim(createAnchor(QLatin1String("bottomRightRim"), aiBottomRightRim)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeftRim(createAnchor(QLatin1String("bottomLeftRim"), aiBottomLeftRim)), + left(createAnchor(QLatin1String("left"), aiLeft)), + center(createAnchor(QLatin1String("center"), aiCenter)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemEllipse::~QCPItemEllipse() +{ +} + +/*! + Sets the pen that will be used to draw the line of the ellipse + + \see setSelectedPen, setBrush +*/ +void QCPItemEllipse::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the ellipse when selected + + \see setPen, setSelected +*/ +void QCPItemEllipse::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemEllipse::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemEllipse::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + QPointF center((p1+p2)/2.0); + double a = qAbs(p1.x()-p2.x())/2.0; + double b = qAbs(p1.y()-p2.y())/2.0; + double x = pos.x()-center.x(); + double y = pos.y()-center.y(); + + // distance to border: + double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); + double result = qAbs(c-1)*qSqrt(x*x+y*y); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (x*x/(a*a) + y*y/(b*b) <= 1) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/* inherits documentation from base class */ +void QCPItemEllipse::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF ellipseRect = QRectF(p1, p2).normalized(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); +#ifdef __EXCEPTIONS + try // drawEllipse sometimes throws exceptions if ellipse is too big + { +#endif + painter->drawEllipse(ellipseRect); +#ifdef __EXCEPTIONS + } catch (...) + { + qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; + setVisible(false); + } +#endif + } +} + +/* inherits documentation from base class */ +QPointF QCPItemEllipse::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemEllipse::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemEllipse::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-ellipse.cpp' */ + + +/* including file 'src/items/item-pixmap.cpp', size 10615 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPixmap + \brief An arbitrary pixmap + + \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will + be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to + fit the rectangle or be drawn aligned to the topLeft position. + + If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown + on the right side of the example image), the pixmap will be flipped in the respective + orientations. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mScaled(false), + mScaledPixmapInvalidated(true), + mAspectRatioMode(Qt::KeepAspectRatio), + mTransformationMode(Qt::SmoothTransformation) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(Qt::NoPen); + setSelectedPen(QPen(Qt::blue)); +} + +QCPItemPixmap::~QCPItemPixmap() +{ +} + +/*! + Sets the pixmap that will be displayed. +*/ +void QCPItemPixmap::setPixmap(const QPixmap &pixmap) +{ + mPixmap = pixmap; + mScaledPixmapInvalidated = true; + if (mPixmap.isNull()) + qDebug() << Q_FUNC_INFO << "pixmap is null"; +} + +/*! + Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a + bottomRight positions. +*/ +void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode) +{ + mScaled = scaled; + mAspectRatioMode = aspectRatioMode; + mTransformationMode = transformationMode; + mScaledPixmapInvalidated = true; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap. + + \see setSelectedPen, setBrush +*/ +void QCPItemPixmap::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap when selected + + \see setPen, setSelected +*/ +void QCPItemPixmap::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return rectDistance(getFinalRect(), pos, true); +} + +/* inherits documentation from base class */ +void QCPItemPixmap::draw(QCPPainter *painter) +{ + bool flipHorz = false; + bool flipVert = false; + QRect rect = getFinalRect(&flipHorz, &flipVert); + double clipPad = mainPen().style() == Qt::NoPen ? 0 : mainPen().widthF(); + QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) + { + updateScaledPixmap(rect, flipHorz, flipVert); + painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); + QPen pen = mainPen(); + if (pen.style() != Qt::NoPen) + { + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawRect(rect); + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const +{ + bool flipHorz; + bool flipVert; + QRect rect = getFinalRect(&flipHorz, &flipVert); + // we actually want denormal rects (negative width/height) here, so restore + // the flipped state: + if (flipHorz) + rect.adjust(rect.width(), 0, -rect.width(), 0); + if (flipVert) + rect.adjust(0, rect.height(), 0, -rect.height()); + + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The + parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped + horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a + bottomRight.) + + This function only creates the scaled pixmap when the buffered pixmap has a different size than + the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does + not cause expensive rescaling every time. + + If scaling is disabled, sets mScaledPixmap to a null QPixmap. +*/ +void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) +{ + if (mPixmap.isNull()) + return; + + if (mScaled) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + double devicePixelRatio = mPixmap.devicePixelRatio(); +#else + double devicePixelRatio = 1.0; +#endif + if (finalRect.isNull()) + finalRect = getFinalRect(&flipHorz, &flipVert); + if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()/devicePixelRatio) + { + mScaledPixmap = mPixmap.scaled(finalRect.size()*devicePixelRatio, mAspectRatioMode, mTransformationMode); + if (flipHorz || flipVert) + mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mScaledPixmap.setDevicePixelRatio(devicePixelRatio); +#endif + } + } else if (!mScaledPixmap.isNull()) + mScaledPixmap = QPixmap(); + mScaledPixmapInvalidated = false; +} + +/*! \internal + + Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions + and scaling settings. + + The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn + flipped horizontally or vertically in the returned rect. (The returned rect itself is always + normalized, i.e. the top left corner of the rect is actually further to the top/left than the + bottom right corner). This is the case when the item position \a topLeft is further to the + bottom/right than \a bottomRight. + + If scaling is disabled, returns a rect with size of the original pixmap and the top left corner + aligned with the item position \a topLeft. The position \a bottomRight is ignored. +*/ +QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const +{ + QRect result; + bool flipHorz = false; + bool flipVert = false; + QPoint p1 = topLeft->pixelPosition().toPoint(); + QPoint p2 = bottomRight->pixelPosition().toPoint(); + if (p1 == p2) + return QRect(p1, QSize(0, 0)); + if (mScaled) + { + QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); + QPoint topLeft = p1; + if (newSize.width() < 0) + { + flipHorz = true; + newSize.rwidth() *= -1; + topLeft.setX(p2.x()); + } + if (newSize.height() < 0) + { + flipVert = true; + newSize.rheight() *= -1; + topLeft.setY(p2.y()); + } + QSize scaledSize = mPixmap.size(); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + scaledSize /= mPixmap.devicePixelRatio(); + scaledSize.scale(newSize*mPixmap.devicePixelRatio(), mAspectRatioMode); +#else + scaledSize.scale(newSize, mAspectRatioMode); +#endif + result = QRect(topLeft, scaledSize); + } else + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + result = QRect(p1, mPixmap.size()/mPixmap.devicePixelRatio()); +#else + result = QRect(p1, mPixmap.size()); +#endif + } + if (flippedHorz) + *flippedHorz = flipHorz; + if (flippedVert) + *flippedVert = flipVert; + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemPixmap::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-pixmap.cpp' */ + + +/* including file 'src/items/item-tracer.cpp', size 14624 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemTracer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemTracer + \brief Item that sticks to QCPGraph data points + + \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." + + The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt + the coordinate axes of the graph and update its \a position to be on the graph's data. This means + the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a + QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a + position will have no effect because they will be overriden in the next redraw (this is when the + coordinate update happens). + + If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will + stay at the corresponding end of the graph. + + With \ref setInterpolating you may specify whether the tracer may only stay exactly on data + points or whether it interpolates data points linearly, if given a key that lies between two data + points of the graph. + + The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer + have no own visual appearance (set the style to \ref tsNone), and just connect other item + positions to the tracer \a position (used as an anchor) via \ref + QCPItemPosition::setParentAnchor. + + \note The tracer position is only automatically updated upon redraws. So when the data of the + graph changes and immediately afterwards (without a redraw) the position coordinates of the + tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref + updatePosition must be called manually, prior to reading the tracer coordinates. +*/ + +/*! + Creates a tracer item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mSize(6), + mStyle(tsCrosshair), + mGraph(0), + mGraphKey(0), + mInterpolating(false), + mType(-1) +{ + position->setCoords(0, 0); + + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush, const QList &alarmStatusList) + : QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mPen(pen), + mBrush(brush), + mSize(5), + mStyle(tsCircle), + mGraph(0), + mGraphKey(0), + mInterpolating(true), + mType(type), + mTimeStamp(timeStamp), + m_alarmStatusList(alarmStatusList) +{ + position->setCoords(0, 0); + setSelectedBrush(Qt::NoBrush); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemTracer::~QCPItemTracer() +{ +} + +/*! + Sets the pen that will be used to draw the line of the tracer + + \see setSelectedPen, setBrush +*/ +void QCPItemTracer::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the tracer when selected + + \see setPen, setSelected +*/ +void QCPItemTracer::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer + + \see setSelectedBrush, setPen +*/ +void QCPItemTracer::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer, when selected. + + \see setBrush, setSelected +*/ +void QCPItemTracer::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare + does, \ref tsCrosshair does not). +*/ +void QCPItemTracer::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the style/visual appearance of the tracer. + + If you only want to use the tracer \a position as an anchor for other items, set \a style to + \ref tsNone. +*/ +void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) +{ + mStyle = style; +} + +/*! + Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type + QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. + + To free the tracer from any graph, set \a graph to 0. The tracer \a position can then be placed + freely like any other item position. This is the state the tracer will assume when its graph gets + deleted while still attached to it. + + \see setGraphKey +*/ +void QCPItemTracer::setGraph(QCPGraph *graph) +{ + if (graph) + { + if (graph->parentPlot() == mParentPlot) + { + position->setType(QCPItemPosition::ptPlotCoords); + position->setAxes(graph->keyAxis(), graph->valueAxis()); + mGraph = graph; + updatePosition(); + } else + qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; + } else + { + mGraph = 0; + } +} + +/*! + Sets the key of the graph's data point the tracer will be positioned at. This is the only free + coordinate of a tracer when attached to a graph. + + Depending on \ref setInterpolating, the tracer will be either positioned on the data point + closest to \a key, or will stay exactly at \a key and interpolate the value linearly. + + \see setGraph, setInterpolating +*/ +void QCPItemTracer::setGraphKey(double key) +{ + mGraphKey = key; +} + +void QCPItemTracer::setHidePoint(const QMultiMap &hidePoint) +{ + m_hidePoint = hidePoint; +} + +void QCPItemTracer::addHidePoint(const qint64 &time, const QString &tag) +{ + m_hidePoint.insert(time, tag); +} + +/*! + Sets whether the value of the graph's data points shall be interpolated, when positioning the + tracer. + + If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on + the data point of the graph which is closest to the key, but which is not necessarily exactly + there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and + the appropriate value will be interpolated from the graph's data points linearly. + + \see setGraph, setGraphKey +*/ +void QCPItemTracer::setInterpolating(bool enabled) +{ + mInterpolating = enabled; +} + +void QCPItemTracer::setType(const int &type) +{ + mType = type; +} + +void QCPItemTracer::setTimeStamp(const qint64 &timeStamp) +{ + mTimeStamp = timeStamp; +} + +void QCPItemTracer::setInfo(const QStringList infos) +{ + m_infos = infos; +} + +void QCPItemTracer::showTips() +{ + QString tips; + tips += m_infos.join("\n\n"); + CToolTip::popup(mParentPlot->mapToGlobal(position->pixelPosition().toPoint()), tips, this->parentPlot()); +} + +/* inherits documentation from base class */ +double QCPItemTracer::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return -1; + case tsPlus: + { + if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(center+QPointF(-w, 0), center+QPointF(w, 0)), + QCPVector2D(pos).distanceSquaredToLine(center+QPointF(0, -w), center+QPointF(0, w)))); + break; + } + case tsCrosshair: + { + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(clip.left(), center.y()), QCPVector2D(clip.right(), center.y())), + QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(center.x(), clip.top()), QCPVector2D(center.x(), clip.bottom())))); + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + // distance to border: + double centerDist = QCPVector2D(center-pos).length(); + double circleLine = w; + double result = qAbs(centerDist-circleLine); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (centerDist <= circleLine) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; + } + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); + } + break; + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemTracer::draw(QCPPainter *painter) +{ + updatePosition(); + if (mStyle == tsNone) + return; + + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return; + case tsPlus: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); + painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); + } + break; + } + case tsCrosshair: + { + if (center.y() > clip.top() && center.y() < clip.bottom()) + painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); + if (center.x() > clip.left() && center.x() < clip.right()) + painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); + break; + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawEllipse(center, w, w); + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); + break; + } + } +} + +void QCPItemTracer::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + QCPAbstractItem::mousePressEvent(event, details); +} + +void QCPItemTracer::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + QCPAbstractItem::mouseMoveEvent(event, startPos); + + if(QPoint(event->pos() - position->pixelPosition().toPoint()).manhattanLength() > 8) + { + hovFlag = 0; + return; + } + else if(QPoint(event->pos() - position->pixelPosition().toPoint()).manhattanLength() < 8) + { + if(hovFlag == 0) + hovFlag = 1; + } + if(hovFlag == 1) + { + emit itemTracerHoverd(mTimeStamp, m_hidePoint, m_alarmStatusList); + hovFlag = 2; + } +} + +/*! + If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a + position to reside on the graph data, depending on the configured key (\ref setGraphKey). + + It is called automatically on every redraw and normally doesn't need to be called manually. One + exception is when you want to read the tracer coordinates via \a position and are not sure that + the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. + In that situation, call this function before accessing \a position, to make sure you don't get + out-of-date coordinates. + + If there is no graph set on this tracer, this function does nothing. +*/ +void QCPItemTracer::updatePosition() +{ + if (mGraph) + { + if (mParentPlot->hasPlottable(mGraph)) + { + if (mGraph->data()->size() > 1) + { + QCPGraphDataContainer::const_iterator first = mGraph->data()->constBegin(); + QCPGraphDataContainer::const_iterator last = mGraph->data()->constEnd()-1; + if (mGraphKey <= first->key) + position->setCoords(first->key, first->value); + else if (mGraphKey >= last->key) + position->setCoords(last->key, last->value); + else + { + if(QCPGraph::lsStepLeft == mGraph->lineStyle()) + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->findEnd(mGraphKey, false); + if(it != mGraph->data()->constBegin()) + { + --it; + } + if (mInterpolating) + { + position->setCoords(mGraphKey, it->value); + } + else + { + position->setCoords(it->key, it->value); + } + } + else + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->findBegin(mGraphKey); + if (it != mGraph->data()->constEnd()) // mGraphKey is not exactly on last iterator, but somewhere between iterators + { + QCPGraphDataContainer::const_iterator prevIt = it; + ++it; // won't advance to constEnd because we handled that case (mGraphKey >= last->key) before + if (mInterpolating) + { + // interpolate between iterators around mGraphKey: + double slope = 0; + if (!qFuzzyCompare((double)it->key, (double)prevIt->key)) + slope = (it->value-prevIt->value)/(it->key-prevIt->key); + position->setCoords(mGraphKey, (mGraphKey-prevIt->key)*slope+prevIt->value); + } else + { + // find iterator with key closest to mGraphKey: + if (mGraphKey < (prevIt->key+it->key)*0.5) + position->setCoords(prevIt->key, prevIt->value); + else + position->setCoords(it->key, it->value); + } + } else // mGraphKey is exactly on last iterator (should actually be caught when comparing first/last keys, but this is a failsafe for fp uncertainty) + position->setCoords(it->key, it->value); + } + } + } else if (mGraph->data()->size() == 1) + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->constBegin(); + position->setCoords(it->key, it->value); + } else + qDebug() << Q_FUNC_INFO << "graph has no data"; + } else + qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemTracer::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemTracer::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-tracer.cpp' */ + + +/* including file 'src/items/item-bracket.cpp', size 10687 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemBracket + \brief A bracket for referencing/highlighting certain parts in the plot. + + \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a left and \a right, which define the span of the bracket. If \a left is + actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the + example image. + + The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket + stretches away from the embraced span, can be controlled with \ref setLength. + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+ + It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine + or QCPItemCurve) or a text label (QCPItemText), to the bracket. +*/ + +/*! + Creates a bracket item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + left(createPosition(QLatin1String("left"))), + right(createPosition(QLatin1String("right"))), + center(createAnchor(QLatin1String("center"), aiCenter)), + mLength(8), + mStyle(bsCalligraphic) +{ + left->setCoords(0, 0); + right->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemBracket::~QCPItemBracket() +{ +} + +/*! + Sets the pen that will be used to draw the bracket. + + Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the + stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use + \ref setLength, which has a similar effect. + + \see setSelectedPen +*/ +void QCPItemBracket::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the bracket when selected + + \see setPen, setSelected +*/ +void QCPItemBracket::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the \a length in pixels how far the bracket extends in the direction towards the embraced + span of the bracket (i.e. perpendicular to the left-right-direction) + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+*/ +void QCPItemBracket::setLength(double length) +{ + mLength = length; +} + +/*! + Sets the style of the bracket, i.e. the shape/visual appearance. + + \see setPen +*/ +void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) +{ + mStyle = style; +} + +/* inherits documentation from base class */ +double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QCPVector2D p(pos); + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return -1; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (mStyle) + { + case QCPItemBracket::bsSquare: + case QCPItemBracket::bsRound: + { + double a = p.distanceSquaredToLine(centerVec-widthVec, centerVec+widthVec); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec, centerVec-widthVec); + double c = p.distanceSquaredToLine(centerVec+widthVec+lengthVec, centerVec+widthVec); + return qSqrt(qMin(qMin(a, b), c)); + } + case QCPItemBracket::bsCurly: + case QCPItemBracket::bsCalligraphic: + { + double a = p.distanceSquaredToLine(centerVec-widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec*0.7, centerVec-widthVec*0.75+lengthVec*0.15); + double c = p.distanceSquaredToLine(centerVec+widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double d = p.distanceSquaredToLine(centerVec+widthVec+lengthVec*0.7, centerVec+widthVec*0.75+lengthVec*0.15); + return qSqrt(qMin(qMin(a, b), qMin(c, d))); + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemBracket::draw(QCPPainter *painter) +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + QPolygon boundingPoly; + boundingPoly << leftVec.toPoint() << rightVec.toPoint() + << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (clip.intersects(boundingPoly.boundingRect())) + { + painter->setPen(mainPen()); + switch (mStyle) + { + case bsSquare: + { + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + break; + } + case bsRound: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCurly: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCalligraphic: + { + painter->setPen(Qt::NoPen); + painter->setBrush(QBrush(mainPen().color())); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec-widthVec-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); + path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + + painter->drawPath(path); + break; + } + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemBracket::anchorPixelPosition(int anchorId) const +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return leftVec.toPointF(); + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (anchorId) + { + case aiCenter: + return centerVec.toPointF(); + } + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemBracket::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-bracket.cpp' */ diff --git a/product/src/gui/plugin/TrendCurves/plot/qcustomplot.h b/product/src/gui/plugin/TrendCurves/plot/qcustomplot.h index d818c5b1..8af1c48a 100644 --- a/product/src/gui/plugin/TrendCurves/plot/qcustomplot.h +++ b/product/src/gui/plugin/TrendCurves/plot/qcustomplot.h @@ -1,6763 +1,6763 @@ -/*************************************************************************** -** ** -** QCustomPlot, an easy to use, modern plotting widget for Qt ** -** Copyright (C) 2011-2017 Emanuel Eichhammer ** -** ** -** This program is free software: you can redistribute it and/or modify ** -** it under the terms of the GNU General Public License as published by ** -** the Free Software Foundation, either version 3 of the License, or ** -** (at your option) any later version. ** -** ** -** This program is distributed in the hope that it will be useful, ** -** but WITHOUT ANY WARRANTY; without even the implied warranty of ** -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** -** GNU General Public License for more details. ** -** ** -** You should have received a copy of the GNU General Public License ** -** along with this program. If not, see http://www.gnu.org/licenses/. ** -** ** -**************************************************************************** -** Author: Emanuel Eichhammer ** -** Website/Contact: http://www.qcustomplot.com/ ** -** Date: 04.09.17 ** -** Version: 2.0.0 ** -****************************************************************************/ - -#ifndef QCUSTOMPLOT_H -#define QCUSTOMPLOT_H - -#include - -// some Qt version/configuration dependent macros to include or exclude certain code paths: -#ifdef QCUSTOMPLOT_USE_OPENGL -# if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -# define QCP_OPENGL_PBUFFER -# else -# define QCP_OPENGL_FBO -# endif -# if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) -# define QCP_OPENGL_OFFSCREENSURFACE -# endif -#endif - -#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) -# define QCP_DEVICEPIXELRATIO_SUPPORTED -# if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) -# define QCP_DEVICEPIXELRATIO_FLOAT -# endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef QCP_OPENGL_FBO -# include -# include -# ifdef QCP_OPENGL_OFFSCREENSURFACE -# include -# else -# include -# endif -#endif -#ifdef QCP_OPENGL_PBUFFER -# include -#endif -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -# include -# include -# include -# include -#else -# include -# include -# include -#endif - -class QCPPainter; -class QCustomPlot; -class QCPLayerable; -class QCPLayoutElement; -class QCPLayout; -class QCPAxis; -class QCPAxisRect; -class QCPAxisPainterPrivate; -class QCPAbstractPlottable; -class QCPGraph; -class QCPAbstractItem; -class QCPPlottableInterface1D; -class QCPLegend; -class QCPItemPosition; -class QCPLayer; -class QCPAbstractLegendItem; -class QCPSelectionRect; -class QCPColorMap; -class QCPColorScale; -class QCPBars; - -/* including file 'src/global.h', size 16225 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -// decl definitions for shared library compilation/usage: -#if defined(QCUSTOMPLOT_COMPILE_LIBRARY) -# define QCP_LIB_DECL Q_DECL_EXPORT -#elif defined(QCUSTOMPLOT_USE_LIBRARY) -# define QCP_LIB_DECL Q_DECL_IMPORT -#else -# define QCP_LIB_DECL -#endif - -// define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5) -#ifndef Q_DECL_OVERRIDE -# define Q_DECL_OVERRIDE -#endif - -/*! - The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot - library. - - It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. -*/ -#ifndef Q_MOC_RUN -namespace QCP { -#else -class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace - Q_GADGET - Q_ENUMS(ExportPen) - Q_ENUMS(ResolutionUnit) - Q_ENUMS(SignDomain) - Q_ENUMS(MarginSide) - Q_FLAGS(MarginSides) - Q_ENUMS(AntialiasedElement) - Q_FLAGS(AntialiasedElements) - Q_ENUMS(PlottingHint) - Q_FLAGS(PlottingHints) - Q_ENUMS(Interaction) - Q_FLAGS(Interactions) - Q_ENUMS(SelectionRectMode) - Q_ENUMS(SelectionType) -public: -#endif - -/*! - Defines the different units in which the image resolution can be specified in the export - functions. - - \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered -*/ -enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) - ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) - ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) - }; - -/*! - Defines how cosmetic pens (pens with numerical width 0) are handled during export. - - \see QCustomPlot::savePdf -*/ -enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting - ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level) - }; - -/*! - Represents negative and positive sign domain, e.g. for passing to \ref - QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. - - This is primarily needed when working with logarithmic axis scales, since only one of the sign - domains can be visible at a time. -*/ -enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero - ,sdBoth ///< Both sign domains, including zero, i.e. all numbers - ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero - }; - -/*! - Defines the sides of a rectangular entity to which margins can be applied. - - \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins -*/ -enum MarginSide { msLeft = 0x01 ///< 0x01 left margin - ,msRight = 0x02 ///< 0x02 right margin - ,msTop = 0x04 ///< 0x04 top margin - ,msBottom = 0x08 ///< 0x08 bottom margin - ,msAll = 0xFF ///< 0xFF all margins - ,msNone = 0x00 ///< 0x00 no margin - }; -Q_DECLARE_FLAGS(MarginSides, MarginSide) - -/*! - Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is - neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective - element how it is drawn. Typically it provides a \a setAntialiased function for this. - - \c AntialiasedElements is a flag of or-combined elements of this enum type. - - \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements -*/ -enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks - ,aeGrid = 0x0002 ///< 0x0002 Grid lines - ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines - ,aeLegend = 0x0008 ///< 0x0008 Legend box - ,aeLegendItems = 0x0010 ///< 0x0010 Legend items - ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables - ,aeItems = 0x0040 ///< 0x0040 Main lines of items - ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) - ,aeFills = 0x0100 ///< 0x0100 Borders of fills (e.g. under or between graphs) - ,aeZeroLine = 0x0200 ///< 0x0200 Zero-lines, see \ref QCPGrid::setZeroLinePen - ,aeOther = 0x8000 ///< 0x8000 Other elements that don't fit into any of the existing categories - ,aeAll = 0xFFFF ///< 0xFFFF All elements - ,aeNone = 0x0000 ///< 0x0000 No elements - }; -Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) - -/*! - Defines plotting hints that control various aspects of the quality and speed of plotting. - - \see QCustomPlot::setPlottingHints -*/ -enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set - ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment - ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens. - ,phImmediateRefresh = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint. - ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). - ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. - }; -Q_DECLARE_FLAGS(PlottingHints, PlottingHint) - -/*! - Defines the mouse interactions possible with QCustomPlot. - - \c Interactions is a flag of or-combined elements of this enum type. - - \see QCustomPlot::setInteractions -*/ -enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) - ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) - ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking - ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) - ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) - ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) - ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) - ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, other layout elements,...) - }; -Q_DECLARE_FLAGS(Interactions, Interaction) - -/*! - Defines the behaviour of the selection rect. - - \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect -*/ -enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging - ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly. - ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.) - ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction. - }; - -/*! - Defines the different ways a plottable can be selected. These images show the effect of the - different selection types, when the indicated selection rect was dragged: - -
- - - - - - - - -
\image html selectiontype-none.png stNone\image html selectiontype-whole.png stWhole\image html selectiontype-singledata.png stSingleData\image html selectiontype-datarange.png stDataRange\image html selectiontype-multipledataranges.png stMultipleDataRanges
-
- - \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType -*/ -enum SelectionType { stNone ///< The plottable is not selectable - ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected. - ,stSingleData ///< One individual data point can be selected at a time - ,stDataRange ///< Multiple contiguous data points (a data range) can be selected - ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected - }; - -/*! \internal - - Returns whether the specified \a value is considered an invalid data value for plottables (i.e. - is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the - compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. -*/ -inline bool isInvalidData(double value) -{ - return qIsNaN(value) || qIsInf(value); -} - -/*! \internal - \overload - - Checks two arguments instead of one. -*/ -inline bool isInvalidData(double value1, double value2) -{ - return isInvalidData(value1) || isInvalidData(value2); -} - -/*! \internal - - Sets the specified \a side of \a margins to \a value - - \see getMarginValue -*/ -inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) -{ - switch (side) - { - case QCP::msLeft: margins.setLeft(value); break; - case QCP::msRight: margins.setRight(value); break; - case QCP::msTop: margins.setTop(value); break; - case QCP::msBottom: margins.setBottom(value); break; - case QCP::msAll: margins = QMargins(value, value, value, value); break; - default: break; - } -} - -/*! \internal - - Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or - \ref QCP::msAll, returns 0. - - \see setMarginValue -*/ -inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) -{ - switch (side) - { - case QCP::msLeft: return margins.left(); - case QCP::msRight: return margins.right(); - case QCP::msTop: return margins.top(); - case QCP::msBottom: return margins.bottom(); - default: break; - } - return 0; -} - - -extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace - -} // end of namespace QCP -Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) -Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) -Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) -Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) -Q_DECLARE_METATYPE(QCP::ExportPen) -Q_DECLARE_METATYPE(QCP::ResolutionUnit) -Q_DECLARE_METATYPE(QCP::SignDomain) -Q_DECLARE_METATYPE(QCP::MarginSide) -Q_DECLARE_METATYPE(QCP::AntialiasedElement) -Q_DECLARE_METATYPE(QCP::PlottingHint) -Q_DECLARE_METATYPE(QCP::Interaction) -Q_DECLARE_METATYPE(QCP::SelectionRectMode) -Q_DECLARE_METATYPE(QCP::SelectionType) - -/* end of 'src/global.h' */ - - -/* including file 'src/vector2d.h', size 4928 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPVector2D -{ -public: - QCPVector2D(); - QCPVector2D(double x, double y); - QCPVector2D(const QPoint &point); - QCPVector2D(const QPointF &point); - - // getters: - double x() const { return mX; } - double y() const { return mY; } - double &rx() { return mX; } - double &ry() { return mY; } - - // setters: - void setX(double x) { mX = x; } - void setY(double y) { mY = y; } - - // non-virtual methods: - double length() const { return qSqrt(mX*mX+mY*mY); } - double lengthSquared() const { return mX*mX+mY*mY; } - QPoint toPoint() const { return QPoint(mX, mY); } - QPointF toPointF() const { return QPointF(mX, mY); } - - bool isNull() const { return qIsNull(mX) && qIsNull(mY); } - void normalize(); - QCPVector2D normalized() const; - QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); } - double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; } - double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; - double distanceSquaredToLine(const QLineF &line) const; - double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; - - QCPVector2D &operator*=(double factor); - QCPVector2D &operator/=(double divisor); - QCPVector2D &operator+=(const QCPVector2D &vector); - QCPVector2D &operator-=(const QCPVector2D &vector); - -private: - // property members: - double mX, mY; - - friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); - friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); - friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); - friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2); - friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2); - friend inline const QCPVector2D operator-(const QCPVector2D &vec); -}; -Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE); - -inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } -inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } -inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); } -inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); } -inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); } -inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); } - -/*! \relates QCPVector2D - - Prints \a vec in a human readable format to the qDebug output. -*/ -inline QDebug operator<< (QDebug d, const QCPVector2D &vec) -{ - d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")"; - return d.space(); -} - -/* end of 'src/vector2d.h' */ - - -/* including file 'src/painter.h', size 4035 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPPainter : public QPainter -{ - Q_GADGET -public: - /*! - Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, - depending on whether they are wanted on the respective output device. - */ - enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices - ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. - ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels - ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) - }; - Q_ENUMS(PainterMode) - Q_FLAGS(PainterModes) - Q_DECLARE_FLAGS(PainterModes, PainterMode) - - QCPPainter(); - explicit QCPPainter(QPaintDevice *device); - - // getters: - bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } - PainterModes modes() const { return mModes; } - - // setters: - void setAntialiasing(bool enabled); - void setMode(PainterMode mode, bool enabled=true); - void setModes(PainterModes modes); - - // methods hiding non-virtual base class functions (QPainter bug workarounds): - bool begin(QPaintDevice *device); - void setPen(const QPen &pen); - void setPen(const QColor &color); - void setPen(Qt::PenStyle penStyle); - void drawLine(const QLineF &line); - void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} - void save(); - void restore(); - - // non-virtual methods: - void makeNonCosmetic(); - -protected: - // property members: - PainterModes mModes; - bool mIsAntialiasing; - - // non-property members: - QStack mAntialiasingStack; -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) -Q_DECLARE_METATYPE(QCPPainter::PainterMode) - -/* end of 'src/painter.h' */ - - -/* including file 'src/paintbuffer.h', size 4958 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAbstractPaintBuffer -{ -public: - explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); - virtual ~QCPAbstractPaintBuffer(); - - // getters: - QSize size() const { return mSize; } - bool invalidated() const { return mInvalidated; } - double devicePixelRatio() const { return mDevicePixelRatio; } - - // setters: - void setSize(const QSize &size); - void setInvalidated(bool invalidated=true); - void setDevicePixelRatio(double ratio); - - // introduced virtual methods: - virtual QCPPainter *startPainting() = 0; - virtual void donePainting() {} - virtual void draw(QCPPainter *painter) const = 0; - virtual void clear(const QColor &color) = 0; - -protected: - // property members: - QSize mSize; - double mDevicePixelRatio; - - // non-property members: - bool mInvalidated; - - // introduced virtual methods: - virtual void reallocateBuffer() = 0; -}; - - -class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer -{ -public: - explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); - virtual ~QCPPaintBufferPixmap(); - - // reimplemented virtual methods: - virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; - void clear(const QColor &color) Q_DECL_OVERRIDE; - -protected: - // non-property members: - QPixmap mBuffer; - - // reimplemented virtual methods: - virtual void reallocateBuffer() Q_DECL_OVERRIDE; -}; - - -#ifdef QCP_OPENGL_PBUFFER -class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer -{ -public: - explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); - virtual ~QCPPaintBufferGlPbuffer(); - - // reimplemented virtual methods: - virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; - void clear(const QColor &color) Q_DECL_OVERRIDE; - -protected: - // non-property members: - QGLPixelBuffer *mGlPBuffer; - int mMultisamples; - - // reimplemented virtual methods: - virtual void reallocateBuffer() Q_DECL_OVERRIDE; -}; -#endif // QCP_OPENGL_PBUFFER - - -#ifdef QCP_OPENGL_FBO -class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer -{ -public: - explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice); - virtual ~QCPPaintBufferGlFbo(); - - // reimplemented virtual methods: - virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; - virtual void donePainting() Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; - void clear(const QColor &color) Q_DECL_OVERRIDE; - -protected: - // non-property members: - QWeakPointer mGlContext; - QWeakPointer mGlPaintDevice; - QOpenGLFramebufferObject *mGlFrameBuffer; - - // reimplemented virtual methods: - virtual void reallocateBuffer() Q_DECL_OVERRIDE; -}; -#endif // QCP_OPENGL_FBO - -/* end of 'src/paintbuffer.h' */ - - -/* including file 'src/layer.h', size 6885 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPLayer : public QObject -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) - Q_PROPERTY(QString name READ name) - Q_PROPERTY(int index READ index) - Q_PROPERTY(QList children READ children) - Q_PROPERTY(bool visible READ visible WRITE setVisible) - Q_PROPERTY(LayerMode mode READ mode WRITE setMode) - /// \endcond -public: - - /*! - Defines the different rendering modes of a layer. Depending on the mode, certain layers can be - replotted individually, without the need to replot (possibly complex) layerables on other - layers. - - \see setMode - */ - enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. - ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). - }; - Q_ENUMS(LayerMode) - - QCPLayer(QCustomPlot* parentPlot, const QString &layerName); - virtual ~QCPLayer(); - - // getters: - QCustomPlot *parentPlot() const { return mParentPlot; } - QString name() const { return mName; } - int index() const { return mIndex; } - QList children() const { return mChildren; } - bool visible() const { return mVisible; } - LayerMode mode() const { return mMode; } - - // setters: - void setVisible(bool visible); - void setMode(LayerMode mode); - - // non-virtual methods: - void replot(); - -protected: - // property members: - QCustomPlot *mParentPlot; - QString mName; - int mIndex; - QList mChildren; - bool mVisible; - LayerMode mMode; - - // non-property members: - QWeakPointer mPaintBuffer; - - // non-virtual methods: - void draw(QCPPainter *painter); - void drawToPaintBuffer(); - void addChild(QCPLayerable *layerable, bool prepend); - void removeChild(QCPLayerable *layerable); - -private: - Q_DISABLE_COPY(QCPLayer) - - friend class QCustomPlot; - friend class QCPLayerable; -}; -Q_DECLARE_METATYPE(QCPLayer::LayerMode) - -class QCP_LIB_DECL QCPLayerable : public QObject -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(bool visible READ visible WRITE setVisible) - Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) - Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) - Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) - Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) - /// \endcond -public: - QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); - virtual ~QCPLayerable(); - - // getters: - bool visible() const { return mVisible; } - QCustomPlot *parentPlot() const { return mParentPlot; } - QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } - QCPLayer *layer() const { return mLayer; } - bool antialiased() const { return mAntialiased; } - - // setters: - void setVisible(bool on); - Q_SLOT bool setLayer(QCPLayer *layer); - bool setLayer(const QString &layerName); - void setAntialiased(bool enabled); - - // introduced virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; - - // non-property methods: - bool realVisibility() const; - -signals: - void layerChanged(QCPLayer *newLayer); - -protected: - // property members: - bool mVisible; - QCustomPlot *mParentPlot; - QPointer mParentLayerable; - QCPLayer *mLayer; - bool mAntialiased; - - // introduced virtual methods: - virtual void parentPlotInitialized(QCustomPlot *parentPlot); - virtual QCP::Interaction selectionCategory() const; - virtual QRect clipRect() const; - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; - virtual void draw(QCPPainter *painter) = 0; - // selection events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); - virtual void deselectEvent(bool *selectionStateChanged); - // low-level mouse events: - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); - virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); - virtual void wheelEvent(QWheelEvent *event); - - // non-property methods: - void initializeParentPlot(QCustomPlot *parentPlot); - void setParentLayerable(QCPLayerable* parentLayerable); - bool moveToLayer(QCPLayer *layer, bool prepend); - void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; - -private: - Q_DISABLE_COPY(QCPLayerable) - - friend class QCustomPlot; - friend class QCPLayer; - friend class QCPAxisRect; -}; - -/* end of 'src/layer.h' */ - - -/* including file 'src/axis/range.h', size 5280 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPRange -{ -public: - double lower, upper; - - QCPRange(); - QCPRange(double lower, double upper); - - bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } - bool operator!=(const QCPRange& other) const { return !(*this == other); } - - QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } - QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } - QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } - QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } - friend inline const QCPRange operator+(const QCPRange&, double); - friend inline const QCPRange operator+(double, const QCPRange&); - friend inline const QCPRange operator-(const QCPRange& range, double value); - friend inline const QCPRange operator*(const QCPRange& range, double value); - friend inline const QCPRange operator*(double value, const QCPRange& range); - friend inline const QCPRange operator/(const QCPRange& range, double value); - - double size() const { return upper-lower; } - double center() const { return (upper+lower)*0.5; } - void normalize() { if (lower > upper) qSwap(lower, upper); } - void expand(const QCPRange &otherRange); - void expand(double includeCoord); - QCPRange expanded(const QCPRange &otherRange) const; - QCPRange expanded(double includeCoord) const; - QCPRange bounded(double lowerBound, double upperBound) const; - QCPRange sanitizedForLogScale() const; - QCPRange sanitizedForLinScale() const; - bool contains(double value) const { return value >= lower && value <= upper; } - - static bool validRange(double lower, double upper); - static bool validRange(const QCPRange &range); - static const double minRange; - static const double maxRange; - -}; -Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); - -/*! \relates QCPRange - - Prints \a range in a human readable format to the qDebug output. -*/ -inline QDebug operator<< (QDebug d, const QCPRange &range) -{ - d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")"; - return d.space(); -} - -/*! - Adds \a value to both boundaries of the range. -*/ -inline const QCPRange operator+(const QCPRange& range, double value) -{ - QCPRange result(range); - result += value; - return result; -} - -/*! - Adds \a value to both boundaries of the range. -*/ -inline const QCPRange operator+(double value, const QCPRange& range) -{ - QCPRange result(range); - result += value; - return result; -} - -/*! - Subtracts \a value from both boundaries of the range. -*/ -inline const QCPRange operator-(const QCPRange& range, double value) -{ - QCPRange result(range); - result -= value; - return result; -} - -/*! - Multiplies both boundaries of the range by \a value. -*/ -inline const QCPRange operator*(const QCPRange& range, double value) -{ - QCPRange result(range); - result *= value; - return result; -} - -/*! - Multiplies both boundaries of the range by \a value. -*/ -inline const QCPRange operator*(double value, const QCPRange& range) -{ - QCPRange result(range); - result *= value; - return result; -} - -/*! - Divides both boundaries of the range by \a value. -*/ -inline const QCPRange operator/(const QCPRange& range, double value) -{ - QCPRange result(range); - result /= value; - return result; -} - -/* end of 'src/axis/range.h' */ - - -/* including file 'src/selection.h', size 8579 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPDataRange -{ -public: - QCPDataRange(); - QCPDataRange(int begin, int end); - - bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; } - bool operator!=(const QCPDataRange& other) const { return !(*this == other); } - - // getters: - int begin() const { return mBegin; } - int end() const { return mEnd; } - int size() const { return mEnd-mBegin; } - int length() const { return size(); } - - // setters: - void setBegin(int begin) { mBegin = begin; } - void setEnd(int end) { mEnd = end; } - - // non-property methods: - bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } - bool isEmpty() const { return length() == 0; } - QCPDataRange bounded(const QCPDataRange &other) const; - QCPDataRange expanded(const QCPDataRange &other) const; - QCPDataRange intersection(const QCPDataRange &other) const; - QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); } - bool intersects(const QCPDataRange &other) const; - bool contains(const QCPDataRange &other) const; - -private: - // property members: - int mBegin, mEnd; - -}; -Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE); - - -class QCP_LIB_DECL QCPDataSelection -{ -public: - explicit QCPDataSelection(); - explicit QCPDataSelection(const QCPDataRange &range); - - bool operator==(const QCPDataSelection& other) const; - bool operator!=(const QCPDataSelection& other) const { return !(*this == other); } - QCPDataSelection &operator+=(const QCPDataSelection& other); - QCPDataSelection &operator+=(const QCPDataRange& other); - QCPDataSelection &operator-=(const QCPDataSelection& other); - QCPDataSelection &operator-=(const QCPDataRange& other); - friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b); - friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b); - friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b); - friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b); - friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b); - friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b); - friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b); - friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b); - - // getters: - int dataRangeCount() const { return mDataRanges.size(); } - int dataPointCount() const; - QCPDataRange dataRange(int index=0) const; - QList dataRanges() const { return mDataRanges; } - QCPDataRange span() const; - - // non-property methods: - void addDataRange(const QCPDataRange &dataRange, bool simplify=true); - void clear(); - bool isEmpty() const { return mDataRanges.isEmpty(); } - void simplify(); - void enforceType(QCP::SelectionType type); - bool contains(const QCPDataSelection &other) const; - QCPDataSelection intersection(const QCPDataRange &other) const; - QCPDataSelection intersection(const QCPDataSelection &other) const; - QCPDataSelection inverse(const QCPDataRange &outerRange) const; - -private: - // property members: - QList mDataRanges; - - inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); } -}; -Q_DECLARE_METATYPE(QCPDataSelection) - - -/*! - Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. - The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). -*/ -inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b) -{ - QCPDataSelection result(a); - result += b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. - The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). -*/ -inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b) -{ - QCPDataSelection result(a); - result += b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. - The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). -*/ -inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b) -{ - QCPDataSelection result(a); - result += b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. - The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). -*/ -inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b) -{ - QCPDataSelection result(a); - result += b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. -*/ -inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b) -{ - QCPDataSelection result(a); - result -= b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. -*/ -inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b) -{ - QCPDataSelection result(a); - result -= b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. -*/ -inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b) -{ - QCPDataSelection result(a); - result -= b; - return result; -} - -/*! - Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. -*/ -inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b) -{ - QCPDataSelection result(a); - result -= b; - return result; -} - -/*! \relates QCPDataRange - - Prints \a dataRange in a human readable format to the qDebug output. -*/ -inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange) -{ - d.nospace() << "[" << dataRange.begin() << ".." << dataRange.end()-1 << "]"; - return d.space(); -} - -/*! \relates QCPDataSelection - - Prints \a selection in a human readable format to the qDebug output. -*/ -inline QDebug operator<< (QDebug d, const QCPDataSelection &selection) -{ - d.nospace() << "QCPDataSelection("; - for (int i=0; i elements(QCP::MarginSide side) const { return mChildren.value(side); } - bool isEmpty() const; - void clear(); - -protected: - // non-property members: - QCustomPlot *mParentPlot; - QHash > mChildren; - - // introduced virtual methods: - virtual int commonMargin(QCP::MarginSide side) const; - - // non-virtual methods: - void addChild(QCP::MarginSide side, QCPLayoutElement *element); - void removeChild(QCP::MarginSide side, QCPLayoutElement *element); - -private: - Q_DISABLE_COPY(QCPMarginGroup) - - friend class QCPLayoutElement; -}; - - -class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPLayout* layout READ layout) - Q_PROPERTY(QRect rect READ rect) - Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) - Q_PROPERTY(QMargins margins READ margins WRITE setMargins) - Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) - Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) - Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) - Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect) - /// \endcond -public: - /*! - Defines the phases of the update process, that happens just before a replot. At each phase, - \ref update is called with the according UpdatePhase value. - */ - enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout - ,upMargins ///< Phase in which the margins are calculated and set - ,upLayout ///< Final phase in which the layout system places the rects of the elements - }; - Q_ENUMS(UpdatePhase) - - /*! - Defines to which rect of a layout element the size constraints that can be set via \ref - setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the - margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect) - does not. - - \see setSizeConstraintRect - */ - enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect - , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins - }; - Q_ENUMS(SizeConstraintRect) - - explicit QCPLayoutElement(QCustomPlot *parentPlot=0); - virtual ~QCPLayoutElement(); - - // getters: - QCPLayout *layout() const { return mParentLayout; } - QRect rect() const { return mRect; } - QRect outerRect() const { return mOuterRect; } - QMargins margins() const { return mMargins; } - QMargins minimumMargins() const { return mMinimumMargins; } - QCP::MarginSides autoMargins() const { return mAutoMargins; } - QSize minimumSize() const { return mMinimumSize; } - QSize maximumSize() const { return mMaximumSize; } - SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; } - QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } - QHash marginGroups() const { return mMarginGroups; } - - // setters: - void setOuterRect(const QRect &rect); - void setMargins(const QMargins &margins); - void setMinimumMargins(const QMargins &margins); - void setAutoMargins(QCP::MarginSides sides); - void setMinimumSize(const QSize &size); - void setMinimumSize(int width, int height); - void setMaximumSize(const QSize &size); - void setMaximumSize(int width, int height); - void setSizeConstraintRect(SizeConstraintRect constraintRect); - void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); - - // introduced virtual methods: - virtual void update(UpdatePhase phase); - virtual QSize minimumOuterSizeHint() const; - virtual QSize maximumOuterSizeHint() const; - virtual QList elements(bool recursive) const; - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - -protected: - // property members: - QCPLayout *mParentLayout; - QSize mMinimumSize, mMaximumSize; - SizeConstraintRect mSizeConstraintRect; - QRect mRect, mOuterRect; - QMargins mMargins, mMinimumMargins; - QCP::MarginSides mAutoMargins; - QHash mMarginGroups; - - // introduced virtual methods: - virtual int calculateAutoMargin(QCP::MarginSide side); - virtual void layoutChanged(); - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) } - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } - virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; - -private: - Q_DISABLE_COPY(QCPLayoutElement) - - friend class QCustomPlot; - friend class QCPLayout; - friend class QCPMarginGroup; -}; -Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase) - - -class QCP_LIB_DECL QCPLayout : public QCPLayoutElement -{ - Q_OBJECT -public: - explicit QCPLayout(); - - // reimplemented virtual methods: - virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; - virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual int elementCount() const = 0; - virtual QCPLayoutElement* elementAt(int index) const = 0; - virtual QCPLayoutElement* takeAt(int index) = 0; - virtual bool take(QCPLayoutElement* element) = 0; - virtual void simplify(); - - // non-virtual methods: - bool removeAt(int index); - bool remove(QCPLayoutElement* element); - void clear(); - -protected: - // introduced virtual methods: - virtual void updateLayout(); - - // non-virtual methods: - void sizeConstraintsChanged() const; - void adoptElement(QCPLayoutElement *el); - void releaseElement(QCPLayoutElement *el); - QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; - static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el); - static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el); - -private: - Q_DISABLE_COPY(QCPLayout) - friend class QCPLayoutElement; -}; - - -class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(int rowCount READ rowCount) - Q_PROPERTY(int columnCount READ columnCount) - Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) - Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) - Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) - Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) - Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder) - Q_PROPERTY(int wrap READ wrap WRITE setWrap) - /// \endcond -public: - - /*! - Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). - The column/row at which wrapping into the next row/column occurs can be specified with \ref - setWrap. - - \see setFillOrder - */ - enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap. - ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. - }; - Q_ENUMS(FillOrder) - - explicit QCPLayoutGrid(); - virtual ~QCPLayoutGrid(); - - // getters: - int rowCount() const { return mElements.size(); } - int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } - QList columnStretchFactors() const { return mColumnStretchFactors; } - QList rowStretchFactors() const { return mRowStretchFactors; } - int columnSpacing() const { return mColumnSpacing; } - int rowSpacing() const { return mRowSpacing; } - int wrap() const { return mWrap; } - FillOrder fillOrder() const { return mFillOrder; } - - // setters: - void setColumnStretchFactor(int column, double factor); - void setColumnStretchFactors(const QList &factors); - void setRowStretchFactor(int row, double factor); - void setRowStretchFactors(const QList &factors); - void setColumnSpacing(int pixels); - void setRowSpacing(int pixels); - void setWrap(int count); - void setFillOrder(FillOrder order, bool rearrange=true); - - // reimplemented virtual methods: - virtual void updateLayout() Q_DECL_OVERRIDE; - virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); } - virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; - virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; - virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; - virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; - virtual void simplify() Q_DECL_OVERRIDE; - virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; - virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; - - // non-virtual methods: - QCPLayoutElement *element(int row, int column) const; - bool addElement(int row, int column, QCPLayoutElement *element); - bool addElement(QCPLayoutElement *element); - bool hasElement(int row, int column); - void expandTo(int newRowCount, int newColumnCount); - void insertRow(int newIndex); - void insertColumn(int newIndex); - int rowColToIndex(int row, int column) const; - void indexToRowCol(int index, int &row, int &column) const; - -protected: - // property members: - QList > mElements; - QList mColumnStretchFactors; - QList mRowStretchFactors; - int mColumnSpacing, mRowSpacing; - int mWrap; - FillOrder mFillOrder; - - // non-virtual methods: - void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; - void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; - -private: - Q_DISABLE_COPY(QCPLayoutGrid) -}; -Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder) - - -class QCP_LIB_DECL QCPLayoutInset : public QCPLayout -{ - Q_OBJECT -public: - /*! - Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. - */ - enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect - ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment - }; - Q_ENUMS(InsetPlacement) - - explicit QCPLayoutInset(); - virtual ~QCPLayoutInset(); - - // getters: - InsetPlacement insetPlacement(int index) const; - Qt::Alignment insetAlignment(int index) const; - QRectF insetRect(int index) const; - - // setters: - void setInsetPlacement(int index, InsetPlacement placement); - void setInsetAlignment(int index, Qt::Alignment alignment); - void setInsetRect(int index, const QRectF &rect); - - // reimplemented virtual methods: - virtual void updateLayout() Q_DECL_OVERRIDE; - virtual int elementCount() const Q_DECL_OVERRIDE; - virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; - virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; - virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; - virtual void simplify() Q_DECL_OVERRIDE {} - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void addElement(QCPLayoutElement *element, Qt::Alignment alignment); - void addElement(QCPLayoutElement *element, const QRectF &rect); - -protected: - // property members: - QList mElements; - QList mInsetPlacement; - QList mInsetAlignment; - QList mInsetRect; - -private: - Q_DISABLE_COPY(QCPLayoutInset) -}; -Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement) - -/* end of 'src/layout.h' */ - - -/* including file 'src/lineending.h', size 4426 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPLineEnding -{ - Q_GADGET -public: - /*! - Defines the type of ending decoration for line-like items, e.g. an arrow. - - \image html QCPLineEnding.png - - The width and length of these decorations can be controlled with the functions \ref setWidth - and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only - support a width, the length property is ignored. - - \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding - */ - enum EndingStyle { esNone ///< No ending decoration - ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) - ,esSpikeArrow ///< A filled arrow head with an indented back - ,esLineArrow ///< A non-filled arrow head with open back - ,esDisc ///< A filled circle - ,esSquare ///< A filled square - ,esDiamond ///< A filled diamond (45 degrees rotated square) - ,esBar ///< A bar perpendicular to the line - ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) - ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) - }; - Q_ENUMS(EndingStyle) - - QCPLineEnding(); - QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); - - // getters: - EndingStyle style() const { return mStyle; } - double width() const { return mWidth; } - double length() const { return mLength; } - bool inverted() const { return mInverted; } - - // setters: - void setStyle(EndingStyle style); - void setWidth(double width); - void setLength(double length); - void setInverted(bool inverted); - - // non-property methods: - double boundingDistance() const; - double realLength() const; - void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; - void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; - -protected: - // property members: - EndingStyle mStyle; - double mWidth, mLength; - bool mInverted; -}; -Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); -Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle) - -/* end of 'src/lineending.h' */ - - -/* including file 'src/axis/axisticker.h', size 4177 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTicker -{ - Q_GADGET -public: - /*! - Defines the strategies that the axis ticker may follow when choosing the size of the tick step. - - \see setTickStepStrategy - */ - enum TickStepStrategy - { - tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount) - ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count - }; - Q_ENUMS(TickStepStrategy) - - QCPAxisTicker(); - virtual ~QCPAxisTicker(); - - // getters: - TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } - int tickCount() const { return mTickCount; } - double tickOrigin() const { return mTickOrigin; } - - // setters: - void setTickStepStrategy(TickStepStrategy strategy); - void setTickCount(int count); - void setTickOrigin(double origin); - - // introduced virtual methods: - virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); - -protected: - // property members: - TickStepStrategy mTickStepStrategy; - int mTickCount; - double mTickOrigin; - - // introduced virtual methods: - virtual double getTickStep(const QCPRange &range); - virtual int getSubTickCount(double tickStep); - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision); - virtual QVector createTickVector(double tickStep, const QCPRange &range); - virtual QVector createSubTickVector(int subTickCount, const QVector &ticks); - virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision); - - // non-virtual methods: - void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const; - double pickClosest(double target, const QVector &candidates) const; - double getMantissa(double input, double *magnitude=0) const; - double cleanMantissa(double input) const; -}; -Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) -Q_DECLARE_METATYPE(QSharedPointer) - -/* end of 'src/axis/axisticker.h' */ - - -/* including file 'src/axis/axistickerdatetime.h', size 3289 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker -{ -public: - QCPAxisTickerDateTime(); - - // getters: - QString dateTimeFormat() const { return mDateTimeFormat; } - Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } - - // setters: - void setDateTimeFormat(const QString &format); - void setDateTimeSpec(Qt::TimeSpec spec); - void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) - void setTickOrigin(const QDateTime &origin); - - // static methods: - static QDateTime keyToDateTime(double key); - static double dateTimeToKey(const QDateTime dateTime); - static double dateTimeToKey(const QDate date); - -protected: - // property members: - QString mDateTimeFormat; - Qt::TimeSpec mDateTimeSpec; - - // non-property members: - enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; -}; - -/* end of 'src/axis/axistickerdatetime.h' */ - - -/* including file 'src/axis/axistickertime.h', size 3542 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker -{ - Q_GADGET -public: - /*! - Defines the logical units in which fractions of time spans can be expressed. - - \see setFieldWidth, setTimeFormat - */ - enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) - ,tuSeconds ///< Seconds (%%s in \ref setTimeFormat) - ,tuMinutes ///< Minutes (%%m in \ref setTimeFormat) - ,tuHours ///< Hours (%%h in \ref setTimeFormat) - ,tuDays ///< Days (%%d in \ref setTimeFormat) - }; - Q_ENUMS(TimeUnit) - - QCPAxisTickerTime(); - - // getters: - QString timeFormat() const { return mTimeFormat; } - int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } - - // setters: - void setTimeFormat(const QString &format); - void setFieldWidth(TimeUnit unit, int width); - -protected: - // property members: - QString mTimeFormat; - QHash mFieldWidth; - - // non-property members: - TimeUnit mSmallestUnit, mBiggestUnit; - QHash mFormatPattern; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - - // non-virtual methods: - void replaceUnit(QString &text, TimeUnit unit, int value) const; -}; -Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit) - -/* end of 'src/axis/axistickertime.h' */ - - -/* including file 'src/axis/axistickerfixed.h', size 3308 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker -{ - Q_GADGET -public: - /*! - Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to - control the number of ticks in the axis range. - - \see setScaleStrategy - */ - enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out. - ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount. - ,ssPowers ///< An integer power of the specified tick step is allowed. - }; - Q_ENUMS(ScaleStrategy) - - QCPAxisTickerFixed(); - - // getters: - double tickStep() const { return mTickStep; } - ScaleStrategy scaleStrategy() const { return mScaleStrategy; } - - // setters: - void setTickStep(double step); - void setScaleStrategy(ScaleStrategy strategy); - -protected: - // property members: - double mTickStep; - ScaleStrategy mScaleStrategy; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; -}; -Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy) - -/* end of 'src/axis/axistickerfixed.h' */ - - -/* including file 'src/axis/axistickertext.h', size 3085 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker -{ -public: - QCPAxisTickerText(); - - // getters: - QMap &ticks() { return mTicks; } - int subTickCount() const { return mSubTickCount; } - - // setters: - void setTicks(const QMap &ticks); - void setTicks(const QVector &positions, const QVector labels); - void setSubTickCount(int subTicks); - - // non-virtual methods: - void clear(); - void addTick(double position, QString label); - void addTicks(const QMap &ticks); - void addTicks(const QVector &positions, const QVector &labels); - -protected: - // property members: - QMap mTicks; - int mSubTickCount; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; - -}; - -/* end of 'src/axis/axistickertext.h' */ - - -/* including file 'src/axis/axistickerpi.h', size 3911 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker -{ - Q_GADGET -public: - /*! - Defines how fractions should be displayed in tick labels. - - \see setFractionStyle - */ - enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125". - ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8" - ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol. - }; - Q_ENUMS(FractionStyle) - - QCPAxisTickerPi(); - - // getters: - QString piSymbol() const { return mPiSymbol; } - double piValue() const { return mPiValue; } - bool periodicity() const { return mPeriodicity; } - FractionStyle fractionStyle() const { return mFractionStyle; } - - // setters: - void setPiSymbol(QString symbol); - void setPiValue(double pi); - void setPeriodicity(int multiplesOfPi); - void setFractionStyle(FractionStyle style); - -protected: - // property members: - QString mPiSymbol; - double mPiValue; - int mPeriodicity; - FractionStyle mFractionStyle; - - // non-property members: - double mPiTickStep; // size of one tick step in units of mPiValue - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; - - // non-virtual methods: - void simplifyFraction(int &numerator, int &denominator) const; - QString fractionToString(int numerator, int denominator) const; - QString unicodeFraction(int numerator, int denominator) const; - QString unicodeSuperscript(int number) const; - QString unicodeSubscript(int number) const; -}; -Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle) - -/* end of 'src/axis/axistickerpi.h' */ - - -/* including file 'src/axis/axistickerlog.h', size 2663 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker -{ -public: - QCPAxisTickerLog(); - - // getters: - double logBase() const { return mLogBase; } - int subTickCount() const { return mSubTickCount; } - - // setters: - void setLogBase(double base); - void setSubTickCount(int subTicks); - -protected: - // property members: - double mLogBase; - int mSubTickCount; - - // non-property members: - double mLogBaseLnInv; - - // reimplemented virtual methods: - virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; - virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; - virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; -}; - -/* end of 'src/axis/axistickerlog.h' */ - - -/* including file 'src/axis/axis.h', size 20634 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPGrid :public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) - Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) - Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) - Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) - /// \endcond -public: - explicit QCPGrid(QCPAxis *parentAxis); - - // getters: - bool subGridVisible() const { return mSubGridVisible; } - bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } - bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } - QPen pen() const { return mPen; } - QPen subGridPen() const { return mSubGridPen; } - QPen zeroLinePen() const { return mZeroLinePen; } - - // setters: - void setSubGridVisible(bool visible); - void setAntialiasedSubGrid(bool enabled); - void setAntialiasedZeroLine(bool enabled); - void setPen(const QPen &pen); - void setSubGridPen(const QPen &pen); - void setZeroLinePen(const QPen &pen); - -protected: - // property members: - bool mSubGridVisible; - bool mAntialiasedSubGrid, mAntialiasedZeroLine; - QPen mPen, mSubGridPen, mZeroLinePen; - - // non-property members: - QCPAxis *mParentAxis; - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - // non-virtual methods: - void drawGridLines(QCPPainter *painter) const; - void drawSubGridLines(QCPPainter *painter) const; - - friend class QCPAxis; -}; - - -class QCP_LIB_DECL QCPAxis : public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(AxisType axisType READ axisType) - Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) - Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) - Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) - Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) - Q_PROPERTY(QSharedPointer ticker READ ticker WRITE setTicker) - Q_PROPERTY(bool ticks READ ticks WRITE setTicks) - Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) - Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) - Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) - Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) - Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) - Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) - Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) - Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) - Q_PROPERTY(QVector tickVector READ tickVector) - Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels) - Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) - Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) - Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks) - Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) - Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) - Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) - Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) - Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) - Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) - Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) - Q_PROPERTY(QString label READ label WRITE setLabel) - Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) - Q_PROPERTY(int padding READ padding WRITE setPadding) - Q_PROPERTY(int offset READ offset WRITE setOffset) - Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) - Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) - Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) - Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) - Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) - Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) - Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) - Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) - Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) - Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) - Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) - Q_PROPERTY(QCPGrid* grid READ grid) - /// \endcond -public: - /*! - Defines at which side of the axis rect the axis will appear. This also affects how the tick - marks are drawn, on which side the labels are placed etc. - */ - enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect - ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect - ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect - ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect - }; - Q_ENUMS(AxisType) - Q_FLAGS(AxisTypes) - Q_DECLARE_FLAGS(AxisTypes, AxisType) - /*! - Defines on which side of the axis the tick labels (numbers) shall appear. - - \see setTickLabelSide - */ - enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect - ,lsOutside ///< Tick labels will be displayed outside the axis rect - }; - Q_ENUMS(LabelSide) - /*! - Defines the scale of an axis. - \see setScaleType - */ - enum ScaleType { stLinear ///< Linear scaling - ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). - }; - Q_ENUMS(ScaleType) - /*! - Defines the selectable parts of an axis. - \see setSelectableParts, setSelectedParts - */ - enum SelectablePart { spNone = 0 ///< None of the selectable parts - ,spAxis = 0x001 ///< The axis backbone and tick marks - ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) - ,spAxisLabel = 0x004 ///< The axis label - }; - Q_ENUMS(SelectablePart) - Q_FLAGS(SelectableParts) - Q_DECLARE_FLAGS(SelectableParts, SelectablePart) - - explicit QCPAxis(QCPAxisRect *parent, AxisType type); - virtual ~QCPAxis(); - - // getters: - AxisType axisType() const { return mAxisType; } - QCPAxisRect *axisRect() const { return mAxisRect; } - ScaleType scaleType() const { return mScaleType; } - const QCPRange range() const { return mRange; } - bool rangeReversed() const { return mRangeReversed; } - QSharedPointer ticker() const { return mTicker; } - bool ticks() const { return mTicks; } - bool tickLabels() const { return mTickLabels; } - int tickLabelPadding() const; - QFont tickLabelFont() const { return mTickLabelFont; } - QColor tickLabelColor() const { return mTickLabelColor; } - double tickLabelRotation() const; - LabelSide tickLabelSide() const; - QString numberFormat() const; - int numberPrecision() const { return mNumberPrecision; } - QVector tickVector() const { return mTickVector; } - QVector tickVectorLabels() const { return mTickVectorLabels; } - int tickLengthIn() const; - int tickLengthOut() const; - bool subTicks() const { return mSubTicks; } - int subTickLengthIn() const; - int subTickLengthOut() const; - QPen basePen() const { return mBasePen; } - QPen tickPen() const { return mTickPen; } - QPen subTickPen() const { return mSubTickPen; } - QFont labelFont() const { return mLabelFont; } - QColor labelColor() const { return mLabelColor; } - QString label() const { return mLabel; } - int labelPadding() const; - int padding() const { return mPadding; } - int offset() const; - SelectableParts selectedParts() const { return mSelectedParts; } - SelectableParts selectableParts() const { return mSelectableParts; } - QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } - QFont selectedLabelFont() const { return mSelectedLabelFont; } - QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } - QColor selectedLabelColor() const { return mSelectedLabelColor; } - QPen selectedBasePen() const { return mSelectedBasePen; } - QPen selectedTickPen() const { return mSelectedTickPen; } - QPen selectedSubTickPen() const { return mSelectedSubTickPen; } - QCPLineEnding lowerEnding() const; - QCPLineEnding upperEnding() const; - QCPGrid *grid() const { return mGrid; } - - // setters: - Q_SLOT void setScaleType(QCPAxis::ScaleType type); - Q_SLOT void setRange(const QCPRange &range); - void setRange(double lower, double upper); - void setRange(double position, double size, Qt::AlignmentFlag alignment); - void setRangeLower(double lower); - void setRangeUpper(double upper); - void setRangeReversed(bool reversed); - void setTicker(QSharedPointer ticker); - void setTicks(bool show); - void setTickLabels(bool show); - void setTickLabelPadding(int padding); - void setTickLabelFont(const QFont &font); - void setTickLabelColor(const QColor &color); - void setTickLabelRotation(double degrees); - void setTickLabelSide(LabelSide side); - void setNumberFormat(const QString &formatCode); - void setNumberPrecision(int precision); - void setTickLength(int inside, int outside=0); - void setTickLengthIn(int inside); - void setTickLengthOut(int outside); - void setSubTicks(bool show); - void setSubTickLength(int inside, int outside=0); - void setSubTickLengthIn(int inside); - void setSubTickLengthOut(int outside); - void setBasePen(const QPen &pen); - void setTickPen(const QPen &pen); - void setSubTickPen(const QPen &pen); - void setLabelFont(const QFont &font); - void setLabelColor(const QColor &color); - void setLabel(const QString &str); - void setLabelPadding(int padding); - void setPadding(int padding); - void setOffset(int offset); - void setSelectedTickLabelFont(const QFont &font); - void setSelectedLabelFont(const QFont &font); - void setSelectedTickLabelColor(const QColor &color); - void setSelectedLabelColor(const QColor &color); - void setSelectedBasePen(const QPen &pen); - void setSelectedTickPen(const QPen &pen); - void setSelectedSubTickPen(const QPen &pen); - Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); - Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); - void setLowerEnding(const QCPLineEnding &ending); - void setUpperEnding(const QCPLineEnding &ending); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - // non-property methods: - Qt::Orientation orientation() const { return mOrientation; } - int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; } - void moveRange(double diff); - void scaleRange(double factor); - void scaleRange(double factor, double center); - void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); - void rescale(bool onlyVisiblePlottables=false); - double pixelToCoord(double value) const; - double coordToPixel(double value) const; - SelectablePart getPartAt(const QPointF &pos) const; - QList plottables() const; - QList graphs() const; - QList items() const; - - static AxisType marginSideToAxisType(QCP::MarginSide side); - static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } - static AxisType opposite(AxisType type); - -signals: - void rangeChanged(const QCPRange &newRange); - void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); - void scaleTypeChanged(QCPAxis::ScaleType scaleType); - void selectionChanged(const QCPAxis::SelectableParts &parts); - void selectableChanged(const QCPAxis::SelectableParts &parts); - -protected: - // property members: - // axis base: - AxisType mAxisType; - QCPAxisRect *mAxisRect; - //int mOffset; // in QCPAxisPainter - int mPadding; - Qt::Orientation mOrientation; - SelectableParts mSelectableParts, mSelectedParts; - QPen mBasePen, mSelectedBasePen; - //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter - // axis label: - //int mLabelPadding; // in QCPAxisPainter - QString mLabel; - QFont mLabelFont, mSelectedLabelFont; - QColor mLabelColor, mSelectedLabelColor; - // tick labels: - //int mTickLabelPadding; // in QCPAxisPainter - bool mTickLabels; - //double mTickLabelRotation; // in QCPAxisPainter - QFont mTickLabelFont, mSelectedTickLabelFont; - QColor mTickLabelColor, mSelectedTickLabelColor; - int mNumberPrecision; - QLatin1Char mNumberFormatChar; - bool mNumberBeautifulPowers; - //bool mNumberMultiplyCross; // QCPAxisPainter - // ticks and subticks: - bool mTicks; - bool mSubTicks; - //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter - QPen mTickPen, mSelectedTickPen; - QPen mSubTickPen, mSelectedSubTickPen; - // scale and range: - QCPRange mRange; - bool mRangeReversed; - ScaleType mScaleType; - - // non-property members: - QCPGrid *mGrid; - QCPAxisPainterPrivate *mAxisPainter; - QSharedPointer mTicker; - QVector mTickVector; - QVector mTickVectorLabels; - QVector mSubTickVector; - bool mCachedMarginValid; - int mCachedMargin; - bool mDragging; - QCPRange mDragStartRange; - QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; - - // introduced virtual methods: - virtual int calculateMargin(); - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - // mouse events: - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); - virtual void wheelEvent(QWheelEvent *event); - - // non-virtual methods: - void setupTickVectors(); - QPen getBasePen() const; - QPen getTickPen() const; - QPen getSubTickPen() const; - QFont getTickLabelFont() const; - QFont getLabelFont() const; - QColor getTickLabelColor() const; - QColor getLabelColor() const; - -private: - Q_DISABLE_COPY(QCPAxis) - - friend class QCustomPlot; - friend class QCPGrid; - friend class QCPAxisRect; -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) -Q_DECLARE_METATYPE(QCPAxis::AxisType) -Q_DECLARE_METATYPE(QCPAxis::LabelSide) -Q_DECLARE_METATYPE(QCPAxis::ScaleType) -Q_DECLARE_METATYPE(QCPAxis::SelectablePart) - - -class QCPAxisPainterPrivate -{ -public: - explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); - virtual ~QCPAxisPainterPrivate(); - - virtual void draw(QCPPainter *painter); - virtual int size() const; - void clearCache(); - - QRect axisSelectionBox() const { return mAxisSelectionBox; } - QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } - QRect labelSelectionBox() const { return mLabelSelectionBox; } - - // public property members: - QCPAxis::AxisType type; - QPen basePen; - QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters - int labelPadding; // directly accessed by QCPAxis setters/getters - QFont labelFont; - QColor labelColor; - QString label; - int tickLabelPadding; // directly accessed by QCPAxis setters/getters - double tickLabelRotation; // directly accessed by QCPAxis setters/getters - QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters - bool substituteExponent; - bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters - int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters - QPen tickPen, subTickPen; - QFont tickLabelFont; - QColor tickLabelColor; - QRect axisRect, viewportRect; - double offset; // directly accessed by QCPAxis setters/getters - bool abbreviateDecimalPowers; - bool reversedEndings; - - QVector subTickPositions; - QVector tickPositions; - QVector tickLabels; - -protected: - struct CachedLabel - { - QPointF offset; - QPixmap pixmap; - }; - struct TickLabelData - { - QString basePart, expPart, suffixPart; - QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds; - QFont baseFont, expFont; - }; - QCustomPlot *mParentPlot; - QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters - QCache mLabelCache; - QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; - - virtual QByteArray generateLabelParameterHash() const; - - virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); - virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; - virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; - virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; - virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; -}; - -/* end of 'src/axis/axis.h' */ - - -/* including file 'src/scatterstyle.h', size 7275 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPScatterStyle -{ - Q_GADGET -public: - /*! - Represents the various properties of a scatter style instance. For example, this enum is used - to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when - highlighting selected data points. - - Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref - setFromOther. - */ - enum ScatterProperty { spNone = 0x00 ///< 0x00 None - ,spPen = 0x01 ///< 0x01 The pen property, see \ref setPen - ,spBrush = 0x02 ///< 0x02 The brush property, see \ref setBrush - ,spSize = 0x04 ///< 0x04 The size property, see \ref setSize - ,spShape = 0x08 ///< 0x08 The shape property, see \ref setShape - ,spAll = 0xFF ///< 0xFF All properties - }; - Q_ENUMS(ScatterProperty) - Q_FLAGS(ScatterProperties) - Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty) - - /*! - Defines the shape used for scatter points. - - On plottables/items that draw scatters, the sizes of these visualizations (with exception of - \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are - drawn with the pen and brush specified with \ref setPen and \ref setBrush. - */ - enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) - ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) - ,ssCross ///< \enumimage{ssCross.png} a cross - ,ssPlus ///< \enumimage{ssPlus.png} a plus - ,ssCircle ///< \enumimage{ssCircle.png} a circle - ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) - ,ssSquare ///< \enumimage{ssSquare.png} a square - ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond - ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus - ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline - ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner - ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside - ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside - ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside - ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside - ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines - ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates - ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) - }; - Q_ENUMS(ScatterShape) - - QCPScatterStyle(); - QCPScatterStyle(ScatterShape shape, double size=6); - QCPScatterStyle(ScatterShape shape, const QColor &color, double size); - QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); - QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); - QCPScatterStyle(const QPixmap &pixmap); - QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); - - // getters: - double size() const { return mSize; } - ScatterShape shape() const { return mShape; } - QPen pen() const { return mPen; } - QBrush brush() const { return mBrush; } - QPixmap pixmap() const { return mPixmap; } - QPainterPath customPath() const { return mCustomPath; } - - // setters: - void setFromOther(const QCPScatterStyle &other, ScatterProperties properties); - void setSize(double size); - void setShape(ScatterShape shape); - void setPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setPixmap(const QPixmap &pixmap); - void setCustomPath(const QPainterPath &customPath); - - // non-property methods: - bool isNone() const { return mShape == ssNone; } - bool isPenDefined() const { return mPenDefined; } - void undefinePen(); - void applyTo(QCPPainter *painter, const QPen &defaultPen) const; - void drawShape(QCPPainter *painter, const QPointF &pos) const; - void drawShape(QCPPainter *painter, double x, double y) const; - -protected: - // property members: - double mSize; - ScatterShape mShape; - QPen mPen; - QBrush mBrush; - QPixmap mPixmap; - QPainterPath mCustomPath; - - // non-property members: - bool mPenDefined; -}; -Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties) -Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty) -Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) - -/* end of 'src/scatterstyle.h' */ - - -/* including file 'src/datacontainer.h', size 4596 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -/*! \relates QCPDataContainer - Returns whether the sort key of \a a is less than the sort key of \a b. - - \see QCPDataContainer::sort -*/ -template -inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); } - -template -class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below) -{ -public: - typedef typename QVector::const_iterator const_iterator; - typedef typename QVector::const_reverse_iterator const_reverse_iterator; - typedef typename QVector::iterator iterator; - - QCPDataContainer(); - - // pointer to data - QVector * data() { return &mData; } - - // getters: - int size() const { return mData.size()-mPreallocSize; } - bool isEmpty() const { return size() == 0; } - bool autoSqueeze() const { return mAutoSqueeze; } - - // setters: - void setAutoSqueeze(bool enabled); - - // non-virtual methods: - void set(const QCPDataContainer &data); - void set(const QVector &data, bool alreadySorted=false); - void add(const QCPDataContainer &data); - void add(const QVector &data, bool alreadySorted=false); - void add(const DataType &data); - void removeBefore(double sortKey); - void removeAfter(double sortKey); - void remove(double sortKeyFrom, double sortKeyTo); - void remove(double sortKey); - void clear(); - void sort(); - void squeeze(bool preAllocation=true, bool postAllocation=true); - - const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; } - const_iterator constEnd() const { return mData.constEnd(); } - iterator begin() { return mData.begin()+mPreallocSize; } - iterator end() { return mData.end(); } - const_iterator findBegin(double sortKey, bool expandedRange=true) const; - const_iterator findEnd(double sortKey, bool expandedRange=true) const; - const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); } - QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth); - QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()); - QCPDataRange dataRange() const { return QCPDataRange(0, size()); } - void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const; - -protected: - // property members: - bool mAutoSqueeze; - - // non-property memebers: - QVector mData; - int mPreallocSize; - int mPreallocIteration; - - // non-virtual methods: - void preallocateGrow(int minimumPreallocSize); - void performAutoSqueeze(); -}; - -// include implementation in header since it is a class template: - -/* including file 'src/datacontainer.cpp', size 31349 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPDataContainer -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPDataContainer - \brief The generic data container for one-dimensional plottables - - This class template provides a fast container for data storage of one-dimensional data. The data - type is specified as template parameter (called \a DataType in the following) and must provide - some methods as described in the \ref qcpdatacontainer-datatype "next section". - - The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well - as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The - container uses a preallocation and a postallocation scheme, such that appending and prepending - data (with respect to the sort key) is very fast and minimizes reallocations. If data is added - which needs to be inserted between existing keys, the merge usually can be done quickly too, - using the fact that existing data is always sorted. The user can further improve performance by - specifying that added data is already itself sorted by key, if he can guarantee that this is the - case (see for example \ref add(const QVector &data, bool alreadySorted)). - - The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If - it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin, - \ref end). Changing data members that are not the sort key (for most data types called \a key) is - safe from the container's perspective. - - Great care must be taken however if the sort key is modified through the non-const iterators. For - performance reasons, the iterators don't automatically cause a re-sorting upon their - manipulation. It is thus the responsibility of the user to leave the container in a sorted state - when finished with the data manipulation, before calling any other methods on the container. A - complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref - sort. Failing to do so can not be detected by the container efficiently and will cause both - rendering artifacts and potential data loss. - - Implementing one-dimensional plottables that make use of a \ref QCPDataContainer is usually - done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D", which - introduces an according \a mDataContainer member and some convenience methods. - - \section qcpdatacontainer-datatype Requirements for the DataType template parameter - - The template parameter DataType is the type of the stored data points. It must be - trivially copyable and have the following public methods, preferably inline: - - \li double sortKey() const\n Returns the member variable of this data point that is the - sort key, defining the ordering in the container. Often this variable is simply called \a key. - - \li static DataType fromSortKey(double sortKey)\n Returns a new instance of the data - type initialized with its sort key set to \a sortKey. - - \li static bool sortKeyIsMainKey()\n Returns true if the sort key is equal to the main - key (see method \c mainKey below). For most plottables this is the case. It is not the case for - example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason - why QCPCurve unlike QCPGraph can display parametric curves with loops. - - \li double mainKey() const\n Returns the variable of this data point considered the main - key. This is commonly the variable that is used as the coordinate of this data point on the key - axis of the plottable. This method is used for example when determining the automatic axis - rescaling of key axes (\ref QCPAxis::rescale). - - \li double mainValue() const\n Returns the variable of this data point considered the - main value. This is commonly the variable that is used as the coordinate of this data point on - the value axis of the plottable. - - \li QCPRange valueRange() const\n Returns the range this data point spans in the value - axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with - both lower and upper set to the main data point value. However if the data points can represent - multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close - values at each \a key) this method should return the range those values span. This method is used - for example when determining the automatic axis rescaling of value axes (\ref - QCPAxis::rescale). -*/ - -/* start documentation of inline functions */ - -/*! \fn int QCPDataContainer::size() const - - Returns the number of data points in the container. -*/ - -/*! \fn bool QCPDataContainer::isEmpty() const - - Returns whether this container holds no data points. -*/ - -/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constBegin() const - - Returns a const iterator to the first data point in this container. -*/ - -/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constEnd() const - - Returns a const iterator to the element past the last data point in this container. -*/ - -/*! \fn QCPDataContainer::iterator QCPDataContainer::begin() const - - Returns a non-const iterator to the first data point in this container. - - You can manipulate the data points in-place through the non-const iterators, but great care must - be taken when manipulating the sort key of a data point, see \ref sort, or the detailed - description of this class. -*/ - -/*! \fn QCPDataContainer::iterator QCPDataContainer::end() const - - Returns a non-const iterator to the element past the last data point in this container. - - You can manipulate the data points in-place through the non-const iterators, but great care must - be taken when manipulating the sort key of a data point, see \ref sort, or the detailed - description of this class. -*/ - -/*! \fn QCPDataContainer::const_iterator QCPDataContainer::at(int index) const - - Returns a const iterator to the element with the specified \a index. If \a index points beyond - the available elements in this container, returns \ref constEnd, i.e. an iterator past the last - valid element. - - You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref - dataselection-accessing "data selection page" for an example. -*/ - -/*! \fn QCPDataRange QCPDataContainer::dataRange() const - - Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the - begin index of the returned range is 0, and the end index is \ref size. -*/ - -/* end documentation of inline functions */ - -/*! - Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted - data -*/ -template -QCPDataContainer::QCPDataContainer() : - mAutoSqueeze(true), - mPreallocSize(0), - mPreallocIteration(0) -{ -} - -/*! - Sets whether the container automatically decides when to release memory from its post- and - preallocation pools when data points are removed. By default this is enabled and for typical - applications shouldn't be changed. - - If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with - \ref squeeze. -*/ -template -void QCPDataContainer::setAutoSqueeze(bool enabled) -{ - if (mAutoSqueeze != enabled) - { - mAutoSqueeze = enabled; - if (mAutoSqueeze) - performAutoSqueeze(); - } -} - -/*! \overload - - Replaces the current data in this container with the provided \a data. - - \see add, remove -*/ -template -void QCPDataContainer::set(const QCPDataContainer &data) -{ - clear(); - add(data); -} - -/*! \overload - - Replaces the current data in this container with the provided \a data - - If you can guarantee that the data points in \a data have ascending order with respect to the - DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. - - \see add, remove -*/ -template -void QCPDataContainer::set(const QVector &data, bool alreadySorted) -{ - mData = data; - mPreallocSize = 0; - mPreallocIteration = 0; - if (!alreadySorted) - sort(); -} - -/*! \overload - - Adds the provided \a data to the current data in this container. - - \see set, remove -*/ -template -void QCPDataContainer::add(const QCPDataContainer &data) -{ - if (data.isEmpty()) - return; - - const int n = data.size(); - const int oldSize = size(); - - if (oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones - { - if (mPreallocSize < n) - preallocateGrow(n); - mPreallocSize -= n; - std::copy(data.constBegin(), data.constEnd(), begin()); - } else // don't need to prepend, so append and merge if necessary - { - mData.resize(mData.size()+n); - std::copy(data.constBegin(), data.constEnd(), end()-n); - if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions - std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); - } -} - -/*! - Adds the provided data points in \a data to the current data. - - If you can guarantee that the data points in \a data have ascending order with respect to the - DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. - - \see set, remove -*/ -template -void QCPDataContainer::add(const QVector &data, bool alreadySorted) -{ - if (data.isEmpty()) - return; - if (isEmpty()) - { - set(data, alreadySorted); - return; - } - - const int n = data.size(); - const int oldSize = size(); - - if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones - { - if (mPreallocSize < n) - preallocateGrow(n); - mPreallocSize -= n; - std::copy(data.constBegin(), data.constEnd(), begin()); - } else // don't need to prepend, so append and then sort and merge if necessary - { - mData.resize(mData.size()+n); - std::copy(data.constBegin(), data.constEnd(), end()-n); - if (!alreadySorted) // sort appended subrange if it wasn't already sorted - std::sort(end()-n, end(), qcpLessThanSortKey); - if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions - std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); - } -} - -/*! \overload - - Adds the provided single data point to the current data. - - \see remove -*/ -template -void QCPDataContainer::add(const DataType &data) -{ - if (isEmpty() || !qcpLessThanSortKey(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones - { - mData.append(data); - } else if (qcpLessThanSortKey(data, *constBegin())) // quickly handle prepends using preallocated space - { - if (mPreallocSize < 1) - preallocateGrow(1); - --mPreallocSize; - *begin() = data; - } else // handle inserts, maintaining sorted keys - { - QCPDataContainer::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey); - mData.insert(insertionPoint, data); - } -} - -/*! - Removes all data points with (sort-)keys smaller than or equal to \a sortKey. - - \see removeAfter, remove, clear -*/ -template -void QCPDataContainer::removeBefore(double sortKey) -{ - QCPDataContainer::iterator it = begin(); - QCPDataContainer::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - mPreallocSize += itEnd-it; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) - if (mAutoSqueeze) - performAutoSqueeze(); -} - -/*! - Removes all data points with (sort-)keys greater than or equal to \a sortKey. - - \see removeBefore, remove, clear -*/ -template -void QCPDataContainer::removeAfter(double sortKey) -{ - QCPDataContainer::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - QCPDataContainer::iterator itEnd = end(); - mData.erase(it, itEnd); // typically adds it to the postallocated block - if (mAutoSqueeze) - performAutoSqueeze(); -} - -/*! - Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a - sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single - data point with known (sort-)key, use \ref remove(double sortKey). - - \see removeBefore, removeAfter, clear -*/ -template -void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) -{ - if (sortKeyFrom >= sortKeyTo || isEmpty()) - return; - - QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey); - QCPDataContainer::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey); - mData.erase(it, itEnd); - if (mAutoSqueeze) - performAutoSqueeze(); -} - -/*! \overload - - Removes a single data point at \a sortKey. If the position is not known with absolute (binary) - precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small - fuzziness interval around the suspected position, depeding on the precision with which the - (sort-)key is known. - - \see removeBefore, removeAfter, clear -*/ -template -void QCPDataContainer::remove(double sortKey) -{ - QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - if (it != end() && it->sortKey() == sortKey) - { - if (it == begin()) - ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) - else - mData.erase(it); - } - if (mAutoSqueeze) - performAutoSqueeze(); -} - -/*! - Removes all data points. - - \see remove, removeAfter, removeBefore -*/ -template -void QCPDataContainer::clear() -{ - mData.clear(); - mPreallocIteration = 0; - mPreallocSize = 0; -} - -/*! - Re-sorts all data points in the container by their sort key. - - When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add, - \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full - resort is never necessary. However, if you choose to directly manipulate the sort key on data - points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it - is your responsibility to bring the container back into a sorted state before any other methods - are called on it. This can be achieved by calling this method immediately after finishing the - sort key manipulation. -*/ -template -void QCPDataContainer::sort() -{ - std::sort(begin(), end(), qcpLessThanSortKey); -} - -/*! - Frees all unused memory that is currently in the preallocation and postallocation pools. - - Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref - setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical - applications. - - The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation - should be freed, respectively. -*/ -template -void QCPDataContainer::squeeze(bool preAllocation, bool postAllocation) -{ - if (preAllocation) - { - if (mPreallocSize > 0) - { - std::copy(begin(), end(), mData.begin()); - mData.resize(size()); - mPreallocSize = 0; - } - mPreallocIteration = 0; - } - if (postAllocation) - mData.squeeze(); -} - -/*! - Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just - above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be - considered, otherwise the one just above. - - This can be used in conjunction with \ref findEnd to iterate over data points within a given key - range, including or excluding the bounding data points that are just beyond the specified range. - - If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is - returned. - - If the container is empty, returns \ref constEnd. - - \see findEnd, QCPPlottableInterface1D::findBegin -*/ -template -typename QCPDataContainer::const_iterator QCPDataContainer::findBegin(double sortKey, bool expandedRange) const -{ - if (isEmpty()) - return constEnd(); - - QCPDataContainer::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty - --it; - return it; -} - -/*! - Returns an iterator to the element after the data point with a (sort-)key that is equal to, just - above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey - will be considered, otherwise the one just below. - - This can be used in conjunction with \ref findBegin to iterate over data points within a given - key range, including the bounding data points that are just below and above the specified range. - - If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is - returned. - - If the container is empty, \ref constEnd is returned. - - \see findBegin, QCPPlottableInterface1D::findEnd -*/ -template -typename QCPDataContainer::const_iterator QCPDataContainer::findEnd(double sortKey, bool expandedRange) const -{ - if (isEmpty()) - return constEnd(); - - QCPDataContainer::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); - if (expandedRange && it != constEnd()) - ++it; - return it; -} - -/*! - Returns the range encompassed by the (main-)key coordinate of all data points. The output - parameter \a foundRange indicates whether a sensible range was found. If this is false, you - should not use the returned QCPRange (e.g. the data container is empty or all points have the - same key). - - Use \a signDomain to control which sign of the key coordinates should be considered. This is - relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a - time. - - If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is - the case for most plottables, this method uses this fact and finds the range very quickly. - - \see valueRange -*/ -template -QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain signDomain) -{ - if (isEmpty()) - { - foundRange = false; - return QCPRange(); - } - QCPRange range; - bool haveLower = false; - bool haveUpper = false; - double current; - - QCPDataContainer::const_iterator it = constBegin(); - QCPDataContainer::const_iterator itEnd = constEnd(); - if (signDomain == QCP::sdBoth) // range may be anywhere - { - if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value - { - while (it != itEnd) // find first non-nan going up from left - { - if (!qIsNaN(it->mainValue())) - { - range.lower = it->mainKey(); - haveLower = true; - break; - } - ++it; - } - it = itEnd; - while (it != constBegin()) // find first non-nan going down from right - { - --it; - if (!qIsNaN(it->mainValue())) - { - range.upper = it->mainKey(); - haveUpper = true; - break; - } - } - } else // DataType is not sorted by main key, go through all data points and accordingly expand range - { - while (it != itEnd) - { - if (!qIsNaN(it->mainValue())) - { - current = it->mainKey(); - if (current < range.lower || !haveLower) - { - range.lower = current; - haveLower = true; - } - if (current > range.upper || !haveUpper) - { - range.upper = current; - haveUpper = true; - } - } - ++it; - } - } - } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain - { - while (it != itEnd) - { - if (!qIsNaN(it->mainValue())) - { - current = it->mainKey(); - if ((current < range.lower || !haveLower) && current < 0) - { - range.lower = current; - haveLower = true; - } - if ((current > range.upper || !haveUpper) && current < 0) - { - range.upper = current; - haveUpper = true; - } - } - ++it; - } - } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain - { - while (it != itEnd) - { - if (!qIsNaN(it->mainValue())) - { - current = it->mainKey(); - if ((current < range.lower || !haveLower) && current > 0) - { - range.lower = current; - haveLower = true; - } - if ((current > range.upper || !haveUpper) && current > 0) - { - range.upper = current; - haveUpper = true; - } - } - ++it; - } - } - - foundRange = haveLower && haveUpper; - return range; -} - -/*! - Returns the range encompassed by the value coordinates of the data points in the specified key - range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The - output parameter \a foundRange indicates whether a sensible range was found. If this is false, - you should not use the returned QCPRange (e.g. the data container is empty or all points have the - same value). - - If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), - all data points are considered, without any restriction on the keys. - - Use \a signDomain to control which sign of the value coordinates should be considered. This is - relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a - time. - - \see keyRange -*/ -template -QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange) -{ - if (isEmpty()) - { - foundRange = false; - return QCPRange(); - } - QCPRange range; - const bool restrictKeyRange = inKeyRange != QCPRange(); - bool haveLower = false; - bool haveUpper = false; - QCPRange current; - QCPDataContainer::const_iterator itBegin = constBegin(); - QCPDataContainer::const_iterator itEnd = constEnd(); - if (DataType::sortKeyIsMainKey() && restrictKeyRange) - { - itBegin = findBegin(inKeyRange.lower); - itEnd = findEnd(inKeyRange.upper); - } - if (signDomain == QCP::sdBoth) // range may be anywhere - { - for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) - continue; - current = it->valueRange(); - if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower)) - { - range.lower = current.lower; - haveLower = true; - } - if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper)) - { - range.upper = current.upper; - haveUpper = true; - } - } - } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain - { - for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) - continue; - current = it->valueRange(); - if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower)) - { - range.lower = current.lower; - haveLower = true; - } - if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper)) - { - range.upper = current.upper; - haveUpper = true; - } - } - } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain - { - for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) - { - if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) - continue; - current = it->valueRange(); - if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower)) - { - range.lower = current.lower; - haveLower = true; - } - if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper)) - { - range.upper = current.upper; - haveUpper = true; - } - } - } - - foundRange = haveLower && haveUpper; - return range; -} - -/*! - Makes sure \a begin and \a end mark a data range that is both within the bounds of this data - container's data, as well as within the specified \a dataRange. The initial range described by - the passed iterators \a begin and \a end is never expanded, only contracted if necessary. - - This function doesn't require for \a dataRange to be within the bounds of this data container's - valid range. -*/ -template -void QCPDataContainer::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const -{ - QCPDataRange iteratorRange(begin-constBegin(), end-constBegin()); - iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange())); - begin = constBegin()+iteratorRange.begin(); - end = constBegin()+iteratorRange.end(); -} - -/*! \internal - - Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on - the preallocation history, the container will grow by more than requested, to speed up future - consecutive size increases. - - if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this - method does nothing. -*/ -template -void QCPDataContainer::preallocateGrow(int minimumPreallocSize) -{ - if (minimumPreallocSize <= mPreallocSize) - return; - - int newPreallocSize = minimumPreallocSize; - newPreallocSize += (1u< -void QCPDataContainer::performAutoSqueeze() -{ - const int totalAlloc = mData.capacity(); - const int postAllocSize = totalAlloc-mData.size(); - const int usedSize = size(); - bool shrinkPostAllocation = false; - bool shrinkPreAllocation = false; - if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size - { - shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate! - shrinkPreAllocation = mPreallocSize*10 > usedSize; - } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother - { - shrinkPostAllocation = postAllocSize > usedSize*5; - shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller - } - - if (shrinkPreAllocation || shrinkPostAllocation) - squeeze(shrinkPreAllocation, shrinkPostAllocation); -} -/* end of 'src/datacontainer.cpp' */ - - -/* end of 'src/datacontainer.h' */ - - -/* including file 'src/plottable.h', size 8312 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPSelectionDecorator -{ - Q_GADGET -public: - QCPSelectionDecorator(); - virtual ~QCPSelectionDecorator(); - - // getters: - QPen pen() const { return mPen; } - QBrush brush() const { return mBrush; } - QCPScatterStyle scatterStyle() const { return mScatterStyle; } - QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; } - - // setters: - void setPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); - void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); - - // non-virtual methods: - void applyPen(QCPPainter *painter) const; - void applyBrush(QCPPainter *painter) const; - QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; - - // introduced virtual methods: - virtual void copyFrom(const QCPSelectionDecorator *other); - virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); - -protected: - // property members: - QPen mPen; - QBrush mBrush; - QCPScatterStyle mScatterStyle; - QCPScatterStyle::ScatterProperties mUsedScatterProperties; - // non-property members: - QCPAbstractPlottable *mPlottable; - - // introduced virtual methods: - virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); - -private: - Q_DISABLE_COPY(QCPSelectionDecorator) - friend class QCPAbstractPlottable; -}; -Q_DECLARE_METATYPE(QCPSelectionDecorator*) - - -class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) - Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) - Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) - Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) - Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged) - Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator) - /// \endcond -public: - QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPAbstractPlottable(); - - // getters: - QString name() const { return mName; } - QString desc() const { return mDesc; } - bool antialiasedFill() const { return mAntialiasedFill; } - bool antialiasedScatters() const { return mAntialiasedScatters; } - QPen pen() const { return mPen; } - QBrush brush() const { return mBrush; } - QCPAxis *keyAxis() const { return mKeyAxis.data(); } - QCPAxis *valueAxis() const { return mValueAxis.data(); } - QCP::SelectionType selectable() const { return mSelectable; } - bool selected() const { return !mSelection.isEmpty(); } - QCPDataSelection selection() const { return mSelection; } - QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } - - // setters: - void setName(const QString &name); - void setDesc(const QString &desc); - void setAntialiasedFill(bool enabled); - void setAntialiasedScatters(bool enabled); - void setPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setKeyAxis(QCPAxis *axis); - void setValueAxis(QCPAxis *axis); - Q_SLOT void setSelectable(QCP::SelectionType selectable); - Q_SLOT void setSelection(QCPDataSelection selection); - void setSelectionDecorator(QCPSelectionDecorator *decorator); - - // introduced virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; - virtual QCPPlottableInterface1D *interface1D() { return 0; } - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; - - // non-property methods: - void coordsToPixels(double key, double value, double &x, double &y) const; - const QPointF coordsToPixels(double key, double value) const; - void pixelsToCoords(double x, double y, double &key, double &value) const; - void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; - void rescaleAxes(bool onlyEnlarge=false) const; - void rescaleKeyAxis(bool onlyEnlarge=false) const; - void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; - bool addToLegend(QCPLegend *legend); - bool addToLegend(); - bool removeFromLegend(QCPLegend *legend) const; - bool removeFromLegend() const; - -signals: - void selectionChanged(bool selected); - void selectionChanged(const QCPDataSelection &selection); - void selectableChanged(QCP::SelectionType selectable); - -protected: - // property members: - QString mName; - QString mDesc; - bool mAntialiasedFill, mAntialiasedScatters; - QPen mPen; - QBrush mBrush; - QPointer mKeyAxis, mValueAxis; - QCP::SelectionType mSelectable; - QCPDataSelection mSelection; - QCPSelectionDecorator *mSelectionDecorator; - - // reimplemented virtual methods: - virtual QRect clipRect() const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; - - // non-virtual methods: - void applyFillAntialiasingHint(QCPPainter *painter) const; - void applyScattersAntialiasingHint(QCPPainter *painter) const; - -private: - Q_DISABLE_COPY(QCPAbstractPlottable) - - friend class QCustomPlot; - friend class QCPAxis; - friend class QCPPlottableLegendItem; -}; - - -/* end of 'src/plottable.h' */ - - -/* including file 'src/item.h', size 9384 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemAnchor -{ - Q_GADGET -public: - QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); - virtual ~QCPItemAnchor(); - - // getters: - QString name() const { return mName; } - virtual QPointF pixelPosition() const; - -protected: - // property members: - QString mName; - - // non-property members: - QCustomPlot *mParentPlot; - QCPAbstractItem *mParentItem; - int mAnchorId; - QSet mChildrenX, mChildrenY; - - // introduced virtual methods: - virtual QCPItemPosition *toQCPItemPosition() { return 0; } - - // non-virtual methods: - void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent - void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted - void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent - void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted - -private: - Q_DISABLE_COPY(QCPItemAnchor) - - friend class QCPItemPosition; -}; - - - -class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor -{ - Q_GADGET -public: - /*! - Defines the ways an item position can be specified. Thus it defines what the numbers passed to - \ref setCoords actually mean. - - \see setType - */ - enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. - ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top - ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and - ///< vertically at the top of the viewport/widget, etc. - ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top - ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and - ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. - ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). - }; - Q_ENUMS(PositionType) - - QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name); - virtual ~QCPItemPosition(); - - // getters: - PositionType type() const { return typeX(); } - PositionType typeX() const { return mPositionTypeX; } - PositionType typeY() const { return mPositionTypeY; } - QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } - QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } - QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } - double key() const { return mKey; } - double value() const { return mValue; } - QPointF coords() const { return QPointF(mKey, mValue); } - QCPAxis *keyAxis() const { return mKeyAxis.data(); } - QCPAxis *valueAxis() const { return mValueAxis.data(); } - QCPAxisRect *axisRect() const; - virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; - - // setters: - void setType(PositionType type); - void setTypeX(PositionType type); - void setTypeY(PositionType type); - bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); - bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); - bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); - void setCoords(double key, double value); - void setCoords(const QPointF &coords); - void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); - void setAxisRect(QCPAxisRect *axisRect); - void setPixelPosition(const QPointF &pixelPosition); - -protected: - // property members: - PositionType mPositionTypeX, mPositionTypeY; - QPointer mKeyAxis, mValueAxis; - QPointer mAxisRect; - double mKey, mValue; - QCPItemAnchor *mParentAnchorX, *mParentAnchorY; - - // reimplemented virtual methods: - virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } - -private: - Q_DISABLE_COPY(QCPItemPosition) - -}; -Q_DECLARE_METATYPE(QCPItemPosition::PositionType) - - -class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) - Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) - Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) - Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) - /// \endcond -public: - explicit QCPAbstractItem(QCustomPlot *parentPlot); - virtual ~QCPAbstractItem(); - - // getters: - bool clipToAxisRect() const { return mClipToAxisRect; } - QCPAxisRect *clipAxisRect() const; - bool selectable() const { return mSelectable; } - bool selected() const { return mSelected; } - - // setters: - void setClipToAxisRect(bool clip); - void setClipAxisRect(QCPAxisRect *rect); - Q_SLOT void setSelectable(bool selectable); - Q_SLOT void setSelected(bool selected); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE = 0; - - // non-virtual methods: - QList positions() const { return mPositions; } - QList anchors() const { return mAnchors; } - QCPItemPosition *position(const QString &name) const; - QCPItemAnchor *anchor(const QString &name) const; - bool hasAnchor(const QString &name) const; - -signals: - void selectionChanged(bool selected); - void selectableChanged(bool selectable); - -protected: - // property members: - bool mClipToAxisRect; - QPointer mClipAxisRect; - QList mPositions; - QList mAnchors; - bool mSelectable, mSelected; - - // reimplemented virtual methods: - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - virtual QRect clipRect() const Q_DECL_OVERRIDE; - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual QPointF anchorPixelPosition(int anchorId) const; - - // non-virtual methods: - double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const; - QCPItemPosition *createPosition(const QString &name); - QCPItemAnchor *createAnchor(const QString &name, int anchorId); - -private: - Q_DISABLE_COPY(QCPAbstractItem) - - friend class QCustomPlot; - friend class QCPItemAnchor; -}; - -/* end of 'src/item.h' */ - - -/* including file 'src/core.h', size 14886 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCustomPlot : public QWidget -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) - Q_PROPERTY(QPixmap background READ background WRITE setBackground) - Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) - Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) - Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) - Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) - Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) - Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) - Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) - Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl) - /// \endcond -public: - /*! - Defines how a layer should be inserted relative to an other layer. - - \see addLayer, moveLayer - */ - enum LayerInsertMode { limBelow ///< Layer is inserted below other layer - ,limAbove ///< Layer is inserted above other layer - }; - Q_ENUMS(LayerInsertMode) - - /*! - Defines with what timing the QCustomPlot surface is refreshed after a replot. - - \see replot - */ - enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot - ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided. - ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints. - ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. - }; - Q_ENUMS(RefreshPriority) - - explicit QCustomPlot(QWidget *parent = 0); - virtual ~QCustomPlot(); - - // getters: - QRect viewport() const { return mViewport; } - double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } - QPixmap background() const { return mBackgroundPixmap; } - bool backgroundScaled() const { return mBackgroundScaled; } - Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } - QCPLayoutGrid *plotLayout() const { return mPlotLayout; } - QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } - QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } - bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } - const QCP::Interactions interactions() const { return mInteractions; } - int selectionTolerance() const { return mSelectionTolerance; } - bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } - QCP::PlottingHints plottingHints() const { return mPlottingHints; } - Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } - QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } - QCPSelectionRect *selectionRect() const { return mSelectionRect; } - bool openGl() const { return mOpenGl; } - QPoint symbolPos() { return mSymbolPos; } - - // setters: - void setSymbolPos(const QPoint pos); - void setViewport(const QRect &rect); - void setBufferDevicePixelRatio(double ratio); - void setBackground(const QPixmap &pm); - void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); - void setBackground(const QBrush &brush); - void setBackgroundScaled(bool scaled); - void setBackgroundScaledMode(Qt::AspectRatioMode mode); - void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); - void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); - void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); - void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); - void setAutoAddPlottableToLegend(bool on); - void setInteractions(const QCP::Interactions &interactions); - void setInteraction(const QCP::Interaction &interaction, bool enabled=true); - void setSelectionTolerance(int pixels); - void setNoAntialiasingOnDrag(bool enabled); - void setPlottingHints(const QCP::PlottingHints &hints); - void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); - void setMultiSelectModifier(Qt::KeyboardModifier modifier); - void setSelectionRectMode(QCP::SelectionRectMode mode); - void setSelectionRect(QCPSelectionRect *selectionRect); - void setOpenGl(bool enabled, int multisampling=16); - - // non-property methods: - // plottable interface: - QCPAbstractPlottable *plottable(int index); - QCPAbstractPlottable *plottable(); - bool removePlottable(QCPAbstractPlottable *plottable); - bool removePlottable(int index); - int clearPlottables(); - int plottableCount() const; - QList selectedPlottables() const; - QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; - bool hasPlottable(QCPAbstractPlottable *plottable) const; - - // specialized interface for QCPGraph: - QCPGraph *graph(int index) const; - QCPGraph *graph() const; - QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); - bool removeGraph(QCPGraph *graph); - bool removeGraph(int index); - int clearGraphs(); - int graphCount() const; - QList selectedGraphs() const; - - // item interface: - QCPAbstractItem *item(int index) const; - QCPAbstractItem *item() const; - bool removeItem(QCPAbstractItem *item); - bool removeItem(int index); - int clearItems(bool clearTitle = false); - int itemCount() const; - QList selectedItems() const; - QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; - bool hasItem(QCPAbstractItem *item) const; - - // layer interface: - QCPLayer *layer(const QString &name) const; - QCPLayer *layer(int index) const; - QCPLayer *currentLayer() const; - bool setCurrentLayer(const QString &name); - bool setCurrentLayer(QCPLayer *layer); - int layerCount() const; - bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); - bool removeLayer(QCPLayer *layer); - bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); - - // axis rect/layout interface: - int axisRectCount() const; - QCPAxisRect* axisRect(int index=0) const; - QList axisRects() const; - QCPLayoutElement* layoutElementAt(const QPointF &pos) const; - QCPAxisRect* axisRectAt(const QPointF &pos) const; - Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); - - QList selectedAxes() const; - QList selectedLegends() const; - Q_SLOT void deselectAll(); - - bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); - bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); - bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); - bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); - bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); - QPixmap toPixmap(int width=0, int height=0, double scale=1.0); - void toPainter(QCPPainter *painter, int width=0, int height=0); - Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); - - QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; - QCPLegend *legend; - -signals: - void mouseDoubleClick(QMouseEvent *event); - void mousePress(QMouseEvent *event); - void mouseMove(QMouseEvent *event); - void mouseRelease(QMouseEvent *event); - void mouseWheel(QWheelEvent *event); - - //< 鼠标按下 更新CCurveLegendModel值 - void symbolPosChanged(const double &value); - - void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); - void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); - void itemClick(QCPAbstractItem *item, QMouseEvent *event); - void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); - void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); - void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); - void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); - void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); - - void selectionChangedByUser(); - void beforeReplot(); - void afterReplot(); - -protected: - // property members: - QRect mViewport; - double mBufferDevicePixelRatio; - QCPLayoutGrid *mPlotLayout; - bool mAutoAddPlottableToLegend; - QList mPlottables; - QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph - QList mItems; - QList mLayers; - QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; - QCP::Interactions mInteractions; - int mSelectionTolerance; - bool mNoAntialiasingOnDrag; - QBrush mBackgroundBrush; - QPixmap mBackgroundPixmap; - QPixmap mScaledBackgroundPixmap; - bool mBackgroundScaled; - Qt::AspectRatioMode mBackgroundScaledMode; - QCPLayer *mCurrentLayer; - QCP::PlottingHints mPlottingHints; - Qt::KeyboardModifier mMultiSelectModifier; - QCP::SelectionRectMode mSelectionRectMode; - QCPSelectionRect *mSelectionRect; - bool mOpenGl; - - // non-property members: - QList > mPaintBuffers; - bool mSymbolPressed; - QPoint mSymbolPos; - QPoint mMousePressPos; - bool mMouseHasMoved; - QPointer mMouseEventLayerable; - QPointer mMouseSignalLayerable; - QVariant mMouseEventLayerableDetails; - QVariant mMouseSignalLayerableDetails; - bool mReplotting; - bool mReplotQueued; - int mOpenGlMultisamples; - QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup; - bool mOpenGlCacheLabelsBackup; -#ifdef QCP_OPENGL_FBO - QSharedPointer mGlContext; - QSharedPointer mGlSurface; - QSharedPointer mGlPaintDevice; -#endif - - // reimplemented virtual methods: - virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; - virtual QSize sizeHint() const Q_DECL_OVERRIDE; - virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; - virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - - bool eventFilter(QObject *object, QEvent *event); - - // introduced virtual methods: - virtual void draw(QCPPainter *painter); - virtual void updateLayout(); - virtual void axisRemoved(QCPAxis *axis); - virtual void legendRemoved(QCPLegend *legend); - Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); - Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); - Q_SLOT virtual void processPointSelection(QMouseEvent *event); - - // non-virtual methods: - bool registerPlottable(QCPAbstractPlottable *plottable); - bool registerGraph(QCPGraph *graph); - bool registerItem(QCPAbstractItem* item); - void updateLayerIndices() const; - QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; - QList layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails=0) const; - void drawBackground(QCPPainter *painter); - void setupPaintBuffers(); - QCPAbstractPaintBuffer *createPaintBuffer(); - bool hasInvalidatedPaintBuffers(); - bool setupOpenGl(); - void freeOpenGl(); - - friend class QCPLegend; - friend class QCPAxis; - friend class QCPLayer; - friend class QCPAxisRect; - friend class QCPAbstractPlottable; - friend class QCPGraph; - friend class QCPAbstractItem; -}; -Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode) -Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) - -/* end of 'src/core.h' */ - - -/* including file 'src/plottable1d.h', size 4544 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCPPlottableInterface1D -{ -public: - virtual ~QCPPlottableInterface1D() {} - // introduced pure virtual methods: - virtual int dataCount() const = 0; - virtual double dataMainKey(int index) const = 0; - virtual double dataSortKey(int index) const = 0; - virtual double dataMainValue(int index) const = 0; - virtual QCPRange dataValueRange(int index) const = 0; - virtual QPointF dataPixelPosition(int index) const = 0; - virtual bool sortKeyIsMainKey() const = 0; - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; - virtual int findBegin(double sortKey, bool expandedRange=true) const = 0; - virtual int findEnd(double sortKey, bool expandedRange=true) const = 0; -}; - -template -class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below) -{ - // No Q_OBJECT macro due to template class - -public: - QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPAbstractPlottable1D(); - - // virtual methods of 1d plottable interface: - virtual int dataCount() const Q_DECL_OVERRIDE; - virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; - virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; - virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; - virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; - virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; - virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } - -protected: - // property members: - QSharedPointer > mDataContainer; - - // helpers for subclasses: - void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; - void drawPolyline(QCPPainter *painter, const QVector &lineData, const QVector &status=QVector()) const; - void drawPolyline(QCPPainter *painter, const QPointF *points, const int *status, int pointCount) const; - -private: - Q_DISABLE_COPY(QCPAbstractPlottable1D) - -}; - -// include implementation in header since it is a class template: - -/* including file 'src/plottable1d.cpp', size 22240 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPPlottableInterface1D -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPPlottableInterface1D - \brief Defines an abstract interface for one-dimensional plottables - - This class contains only pure virtual methods which define a common interface to the data - of one-dimensional plottables. - - For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred - base class for one-dimensional plottables). So if you use that template class as base class of - your one-dimensional plottable, you won't have to care about implementing the 1d interface - yourself. - - If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d - interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref - QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure - virtual methods of the 1d interface, matching your data container. Also, reimplement \ref - QCPAbstractPlottable::interface1D to return the \c this pointer. - - If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this - interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return - value. If it indeed implements this interface, you may use it to access the plottable's data - without needing to know the exact type of the plottable or its data point type. -*/ - -/* start documentation of pure virtual functions */ - -/*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; - - Returns the number of data points of the plottable. -*/ - -/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; - - Returns a data selection containing all the data points of this plottable which are contained (or - hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref - dataselection "data selection mechanism"). - - If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not - selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). - - \note \a rect must be a normalized rect (positive or zero width and height). This is especially - important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily - normalized. Use QRect::normalized() when passing a rect which might not be normalized. -*/ - -/*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 - - Returns the main key of the data point at the given \a index. - - What the main key is, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 - - Returns the sort key of the data point at the given \a index. - - What the sort key is, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 - - Returns the main value of the data point at the given \a index. - - What the main value is, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 - - Returns the value range of the data point at the given \a index. - - What the value range is, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0 - - Returns the pixel position on the widget surface at which the data point at the given \a index - appears. - - Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel - coordinates. However, depending on the plottable, this might be a different apparent position - than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data - values can be shifted depending on their stacking, bar grouping or configured base value. -*/ - -/*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0 - - Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey). - - What the sort and main keys are, is defined by the plottable's data type. See the \ref - qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming - convention. -*/ - -/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0 - - Returns the index of the data point with a (sort-)key that is equal to, just below, or just above - \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered, - otherwise the one just above. - - This can be used in conjunction with \ref findEnd to iterate over data points within a given key - range, including or excluding the bounding data points that are just beyond the specified range. - - If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned. - - If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop - using these methods will not iterate over the index 0). - - \see findEnd, QCPDataContainer::findBegin -*/ - -/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0 - - Returns the index one after the data point with a (sort-)key that is equal to, just above, or - just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be - considered, otherwise the one just below. - - This can be used in conjunction with \ref findBegin to iterate over data points within a given - key range, including the bounding data points that are just below and above the specified range. - - If \a expandedRange is true but there are no data points above \a sortKey, the index just above the - highest data point is returned. - - If the container is empty, returns 0. - - \see findBegin, QCPDataContainer::findEnd -*/ - -/* end documentation of pure virtual functions */ - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// QCPAbstractPlottable1D -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/*! \class QCPAbstractPlottable1D - \brief A template base class for plottables with one-dimensional data - - This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref - QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with - one key dimension), such as \ref QCPGraph and QCPCurve. - - The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref - QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member - \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer") and - implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most - subclassed plottables don't need to worry about this anymore. - - Further, it provides a convenience method for retrieving selected/unselected data segments via - \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to - draw selected segments with a different pen/brush than unselected segments (also see \ref - QCPSelectionDecorator). - - This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref - QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data - interface. In spite of that, most plottable subclasses will want to reimplement those methods - again, to provide a more accurate hit test based on their specific data visualization geometry. -*/ - -/* start documentation of inline functions */ - -/*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() - - Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D - interface. - - \seebaseclassmethod -*/ - -/* end documentation of inline functions */ - -/*! - Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable - "QCPAbstractPlottable" constructor and allocates the \a mDataContainer. -*/ -template -QCPAbstractPlottable1D::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) : - QCPAbstractPlottable(keyAxis, valueAxis), - mDataContainer(new QCPDataContainer) -{ -} - -template -QCPAbstractPlottable1D::~QCPAbstractPlottable1D() -{ -} - -/*! - \copydoc QCPPlottableInterface1D::dataCount -*/ -template -int QCPAbstractPlottable1D::dataCount() const -{ - return mDataContainer->size(); -} - -/*! - \copydoc QCPPlottableInterface1D::dataMainKey -*/ -template -double QCPAbstractPlottable1D::dataMainKey(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - return (mDataContainer->constBegin()+index)->mainKey(); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return 0; - } -} - -/*! - \copydoc QCPPlottableInterface1D::dataSortKey -*/ -template -double QCPAbstractPlottable1D::dataSortKey(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - return (mDataContainer->constBegin()+index)->sortKey(); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return 0; - } -} - -/*! - \copydoc QCPPlottableInterface1D::dataMainValue -*/ -template -double QCPAbstractPlottable1D::dataMainValue(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - return (mDataContainer->constBegin()+index)->mainValue(); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return 0; - } -} - -/*! - \copydoc QCPPlottableInterface1D::dataValueRange -*/ -template -QCPRange QCPAbstractPlottable1D::dataValueRange(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - return (mDataContainer->constBegin()+index)->valueRange(); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return QCPRange(0, 0); - } -} - -/*! - \copydoc QCPPlottableInterface1D::dataPixelPosition -*/ -template -QPointF QCPAbstractPlottable1D::dataPixelPosition(int index) const -{ - if (index >= 0 && index < mDataContainer->size()) - { - const typename QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; - return coordsToPixels(it->mainKey(), it->mainValue()); - } else - { - qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; - return QPointF(); - } -} - -/*! - \copydoc QCPPlottableInterface1D::sortKeyIsMainKey -*/ -template -bool QCPAbstractPlottable1D::sortKeyIsMainKey() const -{ - return DataType::sortKeyIsMainKey(); -} - -/*! - Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is - point-like. Most subclasses will want to reimplement this method again, to provide a more - accurate hit test based on the true data visualization geometry. - - \seebaseclassmethod -*/ -template -QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF &rect, bool onlySelectable) const -{ - QCPDataSelection result; - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return result; - if (!mKeyAxis || !mValueAxis) - return result; - - // convert rect given in pixels to ranges given in plot coordinates: - double key1, value1, key2, value2; - pixelsToCoords(rect.topLeft(), key1, value1); - pixelsToCoords(rect.bottomRight(), key2, value2); - QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2 - QCPRange valueRange(value1, value2); - typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); - typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); - if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: - { - begin = mDataContainer->findBegin(keyRange.lower, false); - end = mDataContainer->findEnd(keyRange.upper, false); - } - if (begin == end) - return result; - - int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect - for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) - { - if (currentSegmentBegin == -1) - { - if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment - currentSegmentBegin = it-mDataContainer->constBegin(); - } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended - { - result.addDataRange(QCPDataRange(currentSegmentBegin, it-mDataContainer->constBegin()), false); - currentSegmentBegin = -1; - } - } - // process potential last segment: - if (currentSegmentBegin != -1) - result.addDataRange(QCPDataRange(currentSegmentBegin, end-mDataContainer->constBegin()), false); - - result.simplify(); - return result; -} - -/*! - \copydoc QCPPlottableInterface1D::findBegin -*/ -template -int QCPAbstractPlottable1D::findBegin(double sortKey, bool expandedRange) const -{ - return mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin(); -} - -/*! - \copydoc QCPPlottableInterface1D::findEnd -*/ -template -int QCPAbstractPlottable1D::findEnd(double sortKey, bool expandedRange) const -{ - return mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin(); -} - -/*! - Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is - point-like. Most subclasses will want to reimplement this method again, to provide a more - accurate hit test based on the true data visualization geometry. - - \seebaseclassmethod -*/ -template -double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const -{ - if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) - return -1; - if (!mKeyAxis || !mValueAxis) - return -1; - - QCPDataSelection selectionResult; - double minDistSqr = std::numeric_limits::max(); - int minDistIndex = mDataContainer->size(); - - typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); - typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); - if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: - { - // determine which key range comes into question, taking selection tolerance around pos into account: - double posKeyMin, posKeyMax, dummy; - pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); - pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); - if (posKeyMin > posKeyMax) - qSwap(posKeyMin, posKeyMax); - begin = mDataContainer->findBegin(posKeyMin, true); - end = mDataContainer->findEnd(posKeyMax, true); - } - if (begin == end) - return -1; - QCPRange keyRange(mKeyAxis->range()); - QCPRange valueRange(mValueAxis->range()); - for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) - { - const double mainKey = it->mainKey(); - const double mainValue = it->mainValue(); - if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points - { - const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared(); - if (currentDistSqr < minDistSqr) - { - minDistSqr = currentDistSqr; - minDistIndex = it-mDataContainer->constBegin(); - } - } - } - if (minDistIndex != mDataContainer->size()) - selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false); - - selectionResult.simplify(); - if (details) - details->setValue(selectionResult); - return qSqrt(minDistSqr); -} - -/*! - Splits all data into selected and unselected segments and outputs them via \a selectedSegments - and \a unselectedSegments, respectively. - - This is useful when subclasses implement their \ref draw method and need to draw selected - segments with a different pen/brush than unselected segments (also see \ref - QCPSelectionDecorator). - - \see setSelection -*/ -template -void QCPAbstractPlottable1D::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const -{ - selectedSegments.clear(); - unselectedSegments.clear(); - if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty - { - if (selected()) - selectedSegments << QCPDataRange(0, dataCount()); - else - unselectedSegments << QCPDataRange(0, dataCount()); - } else - { - QCPDataSelection sel(selection()); - sel.simplify(); - selectedSegments = sel.dataRanges(); - unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); - } -} - -/*! - A helper method which draws a line with the passed \a painter, according to the pixel data in \a - lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is - the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or - crashing). - - Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c - QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter - style allows. -*/ -template -void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QVector &lineData, const QVector &status) const -{ - // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: - if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && - painter->pen().style() == Qt::SolidLine && - !painter->modes().testFlag(QCPPainter::pmVectorized) && - !painter->modes().testFlag(QCPPainter::pmNoCaching)) - { - int i = 0; - bool lastIsNan = false; - const int lineDataSize = lineData.size(); - while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN - ++i; - ++i; // because drawing works in 1 point retrospect - while (i < lineDataSize) - { - if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line - { - if (!lastIsNan) - painter->drawLine(lineData.at(i-1), lineData.at(i)); - else - lastIsNan = false; - } else - lastIsNan = true; - ++i; - } - } else - { - int segmentStart = 0; - int i = 0; - const int lineDataSize = lineData.size(); - while (i < lineDataSize) - { - if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block - { - if(status.size() == lineDataSize) - { - drawPolyline(painter, lineData.constData()+segmentStart, status.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point - } - else - { - painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); - } - segmentStart = i+1; - } - ++i; - } - // draw last segment: - if(status.size() == lineDataSize) - { - drawPolyline(painter, lineData.constData()+segmentStart, status.constData()+segmentStart, lineDataSize-segmentStart); - } - else - { - painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart); - } - } -} - -template -void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QPointF *points, const int *status, int pointCount) const -{ - painter->save(); - QColor color = painter->pen().color(); - int preStatus = 0; - int curStatus = 0; - int segmentStart = 0; - for(int i(0); idrawPolyline(points+segmentStart, i-segmentStart+1); - if(curStatus == 1) - painter->setPen(Qt::gray); - else - painter->setPen(color); - segmentStart = i; - preStatus = curStatus; - } - } - painter->drawPolyline(points+segmentStart, pointCount-segmentStart); - painter->restore(); -} -/* end of 'src/plottable1d.cpp' */ - - -/* end of 'src/plottable1d.h' */ - - -/* including file 'src/colorgradient.h', size 6243 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPColorGradient -{ - Q_GADGET -public: - /*! - Defines the color spaces in which color interpolation between gradient stops can be performed. - - \see setColorInterpolation - */ - enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated - ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) - }; - Q_ENUMS(ColorInterpolation) - - /*! - Defines the available presets that can be loaded with \ref loadPreset. See the documentation - there for an image of the presets. - */ - enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) - ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) - ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) - ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) - ,gpCandy ///< Blue over pink to white - ,gpGeography ///< Colors suitable to represent different elevations on geographical maps - ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) - ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white - ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values - ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) - ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) - ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) - }; - Q_ENUMS(GradientPreset) - - QCPColorGradient(); - QCPColorGradient(GradientPreset preset); - bool operator==(const QCPColorGradient &other) const; - bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } - - // getters: - int levelCount() const { return mLevelCount; } - QMap colorStops() const { return mColorStops; } - ColorInterpolation colorInterpolation() const { return mColorInterpolation; } - bool periodic() const { return mPeriodic; } - - // setters: - void setLevelCount(int n); - void setColorStops(const QMap &colorStops); - void setColorStopAt(double position, const QColor &color); - void setColorInterpolation(ColorInterpolation interpolation); - void setPeriodic(bool enabled); - - // non-property methods: - void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); - void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); - QRgb color(double position, const QCPRange &range, bool logarithmic=false); - void loadPreset(GradientPreset preset); - void clearColorStops(); - QCPColorGradient inverted() const; - -protected: - // property members: - int mLevelCount; - QMap mColorStops; - ColorInterpolation mColorInterpolation; - bool mPeriodic; - - // non-property members: - QVector mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied) - bool mColorBufferInvalidated; - - // non-virtual methods: - bool stopsUseAlpha() const; - void updateColorBuffer(); -}; -Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation) -Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) - -/* end of 'src/colorgradient.h' */ - - -/* including file 'src/selectiondecorator-bracket.h', size 4442 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator -{ - Q_GADGET -public: - - /*! - Defines which shape is drawn at the boundaries of selected data ranges. - - Some of the bracket styles further allow specifying a height and/or width, see \ref - setBracketHeight and \ref setBracketWidth. - */ - enum BracketStyle { bsSquareBracket ///< A square bracket is drawn. - ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. - ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. - ,bsPlus ///< A plus is drawn. - ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket. - }; - Q_ENUMS(BracketStyle) - - QCPSelectionDecoratorBracket(); - virtual ~QCPSelectionDecoratorBracket(); - - // getters: - QPen bracketPen() const { return mBracketPen; } - QBrush bracketBrush() const { return mBracketBrush; } - int bracketWidth() const { return mBracketWidth; } - int bracketHeight() const { return mBracketHeight; } - BracketStyle bracketStyle() const { return mBracketStyle; } - bool tangentToData() const { return mTangentToData; } - int tangentAverage() const { return mTangentAverage; } - - // setters: - void setBracketPen(const QPen &pen); - void setBracketBrush(const QBrush &brush); - void setBracketWidth(int width); - void setBracketHeight(int height); - void setBracketStyle(BracketStyle style); - void setTangentToData(bool enabled); - void setTangentAverage(int pointCount); - - // introduced virtual methods: - virtual void drawBracket(QCPPainter *painter, int direction) const; - - // virtual methods: - virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; - -protected: - // property members: - QPen mBracketPen; - QBrush mBracketBrush; - int mBracketWidth; - int mBracketHeight; - BracketStyle mBracketStyle; - bool mTangentToData; - int mTangentAverage; - - // non-virtual methods: - double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const; - QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; - -}; -Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) - -/* end of 'src/selectiondecorator-bracket.h' */ - - -/* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPixmap background READ background WRITE setBackground) - Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) - Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) - Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) - Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) - /// \endcond -public: - explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); - virtual ~QCPAxisRect(); - - // getters: - QPixmap background() const { return mBackgroundPixmap; } - QBrush backgroundBrush() const { return mBackgroundBrush; } - bool backgroundScaled() const { return mBackgroundScaled; } - Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } - Qt::Orientations rangeDrag() const { return mRangeDrag; } - Qt::Orientations rangeZoom() const { return mRangeZoom; } - QCPAxis *rangeDragAxis(Qt::Orientation orientation); - QCPAxis *rangeZoomAxis(Qt::Orientation orientation); - QList rangeDragAxes(Qt::Orientation orientation); - QList rangeZoomAxes(Qt::Orientation orientation); - double rangeZoomFactor(Qt::Orientation orientation); - - // setters: - void setBackground(const QPixmap &pm); - void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); - void setBackground(const QBrush &brush); - void setBackgroundScaled(bool scaled); - void setBackgroundScaledMode(Qt::AspectRatioMode mode); - void setRangeDrag(Qt::Orientations orientations); - void setRangeZoom(Qt::Orientations orientations); - void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); - void setRangeDragAxes(QList axes); - void setRangeDragAxes(QList horizontal, QList vertical); - void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); - void setRangeZoomAxes(QList axes); - void setRangeZoomAxes(QList horizontal, QList vertical); - void setRangeZoomFactor(double horizontalFactor, double verticalFactor); - void setRangeZoomFactor(double factor); - - // non-property methods: - int axisCount(QCPAxis::AxisType type) const; - QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; - QList axes(QCPAxis::AxisTypes types) const; - QList axes() const; - QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); - QList addAxes(QCPAxis::AxisTypes types); - bool removeAxis(QCPAxis *axis); - QCPLayoutInset *insetLayout() const { return mInsetLayout; } - - void zoom(const QRectF &pixelRect); - void zoom(const QRectF &pixelRect, const QList &affectedAxes); - void setupFullAxesBox(bool connectRanges=false); - QList plottables() const; - QList graphs() const; - QList items() const; - - // read-only interface imitating a QRect: - int left() const { return mRect.left(); } - int right() const { return mRect.right(); } - int top() const { return mRect.top(); } - int bottom() const { return mRect.bottom(); } - int width() const { return mRect.width(); } - int height() const { return mRect.height(); } - QSize size() const { return mRect.size(); } - QPoint topLeft() const { return mRect.topLeft(); } - QPoint topRight() const { return mRect.topRight(); } - QPoint bottomLeft() const { return mRect.bottomLeft(); } - QPoint bottomRight() const { return mRect.bottomRight(); } - QPoint center() const { return mRect.center(); } - - // reimplemented virtual methods: - virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; - virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; - - void setScaleRight(const bool &scaleRight = true) { mIsScaleRight = scaleRight; } - bool isScaleRight() { return mIsScaleRight; } - -signals: - void rangeDraged(); - void rangeScaled(); - -protected: - // property members: - QBrush mBackgroundBrush; - QPixmap mBackgroundPixmap; - QPixmap mScaledBackgroundPixmap; - bool mBackgroundScaled; - Qt::AspectRatioMode mBackgroundScaledMode; - QCPLayoutInset *mInsetLayout; - Qt::Orientations mRangeDrag, mRangeZoom; - QList > mRangeDragHorzAxis, mRangeDragVertAxis; - QList > mRangeZoomHorzAxis, mRangeZoomVertAxis; - double mRangeZoomFactorHorz, mRangeZoomFactorVert; - - // non-property members: - QList mDragStartHorzRange, mDragStartVertRange; - QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; - bool mDragging; - QHash > mAxes; - - //< ZH - bool mIsScaleRight; - bool mIsDragMove; - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE; - virtual void layoutChanged() Q_DECL_OVERRIDE; - // events: - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - - // non-property methods: - void drawBackground(QCPPainter *painter); - void updateAxesOffset(QCPAxis::AxisType type); - -private: - Q_DISABLE_COPY(QCPAxisRect) - - friend class QCustomPlot; -}; - - -/* end of 'src/layoutelements/layoutelement-axisrect.h' */ - - -/* including file 'src/layoutelements/layoutelement-legend.h', size 10397 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) - Q_PROPERTY(QFont font READ font WRITE setFont) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) - Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) - Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) - Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) - /// \endcond -public: - explicit QCPAbstractLegendItem(QCPLegend *parent); - - // getters: - QCPLegend *parentLegend() const { return mParentLegend; } - QFont font() const { return mFont; } - QColor textColor() const { return mTextColor; } - QFont selectedFont() const { return mSelectedFont; } - QColor selectedTextColor() const { return mSelectedTextColor; } - bool selectable() const { return mSelectable; } - bool selected() const { return mSelected; } - - // setters: - void setFont(const QFont &font); - void setTextColor(const QColor &color); - void setSelectedFont(const QFont &font); - void setSelectedTextColor(const QColor &color); - Q_SLOT void setSelectable(bool selectable); - Q_SLOT void setSelected(bool selected); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - -signals: - void selectionChanged(bool selected); - void selectableChanged(bool selectable); - -protected: - // property members: - QCPLegend *mParentLegend; - QFont mFont; - QColor mTextColor; - QFont mSelectedFont; - QColor mSelectedTextColor; - bool mSelectable, mSelected; - - // reimplemented virtual methods: - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual QRect clipRect() const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - -private: - Q_DISABLE_COPY(QCPAbstractLegendItem) - - friend class QCPLegend; -}; - - -class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem -{ - Q_OBJECT -public: - QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); - - // getters: - QCPAbstractPlottable *plottable() { return mPlottable; } - -protected: - // property members: - QCPAbstractPlottable *mPlottable; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen getIconBorderPen() const; - QColor getTextColor() const; - QFont getFont() const; -}; - - -class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QFont font READ font WRITE setFont) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) - Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) - Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) - Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) - Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) - Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) - Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) - Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) - /// \endcond -public: - /*! - Defines the selectable parts of a legend - - \see setSelectedParts, setSelectableParts - */ - enum SelectablePart { spNone = 0x000 ///< 0x000 None - ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) - ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) - }; - Q_ENUMS(SelectablePart) - Q_FLAGS(SelectableParts) - Q_DECLARE_FLAGS(SelectableParts, SelectablePart) - - explicit QCPLegend(); - virtual ~QCPLegend(); - - // getters: - QPen borderPen() const { return mBorderPen; } - QBrush brush() const { return mBrush; } - QFont font() const { return mFont; } - QColor textColor() const { return mTextColor; } - QSize iconSize() const { return mIconSize; } - int iconTextPadding() const { return mIconTextPadding; } - QPen iconBorderPen() const { return mIconBorderPen; } - SelectableParts selectableParts() const { return mSelectableParts; } - SelectableParts selectedParts() const; - QPen selectedBorderPen() const { return mSelectedBorderPen; } - QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } - QBrush selectedBrush() const { return mSelectedBrush; } - QFont selectedFont() const { return mSelectedFont; } - QColor selectedTextColor() const { return mSelectedTextColor; } - - // setters: - void setBorderPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setFont(const QFont &font); - void setTextColor(const QColor &color); - void setIconSize(const QSize &size); - void setIconSize(int width, int height); - void setIconTextPadding(int padding); - void setIconBorderPen(const QPen &pen); - Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); - Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); - void setSelectedBorderPen(const QPen &pen); - void setSelectedIconBorderPen(const QPen &pen); - void setSelectedBrush(const QBrush &brush); - void setSelectedFont(const QFont &font); - void setSelectedTextColor(const QColor &color); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QCPAbstractLegendItem *item(int index) const; - QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; - int itemCount() const; - bool hasItem(QCPAbstractLegendItem *item) const; - bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; - bool addItem(QCPAbstractLegendItem *item); - bool removeItem(int index); - bool removeItem(QCPAbstractLegendItem *item); - void clearItems(); - QList selectedItems() const; - -signals: - void selectionChanged(QCPLegend::SelectableParts parts); - void selectableChanged(QCPLegend::SelectableParts parts); - -protected: - // property members: - QPen mBorderPen, mIconBorderPen; - QBrush mBrush; - QFont mFont; - QColor mTextColor; - QSize mIconSize; - int mIconTextPadding; - SelectableParts mSelectedParts, mSelectableParts; - QPen mSelectedBorderPen, mSelectedIconBorderPen; - QBrush mSelectedBrush; - QFont mSelectedFont; - QColor mSelectedTextColor; - - // reimplemented virtual methods: - virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; - virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen getBorderPen() const; - QBrush getBrush() const; - -private: - Q_DISABLE_COPY(QCPLegend) - - friend class QCustomPlot; - friend class QCPAbstractLegendItem; -}; -Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) -Q_DECLARE_METATYPE(QCPLegend::SelectablePart) - -/* end of 'src/layoutelements/layoutelement-legend.h' */ - - -/* including file 'src/layoutelements/layoutelement-textelement.h', size 5353 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QString text READ text WRITE setText) - Q_PROPERTY(QFont font READ font WRITE setFont) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) - Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) - Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) - Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) - /// \endcond -public: - explicit QCPTextElement(QCustomPlot *parentPlot); - QCPTextElement(QCustomPlot *parentPlot, const QString &text); - QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); - QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize); - QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); - - // getters: - QString text() const { return mText; } - int textFlags() const { return mTextFlags; } - QFont font() const { return mFont; } - QColor textColor() const { return mTextColor; } - QFont selectedFont() const { return mSelectedFont; } - QColor selectedTextColor() const { return mSelectedTextColor; } - bool selectable() const { return mSelectable; } - bool selected() const { return mSelected; } - - // setters: - void setText(const QString &text); - void setTextFlags(int flags); - void setFont(const QFont &font); - void setTextColor(const QColor &color); - void setSelectedFont(const QFont &font); - void setSelectedTextColor(const QColor &color); - Q_SLOT void setSelectable(bool selectable); - Q_SLOT void setSelected(bool selected); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - -signals: - void selectionChanged(bool selected); - void selectableChanged(bool selectable); - void clicked(QMouseEvent *event); - void doubleClicked(QMouseEvent *event); - -protected: - // property members: - QString mText; - int mTextFlags; - QFont mFont; - QColor mTextColor; - QFont mSelectedFont; - QColor mSelectedTextColor; - QRect mTextBoundingRect; - bool mSelectable, mSelected; - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; - virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; - // events: - virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; - virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; - - // non-virtual methods: - QFont mainFont() const; - QColor mainTextColor() const; - -private: - Q_DISABLE_COPY(QCPTextElement) -}; - - - -/* end of 'src/layoutelements/layoutelement-textelement.h' */ - - -/* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - - -class QCPColorScaleAxisRectPrivate : public QCPAxisRect -{ - Q_OBJECT -public: - explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); -protected: - QCPColorScale *mParentColorScale; - QImage mGradientImage; - bool mGradientImageInvalidated; - // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale - using QCPAxisRect::calculateAutoMargin; - using QCPAxisRect::mousePressEvent; - using QCPAxisRect::mouseMoveEvent; - using QCPAxisRect::mouseReleaseEvent; - using QCPAxisRect::wheelEvent; - using QCPAxisRect::update; - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - void updateGradientImage(); - Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); - Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); - friend class QCPColorScale; -}; - - -class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) - Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) - Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) - Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) - Q_PROPERTY(QString label READ label WRITE setLabel) - Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) - Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) - Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) - /// \endcond -public: - explicit QCPColorScale(QCustomPlot *parentPlot); - virtual ~QCPColorScale(); - - // getters: - QCPAxis *axis() const { return mColorAxis.data(); } - QCPAxis::AxisType type() const { return mType; } - QCPRange dataRange() const { return mDataRange; } - QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } - QCPColorGradient gradient() const { return mGradient; } - QString label() const; - int barWidth () const { return mBarWidth; } - bool rangeDrag() const; - bool rangeZoom() const; - - // setters: - void setType(QCPAxis::AxisType type); - Q_SLOT void setDataRange(const QCPRange &dataRange); - Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); - Q_SLOT void setGradient(const QCPColorGradient &gradient); - void setLabel(const QString &str); - void setBarWidth(int width); - void setRangeDrag(bool enabled); - void setRangeZoom(bool enabled); - - // non-property methods: - QList colorMaps() const; - void rescaleDataRange(bool onlyVisibleMaps); - - // reimplemented virtual methods: - virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; - -signals: - void dataRangeChanged(const QCPRange &newRange); - void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); - void gradientChanged(const QCPColorGradient &newGradient); - -protected: - // property members: - QCPAxis::AxisType mType; - QCPRange mDataRange; - QCPAxis::ScaleType mDataScaleType; - QCPColorGradient mGradient; - int mBarWidth; - - // non-property members: - QPointer mAxisRect; - QPointer mColorAxis; - - // reimplemented virtual methods: - virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; - // events: - virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; - virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - -private: - Q_DISABLE_COPY(QCPColorScale) - - friend class QCPColorScaleAxisRectPrivate; -}; - - -/* end of 'src/layoutelements/layoutelement-colorscale.h' */ - - -/* including file 'src/plottables/plottable-graph.h', size 9294 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPGraphData -{ -public: - QCPGraphData(); - QCPGraphData(double key, double value, int status=0); - - inline double sortKey() const { return key; } - inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0, 0); } - inline static bool sortKeyIsMainKey() { return true; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return value; } - inline int mainStatus() const { return status; } - - inline QCPRange valueRange() const { return QCPRange(value, value); } - - double key, value; - int status; -}; -Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPGraphDataContainer - - Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. - - This template instantiation is the container in which QCPGraph holds its data. For details about - the generic container, see the documentation of the class template \ref QCPDataContainer. - - \see QCPGraphData, QCPGraph::setData -*/ -typedef QCPDataContainer QCPGraphDataContainer; - -class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) - Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) - Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) - Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) - Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) - /// \endcond -public: - /*! - Defines how the graph's line is represented visually in the plot. The line is drawn with the - current pen of the graph (\ref setPen). - \see setLineStyle - */ - enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented - ///< with symbols according to the scatter style, see \ref setScatterStyle) - ,lsLine ///< data points are connected by a straight line - ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point - ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point - ,lsStepCenter ///< line is drawn as steps where the step is in between two data points - ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line - }; - Q_ENUMS(LineStyle) - - explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPGraph(); - - // getters: - QSharedPointer data() const { return mDataContainer; } - LineStyle lineStyle() const { return mLineStyle; } - QCPScatterStyle scatterStyle() const { return mScatterStyle; } - int scatterSkip() const { return mScatterSkip; } - QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } - bool adaptiveSampling() const { return mAdaptiveSampling; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted=false); - void setLineStyle(LineStyle ls); - void setScatterStyle(const QCPScatterStyle &style); - void setScatterSkip(int skip); - void setChannelFillGraph(QCPGraph *targetGraph); - void setAdaptiveSampling(bool enabled); - - // non-property methods: - void addData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted=false); - void addData(double key, double value, int status=0); - - /** - * @brief value 根据key值,查找value - */ - double value(const double &key); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - -protected: - // property members: - LineStyle mLineStyle; - QCPScatterStyle mScatterStyle; - int mScatterSkip; - QPointer mChannelFillGraph; - bool mAdaptiveSampling; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual void drawFill(QCPPainter *painter, QVector *lines) const; - virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; - virtual void drawLinePlot(QCPPainter *painter, const QVector &lines, const QVector &status) const; - virtual void drawImpulsePlot(QCPPainter *painter, const QVector &lines) const; - - virtual void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; - virtual void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; - - // non-virtual methods: - void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; - void getLines(QVector *lines, const QCPDataRange &dataRange, QVector *status) const; - void getScatters(QVector *scatters, const QCPDataRange &dataRange) const; - void dataToLines(const QVector &data, QVector &lines, QVector &status) const; - void dataToStepLeftLines(const QVector &data, QVector &lines, QVector &status) const; - void dataToStepRightLines(const QVector &data, QVector &lines, QVector &status) const; - void dataToStepCenterLines(const QVector &data, QVector &lines, QVector &status) const; - void dataToImpulseLines(const QVector &data, QVector &lines, QVector &status) const; - QVector getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const; - QVector > getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const; - bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const; - QPointF getFillBasePoint(QPointF matchingDataPoint) const; - const QPolygonF getFillPolygon(const QVector *lineData, QCPDataRange segment) const; - const QPolygonF getChannelFillPolygon(const QVector *lineData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const; - int findIndexBelowX(const QVector *data, double x) const; - int findIndexAboveX(const QVector *data, double x) const; - int findIndexBelowY(const QVector *data, double y) const; - int findIndexAboveY(const QVector *data, double y) const; - double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; -Q_DECLARE_METATYPE(QCPGraph::LineStyle) - -/* end of 'src/plottables/plottable-graph.h' */ - - -/* including file 'src/plottables/plottable-curve.h', size 7409 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPCurveData -{ -public: - QCPCurveData(); - QCPCurveData(double t, double key, double value); - - inline double sortKey() const { return t; } - inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } - inline static bool sortKeyIsMainKey() { return false; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return value; } - - inline QCPRange valueRange() const { return QCPRange(value, value); } - - double t, key, value; -}; -Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPCurveDataContainer - - Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a - sortKey() (returning \a t) is different from \a mainKey() (returning \a key). - - This template instantiation is the container in which QCPCurve holds its data. For details about - the generic container, see the documentation of the class template \ref QCPDataContainer. - - \see QCPCurveData, QCPCurve::setData -*/ -typedef QCPDataContainer QCPCurveDataContainer; - -class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) - Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) - Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) - /// \endcond -public: - /*! - Defines how the curve's line is represented visually in the plot. The line is drawn with the - current pen of the curve (\ref setPen). - \see setLineStyle - */ - enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) - ,lsLine ///< Data points are connected with a straight line - }; - Q_ENUMS(LineStyle) - - explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPCurve(); - - // getters: - QSharedPointer data() const { return mDataContainer; } - QCPScatterStyle scatterStyle() const { return mScatterStyle; } - int scatterSkip() const { return mScatterSkip; } - LineStyle lineStyle() const { return mLineStyle; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); - void setData(const QVector &keys, const QVector &values); - void setScatterStyle(const QCPScatterStyle &style); - void setScatterSkip(int skip); - void setLineStyle(LineStyle style); - - // non-property methods: - void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); - void addData(const QVector &keys, const QVector &values); - void addData(double t, double key, double value); - void addData(double key, double value); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - -protected: - // property members: - QCPScatterStyle mScatterStyle; - int mScatterSkip; - LineStyle mLineStyle; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual void drawCurveLine(QCPPainter *painter, const QVector &lines) const; - virtual void drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const; - - // non-virtual methods: - void getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const; - void getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const; - int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; - QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; - QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; - bool mayTraverse(int prevRegion, int currentRegion) const; - bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const; - void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const; - double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; -Q_DECLARE_METATYPE(QCPCurve::LineStyle) - -/* end of 'src/plottables/plottable-curve.h' */ - - -/* including file 'src/plottables/plottable-bars.h', size 8924 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPBarsGroup : public QObject -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) - Q_PROPERTY(double spacing READ spacing WRITE setSpacing) - /// \endcond -public: - /*! - Defines the ways the spacing between bars in the group can be specified. Thus it defines what - the number passed to \ref setSpacing actually means. - - \see setSpacingType, setSpacing - */ - enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels - ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size - ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range - }; - Q_ENUMS(SpacingType) - - QCPBarsGroup(QCustomPlot *parentPlot); - virtual ~QCPBarsGroup(); - - // getters: - SpacingType spacingType() const { return mSpacingType; } - double spacing() const { return mSpacing; } - - // setters: - void setSpacingType(SpacingType spacingType); - void setSpacing(double spacing); - - // non-virtual methods: - QList bars() const { return mBars; } - QCPBars* bars(int index) const; - int size() const { return mBars.size(); } - bool isEmpty() const { return mBars.isEmpty(); } - void clear(); - bool contains(QCPBars *bars) const { return mBars.contains(bars); } - void append(QCPBars *bars); - void insert(int i, QCPBars *bars); - void remove(QCPBars *bars); - -protected: - // non-property members: - QCustomPlot *mParentPlot; - SpacingType mSpacingType; - double mSpacing; - QList mBars; - - // non-virtual methods: - void registerBars(QCPBars *bars); - void unregisterBars(QCPBars *bars); - - // virtual methods: - double keyPixelOffset(const QCPBars *bars, double keyCoord); - double getPixelSpacing(const QCPBars *bars, double keyCoord); - -private: - Q_DISABLE_COPY(QCPBarsGroup) - - friend class QCPBars; -}; -Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) - - -class QCP_LIB_DECL QCPBarsData -{ -public: - QCPBarsData(); - QCPBarsData(double key, double value); - - inline double sortKey() const { return key; } - inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } - inline static bool sortKeyIsMainKey() { return true; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return value; } - - inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here - - double key, value; -}; -Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPBarsDataContainer - - Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. - - This template instantiation is the container in which QCPBars holds its data. For details about - the generic container, see the documentation of the class template \ref QCPDataContainer. - - \see QCPBarsData, QCPBars::setData -*/ -typedef QCPDataContainer QCPBarsDataContainer; - -class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(double width READ width WRITE setWidth) - Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) - Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) - Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) - Q_PROPERTY(double stackingGap READ stackingGap WRITE setStackingGap) - Q_PROPERTY(QCPBars* barBelow READ barBelow) - Q_PROPERTY(QCPBars* barAbove READ barAbove) - /// \endcond -public: - /*! - Defines the ways the width of the bar can be specified. Thus it defines what the number passed - to \ref setWidth actually means. - - \see setWidthType, setWidth - */ - enum WidthType { wtAbsolute ///< Bar width is in absolute pixels - ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size - ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range - }; - Q_ENUMS(WidthType) - - explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPBars(); - - // getters: - double width() const { return mWidth; } - WidthType widthType() const { return mWidthType; } - QCPBarsGroup *barsGroup() const { return mBarsGroup; } - double baseValue() const { return mBaseValue; } - double stackingGap() const { return mStackingGap; } - QCPBars *barBelow() const { return mBarBelow.data(); } - QCPBars *barAbove() const { return mBarAbove.data(); } - QSharedPointer data() const { return mDataContainer; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); - void setWidth(double width); - void setWidthType(WidthType widthType); - void setBarsGroup(QCPBarsGroup *barsGroup); - void setBaseValue(double baseValue); - void setStackingGap(double pixels); - - // non-property methods: - void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); - void addData(double key, double value); - void moveBelow(QCPBars *bars); - void moveAbove(QCPBars *bars); - - // reimplemented virtual methods: - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; - -protected: - // property members: - double mWidth; - WidthType mWidthType; - QCPBarsGroup *mBarsGroup; - double mBaseValue; - double mStackingGap; - QPointer mBarBelow, mBarAbove; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const; - QRectF getBarRect(double key, double value) const; - void getPixelWidth(double key, double &lower, double &upper) const; - double getStackedBaseValue(double key, bool positive) const; - static void connectBars(QCPBars* lower, QCPBars* upper); - - friend class QCustomPlot; - friend class QCPLegend; - friend class QCPBarsGroup; -}; -Q_DECLARE_METATYPE(QCPBars::WidthType) - -/* end of 'src/plottables/plottable-bars.h' */ - - -/* including file 'src/plottables/plottable-statisticalbox.h', size 7516 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPStatisticalBoxData -{ -public: - QCPStatisticalBoxData(); - QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector& outliers=QVector()); - - inline double sortKey() const { return key; } - inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); } - inline static bool sortKeyIsMainKey() { return true; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return median; } - - inline QCPRange valueRange() const - { - QCPRange result(minimum, maximum); - for (QVector::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); ++it) - result.expand(*it); - return result; - } - - double key, minimum, lowerQuartile, median, upperQuartile, maximum; - QVector outliers; -}; -Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); - - -/*! \typedef QCPStatisticalBoxDataContainer - - Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. - - This template instantiation is the container in which QCPStatisticalBox holds its data. For - details about the generic container, see the documentation of the class template \ref - QCPDataContainer. - - \see QCPStatisticalBoxData, QCPStatisticalBox::setData -*/ -typedef QCPDataContainer QCPStatisticalBoxDataContainer; - -class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(double width READ width WRITE setWidth) - Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) - Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) - Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) - Q_PROPERTY(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased) - Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) - Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) - /// \endcond -public: - explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); - - // getters: - QSharedPointer data() const { return mDataContainer; } - double width() const { return mWidth; } - double whiskerWidth() const { return mWhiskerWidth; } - QPen whiskerPen() const { return mWhiskerPen; } - QPen whiskerBarPen() const { return mWhiskerBarPen; } - bool whiskerAntialiased() const { return mWhiskerAntialiased; } - QPen medianPen() const { return mMedianPen; } - QCPScatterStyle outlierStyle() const { return mOutlierStyle; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); - void setWidth(double width); - void setWhiskerWidth(double width); - void setWhiskerPen(const QPen &pen); - void setWhiskerBarPen(const QPen &pen); - void setWhiskerAntialiased(bool enabled); - void setMedianPen(const QPen &pen); - void setOutlierStyle(const QCPScatterStyle &style); - - // non-property methods: - void addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); - void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers=QVector()); - - // reimplemented virtual methods: - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - -protected: - // property members: - double mWidth; - double mWhiskerWidth; - QPen mWhiskerPen, mWhiskerBarPen; - bool mWhiskerAntialiased; - QPen mMedianPen; - QCPScatterStyle mOutlierStyle; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // introduced virtual methods: - virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const; - - // non-virtual methods: - void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const; - QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const; - QVector getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; - QVector getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; - -/* end of 'src/plottables/plottable-statisticalbox.h' */ - - -/* including file 'src/plottables/plottable-colormap.h', size 7070 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPColorMapData -{ -public: - QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); - ~QCPColorMapData(); - QCPColorMapData(const QCPColorMapData &other); - QCPColorMapData &operator=(const QCPColorMapData &other); - - // getters: - int keySize() const { return mKeySize; } - int valueSize() const { return mValueSize; } - QCPRange keyRange() const { return mKeyRange; } - QCPRange valueRange() const { return mValueRange; } - QCPRange dataBounds() const { return mDataBounds; } - double data(double key, double value); - double cell(int keyIndex, int valueIndex); - unsigned char alpha(int keyIndex, int valueIndex); - - // setters: - void setSize(int keySize, int valueSize); - void setKeySize(int keySize); - void setValueSize(int valueSize); - void setRange(const QCPRange &keyRange, const QCPRange &valueRange); - void setKeyRange(const QCPRange &keyRange); - void setValueRange(const QCPRange &valueRange); - void setData(double key, double value, double z); - void setCell(int keyIndex, int valueIndex, double z); - void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); - - // non-property methods: - void recalculateDataBounds(); - void clear(); - void clearAlpha(); - void fill(double z); - void fillAlpha(unsigned char alpha); - bool isEmpty() const { return mIsEmpty; } - void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; - void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; - -protected: - // property members: - int mKeySize, mValueSize; - QCPRange mKeyRange, mValueRange; - bool mIsEmpty; - - // non-property members: - double *mData; - unsigned char *mAlpha; - QCPRange mDataBounds; - bool mDataModified; - - bool createAlpha(bool initializeOpaque=true); - - friend class QCPColorMap; -}; - - -class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) - Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) - Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) - Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) - Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) - Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) - /// \endcond -public: - explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPColorMap(); - - // getters: - QCPColorMapData *data() const { return mMapData; } - QCPRange dataRange() const { return mDataRange; } - QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } - bool interpolate() const { return mInterpolate; } - bool tightBoundary() const { return mTightBoundary; } - QCPColorGradient gradient() const { return mGradient; } - QCPColorScale *colorScale() const { return mColorScale.data(); } - - // setters: - void setData(QCPColorMapData *data, bool copy=false); - Q_SLOT void setDataRange(const QCPRange &dataRange); - Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); - Q_SLOT void setGradient(const QCPColorGradient &gradient); - void setInterpolate(bool enabled); - void setTightBoundary(bool enabled); - void setColorScale(QCPColorScale *colorScale); - - // non-property methods: - void rescaleDataRange(bool recalculateDataBounds=false); - Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - -signals: - void dataRangeChanged(const QCPRange &newRange); - void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); - void gradientChanged(const QCPColorGradient &newGradient); - -protected: - // property members: - QCPRange mDataRange; - QCPAxis::ScaleType mDataScaleType; - QCPColorMapData *mMapData; - QCPColorGradient mGradient; - bool mInterpolate; - bool mTightBoundary; - QPointer mColorScale; - - // non-property members: - QImage mMapImage, mUndersampledMapImage; - QPixmap mLegendIcon; - bool mMapImageInvalidated; - - // introduced virtual methods: - virtual void updateMapImage(); - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - friend class QCustomPlot; - friend class QCPLegend; -}; - -/* end of 'src/plottables/plottable-colormap.h' */ - - -/* including file 'src/plottables/plottable-financial.h', size 8622 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPFinancialData -{ -public: - QCPFinancialData(); - QCPFinancialData(double key, double open, double high, double low, double close); - - inline double sortKey() const { return key; } - inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); } - inline static bool sortKeyIsMainKey() { return true; } - - inline double mainKey() const { return key; } - inline double mainValue() const { return open; } - - inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them - - double key, open, high, low, close; -}; -Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPFinancialDataContainer - - Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. - - This template instantiation is the container in which QCPFinancial holds its data. For details - about the generic container, see the documentation of the class template \ref QCPDataContainer. - - \see QCPFinancialData, QCPFinancial::setData -*/ -typedef QCPDataContainer QCPFinancialDataContainer; - -class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) - Q_PROPERTY(double width READ width WRITE setWidth) - Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) - Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) - Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) - Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) - Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) - Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) - /// \endcond -public: - /*! - Defines the ways the width of the financial bar can be specified. Thus it defines what the - number passed to \ref setWidth actually means. - - \see setWidthType, setWidth - */ - enum WidthType { wtAbsolute ///< width is in absolute pixels - ,wtAxisRectRatio ///< width is given by a fraction of the axis rect size - ,wtPlotCoords ///< width is in key coordinates and thus scales with the key axis range - }; - Q_ENUMS(WidthType) - - /*! - Defines the possible representations of OHLC data in the plot. - - \see setChartStyle - */ - enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation - ,csCandlestick ///< Candlestick representation - }; - Q_ENUMS(ChartStyle) - - explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPFinancial(); - - // getters: - QSharedPointer data() const { return mDataContainer; } - ChartStyle chartStyle() const { return mChartStyle; } - double width() const { return mWidth; } - WidthType widthType() const { return mWidthType; } - bool twoColored() const { return mTwoColored; } - QBrush brushPositive() const { return mBrushPositive; } - QBrush brushNegative() const { return mBrushNegative; } - QPen penPositive() const { return mPenPositive; } - QPen penNegative() const { return mPenNegative; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); - void setChartStyle(ChartStyle style); - void setWidth(double width); - void setWidthType(WidthType widthType); - void setTwoColored(bool twoColored); - void setBrushPositive(const QBrush &brush); - void setBrushNegative(const QBrush &brush); - void setPenPositive(const QPen &pen); - void setPenNegative(const QPen &pen); - - // non-property methods: - void addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); - void addData(double key, double open, double high, double low, double close); - - // reimplemented virtual methods: - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - - // static methods: - static QCPFinancialDataContainer timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); - -protected: - // property members: - ChartStyle mChartStyle; - double mWidth; - WidthType mWidthType; - bool mTwoColored; - QBrush mBrushPositive, mBrushNegative; - QPen mPenPositive, mPenNegative; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); - void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); - double getPixelWidth(double key, double keyPixel) const; - double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; - double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; - void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const; - QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; -Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) - -/* end of 'src/plottables/plottable-financial.h' */ - - -/* including file 'src/plottables/plottable-errorbar.h', size 7727 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPErrorBarsData -{ -public: - QCPErrorBarsData(); - explicit QCPErrorBarsData(double error); - QCPErrorBarsData(double errorMinus, double errorPlus); - - double errorMinus, errorPlus; -}; -Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE); - - -/*! \typedef QCPErrorBarsDataContainer - - Container for storing \ref QCPErrorBarsData points. It is a typedef for QVector<\ref - QCPErrorBarsData>. - - This is the container in which \ref QCPErrorBars holds its data. Unlike most other data - containers for plottables, it is not based on \ref QCPDataContainer. This is because the error - bars plottable is special in that it doesn't store its own key and value coordinate per error - bar. It adopts the key and value from the plottable to which the error bars shall be applied - (\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a - sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices - of the other plottable's data. - - \see QCPErrorBarsData, QCPErrorBars::setData -*/ -typedef QVector QCPErrorBarsDataContainer; - -class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QSharedPointer data READ data WRITE setData) - Q_PROPERTY(QCPAbstractPlottable* dataPlottable READ dataPlottable WRITE setDataPlottable) - Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) - Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) - Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap) - /// \endcond -public: - - /*! - Defines in which orientation the error bars shall appear. If your data needs both error - dimensions, create two \ref QCPErrorBars with different \ref ErrorType. - - \see setErrorType - */ - enum ErrorType { etKeyError ///< The errors are for the key dimension (bars appear parallel to the key axis) - ,etValueError ///< The errors are for the value dimension (bars appear parallel to the value axis) - }; - Q_ENUMS(ErrorType) - - explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis); - virtual ~QCPErrorBars(); - // getters: - QSharedPointer data() const { return mDataContainer; } - QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); } - ErrorType errorType() const { return mErrorType; } - double whiskerWidth() const { return mWhiskerWidth; } - double symbolGap() const { return mSymbolGap; } - - // setters: - void setData(QSharedPointer data); - void setData(const QVector &error); - void setData(const QVector &errorMinus, const QVector &errorPlus); - void setDataPlottable(QCPAbstractPlottable* plottable); - void setErrorType(ErrorType type); - void setWhiskerWidth(double pixels); - void setSymbolGap(double pixels); - - // non-property methods: - void addData(const QVector &error); - void addData(const QVector &errorMinus, const QVector &errorPlus); - void addData(double error); - void addData(double errorMinus, double errorPlus); - - // virtual methods of 1d plottable interface: - virtual int dataCount() const Q_DECL_OVERRIDE; - virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; - virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; - virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; - virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; - virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; - virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; - virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; - virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } - -protected: - // property members: - QSharedPointer mDataContainer; - QPointer mDataPlottable; - ErrorType mErrorType; - double mWhiskerWidth; - double mSymbolGap; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; - virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; - virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const; - void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; - double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const; - // helpers: - void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; - bool errorBarVisible(int index) const; - bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; - - friend class QCustomPlot; - friend class QCPLegend; -}; - -/* end of 'src/plottables/plottable-errorbar.h' */ - - -/* including file 'src/items/item-straightline.h', size 3117 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - /// \endcond -public: - explicit QCPItemStraightLine(QCustomPlot *parentPlot); - virtual ~QCPItemStraightLine(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const point1; - QCPItemPosition * const point2; - -protected: - // property members: - QPen mPen, mSelectedPen; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - // non-virtual methods: - QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, const QRect &rect) const; - QPen mainPen() const; -}; - -/* end of 'src/items/item-straightline.h' */ - - -/* including file 'src/items/item-line.h', size 3407 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) - Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) - /// \endcond -public: - explicit QCPItemLine(QCustomPlot *parentPlot); - virtual ~QCPItemLine(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QCPLineEnding head() const { return mHead; } - QCPLineEnding tail() const { return mTail; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setHead(const QCPLineEnding &head); - void setTail(const QCPLineEnding &tail); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const start; - QCPItemPosition * const end; - -protected: - // property members: - QPen mPen, mSelectedPen; - QCPLineEnding mHead, mTail; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - // non-virtual methods: - QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; - QPen mainPen() const; -}; - -/* end of 'src/items/item-line.h' */ - - -/* including file 'src/items/item-curve.h', size 3379 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) - Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) - /// \endcond -public: - explicit QCPItemCurve(QCustomPlot *parentPlot); - virtual ~QCPItemCurve(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QCPLineEnding head() const { return mHead; } - QCPLineEnding tail() const { return mTail; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setHead(const QCPLineEnding &head); - void setTail(const QCPLineEnding &tail); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const start; - QCPItemPosition * const startDir; - QCPItemPosition * const endDir; - QCPItemPosition * const end; - -protected: - // property members: - QPen mPen, mSelectedPen; - QCPLineEnding mHead, mTail; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen mainPen() const; -}; - -/* end of 'src/items/item-curve.h' */ - - -/* including file 'src/items/item-rect.h', size 3688 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - /// \endcond -public: - explicit QCPItemRect(QCustomPlot *parentPlot); - virtual ~QCPItemRect(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QBrush brush() const { return mBrush; } - QBrush selectedBrush() const { return mSelectedBrush; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setSelectedBrush(const QBrush &brush); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const topLeft; - QCPItemPosition * const bottomRight; - QCPItemAnchor * const top; - QCPItemAnchor * const topRight; - QCPItemAnchor * const right; - QCPItemAnchor * const bottom; - QCPItemAnchor * const bottomLeft; - QCPItemAnchor * const left; - -protected: - enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; - - // property members: - QPen mPen, mSelectedPen; - QBrush mBrush, mSelectedBrush; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen mainPen() const; - QBrush mainBrush() const; -}; - -/* end of 'src/items/item-rect.h' */ - - -/* including file 'src/items/item-text.h', size 5554 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemText : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - Q_PROPERTY(QFont font READ font WRITE setFont) - Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) - Q_PROPERTY(QString text READ text WRITE setText) - Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) - Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) - Q_PROPERTY(double rotation READ rotation WRITE setRotation) - Q_PROPERTY(QMargins padding READ padding WRITE setPadding) - /// \endcond -public: - explicit QCPItemText(QCustomPlot *parentPlot); - virtual ~QCPItemText(); - - // getters: - QColor color() const { return mColor; } - QColor selectedColor() const { return mSelectedColor; } - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QBrush brush() const { return mBrush; } - QBrush selectedBrush() const { return mSelectedBrush; } - QFont font() const { return mFont; } - QFont selectedFont() const { return mSelectedFont; } - QString text() const { return mText; } - Qt::Alignment positionAlignment() const { return mPositionAlignment; } - Qt::Alignment textAlignment() const { return mTextAlignment; } - double rotation() const { return mRotation; } - QMargins padding() const { return mPadding; } - - // setters; - void setColor(const QColor &color); - void setSelectedColor(const QColor &color); - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setSelectedBrush(const QBrush &brush); - void setFont(const QFont &font); - void setSelectedFont(const QFont &font); - void setText(const QString &text); - void setPositionAlignment(Qt::Alignment alignment); - void setTextAlignment(Qt::Alignment alignment); - void setRotation(double degrees); - void setPadding(const QMargins &padding); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const position; - QCPItemAnchor * const topLeft; - QCPItemAnchor * const top; - QCPItemAnchor * const topRight; - QCPItemAnchor * const right; - QCPItemAnchor * const bottomRight; - QCPItemAnchor * const bottom; - QCPItemAnchor * const bottomLeft; - QCPItemAnchor * const left; - -protected: - enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; - - // property members: - QColor mColor, mSelectedColor; - QPen mPen, mSelectedPen; - QBrush mBrush, mSelectedBrush; - QFont mFont, mSelectedFont; - QString mText; - Qt::Alignment mPositionAlignment; - Qt::Alignment mTextAlignment; - double mRotation; - QMargins mPadding; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; - QFont mainFont() const; - QColor mainColor() const; - QPen mainPen() const; - QBrush mainBrush() const; -}; - -/* end of 'src/items/item-text.h' */ - - -/* including file 'src/items/item-ellipse.h', size 3868 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - /// \endcond -public: - explicit QCPItemEllipse(QCustomPlot *parentPlot); - virtual ~QCPItemEllipse(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QBrush brush() const { return mBrush; } - QBrush selectedBrush() const { return mSelectedBrush; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setSelectedBrush(const QBrush &brush); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const topLeft; - QCPItemPosition * const bottomRight; - QCPItemAnchor * const topLeftRim; - QCPItemAnchor * const top; - QCPItemAnchor * const topRightRim; - QCPItemAnchor * const right; - QCPItemAnchor * const bottomRightRim; - QCPItemAnchor * const bottom; - QCPItemAnchor * const bottomLeftRim; - QCPItemAnchor * const left; - QCPItemAnchor * const center; - -protected: - enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; - - // property members: - QPen mPen, mSelectedPen; - QBrush mBrush, mSelectedBrush; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen mainPen() const; - QBrush mainBrush() const; -}; - -/* end of 'src/items/item-ellipse.h' */ - - -/* including file 'src/items/item-pixmap.h', size 4373 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) - Q_PROPERTY(bool scaled READ scaled WRITE setScaled) - Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) - Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - /// \endcond -public: - explicit QCPItemPixmap(QCustomPlot *parentPlot); - virtual ~QCPItemPixmap(); - - // getters: - QPixmap pixmap() const { return mPixmap; } - bool scaled() const { return mScaled; } - Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } - Qt::TransformationMode transformationMode() const { return mTransformationMode; } - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - - // setters; - void setPixmap(const QPixmap &pixmap); - void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const topLeft; - QCPItemPosition * const bottomRight; - QCPItemAnchor * const top; - QCPItemAnchor * const topRight; - QCPItemAnchor * const right; - QCPItemAnchor * const bottom; - QCPItemAnchor * const bottomLeft; - QCPItemAnchor * const left; - -protected: - enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; - - // property members: - QPixmap mPixmap; - QPixmap mScaledPixmap; - bool mScaled; - bool mScaledPixmapInvalidated; - Qt::AspectRatioMode mAspectRatioMode; - Qt::TransformationMode mTransformationMode; - QPen mPen, mSelectedPen; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); - QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; - QPen mainPen() const; -}; - -/* end of 'src/items/item-pixmap.h' */ - - -/* including file 'src/items/item-tracer.h', size 4762 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(QBrush brush READ brush WRITE setBrush) - Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) - Q_PROPERTY(double size READ size WRITE setSize) - Q_PROPERTY(TracerStyle style READ style WRITE setStyle) - Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) - Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) - Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) - /// \endcond -public: - /*! - The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. - - \see setStyle - */ - enum TracerStyle { tsNone ///< The tracer is not visible - ,tsPlus ///< A plus shaped crosshair with limited size - ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect - ,tsCircle ///< A circle - ,tsSquare ///< A square - }; - Q_ENUMS(TracerStyle) - - explicit QCPItemTracer(QCustomPlot *parentPlot); - QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush, const QList &alarmStatusList); - virtual ~QCPItemTracer(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - QBrush brush() const { return mBrush; } - QBrush selectedBrush() const { return mSelectedBrush; } - double size() const { return mSize; } - TracerStyle style() const { return mStyle; } - QCPGraph *graph() const { return mGraph; } - double graphKey() const { return mGraphKey; } - bool interpolating() const { return mInterpolating; } - int type() const { return mType; } - qint64 timeStamp() const { return mTimeStamp; } - QMap hidePoint() const { return m_hidePoint; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setBrush(const QBrush &brush); - void setSelectedBrush(const QBrush &brush); - void setSize(double size); - void setStyle(TracerStyle style); - void setGraph(QCPGraph *graph); - void setGraphKey(double key); - void setHidePoint(const QMultiMap &hidePoint); - void addHidePoint(const qint64 &time, const QString &tag); - void setInterpolating(bool enabled); - - void setType(const int &type); - void setTimeStamp(const qint64 &timeStamp); - void setInfo(const QStringList infos); - - void showTips(); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - // non-virtual methods: - void updatePosition(); - - QCPItemPosition * const position; - -signals: - void itemTracerHoverd(const qint64 &time, const QMap& timeTag, const QList &alarmStatusList); - -protected: - // property members: - QPen mPen, mSelectedPen; - QBrush mBrush, mSelectedBrush; - double mSize; - TracerStyle mStyle; - QCPGraph *mGraph; - QMultiMap m_hidePoint; - double mGraphKey; - bool mInterpolating; - int mType; - qint64 mTimeStamp; - QStringList m_infos; - QList m_alarmStatusList; - int hovFlag; - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - - - - virtual void mousePressEvent (QMouseEvent *event, const QVariant &details); - - virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); - - // non-virtual methods: - QPen mainPen() const; - QBrush mainBrush() const; -}; -Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle) - -/* end of 'src/items/item-tracer.h' */ - - -/* including file 'src/items/item-bracket.h', size 3969 */ -/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ - -class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem -{ - Q_OBJECT - /// \cond INCLUDE_QPROPERTIES - Q_PROPERTY(QPen pen READ pen WRITE setPen) - Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) - Q_PROPERTY(double length READ length WRITE setLength) - Q_PROPERTY(BracketStyle style READ style WRITE setStyle) - /// \endcond -public: - /*! - Defines the various visual shapes of the bracket item. The appearance can be further modified - by \ref setLength and \ref setPen. - - \see setStyle - */ - enum BracketStyle { bsSquare ///< A brace with angled edges - ,bsRound ///< A brace with round edges - ,bsCurly ///< A curly brace - ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression - }; - Q_ENUMS(BracketStyle) - - explicit QCPItemBracket(QCustomPlot *parentPlot); - virtual ~QCPItemBracket(); - - // getters: - QPen pen() const { return mPen; } - QPen selectedPen() const { return mSelectedPen; } - double length() const { return mLength; } - BracketStyle style() const { return mStyle; } - - // setters; - void setPen(const QPen &pen); - void setSelectedPen(const QPen &pen); - void setLength(double length); - void setStyle(BracketStyle style); - - // reimplemented virtual methods: - virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; - - QCPItemPosition * const left; - QCPItemPosition * const right; - QCPItemAnchor * const center; - -protected: - // property members: - enum AnchorIndex {aiCenter}; - QPen mPen, mSelectedPen; - double mLength; - BracketStyle mStyle; - - // reimplemented virtual methods: - virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; - virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; - - // non-virtual methods: - QPen mainPen() const; -}; -Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle) - -/* end of 'src/items/item-bracket.h' */ - - -#endif // QCUSTOMPLOT_H - +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2017 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 04.09.17 ** +** Version: 2.0.0 ** +****************************************************************************/ + +#ifndef QCUSTOMPLOT_H +#define QCUSTOMPLOT_H + +#include + +// some Qt version/configuration dependent macros to include or exclude certain code paths: +#ifdef QCUSTOMPLOT_USE_OPENGL +# if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# define QCP_OPENGL_PBUFFER +# else +# define QCP_OPENGL_FBO +# endif +# if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) +# define QCP_OPENGL_OFFSCREENSURFACE +# endif +#endif + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) +# define QCP_DEVICEPIXELRATIO_SUPPORTED +# if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) +# define QCP_DEVICEPIXELRATIO_FLOAT +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef QCP_OPENGL_FBO +# include +# include +# ifdef QCP_OPENGL_OFFSCREENSURFACE +# include +# else +# include +# endif +#endif +#ifdef QCP_OPENGL_PBUFFER +# include +#endif +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# include +# include +# include +# include +#else +# include +# include +# include +#endif + +class QCPPainter; +class QCustomPlot; +class QCPLayerable; +class QCPLayoutElement; +class QCPLayout; +class QCPAxis; +class QCPAxisRect; +class QCPAxisPainterPrivate; +class QCPAbstractPlottable; +class QCPGraph; +class QCPAbstractItem; +class QCPPlottableInterface1D; +class QCPLegend; +class QCPItemPosition; +class QCPLayer; +class QCPAbstractLegendItem; +class QCPSelectionRect; +class QCPColorMap; +class QCPColorScale; +class QCPBars; + +/* including file 'src/global.h', size 16225 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +// decl definitions for shared library compilation/usage: +#if defined(QCUSTOMPLOT_COMPILE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_EXPORT +#elif defined(QCUSTOMPLOT_USE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_IMPORT +#else +# define QCP_LIB_DECL +#endif + +// define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5) +#ifndef Q_DECL_OVERRIDE +# define Q_DECL_OVERRIDE +#endif + +/*! + The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot + library. + + It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. +*/ +#ifndef Q_MOC_RUN +namespace QCP { +#else +class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace + Q_GADGET + Q_ENUMS(ExportPen) + Q_ENUMS(ResolutionUnit) + Q_ENUMS(SignDomain) + Q_ENUMS(MarginSide) + Q_FLAGS(MarginSides) + Q_ENUMS(AntialiasedElement) + Q_FLAGS(AntialiasedElements) + Q_ENUMS(PlottingHint) + Q_FLAGS(PlottingHints) + Q_ENUMS(Interaction) + Q_FLAGS(Interactions) + Q_ENUMS(SelectionRectMode) + Q_ENUMS(SelectionType) +public: +#endif + +/*! + Defines the different units in which the image resolution can be specified in the export + functions. + + \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered +*/ +enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) + ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) + ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) + }; + +/*! + Defines how cosmetic pens (pens with numerical width 0) are handled during export. + + \see QCustomPlot::savePdf +*/ +enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting + ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level) + }; + +/*! + Represents negative and positive sign domain, e.g. for passing to \ref + QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. + + This is primarily needed when working with logarithmic axis scales, since only one of the sign + domains can be visible at a time. +*/ +enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero + ,sdBoth ///< Both sign domains, including zero, i.e. all numbers + ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero + }; + +/*! + Defines the sides of a rectangular entity to which margins can be applied. + + \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins +*/ +enum MarginSide { msLeft = 0x01 ///< 0x01 left margin + ,msRight = 0x02 ///< 0x02 right margin + ,msTop = 0x04 ///< 0x04 top margin + ,msBottom = 0x08 ///< 0x08 bottom margin + ,msAll = 0xFF ///< 0xFF all margins + ,msNone = 0x00 ///< 0x00 no margin + }; +Q_DECLARE_FLAGS(MarginSides, MarginSide) + +/*! + Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is + neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective + element how it is drawn. Typically it provides a \a setAntialiased function for this. + + \c AntialiasedElements is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements +*/ +enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks + ,aeGrid = 0x0002 ///< 0x0002 Grid lines + ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines + ,aeLegend = 0x0008 ///< 0x0008 Legend box + ,aeLegendItems = 0x0010 ///< 0x0010 Legend items + ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables + ,aeItems = 0x0040 ///< 0x0040 Main lines of items + ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) + ,aeFills = 0x0100 ///< 0x0100 Borders of fills (e.g. under or between graphs) + ,aeZeroLine = 0x0200 ///< 0x0200 Zero-lines, see \ref QCPGrid::setZeroLinePen + ,aeOther = 0x8000 ///< 0x8000 Other elements that don't fit into any of the existing categories + ,aeAll = 0xFFFF ///< 0xFFFF All elements + ,aeNone = 0x0000 ///< 0x0000 No elements + }; +Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) + +/*! + Defines plotting hints that control various aspects of the quality and speed of plotting. + + \see QCustomPlot::setPlottingHints +*/ +enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set + ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment + ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens. + ,phImmediateRefresh = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint. + ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). + ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. + }; +Q_DECLARE_FLAGS(PlottingHints, PlottingHint) + +/*! + Defines the mouse interactions possible with QCustomPlot. + + \c Interactions is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setInteractions +*/ +enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) + ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) + ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking + ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) + ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) + ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) + ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) + ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, other layout elements,...) + }; +Q_DECLARE_FLAGS(Interactions, Interaction) + +/*! + Defines the behaviour of the selection rect. + + \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect +*/ +enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging + ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly. + ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.) + ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction. + }; + +/*! + Defines the different ways a plottable can be selected. These images show the effect of the + different selection types, when the indicated selection rect was dragged: + +
+ + + + + + + + +
\image html selectiontype-none.png stNone\image html selectiontype-whole.png stWhole\image html selectiontype-singledata.png stSingleData\image html selectiontype-datarange.png stDataRange\image html selectiontype-multipledataranges.png stMultipleDataRanges
+
+ + \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType +*/ +enum SelectionType { stNone ///< The plottable is not selectable + ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected. + ,stSingleData ///< One individual data point can be selected at a time + ,stDataRange ///< Multiple contiguous data points (a data range) can be selected + ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected + }; + +/*! \internal + + Returns whether the specified \a value is considered an invalid data value for plottables (i.e. + is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the + compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. +*/ +inline bool isInvalidData(double value) +{ + return qIsNaN(value) || qIsInf(value); +} + +/*! \internal + \overload + + Checks two arguments instead of one. +*/ +inline bool isInvalidData(double value1, double value2) +{ + return isInvalidData(value1) || isInvalidData(value2); +} + +/*! \internal + + Sets the specified \a side of \a margins to \a value + + \see getMarginValue +*/ +inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) +{ + switch (side) + { + case QCP::msLeft: margins.setLeft(value); break; + case QCP::msRight: margins.setRight(value); break; + case QCP::msTop: margins.setTop(value); break; + case QCP::msBottom: margins.setBottom(value); break; + case QCP::msAll: margins = QMargins(value, value, value, value); break; + default: break; + } +} + +/*! \internal + + Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or + \ref QCP::msAll, returns 0. + + \see setMarginValue +*/ +inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return margins.left(); + case QCP::msRight: return margins.right(); + case QCP::msTop: return margins.top(); + case QCP::msBottom: return margins.bottom(); + default: break; + } + return 0; +} + + +extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace + +} // end of namespace QCP +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) +Q_DECLARE_METATYPE(QCP::ExportPen) +Q_DECLARE_METATYPE(QCP::ResolutionUnit) +Q_DECLARE_METATYPE(QCP::SignDomain) +Q_DECLARE_METATYPE(QCP::MarginSide) +Q_DECLARE_METATYPE(QCP::AntialiasedElement) +Q_DECLARE_METATYPE(QCP::PlottingHint) +Q_DECLARE_METATYPE(QCP::Interaction) +Q_DECLARE_METATYPE(QCP::SelectionRectMode) +Q_DECLARE_METATYPE(QCP::SelectionType) + +/* end of 'src/global.h' */ + + +/* including file 'src/vector2d.h', size 4928 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPVector2D +{ +public: + QCPVector2D(); + QCPVector2D(double x, double y); + QCPVector2D(const QPoint &point); + QCPVector2D(const QPointF &point); + + // getters: + double x() const { return mX; } + double y() const { return mY; } + double &rx() { return mX; } + double &ry() { return mY; } + + // setters: + void setX(double x) { mX = x; } + void setY(double y) { mY = y; } + + // non-virtual methods: + double length() const { return qSqrt(mX*mX+mY*mY); } + double lengthSquared() const { return mX*mX+mY*mY; } + QPoint toPoint() const { return QPoint(mX, mY); } + QPointF toPointF() const { return QPointF(mX, mY); } + + bool isNull() const { return qIsNull(mX) && qIsNull(mY); } + void normalize(); + QCPVector2D normalized() const; + QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); } + double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; } + double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; + double distanceSquaredToLine(const QLineF &line) const; + double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; + + QCPVector2D &operator*=(double factor); + QCPVector2D &operator/=(double divisor); + QCPVector2D &operator+=(const QCPVector2D &vector); + QCPVector2D &operator-=(const QCPVector2D &vector); + +private: + // property members: + double mX, mY; + + friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); + friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); + friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); + friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec); +}; +Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE); + +inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); } +inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); } + +/*! \relates QCPVector2D + + Prints \a vec in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPVector2D &vec) +{ + d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")"; + return d.space(); +} + +/* end of 'src/vector2d.h' */ + + +/* including file 'src/painter.h', size 4035 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPPainter : public QPainter +{ + Q_GADGET +public: + /*! + Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, + depending on whether they are wanted on the respective output device. + */ + enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices + ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. + ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels + ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) + }; + Q_ENUMS(PainterMode) + Q_FLAGS(PainterModes) + Q_DECLARE_FLAGS(PainterModes, PainterMode) + + QCPPainter(); + explicit QCPPainter(QPaintDevice *device); + + // getters: + bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } + PainterModes modes() const { return mModes; } + + // setters: + void setAntialiasing(bool enabled); + void setMode(PainterMode mode, bool enabled=true); + void setModes(PainterModes modes); + + // methods hiding non-virtual base class functions (QPainter bug workarounds): + bool begin(QPaintDevice *device); + void setPen(const QPen &pen); + void setPen(const QColor &color); + void setPen(Qt::PenStyle penStyle); + void drawLine(const QLineF &line); + void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} + void save(); + void restore(); + + // non-virtual methods: + void makeNonCosmetic(); + +protected: + // property members: + PainterModes mModes; + bool mIsAntialiasing; + + // non-property members: + QStack mAntialiasingStack; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) +Q_DECLARE_METATYPE(QCPPainter::PainterMode) + +/* end of 'src/painter.h' */ + + +/* including file 'src/paintbuffer.h', size 4958 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAbstractPaintBuffer +{ +public: + explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); + virtual ~QCPAbstractPaintBuffer(); + + // getters: + QSize size() const { return mSize; } + bool invalidated() const { return mInvalidated; } + double devicePixelRatio() const { return mDevicePixelRatio; } + + // setters: + void setSize(const QSize &size); + void setInvalidated(bool invalidated=true); + void setDevicePixelRatio(double ratio); + + // introduced virtual methods: + virtual QCPPainter *startPainting() = 0; + virtual void donePainting() {} + virtual void draw(QCPPainter *painter) const = 0; + virtual void clear(const QColor &color) = 0; + +protected: + // property members: + QSize mSize; + double mDevicePixelRatio; + + // non-property members: + bool mInvalidated; + + // introduced virtual methods: + virtual void reallocateBuffer() = 0; +}; + + +class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); + virtual ~QCPPaintBufferPixmap(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QPixmap mBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; + + +#ifdef QCP_OPENGL_PBUFFER +class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); + virtual ~QCPPaintBufferGlPbuffer(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QGLPixelBuffer *mGlPBuffer; + int mMultisamples; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice); + virtual ~QCPPaintBufferGlFbo(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void donePainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QWeakPointer mGlContext; + QWeakPointer mGlPaintDevice; + QOpenGLFramebufferObject *mGlFrameBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_FBO + +/* end of 'src/paintbuffer.h' */ + + +/* including file 'src/layer.h', size 6885 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPLayer : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(int index READ index) + Q_PROPERTY(QList children READ children) + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(LayerMode mode READ mode WRITE setMode) + /// \endcond +public: + + /*! + Defines the different rendering modes of a layer. Depending on the mode, certain layers can be + replotted individually, without the need to replot (possibly complex) layerables on other + layers. + + \see setMode + */ + enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. + ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). + }; + Q_ENUMS(LayerMode) + + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); + virtual ~QCPLayer(); + + // getters: + QCustomPlot *parentPlot() const { return mParentPlot; } + QString name() const { return mName; } + int index() const { return mIndex; } + QList children() const { return mChildren; } + bool visible() const { return mVisible; } + LayerMode mode() const { return mMode; } + + // setters: + void setVisible(bool visible); + void setMode(LayerMode mode); + + // non-virtual methods: + void replot(); + +protected: + // property members: + QCustomPlot *mParentPlot; + QString mName; + int mIndex; + QList mChildren; + bool mVisible; + LayerMode mMode; + + // non-property members: + QWeakPointer mPaintBuffer; + + // non-virtual methods: + void draw(QCPPainter *painter); + void drawToPaintBuffer(); + void addChild(QCPLayerable *layerable, bool prepend); + void removeChild(QCPLayerable *layerable); + +private: + Q_DISABLE_COPY(QCPLayer) + + friend class QCustomPlot; + friend class QCPLayerable; +}; +Q_DECLARE_METATYPE(QCPLayer::LayerMode) + +class QCP_LIB_DECL QCPLayerable : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) + Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) + Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) + /// \endcond +public: + QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); + virtual ~QCPLayerable(); + + // getters: + bool visible() const { return mVisible; } + QCustomPlot *parentPlot() const { return mParentPlot; } + QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } + QCPLayer *layer() const { return mLayer; } + bool antialiased() const { return mAntialiased; } + + // setters: + void setVisible(bool on); + Q_SLOT bool setLayer(QCPLayer *layer); + bool setLayer(const QString &layerName); + void setAntialiased(bool enabled); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-property methods: + bool realVisibility() const; + +signals: + void layerChanged(QCPLayer *newLayer); + +protected: + // property members: + bool mVisible; + QCustomPlot *mParentPlot; + QPointer mParentLayerable; + QCPLayer *mLayer; + bool mAntialiased; + + // introduced virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; + virtual void draw(QCPPainter *painter) = 0; + // selection events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + // low-level mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); + virtual void wheelEvent(QWheelEvent *event); + + // non-property methods: + void initializeParentPlot(QCustomPlot *parentPlot); + void setParentLayerable(QCPLayerable* parentLayerable); + bool moveToLayer(QCPLayer *layer, bool prepend); + void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; + +private: + Q_DISABLE_COPY(QCPLayerable) + + friend class QCustomPlot; + friend class QCPLayer; + friend class QCPAxisRect; +}; + +/* end of 'src/layer.h' */ + + +/* including file 'src/axis/range.h', size 5280 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPRange +{ +public: + double lower, upper; + + QCPRange(); + QCPRange(double lower, double upper); + + bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } + bool operator!=(const QCPRange& other) const { return !(*this == other); } + + QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } + QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } + QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } + QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } + friend inline const QCPRange operator+(const QCPRange&, double); + friend inline const QCPRange operator+(double, const QCPRange&); + friend inline const QCPRange operator-(const QCPRange& range, double value); + friend inline const QCPRange operator*(const QCPRange& range, double value); + friend inline const QCPRange operator*(double value, const QCPRange& range); + friend inline const QCPRange operator/(const QCPRange& range, double value); + + double size() const { return upper-lower; } + double center() const { return (upper+lower)*0.5; } + void normalize() { if (lower > upper) qSwap(lower, upper); } + void expand(const QCPRange &otherRange); + void expand(double includeCoord); + QCPRange expanded(const QCPRange &otherRange) const; + QCPRange expanded(double includeCoord) const; + QCPRange bounded(double lowerBound, double upperBound) const; + QCPRange sanitizedForLogScale() const; + QCPRange sanitizedForLinScale() const; + bool contains(double value) const { return value >= lower && value <= upper; } + + static bool validRange(double lower, double upper); + static bool validRange(const QCPRange &range); + static const double minRange; + static const double maxRange; + +}; +Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); + +/*! \relates QCPRange + + Prints \a range in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPRange &range) +{ + d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")"; + return d.space(); +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(const QCPRange& range, double value) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(double value, const QCPRange& range) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Subtracts \a value from both boundaries of the range. +*/ +inline const QCPRange operator-(const QCPRange& range, double value) +{ + QCPRange result(range); + result -= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(const QCPRange& range, double value) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(double value, const QCPRange& range) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Divides both boundaries of the range by \a value. +*/ +inline const QCPRange operator/(const QCPRange& range, double value) +{ + QCPRange result(range); + result /= value; + return result; +} + +/* end of 'src/axis/range.h' */ + + +/* including file 'src/selection.h', size 8579 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPDataRange +{ +public: + QCPDataRange(); + QCPDataRange(int begin, int end); + + bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; } + bool operator!=(const QCPDataRange& other) const { return !(*this == other); } + + // getters: + int begin() const { return mBegin; } + int end() const { return mEnd; } + int size() const { return mEnd-mBegin; } + int length() const { return size(); } + + // setters: + void setBegin(int begin) { mBegin = begin; } + void setEnd(int end) { mEnd = end; } + + // non-property methods: + bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } + bool isEmpty() const { return length() == 0; } + QCPDataRange bounded(const QCPDataRange &other) const; + QCPDataRange expanded(const QCPDataRange &other) const; + QCPDataRange intersection(const QCPDataRange &other) const; + QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); } + bool intersects(const QCPDataRange &other) const; + bool contains(const QCPDataRange &other) const; + +private: + // property members: + int mBegin, mEnd; + +}; +Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPDataSelection +{ +public: + explicit QCPDataSelection(); + explicit QCPDataSelection(const QCPDataRange &range); + + bool operator==(const QCPDataSelection& other) const; + bool operator!=(const QCPDataSelection& other) const { return !(*this == other); } + QCPDataSelection &operator+=(const QCPDataSelection& other); + QCPDataSelection &operator+=(const QCPDataRange& other); + QCPDataSelection &operator-=(const QCPDataSelection& other); + QCPDataSelection &operator-=(const QCPDataRange& other); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b); + + // getters: + int dataRangeCount() const { return mDataRanges.size(); } + int dataPointCount() const; + QCPDataRange dataRange(int index=0) const; + QList dataRanges() const { return mDataRanges; } + QCPDataRange span() const; + + // non-property methods: + void addDataRange(const QCPDataRange &dataRange, bool simplify=true); + void clear(); + bool isEmpty() const { return mDataRanges.isEmpty(); } + void simplify(); + void enforceType(QCP::SelectionType type); + bool contains(const QCPDataSelection &other) const; + QCPDataSelection intersection(const QCPDataRange &other) const; + QCPDataSelection intersection(const QCPDataSelection &other) const; + QCPDataSelection inverse(const QCPDataRange &outerRange) const; + +private: + // property members: + QList mDataRanges; + + inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); } +}; +Q_DECLARE_METATYPE(QCPDataSelection) + + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! \relates QCPDataRange + + Prints \a dataRange in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange) +{ + d.nospace() << "[" << dataRange.begin() << ".." << dataRange.end()-1 << "]"; + return d.space(); +} + +/*! \relates QCPDataSelection + + Prints \a selection in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataSelection &selection) +{ + d.nospace() << "QCPDataSelection("; + for (int i=0; i elements(QCP::MarginSide side) const { return mChildren.value(side); } + bool isEmpty() const; + void clear(); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + QHash > mChildren; + + // introduced virtual methods: + virtual int commonMargin(QCP::MarginSide side) const; + + // non-virtual methods: + void addChild(QCP::MarginSide side, QCPLayoutElement *element); + void removeChild(QCP::MarginSide side, QCPLayoutElement *element); + +private: + Q_DISABLE_COPY(QCPMarginGroup) + + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLayout* layout READ layout) + Q_PROPERTY(QRect rect READ rect) + Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) + Q_PROPERTY(QMargins margins READ margins WRITE setMargins) + Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) + Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) + Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) + Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect) + /// \endcond +public: + /*! + Defines the phases of the update process, that happens just before a replot. At each phase, + \ref update is called with the according UpdatePhase value. + */ + enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout + ,upMargins ///< Phase in which the margins are calculated and set + ,upLayout ///< Final phase in which the layout system places the rects of the elements + }; + Q_ENUMS(UpdatePhase) + + /*! + Defines to which rect of a layout element the size constraints that can be set via \ref + setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the + margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect) + does not. + + \see setSizeConstraintRect + */ + enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect + , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins + }; + Q_ENUMS(SizeConstraintRect) + + explicit QCPLayoutElement(QCustomPlot *parentPlot=0); + virtual ~QCPLayoutElement(); + + // getters: + QCPLayout *layout() const { return mParentLayout; } + QRect rect() const { return mRect; } + QRect outerRect() const { return mOuterRect; } + QMargins margins() const { return mMargins; } + QMargins minimumMargins() const { return mMinimumMargins; } + QCP::MarginSides autoMargins() const { return mAutoMargins; } + QSize minimumSize() const { return mMinimumSize; } + QSize maximumSize() const { return mMaximumSize; } + SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; } + QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } + QHash marginGroups() const { return mMarginGroups; } + + // setters: + void setOuterRect(const QRect &rect); + void setMargins(const QMargins &margins); + void setMinimumMargins(const QMargins &margins); + void setAutoMargins(QCP::MarginSides sides); + void setMinimumSize(const QSize &size); + void setMinimumSize(int width, int height); + void setMaximumSize(const QSize &size); + void setMaximumSize(int width, int height); + void setSizeConstraintRect(SizeConstraintRect constraintRect); + void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); + + // introduced virtual methods: + virtual void update(UpdatePhase phase); + virtual QSize minimumOuterSizeHint() const; + virtual QSize maximumOuterSizeHint() const; + virtual QList elements(bool recursive) const; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPLayout *mParentLayout; + QSize mMinimumSize, mMaximumSize; + SizeConstraintRect mSizeConstraintRect; + QRect mRect, mOuterRect; + QMargins mMargins, mMinimumMargins; + QCP::MarginSides mAutoMargins; + QHash mMarginGroups; + + // introduced virtual methods: + virtual int calculateAutoMargin(QCP::MarginSide side); + virtual void layoutChanged(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPLayoutElement) + + friend class QCustomPlot; + friend class QCPLayout; + friend class QCPMarginGroup; +}; +Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase) + + +class QCP_LIB_DECL QCPLayout : public QCPLayoutElement +{ + Q_OBJECT +public: + explicit QCPLayout(); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual int elementCount() const = 0; + virtual QCPLayoutElement* elementAt(int index) const = 0; + virtual QCPLayoutElement* takeAt(int index) = 0; + virtual bool take(QCPLayoutElement* element) = 0; + virtual void simplify(); + + // non-virtual methods: + bool removeAt(int index); + bool remove(QCPLayoutElement* element); + void clear(); + +protected: + // introduced virtual methods: + virtual void updateLayout(); + + // non-virtual methods: + void sizeConstraintsChanged() const; + void adoptElement(QCPLayoutElement *el); + void releaseElement(QCPLayoutElement *el); + QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; + static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el); + static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el); + +private: + Q_DISABLE_COPY(QCPLayout) + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(int rowCount READ rowCount) + Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) + Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) + Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) + Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) + Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder) + Q_PROPERTY(int wrap READ wrap WRITE setWrap) + /// \endcond +public: + + /*! + Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). + The column/row at which wrapping into the next row/column occurs can be specified with \ref + setWrap. + + \see setFillOrder + */ + enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap. + ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. + }; + Q_ENUMS(FillOrder) + + explicit QCPLayoutGrid(); + virtual ~QCPLayoutGrid(); + + // getters: + int rowCount() const { return mElements.size(); } + int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } + QList columnStretchFactors() const { return mColumnStretchFactors; } + QList rowStretchFactors() const { return mRowStretchFactors; } + int columnSpacing() const { return mColumnSpacing; } + int rowSpacing() const { return mRowSpacing; } + int wrap() const { return mWrap; } + FillOrder fillOrder() const { return mFillOrder; } + + // setters: + void setColumnStretchFactor(int column, double factor); + void setColumnStretchFactors(const QList &factors); + void setRowStretchFactor(int row, double factor); + void setRowStretchFactors(const QList &factors); + void setColumnSpacing(int pixels); + void setRowSpacing(int pixels); + void setWrap(int count); + void setFillOrder(FillOrder order, bool rearrange=true); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); } + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPLayoutElement *element(int row, int column) const; + bool addElement(int row, int column, QCPLayoutElement *element); + bool addElement(QCPLayoutElement *element); + bool hasElement(int row, int column); + void expandTo(int newRowCount, int newColumnCount); + void insertRow(int newIndex); + void insertColumn(int newIndex); + int rowColToIndex(int row, int column) const; + void indexToRowCol(int index, int &row, int &column) const; + +protected: + // property members: + QList > mElements; + QList mColumnStretchFactors; + QList mRowStretchFactors; + int mColumnSpacing, mRowSpacing; + int mWrap; + FillOrder mFillOrder; + + // non-virtual methods: + void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; + void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; + +private: + Q_DISABLE_COPY(QCPLayoutGrid) +}; +Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder) + + +class QCP_LIB_DECL QCPLayoutInset : public QCPLayout +{ + Q_OBJECT +public: + /*! + Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. + */ + enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect + ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment + }; + Q_ENUMS(InsetPlacement) + + explicit QCPLayoutInset(); + virtual ~QCPLayoutInset(); + + // getters: + InsetPlacement insetPlacement(int index) const; + Qt::Alignment insetAlignment(int index) const; + QRectF insetRect(int index) const; + + // setters: + void setInsetPlacement(int index, InsetPlacement placement); + void setInsetAlignment(int index, Qt::Alignment alignment); + void setInsetRect(int index, const QRectF &rect); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE {} + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void addElement(QCPLayoutElement *element, Qt::Alignment alignment); + void addElement(QCPLayoutElement *element, const QRectF &rect); + +protected: + // property members: + QList mElements; + QList mInsetPlacement; + QList mInsetAlignment; + QList mInsetRect; + +private: + Q_DISABLE_COPY(QCPLayoutInset) +}; +Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement) + +/* end of 'src/layout.h' */ + + +/* including file 'src/lineending.h', size 4426 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPLineEnding +{ + Q_GADGET +public: + /*! + Defines the type of ending decoration for line-like items, e.g. an arrow. + + \image html QCPLineEnding.png + + The width and length of these decorations can be controlled with the functions \ref setWidth + and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only + support a width, the length property is ignored. + + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding + */ + enum EndingStyle { esNone ///< No ending decoration + ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) + ,esSpikeArrow ///< A filled arrow head with an indented back + ,esLineArrow ///< A non-filled arrow head with open back + ,esDisc ///< A filled circle + ,esSquare ///< A filled square + ,esDiamond ///< A filled diamond (45 degrees rotated square) + ,esBar ///< A bar perpendicular to the line + ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) + ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) + }; + Q_ENUMS(EndingStyle) + + QCPLineEnding(); + QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); + + // getters: + EndingStyle style() const { return mStyle; } + double width() const { return mWidth; } + double length() const { return mLength; } + bool inverted() const { return mInverted; } + + // setters: + void setStyle(EndingStyle style); + void setWidth(double width); + void setLength(double length); + void setInverted(bool inverted); + + // non-property methods: + double boundingDistance() const; + double realLength() const; + void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; + void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; + +protected: + // property members: + EndingStyle mStyle; + double mWidth, mLength; + bool mInverted; +}; +Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); +Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle) + +/* end of 'src/lineending.h' */ + + +/* including file 'src/axis/axisticker.h', size 4177 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the strategies that the axis ticker may follow when choosing the size of the tick step. + + \see setTickStepStrategy + */ + enum TickStepStrategy + { + tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount) + ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count + }; + Q_ENUMS(TickStepStrategy) + + QCPAxisTicker(); + virtual ~QCPAxisTicker(); + + // getters: + TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } + int tickCount() const { return mTickCount; } + double tickOrigin() const { return mTickOrigin; } + + // setters: + void setTickStepStrategy(TickStepStrategy strategy); + void setTickCount(int count); + void setTickOrigin(double origin); + + // introduced virtual methods: + virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); + +protected: + // property members: + TickStepStrategy mTickStepStrategy; + int mTickCount; + double mTickOrigin; + + // introduced virtual methods: + virtual double getTickStep(const QCPRange &range); + virtual int getSubTickCount(double tickStep); + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision); + virtual QVector createTickVector(double tickStep, const QCPRange &range); + virtual QVector createSubTickVector(int subTickCount, const QVector &ticks); + virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision); + + // non-virtual methods: + void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const; + double pickClosest(double target, const QVector &candidates) const; + double getMantissa(double input, double *magnitude=0) const; + double cleanMantissa(double input) const; +}; +Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) +Q_DECLARE_METATYPE(QSharedPointer) + +/* end of 'src/axis/axisticker.h' */ + + +/* including file 'src/axis/axistickerdatetime.h', size 3289 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker +{ +public: + QCPAxisTickerDateTime(); + + // getters: + QString dateTimeFormat() const { return mDateTimeFormat; } + Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } + + // setters: + void setDateTimeFormat(const QString &format); + void setDateTimeSpec(Qt::TimeSpec spec); + void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) + void setTickOrigin(const QDateTime &origin); + + // static methods: + static QDateTime keyToDateTime(double key); + static double dateTimeToKey(const QDateTime dateTime); + static double dateTimeToKey(const QDate date); + +protected: + // property members: + QString mDateTimeFormat; + Qt::TimeSpec mDateTimeSpec; + + // non-property members: + enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerdatetime.h' */ + + +/* including file 'src/axis/axistickertime.h', size 3542 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the logical units in which fractions of time spans can be expressed. + + \see setFieldWidth, setTimeFormat + */ + enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) + ,tuSeconds ///< Seconds (%%s in \ref setTimeFormat) + ,tuMinutes ///< Minutes (%%m in \ref setTimeFormat) + ,tuHours ///< Hours (%%h in \ref setTimeFormat) + ,tuDays ///< Days (%%d in \ref setTimeFormat) + }; + Q_ENUMS(TimeUnit) + + QCPAxisTickerTime(); + + // getters: + QString timeFormat() const { return mTimeFormat; } + int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } + + // setters: + void setTimeFormat(const QString &format); + void setFieldWidth(TimeUnit unit, int width); + +protected: + // property members: + QString mTimeFormat; + QHash mFieldWidth; + + // non-property members: + TimeUnit mSmallestUnit, mBiggestUnit; + QHash mFormatPattern; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void replaceUnit(QString &text, TimeUnit unit, int value) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit) + +/* end of 'src/axis/axistickertime.h' */ + + +/* including file 'src/axis/axistickerfixed.h', size 3308 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to + control the number of ticks in the axis range. + + \see setScaleStrategy + */ + enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out. + ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount. + ,ssPowers ///< An integer power of the specified tick step is allowed. + }; + Q_ENUMS(ScaleStrategy) + + QCPAxisTickerFixed(); + + // getters: + double tickStep() const { return mTickStep; } + ScaleStrategy scaleStrategy() const { return mScaleStrategy; } + + // setters: + void setTickStep(double step); + void setScaleStrategy(ScaleStrategy strategy); + +protected: + // property members: + double mTickStep; + ScaleStrategy mScaleStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; +}; +Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy) + +/* end of 'src/axis/axistickerfixed.h' */ + + +/* including file 'src/axis/axistickertext.h', size 3085 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker +{ +public: + QCPAxisTickerText(); + + // getters: + QMap &ticks() { return mTicks; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setTicks(const QMap &ticks); + void setTicks(const QVector &positions, const QVector labels); + void setSubTickCount(int subTicks); + + // non-virtual methods: + void clear(); + void addTick(double position, QString label); + void addTicks(const QMap &ticks); + void addTicks(const QVector &positions, const QVector &labels); + +protected: + // property members: + QMap mTicks; + int mSubTickCount; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; + +}; + +/* end of 'src/axis/axistickertext.h' */ + + +/* including file 'src/axis/axistickerpi.h', size 3911 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how fractions should be displayed in tick labels. + + \see setFractionStyle + */ + enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125". + ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8" + ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol. + }; + Q_ENUMS(FractionStyle) + + QCPAxisTickerPi(); + + // getters: + QString piSymbol() const { return mPiSymbol; } + double piValue() const { return mPiValue; } + bool periodicity() const { return mPeriodicity; } + FractionStyle fractionStyle() const { return mFractionStyle; } + + // setters: + void setPiSymbol(QString symbol); + void setPiValue(double pi); + void setPeriodicity(int multiplesOfPi); + void setFractionStyle(FractionStyle style); + +protected: + // property members: + QString mPiSymbol; + double mPiValue; + int mPeriodicity; + FractionStyle mFractionStyle; + + // non-property members: + double mPiTickStep; // size of one tick step in units of mPiValue + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void simplifyFraction(int &numerator, int &denominator) const; + QString fractionToString(int numerator, int denominator) const; + QString unicodeFraction(int numerator, int denominator) const; + QString unicodeSuperscript(int number) const; + QString unicodeSubscript(int number) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle) + +/* end of 'src/axis/axistickerpi.h' */ + + +/* including file 'src/axis/axistickerlog.h', size 2663 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker +{ +public: + QCPAxisTickerLog(); + + // getters: + double logBase() const { return mLogBase; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setLogBase(double base); + void setSubTickCount(int subTicks); + +protected: + // property members: + double mLogBase; + int mSubTickCount; + + // non-property members: + double mLogBaseLnInv; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerlog.h' */ + + +/* including file 'src/axis/axis.h', size 20634 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPGrid :public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) + Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) + Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) + Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) + /// \endcond +public: + explicit QCPGrid(QCPAxis *parentAxis); + + // getters: + bool subGridVisible() const { return mSubGridVisible; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen pen() const { return mPen; } + QPen subGridPen() const { return mSubGridPen; } + QPen zeroLinePen() const { return mZeroLinePen; } + + // setters: + void setSubGridVisible(bool visible); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + +protected: + // property members: + bool mSubGridVisible; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mPen, mSubGridPen, mZeroLinePen; + + // non-property members: + QCPAxis *mParentAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawGridLines(QCPPainter *painter) const; + void drawSubGridLines(QCPPainter *painter) const; + + friend class QCPAxis; +}; + + +class QCP_LIB_DECL QCPAxis : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(AxisType axisType READ axisType) + Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) + Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) + Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) + Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) + Q_PROPERTY(QSharedPointer ticker READ ticker WRITE setTicker) + Q_PROPERTY(bool ticks READ ticks WRITE setTicks) + Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) + Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) + Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) + Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) + Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) + Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) + Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) + Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) + Q_PROPERTY(QVector tickVector READ tickVector) + Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels) + Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) + Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) + Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks) + Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) + Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) + Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) + Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) + Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) + Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) + Q_PROPERTY(int padding READ padding WRITE setPadding) + Q_PROPERTY(int offset READ offset WRITE setOffset) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) + Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) + Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) + Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) + Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) + Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) + Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) + Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) + Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) + Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) + Q_PROPERTY(QCPGrid* grid READ grid) + /// \endcond +public: + /*! + Defines at which side of the axis rect the axis will appear. This also affects how the tick + marks are drawn, on which side the labels are placed etc. + */ + enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect + ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect + ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect + ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect + }; + Q_ENUMS(AxisType) + Q_FLAGS(AxisTypes) + Q_DECLARE_FLAGS(AxisTypes, AxisType) + /*! + Defines on which side of the axis the tick labels (numbers) shall appear. + + \see setTickLabelSide + */ + enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect + ,lsOutside ///< Tick labels will be displayed outside the axis rect + }; + Q_ENUMS(LabelSide) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPAxis(QCPAxisRect *parent, AxisType type); + virtual ~QCPAxis(); + + // getters: + AxisType axisType() const { return mAxisType; } + QCPAxisRect *axisRect() const { return mAxisRect; } + ScaleType scaleType() const { return mScaleType; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + QSharedPointer ticker() const { return mTicker; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const; + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const; + LabelSide tickLabelSide() const; + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const; + int tickLengthOut() const; + bool subTicks() const { return mSubTicks; } + int subTickLengthIn() const; + int subTickLengthOut() const; + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const; + int padding() const { return mPadding; } + int offset() const; + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + QCPLineEnding lowerEnding() const; + QCPLineEnding upperEnding() const; + QCPGrid *grid() const { return mGrid; } + + // setters: + Q_SLOT void setScaleType(QCPAxis::ScaleType type); + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setTicker(QSharedPointer ticker); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelSide(LabelSide side); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTicks(bool show); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setPadding(int padding); + void setOffset(int offset); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); + void setLowerEnding(const QCPLineEnding &ending); + void setUpperEnding(const QCPLineEnding &ending); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-property methods: + Qt::Orientation orientation() const { return mOrientation; } + int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; } + void moveRange(double diff); + void scaleRange(double factor); + void scaleRange(double factor, double center); + void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); + void rescale(bool onlyVisiblePlottables=false); + double pixelToCoord(double value) const; + double coordToPixel(double value) const; + SelectablePart getPartAt(const QPointF &pos) const; + QList plottables() const; + QList graphs() const; + QList items() const; + + static AxisType marginSideToAxisType(QCP::MarginSide side); + static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } + static AxisType opposite(AxisType type); + +signals: + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void scaleTypeChanged(QCPAxis::ScaleType scaleType); + void selectionChanged(const QCPAxis::SelectableParts &parts); + void selectableChanged(const QCPAxis::SelectableParts &parts); + +protected: + // property members: + // axis base: + AxisType mAxisType; + QCPAxisRect *mAxisRect; + //int mOffset; // in QCPAxisPainter + int mPadding; + Qt::Orientation mOrientation; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter + // axis label: + //int mLabelPadding; // in QCPAxisPainter + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; // in QCPAxisPainter + bool mTickLabels; + //double mTickLabelRotation; // in QCPAxisPainter + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + //bool mNumberMultiplyCross; // QCPAxisPainter + // ticks and subticks: + bool mTicks; + bool mSubTicks; + //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + ScaleType mScaleType; + + // non-property members: + QCPGrid *mGrid; + QCPAxisPainterPrivate *mAxisPainter; + QSharedPointer mTicker; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mSubTickVector; + bool mCachedMarginValid; + int mCachedMargin; + bool mDragging; + QCPRange mDragStartRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + + // introduced virtual methods: + virtual int calculateMargin(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + // mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); + virtual void wheelEvent(QWheelEvent *event); + + // non-virtual methods: + void setupTickVectors(); + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPAxis) + + friend class QCustomPlot; + friend class QCPGrid; + friend class QCPAxisRect; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) +Q_DECLARE_METATYPE(QCPAxis::AxisType) +Q_DECLARE_METATYPE(QCPAxis::LabelSide) +Q_DECLARE_METATYPE(QCPAxis::ScaleType) +Q_DECLARE_METATYPE(QCPAxis::SelectablePart) + + +class QCPAxisPainterPrivate +{ +public: + explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); + virtual ~QCPAxisPainterPrivate(); + + virtual void draw(QCPPainter *painter); + virtual int size() const; + void clearCache(); + + QRect axisSelectionBox() const { return mAxisSelectionBox; } + QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } + QRect labelSelectionBox() const { return mLabelSelectionBox; } + + // public property members: + QCPAxis::AxisType type; + QPen basePen; + QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters + int labelPadding; // directly accessed by QCPAxis setters/getters + QFont labelFont; + QColor labelColor; + QString label; + int tickLabelPadding; // directly accessed by QCPAxis setters/getters + double tickLabelRotation; // directly accessed by QCPAxis setters/getters + QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters + bool substituteExponent; + bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters + int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters + QPen tickPen, subTickPen; + QFont tickLabelFont; + QColor tickLabelColor; + QRect axisRect, viewportRect; + double offset; // directly accessed by QCPAxis setters/getters + bool abbreviateDecimalPowers; + bool reversedEndings; + + QVector subTickPositions; + QVector tickPositions; + QVector tickLabels; + +protected: + struct CachedLabel + { + QPointF offset; + QPixmap pixmap; + }; + struct TickLabelData + { + QString basePart, expPart, suffixPart; + QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds; + QFont baseFont, expFont; + }; + QCustomPlot *mParentPlot; + QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters + QCache mLabelCache; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + + virtual QByteArray generateLabelParameterHash() const; + + virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); + virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; + virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; + virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; + virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; +}; + +/* end of 'src/axis/axis.h' */ + + +/* including file 'src/scatterstyle.h', size 7275 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPScatterStyle +{ + Q_GADGET +public: + /*! + Represents the various properties of a scatter style instance. For example, this enum is used + to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when + highlighting selected data points. + + Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref + setFromOther. + */ + enum ScatterProperty { spNone = 0x00 ///< 0x00 None + ,spPen = 0x01 ///< 0x01 The pen property, see \ref setPen + ,spBrush = 0x02 ///< 0x02 The brush property, see \ref setBrush + ,spSize = 0x04 ///< 0x04 The size property, see \ref setSize + ,spShape = 0x08 ///< 0x08 The shape property, see \ref setShape + ,spAll = 0xFF ///< 0xFF All properties + }; + Q_ENUMS(ScatterProperty) + Q_FLAGS(ScatterProperties) + Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty) + + /*! + Defines the shape used for scatter points. + + On plottables/items that draw scatters, the sizes of these visualizations (with exception of + \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are + drawn with the pen and brush specified with \ref setPen and \ref setBrush. + */ + enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) + ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) + ,ssCross ///< \enumimage{ssCross.png} a cross + ,ssPlus ///< \enumimage{ssPlus.png} a plus + ,ssCircle ///< \enumimage{ssCircle.png} a circle + ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) + ,ssSquare ///< \enumimage{ssSquare.png} a square + ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond + ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus + ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline + ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner + ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside + ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside + ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside + ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside + ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines + ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates + ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) + }; + Q_ENUMS(ScatterShape) + + QCPScatterStyle(); + QCPScatterStyle(ScatterShape shape, double size=6); + QCPScatterStyle(ScatterShape shape, const QColor &color, double size); + QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); + QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); + QCPScatterStyle(const QPixmap &pixmap); + QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); + + // getters: + double size() const { return mSize; } + ScatterShape shape() const { return mShape; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QPixmap pixmap() const { return mPixmap; } + QPainterPath customPath() const { return mCustomPath; } + + // setters: + void setFromOther(const QCPScatterStyle &other, ScatterProperties properties); + void setSize(double size); + void setShape(ScatterShape shape); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setPixmap(const QPixmap &pixmap); + void setCustomPath(const QPainterPath &customPath); + + // non-property methods: + bool isNone() const { return mShape == ssNone; } + bool isPenDefined() const { return mPenDefined; } + void undefinePen(); + void applyTo(QCPPainter *painter, const QPen &defaultPen) const; + void drawShape(QCPPainter *painter, const QPointF &pos) const; + void drawShape(QCPPainter *painter, double x, double y) const; + +protected: + // property members: + double mSize; + ScatterShape mShape; + QPen mPen; + QBrush mBrush; + QPixmap mPixmap; + QPainterPath mCustomPath; + + // non-property members: + bool mPenDefined; +}; +Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) + +/* end of 'src/scatterstyle.h' */ + + +/* including file 'src/datacontainer.h', size 4596 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +/*! \relates QCPDataContainer + Returns whether the sort key of \a a is less than the sort key of \a b. + + \see QCPDataContainer::sort +*/ +template +inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); } + +template +class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below) +{ +public: + typedef typename QVector::const_iterator const_iterator; + typedef typename QVector::const_reverse_iterator const_reverse_iterator; + typedef typename QVector::iterator iterator; + + QCPDataContainer(); + + // pointer to data + QVector * data() { return &mData; } + + // getters: + int size() const { return mData.size()-mPreallocSize; } + bool isEmpty() const { return size() == 0; } + bool autoSqueeze() const { return mAutoSqueeze; } + + // setters: + void setAutoSqueeze(bool enabled); + + // non-virtual methods: + void set(const QCPDataContainer &data); + void set(const QVector &data, bool alreadySorted=false); + void add(const QCPDataContainer &data); + void add(const QVector &data, bool alreadySorted=false); + void add(const DataType &data); + void removeBefore(double sortKey); + void removeAfter(double sortKey); + void remove(double sortKeyFrom, double sortKeyTo); + void remove(double sortKey); + void clear(); + void sort(); + void squeeze(bool preAllocation=true, bool postAllocation=true); + + const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; } + const_iterator constEnd() const { return mData.constEnd(); } + iterator begin() { return mData.begin()+mPreallocSize; } + iterator end() { return mData.end(); } + const_iterator findBegin(double sortKey, bool expandedRange=true) const; + const_iterator findEnd(double sortKey, bool expandedRange=true) const; + const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); } + QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth); + QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()); + QCPDataRange dataRange() const { return QCPDataRange(0, size()); } + void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const; + +protected: + // property members: + bool mAutoSqueeze; + + // non-property memebers: + QVector mData; + int mPreallocSize; + int mPreallocIteration; + + // non-virtual methods: + void preallocateGrow(int minimumPreallocSize); + void performAutoSqueeze(); +}; + +// include implementation in header since it is a class template: + +/* including file 'src/datacontainer.cpp', size 31349 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataContainer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataContainer + \brief The generic data container for one-dimensional plottables + + This class template provides a fast container for data storage of one-dimensional data. The data + type is specified as template parameter (called \a DataType in the following) and must provide + some methods as described in the \ref qcpdatacontainer-datatype "next section". + + The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well + as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The + container uses a preallocation and a postallocation scheme, such that appending and prepending + data (with respect to the sort key) is very fast and minimizes reallocations. If data is added + which needs to be inserted between existing keys, the merge usually can be done quickly too, + using the fact that existing data is always sorted. The user can further improve performance by + specifying that added data is already itself sorted by key, if he can guarantee that this is the + case (see for example \ref add(const QVector &data, bool alreadySorted)). + + The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If + it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin, + \ref end). Changing data members that are not the sort key (for most data types called \a key) is + safe from the container's perspective. + + Great care must be taken however if the sort key is modified through the non-const iterators. For + performance reasons, the iterators don't automatically cause a re-sorting upon their + manipulation. It is thus the responsibility of the user to leave the container in a sorted state + when finished with the data manipulation, before calling any other methods on the container. A + complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref + sort. Failing to do so can not be detected by the container efficiently and will cause both + rendering artifacts and potential data loss. + + Implementing one-dimensional plottables that make use of a \ref QCPDataContainer is usually + done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D", which + introduces an according \a mDataContainer member and some convenience methods. + + \section qcpdatacontainer-datatype Requirements for the DataType template parameter + + The template parameter DataType is the type of the stored data points. It must be + trivially copyable and have the following public methods, preferably inline: + + \li double sortKey() const\n Returns the member variable of this data point that is the + sort key, defining the ordering in the container. Often this variable is simply called \a key. + + \li static DataType fromSortKey(double sortKey)\n Returns a new instance of the data + type initialized with its sort key set to \a sortKey. + + \li static bool sortKeyIsMainKey()\n Returns true if the sort key is equal to the main + key (see method \c mainKey below). For most plottables this is the case. It is not the case for + example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason + why QCPCurve unlike QCPGraph can display parametric curves with loops. + + \li double mainKey() const\n Returns the variable of this data point considered the main + key. This is commonly the variable that is used as the coordinate of this data point on the key + axis of the plottable. This method is used for example when determining the automatic axis + rescaling of key axes (\ref QCPAxis::rescale). + + \li double mainValue() const\n Returns the variable of this data point considered the + main value. This is commonly the variable that is used as the coordinate of this data point on + the value axis of the plottable. + + \li QCPRange valueRange() const\n Returns the range this data point spans in the value + axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with + both lower and upper set to the main data point value. However if the data points can represent + multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close + values at each \a key) this method should return the range those values span. This method is used + for example when determining the automatic axis rescaling of value axes (\ref + QCPAxis::rescale). +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataContainer::size() const + + Returns the number of data points in the container. +*/ + +/*! \fn bool QCPDataContainer::isEmpty() const + + Returns whether this container holds no data points. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constBegin() const + + Returns a const iterator to the first data point in this container. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constEnd() const + + Returns a const iterator to the element past the last data point in this container. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::begin() const + + Returns a non-const iterator to the first data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::end() const + + Returns a non-const iterator to the element past the last data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::at(int index) const + + Returns a const iterator to the element with the specified \a index. If \a index points beyond + the available elements in this container, returns \ref constEnd, i.e. an iterator past the last + valid element. + + You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref + dataselection-accessing "data selection page" for an example. +*/ + +/*! \fn QCPDataRange QCPDataContainer::dataRange() const + + Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the + begin index of the returned range is 0, and the end index is \ref size. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted + data +*/ +template +QCPDataContainer::QCPDataContainer() : + mAutoSqueeze(true), + mPreallocSize(0), + mPreallocIteration(0) +{ +} + +/*! + Sets whether the container automatically decides when to release memory from its post- and + preallocation pools when data points are removed. By default this is enabled and for typical + applications shouldn't be changed. + + If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with + \ref squeeze. +*/ +template +void QCPDataContainer::setAutoSqueeze(bool enabled) +{ + if (mAutoSqueeze != enabled) + { + mAutoSqueeze = enabled; + if (mAutoSqueeze) + performAutoSqueeze(); + } +} + +/*! \overload + + Replaces the current data in this container with the provided \a data. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QCPDataContainer &data) +{ + clear(); + add(data); +} + +/*! \overload + + Replaces the current data in this container with the provided \a data + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QVector &data, bool alreadySorted) +{ + mData = data; + mPreallocSize = 0; + mPreallocIteration = 0; + if (!alreadySorted) + sort(); +} + +/*! \overload + + Adds the provided \a data to the current data in this container. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QCPDataContainer &data) +{ + if (data.isEmpty()) + return; + + const int n = data.size(); + const int oldSize = size(); + + if (oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! + Adds the provided data points in \a data to the current data. + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QVector &data, bool alreadySorted) +{ + if (data.isEmpty()) + return; + if (isEmpty()) + { + set(data, alreadySorted); + return; + } + + const int n = data.size(); + const int oldSize = size(); + + if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and then sort and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (!alreadySorted) // sort appended subrange if it wasn't already sorted + std::sort(end()-n, end(), qcpLessThanSortKey); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! \overload + + Adds the provided single data point to the current data. + + \see remove +*/ +template +void QCPDataContainer::add(const DataType &data) +{ + if (isEmpty() || !qcpLessThanSortKey(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones + { + mData.append(data); + } else if (qcpLessThanSortKey(data, *constBegin())) // quickly handle prepends using preallocated space + { + if (mPreallocSize < 1) + preallocateGrow(1); + --mPreallocSize; + *begin() = data; + } else // handle inserts, maintaining sorted keys + { + QCPDataContainer::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey); + mData.insert(insertionPoint, data); + } +} + +/*! + Removes all data points with (sort-)keys smaller than or equal to \a sortKey. + + \see removeAfter, remove, clear +*/ +template +void QCPDataContainer::removeBefore(double sortKey) +{ + QCPDataContainer::iterator it = begin(); + QCPDataContainer::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + mPreallocSize += itEnd-it; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys greater than or equal to \a sortKey. + + \see removeBefore, remove, clear +*/ +template +void QCPDataContainer::removeAfter(double sortKey) +{ + QCPDataContainer::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = end(); + mData.erase(it, itEnd); // typically adds it to the postallocated block + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a + sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single + data point with known (sort-)key, use \ref remove(double sortKey). + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) +{ + if (sortKeyFrom >= sortKeyTo || isEmpty()) + return; + + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey); + mData.erase(it, itEnd); + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! \overload + + Removes a single data point at \a sortKey. If the position is not known with absolute (binary) + precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small + fuzziness interval around the suspected position, depeding on the precision with which the + (sort-)key is known. + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKey) +{ + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (it != end() && it->sortKey() == sortKey) + { + if (it == begin()) + ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + else + mData.erase(it); + } + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points. + + \see remove, removeAfter, removeBefore +*/ +template +void QCPDataContainer::clear() +{ + mData.clear(); + mPreallocIteration = 0; + mPreallocSize = 0; +} + +/*! + Re-sorts all data points in the container by their sort key. + + When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add, + \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full + resort is never necessary. However, if you choose to directly manipulate the sort key on data + points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it + is your responsibility to bring the container back into a sorted state before any other methods + are called on it. This can be achieved by calling this method immediately after finishing the + sort key manipulation. +*/ +template +void QCPDataContainer::sort() +{ + std::sort(begin(), end(), qcpLessThanSortKey); +} + +/*! + Frees all unused memory that is currently in the preallocation and postallocation pools. + + Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref + setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical + applications. + + The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation + should be freed, respectively. +*/ +template +void QCPDataContainer::squeeze(bool preAllocation, bool postAllocation) +{ + if (preAllocation) + { + if (mPreallocSize > 0) + { + std::copy(begin(), end(), mData.begin()); + mData.resize(size()); + mPreallocSize = 0; + } + mPreallocIteration = 0; + } + if (postAllocation) + mData.squeeze(); +} + +/*! + Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just + above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be + considered, otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is + returned. + + If the container is empty, returns \ref constEnd. + + \see findEnd, QCPPlottableInterface1D::findBegin +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findBegin(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty + --it; + return it; +} + +/*! + Returns an iterator to the element after the data point with a (sort-)key that is equal to, just + above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey + will be considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is + returned. + + If the container is empty, \ref constEnd is returned. + + \see findBegin, QCPPlottableInterface1D::findEnd +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findEnd(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constEnd()) + ++it; + return it; +} + +/*! + Returns the range encompassed by the (main-)key coordinate of all data points. The output + parameter \a foundRange indicates whether a sensible range was found. If this is false, you + should not use the returned QCPRange (e.g. the data container is empty or all points have the + same key). + + Use \a signDomain to control which sign of the key coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is + the case for most plottables, this method uses this fact and finds the range very quickly. + + \see valueRange +*/ +template +QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain signDomain) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + double current; + + QCPDataContainer::const_iterator it = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (signDomain == QCP::sdBoth) // range may be anywhere + { + if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value + { + while (it != itEnd) // find first non-nan going up from left + { + if (!qIsNaN(it->mainValue())) + { + range.lower = it->mainKey(); + haveLower = true; + break; + } + ++it; + } + it = itEnd; + while (it != constBegin()) // find first non-nan going down from right + { + --it; + if (!qIsNaN(it->mainValue())) + { + range.upper = it->mainKey(); + haveUpper = true; + break; + } + } + } else // DataType is not sorted by main key, go through all data points and accordingly expand range + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Returns the range encompassed by the value coordinates of the data points in the specified key + range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The + output parameter \a foundRange indicates whether a sensible range was found. If this is false, + you should not use the returned QCPRange (e.g. the data container is empty or all points have the + same value). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Use \a signDomain to control which sign of the value coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + \see keyRange +*/ +template +QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPRange current; + QCPDataContainer::const_iterator itBegin = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (DataType::sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = findBegin(inKeyRange.lower); + itEnd = findEnd(inKeyRange.upper); + } + if (signDomain == QCP::sdBoth) // range may be anywhere + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Makes sure \a begin and \a end mark a data range that is both within the bounds of this data + container's data, as well as within the specified \a dataRange. The initial range described by + the passed iterators \a begin and \a end is never expanded, only contracted if necessary. + + This function doesn't require for \a dataRange to be within the bounds of this data container's + valid range. +*/ +template +void QCPDataContainer::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const +{ + QCPDataRange iteratorRange(begin-constBegin(), end-constBegin()); + iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange())); + begin = constBegin()+iteratorRange.begin(); + end = constBegin()+iteratorRange.end(); +} + +/*! \internal + + Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on + the preallocation history, the container will grow by more than requested, to speed up future + consecutive size increases. + + if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this + method does nothing. +*/ +template +void QCPDataContainer::preallocateGrow(int minimumPreallocSize) +{ + if (minimumPreallocSize <= mPreallocSize) + return; + + int newPreallocSize = minimumPreallocSize; + newPreallocSize += (1u< +void QCPDataContainer::performAutoSqueeze() +{ + const int totalAlloc = mData.capacity(); + const int postAllocSize = totalAlloc-mData.size(); + const int usedSize = size(); + bool shrinkPostAllocation = false; + bool shrinkPreAllocation = false; + if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size + { + shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate! + shrinkPreAllocation = mPreallocSize*10 > usedSize; + } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother + { + shrinkPostAllocation = postAllocSize > usedSize*5; + shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller + } + + if (shrinkPreAllocation || shrinkPostAllocation) + squeeze(shrinkPreAllocation, shrinkPostAllocation); +} +/* end of 'src/datacontainer.cpp' */ + + +/* end of 'src/datacontainer.h' */ + + +/* including file 'src/plottable.h', size 8312 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPSelectionDecorator +{ + Q_GADGET +public: + QCPSelectionDecorator(); + virtual ~QCPSelectionDecorator(); + + // getters: + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; } + + // setters: + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); + void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); + + // non-virtual methods: + void applyPen(QCPPainter *painter) const; + void applyBrush(QCPPainter *painter) const; + QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; + + // introduced virtual methods: + virtual void copyFrom(const QCPSelectionDecorator *other); + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); + +protected: + // property members: + QPen mPen; + QBrush mBrush; + QCPScatterStyle mScatterStyle; + QCPScatterStyle::ScatterProperties mUsedScatterProperties; + // non-property members: + QCPAbstractPlottable *mPlottable; + + // introduced virtual methods: + virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); + +private: + Q_DISABLE_COPY(QCPSelectionDecorator) + friend class QCPAbstractPlottable; +}; +Q_DECLARE_METATYPE(QCPSelectionDecorator*) + + +class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) + Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) + Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) + Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged) + Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator) + /// \endcond +public: + QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable(); + + // getters: + QString name() const { return mName; } + QString desc() const { return mDesc; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCP::SelectionType selectable() const { return mSelectable; } + bool selected() const { return !mSelection.isEmpty(); } + QCPDataSelection selection() const { return mSelection; } + QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } + + // setters: + void setName(const QString &name); + void setDesc(const QString &desc); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setKeyAxis(QCPAxis *axis); + void setValueAxis(QCPAxis *axis); + Q_SLOT void setSelectable(QCP::SelectionType selectable); + Q_SLOT void setSelection(QCPDataSelection selection); + void setSelectionDecorator(QCPSelectionDecorator *decorator); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; + virtual QCPPlottableInterface1D *interface1D() { return 0; } + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; + + // non-property methods: + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; + bool addToLegend(QCPLegend *legend); + bool addToLegend(); + bool removeFromLegend(QCPLegend *legend) const; + bool removeFromLegend() const; + +signals: + void selectionChanged(bool selected); + void selectionChanged(const QCPDataSelection &selection); + void selectableChanged(QCP::SelectionType selectable); + +protected: + // property members: + QString mName; + QString mDesc; + bool mAntialiasedFill, mAntialiasedScatters; + QPen mPen; + QBrush mBrush; + QPointer mKeyAxis, mValueAxis; + QCP::SelectionType mSelectable; + QCPDataSelection mSelection; + QCPSelectionDecorator *mSelectionDecorator; + + // reimplemented virtual methods: + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; + + // non-virtual methods: + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable) + + friend class QCustomPlot; + friend class QCPAxis; + friend class QCPPlottableLegendItem; +}; + + +/* end of 'src/plottable.h' */ + + +/* including file 'src/item.h', size 9384 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemAnchor +{ + Q_GADGET +public: + QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); + virtual ~QCPItemAnchor(); + + // getters: + QString name() const { return mName; } + virtual QPointF pixelPosition() const; + +protected: + // property members: + QString mName; + + // non-property members: + QCustomPlot *mParentPlot; + QCPAbstractItem *mParentItem; + int mAnchorId; + QSet mChildrenX, mChildrenY; + + // introduced virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return 0; } + + // non-virtual methods: + void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + +private: + Q_DISABLE_COPY(QCPItemAnchor) + + friend class QCPItemPosition; +}; + + + +class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor +{ + Q_GADGET +public: + /*! + Defines the ways an item position can be specified. Thus it defines what the numbers passed to + \ref setCoords actually mean. + + \see setType + */ + enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. + ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the viewport/widget, etc. + ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. + ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). + }; + Q_ENUMS(PositionType) + + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name); + virtual ~QCPItemPosition(); + + // getters: + PositionType type() const { return typeX(); } + PositionType typeX() const { return mPositionTypeX; } + PositionType typeY() const { return mPositionTypeY; } + QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } + QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } + QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } + double key() const { return mKey; } + double value() const { return mValue; } + QPointF coords() const { return QPointF(mKey, mValue); } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCPAxisRect *axisRect() const; + virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; + + // setters: + void setType(PositionType type); + void setTypeX(PositionType type); + void setTypeY(PositionType type); + bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + void setCoords(double key, double value); + void setCoords(const QPointF &coords); + void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); + void setAxisRect(QCPAxisRect *axisRect); + void setPixelPosition(const QPointF &pixelPosition); + +protected: + // property members: + PositionType mPositionTypeX, mPositionTypeY; + QPointer mKeyAxis, mValueAxis; + QPointer mAxisRect; + double mKey, mValue; + QCPItemAnchor *mParentAnchorX, *mParentAnchorY; + + // reimplemented virtual methods: + virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } + +private: + Q_DISABLE_COPY(QCPItemPosition) + +}; +Q_DECLARE_METATYPE(QCPItemPosition::PositionType) + + +class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) + Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPAbstractItem(QCustomPlot *parentPlot); + virtual ~QCPAbstractItem(); + + // getters: + bool clipToAxisRect() const { return mClipToAxisRect; } + QCPAxisRect *clipAxisRect() const; + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setClipToAxisRect(bool clip); + void setClipAxisRect(QCPAxisRect *rect); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE = 0; + + // non-virtual methods: + QList positions() const { return mPositions; } + QList anchors() const { return mAnchors; } + QCPItemPosition *position(const QString &name) const; + QCPItemAnchor *anchor(const QString &name) const; + bool hasAnchor(const QString &name) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + bool mClipToAxisRect; + QPointer mClipAxisRect; + QList mPositions; + QList mAnchors; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual QPointF anchorPixelPosition(int anchorId) const; + + // non-virtual methods: + double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const; + QCPItemPosition *createPosition(const QString &name); + QCPItemAnchor *createAnchor(const QString &name, int anchorId); + +private: + Q_DISABLE_COPY(QCPAbstractItem) + + friend class QCustomPlot; + friend class QCPItemAnchor; +}; + +/* end of 'src/item.h' */ + + +/* including file 'src/core.h', size 14886 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCustomPlot : public QWidget +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) + Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) + Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) + Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) + Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) + Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl) + /// \endcond +public: + /*! + Defines how a layer should be inserted relative to an other layer. + + \see addLayer, moveLayer + */ + enum LayerInsertMode { limBelow ///< Layer is inserted below other layer + ,limAbove ///< Layer is inserted above other layer + }; + Q_ENUMS(LayerInsertMode) + + /*! + Defines with what timing the QCustomPlot surface is refreshed after a replot. + + \see replot + */ + enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot + ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided. + ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints. + ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. + }; + Q_ENUMS(RefreshPriority) + + explicit QCustomPlot(QWidget *parent = 0); + virtual ~QCustomPlot(); + + // getters: + QRect viewport() const { return mViewport; } + double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + QCPLayoutGrid *plotLayout() const { return mPlotLayout; } + QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } + QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } + bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } + const QCP::Interactions interactions() const { return mInteractions; } + int selectionTolerance() const { return mSelectionTolerance; } + bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } + QCP::PlottingHints plottingHints() const { return mPlottingHints; } + Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } + QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } + QCPSelectionRect *selectionRect() const { return mSelectionRect; } + bool openGl() const { return mOpenGl; } + QPoint symbolPos() { return mSymbolPos; } + + // setters: + void setSymbolPos(const QPoint pos); + void setViewport(const QRect &rect); + void setBufferDevicePixelRatio(double ratio); + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); + void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); + void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); + void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); + void setAutoAddPlottableToLegend(bool on); + void setInteractions(const QCP::Interactions &interactions); + void setInteraction(const QCP::Interaction &interaction, bool enabled=true); + void setSelectionTolerance(int pixels); + void setNoAntialiasingOnDrag(bool enabled); + void setPlottingHints(const QCP::PlottingHints &hints); + void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); + void setMultiSelectModifier(Qt::KeyboardModifier modifier); + void setSelectionRectMode(QCP::SelectionRectMode mode); + void setSelectionRect(QCPSelectionRect *selectionRect); + void setOpenGl(bool enabled, int multisampling=16); + + // non-property methods: + // plottable interface: + QCPAbstractPlottable *plottable(int index); + QCPAbstractPlottable *plottable(); + bool removePlottable(QCPAbstractPlottable *plottable); + bool removePlottable(int index); + int clearPlottables(); + int plottableCount() const; + QList selectedPlottables() const; + QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasPlottable(QCPAbstractPlottable *plottable) const; + + // specialized interface for QCPGraph: + QCPGraph *graph(int index) const; + QCPGraph *graph() const; + QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); + bool removeGraph(QCPGraph *graph); + bool removeGraph(int index); + int clearGraphs(); + int graphCount() const; + QList selectedGraphs() const; + + // item interface: + QCPAbstractItem *item(int index) const; + QCPAbstractItem *item() const; + bool removeItem(QCPAbstractItem *item); + bool removeItem(int index); + int clearItems(bool clearTitle = false); + int itemCount() const; + QList selectedItems() const; + QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasItem(QCPAbstractItem *item) const; + + // layer interface: + QCPLayer *layer(const QString &name) const; + QCPLayer *layer(int index) const; + QCPLayer *currentLayer() const; + bool setCurrentLayer(const QString &name); + bool setCurrentLayer(QCPLayer *layer); + int layerCount() const; + bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); + bool removeLayer(QCPLayer *layer); + bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); + + // axis rect/layout interface: + int axisRectCount() const; + QCPAxisRect* axisRect(int index=0) const; + QList axisRects() const; + QCPLayoutElement* layoutElementAt(const QPointF &pos) const; + QCPAxisRect* axisRectAt(const QPointF &pos) const; + Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); + + QList selectedAxes() const; + QList selectedLegends() const; + Q_SLOT void deselectAll(); + + bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); + bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + QPixmap toPixmap(int width=0, int height=0, double scale=1.0); + void toPainter(QCPPainter *painter, int width=0, int height=0); + Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); + + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + QCPLegend *legend; + +signals: + void mouseDoubleClick(QMouseEvent *event); + void mousePress(QMouseEvent *event); + void mouseMove(QMouseEvent *event); + void mouseRelease(QMouseEvent *event); + void mouseWheel(QWheelEvent *event); + + //< 鼠标按下 更新CCurveLegendModel值 + void symbolPosChanged(const double &value); + + void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void itemClick(QCPAbstractItem *item, QMouseEvent *event); + void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); + void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + + void selectionChangedByUser(); + void beforeReplot(); + void afterReplot(); + +protected: + // property members: + QRect mViewport; + double mBufferDevicePixelRatio; + QCPLayoutGrid *mPlotLayout; + bool mAutoAddPlottableToLegend; + QList mPlottables; + QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph + QList mItems; + QList mLayers; + QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; + QCP::Interactions mInteractions; + int mSelectionTolerance; + bool mNoAntialiasingOnDrag; + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayer *mCurrentLayer; + QCP::PlottingHints mPlottingHints; + Qt::KeyboardModifier mMultiSelectModifier; + QCP::SelectionRectMode mSelectionRectMode; + QCPSelectionRect *mSelectionRect; + bool mOpenGl; + + // non-property members: + QList > mPaintBuffers; + bool mSymbolPressed; + QPoint mSymbolPos; + QPoint mMousePressPos; + bool mMouseHasMoved; + QPointer mMouseEventLayerable; + QPointer mMouseSignalLayerable; + QVariant mMouseEventLayerableDetails; + QVariant mMouseSignalLayerableDetails; + bool mReplotting; + bool mReplotQueued; + int mOpenGlMultisamples; + QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup; + bool mOpenGlCacheLabelsBackup; +#ifdef QCP_OPENGL_FBO + QSharedPointer mGlContext; + QSharedPointer mGlSurface; + QSharedPointer mGlPaintDevice; +#endif + + // reimplemented virtual methods: + virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + virtual QSize sizeHint() const Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + bool eventFilter(QObject *object, QEvent *event); + + // introduced virtual methods: + virtual void draw(QCPPainter *painter); + virtual void updateLayout(); + virtual void axisRemoved(QCPAxis *axis); + virtual void legendRemoved(QCPLegend *legend); + Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processPointSelection(QMouseEvent *event); + + // non-virtual methods: + bool registerPlottable(QCPAbstractPlottable *plottable); + bool registerGraph(QCPGraph *graph); + bool registerItem(QCPAbstractItem* item); + void updateLayerIndices() const; + QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; + QList layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails=0) const; + void drawBackground(QCPPainter *painter); + void setupPaintBuffers(); + QCPAbstractPaintBuffer *createPaintBuffer(); + bool hasInvalidatedPaintBuffers(); + bool setupOpenGl(); + void freeOpenGl(); + + friend class QCPLegend; + friend class QCPAxis; + friend class QCPLayer; + friend class QCPAxisRect; + friend class QCPAbstractPlottable; + friend class QCPGraph; + friend class QCPAbstractItem; +}; +Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode) +Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) + +/* end of 'src/core.h' */ + + +/* including file 'src/plottable1d.h', size 4544 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCPPlottableInterface1D +{ +public: + virtual ~QCPPlottableInterface1D() {} + // introduced pure virtual methods: + virtual int dataCount() const = 0; + virtual double dataMainKey(int index) const = 0; + virtual double dataSortKey(int index) const = 0; + virtual double dataMainValue(int index) const = 0; + virtual QCPRange dataValueRange(int index) const = 0; + virtual QPointF dataPixelPosition(int index) const = 0; + virtual bool sortKeyIsMainKey() const = 0; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + virtual int findBegin(double sortKey, bool expandedRange=true) const = 0; + virtual int findEnd(double sortKey, bool expandedRange=true) const = 0; +}; + +template +class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below) +{ + // No Q_OBJECT macro due to template class + +public: + QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable1D(); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const Q_DECL_OVERRIDE; + virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; + virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; + virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; + virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer > mDataContainer; + + // helpers for subclasses: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + void drawPolyline(QCPPainter *painter, const QVector &lineData, const QVector &status=QVector()) const; + void drawPolyline(QCPPainter *painter, const QPointF *points, const int *status, int pointCount) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable1D) + +}; + +// include implementation in header since it is a class template: + +/* including file 'src/plottable1d.cpp', size 22240 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableInterface1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableInterface1D + \brief Defines an abstract interface for one-dimensional plottables + + This class contains only pure virtual methods which define a common interface to the data + of one-dimensional plottables. + + For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred + base class for one-dimensional plottables). So if you use that template class as base class of + your one-dimensional plottable, you won't have to care about implementing the 1d interface + yourself. + + If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d + interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref + QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure + virtual methods of the 1d interface, matching your data container. Also, reimplement \ref + QCPAbstractPlottable::interface1D to return the \c this pointer. + + If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this + interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return + value. If it indeed implements this interface, you may use it to access the plottable's data + without needing to know the exact type of the plottable or its data point type. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; + + Returns the number of data points of the plottable. +*/ + +/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + + Returns a data selection containing all the data points of this plottable which are contained (or + hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref + dataselection "data selection mechanism"). + + If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not + selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). + + \note \a rect must be a normalized rect (positive or zero width and height). This is especially + important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily + normalized. Use QRect::normalized() when passing a rect which might not be normalized. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 + + Returns the main key of the data point at the given \a index. + + What the main key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 + + Returns the sort key of the data point at the given \a index. + + What the sort key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 + + Returns the main value of the data point at the given \a index. + + What the main value is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 + + Returns the value range of the data point at the given \a index. + + What the value range is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0 + + Returns the pixel position on the widget surface at which the data point at the given \a index + appears. + + Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel + coordinates. However, depending on the plottable, this might be a different apparent position + than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data + values can be shifted depending on their stacking, bar grouping or configured base value. +*/ + +/*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0 + + Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey). + + What the sort and main keys are, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0 + + Returns the index of the data point with a (sort-)key that is equal to, just below, or just above + \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered, + otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned. + + If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop + using these methods will not iterate over the index 0). + + \see findEnd, QCPDataContainer::findBegin +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0 + + Returns the index one after the data point with a (sort-)key that is equal to, just above, or + just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be + considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, the index just above the + highest data point is returned. + + If the container is empty, returns 0. + + \see findBegin, QCPDataContainer::findEnd +*/ + +/* end documentation of pure virtual functions */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable1D + \brief A template base class for plottables with one-dimensional data + + This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref + QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with + one key dimension), such as \ref QCPGraph and QCPCurve. + + The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref + QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member + \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer") and + implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most + subclassed plottables don't need to worry about this anymore. + + Further, it provides a convenience method for retrieving selected/unselected data segments via + \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to + draw selected segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref + QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data + interface. In spite of that, most plottable subclasses will want to reimplement those methods + again, to provide a more accurate hit test based on their specific data visualization geometry. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() + + Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D + interface. + + \seebaseclassmethod +*/ + +/* end documentation of inline functions */ + +/*! + Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable + "QCPAbstractPlottable" constructor and allocates the \a mDataContainer. +*/ +template +QCPAbstractPlottable1D::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QCPDataContainer) +{ +} + +template +QCPAbstractPlottable1D::~QCPAbstractPlottable1D() +{ +} + +/*! + \copydoc QCPPlottableInterface1D::dataCount +*/ +template +int QCPAbstractPlottable1D::dataCount() const +{ + return mDataContainer->size(); +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainKey +*/ +template +double QCPAbstractPlottable1D::dataMainKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataSortKey +*/ +template +double QCPAbstractPlottable1D::dataSortKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->sortKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainValue +*/ +template +double QCPAbstractPlottable1D::dataMainValue(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainValue(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataValueRange +*/ +template +QCPRange QCPAbstractPlottable1D::dataValueRange(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->valueRange(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QCPRange(0, 0); + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataPixelPosition +*/ +template +QPointF QCPAbstractPlottable1D::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + const typename QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + return coordsToPixels(it->mainKey(), it->mainValue()); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/*! + \copydoc QCPPlottableInterface1D::sortKeyIsMainKey +*/ +template +bool QCPAbstractPlottable1D::sortKeyIsMainKey() const +{ + return DataType::sortKeyIsMainKey(); +} + +/*! + Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + // convert rect given in pixels to ranges given in plot coordinates: + double key1, value1, key2, value2; + pixelsToCoords(rect.topLeft(), key1, value1); + pixelsToCoords(rect.bottomRight(), key2, value2); + QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2 + QCPRange valueRange(value1, value2); + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + begin = mDataContainer->findBegin(keyRange.lower, false); + end = mDataContainer->findEnd(keyRange.upper, false); + } + if (begin == end) + return result; + + int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (currentSegmentBegin == -1) + { + if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment + currentSegmentBegin = it-mDataContainer->constBegin(); + } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended + { + result.addDataRange(QCPDataRange(currentSegmentBegin, it-mDataContainer->constBegin()), false); + currentSegmentBegin = -1; + } + } + // process potential last segment: + if (currentSegmentBegin != -1) + result.addDataRange(QCPDataRange(currentSegmentBegin, end-mDataContainer->constBegin()), false); + + result.simplify(); + return result; +} + +/*! + \copydoc QCPPlottableInterface1D::findBegin +*/ +template +int QCPAbstractPlottable1D::findBegin(double sortKey, bool expandedRange) const +{ + return mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin(); +} + +/*! + \copydoc QCPPlottableInterface1D::findEnd +*/ +template +int QCPAbstractPlottable1D::findEnd(double sortKey, bool expandedRange) const +{ + return mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin(); +} + +/*! + Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + QCPDataSelection selectionResult; + double minDistSqr = std::numeric_limits::max(); + int minDistIndex = mDataContainer->size(); + + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + begin = mDataContainer->findBegin(posKeyMin, true); + end = mDataContainer->findEnd(posKeyMax, true); + } + if (begin == end) + return -1; + QCPRange keyRange(mKeyAxis->range()); + QCPRange valueRange(mValueAxis->range()); + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double mainKey = it->mainKey(); + const double mainValue = it->mainValue(); + if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points + { + const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + minDistIndex = it-mDataContainer->constBegin(); + } + } + } + if (minDistIndex != mDataContainer->size()) + selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false); + + selectionResult.simplify(); + if (details) + details->setValue(selectionResult); + return qSqrt(minDistSqr); +} + +/*! + Splits all data into selected and unselected segments and outputs them via \a selectedSegments + and \a unselectedSegments, respectively. + + This is useful when subclasses implement their \ref draw method and need to draw selected + segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + \see setSelection +*/ +template +void QCPAbstractPlottable1D::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! + A helper method which draws a line with the passed \a painter, according to the pixel data in \a + lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is + the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or + crashing). + + Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c + QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter + style allows. +*/ +template +void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QVector &lineData, const QVector &status) const +{ + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->modes().testFlag(QCPPainter::pmVectorized) && + !painter->modes().testFlag(QCPPainter::pmNoCaching)) + { + int i = 0; + bool lastIsNan = false; + const int lineDataSize = lineData.size(); + while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN + ++i; + ++i; // because drawing works in 1 point retrospect + while (i < lineDataSize) + { + if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line + { + if (!lastIsNan) + painter->drawLine(lineData.at(i-1), lineData.at(i)); + else + lastIsNan = false; + } else + lastIsNan = true; + ++i; + } + } else + { + int segmentStart = 0; + int i = 0; + const int lineDataSize = lineData.size(); + while (i < lineDataSize) + { + if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block + { + if(status.size() == lineDataSize) + { + drawPolyline(painter, lineData.constData()+segmentStart, status.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point + } + else + { + painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); + } + segmentStart = i+1; + } + ++i; + } + // draw last segment: + if(status.size() == lineDataSize) + { + drawPolyline(painter, lineData.constData()+segmentStart, status.constData()+segmentStart, lineDataSize-segmentStart); + } + else + { + painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart); + } + } +} + +template +void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QPointF *points, const int *status, int pointCount) const +{ + painter->save(); + QColor color = painter->pen().color(); + int preStatus = 0; + int curStatus = 0; + int segmentStart = 0; + for(int i(0); idrawPolyline(points+segmentStart, i-segmentStart+1); + if(curStatus == 1) + painter->setPen(Qt::gray); + else + painter->setPen(color); + segmentStart = i; + preStatus = curStatus; + } + } + painter->drawPolyline(points+segmentStart, pointCount-segmentStart); + painter->restore(); +} +/* end of 'src/plottable1d.cpp' */ + + +/* end of 'src/plottable1d.h' */ + + +/* including file 'src/colorgradient.h', size 6243 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPColorGradient +{ + Q_GADGET +public: + /*! + Defines the color spaces in which color interpolation between gradient stops can be performed. + + \see setColorInterpolation + */ + enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated + ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) + }; + Q_ENUMS(ColorInterpolation) + + /*! + Defines the available presets that can be loaded with \ref loadPreset. See the documentation + there for an image of the presets. + */ + enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) + ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) + ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) + ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) + ,gpCandy ///< Blue over pink to white + ,gpGeography ///< Colors suitable to represent different elevations on geographical maps + ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) + ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white + ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values + ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) + ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) + ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) + }; + Q_ENUMS(GradientPreset) + + QCPColorGradient(); + QCPColorGradient(GradientPreset preset); + bool operator==(const QCPColorGradient &other) const; + bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } + + // getters: + int levelCount() const { return mLevelCount; } + QMap colorStops() const { return mColorStops; } + ColorInterpolation colorInterpolation() const { return mColorInterpolation; } + bool periodic() const { return mPeriodic; } + + // setters: + void setLevelCount(int n); + void setColorStops(const QMap &colorStops); + void setColorStopAt(double position, const QColor &color); + void setColorInterpolation(ColorInterpolation interpolation); + void setPeriodic(bool enabled); + + // non-property methods: + void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + QRgb color(double position, const QCPRange &range, bool logarithmic=false); + void loadPreset(GradientPreset preset); + void clearColorStops(); + QCPColorGradient inverted() const; + +protected: + // property members: + int mLevelCount; + QMap mColorStops; + ColorInterpolation mColorInterpolation; + bool mPeriodic; + + // non-property members: + QVector mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied) + bool mColorBufferInvalidated; + + // non-virtual methods: + bool stopsUseAlpha() const; + void updateColorBuffer(); +}; +Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation) +Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) + +/* end of 'src/colorgradient.h' */ + + +/* including file 'src/selectiondecorator-bracket.h', size 4442 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator +{ + Q_GADGET +public: + + /*! + Defines which shape is drawn at the boundaries of selected data ranges. + + Some of the bracket styles further allow specifying a height and/or width, see \ref + setBracketHeight and \ref setBracketWidth. + */ + enum BracketStyle { bsSquareBracket ///< A square bracket is drawn. + ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsPlus ///< A plus is drawn. + ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket. + }; + Q_ENUMS(BracketStyle) + + QCPSelectionDecoratorBracket(); + virtual ~QCPSelectionDecoratorBracket(); + + // getters: + QPen bracketPen() const { return mBracketPen; } + QBrush bracketBrush() const { return mBracketBrush; } + int bracketWidth() const { return mBracketWidth; } + int bracketHeight() const { return mBracketHeight; } + BracketStyle bracketStyle() const { return mBracketStyle; } + bool tangentToData() const { return mTangentToData; } + int tangentAverage() const { return mTangentAverage; } + + // setters: + void setBracketPen(const QPen &pen); + void setBracketBrush(const QBrush &brush); + void setBracketWidth(int width); + void setBracketHeight(int height); + void setBracketStyle(BracketStyle style); + void setTangentToData(bool enabled); + void setTangentAverage(int pointCount); + + // introduced virtual methods: + virtual void drawBracket(QCPPainter *painter, int direction) const; + + // virtual methods: + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; + +protected: + // property members: + QPen mBracketPen; + QBrush mBracketBrush; + int mBracketWidth; + int mBracketHeight; + BracketStyle mBracketStyle; + bool mTangentToData; + int mTangentAverage; + + // non-virtual methods: + double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const; + QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; + +}; +Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) + +/* end of 'src/selectiondecorator-bracket.h' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); + virtual ~QCPAxisRect(); + + // getters: + QPixmap background() const { return mBackgroundPixmap; } + QBrush backgroundBrush() const { return mBackgroundBrush; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + Qt::Orientations rangeDrag() const { return mRangeDrag; } + Qt::Orientations rangeZoom() const { return mRangeZoom; } + QCPAxis *rangeDragAxis(Qt::Orientation orientation); + QCPAxis *rangeZoomAxis(Qt::Orientation orientation); + QList rangeDragAxes(Qt::Orientation orientation); + QList rangeZoomAxes(Qt::Orientation orientation); + double rangeZoomFactor(Qt::Orientation orientation); + + // setters: + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setRangeDrag(Qt::Orientations orientations); + void setRangeZoom(Qt::Orientations orientations); + void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeDragAxes(QList axes); + void setRangeDragAxes(QList horizontal, QList vertical); + void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomAxes(QList axes); + void setRangeZoomAxes(QList horizontal, QList vertical); + void setRangeZoomFactor(double horizontalFactor, double verticalFactor); + void setRangeZoomFactor(double factor); + + // non-property methods: + int axisCount(QCPAxis::AxisType type) const; + QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; + QList axes(QCPAxis::AxisTypes types) const; + QList axes() const; + QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); + QList addAxes(QCPAxis::AxisTypes types); + bool removeAxis(QCPAxis *axis); + QCPLayoutInset *insetLayout() const { return mInsetLayout; } + + void zoom(const QRectF &pixelRect); + void zoom(const QRectF &pixelRect, const QList &affectedAxes); + void setupFullAxesBox(bool connectRanges=false); + QList plottables() const; + QList graphs() const; + QList items() const; + + // read-only interface imitating a QRect: + int left() const { return mRect.left(); } + int right() const { return mRect.right(); } + int top() const { return mRect.top(); } + int bottom() const { return mRect.bottom(); } + int width() const { return mRect.width(); } + int height() const { return mRect.height(); } + QSize size() const { return mRect.size(); } + QPoint topLeft() const { return mRect.topLeft(); } + QPoint topRight() const { return mRect.topRight(); } + QPoint bottomLeft() const { return mRect.bottomLeft(); } + QPoint bottomRight() const { return mRect.bottomRight(); } + QPoint center() const { return mRect.center(); } + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + void setScaleRight(const bool &scaleRight = true) { mIsScaleRight = scaleRight; } + bool isScaleRight() { return mIsScaleRight; } + +signals: + void rangeDraged(); + void rangeScaled(); + +protected: + // property members: + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayoutInset *mInsetLayout; + Qt::Orientations mRangeDrag, mRangeZoom; + QList > mRangeDragHorzAxis, mRangeDragVertAxis; + QList > mRangeZoomHorzAxis, mRangeZoomVertAxis; + double mRangeZoomFactorHorz, mRangeZoomFactorVert; + + // non-property members: + QList mDragStartHorzRange, mDragStartVertRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + bool mDragging; + QHash > mAxes; + + //< ZH + bool mIsScaleRight; + bool mIsDragMove; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE; + virtual void layoutChanged() Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // non-property methods: + void drawBackground(QCPPainter *painter); + void updateAxesOffset(QCPAxis::AxisType type); + +private: + Q_DISABLE_COPY(QCPAxisRect) + + friend class QCustomPlot; +}; + + +/* end of 'src/layoutelements/layoutelement-axisrect.h' */ + + +/* including file 'src/layoutelements/layoutelement-legend.h', size 10397 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) + /// \endcond +public: + explicit QCPAbstractLegendItem(QCPLegend *parent); + + // getters: + QCPLegend *parentLegend() const { return mParentLegend; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QCPLegend *mParentLegend; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPAbstractLegendItem) + + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); + + // getters: + QCPAbstractPlottable *plottable() { return mPlottable; } + +protected: + // property members: + QCPAbstractPlottable *mPlottable; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; +}; + + +class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) + Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) + Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) + Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + /// \endcond +public: + /*! + Defines the selectable parts of a legend + + \see setSelectedParts, setSelectableParts + */ + enum SelectablePart { spNone = 0x000 ///< 0x000 None + ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) + ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPLegend(); + virtual ~QCPLegend(); + + // getters: + QPen borderPen() const { return mBorderPen; } + QBrush brush() const { return mBrush; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QSize iconSize() const { return mIconSize; } + int iconTextPadding() const { return mIconTextPadding; } + QPen iconBorderPen() const { return mIconBorderPen; } + SelectableParts selectableParts() const { return mSelectableParts; } + SelectableParts selectedParts() const; + QPen selectedBorderPen() const { return mSelectedBorderPen; } + QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + + // setters: + void setBorderPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setIconSize(const QSize &size); + void setIconSize(int width, int height); + void setIconTextPadding(int padding); + void setIconBorderPen(const QPen &pen); + Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); + void setSelectedBorderPen(const QPen &pen); + void setSelectedIconBorderPen(const QPen &pen); + void setSelectedBrush(const QBrush &brush); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPAbstractLegendItem *item(int index) const; + QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; + int itemCount() const; + bool hasItem(QCPAbstractLegendItem *item) const; + bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; + bool addItem(QCPAbstractLegendItem *item); + bool removeItem(int index); + bool removeItem(QCPAbstractLegendItem *item); + void clearItems(); + QList selectedItems() const; + +signals: + void selectionChanged(QCPLegend::SelectableParts parts); + void selectableChanged(QCPLegend::SelectableParts parts); + +protected: + // property members: + QPen mBorderPen, mIconBorderPen; + QBrush mBrush; + QFont mFont; + QColor mTextColor; + QSize mIconSize; + int mIconTextPadding; + SelectableParts mSelectedParts, mSelectableParts; + QPen mSelectedBorderPen, mSelectedIconBorderPen; + QBrush mSelectedBrush; + QFont mSelectedFont; + QColor mSelectedTextColor; + + // reimplemented virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getBorderPen() const; + QBrush getBrush() const; + +private: + Q_DISABLE_COPY(QCPLegend) + + friend class QCustomPlot; + friend class QCPAbstractLegendItem; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) +Q_DECLARE_METATYPE(QCPLegend::SelectablePart) + +/* end of 'src/layoutelements/layoutelement-legend.h' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.h', size 5353 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPTextElement(QCustomPlot *parentPlot); + QCPTextElement(QCustomPlot *parentPlot, const QString &text); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); + + // getters: + QString text() const { return mText; } + int textFlags() const { return mTextFlags; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setText(const QString &text); + void setTextFlags(int flags); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + void clicked(QMouseEvent *event); + void doubleClicked(QMouseEvent *event); + +protected: + // property members: + QString mText; + int mTextFlags; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + QRect mTextBoundingRect; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QFont mainFont() const; + QColor mainTextColor() const; + +private: + Q_DISABLE_COPY(QCPTextElement) +}; + + + +/* end of 'src/layoutelements/layoutelement-textelement.h' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +class QCPColorScaleAxisRectPrivate : public QCPAxisRect +{ + Q_OBJECT +public: + explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); +protected: + QCPColorScale *mParentColorScale; + QImage mGradientImage; + bool mGradientImageInvalidated; + // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale + using QCPAxisRect::calculateAutoMargin; + using QCPAxisRect::mousePressEvent; + using QCPAxisRect::mouseMoveEvent; + using QCPAxisRect::mouseReleaseEvent; + using QCPAxisRect::wheelEvent; + using QCPAxisRect::update; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + void updateGradientImage(); + Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); + Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); + friend class QCPColorScale; +}; + + +class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) + Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPColorScale(QCustomPlot *parentPlot); + virtual ~QCPColorScale(); + + // getters: + QCPAxis *axis() const { return mColorAxis.data(); } + QCPAxis::AxisType type() const { return mType; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + QCPColorGradient gradient() const { return mGradient; } + QString label() const; + int barWidth () const { return mBarWidth; } + bool rangeDrag() const; + bool rangeZoom() const; + + // setters: + void setType(QCPAxis::AxisType type); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setLabel(const QString &str); + void setBarWidth(int width); + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + + // non-property methods: + QList colorMaps() const; + void rescaleDataRange(bool onlyVisibleMaps); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPAxis::AxisType mType; + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorGradient mGradient; + int mBarWidth; + + // non-property members: + QPointer mAxisRect; + QPointer mColorAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPColorScale) + + friend class QCPColorScaleAxisRectPrivate; +}; + + +/* end of 'src/layoutelements/layoutelement-colorscale.h' */ + + +/* including file 'src/plottables/plottable-graph.h', size 9294 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPGraphData +{ +public: + QCPGraphData(); + QCPGraphData(double key, double value, int status=0); + + inline double sortKey() const { return key; } + inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + inline int mainStatus() const { return status; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double key, value; + int status; +}; +Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPGraphDataContainer + + Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPGraph holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPGraphData, QCPGraph::setData +*/ +typedef QCPDataContainer QCPGraphDataContainer; + +class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) + Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) + /// \endcond +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point + ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point + ,lsStepCenter ///< line is drawn as steps where the step is in between two data points + ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line + }; + Q_ENUMS(LineStyle) + + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPGraph(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + LineStyle lineStyle() const { return mLineStyle; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } + bool adaptiveSampling() const { return mAdaptiveSampling; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted=false); + void setLineStyle(LineStyle ls); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setChannelFillGraph(QCPGraph *targetGraph); + void setAdaptiveSampling(bool enabled); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted=false); + void addData(double key, double value, int status=0); + + /** + * @brief value 根据key值,查找value + */ + double value(const double &key); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + LineStyle mLineStyle; + QCPScatterStyle mScatterStyle; + int mScatterSkip; + QPointer mChannelFillGraph; + bool mAdaptiveSampling; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawFill(QCPPainter *painter, QVector *lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; + virtual void drawLinePlot(QCPPainter *painter, const QVector &lines, const QVector &status) const; + virtual void drawImpulsePlot(QCPPainter *painter, const QVector &lines) const; + + virtual void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; + virtual void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + void getLines(QVector *lines, const QCPDataRange &dataRange, QVector *status) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange) const; + void dataToLines(const QVector &data, QVector &lines, QVector &status) const; + void dataToStepLeftLines(const QVector &data, QVector &lines, QVector &status) const; + void dataToStepRightLines(const QVector &data, QVector &lines, QVector &status) const; + void dataToStepCenterLines(const QVector &data, QVector &lines, QVector &status) const; + void dataToImpulseLines(const QVector &data, QVector &lines, QVector &status) const; + QVector getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const; + QVector > getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const; + bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const; + QPointF getFillBasePoint(QPointF matchingDataPoint) const; + const QPolygonF getFillPolygon(const QVector *lineData, QCPDataRange segment) const; + const QPolygonF getChannelFillPolygon(const QVector *lineData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const; + int findIndexBelowX(const QVector *data, double x) const; + int findIndexAboveX(const QVector *data, double x) const; + int findIndexBelowY(const QVector *data, double y) const; + int findIndexAboveY(const QVector *data, double y) const; + double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPGraph::LineStyle) + +/* end of 'src/plottables/plottable-graph.h' */ + + +/* including file 'src/plottables/plottable-curve.h', size 7409 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPCurveData +{ +public: + QCPCurveData(); + QCPCurveData(double t, double key, double value); + + inline double sortKey() const { return t; } + inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } + inline static bool sortKeyIsMainKey() { return false; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double t, key, value; +}; +Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPCurveDataContainer + + Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a + sortKey() (returning \a t) is different from \a mainKey() (returning \a key). + + This template instantiation is the container in which QCPCurve holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPCurveData, QCPCurve::setData +*/ +typedef QCPDataContainer QCPCurveDataContainer; + +class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + /// \endcond +public: + /*! + Defines how the curve's line is represented visually in the plot. The line is drawn with the + current pen of the curve (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) + ,lsLine ///< Data points are connected with a straight line + }; + Q_ENUMS(LineStyle) + + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPCurve(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + LineStyle lineStyle() const { return mLineStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void setData(const QVector &keys, const QVector &values); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setLineStyle(LineStyle style); + + // non-property methods: + void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(const QVector &keys, const QVector &values); + void addData(double t, double key, double value); + void addData(double key, double value); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPScatterStyle mScatterStyle; + int mScatterSkip; + LineStyle mLineStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawCurveLine(QCPPainter *painter, const QVector &lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const; + + // non-virtual methods: + void getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const; + int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + bool mayTraverse(int prevRegion, int currentRegion) const; + bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const; + void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const; + double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPCurve::LineStyle) + +/* end of 'src/plottables/plottable-curve.h' */ + + +/* including file 'src/plottables/plottable-bars.h', size 8924 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPBarsGroup : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) + Q_PROPERTY(double spacing READ spacing WRITE setSpacing) + /// \endcond +public: + /*! + Defines the ways the spacing between bars in the group can be specified. Thus it defines what + the number passed to \ref setSpacing actually means. + + \see setSpacingType, setSpacing + */ + enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels + ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size + ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(SpacingType) + + QCPBarsGroup(QCustomPlot *parentPlot); + virtual ~QCPBarsGroup(); + + // getters: + SpacingType spacingType() const { return mSpacingType; } + double spacing() const { return mSpacing; } + + // setters: + void setSpacingType(SpacingType spacingType); + void setSpacing(double spacing); + + // non-virtual methods: + QList bars() const { return mBars; } + QCPBars* bars(int index) const; + int size() const { return mBars.size(); } + bool isEmpty() const { return mBars.isEmpty(); } + void clear(); + bool contains(QCPBars *bars) const { return mBars.contains(bars); } + void append(QCPBars *bars); + void insert(int i, QCPBars *bars); + void remove(QCPBars *bars); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + SpacingType mSpacingType; + double mSpacing; + QList mBars; + + // non-virtual methods: + void registerBars(QCPBars *bars); + void unregisterBars(QCPBars *bars); + + // virtual methods: + double keyPixelOffset(const QCPBars *bars, double keyCoord); + double getPixelSpacing(const QCPBars *bars, double keyCoord); + +private: + Q_DISABLE_COPY(QCPBarsGroup) + + friend class QCPBars; +}; +Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) + + +class QCP_LIB_DECL QCPBarsData +{ +public: + QCPBarsData(); + QCPBarsData(double key, double value); + + inline double sortKey() const { return key; } + inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here + + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPBarsDataContainer + + Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPBars holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPBarsData, QCPBars::setData +*/ +typedef QCPDataContainer QCPBarsDataContainer; + +class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) + Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) + Q_PROPERTY(double stackingGap READ stackingGap WRITE setStackingGap) + Q_PROPERTY(QCPBars* barBelow READ barBelow) + Q_PROPERTY(QCPBars* barAbove READ barAbove) + /// \endcond +public: + /*! + Defines the ways the width of the bar can be specified. Thus it defines what the number passed + to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< Bar width is in absolute pixels + ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size + ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPBars(); + + // getters: + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + QCPBarsGroup *barsGroup() const { return mBarsGroup; } + double baseValue() const { return mBaseValue; } + double stackingGap() const { return mStackingGap; } + QCPBars *barBelow() const { return mBarBelow.data(); } + QCPBars *barAbove() const { return mBarAbove.data(); } + QSharedPointer data() const { return mDataContainer; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setBarsGroup(QCPBarsGroup *barsGroup); + void setBaseValue(double baseValue); + void setStackingGap(double pixels); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + void moveBelow(QCPBars *bars); + void moveAbove(QCPBars *bars); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + WidthType mWidthType; + QCPBarsGroup *mBarsGroup; + double mBaseValue; + double mStackingGap; + QPointer mBarBelow, mBarAbove; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const; + QRectF getBarRect(double key, double value) const; + void getPixelWidth(double key, double &lower, double &upper) const; + double getStackedBaseValue(double key, bool positive) const; + static void connectBars(QCPBars* lower, QCPBars* upper); + + friend class QCustomPlot; + friend class QCPLegend; + friend class QCPBarsGroup; +}; +Q_DECLARE_METATYPE(QCPBars::WidthType) + +/* end of 'src/plottables/plottable-bars.h' */ + + +/* including file 'src/plottables/plottable-statisticalbox.h', size 7516 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPStatisticalBoxData +{ +public: + QCPStatisticalBoxData(); + QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector& outliers=QVector()); + + inline double sortKey() const { return key; } + inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return median; } + + inline QCPRange valueRange() const + { + QCPRange result(minimum, maximum); + for (QVector::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); ++it) + result.expand(*it); + return result; + } + + double key, minimum, lowerQuartile, median, upperQuartile, maximum; + QVector outliers; +}; +Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); + + +/*! \typedef QCPStatisticalBoxDataContainer + + Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPStatisticalBox holds its data. For + details about the generic container, see the documentation of the class template \ref + QCPDataContainer. + + \see QCPStatisticalBoxData, QCPStatisticalBox::setData +*/ +typedef QCPDataContainer QCPStatisticalBoxDataContainer; + +class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) + Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) + Q_PROPERTY(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased) + Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) + Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) + /// \endcond +public: + explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + QSharedPointer data() const { return mDataContainer; } + double width() const { return mWidth; } + double whiskerWidth() const { return mWhiskerWidth; } + QPen whiskerPen() const { return mWhiskerPen; } + QPen whiskerBarPen() const { return mWhiskerBarPen; } + bool whiskerAntialiased() const { return mWhiskerAntialiased; } + QPen medianPen() const { return mMedianPen; } + QCPScatterStyle outlierStyle() const { return mOutlierStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void setWidth(double width); + void setWhiskerWidth(double width); + void setWhiskerPen(const QPen &pen); + void setWhiskerBarPen(const QPen &pen); + void setWhiskerAntialiased(bool enabled); + void setMedianPen(const QPen &pen); + void setOutlierStyle(const QCPScatterStyle &style); + + // non-property methods: + void addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers=QVector()); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + double mWhiskerWidth; + QPen mWhiskerPen, mWhiskerBarPen; + bool mWhiskerAntialiased; + QPen mMedianPen; + QCPScatterStyle mOutlierStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const; + QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-statisticalbox.h' */ + + +/* including file 'src/plottables/plottable-colormap.h', size 7070 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPColorMapData +{ +public: + QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); + ~QCPColorMapData(); + QCPColorMapData(const QCPColorMapData &other); + QCPColorMapData &operator=(const QCPColorMapData &other); + + // getters: + int keySize() const { return mKeySize; } + int valueSize() const { return mValueSize; } + QCPRange keyRange() const { return mKeyRange; } + QCPRange valueRange() const { return mValueRange; } + QCPRange dataBounds() const { return mDataBounds; } + double data(double key, double value); + double cell(int keyIndex, int valueIndex); + unsigned char alpha(int keyIndex, int valueIndex); + + // setters: + void setSize(int keySize, int valueSize); + void setKeySize(int keySize); + void setValueSize(int valueSize); + void setRange(const QCPRange &keyRange, const QCPRange &valueRange); + void setKeyRange(const QCPRange &keyRange); + void setValueRange(const QCPRange &valueRange); + void setData(double key, double value, double z); + void setCell(int keyIndex, int valueIndex, double z); + void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); + + // non-property methods: + void recalculateDataBounds(); + void clear(); + void clearAlpha(); + void fill(double z); + void fillAlpha(unsigned char alpha); + bool isEmpty() const { return mIsEmpty; } + void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; + void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; + +protected: + // property members: + int mKeySize, mValueSize; + QCPRange mKeyRange, mValueRange; + bool mIsEmpty; + + // non-property members: + double *mData; + unsigned char *mAlpha; + QCPRange mDataBounds; + bool mDataModified; + + bool createAlpha(bool initializeOpaque=true); + + friend class QCPColorMap; +}; + + +class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) + Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) + Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) + /// \endcond +public: + explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPColorMap(); + + // getters: + QCPColorMapData *data() const { return mMapData; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + bool interpolate() const { return mInterpolate; } + bool tightBoundary() const { return mTightBoundary; } + QCPColorGradient gradient() const { return mGradient; } + QCPColorScale *colorScale() const { return mColorScale.data(); } + + // setters: + void setData(QCPColorMapData *data, bool copy=false); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setInterpolate(bool enabled); + void setTightBoundary(bool enabled); + void setColorScale(QCPColorScale *colorScale); + + // non-property methods: + void rescaleDataRange(bool recalculateDataBounds=false); + Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorMapData *mMapData; + QCPColorGradient mGradient; + bool mInterpolate; + bool mTightBoundary; + QPointer mColorScale; + + // non-property members: + QImage mMapImage, mUndersampledMapImage; + QPixmap mLegendIcon; + bool mMapImageInvalidated; + + // introduced virtual methods: + virtual void updateMapImage(); + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-colormap.h' */ + + +/* including file 'src/plottables/plottable-financial.h', size 8622 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPFinancialData +{ +public: + QCPFinancialData(); + QCPFinancialData(double key, double open, double high, double low, double close); + + inline double sortKey() const { return key; } + inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return open; } + + inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them + + double key, open, high, low, close; +}; +Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPFinancialDataContainer + + Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPFinancial holds its data. For details + about the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPFinancialData, QCPFinancial::setData +*/ +typedef QCPDataContainer QCPFinancialDataContainer; + +class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) + Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) + Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) + Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) + Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) + /// \endcond +public: + /*! + Defines the ways the width of the financial bar can be specified. Thus it defines what the + number passed to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< width is in absolute pixels + ,wtAxisRectRatio ///< width is given by a fraction of the axis rect size + ,wtPlotCoords ///< width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + /*! + Defines the possible representations of OHLC data in the plot. + + \see setChartStyle + */ + enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation + ,csCandlestick ///< Candlestick representation + }; + Q_ENUMS(ChartStyle) + + explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPFinancial(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + ChartStyle chartStyle() const { return mChartStyle; } + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + bool twoColored() const { return mTwoColored; } + QBrush brushPositive() const { return mBrushPositive; } + QBrush brushNegative() const { return mBrushNegative; } + QPen penPositive() const { return mPenPositive; } + QPen penNegative() const { return mPenNegative; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void setChartStyle(ChartStyle style); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setTwoColored(bool twoColored); + void setBrushPositive(const QBrush &brush); + void setBrushNegative(const QBrush &brush); + void setPenPositive(const QPen &pen); + void setPenNegative(const QPen &pen); + + // non-property methods: + void addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void addData(double key, double open, double high, double low, double close); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // static methods: + static QCPFinancialDataContainer timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); + +protected: + // property members: + ChartStyle mChartStyle; + double mWidth; + WidthType mWidthType; + bool mTwoColored; + QBrush mBrushPositive, mBrushNegative; + QPen mPenPositive, mPenNegative; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + double getPixelWidth(double key, double keyPixel) const; + double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const; + QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) + +/* end of 'src/plottables/plottable-financial.h' */ + + +/* including file 'src/plottables/plottable-errorbar.h', size 7727 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPErrorBarsData +{ +public: + QCPErrorBarsData(); + explicit QCPErrorBarsData(double error); + QCPErrorBarsData(double errorMinus, double errorPlus); + + double errorMinus, errorPlus; +}; +Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPErrorBarsDataContainer + + Container for storing \ref QCPErrorBarsData points. It is a typedef for QVector<\ref + QCPErrorBarsData>. + + This is the container in which \ref QCPErrorBars holds its data. Unlike most other data + containers for plottables, it is not based on \ref QCPDataContainer. This is because the error + bars plottable is special in that it doesn't store its own key and value coordinate per error + bar. It adopts the key and value from the plottable to which the error bars shall be applied + (\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a + sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices + of the other plottable's data. + + \see QCPErrorBarsData, QCPErrorBars::setData +*/ +typedef QVector QCPErrorBarsDataContainer; + +class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QSharedPointer data READ data WRITE setData) + Q_PROPERTY(QCPAbstractPlottable* dataPlottable READ dataPlottable WRITE setDataPlottable) + Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap) + /// \endcond +public: + + /*! + Defines in which orientation the error bars shall appear. If your data needs both error + dimensions, create two \ref QCPErrorBars with different \ref ErrorType. + + \see setErrorType + */ + enum ErrorType { etKeyError ///< The errors are for the key dimension (bars appear parallel to the key axis) + ,etValueError ///< The errors are for the value dimension (bars appear parallel to the value axis) + }; + Q_ENUMS(ErrorType) + + explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPErrorBars(); + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); } + ErrorType errorType() const { return mErrorType; } + double whiskerWidth() const { return mWhiskerWidth; } + double symbolGap() const { return mSymbolGap; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &error); + void setData(const QVector &errorMinus, const QVector &errorPlus); + void setDataPlottable(QCPAbstractPlottable* plottable); + void setErrorType(ErrorType type); + void setWhiskerWidth(double pixels); + void setSymbolGap(double pixels); + + // non-property methods: + void addData(const QVector &error); + void addData(const QVector &errorMinus, const QVector &errorPlus); + void addData(double error); + void addData(double errorMinus, double errorPlus); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const Q_DECL_OVERRIDE; + virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; + virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; + virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; + virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer mDataContainer; + QPointer mDataPlottable; + ErrorType mErrorType; + double mWhiskerWidth; + double mSymbolGap; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const; + void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const; + // helpers: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + bool errorBarVisible(int index) const; + bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-errorbar.h' */ + + +/* including file 'src/items/item-straightline.h', size 3117 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemStraightLine(QCustomPlot *parentPlot); + virtual ~QCPItemStraightLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const point1; + QCPItemPosition * const point2; + +protected: + // property members: + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-straightline.h' */ + + +/* including file 'src/items/item-line.h', size 3407 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemLine(QCustomPlot *parentPlot); + virtual ~QCPItemLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-line.h' */ + + +/* including file 'src/items/item-curve.h', size 3379 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemCurve(QCustomPlot *parentPlot); + virtual ~QCPItemCurve(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const startDir; + QCPItemPosition * const endDir; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; + +/* end of 'src/items/item-curve.h' */ + + +/* including file 'src/items/item-rect.h', size 3688 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemRect(QCustomPlot *parentPlot); + virtual ~QCPItemRect(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-rect.h' */ + + +/* including file 'src/items/item-text.h', size 5554 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemText : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) + Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) + Q_PROPERTY(double rotation READ rotation WRITE setRotation) + Q_PROPERTY(QMargins padding READ padding WRITE setPadding) + /// \endcond +public: + explicit QCPItemText(QCustomPlot *parentPlot); + virtual ~QCPItemText(); + + // getters: + QColor color() const { return mColor; } + QColor selectedColor() const { return mSelectedColor; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont font() const { return mFont; } + QFont selectedFont() const { return mSelectedFont; } + QString text() const { return mText; } + Qt::Alignment positionAlignment() const { return mPositionAlignment; } + Qt::Alignment textAlignment() const { return mTextAlignment; } + double rotation() const { return mRotation; } + QMargins padding() const { return mPadding; } + + // setters; + void setColor(const QColor &color); + void setSelectedColor(const QColor &color); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setFont(const QFont &font); + void setSelectedFont(const QFont &font); + void setText(const QString &text); + void setPositionAlignment(Qt::Alignment alignment); + void setTextAlignment(Qt::Alignment alignment); + void setRotation(double degrees); + void setPadding(const QMargins &padding); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const position; + QCPItemAnchor * const topLeft; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRight; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QColor mColor, mSelectedColor; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QFont mFont, mSelectedFont; + QString mText; + Qt::Alignment mPositionAlignment; + Qt::Alignment mTextAlignment; + double mRotation; + QMargins mPadding; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; + QFont mainFont() const; + QColor mainColor() const; + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-text.h' */ + + +/* including file 'src/items/item-ellipse.h', size 3868 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemEllipse(QCustomPlot *parentPlot); + virtual ~QCPItemEllipse(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const topLeftRim; + QCPItemAnchor * const top; + QCPItemAnchor * const topRightRim; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRightRim; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeftRim; + QCPItemAnchor * const left; + QCPItemAnchor * const center; + +protected: + enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-ellipse.h' */ + + +/* including file 'src/items/item-pixmap.h', size 4373 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) + Q_PROPERTY(bool scaled READ scaled WRITE setScaled) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) + Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemPixmap(QCustomPlot *parentPlot); + virtual ~QCPItemPixmap(); + + // getters: + QPixmap pixmap() const { return mPixmap; } + bool scaled() const { return mScaled; } + Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } + Qt::TransformationMode transformationMode() const { return mTransformationMode; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPixmap(const QPixmap &pixmap); + void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPixmap mPixmap; + QPixmap mScaledPixmap; + bool mScaled; + bool mScaledPixmapInvalidated; + Qt::AspectRatioMode mAspectRatioMode; + Qt::TransformationMode mTransformationMode; + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); + QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-pixmap.h' */ + + +/* including file 'src/items/item-tracer.h', size 4762 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(double size READ size WRITE setSize) + Q_PROPERTY(TracerStyle style READ style WRITE setStyle) + Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) + Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) + Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) + /// \endcond +public: + /*! + The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. + + \see setStyle + */ + enum TracerStyle { tsNone ///< The tracer is not visible + ,tsPlus ///< A plus shaped crosshair with limited size + ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect + ,tsCircle ///< A circle + ,tsSquare ///< A square + }; + Q_ENUMS(TracerStyle) + + explicit QCPItemTracer(QCustomPlot *parentPlot); + QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush, const QList &alarmStatusList); + virtual ~QCPItemTracer(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + double size() const { return mSize; } + TracerStyle style() const { return mStyle; } + QCPGraph *graph() const { return mGraph; } + double graphKey() const { return mGraphKey; } + bool interpolating() const { return mInterpolating; } + int type() const { return mType; } + qint64 timeStamp() const { return mTimeStamp; } + QMap hidePoint() const { return m_hidePoint; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setSize(double size); + void setStyle(TracerStyle style); + void setGraph(QCPGraph *graph); + void setGraphKey(double key); + void setHidePoint(const QMultiMap &hidePoint); + void addHidePoint(const qint64 &time, const QString &tag); + void setInterpolating(bool enabled); + + void setType(const int &type); + void setTimeStamp(const qint64 &timeStamp); + void setInfo(const QStringList infos); + + void showTips(); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updatePosition(); + + QCPItemPosition * const position; + +signals: + void itemTracerHoverd(const qint64 &time, const QMap& timeTag, const QList &alarmStatusList); + +protected: + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + double mSize; + TracerStyle mStyle; + QCPGraph *mGraph; + QMultiMap m_hidePoint; + double mGraphKey; + bool mInterpolating; + int mType; + qint64 mTimeStamp; + QStringList m_infos; + QList m_alarmStatusList; + int hovFlag; + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + + + virtual void mousePressEvent (QMouseEvent *event, const QVariant &details); + + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; +Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle) + +/* end of 'src/items/item-tracer.h' */ + + +/* including file 'src/items/item-bracket.h', size 3969 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(double length READ length WRITE setLength) + Q_PROPERTY(BracketStyle style READ style WRITE setStyle) + /// \endcond +public: + /*! + Defines the various visual shapes of the bracket item. The appearance can be further modified + by \ref setLength and \ref setPen. + + \see setStyle + */ + enum BracketStyle { bsSquare ///< A brace with angled edges + ,bsRound ///< A brace with round edges + ,bsCurly ///< A curly brace + ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression + }; + Q_ENUMS(BracketStyle) + + explicit QCPItemBracket(QCustomPlot *parentPlot); + virtual ~QCPItemBracket(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + double length() const { return mLength; } + BracketStyle style() const { return mStyle; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setLength(double length); + void setStyle(BracketStyle style); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const left; + QCPItemPosition * const right; + QCPItemAnchor * const center; + +protected: + // property members: + enum AnchorIndex {aiCenter}; + QPen mPen, mSelectedPen; + double mLength; + BracketStyle mStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; +Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle) + +/* end of 'src/items/item-bracket.h' */ + + +#endif // QCUSTOMPLOT_H + diff --git a/product/src/gui/plugin/TrendCurves/widgets/CCalendarWidget.cpp b/product/src/gui/plugin/TrendCurves/widgets/CCalendarWidget.cpp index ec4a8700..84f59f65 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CCalendarWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/CCalendarWidget.cpp @@ -1,41 +1,41 @@ -#include "CCalendarWidget.h" -#include - -CCalendarWidget::CCalendarWidget(QWidget *parent) - : QCalendarWidget(parent) -{ - setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); - setAttribute(Qt::WA_DeleteOnClose); - setHorizontalHeaderFormat(NoHorizontalHeader); - setVerticalHeaderFormat(NoVerticalHeader); - - setMinimumDate(QDate(1970, 0, 0)); - setMaximumDate(QDate(2037, 12, 31)); - - installEventFilter(this); - -} - -CCalendarWidget::~CCalendarWidget() -{ -} - -QSize CCalendarWidget::sizeHint() const -{ - return QSize(260, 180); -} - - -bool CCalendarWidget::eventFilter(QObject *object, QEvent *event) -{ - if (object == this) - { - if (QEvent::WindowDeactivate == event->type()) - { - this->close(); - event->accept(); - return true; - } - } - return QWidget::eventFilter(object, event); -} +#include "CCalendarWidget.h" +#include + +CCalendarWidget::CCalendarWidget(QWidget *parent) + : QCalendarWidget(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_DeleteOnClose); + setHorizontalHeaderFormat(NoHorizontalHeader); + setVerticalHeaderFormat(NoVerticalHeader); + + setMinimumDate(QDate(1970, 0, 0)); + setMaximumDate(QDate(2037, 12, 31)); + + installEventFilter(this); + +} + +CCalendarWidget::~CCalendarWidget() +{ +} + +QSize CCalendarWidget::sizeHint() const +{ + return QSize(260, 180); +} + + +bool CCalendarWidget::eventFilter(QObject *object, QEvent *event) +{ + if (object == this) + { + if (QEvent::WindowDeactivate == event->type()) + { + this->close(); + event->accept(); + return true; + } + } + return QWidget::eventFilter(object, event); +} diff --git a/product/src/gui/plugin/TrendCurves/widgets/CCalendarWidget.h b/product/src/gui/plugin/TrendCurves/widgets/CCalendarWidget.h index bc3cfda1..aa30d8a2 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CCalendarWidget.h +++ b/product/src/gui/plugin/TrendCurves/widgets/CCalendarWidget.h @@ -1,19 +1,19 @@ -#ifndef CCALENDARWIDGET_H -#define CCALENDARWIDGET_H - -#include - -class CCalendarWidget : public QCalendarWidget -{ - Q_OBJECT -public: - CCalendarWidget(QWidget *parent = Q_NULLPTR); - ~CCalendarWidget(); - -protected: - QSize sizeHint() const; - - bool eventFilter(QObject *object, QEvent *event); -}; - -#endif // CCALENDARWIDGET_H +#ifndef CCALENDARWIDGET_H +#define CCALENDARWIDGET_H + +#include + +class CCalendarWidget : public QCalendarWidget +{ + Q_OBJECT +public: + CCalendarWidget(QWidget *parent = Q_NULLPTR); + ~CCalendarWidget(); + +protected: + QSize sizeHint() const; + + bool eventFilter(QObject *object, QEvent *event); +}; + +#endif // CCALENDARWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves/widgets/CEditCollectWidget.cpp b/product/src/gui/plugin/TrendCurves/widgets/CEditCollectWidget.cpp index 8eac30d7..5ef41100 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CEditCollectWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/CEditCollectWidget.cpp @@ -1,76 +1,76 @@ -#include "CEditCollectWidget.h" -#include -#include -#include -#include -#include -#include - -CEditCollectWidget::CEditCollectWidget(QWidget *parent) : - QDialog(parent) -{ -// installEventFilter(this); -// setAttribute(Qt::WA_DeleteOnClose); - setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); - - QHBoxLayout * pTopLayout = new QHBoxLayout(); - QLabel * label = new QLabel(tr("趋势名称:"), this); - m_pNameEdit = new QLineEdit(this); - m_pNameEdit->setMinimumHeight(25); - pTopLayout->addWidget(label, 0); - pTopLayout->addWidget(m_pNameEdit, 10); - pTopLayout->setMargin(0); - QHBoxLayout * pBottomLayout = new QHBoxLayout(); - QPushButton * ok = new QPushButton(tr("确定"), this); - QPushButton * cancle = new QPushButton(tr("取消"), this); - pBottomLayout->addStretch(10); - pBottomLayout->addWidget(ok, 1); - pBottomLayout->addWidget(cancle, 1); - pBottomLayout->setMargin(0); - QVBoxLayout * layout = new QVBoxLayout(this); - layout->addLayout(pTopLayout, 1); - layout->addLayout(pBottomLayout, 1); - setLayout(layout); - layout->setMargin(0); - setContentsMargins(5,0,5,0); - setMaximumHeight(75); - - connect(ok, &QPushButton::clicked, this, [=]() { - emit acceptedInput(); - }); - connect(cancle, &QPushButton::clicked, this, [=]() { hide(); }); -} - -CEditCollectWidget::~CEditCollectWidget() -{ - -} - -void CEditCollectWidget::clear() -{ - m_pNameEdit->clear(); -} - -QString CEditCollectWidget::text() -{ - return m_pNameEdit->text(); -} - -void CEditCollectWidget::setEditFocus() -{ - m_pNameEdit->setFocus(); -} - -//bool CEditCollectWidget::eventFilter(QObject *object, QEvent *event) -//{ -// if (object == this) -// { -// if (QEvent::WindowDeactivate == event->type()) -// { -// this->hide(); -// event->accept(); -// return true; -// } -// } -// return QDialog::eventFilter(object, event); -//} +#include "CEditCollectWidget.h" +#include +#include +#include +#include +#include +#include + +CEditCollectWidget::CEditCollectWidget(QWidget *parent) : + QDialog(parent) +{ +// installEventFilter(this); +// setAttribute(Qt::WA_DeleteOnClose); + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + + QHBoxLayout * pTopLayout = new QHBoxLayout(); + QLabel * label = new QLabel(tr("趋势名称:"), this); + m_pNameEdit = new QLineEdit(this); + m_pNameEdit->setMinimumHeight(25); + pTopLayout->addWidget(label, 0); + pTopLayout->addWidget(m_pNameEdit, 10); + pTopLayout->setMargin(0); + QHBoxLayout * pBottomLayout = new QHBoxLayout(); + QPushButton * ok = new QPushButton(tr("确定"), this); + QPushButton * cancle = new QPushButton(tr("取消"), this); + pBottomLayout->addStretch(10); + pBottomLayout->addWidget(ok, 1); + pBottomLayout->addWidget(cancle, 1); + pBottomLayout->setMargin(0); + QVBoxLayout * layout = new QVBoxLayout(this); + layout->addLayout(pTopLayout, 1); + layout->addLayout(pBottomLayout, 1); + setLayout(layout); + layout->setMargin(0); + setContentsMargins(5,0,5,0); + setMaximumHeight(75); + + connect(ok, &QPushButton::clicked, this, [=]() { + emit acceptedInput(); + }); + connect(cancle, &QPushButton::clicked, this, [=]() { hide(); }); +} + +CEditCollectWidget::~CEditCollectWidget() +{ + +} + +void CEditCollectWidget::clear() +{ + m_pNameEdit->clear(); +} + +QString CEditCollectWidget::text() +{ + return m_pNameEdit->text(); +} + +void CEditCollectWidget::setEditFocus() +{ + m_pNameEdit->setFocus(); +} + +//bool CEditCollectWidget::eventFilter(QObject *object, QEvent *event) +//{ +// if (object == this) +// { +// if (QEvent::WindowDeactivate == event->type()) +// { +// this->hide(); +// event->accept(); +// return true; +// } +// } +// return QDialog::eventFilter(object, event); +//} diff --git a/product/src/gui/plugin/TrendCurves/widgets/CEditCollectWidget.h b/product/src/gui/plugin/TrendCurves/widgets/CEditCollectWidget.h index bfe5dc03..6657c7ab 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CEditCollectWidget.h +++ b/product/src/gui/plugin/TrendCurves/widgets/CEditCollectWidget.h @@ -1,30 +1,30 @@ -#ifndef CEDITCOLLECTWIDGET_H -#define CEDITCOLLECTWIDGET_H - -#include - -class QLineEdit; -class CEditCollectWidget : public QDialog -{ - Q_OBJECT -public: - explicit CEditCollectWidget(QWidget *parent = 0); - ~CEditCollectWidget(); - - void clear(); - - QString text(); - - void setEditFocus(); - -signals: - void acceptedInput(); - -//protected: -// bool eventFilter(QObject *object, QEvent *event); - -private: - QLineEdit * m_pNameEdit; -}; - -#endif // CEDITCOLLECTWIDGET_H +#ifndef CEDITCOLLECTWIDGET_H +#define CEDITCOLLECTWIDGET_H + +#include + +class QLineEdit; +class CEditCollectWidget : public QDialog +{ + Q_OBJECT +public: + explicit CEditCollectWidget(QWidget *parent = 0); + ~CEditCollectWidget(); + + void clear(); + + QString text(); + + void setEditFocus(); + +signals: + void acceptedInput(); + +//protected: +// bool eventFilter(QObject *object, QEvent *event); + +private: + QLineEdit * m_pNameEdit; +}; + +#endif // CEDITCOLLECTWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.cpp b/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.cpp index 702f5adc..e8bce0f9 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.cpp @@ -1,221 +1,221 @@ -#include -#include -#include -#include "CSWitchButton.h" - -CSWitchButton::CSWitchButton(QWidget *parent) - : QWidget(parent), - m_bChecked(false), - m_background(Qt::green), - m_checkedColor(Qt::red), - m_disabledColor(Qt::darkGray), - m_handleColor(Qt::white), - m_textColor(Qt::blue), - m_radius(5.0), - m_borderColor(Qt::gray), - m_nHeight(12), - m_nMargin(0) -{ - setCursor(Qt::PointingHandCursor); - - connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); -} - -// 绘制开关 -void CSWitchButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter painter(this); - painter.setPen(m_borderColor); - painter.setRenderHint(QPainter::Antialiasing); - - QPainterPath path; - QColor background; - QColor handleColor; - QString text; - if (isEnabled()) { // 可用状态 - if (m_bChecked) { // 打开状态 - background = m_checkedColor; - handleColor = m_handleColor; - text = m_strText; - } else { //关闭状态 - background = m_background; - handleColor = m_handleColor; - text = m_strCheckText; - } - } else { // 不可用状态 - background = m_disabledColor; - handleColor = m_disabledColor; - } - // 绘制边界 - painter.setBrush(background); - - path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width(), height()), m_radius, m_radius); - painter.drawPath(path.simplified()); - - // 绘制滑块 - painter.setBrush(handleColor); - painter.drawRoundedRect(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), width()/2, height()), m_radius, m_radius); - painter.setPen(m_textColor); - painter.drawText(QRectF(width()/2 - m_nX + (m_nHeight / 2), height()/5, width()/2, height()), text); -} - -// 鼠标按下事件 -void CSWitchButton::mousePressEvent(QMouseEvent *event) -{ - if (isEnabled()) { - if (event->buttons() & Qt::LeftButton) { - event->accept(); - } else { - event->ignore(); - } - } -} - -// 鼠标释放事件 - 切换开关状态、发射toggled()信号 -void CSWitchButton::mouseReleaseEvent(QMouseEvent *event) -{ - if (isEnabled()) { - if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { - event->accept(); - m_timer.start(10); - m_bChecked = !m_bChecked; - emit toggled(m_bChecked); - } else { - event->ignore(); - } - } -} - -// 大小改变事件 -void CSWitchButton::resizeEvent(QResizeEvent *event) -{ - m_nX = m_nHeight / 2; - m_nY = m_nHeight / 2; - QWidget::resizeEvent(event); -} - -// 默认大小 -QSize CSWitchButton::sizeHint() const -{ - return minimumSizeHint(); -} - -// 最小大小 -QSize CSWitchButton::minimumSizeHint() const -{ - return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); -} - -// 切换状态 - 滑动 -void CSWitchButton::onTimeout() -{ - if (m_bChecked) { - m_nX += 3; - if (m_nX >= width()/2 + m_nHeight / 2) - { - m_nX = width()/2 + m_nHeight / 2; - m_timer.stop(); - } - } else { - m_nX -= 3; - if (m_nX <= m_nHeight / 2) - { - m_nX = m_nHeight / 2; - m_timer.stop(); - } - } - update(); -} - -bool CSWitchButton::isToggled() -{ - return m_bChecked; -} - -void CSWitchButton::setToggle(bool checked) -{ - m_bChecked = checked; -} - -void CSWitchButton::setText(QString text) -{ - m_strText = text; -} - -void CSWitchButton::setCheckedText(QString text) -{ - m_strCheckText = text; -} - -QColor CSWitchButton::backgroundColor() -{ - return m_background; -} - -void CSWitchButton::setBackgroundColor(QColor color) -{ - m_background = color; -} - -QColor CSWitchButton::checkedColor() -{ - return m_checkedColor; -} - -void CSWitchButton::setCheckedColor(QColor color) -{ - m_checkedColor = color; -} - -QColor CSWitchButton::disableColor() -{ - return m_disabledColor; -} - -void CSWitchButton::setDisableColor(QColor color) -{ - m_disabledColor = color; -} - -QColor CSWitchButton::handleColor() -{ - return m_handleColor; -} - -void CSWitchButton::setHandleColor(QColor color) -{ - m_handleColor = color; -} - -QColor CSWitchButton::textColor() -{ - return m_textColor; -} - -void CSWitchButton::setTextColor(QColor color) -{ - m_textColor = color; -} - -qreal CSWitchButton::radius() -{ - return m_radius; -} - -void CSWitchButton::setRadius(qreal radius) -{ - m_radius = radius; -} - -QColor CSWitchButton::borderColor() -{ - return m_borderColor; -} - -void CSWitchButton::setBorderColor(QColor color) -{ - m_borderColor = color; -} - +#include +#include +#include +#include "CSWitchButton.h" + +CSWitchButton::CSWitchButton(QWidget *parent) + : QWidget(parent), + m_bChecked(false), + m_background(Qt::green), + m_checkedColor(Qt::red), + m_disabledColor(Qt::darkGray), + m_handleColor(Qt::white), + m_textColor(Qt::blue), + m_radius(5.0), + m_borderColor(Qt::gray), + m_nHeight(12), + m_nMargin(0) +{ + setCursor(Qt::PointingHandCursor); + + connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); +} + +// 绘制开关 +void CSWitchButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + painter.setPen(m_borderColor); + painter.setRenderHint(QPainter::Antialiasing); + + QPainterPath path; + QColor background; + QColor handleColor; + QString text; + if (isEnabled()) { // 可用状态 + if (m_bChecked) { // 打开状态 + background = m_checkedColor; + handleColor = m_handleColor; + text = m_strText; + } else { //关闭状态 + background = m_background; + handleColor = m_handleColor; + text = m_strCheckText; + } + } else { // 不可用状态 + background = m_disabledColor; + handleColor = m_disabledColor; + } + // 绘制边界 + painter.setBrush(background); + + path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width(), height()), m_radius, m_radius); + painter.drawPath(path.simplified()); + + // 绘制滑块 + painter.setBrush(handleColor); + painter.drawRoundedRect(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), width()/2, height()), m_radius, m_radius); + painter.setPen(m_textColor); + painter.drawText(QRectF(width()/2 - m_nX + (m_nHeight / 2), height()/5, width()/2, height()), text); +} + +// 鼠标按下事件 +void CSWitchButton::mousePressEvent(QMouseEvent *event) +{ + if (isEnabled()) { + if (event->buttons() & Qt::LeftButton) { + event->accept(); + } else { + event->ignore(); + } + } +} + +// 鼠标释放事件 - 切换开关状态、发射toggled()信号 +void CSWitchButton::mouseReleaseEvent(QMouseEvent *event) +{ + if (isEnabled()) { + if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { + event->accept(); + m_timer.start(10); + m_bChecked = !m_bChecked; + emit toggled(m_bChecked); + } else { + event->ignore(); + } + } +} + +// 大小改变事件 +void CSWitchButton::resizeEvent(QResizeEvent *event) +{ + m_nX = m_nHeight / 2; + m_nY = m_nHeight / 2; + QWidget::resizeEvent(event); +} + +// 默认大小 +QSize CSWitchButton::sizeHint() const +{ + return minimumSizeHint(); +} + +// 最小大小 +QSize CSWitchButton::minimumSizeHint() const +{ + return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); +} + +// 切换状态 - 滑动 +void CSWitchButton::onTimeout() +{ + if (m_bChecked) { + m_nX += 3; + if (m_nX >= width()/2 + m_nHeight / 2) + { + m_nX = width()/2 + m_nHeight / 2; + m_timer.stop(); + } + } else { + m_nX -= 3; + if (m_nX <= m_nHeight / 2) + { + m_nX = m_nHeight / 2; + m_timer.stop(); + } + } + update(); +} + +bool CSWitchButton::isToggled() +{ + return m_bChecked; +} + +void CSWitchButton::setToggle(bool checked) +{ + m_bChecked = checked; +} + +void CSWitchButton::setText(QString text) +{ + m_strText = text; +} + +void CSWitchButton::setCheckedText(QString text) +{ + m_strCheckText = text; +} + +QColor CSWitchButton::backgroundColor() +{ + return m_background; +} + +void CSWitchButton::setBackgroundColor(QColor color) +{ + m_background = color; +} + +QColor CSWitchButton::checkedColor() +{ + return m_checkedColor; +} + +void CSWitchButton::setCheckedColor(QColor color) +{ + m_checkedColor = color; +} + +QColor CSWitchButton::disableColor() +{ + return m_disabledColor; +} + +void CSWitchButton::setDisableColor(QColor color) +{ + m_disabledColor = color; +} + +QColor CSWitchButton::handleColor() +{ + return m_handleColor; +} + +void CSWitchButton::setHandleColor(QColor color) +{ + m_handleColor = color; +} + +QColor CSWitchButton::textColor() +{ + return m_textColor; +} + +void CSWitchButton::setTextColor(QColor color) +{ + m_textColor = color; +} + +qreal CSWitchButton::radius() +{ + return m_radius; +} + +void CSWitchButton::setRadius(qreal radius) +{ + m_radius = radius; +} + +QColor CSWitchButton::borderColor() +{ + return m_borderColor; +} + +void CSWitchButton::setBorderColor(QColor color) +{ + m_borderColor = color; +} + diff --git a/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.h b/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.h index abe3466d..f477243e 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.h +++ b/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.h @@ -1,92 +1,92 @@ -#ifndef SWITCHBUTTON_H -#define SWITCHBUTTON_H - -#include -#include - -class CSWitchButton : public QWidget -{ - Q_OBJECT - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) - Q_PROPERTY(QColor checkedColor READ checkedColor WRITE setCheckedColor) - Q_PROPERTY(QColor disableColor READ disableColor WRITE setDisableColor) - Q_PROPERTY(QColor handleColor READ handleColor WRITE setHandleColor) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) - Q_PROPERTY(qreal radius READ radius WRITE setRadius) - Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) - -public: - explicit CSWitchButton(QWidget *parent = 0); - - bool isToggled(); - - void setToggle(bool checked); - - void setText(QString text); - - void setCheckedText(QString text); - - QColor backgroundColor(); - void setBackgroundColor(QColor color); - - QColor checkedColor(); - void setCheckedColor(QColor color); - - QColor disableColor(); - void setDisableColor(QColor color); - - QColor handleColor(); - void setHandleColor(QColor color); - - QColor textColor(); - void setTextColor(QColor color); - - qreal radius(); - void setRadius(qreal radius); - - QColor borderColor(); - void setBorderColor(QColor color); - -protected: - // 绘制开关 - void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - - // 鼠标按下事件 - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // 鼠标释放事件 - 切换开关状态、发射toggled()信号 - void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // 大小改变事件 - void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; - - // 缺省大小 - QSize sizeHint() const Q_DECL_OVERRIDE; - QSize minimumSizeHint() const Q_DECL_OVERRIDE; - -signals: - void toggled(bool checked); - -private slots: - // 状态切换时,用于产生滑动效果 - void onTimeout(); - -private: - bool m_bChecked; - QColor m_background; - QColor m_checkedColor; - QColor m_disabledColor; - QColor m_handleColor; - QColor m_textColor; - qreal m_radius; - QColor m_borderColor; - QString m_strText; - QString m_strCheckText; - qreal m_nX{}; - qreal m_nY{}; - qint16 m_nHeight; - qint16 m_nMargin; - QTimer m_timer; -}; - -#endif // SWITCHBUTTON_H +#ifndef SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include +#include + +class CSWitchButton : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(QColor checkedColor READ checkedColor WRITE setCheckedColor) + Q_PROPERTY(QColor disableColor READ disableColor WRITE setDisableColor) + Q_PROPERTY(QColor handleColor READ handleColor WRITE setHandleColor) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(qreal radius READ radius WRITE setRadius) + Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) + +public: + explicit CSWitchButton(QWidget *parent = 0); + + bool isToggled(); + + void setToggle(bool checked); + + void setText(QString text); + + void setCheckedText(QString text); + + QColor backgroundColor(); + void setBackgroundColor(QColor color); + + QColor checkedColor(); + void setCheckedColor(QColor color); + + QColor disableColor(); + void setDisableColor(QColor color); + + QColor handleColor(); + void setHandleColor(QColor color); + + QColor textColor(); + void setTextColor(QColor color); + + qreal radius(); + void setRadius(qreal radius); + + QColor borderColor(); + void setBorderColor(QColor color); + +protected: + // 绘制开关 + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + // 鼠标按下事件 + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 鼠标释放事件 - 切换开关状态、发射toggled()信号 + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 大小改变事件 + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + + // 缺省大小 + QSize sizeHint() const Q_DECL_OVERRIDE; + QSize minimumSizeHint() const Q_DECL_OVERRIDE; + +signals: + void toggled(bool checked); + +private slots: + // 状态切换时,用于产生滑动效果 + void onTimeout(); + +private: + bool m_bChecked; + QColor m_background; + QColor m_checkedColor; + QColor m_disabledColor; + QColor m_handleColor; + QColor m_textColor; + qreal m_radius; + QColor m_borderColor; + QString m_strText; + QString m_strCheckText; + qreal m_nX{}; + qreal m_nY{}; + qint16 m_nHeight; + qint16 m_nMargin; + QTimer m_timer; +}; + +#endif // SWITCHBUTTON_H diff --git a/product/src/gui/plugin/TrendCurves/widgets/CSliderRangeWidget.cpp b/product/src/gui/plugin/TrendCurves/widgets/CSliderRangeWidget.cpp index 025c4d42..507cbad0 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CSliderRangeWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/CSliderRangeWidget.cpp @@ -1,72 +1,72 @@ -#include "CSliderRangeWidget.h" -#include -#include -#include -#include -#include - -CSliderRangeWidget::CSliderRangeWidget(QWidget *parent) : - QDialog(parent) -{ - setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); - - QGridLayout * pTopLayout = new QGridLayout(); - QLabel * label1 = new QLabel(tr("最小值:"), this); - m_lowSpin = new QSpinBox(this); - QLabel * label2 = new QLabel(tr("最大值:"), this); - m_upSpin = new QSpinBox(this); - QPushButton * ok = new QPushButton(tr("确定"), this); - QPushButton * cancle = new QPushButton(tr("取消"), this); - pTopLayout->addWidget(label1, 0, 0, 1, 1); - pTopLayout->addWidget(m_lowSpin, 0, 1, 1, 1); - pTopLayout->addWidget(label2, 1, 0, 1, 1); - pTopLayout->addWidget(m_upSpin, 1, 1, 1, 1); - pTopLayout->addWidget(ok, 2, 0, 1, 1); - pTopLayout->addWidget(cancle, 2, 1, 1, 1); - pTopLayout->setMargin(0); - setLayout(pTopLayout); - setContentsMargins(5,3,5,3); - - connect(ok, &QPushButton::clicked, this, [=]() { - emit acceptedInput(); - }); - connect(cancle, &QPushButton::clicked, this, [=]() { hide(); }); -} - -CSliderRangeWidget::~CSliderRangeWidget() -{ - -} - -void CSliderRangeWidget::setLowValue(int value) -{ - m_lowSpin->setValue(value); -} - -void CSliderRangeWidget::setUpValue(int value) -{ - m_upSpin->setValue(value); -} - -void CSliderRangeWidget::setSpinRange(int lower, int upper) -{ - m_lowSpin->setMinimum(lower); - m_lowSpin->setMaximum(upper); - m_upSpin->setMinimum(lower); - m_upSpin->setMaximum(upper); -} - -int CSliderRangeWidget::lowValue() -{ - return m_lowSpin->value(); -} - -int CSliderRangeWidget::upValue() -{ - return m_upSpin->value(); -} - -void CSliderRangeWidget::setEditFocus() -{ - m_lowSpin->setFocus(); -} +#include "CSliderRangeWidget.h" +#include +#include +#include +#include +#include + +CSliderRangeWidget::CSliderRangeWidget(QWidget *parent) : + QDialog(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + + QGridLayout * pTopLayout = new QGridLayout(); + QLabel * label1 = new QLabel(tr("最小值:"), this); + m_lowSpin = new QSpinBox(this); + QLabel * label2 = new QLabel(tr("最大值:"), this); + m_upSpin = new QSpinBox(this); + QPushButton * ok = new QPushButton(tr("确定"), this); + QPushButton * cancle = new QPushButton(tr("取消"), this); + pTopLayout->addWidget(label1, 0, 0, 1, 1); + pTopLayout->addWidget(m_lowSpin, 0, 1, 1, 1); + pTopLayout->addWidget(label2, 1, 0, 1, 1); + pTopLayout->addWidget(m_upSpin, 1, 1, 1, 1); + pTopLayout->addWidget(ok, 2, 0, 1, 1); + pTopLayout->addWidget(cancle, 2, 1, 1, 1); + pTopLayout->setMargin(0); + setLayout(pTopLayout); + setContentsMargins(5,3,5,3); + + connect(ok, &QPushButton::clicked, this, [=]() { + emit acceptedInput(); + }); + connect(cancle, &QPushButton::clicked, this, [=]() { hide(); }); +} + +CSliderRangeWidget::~CSliderRangeWidget() +{ + +} + +void CSliderRangeWidget::setLowValue(int value) +{ + m_lowSpin->setValue(value); +} + +void CSliderRangeWidget::setUpValue(int value) +{ + m_upSpin->setValue(value); +} + +void CSliderRangeWidget::setSpinRange(int lower, int upper) +{ + m_lowSpin->setMinimum(lower); + m_lowSpin->setMaximum(upper); + m_upSpin->setMinimum(lower); + m_upSpin->setMaximum(upper); +} + +int CSliderRangeWidget::lowValue() +{ + return m_lowSpin->value(); +} + +int CSliderRangeWidget::upValue() +{ + return m_upSpin->value(); +} + +void CSliderRangeWidget::setEditFocus() +{ + m_lowSpin->setFocus(); +} diff --git a/product/src/gui/plugin/TrendCurves/widgets/CSliderRangeWidget.h b/product/src/gui/plugin/TrendCurves/widgets/CSliderRangeWidget.h index 8b884707..dc902e99 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CSliderRangeWidget.h +++ b/product/src/gui/plugin/TrendCurves/widgets/CSliderRangeWidget.h @@ -1,34 +1,34 @@ -#ifndef CSLIDERRANGEWIDGET_H -#define CSLIDERRANGEWIDGET_H - -#include - -class QSpinBox; -class CSliderRangeWidget : public QDialog -{ - Q_OBJECT -public: - explicit CSliderRangeWidget(QWidget *parent = 0); - ~CSliderRangeWidget(); - - void setLowValue(int value); - - void setUpValue(int value); - - void setSpinRange(int lower, int upper); - - int lowValue(); - - int upValue(); - - void setEditFocus(); - -signals: - void acceptedInput(); - -private: - QSpinBox * m_lowSpin; - QSpinBox * m_upSpin; -}; - -#endif // CSLIDERRANGEWIDGET_H +#ifndef CSLIDERRANGEWIDGET_H +#define CSLIDERRANGEWIDGET_H + +#include + +class QSpinBox; +class CSliderRangeWidget : public QDialog +{ + Q_OBJECT +public: + explicit CSliderRangeWidget(QWidget *parent = 0); + ~CSliderRangeWidget(); + + void setLowValue(int value); + + void setUpValue(int value); + + void setSpinRange(int lower, int upper); + + int lowValue(); + + int upValue(); + + void setEditFocus(); + +signals: + void acceptedInput(); + +private: + QSpinBox * m_lowSpin; + QSpinBox * m_upSpin; +}; + +#endif // CSLIDERRANGEWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves/widgets/CTabButton.cpp b/product/src/gui/plugin/TrendCurves/widgets/CTabButton.cpp index 07ad6330..abd2c898 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CTabButton.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/CTabButton.cpp @@ -1,428 +1,428 @@ -#include "CTabButton.h" -#include -#include "CCalendarWidget.h" - -CTabButton::CTabButton(QWidget *parent) - : QPushButton(parent), - m_isShowCalendarEnable(false) -{ - paddingLeft = 5; - paddingRight = 5; - paddingTop = 5; - paddingBottom = 5; - textAlign = TextAlign_Center; - - showLine = true; - lineSpace = 0; - lineWidth = 6; - linePosition = LinePosition_Bottom; - lineColor = QColor(24, 144, 255); - - normalBgColor = QColor(0, 38, 75); - hoverBgColor = QColor(2, 49, 93); - checkBgColor = QColor(2, 49, 93); - normalTextColor = QColor(182, 194, 205); - hoverTextColor = QColor(255, 255, 255); - checkTextColor = QColor(20, 130, 231); - - normalBgBrush = Qt::NoBrush; - hoverBgBrush = Qt::NoBrush; - checkBgBrush = Qt::NoBrush; - - font = QFont("Microsoft YaHei"); - font.setPointSize(12); - hover = false; - setCheckable(true); -} - -void CTabButton::setShowCalendarEnable(const bool &enable) -{ - m_isShowCalendarEnable = enable; -} - - -int CTabButton::getPaddingLeft() const -{ - return this->paddingLeft; -} - -int CTabButton::getPaddingRight() const -{ - return this->paddingRight; -} - -int CTabButton::getPaddingTop() const -{ - return this->paddingTop; -} - -int CTabButton::getPaddingBottom() const -{ - return this->paddingBottom; -} - -CTabButton::TextAlign CTabButton::getTextAlign() const -{ - return this->textAlign; -} - -QColor CTabButton::getNormalBgColor() const -{ - return this->normalBgColor; -} - -QColor CTabButton::getHoverBgColor() const -{ - return this->hoverBgColor; -} - -QColor CTabButton::getCheckBgColor() const -{ - return this->checkBgColor; -} - -QColor CTabButton::getNormalTextColor() const -{ - return this->normalTextColor; -} - -QColor CTabButton::getHoverTextColor() const -{ - return this->hoverTextColor; -} - -QColor CTabButton::getCheckTextColor() const -{ - return this->checkTextColor; -} - -QFont CTabButton::getFont() const -{ - return this->font; -} - - -void CTabButton::setPaddingLeft(int paddingLeft) -{ - if (this->paddingLeft != paddingLeft) { - this->paddingLeft = paddingLeft; - update(); - } -} - -void CTabButton::setPaddingRight(int paddingRight) -{ - if (this->paddingRight != paddingRight) { - this->paddingRight = paddingRight; - update(); - } -} - -void CTabButton::setPaddingTop(int paddingTop) -{ - if (this->paddingTop != paddingTop) { - this->paddingTop = paddingTop; - update(); - } -} - -void CTabButton::setPaddingBottom(int paddingBottom) -{ - if (this->paddingBottom != paddingBottom) { - this->paddingBottom = paddingBottom; - update(); - } -} - -void CTabButton::setPadding(int padding) -{ - setPadding(padding, padding, padding, padding); -} - -void CTabButton::setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) -{ - this->paddingLeft = paddingLeft; - this->paddingRight = paddingRight; - this->paddingTop = paddingTop; - this->paddingBottom = paddingBottom; - update(); -} - -void CTabButton::setTextAlign(const CTabButton::TextAlign &textAlign) -{ - if (this->textAlign != textAlign) { - this->textAlign = textAlign; - update(); - } -} - -void CTabButton::setShowLine(bool showLine) -{ - if (this->showLine != showLine) { - this->showLine = showLine; - update(); - } -} - -void CTabButton::setLineSpace(int lineSpace) -{ - if (this->lineSpace != lineSpace) { - this->lineSpace = lineSpace; - update(); - } -} - -void CTabButton::setLineWidth(int lineWidth) -{ - if (this->lineWidth != lineWidth) { - this->lineWidth = lineWidth; - update(); - } -} - -void CTabButton::setLinePosition(const CTabButton::LinePosition &linePosition) -{ - if (this->linePosition != linePosition) { - this->linePosition = linePosition; - update(); - } -} - -void CTabButton::setLineColor(const QColor &lineColor) -{ - if (this->lineColor != lineColor) { - this->lineColor = lineColor; - update(); - } -} - -void CTabButton::setNormalBgColor(const QColor &normalBgColor) -{ - if (this->normalBgColor != normalBgColor) { - this->normalBgColor = normalBgColor; - update(); - } -} - -void CTabButton::setHoverBgColor(const QColor &hoverBgColor) -{ - if (this->hoverBgColor != hoverBgColor) { - this->hoverBgColor = hoverBgColor; - update(); - } -} - -void CTabButton::setCheckBgColor(const QColor &checkBgColor) -{ - if (this->checkBgColor != checkBgColor) { - this->checkBgColor = checkBgColor; - update(); - } -} - -void CTabButton::setNormalTextColor(const QColor &normalTextColor) -{ - if (this->normalTextColor != normalTextColor) { - this->normalTextColor = normalTextColor; - update(); - } -} - -void CTabButton::setHoverTextColor(const QColor &hoverTextColor) -{ - if (this->hoverTextColor != hoverTextColor) { - this->hoverTextColor = hoverTextColor; - update(); - } -} - -void CTabButton::setCheckTextColor(const QColor &checkTextColor) -{ - if (this->checkTextColor != checkTextColor) { - this->checkTextColor = checkTextColor; - update(); - } -} - -void CTabButton::setNormalBgBrush(const QBrush &normalBgBrush) -{ - if (this->normalBgBrush != normalBgBrush) { - this->normalBgBrush = normalBgBrush; - update(); - } -} - -void CTabButton::setHoverBgBrush(const QBrush &hoverBgBrush) -{ - if (this->hoverBgBrush != hoverBgBrush) { - this->hoverBgBrush = hoverBgBrush; - update(); - } -} - -void CTabButton::setCheckBgBrush(const QBrush &checkBgBrush) -{ - if (this->checkBgBrush != checkBgBrush) { - this->checkBgBrush = checkBgBrush; - update(); - } -} - -void CTabButton::setFont(const QFont &font) -{ - this->font = font; -} - - -void CTabButton::enterEvent(QEvent *) -{ - hover = true; - update(); -} - -void CTabButton::leaveEvent(QEvent *) -{ - hover = false; - update(); -} - -void CTabButton::paintEvent(QPaintEvent *e) -{ - QPushButton::paintEvent(e); -// //绘制准备工作,启用反锯齿 -// QPainter painter(this); -// painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); - -// //绘制背景 -// drawBg(&painter); -// //绘制文字 -// drawText(&painter); -// //绘制边框线条 -// drawLine(&painter); -} - -void CTabButton::drawBg(QPainter *painter) -{ - painter->save(); - painter->setPen(Qt::NoPen); - - int width = this->width(); - int height = this->height(); - - QRect bgRect; - if (linePosition == LinePosition_Left) { - bgRect = QRect(lineSpace, 0, width - lineSpace, height); - } else if (linePosition == LinePosition_Right) { - bgRect = QRect(0, 0, width - lineSpace, height); - } else if (linePosition == LinePosition_Top) { - bgRect = QRect(0, lineSpace, width, height - lineSpace); - } else if (linePosition == LinePosition_Bottom) { - bgRect = QRect(0, 0, width, height - lineSpace); - } - - //如果画刷存在则取画刷 - QBrush bgBrush; - if (isChecked()) { - bgBrush = checkBgBrush; - } else if (hover) { - bgBrush = hoverBgBrush; - } else { - bgBrush = normalBgBrush; - } - - if (bgBrush != Qt::NoBrush) { - painter->setBrush(bgBrush); - } else { - //根据当前状态选择对应颜色 - QColor bgColor; - if (isChecked()) { - bgColor = checkBgColor; - } else if (hover) { - bgColor = hoverBgColor; - } else { - bgColor = normalBgColor; - } - - painter->setBrush(bgColor); - } - - painter->drawRect(bgRect); - - painter->restore(); -} - -void CTabButton::drawText(QPainter *painter) -{ - painter->save(); - painter->setBrush(Qt::NoBrush); - - //根据当前状态选择对应颜色 - QColor textColor; - if (isChecked()) { - textColor = checkTextColor; - } else if (hover) { - textColor = hoverTextColor; - } else { - textColor = normalTextColor; - } - - QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom); - painter->setPen(textColor); - painter->setFont(font); - painter->drawText(textRect, textAlign | Qt::AlignVCenter, text()); - - painter->restore(); -} - - -void CTabButton::drawLine(QPainter *painter) -{ - if (!showLine) { - return; - } - - if (!isChecked()) { - return; - } - - painter->save(); - - QPen pen; - pen.setWidth(lineWidth); - pen.setColor(lineColor); - painter->setPen(pen); - - //根据线条位置设置线条坐标 - QPoint pointStart, pointEnd; - if (linePosition == LinePosition_Left) { - pointStart = QPoint(0, 0); - pointEnd = QPoint(0, height()); - } else if (linePosition == LinePosition_Right) { - pointStart = QPoint(width(), 0); - pointEnd = QPoint(width(), height()); - } else if (linePosition == LinePosition_Top) { - pointStart = QPoint(0, 0); - pointEnd = QPoint(width(), 0); - } else if (linePosition == LinePosition_Bottom) { - pointStart = QPoint(0, height()); - pointEnd = QPoint(width(), height()); - } - - painter->drawLine(pointStart, pointEnd); - - painter->restore(); -} - -void CTabButton::contextMenuEvent(QContextMenuEvent *event) -{ - Q_UNUSED(event) - if(!m_isShowCalendarEnable) - { - return; - } - CCalendarWidget * calendar = new CCalendarWidget(this); - calendar->setSelectedDate(QDate::currentDate()); - connect(calendar, &CCalendarWidget::clicked, this, &CTabButton::dataChanged); - calendar->show(); - calendar->move(parentWidget()->mapToGlobal(QPoint(width(), height() + 2))); -} +#include "CTabButton.h" +#include +#include "CCalendarWidget.h" + +CTabButton::CTabButton(QWidget *parent) + : QPushButton(parent), + m_isShowCalendarEnable(false) +{ + paddingLeft = 5; + paddingRight = 5; + paddingTop = 5; + paddingBottom = 5; + textAlign = TextAlign_Center; + + showLine = true; + lineSpace = 0; + lineWidth = 6; + linePosition = LinePosition_Bottom; + lineColor = QColor(24, 144, 255); + + normalBgColor = QColor(0, 38, 75); + hoverBgColor = QColor(2, 49, 93); + checkBgColor = QColor(2, 49, 93); + normalTextColor = QColor(182, 194, 205); + hoverTextColor = QColor(255, 255, 255); + checkTextColor = QColor(20, 130, 231); + + normalBgBrush = Qt::NoBrush; + hoverBgBrush = Qt::NoBrush; + checkBgBrush = Qt::NoBrush; + + font = QFont("Microsoft YaHei"); + font.setPointSize(12); + hover = false; + setCheckable(true); +} + +void CTabButton::setShowCalendarEnable(const bool &enable) +{ + m_isShowCalendarEnable = enable; +} + + +int CTabButton::getPaddingLeft() const +{ + return this->paddingLeft; +} + +int CTabButton::getPaddingRight() const +{ + return this->paddingRight; +} + +int CTabButton::getPaddingTop() const +{ + return this->paddingTop; +} + +int CTabButton::getPaddingBottom() const +{ + return this->paddingBottom; +} + +CTabButton::TextAlign CTabButton::getTextAlign() const +{ + return this->textAlign; +} + +QColor CTabButton::getNormalBgColor() const +{ + return this->normalBgColor; +} + +QColor CTabButton::getHoverBgColor() const +{ + return this->hoverBgColor; +} + +QColor CTabButton::getCheckBgColor() const +{ + return this->checkBgColor; +} + +QColor CTabButton::getNormalTextColor() const +{ + return this->normalTextColor; +} + +QColor CTabButton::getHoverTextColor() const +{ + return this->hoverTextColor; +} + +QColor CTabButton::getCheckTextColor() const +{ + return this->checkTextColor; +} + +QFont CTabButton::getFont() const +{ + return this->font; +} + + +void CTabButton::setPaddingLeft(int paddingLeft) +{ + if (this->paddingLeft != paddingLeft) { + this->paddingLeft = paddingLeft; + update(); + } +} + +void CTabButton::setPaddingRight(int paddingRight) +{ + if (this->paddingRight != paddingRight) { + this->paddingRight = paddingRight; + update(); + } +} + +void CTabButton::setPaddingTop(int paddingTop) +{ + if (this->paddingTop != paddingTop) { + this->paddingTop = paddingTop; + update(); + } +} + +void CTabButton::setPaddingBottom(int paddingBottom) +{ + if (this->paddingBottom != paddingBottom) { + this->paddingBottom = paddingBottom; + update(); + } +} + +void CTabButton::setPadding(int padding) +{ + setPadding(padding, padding, padding, padding); +} + +void CTabButton::setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) +{ + this->paddingLeft = paddingLeft; + this->paddingRight = paddingRight; + this->paddingTop = paddingTop; + this->paddingBottom = paddingBottom; + update(); +} + +void CTabButton::setTextAlign(const CTabButton::TextAlign &textAlign) +{ + if (this->textAlign != textAlign) { + this->textAlign = textAlign; + update(); + } +} + +void CTabButton::setShowLine(bool showLine) +{ + if (this->showLine != showLine) { + this->showLine = showLine; + update(); + } +} + +void CTabButton::setLineSpace(int lineSpace) +{ + if (this->lineSpace != lineSpace) { + this->lineSpace = lineSpace; + update(); + } +} + +void CTabButton::setLineWidth(int lineWidth) +{ + if (this->lineWidth != lineWidth) { + this->lineWidth = lineWidth; + update(); + } +} + +void CTabButton::setLinePosition(const CTabButton::LinePosition &linePosition) +{ + if (this->linePosition != linePosition) { + this->linePosition = linePosition; + update(); + } +} + +void CTabButton::setLineColor(const QColor &lineColor) +{ + if (this->lineColor != lineColor) { + this->lineColor = lineColor; + update(); + } +} + +void CTabButton::setNormalBgColor(const QColor &normalBgColor) +{ + if (this->normalBgColor != normalBgColor) { + this->normalBgColor = normalBgColor; + update(); + } +} + +void CTabButton::setHoverBgColor(const QColor &hoverBgColor) +{ + if (this->hoverBgColor != hoverBgColor) { + this->hoverBgColor = hoverBgColor; + update(); + } +} + +void CTabButton::setCheckBgColor(const QColor &checkBgColor) +{ + if (this->checkBgColor != checkBgColor) { + this->checkBgColor = checkBgColor; + update(); + } +} + +void CTabButton::setNormalTextColor(const QColor &normalTextColor) +{ + if (this->normalTextColor != normalTextColor) { + this->normalTextColor = normalTextColor; + update(); + } +} + +void CTabButton::setHoverTextColor(const QColor &hoverTextColor) +{ + if (this->hoverTextColor != hoverTextColor) { + this->hoverTextColor = hoverTextColor; + update(); + } +} + +void CTabButton::setCheckTextColor(const QColor &checkTextColor) +{ + if (this->checkTextColor != checkTextColor) { + this->checkTextColor = checkTextColor; + update(); + } +} + +void CTabButton::setNormalBgBrush(const QBrush &normalBgBrush) +{ + if (this->normalBgBrush != normalBgBrush) { + this->normalBgBrush = normalBgBrush; + update(); + } +} + +void CTabButton::setHoverBgBrush(const QBrush &hoverBgBrush) +{ + if (this->hoverBgBrush != hoverBgBrush) { + this->hoverBgBrush = hoverBgBrush; + update(); + } +} + +void CTabButton::setCheckBgBrush(const QBrush &checkBgBrush) +{ + if (this->checkBgBrush != checkBgBrush) { + this->checkBgBrush = checkBgBrush; + update(); + } +} + +void CTabButton::setFont(const QFont &font) +{ + this->font = font; +} + + +void CTabButton::enterEvent(QEvent *) +{ + hover = true; + update(); +} + +void CTabButton::leaveEvent(QEvent *) +{ + hover = false; + update(); +} + +void CTabButton::paintEvent(QPaintEvent *e) +{ + QPushButton::paintEvent(e); +// //绘制准备工作,启用反锯齿 +// QPainter painter(this); +// painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + +// //绘制背景 +// drawBg(&painter); +// //绘制文字 +// drawText(&painter); +// //绘制边框线条 +// drawLine(&painter); +} + +void CTabButton::drawBg(QPainter *painter) +{ + painter->save(); + painter->setPen(Qt::NoPen); + + int width = this->width(); + int height = this->height(); + + QRect bgRect; + if (linePosition == LinePosition_Left) { + bgRect = QRect(lineSpace, 0, width - lineSpace, height); + } else if (linePosition == LinePosition_Right) { + bgRect = QRect(0, 0, width - lineSpace, height); + } else if (linePosition == LinePosition_Top) { + bgRect = QRect(0, lineSpace, width, height - lineSpace); + } else if (linePosition == LinePosition_Bottom) { + bgRect = QRect(0, 0, width, height - lineSpace); + } + + //如果画刷存在则取画刷 + QBrush bgBrush; + if (isChecked()) { + bgBrush = checkBgBrush; + } else if (hover) { + bgBrush = hoverBgBrush; + } else { + bgBrush = normalBgBrush; + } + + if (bgBrush != Qt::NoBrush) { + painter->setBrush(bgBrush); + } else { + //根据当前状态选择对应颜色 + QColor bgColor; + if (isChecked()) { + bgColor = checkBgColor; + } else if (hover) { + bgColor = hoverBgColor; + } else { + bgColor = normalBgColor; + } + + painter->setBrush(bgColor); + } + + painter->drawRect(bgRect); + + painter->restore(); +} + +void CTabButton::drawText(QPainter *painter) +{ + painter->save(); + painter->setBrush(Qt::NoBrush); + + //根据当前状态选择对应颜色 + QColor textColor; + if (isChecked()) { + textColor = checkTextColor; + } else if (hover) { + textColor = hoverTextColor; + } else { + textColor = normalTextColor; + } + + QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom); + painter->setPen(textColor); + painter->setFont(font); + painter->drawText(textRect, textAlign | Qt::AlignVCenter, text()); + + painter->restore(); +} + + +void CTabButton::drawLine(QPainter *painter) +{ + if (!showLine) { + return; + } + + if (!isChecked()) { + return; + } + + painter->save(); + + QPen pen; + pen.setWidth(lineWidth); + pen.setColor(lineColor); + painter->setPen(pen); + + //根据线条位置设置线条坐标 + QPoint pointStart, pointEnd; + if (linePosition == LinePosition_Left) { + pointStart = QPoint(0, 0); + pointEnd = QPoint(0, height()); + } else if (linePosition == LinePosition_Right) { + pointStart = QPoint(width(), 0); + pointEnd = QPoint(width(), height()); + } else if (linePosition == LinePosition_Top) { + pointStart = QPoint(0, 0); + pointEnd = QPoint(width(), 0); + } else if (linePosition == LinePosition_Bottom) { + pointStart = QPoint(0, height()); + pointEnd = QPoint(width(), height()); + } + + painter->drawLine(pointStart, pointEnd); + + painter->restore(); +} + +void CTabButton::contextMenuEvent(QContextMenuEvent *event) +{ + Q_UNUSED(event) + if(!m_isShowCalendarEnable) + { + return; + } + CCalendarWidget * calendar = new CCalendarWidget(this); + calendar->setSelectedDate(QDate::currentDate()); + connect(calendar, &CCalendarWidget::clicked, this, &CTabButton::dataChanged); + calendar->show(); + calendar->move(parentWidget()->mapToGlobal(QPoint(width(), height() + 2))); +} diff --git a/product/src/gui/plugin/TrendCurves/widgets/CTabButton.h b/product/src/gui/plugin/TrendCurves/widgets/CTabButton.h index e74897d3..56a7c409 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CTabButton.h +++ b/product/src/gui/plugin/TrendCurves/widgets/CTabButton.h @@ -1,136 +1,136 @@ -#ifndef CTABBUTTON_H -#define CTABBUTTON_H - -#include -#include - -class CTabButton : public QPushButton -{ - Q_OBJECT - -public: - enum TextAlign { - TextAlign_Left = 0x0001, //左侧对齐 - TextAlign_Right = 0x0002, //右侧对齐 - TextAlign_Top = 0x0020, //顶部对齐 - TextAlign_Bottom = 0x0040, //底部对齐 - TextAlign_Center = 0x0004 //居中对齐 - }; - - enum LinePosition { - LinePosition_Left = 0, //左侧 - LinePosition_Right = 1, //右侧 - LinePosition_Top = 2, //顶部 - LinePosition_Bottom = 3 //底部 - }; - - explicit CTabButton(QWidget *parent = Q_NULLPTR); - - void setShowCalendarEnable(const bool &enable); - - int getPaddingLeft() const; - int getPaddingRight() const; - int getPaddingTop() const; - int getPaddingBottom() const; - TextAlign getTextAlign() const; - - QColor getNormalBgColor() const; - QColor getHoverBgColor() const; - QColor getCheckBgColor() const; - QColor getNormalTextColor() const; - QColor getHoverTextColor() const; - QColor getCheckTextColor() const; - - QFont getFont() const; - -public slots: - //设置文字间隔 - void setPaddingLeft(int paddingLeft); - void setPaddingRight(int paddingRight); - void setPaddingTop(int paddingTop); - void setPaddingBottom(int paddingBottom); - void setPadding(int padding); - void setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom); - - //设置文字对齐 - void setTextAlign(const TextAlign &textAlign); - - //设置显示线条 - void setShowLine(bool showLine); - //设置线条间隔 - void setLineSpace(int lineSpace); - //设置线条宽度 - void setLineWidth(int lineWidth); - //设置线条位置 - void setLinePosition(const LinePosition &linePosition); - //设置线条颜色 - void setLineColor(const QColor &lineColor); - - //设置正常背景颜色 - void setNormalBgColor(const QColor &normalBgColor); - //设置悬停背景颜色 - void setHoverBgColor(const QColor &hoverBgColor); - //设置选中背景颜色 - void setCheckBgColor(const QColor &checkBgColor); - - //设置正常文字颜色 - void setNormalTextColor(const QColor &normalTextColor); - //设置悬停文字颜色 - void setHoverTextColor(const QColor &hoverTextColor); - //设置选中文字颜色 - void setCheckTextColor(const QColor &checkTextColor); - - //设置正常背景画刷 - void setNormalBgBrush(const QBrush &normalBgBrush); - //设置悬停背景画刷 - void setHoverBgBrush(const QBrush &hoverBgBrush); - //设置选中背景画刷 - void setCheckBgBrush(const QBrush &checkBgBrush); - - void setFont(const QFont &font); - -signals: - void dataChanged(const QDate &date); - -protected: - void enterEvent(QEvent *); - void leaveEvent(QEvent *); - void paintEvent(QPaintEvent *e); - void drawBg(QPainter *painter); - void drawText(QPainter *painter); - void drawLine(QPainter *painter); - - void contextMenuEvent(QContextMenuEvent *event); - -private: - int paddingLeft; //文字左侧间隔 - int paddingRight; //文字右侧间隔 - int paddingTop; //文字顶部间隔 - int paddingBottom; //文字底部间隔 - TextAlign textAlign; //文字对齐 - - bool showLine; //显示线条 - int lineSpace; //线条间隔 - int lineWidth; //线条宽度 - LinePosition linePosition; //线条位置 - QColor lineColor; //线条颜色 - - QColor normalBgColor; //正常背景颜色 - QColor hoverBgColor; //悬停背景颜色 - QColor checkBgColor; //选中背景颜色 - QColor normalTextColor; //正常文字颜色 - QColor hoverTextColor; //悬停文字颜色 - QColor checkTextColor; //选中文字颜色 - - QBrush normalBgBrush; //正常背景画刷 - QBrush hoverBgBrush; //悬停背景画刷 - QBrush checkBgBrush; //选中背景画刷 - - QFont font; - - bool hover; //悬停标志位 - - bool m_isShowCalendarEnable; -}; - -#endif // CTABBUTTON_H +#ifndef CTABBUTTON_H +#define CTABBUTTON_H + +#include +#include + +class CTabButton : public QPushButton +{ + Q_OBJECT + +public: + enum TextAlign { + TextAlign_Left = 0x0001, //左侧对齐 + TextAlign_Right = 0x0002, //右侧对齐 + TextAlign_Top = 0x0020, //顶部对齐 + TextAlign_Bottom = 0x0040, //底部对齐 + TextAlign_Center = 0x0004 //居中对齐 + }; + + enum LinePosition { + LinePosition_Left = 0, //左侧 + LinePosition_Right = 1, //右侧 + LinePosition_Top = 2, //顶部 + LinePosition_Bottom = 3 //底部 + }; + + explicit CTabButton(QWidget *parent = Q_NULLPTR); + + void setShowCalendarEnable(const bool &enable); + + int getPaddingLeft() const; + int getPaddingRight() const; + int getPaddingTop() const; + int getPaddingBottom() const; + TextAlign getTextAlign() const; + + QColor getNormalBgColor() const; + QColor getHoverBgColor() const; + QColor getCheckBgColor() const; + QColor getNormalTextColor() const; + QColor getHoverTextColor() const; + QColor getCheckTextColor() const; + + QFont getFont() const; + +public slots: + //设置文字间隔 + void setPaddingLeft(int paddingLeft); + void setPaddingRight(int paddingRight); + void setPaddingTop(int paddingTop); + void setPaddingBottom(int paddingBottom); + void setPadding(int padding); + void setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom); + + //设置文字对齐 + void setTextAlign(const TextAlign &textAlign); + + //设置显示线条 + void setShowLine(bool showLine); + //设置线条间隔 + void setLineSpace(int lineSpace); + //设置线条宽度 + void setLineWidth(int lineWidth); + //设置线条位置 + void setLinePosition(const LinePosition &linePosition); + //设置线条颜色 + void setLineColor(const QColor &lineColor); + + //设置正常背景颜色 + void setNormalBgColor(const QColor &normalBgColor); + //设置悬停背景颜色 + void setHoverBgColor(const QColor &hoverBgColor); + //设置选中背景颜色 + void setCheckBgColor(const QColor &checkBgColor); + + //设置正常文字颜色 + void setNormalTextColor(const QColor &normalTextColor); + //设置悬停文字颜色 + void setHoverTextColor(const QColor &hoverTextColor); + //设置选中文字颜色 + void setCheckTextColor(const QColor &checkTextColor); + + //设置正常背景画刷 + void setNormalBgBrush(const QBrush &normalBgBrush); + //设置悬停背景画刷 + void setHoverBgBrush(const QBrush &hoverBgBrush); + //设置选中背景画刷 + void setCheckBgBrush(const QBrush &checkBgBrush); + + void setFont(const QFont &font); + +signals: + void dataChanged(const QDate &date); + +protected: + void enterEvent(QEvent *); + void leaveEvent(QEvent *); + void paintEvent(QPaintEvent *e); + void drawBg(QPainter *painter); + void drawText(QPainter *painter); + void drawLine(QPainter *painter); + + void contextMenuEvent(QContextMenuEvent *event); + +private: + int paddingLeft; //文字左侧间隔 + int paddingRight; //文字右侧间隔 + int paddingTop; //文字顶部间隔 + int paddingBottom; //文字底部间隔 + TextAlign textAlign; //文字对齐 + + bool showLine; //显示线条 + int lineSpace; //线条间隔 + int lineWidth; //线条宽度 + LinePosition linePosition; //线条位置 + QColor lineColor; //线条颜色 + + QColor normalBgColor; //正常背景颜色 + QColor hoverBgColor; //悬停背景颜色 + QColor checkBgColor; //选中背景颜色 + QColor normalTextColor; //正常文字颜色 + QColor hoverTextColor; //悬停文字颜色 + QColor checkTextColor; //选中文字颜色 + + QBrush normalBgBrush; //正常背景画刷 + QBrush hoverBgBrush; //悬停背景画刷 + QBrush checkBgBrush; //选中背景画刷 + + QFont font; + + bool hover; //悬停标志位 + + bool m_isShowCalendarEnable; +}; + +#endif // CTABBUTTON_H diff --git a/product/src/gui/plugin/TrendCurves/widgets/CToolTip.cpp b/product/src/gui/plugin/TrendCurves/widgets/CToolTip.cpp index e8472099..d2764cd9 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CToolTip.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/CToolTip.cpp @@ -1,139 +1,139 @@ -#include "CToolTip.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CHisEventManage.h" - -CToolTip::CToolTip(QWidget *parent) - : QDialog(parent), - m_parent(parent) -{ - setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); - setAttribute(Qt::WA_DeleteOnClose); - setObjectName("ToolTip"); - label_ = new QLabel(this); - label_->setMouseTracking(true); - label_->installEventFilter(parent); - button_ = new QPushButton(tr("全部"),this); - button_->setObjectName("m_tipButton"); - QVBoxLayout *mVLayout = new QVBoxLayout(this); - QHBoxLayout *mHLayout = new QHBoxLayout(this); - mHLayout->addWidget(label_); - label_->setMargin(3); - mVLayout->addLayout(mHLayout); - mVLayout->addWidget(button_); - mHLayout->setMargin(0); - installEventFilter(this); - label_->setObjectName("m_tipLabel"); - connect(button_,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked())); -} - -CToolTip::~CToolTip() -{ - m_parent = nullptr; -} - -QString CToolTip::text() -{ - return label_->text(); -} - -void CToolTip::setText(const QString &text) -{ - label_->setText(text); -} - -bool CToolTip::eventFilter(QObject *object, QEvent *event) -{ - if (object == this) - { - if (QEvent::WindowDeactivate == event->type()) - { - this->close(); - event->accept(); - return true; - } - } - return QWidget::eventFilter(object, event); -} - -void CToolTip::on_pushButton_clicked() -{ - int rowCount = alarmList.size(); - alarmTable = new QTableView(m_parent); - model = new QStandardItemModel(); - model->setRowCount(rowCount); - alarmTable->setWindowTitle(tr("告警列表")); - QString alarmTime,alarmContent; - QStringList header; - header<setHorizontalHeaderLabels(header); - QHeaderView *rowHeader = alarmTable->verticalHeader(); - rowHeader->setHidden(true); - for(int i = 0;i < rowCount;i++) - { - QString tmp; - QStringList tmpList; - tmp = alarmList.at(i); - tmpList = tmp.split("\n"); - alarmTime = tmpList[0]; - alarmContent = tmpList[1]; - model->setItem(i,0,new QStandardItem(alarmTime)); - model->setItem(i,1,new QStandardItem(alarmContent)); - } - alarmTable->setModel(model); - alarmTable->resizeColumnsToContents(); - alarmTable->setObjectName("m_tipAlarmTable"); - alarmTable->resize(470,300); - alarmTable->setWindowFlags(alarmTable->windowFlags()&~(Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint)); - alarmTable->horizontalHeader()->setStretchLastSection(true); - alarmTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - alarmTable->setWindowFlag(Qt::WindowStaysOnTopHint); - alarmTable->setWindowFlag(Qt::Dialog); - alarmTable->setWindowModality(Qt::ApplicationModal); - alarmTable->setAttribute(Qt::WA_DeleteOnClose); - alarmTable->setSelectionBehavior(QAbstractItemView::SelectRows); - alarmTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - alarmTable->show(); -} - -void CToolTip::popup(QPoint pos, const QString &text, QWidget *parent) -{ - CToolTip * tip = new CToolTip(parent); - QString showTipText; - if(!tip->alarmList.isEmpty()) - { - tip->alarmList.clear(); - } - tip->alarmList = text.split("\n\n"); - if(tip->alarmList.size()>5) - { - for(int i = 0;i<5;i++) - { - showTipText += tip->alarmList.at(i); - showTipText += "\n\n"; - } - } - else { - showTipText = text; - tip->button_->setVisible(false); - } - tip->setText(showTipText); - tip->show(); - int screenWidth = QApplication::desktop()->screenGeometry().width(); - if((tip->width() + pos.x()) < screenWidth) - { - tip->move(pos.x(),pos.y()-tip->height()); - } - else - { - tip->move(pos.x() - tip->width(), pos.y()-tip->height()); - } -} +#include "CToolTip.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CHisEventManage.h" + +CToolTip::CToolTip(QWidget *parent) + : QDialog(parent), + m_parent(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_DeleteOnClose); + setObjectName("ToolTip"); + label_ = new QLabel(this); + label_->setMouseTracking(true); + label_->installEventFilter(parent); + button_ = new QPushButton(tr("全部"),this); + button_->setObjectName("m_tipButton"); + QVBoxLayout *mVLayout = new QVBoxLayout(this); + QHBoxLayout *mHLayout = new QHBoxLayout(this); + mHLayout->addWidget(label_); + label_->setMargin(3); + mVLayout->addLayout(mHLayout); + mVLayout->addWidget(button_); + mHLayout->setMargin(0); + installEventFilter(this); + label_->setObjectName("m_tipLabel"); + connect(button_,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked())); +} + +CToolTip::~CToolTip() +{ + m_parent = nullptr; +} + +QString CToolTip::text() +{ + return label_->text(); +} + +void CToolTip::setText(const QString &text) +{ + label_->setText(text); +} + +bool CToolTip::eventFilter(QObject *object, QEvent *event) +{ + if (object == this) + { + if (QEvent::WindowDeactivate == event->type()) + { + this->close(); + event->accept(); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +void CToolTip::on_pushButton_clicked() +{ + int rowCount = alarmList.size(); + alarmTable = new QTableView(m_parent); + model = new QStandardItemModel(); + model->setRowCount(rowCount); + alarmTable->setWindowTitle(tr("告警列表")); + QString alarmTime,alarmContent; + QStringList header; + header<setHorizontalHeaderLabels(header); + QHeaderView *rowHeader = alarmTable->verticalHeader(); + rowHeader->setHidden(true); + for(int i = 0;i < rowCount;i++) + { + QString tmp; + QStringList tmpList; + tmp = alarmList.at(i); + tmpList = tmp.split("\n"); + alarmTime = tmpList[0]; + alarmContent = tmpList[1]; + model->setItem(i,0,new QStandardItem(alarmTime)); + model->setItem(i,1,new QStandardItem(alarmContent)); + } + alarmTable->setModel(model); + alarmTable->resizeColumnsToContents(); + alarmTable->setObjectName("m_tipAlarmTable"); + alarmTable->resize(470,300); + alarmTable->setWindowFlags(alarmTable->windowFlags()&~(Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint)); + alarmTable->horizontalHeader()->setStretchLastSection(true); + alarmTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + alarmTable->setWindowFlag(Qt::WindowStaysOnTopHint); + alarmTable->setWindowFlag(Qt::Dialog); + alarmTable->setWindowModality(Qt::ApplicationModal); + alarmTable->setAttribute(Qt::WA_DeleteOnClose); + alarmTable->setSelectionBehavior(QAbstractItemView::SelectRows); + alarmTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + alarmTable->show(); +} + +void CToolTip::popup(QPoint pos, const QString &text, QWidget *parent) +{ + CToolTip * tip = new CToolTip(parent); + QString showTipText; + if(!tip->alarmList.isEmpty()) + { + tip->alarmList.clear(); + } + tip->alarmList = text.split("\n\n"); + if(tip->alarmList.size()>5) + { + for(int i = 0;i<5;i++) + { + showTipText += tip->alarmList.at(i); + showTipText += "\n\n"; + } + } + else { + showTipText = text; + tip->button_->setVisible(false); + } + tip->setText(showTipText); + tip->show(); + int screenWidth = QApplication::desktop()->screenGeometry().width(); + if((tip->width() + pos.x()) < screenWidth) + { + tip->move(pos.x(),pos.y()-tip->height()); + } + else + { + tip->move(pos.x() - tip->width(), pos.y()-tip->height()); + } +} diff --git a/product/src/gui/plugin/TrendCurves/widgets/CToolTip.h b/product/src/gui/plugin/TrendCurves/widgets/CToolTip.h index 71d4da98..1d7378cb 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CToolTip.h +++ b/product/src/gui/plugin/TrendCurves/widgets/CToolTip.h @@ -1,39 +1,39 @@ -#ifndef CTOOLTIP_H -#define CTOOLTIP_H - -#include - -class QLabel; -class QTableView; -class QStandardItemModel; - -class CToolTip : public QDialog -{ - Q_OBJECT -public: - CToolTip(QWidget *parent = nullptr); - ~CToolTip(); - - QString text(); - void setText(const QString &text); - static void popup(QPoint pos, const QString &text, QWidget *parent = nullptr); - -protected: - bool eventFilter(QObject *object, QEvent *event); - -signals: - void alarmListMsg(const QStringList &alarmTable); - -protected slots: - void on_pushButton_clicked(); - -private: - QLabel *label_; - QPushButton *button_; - QStringList alarmList; - QStandardItemModel *model; - QTableView *alarmTable; - QWidget *m_parent; -}; - -#endif // CTOOLTIP_H +#ifndef CTOOLTIP_H +#define CTOOLTIP_H + +#include + +class QLabel; +class QTableView; +class QStandardItemModel; + +class CToolTip : public QDialog +{ + Q_OBJECT +public: + CToolTip(QWidget *parent = nullptr); + ~CToolTip(); + + QString text(); + void setText(const QString &text); + static void popup(QPoint pos, const QString &text, QWidget *parent = nullptr); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +signals: + void alarmListMsg(const QStringList &alarmTable); + +protected slots: + void on_pushButton_clicked(); + +private: + QLabel *label_; + QPushButton *button_; + QStringList alarmList; + QStandardItemModel *model; + QTableView *alarmTable; + QWidget *m_parent; +}; + +#endif // CTOOLTIP_H diff --git a/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider.cpp b/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider.cpp index 5f705541..b45b3a8a 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider.cpp @@ -1,746 +1,746 @@ -#include "QxtSpanSlider.h" -/**************************************************************************** -** Copyright (c) 2006 - 2011, the LibQxt project. -** See the Qxt AUTHORS file for a list of authors and copyright holders. -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** * Neither the name of the LibQxt project nor the -** names of its contributors may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -** -*****************************************************************************/ - -#include "QxtSpanSlider_p.h" -#include -#include -#include -#include -#include -#include - -QxtSpanSliderPrivate::QxtSpanSliderPrivate() : - lower(0), - upper(0), - lowerPos(0), - upperPos(0), - offset(0), - position(0), - lastPressed(QxtSpanSlider::NoHandle), - mainControl(QxtSpanSlider::LowerHandle), - lowerPressed(QStyle::SC_None), - upperPressed(QStyle::SC_None), - movement(QxtSpanSlider::FreeMovement), - firstMovement(false), - blockTracking(false) -{ -} - -void QxtSpanSliderPrivate::initStyleOption(QStyleOptionSlider* option, QxtSpanSlider::SpanHandle handle) const -{ - const QxtSpanSlider* p = q_ptr; - p->initStyleOption(option); - option->sliderPosition = (handle == QxtSpanSlider::LowerHandle ? lowerPos : upperPos); - option->sliderValue = (handle == QxtSpanSlider::LowerHandle ? lower : upper); -} - -int QxtSpanSliderPrivate::pixelPosToRangeValue(int pos) const -{ - QStyleOptionSlider opt; - initStyleOption(&opt); - - int sliderMin = 0; - int sliderMax = 0; - int sliderLength = 0; - const QSlider* p = q_ptr; - const QRect gr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, p); - const QRect sr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, p); - if (p->orientation() == Qt::Horizontal) - { - sliderLength = sr.width(); - sliderMin = gr.x(); - sliderMax = gr.right() - sliderLength + 1; - } - else - { - sliderLength = sr.height(); - sliderMin = gr.y(); - sliderMax = gr.bottom() - sliderLength + 1; - } - return QStyle::sliderValueFromPosition(p->minimum(), p->maximum(), pos - sliderMin, - sliderMax - sliderMin, opt.upsideDown); -} - -void QxtSpanSliderPrivate::handleMousePress(const QPoint& pos, QStyle::SubControl& control, int value, QxtSpanSlider::SpanHandle handle) -{ - QStyleOptionSlider opt; - initStyleOption(&opt, handle); - QxtSpanSlider* p = q_ptr; - const QStyle::SubControl oldControl = control; - control = p->style()->hitTestComplexControl(QStyle::CC_Slider, &opt, pos, p); - const QRect sr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, p); - if (control == QStyle::SC_SliderHandle) - { - position = value; - offset = pick(pos - sr.topLeft()); - lastPressed = handle; - p->setSliderDown(true); - emit p->sliderPressed(handle); - } - if (control != oldControl) - p->update(sr); -} - -void QxtSpanSliderPrivate::setupPainter(QPainter* painter, Qt::Orientation orientation, qreal x1, qreal y1, qreal x2, qreal y2) const -{ - QColor highlight = q_ptr->palette().color(QPalette::Highlight); - QLinearGradient gradient(x1, y1, x2, y2); - gradient.setColorAt(0, highlight.dark(120)); - gradient.setColorAt(1, highlight.light(108)); - painter->setBrush(gradient); - - if (orientation == Qt::Horizontal) - painter->setPen(QPen(highlight.dark(130), 0)); - else - painter->setPen(QPen(highlight.dark(150), 0)); -} - -void QxtSpanSliderPrivate::drawSpan(QStylePainter* painter, const QRect& rect) const -{ - QStyleOptionSlider opt; - initStyleOption(&opt); - const QSlider* p = q_ptr; - - // area - QRect groove = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, p); - if (opt.orientation == Qt::Horizontal) - groove.adjust(0, 0, -1, 0); - else - groove.adjust(0, 0, 0, -1); - - // pen & brush - painter->setPen(QPen(p->palette().color(QPalette::Dark).light(110), 0)); - if (opt.orientation == Qt::Horizontal) - setupPainter(painter, opt.orientation, groove.center().x(), groove.top(), groove.center().x(), groove.bottom()); - else - setupPainter(painter, opt.orientation, groove.left(), groove.center().y(), groove.right(), groove.center().y()); - - // draw groove - painter->drawRect(rect.intersected(groove)); -} - -void QxtSpanSliderPrivate::drawHandle(QStylePainter* painter, QxtSpanSlider::SpanHandle handle) const -{ - QStyleOptionSlider opt; - initStyleOption(&opt, handle); - opt.subControls = QStyle::SC_SliderHandle; - QStyle::SubControl pressed = (handle == QxtSpanSlider::LowerHandle ? lowerPressed : upperPressed); - if (pressed == QStyle::SC_SliderHandle) - { - opt.activeSubControls = pressed; - opt.state |= QStyle::State_Sunken; - } - painter->drawComplexControl(QStyle::CC_Slider, opt); -} - -void QxtSpanSliderPrivate::triggerAction(QAbstractSlider::SliderAction action, bool main) -{ - int value = 0; - bool no = false; - bool up = false; - const int min = q_ptr->minimum(); - const int max = q_ptr->maximum(); - const QxtSpanSlider::SpanHandle altControl = (mainControl == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); - - blockTracking = true; - - switch (action) - { - case QAbstractSlider::SliderSingleStepAdd: - if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) - { - value = qBound(min, upper + q_ptr->singleStep(), max); - up = true; - break; - } - value = qBound(min, lower + q_ptr->singleStep(), max); - break; - case QAbstractSlider::SliderSingleStepSub: - if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) - { - value = qBound(min, upper - q_ptr->singleStep(), max); - up = true; - break; - } - value = qBound(min, lower - q_ptr->singleStep(), max); - break; - case QAbstractSlider::SliderToMinimum: - value = min; - if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) - up = true; - break; - case QAbstractSlider::SliderToMaximum: - value = max; - if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) - up = true; - break; - case QAbstractSlider::SliderMove: - if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) - up = true; - case QAbstractSlider::SliderNoAction: - no = true; - break; - default: - qWarning("QxtSpanSliderPrivate::triggerAction: Unknown action"); - break; - } - - if (!no && !up) - { - if (movement == QxtSpanSlider::NoCrossing) - value = qMin(value, upper); - else if (movement == QxtSpanSlider::NoOverlapping) - value = qMin(value, upper - 1); - - if (movement == QxtSpanSlider::FreeMovement && value > upper) - { - swapControls(); - q_ptr->setUpperPosition(value); - } - else - { - q_ptr->setLowerPosition(value); - } - } - else if (!no) - { - if (movement == QxtSpanSlider::NoCrossing) - value = qMax(value, lower); - else if (movement == QxtSpanSlider::NoOverlapping) - value = qMax(value, lower + 1); - - if (movement == QxtSpanSlider::FreeMovement && value < lower) - { - swapControls(); - q_ptr->setLowerPosition(value); - } - else - { - q_ptr->setUpperPosition(value); - } - } - - blockTracking = false; - q_ptr->setLowerValue(lowerPos); - q_ptr->setUpperValue(upperPos); -} - -void QxtSpanSliderPrivate::swapControls() -{ - qSwap(lower, upper); - qSwap(lowerPressed, upperPressed); - lastPressed = (lastPressed == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); - mainControl = (mainControl == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); -} - -void QxtSpanSliderPrivate::updateRange(int min, int max) -{ - Q_UNUSED(min); - Q_UNUSED(max); - // setSpan() takes care of keeping span in range - q_ptr->setSpan(lower, upper); -} - -void QxtSpanSliderPrivate::movePressedHandle() -{ - switch (lastPressed) - { - case QxtSpanSlider::LowerHandle: - if (lowerPos != lower) - { - bool main = (mainControl == QxtSpanSlider::LowerHandle); - triggerAction(QAbstractSlider::SliderMove, main); - } - break; - case QxtSpanSlider::UpperHandle: - if (upperPos != upper) - { - bool main = (mainControl == QxtSpanSlider::UpperHandle); - triggerAction(QAbstractSlider::SliderMove, main); - } - break; - default: - break; - } -} - -/*! - \class QxtSpanSlider - \inmodule QxtWidgets - \brief The QxtSpanSlider widget is a QSlider with two handles. - QxtSpanSlider is a slider with two handles. QxtSpanSlider is - handy for letting user to choose an span between min/max. - The span color is calculated based on QPalette::Highlight. - The keys are bound according to the following table: - \table - \header \o Orientation \o Key \o Handle - \row \o Qt::Horizontal \o Qt::Key_Left \o lower - \row \o Qt::Horizontal \o Qt::Key_Right \o lower - \row \o Qt::Horizontal \o Qt::Key_Up \o upper - \row \o Qt::Horizontal \o Qt::Key_Down \o upper - \row \o Qt::Vertical \o Qt::Key_Up \o lower - \row \o Qt::Vertical \o Qt::Key_Down \o lower - \row \o Qt::Vertical \o Qt::Key_Left \o upper - \row \o Qt::Vertical \o Qt::Key_Right \o upper - \endtable - Keys are bound by the time the slider is created. A key is bound - to same handle for the lifetime of the slider. So even if the handle - representation might change from lower to upper, the same key binding - remains. - \image qxtspanslider.png "QxtSpanSlider in Plastique style." - \bold {Note:} QxtSpanSlider inherits QSlider for implementation specific - reasons. Adjusting any single handle specific properties like - \list - \o QAbstractSlider::sliderPosition - \o QAbstractSlider::value - \endlist - has no effect. However, all slider specific properties like - \list - \o QAbstractSlider::invertedAppearance - \o QAbstractSlider::invertedControls - \o QAbstractSlider::minimum - \o QAbstractSlider::maximum - \o QAbstractSlider::orientation - \o QAbstractSlider::pageStep - \o QAbstractSlider::singleStep - \o QSlider::tickInterval - \o QSlider::tickPosition - \endlist - are taken into consideration. - */ - -/*! - \enum QxtSpanSlider::HandleMovementMode - This enum describes the available handle movement modes. - \value FreeMovement The handles can be moved freely. - \value NoCrossing The handles cannot cross, but they can still overlap each other. The lower and upper values can be the same. - \value NoOverlapping The handles cannot overlap each other. The lower and upper values cannot be the same. - */ - -/*! - \enum QxtSpanSlider::SpanHandle - This enum describes the available span handles. - \omitvalue NoHandle \omit Internal only (for now). \endomit - \value LowerHandle The lower boundary handle. - \value UpperHandle The upper boundary handle. - */ - -/*! - \fn QxtSpanSlider::lowerValueChanged(int lower) - This signal is emitted whenever the \a lower value has changed. - */ - -/*! - \fn QxtSpanSlider::upperValueChanged(int upper) - This signal is emitted whenever the \a upper value has changed. - */ - -/*! - \fn QxtSpanSlider::spanChanged(int lower, int upper) - This signal is emitted whenever both the \a lower and the \a upper - values have changed ie. the span has changed. - */ - -/*! - \fn QxtSpanSlider::lowerPositionChanged(int lower) - This signal is emitted whenever the \a lower position has changed. - */ - -/*! - \fn QxtSpanSlider::upperPositionChanged(int upper) - This signal is emitted whenever the \a upper position has changed. - */ - -/*! - \fn QxtSpanSlider::sliderPressed(SpanHandle handle) - This signal is emitted whenever the \a handle has been pressed. - */ - -/*! - Constructs a new QxtSpanSlider with \a parent. - */ -QxtSpanSlider::QxtSpanSlider(QWidget* parent) : QSlider(parent), d_ptr(new QxtSpanSliderPrivate()) -{ - d_ptr->q_ptr = this; - connect(this, SIGNAL(rangeChanged(int, int)), d_ptr, SLOT(updateRange(int, int))); - connect(this, SIGNAL(sliderReleased()), d_ptr, SLOT(movePressedHandle())); -} - -/*! - Constructs a new QxtSpanSlider with \a orientation and \a parent. - */ -QxtSpanSlider::QxtSpanSlider(Qt::Orientation orientation, QWidget* parent) : QSlider(orientation, parent), d_ptr(new QxtSpanSliderPrivate()) -{ - d_ptr->q_ptr = this; - connect(this, SIGNAL(rangeChanged(int, int)), d_ptr, SLOT(updateRange(int, int))); - connect(this, SIGNAL(sliderReleased()), d_ptr, SLOT(movePressedHandle())); -} - -/*! - Destructs the span slider. - */ -QxtSpanSlider::~QxtSpanSlider() -{ - if(d_ptr) - { - delete d_ptr; - } - d_ptr = NULL; -} - -/*! - \property QxtSpanSlider::handleMovementMode - \brief the handle movement mode - */ -QxtSpanSlider::HandleMovementMode QxtSpanSlider::handleMovementMode() const -{ - return d_ptr->movement; -} - -void QxtSpanSlider::setHandleMovementMode(QxtSpanSlider::HandleMovementMode mode) -{ - d_ptr->movement = mode; -} - -/*! - \property QxtSpanSlider::lowerValue - \brief the lower value of the span - */ -int QxtSpanSlider::lowerValue() const -{ - return qMin(d_ptr->lower, d_ptr->upper); -} - -void QxtSpanSlider::setLowerValue(int lower) -{ - setSpan(lower, d_ptr->upper); -} - -/*! - \property QxtSpanSlider::upperValue - \brief the upper value of the span - */ -int QxtSpanSlider::upperValue() const -{ - return qMax(d_ptr->lower, d_ptr->upper); -} - -void QxtSpanSlider::setUpperValue(int upper) -{ - setSpan(d_ptr->lower, upper); -} - -/*! - Sets the span from \a lower to \a upper. - */ -void QxtSpanSlider::setSpan(int lower, int upper) -{ - const int low = qBound(minimum(), lower, maximum()); - const int upp = qBound(minimum(), upper, maximum()); - if (low != d_ptr->lower || upp != d_ptr->upper) - { - if (low != d_ptr->lower) - { - d_ptr->lower = low; - d_ptr->lowerPos = low; - emit lowerValueChanged(low); - } - if (upp != d_ptr->upper) - { - d_ptr->upper = upp; - d_ptr->upperPos = upp; - emit upperValueChanged(upp); - } - emit spanChanged(d_ptr->lower, d_ptr->upper); - update(); - } -} - -/*! - \property QxtSpanSlider::lowerPosition - \brief the lower position of the span - */ -int QxtSpanSlider::lowerPosition() const -{ - return d_ptr->lowerPos; -} - -void QxtSpanSlider::setLowerPosition(int lower) -{ - if (d_ptr->lowerPos != lower) - { - d_ptr->lowerPos = lower; - if (!hasTracking()) - update(); - if (isSliderDown()) - emit lowerPositionChanged(lower); - if (hasTracking() && !d_ptr->blockTracking) - { - bool main = (d_ptr->mainControl == QxtSpanSlider::LowerHandle); - d_ptr->triggerAction(SliderMove, main); - } - } -} - -/*! - \property QxtSpanSlider::upperPosition - \brief the upper position of the span - */ -int QxtSpanSlider::upperPosition() const -{ - return d_ptr->upperPos; -} - -void QxtSpanSlider::setUpperPosition(int upper) -{ - if (d_ptr->upperPos != upper) - { - d_ptr->upperPos = upper; - if (!hasTracking()) - update(); - if (isSliderDown()) - emit upperPositionChanged(upper); - if (hasTracking() && !d_ptr->blockTracking) - { - bool main = (d_ptr->mainControl == QxtSpanSlider::UpperHandle); - d_ptr->triggerAction(SliderMove, main); - } - } -} - -/*! - \reimp - */ -void QxtSpanSlider::keyPressEvent(QKeyEvent* event) -{ - QSlider::keyPressEvent(event); - - bool main = true; - SliderAction action = SliderNoAction; - switch (event->key()) - { - case Qt::Key_Left: - main = (orientation() == Qt::Horizontal); - action = !invertedAppearance() ? SliderSingleStepSub : SliderSingleStepAdd; - break; - case Qt::Key_Right: - main = (orientation() == Qt::Horizontal); - action = !invertedAppearance() ? SliderSingleStepAdd : SliderSingleStepSub; - break; - case Qt::Key_Up: - main = (orientation() == Qt::Vertical); - action = invertedControls() ? SliderSingleStepSub : SliderSingleStepAdd; - break; - case Qt::Key_Down: - main = (orientation() == Qt::Vertical); - action = invertedControls() ? SliderSingleStepAdd : SliderSingleStepSub; - break; - case Qt::Key_Home: - main = (d_ptr->mainControl == QxtSpanSlider::LowerHandle); - action = SliderToMinimum; - break; - case Qt::Key_End: - main = (d_ptr->mainControl == QxtSpanSlider::UpperHandle); - action = SliderToMaximum; - break; - default: - event->ignore(); - break; - } - - if (action) - d_ptr->triggerAction(action, main); -} - -/*! - \reimp - */ -void QxtSpanSlider::mousePressEvent(QMouseEvent* event) -{ - if (minimum() == maximum() || (event->buttons() ^ event->button())) - { - event->ignore(); - return; - } - - d_ptr->handleMousePress(event->pos(), d_ptr->upperPressed, d_ptr->upper, QxtSpanSlider::UpperHandle); - if (d_ptr->upperPressed != QStyle::SC_SliderHandle) - d_ptr->handleMousePress(event->pos(), d_ptr->lowerPressed, d_ptr->lower, QxtSpanSlider::LowerHandle); - - d_ptr->firstMovement = true; - event->accept(); -} - -void QxtSpanSlider::mouseDoubleClickEvent(QMouseEvent *event) -{ - QSlider::mouseDoubleClickEvent(event); - emit sliderDoubleClick(event->globalX(), event->globalY()); -} - -/*! - \reimp - */ -void QxtSpanSlider::mouseMoveEvent(QMouseEvent* event) -{ - if (d_ptr->lowerPressed != QStyle::SC_SliderHandle && d_ptr->upperPressed != QStyle::SC_SliderHandle) - { - event->ignore(); - return; - } - - QStyleOptionSlider opt; - d_ptr->initStyleOption(&opt); - const int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this); - int newPosition = d_ptr->pixelPosToRangeValue(d_ptr->pick(event->pos()) - d_ptr->offset); - if (m >= 0) - { - const QRect r = rect().adjusted(-m, -m, m, m); - if (!r.contains(event->pos())) - { - newPosition = d_ptr->position; - } - } - - // pick the preferred handle on the first movement - if (d_ptr->firstMovement) - { - if (d_ptr->lower == d_ptr->upper) - { - if (newPosition < lowerValue()) - { - d_ptr->swapControls(); - d_ptr->firstMovement = false; - } - } - else - { - d_ptr->firstMovement = false; - } - } - - if (d_ptr->lowerPressed == QStyle::SC_SliderHandle) - { - if (d_ptr->movement == NoCrossing) - newPosition = qMin(newPosition, upperValue()); - else if (d_ptr->movement == NoOverlapping) - newPosition = qMin(newPosition, upperValue() - 1); - - if (d_ptr->movement == FreeMovement && newPosition > d_ptr->upper) - { - d_ptr->swapControls(); - setUpperPosition(newPosition); - } - else - { - setLowerPosition(newPosition); - } - } - else if (d_ptr->upperPressed == QStyle::SC_SliderHandle) - { - if (d_ptr->movement == NoCrossing) - newPosition = qMax(newPosition, lowerValue()); - else if (d_ptr->movement == NoOverlapping) - newPosition = qMax(newPosition, lowerValue() + 1); - - if (d_ptr->movement == FreeMovement && newPosition < d_ptr->lower) - { - d_ptr->swapControls(); - setLowerPosition(newPosition); - } - else - { - setUpperPosition(newPosition); - } - } - event->accept(); -} - -/*! - \reimp - */ -void QxtSpanSlider::mouseReleaseEvent(QMouseEvent* event) -{ - QSlider::mouseReleaseEvent(event); - setSliderDown(false); - d_ptr->lowerPressed = QStyle::SC_None; - d_ptr->upperPressed = QStyle::SC_None; - update(); -} - -/*! - \reimp - */ -void QxtSpanSlider::paintEvent(QPaintEvent* event) -{ - Q_UNUSED(event); - QStylePainter painter(this); - - // groove & ticks - QStyleOptionSlider opt; - d_ptr->initStyleOption(&opt); - opt.sliderValue = 0; - opt.sliderPosition = 0; - opt.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderTickmarks; - painter.drawComplexControl(QStyle::CC_Slider, opt); - - // handle rects - opt.sliderPosition = d_ptr->lowerPos; - const QRect lr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); - const int lrv = d_ptr->pick(lr.center()); - opt.sliderPosition = d_ptr->upperPos; - const QRect ur = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); - const int urv = d_ptr->pick(ur.center()); - - // span - const int minv = qMin(lrv, urv); - const int maxv = qMax(lrv, urv); - const QPoint c = QRect(lr.center(), ur.center()).center(); - QRect spanRect; - if (orientation() == Qt::Horizontal) - spanRect = QRect(QPoint(minv, c.y() - 2), QPoint(maxv, c.y() + 1)); - else - spanRect = QRect(QPoint(c.x() - 2, minv), QPoint(c.x() + 1, maxv)); - d_ptr->drawSpan(&painter, spanRect); - - // handles - switch (d_ptr->lastPressed) - { - case QxtSpanSlider::LowerHandle: - d_ptr->drawHandle(&painter, QxtSpanSlider::UpperHandle); - d_ptr->drawHandle(&painter, QxtSpanSlider::LowerHandle); - break; - case QxtSpanSlider::UpperHandle: - default: - d_ptr->drawHandle(&painter, QxtSpanSlider::LowerHandle); - d_ptr->drawHandle(&painter, QxtSpanSlider::UpperHandle); - break; - } -} +#include "QxtSpanSlider.h" +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +#include "QxtSpanSlider_p.h" +#include +#include +#include +#include +#include +#include + +QxtSpanSliderPrivate::QxtSpanSliderPrivate() : + lower(0), + upper(0), + lowerPos(0), + upperPos(0), + offset(0), + position(0), + lastPressed(QxtSpanSlider::NoHandle), + mainControl(QxtSpanSlider::LowerHandle), + lowerPressed(QStyle::SC_None), + upperPressed(QStyle::SC_None), + movement(QxtSpanSlider::FreeMovement), + firstMovement(false), + blockTracking(false) +{ +} + +void QxtSpanSliderPrivate::initStyleOption(QStyleOptionSlider* option, QxtSpanSlider::SpanHandle handle) const +{ + const QxtSpanSlider* p = q_ptr; + p->initStyleOption(option); + option->sliderPosition = (handle == QxtSpanSlider::LowerHandle ? lowerPos : upperPos); + option->sliderValue = (handle == QxtSpanSlider::LowerHandle ? lower : upper); +} + +int QxtSpanSliderPrivate::pixelPosToRangeValue(int pos) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt); + + int sliderMin = 0; + int sliderMax = 0; + int sliderLength = 0; + const QSlider* p = q_ptr; + const QRect gr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, p); + const QRect sr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, p); + if (p->orientation() == Qt::Horizontal) + { + sliderLength = sr.width(); + sliderMin = gr.x(); + sliderMax = gr.right() - sliderLength + 1; + } + else + { + sliderLength = sr.height(); + sliderMin = gr.y(); + sliderMax = gr.bottom() - sliderLength + 1; + } + return QStyle::sliderValueFromPosition(p->minimum(), p->maximum(), pos - sliderMin, + sliderMax - sliderMin, opt.upsideDown); +} + +void QxtSpanSliderPrivate::handleMousePress(const QPoint& pos, QStyle::SubControl& control, int value, QxtSpanSlider::SpanHandle handle) +{ + QStyleOptionSlider opt; + initStyleOption(&opt, handle); + QxtSpanSlider* p = q_ptr; + const QStyle::SubControl oldControl = control; + control = p->style()->hitTestComplexControl(QStyle::CC_Slider, &opt, pos, p); + const QRect sr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, p); + if (control == QStyle::SC_SliderHandle) + { + position = value; + offset = pick(pos - sr.topLeft()); + lastPressed = handle; + p->setSliderDown(true); + emit p->sliderPressed(handle); + } + if (control != oldControl) + p->update(sr); +} + +void QxtSpanSliderPrivate::setupPainter(QPainter* painter, Qt::Orientation orientation, qreal x1, qreal y1, qreal x2, qreal y2) const +{ + QColor highlight = q_ptr->palette().color(QPalette::Highlight); + QLinearGradient gradient(x1, y1, x2, y2); + gradient.setColorAt(0, highlight.dark(120)); + gradient.setColorAt(1, highlight.light(108)); + painter->setBrush(gradient); + + if (orientation == Qt::Horizontal) + painter->setPen(QPen(highlight.dark(130), 0)); + else + painter->setPen(QPen(highlight.dark(150), 0)); +} + +void QxtSpanSliderPrivate::drawSpan(QStylePainter* painter, const QRect& rect) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt); + const QSlider* p = q_ptr; + + // area + QRect groove = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, p); + if (opt.orientation == Qt::Horizontal) + groove.adjust(0, 0, -1, 0); + else + groove.adjust(0, 0, 0, -1); + + // pen & brush + painter->setPen(QPen(p->palette().color(QPalette::Dark).light(110), 0)); + if (opt.orientation == Qt::Horizontal) + setupPainter(painter, opt.orientation, groove.center().x(), groove.top(), groove.center().x(), groove.bottom()); + else + setupPainter(painter, opt.orientation, groove.left(), groove.center().y(), groove.right(), groove.center().y()); + + // draw groove + painter->drawRect(rect.intersected(groove)); +} + +void QxtSpanSliderPrivate::drawHandle(QStylePainter* painter, QxtSpanSlider::SpanHandle handle) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt, handle); + opt.subControls = QStyle::SC_SliderHandle; + QStyle::SubControl pressed = (handle == QxtSpanSlider::LowerHandle ? lowerPressed : upperPressed); + if (pressed == QStyle::SC_SliderHandle) + { + opt.activeSubControls = pressed; + opt.state |= QStyle::State_Sunken; + } + painter->drawComplexControl(QStyle::CC_Slider, opt); +} + +void QxtSpanSliderPrivate::triggerAction(QAbstractSlider::SliderAction action, bool main) +{ + int value = 0; + bool no = false; + bool up = false; + const int min = q_ptr->minimum(); + const int max = q_ptr->maximum(); + const QxtSpanSlider::SpanHandle altControl = (mainControl == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); + + blockTracking = true; + + switch (action) + { + case QAbstractSlider::SliderSingleStepAdd: + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + { + value = qBound(min, upper + q_ptr->singleStep(), max); + up = true; + break; + } + value = qBound(min, lower + q_ptr->singleStep(), max); + break; + case QAbstractSlider::SliderSingleStepSub: + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + { + value = qBound(min, upper - q_ptr->singleStep(), max); + up = true; + break; + } + value = qBound(min, lower - q_ptr->singleStep(), max); + break; + case QAbstractSlider::SliderToMinimum: + value = min; + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + up = true; + break; + case QAbstractSlider::SliderToMaximum: + value = max; + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + up = true; + break; + case QAbstractSlider::SliderMove: + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + up = true; + case QAbstractSlider::SliderNoAction: + no = true; + break; + default: + qWarning("QxtSpanSliderPrivate::triggerAction: Unknown action"); + break; + } + + if (!no && !up) + { + if (movement == QxtSpanSlider::NoCrossing) + value = qMin(value, upper); + else if (movement == QxtSpanSlider::NoOverlapping) + value = qMin(value, upper - 1); + + if (movement == QxtSpanSlider::FreeMovement && value > upper) + { + swapControls(); + q_ptr->setUpperPosition(value); + } + else + { + q_ptr->setLowerPosition(value); + } + } + else if (!no) + { + if (movement == QxtSpanSlider::NoCrossing) + value = qMax(value, lower); + else if (movement == QxtSpanSlider::NoOverlapping) + value = qMax(value, lower + 1); + + if (movement == QxtSpanSlider::FreeMovement && value < lower) + { + swapControls(); + q_ptr->setLowerPosition(value); + } + else + { + q_ptr->setUpperPosition(value); + } + } + + blockTracking = false; + q_ptr->setLowerValue(lowerPos); + q_ptr->setUpperValue(upperPos); +} + +void QxtSpanSliderPrivate::swapControls() +{ + qSwap(lower, upper); + qSwap(lowerPressed, upperPressed); + lastPressed = (lastPressed == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); + mainControl = (mainControl == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); +} + +void QxtSpanSliderPrivate::updateRange(int min, int max) +{ + Q_UNUSED(min); + Q_UNUSED(max); + // setSpan() takes care of keeping span in range + q_ptr->setSpan(lower, upper); +} + +void QxtSpanSliderPrivate::movePressedHandle() +{ + switch (lastPressed) + { + case QxtSpanSlider::LowerHandle: + if (lowerPos != lower) + { + bool main = (mainControl == QxtSpanSlider::LowerHandle); + triggerAction(QAbstractSlider::SliderMove, main); + } + break; + case QxtSpanSlider::UpperHandle: + if (upperPos != upper) + { + bool main = (mainControl == QxtSpanSlider::UpperHandle); + triggerAction(QAbstractSlider::SliderMove, main); + } + break; + default: + break; + } +} + +/*! + \class QxtSpanSlider + \inmodule QxtWidgets + \brief The QxtSpanSlider widget is a QSlider with two handles. + QxtSpanSlider is a slider with two handles. QxtSpanSlider is + handy for letting user to choose an span between min/max. + The span color is calculated based on QPalette::Highlight. + The keys are bound according to the following table: + \table + \header \o Orientation \o Key \o Handle + \row \o Qt::Horizontal \o Qt::Key_Left \o lower + \row \o Qt::Horizontal \o Qt::Key_Right \o lower + \row \o Qt::Horizontal \o Qt::Key_Up \o upper + \row \o Qt::Horizontal \o Qt::Key_Down \o upper + \row \o Qt::Vertical \o Qt::Key_Up \o lower + \row \o Qt::Vertical \o Qt::Key_Down \o lower + \row \o Qt::Vertical \o Qt::Key_Left \o upper + \row \o Qt::Vertical \o Qt::Key_Right \o upper + \endtable + Keys are bound by the time the slider is created. A key is bound + to same handle for the lifetime of the slider. So even if the handle + representation might change from lower to upper, the same key binding + remains. + \image qxtspanslider.png "QxtSpanSlider in Plastique style." + \bold {Note:} QxtSpanSlider inherits QSlider for implementation specific + reasons. Adjusting any single handle specific properties like + \list + \o QAbstractSlider::sliderPosition + \o QAbstractSlider::value + \endlist + has no effect. However, all slider specific properties like + \list + \o QAbstractSlider::invertedAppearance + \o QAbstractSlider::invertedControls + \o QAbstractSlider::minimum + \o QAbstractSlider::maximum + \o QAbstractSlider::orientation + \o QAbstractSlider::pageStep + \o QAbstractSlider::singleStep + \o QSlider::tickInterval + \o QSlider::tickPosition + \endlist + are taken into consideration. + */ + +/*! + \enum QxtSpanSlider::HandleMovementMode + This enum describes the available handle movement modes. + \value FreeMovement The handles can be moved freely. + \value NoCrossing The handles cannot cross, but they can still overlap each other. The lower and upper values can be the same. + \value NoOverlapping The handles cannot overlap each other. The lower and upper values cannot be the same. + */ + +/*! + \enum QxtSpanSlider::SpanHandle + This enum describes the available span handles. + \omitvalue NoHandle \omit Internal only (for now). \endomit + \value LowerHandle The lower boundary handle. + \value UpperHandle The upper boundary handle. + */ + +/*! + \fn QxtSpanSlider::lowerValueChanged(int lower) + This signal is emitted whenever the \a lower value has changed. + */ + +/*! + \fn QxtSpanSlider::upperValueChanged(int upper) + This signal is emitted whenever the \a upper value has changed. + */ + +/*! + \fn QxtSpanSlider::spanChanged(int lower, int upper) + This signal is emitted whenever both the \a lower and the \a upper + values have changed ie. the span has changed. + */ + +/*! + \fn QxtSpanSlider::lowerPositionChanged(int lower) + This signal is emitted whenever the \a lower position has changed. + */ + +/*! + \fn QxtSpanSlider::upperPositionChanged(int upper) + This signal is emitted whenever the \a upper position has changed. + */ + +/*! + \fn QxtSpanSlider::sliderPressed(SpanHandle handle) + This signal is emitted whenever the \a handle has been pressed. + */ + +/*! + Constructs a new QxtSpanSlider with \a parent. + */ +QxtSpanSlider::QxtSpanSlider(QWidget* parent) : QSlider(parent), d_ptr(new QxtSpanSliderPrivate()) +{ + d_ptr->q_ptr = this; + connect(this, SIGNAL(rangeChanged(int, int)), d_ptr, SLOT(updateRange(int, int))); + connect(this, SIGNAL(sliderReleased()), d_ptr, SLOT(movePressedHandle())); +} + +/*! + Constructs a new QxtSpanSlider with \a orientation and \a parent. + */ +QxtSpanSlider::QxtSpanSlider(Qt::Orientation orientation, QWidget* parent) : QSlider(orientation, parent), d_ptr(new QxtSpanSliderPrivate()) +{ + d_ptr->q_ptr = this; + connect(this, SIGNAL(rangeChanged(int, int)), d_ptr, SLOT(updateRange(int, int))); + connect(this, SIGNAL(sliderReleased()), d_ptr, SLOT(movePressedHandle())); +} + +/*! + Destructs the span slider. + */ +QxtSpanSlider::~QxtSpanSlider() +{ + if(d_ptr) + { + delete d_ptr; + } + d_ptr = NULL; +} + +/*! + \property QxtSpanSlider::handleMovementMode + \brief the handle movement mode + */ +QxtSpanSlider::HandleMovementMode QxtSpanSlider::handleMovementMode() const +{ + return d_ptr->movement; +} + +void QxtSpanSlider::setHandleMovementMode(QxtSpanSlider::HandleMovementMode mode) +{ + d_ptr->movement = mode; +} + +/*! + \property QxtSpanSlider::lowerValue + \brief the lower value of the span + */ +int QxtSpanSlider::lowerValue() const +{ + return qMin(d_ptr->lower, d_ptr->upper); +} + +void QxtSpanSlider::setLowerValue(int lower) +{ + setSpan(lower, d_ptr->upper); +} + +/*! + \property QxtSpanSlider::upperValue + \brief the upper value of the span + */ +int QxtSpanSlider::upperValue() const +{ + return qMax(d_ptr->lower, d_ptr->upper); +} + +void QxtSpanSlider::setUpperValue(int upper) +{ + setSpan(d_ptr->lower, upper); +} + +/*! + Sets the span from \a lower to \a upper. + */ +void QxtSpanSlider::setSpan(int lower, int upper) +{ + const int low = qBound(minimum(), lower, maximum()); + const int upp = qBound(minimum(), upper, maximum()); + if (low != d_ptr->lower || upp != d_ptr->upper) + { + if (low != d_ptr->lower) + { + d_ptr->lower = low; + d_ptr->lowerPos = low; + emit lowerValueChanged(low); + } + if (upp != d_ptr->upper) + { + d_ptr->upper = upp; + d_ptr->upperPos = upp; + emit upperValueChanged(upp); + } + emit spanChanged(d_ptr->lower, d_ptr->upper); + update(); + } +} + +/*! + \property QxtSpanSlider::lowerPosition + \brief the lower position of the span + */ +int QxtSpanSlider::lowerPosition() const +{ + return d_ptr->lowerPos; +} + +void QxtSpanSlider::setLowerPosition(int lower) +{ + if (d_ptr->lowerPos != lower) + { + d_ptr->lowerPos = lower; + if (!hasTracking()) + update(); + if (isSliderDown()) + emit lowerPositionChanged(lower); + if (hasTracking() && !d_ptr->blockTracking) + { + bool main = (d_ptr->mainControl == QxtSpanSlider::LowerHandle); + d_ptr->triggerAction(SliderMove, main); + } + } +} + +/*! + \property QxtSpanSlider::upperPosition + \brief the upper position of the span + */ +int QxtSpanSlider::upperPosition() const +{ + return d_ptr->upperPos; +} + +void QxtSpanSlider::setUpperPosition(int upper) +{ + if (d_ptr->upperPos != upper) + { + d_ptr->upperPos = upper; + if (!hasTracking()) + update(); + if (isSliderDown()) + emit upperPositionChanged(upper); + if (hasTracking() && !d_ptr->blockTracking) + { + bool main = (d_ptr->mainControl == QxtSpanSlider::UpperHandle); + d_ptr->triggerAction(SliderMove, main); + } + } +} + +/*! + \reimp + */ +void QxtSpanSlider::keyPressEvent(QKeyEvent* event) +{ + QSlider::keyPressEvent(event); + + bool main = true; + SliderAction action = SliderNoAction; + switch (event->key()) + { + case Qt::Key_Left: + main = (orientation() == Qt::Horizontal); + action = !invertedAppearance() ? SliderSingleStepSub : SliderSingleStepAdd; + break; + case Qt::Key_Right: + main = (orientation() == Qt::Horizontal); + action = !invertedAppearance() ? SliderSingleStepAdd : SliderSingleStepSub; + break; + case Qt::Key_Up: + main = (orientation() == Qt::Vertical); + action = invertedControls() ? SliderSingleStepSub : SliderSingleStepAdd; + break; + case Qt::Key_Down: + main = (orientation() == Qt::Vertical); + action = invertedControls() ? SliderSingleStepAdd : SliderSingleStepSub; + break; + case Qt::Key_Home: + main = (d_ptr->mainControl == QxtSpanSlider::LowerHandle); + action = SliderToMinimum; + break; + case Qt::Key_End: + main = (d_ptr->mainControl == QxtSpanSlider::UpperHandle); + action = SliderToMaximum; + break; + default: + event->ignore(); + break; + } + + if (action) + d_ptr->triggerAction(action, main); +} + +/*! + \reimp + */ +void QxtSpanSlider::mousePressEvent(QMouseEvent* event) +{ + if (minimum() == maximum() || (event->buttons() ^ event->button())) + { + event->ignore(); + return; + } + + d_ptr->handleMousePress(event->pos(), d_ptr->upperPressed, d_ptr->upper, QxtSpanSlider::UpperHandle); + if (d_ptr->upperPressed != QStyle::SC_SliderHandle) + d_ptr->handleMousePress(event->pos(), d_ptr->lowerPressed, d_ptr->lower, QxtSpanSlider::LowerHandle); + + d_ptr->firstMovement = true; + event->accept(); +} + +void QxtSpanSlider::mouseDoubleClickEvent(QMouseEvent *event) +{ + QSlider::mouseDoubleClickEvent(event); + emit sliderDoubleClick(event->globalX(), event->globalY()); +} + +/*! + \reimp + */ +void QxtSpanSlider::mouseMoveEvent(QMouseEvent* event) +{ + if (d_ptr->lowerPressed != QStyle::SC_SliderHandle && d_ptr->upperPressed != QStyle::SC_SliderHandle) + { + event->ignore(); + return; + } + + QStyleOptionSlider opt; + d_ptr->initStyleOption(&opt); + const int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this); + int newPosition = d_ptr->pixelPosToRangeValue(d_ptr->pick(event->pos()) - d_ptr->offset); + if (m >= 0) + { + const QRect r = rect().adjusted(-m, -m, m, m); + if (!r.contains(event->pos())) + { + newPosition = d_ptr->position; + } + } + + // pick the preferred handle on the first movement + if (d_ptr->firstMovement) + { + if (d_ptr->lower == d_ptr->upper) + { + if (newPosition < lowerValue()) + { + d_ptr->swapControls(); + d_ptr->firstMovement = false; + } + } + else + { + d_ptr->firstMovement = false; + } + } + + if (d_ptr->lowerPressed == QStyle::SC_SliderHandle) + { + if (d_ptr->movement == NoCrossing) + newPosition = qMin(newPosition, upperValue()); + else if (d_ptr->movement == NoOverlapping) + newPosition = qMin(newPosition, upperValue() - 1); + + if (d_ptr->movement == FreeMovement && newPosition > d_ptr->upper) + { + d_ptr->swapControls(); + setUpperPosition(newPosition); + } + else + { + setLowerPosition(newPosition); + } + } + else if (d_ptr->upperPressed == QStyle::SC_SliderHandle) + { + if (d_ptr->movement == NoCrossing) + newPosition = qMax(newPosition, lowerValue()); + else if (d_ptr->movement == NoOverlapping) + newPosition = qMax(newPosition, lowerValue() + 1); + + if (d_ptr->movement == FreeMovement && newPosition < d_ptr->lower) + { + d_ptr->swapControls(); + setLowerPosition(newPosition); + } + else + { + setUpperPosition(newPosition); + } + } + event->accept(); +} + +/*! + \reimp + */ +void QxtSpanSlider::mouseReleaseEvent(QMouseEvent* event) +{ + QSlider::mouseReleaseEvent(event); + setSliderDown(false); + d_ptr->lowerPressed = QStyle::SC_None; + d_ptr->upperPressed = QStyle::SC_None; + update(); +} + +/*! + \reimp + */ +void QxtSpanSlider::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + QStylePainter painter(this); + + // groove & ticks + QStyleOptionSlider opt; + d_ptr->initStyleOption(&opt); + opt.sliderValue = 0; + opt.sliderPosition = 0; + opt.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderTickmarks; + painter.drawComplexControl(QStyle::CC_Slider, opt); + + // handle rects + opt.sliderPosition = d_ptr->lowerPos; + const QRect lr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + const int lrv = d_ptr->pick(lr.center()); + opt.sliderPosition = d_ptr->upperPos; + const QRect ur = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + const int urv = d_ptr->pick(ur.center()); + + // span + const int minv = qMin(lrv, urv); + const int maxv = qMax(lrv, urv); + const QPoint c = QRect(lr.center(), ur.center()).center(); + QRect spanRect; + if (orientation() == Qt::Horizontal) + spanRect = QRect(QPoint(minv, c.y() - 2), QPoint(maxv, c.y() + 1)); + else + spanRect = QRect(QPoint(c.x() - 2, minv), QPoint(c.x() + 1, maxv)); + d_ptr->drawSpan(&painter, spanRect); + + // handles + switch (d_ptr->lastPressed) + { + case QxtSpanSlider::LowerHandle: + d_ptr->drawHandle(&painter, QxtSpanSlider::UpperHandle); + d_ptr->drawHandle(&painter, QxtSpanSlider::LowerHandle); + break; + case QxtSpanSlider::UpperHandle: + default: + d_ptr->drawHandle(&painter, QxtSpanSlider::LowerHandle); + d_ptr->drawHandle(&painter, QxtSpanSlider::UpperHandle); + break; + } +} diff --git a/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider.h b/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider.h index 184fc806..cf09f570 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider.h +++ b/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider.h @@ -1,111 +1,111 @@ -#ifndef QXTSPANSLIDER_H -/**************************************************************************** -** Copyright (c) 2006 - 2011, the LibQxt project. -** See the Qxt AUTHORS file for a list of authors and copyright holders. -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** * Neither the name of the LibQxt project nor the -** names of its contributors may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -** -*****************************************************************************/ - -#define QXTSPANSLIDER_H - -#include -//#include "qxtnamespace.h" -//#include "qxtglobal.h" - -class QxtSpanSliderPrivate; - -class QxtSpanSlider : public QSlider { - Q_OBJECT - - //QXT_DECLARE_PRIVATE(QxtSpanSlider) - Q_PROPERTY(int lowerValue READ lowerValue WRITE setLowerValue) - Q_PROPERTY(int upperValue READ upperValue WRITE setUpperValue) - Q_PROPERTY(int lowerPosition READ lowerPosition WRITE setLowerPosition) - Q_PROPERTY(int upperPosition READ upperPosition WRITE setUpperPosition) - Q_PROPERTY(HandleMovementMode handleMovementMode READ handleMovementMode WRITE setHandleMovementMode) - Q_ENUMS(HandleMovementMode) - -public: - explicit QxtSpanSlider(QWidget* parent = 0); - explicit QxtSpanSlider(Qt::Orientation orientation, QWidget* parent = 0); - virtual ~QxtSpanSlider(); - - enum HandleMovementMode - { - FreeMovement, - NoCrossing, - NoOverlapping - }; - - enum SpanHandle - { - NoHandle, - LowerHandle, - UpperHandle - }; - - HandleMovementMode handleMovementMode() const; - void setHandleMovementMode(HandleMovementMode mode); - - int lowerValue() const; - int upperValue() const; - - int lowerPosition() const; - int upperPosition() const; - -public Q_SLOTS: - void setLowerValue(int lower); - void setUpperValue(int upper); - void setSpan(int lower, int upper); - - void setLowerPosition(int lower); - void setUpperPosition(int upper); - -Q_SIGNALS: - void spanChanged(int lower, int upper); - void lowerValueChanged(int lower); - void upperValueChanged(int upper); - - void lowerPositionChanged(int lower); - void upperPositionChanged(int upper); - - void sliderPressed(SpanHandle handle); - void sliderDoubleClick(int x, int y); - -protected: - virtual void keyPressEvent(QKeyEvent* event); - virtual void mousePressEvent(QMouseEvent* event); - virtual void mouseDoubleClickEvent(QMouseEvent* event); - virtual void mouseMoveEvent(QMouseEvent* event); - virtual void mouseReleaseEvent(QMouseEvent* event); - virtual void paintEvent(QPaintEvent* event); - -private: - QxtSpanSliderPrivate* d_ptr; - friend class QxtSpanSliderPrivate; -}; - +#ifndef QXTSPANSLIDER_H +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +#define QXTSPANSLIDER_H + +#include +//#include "qxtnamespace.h" +//#include "qxtglobal.h" + +class QxtSpanSliderPrivate; + +class QxtSpanSlider : public QSlider { + Q_OBJECT + + //QXT_DECLARE_PRIVATE(QxtSpanSlider) + Q_PROPERTY(int lowerValue READ lowerValue WRITE setLowerValue) + Q_PROPERTY(int upperValue READ upperValue WRITE setUpperValue) + Q_PROPERTY(int lowerPosition READ lowerPosition WRITE setLowerPosition) + Q_PROPERTY(int upperPosition READ upperPosition WRITE setUpperPosition) + Q_PROPERTY(HandleMovementMode handleMovementMode READ handleMovementMode WRITE setHandleMovementMode) + Q_ENUMS(HandleMovementMode) + +public: + explicit QxtSpanSlider(QWidget* parent = 0); + explicit QxtSpanSlider(Qt::Orientation orientation, QWidget* parent = 0); + virtual ~QxtSpanSlider(); + + enum HandleMovementMode + { + FreeMovement, + NoCrossing, + NoOverlapping + }; + + enum SpanHandle + { + NoHandle, + LowerHandle, + UpperHandle + }; + + HandleMovementMode handleMovementMode() const; + void setHandleMovementMode(HandleMovementMode mode); + + int lowerValue() const; + int upperValue() const; + + int lowerPosition() const; + int upperPosition() const; + +public Q_SLOTS: + void setLowerValue(int lower); + void setUpperValue(int upper); + void setSpan(int lower, int upper); + + void setLowerPosition(int lower); + void setUpperPosition(int upper); + +Q_SIGNALS: + void spanChanged(int lower, int upper); + void lowerValueChanged(int lower); + void upperValueChanged(int upper); + + void lowerPositionChanged(int lower); + void upperPositionChanged(int upper); + + void sliderPressed(SpanHandle handle); + void sliderDoubleClick(int x, int y); + +protected: + virtual void keyPressEvent(QKeyEvent* event); + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseDoubleClickEvent(QMouseEvent* event); + virtual void mouseMoveEvent(QMouseEvent* event); + virtual void mouseReleaseEvent(QMouseEvent* event); + virtual void paintEvent(QPaintEvent* event); + +private: + QxtSpanSliderPrivate* d_ptr; + friend class QxtSpanSliderPrivate; +}; + #endif // QXTSPANSLIDER_H \ No newline at end of file diff --git a/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider_p.h b/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider_p.h index 3ffba962..0c58fe07 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider_p.h +++ b/product/src/gui/plugin/TrendCurves/widgets/QxtSpanSlider_p.h @@ -1,84 +1,84 @@ -#ifndef QXTSPANSLIDER_P_H -/**************************************************************************** -** Copyright (c) 2006 - 2011, the LibQxt project. -** See the Qxt AUTHORS file for a list of authors and copyright holders. -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** * Neither the name of the LibQxt project nor the -** names of its contributors may be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -** -*****************************************************************************/ - -#define QXTSPANSLIDER_P_H - -#include -#include -#include "QxtSpanSlider.h" - -QT_FORWARD_DECLARE_CLASS(QStylePainter) -QT_FORWARD_DECLARE_CLASS(QStyleOptionSlider) - -class QxtSpanSliderPrivate : public QObject { - Q_OBJECT -public: - QxtSpanSliderPrivate(); - void initStyleOption(QStyleOptionSlider* option, QxtSpanSlider::SpanHandle handle = QxtSpanSlider::UpperHandle) const; - int pick(const QPoint& pt) const - { - return q_ptr->orientation() == Qt::Horizontal ? pt.x() : pt.y(); - } - int pixelPosToRangeValue(int pos) const; - void handleMousePress(const QPoint& pos, QStyle::SubControl& control, int value, QxtSpanSlider::SpanHandle handle); - void drawHandle(QStylePainter* painter, QxtSpanSlider::SpanHandle handle) const; - void setupPainter(QPainter* painter, Qt::Orientation orientation, qreal x1, qreal y1, qreal x2, qreal y2) const; - void drawSpan(QStylePainter* painter, const QRect& rect) const; - void triggerAction(QAbstractSlider::SliderAction action, bool main); - void swapControls(); - - int lower; - int upper; - int lowerPos; - int upperPos; - int offset; - int position; - QxtSpanSlider::SpanHandle lastPressed; - QxtSpanSlider::SpanHandle mainControl; - QStyle::SubControl lowerPressed; - QStyle::SubControl upperPressed; - QxtSpanSlider::HandleMovementMode movement; - bool firstMovement; - bool blockTracking; - - -public Q_SLOTS: - void updateRange(int min, int max); - void movePressedHandle(); - -private: - QxtSpanSlider* q_ptr; - friend class QxtSpanSlider; - - -}; - -#endif // QXTSPANSLIDER_P_H +#ifndef QXTSPANSLIDER_P_H +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +#define QXTSPANSLIDER_P_H + +#include +#include +#include "QxtSpanSlider.h" + +QT_FORWARD_DECLARE_CLASS(QStylePainter) +QT_FORWARD_DECLARE_CLASS(QStyleOptionSlider) + +class QxtSpanSliderPrivate : public QObject { + Q_OBJECT +public: + QxtSpanSliderPrivate(); + void initStyleOption(QStyleOptionSlider* option, QxtSpanSlider::SpanHandle handle = QxtSpanSlider::UpperHandle) const; + int pick(const QPoint& pt) const + { + return q_ptr->orientation() == Qt::Horizontal ? pt.x() : pt.y(); + } + int pixelPosToRangeValue(int pos) const; + void handleMousePress(const QPoint& pos, QStyle::SubControl& control, int value, QxtSpanSlider::SpanHandle handle); + void drawHandle(QStylePainter* painter, QxtSpanSlider::SpanHandle handle) const; + void setupPainter(QPainter* painter, Qt::Orientation orientation, qreal x1, qreal y1, qreal x2, qreal y2) const; + void drawSpan(QStylePainter* painter, const QRect& rect) const; + void triggerAction(QAbstractSlider::SliderAction action, bool main); + void swapControls(); + + int lower; + int upper; + int lowerPos; + int upperPos; + int offset; + int position; + QxtSpanSlider::SpanHandle lastPressed; + QxtSpanSlider::SpanHandle mainControl; + QStyle::SubControl lowerPressed; + QStyle::SubControl upperPressed; + QxtSpanSlider::HandleMovementMode movement; + bool firstMovement; + bool blockTracking; + + +public Q_SLOTS: + void updateRange(int min, int max); + void movePressedHandle(); + +private: + QxtSpanSlider* q_ptr; + friend class QxtSpanSlider; + + +}; + +#endif // QXTSPANSLIDER_P_H diff --git a/product/src/gui/plugin/UserManageWidget/UserDbOpt.cpp b/product/src/gui/plugin/UserManageWidget/UserDbOpt.cpp index 2d83af5f..1889fea7 100644 --- a/product/src/gui/plugin/UserManageWidget/UserDbOpt.cpp +++ b/product/src/gui/plugin/UserManageWidget/UserDbOpt.cpp @@ -1,17 +1,17 @@ -#include "UserDbOpt.h" -#include "kbdtabledatamgr.h" - -UserDbOpt::UserDbOpt() -{ - -} - -UserDbOpt::~UserDbOpt() -{ - -} - -QString UserDbOpt::initilize() -{ - return KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); -} +#include "UserDbOpt.h" +#include "kbdtabledatamgr.h" + +UserDbOpt::UserDbOpt() +{ + +} + +UserDbOpt::~UserDbOpt() +{ + +} + +QString UserDbOpt::initilize() +{ + return KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); +} diff --git a/product/src/gui/plugin/UserManageWidget/UserDbOpt.h b/product/src/gui/plugin/UserManageWidget/UserDbOpt.h index d51670e3..0315071c 100644 --- a/product/src/gui/plugin/UserManageWidget/UserDbOpt.h +++ b/product/src/gui/plugin/UserManageWidget/UserDbOpt.h @@ -1,16 +1,16 @@ -#ifndef USERDBOPT_H -#define USERDBOPT_H - -#include - -class UserDbOpt -{ -public: - UserDbOpt(); - ~UserDbOpt(); - -public: - QString initilize(); -}; - -#endif // USERDBOPT_H +#ifndef USERDBOPT_H +#define USERDBOPT_H + +#include + +class UserDbOpt +{ +public: + UserDbOpt(); + ~UserDbOpt(); + +public: + QString initilize(); +}; + +#endif // USERDBOPT_H diff --git a/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.cpp b/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.cpp index 161ae35f..4dbd8d29 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.cpp +++ b/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.cpp @@ -1,28 +1,28 @@ -#include -#include "UserManagePluginWidget.h" -#include "UserManageWidget.h" -#include "pub_logger_api/logger.h" -UserManagePluginWidget::UserManagePluginWidget(QObject *parent): QObject(parent) -{ - -} - -UserManagePluginWidget::~UserManagePluginWidget() -{ - -} - -bool UserManagePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - UserManageWidget *pWidget = new UserManageWidget(parent, editMode); - pWidget->initialize((int)E_Window_UserGroup); - *widget = (QWidget *)pWidget; - *alarmWidget = (IPluginWidget *)pWidget; - return true; -} - -void UserManagePluginWidget::release() -{ - -} +#include +#include "UserManagePluginWidget.h" +#include "UserManageWidget.h" +#include "pub_logger_api/logger.h" +UserManagePluginWidget::UserManagePluginWidget(QObject *parent): QObject(parent) +{ + +} + +UserManagePluginWidget::~UserManagePluginWidget() +{ + +} + +bool UserManagePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + UserManageWidget *pWidget = new UserManageWidget(parent, editMode); + pWidget->initialize((int)E_Window_UserGroup); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + return true; +} + +void UserManagePluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.h b/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.h index f240dba1..0652b4e6 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.h +++ b/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.h @@ -1,21 +1,21 @@ -#ifndef USERMANAGEPLUGINWIDGET_H -#define USERMANAGEPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class UserManagePluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - UserManagePluginWidget(QObject *parent = 0); - ~UserManagePluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); - void release(); -}; - -#endif // USERMANAGEPLUGINWIDGET_H +#ifndef USERMANAGEPLUGINWIDGET_H +#define USERMANAGEPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class UserManagePluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + UserManagePluginWidget(QObject *parent = 0); + ~UserManagePluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif // USERMANAGEPLUGINWIDGET_H diff --git a/product/src/gui/plugin/UserManageWidget/UserManageWidget.cpp b/product/src/gui/plugin/UserManageWidget/UserManageWidget.cpp index 7f2985a5..b24fda25 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManageWidget.cpp +++ b/product/src/gui/plugin/UserManageWidget/UserManageWidget.cpp @@ -1,176 +1,176 @@ -#include "UserManageWidget.h" -#include "ui_UserManageWidget.h" -#include -#include -#include -#include -#include "../../../tools/model_user/kbduserwidget.h" -#include "common.h" -#include "kbdtabledatamgr.h" -#include "kbdtablemodel.h" -#include "UserDbOpt.h" -#include -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" - -#define CLK_FUNC "CLK_FUNC" -#define CLK_USER "CLK_USER" -#define CLK_ROLE "CLK_ROLE" -#define CLK_USER_GROUP "CLK_USER_GROUP" -#define CLK_PIC_DEF "CLK_PIC_DEF" -#define CLK_REPORT_DEF "CLK_REPORT_DEF" -#define CLK_SAFE "CLK_SAFE" -#define CLK_DEPT_DEF "CLK_DEPT_DEF" -#define CLK_ACS_DEV "CLK_ACS_DEV" - -UserManageWidget::UserManageWidget(QWidget *parent, bool editMode) : - QWidget(parent), - m_bIsEditMode(editMode), - m_ptrPerm(Q_NULLPTR), - m_stack(Q_NULLPTR), - m_dbOpt(Q_NULLPTR), - ui(new Ui::UserManageWidget) -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("usermng.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } - - ui->setupUi(this); - if(!m_bIsEditMode) - { - m_dbOpt = new UserDbOpt; - init(); - } - initLayout(); -} - -UserManageWidget::~UserManageWidget() -{ - if(m_dbOpt) - { - delete m_dbOpt; - m_dbOpt =NULL; - } - delete ui; -} - -void UserManageWidget::initLayout() -{ - QHBoxLayout *hLayout = new QHBoxLayout; - QList listCfgType; - listCfgType.append(KbdUserWidget::USERGRP_CFG); - listCfgType.append(KbdUserWidget::USER_CFG); - listCfgType.append(KbdUserWidget::ROLE_CFG); - m_stack = new KbdUserWidget(listCfgType,this); - connect(m_stack, &KbdUserWidget::userRemove, this, &UserManageWidget::userRemove); - hLayout->addWidget(m_stack); - ui->mainWidget->setLayout(hLayout); -} - -void UserManageWidget::initialize(int model) -{ - if(E_Window_UserGroup == model) - { - m_stack->setCurrentIndex(0); - } - else if(E_Window_User == model) - { - m_stack->setCurrentIndex(1); - } - else if(E_Window_Role == model) - { - m_stack->setCurrentIndex(2); - } -} - -void UserManageWidget::login() -{ - if(!m_bIsEditMode) - { - checkPerm(); - } -} - -void UserManageWidget::logout() -{ - if(!m_bIsEditMode) - { - checkPerm(); - } -} - -void UserManageWidget::init() -{ - QString err = m_dbOpt->initilize(); - if(err.isEmpty()) - { - initPerm(); - }else - { - LOGERROR("在线连接数据库失败,原因:%s",err.toStdString().c_str()); - } - - -} - -void UserManageWidget::initPerm() -{ - m_ptrPerm = kbd_service::getPermMngInstance("base"); - if(!m_ptrPerm || m_ptrPerm->PermDllInit() != 0) - { - QMessageBox::warning(this, tr("提示"), tr("用户管理插件用户权限认证库调用失败!"), QMessageBox::Ok); - LOGERROR("用户管理插件用户权限认证库调用失败!"); - return ; - } - checkPerm(); -} - -void UserManageWidget::checkPerm() -{ - int nUserId = 1; - int nUserGrpId =1; - int nLevel; - int nLoginSec; - std::string strInstanceName; - if(0 != m_ptrPerm->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_SCAN); - QMessageBox::warning(this, tr("提示"), tr("当前用户ID获取失败!"), QMessageBox::Ok); - LOGERROR("用户ID获取失败"); - return; - } - - std::string tmp = "FUNC_NOM_USER_MNG"; - if((m_ptrPerm->PermCheck(PERM_NOM_FUNC_DEF,&tmp,nUserGrpId))== PERM_PERMIT) - { - KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_EDIT); - LOGINFO("当前登录用户ID[%d],用户组ID[%d],具有编辑权限!",nUserId,nUserGrpId); - } - else - { - KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_SCAN); - LOGINFO("当前登录用户ID[%d],用户组ID[%d],具有浏览权限!",nUserId,nUserGrpId); - } -} +#include "UserManageWidget.h" +#include "ui_UserManageWidget.h" +#include +#include +#include +#include +#include "../../../tools/model_user/kbduserwidget.h" +#include "common.h" +#include "kbdtabledatamgr.h" +#include "kbdtablemodel.h" +#include "UserDbOpt.h" +#include +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" + +#define CLK_FUNC "CLK_FUNC" +#define CLK_USER "CLK_USER" +#define CLK_ROLE "CLK_ROLE" +#define CLK_USER_GROUP "CLK_USER_GROUP" +#define CLK_PIC_DEF "CLK_PIC_DEF" +#define CLK_REPORT_DEF "CLK_REPORT_DEF" +#define CLK_SAFE "CLK_SAFE" +#define CLK_DEPT_DEF "CLK_DEPT_DEF" +#define CLK_ACS_DEV "CLK_ACS_DEV" + +UserManageWidget::UserManageWidget(QWidget *parent, bool editMode) : + QWidget(parent), + m_bIsEditMode(editMode), + m_ptrPerm(Q_NULLPTR), + m_stack(Q_NULLPTR), + m_dbOpt(Q_NULLPTR), + ui(new Ui::UserManageWidget) +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("usermng.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + ui->setupUi(this); + if(!m_bIsEditMode) + { + m_dbOpt = new UserDbOpt; + init(); + } + initLayout(); +} + +UserManageWidget::~UserManageWidget() +{ + if(m_dbOpt) + { + delete m_dbOpt; + m_dbOpt =NULL; + } + delete ui; +} + +void UserManageWidget::initLayout() +{ + QHBoxLayout *hLayout = new QHBoxLayout; + QList listCfgType; + listCfgType.append(KbdUserWidget::USERGRP_CFG); + listCfgType.append(KbdUserWidget::USER_CFG); + listCfgType.append(KbdUserWidget::ROLE_CFG); + m_stack = new KbdUserWidget(listCfgType,this); + connect(m_stack, &KbdUserWidget::userRemove, this, &UserManageWidget::userRemove); + hLayout->addWidget(m_stack); + ui->mainWidget->setLayout(hLayout); +} + +void UserManageWidget::initialize(int model) +{ + if(E_Window_UserGroup == model) + { + m_stack->setCurrentIndex(0); + } + else if(E_Window_User == model) + { + m_stack->setCurrentIndex(1); + } + else if(E_Window_Role == model) + { + m_stack->setCurrentIndex(2); + } +} + +void UserManageWidget::login() +{ + if(!m_bIsEditMode) + { + checkPerm(); + } +} + +void UserManageWidget::logout() +{ + if(!m_bIsEditMode) + { + checkPerm(); + } +} + +void UserManageWidget::init() +{ + QString err = m_dbOpt->initilize(); + if(err.isEmpty()) + { + initPerm(); + }else + { + LOGERROR("在线连接数据库失败,原因:%s",err.toStdString().c_str()); + } + + +} + +void UserManageWidget::initPerm() +{ + m_ptrPerm = kbd_service::getPermMngInstance("base"); + if(!m_ptrPerm || m_ptrPerm->PermDllInit() != 0) + { + QMessageBox::warning(this, tr("提示"), tr("用户管理插件用户权限认证库调用失败!"), QMessageBox::Ok); + LOGERROR("用户管理插件用户权限认证库调用失败!"); + return ; + } + checkPerm(); +} + +void UserManageWidget::checkPerm() +{ + int nUserId = 1; + int nUserGrpId =1; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(0 != m_ptrPerm->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_SCAN); + QMessageBox::warning(this, tr("提示"), tr("当前用户ID获取失败!"), QMessageBox::Ok); + LOGERROR("用户ID获取失败"); + return; + } + + std::string tmp = "FUNC_NOM_USER_MNG"; + if((m_ptrPerm->PermCheck(PERM_NOM_FUNC_DEF,&tmp,nUserGrpId))== PERM_PERMIT) + { + KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_EDIT); + LOGINFO("当前登录用户ID[%d],用户组ID[%d],具有编辑权限!",nUserId,nUserGrpId); + } + else + { + KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_SCAN); + LOGINFO("当前登录用户ID[%d],用户组ID[%d],具有浏览权限!",nUserId,nUserGrpId); + } +} diff --git a/product/src/gui/plugin/UserManageWidget/UserManageWidget.h b/product/src/gui/plugin/UserManageWidget/UserManageWidget.h index 55a1d912..f7a99011 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManageWidget.h +++ b/product/src/gui/plugin/UserManageWidget/UserManageWidget.h @@ -1,62 +1,62 @@ -#ifndef USERMANAGEWIDGET_H -#define USERMANAGEWIDGET_H - -#include -#include "PermMngApi.h" - -class UserDbOpt; -class KbdUserWidget; -class KbdTreeView; - -namespace Ui { -class UserManageWidget; -} - -enum E_Window_Mode -{ - E_Window_UserGroup = 0, - E_Window_User, - E_Window_Role -}; - -class UserManageWidget : public QWidget -{ - Q_OBJECT - -public: - explicit UserManageWidget(QWidget *parent = 0, bool editMode = false); - ~UserManageWidget(); - - void initLayout(); - -signals: - void userRemove(); - -public slots: - /** - * @brief initialize - * @param model 0:用户组配置 1:用户配置 2:角色配置 - */ - void initialize(int model); - - void login(); - - void logout(); - -private: - void init(); - void initPerm(); - - void checkPerm(); - -private: - Ui::UserManageWidget *ui; - - kbd_service::CPermMngApiPtr m_ptrPerm; - KbdUserWidget *m_stack; - UserDbOpt *m_dbOpt; - bool m_bIsEditMode; - int m_index; -}; - -#endif // USERMANAGEWIDGET_H +#ifndef USERMANAGEWIDGET_H +#define USERMANAGEWIDGET_H + +#include +#include "PermMngApi.h" + +class UserDbOpt; +class KbdUserWidget; +class KbdTreeView; + +namespace Ui { +class UserManageWidget; +} + +enum E_Window_Mode +{ + E_Window_UserGroup = 0, + E_Window_User, + E_Window_Role +}; + +class UserManageWidget : public QWidget +{ + Q_OBJECT + +public: + explicit UserManageWidget(QWidget *parent = 0, bool editMode = false); + ~UserManageWidget(); + + void initLayout(); + +signals: + void userRemove(); + +public slots: + /** + * @brief initialize + * @param model 0:用户组配置 1:用户配置 2:角色配置 + */ + void initialize(int model); + + void login(); + + void logout(); + +private: + void init(); + void initPerm(); + + void checkPerm(); + +private: + Ui::UserManageWidget *ui; + + kbd_service::CPermMngApiPtr m_ptrPerm; + KbdUserWidget *m_stack; + UserDbOpt *m_dbOpt; + bool m_bIsEditMode; + int m_index; +}; + +#endif // USERMANAGEWIDGET_H diff --git a/product/src/gui/plugin/UserManageWidget/UserManageWidget.pro b/product/src/gui/plugin/UserManageWidget/UserManageWidget.pro index d3926971..594bc0f5 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManageWidget.pro +++ b/product/src/gui/plugin/UserManageWidget/UserManageWidget.pro @@ -1,67 +1,67 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2020-08-27T16:30:15 -# -#------------------------------------------------- - -QT += core gui widgets charts sql - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = UserManageWidget -TEMPLATE = lib - -CONFIG += plugin - - -exists($$PWD/../../../common.pri) { - include($$PWD/../../../common.pri) -}else { - error("FATAL error: connot find common.pri") -} - -INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_common \ - $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx \ - $$PWD/../../../../../platform/src/include/tools/model_table \ - $$PWD/../../../../../platform/src/include/tools/model_user \ - $$PWD/../../../../../platform/src/include/tools/model_table/CustomWidget \ - $$PWD/../../../../../platform/src/include/service/perm_mng_api \ - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - UserManageWidget.cpp \ - UserDbOpt.cpp \ - UserManagePluginWidget.cpp - -HEADERS += \ - UserManageWidget.h \ - UserDbOpt.h \ - UserManagePluginWidget.h - -FORMS += \ - UserManageWidget.ui - -LIBS += -lnet_msg_bus_api -LIBS += -llog4cplus -LIBS += -lpub_utility_api - -LIBS += -lperm_mng_api -LIBS += -lpub_logger_api -LIBS += -llog4cplus -LIBS += -lmodel_table -LIBS += -lmodel_common -LIBS += -lmodel_excel - -LIBS += -lmodel_user - +#------------------------------------------------- +# +# Project created by QtCreator 2020-08-27T16:30:15 +# +#------------------------------------------------- + +QT += core gui widgets charts sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = UserManageWidget +TEMPLATE = lib + +CONFIG += plugin + + +exists($$PWD/../../../common.pri) { + include($$PWD/../../../common.pri) +}else { + error("FATAL error: connot find common.pri") +} + +INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_common \ + $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx \ + $$PWD/../../../../../platform/src/include/tools/model_table \ + $$PWD/../../../../../platform/src/include/tools/model_user \ + $$PWD/../../../../../platform/src/include/tools/model_table/CustomWidget \ + $$PWD/../../../../../platform/src/include/service/perm_mng_api \ + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + UserManageWidget.cpp \ + UserDbOpt.cpp \ + UserManagePluginWidget.cpp + +HEADERS += \ + UserManageWidget.h \ + UserDbOpt.h \ + UserManagePluginWidget.h + +FORMS += \ + UserManageWidget.ui + +LIBS += -lnet_msg_bus_api +LIBS += -llog4cplus +LIBS += -lpub_utility_api + +LIBS += -lperm_mng_api +LIBS += -lpub_logger_api +LIBS += -llog4cplus +LIBS += -lmodel_table +LIBS += -lmodel_common +LIBS += -lmodel_excel + +LIBS += -lmodel_user + diff --git a/product/src/gui/plugin/UserManageWidget/UserManageWidget.ui b/product/src/gui/plugin/UserManageWidget/UserManageWidget.ui index 78965f1b..065d5234 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManageWidget.ui +++ b/product/src/gui/plugin/UserManageWidget/UserManageWidget.ui @@ -1,61 +1,61 @@ - - - UserManageWidget - - - - 0 - 0 - 879 - 568 - - - - UserManageWidget - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - - - - - - - - - + + + UserManageWidget + + + + 0 + 0 + 879 + 568 + + + + UserManageWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/UserManageWidget/main.cpp b/product/src/gui/plugin/UserManageWidget/main.cpp index 0ff10475..7e9f738f 100644 --- a/product/src/gui/plugin/UserManageWidget/main.cpp +++ b/product/src/gui/plugin/UserManageWidget/main.cpp @@ -1,36 +1,36 @@ -#include "UserManageWidget.h" -#include -#include "net_msg_bus_api/MsgBusApi.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "pub_logger_api/logger.h" - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - - std::string name="admin"; - std::string password ="kbdct"; - kbd_public::StartLogSystem("HMI", "hmi"); - kbd_net::initMsgBus("HMI", "HMI"); - int group =1; - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - - if(perm->SysLogin(name, password, group, 12*60*60, "hmi") != 0) - { - return -1; - } - { - UserManageWidget w(NULL,false); - w.initialize(2); - - w.show(); - a.exec(); - } - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - return 0; -} +#include "UserManageWidget.h" +#include +#include "net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + std::string name="admin"; + std::string password ="kbdct"; + kbd_public::StartLogSystem("HMI", "hmi"); + kbd_net::initMsgBus("HMI", "HMI"); + int group =1; + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin(name, password, group, 12*60*60, "hmi") != 0) + { + return -1; + } + { + UserManageWidget w(NULL,false); + w.initialize(2); + + w.show(); + a.exec(); + } + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + return 0; +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/CFileTableWidget.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/CFileTableWidget.cpp index c9d7ae4a..575f94c4 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/CFileTableWidget.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/CFileTableWidget.cpp @@ -1,312 +1,312 @@ -#include "CFileTableWidget.h" -#include "public/pub_utility_api/FileUtil.h" -#include "perm_mng_api/PermMngApi.h" -#include -#include -#include -#include -#include -#include - -CFileTableWidget::CFileTableWidget(QWidget *parent) - : QTableWidget(parent) -{ - initialize(); -} - -CFileTableWidget::~CFileTableWidget() -{ - -} - -QString CFileTableWidget::getRootPath() -{ - std::string strCurModuleDir = kbd_public::CFileUtil::getCurModuleDir(); - strCurModuleDir += "../../data/rec"; - return QString::fromStdString(strCurModuleDir); -} - -bool CFileTableWidget::checkDeletePerm() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - return false; - } - std::string tmpStr = "FUNC_NOM_OM"; - if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) - { - return false; - } - return true; -} - -void CFileTableWidget::slotOpenFile() -{ - QModelIndexList indexList = selectionModel()->selectedRows(); - if(indexList.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("请选择一个录波文件")); - return; - } - - int row = indexList[0].row(); - QString file = getRootPath() + - QDir::separator() + item(row, COLUMN_PATH)->text() + - QDir::separator() + item(row, COLUMN_NAME)->text(); - - emit sigOpenFile(file); -} - -void CFileTableWidget::slotDeleteFile() -{ - QModelIndexList indexList = selectionModel()->selectedRows(); - if(indexList.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("请选择一个录波文件")); - return; - } - - if(!checkDeletePerm()) - { - QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); - return; - } - - if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("确认删除?"))) - { - return; - } - - int row = indexList[0].row(); - QString filePath = getRootPath() + QDir::separator() + item(row, COLUMN_PATH)->text() + QDir::separator() + item(row, COLUMN_NAME)->text(); - QFileInfo fileInfo(filePath); - QString baseName = fileInfo.baseName(); - QStringList typeList; - typeList.push_back(".dat"); - typeList.push_back(".cnf"); - typeList.push_back(".cfg"); - - QString error; - for(int n=0; n < typeList.length(); n++) - { - QDir dir(getRootPath() + QDir::separator() + item(row, COLUMN_PATH)->text()); - if(!dir.exists(baseName + typeList[n])) - { - continue; - } - if(!dir.remove(getRootPath() + QDir::separator() + item(row, COLUMN_PATH)->text() + QDir::separator() + baseName + typeList[n])) - { - error.push_back(tr("删除 %1 失败").arg(item(row, COLUMN_PATH)->text() + QDir::separator() + baseName + typeList[n])); - continue; - } - } - - if(!error.isEmpty()) - { - QMessageBox::information(this, tr("提示"), error); - } - - clearContents(); - setRowCount(0); - makeTable(getRootPath()); -} - -void CFileTableWidget::slotExport() -{ - QModelIndexList indexList = selectionModel()->selectedRows(); - if(indexList.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("请选择一个录波文件")); - return; - } - - QString loadPath = QFileDialog::getExistingDirectory(this, tr("请选择导出路径")); - if(loadPath.isEmpty()) - { - return; - } - - int row = indexList[0].row(); - QString filePath = getRootPath() + QDir::separator() + item(row, COLUMN_PATH)->text() + QDir::separator() + item(row, COLUMN_NAME)->text(); - QFileInfo fileInfo(filePath); - QString baseName = fileInfo.baseName(); - QStringList typeList; - typeList.push_back(".dat"); - typeList.push_back(".cnf"); - typeList.push_back(".cfg"); - - QString error; - foreach (QString type, typeList) { - QString folder = item(row, COLUMN_PATH)->text(); - QString file = baseName + type; - QString filePath = folder + QDir::separator() + file; - QString srcPath = getRootPath() + QDir::separator() + filePath; - QString dstPath = loadPath + QDir::separator() + filePath; - QDir srcDir(getRootPath() + QDir::separator() + folder); - if(!srcDir.exists(file)) - { - continue; - } - QDir dstDir(loadPath); - if(!dstDir.exists(folder)) - { - dstDir.mkpath(folder); - } - if(dstDir.exists(filePath)) - { - if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("文件已存在: %1,是否替换?").arg(filePath))) - { - continue; - } - if(false == QFile::remove(dstPath)) - { - error += QString("%1\n").arg(filePath); - continue; - } - } - bool isSuccess = QFile::copy(srcPath, dstPath); - if(!isSuccess) - { - error += QString("%1\n").arg(filePath); - } - } - if(!error.isEmpty()) - { - QMessageBox::information(this, tr("提示"), tr("%1 导出失败").arg(error)); - } - else - { - QMessageBox::information(this, tr("提示"), tr("导出成功")); - } -} - -void CFileTableWidget::slotFilter(qint64 beginMsec, qint64 endMsec) -{ - int row = rowCount(); - for(int nIndex(0); nIndex < row; nIndex++) - { - qint64 time = item(nIndex, COLUMN_DATE)->data(Qt::UserRole).toLongLong(); - - if(time < beginMsec || time > endMsec) - { - setRowHidden(nIndex, true); - } - else - { - setRowHidden(nIndex, false); - } - } -} - -int CFileTableWidget::tableColumnWidth() -{ - return m_nTableColWidth; -} - -void CFileTableWidget::setTableColumnWidth(const int &nWidth) -{ - m_nTableColWidth = nWidth; - - horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); -} - -int CFileTableWidget::tableRowHeight() -{ - return m_nTableRowHeight; -} - -void CFileTableWidget::setTableRowHeight(const int &nHeight) -{ - m_nTableRowHeight = nHeight; - - verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); -} - -void CFileTableWidget::mouseDoubleClickEvent(QMouseEvent *event) -{ - QModelIndex modelIndex = indexAt(event->pos()); - if(modelIndex.isValid()) - { - int row = modelIndex.row(); - QString file = getRootPath() + - QDir::separator() + item(row, COLUMN_PATH)->text() + - QDir::separator() + item(row, COLUMN_NAME)->text(); - - emit sigOpenFile(file); - } - return QTableWidget::mouseDoubleClickEvent(event); -} - -void CFileTableWidget::mousePressEvent(QMouseEvent *event) -{ - QTableWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); - if(Q_NULLPTR == pItem) - { - clearSelection(); - } - else - { - } - return QTableWidget::mousePressEvent(event); -} - -void CFileTableWidget::initialize() -{ - setColumnCount(4); - setColumnWidth(COLUMN_PATH, 360); - setColumnWidth(COLUMN_DATE, 190); - setHorizontalHeaderLabels(QStringList() << tr("序号") << tr("设备名") << tr("创建时间") << tr("文件名")); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::SingleSelection); - setEditTriggers(QAbstractItemView::NoEditTriggers); - horizontalHeader()->setStretchLastSection(true); - setAlternatingRowColors(true); - verticalHeader()->setHidden(true); - - makeTable(getRootPath()); -} - -void CFileTableWidget::makeTable(const QString &path) -{ - QDir dir(path); - QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Time); - foreach (QFileInfo fileInfo, fileInfoList) { - QString suffix = fileInfo.suffix(); - if(suffix != "dat") - { - continue; - } - int row = rowCount(); - insertRow(row); - - QTableWidgetItem * seqItem = new QTableWidgetItem(); - seqItem->setText(QString::number(row + 1)); - seqItem->setTextAlignment(Qt::AlignCenter); - setItem(row, COLUMN_SEQ, seqItem); - - QTableWidgetItem * pathItem = new QTableWidgetItem; - QDir tmpRootDir(getRootPath()); - QDir tmpFileDir(fileInfo.filePath()); - tmpFileDir.cdUp(); - pathItem->setText(tmpRootDir.relativeFilePath(tmpFileDir.path())); - pathItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); - setItem(row, COLUMN_PATH, pathItem); - - QTableWidgetItem * dateItem = new QTableWidgetItem; - dateItem->setText(fileInfo.created().toString("yyyy-MM-dd hh:mm:ss")); - dateItem->setData(Qt::UserRole, fileInfo.created().toMSecsSinceEpoch()); - dateItem->setTextAlignment(Qt::AlignCenter); - setItem(row, COLUMN_DATE, dateItem); - - QTableWidgetItem * nameItem = new QTableWidgetItem; - nameItem->setText(fileInfo.fileName()); - nameItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); - setItem(row, COLUMN_NAME, nameItem); - } - - QStringList entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time); - foreach (QString entry, entryList) { - makeTable(path + QDir::separator() + entry); - } -} +#include "CFileTableWidget.h" +#include "public/pub_utility_api/FileUtil.h" +#include "perm_mng_api/PermMngApi.h" +#include +#include +#include +#include +#include +#include + +CFileTableWidget::CFileTableWidget(QWidget *parent) + : QTableWidget(parent) +{ + initialize(); +} + +CFileTableWidget::~CFileTableWidget() +{ + +} + +QString CFileTableWidget::getRootPath() +{ + std::string strCurModuleDir = kbd_public::CFileUtil::getCurModuleDir(); + strCurModuleDir += "../../data/rec"; + return QString::fromStdString(strCurModuleDir); +} + +bool CFileTableWidget::checkDeletePerm() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + return false; + } + std::string tmpStr = "FUNC_NOM_OM"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + return false; + } + return true; +} + +void CFileTableWidget::slotOpenFile() +{ + QModelIndexList indexList = selectionModel()->selectedRows(); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("请选择一个录波文件")); + return; + } + + int row = indexList[0].row(); + QString file = getRootPath() + + QDir::separator() + item(row, COLUMN_PATH)->text() + + QDir::separator() + item(row, COLUMN_NAME)->text(); + + emit sigOpenFile(file); +} + +void CFileTableWidget::slotDeleteFile() +{ + QModelIndexList indexList = selectionModel()->selectedRows(); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("请选择一个录波文件")); + return; + } + + if(!checkDeletePerm()) + { + QMessageBox::information(this, tr("提示"), tr("当前登录用户无运维管理功能权限")); + return; + } + + if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("确认删除?"))) + { + return; + } + + int row = indexList[0].row(); + QString filePath = getRootPath() + QDir::separator() + item(row, COLUMN_PATH)->text() + QDir::separator() + item(row, COLUMN_NAME)->text(); + QFileInfo fileInfo(filePath); + QString baseName = fileInfo.baseName(); + QStringList typeList; + typeList.push_back(".dat"); + typeList.push_back(".cnf"); + typeList.push_back(".cfg"); + + QString error; + for(int n=0; n < typeList.length(); n++) + { + QDir dir(getRootPath() + QDir::separator() + item(row, COLUMN_PATH)->text()); + if(!dir.exists(baseName + typeList[n])) + { + continue; + } + if(!dir.remove(getRootPath() + QDir::separator() + item(row, COLUMN_PATH)->text() + QDir::separator() + baseName + typeList[n])) + { + error.push_back(tr("删除 %1 失败").arg(item(row, COLUMN_PATH)->text() + QDir::separator() + baseName + typeList[n])); + continue; + } + } + + if(!error.isEmpty()) + { + QMessageBox::information(this, tr("提示"), error); + } + + clearContents(); + setRowCount(0); + makeTable(getRootPath()); +} + +void CFileTableWidget::slotExport() +{ + QModelIndexList indexList = selectionModel()->selectedRows(); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("请选择一个录波文件")); + return; + } + + QString loadPath = QFileDialog::getExistingDirectory(this, tr("请选择导出路径")); + if(loadPath.isEmpty()) + { + return; + } + + int row = indexList[0].row(); + QString filePath = getRootPath() + QDir::separator() + item(row, COLUMN_PATH)->text() + QDir::separator() + item(row, COLUMN_NAME)->text(); + QFileInfo fileInfo(filePath); + QString baseName = fileInfo.baseName(); + QStringList typeList; + typeList.push_back(".dat"); + typeList.push_back(".cnf"); + typeList.push_back(".cfg"); + + QString error; + foreach (QString type, typeList) { + QString folder = item(row, COLUMN_PATH)->text(); + QString file = baseName + type; + QString filePath = folder + QDir::separator() + file; + QString srcPath = getRootPath() + QDir::separator() + filePath; + QString dstPath = loadPath + QDir::separator() + filePath; + QDir srcDir(getRootPath() + QDir::separator() + folder); + if(!srcDir.exists(file)) + { + continue; + } + QDir dstDir(loadPath); + if(!dstDir.exists(folder)) + { + dstDir.mkpath(folder); + } + if(dstDir.exists(filePath)) + { + if(QMessageBox::No == QMessageBox::question(this, tr("提示"), tr("文件已存在: %1,是否替换?").arg(filePath))) + { + continue; + } + if(false == QFile::remove(dstPath)) + { + error += QString("%1\n").arg(filePath); + continue; + } + } + bool isSuccess = QFile::copy(srcPath, dstPath); + if(!isSuccess) + { + error += QString("%1\n").arg(filePath); + } + } + if(!error.isEmpty()) + { + QMessageBox::information(this, tr("提示"), tr("%1 导出失败").arg(error)); + } + else + { + QMessageBox::information(this, tr("提示"), tr("导出成功")); + } +} + +void CFileTableWidget::slotFilter(qint64 beginMsec, qint64 endMsec) +{ + int row = rowCount(); + for(int nIndex(0); nIndex < row; nIndex++) + { + qint64 time = item(nIndex, COLUMN_DATE)->data(Qt::UserRole).toLongLong(); + + if(time < beginMsec || time > endMsec) + { + setRowHidden(nIndex, true); + } + else + { + setRowHidden(nIndex, false); + } + } +} + +int CFileTableWidget::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CFileTableWidget::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CFileTableWidget::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CFileTableWidget::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} + +void CFileTableWidget::mouseDoubleClickEvent(QMouseEvent *event) +{ + QModelIndex modelIndex = indexAt(event->pos()); + if(modelIndex.isValid()) + { + int row = modelIndex.row(); + QString file = getRootPath() + + QDir::separator() + item(row, COLUMN_PATH)->text() + + QDir::separator() + item(row, COLUMN_NAME)->text(); + + emit sigOpenFile(file); + } + return QTableWidget::mouseDoubleClickEvent(event); +} + +void CFileTableWidget::mousePressEvent(QMouseEvent *event) +{ + QTableWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if(Q_NULLPTR == pItem) + { + clearSelection(); + } + else + { + } + return QTableWidget::mousePressEvent(event); +} + +void CFileTableWidget::initialize() +{ + setColumnCount(4); + setColumnWidth(COLUMN_PATH, 360); + setColumnWidth(COLUMN_DATE, 190); + setHorizontalHeaderLabels(QStringList() << tr("序号") << tr("设备名") << tr("创建时间") << tr("文件名")); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::SingleSelection); + setEditTriggers(QAbstractItemView::NoEditTriggers); + horizontalHeader()->setStretchLastSection(true); + setAlternatingRowColors(true); + verticalHeader()->setHidden(true); + + makeTable(getRootPath()); +} + +void CFileTableWidget::makeTable(const QString &path) +{ + QDir dir(path); + QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Time); + foreach (QFileInfo fileInfo, fileInfoList) { + QString suffix = fileInfo.suffix(); + if(suffix != "dat") + { + continue; + } + int row = rowCount(); + insertRow(row); + + QTableWidgetItem * seqItem = new QTableWidgetItem(); + seqItem->setText(QString::number(row + 1)); + seqItem->setTextAlignment(Qt::AlignCenter); + setItem(row, COLUMN_SEQ, seqItem); + + QTableWidgetItem * pathItem = new QTableWidgetItem; + QDir tmpRootDir(getRootPath()); + QDir tmpFileDir(fileInfo.filePath()); + tmpFileDir.cdUp(); + pathItem->setText(tmpRootDir.relativeFilePath(tmpFileDir.path())); + pathItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); + setItem(row, COLUMN_PATH, pathItem); + + QTableWidgetItem * dateItem = new QTableWidgetItem; + dateItem->setText(fileInfo.created().toString("yyyy-MM-dd hh:mm:ss")); + dateItem->setData(Qt::UserRole, fileInfo.created().toMSecsSinceEpoch()); + dateItem->setTextAlignment(Qt::AlignCenter); + setItem(row, COLUMN_DATE, dateItem); + + QTableWidgetItem * nameItem = new QTableWidgetItem; + nameItem->setText(fileInfo.fileName()); + nameItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); + setItem(row, COLUMN_NAME, nameItem); + } + + QStringList entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time); + foreach (QString entry, entryList) { + makeTable(path + QDir::separator() + entry); + } +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/CFileTableWidget.h b/product/src/gui/plugin/WaveAnalyzeWidget/CFileTableWidget.h index af6e24d0..e2f24093 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/CFileTableWidget.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/CFileTableWidget.h @@ -1,55 +1,55 @@ -#ifndef CFILETABLEWIDGET_H -#define CFILETABLEWIDGET_H - -#include - -class CFileTableWidget : public QTableWidget -{ - Q_OBJECT - Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) - Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) - -public: - enum EN_COLUMN - { - COLUMN_SEQ = 0, - COLUMN_PATH, - COLUMN_DATE, - COLUMN_NAME - }; - explicit CFileTableWidget(QWidget *parent = Q_NULLPTR); - ~CFileTableWidget(); - - QString getRootPath(); - - bool checkDeletePerm(); - -signals: - void sigOpenFile(const QString &file); - -public slots: - void slotOpenFile(); - void slotDeleteFile(); - void slotExport(); - void slotFilter(qint64 beginMsec, qint64 endMsec); - - int tableColumnWidth(); - void setTableColumnWidth(const int &nWidth); - - int tableRowHeight(); - void setTableRowHeight(const int &nHeight); - -protected: - void mouseDoubleClickEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); - -private: - void initialize(); - void makeTable(const QString &path); - -private: - int m_nTableColWidth; - int m_nTableRowHeight; -}; - -#endif // CFILETABLEWIDGET_H +#ifndef CFILETABLEWIDGET_H +#define CFILETABLEWIDGET_H + +#include + +class CFileTableWidget : public QTableWidget +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + enum EN_COLUMN + { + COLUMN_SEQ = 0, + COLUMN_PATH, + COLUMN_DATE, + COLUMN_NAME + }; + explicit CFileTableWidget(QWidget *parent = Q_NULLPTR); + ~CFileTableWidget(); + + QString getRootPath(); + + bool checkDeletePerm(); + +signals: + void sigOpenFile(const QString &file); + +public slots: + void slotOpenFile(); + void slotDeleteFile(); + void slotExport(); + void slotFilter(qint64 beginMsec, qint64 endMsec); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + +protected: + void mouseDoubleClickEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + +private: + void initialize(); + void makeTable(const QString &path); + +private: + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +#endif // CFILETABLEWIDGET_H diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.cpp index 61ff0182..5a07c7f1 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.cpp @@ -1,26 +1,26 @@ -#include "CWaveAnalyzePlugin.h" -#include "CWaveAnalyzeWidget.h" - -CWaveAnalyzePlugin::CWaveAnalyzePlugin(QObject *parent) -{ - -} - -CWaveAnalyzePlugin::~CWaveAnalyzePlugin() -{ - -} - -bool CWaveAnalyzePlugin::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CWaveAnalyzeWidget *pWidget = new CWaveAnalyzeWidget(parent, editMode); - *widget = (QWidget *)pWidget; - *workTicketWidget = (IPluginWidget *)pWidget; - return true; -} - -void CWaveAnalyzePlugin::release() -{ - -} +#include "CWaveAnalyzePlugin.h" +#include "CWaveAnalyzeWidget.h" + +CWaveAnalyzePlugin::CWaveAnalyzePlugin(QObject *parent) +{ + +} + +CWaveAnalyzePlugin::~CWaveAnalyzePlugin() +{ + +} + +bool CWaveAnalyzePlugin::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CWaveAnalyzeWidget *pWidget = new CWaveAnalyzeWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *workTicketWidget = (IPluginWidget *)pWidget; + return true; +} + +void CWaveAnalyzePlugin::release() +{ + +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.h b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.h index 7b75c45c..cfa0f380 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.h @@ -1,21 +1,21 @@ -#ifndef CWAVEANALYZEPLUGIN_H -#define CWAVEANALYZEPLUGIN_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CWaveAnalyzePlugin : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CWaveAnalyzePlugin(QObject *parent = 0); - ~CWaveAnalyzePlugin(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec); - void release(); -}; - -#endif // CWAVEANALYZEPLUGIN_H +#ifndef CWAVEANALYZEPLUGIN_H +#define CWAVEANALYZEPLUGIN_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CWaveAnalyzePlugin : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CWaveAnalyzePlugin(QObject *parent = 0); + ~CWaveAnalyzePlugin(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec); + void release(); +}; + +#endif // CWAVEANALYZEPLUGIN_H diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.cpp index 49c2e989..a964dda7 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.cpp @@ -1,168 +1,168 @@ -#include "CWaveAnalyzeWidget.h" -#include "ui_CWaveAnalyzeWidget.h" -#include "pub_utility_api/FileStyle.h" -#include "./WaveAnalyze/CComDataClass.h" -#include "./WaveAnalyze/CWaveGraph.h" -#include "CFileTableWidget.h" -#include -#include -#include - -CWaveAnalyzeWidget::CWaveAnalyzeWidget(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CWaveAnalyzeWidget), - m_pWaveFile(Q_NULLPTR) -{ - ui->setupUi(this); - - if(!editMode) - { - initStyle(); - m_pWaveFile = new CComtradeFile; - setPrintVisible(false); - - ui->beginTime->setDate(QDate::currentDate()); - ui->beginTime->setTime(QTime(0, 0, 0, 0)); - ui->beginTime->setCalendarPopup(true); - ui->beginTime->setDisplayFormat("yyyy-MM-dd"); - ui->endTime->setDate(QDate::currentDate()); - ui->endTime->setTime(QTime(23, 59, 59, 999)); - ui->endTime->setCalendarPopup(true); - ui->endTime->setDisplayFormat("yyyy-MM-dd"); - - connect(ui->open, &QPushButton::clicked, ui->fileTable, &CFileTableWidget::slotOpenFile); - connect(ui->delete_2, &QPushButton::clicked, ui->fileTable, &CFileTableWidget::slotDeleteFile); - connect(ui->export_2, &QPushButton::clicked, ui->fileTable, &CFileTableWidget::slotExport); - connect(ui->search, &QPushButton::clicked, this, &CWaveAnalyzeWidget::timeFilter); - connect(ui->fileTable, &CFileTableWidget::sigOpenFile, this, &CWaveAnalyzeWidget::openWaveFile); - connect(ui->print, &QPushButton::clicked, this, &CWaveAnalyzeWidget::printWave); - connect(ui->tableShow, &QPushButton::clicked, this, &CWaveAnalyzeWidget::setTableVisible); - - ui->splitter->setSizes(QList() << 0 << 1); - } -} - -CWaveAnalyzeWidget::~CWaveAnalyzeWidget() -{ - if(m_pWaveFile) - { - delete m_pWaveFile; - } - m_pWaveFile = Q_NULLPTR; - - delete ui; -} - -bool CWaveAnalyzeWidget::openWaveFile(const QString &strFile) -{ - QString strFilePath = QFileInfo(strFile).absolutePath()+"/"; - QString strFileName = QFileInfo(strFile).fileName(); - CWaveEnv::GetInst()->m_sWaveFilePath = strFilePath; - CWaveEnv::GetInst()->ChangeColor(3); - CWaveEnv::GetInst()->Save(); - - if(Q_NULLPTR == m_pWaveFile) - return false; - - if(m_pWaveFile->OpenWaveFile(strFilePath, strFileName)) - { - showComtradeFile(); - } - else - { - QMessageBox objMsgBox(QMessageBox::Warning, tr("Error"), m_pWaveFile->m_strErrReadMsg); - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - } - return true; -} - -void CWaveAnalyzeWidget::printWave() -{ - ui->waveWidget->Print(); -} - -void CWaveAnalyzeWidget::setTableColumnWidth(int column, int width) -{ - ui->fileTable->setColumnWidth(column, width); -} - -void CWaveAnalyzeWidget::setTableRowHeight(int height) -{ - ui->fileTable->horizontalHeader()->setDefaultSectionSize(height); -} - -void CWaveAnalyzeWidget::setPrintVisible(bool visible) -{ - ui->print->setVisible(visible); -} - -void CWaveAnalyzeWidget::timeFilter() -{ - QDateTime beginTime = ui->beginTime->dateTime(); - beginTime.setTime(QTime(0, 0, 0, 0)); - QDateTime endTime = ui->endTime->dateTime(); - endTime.setTime(QTime(23, 59, 59, 999)); - - if(beginTime > endTime) - { - QMessageBox::information(this, tr("提示"), tr("开始时间应小于结束时间")); - return; - } - ui->fileTable->slotFilter(beginTime.toMSecsSinceEpoch(), endTime.toMSecsSinceEpoch()); -} - -void CWaveAnalyzeWidget::setTableVisible() -{ - ui->fileTable->setVisible(ui->fileTable->isHidden()); - - ui->search->setEnabled(!ui->fileTable->isHidden()); - ui->open->setEnabled(!ui->fileTable->isHidden()); - ui->delete_2->setEnabled(!ui->fileTable->isHidden()); - ui->export_2->setEnabled(!ui->fileTable->isHidden()); - - if(ui->fileTable->isHidden()) - { - ui->splitter->setSizes(QList() << 10000 << 1); - } - else - { - ui->splitter->setSizes(QList() << 1 << 10000); - } -} - -void CWaveAnalyzeWidget::showComtradeFile() -{ - m_pWaveFile->InitDisplyAttr(); - ui->waveWidget->SetComtradeData(*m_pWaveFile); - ui->waveWidget->showStatus(); - ui->waveWidget->ShowActionTags(); - ui->fileTable->setVisible(true); - setTableVisible(); -} - -void CWaveAnalyzeWidget::initStyle() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("waveAnalyze.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} +#include "CWaveAnalyzeWidget.h" +#include "ui_CWaveAnalyzeWidget.h" +#include "pub_utility_api/FileStyle.h" +#include "./WaveAnalyze/CComDataClass.h" +#include "./WaveAnalyze/CWaveGraph.h" +#include "CFileTableWidget.h" +#include +#include +#include + +CWaveAnalyzeWidget::CWaveAnalyzeWidget(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CWaveAnalyzeWidget), + m_pWaveFile(Q_NULLPTR) +{ + ui->setupUi(this); + + if(!editMode) + { + initStyle(); + m_pWaveFile = new CComtradeFile; + setPrintVisible(false); + + ui->beginTime->setDate(QDate::currentDate()); + ui->beginTime->setTime(QTime(0, 0, 0, 0)); + ui->beginTime->setCalendarPopup(true); + ui->beginTime->setDisplayFormat("yyyy-MM-dd"); + ui->endTime->setDate(QDate::currentDate()); + ui->endTime->setTime(QTime(23, 59, 59, 999)); + ui->endTime->setCalendarPopup(true); + ui->endTime->setDisplayFormat("yyyy-MM-dd"); + + connect(ui->open, &QPushButton::clicked, ui->fileTable, &CFileTableWidget::slotOpenFile); + connect(ui->delete_2, &QPushButton::clicked, ui->fileTable, &CFileTableWidget::slotDeleteFile); + connect(ui->export_2, &QPushButton::clicked, ui->fileTable, &CFileTableWidget::slotExport); + connect(ui->search, &QPushButton::clicked, this, &CWaveAnalyzeWidget::timeFilter); + connect(ui->fileTable, &CFileTableWidget::sigOpenFile, this, &CWaveAnalyzeWidget::openWaveFile); + connect(ui->print, &QPushButton::clicked, this, &CWaveAnalyzeWidget::printWave); + connect(ui->tableShow, &QPushButton::clicked, this, &CWaveAnalyzeWidget::setTableVisible); + + ui->splitter->setSizes(QList() << 0 << 1); + } +} + +CWaveAnalyzeWidget::~CWaveAnalyzeWidget() +{ + if(m_pWaveFile) + { + delete m_pWaveFile; + } + m_pWaveFile = Q_NULLPTR; + + delete ui; +} + +bool CWaveAnalyzeWidget::openWaveFile(const QString &strFile) +{ + QString strFilePath = QFileInfo(strFile).absolutePath()+"/"; + QString strFileName = QFileInfo(strFile).fileName(); + CWaveEnv::GetInst()->m_sWaveFilePath = strFilePath; + CWaveEnv::GetInst()->ChangeColor(3); + CWaveEnv::GetInst()->Save(); + + if(Q_NULLPTR == m_pWaveFile) + return false; + + if(m_pWaveFile->OpenWaveFile(strFilePath, strFileName)) + { + showComtradeFile(); + } + else + { + QMessageBox objMsgBox(QMessageBox::Warning, tr("Error"), m_pWaveFile->m_strErrReadMsg); + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + } + return true; +} + +void CWaveAnalyzeWidget::printWave() +{ + ui->waveWidget->Print(); +} + +void CWaveAnalyzeWidget::setTableColumnWidth(int column, int width) +{ + ui->fileTable->setColumnWidth(column, width); +} + +void CWaveAnalyzeWidget::setTableRowHeight(int height) +{ + ui->fileTable->horizontalHeader()->setDefaultSectionSize(height); +} + +void CWaveAnalyzeWidget::setPrintVisible(bool visible) +{ + ui->print->setVisible(visible); +} + +void CWaveAnalyzeWidget::timeFilter() +{ + QDateTime beginTime = ui->beginTime->dateTime(); + beginTime.setTime(QTime(0, 0, 0, 0)); + QDateTime endTime = ui->endTime->dateTime(); + endTime.setTime(QTime(23, 59, 59, 999)); + + if(beginTime > endTime) + { + QMessageBox::information(this, tr("提示"), tr("开始时间应小于结束时间")); + return; + } + ui->fileTable->slotFilter(beginTime.toMSecsSinceEpoch(), endTime.toMSecsSinceEpoch()); +} + +void CWaveAnalyzeWidget::setTableVisible() +{ + ui->fileTable->setVisible(ui->fileTable->isHidden()); + + ui->search->setEnabled(!ui->fileTable->isHidden()); + ui->open->setEnabled(!ui->fileTable->isHidden()); + ui->delete_2->setEnabled(!ui->fileTable->isHidden()); + ui->export_2->setEnabled(!ui->fileTable->isHidden()); + + if(ui->fileTable->isHidden()) + { + ui->splitter->setSizes(QList() << 10000 << 1); + } + else + { + ui->splitter->setSizes(QList() << 1 << 10000); + } +} + +void CWaveAnalyzeWidget::showComtradeFile() +{ + m_pWaveFile->InitDisplyAttr(); + ui->waveWidget->SetComtradeData(*m_pWaveFile); + ui->waveWidget->showStatus(); + ui->waveWidget->ShowActionTags(); + ui->fileTable->setVisible(true); + setTableVisible(); +} + +void CWaveAnalyzeWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("waveAnalyze.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.h b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.h index 7918be9b..673ffd97 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.h @@ -1,45 +1,45 @@ -#ifndef CWAVEANALYZEWIDGET_H -#define CWAVEANALYZEWIDGET_H - -#include - -namespace Ui { -class CWaveAnalyzeWidget; -} - -class CComtradeFile; -class CWaveAnalyzeWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CWaveAnalyzeWidget(QWidget *parent = 0, bool editMode = true); - ~CWaveAnalyzeWidget(); - -public slots: - bool openWaveFile(const QString &strFile); - - void printWave(); - - void setTableColumnWidth(int column, int width); - - void setTableRowHeight(int height); - - void setPrintVisible(bool visible); - - void timeFilter(); - - void setTableVisible(); - -private: - void showComtradeFile(); - - void initStyle(); - -private: - Ui::CWaveAnalyzeWidget *ui; - - CComtradeFile *m_pWaveFile; -}; - -#endif // CWAVEANALYZEWIDGET_H +#ifndef CWAVEANALYZEWIDGET_H +#define CWAVEANALYZEWIDGET_H + +#include + +namespace Ui { +class CWaveAnalyzeWidget; +} + +class CComtradeFile; +class CWaveAnalyzeWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CWaveAnalyzeWidget(QWidget *parent = 0, bool editMode = true); + ~CWaveAnalyzeWidget(); + +public slots: + bool openWaveFile(const QString &strFile); + + void printWave(); + + void setTableColumnWidth(int column, int width); + + void setTableRowHeight(int height); + + void setPrintVisible(bool visible); + + void timeFilter(); + + void setTableVisible(); + +private: + void showComtradeFile(); + + void initStyle(); + +private: + Ui::CWaveAnalyzeWidget *ui; + + CComtradeFile *m_pWaveFile; +}; + +#endif // CWAVEANALYZEWIDGET_H diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.ui b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.ui index 8eadd638..bd27c0f2 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.ui +++ b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzeWidget.ui @@ -1,145 +1,145 @@ - - - CWaveAnalyzeWidget - - - - 0 - 0 - 1160 - 660 - - - - CWaveAnalyzeWidget - - - - - - - 9 - - - 9 - - - 9 - - - 9 - - - - - Qt::Vertical - - - - - - - - - - - - - 开始日期 - - - - - - - - - - 结束日期 - - - - - - - - - - 查询 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 打开 - - - - - - - 删除 - - - - - - - 导出 - - - - - - - 打印 - - - - - - - 文件列表 - - - - - - - - - - - - - - - CFileTableWidget - QWidget -
CFileTableWidget.h
- 1 -
- - CWaveGraph - QWidget -
./WaveAnalyze/CWaveGraph.h
- 1 -
-
- - -
+ + + CWaveAnalyzeWidget + + + + 0 + 0 + 1160 + 660 + + + + CWaveAnalyzeWidget + + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + Qt::Vertical + + + + + + + + + + + + + 开始日期 + + + + + + + + + + 结束日期 + + + + + + + + + + 查询 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 打开 + + + + + + + 删除 + + + + + + + 导出 + + + + + + + 打印 + + + + + + + 文件列表 + + + + + + + + + + + + + + + CFileTableWidget + QWidget +
CFileTableWidget.h
+ 1 +
+ + CWaveGraph + QWidget +
./WaveAnalyze/CWaveGraph.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnaAxisShow.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnaAxisShow.cpp index f4b096c3..0ec006cb 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnaAxisShow.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnaAxisShow.cpp @@ -1,994 +1,994 @@ -#include "CAnaAxisShow.h" -#include "CTimeAxisShow.h" -#include -#include -#include -#include -#include -#include -#include "CPublic.h" -#include -#include "CComDataClass.h" -//#include "canaaxisset.h" -#include -#include -#include "CWaveShow.h" -#include - -///////////////////////////////////////////////////// -CAnaAxisShow::CAnaAxisShow(QWidget *parent, Qt::WindowFlags f ) - :QWidget(parent,f),m_pRectBand(0) -{ - setWindowFlag( Qt::WindowStaysOnTopHint ); - setMouseTracking(true); -// setAttribute(Qt::WA_PaintOutsidePaintEvent); - - QPalette p = palette(); - p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_NameBackColor); -// p.setColor(foregroundRole(), CWaveEnv::GetInst()->m_NameForeColor); - setPalette(p); - setAutoFillBackground(true); - - m_pWaveFile = 0; - m_nScrollTop = 0; - - m_bMovingWave = false; - m_bOnMoveWave = false; - m_hArrowCursor.setShape(Qt::ArrowCursor); - m_hHandCursor.setShape(Qt::PointingHandCursor); - - m_TinyFont.setPixelSize(10); - m_LittleFont.setPixelSize(10); - m_TextBrush.setColor(QColor(0,0,224)); - - m_nMoveAnalogueNo = -1; - - for(int i = 0;iSetPosition( 0 ); -} - -CAnaAxisShow::~CAnaAxisShow() -{ - -} - -////////////////////////////////////////////////////////////////////////// -void CAnaAxisShow::contextMenuEvent ( QContextMenuEvent *e ) -{ - Q_UNUSED(e) - //选中波形 - //GetParent()->HitTestWave( m_nScrollTop,e->pos().y() ); - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0 || Ch>=MAX_WAVES) - return; - QMenu* contextMenu = new QMenu( this ); - Q_CHECK_PTR( contextMenu ); - contextMenu->addAction( tr("Hide This Channel"), GetParent(), SLOT(OnHideWaveChannel()));//隐藏本通道 - contextMenu->addAction( tr("Restore to Default Group"), GetParent(), SLOT(OnResumeGroup()));//恢复默认分组 -// contextMenu->addAction( tr("Coordinate Setting"), this, SLOT(OnWaveAxisSet()));//设置坐标 - contextMenu->addAction(tr("Wave Amplitude Zoom In"),GetParent(),SLOT(OnAnaAmpSingleIn()));//波形幅值放大 - contextMenu->addAction(tr("Wave Amplitude Zoom Out"),GetParent(),SLOT(OnAnaAmpSingleOut()));//波形幅值缩小 - - - contextMenu->exec( QCursor::pos() ); - delete contextMenu; -} - -void CAnaAxisShow::mousePressEvent( QMouseEvent *e ) -{ - if(!m_pWaveFile) return; - - //{{处理移动 - if( m_SliderBar.contains( e->pos() )&& CWaveEnv::GetInst()->m_bShowCompLine ) - { - m_pLineSlider->DoMousePress(e); - return; - } - //}} - - bool bFind = false; - int nGroupNo = -1; - int nAnaNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - int i; - for(i=0;iGetMaxWaveGroupNum()+1&&iIsWaveGroupEmpty( i ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[i]*/ ) - continue; - - QPoint pt = e->pos(); - if(e->button() == Qt::LeftButton) - { - if(m_UpArea[i].contains(pt))//点击则放大 - { - m_pWaveFile->m_DispAttr.m_dWaveHeight[i] += 5.0; - bFind = true; - nGroupNo = i; - break; - } - else if(m_DownArea[i].contains(pt))//点击则缩小 - { - m_pWaveFile->m_DispAttr.m_dWaveHeight[i] -= 5.0; - if(m_pWaveFile->m_DispAttr.m_dWaveHeight[i] < 5.0) - m_pWaveFile->m_DispAttr.m_dWaveHeight[i] = 5.0; - bFind = true; - nGroupNo = i; - break; - } - } - } - - if(bFind&&nGroupNo != -1) - { - - for(int Ch=0;Chm_nAnagueNum;Ch++) - { - if(m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]!=nGroupNo) continue; - m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[nGroupNo])*45.0 - /double(m_pWaveFile->m_aChMaximumArray[Ch]); - } - update(); - GetParent()->redrawWindow(2,false); - } - else - { - if(!m_bOnMoveWave) - { - setCursor( m_hHandCursor ); - m_bOnMoveWave = true; - m_nLastXPos = e->x(); - m_nLastYPos = e->y(); - - int nWidth = m_pWaveFile->m_DispAttr.m_nLeftMargin; - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - int nTopPos = 0; - int g; - //int nCurAnalogueNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - int nNameHeight = m_pWaveFile->m_DispAttr.m_nNameHeight; - QStringList szName; - for( g=0; gGetMaxWaveGroupNum()+1 && gIsWaveGroupEmpty( g ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[g]*/) - continue; - int nGroupHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[g]*dWaveZoomY1; - if(nGroupHeight<5) nGroupHeight=5; - - szName.clear(); - - int nChCount = 0; - int ChAna = 0; - for(ChAna = 0;ChAnam_nAnagueNum && ChAnam_DispAttr.m_nWaveGroup[ChAna]!=g) continue; - szName.append(m_pWaveFile->AnalogDataList[ChAna].m_sName); - nChCount++; - } - bool bShow = false; - nTopPos += nGroupHeight; - if(nTopPos - m_nScrollTop < 0) continue; - nTopPos -= nGroupHeight; - for(int i = 0;im_nAnagueNum && jm_DispAttr.m_nWaveGroup[j]!=g) continue; - if(m_pWaveFile->m_DispAttr.m_bWaveMarked[j]) continue; - bShow = true; - if(m_pWaveFile->AnalogDataList[j].m_sName == szName[i]) - { - if(grpArea1.contains(/*e->pos()*/QPoint(5,m_nScrollTop+e->y()),true)) - { - m_nMoveAnalogueNo = j; - nAnaNo = j; - break; - } - } - - } - } - // //记录每个波形的区域 - // QRect grpArea = QRect(0,nTopPos,nWidth,nGroupHeight); - // - // int Ch=0; - // for(Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=g) continue; - // - // if( grpArea.contains( QPoint(5,nScrollTop+nY),true)) - // { - // nCurAnalogueNo = Ch; - // break; - // } - // } - if(bShow) - nTopPos += nGroupHeight; - } -// for(i=0;im_nAnagueNum && ipos(); -// if(m_WaveArea[i].contains(pt))//选中了第i个通道 -// { -// m_nMoveAnalogueNo = i; -// } -// } - //m_nMoveAnalogueNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - m_pWaveFile->m_DispAttr.m_nSelAnalogueNo = nAnaNo; - if (!m_pRectBand) - m_pRectBand = new QRubberBand(QRubberBand::Rectangle, this); - m_pRectBand->setGeometry( QRect(m_nLastXPos-5,m_nLastYPos-5,1,1) ); - m_pRectBand->show(); - GetParent()->redrawWindow(1,false); - - } - } -} - -void CAnaAxisShow::mouseReleaseEvent( QMouseEvent *e ) -{ - releaseMouse(); - //{{处理移动 - if( m_SliderBar.contains( e->pos() )&& CWaveEnv::GetInst()->m_bShowCompLine ) - { - m_pLineSlider->DoMouseRelease(e); - return; - } - //}} - QRect ClientRect = geometry(); - //选中波形 - //GetParent()->HitTestWave( m_nScrollTop,e->pos().y() ); - - if( e->button() == Qt::LeftButton ) - { - ///////////////////////////////////////////////////////////////// - if(m_pWaveFile) - { - setCursor( m_hArrowCursor ); - if(m_bOnMoveWave&&m_nMoveAnalogueNo>=0&&m_nMoveAnalogueNom_nAnagueNum&&m_bMovingWave) - { - m_bOnMoveWave = false; - m_bMovingWave = false; - - if (m_pRectBand) - m_pRectBand->hide(); - - int i = 0; - QPoint pt = e->pos(); - for( i=0;i<=m_pWaveFile->GetMaxWaveGroupNum() && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; - - if(m_WaveGroupArea[i].contains(pt))//选中了第i个通道 - { - - m_pWaveFile->m_DispAttr.m_nWaveGroup[m_nMoveAnalogueNo] = i; - m_pWaveFile->m_DispAttr.m_bWaveMarked[i] = false; - m_nMoveAnalogueNo = -1; - - GetParent()->redrawWindow(1,false); - GetParent()->redrawWindow(2,false); - return; - } - } - - //out of Group Area,then add a new Group - int nGroupSet = -1; - if( ClientRect.contains( pt ) ) - { - i = 0; - bool bFindEmptyGroup = false; - for( i=0;i<=m_pWaveFile->GetMaxWaveGroupNum() && iIsWaveGroupEmpty( i ) ) - { - nGroupSet = i; - bFindEmptyGroup = true; - break; - } - } - - if(!bFindEmptyGroup) - nGroupSet = i; - - m_pWaveFile->m_DispAttr.m_nWaveGroup[m_nMoveAnalogueNo] = nGroupSet; - m_WaveArea[m_nMoveAnalogueNo] = QRect(0,0,0,0); - m_nMoveAnalogueNo = -1; - } - - - GetParent()->redrawWindow(1,false); - GetParent()->redrawWindow(2,false); - - } - } - //////////////////////////////////////////////////// - } - QWidget::mouseReleaseEvent( e ); -} - - -void CAnaAxisShow::mouseMoveEvent( QMouseEvent *e ) -{ - //{{处理移动 - if( m_SliderBar.contains( e->pos() ) && CWaveEnv::GetInst()->m_bShowCompLine ) - { - m_pLineSlider->DoMouseMove(e); - setCursor( m_hArrowCursor ); - update(); - return; - } - //}} - - if(m_bOnMoveWave) - { - setCursor( m_hHandCursor ); - if(e->buttons() & Qt::LeftButton) - { - m_bMovingWave = true; - m_nLastXPos = e->x(); - m_nLastYPos = e->y(); - - if (m_pRectBand) - m_pRectBand->setGeometry( QRect(m_nLastXPos-5,m_nLastYPos-5,10,10) ); - - } - else - { - m_bOnMoveWave = false; - if(m_pRectBand) - m_pRectBand->hide(); - setCursor( m_hArrowCursor ); - } - } - - QWidget::mouseMoveEvent( e ); -} - -void CAnaAxisShow::paintEvent( QPaintEvent *e ) -{ - Q_UNUSED(e) - QPainter paint; - paint.begin(this); - //paint.setBrush( palette().brush( QPalette::Background )); - drawBackGnd(&paint); - draw( &paint ); - paint.end(); -} - -void CAnaAxisShow::drawBackGnd(QPainter *paint) -{ - QRect ClientRect = rect(); - ClientRect.setTop(ClientRect.top() - 1); - QBrush oldBrush = paint->brush(); - paint->setBrush(CWaveEnv::GetInst()->m_NameBackColor); - paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); - paint->drawRect(ClientRect); -} - -void CAnaAxisShow::draw( QPainter *paint ) -{ - if(!m_pWaveFile) return; - drawAna(paint); - if( CWaveEnv::GetInst()->m_bShowCompLine ) - { - m_SliderBar = rect(); - m_SliderBar.setLeft( m_SliderBar.right() - SILIDER_HEIGHT ); - m_pLineSlider->SetGeometry( m_SliderBar ); - m_pLineSlider->Draw(paint); - } -} - -void CAnaAxisShow::drawAna( QPainter *paint ,bool bPrint) -{ - QRect ClientRect; - QStringList szNameList; - QList clrList; - QStringList sValueList; - QStringList sValueBaseList; - QStringList sValueStaticList; - - if(!bPrint) ClientRect = geometry(); - else ClientRect = paint->viewport(); - - int nHeight = ClientRect.height(); - int nWidth = ClientRect.width(); - if( CWaveEnv::GetInst()->m_bShowCompLine ) - { - nWidth -= SILIDER_HEIGHT; - } - - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - int nCurAnalogueNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if(nCurAnalogueNo < 0) nCurAnalogueNo = 0; - else if(nCurAnalogueNo > m_pWaveFile->AnalogDataList.size() - 1) nCurAnalogueNo = m_pWaveFile->AnalogDataList.size() - 1; - - int nTopPos = 0 - m_nScrollTop; - -// //获取选中的通道所在的组 -// int nCurGroup = -1; -// if(nCurAnalogueNo>=0&&nCurAnalogueNom_nAnagueNum && nCurAnalogueNom_DispAttr.m_nWaveGroup[nCurAnalogueNo]; - - int nNameWidth = 0; - int nBaseWidth = 0; - int nStaticWidth = 0; - for(int mm = 0;mmAnalogDataList.size();mm++) - nNameWidth = qMax(nNameWidth,paint->fontMetrics().width(m_pWaveFile->AnalogDataList[mm].m_sName+"["+m_pWaveFile->AnalogDataList[mm].m_sUnit+"] ")); - - int i; - for( i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[i]*/ ) - continue; - - if(nTopPos > nHeight + 2 ) - break; - QPen WavePen = QPen(QColor(192,192,192),1,Qt::SolidLine); - bool bFind = false; - double dMax = 0.01; - double dChMax = 0.0; - double dMin = -0.01; - double dChMin = 0.0; - - szNameList.clear(); - clrList.clear(); - sValueList.clear(); - sValueBaseList.clear(); - sValueStaticList.clear(); - - int nGroupHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nGroupHeight<5) nGroupHeight=5; - - if( nTopPos<0-nGroupHeight ) - { - nTopPos += nGroupHeight; - continue; - } - - //记录每个波形的区域 - //m_WaveGroupArea[i] = QRect(0,nTopPos,nWidth,nGroupHeight); - //选中,则反色 -// if(nCurGroup==i) -// { -// -// // QBrush textBrush; -// // textBrush.setColor(QColor(255,255,255)); -// // QPalette p = palette(); -// // p.setBrush(QPalette::HighlightedText,textBrush); -// // p.setColor(QPalette::HighlightedText,QColor(255,0,144)); -// // setPalette(p); -// //palette().setBrush(QPalette::Active,QPalette::HighlightedText,textBrush); -// //qDrawShadePanel(paint,m_WaveGroupArea[i],palette(),true); -// } -// else -// { -// //qDrawShadePanel(paint,m_WaveGroupArea[i],palette()); -// } - - //qDrawShadePanel(paint,m_WaveGroupArea[i],palette(),true); - - QString valueString = ""; - int Ch=0; - for(Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i) continue; - if(m_pWaveFile->m_DispAttr.m_bWaveMarked[Ch]) continue; - m_WaveGroupArea[i] = QRect(0,nTopPos,nWidth,nGroupHeight); - m_WaveArea[Ch] = m_WaveGroupArea[i]; - - - - if(!bFind) { -// WavePen = QPen(m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch], -// m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], -// m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] -// ); -// WavePen = QPen(CWaveEnv::GetInst()->m_NameForeColor, -// m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], -// m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] -// ); - - - bFind = true; - } - -// dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw( m_pWaveFile->m_DispAttr.m_byValueType,m_pWaveFile->m_aChMaximumArray[Ch] ); -// dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw( m_pWaveFile->m_DispAttr.m_byValueType,-m_pWaveFile->m_aChMaximumArray[Ch] ); - - dChMax = m_pWaveFile->AnalogDataList[Ch].GetMaxValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); - dChMin = m_pWaveFile->AnalogDataList[Ch].GetMinValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); - - dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMax); - dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMin); - -// if (fabs(dChMin) > dChMax) -// dChMax = fabs(dChMin); -// else -// dChMin = -dChMax; - dMax = qMax(dMax, dChMax); - dMin = qMin(dMin, dChMin); - QString szName = QString("%1[%2]").arg(m_pWaveFile->AnalogDataList[Ch].m_sName ).arg(m_pWaveFile->AnalogDataList[Ch].m_sUnit); - - if( nCurAnalogueNo == Ch) - { - //szName = "*"+szName; - //paint->setPen(); - } - szName = " " + szName; - szNameList.append( szName ); - - //clrList.append(m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch]); -// if(m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("A") >= 0 || -// m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("a") >= 0) -// { -// clrList.append(m_pWaveFile->m_DispAttr.m_dwColorArray1[0]); -// } -// else if(m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("B") >= 0 || -// m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("b") >= 0) -// { -// clrList.append(m_pWaveFile->m_DispAttr.m_dwColorArray1[1]); -// } -// else if(m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("C") >= 0 || -// m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("c") >= 0) -// { -// clrList.append(m_pWaveFile->m_DispAttr.m_dwColorArray1[2]); -// } -// else -// { -// clrList.append(m_pWaveFile->m_DispAttr.m_DefaultWaveColor); -// } - clrList.append(CWaveEnv::GetInst()->m_WaveForeColor); - //显示数据值 - double dValueT1 = 0.0; - double dValueT2 = 0.0; - char TempString1[100]; - char TempString2[100]; - int nThisTick1 = m_pWaveFile->m_DispAttr.m_fBaseTick; - int nThisTick2 = m_pWaveFile->m_DispAttr.m_fStaticTick; - if(nThisTick1<0) - nThisTick1 = 0; - if(nThisTick1 >= m_pWaveFile->GetTotalPointAmount()) - nThisTick1 = m_pWaveFile->GetTotalPointAmount() - 1; - if(nThisTick2 < 0) - nThisTick2 = 0; - if(nThisTick2 >= m_pWaveFile->GetTotalPointAmount()) - nThisTick2 = m_pWaveFile->GetTotalPointAmount() - 1; - CAnalogData ana1 = m_pWaveFile->AnalogDataList[Ch]; - CAnalogData ana2 = m_pWaveFile->AnalogDataList[Ch]; - if(ana1.GetUpDowmValue(nThisTick1,m_pWaveFile->m_DispAttr.m_byValueType,dValueT1)) - sprintf(TempString1,"%0.2f",dValueT1); - else - sprintf(TempString1,"******"); - if (ana2.GetUpDowmValue(nThisTick2,m_pWaveFile->m_DispAttr.m_byValueType,dValueT2)) - sprintf(TempString2,"%0.2f",dValueT2); - else - sprintf(TempString2,"******"); - valueString = "[" + QString(TempString1) + "][" + QString(TempString2) + "]"; - sValueList.append(QString(valueString)); - sValueBaseList.append("[" + QString(TempString1) + "]"); - sValueStaticList.append("[" + QString(TempString2) + "]"); - } - if(szNameList.size() == 0) - continue; - paint->setPen(QColor(128,128,128)); -// paint->drawLine(0,nTopPos,nWidth,nTopPos); - paint->setPen(QColor(255,255,255)); -// paint->drawLine(0,nTopPos+1,nWidth,nTopPos+1); - - QPen oldPen = paint->pen(); - if(nTopPos <= nHeight - 2 ) - { - //int nStep = nWidth/(2.0*(double)szNameList.count()); - //int nStep = (nWidth-80)/(double)szNameList.count(); -// int nStep; -// if(nWidth >= 150) -// nStep = (nWidth-70)/(double)szNameList.count(); -// else -// nStep = nWidth/(2.0*(double)szNameList.count()); -// {{20090811,修改合并通道后名称显示方式,以纵列方式显示 -// if(nWidth >= 150) -// nStep = (nWidth-90); -// else -// nStep = nWidth/2.0; -// nStep = nWidth - 5; - QString szTxt; - QString szBase; - QString szStatic; - //名称显示高度固定为20 - int nNameHeight = m_pWaveFile->m_DispAttr.m_nNameHeight; - //}} - - for(int mm = 0;mmfontMetrics().width(sValueBaseList[mm])); - for(int mm = 0;mmfontMetrics().width(sValueStaticList[mm])); - - for(int j=0;j<(int)szNameList.count();j++) - { - if(szNameList[j].indexOf(m_pWaveFile->AnalogDataList[nCurAnalogueNo].m_sName) >= 0) - { - //name - QRect rcAll(0,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nNameWidth+nBaseWidth+nStaticWidth,nNameHeight); - paint->setPen(CWaveEnv::GetInst()->m_WaveForeColor); - paint->setBrush(CWaveEnv::GetInst()->m_WaveBackColor); - QRect rcName(0,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nNameWidth,nNameHeight); - szTxt = szNameList[j];szTxt += " "; - paint->drawRect(rcName); - paint->drawText(rcName,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szTxt)); - - //base value - paint->setPen(CWaveEnv::GetInst()->m_BaseLineColor); - paint->setBrush(QBrush(CWaveEnv::GetInst()->m_WaveForeColor)); - QRect rcBase(nNameWidth,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nBaseWidth,nNameHeight); - szBase = sValueBaseList[j].trimmed(); - paint->drawText(rcBase,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szBase)); - //static value - paint->setPen(CWaveEnv::GetInst()->m_StaticLineColor); - paint->setBrush(QBrush(CWaveEnv::GetInst()->m_WaveForeColor)); - QRect rcStatic(nNameWidth+nBaseWidth,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nStaticWidth,nNameHeight); - szStatic = sValueStaticList[j].trimmed(); - paint->drawText(rcStatic,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szStatic)); - } - else - { - //name - paint->setPen(clrList[j]); - //QRect rc(nStep*j,nTopPos+nGroupHeight/2,nStep,nGroupHeight/2); - QRect rcName(0,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nNameWidth,nNameHeight); - szTxt = szNameList[j];szTxt += " "; - //szTxt += sValueList[j].trimmed(); - paint->drawText(rcName,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szTxt)); - //base value - paint->setPen(CWaveEnv::GetInst()->m_BaseLineColor); - QRect rcBase(nNameWidth,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nBaseWidth,nNameHeight); - szBase = sValueBaseList[j].trimmed(); - paint->drawText(rcBase,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szBase)); - //static value - paint->setPen(CWaveEnv::GetInst()->m_StaticLineColor); - QRect rcStatic(nNameWidth+nBaseWidth,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nStaticWidth,nNameHeight); - szStatic = sValueStaticList[j].trimmed(); - paint->drawText(rcStatic,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szStatic)); - } - - } - - //axis - //QRect rcAxis(nWidth/2,nTopPos+1,nWidth/2,nGroupHeight); - QRect rcAxis; -// if(nWidth >= 150) -// rcAxis.setRect(nWidth-90,nTopPos+1,90,nGroupHeight); -// else -// rcAxis.setRect(nWidth/2,nTopPos+1,nWidth/2,nGroupHeight); - rcAxis.setRect(nWidth-5,nTopPos + 1,5,nGroupHeight); - //drawAxis(paint,i,rcAxis,dMin,dMax); - - } - nTopPos += nGroupHeight; - paint->setPen(oldPen); - } -// paint->setPen(QColor(128,128,128)); -// paint->drawLine(0,nTopPos,nWidth,nTopPos); -// paint->setPen(QColor(255,255,255)); -// paint->drawLine(0,nTopPos+1,nWidth,nTopPos+1); - -} - -void CAnaAxisShow::drawAxis( QPainter *paint ,int nChannelNo, QRect& rc,double dMin,double dMax) -{ - Q_UNUSED(dMax) - Q_UNUSED(dMin) - if(nChannelNo<0||nChannelNo>MAX_WAVES) return; - - int nLen = 5; - int nCenter = rc.right()-4 * nLen; - int nBar = rc.right() - 2 * nLen; -// int nLeft = rc.left() + 2; - if(nCenter < rc.left()) - nCenter = rc.left() + nLen; - int nTop = rc.top() + 2; - int nBottom = rc.bottom() - 2; - - - QFont oldFont = paint->font(); - paint->setFont(m_TinyFont); - QBrush oldBrush = paint->brush(); - paint->setBrush(m_TextBrush); -// -// double dStep = (dMax-dMin)/((double)4); -// int nStep = (rc.height()-4)/6; -// paint->drawLine(nCenter,nTop,nCenter,nBottom); -// paint->drawLine(nCenter,nTop,nCenter-nLen,nTop + nLen); -// paint->drawLine(nCenter,nTop,nCenter+nLen,nTop + nLen); -// paint->drawLine(nCenter-nLen,nBottom,nCenter+nLen,nBottom); -// for(int i=1;i<6;i++) -// { -// paint->drawLine(nCenter,nBottom - i* nStep,nCenter+nLen,nBottom - i* nStep); -// -// if(i==1||i==5) -// { -// double nVal; -// if(i==1) nVal = dMin; -// else if(i==4) nVal = dMax; -// else nVal = dMin+ dStep*(i-1); -// -// QRect rcText( nLeft ,nBottom - (double(i) + 0.5)* nStep, nCenter - nLeft - 2 , nStep); -// QString szTxt; -// szTxt.sprintf("%4.2f",nVal); -// paint->drawText(rcText,Qt::AlignRight | Qt::TextSingleLine,szTxt); -// } -// if (i == 3) -// { -// double nVal; -// nVal = 0.0; -// -// QRect rcText( nLeft ,nBottom - (double(i) + 0.5)* nStep, nCenter - nLeft - 2 , nStep); -// QString szTxt; -// szTxt.sprintf("%4.2f",nVal); -// paint->drawText(rcText,Qt::AlignRight | Qt::TextSingleLine,szTxt); -// } -// } - - m_UpArea[nChannelNo] = QRect(nBar,nTop ,nLen*2,2*nLen); -// m_DownArea[nChannelNo] = QRect(nBar,nTop + 2*nLen +2,nLen*2,2*nLen); - m_DownArea[nChannelNo] = QRect(nBar,nBottom - nLen*2 - 2,nLen*2,2*nLen); - - paint->drawText(m_UpArea[nChannelNo],Qt::AlignCenter,"+"); - paint->drawText(m_DownArea[nChannelNo],Qt::AlignCenter,"-"); - qDrawShadePanel(paint,m_UpArea[nChannelNo],palette()); - qDrawShadePanel(paint,m_DownArea[nChannelNo],palette()); - - paint->setFont(oldFont); - paint->setBrush(oldBrush); -} - -void CAnaAxisShow::GetAnaAxisMargin(QRect &rect) -{ - if(!m_pWaveFile) return; -// double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - if(m_pWaveFile->m_nNRates<=0) - {rect = QRect(0,0,0,0);return;} - - int nLeft = 0; - int nRight = GetParent()->m_nLeftMargin; - - int nTop = 0; - int nBottom = 0; - for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; - - int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; - - bool bPrintGroup = false; - for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; - bPrintGroup = true; - } - if(!bPrintGroup) continue; - - nBottom += nWaveHeight; - } - - rect = QRect(nLeft,nTop,nRight - nLeft,nBottom - nTop); -} - -void CAnaAxisShow::Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) -{ - if(!m_pWaveFile) return; - PrintAna(paint,rect,ptOffset,bColor); - paint->drawLine(rect.topRight() + ptOffset,rect.bottomRight() + ptOffset); - -} - -void CAnaAxisShow::PrintAna( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) -{ - QRect ClientRect; - QStringList szNameList; - QList clrList; - - ClientRect = rect; - -// int nHeight = ClientRect.height(); - int nWidth = ClientRect.width(); - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - int nTopPos = 0; -// int nNameWidth = 0; - for( int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; -// QPen WavePen = QPen(QColor(192,192,192),1,Qt::SolidLine); -// bool bFind = false; - double dMax = 0.01; - double dChMax = 0.0; - double dMin = -0.01; - double dChMin = 0.0; - - szNameList.clear(); - clrList.clear(); - - int nGroupHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nGroupHeight<5) nGroupHeight=5; - - bool bPrintGroup = false; - for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; - bPrintGroup = true; - -// dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw( m_pWaveFile->m_DispAttr.m_byValueType,m_pWaveFile->m_aChMaximumArray[Ch] ); -// dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw( m_pWaveFile->m_DispAttr.m_byValueType,-m_pWaveFile->m_aChMaximumArray[Ch] ); - - dChMax = m_pWaveFile->AnalogDataList[Ch].GetMaxValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); - dChMin = m_pWaveFile->AnalogDataList[Ch].GetMinValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); - - dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMax); - dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMin); - - dMax = qMax(dMax, dChMax); - dMin = qMin(dMin, dChMin); - szNameList.append( m_pWaveFile->AnalogDataList[Ch].m_sName ); - //clrList.append(m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch]); - clrList.append(CWaveEnv::GetInst()->m_WaveForeColor); - } - if(!bPrintGroup) continue; - - paint->drawLine(QPoint(0,nTopPos) + ptOffset,QPoint(nWidth,nTopPos) + ptOffset); - - QPen oldPen = paint->pen(); - QFont nameFont; - nameFont.setPixelSize(16); - paint->setFont(nameFont); - - //int nStep = nWidth/(2.0*(double)szNameList.count()); - int nStep = nWidth - 5; -// int nNameHeight = m_pWaveFile->m_DispAttr.m_nNameHeight; - QString szTxt; - for(int j=0;j<(int)szNameList.count();j++) - { - //name - if(bColor) paint->setPen(clrList[j]); - - QRect rc(nStep*j + ptOffset.x(),nTopPos+nGroupHeight/2+ ptOffset.y(),nStep,nGroupHeight/2); - //QRect rcName(0,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nNameWidth,nNameHeight); - szTxt = szNameList[j];szTxt += " "; - paint->drawText(rc,Qt::AlignLeft | Qt::TextSingleLine,(szTxt)); - //paint->drawText(rcName,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szTxt)); - } - //axis - QRect rcAxis(nWidth/2 + ptOffset.x(),nTopPos+1 + ptOffset.y(),nWidth/2,nGroupHeight); - //drawAxis(paint,i,rcAxis,dMin,dMax); - - nTopPos += nGroupHeight; - paint->setPen(oldPen); - } - - paint->drawLine(QPoint(0,nTopPos) + ptOffset,QPoint(nWidth,nTopPos) + ptOffset); - -} -///////////////////////////////////////////////////////////////////////// -void CAnaAxisShow::OnWaveAxisSet() -{ -/* - CAnaAxisSet dlg( m_pWaveFile,this ); - if( QDialog::Accepted == dlg.exec() ) - { - double dChMax = dlg.GetMaxValue(); - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0||Ch>MAX_WAVES ) - return; - int nGroupNo = m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]; - if( nGroupNo<0||nGroupNo>MAX_WAVES) - return; - - double fMax = m_pWaveFile->AnalogDataList[Ch].TransValueToRaw( m_pWaveFile->m_DispAttr.m_byValueType,dChMax ); - m_pWaveFile->m_aChMaximumArray[Ch] = fMax; - m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch])*45.0 - /double(fMax); - - update(); - GetParent()->redrawWindow(2,false); - } -*/ -} - -//////////////////////////////////////////////////////////////////////// -//##ModelId=4039BEDE0118 -bool CAnaAxisShow::SetComtradeData(CComtradeFile& pComtradeData) -{ - m_pWaveFile = &pComtradeData; - - update(); - return true; -} - -CWaveShow* CAnaAxisShow::GetParent() -{ - return (CWaveShow*)parent(); -} - -void CAnaAxisShow::VScroll(int value) -{ - m_nScrollTop = value; - update(); -} - -void CAnaAxisShow::wheelEvent(QWheelEvent *e) -{ - bool bVscroll = false; - bool bHscroll = false; - if(QApplication::keyboardModifiers() == Qt::ControlModifier) - { - bVscroll = true; - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 += AMP_RATE; - else if(e->delta() < 0) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 -=AMP_RATE; - - } - else if(QApplication::keyboardModifiers() == Qt::ShiftModifier) - { - bHscroll = true; - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; - else - m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; - } - else - { - bVscroll = true; - GetParent()->m_pAnalogueView->vert_bar->setValue( GetParent()->m_pAnalogueView->vert_bar->value() - e->delta()/10 ); - } - - if(bVscroll) - { - if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 > 20.0) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 20.0; - if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 < 0.5) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 0.5; - } - - if(bHscroll) - { - if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; - if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; - } - - if(bVscroll) - { - GetParent()->m_pAnalogueView->ResetVScrollSize(); - //GetParent()->m_pDigitalView->ResetVScrollSize(); - } - if(bHscroll) - GetParent()->m_pTimeAxisView->ResetHScrollSize(); - - if(bHscroll | bVscroll) - { - GetParent()->redrawWindow(1,false); - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(3,false); - GetParent()->redrawWindow(4,false); - GetParent()->redrawWindow(5,false); - } -} +#include "CAnaAxisShow.h" +#include "CTimeAxisShow.h" +#include +#include +#include +#include +#include +#include +#include "CPublic.h" +#include +#include "CComDataClass.h" +//#include "canaaxisset.h" +#include +#include +#include "CWaveShow.h" +#include + +///////////////////////////////////////////////////// +CAnaAxisShow::CAnaAxisShow(QWidget *parent, Qt::WindowFlags f ) + :QWidget(parent,f),m_pRectBand(0) +{ + setWindowFlag( Qt::WindowStaysOnTopHint ); + setMouseTracking(true); +// setAttribute(Qt::WA_PaintOutsidePaintEvent); + + QPalette p = palette(); + p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_NameBackColor); +// p.setColor(foregroundRole(), CWaveEnv::GetInst()->m_NameForeColor); + setPalette(p); + setAutoFillBackground(true); + + m_pWaveFile = 0; + m_nScrollTop = 0; + + m_bMovingWave = false; + m_bOnMoveWave = false; + m_hArrowCursor.setShape(Qt::ArrowCursor); + m_hHandCursor.setShape(Qt::PointingHandCursor); + + m_TinyFont.setPixelSize(10); + m_LittleFont.setPixelSize(10); + m_TextBrush.setColor(QColor(0,0,224)); + + m_nMoveAnalogueNo = -1; + + for(int i = 0;iSetPosition( 0 ); +} + +CAnaAxisShow::~CAnaAxisShow() +{ + +} + +////////////////////////////////////////////////////////////////////////// +void CAnaAxisShow::contextMenuEvent ( QContextMenuEvent *e ) +{ + Q_UNUSED(e) + //选中波形 + //GetParent()->HitTestWave( m_nScrollTop,e->pos().y() ); + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0 || Ch>=MAX_WAVES) + return; + QMenu* contextMenu = new QMenu( this ); + Q_CHECK_PTR( contextMenu ); + contextMenu->addAction( tr("Hide This Channel"), GetParent(), SLOT(OnHideWaveChannel()));//隐藏本通道 + contextMenu->addAction( tr("Restore to Default Group"), GetParent(), SLOT(OnResumeGroup()));//恢复默认分组 +// contextMenu->addAction( tr("Coordinate Setting"), this, SLOT(OnWaveAxisSet()));//设置坐标 + contextMenu->addAction(tr("Wave Amplitude Zoom In"),GetParent(),SLOT(OnAnaAmpSingleIn()));//波形幅值放大 + contextMenu->addAction(tr("Wave Amplitude Zoom Out"),GetParent(),SLOT(OnAnaAmpSingleOut()));//波形幅值缩小 + + + contextMenu->exec( QCursor::pos() ); + delete contextMenu; +} + +void CAnaAxisShow::mousePressEvent( QMouseEvent *e ) +{ + if(!m_pWaveFile) return; + + //{{处理移动 + if( m_SliderBar.contains( e->pos() )&& CWaveEnv::GetInst()->m_bShowCompLine ) + { + m_pLineSlider->DoMousePress(e); + return; + } + //}} + + bool bFind = false; + int nGroupNo = -1; + int nAnaNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + int i; + for(i=0;iGetMaxWaveGroupNum()+1&&iIsWaveGroupEmpty( i ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[i]*/ ) + continue; + + QPoint pt = e->pos(); + if(e->button() == Qt::LeftButton) + { + if(m_UpArea[i].contains(pt))//点击则放大 + { + m_pWaveFile->m_DispAttr.m_dWaveHeight[i] += 5.0; + bFind = true; + nGroupNo = i; + break; + } + else if(m_DownArea[i].contains(pt))//点击则缩小 + { + m_pWaveFile->m_DispAttr.m_dWaveHeight[i] -= 5.0; + if(m_pWaveFile->m_DispAttr.m_dWaveHeight[i] < 5.0) + m_pWaveFile->m_DispAttr.m_dWaveHeight[i] = 5.0; + bFind = true; + nGroupNo = i; + break; + } + } + } + + if(bFind&&nGroupNo != -1) + { + + for(int Ch=0;Chm_nAnagueNum;Ch++) + { + if(m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]!=nGroupNo) continue; + m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[nGroupNo])*45.0 + /double(m_pWaveFile->m_aChMaximumArray[Ch]); + } + update(); + GetParent()->redrawWindow(2,false); + } + else + { + if(!m_bOnMoveWave) + { + setCursor( m_hHandCursor ); + m_bOnMoveWave = true; + m_nLastXPos = e->x(); + m_nLastYPos = e->y(); + + int nWidth = m_pWaveFile->m_DispAttr.m_nLeftMargin; + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + int nTopPos = 0; + int g; + //int nCurAnalogueNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + int nNameHeight = m_pWaveFile->m_DispAttr.m_nNameHeight; + QStringList szName; + for( g=0; gGetMaxWaveGroupNum()+1 && gIsWaveGroupEmpty( g ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[g]*/) + continue; + int nGroupHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[g]*dWaveZoomY1; + if(nGroupHeight<5) nGroupHeight=5; + + szName.clear(); + + int nChCount = 0; + int ChAna = 0; + for(ChAna = 0;ChAnam_nAnagueNum && ChAnam_DispAttr.m_nWaveGroup[ChAna]!=g) continue; + szName.append(m_pWaveFile->AnalogDataList[ChAna].m_sName); + nChCount++; + } + bool bShow = false; + nTopPos += nGroupHeight; + if(nTopPos - m_nScrollTop < 0) continue; + nTopPos -= nGroupHeight; + for(int i = 0;im_nAnagueNum && jm_DispAttr.m_nWaveGroup[j]!=g) continue; + if(m_pWaveFile->m_DispAttr.m_bWaveMarked[j]) continue; + bShow = true; + if(m_pWaveFile->AnalogDataList[j].m_sName == szName[i]) + { + if(grpArea1.contains(/*e->pos()*/QPoint(5,m_nScrollTop+e->y()),true)) + { + m_nMoveAnalogueNo = j; + nAnaNo = j; + break; + } + } + + } + } + // //记录每个波形的区域 + // QRect grpArea = QRect(0,nTopPos,nWidth,nGroupHeight); + // + // int Ch=0; + // for(Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=g) continue; + // + // if( grpArea.contains( QPoint(5,nScrollTop+nY),true)) + // { + // nCurAnalogueNo = Ch; + // break; + // } + // } + if(bShow) + nTopPos += nGroupHeight; + } +// for(i=0;im_nAnagueNum && ipos(); +// if(m_WaveArea[i].contains(pt))//选中了第i个通道 +// { +// m_nMoveAnalogueNo = i; +// } +// } + //m_nMoveAnalogueNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + m_pWaveFile->m_DispAttr.m_nSelAnalogueNo = nAnaNo; + if (!m_pRectBand) + m_pRectBand = new QRubberBand(QRubberBand::Rectangle, this); + m_pRectBand->setGeometry( QRect(m_nLastXPos-5,m_nLastYPos-5,1,1) ); + m_pRectBand->show(); + GetParent()->redrawWindow(1,false); + + } + } +} + +void CAnaAxisShow::mouseReleaseEvent( QMouseEvent *e ) +{ + releaseMouse(); + //{{处理移动 + if( m_SliderBar.contains( e->pos() )&& CWaveEnv::GetInst()->m_bShowCompLine ) + { + m_pLineSlider->DoMouseRelease(e); + return; + } + //}} + QRect ClientRect = geometry(); + //选中波形 + //GetParent()->HitTestWave( m_nScrollTop,e->pos().y() ); + + if( e->button() == Qt::LeftButton ) + { + ///////////////////////////////////////////////////////////////// + if(m_pWaveFile) + { + setCursor( m_hArrowCursor ); + if(m_bOnMoveWave&&m_nMoveAnalogueNo>=0&&m_nMoveAnalogueNom_nAnagueNum&&m_bMovingWave) + { + m_bOnMoveWave = false; + m_bMovingWave = false; + + if (m_pRectBand) + m_pRectBand->hide(); + + int i = 0; + QPoint pt = e->pos(); + for( i=0;i<=m_pWaveFile->GetMaxWaveGroupNum() && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; + + if(m_WaveGroupArea[i].contains(pt))//选中了第i个通道 + { + + m_pWaveFile->m_DispAttr.m_nWaveGroup[m_nMoveAnalogueNo] = i; + m_pWaveFile->m_DispAttr.m_bWaveMarked[i] = false; + m_nMoveAnalogueNo = -1; + + GetParent()->redrawWindow(1,false); + GetParent()->redrawWindow(2,false); + return; + } + } + + //out of Group Area,then add a new Group + int nGroupSet = -1; + if( ClientRect.contains( pt ) ) + { + i = 0; + bool bFindEmptyGroup = false; + for( i=0;i<=m_pWaveFile->GetMaxWaveGroupNum() && iIsWaveGroupEmpty( i ) ) + { + nGroupSet = i; + bFindEmptyGroup = true; + break; + } + } + + if(!bFindEmptyGroup) + nGroupSet = i; + + m_pWaveFile->m_DispAttr.m_nWaveGroup[m_nMoveAnalogueNo] = nGroupSet; + m_WaveArea[m_nMoveAnalogueNo] = QRect(0,0,0,0); + m_nMoveAnalogueNo = -1; + } + + + GetParent()->redrawWindow(1,false); + GetParent()->redrawWindow(2,false); + + } + } + //////////////////////////////////////////////////// + } + QWidget::mouseReleaseEvent( e ); +} + + +void CAnaAxisShow::mouseMoveEvent( QMouseEvent *e ) +{ + //{{处理移动 + if( m_SliderBar.contains( e->pos() ) && CWaveEnv::GetInst()->m_bShowCompLine ) + { + m_pLineSlider->DoMouseMove(e); + setCursor( m_hArrowCursor ); + update(); + return; + } + //}} + + if(m_bOnMoveWave) + { + setCursor( m_hHandCursor ); + if(e->buttons() & Qt::LeftButton) + { + m_bMovingWave = true; + m_nLastXPos = e->x(); + m_nLastYPos = e->y(); + + if (m_pRectBand) + m_pRectBand->setGeometry( QRect(m_nLastXPos-5,m_nLastYPos-5,10,10) ); + + } + else + { + m_bOnMoveWave = false; + if(m_pRectBand) + m_pRectBand->hide(); + setCursor( m_hArrowCursor ); + } + } + + QWidget::mouseMoveEvent( e ); +} + +void CAnaAxisShow::paintEvent( QPaintEvent *e ) +{ + Q_UNUSED(e) + QPainter paint; + paint.begin(this); + //paint.setBrush( palette().brush( QPalette::Background )); + drawBackGnd(&paint); + draw( &paint ); + paint.end(); +} + +void CAnaAxisShow::drawBackGnd(QPainter *paint) +{ + QRect ClientRect = rect(); + ClientRect.setTop(ClientRect.top() - 1); + QBrush oldBrush = paint->brush(); + paint->setBrush(CWaveEnv::GetInst()->m_NameBackColor); + paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); + paint->drawRect(ClientRect); +} + +void CAnaAxisShow::draw( QPainter *paint ) +{ + if(!m_pWaveFile) return; + drawAna(paint); + if( CWaveEnv::GetInst()->m_bShowCompLine ) + { + m_SliderBar = rect(); + m_SliderBar.setLeft( m_SliderBar.right() - SILIDER_HEIGHT ); + m_pLineSlider->SetGeometry( m_SliderBar ); + m_pLineSlider->Draw(paint); + } +} + +void CAnaAxisShow::drawAna( QPainter *paint ,bool bPrint) +{ + QRect ClientRect; + QStringList szNameList; + QList clrList; + QStringList sValueList; + QStringList sValueBaseList; + QStringList sValueStaticList; + + if(!bPrint) ClientRect = geometry(); + else ClientRect = paint->viewport(); + + int nHeight = ClientRect.height(); + int nWidth = ClientRect.width(); + if( CWaveEnv::GetInst()->m_bShowCompLine ) + { + nWidth -= SILIDER_HEIGHT; + } + + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + int nCurAnalogueNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if(nCurAnalogueNo < 0) nCurAnalogueNo = 0; + else if(nCurAnalogueNo > m_pWaveFile->AnalogDataList.size() - 1) nCurAnalogueNo = m_pWaveFile->AnalogDataList.size() - 1; + + int nTopPos = 0 - m_nScrollTop; + +// //获取选中的通道所在的组 +// int nCurGroup = -1; +// if(nCurAnalogueNo>=0&&nCurAnalogueNom_nAnagueNum && nCurAnalogueNom_DispAttr.m_nWaveGroup[nCurAnalogueNo]; + + int nNameWidth = 0; + int nBaseWidth = 0; + int nStaticWidth = 0; + for(int mm = 0;mmAnalogDataList.size();mm++) + nNameWidth = qMax(nNameWidth,paint->fontMetrics().width(m_pWaveFile->AnalogDataList[mm].m_sName+"["+m_pWaveFile->AnalogDataList[mm].m_sUnit+"] ")); + + int i; + for( i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[i]*/ ) + continue; + + if(nTopPos > nHeight + 2 ) + break; + QPen WavePen = QPen(QColor(192,192,192),1,Qt::SolidLine); + bool bFind = false; + double dMax = 0.01; + double dChMax = 0.0; + double dMin = -0.01; + double dChMin = 0.0; + + szNameList.clear(); + clrList.clear(); + sValueList.clear(); + sValueBaseList.clear(); + sValueStaticList.clear(); + + int nGroupHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nGroupHeight<5) nGroupHeight=5; + + if( nTopPos<0-nGroupHeight ) + { + nTopPos += nGroupHeight; + continue; + } + + //记录每个波形的区域 + //m_WaveGroupArea[i] = QRect(0,nTopPos,nWidth,nGroupHeight); + //选中,则反色 +// if(nCurGroup==i) +// { +// +// // QBrush textBrush; +// // textBrush.setColor(QColor(255,255,255)); +// // QPalette p = palette(); +// // p.setBrush(QPalette::HighlightedText,textBrush); +// // p.setColor(QPalette::HighlightedText,QColor(255,0,144)); +// // setPalette(p); +// //palette().setBrush(QPalette::Active,QPalette::HighlightedText,textBrush); +// //qDrawShadePanel(paint,m_WaveGroupArea[i],palette(),true); +// } +// else +// { +// //qDrawShadePanel(paint,m_WaveGroupArea[i],palette()); +// } + + //qDrawShadePanel(paint,m_WaveGroupArea[i],palette(),true); + + QString valueString = ""; + int Ch=0; + for(Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i) continue; + if(m_pWaveFile->m_DispAttr.m_bWaveMarked[Ch]) continue; + m_WaveGroupArea[i] = QRect(0,nTopPos,nWidth,nGroupHeight); + m_WaveArea[Ch] = m_WaveGroupArea[i]; + + + + if(!bFind) { +// WavePen = QPen(m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch], +// m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], +// m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] +// ); +// WavePen = QPen(CWaveEnv::GetInst()->m_NameForeColor, +// m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], +// m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] +// ); + + + bFind = true; + } + +// dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw( m_pWaveFile->m_DispAttr.m_byValueType,m_pWaveFile->m_aChMaximumArray[Ch] ); +// dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw( m_pWaveFile->m_DispAttr.m_byValueType,-m_pWaveFile->m_aChMaximumArray[Ch] ); + + dChMax = m_pWaveFile->AnalogDataList[Ch].GetMaxValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); + dChMin = m_pWaveFile->AnalogDataList[Ch].GetMinValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); + + dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMax); + dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMin); + +// if (fabs(dChMin) > dChMax) +// dChMax = fabs(dChMin); +// else +// dChMin = -dChMax; + dMax = qMax(dMax, dChMax); + dMin = qMin(dMin, dChMin); + QString szName = QString("%1[%2]").arg(m_pWaveFile->AnalogDataList[Ch].m_sName ).arg(m_pWaveFile->AnalogDataList[Ch].m_sUnit); + + if( nCurAnalogueNo == Ch) + { + //szName = "*"+szName; + //paint->setPen(); + } + szName = " " + szName; + szNameList.append( szName ); + + //clrList.append(m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch]); +// if(m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("A") >= 0 || +// m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("a") >= 0) +// { +// clrList.append(m_pWaveFile->m_DispAttr.m_dwColorArray1[0]); +// } +// else if(m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("B") >= 0 || +// m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("b") >= 0) +// { +// clrList.append(m_pWaveFile->m_DispAttr.m_dwColorArray1[1]); +// } +// else if(m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("C") >= 0 || +// m_pWaveFile->AnalogDataList[Ch].m_sName.indexOf("c") >= 0) +// { +// clrList.append(m_pWaveFile->m_DispAttr.m_dwColorArray1[2]); +// } +// else +// { +// clrList.append(m_pWaveFile->m_DispAttr.m_DefaultWaveColor); +// } + clrList.append(CWaveEnv::GetInst()->m_WaveForeColor); + //显示数据值 + double dValueT1 = 0.0; + double dValueT2 = 0.0; + char TempString1[100]; + char TempString2[100]; + int nThisTick1 = m_pWaveFile->m_DispAttr.m_fBaseTick; + int nThisTick2 = m_pWaveFile->m_DispAttr.m_fStaticTick; + if(nThisTick1<0) + nThisTick1 = 0; + if(nThisTick1 >= m_pWaveFile->GetTotalPointAmount()) + nThisTick1 = m_pWaveFile->GetTotalPointAmount() - 1; + if(nThisTick2 < 0) + nThisTick2 = 0; + if(nThisTick2 >= m_pWaveFile->GetTotalPointAmount()) + nThisTick2 = m_pWaveFile->GetTotalPointAmount() - 1; + CAnalogData ana1 = m_pWaveFile->AnalogDataList[Ch]; + CAnalogData ana2 = m_pWaveFile->AnalogDataList[Ch]; + if(ana1.GetUpDowmValue(nThisTick1,m_pWaveFile->m_DispAttr.m_byValueType,dValueT1)) + sprintf(TempString1,"%0.2f",dValueT1); + else + sprintf(TempString1,"******"); + if (ana2.GetUpDowmValue(nThisTick2,m_pWaveFile->m_DispAttr.m_byValueType,dValueT2)) + sprintf(TempString2,"%0.2f",dValueT2); + else + sprintf(TempString2,"******"); + valueString = "[" + QString(TempString1) + "][" + QString(TempString2) + "]"; + sValueList.append(QString(valueString)); + sValueBaseList.append("[" + QString(TempString1) + "]"); + sValueStaticList.append("[" + QString(TempString2) + "]"); + } + if(szNameList.size() == 0) + continue; + paint->setPen(QColor(128,128,128)); +// paint->drawLine(0,nTopPos,nWidth,nTopPos); + paint->setPen(QColor(255,255,255)); +// paint->drawLine(0,nTopPos+1,nWidth,nTopPos+1); + + QPen oldPen = paint->pen(); + if(nTopPos <= nHeight - 2 ) + { + //int nStep = nWidth/(2.0*(double)szNameList.count()); + //int nStep = (nWidth-80)/(double)szNameList.count(); +// int nStep; +// if(nWidth >= 150) +// nStep = (nWidth-70)/(double)szNameList.count(); +// else +// nStep = nWidth/(2.0*(double)szNameList.count()); +// {{20090811,修改合并通道后名称显示方式,以纵列方式显示 +// if(nWidth >= 150) +// nStep = (nWidth-90); +// else +// nStep = nWidth/2.0; +// nStep = nWidth - 5; + QString szTxt; + QString szBase; + QString szStatic; + //名称显示高度固定为20 + int nNameHeight = m_pWaveFile->m_DispAttr.m_nNameHeight; + //}} + + for(int mm = 0;mmfontMetrics().width(sValueBaseList[mm])); + for(int mm = 0;mmfontMetrics().width(sValueStaticList[mm])); + + for(int j=0;j<(int)szNameList.count();j++) + { + if(szNameList[j].indexOf(m_pWaveFile->AnalogDataList[nCurAnalogueNo].m_sName) >= 0) + { + //name + QRect rcAll(0,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nNameWidth+nBaseWidth+nStaticWidth,nNameHeight); + paint->setPen(CWaveEnv::GetInst()->m_WaveForeColor); + paint->setBrush(CWaveEnv::GetInst()->m_WaveBackColor); + QRect rcName(0,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nNameWidth,nNameHeight); + szTxt = szNameList[j];szTxt += " "; + paint->drawRect(rcName); + paint->drawText(rcName,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szTxt)); + + //base value + paint->setPen(CWaveEnv::GetInst()->m_BaseLineColor); + paint->setBrush(QBrush(CWaveEnv::GetInst()->m_WaveForeColor)); + QRect rcBase(nNameWidth,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nBaseWidth,nNameHeight); + szBase = sValueBaseList[j].trimmed(); + paint->drawText(rcBase,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szBase)); + //static value + paint->setPen(CWaveEnv::GetInst()->m_StaticLineColor); + paint->setBrush(QBrush(CWaveEnv::GetInst()->m_WaveForeColor)); + QRect rcStatic(nNameWidth+nBaseWidth,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nStaticWidth,nNameHeight); + szStatic = sValueStaticList[j].trimmed(); + paint->drawText(rcStatic,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szStatic)); + } + else + { + //name + paint->setPen(clrList[j]); + //QRect rc(nStep*j,nTopPos+nGroupHeight/2,nStep,nGroupHeight/2); + QRect rcName(0,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nNameWidth,nNameHeight); + szTxt = szNameList[j];szTxt += " "; + //szTxt += sValueList[j].trimmed(); + paint->drawText(rcName,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szTxt)); + //base value + paint->setPen(CWaveEnv::GetInst()->m_BaseLineColor); + QRect rcBase(nNameWidth,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nBaseWidth,nNameHeight); + szBase = sValueBaseList[j].trimmed(); + paint->drawText(rcBase,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szBase)); + //static value + paint->setPen(CWaveEnv::GetInst()->m_StaticLineColor); + QRect rcStatic(nNameWidth+nBaseWidth,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nStaticWidth,nNameHeight); + szStatic = sValueStaticList[j].trimmed(); + paint->drawText(rcStatic,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szStatic)); + } + + } + + //axis + //QRect rcAxis(nWidth/2,nTopPos+1,nWidth/2,nGroupHeight); + QRect rcAxis; +// if(nWidth >= 150) +// rcAxis.setRect(nWidth-90,nTopPos+1,90,nGroupHeight); +// else +// rcAxis.setRect(nWidth/2,nTopPos+1,nWidth/2,nGroupHeight); + rcAxis.setRect(nWidth-5,nTopPos + 1,5,nGroupHeight); + //drawAxis(paint,i,rcAxis,dMin,dMax); + + } + nTopPos += nGroupHeight; + paint->setPen(oldPen); + } +// paint->setPen(QColor(128,128,128)); +// paint->drawLine(0,nTopPos,nWidth,nTopPos); +// paint->setPen(QColor(255,255,255)); +// paint->drawLine(0,nTopPos+1,nWidth,nTopPos+1); + +} + +void CAnaAxisShow::drawAxis( QPainter *paint ,int nChannelNo, QRect& rc,double dMin,double dMax) +{ + Q_UNUSED(dMax) + Q_UNUSED(dMin) + if(nChannelNo<0||nChannelNo>MAX_WAVES) return; + + int nLen = 5; + int nCenter = rc.right()-4 * nLen; + int nBar = rc.right() - 2 * nLen; +// int nLeft = rc.left() + 2; + if(nCenter < rc.left()) + nCenter = rc.left() + nLen; + int nTop = rc.top() + 2; + int nBottom = rc.bottom() - 2; + + + QFont oldFont = paint->font(); + paint->setFont(m_TinyFont); + QBrush oldBrush = paint->brush(); + paint->setBrush(m_TextBrush); +// +// double dStep = (dMax-dMin)/((double)4); +// int nStep = (rc.height()-4)/6; +// paint->drawLine(nCenter,nTop,nCenter,nBottom); +// paint->drawLine(nCenter,nTop,nCenter-nLen,nTop + nLen); +// paint->drawLine(nCenter,nTop,nCenter+nLen,nTop + nLen); +// paint->drawLine(nCenter-nLen,nBottom,nCenter+nLen,nBottom); +// for(int i=1;i<6;i++) +// { +// paint->drawLine(nCenter,nBottom - i* nStep,nCenter+nLen,nBottom - i* nStep); +// +// if(i==1||i==5) +// { +// double nVal; +// if(i==1) nVal = dMin; +// else if(i==4) nVal = dMax; +// else nVal = dMin+ dStep*(i-1); +// +// QRect rcText( nLeft ,nBottom - (double(i) + 0.5)* nStep, nCenter - nLeft - 2 , nStep); +// QString szTxt; +// szTxt.sprintf("%4.2f",nVal); +// paint->drawText(rcText,Qt::AlignRight | Qt::TextSingleLine,szTxt); +// } +// if (i == 3) +// { +// double nVal; +// nVal = 0.0; +// +// QRect rcText( nLeft ,nBottom - (double(i) + 0.5)* nStep, nCenter - nLeft - 2 , nStep); +// QString szTxt; +// szTxt.sprintf("%4.2f",nVal); +// paint->drawText(rcText,Qt::AlignRight | Qt::TextSingleLine,szTxt); +// } +// } + + m_UpArea[nChannelNo] = QRect(nBar,nTop ,nLen*2,2*nLen); +// m_DownArea[nChannelNo] = QRect(nBar,nTop + 2*nLen +2,nLen*2,2*nLen); + m_DownArea[nChannelNo] = QRect(nBar,nBottom - nLen*2 - 2,nLen*2,2*nLen); + + paint->drawText(m_UpArea[nChannelNo],Qt::AlignCenter,"+"); + paint->drawText(m_DownArea[nChannelNo],Qt::AlignCenter,"-"); + qDrawShadePanel(paint,m_UpArea[nChannelNo],palette()); + qDrawShadePanel(paint,m_DownArea[nChannelNo],palette()); + + paint->setFont(oldFont); + paint->setBrush(oldBrush); +} + +void CAnaAxisShow::GetAnaAxisMargin(QRect &rect) +{ + if(!m_pWaveFile) return; +// double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + if(m_pWaveFile->m_nNRates<=0) + {rect = QRect(0,0,0,0);return;} + + int nLeft = 0; + int nRight = GetParent()->m_nLeftMargin; + + int nTop = 0; + int nBottom = 0; + for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; + + int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; + + bool bPrintGroup = false; + for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; + bPrintGroup = true; + } + if(!bPrintGroup) continue; + + nBottom += nWaveHeight; + } + + rect = QRect(nLeft,nTop,nRight - nLeft,nBottom - nTop); +} + +void CAnaAxisShow::Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) +{ + if(!m_pWaveFile) return; + PrintAna(paint,rect,ptOffset,bColor); + paint->drawLine(rect.topRight() + ptOffset,rect.bottomRight() + ptOffset); + +} + +void CAnaAxisShow::PrintAna( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) +{ + QRect ClientRect; + QStringList szNameList; + QList clrList; + + ClientRect = rect; + +// int nHeight = ClientRect.height(); + int nWidth = ClientRect.width(); + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + int nTopPos = 0; +// int nNameWidth = 0; + for( int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; +// QPen WavePen = QPen(QColor(192,192,192),1,Qt::SolidLine); +// bool bFind = false; + double dMax = 0.01; + double dChMax = 0.0; + double dMin = -0.01; + double dChMin = 0.0; + + szNameList.clear(); + clrList.clear(); + + int nGroupHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nGroupHeight<5) nGroupHeight=5; + + bool bPrintGroup = false; + for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; + bPrintGroup = true; + +// dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw( m_pWaveFile->m_DispAttr.m_byValueType,m_pWaveFile->m_aChMaximumArray[Ch] ); +// dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw( m_pWaveFile->m_DispAttr.m_byValueType,-m_pWaveFile->m_aChMaximumArray[Ch] ); + + dChMax = m_pWaveFile->AnalogDataList[Ch].GetMaxValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); + dChMin = m_pWaveFile->AnalogDataList[Ch].GetMinValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); + + dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMax); + dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMin); + + dMax = qMax(dMax, dChMax); + dMin = qMin(dMin, dChMin); + szNameList.append( m_pWaveFile->AnalogDataList[Ch].m_sName ); + //clrList.append(m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch]); + clrList.append(CWaveEnv::GetInst()->m_WaveForeColor); + } + if(!bPrintGroup) continue; + + paint->drawLine(QPoint(0,nTopPos) + ptOffset,QPoint(nWidth,nTopPos) + ptOffset); + + QPen oldPen = paint->pen(); + QFont nameFont; + nameFont.setPixelSize(16); + paint->setFont(nameFont); + + //int nStep = nWidth/(2.0*(double)szNameList.count()); + int nStep = nWidth - 5; +// int nNameHeight = m_pWaveFile->m_DispAttr.m_nNameHeight; + QString szTxt; + for(int j=0;j<(int)szNameList.count();j++) + { + //name + if(bColor) paint->setPen(clrList[j]); + + QRect rc(nStep*j + ptOffset.x(),nTopPos+nGroupHeight/2+ ptOffset.y(),nStep,nGroupHeight/2); + //QRect rcName(0,nTopPos+nGroupHeight/2-szNameList.count()*nNameHeight/2+j*nNameHeight,nNameWidth,nNameHeight); + szTxt = szNameList[j];szTxt += " "; + paint->drawText(rc,Qt::AlignLeft | Qt::TextSingleLine,(szTxt)); + //paint->drawText(rcName,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szTxt)); + } + //axis + QRect rcAxis(nWidth/2 + ptOffset.x(),nTopPos+1 + ptOffset.y(),nWidth/2,nGroupHeight); + //drawAxis(paint,i,rcAxis,dMin,dMax); + + nTopPos += nGroupHeight; + paint->setPen(oldPen); + } + + paint->drawLine(QPoint(0,nTopPos) + ptOffset,QPoint(nWidth,nTopPos) + ptOffset); + +} +///////////////////////////////////////////////////////////////////////// +void CAnaAxisShow::OnWaveAxisSet() +{ +/* + CAnaAxisSet dlg( m_pWaveFile,this ); + if( QDialog::Accepted == dlg.exec() ) + { + double dChMax = dlg.GetMaxValue(); + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0||Ch>MAX_WAVES ) + return; + int nGroupNo = m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]; + if( nGroupNo<0||nGroupNo>MAX_WAVES) + return; + + double fMax = m_pWaveFile->AnalogDataList[Ch].TransValueToRaw( m_pWaveFile->m_DispAttr.m_byValueType,dChMax ); + m_pWaveFile->m_aChMaximumArray[Ch] = fMax; + m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch])*45.0 + /double(fMax); + + update(); + GetParent()->redrawWindow(2,false); + } +*/ +} + +//////////////////////////////////////////////////////////////////////// +//##ModelId=4039BEDE0118 +bool CAnaAxisShow::SetComtradeData(CComtradeFile& pComtradeData) +{ + m_pWaveFile = &pComtradeData; + + update(); + return true; +} + +CWaveShow* CAnaAxisShow::GetParent() +{ + return (CWaveShow*)parent(); +} + +void CAnaAxisShow::VScroll(int value) +{ + m_nScrollTop = value; + update(); +} + +void CAnaAxisShow::wheelEvent(QWheelEvent *e) +{ + bool bVscroll = false; + bool bHscroll = false; + if(QApplication::keyboardModifiers() == Qt::ControlModifier) + { + bVscroll = true; + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 += AMP_RATE; + else if(e->delta() < 0) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 -=AMP_RATE; + + } + else if(QApplication::keyboardModifiers() == Qt::ShiftModifier) + { + bHscroll = true; + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; + else + m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; + } + else + { + bVscroll = true; + GetParent()->m_pAnalogueView->vert_bar->setValue( GetParent()->m_pAnalogueView->vert_bar->value() - e->delta()/10 ); + } + + if(bVscroll) + { + if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 > 20.0) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 20.0; + if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 < 0.5) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 0.5; + } + + if(bHscroll) + { + if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; + if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; + } + + if(bVscroll) + { + GetParent()->m_pAnalogueView->ResetVScrollSize(); + //GetParent()->m_pDigitalView->ResetVScrollSize(); + } + if(bHscroll) + GetParent()->m_pTimeAxisView->ResetHScrollSize(); + + if(bHscroll | bVscroll) + { + GetParent()->redrawWindow(1,false); + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(3,false); + GetParent()->redrawWindow(4,false); + GetParent()->redrawWindow(5,false); + } +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnaAxisShow.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnaAxisShow.h index 8b5fb2e4..706fa67d 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnaAxisShow.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnaAxisShow.h @@ -1,80 +1,80 @@ -#ifndef CANASHOWSHOW_H_HEADER_INCLUDED_BFC41131 -#define CANASHOWSHOW_H_HEADER_INCLUDED_BFC41131 - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CComDataClass.h" - -#include "CWaveGraph.h" - -class CVerticalSlider; - -//##ModelId=403405ED00B3 -class CAnaAxisShow : public QWidget -{ - Q_OBJECT - -public: - CAnaAxisShow(QWidget * parent = 0, Qt::WindowFlags f = 0); - ~CAnaAxisShow(); -public: - CComtradeFile* m_pWaveFile; - - QRubberBand* m_pRectBand; - - bool m_bMovingWave; - bool m_bOnMoveWave; - int m_nLastYPos; - int m_nLastXPos; - QCursor m_hArrowCursor; - QCursor m_hHandCursor; - - int m_nScrollTop; - QFont m_LittleFont; - QFont m_TinyFont; - QBrush m_TextBrush; - - double m_dGroupMaxValue[MAX_WAVES]; - QRect m_UpArea[MAX_WAVES]; - QRect m_DownArea[MAX_WAVES]; - - QRect m_WaveGroupArea[MAX_WAVES]; //波形组区域s - QRect m_WaveArea[MAX_WAVES]; //波形区域s - int m_nMoveAnalogueNo; //被拖拽的模拟通道号 - - CVerticalSlider* m_pLineSlider; - QRect m_SliderBar; - int m_nSliderWidth; - -public: - //##ModelId=4039BEDE0118 - bool SetComtradeData(CComtradeFile& pComtradeData); - CWaveShow* GetParent(); - void draw( QPainter *); - void drawAna( QPainter *paint ,bool bPrint = false); - void drawAxis( QPainter *paint ,int nChannelNo, QRect& rc,double dMin = 0.0,double dMax = 100.0); - void Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); - void PrintAna( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); - void GetAnaAxisMargin(QRect &rect); - void VScroll(int value); - void drawBackGnd(QPainter *); - -public slots: - void OnWaveAxisSet(); -protected: - void mousePressEvent( QMouseEvent * ); - void mouseReleaseEvent( QMouseEvent * ); - void mouseMoveEvent( QMouseEvent * ); - void paintEvent( QPaintEvent *); - void contextMenuEvent ( QContextMenuEvent * ); - void wheelEvent(QWheelEvent *); -}; - -#endif /* CANASHOWSHOW_H_HEADER_INCLUDED_BFC41131 */ +#ifndef CANASHOWSHOW_H_HEADER_INCLUDED_BFC41131 +#define CANASHOWSHOW_H_HEADER_INCLUDED_BFC41131 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CComDataClass.h" + +#include "CWaveGraph.h" + +class CVerticalSlider; + +//##ModelId=403405ED00B3 +class CAnaAxisShow : public QWidget +{ + Q_OBJECT + +public: + CAnaAxisShow(QWidget * parent = 0, Qt::WindowFlags f = 0); + ~CAnaAxisShow(); +public: + CComtradeFile* m_pWaveFile; + + QRubberBand* m_pRectBand; + + bool m_bMovingWave; + bool m_bOnMoveWave; + int m_nLastYPos; + int m_nLastXPos; + QCursor m_hArrowCursor; + QCursor m_hHandCursor; + + int m_nScrollTop; + QFont m_LittleFont; + QFont m_TinyFont; + QBrush m_TextBrush; + + double m_dGroupMaxValue[MAX_WAVES]; + QRect m_UpArea[MAX_WAVES]; + QRect m_DownArea[MAX_WAVES]; + + QRect m_WaveGroupArea[MAX_WAVES]; //波形组区域s + QRect m_WaveArea[MAX_WAVES]; //波形区域s + int m_nMoveAnalogueNo; //被拖拽的模拟通道号 + + CVerticalSlider* m_pLineSlider; + QRect m_SliderBar; + int m_nSliderWidth; + +public: + //##ModelId=4039BEDE0118 + bool SetComtradeData(CComtradeFile& pComtradeData); + CWaveShow* GetParent(); + void draw( QPainter *); + void drawAna( QPainter *paint ,bool bPrint = false); + void drawAxis( QPainter *paint ,int nChannelNo, QRect& rc,double dMin = 0.0,double dMax = 100.0); + void Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); + void PrintAna( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); + void GetAnaAxisMargin(QRect &rect); + void VScroll(int value); + void drawBackGnd(QPainter *); + +public slots: + void OnWaveAxisSet(); +protected: + void mousePressEvent( QMouseEvent * ); + void mouseReleaseEvent( QMouseEvent * ); + void mouseMoveEvent( QMouseEvent * ); + void paintEvent( QPaintEvent *); + void contextMenuEvent ( QContextMenuEvent * ); + void wheelEvent(QWheelEvent *); +}; + +#endif /* CANASHOWSHOW_H_HEADER_INCLUDED_BFC41131 */ diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogDataSet.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogDataSet.cpp index bd39e502..8e492e82 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogDataSet.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogDataSet.cpp @@ -1,953 +1,953 @@ -#include "CComDataClass.h" -#include "math.h" -//////////////////////////////////// -CAnalogData::CAnalogData(): m_nAverageTicks(0) -{ - m_nIndex = 0; //模拟通道索引 - m_sName = ""; //名称 - m_sPhase = ""; //相位特征 - m_sCCBM = ""; //被监视的回路元件 - m_sUnit = "V"; //单位 - m_sUnitRaw = "V"; //原始单位 - m_dMultiplier = 1.0; //a - m_dOffsetAdder = 0.0; //b ax+b - m_dSkew = 1.0; //通道时滞 - m_nMin = -32767; //最小 - m_nMax = 32767; //最大 - m_dPrimary = 1.0; //一次变比系数 - m_dSecondary = 1.0; //二次变比系数 - m_byPS = 0; //0-无效,1-一次值,2-二次值 特征符 - m_dlSampleData.resize(0); //采样值 - m_bSampleValid.resize(0); - m_nWaveType = CHN_NO_ATTR; - m_bVectorValid = false; - m_bFreqValid = false; - m_byPhaseType = PHASE_NULL; -} - -CAnalogData::~CAnalogData() -{ -} - - -CAnalogData &CAnalogData::operator=( const CAnalogData &p ) -{ - m_nIndex = p.m_nIndex; //模拟通道索引 - m_sName = p.m_sName; //名称 - m_sPhase = p.m_sPhase; //相位特征 - m_sCCBM = p.m_sCCBM; //被监视的回路元件 - m_sUnit = p.m_sUnit; //单位 - m_sUnitRaw = p.m_sUnitRaw; - m_dMultiplier = p.m_dMultiplier; //a - m_dOffsetAdder= p.m_dOffsetAdder; //b ax+b - m_dSkew=p.m_dSkew; //通道时滞 - m_nMin=p.m_nMin; //最小 - m_nMax = p.m_nMax; //最大 - m_dPrimary = p.m_dPrimary; //一次变比系数 - m_dSecondary = p.m_dSecondary; //二次变比系数 - m_byPS = p.m_byPS; //特征符 - - m_dlSampleData = p.m_dlSampleData; - m_bSampleValid = p.m_bSampleValid; - return *this; -} - -void CAnalogData::Detach() -{ - m_dlSampleData.detach(); - m_bSampleValid.detach(); -} - -void CAnalogData::clone(CAnalogData& clone) -{ - clone.m_nIndex = m_nIndex; //模拟通道索引 - clone.m_sName = m_sName; //名称 - clone.m_sPhase = m_sPhase; //相位特征 - clone.m_sCCBM = m_sCCBM; //被监视的回路元件 - clone.m_sUnit = m_sUnit; //单位 - clone.m_sUnitRaw = m_sUnitRaw; - clone.m_dMultiplier = m_dMultiplier; //a - clone.m_dOffsetAdder= m_dOffsetAdder; //b ax+b - clone.m_dSkew=m_dSkew; //通道时滞 - clone.m_nMin=m_nMin; //最小 - clone.m_nMax = m_nMax; //最大 - clone.m_dPrimary = m_dPrimary; //一次变比系数 - clone.m_dSecondary = m_dSecondary; //二次变比系数 - clone.m_byPS = m_byPS; //特征符 - - clone.m_dlSampleData = m_dlSampleData; - clone.m_bSampleValid = m_bSampleValid; -} - -void CAnalogData::CopyDataTo(CAnalogData& clone,int nBegin,int nEnd) -{ - if(nBegin>=0&&nBegin= 0 || - m_sChannelName.indexOf("ua") >= 0 || - m_sChannelName.indexOf(QObject::tr("phase A"), Qt::CaseInsensitive) >= 0 )//a相 - { - m_byPhaseType = PHASE_A; - } - else if(m_sChannelName.indexOf("ib") >= 0 || - m_sChannelName.indexOf("ub") >= 0 || - m_sChannelName.indexOf(QObject::tr("phase B"), Qt::CaseInsensitive) >= 0 )//a相 - { - m_byPhaseType = PHASE_B; - } - else if(m_sChannelName.indexOf("ic") >= 0 || - m_sChannelName.indexOf("uc") >= 0 || - m_sChannelName.indexOf(QObject::tr("phase C"), Qt::CaseInsensitive) >= 0 )//c相 - { - m_byPhaseType = PHASE_C; - } - else if(m_sChannelName.indexOf("a") >= 0) - { - m_byPhaseType = PHASE_A; - } - else if(m_sChannelName.indexOf("b") >= 0) - { - m_byPhaseType = PHASE_B; - } - else if(m_sChannelName.indexOf("c") >= 0) - { - m_byPhaseType = PHASE_C; - } - else - { - m_byPhaseType = PHASE_NULL; - } - -} - -unsigned short CAnalogData::UnitType() -{ - QString sUnit = m_sUnit.toLower(); - sUnit = sUnit.trimmed(); -// int n = sUnit.compare("kv"); -// n = QString::compare(sUnit,"kv"); - -// if(m_nWaveType == CHN_ANG0_ATTR) -// return UNIT_ANG; - /*else*/ if( 0 == sUnit.compare("kv") ) - return UNIT_KV; - else if( 0 == sUnit.compare("v") ) - return UNIT_V; - else if( 0 == sUnit.compare("ka") ) - return UNIT_KA; - else if( 0 == sUnit.compare("a") ) - return UNIT_A; - else if( 0 == sUnit.compare("kw") ) - return UNIT_KW; - else if( 0 == sUnit.compare("w") ) - return UNIT_W; - else if( 0 == sUnit.compare("va") ) - return UNIT_VA; - else if( 0 == sUnit.compare("var") ) - return UNIT_Var; - else if( 0 == sUnit.compare("kva") ) - return UNIT_KVA; - else if( 0 == sUnit.compare("kvar") ) - return UNIT_KVar; - return UNIT_NO; -} - -bool CAnalogData::GetTickValue(int nTick,byte byValueType,double& dValue) -{ - if(nTick<0||nTick>=m_dlSampleData.size()) - { - dValue = 0.0; - return true; - } -// int nSize = m_bSampleValid.size(); - - int fRaw = m_dlSampleData[nTick]; //采样值 - -// double fRealValue = m_aRealArray[nTick];//实部的值 -// double fImgValue = m_aImagArray[nTick]; //虚部的值 -// double fEfectValue = m_aAmpArray[nTick];//有效值 -// double fAngValue = m_aAngArray[nTick]; //角度 -// double fAmpValue = fEfectValue*M_SQRT2; //幅值 - -// bool bValid = m_bSampleValid[nTick]; - if( fRaw>m_nMax ) fRaw = m_nMax; - else if( fRaw < m_nMin ) fRaw = m_nMin; - - if(byValueType==VAL_RAW) - { - dValue = (double)fRaw; - return true; - } - - double fValue = fRaw*m_dMultiplier+m_dOffsetAdder; - switch(m_byPS) { - case 1://fvalue为一次值 - { - if(byValueType==VAL_SECONDARY) - { - if(m_dPrimary>1E-5) - { - dValue = fValue*m_dSecondary/m_dPrimary; - //{{一次值转为二次值时量纲应随之变化 - unsigned short ut = UnitType(); - //if( fabs(dValue)1E-5) - { - dValue = fValue*m_dPrimary/m_dSecondary; - return true; - } - } - } - break; - default: - break; - } - - dValue = fValue; - return true; -} - -double CAnalogData::GetUpDowmValue(int nTick,byte byValueType,double& dValue) -{ - if(nTick<0||nTick>=m_dlSampleData.size()) - { - dValue = 0.0; - return true; - } -// int nSize = m_bSampleValid.size(); - - int fRaw = m_dlSampleData[nTick]; //采样值 - - double fRealValue = m_aRealArray[nTick];//实部的值 - double fImgValue = m_aImagArray[nTick]; //虚部的值 - double fEfectValue = m_aAmpArray[nTick];//有效值 - double fAngValue = m_aAngArray[nTick]; //角度 - double fAmpValue = fEfectValue*M_SQRT2; //幅值 - -// bool bValid = m_bSampleValid[nTick]; - if( fRaw>m_nMax ) fRaw = m_nMax; - else if( fRaw < m_nMin ) fRaw = m_nMin; - - if(byValueType==VAL_RAW) - { - // 幅值 - if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) - { - dValue = fAmpValue; - }//有效值 - else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) - { - dValue = fEfectValue; - }//实部的值 - else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) - { - dValue = fRealValue*M_SQRT2; - }//虚部的值 - else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) - { - dValue = fImgValue*M_SQRT2; - }//角度 - else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) - { - dValue = fAngValue; - }//采样值 - else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) - { - dValue = (double)fRaw; - } - else - dValue = (double)fRaw; - return true; - } - - double fValue = fRaw*m_dMultiplier+m_dOffsetAdder; - switch(m_byPS) { - case 1://fvalue为一次值 - { - if(byValueType==VAL_SECONDARY) - { - if(m_dPrimary>1E-5) - { - //幅值 - if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) - { - dValue = (fAmpValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; - }//有效值 - else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) - { - dValue = (fEfectValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; - }//实部的值 - else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) - { - dValue = ((fRealValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary)*M_SQRT2; - }//虚部的值 - else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) - { - dValue = ((fImgValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary)*M_SQRT2; - }//角度 - else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) - { - dValue = fAngValue; - }//瞬时值 - else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) - { - dValue = fValue*m_dSecondary/m_dPrimary; - } - else - dValue = fValue*m_dSecondary/m_dPrimary; - //{{一次值转为二次值时量纲应随之变化 - unsigned short ut = UnitType(); - if( fabs(dValue)1E-5) - { - //幅值 - if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) - { - dValue = (fAmpValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; - }//有效值 - else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) - { - dValue = (fEfectValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; - }//实部的值 - else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) - { - dValue = ((fRealValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary)*M_SQRT2; - }//虚部的值 - else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) - { - dValue = ((fImgValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary)*M_SQRT2; - }//角度 - else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) - { - dValue = fAngValue; - }//瞬时值 - else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) - { - dValue = fValue*m_dPrimary/m_dSecondary; - } - else - dValue = fValue*m_dPrimary/m_dSecondary; - return true; - } - } - } - break; - default: - break; - } - //幅值 - if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) - { - dValue = fAmpValue*m_dMultiplier+m_dOffsetAdder; - }//有效值 - else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) - { - dValue = fEfectValue*m_dMultiplier+m_dOffsetAdder; - }//实部的值 - else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) - { - dValue = (fRealValue*m_dMultiplier+m_dOffsetAdder)*M_SQRT2; - }//虚部的值 - else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) - { - dValue = (fImgValue*m_dMultiplier+m_dOffsetAdder)*M_SQRT2; - }//角度 - else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) - { - dValue = fAngValue; - }//瞬时值 - else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) - { - dValue = fValue; - } - else - dValue = fValue; - return true; -} - -double CAnalogData::TransValueToRaw( byte byValueType,double dTypeValue ) -{ - if(byValueType==VAL_RAW) - return dTypeValue; - - double fValue = dTypeValue; - switch(m_byPS) { - case 1://fvalue为一次值 - if(byValueType==VAL_SECONDARY) - { - if(m_dPrimary>1E-5) - { - //{{二次值还原为一次值时量纲应随之变化 - unsigned short ut = UnitType(); - if( fabs(fValue)1E-5) - { - fValue = fValue*m_dSecondary/m_dPrimary; - } - } - break; - default: - break; - } - fValue = (fValue - m_dOffsetAdder)/m_dMultiplier; - return fValue; -} - -double CAnalogData::GetValueFromRaw( byte byValueType,double dRawValue ) -{ - if(byValueType==VAL_RAW) - return dRawValue; -// if (m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) -// return dRawValue; - double fValue = dRawValue*m_dMultiplier+m_dOffsetAdder; - switch(m_byPS) { - case 1://fvalue为一次值 - if(byValueType==VAL_SECONDARY) - { - if(m_dPrimary>1E-5) - { - fValue = fValue*m_dSecondary/m_dPrimary; - //{{一次值转为二次值时量纲应随之变化 - unsigned short ut = UnitType(); - if( fabs(fValue)1E-5) - { - fValue = fValue*m_dPrimary/m_dSecondary; - return fValue; - } - } - break; - default: - break; - } - return fValue; -} - -double CAnalogData::GetMaxValue(byte /*byValueType*/,double /*dValue*/) -{ - double dMax = 0.0; - double dTempValue = 0.0; - for(int i = 0;i= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) -// { -// dMax = dMax*M_SQRT2; -// } -// return dMax; -// if (byValueType == VAL_RAW) -// { - //幅值 - if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) - { - for (int i = 0;i < m_aAmpArray.count();i++) - { - dTempValue = m_aAmpArray[i]*M_SQRT2; - dMax = qMax(dMax,fabs(dTempValue)); - } - dMax = dMax * M_SQRT2; - }//有效值 - else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) - { - for (int i = 0;i < m_aAmpArray.count();i++) - { - dTempValue = m_aAmpArray[i]; - dMax = qMax(dMax,fabs(dTempValue)); - } - }//实部的值 - else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) - { - for (int i = 0;i < m_aRealArray.count();i++) - { - dTempValue = m_aRealArray[i]*M_SQRT2; - dMax = qMax(dMax,fabs(dTempValue)); - } - }//虚部的值 - else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) - { - for (int i = 0;i < m_aImagArray.count();i++) - { - dTempValue = m_aImagArray[i]*M_SQRT2; - dMax = qMax(dMax,fabs(dTempValue)); - } - }//角度 - else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) - { - dMax = 180; - }//采样值 - else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) - { - for (int i = 0;i < m_aAmpArray.count();i++) - { - dTempValue = m_aAmpArray[i]; - dMax = qMax(dMax,fabs(dTempValue)); - } - } - else - { - for (int i = 0;i < m_dlSampleData.count();i++) - { - dTempValue = m_dlSampleData[i]; - dMax = qMax(dMax,fabs(dTempValue)); - } - } -// //{{一次值转为二次值时量纲应随之变化 -// unsigned short ut = UnitType(); -// if( fabs(dMax) 1E-5) -// { -// // 幅值 -// if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) -// { -// for (int i = 0;i < m_aAmpArray.count();i++) -// { -// dTempValue = m_aAmpArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMax = qMax(dMax,dTempValue); -// } -// dMax = dMax * M_SQRT2; -// }//有效值 -// else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) -// { -// for (int i = 0;i < m_aAmpArray.count();i++) -// { -// dTempValue = (m_aAmpArray[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMax = qMax(dMax,dTempValue); -// } -// }//实部的值 -// else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) -// { -// for (int i = 0;i < m_aRealArray.count();i++) -// { -// dTempValue = m_aRealArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMax = qMax(dMax,dTempValue); -// } -// }//虚部的值 -// else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) -// { -// for (int i = 0;i < m_aImagArray.count();i++) -// { -// dTempValue = m_aImagArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMax = qMax(dMax,dTempValue); -// } -// }//角度 -// else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) -// { -// dMax = 180; -// }//采样值 -// else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) -// { -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = (m_dlSampleData[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMax = qMax(dMax,dTempValue); -// } -// } -// else -// { -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = (m_dlSampleData[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMax = qMax(dMax,dTempValue); -// } -// } -// //{{一次值转为二次值时量纲应随之变化 -// unsigned short ut = UnitType(); -// if( fabs(dMax) 1E-5) -// { -// // 幅值 -// if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) -// { -// for (int i = 0;i < m_aAmpArray.count();i++) -// { -// dTempValue = m_aAmpArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMax = qMax(dMax,dTempValue); -// } -// dMax = dMax * M_SQRT2; -// }//有效值 -// else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) -// { -// for (int i = 0;i < m_aAmpArray.count();i++) -// { -// dTempValue = m_aAmpArray[i]; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMax = qMax(dMax,dTempValue); -// } -// }//实部的值 -// else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) -// { -// for (int i = 0;i < m_aRealArray.count();i++) -// { -// dTempValue = m_aRealArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMax = qMax(dMax,dTempValue); -// } -// }//虚部的值 -// else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) -// { -// for (int i = 0;i < m_aImagArray.count();i++) -// { -// dTempValue = m_aImagArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMax = qMax(dMax,dTempValue); -// } -// }//角度 -// else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) -// { -// dMax = 180; -// }//采样值 -// else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) -// { -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = m_dlSampleData[i]; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMax = qMax(dMax,dTempValue); -// } -// } -// else -// { -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = m_dlSampleData[i]; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMax = qMax(dMax,dTempValue); -// } -// } -// return dMax; -// } -// } -// } -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = m_dlSampleData[i]; -// dTempValue = dTempValue*m_dMultiplier+m_dOffsetAdder; -// dMax = qMax(dMax,dTempValue); -// } -// return dMax; -} - -double CAnalogData::GetMinValue(byte /*byValueType*/,double /*dValue*/) -{ - double dMin = 0.0; - double dTempValue = 0.0; -// for(int i = 0;i= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) -// { -// dMin = dMin*M_SQRT2; -// } -// return dMin; -// if (byValueType == VAL_RAW) -// { - // 幅值 - if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) - { - for (int i = 0;i < m_aAmpArray.count();i++) - { - dTempValue = m_aAmpArray[i]*M_SQRT2; - dMin = qMin(dMin,dTempValue); - } - dMin = dMin * M_SQRT2; - }//有效值 - else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) - { - for (int i = 0;i < m_aAmpArray.count();i++) - { - dTempValue = m_aAmpArray[i]; - dMin = qMin(dMin,dTempValue); - } - }//实部的值 - else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) - { - for (int i = 0;i < m_aRealArray.count();i++) - { - dTempValue = m_aRealArray[i]*M_SQRT2; - dMin = qMin(dMin,dTempValue); - } - }//虚部的值 - else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) - { - for (int i = 0;i < m_aImagArray.count();i++) - { - dTempValue = m_aImagArray[i]*M_SQRT2; - dMin = qMin(dMin,dTempValue); - } - }//角度 - else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) - { - dMin = -180; - }//采样值 - else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) - { - for (int i = 0;i < m_aAmpArray.count();i++) - { - dTempValue = m_aAmpArray[i]; - dMin = qMin(dMin,dTempValue); - } - } - else - { - for (int i = 0;i < m_dlSampleData.count();i++) - { - dTempValue = m_dlSampleData[i]; - dMin = qMin(dMin,dTempValue); - } - } - return dMin; -// } -// switch(m_byPS) -// { -// case 1: -// if (byValueType == VAL_SECONDARY) -// { -// if(m_dPrimary > 1E-5) -// { -// // 幅值 -// if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) -// { -// for (int i = 0;i < m_aAmpArray.count();i++) -// { -// dTempValue = m_aAmpArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMin = qMin(dMin,dTempValue); -// } -// dMin = dMin * M_SQRT2; -// }//有效值 -// else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) -// { -// for (int i = 0;i < m_aAmpArray.count();i++) -// { -// dTempValue = (m_aAmpArray[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMin = qMin(dMin,dTempValue); -// } -// }//实部的值 -// else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) -// { -// for (int i = 0;i < m_aRealArray.count();i++) -// { -// dTempValue = m_aRealArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMin = qMin(dMin,dTempValue); -// } -// }//虚部的值 -// else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) -// { -// for (int i = 0;i < m_aImagArray.count();i++) -// { -// dTempValue = m_aImagArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMin = qMin(dMin,dTempValue); -// } -// }//角度 -// else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) -// { -// dMin = 180; -// }//采样值 -// else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) -// { -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = (m_dlSampleData[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMin = qMin(dMin,dTempValue); -// } -// } -// else -// { -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = (m_dlSampleData[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; -// dMin = qMin(dMin,dTempValue); -// } -// } -// //{{一次值转为二次值时量纲应随之变化 -// unsigned short ut = UnitType(); -// if( fabs(dMin) 1E-5) -// { -// // 幅值 -// if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) -// { -// for (int i = 0;i < m_aAmpArray.count();i++) -// { -// dTempValue = m_aAmpArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMin = qMin(dMin,dTempValue); -// } -// dMin = dMin * M_SQRT2; -// }//有效值 -// else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) -// { -// for (int i = 0;i < m_aAmpArray.count();i++) -// { -// dTempValue = m_aAmpArray[i]; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMin = qMin(dMin,dTempValue); -// } -// }//实部的值 -// else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) -// { -// for (int i = 0;i < m_aRealArray.count();i++) -// { -// dTempValue = m_aRealArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMin = qMin(dMin,dTempValue); -// } -// }//虚部的值 -// else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) -// { -// for (int i = 0;i < m_aImagArray.count();i++) -// { -// dTempValue = m_aImagArray[i]*M_SQRT2; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMin = qMin(dMin,dTempValue); -// } -// }//角度 -// else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) -// { -// dMin = 180; -// }//采样值 -// else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) -// { -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = m_dlSampleData[i]; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMin = qMin(dMin,dTempValue); -// } -// } -// else -// { -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = m_dlSampleData[i]; -// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; -// dMin = qMin(dMin,dTempValue); -// } -// } -// return dMin; -// } -// } -// } -// for (int i = 0;i < m_dlSampleData.count();i++) -// { -// dTempValue = m_dlSampleData[i]; -// dTempValue = dTempValue*m_dMultiplier+m_dOffsetAdder; -// dMin = qMin(dMin,dTempValue); -// } -// return dMin; -} +#include "CComDataClass.h" +#include "math.h" +//////////////////////////////////// +CAnalogData::CAnalogData(): m_nAverageTicks(0) +{ + m_nIndex = 0; //模拟通道索引 + m_sName = ""; //名称 + m_sPhase = ""; //相位特征 + m_sCCBM = ""; //被监视的回路元件 + m_sUnit = "V"; //单位 + m_sUnitRaw = "V"; //原始单位 + m_dMultiplier = 1.0; //a + m_dOffsetAdder = 0.0; //b ax+b + m_dSkew = 1.0; //通道时滞 + m_nMin = -32767; //最小 + m_nMax = 32767; //最大 + m_dPrimary = 1.0; //一次变比系数 + m_dSecondary = 1.0; //二次变比系数 + m_byPS = 0; //0-无效,1-一次值,2-二次值 特征符 + m_dlSampleData.resize(0); //采样值 + m_bSampleValid.resize(0); + m_nWaveType = CHN_NO_ATTR; + m_bVectorValid = false; + m_bFreqValid = false; + m_byPhaseType = PHASE_NULL; +} + +CAnalogData::~CAnalogData() +{ +} + + +CAnalogData &CAnalogData::operator=( const CAnalogData &p ) +{ + m_nIndex = p.m_nIndex; //模拟通道索引 + m_sName = p.m_sName; //名称 + m_sPhase = p.m_sPhase; //相位特征 + m_sCCBM = p.m_sCCBM; //被监视的回路元件 + m_sUnit = p.m_sUnit; //单位 + m_sUnitRaw = p.m_sUnitRaw; + m_dMultiplier = p.m_dMultiplier; //a + m_dOffsetAdder= p.m_dOffsetAdder; //b ax+b + m_dSkew=p.m_dSkew; //通道时滞 + m_nMin=p.m_nMin; //最小 + m_nMax = p.m_nMax; //最大 + m_dPrimary = p.m_dPrimary; //一次变比系数 + m_dSecondary = p.m_dSecondary; //二次变比系数 + m_byPS = p.m_byPS; //特征符 + + m_dlSampleData = p.m_dlSampleData; + m_bSampleValid = p.m_bSampleValid; + return *this; +} + +void CAnalogData::Detach() +{ + m_dlSampleData.detach(); + m_bSampleValid.detach(); +} + +void CAnalogData::clone(CAnalogData& clone) +{ + clone.m_nIndex = m_nIndex; //模拟通道索引 + clone.m_sName = m_sName; //名称 + clone.m_sPhase = m_sPhase; //相位特征 + clone.m_sCCBM = m_sCCBM; //被监视的回路元件 + clone.m_sUnit = m_sUnit; //单位 + clone.m_sUnitRaw = m_sUnitRaw; + clone.m_dMultiplier = m_dMultiplier; //a + clone.m_dOffsetAdder= m_dOffsetAdder; //b ax+b + clone.m_dSkew=m_dSkew; //通道时滞 + clone.m_nMin=m_nMin; //最小 + clone.m_nMax = m_nMax; //最大 + clone.m_dPrimary = m_dPrimary; //一次变比系数 + clone.m_dSecondary = m_dSecondary; //二次变比系数 + clone.m_byPS = m_byPS; //特征符 + + clone.m_dlSampleData = m_dlSampleData; + clone.m_bSampleValid = m_bSampleValid; +} + +void CAnalogData::CopyDataTo(CAnalogData& clone,int nBegin,int nEnd) +{ + if(nBegin>=0&&nBegin= 0 || + m_sChannelName.indexOf("ua") >= 0 || + m_sChannelName.indexOf(QObject::tr("phase A"), Qt::CaseInsensitive) >= 0 )//a相 + { + m_byPhaseType = PHASE_A; + } + else if(m_sChannelName.indexOf("ib") >= 0 || + m_sChannelName.indexOf("ub") >= 0 || + m_sChannelName.indexOf(QObject::tr("phase B"), Qt::CaseInsensitive) >= 0 )//a相 + { + m_byPhaseType = PHASE_B; + } + else if(m_sChannelName.indexOf("ic") >= 0 || + m_sChannelName.indexOf("uc") >= 0 || + m_sChannelName.indexOf(QObject::tr("phase C"), Qt::CaseInsensitive) >= 0 )//c相 + { + m_byPhaseType = PHASE_C; + } + else if(m_sChannelName.indexOf("a") >= 0) + { + m_byPhaseType = PHASE_A; + } + else if(m_sChannelName.indexOf("b") >= 0) + { + m_byPhaseType = PHASE_B; + } + else if(m_sChannelName.indexOf("c") >= 0) + { + m_byPhaseType = PHASE_C; + } + else + { + m_byPhaseType = PHASE_NULL; + } + +} + +unsigned short CAnalogData::UnitType() +{ + QString sUnit = m_sUnit.toLower(); + sUnit = sUnit.trimmed(); +// int n = sUnit.compare("kv"); +// n = QString::compare(sUnit,"kv"); + +// if(m_nWaveType == CHN_ANG0_ATTR) +// return UNIT_ANG; + /*else*/ if( 0 == sUnit.compare("kv") ) + return UNIT_KV; + else if( 0 == sUnit.compare("v") ) + return UNIT_V; + else if( 0 == sUnit.compare("ka") ) + return UNIT_KA; + else if( 0 == sUnit.compare("a") ) + return UNIT_A; + else if( 0 == sUnit.compare("kw") ) + return UNIT_KW; + else if( 0 == sUnit.compare("w") ) + return UNIT_W; + else if( 0 == sUnit.compare("va") ) + return UNIT_VA; + else if( 0 == sUnit.compare("var") ) + return UNIT_Var; + else if( 0 == sUnit.compare("kva") ) + return UNIT_KVA; + else if( 0 == sUnit.compare("kvar") ) + return UNIT_KVar; + return UNIT_NO; +} + +bool CAnalogData::GetTickValue(int nTick,byte byValueType,double& dValue) +{ + if(nTick<0||nTick>=m_dlSampleData.size()) + { + dValue = 0.0; + return true; + } +// int nSize = m_bSampleValid.size(); + + int fRaw = m_dlSampleData[nTick]; //采样值 + +// double fRealValue = m_aRealArray[nTick];//实部的值 +// double fImgValue = m_aImagArray[nTick]; //虚部的值 +// double fEfectValue = m_aAmpArray[nTick];//有效值 +// double fAngValue = m_aAngArray[nTick]; //角度 +// double fAmpValue = fEfectValue*M_SQRT2; //幅值 + +// bool bValid = m_bSampleValid[nTick]; + if( fRaw>m_nMax ) fRaw = m_nMax; + else if( fRaw < m_nMin ) fRaw = m_nMin; + + if(byValueType==VAL_RAW) + { + dValue = (double)fRaw; + return true; + } + + double fValue = fRaw*m_dMultiplier+m_dOffsetAdder; + switch(m_byPS) { + case 1://fvalue为一次值 + { + if(byValueType==VAL_SECONDARY) + { + if(m_dPrimary>1E-5) + { + dValue = fValue*m_dSecondary/m_dPrimary; + //{{一次值转为二次值时量纲应随之变化 + unsigned short ut = UnitType(); + //if( fabs(dValue)1E-5) + { + dValue = fValue*m_dPrimary/m_dSecondary; + return true; + } + } + } + break; + default: + break; + } + + dValue = fValue; + return true; +} + +double CAnalogData::GetUpDowmValue(int nTick,byte byValueType,double& dValue) +{ + if(nTick<0||nTick>=m_dlSampleData.size()) + { + dValue = 0.0; + return true; + } +// int nSize = m_bSampleValid.size(); + + int fRaw = m_dlSampleData[nTick]; //采样值 + + double fRealValue = m_aRealArray[nTick];//实部的值 + double fImgValue = m_aImagArray[nTick]; //虚部的值 + double fEfectValue = m_aAmpArray[nTick];//有效值 + double fAngValue = m_aAngArray[nTick]; //角度 + double fAmpValue = fEfectValue*M_SQRT2; //幅值 + +// bool bValid = m_bSampleValid[nTick]; + if( fRaw>m_nMax ) fRaw = m_nMax; + else if( fRaw < m_nMin ) fRaw = m_nMin; + + if(byValueType==VAL_RAW) + { + // 幅值 + if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) + { + dValue = fAmpValue; + }//有效值 + else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) + { + dValue = fEfectValue; + }//实部的值 + else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) + { + dValue = fRealValue*M_SQRT2; + }//虚部的值 + else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) + { + dValue = fImgValue*M_SQRT2; + }//角度 + else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) + { + dValue = fAngValue; + }//采样值 + else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) + { + dValue = (double)fRaw; + } + else + dValue = (double)fRaw; + return true; + } + + double fValue = fRaw*m_dMultiplier+m_dOffsetAdder; + switch(m_byPS) { + case 1://fvalue为一次值 + { + if(byValueType==VAL_SECONDARY) + { + if(m_dPrimary>1E-5) + { + //幅值 + if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) + { + dValue = (fAmpValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; + }//有效值 + else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) + { + dValue = (fEfectValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; + }//实部的值 + else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) + { + dValue = ((fRealValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary)*M_SQRT2; + }//虚部的值 + else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) + { + dValue = ((fImgValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary)*M_SQRT2; + }//角度 + else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) + { + dValue = fAngValue; + }//瞬时值 + else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) + { + dValue = fValue*m_dSecondary/m_dPrimary; + } + else + dValue = fValue*m_dSecondary/m_dPrimary; + //{{一次值转为二次值时量纲应随之变化 + unsigned short ut = UnitType(); + if( fabs(dValue)1E-5) + { + //幅值 + if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) + { + dValue = (fAmpValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; + }//有效值 + else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) + { + dValue = (fEfectValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; + }//实部的值 + else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) + { + dValue = ((fRealValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary)*M_SQRT2; + }//虚部的值 + else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) + { + dValue = ((fImgValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary)*M_SQRT2; + }//角度 + else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) + { + dValue = fAngValue; + }//瞬时值 + else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) + { + dValue = fValue*m_dPrimary/m_dSecondary; + } + else + dValue = fValue*m_dPrimary/m_dSecondary; + return true; + } + } + } + break; + default: + break; + } + //幅值 + if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) + { + dValue = fAmpValue*m_dMultiplier+m_dOffsetAdder; + }//有效值 + else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) + { + dValue = fEfectValue*m_dMultiplier+m_dOffsetAdder; + }//实部的值 + else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) + { + dValue = (fRealValue*m_dMultiplier+m_dOffsetAdder)*M_SQRT2; + }//虚部的值 + else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) + { + dValue = (fImgValue*m_dMultiplier+m_dOffsetAdder)*M_SQRT2; + }//角度 + else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) + { + dValue = fAngValue; + }//瞬时值 + else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) + { + dValue = fValue; + } + else + dValue = fValue; + return true; +} + +double CAnalogData::TransValueToRaw( byte byValueType,double dTypeValue ) +{ + if(byValueType==VAL_RAW) + return dTypeValue; + + double fValue = dTypeValue; + switch(m_byPS) { + case 1://fvalue为一次值 + if(byValueType==VAL_SECONDARY) + { + if(m_dPrimary>1E-5) + { + //{{二次值还原为一次值时量纲应随之变化 + unsigned short ut = UnitType(); + if( fabs(fValue)1E-5) + { + fValue = fValue*m_dSecondary/m_dPrimary; + } + } + break; + default: + break; + } + fValue = (fValue - m_dOffsetAdder)/m_dMultiplier; + return fValue; +} + +double CAnalogData::GetValueFromRaw( byte byValueType,double dRawValue ) +{ + if(byValueType==VAL_RAW) + return dRawValue; +// if (m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) +// return dRawValue; + double fValue = dRawValue*m_dMultiplier+m_dOffsetAdder; + switch(m_byPS) { + case 1://fvalue为一次值 + if(byValueType==VAL_SECONDARY) + { + if(m_dPrimary>1E-5) + { + fValue = fValue*m_dSecondary/m_dPrimary; + //{{一次值转为二次值时量纲应随之变化 + unsigned short ut = UnitType(); + if( fabs(fValue)1E-5) + { + fValue = fValue*m_dPrimary/m_dSecondary; + return fValue; + } + } + break; + default: + break; + } + return fValue; +} + +double CAnalogData::GetMaxValue(byte /*byValueType*/,double /*dValue*/) +{ + double dMax = 0.0; + double dTempValue = 0.0; + for(int i = 0;i= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) +// { +// dMax = dMax*M_SQRT2; +// } +// return dMax; +// if (byValueType == VAL_RAW) +// { + //幅值 + if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) + { + for (int i = 0;i < m_aAmpArray.count();i++) + { + dTempValue = m_aAmpArray[i]*M_SQRT2; + dMax = qMax(dMax,fabs(dTempValue)); + } + dMax = dMax * M_SQRT2; + }//有效值 + else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) + { + for (int i = 0;i < m_aAmpArray.count();i++) + { + dTempValue = m_aAmpArray[i]; + dMax = qMax(dMax,fabs(dTempValue)); + } + }//实部的值 + else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) + { + for (int i = 0;i < m_aRealArray.count();i++) + { + dTempValue = m_aRealArray[i]*M_SQRT2; + dMax = qMax(dMax,fabs(dTempValue)); + } + }//虚部的值 + else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) + { + for (int i = 0;i < m_aImagArray.count();i++) + { + dTempValue = m_aImagArray[i]*M_SQRT2; + dMax = qMax(dMax,fabs(dTempValue)); + } + }//角度 + else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) + { + dMax = 180; + }//采样值 + else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) + { + for (int i = 0;i < m_aAmpArray.count();i++) + { + dTempValue = m_aAmpArray[i]; + dMax = qMax(dMax,fabs(dTempValue)); + } + } + else + { + for (int i = 0;i < m_dlSampleData.count();i++) + { + dTempValue = m_dlSampleData[i]; + dMax = qMax(dMax,fabs(dTempValue)); + } + } +// //{{一次值转为二次值时量纲应随之变化 +// unsigned short ut = UnitType(); +// if( fabs(dMax) 1E-5) +// { +// // 幅值 +// if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) +// { +// for (int i = 0;i < m_aAmpArray.count();i++) +// { +// dTempValue = m_aAmpArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMax = qMax(dMax,dTempValue); +// } +// dMax = dMax * M_SQRT2; +// }//有效值 +// else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) +// { +// for (int i = 0;i < m_aAmpArray.count();i++) +// { +// dTempValue = (m_aAmpArray[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMax = qMax(dMax,dTempValue); +// } +// }//实部的值 +// else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) +// { +// for (int i = 0;i < m_aRealArray.count();i++) +// { +// dTempValue = m_aRealArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMax = qMax(dMax,dTempValue); +// } +// }//虚部的值 +// else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) +// { +// for (int i = 0;i < m_aImagArray.count();i++) +// { +// dTempValue = m_aImagArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMax = qMax(dMax,dTempValue); +// } +// }//角度 +// else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) +// { +// dMax = 180; +// }//采样值 +// else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) +// { +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = (m_dlSampleData[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMax = qMax(dMax,dTempValue); +// } +// } +// else +// { +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = (m_dlSampleData[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMax = qMax(dMax,dTempValue); +// } +// } +// //{{一次值转为二次值时量纲应随之变化 +// unsigned short ut = UnitType(); +// if( fabs(dMax) 1E-5) +// { +// // 幅值 +// if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) +// { +// for (int i = 0;i < m_aAmpArray.count();i++) +// { +// dTempValue = m_aAmpArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMax = qMax(dMax,dTempValue); +// } +// dMax = dMax * M_SQRT2; +// }//有效值 +// else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) +// { +// for (int i = 0;i < m_aAmpArray.count();i++) +// { +// dTempValue = m_aAmpArray[i]; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMax = qMax(dMax,dTempValue); +// } +// }//实部的值 +// else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) +// { +// for (int i = 0;i < m_aRealArray.count();i++) +// { +// dTempValue = m_aRealArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMax = qMax(dMax,dTempValue); +// } +// }//虚部的值 +// else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) +// { +// for (int i = 0;i < m_aImagArray.count();i++) +// { +// dTempValue = m_aImagArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMax = qMax(dMax,dTempValue); +// } +// }//角度 +// else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) +// { +// dMax = 180; +// }//采样值 +// else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) +// { +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = m_dlSampleData[i]; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMax = qMax(dMax,dTempValue); +// } +// } +// else +// { +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = m_dlSampleData[i]; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMax = qMax(dMax,dTempValue); +// } +// } +// return dMax; +// } +// } +// } +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = m_dlSampleData[i]; +// dTempValue = dTempValue*m_dMultiplier+m_dOffsetAdder; +// dMax = qMax(dMax,dTempValue); +// } +// return dMax; +} + +double CAnalogData::GetMinValue(byte /*byValueType*/,double /*dValue*/) +{ + double dMin = 0.0; + double dTempValue = 0.0; +// for(int i = 0;i= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) +// { +// dMin = dMin*M_SQRT2; +// } +// return dMin; +// if (byValueType == VAL_RAW) +// { + // 幅值 + if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) + { + for (int i = 0;i < m_aAmpArray.count();i++) + { + dTempValue = m_aAmpArray[i]*M_SQRT2; + dMin = qMin(dMin,dTempValue); + } + dMin = dMin * M_SQRT2; + }//有效值 + else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) + { + for (int i = 0;i < m_aAmpArray.count();i++) + { + dTempValue = m_aAmpArray[i]; + dMin = qMin(dMin,dTempValue); + } + }//实部的值 + else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) + { + for (int i = 0;i < m_aRealArray.count();i++) + { + dTempValue = m_aRealArray[i]*M_SQRT2; + dMin = qMin(dMin,dTempValue); + } + }//虚部的值 + else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) + { + for (int i = 0;i < m_aImagArray.count();i++) + { + dTempValue = m_aImagArray[i]*M_SQRT2; + dMin = qMin(dMin,dTempValue); + } + }//角度 + else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) + { + dMin = -180; + }//采样值 + else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) + { + for (int i = 0;i < m_aAmpArray.count();i++) + { + dTempValue = m_aAmpArray[i]; + dMin = qMin(dMin,dTempValue); + } + } + else + { + for (int i = 0;i < m_dlSampleData.count();i++) + { + dTempValue = m_dlSampleData[i]; + dMin = qMin(dMin,dTempValue); + } + } + return dMin; +// } +// switch(m_byPS) +// { +// case 1: +// if (byValueType == VAL_SECONDARY) +// { +// if(m_dPrimary > 1E-5) +// { +// // 幅值 +// if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) +// { +// for (int i = 0;i < m_aAmpArray.count();i++) +// { +// dTempValue = m_aAmpArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMin = qMin(dMin,dTempValue); +// } +// dMin = dMin * M_SQRT2; +// }//有效值 +// else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) +// { +// for (int i = 0;i < m_aAmpArray.count();i++) +// { +// dTempValue = (m_aAmpArray[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMin = qMin(dMin,dTempValue); +// } +// }//实部的值 +// else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) +// { +// for (int i = 0;i < m_aRealArray.count();i++) +// { +// dTempValue = m_aRealArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMin = qMin(dMin,dTempValue); +// } +// }//虚部的值 +// else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) +// { +// for (int i = 0;i < m_aImagArray.count();i++) +// { +// dTempValue = m_aImagArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMin = qMin(dMin,dTempValue); +// } +// }//角度 +// else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) +// { +// dMin = 180; +// }//采样值 +// else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) +// { +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = (m_dlSampleData[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMin = qMin(dMin,dTempValue); +// } +// } +// else +// { +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = (m_dlSampleData[i]*m_dMultiplier+m_dOffsetAdder)*m_dSecondary/m_dPrimary; +// dMin = qMin(dMin,dTempValue); +// } +// } +// //{{一次值转为二次值时量纲应随之变化 +// unsigned short ut = UnitType(); +// if( fabs(dMin) 1E-5) +// { +// // 幅值 +// if(m_nWaveType >= CHN_AMP0_ATTR && m_nWaveType <= CHN_AMP99_ATTR) +// { +// for (int i = 0;i < m_aAmpArray.count();i++) +// { +// dTempValue = m_aAmpArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMin = qMin(dMin,dTempValue); +// } +// dMin = dMin * M_SQRT2; +// }//有效值 +// else if(m_nWaveType >= CHN_EFCT0_ATTR && m_nWaveType <= CHN_EFCT99_ATTR) +// { +// for (int i = 0;i < m_aAmpArray.count();i++) +// { +// dTempValue = m_aAmpArray[i]; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMin = qMin(dMin,dTempValue); +// } +// }//实部的值 +// else if(m_nWaveType >= CHN_REAL0_ATTR && m_nWaveType <= CHN_REAL99_ATTR) +// { +// for (int i = 0;i < m_aRealArray.count();i++) +// { +// dTempValue = m_aRealArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMin = qMin(dMin,dTempValue); +// } +// }//虚部的值 +// else if(m_nWaveType >= CHN_IMG0_ATTR && m_nWaveType <= CHN_IMG99_ATTR) +// { +// for (int i = 0;i < m_aImagArray.count();i++) +// { +// dTempValue = m_aImagArray[i]*M_SQRT2; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMin = qMin(dMin,dTempValue); +// } +// }//角度 +// else if(m_nWaveType >= CHN_ANG0_ATTR && m_nWaveType <= CHN_ANG99_ATTR) +// { +// dMin = 180; +// }//采样值 +// else if(m_nWaveType >= CHN_RVAL0_ATTR && m_nWaveType <= CHN_RVAL99_ATTR) +// { +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = m_dlSampleData[i]; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMin = qMin(dMin,dTempValue); +// } +// } +// else +// { +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = m_dlSampleData[i]; +// dTempValue = (dTempValue*m_dMultiplier+m_dOffsetAdder)*m_dPrimary/m_dSecondary; +// dMin = qMin(dMin,dTempValue); +// } +// } +// return dMin; +// } +// } +// } +// for (int i = 0;i < m_dlSampleData.count();i++) +// { +// dTempValue = m_dlSampleData[i]; +// dTempValue = dTempValue*m_dMultiplier+m_dOffsetAdder; +// dMin = qMin(dMin,dTempValue); +// } +// return dMin; +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogueShow.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogueShow.cpp index b0fea4dd..669046a9 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogueShow.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogueShow.cpp @@ -1,1266 +1,1266 @@ -#include "CAnalogueShow.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CPublic.h" -#include "CWaveShow.h" -#include "CComDataClass.h" -//#include "clabelsetdlg.h" -#include "CPrintPreview.h" -///////////////////////////////////////////////////// -CAnalogueShow::CAnalogueShow(QWidget *parent, Qt::WindowFlags f ) - :QWidget(parent,f) -{ -//Scroll - setWindowFlag( Qt::WindowStaysOnTopHint ); - setMouseTracking(true); -// setAttribute(Qt::WA_PaintOutsidePaintEvent); - - QPalette p = palette(); - //p.setColor(backgroundRole(), QColor(255,255,255)); - p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_WaveBackColor); - // p.setColor(foregroundRole(), QColor(255,255,255)); - //p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_WaveForeColor); - setPalette(p); - setAutoFillBackground(true); - - QHBoxLayout* hboxLayout = new QHBoxLayout(this); - hboxLayout->setSpacing(0); - hboxLayout->setContentsMargins(0, 0, 0, 0); - - QSpacerItem* spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); - vert_bar = new QScrollBar(Qt::Vertical,this); - hboxLayout->addItem(spacerItem); - hboxLayout->addWidget( vert_bar ); - - vert_bar->setSingleStep(SCROLLBAR_V_LINE); - vert_bar->setPageStep(SCROLLBAR_V_LINE); - vert_bar->setTracking(false); - vert_bar->setMinimum(0); - vert_bar->setMaximum(10); - vert_bar->setCursor(GetParent()->m_hHandCursor); - connect(vert_bar,SIGNAL(valueChanged(int)),this,SLOT(VerticalScrollBarMove(int))); - connect(vert_bar,SIGNAL(sliderMoved(int)),this,SLOT(VerticalScrollBarMove(int))); - -//init - m_pWaveFile = 0; - m_pSelectLabel = 0L; - m_nCursorX = -1; - m_nCompPosY = -1; - m_nScrollTop = 0; - m_nScrollLeft = 0; - m_nWaveViewWidth = 0; - m_ValueFont = QFont("Arial",10); - - LLGrayPen = QPen(LLGRAY_COLOR,1,Qt::SolidLine); - LGrayPen = QPen(LGRAY_COLOR,1,Qt::SolidLine); - BluePen = QPen(BLUE_COLOR,1,Qt::SolidLine); - RedPen = QPen(RED_COLOR,1,Qt::SolidLine); - GrayPen = QPen(DGRAY_COLOR,1,Qt::SolidLine); - LCyanPen = QPen(LCYAN_COLOR,1,Qt::SolidLine); - WhitePen = QPen(WHITE_COLOR,1,Qt::SolidLine); - BlackPen = QPen(BLACK_COLOR,1,Qt::SolidLine); - - setCursor( GetParent()->m_hCrossCursor ); - -} - -CAnalogueShow::~CAnalogueShow() -{ - -} - -////////////////////////////////////////////////////////////////////////// -void CAnalogueShow::VerticalScrollBarMove(int value) -{ - setCursor(GetParent()->m_hHandCursor); - GetParent()->VAnaScroll(value); -} - -void CAnalogueShow::OnMousePressEvent( QMouseEvent *e ) -{ -// QDateTime tt = QDateTime::currentDateTime(); -// qDebug("开始时间是%d \n",tt.time().msec()); - - if(!GetParent()) - { - QWidget::mousePressEvent( e ); - return; - } - - if( 0==GetParent()->m_nZoomState || 1==GetParent()->m_nZoomState ) - { - if(e->button() == Qt::LeftButton ) - { - //选中波形 - GetParent()->HitTestWave( m_nScrollTop,e->pos().y() ); - - if( 0==GetParent()->m_nZoomState ) - GetParent()->OnAnaAreaIn(); - else if(1==GetParent()->m_nZoomState) - GetParent()->OnAnaAreaOut(); - } - else - { - GetParent()->SetZoomState( CWaveShow::SINGLEZOOM_NULL ); - } - QWidget::mousePressEvent( e ); - return; - } - - if(e->button() == Qt::LeftButton) - { - bool bMoveLabel = false; - if(m_pSelectLabel){ - m_pSelectLabel = 0L;bMoveLabel = true;} - else - m_pSelectLabel = m_pWaveFile->SelectLabel(QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop)); - - if(m_pSelectLabel||bMoveLabel) - { - update(); - QWidget::mousePressEvent( e ); - return; - } - } - doMousePress( e ); - -// update(); -// GetParent()->update(); - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(4,false); - GetParent()->redrawWindow(5,false); - GetParent()->redrawWindow(1,false);//在名称去显示数据值,20090818 - GetParent()->redrawWindow(7,false); - GetParent()->showStatus(); - -// if( GetParent()->m_pStatusView ) -// GetParent()->m_pStatusView->Refresh(); -// if(GetParent()->m_pLinStatusView) -// GetParent()->m_pLinStatusView->Refresh(); - - QWidget::mousePressEvent( e ); - -// QDateTime tt1 = QDateTime::currentDateTime(); -// qDebug("结束时间是%d \n",tt1.time().msec()); -// qDebug("时间差是%d \n",tt1.time().msec() - tt.time().msec()); -// QString stt = QString::number(tt.time().msec()) + "\n"; -// stt += QString::number(tt1.time().msec()); -} - -void CAnalogueShow::OnMouseReleaseEvent( QMouseEvent *e ) -{ - - QWidget::mouseReleaseEvent( e ); -} - -void CAnalogueShow::OnMouseMoveEvent( QMouseEvent *e ) -{ - setCursor(GetParent()->m_hCrossCursor); - if(GetParent()) - { - if( 0==GetParent()->m_nZoomState || 1==GetParent()->m_nZoomState ) - { - QWidget::mouseMoveEvent( e ); - return; - } - - if(m_pSelectLabel) - { - QPoint m_TopLeft = QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop); - m_pSelectLabel->m_lLeftTick = m_pWaveFile->GetTick(m_TopLeft.x()); - m_pSelectLabel->m_dTopValue = ((double)m_TopLeft.y())/m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - -// m_pSelectLabel->m_TopLeft = QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop); - update(); - } - - doMouseMove(e); -// -// CDigitalShow *pDgtView = GetParent()->m_pDigitalView; -// if(pDgtView) pDgtView->doMouseMove( e ); -// -// int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; -// QPoint pt(e->x() + nLeftMargin,e->y()); -// QMouseEvent event(QEvent::MouseMove,pt,e->button(),e->buttons(),e->modifiers()); -// -// CTimeAxisShow *pTimeView = GetParent()->m_pTimeAxisView; -// if(pTimeView) pTimeView->doMouseMove( &event ); - -// GetParent()->redrawWindow(4,false); -// GetParent()->redrawWindow(5,false); -// update(); - } - QWidget::mouseMoveEvent( e ); -} - -void CAnalogueShow::wheelEvent( QWheelEvent* e ) -{ - bool bVscroll = false; - bool bHscroll = false; - if(QApplication::keyboardModifiers() == Qt::ControlModifier) - { - bVscroll = true; - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 += AMP_RATE; - else if(e->delta() < 0) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 -=AMP_RATE; - - } - else if(QApplication::keyboardModifiers() == Qt::ShiftModifier) - { - bHscroll = true; - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; - else - m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; - } - else - { - bVscroll = true; - vert_bar->setValue( vert_bar->value() - e->delta()/10 ); - } - - if(bVscroll) - { - if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 > 20.0) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 20.0; - if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 < 0.5) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 0.5; - } - - if(bHscroll) - { - if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; - if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; - } - - if(bVscroll) - { - ResetVScrollSize(); - //GetParent()->m_pDigitalView->ResetVScrollSize(); - } - if(bHscroll) - GetParent()->m_pTimeAxisView->ResetHScrollSize(); - - if(bHscroll | bVscroll) - { - GetParent()->redrawWindow(1,false); - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(3,false); - GetParent()->redrawWindow(4,false); - GetParent()->redrawWindow(5,false); - } -} - -void CAnalogueShow::contextMenuEvent ( QContextMenuEvent *e ) -{ - Q_UNUSED(e) -// if(m_pSelectLabel) -// { -// QMenu* contextMenu = new QMenu( this ); -// Q_CHECK_PTR( contextMenu ); -// contextMenu->addAction( tr("删除标注"), this, SLOT(OnDelLabel())); -// contextMenu->addAction( tr("修改标注"), this, SLOT(OnModLabel())); -// contextMenu->exec( QCursor::pos() ); -// delete contextMenu; -// } -// else -// { -// //选中波形 -// GetParent()->HitTestWave( m_nScrollTop,e->pos().y() ); -// int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; -// if( Ch<0 || Ch>=MAX_WAVES) -// return; -// -// QMenu* contextMenu = new QMenu( this ); -// Q_CHECK_PTR( contextMenu ); -// -// contextMenu->addAction( tr("波形幅值放大"), GetParent(), SLOT(OnAnaAmpIn())); -// contextMenu->addAction( tr("波形幅值缩小"), GetParent(), SLOT(OnAnaAmpOut())); -// // contextMenu->addAction( tr("设置波形幅值..."), GetParent(), SLOT(OnAnaAmpSet())); -// contextMenu->addAction( tr("波形显示区放大"), GetParent(), SLOT(OnAnaAreaIn())); -// contextMenu->addAction( tr("波形显示区缩小"), GetParent(), SLOT(OnAnaAreaOut())); -// contextMenu->addSeparator(); -// contextMenu->addAction( tr("隐藏本通道"), GetParent(), SLOT(OnHideWaveChannel())); -// contextMenu->addAction( tr("恢复默认分组"), GetParent(), SLOT(OnResumeGroup())); -// contextMenu->addSeparator(); -// contextMenu->addAction( tr("颜色设置"), GetParent(), SLOT(OnAnaColorSet())); -// contextMenu->addAction( tr("线型设置"), GetParent(), SLOT(OnAnaLineSet())); -// contextMenu->addSeparator(); -// contextMenu->addAction( tr("设置基准线(B线)"), GetParent(), SLOT(OnSetZoneStart())); -// contextMenu->addAction( tr("取消基准线(B线)"), GetParent(), SLOT(OnCacelZone())); -// contextMenu->addSeparator(); -// contextMenu->addAction( tr("添加标注"), GetParent(), SLOT(OnAddLabel())); -// contextMenu->addAction( tr("标注列表"), GetParent(), SLOT(OnLabelList())); -// -// contextMenu->exec( QCursor::pos() ); -// delete contextMenu; -// } -// setCursor(GetParent()->m_hCrossCursor); -} - -void CAnalogueShow::paintEvent( QPaintEvent *e ) -{ - Q_UNUSED(e) - QPainter paint; - paint.begin( this ); - paint.setBrush( Qt::white);//palette().color( QPalette::Foreground )); - //paint.setPen( Qt::red); - draw( &paint ); - paint.end(); -} - -void CAnalogueShow::draw(QPainter *paint) -{ - if(!m_pWaveFile) return; - drawBackGnd(paint); -// drawChannelLine(paint); -// drawVertGridLine(paint); - drawWave(paint); - //QSize s = frameSize(); - if( CWaveEnv::GetInst()->m_bShowBaseLine ) - drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fBaseTick,CWaveEnv::GetInst()->m_BaseLineColor);//第一时标线 - - if(CWaveEnv::GetInst()->m_bShowTriggerLine) - drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fTriggerTick,RED_COLOR);//触发线 - - drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fStaticTick,CWaveEnv::GetInst()->m_StaticLineColor);//当前时标线 -// drawUpDownLineValue(paint,m_pWaveFile->m_DispAttr.m_fStaticTick); //当前时标值 - -// drawCursor(paint); - if( CWaveEnv::GetInst()->m_bShowCompLine ) - drawCompLine( paint ); - -} - -void CAnalogueShow::drawBackGnd(QPainter *paint) -{ - if(!m_pWaveFile) return; - -// int XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime); -// if(XPosition1 < 0 || XPosition1 > m_pWaveFile->GetMaxWidth()) -// XPosition1 = 0; -// XPosition1 -= m_nScrollLeft; -// -// int XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime); -// if(XPosition2 < 0 || XPosition2 > m_pWaveFile->GetMaxWidth()) -// XPosition2 = 0; -// XPosition2 -= m_nScrollLeft; - - QBrush oldBrush = paint->brush(); - QPen oldPen = paint->pen(); - - QRect ClientRect = rect(); - QRect rcDraw = ClientRect; - - //QSize s = frameSize(); - QSize s = size(); - //rcDraw.setLeft(XPosition1); - //rcDraw.setRight(XPosition2); - - rcDraw.setRight( s.width() - SPLITTERWIDTH ); - //rcDraw.setTop( CWaveEnv::GetInst()->m_nWaveViewTop1 ); - if(rcDraw.right() > rcDraw.left()) - { - //paint->setBrush(CWaveEnv::GetInst()->m_MiddleColor); - paint->setBrush(CWaveEnv::GetInst()->m_WaveBackColor); - paint->setPen(CWaveEnv::GetInst()->m_WaveBackColor); - paint->drawRect(rcDraw); - } - - paint->setPen(oldPen); - paint->setBrush(oldBrush); -} - -void CAnalogueShow::drawChannelLine(QPainter *paint) -{ - if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowGrid) return; - - QRect ClientRect = paint->viewport(); - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); - if(ClientRect.right() < ClientRect.left()) return; - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - QPen oldPen = paint->pen(); - paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); - int nTop = 0; - int i=0; - for( i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; - - int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; - int nYPos = nTop + nWaveHeight/2 - m_nScrollTop; - nTop += nWaveHeight; - - if(nYPos < ClientRect.top()) continue; - if(nYPos > ClientRect.bottom()) break; - - paint->drawLine(ClientRect.left(), nYPos, ClientRect.right(), nYPos); - - int nGrid = nWaveHeight/4; - if( nGrid <10 ) - continue; - nYPos -= nGrid; - paint->drawLine(ClientRect.left(), nYPos, ClientRect.right(), nYPos); - nYPos += nGrid*2; - paint->drawLine(ClientRect.left(), nYPos, ClientRect.right(), nYPos); - } - -/* - paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); - nTop = 0; - if(CWaveEnv::GetInst()->m_bShowGrid) - { - for(int i=0; iGetMaxWaveGroupNum()+1 && im_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; - - int nGridHeight = int(double(m_pWaveFile->m_DispAttr.m_dGridHeight) * dWaveZoomY1); - if(nGridHeight==0) nGridHeight=10; - - int nGrids = nWaveHeight/2/nGridHeight; - int nYPos = nTop + nWaveHeight/2 - m_nScrollTop; - nTop += nWaveHeight; - - for(int j=1; j<=nGrids; j++) - { - int nYPos2 = nYPos + j*nGridHeight; - paint->drawLine( ClientRect.left(), nYPos2, ClientRect.right(), nYPos2); - nYPos2 = nYPos - j*nGridHeight; - paint->drawLine( ClientRect.left(), nYPos2, ClientRect.right(), nYPos2); - } - } - }*/ - paint->setPen(oldPen); -} - -void CAnalogueShow::drawVertGridLine( QPainter *paint) -{ - if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowVertGrid) return; - - QRect ClientRect = paint->viewport(); - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); - if(ClientRect.right() < ClientRect.left()) return; - - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; -// int nHeight = 12; - - double fOneWidth = int(dGirdWidth*(fZoomX)+.5); - if(fOneWidth < dGirdWidth) - fOneWidth = dGirdWidth; - - QPen oldPen = paint->pen(); - paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); - for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) - { - int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); - int nBlockRight = m_pWaveFile->GetBlockRight(nBlk); - long lTimeBegin = m_pWaveFile->GetBlockBeginTime(nBlk); - long lTimeEnd = m_pWaveFile->GetBlockEndTime(nBlk); - - if((nBlockLeft-m_nScrollLeft) > ClientRect.width()) break; - - double dRate = m_pWaveFile->m_dSampleRate[nBlk]; - int nGridAmt = int(double(nBlockRight-nBlockLeft)/fOneWidth+.5)+1; - - int dGridArr[10] = {10,20,50, 200, 500, 1000, 2000, 5000, 10000,20000 }; - int nUnit = 0; - - int i = 0; - int nSelGridArr = dGridArr[0]; - for( i=nUnit; i<10; i++) - { - nSelGridArr = dGridArr[i]; - if(nSelGridArr*dRate/1000.0 >=10.0) - break; - } - - int nTick =0; - int nTime = lTimeBegin; - int nIntTime = 0; - for(nTick=0; nTick=lTimeBegin ) - { - int nIntTick = int(.5+(nIntTime-lTimeBegin) / (1000.0/dRate)); - int nIntPos = nBlockLeft + nIntTick*fOneWidth-m_nScrollLeft; - if( nIntPos > nBlockRight) break; - if(nIntPos > ClientRect.right() ) - break; - if( nIntPos < ClientRect.left() ) - continue; - paint->drawLine(nIntPos,0,nIntPos,ClientRect.bottom()); - } - } - } - } - - paint->setPen(oldPen); -} - -void CAnalogueShow::drawWave(QPainter *paint) -{ - if(!m_pWaveFile) return; - - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double fGridWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - int nOneWidth = 0; - if(fZoomX >= (1.0 - 1E-5)) nOneWidth = int(fGridWidth*fZoomX+.5); - else nOneWidth = int(.5+fGridWidth); - - QRect ClientRect = paint->viewport(); -// int nh = rect().height(); - - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); - if(ClientRect.right() < ClientRect.left()) return; - int nTop = 0; -// int nLeftWaveAxis = m_pWaveFile->m_DispAttr.m_nLeftWaveAxis; - - for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[i]*/ ) - continue; - - int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; -// double dMax = 0.01; -// double dChMax = 0.0; -// double dMin = -0.01; -// double dChMin = 0.0; - - if(nTop - m_nScrollTop>ClientRect.bottom()) break; - - int nMidLineY = nTop + nWaveHeight/2 - m_nScrollTop; - nTop += nWaveHeight; - if(nTop - m_nScrollTop + nWaveHeight<0) continue; - bool bShow = false; - for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i) continue; - if(m_pWaveFile->m_DispAttr.m_bWaveMarked[Ch]) continue; - bShow = true; - QPen oldPen = paint->pen(); - QPen WavePen; - // - //int nMidLineY = nTop + nWaveHeight/2 - m_nScrollTop; - PHASE_TYPE byPhType = m_pWaveFile->AnalogDataList[Ch].m_byPhaseType; - switch(byPhType) - { - case PHASE_A: - case PHASE_B: - case PHASE_C: - paint->setPen(QPen(m_pWaveFile->m_DispAttr.m_dwColorArray1[byPhType-1], - m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], - m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] - )); - break; - default: - paint->setPen(QPen(m_pWaveFile->m_DispAttr.m_DefaultWaveColor, - m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], - m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] - )); - break; - } - - //paint->setPen(WavePen); - - //dChMax = m_pWaveFile->AnalogDataList[Ch].GetMaxValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); - //dChMin = m_pWaveFile->AnalogDataList[Ch].GetMinValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); - - //dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMax); - //dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMin); - - //dMax = qMax(dMax, dChMax); - //dMin = qMin(dMin, dChMin); - - QPoint ptPrev; - int nTickPos = 0; - bool bFirst = false; - for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) - { - bool bAmplitude = false; - if(m_pWaveFile->m_dSampleRate[nBlk] < 100.1) bAmplitude = true; - - int nBlockRight = m_pWaveFile->GetBlockRight(nBlk); - if((nBlockRight-m_nScrollLeft) < 0) { nTickPos += m_pWaveFile->m_lSampleAmount[nBlk] ; continue; } - int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); - if((nBlockLeft-m_nScrollLeft) > ClientRect.width()) break; - - - for(int nTick=0; nTickm_lSampleAmount[nBlk]; nTick++) - { - int nXPos; - if(fZoomX >= (1.0 - 1E-5)) nXPos = nBlockLeft+nTick*nOneWidth; - else nXPos = nBlockLeft + int(double(nTick*nOneWidth)*fZoomX); - - - if((nXPos-m_nScrollLeft) < 0){ nTickPos++;continue;} - if((nXPos-m_nScrollLeft) > ClientRect.width()) break; - - CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; - double Value = 0.0; - Ana.GetTickValue(nTickPos,VAL_RAW/*m_pWaveFile->m_DispAttr.m_byValueType*/,Value); - //Ana.GetUpDowmValue(nTickPos,m_pWaveFile->m_DispAttr.m_byValueType,Value); - nTickPos++; - Value = m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch]*(Value); - Value = Value/90*m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - //Value = Value/dMax*m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch]*0.5*m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - if(bAmplitude) - { - QPoint pt(nXPos - m_nScrollLeft, nMidLineY-int(Value)); - - if(nTick == 0) - { - paint->drawLine(ptPrev,pt); - paint->drawLine(nXPos - m_nScrollLeft, nMidLineY-int(Value)-1, nXPos - m_nScrollLeft, nMidLineY+int(Value)+1); - } - else - { - paint->drawLine(nXPos - m_nScrollLeft, nMidLineY-int(Value)-1, nXPos - m_nScrollLeft, nMidLineY+int(Value)+1); - } - ptPrev = pt; - } - else - { - QPoint pt(nXPos - m_nScrollLeft, nMidLineY-int(Value)); - if(!bFirst) - { - ptPrev = pt; - bFirst = true; - } - else - { - paint->drawLine(ptPrev,pt); - ptPrev = pt; - } - } - } - } - - - if(!CWaveEnv::GetInst()->m_bShowLabel) continue; - paint->setPen(QPen(QColor(255,255,255/*CWaveEnv::GetInst()->m_LabelTextColor*/))); - QString szChannelName = m_pWaveFile->AnalogDataList[Ch].m_sName; - for(int j=0;j<(int)m_pWaveFile->m_LabelList.count();j++) - { - CLabel label = m_pWaveFile->m_LabelList[j]; - if(0!=QString::compare(label.m_szChannelName,szChannelName)) continue; - - int nLabelYPos=nMidLineY; - int nLabelXPos = m_pWaveFile->GetXPosition(label.m_lTime); - if(nLabelXPos== (-1)) return; - - int nLabelTick = int(.5+m_pWaveFile->GetTick(nLabelXPos)); - if(nLabelTick<0 || nLabelTick >= m_pWaveFile->GetTotalPointAmount()) return; - - CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; - double Value = 0.0; - Ana.GetTickValue(nTickPos,VAL_RAW/*m_pWaveFile->m_DispAttr.m_byValueType*/,Value); - - Value = m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch]*(Value); - Value = Value/100.0 * m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - nLabelYPos += int(Value); - nLabelXPos -= m_nScrollLeft; - - QPoint pt(nLabelXPos,nLabelYPos); - drawLabel(paint,&label,pt ); - } - paint->setPen(oldPen); - } - if(!bShow) - nTop -= nWaveHeight; - } -} -//画竖线 -void CAnalogueShow::drawUpDownLine(QPainter * paint, double fLineTick, const QColor& clr) -{ - if(!m_pWaveFile) return; - - int XPosition = m_pWaveFile->GetPointPosition(fLineTick); - if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) - XPosition = m_pWaveFile->GetMaxWidth(); - - XPosition -= m_nScrollLeft; - - QRect ClientRect = rect(); - if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) - { - LCyanPen.setColor(clr); - QPen oldPen = paint->pen(); - paint->setPen(LCyanPen); - - paint->drawLine(XPosition,0,XPosition,ClientRect.bottom()); - - paint->setPen(oldPen); - } -} -//画线值 -void CAnalogueShow::drawUpDownLineValue(QPainter * paint, double fLineTick) -{ - if(!m_pWaveFile) return; - - int nXPos = m_pWaveFile->GetPointPosition(fLineTick); - if(nXPos== (-1)) return; - - int nThisTick = fLineTick; - if(nThisTick<0 || nThisTick >= m_pWaveFile->GetTotalPointAmount()) return; - - nXPos -= m_nScrollLeft; - - QRect ClientRect = rect(); - if(nXPos < ClientRect.left() || nXPos > ClientRect.right()) - return; - - QFont oldFont = paint->font(); - paint->setFont(m_ValueFont); - QColor oldColor = CWaveEnv::GetInst()->m_WaveBackColor; - Qt::BGMode oldMode = paint->backgroundMode(); - paint->setBackgroundMode(Qt::TransparentMode); - QPen oldPen = paint->pen(); - //paint->setPen(QColor(255-oldColor.red(),255-oldColor.green(),255-oldColor.blue())); - paint->setPen(CWaveEnv::GetInst()->m_WaveForeColor); - - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - int nTop = 0; - for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; - - int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; - int nYPos = nTop + nWaveHeight/2 - 15 - m_nScrollTop; - nTop += nWaveHeight; - - if(nTop - m_nScrollTop<0) continue; - if(nTop - m_nScrollTop>ClientRect.bottom()) break; - - QString ValueString;; - ValueString = ""; -// bool bFind = false; - - for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i) continue; -// bFind = true; - - double Value; - CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; - char TempString[100]; -// int nWaveType = Ana.m_nWaveType; - if(Ana.GetUpDowmValue(nThisTick,m_pWaveFile->m_DispAttr.m_byValueType,Value)) - sprintf(TempString,"%8.2f",Value); - else sprintf(TempString,"*****"); - - if(ValueString.length()!=0) ValueString.append(","); - ValueString.append(TempString); - } - QRect Rect2(nXPos+5,nYPos,150,20); - paint->drawText(Rect2,Qt::AlignLeft | Qt::TextSingleLine,ValueString); - } - - paint->setPen(oldPen); - paint->setBackgroundMode(oldMode); - paint->setBackground(QBrush(oldColor)); - paint->setFont(oldFont); -} - -void CAnalogueShow::drawCursor(QPainter* paint) -{ - if(m_nCursorX > 0) - { - QRect rcRect = rect(); - QPen oldPen = paint->pen(); - //paint->setPen(BluePen); - paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); - paint->drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); - paint->setPen(oldPen); - } -} - -void CAnalogueShow::drawCompLine( QPainter* paint ) -{ - if(m_nCompPosY > 0) - { - QRect rcRect = rect(); - - QPainter::CompositionMode OldRop2 = paint->compositionMode(); - paint->setCompositionMode(QPainter::CompositionMode_Xor); - QPen oldPen = paint->pen(); - paint->setPen(BluePen); - - paint->drawLine(rcRect.left(), m_nCompPosY,rcRect.right(), m_nCompPosY); - - paint->setPen(oldPen); - paint->setCompositionMode(OldRop2); - } -} - -void CAnalogueShow::drawLabel(QPainter* paint,CLabel* pLabel,QPoint ptChannel) -{ - int nLeft = m_pWaveFile->GetPointPosition(pLabel->m_lLeftTick); - int nTop = m_pWaveFile->m_DispAttr.m_dWaveZoomY1*pLabel->m_dTopValue; - - QRect rc = QRect(QPoint(nLeft,nTop) - QPoint(m_nScrollLeft,m_nScrollTop),pLabel->m_Size); - - QPen LabelPen(CWaveEnv::GetInst()->m_LabelFrameColor,1,Qt::SolidLine); - QPen LinePen(CWaveEnv::GetInst()->m_LabelConnectColor,1,Qt::DotLine); - QPen oldPen = paint->pen(); - QBrush oldBrh = paint->brush(); - - paint->setPen(LabelPen); - paint->setBrush(CWaveEnv::GetInst()->m_LabelBackColor); - - Qt::BGMode oldMode = paint->backgroundMode(); - paint->setBackgroundMode(Qt::OpaqueMode); - - QPoint Mid; - if(ptChannel.y() > rc.top()) - Mid = QPoint((rc.left()+rc.right())/2,rc.bottom()); - else - Mid = QPoint((rc.left()+rc.right())/2,rc.top()); - paint->drawRect(rc); - paint->setBackgroundMode(oldMode); - paint->setPen(CWaveEnv::GetInst()->m_LabelTextColor); - paint->drawText(rc,Qt::AlignHCenter |Qt::AlignVCenter | Qt::TextSingleLine,(pLabel->m_szText)); - paint->setPen(LinePen); - paint->drawLine(Mid,ptChannel); - - paint->setPen(oldPen); - paint->setBrush(oldBrh); - -} - -void CAnalogueShow::GetWaveMargin(QRect &rect) -{ - if(!m_pWaveFile) return; -// double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - if(m_pWaveFile->m_nNRates<=0) - {rect = QRect(0,0,0,0);return;} - - int nLeft = m_pWaveFile->GetBlockLeft(0); - int nRight = m_pWaveFile->GetBlockRight(m_pWaveFile->m_nNRates-1); - - int nTop = 0; - int nBottom = 0; - for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; - - int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; - - bool bPrintGroup = false; - for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; - bPrintGroup = true; - } - if(!bPrintGroup) continue; - - nBottom += nWaveHeight; - } - - rect = QRect(nLeft,nTop,nRight - nLeft,nBottom - nTop); - -} - -void CAnalogueShow::Print(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor) -{ - if(!m_pWaveFile) return; - PrintChannelLine(paint,rect,ptOffset,bColor); - PrintWave(paint,rect,ptOffset,bColor); -} - -void CAnalogueShow::PrintChannelLine(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor) -{ - if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowGrid) return; - - QRect ClientRect = rect; - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth())); - if(ClientRect.right() < ClientRect.left()) return; - - QPen oldPen = paint->pen(); - if(bColor) paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); - else paint->setPen(QPen(Qt::lightGray,0,Qt::DotLine)); - - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - int nTop = 0; - for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; - - int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; - - bool bPrintGroup = false; - for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; - bPrintGroup = true; - } - if(!bPrintGroup) continue; - - int nYPos = nTop + nWaveHeight/2; - nTop += nWaveHeight; - - if(nYPos < ClientRect.top()||nYPos > ClientRect.bottom()) continue; - paint->drawLine(QPoint(ClientRect.left(), nYPos) + ptOffset, QPoint(ClientRect.right(), nYPos)+ptOffset); - } - paint->setPen(oldPen); -} - -void CAnalogueShow::PrintWave(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor) -{ - if(!m_pWaveFile) return; - - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double fGridWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - int nOneWidth = 0; - if(fZoomX >= (1.0 - 1E-5)) nOneWidth = int(fGridWidth*fZoomX+.5); - else nOneWidth = int(.5+fGridWidth); - - QRect ClientRect = rect; - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth())); - if(ClientRect.right() < ClientRect.left()) return; - - QPen oldPen = paint->pen(); - if(!bColor) - paint->setPen(BlackPen); - - int nTop = 0; - for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; - - int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; - - int nMidLineY = nTop + nWaveHeight/2; - - bool bPrintGroup = false; - for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; - - bPrintGroup = true; - - QPen WavePen(m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch], - m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], - m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] - ); - - - if(bColor) paint->setPen(WavePen); - - int nTickPos = 0; - QPoint ptPrev; - for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) - { - bool bAmplitude = false; - if(m_pWaveFile->m_dSampleRate[nBlk] < 100.1) bAmplitude = true; - - int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); - bool bFirst = true; - for(int nTick=0; nTickm_lSampleAmount[nBlk]; nTick++) - { - int nXPos; - if(fZoomX >= (1.0 - 1E-5)) nXPos = nBlockLeft+nTick*nOneWidth; - else nXPos = nBlockLeft + int(double(nTick*nOneWidth)*fZoomX); - - nTickPos++; - if( nXPos > ClientRect.right() ) - break; - - if(nXPos < ClientRect.left()) - continue; - - CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; - - double Value = 0.0; - Ana.GetTickValue(nTickPos,VAL_RAW/*m_pWaveFile->m_DispAttr.m_byValueType*/,Value); - - - Value = m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch]*(Value); - Value = Value/100.0 * m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - - if(bAmplitude) - { - if(true)//幅值为竖线 - { - QPoint p1 = QPoint(nXPos, nMidLineY-int(Value)-1); - QPoint p2 = QPoint(nXPos, nMidLineY+int(Value)+1); - paint->drawLine(p1+ptOffset,p2+ptOffset); - } - else - { - paint->drawPoint( QPoint(nXPos, nMidLineY) + ptOffset ); - } - } - else - { - QPoint pt = QPoint(nXPos, nMidLineY-int(Value))+ptOffset; - if(bFirst) - { - ptPrev = pt; - bFirst=false; - } - else - { - paint->drawLine(ptPrev,pt); - ptPrev = pt; - } - } - } - } - - if(!bPrintGroup) continue; - - nTop += nWaveHeight; - - QString szChannelName = m_pWaveFile->AnalogDataList[Ch].m_sName; - for(int j=0;j<(int)m_pWaveFile->m_LabelList.count();j++) - { - CLabel label = m_pWaveFile->m_LabelList[j]; - if(0!=QString::compare(label.m_szChannelName,szChannelName)) continue; - - int nLabelYPos=nMidLineY; - int nLabelXPos = m_pWaveFile->GetXPosition(label.m_lTime); - if(nLabelXPos== (-1)) return; - - int nLabelTick = int(.5+m_pWaveFile->GetTick(nLabelXPos)); - if(nLabelTick<0 || nLabelTick >= m_pWaveFile->GetTotalPointAmount()) return; - - CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; - double Value = 0.0; - Ana.GetTickValue(nTickPos,VAL_RAW/*m_pWaveFile->m_DispAttr.m_byValueType*/,Value); - - Value = m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch]*(Value); - Value = Value/100.0 * m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - - nLabelYPos += int(Value); - - QPoint pt(nLabelXPos,nLabelYPos); - PrintLabel(paint,rect,ptOffset,bColor,&label,pt ); - } - } - } - paint->setPen(oldPen); -} - -void CAnalogueShow::PrintLabel(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,CLabel* pLabel,QPoint ptChannel) -{ - Q_UNUSED(rect) - int nLeft = m_pWaveFile->GetPointPosition(pLabel->m_lLeftTick); - int nTop = m_pWaveFile->m_DispAttr.m_dWaveZoomY1*pLabel->m_dTopValue; - - QRect rc = QRect(QPoint(nLeft,nTop),pLabel->m_Size); - - QPen LabelPen(CWaveEnv::GetInst()->m_LabelFrameColor,1,Qt::SolidLine); - QPen LinePen(CWaveEnv::GetInst()->m_LabelConnectColor,1,Qt::DotLine); - QPen oldPen = paint->pen(); - QBrush oldBrh = paint->brush(); - QFont nameFont; - nameFont.setPixelSize(12); - paint->setFont(nameFont); - - if(bColor){ - paint->setPen(LabelPen); - paint->setBrush(CWaveEnv::GetInst()->m_LabelBackColor); - } - else{ - paint->setPen(Qt::NoPen); - paint->setBrush(Qt::NoBrush); - } - - Qt::BGMode oldMode = paint->backgroundMode(); - paint->setBackgroundMode(Qt::OpaqueMode); - - QPoint Mid; - if(ptChannel.y() > rc.top()) - Mid = QPoint((rc.left()+rc.right())/2,rc.bottom()); - else - Mid = QPoint((rc.left()+rc.right())/2,rc.top()); - paint->drawRect(QRect(rc.topLeft()+ptOffset,rc.bottomRight()+ptOffset)); - paint->setBackgroundMode(oldMode); - paint->drawText(QRect(rc.topLeft()+ptOffset,rc.bottomRight()+ptOffset),Qt::AlignHCenter |Qt::AlignVCenter | Qt::TextSingleLine,(pLabel->m_szText)); - paint->setPen(LinePen); - paint->drawLine(Mid+ptOffset,ptChannel+ptOffset); - - paint->setPen(oldPen); - paint->setBrush(oldBrh); - -} -//////////////////////////////////////////////////////////////////////// -//##ModelId=4039BEDE0118 -bool CAnalogueShow::SetComtradeData(CComtradeFile& pComtradeData) -{ - m_pWaveFile = &pComtradeData; - ResetVScrollSize(); - update(); - return true; -} - -CWaveShow* CAnalogueShow::GetParent() -{ - return (CWaveShow*)parent(); -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -void CAnalogueShow::VScroll(int value) -{ - m_nScrollTop = value; - update(); -} - -void CAnalogueShow::ResetVScrollSize() -{ - if(!m_pWaveFile) return; - - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - int nTop = 0; - int nBottom = 0; - for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) - continue; - - int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; - if(nWaveHeight<18) nWaveHeight=18; - nBottom += nWaveHeight; - } - int nh = rect().height(); - int nRange = nBottom - nh; - if(nRange < 0) - nRange = 0; - vert_bar->setRange(nTop,nRange); -} - -void CAnalogueShow::HScroll(int value) -{ - m_nScrollLeft = value; - update(); -} - -void CAnalogueShow::doMouseMove(QMouseEvent *e) -{ - if(e->x() < 0) return; - - m_nCursorX = e->x(); - - //显示值 - { - int nAbsXPos = m_nCursorX + m_nScrollLeft; - if(nAbsXPos < 0) nAbsXPos = 0; - if(nAbsXPos > m_pWaveFile->GetMaxWidth()) - nAbsXPos = m_pWaveFile->GetMaxWidth(); - - double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; - double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); - - m_pWaveFile->m_DispAttr.m_fCurrentTime = RTime; - m_pWaveFile->m_DispAttr.m_fCurrentTick = dTick; - } -} - -void CAnalogueShow::doMousePress(QMouseEvent *e) -{ - if(!m_pWaveFile) return; - - int nAbsXPos = e->x() + m_nScrollLeft; - if(nAbsXPos < 0) nAbsXPos = 0; - if(nAbsXPos > m_pWaveFile->GetMaxWidth()) - nAbsXPos = m_pWaveFile->GetMaxWidth(); - - double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; - double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); - // 始终保证第二时标>=第一时标 - if(e->button() == Qt::LeftButton) - { - m_pWaveFile->m_DispAttr.m_fStaticTime = RTime; - m_pWaveFile->m_DispAttr.m_fStaticTick = dTick; - m_pWaveFile->EmitLineCChanged(); - } - else if(e->button() == Qt::RightButton) - { - m_pWaveFile->m_DispAttr.m_fBaseTime = RTime; - m_pWaveFile->m_DispAttr.m_fBaseTick = dTick; - m_pWaveFile->EmitLineBChanged(); - } -} - -void CAnalogueShow::OnDelLabel() -{ - if(m_pWaveFile&&m_pSelectLabel) - { - for ( int i=0; i<(int)m_pWaveFile->m_LabelList.count(); i++ ) - { - CLabel& label = m_pWaveFile->m_LabelList[i]; - if(label.m_szChannelName.compare(m_pSelectLabel->m_szChannelName)==0 - &&label.m_szText.compare(m_pSelectLabel->m_szText)==0 - &&label.m_lTime==m_pSelectLabel->m_lTime) - { - m_pWaveFile->m_LabelList.removeAt(i); - m_pSelectLabel = 0; - update(); - break; - } - } - } - -} - -void CAnalogueShow::OnModLabel() -{ -/* - if(m_pWaveFile&&m_pSelectLabel) - { - CLabelSetDlg *dlg = new CLabelSetDlg( this ); - dlg->SetParam(m_pWaveFile,m_pSelectLabel); - if ( dlg->exec() == QDialog::Accepted ) { - - } - delete dlg; - } -*/ -} +#include "CAnalogueShow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CPublic.h" +#include "CWaveShow.h" +#include "CComDataClass.h" +//#include "clabelsetdlg.h" +#include "CPrintPreview.h" +///////////////////////////////////////////////////// +CAnalogueShow::CAnalogueShow(QWidget *parent, Qt::WindowFlags f ) + :QWidget(parent,f) +{ +//Scroll + setWindowFlag( Qt::WindowStaysOnTopHint ); + setMouseTracking(true); +// setAttribute(Qt::WA_PaintOutsidePaintEvent); + + QPalette p = palette(); + //p.setColor(backgroundRole(), QColor(255,255,255)); + p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_WaveBackColor); + // p.setColor(foregroundRole(), QColor(255,255,255)); + //p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_WaveForeColor); + setPalette(p); + setAutoFillBackground(true); + + QHBoxLayout* hboxLayout = new QHBoxLayout(this); + hboxLayout->setSpacing(0); + hboxLayout->setContentsMargins(0, 0, 0, 0); + + QSpacerItem* spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); + vert_bar = new QScrollBar(Qt::Vertical,this); + hboxLayout->addItem(spacerItem); + hboxLayout->addWidget( vert_bar ); + + vert_bar->setSingleStep(SCROLLBAR_V_LINE); + vert_bar->setPageStep(SCROLLBAR_V_LINE); + vert_bar->setTracking(false); + vert_bar->setMinimum(0); + vert_bar->setMaximum(10); + vert_bar->setCursor(GetParent()->m_hHandCursor); + connect(vert_bar,SIGNAL(valueChanged(int)),this,SLOT(VerticalScrollBarMove(int))); + connect(vert_bar,SIGNAL(sliderMoved(int)),this,SLOT(VerticalScrollBarMove(int))); + +//init + m_pWaveFile = 0; + m_pSelectLabel = 0L; + m_nCursorX = -1; + m_nCompPosY = -1; + m_nScrollTop = 0; + m_nScrollLeft = 0; + m_nWaveViewWidth = 0; + m_ValueFont = QFont("Arial",10); + + LLGrayPen = QPen(LLGRAY_COLOR,1,Qt::SolidLine); + LGrayPen = QPen(LGRAY_COLOR,1,Qt::SolidLine); + BluePen = QPen(BLUE_COLOR,1,Qt::SolidLine); + RedPen = QPen(RED_COLOR,1,Qt::SolidLine); + GrayPen = QPen(DGRAY_COLOR,1,Qt::SolidLine); + LCyanPen = QPen(LCYAN_COLOR,1,Qt::SolidLine); + WhitePen = QPen(WHITE_COLOR,1,Qt::SolidLine); + BlackPen = QPen(BLACK_COLOR,1,Qt::SolidLine); + + setCursor( GetParent()->m_hCrossCursor ); + +} + +CAnalogueShow::~CAnalogueShow() +{ + +} + +////////////////////////////////////////////////////////////////////////// +void CAnalogueShow::VerticalScrollBarMove(int value) +{ + setCursor(GetParent()->m_hHandCursor); + GetParent()->VAnaScroll(value); +} + +void CAnalogueShow::OnMousePressEvent( QMouseEvent *e ) +{ +// QDateTime tt = QDateTime::currentDateTime(); +// qDebug("开始时间是%d \n",tt.time().msec()); + + if(!GetParent()) + { + QWidget::mousePressEvent( e ); + return; + } + + if( 0==GetParent()->m_nZoomState || 1==GetParent()->m_nZoomState ) + { + if(e->button() == Qt::LeftButton ) + { + //选中波形 + GetParent()->HitTestWave( m_nScrollTop,e->pos().y() ); + + if( 0==GetParent()->m_nZoomState ) + GetParent()->OnAnaAreaIn(); + else if(1==GetParent()->m_nZoomState) + GetParent()->OnAnaAreaOut(); + } + else + { + GetParent()->SetZoomState( CWaveShow::SINGLEZOOM_NULL ); + } + QWidget::mousePressEvent( e ); + return; + } + + if(e->button() == Qt::LeftButton) + { + bool bMoveLabel = false; + if(m_pSelectLabel){ + m_pSelectLabel = 0L;bMoveLabel = true;} + else + m_pSelectLabel = m_pWaveFile->SelectLabel(QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop)); + + if(m_pSelectLabel||bMoveLabel) + { + update(); + QWidget::mousePressEvent( e ); + return; + } + } + doMousePress( e ); + +// update(); +// GetParent()->update(); + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(4,false); + GetParent()->redrawWindow(5,false); + GetParent()->redrawWindow(1,false);//在名称去显示数据值,20090818 + GetParent()->redrawWindow(7,false); + GetParent()->showStatus(); + +// if( GetParent()->m_pStatusView ) +// GetParent()->m_pStatusView->Refresh(); +// if(GetParent()->m_pLinStatusView) +// GetParent()->m_pLinStatusView->Refresh(); + + QWidget::mousePressEvent( e ); + +// QDateTime tt1 = QDateTime::currentDateTime(); +// qDebug("结束时间是%d \n",tt1.time().msec()); +// qDebug("时间差是%d \n",tt1.time().msec() - tt.time().msec()); +// QString stt = QString::number(tt.time().msec()) + "\n"; +// stt += QString::number(tt1.time().msec()); +} + +void CAnalogueShow::OnMouseReleaseEvent( QMouseEvent *e ) +{ + + QWidget::mouseReleaseEvent( e ); +} + +void CAnalogueShow::OnMouseMoveEvent( QMouseEvent *e ) +{ + setCursor(GetParent()->m_hCrossCursor); + if(GetParent()) + { + if( 0==GetParent()->m_nZoomState || 1==GetParent()->m_nZoomState ) + { + QWidget::mouseMoveEvent( e ); + return; + } + + if(m_pSelectLabel) + { + QPoint m_TopLeft = QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop); + m_pSelectLabel->m_lLeftTick = m_pWaveFile->GetTick(m_TopLeft.x()); + m_pSelectLabel->m_dTopValue = ((double)m_TopLeft.y())/m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + +// m_pSelectLabel->m_TopLeft = QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop); + update(); + } + + doMouseMove(e); +// +// CDigitalShow *pDgtView = GetParent()->m_pDigitalView; +// if(pDgtView) pDgtView->doMouseMove( e ); +// +// int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; +// QPoint pt(e->x() + nLeftMargin,e->y()); +// QMouseEvent event(QEvent::MouseMove,pt,e->button(),e->buttons(),e->modifiers()); +// +// CTimeAxisShow *pTimeView = GetParent()->m_pTimeAxisView; +// if(pTimeView) pTimeView->doMouseMove( &event ); + +// GetParent()->redrawWindow(4,false); +// GetParent()->redrawWindow(5,false); +// update(); + } + QWidget::mouseMoveEvent( e ); +} + +void CAnalogueShow::wheelEvent( QWheelEvent* e ) +{ + bool bVscroll = false; + bool bHscroll = false; + if(QApplication::keyboardModifiers() == Qt::ControlModifier) + { + bVscroll = true; + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 += AMP_RATE; + else if(e->delta() < 0) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 -=AMP_RATE; + + } + else if(QApplication::keyboardModifiers() == Qt::ShiftModifier) + { + bHscroll = true; + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; + else + m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; + } + else + { + bVscroll = true; + vert_bar->setValue( vert_bar->value() - e->delta()/10 ); + } + + if(bVscroll) + { + if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 > 20.0) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 20.0; + if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 < 0.5) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 0.5; + } + + if(bHscroll) + { + if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; + if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; + } + + if(bVscroll) + { + ResetVScrollSize(); + //GetParent()->m_pDigitalView->ResetVScrollSize(); + } + if(bHscroll) + GetParent()->m_pTimeAxisView->ResetHScrollSize(); + + if(bHscroll | bVscroll) + { + GetParent()->redrawWindow(1,false); + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(3,false); + GetParent()->redrawWindow(4,false); + GetParent()->redrawWindow(5,false); + } +} + +void CAnalogueShow::contextMenuEvent ( QContextMenuEvent *e ) +{ + Q_UNUSED(e) +// if(m_pSelectLabel) +// { +// QMenu* contextMenu = new QMenu( this ); +// Q_CHECK_PTR( contextMenu ); +// contextMenu->addAction( tr("删除标注"), this, SLOT(OnDelLabel())); +// contextMenu->addAction( tr("修改标注"), this, SLOT(OnModLabel())); +// contextMenu->exec( QCursor::pos() ); +// delete contextMenu; +// } +// else +// { +// //选中波形 +// GetParent()->HitTestWave( m_nScrollTop,e->pos().y() ); +// int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; +// if( Ch<0 || Ch>=MAX_WAVES) +// return; +// +// QMenu* contextMenu = new QMenu( this ); +// Q_CHECK_PTR( contextMenu ); +// +// contextMenu->addAction( tr("波形幅值放大"), GetParent(), SLOT(OnAnaAmpIn())); +// contextMenu->addAction( tr("波形幅值缩小"), GetParent(), SLOT(OnAnaAmpOut())); +// // contextMenu->addAction( tr("设置波形幅值..."), GetParent(), SLOT(OnAnaAmpSet())); +// contextMenu->addAction( tr("波形显示区放大"), GetParent(), SLOT(OnAnaAreaIn())); +// contextMenu->addAction( tr("波形显示区缩小"), GetParent(), SLOT(OnAnaAreaOut())); +// contextMenu->addSeparator(); +// contextMenu->addAction( tr("隐藏本通道"), GetParent(), SLOT(OnHideWaveChannel())); +// contextMenu->addAction( tr("恢复默认分组"), GetParent(), SLOT(OnResumeGroup())); +// contextMenu->addSeparator(); +// contextMenu->addAction( tr("颜色设置"), GetParent(), SLOT(OnAnaColorSet())); +// contextMenu->addAction( tr("线型设置"), GetParent(), SLOT(OnAnaLineSet())); +// contextMenu->addSeparator(); +// contextMenu->addAction( tr("设置基准线(B线)"), GetParent(), SLOT(OnSetZoneStart())); +// contextMenu->addAction( tr("取消基准线(B线)"), GetParent(), SLOT(OnCacelZone())); +// contextMenu->addSeparator(); +// contextMenu->addAction( tr("添加标注"), GetParent(), SLOT(OnAddLabel())); +// contextMenu->addAction( tr("标注列表"), GetParent(), SLOT(OnLabelList())); +// +// contextMenu->exec( QCursor::pos() ); +// delete contextMenu; +// } +// setCursor(GetParent()->m_hCrossCursor); +} + +void CAnalogueShow::paintEvent( QPaintEvent *e ) +{ + Q_UNUSED(e) + QPainter paint; + paint.begin( this ); + paint.setBrush( Qt::white);//palette().color( QPalette::Foreground )); + //paint.setPen( Qt::red); + draw( &paint ); + paint.end(); +} + +void CAnalogueShow::draw(QPainter *paint) +{ + if(!m_pWaveFile) return; + drawBackGnd(paint); +// drawChannelLine(paint); +// drawVertGridLine(paint); + drawWave(paint); + //QSize s = frameSize(); + if( CWaveEnv::GetInst()->m_bShowBaseLine ) + drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fBaseTick,CWaveEnv::GetInst()->m_BaseLineColor);//第一时标线 + + if(CWaveEnv::GetInst()->m_bShowTriggerLine) + drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fTriggerTick,RED_COLOR);//触发线 + + drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fStaticTick,CWaveEnv::GetInst()->m_StaticLineColor);//当前时标线 +// drawUpDownLineValue(paint,m_pWaveFile->m_DispAttr.m_fStaticTick); //当前时标值 + +// drawCursor(paint); + if( CWaveEnv::GetInst()->m_bShowCompLine ) + drawCompLine( paint ); + +} + +void CAnalogueShow::drawBackGnd(QPainter *paint) +{ + if(!m_pWaveFile) return; + +// int XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime); +// if(XPosition1 < 0 || XPosition1 > m_pWaveFile->GetMaxWidth()) +// XPosition1 = 0; +// XPosition1 -= m_nScrollLeft; +// +// int XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime); +// if(XPosition2 < 0 || XPosition2 > m_pWaveFile->GetMaxWidth()) +// XPosition2 = 0; +// XPosition2 -= m_nScrollLeft; + + QBrush oldBrush = paint->brush(); + QPen oldPen = paint->pen(); + + QRect ClientRect = rect(); + QRect rcDraw = ClientRect; + + //QSize s = frameSize(); + QSize s = size(); + //rcDraw.setLeft(XPosition1); + //rcDraw.setRight(XPosition2); + + rcDraw.setRight( s.width() - SPLITTERWIDTH ); + //rcDraw.setTop( CWaveEnv::GetInst()->m_nWaveViewTop1 ); + if(rcDraw.right() > rcDraw.left()) + { + //paint->setBrush(CWaveEnv::GetInst()->m_MiddleColor); + paint->setBrush(CWaveEnv::GetInst()->m_WaveBackColor); + paint->setPen(CWaveEnv::GetInst()->m_WaveBackColor); + paint->drawRect(rcDraw); + } + + paint->setPen(oldPen); + paint->setBrush(oldBrush); +} + +void CAnalogueShow::drawChannelLine(QPainter *paint) +{ + if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowGrid) return; + + QRect ClientRect = paint->viewport(); + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); + if(ClientRect.right() < ClientRect.left()) return; + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + QPen oldPen = paint->pen(); + paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); + int nTop = 0; + int i=0; + for( i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; + + int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; + int nYPos = nTop + nWaveHeight/2 - m_nScrollTop; + nTop += nWaveHeight; + + if(nYPos < ClientRect.top()) continue; + if(nYPos > ClientRect.bottom()) break; + + paint->drawLine(ClientRect.left(), nYPos, ClientRect.right(), nYPos); + + int nGrid = nWaveHeight/4; + if( nGrid <10 ) + continue; + nYPos -= nGrid; + paint->drawLine(ClientRect.left(), nYPos, ClientRect.right(), nYPos); + nYPos += nGrid*2; + paint->drawLine(ClientRect.left(), nYPos, ClientRect.right(), nYPos); + } + +/* + paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); + nTop = 0; + if(CWaveEnv::GetInst()->m_bShowGrid) + { + for(int i=0; iGetMaxWaveGroupNum()+1 && im_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; + + int nGridHeight = int(double(m_pWaveFile->m_DispAttr.m_dGridHeight) * dWaveZoomY1); + if(nGridHeight==0) nGridHeight=10; + + int nGrids = nWaveHeight/2/nGridHeight; + int nYPos = nTop + nWaveHeight/2 - m_nScrollTop; + nTop += nWaveHeight; + + for(int j=1; j<=nGrids; j++) + { + int nYPos2 = nYPos + j*nGridHeight; + paint->drawLine( ClientRect.left(), nYPos2, ClientRect.right(), nYPos2); + nYPos2 = nYPos - j*nGridHeight; + paint->drawLine( ClientRect.left(), nYPos2, ClientRect.right(), nYPos2); + } + } + }*/ + paint->setPen(oldPen); +} + +void CAnalogueShow::drawVertGridLine( QPainter *paint) +{ + if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowVertGrid) return; + + QRect ClientRect = paint->viewport(); + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); + if(ClientRect.right() < ClientRect.left()) return; + + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; +// int nHeight = 12; + + double fOneWidth = int(dGirdWidth*(fZoomX)+.5); + if(fOneWidth < dGirdWidth) + fOneWidth = dGirdWidth; + + QPen oldPen = paint->pen(); + paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); + for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) + { + int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); + int nBlockRight = m_pWaveFile->GetBlockRight(nBlk); + long lTimeBegin = m_pWaveFile->GetBlockBeginTime(nBlk); + long lTimeEnd = m_pWaveFile->GetBlockEndTime(nBlk); + + if((nBlockLeft-m_nScrollLeft) > ClientRect.width()) break; + + double dRate = m_pWaveFile->m_dSampleRate[nBlk]; + int nGridAmt = int(double(nBlockRight-nBlockLeft)/fOneWidth+.5)+1; + + int dGridArr[10] = {10,20,50, 200, 500, 1000, 2000, 5000, 10000,20000 }; + int nUnit = 0; + + int i = 0; + int nSelGridArr = dGridArr[0]; + for( i=nUnit; i<10; i++) + { + nSelGridArr = dGridArr[i]; + if(nSelGridArr*dRate/1000.0 >=10.0) + break; + } + + int nTick =0; + int nTime = lTimeBegin; + int nIntTime = 0; + for(nTick=0; nTick=lTimeBegin ) + { + int nIntTick = int(.5+(nIntTime-lTimeBegin) / (1000.0/dRate)); + int nIntPos = nBlockLeft + nIntTick*fOneWidth-m_nScrollLeft; + if( nIntPos > nBlockRight) break; + if(nIntPos > ClientRect.right() ) + break; + if( nIntPos < ClientRect.left() ) + continue; + paint->drawLine(nIntPos,0,nIntPos,ClientRect.bottom()); + } + } + } + } + + paint->setPen(oldPen); +} + +void CAnalogueShow::drawWave(QPainter *paint) +{ + if(!m_pWaveFile) return; + + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double fGridWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + int nOneWidth = 0; + if(fZoomX >= (1.0 - 1E-5)) nOneWidth = int(fGridWidth*fZoomX+.5); + else nOneWidth = int(.5+fGridWidth); + + QRect ClientRect = paint->viewport(); +// int nh = rect().height(); + + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); + if(ClientRect.right() < ClientRect.left()) return; + int nTop = 0; +// int nLeftWaveAxis = m_pWaveFile->m_DispAttr.m_nLeftWaveAxis; + + for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[i]*/ ) + continue; + + int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; +// double dMax = 0.01; +// double dChMax = 0.0; +// double dMin = -0.01; +// double dChMin = 0.0; + + if(nTop - m_nScrollTop>ClientRect.bottom()) break; + + int nMidLineY = nTop + nWaveHeight/2 - m_nScrollTop; + nTop += nWaveHeight; + if(nTop - m_nScrollTop + nWaveHeight<0) continue; + bool bShow = false; + for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i) continue; + if(m_pWaveFile->m_DispAttr.m_bWaveMarked[Ch]) continue; + bShow = true; + QPen oldPen = paint->pen(); + QPen WavePen; + // + //int nMidLineY = nTop + nWaveHeight/2 - m_nScrollTop; + PHASE_TYPE byPhType = m_pWaveFile->AnalogDataList[Ch].m_byPhaseType; + switch(byPhType) + { + case PHASE_A: + case PHASE_B: + case PHASE_C: + paint->setPen(QPen(m_pWaveFile->m_DispAttr.m_dwColorArray1[byPhType-1], + m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], + m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] + )); + break; + default: + paint->setPen(QPen(m_pWaveFile->m_DispAttr.m_DefaultWaveColor, + m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], + m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] + )); + break; + } + + //paint->setPen(WavePen); + + //dChMax = m_pWaveFile->AnalogDataList[Ch].GetMaxValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); + //dChMin = m_pWaveFile->AnalogDataList[Ch].GetMinValue(m_pWaveFile->m_DispAttr.m_byValueType,0.0); + + //dChMax = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMax); + //dChMin = m_pWaveFile->AnalogDataList[Ch].GetValueFromRaw(m_pWaveFile->m_DispAttr.m_byValueType,dChMin); + + //dMax = qMax(dMax, dChMax); + //dMin = qMin(dMin, dChMin); + + QPoint ptPrev; + int nTickPos = 0; + bool bFirst = false; + for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) + { + bool bAmplitude = false; + if(m_pWaveFile->m_dSampleRate[nBlk] < 100.1) bAmplitude = true; + + int nBlockRight = m_pWaveFile->GetBlockRight(nBlk); + if((nBlockRight-m_nScrollLeft) < 0) { nTickPos += m_pWaveFile->m_lSampleAmount[nBlk] ; continue; } + int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); + if((nBlockLeft-m_nScrollLeft) > ClientRect.width()) break; + + + for(int nTick=0; nTickm_lSampleAmount[nBlk]; nTick++) + { + int nXPos; + if(fZoomX >= (1.0 - 1E-5)) nXPos = nBlockLeft+nTick*nOneWidth; + else nXPos = nBlockLeft + int(double(nTick*nOneWidth)*fZoomX); + + + if((nXPos-m_nScrollLeft) < 0){ nTickPos++;continue;} + if((nXPos-m_nScrollLeft) > ClientRect.width()) break; + + CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; + double Value = 0.0; + Ana.GetTickValue(nTickPos,VAL_RAW/*m_pWaveFile->m_DispAttr.m_byValueType*/,Value); + //Ana.GetUpDowmValue(nTickPos,m_pWaveFile->m_DispAttr.m_byValueType,Value); + nTickPos++; + Value = m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch]*(Value); + Value = Value/90*m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + //Value = Value/dMax*m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch]*0.5*m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + if(bAmplitude) + { + QPoint pt(nXPos - m_nScrollLeft, nMidLineY-int(Value)); + + if(nTick == 0) + { + paint->drawLine(ptPrev,pt); + paint->drawLine(nXPos - m_nScrollLeft, nMidLineY-int(Value)-1, nXPos - m_nScrollLeft, nMidLineY+int(Value)+1); + } + else + { + paint->drawLine(nXPos - m_nScrollLeft, nMidLineY-int(Value)-1, nXPos - m_nScrollLeft, nMidLineY+int(Value)+1); + } + ptPrev = pt; + } + else + { + QPoint pt(nXPos - m_nScrollLeft, nMidLineY-int(Value)); + if(!bFirst) + { + ptPrev = pt; + bFirst = true; + } + else + { + paint->drawLine(ptPrev,pt); + ptPrev = pt; + } + } + } + } + + + if(!CWaveEnv::GetInst()->m_bShowLabel) continue; + paint->setPen(QPen(QColor(255,255,255/*CWaveEnv::GetInst()->m_LabelTextColor*/))); + QString szChannelName = m_pWaveFile->AnalogDataList[Ch].m_sName; + for(int j=0;j<(int)m_pWaveFile->m_LabelList.count();j++) + { + CLabel label = m_pWaveFile->m_LabelList[j]; + if(0!=QString::compare(label.m_szChannelName,szChannelName)) continue; + + int nLabelYPos=nMidLineY; + int nLabelXPos = m_pWaveFile->GetXPosition(label.m_lTime); + if(nLabelXPos== (-1)) return; + + int nLabelTick = int(.5+m_pWaveFile->GetTick(nLabelXPos)); + if(nLabelTick<0 || nLabelTick >= m_pWaveFile->GetTotalPointAmount()) return; + + CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; + double Value = 0.0; + Ana.GetTickValue(nTickPos,VAL_RAW/*m_pWaveFile->m_DispAttr.m_byValueType*/,Value); + + Value = m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch]*(Value); + Value = Value/100.0 * m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + nLabelYPos += int(Value); + nLabelXPos -= m_nScrollLeft; + + QPoint pt(nLabelXPos,nLabelYPos); + drawLabel(paint,&label,pt ); + } + paint->setPen(oldPen); + } + if(!bShow) + nTop -= nWaveHeight; + } +} +//画竖线 +void CAnalogueShow::drawUpDownLine(QPainter * paint, double fLineTick, const QColor& clr) +{ + if(!m_pWaveFile) return; + + int XPosition = m_pWaveFile->GetPointPosition(fLineTick); + if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) + XPosition = m_pWaveFile->GetMaxWidth(); + + XPosition -= m_nScrollLeft; + + QRect ClientRect = rect(); + if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) + { + LCyanPen.setColor(clr); + QPen oldPen = paint->pen(); + paint->setPen(LCyanPen); + + paint->drawLine(XPosition,0,XPosition,ClientRect.bottom()); + + paint->setPen(oldPen); + } +} +//画线值 +void CAnalogueShow::drawUpDownLineValue(QPainter * paint, double fLineTick) +{ + if(!m_pWaveFile) return; + + int nXPos = m_pWaveFile->GetPointPosition(fLineTick); + if(nXPos== (-1)) return; + + int nThisTick = fLineTick; + if(nThisTick<0 || nThisTick >= m_pWaveFile->GetTotalPointAmount()) return; + + nXPos -= m_nScrollLeft; + + QRect ClientRect = rect(); + if(nXPos < ClientRect.left() || nXPos > ClientRect.right()) + return; + + QFont oldFont = paint->font(); + paint->setFont(m_ValueFont); + QColor oldColor = CWaveEnv::GetInst()->m_WaveBackColor; + Qt::BGMode oldMode = paint->backgroundMode(); + paint->setBackgroundMode(Qt::TransparentMode); + QPen oldPen = paint->pen(); + //paint->setPen(QColor(255-oldColor.red(),255-oldColor.green(),255-oldColor.blue())); + paint->setPen(CWaveEnv::GetInst()->m_WaveForeColor); + + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + int nTop = 0; + for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; + + int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; + int nYPos = nTop + nWaveHeight/2 - 15 - m_nScrollTop; + nTop += nWaveHeight; + + if(nTop - m_nScrollTop<0) continue; + if(nTop - m_nScrollTop>ClientRect.bottom()) break; + + QString ValueString;; + ValueString = ""; +// bool bFind = false; + + for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i) continue; +// bFind = true; + + double Value; + CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; + char TempString[100]; +// int nWaveType = Ana.m_nWaveType; + if(Ana.GetUpDowmValue(nThisTick,m_pWaveFile->m_DispAttr.m_byValueType,Value)) + sprintf(TempString,"%8.2f",Value); + else sprintf(TempString,"*****"); + + if(ValueString.length()!=0) ValueString.append(","); + ValueString.append(TempString); + } + QRect Rect2(nXPos+5,nYPos,150,20); + paint->drawText(Rect2,Qt::AlignLeft | Qt::TextSingleLine,ValueString); + } + + paint->setPen(oldPen); + paint->setBackgroundMode(oldMode); + paint->setBackground(QBrush(oldColor)); + paint->setFont(oldFont); +} + +void CAnalogueShow::drawCursor(QPainter* paint) +{ + if(m_nCursorX > 0) + { + QRect rcRect = rect(); + QPen oldPen = paint->pen(); + //paint->setPen(BluePen); + paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); + paint->drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); + paint->setPen(oldPen); + } +} + +void CAnalogueShow::drawCompLine( QPainter* paint ) +{ + if(m_nCompPosY > 0) + { + QRect rcRect = rect(); + + QPainter::CompositionMode OldRop2 = paint->compositionMode(); + paint->setCompositionMode(QPainter::CompositionMode_Xor); + QPen oldPen = paint->pen(); + paint->setPen(BluePen); + + paint->drawLine(rcRect.left(), m_nCompPosY,rcRect.right(), m_nCompPosY); + + paint->setPen(oldPen); + paint->setCompositionMode(OldRop2); + } +} + +void CAnalogueShow::drawLabel(QPainter* paint,CLabel* pLabel,QPoint ptChannel) +{ + int nLeft = m_pWaveFile->GetPointPosition(pLabel->m_lLeftTick); + int nTop = m_pWaveFile->m_DispAttr.m_dWaveZoomY1*pLabel->m_dTopValue; + + QRect rc = QRect(QPoint(nLeft,nTop) - QPoint(m_nScrollLeft,m_nScrollTop),pLabel->m_Size); + + QPen LabelPen(CWaveEnv::GetInst()->m_LabelFrameColor,1,Qt::SolidLine); + QPen LinePen(CWaveEnv::GetInst()->m_LabelConnectColor,1,Qt::DotLine); + QPen oldPen = paint->pen(); + QBrush oldBrh = paint->brush(); + + paint->setPen(LabelPen); + paint->setBrush(CWaveEnv::GetInst()->m_LabelBackColor); + + Qt::BGMode oldMode = paint->backgroundMode(); + paint->setBackgroundMode(Qt::OpaqueMode); + + QPoint Mid; + if(ptChannel.y() > rc.top()) + Mid = QPoint((rc.left()+rc.right())/2,rc.bottom()); + else + Mid = QPoint((rc.left()+rc.right())/2,rc.top()); + paint->drawRect(rc); + paint->setBackgroundMode(oldMode); + paint->setPen(CWaveEnv::GetInst()->m_LabelTextColor); + paint->drawText(rc,Qt::AlignHCenter |Qt::AlignVCenter | Qt::TextSingleLine,(pLabel->m_szText)); + paint->setPen(LinePen); + paint->drawLine(Mid,ptChannel); + + paint->setPen(oldPen); + paint->setBrush(oldBrh); + +} + +void CAnalogueShow::GetWaveMargin(QRect &rect) +{ + if(!m_pWaveFile) return; +// double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + if(m_pWaveFile->m_nNRates<=0) + {rect = QRect(0,0,0,0);return;} + + int nLeft = m_pWaveFile->GetBlockLeft(0); + int nRight = m_pWaveFile->GetBlockRight(m_pWaveFile->m_nNRates-1); + + int nTop = 0; + int nBottom = 0; + for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; + + int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; + + bool bPrintGroup = false; + for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; + bPrintGroup = true; + } + if(!bPrintGroup) continue; + + nBottom += nWaveHeight; + } + + rect = QRect(nLeft,nTop,nRight - nLeft,nBottom - nTop); + +} + +void CAnalogueShow::Print(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor) +{ + if(!m_pWaveFile) return; + PrintChannelLine(paint,rect,ptOffset,bColor); + PrintWave(paint,rect,ptOffset,bColor); +} + +void CAnalogueShow::PrintChannelLine(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor) +{ + if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowGrid) return; + + QRect ClientRect = rect; + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth())); + if(ClientRect.right() < ClientRect.left()) return; + + QPen oldPen = paint->pen(); + if(bColor) paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); + else paint->setPen(QPen(Qt::lightGray,0,Qt::DotLine)); + + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + int nTop = 0; + for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; + + int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; + + bool bPrintGroup = false; + for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; + bPrintGroup = true; + } + if(!bPrintGroup) continue; + + int nYPos = nTop + nWaveHeight/2; + nTop += nWaveHeight; + + if(nYPos < ClientRect.top()||nYPos > ClientRect.bottom()) continue; + paint->drawLine(QPoint(ClientRect.left(), nYPos) + ptOffset, QPoint(ClientRect.right(), nYPos)+ptOffset); + } + paint->setPen(oldPen); +} + +void CAnalogueShow::PrintWave(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor) +{ + if(!m_pWaveFile) return; + + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double fGridWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + int nOneWidth = 0; + if(fZoomX >= (1.0 - 1E-5)) nOneWidth = int(fGridWidth*fZoomX+.5); + else nOneWidth = int(.5+fGridWidth); + + QRect ClientRect = rect; + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth())); + if(ClientRect.right() < ClientRect.left()) return; + + QPen oldPen = paint->pen(); + if(!bColor) + paint->setPen(BlackPen); + + int nTop = 0; + for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; + + int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; + + int nMidLineY = nTop + nWaveHeight/2; + + bool bPrintGroup = false; + for(int Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=i||!m_pWaveFile->m_DispAttr.m_bWavePrint[Ch]) continue; + + bPrintGroup = true; + + QPen WavePen(m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch], + m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch], + m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] + ); + + + if(bColor) paint->setPen(WavePen); + + int nTickPos = 0; + QPoint ptPrev; + for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) + { + bool bAmplitude = false; + if(m_pWaveFile->m_dSampleRate[nBlk] < 100.1) bAmplitude = true; + + int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); + bool bFirst = true; + for(int nTick=0; nTickm_lSampleAmount[nBlk]; nTick++) + { + int nXPos; + if(fZoomX >= (1.0 - 1E-5)) nXPos = nBlockLeft+nTick*nOneWidth; + else nXPos = nBlockLeft + int(double(nTick*nOneWidth)*fZoomX); + + nTickPos++; + if( nXPos > ClientRect.right() ) + break; + + if(nXPos < ClientRect.left()) + continue; + + CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; + + double Value = 0.0; + Ana.GetTickValue(nTickPos,VAL_RAW/*m_pWaveFile->m_DispAttr.m_byValueType*/,Value); + + + Value = m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch]*(Value); + Value = Value/100.0 * m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + + if(bAmplitude) + { + if(true)//幅值为竖线 + { + QPoint p1 = QPoint(nXPos, nMidLineY-int(Value)-1); + QPoint p2 = QPoint(nXPos, nMidLineY+int(Value)+1); + paint->drawLine(p1+ptOffset,p2+ptOffset); + } + else + { + paint->drawPoint( QPoint(nXPos, nMidLineY) + ptOffset ); + } + } + else + { + QPoint pt = QPoint(nXPos, nMidLineY-int(Value))+ptOffset; + if(bFirst) + { + ptPrev = pt; + bFirst=false; + } + else + { + paint->drawLine(ptPrev,pt); + ptPrev = pt; + } + } + } + } + + if(!bPrintGroup) continue; + + nTop += nWaveHeight; + + QString szChannelName = m_pWaveFile->AnalogDataList[Ch].m_sName; + for(int j=0;j<(int)m_pWaveFile->m_LabelList.count();j++) + { + CLabel label = m_pWaveFile->m_LabelList[j]; + if(0!=QString::compare(label.m_szChannelName,szChannelName)) continue; + + int nLabelYPos=nMidLineY; + int nLabelXPos = m_pWaveFile->GetXPosition(label.m_lTime); + if(nLabelXPos== (-1)) return; + + int nLabelTick = int(.5+m_pWaveFile->GetTick(nLabelXPos)); + if(nLabelTick<0 || nLabelTick >= m_pWaveFile->GetTotalPointAmount()) return; + + CAnalogData& Ana = m_pWaveFile->AnalogDataList[Ch]; + double Value = 0.0; + Ana.GetTickValue(nTickPos,VAL_RAW/*m_pWaveFile->m_DispAttr.m_byValueType*/,Value); + + Value = m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch]*(Value); + Value = Value/100.0 * m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + + nLabelYPos += int(Value); + + QPoint pt(nLabelXPos,nLabelYPos); + PrintLabel(paint,rect,ptOffset,bColor,&label,pt ); + } + } + } + paint->setPen(oldPen); +} + +void CAnalogueShow::PrintLabel(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,CLabel* pLabel,QPoint ptChannel) +{ + Q_UNUSED(rect) + int nLeft = m_pWaveFile->GetPointPosition(pLabel->m_lLeftTick); + int nTop = m_pWaveFile->m_DispAttr.m_dWaveZoomY1*pLabel->m_dTopValue; + + QRect rc = QRect(QPoint(nLeft,nTop),pLabel->m_Size); + + QPen LabelPen(CWaveEnv::GetInst()->m_LabelFrameColor,1,Qt::SolidLine); + QPen LinePen(CWaveEnv::GetInst()->m_LabelConnectColor,1,Qt::DotLine); + QPen oldPen = paint->pen(); + QBrush oldBrh = paint->brush(); + QFont nameFont; + nameFont.setPixelSize(12); + paint->setFont(nameFont); + + if(bColor){ + paint->setPen(LabelPen); + paint->setBrush(CWaveEnv::GetInst()->m_LabelBackColor); + } + else{ + paint->setPen(Qt::NoPen); + paint->setBrush(Qt::NoBrush); + } + + Qt::BGMode oldMode = paint->backgroundMode(); + paint->setBackgroundMode(Qt::OpaqueMode); + + QPoint Mid; + if(ptChannel.y() > rc.top()) + Mid = QPoint((rc.left()+rc.right())/2,rc.bottom()); + else + Mid = QPoint((rc.left()+rc.right())/2,rc.top()); + paint->drawRect(QRect(rc.topLeft()+ptOffset,rc.bottomRight()+ptOffset)); + paint->setBackgroundMode(oldMode); + paint->drawText(QRect(rc.topLeft()+ptOffset,rc.bottomRight()+ptOffset),Qt::AlignHCenter |Qt::AlignVCenter | Qt::TextSingleLine,(pLabel->m_szText)); + paint->setPen(LinePen); + paint->drawLine(Mid+ptOffset,ptChannel+ptOffset); + + paint->setPen(oldPen); + paint->setBrush(oldBrh); + +} +//////////////////////////////////////////////////////////////////////// +//##ModelId=4039BEDE0118 +bool CAnalogueShow::SetComtradeData(CComtradeFile& pComtradeData) +{ + m_pWaveFile = &pComtradeData; + ResetVScrollSize(); + update(); + return true; +} + +CWaveShow* CAnalogueShow::GetParent() +{ + return (CWaveShow*)parent(); +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +void CAnalogueShow::VScroll(int value) +{ + m_nScrollTop = value; + update(); +} + +void CAnalogueShow::ResetVScrollSize() +{ + if(!m_pWaveFile) return; + + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + int nTop = 0; + int nBottom = 0; + for(int i=0; iGetMaxWaveGroupNum()+1 && iIsWaveGroupEmpty( i ) || m_pWaveFile->m_DispAttr.m_bWaveMarked[i] ) + continue; + + int nWaveHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[i]*dWaveZoomY1; + if(nWaveHeight<18) nWaveHeight=18; + nBottom += nWaveHeight; + } + int nh = rect().height(); + int nRange = nBottom - nh; + if(nRange < 0) + nRange = 0; + vert_bar->setRange(nTop,nRange); +} + +void CAnalogueShow::HScroll(int value) +{ + m_nScrollLeft = value; + update(); +} + +void CAnalogueShow::doMouseMove(QMouseEvent *e) +{ + if(e->x() < 0) return; + + m_nCursorX = e->x(); + + //显示值 + { + int nAbsXPos = m_nCursorX + m_nScrollLeft; + if(nAbsXPos < 0) nAbsXPos = 0; + if(nAbsXPos > m_pWaveFile->GetMaxWidth()) + nAbsXPos = m_pWaveFile->GetMaxWidth(); + + double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; + double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); + + m_pWaveFile->m_DispAttr.m_fCurrentTime = RTime; + m_pWaveFile->m_DispAttr.m_fCurrentTick = dTick; + } +} + +void CAnalogueShow::doMousePress(QMouseEvent *e) +{ + if(!m_pWaveFile) return; + + int nAbsXPos = e->x() + m_nScrollLeft; + if(nAbsXPos < 0) nAbsXPos = 0; + if(nAbsXPos > m_pWaveFile->GetMaxWidth()) + nAbsXPos = m_pWaveFile->GetMaxWidth(); + + double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; + double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); + // 始终保证第二时标>=第一时标 + if(e->button() == Qt::LeftButton) + { + m_pWaveFile->m_DispAttr.m_fStaticTime = RTime; + m_pWaveFile->m_DispAttr.m_fStaticTick = dTick; + m_pWaveFile->EmitLineCChanged(); + } + else if(e->button() == Qt::RightButton) + { + m_pWaveFile->m_DispAttr.m_fBaseTime = RTime; + m_pWaveFile->m_DispAttr.m_fBaseTick = dTick; + m_pWaveFile->EmitLineBChanged(); + } +} + +void CAnalogueShow::OnDelLabel() +{ + if(m_pWaveFile&&m_pSelectLabel) + { + for ( int i=0; i<(int)m_pWaveFile->m_LabelList.count(); i++ ) + { + CLabel& label = m_pWaveFile->m_LabelList[i]; + if(label.m_szChannelName.compare(m_pSelectLabel->m_szChannelName)==0 + &&label.m_szText.compare(m_pSelectLabel->m_szText)==0 + &&label.m_lTime==m_pSelectLabel->m_lTime) + { + m_pWaveFile->m_LabelList.removeAt(i); + m_pSelectLabel = 0; + update(); + break; + } + } + } + +} + +void CAnalogueShow::OnModLabel() +{ +/* + if(m_pWaveFile&&m_pSelectLabel) + { + CLabelSetDlg *dlg = new CLabelSetDlg( this ); + dlg->SetParam(m_pWaveFile,m_pSelectLabel); + if ( dlg->exec() == QDialog::Accepted ) { + + } + delete dlg; + } +*/ +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogueShow.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogueShow.h index ca3a0568..0f20a1d5 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogueShow.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CAnalogueShow.h @@ -1,90 +1,90 @@ -#ifndef CANALOGUESHOW_H_HEADER_INCLUDED_BFC41131 -#define CANALOGUESHOW_H_HEADER_INCLUDED_BFC41131 - -#include - -#include -#include -#include -#include - -#include "CWaveGraph.h" -#include "CComDataClass.h" - -//class CWaveShow; - -//##ModelId=403405ED00B3 -class CAnalogueShow : public QWidget -{ - Q_OBJECT - -public: - CAnalogueShow(QWidget * parent = 0, Qt::WindowFlags f = 0); - ~CAnalogueShow(); -public: - QScrollBar *vert_bar; - - CComtradeFile* m_pWaveFile; - CLabel* m_pSelectLabel; -public: - QPen LLGrayPen; - QPen LGrayPen; - QPen BluePen; - QPen RedPen; - QPen GrayPen; - QPen LCyanPen; - QPen WhitePen; - QPen BlackPen; - - QFont m_ValueFont; - - int m_nCursorX; - int m_nCompPosY; - - int m_nScrollTop; - int m_nScrollLeft; - int m_nWaveViewWidth; -public: - //##ModelId=4039BEDE0118 - bool SetComtradeData(CComtradeFile& pComtradeData); - - CWaveShow* GetParent(); - void draw( QPainter *); - void drawWave(QPainter *); - void drawChannelLine(QPainter *); - void drawVertGridLine( QPainter *paint); - void drawBackGnd(QPainter *); - void drawUpDownLine(QPainter * ,double, const QColor&); - void drawUpDownLineValue(QPainter * ,double); - void drawCursor(QPainter*); - void drawCompLine( QPainter* paint ); - void drawLabel(QPainter* paint,CLabel* pLabel,QPoint ptChannel); -// - void Print(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor); - void PrintChannelLine(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor); - void PrintWave(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor); - void PrintLabel(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,CLabel* pLabel,QPoint ptChannel); - -// - void GetWaveMargin(QRect &rect); - - void ResetVScrollSize(); - void VScroll(int value); - void HScroll(int value); - -public slots: - void VerticalScrollBarMove(int value); - void doMousePress( QMouseEvent *e ); - void doMouseMove( QMouseEvent *e ); - void OnDelLabel(); - void OnModLabel(); - void OnMousePressEvent( QMouseEvent * ); - void OnMouseReleaseEvent( QMouseEvent * ); - void OnMouseMoveEvent( QMouseEvent * ); -protected: - void contextMenuEvent ( QContextMenuEvent * ); - void wheelEvent( QWheelEvent* e ); - void paintEvent( QPaintEvent *); -}; - -#endif /* CANALOGUESHOW_H_HEADER_INCLUDED_BFC41131 */ +#ifndef CANALOGUESHOW_H_HEADER_INCLUDED_BFC41131 +#define CANALOGUESHOW_H_HEADER_INCLUDED_BFC41131 + +#include + +#include +#include +#include +#include + +#include "CWaveGraph.h" +#include "CComDataClass.h" + +//class CWaveShow; + +//##ModelId=403405ED00B3 +class CAnalogueShow : public QWidget +{ + Q_OBJECT + +public: + CAnalogueShow(QWidget * parent = 0, Qt::WindowFlags f = 0); + ~CAnalogueShow(); +public: + QScrollBar *vert_bar; + + CComtradeFile* m_pWaveFile; + CLabel* m_pSelectLabel; +public: + QPen LLGrayPen; + QPen LGrayPen; + QPen BluePen; + QPen RedPen; + QPen GrayPen; + QPen LCyanPen; + QPen WhitePen; + QPen BlackPen; + + QFont m_ValueFont; + + int m_nCursorX; + int m_nCompPosY; + + int m_nScrollTop; + int m_nScrollLeft; + int m_nWaveViewWidth; +public: + //##ModelId=4039BEDE0118 + bool SetComtradeData(CComtradeFile& pComtradeData); + + CWaveShow* GetParent(); + void draw( QPainter *); + void drawWave(QPainter *); + void drawChannelLine(QPainter *); + void drawVertGridLine( QPainter *paint); + void drawBackGnd(QPainter *); + void drawUpDownLine(QPainter * ,double, const QColor&); + void drawUpDownLineValue(QPainter * ,double); + void drawCursor(QPainter*); + void drawCompLine( QPainter* paint ); + void drawLabel(QPainter* paint,CLabel* pLabel,QPoint ptChannel); +// + void Print(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor); + void PrintChannelLine(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor); + void PrintWave(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor); + void PrintLabel(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,CLabel* pLabel,QPoint ptChannel); + +// + void GetWaveMargin(QRect &rect); + + void ResetVScrollSize(); + void VScroll(int value); + void HScroll(int value); + +public slots: + void VerticalScrollBarMove(int value); + void doMousePress( QMouseEvent *e ); + void doMouseMove( QMouseEvent *e ); + void OnDelLabel(); + void OnModLabel(); + void OnMousePressEvent( QMouseEvent * ); + void OnMouseReleaseEvent( QMouseEvent * ); + void OnMouseMoveEvent( QMouseEvent * ); +protected: + void contextMenuEvent ( QContextMenuEvent * ); + void wheelEvent( QWheelEvent* e ); + void paintEvent( QPaintEvent *); +}; + +#endif /* CANALOGUESHOW_H_HEADER_INCLUDED_BFC41131 */ diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComDataClass.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComDataClass.h index 463dd0d7..edd3fe9f 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComDataClass.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComDataClass.h @@ -1,685 +1,685 @@ -#ifndef _COMMONDATA_H -#define _COMMONDATA_H - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "datastruct.h" - -//文件格式 -#define COMTRADE91_BINARY 1 -#define COMTRADE91_ASCII 2 -#define COMTRADE99_BINARY 3 -#define COMTRADE99_ASCII 4 - -// -#define MAX_BLOCKS 10000// 最大波形块数(容量) lww 20201207 100->10000 避免dat文件时间抖动引起block数量大增 -#define MAX_TAGS 2048// 最大开关量数(容量) -#define MAX_WAVES 2048// 最大波形量数(容量) - -//数值显示类型 -#define VAL_RAW 0 // 原始值 -#define VAL_PRIMARY 1 // 一次值 -#define VAL_SECONDARY 2 // 二次值 - -//开关量显示类型 -#define TAG_SHOWALL 0 //显示全部开关量 -#define TAG_SHOWACTION 1 //显示变化的开关量 -#define TAG_SHOWNONE 2 //不显示开关量 - -//颜色方案 -#define PATTERN_NUM 3 //颜色显示方案个数 -#define PATTERN_0 0 // 0 -#define PATTERN_1 1 // 1 -#define PATTERN_2 2 // 2 - -#define COLOR_NUM 9 -#define COLOR_NUM_ANA 3 -#define COLOR_NUM_DGT 3 -//工频 -const double FREQ_WORK = 50.0; -const long FREQ_SAMPLE = 12; - -const char LEFTTAG = '['; -const char RIGHTTAG = ']'; -const char DLINE = '_'; -const char EQU = '='; -const char SEPOR = ','; -const char CRLF = '\n'; - -enum PHASE_TYPE -{ - PHASE_NULL = 0, - PHASE_A = 1, - PHASE_B = 2, - PHASE_C = 3, - PHASE_0 = 4 -}; - -//## 采样数据集 -class CAnalogData -{ -public: - CAnalogData(); - ~CAnalogData(); - - CAnalogData &operator=( const CAnalogData & ); - void clone(CAnalogData& clone); - void CopyDataTo(CAnalogData& clone,int nBegin,int nEnd); - - //解除数据的引用关系 - void Detach(); - - void Check(); -public: - // CAnalogDataList *pParent; - QString GetName(){ return m_sName;}; - unsigned short UnitType(); - //波形信息值 - bool GetTickValue(int nTick,byte byValueType,double& dValue); - double GetValueFromRaw( byte byValueType,double dRawValue ); - double TransValueToRaw( byte byValueType,double dTypeValue ); - - double GetMaxValue(byte byValueType,double dValue); - double GetMinValue(byte byValueType,double dValue); - - //游标线值,2009-07-29 - double GetUpDowmValue(int nTick,byte byValueType,double& dValue); -public: - int m_nIndex; //模拟通道索引 - QString m_sName; //名称 - QString m_sPhase; //相位特征 - QString m_sCCBM; //被监视的回路元件 - QString m_sUnit; //单位 - QString m_sUnitRaw; //原始的单位 - double m_dMultiplier; //a - double m_dOffsetAdder; //b ax+b - double m_dSkew; //通道时滞 - int m_nMin; //最小 - int m_nMax; //最大 - double m_dPrimary; //一次变比系数 - double m_dSecondary; //二次变比系数 - byte m_byPS; //特征符(一次1或二次2) - QIntArray m_dlSampleData; //采样值 - QBitArray m_bSampleValid; //有效标记 - - PHASE_TYPE m_byPhaseType; - // - QVector m_aRealArray; //实部 - QVector m_aImagArray; //虚部 - QVector m_aAmpArray; //幅值 - QVector m_aAngArray; //相角 - QVector m_aBaseArray; //基波有效值 - QVector m_aTrueArray; //真值有效值 - bool m_bVectorValid; //true:已作矢量分析 - - // 频率分析值 - bool m_bFreqValid; //true:已作频率分析 - QVector m_aFreqArray; //频率分析的数据 - - // 平滑处理 - int m_nAverageTicks; - // 波形数据类型属性 - int m_nWaveType; -}; - -class CAnalogDataList :public QList -{ - public: - CAnalogDataList(){}; - bool DeleteItemByIndex(int nIndex); - bool FindItemByIndex(int nIndex ,CAnalogData& data); -}; - - -class CDigitData -{ -public: - CDigitData(); - ~CDigitData(); - CDigitData &operator=( const CDigitData & ); - - void clone(CDigitData& clone); - void CopyDataTo(CDigitData& clone,int nBegin,int nEnd); - //解除数据的引用关系 - void Detach(); - void Check(); -public: -// CDigitDataList *ptParent; - -public: - int m_nIndex; //索引 - QString m_sName; //name - QString m_sPhase; //相位特征 - QString m_sCCBM; //被监视的回路元件 - byte m_byNormalState; //状态 - QByteArray m_bySampleData; //值 - - bool m_bChanged; //有change -}; - -class CDigitDataList :public QList -{ - public: - CDigitDataList(){}; - bool DeleteItemByIndex(int nIndex); - bool FindItemByIndex(int nIndex ,CDigitData& data); -}; - - -class CInfEntry -{ -public: - CInfEntry(){} - ~CInfEntry(){} - -public: -// CEntryList *ptParent; - -public: - QString m_sName; - QString m_sValue; - QString m_sComment; - -}; - -class CEntryList :public QList -{ -}; - -class CInfSection -{ -public: - CInfSection(); - ~CInfSection(); - - public: - QString GetAttribute(const QString& sName, const QString& sDefault); - void SetAttribute(const QString& sName, const QString& sValue); - -public: - CEntryList EntryList; -public: - QString m_sCompany; - QString m_sName; - QString m_sComment; -}; - -class CSectionList :public QList -{ -}; - -class CSectionOperate -{ - public: - //return Index - static int GetSection( CSectionList& SectionList, const QString& sName, const QString& sCompany ); - //return Index - static int SetSection( CSectionList& SectionList, const QString& sName, const QString& sCompany ); - //return string - static QString GetAttribute(CSectionList& SectionList,const QString& sName, const QString& sDefault ); - static bool ReadFile(CSectionList& SectionList,const QString &sFileName); - static bool writeFile(CSectionList& SectionList,const QString &sFileName); -}; - -class CLabel -{ -public: - CLabel(); - ~CLabel(); - - -public: - QString m_szChannelName;//通道名 - QString m_szText; //内容 - long m_lTime; //时间点 - QString m_szStyle; //显示风格 - QString m_szFont; //字体 - bool m_bBold; //粗 - bool m_bItalic; //斜 - int m_nFontSize; //大小 - long m_lLeftTick; //最左边对应的采样点号 - double m_dTopValue; //最上边对应的值 - QSize m_Size; -}; - -class CLabelList :public QList -{ - -public: - bool OpenLabelFile(QString strPath,QString strFile); - bool SaveLabelFile(QString strPath,QString strFile); - -}; -//波形工具的环境 -class CWaveEnv -{ -public: - CWaveEnv(); - ~CWaveEnv(); - -public: - void Save(); - void Load(); - void Revert(); - void SaveZoomSet(); - void LoadZoomSet(); - - void SetEnvDir( const QString& ed ); - QString EnvDir(); - void ChangeColor(int nType);//两种,1-第一种,2-第二种 - - static CWaveEnv* GetInst(); - static CWaveEnv* GetDefault(); - -public: - QString m_sEnvDir; //执行目录 - - bool m_bShowWave; //是否显示模拟量区域 - bool m_bShowDigital; //是否显示数字量 - bool m_bShowTimeAxis; //是否显示时标区 - bool m_bShowLabel; //显示标注 - - bool m_bShowTriggerLine; //是否显示触发线 - bool m_bShowBaseLine; // 显示基线 - bool m_bShowGrid; // 显示格线,水平 - bool m_bShowVertGrid; // 显示格线,垂直 - bool m_bShowCompLine; // 显示比较线,水平 - - bool m_bBaseCompute; //是否执行基本计算 - bool m_bExtensive; //是否展开低频部分 - bool m_bAnalysisEnable; //显示波形分析功能 - bool m_bEndStamp; //读取文件时使用.波形文件配置文件中每段采样后的数字是序号(true),还是个数(false) - - int m_nLanguage; //语言类型 0-中文,1-俄文,2-英文 - int m_nDateSetOption; //时间设置,0-月/日/年,1-日/月/年 - bool m_bCruise; //漫游 - double m_fZoomXX; // 时标的比例,正常1.0 - double m_dWaveZoomYY; //通道变比 - double m_dTagsZoomYY; // - int m_nLeftMarginName; //左边名称区宽度 - int m_nTagsViewTop1; //开关量top - int m_nTagsViewHgt1; //开关量height - int m_nWaveViewTop1; //波形显示区top - int m_nWaveViewHgt1; //波形显示区height - int m_nTimeViewTop1; //时标top - int m_nTimeViewHgt1; //时标height - int m_nMinViewHgt1; //最小显示height - float m_fWaveHeightRate1; //显示区比例 - - int m_nBackColorType; //背景颜色类型,1,2, - QString m_sWaveFilePath; //保存最后打开的 - -//全局颜色 - QColor m_WaveBackColor; //波形状态区背景色 - QColor m_WaveForeColor; //波形状态区前景色(选择) - - QColor m_MiddleColor; //选择区域色 - - QColor m_TimeBackColor; //时间轴背景色 - QColor m_TimeForeColor; //时间轴前景色 - - QColor m_NameBackColor; //波形状态名称背景色 - QColor m_NameForeColor; //波形状态名称前景色 - - QColor m_statusBackColor; //时间轴背景色 - QColor m_statusForeColor; //时间轴背景色 - - QColor m_GridColor; //网格颜色 - QColor m_BaseLineColor; //基线颜色 - QColor m_StaticLineColor; //当前线颜色 - QColor m_MoveLineColor; //移动线颜色 - - QColor m_LabelBackColor; //标注背景 - QColor m_LabelTextColor; //标注文字 - QColor m_LabelFrameColor; //标注边框 - QColor m_LabelConnectColor;//标注连线 - - -private: - static CWaveEnv* m_pWaveEnvInstance; - static CWaveEnv* m_pWaveEnvDefault; -}; - -//波形显示属性 -class CWaveDisplay -{ -public: - CWaveDisplay(); - ~CWaveDisplay(); - void ResumeGroup(); - void ResumeCollocation(); - -public: -//需保存属性 - double m_dGridWidth; //采样点格宽度2.0 - double m_dGridHeight; //波形显示网格边长20.0 - double m_dTimeHeight; //时标区高度30 - double m_dTagsHeight; //开关量显示边界高度20.0 - double m_fZoomX; // 时标的比例,正常1.0 - double m_dWaveZoomY1; //通道变比 - double m_dTagsZoomY1; // - double m_dGridTime; //横格单位ms - byte m_byValueType; //原始值,一次,二次 - int m_nNameHeight; //通道名称高度20 - - QString m_strChannelName[MAX_WAVES]; // Wave channel name - QString m_strChPhaseName[MAX_WAVES]; // Wave channel phase - QString m_strChLineCompName[MAX_WAVES]; // Wave channel line component name - QString m_strChUnitName[MAX_WAVES]; // Wave channel unit name - QColor m_dwWaveColor[MAX_WAVES]; // 颜色 - Qt::PenStyle m_nWaveLineStyle[MAX_WAVES]; // 线型 - int m_nWaveLineWidth[MAX_WAVES]; // 线宽 - double m_dWaveHeight[MAX_WAVES]; // 波形显示边界高度初始60 - double m_fWaveZoom[MAX_WAVES]; // 放缩 - double m_fWaveZoomRevert[MAX_WAVES]; // 放缩备份 - int m_nWaveGroup[MAX_WAVES]; // 分组 - bool m_bWaveMarked[MAX_WAVES]; // 分组 - bool m_bWavePrint[MAX_WAVES]; // 打印 - - QString m_strTagName[MAX_TAGS]; - QColor m_dwTagsColor[MAX_TAGS]; // 颜色 - Qt::PenStyle m_nTagsLineStyle[MAX_TAGS]; // 线型 - int m_nTagsLineWidth[MAX_TAGS]; // 线宽 - int m_nTagsGroup[MAX_TAGS]; // 分组 - bool m_bTagsMarked[MAX_TAGS]; // 分组 - bool m_bTagsPrint[MAX_TAGS]; // 打印 - - int m_nLeftMargin; //左侧宽度 - int m_nLeftWaveAxis; //波形区标尺宽度 - - bool m_bShowZoon; // 是否显示选择区域 - - double m_fBaseTime; // 基准时标线 - double m_fBaseTick; // 基准点 - - double m_fTriggerTime; // 触发点 - double m_fTriggerTick; //触发点 - - double m_fStaticTime; // 当前时标 - double m_fStaticTick; //当前点 - - double m_fCurrentTime; // 移动时标 - double m_fCurrentTick; //移动点 - - int m_nSelAnalogueNo; //被选中的模拟通道号 - int m_nSelDigitalNo; //被选中的状态量通道号 - - static QColor m_dwColorArray[COLOR_NUM]; - static QColor m_dwColorArray1[COLOR_NUM_ANA]; - static QColor m_dwColorArray2[COLOR_NUM_DGT]; - - byte m_nTagShowType; //开关量 - QColor m_DefaultWaveColor; //波形颜色,非A,B,C三相 -}; - - -//录波器的配置信息 -class CLBQAnalog -{ -public: - CLBQAnalog(){}; - ~CLBQAnalog(){}; -public: - QString sDesc; - int nCh; - int nTypeId; -}; - -class CLBQBinary -{ -public: - CLBQBinary(){}; - ~CLBQBinary(){}; -public: - QString sDesc; - int nCh; - int nRelayAct; - int nRecd_cntr; -}; - -class CLBQParameter -{ -public: - CLBQParameter(){}; - ~CLBQParameter(){}; -public: - QString sDesc; - float fValue; - QString sUnit; -}; - -//关联信息 -class CLBQRelation -{ -public: - CLBQRelation(){}; - ~CLBQRelation(){}; -public: - int nBayNo; -}; - -//录波器的配置信息 -class CLBQComponent -{ -public: - CLBQComponent(){}; - ~CLBQComponent(){}; - -public: - QString sType; - QString sName; - int nBayNo; - - - QList m_AnaList; - QList m_BinList; - QList m_RelList; - QList m_ParamList; -}; - -class CLBQConfigFile -{ -public: - CLBQConfigFile(); - ~CLBQConfigFile(); - - //XML文件读写 - virtual void ReadXmlFile(const QString&); - virtual void WriteXmlFile(const QString&); - //XML文件读写 - //实现方法:将元素属性映射为属性值 - virtual void ReadXml(QDomElement* d); - //实现方法:将需要保存的数据设置为元素属性 - virtual void WriteXml(QDomElement* d); -public: - QString sType; - int nAnalog; - int nBinary; - int nSampleRate; - - QList m_CompList; - -}; - -class CComtradeFile: public QObject -{ - Q_OBJECT -public: - CComtradeFile(); - virtual ~CComtradeFile(); - CComtradeFile &operator=( const CComtradeFile & ); -public: -/************************************************************************/ -/* 原始信息 */ -/************************************************************************/ - QString m_sRevisionYear;//版本年号 - bool m_bAsciiDataFormat;//true-ASCII,false-bin - QString m_sHeadFileText; //头文件内容 - QString m_sStationName; //站名 - int m_nStationID; //ID - int m_nChannelTotal;//通道数 - int m_nAnagueNum; //模拟通道数 - int m_nDigitalNum; //状态通道数量 - double m_dLineFreq; //线路频率 - int m_nNRates; //采样率块数 - double dTimeMult; //时间比例,正常1.0 - - //{{for 连续可变采样周期 - bool m_bIsSeqSample; //是否为连续可变采样周期文件? - int m_nSampleNum; //连续可变采样周期采样点数 - //}} - //{{判断波形文件是否是新格式的 - bool m_bNewFile; //true:新格式的文件,false:老格式的文件 - bool m_bSeqFile; //true:ASCII类型的数据文件最后一行的序号与配置文件最后一段的序号是相同的,false:不相同 - bool m_bNotZeroFile; //true:数据文件第一行数据是从1开始的,false:数据文件第一行数据是从0开始的 - bool m_bASCFile; //true:配置文件每段最后的数字是增加的(是序号),false:不是增加的 - //}} - QDoubleArray m_dSampleRate; //每块以HZ为单位的采样率 - QLongArray m_lSampleAmount; //每块每通道数据点数 - QDateTime m_tFirstTime; //起始采样时间 - QDateTime m_tTriggerTime; //触发时间 - - QLLongArray m_aTimeArray; // 时间序列, 微秒数 - CSectionList m_SectionList; //信息文件内容 - CAnalogDataList AnalogDataList; //模拟通道 - CDigitDataList DigitDataList; //数字通道 - - CLBQConfigFile m_LBQConfig; //录波器配置文件 -/************************************************************************/ -/* 收集的信息 */ -/************************************************************************/ - CLabelList m_LabelList; //标注信息 - CWaveDisplay m_DispAttr; //显示属性 - - qint64 m_lFirstMicroSecs; // 绝对起始微秒数 - QLLongArray m_PointTimeArray; //计算得到绝对时间 - QDoubleArray m_aChMaximumArray; // 绝对Raw最大值 - - int m_nTrigger_ms; //触发点的毫秒数 - int m_nFrist_ms; //起点点的毫秒数 - -/////////////////////////////////////////////////////////////// -public: - QString m_sDirName; - QString m_sFileName; - QString m_strErrReadMsg; // 读文件错误信息 - int m_nReadLine; //记录出错行 -private: - // 文件名 - QString m_strHeadFilePath; // Head file name, *.HDR - QString m_strConfigFilePath; // Config file name, *.CFG - QString m_strDataFilePath; // Data file name, *.DAT - QString m_strInfoFilePath; // Information file name, *.inf - QString m_strLBQFilePath; //录波器配置文件 - QString m_strDispFilePath; // Display format file name, *.DSP - -signals: - - //B线改变 - void LineBChanged(); - //C线改变 - void LineCChanged(); - //波形文件读入结束 - void FileOpenOver(); -public: - void EmitLineBChanged(); - void EmitLineCChanged(); - void EmitFileOpenOver(); -public: - //初始序分量分析 - bool DoSubseq(); - void InitDisplyAttr(); - bool TransToContinus(); - void LoadDisplayOption(); - int GetMaxWaveGroupNum(); - int GetMaxTagsGroupNum(); - bool IsWaveGroupEmpty( int nGroup ); - bool IsTagGroupEmpty( int nGroup ); - int GetBlockRight(int nBlock) const; - int GetBlockLeft(int nBlock) const; - int GetMaxWidth() const; - double GetTick(int XPosition) const; - int GetStartTick( int nBlock ) const; - int GetXPosition(double fTime); - double GetXPositionTime(int xPos) const; - long GetBlockBeginTime(int nBlk) const; - long GetBlockEndTime(int nBlk) const; - long GetPointTime(int nTick) const; - int GetPointNoFromTime(long l_time) const; - int GetTotalPointAmount( ) const; - void GetFirstMicroSecs(); - qint64 GetPointRelTime(int nTick); - int GetPointPosition(int nTick); - int GetNumberOfWaveTags(); - //获取波形某块的起始和终止角度 - void CaculateChannelAngle( double* dWaveAngle,int len ); -////////////////////////////////////////////////// - CAnalogData* GetChannelByName(QString& szName ); - CDigitData* GetTagDataByName(QString& szName ); - CLabel* SelectLabel(QPoint pt); - void GetConfToString( QString& sConf ); - void GetCFGToString( QString& sCFG ); - void SetUnitType(int nType); - -////////////////////////////////////////////////// - static bool ReadChannelInf(CInfSection& pReadFileParam, CAnalogDataList& pAnalogList, CDigitDataList& pDigitList); - void SetInformation(const QString& strPath, const QString& strFileName ); - bool OpenWaveFile(CInfSection& pReadFileParam); - bool SaveWaveFile(CInfSection& pWriteFileParam); - bool OpenWaveFile(const QString& strPath, const QString& strFileName ); - bool SaveWaveFile(const QString& strPath, const QString& strFileName ); - bool CloseWaveFile(); -private: - bool ReadHeadFile(); - bool ReadConfFile(); - bool ReadDataFile(); - bool ReadInfFile(); - - - bool WriteHeadFile(); - bool WriteConfFile(); - bool WriteDataFile(); - bool WriteInfFile(); - - //{{for 连续可变采样周期 - bool ReadSeqDataFile(); - //}} -public: - //{{2009-2-4 zhn add for read real data长录波文件 - //读取CFG路径文件名 - //设置选中的波形,形成相应的配置信息 - void SetSelectRealConfFile(QList& listAnalog,QList& listDigit,float fSampleRate = 1200 ,int nSampleNum = 100); - bool ReadConfFile(const QString& strCfgPathFileName); - bool WriteConfFile(const QString& strCfgPathFileName); - bool ReadRealDataFile(); - //读取二进制文件的部分经过选择的文件 - bool ReadRealDataFile(const QString& strRealDataPathFileName,int& nTotalAnalogAmount,int& nTotalDigitalAmount,QList& listAnalog,QList& listDigital) ; - - //读取波形内存数据过选择的文件 - bool ReadRealDataFile(char* szData,int wLen,int& nTotalAnalogAmount,int& nTotalDigitalAmount,QList& listAnalog,QList& listDigital); - - //读取文件选择的文件 - bool ReadSelectionFile(const QString& strSelectionPathFileName,int& nTotalAnalogAmount,int& nTotalDigitalAmount,QList& listAnalog,QList& listDigital); - - //读取二进制文件 - bool ReadRealDataFile(const QString& strRealDataPathFileName); - bool OpenRealWaveFile(const QString& strRealWaveDataPathFileName,const QString& strRealWaveCfgPathFileName); - bool OpenRealWaveFile(const QString& strRealWaveDataPath,const QString& strRealWaveDataFileName,const QString& strRealWaveCfgPath,const QString& strRealWaveCfgDataFileName); - //}} -}; - -#endif - +#ifndef _COMMONDATA_H +#define _COMMONDATA_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "datastruct.h" + +//文件格式 +#define COMTRADE91_BINARY 1 +#define COMTRADE91_ASCII 2 +#define COMTRADE99_BINARY 3 +#define COMTRADE99_ASCII 4 + +// +#define MAX_BLOCKS 10000// 最大波形块数(容量) lww 20201207 100->10000 避免dat文件时间抖动引起block数量大增 +#define MAX_TAGS 2048// 最大开关量数(容量) +#define MAX_WAVES 2048// 最大波形量数(容量) + +//数值显示类型 +#define VAL_RAW 0 // 原始值 +#define VAL_PRIMARY 1 // 一次值 +#define VAL_SECONDARY 2 // 二次值 + +//开关量显示类型 +#define TAG_SHOWALL 0 //显示全部开关量 +#define TAG_SHOWACTION 1 //显示变化的开关量 +#define TAG_SHOWNONE 2 //不显示开关量 + +//颜色方案 +#define PATTERN_NUM 3 //颜色显示方案个数 +#define PATTERN_0 0 // 0 +#define PATTERN_1 1 // 1 +#define PATTERN_2 2 // 2 + +#define COLOR_NUM 9 +#define COLOR_NUM_ANA 3 +#define COLOR_NUM_DGT 3 +//工频 +const double FREQ_WORK = 50.0; +const long FREQ_SAMPLE = 12; + +const char LEFTTAG = '['; +const char RIGHTTAG = ']'; +const char DLINE = '_'; +const char EQU = '='; +const char SEPOR = ','; +const char CRLF = '\n'; + +enum PHASE_TYPE +{ + PHASE_NULL = 0, + PHASE_A = 1, + PHASE_B = 2, + PHASE_C = 3, + PHASE_0 = 4 +}; + +//## 采样数据集 +class CAnalogData +{ +public: + CAnalogData(); + ~CAnalogData(); + + CAnalogData &operator=( const CAnalogData & ); + void clone(CAnalogData& clone); + void CopyDataTo(CAnalogData& clone,int nBegin,int nEnd); + + //解除数据的引用关系 + void Detach(); + + void Check(); +public: + // CAnalogDataList *pParent; + QString GetName(){ return m_sName;}; + unsigned short UnitType(); + //波形信息值 + bool GetTickValue(int nTick,byte byValueType,double& dValue); + double GetValueFromRaw( byte byValueType,double dRawValue ); + double TransValueToRaw( byte byValueType,double dTypeValue ); + + double GetMaxValue(byte byValueType,double dValue); + double GetMinValue(byte byValueType,double dValue); + + //游标线值,2009-07-29 + double GetUpDowmValue(int nTick,byte byValueType,double& dValue); +public: + int m_nIndex; //模拟通道索引 + QString m_sName; //名称 + QString m_sPhase; //相位特征 + QString m_sCCBM; //被监视的回路元件 + QString m_sUnit; //单位 + QString m_sUnitRaw; //原始的单位 + double m_dMultiplier; //a + double m_dOffsetAdder; //b ax+b + double m_dSkew; //通道时滞 + int m_nMin; //最小 + int m_nMax; //最大 + double m_dPrimary; //一次变比系数 + double m_dSecondary; //二次变比系数 + byte m_byPS; //特征符(一次1或二次2) + QIntArray m_dlSampleData; //采样值 + QBitArray m_bSampleValid; //有效标记 + + PHASE_TYPE m_byPhaseType; + // + QVector m_aRealArray; //实部 + QVector m_aImagArray; //虚部 + QVector m_aAmpArray; //幅值 + QVector m_aAngArray; //相角 + QVector m_aBaseArray; //基波有效值 + QVector m_aTrueArray; //真值有效值 + bool m_bVectorValid; //true:已作矢量分析 + + // 频率分析值 + bool m_bFreqValid; //true:已作频率分析 + QVector m_aFreqArray; //频率分析的数据 + + // 平滑处理 + int m_nAverageTicks; + // 波形数据类型属性 + int m_nWaveType; +}; + +class CAnalogDataList :public QList +{ + public: + CAnalogDataList(){}; + bool DeleteItemByIndex(int nIndex); + bool FindItemByIndex(int nIndex ,CAnalogData& data); +}; + + +class CDigitData +{ +public: + CDigitData(); + ~CDigitData(); + CDigitData &operator=( const CDigitData & ); + + void clone(CDigitData& clone); + void CopyDataTo(CDigitData& clone,int nBegin,int nEnd); + //解除数据的引用关系 + void Detach(); + void Check(); +public: +// CDigitDataList *ptParent; + +public: + int m_nIndex; //索引 + QString m_sName; //name + QString m_sPhase; //相位特征 + QString m_sCCBM; //被监视的回路元件 + byte m_byNormalState; //状态 + QByteArray m_bySampleData; //值 + + bool m_bChanged; //有change +}; + +class CDigitDataList :public QList +{ + public: + CDigitDataList(){}; + bool DeleteItemByIndex(int nIndex); + bool FindItemByIndex(int nIndex ,CDigitData& data); +}; + + +class CInfEntry +{ +public: + CInfEntry(){} + ~CInfEntry(){} + +public: +// CEntryList *ptParent; + +public: + QString m_sName; + QString m_sValue; + QString m_sComment; + +}; + +class CEntryList :public QList +{ +}; + +class CInfSection +{ +public: + CInfSection(); + ~CInfSection(); + + public: + QString GetAttribute(const QString& sName, const QString& sDefault); + void SetAttribute(const QString& sName, const QString& sValue); + +public: + CEntryList EntryList; +public: + QString m_sCompany; + QString m_sName; + QString m_sComment; +}; + +class CSectionList :public QList +{ +}; + +class CSectionOperate +{ + public: + //return Index + static int GetSection( CSectionList& SectionList, const QString& sName, const QString& sCompany ); + //return Index + static int SetSection( CSectionList& SectionList, const QString& sName, const QString& sCompany ); + //return string + static QString GetAttribute(CSectionList& SectionList,const QString& sName, const QString& sDefault ); + static bool ReadFile(CSectionList& SectionList,const QString &sFileName); + static bool writeFile(CSectionList& SectionList,const QString &sFileName); +}; + +class CLabel +{ +public: + CLabel(); + ~CLabel(); + + +public: + QString m_szChannelName;//通道名 + QString m_szText; //内容 + long m_lTime; //时间点 + QString m_szStyle; //显示风格 + QString m_szFont; //字体 + bool m_bBold; //粗 + bool m_bItalic; //斜 + int m_nFontSize; //大小 + long m_lLeftTick; //最左边对应的采样点号 + double m_dTopValue; //最上边对应的值 + QSize m_Size; +}; + +class CLabelList :public QList +{ + +public: + bool OpenLabelFile(QString strPath,QString strFile); + bool SaveLabelFile(QString strPath,QString strFile); + +}; +//波形工具的环境 +class CWaveEnv +{ +public: + CWaveEnv(); + ~CWaveEnv(); + +public: + void Save(); + void Load(); + void Revert(); + void SaveZoomSet(); + void LoadZoomSet(); + + void SetEnvDir( const QString& ed ); + QString EnvDir(); + void ChangeColor(int nType);//两种,1-第一种,2-第二种 + + static CWaveEnv* GetInst(); + static CWaveEnv* GetDefault(); + +public: + QString m_sEnvDir; //执行目录 + + bool m_bShowWave; //是否显示模拟量区域 + bool m_bShowDigital; //是否显示数字量 + bool m_bShowTimeAxis; //是否显示时标区 + bool m_bShowLabel; //显示标注 + + bool m_bShowTriggerLine; //是否显示触发线 + bool m_bShowBaseLine; // 显示基线 + bool m_bShowGrid; // 显示格线,水平 + bool m_bShowVertGrid; // 显示格线,垂直 + bool m_bShowCompLine; // 显示比较线,水平 + + bool m_bBaseCompute; //是否执行基本计算 + bool m_bExtensive; //是否展开低频部分 + bool m_bAnalysisEnable; //显示波形分析功能 + bool m_bEndStamp; //读取文件时使用.波形文件配置文件中每段采样后的数字是序号(true),还是个数(false) + + int m_nLanguage; //语言类型 0-中文,1-俄文,2-英文 + int m_nDateSetOption; //时间设置,0-月/日/年,1-日/月/年 + bool m_bCruise; //漫游 + double m_fZoomXX; // 时标的比例,正常1.0 + double m_dWaveZoomYY; //通道变比 + double m_dTagsZoomYY; // + int m_nLeftMarginName; //左边名称区宽度 + int m_nTagsViewTop1; //开关量top + int m_nTagsViewHgt1; //开关量height + int m_nWaveViewTop1; //波形显示区top + int m_nWaveViewHgt1; //波形显示区height + int m_nTimeViewTop1; //时标top + int m_nTimeViewHgt1; //时标height + int m_nMinViewHgt1; //最小显示height + float m_fWaveHeightRate1; //显示区比例 + + int m_nBackColorType; //背景颜色类型,1,2, + QString m_sWaveFilePath; //保存最后打开的 + +//全局颜色 + QColor m_WaveBackColor; //波形状态区背景色 + QColor m_WaveForeColor; //波形状态区前景色(选择) + + QColor m_MiddleColor; //选择区域色 + + QColor m_TimeBackColor; //时间轴背景色 + QColor m_TimeForeColor; //时间轴前景色 + + QColor m_NameBackColor; //波形状态名称背景色 + QColor m_NameForeColor; //波形状态名称前景色 + + QColor m_statusBackColor; //时间轴背景色 + QColor m_statusForeColor; //时间轴背景色 + + QColor m_GridColor; //网格颜色 + QColor m_BaseLineColor; //基线颜色 + QColor m_StaticLineColor; //当前线颜色 + QColor m_MoveLineColor; //移动线颜色 + + QColor m_LabelBackColor; //标注背景 + QColor m_LabelTextColor; //标注文字 + QColor m_LabelFrameColor; //标注边框 + QColor m_LabelConnectColor;//标注连线 + + +private: + static CWaveEnv* m_pWaveEnvInstance; + static CWaveEnv* m_pWaveEnvDefault; +}; + +//波形显示属性 +class CWaveDisplay +{ +public: + CWaveDisplay(); + ~CWaveDisplay(); + void ResumeGroup(); + void ResumeCollocation(); + +public: +//需保存属性 + double m_dGridWidth; //采样点格宽度2.0 + double m_dGridHeight; //波形显示网格边长20.0 + double m_dTimeHeight; //时标区高度30 + double m_dTagsHeight; //开关量显示边界高度20.0 + double m_fZoomX; // 时标的比例,正常1.0 + double m_dWaveZoomY1; //通道变比 + double m_dTagsZoomY1; // + double m_dGridTime; //横格单位ms + byte m_byValueType; //原始值,一次,二次 + int m_nNameHeight; //通道名称高度20 + + QString m_strChannelName[MAX_WAVES]; // Wave channel name + QString m_strChPhaseName[MAX_WAVES]; // Wave channel phase + QString m_strChLineCompName[MAX_WAVES]; // Wave channel line component name + QString m_strChUnitName[MAX_WAVES]; // Wave channel unit name + QColor m_dwWaveColor[MAX_WAVES]; // 颜色 + Qt::PenStyle m_nWaveLineStyle[MAX_WAVES]; // 线型 + int m_nWaveLineWidth[MAX_WAVES]; // 线宽 + double m_dWaveHeight[MAX_WAVES]; // 波形显示边界高度初始60 + double m_fWaveZoom[MAX_WAVES]; // 放缩 + double m_fWaveZoomRevert[MAX_WAVES]; // 放缩备份 + int m_nWaveGroup[MAX_WAVES]; // 分组 + bool m_bWaveMarked[MAX_WAVES]; // 分组 + bool m_bWavePrint[MAX_WAVES]; // 打印 + + QString m_strTagName[MAX_TAGS]; + QColor m_dwTagsColor[MAX_TAGS]; // 颜色 + Qt::PenStyle m_nTagsLineStyle[MAX_TAGS]; // 线型 + int m_nTagsLineWidth[MAX_TAGS]; // 线宽 + int m_nTagsGroup[MAX_TAGS]; // 分组 + bool m_bTagsMarked[MAX_TAGS]; // 分组 + bool m_bTagsPrint[MAX_TAGS]; // 打印 + + int m_nLeftMargin; //左侧宽度 + int m_nLeftWaveAxis; //波形区标尺宽度 + + bool m_bShowZoon; // 是否显示选择区域 + + double m_fBaseTime; // 基准时标线 + double m_fBaseTick; // 基准点 + + double m_fTriggerTime; // 触发点 + double m_fTriggerTick; //触发点 + + double m_fStaticTime; // 当前时标 + double m_fStaticTick; //当前点 + + double m_fCurrentTime; // 移动时标 + double m_fCurrentTick; //移动点 + + int m_nSelAnalogueNo; //被选中的模拟通道号 + int m_nSelDigitalNo; //被选中的状态量通道号 + + static QColor m_dwColorArray[COLOR_NUM]; + static QColor m_dwColorArray1[COLOR_NUM_ANA]; + static QColor m_dwColorArray2[COLOR_NUM_DGT]; + + byte m_nTagShowType; //开关量 + QColor m_DefaultWaveColor; //波形颜色,非A,B,C三相 +}; + + +//录波器的配置信息 +class CLBQAnalog +{ +public: + CLBQAnalog(){}; + ~CLBQAnalog(){}; +public: + QString sDesc; + int nCh; + int nTypeId; +}; + +class CLBQBinary +{ +public: + CLBQBinary(){}; + ~CLBQBinary(){}; +public: + QString sDesc; + int nCh; + int nRelayAct; + int nRecd_cntr; +}; + +class CLBQParameter +{ +public: + CLBQParameter(){}; + ~CLBQParameter(){}; +public: + QString sDesc; + float fValue; + QString sUnit; +}; + +//关联信息 +class CLBQRelation +{ +public: + CLBQRelation(){}; + ~CLBQRelation(){}; +public: + int nBayNo; +}; + +//录波器的配置信息 +class CLBQComponent +{ +public: + CLBQComponent(){}; + ~CLBQComponent(){}; + +public: + QString sType; + QString sName; + int nBayNo; + + + QList m_AnaList; + QList m_BinList; + QList m_RelList; + QList m_ParamList; +}; + +class CLBQConfigFile +{ +public: + CLBQConfigFile(); + ~CLBQConfigFile(); + + //XML文件读写 + virtual void ReadXmlFile(const QString&); + virtual void WriteXmlFile(const QString&); + //XML文件读写 + //实现方法:将元素属性映射为属性值 + virtual void ReadXml(QDomElement* d); + //实现方法:将需要保存的数据设置为元素属性 + virtual void WriteXml(QDomElement* d); +public: + QString sType; + int nAnalog; + int nBinary; + int nSampleRate; + + QList m_CompList; + +}; + +class CComtradeFile: public QObject +{ + Q_OBJECT +public: + CComtradeFile(); + virtual ~CComtradeFile(); + CComtradeFile &operator=( const CComtradeFile & ); +public: +/************************************************************************/ +/* 原始信息 */ +/************************************************************************/ + QString m_sRevisionYear;//版本年号 + bool m_bAsciiDataFormat;//true-ASCII,false-bin + QString m_sHeadFileText; //头文件内容 + QString m_sStationName; //站名 + int m_nStationID; //ID + int m_nChannelTotal;//通道数 + int m_nAnagueNum; //模拟通道数 + int m_nDigitalNum; //状态通道数量 + double m_dLineFreq; //线路频率 + int m_nNRates; //采样率块数 + double dTimeMult; //时间比例,正常1.0 + + //{{for 连续可变采样周期 + bool m_bIsSeqSample; //是否为连续可变采样周期文件? + int m_nSampleNum; //连续可变采样周期采样点数 + //}} + //{{判断波形文件是否是新格式的 + bool m_bNewFile; //true:新格式的文件,false:老格式的文件 + bool m_bSeqFile; //true:ASCII类型的数据文件最后一行的序号与配置文件最后一段的序号是相同的,false:不相同 + bool m_bNotZeroFile; //true:数据文件第一行数据是从1开始的,false:数据文件第一行数据是从0开始的 + bool m_bASCFile; //true:配置文件每段最后的数字是增加的(是序号),false:不是增加的 + //}} + QDoubleArray m_dSampleRate; //每块以HZ为单位的采样率 + QLongArray m_lSampleAmount; //每块每通道数据点数 + QDateTime m_tFirstTime; //起始采样时间 + QDateTime m_tTriggerTime; //触发时间 + + QLLongArray m_aTimeArray; // 时间序列, 微秒数 + CSectionList m_SectionList; //信息文件内容 + CAnalogDataList AnalogDataList; //模拟通道 + CDigitDataList DigitDataList; //数字通道 + + CLBQConfigFile m_LBQConfig; //录波器配置文件 +/************************************************************************/ +/* 收集的信息 */ +/************************************************************************/ + CLabelList m_LabelList; //标注信息 + CWaveDisplay m_DispAttr; //显示属性 + + qint64 m_lFirstMicroSecs; // 绝对起始微秒数 + QLLongArray m_PointTimeArray; //计算得到绝对时间 + QDoubleArray m_aChMaximumArray; // 绝对Raw最大值 + + int m_nTrigger_ms; //触发点的毫秒数 + int m_nFrist_ms; //起点点的毫秒数 + +/////////////////////////////////////////////////////////////// +public: + QString m_sDirName; + QString m_sFileName; + QString m_strErrReadMsg; // 读文件错误信息 + int m_nReadLine; //记录出错行 +private: + // 文件名 + QString m_strHeadFilePath; // Head file name, *.HDR + QString m_strConfigFilePath; // Config file name, *.CFG + QString m_strDataFilePath; // Data file name, *.DAT + QString m_strInfoFilePath; // Information file name, *.inf + QString m_strLBQFilePath; //录波器配置文件 + QString m_strDispFilePath; // Display format file name, *.DSP + +signals: + + //B线改变 + void LineBChanged(); + //C线改变 + void LineCChanged(); + //波形文件读入结束 + void FileOpenOver(); +public: + void EmitLineBChanged(); + void EmitLineCChanged(); + void EmitFileOpenOver(); +public: + //初始序分量分析 + bool DoSubseq(); + void InitDisplyAttr(); + bool TransToContinus(); + void LoadDisplayOption(); + int GetMaxWaveGroupNum(); + int GetMaxTagsGroupNum(); + bool IsWaveGroupEmpty( int nGroup ); + bool IsTagGroupEmpty( int nGroup ); + int GetBlockRight(int nBlock) const; + int GetBlockLeft(int nBlock) const; + int GetMaxWidth() const; + double GetTick(int XPosition) const; + int GetStartTick( int nBlock ) const; + int GetXPosition(double fTime); + double GetXPositionTime(int xPos) const; + long GetBlockBeginTime(int nBlk) const; + long GetBlockEndTime(int nBlk) const; + long GetPointTime(int nTick) const; + int GetPointNoFromTime(long l_time) const; + int GetTotalPointAmount( ) const; + void GetFirstMicroSecs(); + qint64 GetPointRelTime(int nTick); + int GetPointPosition(int nTick); + int GetNumberOfWaveTags(); + //获取波形某块的起始和终止角度 + void CaculateChannelAngle( double* dWaveAngle,int len ); +////////////////////////////////////////////////// + CAnalogData* GetChannelByName(QString& szName ); + CDigitData* GetTagDataByName(QString& szName ); + CLabel* SelectLabel(QPoint pt); + void GetConfToString( QString& sConf ); + void GetCFGToString( QString& sCFG ); + void SetUnitType(int nType); + +////////////////////////////////////////////////// + static bool ReadChannelInf(CInfSection& pReadFileParam, CAnalogDataList& pAnalogList, CDigitDataList& pDigitList); + void SetInformation(const QString& strPath, const QString& strFileName ); + bool OpenWaveFile(CInfSection& pReadFileParam); + bool SaveWaveFile(CInfSection& pWriteFileParam); + bool OpenWaveFile(const QString& strPath, const QString& strFileName ); + bool SaveWaveFile(const QString& strPath, const QString& strFileName ); + bool CloseWaveFile(); +private: + bool ReadHeadFile(); + bool ReadConfFile(); + bool ReadDataFile(); + bool ReadInfFile(); + + + bool WriteHeadFile(); + bool WriteConfFile(); + bool WriteDataFile(); + bool WriteInfFile(); + + //{{for 连续可变采样周期 + bool ReadSeqDataFile(); + //}} +public: + //{{2009-2-4 zhn add for read real data长录波文件 + //读取CFG路径文件名 + //设置选中的波形,形成相应的配置信息 + void SetSelectRealConfFile(QList& listAnalog,QList& listDigit,float fSampleRate = 1200 ,int nSampleNum = 100); + bool ReadConfFile(const QString& strCfgPathFileName); + bool WriteConfFile(const QString& strCfgPathFileName); + bool ReadRealDataFile(); + //读取二进制文件的部分经过选择的文件 + bool ReadRealDataFile(const QString& strRealDataPathFileName,int& nTotalAnalogAmount,int& nTotalDigitalAmount,QList& listAnalog,QList& listDigital) ; + + //读取波形内存数据过选择的文件 + bool ReadRealDataFile(char* szData,int wLen,int& nTotalAnalogAmount,int& nTotalDigitalAmount,QList& listAnalog,QList& listDigital); + + //读取文件选择的文件 + bool ReadSelectionFile(const QString& strSelectionPathFileName,int& nTotalAnalogAmount,int& nTotalDigitalAmount,QList& listAnalog,QList& listDigital); + + //读取二进制文件 + bool ReadRealDataFile(const QString& strRealDataPathFileName); + bool OpenRealWaveFile(const QString& strRealWaveDataPathFileName,const QString& strRealWaveCfgPathFileName); + bool OpenRealWaveFile(const QString& strRealWaveDataPath,const QString& strRealWaveDataFileName,const QString& strRealWaveCfgPath,const QString& strRealWaveCfgDataFileName); + //}} +}; + +#endif + diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComtradeFile.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComtradeFile.cpp index cc383af8..71b77ced 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComtradeFile.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComtradeFile.cpp @@ -1,4712 +1,4712 @@ -#include "CComDataClass.h" -#include -#include -#include -#include -#include "CPublic.h" -#include -#include -#include -#include -#include -#include "wavedata.h" -#include "calgorithms.h" -#include "CommonFunction.h" -#include -#include -#include - -///////////////////////////////////////////////////// -//罗马数字检查 - -void RomanNumberCheck(QString &sTextLine) -{ - QString newstr; - char ch1,ch2; - for(int i=0;i-16&&ch2<-2)) - { - switch(ch2) - { - case -15: - newstr.append("I"); - break; - case -14: - newstr.append("II"); - break; - case -13: - newstr.append("III"); - break; - case -12: - newstr.append("IV"); - break; - case -11: - newstr.append("V"); - break; - case -10: - newstr.append("VI"); - break; - case -9: - newstr.append("VII"); - break; - case -8: - newstr.append("VII"); - break; - case -7: - newstr.append("VIII"); - break; - case -6: - newstr.append("IX"); - break; - case -5: - newstr.append("X"); - break; - case -4: - newstr.append("XI"); - break; - case -3: - newstr.append("XII"); - break; - default: - newstr.append("?"); - break; - - } - - } - else - { - newstr.append(ch1); - newstr.append(ch2); - } - } - else - { - newstr.append(ch1); - } - - - } - sTextLine = newstr; -} - -/////////////////////////////////////////// - -bool CAnalogDataList::FindItemByIndex(int nIndex ,CAnalogData& data) -{ - for(int i = 0 ;i< count();i++) - { - CAnalogData dataAna = at(i); - if (dataAna.m_nIndex == nIndex) - { - data = dataAna ; - return true; - } - } - return false; -} - -bool CAnalogDataList::DeleteItemByIndex(int nIndex) -{ - for(int i = 0 ;i< count();i++) - { - CAnalogData data = at(i); - if (data.m_nIndex == nIndex) - { - removeAt(i); - return true; - } - } - return false; -} - -bool CDigitDataList::FindItemByIndex(int nIndex ,CDigitData& data) -{ - for(int i = 0 ;i< count();i++) - { - CDigitData dataDgt = at(i); - if (dataDgt.m_nIndex == nIndex) - { - data = dataDgt ; - return true; - } - } - return false; -} - -bool CDigitDataList::DeleteItemByIndex(int nIndex) -{ - for(int i = 0 ;i< count();i++) - { - CDigitData data = at(i); - if (data.m_nIndex == nIndex) - { - removeAt(i); - return true; - } - } - return false; -} -///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -CLBQConfigFile::CLBQConfigFile() -{ -} - -CLBQConfigFile::~CLBQConfigFile() -{ -} - -#include -//XML文件读写 -void CLBQConfigFile::ReadXmlFile(const QString& sf) -{ - QFile file(sf); - if( !file.open(QIODevice::ReadOnly|QIODevice::Text) ) - { - return; - } - QTextStream ConfigFile( &file ); - autoSetTextStreamCodec( ConfigFile ); - - QString sCnt = ConfigFile.readAll(); - int n = sCnt.indexOf("xml"); - sCnt = sCnt.remove(0,n); - - sCnt = "firstChild(); !n.isNull(); n=n.nextSibling() ) - { - QDomElement elConfig = n.toElement(); - if( elConfig.isNull() ) - continue; - if( elConfig.tagName() == "Config" ) - { - sType = elConfig.attribute("type"); - nAnalog = elConfig.attribute("analog").toInt(); - nBinary = elConfig.attribute("binary").toInt(); - nSampleRate = elConfig.attribute("sample_rate").toInt(); - } - else if( elConfig.tagName() == "Component" ) - { - //{{ - CLBQComponent cmp; - - cmp.sType = elConfig.attribute("type"); - cmp.sName = elConfig.attribute("name"); - cmp.nBayNo = elConfig.attribute("bay_no").toInt(); - - - QDomElement elAnaList = elConfig.namedItem( "Analogs" ).toElement(); - if(!elAnaList.isNull() ) - { - for( QDomNode ana=elAnaList.firstChild(); !ana.isNull(); ana=ana.nextSibling() ) - { - QDomElement elAna = ana.toElement(); - if( elAna.isNull() ) - { - continue; - } - - CLBQAnalog ag; - - ag.sDesc = elAna.attribute("desc"); - ag.nCh = elAna.attribute("rec_chnl").toInt(); - ag.nTypeId = elAna.attribute("typeid").toInt(); - - cmp.m_AnaList.append(ag); - } - } - - QDomElement elBinList = elConfig.namedItem( "Binaries" ).toElement(); - if(!elBinList.isNull() ) - { - for( QDomNode bina=elBinList.firstChild(); !bina.isNull(); bina=bina.nextSibling() ) - { - QDomElement elBina = bina.toElement(); - if( elBina.isNull() ) - { - continue; - } - - CLBQBinary by; - - by.sDesc = elBina.attribute("desc"); - by.nCh = elBina.attribute("channel").toInt(); - by.nRelayAct = elBina.attribute("relay_act").toInt(); - by.nRecd_cntr = elBina.attribute("recd_cntr").toInt(); - - cmp.m_BinList.append(by); - } - } - - QDomElement elParaList = elConfig.namedItem( "Parameters" ).toElement(); - if(!elParaList.isNull() ) - { - for( QDomNode para=elParaList.firstChild(); !para.isNull(); para=para.nextSibling() ) - { - QDomElement elPara = para.toElement(); - if( elPara.isNull() ) - { - continue; - } - CLBQParameter pr; - - pr.sDesc = elPara.attribute("desc"); - pr.fValue = elPara.attribute("value").toFloat(); - pr.sUnit = elPara.attribute("unit"); - - cmp.m_ParamList.append(pr); - } - } - - QDomElement elRelList = elConfig.namedItem( "Relations" ).toElement(); - if(!elRelList.isNull() ) - { - for( QDomNode relt=elRelList.firstChild(); !relt.isNull(); relt=relt.nextSibling() ) - { - QDomElement elRelt = relt.toElement(); - if( elRelt.isNull() ) - { - continue; - } - CLBQRelation rt; - rt.nBayNo = elRelt.attribute("bay_no").toInt(); - cmp.m_RelList.append(rt); - } - } - - m_CompList.append(cmp); - //}} - } - } -} - -//实现方法:将需要保存的数据设置为元素属性 -void CLBQConfigFile::WriteXml(QDomElement* d) -{ - if(!d) - { - return; - } - QDomElement elConfig = d->ownerDocument().createElement( "Config" ); - if( !elConfig.isNull() ) - { - elConfig.setAttribute( "type", sType ); - elConfig.setAttribute( "analog", nAnalog ); - elConfig.setAttribute( "binary", nBinary ); - elConfig.setAttribute( "sample_rate", nSampleRate ); - d->appendChild( elConfig ); - } - if( m_CompList.count() < 1 ) - return; - for(int i = 0; i < m_CompList.count(); i++ ) - { - CLBQComponent& cmp = m_CompList[i]; - QDomElement elComponent = d->ownerDocument().createElement( "Component" ); - if( !elComponent.isNull() ) - { - d->appendChild( elComponent ); - - QDomElement elAnas = d->ownerDocument().createElement( "Analogs" ); - if( !elAnas.isNull() ) - { - elComponent.setAttribute( "type", cmp.sType ); - elComponent.setAttribute( "name", cmp.sName ); - elComponent.setAttribute( "bay_no", cmp.nBayNo ); - elComponent.appendChild( elAnas ); - for( int j = 0; j < cmp.m_AnaList.count(); j++) - { - CLBQAnalog& cAna = cmp.m_AnaList[j]; - QDomElement elAna = d->ownerDocument().createElement( "Analog" ); - if( !elAna.isNull() ) - { - elAna.setAttribute( "desc" , cAna.sDesc ); - elAna.setAttribute( "typeid" , cAna.nTypeId ); - elAna.setAttribute( "rec_chnl" , cAna.nCh ); - elAnas.appendChild( elAna ); - } - } - - } - QDomElement elBins = d->ownerDocument().createElement( "Binaries" ); - if( !elBins.isNull() ) - { - elComponent.appendChild( elBins ); - for( int k = 0; k < cmp.m_BinList.count(); k++) - { - CLBQBinary& cBin = cmp.m_BinList[k]; - QDomElement elBin = d->ownerDocument().createElement( "Binary" ); - if( !elBin.isNull() ) - { - elBin.setAttribute( "desc" , cBin.sDesc ); - elBin.setAttribute( "channel" , cBin.nCh ); - elBin.setAttribute( "relay_act" , cBin.nRelayAct ); - elBin.setAttribute( "recd_cntr" , cBin.nRecd_cntr ); - elBins.appendChild( elBin ); - } - } - } - QDomElement elRelas = d->ownerDocument().createElement( "Relations" ); - if( !elRelas.isNull() ) - { - elComponent.appendChild( elRelas ); - for(int l = 0; l < cmp.m_RelList.count(); l++ ) - { - CLBQRelation& cRela = cmp.m_RelList[l]; - QDomElement elRela = d->ownerDocument().createElement( "Relation" ); - if( !elRela.isNull() ) - { - elRela.setAttribute( "bay_no", cRela.nBayNo ); - elRelas.appendChild( elRela ); - } - } - } - QDomElement elParas = d->ownerDocument().createElement( "Parameters" ); - if( !elParas.isNull() ) - { - elComponent.appendChild( elParas ); - for( int m = 0 ; m < cmp.m_ParamList.count(); m++ ) - { - CLBQParameter& cPara = cmp.m_ParamList[m]; - QDomElement elPara = d->ownerDocument().createElement( "Parameter" ); - if( !elPara.isNull() ) - { - elPara.setAttribute( "desc" ,cPara.sDesc ); - elPara.setAttribute( "value" ,cPara.fValue ); - elPara.setAttribute( "unit" ,cPara.sUnit ); - elParas.appendChild( elPara ); - } - } - } - - } - } -/* - if(!d) - { - return; - } - - QDomElement elOsgList = d->ownerDocument().createElement( "OsgFileTable" ); - - if(!elOsgList.isNull() ) - { - d->appendChild(elOsgList); - - int i = 0; - quint16 sz = 0; - sz = m_sOsgFiles.count(); - for( i=0;iownerDocument().createElement( "OsgFile" ); - elOsg.setAttribute("OsgFile",m_sOsgFiles[i]); - - elOsgList.appendChild(elOsg); - } - } - - QDomElement elDataList = d->ownerDocument().createElement( "NodeDataTable" ); - if(!elDataList.isNull() ) - { - d->appendChild(elDataList); - - int i = 0; - quint16 sz = 0; - sz = m_NodeDatas.count(); - for( i=0;iHasNode()) - continue; - - QDomElement scEle = d->ownerDocument().createElement( nd->TagName() ); - elDataList.appendChild(scEle); - - nd->WriteXml( &scEle ); - } - }*/ -} - - -////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////// -CComtradeFile::CComtradeFile() -:QObject(),m_bIsSeqSample(false),m_nSampleNum(0) -{ - m_sHeadFileText = ""; - m_sStationName = ""; - m_nStationID = -1; - m_sRevisionYear = ""; - m_nChannelTotal = 0; - m_nAnagueNum = 0; - m_nDigitalNum = 0; - m_dLineFreq = 0.0; - m_nNRates = 0.0; - m_bAsciiDataFormat = true; - dTimeMult = 0.0; - m_sDirName = ""; - m_sFileName = ""; - m_strErrReadMsg = ""; - m_strHeadFilePath=""; - m_strConfigFilePath=""; - m_strDataFilePath=""; - m_strInfoFilePath=""; - m_strDispFilePath=""; - - m_bNewFile = false; - m_bSeqFile = false; - m_bNotZeroFile = false; - m_bASCFile = false; - - m_tFirstTime = QDateTime::currentDateTime(); - m_tTriggerTime = QDateTime::currentDateTime(); - - m_nTrigger_ms = 0; - m_nFrist_ms = -6000L; - - m_dSampleRate.resize(0); - m_lSampleAmount.resize(0); - m_SectionList.clear(); - AnalogDataList.clear(); - DigitDataList.clear(); - m_aTimeArray.resize(0); - m_aChMaximumArray.resize(0); - -} - -CComtradeFile::~CComtradeFile() -{ - -} - -CComtradeFile &CComtradeFile::operator=( const CComtradeFile &p ) -{ - AnalogDataList.clear(); - DigitDataList.clear(); - m_LabelList.clear(); - - m_sHeadFileText = p.m_sHeadFileText; //头文件内容 - m_sStationName = p.m_sStationName; //站名 - m_nStationID = p.m_nStationID; //ID - m_sRevisionYear = p.m_sRevisionYear; //版本年号 - - m_dLineFreq = p.m_dLineFreq; //线路频率 - m_nNRates = p.m_nNRates; //采样率块数 - m_dSampleRate = p.m_dSampleRate; //每块以HZ为单位的采样率 - m_lSampleAmount = p.m_lSampleAmount; //每块每通道数据点数 - m_tFirstTime = p.m_tFirstTime; //起始采样时间 - m_tTriggerTime = p.m_tTriggerTime; //触发时间 - m_bAsciiDataFormat = p.m_bAsciiDataFormat;//文件类型ASCII,BIN - dTimeMult = p.dTimeMult; //时间比例,正常1.0 - m_aTimeArray = p.m_aTimeArray; // 时间序列, 微秒数 - m_SectionList = p.m_SectionList; //信息文件内容 - - m_nTrigger_ms = p.m_nTrigger_ms; - m_nFrist_ms = p.m_nFrist_ms; - //{{for 连续可变采样周期 - m_bIsSeqSample = p.m_bIsSeqSample; - m_nSampleNum = p.m_nSampleNum; - //}} - - m_bNewFile = p.m_bNewFile; - m_bSeqFile = p.m_bSeqFile; - m_bNotZeroFile = p.m_bNotZeroFile; - m_bASCFile = p.m_bASCFile; - - int i; - - - for( i = 0;i= (1.0 - 1E-5)) - { - int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); - return(nTick*nOneWidth + nLeft); - } - else - { - int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); - return(int(double(nTick*nOneWidth)*m_DispAttr.m_fZoomX) + nLeft); - } - } - nTick -= m_lSampleAmount[nBlock]; - } - return 0; - -} -//******************************************************************** -// 取时标最大宽度, 不计左边界 -//******************************************************************** -int CComtradeFile::GetMaxWidth() const -{ - if(m_DispAttr.m_fZoomX >= (1.0 - 1E-5)) - { - int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); - return(GetTotalPointAmount()*nOneWidth); - } - else - { - int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); - return(int(double(GetTotalPointAmount()*nOneWidth)*m_DispAttr.m_fZoomX)); - } - return 0; -} -//******************************************************************** -// 取各块波形左边位置, 不计左边界 -//******************************************************************** -int CComtradeFile::GetBlockLeft(int nBlock) const -{ - int nAmt = 0; - for(int i=0; i= (1.0 - 1E-5)) - { - int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); - return(nAmt*nOneWidth); - } - else - { - int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); - return(int(double(nAmt*nOneWidth)*m_DispAttr.m_fZoomX)); - } - return 0; -} -//******************************************************************** -// 取各块波形右边界位置 -// -//******************************************************************** -int CComtradeFile::GetBlockRight(int nBlock) const -{ - if(nBlock<0) return -1; - - int nLeft = GetBlockLeft(nBlock); - int nAmt = m_lSampleAmount[nBlock]; - - if(m_DispAttr.m_fZoomX >= (1.0 - 1E-5)) - { - int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); - return(nAmt*nOneWidth + nLeft); - } - else - { - int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); - return(int(double(nAmt*nOneWidth)*m_DispAttr.m_fZoomX) + nLeft); - } - return 0; -} - -//******************************************************************** -// 根据X位置, 取Tick位置 -//******************************************************************** -double CComtradeFile::GetTick(int XPosition) const -{ - double fPointPos = 0.0; - for(int i=0; i= nBlockLeft && XPosition <= nBlockRight) - { - if(m_DispAttr.m_fZoomX >= (1.0 - 1E-5)) - { - int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+0.05); - fPointPos += double(XPosition-nBlockLeft)/double(nOneWidth); - } - else - { - int nOneWidth = int(0.05+m_DispAttr.m_dGridWidth); - fPointPos += double(XPosition-nBlockLeft)/m_DispAttr.m_fZoomX/double(nOneWidth); - } - return fPointPos; - } - fPointPos += double(m_lSampleAmount[i]); - } - return 0.0; -} - -int CComtradeFile::GetStartTick( int nBlock ) const -{ - int nAmt = 0; - for(int i=0; i= nBlockLeft && xPos <= nBlockRight) - { - long lTime = GetBlockBeginTime(i); - int nPointPos = 0; - - if(m_DispAttr.m_fZoomX >= (1.0 - 1E-5)) - { - int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); - nPointPos = (xPos-nBlockLeft)/nOneWidth; - } - else - { - int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); - nPointPos = int(.5+double(xPos-nBlockLeft)/m_DispAttr.m_fZoomX)/nOneWidth; - } - return (lTime + long(.5+double(nPointPos) * 1000.0 / m_dSampleRate[i])); - } - } - return 0; -} - -int CComtradeFile::GetXPosition(double fTime) -{ - for(int i=0; i= (1.0 - 1E-5)) - { - int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); - return(nBlockLeft + nTick*nOneWidth); - } - else - { - int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); - return(nBlockLeft + int(double(nTick*nOneWidth)*m_DispAttr.m_fZoomX)); - } - } - } - return 0; -} - - -void CComtradeFile::CaculateChannelAngle( double* dWaveAngle,int /*len*/ ) -{ - int nFirstIdx =0; - int nRate = 0; - for(int block=0; block FREQ_WORK ) - { - unsigned int nSampleNum = m_lSampleAmount[block]; - unsigned int nSampleRate = m_dSampleRate[block]; - - double* pWaveData = new double[nSampleNum]; - double* pRMSData = new double[nSampleNum]; - double* pAngleData = new double[nSampleNum]; - - memset(pWaveData, 0, nSampleNum*sizeof(double)); - memset(pRMSData, 0, nSampleNum*sizeof(double)); - memset(pAngleData, 0, nSampleNum*sizeof(double)); - - int ch =0; - for( ch=0; chm_bShowLabel) return 0L; - - int nLeft,nTop; - for ( int i=0; i0) m_sFileName = sName.left(nPos); - nPos = sName.indexOf(".CFG"); - if(nPos>0) m_sFileName = sName.left(nPos); - nPos = sName.indexOf(".HDR"); - if(nPos>0) m_sFileName = sName.left(nPos); - nPos = sName.indexOf(".INF"); - if(nPos>0) m_sFileName = sName.left(nPos); - - // COMTRADE头文件名 - // - m_strHeadFilePath = m_sDirName; - m_strHeadFilePath += m_sFileName; - m_strHeadFilePath.append( ".HDR" ); - // COMTRADE配置文件名 - // - m_strConfigFilePath = m_sDirName; - m_strConfigFilePath += m_sFileName; - m_strConfigFilePath.append( ".CFG" ); - // COMTRADE数据文件名 - // - m_strDataFilePath = m_sDirName; - m_strDataFilePath += m_sFileName; - m_strDataFilePath.append( ".DAT" ); - // COMTRADE信息文件名 - // - m_strInfoFilePath = m_sDirName; - m_strInfoFilePath += m_sFileName; - m_strInfoFilePath.append( ".INF" ); -} - -bool CComtradeFile::OpenWaveFile(CInfSection& pReadFileParam) -{ - QString sDirName = ""; - QString sFileName = ""; - QString strFileType = ""; - - CEntryList::iterator ite; - for ( ite = pReadFileParam.EntryList.begin(); ite != pReadFileParam.EntryList.end(); ++ite ) - { - QString szName = (*ite).m_sName; - if(szName.compare("path")==0) - sDirName = (*ite).m_sValue; - if(szName.compare("filename")==0) - sFileName = (*ite).m_sValue; - if(szName.compare("filetype")==0) - strFileType = (*ite).m_sValue; - } - - if(sFileName.isEmpty()||sDirName.isEmpty()) - { - m_strErrReadMsg = tr("The Filename is Error!");//空文件名错! - return false; - } - - return OpenWaveFile(sDirName,sFileName); - -} - -bool CComtradeFile::SaveWaveFile(CInfSection& pWriteFileParam) -{ - QString sDirName = ""; - QString sFileName = ""; - QString strFileType = ""; - - CEntryList::iterator ite; - for ( ite = pWriteFileParam.EntryList.begin(); ite != pWriteFileParam.EntryList.end(); ++ite ) - { - QString szName = (*ite).m_sName; - if(szName.compare("path")==0) - sDirName = (*ite).m_sValue; - if(szName.compare("filename")==0) - sFileName = (*ite).m_sValue; - if(szName.compare("filetype")==0) - strFileType = (*ite).m_sValue; - } - - if(strFileType.compare("ASCII")==0||strFileType.compare("COMTRADE91-ASCII")==0||strFileType.compare("COMTRADE99-ASCII")==0) - { - if(strFileType.compare("COMTRADE99-ASCII")==0) - m_sRevisionYear = "1999"; - else - m_sRevisionYear = ""; - - m_bAsciiDataFormat = true; - } - else if(strFileType.compare("BINARY")==0||strFileType.compare("COMTRADE91-BINARY")==0||strFileType.compare("COMTRADE99-BINARY")==0) - { - if(strFileType.compare("COMTRADE99-BINARY")==0) - m_sRevisionYear = "1999"; - else - m_sRevisionYear = ""; - - m_bAsciiDataFormat = false; - } - else - return false; - - - - if(sFileName.isEmpty()||sDirName.isEmpty()) - { - m_strErrReadMsg = tr("The Filename is Error!");//空文件名错! - return false; - } - - return SaveWaveFile(sDirName,sFileName); - -} -bool CComtradeFile::OpenWaveFile(const QString& strPath, const QString& strFileName ) -{ - CloseWaveFile(); - // Skip tail ".DAT", ".HDR" or ".CFG" - m_sFileName.clear(); - int len = strFileName.length(); - if (strFileName.endsWith(".DAT", Qt::CaseInsensitive)){ - m_sFileName = strFileName.left (len-4); - } - if (m_sFileName.isEmpty() && strFileName.endsWith(".CFG", Qt::CaseInsensitive)){ - m_sFileName = strFileName.left (len-4); - } - if (m_sFileName.isEmpty() && strFileName.endsWith(".HDR", Qt::CaseInsensitive)){ - m_sFileName = strFileName.left (len-4); - } - if (m_sFileName.isEmpty() && strFileName.endsWith(".INF", Qt::CaseInsensitive)){ - m_sFileName = strFileName.left (len-4); - } - if (m_sFileName.isEmpty() && strFileName.endsWith(".AUX", Qt::CaseInsensitive)){ - m_sFileName = strFileName.left (len-4); - } - if (m_sFileName.isEmpty()) - m_sFileName = strFileName; - m_strErrReadMsg = ""; - if(m_sFileName.isEmpty()) - { - m_strErrReadMsg = tr("The Filename is Error!");//空文件名错! - return false; - } - QDir directory(strPath); - if (!directory.exists()){ - m_strErrReadMsg = QString("%1(%2)").arg(tr("The Path is Error!")).arg(strPath); - return false; - } - m_strHeadFilePath.clear(); - m_strConfigFilePath.clear(); - m_strDataFilePath.clear(); - m_strInfoFilePath.clear(); - m_strLBQFilePath.clear(); - QFileInfoList waveFiles = directory.entryInfoList(); - int cnt = waveFiles.count(); - int validFileCnt = 0; - for (int i = 0; i < cnt; ++i) - { - QString fileName = waveFiles[i].fileName(); - QString sFileNameWithNoSuffix = fileName.left(fileName.count()-4); - if ( waveFiles[i].isFile() && sFileNameWithNoSuffix.toLower()==m_sFileName.toLower() ) - { - validFileCnt++; - if (fileName.endsWith(".HDR", Qt::CaseInsensitive)) - m_strHeadFilePath = waveFiles[i].absoluteFilePath(); - else if (fileName.endsWith(".CFG", Qt::CaseInsensitive)) - m_strConfigFilePath = waveFiles[i].absoluteFilePath(); - else if (fileName.endsWith(".DAT", Qt::CaseInsensitive)) - m_strDataFilePath = waveFiles[i].absoluteFilePath(); - else if (fileName.endsWith(".INF", Qt::CaseInsensitive)) - m_strInfoFilePath = waveFiles[i].absoluteFilePath(); - else if (fileName.endsWith(".AUX", Qt::CaseInsensitive)) - m_strLBQFilePath = waveFiles[i].absoluteFilePath(); - else - validFileCnt--; - } - if (validFileCnt == 5) - break; - } - - m_sDirName = strPath; - - //QString sTextLine; - //QString sSubString; - - // COMTRADE头文件名 - // - // 读头文件 - // -#ifndef ENGLISH_WAVETOOLS - //{{hujf del for english - ReadHeadFile(); - //}} -#endif - - // COMTRADE配置文件名 - // - - //读配置文件 - // - if( !ReadConfFile() ) - { - CloseWaveFile(); - return false; - } - - // 打开数据文件 - //{{for 连续可变采样周期 - bool bRet = true; - if( m_bIsSeqSample ) - bRet = ReadSeqDataFile(); - else - bRet = ReadDataFile(); - //}} - if( !bRet ) - { - CloseWaveFile(); - return false; - } - - // COMTRADE信息文件名 - // - - if( CWaveEnv::GetInst()->m_bExtensive ) - TransToContinus(); - - //录波器配置文件 - - m_LBQConfig.ReadXmlFile( m_strLBQFilePath ); - //属性 - InitDisplyAttr(); - - return true; -} - -bool CComtradeFile::TransToContinus() -{ - int i=0,j=0,k=0,ch=0,nStep=0;//nTick=0, - int nStartTick=0,nAng=0,nValue=0; - double nBeginAng=0.0,nEndAng=0.0; - unsigned char btValue=0; - qint64 nBeTm=0,nEdTm=0; - - int bufflen = m_nNRates*m_nAnagueNum*2+10; - double* dWaveAngle = new double[bufflen]; - memset(dWaveAngle,0.0,sizeof(double)*bufflen); - CaculateChannelAngle( dWaveAngle,bufflen); - - double nRate = 1200.0; - int nSampleNum=0; - for( i=0; i0 ) - nBeTm = m_aTimeArray[nStartTick]; - - int nEndTick = nStartTick+nSampleNum; - if(nEndTick >=m_aTimeArray.size() ) - nEndTick = m_aTimeArray.size()-1; - - nEdTm = m_aTimeArray[nEndTick]; - int nNum = ( nEdTm - nBeTm )*FREQ_SAMPLE*FREQ_WORK/(1000.0*1000.0); - if( i>= m_nNRates -1 ) - nNum++; - - m_lSampleAmount[i] = nNum; - m_dSampleRate[i] = FREQ_SAMPLE*FREQ_WORK; - - //2.各个点的时间 - QLLongArray timeadd; - timeadd.resize(nNum); - //第一段 - for( j=0;j=1&&iFREQ_WORK) - bDiff = true; - - for(ch=0; ch=1) - nBeginAng = dWaveAngle[(i-1)*m_nAnagueNum*2+ch*2+1]; - if( bDiff ) - { - nEndAng = dWaveAngle[(i+1)*m_nAnagueNum*2+ch*2]; - nDelta = (nEndAng - nBeginAng+360.0)/(double)nSampleNum; - } - - nStep = 0; - CAnalogData& anai = AnalogDataList[ch]; - for( k=0;k FREQ_WORK ) - { - if( bAllDP ) - bAllDP = false; - - for( nTicks=0; nTicks0 ) - { - double dMinRule = Ana.TransValueToRaw( m_DispAttr.m_byValueType,MIN_RULER ); - if( dMax < dMinRule ) - dMax = dMinRule; - } - - m_aChMaximumArray[i] = dMax;//CPublic::GetIntergerMax(dMax); - - m_DispAttr.m_strChannelName[i] = Ana.m_sName; - m_DispAttr.m_strChPhaseName[i] = Ana.m_sPhase; - m_DispAttr.m_strChLineCompName[i] = Ana.m_sCCBM; - m_DispAttr.m_strChUnitName[i] = Ana.m_sUnit; - } - - for( i=0; i= 0 || - AnalogDataList[i].m_sUnit.toLower().indexOf("v") >= 0 ) - { - dTempMaxU = qMax(dTempMaxU,m_aChMaximumArray[i]); - } - else if(AnalogDataList[i].m_sUnit.toLower().indexOf("a") >= 0 ) - { - dTempMaxI = qMax(dTempMaxI,m_aChMaximumArray[i]); - } - } - for(i = 0;i= 0 || - AnalogDataList[i].m_sUnit.toLower().indexOf("v") >= 0 ) - { - m_aChMaximumArray[i] = dTempMaxU; - } - else if(AnalogDataList[i].m_sUnit.toLower().indexOf("a") >= 0 ) - { - m_aChMaximumArray[i] = dTempMaxI; - } - } - - for( i=0; i1E-5) - { - m_DispAttr.m_fWaveZoom[i] = double(m_DispAttr.m_dWaveHeight[i])*45.0 - /double(m_aChMaximumArray[i]); - m_DispAttr.m_fWaveZoomRevert[i] = m_DispAttr.m_fWaveZoom[i]; - } - } - - m_DispAttr.m_fTriggerTick = GetPointNoFromTime(m_DispAttr.m_fTriggerTime); - - - //计算合适名称区宽度 - int nNameWidth = 50; - QString sTemp = ""; - CAnalogDataList::Iterator ita; - for( ita = AnalogDataList.begin();ita!=AnalogDataList.end();ita++) - { - sTemp = (*ita).m_sName + (*ita).m_sUnit; - int nLen = (sTemp.length() + 3)*10 + 50; - if( nNameWidthm_nLeftMarginName; - - //检查模拟量相别 - for( ita = AnalogDataList.begin();ita!=AnalogDataList.end();ita++) - { - (*ita).Check(); - } - //检查数字量的变化 - for( itd = DigitDataList.begin();itd!=DigitDataList.end();itd++) - { - (*itd).Check(); - } -/************************************************************************/ -/* 计算基本数值//{{hujf 20080708 */ -/************************************************************************/ - if(m_dLineFreq <= 0) - m_dLineFreq = 50; - - // 计算矢量值 - int Ch=0; - bool bNeed = false; - int nWaveAmt = m_nAnagueNum; - int nTotalPointAmt = GetTotalPointAmount(); - for( Ch=0; Chm_bBaseCompute) - return; - - CAlgorithms algorithms; - int nPos = 0; - int cho = 0; - int chi = 0; - for( nBlks = 0; nBlksnMaxGroup) - nMaxGroup=m_DispAttr.m_nWaveGroup[Ch]; - } - return nMaxGroup; -} -//******************************************************************** -// 取状态最大组数 -// 同一组同一高度. -//******************************************************************** -int CComtradeFile::GetMaxTagsGroupNum() -{ - int nMaxGroup = -1; - for(int Ch=0; ChnMaxGroup) - nMaxGroup=m_DispAttr.m_nTagsGroup[Ch]; - } - return nMaxGroup; -} - -bool CComtradeFile::IsWaveGroupEmpty( int nGroup ) -{ - int ch=0; - for(ch=0; ch300 ) - { - m_sHeadFileText = tr("The Header File's Format is Error");//头文件格式错误 - break; - } - - m_sHeadFileText += sTextLine; - m_sHeadFileText += "\n"; - } - - file.close(); - return true; -} - -bool CComtradeFile::ReadConfFile() -{ - QString sTextLine; - QString sSubString; - m_bIsSeqSample = false; - int i; - // 打开配置文件 - // - QFile file( m_strConfigFilePath ); - if ( !file.open( QIODevice::ReadOnly ) ) - { - m_strErrReadMsg = tr("Config Files Open Failed");//不能打开相应的配置文件 - m_strErrReadMsg.append( m_strConfigFilePath ); - return false; - } - - QTextStream ConfigFile( &file ); - autoSetTextStreamCodec( ConfigFile ); - - m_nReadLine = 1; - // 站名 - if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ){ - return false; - } - if(!CPublic::GetSubString(sTextLine,0,sSubString)){ - return false; - } - m_sStationName = sSubString; - - // 站号 - if(!CPublic::GetSubString(sTextLine,1,sSubString)) - { - return false; - } - m_nStationID = sSubString.toInt(); - - // 版本年号 - if(CPublic::GetSubString(sTextLine,2,sSubString)) - m_sRevisionYear = sSubString; - - if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) - return false; - // 通道个数 - if(!CPublic::GetSubString(sTextLine,0,sSubString)) return false; - m_nChannelTotal = sSubString.toInt(); - - - // 模拟量,数字量个数 - m_nAnagueNum = 0; - m_nDigitalNum = 0; - for(i=1; i<=2; i++) - { - if(!CPublic::GetSubString(sTextLine,i,sSubString)) continue; - - int nCount = sSubString.length(); - if(nCount>1) - { - if(sSubString.right(1)=="A" || sSubString.right(1)=="a") - { - QString sNumStr = sSubString.left(nCount-1); - m_nAnagueNum = sNumStr.toInt(); - } - if(sSubString.right(1)=="D" || sSubString.right(1)=="d") - { - QString sNumStr = sSubString.left(nCount-1); - m_nDigitalNum = sNumStr.toInt(); - } - } - } - - if(m_nChannelTotal != m_nAnagueNum+m_nDigitalNum) - { - m_strErrReadMsg = tr("Config File, Line") + " " + QString::number(m_nReadLine) + ", " + tr("Channel Count Error");//配置文件第,行: 通道数目错! - return false; - } - - if((m_nAnagueNum > MAX_WAVES) || (m_nDigitalNum > MAX_TAGS)) - { - m_strErrReadMsg = tr("Config File, Line") + " " + QString::number(m_nReadLine) + ", " + tr("Channel Count Over Limited") + "(2048A,2048D)!";//通道数目越限 - return false; - } - - // 模拟量配置数组, 清除,预置 - AnalogDataList.clear(); - - // 读入模拟量配置 - // - for(i=0; i MAX_BLOCKS) - return false; - - //{{for 连续可变采样周期 - if( m_nNRates <= 0 ) - { - m_nNRates = 0; - m_bIsSeqSample = true; - m_dSampleRate.resize(0); - m_lSampleAmount.resize(0); - - if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) - return false; - // 采样率 - if(!CPublic::GetSubString(sTextLine,0,sSubString)) return false; - // 采样数 - if(!CPublic::GetSubString(sTextLine,1,sSubString)) return false; - m_nSampleNum = sSubString.toLong(); - } - else - { - //{{hujf for malai 20080125(每段记录的是本段最后一个采样点的序号,而不是本段的采样个数) -// int nBeginStamp = 0; - //}} - m_dSampleRate.resize(m_nNRates); - m_lSampleAmount.resize(m_nNRates); - for(i=0; im_bEndStamp ) - //{ - m_lSampleAmount[i] = sSubString.toLong(); - //} - //else - //{ - // nEndStamp = sSubString.toLong(); - // m_lSampleAmount[i] = nEndStamp - nBeginStamp; - //} - - if( m_lSampleAmount[i]<=0) - m_lSampleAmount[i] = 0; - //nBeginStamp = nEndStamp; - //}} - } - } - //{判断每段最后的序号是否是递增的,m_bASCFile - for(int iTemp = 0; iTemp < m_nNRates - 1; iTemp++) - { - - if( ( m_lSampleAmount[iTemp+1] - m_lSampleAmount[iTemp] ) > 0 ) - { - m_bASCFile = true; - } - else - { - m_bASCFile = false; - } - } - //} - //}} - // 读入起始时间 - // - if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) - return false; - QString sdate = sTextLine.section(",",0,0); - QString sutime = sTextLine.section(",",1,1); - QString sd = sdate.section("/",0,0); - QString sm = sdate.section("/",1,1); - QString sy = sdate.section("/",2,2); - QString stime = sutime.section(".",0,0); - QString smicro = sutime.section(".",1,1); - QString sh = stime.section(":",0,0); - QString smin = stime.section(":",1,1); - QString ssec = stime.section(":",2,2); - - int wMonth = sm.toInt(); - int wDay = sd.toInt(); - int wYear = 0; - /*if(wMonth > 12) - { - int nTemp = wDay; - wDay = wMonth; - wMonth = nTemp; - }*/ - - if(CWaveEnv::GetInst()->m_nDateSetOption == 0) - { - int nTemp = wDay; - wDay = wMonth; - wMonth = nTemp; - } - if(sy.length()>2) - { - wYear = sy.toInt(); - } - else - { - wYear = sy.toInt(); - if(wYear>80) - wYear += 1900; - else wYear += 2000; - } - - int wHour = sh.toInt(); - int wMinute = smin.toInt(); - int wSecond = ssec.toInt(); - int wMilliseconds = smicro.toInt(); - if( wMilliseconds>1000 ) - wMilliseconds = wMilliseconds/1000; - - m_tFirstTime.setDate(QDate(wYear,wMonth,wDay)); - m_tFirstTime.setTime(QTime(wHour,wMinute,wSecond,wMilliseconds)); - - // 读入故障时间 - // - if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) - return false; - - sdate = sTextLine.section(",",0,0); - sutime = sTextLine.section(",",1,1); - sd = sdate.section("/",0,0); - sm = sdate.section("/",1,1); - sy = sdate.section("/",2,2); - stime = sutime.section(".",0,0); - smicro = sutime.section(".",1,1); - sh = stime.section(":",0,0); - smin = stime.section(":",1,1); - ssec = stime.section(":",2,2); - - wMonth = sm.toInt(); - wDay = sd.toInt(); - /*if(wMonth > 12) - { - int nTemp = wDay; - wDay = wMonth; - wMonth = nTemp; - }*/ - - if(CWaveEnv::GetInst()->m_nDateSetOption == 0) - { - int nTemp = wDay; - wDay = wMonth; - wMonth = nTemp; - } - if(sy.length()>2) - { - wYear = sy.toInt(); - } - else - { - wYear = sy.toInt(); - if(wYear>80) - wYear += 1900; - else wYear += 2000; - } - - wHour = sh.toInt(); - wMinute = smin.toInt(); - wSecond = ssec.toInt(); - wMilliseconds = smicro.toInt(); - if( wMilliseconds>1000 ) - wMilliseconds = wMilliseconds/1000; - - m_tTriggerTime.setDate(QDate(wYear,wMonth,wDay)); - m_tTriggerTime.setTime(QTime(wHour,wMinute,wSecond,wMilliseconds)); - - GetFirstMicroSecs(); - - m_DispAttr.m_fBaseTick = 0; - m_DispAttr.m_fBaseTime = GetPointTime(0); - - if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) - return false; - - if(!CPublic::GetSubString(sTextLine,0,sSubString)) return false; - sSubString = sSubString.trimmed(); - QString sFileType = sSubString.toUpper(); - if( 0==sFileType.compare("ASCII") ) - m_bAsciiDataFormat = true; - else if( 0==sFileType.compare("BINARY") ) - m_bAsciiDataFormat = false; - else - { - Q_ASSERT(false); - /*2008-1-5 zhn del for initial value of reference to non-const must be an lvalue - m_strErrReadMsg.sprintf("%s%d%s",QObject::tr("配置文件 第").toAscii(),m_nReadLine,QObject::tr("行: 格式错!").toAscii()); - */ - //{{2008-1-5 zhn add for initial value of reference to non-const must be an lvalue - m_strErrReadMsg = QString("%1 %2%, 3").arg(tr("Config File, Line")).arg(m_nReadLine).arg(tr("Format Error!"));//格式错误 - //}} - return false; - - } - // 读入时间系数 - // - if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) - { - dTimeMult = 1.0; - } - else - { - if(CPublic::GetSubString(sTextLine,0,sSubString)) - dTimeMult = sSubString.toDouble(); - } - file.close(); - return true; -} -//非连续采样的波形 -bool CComtradeFile::ReadDataFile() -{ - int i; - int nSamplePointNum = 0; - int nPointNum = 0; - - if(m_bAsciiDataFormat) - { - if(m_bASCFile) - {//先判断cfg文件中采样数是否是递增的 -// QFile tempFile(m_strDataFilePath); -// if ( !tempFile.open( QIODevice::ReadOnly ) ) -// { -// m_strErrReadMsg = QObject::tr("不能打开相应的数据文件 "); -// m_strErrReadMsg.append( m_strConfigFilePath ); -// return false; -// } -// //{{下面从dat文件中读取第一行与最后一行的序号,并判断是否为新文件 -// //2009-06-20 -// QTextStream tempStream( &tempFile ); -// QString sTempLine = ""; -// QString sTempString = ""; -// int nFirstNO = 0; -// int nLastNO = 0; -// int nTempNum = 1; -// //读第一行数据的第一个数,是序号 -// if(!CPublic::ReadStreamLine( tempStream, sTempLine, nTempNum ) ) -// return false; -// if( !CPublic::GetSubString ( sTempLine, 0, sTempString ) ) -// return false; -// //读第一行序号 -// nFirstNO = sTempString.toInt(); -// //循环读取数据,直到最后一行 -// while( CPublic::ReadStreamLine( tempStream, sTempLine, nTempNum ) ) ; -// //读取最后一行数据的序号 -// if( !CPublic::GetSubString( sTempLine, 0, sTempString ) ) -// return false; -// nLastNO = sTempString.toInt(); -// tempFile.close(); -// //判断第一行序号是否为0,0:老文件,1:新文件 -// if( nFirstNO == 0 ) -// m_bNotZeroFile = false; -// else if( nFirstNO == 1 ) -// m_bNotZeroFile = true; -// //判断最后一行序号是否与记录的最后一块数据的个数相同,相同即为新文件,不同为老文件 -// if( nLastNO == m_lSampleAmount[m_nNRates - 1] ) -// m_bSeqFile = true; -// else -// m_bSeqFile = false; - //通过三个条件来判断是否为新文件,若是新文件, - //则要将m_lSampleAmount中的数据进行处理,换算成每块数据的个数 -// if( m_bSeqFile && m_bNotZeroFile) -// { -// m_bNewFile = true; - for( int k = m_nNRates - 1; k > 0; k--) - m_lSampleAmount[k] = m_lSampleAmount[k] - m_lSampleAmount[k-1]; -// } -// else -// { -// m_bNewFile = false; -// } - } - //}}读取第一行与最后一行的序号 - - nSamplePointNum = GetTotalPointAmount(); - nPointNum = GetNumberOfWaveTags(); - - if(nSamplePointNum<=0 || nPointNum<=0) - return false; - - // 清除, 设置数组 - // - for( i=0; i0) - BlkBeginTime_us +=(long)( double(1000000.0)/((double)m_dSampleRate[TR-1]) + 0.5 ); - - if( nRates>0 ) - { - for( PT = 0; PT0) - BlkBeginTime_us+=(long)(double(1.0)*(1000000.0/((double)nRates))+0.5); - - if( nRates>0 ) - { - for( PT = 0; PT= (nPointNum-1) ) -// {//本行最后一个数据 -// if( EOF==fscanf( pFile,"%d",&nData) ) -// { -// continue; -// } -// //换行 -// if( EOF==fscanf( pFile,",\n"/*,pBuf*/) ) -// { -// continue; -// } -// } -// else -// { -// if( EOF==fscanf( pFile,"%d,",&nData) ) -// continue; -// } - -// // 设置波形最大值 -// if(nCol=0) -// { -// // 设置数据数组 -// if(nRow < nSamplePointNum ) -// { -// CAnalogData& AnaData = AnalogDataList[nCol]; -// AnaData.m_dlSampleData[nRow] = nData; -// } -// } -// else if(nCol < nPointNum) -// { -// // 设置数据数组 -// if(nRow < nSamplePointNum ) -// { -// CDigitData& DgtData = DigitDataList[nCol - m_nAnagueNum]; -// DgtData.m_bySampleData[nRow] = nData; -// } -// } - -// } - -// nRow ++; // 换行 -// } -// } -// fclose(pFile); - - QFile file( m_strDataFilePath ); - if ( !file.open(QIODevice::ReadOnly) ) - { - m_strErrReadMsg = tr("Data File Open Failed"); - m_strErrReadMsg.append( m_strDataFilePath ); - return false; - } - - int nLineNum = 1; - int nRow = 0; // 数据行 - int nCol = 0; // 数据列 - for ( int nRateIdx=0; nRateIdx listData = QString(file.readLine()).simplified().split(","); - - if ( listData.count() != m_nAnagueNum + m_nDigitalNum + 2 ) - { - m_strErrReadMsg = QString("数据文件 %1 行格式不正确").arg(nLineNum); - return false; - } - - nLineNum++; - int nData = 0; - for(nCol=0; nCol=0) - { - // 设置数据数组 - if(nRow < nSamplePointNum ) - { - CAnalogData& AnaData = AnalogDataList[nCol]; - AnaData.m_dlSampleData[nRow] = nData; - } - } - else if(nCol < nPointNum) - { - // 设置数据数组 - if(nRow < nSamplePointNum ) - { - CDigitData& DgtData = DigitDataList[nCol - m_nAnagueNum]; - DgtData.m_bySampleData[nRow] = nData; - } - } - } - nRow++; // 换行 - } - } - file.close(); - } - else - { - int nBitsBytes = (m_nDigitalNum+15)/16*2; - WORD wDataWidth = 8+m_nAnagueNum*2+nBitsBytes; - - //{{判断文件是否是新格式的文件 - if(m_bASCFile) - { -// QFile fileTemp( m_strDataFilePath ); -// if ( !fileTemp.open( QIODevice::ReadOnly ) ) -// { -// m_strErrReadMsg = QObject::tr("不能打开相应的数据文件 "); -// m_strErrReadMsg.append( m_strDataFilePath ); -// return false; -// } -// QDataStream DataFileTemp( &fileTemp ); -// char *pDataTemp = new char[wDataWidth+10]; -// -// DataFileTemp.readRawData(pDataTemp,wDataWidth); -// DWORD dFirstIndex = MAKELONG(MAKEWORD(pDataTemp[0],pDataTemp[1]),MAKEWORD(pDataTemp[2],pDataTemp[3])); -// if(dFirstIndex == 0) -// { -// m_bNotZeroFile = false; -// } -// else if(dFirstIndex == 1) -// { -// m_bNotZeroFile = true; -// } -// int i = 0; -// while(!DataFileTemp.atEnd()) -// { -// DataFileTemp.readRawData(pDataTemp,wDataWidth); -// i++; -// } - - -// for(int nRateIdx = 0; nRateIdx < m_nNRates; nRateIdx++) -// { -// int nPointAmt = m_lSampleAmount[nRateIdx]; -// if(nRateIdx == 0) -// { -// DataFileTemp.readRawData(pDataTemp,wDataWidth); -// DWORD dFirstIndex = MAKELONG(MAKEWORD(pDataTemp[0],pDataTemp[1]),MAKEWORD(pDataTemp[2],pDataTemp[3])); -// if(dFirstIndex == 0) -// { -// m_bNotZeroFile = false; -// } -// else if(dFirstIndex == 1) -// { -// m_bNotZeroFile = true; -// } -// for(int p = 1; p 0) -// { -// for(int p = 0; p 0; k--) - m_lSampleAmount[k] = m_lSampleAmount[k] - m_lSampleAmount[k-1]; -// } -// else -// { -// m_bNewFile = false; -// } - } - //}}判断文件是否是新格式的文件 - - nSamplePointNum = GetTotalPointAmount(); - nPointNum = GetNumberOfWaveTags(); - - if(nSamplePointNum<=0 || nPointNum<=0) - return false; - - // 清除, 设置数组 - // - for( i=0; i0) - BlkBeginTime_us1 +=(long)( double(1000000.0)/((double)m_dSampleRate[TR1-1]) + 0.5 ); - - if( nRates1>0 ) - { - for( PT1 = 0; PT10) - BlkBeginTime_us1+=(long)(double(1.0)*(1000000.0/((double)nRates1))+0.5); - - if( nRates1>0 ) - { - for( PT1 = 0; PT1= nPointNum-1) -// {//本行最后一个数据 -// if( EOF==fscanf( pFile,"%d\n",&nData ) ) -// continue; -// } -// else -// { -// if( EOF==fscanf( pFile,"%d,",&nData) ) -// continue; -// } - -// bool bValid = true; -// if(nData>99998||nData<-99999) -// { -// nData = 0; -// bValid = false; -// } -// // 设置波形最大值 -// if(nCol=0) -// { -// // 设置数据数组 -// CAnalogData& AnaData = AnalogDataList[nCol]; -// AnaData.m_dlSampleData[nSampleIndex] = nData; -// AnaData.m_bSampleValid[nSampleIndex] = bValid; -// m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; -// } -// else if(nCol < nPointNum) -// { -// // 设置数据数组 -// CDigitData& DgtData = DigitDataList[nCol - m_nAnagueNum]; -// DgtData.m_bySampleData[nSampleIndex] = nData; -// m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; -// } -// } -// } -// fclose(pFile); - - QFile file( m_strDataFilePath ); - if ( !file.open(QIODevice::ReadOnly) ) - { - m_strErrReadMsg = tr("Data File Open Failed"); - m_strErrReadMsg.append( m_strDataFilePath ); - return false; - } - - int nCol = 0; // 数据列 - qlonglong nTimeStamp = 0; - for( nSampleIndex = 0;nSampleIndex listData = QString(file.readLine()).simplified().split(","); - if(listData.size()99998||nData<-99999) - { - nData = 0; - bValid = false; - } - // 设置波形最大值 - if(nCol=0) - { - // 设置数据数组 - CAnalogData& AnaData = AnalogDataList[nCol]; - AnaData.m_dlSampleData[nSampleIndex] = nData; - AnaData.m_bSampleValid[nSampleIndex] = bValid; - m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; - } - else if(nCol < nPointNum) - { - // 设置数据数组 - CDigitData& DgtData = DigitDataList[nCol - m_nAnagueNum]; - DgtData.m_bySampleData[nSampleIndex] = nData; - m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; - } - } - } - file.close(); - } - else - { - // 打开数据文件 - // - QFile file( m_strDataFilePath ); - if ( !file.open(QIODevice::ReadOnly) ) - { - m_strErrReadMsg = tr("Data File Open Failed"); - m_strErrReadMsg.append( m_strDataFilePath ); - return false; - } - - QDataStream DataFile( &file ); - // All digitals are combined in even bytes - int nBitsBytes = (m_nDigitalNum+15)/16*2; - WORD wDataWidth = 8+m_nAnagueNum*2+nBitsBytes; - char *pData = new char[wDataWidth+10]; - qlonglong nTimeStamp = 0; - int ch; - - int nSampleIndex = 0; - for( nSampleIndex = 0;nSampleIndex32767||nData<-32767) - { nData = 0; bValid = false;} - - // 设置数据数组 - AnaData.m_dlSampleData[nSampleIndex] = nData; - AnaData.m_bSampleValid[nSampleIndex] = bValid; - m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; - } - - for(ch=0; ch0) - { - nCurStep = nCurStamp - nPrevStamp; - if( nCurStep != nPrevStep ) - { - m_nNRates++; - nCurRate = 1000000.0/(double)(nCurStep); - m_dSampleRate.resize( m_nNRates ); - m_lSampleAmount.resize( m_nNRates ); - - m_dSampleRate[m_nNRates-1] = nCurRate; - if( m_nNRates >=2 ) - { - m_lSampleAmount[m_nNRates-2] = nSampleIndex-1-nPrevBlockIndex; - nPrevBlockIndex = nSampleIndex-1; - } - } - nPrevStep = nCurStep; - } - nPrevStamp = nCurStamp; - } - m_lSampleAmount[m_nNRates-1] = nSampleIndex-1-nPrevBlockIndex; - - return true; -} - -bool CComtradeFile::ReadInfFile() -{ - if ( CSectionOperate::ReadFile( m_SectionList, m_strInfoFilePath ) ) - { - m_strErrReadMsg = tr("Info File Open Failed");//不能打开相应的信息文件 - m_strErrReadMsg.append( m_strInfoFilePath ); - return false; - } - return true; -} - -bool CComtradeFile::SaveWaveFile(const QString& strPath, const QString& strFileName ) -{ - // Skip tail ".DAT", ".HDR" or ".CFG" - m_sDirName = strPath; - QString sName = strFileName.toUpper(); - m_sFileName = strFileName; - - int nPos = sName.indexOf(".DAT"); - if(nPos>0) m_sFileName = strFileName.left(nPos); - nPos = sName.indexOf(".CFG"); - if(nPos>0) m_sFileName = strFileName.left(nPos); - nPos = sName.indexOf(".HDR"); - if(nPos>0) m_sFileName = strFileName.left(nPos); - nPos = sName.indexOf(".INF"); - if(nPos>0) m_sFileName = strFileName.left(nPos); - - m_strErrReadMsg = ""; - if(m_sFileName.isEmpty()) - { - m_strErrReadMsg = tr("The Filename is Error!"); - return false; - } - - QString sTextLine; - QString sSubString; - - // COMTRADE头文件名 - // - m_strHeadFilePath = m_sDirName; - m_strHeadFilePath += m_sFileName; - m_strHeadFilePath.append( ".HDR" ); - // 写头文件 - // - WriteHeadFile(); - - // COMTRADE配置文件名 - // - m_strConfigFilePath = m_sDirName; - m_strConfigFilePath += m_sFileName; - m_strConfigFilePath.append( ".CFG" ); - - //写配置文件 - // - if(!WriteConfFile()) - return false; - - // COMTRADE数据文件名 - // - m_strDataFilePath = m_sDirName; - m_strDataFilePath += m_sFileName; - m_strDataFilePath.append( ".DAT" ); - - // 写数据文件 - // - if(!WriteDataFile()) - return false; - - // COMTRADE信息文件名 - // - m_strInfoFilePath = m_sDirName; - m_strInfoFilePath += m_sFileName; - m_strInfoFilePath.append( ".INF" ); - - // 保存信息文件 - // - WriteInfFile(); - - //保存标注文件 - m_LabelList.SaveLabelFile(m_sDirName,m_sFileName); - QString m_sStrFile = m_sDirName + "\\" + m_sFileName; - m_sStrFile.append( ".AUX" ); - m_LBQConfig.WriteXmlFile(m_sStrFile); - return true; -} - -bool CComtradeFile::WriteHeadFile() -{ - //写头文件 - // - QFile file( m_strHeadFilePath ); - if ( !file.open( QIODevice::WriteOnly ) ) - return true; - QTextStream ts( &file ); - ts << (m_sHeadFileText); - file.close(); - return true; -} - -bool CComtradeFile::WriteConfFile() -{ - //保存配置文件 - // - QFile file( m_strConfigFilePath ); - if ( !file.open( QIODevice::WriteOnly ) ) - { - m_strErrReadMsg = tr("Config Files Open Failed");//不能打开相应的配置文件 - m_strErrReadMsg.append( m_strConfigFilePath ); - return false; - } - - QString sFileType = "ASCII"; - if( !m_bAsciiDataFormat ) - sFileType = "BINARY"; - - QTextStream ConfigFile( &file ); - - ConfigFile<<(m_sStationName)<=2000) - nYear -= 2000; - else - nYear -= 1900; - - - ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<=2000) - nYear -= 2000; - else - nYear -= 1900; - - ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<nIndex) - nTime = m_aTimeArray[nIndex]; - sprintf(buf,"%12d",nTime); - DataFile<nIndex) - n2 = m_aTimeArray[nIndex]; - - DataFile<0) sFileName = sName.left(nPos); - nPos = sName.indexOf(".CFG"); - if(nPos>0) sFileName = sName.left(nPos); - nPos = sName.indexOf(".HDR"); - if(nPos>0) sFileName = sName.left(nPos); - nPos = sName.indexOf(".INF"); - if(nPos>0) sFileName = sName.left(nPos); - - QString strConfigFilePath = sDirName; - strConfigFilePath.append("/"); - strConfigFilePath += sFileName; - strConfigFilePath.append( ".CFG" ); - - QString sTextLine; - QString sSubString; -// bool bValidConfigFile = false; - // 打开配置文件 - // - QFile file( strConfigFilePath ); - if ( !file.open( QIODevice::ReadOnly ) ) - return false; - - QTextStream ConfigFile( &file ); - autoSetTextStreamCodec( ConfigFile ); - - int nLineNum = 1; - while(!ConfigFile.atEnd()) - { - int ChanelsNum = 0,TagsNum = 0,ChanTotal = 0; - // 站名 - sTextLine = ConfigFile.readLine(); - if(QString()==sTextLine) break; - nLineNum++; - //第一行跳过 - sTextLine = ConfigFile.readLine(); - if(QString()==sTextLine) break; - nLineNum++; - // 通道个数 - if(!CPublic::GetSubString(sTextLine,0,sSubString)) break; - ChanTotal = sSubString.toInt(); - - // 模拟量,数字量个数 - int i; - for( i=1; i<=2; i++) - { - if(!CPublic::GetSubString(sTextLine,i,sSubString)) continue; - - int nCount = sSubString.length(); - if(nCount>1) - { - if(sSubString.right(1)=="A" || sSubString.right(1)=="a") - { - QString sNumStr = sSubString.left(nCount-1); - ChanelsNum = sNumStr.toInt(); - } - if(sSubString.right(1)=="D" || sSubString.right(1)=="d") - { - QString sNumStr = sSubString.left(nCount-1); - TagsNum = sNumStr.toInt(); - } - } - } - - if(ChanTotal != ChanelsNum+TagsNum) - break; - - if((ChanelsNum > MAX_WAVES) || (TagsNum > MAX_TAGS)) - break; - - // 模拟量配置数组, 清除,预置 - pAnalogList.clear(); - - // 读入模拟量配置 - // - for(i=0; i=2000) - nYear -= 2000; - else - nYear -= 1900; - - - ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<=2000) - nYear -= 2000; - else - nYear -= 1900; - - ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<=2000) - nYear -= 2000; - else - nYear -= 1900; - - - ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<=2000) - nYear -= 2000; - else - nYear -= 1900; - - ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<& listAnalog , QList& listDigit ,float fSampleRate,int nSampleNum) -{ -// int nCount = AnalogDataList.count() ; - CAnalogDataList anaDataList; - CDigitDataList dgtDataList; - for(int i = 0 ;i 0) - { - m_dSampleRate[0] = fSampleRate ; - m_lSampleAmount[0] = nSampleNum; - } - - } - // 模拟量,数字量个数 - m_nAnagueNum = listAnalog.count(); - m_nDigitalNum = listDigit.count(); - m_nChannelTotal = m_nAnagueNum+m_nDigitalNum ; - -} - -bool CComtradeFile::WriteConfFile(const QString& strCfgPathFileName) -{ - m_strConfigFilePath = strCfgPathFileName ; - return WriteConfFile(); -} - -//读取CFG路径文件名 -bool CComtradeFile::ReadConfFile(const QString& strCfgPathFileName) -{ - //char sz[1024]; - //strcpy(sz,strCfgPathFileName.toAscii().data()); - //strcpy(sz,m_strConfigFilePath.toAscii().data()); - if (m_strConfigFilePath == strCfgPathFileName) - return true; - m_strConfigFilePath = strCfgPathFileName; - bool result = ReadConfFile(); - return result; -} - - - -//读取文件选择的文件 -bool CComtradeFile::ReadSelectionFile(const QString& strSelectionPathFileName,int& nTotalAnalogAmount,int& nTotalDigitalAmount,QList& listAnalog,QList& listDigital) -{ - nTotalAnalogAmount = 0 ; - nTotalDigitalAmount = 0 ; - listAnalog.clear(); - listDigital.clear(); - - QFile file( strSelectionPathFileName ); - - if ( file.open( QIODevice::ReadOnly|QIODevice::Text ) ) - { - - QTextStream stream( &file ); - autoSetTextStreamCodec( stream ); - - QString line; - QString lineTrimmed; -// int n = 1; - QStringList list; - while ( !stream.atEnd() ) { - //Untrimmed - line = stream.readLine(); - lineTrimmed = line.trimmed(); - list< 0) - { - QStringList listSection = list[0].split(","); - if (listSection.count() < 2 ) - return false; - if (listSection.count()>=2) - { - nTotalAnalogAmount = listSection[0].trimmed().toInt(); - nTotalDigitalAmount = listSection[1].trimmed().toInt(); - } - } - - //2.读取选中的模拟通道 - if (list.count() > 1) - { - QStringList listSection = list[1].split(","); - for(int i = 0 ; i < listSection.count(); i++) - { - - QString strChan = listSection[i]; - - if ("" == strChan.trimmed()) continue; - listAnalog< 2) - { - - QStringList listSection = list[2].split(","); - for(int i = 0 ; i < listSection.count(); i++) - { - QString strChan = listSection[i]; - if ("" == strChan.trimmed()) continue; - listDigital<& listAnalog,QList& listDigital) -{ - if (!szData) - return false; - if ("" == m_strConfigFilePath ) - { - return false; - } - - if (wLen < (nTotalAnalogAmount*2 +nTotalDigitalAmount/8)*24) - return false; - //CloseWaveFile(); - - //设置当前DataFile路径文件名称 - //m_strDataFilePath = strRealDataPathFileName; - - //设置起始时间 - m_tFirstTime = QDateTime::currentDateTime(); - //设置触发时间 - m_tTriggerTime = QDateTime::currentDateTime(); - - QString sTextLine; - QString sSubString; - int i; - int nSamplePointNum = GetTotalPointAmount(); - int nPointNum = GetNumberOfWaveTags(); - - if(nSamplePointNum<=0 || nPointNum<=0) - return false; - - // 清除, 设置数组 - // - for( i=0; im_bEndStamp ) - { - double BlkBeginTime_us = 0.0; - for( TR=0; TR0) - BlkBeginTime_us +=(long)( double(1000000.0)/((double)m_dSampleRate[TR-1]) + 0.5 ); - - if( nRates>0 ) - { - for( PT = 0; PT0) - BlkBeginTime_us+=(long)(double(1.0)*(1000000.0/((double)nRates))+0.5); - - if( nRates>0 ) - { - for( PT = 0; PT& listAnalog,QList& listDigital) -{ - if ("" == m_strConfigFilePath ) - { - return false; - } - - //CloseWaveFile(); - - //设置当前DataFile路径文件名称 - m_strDataFilePath = strRealDataPathFileName; - - //设置起始时间 - QFileInfo dataFileInfo(m_strDataFilePath); - m_tFirstTime.setTime_t(dataFileInfo.fileName().toUInt() - 8*3600); - //设置触发时间 - m_tTriggerTime.setTime_t(dataFileInfo.fileName().toUInt() - 8*3600 ); - - QString sTextLine; - QString sSubString; - int i; - int nSamplePointNum = GetTotalPointAmount(); - int nPointNum = GetNumberOfWaveTags(); - - if(nSamplePointNum<=0 || nPointNum<=0) - return false; - - // 清除, 设置数组 - // - for( i=0; i0 ) - { - for(int PT = 0; PTm_bEndStamp ) - { - double BlkBeginTime_us = 0.0; - for( TR=0; TR0) - BlkBeginTime_us +=(long)( double(1000000.0)/((double)m_dSampleRate[TR-1]) + 0.5 ); - - if( nRates>0 ) - { - for( PT = 0; PT0) - BlkBeginTime_us+=(long)(double(1.0)*(1000000.0/((double)nRates))+0.5); - - if( nRates>0 ) - { - for( PT = 0; PT0 ) - { - for(int PT = 0; PTm_bEndStamp ) - { - double BlkBeginTime_us = 0.0; - for( TR=0; TR0) - BlkBeginTime_us +=(long)( double(1000000.0)/((double)m_dSampleRate[TR-1]) + 0.5 ); - - if( nRates>0 ) - { - for( PT = 0; PT0) - BlkBeginTime_us+=(long)(double(1.0)*(1000000.0/((double)nRates))+0.5); - - if( nRates>0 ) - { - for( PT = 0; PTm_bExtensive ) - TransToContinus(); - //属性 - InitDisplyAttr(); - - return true; - -} - -bool CComtradeFile::OpenRealWaveFile(const QString& strRealWaveDataPathFileName,const QString& strRealWaveCfgPathFileName) -{ - - - ReadConfFile(strRealWaveCfgPathFileName); - ReadRealDataFile(strRealWaveDataPathFileName); - - return true; -} -bool CComtradeFile::OpenRealWaveFile(const QString& strRealWaveDataPath,const QString& strRealWaveDataFileName,const QString& strRealWaveCfgPath,const QString& strRealWaveCfgDataFileName) -{ - CloseWaveFile(); - - // Skip tail ".DAT", ".HDR" or ".CFG" - m_sDirName = strRealWaveDataPath; - QString sName = strRealWaveDataFileName.toUpper(); - m_sFileName = strRealWaveDataFileName; - - int nPos = sName.indexOf(".DAT",0,Qt::CaseInsensitive); - if(nPos>0) m_sFileName = sName.left(nPos); - - m_strErrReadMsg = ""; - if(m_sFileName.isEmpty()) - { - m_strErrReadMsg = tr("The Filename is Error!");//空文件名错! - return false; - } - - QString sTextLine; - QString sSubString; - - - // COMTRADE配置文件名 - // - m_strConfigFilePath = strRealWaveCfgPath; - m_strConfigFilePath += "/"; - m_strConfigFilePath += strRealWaveCfgDataFileName; - - - //读配置文件 - // - if( !ReadConfFile() ) - { - CloseWaveFile(); - return false; - } - // COMTRADE数据文件名 - // - m_strDataFilePath = strRealWaveDataPath; - m_strDataFilePath += "/"; - m_strDataFilePath += strRealWaveDataFileName; - - - // 打开数据文件 - //{{for 连续可变采样周期 - bool bRet = true; - - bRet = ReadRealDataFile(); - //}} - if( !bRet ) - { - CloseWaveFile(); - return false; - } - - - //打开标注文件 - m_LabelList.OpenLabelFile(m_sDirName,m_sFileName); - - if( CWaveEnv::GetInst()->m_bExtensive ) - TransToContinus(); - //属性 - InitDisplyAttr(); - - return true; -} -//}} +#include "CComDataClass.h" +#include +#include +#include +#include +#include "CPublic.h" +#include +#include +#include +#include +#include +#include "wavedata.h" +#include "calgorithms.h" +#include "CommonFunction.h" +#include +#include +#include + +///////////////////////////////////////////////////// +//罗马数字检查 + +void RomanNumberCheck(QString &sTextLine) +{ + QString newstr; + char ch1,ch2; + for(int i=0;i-16&&ch2<-2)) + { + switch(ch2) + { + case -15: + newstr.append("I"); + break; + case -14: + newstr.append("II"); + break; + case -13: + newstr.append("III"); + break; + case -12: + newstr.append("IV"); + break; + case -11: + newstr.append("V"); + break; + case -10: + newstr.append("VI"); + break; + case -9: + newstr.append("VII"); + break; + case -8: + newstr.append("VII"); + break; + case -7: + newstr.append("VIII"); + break; + case -6: + newstr.append("IX"); + break; + case -5: + newstr.append("X"); + break; + case -4: + newstr.append("XI"); + break; + case -3: + newstr.append("XII"); + break; + default: + newstr.append("?"); + break; + + } + + } + else + { + newstr.append(ch1); + newstr.append(ch2); + } + } + else + { + newstr.append(ch1); + } + + + } + sTextLine = newstr; +} + +/////////////////////////////////////////// + +bool CAnalogDataList::FindItemByIndex(int nIndex ,CAnalogData& data) +{ + for(int i = 0 ;i< count();i++) + { + CAnalogData dataAna = at(i); + if (dataAna.m_nIndex == nIndex) + { + data = dataAna ; + return true; + } + } + return false; +} + +bool CAnalogDataList::DeleteItemByIndex(int nIndex) +{ + for(int i = 0 ;i< count();i++) + { + CAnalogData data = at(i); + if (data.m_nIndex == nIndex) + { + removeAt(i); + return true; + } + } + return false; +} + +bool CDigitDataList::FindItemByIndex(int nIndex ,CDigitData& data) +{ + for(int i = 0 ;i< count();i++) + { + CDigitData dataDgt = at(i); + if (dataDgt.m_nIndex == nIndex) + { + data = dataDgt ; + return true; + } + } + return false; +} + +bool CDigitDataList::DeleteItemByIndex(int nIndex) +{ + for(int i = 0 ;i< count();i++) + { + CDigitData data = at(i); + if (data.m_nIndex == nIndex) + { + removeAt(i); + return true; + } + } + return false; +} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +CLBQConfigFile::CLBQConfigFile() +{ +} + +CLBQConfigFile::~CLBQConfigFile() +{ +} + +#include +//XML文件读写 +void CLBQConfigFile::ReadXmlFile(const QString& sf) +{ + QFile file(sf); + if( !file.open(QIODevice::ReadOnly|QIODevice::Text) ) + { + return; + } + QTextStream ConfigFile( &file ); + autoSetTextStreamCodec( ConfigFile ); + + QString sCnt = ConfigFile.readAll(); + int n = sCnt.indexOf("xml"); + sCnt = sCnt.remove(0,n); + + sCnt = "firstChild(); !n.isNull(); n=n.nextSibling() ) + { + QDomElement elConfig = n.toElement(); + if( elConfig.isNull() ) + continue; + if( elConfig.tagName() == "Config" ) + { + sType = elConfig.attribute("type"); + nAnalog = elConfig.attribute("analog").toInt(); + nBinary = elConfig.attribute("binary").toInt(); + nSampleRate = elConfig.attribute("sample_rate").toInt(); + } + else if( elConfig.tagName() == "Component" ) + { + //{{ + CLBQComponent cmp; + + cmp.sType = elConfig.attribute("type"); + cmp.sName = elConfig.attribute("name"); + cmp.nBayNo = elConfig.attribute("bay_no").toInt(); + + + QDomElement elAnaList = elConfig.namedItem( "Analogs" ).toElement(); + if(!elAnaList.isNull() ) + { + for( QDomNode ana=elAnaList.firstChild(); !ana.isNull(); ana=ana.nextSibling() ) + { + QDomElement elAna = ana.toElement(); + if( elAna.isNull() ) + { + continue; + } + + CLBQAnalog ag; + + ag.sDesc = elAna.attribute("desc"); + ag.nCh = elAna.attribute("rec_chnl").toInt(); + ag.nTypeId = elAna.attribute("typeid").toInt(); + + cmp.m_AnaList.append(ag); + } + } + + QDomElement elBinList = elConfig.namedItem( "Binaries" ).toElement(); + if(!elBinList.isNull() ) + { + for( QDomNode bina=elBinList.firstChild(); !bina.isNull(); bina=bina.nextSibling() ) + { + QDomElement elBina = bina.toElement(); + if( elBina.isNull() ) + { + continue; + } + + CLBQBinary by; + + by.sDesc = elBina.attribute("desc"); + by.nCh = elBina.attribute("channel").toInt(); + by.nRelayAct = elBina.attribute("relay_act").toInt(); + by.nRecd_cntr = elBina.attribute("recd_cntr").toInt(); + + cmp.m_BinList.append(by); + } + } + + QDomElement elParaList = elConfig.namedItem( "Parameters" ).toElement(); + if(!elParaList.isNull() ) + { + for( QDomNode para=elParaList.firstChild(); !para.isNull(); para=para.nextSibling() ) + { + QDomElement elPara = para.toElement(); + if( elPara.isNull() ) + { + continue; + } + CLBQParameter pr; + + pr.sDesc = elPara.attribute("desc"); + pr.fValue = elPara.attribute("value").toFloat(); + pr.sUnit = elPara.attribute("unit"); + + cmp.m_ParamList.append(pr); + } + } + + QDomElement elRelList = elConfig.namedItem( "Relations" ).toElement(); + if(!elRelList.isNull() ) + { + for( QDomNode relt=elRelList.firstChild(); !relt.isNull(); relt=relt.nextSibling() ) + { + QDomElement elRelt = relt.toElement(); + if( elRelt.isNull() ) + { + continue; + } + CLBQRelation rt; + rt.nBayNo = elRelt.attribute("bay_no").toInt(); + cmp.m_RelList.append(rt); + } + } + + m_CompList.append(cmp); + //}} + } + } +} + +//实现方法:将需要保存的数据设置为元素属性 +void CLBQConfigFile::WriteXml(QDomElement* d) +{ + if(!d) + { + return; + } + QDomElement elConfig = d->ownerDocument().createElement( "Config" ); + if( !elConfig.isNull() ) + { + elConfig.setAttribute( "type", sType ); + elConfig.setAttribute( "analog", nAnalog ); + elConfig.setAttribute( "binary", nBinary ); + elConfig.setAttribute( "sample_rate", nSampleRate ); + d->appendChild( elConfig ); + } + if( m_CompList.count() < 1 ) + return; + for(int i = 0; i < m_CompList.count(); i++ ) + { + CLBQComponent& cmp = m_CompList[i]; + QDomElement elComponent = d->ownerDocument().createElement( "Component" ); + if( !elComponent.isNull() ) + { + d->appendChild( elComponent ); + + QDomElement elAnas = d->ownerDocument().createElement( "Analogs" ); + if( !elAnas.isNull() ) + { + elComponent.setAttribute( "type", cmp.sType ); + elComponent.setAttribute( "name", cmp.sName ); + elComponent.setAttribute( "bay_no", cmp.nBayNo ); + elComponent.appendChild( elAnas ); + for( int j = 0; j < cmp.m_AnaList.count(); j++) + { + CLBQAnalog& cAna = cmp.m_AnaList[j]; + QDomElement elAna = d->ownerDocument().createElement( "Analog" ); + if( !elAna.isNull() ) + { + elAna.setAttribute( "desc" , cAna.sDesc ); + elAna.setAttribute( "typeid" , cAna.nTypeId ); + elAna.setAttribute( "rec_chnl" , cAna.nCh ); + elAnas.appendChild( elAna ); + } + } + + } + QDomElement elBins = d->ownerDocument().createElement( "Binaries" ); + if( !elBins.isNull() ) + { + elComponent.appendChild( elBins ); + for( int k = 0; k < cmp.m_BinList.count(); k++) + { + CLBQBinary& cBin = cmp.m_BinList[k]; + QDomElement elBin = d->ownerDocument().createElement( "Binary" ); + if( !elBin.isNull() ) + { + elBin.setAttribute( "desc" , cBin.sDesc ); + elBin.setAttribute( "channel" , cBin.nCh ); + elBin.setAttribute( "relay_act" , cBin.nRelayAct ); + elBin.setAttribute( "recd_cntr" , cBin.nRecd_cntr ); + elBins.appendChild( elBin ); + } + } + } + QDomElement elRelas = d->ownerDocument().createElement( "Relations" ); + if( !elRelas.isNull() ) + { + elComponent.appendChild( elRelas ); + for(int l = 0; l < cmp.m_RelList.count(); l++ ) + { + CLBQRelation& cRela = cmp.m_RelList[l]; + QDomElement elRela = d->ownerDocument().createElement( "Relation" ); + if( !elRela.isNull() ) + { + elRela.setAttribute( "bay_no", cRela.nBayNo ); + elRelas.appendChild( elRela ); + } + } + } + QDomElement elParas = d->ownerDocument().createElement( "Parameters" ); + if( !elParas.isNull() ) + { + elComponent.appendChild( elParas ); + for( int m = 0 ; m < cmp.m_ParamList.count(); m++ ) + { + CLBQParameter& cPara = cmp.m_ParamList[m]; + QDomElement elPara = d->ownerDocument().createElement( "Parameter" ); + if( !elPara.isNull() ) + { + elPara.setAttribute( "desc" ,cPara.sDesc ); + elPara.setAttribute( "value" ,cPara.fValue ); + elPara.setAttribute( "unit" ,cPara.sUnit ); + elParas.appendChild( elPara ); + } + } + } + + } + } +/* + if(!d) + { + return; + } + + QDomElement elOsgList = d->ownerDocument().createElement( "OsgFileTable" ); + + if(!elOsgList.isNull() ) + { + d->appendChild(elOsgList); + + int i = 0; + quint16 sz = 0; + sz = m_sOsgFiles.count(); + for( i=0;iownerDocument().createElement( "OsgFile" ); + elOsg.setAttribute("OsgFile",m_sOsgFiles[i]); + + elOsgList.appendChild(elOsg); + } + } + + QDomElement elDataList = d->ownerDocument().createElement( "NodeDataTable" ); + if(!elDataList.isNull() ) + { + d->appendChild(elDataList); + + int i = 0; + quint16 sz = 0; + sz = m_NodeDatas.count(); + for( i=0;iHasNode()) + continue; + + QDomElement scEle = d->ownerDocument().createElement( nd->TagName() ); + elDataList.appendChild(scEle); + + nd->WriteXml( &scEle ); + } + }*/ +} + + +////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////// +CComtradeFile::CComtradeFile() +:QObject(),m_bIsSeqSample(false),m_nSampleNum(0) +{ + m_sHeadFileText = ""; + m_sStationName = ""; + m_nStationID = -1; + m_sRevisionYear = ""; + m_nChannelTotal = 0; + m_nAnagueNum = 0; + m_nDigitalNum = 0; + m_dLineFreq = 0.0; + m_nNRates = 0.0; + m_bAsciiDataFormat = true; + dTimeMult = 0.0; + m_sDirName = ""; + m_sFileName = ""; + m_strErrReadMsg = ""; + m_strHeadFilePath=""; + m_strConfigFilePath=""; + m_strDataFilePath=""; + m_strInfoFilePath=""; + m_strDispFilePath=""; + + m_bNewFile = false; + m_bSeqFile = false; + m_bNotZeroFile = false; + m_bASCFile = false; + + m_tFirstTime = QDateTime::currentDateTime(); + m_tTriggerTime = QDateTime::currentDateTime(); + + m_nTrigger_ms = 0; + m_nFrist_ms = -6000L; + + m_dSampleRate.resize(0); + m_lSampleAmount.resize(0); + m_SectionList.clear(); + AnalogDataList.clear(); + DigitDataList.clear(); + m_aTimeArray.resize(0); + m_aChMaximumArray.resize(0); + +} + +CComtradeFile::~CComtradeFile() +{ + +} + +CComtradeFile &CComtradeFile::operator=( const CComtradeFile &p ) +{ + AnalogDataList.clear(); + DigitDataList.clear(); + m_LabelList.clear(); + + m_sHeadFileText = p.m_sHeadFileText; //头文件内容 + m_sStationName = p.m_sStationName; //站名 + m_nStationID = p.m_nStationID; //ID + m_sRevisionYear = p.m_sRevisionYear; //版本年号 + + m_dLineFreq = p.m_dLineFreq; //线路频率 + m_nNRates = p.m_nNRates; //采样率块数 + m_dSampleRate = p.m_dSampleRate; //每块以HZ为单位的采样率 + m_lSampleAmount = p.m_lSampleAmount; //每块每通道数据点数 + m_tFirstTime = p.m_tFirstTime; //起始采样时间 + m_tTriggerTime = p.m_tTriggerTime; //触发时间 + m_bAsciiDataFormat = p.m_bAsciiDataFormat;//文件类型ASCII,BIN + dTimeMult = p.dTimeMult; //时间比例,正常1.0 + m_aTimeArray = p.m_aTimeArray; // 时间序列, 微秒数 + m_SectionList = p.m_SectionList; //信息文件内容 + + m_nTrigger_ms = p.m_nTrigger_ms; + m_nFrist_ms = p.m_nFrist_ms; + //{{for 连续可变采样周期 + m_bIsSeqSample = p.m_bIsSeqSample; + m_nSampleNum = p.m_nSampleNum; + //}} + + m_bNewFile = p.m_bNewFile; + m_bSeqFile = p.m_bSeqFile; + m_bNotZeroFile = p.m_bNotZeroFile; + m_bASCFile = p.m_bASCFile; + + int i; + + + for( i = 0;i= (1.0 - 1E-5)) + { + int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); + return(nTick*nOneWidth + nLeft); + } + else + { + int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); + return(int(double(nTick*nOneWidth)*m_DispAttr.m_fZoomX) + nLeft); + } + } + nTick -= m_lSampleAmount[nBlock]; + } + return 0; + +} +//******************************************************************** +// 取时标最大宽度, 不计左边界 +//******************************************************************** +int CComtradeFile::GetMaxWidth() const +{ + if(m_DispAttr.m_fZoomX >= (1.0 - 1E-5)) + { + int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); + return(GetTotalPointAmount()*nOneWidth); + } + else + { + int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); + return(int(double(GetTotalPointAmount()*nOneWidth)*m_DispAttr.m_fZoomX)); + } + return 0; +} +//******************************************************************** +// 取各块波形左边位置, 不计左边界 +//******************************************************************** +int CComtradeFile::GetBlockLeft(int nBlock) const +{ + int nAmt = 0; + for(int i=0; i= (1.0 - 1E-5)) + { + int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); + return(nAmt*nOneWidth); + } + else + { + int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); + return(int(double(nAmt*nOneWidth)*m_DispAttr.m_fZoomX)); + } + return 0; +} +//******************************************************************** +// 取各块波形右边界位置 +// +//******************************************************************** +int CComtradeFile::GetBlockRight(int nBlock) const +{ + if(nBlock<0) return -1; + + int nLeft = GetBlockLeft(nBlock); + int nAmt = m_lSampleAmount[nBlock]; + + if(m_DispAttr.m_fZoomX >= (1.0 - 1E-5)) + { + int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); + return(nAmt*nOneWidth + nLeft); + } + else + { + int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); + return(int(double(nAmt*nOneWidth)*m_DispAttr.m_fZoomX) + nLeft); + } + return 0; +} + +//******************************************************************** +// 根据X位置, 取Tick位置 +//******************************************************************** +double CComtradeFile::GetTick(int XPosition) const +{ + double fPointPos = 0.0; + for(int i=0; i= nBlockLeft && XPosition <= nBlockRight) + { + if(m_DispAttr.m_fZoomX >= (1.0 - 1E-5)) + { + int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+0.05); + fPointPos += double(XPosition-nBlockLeft)/double(nOneWidth); + } + else + { + int nOneWidth = int(0.05+m_DispAttr.m_dGridWidth); + fPointPos += double(XPosition-nBlockLeft)/m_DispAttr.m_fZoomX/double(nOneWidth); + } + return fPointPos; + } + fPointPos += double(m_lSampleAmount[i]); + } + return 0.0; +} + +int CComtradeFile::GetStartTick( int nBlock ) const +{ + int nAmt = 0; + for(int i=0; i= nBlockLeft && xPos <= nBlockRight) + { + long lTime = GetBlockBeginTime(i); + int nPointPos = 0; + + if(m_DispAttr.m_fZoomX >= (1.0 - 1E-5)) + { + int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); + nPointPos = (xPos-nBlockLeft)/nOneWidth; + } + else + { + int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); + nPointPos = int(.5+double(xPos-nBlockLeft)/m_DispAttr.m_fZoomX)/nOneWidth; + } + return (lTime + long(.5+double(nPointPos) * 1000.0 / m_dSampleRate[i])); + } + } + return 0; +} + +int CComtradeFile::GetXPosition(double fTime) +{ + for(int i=0; i= (1.0 - 1E-5)) + { + int nOneWidth = int(m_DispAttr.m_dGridWidth*m_DispAttr.m_fZoomX+.5); + return(nBlockLeft + nTick*nOneWidth); + } + else + { + int nOneWidth = int(.5+m_DispAttr.m_dGridWidth); + return(nBlockLeft + int(double(nTick*nOneWidth)*m_DispAttr.m_fZoomX)); + } + } + } + return 0; +} + + +void CComtradeFile::CaculateChannelAngle( double* dWaveAngle,int /*len*/ ) +{ + int nFirstIdx =0; + int nRate = 0; + for(int block=0; block FREQ_WORK ) + { + unsigned int nSampleNum = m_lSampleAmount[block]; + unsigned int nSampleRate = m_dSampleRate[block]; + + double* pWaveData = new double[nSampleNum]; + double* pRMSData = new double[nSampleNum]; + double* pAngleData = new double[nSampleNum]; + + memset(pWaveData, 0, nSampleNum*sizeof(double)); + memset(pRMSData, 0, nSampleNum*sizeof(double)); + memset(pAngleData, 0, nSampleNum*sizeof(double)); + + int ch =0; + for( ch=0; chm_bShowLabel) return 0L; + + int nLeft,nTop; + for ( int i=0; i0) m_sFileName = sName.left(nPos); + nPos = sName.indexOf(".CFG"); + if(nPos>0) m_sFileName = sName.left(nPos); + nPos = sName.indexOf(".HDR"); + if(nPos>0) m_sFileName = sName.left(nPos); + nPos = sName.indexOf(".INF"); + if(nPos>0) m_sFileName = sName.left(nPos); + + // COMTRADE头文件名 + // + m_strHeadFilePath = m_sDirName; + m_strHeadFilePath += m_sFileName; + m_strHeadFilePath.append( ".HDR" ); + // COMTRADE配置文件名 + // + m_strConfigFilePath = m_sDirName; + m_strConfigFilePath += m_sFileName; + m_strConfigFilePath.append( ".CFG" ); + // COMTRADE数据文件名 + // + m_strDataFilePath = m_sDirName; + m_strDataFilePath += m_sFileName; + m_strDataFilePath.append( ".DAT" ); + // COMTRADE信息文件名 + // + m_strInfoFilePath = m_sDirName; + m_strInfoFilePath += m_sFileName; + m_strInfoFilePath.append( ".INF" ); +} + +bool CComtradeFile::OpenWaveFile(CInfSection& pReadFileParam) +{ + QString sDirName = ""; + QString sFileName = ""; + QString strFileType = ""; + + CEntryList::iterator ite; + for ( ite = pReadFileParam.EntryList.begin(); ite != pReadFileParam.EntryList.end(); ++ite ) + { + QString szName = (*ite).m_sName; + if(szName.compare("path")==0) + sDirName = (*ite).m_sValue; + if(szName.compare("filename")==0) + sFileName = (*ite).m_sValue; + if(szName.compare("filetype")==0) + strFileType = (*ite).m_sValue; + } + + if(sFileName.isEmpty()||sDirName.isEmpty()) + { + m_strErrReadMsg = tr("The Filename is Error!");//空文件名错! + return false; + } + + return OpenWaveFile(sDirName,sFileName); + +} + +bool CComtradeFile::SaveWaveFile(CInfSection& pWriteFileParam) +{ + QString sDirName = ""; + QString sFileName = ""; + QString strFileType = ""; + + CEntryList::iterator ite; + for ( ite = pWriteFileParam.EntryList.begin(); ite != pWriteFileParam.EntryList.end(); ++ite ) + { + QString szName = (*ite).m_sName; + if(szName.compare("path")==0) + sDirName = (*ite).m_sValue; + if(szName.compare("filename")==0) + sFileName = (*ite).m_sValue; + if(szName.compare("filetype")==0) + strFileType = (*ite).m_sValue; + } + + if(strFileType.compare("ASCII")==0||strFileType.compare("COMTRADE91-ASCII")==0||strFileType.compare("COMTRADE99-ASCII")==0) + { + if(strFileType.compare("COMTRADE99-ASCII")==0) + m_sRevisionYear = "1999"; + else + m_sRevisionYear = ""; + + m_bAsciiDataFormat = true; + } + else if(strFileType.compare("BINARY")==0||strFileType.compare("COMTRADE91-BINARY")==0||strFileType.compare("COMTRADE99-BINARY")==0) + { + if(strFileType.compare("COMTRADE99-BINARY")==0) + m_sRevisionYear = "1999"; + else + m_sRevisionYear = ""; + + m_bAsciiDataFormat = false; + } + else + return false; + + + + if(sFileName.isEmpty()||sDirName.isEmpty()) + { + m_strErrReadMsg = tr("The Filename is Error!");//空文件名错! + return false; + } + + return SaveWaveFile(sDirName,sFileName); + +} +bool CComtradeFile::OpenWaveFile(const QString& strPath, const QString& strFileName ) +{ + CloseWaveFile(); + // Skip tail ".DAT", ".HDR" or ".CFG" + m_sFileName.clear(); + int len = strFileName.length(); + if (strFileName.endsWith(".DAT", Qt::CaseInsensitive)){ + m_sFileName = strFileName.left (len-4); + } + if (m_sFileName.isEmpty() && strFileName.endsWith(".CFG", Qt::CaseInsensitive)){ + m_sFileName = strFileName.left (len-4); + } + if (m_sFileName.isEmpty() && strFileName.endsWith(".HDR", Qt::CaseInsensitive)){ + m_sFileName = strFileName.left (len-4); + } + if (m_sFileName.isEmpty() && strFileName.endsWith(".INF", Qt::CaseInsensitive)){ + m_sFileName = strFileName.left (len-4); + } + if (m_sFileName.isEmpty() && strFileName.endsWith(".AUX", Qt::CaseInsensitive)){ + m_sFileName = strFileName.left (len-4); + } + if (m_sFileName.isEmpty()) + m_sFileName = strFileName; + m_strErrReadMsg = ""; + if(m_sFileName.isEmpty()) + { + m_strErrReadMsg = tr("The Filename is Error!");//空文件名错! + return false; + } + QDir directory(strPath); + if (!directory.exists()){ + m_strErrReadMsg = QString("%1(%2)").arg(tr("The Path is Error!")).arg(strPath); + return false; + } + m_strHeadFilePath.clear(); + m_strConfigFilePath.clear(); + m_strDataFilePath.clear(); + m_strInfoFilePath.clear(); + m_strLBQFilePath.clear(); + QFileInfoList waveFiles = directory.entryInfoList(); + int cnt = waveFiles.count(); + int validFileCnt = 0; + for (int i = 0; i < cnt; ++i) + { + QString fileName = waveFiles[i].fileName(); + QString sFileNameWithNoSuffix = fileName.left(fileName.count()-4); + if ( waveFiles[i].isFile() && sFileNameWithNoSuffix.toLower()==m_sFileName.toLower() ) + { + validFileCnt++; + if (fileName.endsWith(".HDR", Qt::CaseInsensitive)) + m_strHeadFilePath = waveFiles[i].absoluteFilePath(); + else if (fileName.endsWith(".CFG", Qt::CaseInsensitive)) + m_strConfigFilePath = waveFiles[i].absoluteFilePath(); + else if (fileName.endsWith(".DAT", Qt::CaseInsensitive)) + m_strDataFilePath = waveFiles[i].absoluteFilePath(); + else if (fileName.endsWith(".INF", Qt::CaseInsensitive)) + m_strInfoFilePath = waveFiles[i].absoluteFilePath(); + else if (fileName.endsWith(".AUX", Qt::CaseInsensitive)) + m_strLBQFilePath = waveFiles[i].absoluteFilePath(); + else + validFileCnt--; + } + if (validFileCnt == 5) + break; + } + + m_sDirName = strPath; + + //QString sTextLine; + //QString sSubString; + + // COMTRADE头文件名 + // + // 读头文件 + // +#ifndef ENGLISH_WAVETOOLS + //{{hujf del for english + ReadHeadFile(); + //}} +#endif + + // COMTRADE配置文件名 + // + + //读配置文件 + // + if( !ReadConfFile() ) + { + CloseWaveFile(); + return false; + } + + // 打开数据文件 + //{{for 连续可变采样周期 + bool bRet = true; + if( m_bIsSeqSample ) + bRet = ReadSeqDataFile(); + else + bRet = ReadDataFile(); + //}} + if( !bRet ) + { + CloseWaveFile(); + return false; + } + + // COMTRADE信息文件名 + // + + if( CWaveEnv::GetInst()->m_bExtensive ) + TransToContinus(); + + //录波器配置文件 + + m_LBQConfig.ReadXmlFile( m_strLBQFilePath ); + //属性 + InitDisplyAttr(); + + return true; +} + +bool CComtradeFile::TransToContinus() +{ + int i=0,j=0,k=0,ch=0,nStep=0;//nTick=0, + int nStartTick=0,nAng=0,nValue=0; + double nBeginAng=0.0,nEndAng=0.0; + unsigned char btValue=0; + qint64 nBeTm=0,nEdTm=0; + + int bufflen = m_nNRates*m_nAnagueNum*2+10; + double* dWaveAngle = new double[bufflen]; + memset(dWaveAngle,0.0,sizeof(double)*bufflen); + CaculateChannelAngle( dWaveAngle,bufflen); + + double nRate = 1200.0; + int nSampleNum=0; + for( i=0; i0 ) + nBeTm = m_aTimeArray[nStartTick]; + + int nEndTick = nStartTick+nSampleNum; + if(nEndTick >=m_aTimeArray.size() ) + nEndTick = m_aTimeArray.size()-1; + + nEdTm = m_aTimeArray[nEndTick]; + int nNum = ( nEdTm - nBeTm )*FREQ_SAMPLE*FREQ_WORK/(1000.0*1000.0); + if( i>= m_nNRates -1 ) + nNum++; + + m_lSampleAmount[i] = nNum; + m_dSampleRate[i] = FREQ_SAMPLE*FREQ_WORK; + + //2.各个点的时间 + QLLongArray timeadd; + timeadd.resize(nNum); + //第一段 + for( j=0;j=1&&iFREQ_WORK) + bDiff = true; + + for(ch=0; ch=1) + nBeginAng = dWaveAngle[(i-1)*m_nAnagueNum*2+ch*2+1]; + if( bDiff ) + { + nEndAng = dWaveAngle[(i+1)*m_nAnagueNum*2+ch*2]; + nDelta = (nEndAng - nBeginAng+360.0)/(double)nSampleNum; + } + + nStep = 0; + CAnalogData& anai = AnalogDataList[ch]; + for( k=0;k FREQ_WORK ) + { + if( bAllDP ) + bAllDP = false; + + for( nTicks=0; nTicks0 ) + { + double dMinRule = Ana.TransValueToRaw( m_DispAttr.m_byValueType,MIN_RULER ); + if( dMax < dMinRule ) + dMax = dMinRule; + } + + m_aChMaximumArray[i] = dMax;//CPublic::GetIntergerMax(dMax); + + m_DispAttr.m_strChannelName[i] = Ana.m_sName; + m_DispAttr.m_strChPhaseName[i] = Ana.m_sPhase; + m_DispAttr.m_strChLineCompName[i] = Ana.m_sCCBM; + m_DispAttr.m_strChUnitName[i] = Ana.m_sUnit; + } + + for( i=0; i= 0 || + AnalogDataList[i].m_sUnit.toLower().indexOf("v") >= 0 ) + { + dTempMaxU = qMax(dTempMaxU,m_aChMaximumArray[i]); + } + else if(AnalogDataList[i].m_sUnit.toLower().indexOf("a") >= 0 ) + { + dTempMaxI = qMax(dTempMaxI,m_aChMaximumArray[i]); + } + } + for(i = 0;i= 0 || + AnalogDataList[i].m_sUnit.toLower().indexOf("v") >= 0 ) + { + m_aChMaximumArray[i] = dTempMaxU; + } + else if(AnalogDataList[i].m_sUnit.toLower().indexOf("a") >= 0 ) + { + m_aChMaximumArray[i] = dTempMaxI; + } + } + + for( i=0; i1E-5) + { + m_DispAttr.m_fWaveZoom[i] = double(m_DispAttr.m_dWaveHeight[i])*45.0 + /double(m_aChMaximumArray[i]); + m_DispAttr.m_fWaveZoomRevert[i] = m_DispAttr.m_fWaveZoom[i]; + } + } + + m_DispAttr.m_fTriggerTick = GetPointNoFromTime(m_DispAttr.m_fTriggerTime); + + + //计算合适名称区宽度 + int nNameWidth = 50; + QString sTemp = ""; + CAnalogDataList::Iterator ita; + for( ita = AnalogDataList.begin();ita!=AnalogDataList.end();ita++) + { + sTemp = (*ita).m_sName + (*ita).m_sUnit; + int nLen = (sTemp.length() + 3)*10 + 50; + if( nNameWidthm_nLeftMarginName; + + //检查模拟量相别 + for( ita = AnalogDataList.begin();ita!=AnalogDataList.end();ita++) + { + (*ita).Check(); + } + //检查数字量的变化 + for( itd = DigitDataList.begin();itd!=DigitDataList.end();itd++) + { + (*itd).Check(); + } +/************************************************************************/ +/* 计算基本数值//{{hujf 20080708 */ +/************************************************************************/ + if(m_dLineFreq <= 0) + m_dLineFreq = 50; + + // 计算矢量值 + int Ch=0; + bool bNeed = false; + int nWaveAmt = m_nAnagueNum; + int nTotalPointAmt = GetTotalPointAmount(); + for( Ch=0; Chm_bBaseCompute) + return; + + CAlgorithms algorithms; + int nPos = 0; + int cho = 0; + int chi = 0; + for( nBlks = 0; nBlksnMaxGroup) + nMaxGroup=m_DispAttr.m_nWaveGroup[Ch]; + } + return nMaxGroup; +} +//******************************************************************** +// 取状态最大组数 +// 同一组同一高度. +//******************************************************************** +int CComtradeFile::GetMaxTagsGroupNum() +{ + int nMaxGroup = -1; + for(int Ch=0; ChnMaxGroup) + nMaxGroup=m_DispAttr.m_nTagsGroup[Ch]; + } + return nMaxGroup; +} + +bool CComtradeFile::IsWaveGroupEmpty( int nGroup ) +{ + int ch=0; + for(ch=0; ch300 ) + { + m_sHeadFileText = tr("The Header File's Format is Error");//头文件格式错误 + break; + } + + m_sHeadFileText += sTextLine; + m_sHeadFileText += "\n"; + } + + file.close(); + return true; +} + +bool CComtradeFile::ReadConfFile() +{ + QString sTextLine; + QString sSubString; + m_bIsSeqSample = false; + int i; + // 打开配置文件 + // + QFile file( m_strConfigFilePath ); + if ( !file.open( QIODevice::ReadOnly ) ) + { + m_strErrReadMsg = tr("Config Files Open Failed");//不能打开相应的配置文件 + m_strErrReadMsg.append( m_strConfigFilePath ); + return false; + } + + QTextStream ConfigFile( &file ); + autoSetTextStreamCodec( ConfigFile ); + + m_nReadLine = 1; + // 站名 + if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ){ + return false; + } + if(!CPublic::GetSubString(sTextLine,0,sSubString)){ + return false; + } + m_sStationName = sSubString; + + // 站号 + if(!CPublic::GetSubString(sTextLine,1,sSubString)) + { + return false; + } + m_nStationID = sSubString.toInt(); + + // 版本年号 + if(CPublic::GetSubString(sTextLine,2,sSubString)) + m_sRevisionYear = sSubString; + + if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) + return false; + // 通道个数 + if(!CPublic::GetSubString(sTextLine,0,sSubString)) return false; + m_nChannelTotal = sSubString.toInt(); + + + // 模拟量,数字量个数 + m_nAnagueNum = 0; + m_nDigitalNum = 0; + for(i=1; i<=2; i++) + { + if(!CPublic::GetSubString(sTextLine,i,sSubString)) continue; + + int nCount = sSubString.length(); + if(nCount>1) + { + if(sSubString.right(1)=="A" || sSubString.right(1)=="a") + { + QString sNumStr = sSubString.left(nCount-1); + m_nAnagueNum = sNumStr.toInt(); + } + if(sSubString.right(1)=="D" || sSubString.right(1)=="d") + { + QString sNumStr = sSubString.left(nCount-1); + m_nDigitalNum = sNumStr.toInt(); + } + } + } + + if(m_nChannelTotal != m_nAnagueNum+m_nDigitalNum) + { + m_strErrReadMsg = tr("Config File, Line") + " " + QString::number(m_nReadLine) + ", " + tr("Channel Count Error");//配置文件第,行: 通道数目错! + return false; + } + + if((m_nAnagueNum > MAX_WAVES) || (m_nDigitalNum > MAX_TAGS)) + { + m_strErrReadMsg = tr("Config File, Line") + " " + QString::number(m_nReadLine) + ", " + tr("Channel Count Over Limited") + "(2048A,2048D)!";//通道数目越限 + return false; + } + + // 模拟量配置数组, 清除,预置 + AnalogDataList.clear(); + + // 读入模拟量配置 + // + for(i=0; i MAX_BLOCKS) + return false; + + //{{for 连续可变采样周期 + if( m_nNRates <= 0 ) + { + m_nNRates = 0; + m_bIsSeqSample = true; + m_dSampleRate.resize(0); + m_lSampleAmount.resize(0); + + if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) + return false; + // 采样率 + if(!CPublic::GetSubString(sTextLine,0,sSubString)) return false; + // 采样数 + if(!CPublic::GetSubString(sTextLine,1,sSubString)) return false; + m_nSampleNum = sSubString.toLong(); + } + else + { + //{{hujf for malai 20080125(每段记录的是本段最后一个采样点的序号,而不是本段的采样个数) +// int nBeginStamp = 0; + //}} + m_dSampleRate.resize(m_nNRates); + m_lSampleAmount.resize(m_nNRates); + for(i=0; im_bEndStamp ) + //{ + m_lSampleAmount[i] = sSubString.toLong(); + //} + //else + //{ + // nEndStamp = sSubString.toLong(); + // m_lSampleAmount[i] = nEndStamp - nBeginStamp; + //} + + if( m_lSampleAmount[i]<=0) + m_lSampleAmount[i] = 0; + //nBeginStamp = nEndStamp; + //}} + } + } + //{判断每段最后的序号是否是递增的,m_bASCFile + for(int iTemp = 0; iTemp < m_nNRates - 1; iTemp++) + { + + if( ( m_lSampleAmount[iTemp+1] - m_lSampleAmount[iTemp] ) > 0 ) + { + m_bASCFile = true; + } + else + { + m_bASCFile = false; + } + } + //} + //}} + // 读入起始时间 + // + if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) + return false; + QString sdate = sTextLine.section(",",0,0); + QString sutime = sTextLine.section(",",1,1); + QString sd = sdate.section("/",0,0); + QString sm = sdate.section("/",1,1); + QString sy = sdate.section("/",2,2); + QString stime = sutime.section(".",0,0); + QString smicro = sutime.section(".",1,1); + QString sh = stime.section(":",0,0); + QString smin = stime.section(":",1,1); + QString ssec = stime.section(":",2,2); + + int wMonth = sm.toInt(); + int wDay = sd.toInt(); + int wYear = 0; + /*if(wMonth > 12) + { + int nTemp = wDay; + wDay = wMonth; + wMonth = nTemp; + }*/ + + if(CWaveEnv::GetInst()->m_nDateSetOption == 0) + { + int nTemp = wDay; + wDay = wMonth; + wMonth = nTemp; + } + if(sy.length()>2) + { + wYear = sy.toInt(); + } + else + { + wYear = sy.toInt(); + if(wYear>80) + wYear += 1900; + else wYear += 2000; + } + + int wHour = sh.toInt(); + int wMinute = smin.toInt(); + int wSecond = ssec.toInt(); + int wMilliseconds = smicro.toInt(); + if( wMilliseconds>1000 ) + wMilliseconds = wMilliseconds/1000; + + m_tFirstTime.setDate(QDate(wYear,wMonth,wDay)); + m_tFirstTime.setTime(QTime(wHour,wMinute,wSecond,wMilliseconds)); + + // 读入故障时间 + // + if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) + return false; + + sdate = sTextLine.section(",",0,0); + sutime = sTextLine.section(",",1,1); + sd = sdate.section("/",0,0); + sm = sdate.section("/",1,1); + sy = sdate.section("/",2,2); + stime = sutime.section(".",0,0); + smicro = sutime.section(".",1,1); + sh = stime.section(":",0,0); + smin = stime.section(":",1,1); + ssec = stime.section(":",2,2); + + wMonth = sm.toInt(); + wDay = sd.toInt(); + /*if(wMonth > 12) + { + int nTemp = wDay; + wDay = wMonth; + wMonth = nTemp; + }*/ + + if(CWaveEnv::GetInst()->m_nDateSetOption == 0) + { + int nTemp = wDay; + wDay = wMonth; + wMonth = nTemp; + } + if(sy.length()>2) + { + wYear = sy.toInt(); + } + else + { + wYear = sy.toInt(); + if(wYear>80) + wYear += 1900; + else wYear += 2000; + } + + wHour = sh.toInt(); + wMinute = smin.toInt(); + wSecond = ssec.toInt(); + wMilliseconds = smicro.toInt(); + if( wMilliseconds>1000 ) + wMilliseconds = wMilliseconds/1000; + + m_tTriggerTime.setDate(QDate(wYear,wMonth,wDay)); + m_tTriggerTime.setTime(QTime(wHour,wMinute,wSecond,wMilliseconds)); + + GetFirstMicroSecs(); + + m_DispAttr.m_fBaseTick = 0; + m_DispAttr.m_fBaseTime = GetPointTime(0); + + if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) + return false; + + if(!CPublic::GetSubString(sTextLine,0,sSubString)) return false; + sSubString = sSubString.trimmed(); + QString sFileType = sSubString.toUpper(); + if( 0==sFileType.compare("ASCII") ) + m_bAsciiDataFormat = true; + else if( 0==sFileType.compare("BINARY") ) + m_bAsciiDataFormat = false; + else + { + Q_ASSERT(false); + /*2008-1-5 zhn del for initial value of reference to non-const must be an lvalue + m_strErrReadMsg.sprintf("%s%d%s",QObject::tr("配置文件 第").toAscii(),m_nReadLine,QObject::tr("行: 格式错!").toAscii()); + */ + //{{2008-1-5 zhn add for initial value of reference to non-const must be an lvalue + m_strErrReadMsg = QString("%1 %2%, 3").arg(tr("Config File, Line")).arg(m_nReadLine).arg(tr("Format Error!"));//格式错误 + //}} + return false; + + } + // 读入时间系数 + // + if( !CPublic::ReadStreamLine(ConfigFile,sTextLine,m_nReadLine) ) + { + dTimeMult = 1.0; + } + else + { + if(CPublic::GetSubString(sTextLine,0,sSubString)) + dTimeMult = sSubString.toDouble(); + } + file.close(); + return true; +} +//非连续采样的波形 +bool CComtradeFile::ReadDataFile() +{ + int i; + int nSamplePointNum = 0; + int nPointNum = 0; + + if(m_bAsciiDataFormat) + { + if(m_bASCFile) + {//先判断cfg文件中采样数是否是递增的 +// QFile tempFile(m_strDataFilePath); +// if ( !tempFile.open( QIODevice::ReadOnly ) ) +// { +// m_strErrReadMsg = QObject::tr("不能打开相应的数据文件 "); +// m_strErrReadMsg.append( m_strConfigFilePath ); +// return false; +// } +// //{{下面从dat文件中读取第一行与最后一行的序号,并判断是否为新文件 +// //2009-06-20 +// QTextStream tempStream( &tempFile ); +// QString sTempLine = ""; +// QString sTempString = ""; +// int nFirstNO = 0; +// int nLastNO = 0; +// int nTempNum = 1; +// //读第一行数据的第一个数,是序号 +// if(!CPublic::ReadStreamLine( tempStream, sTempLine, nTempNum ) ) +// return false; +// if( !CPublic::GetSubString ( sTempLine, 0, sTempString ) ) +// return false; +// //读第一行序号 +// nFirstNO = sTempString.toInt(); +// //循环读取数据,直到最后一行 +// while( CPublic::ReadStreamLine( tempStream, sTempLine, nTempNum ) ) ; +// //读取最后一行数据的序号 +// if( !CPublic::GetSubString( sTempLine, 0, sTempString ) ) +// return false; +// nLastNO = sTempString.toInt(); +// tempFile.close(); +// //判断第一行序号是否为0,0:老文件,1:新文件 +// if( nFirstNO == 0 ) +// m_bNotZeroFile = false; +// else if( nFirstNO == 1 ) +// m_bNotZeroFile = true; +// //判断最后一行序号是否与记录的最后一块数据的个数相同,相同即为新文件,不同为老文件 +// if( nLastNO == m_lSampleAmount[m_nNRates - 1] ) +// m_bSeqFile = true; +// else +// m_bSeqFile = false; + //通过三个条件来判断是否为新文件,若是新文件, + //则要将m_lSampleAmount中的数据进行处理,换算成每块数据的个数 +// if( m_bSeqFile && m_bNotZeroFile) +// { +// m_bNewFile = true; + for( int k = m_nNRates - 1; k > 0; k--) + m_lSampleAmount[k] = m_lSampleAmount[k] - m_lSampleAmount[k-1]; +// } +// else +// { +// m_bNewFile = false; +// } + } + //}}读取第一行与最后一行的序号 + + nSamplePointNum = GetTotalPointAmount(); + nPointNum = GetNumberOfWaveTags(); + + if(nSamplePointNum<=0 || nPointNum<=0) + return false; + + // 清除, 设置数组 + // + for( i=0; i0) + BlkBeginTime_us +=(long)( double(1000000.0)/((double)m_dSampleRate[TR-1]) + 0.5 ); + + if( nRates>0 ) + { + for( PT = 0; PT0) + BlkBeginTime_us+=(long)(double(1.0)*(1000000.0/((double)nRates))+0.5); + + if( nRates>0 ) + { + for( PT = 0; PT= (nPointNum-1) ) +// {//本行最后一个数据 +// if( EOF==fscanf( pFile,"%d",&nData) ) +// { +// continue; +// } +// //换行 +// if( EOF==fscanf( pFile,",\n"/*,pBuf*/) ) +// { +// continue; +// } +// } +// else +// { +// if( EOF==fscanf( pFile,"%d,",&nData) ) +// continue; +// } + +// // 设置波形最大值 +// if(nCol=0) +// { +// // 设置数据数组 +// if(nRow < nSamplePointNum ) +// { +// CAnalogData& AnaData = AnalogDataList[nCol]; +// AnaData.m_dlSampleData[nRow] = nData; +// } +// } +// else if(nCol < nPointNum) +// { +// // 设置数据数组 +// if(nRow < nSamplePointNum ) +// { +// CDigitData& DgtData = DigitDataList[nCol - m_nAnagueNum]; +// DgtData.m_bySampleData[nRow] = nData; +// } +// } + +// } + +// nRow ++; // 换行 +// } +// } +// fclose(pFile); + + QFile file( m_strDataFilePath ); + if ( !file.open(QIODevice::ReadOnly) ) + { + m_strErrReadMsg = tr("Data File Open Failed"); + m_strErrReadMsg.append( m_strDataFilePath ); + return false; + } + + int nLineNum = 1; + int nRow = 0; // 数据行 + int nCol = 0; // 数据列 + for ( int nRateIdx=0; nRateIdx listData = QString(file.readLine()).simplified().split(","); + + if ( listData.count() != m_nAnagueNum + m_nDigitalNum + 2 ) + { + m_strErrReadMsg = QString("数据文件 %1 行格式不正确").arg(nLineNum); + return false; + } + + nLineNum++; + int nData = 0; + for(nCol=0; nCol=0) + { + // 设置数据数组 + if(nRow < nSamplePointNum ) + { + CAnalogData& AnaData = AnalogDataList[nCol]; + AnaData.m_dlSampleData[nRow] = nData; + } + } + else if(nCol < nPointNum) + { + // 设置数据数组 + if(nRow < nSamplePointNum ) + { + CDigitData& DgtData = DigitDataList[nCol - m_nAnagueNum]; + DgtData.m_bySampleData[nRow] = nData; + } + } + } + nRow++; // 换行 + } + } + file.close(); + } + else + { + int nBitsBytes = (m_nDigitalNum+15)/16*2; + WORD wDataWidth = 8+m_nAnagueNum*2+nBitsBytes; + + //{{判断文件是否是新格式的文件 + if(m_bASCFile) + { +// QFile fileTemp( m_strDataFilePath ); +// if ( !fileTemp.open( QIODevice::ReadOnly ) ) +// { +// m_strErrReadMsg = QObject::tr("不能打开相应的数据文件 "); +// m_strErrReadMsg.append( m_strDataFilePath ); +// return false; +// } +// QDataStream DataFileTemp( &fileTemp ); +// char *pDataTemp = new char[wDataWidth+10]; +// +// DataFileTemp.readRawData(pDataTemp,wDataWidth); +// DWORD dFirstIndex = MAKELONG(MAKEWORD(pDataTemp[0],pDataTemp[1]),MAKEWORD(pDataTemp[2],pDataTemp[3])); +// if(dFirstIndex == 0) +// { +// m_bNotZeroFile = false; +// } +// else if(dFirstIndex == 1) +// { +// m_bNotZeroFile = true; +// } +// int i = 0; +// while(!DataFileTemp.atEnd()) +// { +// DataFileTemp.readRawData(pDataTemp,wDataWidth); +// i++; +// } + + +// for(int nRateIdx = 0; nRateIdx < m_nNRates; nRateIdx++) +// { +// int nPointAmt = m_lSampleAmount[nRateIdx]; +// if(nRateIdx == 0) +// { +// DataFileTemp.readRawData(pDataTemp,wDataWidth); +// DWORD dFirstIndex = MAKELONG(MAKEWORD(pDataTemp[0],pDataTemp[1]),MAKEWORD(pDataTemp[2],pDataTemp[3])); +// if(dFirstIndex == 0) +// { +// m_bNotZeroFile = false; +// } +// else if(dFirstIndex == 1) +// { +// m_bNotZeroFile = true; +// } +// for(int p = 1; p 0) +// { +// for(int p = 0; p 0; k--) + m_lSampleAmount[k] = m_lSampleAmount[k] - m_lSampleAmount[k-1]; +// } +// else +// { +// m_bNewFile = false; +// } + } + //}}判断文件是否是新格式的文件 + + nSamplePointNum = GetTotalPointAmount(); + nPointNum = GetNumberOfWaveTags(); + + if(nSamplePointNum<=0 || nPointNum<=0) + return false; + + // 清除, 设置数组 + // + for( i=0; i0) + BlkBeginTime_us1 +=(long)( double(1000000.0)/((double)m_dSampleRate[TR1-1]) + 0.5 ); + + if( nRates1>0 ) + { + for( PT1 = 0; PT10) + BlkBeginTime_us1+=(long)(double(1.0)*(1000000.0/((double)nRates1))+0.5); + + if( nRates1>0 ) + { + for( PT1 = 0; PT1= nPointNum-1) +// {//本行最后一个数据 +// if( EOF==fscanf( pFile,"%d\n",&nData ) ) +// continue; +// } +// else +// { +// if( EOF==fscanf( pFile,"%d,",&nData) ) +// continue; +// } + +// bool bValid = true; +// if(nData>99998||nData<-99999) +// { +// nData = 0; +// bValid = false; +// } +// // 设置波形最大值 +// if(nCol=0) +// { +// // 设置数据数组 +// CAnalogData& AnaData = AnalogDataList[nCol]; +// AnaData.m_dlSampleData[nSampleIndex] = nData; +// AnaData.m_bSampleValid[nSampleIndex] = bValid; +// m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; +// } +// else if(nCol < nPointNum) +// { +// // 设置数据数组 +// CDigitData& DgtData = DigitDataList[nCol - m_nAnagueNum]; +// DgtData.m_bySampleData[nSampleIndex] = nData; +// m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; +// } +// } +// } +// fclose(pFile); + + QFile file( m_strDataFilePath ); + if ( !file.open(QIODevice::ReadOnly) ) + { + m_strErrReadMsg = tr("Data File Open Failed"); + m_strErrReadMsg.append( m_strDataFilePath ); + return false; + } + + int nCol = 0; // 数据列 + qlonglong nTimeStamp = 0; + for( nSampleIndex = 0;nSampleIndex listData = QString(file.readLine()).simplified().split(","); + if(listData.size()99998||nData<-99999) + { + nData = 0; + bValid = false; + } + // 设置波形最大值 + if(nCol=0) + { + // 设置数据数组 + CAnalogData& AnaData = AnalogDataList[nCol]; + AnaData.m_dlSampleData[nSampleIndex] = nData; + AnaData.m_bSampleValid[nSampleIndex] = bValid; + m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; + } + else if(nCol < nPointNum) + { + // 设置数据数组 + CDigitData& DgtData = DigitDataList[nCol - m_nAnagueNum]; + DgtData.m_bySampleData[nSampleIndex] = nData; + m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; + } + } + } + file.close(); + } + else + { + // 打开数据文件 + // + QFile file( m_strDataFilePath ); + if ( !file.open(QIODevice::ReadOnly) ) + { + m_strErrReadMsg = tr("Data File Open Failed"); + m_strErrReadMsg.append( m_strDataFilePath ); + return false; + } + + QDataStream DataFile( &file ); + // All digitals are combined in even bytes + int nBitsBytes = (m_nDigitalNum+15)/16*2; + WORD wDataWidth = 8+m_nAnagueNum*2+nBitsBytes; + char *pData = new char[wDataWidth+10]; + qlonglong nTimeStamp = 0; + int ch; + + int nSampleIndex = 0; + for( nSampleIndex = 0;nSampleIndex32767||nData<-32767) + { nData = 0; bValid = false;} + + // 设置数据数组 + AnaData.m_dlSampleData[nSampleIndex] = nData; + AnaData.m_bSampleValid[nSampleIndex] = bValid; + m_PointTimeArray[nSampleIndex] = m_lFirstMicroSecs + nTimeStamp/1000; + } + + for(ch=0; ch0) + { + nCurStep = nCurStamp - nPrevStamp; + if( nCurStep != nPrevStep ) + { + m_nNRates++; + nCurRate = 1000000.0/(double)(nCurStep); + m_dSampleRate.resize( m_nNRates ); + m_lSampleAmount.resize( m_nNRates ); + + m_dSampleRate[m_nNRates-1] = nCurRate; + if( m_nNRates >=2 ) + { + m_lSampleAmount[m_nNRates-2] = nSampleIndex-1-nPrevBlockIndex; + nPrevBlockIndex = nSampleIndex-1; + } + } + nPrevStep = nCurStep; + } + nPrevStamp = nCurStamp; + } + m_lSampleAmount[m_nNRates-1] = nSampleIndex-1-nPrevBlockIndex; + + return true; +} + +bool CComtradeFile::ReadInfFile() +{ + if ( CSectionOperate::ReadFile( m_SectionList, m_strInfoFilePath ) ) + { + m_strErrReadMsg = tr("Info File Open Failed");//不能打开相应的信息文件 + m_strErrReadMsg.append( m_strInfoFilePath ); + return false; + } + return true; +} + +bool CComtradeFile::SaveWaveFile(const QString& strPath, const QString& strFileName ) +{ + // Skip tail ".DAT", ".HDR" or ".CFG" + m_sDirName = strPath; + QString sName = strFileName.toUpper(); + m_sFileName = strFileName; + + int nPos = sName.indexOf(".DAT"); + if(nPos>0) m_sFileName = strFileName.left(nPos); + nPos = sName.indexOf(".CFG"); + if(nPos>0) m_sFileName = strFileName.left(nPos); + nPos = sName.indexOf(".HDR"); + if(nPos>0) m_sFileName = strFileName.left(nPos); + nPos = sName.indexOf(".INF"); + if(nPos>0) m_sFileName = strFileName.left(nPos); + + m_strErrReadMsg = ""; + if(m_sFileName.isEmpty()) + { + m_strErrReadMsg = tr("The Filename is Error!"); + return false; + } + + QString sTextLine; + QString sSubString; + + // COMTRADE头文件名 + // + m_strHeadFilePath = m_sDirName; + m_strHeadFilePath += m_sFileName; + m_strHeadFilePath.append( ".HDR" ); + // 写头文件 + // + WriteHeadFile(); + + // COMTRADE配置文件名 + // + m_strConfigFilePath = m_sDirName; + m_strConfigFilePath += m_sFileName; + m_strConfigFilePath.append( ".CFG" ); + + //写配置文件 + // + if(!WriteConfFile()) + return false; + + // COMTRADE数据文件名 + // + m_strDataFilePath = m_sDirName; + m_strDataFilePath += m_sFileName; + m_strDataFilePath.append( ".DAT" ); + + // 写数据文件 + // + if(!WriteDataFile()) + return false; + + // COMTRADE信息文件名 + // + m_strInfoFilePath = m_sDirName; + m_strInfoFilePath += m_sFileName; + m_strInfoFilePath.append( ".INF" ); + + // 保存信息文件 + // + WriteInfFile(); + + //保存标注文件 + m_LabelList.SaveLabelFile(m_sDirName,m_sFileName); + QString m_sStrFile = m_sDirName + "\\" + m_sFileName; + m_sStrFile.append( ".AUX" ); + m_LBQConfig.WriteXmlFile(m_sStrFile); + return true; +} + +bool CComtradeFile::WriteHeadFile() +{ + //写头文件 + // + QFile file( m_strHeadFilePath ); + if ( !file.open( QIODevice::WriteOnly ) ) + return true; + QTextStream ts( &file ); + ts << (m_sHeadFileText); + file.close(); + return true; +} + +bool CComtradeFile::WriteConfFile() +{ + //保存配置文件 + // + QFile file( m_strConfigFilePath ); + if ( !file.open( QIODevice::WriteOnly ) ) + { + m_strErrReadMsg = tr("Config Files Open Failed");//不能打开相应的配置文件 + m_strErrReadMsg.append( m_strConfigFilePath ); + return false; + } + + QString sFileType = "ASCII"; + if( !m_bAsciiDataFormat ) + sFileType = "BINARY"; + + QTextStream ConfigFile( &file ); + + ConfigFile<<(m_sStationName)<=2000) + nYear -= 2000; + else + nYear -= 1900; + + + ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<=2000) + nYear -= 2000; + else + nYear -= 1900; + + ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<nIndex) + nTime = m_aTimeArray[nIndex]; + sprintf(buf,"%12d",nTime); + DataFile<nIndex) + n2 = m_aTimeArray[nIndex]; + + DataFile<0) sFileName = sName.left(nPos); + nPos = sName.indexOf(".CFG"); + if(nPos>0) sFileName = sName.left(nPos); + nPos = sName.indexOf(".HDR"); + if(nPos>0) sFileName = sName.left(nPos); + nPos = sName.indexOf(".INF"); + if(nPos>0) sFileName = sName.left(nPos); + + QString strConfigFilePath = sDirName; + strConfigFilePath.append("/"); + strConfigFilePath += sFileName; + strConfigFilePath.append( ".CFG" ); + + QString sTextLine; + QString sSubString; +// bool bValidConfigFile = false; + // 打开配置文件 + // + QFile file( strConfigFilePath ); + if ( !file.open( QIODevice::ReadOnly ) ) + return false; + + QTextStream ConfigFile( &file ); + autoSetTextStreamCodec( ConfigFile ); + + int nLineNum = 1; + while(!ConfigFile.atEnd()) + { + int ChanelsNum = 0,TagsNum = 0,ChanTotal = 0; + // 站名 + sTextLine = ConfigFile.readLine(); + if(QString()==sTextLine) break; + nLineNum++; + //第一行跳过 + sTextLine = ConfigFile.readLine(); + if(QString()==sTextLine) break; + nLineNum++; + // 通道个数 + if(!CPublic::GetSubString(sTextLine,0,sSubString)) break; + ChanTotal = sSubString.toInt(); + + // 模拟量,数字量个数 + int i; + for( i=1; i<=2; i++) + { + if(!CPublic::GetSubString(sTextLine,i,sSubString)) continue; + + int nCount = sSubString.length(); + if(nCount>1) + { + if(sSubString.right(1)=="A" || sSubString.right(1)=="a") + { + QString sNumStr = sSubString.left(nCount-1); + ChanelsNum = sNumStr.toInt(); + } + if(sSubString.right(1)=="D" || sSubString.right(1)=="d") + { + QString sNumStr = sSubString.left(nCount-1); + TagsNum = sNumStr.toInt(); + } + } + } + + if(ChanTotal != ChanelsNum+TagsNum) + break; + + if((ChanelsNum > MAX_WAVES) || (TagsNum > MAX_TAGS)) + break; + + // 模拟量配置数组, 清除,预置 + pAnalogList.clear(); + + // 读入模拟量配置 + // + for(i=0; i=2000) + nYear -= 2000; + else + nYear -= 1900; + + + ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<=2000) + nYear -= 2000; + else + nYear -= 1900; + + ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<=2000) + nYear -= 2000; + else + nYear -= 1900; + + + ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<=2000) + nYear -= 2000; + else + nYear -= 1900; + + ConfigFile << CPublic::GetDateString(pdate.month(),2)<<'/'<& listAnalog , QList& listDigit ,float fSampleRate,int nSampleNum) +{ +// int nCount = AnalogDataList.count() ; + CAnalogDataList anaDataList; + CDigitDataList dgtDataList; + for(int i = 0 ;i 0) + { + m_dSampleRate[0] = fSampleRate ; + m_lSampleAmount[0] = nSampleNum; + } + + } + // 模拟量,数字量个数 + m_nAnagueNum = listAnalog.count(); + m_nDigitalNum = listDigit.count(); + m_nChannelTotal = m_nAnagueNum+m_nDigitalNum ; + +} + +bool CComtradeFile::WriteConfFile(const QString& strCfgPathFileName) +{ + m_strConfigFilePath = strCfgPathFileName ; + return WriteConfFile(); +} + +//读取CFG路径文件名 +bool CComtradeFile::ReadConfFile(const QString& strCfgPathFileName) +{ + //char sz[1024]; + //strcpy(sz,strCfgPathFileName.toAscii().data()); + //strcpy(sz,m_strConfigFilePath.toAscii().data()); + if (m_strConfigFilePath == strCfgPathFileName) + return true; + m_strConfigFilePath = strCfgPathFileName; + bool result = ReadConfFile(); + return result; +} + + + +//读取文件选择的文件 +bool CComtradeFile::ReadSelectionFile(const QString& strSelectionPathFileName,int& nTotalAnalogAmount,int& nTotalDigitalAmount,QList& listAnalog,QList& listDigital) +{ + nTotalAnalogAmount = 0 ; + nTotalDigitalAmount = 0 ; + listAnalog.clear(); + listDigital.clear(); + + QFile file( strSelectionPathFileName ); + + if ( file.open( QIODevice::ReadOnly|QIODevice::Text ) ) + { + + QTextStream stream( &file ); + autoSetTextStreamCodec( stream ); + + QString line; + QString lineTrimmed; +// int n = 1; + QStringList list; + while ( !stream.atEnd() ) { + //Untrimmed + line = stream.readLine(); + lineTrimmed = line.trimmed(); + list< 0) + { + QStringList listSection = list[0].split(","); + if (listSection.count() < 2 ) + return false; + if (listSection.count()>=2) + { + nTotalAnalogAmount = listSection[0].trimmed().toInt(); + nTotalDigitalAmount = listSection[1].trimmed().toInt(); + } + } + + //2.读取选中的模拟通道 + if (list.count() > 1) + { + QStringList listSection = list[1].split(","); + for(int i = 0 ; i < listSection.count(); i++) + { + + QString strChan = listSection[i]; + + if ("" == strChan.trimmed()) continue; + listAnalog< 2) + { + + QStringList listSection = list[2].split(","); + for(int i = 0 ; i < listSection.count(); i++) + { + QString strChan = listSection[i]; + if ("" == strChan.trimmed()) continue; + listDigital<& listAnalog,QList& listDigital) +{ + if (!szData) + return false; + if ("" == m_strConfigFilePath ) + { + return false; + } + + if (wLen < (nTotalAnalogAmount*2 +nTotalDigitalAmount/8)*24) + return false; + //CloseWaveFile(); + + //设置当前DataFile路径文件名称 + //m_strDataFilePath = strRealDataPathFileName; + + //设置起始时间 + m_tFirstTime = QDateTime::currentDateTime(); + //设置触发时间 + m_tTriggerTime = QDateTime::currentDateTime(); + + QString sTextLine; + QString sSubString; + int i; + int nSamplePointNum = GetTotalPointAmount(); + int nPointNum = GetNumberOfWaveTags(); + + if(nSamplePointNum<=0 || nPointNum<=0) + return false; + + // 清除, 设置数组 + // + for( i=0; im_bEndStamp ) + { + double BlkBeginTime_us = 0.0; + for( TR=0; TR0) + BlkBeginTime_us +=(long)( double(1000000.0)/((double)m_dSampleRate[TR-1]) + 0.5 ); + + if( nRates>0 ) + { + for( PT = 0; PT0) + BlkBeginTime_us+=(long)(double(1.0)*(1000000.0/((double)nRates))+0.5); + + if( nRates>0 ) + { + for( PT = 0; PT& listAnalog,QList& listDigital) +{ + if ("" == m_strConfigFilePath ) + { + return false; + } + + //CloseWaveFile(); + + //设置当前DataFile路径文件名称 + m_strDataFilePath = strRealDataPathFileName; + + //设置起始时间 + QFileInfo dataFileInfo(m_strDataFilePath); + m_tFirstTime.setTime_t(dataFileInfo.fileName().toUInt() - 8*3600); + //设置触发时间 + m_tTriggerTime.setTime_t(dataFileInfo.fileName().toUInt() - 8*3600 ); + + QString sTextLine; + QString sSubString; + int i; + int nSamplePointNum = GetTotalPointAmount(); + int nPointNum = GetNumberOfWaveTags(); + + if(nSamplePointNum<=0 || nPointNum<=0) + return false; + + // 清除, 设置数组 + // + for( i=0; i0 ) + { + for(int PT = 0; PTm_bEndStamp ) + { + double BlkBeginTime_us = 0.0; + for( TR=0; TR0) + BlkBeginTime_us +=(long)( double(1000000.0)/((double)m_dSampleRate[TR-1]) + 0.5 ); + + if( nRates>0 ) + { + for( PT = 0; PT0) + BlkBeginTime_us+=(long)(double(1.0)*(1000000.0/((double)nRates))+0.5); + + if( nRates>0 ) + { + for( PT = 0; PT0 ) + { + for(int PT = 0; PTm_bEndStamp ) + { + double BlkBeginTime_us = 0.0; + for( TR=0; TR0) + BlkBeginTime_us +=(long)( double(1000000.0)/((double)m_dSampleRate[TR-1]) + 0.5 ); + + if( nRates>0 ) + { + for( PT = 0; PT0) + BlkBeginTime_us+=(long)(double(1.0)*(1000000.0/((double)nRates))+0.5); + + if( nRates>0 ) + { + for( PT = 0; PTm_bExtensive ) + TransToContinus(); + //属性 + InitDisplyAttr(); + + return true; + +} + +bool CComtradeFile::OpenRealWaveFile(const QString& strRealWaveDataPathFileName,const QString& strRealWaveCfgPathFileName) +{ + + + ReadConfFile(strRealWaveCfgPathFileName); + ReadRealDataFile(strRealWaveDataPathFileName); + + return true; +} +bool CComtradeFile::OpenRealWaveFile(const QString& strRealWaveDataPath,const QString& strRealWaveDataFileName,const QString& strRealWaveCfgPath,const QString& strRealWaveCfgDataFileName) +{ + CloseWaveFile(); + + // Skip tail ".DAT", ".HDR" or ".CFG" + m_sDirName = strRealWaveDataPath; + QString sName = strRealWaveDataFileName.toUpper(); + m_sFileName = strRealWaveDataFileName; + + int nPos = sName.indexOf(".DAT",0,Qt::CaseInsensitive); + if(nPos>0) m_sFileName = sName.left(nPos); + + m_strErrReadMsg = ""; + if(m_sFileName.isEmpty()) + { + m_strErrReadMsg = tr("The Filename is Error!");//空文件名错! + return false; + } + + QString sTextLine; + QString sSubString; + + + // COMTRADE配置文件名 + // + m_strConfigFilePath = strRealWaveCfgPath; + m_strConfigFilePath += "/"; + m_strConfigFilePath += strRealWaveCfgDataFileName; + + + //读配置文件 + // + if( !ReadConfFile() ) + { + CloseWaveFile(); + return false; + } + // COMTRADE数据文件名 + // + m_strDataFilePath = strRealWaveDataPath; + m_strDataFilePath += "/"; + m_strDataFilePath += strRealWaveDataFileName; + + + // 打开数据文件 + //{{for 连续可变采样周期 + bool bRet = true; + + bRet = ReadRealDataFile(); + //}} + if( !bRet ) + { + CloseWaveFile(); + return false; + } + + + //打开标注文件 + m_LabelList.OpenLabelFile(m_sDirName,m_sFileName); + + if( CWaveEnv::GetInst()->m_bExtensive ) + TransToContinus(); + //属性 + InitDisplyAttr(); + + return true; +} +//}} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDgtNameShow.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDgtNameShow.cpp index 35f542bb..dd092ea4 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDgtNameShow.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDgtNameShow.cpp @@ -1,343 +1,343 @@ -#include "CDgtNameShow.h" -#include -#include -#include -#include -#include -#include -#include "CPublic.h" -#include "CWaveShow.h" -#include -#include "CComDataClass.h" -#include -#include - -///////////////////////////////////////////////////// -CDgtNameShow::CDgtNameShow(QWidget *parent,Qt::WindowFlags f ) - :QWidget(parent,f) -{ - setWindowFlag( Qt::WindowStaysOnTopHint ); - setMouseTracking(true); -// setAttribute(Qt::WA_PaintOutsidePaintEvent); - - QPalette p = palette(); -// p.setColor(backgroundRole(), QColor(224,224,224)); -// p.setColor(foregroundRole(), QColor(224,224,224)); - p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_NameBackColor); -// p.setColor(foregroundRole(), CWaveEnv::GetInst()->m_NameForeColor); - setPalette(p); - setAutoFillBackground(true); - - m_pWaveFile = 0; - m_nScrollTop = 0; - -} - -CDgtNameShow::~CDgtNameShow() -{ - -} - -////////////////////////////////////////////////////////////////////////// -void CDgtNameShow::contextMenuEvent ( QContextMenuEvent *e ) -{ - //选中波形 - GetParent()->HitTestTag( m_nScrollTop,e->pos().y() ); - int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; - if( Ch<0 || Ch>=MAX_TAGS) - return; - QMenu* contextMenu = new QMenu( this ); - Q_CHECK_PTR( contextMenu ); - contextMenu->addAction( tr("Hide This Channel"), GetParent(), SLOT(OnHideTagChannel())); - contextMenu->addAction( tr("Restore to Default Group"), GetParent(), SLOT(OnResumeGroup())); - contextMenu->exec( QCursor::pos() ); - delete contextMenu; -} - -void CDgtNameShow::mousePressEvent( QMouseEvent *e ) -{ - Q_UNUSED(e) -} - -void CDgtNameShow::mouseReleaseEvent( QMouseEvent *e ) -{ - GetParent()->HitTestTag( m_nScrollTop,e->pos().y() ); -} -/* -void CDgtNameShow::mouseMoveEvent( QMouseEvent *e ) -{ - QWidget::mouseMoveEvent( e ); -} -*/ - -void CDgtNameShow::paintEvent( QPaintEvent *e ) -{ - Q_UNUSED(e) - QPainter paint; - paint.begin(this ); - paint.setBrush(palette().color( QPalette::Foreground )); - drawBackGnd(&paint); - draw( &paint ); - paint.end(); - -} - -void CDgtNameShow::draw( QPainter *paint ) -{ - if(!m_pWaveFile) return; - if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWNONE) - return; - drawTagsName(paint); -} - -void CDgtNameShow::drawBackGnd(QPainter *paint) -{ - QRect ClientRect = rect(); - ClientRect.setTop(ClientRect.top() - 1); - QBrush oldBrush = paint->brush(); - paint->setBrush(CWaveEnv::GetInst()->m_NameBackColor); - paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); - paint->drawRect(ClientRect); -} - -void CDgtNameShow::drawTagsName( QPainter *paint ,bool bPrint) -{ - if(!m_pWaveFile) return; - - QRect ClientRect; - if(bPrint) - ClientRect = paint->viewport(); - else - ClientRect = geometry(); - - QBrush b1( Qt::green, Qt::Dense6Pattern ); - paint->setBrush( b1 ); - paint->setPen( Qt::blue ); - - int nHeight = ClientRect.height(); - int nWidth = ClientRect.width(); - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - QFont font = paint->font(); - font.setPointSize(10); - paint->setFont(font); - - int nTopPos = - m_nScrollTop; - for(int ch=0;chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0) continue; - //{{判断开关量是否有变化 -// int nTickTemp = 0; - if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWACTION) - { - if( !m_pWaveFile->DigitDataList[ch].m_bChanged ) - continue; - /* - for(nTickTemp = 0;nTickTempDigitDataList[ch].m_bySampleData.count();nTickTemp++) - { - byte nTickBy = m_pWaveFile->DigitDataList[ch].m_bySampleData[nTickTemp]; - if(nTickBy == 1) - break; - } - if(nTickTemp == m_pWaveFile->DigitDataList[ch].m_bySampleData.count()) - continue; - */ - } - - //}} - if(nTopPos + nTagsHeight <0){ nTopPos += nTagsHeight; continue;} - //记录每个波形名的区域 - m_DgtArea[ch] = QRect(0,nTopPos,nWidth,nTagsHeight); - - //选中,则反色 -// if(m_pWaveFile->m_DispAttr.m_nSelDigitalNo==ch) -// { -// qDrawShadePanel(paint,m_DgtArea[ch],palette(),true); -// } -// else -// { -// qDrawShadePanel(paint,m_DgtArea[ch],palette()); -// } - - //qDrawShadePanel(paint,m_DgtArea[ch],palette(),true); - - if(chm_nDigitalNum&&nTopPos <= nHeight - 2 ) - { -// paint->setPen(m_pWaveFile->m_DispAttr.m_dwTagsColor[ch]); - //paint->setPen(CWaveEnv::GetInst()->m_NameForeColor); - paint->setPen(m_pWaveFile->m_DispAttr.m_dwColorArray1[ch%COLOR_NUM_DGT]); - QRect rc(1,nTopPos,nWidth-SPLITTERWIDTH,nTagsHeight); - QString szName = " " + m_pWaveFile->DigitDataList[ch].m_sName; - //paint->drawLine(1,nTopPos+nTagsHeight-1,nWidth-SPLITTERWIDTH,nTopPos+nTagsHeight-1); - paint->drawText(rc,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szName)); - } - nTopPos += nTagsHeight; - if(nTopPos>nHeight) break; - } -} - -void CDgtNameShow::GetTagNameMargin(QRect &rect) -{ - if(!m_pWaveFile) return; - - double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; - //状态量间隔高度 - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - if(m_pWaveFile->m_nNRates<=0) - {rect = QRect(0,0,0,0);return;} - - int nLeft = 0; - int nRight = GetParent()->m_nLeftMargin; - - int nTop = 0; - int nBottom = 0; - for(int ch=0; chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0||!m_pWaveFile->m_DispAttr.m_bTagsPrint[ch]) continue; - nBottom += nTagsHeight; - } - - rect = QRect(nLeft,nTop,nRight - nLeft,nBottom - nTop); - -} - -void CDgtNameShow::Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) -{ - if(!m_pWaveFile) return; - PrintTagsName(paint,rect,ptOffset,bColor); - paint->drawLine(rect.topRight() + ptOffset,rect.bottomRight() + ptOffset); - -} - -void CDgtNameShow::PrintTagsName( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) -{ - if(!m_pWaveFile) return; - - QRect ClientRect; - ClientRect = rect; - - paint->setPen( Qt::black ); - if(bColor){ - QBrush b1( Qt::green, Qt::Dense6Pattern ); - paint->setBrush( b1 ); - paint->setPen( Qt::blue ); - } - - - int nRectTop = ClientRect.top(); - int nRectBottom = ClientRect.bottom(); - int nWidth = ClientRect.width(); - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - QFont nameFont; - nameFont.setPixelSize(12); - paint->setFont(nameFont); - - int nTopPos = 0; - paint->setPen(QColor(0,0,0)); - for(int ch=0;ch<=m_pWaveFile->m_nDigitalNum;ch++) - { - if(m_pWaveFile->m_DispAttr.m_nTagsGroup[ch] < 0||!m_pWaveFile->m_DispAttr.m_bTagsPrint[ch]) continue; - - if(chm_nDigitalNum&&nTopPos > nRectTop -nTagsHeight && nTopPos < nRectBottom +nTagsHeight ) - { - paint->drawLine(QPoint(0,nTopPos) + ptOffset,QPoint(nWidth,nTopPos) + ptOffset); - - if( ch == m_pWaveFile->m_nDigitalNum -1 ) - { - nTagsHeight = nTagsHeight - 4.0; - paint->drawLine(QPoint(0,nTopPos+nTagsHeight) + ptOffset,QPoint(nWidth,nTopPos + nTagsHeight) + ptOffset); - } - - if(bColor) paint->setPen(m_pWaveFile->m_DispAttr.m_dwTagsColor[ch]); - QRect rc(1 + ptOffset.x(),nTopPos+SPLITTERWIDTH + ptOffset.y(),nWidth-SPLITTERWIDTH,nTagsHeight); - QString szName = m_pWaveFile->DigitDataList[ch].m_sName; - paint->drawText(rc,Qt::AlignLeft | Qt::TextSingleLine,(szName)); - } - nTopPos += nTagsHeight; - } -} -//////////////////////////////////////////////////////////////////////// -//##ModelId=4039BEDE0118 -bool CDgtNameShow::SetComtradeData(CComtradeFile& pComtradeData) -{ - m_pWaveFile = &pComtradeData; - update(); - return true; -} - -CWaveShow* CDgtNameShow::GetParent() -{ - return (CWaveShow*)parent(); -} - -void CDgtNameShow::VScroll(int value) -{ - m_nScrollTop = value; - update(); -} - -void CDgtNameShow::wheelEvent(QWheelEvent *e) -{ - bool bVscroll = false; - bool bHscroll = false; - if(QApplication::keyboardModifiers() == Qt::ControlModifier) - { - bVscroll = true; - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 += AMP_RATE; - else if(e->delta() < 0) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 -=AMP_RATE; - - } - else if(QApplication::keyboardModifiers() == Qt::ShiftModifier) - { - bHscroll = true; - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; - else - m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; - } - else - { - bVscroll = true; - GetParent()->m_pDigitalView->vert_bar->setValue( GetParent()->m_pDigitalView->vert_bar->value() - e->delta()/10 ); - } - - if(bVscroll) - { - if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 > 20.0) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 20.0; - if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 < 0.5) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 0.5; - } - - if(bHscroll) - { - if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; - if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; - } - - if(bVscroll) - { - GetParent()->m_pDigitalView->ResetVScrollSize(); - //GetParent()->m_pAnalogueView->ResetVScrollSize(); - } - if(bHscroll) - GetParent()->m_pTimeAxisView->ResetHScrollSize(); - if(bHscroll | bVscroll) - { - GetParent()->redrawWindow(1,false); - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(3,false); - GetParent()->redrawWindow(4,false); - GetParent()->redrawWindow(5,false); - } - -} +#include "CDgtNameShow.h" +#include +#include +#include +#include +#include +#include +#include "CPublic.h" +#include "CWaveShow.h" +#include +#include "CComDataClass.h" +#include +#include + +///////////////////////////////////////////////////// +CDgtNameShow::CDgtNameShow(QWidget *parent,Qt::WindowFlags f ) + :QWidget(parent,f) +{ + setWindowFlag( Qt::WindowStaysOnTopHint ); + setMouseTracking(true); +// setAttribute(Qt::WA_PaintOutsidePaintEvent); + + QPalette p = palette(); +// p.setColor(backgroundRole(), QColor(224,224,224)); +// p.setColor(foregroundRole(), QColor(224,224,224)); + p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_NameBackColor); +// p.setColor(foregroundRole(), CWaveEnv::GetInst()->m_NameForeColor); + setPalette(p); + setAutoFillBackground(true); + + m_pWaveFile = 0; + m_nScrollTop = 0; + +} + +CDgtNameShow::~CDgtNameShow() +{ + +} + +////////////////////////////////////////////////////////////////////////// +void CDgtNameShow::contextMenuEvent ( QContextMenuEvent *e ) +{ + //选中波形 + GetParent()->HitTestTag( m_nScrollTop,e->pos().y() ); + int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; + if( Ch<0 || Ch>=MAX_TAGS) + return; + QMenu* contextMenu = new QMenu( this ); + Q_CHECK_PTR( contextMenu ); + contextMenu->addAction( tr("Hide This Channel"), GetParent(), SLOT(OnHideTagChannel())); + contextMenu->addAction( tr("Restore to Default Group"), GetParent(), SLOT(OnResumeGroup())); + contextMenu->exec( QCursor::pos() ); + delete contextMenu; +} + +void CDgtNameShow::mousePressEvent( QMouseEvent *e ) +{ + Q_UNUSED(e) +} + +void CDgtNameShow::mouseReleaseEvent( QMouseEvent *e ) +{ + GetParent()->HitTestTag( m_nScrollTop,e->pos().y() ); +} +/* +void CDgtNameShow::mouseMoveEvent( QMouseEvent *e ) +{ + QWidget::mouseMoveEvent( e ); +} +*/ + +void CDgtNameShow::paintEvent( QPaintEvent *e ) +{ + Q_UNUSED(e) + QPainter paint; + paint.begin(this ); + paint.setBrush(palette().color( QPalette::Foreground )); + drawBackGnd(&paint); + draw( &paint ); + paint.end(); + +} + +void CDgtNameShow::draw( QPainter *paint ) +{ + if(!m_pWaveFile) return; + if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWNONE) + return; + drawTagsName(paint); +} + +void CDgtNameShow::drawBackGnd(QPainter *paint) +{ + QRect ClientRect = rect(); + ClientRect.setTop(ClientRect.top() - 1); + QBrush oldBrush = paint->brush(); + paint->setBrush(CWaveEnv::GetInst()->m_NameBackColor); + paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); + paint->drawRect(ClientRect); +} + +void CDgtNameShow::drawTagsName( QPainter *paint ,bool bPrint) +{ + if(!m_pWaveFile) return; + + QRect ClientRect; + if(bPrint) + ClientRect = paint->viewport(); + else + ClientRect = geometry(); + + QBrush b1( Qt::green, Qt::Dense6Pattern ); + paint->setBrush( b1 ); + paint->setPen( Qt::blue ); + + int nHeight = ClientRect.height(); + int nWidth = ClientRect.width(); + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + QFont font = paint->font(); + font.setPointSize(10); + paint->setFont(font); + + int nTopPos = - m_nScrollTop; + for(int ch=0;chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0) continue; + //{{判断开关量是否有变化 +// int nTickTemp = 0; + if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWACTION) + { + if( !m_pWaveFile->DigitDataList[ch].m_bChanged ) + continue; + /* + for(nTickTemp = 0;nTickTempDigitDataList[ch].m_bySampleData.count();nTickTemp++) + { + byte nTickBy = m_pWaveFile->DigitDataList[ch].m_bySampleData[nTickTemp]; + if(nTickBy == 1) + break; + } + if(nTickTemp == m_pWaveFile->DigitDataList[ch].m_bySampleData.count()) + continue; + */ + } + + //}} + if(nTopPos + nTagsHeight <0){ nTopPos += nTagsHeight; continue;} + //记录每个波形名的区域 + m_DgtArea[ch] = QRect(0,nTopPos,nWidth,nTagsHeight); + + //选中,则反色 +// if(m_pWaveFile->m_DispAttr.m_nSelDigitalNo==ch) +// { +// qDrawShadePanel(paint,m_DgtArea[ch],palette(),true); +// } +// else +// { +// qDrawShadePanel(paint,m_DgtArea[ch],palette()); +// } + + //qDrawShadePanel(paint,m_DgtArea[ch],palette(),true); + + if(chm_nDigitalNum&&nTopPos <= nHeight - 2 ) + { +// paint->setPen(m_pWaveFile->m_DispAttr.m_dwTagsColor[ch]); + //paint->setPen(CWaveEnv::GetInst()->m_NameForeColor); + paint->setPen(m_pWaveFile->m_DispAttr.m_dwColorArray1[ch%COLOR_NUM_DGT]); + QRect rc(1,nTopPos,nWidth-SPLITTERWIDTH,nTagsHeight); + QString szName = " " + m_pWaveFile->DigitDataList[ch].m_sName; + //paint->drawLine(1,nTopPos+nTagsHeight-1,nWidth-SPLITTERWIDTH,nTopPos+nTagsHeight-1); + paint->drawText(rc,Qt::AlignLeft | Qt::TextSingleLine | Qt::AlignVCenter,(szName)); + } + nTopPos += nTagsHeight; + if(nTopPos>nHeight) break; + } +} + +void CDgtNameShow::GetTagNameMargin(QRect &rect) +{ + if(!m_pWaveFile) return; + + double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; + //状态量间隔高度 + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + if(m_pWaveFile->m_nNRates<=0) + {rect = QRect(0,0,0,0);return;} + + int nLeft = 0; + int nRight = GetParent()->m_nLeftMargin; + + int nTop = 0; + int nBottom = 0; + for(int ch=0; chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0||!m_pWaveFile->m_DispAttr.m_bTagsPrint[ch]) continue; + nBottom += nTagsHeight; + } + + rect = QRect(nLeft,nTop,nRight - nLeft,nBottom - nTop); + +} + +void CDgtNameShow::Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) +{ + if(!m_pWaveFile) return; + PrintTagsName(paint,rect,ptOffset,bColor); + paint->drawLine(rect.topRight() + ptOffset,rect.bottomRight() + ptOffset); + +} + +void CDgtNameShow::PrintTagsName( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) +{ + if(!m_pWaveFile) return; + + QRect ClientRect; + ClientRect = rect; + + paint->setPen( Qt::black ); + if(bColor){ + QBrush b1( Qt::green, Qt::Dense6Pattern ); + paint->setBrush( b1 ); + paint->setPen( Qt::blue ); + } + + + int nRectTop = ClientRect.top(); + int nRectBottom = ClientRect.bottom(); + int nWidth = ClientRect.width(); + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + QFont nameFont; + nameFont.setPixelSize(12); + paint->setFont(nameFont); + + int nTopPos = 0; + paint->setPen(QColor(0,0,0)); + for(int ch=0;ch<=m_pWaveFile->m_nDigitalNum;ch++) + { + if(m_pWaveFile->m_DispAttr.m_nTagsGroup[ch] < 0||!m_pWaveFile->m_DispAttr.m_bTagsPrint[ch]) continue; + + if(chm_nDigitalNum&&nTopPos > nRectTop -nTagsHeight && nTopPos < nRectBottom +nTagsHeight ) + { + paint->drawLine(QPoint(0,nTopPos) + ptOffset,QPoint(nWidth,nTopPos) + ptOffset); + + if( ch == m_pWaveFile->m_nDigitalNum -1 ) + { + nTagsHeight = nTagsHeight - 4.0; + paint->drawLine(QPoint(0,nTopPos+nTagsHeight) + ptOffset,QPoint(nWidth,nTopPos + nTagsHeight) + ptOffset); + } + + if(bColor) paint->setPen(m_pWaveFile->m_DispAttr.m_dwTagsColor[ch]); + QRect rc(1 + ptOffset.x(),nTopPos+SPLITTERWIDTH + ptOffset.y(),nWidth-SPLITTERWIDTH,nTagsHeight); + QString szName = m_pWaveFile->DigitDataList[ch].m_sName; + paint->drawText(rc,Qt::AlignLeft | Qt::TextSingleLine,(szName)); + } + nTopPos += nTagsHeight; + } +} +//////////////////////////////////////////////////////////////////////// +//##ModelId=4039BEDE0118 +bool CDgtNameShow::SetComtradeData(CComtradeFile& pComtradeData) +{ + m_pWaveFile = &pComtradeData; + update(); + return true; +} + +CWaveShow* CDgtNameShow::GetParent() +{ + return (CWaveShow*)parent(); +} + +void CDgtNameShow::VScroll(int value) +{ + m_nScrollTop = value; + update(); +} + +void CDgtNameShow::wheelEvent(QWheelEvent *e) +{ + bool bVscroll = false; + bool bHscroll = false; + if(QApplication::keyboardModifiers() == Qt::ControlModifier) + { + bVscroll = true; + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 += AMP_RATE; + else if(e->delta() < 0) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 -=AMP_RATE; + + } + else if(QApplication::keyboardModifiers() == Qt::ShiftModifier) + { + bHscroll = true; + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; + else + m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; + } + else + { + bVscroll = true; + GetParent()->m_pDigitalView->vert_bar->setValue( GetParent()->m_pDigitalView->vert_bar->value() - e->delta()/10 ); + } + + if(bVscroll) + { + if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 > 20.0) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 20.0; + if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 < 0.5) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 0.5; + } + + if(bHscroll) + { + if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; + if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; + } + + if(bVscroll) + { + GetParent()->m_pDigitalView->ResetVScrollSize(); + //GetParent()->m_pAnalogueView->ResetVScrollSize(); + } + if(bHscroll) + GetParent()->m_pTimeAxisView->ResetHScrollSize(); + if(bHscroll | bVscroll) + { + GetParent()->redrawWindow(1,false); + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(3,false); + GetParent()->redrawWindow(4,false); + GetParent()->redrawWindow(5,false); + } + +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDgtNameShow.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDgtNameShow.h index 8ff31784..26d4b387 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDgtNameShow.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDgtNameShow.h @@ -1,50 +1,50 @@ -#ifndef CDGTNAMESHOW_H_HEADER_INCLUDED_BFC41131 -#define CDGTNAMESHOW_H_HEADER_INCLUDED_BFC41131 - -#include - -#include -#include -#include -#include "CComDataClass.h" -#include "CWaveGraph.h" - -//class CWaveShow; - -//##ModelId=403405ED00B3 -class CDgtNameShow : public QWidget -{ - Q_OBJECT - -public: - CDgtNameShow(QWidget * parent = 0, Qt::WindowFlags f = 0); - ~CDgtNameShow(); -public: - CComtradeFile* m_pWaveFile; - - QFont m_Font; - int m_nScrollTop; - - bool m_bMoveWave; - QRect m_DgtArea[MAX_TAGS]; - -public: - //##ModelId=4039BEDE0118 - bool SetComtradeData(CComtradeFile& pComtradeData); - CWaveShow* GetParent(); - void draw( QPainter *); - void drawTagsName( QPainter *,bool bPrint = false); - void Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); - void PrintTagsName( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); - void GetTagNameMargin(QRect &rect); - void VScroll(int value); - void drawBackGnd(QPainter *); -protected: - void mousePressEvent( QMouseEvent * ); - void mouseReleaseEvent( QMouseEvent * ); - void paintEvent( QPaintEvent *); - void contextMenuEvent ( QContextMenuEvent * ); - void wheelEvent(QWheelEvent *); -}; - -#endif /* CDGTNAMESHOW_H_HEADER_INCLUDED_BFC41131 */ +#ifndef CDGTNAMESHOW_H_HEADER_INCLUDED_BFC41131 +#define CDGTNAMESHOW_H_HEADER_INCLUDED_BFC41131 + +#include + +#include +#include +#include +#include "CComDataClass.h" +#include "CWaveGraph.h" + +//class CWaveShow; + +//##ModelId=403405ED00B3 +class CDgtNameShow : public QWidget +{ + Q_OBJECT + +public: + CDgtNameShow(QWidget * parent = 0, Qt::WindowFlags f = 0); + ~CDgtNameShow(); +public: + CComtradeFile* m_pWaveFile; + + QFont m_Font; + int m_nScrollTop; + + bool m_bMoveWave; + QRect m_DgtArea[MAX_TAGS]; + +public: + //##ModelId=4039BEDE0118 + bool SetComtradeData(CComtradeFile& pComtradeData); + CWaveShow* GetParent(); + void draw( QPainter *); + void drawTagsName( QPainter *,bool bPrint = false); + void Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); + void PrintTagsName( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); + void GetTagNameMargin(QRect &rect); + void VScroll(int value); + void drawBackGnd(QPainter *); +protected: + void mousePressEvent( QMouseEvent * ); + void mouseReleaseEvent( QMouseEvent * ); + void paintEvent( QPaintEvent *); + void contextMenuEvent ( QContextMenuEvent * ); + void wheelEvent(QWheelEvent *); +}; + +#endif /* CDGTNAMESHOW_H_HEADER_INCLUDED_BFC41131 */ diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDigitDataSet.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDigitDataSet.cpp index 7d90b35a..62dfa616 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDigitDataSet.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDigitDataSet.cpp @@ -1,73 +1,73 @@ -#include "CComDataClass.h" - -/////////////////////////////////// -CDigitData::CDigitData() -{ - m_nIndex = 0; //索引 - m_sName = ""; //name - m_sPhase = ""; //相位特征 - m_sCCBM = ""; //被监视的回路元件 - m_byNormalState = 0; //状态 - m_bChanged = false; - m_bySampleData.resize(0); //值 -} - -CDigitData::~CDigitData() -{ -} - -CDigitData &CDigitData::operator=( const CDigitData &p ) -{ - m_nIndex = p.m_nIndex; //模拟通道索引 - m_sName = p.m_sName; //名称 - m_sPhase = p.m_sPhase; //相位特征 - m_sCCBM = p.m_sCCBM; - m_byNormalState = p.m_byNormalState; //被监视的回路元件 - m_bChanged = p.m_bChanged; - m_bySampleData = p.m_bySampleData; - return *this; -} - - - -void CDigitData::Detach() -{ - m_bySampleData.detach(); -} - -void CDigitData::clone(CDigitData& clone) -{ - clone.m_nIndex = m_nIndex; - clone.m_sName = m_sName; - clone.m_sPhase = m_sPhase; - clone.m_sCCBM = m_sCCBM; - clone.m_byNormalState = m_byNormalState; - clone.m_bySampleData.resize(0); -} - -void CDigitData::CopyDataTo(CDigitData& clone,int nBegin,int nEnd) -{ - if(nBegin>=0&&nBegin=0&&nBegin -#include -#include -#include -#include -#include -#include "CPublic.h" -#include "CWaveShow.h" -//#include "clabelsetdlg.h" -#include "CComDataClass.h" -#include -#include - -///////////////////////////////////////////////////// -CDigitalShow::CDigitalShow(QWidget *parent, Qt::WindowFlags f ) - :QWidget(parent,f) -{ - setWindowFlag( Qt::WindowStaysOnTopHint ); - setMouseTracking(true); -// setAttribute(Qt::WA_PaintOutsidePaintEvent); - - QPalette p = palette(); - //p.setColor(backgroundRole(), QColor(255,255,255)); - p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_WaveBackColor); -// p.setColor(foregroundRole(), QColor(255,255,255)); - setPalette(p); - setAutoFillBackground(true); - - QHBoxLayout* hboxLayout = new QHBoxLayout(this); - hboxLayout->setSpacing(0); - hboxLayout->setContentsMargins(0, 0, 0, 0); - - QSpacerItem* spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); - vert_bar = new QScrollBar(Qt::Vertical,this); - hboxLayout->addItem(spacerItem); - hboxLayout->addWidget( vert_bar ); - - vert_bar->setSingleStep(SCROLLBAR_V_LINE); - vert_bar->setPageStep(SCROLLBAR_V_LINE); - vert_bar->setTracking(false); - vert_bar->setMinimum(0); - vert_bar->setMaximum(100); - vert_bar->setCursor(GetParent()->m_hHandCursor); - connect(vert_bar,SIGNAL(valueChanged(int)),this,SLOT(VerticalScrollBarMove(int))); - connect(vert_bar,SIGNAL(sliderMoved(int)),this,SLOT(VerticalScrollBarMove(int))); - - m_pWaveFile = 0; - m_pSelectLabel = 0; - - LLGrayPen = QPen(LLGRAY_COLOR,1,Qt::SolidLine); - BluePen = QPen(BLUE_COLOR,1,Qt::SolidLine); - BlackPen = QPen(BLACK_COLOR,1,Qt::SolidLine); - RedPen = QPen(RED_COLOR,1,Qt::SolidLine); - LCyanPen = QPen(LCYAN_COLOR,1,Qt::SolidLine); - WhitePen = QPen(WHITE_COLOR,1,Qt::SolidLine); - - m_ValueFont = QFont("Arial",10); - - m_nScrollMin = 0; - m_nScrollMax = 100; - - m_nCursorX = -1; - m_nScrollTop = 0; - m_nScrollLeft = 0; - - setCursor(GetParent()->m_hCrossCursor); -} - -CDigitalShow::~CDigitalShow() -{ - -} - -////////////////////////////////////////////////////////////////////////// -void CDigitalShow::OnMousePressEvent( QMouseEvent *e ) -{ - if(e->button() == Qt::LeftButton) - { - bool bMoveLabel = false; - if(m_pSelectLabel){ - m_pSelectLabel = 0L;bMoveLabel = true;} - else - m_pSelectLabel = m_pWaveFile->SelectLabel(QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop)); - - if(m_pSelectLabel||bMoveLabel) - { - update(); - QWidget::mousePressEvent( e ); - return; - } - } - - doMousePress( e ); - update(); - GetParent()->update(); - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(5,false); - GetParent()->redrawWindow(1,false);//在名称去显示数据值,20090818 - GetParent()->redrawWindow(7,false); - GetParent()->showStatus(); -// if( GetParent()->m_pStatusView ) -// GetParent()->m_pStatusView->Refresh(); - QWidget::mousePressEvent( e ); -} - -void CDigitalShow::OnMouseReleaseEvent( QMouseEvent *e ) -{ - QWidget::mouseReleaseEvent( e ); -} - -void CDigitalShow::OnMouseMoveEvent( QMouseEvent *e ) -{ - Q_UNUSED(e) - setCursor(GetParent()->m_hCrossCursor); -// if(GetParent()) -// { -// if(m_pSelectLabel) -// { -// QPoint m_TopLeft = QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop); -// m_pSelectLabel->m_lLeftTick = m_pWaveFile->GetTick(m_TopLeft.x()); -// m_pSelectLabel->m_dTopValue = ((double)m_TopLeft.y())/m_pWaveFile->m_DispAttr.m_dWaveZoomY1; -// update(); -// } -// -// setCursor( GetParent()->m_hArrowCursor ); -// doMouseMove(e); - -// CAnalogueShow *pAnaView = GetParent()->m_pAnalogueView; -// if(pAnaView) pAnaView->doMouseMove( e ); -// -// int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; -// QPoint pt(e->x() + nLeftMargin,e->y()); -// QMouseEvent event(QEvent::MouseMove,pt,e->button(),e->buttons(),e->modifiers()); -// -// CTimeAxisShow *pTimeView = GetParent()->m_pTimeAxisView; -// if(pTimeView) pTimeView->doMouseMove( &event ); - -// GetParent()->redrawWindow(2,false); -// GetParent()->redrawWindow(5,false); -// update(); -// -// } -// QWidget::mouseMoveEvent( e ); -} - -void CDigitalShow::wheelEvent( QWheelEvent* e ) -{ - bool bVscroll = false; - bool bHscroll = false; - if(QApplication::keyboardModifiers() == Qt::ControlModifier) - { - bVscroll =true; - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 += AMP_RATE; - else - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 -= AMP_RATE; - - } - else if(QApplication::keyboardModifiers() == Qt::ShiftModifier) - { - bHscroll = true; - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; - else - m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; - } - else - { - bVscroll = true; - vert_bar->setValue( vert_bar->value() - e->delta()/10 ); - } - - if(bVscroll) - { - if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 > 20.0) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 20.0; - if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 < 0.5) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 0.5; - } - - if(bHscroll) - { - if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; - if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; - } - - - if(bVscroll) - { - ResetVScrollSize(); - //GetParent()->m_pAnalogueView->ResetVScrollSize(); - } - if(bHscroll) - GetParent()->m_pTimeAxisView->ResetHScrollSize(); - - if(bHscroll | bVscroll) - { - GetParent()->redrawWindow(1,false); - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(3,false); - GetParent()->redrawWindow(4,false); - GetParent()->redrawWindow(5,false); - } -} - -void CDigitalShow::contextMenuEvent ( QContextMenuEvent *e ) -{ - Q_UNUSED(e) -// if(m_pSelectLabel) -// { -// QMenu* contextMenu = new QMenu( this ); -// Q_CHECK_PTR( contextMenu ); -// contextMenu->addAction( tr("删除标注"), this, SLOT(OnDelLabel())); -// contextMenu->addAction( tr("修改标注"), this, SLOT(OnModLabel())); -// contextMenu->exec( QCursor::pos() ); -// delete contextMenu; -// } -// else -// { -// //选中波形 -// GetParent()->HitTestTag( m_nScrollTop,e->pos().y() ); -// int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; -// if( Ch<0 || Ch>=MAX_TAGS) -// return; -// -// QMenu* contextMenu = new QMenu( this ); -// Q_CHECK_PTR( contextMenu ); -// contextMenu->addAction( tr("颜色设置"), GetParent(), SLOT(OnDgtColorSet())); -// contextMenu->addAction( tr("线型设置"), GetParent(), SLOT(OnDgtLineSet())); -// contextMenu->addSeparator(); -// contextMenu->addAction( tr("隐藏本通道"), GetParent(), SLOT(OnHideTagChannel())); -// contextMenu->addAction( tr("恢复默认分组"), GetParent(), SLOT(OnResumeGroup())); -// contextMenu->addSeparator(); -// contextMenu->addAction( tr("设置基准线(B线)"), GetParent(), SLOT(OnSetZoneStart())); -// contextMenu->addAction( tr("取消基准线(B线)"), GetParent(), SLOT(OnCacelZone())); -// contextMenu->addSeparator(); -// contextMenu->addAction( tr("添加标注"), GetParent(), SLOT(OnAddLabel())); -// contextMenu->addAction( tr("标注列表"), GetParent(), SLOT(OnLabelList())); -// -// contextMenu->exec( QCursor::pos() ); -// delete contextMenu; -// } - -} - -void CDigitalShow::paintEvent( QPaintEvent *e ) -{ - Q_UNUSED(e) - if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWNONE) - return; - QPainter paint; - paint.begin(this ); - paint.setBrush(palette().color( QPalette::Foreground )); - draw( &paint ); - paint.end(); -} - -void CDigitalShow::draw( QPainter *paint ) -{ - if(!m_pWaveFile) return; - - drawBackGnd(paint); - //drawTagsLine(paint); - //drawVertGridLine(paint); - if(m_pWaveFile->m_DispAttr.m_nTagShowType != TAG_SHOWNONE) - drawTags(paint); - - if( CWaveEnv::GetInst()->m_bShowBaseLine ) - drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fBaseTick,CWaveEnv::GetInst()->m_BaseLineColor);//第一时标线 - - if(CWaveEnv::GetInst()->m_bShowTriggerLine) - drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fTriggerTick,RED_COLOR);//游标线 - - drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fStaticTick,CWaveEnv::GetInst()->m_StaticLineColor);//当前时标线 - drawUpDownLineValue(paint,m_pWaveFile->m_DispAttr.m_fStaticTick); //当前时标值 - -// drawCursor(paint); - -} - -void CDigitalShow::Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) -{ - if(!m_pWaveFile) return; - PrintTags(paint,rect,ptOffset,bColor); -} - -void CDigitalShow::PrintTags(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor) -{ - if(!m_pWaveFile) return; - - QRect ClientRect; - ClientRect = rect; - int nRectTop = ClientRect.top(); - int nRectBottom = ClientRect.bottom(); - - QPen oldPen = paint->pen(); - - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; - double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; - - int nOneWidth = 0; - if(fZoomX >= (1.0 - 1E-5)) nOneWidth = int(dGirdWidth*fZoomX+.5); - else nOneWidth = int(.5+dGirdWidth); - - //状态量间隔高度 - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - int sh = nTagsHeight*2/3; //1状态量绘图高度 - int zh = 0; //0状态高度 - - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth())); - if(ClientRect.right() < ClientRect.left()) return; - - if(!bColor) - paint->setPen(BlackPen); - //每个通道 - - int yBasePosi = 0.0; - for(int ch=0; chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0||!m_pWaveFile->m_DispAttr.m_bTagsPrint[ch]) continue; - - if( yBasePosinRectBottom + nTagsHeight ) - break; - if( ch == m_pWaveFile->m_nDigitalNum -1 ) - { - nTagsHeight = nTagsHeight - 4.0; - sh = nTagsHeight*2/3; - } - - yBasePosi += nTagsHeight; - - paint->setPen(Qt::SolidLine); - - if(bColor){ - QPen TagsPen( m_pWaveFile->m_DispAttr.m_dwTagsColor[ch], - m_pWaveFile->m_DispAttr.m_nTagsLineWidth[ch], - m_pWaveFile->m_DispAttr.m_nTagsLineStyle[ch] - ); - paint->setPen(TagsPen); - } - - bool bPrevZeroVal = true; - // 画状态量 - int nTickPos = 0; - QPoint ptPrev(0,0),ptCur(0,0); - bool bFirst = true; - for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) - { - int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); - for(int nTick=0; nTickm_lSampleAmount[nBlk]; nTick++) - { - - byte byVal = m_pWaveFile->DigitDataList[ch].m_bySampleData[nTickPos]; - nTickPos++; - - - if(fZoomX >= (1.0 - 1E-5)) - { - ptCur.setX(nBlockLeft+nTick*nOneWidth); - } - else - { - ptCur.setX(nBlockLeft + int(double(nTick*nOneWidth)*fZoomX)); - } - if(byVal==0) - ptCur.setY(yBasePosi-zh); - else - ptCur.setY(yBasePosi-sh); - - - if(ptCur.x()ClientRect.right()||ptCur.y()>ClientRect.bottom()) break; - - if(bFirst) - { - ptPrev = ptCur; - if(byVal==0) - bPrevZeroVal = true; - else - bPrevZeroVal = false; - bFirst = false; - continue; - } - - if(byVal==0) - { - if(!bPrevZeroVal) - { - paint->drawLine(ptPrev + ptOffset,ptCur+QPoint(0,-sh) + ptOffset); - paint->drawLine(ptCur+QPoint(0,-sh) + ptOffset , ptCur + ptOffset); - } - else - { - paint->drawLine(ptPrev + ptOffset,ptCur + ptOffset); - } - ptPrev = ptCur; - bPrevZeroVal = true; - } - else if(byVal==1) - { - if(bPrevZeroVal) - { - paint->drawLine(ptPrev + ptOffset,ptCur+QPoint(0,sh) + ptOffset); - paint->drawLine(ptCur+QPoint(0,sh) + ptOffset , ptCur + ptOffset); - } - else - { - paint->drawLine(ptPrev + ptOffset,ptCur + ptOffset); - } - ptPrev = ptCur; - bPrevZeroVal = false; - } - } - } - - QString szChannelName = m_pWaveFile->DigitDataList[ch].m_sName; - for(int j=0;j<(int)m_pWaveFile->m_LabelList.count();j++) - { - CLabel label = m_pWaveFile->m_LabelList[j]; - if(0!=QString::compare(label.m_szChannelName,szChannelName)) continue; - - int nLabelYPos=yBasePosi; - int nLabelXPos = m_pWaveFile->GetXPosition(label.m_lTime); - if(nLabelXPos== (-1)) return; - - int nLabelTick = int(.5+m_pWaveFile->GetTick(nLabelXPos)); - if(nLabelTick<0 || nLabelTick >= m_pWaveFile->GetTotalPointAmount()) return; - - byte Value = m_pWaveFile->DigitDataList[ch].m_bySampleData[nLabelTick]; - - if(Value>0) - nLabelYPos -= sh; - QPoint pt(nLabelXPos,nLabelYPos); - PrintLabel(paint,rect,ptOffset,bColor,&label,pt ); - } - } - - paint->setPen(oldPen); -} - -void CDigitalShow::PrintLabel(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,CLabel* pLabel,QPoint ptChannel) -{ - Q_UNUSED(rect) - int nLeft = m_pWaveFile->GetPointPosition(pLabel->m_lLeftTick); - int nTop = m_pWaveFile->m_DispAttr.m_dWaveZoomY1*pLabel->m_dTopValue; - - QRect rc = QRect(QPoint(nLeft,nTop),pLabel->m_Size); - - QPen LabelPen(CWaveEnv::GetInst()->m_LabelFrameColor,1,Qt::SolidLine); - QPen LinePen(CWaveEnv::GetInst()->m_LabelConnectColor,1,Qt::DotLine); - QPen oldPen = paint->pen(); - QBrush oldBrh = paint->brush(); - QFont nameFont; - nameFont.setPixelSize(12); - paint->setFont(nameFont); - - if(bColor){ - paint->setPen(LabelPen); - paint->setBrush(CWaveEnv::GetInst()->m_LabelBackColor); - } - else{ - paint->setPen(Qt::NoPen); - paint->setBrush(Qt::NoBrush); - } - - Qt::BGMode oldMode = paint->backgroundMode(); - paint->setBackgroundMode(Qt::OpaqueMode); - - QPoint Mid; - if(ptChannel.y() > rc.top()) - Mid = QPoint((rc.left()+rc.right())/2,rc.bottom()); - else - Mid = QPoint((rc.left()+rc.right())/2,rc.top()); - paint->drawRect(QRect(rc.topLeft()+ptOffset,rc.bottomRight()+ptOffset)); - paint->setBackgroundMode(oldMode); - paint->drawText(QRect(rc.topLeft()+ptOffset,rc.bottomRight()+ptOffset),Qt::AlignHCenter |Qt::AlignVCenter | Qt::TextSingleLine,(pLabel->m_szText)); - paint->setPen(LinePen); - paint->drawLine(Mid+ptOffset,ptChannel+ptOffset); - - paint->setPen(oldPen); - paint->setBrush(oldBrh); - -} - -void CDigitalShow::drawBackGnd(QPainter *paint) -{ - if(!m_pWaveFile) return; - -// int XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime); -// if(XPosition1 < 0 || XPosition1 > m_pWaveFile->GetMaxWidth()) -// XPosition1 = 0; -// XPosition1 -= m_nScrollLeft; -// -// int XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime); -// if(XPosition2 < 0 || XPosition2 > m_pWaveFile->GetMaxWidth()) -// XPosition2 = 0; -// XPosition2 -= m_nScrollLeft; - - QBrush oldBrush = paint->brush(); - QPen oldPen = paint->pen(); - QRect ClientRect = rect(); - - QRect rcDraw = ClientRect; - //QSize s = frameSize(); - QSize s = size(); - //rcDraw.setLeft(XPosition1); - //rcDraw.setRight(XPosition2); - rcDraw.setRight( s.width() - SPLITTERWIDTH ); - //rcDraw.setBottom( ); - if(rcDraw.right() > rcDraw.left()) - { - paint->setBrush(CWaveEnv::GetInst()->m_WaveBackColor); - paint->setPen(CWaveEnv::GetInst()->m_WaveBackColor); - paint->drawRect(rcDraw); - } - - paint->setPen(oldPen); - paint->setBrush(oldBrush); -} - -void CDigitalShow::drawTags( QPainter *paint) -{ - if(!m_pWaveFile) return; - - QRect ClientRect; - ClientRect = paint->viewport(); - - QPen oldPen = paint->pen(); - paint->setPen( QColor(255,0,0) ); - - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; - double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; - - int nOneWidth = 0; - if(fZoomX >= (1.0 - 1E-5)) nOneWidth = int(dGirdWidth*fZoomX+.5); - else nOneWidth = int(.5+dGirdWidth); - - //状态量间隔高度 - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - int sh = nTagsHeight*2/3; //状态量绘图高度 - //{{20090821 -// int nLeftWaveAxis = m_pWaveFile->m_DispAttr.m_nLeftWaveAxis; - //}} - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); - if(ClientRect.right() < ClientRect.left()) return; - - //每个通道 - int yBasePosi = -m_nScrollTop-(int)(1.0*dTagsZoomY1); - int nShowNO = 0; - for(int ch=0; chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0) continue; -// int nTickTemp = 0; - if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWACTION) - { - if( !m_pWaveFile->DigitDataList[ch].m_bChanged ) - continue; - } - - yBasePosi += nTagsHeight; - - if(yBasePosi>ClientRect.bottom()) break; - - if(yBasePosi-sh < 0 ) continue; - - QPen TagsPen( m_pWaveFile->m_DispAttr.m_dwColorArray1[ch%COLOR_NUM_DGT], - m_pWaveFile->m_DispAttr.m_nTagsLineWidth[ch], - m_pWaveFile->m_DispAttr.m_nTagsLineStyle[ch] - ); - nShowNO++; -// QPen TagsPen( CWaveEnv::GetInst()->m_WaveForeColor, -// m_pWaveFile->m_DispAttr.m_nTagsLineWidth[ch], -// m_pWaveFile->m_DispAttr.m_nTagsLineStyle[ch] -// ); - - oldPen = paint->pen(); - paint->setPen(TagsPen); - - bool bPrevZeroVal = true; - // 画状态量 - int nTickPos = 0; - int nDataCount = m_pWaveFile->DigitDataList[ch].m_bySampleData.size(); - for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) - { - int nBlockRight = m_pWaveFile->GetBlockRight(nBlk); - if((nBlockRight-m_nScrollLeft) < 0) { nTickPos += m_pWaveFile->m_lSampleAmount[nBlk] ; continue; } - int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); - if((nBlockLeft-m_nScrollLeft) > ClientRect.width()) break; - if( nDataCount <= nTickPos ) - break; - - for(int nTick=0; nTickm_lSampleAmount[nBlk]; nTick++) - { - if( nDataCount <= nTickPos ) - break; - - byte byVal = m_pWaveFile->DigitDataList[ch].m_bySampleData[nTickPos]; - nTickPos++; - - - int nX1, nX2; - if(fZoomX >= (1.0 - 1E-5)) - { - nX1 = nBlockLeft+nTick*nOneWidth; - nX2 = nX1 + nOneWidth; - } - else - { - nX1 = nBlockLeft + int(double(nTick*nOneWidth)*fZoomX); - nX2 = nBlockLeft + int(double((nTick+1)*nOneWidth)*fZoomX); - } - - if((nX2-m_nScrollLeft) < 0) continue; - if((nX1-m_nScrollLeft) > ClientRect.width()) break; - - if(byVal==0) - { - if(bPrevZeroVal) - { - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi,nX2 - m_nScrollLeft, yBasePosi); - } - else - { - bPrevZeroVal = true; - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh, nX1 - m_nScrollLeft, yBasePosi); - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi, nX2 - m_nScrollLeft, yBasePosi); - } - } - else - { - if(bPrevZeroVal) - { - bPrevZeroVal = false; - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh, nX1 - m_nScrollLeft, yBasePosi); - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh, nX2 - m_nScrollLeft, yBasePosi-sh); - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi, nX2 - m_nScrollLeft, yBasePosi); - } - else - { - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh+2,nX1 - m_nScrollLeft, yBasePosi-1); - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh,nX2 - m_nScrollLeft, yBasePosi-sh); - paint->drawLine(nX1 - m_nScrollLeft, yBasePosi,nX2 - m_nScrollLeft, yBasePosi); - } - } - } - } - - if(!CWaveEnv::GetInst()->m_bShowLabel) continue; - - QString szChannelName = m_pWaveFile->DigitDataList[ch].m_sName; - for(int j=0;j<(int)m_pWaveFile->m_LabelList.count();j++) - { - CLabel label = m_pWaveFile->m_LabelList[j]; - if(0!=QString::compare(label.m_szChannelName,szChannelName)) continue; - - int nLabelYPos=yBasePosi; - int nLabelXPos = m_pWaveFile->GetXPosition(label.m_lTime); - if(nLabelXPos== (-1)) return; - - int nLabelTick = int(.5+m_pWaveFile->GetTick(nLabelXPos)); - if(nLabelTick<0 || nLabelTick >= m_pWaveFile->GetTotalPointAmount()) return; - - byte Value = m_pWaveFile->DigitDataList[ch].m_bySampleData[nLabelTick]; - - if(Value>0) - nLabelYPos -= sh; - nLabelXPos -= m_nScrollLeft; - - QPoint pt(nLabelXPos,nLabelYPos); - drawLabel(paint,&label,pt ); - } - } - - paint->setPen(oldPen); -} - -void CDigitalShow::drawTagsLine( QPainter *paint) -{ - if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowGrid) return; - - QRect ClientRect; - ClientRect = paint->viewport(); - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); - if(ClientRect.right() < ClientRect.left()) return; - - QPen oldPen = paint->pen(); - paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); - int i=0,j=0; - int nGridHeight = m_pWaveFile->m_DispAttr.m_dGridHeight; - for(i=ClientRect.left();idrawPoint(i,j); - } - } -/* - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); - if(ClientRect.right() < ClientRect.left()) return; - int nHeight = ClientRect.height(); - int nWidth = ClientRect.width(); - - int nTop = -m_nScrollTop; - for(int Ch=0; Chm_nDigitalNum && Chm_DispAttr.m_nTagsGroup[Ch] < 0) continue; - - nTop += nTagsHeight; - if(nTop <= nHeight - 2) - paint->drawLine(1,nTop,nWidth,nTop); - } -*/ - paint->setPen(oldPen); -} - -void CDigitalShow::drawVertGridLine( QPainter *paint) -{ - if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowVertGrid) return; - - QRect ClientRect = paint->viewport(); - ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); - if(ClientRect.right() < ClientRect.left()) return; - - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; -// int nHeight = 12; - - double fOneWidth = int(dGirdWidth*(fZoomX)+.5); - if(fOneWidth < dGirdWidth) - fOneWidth = dGirdWidth; - - QPen oldPen = paint->pen(); - paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); - for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) - { - int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); - int nBlockRight = m_pWaveFile->GetBlockRight(nBlk); - long lTimeBegin = m_pWaveFile->GetBlockBeginTime(nBlk); - long lTimeEnd = m_pWaveFile->GetBlockEndTime(nBlk); - - if((nBlockLeft-m_nScrollLeft) > ClientRect.width()) break; - - double dRate = m_pWaveFile->m_dSampleRate[nBlk]; - int nGridAmt = int(double(nBlockRight-nBlockLeft)/fOneWidth+.5)+1; - - int dGridArr[10] = {10,20,50, 200, 500, 1000, 2000, 5000, 10000,20000 }; - int nUnit = 0; - - int i = 0; - int nSelGridArr = dGridArr[0]; - for( i=nUnit; i<10; i++) - { - nSelGridArr = dGridArr[i]; - if(nSelGridArr*dRate/1000.0 >=10.0) - break; - } - - int nTick =0; - int nTime = lTimeBegin; - int nIntTime = 0; - for(nTick=0; nTick=lTimeBegin ) - { - int nIntTick = int(.5+(nIntTime-lTimeBegin) / (1000.0/dRate)); - int nIntPos = nBlockLeft + nIntTick*fOneWidth-m_nScrollLeft; - if( nIntPos > nBlockRight) break; - if(nIntPos > ClientRect.right() ) - break; - if( nIntPos < ClientRect.left() ) - continue; - paint->drawLine(nIntPos,0,nIntPos,ClientRect.bottom()); - } - } - } - } - - paint->setPen(oldPen); -} - -//画竖线 -void CDigitalShow::drawUpDownLine(QPainter * paint, double fLineTick, const QColor& clr) -{ - if(!m_pWaveFile) return; - - int XPosition = m_pWaveFile->GetPointPosition(fLineTick); - if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) - XPosition = m_pWaveFile->GetMaxWidth(); - - XPosition -= m_nScrollLeft; - - QRect ClientRect = rect(); - if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) - { - LCyanPen.setColor(clr); - QPen oldPen = paint->pen(); - paint->setPen(LCyanPen); - - paint->drawLine(XPosition,0,XPosition,ClientRect.bottom()); - - paint->setPen(oldPen); - } -} -//画线值 -void CDigitalShow::drawUpDownLineValue(QPainter * paint, double fLineTick) -{ - if(!m_pWaveFile) return; - - int nXPos = m_pWaveFile->GetPointPosition(fLineTick); - if(nXPos== (-1)) return; - - int nThisTick = int(m_pWaveFile->GetTick(nXPos)+0.1); - if(nThisTick<0 || nThisTick >= m_pWaveFile->GetTotalPointAmount()) return; - - nXPos -= m_nScrollLeft; - - QRect ClientRect = rect(); - if(nXPos < ClientRect.left() || nXPos > ClientRect.right()) - return; - - QFont oldFont = paint->font(); - paint->setFont(m_ValueFont); - QColor oldColor = CWaveEnv::GetInst()->m_WaveBackColor; - Qt::BGMode oldMode = paint->backgroundMode(); - paint->setBackgroundMode(Qt::TransparentMode); - QPen oldPen = paint->pen(); - paint->setPen(QColor(255-oldColor.red(),255-oldColor.green(),255-oldColor.blue())); - - - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - -// int nTop = 0; - int nYPos = 0 - nTagsHeight - m_nScrollTop; - for(int Ch=0; Chm_nDigitalNum && Chm_DispAttr.m_nTagsGroup[Ch] < 0) continue; - //{{ -// int nTickTemp = 0; - if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWACTION) - { - if( !m_pWaveFile->DigitDataList[Ch].m_bChanged ) - continue; - } - //}} - nYPos += nTagsHeight; - if(nYPos<0) continue; - else if(nYPos <= ClientRect.height()) - { - QString ValueString;; - byte Value = 0; - - CDigitData& Dgt = m_pWaveFile->DigitDataList[Ch]; - if( nThisTick < (int)Dgt.m_bySampleData.size() ) - Value = Dgt.m_bySampleData[nThisTick]; - if( 0!=Value ) - { - QRect Rect2(nXPos+5,nYPos,20,20); - paint->drawText(Rect2,Qt::AlignLeft | Qt::TextSingleLine,QString::number(Value)); - } - } - else break; - - - } - - paint->setPen(oldPen); - paint->setBackgroundMode(oldMode); - paint->setBackground(QBrush(oldColor)); - paint->setFont(oldFont); -} - -void CDigitalShow::drawCursor(QPainter* paint) -{ - if(m_nCursorX > 0) - { - QRect rcRect = rect(); - QPen oldPen = paint->pen(); - //paint->setPen(BluePen); - paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); - paint->drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); - paint->setPen(oldPen); - } -} - -void CDigitalShow::drawLabel(QPainter* paint,CLabel* pLabel,QPoint ptChannel) -{ - int nLeft = m_pWaveFile->GetPointPosition(pLabel->m_lLeftTick); - int nTop = m_pWaveFile->m_DispAttr.m_dWaveZoomY1*pLabel->m_dTopValue; - - QRect rc = QRect(QPoint(nLeft,nTop) - QPoint(m_nScrollLeft,m_nScrollTop),pLabel->m_Size); - - QPen LabelPen(CWaveEnv::GetInst()->m_LabelFrameColor,1,Qt::SolidLine); - QPen LinePen(CWaveEnv::GetInst()->m_LabelConnectColor,1,Qt::DotLine); - QPen oldPen = paint->pen(); - QBrush oldBrh = paint->brush(); - - paint->setPen(LabelPen); - paint->setBrush(CWaveEnv::GetInst()->m_LabelBackColor); - - Qt::BGMode oldMode = paint->backgroundMode(); - paint->setBackgroundMode(Qt::OpaqueMode); - - QPoint Mid; - if(ptChannel.y() > rc.top()) - Mid = QPoint((rc.left()+rc.right())/2,rc.bottom()); - else - Mid = QPoint((rc.left()+rc.right())/2,rc.top()); - paint->drawRect(rc); - paint->setBackgroundMode(oldMode); - paint->setPen(CWaveEnv::GetInst()->m_LabelTextColor); - paint->drawText(rc,Qt::AlignHCenter |Qt::AlignVCenter | Qt::TextSingleLine,(pLabel->m_szText)); - paint->setPen(LinePen); - paint->drawLine(Mid,ptChannel); - - paint->setPen(oldPen); - paint->setBrush(oldBrh); -} - -void CDigitalShow::GetTagMargin(QRect &rect) -{ - if(!m_pWaveFile) return; - - double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; - //状态量间隔高度 - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - if(m_pWaveFile->m_nNRates<=0) - {rect = QRect(0,0,0,0);return;} - - int nLeft = m_pWaveFile->GetBlockLeft(0); - int nRight = m_pWaveFile->GetBlockRight(m_pWaveFile->m_nNRates-1); - - int nTop = 0; - int nBottom = 0; - for(int ch=0; chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch]<0||!m_pWaveFile->m_DispAttr.m_bTagsPrint[ch]) continue; - - nBottom += nTagsHeight; - } - - rect = QRect(nLeft,nTop,nRight - nLeft,nBottom - nTop); - -} -//////////////////////////////////////////////////////////////////////// -//##ModelId=4039BEDE0118 -bool CDigitalShow::SetComtradeData(CComtradeFile& pComtradeData) -{ - m_pWaveFile = &pComtradeData; - - ResetVScrollSize(); - - update(); - return true; -} - -CWaveShow* CDigitalShow::GetParent() -{ - return (CWaveShow*)parent(); -} - -void CDigitalShow::ResetVScrollSize() -{ - if(!m_pWaveFile) return; - - double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; - //状态量间隔高度 - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - int nTop = 0; - int nBottom = 0; - if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWACTION) - { - for(int ch = 0;chm_nDigitalNum;ch++) - { - if( m_pWaveFile->DigitDataList[ch].m_bChanged ) - nBottom += nTagsHeight; - } - } - else if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWALL) - { - nBottom = m_pWaveFile->m_nDigitalNum*nTagsHeight; - } - else if (m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWNONE) - { - nBottom = 0; - } - - int nh = rect().height(); - int nRange = nBottom - nh; - if(nRange < 0) - nRange = 0; - vert_bar->setRange( nTop,nRange ); -} - -void CDigitalShow::VScroll(int value) -{ - m_nScrollTop = value; - update(); -} - -void CDigitalShow::HScroll(int value) -{ - m_nScrollLeft = value; - update(); -} - - -void CDigitalShow::doMouseMove( QMouseEvent *e ) -{ - if(e->x() < 0) return; - m_nCursorX = e->x(); - - //显示值 - { - int nAbsXPos = m_nCursorX + m_nScrollLeft; - if(nAbsXPos < 0) nAbsXPos = 0; - if(nAbsXPos > m_pWaveFile->GetMaxWidth()) - nAbsXPos = m_pWaveFile->GetMaxWidth(); - - double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; - double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); - - m_pWaveFile->m_DispAttr.m_fCurrentTime = RTime; - m_pWaveFile->m_DispAttr.m_fCurrentTick = dTick; - } - -} - -void CDigitalShow::doMousePress( QMouseEvent *e ) -{ - if(!m_pWaveFile) return; - - int nAbsXPos = e->x() + m_nScrollLeft; - if(nAbsXPos < 0) nAbsXPos = 0; - if(nAbsXPos > m_pWaveFile->GetMaxWidth()) - nAbsXPos = m_pWaveFile->GetMaxWidth(); - - double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; - double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); - // 始终保证第二时标>=第一时标 - if(e->button() == Qt::LeftButton) - { - m_pWaveFile->m_DispAttr.m_fStaticTime = RTime; - m_pWaveFile->m_DispAttr.m_fStaticTick = dTick; - m_pWaveFile->EmitLineCChanged(); - } - else if(e->button() == Qt::RightButton) - { - m_pWaveFile->m_DispAttr.m_fBaseTime = RTime; - m_pWaveFile->m_DispAttr.m_fBaseTick = dTick; - m_pWaveFile->EmitLineBChanged(); - } -} - -void CDigitalShow::VerticalScrollBarMove(int value) -{ - setCursor(GetParent()->m_hHandCursor); - GetParent()->VDgtScroll(value); -} - -void CDigitalShow::OnDelLabel() -{ - if(m_pWaveFile&&m_pSelectLabel) - { - for ( int i=0; i<(int)m_pWaveFile->m_LabelList.count(); i++ ) - { - CLabel& label = m_pWaveFile->m_LabelList[i]; - if(label.m_szChannelName.compare(m_pSelectLabel->m_szChannelName)==0 - &&label.m_szText.compare(m_pSelectLabel->m_szText)==0 - &&label.m_lTime==m_pSelectLabel->m_lTime) - { - CLabelList::iterator ite; - m_pWaveFile->m_LabelList.removeAt(i); - m_pSelectLabel = 0; - update(); - break; - } - } - } - -} - -void CDigitalShow::OnModLabel() -{ -/* - if(m_pWaveFile&&m_pSelectLabel) - { - CLabelSetDlg *dlg = new CLabelSetDlg( this ); - dlg->SetParam(m_pWaveFile,m_pSelectLabel); - if ( dlg->exec() == QDialog::Accepted ) { - - } - delete dlg; - } -*/ -} +#include "CDigitalShow.h" +#include +#include +#include +#include +#include +#include +#include "CPublic.h" +#include "CWaveShow.h" +//#include "clabelsetdlg.h" +#include "CComDataClass.h" +#include +#include + +///////////////////////////////////////////////////// +CDigitalShow::CDigitalShow(QWidget *parent, Qt::WindowFlags f ) + :QWidget(parent,f) +{ + setWindowFlag( Qt::WindowStaysOnTopHint ); + setMouseTracking(true); +// setAttribute(Qt::WA_PaintOutsidePaintEvent); + + QPalette p = palette(); + //p.setColor(backgroundRole(), QColor(255,255,255)); + p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_WaveBackColor); +// p.setColor(foregroundRole(), QColor(255,255,255)); + setPalette(p); + setAutoFillBackground(true); + + QHBoxLayout* hboxLayout = new QHBoxLayout(this); + hboxLayout->setSpacing(0); + hboxLayout->setContentsMargins(0, 0, 0, 0); + + QSpacerItem* spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); + vert_bar = new QScrollBar(Qt::Vertical,this); + hboxLayout->addItem(spacerItem); + hboxLayout->addWidget( vert_bar ); + + vert_bar->setSingleStep(SCROLLBAR_V_LINE); + vert_bar->setPageStep(SCROLLBAR_V_LINE); + vert_bar->setTracking(false); + vert_bar->setMinimum(0); + vert_bar->setMaximum(100); + vert_bar->setCursor(GetParent()->m_hHandCursor); + connect(vert_bar,SIGNAL(valueChanged(int)),this,SLOT(VerticalScrollBarMove(int))); + connect(vert_bar,SIGNAL(sliderMoved(int)),this,SLOT(VerticalScrollBarMove(int))); + + m_pWaveFile = 0; + m_pSelectLabel = 0; + + LLGrayPen = QPen(LLGRAY_COLOR,1,Qt::SolidLine); + BluePen = QPen(BLUE_COLOR,1,Qt::SolidLine); + BlackPen = QPen(BLACK_COLOR,1,Qt::SolidLine); + RedPen = QPen(RED_COLOR,1,Qt::SolidLine); + LCyanPen = QPen(LCYAN_COLOR,1,Qt::SolidLine); + WhitePen = QPen(WHITE_COLOR,1,Qt::SolidLine); + + m_ValueFont = QFont("Arial",10); + + m_nScrollMin = 0; + m_nScrollMax = 100; + + m_nCursorX = -1; + m_nScrollTop = 0; + m_nScrollLeft = 0; + + setCursor(GetParent()->m_hCrossCursor); +} + +CDigitalShow::~CDigitalShow() +{ + +} + +////////////////////////////////////////////////////////////////////////// +void CDigitalShow::OnMousePressEvent( QMouseEvent *e ) +{ + if(e->button() == Qt::LeftButton) + { + bool bMoveLabel = false; + if(m_pSelectLabel){ + m_pSelectLabel = 0L;bMoveLabel = true;} + else + m_pSelectLabel = m_pWaveFile->SelectLabel(QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop)); + + if(m_pSelectLabel||bMoveLabel) + { + update(); + QWidget::mousePressEvent( e ); + return; + } + } + + doMousePress( e ); + update(); + GetParent()->update(); + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(5,false); + GetParent()->redrawWindow(1,false);//在名称去显示数据值,20090818 + GetParent()->redrawWindow(7,false); + GetParent()->showStatus(); +// if( GetParent()->m_pStatusView ) +// GetParent()->m_pStatusView->Refresh(); + QWidget::mousePressEvent( e ); +} + +void CDigitalShow::OnMouseReleaseEvent( QMouseEvent *e ) +{ + QWidget::mouseReleaseEvent( e ); +} + +void CDigitalShow::OnMouseMoveEvent( QMouseEvent *e ) +{ + Q_UNUSED(e) + setCursor(GetParent()->m_hCrossCursor); +// if(GetParent()) +// { +// if(m_pSelectLabel) +// { +// QPoint m_TopLeft = QPoint(e->x()+m_nScrollLeft,e->y() + m_nScrollTop); +// m_pSelectLabel->m_lLeftTick = m_pWaveFile->GetTick(m_TopLeft.x()); +// m_pSelectLabel->m_dTopValue = ((double)m_TopLeft.y())/m_pWaveFile->m_DispAttr.m_dWaveZoomY1; +// update(); +// } +// +// setCursor( GetParent()->m_hArrowCursor ); +// doMouseMove(e); + +// CAnalogueShow *pAnaView = GetParent()->m_pAnalogueView; +// if(pAnaView) pAnaView->doMouseMove( e ); +// +// int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; +// QPoint pt(e->x() + nLeftMargin,e->y()); +// QMouseEvent event(QEvent::MouseMove,pt,e->button(),e->buttons(),e->modifiers()); +// +// CTimeAxisShow *pTimeView = GetParent()->m_pTimeAxisView; +// if(pTimeView) pTimeView->doMouseMove( &event ); + +// GetParent()->redrawWindow(2,false); +// GetParent()->redrawWindow(5,false); +// update(); +// +// } +// QWidget::mouseMoveEvent( e ); +} + +void CDigitalShow::wheelEvent( QWheelEvent* e ) +{ + bool bVscroll = false; + bool bHscroll = false; + if(QApplication::keyboardModifiers() == Qt::ControlModifier) + { + bVscroll =true; + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 += AMP_RATE; + else + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 -= AMP_RATE; + + } + else if(QApplication::keyboardModifiers() == Qt::ShiftModifier) + { + bHscroll = true; + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; + else + m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; + } + else + { + bVscroll = true; + vert_bar->setValue( vert_bar->value() - e->delta()/10 ); + } + + if(bVscroll) + { + if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 > 20.0) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 20.0; + if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 < 0.5) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 0.5; + } + + if(bHscroll) + { + if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; + if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; + } + + + if(bVscroll) + { + ResetVScrollSize(); + //GetParent()->m_pAnalogueView->ResetVScrollSize(); + } + if(bHscroll) + GetParent()->m_pTimeAxisView->ResetHScrollSize(); + + if(bHscroll | bVscroll) + { + GetParent()->redrawWindow(1,false); + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(3,false); + GetParent()->redrawWindow(4,false); + GetParent()->redrawWindow(5,false); + } +} + +void CDigitalShow::contextMenuEvent ( QContextMenuEvent *e ) +{ + Q_UNUSED(e) +// if(m_pSelectLabel) +// { +// QMenu* contextMenu = new QMenu( this ); +// Q_CHECK_PTR( contextMenu ); +// contextMenu->addAction( tr("删除标注"), this, SLOT(OnDelLabel())); +// contextMenu->addAction( tr("修改标注"), this, SLOT(OnModLabel())); +// contextMenu->exec( QCursor::pos() ); +// delete contextMenu; +// } +// else +// { +// //选中波形 +// GetParent()->HitTestTag( m_nScrollTop,e->pos().y() ); +// int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; +// if( Ch<0 || Ch>=MAX_TAGS) +// return; +// +// QMenu* contextMenu = new QMenu( this ); +// Q_CHECK_PTR( contextMenu ); +// contextMenu->addAction( tr("颜色设置"), GetParent(), SLOT(OnDgtColorSet())); +// contextMenu->addAction( tr("线型设置"), GetParent(), SLOT(OnDgtLineSet())); +// contextMenu->addSeparator(); +// contextMenu->addAction( tr("隐藏本通道"), GetParent(), SLOT(OnHideTagChannel())); +// contextMenu->addAction( tr("恢复默认分组"), GetParent(), SLOT(OnResumeGroup())); +// contextMenu->addSeparator(); +// contextMenu->addAction( tr("设置基准线(B线)"), GetParent(), SLOT(OnSetZoneStart())); +// contextMenu->addAction( tr("取消基准线(B线)"), GetParent(), SLOT(OnCacelZone())); +// contextMenu->addSeparator(); +// contextMenu->addAction( tr("添加标注"), GetParent(), SLOT(OnAddLabel())); +// contextMenu->addAction( tr("标注列表"), GetParent(), SLOT(OnLabelList())); +// +// contextMenu->exec( QCursor::pos() ); +// delete contextMenu; +// } + +} + +void CDigitalShow::paintEvent( QPaintEvent *e ) +{ + Q_UNUSED(e) + if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWNONE) + return; + QPainter paint; + paint.begin(this ); + paint.setBrush(palette().color( QPalette::Foreground )); + draw( &paint ); + paint.end(); +} + +void CDigitalShow::draw( QPainter *paint ) +{ + if(!m_pWaveFile) return; + + drawBackGnd(paint); + //drawTagsLine(paint); + //drawVertGridLine(paint); + if(m_pWaveFile->m_DispAttr.m_nTagShowType != TAG_SHOWNONE) + drawTags(paint); + + if( CWaveEnv::GetInst()->m_bShowBaseLine ) + drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fBaseTick,CWaveEnv::GetInst()->m_BaseLineColor);//第一时标线 + + if(CWaveEnv::GetInst()->m_bShowTriggerLine) + drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fTriggerTick,RED_COLOR);//游标线 + + drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fStaticTick,CWaveEnv::GetInst()->m_StaticLineColor);//当前时标线 + drawUpDownLineValue(paint,m_pWaveFile->m_DispAttr.m_fStaticTick); //当前时标值 + +// drawCursor(paint); + +} + +void CDigitalShow::Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ) +{ + if(!m_pWaveFile) return; + PrintTags(paint,rect,ptOffset,bColor); +} + +void CDigitalShow::PrintTags(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor) +{ + if(!m_pWaveFile) return; + + QRect ClientRect; + ClientRect = rect; + int nRectTop = ClientRect.top(); + int nRectBottom = ClientRect.bottom(); + + QPen oldPen = paint->pen(); + + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; + double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; + + int nOneWidth = 0; + if(fZoomX >= (1.0 - 1E-5)) nOneWidth = int(dGirdWidth*fZoomX+.5); + else nOneWidth = int(.5+dGirdWidth); + + //状态量间隔高度 + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + int sh = nTagsHeight*2/3; //1状态量绘图高度 + int zh = 0; //0状态高度 + + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth())); + if(ClientRect.right() < ClientRect.left()) return; + + if(!bColor) + paint->setPen(BlackPen); + //每个通道 + + int yBasePosi = 0.0; + for(int ch=0; chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0||!m_pWaveFile->m_DispAttr.m_bTagsPrint[ch]) continue; + + if( yBasePosinRectBottom + nTagsHeight ) + break; + if( ch == m_pWaveFile->m_nDigitalNum -1 ) + { + nTagsHeight = nTagsHeight - 4.0; + sh = nTagsHeight*2/3; + } + + yBasePosi += nTagsHeight; + + paint->setPen(Qt::SolidLine); + + if(bColor){ + QPen TagsPen( m_pWaveFile->m_DispAttr.m_dwTagsColor[ch], + m_pWaveFile->m_DispAttr.m_nTagsLineWidth[ch], + m_pWaveFile->m_DispAttr.m_nTagsLineStyle[ch] + ); + paint->setPen(TagsPen); + } + + bool bPrevZeroVal = true; + // 画状态量 + int nTickPos = 0; + QPoint ptPrev(0,0),ptCur(0,0); + bool bFirst = true; + for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) + { + int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); + for(int nTick=0; nTickm_lSampleAmount[nBlk]; nTick++) + { + + byte byVal = m_pWaveFile->DigitDataList[ch].m_bySampleData[nTickPos]; + nTickPos++; + + + if(fZoomX >= (1.0 - 1E-5)) + { + ptCur.setX(nBlockLeft+nTick*nOneWidth); + } + else + { + ptCur.setX(nBlockLeft + int(double(nTick*nOneWidth)*fZoomX)); + } + if(byVal==0) + ptCur.setY(yBasePosi-zh); + else + ptCur.setY(yBasePosi-sh); + + + if(ptCur.x()ClientRect.right()||ptCur.y()>ClientRect.bottom()) break; + + if(bFirst) + { + ptPrev = ptCur; + if(byVal==0) + bPrevZeroVal = true; + else + bPrevZeroVal = false; + bFirst = false; + continue; + } + + if(byVal==0) + { + if(!bPrevZeroVal) + { + paint->drawLine(ptPrev + ptOffset,ptCur+QPoint(0,-sh) + ptOffset); + paint->drawLine(ptCur+QPoint(0,-sh) + ptOffset , ptCur + ptOffset); + } + else + { + paint->drawLine(ptPrev + ptOffset,ptCur + ptOffset); + } + ptPrev = ptCur; + bPrevZeroVal = true; + } + else if(byVal==1) + { + if(bPrevZeroVal) + { + paint->drawLine(ptPrev + ptOffset,ptCur+QPoint(0,sh) + ptOffset); + paint->drawLine(ptCur+QPoint(0,sh) + ptOffset , ptCur + ptOffset); + } + else + { + paint->drawLine(ptPrev + ptOffset,ptCur + ptOffset); + } + ptPrev = ptCur; + bPrevZeroVal = false; + } + } + } + + QString szChannelName = m_pWaveFile->DigitDataList[ch].m_sName; + for(int j=0;j<(int)m_pWaveFile->m_LabelList.count();j++) + { + CLabel label = m_pWaveFile->m_LabelList[j]; + if(0!=QString::compare(label.m_szChannelName,szChannelName)) continue; + + int nLabelYPos=yBasePosi; + int nLabelXPos = m_pWaveFile->GetXPosition(label.m_lTime); + if(nLabelXPos== (-1)) return; + + int nLabelTick = int(.5+m_pWaveFile->GetTick(nLabelXPos)); + if(nLabelTick<0 || nLabelTick >= m_pWaveFile->GetTotalPointAmount()) return; + + byte Value = m_pWaveFile->DigitDataList[ch].m_bySampleData[nLabelTick]; + + if(Value>0) + nLabelYPos -= sh; + QPoint pt(nLabelXPos,nLabelYPos); + PrintLabel(paint,rect,ptOffset,bColor,&label,pt ); + } + } + + paint->setPen(oldPen); +} + +void CDigitalShow::PrintLabel(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,CLabel* pLabel,QPoint ptChannel) +{ + Q_UNUSED(rect) + int nLeft = m_pWaveFile->GetPointPosition(pLabel->m_lLeftTick); + int nTop = m_pWaveFile->m_DispAttr.m_dWaveZoomY1*pLabel->m_dTopValue; + + QRect rc = QRect(QPoint(nLeft,nTop),pLabel->m_Size); + + QPen LabelPen(CWaveEnv::GetInst()->m_LabelFrameColor,1,Qt::SolidLine); + QPen LinePen(CWaveEnv::GetInst()->m_LabelConnectColor,1,Qt::DotLine); + QPen oldPen = paint->pen(); + QBrush oldBrh = paint->brush(); + QFont nameFont; + nameFont.setPixelSize(12); + paint->setFont(nameFont); + + if(bColor){ + paint->setPen(LabelPen); + paint->setBrush(CWaveEnv::GetInst()->m_LabelBackColor); + } + else{ + paint->setPen(Qt::NoPen); + paint->setBrush(Qt::NoBrush); + } + + Qt::BGMode oldMode = paint->backgroundMode(); + paint->setBackgroundMode(Qt::OpaqueMode); + + QPoint Mid; + if(ptChannel.y() > rc.top()) + Mid = QPoint((rc.left()+rc.right())/2,rc.bottom()); + else + Mid = QPoint((rc.left()+rc.right())/2,rc.top()); + paint->drawRect(QRect(rc.topLeft()+ptOffset,rc.bottomRight()+ptOffset)); + paint->setBackgroundMode(oldMode); + paint->drawText(QRect(rc.topLeft()+ptOffset,rc.bottomRight()+ptOffset),Qt::AlignHCenter |Qt::AlignVCenter | Qt::TextSingleLine,(pLabel->m_szText)); + paint->setPen(LinePen); + paint->drawLine(Mid+ptOffset,ptChannel+ptOffset); + + paint->setPen(oldPen); + paint->setBrush(oldBrh); + +} + +void CDigitalShow::drawBackGnd(QPainter *paint) +{ + if(!m_pWaveFile) return; + +// int XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime); +// if(XPosition1 < 0 || XPosition1 > m_pWaveFile->GetMaxWidth()) +// XPosition1 = 0; +// XPosition1 -= m_nScrollLeft; +// +// int XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime); +// if(XPosition2 < 0 || XPosition2 > m_pWaveFile->GetMaxWidth()) +// XPosition2 = 0; +// XPosition2 -= m_nScrollLeft; + + QBrush oldBrush = paint->brush(); + QPen oldPen = paint->pen(); + QRect ClientRect = rect(); + + QRect rcDraw = ClientRect; + //QSize s = frameSize(); + QSize s = size(); + //rcDraw.setLeft(XPosition1); + //rcDraw.setRight(XPosition2); + rcDraw.setRight( s.width() - SPLITTERWIDTH ); + //rcDraw.setBottom( ); + if(rcDraw.right() > rcDraw.left()) + { + paint->setBrush(CWaveEnv::GetInst()->m_WaveBackColor); + paint->setPen(CWaveEnv::GetInst()->m_WaveBackColor); + paint->drawRect(rcDraw); + } + + paint->setPen(oldPen); + paint->setBrush(oldBrush); +} + +void CDigitalShow::drawTags( QPainter *paint) +{ + if(!m_pWaveFile) return; + + QRect ClientRect; + ClientRect = paint->viewport(); + + QPen oldPen = paint->pen(); + paint->setPen( QColor(255,0,0) ); + + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; + double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; + + int nOneWidth = 0; + if(fZoomX >= (1.0 - 1E-5)) nOneWidth = int(dGirdWidth*fZoomX+.5); + else nOneWidth = int(.5+dGirdWidth); + + //状态量间隔高度 + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + int sh = nTagsHeight*2/3; //状态量绘图高度 + //{{20090821 +// int nLeftWaveAxis = m_pWaveFile->m_DispAttr.m_nLeftWaveAxis; + //}} + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); + if(ClientRect.right() < ClientRect.left()) return; + + //每个通道 + int yBasePosi = -m_nScrollTop-(int)(1.0*dTagsZoomY1); + int nShowNO = 0; + for(int ch=0; chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0) continue; +// int nTickTemp = 0; + if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWACTION) + { + if( !m_pWaveFile->DigitDataList[ch].m_bChanged ) + continue; + } + + yBasePosi += nTagsHeight; + + if(yBasePosi>ClientRect.bottom()) break; + + if(yBasePosi-sh < 0 ) continue; + + QPen TagsPen( m_pWaveFile->m_DispAttr.m_dwColorArray1[ch%COLOR_NUM_DGT], + m_pWaveFile->m_DispAttr.m_nTagsLineWidth[ch], + m_pWaveFile->m_DispAttr.m_nTagsLineStyle[ch] + ); + nShowNO++; +// QPen TagsPen( CWaveEnv::GetInst()->m_WaveForeColor, +// m_pWaveFile->m_DispAttr.m_nTagsLineWidth[ch], +// m_pWaveFile->m_DispAttr.m_nTagsLineStyle[ch] +// ); + + oldPen = paint->pen(); + paint->setPen(TagsPen); + + bool bPrevZeroVal = true; + // 画状态量 + int nTickPos = 0; + int nDataCount = m_pWaveFile->DigitDataList[ch].m_bySampleData.size(); + for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) + { + int nBlockRight = m_pWaveFile->GetBlockRight(nBlk); + if((nBlockRight-m_nScrollLeft) < 0) { nTickPos += m_pWaveFile->m_lSampleAmount[nBlk] ; continue; } + int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); + if((nBlockLeft-m_nScrollLeft) > ClientRect.width()) break; + if( nDataCount <= nTickPos ) + break; + + for(int nTick=0; nTickm_lSampleAmount[nBlk]; nTick++) + { + if( nDataCount <= nTickPos ) + break; + + byte byVal = m_pWaveFile->DigitDataList[ch].m_bySampleData[nTickPos]; + nTickPos++; + + + int nX1, nX2; + if(fZoomX >= (1.0 - 1E-5)) + { + nX1 = nBlockLeft+nTick*nOneWidth; + nX2 = nX1 + nOneWidth; + } + else + { + nX1 = nBlockLeft + int(double(nTick*nOneWidth)*fZoomX); + nX2 = nBlockLeft + int(double((nTick+1)*nOneWidth)*fZoomX); + } + + if((nX2-m_nScrollLeft) < 0) continue; + if((nX1-m_nScrollLeft) > ClientRect.width()) break; + + if(byVal==0) + { + if(bPrevZeroVal) + { + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi,nX2 - m_nScrollLeft, yBasePosi); + } + else + { + bPrevZeroVal = true; + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh, nX1 - m_nScrollLeft, yBasePosi); + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi, nX2 - m_nScrollLeft, yBasePosi); + } + } + else + { + if(bPrevZeroVal) + { + bPrevZeroVal = false; + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh, nX1 - m_nScrollLeft, yBasePosi); + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh, nX2 - m_nScrollLeft, yBasePosi-sh); + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi, nX2 - m_nScrollLeft, yBasePosi); + } + else + { + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh+2,nX1 - m_nScrollLeft, yBasePosi-1); + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi-sh,nX2 - m_nScrollLeft, yBasePosi-sh); + paint->drawLine(nX1 - m_nScrollLeft, yBasePosi,nX2 - m_nScrollLeft, yBasePosi); + } + } + } + } + + if(!CWaveEnv::GetInst()->m_bShowLabel) continue; + + QString szChannelName = m_pWaveFile->DigitDataList[ch].m_sName; + for(int j=0;j<(int)m_pWaveFile->m_LabelList.count();j++) + { + CLabel label = m_pWaveFile->m_LabelList[j]; + if(0!=QString::compare(label.m_szChannelName,szChannelName)) continue; + + int nLabelYPos=yBasePosi; + int nLabelXPos = m_pWaveFile->GetXPosition(label.m_lTime); + if(nLabelXPos== (-1)) return; + + int nLabelTick = int(.5+m_pWaveFile->GetTick(nLabelXPos)); + if(nLabelTick<0 || nLabelTick >= m_pWaveFile->GetTotalPointAmount()) return; + + byte Value = m_pWaveFile->DigitDataList[ch].m_bySampleData[nLabelTick]; + + if(Value>0) + nLabelYPos -= sh; + nLabelXPos -= m_nScrollLeft; + + QPoint pt(nLabelXPos,nLabelYPos); + drawLabel(paint,&label,pt ); + } + } + + paint->setPen(oldPen); +} + +void CDigitalShow::drawTagsLine( QPainter *paint) +{ + if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowGrid) return; + + QRect ClientRect; + ClientRect = paint->viewport(); + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); + if(ClientRect.right() < ClientRect.left()) return; + + QPen oldPen = paint->pen(); + paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); + int i=0,j=0; + int nGridHeight = m_pWaveFile->m_DispAttr.m_dGridHeight; + for(i=ClientRect.left();idrawPoint(i,j); + } + } +/* + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); + if(ClientRect.right() < ClientRect.left()) return; + int nHeight = ClientRect.height(); + int nWidth = ClientRect.width(); + + int nTop = -m_nScrollTop; + for(int Ch=0; Chm_nDigitalNum && Chm_DispAttr.m_nTagsGroup[Ch] < 0) continue; + + nTop += nTagsHeight; + if(nTop <= nHeight - 2) + paint->drawLine(1,nTop,nWidth,nTop); + } +*/ + paint->setPen(oldPen); +} + +void CDigitalShow::drawVertGridLine( QPainter *paint) +{ + if(!m_pWaveFile||!CWaveEnv::GetInst()->m_bShowVertGrid) return; + + QRect ClientRect = paint->viewport(); + ClientRect.setRight(qMin(ClientRect.right(), m_pWaveFile->GetMaxWidth() - m_nScrollLeft)); + if(ClientRect.right() < ClientRect.left()) return; + + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; +// int nHeight = 12; + + double fOneWidth = int(dGirdWidth*(fZoomX)+.5); + if(fOneWidth < dGirdWidth) + fOneWidth = dGirdWidth; + + QPen oldPen = paint->pen(); + paint->setPen(QPen(QColor(CWaveEnv::GetInst()->m_GridColor),0,Qt::DotLine)); + for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) + { + int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk); + int nBlockRight = m_pWaveFile->GetBlockRight(nBlk); + long lTimeBegin = m_pWaveFile->GetBlockBeginTime(nBlk); + long lTimeEnd = m_pWaveFile->GetBlockEndTime(nBlk); + + if((nBlockLeft-m_nScrollLeft) > ClientRect.width()) break; + + double dRate = m_pWaveFile->m_dSampleRate[nBlk]; + int nGridAmt = int(double(nBlockRight-nBlockLeft)/fOneWidth+.5)+1; + + int dGridArr[10] = {10,20,50, 200, 500, 1000, 2000, 5000, 10000,20000 }; + int nUnit = 0; + + int i = 0; + int nSelGridArr = dGridArr[0]; + for( i=nUnit; i<10; i++) + { + nSelGridArr = dGridArr[i]; + if(nSelGridArr*dRate/1000.0 >=10.0) + break; + } + + int nTick =0; + int nTime = lTimeBegin; + int nIntTime = 0; + for(nTick=0; nTick=lTimeBegin ) + { + int nIntTick = int(.5+(nIntTime-lTimeBegin) / (1000.0/dRate)); + int nIntPos = nBlockLeft + nIntTick*fOneWidth-m_nScrollLeft; + if( nIntPos > nBlockRight) break; + if(nIntPos > ClientRect.right() ) + break; + if( nIntPos < ClientRect.left() ) + continue; + paint->drawLine(nIntPos,0,nIntPos,ClientRect.bottom()); + } + } + } + } + + paint->setPen(oldPen); +} + +//画竖线 +void CDigitalShow::drawUpDownLine(QPainter * paint, double fLineTick, const QColor& clr) +{ + if(!m_pWaveFile) return; + + int XPosition = m_pWaveFile->GetPointPosition(fLineTick); + if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) + XPosition = m_pWaveFile->GetMaxWidth(); + + XPosition -= m_nScrollLeft; + + QRect ClientRect = rect(); + if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) + { + LCyanPen.setColor(clr); + QPen oldPen = paint->pen(); + paint->setPen(LCyanPen); + + paint->drawLine(XPosition,0,XPosition,ClientRect.bottom()); + + paint->setPen(oldPen); + } +} +//画线值 +void CDigitalShow::drawUpDownLineValue(QPainter * paint, double fLineTick) +{ + if(!m_pWaveFile) return; + + int nXPos = m_pWaveFile->GetPointPosition(fLineTick); + if(nXPos== (-1)) return; + + int nThisTick = int(m_pWaveFile->GetTick(nXPos)+0.1); + if(nThisTick<0 || nThisTick >= m_pWaveFile->GetTotalPointAmount()) return; + + nXPos -= m_nScrollLeft; + + QRect ClientRect = rect(); + if(nXPos < ClientRect.left() || nXPos > ClientRect.right()) + return; + + QFont oldFont = paint->font(); + paint->setFont(m_ValueFont); + QColor oldColor = CWaveEnv::GetInst()->m_WaveBackColor; + Qt::BGMode oldMode = paint->backgroundMode(); + paint->setBackgroundMode(Qt::TransparentMode); + QPen oldPen = paint->pen(); + paint->setPen(QColor(255-oldColor.red(),255-oldColor.green(),255-oldColor.blue())); + + + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + +// int nTop = 0; + int nYPos = 0 - nTagsHeight - m_nScrollTop; + for(int Ch=0; Chm_nDigitalNum && Chm_DispAttr.m_nTagsGroup[Ch] < 0) continue; + //{{ +// int nTickTemp = 0; + if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWACTION) + { + if( !m_pWaveFile->DigitDataList[Ch].m_bChanged ) + continue; + } + //}} + nYPos += nTagsHeight; + if(nYPos<0) continue; + else if(nYPos <= ClientRect.height()) + { + QString ValueString;; + byte Value = 0; + + CDigitData& Dgt = m_pWaveFile->DigitDataList[Ch]; + if( nThisTick < (int)Dgt.m_bySampleData.size() ) + Value = Dgt.m_bySampleData[nThisTick]; + if( 0!=Value ) + { + QRect Rect2(nXPos+5,nYPos,20,20); + paint->drawText(Rect2,Qt::AlignLeft | Qt::TextSingleLine,QString::number(Value)); + } + } + else break; + + + } + + paint->setPen(oldPen); + paint->setBackgroundMode(oldMode); + paint->setBackground(QBrush(oldColor)); + paint->setFont(oldFont); +} + +void CDigitalShow::drawCursor(QPainter* paint) +{ + if(m_nCursorX > 0) + { + QRect rcRect = rect(); + QPen oldPen = paint->pen(); + //paint->setPen(BluePen); + paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); + paint->drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); + paint->setPen(oldPen); + } +} + +void CDigitalShow::drawLabel(QPainter* paint,CLabel* pLabel,QPoint ptChannel) +{ + int nLeft = m_pWaveFile->GetPointPosition(pLabel->m_lLeftTick); + int nTop = m_pWaveFile->m_DispAttr.m_dWaveZoomY1*pLabel->m_dTopValue; + + QRect rc = QRect(QPoint(nLeft,nTop) - QPoint(m_nScrollLeft,m_nScrollTop),pLabel->m_Size); + + QPen LabelPen(CWaveEnv::GetInst()->m_LabelFrameColor,1,Qt::SolidLine); + QPen LinePen(CWaveEnv::GetInst()->m_LabelConnectColor,1,Qt::DotLine); + QPen oldPen = paint->pen(); + QBrush oldBrh = paint->brush(); + + paint->setPen(LabelPen); + paint->setBrush(CWaveEnv::GetInst()->m_LabelBackColor); + + Qt::BGMode oldMode = paint->backgroundMode(); + paint->setBackgroundMode(Qt::OpaqueMode); + + QPoint Mid; + if(ptChannel.y() > rc.top()) + Mid = QPoint((rc.left()+rc.right())/2,rc.bottom()); + else + Mid = QPoint((rc.left()+rc.right())/2,rc.top()); + paint->drawRect(rc); + paint->setBackgroundMode(oldMode); + paint->setPen(CWaveEnv::GetInst()->m_LabelTextColor); + paint->drawText(rc,Qt::AlignHCenter |Qt::AlignVCenter | Qt::TextSingleLine,(pLabel->m_szText)); + paint->setPen(LinePen); + paint->drawLine(Mid,ptChannel); + + paint->setPen(oldPen); + paint->setBrush(oldBrh); +} + +void CDigitalShow::GetTagMargin(QRect &rect) +{ + if(!m_pWaveFile) return; + + double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; + //状态量间隔高度 + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + if(m_pWaveFile->m_nNRates<=0) + {rect = QRect(0,0,0,0);return;} + + int nLeft = m_pWaveFile->GetBlockLeft(0); + int nRight = m_pWaveFile->GetBlockRight(m_pWaveFile->m_nNRates-1); + + int nTop = 0; + int nBottom = 0; + for(int ch=0; chm_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch]<0||!m_pWaveFile->m_DispAttr.m_bTagsPrint[ch]) continue; + + nBottom += nTagsHeight; + } + + rect = QRect(nLeft,nTop,nRight - nLeft,nBottom - nTop); + +} +//////////////////////////////////////////////////////////////////////// +//##ModelId=4039BEDE0118 +bool CDigitalShow::SetComtradeData(CComtradeFile& pComtradeData) +{ + m_pWaveFile = &pComtradeData; + + ResetVScrollSize(); + + update(); + return true; +} + +CWaveShow* CDigitalShow::GetParent() +{ + return (CWaveShow*)parent(); +} + +void CDigitalShow::ResetVScrollSize() +{ + if(!m_pWaveFile) return; + + double dTagsZoomY1 = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; + //状态量间隔高度 + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + int nTop = 0; + int nBottom = 0; + if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWACTION) + { + for(int ch = 0;chm_nDigitalNum;ch++) + { + if( m_pWaveFile->DigitDataList[ch].m_bChanged ) + nBottom += nTagsHeight; + } + } + else if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWALL) + { + nBottom = m_pWaveFile->m_nDigitalNum*nTagsHeight; + } + else if (m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWNONE) + { + nBottom = 0; + } + + int nh = rect().height(); + int nRange = nBottom - nh; + if(nRange < 0) + nRange = 0; + vert_bar->setRange( nTop,nRange ); +} + +void CDigitalShow::VScroll(int value) +{ + m_nScrollTop = value; + update(); +} + +void CDigitalShow::HScroll(int value) +{ + m_nScrollLeft = value; + update(); +} + + +void CDigitalShow::doMouseMove( QMouseEvent *e ) +{ + if(e->x() < 0) return; + m_nCursorX = e->x(); + + //显示值 + { + int nAbsXPos = m_nCursorX + m_nScrollLeft; + if(nAbsXPos < 0) nAbsXPos = 0; + if(nAbsXPos > m_pWaveFile->GetMaxWidth()) + nAbsXPos = m_pWaveFile->GetMaxWidth(); + + double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; + double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); + + m_pWaveFile->m_DispAttr.m_fCurrentTime = RTime; + m_pWaveFile->m_DispAttr.m_fCurrentTick = dTick; + } + +} + +void CDigitalShow::doMousePress( QMouseEvent *e ) +{ + if(!m_pWaveFile) return; + + int nAbsXPos = e->x() + m_nScrollLeft; + if(nAbsXPos < 0) nAbsXPos = 0; + if(nAbsXPos > m_pWaveFile->GetMaxWidth()) + nAbsXPos = m_pWaveFile->GetMaxWidth(); + + double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; + double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); + // 始终保证第二时标>=第一时标 + if(e->button() == Qt::LeftButton) + { + m_pWaveFile->m_DispAttr.m_fStaticTime = RTime; + m_pWaveFile->m_DispAttr.m_fStaticTick = dTick; + m_pWaveFile->EmitLineCChanged(); + } + else if(e->button() == Qt::RightButton) + { + m_pWaveFile->m_DispAttr.m_fBaseTime = RTime; + m_pWaveFile->m_DispAttr.m_fBaseTick = dTick; + m_pWaveFile->EmitLineBChanged(); + } +} + +void CDigitalShow::VerticalScrollBarMove(int value) +{ + setCursor(GetParent()->m_hHandCursor); + GetParent()->VDgtScroll(value); +} + +void CDigitalShow::OnDelLabel() +{ + if(m_pWaveFile&&m_pSelectLabel) + { + for ( int i=0; i<(int)m_pWaveFile->m_LabelList.count(); i++ ) + { + CLabel& label = m_pWaveFile->m_LabelList[i]; + if(label.m_szChannelName.compare(m_pSelectLabel->m_szChannelName)==0 + &&label.m_szText.compare(m_pSelectLabel->m_szText)==0 + &&label.m_lTime==m_pSelectLabel->m_lTime) + { + CLabelList::iterator ite; + m_pWaveFile->m_LabelList.removeAt(i); + m_pSelectLabel = 0; + update(); + break; + } + } + } + +} + +void CDigitalShow::OnModLabel() +{ +/* + if(m_pWaveFile&&m_pSelectLabel) + { + CLabelSetDlg *dlg = new CLabelSetDlg( this ); + dlg->SetParam(m_pWaveFile,m_pSelectLabel); + if ( dlg->exec() == QDialog::Accepted ) { + + } + delete dlg; + } +*/ +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDigitalShow.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDigitalShow.h index 570299da..c92c1b9e 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDigitalShow.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CDigitalShow.h @@ -1,105 +1,105 @@ -#ifndef CDIGITALSHOW_H_HEADER_INCLUDED_BFC41131 -#define CDIGITALSHOW_H_HEADER_INCLUDED_BFC41131 - -#include - -#include -#include -#include -#include -#include "CComDataClass.h" -#include "CWaveGraph.h" - -//class CWaveShow; - -//##ModelId=403405ED00B3 -class CDigitalShow : public QWidget -{ - Q_OBJECT - -public: - CDigitalShow(QWidget * parent = 0, Qt::WindowFlags f = 0); - ~CDigitalShow(); -public: - QScrollBar *vert_bar; - - CComtradeFile* m_pWaveFile; - CLabel* m_pSelectLabel; -public: - QPen LLGrayPen; - QPen BlackPen; - QPen RedPen; - QPen BluePen; - QPen LCyanPen; - QPen WhitePen; - - QFont m_ValueFont; - - int m_nScrollMin; - int m_nScrollMax; - - int m_nCursorX; - int m_nScrollTop; - int m_nScrollLeft; - -public: - //##ModelId=4039BEDE0118 - bool SetComtradeData(CComtradeFile& pComtradeData); - - - CWaveShow* GetParent(); - void draw( QPainter *paint ); - void drawTags( QPainter *); - void drawTagsLine( QPainter *); - void drawVertGridLine( QPainter *paint); - void drawBackGnd(QPainter *); - void drawUpDownLine(QPainter * ,double, const QColor&); - void drawUpDownLineValue(QPainter * ,double); - void drawCursor(QPainter *); - void drawLabel(QPainter* paint,CLabel* pLabel,QPoint ptChannel); - void Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); - void PrintTags(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor); - void PrintLabel(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,CLabel* pLabel,QPoint ptChannel); - - void GetTagMargin(QRect &rect); - void ResetVScrollSize(); - void VScroll(int value); - void HScroll(int value); - -public slots: - void VerticalScrollBarMove(int value); - void doMousePress( QMouseEvent *e ); - void doMouseMove( QMouseEvent *e ); - void OnDelLabel(); - void OnModLabel(); - void OnMousePressEvent( QMouseEvent * ); - void OnMouseReleaseEvent( QMouseEvent * ); - void OnMouseMoveEvent( QMouseEvent * ); -protected: - void contextMenuEvent ( QContextMenuEvent * ); - void wheelEvent( QWheelEvent* e ); - void paintEvent( QPaintEvent *); -}; - -#endif /* CDIGITALSHOW_H_HEADER_INCLUDED_BFC41131 */ - - - - - - - - - - - - - - - - - - - - - +#ifndef CDIGITALSHOW_H_HEADER_INCLUDED_BFC41131 +#define CDIGITALSHOW_H_HEADER_INCLUDED_BFC41131 + +#include + +#include +#include +#include +#include +#include "CComDataClass.h" +#include "CWaveGraph.h" + +//class CWaveShow; + +//##ModelId=403405ED00B3 +class CDigitalShow : public QWidget +{ + Q_OBJECT + +public: + CDigitalShow(QWidget * parent = 0, Qt::WindowFlags f = 0); + ~CDigitalShow(); +public: + QScrollBar *vert_bar; + + CComtradeFile* m_pWaveFile; + CLabel* m_pSelectLabel; +public: + QPen LLGrayPen; + QPen BlackPen; + QPen RedPen; + QPen BluePen; + QPen LCyanPen; + QPen WhitePen; + + QFont m_ValueFont; + + int m_nScrollMin; + int m_nScrollMax; + + int m_nCursorX; + int m_nScrollTop; + int m_nScrollLeft; + +public: + //##ModelId=4039BEDE0118 + bool SetComtradeData(CComtradeFile& pComtradeData); + + + CWaveShow* GetParent(); + void draw( QPainter *paint ); + void drawTags( QPainter *); + void drawTagsLine( QPainter *); + void drawVertGridLine( QPainter *paint); + void drawBackGnd(QPainter *); + void drawUpDownLine(QPainter * ,double, const QColor&); + void drawUpDownLineValue(QPainter * ,double); + void drawCursor(QPainter *); + void drawLabel(QPainter* paint,CLabel* pLabel,QPoint ptChannel); + void Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor ); + void PrintTags(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor); + void PrintLabel(QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,CLabel* pLabel,QPoint ptChannel); + + void GetTagMargin(QRect &rect); + void ResetVScrollSize(); + void VScroll(int value); + void HScroll(int value); + +public slots: + void VerticalScrollBarMove(int value); + void doMousePress( QMouseEvent *e ); + void doMouseMove( QMouseEvent *e ); + void OnDelLabel(); + void OnModLabel(); + void OnMousePressEvent( QMouseEvent * ); + void OnMouseReleaseEvent( QMouseEvent * ); + void OnMouseMoveEvent( QMouseEvent * ); +protected: + void contextMenuEvent ( QContextMenuEvent * ); + void wheelEvent( QWheelEvent* e ); + void paintEvent( QPaintEvent *); +}; + +#endif /* CDIGITALSHOW_H_HEADER_INCLUDED_BFC41131 */ + + + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CInfSection.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CInfSection.cpp index 4e848a32..b457c3d4 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CInfSection.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CInfSection.cpp @@ -1,217 +1,217 @@ -#include "CComDataClass.h" -#include -#include "CPublic.h" -#include "CommonFunction.h" - -//////////////////////////////////////////////////////// -//CInfSection -CInfSection::CInfSection() -{ -} - -CInfSection::~CInfSection() -{ -} - - - -void CInfSection::SetAttribute(const QString& sName, const QString& sValue) -{ - CEntryList::iterator itEntry; - for ( itEntry = EntryList.begin(); itEntry != EntryList.end(); ++itEntry ) - { - if((*itEntry).m_sName == sName) - { - (*itEntry).m_sValue = sValue; - return; - } - } - - CInfEntry entry; - entry.m_sName = sName; - entry.m_sValue = sValue; - entry.m_sComment = ""; - EntryList.append(entry); - return; -} - -QString CInfSection::GetAttribute(const QString& sName, const QString& sDefault) -{ - QString sRetString = sDefault; - - CEntryList::iterator itEntry; - for ( itEntry = EntryList.begin(); itEntry != EntryList.end(); ++itEntry ) - { - if((*itEntry).m_sName == sName) - { - sRetString = (*itEntry).m_sValue; - break; - } - } - return sRetString; -} - -//////////////////////////////// -//CSectionOperate -//******************************************************************** -// 新建给定名称的组 -// -//******************************************************************** -int CSectionOperate::SetSection(CSectionList& SectionList, const QString& sName, const QString& sCompany ) -{ - int nIndex = 0; - CSectionList::iterator itSec; - for ( itSec = SectionList.begin(); itSec != SectionList.end(); ++itSec,nIndex++ ) - { - if((*itSec).m_sName == sName && (*itSec).m_sCompany == sCompany) - { - return nIndex; - } - } - - CInfSection section; - section.m_sName = sName; - section.m_sCompany = sCompany; - section.m_sComment = ""; - SectionList.append(section); - return (SectionList.count() - 1); -} -//******************************************************************** -// 获得给定名称的组 -// -//******************************************************************** -int CSectionOperate::GetSection(CSectionList& SectionList, const QString& sName, const QString& sCompany ) -{ - int nIndex = 0; - CSectionList::iterator itSec; - for ( itSec = SectionList.begin(); itSec != SectionList.end(); ++itSec,nIndex++ ) - { - if((*itSec).m_sName == sName && (*itSec).m_sCompany == sCompany) - { - return nIndex; - } - } - return -1; -} -//******************************************************************** -// 获得给定名称的属性值 -// -//******************************************************************** -QString CSectionOperate::GetAttribute(CSectionList& SectionList, const QString& sName, const QString& sDefault ) -{ - QString sRetString = sDefault; - - CSectionList::iterator itSec; - for ( itSec = SectionList.begin(); itSec != SectionList.end(); ++itSec ) - { - CEntryList& listEntry = (*itSec).EntryList; - - CEntryList::iterator itEntry; - for ( itEntry = listEntry.begin(); itEntry != listEntry.end(); ++itEntry ) - { - if((*itEntry).m_sName == sName) - { - sRetString = (*itEntry).m_sValue; - break; - } - } - break; - } - return sRetString; -} - -bool CSectionOperate::ReadFile(CSectionList& SectionList, const QString &sFileName) -{ - SectionList.clear(); - - QString sTextLine; - QString sLeft,sRight; - QString m_strInfoFilePath; - m_strInfoFilePath = sFileName; - // 打开信息文件 - // - QFile file( m_strInfoFilePath ); - if ( !file.open( QIODevice::ReadOnly ) ) - return false; - - QTextStream InfoFile( &file ); - autoSetTextStreamCodec( InfoFile ); - - int nLineNum = 1; - while(!InfoFile.atEnd()) - { - sTextLine = InfoFile.readLine(); - if(QString()==sTextLine) break; - nLineNum++; - - int nHead,nTail,nEqu,nLine; - nHead = sTextLine.indexOf('[',0); - nTail = sTextLine.indexOf("]",0); - if(nHead>=0&&nTail>=0) - { - sTextLine = sTextLine.right(sTextLine.length()-nHead-1); - sTextLine = sTextLine.left(nTail-nHead-1); -// sTextLine = (sTextLine); - sRight = ""; - sLeft = ""; - nLine = sTextLine.indexOf('_',0); - if(nLine>0) - { - sRight = sTextLine.right(sTextLine.length() - nLine -1); - sLeft = sTextLine.left(nLine); - } - else - sLeft = sTextLine; - - CInfSection section; - section.m_sName = sLeft; - section.m_sCompany = sRight; - section.m_sComment = ""; - SectionList.append(section); - } - else - { - nEqu = sTextLine.indexOf('=',0); - if(!SectionList.isEmpty()&&nEqu>0) - { - CInfSection& sect = SectionList.last(); -// sTextLine = (sTextLine); - sRight = sTextLine.right(sTextLine.length() - nEqu -1); - sLeft = sTextLine.left(nEqu); - - sect.SetAttribute(sLeft,sRight); - } - } - } - return true; -} - -bool CSectionOperate::writeFile(CSectionList& SectionList, const QString &sFileName) -{ - QString m_strInfoFilePath,szName; - m_strInfoFilePath = sFileName; - - // 保存信息文件 - // - QFile file( m_strInfoFilePath ); - if ( !file.open( QIODevice::WriteOnly ) ) - return false; - - QTextStream InfoFile( &file ); - - CSectionList::iterator it; - for ( it = SectionList.begin(); it != SectionList.end(); ++it ) - { - if((*it).m_sCompany.isEmpty()) - InfoFile < +#include "CPublic.h" +#include "CommonFunction.h" + +//////////////////////////////////////////////////////// +//CInfSection +CInfSection::CInfSection() +{ +} + +CInfSection::~CInfSection() +{ +} + + + +void CInfSection::SetAttribute(const QString& sName, const QString& sValue) +{ + CEntryList::iterator itEntry; + for ( itEntry = EntryList.begin(); itEntry != EntryList.end(); ++itEntry ) + { + if((*itEntry).m_sName == sName) + { + (*itEntry).m_sValue = sValue; + return; + } + } + + CInfEntry entry; + entry.m_sName = sName; + entry.m_sValue = sValue; + entry.m_sComment = ""; + EntryList.append(entry); + return; +} + +QString CInfSection::GetAttribute(const QString& sName, const QString& sDefault) +{ + QString sRetString = sDefault; + + CEntryList::iterator itEntry; + for ( itEntry = EntryList.begin(); itEntry != EntryList.end(); ++itEntry ) + { + if((*itEntry).m_sName == sName) + { + sRetString = (*itEntry).m_sValue; + break; + } + } + return sRetString; +} + +//////////////////////////////// +//CSectionOperate +//******************************************************************** +// 新建给定名称的组 +// +//******************************************************************** +int CSectionOperate::SetSection(CSectionList& SectionList, const QString& sName, const QString& sCompany ) +{ + int nIndex = 0; + CSectionList::iterator itSec; + for ( itSec = SectionList.begin(); itSec != SectionList.end(); ++itSec,nIndex++ ) + { + if((*itSec).m_sName == sName && (*itSec).m_sCompany == sCompany) + { + return nIndex; + } + } + + CInfSection section; + section.m_sName = sName; + section.m_sCompany = sCompany; + section.m_sComment = ""; + SectionList.append(section); + return (SectionList.count() - 1); +} +//******************************************************************** +// 获得给定名称的组 +// +//******************************************************************** +int CSectionOperate::GetSection(CSectionList& SectionList, const QString& sName, const QString& sCompany ) +{ + int nIndex = 0; + CSectionList::iterator itSec; + for ( itSec = SectionList.begin(); itSec != SectionList.end(); ++itSec,nIndex++ ) + { + if((*itSec).m_sName == sName && (*itSec).m_sCompany == sCompany) + { + return nIndex; + } + } + return -1; +} +//******************************************************************** +// 获得给定名称的属性值 +// +//******************************************************************** +QString CSectionOperate::GetAttribute(CSectionList& SectionList, const QString& sName, const QString& sDefault ) +{ + QString sRetString = sDefault; + + CSectionList::iterator itSec; + for ( itSec = SectionList.begin(); itSec != SectionList.end(); ++itSec ) + { + CEntryList& listEntry = (*itSec).EntryList; + + CEntryList::iterator itEntry; + for ( itEntry = listEntry.begin(); itEntry != listEntry.end(); ++itEntry ) + { + if((*itEntry).m_sName == sName) + { + sRetString = (*itEntry).m_sValue; + break; + } + } + break; + } + return sRetString; +} + +bool CSectionOperate::ReadFile(CSectionList& SectionList, const QString &sFileName) +{ + SectionList.clear(); + + QString sTextLine; + QString sLeft,sRight; + QString m_strInfoFilePath; + m_strInfoFilePath = sFileName; + // 打开信息文件 + // + QFile file( m_strInfoFilePath ); + if ( !file.open( QIODevice::ReadOnly ) ) + return false; + + QTextStream InfoFile( &file ); + autoSetTextStreamCodec( InfoFile ); + + int nLineNum = 1; + while(!InfoFile.atEnd()) + { + sTextLine = InfoFile.readLine(); + if(QString()==sTextLine) break; + nLineNum++; + + int nHead,nTail,nEqu,nLine; + nHead = sTextLine.indexOf('[',0); + nTail = sTextLine.indexOf("]",0); + if(nHead>=0&&nTail>=0) + { + sTextLine = sTextLine.right(sTextLine.length()-nHead-1); + sTextLine = sTextLine.left(nTail-nHead-1); +// sTextLine = (sTextLine); + sRight = ""; + sLeft = ""; + nLine = sTextLine.indexOf('_',0); + if(nLine>0) + { + sRight = sTextLine.right(sTextLine.length() - nLine -1); + sLeft = sTextLine.left(nLine); + } + else + sLeft = sTextLine; + + CInfSection section; + section.m_sName = sLeft; + section.m_sCompany = sRight; + section.m_sComment = ""; + SectionList.append(section); + } + else + { + nEqu = sTextLine.indexOf('=',0); + if(!SectionList.isEmpty()&&nEqu>0) + { + CInfSection& sect = SectionList.last(); +// sTextLine = (sTextLine); + sRight = sTextLine.right(sTextLine.length() - nEqu -1); + sLeft = sTextLine.left(nEqu); + + sect.SetAttribute(sLeft,sRight); + } + } + } + return true; +} + +bool CSectionOperate::writeFile(CSectionList& SectionList, const QString &sFileName) +{ + QString m_strInfoFilePath,szName; + m_strInfoFilePath = sFileName; + + // 保存信息文件 + // + QFile file( m_strInfoFilePath ); + if ( !file.open( QIODevice::WriteOnly ) ) + return false; + + QTextStream InfoFile( &file ); + + CSectionList::iterator it; + for ( it = SectionList.begin(); it != SectionList.end(); ++it ) + { + if((*it).m_sCompany.isEmpty()) + InfoFile < -#include -#include -#include "CPublic.h" -#include -#include "CommonFunction.h" - -/////////////////////////////////////////////////////////////////// -//CLabel -CLabel::CLabel() -{ - m_szChannelName = ""; //通道名 - m_szText = QObject::tr("Mark"); //标注 - m_lTime = 50.0; //时间点 - m_szStyle = ""; //显示风格 - m_szFont = "Arial"; //字体 - m_bBold = false; //粗 - m_bItalic = false; //斜 - m_nFontSize = 9; //大小 - - m_lLeftTick = 10; - m_dTopValue = 10.0; - m_Size = QSize(60,60); -} - -CLabel::~CLabel() -{ -} - -//////////////////////////////////////////////////////////////////// -//CLabelList -bool CLabelList::OpenLabelFile(QString strPath,QString strFile) -{ - // COMTRADE标注文件名 - // - QString m_strLabelFilePath; - m_strLabelFilePath = strPath; - m_strLabelFilePath.append("\\"); - m_strLabelFilePath += strFile; - m_strLabelFilePath.append( ".LABEL" ); - - clear(); - - QFile file( m_strLabelFilePath ); - if ( !file.open( QIODevice::ReadOnly ) ) - { - return false; - } - - QTextStream LabelFile( &file ); - autoSetTextStreamCodec( LabelFile ); - - QString sTextLine,sSubString; - int nCount = 0; - int nLineNum = 1; - while(!LabelFile.atEnd()) - { - //count - sTextLine = LabelFile.readLine(); - if(QString()==sTextLine) break; - nLineNum++; - - if(!CPublic::GetSubString(sTextLine,0,sSubString)) break; - nCount = sSubString.toInt(); - - for(int i=0;i +#include +#include +#include "CPublic.h" +#include +#include "CommonFunction.h" + +/////////////////////////////////////////////////////////////////// +//CLabel +CLabel::CLabel() +{ + m_szChannelName = ""; //通道名 + m_szText = QObject::tr("Mark"); //标注 + m_lTime = 50.0; //时间点 + m_szStyle = ""; //显示风格 + m_szFont = "Arial"; //字体 + m_bBold = false; //粗 + m_bItalic = false; //斜 + m_nFontSize = 9; //大小 + + m_lLeftTick = 10; + m_dTopValue = 10.0; + m_Size = QSize(60,60); +} + +CLabel::~CLabel() +{ +} + +//////////////////////////////////////////////////////////////////// +//CLabelList +bool CLabelList::OpenLabelFile(QString strPath,QString strFile) +{ + // COMTRADE标注文件名 + // + QString m_strLabelFilePath; + m_strLabelFilePath = strPath; + m_strLabelFilePath.append("\\"); + m_strLabelFilePath += strFile; + m_strLabelFilePath.append( ".LABEL" ); + + clear(); + + QFile file( m_strLabelFilePath ); + if ( !file.open( QIODevice::ReadOnly ) ) + { + return false; + } + + QTextStream LabelFile( &file ); + autoSetTextStreamCodec( LabelFile ); + + QString sTextLine,sSubString; + int nCount = 0; + int nLineNum = 1; + while(!LabelFile.atEnd()) + { + //count + sTextLine = LabelFile.readLine(); + if(QString()==sTextLine) break; + nLineNum++; + + if(!CPublic::GetSubString(sTextLine,0,sSubString)) break; + nCount = sSubString.toInt(); + + for(int i=0;im_statusBackColor); -// p.setColor(foregroundRole(), CWaveEnv::GetInst()->m_statusForeColor); -// setPalette(p); -// setAutoFillBackground(true); - m_pWaveFile = 0; -} - -CLineStatusShow::~CLineStatusShow() -{ -} - -bool CLineStatusShow::SetComtradeData(CComtradeFile& pComtradeData) -{ - m_pWaveFile = &pComtradeData; - // update(); - return true; -} - -// CWaveGraph* CLineStatusShow::GetParent() -// { -// return (CWaveGraph*)parent(); -// } - -void CLineStatusShow::paintEvent(QPaintEvent *e) -{ - Q_UNUSED(e) - QPainter paint; - paint.begin(this ); - //paint.setBrush(palette().color( QPalette::Foreground )); - drawBackGnd(&paint); - draw( &paint ); - paint.end(); -} - -void CLineStatusShow::drawBackGnd(QPainter *paint) -{ - QRect ClientRect = rect(); - ClientRect.setTop(ClientRect.top() - 1); - QBrush oldBrush = paint->brush(); - paint->setBrush(CWaveEnv::GetInst()->m_statusBackColor); - paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); - paint->drawRect(ClientRect); -} - -void CLineStatusShow::draw(QPainter* paint) -{ - drawStatus(paint); -} - -void CLineStatusShow::drawStatus(QPainter* paint) -{ -// int nWidth = rect().width(); - int nHeight = rect().height(); - int nH = nHeight/2; - -// rectLine3 = QRect(1,nH*2 + 1,nWidth,nH - 2); - -// QDateTime tDateTime = m_pWaveFile->m_tFirstTime; -// QDate tDate = m_pWaveFile->m_tFirstTime.date(); -// QTime tTime = m_pWaveFile->m_tFirstTime.time(); - - QString strBase = tr("Line B") + ":";//B线 - strBase += QString("%1=%2,").arg(tr("Dot No.")).arg((int)m_pWaveFile->m_DispAttr.m_fBaseTick);//点号 - strBase += QString("%1=%2,").arg(tr("Absolute Timestamp")).arg((int)m_pWaveFile->m_DispAttr.m_fBaseTime);//绝对时标 - //相对时差 - strBase += QString("%1=%2,").arg(tr("Relative Time Difference")).arg((int)fabs((float)((int)m_pWaveFile->m_DispAttr.m_fBaseTime - (int)m_pWaveFile->m_DispAttr.m_fTriggerTime))); - QString strStatic = tr("Line C") + ":";//C线 - strStatic += QString("%1=%2,").arg(tr("Dot No.")).arg((int)m_pWaveFile->m_DispAttr.m_fStaticTick); - strStatic += QString("%1=%2,").arg(tr("Absolute Timestamp")).arg((int)m_pWaveFile->m_DispAttr.m_fStaticTime); - strStatic += QString("%1=%2,").arg(tr("Relative Time Difference")).arg((int)fabs(m_pWaveFile->m_DispAttr.m_fStaticTime - m_pWaveFile->m_DispAttr.m_fTriggerTime)); - QString strTemp = ""; - //点差 - strTemp += QString("%1=%2,").arg(tr("Dot Difference")).arg((int)fabs((float)((int)m_pWaveFile->m_DispAttr.m_fStaticTick - (int)m_pWaveFile->m_DispAttr.m_fBaseTick))); - //时差 - strTemp += QString("%1=%2").arg(tr("Time Difference")).arg((int)fabs(m_pWaveFile->m_DispAttr.m_fStaticTime - m_pWaveFile->m_DispAttr.m_fBaseTime)); - - int nBaseWidth = paint->fontMetrics().width(strBase); - int nStaticWidth = paint->fontMetrics().width(strStatic); - rectLine1 = QRect(5,0,nBaseWidth+5,nH); - rectLine2 = QRect(5,nH,nStaticWidth+5,nH); - - QPen oldPen = paint->pen(); - QPen penBase(CWaveEnv::GetInst()->m_BaseLineColor); - paint->setPen(penBase); - paint->drawText(rectLine1,Qt::AlignVCenter,strBase); - QPen penStatic(CWaveEnv::GetInst()->m_StaticLineColor); - paint->setPen(penStatic); - paint->drawText(rectLine2,Qt::AlignVCenter,strStatic); -// paint->drawText(rectLine3,strTemp); - paint->setPen(oldPen); -} +#include "CLineStatusShow.h" + +CLineStatusShow::CLineStatusShow( QWidget *parent ) + :QWidget(parent) +{ + setWindowFlag( Qt::WindowStaysOnTopHint ); +// QPalette p = palette(); +// p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_statusBackColor); +// p.setColor(foregroundRole(), CWaveEnv::GetInst()->m_statusForeColor); +// setPalette(p); +// setAutoFillBackground(true); + m_pWaveFile = 0; +} + +CLineStatusShow::~CLineStatusShow() +{ +} + +bool CLineStatusShow::SetComtradeData(CComtradeFile& pComtradeData) +{ + m_pWaveFile = &pComtradeData; + // update(); + return true; +} + +// CWaveGraph* CLineStatusShow::GetParent() +// { +// return (CWaveGraph*)parent(); +// } + +void CLineStatusShow::paintEvent(QPaintEvent *e) +{ + Q_UNUSED(e) + QPainter paint; + paint.begin(this ); + //paint.setBrush(palette().color( QPalette::Foreground )); + drawBackGnd(&paint); + draw( &paint ); + paint.end(); +} + +void CLineStatusShow::drawBackGnd(QPainter *paint) +{ + QRect ClientRect = rect(); + ClientRect.setTop(ClientRect.top() - 1); + QBrush oldBrush = paint->brush(); + paint->setBrush(CWaveEnv::GetInst()->m_statusBackColor); + paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); + paint->drawRect(ClientRect); +} + +void CLineStatusShow::draw(QPainter* paint) +{ + drawStatus(paint); +} + +void CLineStatusShow::drawStatus(QPainter* paint) +{ +// int nWidth = rect().width(); + int nHeight = rect().height(); + int nH = nHeight/2; + +// rectLine3 = QRect(1,nH*2 + 1,nWidth,nH - 2); + +// QDateTime tDateTime = m_pWaveFile->m_tFirstTime; +// QDate tDate = m_pWaveFile->m_tFirstTime.date(); +// QTime tTime = m_pWaveFile->m_tFirstTime.time(); + + QString strBase = tr("Line B") + ":";//B线 + strBase += QString("%1=%2,").arg(tr("Dot No.")).arg((int)m_pWaveFile->m_DispAttr.m_fBaseTick);//点号 + strBase += QString("%1=%2,").arg(tr("Absolute Timestamp")).arg((int)m_pWaveFile->m_DispAttr.m_fBaseTime);//绝对时标 + //相对时差 + strBase += QString("%1=%2,").arg(tr("Relative Time Difference")).arg((int)fabs((float)((int)m_pWaveFile->m_DispAttr.m_fBaseTime - (int)m_pWaveFile->m_DispAttr.m_fTriggerTime))); + QString strStatic = tr("Line C") + ":";//C线 + strStatic += QString("%1=%2,").arg(tr("Dot No.")).arg((int)m_pWaveFile->m_DispAttr.m_fStaticTick); + strStatic += QString("%1=%2,").arg(tr("Absolute Timestamp")).arg((int)m_pWaveFile->m_DispAttr.m_fStaticTime); + strStatic += QString("%1=%2,").arg(tr("Relative Time Difference")).arg((int)fabs(m_pWaveFile->m_DispAttr.m_fStaticTime - m_pWaveFile->m_DispAttr.m_fTriggerTime)); + QString strTemp = ""; + //点差 + strTemp += QString("%1=%2,").arg(tr("Dot Difference")).arg((int)fabs((float)((int)m_pWaveFile->m_DispAttr.m_fStaticTick - (int)m_pWaveFile->m_DispAttr.m_fBaseTick))); + //时差 + strTemp += QString("%1=%2").arg(tr("Time Difference")).arg((int)fabs(m_pWaveFile->m_DispAttr.m_fStaticTime - m_pWaveFile->m_DispAttr.m_fBaseTime)); + + int nBaseWidth = paint->fontMetrics().width(strBase); + int nStaticWidth = paint->fontMetrics().width(strStatic); + rectLine1 = QRect(5,0,nBaseWidth+5,nH); + rectLine2 = QRect(5,nH,nStaticWidth+5,nH); + + QPen oldPen = paint->pen(); + QPen penBase(CWaveEnv::GetInst()->m_BaseLineColor); + paint->setPen(penBase); + paint->drawText(rectLine1,Qt::AlignVCenter,strBase); + QPen penStatic(CWaveEnv::GetInst()->m_StaticLineColor); + paint->setPen(penStatic); + paint->drawText(rectLine2,Qt::AlignVCenter,strStatic); +// paint->drawText(rectLine3,strTemp); + paint->setPen(oldPen); +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CLineStatusShow.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CLineStatusShow.h index ea999e16..fbe64032 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CLineStatusShow.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CLineStatusShow.h @@ -1,43 +1,43 @@ -#ifndef CLINESTATUSSHOW_H -#define CLINESTATUSSHOW_H - -#include - -#include -#include -#include -#include -#include -#include -#include "CComDataClass.h" -#include "CWaveGraph.h" - -//class CWaveShow; - -//##ModelId=403405ED00B3 -class CLineStatusShow : public QWidget -{ - Q_OBJECT - -public: - CLineStatusShow( QWidget *parent ); - ~CLineStatusShow(); -public: - CComtradeFile* m_pWaveFile; - -public: - QRect rectLine1; - QRect rectLine2; - QRect rectLine3; - -public: - bool SetComtradeData(CComtradeFile& pComtradeData); -// CWaveGraph* GetParent(); - void draw(QPainter*); - void drawStatus(QPainter*); - void drawBackGnd(QPainter *); -protected: - void paintEvent(QPaintEvent *); -}; - -#endif /* CSTATUSSHOW_H_HEADER_INCLUDED_BFC41131 */ +#ifndef CLINESTATUSSHOW_H +#define CLINESTATUSSHOW_H + +#include + +#include +#include +#include +#include +#include +#include +#include "CComDataClass.h" +#include "CWaveGraph.h" + +//class CWaveShow; + +//##ModelId=403405ED00B3 +class CLineStatusShow : public QWidget +{ + Q_OBJECT + +public: + CLineStatusShow( QWidget *parent ); + ~CLineStatusShow(); +public: + CComtradeFile* m_pWaveFile; + +public: + QRect rectLine1; + QRect rectLine2; + QRect rectLine3; + +public: + bool SetComtradeData(CComtradeFile& pComtradeData); +// CWaveGraph* GetParent(); + void draw(QPainter*); + void drawStatus(QPainter*); + void drawBackGnd(QPainter *); +protected: + void paintEvent(QPaintEvent *); +}; + +#endif /* CSTATUSSHOW_H_HEADER_INCLUDED_BFC41131 */ diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPrintPreview.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPrintPreview.cpp index dbb3256d..53dc9f9e 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPrintPreview.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPrintPreview.cpp @@ -1,148 +1,148 @@ -/**************************************************************************** -** Form implementation generated from reading ui file 'CPrintPreview.ui' -** -** Created: 鏄熸湡鍥?涓夋湀 25 19:21:48 2004 -** by: The User Interface Compiler ($Id: qt/main.cpp 3.2.2 edited May 19 14:22 $) -** -** WARNING! All changes made in this file will be lost! -****************************************************************************/ - -#include "CPrintPreview.h" - -#include -#include -#include -#include -#include -#include -#include "cpageshow.h" - -/* - * Constructs a CPrintPreview as a child of 'parent', with the - * name 'name' and widget flags set to 'f'. - * - * The dialog will by default be modeless, unless you set 'modal' to - * true to construct a modal dialog. - */ -CPrintPreview::CPrintPreview( QWidget * parent, Qt::WindowFlags f ) - : QDialog( parent,f ) -{ -// setAttribute(Qt::WA_PaintOutsidePaintEvent); - - setWindowFlag( Qt::WindowStaysOnTopHint ); - setWindowTitle( "CPrintPreview" ); - setSizeGripEnabled( true ); - - m_nTopMargin = 30; - m_pPageShow = new CPageShow(this); - RecacuArea(); - - m_btnPrint = new QPushButton( this ); - m_btnPrint->setGeometry( QRect( 0, 0, 80, 23 ) ); - - m_btnNextPage = new QPushButton( this); - m_btnNextPage->setGeometry( QRect( 80, 0, 80, 23 ) ); - - m_btnPrevPage = new QPushButton( this ); - m_btnPrevPage->setGeometry( QRect( 160, 0, 80, 23 ) ); - - m_btnTwoPage = new QPushButton( this ); - m_btnTwoPage->setGeometry( QRect( 240, 0, 80, 23 ) ); - - m_btnZoomin = new QPushButton( this ); - m_btnZoomin->setGeometry( QRect( 320, 0, 80, 23 ) ); - - m_btnZoomout = new QPushButton( this ); - m_btnZoomout->setGeometry( QRect( 400, 0, 80, 23 ) ); - - m_btnClose = new QPushButton( this ); - m_btnClose->setGeometry( QRect( 480, 0, 80, 23 ) ); - CPrintPreview::languageChange(); -// resize( QSize(759, 521).expandedTo(minimumSizeHint()) ); - showMaximized(); - - // signals and slots connections - connect( m_btnPrint, SIGNAL( clicked() ), this, SLOT( accept() ) ); - connect( m_btnClose, SIGNAL( clicked() ), this, SLOT( reject() ) ); - connect( m_btnNextPage, SIGNAL( clicked() ), this, SLOT( OnNextPage() ) ); - connect( m_btnPrevPage, SIGNAL( clicked() ), this, SLOT( OnPrevPage() ) ); - connect( m_btnTwoPage, SIGNAL( clicked() ), this, SLOT( OnTwoPage() ) ); - connect( m_btnZoomin, SIGNAL( clicked() ), this, SLOT( OnZoomIn() ) ); - connect( m_btnZoomout, SIGNAL( clicked() ), this, SLOT( OnZoomOut() ) ); - - -} - -/* - * Destroys the object and frees any allocated resources - */ -CPrintPreview::~CPrintPreview() -{ - // no need to delete child widgets, Qt does it all for us -} - -/* - * Sets the strings of the subwidgets using the current - * language. - */ -void CPrintPreview::languageChange() -{ - setWindowTitle( tr("Print Preview" ) );//打印预览 - m_btnPrint->setText( tr("Print..." ) );//打印.. - m_btnNextPage->setText( tr("Next" ) );//下一页 - m_btnPrevPage->setText( tr("Prev" ) );//上一页 - m_btnTwoPage->setText( tr("Single/Dual" ) );//单页/两页 - m_btnZoomin->setText( tr("Zoom In" ) );//放大 - m_btnZoomout->setText( tr("Zoom Out" ) );//缩小 - m_btnClose->setText( tr("Close" ) );//关闭 -} - -void CPrintPreview::resizeEvent(QResizeEvent* event) -{ - Q_UNUSED(event) - RecacuArea(); -} - -void CPrintPreview::OnNextPage() -{ - if(m_pPageShow) m_pPageShow->DoNextPage(); -} - - -void CPrintPreview::OnPrevPage() -{ - if(m_pPageShow) m_pPageShow->DoPrevPage(); -} - - -void CPrintPreview::OnTwoPage() -{ - if(m_pPageShow) m_pPageShow->DoTwoPage(); -} - - -void CPrintPreview::OnZoomIn() -{ - if(m_pPageShow) m_pPageShow->DoZoomIn(); -} - - -void CPrintPreview::OnZoomOut() -{ - if(m_pPageShow) m_pPageShow->DoZoomOut(); -} - -void CPrintPreview::setPages( const CPixmapList & list ) -{ - if(m_pPageShow) - m_pPageShow->setPages(list); -} - -void CPrintPreview::RecacuArea() -{ - QRect rc = rect(); - QRect rc1(2,m_nTopMargin,rc.width()- 4,rc.height() - m_nTopMargin - 2); - - if(m_pPageShow) m_pPageShow->setGeometry(rc1); - m_pPageShow->update(); -} +/**************************************************************************** +** Form implementation generated from reading ui file 'CPrintPreview.ui' +** +** Created: 鏄熸湡鍥?涓夋湀 25 19:21:48 2004 +** by: The User Interface Compiler ($Id: qt/main.cpp 3.2.2 edited May 19 14:22 $) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "CPrintPreview.h" + +#include +#include +#include +#include +#include +#include +#include "cpageshow.h" + +/* + * Constructs a CPrintPreview as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * true to construct a modal dialog. + */ +CPrintPreview::CPrintPreview( QWidget * parent, Qt::WindowFlags f ) + : QDialog( parent,f ) +{ +// setAttribute(Qt::WA_PaintOutsidePaintEvent); + + setWindowFlag( Qt::WindowStaysOnTopHint ); + setWindowTitle( "CPrintPreview" ); + setSizeGripEnabled( true ); + + m_nTopMargin = 30; + m_pPageShow = new CPageShow(this); + RecacuArea(); + + m_btnPrint = new QPushButton( this ); + m_btnPrint->setGeometry( QRect( 0, 0, 80, 23 ) ); + + m_btnNextPage = new QPushButton( this); + m_btnNextPage->setGeometry( QRect( 80, 0, 80, 23 ) ); + + m_btnPrevPage = new QPushButton( this ); + m_btnPrevPage->setGeometry( QRect( 160, 0, 80, 23 ) ); + + m_btnTwoPage = new QPushButton( this ); + m_btnTwoPage->setGeometry( QRect( 240, 0, 80, 23 ) ); + + m_btnZoomin = new QPushButton( this ); + m_btnZoomin->setGeometry( QRect( 320, 0, 80, 23 ) ); + + m_btnZoomout = new QPushButton( this ); + m_btnZoomout->setGeometry( QRect( 400, 0, 80, 23 ) ); + + m_btnClose = new QPushButton( this ); + m_btnClose->setGeometry( QRect( 480, 0, 80, 23 ) ); + CPrintPreview::languageChange(); +// resize( QSize(759, 521).expandedTo(minimumSizeHint()) ); + showMaximized(); + + // signals and slots connections + connect( m_btnPrint, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( m_btnClose, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( m_btnNextPage, SIGNAL( clicked() ), this, SLOT( OnNextPage() ) ); + connect( m_btnPrevPage, SIGNAL( clicked() ), this, SLOT( OnPrevPage() ) ); + connect( m_btnTwoPage, SIGNAL( clicked() ), this, SLOT( OnTwoPage() ) ); + connect( m_btnZoomin, SIGNAL( clicked() ), this, SLOT( OnZoomIn() ) ); + connect( m_btnZoomout, SIGNAL( clicked() ), this, SLOT( OnZoomOut() ) ); + + +} + +/* + * Destroys the object and frees any allocated resources + */ +CPrintPreview::~CPrintPreview() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void CPrintPreview::languageChange() +{ + setWindowTitle( tr("Print Preview" ) );//打印预览 + m_btnPrint->setText( tr("Print..." ) );//打印.. + m_btnNextPage->setText( tr("Next" ) );//下一页 + m_btnPrevPage->setText( tr("Prev" ) );//上一页 + m_btnTwoPage->setText( tr("Single/Dual" ) );//单页/两页 + m_btnZoomin->setText( tr("Zoom In" ) );//放大 + m_btnZoomout->setText( tr("Zoom Out" ) );//缩小 + m_btnClose->setText( tr("Close" ) );//关闭 +} + +void CPrintPreview::resizeEvent(QResizeEvent* event) +{ + Q_UNUSED(event) + RecacuArea(); +} + +void CPrintPreview::OnNextPage() +{ + if(m_pPageShow) m_pPageShow->DoNextPage(); +} + + +void CPrintPreview::OnPrevPage() +{ + if(m_pPageShow) m_pPageShow->DoPrevPage(); +} + + +void CPrintPreview::OnTwoPage() +{ + if(m_pPageShow) m_pPageShow->DoTwoPage(); +} + + +void CPrintPreview::OnZoomIn() +{ + if(m_pPageShow) m_pPageShow->DoZoomIn(); +} + + +void CPrintPreview::OnZoomOut() +{ + if(m_pPageShow) m_pPageShow->DoZoomOut(); +} + +void CPrintPreview::setPages( const CPixmapList & list ) +{ + if(m_pPageShow) + m_pPageShow->setPages(list); +} + +void CPrintPreview::RecacuArea() +{ + QRect rc = rect(); + QRect rc1(2,m_nTopMargin,rc.width()- 4,rc.height() - m_nTopMargin - 2); + + if(m_pPageShow) m_pPageShow->setGeometry(rc1); + m_pPageShow->update(); +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPrintPreview.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPrintPreview.h index 4987fe13..1b0681b5 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPrintPreview.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPrintPreview.h @@ -1,63 +1,63 @@ -/**************************************************************************** -** Created:hujf 03-22 11:50:06 2004 -** by: hujf -****************************************************************************/ - -#ifndef CPRINTLIB_H -#define CPRINTLIB_H - -#include -#include -#include -#include - -class QVBoxLayout; -class QHBoxLayout; -class QGridLayout; -class QPushButton; -class CPageShow; - -class CPixmapList :public QList -{ -}; - -class CPrintPreview : public QDialog -{ - Q_OBJECT - -public: - CPrintPreview( QWidget * parent = 0, Qt::WindowFlags f = 0 ); - ~CPrintPreview(); - - QPushButton* m_btnPrint; - QPushButton* m_btnNextPage; - QPushButton* m_btnPrevPage; - QPushButton* m_btnTwoPage; - QPushButton* m_btnZoomin; - QPushButton* m_btnZoomout; - QPushButton* m_btnClose; -public: - int m_nTopMargin; - CPageShow* m_pPageShow; -public: - void setPages( const CPixmapList & list ); - void RecacuArea(); - -public slots: - virtual void OnNextPage(); - virtual void OnPrevPage(); - virtual void OnTwoPage(); - virtual void OnZoomIn(); - virtual void OnZoomOut(); - -protected: - virtual void resizeEvent( QResizeEvent * ); - - -protected slots: - virtual void languageChange(); - -}; - - -#endif // CPRINTLIB_H +/**************************************************************************** +** Created:hujf 03-22 11:50:06 2004 +** by: hujf +****************************************************************************/ + +#ifndef CPRINTLIB_H +#define CPRINTLIB_H + +#include +#include +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QPushButton; +class CPageShow; + +class CPixmapList :public QList +{ +}; + +class CPrintPreview : public QDialog +{ + Q_OBJECT + +public: + CPrintPreview( QWidget * parent = 0, Qt::WindowFlags f = 0 ); + ~CPrintPreview(); + + QPushButton* m_btnPrint; + QPushButton* m_btnNextPage; + QPushButton* m_btnPrevPage; + QPushButton* m_btnTwoPage; + QPushButton* m_btnZoomin; + QPushButton* m_btnZoomout; + QPushButton* m_btnClose; +public: + int m_nTopMargin; + CPageShow* m_pPageShow; +public: + void setPages( const CPixmapList & list ); + void RecacuArea(); + +public slots: + virtual void OnNextPage(); + virtual void OnPrevPage(); + virtual void OnTwoPage(); + virtual void OnZoomIn(); + virtual void OnZoomOut(); + +protected: + virtual void resizeEvent( QResizeEvent * ); + + +protected slots: + virtual void languageChange(); + +}; + + +#endif // CPRINTLIB_H diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPublic.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPublic.cpp index 419e8973..768f7fee 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPublic.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CPublic.cpp @@ -1,2229 +1,2229 @@ -// CPublic.cpp: implementation of the CPublic class. -// -////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include "CPublic.h" - -void CPublic::SetWidgetBackColor( QWidget* wg,const QColor& bc ) -{ - QPalette plt = wg->palette(); - plt.setColor(wg->backgroundRole(), bc); - wg->setPalette(plt); -} - -void CPublic::SetWidgetForeColor( QWidget* wg,const QColor& fc ) -{ - QPalette plt = wg->palette(); - plt.setColor(wg->foregroundRole(), fc); - wg->setPalette(plt); -} - -QColor CPublic::GetWidgetBackColor( QWidget* wg ) -{ - return wg->palette().color(wg->backgroundRole()); -} - -QColor CPublic::GetWidgetForeColor( QWidget* wg ) -{ - return wg->palette().color(wg->foregroundRole()); -} - -bool CPublic::ReadStreamLine( QTextStream& stream,QString& sLine,int& nRow ) -{ - while( !stream.atEnd() ) - { - sLine = stream.readLine(); - nRow++; - if( sLine!=QString() && !sLine.isEmpty() ) - return true; - } - return false; -} - -//******************************************************************** -// 读子字符串,子字符串间用‘,’隔开 -//******************************************************************** -bool CPublic::GetSubString(const QString& sString, - const int nIndex, QString& sSub) -{ - int nBegin = 0; - for(int i=0; i -bool CPublic::GetSubString(QString& sString, QString& sSub) -{ - int nPos = sString.indexOf(",",0); - if(nPos<0) - { - sSub = sString; - sString = ""; - } - else - { - sSub = sString.left(nPos); - sString = sString.remove(0,nPos+1); - } - return true; -} -//******************************************************************** -// 取位的值 -//******************************************************************** -byte CPublic::GetBitValue(const int nIndex, const WORD wLen, - const char* pData) -{ - int nBytePos = nIndex/8; - int nBitPos = nIndex%8; - - if(nBytePos < (int)wLen) - return (((WORD)(pData[nBytePos]) >> nBitPos) & 0x1); - return 0; -} - -//******************************************************************** -// 时间换算 -//******************************************************************** -void CPublic::GetAbsTime(const QDateTime& pBaseTime, int nTime, QDateTime& pstTime) -{ - QTime BaseTime = pBaseTime.time(); - QDate BaseDate = pBaseTime.date(); - nTime += BaseTime.msec(); - int hour; - int nSec = 0; - int mSec = 0; - int mini = 0; - if(nTime>0) - { - nSec = nTime/1000; - mSec = WORD(nTime%1000); - } - else - { - nSec = -((-nTime)/1000+1); - mSec = nTime-(nSec*1000); - } - - hour = BaseTime.hour(); - mini = BaseTime.minute(); - nSec += BaseTime.second(); - BaseTime.setHMS(hour,mini,nSec,mSec); - - pstTime.setDate(BaseDate); - pstTime.setTime(BaseTime); -} - - -//******************************************************************** -// 浮点数转换为字符串 -//******************************************************************** -QString CPublic::GetDoubleValString(double dVal) -{ - QString sVal; - if(fabs(dVal) >= 0.01) - sVal.sprintf("%.3f ", dVal); - else sVal.sprintf("%.5f ", dVal); - return sVal; -} - -//********************************************************** -//日期转换为两位字符串 -QString CPublic::GetDateString(int nData,int nBitNum) -{ - int nGe,nShi,nBai,nQian,nWan; - if(nBitNum>5||nBitNum<1) return QString(); - nWan = int(nData/10000); - nData = nData-nWan*10000; - nQian = int(nData/1000); - nData = nData-nQian*1000; - nBai = int(nData/100); - nData = nData-nBai*100; - nShi = int(nData/10); - nData = nData-nShi*10; - nGe = nData; - - QString sVal; - switch(nBitNum) - { - case 1: - sVal.sprintf("%d",nGe);break; - case 2: - sVal.sprintf("%d%d",nShi,nGe);break; - case 3: - sVal.sprintf("%d%d%d",nBai,nShi,nGe);break; - case 4: - sVal.sprintf("%d%d%d%d",nQian,nBai,nShi,nGe);break; - case 5: - sVal.sprintf("%d%d%d%d%d",nWan,nQian,nBai,nShi,nGe);break; - default: - return QString(); - } - return sVal; -} -////////////////////////////////////////////////////////////////////////// -//获取时间轴的缩放比率,必须为2的倍数 -////////////////////////////////////////////////////////////////////////// -double CPublic::GetTimeZoomRate( double fRaw ) -{ - double f = 1.0; - if( fRaw >= 1.0 ) - { - for( int i=0;i<5;i++) - { - if( fRaw <= f ) - return f; - f *= 2.0; - } - return f; - } - else - { - for( int i=0;i<5;i++) - { - if( fRaw <= f ) - return f; - f /= 2.0; - } - return f; - } -} - -////////////////////////////////////////////////////////////////////// -// 取整十 -////////////////////////////////////////////////////////////////////// -double CPublic::GetIntergerMax(double bMax) -{ - double dMax = fabs(bMax); - if(dMax <= 1.0) - return 1.0; - if( dMax<=10.0 ) - return 1.0+(int)dMax; - - return ((dMax/10.0) +1)*10.0; -} -////////////////////////////////////////////////////////////////////////// -//caculate -//******************************************************************** -// 计算有效值和相角(角度为度数) -// -//******************************************************************** -void CPublic::CalcuVirtualValue( double* pWaveData, - unsigned int nSampleNum, - unsigned int nSampleRate, - double* pRMSData, - double* pAngleData ) -{ - unsigned int i,j,ne; - double sumc,sums,sumq,rad,fi; - unsigned char gi; - ne=nSampleRate/50; - if(ne<1) return; - if(nSampleNum<1) return; - - j=ne; - rad = M_PI*2.0/ne; //基波角速度 - while(j=0) pAngleData[j]=(fi/ne)*360; - else pAngleData[j]=(fi/ne)*360+180; - } - if((pAngleData[j]>=360)&&(pAngleData[j]<720)) pAngleData[j]-=360;//基波相角 - if(pAngleData[j]<0) pAngleData[j]=fabs(pAngleData[j]);//基波相角 - j++; - } - for(j=0;j= lends-1 ) - { - int i=0; - for( i=lends;i= lends) - { - return true; - } - - if( pos+len < lends ) - { - int i = 0; - for(i=0;i= lends-1 ) - { - memcpy(buff+lends,dc,lendc*sizeof(char)); - } - else - { - pos = pos + 1; - memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(char)); - memcpy(buff+pos,dc,lendc*sizeof(char)); - } - return true; -}; - -bool CPublic::RemoveByteArray( QByteArray& datasrc, int pos,int len ) -{ - if(len<=0) - return true; - - int lends = datasrc.size(); - - if( pos <0 || pos >= lends-1) - { - return true; - } - - if( pos+len < lends ) - { - char *buff = datasrc.data(); - memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(char)); - datasrc.resize(lends-len); - } - else - { - datasrc.resize(pos); - } - return true; -}; - -struct wavedata_old wave_datao; -struct wavedata_old * wdp[100]; //故障选线所需线路波形数据指针 -struct wavedata_old * wpi; //双端测距本端波形数据块指针 -struct wavedata_old * wpj; //双端测距对端波形数据块指针 - -//******************************************************************** -// 计算有效值和相角(角度为度数) -//******************************************************************** -void CPublic::CalcuVirtualValue() -{ - double* pi = wave_datao.pi[0]; - - unsigned int i,j,ne; - double sumc,sums,sumq,rad,fi; - unsigned char gi; - ne=wave_datao.fsi/50; - j=ne; - rad = M_PI*2.0/ne; //基波角速度 - while(j=0) wave_datao.po[1][j]=(fi/ne)*360; - else wave_datao.po[1][j]=(fi/ne)*360+180; - } - if((wave_datao.po[1][j]>=360)&&(wave_datao.po[1][j]<720)) wave_datao.po[1][j]-=360;//基波相角 - if(wave_datao.po[1][j]<0) wave_datao.po[1][j]=fabs(wave_datao.po[1][j]);//基波相角 - j++; - } - for(j=0;j0) - { //求出各个过零点的频率值 - da[0]=fabs(wave_datao.po[1][j-wave_datao.pfo[j]-1]); - da[1]=fabs(wave_datao.po[1][j-wave_datao.pfo[j]]); - da[2]=fabs(wave_datao.po[1][j-1]); - da[3]=fabs(wave_datao.po[1][j]); - wave_datao.po[0][j]=wave_datao.fsi/(2*(da[1]/(da[0]+da[1])+da[2]/(da[2]+da[3])+wave_datao.pfo[j]-1)); - } - } - wave_datao.po[0][0]=50; //初始点设为50赫兹 - wave_datao.po[0][1]=50; //初始点设为50赫兹 - j=0; - while(wave_datao.pfo[j]==0) j++; - wave_datao.po[0][j]=50; //第一个过零点设为50赫兹 - for(j=wave_datao.numi-1;j>0;j--) - { - if(wave_datao.pfo[j]>0) - { - for(i=1;i0){ //求出各个过零点的频率值 - da[0]=fabs(wave_datao.po[1][j-wave_datao.pfo[j]-1]); - da[1]=fabs(wave_datao.po[1][j-wave_datao.pfo[j]]); - da[2]=fabs(wave_datao.po[1][j-1]); - da[3]=fabs(wave_datao.po[1][j]); - da[4]=wave_datao.pfo[j]-1; - if((da[0]+da[1])==0) da[4]+=0; - else da[4]+=da[1]/(da[0]+da[1]); - if((da[2]+da[3])==0) da[4]+=0; - else da[4]+=da[2]/(da[2]+da[3]); - if(da[4]==0) wave_datao.po[0][j]=0; - else wave_datao.po[0][j]=wave_datao.fsi/(2*da[4]); - } - } - wave_datao.po[0][0]=50; //初始点设为50赫兹 - wave_datao.po[0][1]=50; //初始点设为50赫兹 - j=0; - while(wave_datao.pfo[j]==0) j++; - wave_datao.po[0][j]=50; //第一个过零点设为50赫兹 - for(j=wave_datao.numi-1;j>0;j--){ - if(wave_datao.pfo[j]>0){ - for(i=1;i<(int)wave_datao.pfo[j];i++){ //插值求出中间点的频率 - wave_datao.po[0][j-i]=((wave_datao.pfo[j]-i)*wave_datao.po[0][j]+wave_datao.po[0][j-wave_datao.pfo[j]]*i)/wave_datao.pfo[j]; - } - } - } -} - - -//******************************************************************** -// 计算平均值 -//******************************************************************** -void CPublic::Average(int nAveTicks) -{ - double dSum; - int i=0,j=0; - for( i=0; i<(int)wave_datao.numi; i++) - { - dSum = 0.0; - for( j=0; j0) dSum /= j; - wave_datao.po[0][i] = dSum; - } -} - - -//******************************************************************** -// 计算最大最小值 -//******************************************************************** -void CPublic::CalcuMinMax() -{ - wave_datao.dMinVal = 1e100; - wave_datao.dMaxVal = -1e100; - wave_datao.nMinTick = 0; - wave_datao.nMaxTick = 0; - for(unsigned int j=0; j wave_datao.dMaxVal) - { - wave_datao.dMaxVal = wave_datao.pi[0][j]; - wave_datao.nMaxTick = j; - } - } -} - - -//******************************************************************** -// 直接移相法 计算序分量 -//******************************************************************** -void CPublic::Subsequence() -{ - unsigned int i,j,k,ne,ne31,ne32; - double sumc,rad; -// double sums; - ne = wave_datao.fsi/50; - rad = M_PI*2.0/ne; //角速度 - for(k=0;k<3;k++) // 求出非周期分量 - { - j=ne; - while(j40) hi=20; //最高次谐波次数 - else hi = ne/2; //满足采样定理 - j=ne; - for(num=1;num<=hi;num++) //整数次谐波分量 - { - rad=M_PI*2.0*num/ne; //角速度 - while(j>2); - m=(ne<<1)-(ne>>2); - rad=M_PI*2.0/ne; //基波角速度 - while(j>2)) sums+=wave_datao.pi[0][j+i-k]*wave_datao.pi[1][j+i-ne]; - else sums+=wave_datao.pi[0][j+i-m]*wave_datao.pi[1][j+i-ne]; - } - if(wave_datao.type==1){ //LFP老保护 - ma[0]=sumc*cos(wave_datao.angle*M_PI/180.0)-sums*sin(wave_datao.angle*M_PI/180.0); - mb[0]=sums*cos(wave_datao.angle*M_PI/180.0)+sumc*sin(wave_datao.angle*M_PI/180.0); - sumc=ma[0]; - sums=mb[0]; - } - wave_datao.po[0][j]=sumc/ne; - wave_datao.po[1][j]=sums/ne; - wave_datao.po[2][j++]=sumc/(sqrt(sumc*sumc+sums*sums)); - } - } - for(j=0;j>2); - m=(ne<<1)-(ne>>2); - rad=M_PI*2.0/ne; //基波角速度 - while(j>2)) sums+=wave_datao.pi[0][j+i-k]*wave_datao.pi[3][j+i-ne]+wave_datao.pi[1][j+i-k]*wave_datao.pi[4][j+i-ne]+wave_datao.pi[2][j+i-k]*wave_datao.pi[5][j+i-ne]; - else sums+=wave_datao.pi[0][j+i-m]*wave_datao.pi[3][j+i-ne]+wave_datao.pi[1][j+i-m]*wave_datao.pi[4][j+i-ne]+wave_datao.pi[2][j+i-m]*wave_datao.pi[5][j+i-ne]; - } - if(wave_datao.type==1){ //LFP老保护 - ma[0]=sumc*cos(wave_datao.angle*M_PI/180.0)-sums*sin(wave_datao.angle*M_PI/180.0); - mb[0]=sums*cos(wave_datao.angle*M_PI/180.0)+sumc*sin(wave_datao.angle*M_PI/180.0); - sumc=ma[0]; - sums=mb[0]; - } - wave_datao.po[0][j]=sumc/ne; //有功 - wave_datao.po[1][j]=sums/ne; //无功 - wave_datao.po[2][j++]=sumc/(sqrt(sumc*sumc+sums*sums)); //功率因数 - } - } - for(j=0;jwave_datao.dzlqd) dnum[0]++; - else if(dnum[0]>0) dnum[0]--; - if(fabs(wave_datao.pi[1][j]-wave_datao.pi[1][j-ne])>wave_datao.dzlqd) dnum[1]++; - else if(dnum[1]>0) dnum[1]--; - if(fabs(wave_datao.pi[2][j]-wave_datao.pi[2][j-ne])>wave_datao.dzlqd) dnum[2]++; - else if(dnum[2]>0) dnum[2]--; - if(dnum[0]>3||dnum[1]>3||dnum[2]>3) - { //任意一相连续三点满足突变量起动要求 - k=j; - break; - } - j++; - } - if((k>=ne+3)&&(kmax[0])&&(wave_datao.po[4][j]>max[1])&&(wave_datao.po[5][j]>max[2])) dnum[3]++; - else if(dnum[3]>0) dnum[3]--; - if(dnum[3]>3) break; - } - if(dnum[3]>3) - { //接地故障 - for(j=k-3;j0) dnum[0]--; - if((25*max[2]0) dnum[1]--; - if((25*max[0]0) dnum[2]--; - if(dnum[0]>3) return 1; //a相接地短路 - if(dnum[1]>3) return 2; //b相接地短路 - if(dnum[2]>3) return 3; //c相接地短路 - } - for(i=0;i<3;i++) dnum[i]=0; - for(j=k-3;j0) dnum[0]--; - if((max[0]0) dnum[1]--; - if((max[1]0) dnum[2]--; - if(dnum[0]>3) return 7; //ab相间接地短路 - if(dnum[1]>3) return 8; //bc相间接地短路 - if(dnum[2]>3) return 9; //ca相间接地短路 - } - } - else - { //不接地故障 - max[3]=wave_datao.sill[3]*wave_datao.dled; //三相短路电流门槛 - for(j=k-3;jmax[3])&&(max[1]>max[3])&&(max[2])>max[3]) dnum[0]++; - else if(dnum[0]>0) dnum[0]--; - if(dnum[0]>3) return 10; //三相短路 - } - for(i=0;i<3;i++) dnum[i]=0; - for(j=k-3;j0) dnum[0]--; - if((max[0]0) dnum[1]--; - if((max[1]0) dnum[2]--; - if(dnum[0]>3) return 4; //ab相间短路 - if(dnum[1]>3) return 5; //bc相间短路 - if(dnum[2]>3) return 6; //ca相间短路 - } - } - } - return 0; -} - - -//******************************************************************** -// 单端测距(阻抗算法) -// -// 输入: -// mode 故障类型 -// 1: A相接地短路 -// 2: B相接地短路 -// 3: C相接地短路 -// 4: AB相间短路 -// 5: BC相间短路 -// 6: CA相间短路 -// 7: AB相接地短路 -// 8: BC相接地短路 -// 9: CA相接地短路 -// 10: ABC三相短路 -// wave_datao.numi 采样点数 -// wave_datao.fsi 采样率 -// wave_datao.pi[0] A相电流瞬时值 -// wave_datao.pi[1] B相电流瞬时值 -// wave_datao.pi[2] C相电流瞬时值 -// wave_datao.pi[3] A相电压瞬时值 -// wave_datao.pi[4] B相电压瞬时值 -// wave_datao.pi[5] C相电压瞬时值 -// wave_datao.pi[6] 零序电流 -// wave_datao.pi[7] 零序电压 -// wave_datao.zerocomp 零序补偿系数 -// -// wave_datao.dzlqd 电流启动定值 -// wave_datao.type =1: LFP老保护, -// wave_datao.angle 当为LFP老保护时,电流旋转角 一般78度 -// -// wave_datao.xps 正序电抗 -// wave_datao.rps 正序电阻 -// wave_datao.xps0 零序电抗 -// wave_datao.rps0 零序电阻 -// wave_datao.length 线路长度 -// -// 输出: -// double* dImp 阻抗 -// double* dLen 距离 -// -// 新算法 -// 阻抗法单端测距(电气量算法) -// 本函数只需输入故障类型代码,返回值为测距长度其他参数同 -// 本函数和以前的测距函数直接由输入的正序阻抗和零序阻抗计算 -// 零序补偿系数,不受输入的零序补偿系数影响 -// -//******************************************************************** -void CPublic::SingleFaultLoc(unsigned int mode, double* dImp, double* dLen) -{ - /* - (*dImp) = 0.0; - (*dLen) = 0.0; - - unsigned int i,j,k,ne,dnum[4]; - double e,ma[6],mb[6],com,sum,rad,zmp,zmp0; - ne=wave_datao.fsi/50; //每周采样数 - rad=M_PI*2.0/ne; //角速度 - e=wave_datao.xps/wave_datao.rps; //正序电抗/电阻之比 - zmp=sqrt(wave_datao.xps*wave_datao.xps+wave_datao.rps*wave_datao.rps); - zmp0=sqrt(wave_datao.xps0*wave_datao.xps0+wave_datao.rps0*wave_datao.rps0); -// com=(wave_datao.xps0-wave_datao.xps)/(3*wave_datao.xps); //零序补偿系数 - com=(zmp0-zmp)/(3*zmp); //零序补偿系数 - j=ne; - k=0; - for(i=0;i<3;i++) dnum[i]=0; - while(jwave_datao.dzlqd) dnum[0]++; - else if(dnum[0]>0) dnum[0]--; - if(fabs(wave_datao.pi[1][j]-wave_datao.pi[1][j-ne])>wave_datao.dzlqd) dnum[1]++; - else if(dnum[1]>0) dnum[1]--; - if(fabs(wave_datao.pi[2][j]-wave_datao.pi[2][j-ne])>wave_datao.dzlqd) dnum[2]++; - else if(dnum[2]>0) dnum[2]--; - if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 - k=j; - break; - } - j++; - } - for(i=0;i<6;i++){ - ma[i]=0; - mb[i]=0; - } - if((k>=ne+3)&&(k>1)+ne; //起动后一个半周期 - switch(mode){ - case 1: //a相接地短路 - for(i=0;iwave_datao.dzlqd) dnum[0]++; - else if(dnum[0]>0) dnum[0]--; - if(fabs(wave_datao.pi[1][j]-wave_datao.pi[1][j-ne])>wave_datao.dzlqd) dnum[1]++; - else if(dnum[1]>0) dnum[1]--; - if(fabs(wave_datao.pi[2][j]-wave_datao.pi[2][j-ne])>wave_datao.dzlqd) dnum[2]++; - else if(dnum[2]>0) dnum[2]--; - if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 - k=j; - break; - } - j++; - } - for(i=0;i<6;i++){ - ma[i]=0; - mb[i]=0; - } - if((k>=ne+3)&&(k>1)+2*ne; //起动后一个半周期 - switch(mode){ - case 1: //a相接地短路 - for(i=0;inumi 采样点数 -// wpi->fsi 采样率 -// wpi->pi[0] A相电流瞬时值 -// wpi->pi[1] B相电流瞬时值 -// wpi->pi[2] C相电流瞬时值 -// wpi->pi[3] A相电压瞬时值 -// wpi->pi[4] B相电压瞬时值 -// wpi->pi[5] C相电压瞬时值 -// wpi->pi[6] 零序电流 -// wpi->pi[7] 零序电压 -// -// wpi->dzlqd 电流启动定值 -// wpi->type =1: LFP老保护, -// wpi->angle 当为LFP老保护时,电流旋转角 一般78度 -// -// wpi->xps 正序电抗 -// wpi->rps 正序电阻 -// wpi->xps0 零序电抗 -// wpi->rps0 零序电阻 -// wpi->length 线路长度 -// wpi->zerocomp 零序补偿系数 -// -// 对侧数据块: -// wpj->numi 采样点数 -// wpj->fsi 采样率 -// wpj->pi[0] A相电流瞬时值 -// wpj->pi[1] B相电流瞬时值 -// wpj->pi[2] C相电流瞬时值 -// wpj->pi[3] A相电压瞬时值 -// wpj->pi[4] B相电压瞬时值 -// wpj->pi[5] C相电压瞬时值 -// wpj->pi[6] 零序电流 -// wpj->pi[7] 零序电压 -// -// wpj->dzlqd 电流启动定值 -// wpj->type =1: LFP老保护, -// wpj->angle 当为LFP老保护时,电流旋转角 一般78度 -// -// 输出: -// double* dImp 阻抗 -// double* dLen 距离 -// -//******************************************************************** -void CPublic::DoubleFaultLoc(unsigned int mode, double* dImp, double* dLen) -{ - //双端测距(阻抗算法) - - (*dImp) = 0.0; - (*dLen) = 0.0; - - unsigned int i,j,ki,kj,nei,nej,dnum[4]; - double ma[8],mb[8],na[8],nb[8],com,sum,radi,radj,sumi,sumj,zmp; - nei=wpi->fsi/50; //本端每周采样数 - radi=M_PI*2.0/nei; //本端角速度 - nej=wpj->fsi/50; //对端每周采样数 - radj=M_PI*2.0/nej; //对端角速度 - zmp=sqrt(wpi->xps*wpi->xps+wpi->rps*wpi->rps); //全线路阻抗 - com=wpi->zerocomp; //零序补偿系数 - j=nei; - ki=0; - for(i=0;i<3;i++) dnum[i]=0; - while(jnumi){ //起动判断 - if(fabs(wpi->pi[0][j]-wpi->pi[0][j-nei])>wpi->dzlqd) dnum[0]++; - else if(dnum[0]>0) dnum[0]--; - if(fabs(wpi->pi[1][j]-wpi->pi[1][j-nei])>wpi->dzlqd) dnum[1]++; - else if(dnum[1]>0) dnum[1]--; - if(fabs(wpi->pi[2][j]-wpi->pi[2][j-nei])>wpi->dzlqd) dnum[2]++; - else if(dnum[2]>0) dnum[2]--; - if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 - ki=j; - break; - } - j++; - } - j=nej; - kj=0; - for(i=0;i<3;i++) dnum[i]=0; - while(jnumi){ //起动判断 - if(fabs(wpj->pi[0][j]-wpj->pi[0][j-nej])>wpj->dzlqd) dnum[0]++; - else if(dnum[0]>0) dnum[0]--; - if(fabs(wpj->pi[1][j]-wpj->pi[1][j-nej])>wpj->dzlqd) dnum[1]++; - else if(dnum[1]>0) dnum[1]--; - if(fabs(wpj->pi[2][j]-wpj->pi[2][j-nej])>wpj->dzlqd) dnum[2]++; - else if(dnum[2]>0) dnum[2]--; - if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 - kj=j; - break; - } - j++; - } - for(i=0;i<8;i++){ - ma[i]=0; - mb[i]=0; - na[i]=0; - nb[i]=0; - } - if((ki>=nei+3)&&(kinumi-2*nei)&&(kj>=nej+3)&&(kjnumi-2*nej)){ //起动元件动作 - j=ki-nei; //本端起动前一个周期 - for(i=0;ipi[0][j+i-nei]*cos(radi*i); //a相电流实部 - mb[0]-=wpi->pi[0][j+i-nei]*sin(radi*i); //a相电流虚部 - ma[1]+=wpi->pi[1][j+i-nei]*cos(radi*i); //b相电流实部 - mb[1]-=wpi->pi[1][j+i-nei]*sin(radi*i); //b相电流虚部 - ma[2]+=wpi->pi[2][j+i-nei]*cos(radi*i); //c相电流实部 - mb[2]-=wpi->pi[2][j+i-nei]*sin(radi*i); //c相电流虚部 - ma[3]+=wpi->pi[3][j+i-nei]*cos(radi*i); //a相电压实部 - mb[3]-=wpi->pi[3][j+i-nei]*sin(radi*i); //a相电压虚部 - ma[4]+=wpi->pi[4][j+i-nei]*cos(radi*i); //b相电压实部 - mb[4]-=wpi->pi[4][j+i-nei]*sin(radi*i); //b相电压虚部 - ma[5]+=wpi->pi[5][j+i-nei]*cos(radi*i); //c相电压实部 - mb[5]-=wpi->pi[5][j+i-nei]*sin(radi*i); //c相电压虚部 - } - j=kj-nej; //对端起动前一个周期 - for(i=0;ipi[0][j+i-nej]*cos(radj*i); //a相电流实部 - nb[0]-=wpj->pi[0][j+i-nej]*sin(radj*i); //a相电流虚部 - na[1]+=wpj->pi[1][j+i-nej]*cos(radj*i); //b相电流实部 - nb[1]-=wpj->pi[1][j+i-nej]*sin(radj*i); //b相电流虚部 - na[2]+=wpj->pi[2][j+i-nej]*cos(radj*i); //c相电流实部 - nb[2]-=wpj->pi[2][j+i-nej]*sin(radj*i); //c相电流虚部 - na[3]+=wpj->pi[3][j+i-nej]*cos(radj*i); //a相电压实部 - nb[3]-=wpj->pi[3][j+i-nej]*sin(radj*i); //a相电压虚部 - na[4]+=wpj->pi[4][j+i-nej]*cos(radj*i); //b相电压实部 - nb[4]-=wpj->pi[4][j+i-nej]*sin(radj*i); //b相电压虚部 - na[5]+=wpj->pi[5][j+i-nej]*cos(radj*i); //c相电压实部 - nb[5]-=wpj->pi[5][j+i-nej]*sin(radj*i); //c相电压虚部 - } - ma[6]=(ma[0]-0.5*ma[1]-0.8660254*mb[1]-0.5*ma[2]+0.8660254*mb[2])/nei; //本端正序电流 - mb[6]=(mb[0]-0.5*mb[1]+0.8660254*ma[1]-0.5*mb[2]-0.8660254*ma[2])/nei; - ma[1]=(ma[3]-0.5*ma[4]-0.8660254*mb[4]-0.5*ma[5]+0.8660254*mb[5])/nei; //本端正序电压 - mb[1]=(mb[3]-0.5*mb[4]+0.8660254*ma[4]-0.5*mb[5]-0.8660254*ma[5])/nei; - if(wpi->type==1){ //LFP老保护电流移相 - ma[0]=ma[6]*cos(0.0174533*wpi->angle)+mb[6]*sin(0.0174533*wpi->angle); - mb[0]=mb[6]*cos(0.0174533*wpi->angle)-ma[6]*sin(0.0174533*wpi->angle); - ma[6]=ma[0]; - mb[6]=mb[0]; - } - ma[2]=ma[1]-ma[6]*wpi->rps+mb[6]*wpi->xps; //由本侧计算出的对端电压 - mb[2]=mb[1]-ma[6]*wpi->xps-mb[6]*wpi->rps; - - na[6]=(na[0]-0.5*na[1]-0.8660254*nb[1]-0.5*na[2]+0.8660254*nb[2])/nej; //对端正序电流 - nb[6]=(nb[0]-0.5*nb[1]+0.8660254*na[1]-0.5*nb[2]-0.8660254*na[2])/nej; - na[1]=(na[3]-0.5*na[4]-0.8660254*nb[4]-0.5*na[5]+0.8660254*nb[5])/nej; //对端正序电压 - nb[1]=(nb[3]-0.5*nb[4]+0.8660254*na[4]-0.5*nb[5]-0.8660254*na[5])/nej; - if(wpj->type==1){ //LFP老保护电流移相 - na[0]=na[6]*cos(0.0174533*wpj->angle)+nb[6]*sin(0.0174533*wpj->angle); - nb[0]=nb[6]*cos(0.0174533*wpj->angle)-na[6]*sin(0.0174533*wpj->angle); - na[6]=na[0]; - nb[6]=nb[0]; - } - na[2]=na[1]-na[6]*wpi->rps+nb[6]*wpi->xps; //由对端计算出的本侧电压 - nb[2]=nb[1]-na[6]*wpi->xps-nb[6]*wpi->rps; - sumi=na[1]*na[1]+nb[1]*nb[1]; - sumj=na[2]*na[2]+nb[2]*nb[2]; - ma[3]=(ma[2]*na[1]+mb[2]*nb[1])/sumi; - mb[3]=(mb[2]*na[1]-ma[2]*nb[1])/sumi; - na[3]=(ma[1]*na[2]+mb[1]*nb[2])/sumj; - nb[3]=(mb[1]*na[2]-ma[1]*nb[2])/sumj; - sumi=(ma[3]+na[3])/2; //旋转因子实部 - sumj=(mb[3]+nb[3])/2; //旋转因子虚部 - for(i=0;i<6;i++){ - ma[i]=0; - mb[i]=0; - na[i]=0; - nb[i]=0; - } - switch(mode){ - case 1: //a相接地短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[0][j+i-nei]+com*wpi->pi[6][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[0][j+i-nei]+com*wpi->pi[6][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=wpi->pi[3][j+i-nei]*cos(radi*i); //电压实部 - mb[1]-=wpi->pi[3][j+i-nei]*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[0][j+i-nej]+com*wpj->pi[6][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[0][j+i-nej]+com*wpj->pi[6][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=wpj->pi[3][j+i-nej]*cos(radj*i); //电压实部 - nb[1]-=wpj->pi[3][j+i-nej]*sin(radj*i); //电压虚部 - } - break; - case 2: //b相接地短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[1][j+i-nei]+com*wpi->pi[6][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[1][j+i-nei]+com*wpi->pi[6][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=wpi->pi[4][j+i-nei]*cos(radi*i); //电压实部 - mb[1]-=wpi->pi[4][j+i-nei]*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[1][j+i-nej]+com*wpj->pi[6][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[1][j+i-nej]+com*wpj->pi[6][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=wpj->pi[4][j+i-nej]*cos(radj*i); //电压实部 - nb[1]-=wpj->pi[4][j+i-nej]*sin(radj*i); //电压虚部 - } - break; - case 3: //c相接地短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[2][j+i-nei]+com*wpi->pi[6][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[2][j+i-nei]+com*wpi->pi[6][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=wpi->pi[5][j+i-nei]*cos(radi*i); //电压实部 - mb[1]-=wpi->pi[5][j+i-nei]*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[2][j+i-nej]+com*wpj->pi[6][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[2][j+i-nej]+com*wpj->pi[6][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=wpj->pi[5][j+i-nej]*cos(radj*i); //电压实部 - nb[1]-=wpj->pi[5][j+i-nej]*sin(radj*i); //电压虚部 - } - break; - case 4: //ab相间短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[0][j+i-nei]-wpi->pi[1][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[0][j+i-nei]-wpi->pi[1][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*cos(radi*i); //电压实部 - mb[1]-=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[0][j+i-nej]-wpj->pi[1][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[0][j+i-nej]-wpj->pi[1][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*cos(radj*i); //电压实部 - nb[1]-=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*sin(radj*i); //电压虚部 - } - break; - case 5: //bc相间短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[1][j+i-nei]-wpi->pi[2][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[1][j+i-nei]-wpi->pi[2][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=(wpi->pi[4][j+i-nei]-wpi->pi[5][j+i-nei])*cos(radi*i); //电压实部 - mb[1]-=(wpi->pi[4][j+i-nei]-wpi->pi[5][j+i-nei])*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[1][j+i-nej]-wpj->pi[2][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[1][j+i-nej]-wpj->pi[2][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=(wpj->pi[4][j+i-nej]-wpj->pi[5][j+i-nej])*cos(radj*i); //电压实部 - nb[1]-=(wpj->pi[4][j+i-nej]-wpj->pi[5][j+i-nej])*sin(radj*i); //电压虚部 - } - break; - case 6: //ca相间短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[2][j+i-nei]-wpi->pi[0][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[2][j+i-nei]-wpi->pi[0][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=(wpi->pi[5][j+i-nei]-wpi->pi[3][j+i-nei])*cos(radi*i); //电压实部 - mb[1]-=(wpi->pi[5][j+i-nei]-wpi->pi[3][j+i-nei])*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[2][j+i-nej]-wpj->pi[0][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[2][j+i-nej]-wpj->pi[0][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=(wpj->pi[5][j+i-nej]-wpj->pi[3][j+i-nej])*cos(radj*i); //电压实部 - nb[1]-=(wpj->pi[5][j+i-nej]-wpj->pi[3][j+i-nej])*sin(radj*i); //电压虚部 - } - break; - case 7: //ab相间接地短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[0][j+i-nei]-wpi->pi[1][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[0][j+i-nei]-wpi->pi[1][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*cos(radi*i); //电压实部 - mb[1]-=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[0][j+i-nej]-wpj->pi[1][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[0][j+i-nej]-wpj->pi[1][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*cos(radj*i); //电压实部 - nb[1]-=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*sin(radj*i); //电压虚部 - } - break; - case 8: //bc相间接地短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[1][j+i-nei]-wpi->pi[2][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[1][j+i-nei]-wpi->pi[2][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=(wpi->pi[4][j+i-nei]-wpi->pi[5][j+i-nei])*cos(radi*i); //电压实部 - mb[1]-=(wpi->pi[4][j+i-nei]-wpi->pi[5][j+i-nei])*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[1][j+i-nej]-wpj->pi[2][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[1][j+i-nej]-wpj->pi[2][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=(wpj->pi[4][j+i-nej]-wpj->pi[5][j+i-nej])*cos(radj*i); //电压实部 - nb[1]-=(wpj->pi[4][j+i-nej]-wpj->pi[5][j+i-nej])*sin(radj*i); //电压虚部 - } - case 9: //ca相间接地短路 - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[2][j+i-nei]-wpi->pi[0][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[2][j+i-nei]-wpi->pi[0][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=(wpi->pi[5][j+i-nei]-wpi->pi[3][j+i-nei])*cos(radi*i); //电压实部 - mb[1]-=(wpi->pi[5][j+i-nei]-wpi->pi[3][j+i-nei])*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[2][j+i-nej]-wpj->pi[0][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[2][j+i-nej]-wpj->pi[0][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=(wpj->pi[5][j+i-nej]-wpj->pi[3][j+i-nej])*cos(radj*i); //电压实部 - nb[1]-=(wpj->pi[5][j+i-nej]-wpj->pi[3][j+i-nej])*sin(radj*i); //电压虚部 - } - break; - case 10: //abc三相短路(任选ab相间电气量计算) - j=ki+2*nei; //本端起动后两个周期 - for(i=0;ipi[0][j+i-nei]-wpi->pi[1][j+i-nei])*cos(radi*i); //电流实部 - mb[0]-=(wpi->pi[0][j+i-nei]-wpi->pi[1][j+i-nei])*sin(radi*i); //电流虚部 - ma[1]+=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*cos(radi*i); //电压实部 - mb[1]-=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*sin(radi*i); //电压虚部 - } - j=kj+2*nej; //对端起动后两个周期 - for(i=0;ipi[0][j+i-nej]-wpj->pi[1][j+i-nej])*cos(radj*i); //电流实部 - nb[0]-=(wpj->pi[0][j+i-nej]-wpj->pi[1][j+i-nej])*sin(radj*i); //电流虚部 - na[1]+=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*cos(radj*i); //电压实部 - nb[1]-=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*sin(radj*i); //电压虚部 - } - break; - } - ma[0]=2*ma[0]/nei; //本端电流 - mb[0]=2*mb[0]/nei; - if(wpi->type==1){ //LFP老保护电流移相 - ma[6]=ma[0]*cos(0.0174533*wpi->angle)+mb[0]*sin(0.0174533*wpi->angle); - mb[6]=mb[0]*cos(0.0174533*wpi->angle)-ma[0]*sin(0.0174533*wpi->angle); - ma[0]=ma[6]; - mb[0]=mb[6]; - } - ma[1]=2*ma[1]/nei; //本端电压 - mb[1]=2*mb[1]/nei; - na[0]=2*na[0]/nej; //对端电流 - nb[0]=2*nb[0]/nej; - if(wpj->type==1){ //LFP老保护电流移相 - na[6]=na[0]*cos(0.0174533*wpj->angle)+nb[0]*sin(0.0174533*wpj->angle); - nb[6]=nb[0]*cos(0.0174533*wpj->angle)-na[0]*sin(0.0174533*wpj->angle); - na[0]=na[6]; - nb[0]=nb[6]; - } - na[1]=2*na[1]/nej; //对端电压 - nb[1]=2*nb[1]/nej; - na[2]=na[0]*sumi-nb[0]*sumj; //同步后的对端电流 - nb[2]=nb[0]*sumi+na[0]*sumj; - na[3]=na[1]*sumi-nb[1]*sumj; //同步后的对端电压 - nb[3]=nb[1]*sumi+na[1]*sumj; - ma[2]=ma[0]+na[2]; - mb[2]=mb[0]+nb[2]; - ma[3]=ma[1]-na[3]+na[2]*wpi->rps-nb[2]*wpi->xps; - mb[3]=mb[1]-nb[3]+nb[2]*wpi->rps+na[2]*wpi->xps; - sum=ma[2]*ma[2]+mb[2]*mb[2]; - ma[4]=(ma[3]*ma[2]+mb[3]*mb[2])/sum; //故障点至母线处电阻R - mb[4]=(mb[3]*ma[2]-ma[3]*mb[2])/sum; //故障点至母线处电抗X - (*dImp)=sqrt(ma[4]*ma[4]+mb[4]*mb[4]); //故障点至母线处阻抗值 - (*dLen)=wpi->length*(*dImp)/zmp; //故障点至母线处距离 - } -} - -//******************************************************************** -// 故障选线(复合功率因数突变量算法) -// -// 输入: -// -// 输出: -// true: 有选线结果 -// false: 无选线结果 -// -// line数组:线路号的排序 -// -//******************************************************************** -bool CPublic::CalcuFaultLine(int num, unsigned int* line) -{ - if(num<=0 || num>100) return false; - - int i,j,dir,k,m,n,max,*pd,*pr; - double *pp; - pd=new int[num]; - pr=new int[num]; - pp=new double[num]; - if((pd==NULL)||(pr==NULL)||(pp==NULL)){ - if(pd!=NULL) delete [] pd; - if(pr!=NULL) delete [] pr; - if(pp!=NULL) delete [] pp; - return false; - } - k=0; - m=0; - n=0; - for(i=0;ifsi/50; //每周采样数 - rad=M_PI*2.0/ne; //角速度 - j=ne; - k=0; - for(i=0;i<3;i++) dnum[i]=0; - while(jnumi){ //起动判断 - if(fabs(wp->pi[0][j]-wp->pi[0][j-ne])>wp->dzlqd) dnum[0]++; - else if(dnum[0]>0) dnum[0]--; - if(fabs(wp->pi[1][j]-wp->pi[1][j-ne])>wp->dzlqd) dnum[1]++; - else if(dnum[1]>0) dnum[1]--; - if(fabs(wp->pi[2][j]-wp->pi[2][j-ne])>wp->dzlqd) dnum[2]++; - else if(dnum[2]>0) dnum[2]--; - if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 - k=j; - break; - } - j++; - } - for(i=0;i<8;i++){ - ma[i]=0; - mb[i]=0; - } - if((k>=ne+3)&&(knumi-2*ne)){ //起动元件动作(测距计算采用起动点前后两个周波数据) - j=k+(ne>>1)+ne; //起动后一个半周期 - for(i=0;ipi[0][j+i-ne]-wp->pi[0][j+i-3*ne])*cos(rad*i); //a相故障电流实部 - mb[0]-=(wp->pi[0][j+i-ne]-wp->pi[0][j+i-3*ne])*sin(rad*i); //a相故障电流虚部 - ma[1]+=(wp->pi[1][j+i-ne]-wp->pi[1][j+i-3*ne])*cos(rad*i); //b相故障电流实部 - mb[1]-=(wp->pi[1][j+i-ne]-wp->pi[1][j+i-3*ne])*sin(rad*i); //b相故障电流虚部 - ma[2]+=(wp->pi[2][j+i-ne]-wp->pi[2][j+i-3*ne])*cos(rad*i); //c相故障电流实部 - mb[2]-=(wp->pi[2][j+i-ne]-wp->pi[2][j+i-3*ne])*sin(rad*i); //c相故障电流虚部 - ma[3]+=(wp->pi[3][j+i-ne]-wp->pi[3][j+i-3*ne])*cos(rad*i); //a相故障电压实部 - mb[3]-=(wp->pi[3][j+i-ne]-wp->pi[3][j+i-3*ne])*sin(rad*i); //a相故障电压虚部 - ma[4]+=(wp->pi[4][j+i-ne]-wp->pi[4][j+i-3*ne])*cos(rad*i); //b相故障电压实部 - mb[4]-=(wp->pi[4][j+i-ne]-wp->pi[4][j+i-3*ne])*sin(rad*i); //b相故障电压虚部 - ma[5]+=(wp->pi[5][j+i-ne]-wp->pi[5][j+i-3*ne])*cos(rad*i); //c相故障电压实部 - mb[5]-=(wp->pi[5][j+i-ne]-wp->pi[5][j+i-3*ne])*sin(rad*i); //c相故障电压虚部 - } - ma[6]=(ma[0]-0.5*ma[1]-0.8660254*mb[1]-0.5*ma[2]+0.8660254*mb[2])/ne; //正序故障电流 - mb[6]=(mb[0]-0.5*mb[1]+0.8660254*ma[1]-0.5*mb[2]-0.8660254*ma[2])/ne; - ma[1]=(ma[3]-0.5*ma[4]-0.8660254*mb[4]-0.5*ma[5]+0.8660254*mb[5])/ne; //故障正序电压 - mb[1]=(mb[3]-0.5*mb[4]+0.8660254*ma[4]-0.5*mb[5]-0.8660254*ma[5])/ne; - if(wp->type==1){ //LFP老保护电流移相 - ma[0]=ma[6]*cos(0.0174533*wp->angle)+mb[6]*sin(0.0174533*wp->angle); - mb[0]=mb[6]*cos(0.0174533*wp->angle)-ma[6]*sin(0.0174533*wp->angle); - ma[6]=ma[0]; - mb[6]=mb[0]; - } - ma[7]=ma[1]*mb[6]-mb[1]*ma[6]; - mb[7]=ma[1]*ma[6]+mb[1]*mb[6]; - amp=sqrt(ma[6]*ma[6]+mb[6]*mb[6]); //故障电流幅值 - if((ma[7]>0)&&(fabs(mb[7]) +#include +#include +#include +#include +#include "CPublic.h" + +void CPublic::SetWidgetBackColor( QWidget* wg,const QColor& bc ) +{ + QPalette plt = wg->palette(); + plt.setColor(wg->backgroundRole(), bc); + wg->setPalette(plt); +} + +void CPublic::SetWidgetForeColor( QWidget* wg,const QColor& fc ) +{ + QPalette plt = wg->palette(); + plt.setColor(wg->foregroundRole(), fc); + wg->setPalette(plt); +} + +QColor CPublic::GetWidgetBackColor( QWidget* wg ) +{ + return wg->palette().color(wg->backgroundRole()); +} + +QColor CPublic::GetWidgetForeColor( QWidget* wg ) +{ + return wg->palette().color(wg->foregroundRole()); +} + +bool CPublic::ReadStreamLine( QTextStream& stream,QString& sLine,int& nRow ) +{ + while( !stream.atEnd() ) + { + sLine = stream.readLine(); + nRow++; + if( sLine!=QString() && !sLine.isEmpty() ) + return true; + } + return false; +} + +//******************************************************************** +// 读子字符串,子字符串间用‘,’隔开 +//******************************************************************** +bool CPublic::GetSubString(const QString& sString, + const int nIndex, QString& sSub) +{ + int nBegin = 0; + for(int i=0; i +bool CPublic::GetSubString(QString& sString, QString& sSub) +{ + int nPos = sString.indexOf(",",0); + if(nPos<0) + { + sSub = sString; + sString = ""; + } + else + { + sSub = sString.left(nPos); + sString = sString.remove(0,nPos+1); + } + return true; +} +//******************************************************************** +// 取位的值 +//******************************************************************** +byte CPublic::GetBitValue(const int nIndex, const WORD wLen, + const char* pData) +{ + int nBytePos = nIndex/8; + int nBitPos = nIndex%8; + + if(nBytePos < (int)wLen) + return (((WORD)(pData[nBytePos]) >> nBitPos) & 0x1); + return 0; +} + +//******************************************************************** +// 时间换算 +//******************************************************************** +void CPublic::GetAbsTime(const QDateTime& pBaseTime, int nTime, QDateTime& pstTime) +{ + QTime BaseTime = pBaseTime.time(); + QDate BaseDate = pBaseTime.date(); + nTime += BaseTime.msec(); + int hour; + int nSec = 0; + int mSec = 0; + int mini = 0; + if(nTime>0) + { + nSec = nTime/1000; + mSec = WORD(nTime%1000); + } + else + { + nSec = -((-nTime)/1000+1); + mSec = nTime-(nSec*1000); + } + + hour = BaseTime.hour(); + mini = BaseTime.minute(); + nSec += BaseTime.second(); + BaseTime.setHMS(hour,mini,nSec,mSec); + + pstTime.setDate(BaseDate); + pstTime.setTime(BaseTime); +} + + +//******************************************************************** +// 浮点数转换为字符串 +//******************************************************************** +QString CPublic::GetDoubleValString(double dVal) +{ + QString sVal; + if(fabs(dVal) >= 0.01) + sVal.sprintf("%.3f ", dVal); + else sVal.sprintf("%.5f ", dVal); + return sVal; +} + +//********************************************************** +//日期转换为两位字符串 +QString CPublic::GetDateString(int nData,int nBitNum) +{ + int nGe,nShi,nBai,nQian,nWan; + if(nBitNum>5||nBitNum<1) return QString(); + nWan = int(nData/10000); + nData = nData-nWan*10000; + nQian = int(nData/1000); + nData = nData-nQian*1000; + nBai = int(nData/100); + nData = nData-nBai*100; + nShi = int(nData/10); + nData = nData-nShi*10; + nGe = nData; + + QString sVal; + switch(nBitNum) + { + case 1: + sVal.sprintf("%d",nGe);break; + case 2: + sVal.sprintf("%d%d",nShi,nGe);break; + case 3: + sVal.sprintf("%d%d%d",nBai,nShi,nGe);break; + case 4: + sVal.sprintf("%d%d%d%d",nQian,nBai,nShi,nGe);break; + case 5: + sVal.sprintf("%d%d%d%d%d",nWan,nQian,nBai,nShi,nGe);break; + default: + return QString(); + } + return sVal; +} +////////////////////////////////////////////////////////////////////////// +//获取时间轴的缩放比率,必须为2的倍数 +////////////////////////////////////////////////////////////////////////// +double CPublic::GetTimeZoomRate( double fRaw ) +{ + double f = 1.0; + if( fRaw >= 1.0 ) + { + for( int i=0;i<5;i++) + { + if( fRaw <= f ) + return f; + f *= 2.0; + } + return f; + } + else + { + for( int i=0;i<5;i++) + { + if( fRaw <= f ) + return f; + f /= 2.0; + } + return f; + } +} + +////////////////////////////////////////////////////////////////////// +// 取整十 +////////////////////////////////////////////////////////////////////// +double CPublic::GetIntergerMax(double bMax) +{ + double dMax = fabs(bMax); + if(dMax <= 1.0) + return 1.0; + if( dMax<=10.0 ) + return 1.0+(int)dMax; + + return ((dMax/10.0) +1)*10.0; +} +////////////////////////////////////////////////////////////////////////// +//caculate +//******************************************************************** +// 计算有效值和相角(角度为度数) +// +//******************************************************************** +void CPublic::CalcuVirtualValue( double* pWaveData, + unsigned int nSampleNum, + unsigned int nSampleRate, + double* pRMSData, + double* pAngleData ) +{ + unsigned int i,j,ne; + double sumc,sums,sumq,rad,fi; + unsigned char gi; + ne=nSampleRate/50; + if(ne<1) return; + if(nSampleNum<1) return; + + j=ne; + rad = M_PI*2.0/ne; //基波角速度 + while(j=0) pAngleData[j]=(fi/ne)*360; + else pAngleData[j]=(fi/ne)*360+180; + } + if((pAngleData[j]>=360)&&(pAngleData[j]<720)) pAngleData[j]-=360;//基波相角 + if(pAngleData[j]<0) pAngleData[j]=fabs(pAngleData[j]);//基波相角 + j++; + } + for(j=0;j= lends-1 ) + { + int i=0; + for( i=lends;i= lends) + { + return true; + } + + if( pos+len < lends ) + { + int i = 0; + for(i=0;i= lends-1 ) + { + memcpy(buff+lends,dc,lendc*sizeof(char)); + } + else + { + pos = pos + 1; + memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(char)); + memcpy(buff+pos,dc,lendc*sizeof(char)); + } + return true; +}; + +bool CPublic::RemoveByteArray( QByteArray& datasrc, int pos,int len ) +{ + if(len<=0) + return true; + + int lends = datasrc.size(); + + if( pos <0 || pos >= lends-1) + { + return true; + } + + if( pos+len < lends ) + { + char *buff = datasrc.data(); + memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(char)); + datasrc.resize(lends-len); + } + else + { + datasrc.resize(pos); + } + return true; +}; + +struct wavedata_old wave_datao; +struct wavedata_old * wdp[100]; //故障选线所需线路波形数据指针 +struct wavedata_old * wpi; //双端测距本端波形数据块指针 +struct wavedata_old * wpj; //双端测距对端波形数据块指针 + +//******************************************************************** +// 计算有效值和相角(角度为度数) +//******************************************************************** +void CPublic::CalcuVirtualValue() +{ + double* pi = wave_datao.pi[0]; + + unsigned int i,j,ne; + double sumc,sums,sumq,rad,fi; + unsigned char gi; + ne=wave_datao.fsi/50; + j=ne; + rad = M_PI*2.0/ne; //基波角速度 + while(j=0) wave_datao.po[1][j]=(fi/ne)*360; + else wave_datao.po[1][j]=(fi/ne)*360+180; + } + if((wave_datao.po[1][j]>=360)&&(wave_datao.po[1][j]<720)) wave_datao.po[1][j]-=360;//基波相角 + if(wave_datao.po[1][j]<0) wave_datao.po[1][j]=fabs(wave_datao.po[1][j]);//基波相角 + j++; + } + for(j=0;j0) + { //求出各个过零点的频率值 + da[0]=fabs(wave_datao.po[1][j-wave_datao.pfo[j]-1]); + da[1]=fabs(wave_datao.po[1][j-wave_datao.pfo[j]]); + da[2]=fabs(wave_datao.po[1][j-1]); + da[3]=fabs(wave_datao.po[1][j]); + wave_datao.po[0][j]=wave_datao.fsi/(2*(da[1]/(da[0]+da[1])+da[2]/(da[2]+da[3])+wave_datao.pfo[j]-1)); + } + } + wave_datao.po[0][0]=50; //初始点设为50赫兹 + wave_datao.po[0][1]=50; //初始点设为50赫兹 + j=0; + while(wave_datao.pfo[j]==0) j++; + wave_datao.po[0][j]=50; //第一个过零点设为50赫兹 + for(j=wave_datao.numi-1;j>0;j--) + { + if(wave_datao.pfo[j]>0) + { + for(i=1;i0){ //求出各个过零点的频率值 + da[0]=fabs(wave_datao.po[1][j-wave_datao.pfo[j]-1]); + da[1]=fabs(wave_datao.po[1][j-wave_datao.pfo[j]]); + da[2]=fabs(wave_datao.po[1][j-1]); + da[3]=fabs(wave_datao.po[1][j]); + da[4]=wave_datao.pfo[j]-1; + if((da[0]+da[1])==0) da[4]+=0; + else da[4]+=da[1]/(da[0]+da[1]); + if((da[2]+da[3])==0) da[4]+=0; + else da[4]+=da[2]/(da[2]+da[3]); + if(da[4]==0) wave_datao.po[0][j]=0; + else wave_datao.po[0][j]=wave_datao.fsi/(2*da[4]); + } + } + wave_datao.po[0][0]=50; //初始点设为50赫兹 + wave_datao.po[0][1]=50; //初始点设为50赫兹 + j=0; + while(wave_datao.pfo[j]==0) j++; + wave_datao.po[0][j]=50; //第一个过零点设为50赫兹 + for(j=wave_datao.numi-1;j>0;j--){ + if(wave_datao.pfo[j]>0){ + for(i=1;i<(int)wave_datao.pfo[j];i++){ //插值求出中间点的频率 + wave_datao.po[0][j-i]=((wave_datao.pfo[j]-i)*wave_datao.po[0][j]+wave_datao.po[0][j-wave_datao.pfo[j]]*i)/wave_datao.pfo[j]; + } + } + } +} + + +//******************************************************************** +// 计算平均值 +//******************************************************************** +void CPublic::Average(int nAveTicks) +{ + double dSum; + int i=0,j=0; + for( i=0; i<(int)wave_datao.numi; i++) + { + dSum = 0.0; + for( j=0; j0) dSum /= j; + wave_datao.po[0][i] = dSum; + } +} + + +//******************************************************************** +// 计算最大最小值 +//******************************************************************** +void CPublic::CalcuMinMax() +{ + wave_datao.dMinVal = 1e100; + wave_datao.dMaxVal = -1e100; + wave_datao.nMinTick = 0; + wave_datao.nMaxTick = 0; + for(unsigned int j=0; j wave_datao.dMaxVal) + { + wave_datao.dMaxVal = wave_datao.pi[0][j]; + wave_datao.nMaxTick = j; + } + } +} + + +//******************************************************************** +// 直接移相法 计算序分量 +//******************************************************************** +void CPublic::Subsequence() +{ + unsigned int i,j,k,ne,ne31,ne32; + double sumc,rad; +// double sums; + ne = wave_datao.fsi/50; + rad = M_PI*2.0/ne; //角速度 + for(k=0;k<3;k++) // 求出非周期分量 + { + j=ne; + while(j40) hi=20; //最高次谐波次数 + else hi = ne/2; //满足采样定理 + j=ne; + for(num=1;num<=hi;num++) //整数次谐波分量 + { + rad=M_PI*2.0*num/ne; //角速度 + while(j>2); + m=(ne<<1)-(ne>>2); + rad=M_PI*2.0/ne; //基波角速度 + while(j>2)) sums+=wave_datao.pi[0][j+i-k]*wave_datao.pi[1][j+i-ne]; + else sums+=wave_datao.pi[0][j+i-m]*wave_datao.pi[1][j+i-ne]; + } + if(wave_datao.type==1){ //LFP老保护 + ma[0]=sumc*cos(wave_datao.angle*M_PI/180.0)-sums*sin(wave_datao.angle*M_PI/180.0); + mb[0]=sums*cos(wave_datao.angle*M_PI/180.0)+sumc*sin(wave_datao.angle*M_PI/180.0); + sumc=ma[0]; + sums=mb[0]; + } + wave_datao.po[0][j]=sumc/ne; + wave_datao.po[1][j]=sums/ne; + wave_datao.po[2][j++]=sumc/(sqrt(sumc*sumc+sums*sums)); + } + } + for(j=0;j>2); + m=(ne<<1)-(ne>>2); + rad=M_PI*2.0/ne; //基波角速度 + while(j>2)) sums+=wave_datao.pi[0][j+i-k]*wave_datao.pi[3][j+i-ne]+wave_datao.pi[1][j+i-k]*wave_datao.pi[4][j+i-ne]+wave_datao.pi[2][j+i-k]*wave_datao.pi[5][j+i-ne]; + else sums+=wave_datao.pi[0][j+i-m]*wave_datao.pi[3][j+i-ne]+wave_datao.pi[1][j+i-m]*wave_datao.pi[4][j+i-ne]+wave_datao.pi[2][j+i-m]*wave_datao.pi[5][j+i-ne]; + } + if(wave_datao.type==1){ //LFP老保护 + ma[0]=sumc*cos(wave_datao.angle*M_PI/180.0)-sums*sin(wave_datao.angle*M_PI/180.0); + mb[0]=sums*cos(wave_datao.angle*M_PI/180.0)+sumc*sin(wave_datao.angle*M_PI/180.0); + sumc=ma[0]; + sums=mb[0]; + } + wave_datao.po[0][j]=sumc/ne; //有功 + wave_datao.po[1][j]=sums/ne; //无功 + wave_datao.po[2][j++]=sumc/(sqrt(sumc*sumc+sums*sums)); //功率因数 + } + } + for(j=0;jwave_datao.dzlqd) dnum[0]++; + else if(dnum[0]>0) dnum[0]--; + if(fabs(wave_datao.pi[1][j]-wave_datao.pi[1][j-ne])>wave_datao.dzlqd) dnum[1]++; + else if(dnum[1]>0) dnum[1]--; + if(fabs(wave_datao.pi[2][j]-wave_datao.pi[2][j-ne])>wave_datao.dzlqd) dnum[2]++; + else if(dnum[2]>0) dnum[2]--; + if(dnum[0]>3||dnum[1]>3||dnum[2]>3) + { //任意一相连续三点满足突变量起动要求 + k=j; + break; + } + j++; + } + if((k>=ne+3)&&(kmax[0])&&(wave_datao.po[4][j]>max[1])&&(wave_datao.po[5][j]>max[2])) dnum[3]++; + else if(dnum[3]>0) dnum[3]--; + if(dnum[3]>3) break; + } + if(dnum[3]>3) + { //接地故障 + for(j=k-3;j0) dnum[0]--; + if((25*max[2]0) dnum[1]--; + if((25*max[0]0) dnum[2]--; + if(dnum[0]>3) return 1; //a相接地短路 + if(dnum[1]>3) return 2; //b相接地短路 + if(dnum[2]>3) return 3; //c相接地短路 + } + for(i=0;i<3;i++) dnum[i]=0; + for(j=k-3;j0) dnum[0]--; + if((max[0]0) dnum[1]--; + if((max[1]0) dnum[2]--; + if(dnum[0]>3) return 7; //ab相间接地短路 + if(dnum[1]>3) return 8; //bc相间接地短路 + if(dnum[2]>3) return 9; //ca相间接地短路 + } + } + else + { //不接地故障 + max[3]=wave_datao.sill[3]*wave_datao.dled; //三相短路电流门槛 + for(j=k-3;jmax[3])&&(max[1]>max[3])&&(max[2])>max[3]) dnum[0]++; + else if(dnum[0]>0) dnum[0]--; + if(dnum[0]>3) return 10; //三相短路 + } + for(i=0;i<3;i++) dnum[i]=0; + for(j=k-3;j0) dnum[0]--; + if((max[0]0) dnum[1]--; + if((max[1]0) dnum[2]--; + if(dnum[0]>3) return 4; //ab相间短路 + if(dnum[1]>3) return 5; //bc相间短路 + if(dnum[2]>3) return 6; //ca相间短路 + } + } + } + return 0; +} + + +//******************************************************************** +// 单端测距(阻抗算法) +// +// 输入: +// mode 故障类型 +// 1: A相接地短路 +// 2: B相接地短路 +// 3: C相接地短路 +// 4: AB相间短路 +// 5: BC相间短路 +// 6: CA相间短路 +// 7: AB相接地短路 +// 8: BC相接地短路 +// 9: CA相接地短路 +// 10: ABC三相短路 +// wave_datao.numi 采样点数 +// wave_datao.fsi 采样率 +// wave_datao.pi[0] A相电流瞬时值 +// wave_datao.pi[1] B相电流瞬时值 +// wave_datao.pi[2] C相电流瞬时值 +// wave_datao.pi[3] A相电压瞬时值 +// wave_datao.pi[4] B相电压瞬时值 +// wave_datao.pi[5] C相电压瞬时值 +// wave_datao.pi[6] 零序电流 +// wave_datao.pi[7] 零序电压 +// wave_datao.zerocomp 零序补偿系数 +// +// wave_datao.dzlqd 电流启动定值 +// wave_datao.type =1: LFP老保护, +// wave_datao.angle 当为LFP老保护时,电流旋转角 一般78度 +// +// wave_datao.xps 正序电抗 +// wave_datao.rps 正序电阻 +// wave_datao.xps0 零序电抗 +// wave_datao.rps0 零序电阻 +// wave_datao.length 线路长度 +// +// 输出: +// double* dImp 阻抗 +// double* dLen 距离 +// +// 新算法 +// 阻抗法单端测距(电气量算法) +// 本函数只需输入故障类型代码,返回值为测距长度其他参数同 +// 本函数和以前的测距函数直接由输入的正序阻抗和零序阻抗计算 +// 零序补偿系数,不受输入的零序补偿系数影响 +// +//******************************************************************** +void CPublic::SingleFaultLoc(unsigned int mode, double* dImp, double* dLen) +{ + /* + (*dImp) = 0.0; + (*dLen) = 0.0; + + unsigned int i,j,k,ne,dnum[4]; + double e,ma[6],mb[6],com,sum,rad,zmp,zmp0; + ne=wave_datao.fsi/50; //每周采样数 + rad=M_PI*2.0/ne; //角速度 + e=wave_datao.xps/wave_datao.rps; //正序电抗/电阻之比 + zmp=sqrt(wave_datao.xps*wave_datao.xps+wave_datao.rps*wave_datao.rps); + zmp0=sqrt(wave_datao.xps0*wave_datao.xps0+wave_datao.rps0*wave_datao.rps0); +// com=(wave_datao.xps0-wave_datao.xps)/(3*wave_datao.xps); //零序补偿系数 + com=(zmp0-zmp)/(3*zmp); //零序补偿系数 + j=ne; + k=0; + for(i=0;i<3;i++) dnum[i]=0; + while(jwave_datao.dzlqd) dnum[0]++; + else if(dnum[0]>0) dnum[0]--; + if(fabs(wave_datao.pi[1][j]-wave_datao.pi[1][j-ne])>wave_datao.dzlqd) dnum[1]++; + else if(dnum[1]>0) dnum[1]--; + if(fabs(wave_datao.pi[2][j]-wave_datao.pi[2][j-ne])>wave_datao.dzlqd) dnum[2]++; + else if(dnum[2]>0) dnum[2]--; + if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 + k=j; + break; + } + j++; + } + for(i=0;i<6;i++){ + ma[i]=0; + mb[i]=0; + } + if((k>=ne+3)&&(k>1)+ne; //起动后一个半周期 + switch(mode){ + case 1: //a相接地短路 + for(i=0;iwave_datao.dzlqd) dnum[0]++; + else if(dnum[0]>0) dnum[0]--; + if(fabs(wave_datao.pi[1][j]-wave_datao.pi[1][j-ne])>wave_datao.dzlqd) dnum[1]++; + else if(dnum[1]>0) dnum[1]--; + if(fabs(wave_datao.pi[2][j]-wave_datao.pi[2][j-ne])>wave_datao.dzlqd) dnum[2]++; + else if(dnum[2]>0) dnum[2]--; + if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 + k=j; + break; + } + j++; + } + for(i=0;i<6;i++){ + ma[i]=0; + mb[i]=0; + } + if((k>=ne+3)&&(k>1)+2*ne; //起动后一个半周期 + switch(mode){ + case 1: //a相接地短路 + for(i=0;inumi 采样点数 +// wpi->fsi 采样率 +// wpi->pi[0] A相电流瞬时值 +// wpi->pi[1] B相电流瞬时值 +// wpi->pi[2] C相电流瞬时值 +// wpi->pi[3] A相电压瞬时值 +// wpi->pi[4] B相电压瞬时值 +// wpi->pi[5] C相电压瞬时值 +// wpi->pi[6] 零序电流 +// wpi->pi[7] 零序电压 +// +// wpi->dzlqd 电流启动定值 +// wpi->type =1: LFP老保护, +// wpi->angle 当为LFP老保护时,电流旋转角 一般78度 +// +// wpi->xps 正序电抗 +// wpi->rps 正序电阻 +// wpi->xps0 零序电抗 +// wpi->rps0 零序电阻 +// wpi->length 线路长度 +// wpi->zerocomp 零序补偿系数 +// +// 对侧数据块: +// wpj->numi 采样点数 +// wpj->fsi 采样率 +// wpj->pi[0] A相电流瞬时值 +// wpj->pi[1] B相电流瞬时值 +// wpj->pi[2] C相电流瞬时值 +// wpj->pi[3] A相电压瞬时值 +// wpj->pi[4] B相电压瞬时值 +// wpj->pi[5] C相电压瞬时值 +// wpj->pi[6] 零序电流 +// wpj->pi[7] 零序电压 +// +// wpj->dzlqd 电流启动定值 +// wpj->type =1: LFP老保护, +// wpj->angle 当为LFP老保护时,电流旋转角 一般78度 +// +// 输出: +// double* dImp 阻抗 +// double* dLen 距离 +// +//******************************************************************** +void CPublic::DoubleFaultLoc(unsigned int mode, double* dImp, double* dLen) +{ + //双端测距(阻抗算法) + + (*dImp) = 0.0; + (*dLen) = 0.0; + + unsigned int i,j,ki,kj,nei,nej,dnum[4]; + double ma[8],mb[8],na[8],nb[8],com,sum,radi,radj,sumi,sumj,zmp; + nei=wpi->fsi/50; //本端每周采样数 + radi=M_PI*2.0/nei; //本端角速度 + nej=wpj->fsi/50; //对端每周采样数 + radj=M_PI*2.0/nej; //对端角速度 + zmp=sqrt(wpi->xps*wpi->xps+wpi->rps*wpi->rps); //全线路阻抗 + com=wpi->zerocomp; //零序补偿系数 + j=nei; + ki=0; + for(i=0;i<3;i++) dnum[i]=0; + while(jnumi){ //起动判断 + if(fabs(wpi->pi[0][j]-wpi->pi[0][j-nei])>wpi->dzlqd) dnum[0]++; + else if(dnum[0]>0) dnum[0]--; + if(fabs(wpi->pi[1][j]-wpi->pi[1][j-nei])>wpi->dzlqd) dnum[1]++; + else if(dnum[1]>0) dnum[1]--; + if(fabs(wpi->pi[2][j]-wpi->pi[2][j-nei])>wpi->dzlqd) dnum[2]++; + else if(dnum[2]>0) dnum[2]--; + if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 + ki=j; + break; + } + j++; + } + j=nej; + kj=0; + for(i=0;i<3;i++) dnum[i]=0; + while(jnumi){ //起动判断 + if(fabs(wpj->pi[0][j]-wpj->pi[0][j-nej])>wpj->dzlqd) dnum[0]++; + else if(dnum[0]>0) dnum[0]--; + if(fabs(wpj->pi[1][j]-wpj->pi[1][j-nej])>wpj->dzlqd) dnum[1]++; + else if(dnum[1]>0) dnum[1]--; + if(fabs(wpj->pi[2][j]-wpj->pi[2][j-nej])>wpj->dzlqd) dnum[2]++; + else if(dnum[2]>0) dnum[2]--; + if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 + kj=j; + break; + } + j++; + } + for(i=0;i<8;i++){ + ma[i]=0; + mb[i]=0; + na[i]=0; + nb[i]=0; + } + if((ki>=nei+3)&&(kinumi-2*nei)&&(kj>=nej+3)&&(kjnumi-2*nej)){ //起动元件动作 + j=ki-nei; //本端起动前一个周期 + for(i=0;ipi[0][j+i-nei]*cos(radi*i); //a相电流实部 + mb[0]-=wpi->pi[0][j+i-nei]*sin(radi*i); //a相电流虚部 + ma[1]+=wpi->pi[1][j+i-nei]*cos(radi*i); //b相电流实部 + mb[1]-=wpi->pi[1][j+i-nei]*sin(radi*i); //b相电流虚部 + ma[2]+=wpi->pi[2][j+i-nei]*cos(radi*i); //c相电流实部 + mb[2]-=wpi->pi[2][j+i-nei]*sin(radi*i); //c相电流虚部 + ma[3]+=wpi->pi[3][j+i-nei]*cos(radi*i); //a相电压实部 + mb[3]-=wpi->pi[3][j+i-nei]*sin(radi*i); //a相电压虚部 + ma[4]+=wpi->pi[4][j+i-nei]*cos(radi*i); //b相电压实部 + mb[4]-=wpi->pi[4][j+i-nei]*sin(radi*i); //b相电压虚部 + ma[5]+=wpi->pi[5][j+i-nei]*cos(radi*i); //c相电压实部 + mb[5]-=wpi->pi[5][j+i-nei]*sin(radi*i); //c相电压虚部 + } + j=kj-nej; //对端起动前一个周期 + for(i=0;ipi[0][j+i-nej]*cos(radj*i); //a相电流实部 + nb[0]-=wpj->pi[0][j+i-nej]*sin(radj*i); //a相电流虚部 + na[1]+=wpj->pi[1][j+i-nej]*cos(radj*i); //b相电流实部 + nb[1]-=wpj->pi[1][j+i-nej]*sin(radj*i); //b相电流虚部 + na[2]+=wpj->pi[2][j+i-nej]*cos(radj*i); //c相电流实部 + nb[2]-=wpj->pi[2][j+i-nej]*sin(radj*i); //c相电流虚部 + na[3]+=wpj->pi[3][j+i-nej]*cos(radj*i); //a相电压实部 + nb[3]-=wpj->pi[3][j+i-nej]*sin(radj*i); //a相电压虚部 + na[4]+=wpj->pi[4][j+i-nej]*cos(radj*i); //b相电压实部 + nb[4]-=wpj->pi[4][j+i-nej]*sin(radj*i); //b相电压虚部 + na[5]+=wpj->pi[5][j+i-nej]*cos(radj*i); //c相电压实部 + nb[5]-=wpj->pi[5][j+i-nej]*sin(radj*i); //c相电压虚部 + } + ma[6]=(ma[0]-0.5*ma[1]-0.8660254*mb[1]-0.5*ma[2]+0.8660254*mb[2])/nei; //本端正序电流 + mb[6]=(mb[0]-0.5*mb[1]+0.8660254*ma[1]-0.5*mb[2]-0.8660254*ma[2])/nei; + ma[1]=(ma[3]-0.5*ma[4]-0.8660254*mb[4]-0.5*ma[5]+0.8660254*mb[5])/nei; //本端正序电压 + mb[1]=(mb[3]-0.5*mb[4]+0.8660254*ma[4]-0.5*mb[5]-0.8660254*ma[5])/nei; + if(wpi->type==1){ //LFP老保护电流移相 + ma[0]=ma[6]*cos(0.0174533*wpi->angle)+mb[6]*sin(0.0174533*wpi->angle); + mb[0]=mb[6]*cos(0.0174533*wpi->angle)-ma[6]*sin(0.0174533*wpi->angle); + ma[6]=ma[0]; + mb[6]=mb[0]; + } + ma[2]=ma[1]-ma[6]*wpi->rps+mb[6]*wpi->xps; //由本侧计算出的对端电压 + mb[2]=mb[1]-ma[6]*wpi->xps-mb[6]*wpi->rps; + + na[6]=(na[0]-0.5*na[1]-0.8660254*nb[1]-0.5*na[2]+0.8660254*nb[2])/nej; //对端正序电流 + nb[6]=(nb[0]-0.5*nb[1]+0.8660254*na[1]-0.5*nb[2]-0.8660254*na[2])/nej; + na[1]=(na[3]-0.5*na[4]-0.8660254*nb[4]-0.5*na[5]+0.8660254*nb[5])/nej; //对端正序电压 + nb[1]=(nb[3]-0.5*nb[4]+0.8660254*na[4]-0.5*nb[5]-0.8660254*na[5])/nej; + if(wpj->type==1){ //LFP老保护电流移相 + na[0]=na[6]*cos(0.0174533*wpj->angle)+nb[6]*sin(0.0174533*wpj->angle); + nb[0]=nb[6]*cos(0.0174533*wpj->angle)-na[6]*sin(0.0174533*wpj->angle); + na[6]=na[0]; + nb[6]=nb[0]; + } + na[2]=na[1]-na[6]*wpi->rps+nb[6]*wpi->xps; //由对端计算出的本侧电压 + nb[2]=nb[1]-na[6]*wpi->xps-nb[6]*wpi->rps; + sumi=na[1]*na[1]+nb[1]*nb[1]; + sumj=na[2]*na[2]+nb[2]*nb[2]; + ma[3]=(ma[2]*na[1]+mb[2]*nb[1])/sumi; + mb[3]=(mb[2]*na[1]-ma[2]*nb[1])/sumi; + na[3]=(ma[1]*na[2]+mb[1]*nb[2])/sumj; + nb[3]=(mb[1]*na[2]-ma[1]*nb[2])/sumj; + sumi=(ma[3]+na[3])/2; //旋转因子实部 + sumj=(mb[3]+nb[3])/2; //旋转因子虚部 + for(i=0;i<6;i++){ + ma[i]=0; + mb[i]=0; + na[i]=0; + nb[i]=0; + } + switch(mode){ + case 1: //a相接地短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[0][j+i-nei]+com*wpi->pi[6][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[0][j+i-nei]+com*wpi->pi[6][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=wpi->pi[3][j+i-nei]*cos(radi*i); //电压实部 + mb[1]-=wpi->pi[3][j+i-nei]*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[0][j+i-nej]+com*wpj->pi[6][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[0][j+i-nej]+com*wpj->pi[6][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=wpj->pi[3][j+i-nej]*cos(radj*i); //电压实部 + nb[1]-=wpj->pi[3][j+i-nej]*sin(radj*i); //电压虚部 + } + break; + case 2: //b相接地短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[1][j+i-nei]+com*wpi->pi[6][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[1][j+i-nei]+com*wpi->pi[6][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=wpi->pi[4][j+i-nei]*cos(radi*i); //电压实部 + mb[1]-=wpi->pi[4][j+i-nei]*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[1][j+i-nej]+com*wpj->pi[6][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[1][j+i-nej]+com*wpj->pi[6][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=wpj->pi[4][j+i-nej]*cos(radj*i); //电压实部 + nb[1]-=wpj->pi[4][j+i-nej]*sin(radj*i); //电压虚部 + } + break; + case 3: //c相接地短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[2][j+i-nei]+com*wpi->pi[6][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[2][j+i-nei]+com*wpi->pi[6][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=wpi->pi[5][j+i-nei]*cos(radi*i); //电压实部 + mb[1]-=wpi->pi[5][j+i-nei]*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[2][j+i-nej]+com*wpj->pi[6][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[2][j+i-nej]+com*wpj->pi[6][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=wpj->pi[5][j+i-nej]*cos(radj*i); //电压实部 + nb[1]-=wpj->pi[5][j+i-nej]*sin(radj*i); //电压虚部 + } + break; + case 4: //ab相间短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[0][j+i-nei]-wpi->pi[1][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[0][j+i-nei]-wpi->pi[1][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*cos(radi*i); //电压实部 + mb[1]-=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[0][j+i-nej]-wpj->pi[1][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[0][j+i-nej]-wpj->pi[1][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*cos(radj*i); //电压实部 + nb[1]-=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*sin(radj*i); //电压虚部 + } + break; + case 5: //bc相间短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[1][j+i-nei]-wpi->pi[2][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[1][j+i-nei]-wpi->pi[2][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=(wpi->pi[4][j+i-nei]-wpi->pi[5][j+i-nei])*cos(radi*i); //电压实部 + mb[1]-=(wpi->pi[4][j+i-nei]-wpi->pi[5][j+i-nei])*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[1][j+i-nej]-wpj->pi[2][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[1][j+i-nej]-wpj->pi[2][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=(wpj->pi[4][j+i-nej]-wpj->pi[5][j+i-nej])*cos(radj*i); //电压实部 + nb[1]-=(wpj->pi[4][j+i-nej]-wpj->pi[5][j+i-nej])*sin(radj*i); //电压虚部 + } + break; + case 6: //ca相间短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[2][j+i-nei]-wpi->pi[0][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[2][j+i-nei]-wpi->pi[0][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=(wpi->pi[5][j+i-nei]-wpi->pi[3][j+i-nei])*cos(radi*i); //电压实部 + mb[1]-=(wpi->pi[5][j+i-nei]-wpi->pi[3][j+i-nei])*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[2][j+i-nej]-wpj->pi[0][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[2][j+i-nej]-wpj->pi[0][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=(wpj->pi[5][j+i-nej]-wpj->pi[3][j+i-nej])*cos(radj*i); //电压实部 + nb[1]-=(wpj->pi[5][j+i-nej]-wpj->pi[3][j+i-nej])*sin(radj*i); //电压虚部 + } + break; + case 7: //ab相间接地短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[0][j+i-nei]-wpi->pi[1][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[0][j+i-nei]-wpi->pi[1][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*cos(radi*i); //电压实部 + mb[1]-=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[0][j+i-nej]-wpj->pi[1][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[0][j+i-nej]-wpj->pi[1][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*cos(radj*i); //电压实部 + nb[1]-=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*sin(radj*i); //电压虚部 + } + break; + case 8: //bc相间接地短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[1][j+i-nei]-wpi->pi[2][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[1][j+i-nei]-wpi->pi[2][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=(wpi->pi[4][j+i-nei]-wpi->pi[5][j+i-nei])*cos(radi*i); //电压实部 + mb[1]-=(wpi->pi[4][j+i-nei]-wpi->pi[5][j+i-nei])*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[1][j+i-nej]-wpj->pi[2][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[1][j+i-nej]-wpj->pi[2][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=(wpj->pi[4][j+i-nej]-wpj->pi[5][j+i-nej])*cos(radj*i); //电压实部 + nb[1]-=(wpj->pi[4][j+i-nej]-wpj->pi[5][j+i-nej])*sin(radj*i); //电压虚部 + } + case 9: //ca相间接地短路 + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[2][j+i-nei]-wpi->pi[0][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[2][j+i-nei]-wpi->pi[0][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=(wpi->pi[5][j+i-nei]-wpi->pi[3][j+i-nei])*cos(radi*i); //电压实部 + mb[1]-=(wpi->pi[5][j+i-nei]-wpi->pi[3][j+i-nei])*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[2][j+i-nej]-wpj->pi[0][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[2][j+i-nej]-wpj->pi[0][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=(wpj->pi[5][j+i-nej]-wpj->pi[3][j+i-nej])*cos(radj*i); //电压实部 + nb[1]-=(wpj->pi[5][j+i-nej]-wpj->pi[3][j+i-nej])*sin(radj*i); //电压虚部 + } + break; + case 10: //abc三相短路(任选ab相间电气量计算) + j=ki+2*nei; //本端起动后两个周期 + for(i=0;ipi[0][j+i-nei]-wpi->pi[1][j+i-nei])*cos(radi*i); //电流实部 + mb[0]-=(wpi->pi[0][j+i-nei]-wpi->pi[1][j+i-nei])*sin(radi*i); //电流虚部 + ma[1]+=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*cos(radi*i); //电压实部 + mb[1]-=(wpi->pi[3][j+i-nei]-wpi->pi[4][j+i-nei])*sin(radi*i); //电压虚部 + } + j=kj+2*nej; //对端起动后两个周期 + for(i=0;ipi[0][j+i-nej]-wpj->pi[1][j+i-nej])*cos(radj*i); //电流实部 + nb[0]-=(wpj->pi[0][j+i-nej]-wpj->pi[1][j+i-nej])*sin(radj*i); //电流虚部 + na[1]+=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*cos(radj*i); //电压实部 + nb[1]-=(wpj->pi[3][j+i-nej]-wpj->pi[4][j+i-nej])*sin(radj*i); //电压虚部 + } + break; + } + ma[0]=2*ma[0]/nei; //本端电流 + mb[0]=2*mb[0]/nei; + if(wpi->type==1){ //LFP老保护电流移相 + ma[6]=ma[0]*cos(0.0174533*wpi->angle)+mb[0]*sin(0.0174533*wpi->angle); + mb[6]=mb[0]*cos(0.0174533*wpi->angle)-ma[0]*sin(0.0174533*wpi->angle); + ma[0]=ma[6]; + mb[0]=mb[6]; + } + ma[1]=2*ma[1]/nei; //本端电压 + mb[1]=2*mb[1]/nei; + na[0]=2*na[0]/nej; //对端电流 + nb[0]=2*nb[0]/nej; + if(wpj->type==1){ //LFP老保护电流移相 + na[6]=na[0]*cos(0.0174533*wpj->angle)+nb[0]*sin(0.0174533*wpj->angle); + nb[6]=nb[0]*cos(0.0174533*wpj->angle)-na[0]*sin(0.0174533*wpj->angle); + na[0]=na[6]; + nb[0]=nb[6]; + } + na[1]=2*na[1]/nej; //对端电压 + nb[1]=2*nb[1]/nej; + na[2]=na[0]*sumi-nb[0]*sumj; //同步后的对端电流 + nb[2]=nb[0]*sumi+na[0]*sumj; + na[3]=na[1]*sumi-nb[1]*sumj; //同步后的对端电压 + nb[3]=nb[1]*sumi+na[1]*sumj; + ma[2]=ma[0]+na[2]; + mb[2]=mb[0]+nb[2]; + ma[3]=ma[1]-na[3]+na[2]*wpi->rps-nb[2]*wpi->xps; + mb[3]=mb[1]-nb[3]+nb[2]*wpi->rps+na[2]*wpi->xps; + sum=ma[2]*ma[2]+mb[2]*mb[2]; + ma[4]=(ma[3]*ma[2]+mb[3]*mb[2])/sum; //故障点至母线处电阻R + mb[4]=(mb[3]*ma[2]-ma[3]*mb[2])/sum; //故障点至母线处电抗X + (*dImp)=sqrt(ma[4]*ma[4]+mb[4]*mb[4]); //故障点至母线处阻抗值 + (*dLen)=wpi->length*(*dImp)/zmp; //故障点至母线处距离 + } +} + +//******************************************************************** +// 故障选线(复合功率因数突变量算法) +// +// 输入: +// +// 输出: +// true: 有选线结果 +// false: 无选线结果 +// +// line数组:线路号的排序 +// +//******************************************************************** +bool CPublic::CalcuFaultLine(int num, unsigned int* line) +{ + if(num<=0 || num>100) return false; + + int i,j,dir,k,m,n,max,*pd,*pr; + double *pp; + pd=new int[num]; + pr=new int[num]; + pp=new double[num]; + if((pd==NULL)||(pr==NULL)||(pp==NULL)){ + if(pd!=NULL) delete [] pd; + if(pr!=NULL) delete [] pr; + if(pp!=NULL) delete [] pp; + return false; + } + k=0; + m=0; + n=0; + for(i=0;ifsi/50; //每周采样数 + rad=M_PI*2.0/ne; //角速度 + j=ne; + k=0; + for(i=0;i<3;i++) dnum[i]=0; + while(jnumi){ //起动判断 + if(fabs(wp->pi[0][j]-wp->pi[0][j-ne])>wp->dzlqd) dnum[0]++; + else if(dnum[0]>0) dnum[0]--; + if(fabs(wp->pi[1][j]-wp->pi[1][j-ne])>wp->dzlqd) dnum[1]++; + else if(dnum[1]>0) dnum[1]--; + if(fabs(wp->pi[2][j]-wp->pi[2][j-ne])>wp->dzlqd) dnum[2]++; + else if(dnum[2]>0) dnum[2]--; + if(dnum[0]>3||dnum[1]>3||dnum[2]>3){ //任意一相连续三点满足突变量起动要求 + k=j; + break; + } + j++; + } + for(i=0;i<8;i++){ + ma[i]=0; + mb[i]=0; + } + if((k>=ne+3)&&(knumi-2*ne)){ //起动元件动作(测距计算采用起动点前后两个周波数据) + j=k+(ne>>1)+ne; //起动后一个半周期 + for(i=0;ipi[0][j+i-ne]-wp->pi[0][j+i-3*ne])*cos(rad*i); //a相故障电流实部 + mb[0]-=(wp->pi[0][j+i-ne]-wp->pi[0][j+i-3*ne])*sin(rad*i); //a相故障电流虚部 + ma[1]+=(wp->pi[1][j+i-ne]-wp->pi[1][j+i-3*ne])*cos(rad*i); //b相故障电流实部 + mb[1]-=(wp->pi[1][j+i-ne]-wp->pi[1][j+i-3*ne])*sin(rad*i); //b相故障电流虚部 + ma[2]+=(wp->pi[2][j+i-ne]-wp->pi[2][j+i-3*ne])*cos(rad*i); //c相故障电流实部 + mb[2]-=(wp->pi[2][j+i-ne]-wp->pi[2][j+i-3*ne])*sin(rad*i); //c相故障电流虚部 + ma[3]+=(wp->pi[3][j+i-ne]-wp->pi[3][j+i-3*ne])*cos(rad*i); //a相故障电压实部 + mb[3]-=(wp->pi[3][j+i-ne]-wp->pi[3][j+i-3*ne])*sin(rad*i); //a相故障电压虚部 + ma[4]+=(wp->pi[4][j+i-ne]-wp->pi[4][j+i-3*ne])*cos(rad*i); //b相故障电压实部 + mb[4]-=(wp->pi[4][j+i-ne]-wp->pi[4][j+i-3*ne])*sin(rad*i); //b相故障电压虚部 + ma[5]+=(wp->pi[5][j+i-ne]-wp->pi[5][j+i-3*ne])*cos(rad*i); //c相故障电压实部 + mb[5]-=(wp->pi[5][j+i-ne]-wp->pi[5][j+i-3*ne])*sin(rad*i); //c相故障电压虚部 + } + ma[6]=(ma[0]-0.5*ma[1]-0.8660254*mb[1]-0.5*ma[2]+0.8660254*mb[2])/ne; //正序故障电流 + mb[6]=(mb[0]-0.5*mb[1]+0.8660254*ma[1]-0.5*mb[2]-0.8660254*ma[2])/ne; + ma[1]=(ma[3]-0.5*ma[4]-0.8660254*mb[4]-0.5*ma[5]+0.8660254*mb[5])/ne; //故障正序电压 + mb[1]=(mb[3]-0.5*mb[4]+0.8660254*ma[4]-0.5*mb[5]-0.8660254*ma[5])/ne; + if(wp->type==1){ //LFP老保护电流移相 + ma[0]=ma[6]*cos(0.0174533*wp->angle)+mb[6]*sin(0.0174533*wp->angle); + mb[0]=mb[6]*cos(0.0174533*wp->angle)-ma[6]*sin(0.0174533*wp->angle); + ma[6]=ma[0]; + mb[6]=mb[0]; + } + ma[7]=ma[1]*mb[6]-mb[1]*ma[6]; + mb[7]=ma[1]*ma[6]+mb[1]*mb[6]; + amp=sqrt(ma[6]*ma[6]+mb[6]*mb[6]); //故障电流幅值 + if((ma[7]>0)&&(fabs(mb[7]) -#include -#include -#include -#include -#include - - -// 分析算法规模 -// -#define MAX_IN_WAVES 16 -#define MAX_OUT_WAVES 32 -#define MAX_POINTS 10000 -#define MAX_SILLS 8 - - -// 分析算法数据区 -// -struct wavedata_old -{ - int type; //保护类型 1--是LFP系列有前置移相电抗器的老保护 - double angle; //前置移相电抗器移相角度(度数) - unsigned int numi; //输入采样点个数 - unsigned int fsi; //输入采样率 - double pi[MAX_IN_WAVES][MAX_POINTS]; - //输入数据缓存 - unsigned int pfi; //输入数据标识 - unsigned int chi; //输入采样数据的通道数 - unsigned int numo; //输出采样点个数 - unsigned int fso; //输出采样率 - double po[MAX_OUT_WAVES][MAX_POINTS]; - //输出数据缓存 - unsigned int pfo[MAX_POINTS]; - //输出数据标识 - unsigned int cho; //输出数据的通道数 - unsigned int max; //要计算的最大谐波次数 - unsigned int min; //要计算的最小谐波次数 - unsigned int faultmode; //短路故障形式 - double dMaxVal; //最大有效值 - double dMinVal; //最小有效值 - int nMaxTick; //最大有效值位置 - int nMinTick; //最小有效值位置 - double zerocomp; //零序补偿系数 - double rps; //全线路正序电阻 - double xps; //全线路正序电抗 - double rps0; //全线路零序电阻 - double xps0; //全线路零序电抗 - double length; //线路长度 - double sill[MAX_SILLS]; //各种门槛值系数 - double dzlqd; //突变量电流起动定值 - double dled; //电流额定值 - double dyed; //电压额定值 -}; - -class CPublic -{ -public: - static void SetWidgetBackColor( QWidget* wg,const QColor& bc ); - static void SetWidgetForeColor( QWidget* wg,const QColor& fc ); - static QColor GetWidgetBackColor( QWidget* wg ); - static QColor GetWidgetForeColor( QWidget* wg ); - - static bool ReadStreamLine( QTextStream& stream,QString& sLine,int& nRow ); - static bool GetSubString(const QString& sString, const int nIndex, QString& sSub); - static bool GetSubString(QString& sString, QString& sSub); - static byte GetBitValue(const int nIndex, const WORD wLen, const char* pData); - static void GetAbsTime(const QDateTime& pBaseTime, int nTime, QDateTime& pstTime); - static QString GetDoubleValString(double dVal); - static QString GetDateString(int nData,int nBitNum); - static double GetTimeZoomRate( double fRaw ); - static double GetIntergerMax(double bMax); - //在pos位置后插入数组 - static bool InsertBitArray( QBitArray& datasrc,const QBitArray& datainsert,int pos ); - //从pos位置开始删除len个点 - static bool RemoveBitArray( QBitArray& datasrc, int pos,int len ); - //在pos位置后插入数组 - static bool InsertByteArray( QByteArray& datasrc,QByteArray& datainsert,int pos ); - //从pos位置开始删除len个点 - static bool RemoveByteArray( QByteArray& datasrc, int pos,int len ); - - /****************计算算法*****************************************/ - static void CalcuVirtualValue( double* pWaveData, - unsigned int nSampleNum, - unsigned int nSampleRate, - double* pRMSData, - double* pAngleData ); - - static void CalcuVirtualValue(); // 计算有效值及角度 - static void Frequence(); // 计算频率 - static void Average(int nAveTicks); // 计算平均值 - static void CalcuMinMax(); // 计算最大最小值 - - // 计算序分量 - static void Subsequence(); // 直接移相法 - static void FSubsequence(); // 富氏积分旋转向量法 - - // 全周富氏积分计算谐波 - static void Foriere(int mode); // mode=0: 输出幅值 - // mode=1: 输出瞬时值 - - // 计算阻抗 - static void Impedance(unsigned int mode,unsigned int type); - - static void PowerOfOne(int mode); // 计算单相功率 - static void PowerOfTrip(int mode); // 计算三相功率 - - static unsigned int CalcuFaultPhase(void); // 故障选相 - static void SingleFaultLoc(unsigned int mode, double* dImp, double* dLen); - //单端测距(阻抗算法) - static void DoubleFaultLoc(unsigned int mode, double* dImp, double* dLen); - //双端测距(阻抗算法) - static bool CalcuFaultLine(int num, unsigned int* line); - // 故障选线(复合功率因数突变量算法) - static void PowerFactor(int n,int *dir,double *power); - // 求取复合功率因数 -}; -#endif //_PUBLICFUN_H - - +#ifndef _PUBLICFUN_H +#define _PUBLICFUN_H + + +#include "datastruct.h" +#include +#include +#include +#include +#include +#include + + +// 分析算法规模 +// +#define MAX_IN_WAVES 16 +#define MAX_OUT_WAVES 32 +#define MAX_POINTS 10000 +#define MAX_SILLS 8 + + +// 分析算法数据区 +// +struct wavedata_old +{ + int type; //保护类型 1--是LFP系列有前置移相电抗器的老保护 + double angle; //前置移相电抗器移相角度(度数) + unsigned int numi; //输入采样点个数 + unsigned int fsi; //输入采样率 + double pi[MAX_IN_WAVES][MAX_POINTS]; + //输入数据缓存 + unsigned int pfi; //输入数据标识 + unsigned int chi; //输入采样数据的通道数 + unsigned int numo; //输出采样点个数 + unsigned int fso; //输出采样率 + double po[MAX_OUT_WAVES][MAX_POINTS]; + //输出数据缓存 + unsigned int pfo[MAX_POINTS]; + //输出数据标识 + unsigned int cho; //输出数据的通道数 + unsigned int max; //要计算的最大谐波次数 + unsigned int min; //要计算的最小谐波次数 + unsigned int faultmode; //短路故障形式 + double dMaxVal; //最大有效值 + double dMinVal; //最小有效值 + int nMaxTick; //最大有效值位置 + int nMinTick; //最小有效值位置 + double zerocomp; //零序补偿系数 + double rps; //全线路正序电阻 + double xps; //全线路正序电抗 + double rps0; //全线路零序电阻 + double xps0; //全线路零序电抗 + double length; //线路长度 + double sill[MAX_SILLS]; //各种门槛值系数 + double dzlqd; //突变量电流起动定值 + double dled; //电流额定值 + double dyed; //电压额定值 +}; + +class CPublic +{ +public: + static void SetWidgetBackColor( QWidget* wg,const QColor& bc ); + static void SetWidgetForeColor( QWidget* wg,const QColor& fc ); + static QColor GetWidgetBackColor( QWidget* wg ); + static QColor GetWidgetForeColor( QWidget* wg ); + + static bool ReadStreamLine( QTextStream& stream,QString& sLine,int& nRow ); + static bool GetSubString(const QString& sString, const int nIndex, QString& sSub); + static bool GetSubString(QString& sString, QString& sSub); + static byte GetBitValue(const int nIndex, const WORD wLen, const char* pData); + static void GetAbsTime(const QDateTime& pBaseTime, int nTime, QDateTime& pstTime); + static QString GetDoubleValString(double dVal); + static QString GetDateString(int nData,int nBitNum); + static double GetTimeZoomRate( double fRaw ); + static double GetIntergerMax(double bMax); + //在pos位置后插入数组 + static bool InsertBitArray( QBitArray& datasrc,const QBitArray& datainsert,int pos ); + //从pos位置开始删除len个点 + static bool RemoveBitArray( QBitArray& datasrc, int pos,int len ); + //在pos位置后插入数组 + static bool InsertByteArray( QByteArray& datasrc,QByteArray& datainsert,int pos ); + //从pos位置开始删除len个点 + static bool RemoveByteArray( QByteArray& datasrc, int pos,int len ); + + /****************计算算法*****************************************/ + static void CalcuVirtualValue( double* pWaveData, + unsigned int nSampleNum, + unsigned int nSampleRate, + double* pRMSData, + double* pAngleData ); + + static void CalcuVirtualValue(); // 计算有效值及角度 + static void Frequence(); // 计算频率 + static void Average(int nAveTicks); // 计算平均值 + static void CalcuMinMax(); // 计算最大最小值 + + // 计算序分量 + static void Subsequence(); // 直接移相法 + static void FSubsequence(); // 富氏积分旋转向量法 + + // 全周富氏积分计算谐波 + static void Foriere(int mode); // mode=0: 输出幅值 + // mode=1: 输出瞬时值 + + // 计算阻抗 + static void Impedance(unsigned int mode,unsigned int type); + + static void PowerOfOne(int mode); // 计算单相功率 + static void PowerOfTrip(int mode); // 计算三相功率 + + static unsigned int CalcuFaultPhase(void); // 故障选相 + static void SingleFaultLoc(unsigned int mode, double* dImp, double* dLen); + //单端测距(阻抗算法) + static void DoubleFaultLoc(unsigned int mode, double* dImp, double* dLen); + //双端测距(阻抗算法) + static bool CalcuFaultLine(int num, unsigned int* line); + // 故障选线(复合功率因数突变量算法) + static void PowerFactor(int n,int *dir,double *power); + // 求取复合功率因数 +}; +#endif //_PUBLICFUN_H + + diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CTimeAxisShow.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CTimeAxisShow.cpp index 1dc3c1e9..a8a6c1c5 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CTimeAxisShow.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CTimeAxisShow.cpp @@ -1,1883 +1,1883 @@ -#include "CTimeAxisShow.h" -#include -#include -#include -#include -#include -#include -#include -#include "CPublic.h" -#include "CComDataClass.h" -#include -#include -#include -#include -#include "CWaveShow.h" -const int TEXT_WIDTH = 50; -const int GRID_WIDTH = 2; - -CTimeSlider::CTimeSlider( QWidget *parent ) -:QObject(parent),m_pParent(parent) -{ - m_Palette.setColor( QPalette::Foreground, QColor( 0, 170, 127) ); - m_Palette.setColor( QPalette::Button, QColor( 236, 233, 216) ); - m_Palette.setColor( QPalette::Light, Qt::white ); - m_Palette.setColor( QPalette::Midlight, QColor( 241, 239, 226) ); - m_Palette.setColor( QPalette::Dark, QColor( 172, 168, 153) ); - m_Palette.setColor( QPalette::Mid, QColor( 157, 155, 143) ); - m_Palette.setColor( QPalette::Text, Qt::black ); - m_Palette.setColor( QPalette::BrightText, Qt::white ); - m_Palette.setColor( QPalette::ButtonText, Qt::black ); - m_Palette.setColor( QPalette::Base, Qt::white ); - m_Palette.setColor( QPalette::Background, Qt::white ); - m_Palette.setColor( QPalette::Shadow, QColor( 113, 111, 100) ); - m_Palette.setColor( QPalette::Highlight, QColor( 49, 106, 197) ); - m_Palette.setColor( QPalette::HighlightedText, Qt::white ); - m_Palette.setColor( QPalette::Link, QColor( 0, 0, 255) ); - m_Palette.setColor( QPalette::LinkVisited, QColor( 255, 0, 255) ); - - m_bMoveBaseBar1 = false; - m_bMoveBaseBar2 = false; - - m_bEnablePos1 = true; - m_bEnablePos2 = true; -} - -CTimeSlider::~CTimeSlider() -{ - -} - -void CTimeSlider::Draw( QPainter *paint ) -{ - paint->setPen(Qt::blue); - qDrawShadePanel(paint,m_rcGeometry,m_Palette,true); - if( m_bEnablePos1 ) - { - paint->drawText(m_rcBar1,Qt::AlignCenter,"B"); - qDrawShadePanel(paint,m_rcBar1,m_Palette); - } - if(m_bEnablePos2) - { - paint->drawText(m_rcBar2,Qt::AlignCenter,"C"); - qDrawShadePanel(paint,m_rcBar2,m_Palette); - } - - if( m_bMoveBaseBar1 ) - DrawMoveBar(paint,1,m_nLastXPos); - if( m_bMoveBaseBar2 ) - DrawMoveBar(paint,2,m_nLastXPos); -} - -//******************************************************************** -// 画BaseBar的移动线 -//******************************************************************** -void CTimeSlider::DrawMoveBar( QPainter* paint,int nNo,int nPos ) -{ - if(1==nNo) - { - paint->setPen( m_Palette.color( QPalette::Background ) ); - paint->setBrush( m_Palette.color( QPalette::Foreground ) ); - QRect rcRect = m_rcBar1; - rcRect.setLeft( nPos -SILIDER_HEIGHT/2); - rcRect.setWidth(SILIDER_HEIGHT); - paint->drawText(rcRect,Qt::AlignCenter,"B"); - qDrawShadePanel(paint,rcRect,m_Palette); - } - else if(2==nNo) - { - paint->setPen( m_Palette.color( QPalette::Background ) ); - paint->setBrush( m_Palette.color( QPalette::Foreground ) ); - QRect rcRect = m_rcBar2; - rcRect.setLeft( nPos -SILIDER_HEIGHT/2); - rcRect.setWidth(SILIDER_HEIGHT); - paint->drawText(rcRect,Qt::AlignCenter,"C"); - qDrawShadePanel(paint,rcRect,m_Palette); - } -} - -void CTimeSlider::SetPosition1( int nPos1 ) -{ - m_nPos1 = nPos1; - - m_rcBar1 = m_rcGeometry; - m_rcBar1.setLeft( nPos1 -SILIDER_HEIGHT/2 ); - m_rcBar1.setWidth(SILIDER_HEIGHT); -} - -void CTimeSlider::SetPosition2( int nPos2 ) -{ - m_nPos2 = nPos2; - m_rcBar2 = m_rcGeometry; - m_rcBar2.setLeft( nPos2 - SILIDER_HEIGHT/2 ); - m_rcBar2.setWidth(SILIDER_HEIGHT); -} - -void CTimeSlider::SetEnablePso1( bool bEnable ) -{ - m_bEnablePos1 = bEnable; -} - -void CTimeSlider::SetEnablePso2( bool bEnable ) -{ - m_bEnablePos2 = bEnable; -} - -void CTimeSlider::SetGeometry( const QRect& geom ) -{ - m_rcGeometry = geom; -} - -void CTimeSlider::DoMousePress(QMouseEvent *e) -{ - //{{处理移动 - if( e->button() == Qt::LeftButton ) - { - QPoint pt = e->pos(); - if(m_rcBar1.contains(pt)) - { - m_bMoveBaseBar1 = true; - m_bMoveBaseBar2 = false; - m_nLastXPos = e->x(); - return; - } - - if(m_rcBar2.contains(pt)) - { - m_bMoveBaseBar1 = false; - m_bMoveBaseBar2 = true; - m_nLastXPos = e->x(); - return; - } - } - //}} -} - -void CTimeSlider::DoMouseMove(QMouseEvent *e) -{ - //{{处理移动 - if( e->buttons() & Qt::LeftButton ) - { - if( m_bMoveBaseBar1 ) - { - m_nLastXPos = e->x(); - return; - } - if( m_bMoveBaseBar2 ) - { - m_nLastXPos = e->x(); - return; - } - } - //}} -} - -void CTimeSlider::DoMouseRelease(QMouseEvent *e) -{ - //{{处理移动 - if( e->button() == Qt::LeftButton ) - { - if( m_bMoveBaseBar1 ) - { - m_bMoveBaseBar1 = false; - m_bMoveBaseBar2 = false; - emit OnChange(1,m_nLastXPos); - } - else if( m_bMoveBaseBar2 ) - { - m_bMoveBaseBar1 = false; - m_bMoveBaseBar2 = false; - emit OnChange(2,m_nLastXPos); - } - } - //}} -} - -////////////////////////////////////////////////////////////////////////// -CVerticalSlider::CVerticalSlider( QWidget *parent ) -:QObject(parent),m_pParent(parent) -{ - m_Palette.setColor( QPalette::Foreground, QColor( 0, 170, 127) ); - m_Palette.setColor( QPalette::Button, QColor( 236, 233, 216) ); - m_Palette.setColor( QPalette::Light, Qt::white ); - m_Palette.setColor( QPalette::Midlight, QColor( 241, 239, 226) ); - m_Palette.setColor( QPalette::Dark, QColor( 172, 168, 153) ); - m_Palette.setColor( QPalette::Mid, QColor( 157, 155, 143) ); - m_Palette.setColor( QPalette::Text, Qt::white ); - m_Palette.setColor( QPalette::BrightText, Qt::white ); - m_Palette.setColor( QPalette::ButtonText, Qt::black ); - m_Palette.setColor( QPalette::Base, Qt::blue ); - m_Palette.setColor( QPalette::Background, Qt::white ); - m_Palette.setColor( QPalette::Shadow, QColor( 113, 111, 100) ); - m_Palette.setColor( QPalette::Highlight, QColor( 49, 106, 197) ); - m_Palette.setColor( QPalette::HighlightedText, Qt::white ); - m_Palette.setColor( QPalette::Link, QColor( 0, 0, 255) ); - m_Palette.setColor( QPalette::LinkVisited, QColor( 255, 0, 255) ); - - m_bMoveBaseBar = false; - SetPosition(0); -} - -CVerticalSlider::~CVerticalSlider() -{ - -} - -void CVerticalSlider::Draw( QPainter *paint ) -{ - paint->setPen( Qt::blue ); - qDrawShadePanel(paint,m_rcGeometry,m_Palette,true); - paint->drawText(m_rcBar,Qt::AlignCenter,"P"); - qDrawShadePanel(paint,m_rcBar,m_Palette); - - if( m_bMoveBaseBar ) - DrawMoveBar(paint,m_nLastXPos); - -} - -//******************************************************************** -// 画BaseBar的移动线 -//******************************************************************** -void CVerticalSlider::DrawMoveBar( QPainter *paint,int nPos ) -{ -// QPainter paint( m_pParent ); - paint->setPen( m_Palette.color( QPalette::Background ) ); - paint->setBrush( m_Palette.color( QPalette::Foreground ) ); - paint->setCompositionMode( QPainter::CompositionMode_Xor ); - QRect rcRect = m_rcBar; - rcRect.setTop( nPos -SILIDER_HEIGHT/2); - rcRect.setHeight(SILIDER_HEIGHT); - paint->drawText(rcRect,Qt::AlignCenter,"P"); - qDrawShadePanel(paint,rcRect,m_Palette); -} - -void CVerticalSlider::SetPosition( int nPos ) -{ - m_nPos = nPos; - - m_rcBar = m_rcGeometry; - m_rcBar.setTop( nPos -SILIDER_HEIGHT/2 ); - m_rcBar.setHeight(SILIDER_HEIGHT); -} - -void CVerticalSlider::SetGeometry( const QRect& geom ) -{ - m_rcGeometry = geom; - SetPosition( m_nPos ); -} - -void CVerticalSlider::DoMousePress(QMouseEvent *e) -{ - //{{处理移动 - if( e->button() == Qt::LeftButton ) - { - QPoint pt = e->pos(); - if(m_rcBar.contains(pt)) - { - m_bMoveBaseBar = true; - m_nLastXPos = e->y(); - return; - } - } - //}} -} - -void CVerticalSlider::DoMouseMove(QMouseEvent *e) -{ - //{{处理移动 - if( e->buttons() & Qt::LeftButton ) - { - if( m_bMoveBaseBar ) - { - m_nLastXPos = e->y(); - return; - } - } - //}} -} - -void CVerticalSlider::DoMouseRelease(QMouseEvent *e) -{ - //{{处理移动 - if( e->button() == Qt::LeftButton ) - { - if( m_bMoveBaseBar ) - { - m_nLastXPos = e->y(); - m_bMoveBaseBar = false; - SetPosition( m_nLastXPos ); - emit OnChange(m_nLastXPos); - } - } - //}} -} -///////////////////////////////////////////////////// -CTimeAxisShow::CTimeAxisShow(QWidget *parent,QScrollBar* horscrl, Qt::WindowFlags f ) - :QWidget(parent,f),horiz_bar(horscrl) -{ -// setAttribute(Qt::WA_PaintOutsidePaintEvent); - - setWindowFlag( Qt::WindowStaysOnTopHint ); - setMouseTracking(true); - - QVBoxLayout* vboxLayout = new QVBoxLayout(this); - vboxLayout->setSpacing(0); - vboxLayout->setContentsMargins(0, 0, 0, 0); - QSpacerItem* spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); - horiz_bar = new QScrollBar(Qt::Horizontal,this); - vboxLayout->addItem(spacerItem); - vboxLayout->addWidget( horiz_bar ); - horiz_bar->setRange(0,500); - horiz_bar->setSingleStep(SCROLLBAR_H_LINE); - horiz_bar->setPageStep(SCROLLBAR_H_LINE*5); - horiz_bar->setTracking(false); - horiz_bar->setCursor(GetParent()->m_hHandCursor); - - connect(horiz_bar,SIGNAL(valueChanged(int)),this,SLOT(HoriztalScrollBarMove(int))); - connect(horiz_bar,SIGNAL(sliderMoved(int)),this,SLOT(HoriztalScrollBarMove(int))); - -// m_pTimeSlider = new CTimeSlider(this); -// connect(m_pTimeSlider,SIGNAL(OnChange(int,int)),this,SLOT(OnSliderMove(int,int))); - -// setAutoFillBackground(true); - - DGrayPen = QPen(DGRAY_COLOR,1,Qt::SolidLine); - BluePen = QPen(BLUE_COLOR,1,Qt::SolidLine); - RedPen = QPen(RED_COLOR,1,Qt::SolidLine); - WhitePen = QPen(WHITE_COLOR,1,Qt::SolidLine); - DRedPen = QPen(DRED_COLOR,1,Qt::SolidLine); - LLGrayPen = QPen(LLGRAY_COLOR,1,Qt::SolidLine); - LCyanPen = QPen(LCYAN_COLOR,1,Qt::SolidLine); - m_TinyFont = QFont("Arial",10); - m_LittleFont = QFont("Arial",10); - m_TextBrush.setColor(QColor(0,0,224)); - - m_nCursorX = -1; - m_nScrollLeft = 0; - - m_pWaveFile = 0; - - - - setCursor(GetParent()->m_hCrossCursor); -} - -CTimeAxisShow::~CTimeAxisShow() -{ - -} - -////////////////////////////////////////////////////////////////////////// -void CTimeAxisShow::OnMousePressEvent( QMouseEvent *e ) -{ - doMousePress( e ); - update(); - //GetParent()->update(); - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(4,false); - GetParent()->redrawWindow(1,false);//在名称区显示数据值,20090818 - GetParent()->redrawWindow(7,false); - GetParent()->showStatus(); -// if( GetParent()->m_pStatusView ) -// GetParent()->m_pStatusView->Refresh(); - QWidget::mousePressEvent( e ); -} - -void CTimeAxisShow::OnMouseReleaseEvent( QMouseEvent *e ) -{ - doMouseRelease( e ); - QWidget::mouseReleaseEvent( e ); -} - -void CTimeAxisShow::OnMouseMoveEvent( QMouseEvent *e ) -{ - if(GetParent()) - { -// setCursor( GetParent()->m_hArrowCursor ); - doMouseMove(e); - -// int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; -// QPoint pt(e->x() - nLeftMargin,e->y()); -// QMouseEvent event(QEvent::MouseMove,pt,e->button(),e->buttons(),e->modifiers()); -// -// CDigitalShow *pDgtView = GetParent()->m_pDigitalView; -// if(pDgtView) pDgtView->doMouseMove( &event ); -// -// CAnalogueShow *pAnaView = GetParent()->m_pAnalogueView; -// if(pAnaView) pAnaView->doMouseMove( &event ); - -// GetParent()->redrawWindow(2,false); -// GetParent()->redrawWindow(4,false); - update(); - } -// QWidget::mouseMoveEvent( e ); -} - -void CTimeAxisShow::paintEvent( QPaintEvent *e ) -{ - Q_UNUSED(e) - QPainter paint; - paint.begin(this ); - //paint.setBrush(palette().color( QPalette::Foreground )); - draw( &paint ); - paint.end(); -} - -void CTimeAxisShow::draw( QPainter *paint) -{ - if(!m_pWaveFile) return; - - m_SliderBar = rect(); - m_SliderBar.setTop( m_SliderBar.bottom() - SILIDER_HEIGHT ); -// m_pTimeSlider->SetGeometry( m_SliderBar ); - - drawBackGnd(paint); - drawTimeAxisB(paint); - if(CWaveEnv::GetInst()->m_bShowBaseLine )//基准线 - drawBaseLine(paint,CWaveEnv::GetInst()->m_BaseLineColor); - - if(CWaveEnv::GetInst()->m_bShowTriggerLine) - drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fTriggerTick,RED_COLOR);//游标线 - - drawStaticLine(paint,CWaveEnv::GetInst()->m_StaticLineColor);//当前时标线 - drawCursor(paint); -// m_pTimeSlider->Draw(paint); -} - -//下边打印 -void CTimeAxisShow::PrintB( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,bool bUpper) -{ - Q_UNUSED(bColor) - if(!m_pWaveFile) return; - - int nLeftMargin = 0; - int nMaxWidth = m_pWaveFile->GetMaxWidth(); - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; -// double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; - - QRect ClientRect = rect; - QPen oldPen = paint->pen(); - QBrush oldBrush = paint->brush(); - QFont OldFont = paint->font(); - - paint->setPen(DRedPen); - - QFont textFont("Arial"); - textFont.setPixelSize(9); - - paint->setFont( textFont ); - paint->setBrush( m_TextBrush ); - - int nLeft = qMax(ClientRect.left(), nLeftMargin); - int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin); - - int nTipStart,nTipEnd; - if(!bUpper){ - nTipStart = 0;nTipEnd = TIPS_HEIGHT;} - else{ - nTipStart = TIMEAXIS_HEIGHT -1;nTipEnd = TIMEAXIS_HEIGHT - TIPS_HEIGHT;} - - paint->drawLine(QPoint(nLeft,nTipStart) + ptOffset,QPoint(nRight,nTipStart) + ptOffset); - - QRect rcPoint; - int m_nZoomX = int(128.0*fZoomX); - // 画标线 - if(m_nZoomX >= 128) - { - double nOneWidth = GRID_WIDTH*fZoomX; - int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); - - int Tick1 = (ClientRect.left() - nLeftMargin - 51) / nOneWidth - 1; - int Tick2 = (ClientRect.right() - nLeftMargin + 51) / nOneWidth + 1; - if(Tick1 < 0) Tick1 = 0; - if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; - - // 小格线 每点 - // 中格线, 每100毫秒, 每5ms - // 大格线, 每500秒, 块的起始点, 每20ms - // 写文字, 块的起始点, 500ms, 20ms - for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) - { - int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; - // 如每格20ms 或 > 20ms - int TB1 = m_pWaveFile->GetStartTick(TR); - int TB2 = TB1 + nGridAmt; - int T1, T2; - if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); - if(TB2 ClientRect.right() ) - break; - - // 小格线 - - if( (int)(ii*nOneWidth)%(int)(GRID_WIDTH) == 0 ) - { - paint->drawLine( nTickPos + ptOffset.x(), nTipStart + ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd + ptOffset.y()); - } - - // 起始点,最后一块的中止点 - bool bDrawText = false; - qlonglong time = m_pWaveFile->m_aTimeArray[ii]; - long TimeDrawn = 0; - if( (ii==TB1)||(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1) ) - { - // 起始点 - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - paint->drawLine(nTickPos + ptOffset.x()+1, nTipStart+ptOffset.y(),nTickPos + ptOffset.x()+1, nTipEnd+ ptOffset.y()); - - bDrawText = true; - TimeDrawn = (time/1000L); - paint->setPen( QColor( 0,0,224 ) ); - } - else - { - if(m_pWaveFile->m_dSampleRate[TR] <= 50) - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 100ms点 - if((time1 % 100000L) >= (time % 100000L)) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - } - // 500ms点 - if((time1 % 500000L) >= (time % 500000L)) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - - if(abs(ii-TB1)>10 && abs(ii-TB2)>10) - { - TimeDrawn = (time/500000L)*500; - paint->setPen( QColor( 0,0,64 ) ); - bDrawText = true; - } - } - } - else - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 5ms点 - if((time1 % 5000L) >= (time % 5000L)) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - } - // 20ms点 - if((time1 % 20000L) >= (time % 20000L)) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - - if(abs(ii-TB1)>10 && abs(ii-TB2)>10) - { - TimeDrawn = (time/20000L)*20; - paint->setPen( QColor( 0,0,64 ) ); - bDrawText = true; - } - } - } - } - - if(bDrawText) - { - TimeDrawn = time/1000L; - TimeDrawn += m_pWaveFile->m_nFrist_ms; - - rcPoint = QRect(nTickPos + ptOffset.x() - 10, 8 + ptOffset.y() ,TEXT_WIDTH, TEXT_WIDTH); - - QString sComment; - if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); - else sComment.sprintf("%ld,%03ld", TimeDrawn/1000L, TimeDrawn%1000L); - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - paint->setPen(QColor(0,0,64)); - } - } - } - } - - if(m_nZoomX<=64 && m_nZoomX>0) - { - int n = 1.0/fZoomX; - if(n <= 0) n = 1; - - int nOneWidth = GRID_WIDTH; - int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); - - int Tick1 = ((ClientRect.left()- nLeftMargin - 51) / nOneWidth - 1)* n; - int Tick2 = ((ClientRect.right() - nLeftMargin + 51) / nOneWidth + 1)* n; - - if(Tick1 < 0) Tick1 = 0; - if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; - - // 小格线 每100ms, 5ms, - // 中格线, 每500ms, 每20ms - // 大格线, 块的起始点, n*500ms, n*20ms - // 写文字, 块的起始点, n*500ms, n*20ms - for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) - { - int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; - // 如每格20ms 或 > 20ms - int TB1 = m_pWaveFile->GetStartTick(TR); - int TB2 = TB1 + nGridAmt; - int T1, T2; - if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); - if(TB2 ClientRect.right() ) - break; - - bool bDrawText = false; - int time = m_pWaveFile->m_aTimeArray[ii]; - long TimeDrawn = 0; - if((ii==TB1)||(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1)) - { - // 起始点 - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - paint->drawLine(nTickPos + ptOffset.x()+1, nTipStart+ptOffset.y(),nTickPos + ptOffset.x()+1, nTipEnd+ ptOffset.y()); - - bDrawText = true; - TimeDrawn = (time/1000L); - paint->setPen(QColor(0,0,224)); - } - else - { - if(m_pWaveFile->m_dSampleRate[TR] <= 50) - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 100ms点 - if((time1 % 100000L) >= (time % 100000L)) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - } - - // 500ms点 - if((time1 % 500000L) >= (time % 500000L)) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - } - // n*500ms点 - if((time1 % (500000L*n)) >= (time % (500000L*n))) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - - - if(abs(ii-TB1)>10*n && abs(ii-TB2)>10*n) - { - TimeDrawn = (time/500000L)*500; - paint->setPen(QColor(0,0,64)); - bDrawText = true; - } - } - } - else - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 5ms点 - if((time1 % 5000L) >= (time % 5000L)) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - } - if((time1 % 20000L) >= (time % 20000L)) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - } - if((time1 % (20000L*n)) >= (time % (20000L*n))) - { - paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); - - if(abs(ii-TB1)>10*n && abs(ii-TB2)>10*n) - { - TimeDrawn = (time/20000L)*20; - paint->setPen(QColor(0,0,64)); - bDrawText = true; - } - } - } - } - if(bDrawText) - { - TimeDrawn = time/1000L; - TimeDrawn += m_pWaveFile->m_nFrist_ms; - - rcPoint = QRect(nTickPos + ptOffset.x() - 5, 8+ptOffset.y() , TEXT_WIDTH, TEXT_WIDTH); - - QString sComment; - if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); - else sComment.sprintf("%ld,%03ld", TimeDrawn/1000L, TimeDrawn%1000L); - //GetTimeString(MsString,TimeDrawn); - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - paint->setPen(QColor(0,0,64)); - } - } - } - } - - paint->setFont(OldFont); - paint->setPen(oldPen); -} - -void CTimeAxisShow::Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,bool bUpper) -{ - Q_UNUSED(bColor) - if(!m_pWaveFile) return; - - QFont ptFont = QFont("Arial",9); - int nLeftMargin = 0; - int nMaxWidth = m_pWaveFile->GetMaxWidth(); - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; - - QPen oldPen = paint->pen(); - - QRect ClientRect = rect; - QBrush oldBrush = paint->brush(); - - paint->setPen(DRedPen); - QFont OldFont = paint->font(); - paint->setFont( ptFont ); - int nStyle = Qt::AlignLeft |Qt::AlignTop | Qt::TextSingleLine; - if(bUpper) - nStyle = Qt::AlignLeft |Qt::AlignBottom | Qt::TextSingleLine; - - int nLeft = qMax(ClientRect.left(), nLeftMargin); - int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin); - - int nTipStart,nTipEnd; - if(!bUpper){ - nTipStart = 0;nTipEnd = TIPS_HEIGHT;} - else{ - nTipStart = TIMEAXIS_HEIGHT -1;nTipEnd = TIMEAXIS_HEIGHT - TIPS_HEIGHT;} - - paint->drawLine(QPoint(nLeft,nTipStart) + ptOffset,QPoint(nRight,nTipStart) + ptOffset); - - for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) - { - int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk)+nLeftMargin; - int nBlockRight = m_pWaveFile->GetBlockRight(nBlk)+nLeftMargin; - - // 画小格线 - double fOneWidth = int(dGirdWidth*(fZoomX)+.5); - if(fOneWidth < dGirdWidth) - fOneWidth = dGirdWidth; - - int nGridAmt = int(double(nBlockRight-nBlockLeft)/fOneWidth+.5)+1; - - // 起始点,中止点 - - if(nBlockLeft>=ClientRect.left()&&nBlockLeft<=ClientRect.right()){ - paint->drawLine(nBlockLeft + ptOffset.x(), nTipStart + ptOffset.y(),nBlockLeft + ptOffset.x(), nTipEnd + ptOffset.y()); - } - - if(nBlockRight>=ClientRect.left()&&nBlockRight<=ClientRect.right()){ - paint->drawLine(nBlockRight + ptOffset.x(), nTipStart + ptOffset.y(),nBlockRight + ptOffset.x(), nTipEnd + ptOffset.y()); - } - - // 画起始,中止时间 - // - paint->setFont( ptFont ); - paint->setBrush( m_TextBrush ); - - QRect rcPoint; - QString sComment; - if(nBlockLeft>=ClientRect.left()&&nBlockLeft<=ClientRect.right()){ - if(bUpper) rcPoint = QRect (nBlockLeft, 9 - TIPS_HEIGHT ,TEXT_WIDTH, TEXT_WIDTH); - else rcPoint = QRect (nBlockLeft, TIPS_HEIGHT + 1 , TEXT_WIDTH, TEXT_WIDTH); - long lTime = m_pWaveFile->GetBlockBeginTime(nBlk); - sComment.sprintf("%ld", lTime); - QRect tem = QRect(rcPoint.topLeft() + ptOffset,rcPoint.bottomRight() + ptOffset); - paint->drawText(tem,nStyle,sComment); - } - - if(nBlockRight>=ClientRect.left()&&nBlockRight<=ClientRect.right()){ - if(nBlk == m_pWaveFile->m_nNRates-1) - { - rcPoint.setX(nBlockRight); - if(bUpper) rcPoint.setY( 9 - TIPS_HEIGHT ); - else rcPoint.setY(TIPS_HEIGHT + 1); - long lTime = m_pWaveFile->GetBlockEndTime(nBlk); - sComment.sprintf("%ld", lTime); - QRect tem = QRect(rcPoint.topLeft() + ptOffset,rcPoint.bottomRight() + ptOffset); - paint->drawText(tem,nStyle,sComment); - } - } - - double dGridArr[7] = {0.005, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0 }; - double dBigGridWidth = dGirdWidth*10.0; - for(int i=0; i<7; i++) - { - dBigGridWidth = m_pWaveFile->m_dSampleRate[nBlk]*dGridArr[i]*dGirdWidth*fZoomX; - if(dBigGridWidth >= 10.0*dGirdWidth) - break; - } - int nGrid = int(.5+dBigGridWidth/fOneWidth); - if(nGrid<1) nGrid = 1; - for(int nTick=1; nTick<(nGridAmt/nGrid)+1; nTick++) - { - int nX = nBlockLeft + int(.5+nTick*fOneWidth*double(nGrid)); - if(nXClientRect.right()) continue; - - if(nX + dGirdWidth*5.0 > nBlockRight) break; - paint->drawLine(QPoint(nX, nTipStart) + ptOffset,QPoint(nX, nTipEnd) + ptOffset); - - paint->setFont( ptFont ); - paint->setBrush( m_TextBrush ); - if(bUpper) rcPoint = QRect(nX - 5,9 - TIPS_HEIGHT, 30 , 20); - else rcPoint = QRect(nX - 5, TIPS_HEIGHT + 1 , 20 , 20); - QString sComment; - long lTime = long(.5+m_pWaveFile->GetXPositionTime(nX-nLeftMargin)); - if(lTime < 0) lTime = long(-0.5+m_pWaveFile->GetXPositionTime(nX-nLeftMargin)); - sComment.sprintf("%ld", lTime); - QRect tem = QRect(rcPoint.topLeft() + ptOffset,rcPoint.bottomRight() + ptOffset); - paint->drawText(tem,nStyle,sComment); - - } - paint->setBrush(oldBrush); - } - - paint->setFont(OldFont); - paint->setPen(oldPen); -} - -void CTimeAxisShow::drawBackGnd(QPainter *paint) -{ - QRect ClientRect = rect(); - ClientRect.setTop(ClientRect.top() - 1); - QBrush oldBrush = paint->brush(); - paint->setBrush(CWaveEnv::GetInst()->m_TimeBackColor); - paint->drawRect(ClientRect); -} - -void CTimeAxisShow::drawTimeAxisA( QPainter *paint ) -{ - if(!m_pWaveFile) return; - - int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; - int nMaxWidth = m_pWaveFile->GetMaxWidth(); - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; -// int nHeight = 6; - int nX = 0; - - int fOneWidth = int(dGirdWidth*(fZoomX)+.5); - if(fOneWidth < dGirdWidth) - fOneWidth = dGirdWidth; - - QPen oldPen = paint->pen(); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - QFont OldFont = paint->font(); - paint->setFont(m_TinyFont); - - Qt::BGMode oldMode = paint->backgroundMode(); - paint-> setBackgroundMode(Qt::TransparentMode); - - QRect ClientRect = GetValidRect(); - int nLeft = qMax(ClientRect.left(), nLeftMargin - m_nScrollLeft); - int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin - m_nScrollLeft); - - paint->drawLine(nLeft,0,nRight,0); - - -//** - // 画标线 -// if(m_nZoomX >= 128) - { - double nOneWidth = GRID_WIDTH*fZoomX; - int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); - - int Tick1 = (ClientRect.left() - nLeftMargin - 51) / nOneWidth - 1; - int Tick2 = (ClientRect.right() - nLeftMargin + 51) / nOneWidth + 1; - if(Tick1 < 0) Tick1 = 0; - if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; - - // 小格线 每点 - // 中格线, 每100毫秒, 每5ms - // 大格线, 每500秒, 块的起始点, 每20ms - // 写文字, 块的起始点, 500ms, 20ms - QRect rcPoint; - for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) - { - int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; - // 如每格20ms 或 > 20ms - int TB1 = m_pWaveFile->GetStartTick(TR); - int TB2 = TB1 + nGridAmt; - int T1, T2; - if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); - if(TB2SelectObject(&trPen); - int ii = 0; - for(ii=T1; iidrawLine(nLeftMargin + ii*nOneWidth -m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth -m_nScrollLeft, nHeight); - } - - // 起始点,最后一块的中止点 - bool bDrawText = false; - double time = m_pWaveFile->m_aTimeArray[ii]; - long TimeDrawn = 0; - if(ii==TB1 ) - { - // 起始点 - nHeight = 12; - nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; - paint->drawLine(nX, 0 ,nX, nHeight ); - paint->drawLine(nX+1, 0,nX+1, nHeight); - bDrawText = true; - } - else if(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1) - { - // 终点 - nHeight = 12; - nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; - paint->drawLine(nX, 0,nX, nHeight ); - paint->drawLine(nX+1, 0,nX+1, nHeight); - bDrawText = true; - } - - if(bDrawText) - { - TimeDrawn = time/1000L; -// TimeDrawn += m_pWaveFile->GetFirstMicroSecs(); - nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; - rcPoint = QRect(nX - m_nScrollLeft - 5, 18 , TEXT_WIDTH, TEXT_WIDTH); - - QString sComment; - if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); - else sComment.sprintf("%ld\"%03ld", TimeDrawn/1000L, TimeDrawn%1000L); -// GetTimeString(MsString,TimeDrawn); - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - } - } - - - //画中格线 - // (每5ms), - // 如间距 < 10*GRID_WIDTH, (每20ms) - // 如间距 < 10*GRID_WIDTH, (每50ms) - // 如间距 < 10*GRID_WIDTH, (每100ms) - // 如间距 < 10*GRID_WIDTH, (每200ms) - // 如间距 < 10*GRID_WIDTH, (每500ms) - // 如间距 < 10*GRID_WIDTH, (每1000ms) - - double dBigGridWidth = GRID_WIDTH*10.0; -/* for(int i=0; i<12; i++)//按照整数来画标尺 - { - dBigGridWidth = pDoc->m_aRatesArray[TR]*dGridArr[i]*GRID_WIDTH*fZoomX; - if(dBigGridWidth >= 10.0*GRID_WIDTH) - break; - }*/ - int nGrid = int(.5+dBigGridWidth/nOneWidth); - - //pDC->SetTextColor(TmColorArray[TR%32]); - int nStart = 0; - if( TR>0 ) - { - int nGridAmt_prv = m_pWaveFile->m_lSampleAmount[TR-1]; - nStart = nGridAmt_prv%nGrid; - } - - for(ii=1; ii<(nGridAmt/nGrid)+1; ii++) - { - int nRulerStick = TB1+ii*double(nGrid) - nStart; - if( nRulerStick>TB2 ) - break; - - int nHeight = 12; - int nX = nLeftMargin + nRulerStick*nOneWidth - m_nScrollLeft; - - paint->drawLine(nX, 0,nX, nHeight); - - rcPoint = QRect(nX - m_nScrollLeft - 5, 18 , TEXT_WIDTH, TEXT_WIDTH); - - long TimeDrawn = m_pWaveFile->GetPointTime( nRulerStick ); - - QString sComment; - if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); - else sComment.sprintf("%ld\"%03ld", TimeDrawn/1000L, TimeDrawn%1000L); - //GetTimeString(MsString,lTime); - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - } - } - } - - QPoint rcText(nLeftMargin - m_nScrollLeft - 10, 15); - - QFont font = QApplication::font(); - font.setPointSize(OldFont.pointSize()); - paint->setFont(font); - - QString sComment = tr("Timestamp"); - paint->drawText(rcText,sComment); - - paint->setBackgroundMode(oldMode); - - paint->setFont(OldFont); - paint->setPen(oldPen); -} - - -void CTimeAxisShow::drawTimeAxisB( QPainter *paint ) -{ - if(!m_pWaveFile) return; - - int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; - nLeftMargin = 0; -// int nMaxWidth = m_pWaveFile->GetMaxWidth(); - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; -// int nHeight = 6; - int nX = 0; - //{{20090821 -// int nLeftWaveAxis = m_pWaveFile->m_DispAttr.m_nLeftWaveAxis; - //}} - - double fOneWidth = int(dGirdWidth*(fZoomX)+.5); - if(fOneWidth < dGirdWidth) - fOneWidth = dGirdWidth; - - QPen oldPen = paint->pen(); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - QFont OldFont = paint->font(); - paint->setFont(m_TinyFont); - -// Qt::BGMode oldMode = paint->backgroundMode(); -// paint-> setBackgroundMode(Qt::TransparentMode); - - QRect ClientRect = GetValidRect(); -// int nLeft = qMax(ClientRect.left(), nLeftMargin - m_nScrollLeft); -// int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin - m_nScrollLeft); -// int nLeft = ClientRect.left(); -// int nRight = qMin(ClientRect.right(), nMaxWidth - m_nScrollLeft); - - //paint->drawLine(nLeft, 0,nRight, 0); - - QRect rcPoint; - - int m_nZoomX = int(128.0*fZoomX); - // 画标线 - if(m_nZoomX >= 128) - { - double nOneWidth = GRID_WIDTH*fZoomX; - int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); - -// int Tick1 = (ClientRect.left() + m_nScrollLeft - nLeftMargin - 51) / nOneWidth - 1; -// int Tick2 = (ClientRect.right() + m_nScrollLeft- nLeftMargin + 51) / nOneWidth + 1; - int Tick1 = (ClientRect.left() + m_nScrollLeft - 51) / nOneWidth - 1; - int Tick2 = (ClientRect.right() + m_nScrollLeft + 51) / nOneWidth + 1; - if(Tick1 < 0) Tick1 = 0; - if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; - - // 小格线 每点 - // 中格线, 每100毫秒, 每5ms - // 大格线, 每500秒, 块的起始点, 每20ms - // 写文字, 块的起始点, 500ms, 20ms - for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) - { - int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; - // 如每格20ms 或 > 20ms - int TB1 = m_pWaveFile->GetStartTick(TR); - int TB2 = TB1 + nGridAmt; - int T1, T2; - if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); - if(TB2= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth -m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth -m_nScrollLeft, nHeight); - } - - // 起始点,最后一块的中止点 - bool bDrawText = false; - qlonglong time = m_pWaveFile->m_aTimeArray[ii]; - long TimeDrawn = 0; - if( (ii==TB1)||(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1) ) - { - // 起始点 - nHeight = 8/*18*/; - nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nX, 0 ,nX, nHeight ); - - bDrawText = true; - TimeDrawn = (time/1000L); - //paint->setPen( QColor( 0,0,224 ) ); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - } - else - { - if(m_pWaveFile->m_dSampleRate[TR] <= 5) - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 5000ms点 - if((time1 % 5000000L) >= (time % 5000000L)) - { - nHeight = 4/*8*/; - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft ,nHeight); - } - - // 20000ms点 - if((time1 % 20000000L) >= (time % 20000000L)) - { - nHeight = 6/*12*/; - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); - - if(abs(ii-TB1)>10 && abs(ii-TB2)>10) - { - TimeDrawn = (time/1000L); - //paint->setPen( QColor( 0,0,64 ) ); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - bDrawText = true; - } - } - } - else if(m_pWaveFile->m_dSampleRate[TR] <= 20) - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - - // 200ms点 - if((time1 % 200000L) >= (time % 200000L)) - { - nHeight = 4/*8*/; - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); - } - - // 10000ms点 - if((time1 % 1000000L) >= (time % 10000000L)) - { - nHeight = 6/*12*/; - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); - - if(abs(ii-TB1)>10 && abs(ii-TB2)>10) - { - TimeDrawn = (time/1000L); - //paint->setPen( QColor( 0,0,64 ) ); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - bDrawText = true; - } - } - } - else if(m_pWaveFile->m_dSampleRate[TR] <= 50) - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 100ms点 - if((time1 % 100000L) >= (time % 100000L)) - { - nHeight = 4/*8*/; - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); - } - // 500ms点 - if((time1 % 500000L) >= (time % 500000L)) - { - nHeight = 6/*12*/; - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); - - if(abs(ii-TB1)>10 && abs(ii-TB2)>10) - { - TimeDrawn = (time/500000L)*500; - //paint->setPen( QColor( 0,0,64 ) ); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - bDrawText = true; - } - } - } - else - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 5ms点 - nHeight = 4/*8*/; - if((time1 % 5000L) >= (time % 5000L)) - { - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); - } - // 20ms点 - nHeight = 6/*12*/; - if((time1 % 20000L) >= (time % 20000L)) - { - if(int(ii*nOneWidth) - m_nScrollLeft >= 0) - paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); - - if(abs(ii-TB1)>10 && abs(ii-TB2)>10) - { - TimeDrawn = (time/20000L)*20; - //paint->setPen( QColor( 0,0,64 ) ); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - bDrawText = true; - } - } - } - } - - if(bDrawText && (int(ii*nOneWidth) - m_nScrollLeft >= 0)) - { - TimeDrawn = time/1000L; - TimeDrawn += m_pWaveFile->m_nFrist_ms; - nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; - rcPoint = QRect(nX - 5, 7/*18*/ , TEXT_WIDTH, TEXT_WIDTH); - - QString sComment; - if (TimeDrawn < 0) sComment.sprintf("-%ld", -1*TimeDrawn); - else if((TimeDrawn < 1000)&&(TimeDrawn >= 0)) sComment.sprintf("%ld", TimeDrawn); - else sComment.sprintf("%ld\"%03ld", TimeDrawn/1000L, TimeDrawn%1000L); - - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - //paint->setPen(QColor(0,0,64)); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - } - } - } - } - - if(m_nZoomX<=64 && m_nZoomX>0) - { - int n = 1.0/fZoomX; - if(n <= 0) n = 1; - - int nOneWidth = GRID_WIDTH; - int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); - - int Tick1 = ((ClientRect.left() + m_nScrollLeft - nLeftMargin - 51) / nOneWidth - 1)* n; - int Tick2 = ((ClientRect.right() + m_nScrollLeft - nLeftMargin + 51) / nOneWidth + 1)* n; - - if(Tick1 < 0) Tick1 = 0; - if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; - - // 小格线 每100ms, 5ms, - // 中格线, 每500ms, 每20ms - // 大格线, 块的起始点, n*500ms, n*20ms - // 写文字, 块的起始点, n*500ms, n*20ms - for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) - { - int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; - // 如每格20ms 或 > 20ms - int TB1 = m_pWaveFile->GetStartTick(TR); - int TB2 = TB1 + nGridAmt; - int T1, T2; - if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); - if(TB2m_aTimeArray[ii]; - long TimeDrawn = 0; - if((ii==TB1)||(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1)) - { - // 起始点 - nHeight = 6/*12*/; - nX = nLeftMargin + ii*nOneWidth/n - m_nScrollLeft; - paint->drawLine(nX, 0 ,nX, nHeight ); - paint->drawLine(nX+1, 0,nX+1, nHeight); - - bDrawText = true; - TimeDrawn = (time/1000L); - //paint->setPen(QColor(0,0,224)); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - } - else - { - if(m_pWaveFile->m_dSampleRate[TR] <= 50) - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 小格线 - nHeight = 2/*5*/; - // 100ms点 - if((time1 % 100000L) >= (time % 100000L)) - { - paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); - } - - // 500ms点 - if((time1 % 500000L) >= (time % 500000L)) - { - nHeight = 4/*8*/; - paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); - } - // n*500ms点 - if((time1 % (500000L*n)) >= (time % (500000L*n))) - { - nHeight = 6/*12*/; - paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); - - - if(abs(ii-TB1)>10*n && abs(ii-TB2)>10*n) - { - TimeDrawn = (time/500000L)*500; - //paint->setPen(QColor(0,0,64)); - bDrawText = true; - } - } - } - else - { - int time1 = m_pWaveFile->m_aTimeArray[ii-1]; - // 小格线 - nHeight = 2/*5*/; - // 5ms点 - if((time1 % 5000L) >= (time % 5000L)) - { - paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); - } - - // 20ms点 - nHeight = 4/*8*/; - if((time1 % 20000L) >= (time % 20000L)) - { - paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); - } - // n*20ms点 - nHeight = 6/*12*/; - if((time1 % (20000L*n)) >= (time % (20000L*n))) - { - paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); - - if(abs(ii-TB1)>10*n && abs(ii-TB2)>10*n) - { - TimeDrawn = (time/20000L)*20; - //paint->setPen(QColor(0,0,64)); - bDrawText = true; - } - } - } - } - if(bDrawText) - { - TimeDrawn = time/1000L; - TimeDrawn += m_pWaveFile->m_nFrist_ms; - nX = nLeftMargin + ii*nOneWidth/n - m_nScrollLeft; - rcPoint = QRect(nX - 5, 7/*18*/ , TEXT_WIDTH, TEXT_WIDTH); - - QString sComment; - if (TimeDrawn < 0) sComment.sprintf("-%ld", -1*TimeDrawn); - else if((TimeDrawn < 1000)&&(TimeDrawn >= 0)) sComment.sprintf("%ld", TimeDrawn); - else sComment.sprintf("%ld\"%03ld", TimeDrawn/1000L, TimeDrawn%1000L); - - //if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); - //else sComment.sprintf("%d,%03d", TimeDrawn/1000L, TimeDrawn%1000L); - //GetTimeString(MsString,TimeDrawn); - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - //paint->setPen(QColor(0,0,64)); - } - } - } - } - -// QPoint rcText(nLeftMargin - m_nScrollLeft - 40, 15); -// QPoint rcText(nLeftMargin + 20,15); -// -// QFont font = QApplication::font(); -// font.setPointSize(OldFont.pointSize()); -// paint->setFont(font); -// -// QString sComment = tr("时标"); -// paint->drawText(rcText,sComment); - -// paint->setBackgroundMode(oldMode); - - paint->setFont(OldFont); - paint->setPen(oldPen); -} - -void CTimeAxisShow::drawTimeAxis( QPainter *paint ) -{ - if(!m_pWaveFile) return; - - int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; -// int nMaxWidth = m_pWaveFile->GetMaxWidth(); - double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; - //fZoomX = 25.0/43.0; - double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; - int nHeight = 6; - - double fOneWidth = double(dGirdWidth*(fZoomX)+.5); - if(fOneWidth < dGirdWidth) - fOneWidth = dGirdWidth; - //double fOneWidth = 1.0; - //if(fZoomX >= (1.0 - 1E-5)) fOneWidth = double(dGirdWidth*fZoomX+.5); - //else fOneWidth = double(dGirdWidth+.5); - - QPen oldPen = paint->pen(); - paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); - QFont OldFont = paint->font(); - paint->setFont(m_TinyFont); - - Qt::BGMode oldMode = paint->backgroundMode(); - paint-> setBackgroundMode(Qt::TransparentMode); - -// QRect ClientRect = GetValidRect(); -// int nLeft = qMax(ClientRect.left(), nLeftMargin - m_nScrollLeft); -// int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin - m_nScrollLeft); - - for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) - { - int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk)+nLeftMargin; - int nBlockRight = m_pWaveFile->GetBlockRight(nBlk)+nLeftMargin; - //fOneWidth = 1.0; - // 画小格线 - int nGridAmt = int(double(nBlockRight-nBlockLeft)/fOneWidth+.5)+1; - - int nTick = 0; - for( nTick=0; nTick nBlockRight) break; - paint->drawLine(nX - m_nScrollLeft, 0,nX - m_nScrollLeft, nHeight); - } - - // 起始点,中止点 - int nHeight = 12; - paint->drawLine(nBlockLeft - m_nScrollLeft, 0,nBlockLeft - m_nScrollLeft, nHeight*2); - - paint->drawLine(nBlockRight - m_nScrollLeft, 0,nBlockRight - m_nScrollLeft, nHeight*2); - - // 画起始,中止时间 - // - paint->setFont(m_LittleFont); - QBrush oldBrush = paint->brush(); - paint->setBrush( m_TextBrush ); - QRect rcPoint(nBlockLeft - m_nScrollLeft, 18 , TEXT_WIDTH , TEXT_WIDTH); - QString sComment; - long lTime = m_pWaveFile->GetBlockBeginTime(nBlk); - if (lTime < 0) sComment.sprintf("-%ld", -1*lTime); - else if((lTime < 1000)&&(lTime >= 0)) sComment.sprintf("%ld", lTime); - else sComment.sprintf("%ld\"%03ld", lTime/1000L, lTime%1000L); - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - - if(nBlk == m_pWaveFile->m_nNRates-1) - { - rcPoint.setX(nBlockRight - m_nScrollLeft); - rcPoint.setY(13); - long lTime = m_pWaveFile->GetBlockEndTime(nBlk); - if (lTime < 0) sComment.sprintf("-%ld", -1*lTime); - else if((lTime < 1000)&&(lTime >= 0)) sComment.sprintf("%ld", lTime); - else sComment.sprintf("%ld\"%03ld", lTime/1000L, lTime%1000L); - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - } - - - //找出中格的点数和大格的点数 - // (每5ms), - // 如间距 < 10*GRID_WIDTH, (每20ms) - // 如间距 < 10*GRID_WIDTH, (每50ms) - // 如间距 < 10*GRID_WIDTH, (每100ms) - // 如间距 < 10*GRID_WIDTH, (每200ms) - // 如间距 < 10*GRID_WIDTH, (每500ms) - // 如间距 < 10*GRID_WIDTH, (每1000ms) - - double dGridArr[7] = {0.005, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0 }; - double dMidGridWidth = dGirdWidth*1.0;//中格 - double dBigGridWidth = dGirdWidth*10.0; - int nUnit = 0; - if( m_pWaveFile->m_dSampleRate[nBlk]<=50.0 ) - nUnit = 3; - - for(int i=nUnit; i<7; i++) - { - dBigGridWidth = m_pWaveFile->m_dSampleRate[nBlk]*dGridArr[i]*dGirdWidth*fZoomX; - if(dBigGridWidth >=10.0*dGirdWidth) - break; - dMidGridWidth = dBigGridWidth; - } - //画中格线 - int nGrid = int(.5+dMidGridWidth/fOneWidth); - if(nGrid>1) - { - for(nTick=1; nTick<(nGridAmt/nGrid)+1; nTick++) - { - int nHeight = 10; - int nX = nBlockLeft + int(.5+nTick*fOneWidth*double(nGrid)); - if(nX + dGirdWidth*5.0 > nBlockRight) break; - paint->drawLine(nX - m_nScrollLeft, 0,nX - m_nScrollLeft, nHeight); - } - } - - //画大格线(带刻度) - nGrid = int(.5+dBigGridWidth/fOneWidth); - if(nGrid<1) nGrid = 1; - for(nTick=1; nTick<(nGridAmt/nGrid)+1; nTick++) - { - int nHeight = 12; - int nX = nBlockLeft + int(.5+nTick*fOneWidth*double(nGrid)); - if(nX + dGirdWidth*5.0 > nBlockRight) break; - paint->drawLine(nX - m_nScrollLeft, 0,nX - m_nScrollLeft, nHeight); - - paint->setBrush( m_TextBrush ); - rcPoint = QRect(nX - m_nScrollLeft - 5, 18 , TEXT_WIDTH, TEXT_WIDTH); - QString sComment; - long lTime = long(.5+m_pWaveFile->GetXPositionTime(nX-nLeftMargin)); - if(lTime < 0) lTime = long(-0.5+m_pWaveFile->GetXPositionTime(nX-nLeftMargin)); - if (lTime < 0) sComment.sprintf("-%ld", -1*lTime); - else if((lTime < 1000)&&(lTime >= 0)) sComment.sprintf("%ld", lTime); - else sComment.sprintf("%ld\"%03ld", lTime/1000L, lTime%1000L); - paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); - - } - paint->setBrush(oldBrush); - } - - QPoint rcText(nLeftMargin - m_nScrollLeft - 10, 15); - - - QFont font = QApplication::font(); - font.setPointSize(OldFont.pointSize()); - paint->setFont(font); - QString sComment = tr("Timestamp");//时标 - paint->drawText(rcText,sComment); - - paint->setBackgroundMode(oldMode); - - - paint->setFont(OldFont); - paint->setPen(oldPen); -} - -void CTimeAxisShow::drawBaseLine(QPainter * paint,const QColor& clr) -{ - if(!m_pWaveFile) return; - int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; - nLeftMargin = 0; - - int XPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fBaseTick ); - - if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) - XPosition = m_pWaveFile->GetMaxWidth(); - - XPosition -= m_nScrollLeft; - XPosition += nLeftMargin; - -// m_pTimeSlider->SetPosition1(XPosition); - - QRect ClientRect = GetValidRect(); - if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) - { - LCyanPen.setColor(clr); - QPen oldPen = paint->pen(); - paint->setPen(clr); - paint->setBrush( QColor(0,123,247) ); - paint->drawLine(XPosition,0,XPosition,8/*ClientRect.bottom()*/); - QRect rcText(XPosition-5,8/*20*/,12,12); - paint->drawText(rcText,Qt::AlignCenter | Qt::AlignVCenter,"B"); - paint->setPen(oldPen); - } -} - -//画竖线 -void CTimeAxisShow::drawStaticLine(QPainter * paint,const QColor& clr) -{ - if(!m_pWaveFile) return; - int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; - nLeftMargin = 0; - - int XPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fStaticTick ); - if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) - XPosition = m_pWaveFile->GetMaxWidth(); - - XPosition -= m_nScrollLeft; - XPosition += nLeftMargin; - -// m_pTimeSlider->SetPosition2(XPosition); - - QRect ClientRect = GetValidRect(); - if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) - { - LCyanPen.setColor(clr); - QPen oldPen = paint->pen(); - paint->setPen(LCyanPen); - - paint->drawLine(XPosition,0,XPosition,8/*ClientRect.bottom()*/); - QRect rcText(XPosition-5,8/*20*/,12,12); - paint->drawText(rcText,Qt::AlignCenter | Qt::AlignVCenter,"C"); - paint->setPen(oldPen); - } -} - -//画竖线 -void CTimeAxisShow::drawUpDownLine(QPainter * paint, double fLineTick, const QColor& clr) -{ - if(!m_pWaveFile) return; - int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; - nLeftMargin = 0; - - int XPosition = m_pWaveFile->GetPointPosition(fLineTick); - if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) - XPosition = m_pWaveFile->GetMaxWidth(); - - XPosition -= m_nScrollLeft; - XPosition += nLeftMargin; - - QRect ClientRect = GetValidRect(); - if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) - { - LCyanPen.setColor(clr); - QPen oldPen = paint->pen(); - paint->setPen(LCyanPen); - - paint->drawLine(XPosition,0,XPosition,ClientRect.bottom()); - - paint->setPen(oldPen); - } -} - -void CTimeAxisShow::drawCursor(QPainter* paint) -{ - if(m_nCursorX > 0) - { - QRect rcRect = GetValidRect(); - - QPainter::CompositionMode OldRop2 = paint->compositionMode(); - paint->setCompositionMode(QPainter::CompositionMode_Xor); - QPen oldPen = paint->pen(); - //paint->setPen(BluePen); - paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); - - paint->drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); - - paint->setPen(oldPen); - paint->setCompositionMode(OldRop2); - } -} - -QRect CTimeAxisShow::GetValidRect() -{ - QRect rcRect = rect(); - rcRect.setBottom( rcRect.bottom() - SILIDER_HEIGHT ); - return rcRect; -} - -void CTimeAxisShow::GetTimeMargin(QRect &rect) -{ - if(!m_pWaveFile) return; - - int nMaxWidth = m_pWaveFile->GetMaxWidth(); - rect = QRect(0,0,nMaxWidth,TIMEAXIS_HEIGHT); -} -//////////////////////////////////////////////////////////////////////// -//##ModelId=4039BEDE0118 -bool CTimeAxisShow::SetComtradeData(CComtradeFile& pComtradeData) -{ - m_pWaveFile = &pComtradeData; - - ResetHScrollSize(); - - update(); - - return true; -} - -CWaveShow* CTimeAxisShow::GetParent() -{ - return (CWaveShow*)parent(); -} - -void CTimeAxisShow::HoriztalScrollBarMove(int value) -{ - GetParent()->HTimeScroll(value); -} - -void CTimeAxisShow::ResetHScrollSize() -{ - int nMaxWidth = m_pWaveFile->GetMaxWidth(); -// int nTemp = QApplication::desktop()->size().width(); -// horiz_bar->setRange(0,nMaxWidth - nTemp + GetParent()->m_nLeftMargin + 50); - horiz_bar->setRange(0,nMaxWidth - rect().width() + 50); -// horiz_bar->setRange(0,nMaxWidth - nTemp); -} - -void CTimeAxisShow::HScroll(int value) -{ - //horiz_bar->setValue(value); - //m_nScrollLeft = horiz_bar->value(); - m_nScrollLeft = value ; - update(); -} - -int CTimeAxisShow::GetHScroll() -{ - return horiz_bar->value(); -} - -void CTimeAxisShow::OnSliderMove( int no,int pos ) -{ - int nPosX; - int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; - nLeftMargin = 0; - nPosX = pos - nLeftMargin; - - if(nPosX < 0) nPosX = 0; - - int nAbsXPos = nPosX + m_nScrollLeft; - if(nAbsXPos < 0) nAbsXPos = 0; - if(nAbsXPos > m_pWaveFile->GetMaxWidth()) - nAbsXPos = m_pWaveFile->GetMaxWidth(); - - double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; - double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); - - switch( no ) - { - case 1: - { - m_pWaveFile->m_DispAttr.m_fBaseTime = RTime; - m_pWaveFile->m_DispAttr.m_fBaseTick = dTick; - m_pWaveFile->EmitLineBChanged(); - } - break; - case 2: - { - m_pWaveFile->m_DispAttr.m_fStaticTime = RTime; - m_pWaveFile->m_DispAttr.m_fStaticTick = dTick; - m_pWaveFile->EmitLineCChanged(); - } - break; - default: - break; - } - GetParent()->update(); - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(4,false); - GetParent()->redrawWindow(1,false);//名称区显示数据值 - update(); - -} - -void CTimeAxisShow::doMouseMove( QMouseEvent *e) -{ - //{{处理移动 -// m_pTimeSlider->DoMouseMove(e); - //}} - - if(e->x() < 0) return; - -// QRect rcRect = GetValidRect(); - -// QPainter paint(this); -// QPainter::CompositionMode OldRop2 = paint.compositionMode(); -// paint.setCompositionMode(QPainter::CompositionMode_Xor); - -// paint.setCompositionMode(QPainter::CompositionMode_SourceOver); -// QPen oldPen = paint.pen(); -// paint.setPen(BluePen); - // -// if(m_nCursorX > 0) -// paint.drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); -// m_nCursorX = e->x(); -// paint.drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); -// -// m_nCursorX = e->x(); -// -// if(CWaveEnv::GetInst()->m_bCruise&&m_nCursorX>=(rcRect.right() - 30)) -// { -// m_nScrollLeft += SCROLLBAR_H_LINE; -// GetParent()->HTimeScroll(m_nScrollLeft); -// } -// else if(CWaveEnv::GetInst()->m_bCruise&&m_nCursorX<=(rcRect.left() + GetParent()->m_nLeftMargin + 30)) -// { -// m_nScrollLeft -= SCROLLBAR_H_LINE; -// if(m_nScrollLeft<0) -// m_nScrollLeft = 0; -// GetParent()->HTimeScroll(m_nScrollLeft); -// } -// -// paint.setPen(oldPen); - //paint.setCompositionMode(OldRop2); -} - -void CTimeAxisShow::doMousePress( QMouseEvent *e ) -{ - //{{处理移动 -// if( m_SliderBar.contains( e->pos() ) ) -// { -// m_pTimeSlider->DoMousePress(e); -// return; -// } - //}} - - int nPosX; - int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; - nLeftMargin = SPLITTERWIDTH; - nPosX = e->x() - nLeftMargin; - - if(nPosX < 0) nPosX = 0; - - int nAbsXPos = nPosX + m_nScrollLeft; - if(nAbsXPos < 0) nAbsXPos = 0; - if(nAbsXPos > m_pWaveFile->GetMaxWidth()) - nAbsXPos = m_pWaveFile->GetMaxWidth(); - - double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; - double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); - - if(e->button() == Qt::LeftButton) - { - m_pWaveFile->m_DispAttr.m_fStaticTime = RTime; - m_pWaveFile->m_DispAttr.m_fStaticTick = dTick; - m_pWaveFile->EmitLineCChanged(); - } - else if(e->button() == Qt::RightButton) - { - m_pWaveFile->m_DispAttr.m_fBaseTime = RTime; - m_pWaveFile->m_DispAttr.m_fBaseTick = dTick; - m_pWaveFile->EmitLineBChanged(); - } - - -} - -void CTimeAxisShow::doMouseRelease( QMouseEvent *e ) -{ - Q_UNUSED(e) - //{{处理移动 -// m_pTimeSlider->DoMouseRelease(e); - //}} - - -} - -void CTimeAxisShow::wheelEvent(QWheelEvent *e) -{ - if(e->delta() > 0) - m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; - else - m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; - - if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; - if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; - - ResetHScrollSize(); - - GetParent()->redrawWindow(2,false); - GetParent()->redrawWindow(4,false); - GetParent()->redrawWindow(5,false); -} +#include "CTimeAxisShow.h" +#include +#include +#include +#include +#include +#include +#include +#include "CPublic.h" +#include "CComDataClass.h" +#include +#include +#include +#include +#include "CWaveShow.h" +const int TEXT_WIDTH = 50; +const int GRID_WIDTH = 2; + +CTimeSlider::CTimeSlider( QWidget *parent ) +:QObject(parent),m_pParent(parent) +{ + m_Palette.setColor( QPalette::Foreground, QColor( 0, 170, 127) ); + m_Palette.setColor( QPalette::Button, QColor( 236, 233, 216) ); + m_Palette.setColor( QPalette::Light, Qt::white ); + m_Palette.setColor( QPalette::Midlight, QColor( 241, 239, 226) ); + m_Palette.setColor( QPalette::Dark, QColor( 172, 168, 153) ); + m_Palette.setColor( QPalette::Mid, QColor( 157, 155, 143) ); + m_Palette.setColor( QPalette::Text, Qt::black ); + m_Palette.setColor( QPalette::BrightText, Qt::white ); + m_Palette.setColor( QPalette::ButtonText, Qt::black ); + m_Palette.setColor( QPalette::Base, Qt::white ); + m_Palette.setColor( QPalette::Background, Qt::white ); + m_Palette.setColor( QPalette::Shadow, QColor( 113, 111, 100) ); + m_Palette.setColor( QPalette::Highlight, QColor( 49, 106, 197) ); + m_Palette.setColor( QPalette::HighlightedText, Qt::white ); + m_Palette.setColor( QPalette::Link, QColor( 0, 0, 255) ); + m_Palette.setColor( QPalette::LinkVisited, QColor( 255, 0, 255) ); + + m_bMoveBaseBar1 = false; + m_bMoveBaseBar2 = false; + + m_bEnablePos1 = true; + m_bEnablePos2 = true; +} + +CTimeSlider::~CTimeSlider() +{ + +} + +void CTimeSlider::Draw( QPainter *paint ) +{ + paint->setPen(Qt::blue); + qDrawShadePanel(paint,m_rcGeometry,m_Palette,true); + if( m_bEnablePos1 ) + { + paint->drawText(m_rcBar1,Qt::AlignCenter,"B"); + qDrawShadePanel(paint,m_rcBar1,m_Palette); + } + if(m_bEnablePos2) + { + paint->drawText(m_rcBar2,Qt::AlignCenter,"C"); + qDrawShadePanel(paint,m_rcBar2,m_Palette); + } + + if( m_bMoveBaseBar1 ) + DrawMoveBar(paint,1,m_nLastXPos); + if( m_bMoveBaseBar2 ) + DrawMoveBar(paint,2,m_nLastXPos); +} + +//******************************************************************** +// 画BaseBar的移动线 +//******************************************************************** +void CTimeSlider::DrawMoveBar( QPainter* paint,int nNo,int nPos ) +{ + if(1==nNo) + { + paint->setPen( m_Palette.color( QPalette::Background ) ); + paint->setBrush( m_Palette.color( QPalette::Foreground ) ); + QRect rcRect = m_rcBar1; + rcRect.setLeft( nPos -SILIDER_HEIGHT/2); + rcRect.setWidth(SILIDER_HEIGHT); + paint->drawText(rcRect,Qt::AlignCenter,"B"); + qDrawShadePanel(paint,rcRect,m_Palette); + } + else if(2==nNo) + { + paint->setPen( m_Palette.color( QPalette::Background ) ); + paint->setBrush( m_Palette.color( QPalette::Foreground ) ); + QRect rcRect = m_rcBar2; + rcRect.setLeft( nPos -SILIDER_HEIGHT/2); + rcRect.setWidth(SILIDER_HEIGHT); + paint->drawText(rcRect,Qt::AlignCenter,"C"); + qDrawShadePanel(paint,rcRect,m_Palette); + } +} + +void CTimeSlider::SetPosition1( int nPos1 ) +{ + m_nPos1 = nPos1; + + m_rcBar1 = m_rcGeometry; + m_rcBar1.setLeft( nPos1 -SILIDER_HEIGHT/2 ); + m_rcBar1.setWidth(SILIDER_HEIGHT); +} + +void CTimeSlider::SetPosition2( int nPos2 ) +{ + m_nPos2 = nPos2; + m_rcBar2 = m_rcGeometry; + m_rcBar2.setLeft( nPos2 - SILIDER_HEIGHT/2 ); + m_rcBar2.setWidth(SILIDER_HEIGHT); +} + +void CTimeSlider::SetEnablePso1( bool bEnable ) +{ + m_bEnablePos1 = bEnable; +} + +void CTimeSlider::SetEnablePso2( bool bEnable ) +{ + m_bEnablePos2 = bEnable; +} + +void CTimeSlider::SetGeometry( const QRect& geom ) +{ + m_rcGeometry = geom; +} + +void CTimeSlider::DoMousePress(QMouseEvent *e) +{ + //{{处理移动 + if( e->button() == Qt::LeftButton ) + { + QPoint pt = e->pos(); + if(m_rcBar1.contains(pt)) + { + m_bMoveBaseBar1 = true; + m_bMoveBaseBar2 = false; + m_nLastXPos = e->x(); + return; + } + + if(m_rcBar2.contains(pt)) + { + m_bMoveBaseBar1 = false; + m_bMoveBaseBar2 = true; + m_nLastXPos = e->x(); + return; + } + } + //}} +} + +void CTimeSlider::DoMouseMove(QMouseEvent *e) +{ + //{{处理移动 + if( e->buttons() & Qt::LeftButton ) + { + if( m_bMoveBaseBar1 ) + { + m_nLastXPos = e->x(); + return; + } + if( m_bMoveBaseBar2 ) + { + m_nLastXPos = e->x(); + return; + } + } + //}} +} + +void CTimeSlider::DoMouseRelease(QMouseEvent *e) +{ + //{{处理移动 + if( e->button() == Qt::LeftButton ) + { + if( m_bMoveBaseBar1 ) + { + m_bMoveBaseBar1 = false; + m_bMoveBaseBar2 = false; + emit OnChange(1,m_nLastXPos); + } + else if( m_bMoveBaseBar2 ) + { + m_bMoveBaseBar1 = false; + m_bMoveBaseBar2 = false; + emit OnChange(2,m_nLastXPos); + } + } + //}} +} + +////////////////////////////////////////////////////////////////////////// +CVerticalSlider::CVerticalSlider( QWidget *parent ) +:QObject(parent),m_pParent(parent) +{ + m_Palette.setColor( QPalette::Foreground, QColor( 0, 170, 127) ); + m_Palette.setColor( QPalette::Button, QColor( 236, 233, 216) ); + m_Palette.setColor( QPalette::Light, Qt::white ); + m_Palette.setColor( QPalette::Midlight, QColor( 241, 239, 226) ); + m_Palette.setColor( QPalette::Dark, QColor( 172, 168, 153) ); + m_Palette.setColor( QPalette::Mid, QColor( 157, 155, 143) ); + m_Palette.setColor( QPalette::Text, Qt::white ); + m_Palette.setColor( QPalette::BrightText, Qt::white ); + m_Palette.setColor( QPalette::ButtonText, Qt::black ); + m_Palette.setColor( QPalette::Base, Qt::blue ); + m_Palette.setColor( QPalette::Background, Qt::white ); + m_Palette.setColor( QPalette::Shadow, QColor( 113, 111, 100) ); + m_Palette.setColor( QPalette::Highlight, QColor( 49, 106, 197) ); + m_Palette.setColor( QPalette::HighlightedText, Qt::white ); + m_Palette.setColor( QPalette::Link, QColor( 0, 0, 255) ); + m_Palette.setColor( QPalette::LinkVisited, QColor( 255, 0, 255) ); + + m_bMoveBaseBar = false; + SetPosition(0); +} + +CVerticalSlider::~CVerticalSlider() +{ + +} + +void CVerticalSlider::Draw( QPainter *paint ) +{ + paint->setPen( Qt::blue ); + qDrawShadePanel(paint,m_rcGeometry,m_Palette,true); + paint->drawText(m_rcBar,Qt::AlignCenter,"P"); + qDrawShadePanel(paint,m_rcBar,m_Palette); + + if( m_bMoveBaseBar ) + DrawMoveBar(paint,m_nLastXPos); + +} + +//******************************************************************** +// 画BaseBar的移动线 +//******************************************************************** +void CVerticalSlider::DrawMoveBar( QPainter *paint,int nPos ) +{ +// QPainter paint( m_pParent ); + paint->setPen( m_Palette.color( QPalette::Background ) ); + paint->setBrush( m_Palette.color( QPalette::Foreground ) ); + paint->setCompositionMode( QPainter::CompositionMode_Xor ); + QRect rcRect = m_rcBar; + rcRect.setTop( nPos -SILIDER_HEIGHT/2); + rcRect.setHeight(SILIDER_HEIGHT); + paint->drawText(rcRect,Qt::AlignCenter,"P"); + qDrawShadePanel(paint,rcRect,m_Palette); +} + +void CVerticalSlider::SetPosition( int nPos ) +{ + m_nPos = nPos; + + m_rcBar = m_rcGeometry; + m_rcBar.setTop( nPos -SILIDER_HEIGHT/2 ); + m_rcBar.setHeight(SILIDER_HEIGHT); +} + +void CVerticalSlider::SetGeometry( const QRect& geom ) +{ + m_rcGeometry = geom; + SetPosition( m_nPos ); +} + +void CVerticalSlider::DoMousePress(QMouseEvent *e) +{ + //{{处理移动 + if( e->button() == Qt::LeftButton ) + { + QPoint pt = e->pos(); + if(m_rcBar.contains(pt)) + { + m_bMoveBaseBar = true; + m_nLastXPos = e->y(); + return; + } + } + //}} +} + +void CVerticalSlider::DoMouseMove(QMouseEvent *e) +{ + //{{处理移动 + if( e->buttons() & Qt::LeftButton ) + { + if( m_bMoveBaseBar ) + { + m_nLastXPos = e->y(); + return; + } + } + //}} +} + +void CVerticalSlider::DoMouseRelease(QMouseEvent *e) +{ + //{{处理移动 + if( e->button() == Qt::LeftButton ) + { + if( m_bMoveBaseBar ) + { + m_nLastXPos = e->y(); + m_bMoveBaseBar = false; + SetPosition( m_nLastXPos ); + emit OnChange(m_nLastXPos); + } + } + //}} +} +///////////////////////////////////////////////////// +CTimeAxisShow::CTimeAxisShow(QWidget *parent,QScrollBar* horscrl, Qt::WindowFlags f ) + :QWidget(parent,f),horiz_bar(horscrl) +{ +// setAttribute(Qt::WA_PaintOutsidePaintEvent); + + setWindowFlag( Qt::WindowStaysOnTopHint ); + setMouseTracking(true); + + QVBoxLayout* vboxLayout = new QVBoxLayout(this); + vboxLayout->setSpacing(0); + vboxLayout->setContentsMargins(0, 0, 0, 0); + QSpacerItem* spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); + horiz_bar = new QScrollBar(Qt::Horizontal,this); + vboxLayout->addItem(spacerItem); + vboxLayout->addWidget( horiz_bar ); + horiz_bar->setRange(0,500); + horiz_bar->setSingleStep(SCROLLBAR_H_LINE); + horiz_bar->setPageStep(SCROLLBAR_H_LINE*5); + horiz_bar->setTracking(false); + horiz_bar->setCursor(GetParent()->m_hHandCursor); + + connect(horiz_bar,SIGNAL(valueChanged(int)),this,SLOT(HoriztalScrollBarMove(int))); + connect(horiz_bar,SIGNAL(sliderMoved(int)),this,SLOT(HoriztalScrollBarMove(int))); + +// m_pTimeSlider = new CTimeSlider(this); +// connect(m_pTimeSlider,SIGNAL(OnChange(int,int)),this,SLOT(OnSliderMove(int,int))); + +// setAutoFillBackground(true); + + DGrayPen = QPen(DGRAY_COLOR,1,Qt::SolidLine); + BluePen = QPen(BLUE_COLOR,1,Qt::SolidLine); + RedPen = QPen(RED_COLOR,1,Qt::SolidLine); + WhitePen = QPen(WHITE_COLOR,1,Qt::SolidLine); + DRedPen = QPen(DRED_COLOR,1,Qt::SolidLine); + LLGrayPen = QPen(LLGRAY_COLOR,1,Qt::SolidLine); + LCyanPen = QPen(LCYAN_COLOR,1,Qt::SolidLine); + m_TinyFont = QFont("Arial",10); + m_LittleFont = QFont("Arial",10); + m_TextBrush.setColor(QColor(0,0,224)); + + m_nCursorX = -1; + m_nScrollLeft = 0; + + m_pWaveFile = 0; + + + + setCursor(GetParent()->m_hCrossCursor); +} + +CTimeAxisShow::~CTimeAxisShow() +{ + +} + +////////////////////////////////////////////////////////////////////////// +void CTimeAxisShow::OnMousePressEvent( QMouseEvent *e ) +{ + doMousePress( e ); + update(); + //GetParent()->update(); + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(4,false); + GetParent()->redrawWindow(1,false);//在名称区显示数据值,20090818 + GetParent()->redrawWindow(7,false); + GetParent()->showStatus(); +// if( GetParent()->m_pStatusView ) +// GetParent()->m_pStatusView->Refresh(); + QWidget::mousePressEvent( e ); +} + +void CTimeAxisShow::OnMouseReleaseEvent( QMouseEvent *e ) +{ + doMouseRelease( e ); + QWidget::mouseReleaseEvent( e ); +} + +void CTimeAxisShow::OnMouseMoveEvent( QMouseEvent *e ) +{ + if(GetParent()) + { +// setCursor( GetParent()->m_hArrowCursor ); + doMouseMove(e); + +// int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; +// QPoint pt(e->x() - nLeftMargin,e->y()); +// QMouseEvent event(QEvent::MouseMove,pt,e->button(),e->buttons(),e->modifiers()); +// +// CDigitalShow *pDgtView = GetParent()->m_pDigitalView; +// if(pDgtView) pDgtView->doMouseMove( &event ); +// +// CAnalogueShow *pAnaView = GetParent()->m_pAnalogueView; +// if(pAnaView) pAnaView->doMouseMove( &event ); + +// GetParent()->redrawWindow(2,false); +// GetParent()->redrawWindow(4,false); + update(); + } +// QWidget::mouseMoveEvent( e ); +} + +void CTimeAxisShow::paintEvent( QPaintEvent *e ) +{ + Q_UNUSED(e) + QPainter paint; + paint.begin(this ); + //paint.setBrush(palette().color( QPalette::Foreground )); + draw( &paint ); + paint.end(); +} + +void CTimeAxisShow::draw( QPainter *paint) +{ + if(!m_pWaveFile) return; + + m_SliderBar = rect(); + m_SliderBar.setTop( m_SliderBar.bottom() - SILIDER_HEIGHT ); +// m_pTimeSlider->SetGeometry( m_SliderBar ); + + drawBackGnd(paint); + drawTimeAxisB(paint); + if(CWaveEnv::GetInst()->m_bShowBaseLine )//基准线 + drawBaseLine(paint,CWaveEnv::GetInst()->m_BaseLineColor); + + if(CWaveEnv::GetInst()->m_bShowTriggerLine) + drawUpDownLine(paint,m_pWaveFile->m_DispAttr.m_fTriggerTick,RED_COLOR);//游标线 + + drawStaticLine(paint,CWaveEnv::GetInst()->m_StaticLineColor);//当前时标线 + drawCursor(paint); +// m_pTimeSlider->Draw(paint); +} + +//下边打印 +void CTimeAxisShow::PrintB( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,bool bUpper) +{ + Q_UNUSED(bColor) + if(!m_pWaveFile) return; + + int nLeftMargin = 0; + int nMaxWidth = m_pWaveFile->GetMaxWidth(); + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; +// double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; + + QRect ClientRect = rect; + QPen oldPen = paint->pen(); + QBrush oldBrush = paint->brush(); + QFont OldFont = paint->font(); + + paint->setPen(DRedPen); + + QFont textFont("Arial"); + textFont.setPixelSize(9); + + paint->setFont( textFont ); + paint->setBrush( m_TextBrush ); + + int nLeft = qMax(ClientRect.left(), nLeftMargin); + int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin); + + int nTipStart,nTipEnd; + if(!bUpper){ + nTipStart = 0;nTipEnd = TIPS_HEIGHT;} + else{ + nTipStart = TIMEAXIS_HEIGHT -1;nTipEnd = TIMEAXIS_HEIGHT - TIPS_HEIGHT;} + + paint->drawLine(QPoint(nLeft,nTipStart) + ptOffset,QPoint(nRight,nTipStart) + ptOffset); + + QRect rcPoint; + int m_nZoomX = int(128.0*fZoomX); + // 画标线 + if(m_nZoomX >= 128) + { + double nOneWidth = GRID_WIDTH*fZoomX; + int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); + + int Tick1 = (ClientRect.left() - nLeftMargin - 51) / nOneWidth - 1; + int Tick2 = (ClientRect.right() - nLeftMargin + 51) / nOneWidth + 1; + if(Tick1 < 0) Tick1 = 0; + if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; + + // 小格线 每点 + // 中格线, 每100毫秒, 每5ms + // 大格线, 每500秒, 块的起始点, 每20ms + // 写文字, 块的起始点, 500ms, 20ms + for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) + { + int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; + // 如每格20ms 或 > 20ms + int TB1 = m_pWaveFile->GetStartTick(TR); + int TB2 = TB1 + nGridAmt; + int T1, T2; + if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); + if(TB2 ClientRect.right() ) + break; + + // 小格线 + + if( (int)(ii*nOneWidth)%(int)(GRID_WIDTH) == 0 ) + { + paint->drawLine( nTickPos + ptOffset.x(), nTipStart + ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd + ptOffset.y()); + } + + // 起始点,最后一块的中止点 + bool bDrawText = false; + qlonglong time = m_pWaveFile->m_aTimeArray[ii]; + long TimeDrawn = 0; + if( (ii==TB1)||(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1) ) + { + // 起始点 + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + paint->drawLine(nTickPos + ptOffset.x()+1, nTipStart+ptOffset.y(),nTickPos + ptOffset.x()+1, nTipEnd+ ptOffset.y()); + + bDrawText = true; + TimeDrawn = (time/1000L); + paint->setPen( QColor( 0,0,224 ) ); + } + else + { + if(m_pWaveFile->m_dSampleRate[TR] <= 50) + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 100ms点 + if((time1 % 100000L) >= (time % 100000L)) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + } + // 500ms点 + if((time1 % 500000L) >= (time % 500000L)) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + + if(abs(ii-TB1)>10 && abs(ii-TB2)>10) + { + TimeDrawn = (time/500000L)*500; + paint->setPen( QColor( 0,0,64 ) ); + bDrawText = true; + } + } + } + else + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 5ms点 + if((time1 % 5000L) >= (time % 5000L)) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + } + // 20ms点 + if((time1 % 20000L) >= (time % 20000L)) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + + if(abs(ii-TB1)>10 && abs(ii-TB2)>10) + { + TimeDrawn = (time/20000L)*20; + paint->setPen( QColor( 0,0,64 ) ); + bDrawText = true; + } + } + } + } + + if(bDrawText) + { + TimeDrawn = time/1000L; + TimeDrawn += m_pWaveFile->m_nFrist_ms; + + rcPoint = QRect(nTickPos + ptOffset.x() - 10, 8 + ptOffset.y() ,TEXT_WIDTH, TEXT_WIDTH); + + QString sComment; + if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); + else sComment.sprintf("%ld,%03ld", TimeDrawn/1000L, TimeDrawn%1000L); + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + paint->setPen(QColor(0,0,64)); + } + } + } + } + + if(m_nZoomX<=64 && m_nZoomX>0) + { + int n = 1.0/fZoomX; + if(n <= 0) n = 1; + + int nOneWidth = GRID_WIDTH; + int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); + + int Tick1 = ((ClientRect.left()- nLeftMargin - 51) / nOneWidth - 1)* n; + int Tick2 = ((ClientRect.right() - nLeftMargin + 51) / nOneWidth + 1)* n; + + if(Tick1 < 0) Tick1 = 0; + if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; + + // 小格线 每100ms, 5ms, + // 中格线, 每500ms, 每20ms + // 大格线, 块的起始点, n*500ms, n*20ms + // 写文字, 块的起始点, n*500ms, n*20ms + for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) + { + int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; + // 如每格20ms 或 > 20ms + int TB1 = m_pWaveFile->GetStartTick(TR); + int TB2 = TB1 + nGridAmt; + int T1, T2; + if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); + if(TB2 ClientRect.right() ) + break; + + bool bDrawText = false; + int time = m_pWaveFile->m_aTimeArray[ii]; + long TimeDrawn = 0; + if((ii==TB1)||(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1)) + { + // 起始点 + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + paint->drawLine(nTickPos + ptOffset.x()+1, nTipStart+ptOffset.y(),nTickPos + ptOffset.x()+1, nTipEnd+ ptOffset.y()); + + bDrawText = true; + TimeDrawn = (time/1000L); + paint->setPen(QColor(0,0,224)); + } + else + { + if(m_pWaveFile->m_dSampleRate[TR] <= 50) + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 100ms点 + if((time1 % 100000L) >= (time % 100000L)) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + } + + // 500ms点 + if((time1 % 500000L) >= (time % 500000L)) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + } + // n*500ms点 + if((time1 % (500000L*n)) >= (time % (500000L*n))) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + + + if(abs(ii-TB1)>10*n && abs(ii-TB2)>10*n) + { + TimeDrawn = (time/500000L)*500; + paint->setPen(QColor(0,0,64)); + bDrawText = true; + } + } + } + else + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 5ms点 + if((time1 % 5000L) >= (time % 5000L)) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + } + if((time1 % 20000L) >= (time % 20000L)) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + } + if((time1 % (20000L*n)) >= (time % (20000L*n))) + { + paint->drawLine(nTickPos + ptOffset.x(), nTipStart+ptOffset.y(),nTickPos + ptOffset.x(), nTipEnd+ ptOffset.y() ); + + if(abs(ii-TB1)>10*n && abs(ii-TB2)>10*n) + { + TimeDrawn = (time/20000L)*20; + paint->setPen(QColor(0,0,64)); + bDrawText = true; + } + } + } + } + if(bDrawText) + { + TimeDrawn = time/1000L; + TimeDrawn += m_pWaveFile->m_nFrist_ms; + + rcPoint = QRect(nTickPos + ptOffset.x() - 5, 8+ptOffset.y() , TEXT_WIDTH, TEXT_WIDTH); + + QString sComment; + if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); + else sComment.sprintf("%ld,%03ld", TimeDrawn/1000L, TimeDrawn%1000L); + //GetTimeString(MsString,TimeDrawn); + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + paint->setPen(QColor(0,0,64)); + } + } + } + } + + paint->setFont(OldFont); + paint->setPen(oldPen); +} + +void CTimeAxisShow::Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,bool bUpper) +{ + Q_UNUSED(bColor) + if(!m_pWaveFile) return; + + QFont ptFont = QFont("Arial",9); + int nLeftMargin = 0; + int nMaxWidth = m_pWaveFile->GetMaxWidth(); + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; + + QPen oldPen = paint->pen(); + + QRect ClientRect = rect; + QBrush oldBrush = paint->brush(); + + paint->setPen(DRedPen); + QFont OldFont = paint->font(); + paint->setFont( ptFont ); + int nStyle = Qt::AlignLeft |Qt::AlignTop | Qt::TextSingleLine; + if(bUpper) + nStyle = Qt::AlignLeft |Qt::AlignBottom | Qt::TextSingleLine; + + int nLeft = qMax(ClientRect.left(), nLeftMargin); + int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin); + + int nTipStart,nTipEnd; + if(!bUpper){ + nTipStart = 0;nTipEnd = TIPS_HEIGHT;} + else{ + nTipStart = TIMEAXIS_HEIGHT -1;nTipEnd = TIMEAXIS_HEIGHT - TIPS_HEIGHT;} + + paint->drawLine(QPoint(nLeft,nTipStart) + ptOffset,QPoint(nRight,nTipStart) + ptOffset); + + for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) + { + int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk)+nLeftMargin; + int nBlockRight = m_pWaveFile->GetBlockRight(nBlk)+nLeftMargin; + + // 画小格线 + double fOneWidth = int(dGirdWidth*(fZoomX)+.5); + if(fOneWidth < dGirdWidth) + fOneWidth = dGirdWidth; + + int nGridAmt = int(double(nBlockRight-nBlockLeft)/fOneWidth+.5)+1; + + // 起始点,中止点 + + if(nBlockLeft>=ClientRect.left()&&nBlockLeft<=ClientRect.right()){ + paint->drawLine(nBlockLeft + ptOffset.x(), nTipStart + ptOffset.y(),nBlockLeft + ptOffset.x(), nTipEnd + ptOffset.y()); + } + + if(nBlockRight>=ClientRect.left()&&nBlockRight<=ClientRect.right()){ + paint->drawLine(nBlockRight + ptOffset.x(), nTipStart + ptOffset.y(),nBlockRight + ptOffset.x(), nTipEnd + ptOffset.y()); + } + + // 画起始,中止时间 + // + paint->setFont( ptFont ); + paint->setBrush( m_TextBrush ); + + QRect rcPoint; + QString sComment; + if(nBlockLeft>=ClientRect.left()&&nBlockLeft<=ClientRect.right()){ + if(bUpper) rcPoint = QRect (nBlockLeft, 9 - TIPS_HEIGHT ,TEXT_WIDTH, TEXT_WIDTH); + else rcPoint = QRect (nBlockLeft, TIPS_HEIGHT + 1 , TEXT_WIDTH, TEXT_WIDTH); + long lTime = m_pWaveFile->GetBlockBeginTime(nBlk); + sComment.sprintf("%ld", lTime); + QRect tem = QRect(rcPoint.topLeft() + ptOffset,rcPoint.bottomRight() + ptOffset); + paint->drawText(tem,nStyle,sComment); + } + + if(nBlockRight>=ClientRect.left()&&nBlockRight<=ClientRect.right()){ + if(nBlk == m_pWaveFile->m_nNRates-1) + { + rcPoint.setX(nBlockRight); + if(bUpper) rcPoint.setY( 9 - TIPS_HEIGHT ); + else rcPoint.setY(TIPS_HEIGHT + 1); + long lTime = m_pWaveFile->GetBlockEndTime(nBlk); + sComment.sprintf("%ld", lTime); + QRect tem = QRect(rcPoint.topLeft() + ptOffset,rcPoint.bottomRight() + ptOffset); + paint->drawText(tem,nStyle,sComment); + } + } + + double dGridArr[7] = {0.005, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0 }; + double dBigGridWidth = dGirdWidth*10.0; + for(int i=0; i<7; i++) + { + dBigGridWidth = m_pWaveFile->m_dSampleRate[nBlk]*dGridArr[i]*dGirdWidth*fZoomX; + if(dBigGridWidth >= 10.0*dGirdWidth) + break; + } + int nGrid = int(.5+dBigGridWidth/fOneWidth); + if(nGrid<1) nGrid = 1; + for(int nTick=1; nTick<(nGridAmt/nGrid)+1; nTick++) + { + int nX = nBlockLeft + int(.5+nTick*fOneWidth*double(nGrid)); + if(nXClientRect.right()) continue; + + if(nX + dGirdWidth*5.0 > nBlockRight) break; + paint->drawLine(QPoint(nX, nTipStart) + ptOffset,QPoint(nX, nTipEnd) + ptOffset); + + paint->setFont( ptFont ); + paint->setBrush( m_TextBrush ); + if(bUpper) rcPoint = QRect(nX - 5,9 - TIPS_HEIGHT, 30 , 20); + else rcPoint = QRect(nX - 5, TIPS_HEIGHT + 1 , 20 , 20); + QString sComment; + long lTime = long(.5+m_pWaveFile->GetXPositionTime(nX-nLeftMargin)); + if(lTime < 0) lTime = long(-0.5+m_pWaveFile->GetXPositionTime(nX-nLeftMargin)); + sComment.sprintf("%ld", lTime); + QRect tem = QRect(rcPoint.topLeft() + ptOffset,rcPoint.bottomRight() + ptOffset); + paint->drawText(tem,nStyle,sComment); + + } + paint->setBrush(oldBrush); + } + + paint->setFont(OldFont); + paint->setPen(oldPen); +} + +void CTimeAxisShow::drawBackGnd(QPainter *paint) +{ + QRect ClientRect = rect(); + ClientRect.setTop(ClientRect.top() - 1); + QBrush oldBrush = paint->brush(); + paint->setBrush(CWaveEnv::GetInst()->m_TimeBackColor); + paint->drawRect(ClientRect); +} + +void CTimeAxisShow::drawTimeAxisA( QPainter *paint ) +{ + if(!m_pWaveFile) return; + + int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; + int nMaxWidth = m_pWaveFile->GetMaxWidth(); + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; +// int nHeight = 6; + int nX = 0; + + int fOneWidth = int(dGirdWidth*(fZoomX)+.5); + if(fOneWidth < dGirdWidth) + fOneWidth = dGirdWidth; + + QPen oldPen = paint->pen(); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + QFont OldFont = paint->font(); + paint->setFont(m_TinyFont); + + Qt::BGMode oldMode = paint->backgroundMode(); + paint-> setBackgroundMode(Qt::TransparentMode); + + QRect ClientRect = GetValidRect(); + int nLeft = qMax(ClientRect.left(), nLeftMargin - m_nScrollLeft); + int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin - m_nScrollLeft); + + paint->drawLine(nLeft,0,nRight,0); + + +//** + // 画标线 +// if(m_nZoomX >= 128) + { + double nOneWidth = GRID_WIDTH*fZoomX; + int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); + + int Tick1 = (ClientRect.left() - nLeftMargin - 51) / nOneWidth - 1; + int Tick2 = (ClientRect.right() - nLeftMargin + 51) / nOneWidth + 1; + if(Tick1 < 0) Tick1 = 0; + if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; + + // 小格线 每点 + // 中格线, 每100毫秒, 每5ms + // 大格线, 每500秒, 块的起始点, 每20ms + // 写文字, 块的起始点, 500ms, 20ms + QRect rcPoint; + for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) + { + int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; + // 如每格20ms 或 > 20ms + int TB1 = m_pWaveFile->GetStartTick(TR); + int TB2 = TB1 + nGridAmt; + int T1, T2; + if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); + if(TB2SelectObject(&trPen); + int ii = 0; + for(ii=T1; iidrawLine(nLeftMargin + ii*nOneWidth -m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth -m_nScrollLeft, nHeight); + } + + // 起始点,最后一块的中止点 + bool bDrawText = false; + double time = m_pWaveFile->m_aTimeArray[ii]; + long TimeDrawn = 0; + if(ii==TB1 ) + { + // 起始点 + nHeight = 12; + nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; + paint->drawLine(nX, 0 ,nX, nHeight ); + paint->drawLine(nX+1, 0,nX+1, nHeight); + bDrawText = true; + } + else if(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1) + { + // 终点 + nHeight = 12; + nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; + paint->drawLine(nX, 0,nX, nHeight ); + paint->drawLine(nX+1, 0,nX+1, nHeight); + bDrawText = true; + } + + if(bDrawText) + { + TimeDrawn = time/1000L; +// TimeDrawn += m_pWaveFile->GetFirstMicroSecs(); + nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; + rcPoint = QRect(nX - m_nScrollLeft - 5, 18 , TEXT_WIDTH, TEXT_WIDTH); + + QString sComment; + if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); + else sComment.sprintf("%ld\"%03ld", TimeDrawn/1000L, TimeDrawn%1000L); +// GetTimeString(MsString,TimeDrawn); + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + } + } + + + //画中格线 + // (每5ms), + // 如间距 < 10*GRID_WIDTH, (每20ms) + // 如间距 < 10*GRID_WIDTH, (每50ms) + // 如间距 < 10*GRID_WIDTH, (每100ms) + // 如间距 < 10*GRID_WIDTH, (每200ms) + // 如间距 < 10*GRID_WIDTH, (每500ms) + // 如间距 < 10*GRID_WIDTH, (每1000ms) + + double dBigGridWidth = GRID_WIDTH*10.0; +/* for(int i=0; i<12; i++)//按照整数来画标尺 + { + dBigGridWidth = pDoc->m_aRatesArray[TR]*dGridArr[i]*GRID_WIDTH*fZoomX; + if(dBigGridWidth >= 10.0*GRID_WIDTH) + break; + }*/ + int nGrid = int(.5+dBigGridWidth/nOneWidth); + + //pDC->SetTextColor(TmColorArray[TR%32]); + int nStart = 0; + if( TR>0 ) + { + int nGridAmt_prv = m_pWaveFile->m_lSampleAmount[TR-1]; + nStart = nGridAmt_prv%nGrid; + } + + for(ii=1; ii<(nGridAmt/nGrid)+1; ii++) + { + int nRulerStick = TB1+ii*double(nGrid) - nStart; + if( nRulerStick>TB2 ) + break; + + int nHeight = 12; + int nX = nLeftMargin + nRulerStick*nOneWidth - m_nScrollLeft; + + paint->drawLine(nX, 0,nX, nHeight); + + rcPoint = QRect(nX - m_nScrollLeft - 5, 18 , TEXT_WIDTH, TEXT_WIDTH); + + long TimeDrawn = m_pWaveFile->GetPointTime( nRulerStick ); + + QString sComment; + if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); + else sComment.sprintf("%ld\"%03ld", TimeDrawn/1000L, TimeDrawn%1000L); + //GetTimeString(MsString,lTime); + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + } + } + } + + QPoint rcText(nLeftMargin - m_nScrollLeft - 10, 15); + + QFont font = QApplication::font(); + font.setPointSize(OldFont.pointSize()); + paint->setFont(font); + + QString sComment = tr("Timestamp"); + paint->drawText(rcText,sComment); + + paint->setBackgroundMode(oldMode); + + paint->setFont(OldFont); + paint->setPen(oldPen); +} + + +void CTimeAxisShow::drawTimeAxisB( QPainter *paint ) +{ + if(!m_pWaveFile) return; + + int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; + nLeftMargin = 0; +// int nMaxWidth = m_pWaveFile->GetMaxWidth(); + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; +// int nHeight = 6; + int nX = 0; + //{{20090821 +// int nLeftWaveAxis = m_pWaveFile->m_DispAttr.m_nLeftWaveAxis; + //}} + + double fOneWidth = int(dGirdWidth*(fZoomX)+.5); + if(fOneWidth < dGirdWidth) + fOneWidth = dGirdWidth; + + QPen oldPen = paint->pen(); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + QFont OldFont = paint->font(); + paint->setFont(m_TinyFont); + +// Qt::BGMode oldMode = paint->backgroundMode(); +// paint-> setBackgroundMode(Qt::TransparentMode); + + QRect ClientRect = GetValidRect(); +// int nLeft = qMax(ClientRect.left(), nLeftMargin - m_nScrollLeft); +// int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin - m_nScrollLeft); +// int nLeft = ClientRect.left(); +// int nRight = qMin(ClientRect.right(), nMaxWidth - m_nScrollLeft); + + //paint->drawLine(nLeft, 0,nRight, 0); + + QRect rcPoint; + + int m_nZoomX = int(128.0*fZoomX); + // 画标线 + if(m_nZoomX >= 128) + { + double nOneWidth = GRID_WIDTH*fZoomX; + int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); + +// int Tick1 = (ClientRect.left() + m_nScrollLeft - nLeftMargin - 51) / nOneWidth - 1; +// int Tick2 = (ClientRect.right() + m_nScrollLeft- nLeftMargin + 51) / nOneWidth + 1; + int Tick1 = (ClientRect.left() + m_nScrollLeft - 51) / nOneWidth - 1; + int Tick2 = (ClientRect.right() + m_nScrollLeft + 51) / nOneWidth + 1; + if(Tick1 < 0) Tick1 = 0; + if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; + + // 小格线 每点 + // 中格线, 每100毫秒, 每5ms + // 大格线, 每500秒, 块的起始点, 每20ms + // 写文字, 块的起始点, 500ms, 20ms + for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) + { + int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; + // 如每格20ms 或 > 20ms + int TB1 = m_pWaveFile->GetStartTick(TR); + int TB2 = TB1 + nGridAmt; + int T1, T2; + if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); + if(TB2= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth -m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth -m_nScrollLeft, nHeight); + } + + // 起始点,最后一块的中止点 + bool bDrawText = false; + qlonglong time = m_pWaveFile->m_aTimeArray[ii]; + long TimeDrawn = 0; + if( (ii==TB1)||(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1) ) + { + // 起始点 + nHeight = 8/*18*/; + nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nX, 0 ,nX, nHeight ); + + bDrawText = true; + TimeDrawn = (time/1000L); + //paint->setPen( QColor( 0,0,224 ) ); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + } + else + { + if(m_pWaveFile->m_dSampleRate[TR] <= 5) + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 5000ms点 + if((time1 % 5000000L) >= (time % 5000000L)) + { + nHeight = 4/*8*/; + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft ,nHeight); + } + + // 20000ms点 + if((time1 % 20000000L) >= (time % 20000000L)) + { + nHeight = 6/*12*/; + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); + + if(abs(ii-TB1)>10 && abs(ii-TB2)>10) + { + TimeDrawn = (time/1000L); + //paint->setPen( QColor( 0,0,64 ) ); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + bDrawText = true; + } + } + } + else if(m_pWaveFile->m_dSampleRate[TR] <= 20) + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + + // 200ms点 + if((time1 % 200000L) >= (time % 200000L)) + { + nHeight = 4/*8*/; + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); + } + + // 10000ms点 + if((time1 % 1000000L) >= (time % 10000000L)) + { + nHeight = 6/*12*/; + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); + + if(abs(ii-TB1)>10 && abs(ii-TB2)>10) + { + TimeDrawn = (time/1000L); + //paint->setPen( QColor( 0,0,64 ) ); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + bDrawText = true; + } + } + } + else if(m_pWaveFile->m_dSampleRate[TR] <= 50) + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 100ms点 + if((time1 % 100000L) >= (time % 100000L)) + { + nHeight = 4/*8*/; + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); + } + // 500ms点 + if((time1 % 500000L) >= (time % 500000L)) + { + nHeight = 6/*12*/; + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); + + if(abs(ii-TB1)>10 && abs(ii-TB2)>10) + { + TimeDrawn = (time/500000L)*500; + //paint->setPen( QColor( 0,0,64 ) ); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + bDrawText = true; + } + } + } + else + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 5ms点 + nHeight = 4/*8*/; + if((time1 % 5000L) >= (time % 5000L)) + { + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); + } + // 20ms点 + nHeight = 6/*12*/; + if((time1 % 20000L) >= (time % 20000L)) + { + if(int(ii*nOneWidth) - m_nScrollLeft >= 0) + paint->drawLine(nLeftMargin + ii*nOneWidth - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth - m_nScrollLeft,nHeight); + + if(abs(ii-TB1)>10 && abs(ii-TB2)>10) + { + TimeDrawn = (time/20000L)*20; + //paint->setPen( QColor( 0,0,64 ) ); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + bDrawText = true; + } + } + } + } + + if(bDrawText && (int(ii*nOneWidth) - m_nScrollLeft >= 0)) + { + TimeDrawn = time/1000L; + TimeDrawn += m_pWaveFile->m_nFrist_ms; + nX = nLeftMargin + ii*nOneWidth - m_nScrollLeft; + rcPoint = QRect(nX - 5, 7/*18*/ , TEXT_WIDTH, TEXT_WIDTH); + + QString sComment; + if (TimeDrawn < 0) sComment.sprintf("-%ld", -1*TimeDrawn); + else if((TimeDrawn < 1000)&&(TimeDrawn >= 0)) sComment.sprintf("%ld", TimeDrawn); + else sComment.sprintf("%ld\"%03ld", TimeDrawn/1000L, TimeDrawn%1000L); + + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + //paint->setPen(QColor(0,0,64)); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + } + } + } + } + + if(m_nZoomX<=64 && m_nZoomX>0) + { + int n = 1.0/fZoomX; + if(n <= 0) n = 1; + + int nOneWidth = GRID_WIDTH; + int nTotalTicks = m_pWaveFile->GetTotalPointAmount(); + + int Tick1 = ((ClientRect.left() + m_nScrollLeft - nLeftMargin - 51) / nOneWidth - 1)* n; + int Tick2 = ((ClientRect.right() + m_nScrollLeft - nLeftMargin + 51) / nOneWidth + 1)* n; + + if(Tick1 < 0) Tick1 = 0; + if(Tick2 > nTotalTicks) Tick2 = nTotalTicks; + + // 小格线 每100ms, 5ms, + // 中格线, 每500ms, 每20ms + // 大格线, 块的起始点, n*500ms, n*20ms + // 写文字, 块的起始点, n*500ms, n*20ms + for(int TR=0; TR<(m_pWaveFile->m_nNRates); TR++) + { + int nGridAmt = m_pWaveFile->m_lSampleAmount[TR]; + // 如每格20ms 或 > 20ms + int TB1 = m_pWaveFile->GetStartTick(TR); + int TB2 = TB1 + nGridAmt; + int T1, T2; + if(TB1>=Tick2) continue; else T1 = qMax(TB1, Tick1); + if(TB2m_aTimeArray[ii]; + long TimeDrawn = 0; + if((ii==TB1)||(TR==m_pWaveFile->m_nNRates-1 && ii==TB2-1)) + { + // 起始点 + nHeight = 6/*12*/; + nX = nLeftMargin + ii*nOneWidth/n - m_nScrollLeft; + paint->drawLine(nX, 0 ,nX, nHeight ); + paint->drawLine(nX+1, 0,nX+1, nHeight); + + bDrawText = true; + TimeDrawn = (time/1000L); + //paint->setPen(QColor(0,0,224)); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + } + else + { + if(m_pWaveFile->m_dSampleRate[TR] <= 50) + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 小格线 + nHeight = 2/*5*/; + // 100ms点 + if((time1 % 100000L) >= (time % 100000L)) + { + paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); + } + + // 500ms点 + if((time1 % 500000L) >= (time % 500000L)) + { + nHeight = 4/*8*/; + paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); + } + // n*500ms点 + if((time1 % (500000L*n)) >= (time % (500000L*n))) + { + nHeight = 6/*12*/; + paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); + + + if(abs(ii-TB1)>10*n && abs(ii-TB2)>10*n) + { + TimeDrawn = (time/500000L)*500; + //paint->setPen(QColor(0,0,64)); + bDrawText = true; + } + } + } + else + { + int time1 = m_pWaveFile->m_aTimeArray[ii-1]; + // 小格线 + nHeight = 2/*5*/; + // 5ms点 + if((time1 % 5000L) >= (time % 5000L)) + { + paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); + } + + // 20ms点 + nHeight = 4/*8*/; + if((time1 % 20000L) >= (time % 20000L)) + { + paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); + } + // n*20ms点 + nHeight = 6/*12*/; + if((time1 % (20000L*n)) >= (time % (20000L*n))) + { + paint->drawLine(nLeftMargin + ii*nOneWidth/n - m_nScrollLeft, 0,nLeftMargin + ii*nOneWidth/n - m_nScrollLeft,nHeight); + + if(abs(ii-TB1)>10*n && abs(ii-TB2)>10*n) + { + TimeDrawn = (time/20000L)*20; + //paint->setPen(QColor(0,0,64)); + bDrawText = true; + } + } + } + } + if(bDrawText) + { + TimeDrawn = time/1000L; + TimeDrawn += m_pWaveFile->m_nFrist_ms; + nX = nLeftMargin + ii*nOneWidth/n - m_nScrollLeft; + rcPoint = QRect(nX - 5, 7/*18*/ , TEXT_WIDTH, TEXT_WIDTH); + + QString sComment; + if (TimeDrawn < 0) sComment.sprintf("-%ld", -1*TimeDrawn); + else if((TimeDrawn < 1000)&&(TimeDrawn >= 0)) sComment.sprintf("%ld", TimeDrawn); + else sComment.sprintf("%ld\"%03ld", TimeDrawn/1000L, TimeDrawn%1000L); + + //if(TimeDrawn < 1000) sComment.sprintf("%ld", TimeDrawn); + //else sComment.sprintf("%d,%03d", TimeDrawn/1000L, TimeDrawn%1000L); + //GetTimeString(MsString,TimeDrawn); + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + //paint->setPen(QColor(0,0,64)); + } + } + } + } + +// QPoint rcText(nLeftMargin - m_nScrollLeft - 40, 15); +// QPoint rcText(nLeftMargin + 20,15); +// +// QFont font = QApplication::font(); +// font.setPointSize(OldFont.pointSize()); +// paint->setFont(font); +// +// QString sComment = tr("时标"); +// paint->drawText(rcText,sComment); + +// paint->setBackgroundMode(oldMode); + + paint->setFont(OldFont); + paint->setPen(oldPen); +} + +void CTimeAxisShow::drawTimeAxis( QPainter *paint ) +{ + if(!m_pWaveFile) return; + + int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; +// int nMaxWidth = m_pWaveFile->GetMaxWidth(); + double fZoomX = m_pWaveFile->m_DispAttr.m_fZoomX; + //fZoomX = 25.0/43.0; + double dGirdWidth = m_pWaveFile->m_DispAttr.m_dGridWidth; + int nHeight = 6; + + double fOneWidth = double(dGirdWidth*(fZoomX)+.5); + if(fOneWidth < dGirdWidth) + fOneWidth = dGirdWidth; + //double fOneWidth = 1.0; + //if(fZoomX >= (1.0 - 1E-5)) fOneWidth = double(dGirdWidth*fZoomX+.5); + //else fOneWidth = double(dGirdWidth+.5); + + QPen oldPen = paint->pen(); + paint->setPen(CWaveEnv::GetInst()->m_TimeForeColor); + QFont OldFont = paint->font(); + paint->setFont(m_TinyFont); + + Qt::BGMode oldMode = paint->backgroundMode(); + paint-> setBackgroundMode(Qt::TransparentMode); + +// QRect ClientRect = GetValidRect(); +// int nLeft = qMax(ClientRect.left(), nLeftMargin - m_nScrollLeft); +// int nRight = qMin(ClientRect.right(), nMaxWidth + nLeftMargin - m_nScrollLeft); + + for(int nBlk = 0; nBlk < m_pWaveFile->m_nNRates; nBlk++) + { + int nBlockLeft = m_pWaveFile->GetBlockLeft(nBlk)+nLeftMargin; + int nBlockRight = m_pWaveFile->GetBlockRight(nBlk)+nLeftMargin; + //fOneWidth = 1.0; + // 画小格线 + int nGridAmt = int(double(nBlockRight-nBlockLeft)/fOneWidth+.5)+1; + + int nTick = 0; + for( nTick=0; nTick nBlockRight) break; + paint->drawLine(nX - m_nScrollLeft, 0,nX - m_nScrollLeft, nHeight); + } + + // 起始点,中止点 + int nHeight = 12; + paint->drawLine(nBlockLeft - m_nScrollLeft, 0,nBlockLeft - m_nScrollLeft, nHeight*2); + + paint->drawLine(nBlockRight - m_nScrollLeft, 0,nBlockRight - m_nScrollLeft, nHeight*2); + + // 画起始,中止时间 + // + paint->setFont(m_LittleFont); + QBrush oldBrush = paint->brush(); + paint->setBrush( m_TextBrush ); + QRect rcPoint(nBlockLeft - m_nScrollLeft, 18 , TEXT_WIDTH , TEXT_WIDTH); + QString sComment; + long lTime = m_pWaveFile->GetBlockBeginTime(nBlk); + if (lTime < 0) sComment.sprintf("-%ld", -1*lTime); + else if((lTime < 1000)&&(lTime >= 0)) sComment.sprintf("%ld", lTime); + else sComment.sprintf("%ld\"%03ld", lTime/1000L, lTime%1000L); + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + + if(nBlk == m_pWaveFile->m_nNRates-1) + { + rcPoint.setX(nBlockRight - m_nScrollLeft); + rcPoint.setY(13); + long lTime = m_pWaveFile->GetBlockEndTime(nBlk); + if (lTime < 0) sComment.sprintf("-%ld", -1*lTime); + else if((lTime < 1000)&&(lTime >= 0)) sComment.sprintf("%ld", lTime); + else sComment.sprintf("%ld\"%03ld", lTime/1000L, lTime%1000L); + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + } + + + //找出中格的点数和大格的点数 + // (每5ms), + // 如间距 < 10*GRID_WIDTH, (每20ms) + // 如间距 < 10*GRID_WIDTH, (每50ms) + // 如间距 < 10*GRID_WIDTH, (每100ms) + // 如间距 < 10*GRID_WIDTH, (每200ms) + // 如间距 < 10*GRID_WIDTH, (每500ms) + // 如间距 < 10*GRID_WIDTH, (每1000ms) + + double dGridArr[7] = {0.005, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0 }; + double dMidGridWidth = dGirdWidth*1.0;//中格 + double dBigGridWidth = dGirdWidth*10.0; + int nUnit = 0; + if( m_pWaveFile->m_dSampleRate[nBlk]<=50.0 ) + nUnit = 3; + + for(int i=nUnit; i<7; i++) + { + dBigGridWidth = m_pWaveFile->m_dSampleRate[nBlk]*dGridArr[i]*dGirdWidth*fZoomX; + if(dBigGridWidth >=10.0*dGirdWidth) + break; + dMidGridWidth = dBigGridWidth; + } + //画中格线 + int nGrid = int(.5+dMidGridWidth/fOneWidth); + if(nGrid>1) + { + for(nTick=1; nTick<(nGridAmt/nGrid)+1; nTick++) + { + int nHeight = 10; + int nX = nBlockLeft + int(.5+nTick*fOneWidth*double(nGrid)); + if(nX + dGirdWidth*5.0 > nBlockRight) break; + paint->drawLine(nX - m_nScrollLeft, 0,nX - m_nScrollLeft, nHeight); + } + } + + //画大格线(带刻度) + nGrid = int(.5+dBigGridWidth/fOneWidth); + if(nGrid<1) nGrid = 1; + for(nTick=1; nTick<(nGridAmt/nGrid)+1; nTick++) + { + int nHeight = 12; + int nX = nBlockLeft + int(.5+nTick*fOneWidth*double(nGrid)); + if(nX + dGirdWidth*5.0 > nBlockRight) break; + paint->drawLine(nX - m_nScrollLeft, 0,nX - m_nScrollLeft, nHeight); + + paint->setBrush( m_TextBrush ); + rcPoint = QRect(nX - m_nScrollLeft - 5, 18 , TEXT_WIDTH, TEXT_WIDTH); + QString sComment; + long lTime = long(.5+m_pWaveFile->GetXPositionTime(nX-nLeftMargin)); + if(lTime < 0) lTime = long(-0.5+m_pWaveFile->GetXPositionTime(nX-nLeftMargin)); + if (lTime < 0) sComment.sprintf("-%ld", -1*lTime); + else if((lTime < 1000)&&(lTime >= 0)) sComment.sprintf("%ld", lTime); + else sComment.sprintf("%ld\"%03ld", lTime/1000L, lTime%1000L); + paint->drawText(rcPoint,Qt::AlignLeft | Qt::TextSingleLine,sComment); + + } + paint->setBrush(oldBrush); + } + + QPoint rcText(nLeftMargin - m_nScrollLeft - 10, 15); + + + QFont font = QApplication::font(); + font.setPointSize(OldFont.pointSize()); + paint->setFont(font); + QString sComment = tr("Timestamp");//时标 + paint->drawText(rcText,sComment); + + paint->setBackgroundMode(oldMode); + + + paint->setFont(OldFont); + paint->setPen(oldPen); +} + +void CTimeAxisShow::drawBaseLine(QPainter * paint,const QColor& clr) +{ + if(!m_pWaveFile) return; + int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; + nLeftMargin = 0; + + int XPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fBaseTick ); + + if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) + XPosition = m_pWaveFile->GetMaxWidth(); + + XPosition -= m_nScrollLeft; + XPosition += nLeftMargin; + +// m_pTimeSlider->SetPosition1(XPosition); + + QRect ClientRect = GetValidRect(); + if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) + { + LCyanPen.setColor(clr); + QPen oldPen = paint->pen(); + paint->setPen(clr); + paint->setBrush( QColor(0,123,247) ); + paint->drawLine(XPosition,0,XPosition,8/*ClientRect.bottom()*/); + QRect rcText(XPosition-5,8/*20*/,12,12); + paint->drawText(rcText,Qt::AlignCenter | Qt::AlignVCenter,"B"); + paint->setPen(oldPen); + } +} + +//画竖线 +void CTimeAxisShow::drawStaticLine(QPainter * paint,const QColor& clr) +{ + if(!m_pWaveFile) return; + int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; + nLeftMargin = 0; + + int XPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fStaticTick ); + if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) + XPosition = m_pWaveFile->GetMaxWidth(); + + XPosition -= m_nScrollLeft; + XPosition += nLeftMargin; + +// m_pTimeSlider->SetPosition2(XPosition); + + QRect ClientRect = GetValidRect(); + if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) + { + LCyanPen.setColor(clr); + QPen oldPen = paint->pen(); + paint->setPen(LCyanPen); + + paint->drawLine(XPosition,0,XPosition,8/*ClientRect.bottom()*/); + QRect rcText(XPosition-5,8/*20*/,12,12); + paint->drawText(rcText,Qt::AlignCenter | Qt::AlignVCenter,"C"); + paint->setPen(oldPen); + } +} + +//画竖线 +void CTimeAxisShow::drawUpDownLine(QPainter * paint, double fLineTick, const QColor& clr) +{ + if(!m_pWaveFile) return; + int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; + nLeftMargin = 0; + + int XPosition = m_pWaveFile->GetPointPosition(fLineTick); + if(XPosition < 0 || XPosition > m_pWaveFile->GetMaxWidth()) + XPosition = m_pWaveFile->GetMaxWidth(); + + XPosition -= m_nScrollLeft; + XPosition += nLeftMargin; + + QRect ClientRect = GetValidRect(); + if(XPosition>=ClientRect.left() && XPosition<=ClientRect.right()) + { + LCyanPen.setColor(clr); + QPen oldPen = paint->pen(); + paint->setPen(LCyanPen); + + paint->drawLine(XPosition,0,XPosition,ClientRect.bottom()); + + paint->setPen(oldPen); + } +} + +void CTimeAxisShow::drawCursor(QPainter* paint) +{ + if(m_nCursorX > 0) + { + QRect rcRect = GetValidRect(); + + QPainter::CompositionMode OldRop2 = paint->compositionMode(); + paint->setCompositionMode(QPainter::CompositionMode_Xor); + QPen oldPen = paint->pen(); + //paint->setPen(BluePen); + paint->setPen(CWaveEnv::GetInst()->m_MoveLineColor); + + paint->drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); + + paint->setPen(oldPen); + paint->setCompositionMode(OldRop2); + } +} + +QRect CTimeAxisShow::GetValidRect() +{ + QRect rcRect = rect(); + rcRect.setBottom( rcRect.bottom() - SILIDER_HEIGHT ); + return rcRect; +} + +void CTimeAxisShow::GetTimeMargin(QRect &rect) +{ + if(!m_pWaveFile) return; + + int nMaxWidth = m_pWaveFile->GetMaxWidth(); + rect = QRect(0,0,nMaxWidth,TIMEAXIS_HEIGHT); +} +//////////////////////////////////////////////////////////////////////// +//##ModelId=4039BEDE0118 +bool CTimeAxisShow::SetComtradeData(CComtradeFile& pComtradeData) +{ + m_pWaveFile = &pComtradeData; + + ResetHScrollSize(); + + update(); + + return true; +} + +CWaveShow* CTimeAxisShow::GetParent() +{ + return (CWaveShow*)parent(); +} + +void CTimeAxisShow::HoriztalScrollBarMove(int value) +{ + GetParent()->HTimeScroll(value); +} + +void CTimeAxisShow::ResetHScrollSize() +{ + int nMaxWidth = m_pWaveFile->GetMaxWidth(); +// int nTemp = QApplication::desktop()->size().width(); +// horiz_bar->setRange(0,nMaxWidth - nTemp + GetParent()->m_nLeftMargin + 50); + horiz_bar->setRange(0,nMaxWidth - rect().width() + 50); +// horiz_bar->setRange(0,nMaxWidth - nTemp); +} + +void CTimeAxisShow::HScroll(int value) +{ + //horiz_bar->setValue(value); + //m_nScrollLeft = horiz_bar->value(); + m_nScrollLeft = value ; + update(); +} + +int CTimeAxisShow::GetHScroll() +{ + return horiz_bar->value(); +} + +void CTimeAxisShow::OnSliderMove( int no,int pos ) +{ + int nPosX; + int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; + nLeftMargin = 0; + nPosX = pos - nLeftMargin; + + if(nPosX < 0) nPosX = 0; + + int nAbsXPos = nPosX + m_nScrollLeft; + if(nAbsXPos < 0) nAbsXPos = 0; + if(nAbsXPos > m_pWaveFile->GetMaxWidth()) + nAbsXPos = m_pWaveFile->GetMaxWidth(); + + double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; + double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); + + switch( no ) + { + case 1: + { + m_pWaveFile->m_DispAttr.m_fBaseTime = RTime; + m_pWaveFile->m_DispAttr.m_fBaseTick = dTick; + m_pWaveFile->EmitLineBChanged(); + } + break; + case 2: + { + m_pWaveFile->m_DispAttr.m_fStaticTime = RTime; + m_pWaveFile->m_DispAttr.m_fStaticTick = dTick; + m_pWaveFile->EmitLineCChanged(); + } + break; + default: + break; + } + GetParent()->update(); + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(4,false); + GetParent()->redrawWindow(1,false);//名称区显示数据值 + update(); + +} + +void CTimeAxisShow::doMouseMove( QMouseEvent *e) +{ + //{{处理移动 +// m_pTimeSlider->DoMouseMove(e); + //}} + + if(e->x() < 0) return; + +// QRect rcRect = GetValidRect(); + +// QPainter paint(this); +// QPainter::CompositionMode OldRop2 = paint.compositionMode(); +// paint.setCompositionMode(QPainter::CompositionMode_Xor); + +// paint.setCompositionMode(QPainter::CompositionMode_SourceOver); +// QPen oldPen = paint.pen(); +// paint.setPen(BluePen); + // +// if(m_nCursorX > 0) +// paint.drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); +// m_nCursorX = e->x(); +// paint.drawLine(m_nCursorX, rcRect.top(),m_nCursorX, rcRect.bottom()); +// +// m_nCursorX = e->x(); +// +// if(CWaveEnv::GetInst()->m_bCruise&&m_nCursorX>=(rcRect.right() - 30)) +// { +// m_nScrollLeft += SCROLLBAR_H_LINE; +// GetParent()->HTimeScroll(m_nScrollLeft); +// } +// else if(CWaveEnv::GetInst()->m_bCruise&&m_nCursorX<=(rcRect.left() + GetParent()->m_nLeftMargin + 30)) +// { +// m_nScrollLeft -= SCROLLBAR_H_LINE; +// if(m_nScrollLeft<0) +// m_nScrollLeft = 0; +// GetParent()->HTimeScroll(m_nScrollLeft); +// } +// +// paint.setPen(oldPen); + //paint.setCompositionMode(OldRop2); +} + +void CTimeAxisShow::doMousePress( QMouseEvent *e ) +{ + //{{处理移动 +// if( m_SliderBar.contains( e->pos() ) ) +// { +// m_pTimeSlider->DoMousePress(e); +// return; +// } + //}} + + int nPosX; + int nLeftMargin = GetParent()->m_nLeftMargin+SPLITTERWIDTH; + nLeftMargin = SPLITTERWIDTH; + nPosX = e->x() - nLeftMargin; + + if(nPosX < 0) nPosX = 0; + + int nAbsXPos = nPosX + m_nScrollLeft; + if(nAbsXPos < 0) nAbsXPos = 0; + if(nAbsXPos > m_pWaveFile->GetMaxWidth()) + nAbsXPos = m_pWaveFile->GetMaxWidth(); + + double dTick = m_pWaveFile->GetTick(nAbsXPos)+0.1; + double RTime = m_pWaveFile->GetXPositionTime(nAbsXPos); + + if(e->button() == Qt::LeftButton) + { + m_pWaveFile->m_DispAttr.m_fStaticTime = RTime; + m_pWaveFile->m_DispAttr.m_fStaticTick = dTick; + m_pWaveFile->EmitLineCChanged(); + } + else if(e->button() == Qt::RightButton) + { + m_pWaveFile->m_DispAttr.m_fBaseTime = RTime; + m_pWaveFile->m_DispAttr.m_fBaseTick = dTick; + m_pWaveFile->EmitLineBChanged(); + } + + +} + +void CTimeAxisShow::doMouseRelease( QMouseEvent *e ) +{ + Q_UNUSED(e) + //{{处理移动 +// m_pTimeSlider->DoMouseRelease(e); + //}} + + +} + +void CTimeAxisShow::wheelEvent(QWheelEvent *e) +{ + if(e->delta() > 0) + m_pWaveFile->m_DispAttr.m_fZoomX *= 2.0; + else + m_pWaveFile->m_DispAttr.m_fZoomX /=2.0; + + if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; + if(m_pWaveFile->m_DispAttr.m_fZoomX*256.0 < 8.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/256.0; + + ResetHScrollSize(); + + GetParent()->redrawWindow(2,false); + GetParent()->redrawWindow(4,false); + GetParent()->redrawWindow(5,false); +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CTimeAxisShow.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CTimeAxisShow.h index b10fff26..ec14044d 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CTimeAxisShow.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CTimeAxisShow.h @@ -1,165 +1,165 @@ -#ifndef CTIMEAXISSHOW_H_HEADER_INCLUDED_BFC41131 -#define CTIMEAXISSHOW_H_HEADER_INCLUDED_BFC41131 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include "CComDataClass.h" - -#include "CWaveGraph.h" - -//class CWaveShow; - -const int TIMEAXIS_HEIGHT = 30; -const int TIPS_HEIGHT = 6; -const int SILIDER_HEIGHT = 16; - -class CTimeSlider: public QObject -{ - Q_OBJECT - -public: - CTimeSlider(QWidget *parent); - virtual ~CTimeSlider(); -public: - void Draw( QPainter *paint ); - void DrawMoveBar( QPainter* paint,int nNo,int nPos ); - void SetPosition1( int nPos1 ); - void SetPosition2( int nPos2 ); - void SetEnablePso1( bool bEnable ); - void SetEnablePso2( bool bEnable ); - void SetGeometry( const QRect& geom ); - void DoMousePress(QMouseEvent *e); - void DoMouseMove(QMouseEvent *e); - void DoMouseRelease(QMouseEvent *e); - -signals: - void OnChange( int no,int nPos ); - -private: - QWidget* m_pParent; - QPalette m_Palette; - bool m_bEnablePos1; - bool m_bEnablePos2; - int m_nPos1; - int m_nPos2; - QRect m_rcGeometry; - QRect m_rcBar1; - QRect m_rcBar2; - - bool m_bMoveBaseBar1; - bool m_bMoveBaseBar2; - int m_nLastXPos; - -}; - -class CVerticalSlider: public QObject -{ - Q_OBJECT - -public: - CVerticalSlider(QWidget *parent); - virtual ~CVerticalSlider(); -public: - void Draw( QPainter *paint ); - void DrawMoveBar( QPainter *paint,int nPos ); - void SetPosition( int nPos ); - void SetGeometry( const QRect& geom ); - void DoMousePress(QMouseEvent *e); - void DoMouseMove(QMouseEvent *e); - void DoMouseRelease(QMouseEvent *e); - -signals: - void OnChange( int nPos ); - -private: - QWidget* m_pParent; - QPalette m_Palette; - int m_nPos; - QRect m_rcGeometry; - QRect m_rcBar; - - bool m_bMoveBaseBar; - int m_nLastXPos; -}; - -//##ModelId=403405ED00B3 -class CTimeAxisShow : public QWidget -{ - Q_OBJECT - -public: - CTimeAxisShow(QWidget *parent, QScrollBar* horscrl,Qt::WindowFlags f = 0); - ~CTimeAxisShow(); -public: - CTimeSlider* m_pTimeSlider; - - QScrollBar *horiz_bar; - CComtradeFile* m_pWaveFile; - -public: - QPen DGrayPen; - QPen BluePen; - QPen RedPen; - QPen WhitePen; - QPen DRedPen; - QPen LLGrayPen; - QPen LCyanPen; - - QFont m_LittleFont; - QFont m_TinyFont; - QBrush m_TextBrush; - - int m_nScrollLeft; - int m_nCursorX; - - QRect m_SliderBar; - int m_nLastXPos; - -public: - //##ModelId=4039BEDE0118 - bool SetComtradeData(CComtradeFile& pComtradeData); - - CWaveShow* GetParent(); - void draw( QPainter *); - //稳控的等分画法 - void drawTimeAxisA( QPainter *); - //王长林旧波行工具算法 - void drawTimeAxisB( QPainter *); - void drawTimeAxis( QPainter *); - void drawBackGnd(QPainter *); - void drawBaseLine(QPainter * paint,const QColor& clr); - void drawStaticLine(QPainter * paint,const QColor& clr); - void drawUpDownLine(QPainter * ,double, const QColor& ); - void drawCursor(QPainter *); - void PrintB( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,bool bUpper); - void Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,bool bUpper); - void GetTimeMargin(QRect &rect); - QRect GetValidRect(); - - void ResetHScrollSize(); - void HScroll(int value); - int GetHScroll(); - -public slots: - void OnSliderMove( int no,int pos ); - void HoriztalScrollBarMove(int value); - void doMouseMove( QMouseEvent *e ); - void doMousePress( QMouseEvent *e ); - void doMouseRelease( QMouseEvent *e ); - void OnMousePressEvent( QMouseEvent * ); - void OnMouseReleaseEvent( QMouseEvent * ); - void OnMouseMoveEvent( QMouseEvent * ); - -protected: - void wheelEvent(QWheelEvent *); - void paintEvent( QPaintEvent *); -}; - -#endif /* CTIMEAXISSHOW_H_HEADER_INCLUDED_BFC41131 */ +#ifndef CTIMEAXISSHOW_H_HEADER_INCLUDED_BFC41131 +#define CTIMEAXISSHOW_H_HEADER_INCLUDED_BFC41131 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "CComDataClass.h" + +#include "CWaveGraph.h" + +//class CWaveShow; + +const int TIMEAXIS_HEIGHT = 30; +const int TIPS_HEIGHT = 6; +const int SILIDER_HEIGHT = 16; + +class CTimeSlider: public QObject +{ + Q_OBJECT + +public: + CTimeSlider(QWidget *parent); + virtual ~CTimeSlider(); +public: + void Draw( QPainter *paint ); + void DrawMoveBar( QPainter* paint,int nNo,int nPos ); + void SetPosition1( int nPos1 ); + void SetPosition2( int nPos2 ); + void SetEnablePso1( bool bEnable ); + void SetEnablePso2( bool bEnable ); + void SetGeometry( const QRect& geom ); + void DoMousePress(QMouseEvent *e); + void DoMouseMove(QMouseEvent *e); + void DoMouseRelease(QMouseEvent *e); + +signals: + void OnChange( int no,int nPos ); + +private: + QWidget* m_pParent; + QPalette m_Palette; + bool m_bEnablePos1; + bool m_bEnablePos2; + int m_nPos1; + int m_nPos2; + QRect m_rcGeometry; + QRect m_rcBar1; + QRect m_rcBar2; + + bool m_bMoveBaseBar1; + bool m_bMoveBaseBar2; + int m_nLastXPos; + +}; + +class CVerticalSlider: public QObject +{ + Q_OBJECT + +public: + CVerticalSlider(QWidget *parent); + virtual ~CVerticalSlider(); +public: + void Draw( QPainter *paint ); + void DrawMoveBar( QPainter *paint,int nPos ); + void SetPosition( int nPos ); + void SetGeometry( const QRect& geom ); + void DoMousePress(QMouseEvent *e); + void DoMouseMove(QMouseEvent *e); + void DoMouseRelease(QMouseEvent *e); + +signals: + void OnChange( int nPos ); + +private: + QWidget* m_pParent; + QPalette m_Palette; + int m_nPos; + QRect m_rcGeometry; + QRect m_rcBar; + + bool m_bMoveBaseBar; + int m_nLastXPos; +}; + +//##ModelId=403405ED00B3 +class CTimeAxisShow : public QWidget +{ + Q_OBJECT + +public: + CTimeAxisShow(QWidget *parent, QScrollBar* horscrl,Qt::WindowFlags f = 0); + ~CTimeAxisShow(); +public: + CTimeSlider* m_pTimeSlider; + + QScrollBar *horiz_bar; + CComtradeFile* m_pWaveFile; + +public: + QPen DGrayPen; + QPen BluePen; + QPen RedPen; + QPen WhitePen; + QPen DRedPen; + QPen LLGrayPen; + QPen LCyanPen; + + QFont m_LittleFont; + QFont m_TinyFont; + QBrush m_TextBrush; + + int m_nScrollLeft; + int m_nCursorX; + + QRect m_SliderBar; + int m_nLastXPos; + +public: + //##ModelId=4039BEDE0118 + bool SetComtradeData(CComtradeFile& pComtradeData); + + CWaveShow* GetParent(); + void draw( QPainter *); + //稳控的等分画法 + void drawTimeAxisA( QPainter *); + //王长林旧波行工具算法 + void drawTimeAxisB( QPainter *); + void drawTimeAxis( QPainter *); + void drawBackGnd(QPainter *); + void drawBaseLine(QPainter * paint,const QColor& clr); + void drawStaticLine(QPainter * paint,const QColor& clr); + void drawUpDownLine(QPainter * ,double, const QColor& ); + void drawCursor(QPainter *); + void PrintB( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,bool bUpper); + void Print( QPainter *paint ,QRect& rect ,QPoint ptOffset, bool bColor,bool bUpper); + void GetTimeMargin(QRect &rect); + QRect GetValidRect(); + + void ResetHScrollSize(); + void HScroll(int value); + int GetHScroll(); + +public slots: + void OnSliderMove( int no,int pos ); + void HoriztalScrollBarMove(int value); + void doMouseMove( QMouseEvent *e ); + void doMousePress( QMouseEvent *e ); + void doMouseRelease( QMouseEvent *e ); + void OnMousePressEvent( QMouseEvent * ); + void OnMouseReleaseEvent( QMouseEvent * ); + void OnMouseMoveEvent( QMouseEvent * ); + +protected: + void wheelEvent(QWheelEvent *); + void paintEvent( QPaintEvent *); +}; + +#endif /* CTIMEAXISSHOW_H_HEADER_INCLUDED_BFC41131 */ diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveGraph.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveGraph.cpp index db2f54ad..41631728 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveGraph.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveGraph.cpp @@ -1,376 +1,376 @@ -#include -#include "CWaveGraph.h" -#include "CWaveShow.h" - -CWaveGraph::CWaveGraph(QWidget *parent,Qt::WindowFlags f) - : QWidget(parent,f) -{ - m_pWaveShow = new CWaveShow(parent); - m_pWaveShow->SetComtradeData(m_pWaveFile); - - connect(m_pWaveShow,SIGNAL(StatusEmited()),this,SLOT(showStatus())); - - triggerLabel = new QLabel(); - startLabel = new QLabel(); - endLabel = new QLabel(); - statusLabel = new QLabel(); - diffLabel = new QLabel(); - statusLabel->setFixedWidth(50); - statusLabel->setAlignment(Qt::AlignRight); - - triggerLabel->setFrameShape(QFrame::NoFrame); - triggerLabel->setFrameShadow(QFrame::Plain); - startLabel->setFrameShape(QFrame::NoFrame); - startLabel->setFrameShadow(QFrame::Plain); - endLabel->setFrameShape(QFrame::NoFrame); - endLabel->setFrameShadow(QFrame::Plain); - statusLabel->setFrameShape(QFrame::NoFrame); - statusLabel->setFrameShadow(QFrame::Plain); - diffLabel->setFrameShape(QFrame::NoFrame); - diffLabel->setFrameShadow(QFrame::Plain); - - QHBoxLayout * hLayout = new QHBoxLayout; - hLayout->addWidget(triggerLabel); - hLayout->addWidget(startLabel); - hLayout->addWidget(endLabel); - hLayout->addWidget(diffLabel); - hLayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding)); - hLayout->addWidget(statusLabel); - QVBoxLayout * vLayout = new QVBoxLayout; - vLayout->addWidget(m_pWaveShow); - vLayout->addLayout(hLayout); - vLayout->setStretch(0,1); - vLayout->setMargin(0); - setLayout(vLayout); - - triggerLabel->setText(tr("Trigger Line") + ": ");//触发线 - startLabel->setText(tr("Line B") + ": "); - endLabel->setText(tr("Line C") + ": "); - diffLabel->setText("Delta:ms"); -} - -CWaveGraph::~CWaveGraph() -{ - -} - - -//##ModelId=4034009102B7 -bool CWaveGraph::SetComtradeData(CComtradeFile& pComtradeData) -{ - if(m_pWaveShow) - { - m_pWaveFile = pComtradeData; - setWindowTitle(m_pWaveFile.m_sFileName); - return m_pWaveShow->SetComtradeData(pComtradeData); - } - return false; -} - -void CWaveGraph::showComtradeFile() -{ - m_pWaveShow->SetComtradeData(m_pWaveFile); -} - -//##ModelId=403401F301CC -bool CWaveGraph::SetShowAttribute( CSectionList& pAttrList) -{ - Q_UNUSED(pAttrList) - return true; -} - -bool CWaveGraph::EditAnaGroup() -{ -// if(m_pWaveShow) return m_pWaveShow->EditAnaGroup(); - return false; -} - -bool CWaveGraph::EditDgtGroup() -{ -// if(m_pWaveShow) return m_pWaveShow->EditDgtGroup(); - return false; -} - -bool CWaveGraph::EditAnaTable() -{ -// if(m_pWaveShow) return m_pWaveShow->EditAnaTable(); - return false; -} - -bool CWaveGraph::EditDgtTable() -{ -// if(m_pWaveShow) return m_pWaveShow->EditDgtTable(); - return false; -} - -bool CWaveGraph::EditGridSet() -{ -// if(m_pWaveShow) return m_pWaveShow->EditGridSet(); - return false; -} - -bool CWaveGraph::EditSelectLine() -{ - if(m_pWaveShow) return m_pWaveShow->EditSelectLine(); - return false; -} - -bool CWaveGraph::EditSelectColor() -{ - if(m_pWaveShow) return m_pWaveShow->EditSelectColor(); - return false; -} - -//##ModelId=4034037702B7 -bool CWaveGraph::GetShowAttribute( CSectionList& pAttrList) -{ - Q_UNUSED(pAttrList) - return true; -} - -//##ModelId=4034051400C3 -bool CWaveGraph::IsDispAttrModified() -{ - return true; -} - -int CWaveGraph::GetCursorTicks() -{ - if(m_pWaveShow) - return m_pWaveShow->GetCursorTicks(); - return 0; -} - -//##ModelId=4039BE8503AB -int CWaveGraph::GetLabelAmount() -{ - return true; -} - -//##ModelId=4039BE8C0188 -void CWaveGraph::GetLabel() -{ -} - -//##ModelId=4039BE9001A7 -void CWaveGraph::AddLabel() -{ -// if(m_pWaveShow) -// m_pWaveShow->AddLabel(); -} - -//##ModelId=4039BE960159 -void CWaveGraph::ModifyLabel() -{ - -} - -//##ModelId=4039BE9A0272 -void CWaveGraph::DeleteLabel() -{ -} - -//##ModelId=4039BF0D00C9 -void CWaveGraph::ShowLabel() -{ -// if(m_pWaveShow) -// m_pWaveShow->ShowLabels(); -} - -void CWaveGraph::SetZoon() -{ -// if(m_pWaveShow) -// m_pWaveShow->SetZoon(); -} - -void CWaveGraph::CancelZone() -{ - if(m_pWaveShow) - m_pWaveShow->OnCacelZone(); -} - -void CWaveGraph::CopySelectPixmap() -{ -// if(m_pWaveShow) -// m_pWaveShow->CopySelectPixmap(); -} - -void CWaveGraph::CopyZonePixmap() -{ -// if(m_pWaveShow) -// m_pWaveShow->CopyZonePixmap(); -} - -//{{ Add by qizhong -void CWaveGraph::copyZonepixmapToFile() -{ - if(m_pWaveShow) - m_pWaveShow->copyZonepixmapToFile(); -} -//}} - -void CWaveGraph::CopyFullPixmap() -{ -// if(m_pWaveShow) -// m_pWaveShow->CopyFullPixmap(); -} - -void CWaveGraph::PrintSetup() -{ -// if(m_pWaveShow) m_pWaveShow->PrintSetup(); -} - -void CWaveGraph::Print() -{ - if(m_pWaveShow) m_pWaveShow->Print(); -} - -void CWaveGraph::PrintPreview() -{ - if(m_pWaveShow) m_pWaveShow->PrintPreview(); -} - -void CWaveGraph::MoveTo(int x, int y) -{ - if(m_pWaveShow) m_pWaveShow->move(x,y); -} - -void CWaveGraph::ReSize(const QSize &size) -{ - if(m_pWaveShow) m_pWaveShow->ReSize(size); -} - -void CWaveGraph::RedrawZone(int i , bool bErase) -{ - if(m_pWaveShow) m_pWaveShow->redrawWindow(i,bErase); -} - -void CWaveGraph::SetZoomState( int nState ) -{ - if(m_pWaveShow) m_pWaveShow->SetZoomState(nState); -} - -void CWaveGraph::ZoomInX() -{ - if(m_pWaveShow) m_pWaveShow->ZoomInX(); -} - -void CWaveGraph::ZoomOutX() -{ - if(m_pWaveShow) m_pWaveShow->ZoomOutX(); -} - -void CWaveGraph::ZoomInAnalogueY() -{ - if(m_pWaveShow) m_pWaveShow->ZoomInAnalogueY(); -} - -void CWaveGraph::ZoomOutAnalogueY() -{ - if(m_pWaveShow) m_pWaveShow->ZoomOutAnalogueY(); -} - -void CWaveGraph::ZoomInDigitalY() -{ - if(m_pWaveShow) m_pWaveShow->ZoomInDigitalY(); -} - -void CWaveGraph::ZoomOutDigitalY() -{ - if(m_pWaveShow) m_pWaveShow->ZoomOutDigitalY(); -} - -void CWaveGraph::ZoomInName() -{ - if(m_pWaveShow) m_pWaveShow->ZoomInName(); -} - -void CWaveGraph::ZoomOutName() -{ - if(m_pWaveShow) m_pWaveShow->ZoomOutName(); -} - -int CWaveGraph::GetCurAnaChannel() -{ - if(m_pWaveShow) return m_pWaveShow->GetCurAnaChannel(); - return -1; -} - -int CWaveGraph::GetCurDgtChannel() -{ - if(m_pWaveShow) return m_pWaveShow->GetCurDgtChannel(); - return -1; -} - -void CWaveGraph::SetValueType( int nType ) -{ - if(m_pWaveShow) - m_pWaveShow->SetValueType( nType ); -} - -void CWaveGraph::OnMoveStepLeft() -{ - if(m_pWaveShow) - m_pWaveShow->OnMoveStepLeft(); -} - -void CWaveGraph::OnMoveStepRight() -{ - if(m_pWaveShow) - m_pWaveShow->OnMoveStepRight(); -} - -void CWaveGraph::ZoomFull() -{ - if(m_pWaveShow) - m_pWaveShow->ZoomFull(); -} - -void CWaveGraph::ResumeZoom() -{ - if(m_pWaveShow) - { - m_pWaveShow->m_pWaveFile->m_DispAttr.ResumeCollocation(); - m_pWaveShow->ResumeZoom(); - } -} - -void CWaveGraph::OnResumeGroup() -{ - if(m_pWaveShow) - m_pWaveShow->OnResumeGroup(); -} - -void CWaveGraph::showStatus() -{ - triggerLabel->setText(QString("%1: %2").arg(tr("Trigger Line")).arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fTriggerTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); - startLabel->setText(QString("%1: %2").arg(tr("Line B")).arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fBaseTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); - endLabel->setText(QString("%1: %2").arg(tr("Line C")).arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fStaticTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); - diffLabel->setText(QString("Delta: %1ms").arg(m_pWaveShow->m_pWaveFile->m_DispAttr.m_fStaticTime - m_pWaveShow->m_pWaveFile->m_DispAttr.m_fBaseTime)); - statusLabel->setText("OK!"); -} - -void CWaveGraph::ShowAllTags() -{ - if(m_pWaveShow) - m_pWaveShow->ShowAllTags(); -} - -void CWaveGraph::ShowActionTags() -{ - if(m_pWaveShow) - m_pWaveShow->ShowActionTags(); -} - -void CWaveGraph::ShowNoneTags() -{ - if(m_pWaveShow) - m_pWaveShow->ShowNoneTags(); -} - -void CWaveGraph::setLineValueType( int nType ) -{ - if(m_pWaveShow) - m_pWaveShow->setLineValueType(nType); -} - +#include +#include "CWaveGraph.h" +#include "CWaveShow.h" + +CWaveGraph::CWaveGraph(QWidget *parent,Qt::WindowFlags f) + : QWidget(parent,f) +{ + m_pWaveShow = new CWaveShow(parent); + m_pWaveShow->SetComtradeData(m_pWaveFile); + + connect(m_pWaveShow,SIGNAL(StatusEmited()),this,SLOT(showStatus())); + + triggerLabel = new QLabel(); + startLabel = new QLabel(); + endLabel = new QLabel(); + statusLabel = new QLabel(); + diffLabel = new QLabel(); + statusLabel->setFixedWidth(50); + statusLabel->setAlignment(Qt::AlignRight); + + triggerLabel->setFrameShape(QFrame::NoFrame); + triggerLabel->setFrameShadow(QFrame::Plain); + startLabel->setFrameShape(QFrame::NoFrame); + startLabel->setFrameShadow(QFrame::Plain); + endLabel->setFrameShape(QFrame::NoFrame); + endLabel->setFrameShadow(QFrame::Plain); + statusLabel->setFrameShape(QFrame::NoFrame); + statusLabel->setFrameShadow(QFrame::Plain); + diffLabel->setFrameShape(QFrame::NoFrame); + diffLabel->setFrameShadow(QFrame::Plain); + + QHBoxLayout * hLayout = new QHBoxLayout; + hLayout->addWidget(triggerLabel); + hLayout->addWidget(startLabel); + hLayout->addWidget(endLabel); + hLayout->addWidget(diffLabel); + hLayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding)); + hLayout->addWidget(statusLabel); + QVBoxLayout * vLayout = new QVBoxLayout; + vLayout->addWidget(m_pWaveShow); + vLayout->addLayout(hLayout); + vLayout->setStretch(0,1); + vLayout->setMargin(0); + setLayout(vLayout); + + triggerLabel->setText(tr("Trigger Line") + ": ");//触发线 + startLabel->setText(tr("Line B") + ": "); + endLabel->setText(tr("Line C") + ": "); + diffLabel->setText("Delta:ms"); +} + +CWaveGraph::~CWaveGraph() +{ + +} + + +//##ModelId=4034009102B7 +bool CWaveGraph::SetComtradeData(CComtradeFile& pComtradeData) +{ + if(m_pWaveShow) + { + m_pWaveFile = pComtradeData; + setWindowTitle(m_pWaveFile.m_sFileName); + return m_pWaveShow->SetComtradeData(pComtradeData); + } + return false; +} + +void CWaveGraph::showComtradeFile() +{ + m_pWaveShow->SetComtradeData(m_pWaveFile); +} + +//##ModelId=403401F301CC +bool CWaveGraph::SetShowAttribute( CSectionList& pAttrList) +{ + Q_UNUSED(pAttrList) + return true; +} + +bool CWaveGraph::EditAnaGroup() +{ +// if(m_pWaveShow) return m_pWaveShow->EditAnaGroup(); + return false; +} + +bool CWaveGraph::EditDgtGroup() +{ +// if(m_pWaveShow) return m_pWaveShow->EditDgtGroup(); + return false; +} + +bool CWaveGraph::EditAnaTable() +{ +// if(m_pWaveShow) return m_pWaveShow->EditAnaTable(); + return false; +} + +bool CWaveGraph::EditDgtTable() +{ +// if(m_pWaveShow) return m_pWaveShow->EditDgtTable(); + return false; +} + +bool CWaveGraph::EditGridSet() +{ +// if(m_pWaveShow) return m_pWaveShow->EditGridSet(); + return false; +} + +bool CWaveGraph::EditSelectLine() +{ + if(m_pWaveShow) return m_pWaveShow->EditSelectLine(); + return false; +} + +bool CWaveGraph::EditSelectColor() +{ + if(m_pWaveShow) return m_pWaveShow->EditSelectColor(); + return false; +} + +//##ModelId=4034037702B7 +bool CWaveGraph::GetShowAttribute( CSectionList& pAttrList) +{ + Q_UNUSED(pAttrList) + return true; +} + +//##ModelId=4034051400C3 +bool CWaveGraph::IsDispAttrModified() +{ + return true; +} + +int CWaveGraph::GetCursorTicks() +{ + if(m_pWaveShow) + return m_pWaveShow->GetCursorTicks(); + return 0; +} + +//##ModelId=4039BE8503AB +int CWaveGraph::GetLabelAmount() +{ + return true; +} + +//##ModelId=4039BE8C0188 +void CWaveGraph::GetLabel() +{ +} + +//##ModelId=4039BE9001A7 +void CWaveGraph::AddLabel() +{ +// if(m_pWaveShow) +// m_pWaveShow->AddLabel(); +} + +//##ModelId=4039BE960159 +void CWaveGraph::ModifyLabel() +{ + +} + +//##ModelId=4039BE9A0272 +void CWaveGraph::DeleteLabel() +{ +} + +//##ModelId=4039BF0D00C9 +void CWaveGraph::ShowLabel() +{ +// if(m_pWaveShow) +// m_pWaveShow->ShowLabels(); +} + +void CWaveGraph::SetZoon() +{ +// if(m_pWaveShow) +// m_pWaveShow->SetZoon(); +} + +void CWaveGraph::CancelZone() +{ + if(m_pWaveShow) + m_pWaveShow->OnCacelZone(); +} + +void CWaveGraph::CopySelectPixmap() +{ +// if(m_pWaveShow) +// m_pWaveShow->CopySelectPixmap(); +} + +void CWaveGraph::CopyZonePixmap() +{ +// if(m_pWaveShow) +// m_pWaveShow->CopyZonePixmap(); +} + +//{{ Add by qizhong +void CWaveGraph::copyZonepixmapToFile() +{ + if(m_pWaveShow) + m_pWaveShow->copyZonepixmapToFile(); +} +//}} + +void CWaveGraph::CopyFullPixmap() +{ +// if(m_pWaveShow) +// m_pWaveShow->CopyFullPixmap(); +} + +void CWaveGraph::PrintSetup() +{ +// if(m_pWaveShow) m_pWaveShow->PrintSetup(); +} + +void CWaveGraph::Print() +{ + if(m_pWaveShow) m_pWaveShow->Print(); +} + +void CWaveGraph::PrintPreview() +{ + if(m_pWaveShow) m_pWaveShow->PrintPreview(); +} + +void CWaveGraph::MoveTo(int x, int y) +{ + if(m_pWaveShow) m_pWaveShow->move(x,y); +} + +void CWaveGraph::ReSize(const QSize &size) +{ + if(m_pWaveShow) m_pWaveShow->ReSize(size); +} + +void CWaveGraph::RedrawZone(int i , bool bErase) +{ + if(m_pWaveShow) m_pWaveShow->redrawWindow(i,bErase); +} + +void CWaveGraph::SetZoomState( int nState ) +{ + if(m_pWaveShow) m_pWaveShow->SetZoomState(nState); +} + +void CWaveGraph::ZoomInX() +{ + if(m_pWaveShow) m_pWaveShow->ZoomInX(); +} + +void CWaveGraph::ZoomOutX() +{ + if(m_pWaveShow) m_pWaveShow->ZoomOutX(); +} + +void CWaveGraph::ZoomInAnalogueY() +{ + if(m_pWaveShow) m_pWaveShow->ZoomInAnalogueY(); +} + +void CWaveGraph::ZoomOutAnalogueY() +{ + if(m_pWaveShow) m_pWaveShow->ZoomOutAnalogueY(); +} + +void CWaveGraph::ZoomInDigitalY() +{ + if(m_pWaveShow) m_pWaveShow->ZoomInDigitalY(); +} + +void CWaveGraph::ZoomOutDigitalY() +{ + if(m_pWaveShow) m_pWaveShow->ZoomOutDigitalY(); +} + +void CWaveGraph::ZoomInName() +{ + if(m_pWaveShow) m_pWaveShow->ZoomInName(); +} + +void CWaveGraph::ZoomOutName() +{ + if(m_pWaveShow) m_pWaveShow->ZoomOutName(); +} + +int CWaveGraph::GetCurAnaChannel() +{ + if(m_pWaveShow) return m_pWaveShow->GetCurAnaChannel(); + return -1; +} + +int CWaveGraph::GetCurDgtChannel() +{ + if(m_pWaveShow) return m_pWaveShow->GetCurDgtChannel(); + return -1; +} + +void CWaveGraph::SetValueType( int nType ) +{ + if(m_pWaveShow) + m_pWaveShow->SetValueType( nType ); +} + +void CWaveGraph::OnMoveStepLeft() +{ + if(m_pWaveShow) + m_pWaveShow->OnMoveStepLeft(); +} + +void CWaveGraph::OnMoveStepRight() +{ + if(m_pWaveShow) + m_pWaveShow->OnMoveStepRight(); +} + +void CWaveGraph::ZoomFull() +{ + if(m_pWaveShow) + m_pWaveShow->ZoomFull(); +} + +void CWaveGraph::ResumeZoom() +{ + if(m_pWaveShow) + { + m_pWaveShow->m_pWaveFile->m_DispAttr.ResumeCollocation(); + m_pWaveShow->ResumeZoom(); + } +} + +void CWaveGraph::OnResumeGroup() +{ + if(m_pWaveShow) + m_pWaveShow->OnResumeGroup(); +} + +void CWaveGraph::showStatus() +{ + triggerLabel->setText(QString("%1: %2").arg(tr("Trigger Line")).arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fTriggerTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); + startLabel->setText(QString("%1: %2").arg(tr("Line B")).arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fBaseTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); + endLabel->setText(QString("%1: %2").arg(tr("Line C")).arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fStaticTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); + diffLabel->setText(QString("Delta: %1ms").arg(m_pWaveShow->m_pWaveFile->m_DispAttr.m_fStaticTime - m_pWaveShow->m_pWaveFile->m_DispAttr.m_fBaseTime)); + statusLabel->setText("OK!"); +} + +void CWaveGraph::ShowAllTags() +{ + if(m_pWaveShow) + m_pWaveShow->ShowAllTags(); +} + +void CWaveGraph::ShowActionTags() +{ + if(m_pWaveShow) + m_pWaveShow->ShowActionTags(); +} + +void CWaveGraph::ShowNoneTags() +{ + if(m_pWaveShow) + m_pWaveShow->ShowNoneTags(); +} + +void CWaveGraph::setLineValueType( int nType ) +{ + if(m_pWaveShow) + m_pWaveShow->setLineValueType(nType); +} + diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveGraph.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveGraph.h index f9277455..7c0b4679 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveGraph.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveGraph.h @@ -1,137 +1,137 @@ -#ifndef CWAVEGRAPH_H_HEADER_INCLUDED_BFC4519F -#define CWAVEGRAPH_H_HEADER_INCLUDED_BFC4519F - -#include -#include -#include -#include -#include -#include -#include "datastruct.h" -#include "CComDataClass.h" - -const int WAVE_LEFTMARGIN = 120; -const int WAVE_TIMEAXISHEIGHT = 50/*55*/; -//const int WAVE_STATUSHEIGHT = 65; -const int WAVE_STATUSHEIGHT = 0; - -const int SPLITTERWIDTH = 3; - -const int SCROLLBAR_H_LINE = 100; -const int SCROLLBAR_V_LINE = 100; - -class CWaveShow; -//##ModelId=4034005C0372 -class CWaveGraph : public QWidget -{ - Q_OBJECT - -public: - CWaveGraph(QWidget *parent,Qt::WindowFlags f = 0); - ~CWaveGraph(); -public: - CComtradeFile m_pWaveFile; - CWaveShow *m_pWaveShow; - - QLabel *startLabel; - QLabel *endLabel; - QLabel *statusLabel; - QLabel *diffLabel; - QLabel *triggerLabel; - -public: - //##ModelId=4034009102B7 - //##Documentation - //## 设置COMTRADE文件类型的数据,包括.CFG和.DAT的所有数据及属性. - bool SetComtradeData(CComtradeFile& pComtradeData); - void showComtradeFile(); - - QWidget* GetWidget(){ return (QWidget*)m_pWaveShow;} - //##ModelId=403401F301CC - bool SetShowAttribute( CSectionList& pAttrList); - //##ModelId=4034037702B7 - bool GetShowAttribute( CSectionList& pAttrList); - - bool EditAnaGroup(); - bool EditDgtGroup(); - bool EditAnaTable(); - bool EditDgtTable(); - bool EditGridSet(); - bool EditSelectLine(); - bool EditSelectColor(); - - void SetZoomState( int nState ); - - int GetCursorTicks(); - - //##ModelId=4034051400C3 - bool IsDispAttrModified(); - - //##ModelId=4039BE8503AB - int GetLabelAmount(); - - //##ModelId=4039BE8C0188 - void GetLabel(); - - //##ModelId=4039BE9001A7 - void AddLabel(); - - //##ModelId=4039BE960159 - void ModifyLabel(); - - //##ModelId=4039BE9A0272 - void DeleteLabel(); - - //##ModelId=4039BF0D00C9 - - int GetCurAnaChannel(); - int GetCurDgtChannel(); - - void ShowLabel(); - void SetZoon(); - void CancelZone(); - void CopySelectPixmap(); //选择抓图复制 - void CopyZonePixmap(); //区域复制 - //{{ Add by qizhong - void copyZonepixmapToFile(); - //}} - void CopyFullPixmap(); //全部复制 - // - void PrintSetup(); - void Print(); - void PrintPreview(); - // - void ZoomInX(); - void ZoomOutX(); - void ZoomInAnalogueY(); - void ZoomOutAnalogueY(); - void ZoomInDigitalY(); - void ZoomOutDigitalY(); - void ZoomInName(); - void ZoomOutName(); - void ZoomFull(); - void ResumeZoom(); - void OnResumeGroup(); - //0-raw,1-primary,2-secondry - void SetValueType( int nType ); - void OnMoveStepLeft(); - void OnMoveStepRight(); - - void MoveTo(int x, int y); - void ReSize(const QSize &); - /*重绘区域*/ - void RedrawZone(int i , bool bErase = true); - - void ShowAllTags(); - void ShowActionTags(); - void ShowNoneTags(); - void setLineValueType(int nType); - -public slots: - void showStatus(); - -}; - - - -#endif /* CWAVEGRAPH_H_HEADER_INCLUDED_BFC4519F */ +#ifndef CWAVEGRAPH_H_HEADER_INCLUDED_BFC4519F +#define CWAVEGRAPH_H_HEADER_INCLUDED_BFC4519F + +#include +#include +#include +#include +#include +#include +#include "datastruct.h" +#include "CComDataClass.h" + +const int WAVE_LEFTMARGIN = 120; +const int WAVE_TIMEAXISHEIGHT = 50/*55*/; +//const int WAVE_STATUSHEIGHT = 65; +const int WAVE_STATUSHEIGHT = 0; + +const int SPLITTERWIDTH = 3; + +const int SCROLLBAR_H_LINE = 100; +const int SCROLLBAR_V_LINE = 100; + +class CWaveShow; +//##ModelId=4034005C0372 +class CWaveGraph : public QWidget +{ + Q_OBJECT + +public: + CWaveGraph(QWidget *parent,Qt::WindowFlags f = 0); + ~CWaveGraph(); +public: + CComtradeFile m_pWaveFile; + CWaveShow *m_pWaveShow; + + QLabel *startLabel; + QLabel *endLabel; + QLabel *statusLabel; + QLabel *diffLabel; + QLabel *triggerLabel; + +public: + //##ModelId=4034009102B7 + //##Documentation + //## 设置COMTRADE文件类型的数据,包括.CFG和.DAT的所有数据及属性. + bool SetComtradeData(CComtradeFile& pComtradeData); + void showComtradeFile(); + + QWidget* GetWidget(){ return (QWidget*)m_pWaveShow;} + //##ModelId=403401F301CC + bool SetShowAttribute( CSectionList& pAttrList); + //##ModelId=4034037702B7 + bool GetShowAttribute( CSectionList& pAttrList); + + bool EditAnaGroup(); + bool EditDgtGroup(); + bool EditAnaTable(); + bool EditDgtTable(); + bool EditGridSet(); + bool EditSelectLine(); + bool EditSelectColor(); + + void SetZoomState( int nState ); + + int GetCursorTicks(); + + //##ModelId=4034051400C3 + bool IsDispAttrModified(); + + //##ModelId=4039BE8503AB + int GetLabelAmount(); + + //##ModelId=4039BE8C0188 + void GetLabel(); + + //##ModelId=4039BE9001A7 + void AddLabel(); + + //##ModelId=4039BE960159 + void ModifyLabel(); + + //##ModelId=4039BE9A0272 + void DeleteLabel(); + + //##ModelId=4039BF0D00C9 + + int GetCurAnaChannel(); + int GetCurDgtChannel(); + + void ShowLabel(); + void SetZoon(); + void CancelZone(); + void CopySelectPixmap(); //选择抓图复制 + void CopyZonePixmap(); //区域复制 + //{{ Add by qizhong + void copyZonepixmapToFile(); + //}} + void CopyFullPixmap(); //全部复制 + // + void PrintSetup(); + void Print(); + void PrintPreview(); + // + void ZoomInX(); + void ZoomOutX(); + void ZoomInAnalogueY(); + void ZoomOutAnalogueY(); + void ZoomInDigitalY(); + void ZoomOutDigitalY(); + void ZoomInName(); + void ZoomOutName(); + void ZoomFull(); + void ResumeZoom(); + void OnResumeGroup(); + //0-raw,1-primary,2-secondry + void SetValueType( int nType ); + void OnMoveStepLeft(); + void OnMoveStepRight(); + + void MoveTo(int x, int y); + void ReSize(const QSize &); + /*重绘区域*/ + void RedrawZone(int i , bool bErase = true); + + void ShowAllTags(); + void ShowActionTags(); + void ShowNoneTags(); + void setLineValueType(int nType); + +public slots: + void showStatus(); + +}; + + + +#endif /* CWAVEGRAPH_H_HEADER_INCLUDED_BFC4519F */ diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveShow.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveShow.cpp index 518406dd..8a43f2c7 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveShow.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveShow.cpp @@ -1,2841 +1,2841 @@ -#include "CWaveShow.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CPublic.h" -#include -#include -#include -#include -#include -#include "stdlib.h" -#include -#include -//#include "cprintsetupdlg.h" -//#include "clabelsetdlg.h" -//#include "clabelbrowser.h" -#include "CPrintPreview.h" -//#include "czoomsetdlg.h" -//#include "cstylesetdialog.h" -//#include "canagroupset.h" -//#include "cdgtgroupset.h" -//#include "canatableset.h" -//#include "cdgttableset.h" -//#include "cgridset.h" -//#include "ccopywaveset.h" -///////////////////////////////////////////////////// -CWaveShow::CWaveShow(QWidget *parent, Qt::WindowFlags f ) - :QFrame(parent,f) -{ - printer = 0; - m_pRectBand = 0; - m_pVLineBand = 0; - m_pHLineBand = 0; - setWindowFlag( Qt::WindowStaysOnTopHint ); - setMouseTracking(true); - -// QPalette p = palette(); -// p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_statusBackColor); -// setPalette(p); -// setAutoFillBackground(true); - -// setFrameShape( QFrame::WinPanel ); -// setFrameShadow( QFrame::Sunken ); - //{{hor scroll -// QVBoxLayout* vboxLayout = new QVBoxLayout(this); -// vboxLayout->setSpacing(0); -// vboxLayout->setContentsMargins(0, 0, 0, 0); -// -// QSpacerItem* spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); -// horiz_bar = new QScrollBar(Qt::Horizontal,this); -// vboxLayout->addItem(spacerItem); -// vboxLayout->addWidget( horiz_bar ); -// -// horiz_bar->setRange(0,0); -// horiz_bar->setSingleStep(SCROLLBAR_H_LINE); -// horiz_bar->setPageStep(SCROLLBAR_H_LINE*5); -// horiz_bar->setTracking(false); - //}} - - m_bOnYMoveBar = false; - m_bOnXMoveBar = false; - m_nLastYPos = 0; - m_nLastXPos = 0; - m_nCursorX = -1; - m_nZoomState = SINGLEZOOM_NULL; - - m_bZoomStart = false; - - moveleftAction = new QAction( "moveleftAction",this ); - moveleftAction->setShortcut(QKeySequence(Qt::Key_Left)); - moverightAction = new QAction( "moverightAction",this ); - moverightAction->setShortcut( QKeySequence(Qt::Key_Right) ); - - connect( moveleftAction, SIGNAL( triggered(bool) ), this, SLOT( OnMoveStepLeft() ) ); - connect( moverightAction, SIGNAL( triggered(bool) ), this, SLOT( OnMoveStepRight() ) ); - connect( this,SIGNAL( ZoomSelected() ), this, SLOT( OnZoomSelected() ) ); - - m_hArrowCursor.setShape(Qt::ArrowCursor); - m_hUpDownCursor.setShape(Qt::SplitVCursor); - m_hLeftRightCursor.setShape(Qt::SplitHCursor); - - m_hCrossCursor.setShape(Qt::CrossCursor); - m_hHandCursor.setShape(Qt::PointingHandCursor); - - m_hZoomIn = QCursor( QPixmap(":/images/zoomin.xpm") ); - m_hZoomOut = QCursor( QPixmap(":/images/zoomout.xpm") ); - m_hZoomRect = QCursor( QPixmap(":ico/ico/zoomrect.xpm") ); - - m_pWaveFile = 0L; - - m_pAnalogueView = new CAnalogueShow(this); - m_pDigitalView = new CDigitalShow(this); - m_pAnaAxisView = new CAnaAxisShow(this); - m_pDgtNameView = new CDgtNameShow(this); -// m_pTimeAxisView = new CTimeAxisShow(this,horiz_bar); - m_pTimeAxisView = new CTimeAxisShow(this,0); -// m_pStatusView = new CStatusShow(this); - m_pLinStatusView = new CLineStatusShow(this); - - //resize(QSize(600,700).expandedTo(minimumSizeHint())); - resize(QSize(400,300).expandedTo(minimumSizeHint())); - setMinimumSize(QSize(400,300)); - m_fWaveHeightRate = 0.75f; - m_nLeftMargin = WAVE_LEFTMARGIN; -// m_nLeftMargin = 300; - //m_nLeftMargin = CWaveEnv::GetInst()->m_nLeftMarginName; -// m_nTimeViewTop = 700 - WAVE_TIMEAXISHEIGHT - WAVE_STATUSHEIGHT; - m_nTimeViewTop = 300 - WAVE_TIMEAXISHEIGHT - WAVE_STATUSHEIGHT; - m_nTimeViewHgt = WAVE_TIMEAXISHEIGHT; - m_nWaveViewTop = 0; - m_nWaveViewHgt = m_nTimeViewTop*m_fWaveHeightRate; - m_nMinViewHgt = 0; - - m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; - m_nTagsViewHgt = m_nTimeViewTop - m_nTagsViewTop; - - RecacuAreas(); - - m_bPixmapCapturePt1 = false; - m_bPixmapCaptureStart = false; - m_pCapturePt1 = QPoint(0,0); - m_pCapturePt2 = QPoint(0,0); - m_ptSelectLastPt = QPoint(0,0); - - installEventFilter( this ); - m_pAnalogueView->installEventFilter( this ); - m_pDigitalView->installEventFilter( this ); - m_pTimeAxisView->installEventFilter( this ); - // - m_PrintAttr.bOrient = true; - m_PrintAttr.bLinePrint = false; - m_PrintAttr.bAnaPrint = true; - m_PrintAttr.bColor = true; - m_PrintAttr.bDgtPrint = true; - m_PrintAttr.bNamePrint = true; - m_PrintAttr.bTimePrint = true; - m_PrintAttr.bTitlePrint = true; - m_PrintAttr.bZonePrint = false; - m_PrintAttr.dBottomMargin = 20.0; - m_PrintAttr.dLeftMargin = 20.0; - m_PrintAttr.dRightMargin = 20.0; - m_PrintAttr.dTopMargin = 20.0; -} - -CWaveShow::~CWaveShow() -{ - if(printer) - delete printer; - printer = 0; -} - -void CWaveShow::RecacuAreas() -{ - QSize s = frameSize(); - - if( m_pWaveFile ) - { - m_nLeftMargin = m_pWaveFile->m_DispAttr.m_nLeftMargin; - if( m_nLeftMargin<50 ) - m_nLeftMargin = 50; - } - else - { - m_nLeftMargin = WAVE_LEFTMARGIN; - } - - m_nLeftMargin = CWaveEnv::GetInst()->m_nLeftMarginName; - double nMainHeight = s.height() - WAVE_TIMEAXISHEIGHT; - //时标top,height - m_nTimeViewTop = nMainHeight; - m_nTimeViewHgt = WAVE_TIMEAXISHEIGHT; - if(m_pWaveFile) - { - if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWNONE) - { - //模拟量top,height - m_nWaveViewTop = 0; - m_nWaveViewHgt = nMainHeight; - //数字量top,height - m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; - m_nTagsViewHgt = nMainHeight - m_nTagsViewTop; - } - else - { - //模拟量top,height - m_nWaveViewTop = 0; - m_nWaveViewHgt = nMainHeight*m_fWaveHeightRate; - //数字量top,height - m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; - m_nTagsViewHgt = nMainHeight - m_nTagsViewTop; - } - } - else - { - //模拟量top,height - m_nWaveViewTop = 0; - m_nWaveViewHgt = nMainHeight*m_fWaveHeightRate; - //数字量top,height - m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; - m_nTagsViewHgt = nMainHeight - m_nTagsViewTop; - } - - /*//{{ - m_nTimeViewTop = CWaveEnv::GetInst()->m_nTimeViewTop1; - m_nTimeViewHgt = CWaveEnv::GetInst()->m_nTimeViewHgt1; - - m_nWaveViewTop = CWaveEnv::GetInst()->m_nWaveViewTop1; - m_nWaveViewHgt = CWaveEnv::GetInst()->m_nWaveViewHgt1; - m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; - m_nTagsViewHgt = nMainHeight - m_nTagsViewTop; - //}}*/ - MoveAllViews(); -} - -void CWaveShow::MoveAllViews() -{ - QSize s = frameSize(); - - //ana name - QRect rc1(0,m_nWaveViewTop,m_nLeftMargin,m_nWaveViewHgt); - //ana show - QRect rc2(m_nLeftMargin+SPLITTERWIDTH,m_nWaveViewTop,s.width() - m_nLeftMargin -SPLITTERWIDTH,m_nWaveViewHgt); - //dgt name - QRect rc3(0,m_nTagsViewTop+SPLITTERWIDTH,m_nLeftMargin,m_nTagsViewHgt-SPLITTERWIDTH); - //dgt show - QRect rc4(m_nLeftMargin+SPLITTERWIDTH,m_nTagsViewTop+SPLITTERWIDTH,s.width() - m_nLeftMargin -SPLITTERWIDTH,m_nTagsViewHgt-SPLITTERWIDTH); -// QRect rc5(0,m_nTimeViewTop+SPLITTERWIDTH,s.width(),WAVE_TIMEAXISHEIGHT-SPLITTERWIDTH); -// QRect rc6(0,m_nTimeViewTop+WAVE_TIMEAXISHEIGHT+SPLITTERWIDTH,s.width(),WAVE_STATUSHEIGHT-SPLITTERWIDTH -20); - //time - QRect rc5(m_nLeftMargin+SPLITTERWIDTH,m_nTimeViewTop+1/*+SPLITTERWIDTH*/,s.width() - m_nLeftMargin -SPLITTERWIDTH,WAVE_TIMEAXISHEIGHT-1/*-SPLITTERWIDTH*/); - //status - QRect rc6(0,m_nTimeViewTop+1/*+SPLITTERWIDTH*/,m_nLeftMargin,WAVE_TIMEAXISHEIGHT-1/*-SPLITTERWIDTH*/); - - m_pAnaAxisView->setGeometry(rc1); - m_pAnaAxisView->update(); - m_pAnalogueView->setGeometry(rc2); - m_pAnalogueView->update(); - m_pDgtNameView->setGeometry(rc3); - m_pDgtNameView->update(); - m_pDigitalView->setGeometry(rc4); - m_pDigitalView->update(); - m_pTimeAxisView->setGeometry(rc5); - m_pTimeAxisView->update(); - m_pLinStatusView->setGeometry(rc6); - m_pLinStatusView->update(); - - update(); - - CWaveEnv::GetInst()->m_nLeftMarginName = m_nLeftMargin; - - CWaveEnv::GetInst()->m_nTimeViewTop1 = m_nTimeViewTop; - CWaveEnv::GetInst()->m_nTimeViewHgt1 = m_nTimeViewHgt; - CWaveEnv::GetInst()->m_nWaveViewTop1 = m_nWaveViewTop; - CWaveEnv::GetInst()->m_nWaveViewHgt1 = m_nWaveViewHgt; - CWaveEnv::GetInst()->m_nTagsViewTop1 = m_nTagsViewTop; - CWaveEnv::GetInst()->m_nTagsViewHgt1 = m_nTagsViewHgt; - - CWaveEnv::GetInst()->SaveZoomSet(); - -} -////////////////////////////////////////////////////////////////////////// -bool CWaveShow::eventFilter( QObject* obj,QEvent* e ) -{ - if( e->type() == QEvent::MouseMove ) - { - QMouseEvent* mev = (QMouseEvent*)e; - if( obj == this ) - OnMouseMoveEvent( mev ); - if( m_nZoomState==ZOOMRECT_X ) - mev->ignore(); - if( obj == m_pAnalogueView && mev->isAccepted() ) - m_pAnalogueView->OnMouseMoveEvent(mev); - if( obj == m_pDigitalView && mev->isAccepted() ) - m_pDigitalView->OnMouseMoveEvent(mev); - if( obj == m_pTimeAxisView && mev->isAccepted() ) - m_pTimeAxisView->OnMouseMoveEvent(mev); - } - else if(e->type() == QEvent::MouseButtonPress) - { - QMouseEvent* mev = (QMouseEvent*)e; - if( obj == this ) - OnMousePressEvent( mev ); - if( m_nZoomState==ZOOMRECT_X ) - mev->ignore(); - - if( obj == m_pAnalogueView && mev->isAccepted() ) - m_pAnalogueView->OnMousePressEvent(mev); - if( obj == m_pDigitalView && mev->isAccepted() ) - m_pDigitalView->OnMousePressEvent(mev); - if( obj == m_pTimeAxisView && mev->isAccepted() ) - m_pTimeAxisView->OnMousePressEvent(mev); - } - else if(e->type() == QEvent::MouseButtonRelease) - { - QMouseEvent* mev = (QMouseEvent*)e; - if( obj == this ) - OnMouseReleaseEvent( mev ); - if( m_nZoomState==ZOOMRECT_X ) - mev->ignore(); - if( obj == m_pAnalogueView && mev->isAccepted() ) - m_pAnalogueView->OnMouseReleaseEvent(mev); - if( obj == m_pDigitalView && mev->isAccepted() ) - m_pDigitalView->OnMouseReleaseEvent(mev); - if( obj == m_pTimeAxisView && mev->isAccepted() ) - m_pTimeAxisView->OnMouseReleaseEvent(mev); - } - - return false; -} - -void CWaveShow::OnMousePressEvent( QMouseEvent *e ) -{ -////////////////////////////////////////////////////////////// - if ( e->button() == Qt::LeftButton ) { -/////////////////////////////////////////////////////////// - if(m_pWaveFile) - { - if(m_bPixmapCapturePt1) - { - m_pCapturePt1 = e->pos(); - if(m_pCapturePt1.x()m_nTimeViewTop) - m_pCapturePt1.ry() = m_nTimeViewTop - 1; - - m_ptSelectLastPt = m_pCapturePt1; - - - if (!m_pRectBand) - m_pRectBand = new QRubberBand(QRubberBand::Rectangle, this); - m_pRectBand->setGeometry(QRect(m_pCapturePt1,m_ptSelectLastPt)); - m_pRectBand->show(); - - m_bPixmapCaptureStart = true; - - } - else if( m_nZoomState==ZOOMRECT_X ) - { - m_ptZoomOld = e->pos(); - m_ptZoomNew = e->pos(); - m_bZoomStart = true; - - if (!m_pRectBand) - m_pRectBand = new QRubberBand(QRubberBand::Rectangle, this); - m_pRectBand->setGeometry(QRect(m_ptZoomOld,m_ptZoomNew)); - m_pRectBand->show(); - - e->ignore(); - } - else - { - - if((!m_bOnYMoveBar) - && (e->y() >= (m_nTagsViewTop-SPLITTERWIDTH) ) - && (e->y() < (m_nTagsViewTop+SPLITTERWIDTH)) ) - { - - setCursor( m_hUpDownCursor ); - m_bOnYMoveBar = true; - m_nLastYPos = e->y(); - - if( !m_pHLineBand ) - m_pHLineBand = new QRubberBand(QRubberBand::Line, this); - - int w = width(); - m_pHLineBand->setGeometry(QRect(0,m_nLastYPos, w,2)); - m_pHLineBand->show(); - } - else if((!m_bOnXMoveBar) - && (e->x() >= (m_nLeftMargin-SPLITTERWIDTH) ) - && (e->x() < (m_nLeftMargin+SPLITTERWIDTH) ) - &&e->y() < (m_nTimeViewTop+SPLITTERWIDTH) ) - { - setCursor( m_hLeftRightCursor ); - m_bOnXMoveBar = true; - m_nLastXPos = e->x(); - - if( !m_pVLineBand ) - m_pVLineBand = new QRubberBand(QRubberBand::Line, this); - - m_pVLineBand->setGeometry(QRect(m_nLastXPos,0,2,m_nTimeViewTop)); - m_pVLineBand->show(); - } - } - } -/////////////////////////////////////////////////////////////// - } -} - -void CWaveShow::OnMouseReleaseEvent( QMouseEvent *e ) -{ - if( e->button() == Qt::LeftButton ) - { -///////////////////////////////////////////////////////////////// - if(m_pWaveFile) - { - if(m_bPixmapCapturePt1) - { - m_bPixmapCapturePt1 = false; - m_bPixmapCaptureStart = false; - m_pCapturePt2 = e->pos(); - - if(m_pCapturePt2.x()m_nTimeViewTop) - m_pCapturePt2.ry() = m_nTimeViewTop - 1; - - copySelectToClip(); - if (m_pRectBand) - m_pRectBand->hide(); - - } - else if(m_bOnYMoveBar) - { - m_bOnYMoveBar = false; - - QRect rcClient; - rcClient = rect(); - -// int nTotalHgt = rcClient.height(); -// int nBarHeight = SPLITTERWIDTH; - - // Calcu Top - // - int nPos = m_nLastYPos+2; - if(nPos+m_nMinViewHgt > m_nTimeViewTop) - { - m_nTagsViewTop = m_nTimeViewTop - m_nMinViewHgt; - } - else if(nPos-m_nMinViewHgt < 0) - { - m_nTagsViewTop = m_nMinViewHgt; - } - else m_nTagsViewTop = nPos; - // Calcu Height - // - m_nTimeViewHgt = rcClient.bottom() - m_nTimeViewTop; - m_nTagsViewHgt = m_nTimeViewTop - m_nTagsViewTop; - m_nWaveViewHgt = m_nTagsViewTop - rcClient.top(); - m_fWaveHeightRate = (float)m_nWaveViewHgt/(float)(m_nWaveViewHgt+m_nTagsViewHgt); - if( m_pHLineBand ) - m_pHLineBand->hide(); - // Move Window - // - MoveAllViews(); - m_pAnalogueView->ResetVScrollSize(); - m_pDigitalView->ResetVScrollSize(); - } - else if(m_bOnXMoveBar) - { - m_bOnXMoveBar = false; - - m_nLeftMargin = m_nLastXPos; - - if( m_pVLineBand ) - m_pVLineBand->hide(); - // Move Window - // - MoveAllViews(); - m_pAnalogueView->ResetVScrollSize(); - m_pDigitalView->ResetVScrollSize(); - m_pTimeAxisView->ResetHScrollSize(); - } - else if( m_nZoomState==ZOOMRECT_X && m_bZoomStart ) - { - m_bZoomStart = false; - SetZoomState( SINGLEZOOM_NULL ); - - if (m_pRectBand) - m_pRectBand->hide(); - - e->ignore(); - emit ZoomSelected(); - } - - releaseMouse(); - setCursor( m_hArrowCursor ); - } -//////////////////////////////////////////////////// - } - else if( e->button() == Qt::RightButton ) - { - m_bZoomStart = false; - SetZoomState( SINGLEZOOM_NULL ); -//////////////////////////////////////////////////// - } -} - -void CWaveShow::OnMouseMoveEvent( QMouseEvent *e ) -{ -///////////////////////////////////////////////////////////////// - if(m_bPixmapCapturePt1 && m_bPixmapCaptureStart) - { - QPoint ptCur = e->pos(); - m_ptSelectLastPt = ptCur; - if(m_pRectBand) - m_pRectBand->setGeometry(QRect(m_pCapturePt1,m_ptSelectLastPt) ); - } - else if( m_nZoomState==ZOOMRECT_X && m_bZoomStart ) - { - m_ptZoomNew = e->pos(); - if(m_pRectBand) - m_pRectBand->setGeometry(QRect(m_ptZoomOld,m_ptZoomNew)); - e->ignore(); - return; - } - else if(m_bOnYMoveBar) - { - setCursor( m_hUpDownCursor ); - if(e->buttons() & Qt::LeftButton) - { - m_nLastYPos = e->y(); - int w = width(); - if( m_pHLineBand ) - m_pHLineBand->setGeometry(QRect(0,m_nLastYPos,w,2)); - } - else - { - m_bOnYMoveBar = false; - if( m_pHLineBand ) - m_pHLineBand->hide(); - setCursor( m_hArrowCursor ); - } - } - else if(m_bOnXMoveBar) - { - setCursor( m_hLeftRightCursor ); - if(e->buttons() & Qt::LeftButton) - { - m_nLastXPos = e->x(); - if( m_pVLineBand ) - m_pVLineBand->setGeometry(QRect(m_nLastXPos,0,2,m_nTimeViewTop+TIMEAXIS_HEIGHT+20)); - } - else - { - m_bOnXMoveBar = false; - if( m_pVLineBand ) - m_pVLineBand->hide(); - setCursor( m_hArrowCursor ); - } - } - else - { - if(e->y() >= m_nTagsViewTop - && e->y() < m_nTagsViewTop+SPLITTERWIDTH) - { - setCursor( m_hUpDownCursor ); - } - else if( e->x() >= m_nLeftMargin - && e->x() < (m_nLeftMargin+SPLITTERWIDTH) - && e->y() < (m_nTimeViewTop+SPLITTERWIDTH) ) - { - setCursor( m_hLeftRightCursor ); - } - else - { - setCursor( m_hArrowCursor ); - } - } -///////////////////////////////////////////////////// -// update(); -} - -void CWaveShow::paintEvent( QPaintEvent *e ) -{ - Q_UNUSED(e) - if( palette().color( QPalette::Background )!=CWaveEnv::GetInst()->m_WaveBackColor ) - { - QPalette palette; - palette.setColor(QPalette::Light, CWaveEnv::GetInst()->m_MoveLineColor); - palette.setColor(QPalette::Dark, CWaveEnv::GetInst()->m_MoveLineColor); - palette.setColor(QPalette::Mid, CWaveEnv::GetInst()->m_WaveBackColor); - palette.setColor(backgroundRole(), CWaveEnv::GetInst()->m_WaveBackColor); - setPalette(palette); - } - - QPainter paint; - paint.begin(this ); - DoDraw( &paint ); - paint.end(); - -} - -void CWaveShow::resizeEvent(QResizeEvent* event) -{ - RecacuAreas(); - m_pAnalogueView->ResetVScrollSize(); - m_pDigitalView->ResetVScrollSize(); - m_pTimeAxisView->ResetHScrollSize(); - QWidget::resizeEvent( event ); -} - -void CWaveShow::DoDraw( QPainter *paint ) -{ -// DrawXSplitterBar(paint, m_nLeftMargin,m_nTimeViewTop); - DrawXSplitterBar(paint, m_nLeftMargin,m_nTimeViewTop + WAVE_TIMEAXISHEIGHT + 20); - DrawYSplitterBar(paint, m_nTagsViewTop); - //DrawYSplitterBar(paint, m_nTimeViewTop); - //DrawYBottomSplitterBar(paint, m_nTimeViewTop); - - -// if( m_pStatusView ) -// m_pStatusView->Refresh(); -// if(m_pLinStatusView) -// m_pLinStatusView->Refresh(); - -} -void CWaveShow::PrintPageTitle(QPainter *paint,QString szTitle,int nPageNo) -{ - if(!m_pWaveFile) return; - QString szPage; - szPage.sprintf("Page %d",nPageNo); - QRect rect = paint->viewport(); - paint->drawText(rect,Qt::AlignLeft | Qt::TextSingleLine,szTitle); - paint->drawText(rect,Qt::AlignHCenter | Qt::TextSingleLine,szTitle); - -} -//////////////////////////////////////////////////////////////////////// -void CWaveShow::OnAddLabel() -{ -// AddLabel(); -} - -void CWaveShow::OnLabelList() -{ -// ShowLabels(); -} - -void CWaveShow::OnSetZoneStart() -{ - m_pWaveFile->m_DispAttr.m_fBaseTime = m_pWaveFile->m_DispAttr.m_fCurrentTime; - m_pWaveFile->m_DispAttr.m_fBaseTick = m_pWaveFile->m_DispAttr.m_fCurrentTick; - - m_pWaveFile->m_DispAttr.m_bShowZoon = true; - redrawWindow(1,false);//在名称去显示数据值,20090818 - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); - redrawWindow(7,false); - showStatus(); - m_pWaveFile->EmitLineBChanged(); -} - -void CWaveShow::OnSetZoneEnd() -{ - m_pWaveFile->m_DispAttr.m_bShowZoon = true; - redrawWindow(1,false);//在名称去显示数据值,20090818 - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); - redrawWindow(7,false); - showStatus(); - m_pWaveFile->EmitLineBChanged(); -} - -void CWaveShow::OnCacelZone() -{ - m_pWaveFile->m_DispAttr.m_fBaseTime = m_pWaveFile->m_nFrist_ms; - m_pWaveFile->m_DispAttr.m_fBaseTick = 0; - - m_pWaveFile->m_DispAttr.m_bShowZoon = false; - redrawWindow(1,false);//在名称去显示数据值,20090818 - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); - redrawWindow(7,false); - showStatus(); - m_pWaveFile->EmitLineBChanged(); -} - -void CWaveShow::OnAnaAmpSingleIn() -{ - int ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - m_pWaveFile->m_DispAttr.m_dWaveHeight[ch] += 5.0; - double dMax = m_pWaveFile->m_aChMaximumArray[ch]; - m_pWaveFile->m_DispAttr.m_fWaveZoom[ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[ch])*45.0 - /double(dMax); - redrawWindow(1,false); - redrawWindow(2,false); -} - -void CWaveShow::OnAnaAmpSingleOut() -{ - int ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - m_pWaveFile->m_DispAttr.m_dWaveHeight[ch] -= 5.0; - double dMax = m_pWaveFile->m_aChMaximumArray[ch]; - m_pWaveFile->m_DispAttr.m_fWaveZoom[ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[ch])*45.0 - /double(dMax); - redrawWindow(1,false); - redrawWindow(2,false); -} - -void CWaveShow::OnAnaAmpIn() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0 || Ch>=MAX_WAVES) - return; - double dMax = m_pWaveFile->m_aChMaximumArray[Ch]*(0.5); - m_pWaveFile->m_aChMaximumArray[Ch] = dMax ; - m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch])*45.0 - /double(dMax); - redrawWindow(1,false); - redrawWindow(2,false); - -} - -void CWaveShow::OnAnaAmpOut() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0 || Ch>=MAX_WAVES) - return; - double dMax = m_pWaveFile->m_aChMaximumArray[Ch]*(2.0); - m_pWaveFile->m_aChMaximumArray[Ch] = dMax ; - m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch])*45.0 - /double(dMax); - redrawWindow(1,false); - redrawWindow(2,false); -} - -void CWaveShow::OnAnaAmpSet() -{ - -} - -void CWaveShow::OnAnaAreaIn() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0 || Ch>=MAX_WAVES) - return; - - int nGroupNo = m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]; - for( Ch=0;Chm_nAnagueNum;Ch++ ) - { - if(m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]!=nGroupNo) continue; - - m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch] += 5.0; - m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[nGroupNo])*45.0 - /double(m_pWaveFile->m_aChMaximumArray[Ch]); - } - - m_pAnalogueView->ResetVScrollSize(); - - redrawWindow(1,false); - redrawWindow(2,false); -} - -void CWaveShow::OnAnaAreaOut() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0 || Ch>=MAX_WAVES) - return; - int nGroupNo = m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]; - for( Ch=0;Chm_nAnagueNum;Ch++ ) - { - if(m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]!=nGroupNo) continue; - - m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch] -= 5.0; - if(m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch] < 5.0) - m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch] = 5.0; - - m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[nGroupNo])*45.0 - /double(m_pWaveFile->m_aChMaximumArray[Ch]); - } - - m_pAnalogueView->ResetVScrollSize(); - - redrawWindow(1,false); - redrawWindow(2,false); -} - -void CWaveShow::OnAnaColorSet() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0 || Ch>=MAX_WAVES) - return; - QColor clrWave = m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch]; - QColor clrWaveNew = QColorDialog::getColor(clrWave,this); - if( clrWaveNew.isValid() && clrWaveNew != clrWave ) - { - m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch] = clrWaveNew; - redrawWindow(1,false); - redrawWindow(2,false); - } -} - -void CWaveShow::OnAnaLineSet() -{ -/* - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0 || Ch>=MAX_WAVES) - return; - - CStyleSetDialog dlg(this); - dlg.SetLineStyle( m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch],m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch] ); - dlg.Refresh(); - if( QDialog::Accepted == dlg.exec() ) - { - m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] = dlg.GetStyle(); - m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch] = dlg.GetWidth(); - redrawWindow(1,false); - redrawWindow(2,false); - } -*/ -} - -void CWaveShow::OnDgtColorSet() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; - if( Ch<0 || Ch>=MAX_TAGS) - return; - QColor clrTag = m_pWaveFile->m_DispAttr.m_dwTagsColor[Ch]; - QColor clrTagNew = QColorDialog::getColor(clrTag,this); - if( clrTagNew.isValid() && clrTagNew != clrTag ) - { - m_pWaveFile->m_DispAttr.m_dwTagsColor[Ch] = clrTagNew; - redrawWindow(3,false); - redrawWindow(4,false); - } -} - -void CWaveShow::OnDgtLineSet() -{ -/* - int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; - if( Ch<0 || Ch>=MAX_TAGS) - return; - - CStyleSetDialog dlg(this); - dlg.SetLineStyle( m_pWaveFile->m_DispAttr.m_nTagsLineStyle[Ch],m_pWaveFile->m_DispAttr.m_nTagsLineWidth[Ch] ); - dlg.Refresh(); - if( QDialog::Accepted == dlg.exec() ) - { - m_pWaveFile->m_DispAttr.m_nTagsLineStyle[Ch] = dlg.GetStyle(); - m_pWaveFile->m_DispAttr.m_nTagsLineWidth[Ch] = dlg.GetWidth(); - redrawWindow(3,false); - redrawWindow(4,false); - } -*/ -} - -void CWaveShow::OnMoveStepLeft() -{ - if( m_pWaveFile ) - { - m_pWaveFile->m_DispAttr.m_fStaticTick--; - if( m_pWaveFile->m_DispAttr.m_fStaticTick<0 ) - { - m_pWaveFile->m_DispAttr.m_fStaticTick = 0; - } - m_pWaveFile->m_DispAttr.m_fStaticTime = m_pWaveFile->GetPointTime(m_pWaveFile->m_DispAttr.m_fStaticTick); - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); - redrawWindow(1,false);//在名称区显示数据值 -// if( m_pStatusView ) -// m_pStatusView->Refresh(); - m_pWaveFile->EmitLineCChanged(); - showStatus(); - update(); - } -} - -void CWaveShow::OnMoveStepRight() -{ - if( m_pWaveFile ) - { - m_pWaveFile->m_DispAttr.m_fStaticTick++; - m_pWaveFile->m_DispAttr.m_fStaticTime = m_pWaveFile->GetPointTime(m_pWaveFile->m_DispAttr.m_fStaticTick); - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); - redrawWindow(1,false);//在名称区显示数据值 -// if( m_pStatusView ) -// m_pStatusView->Refresh(); - m_pWaveFile->EmitLineCChanged(); - showStatus(); - update(); - } -} - -void CWaveShow::OnHideWaveChannel() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch<0 || Ch>=MAX_WAVES) - return; - - int nGroup = m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]; - m_pWaveFile->m_DispAttr.m_bWaveMarked[nGroup] = true; - - redrawWindow(1,false); - redrawWindow(2,false); - -} - -void CWaveShow::OnHideTagChannel() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; - if( Ch<0 || Ch>=MAX_TAGS) - return; - - m_pWaveFile->m_DispAttr.m_nTagsGroup[Ch] = -1; - - redrawWindow(3,false); - redrawWindow(4,false); -} - - - -void CWaveShow::OnZoomSelected() -{ - //horizon - int nStartX = m_ptZoomNew.x()m_ptZoomOld.x()?m_ptZoomNew.x():m_ptZoomOld.x(); - //vertical - int nStartY = m_ptZoomNew.y()m_ptZoomOld.y()?m_ptZoomNew.y():m_ptZoomOld.y(); - //horizon - int nLeftMargin = CWaveEnv::GetInst()->m_nLeftMarginName/*SPLITTERWIDTH*/; - int nMidPos = ( nStartX + nEndX )/2 - nLeftMargin + m_pTimeAxisView->m_nScrollLeft; -// int nStartPos = nStartX - nLeftMargin + m_pTimeAxisView->m_nScrollLeft; - double dTick = m_pWaveFile->GetTick(nMidPos); -// double dTickStart = m_pWaveFile->GetTick(nStartPos); - //vertical - int nScrollTop = m_pAnalogueView->m_nScrollTop; - int nMidY = (nStartY + nEndY)/2; - //{{horizon - double fOldRate = m_pWaveFile->m_DispAttr.m_fZoomX; - QRect rect = m_pAnalogueView->rect(); - int nWidth = rect.width(); - int nTemp = 0; - double fNewRate; - if(fOldRate*(double)nWidth/(double)(nEndX-nStartX) < 1.0) - { - nTemp = (int)((nEndX-nStartX)/(fOldRate*(double)nWidth)); - fNewRate = 1.0/(double)nTemp; - } - else - fNewRate = (int)(fOldRate*(double)nWidth/(double)(nEndX - nStartX)); - if(fNewRate > 16.0) - fNewRate = 16.0; - if(fNewRate*256.0 < 8.0) - fNewRate = 8.0/256.0; - m_pWaveFile->m_DispAttr.m_fZoomX = fNewRate; - //}} - //{{vertical - double fOldRateY = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - int nHeight = rect.height(); - double fNewRateY = fOldRateY*nHeight/(nEndY - nStartY); - if(fNewRateY > 20.0) - fNewRateY = 20.0; - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = fNewRateY; - int nValue = (nMidY + nScrollTop)*fNewRateY/fOldRateY - nHeight/2; - //}} - - m_pTimeAxisView->ResetHScrollSize(); - m_pAnalogueView->ResetVScrollSize(); - - int xPosition = m_pWaveFile->GetPointPosition( dTick ); - - int nHScroll = xPosition - nWidth/2; - if(nHScroll<0) nHScroll =0; - //int nMaxWidth = m_pWaveFile->GetMaxWidth(); - m_pTimeAxisView->horiz_bar->setValue(nHScroll); - m_pAnalogueView->vert_bar->setValue(nValue); - - redrawWindow(1,false); - redrawWindow(2,false); - redrawWindow(3,false); - redrawWindow(4,false); - redrawWindow(5,false); - -} - -void CWaveShow::OnLineSliderMove(int pos) -{ - if( !CWaveEnv::GetInst()->m_bShowCompLine ) - return; - m_pAnalogueView->m_nCompPosY = pos; - redrawWindow(1,false); - redrawWindow(2,false); -} - -void CWaveShow::OnResumeGroup() -{ - m_pWaveFile->m_DispAttr.ResumeGroup(); - redrawWindow(1,false); - redrawWindow(2,false); - redrawWindow(3,false); - redrawWindow(4,false); - redrawWindow(5,false); -} -//////////////////////////////////////////////////////////////////////// -//##ModelId=4039BEDE0118 -bool CWaveShow::SetComtradeData(CComtradeFile& pComtradeData) -{ - m_pWaveFile = &pComtradeData; - m_pAnalogueView->SetComtradeData(pComtradeData); - m_pDigitalView->SetComtradeData(pComtradeData); - m_pAnaAxisView->SetComtradeData(pComtradeData); - m_pDgtNameView->SetComtradeData(pComtradeData); - m_pTimeAxisView->SetComtradeData(pComtradeData); -// m_pStatusView->SetComtradeData(pComtradeData); - m_pLinStatusView->SetComtradeData(pComtradeData); - RecacuAreas(); - update(); - return true; -} - -//##ModelId=4039BEE60389 -bool CWaveShow::SetShowAttribute(CSectionList& pAttrList) -{ - Q_UNUSED(pAttrList) - return true; -} -/* -bool CWaveShow::EditAnaGroup() -{ - if(!m_pWaveFile) - return false; - CAnaGroupSet* dlg = new CAnaGroupSet(m_pWaveFile,this); - if ( dlg->exec() == QDialog::Accepted ) { - redrawWindow(1,false); - redrawWindow(2,false); - } - return true; -} - -bool CWaveShow::EditDgtGroup() -{ - if(!m_pWaveFile) - return false; - CDgtGroupSet* dlg = new CDgtGroupSet(m_pWaveFile,this); - if ( dlg->exec() == QDialog::Accepted ) { - redrawWindow(3,false); - redrawWindow(4,false); - } - return true; -} - -bool CWaveShow::EditAnaTable() -{ - if(!m_pWaveFile) - return false; - CAnaTableSet* dlg = new CAnaTableSet(m_pWaveFile,this); - if ( dlg->exec() == QDialog::Accepted ) { - } - return true; -} - -bool CWaveShow::EditDgtTable() -{ - if(!m_pWaveFile) - return false; - CDgtTableSet* dlg = new CDgtTableSet(m_pWaveFile,this); - if ( dlg->exec() == QDialog::Accepted ) { - } - return true; -} - -bool CWaveShow::EditGridSet() -{ - if(!m_pWaveFile) - return false; - CGridSet* dlg = new CGridSet(m_pWaveFile,this); - if ( dlg->exec() == QDialog::Accepted ) { - } - return true; -} -*/ -bool CWaveShow::EditSelectLine() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch>=0 && Chm_DispAttr.m_nSelDigitalNo; - if( Ch<0 || Ch>=MAX_TAGS) - return false; - OnDgtLineSet(); - return true; -} - -bool CWaveShow::EditSelectColor() -{ - int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - if( Ch>=0 && Chm_DispAttr.m_nSelDigitalNo; - if( Ch<0 || Ch>=MAX_TAGS) - return false; - OnDgtColorSet(); - return true; -} - -//##ModelId=4039BEEE026F -bool CWaveShow::GetShowAttribute(CSectionList& pAttrList) -{ - Q_UNUSED(pAttrList) - return true; -} - -void CWaveShow::SetValueType( int nType ) -{ - if( m_pWaveFile->m_DispAttr.m_byValueType != nType ) - { - m_pWaveFile->m_DispAttr.m_byValueType = nType; - m_pWaveFile->SetUnitType(nType); - if(m_pAnaAxisView) m_pAnaAxisView->update(); - if(m_pAnalogueView) m_pAnalogueView->update(); - if(m_pDgtNameView) m_pDgtNameView->update(); - if(m_pDigitalView) m_pDigitalView->update(); - if(m_pTimeAxisView) m_pTimeAxisView->update(); - update(); - } -} - -int CWaveShow::GetCursorTicks() -{ - if(m_pWaveFile) - return m_pWaveFile->m_DispAttr.m_fStaticTick; - return 0; -} - -/* -void CWaveShow::AddLabel() -{ - CLabel label; - label.m_lTime = m_pWaveFile->m_DispAttr.m_fStaticTime; - CLabelSetDlg *dlg = new CLabelSetDlg( this ); - dlg->SetParam(m_pWaveFile,&label); - if ( dlg->exec() == QDialog::Accepted ) { - - m_pWaveFile->m_LabelList.append(label); - redrawWindow(2,false); - redrawWindow(4,false); - } - delete dlg; -} - -void CWaveShow::ShowLabels() -{ - CLabelBrowser *dlg = new CLabelBrowser( this ); - dlg->setLabelList(m_pWaveFile,m_pWaveFile->m_LabelList); - dlg->Rebuild(); - if ( dlg->exec() == QDialog::Accepted ) { - - m_pWaveFile->m_LabelList = dlg->m_labelList; - redrawWindow(2,false); - redrawWindow(4,false); - } - delete dlg; -} - -void CWaveShow::SetZoon() -{ - QDate db = m_pWaveFile->m_tTriggerTime.date(); - QTime tb = m_pWaveFile->m_tTriggerTime.time(); - int nMsec = m_pWaveFile->m_DispAttr.m_fBaseTime; - int nSecs= nMsec/1000; - int nDays = nSecs/(24*3600); - nSecs = nSecs%(24*3600); - int nMsec1 = nMsec%1000; - QDate d1 = db.addDays(nDays); - QTime t1 = tb.addSecs(nSecs); - - nMsec = m_pWaveFile->m_DispAttr.m_fStaticTick; - nSecs= nMsec/1000; - nDays = nSecs/(24*3600); - nSecs = nSecs%(24*3600); - int nMsec2 = nMsec%1000; - QDate d2 = db.addDays(nDays); - QTime t2 = tb.addSecs(nSecs); - - czoomsetdlg *dlg = new czoomsetdlg( this ); - dlg->setZoonTime(d1,t1,nMsec1,d2,t2,nMsec2); - if( dlg->exec() == QDialog::Accepted ) { - d1 = dlg->m_date1; - t1 = dlg->m_time1; - d2 = dlg->m_date2; - t2 = dlg->m_time2; - nMsec1 = dlg->m_msec1; - nMsec2 = dlg->m_msec2; - - nMsec1 += (d1.daysTo(db)*24*3600 + t1.secsTo(tb))*1000; - nMsec2 += (d2.daysTo(db)*24*3600 + t2.secsTo(tb))*1000; - - if(nMsec1<0) nMsec1 = 0; - if(nMsec2<0) nMsec2 = 0; - m_pWaveFile->m_DispAttr.m_fBaseTime = nMsec1; - m_pWaveFile->m_DispAttr.m_fBaseTick = m_pWaveFile->GetPointNoFromTime(m_pWaveFile->m_DispAttr.m_fBaseTime); - m_pWaveFile->m_DispAttr.m_fStaticTime = nMsec2; - m_pWaveFile->m_DispAttr.m_fStaticTick = m_pWaveFile->GetPointNoFromTime(m_pWaveFile->m_DispAttr.m_fStaticTime); - - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); - update(); - - m_pWaveFile->EmitLineCChanged(); - } - delete dlg; - -} -*/ -void CWaveShow::ReSize(const QSize &size) -{ - resize(size.expandedTo(minimumSizeHint())); - RecacuAreas(); -} - -void CWaveShow::SetZoomState( int nState ) -{ - m_nZoomState = (enum_ZoomState)nState; - switch( m_nZoomState ) - { - case SINGLEZOOM_IN: - setCursor( m_hZoomIn ); - m_pAnalogueView->setCursor( m_hZoomIn ); - break; - case SINGLEZOOM_OUT: - setCursor( m_hZoomOut ); - m_pAnalogueView->setCursor( m_hZoomOut ); - break; - case ZOOMRECT_X: - setCursor( m_hZoomRect ); - m_pAnalogueView->setCursor( m_hZoomRect ); - break; - default: - setCursor( m_hZoomOut ); - m_pAnalogueView->setCursor( m_hArrowCursor ); - break; - } -} - -void CWaveShow::ZoomInX() -{ - m_pWaveFile->m_DispAttr.m_fZoomX *=2.0; - if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; - - m_pTimeAxisView->ResetHScrollSize(); - - int xPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fStaticTick ); - - QRect rect = m_pTimeAxisView->rect(); - int nHScroll = xPosition - rect.width()/2; - //int nHScroll = xPosition - rect.width(); - if(nHScroll<0) nHScroll =0; - - HTimeScroll(nHScroll); - - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); -} - -void CWaveShow::ZoomOutX() -{ - m_pWaveFile->m_DispAttr.m_fZoomX /= 2.0;// TIME_RATE; - if(m_pWaveFile->m_DispAttr.m_fZoomX*128 < 8.0) - m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/128.0; - m_pTimeAxisView->ResetHScrollSize(); - - int xPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fStaticTick ); - - QRect rect = m_pTimeAxisView->rect(); - int nHScroll = xPosition - rect.width()/2; - //int nHScroll = xPosition - rect.width(); - if(nHScroll<0) nHScroll =0; - HTimeScroll(nHScroll); - - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); -} - -void CWaveShow::ZoomInAnalogueY() -{ - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 += AMP_RATE; - if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 > 20.0) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 20.0; - - m_pAnalogueView->ResetVScrollSize(); - - redrawWindow(1,false); - redrawWindow(2,false); -} - -void CWaveShow::ZoomOutAnalogueY() -{ - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 -= AMP_RATE; - if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 < 0.5) - m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 0.5; - - m_pAnalogueView->ResetVScrollSize(); - - redrawWindow(1,false); - redrawWindow(2,false); -} - -void CWaveShow::ZoomInDigitalY() -{ - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 += AMP_RATE; - if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 > 100.0) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 100.0; - - m_pDigitalView->ResetVScrollSize(); - - redrawWindow(3,false); - redrawWindow(4,false); -} - -void CWaveShow::ZoomOutDigitalY() -{ - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 -= AMP_RATE; - if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 < 0.5) - m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 0.5; - - m_pDigitalView->ResetVScrollSize(); - - redrawWindow(3,false); - redrawWindow(4,false); -} - -void CWaveShow::ZoomInName() -{ - QRect rc = rect(); - m_nLeftMargin += 10; - if(m_nLeftMargin > rc.width() - 20 ) - m_nLeftMargin = rc.width() - 20; - update(); - MoveAllViews(); -} - -void CWaveShow::ZoomOutName() -{ - m_nLeftMargin -= 10; - if(m_nLeftMargin < 0 ) - m_nLeftMargin = 0; - update(); - MoveAllViews(); -} - -void CWaveShow::copySelectToClip() -{ - - if(m_pCapturePt1.y() == m_pCapturePt2.y()||m_pCapturePt1.x()==m_pCapturePt2.x()) - return; - - QPoint pt1 = ( m_pCapturePt1.y() < m_pCapturePt2.y() )? m_pCapturePt1:m_pCapturePt2; - QPoint pt2 = ( m_pCapturePt1.y() > m_pCapturePt2.y() )? m_pCapturePt1:m_pCapturePt2; - - QRect rect2; - m_pAnalogueView->GetWaveMargin(rect2); - QPixmap pmAna( rect2.width(), rect2.height()); - pmAna.fill( Qt::white ); - QPainter paint; - paint.begin( &pmAna ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pAnalogueView->Print( &paint,rect2,QPoint(0,0),true); - paint.end(); - - QRect rect3; - m_pDigitalView->GetTagMargin(rect3); - QPixmap pmDgt( rect3.width(), rect3.height()); - pmDgt.fill( Qt::white ); - - paint.begin( &pmDgt ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pDigitalView->Print( &paint,rect3,QPoint(0,0),true); - paint.end(); - - QRect rect4,rect5; - if(pt2.y()m_nScrollLeft); - rect4.setRight(qMax(pt1.x(),pt2.x()) - m_nLeftMargin + m_pAnalogueView->m_nScrollLeft); - rect4.setTop(pt1.y() + m_pAnalogueView->m_nScrollTop); - rect4.setBottom(pt2.y() + m_pAnalogueView->m_nScrollTop); - rect5 = QRect(0,0,0,0); - } - else if(pt1.y()>m_nTagsViewTop) - { - rect5.setLeft(qMin(pt1.x(),pt2.x()) - m_nLeftMargin + m_pDigitalView->m_nScrollLeft); - rect5.setRight(qMax(pt1.x(),pt2.x()) - m_nLeftMargin + m_pDigitalView->m_nScrollLeft); - rect5.setTop(pt1.y() - m_nTagsViewTop + m_pDigitalView->m_nScrollTop); - rect5.setBottom(pt2.y() - m_nTagsViewTop + m_pDigitalView->m_nScrollTop); - rect4 = QRect(0,0,0,0); - } - else - { - rect4.setLeft(qMin(pt1.x(),pt2.x()) - m_nLeftMargin + m_pAnalogueView->m_nScrollLeft); - rect4.setRight(qMax(pt1.x(),pt2.x()) - m_nLeftMargin + m_pAnalogueView->m_nScrollLeft); - rect4.setTop(pt1.y() + m_pAnalogueView->m_nScrollTop); - rect4.setBottom(m_nTagsViewTop + m_pAnalogueView->m_nScrollTop); - - rect5.setLeft(rect4.left()); - rect5.setRight(rect4.right()); - rect5.setTop(0 + m_pDigitalView->m_nScrollTop); - rect5.setBottom(pt2.y() - m_nTagsViewTop + m_pDigitalView->m_nScrollTop); - } - - int nWidth = qMax(rect4.width(),rect5.width()); - int nHeight = rect4.height() + rect5.height(); - - QPixmap pmFull( nWidth, nHeight); - pmFull.fill( Qt::white ); - - if(rect4!=QRect(0,0,0,0)) - { - QPainter painter(&pmFull); - painter.drawPixmap(QPoint(0,0),pmAna,rect4); - } - - if(rect5!=QRect(0,0,0,0)) - { - QPainter painter(&pmFull); - painter.drawPixmap(QPoint(0,rect4.height()),pmDgt,rect5); - } - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); - clipboard->setPixmap(pmFull); -} -/* -void CWaveShow::CopySelectPixmap() -{ - if(!m_pWaveFile)return; - - m_bPixmapCapturePt1 = true; - m_bPixmapCaptureStart = false; - -} - -void CWaveShow::CopyZonePixmap() -{ - if(!m_pWaveFile) - return; - - bool bShowName = true; - bool bShowWave = true; - bool bShowTag = true; - bool bShowTime = true; - - CCopyWaveSet dlg; - if( QDialog::Accepted !=dlg.exec() ) - return; - bShowName = dlg.m_bShowName; - bShowWave = dlg.m_bShowWave; - bShowTag = dlg.m_bShowTag; - bShowTime = dlg.m_bShowTime; - - QPainter paint; - - QRect rectTmp = QRect(0,0,0,0); - QRect rectTmp1 = QRect(0,0,0,0); - QRect rect1 = QRect(0,0,0,0); - QRect rect2 = QRect(0,0,0,0); - QRect rect3 = QRect(0,0,0,0); - QRect rect4 = QRect(0,0,0,0); - QRect rect5 = QRect(0,0,0,0); - - QPixmap pmAnaAxis; - QPixmap pmAna; - QPixmap pmDgt; - QPixmap pmTime; - QPixmap pmDgtName; - - m_pAnalogueView->GetWaveMargin(rectTmp); - m_pDigitalView->GetTagMargin(rectTmp1); - - int XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime); - int XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime); - int nBegin = qMax(0,qMin(XPosition1,XPosition2)); - int nEnd = qMin(qMax(rectTmp.width(),rectTmp1.width()),qMax(XPosition1,XPosition2)); - - rectTmp.setLeft( nBegin ); - rectTmp.setRight( nEnd ); - - QPoint ptOffset = QPoint(-rectTmp.left(),0); - - if( bShowName && bShowWave ) - { - m_pAnaAxisView->GetAnaAxisMargin(rect1); - pmAnaAxis = QPixmap(rect1.width(), rect1.height()); - pmAnaAxis.fill( Qt::white ); - - paint.begin( &pmAnaAxis ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pAnaAxisView->Print( &paint,rect1,QPoint(0,0),true); - paint.end(); - } - - if( bShowWave ) - { - - m_pAnalogueView->GetWaveMargin(rect2); - rect2.setLeft( nBegin ); - rect2.setRight( nEnd ); - pmAna = QPixmap( rect2.width(), rect2.height() ); - pmAna.fill( Qt::white ); - - paint.begin( &pmAna ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pAnalogueView->Print( &paint,rect2,ptOffset,true); - paint.end(); - } - - if( bShowName && bShowTag ) - { - m_pDgtNameView->GetTagNameMargin(rect3); - pmDgtName = QPixmap( rect3.width(), rect3.height() ); - pmDgtName.fill( Qt::white ); - - paint.begin( &pmDgtName ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pDgtNameView->Print( &paint,rect3,QPoint(0,0),true); - paint.end(); - } - - if( bShowTag ) - { - m_pDigitalView->GetTagMargin(rect4); - rect4.setLeft( nBegin ); - rect4.setRight( nEnd ); - pmDgt = QPixmap( rect4.width(), rect4.height()); - pmDgt.fill( Qt::white ); - - paint.begin( &pmDgt ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pDigitalView->Print( &paint,rect4,ptOffset,true); - paint.end(); - } - - if( bShowTime ) - { - m_pTimeAxisView->GetTimeMargin(rect5); - rect5.setLeft( nBegin ); - rect5.setRight( nEnd ); - pmTime = QPixmap( rect5.width(), rect5.height()); - pmTime.fill( Qt::white ); - - paint.begin( &pmTime ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pTimeAxisView->PrintB( &paint,rect5,ptOffset,true,false); - paint.end(); - } - - QPixmap pmFull( qMax(rect1.width() + rect2.width(),rect1.width() + rect4.width() ), (rect2.height()+rect4.height()+rect5.height())); - pmFull.fill( Qt::white ); - - QPainter painter(&pmFull); - if( bShowWave ) - { - if( bShowName ) - painter.drawPixmap(0,0,pmAnaAxis,0,0,rect1.width(),rect1.height() ); - painter.drawPixmap(rect1.width(),0,pmAna,0,0,rect2.width(),rect2.height()); - } - - if( bShowTag ) - { - if( bShowName ) - painter.drawPixmap(0,rect2.height(),pmDgtName,0,0,rect3.width(),rect3.height() ); - painter.drawPixmap(rect1.width(),rect2.height(),pmDgt,0,0,rect4.width(),rect4.height() ); - } - - if( bShowTime ) - painter.drawPixmap(rect1.width(),rect2.height()+rect4.height(),pmTime,0,0,rect5.width(),rect5.height() ); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); - clipboard->setPixmap(pmFull); -} -*/ -//{{ Add by qizhong -void CWaveShow::copyZonepixmapToFile() -{ - if(!m_pWaveFile)return; - - double m_fBaseTime = m_pWaveFile->m_nFrist_ms; -// double m_fSecondLineTime = m_pWaveFile->m_nFrist_ms + int((1000.0/m_pWaveFile->m_dLineFreq)*10); - - QPainter paint; - - QRect rect0; - m_pAnaAxisView->GetAnaAxisMargin(rect0); - QPixmap pmAnaAxis( rect0.width(), rect0.height()); - pmAnaAxis.fill( Qt::white ); - paint.begin( &pmAnaAxis ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pAnaAxisView->Print( &paint,rect0,QPoint(0,0),true); - paint.end(); - - QRect rect1; - m_pDgtNameView->GetTagNameMargin(rect1); - QPixmap pmDgtAxis( rect1.width(), rect1.height()); - pmDgtAxis.fill( Qt::white ); - paint.begin( &pmDgtAxis ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pDgtNameView->Print( &paint,rect1,QPoint(0,0),true); - paint.end(); - - QRect rect2; - m_pAnalogueView->GetWaveMargin(rect2); - QPixmap pmAna( rect2.width(), rect2.height()); - pmAna.fill( Qt::white ); -// QPainter paint; - paint.begin( &pmAna ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pAnalogueView->Print( &paint,rect2,QPoint(0,0),true); - paint.end(); - - QRect rect3; - m_pDigitalView->GetTagMargin(rect3); - QPixmap pmDgt( rect3.width(), rect3.height()); - pmDgt.fill( Qt::white ); - paint.begin( &pmDgt ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pDigitalView->Print( &paint,rect3,QPoint(0,0),true); - paint.end(); - - QRect rect4; - m_pTimeAxisView->GetTimeMargin(rect4); - QPixmap pmTime( rect4.width(), rect4.height()); - pmTime.fill( Qt::white ); - paint.begin( &pmTime ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pTimeAxisView->PrintB( &paint,rect4,QPoint(0,0),true,false); - paint.end(); - - int XPosition1 = m_pWaveFile->GetXPosition(m_fBaseTime); - //int XPosition2 = m_pWaveFile->GetXPosition(m_fSecondLineTime); - int nLastTick = m_pWaveFile->GetTotalPointAmount(); - int XPosition2 = m_pWaveFile->GetPointPosition(nLastTick-1)+50; - int nBegin = qMax(0,qMin(XPosition1,XPosition2)); - int nEnd = qMin(qMax(rect2.width(),rect3.width()),qMax(XPosition1,XPosition2)); - - QPixmap pmFull( nEnd - nBegin+rect0.width(), (rect2.height()+rect3.height()+rect4.height())); - pmFull.fill( Qt::white ); - - QPainter painter(&pmFull); - painter.drawPixmap(0,0,pmAnaAxis,0,0,rect0.width()-2,rect0.height() ); - painter.drawPixmap(0,rect0.height(),pmDgtAxis,0,0,rect1.width()-2,rect1.height() ); - - painter.drawPixmap(rect1.width(),0,pmAna,nBegin,0,nEnd - nBegin,rect2.height() ); - painter.drawPixmap(rect0.width(),rect2.height(),pmDgt,nBegin,0,nEnd - nBegin,rect3.height() ); - painter.drawPixmap(rect0.width(),rect2.height()+rect3.height(),pmTime,nBegin,0,nEnd - nBegin,rect4.height()); - - paint.begin( &pmFull ); - paint.setPen(QColor(0,0,0)); - paint.drawLine(rect0.width()-1,0, rect0.width()-1,rect2.height()+rect3.height()+5); - paint.end(); - - //QString szFileName = m_pWaveFile->m_sFileName +".bmp"; - QString strFileName = QFileDialog::getSaveFileName(this,tr("Save Wave Graph"),QApplication::applicationFilePath(),"Images (*.bmp)");//保存波形图片 - QDir dir = QDir::current(); - strFileName = dir.absoluteFilePath(strFileName); - - if(pmFull.save(strFileName,"BMP")) - { - QMessageBox objMsgBox(QMessageBox::Information,tr("Save File"),tr("Save Successfully!"));//保存文件 文件保存成功 - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - } - -/* - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); - clipboard->setPixmap(pmFull); -*/ -} -//}} -/* -void CWaveShow::CopyFullPixmap() -{ - if(!m_pWaveFile) - return; - - bool bShowName = true; - bool bShowWave = true; - bool bShowTag = true; - bool bShowTime = true; - - CCopyWaveSet dlg; - if( QDialog::Accepted !=dlg.exec() ) - return; - bShowName = dlg.m_bShowName; - bShowWave = dlg.m_bShowWave; - bShowTag = dlg.m_bShowTag; - bShowTime = dlg.m_bShowTime; - - - QPainter paint; - - QRect rect1 = QRect(0,0,0,0); - QRect rect2 = QRect(0,0,0,0); - QRect rect3 = QRect(0,0,0,0); - QRect rect4 = QRect(0,0,0,0); - QRect rect5 = QRect(0,0,0,0); - - QPixmap pmAnaAxis; - QPixmap pmAna; - QPixmap pmDgt; - QPixmap pmTime; - QPixmap pmDgtName; - - if( bShowName && bShowWave ) - { - m_pAnaAxisView->GetAnaAxisMargin(rect1); - pmAnaAxis = QPixmap(rect1.width(), rect1.height()); - pmAnaAxis.fill( Qt::white ); - - paint.begin( &pmAnaAxis ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pAnaAxisView->Print( &paint,rect1,QPoint(0,0),true); - paint.end(); - } - - if( bShowWave ) - { - m_pAnalogueView->GetWaveMargin(rect2); - pmAna = QPixmap( rect2.width(), rect2.height() ); - pmAna.fill( Qt::white ); - - paint.begin( &pmAna ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pAnalogueView->Print( &paint,rect2,QPoint(0,0),true); - paint.end(); - } - - if( bShowName && bShowTag ) - { - m_pDgtNameView->GetTagNameMargin(rect3); - pmDgtName = QPixmap( rect3.width(), rect3.height() ); - pmDgtName.fill( Qt::white ); - - paint.begin( &pmDgtName ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pDgtNameView->Print( &paint,rect3,QPoint(0,0),true); - paint.end(); - } - - if( bShowTag ) - { - m_pDigitalView->GetTagMargin(rect4); - pmDgt = QPixmap( rect4.width(), rect4.height()); - pmDgt.fill( Qt::white ); - - paint.begin( &pmDgt ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pDigitalView->Print( &paint,rect4,QPoint(0,0),true); - paint.end(); - } - - if( bShowTime ) - { - m_pTimeAxisView->GetTimeMargin(rect5); - pmTime = QPixmap( rect5.width(), rect5.height()); - pmTime.fill( Qt::white ); - - paint.begin( &pmTime ); - paint.setBrush(palette().color( QPalette::Foreground )); - m_pTimeAxisView->PrintB( &paint,rect5,QPoint(0,0),true,false); - paint.end(); - } - - - QPixmap pmFull( qMax(rect1.width() + rect2.width(),rect1.width() + rect4.width() ), (rect2.height()+rect4.height()+rect5.height())); - pmFull.fill( Qt::white ); - - QPainter painter(&pmFull); - if( bShowWave ) - { - if( bShowName ) - painter.drawPixmap(0,0,pmAnaAxis,0,0,rect1.width(),rect1.height() ); - painter.drawPixmap(rect1.width(),0,pmAna,0,0,rect2.width(),rect2.height() ); - } - - if( bShowTag ) - { - if( bShowName ) - painter.drawPixmap(0,rect2.height(),pmDgtName,0,0,rect3.width(),rect3.height() ); - painter.drawPixmap(rect1.width(),rect2.height(),pmDgt,0,0,rect4.width(),rect4.height() ); - } - - if( bShowTime ) - painter.drawPixmap(rect1.width(),rect2.height()+rect4.height(),pmTime,0,0,rect5.width(),rect5.height() ); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); - clipboard->setPixmap(pmFull); -} -*/ -QPrinter* CWaveShow::GetPrinter() -{ - if( !printer ) - { -// printer = new QPrinter(); - printer = new QPrinter(QPrinter::PrinterResolution);//QPrinter::HighResolution);//QPrinter::PrinterResolution); - } - return printer; -} -/* -void CWaveShow::TestPrintPriview( CPrintsetupDlg *dlg ) -{ - if(!dlg || !GetPrinter() ) - return; - - ////////////////////////////////////////////////////////// - //得到需要打印的通道 - if(!m_pWaveFile) - return; - - PRINTPARAM oldParam = m_PrintAttr; - m_PrintAttr = dlg->m_Attr; - - int i,j; - for(i=0;im_DispAttr.m_bWavePrint[i] = false; - for(i=0;im_DispAttr.m_bTagsPrint[i] = false; - - if(m_PrintAttr.bAnaPrint) - { - for(j=0;j<(int)m_pWaveFile->AnalogDataList.count();j++) - { - for(i=0;i<(int)m_PrintAttr.m_listAnaPrint.count();i++) - { - if(0==m_pWaveFile->AnalogDataList[j].m_sName.compare(m_PrintAttr.m_listAnaPrint[i])) - { - m_pWaveFile->m_DispAttr.m_bWavePrint[j] = true; - } - } - } - } - if(m_PrintAttr.bDgtPrint) - { - for(j=0;j<(int)m_pWaveFile->DigitDataList.count();j++) - { - for(i=0;i<(int)m_PrintAttr.m_listDgtPrint.count();i++) - { - if(0==m_pWaveFile->DigitDataList[j].m_sName.compare(m_PrintAttr.m_listDgtPrint[i])) - { - m_pWaveFile->m_DispAttr.m_bTagsPrint[j] = true; - } - } - } - } - - /////////////////////////////////////////////// - - if(m_PrintAttr.bOrient) - printer->setOrientation(QPrinter::Landscape); - else - printer->setOrientation(QPrinter::Portrait); - - if(dlg->m_bDoprintPrv) - { - PrintPreview( dlg ); - } - - m_PrintAttr = oldParam; - -} - -void CWaveShow::PrintSetup() -{ - if(!GetPrinter()) - return; - - CPrintsetupDlg *dlg = new CPrintsetupDlg(this); - dlg->SetAttr(m_pWaveFile,m_PrintAttr,printer); - dlg->RedrawPixmapLabel(); - if(dlg->exec()==QDialog::Accepted) - { - m_PrintAttr = dlg->m_Attr; -////////////////////////////////////////////////////////// -//得到需要打印的通道 - if(m_pWaveFile) - { - int i,j; - for(i=0;im_DispAttr.m_bWavePrint[i] = false; - for(i=0;im_DispAttr.m_bTagsPrint[i] = false; - - if(m_PrintAttr.bAnaPrint) - { - for(j=0;j<(int)m_pWaveFile->AnalogDataList.count();j++) - { - for(i=0;i<(int)m_PrintAttr.m_listAnaPrint.count();i++) - { - if(0==m_pWaveFile->AnalogDataList[j].m_sName.compare(m_PrintAttr.m_listAnaPrint[i])) - { - m_pWaveFile->m_DispAttr.m_bWavePrint[j] = true; - } - } - } - } - if(m_PrintAttr.bDgtPrint) - { - for(j=0;j<(int)m_pWaveFile->DigitDataList.count();j++) - { - for(i=0;i<(int)m_PrintAttr.m_listDgtPrint.count();i++) - { - if(0==m_pWaveFile->DigitDataList[j].m_sName.compare(m_PrintAttr.m_listDgtPrint[i])) - { - m_pWaveFile->m_DispAttr.m_bTagsPrint[j] = true; - } - } - } - } - } -/////////////////////////////////////////////// - - if(m_PrintAttr.bOrient) - printer->setOrientation(QPrinter::Landscape); - else - printer->setOrientation(QPrinter::Portrait); - - if(dlg->m_bDoprintPrv) - { - PrintPreview(); - } - - if(dlg->m_bDoprint) - { - Print(true); - } - } - -} -*/ -void ScaleRect(QRect &rect,double sx,double sy) -{ - rect.setLeft(rect.left()*sx); - rect.setRight(rect.right()*sx); - rect.setTop(rect.top()*sy); - rect.setBottom(rect.bottom()*sy); -} - -void CWaveShow::Print(bool bSetuped) -{ - Q_UNUSED(bSetuped) - if(!m_pWaveFile||!GetPrinter()) - return; - - printer->setPageSize(QPrinter::A4); - - //if(!bSetuped) - if (NULL == printer->printEngine()) - { - QPrintDialog printDialog(printer, this); - if (printDialog.exec() != QDialog::Accepted) { - return; - } - } - - if(m_PrintAttr.bOrient) - printer->setOrientation(QPrinter::Landscape); - else - printer->setOrientation(QPrinter::Portrait); - - - double dLeftMargin = m_PrintAttr.dLeftMargin;//边距 - double dTopMargin = m_PrintAttr.dTopMargin; - double dRightMargin = m_PrintAttr.dRightMargin; - double dBottomMargin = m_PrintAttr.dBottomMargin; - - QFont m_LittleFont; - m_LittleFont.setPixelSize(10); - - //qDebug()<<"PageSize = " <pageSize(); - - //printer size - int pagew = printer->pageRect().width(); - int pageh = printer->pageRect().height(); - - - QRect rcScreen(0,0,800,600); - if (this->parentWidget()) - { - rcScreen.setSize(this->parentWidget()->size()); - } - else - { - rcScreen.setSize(this->size()); - } - - double dXCordRate = 1.0, dYCordRate = 1.0; - dXCordRate = (double)pagew/(double)rcScreen.width(); - dYCordRate = (double)pageh/(double)rcScreen.height(); - - QMatrix m; - m.scale( dXCordRate,dYCordRate ); - - QString szTitle; - szTitle = m_pWaveFile->m_sDirName; - szTitle.append("/"); - szTitle+= m_pWaveFile->m_sFileName; - - - int drawPagew = pagew/dXCordRate; - int drawPageh = pageh/dYCordRate; - - - QRect rect1(0,0,0,0),rect2(0,0,0,0),rect3(0,0,0,0),rect4(0,0,0,0),rect5(0,0,0,0); - if(m_PrintAttr.bNamePrint) m_pAnaAxisView->GetAnaAxisMargin(rect1); - m_pAnalogueView->GetWaveMargin(rect2); - if(m_PrintAttr.bNamePrint) m_pDgtNameView->GetTagNameMargin(rect3); - m_pDigitalView->GetTagMargin(rect4); - m_pTimeAxisView->GetTimeMargin(rect5); - - - int nWidth1 = qMax(rect1.width(),rect3.width()); - int nWidth2 = qMax(rect2.width(),rect4.width()); - int nHeight1 = qMax(rect1.height(),rect2.height()); - int nHeight2 = qMax(rect3.height(),rect4.height()); - int nTimeHeight =rect5.height(); -// int nTimeWidth =rect5.width(); -// int nTitleWidth = drawPagew; - int nTitleHeight = 20; - - int oneWaveheight = drawPageh - 2*nTimeHeight - dTopMargin - dBottomMargin + 10; //留上下边画坐标 - int oneWaveWidth = drawPagew - nWidth1 - dLeftMargin - dRightMargin; - if(oneWaveWidth<=0) oneWaveWidth = 10; - if(oneWaveheight<=0) oneWaveheight = 10; - - int nColumns = 0,nRows = 0; - int XPosition1 = 0,XPosition2 = 0,nBegin = 0,nEnd = 0; - if(m_PrintAttr.bZonePrint){ - //区域大小 - XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime) -5; - XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime) + 5; - nBegin = qMax(0,qMin(XPosition1,XPosition2)); - nEnd = qMin(qMax(rect2.width(),rect3.width()),qMax(XPosition1,XPosition2)); - //int nPages - nColumns = fabs(double(nBegin - nEnd))/oneWaveWidth; - nRows = (nHeight1 + nHeight2)/oneWaveheight; - } - else - { - nColumns = nWidth2/oneWaveWidth; - nRows = (nHeight1 + nHeight2)/oneWaveheight; - } - -// QPaintEngine * pe = printer->paintEngine(); - -// printer->setMinMax(0,(nColumns+1)*(nRows+1)); - - //设置打印起始页 - //printer->setFromTo(1,nRows*nColumns); - - QPainter paint; - if ( !paint.begin( printer ) ) - return; - paint.setWorldMatrix( m ); - - int nIndex = 0; - int nAnaTop = 0; - int nDgtTop = 0; - for(int i = 0;i<=nRows;i++) - { - - int nWaveHeight = 0; - int nDgtBegin = 0; - bool bAnaOver = true; - int nAnaHeight = 0; - int nDgtHeight = 0; - if(m_PrintAttr.bAnaPrint&&nAnaTop<=nHeight1) - { - bAnaOver = false; - nAnaHeight = oneWaveheight; - - if(nAnaTop+nAnaHeight>nHeight1) - { - nAnaHeight = nHeight1 - nAnaTop; - nDgtBegin = nAnaHeight; - bAnaOver = true; - } - - nWaveHeight += nAnaHeight; - } - - if(m_PrintAttr.bDgtPrint&&nDgtTop<= nHeight2&&bAnaOver) - { - nDgtHeight = oneWaveheight - nDgtBegin; - if(nDgtTop+nDgtHeight>nHeight2) - { - nDgtHeight = nHeight2- nDgtTop; - } - nWaveHeight += nDgtHeight; - } - - for(int j= 0;j<= nColumns;j++) - { - //wave - if(m_PrintAttr.bAnaPrint&&nAnaTop<=nHeight1&&nAnaHeight>0) - { - if(nWidth1>0&&m_PrintAttr.bNamePrint) - { - //QRect rcPrintt(dLeftMargin,nTimeHeight+dTopMargin,nWidth1,nAnaHeight); - QRect rcDrawt(0,nAnaTop,nWidth1,nAnaHeight); - QPoint ptOffset(dLeftMargin,nTimeHeight+dTopMargin - nAnaTop ); - m_pAnaAxisView->Print( &paint, rcDrawt ,ptOffset, m_PrintAttr.bColor); - } - - if(m_PrintAttr.bZonePrint) - { - //QRect rcPrint(nWidth1+dLeftMargin,nTimeHeight+dTopMargin,oneWaveWidth,nAnaHeight); - QRect rcDraw(nBegin + j*oneWaveWidth ,nAnaTop,qMin(oneWaveWidth,nEnd -nBegin - j*oneWaveWidth),nAnaHeight); - QPoint ptOffset(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nTimeHeight+dTopMargin - nAnaTop ); - m_pAnalogueView->Print( &paint, rcDraw , ptOffset,m_PrintAttr.bColor); - - } - else - { - //QRect rcPrint(nWidth1+dLeftMargin,nTimeHeight+dTopMargin,oneWaveWidth,nAnaHeight); - QRect rcDraw(j*oneWaveWidth,nAnaTop,oneWaveWidth,nAnaHeight); - QPoint ptOffset(nWidth1+dLeftMargin - j*oneWaveWidth,nTimeHeight+dTopMargin - nAnaTop ); - m_pAnalogueView->Print( &paint, rcDraw , ptOffset,m_PrintAttr.bColor); - } - - } - - if(m_PrintAttr.bDgtPrint&&nDgtTop<= nHeight2&&nDgtHeight>0&&bAnaOver) - { - if(nWidth1>0&&m_PrintAttr.bNamePrint) - { - //QRect rcPrintt(dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin,nWidth1,nDgtHeight); - QRect rcDrawt(0,nDgtTop,nWidth1,nDgtHeight); - QPoint ptOffset(dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); - m_pDgtNameView->Print( &paint, rcDrawt , ptOffset ,m_PrintAttr.bColor); - } - - if(m_PrintAttr.bZonePrint)//区域打印 - { - //QRect rcPrint(nWidth1+dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin,oneWaveWidth,nDgtHeight); - QRect rcDraw(nBegin + j*oneWaveWidth,nDgtTop,qMin(oneWaveWidth,nEnd -nBegin - j*oneWaveWidth),nDgtHeight); - QPoint ptOffset(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); - m_pDigitalView->Print( &paint, rcDraw ,ptOffset , m_PrintAttr.bColor); - - } - else - { - //QRect rcPrint(nWidth1+dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin,oneWaveWidth,nDgtHeight); - QRect rcDraw(j*oneWaveWidth,nDgtTop,oneWaveWidth,nDgtHeight); - QPoint ptOffset(nWidth1+dLeftMargin - j*oneWaveWidth,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); - m_pDigitalView->Print( &paint, rcDraw ,ptOffset , m_PrintAttr.bColor); - } - } - - { - QRect rcPrint(0,0,drawPagew,drawPageh); - QRect rcDraw(0,0,drawPagew,drawPageh); - paint.setWindow(rcDraw); - paint.setViewport(rcPrint); - paint.setBrush(Qt::white); - paint.setPen(Qt::NoPen); - paint.drawRect(QRect(0,0,drawPagew,dTopMargin+nTimeHeight)); - paint.drawRect(QRect(0,0,dLeftMargin,drawPageh)); - paint.drawRect(QRect(0,drawPageh - dBottomMargin - nTimeHeight,drawPagew,dBottomMargin+nTimeHeight)); - paint.drawRect(QRect(drawPagew - dRightMargin,0,dRightMargin,drawPageh)); - paint.setPen(QPen(Qt::black)); - } - - if(m_PrintAttr.bTimePrint) - { - if(m_PrintAttr.bZonePrint) - { - //QRect rcPrint(nWidth1+dLeftMargin,dTopMargin,oneWaveWidth,nTimeHeight); - QRect rcDraw(nBegin + j*oneWaveWidth,0,qMin(oneWaveWidth,nEnd - nBegin - j*oneWaveWidth),nTimeHeight); - QPoint ptOffset1(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,dTopMargin ); - m_pTimeAxisView->PrintB( &paint, rcDraw ,ptOffset1, m_PrintAttr.bColor,true ); - - //QRect rcPrint1(nWidth1+dLeftMargin,nWaveHeight+nTimeHeight + dTopMargin,oneWaveWidth,nTimeHeight); - QRect rcDraw1(nBegin + j*oneWaveWidth,0,qMin(oneWaveWidth,nEnd - nBegin - j*oneWaveWidth),nTimeHeight); - QPoint ptOffset2(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nWaveHeight+nTimeHeight + dTopMargin ); - m_pTimeAxisView->PrintB( &paint, rcDraw1 ,ptOffset2, m_PrintAttr.bColor , false ); - } - else - { - //QRect rcPrint(nWidth1+dLeftMargin,dTopMargin,oneWaveWidth,nTimeHeight); - QRect rcDraw(j*oneWaveWidth,0,oneWaveWidth,nTimeHeight); - QPoint ptOffset1(nWidth1+dLeftMargin - j*oneWaveWidth,dTopMargin ); - m_pTimeAxisView->PrintB( &paint, rcDraw ,ptOffset1, m_PrintAttr.bColor,true ); - - //QRect rcPrint1(nWidth1+dLeftMargin,nWaveHeight+nTimeHeight + dTopMargin,oneWaveWidth,nTimeHeight); - QRect rcDraw1(j*oneWaveWidth,0,oneWaveWidth,nTimeHeight); - QPoint ptOffset2(nWidth1+dLeftMargin - j*oneWaveWidth,nWaveHeight+nTimeHeight + dTopMargin ); - m_pTimeAxisView->PrintB( &paint, rcDraw1 ,ptOffset2, m_PrintAttr.bColor , false ); - } - - } - - if(m_PrintAttr.bTitlePrint) - { - QString szPage; - szPage.sprintf("Page %d",nIndex++); - QRect rcPrint(0,0,drawPagew,drawPageh); - QRect rcDraw(0,0,drawPagew,drawPageh); - paint.setPen(QPen(Qt::black)); - paint.setFont(m_LittleFont); - paint.drawLine(QPoint(dLeftMargin,dTopMargin + nTimeHeight),QPoint(dLeftMargin,dTopMargin+nWaveHeight+nTimeHeight)); - paint.drawLine(QPoint(nWidth1+dLeftMargin,dTopMargin + nTimeHeight),QPoint(nWidth1+dLeftMargin,dTopMargin+nWaveHeight+nTimeHeight)); - paint.drawText(QRect(20,drawPageh - nTitleHeight,drawPagew,nTitleHeight),Qt::AlignLeft | Qt::TextSingleLine,szTitle); - paint.drawText(QRect(20,drawPageh - nTitleHeight,drawPagew,nTitleHeight),Qt::AlignHCenter | Qt::TextSingleLine,szPage); - } - - printer->newPage(); - } - nAnaTop = nAnaTop + nAnaHeight; - nDgtTop = nDgtTop + nDgtHeight; - } - paint.end(); -} - -void CWaveShow::PrintPreview( QWidget* pParent ) -{ - if(!m_pWaveFile||!GetPrinter())return; - - double dLeftMargin = m_PrintAttr.dLeftMargin;//边距 - double dTopMargin = m_PrintAttr.dTopMargin; - double dRightMargin = m_PrintAttr.dRightMargin; - double dBottomMargin = m_PrintAttr.dBottomMargin; - - QFont m_LittleFont; - m_LittleFont.setPixelSize(10); - - int pagewOrgin = 6814; - int pagehOrgin = 4760; - if(m_PrintAttr.bOrient) - { - pagehOrgin = printer->pageRect().width(); - pagewOrgin = printer->pageRect().height(); - } - else - { - pagewOrgin = printer->pageRect().width(); - pagehOrgin = printer->pageRect().height(); - } - - - QRect rcScreen(0,0,800,600); - if (this->parentWidget()) - { - rcScreen.setSize(this->parentWidget()->size()); - } - else - { - rcScreen.setSize(this->size()); - } - double dXCordRate = 1.0, dYCordRate = 1.0; - dXCordRate = (double)pagewOrgin/(double)rcScreen.width(); - dYCordRate = (double)pagehOrgin/(double)rcScreen.height(); - - QMatrix m; - m.scale( dXCordRate,dYCordRate ); - - QString szTitle; - szTitle = m_pWaveFile->m_sDirName; - szTitle.append("/"); - szTitle+= m_pWaveFile->m_sFileName; - - - int drawPagew = rcScreen.width(); - int drawPageh = rcScreen.height(); - - - QRect rect1(0,0,0,0),rect2(0,0,0,0),rect3(0,0,0,0),rect4(0,0,0,0),rect5(0,0,0,0); - if(m_PrintAttr.bNamePrint) m_pAnaAxisView->GetAnaAxisMargin(rect1); - m_pAnalogueView->GetWaveMargin(rect2); - if(m_PrintAttr.bNamePrint) m_pDgtNameView->GetTagNameMargin(rect3); - m_pDigitalView->GetTagMargin(rect4); - m_pTimeAxisView->GetTimeMargin(rect5); - - - int nWidth1 = qMax(rect1.width(),rect3.width()); - int nWidth2 = qMax(rect2.width(),rect4.width()); - int nHeight1 = qMax(rect1.height(),rect2.height()); - int nHeight2 = qMax(rect3.height(),rect4.height()); - int nTimeHeight =rect5.height(); -// int nTimeWidth =rect5.width(); -// int nTitleWidth = drawPagew; - int nTitleHeight = 20; - - int oneWaveheight = drawPageh - 2*nTimeHeight - dTopMargin - dBottomMargin + 10; //留上下边画坐标 - int oneWaveWidth = drawPagew - nWidth1 - dLeftMargin - dRightMargin; - if(oneWaveWidth<=0) oneWaveWidth = 10; - if(oneWaveheight<=0) oneWaveheight = 10; - - int nColumns = 0,nRows = 0; - int XPosition1 = 0,XPosition2 = 0,nBegin = 0,nEnd = 0; - if(m_PrintAttr.bZonePrint){ - //区域大小 - XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime) -5; - XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime) + 5; - nBegin = qMax(0,qMin(XPosition1,XPosition2)); - nEnd = qMin(qMax(rect2.width(),rect3.width()),qMax(XPosition1,XPosition2)); - //int nPages - nColumns = fabs(double(nBegin - nEnd))/oneWaveWidth; - nRows = (nHeight1 + nHeight2)/oneWaveheight; - } - else - { - nColumns = nWidth2/oneWaveWidth; - nRows = (nHeight1 + nHeight2)/oneWaveheight; - } - -// printer->setMinMax(0,(nColumns+1)*(nRows+1)); -// if(!printer->setup( this )) return; - QPainter paint; - - CPixmapList ImageList; - int nIndex = 0; - int nAnaTop = 0; - int nDgtTop = 0; - for(int i = 0;i<=nRows;i++) - { - - int nWaveHeight = 0; - int nDgtBegin = 0; - bool bAnaOver = true; - int nAnaHeight = 0; - int nDgtHeight = 0; - if(m_PrintAttr.bAnaPrint&&nAnaTop<=nHeight1) - { - bAnaOver = false; - nAnaHeight = oneWaveheight; - - if(nAnaTop+nAnaHeight>nHeight1) - { - nAnaHeight = nHeight1 - nAnaTop; - nDgtBegin = nAnaHeight; - bAnaOver = true; - } - - nWaveHeight += nAnaHeight; - } - - if(m_PrintAttr.bDgtPrint&&nDgtTop<= nHeight2&&bAnaOver) - { - nDgtHeight = oneWaveheight - nDgtBegin; - if(nDgtTop+nDgtHeight>nHeight2) - { - nDgtHeight = nHeight2- nDgtTop; - } - nWaveHeight += nDgtHeight; - } - - for(int j= 0;j<= nColumns;j++) - { - QPixmap map(pagewOrgin, pagehOrgin); - map.fill( Qt::white ); - paint.begin( &map ); - paint.setWorldMatrix( m ); - paint.setBrush(palette().color( QPalette::Foreground )); - //wave - - if(m_PrintAttr.bAnaPrint&&nAnaTop<=nHeight1&&nAnaHeight>0) - { - if(nWidth1>0&&m_PrintAttr.bNamePrint) - { - QRect rcDrawt(0,nAnaTop,nWidth1,nAnaHeight); - QPoint ptOffset(dLeftMargin,nTimeHeight+dTopMargin - nAnaTop ); - m_pAnaAxisView->Print( &paint, rcDrawt ,ptOffset, m_PrintAttr.bColor); - } - - if(m_PrintAttr.bZonePrint) - { - QRect rcDraw(nBegin + j*oneWaveWidth ,nAnaTop,qMin(oneWaveWidth,nEnd -nBegin - j*oneWaveWidth),nAnaHeight); - QPoint ptOffset(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nTimeHeight+dTopMargin - nAnaTop ); - m_pAnalogueView->Print( &paint, rcDraw , ptOffset,m_PrintAttr.bColor); - - } - else - { - QRect rcDraw(j*oneWaveWidth,nAnaTop,oneWaveWidth,nAnaHeight); - QPoint ptOffset(nWidth1+dLeftMargin - j*oneWaveWidth,nTimeHeight+dTopMargin - nAnaTop ); - m_pAnalogueView->Print( &paint, rcDraw , ptOffset,m_PrintAttr.bColor); - } - } - - if(m_PrintAttr.bDgtPrint&&nDgtTop<= nHeight2&&nDgtHeight>0&&bAnaOver) - { - if(nWidth1>0&&m_PrintAttr.bNamePrint) - { - QRect rcDrawt(0,nDgtTop,nWidth1,nDgtHeight); - QPoint ptOffset(dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); - m_pDgtNameView->Print( &paint, rcDrawt , ptOffset ,m_PrintAttr.bColor); - } - - if(m_PrintAttr.bZonePrint)//区域打印 - { - QRect rcDraw(nBegin + j*oneWaveWidth,nDgtTop,qMin(oneWaveWidth,nEnd -nBegin - j*oneWaveWidth),nDgtHeight); - QPoint ptOffset(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); - m_pDigitalView->Print( &paint, rcDraw ,ptOffset , m_PrintAttr.bColor); - - } - else - { - QRect rcDraw(j*oneWaveWidth,nDgtTop,oneWaveWidth,nDgtHeight); - QPoint ptOffset(nWidth1+dLeftMargin - j*oneWaveWidth,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); - m_pDigitalView->Print( &paint, rcDraw ,ptOffset , m_PrintAttr.bColor); - } - } - - { - QRect rcPrint(0,0,drawPagew,drawPageh); - QRect rcDraw(0,0,drawPagew,drawPageh); - paint.setWindow(rcDraw); - paint.setViewport(rcPrint); - paint.setBrush(Qt::white); - paint.setPen(Qt::NoPen); - paint.setFont(m_LittleFont); - paint.drawRect(QRect(0,0,drawPagew,dTopMargin+nTimeHeight)); - paint.drawRect(QRect(0,0,dLeftMargin,drawPageh)); - paint.drawRect(QRect(0,drawPageh - dBottomMargin - nTimeHeight,drawPagew,dBottomMargin+nTimeHeight)); - paint.drawRect(QRect(drawPagew - dRightMargin,0,dRightMargin,drawPageh)); - paint.setPen(QPen(Qt::black)); - } - - if(m_PrintAttr.bTimePrint) - { - if(m_PrintAttr.bZonePrint) - { - QRect rcDraw(nBegin + j*oneWaveWidth,0,qMin(oneWaveWidth,nEnd - nBegin - j*oneWaveWidth),nTimeHeight); - QPoint ptOffset1(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,dTopMargin ); - m_pTimeAxisView->PrintB( &paint, rcDraw ,ptOffset1, m_PrintAttr.bColor,true ); - - QRect rcDraw1(nBegin + j*oneWaveWidth,0,qMin(oneWaveWidth,nEnd - nBegin - j*oneWaveWidth),nTimeHeight); - QPoint ptOffset2(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nWaveHeight+nTimeHeight + dTopMargin ); - m_pTimeAxisView->PrintB( &paint, rcDraw1 ,ptOffset2, m_PrintAttr.bColor , false ); - } - else - { - QRect rcDraw(j*oneWaveWidth,0,oneWaveWidth,nTimeHeight); - QPoint ptOffset1(nWidth1+dLeftMargin - j*oneWaveWidth,dTopMargin ); - m_pTimeAxisView->PrintB( &paint, rcDraw ,ptOffset1, m_PrintAttr.bColor,true ); - - QRect rcDraw1(j*oneWaveWidth,0,oneWaveWidth,nTimeHeight); - QPoint ptOffset2(nWidth1+dLeftMargin - j*oneWaveWidth,nWaveHeight+nTimeHeight + dTopMargin ); - m_pTimeAxisView->PrintB( &paint, rcDraw1 ,ptOffset2, m_PrintAttr.bColor , false ); - } - - } - - if(m_PrintAttr.bTitlePrint) - { - QString szPage; - szPage.sprintf("Page %d",nIndex++); - QRect rcPrint(0,0,drawPagew,drawPageh); - QRect rcDraw(0,0,drawPagew,drawPageh); - paint.setPen(QPen(Qt::black)); - paint.drawLine(QPoint(nWidth1+dLeftMargin,dTopMargin + nTimeHeight),QPoint(nWidth1+dLeftMargin,dTopMargin+nWaveHeight+nTimeHeight)); - paint.drawLine(QPoint(dLeftMargin,dTopMargin + nTimeHeight),QPoint(dLeftMargin,dTopMargin+nWaveHeight+nTimeHeight)); - paint.drawText(QRect(20,drawPageh - nTitleHeight,drawPagew,nTitleHeight),Qt::AlignLeft | Qt::TextSingleLine,szTitle); - paint.drawText(QRect(20,drawPageh - nTitleHeight,drawPagew,nTitleHeight),Qt::AlignHCenter | Qt::TextSingleLine,szPage); - } - - paint.end(); - ImageList.append(map); - } - nAnaTop = nAnaTop + nAnaHeight; - nDgtTop = nDgtTop + nDgtHeight; - } - - QWidget* pWin = pParent; - if( !pWin ) - pWin = this; - - CPrintPreview view( pWin ); - view.setPages( ImageList ); - if ( view.exec() ) { - Print(true); - } -} - -//******************************************************************** -// 画X分隔条 -//******************************************************************** -void CWaveShow::DrawXSplitterBar( QPainter *paint, int nXPos, int nYPos) -{ - QRect rcClient; - rcClient = geometry(); - - qDrawShadePanel(paint,QRect(nXPos,rcClient.top(),SPLITTERWIDTH,nYPos - rcClient.top()),palette()); -} - - -//******************************************************************** -// 画Y分隔条 -//******************************************************************** -void CWaveShow::DrawYSplitterBar( QPainter *paint , int nYPos) -{ - QRect rcClient; - rcClient = geometry(); - - qDrawShadePanel(paint,QRect(rcClient.left(),nYPos,rcClient.width(),SPLITTERWIDTH),palette()); -} - -//******************************************************************** -// 画Y底部的分隔条 -//******************************************************************** -void CWaveShow::DrawYBottomSplitterBar( QPainter *paint , int nYPos) -{ - QRect rcClient; - rcClient = geometry(); - - //qDrawShadePanel(paint,QRect(rcClient.left(),nYPos,rcClient.width(),1),palette()); - paint->drawLine(QPoint(rcClient.left(),nYPos),QPoint(rcClient.right(),nYPos+20)); -} - -//******************************************************************** -//滚动 -//******************************************************************** -void CWaveShow::VAnaScroll(int nValue) -{ - if(m_pAnalogueView) - m_pAnalogueView->VScroll(nValue); - if(m_pAnaAxisView) - m_pAnaAxisView->VScroll(nValue); -} - -void CWaveShow::VDgtScroll(int nValue) -{ - if(m_pDigitalView) - m_pDigitalView->VScroll(nValue); - if(m_pDgtNameView) - m_pDgtNameView->VScroll(nValue); -} - -void CWaveShow::HTimeScroll(int nValue) -{ - if(m_pTimeAxisView) - m_pTimeAxisView->HScroll(nValue); - if(m_pAnalogueView) - m_pAnalogueView->HScroll(nValue); - if(m_pDigitalView) - m_pDigitalView->HScroll(nValue); -} - -void CWaveShow::HitTestWave( int nScrollTop,int nY ) -{ - // int nHeight = ClientRect.height(); - int nWidth = m_pWaveFile->m_DispAttr.m_nLeftMargin; - double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - int nTopPos = 0; - int g; - int nCurAnalogueNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; - int nNameHeight = m_pWaveFile->m_DispAttr.m_nNameHeight; - QStringList szName; - for( g=0; gGetMaxWaveGroupNum()+1 && gIsWaveGroupEmpty( g ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[g]*/) - continue; - int nGroupHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[g]*dWaveZoomY1; - if(nGroupHeight<5) nGroupHeight=5; - - szName.clear(); - - int nChCount = 0; - int ChAna = 0; - for(ChAna = 0;ChAnam_nAnagueNum && ChAnam_DispAttr.m_nWaveGroup[ChAna]!=g) continue; - szName.append(m_pWaveFile->AnalogDataList[ChAna].m_sName); - nChCount++; - } - - for(int i = 0;im_nAnagueNum && jm_DispAttr.m_nWaveGroup[j]!=g) continue; - if(m_pWaveFile->AnalogDataList[j].m_sName == szName[i]) - { - if(grpArea1.contains(QPoint(5,nScrollTop+nY),true)) - { - nCurAnalogueNo = j; - break; - } - } - - } - } -// //记录每个波形的区域 -// QRect grpArea = QRect(0,nTopPos,nWidth,nGroupHeight); -// -// int Ch=0; -// for(Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=g) continue; -// -// if( grpArea.contains( QPoint(5,nScrollTop+nY),true)) -// { -// nCurAnalogueNo = Ch; -// break; -// } -// } - nTopPos += nGroupHeight; - } - - m_pWaveFile->m_DispAttr.m_nSelAnalogueNo = nCurAnalogueNo; - if(nCurAnalogueNo>=0) - { - m_pWaveFile->m_DispAttr.m_nSelDigitalNo = -1; - redrawWindow( 1,false); - redrawWindow( 3,false); - } -} - -void CWaveShow::HitTestTag( int nScrollTop,int nY ) -{ - int nWidth = 10; - int nCurDigitalNo = -1; - int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); - if(nTagsHeight<5) nTagsHeight=5; - - int nTopPos = 0; - for(int ch=0;ch<=m_pWaveFile->m_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0) continue; - - QRect dgtArea = QRect(0,nTopPos,nWidth,nTagsHeight); - if(dgtArea.contains(QPoint(5,nScrollTop+nY),true)) - { - nCurDigitalNo = ch; - break; - } - nTopPos += nTagsHeight; - } - - m_pWaveFile->m_DispAttr.m_nSelDigitalNo = nCurDigitalNo; - if(nCurDigitalNo>=0) - { - m_pWaveFile->m_DispAttr.m_nSelAnalogueNo = -1; - redrawWindow( 1,false); - redrawWindow( 3,false); - } -} - -void CWaveShow::redrawWindow(int i , bool bErase) -{ - Q_UNUSED(bErase) - switch(i) - { - case 0: - update();break; - case 1: - if(m_pAnaAxisView) m_pAnaAxisView->update();break; - case 2: - if(m_pAnalogueView) m_pAnalogueView->update();break; - case 3: - if(m_pDgtNameView) m_pDgtNameView->update();break; - case 4: - if(m_pDigitalView) m_pDigitalView->update();break; - case 5: - if(m_pTimeAxisView) m_pTimeAxisView->update();break; - case 7: - if(m_pLinStatusView) m_pLinStatusView->update();break; - - } - if( (CWaveEnv::GetInst()->m_fZoomXX != m_pWaveFile->m_DispAttr.m_fZoomX)|| - (CWaveEnv::GetInst()->m_dWaveZoomYY != m_pWaveFile->m_DispAttr.m_dWaveZoomY1) || - (CWaveEnv::GetInst()->m_dTagsZoomYY != m_pWaveFile->m_DispAttr.m_dTagsZoomY1) || - (CWaveEnv::GetInst()->m_nLeftMarginName != m_nLeftMargin) ) - { - CWaveEnv::GetInst()->m_fZoomXX = m_pWaveFile->m_DispAttr.m_fZoomX; - CWaveEnv::GetInst()->m_dWaveZoomYY = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; - CWaveEnv::GetInst()->m_dTagsZoomYY = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; - CWaveEnv::GetInst()->m_nLeftMarginName = m_nLeftMargin; - CWaveEnv::GetInst()->SaveZoomSet(); - } - -} - -int CWaveShow::GetCurAnaChannel() -{ - return m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; -} - -int CWaveShow::GetCurDgtChannel() -{ - return m_pWaveFile->m_DispAttr.m_nSelDigitalNo; -} - -void CWaveShow::ZoomFull() -{ - QRect rect = m_pAnalogueView->rect(); - int nSample = 0; - for(int i = 0; i < m_pWaveFile->m_nNRates; i++) - nSample += m_pWaveFile->m_lSampleAmount[i]; - double dTemp1 = 0; - double dTemp2 = 0; - dTemp1 = rect.width()*1.0-80.0; - dTemp2 = nSample*m_pWaveFile->m_DispAttr.m_dGridWidth; - int dTemp = int(dTemp2/dTemp1); - if(dTemp == 0) - { - int dTemp3 = 1.0; - dTemp3 = int((dTemp1/dTemp2+.5)*0.8); - m_pWaveFile->m_DispAttr.m_fZoomX = double(dTemp3); - } - else - { - dTemp = int((1.2*dTemp2)/dTemp1+.5); - m_pWaveFile->m_DispAttr.m_fZoomX = double(1.0/dTemp); - } - m_pTimeAxisView->ResetHScrollSize(); - - int xPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fStaticTick ); - int nHScroll = xPosition - rect.width()/2; - //int nHScroll = xPosition - rect.width(); - if(nHScroll<0) nHScroll =0; - - HTimeScroll(nHScroll); - - redrawWindow(2,false); - redrawWindow(4,false); - redrawWindow(5,false); -} - -void CWaveShow::ResumeZoom() -{ - m_pTimeAxisView->m_nScrollLeft = 0; - m_pAnalogueView->m_nScrollTop = 0; - m_pDigitalView->m_nScrollTop = 0; - m_pTimeAxisView->ResetHScrollSize(); - m_pAnalogueView->ResetVScrollSize(); - m_pDigitalView->ResetVScrollSize(); - m_pAnalogueView->vert_bar->setValue(0); - m_pDigitalView->vert_bar->setValue(0); - m_pTimeAxisView->horiz_bar->setValue(0); - - redrawWindow(1,false); - redrawWindow(2,false); - redrawWindow(3,false); - redrawWindow(4,false); - redrawWindow(5,false); -} - -void CWaveShow::showStatus() -{ -// if(m_statusBar) -// { -// startLabel->setText(tr("B线:%1").arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fBaseTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); -// endLabel->setText(tr("C线:%1").arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fStaticTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); -// statusLabel->setText("OK!"); -// } - emit StatusEmited(); -} - -void CWaveShow::ShowAllTags() -{ - if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWALL) - m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWNONE; - else - m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWALL; - RecacuAreas(); - if(m_pDigitalView) - m_pDigitalView->ResetVScrollSize(); - redrawWindow(3,false); - redrawWindow(4,false); -} - -void CWaveShow::ShowActionTags() -{ - int nDigtialActive = 0; - for(int i = 0;im_nDigitalNum;i++) - { - int nTickTemp = 0; - for(nTickTemp = 0;nTickTempDigitDataList[i].m_bySampleData.count();nTickTemp++) - { - byte nTickBy = m_pWaveFile->DigitDataList[i].m_bySampleData[nTickTemp]; - if(nTickBy == 1) - break; - } - if(nTickTemp == m_pWaveFile->DigitDataList[i].m_bySampleData.count()) - continue; - nDigtialActive++; - } - if(nDigtialActive > 0) - m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWACTION; - else - m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWNONE; - RecacuAreas(); - if(m_pDigitalView) - m_pDigitalView->ResetVScrollSize(); - redrawWindow(3,false); - redrawWindow(4,false); -} - -void CWaveShow::ShowNoneTags() -{ - m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWNONE; - RecacuAreas(); - if(m_pDigitalView) - m_pDigitalView->ResetVScrollSize(); - redrawWindow(3,false); - redrawWindow(4,false); -} - -void CWaveShow::setLineValueType( int nType ) -{ - for(int i = 0;iAnalogDataList.count();i++) - { - CAnalogData& ana = m_pWaveFile->AnalogDataList[i]; - if( ana.m_nWaveType>=CHN_AMP0_ATTR&&ana.m_nWaveType<=CHN_AMP99_ATTR ) - continue; - m_pWaveFile->AnalogDataList[i].m_nWaveType = nType; - } - m_pWaveFile->SetUnitType(m_pWaveFile->m_DispAttr.m_byValueType); - if(m_pAnaAxisView) m_pAnaAxisView->update(); - if(m_pAnalogueView) m_pAnalogueView->update(); - if(m_pDgtNameView) m_pDgtNameView->update(); - if(m_pDigitalView) m_pDigitalView->update(); - if(m_pTimeAxisView) m_pTimeAxisView->update(); - update(); -} +#include "CWaveShow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CPublic.h" +#include +#include +#include +#include +#include +#include "stdlib.h" +#include +#include +//#include "cprintsetupdlg.h" +//#include "clabelsetdlg.h" +//#include "clabelbrowser.h" +#include "CPrintPreview.h" +//#include "czoomsetdlg.h" +//#include "cstylesetdialog.h" +//#include "canagroupset.h" +//#include "cdgtgroupset.h" +//#include "canatableset.h" +//#include "cdgttableset.h" +//#include "cgridset.h" +//#include "ccopywaveset.h" +///////////////////////////////////////////////////// +CWaveShow::CWaveShow(QWidget *parent, Qt::WindowFlags f ) + :QFrame(parent,f) +{ + printer = 0; + m_pRectBand = 0; + m_pVLineBand = 0; + m_pHLineBand = 0; + setWindowFlag( Qt::WindowStaysOnTopHint ); + setMouseTracking(true); + +// QPalette p = palette(); +// p.setColor(backgroundRole(), CWaveEnv::GetInst()->m_statusBackColor); +// setPalette(p); +// setAutoFillBackground(true); + +// setFrameShape( QFrame::WinPanel ); +// setFrameShadow( QFrame::Sunken ); + //{{hor scroll +// QVBoxLayout* vboxLayout = new QVBoxLayout(this); +// vboxLayout->setSpacing(0); +// vboxLayout->setContentsMargins(0, 0, 0, 0); +// +// QSpacerItem* spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding); +// horiz_bar = new QScrollBar(Qt::Horizontal,this); +// vboxLayout->addItem(spacerItem); +// vboxLayout->addWidget( horiz_bar ); +// +// horiz_bar->setRange(0,0); +// horiz_bar->setSingleStep(SCROLLBAR_H_LINE); +// horiz_bar->setPageStep(SCROLLBAR_H_LINE*5); +// horiz_bar->setTracking(false); + //}} + + m_bOnYMoveBar = false; + m_bOnXMoveBar = false; + m_nLastYPos = 0; + m_nLastXPos = 0; + m_nCursorX = -1; + m_nZoomState = SINGLEZOOM_NULL; + + m_bZoomStart = false; + + moveleftAction = new QAction( "moveleftAction",this ); + moveleftAction->setShortcut(QKeySequence(Qt::Key_Left)); + moverightAction = new QAction( "moverightAction",this ); + moverightAction->setShortcut( QKeySequence(Qt::Key_Right) ); + + connect( moveleftAction, SIGNAL( triggered(bool) ), this, SLOT( OnMoveStepLeft() ) ); + connect( moverightAction, SIGNAL( triggered(bool) ), this, SLOT( OnMoveStepRight() ) ); + connect( this,SIGNAL( ZoomSelected() ), this, SLOT( OnZoomSelected() ) ); + + m_hArrowCursor.setShape(Qt::ArrowCursor); + m_hUpDownCursor.setShape(Qt::SplitVCursor); + m_hLeftRightCursor.setShape(Qt::SplitHCursor); + + m_hCrossCursor.setShape(Qt::CrossCursor); + m_hHandCursor.setShape(Qt::PointingHandCursor); + + m_hZoomIn = QCursor( QPixmap(":/images/zoomin.xpm") ); + m_hZoomOut = QCursor( QPixmap(":/images/zoomout.xpm") ); + m_hZoomRect = QCursor( QPixmap(":ico/ico/zoomrect.xpm") ); + + m_pWaveFile = 0L; + + m_pAnalogueView = new CAnalogueShow(this); + m_pDigitalView = new CDigitalShow(this); + m_pAnaAxisView = new CAnaAxisShow(this); + m_pDgtNameView = new CDgtNameShow(this); +// m_pTimeAxisView = new CTimeAxisShow(this,horiz_bar); + m_pTimeAxisView = new CTimeAxisShow(this,0); +// m_pStatusView = new CStatusShow(this); + m_pLinStatusView = new CLineStatusShow(this); + + //resize(QSize(600,700).expandedTo(minimumSizeHint())); + resize(QSize(400,300).expandedTo(minimumSizeHint())); + setMinimumSize(QSize(400,300)); + m_fWaveHeightRate = 0.75f; + m_nLeftMargin = WAVE_LEFTMARGIN; +// m_nLeftMargin = 300; + //m_nLeftMargin = CWaveEnv::GetInst()->m_nLeftMarginName; +// m_nTimeViewTop = 700 - WAVE_TIMEAXISHEIGHT - WAVE_STATUSHEIGHT; + m_nTimeViewTop = 300 - WAVE_TIMEAXISHEIGHT - WAVE_STATUSHEIGHT; + m_nTimeViewHgt = WAVE_TIMEAXISHEIGHT; + m_nWaveViewTop = 0; + m_nWaveViewHgt = m_nTimeViewTop*m_fWaveHeightRate; + m_nMinViewHgt = 0; + + m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; + m_nTagsViewHgt = m_nTimeViewTop - m_nTagsViewTop; + + RecacuAreas(); + + m_bPixmapCapturePt1 = false; + m_bPixmapCaptureStart = false; + m_pCapturePt1 = QPoint(0,0); + m_pCapturePt2 = QPoint(0,0); + m_ptSelectLastPt = QPoint(0,0); + + installEventFilter( this ); + m_pAnalogueView->installEventFilter( this ); + m_pDigitalView->installEventFilter( this ); + m_pTimeAxisView->installEventFilter( this ); + // + m_PrintAttr.bOrient = true; + m_PrintAttr.bLinePrint = false; + m_PrintAttr.bAnaPrint = true; + m_PrintAttr.bColor = true; + m_PrintAttr.bDgtPrint = true; + m_PrintAttr.bNamePrint = true; + m_PrintAttr.bTimePrint = true; + m_PrintAttr.bTitlePrint = true; + m_PrintAttr.bZonePrint = false; + m_PrintAttr.dBottomMargin = 20.0; + m_PrintAttr.dLeftMargin = 20.0; + m_PrintAttr.dRightMargin = 20.0; + m_PrintAttr.dTopMargin = 20.0; +} + +CWaveShow::~CWaveShow() +{ + if(printer) + delete printer; + printer = 0; +} + +void CWaveShow::RecacuAreas() +{ + QSize s = frameSize(); + + if( m_pWaveFile ) + { + m_nLeftMargin = m_pWaveFile->m_DispAttr.m_nLeftMargin; + if( m_nLeftMargin<50 ) + m_nLeftMargin = 50; + } + else + { + m_nLeftMargin = WAVE_LEFTMARGIN; + } + + m_nLeftMargin = CWaveEnv::GetInst()->m_nLeftMarginName; + double nMainHeight = s.height() - WAVE_TIMEAXISHEIGHT; + //时标top,height + m_nTimeViewTop = nMainHeight; + m_nTimeViewHgt = WAVE_TIMEAXISHEIGHT; + if(m_pWaveFile) + { + if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWNONE) + { + //模拟量top,height + m_nWaveViewTop = 0; + m_nWaveViewHgt = nMainHeight; + //数字量top,height + m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; + m_nTagsViewHgt = nMainHeight - m_nTagsViewTop; + } + else + { + //模拟量top,height + m_nWaveViewTop = 0; + m_nWaveViewHgt = nMainHeight*m_fWaveHeightRate; + //数字量top,height + m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; + m_nTagsViewHgt = nMainHeight - m_nTagsViewTop; + } + } + else + { + //模拟量top,height + m_nWaveViewTop = 0; + m_nWaveViewHgt = nMainHeight*m_fWaveHeightRate; + //数字量top,height + m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; + m_nTagsViewHgt = nMainHeight - m_nTagsViewTop; + } + + /*//{{ + m_nTimeViewTop = CWaveEnv::GetInst()->m_nTimeViewTop1; + m_nTimeViewHgt = CWaveEnv::GetInst()->m_nTimeViewHgt1; + + m_nWaveViewTop = CWaveEnv::GetInst()->m_nWaveViewTop1; + m_nWaveViewHgt = CWaveEnv::GetInst()->m_nWaveViewHgt1; + m_nTagsViewTop = m_nWaveViewTop + m_nWaveViewHgt; + m_nTagsViewHgt = nMainHeight - m_nTagsViewTop; + //}}*/ + MoveAllViews(); +} + +void CWaveShow::MoveAllViews() +{ + QSize s = frameSize(); + + //ana name + QRect rc1(0,m_nWaveViewTop,m_nLeftMargin,m_nWaveViewHgt); + //ana show + QRect rc2(m_nLeftMargin+SPLITTERWIDTH,m_nWaveViewTop,s.width() - m_nLeftMargin -SPLITTERWIDTH,m_nWaveViewHgt); + //dgt name + QRect rc3(0,m_nTagsViewTop+SPLITTERWIDTH,m_nLeftMargin,m_nTagsViewHgt-SPLITTERWIDTH); + //dgt show + QRect rc4(m_nLeftMargin+SPLITTERWIDTH,m_nTagsViewTop+SPLITTERWIDTH,s.width() - m_nLeftMargin -SPLITTERWIDTH,m_nTagsViewHgt-SPLITTERWIDTH); +// QRect rc5(0,m_nTimeViewTop+SPLITTERWIDTH,s.width(),WAVE_TIMEAXISHEIGHT-SPLITTERWIDTH); +// QRect rc6(0,m_nTimeViewTop+WAVE_TIMEAXISHEIGHT+SPLITTERWIDTH,s.width(),WAVE_STATUSHEIGHT-SPLITTERWIDTH -20); + //time + QRect rc5(m_nLeftMargin+SPLITTERWIDTH,m_nTimeViewTop+1/*+SPLITTERWIDTH*/,s.width() - m_nLeftMargin -SPLITTERWIDTH,WAVE_TIMEAXISHEIGHT-1/*-SPLITTERWIDTH*/); + //status + QRect rc6(0,m_nTimeViewTop+1/*+SPLITTERWIDTH*/,m_nLeftMargin,WAVE_TIMEAXISHEIGHT-1/*-SPLITTERWIDTH*/); + + m_pAnaAxisView->setGeometry(rc1); + m_pAnaAxisView->update(); + m_pAnalogueView->setGeometry(rc2); + m_pAnalogueView->update(); + m_pDgtNameView->setGeometry(rc3); + m_pDgtNameView->update(); + m_pDigitalView->setGeometry(rc4); + m_pDigitalView->update(); + m_pTimeAxisView->setGeometry(rc5); + m_pTimeAxisView->update(); + m_pLinStatusView->setGeometry(rc6); + m_pLinStatusView->update(); + + update(); + + CWaveEnv::GetInst()->m_nLeftMarginName = m_nLeftMargin; + + CWaveEnv::GetInst()->m_nTimeViewTop1 = m_nTimeViewTop; + CWaveEnv::GetInst()->m_nTimeViewHgt1 = m_nTimeViewHgt; + CWaveEnv::GetInst()->m_nWaveViewTop1 = m_nWaveViewTop; + CWaveEnv::GetInst()->m_nWaveViewHgt1 = m_nWaveViewHgt; + CWaveEnv::GetInst()->m_nTagsViewTop1 = m_nTagsViewTop; + CWaveEnv::GetInst()->m_nTagsViewHgt1 = m_nTagsViewHgt; + + CWaveEnv::GetInst()->SaveZoomSet(); + +} +////////////////////////////////////////////////////////////////////////// +bool CWaveShow::eventFilter( QObject* obj,QEvent* e ) +{ + if( e->type() == QEvent::MouseMove ) + { + QMouseEvent* mev = (QMouseEvent*)e; + if( obj == this ) + OnMouseMoveEvent( mev ); + if( m_nZoomState==ZOOMRECT_X ) + mev->ignore(); + if( obj == m_pAnalogueView && mev->isAccepted() ) + m_pAnalogueView->OnMouseMoveEvent(mev); + if( obj == m_pDigitalView && mev->isAccepted() ) + m_pDigitalView->OnMouseMoveEvent(mev); + if( obj == m_pTimeAxisView && mev->isAccepted() ) + m_pTimeAxisView->OnMouseMoveEvent(mev); + } + else if(e->type() == QEvent::MouseButtonPress) + { + QMouseEvent* mev = (QMouseEvent*)e; + if( obj == this ) + OnMousePressEvent( mev ); + if( m_nZoomState==ZOOMRECT_X ) + mev->ignore(); + + if( obj == m_pAnalogueView && mev->isAccepted() ) + m_pAnalogueView->OnMousePressEvent(mev); + if( obj == m_pDigitalView && mev->isAccepted() ) + m_pDigitalView->OnMousePressEvent(mev); + if( obj == m_pTimeAxisView && mev->isAccepted() ) + m_pTimeAxisView->OnMousePressEvent(mev); + } + else if(e->type() == QEvent::MouseButtonRelease) + { + QMouseEvent* mev = (QMouseEvent*)e; + if( obj == this ) + OnMouseReleaseEvent( mev ); + if( m_nZoomState==ZOOMRECT_X ) + mev->ignore(); + if( obj == m_pAnalogueView && mev->isAccepted() ) + m_pAnalogueView->OnMouseReleaseEvent(mev); + if( obj == m_pDigitalView && mev->isAccepted() ) + m_pDigitalView->OnMouseReleaseEvent(mev); + if( obj == m_pTimeAxisView && mev->isAccepted() ) + m_pTimeAxisView->OnMouseReleaseEvent(mev); + } + + return false; +} + +void CWaveShow::OnMousePressEvent( QMouseEvent *e ) +{ +////////////////////////////////////////////////////////////// + if ( e->button() == Qt::LeftButton ) { +/////////////////////////////////////////////////////////// + if(m_pWaveFile) + { + if(m_bPixmapCapturePt1) + { + m_pCapturePt1 = e->pos(); + if(m_pCapturePt1.x()m_nTimeViewTop) + m_pCapturePt1.ry() = m_nTimeViewTop - 1; + + m_ptSelectLastPt = m_pCapturePt1; + + + if (!m_pRectBand) + m_pRectBand = new QRubberBand(QRubberBand::Rectangle, this); + m_pRectBand->setGeometry(QRect(m_pCapturePt1,m_ptSelectLastPt)); + m_pRectBand->show(); + + m_bPixmapCaptureStart = true; + + } + else if( m_nZoomState==ZOOMRECT_X ) + { + m_ptZoomOld = e->pos(); + m_ptZoomNew = e->pos(); + m_bZoomStart = true; + + if (!m_pRectBand) + m_pRectBand = new QRubberBand(QRubberBand::Rectangle, this); + m_pRectBand->setGeometry(QRect(m_ptZoomOld,m_ptZoomNew)); + m_pRectBand->show(); + + e->ignore(); + } + else + { + + if((!m_bOnYMoveBar) + && (e->y() >= (m_nTagsViewTop-SPLITTERWIDTH) ) + && (e->y() < (m_nTagsViewTop+SPLITTERWIDTH)) ) + { + + setCursor( m_hUpDownCursor ); + m_bOnYMoveBar = true; + m_nLastYPos = e->y(); + + if( !m_pHLineBand ) + m_pHLineBand = new QRubberBand(QRubberBand::Line, this); + + int w = width(); + m_pHLineBand->setGeometry(QRect(0,m_nLastYPos, w,2)); + m_pHLineBand->show(); + } + else if((!m_bOnXMoveBar) + && (e->x() >= (m_nLeftMargin-SPLITTERWIDTH) ) + && (e->x() < (m_nLeftMargin+SPLITTERWIDTH) ) + &&e->y() < (m_nTimeViewTop+SPLITTERWIDTH) ) + { + setCursor( m_hLeftRightCursor ); + m_bOnXMoveBar = true; + m_nLastXPos = e->x(); + + if( !m_pVLineBand ) + m_pVLineBand = new QRubberBand(QRubberBand::Line, this); + + m_pVLineBand->setGeometry(QRect(m_nLastXPos,0,2,m_nTimeViewTop)); + m_pVLineBand->show(); + } + } + } +/////////////////////////////////////////////////////////////// + } +} + +void CWaveShow::OnMouseReleaseEvent( QMouseEvent *e ) +{ + if( e->button() == Qt::LeftButton ) + { +///////////////////////////////////////////////////////////////// + if(m_pWaveFile) + { + if(m_bPixmapCapturePt1) + { + m_bPixmapCapturePt1 = false; + m_bPixmapCaptureStart = false; + m_pCapturePt2 = e->pos(); + + if(m_pCapturePt2.x()m_nTimeViewTop) + m_pCapturePt2.ry() = m_nTimeViewTop - 1; + + copySelectToClip(); + if (m_pRectBand) + m_pRectBand->hide(); + + } + else if(m_bOnYMoveBar) + { + m_bOnYMoveBar = false; + + QRect rcClient; + rcClient = rect(); + +// int nTotalHgt = rcClient.height(); +// int nBarHeight = SPLITTERWIDTH; + + // Calcu Top + // + int nPos = m_nLastYPos+2; + if(nPos+m_nMinViewHgt > m_nTimeViewTop) + { + m_nTagsViewTop = m_nTimeViewTop - m_nMinViewHgt; + } + else if(nPos-m_nMinViewHgt < 0) + { + m_nTagsViewTop = m_nMinViewHgt; + } + else m_nTagsViewTop = nPos; + // Calcu Height + // + m_nTimeViewHgt = rcClient.bottom() - m_nTimeViewTop; + m_nTagsViewHgt = m_nTimeViewTop - m_nTagsViewTop; + m_nWaveViewHgt = m_nTagsViewTop - rcClient.top(); + m_fWaveHeightRate = (float)m_nWaveViewHgt/(float)(m_nWaveViewHgt+m_nTagsViewHgt); + if( m_pHLineBand ) + m_pHLineBand->hide(); + // Move Window + // + MoveAllViews(); + m_pAnalogueView->ResetVScrollSize(); + m_pDigitalView->ResetVScrollSize(); + } + else if(m_bOnXMoveBar) + { + m_bOnXMoveBar = false; + + m_nLeftMargin = m_nLastXPos; + + if( m_pVLineBand ) + m_pVLineBand->hide(); + // Move Window + // + MoveAllViews(); + m_pAnalogueView->ResetVScrollSize(); + m_pDigitalView->ResetVScrollSize(); + m_pTimeAxisView->ResetHScrollSize(); + } + else if( m_nZoomState==ZOOMRECT_X && m_bZoomStart ) + { + m_bZoomStart = false; + SetZoomState( SINGLEZOOM_NULL ); + + if (m_pRectBand) + m_pRectBand->hide(); + + e->ignore(); + emit ZoomSelected(); + } + + releaseMouse(); + setCursor( m_hArrowCursor ); + } +//////////////////////////////////////////////////// + } + else if( e->button() == Qt::RightButton ) + { + m_bZoomStart = false; + SetZoomState( SINGLEZOOM_NULL ); +//////////////////////////////////////////////////// + } +} + +void CWaveShow::OnMouseMoveEvent( QMouseEvent *e ) +{ +///////////////////////////////////////////////////////////////// + if(m_bPixmapCapturePt1 && m_bPixmapCaptureStart) + { + QPoint ptCur = e->pos(); + m_ptSelectLastPt = ptCur; + if(m_pRectBand) + m_pRectBand->setGeometry(QRect(m_pCapturePt1,m_ptSelectLastPt) ); + } + else if( m_nZoomState==ZOOMRECT_X && m_bZoomStart ) + { + m_ptZoomNew = e->pos(); + if(m_pRectBand) + m_pRectBand->setGeometry(QRect(m_ptZoomOld,m_ptZoomNew)); + e->ignore(); + return; + } + else if(m_bOnYMoveBar) + { + setCursor( m_hUpDownCursor ); + if(e->buttons() & Qt::LeftButton) + { + m_nLastYPos = e->y(); + int w = width(); + if( m_pHLineBand ) + m_pHLineBand->setGeometry(QRect(0,m_nLastYPos,w,2)); + } + else + { + m_bOnYMoveBar = false; + if( m_pHLineBand ) + m_pHLineBand->hide(); + setCursor( m_hArrowCursor ); + } + } + else if(m_bOnXMoveBar) + { + setCursor( m_hLeftRightCursor ); + if(e->buttons() & Qt::LeftButton) + { + m_nLastXPos = e->x(); + if( m_pVLineBand ) + m_pVLineBand->setGeometry(QRect(m_nLastXPos,0,2,m_nTimeViewTop+TIMEAXIS_HEIGHT+20)); + } + else + { + m_bOnXMoveBar = false; + if( m_pVLineBand ) + m_pVLineBand->hide(); + setCursor( m_hArrowCursor ); + } + } + else + { + if(e->y() >= m_nTagsViewTop + && e->y() < m_nTagsViewTop+SPLITTERWIDTH) + { + setCursor( m_hUpDownCursor ); + } + else if( e->x() >= m_nLeftMargin + && e->x() < (m_nLeftMargin+SPLITTERWIDTH) + && e->y() < (m_nTimeViewTop+SPLITTERWIDTH) ) + { + setCursor( m_hLeftRightCursor ); + } + else + { + setCursor( m_hArrowCursor ); + } + } +///////////////////////////////////////////////////// +// update(); +} + +void CWaveShow::paintEvent( QPaintEvent *e ) +{ + Q_UNUSED(e) + if( palette().color( QPalette::Background )!=CWaveEnv::GetInst()->m_WaveBackColor ) + { + QPalette palette; + palette.setColor(QPalette::Light, CWaveEnv::GetInst()->m_MoveLineColor); + palette.setColor(QPalette::Dark, CWaveEnv::GetInst()->m_MoveLineColor); + palette.setColor(QPalette::Mid, CWaveEnv::GetInst()->m_WaveBackColor); + palette.setColor(backgroundRole(), CWaveEnv::GetInst()->m_WaveBackColor); + setPalette(palette); + } + + QPainter paint; + paint.begin(this ); + DoDraw( &paint ); + paint.end(); + +} + +void CWaveShow::resizeEvent(QResizeEvent* event) +{ + RecacuAreas(); + m_pAnalogueView->ResetVScrollSize(); + m_pDigitalView->ResetVScrollSize(); + m_pTimeAxisView->ResetHScrollSize(); + QWidget::resizeEvent( event ); +} + +void CWaveShow::DoDraw( QPainter *paint ) +{ +// DrawXSplitterBar(paint, m_nLeftMargin,m_nTimeViewTop); + DrawXSplitterBar(paint, m_nLeftMargin,m_nTimeViewTop + WAVE_TIMEAXISHEIGHT + 20); + DrawYSplitterBar(paint, m_nTagsViewTop); + //DrawYSplitterBar(paint, m_nTimeViewTop); + //DrawYBottomSplitterBar(paint, m_nTimeViewTop); + + +// if( m_pStatusView ) +// m_pStatusView->Refresh(); +// if(m_pLinStatusView) +// m_pLinStatusView->Refresh(); + +} +void CWaveShow::PrintPageTitle(QPainter *paint,QString szTitle,int nPageNo) +{ + if(!m_pWaveFile) return; + QString szPage; + szPage.sprintf("Page %d",nPageNo); + QRect rect = paint->viewport(); + paint->drawText(rect,Qt::AlignLeft | Qt::TextSingleLine,szTitle); + paint->drawText(rect,Qt::AlignHCenter | Qt::TextSingleLine,szTitle); + +} +//////////////////////////////////////////////////////////////////////// +void CWaveShow::OnAddLabel() +{ +// AddLabel(); +} + +void CWaveShow::OnLabelList() +{ +// ShowLabels(); +} + +void CWaveShow::OnSetZoneStart() +{ + m_pWaveFile->m_DispAttr.m_fBaseTime = m_pWaveFile->m_DispAttr.m_fCurrentTime; + m_pWaveFile->m_DispAttr.m_fBaseTick = m_pWaveFile->m_DispAttr.m_fCurrentTick; + + m_pWaveFile->m_DispAttr.m_bShowZoon = true; + redrawWindow(1,false);//在名称去显示数据值,20090818 + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); + redrawWindow(7,false); + showStatus(); + m_pWaveFile->EmitLineBChanged(); +} + +void CWaveShow::OnSetZoneEnd() +{ + m_pWaveFile->m_DispAttr.m_bShowZoon = true; + redrawWindow(1,false);//在名称去显示数据值,20090818 + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); + redrawWindow(7,false); + showStatus(); + m_pWaveFile->EmitLineBChanged(); +} + +void CWaveShow::OnCacelZone() +{ + m_pWaveFile->m_DispAttr.m_fBaseTime = m_pWaveFile->m_nFrist_ms; + m_pWaveFile->m_DispAttr.m_fBaseTick = 0; + + m_pWaveFile->m_DispAttr.m_bShowZoon = false; + redrawWindow(1,false);//在名称去显示数据值,20090818 + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); + redrawWindow(7,false); + showStatus(); + m_pWaveFile->EmitLineBChanged(); +} + +void CWaveShow::OnAnaAmpSingleIn() +{ + int ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + m_pWaveFile->m_DispAttr.m_dWaveHeight[ch] += 5.0; + double dMax = m_pWaveFile->m_aChMaximumArray[ch]; + m_pWaveFile->m_DispAttr.m_fWaveZoom[ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[ch])*45.0 + /double(dMax); + redrawWindow(1,false); + redrawWindow(2,false); +} + +void CWaveShow::OnAnaAmpSingleOut() +{ + int ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + m_pWaveFile->m_DispAttr.m_dWaveHeight[ch] -= 5.0; + double dMax = m_pWaveFile->m_aChMaximumArray[ch]; + m_pWaveFile->m_DispAttr.m_fWaveZoom[ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[ch])*45.0 + /double(dMax); + redrawWindow(1,false); + redrawWindow(2,false); +} + +void CWaveShow::OnAnaAmpIn() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0 || Ch>=MAX_WAVES) + return; + double dMax = m_pWaveFile->m_aChMaximumArray[Ch]*(0.5); + m_pWaveFile->m_aChMaximumArray[Ch] = dMax ; + m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch])*45.0 + /double(dMax); + redrawWindow(1,false); + redrawWindow(2,false); + +} + +void CWaveShow::OnAnaAmpOut() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0 || Ch>=MAX_WAVES) + return; + double dMax = m_pWaveFile->m_aChMaximumArray[Ch]*(2.0); + m_pWaveFile->m_aChMaximumArray[Ch] = dMax ; + m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch])*45.0 + /double(dMax); + redrawWindow(1,false); + redrawWindow(2,false); +} + +void CWaveShow::OnAnaAmpSet() +{ + +} + +void CWaveShow::OnAnaAreaIn() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0 || Ch>=MAX_WAVES) + return; + + int nGroupNo = m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]; + for( Ch=0;Chm_nAnagueNum;Ch++ ) + { + if(m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]!=nGroupNo) continue; + + m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch] += 5.0; + m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[nGroupNo])*45.0 + /double(m_pWaveFile->m_aChMaximumArray[Ch]); + } + + m_pAnalogueView->ResetVScrollSize(); + + redrawWindow(1,false); + redrawWindow(2,false); +} + +void CWaveShow::OnAnaAreaOut() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0 || Ch>=MAX_WAVES) + return; + int nGroupNo = m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]; + for( Ch=0;Chm_nAnagueNum;Ch++ ) + { + if(m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]!=nGroupNo) continue; + + m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch] -= 5.0; + if(m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch] < 5.0) + m_pWaveFile->m_DispAttr.m_dWaveHeight[Ch] = 5.0; + + m_pWaveFile->m_DispAttr.m_fWaveZoom[Ch] = double(m_pWaveFile->m_DispAttr.m_dWaveHeight[nGroupNo])*45.0 + /double(m_pWaveFile->m_aChMaximumArray[Ch]); + } + + m_pAnalogueView->ResetVScrollSize(); + + redrawWindow(1,false); + redrawWindow(2,false); +} + +void CWaveShow::OnAnaColorSet() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0 || Ch>=MAX_WAVES) + return; + QColor clrWave = m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch]; + QColor clrWaveNew = QColorDialog::getColor(clrWave,this); + if( clrWaveNew.isValid() && clrWaveNew != clrWave ) + { + m_pWaveFile->m_DispAttr.m_dwWaveColor[Ch] = clrWaveNew; + redrawWindow(1,false); + redrawWindow(2,false); + } +} + +void CWaveShow::OnAnaLineSet() +{ +/* + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0 || Ch>=MAX_WAVES) + return; + + CStyleSetDialog dlg(this); + dlg.SetLineStyle( m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch],m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch] ); + dlg.Refresh(); + if( QDialog::Accepted == dlg.exec() ) + { + m_pWaveFile->m_DispAttr.m_nWaveLineStyle[Ch] = dlg.GetStyle(); + m_pWaveFile->m_DispAttr.m_nWaveLineWidth[Ch] = dlg.GetWidth(); + redrawWindow(1,false); + redrawWindow(2,false); + } +*/ +} + +void CWaveShow::OnDgtColorSet() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; + if( Ch<0 || Ch>=MAX_TAGS) + return; + QColor clrTag = m_pWaveFile->m_DispAttr.m_dwTagsColor[Ch]; + QColor clrTagNew = QColorDialog::getColor(clrTag,this); + if( clrTagNew.isValid() && clrTagNew != clrTag ) + { + m_pWaveFile->m_DispAttr.m_dwTagsColor[Ch] = clrTagNew; + redrawWindow(3,false); + redrawWindow(4,false); + } +} + +void CWaveShow::OnDgtLineSet() +{ +/* + int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; + if( Ch<0 || Ch>=MAX_TAGS) + return; + + CStyleSetDialog dlg(this); + dlg.SetLineStyle( m_pWaveFile->m_DispAttr.m_nTagsLineStyle[Ch],m_pWaveFile->m_DispAttr.m_nTagsLineWidth[Ch] ); + dlg.Refresh(); + if( QDialog::Accepted == dlg.exec() ) + { + m_pWaveFile->m_DispAttr.m_nTagsLineStyle[Ch] = dlg.GetStyle(); + m_pWaveFile->m_DispAttr.m_nTagsLineWidth[Ch] = dlg.GetWidth(); + redrawWindow(3,false); + redrawWindow(4,false); + } +*/ +} + +void CWaveShow::OnMoveStepLeft() +{ + if( m_pWaveFile ) + { + m_pWaveFile->m_DispAttr.m_fStaticTick--; + if( m_pWaveFile->m_DispAttr.m_fStaticTick<0 ) + { + m_pWaveFile->m_DispAttr.m_fStaticTick = 0; + } + m_pWaveFile->m_DispAttr.m_fStaticTime = m_pWaveFile->GetPointTime(m_pWaveFile->m_DispAttr.m_fStaticTick); + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); + redrawWindow(1,false);//在名称区显示数据值 +// if( m_pStatusView ) +// m_pStatusView->Refresh(); + m_pWaveFile->EmitLineCChanged(); + showStatus(); + update(); + } +} + +void CWaveShow::OnMoveStepRight() +{ + if( m_pWaveFile ) + { + m_pWaveFile->m_DispAttr.m_fStaticTick++; + m_pWaveFile->m_DispAttr.m_fStaticTime = m_pWaveFile->GetPointTime(m_pWaveFile->m_DispAttr.m_fStaticTick); + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); + redrawWindow(1,false);//在名称区显示数据值 +// if( m_pStatusView ) +// m_pStatusView->Refresh(); + m_pWaveFile->EmitLineCChanged(); + showStatus(); + update(); + } +} + +void CWaveShow::OnHideWaveChannel() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch<0 || Ch>=MAX_WAVES) + return; + + int nGroup = m_pWaveFile->m_DispAttr.m_nWaveGroup[Ch]; + m_pWaveFile->m_DispAttr.m_bWaveMarked[nGroup] = true; + + redrawWindow(1,false); + redrawWindow(2,false); + +} + +void CWaveShow::OnHideTagChannel() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelDigitalNo; + if( Ch<0 || Ch>=MAX_TAGS) + return; + + m_pWaveFile->m_DispAttr.m_nTagsGroup[Ch] = -1; + + redrawWindow(3,false); + redrawWindow(4,false); +} + + + +void CWaveShow::OnZoomSelected() +{ + //horizon + int nStartX = m_ptZoomNew.x()m_ptZoomOld.x()?m_ptZoomNew.x():m_ptZoomOld.x(); + //vertical + int nStartY = m_ptZoomNew.y()m_ptZoomOld.y()?m_ptZoomNew.y():m_ptZoomOld.y(); + //horizon + int nLeftMargin = CWaveEnv::GetInst()->m_nLeftMarginName/*SPLITTERWIDTH*/; + int nMidPos = ( nStartX + nEndX )/2 - nLeftMargin + m_pTimeAxisView->m_nScrollLeft; +// int nStartPos = nStartX - nLeftMargin + m_pTimeAxisView->m_nScrollLeft; + double dTick = m_pWaveFile->GetTick(nMidPos); +// double dTickStart = m_pWaveFile->GetTick(nStartPos); + //vertical + int nScrollTop = m_pAnalogueView->m_nScrollTop; + int nMidY = (nStartY + nEndY)/2; + //{{horizon + double fOldRate = m_pWaveFile->m_DispAttr.m_fZoomX; + QRect rect = m_pAnalogueView->rect(); + int nWidth = rect.width(); + int nTemp = 0; + double fNewRate; + if(fOldRate*(double)nWidth/(double)(nEndX-nStartX) < 1.0) + { + nTemp = (int)((nEndX-nStartX)/(fOldRate*(double)nWidth)); + fNewRate = 1.0/(double)nTemp; + } + else + fNewRate = (int)(fOldRate*(double)nWidth/(double)(nEndX - nStartX)); + if(fNewRate > 16.0) + fNewRate = 16.0; + if(fNewRate*256.0 < 8.0) + fNewRate = 8.0/256.0; + m_pWaveFile->m_DispAttr.m_fZoomX = fNewRate; + //}} + //{{vertical + double fOldRateY = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + int nHeight = rect.height(); + double fNewRateY = fOldRateY*nHeight/(nEndY - nStartY); + if(fNewRateY > 20.0) + fNewRateY = 20.0; + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = fNewRateY; + int nValue = (nMidY + nScrollTop)*fNewRateY/fOldRateY - nHeight/2; + //}} + + m_pTimeAxisView->ResetHScrollSize(); + m_pAnalogueView->ResetVScrollSize(); + + int xPosition = m_pWaveFile->GetPointPosition( dTick ); + + int nHScroll = xPosition - nWidth/2; + if(nHScroll<0) nHScroll =0; + //int nMaxWidth = m_pWaveFile->GetMaxWidth(); + m_pTimeAxisView->horiz_bar->setValue(nHScroll); + m_pAnalogueView->vert_bar->setValue(nValue); + + redrawWindow(1,false); + redrawWindow(2,false); + redrawWindow(3,false); + redrawWindow(4,false); + redrawWindow(5,false); + +} + +void CWaveShow::OnLineSliderMove(int pos) +{ + if( !CWaveEnv::GetInst()->m_bShowCompLine ) + return; + m_pAnalogueView->m_nCompPosY = pos; + redrawWindow(1,false); + redrawWindow(2,false); +} + +void CWaveShow::OnResumeGroup() +{ + m_pWaveFile->m_DispAttr.ResumeGroup(); + redrawWindow(1,false); + redrawWindow(2,false); + redrawWindow(3,false); + redrawWindow(4,false); + redrawWindow(5,false); +} +//////////////////////////////////////////////////////////////////////// +//##ModelId=4039BEDE0118 +bool CWaveShow::SetComtradeData(CComtradeFile& pComtradeData) +{ + m_pWaveFile = &pComtradeData; + m_pAnalogueView->SetComtradeData(pComtradeData); + m_pDigitalView->SetComtradeData(pComtradeData); + m_pAnaAxisView->SetComtradeData(pComtradeData); + m_pDgtNameView->SetComtradeData(pComtradeData); + m_pTimeAxisView->SetComtradeData(pComtradeData); +// m_pStatusView->SetComtradeData(pComtradeData); + m_pLinStatusView->SetComtradeData(pComtradeData); + RecacuAreas(); + update(); + return true; +} + +//##ModelId=4039BEE60389 +bool CWaveShow::SetShowAttribute(CSectionList& pAttrList) +{ + Q_UNUSED(pAttrList) + return true; +} +/* +bool CWaveShow::EditAnaGroup() +{ + if(!m_pWaveFile) + return false; + CAnaGroupSet* dlg = new CAnaGroupSet(m_pWaveFile,this); + if ( dlg->exec() == QDialog::Accepted ) { + redrawWindow(1,false); + redrawWindow(2,false); + } + return true; +} + +bool CWaveShow::EditDgtGroup() +{ + if(!m_pWaveFile) + return false; + CDgtGroupSet* dlg = new CDgtGroupSet(m_pWaveFile,this); + if ( dlg->exec() == QDialog::Accepted ) { + redrawWindow(3,false); + redrawWindow(4,false); + } + return true; +} + +bool CWaveShow::EditAnaTable() +{ + if(!m_pWaveFile) + return false; + CAnaTableSet* dlg = new CAnaTableSet(m_pWaveFile,this); + if ( dlg->exec() == QDialog::Accepted ) { + } + return true; +} + +bool CWaveShow::EditDgtTable() +{ + if(!m_pWaveFile) + return false; + CDgtTableSet* dlg = new CDgtTableSet(m_pWaveFile,this); + if ( dlg->exec() == QDialog::Accepted ) { + } + return true; +} + +bool CWaveShow::EditGridSet() +{ + if(!m_pWaveFile) + return false; + CGridSet* dlg = new CGridSet(m_pWaveFile,this); + if ( dlg->exec() == QDialog::Accepted ) { + } + return true; +} +*/ +bool CWaveShow::EditSelectLine() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch>=0 && Chm_DispAttr.m_nSelDigitalNo; + if( Ch<0 || Ch>=MAX_TAGS) + return false; + OnDgtLineSet(); + return true; +} + +bool CWaveShow::EditSelectColor() +{ + int Ch = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + if( Ch>=0 && Chm_DispAttr.m_nSelDigitalNo; + if( Ch<0 || Ch>=MAX_TAGS) + return false; + OnDgtColorSet(); + return true; +} + +//##ModelId=4039BEEE026F +bool CWaveShow::GetShowAttribute(CSectionList& pAttrList) +{ + Q_UNUSED(pAttrList) + return true; +} + +void CWaveShow::SetValueType( int nType ) +{ + if( m_pWaveFile->m_DispAttr.m_byValueType != nType ) + { + m_pWaveFile->m_DispAttr.m_byValueType = nType; + m_pWaveFile->SetUnitType(nType); + if(m_pAnaAxisView) m_pAnaAxisView->update(); + if(m_pAnalogueView) m_pAnalogueView->update(); + if(m_pDgtNameView) m_pDgtNameView->update(); + if(m_pDigitalView) m_pDigitalView->update(); + if(m_pTimeAxisView) m_pTimeAxisView->update(); + update(); + } +} + +int CWaveShow::GetCursorTicks() +{ + if(m_pWaveFile) + return m_pWaveFile->m_DispAttr.m_fStaticTick; + return 0; +} + +/* +void CWaveShow::AddLabel() +{ + CLabel label; + label.m_lTime = m_pWaveFile->m_DispAttr.m_fStaticTime; + CLabelSetDlg *dlg = new CLabelSetDlg( this ); + dlg->SetParam(m_pWaveFile,&label); + if ( dlg->exec() == QDialog::Accepted ) { + + m_pWaveFile->m_LabelList.append(label); + redrawWindow(2,false); + redrawWindow(4,false); + } + delete dlg; +} + +void CWaveShow::ShowLabels() +{ + CLabelBrowser *dlg = new CLabelBrowser( this ); + dlg->setLabelList(m_pWaveFile,m_pWaveFile->m_LabelList); + dlg->Rebuild(); + if ( dlg->exec() == QDialog::Accepted ) { + + m_pWaveFile->m_LabelList = dlg->m_labelList; + redrawWindow(2,false); + redrawWindow(4,false); + } + delete dlg; +} + +void CWaveShow::SetZoon() +{ + QDate db = m_pWaveFile->m_tTriggerTime.date(); + QTime tb = m_pWaveFile->m_tTriggerTime.time(); + int nMsec = m_pWaveFile->m_DispAttr.m_fBaseTime; + int nSecs= nMsec/1000; + int nDays = nSecs/(24*3600); + nSecs = nSecs%(24*3600); + int nMsec1 = nMsec%1000; + QDate d1 = db.addDays(nDays); + QTime t1 = tb.addSecs(nSecs); + + nMsec = m_pWaveFile->m_DispAttr.m_fStaticTick; + nSecs= nMsec/1000; + nDays = nSecs/(24*3600); + nSecs = nSecs%(24*3600); + int nMsec2 = nMsec%1000; + QDate d2 = db.addDays(nDays); + QTime t2 = tb.addSecs(nSecs); + + czoomsetdlg *dlg = new czoomsetdlg( this ); + dlg->setZoonTime(d1,t1,nMsec1,d2,t2,nMsec2); + if( dlg->exec() == QDialog::Accepted ) { + d1 = dlg->m_date1; + t1 = dlg->m_time1; + d2 = dlg->m_date2; + t2 = dlg->m_time2; + nMsec1 = dlg->m_msec1; + nMsec2 = dlg->m_msec2; + + nMsec1 += (d1.daysTo(db)*24*3600 + t1.secsTo(tb))*1000; + nMsec2 += (d2.daysTo(db)*24*3600 + t2.secsTo(tb))*1000; + + if(nMsec1<0) nMsec1 = 0; + if(nMsec2<0) nMsec2 = 0; + m_pWaveFile->m_DispAttr.m_fBaseTime = nMsec1; + m_pWaveFile->m_DispAttr.m_fBaseTick = m_pWaveFile->GetPointNoFromTime(m_pWaveFile->m_DispAttr.m_fBaseTime); + m_pWaveFile->m_DispAttr.m_fStaticTime = nMsec2; + m_pWaveFile->m_DispAttr.m_fStaticTick = m_pWaveFile->GetPointNoFromTime(m_pWaveFile->m_DispAttr.m_fStaticTime); + + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); + update(); + + m_pWaveFile->EmitLineCChanged(); + } + delete dlg; + +} +*/ +void CWaveShow::ReSize(const QSize &size) +{ + resize(size.expandedTo(minimumSizeHint())); + RecacuAreas(); +} + +void CWaveShow::SetZoomState( int nState ) +{ + m_nZoomState = (enum_ZoomState)nState; + switch( m_nZoomState ) + { + case SINGLEZOOM_IN: + setCursor( m_hZoomIn ); + m_pAnalogueView->setCursor( m_hZoomIn ); + break; + case SINGLEZOOM_OUT: + setCursor( m_hZoomOut ); + m_pAnalogueView->setCursor( m_hZoomOut ); + break; + case ZOOMRECT_X: + setCursor( m_hZoomRect ); + m_pAnalogueView->setCursor( m_hZoomRect ); + break; + default: + setCursor( m_hZoomOut ); + m_pAnalogueView->setCursor( m_hArrowCursor ); + break; + } +} + +void CWaveShow::ZoomInX() +{ + m_pWaveFile->m_DispAttr.m_fZoomX *=2.0; + if(m_pWaveFile->m_DispAttr.m_fZoomX > 16.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 16.0; + + m_pTimeAxisView->ResetHScrollSize(); + + int xPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fStaticTick ); + + QRect rect = m_pTimeAxisView->rect(); + int nHScroll = xPosition - rect.width()/2; + //int nHScroll = xPosition - rect.width(); + if(nHScroll<0) nHScroll =0; + + HTimeScroll(nHScroll); + + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); +} + +void CWaveShow::ZoomOutX() +{ + m_pWaveFile->m_DispAttr.m_fZoomX /= 2.0;// TIME_RATE; + if(m_pWaveFile->m_DispAttr.m_fZoomX*128 < 8.0) + m_pWaveFile->m_DispAttr.m_fZoomX = 8.0/128.0; + m_pTimeAxisView->ResetHScrollSize(); + + int xPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fStaticTick ); + + QRect rect = m_pTimeAxisView->rect(); + int nHScroll = xPosition - rect.width()/2; + //int nHScroll = xPosition - rect.width(); + if(nHScroll<0) nHScroll =0; + HTimeScroll(nHScroll); + + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); +} + +void CWaveShow::ZoomInAnalogueY() +{ + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 += AMP_RATE; + if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 > 20.0) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 20.0; + + m_pAnalogueView->ResetVScrollSize(); + + redrawWindow(1,false); + redrawWindow(2,false); +} + +void CWaveShow::ZoomOutAnalogueY() +{ + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 -= AMP_RATE; + if(m_pWaveFile->m_DispAttr.m_dWaveZoomY1 < 0.5) + m_pWaveFile->m_DispAttr.m_dWaveZoomY1 = 0.5; + + m_pAnalogueView->ResetVScrollSize(); + + redrawWindow(1,false); + redrawWindow(2,false); +} + +void CWaveShow::ZoomInDigitalY() +{ + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 += AMP_RATE; + if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 > 100.0) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 100.0; + + m_pDigitalView->ResetVScrollSize(); + + redrawWindow(3,false); + redrawWindow(4,false); +} + +void CWaveShow::ZoomOutDigitalY() +{ + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 -= AMP_RATE; + if(m_pWaveFile->m_DispAttr.m_dTagsZoomY1 < 0.5) + m_pWaveFile->m_DispAttr.m_dTagsZoomY1 = 0.5; + + m_pDigitalView->ResetVScrollSize(); + + redrawWindow(3,false); + redrawWindow(4,false); +} + +void CWaveShow::ZoomInName() +{ + QRect rc = rect(); + m_nLeftMargin += 10; + if(m_nLeftMargin > rc.width() - 20 ) + m_nLeftMargin = rc.width() - 20; + update(); + MoveAllViews(); +} + +void CWaveShow::ZoomOutName() +{ + m_nLeftMargin -= 10; + if(m_nLeftMargin < 0 ) + m_nLeftMargin = 0; + update(); + MoveAllViews(); +} + +void CWaveShow::copySelectToClip() +{ + + if(m_pCapturePt1.y() == m_pCapturePt2.y()||m_pCapturePt1.x()==m_pCapturePt2.x()) + return; + + QPoint pt1 = ( m_pCapturePt1.y() < m_pCapturePt2.y() )? m_pCapturePt1:m_pCapturePt2; + QPoint pt2 = ( m_pCapturePt1.y() > m_pCapturePt2.y() )? m_pCapturePt1:m_pCapturePt2; + + QRect rect2; + m_pAnalogueView->GetWaveMargin(rect2); + QPixmap pmAna( rect2.width(), rect2.height()); + pmAna.fill( Qt::white ); + QPainter paint; + paint.begin( &pmAna ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pAnalogueView->Print( &paint,rect2,QPoint(0,0),true); + paint.end(); + + QRect rect3; + m_pDigitalView->GetTagMargin(rect3); + QPixmap pmDgt( rect3.width(), rect3.height()); + pmDgt.fill( Qt::white ); + + paint.begin( &pmDgt ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pDigitalView->Print( &paint,rect3,QPoint(0,0),true); + paint.end(); + + QRect rect4,rect5; + if(pt2.y()m_nScrollLeft); + rect4.setRight(qMax(pt1.x(),pt2.x()) - m_nLeftMargin + m_pAnalogueView->m_nScrollLeft); + rect4.setTop(pt1.y() + m_pAnalogueView->m_nScrollTop); + rect4.setBottom(pt2.y() + m_pAnalogueView->m_nScrollTop); + rect5 = QRect(0,0,0,0); + } + else if(pt1.y()>m_nTagsViewTop) + { + rect5.setLeft(qMin(pt1.x(),pt2.x()) - m_nLeftMargin + m_pDigitalView->m_nScrollLeft); + rect5.setRight(qMax(pt1.x(),pt2.x()) - m_nLeftMargin + m_pDigitalView->m_nScrollLeft); + rect5.setTop(pt1.y() - m_nTagsViewTop + m_pDigitalView->m_nScrollTop); + rect5.setBottom(pt2.y() - m_nTagsViewTop + m_pDigitalView->m_nScrollTop); + rect4 = QRect(0,0,0,0); + } + else + { + rect4.setLeft(qMin(pt1.x(),pt2.x()) - m_nLeftMargin + m_pAnalogueView->m_nScrollLeft); + rect4.setRight(qMax(pt1.x(),pt2.x()) - m_nLeftMargin + m_pAnalogueView->m_nScrollLeft); + rect4.setTop(pt1.y() + m_pAnalogueView->m_nScrollTop); + rect4.setBottom(m_nTagsViewTop + m_pAnalogueView->m_nScrollTop); + + rect5.setLeft(rect4.left()); + rect5.setRight(rect4.right()); + rect5.setTop(0 + m_pDigitalView->m_nScrollTop); + rect5.setBottom(pt2.y() - m_nTagsViewTop + m_pDigitalView->m_nScrollTop); + } + + int nWidth = qMax(rect4.width(),rect5.width()); + int nHeight = rect4.height() + rect5.height(); + + QPixmap pmFull( nWidth, nHeight); + pmFull.fill( Qt::white ); + + if(rect4!=QRect(0,0,0,0)) + { + QPainter painter(&pmFull); + painter.drawPixmap(QPoint(0,0),pmAna,rect4); + } + + if(rect5!=QRect(0,0,0,0)) + { + QPainter painter(&pmFull); + painter.drawPixmap(QPoint(0,rect4.height()),pmDgt,rect5); + } + + QClipboard *clipboard = QApplication::clipboard(); + clipboard->clear(); + clipboard->setPixmap(pmFull); +} +/* +void CWaveShow::CopySelectPixmap() +{ + if(!m_pWaveFile)return; + + m_bPixmapCapturePt1 = true; + m_bPixmapCaptureStart = false; + +} + +void CWaveShow::CopyZonePixmap() +{ + if(!m_pWaveFile) + return; + + bool bShowName = true; + bool bShowWave = true; + bool bShowTag = true; + bool bShowTime = true; + + CCopyWaveSet dlg; + if( QDialog::Accepted !=dlg.exec() ) + return; + bShowName = dlg.m_bShowName; + bShowWave = dlg.m_bShowWave; + bShowTag = dlg.m_bShowTag; + bShowTime = dlg.m_bShowTime; + + QPainter paint; + + QRect rectTmp = QRect(0,0,0,0); + QRect rectTmp1 = QRect(0,0,0,0); + QRect rect1 = QRect(0,0,0,0); + QRect rect2 = QRect(0,0,0,0); + QRect rect3 = QRect(0,0,0,0); + QRect rect4 = QRect(0,0,0,0); + QRect rect5 = QRect(0,0,0,0); + + QPixmap pmAnaAxis; + QPixmap pmAna; + QPixmap pmDgt; + QPixmap pmTime; + QPixmap pmDgtName; + + m_pAnalogueView->GetWaveMargin(rectTmp); + m_pDigitalView->GetTagMargin(rectTmp1); + + int XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime); + int XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime); + int nBegin = qMax(0,qMin(XPosition1,XPosition2)); + int nEnd = qMin(qMax(rectTmp.width(),rectTmp1.width()),qMax(XPosition1,XPosition2)); + + rectTmp.setLeft( nBegin ); + rectTmp.setRight( nEnd ); + + QPoint ptOffset = QPoint(-rectTmp.left(),0); + + if( bShowName && bShowWave ) + { + m_pAnaAxisView->GetAnaAxisMargin(rect1); + pmAnaAxis = QPixmap(rect1.width(), rect1.height()); + pmAnaAxis.fill( Qt::white ); + + paint.begin( &pmAnaAxis ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pAnaAxisView->Print( &paint,rect1,QPoint(0,0),true); + paint.end(); + } + + if( bShowWave ) + { + + m_pAnalogueView->GetWaveMargin(rect2); + rect2.setLeft( nBegin ); + rect2.setRight( nEnd ); + pmAna = QPixmap( rect2.width(), rect2.height() ); + pmAna.fill( Qt::white ); + + paint.begin( &pmAna ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pAnalogueView->Print( &paint,rect2,ptOffset,true); + paint.end(); + } + + if( bShowName && bShowTag ) + { + m_pDgtNameView->GetTagNameMargin(rect3); + pmDgtName = QPixmap( rect3.width(), rect3.height() ); + pmDgtName.fill( Qt::white ); + + paint.begin( &pmDgtName ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pDgtNameView->Print( &paint,rect3,QPoint(0,0),true); + paint.end(); + } + + if( bShowTag ) + { + m_pDigitalView->GetTagMargin(rect4); + rect4.setLeft( nBegin ); + rect4.setRight( nEnd ); + pmDgt = QPixmap( rect4.width(), rect4.height()); + pmDgt.fill( Qt::white ); + + paint.begin( &pmDgt ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pDigitalView->Print( &paint,rect4,ptOffset,true); + paint.end(); + } + + if( bShowTime ) + { + m_pTimeAxisView->GetTimeMargin(rect5); + rect5.setLeft( nBegin ); + rect5.setRight( nEnd ); + pmTime = QPixmap( rect5.width(), rect5.height()); + pmTime.fill( Qt::white ); + + paint.begin( &pmTime ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pTimeAxisView->PrintB( &paint,rect5,ptOffset,true,false); + paint.end(); + } + + QPixmap pmFull( qMax(rect1.width() + rect2.width(),rect1.width() + rect4.width() ), (rect2.height()+rect4.height()+rect5.height())); + pmFull.fill( Qt::white ); + + QPainter painter(&pmFull); + if( bShowWave ) + { + if( bShowName ) + painter.drawPixmap(0,0,pmAnaAxis,0,0,rect1.width(),rect1.height() ); + painter.drawPixmap(rect1.width(),0,pmAna,0,0,rect2.width(),rect2.height()); + } + + if( bShowTag ) + { + if( bShowName ) + painter.drawPixmap(0,rect2.height(),pmDgtName,0,0,rect3.width(),rect3.height() ); + painter.drawPixmap(rect1.width(),rect2.height(),pmDgt,0,0,rect4.width(),rect4.height() ); + } + + if( bShowTime ) + painter.drawPixmap(rect1.width(),rect2.height()+rect4.height(),pmTime,0,0,rect5.width(),rect5.height() ); + + QClipboard *clipboard = QApplication::clipboard(); + clipboard->clear(); + clipboard->setPixmap(pmFull); +} +*/ +//{{ Add by qizhong +void CWaveShow::copyZonepixmapToFile() +{ + if(!m_pWaveFile)return; + + double m_fBaseTime = m_pWaveFile->m_nFrist_ms; +// double m_fSecondLineTime = m_pWaveFile->m_nFrist_ms + int((1000.0/m_pWaveFile->m_dLineFreq)*10); + + QPainter paint; + + QRect rect0; + m_pAnaAxisView->GetAnaAxisMargin(rect0); + QPixmap pmAnaAxis( rect0.width(), rect0.height()); + pmAnaAxis.fill( Qt::white ); + paint.begin( &pmAnaAxis ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pAnaAxisView->Print( &paint,rect0,QPoint(0,0),true); + paint.end(); + + QRect rect1; + m_pDgtNameView->GetTagNameMargin(rect1); + QPixmap pmDgtAxis( rect1.width(), rect1.height()); + pmDgtAxis.fill( Qt::white ); + paint.begin( &pmDgtAxis ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pDgtNameView->Print( &paint,rect1,QPoint(0,0),true); + paint.end(); + + QRect rect2; + m_pAnalogueView->GetWaveMargin(rect2); + QPixmap pmAna( rect2.width(), rect2.height()); + pmAna.fill( Qt::white ); +// QPainter paint; + paint.begin( &pmAna ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pAnalogueView->Print( &paint,rect2,QPoint(0,0),true); + paint.end(); + + QRect rect3; + m_pDigitalView->GetTagMargin(rect3); + QPixmap pmDgt( rect3.width(), rect3.height()); + pmDgt.fill( Qt::white ); + paint.begin( &pmDgt ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pDigitalView->Print( &paint,rect3,QPoint(0,0),true); + paint.end(); + + QRect rect4; + m_pTimeAxisView->GetTimeMargin(rect4); + QPixmap pmTime( rect4.width(), rect4.height()); + pmTime.fill( Qt::white ); + paint.begin( &pmTime ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pTimeAxisView->PrintB( &paint,rect4,QPoint(0,0),true,false); + paint.end(); + + int XPosition1 = m_pWaveFile->GetXPosition(m_fBaseTime); + //int XPosition2 = m_pWaveFile->GetXPosition(m_fSecondLineTime); + int nLastTick = m_pWaveFile->GetTotalPointAmount(); + int XPosition2 = m_pWaveFile->GetPointPosition(nLastTick-1)+50; + int nBegin = qMax(0,qMin(XPosition1,XPosition2)); + int nEnd = qMin(qMax(rect2.width(),rect3.width()),qMax(XPosition1,XPosition2)); + + QPixmap pmFull( nEnd - nBegin+rect0.width(), (rect2.height()+rect3.height()+rect4.height())); + pmFull.fill( Qt::white ); + + QPainter painter(&pmFull); + painter.drawPixmap(0,0,pmAnaAxis,0,0,rect0.width()-2,rect0.height() ); + painter.drawPixmap(0,rect0.height(),pmDgtAxis,0,0,rect1.width()-2,rect1.height() ); + + painter.drawPixmap(rect1.width(),0,pmAna,nBegin,0,nEnd - nBegin,rect2.height() ); + painter.drawPixmap(rect0.width(),rect2.height(),pmDgt,nBegin,0,nEnd - nBegin,rect3.height() ); + painter.drawPixmap(rect0.width(),rect2.height()+rect3.height(),pmTime,nBegin,0,nEnd - nBegin,rect4.height()); + + paint.begin( &pmFull ); + paint.setPen(QColor(0,0,0)); + paint.drawLine(rect0.width()-1,0, rect0.width()-1,rect2.height()+rect3.height()+5); + paint.end(); + + //QString szFileName = m_pWaveFile->m_sFileName +".bmp"; + QString strFileName = QFileDialog::getSaveFileName(this,tr("Save Wave Graph"),QApplication::applicationFilePath(),"Images (*.bmp)");//保存波形图片 + QDir dir = QDir::current(); + strFileName = dir.absoluteFilePath(strFileName); + + if(pmFull.save(strFileName,"BMP")) + { + QMessageBox objMsgBox(QMessageBox::Information,tr("Save File"),tr("Save Successfully!"));//保存文件 文件保存成功 + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + } + +/* + QClipboard *clipboard = QApplication::clipboard(); + clipboard->clear(); + clipboard->setPixmap(pmFull); +*/ +} +//}} +/* +void CWaveShow::CopyFullPixmap() +{ + if(!m_pWaveFile) + return; + + bool bShowName = true; + bool bShowWave = true; + bool bShowTag = true; + bool bShowTime = true; + + CCopyWaveSet dlg; + if( QDialog::Accepted !=dlg.exec() ) + return; + bShowName = dlg.m_bShowName; + bShowWave = dlg.m_bShowWave; + bShowTag = dlg.m_bShowTag; + bShowTime = dlg.m_bShowTime; + + + QPainter paint; + + QRect rect1 = QRect(0,0,0,0); + QRect rect2 = QRect(0,0,0,0); + QRect rect3 = QRect(0,0,0,0); + QRect rect4 = QRect(0,0,0,0); + QRect rect5 = QRect(0,0,0,0); + + QPixmap pmAnaAxis; + QPixmap pmAna; + QPixmap pmDgt; + QPixmap pmTime; + QPixmap pmDgtName; + + if( bShowName && bShowWave ) + { + m_pAnaAxisView->GetAnaAxisMargin(rect1); + pmAnaAxis = QPixmap(rect1.width(), rect1.height()); + pmAnaAxis.fill( Qt::white ); + + paint.begin( &pmAnaAxis ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pAnaAxisView->Print( &paint,rect1,QPoint(0,0),true); + paint.end(); + } + + if( bShowWave ) + { + m_pAnalogueView->GetWaveMargin(rect2); + pmAna = QPixmap( rect2.width(), rect2.height() ); + pmAna.fill( Qt::white ); + + paint.begin( &pmAna ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pAnalogueView->Print( &paint,rect2,QPoint(0,0),true); + paint.end(); + } + + if( bShowName && bShowTag ) + { + m_pDgtNameView->GetTagNameMargin(rect3); + pmDgtName = QPixmap( rect3.width(), rect3.height() ); + pmDgtName.fill( Qt::white ); + + paint.begin( &pmDgtName ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pDgtNameView->Print( &paint,rect3,QPoint(0,0),true); + paint.end(); + } + + if( bShowTag ) + { + m_pDigitalView->GetTagMargin(rect4); + pmDgt = QPixmap( rect4.width(), rect4.height()); + pmDgt.fill( Qt::white ); + + paint.begin( &pmDgt ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pDigitalView->Print( &paint,rect4,QPoint(0,0),true); + paint.end(); + } + + if( bShowTime ) + { + m_pTimeAxisView->GetTimeMargin(rect5); + pmTime = QPixmap( rect5.width(), rect5.height()); + pmTime.fill( Qt::white ); + + paint.begin( &pmTime ); + paint.setBrush(palette().color( QPalette::Foreground )); + m_pTimeAxisView->PrintB( &paint,rect5,QPoint(0,0),true,false); + paint.end(); + } + + + QPixmap pmFull( qMax(rect1.width() + rect2.width(),rect1.width() + rect4.width() ), (rect2.height()+rect4.height()+rect5.height())); + pmFull.fill( Qt::white ); + + QPainter painter(&pmFull); + if( bShowWave ) + { + if( bShowName ) + painter.drawPixmap(0,0,pmAnaAxis,0,0,rect1.width(),rect1.height() ); + painter.drawPixmap(rect1.width(),0,pmAna,0,0,rect2.width(),rect2.height() ); + } + + if( bShowTag ) + { + if( bShowName ) + painter.drawPixmap(0,rect2.height(),pmDgtName,0,0,rect3.width(),rect3.height() ); + painter.drawPixmap(rect1.width(),rect2.height(),pmDgt,0,0,rect4.width(),rect4.height() ); + } + + if( bShowTime ) + painter.drawPixmap(rect1.width(),rect2.height()+rect4.height(),pmTime,0,0,rect5.width(),rect5.height() ); + + QClipboard *clipboard = QApplication::clipboard(); + clipboard->clear(); + clipboard->setPixmap(pmFull); +} +*/ +QPrinter* CWaveShow::GetPrinter() +{ + if( !printer ) + { +// printer = new QPrinter(); + printer = new QPrinter(QPrinter::PrinterResolution);//QPrinter::HighResolution);//QPrinter::PrinterResolution); + } + return printer; +} +/* +void CWaveShow::TestPrintPriview( CPrintsetupDlg *dlg ) +{ + if(!dlg || !GetPrinter() ) + return; + + ////////////////////////////////////////////////////////// + //得到需要打印的通道 + if(!m_pWaveFile) + return; + + PRINTPARAM oldParam = m_PrintAttr; + m_PrintAttr = dlg->m_Attr; + + int i,j; + for(i=0;im_DispAttr.m_bWavePrint[i] = false; + for(i=0;im_DispAttr.m_bTagsPrint[i] = false; + + if(m_PrintAttr.bAnaPrint) + { + for(j=0;j<(int)m_pWaveFile->AnalogDataList.count();j++) + { + for(i=0;i<(int)m_PrintAttr.m_listAnaPrint.count();i++) + { + if(0==m_pWaveFile->AnalogDataList[j].m_sName.compare(m_PrintAttr.m_listAnaPrint[i])) + { + m_pWaveFile->m_DispAttr.m_bWavePrint[j] = true; + } + } + } + } + if(m_PrintAttr.bDgtPrint) + { + for(j=0;j<(int)m_pWaveFile->DigitDataList.count();j++) + { + for(i=0;i<(int)m_PrintAttr.m_listDgtPrint.count();i++) + { + if(0==m_pWaveFile->DigitDataList[j].m_sName.compare(m_PrintAttr.m_listDgtPrint[i])) + { + m_pWaveFile->m_DispAttr.m_bTagsPrint[j] = true; + } + } + } + } + + /////////////////////////////////////////////// + + if(m_PrintAttr.bOrient) + printer->setOrientation(QPrinter::Landscape); + else + printer->setOrientation(QPrinter::Portrait); + + if(dlg->m_bDoprintPrv) + { + PrintPreview( dlg ); + } + + m_PrintAttr = oldParam; + +} + +void CWaveShow::PrintSetup() +{ + if(!GetPrinter()) + return; + + CPrintsetupDlg *dlg = new CPrintsetupDlg(this); + dlg->SetAttr(m_pWaveFile,m_PrintAttr,printer); + dlg->RedrawPixmapLabel(); + if(dlg->exec()==QDialog::Accepted) + { + m_PrintAttr = dlg->m_Attr; +////////////////////////////////////////////////////////// +//得到需要打印的通道 + if(m_pWaveFile) + { + int i,j; + for(i=0;im_DispAttr.m_bWavePrint[i] = false; + for(i=0;im_DispAttr.m_bTagsPrint[i] = false; + + if(m_PrintAttr.bAnaPrint) + { + for(j=0;j<(int)m_pWaveFile->AnalogDataList.count();j++) + { + for(i=0;i<(int)m_PrintAttr.m_listAnaPrint.count();i++) + { + if(0==m_pWaveFile->AnalogDataList[j].m_sName.compare(m_PrintAttr.m_listAnaPrint[i])) + { + m_pWaveFile->m_DispAttr.m_bWavePrint[j] = true; + } + } + } + } + if(m_PrintAttr.bDgtPrint) + { + for(j=0;j<(int)m_pWaveFile->DigitDataList.count();j++) + { + for(i=0;i<(int)m_PrintAttr.m_listDgtPrint.count();i++) + { + if(0==m_pWaveFile->DigitDataList[j].m_sName.compare(m_PrintAttr.m_listDgtPrint[i])) + { + m_pWaveFile->m_DispAttr.m_bTagsPrint[j] = true; + } + } + } + } + } +/////////////////////////////////////////////// + + if(m_PrintAttr.bOrient) + printer->setOrientation(QPrinter::Landscape); + else + printer->setOrientation(QPrinter::Portrait); + + if(dlg->m_bDoprintPrv) + { + PrintPreview(); + } + + if(dlg->m_bDoprint) + { + Print(true); + } + } + +} +*/ +void ScaleRect(QRect &rect,double sx,double sy) +{ + rect.setLeft(rect.left()*sx); + rect.setRight(rect.right()*sx); + rect.setTop(rect.top()*sy); + rect.setBottom(rect.bottom()*sy); +} + +void CWaveShow::Print(bool bSetuped) +{ + Q_UNUSED(bSetuped) + if(!m_pWaveFile||!GetPrinter()) + return; + + printer->setPageSize(QPrinter::A4); + + //if(!bSetuped) + if (NULL == printer->printEngine()) + { + QPrintDialog printDialog(printer, this); + if (printDialog.exec() != QDialog::Accepted) { + return; + } + } + + if(m_PrintAttr.bOrient) + printer->setOrientation(QPrinter::Landscape); + else + printer->setOrientation(QPrinter::Portrait); + + + double dLeftMargin = m_PrintAttr.dLeftMargin;//边距 + double dTopMargin = m_PrintAttr.dTopMargin; + double dRightMargin = m_PrintAttr.dRightMargin; + double dBottomMargin = m_PrintAttr.dBottomMargin; + + QFont m_LittleFont; + m_LittleFont.setPixelSize(10); + + //qDebug()<<"PageSize = " <pageSize(); + + //printer size + int pagew = printer->pageRect().width(); + int pageh = printer->pageRect().height(); + + + QRect rcScreen(0,0,800,600); + if (this->parentWidget()) + { + rcScreen.setSize(this->parentWidget()->size()); + } + else + { + rcScreen.setSize(this->size()); + } + + double dXCordRate = 1.0, dYCordRate = 1.0; + dXCordRate = (double)pagew/(double)rcScreen.width(); + dYCordRate = (double)pageh/(double)rcScreen.height(); + + QMatrix m; + m.scale( dXCordRate,dYCordRate ); + + QString szTitle; + szTitle = m_pWaveFile->m_sDirName; + szTitle.append("/"); + szTitle+= m_pWaveFile->m_sFileName; + + + int drawPagew = pagew/dXCordRate; + int drawPageh = pageh/dYCordRate; + + + QRect rect1(0,0,0,0),rect2(0,0,0,0),rect3(0,0,0,0),rect4(0,0,0,0),rect5(0,0,0,0); + if(m_PrintAttr.bNamePrint) m_pAnaAxisView->GetAnaAxisMargin(rect1); + m_pAnalogueView->GetWaveMargin(rect2); + if(m_PrintAttr.bNamePrint) m_pDgtNameView->GetTagNameMargin(rect3); + m_pDigitalView->GetTagMargin(rect4); + m_pTimeAxisView->GetTimeMargin(rect5); + + + int nWidth1 = qMax(rect1.width(),rect3.width()); + int nWidth2 = qMax(rect2.width(),rect4.width()); + int nHeight1 = qMax(rect1.height(),rect2.height()); + int nHeight2 = qMax(rect3.height(),rect4.height()); + int nTimeHeight =rect5.height(); +// int nTimeWidth =rect5.width(); +// int nTitleWidth = drawPagew; + int nTitleHeight = 20; + + int oneWaveheight = drawPageh - 2*nTimeHeight - dTopMargin - dBottomMargin + 10; //留上下边画坐标 + int oneWaveWidth = drawPagew - nWidth1 - dLeftMargin - dRightMargin; + if(oneWaveWidth<=0) oneWaveWidth = 10; + if(oneWaveheight<=0) oneWaveheight = 10; + + int nColumns = 0,nRows = 0; + int XPosition1 = 0,XPosition2 = 0,nBegin = 0,nEnd = 0; + if(m_PrintAttr.bZonePrint){ + //区域大小 + XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime) -5; + XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime) + 5; + nBegin = qMax(0,qMin(XPosition1,XPosition2)); + nEnd = qMin(qMax(rect2.width(),rect3.width()),qMax(XPosition1,XPosition2)); + //int nPages + nColumns = fabs(double(nBegin - nEnd))/oneWaveWidth; + nRows = (nHeight1 + nHeight2)/oneWaveheight; + } + else + { + nColumns = nWidth2/oneWaveWidth; + nRows = (nHeight1 + nHeight2)/oneWaveheight; + } + +// QPaintEngine * pe = printer->paintEngine(); + +// printer->setMinMax(0,(nColumns+1)*(nRows+1)); + + //设置打印起始页 + //printer->setFromTo(1,nRows*nColumns); + + QPainter paint; + if ( !paint.begin( printer ) ) + return; + paint.setWorldMatrix( m ); + + int nIndex = 0; + int nAnaTop = 0; + int nDgtTop = 0; + for(int i = 0;i<=nRows;i++) + { + + int nWaveHeight = 0; + int nDgtBegin = 0; + bool bAnaOver = true; + int nAnaHeight = 0; + int nDgtHeight = 0; + if(m_PrintAttr.bAnaPrint&&nAnaTop<=nHeight1) + { + bAnaOver = false; + nAnaHeight = oneWaveheight; + + if(nAnaTop+nAnaHeight>nHeight1) + { + nAnaHeight = nHeight1 - nAnaTop; + nDgtBegin = nAnaHeight; + bAnaOver = true; + } + + nWaveHeight += nAnaHeight; + } + + if(m_PrintAttr.bDgtPrint&&nDgtTop<= nHeight2&&bAnaOver) + { + nDgtHeight = oneWaveheight - nDgtBegin; + if(nDgtTop+nDgtHeight>nHeight2) + { + nDgtHeight = nHeight2- nDgtTop; + } + nWaveHeight += nDgtHeight; + } + + for(int j= 0;j<= nColumns;j++) + { + //wave + if(m_PrintAttr.bAnaPrint&&nAnaTop<=nHeight1&&nAnaHeight>0) + { + if(nWidth1>0&&m_PrintAttr.bNamePrint) + { + //QRect rcPrintt(dLeftMargin,nTimeHeight+dTopMargin,nWidth1,nAnaHeight); + QRect rcDrawt(0,nAnaTop,nWidth1,nAnaHeight); + QPoint ptOffset(dLeftMargin,nTimeHeight+dTopMargin - nAnaTop ); + m_pAnaAxisView->Print( &paint, rcDrawt ,ptOffset, m_PrintAttr.bColor); + } + + if(m_PrintAttr.bZonePrint) + { + //QRect rcPrint(nWidth1+dLeftMargin,nTimeHeight+dTopMargin,oneWaveWidth,nAnaHeight); + QRect rcDraw(nBegin + j*oneWaveWidth ,nAnaTop,qMin(oneWaveWidth,nEnd -nBegin - j*oneWaveWidth),nAnaHeight); + QPoint ptOffset(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nTimeHeight+dTopMargin - nAnaTop ); + m_pAnalogueView->Print( &paint, rcDraw , ptOffset,m_PrintAttr.bColor); + + } + else + { + //QRect rcPrint(nWidth1+dLeftMargin,nTimeHeight+dTopMargin,oneWaveWidth,nAnaHeight); + QRect rcDraw(j*oneWaveWidth,nAnaTop,oneWaveWidth,nAnaHeight); + QPoint ptOffset(nWidth1+dLeftMargin - j*oneWaveWidth,nTimeHeight+dTopMargin - nAnaTop ); + m_pAnalogueView->Print( &paint, rcDraw , ptOffset,m_PrintAttr.bColor); + } + + } + + if(m_PrintAttr.bDgtPrint&&nDgtTop<= nHeight2&&nDgtHeight>0&&bAnaOver) + { + if(nWidth1>0&&m_PrintAttr.bNamePrint) + { + //QRect rcPrintt(dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin,nWidth1,nDgtHeight); + QRect rcDrawt(0,nDgtTop,nWidth1,nDgtHeight); + QPoint ptOffset(dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); + m_pDgtNameView->Print( &paint, rcDrawt , ptOffset ,m_PrintAttr.bColor); + } + + if(m_PrintAttr.bZonePrint)//区域打印 + { + //QRect rcPrint(nWidth1+dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin,oneWaveWidth,nDgtHeight); + QRect rcDraw(nBegin + j*oneWaveWidth,nDgtTop,qMin(oneWaveWidth,nEnd -nBegin - j*oneWaveWidth),nDgtHeight); + QPoint ptOffset(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); + m_pDigitalView->Print( &paint, rcDraw ,ptOffset , m_PrintAttr.bColor); + + } + else + { + //QRect rcPrint(nWidth1+dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin,oneWaveWidth,nDgtHeight); + QRect rcDraw(j*oneWaveWidth,nDgtTop,oneWaveWidth,nDgtHeight); + QPoint ptOffset(nWidth1+dLeftMargin - j*oneWaveWidth,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); + m_pDigitalView->Print( &paint, rcDraw ,ptOffset , m_PrintAttr.bColor); + } + } + + { + QRect rcPrint(0,0,drawPagew,drawPageh); + QRect rcDraw(0,0,drawPagew,drawPageh); + paint.setWindow(rcDraw); + paint.setViewport(rcPrint); + paint.setBrush(Qt::white); + paint.setPen(Qt::NoPen); + paint.drawRect(QRect(0,0,drawPagew,dTopMargin+nTimeHeight)); + paint.drawRect(QRect(0,0,dLeftMargin,drawPageh)); + paint.drawRect(QRect(0,drawPageh - dBottomMargin - nTimeHeight,drawPagew,dBottomMargin+nTimeHeight)); + paint.drawRect(QRect(drawPagew - dRightMargin,0,dRightMargin,drawPageh)); + paint.setPen(QPen(Qt::black)); + } + + if(m_PrintAttr.bTimePrint) + { + if(m_PrintAttr.bZonePrint) + { + //QRect rcPrint(nWidth1+dLeftMargin,dTopMargin,oneWaveWidth,nTimeHeight); + QRect rcDraw(nBegin + j*oneWaveWidth,0,qMin(oneWaveWidth,nEnd - nBegin - j*oneWaveWidth),nTimeHeight); + QPoint ptOffset1(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,dTopMargin ); + m_pTimeAxisView->PrintB( &paint, rcDraw ,ptOffset1, m_PrintAttr.bColor,true ); + + //QRect rcPrint1(nWidth1+dLeftMargin,nWaveHeight+nTimeHeight + dTopMargin,oneWaveWidth,nTimeHeight); + QRect rcDraw1(nBegin + j*oneWaveWidth,0,qMin(oneWaveWidth,nEnd - nBegin - j*oneWaveWidth),nTimeHeight); + QPoint ptOffset2(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nWaveHeight+nTimeHeight + dTopMargin ); + m_pTimeAxisView->PrintB( &paint, rcDraw1 ,ptOffset2, m_PrintAttr.bColor , false ); + } + else + { + //QRect rcPrint(nWidth1+dLeftMargin,dTopMargin,oneWaveWidth,nTimeHeight); + QRect rcDraw(j*oneWaveWidth,0,oneWaveWidth,nTimeHeight); + QPoint ptOffset1(nWidth1+dLeftMargin - j*oneWaveWidth,dTopMargin ); + m_pTimeAxisView->PrintB( &paint, rcDraw ,ptOffset1, m_PrintAttr.bColor,true ); + + //QRect rcPrint1(nWidth1+dLeftMargin,nWaveHeight+nTimeHeight + dTopMargin,oneWaveWidth,nTimeHeight); + QRect rcDraw1(j*oneWaveWidth,0,oneWaveWidth,nTimeHeight); + QPoint ptOffset2(nWidth1+dLeftMargin - j*oneWaveWidth,nWaveHeight+nTimeHeight + dTopMargin ); + m_pTimeAxisView->PrintB( &paint, rcDraw1 ,ptOffset2, m_PrintAttr.bColor , false ); + } + + } + + if(m_PrintAttr.bTitlePrint) + { + QString szPage; + szPage.sprintf("Page %d",nIndex++); + QRect rcPrint(0,0,drawPagew,drawPageh); + QRect rcDraw(0,0,drawPagew,drawPageh); + paint.setPen(QPen(Qt::black)); + paint.setFont(m_LittleFont); + paint.drawLine(QPoint(dLeftMargin,dTopMargin + nTimeHeight),QPoint(dLeftMargin,dTopMargin+nWaveHeight+nTimeHeight)); + paint.drawLine(QPoint(nWidth1+dLeftMargin,dTopMargin + nTimeHeight),QPoint(nWidth1+dLeftMargin,dTopMargin+nWaveHeight+nTimeHeight)); + paint.drawText(QRect(20,drawPageh - nTitleHeight,drawPagew,nTitleHeight),Qt::AlignLeft | Qt::TextSingleLine,szTitle); + paint.drawText(QRect(20,drawPageh - nTitleHeight,drawPagew,nTitleHeight),Qt::AlignHCenter | Qt::TextSingleLine,szPage); + } + + printer->newPage(); + } + nAnaTop = nAnaTop + nAnaHeight; + nDgtTop = nDgtTop + nDgtHeight; + } + paint.end(); +} + +void CWaveShow::PrintPreview( QWidget* pParent ) +{ + if(!m_pWaveFile||!GetPrinter())return; + + double dLeftMargin = m_PrintAttr.dLeftMargin;//边距 + double dTopMargin = m_PrintAttr.dTopMargin; + double dRightMargin = m_PrintAttr.dRightMargin; + double dBottomMargin = m_PrintAttr.dBottomMargin; + + QFont m_LittleFont; + m_LittleFont.setPixelSize(10); + + int pagewOrgin = 6814; + int pagehOrgin = 4760; + if(m_PrintAttr.bOrient) + { + pagehOrgin = printer->pageRect().width(); + pagewOrgin = printer->pageRect().height(); + } + else + { + pagewOrgin = printer->pageRect().width(); + pagehOrgin = printer->pageRect().height(); + } + + + QRect rcScreen(0,0,800,600); + if (this->parentWidget()) + { + rcScreen.setSize(this->parentWidget()->size()); + } + else + { + rcScreen.setSize(this->size()); + } + double dXCordRate = 1.0, dYCordRate = 1.0; + dXCordRate = (double)pagewOrgin/(double)rcScreen.width(); + dYCordRate = (double)pagehOrgin/(double)rcScreen.height(); + + QMatrix m; + m.scale( dXCordRate,dYCordRate ); + + QString szTitle; + szTitle = m_pWaveFile->m_sDirName; + szTitle.append("/"); + szTitle+= m_pWaveFile->m_sFileName; + + + int drawPagew = rcScreen.width(); + int drawPageh = rcScreen.height(); + + + QRect rect1(0,0,0,0),rect2(0,0,0,0),rect3(0,0,0,0),rect4(0,0,0,0),rect5(0,0,0,0); + if(m_PrintAttr.bNamePrint) m_pAnaAxisView->GetAnaAxisMargin(rect1); + m_pAnalogueView->GetWaveMargin(rect2); + if(m_PrintAttr.bNamePrint) m_pDgtNameView->GetTagNameMargin(rect3); + m_pDigitalView->GetTagMargin(rect4); + m_pTimeAxisView->GetTimeMargin(rect5); + + + int nWidth1 = qMax(rect1.width(),rect3.width()); + int nWidth2 = qMax(rect2.width(),rect4.width()); + int nHeight1 = qMax(rect1.height(),rect2.height()); + int nHeight2 = qMax(rect3.height(),rect4.height()); + int nTimeHeight =rect5.height(); +// int nTimeWidth =rect5.width(); +// int nTitleWidth = drawPagew; + int nTitleHeight = 20; + + int oneWaveheight = drawPageh - 2*nTimeHeight - dTopMargin - dBottomMargin + 10; //留上下边画坐标 + int oneWaveWidth = drawPagew - nWidth1 - dLeftMargin - dRightMargin; + if(oneWaveWidth<=0) oneWaveWidth = 10; + if(oneWaveheight<=0) oneWaveheight = 10; + + int nColumns = 0,nRows = 0; + int XPosition1 = 0,XPosition2 = 0,nBegin = 0,nEnd = 0; + if(m_PrintAttr.bZonePrint){ + //区域大小 + XPosition1 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fBaseTime) -5; + XPosition2 = m_pWaveFile->GetXPosition(m_pWaveFile->m_DispAttr.m_fStaticTime) + 5; + nBegin = qMax(0,qMin(XPosition1,XPosition2)); + nEnd = qMin(qMax(rect2.width(),rect3.width()),qMax(XPosition1,XPosition2)); + //int nPages + nColumns = fabs(double(nBegin - nEnd))/oneWaveWidth; + nRows = (nHeight1 + nHeight2)/oneWaveheight; + } + else + { + nColumns = nWidth2/oneWaveWidth; + nRows = (nHeight1 + nHeight2)/oneWaveheight; + } + +// printer->setMinMax(0,(nColumns+1)*(nRows+1)); +// if(!printer->setup( this )) return; + QPainter paint; + + CPixmapList ImageList; + int nIndex = 0; + int nAnaTop = 0; + int nDgtTop = 0; + for(int i = 0;i<=nRows;i++) + { + + int nWaveHeight = 0; + int nDgtBegin = 0; + bool bAnaOver = true; + int nAnaHeight = 0; + int nDgtHeight = 0; + if(m_PrintAttr.bAnaPrint&&nAnaTop<=nHeight1) + { + bAnaOver = false; + nAnaHeight = oneWaveheight; + + if(nAnaTop+nAnaHeight>nHeight1) + { + nAnaHeight = nHeight1 - nAnaTop; + nDgtBegin = nAnaHeight; + bAnaOver = true; + } + + nWaveHeight += nAnaHeight; + } + + if(m_PrintAttr.bDgtPrint&&nDgtTop<= nHeight2&&bAnaOver) + { + nDgtHeight = oneWaveheight - nDgtBegin; + if(nDgtTop+nDgtHeight>nHeight2) + { + nDgtHeight = nHeight2- nDgtTop; + } + nWaveHeight += nDgtHeight; + } + + for(int j= 0;j<= nColumns;j++) + { + QPixmap map(pagewOrgin, pagehOrgin); + map.fill( Qt::white ); + paint.begin( &map ); + paint.setWorldMatrix( m ); + paint.setBrush(palette().color( QPalette::Foreground )); + //wave + + if(m_PrintAttr.bAnaPrint&&nAnaTop<=nHeight1&&nAnaHeight>0) + { + if(nWidth1>0&&m_PrintAttr.bNamePrint) + { + QRect rcDrawt(0,nAnaTop,nWidth1,nAnaHeight); + QPoint ptOffset(dLeftMargin,nTimeHeight+dTopMargin - nAnaTop ); + m_pAnaAxisView->Print( &paint, rcDrawt ,ptOffset, m_PrintAttr.bColor); + } + + if(m_PrintAttr.bZonePrint) + { + QRect rcDraw(nBegin + j*oneWaveWidth ,nAnaTop,qMin(oneWaveWidth,nEnd -nBegin - j*oneWaveWidth),nAnaHeight); + QPoint ptOffset(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nTimeHeight+dTopMargin - nAnaTop ); + m_pAnalogueView->Print( &paint, rcDraw , ptOffset,m_PrintAttr.bColor); + + } + else + { + QRect rcDraw(j*oneWaveWidth,nAnaTop,oneWaveWidth,nAnaHeight); + QPoint ptOffset(nWidth1+dLeftMargin - j*oneWaveWidth,nTimeHeight+dTopMargin - nAnaTop ); + m_pAnalogueView->Print( &paint, rcDraw , ptOffset,m_PrintAttr.bColor); + } + } + + if(m_PrintAttr.bDgtPrint&&nDgtTop<= nHeight2&&nDgtHeight>0&&bAnaOver) + { + if(nWidth1>0&&m_PrintAttr.bNamePrint) + { + QRect rcDrawt(0,nDgtTop,nWidth1,nDgtHeight); + QPoint ptOffset(dLeftMargin,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); + m_pDgtNameView->Print( &paint, rcDrawt , ptOffset ,m_PrintAttr.bColor); + } + + if(m_PrintAttr.bZonePrint)//区域打印 + { + QRect rcDraw(nBegin + j*oneWaveWidth,nDgtTop,qMin(oneWaveWidth,nEnd -nBegin - j*oneWaveWidth),nDgtHeight); + QPoint ptOffset(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); + m_pDigitalView->Print( &paint, rcDraw ,ptOffset , m_PrintAttr.bColor); + + } + else + { + QRect rcDraw(j*oneWaveWidth,nDgtTop,oneWaveWidth,nDgtHeight); + QPoint ptOffset(nWidth1+dLeftMargin - j*oneWaveWidth,nTimeHeight+nDgtBegin+dTopMargin - nDgtTop ); + m_pDigitalView->Print( &paint, rcDraw ,ptOffset , m_PrintAttr.bColor); + } + } + + { + QRect rcPrint(0,0,drawPagew,drawPageh); + QRect rcDraw(0,0,drawPagew,drawPageh); + paint.setWindow(rcDraw); + paint.setViewport(rcPrint); + paint.setBrush(Qt::white); + paint.setPen(Qt::NoPen); + paint.setFont(m_LittleFont); + paint.drawRect(QRect(0,0,drawPagew,dTopMargin+nTimeHeight)); + paint.drawRect(QRect(0,0,dLeftMargin,drawPageh)); + paint.drawRect(QRect(0,drawPageh - dBottomMargin - nTimeHeight,drawPagew,dBottomMargin+nTimeHeight)); + paint.drawRect(QRect(drawPagew - dRightMargin,0,dRightMargin,drawPageh)); + paint.setPen(QPen(Qt::black)); + } + + if(m_PrintAttr.bTimePrint) + { + if(m_PrintAttr.bZonePrint) + { + QRect rcDraw(nBegin + j*oneWaveWidth,0,qMin(oneWaveWidth,nEnd - nBegin - j*oneWaveWidth),nTimeHeight); + QPoint ptOffset1(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,dTopMargin ); + m_pTimeAxisView->PrintB( &paint, rcDraw ,ptOffset1, m_PrintAttr.bColor,true ); + + QRect rcDraw1(nBegin + j*oneWaveWidth,0,qMin(oneWaveWidth,nEnd - nBegin - j*oneWaveWidth),nTimeHeight); + QPoint ptOffset2(nWidth1+dLeftMargin - nBegin - j*oneWaveWidth,nWaveHeight+nTimeHeight + dTopMargin ); + m_pTimeAxisView->PrintB( &paint, rcDraw1 ,ptOffset2, m_PrintAttr.bColor , false ); + } + else + { + QRect rcDraw(j*oneWaveWidth,0,oneWaveWidth,nTimeHeight); + QPoint ptOffset1(nWidth1+dLeftMargin - j*oneWaveWidth,dTopMargin ); + m_pTimeAxisView->PrintB( &paint, rcDraw ,ptOffset1, m_PrintAttr.bColor,true ); + + QRect rcDraw1(j*oneWaveWidth,0,oneWaveWidth,nTimeHeight); + QPoint ptOffset2(nWidth1+dLeftMargin - j*oneWaveWidth,nWaveHeight+nTimeHeight + dTopMargin ); + m_pTimeAxisView->PrintB( &paint, rcDraw1 ,ptOffset2, m_PrintAttr.bColor , false ); + } + + } + + if(m_PrintAttr.bTitlePrint) + { + QString szPage; + szPage.sprintf("Page %d",nIndex++); + QRect rcPrint(0,0,drawPagew,drawPageh); + QRect rcDraw(0,0,drawPagew,drawPageh); + paint.setPen(QPen(Qt::black)); + paint.drawLine(QPoint(nWidth1+dLeftMargin,dTopMargin + nTimeHeight),QPoint(nWidth1+dLeftMargin,dTopMargin+nWaveHeight+nTimeHeight)); + paint.drawLine(QPoint(dLeftMargin,dTopMargin + nTimeHeight),QPoint(dLeftMargin,dTopMargin+nWaveHeight+nTimeHeight)); + paint.drawText(QRect(20,drawPageh - nTitleHeight,drawPagew,nTitleHeight),Qt::AlignLeft | Qt::TextSingleLine,szTitle); + paint.drawText(QRect(20,drawPageh - nTitleHeight,drawPagew,nTitleHeight),Qt::AlignHCenter | Qt::TextSingleLine,szPage); + } + + paint.end(); + ImageList.append(map); + } + nAnaTop = nAnaTop + nAnaHeight; + nDgtTop = nDgtTop + nDgtHeight; + } + + QWidget* pWin = pParent; + if( !pWin ) + pWin = this; + + CPrintPreview view( pWin ); + view.setPages( ImageList ); + if ( view.exec() ) { + Print(true); + } +} + +//******************************************************************** +// 画X分隔条 +//******************************************************************** +void CWaveShow::DrawXSplitterBar( QPainter *paint, int nXPos, int nYPos) +{ + QRect rcClient; + rcClient = geometry(); + + qDrawShadePanel(paint,QRect(nXPos,rcClient.top(),SPLITTERWIDTH,nYPos - rcClient.top()),palette()); +} + + +//******************************************************************** +// 画Y分隔条 +//******************************************************************** +void CWaveShow::DrawYSplitterBar( QPainter *paint , int nYPos) +{ + QRect rcClient; + rcClient = geometry(); + + qDrawShadePanel(paint,QRect(rcClient.left(),nYPos,rcClient.width(),SPLITTERWIDTH),palette()); +} + +//******************************************************************** +// 画Y底部的分隔条 +//******************************************************************** +void CWaveShow::DrawYBottomSplitterBar( QPainter *paint , int nYPos) +{ + QRect rcClient; + rcClient = geometry(); + + //qDrawShadePanel(paint,QRect(rcClient.left(),nYPos,rcClient.width(),1),palette()); + paint->drawLine(QPoint(rcClient.left(),nYPos),QPoint(rcClient.right(),nYPos+20)); +} + +//******************************************************************** +//滚动 +//******************************************************************** +void CWaveShow::VAnaScroll(int nValue) +{ + if(m_pAnalogueView) + m_pAnalogueView->VScroll(nValue); + if(m_pAnaAxisView) + m_pAnaAxisView->VScroll(nValue); +} + +void CWaveShow::VDgtScroll(int nValue) +{ + if(m_pDigitalView) + m_pDigitalView->VScroll(nValue); + if(m_pDgtNameView) + m_pDgtNameView->VScroll(nValue); +} + +void CWaveShow::HTimeScroll(int nValue) +{ + if(m_pTimeAxisView) + m_pTimeAxisView->HScroll(nValue); + if(m_pAnalogueView) + m_pAnalogueView->HScroll(nValue); + if(m_pDigitalView) + m_pDigitalView->HScroll(nValue); +} + +void CWaveShow::HitTestWave( int nScrollTop,int nY ) +{ + // int nHeight = ClientRect.height(); + int nWidth = m_pWaveFile->m_DispAttr.m_nLeftMargin; + double dWaveZoomY1 = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + int nTopPos = 0; + int g; + int nCurAnalogueNo = m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; + int nNameHeight = m_pWaveFile->m_DispAttr.m_nNameHeight; + QStringList szName; + for( g=0; gGetMaxWaveGroupNum()+1 && gIsWaveGroupEmpty( g ) /*|| m_pWaveFile->m_DispAttr.m_bWaveMarked[g]*/) + continue; + int nGroupHeight = m_pWaveFile->m_DispAttr.m_dWaveHeight[g]*dWaveZoomY1; + if(nGroupHeight<5) nGroupHeight=5; + + szName.clear(); + + int nChCount = 0; + int ChAna = 0; + for(ChAna = 0;ChAnam_nAnagueNum && ChAnam_DispAttr.m_nWaveGroup[ChAna]!=g) continue; + szName.append(m_pWaveFile->AnalogDataList[ChAna].m_sName); + nChCount++; + } + + for(int i = 0;im_nAnagueNum && jm_DispAttr.m_nWaveGroup[j]!=g) continue; + if(m_pWaveFile->AnalogDataList[j].m_sName == szName[i]) + { + if(grpArea1.contains(QPoint(5,nScrollTop+nY),true)) + { + nCurAnalogueNo = j; + break; + } + } + + } + } +// //记录每个波形的区域 +// QRect grpArea = QRect(0,nTopPos,nWidth,nGroupHeight); +// +// int Ch=0; +// for(Ch=0; Chm_nAnagueNum && Chm_DispAttr.m_nWaveGroup[Ch]!=g) continue; +// +// if( grpArea.contains( QPoint(5,nScrollTop+nY),true)) +// { +// nCurAnalogueNo = Ch; +// break; +// } +// } + nTopPos += nGroupHeight; + } + + m_pWaveFile->m_DispAttr.m_nSelAnalogueNo = nCurAnalogueNo; + if(nCurAnalogueNo>=0) + { + m_pWaveFile->m_DispAttr.m_nSelDigitalNo = -1; + redrawWindow( 1,false); + redrawWindow( 3,false); + } +} + +void CWaveShow::HitTestTag( int nScrollTop,int nY ) +{ + int nWidth = 10; + int nCurDigitalNo = -1; + int nTagsHeight = int(double(m_pWaveFile->m_DispAttr.m_dTagsHeight) * m_pWaveFile->m_DispAttr.m_dTagsZoomY1); + if(nTagsHeight<5) nTagsHeight=5; + + int nTopPos = 0; + for(int ch=0;ch<=m_pWaveFile->m_nDigitalNum && chm_DispAttr.m_nTagsGroup[ch] < 0) continue; + + QRect dgtArea = QRect(0,nTopPos,nWidth,nTagsHeight); + if(dgtArea.contains(QPoint(5,nScrollTop+nY),true)) + { + nCurDigitalNo = ch; + break; + } + nTopPos += nTagsHeight; + } + + m_pWaveFile->m_DispAttr.m_nSelDigitalNo = nCurDigitalNo; + if(nCurDigitalNo>=0) + { + m_pWaveFile->m_DispAttr.m_nSelAnalogueNo = -1; + redrawWindow( 1,false); + redrawWindow( 3,false); + } +} + +void CWaveShow::redrawWindow(int i , bool bErase) +{ + Q_UNUSED(bErase) + switch(i) + { + case 0: + update();break; + case 1: + if(m_pAnaAxisView) m_pAnaAxisView->update();break; + case 2: + if(m_pAnalogueView) m_pAnalogueView->update();break; + case 3: + if(m_pDgtNameView) m_pDgtNameView->update();break; + case 4: + if(m_pDigitalView) m_pDigitalView->update();break; + case 5: + if(m_pTimeAxisView) m_pTimeAxisView->update();break; + case 7: + if(m_pLinStatusView) m_pLinStatusView->update();break; + + } + if( (CWaveEnv::GetInst()->m_fZoomXX != m_pWaveFile->m_DispAttr.m_fZoomX)|| + (CWaveEnv::GetInst()->m_dWaveZoomYY != m_pWaveFile->m_DispAttr.m_dWaveZoomY1) || + (CWaveEnv::GetInst()->m_dTagsZoomYY != m_pWaveFile->m_DispAttr.m_dTagsZoomY1) || + (CWaveEnv::GetInst()->m_nLeftMarginName != m_nLeftMargin) ) + { + CWaveEnv::GetInst()->m_fZoomXX = m_pWaveFile->m_DispAttr.m_fZoomX; + CWaveEnv::GetInst()->m_dWaveZoomYY = m_pWaveFile->m_DispAttr.m_dWaveZoomY1; + CWaveEnv::GetInst()->m_dTagsZoomYY = m_pWaveFile->m_DispAttr.m_dTagsZoomY1; + CWaveEnv::GetInst()->m_nLeftMarginName = m_nLeftMargin; + CWaveEnv::GetInst()->SaveZoomSet(); + } + +} + +int CWaveShow::GetCurAnaChannel() +{ + return m_pWaveFile->m_DispAttr.m_nSelAnalogueNo; +} + +int CWaveShow::GetCurDgtChannel() +{ + return m_pWaveFile->m_DispAttr.m_nSelDigitalNo; +} + +void CWaveShow::ZoomFull() +{ + QRect rect = m_pAnalogueView->rect(); + int nSample = 0; + for(int i = 0; i < m_pWaveFile->m_nNRates; i++) + nSample += m_pWaveFile->m_lSampleAmount[i]; + double dTemp1 = 0; + double dTemp2 = 0; + dTemp1 = rect.width()*1.0-80.0; + dTemp2 = nSample*m_pWaveFile->m_DispAttr.m_dGridWidth; + int dTemp = int(dTemp2/dTemp1); + if(dTemp == 0) + { + int dTemp3 = 1.0; + dTemp3 = int((dTemp1/dTemp2+.5)*0.8); + m_pWaveFile->m_DispAttr.m_fZoomX = double(dTemp3); + } + else + { + dTemp = int((1.2*dTemp2)/dTemp1+.5); + m_pWaveFile->m_DispAttr.m_fZoomX = double(1.0/dTemp); + } + m_pTimeAxisView->ResetHScrollSize(); + + int xPosition = m_pWaveFile->GetPointPosition( m_pWaveFile->m_DispAttr.m_fStaticTick ); + int nHScroll = xPosition - rect.width()/2; + //int nHScroll = xPosition - rect.width(); + if(nHScroll<0) nHScroll =0; + + HTimeScroll(nHScroll); + + redrawWindow(2,false); + redrawWindow(4,false); + redrawWindow(5,false); +} + +void CWaveShow::ResumeZoom() +{ + m_pTimeAxisView->m_nScrollLeft = 0; + m_pAnalogueView->m_nScrollTop = 0; + m_pDigitalView->m_nScrollTop = 0; + m_pTimeAxisView->ResetHScrollSize(); + m_pAnalogueView->ResetVScrollSize(); + m_pDigitalView->ResetVScrollSize(); + m_pAnalogueView->vert_bar->setValue(0); + m_pDigitalView->vert_bar->setValue(0); + m_pTimeAxisView->horiz_bar->setValue(0); + + redrawWindow(1,false); + redrawWindow(2,false); + redrawWindow(3,false); + redrawWindow(4,false); + redrawWindow(5,false); +} + +void CWaveShow::showStatus() +{ +// if(m_statusBar) +// { +// startLabel->setText(tr("B线:%1").arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fBaseTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); +// endLabel->setText(tr("C线:%1").arg(m_pWaveShow->m_pWaveFile->m_tFirstTime.addMSecs((int)m_pWaveShow->m_pWaveFile->m_DispAttr.m_fStaticTime).toString("yyyy-MM-dd hh:mm:ss.zzz"))); +// statusLabel->setText("OK!"); +// } + emit StatusEmited(); +} + +void CWaveShow::ShowAllTags() +{ + if(m_pWaveFile->m_DispAttr.m_nTagShowType == TAG_SHOWALL) + m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWNONE; + else + m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWALL; + RecacuAreas(); + if(m_pDigitalView) + m_pDigitalView->ResetVScrollSize(); + redrawWindow(3,false); + redrawWindow(4,false); +} + +void CWaveShow::ShowActionTags() +{ + int nDigtialActive = 0; + for(int i = 0;im_nDigitalNum;i++) + { + int nTickTemp = 0; + for(nTickTemp = 0;nTickTempDigitDataList[i].m_bySampleData.count();nTickTemp++) + { + byte nTickBy = m_pWaveFile->DigitDataList[i].m_bySampleData[nTickTemp]; + if(nTickBy == 1) + break; + } + if(nTickTemp == m_pWaveFile->DigitDataList[i].m_bySampleData.count()) + continue; + nDigtialActive++; + } + if(nDigtialActive > 0) + m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWACTION; + else + m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWNONE; + RecacuAreas(); + if(m_pDigitalView) + m_pDigitalView->ResetVScrollSize(); + redrawWindow(3,false); + redrawWindow(4,false); +} + +void CWaveShow::ShowNoneTags() +{ + m_pWaveFile->m_DispAttr.m_nTagShowType = TAG_SHOWNONE; + RecacuAreas(); + if(m_pDigitalView) + m_pDigitalView->ResetVScrollSize(); + redrawWindow(3,false); + redrawWindow(4,false); +} + +void CWaveShow::setLineValueType( int nType ) +{ + for(int i = 0;iAnalogDataList.count();i++) + { + CAnalogData& ana = m_pWaveFile->AnalogDataList[i]; + if( ana.m_nWaveType>=CHN_AMP0_ATTR&&ana.m_nWaveType<=CHN_AMP99_ATTR ) + continue; + m_pWaveFile->AnalogDataList[i].m_nWaveType = nType; + } + m_pWaveFile->SetUnitType(m_pWaveFile->m_DispAttr.m_byValueType); + if(m_pAnaAxisView) m_pAnaAxisView->update(); + if(m_pAnalogueView) m_pAnalogueView->update(); + if(m_pDgtNameView) m_pDgtNameView->update(); + if(m_pDigitalView) m_pDigitalView->update(); + if(m_pTimeAxisView) m_pTimeAxisView->update(); + update(); +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveShow.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveShow.h index ec673a5f..dcec48de 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveShow.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CWaveShow.h @@ -1,243 +1,243 @@ -#ifndef CWAVESHOW_H_HEADER_INCLUDED_BFC41131 -#define CWAVESHOW_H_HEADER_INCLUDED_BFC41131 - -#include - -#include -#include -#include -#include -#include -#include -#include "CWaveGraph.h" -#include -#include "CAnalogueShow.h" -#include "CAnaAxisShow.h" -#include "CDigitalShow.h" -#include "CDgtNameShow.h" -#include "CTimeAxisShow.h" -//#include "cstatusshow.h" -#include "CLineStatusShow.h" - -//class CPrintsetupDlg; -class QAction; -//打印设置属性 -struct PRINTPARAM{ - - double dLeftMargin;//边距 - double dTopMargin; - double dRightMargin; - double dBottomMargin; - - bool bColor; //彩色或黑白 - bool bZonePrint; //区域打印或全部打印 - bool bAnaPrint; //模拟 - bool bDgtPrint; //状态 - bool bTimePrint; //时间 - bool bNamePrint; //名称 - bool bTitlePrint; //页眉与页角 - bool bLinePrint; //时标线值 - bool bOrient; //方向true 横向、false纵向 - - QStringList m_listAnaPrint; //打印模拟通道 - QStringList m_listDgtPrint; //打印状态通道 -}; - -//##ModelId=403405ED00B3 -class CWaveShow : public QFrame -{ - Q_OBJECT -public: - enum enum_ZoomState{ SINGLEZOOM_IN=0,SINGLEZOOM_OUT,ZOOMRECT_X,SINGLEZOOM_NULL }; -public: - CWaveShow(QWidget *parent = 0, Qt::WindowFlags f = 0); - ~CWaveShow(); - -public: - CComtradeFile* m_pWaveFile; - PRINTPARAM m_PrintAttr; - QPrinter *printer; - - bool m_bPixmapCapturePt1; - bool m_bPixmapCaptureStart; - QPoint m_pCapturePt1; - QPoint m_pCapturePt2; - QPoint m_ptSelectLastPt; - -// QStatusBar *m_statusBar; -// QLabel *startLabel; -// QLabel *endLabel; -// QLabel *statusLabel; - - -public: - QGridLayout *grid_layout; - QScrollBar *horiz_bar; - QRubberBand* m_pRectBand; - QRubberBand* m_pHLineBand; - QRubberBand* m_pVLineBand; - -public: - enum_ZoomState m_nZoomState; - - //拉框缩放的数据 - bool m_bZoomStart; - QPoint m_ptZoomOld; - QPoint m_ptZoomNew; - - - bool m_bOnYMoveBar; - int m_nLastYPos; - bool m_bOnXMoveBar; - int m_nLastXPos; - QCursor m_hArrowCursor; - QCursor m_hUpDownCursor; - QCursor m_hLeftRightCursor; - - QCursor m_hCrossCursor; - QCursor m_hHandCursor; - - QCursor m_hZoomIn; - QCursor m_hZoomOut; - QCursor m_hZoomRect; - - CAnalogueShow *m_pAnalogueView; - CDigitalShow *m_pDigitalView; - CAnaAxisShow *m_pAnaAxisView; - CDgtNameShow *m_pDgtNameView; - CTimeAxisShow *m_pTimeAxisView; -// CStatusShow *m_pStatusView; - CLineStatusShow *m_pLinStatusView; - - int m_nCursorX; - int m_nLeftMargin; // Left margin - int m_nTimeViewTop; - int m_nTimeViewHgt; - int m_nTagsViewTop; - int m_nTagsViewHgt; - int m_nWaveViewTop; - int m_nWaveViewHgt; - int m_nMinViewHgt; - float m_fWaveHeightRate; - - QAction* moveleftAction; - QAction* moverightAction; - -public: - void redrawWindow(int i , bool bErase = true); - //##ModelId=4039BEDE0118 - bool SetComtradeData(CComtradeFile& pComtradeData); - - //##ModelId=4039BEE60389 - bool SetShowAttribute(CSectionList& pAttrList); - //##ModelId=4039BEEE026F - bool GetShowAttribute(CSectionList& pAttrList); -// bool EditAnaGroup(); -// bool EditDgtGroup(); -// bool EditAnaTable(); -// bool EditDgtTable(); -// bool EditGridSet(); - bool EditSelectLine(); - bool EditSelectColor(); - - // - void SetValueType( int nType ); - - int GetCurAnaChannel(); - int GetCurDgtChannel(); - - int GetCursorTicks(); -// void AddLabel(); -// void ShowLabels(); -// void SetZoon(); - - void DoDraw( QPainter *); - void DrawXSplitterBar( QPainter *paint, int nXPos, int nYPos ); - void DrawYSplitterBar( QPainter *paint , int nYPos ); - void DrawYBottomSplitterBar( QPainter *paint , int nYPos ); - void ReSize(const QSize &size); - // - void SetZoomState( int nState ); - - void ZoomInX(); - void ZoomOutX(); - void ZoomInAnalogueY(); - void ZoomOutAnalogueY(); - void ZoomInDigitalY(); - void ZoomOutDigitalY(); - void ZoomInName(); - void ZoomOutName(); - void ZoomFull(); - void ResumeZoom(); - // - void copySelectToClip(); -// void CopySelectPixmap(); //选择抓图复制 -// void CopyZonePixmap(); //区域复制 -// void CopyFullPixmap(); //全部复制 - - // -// void TestPrintPriview( CPrintsetupDlg *dlg ); - QPrinter* GetPrinter(); -// void PrintSetup(); - void Print(bool bSetuped = false); - void PrintPreview( QWidget* pParent = NULL ); - void PrintPageTitle(QPainter *paint,QString szTitle,int nPageNo); - - // - void RecacuAreas(); - void MoveAllViews(); - void VAnaScroll(int nValue); - void VDgtScroll(int nValue); - void HTimeScroll(int nValue); - //根据高度获取选中波形 - void HitTestWave( int nScrollTop,int nY ); - void HitTestTag( int nScrollTop,int nY ); - //{{ Add by qizhong - void copyZonepixmapToFile(); - //}} - - void showStatus(); - void ShowAllTags(); - void ShowActionTags(); - void ShowNoneTags(); - - void setLineValueType(int nType); -signals: - void ZoomSelected(); - void StatusEmited(); -protected: - virtual void resizeEvent( QResizeEvent * ); -public slots: - virtual void OnAddLabel(); - virtual void OnLabelList(); - virtual void OnSetZoneStart(); - virtual void OnSetZoneEnd(); - virtual void OnCacelZone(); - virtual void OnAnaAmpSingleIn(); - virtual void OnAnaAmpSingleOut(); - virtual void OnAnaAmpIn(); - virtual void OnAnaAmpOut(); - virtual void OnAnaAmpSet(); - virtual void OnAnaAreaIn(); - virtual void OnAnaAreaOut(); - virtual void OnAnaColorSet(); - virtual void OnAnaLineSet(); - virtual void OnDgtColorSet(); - virtual void OnDgtLineSet(); - virtual void OnMoveStepLeft(); - virtual void OnMoveStepRight(); - virtual void OnHideWaveChannel(); - virtual void OnHideTagChannel(); - virtual void OnZoomSelected(); - virtual void OnLineSliderMove(int pos); - virtual void OnResumeGroup(); -protected: - bool eventFilter( QObject* obj,QEvent* e ); - void OnMousePressEvent( QMouseEvent * ); - void OnMouseReleaseEvent( QMouseEvent * ); - void OnMouseMoveEvent( QMouseEvent * ); - void paintEvent( QPaintEvent *); -// void wheelEvent(QWheelEvent*); -}; - -#endif /* CWAVESHOW_H_HEADER_INCLUDED_BFC41131 */ +#ifndef CWAVESHOW_H_HEADER_INCLUDED_BFC41131 +#define CWAVESHOW_H_HEADER_INCLUDED_BFC41131 + +#include + +#include +#include +#include +#include +#include +#include +#include "CWaveGraph.h" +#include +#include "CAnalogueShow.h" +#include "CAnaAxisShow.h" +#include "CDigitalShow.h" +#include "CDgtNameShow.h" +#include "CTimeAxisShow.h" +//#include "cstatusshow.h" +#include "CLineStatusShow.h" + +//class CPrintsetupDlg; +class QAction; +//打印设置属性 +struct PRINTPARAM{ + + double dLeftMargin;//边距 + double dTopMargin; + double dRightMargin; + double dBottomMargin; + + bool bColor; //彩色或黑白 + bool bZonePrint; //区域打印或全部打印 + bool bAnaPrint; //模拟 + bool bDgtPrint; //状态 + bool bTimePrint; //时间 + bool bNamePrint; //名称 + bool bTitlePrint; //页眉与页角 + bool bLinePrint; //时标线值 + bool bOrient; //方向true 横向、false纵向 + + QStringList m_listAnaPrint; //打印模拟通道 + QStringList m_listDgtPrint; //打印状态通道 +}; + +//##ModelId=403405ED00B3 +class CWaveShow : public QFrame +{ + Q_OBJECT +public: + enum enum_ZoomState{ SINGLEZOOM_IN=0,SINGLEZOOM_OUT,ZOOMRECT_X,SINGLEZOOM_NULL }; +public: + CWaveShow(QWidget *parent = 0, Qt::WindowFlags f = 0); + ~CWaveShow(); + +public: + CComtradeFile* m_pWaveFile; + PRINTPARAM m_PrintAttr; + QPrinter *printer; + + bool m_bPixmapCapturePt1; + bool m_bPixmapCaptureStart; + QPoint m_pCapturePt1; + QPoint m_pCapturePt2; + QPoint m_ptSelectLastPt; + +// QStatusBar *m_statusBar; +// QLabel *startLabel; +// QLabel *endLabel; +// QLabel *statusLabel; + + +public: + QGridLayout *grid_layout; + QScrollBar *horiz_bar; + QRubberBand* m_pRectBand; + QRubberBand* m_pHLineBand; + QRubberBand* m_pVLineBand; + +public: + enum_ZoomState m_nZoomState; + + //拉框缩放的数据 + bool m_bZoomStart; + QPoint m_ptZoomOld; + QPoint m_ptZoomNew; + + + bool m_bOnYMoveBar; + int m_nLastYPos; + bool m_bOnXMoveBar; + int m_nLastXPos; + QCursor m_hArrowCursor; + QCursor m_hUpDownCursor; + QCursor m_hLeftRightCursor; + + QCursor m_hCrossCursor; + QCursor m_hHandCursor; + + QCursor m_hZoomIn; + QCursor m_hZoomOut; + QCursor m_hZoomRect; + + CAnalogueShow *m_pAnalogueView; + CDigitalShow *m_pDigitalView; + CAnaAxisShow *m_pAnaAxisView; + CDgtNameShow *m_pDgtNameView; + CTimeAxisShow *m_pTimeAxisView; +// CStatusShow *m_pStatusView; + CLineStatusShow *m_pLinStatusView; + + int m_nCursorX; + int m_nLeftMargin; // Left margin + int m_nTimeViewTop; + int m_nTimeViewHgt; + int m_nTagsViewTop; + int m_nTagsViewHgt; + int m_nWaveViewTop; + int m_nWaveViewHgt; + int m_nMinViewHgt; + float m_fWaveHeightRate; + + QAction* moveleftAction; + QAction* moverightAction; + +public: + void redrawWindow(int i , bool bErase = true); + //##ModelId=4039BEDE0118 + bool SetComtradeData(CComtradeFile& pComtradeData); + + //##ModelId=4039BEE60389 + bool SetShowAttribute(CSectionList& pAttrList); + //##ModelId=4039BEEE026F + bool GetShowAttribute(CSectionList& pAttrList); +// bool EditAnaGroup(); +// bool EditDgtGroup(); +// bool EditAnaTable(); +// bool EditDgtTable(); +// bool EditGridSet(); + bool EditSelectLine(); + bool EditSelectColor(); + + // + void SetValueType( int nType ); + + int GetCurAnaChannel(); + int GetCurDgtChannel(); + + int GetCursorTicks(); +// void AddLabel(); +// void ShowLabels(); +// void SetZoon(); + + void DoDraw( QPainter *); + void DrawXSplitterBar( QPainter *paint, int nXPos, int nYPos ); + void DrawYSplitterBar( QPainter *paint , int nYPos ); + void DrawYBottomSplitterBar( QPainter *paint , int nYPos ); + void ReSize(const QSize &size); + // + void SetZoomState( int nState ); + + void ZoomInX(); + void ZoomOutX(); + void ZoomInAnalogueY(); + void ZoomOutAnalogueY(); + void ZoomInDigitalY(); + void ZoomOutDigitalY(); + void ZoomInName(); + void ZoomOutName(); + void ZoomFull(); + void ResumeZoom(); + // + void copySelectToClip(); +// void CopySelectPixmap(); //选择抓图复制 +// void CopyZonePixmap(); //区域复制 +// void CopyFullPixmap(); //全部复制 + + // +// void TestPrintPriview( CPrintsetupDlg *dlg ); + QPrinter* GetPrinter(); +// void PrintSetup(); + void Print(bool bSetuped = false); + void PrintPreview( QWidget* pParent = NULL ); + void PrintPageTitle(QPainter *paint,QString szTitle,int nPageNo); + + // + void RecacuAreas(); + void MoveAllViews(); + void VAnaScroll(int nValue); + void VDgtScroll(int nValue); + void HTimeScroll(int nValue); + //根据高度获取选中波形 + void HitTestWave( int nScrollTop,int nY ); + void HitTestTag( int nScrollTop,int nY ); + //{{ Add by qizhong + void copyZonepixmapToFile(); + //}} + + void showStatus(); + void ShowAllTags(); + void ShowActionTags(); + void ShowNoneTags(); + + void setLineValueType(int nType); +signals: + void ZoomSelected(); + void StatusEmited(); +protected: + virtual void resizeEvent( QResizeEvent * ); +public slots: + virtual void OnAddLabel(); + virtual void OnLabelList(); + virtual void OnSetZoneStart(); + virtual void OnSetZoneEnd(); + virtual void OnCacelZone(); + virtual void OnAnaAmpSingleIn(); + virtual void OnAnaAmpSingleOut(); + virtual void OnAnaAmpIn(); + virtual void OnAnaAmpOut(); + virtual void OnAnaAmpSet(); + virtual void OnAnaAreaIn(); + virtual void OnAnaAreaOut(); + virtual void OnAnaColorSet(); + virtual void OnAnaLineSet(); + virtual void OnDgtColorSet(); + virtual void OnDgtLineSet(); + virtual void OnMoveStepLeft(); + virtual void OnMoveStepRight(); + virtual void OnHideWaveChannel(); + virtual void OnHideTagChannel(); + virtual void OnZoomSelected(); + virtual void OnLineSliderMove(int pos); + virtual void OnResumeGroup(); +protected: + bool eventFilter( QObject* obj,QEvent* e ); + void OnMousePressEvent( QMouseEvent * ); + void OnMouseReleaseEvent( QMouseEvent * ); + void OnMouseMoveEvent( QMouseEvent * ); + void paintEvent( QPaintEvent *); +// void wheelEvent(QWheelEvent*); +}; + +#endif /* CWAVESHOW_H_HEADER_INCLUDED_BFC41131 */ diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CommonFunction.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CommonFunction.cpp index f10c7b92..f127b077 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CommonFunction.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CommonFunction.cpp @@ -1,30 +1,30 @@ -#include "CommonFunction.h" - -bool autoSetTextStreamCodec( QTextStream& objTextStream ) -{ - QIODevice* pDevice = objTextStream.device(); - if ( !pDevice || !pDevice->isOpen() || !pDevice->isReadable() ) - return false; - - QByteArray byData = pDevice->readAll(); - pDevice->reset(); - - QTextCodec::ConverterState stStateUTF8; - QTextCodec::ConverterState stStateGBK; - QTextCodec::codecForName("UTF-8")->toUnicode(byData.data(),byData.length(),&stStateUTF8); - if ( stStateUTF8.invalidChars <= 0 ) - { - objTextStream.setCodec("UTF-8"); - return true; - } - else - { - QTextCodec::codecForName("GBK")->toUnicode(byData.data(),byData.length(),&stStateGBK); - if ( stStateGBK.invalidChars <= 0 ) - { - objTextStream.setCodec("GBK"); - return true; - } - } - return false; -} +#include "CommonFunction.h" + +bool autoSetTextStreamCodec( QTextStream& objTextStream ) +{ + QIODevice* pDevice = objTextStream.device(); + if ( !pDevice || !pDevice->isOpen() || !pDevice->isReadable() ) + return false; + + QByteArray byData = pDevice->readAll(); + pDevice->reset(); + + QTextCodec::ConverterState stStateUTF8; + QTextCodec::ConverterState stStateGBK; + QTextCodec::codecForName("UTF-8")->toUnicode(byData.data(),byData.length(),&stStateUTF8); + if ( stStateUTF8.invalidChars <= 0 ) + { + objTextStream.setCodec("UTF-8"); + return true; + } + else + { + QTextCodec::codecForName("GBK")->toUnicode(byData.data(),byData.length(),&stStateGBK); + if ( stStateGBK.invalidChars <= 0 ) + { + objTextStream.setCodec("GBK"); + return true; + } + } + return false; +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CommonFunction.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CommonFunction.h index 1b7f3689..06bb150d 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CommonFunction.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CommonFunction.h @@ -1,17 +1,17 @@ -#ifndef COMMONFUNCTION_H -#define COMMONFUNCTION_H - -#include -#include -#include -#include - -/** - * @brief autoSetTextStreamCodec 自动设置TextStream文件读取编码,设置为gbk或utf8其中一种 - * @param objFile 文件对象 - * @param objTextStream 读取对象 - * @return true:成功 false:失败 - */ -bool autoSetTextStreamCodec( QTextStream& objTextStream ); - -#endif // COMMONFUNCTION_H +#ifndef COMMONFUNCTION_H +#define COMMONFUNCTION_H + +#include +#include +#include +#include + +/** + * @brief autoSetTextStreamCodec 自动设置TextStream文件读取编码,设置为gbk或utf8其中一种 + * @param objFile 文件对象 + * @param objTextStream 读取对象 + * @return true:成功 false:失败 + */ +bool autoSetTextStreamCodec( QTextStream& objTextStream ); + +#endif // COMMONFUNCTION_H diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/calgorithms.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/calgorithms.cpp index 4ad427c5..8ff5f142 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/calgorithms.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/calgorithms.cpp @@ -1,301 +1,301 @@ -#include "calgorithms.h" -#include "math.h" - -#include -#include -#include - -const double PI = 3.1415926535897932384626433832795 ; -const double SQRT_OF_2 = 1.4142135623730950488016887242097; -const double PI_TO_ANGLE = 180 / PI ; - -/////////////////////////////////////////////////////////////////// -CAlgorithms::CAlgorithms():fourier_coff_cos(0), fourier_coff_sin(0) -{ -} - -CAlgorithms::~CAlgorithms() -{ - delete [] fourier_coff_cos; - delete [] fourier_coff_sin; -} - -//---------------------------------------------------------- -// Function: preCalCoff -// Input: wavedata &wave_data -// Output: void -// Return: bool -// Desc: 计算付式算法系数 -// ModifyTime Reason -//---------------------------------------------------------- -bool CAlgorithms::preCalCoff(wavedata &wave_data, const unsigned int fv_harmonic) -{ - unsigned int i; - - if(fv_harmonic == 0) - { - QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("The Order Of Harmonic Sholud Be Greater Than 0"));//对不起,该算法不能计算0次谐波,带来不便敬清谅解 - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - return 0; - } - sample_dot = (wave_data.fsi + 25) / 50;//基波采样点数,四舍五入处理 - - if(sample_dot == 0) - { - QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Smapling Data Reading Error"));//"preCalCoff函数:采样点读取错误" - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - return 0; - } - if((sample_dot > 2) && (fv_harmonic > (sample_dot / 3)))//根据采样定律,至少3个点 - { - //对不起,根据\"采样定律\"该算法最大只能计算到nn次谐波,带来不便敬清谅解 - - QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("The Order Of Harmonic Sholud Be Less Than nn")); - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - return 0; - } - rad = PI * 2.0 / sample_dot;//基波角速度 - - //傅式算法系数计算,固定取基波一周期的采样点,高次谐波系数不一定重复,以减小误差 - delete [] fourier_coff_cos; - delete [] fourier_coff_sin; - fourier_coff_cos = new double[sample_dot]; - fourier_coff_sin = new double[sample_dot]; - if((fourier_coff_sin == 0) || (fourier_coff_cos == 0)) - { - QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Out of Memory"));//"preCalCoff函数:lv_p_cos、lv_p_sin内存分配错误" - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - return 0; - } - - for(i = 0; i < sample_dot; i++) - { - double lv_harmonic_angle = rad * fv_harmonic * i;//谐波角度 = 谐波角速度 X i - fourier_coff_cos[i] = cos(lv_harmonic_angle); - fourier_coff_sin[i] = sin(lv_harmonic_angle); - } - - return 1; -} - -//---------------------------------------------------------- -// Function: basicArithmetic -// Input: wavedata &wave_data -// Output: wavedata &wave_data -// Return: bool -// Desc: 三或四输入求付式算法 -// ModifyTime Reason -//---------------------------------------------------------- -bool CAlgorithms::fourInputArithmetic(wavedata &wave_data) -{ - unsigned int i, k; - - if(!preCalCoff(wave_data))//系数求取 - { - wave_data.numo = 0; - wave_data.numoc = 0; - return 0; - } - - if(wave_data.numic == 3) - { - wave_data.numoc = 24;//输出量个数 - } - else if(wave_data.numic == 4) - { - wave_data.numoc = 28;//输出量个数 - } - else - { - QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Error") + ":wave_data.numic");//"fourInputArithmetic函数:wave_data.numic错误" - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - wave_data.numo = 0; - wave_data.numoc = 0; - return 0; - } - - wave_data.numo = wave_data.numi;//每个输出量的长度 - - for(i = 0; i < wave_data.numoc; i++)//分配内存 - { - wave_data.po[i] = new double[wave_data.numo]; - if(wave_data.po[i] == 0) - { - QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Out of Memory"));//"fourInputArithmetic函数:wave_data.po[i]内存分配错误" - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - return 0; - } - } - - //求取零、正、负序电量 - for(k = 0; k < 3; k++)//付式算法 - { - short lv_index = 4 * k; - if(!resultOfFourier(wave_data.numi, wave_data.pi[k], wave_data.po[lv_index], - wave_data.po[lv_index + 1], wave_data.po[lv_index + 2], wave_data.po[lv_index + 3])) - { - return 0; - } - } - - for(i = 0; i < wave_data.numi; i++) - { - //正序 - wave_data.po[12][i] = (wave_data.po[0][i] - 0.5 * (wave_data.po[4][i] + wave_data.po[8][i]) - 0.866 * (wave_data.po[5][i] - wave_data.po[9][i])) / 3; - wave_data.po[13][i] = (wave_data.po[1][i] - 0.5 * (wave_data.po[5][i] + wave_data.po[9][i]) + 0.866 * (wave_data.po[4][i] - wave_data.po[8][i])) / 3; - wave_data.po[14][i] = sqrt(wave_data.po[13][i] * wave_data.po[13][i] + wave_data.po[12][i] * wave_data.po[12][i]); - wave_data.po[15][i] = atan2(wave_data.po[13][i], wave_data.po[12][i]) * PI_TO_ANGLE; - - //负序 - wave_data.po[16][i] = (wave_data.po[0][i] - 0.5 * (wave_data.po[4][i] + wave_data.po[8][i]) + 0.866 * (wave_data.po[5][i] - wave_data.po[9][i])) / 3; - wave_data.po[17][i] = (wave_data.po[1][i] - 0.5 * (wave_data.po[5][i] + wave_data.po[9][i]) - 0.866 * (wave_data.po[4][i] - wave_data.po[8][i])) / 3; - wave_data.po[18][i] = sqrt(wave_data.po[17][i] * wave_data.po[17][i] + wave_data.po[16][i] * wave_data.po[16][i]); - wave_data.po[19][i] = atan2(wave_data.po[17][i], wave_data.po[16][i]) * PI_TO_ANGLE; - - //三倍零序 - wave_data.po[20][i] = (wave_data.po[0][i] + wave_data.po[4][i] + wave_data.po[8][i]); - wave_data.po[21][i] = (wave_data.po[1][i] + wave_data.po[5][i] + wave_data.po[9][i]); - wave_data.po[22][i] = sqrt(wave_data.po[21][i] * wave_data.po[21][i] + wave_data.po[20][i] * wave_data.po[20][i]); - wave_data.po[23][i] = atan2(wave_data.po[21][i], wave_data.po[20][i]) * PI_TO_ANGLE; - } - if(wave_data.numic == 4) - { - if(!resultOfFourier(wave_data.numi, wave_data.pi[3], wave_data.po[24], - wave_data.po[25], wave_data.po[26], wave_data.po[27])) - { - return 0; - } - } - - return 1; -} - - -//---------------------------------------------------------- -// Function: oneInputArithmetic -// Input: wavedata &wave_data -// Output: wavedata &wave_data -// Return: bool -// Desc: 一输入求付式算法 -// ModifyTime Reason -//---------------------------------------------------------- -bool CAlgorithms::oneInputArithmetic(wavedata &wave_data, const unsigned int fv_harmonic) -{ - unsigned int i; - - if(!preCalCoff(wave_data, fv_harmonic))//系数求取 - { - wave_data.numo = 0; - wave_data.numoc = 0; - return 0; - } - - wave_data.numoc = 4;//输出量个数 - wave_data.numo = wave_data.numi;//每个输出量的长度 - - for(i = 0; i < wave_data.numoc; i++)//分配内存 - { - wave_data.po[i] = new double[wave_data.numo]; - if(wave_data.po[i] == 0) - { - QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Out of Memory"));//"preCalCoff函数:wave_data.po[i]内存分配错误" - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - return 0; - } - } - - //电量 - if(resultOfFourier(wave_data.numi, wave_data.pi[0], wave_data.po[0], - wave_data.po[1], wave_data.po[2], wave_data.po[3])) - { - return 1; - } - else - { - return 0; - } - -} - - -//---------------------------------------------------------- -// Function: resultOfFourier -// Input: wavedata &wave_data -// Output: wavedata &wave_data -// Return: bool -// Desc: 付式算法 -// ModifyTime Reason -//---------------------------------------------------------- -bool CAlgorithms::resultOfFourier(unsigned int fv_num, double *fv_input, - double *fv_output_real, double *fv_output_imag, double *fv_output_ampl, double *fv_output_angle) -{ - double lv_sum_real; - double lv_sum_imag; - unsigned int i, j; - - if((fv_input == 0) || (fourier_coff_cos == 0) || (fourier_coff_sin == 0) - || (fv_output_real == 0) || (fv_output_imag == 0) || (fv_output_ampl == 0) || (fv_output_angle == 0)) - { - QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("input error")); - objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); - objMsgBox.exec(); - return 0; - } - - for(j = sample_dot; j < fv_num; j++) - { - lv_sum_real = 0; - lv_sum_imag = 0; - for(i =0; i < sample_dot; i++) - { - double lv_val_temp = fv_input[j + i - sample_dot]; - lv_sum_real += lv_val_temp * fourier_coff_sin[i]; - lv_sum_imag += lv_val_temp * fourier_coff_cos[i]; - } - fv_output_real[j] = 2 * lv_sum_real / sample_dot / SQRT_OF_2; - fv_output_imag[j] = 2 * lv_sum_imag / sample_dot / SQRT_OF_2; - fv_output_ampl[j] = sqrt(fv_output_real[j] * fv_output_real[j] + fv_output_imag[j] * fv_output_imag[j]); - fv_output_angle[j] = atan2(fv_output_imag[j], fv_output_real[j]) * PI_TO_ANGLE; - } - //胡剑锋修改:有问题,如果fv_num<2*sample_dot,怎么办? - //old: for(j = 0; j < sample_dot; j++)//第一个周期使用第二个周期的重复 - for(j = 0; j < sample_dot &&j < fv_num&&j <(fv_num - sample_dot); j++)//第一个周期使用第二个周期的重复 - { - fv_output_real[j] = fv_output_real[j + sample_dot]; - fv_output_imag[j] = fv_output_imag[j + sample_dot]; - fv_output_ampl[j] = fv_output_ampl[j + sample_dot]; - fv_output_angle[j] = fv_output_angle[j + sample_dot]; - } - - return 1; -} - -//---------------------------------------------------------- -// Function: angelCal -// Input: double &fv_real: -// double &fv_imag: -// Output: wave_data -// Return: double: 反正切结果,0~360度 -// Desc: 计算角度 -// ModifyTime Reason -//---------------------------------------------------------- -double CAlgorithms::angelCal(double &fv_imag, double &fv_real) -{ - double lv_angle; - - lv_angle = atan2(fv_imag, fv_real) * PI_TO_ANGLE; - if(lv_angle < 0) - { - lv_angle += 360; - } - - return lv_angle; -} - +#include "calgorithms.h" +#include "math.h" + +#include +#include +#include + +const double PI = 3.1415926535897932384626433832795 ; +const double SQRT_OF_2 = 1.4142135623730950488016887242097; +const double PI_TO_ANGLE = 180 / PI ; + +/////////////////////////////////////////////////////////////////// +CAlgorithms::CAlgorithms():fourier_coff_cos(0), fourier_coff_sin(0) +{ +} + +CAlgorithms::~CAlgorithms() +{ + delete [] fourier_coff_cos; + delete [] fourier_coff_sin; +} + +//---------------------------------------------------------- +// Function: preCalCoff +// Input: wavedata &wave_data +// Output: void +// Return: bool +// Desc: 计算付式算法系数 +// ModifyTime Reason +//---------------------------------------------------------- +bool CAlgorithms::preCalCoff(wavedata &wave_data, const unsigned int fv_harmonic) +{ + unsigned int i; + + if(fv_harmonic == 0) + { + QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("The Order Of Harmonic Sholud Be Greater Than 0"));//对不起,该算法不能计算0次谐波,带来不便敬清谅解 + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + return 0; + } + sample_dot = (wave_data.fsi + 25) / 50;//基波采样点数,四舍五入处理 + + if(sample_dot == 0) + { + QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Smapling Data Reading Error"));//"preCalCoff函数:采样点读取错误" + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + return 0; + } + if((sample_dot > 2) && (fv_harmonic > (sample_dot / 3)))//根据采样定律,至少3个点 + { + //对不起,根据\"采样定律\"该算法最大只能计算到nn次谐波,带来不便敬清谅解 + + QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("The Order Of Harmonic Sholud Be Less Than nn")); + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + return 0; + } + rad = PI * 2.0 / sample_dot;//基波角速度 + + //傅式算法系数计算,固定取基波一周期的采样点,高次谐波系数不一定重复,以减小误差 + delete [] fourier_coff_cos; + delete [] fourier_coff_sin; + fourier_coff_cos = new double[sample_dot]; + fourier_coff_sin = new double[sample_dot]; + if((fourier_coff_sin == 0) || (fourier_coff_cos == 0)) + { + QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Out of Memory"));//"preCalCoff函数:lv_p_cos、lv_p_sin内存分配错误" + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + return 0; + } + + for(i = 0; i < sample_dot; i++) + { + double lv_harmonic_angle = rad * fv_harmonic * i;//谐波角度 = 谐波角速度 X i + fourier_coff_cos[i] = cos(lv_harmonic_angle); + fourier_coff_sin[i] = sin(lv_harmonic_angle); + } + + return 1; +} + +//---------------------------------------------------------- +// Function: basicArithmetic +// Input: wavedata &wave_data +// Output: wavedata &wave_data +// Return: bool +// Desc: 三或四输入求付式算法 +// ModifyTime Reason +//---------------------------------------------------------- +bool CAlgorithms::fourInputArithmetic(wavedata &wave_data) +{ + unsigned int i, k; + + if(!preCalCoff(wave_data))//系数求取 + { + wave_data.numo = 0; + wave_data.numoc = 0; + return 0; + } + + if(wave_data.numic == 3) + { + wave_data.numoc = 24;//输出量个数 + } + else if(wave_data.numic == 4) + { + wave_data.numoc = 28;//输出量个数 + } + else + { + QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Error") + ":wave_data.numic");//"fourInputArithmetic函数:wave_data.numic错误" + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + wave_data.numo = 0; + wave_data.numoc = 0; + return 0; + } + + wave_data.numo = wave_data.numi;//每个输出量的长度 + + for(i = 0; i < wave_data.numoc; i++)//分配内存 + { + wave_data.po[i] = new double[wave_data.numo]; + if(wave_data.po[i] == 0) + { + QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Out of Memory"));//"fourInputArithmetic函数:wave_data.po[i]内存分配错误" + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + return 0; + } + } + + //求取零、正、负序电量 + for(k = 0; k < 3; k++)//付式算法 + { + short lv_index = 4 * k; + if(!resultOfFourier(wave_data.numi, wave_data.pi[k], wave_data.po[lv_index], + wave_data.po[lv_index + 1], wave_data.po[lv_index + 2], wave_data.po[lv_index + 3])) + { + return 0; + } + } + + for(i = 0; i < wave_data.numi; i++) + { + //正序 + wave_data.po[12][i] = (wave_data.po[0][i] - 0.5 * (wave_data.po[4][i] + wave_data.po[8][i]) - 0.866 * (wave_data.po[5][i] - wave_data.po[9][i])) / 3; + wave_data.po[13][i] = (wave_data.po[1][i] - 0.5 * (wave_data.po[5][i] + wave_data.po[9][i]) + 0.866 * (wave_data.po[4][i] - wave_data.po[8][i])) / 3; + wave_data.po[14][i] = sqrt(wave_data.po[13][i] * wave_data.po[13][i] + wave_data.po[12][i] * wave_data.po[12][i]); + wave_data.po[15][i] = atan2(wave_data.po[13][i], wave_data.po[12][i]) * PI_TO_ANGLE; + + //负序 + wave_data.po[16][i] = (wave_data.po[0][i] - 0.5 * (wave_data.po[4][i] + wave_data.po[8][i]) + 0.866 * (wave_data.po[5][i] - wave_data.po[9][i])) / 3; + wave_data.po[17][i] = (wave_data.po[1][i] - 0.5 * (wave_data.po[5][i] + wave_data.po[9][i]) - 0.866 * (wave_data.po[4][i] - wave_data.po[8][i])) / 3; + wave_data.po[18][i] = sqrt(wave_data.po[17][i] * wave_data.po[17][i] + wave_data.po[16][i] * wave_data.po[16][i]); + wave_data.po[19][i] = atan2(wave_data.po[17][i], wave_data.po[16][i]) * PI_TO_ANGLE; + + //三倍零序 + wave_data.po[20][i] = (wave_data.po[0][i] + wave_data.po[4][i] + wave_data.po[8][i]); + wave_data.po[21][i] = (wave_data.po[1][i] + wave_data.po[5][i] + wave_data.po[9][i]); + wave_data.po[22][i] = sqrt(wave_data.po[21][i] * wave_data.po[21][i] + wave_data.po[20][i] * wave_data.po[20][i]); + wave_data.po[23][i] = atan2(wave_data.po[21][i], wave_data.po[20][i]) * PI_TO_ANGLE; + } + if(wave_data.numic == 4) + { + if(!resultOfFourier(wave_data.numi, wave_data.pi[3], wave_data.po[24], + wave_data.po[25], wave_data.po[26], wave_data.po[27])) + { + return 0; + } + } + + return 1; +} + + +//---------------------------------------------------------- +// Function: oneInputArithmetic +// Input: wavedata &wave_data +// Output: wavedata &wave_data +// Return: bool +// Desc: 一输入求付式算法 +// ModifyTime Reason +//---------------------------------------------------------- +bool CAlgorithms::oneInputArithmetic(wavedata &wave_data, const unsigned int fv_harmonic) +{ + unsigned int i; + + if(!preCalCoff(wave_data, fv_harmonic))//系数求取 + { + wave_data.numo = 0; + wave_data.numoc = 0; + return 0; + } + + wave_data.numoc = 4;//输出量个数 + wave_data.numo = wave_data.numi;//每个输出量的长度 + + for(i = 0; i < wave_data.numoc; i++)//分配内存 + { + wave_data.po[i] = new double[wave_data.numo]; + if(wave_data.po[i] == 0) + { + QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("Out of Memory"));//"preCalCoff函数:wave_data.po[i]内存分配错误" + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + return 0; + } + } + + //电量 + if(resultOfFourier(wave_data.numi, wave_data.pi[0], wave_data.po[0], + wave_data.po[1], wave_data.po[2], wave_data.po[3])) + { + return 1; + } + else + { + return 0; + } + +} + + +//---------------------------------------------------------- +// Function: resultOfFourier +// Input: wavedata &wave_data +// Output: wavedata &wave_data +// Return: bool +// Desc: 付式算法 +// ModifyTime Reason +//---------------------------------------------------------- +bool CAlgorithms::resultOfFourier(unsigned int fv_num, double *fv_input, + double *fv_output_real, double *fv_output_imag, double *fv_output_ampl, double *fv_output_angle) +{ + double lv_sum_real; + double lv_sum_imag; + unsigned int i, j; + + if((fv_input == 0) || (fourier_coff_cos == 0) || (fourier_coff_sin == 0) + || (fv_output_real == 0) || (fv_output_imag == 0) || (fv_output_ampl == 0) || (fv_output_angle == 0)) + { + QMessageBox objMsgBox(QMessageBox::Information, "Info", QObject::tr("input error")); + objMsgBox.setWindowFlag( Qt::WindowStaysOnTopHint ); + objMsgBox.exec(); + return 0; + } + + for(j = sample_dot; j < fv_num; j++) + { + lv_sum_real = 0; + lv_sum_imag = 0; + for(i =0; i < sample_dot; i++) + { + double lv_val_temp = fv_input[j + i - sample_dot]; + lv_sum_real += lv_val_temp * fourier_coff_sin[i]; + lv_sum_imag += lv_val_temp * fourier_coff_cos[i]; + } + fv_output_real[j] = 2 * lv_sum_real / sample_dot / SQRT_OF_2; + fv_output_imag[j] = 2 * lv_sum_imag / sample_dot / SQRT_OF_2; + fv_output_ampl[j] = sqrt(fv_output_real[j] * fv_output_real[j] + fv_output_imag[j] * fv_output_imag[j]); + fv_output_angle[j] = atan2(fv_output_imag[j], fv_output_real[j]) * PI_TO_ANGLE; + } + //胡剑锋修改:有问题,如果fv_num<2*sample_dot,怎么办? + //old: for(j = 0; j < sample_dot; j++)//第一个周期使用第二个周期的重复 + for(j = 0; j < sample_dot &&j < fv_num&&j <(fv_num - sample_dot); j++)//第一个周期使用第二个周期的重复 + { + fv_output_real[j] = fv_output_real[j + sample_dot]; + fv_output_imag[j] = fv_output_imag[j + sample_dot]; + fv_output_ampl[j] = fv_output_ampl[j + sample_dot]; + fv_output_angle[j] = fv_output_angle[j + sample_dot]; + } + + return 1; +} + +//---------------------------------------------------------- +// Function: angelCal +// Input: double &fv_real: +// double &fv_imag: +// Output: wave_data +// Return: double: 反正切结果,0~360度 +// Desc: 计算角度 +// ModifyTime Reason +//---------------------------------------------------------- +double CAlgorithms::angelCal(double &fv_imag, double &fv_real) +{ + double lv_angle; + + lv_angle = atan2(fv_imag, fv_real) * PI_TO_ANGLE; + if(lv_angle < 0) + { + lv_angle += 360; + } + + return lv_angle; +} + diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/calgorithms.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/calgorithms.h index 86195f1f..3f7fe3f7 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/calgorithms.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/calgorithms.h @@ -1,96 +1,96 @@ -#ifndef CALGORITHMS_H_HEADER_INCLUDED -#define CALGORITHMS_H_HEADER_INCLUDED - - -#include "wavedata.h" - -class CAlgorithms -{ -public: - CAlgorithms(); - ~CAlgorithms(); -public: -//******************************************************************** -// 输入ABC三相电量,或 -// 输入ABC、外接零序四相电量, -// 输出各相及正序、负序、自产零序的实部、虚部、幅值、相角 -//==输入:================================= -// -// wave_data.numi 采样点数 -// wave_data.fsi 采样率 -// wave_data.pi[0] A相电量瞬时值 -// wave_data.pi[1] B相电量瞬时值 -// wave_data.pi[2] C相电量瞬时值 -// wave_data.pi[3] 外接零序电量瞬时值 -// -//==输出:================================ -// wave_data.po[0] A相real -// wave_data.po[1] A相imag -// wave_data.po[2] A相幅值 -// wave_data.po[3] A相相角 -// -// wave_data.po[4] B相real -// wave_data.po[5] B相imag -// wave_data.po[6] B相幅值 -// wave_data.po[7] B相相角 -// -// wave_data.po[8] C相real -// wave_data.po[9] C相imag -// wave_data.po[10] C相幅值 -// wave_data.po[11] C相相角 -// -// wave_data.po[12] 正序real -// wave_data.po[13] 正序imag -// wave_data.po[14] 正序幅值 -// wave_data.po[15] 正序相角 -// -// wave_data.po[12] 负序real -// wave_data.po[13] 负序imag -// wave_data.po[14] 负序幅值 -// wave_data.po[15] 负序相角 -// -// wave_data.po[16] 自产零序real -// wave_data.po[17] 自产零序imag -// wave_data.po[18] 自产零序幅值 -// wave_data.po[19] 自产零序相角 -// -// wave_data.po[20] 外接零序real -// wave_data.po[21] 外接零序imag -// wave_data.po[22] 外接零序幅值 -// wave_data.po[23] 外接零序相角 -//******************************************************************** - bool fourInputArithmetic( wavedata &wave_data); - -//******************************************************************** -// 输入一相电量, -// 输出该项的实部、虚部、幅值、相角 -//==输入:================================= -// fv_freq 谐波次数,默认为基波 -// wave_data.numi 采样点数 -// wave_data.fsi 采样率 -// wave_data.pi[0] 电量瞬时值 -// -//==输出:================================ -// wave_data.po[0] real -// wave_data.po[1] imag -// wave_data.po[2] 幅值 -// wave_data.po[3] 相角 -//******************************************************************** - bool oneInputArithmetic( wavedata &wave_data, const unsigned int fv_harmonic = 1); - - -private: - double *fourier_coff_cos; - double *fourier_coff_sin; - unsigned int sample_dot; - double rad; -private: - bool preCalCoff(wavedata &wave_data, const unsigned int fv_harmonic = 1); - double angelCal(double &fv_imag, double &fv_real); - bool resultOfFourier(unsigned int fv_num, double *fv_input, double *fv_output_real, double *fv_output_imag, double *fv_output_ampl, double *fv_output_angle); - -}; - - - -#endif /* CALGORITHMS_H_HEADER_INCLUDED */ +#ifndef CALGORITHMS_H_HEADER_INCLUDED +#define CALGORITHMS_H_HEADER_INCLUDED + + +#include "wavedata.h" + +class CAlgorithms +{ +public: + CAlgorithms(); + ~CAlgorithms(); +public: +//******************************************************************** +// 输入ABC三相电量,或 +// 输入ABC、外接零序四相电量, +// 输出各相及正序、负序、自产零序的实部、虚部、幅值、相角 +//==输入:================================= +// +// wave_data.numi 采样点数 +// wave_data.fsi 采样率 +// wave_data.pi[0] A相电量瞬时值 +// wave_data.pi[1] B相电量瞬时值 +// wave_data.pi[2] C相电量瞬时值 +// wave_data.pi[3] 外接零序电量瞬时值 +// +//==输出:================================ +// wave_data.po[0] A相real +// wave_data.po[1] A相imag +// wave_data.po[2] A相幅值 +// wave_data.po[3] A相相角 +// +// wave_data.po[4] B相real +// wave_data.po[5] B相imag +// wave_data.po[6] B相幅值 +// wave_data.po[7] B相相角 +// +// wave_data.po[8] C相real +// wave_data.po[9] C相imag +// wave_data.po[10] C相幅值 +// wave_data.po[11] C相相角 +// +// wave_data.po[12] 正序real +// wave_data.po[13] 正序imag +// wave_data.po[14] 正序幅值 +// wave_data.po[15] 正序相角 +// +// wave_data.po[12] 负序real +// wave_data.po[13] 负序imag +// wave_data.po[14] 负序幅值 +// wave_data.po[15] 负序相角 +// +// wave_data.po[16] 自产零序real +// wave_data.po[17] 自产零序imag +// wave_data.po[18] 自产零序幅值 +// wave_data.po[19] 自产零序相角 +// +// wave_data.po[20] 外接零序real +// wave_data.po[21] 外接零序imag +// wave_data.po[22] 外接零序幅值 +// wave_data.po[23] 外接零序相角 +//******************************************************************** + bool fourInputArithmetic( wavedata &wave_data); + +//******************************************************************** +// 输入一相电量, +// 输出该项的实部、虚部、幅值、相角 +//==输入:================================= +// fv_freq 谐波次数,默认为基波 +// wave_data.numi 采样点数 +// wave_data.fsi 采样率 +// wave_data.pi[0] 电量瞬时值 +// +//==输出:================================ +// wave_data.po[0] real +// wave_data.po[1] imag +// wave_data.po[2] 幅值 +// wave_data.po[3] 相角 +//******************************************************************** + bool oneInputArithmetic( wavedata &wave_data, const unsigned int fv_harmonic = 1); + + +private: + double *fourier_coff_cos; + double *fourier_coff_sin; + unsigned int sample_dot; + double rad; +private: + bool preCalCoff(wavedata &wave_data, const unsigned int fv_harmonic = 1); + double angelCal(double &fv_imag, double &fv_real); + bool resultOfFourier(unsigned int fv_num, double *fv_input, double *fv_output_real, double *fv_output_imag, double *fv_output_ampl, double *fv_output_angle); + +}; + + + +#endif /* CALGORITHMS_H_HEADER_INCLUDED */ diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cpageshow.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cpageshow.cpp index 8c103d38..8adb8111 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cpageshow.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cpageshow.cpp @@ -1,221 +1,221 @@ -#include "cpageshow.h" -#include -#include -#include -#include -#include -#include -#include - - -///////////////////////////////////////////////////// -CPageShow::CPageShow(QWidget *parent, Qt::WindowFlags f ) - :QWidget(parent,f) -{ -// setAttribute(Qt::WA_PaintOutsidePaintEvent); - setWindowFlag( Qt::WindowStaysOnTopHint ); - m_nScrollTop = 0; - m_nScrollLeft = 0; - m_nCurIndex = 0; - m_bTwoPage = false; - m_fZoomRate = 1.0; - m_nOnePageHeight = 2000; - - grid_layout = new QGridLayout(this); - - horiz_bar = new QScrollBar(Qt::Horizontal,this); - grid_layout->addWidget(horiz_bar,1,0); - horiz_bar->setMinimum(0); - horiz_bar->setMaximum(100); - horiz_bar->setSingleStep(100); - horiz_bar->setTracking(false); - connect(horiz_bar,SIGNAL(valueChanged(int)),this,SLOT(HoriztalScrollBarMove(int))); - - vert_bar = new QScrollBar(Qt::Vertical,this); - grid_layout->addWidget(vert_bar,0,1); - vert_bar->setSingleStep(100); - vert_bar->setTracking(false); - vert_bar->setMinimum(0); - vert_bar->setMaximum(100); - connect(vert_bar,SIGNAL(sliderMoved(int)),this,SLOT(VerticalSliderMove(int))); - connect(vert_bar,SIGNAL(nextLine()),this,SLOT(VerticalNextPage())); - connect(vert_bar,SIGNAL(prevLine()),this,SLOT(VerticalPrevPage())); -} - -CPageShow::~CPageShow() -{ - -} - -////////////////////////////////////////////////////////////////////////// - -void CPageShow::mousePressEvent( QMouseEvent *e ) -{ - Q_UNUSED(e) -} - -void CPageShow::mouseReleaseEvent( QMouseEvent *e ) -{ - Q_UNUSED(e) -} - -void CPageShow::paintEvent( QPaintEvent *e ) -{ - Q_UNUSED(e) - QPainter paint; - paint.begin(this ); - paint.setBrush(palette().color( QPalette::Foreground )); - draw( &paint ); - paint.end(); -} - -void CPageShow::draw( QPainter *paint ) -{ - int nWidth = width(); - int nHeight = height(); - int m_nMarginHeight = 30; - int m_nMarginWidth = 30; - - if(m_bTwoPage) - { - if(m_nCurIndex+1drawPixmap( rcMap1, m_ImageList[m_nCurIndex] ); - paint->drawPixmap( rcMap2, m_ImageList[m_nCurIndex+1] ); - - horiz_bar->setRange(0,size2.width() + size1.width() + 4*m_nMarginWidth); - horiz_bar->setSingleStep(nWidth); - vert_bar->setRange(0,qMax(size1.height(),size2.height()) + 2*m_nMarginWidth); - vert_bar->setSingleStep(nHeight); - vert_bar->setPageStep(nHeight); - m_nOnePageHeight = qMax(size1.height(),size2.height()) + 2*m_nMarginWidth; - } - } - else - { - if(m_nCurIndexdrawPixmap( rcMap, m_ImageList[m_nCurIndex] ); - - horiz_bar->setRange(0,size.width() + 2*m_nMarginWidth); - horiz_bar->setSingleStep(nWidth); - vert_bar->setRange(0,size.height() + 2*m_nMarginWidth); - vert_bar->setSingleStep(nHeight); - vert_bar->setPageStep(nHeight); - m_nOnePageHeight = size.height() + 2*m_nMarginWidth; - } - } -} - -void CPageShow::setPages( const CPixmapList & list ) -{ - for(int i=0;isetRange(0,m_ImageList.count()); - vert_bar->setSingleStep(1); - - update(); -} - -///////////////////////////////////////////////////////////////////////// -void CPageShow::HoriztalScrollBarMove(int value) -{ - m_nScrollLeft = value; - update(); -} - -void CPageShow::VerticalSliderMove(int value) -{ - m_nScrollTop = value; - update(); -} - -void CPageShow::VerticalNextPage() -{ - DoNextPage(); -} - -void CPageShow::VerticalPrevPage() -{ - DoPrevPage(); -} - - -void CPageShow::DoNextPage() -{ - m_nCurIndex++; - int nMax = m_ImageList.count() -1; - if(m_bTwoPage) - nMax -= 1; - if(m_nCurIndex >= nMax ) - m_nCurIndex = nMax; - vert_bar->setValue(0); - update(); -} - -void CPageShow::DoPrevPage() -{ - m_nCurIndex--; - if(m_nCurIndex < 0 ) - m_nCurIndex = 0; - vert_bar->setValue(0); - update(); -} - -void CPageShow::DoTwoPage() -{ - m_bTwoPage = !m_bTwoPage; - update(); - -} - -void CPageShow::DoZoomIn() -{ - m_fZoomRate += 0.5; - if(m_fZoomRate > 3.0 ) - m_fZoomRate = 3.0; - update(); - -} - - -void CPageShow::DoZoomOut() -{ - m_fZoomRate -= 0.5; - if(m_fZoomRate < 1.0 ) - m_fZoomRate = 1.0; - update(); -} +#include "cpageshow.h" +#include +#include +#include +#include +#include +#include +#include + + +///////////////////////////////////////////////////// +CPageShow::CPageShow(QWidget *parent, Qt::WindowFlags f ) + :QWidget(parent,f) +{ +// setAttribute(Qt::WA_PaintOutsidePaintEvent); + setWindowFlag( Qt::WindowStaysOnTopHint ); + m_nScrollTop = 0; + m_nScrollLeft = 0; + m_nCurIndex = 0; + m_bTwoPage = false; + m_fZoomRate = 1.0; + m_nOnePageHeight = 2000; + + grid_layout = new QGridLayout(this); + + horiz_bar = new QScrollBar(Qt::Horizontal,this); + grid_layout->addWidget(horiz_bar,1,0); + horiz_bar->setMinimum(0); + horiz_bar->setMaximum(100); + horiz_bar->setSingleStep(100); + horiz_bar->setTracking(false); + connect(horiz_bar,SIGNAL(valueChanged(int)),this,SLOT(HoriztalScrollBarMove(int))); + + vert_bar = new QScrollBar(Qt::Vertical,this); + grid_layout->addWidget(vert_bar,0,1); + vert_bar->setSingleStep(100); + vert_bar->setTracking(false); + vert_bar->setMinimum(0); + vert_bar->setMaximum(100); + connect(vert_bar,SIGNAL(sliderMoved(int)),this,SLOT(VerticalSliderMove(int))); + connect(vert_bar,SIGNAL(nextLine()),this,SLOT(VerticalNextPage())); + connect(vert_bar,SIGNAL(prevLine()),this,SLOT(VerticalPrevPage())); +} + +CPageShow::~CPageShow() +{ + +} + +////////////////////////////////////////////////////////////////////////// + +void CPageShow::mousePressEvent( QMouseEvent *e ) +{ + Q_UNUSED(e) +} + +void CPageShow::mouseReleaseEvent( QMouseEvent *e ) +{ + Q_UNUSED(e) +} + +void CPageShow::paintEvent( QPaintEvent *e ) +{ + Q_UNUSED(e) + QPainter paint; + paint.begin(this ); + paint.setBrush(palette().color( QPalette::Foreground )); + draw( &paint ); + paint.end(); +} + +void CPageShow::draw( QPainter *paint ) +{ + int nWidth = width(); + int nHeight = height(); + int m_nMarginHeight = 30; + int m_nMarginWidth = 30; + + if(m_bTwoPage) + { + if(m_nCurIndex+1drawPixmap( rcMap1, m_ImageList[m_nCurIndex] ); + paint->drawPixmap( rcMap2, m_ImageList[m_nCurIndex+1] ); + + horiz_bar->setRange(0,size2.width() + size1.width() + 4*m_nMarginWidth); + horiz_bar->setSingleStep(nWidth); + vert_bar->setRange(0,qMax(size1.height(),size2.height()) + 2*m_nMarginWidth); + vert_bar->setSingleStep(nHeight); + vert_bar->setPageStep(nHeight); + m_nOnePageHeight = qMax(size1.height(),size2.height()) + 2*m_nMarginWidth; + } + } + else + { + if(m_nCurIndexdrawPixmap( rcMap, m_ImageList[m_nCurIndex] ); + + horiz_bar->setRange(0,size.width() + 2*m_nMarginWidth); + horiz_bar->setSingleStep(nWidth); + vert_bar->setRange(0,size.height() + 2*m_nMarginWidth); + vert_bar->setSingleStep(nHeight); + vert_bar->setPageStep(nHeight); + m_nOnePageHeight = size.height() + 2*m_nMarginWidth; + } + } +} + +void CPageShow::setPages( const CPixmapList & list ) +{ + for(int i=0;isetRange(0,m_ImageList.count()); + vert_bar->setSingleStep(1); + + update(); +} + +///////////////////////////////////////////////////////////////////////// +void CPageShow::HoriztalScrollBarMove(int value) +{ + m_nScrollLeft = value; + update(); +} + +void CPageShow::VerticalSliderMove(int value) +{ + m_nScrollTop = value; + update(); +} + +void CPageShow::VerticalNextPage() +{ + DoNextPage(); +} + +void CPageShow::VerticalPrevPage() +{ + DoPrevPage(); +} + + +void CPageShow::DoNextPage() +{ + m_nCurIndex++; + int nMax = m_ImageList.count() -1; + if(m_bTwoPage) + nMax -= 1; + if(m_nCurIndex >= nMax ) + m_nCurIndex = nMax; + vert_bar->setValue(0); + update(); +} + +void CPageShow::DoPrevPage() +{ + m_nCurIndex--; + if(m_nCurIndex < 0 ) + m_nCurIndex = 0; + vert_bar->setValue(0); + update(); +} + +void CPageShow::DoTwoPage() +{ + m_bTwoPage = !m_bTwoPage; + update(); + +} + +void CPageShow::DoZoomIn() +{ + m_fZoomRate += 0.5; + if(m_fZoomRate > 3.0 ) + m_fZoomRate = 3.0; + update(); + +} + + +void CPageShow::DoZoomOut() +{ + m_fZoomRate -= 0.5; + if(m_fZoomRate < 1.0 ) + m_fZoomRate = 1.0; + update(); +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cpageshow.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cpageshow.h index e762deea..eebaf912 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cpageshow.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cpageshow.h @@ -1,58 +1,58 @@ -#ifndef CPAGESHOW_H_HEADER_INCLUDED -#define CPAGESHOW_H_HEADER_INCLUDED - -#include - -#include -#include -#include -#include -#include -#include "CPrintPreview.h" - -//##ModelId=403405ED00B3 -class CPageShow : public QWidget -{ - Q_OBJECT - -public: - CPageShow(QWidget * parent = 0, Qt::WindowFlags f = 0); - ~CPageShow(); -public: - QGridLayout *grid_layout; - QScrollBar *vert_bar; - QScrollBar *horiz_bar; - - int m_nCurIndex; - bool m_bTwoPage; - float m_fZoomRate; - int m_nOnePageHeight; - - int m_nScrollLeft; - int m_nScrollTop; - - int m_nPageNum; - CPixmapList m_ImageList; - -public: - void draw( QPainter *); - void setPages( const CPixmapList & list ); - void DoNextPage(); - void DoPrevPage(); - void DoTwoPage(); - void DoZoomIn(); - void DoZoomOut(); -public slots: - void HoriztalScrollBarMove(int value); - void VerticalSliderMove(int value); - void VerticalNextPage(); - void VerticalPrevPage(); - -protected: - void mousePressEvent( QMouseEvent * ); - void mouseReleaseEvent( QMouseEvent * ); - void paintEvent( QPaintEvent *); -}; - -#endif /* CPAGESHOW_H_HEADER_INCLUDED */ - +#ifndef CPAGESHOW_H_HEADER_INCLUDED +#define CPAGESHOW_H_HEADER_INCLUDED + +#include + +#include +#include +#include +#include +#include +#include "CPrintPreview.h" + +//##ModelId=403405ED00B3 +class CPageShow : public QWidget +{ + Q_OBJECT + +public: + CPageShow(QWidget * parent = 0, Qt::WindowFlags f = 0); + ~CPageShow(); +public: + QGridLayout *grid_layout; + QScrollBar *vert_bar; + QScrollBar *horiz_bar; + + int m_nCurIndex; + bool m_bTwoPage; + float m_fZoomRate; + int m_nOnePageHeight; + + int m_nScrollLeft; + int m_nScrollTop; + + int m_nPageNum; + CPixmapList m_ImageList; + +public: + void draw( QPainter *); + void setPages( const CPixmapList & list ); + void DoNextPage(); + void DoPrevPage(); + void DoTwoPage(); + void DoZoomIn(); + void DoZoomOut(); +public slots: + void HoriztalScrollBarMove(int value); + void VerticalSliderMove(int value); + void VerticalNextPage(); + void VerticalPrevPage(); + +protected: + void mousePressEvent( QMouseEvent * ); + void mouseReleaseEvent( QMouseEvent * ); + void paintEvent( QPaintEvent *); +}; + +#endif /* CPAGESHOW_H_HEADER_INCLUDED */ + diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cwavedisplay.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cwavedisplay.cpp index 9f5cc227..87b85b20 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cwavedisplay.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/cwavedisplay.cpp @@ -1,557 +1,557 @@ -#include "CComDataClass.h" -#include -////////////////////////////////////////////////////////// -//CWaveDisplay - -QColor CWaveDisplay::m_dwColorArray[COLOR_NUM] = -{ - QColor(0,170,0), QColor(170,0,0), QColor(0,0,170), - QColor(128,128,128), QColor(128,0,128), QColor(0,64,128), - QColor(0,0,64), QColor(0,64,64), QColor(0,0,128) -}; - -// QColor CWaveDisplay::m_dwColorArray1[COLOR_NUM_ANA] = -// { -// QColor(0,170,0),QColor(170,0,0),QColor(0,0,170) -// }; - -// QColor CWaveDisplay::m_dwColorArray2[COLOR_NUM_DGT] = -// { -// QColor(0,170,0),QColor(170,0,0),QColor(0,0,170) -// }; - -QColor CWaveDisplay::m_dwColorArray1[COLOR_NUM_ANA] = -{ - QColor(200,0,0),QColor(0,200,0),QColor(200,200,0) -}; - -QColor CWaveDisplay::m_dwColorArray2[COLOR_NUM_DGT] = -{ - QColor(200,0,0),QColor(0,200,0),QColor(200,200,0) -}; - - -////////////////////////////////////////////////////////////////////////// -CWaveEnv* CWaveEnv::m_pWaveEnvInstance = NULL; -CWaveEnv* CWaveEnv::m_pWaveEnvDefault = NULL; -CWaveEnv::CWaveEnv() -{ - m_bShowWave = true; - m_bShowDigital = true; - m_bShowTimeAxis = true; - - m_bShowTriggerLine = false; - m_bShowBaseLine = true; - m_bShowGrid = false; - m_bShowCompLine = false; - m_bCruise = false; - m_bShowLabel = true; - m_bExtensive = false; - m_bBaseCompute = false; - m_bAnalysisEnable = false; - - m_fZoomXX = 1.0; - m_dWaveZoomYY = 1.0; - m_dTagsZoomYY = 1.0; - m_nLeftMarginName = 300; - m_nTimeViewTop1 = 580; - m_nTimeViewHgt1 = 55; - m_nTagsViewTop1 = 348; - m_nTagsViewHgt1 = 232; - m_nWaveViewTop1 = 0; - m_nWaveViewHgt1 = 348; - m_nMinViewHgt1 = 0; - m_fWaveHeightRate1 = 0.6f; - - m_nBackColorType = 1; - - m_bEndStamp = true; - - m_nLanguage = 0; - m_nDateSetOption = 0; - m_sWaveFilePath = "../../data/rec"; - - QDir dir = QDir::current(); - m_sEnvDir = dir.absolutePath(); - - //Revert(); - ChangeColor(1); -} - -CWaveEnv::~CWaveEnv() -{ - -} - -void CWaveEnv::Revert() -{ - m_WaveBackColor = QColor(10,10,10); - m_WaveForeColor = QColor(0,170,0); - m_TimeBackColor = QColor(10,10,10); - m_TimeForeColor = QColor(255,255,255); - m_NameBackColor = QColor(10,10,10); - m_NameForeColor = QColor(0,170,0); - m_statusBackColor = QColor(10,10,10); - m_statusForeColor = QColor(0,0,128); - m_BaseLineColor = QColor(81,166,189); - m_StaticLineColor = QColor(213,86,13); - m_GridColor = QColor(200,200,200); - m_MiddleColor = QColor(200,200,200); - m_MoveLineColor = QColor(32,32,32); - m_LabelBackColor = QColor(242,223,145); - m_LabelTextColor = QColor(255,128,0); - m_LabelFrameColor = QColor(0,0,0); - m_LabelConnectColor = QColor(255,128,64); -} - -CWaveEnv* CWaveEnv::GetInst() -{ - if( !m_pWaveEnvInstance ) - { - m_pWaveEnvInstance = new CWaveEnv(); - m_pWaveEnvInstance->Load(); - m_pWaveEnvInstance->LoadZoomSet(); - } - return m_pWaveEnvInstance; -} - -CWaveEnv* CWaveEnv::GetDefault() -{ - if( !m_pWaveEnvDefault ) - m_pWaveEnvDefault = new CWaveEnv(); - return m_pWaveEnvDefault; -} - -void CWaveEnv::SetEnvDir( const QString& ed ) -{ - m_sEnvDir = ed; -} - -QString CWaveEnv::EnvDir() -{ - return m_sEnvDir; -} - -void CWaveEnv::ChangeColor(int nType) -{ - m_nBackColorType = nType; - switch(nType) - { - case 1: - { - m_WaveBackColor = QColor(230,237,242); - m_WaveForeColor = QColor(0,170,0); - m_TimeBackColor = QColor(230,237,242); - m_TimeForeColor = QColor(0,0,0); - m_NameBackColor = QColor(230,237,242); - m_NameForeColor = QColor(0,170,0); - m_statusBackColor = QColor(230,237,242); - m_statusForeColor = QColor(0,0,128); - m_BaseLineColor = QColor(81,166,189); - m_StaticLineColor = QColor(213,86,13); - m_GridColor = QColor(200,200,200); - m_MoveLineColor = QColor(32,32,32); - m_LabelBackColor = QColor(242,223,145); - m_LabelTextColor = QColor(255,128,0); - m_LabelFrameColor = QColor(0,0,0); - m_LabelConnectColor = QColor(255,128,64); - break; - } - case 2: - { - m_WaveBackColor = QColor(50,50,50); - m_WaveForeColor = QColor(133,189,194); - m_TimeBackColor = QColor(50,50,50); - m_TimeForeColor = QColor(255,255,255); - m_NameBackColor = QColor(50,50,50); - m_NameForeColor = QColor(133,189,194); - m_statusBackColor = QColor(50,50,50); - m_statusForeColor = QColor(0,0,128); - m_BaseLineColor = QColor(159,154,5); - m_StaticLineColor = QColor(213,86,13); - m_GridColor = QColor(200,200,200); - m_MoveLineColor = QColor(32,32,32); - m_LabelBackColor = QColor(242,223,145); - m_LabelTextColor = QColor(255,128,0); - m_LabelFrameColor = QColor(0,0,0); - m_LabelConnectColor = QColor(255,128,64); - break; - } - case 3: - { - m_WaveBackColor = QColor(90,90,90,0); - m_WaveForeColor = QColor(167,190,227); - m_TimeBackColor = QColor(90,90,90,0); - m_TimeForeColor = QColor(167,190,227); - m_NameBackColor = QColor(90,90,90,0); - m_NameForeColor = QColor(167,190,227); - m_statusBackColor = QColor(90,90,90,0); - m_statusForeColor = QColor(167,190,227); - m_BaseLineColor = QColor(0,200,0); - m_StaticLineColor = QColor(213,86,13); - m_GridColor = QColor(200,200,200,0); - m_MoveLineColor = QColor(20,76,126); - m_LabelBackColor = QColor(242,223,145); - m_LabelTextColor = QColor(255,128,0); - m_LabelFrameColor = QColor(0,0,0); - m_LabelConnectColor = QColor(255,128,64); - break; - } - } -} - -void CWaveEnv::Save() -{ - CSectionList sectlist; - //显示属性 - CInfSection sect1; - sect1.m_sName = "Wave Analysis Toolset"; - sect1.m_sCompany = "SHENZHEN KANGBIDA CONTROL TECHNOLOGY CO.LTD"; - sect1.SetAttribute(QString("ShowWaveZone"),QString::number(m_bShowWave)); - sect1.SetAttribute(QString("ShowDigitalZone"),QString::number(m_bShowDigital)); - sect1.SetAttribute(QString("ShowTimeZone"),QString::number(m_bShowTimeAxis)); - sect1.SetAttribute(QString("ShowLabel"),QString::number(m_bShowLabel)); - sect1.SetAttribute(QString("ShowBaseLine"),QString::number(m_bShowBaseLine)); - sect1.SetAttribute(QString("ShowTriggerLine"),QString::number(m_bShowTriggerLine)); - sect1.SetAttribute(QString("ShowGrid"),QString::number(m_bShowGrid)); - sect1.SetAttribute(QString("ShowVertGrid"),QString::number(m_bShowVertGrid)); - sect1.SetAttribute(QString("ShowCompLine"),QString::number(m_bShowCompLine)); - sect1.SetAttribute(QString("Extensive"),QString::number(m_bExtensive)); - sect1.SetAttribute(QString("AnalysisEnable"),QString::number(m_bAnalysisEnable)); - sect1.SetAttribute(QString("IsEndStamp"),QString::number(m_bEndStamp)); - sect1.SetAttribute(QString("BaseCompute"),QString::number(m_bBaseCompute)); - sect1.SetAttribute(QString("Cruise"),QString::number(m_bCruise)); - sect1.SetAttribute(QString("WaveFilePath"),m_sWaveFilePath); - - sectlist.append(sect1); - - //语言设置 - CInfSection sect2; - sect2.m_sName = "Wave Analysis Toolset"; - sect2.m_sCompany = "Language"; - sect2.SetAttribute(QString("Type"),QString::number(m_nLanguage)); - - sectlist.append(sect2); - - //时间设置 - CInfSection sect3; - sect3.m_sName = "Wave Analysis Toolset"; - sect3.m_sCompany = "DateSet"; - sect3.SetAttribute(QString("DateOption"),QString::number( m_nDateSetOption ) ); - - sectlist.append( sect3 ); - - //颜色属性 - CInfSection sect4; - sect4.m_sName = QString("Wave Analysis Toolset"); - sect4.m_sCompany = QString("ColorSet"); - sect4.SetAttribute(QString("WaveBackColor"),m_WaveBackColor.name()); - sect4.SetAttribute(QString("WaveForeColor"),m_WaveForeColor.name()); - sect4.SetAttribute(QString("MiddleColor"),m_MiddleColor.name()); - sect4.SetAttribute(QString("TimeBackColor"),m_TimeBackColor.name()); - sect4.SetAttribute(QString("TimeForeColor"),m_TimeForeColor.name()); - sect4.SetAttribute(QString("NameBackColor"),m_NameBackColor.name()); - sect4.SetAttribute(QString("NameForeColor"),m_NameForeColor.name()); - sect4.SetAttribute(QString("statusBackColor"),m_statusBackColor.name()); - sect4.SetAttribute(QString("statusForeColor"),m_statusForeColor.name()); - sect4.SetAttribute(QString("GridColor"),m_GridColor.name()); - sect4.SetAttribute(QString("BaseLineColor"),m_BaseLineColor.name()); - sect4.SetAttribute(QString("StaticLineColor"),m_StaticLineColor.name()); - sect4.SetAttribute(QString("MoveLineColor"),m_MoveLineColor.name()); - sect4.SetAttribute(QString("LabelBackColor"),m_LabelBackColor.name()); - sect4.SetAttribute(QString("LabelTextColor"),m_LabelTextColor.name()); - sect4.SetAttribute(QString("LabelFrameColor"),m_LabelFrameColor.name()); - sect4.SetAttribute(QString("LabelConnectColor"),m_LabelConnectColor.name()); - - sectlist.append(sect4); - - QString szFileName = "wavetoolenv.ini"; - QDir dir = QDir::current(); - szFileName = dir.absoluteFilePath(szFileName); - - // lww 20181208 - //CSectionOperate::writeFile(sectlist,szFileName); -} - -void CWaveEnv::SaveZoomSet() -{ - CSectionList sectlist; - - CInfSection sect1; - sect1.m_sName = "WaveEnvTool"; - sect1.m_sCompany = "ZoomSet"; - sect1.SetAttribute( QString("ZoomX"), QString::number(m_fZoomXX,'f',4) ); - sect1.SetAttribute( QString("WaveZoomY"), QString::number(m_dWaveZoomYY,'f',1) ); - sect1.SetAttribute( QString("TagsZoomY"), QString::number(m_dTagsZoomYY,'f',1) ); - sect1.SetAttribute( QString("LeftMargin"), QString::number(m_nLeftMarginName) ); - sect1.SetAttribute( QString("TagsViewTop"), QString::number(m_nTagsViewTop1) ); - sect1.SetAttribute( QString("TagsViewHgt"), QString::number(m_nTagsViewHgt1) ); - sect1.SetAttribute( QString("WaveViewTop"), QString::number(m_nWaveViewTop1) ); - sect1.SetAttribute( QString("WaveViewHgt"), QString::number(m_nWaveViewHgt1) ); - sect1.SetAttribute( QString("TimeViewTop"), QString::number(m_nTimeViewTop1) ); - sect1.SetAttribute( QString("TimeViewHgt"), QString::number(m_nTimeViewHgt1) ); - sect1.SetAttribute( QString("MinViewHgt"), QString::number(m_nMinViewHgt1) ); - sect1.SetAttribute( QString("WaveHeightRate"), QString::number(m_fWaveHeightRate1,'f',1) ); - - sectlist.append(sect1); - - QString szFileName = "WaveEnvSet.ini"; - QDir dir = QDir::current(); - szFileName = dir.absoluteFilePath(szFileName); - - // lww 20181208 - //CSectionOperate::writeFile(sectlist,szFileName); -} - -void CWaveEnv::Load() -{ - QString szFileName = "wavetoolenv.ini"; - QDir dir = QDir::current(); - szFileName = dir.absoluteFilePath(szFileName); - - CSectionList sectlist; - CSectionOperate::ReadFile(sectlist,szFileName); - - if(sectlist.count()<1) - { - Save(); - return; - } - - int nIndex = -1; - //显示属性 - nIndex = CSectionOperate::GetSection(sectlist,QString("WaveToolEnv"),QString("SHENZHEN KANGBIDA CONTROL TECHNOLOGY CO.LTD")); - if(nIndex<0) return; - CInfSection& sect1 = sectlist[nIndex]; - - m_bShowWave = (bool)sect1.GetAttribute(QString("ShowWaveZone"),QString("1")).toInt(); - m_bShowDigital = (bool)sect1.GetAttribute(QString("ShowDigitalZone"),QString("1")).toInt(); - m_bShowTimeAxis = (bool)sect1.GetAttribute(QString("ShowTimeZone"),QString("1")).toInt(); - m_bShowLabel = (bool)sect1.GetAttribute(QString("ShowLabel"),QString("0")).toInt(); - - m_bShowBaseLine = (bool)sect1.GetAttribute(QString("ShowBaseLine"),QString("1")).toInt(); - m_bShowTriggerLine = (bool)sect1.GetAttribute(QString("ShowTriggerLine"),QString("0")).toInt(); - m_bShowGrid = (bool)sect1.GetAttribute(QString("ShowGrid"),QString("0")).toInt(); - m_bShowVertGrid = (bool)sect1.GetAttribute(QString("ShowVertGrid"),QString("0")).toInt(); - m_bShowCompLine = (bool)sect1.GetAttribute(QString("ShowCompLine"),QString("0")).toInt(); - - m_bExtensive = (bool)sect1.GetAttribute(QString("Extensive"),QString("0")).toInt(); - m_bAnalysisEnable = (bool)sect1.GetAttribute(QString("AnalysisEnable"),QString("0")).toInt(); - m_bEndStamp = (bool)sect1.GetAttribute(QString("IsEndStamp"),QString("1")).toInt(); - m_bBaseCompute = (bool)sect1.GetAttribute(QString("BaseCompute"),QString("0")).toInt(); - m_bCruise = (bool)sect1.GetAttribute(QString("Cruise"),QString("0")).toInt(); - m_sWaveFilePath = sect1.GetAttribute(QString("WaveFilePath"),""); - - //语言属性 - nIndex = CSectionOperate::GetSection(sectlist,QString("WaveToolEnv"),QString("Language")); - if(nIndex<0) return; - CInfSection& sect2 = sectlist[nIndex]; - m_nLanguage = sect2.GetAttribute(QString("Type"),QString("0")).toInt(); - - //时间设置 - nIndex = CSectionOperate::GetSection(sectlist,QString("WaveToolEnv"),QString("DateSet")); - if(nIndex<0) return; - CInfSection& sect3 = sectlist[nIndex]; - m_nDateSetOption = sect3.GetAttribute(QString("DateOption"),QString("0")).toInt(); - //颜色 - nIndex = CSectionOperate::GetSection(sectlist,QString("WaveToolEnv"),QString("ColorSet")); - if(nIndex<0) return; - CInfSection sect4 = sectlist[nIndex]; - m_WaveBackColor = QColor(sect4.GetAttribute(QString("WaveBackColor"),m_WaveBackColor.name())); - m_WaveForeColor = QColor(sect4.GetAttribute(QString("WaveForeColor"),m_WaveForeColor.name())); - - m_MiddleColor = QColor(sect4.GetAttribute(QString("SectionColor"),m_MiddleColor.name())); - - m_TimeBackColor = QColor(sect4.GetAttribute(QString("TimeBackColor"),m_TimeBackColor.name())); - m_TimeForeColor = QColor(sect4.GetAttribute(QString("TimeForeColor"),m_TimeForeColor.name())); - - m_NameBackColor = QColor(sect4.GetAttribute(QString("NameBackColor"),m_NameBackColor.name())); - m_NameForeColor = QColor(sect4.GetAttribute(QString("NameForeColor"),m_NameForeColor.name())); - - m_statusBackColor = QColor(sect4.GetAttribute(QString("statusBackColor"),m_statusBackColor.name())); - m_statusForeColor = QColor(sect4.GetAttribute(QString("statusForeColor"),m_statusForeColor.name())); - - m_GridColor = QColor(sect4.GetAttribute(QString("GridColor"),m_GridColor.name())); - - m_BaseLineColor = QColor(sect4.GetAttribute(QString("BaseLineColor"),m_BaseLineColor.name())); - m_StaticLineColor = QColor(sect4.GetAttribute(QString("StaticLineColor"),m_StaticLineColor.name())); - m_MoveLineColor = QColor(sect4.GetAttribute(QString("MoveLineColor"),m_MoveLineColor.name())); - - m_LabelBackColor = QColor(sect4.GetAttribute(QString("LabelBackColor"),m_LabelBackColor.name())); - m_LabelTextColor = QColor(sect4.GetAttribute(QString("LabelTextColor"),m_LabelTextColor.name())); - m_LabelFrameColor = QColor(sect4.GetAttribute(QString("LabelFrameColor"),m_LabelFrameColor.name())); - m_LabelConnectColor = QColor(sect4.GetAttribute(QString("LabelConnectColor"),m_LabelConnectColor.name())); - -} - -void CWaveEnv::LoadZoomSet() -{ - QString szFileName = "WaveEnvSet.ini"; - QDir dir = QDir::current(); - szFileName = dir.absoluteFilePath(szFileName); - - CSectionList sectlist; - CSectionOperate::ReadFile(sectlist,szFileName); - - if(sectlist.count()<1) - { - //Save(); - m_fZoomXX = 1.0; - m_dWaveZoomYY = 1.0; - m_dTagsZoomYY =1.0; - m_nLeftMarginName = 300; - SaveZoomSet(); - return; - } - - int nIndex = -1; - //显示属性 - nIndex = CSectionOperate::GetSection(sectlist,QString("WaveEnvTool"),QString("ZoomSet")); - if(nIndex<0) return; - CInfSection& sect1 = sectlist[nIndex]; - m_fZoomXX = (double)sect1.GetAttribute(QString("ZoomX"),QString("1.0")).toDouble(); - m_dWaveZoomYY = (double)sect1.GetAttribute(QString("WaveZoomY"),QString("1.0")).toDouble(); - m_dTagsZoomYY = (double)sect1.GetAttribute(QString("TagsZoomY"),QString("1.0")).toDouble(); - m_nLeftMarginName = (int)sect1.GetAttribute(QString("LeftMargin"),QString("300")).toInt(); - m_nTagsViewTop1 = (int)sect1.GetAttribute(QString("TagsViewTop"),QString("348")).toInt(); - m_nTagsViewHgt1 = (int)sect1.GetAttribute(QString("TagsViewHgt"),QString("232")).toInt(); - m_nWaveViewTop1 = (int)sect1.GetAttribute(QString("WaveViewTop"),QString("0")).toInt(); - m_nWaveViewHgt1 = (int)sect1.GetAttribute(QString("WaveViewHgt"),QString("348")).toInt(); - m_nTimeViewTop1 = (int)sect1.GetAttribute(QString("TimeViewTop"),QString("580")).toInt(); - m_nTimeViewHgt1 = (int)sect1.GetAttribute(QString("TimeViewHgt"),QString("55")).toInt(); - m_nMinViewHgt1 = (int)sect1.GetAttribute(QString("MinViewHgt"),QString("0")).toInt(); - m_fWaveHeightRate1 = (int)sect1.GetAttribute(QString("WaveHeightRate"),QString("0.6")).toDouble(); -} - -////////////////////////////////////////////////////////////////////////// -CWaveDisplay::CWaveDisplay() -{ - m_dGridWidth = 2.0; - m_dGridHeight = 50.0; - m_dTimeHeight = 30.0; - m_dTagsHeight = 20.0; - //m_fZoomX = 1.0; - m_fZoomX = CWaveEnv::GetInst()->m_fZoomXX; - if(m_fZoomX == 0.0 ) - m_fZoomX = 1.0; - //m_dWaveZoomY1 = 1.0; - m_dWaveZoomY1 = CWaveEnv::GetInst()->m_dWaveZoomYY; - if(m_dWaveZoomY1 == 0.0) - m_dWaveZoomY1 = 1.0; - //m_dTagsZoomY1 = 1.0; - m_dTagsZoomY1 = CWaveEnv::GetInst()->m_dTagsZoomYY; - if(m_dTagsZoomY1 == 0.0) - m_dTagsZoomY1 = 1.0; - m_nLeftMargin = CWaveEnv::GetInst()->m_nLeftMarginName; - if(m_nLeftMargin == 0) - m_nLeftMargin = 300; - //波形区标尺宽度,20090821 - m_nLeftWaveAxis = 80; - - m_dGridTime = 100.0; - - m_byValueType = VAL_SECONDARY; - - m_bShowZoon = false; - m_fBaseTime = 0.0; - - m_fStaticTime = 0.0; - m_fTriggerTime = 0.0; - m_fCurrentTime = 0.0; - - m_fBaseTick = 0.0; - m_fStaticTick = 0.0; - m_fCurrentTick = 0.0; - - m_nNameHeight = 18; - - m_nTagShowType = TAG_SHOWACTION; - m_DefaultWaveColor = QColor(170,0,255); - - int i; - for( i=0; i +////////////////////////////////////////////////////////// +//CWaveDisplay + +QColor CWaveDisplay::m_dwColorArray[COLOR_NUM] = +{ + QColor(0,170,0), QColor(170,0,0), QColor(0,0,170), + QColor(128,128,128), QColor(128,0,128), QColor(0,64,128), + QColor(0,0,64), QColor(0,64,64), QColor(0,0,128) +}; + +// QColor CWaveDisplay::m_dwColorArray1[COLOR_NUM_ANA] = +// { +// QColor(0,170,0),QColor(170,0,0),QColor(0,0,170) +// }; + +// QColor CWaveDisplay::m_dwColorArray2[COLOR_NUM_DGT] = +// { +// QColor(0,170,0),QColor(170,0,0),QColor(0,0,170) +// }; + +QColor CWaveDisplay::m_dwColorArray1[COLOR_NUM_ANA] = +{ + QColor(200,0,0),QColor(0,200,0),QColor(200,200,0) +}; + +QColor CWaveDisplay::m_dwColorArray2[COLOR_NUM_DGT] = +{ + QColor(200,0,0),QColor(0,200,0),QColor(200,200,0) +}; + + +////////////////////////////////////////////////////////////////////////// +CWaveEnv* CWaveEnv::m_pWaveEnvInstance = NULL; +CWaveEnv* CWaveEnv::m_pWaveEnvDefault = NULL; +CWaveEnv::CWaveEnv() +{ + m_bShowWave = true; + m_bShowDigital = true; + m_bShowTimeAxis = true; + + m_bShowTriggerLine = false; + m_bShowBaseLine = true; + m_bShowGrid = false; + m_bShowCompLine = false; + m_bCruise = false; + m_bShowLabel = true; + m_bExtensive = false; + m_bBaseCompute = false; + m_bAnalysisEnable = false; + + m_fZoomXX = 1.0; + m_dWaveZoomYY = 1.0; + m_dTagsZoomYY = 1.0; + m_nLeftMarginName = 300; + m_nTimeViewTop1 = 580; + m_nTimeViewHgt1 = 55; + m_nTagsViewTop1 = 348; + m_nTagsViewHgt1 = 232; + m_nWaveViewTop1 = 0; + m_nWaveViewHgt1 = 348; + m_nMinViewHgt1 = 0; + m_fWaveHeightRate1 = 0.6f; + + m_nBackColorType = 1; + + m_bEndStamp = true; + + m_nLanguage = 0; + m_nDateSetOption = 0; + m_sWaveFilePath = "../../data/rec"; + + QDir dir = QDir::current(); + m_sEnvDir = dir.absolutePath(); + + //Revert(); + ChangeColor(1); +} + +CWaveEnv::~CWaveEnv() +{ + +} + +void CWaveEnv::Revert() +{ + m_WaveBackColor = QColor(10,10,10); + m_WaveForeColor = QColor(0,170,0); + m_TimeBackColor = QColor(10,10,10); + m_TimeForeColor = QColor(255,255,255); + m_NameBackColor = QColor(10,10,10); + m_NameForeColor = QColor(0,170,0); + m_statusBackColor = QColor(10,10,10); + m_statusForeColor = QColor(0,0,128); + m_BaseLineColor = QColor(81,166,189); + m_StaticLineColor = QColor(213,86,13); + m_GridColor = QColor(200,200,200); + m_MiddleColor = QColor(200,200,200); + m_MoveLineColor = QColor(32,32,32); + m_LabelBackColor = QColor(242,223,145); + m_LabelTextColor = QColor(255,128,0); + m_LabelFrameColor = QColor(0,0,0); + m_LabelConnectColor = QColor(255,128,64); +} + +CWaveEnv* CWaveEnv::GetInst() +{ + if( !m_pWaveEnvInstance ) + { + m_pWaveEnvInstance = new CWaveEnv(); + m_pWaveEnvInstance->Load(); + m_pWaveEnvInstance->LoadZoomSet(); + } + return m_pWaveEnvInstance; +} + +CWaveEnv* CWaveEnv::GetDefault() +{ + if( !m_pWaveEnvDefault ) + m_pWaveEnvDefault = new CWaveEnv(); + return m_pWaveEnvDefault; +} + +void CWaveEnv::SetEnvDir( const QString& ed ) +{ + m_sEnvDir = ed; +} + +QString CWaveEnv::EnvDir() +{ + return m_sEnvDir; +} + +void CWaveEnv::ChangeColor(int nType) +{ + m_nBackColorType = nType; + switch(nType) + { + case 1: + { + m_WaveBackColor = QColor(230,237,242); + m_WaveForeColor = QColor(0,170,0); + m_TimeBackColor = QColor(230,237,242); + m_TimeForeColor = QColor(0,0,0); + m_NameBackColor = QColor(230,237,242); + m_NameForeColor = QColor(0,170,0); + m_statusBackColor = QColor(230,237,242); + m_statusForeColor = QColor(0,0,128); + m_BaseLineColor = QColor(81,166,189); + m_StaticLineColor = QColor(213,86,13); + m_GridColor = QColor(200,200,200); + m_MoveLineColor = QColor(32,32,32); + m_LabelBackColor = QColor(242,223,145); + m_LabelTextColor = QColor(255,128,0); + m_LabelFrameColor = QColor(0,0,0); + m_LabelConnectColor = QColor(255,128,64); + break; + } + case 2: + { + m_WaveBackColor = QColor(50,50,50); + m_WaveForeColor = QColor(133,189,194); + m_TimeBackColor = QColor(50,50,50); + m_TimeForeColor = QColor(255,255,255); + m_NameBackColor = QColor(50,50,50); + m_NameForeColor = QColor(133,189,194); + m_statusBackColor = QColor(50,50,50); + m_statusForeColor = QColor(0,0,128); + m_BaseLineColor = QColor(159,154,5); + m_StaticLineColor = QColor(213,86,13); + m_GridColor = QColor(200,200,200); + m_MoveLineColor = QColor(32,32,32); + m_LabelBackColor = QColor(242,223,145); + m_LabelTextColor = QColor(255,128,0); + m_LabelFrameColor = QColor(0,0,0); + m_LabelConnectColor = QColor(255,128,64); + break; + } + case 3: + { + m_WaveBackColor = QColor(90,90,90,0); + m_WaveForeColor = QColor(167,190,227); + m_TimeBackColor = QColor(90,90,90,0); + m_TimeForeColor = QColor(167,190,227); + m_NameBackColor = QColor(90,90,90,0); + m_NameForeColor = QColor(167,190,227); + m_statusBackColor = QColor(90,90,90,0); + m_statusForeColor = QColor(167,190,227); + m_BaseLineColor = QColor(0,200,0); + m_StaticLineColor = QColor(213,86,13); + m_GridColor = QColor(200,200,200,0); + m_MoveLineColor = QColor(20,76,126); + m_LabelBackColor = QColor(242,223,145); + m_LabelTextColor = QColor(255,128,0); + m_LabelFrameColor = QColor(0,0,0); + m_LabelConnectColor = QColor(255,128,64); + break; + } + } +} + +void CWaveEnv::Save() +{ + CSectionList sectlist; + //显示属性 + CInfSection sect1; + sect1.m_sName = "Wave Analysis Toolset"; + sect1.m_sCompany = "SHENZHEN KANGBIDA CONTROL TECHNOLOGY CO.LTD"; + sect1.SetAttribute(QString("ShowWaveZone"),QString::number(m_bShowWave)); + sect1.SetAttribute(QString("ShowDigitalZone"),QString::number(m_bShowDigital)); + sect1.SetAttribute(QString("ShowTimeZone"),QString::number(m_bShowTimeAxis)); + sect1.SetAttribute(QString("ShowLabel"),QString::number(m_bShowLabel)); + sect1.SetAttribute(QString("ShowBaseLine"),QString::number(m_bShowBaseLine)); + sect1.SetAttribute(QString("ShowTriggerLine"),QString::number(m_bShowTriggerLine)); + sect1.SetAttribute(QString("ShowGrid"),QString::number(m_bShowGrid)); + sect1.SetAttribute(QString("ShowVertGrid"),QString::number(m_bShowVertGrid)); + sect1.SetAttribute(QString("ShowCompLine"),QString::number(m_bShowCompLine)); + sect1.SetAttribute(QString("Extensive"),QString::number(m_bExtensive)); + sect1.SetAttribute(QString("AnalysisEnable"),QString::number(m_bAnalysisEnable)); + sect1.SetAttribute(QString("IsEndStamp"),QString::number(m_bEndStamp)); + sect1.SetAttribute(QString("BaseCompute"),QString::number(m_bBaseCompute)); + sect1.SetAttribute(QString("Cruise"),QString::number(m_bCruise)); + sect1.SetAttribute(QString("WaveFilePath"),m_sWaveFilePath); + + sectlist.append(sect1); + + //语言设置 + CInfSection sect2; + sect2.m_sName = "Wave Analysis Toolset"; + sect2.m_sCompany = "Language"; + sect2.SetAttribute(QString("Type"),QString::number(m_nLanguage)); + + sectlist.append(sect2); + + //时间设置 + CInfSection sect3; + sect3.m_sName = "Wave Analysis Toolset"; + sect3.m_sCompany = "DateSet"; + sect3.SetAttribute(QString("DateOption"),QString::number( m_nDateSetOption ) ); + + sectlist.append( sect3 ); + + //颜色属性 + CInfSection sect4; + sect4.m_sName = QString("Wave Analysis Toolset"); + sect4.m_sCompany = QString("ColorSet"); + sect4.SetAttribute(QString("WaveBackColor"),m_WaveBackColor.name()); + sect4.SetAttribute(QString("WaveForeColor"),m_WaveForeColor.name()); + sect4.SetAttribute(QString("MiddleColor"),m_MiddleColor.name()); + sect4.SetAttribute(QString("TimeBackColor"),m_TimeBackColor.name()); + sect4.SetAttribute(QString("TimeForeColor"),m_TimeForeColor.name()); + sect4.SetAttribute(QString("NameBackColor"),m_NameBackColor.name()); + sect4.SetAttribute(QString("NameForeColor"),m_NameForeColor.name()); + sect4.SetAttribute(QString("statusBackColor"),m_statusBackColor.name()); + sect4.SetAttribute(QString("statusForeColor"),m_statusForeColor.name()); + sect4.SetAttribute(QString("GridColor"),m_GridColor.name()); + sect4.SetAttribute(QString("BaseLineColor"),m_BaseLineColor.name()); + sect4.SetAttribute(QString("StaticLineColor"),m_StaticLineColor.name()); + sect4.SetAttribute(QString("MoveLineColor"),m_MoveLineColor.name()); + sect4.SetAttribute(QString("LabelBackColor"),m_LabelBackColor.name()); + sect4.SetAttribute(QString("LabelTextColor"),m_LabelTextColor.name()); + sect4.SetAttribute(QString("LabelFrameColor"),m_LabelFrameColor.name()); + sect4.SetAttribute(QString("LabelConnectColor"),m_LabelConnectColor.name()); + + sectlist.append(sect4); + + QString szFileName = "wavetoolenv.ini"; + QDir dir = QDir::current(); + szFileName = dir.absoluteFilePath(szFileName); + + // lww 20181208 + //CSectionOperate::writeFile(sectlist,szFileName); +} + +void CWaveEnv::SaveZoomSet() +{ + CSectionList sectlist; + + CInfSection sect1; + sect1.m_sName = "WaveEnvTool"; + sect1.m_sCompany = "ZoomSet"; + sect1.SetAttribute( QString("ZoomX"), QString::number(m_fZoomXX,'f',4) ); + sect1.SetAttribute( QString("WaveZoomY"), QString::number(m_dWaveZoomYY,'f',1) ); + sect1.SetAttribute( QString("TagsZoomY"), QString::number(m_dTagsZoomYY,'f',1) ); + sect1.SetAttribute( QString("LeftMargin"), QString::number(m_nLeftMarginName) ); + sect1.SetAttribute( QString("TagsViewTop"), QString::number(m_nTagsViewTop1) ); + sect1.SetAttribute( QString("TagsViewHgt"), QString::number(m_nTagsViewHgt1) ); + sect1.SetAttribute( QString("WaveViewTop"), QString::number(m_nWaveViewTop1) ); + sect1.SetAttribute( QString("WaveViewHgt"), QString::number(m_nWaveViewHgt1) ); + sect1.SetAttribute( QString("TimeViewTop"), QString::number(m_nTimeViewTop1) ); + sect1.SetAttribute( QString("TimeViewHgt"), QString::number(m_nTimeViewHgt1) ); + sect1.SetAttribute( QString("MinViewHgt"), QString::number(m_nMinViewHgt1) ); + sect1.SetAttribute( QString("WaveHeightRate"), QString::number(m_fWaveHeightRate1,'f',1) ); + + sectlist.append(sect1); + + QString szFileName = "WaveEnvSet.ini"; + QDir dir = QDir::current(); + szFileName = dir.absoluteFilePath(szFileName); + + // lww 20181208 + //CSectionOperate::writeFile(sectlist,szFileName); +} + +void CWaveEnv::Load() +{ + QString szFileName = "wavetoolenv.ini"; + QDir dir = QDir::current(); + szFileName = dir.absoluteFilePath(szFileName); + + CSectionList sectlist; + CSectionOperate::ReadFile(sectlist,szFileName); + + if(sectlist.count()<1) + { + Save(); + return; + } + + int nIndex = -1; + //显示属性 + nIndex = CSectionOperate::GetSection(sectlist,QString("WaveToolEnv"),QString("SHENZHEN KANGBIDA CONTROL TECHNOLOGY CO.LTD")); + if(nIndex<0) return; + CInfSection& sect1 = sectlist[nIndex]; + + m_bShowWave = (bool)sect1.GetAttribute(QString("ShowWaveZone"),QString("1")).toInt(); + m_bShowDigital = (bool)sect1.GetAttribute(QString("ShowDigitalZone"),QString("1")).toInt(); + m_bShowTimeAxis = (bool)sect1.GetAttribute(QString("ShowTimeZone"),QString("1")).toInt(); + m_bShowLabel = (bool)sect1.GetAttribute(QString("ShowLabel"),QString("0")).toInt(); + + m_bShowBaseLine = (bool)sect1.GetAttribute(QString("ShowBaseLine"),QString("1")).toInt(); + m_bShowTriggerLine = (bool)sect1.GetAttribute(QString("ShowTriggerLine"),QString("0")).toInt(); + m_bShowGrid = (bool)sect1.GetAttribute(QString("ShowGrid"),QString("0")).toInt(); + m_bShowVertGrid = (bool)sect1.GetAttribute(QString("ShowVertGrid"),QString("0")).toInt(); + m_bShowCompLine = (bool)sect1.GetAttribute(QString("ShowCompLine"),QString("0")).toInt(); + + m_bExtensive = (bool)sect1.GetAttribute(QString("Extensive"),QString("0")).toInt(); + m_bAnalysisEnable = (bool)sect1.GetAttribute(QString("AnalysisEnable"),QString("0")).toInt(); + m_bEndStamp = (bool)sect1.GetAttribute(QString("IsEndStamp"),QString("1")).toInt(); + m_bBaseCompute = (bool)sect1.GetAttribute(QString("BaseCompute"),QString("0")).toInt(); + m_bCruise = (bool)sect1.GetAttribute(QString("Cruise"),QString("0")).toInt(); + m_sWaveFilePath = sect1.GetAttribute(QString("WaveFilePath"),""); + + //语言属性 + nIndex = CSectionOperate::GetSection(sectlist,QString("WaveToolEnv"),QString("Language")); + if(nIndex<0) return; + CInfSection& sect2 = sectlist[nIndex]; + m_nLanguage = sect2.GetAttribute(QString("Type"),QString("0")).toInt(); + + //时间设置 + nIndex = CSectionOperate::GetSection(sectlist,QString("WaveToolEnv"),QString("DateSet")); + if(nIndex<0) return; + CInfSection& sect3 = sectlist[nIndex]; + m_nDateSetOption = sect3.GetAttribute(QString("DateOption"),QString("0")).toInt(); + //颜色 + nIndex = CSectionOperate::GetSection(sectlist,QString("WaveToolEnv"),QString("ColorSet")); + if(nIndex<0) return; + CInfSection sect4 = sectlist[nIndex]; + m_WaveBackColor = QColor(sect4.GetAttribute(QString("WaveBackColor"),m_WaveBackColor.name())); + m_WaveForeColor = QColor(sect4.GetAttribute(QString("WaveForeColor"),m_WaveForeColor.name())); + + m_MiddleColor = QColor(sect4.GetAttribute(QString("SectionColor"),m_MiddleColor.name())); + + m_TimeBackColor = QColor(sect4.GetAttribute(QString("TimeBackColor"),m_TimeBackColor.name())); + m_TimeForeColor = QColor(sect4.GetAttribute(QString("TimeForeColor"),m_TimeForeColor.name())); + + m_NameBackColor = QColor(sect4.GetAttribute(QString("NameBackColor"),m_NameBackColor.name())); + m_NameForeColor = QColor(sect4.GetAttribute(QString("NameForeColor"),m_NameForeColor.name())); + + m_statusBackColor = QColor(sect4.GetAttribute(QString("statusBackColor"),m_statusBackColor.name())); + m_statusForeColor = QColor(sect4.GetAttribute(QString("statusForeColor"),m_statusForeColor.name())); + + m_GridColor = QColor(sect4.GetAttribute(QString("GridColor"),m_GridColor.name())); + + m_BaseLineColor = QColor(sect4.GetAttribute(QString("BaseLineColor"),m_BaseLineColor.name())); + m_StaticLineColor = QColor(sect4.GetAttribute(QString("StaticLineColor"),m_StaticLineColor.name())); + m_MoveLineColor = QColor(sect4.GetAttribute(QString("MoveLineColor"),m_MoveLineColor.name())); + + m_LabelBackColor = QColor(sect4.GetAttribute(QString("LabelBackColor"),m_LabelBackColor.name())); + m_LabelTextColor = QColor(sect4.GetAttribute(QString("LabelTextColor"),m_LabelTextColor.name())); + m_LabelFrameColor = QColor(sect4.GetAttribute(QString("LabelFrameColor"),m_LabelFrameColor.name())); + m_LabelConnectColor = QColor(sect4.GetAttribute(QString("LabelConnectColor"),m_LabelConnectColor.name())); + +} + +void CWaveEnv::LoadZoomSet() +{ + QString szFileName = "WaveEnvSet.ini"; + QDir dir = QDir::current(); + szFileName = dir.absoluteFilePath(szFileName); + + CSectionList sectlist; + CSectionOperate::ReadFile(sectlist,szFileName); + + if(sectlist.count()<1) + { + //Save(); + m_fZoomXX = 1.0; + m_dWaveZoomYY = 1.0; + m_dTagsZoomYY =1.0; + m_nLeftMarginName = 300; + SaveZoomSet(); + return; + } + + int nIndex = -1; + //显示属性 + nIndex = CSectionOperate::GetSection(sectlist,QString("WaveEnvTool"),QString("ZoomSet")); + if(nIndex<0) return; + CInfSection& sect1 = sectlist[nIndex]; + m_fZoomXX = (double)sect1.GetAttribute(QString("ZoomX"),QString("1.0")).toDouble(); + m_dWaveZoomYY = (double)sect1.GetAttribute(QString("WaveZoomY"),QString("1.0")).toDouble(); + m_dTagsZoomYY = (double)sect1.GetAttribute(QString("TagsZoomY"),QString("1.0")).toDouble(); + m_nLeftMarginName = (int)sect1.GetAttribute(QString("LeftMargin"),QString("300")).toInt(); + m_nTagsViewTop1 = (int)sect1.GetAttribute(QString("TagsViewTop"),QString("348")).toInt(); + m_nTagsViewHgt1 = (int)sect1.GetAttribute(QString("TagsViewHgt"),QString("232")).toInt(); + m_nWaveViewTop1 = (int)sect1.GetAttribute(QString("WaveViewTop"),QString("0")).toInt(); + m_nWaveViewHgt1 = (int)sect1.GetAttribute(QString("WaveViewHgt"),QString("348")).toInt(); + m_nTimeViewTop1 = (int)sect1.GetAttribute(QString("TimeViewTop"),QString("580")).toInt(); + m_nTimeViewHgt1 = (int)sect1.GetAttribute(QString("TimeViewHgt"),QString("55")).toInt(); + m_nMinViewHgt1 = (int)sect1.GetAttribute(QString("MinViewHgt"),QString("0")).toInt(); + m_fWaveHeightRate1 = (int)sect1.GetAttribute(QString("WaveHeightRate"),QString("0.6")).toDouble(); +} + +////////////////////////////////////////////////////////////////////////// +CWaveDisplay::CWaveDisplay() +{ + m_dGridWidth = 2.0; + m_dGridHeight = 50.0; + m_dTimeHeight = 30.0; + m_dTagsHeight = 20.0; + //m_fZoomX = 1.0; + m_fZoomX = CWaveEnv::GetInst()->m_fZoomXX; + if(m_fZoomX == 0.0 ) + m_fZoomX = 1.0; + //m_dWaveZoomY1 = 1.0; + m_dWaveZoomY1 = CWaveEnv::GetInst()->m_dWaveZoomYY; + if(m_dWaveZoomY1 == 0.0) + m_dWaveZoomY1 = 1.0; + //m_dTagsZoomY1 = 1.0; + m_dTagsZoomY1 = CWaveEnv::GetInst()->m_dTagsZoomYY; + if(m_dTagsZoomY1 == 0.0) + m_dTagsZoomY1 = 1.0; + m_nLeftMargin = CWaveEnv::GetInst()->m_nLeftMarginName; + if(m_nLeftMargin == 0) + m_nLeftMargin = 300; + //波形区标尺宽度,20090821 + m_nLeftWaveAxis = 80; + + m_dGridTime = 100.0; + + m_byValueType = VAL_SECONDARY; + + m_bShowZoon = false; + m_fBaseTime = 0.0; + + m_fStaticTime = 0.0; + m_fTriggerTime = 0.0; + m_fCurrentTime = 0.0; + + m_fBaseTick = 0.0; + m_fStaticTick = 0.0; + m_fCurrentTick = 0.0; + + m_nNameHeight = 18; + + m_nTagShowType = TAG_SHOWACTION; + m_DefaultWaveColor = QColor(170,0,255); + + int i; + for( i=0; i -#include -#include - -//datatype -//#ifndef WIN32 - -typedef unsigned long DWORD; -#ifndef PREFIXTYPE -typedef unsigned int WORD; -#endif - -//#endif -typedef unsigned char byte; - -#ifndef _TIME_T_DEFINED -typedef long time_t; /* time value */ -#define _TIME_T_DEFINED /* avoid multiple def's of time_t */ -#endif - -#ifdef WIN32 -#define M_PI 3.141592653590 -#define M_SQRT2 1.414213562373 -#endif -#define M_SQRT3P2 0.8660254 //二分之根号3 -//data -#define MAKEWORD(a, b) ((WORD)(((byte)(a)) | ((WORD)((byte)(b))) << 8)) -#define MAKELONG(a, b) ((long)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16)) -#define LOWORD(l) ((WORD)(l)) -#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) -#define LOBYTE(w) ((byte)(w)) -#define HIBYTE(w) ((byte)(((WORD)(w) >> 8) & 0xFF)) - -//color -#define LLGRAY_COLOR QColor(224,224,224) -#define LGRAY_COLOR QColor(192,192,192) -#define DGRAY_COLOR QColor(128,128,128) -#define DRED_COLOR QColor(64,0,0) -#define RED_COLOR QColor(255,0,0) -#define BLUE_COLOR QColor(0,0,128) -#define BLACK_COLOR QColor(0,0,0) -#define WHITE_COLOR QColor(255,255,255) -#define LCYAN_COLOR QColor(0,255,255) -//wave type -#define CHN_NO_ATTR 0// 无属性 -#define CHN_RIA_ATTR 51// A相电流瞬时值 -#define CHN_RIB_ATTR 52// B相电流瞬时值 -#define CHN_RIC_ATTR 53// C相电流瞬时值 -#define CHN_RUA_ATTR 54// A相电压瞬时值 -#define CHN_RUB_ATTR 55// B相电压瞬时值 -#define CHN_RUC_ATTR 56// C相电压瞬时值 -// -#define CHN_EIA_ATTR 101// A相电流有效值 -#define CHN_EIB_ATTR 102// B相电流有效值 -#define CHN_EIC_ATTR 103// C相电流有效值 -#define CHN_EUA_ATTR 104// A相电压有效值 -#define CHN_EUB_ATTR 105// B相电压有效值 -#define CHN_EUC_ATTR 106// C相电压有效值 -#define CHN_AIA_ATTR 111// A相电流角度 -#define CHN_AIB_ATTR 112// B相电流角度 -#define CHN_AIC_ATTR 113// C相电流角度 -#define CHN_AUA_ATTR 114// A相电压角度 -#define CHN_AUB_ATTR 115// B相电压角度 -#define CHN_AUC_ATTR 116// C相电压角度 -#define CHN_RI0_ATTR 121// 零序电流瞬时值 -#define CHN_RIP_ATTR 122// 正序电流瞬时值 -#define CHN_RIN_ATTR 123// 负序电流瞬时值 -#define CHN_RU0_ATTR 124// 零序电压瞬时值 -#define CHN_RUP_ATTR 125// 正序电压瞬时值 -#define CHN_RUN_ATTR 126// 负序电压瞬时值 -// -#define CHN_P_ATTR 140// 有功功率 -#define CHN_Q_ATTR 141// 无功功率 -#define CHN_S_ATTR 142// 视在功率 -#define CHN_RATE_ATTR 143// 功率因数 -// -#define CHN_RESIST_ATTR 150// 电阻 -#define CHN_REACT_ATTR 151// 电抗 -// -#define CHN_AMP0_ATTR 200// 0次谐波幅值 -#define CHN_AMP1_ATTR 201// 1-99次谐波幅值 -#define CHN_AMP99_ATTR 299// 1-99次谐波幅值 -#define CHN_RVAL0_ATTR 300// 0次谐波瞬时值 -#define CHN_RVAL1_ATTR 301// 1-99次谐波瞬时值 -#define CHN_RVAL99_ATTR 399// 1-99次谐波瞬时值 -//{{liuzp add 2009-07-28 -#define CHN_REAL0_ATTR 400// 0次谐波实部值 -#define CHN_REAL1_ATTR 401// 1次谐波实部值 -#define CHN_REAL99_ATTR 499// 99次谐波实部值 -#define CHN_IMG0_ATTR 500// 0次谐波虚部值 -#define CHN_IMG1_ATTR 501// 1次谐波虚部值 -#define CHN_IMG99_ATTR 599// 99次谐波虚部值 -#define CHN_ANG0_ATTR 600// 0次谐波角度 -#define CHN_ANG1_ATTR 601// 1次谐波角度 -#define CHN_ANG99_ATTR 699// 99次谐波角度 -#define CHN_EFCT0_ATTR 700// 0次谐波有效值 -#define CHN_EFCT1_ATTR 701// 1次谐波有效值 -#define CHN_EFCT99_ATTR 799// 99次谐波有效值 -//}} -// - -#define UNIT_NO 0 -#define UNIT_KV 10 -#define UNIT_V 11 -#define UNIT_KA 12 -#define UNIT_A 13 -#define UNIT_KW 14 -#define UNIT_W 15 -#define UNIT_VA 16 -#define UNIT_KVA 17 -#define UNIT_Var 18 -#define UNIT_KVar 19 -#define UNIT_ANG 20 - -#define MIN_RULER 2.0//电压电流等最小初始刻度 -#define KUNIT_1 1.0//1 kv(ka,kw)与v(a,w)的转换 -#define UNIT_1000 1000.0//1000.0 - -#define SQUART2 1.414213562373 -//zoom rate -#define TIME_RATE 0.1 -#define AMP_RATE 0.1 -#define MAX_PAGES 8 -class QDoubleArray : public QVector -{ -public: - QDoubleArray(){}; - QDoubleArray( int ){}; - //在pos位置后插入数组 - bool Insert( QDoubleArray& datainsert,int pos ) - { - int lends = size(); - int lendc = datainsert.size(); - double* dc = datainsert.data(); - - resize(lends+ lendc); - - double *buff = this->data(); - if( pos <0 ) - { - memcpy(buff+lendc,buff,lends*sizeof(double)); - memcpy(buff,dc,lendc*sizeof(double)); - - } - else if( pos >= lends-1 ) - { - memcpy(buff+lends,dc,lendc*sizeof(double)); - } - else - { - pos = pos + 1; - memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(double)); - memcpy(buff+pos,dc,lendc*sizeof(double)); - } - return true; - }; - bool Remove( int pos,int len ) - { - if(len<=0) - return true; - - int lends = size(); - - if( pos <0 || pos >= lends) - { - return true; - } - - if( pos+len < lends ) - { - double *buff = data(); - memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(double)); - resize(lends-len); - } - else - { - resize(pos); - } - - return true; - }; -}; - -class QIntArray : public QVector -{ -public: - QIntArray(){}; - QIntArray( int ){}; - //在pos位置后插入数组 - bool Insert( QIntArray& datainsert,int pos ) - { - int lends = size(); - int lendc = datainsert.size(); - int* dc = datainsert.data(); - - resize(lends+ lendc); - - int *buff = this->data(); - if( pos <0 ) - { - memcpy(buff+lendc,buff,lends*sizeof(int)); - memcpy(buff,dc,lendc*sizeof(int)); - } - else if( pos >= lends-1 ) - { - memcpy(buff+lends,dc,lendc*sizeof(int)); - } - else - { - pos = pos + 1; - memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(int)); - memcpy(buff+pos,dc,lendc*sizeof(int)); - } - return true; - }; - bool Remove( int pos,int len ) - { - if(len<=0) - return true; - - int lends = size(); - - if( pos <0 || pos >= lends-1) - { - return true; - } - - if( pos+len < lends ) - { - int *buff = data(); - memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(int)); - resize(lends-len); - } - else - { - resize(pos); - } - return true; - }; -}; - -class QLongArray : public QVector -{ -public: - QLongArray(){}; - QLongArray( int ){}; - //在pos位置后插入数组 - bool Insert( QLongArray& datainsert,int pos ) - { - int lends = size(); - int lendc = datainsert.size(); - long* dc = datainsert.data(); - - resize(lends+ lendc); - - long *buff = this->data(); - if( pos <0 ) - { - memcpy(buff+lendc,buff,lends*sizeof(long)); - memcpy(buff,dc,lendc*sizeof(long)); - - } - else if( pos >= lends-1 ) - { - memcpy(buff+lends,dc,lendc*sizeof(long)); - } - else - { - pos = pos + 1; - memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(long)); - memcpy(buff+pos,dc,lendc*sizeof(long)); - } - return true; - }; - bool Remove( int pos,int len ) - { - if(len<=0) - return true; - - int lends = size(); - - if( pos <0 || pos >= lends-1) - { - return true; - } - - if( pos+len < lends ) - { - long *buff = data(); - memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(long)); - resize(lends-len); - } - else - { - resize(pos); - } - return true; - }; -}; - -class QLLongArray : public QVector -{ -public: - QLLongArray(){}; - QLLongArray( int ){}; - //在pos位置后插入数组 - bool Insert( QLLongArray& datainsert,int pos ) - { - int lends = size(); - int lendc = datainsert.size(); - qint64* dc = datainsert.data(); - - resize(lends+ lendc); - - qint64 *buff = this->data(); - if( pos <0 ) - { - memcpy(buff+lendc,buff,lends*sizeof(qint64)); - memcpy(buff,dc,lendc*sizeof(qint64)); - - } - else if( pos >= lends-1 ) - { - memcpy(buff+lends,dc,lendc*sizeof(qint64)); - } - else - { - pos = pos + 1; - memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(qint64)); - memcpy(buff+pos,dc,lendc*sizeof(qint64)); - } - return true; - }; - bool Remove( int pos,int len ) - { - if(len<=0) - return true; - - int lends = size(); - - if( pos <0 || pos >= lends-1) - { - return true; - } - - if( pos+len < lends ) - { - qint64 *buff = data(); - memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(qint64)); - resize(lends-len); - } - else - { - resize(pos); - } - return true; - }; -}; - -class QUintArray : public QVector -{ -public: - QUintArray(){}; - QUintArray( int ){}; - //在pos位置后插入数组 - bool Insert( QUintArray& datainsert,int pos ) - { - int lends = size(); - int lendc = datainsert.size(); - uint* dc = datainsert.data(); - - resize(lends+ lendc); - - uint *buff = this->data(); - if( pos <0 ) - { - memcpy(buff+lendc,buff,lends*sizeof(uint)); - memcpy(buff,dc,lendc*sizeof(uint)); - - } - else if( pos >= lends-1 ) - { - memcpy(buff+lends,dc,lendc*sizeof(uint)); - } - else - { - pos = pos + 1; - memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(uint)); - memcpy(buff+pos,dc,lendc*sizeof(uint)); - } - return true; - }; - bool Remove( int pos,int len ) - { - if(len<=0) - return true; - - int lends = size(); - - if( pos <0 || pos >= lends-1) - { - return true; - } - - if( pos+len < lends ) - { - uint *buff = data(); - memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(uint)); - resize(lends-len); - } - else - { - resize(pos); - } - return true; - }; -}; - -//插件信息 -struct PLUGININFO{ - int nIndex; //索引 - QString szDiscrip; //描述 - QString szFileName; //文件名 -}; - -#endif //_DATASTRUCT_H - - - +#ifndef _DATASTRUCT_H +#define _DATASTRUCT_H + + +#include +#include +#include + +//datatype +//#ifndef WIN32 + +typedef unsigned long DWORD; +#ifndef PREFIXTYPE +typedef unsigned int WORD; +#endif + +//#endif +typedef unsigned char byte; + +#ifndef _TIME_T_DEFINED +typedef long time_t; /* time value */ +#define _TIME_T_DEFINED /* avoid multiple def's of time_t */ +#endif + +#ifdef WIN32 +#define M_PI 3.141592653590 +#define M_SQRT2 1.414213562373 +#endif +#define M_SQRT3P2 0.8660254 //二分之根号3 +//data +#define MAKEWORD(a, b) ((WORD)(((byte)(a)) | ((WORD)((byte)(b))) << 8)) +#define MAKELONG(a, b) ((long)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16)) +#define LOWORD(l) ((WORD)(l)) +#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) +#define LOBYTE(w) ((byte)(w)) +#define HIBYTE(w) ((byte)(((WORD)(w) >> 8) & 0xFF)) + +//color +#define LLGRAY_COLOR QColor(224,224,224) +#define LGRAY_COLOR QColor(192,192,192) +#define DGRAY_COLOR QColor(128,128,128) +#define DRED_COLOR QColor(64,0,0) +#define RED_COLOR QColor(255,0,0) +#define BLUE_COLOR QColor(0,0,128) +#define BLACK_COLOR QColor(0,0,0) +#define WHITE_COLOR QColor(255,255,255) +#define LCYAN_COLOR QColor(0,255,255) +//wave type +#define CHN_NO_ATTR 0// 无属性 +#define CHN_RIA_ATTR 51// A相电流瞬时值 +#define CHN_RIB_ATTR 52// B相电流瞬时值 +#define CHN_RIC_ATTR 53// C相电流瞬时值 +#define CHN_RUA_ATTR 54// A相电压瞬时值 +#define CHN_RUB_ATTR 55// B相电压瞬时值 +#define CHN_RUC_ATTR 56// C相电压瞬时值 +// +#define CHN_EIA_ATTR 101// A相电流有效值 +#define CHN_EIB_ATTR 102// B相电流有效值 +#define CHN_EIC_ATTR 103// C相电流有效值 +#define CHN_EUA_ATTR 104// A相电压有效值 +#define CHN_EUB_ATTR 105// B相电压有效值 +#define CHN_EUC_ATTR 106// C相电压有效值 +#define CHN_AIA_ATTR 111// A相电流角度 +#define CHN_AIB_ATTR 112// B相电流角度 +#define CHN_AIC_ATTR 113// C相电流角度 +#define CHN_AUA_ATTR 114// A相电压角度 +#define CHN_AUB_ATTR 115// B相电压角度 +#define CHN_AUC_ATTR 116// C相电压角度 +#define CHN_RI0_ATTR 121// 零序电流瞬时值 +#define CHN_RIP_ATTR 122// 正序电流瞬时值 +#define CHN_RIN_ATTR 123// 负序电流瞬时值 +#define CHN_RU0_ATTR 124// 零序电压瞬时值 +#define CHN_RUP_ATTR 125// 正序电压瞬时值 +#define CHN_RUN_ATTR 126// 负序电压瞬时值 +// +#define CHN_P_ATTR 140// 有功功率 +#define CHN_Q_ATTR 141// 无功功率 +#define CHN_S_ATTR 142// 视在功率 +#define CHN_RATE_ATTR 143// 功率因数 +// +#define CHN_RESIST_ATTR 150// 电阻 +#define CHN_REACT_ATTR 151// 电抗 +// +#define CHN_AMP0_ATTR 200// 0次谐波幅值 +#define CHN_AMP1_ATTR 201// 1-99次谐波幅值 +#define CHN_AMP99_ATTR 299// 1-99次谐波幅值 +#define CHN_RVAL0_ATTR 300// 0次谐波瞬时值 +#define CHN_RVAL1_ATTR 301// 1-99次谐波瞬时值 +#define CHN_RVAL99_ATTR 399// 1-99次谐波瞬时值 +//{{liuzp add 2009-07-28 +#define CHN_REAL0_ATTR 400// 0次谐波实部值 +#define CHN_REAL1_ATTR 401// 1次谐波实部值 +#define CHN_REAL99_ATTR 499// 99次谐波实部值 +#define CHN_IMG0_ATTR 500// 0次谐波虚部值 +#define CHN_IMG1_ATTR 501// 1次谐波虚部值 +#define CHN_IMG99_ATTR 599// 99次谐波虚部值 +#define CHN_ANG0_ATTR 600// 0次谐波角度 +#define CHN_ANG1_ATTR 601// 1次谐波角度 +#define CHN_ANG99_ATTR 699// 99次谐波角度 +#define CHN_EFCT0_ATTR 700// 0次谐波有效值 +#define CHN_EFCT1_ATTR 701// 1次谐波有效值 +#define CHN_EFCT99_ATTR 799// 99次谐波有效值 +//}} +// + +#define UNIT_NO 0 +#define UNIT_KV 10 +#define UNIT_V 11 +#define UNIT_KA 12 +#define UNIT_A 13 +#define UNIT_KW 14 +#define UNIT_W 15 +#define UNIT_VA 16 +#define UNIT_KVA 17 +#define UNIT_Var 18 +#define UNIT_KVar 19 +#define UNIT_ANG 20 + +#define MIN_RULER 2.0//电压电流等最小初始刻度 +#define KUNIT_1 1.0//1 kv(ka,kw)与v(a,w)的转换 +#define UNIT_1000 1000.0//1000.0 + +#define SQUART2 1.414213562373 +//zoom rate +#define TIME_RATE 0.1 +#define AMP_RATE 0.1 +#define MAX_PAGES 8 +class QDoubleArray : public QVector +{ +public: + QDoubleArray(){}; + QDoubleArray( int ){}; + //在pos位置后插入数组 + bool Insert( QDoubleArray& datainsert,int pos ) + { + int lends = size(); + int lendc = datainsert.size(); + double* dc = datainsert.data(); + + resize(lends+ lendc); + + double *buff = this->data(); + if( pos <0 ) + { + memcpy(buff+lendc,buff,lends*sizeof(double)); + memcpy(buff,dc,lendc*sizeof(double)); + + } + else if( pos >= lends-1 ) + { + memcpy(buff+lends,dc,lendc*sizeof(double)); + } + else + { + pos = pos + 1; + memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(double)); + memcpy(buff+pos,dc,lendc*sizeof(double)); + } + return true; + }; + bool Remove( int pos,int len ) + { + if(len<=0) + return true; + + int lends = size(); + + if( pos <0 || pos >= lends) + { + return true; + } + + if( pos+len < lends ) + { + double *buff = data(); + memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(double)); + resize(lends-len); + } + else + { + resize(pos); + } + + return true; + }; +}; + +class QIntArray : public QVector +{ +public: + QIntArray(){}; + QIntArray( int ){}; + //在pos位置后插入数组 + bool Insert( QIntArray& datainsert,int pos ) + { + int lends = size(); + int lendc = datainsert.size(); + int* dc = datainsert.data(); + + resize(lends+ lendc); + + int *buff = this->data(); + if( pos <0 ) + { + memcpy(buff+lendc,buff,lends*sizeof(int)); + memcpy(buff,dc,lendc*sizeof(int)); + } + else if( pos >= lends-1 ) + { + memcpy(buff+lends,dc,lendc*sizeof(int)); + } + else + { + pos = pos + 1; + memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(int)); + memcpy(buff+pos,dc,lendc*sizeof(int)); + } + return true; + }; + bool Remove( int pos,int len ) + { + if(len<=0) + return true; + + int lends = size(); + + if( pos <0 || pos >= lends-1) + { + return true; + } + + if( pos+len < lends ) + { + int *buff = data(); + memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(int)); + resize(lends-len); + } + else + { + resize(pos); + } + return true; + }; +}; + +class QLongArray : public QVector +{ +public: + QLongArray(){}; + QLongArray( int ){}; + //在pos位置后插入数组 + bool Insert( QLongArray& datainsert,int pos ) + { + int lends = size(); + int lendc = datainsert.size(); + long* dc = datainsert.data(); + + resize(lends+ lendc); + + long *buff = this->data(); + if( pos <0 ) + { + memcpy(buff+lendc,buff,lends*sizeof(long)); + memcpy(buff,dc,lendc*sizeof(long)); + + } + else if( pos >= lends-1 ) + { + memcpy(buff+lends,dc,lendc*sizeof(long)); + } + else + { + pos = pos + 1; + memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(long)); + memcpy(buff+pos,dc,lendc*sizeof(long)); + } + return true; + }; + bool Remove( int pos,int len ) + { + if(len<=0) + return true; + + int lends = size(); + + if( pos <0 || pos >= lends-1) + { + return true; + } + + if( pos+len < lends ) + { + long *buff = data(); + memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(long)); + resize(lends-len); + } + else + { + resize(pos); + } + return true; + }; +}; + +class QLLongArray : public QVector +{ +public: + QLLongArray(){}; + QLLongArray( int ){}; + //在pos位置后插入数组 + bool Insert( QLLongArray& datainsert,int pos ) + { + int lends = size(); + int lendc = datainsert.size(); + qint64* dc = datainsert.data(); + + resize(lends+ lendc); + + qint64 *buff = this->data(); + if( pos <0 ) + { + memcpy(buff+lendc,buff,lends*sizeof(qint64)); + memcpy(buff,dc,lendc*sizeof(qint64)); + + } + else if( pos >= lends-1 ) + { + memcpy(buff+lends,dc,lendc*sizeof(qint64)); + } + else + { + pos = pos + 1; + memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(qint64)); + memcpy(buff+pos,dc,lendc*sizeof(qint64)); + } + return true; + }; + bool Remove( int pos,int len ) + { + if(len<=0) + return true; + + int lends = size(); + + if( pos <0 || pos >= lends-1) + { + return true; + } + + if( pos+len < lends ) + { + qint64 *buff = data(); + memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(qint64)); + resize(lends-len); + } + else + { + resize(pos); + } + return true; + }; +}; + +class QUintArray : public QVector +{ +public: + QUintArray(){}; + QUintArray( int ){}; + //在pos位置后插入数组 + bool Insert( QUintArray& datainsert,int pos ) + { + int lends = size(); + int lendc = datainsert.size(); + uint* dc = datainsert.data(); + + resize(lends+ lendc); + + uint *buff = this->data(); + if( pos <0 ) + { + memcpy(buff+lendc,buff,lends*sizeof(uint)); + memcpy(buff,dc,lendc*sizeof(uint)); + + } + else if( pos >= lends-1 ) + { + memcpy(buff+lends,dc,lendc*sizeof(uint)); + } + else + { + pos = pos + 1; + memcpy(buff+pos+lendc,buff+pos,(lends-pos)*sizeof(uint)); + memcpy(buff+pos,dc,lendc*sizeof(uint)); + } + return true; + }; + bool Remove( int pos,int len ) + { + if(len<=0) + return true; + + int lends = size(); + + if( pos <0 || pos >= lends-1) + { + return true; + } + + if( pos+len < lends ) + { + uint *buff = data(); + memcpy(buff+pos,buff+pos+len,(lends-len-pos)*sizeof(uint)); + resize(lends-len); + } + else + { + resize(pos); + } + return true; + }; +}; + +//插件信息 +struct PLUGININFO{ + int nIndex; //索引 + QString szDiscrip; //描述 + QString szFileName; //文件名 +}; + +#endif //_DATASTRUCT_H + + + diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/wavedata.h b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/wavedata.h index 6b15e1dd..649deb10 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/wavedata.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/wavedata.h @@ -1,54 +1,54 @@ -#ifndef WAVEDATA_H_HEADER_INCLUDED -#define WAVEDATA_H_HEADER_INCLUDED -//1.分析算法交换数据 -// 分析算法规模 -// -#define MAX_IN_WAVES 16 -#define MAX_OUT_WAVES 32 -#define MAX_POINTS 10000 -#define MAX_SILLS 8 - -// -struct wavedata -{ - int type; //保护类型 1--是LFP系列有前置移相电抗器的老保护 - double angle; //前置移相电抗器移相角度(度数) - unsigned int numic; //输入通道个数 - unsigned int numi; //输入采样点个数 - unsigned int fsi; //输入采样率 - double* pi[MAX_IN_WAVES]; - - //输入数据缓存 - unsigned int pfi; //输入数据标识 - unsigned int chi; //输入采样数据的通道数 - - unsigned int numoc; //输出通道个数 - unsigned int numo; //输出采样点个数 - unsigned int fso; //输出采样率 - double* po[MAX_OUT_WAVES]; // - - //输出数据标识 - unsigned int cho; //输出数据的通道数 - unsigned int max; //要计算的最大谐波次数 - unsigned int min; //要计算的最小谐波次数 - unsigned int faultmode; //短路故障形式 - double dMaxVal; //最大有效值 - double dMinVal; //最小有效值 - int nMaxTick; //最大有效值位置 - int nMinTick; //最小有效值位置 - double zerocomp; //零序补偿系数 - double rps; //全线路正序电阻 - double xps; //全线路正序电抗 - double rps0; //全线路零序电阻 - double xps0; //全线路零序电抗 - double length; //线路长度 - double sill[MAX_SILLS]; //各种门槛值系数 - double dzlqd; //突变量电流起动定值 - double dled; //电流额定值 - double dyed; //电压额定值 -}; - -#endif//WAVEDATA_H_HEADER_INCLUDED - - - +#ifndef WAVEDATA_H_HEADER_INCLUDED +#define WAVEDATA_H_HEADER_INCLUDED +//1.分析算法交换数据 +// 分析算法规模 +// +#define MAX_IN_WAVES 16 +#define MAX_OUT_WAVES 32 +#define MAX_POINTS 10000 +#define MAX_SILLS 8 + +// +struct wavedata +{ + int type; //保护类型 1--是LFP系列有前置移相电抗器的老保护 + double angle; //前置移相电抗器移相角度(度数) + unsigned int numic; //输入通道个数 + unsigned int numi; //输入采样点个数 + unsigned int fsi; //输入采样率 + double* pi[MAX_IN_WAVES]; + + //输入数据缓存 + unsigned int pfi; //输入数据标识 + unsigned int chi; //输入采样数据的通道数 + + unsigned int numoc; //输出通道个数 + unsigned int numo; //输出采样点个数 + unsigned int fso; //输出采样率 + double* po[MAX_OUT_WAVES]; // + + //输出数据标识 + unsigned int cho; //输出数据的通道数 + unsigned int max; //要计算的最大谐波次数 + unsigned int min; //要计算的最小谐波次数 + unsigned int faultmode; //短路故障形式 + double dMaxVal; //最大有效值 + double dMinVal; //最小有效值 + int nMaxTick; //最大有效值位置 + int nMinTick; //最小有效值位置 + double zerocomp; //零序补偿系数 + double rps; //全线路正序电阻 + double xps; //全线路正序电抗 + double rps0; //全线路零序电阻 + double xps0; //全线路零序电抗 + double length; //线路长度 + double sill[MAX_SILLS]; //各种门槛值系数 + double dzlqd; //突变量电流起动定值 + double dled; //电流额定值 + double dyed; //电压额定值 +}; + +#endif//WAVEDATA_H_HEADER_INCLUDED + + + diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyzeWidget.pro b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyzeWidget.pro index 4008b599..f39e0a6b 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyzeWidget.pro +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyzeWidget.pro @@ -1,85 +1,85 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2021-12-24T10:38:18 -# -#------------------------------------------------- - -QT += core gui printsupport xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = WaveAnalyzeWidget -TEMPLATE = lib - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - ./WaveAnalyze/CComtradeFile.cpp \ - ./WaveAnalyze/CWaveGraph.cpp \ - ./WaveAnalyze/CWaveShow.cpp \ - ./WaveAnalyze/CLineStatusShow.cpp \ - ./WaveAnalyze/CDigitalShow.cpp \ - ./WaveAnalyze/CAnaAxisShow.cpp \ - ./WaveAnalyze/CDgtNameShow.cpp \ - ./WaveAnalyze/CTimeAxisShow.cpp \ - ./WaveAnalyze/CAnalogueShow.cpp \ - ./WaveAnalyze/CPrintPreview.cpp \ - ./WaveAnalyze/CPublic.cpp \ - ./WaveAnalyze/cpageshow.cpp \ - ./WaveAnalyze/calgorithms.cpp \ - ./WaveAnalyze/CommonFunction.cpp \ - ./WaveAnalyze/cwavedisplay.cpp \ - ./WaveAnalyze/CAnalogDataSet.cpp \ - ./WaveAnalyze/CDigitDataSet.cpp \ - ./WaveAnalyze/CInfSection.cpp \ - ./WaveAnalyze/CLabel.cpp \ - main.cpp \ - CWaveAnalyzeWidget.cpp \ - CFileTableWidget.cpp \ - CWaveAnalyzePlugin.cpp - -HEADERS += \ - ./WaveAnalyze/CComDataClass.h \ - ./WaveAnalyze/CWaveGraph.h \ - ./WaveAnalyze/CWaveShow.h \ - ./WaveAnalyze/datastruct.h \ - ./WaveAnalyze/CAnalogueShow.h \ - ./WaveAnalyze/CLineStatusShow.h \ - ./WaveAnalyze/CDgtNameShow.h \ - ./WaveAnalyze/CAnaAxisShow.h \ - ./WaveAnalyze/CTimeAxisShow.h \ - ./WaveAnalyze/CDigitalShow.h \ - ./WaveAnalyze/CPrintPreview.h \ - ./WaveAnalyze/CPublic.h \ - ./WaveAnalyze/cpageshow.h \ - ./WaveAnalyze/calgorithms.h \ - ./WaveAnalyze/CommonFunction.h \ - ./WaveAnalyze/wavedata.h \ - CWaveAnalyzeWidget.h \ - CFileTableWidget.h \ - CWaveAnalyzePlugin.h - -FORMS += \ - CWaveAnalyzeWidget.ui - -LIBS += \ - -lpub_utility_api \ - -lperm_mng_api - - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} +#------------------------------------------------- +# +# Project created by QtCreator 2021-12-24T10:38:18 +# +#------------------------------------------------- + +QT += core gui printsupport xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = WaveAnalyzeWidget +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + ./WaveAnalyze/CComtradeFile.cpp \ + ./WaveAnalyze/CWaveGraph.cpp \ + ./WaveAnalyze/CWaveShow.cpp \ + ./WaveAnalyze/CLineStatusShow.cpp \ + ./WaveAnalyze/CDigitalShow.cpp \ + ./WaveAnalyze/CAnaAxisShow.cpp \ + ./WaveAnalyze/CDgtNameShow.cpp \ + ./WaveAnalyze/CTimeAxisShow.cpp \ + ./WaveAnalyze/CAnalogueShow.cpp \ + ./WaveAnalyze/CPrintPreview.cpp \ + ./WaveAnalyze/CPublic.cpp \ + ./WaveAnalyze/cpageshow.cpp \ + ./WaveAnalyze/calgorithms.cpp \ + ./WaveAnalyze/CommonFunction.cpp \ + ./WaveAnalyze/cwavedisplay.cpp \ + ./WaveAnalyze/CAnalogDataSet.cpp \ + ./WaveAnalyze/CDigitDataSet.cpp \ + ./WaveAnalyze/CInfSection.cpp \ + ./WaveAnalyze/CLabel.cpp \ + main.cpp \ + CWaveAnalyzeWidget.cpp \ + CFileTableWidget.cpp \ + CWaveAnalyzePlugin.cpp + +HEADERS += \ + ./WaveAnalyze/CComDataClass.h \ + ./WaveAnalyze/CWaveGraph.h \ + ./WaveAnalyze/CWaveShow.h \ + ./WaveAnalyze/datastruct.h \ + ./WaveAnalyze/CAnalogueShow.h \ + ./WaveAnalyze/CLineStatusShow.h \ + ./WaveAnalyze/CDgtNameShow.h \ + ./WaveAnalyze/CAnaAxisShow.h \ + ./WaveAnalyze/CTimeAxisShow.h \ + ./WaveAnalyze/CDigitalShow.h \ + ./WaveAnalyze/CPrintPreview.h \ + ./WaveAnalyze/CPublic.h \ + ./WaveAnalyze/cpageshow.h \ + ./WaveAnalyze/calgorithms.h \ + ./WaveAnalyze/CommonFunction.h \ + ./WaveAnalyze/wavedata.h \ + CWaveAnalyzeWidget.h \ + CFileTableWidget.h \ + CWaveAnalyzePlugin.h + +FORMS += \ + CWaveAnalyzeWidget.ui + +LIBS += \ + -lpub_utility_api \ + -lperm_mng_api + + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/main.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/main.cpp index a3511c15..c186d427 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/main.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/main.cpp @@ -1,11 +1,11 @@ -#include "CWaveAnalyzeWidget.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - CWaveAnalyzeWidget w(NULL, false); - w.show(); - - return a.exec(); -} +#include "CWaveAnalyzeWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CWaveAnalyzeWidget w(NULL, false); + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/WebBrowserWidget/CBiCookieManage.cpp b/product/src/gui/plugin/WebBrowserWidget/CBiCookieManage.cpp index 27b790a6..0b46dc2d 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBiCookieManage.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/CBiCookieManage.cpp @@ -1,147 +1,147 @@ -#include -#include "pub_sysinfo_api/SysInfoApi.h" -#include "pub_logger_api/logger.h" -#include "CBiCookieManage.h" - -using namespace kbd_service; -using namespace kbd_public; -CBiCookieManage::CBiCookieManage() - : m_strNode(""), - m_nDomainId(CN_InvalidDomainId) -{ - m_ptrPermMngApi = kbd_service::getPermMngInstance("base"); - if(PERM_NORMAL != m_ptrPermMngApi->PermDllInit()) - { - LOGERROR("权限接口初始化失败!"); - return; - } - - //< 获取本机节点名 - CSysInfoInterfacePtr sysInfoPtr; - if(false == createSysInfoInstance(sysInfoPtr)) - { - LOGERROR("创建系统信息访问库实例失败!"); - return; - } - SNodeInfo stNodeInfo; - if(kbdFailed == sysInfoPtr->getLocalNodeInfo(stNodeInfo)) - { - LOGERROR("获取本机节点信息失败!"); - return; - } - m_strNode = stNodeInfo.strName; - m_nDomainId = stNodeInfo.nDomainId; - m_objRdbNetApi.connect(m_nDomainId, CN_AppId_COMAPP); -} - -bool CBiCookieManage::createCookie(QString &strCookie, int &nUserId) -{ - if(m_strNode == "" || m_nDomainId == CN_InvalidDomainId) - { - return false; - } - - int nUserGrpId, nLevel, nLoginSec; - std::string strInstanceName; - if(kbdSuccess != m_ptrPermMngApi->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) - { - LOGERROR("获取当前登录用户信息失败!"); - return false; - } - - strCookie.resize(0); - strCookie += COOKIE_HEADER; - strCookie += QString::number(nUserId); - strCookie += QString::fromStdString(m_strNode); - strCookie.resize(22, 'A'); - //LOGDEBUG("%s", strCookie.toStdString().c_str()); - return true; -} - -bool CBiCookieManage::isAuthExist(const QString &strCookie) -{ - kbd_idlfile::RdbRet objRet; - bool bRet = m_objRdbNetApi.queryByKey(WEB_AUTH, strCookie.toStdString(), WEB_AUTH_EXPIRED_TIME, objRet); - if(false == bRet) - { - return false; - } - int nRecordNum = objRet.msgrecord_size(); - if(nRecordNum <= 0) - { - return false; - } - int64 expired_time = objRet.msgrecord(0).msgvaluearray(0).lvalue(); - if(expired_time <= QDateTime::currentDateTime().toMSecsSinceEpoch()) - { - //< 删除过期鉴权 - bRet = ( removeWebAuth(strCookie) == true ? false : true ); - } - return bRet; -} - -bool CBiCookieManage::addWebAuth(const QString &strCookie, const int &nUserId) -{ - kbd_idlfile::RdbInsert rdbInsert; - rdbInsert.set_strtablename(WEB_AUTH); - - rdbInsert.add_strcolumnname(WEB_AUTH_ID); - rdbInsert.add_strcolumnname(WEB_AUTH_PERM_ID); - rdbInsert.add_strcolumnname(WEB_AUTH_EXPIRED_TIME); - - rdbInsert.add_msgdata(); - rdbInsert.mutable_msgdata(0); - rdbInsert.mutable_msgdata(0)->add_msgvaluearray(); - rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(0)->set_edatatype(kbd_idlfile::CN_DATATYPE_STRING); - rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(0)->set_strvalue(strCookie.toStdString()); - - rdbInsert.mutable_msgdata(0)->add_msgvaluearray(); - rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(1)->set_edatatype(kbd_idlfile::CN_DATATYPE_INT32); - rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(1)->set_nvalue(nUserId); - - QDateTime expired = QDateTime::currentDateTime().addDays(EXPIRED_TIME); - int64 expiredDate = expired.toMSecsSinceEpoch(); - rdbInsert.mutable_msgdata(0)->add_msgvaluearray(); - rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(2)->set_edatatype(kbd_idlfile::CN_DATATYPE_INT64); - rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(2)->set_lvalue(expiredDate); - - bool bRc = false; - // 可能插入失败,重试两次 - for ( int i = 0; i < 2; ++i ) - { - if( m_objRdbNetApi.insert(rdbInsert) ) - { - bRc = true; - break; - } - } - - if( !bRc ) - { - LOGERROR("cannot insert record to web_auth, id:%s", strCookie.toStdString().c_str()); - return false; - } - return true; -} - -bool CBiCookieManage::removeWebAuth(const QString &strCookie) -{ - kbd_idlfile::RdbRemove rdbremove; - rdbremove.set_strtablename(WEB_AUTH); - - rdbremove.add_msgcondtionarray(); - rdbremove.mutable_msgcondtionarray(0)->set_enlogic(kbd_idlfile::enumCondAnd); - rdbremove.mutable_msgcondtionarray(0)->set_enrelation(kbd_idlfile::enumCondEqual); - rdbremove.mutable_msgcondtionarray(0)->set_strcolumnname(WEB_AUTH_ID); - rdbremove.mutable_msgcondtionarray(0)->mutable_msgvalue()->set_edatatype(kbd_idlfile::CN_DATATYPE_STRING); - rdbremove.mutable_msgcondtionarray(0)->mutable_msgvalue()->set_strvalue(strCookie.toStdString()); - - bool bRet = false; - bRet = m_objRdbNetApi.remove(rdbremove); - if( !bRet ) - { - LOGERROR("cannot remove record from web_auth, id:%s", strCookie.toStdString().c_str()); - return false; - } - return true; -} +#include +#include "pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include "CBiCookieManage.h" + +using namespace kbd_service; +using namespace kbd_public; +CBiCookieManage::CBiCookieManage() + : m_strNode(""), + m_nDomainId(CN_InvalidDomainId) +{ + m_ptrPermMngApi = kbd_service::getPermMngInstance("base"); + if(PERM_NORMAL != m_ptrPermMngApi->PermDllInit()) + { + LOGERROR("权限接口初始化失败!"); + return; + } + + //< 获取本机节点名 + CSysInfoInterfacePtr sysInfoPtr; + if(false == createSysInfoInstance(sysInfoPtr)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + SNodeInfo stNodeInfo; + if(kbdFailed == sysInfoPtr->getLocalNodeInfo(stNodeInfo)) + { + LOGERROR("获取本机节点信息失败!"); + return; + } + m_strNode = stNodeInfo.strName; + m_nDomainId = stNodeInfo.nDomainId; + m_objRdbNetApi.connect(m_nDomainId, CN_AppId_COMAPP); +} + +bool CBiCookieManage::createCookie(QString &strCookie, int &nUserId) +{ + if(m_strNode == "" || m_nDomainId == CN_InvalidDomainId) + { + return false; + } + + int nUserGrpId, nLevel, nLoginSec; + std::string strInstanceName; + if(kbdSuccess != m_ptrPermMngApi->CurUser(nUserId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + LOGERROR("获取当前登录用户信息失败!"); + return false; + } + + strCookie.resize(0); + strCookie += COOKIE_HEADER; + strCookie += QString::number(nUserId); + strCookie += QString::fromStdString(m_strNode); + strCookie.resize(22, 'A'); + //LOGDEBUG("%s", strCookie.toStdString().c_str()); + return true; +} + +bool CBiCookieManage::isAuthExist(const QString &strCookie) +{ + kbd_idlfile::RdbRet objRet; + bool bRet = m_objRdbNetApi.queryByKey(WEB_AUTH, strCookie.toStdString(), WEB_AUTH_EXPIRED_TIME, objRet); + if(false == bRet) + { + return false; + } + int nRecordNum = objRet.msgrecord_size(); + if(nRecordNum <= 0) + { + return false; + } + int64 expired_time = objRet.msgrecord(0).msgvaluearray(0).lvalue(); + if(expired_time <= QDateTime::currentDateTime().toMSecsSinceEpoch()) + { + //< 删除过期鉴权 + bRet = ( removeWebAuth(strCookie) == true ? false : true ); + } + return bRet; +} + +bool CBiCookieManage::addWebAuth(const QString &strCookie, const int &nUserId) +{ + kbd_idlfile::RdbInsert rdbInsert; + rdbInsert.set_strtablename(WEB_AUTH); + + rdbInsert.add_strcolumnname(WEB_AUTH_ID); + rdbInsert.add_strcolumnname(WEB_AUTH_PERM_ID); + rdbInsert.add_strcolumnname(WEB_AUTH_EXPIRED_TIME); + + rdbInsert.add_msgdata(); + rdbInsert.mutable_msgdata(0); + rdbInsert.mutable_msgdata(0)->add_msgvaluearray(); + rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(0)->set_edatatype(kbd_idlfile::CN_DATATYPE_STRING); + rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(0)->set_strvalue(strCookie.toStdString()); + + rdbInsert.mutable_msgdata(0)->add_msgvaluearray(); + rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(1)->set_edatatype(kbd_idlfile::CN_DATATYPE_INT32); + rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(1)->set_nvalue(nUserId); + + QDateTime expired = QDateTime::currentDateTime().addDays(EXPIRED_TIME); + int64 expiredDate = expired.toMSecsSinceEpoch(); + rdbInsert.mutable_msgdata(0)->add_msgvaluearray(); + rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(2)->set_edatatype(kbd_idlfile::CN_DATATYPE_INT64); + rdbInsert.mutable_msgdata(0)->mutable_msgvaluearray(2)->set_lvalue(expiredDate); + + bool bRc = false; + // 可能插入失败,重试两次 + for ( int i = 0; i < 2; ++i ) + { + if( m_objRdbNetApi.insert(rdbInsert) ) + { + bRc = true; + break; + } + } + + if( !bRc ) + { + LOGERROR("cannot insert record to web_auth, id:%s", strCookie.toStdString().c_str()); + return false; + } + return true; +} + +bool CBiCookieManage::removeWebAuth(const QString &strCookie) +{ + kbd_idlfile::RdbRemove rdbremove; + rdbremove.set_strtablename(WEB_AUTH); + + rdbremove.add_msgcondtionarray(); + rdbremove.mutable_msgcondtionarray(0)->set_enlogic(kbd_idlfile::enumCondAnd); + rdbremove.mutable_msgcondtionarray(0)->set_enrelation(kbd_idlfile::enumCondEqual); + rdbremove.mutable_msgcondtionarray(0)->set_strcolumnname(WEB_AUTH_ID); + rdbremove.mutable_msgcondtionarray(0)->mutable_msgvalue()->set_edatatype(kbd_idlfile::CN_DATATYPE_STRING); + rdbremove.mutable_msgcondtionarray(0)->mutable_msgvalue()->set_strvalue(strCookie.toStdString()); + + bool bRet = false; + bRet = m_objRdbNetApi.remove(rdbremove); + if( !bRet ) + { + LOGERROR("cannot remove record from web_auth, id:%s", strCookie.toStdString().c_str()); + return false; + } + return true; +} diff --git a/product/src/gui/plugin/WebBrowserWidget/CBiCookieManage.h b/product/src/gui/plugin/WebBrowserWidget/CBiCookieManage.h index 8efe0a12..d2544bfd 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBiCookieManage.h +++ b/product/src/gui/plugin/WebBrowserWidget/CBiCookieManage.h @@ -1,36 +1,36 @@ -#ifndef CBICOOKIEMANAGE_H -#define CBICOOKIEMANAGE_H - -#include -#include "perm_mng_api/PermMngApi.h" -#include "rdb_net_api/CRdbNetApi.h" - -#define WEB_AUTH "web_auth" -#define WEB_AUTH_ID "id" -#define WEB_AUTH_PERM_ID "perm_id" -#define WEB_AUTH_EXPIRED_TIME "expired_time" - -#define COOKIE_HEADER "HTMLBROWSER" -const int EXPIRED_TIME = 30; //< 超时时间30天 - -class CBiCookieManage -{ -public: - CBiCookieManage(); - - bool createCookie(QString &strCookie, int &nUserId); - - bool isAuthExist(const QString &strCookie); - - bool addWebAuth(const QString &strCookie, const int &nUserId); - - bool removeWebAuth(const QString &strCookie); - -private: - std::string m_strNode; - int m_nDomainId; - kbd_service::CPermMngApiPtr m_ptrPermMngApi; - kbd_dbms::CRdbNetApi m_objRdbNetApi; -}; - -#endif // CBICOOKIEMANAGE_H +#ifndef CBICOOKIEMANAGE_H +#define CBICOOKIEMANAGE_H + +#include +#include "perm_mng_api/PermMngApi.h" +#include "rdb_net_api/CRdbNetApi.h" + +#define WEB_AUTH "web_auth" +#define WEB_AUTH_ID "id" +#define WEB_AUTH_PERM_ID "perm_id" +#define WEB_AUTH_EXPIRED_TIME "expired_time" + +#define COOKIE_HEADER "HTMLBROWSER" +const int EXPIRED_TIME = 30; //< 超时时间30天 + +class CBiCookieManage +{ +public: + CBiCookieManage(); + + bool createCookie(QString &strCookie, int &nUserId); + + bool isAuthExist(const QString &strCookie); + + bool addWebAuth(const QString &strCookie, const int &nUserId); + + bool removeWebAuth(const QString &strCookie); + +private: + std::string m_strNode; + int m_nDomainId; + kbd_service::CPermMngApiPtr m_ptrPermMngApi; + kbd_dbms::CRdbNetApi m_objRdbNetApi; +}; + +#endif // CBICOOKIEMANAGE_H diff --git a/product/src/gui/plugin/WebBrowserWidget/CBiTabWidget.cpp b/product/src/gui/plugin/WebBrowserWidget/CBiTabWidget.cpp index 0740a91a..81554000 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBiTabWidget.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/CBiTabWidget.cpp @@ -1,56 +1,56 @@ -#include -#include -#include -#include "pub_utility_api/FileStyle.h" -#include "pub_logger_api/logger.h" -#include "CBiTabWidget.h" -#include "CWebEngineView.h" -#include "CBiCookieManage.h" - -CBiTabWidget::CBiTabWidget(QWidget *parent) - : CWebTabWidget(parent), - m_strCookie("") -{ - m_networkCookie.setName("id"); - m_strStyle = std::move(kbd_public::CFileStyle::getCurStyle()); -} - -void CBiTabWidget::setUrl(const QUrl &url) -{ - if (CWebEngineView *view = currentWebView()) { - QUrl origin; - origin.setScheme(url.scheme()); - origin.setHost(url.host()); - origin.setPort(url.port()); - //< 使用http://192.168.77.81:1120,否则后续请求会被拦截 - view->page()->profile()->cookieStore()->setCookie(m_networkCookie, origin); - - QUrl themeUrl(url); - QUrlQuery query(themeUrl.query()); - query.addQueryItem("theme", QString::fromStdString(m_strStyle)); - themeUrl.setQuery(query); - - view->setUrl(themeUrl); - view->setFocus(); - LOGINFO("BI url : %s", themeUrl.toString().toStdString().c_str()); - } -} - -void CBiTabWidget::updateCookie() -{ - CBiCookieManage cookieManage; - int nUserId; - if(cookieManage.createCookie(m_strCookie, nUserId)) - { - m_networkCookie.setValue(m_strCookie.toLocal8Bit()); - if(!cookieManage.isAuthExist(m_strCookie)) - { - cookieManage.addWebAuth(m_strCookie, nUserId); - } - } - else - { - m_strCookie = ""; - m_networkCookie.setValue(""); - } -} +#include +#include +#include +#include "pub_utility_api/FileStyle.h" +#include "pub_logger_api/logger.h" +#include "CBiTabWidget.h" +#include "CWebEngineView.h" +#include "CBiCookieManage.h" + +CBiTabWidget::CBiTabWidget(QWidget *parent) + : CWebTabWidget(parent), + m_strCookie("") +{ + m_networkCookie.setName("id"); + m_strStyle = std::move(kbd_public::CFileStyle::getCurStyle()); +} + +void CBiTabWidget::setUrl(const QUrl &url) +{ + if (CWebEngineView *view = currentWebView()) { + QUrl origin; + origin.setScheme(url.scheme()); + origin.setHost(url.host()); + origin.setPort(url.port()); + //< 使用http://192.168.77.81:1120,否则后续请求会被拦截 + view->page()->profile()->cookieStore()->setCookie(m_networkCookie, origin); + + QUrl themeUrl(url); + QUrlQuery query(themeUrl.query()); + query.addQueryItem("theme", QString::fromStdString(m_strStyle)); + themeUrl.setQuery(query); + + view->setUrl(themeUrl); + view->setFocus(); + LOGINFO("BI url : %s", themeUrl.toString().toStdString().c_str()); + } +} + +void CBiTabWidget::updateCookie() +{ + CBiCookieManage cookieManage; + int nUserId; + if(cookieManage.createCookie(m_strCookie, nUserId)) + { + m_networkCookie.setValue(m_strCookie.toLocal8Bit()); + if(!cookieManage.isAuthExist(m_strCookie)) + { + cookieManage.addWebAuth(m_strCookie, nUserId); + } + } + else + { + m_strCookie = ""; + m_networkCookie.setValue(""); + } +} diff --git a/product/src/gui/plugin/WebBrowserWidget/CBiTabWidget.h b/product/src/gui/plugin/WebBrowserWidget/CBiTabWidget.h index 50378f62..01cda06e 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBiTabWidget.h +++ b/product/src/gui/plugin/WebBrowserWidget/CBiTabWidget.h @@ -1,22 +1,22 @@ -#ifndef CBITABWIDGET_H -#define CBITABWIDGET_H - -#include -#include "CWebTabWidget.h" - -class CBiTabWidget : public CWebTabWidget -{ -public: - CBiTabWidget(QWidget *parent = Q_NULLPTR); - - void setUrl(const QUrl &url) override; - - void updateCookie() override; - -private: - QString m_strCookie; - QNetworkCookie m_networkCookie; //< id=HTMLBROWSER1kbd-rd-sh - std::string m_strStyle; -}; - -#endif // CBITABWIDGET_H +#ifndef CBITABWIDGET_H +#define CBITABWIDGET_H + +#include +#include "CWebTabWidget.h" + +class CBiTabWidget : public CWebTabWidget +{ +public: + CBiTabWidget(QWidget *parent = Q_NULLPTR); + + void setUrl(const QUrl &url) override; + + void updateCookie() override; + +private: + QString m_strCookie; + QNetworkCookie m_networkCookie; //< id=HTMLBROWSER1kbd-rd-sh + std::string m_strStyle; +}; + +#endif // CBITABWIDGET_H diff --git a/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.cpp b/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.cpp index a1742926..c4a4703a 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CBrowserPluginWidget.h" -#include "CBrowserWidget.h" - -CBrowserPluginWidget::CBrowserPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CBrowserPluginWidget::~CBrowserPluginWidget() -{ - -} - -bool CBrowserPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CBrowserWidget *pWidget = new CBrowserWidget(parent,editMode); - *widget = (QWidget *)pWidget; - *reportWidget = (IPluginWidget *)pWidget; - return true; -} - -void CBrowserPluginWidget::release() -{ - -} +#include +#include "CBrowserPluginWidget.h" +#include "CBrowserWidget.h" + +CBrowserPluginWidget::CBrowserPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CBrowserPluginWidget::~CBrowserPluginWidget() +{ + +} + +bool CBrowserPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CBrowserWidget *pWidget = new CBrowserWidget(parent,editMode); + *widget = (QWidget *)pWidget; + *reportWidget = (IPluginWidget *)pWidget; + return true; +} + +void CBrowserPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.h b/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.h index 267ba0f6..4fd2cc2d 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.h +++ b/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CBROWSERPLUGINWIDGET_H -#define CBROWSERPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CBrowserPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CBrowserPluginWidget(QObject *parent = 0); - ~CBrowserPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); - void release(); -}; - -#endif // CBROWSERPLUGINWIDGET_H +#ifndef CBROWSERPLUGINWIDGET_H +#define CBROWSERPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CBrowserPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CBrowserPluginWidget(QObject *parent = 0); + ~CBrowserPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); + void release(); +}; + +#endif // CBROWSERPLUGINWIDGET_H diff --git a/product/src/gui/plugin/WebBrowserWidget/CBrowserWidget.cpp b/product/src/gui/plugin/WebBrowserWidget/CBrowserWidget.cpp index ba8a26b6..ecce4980 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBrowserWidget.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/CBrowserWidget.cpp @@ -1,162 +1,162 @@ -#include -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "pub_utility_api/FileStyle.h" -#include "CBrowserWidget.h" -#include "CBiTabWidget.h" -#include "CEnergyTabWidget.h" - -CBrowserWidget::CBrowserWidget(QWidget *parent, bool editMode) - : QWidget(parent), - m_pTabWidget(Q_NULLPTR), - m_strIpAddr("127.0.0.1") -{ - if(editMode) - { - QLabel *label = new QLabel(this); - label->setPixmap(QPixmap(":/report")); - label->setScaledContents(true); - QGridLayout *lay = new QGridLayout(this); - lay->addWidget(label); - this->setLayout(lay); - } - else - { - initStyle(); - initialize(); - } -} - -CBrowserWidget::~CBrowserWidget() -{ - if(m_pTabWidget) - { - delete m_pTabWidget; - } - m_pTabWidget = NULL; -} - -CWebTabWidget *CBrowserWidget::tabWidget() -{ - return m_pTabWidget; -} - -void CBrowserWidget::init(int source) -{ - if(m_pTabWidget) - { - delete m_pTabWidget; - } - - switch (source) { - case SOURCE_DEFAULT: - { - m_pTabWidget = new CWebTabWidget(this); - break; - } - case SOURCE_BI: - { - m_pTabWidget = new CBiTabWidget(this); - break; - } - case SOURCE_ENERGY: - { - m_pTabWidget = new CEnergyTabWidget(this); - break; - } - default: - { - m_pTabWidget = Q_NULLPTR; - return; - } - } - - QGridLayout * layout = new QGridLayout(this); - layout->addWidget(m_pTabWidget); - layout->setMargin(0); - this->setLayout(layout); - - m_pTabWidget->updateCookie(); - m_pTabWidget->createTab(); -} - -void CBrowserWidget::setIpAddr(const QString &ipAddr) -{ - m_strIpAddr = ipAddr; -} - -void CBrowserWidget::loadHtml(const QString &url) -{ - QUrl html(url); - if(!html.isValid()) - { - LOGERROR("loadHtml , [%s] is invalid!", url.toStdString().c_str()); - return; - } - if(m_pTabWidget) - { - LOGINFO("loadHtml : %s", url.toStdString().c_str()); - m_pTabWidget->setUrl(html); - } -} - -void CBrowserWidget::loadPage(const QString &url) -{ - QString strUrl ="http://" + m_strIpAddr + url; - QUrl html(strUrl); - if(!html.isValid()) - { - LOGERROR("loadPage , [%s] is invalid!", strUrl.toStdString().c_str()); - return; - } - if(m_pTabWidget) - { - LOGINFO("loadPage : %s", strUrl.toStdString().c_str()); - m_pTabWidget->setUrl(html); - } -} - -void CBrowserWidget::login() -{ - if(m_pTabWidget) - { - m_pTabWidget->updateCookie(); - m_pTabWidget->closeOtherTabs(0); - } -} - -void CBrowserWidget::initialize() -{ - QNetworkProxyFactory::setUseSystemConfiguration(false); - QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); - QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); -} - -void CBrowserWidget::initStyle() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("WebBrowserWidget.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} +#include +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" +#include "CBrowserWidget.h" +#include "CBiTabWidget.h" +#include "CEnergyTabWidget.h" + +CBrowserWidget::CBrowserWidget(QWidget *parent, bool editMode) + : QWidget(parent), + m_pTabWidget(Q_NULLPTR), + m_strIpAddr("127.0.0.1") +{ + if(editMode) + { + QLabel *label = new QLabel(this); + label->setPixmap(QPixmap(":/report")); + label->setScaledContents(true); + QGridLayout *lay = new QGridLayout(this); + lay->addWidget(label); + this->setLayout(lay); + } + else + { + initStyle(); + initialize(); + } +} + +CBrowserWidget::~CBrowserWidget() +{ + if(m_pTabWidget) + { + delete m_pTabWidget; + } + m_pTabWidget = NULL; +} + +CWebTabWidget *CBrowserWidget::tabWidget() +{ + return m_pTabWidget; +} + +void CBrowserWidget::init(int source) +{ + if(m_pTabWidget) + { + delete m_pTabWidget; + } + + switch (source) { + case SOURCE_DEFAULT: + { + m_pTabWidget = new CWebTabWidget(this); + break; + } + case SOURCE_BI: + { + m_pTabWidget = new CBiTabWidget(this); + break; + } + case SOURCE_ENERGY: + { + m_pTabWidget = new CEnergyTabWidget(this); + break; + } + default: + { + m_pTabWidget = Q_NULLPTR; + return; + } + } + + QGridLayout * layout = new QGridLayout(this); + layout->addWidget(m_pTabWidget); + layout->setMargin(0); + this->setLayout(layout); + + m_pTabWidget->updateCookie(); + m_pTabWidget->createTab(); +} + +void CBrowserWidget::setIpAddr(const QString &ipAddr) +{ + m_strIpAddr = ipAddr; +} + +void CBrowserWidget::loadHtml(const QString &url) +{ + QUrl html(url); + if(!html.isValid()) + { + LOGERROR("loadHtml , [%s] is invalid!", url.toStdString().c_str()); + return; + } + if(m_pTabWidget) + { + LOGINFO("loadHtml : %s", url.toStdString().c_str()); + m_pTabWidget->setUrl(html); + } +} + +void CBrowserWidget::loadPage(const QString &url) +{ + QString strUrl ="http://" + m_strIpAddr + url; + QUrl html(strUrl); + if(!html.isValid()) + { + LOGERROR("loadPage , [%s] is invalid!", strUrl.toStdString().c_str()); + return; + } + if(m_pTabWidget) + { + LOGINFO("loadPage : %s", strUrl.toStdString().c_str()); + m_pTabWidget->setUrl(html); + } +} + +void CBrowserWidget::login() +{ + if(m_pTabWidget) + { + m_pTabWidget->updateCookie(); + m_pTabWidget->closeOtherTabs(0); + } +} + +void CBrowserWidget::initialize() +{ + QNetworkProxyFactory::setUseSystemConfiguration(false); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); +} + +void CBrowserWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("WebBrowserWidget.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} diff --git a/product/src/gui/plugin/WebBrowserWidget/CBrowserWidget.h b/product/src/gui/plugin/WebBrowserWidget/CBrowserWidget.h index d6173b55..b0f0286c 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBrowserWidget.h +++ b/product/src/gui/plugin/WebBrowserWidget/CBrowserWidget.h @@ -1,56 +1,56 @@ -#ifndef CBROWSERWIDGET_H -#define CBROWSERWIDGET_H - -#include -#include "CWebTabWidget.h" - -class CBrowserWidget : public QWidget -{ - Q_OBJECT -public: - enum EN_SOURCE{ - SOURCE_DEFAULT = 0, - SOURCE_BI = 1, - SOURCE_ENERGY, - }; - explicit CBrowserWidget(QWidget *parent, bool editMode); - ~CBrowserWidget(); - - CWebTabWidget * tabWidget(); - -public slots: - /** - * @brief init 初始化web来源,必须先初始化才能进行后续操作 - * @param source 0:通用,直接加载url 1:BI,2:能源管理 - */ - void init(int source = 0); - /** - * @brief setIpAddr 设置连接IP,用于loadPage() - * @param ipAddr - */ - void setIpAddr(const QString &ipAddr); - /** - * @brief loadHtml - * @param url "http://192.168.77.81:1120/platform/pageManage" - */ - void loadHtml(const QString &url); - /** - * @brief loadPage - * @param url ":1120/platform/pageManage" - */ - void loadPage(const QString &url); - /** - * @brief login 登录 - */ - void login(); - -private: - void initialize(); - void initStyle(); - -private: - CWebTabWidget * m_pTabWidget; - QString m_strIpAddr; -}; - -#endif // CBROWSERWIDGET_H +#ifndef CBROWSERWIDGET_H +#define CBROWSERWIDGET_H + +#include +#include "CWebTabWidget.h" + +class CBrowserWidget : public QWidget +{ + Q_OBJECT +public: + enum EN_SOURCE{ + SOURCE_DEFAULT = 0, + SOURCE_BI = 1, + SOURCE_ENERGY, + }; + explicit CBrowserWidget(QWidget *parent, bool editMode); + ~CBrowserWidget(); + + CWebTabWidget * tabWidget(); + +public slots: + /** + * @brief init 初始化web来源,必须先初始化才能进行后续操作 + * @param source 0:通用,直接加载url 1:BI,2:能源管理 + */ + void init(int source = 0); + /** + * @brief setIpAddr 设置连接IP,用于loadPage() + * @param ipAddr + */ + void setIpAddr(const QString &ipAddr); + /** + * @brief loadHtml + * @param url "http://192.168.77.81:1120/platform/pageManage" + */ + void loadHtml(const QString &url); + /** + * @brief loadPage + * @param url ":1120/platform/pageManage" + */ + void loadPage(const QString &url); + /** + * @brief login 登录 + */ + void login(); + +private: + void initialize(); + void initStyle(); + +private: + CWebTabWidget * m_pTabWidget; + QString m_strIpAddr; +}; + +#endif // CBROWSERWIDGET_H diff --git a/product/src/gui/plugin/WebBrowserWidget/CEnergyTabWidget.cpp b/product/src/gui/plugin/WebBrowserWidget/CEnergyTabWidget.cpp index 0088b6a1..5f9f966c 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CEnergyTabWidget.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/CEnergyTabWidget.cpp @@ -1,29 +1,29 @@ -#include -#include "CWebEngineView.h" -#include "CEnergyTabWidget.h" -#include "pub_utility_api/FileStyle.h" -#include "pub_logger_api/logger.h" - -CEnergyTabWidget::CEnergyTabWidget(QWidget *parent) - : CWebTabWidget(parent) -{ - m_strStyle = std::move(kbd_public::CFileStyle::getCurStyle()); -} - -void CEnergyTabWidget::setUrl(const QUrl &url) -{ - if (CWebEngineView *view = currentWebView()){ - QUrl origin; - origin.setUrl(QString("%1&theme=%2") - .arg(url.toString()) - .arg(QString::fromStdString(m_strStyle))); - view->setUrl(origin); - view->setFocus(); - LOGINFO("energy url : %s", origin.toString().toStdString().c_str()); - } -} - -void CEnergyTabWidget::updateCookie() -{ - -} +#include +#include "CWebEngineView.h" +#include "CEnergyTabWidget.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_logger_api/logger.h" + +CEnergyTabWidget::CEnergyTabWidget(QWidget *parent) + : CWebTabWidget(parent) +{ + m_strStyle = std::move(kbd_public::CFileStyle::getCurStyle()); +} + +void CEnergyTabWidget::setUrl(const QUrl &url) +{ + if (CWebEngineView *view = currentWebView()){ + QUrl origin; + origin.setUrl(QString("%1&theme=%2") + .arg(url.toString()) + .arg(QString::fromStdString(m_strStyle))); + view->setUrl(origin); + view->setFocus(); + LOGINFO("energy url : %s", origin.toString().toStdString().c_str()); + } +} + +void CEnergyTabWidget::updateCookie() +{ + +} diff --git a/product/src/gui/plugin/WebBrowserWidget/CEnergyTabWidget.h b/product/src/gui/plugin/WebBrowserWidget/CEnergyTabWidget.h index c09aa3ca..ebb41594 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CEnergyTabWidget.h +++ b/product/src/gui/plugin/WebBrowserWidget/CEnergyTabWidget.h @@ -1,19 +1,19 @@ -#ifndef CENERGYTABWIDGET_H -#define CENERGYTABWIDGET_H - -#include "CWebTabWidget.h" - -class CEnergyTabWidget : public CWebTabWidget -{ -public: - CEnergyTabWidget(QWidget *parent = Q_NULLPTR); - - void setUrl(const QUrl &url) override; - - void updateCookie() override; - -private: - std::string m_strStyle; -}; - -#endif // CENERGYTABWIDGET_H +#ifndef CENERGYTABWIDGET_H +#define CENERGYTABWIDGET_H + +#include "CWebTabWidget.h" + +class CEnergyTabWidget : public CWebTabWidget +{ +public: + CEnergyTabWidget(QWidget *parent = Q_NULLPTR); + + void setUrl(const QUrl &url) override; + + void updateCookie() override; + +private: + std::string m_strStyle; +}; + +#endif // CENERGYTABWIDGET_H diff --git a/product/src/gui/plugin/WebBrowserWidget/CWebEngineView.cpp b/product/src/gui/plugin/WebBrowserWidget/CWebEngineView.cpp index fb654418..87b341ce 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CWebEngineView.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/CWebEngineView.cpp @@ -1,116 +1,116 @@ -#include -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "CWebEngineView.h" -#include "CWebTabWidget.h" - -CWebEngineView::CWebEngineView(QWidget *parent) - : QWebEngineView(parent), - m_loadProgress(100) -{ - this->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled,false); - this->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); - this->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); - this->setContextMenuPolicy(Qt::CustomContextMenu); - - //< Tab图标展示 - connect(this, &QWebEngineView::loadStarted, [this]() { - m_loadProgress = 0; - emit favIconChanged(favIcon()); - }); - connect(this, &QWebEngineView::loadProgress, [this](int progress) { - m_loadProgress = progress; - }); - connect(this, &QWebEngineView::loadFinished, [this](bool success) { - m_loadProgress = success ? 100 : -1; - emit favIconChanged(favIcon()); - }); - connect(this, &QWebEngineView::iconChanged, [this](const QIcon &) { - emit favIconChanged(favIcon()); - }); - - //< 异常中断 - connect(this, &QWebEngineView::renderProcessTerminated, - [this](QWebEnginePage::RenderProcessTerminationStatus termStatus, int statusCode) { - QString status; - switch (termStatus) { - case QWebEnginePage::NormalTerminationStatus: - status = tr("Render process normal exit"); - break; - case QWebEnginePage::AbnormalTerminationStatus: - status = tr("Render process abnormal exit"); - break; - case QWebEnginePage::CrashedTerminationStatus: - status = tr("Render process crashed"); - break; - case QWebEnginePage::KilledTerminationStatus: - status = tr("Render process killed"); - break; - } - LOGERROR("%s : %d", status.toStdString().c_str(), statusCode); - }); - - connect(this, &CWebEngineView::customContextMenuRequested, this, &CWebEngineView::handleContextMenuRequested); -} - -CWebEngineView::~CWebEngineView() -{ - //< 由CWebTabWidget管理 -// this->page()->profile()->cookieStore()->deleteAllCookies(); -} - -void CWebEngineView::setParentWidget(QWidget *parent) -{ - m_pParent = parent; -} - -CWebEngineView *CWebEngineView::createWindow(QWebEnginePage::WebWindowType type) -{ - CWebTabWidget *mainWidget = qobject_cast(m_pParent); - if (!mainWidget) - return nullptr; - - switch (type) { - case QWebEnginePage::WebBrowserTab: { - return mainWidget->createTab(); - } - case QWebEnginePage::WebBrowserBackgroundTab: { - return mainWidget->createBackgroundTab(); - } - case QWebEnginePage::WebBrowserWindow: { - return nullptr; - } - case QWebEnginePage::WebDialog: { - return nullptr; - } - } - return nullptr; -} - -void CWebEngineView::handleContextMenuRequested(const QPoint &pos) -{ - Q_UNUSED(pos) - QMenu menu; - menu.addAction(tr("刷新"), this, [this](){reload();}); - menu.exec(QCursor::pos()); -} - -QIcon CWebEngineView::favIcon() const -{ - QIcon favIcon = icon(); - if (!favIcon.isNull()) - return favIcon; - - if (m_loadProgress < 0) { - static QIcon errorIcon(":/error"); - return errorIcon; - } else if (m_loadProgress < 100) { - static QIcon loadingIcon(":/refresh"); - return loadingIcon; - } else { - static QIcon defaultIcon(":/html"); - return defaultIcon; - } -} +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "CWebEngineView.h" +#include "CWebTabWidget.h" + +CWebEngineView::CWebEngineView(QWidget *parent) + : QWebEngineView(parent), + m_loadProgress(100) +{ + this->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled,false); + this->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); + this->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); + this->setContextMenuPolicy(Qt::CustomContextMenu); + + //< Tab图标展示 + connect(this, &QWebEngineView::loadStarted, [this]() { + m_loadProgress = 0; + emit favIconChanged(favIcon()); + }); + connect(this, &QWebEngineView::loadProgress, [this](int progress) { + m_loadProgress = progress; + }); + connect(this, &QWebEngineView::loadFinished, [this](bool success) { + m_loadProgress = success ? 100 : -1; + emit favIconChanged(favIcon()); + }); + connect(this, &QWebEngineView::iconChanged, [this](const QIcon &) { + emit favIconChanged(favIcon()); + }); + + //< 异常中断 + connect(this, &QWebEngineView::renderProcessTerminated, + [this](QWebEnginePage::RenderProcessTerminationStatus termStatus, int statusCode) { + QString status; + switch (termStatus) { + case QWebEnginePage::NormalTerminationStatus: + status = tr("Render process normal exit"); + break; + case QWebEnginePage::AbnormalTerminationStatus: + status = tr("Render process abnormal exit"); + break; + case QWebEnginePage::CrashedTerminationStatus: + status = tr("Render process crashed"); + break; + case QWebEnginePage::KilledTerminationStatus: + status = tr("Render process killed"); + break; + } + LOGERROR("%s : %d", status.toStdString().c_str(), statusCode); + }); + + connect(this, &CWebEngineView::customContextMenuRequested, this, &CWebEngineView::handleContextMenuRequested); +} + +CWebEngineView::~CWebEngineView() +{ + //< 由CWebTabWidget管理 +// this->page()->profile()->cookieStore()->deleteAllCookies(); +} + +void CWebEngineView::setParentWidget(QWidget *parent) +{ + m_pParent = parent; +} + +CWebEngineView *CWebEngineView::createWindow(QWebEnginePage::WebWindowType type) +{ + CWebTabWidget *mainWidget = qobject_cast(m_pParent); + if (!mainWidget) + return nullptr; + + switch (type) { + case QWebEnginePage::WebBrowserTab: { + return mainWidget->createTab(); + } + case QWebEnginePage::WebBrowserBackgroundTab: { + return mainWidget->createBackgroundTab(); + } + case QWebEnginePage::WebBrowserWindow: { + return nullptr; + } + case QWebEnginePage::WebDialog: { + return nullptr; + } + } + return nullptr; +} + +void CWebEngineView::handleContextMenuRequested(const QPoint &pos) +{ + Q_UNUSED(pos) + QMenu menu; + menu.addAction(tr("刷新"), this, [this](){reload();}); + menu.exec(QCursor::pos()); +} + +QIcon CWebEngineView::favIcon() const +{ + QIcon favIcon = icon(); + if (!favIcon.isNull()) + return favIcon; + + if (m_loadProgress < 0) { + static QIcon errorIcon(":/error"); + return errorIcon; + } else if (m_loadProgress < 100) { + static QIcon loadingIcon(":/refresh"); + return loadingIcon; + } else { + static QIcon defaultIcon(":/html"); + return defaultIcon; + } +} diff --git a/product/src/gui/plugin/WebBrowserWidget/CWebEngineView.h b/product/src/gui/plugin/WebBrowserWidget/CWebEngineView.h index 404cde8a..9699e48d 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CWebEngineView.h +++ b/product/src/gui/plugin/WebBrowserWidget/CWebEngineView.h @@ -1,32 +1,32 @@ -#ifndef CWEBENGINEVIEW_H -#define CWEBENGINEVIEW_H - -#include - -class CWebEngineView : public QWebEngineView -{ - Q_OBJECT -public: - explicit CWebEngineView(QWidget* parent = Q_NULLPTR); - ~CWebEngineView(); - - void setParentWidget(QWidget *parent); - -signals: - void favIconChanged(const QIcon &icon); - -protected: - CWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override; - -private slots: - void handleContextMenuRequested(const QPoint &pos); - -private: - QIcon favIcon() const; - -private: - int m_loadProgress; - QWidget *m_pParent; -}; - -#endif // CWEBENGINEVIEW_H +#ifndef CWEBENGINEVIEW_H +#define CWEBENGINEVIEW_H + +#include + +class CWebEngineView : public QWebEngineView +{ + Q_OBJECT +public: + explicit CWebEngineView(QWidget* parent = Q_NULLPTR); + ~CWebEngineView(); + + void setParentWidget(QWidget *parent); + +signals: + void favIconChanged(const QIcon &icon); + +protected: + CWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override; + +private slots: + void handleContextMenuRequested(const QPoint &pos); + +private: + QIcon favIcon() const; + +private: + int m_loadProgress; + QWidget *m_pParent; +}; + +#endif // CWEBENGINEVIEW_H diff --git a/product/src/gui/plugin/WebBrowserWidget/CWebTabWidget.cpp b/product/src/gui/plugin/WebBrowserWidget/CWebTabWidget.cpp index feaf9df1..64d0b02d 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CWebTabWidget.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/CWebTabWidget.cpp @@ -1,124 +1,124 @@ -#include -#include -#include -#include "pub_logger_api/logger.h" -#include "CWebTabWidget.h" -#include "CWebEngineView.h" - -CWebTabWidget::CWebTabWidget(QWidget *parent) - : QTabWidget(parent) -{ - QTabBar *tabBar = this->tabBar(); - tabBar->setTabsClosable(true); - tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); - //tabBar->setMovable(true); - tabBar->setContextMenuPolicy(Qt::NoContextMenu); - tabBar->setHidden(true); - connect(tabBar, &QTabBar::tabCloseRequested, this, &CWebTabWidget::closeTab); - //setDocumentMode(true); - setElideMode(Qt::ElideRight); -} - -CWebTabWidget::~CWebTabWidget() -{ - deleteAllCookie(); -} - -CWebEngineView *CWebTabWidget::currentWebView() const -{ - return webView(currentIndex()); -} - -void CWebTabWidget::setUrl(const QUrl &url) -{ - if (CWebEngineView *view = currentWebView()){ - view->setUrl(url); - view->setFocus(); - } -} - -void CWebTabWidget::updateCookie() -{ - -} - -CWebEngineView *CWebTabWidget::createTab() -{ - CWebEngineView *webView = createBackgroundTab(); - setCurrentWidget(webView); - if(count() > 1) - tabBar()->setHidden(false); - return webView; -} - -CWebEngineView *CWebTabWidget::createBackgroundTab() -{ - CWebEngineView *webView = new CWebEngineView; - QWebEnginePage *webPage = new QWebEnginePage(QWebEngineProfile::defaultProfile(), webView); - webView->setPage(webPage); - setupView(webView); - webView->setParentWidget(this); - addTab(webView, tr("")); - return webView; -} - -void CWebTabWidget::closeOtherTabs(int index) -{ - for (int i = count() - 1; i > index; --i) - closeTab(i); - for (int i = index - 1; i >= 0; --i) - closeTab(i); -} - -void CWebTabWidget::closeTab(int index) -{ - if (CWebEngineView *view = webView(index)) { - bool hasFocus = view->hasFocus(); - removeTab(index); - if (hasFocus && count() > 0) - currentWebView()->setFocus(); - if (count() == 0) - createTab(); - view->deleteLater(); - } - if (count() <= 1) - tabBar()->setHidden(true); -} - -CWebEngineView *CWebTabWidget::webView(int index) const -{ - return qobject_cast(widget(index)); -} - -void CWebTabWidget::setupView(CWebEngineView *webView) -{ - QWebEnginePage *webPage = webView->page(); -// connect(webView, &CWebEngineView::titleChanged, [this, webView](const QString &title) { -// int index = indexOf(webView); -// if (index != -1) { -// setTabText(index, title); -// setTabToolTip(index, title); -// } -// }); -// connect(webView, &CWebEngineView::favIconChanged, [this, webView](const QIcon &icon) { -// int index = indexOf(webView); -// if (index != -1) -// setTabIcon(index, icon); -// }); - connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() { - int index = indexOf(webView); - if (index >= 0) - closeTab(index); - }); -} - -void CWebTabWidget::deleteAllCookie() -{ - for(int i = 0; i < count(); ++i) - { - if (CWebEngineView *view = webView(i)) - { - view->page()->profile()->cookieStore()->deleteAllCookies(); - } - } -} +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "CWebTabWidget.h" +#include "CWebEngineView.h" + +CWebTabWidget::CWebTabWidget(QWidget *parent) + : QTabWidget(parent) +{ + QTabBar *tabBar = this->tabBar(); + tabBar->setTabsClosable(true); + tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); + //tabBar->setMovable(true); + tabBar->setContextMenuPolicy(Qt::NoContextMenu); + tabBar->setHidden(true); + connect(tabBar, &QTabBar::tabCloseRequested, this, &CWebTabWidget::closeTab); + //setDocumentMode(true); + setElideMode(Qt::ElideRight); +} + +CWebTabWidget::~CWebTabWidget() +{ + deleteAllCookie(); +} + +CWebEngineView *CWebTabWidget::currentWebView() const +{ + return webView(currentIndex()); +} + +void CWebTabWidget::setUrl(const QUrl &url) +{ + if (CWebEngineView *view = currentWebView()){ + view->setUrl(url); + view->setFocus(); + } +} + +void CWebTabWidget::updateCookie() +{ + +} + +CWebEngineView *CWebTabWidget::createTab() +{ + CWebEngineView *webView = createBackgroundTab(); + setCurrentWidget(webView); + if(count() > 1) + tabBar()->setHidden(false); + return webView; +} + +CWebEngineView *CWebTabWidget::createBackgroundTab() +{ + CWebEngineView *webView = new CWebEngineView; + QWebEnginePage *webPage = new QWebEnginePage(QWebEngineProfile::defaultProfile(), webView); + webView->setPage(webPage); + setupView(webView); + webView->setParentWidget(this); + addTab(webView, tr("")); + return webView; +} + +void CWebTabWidget::closeOtherTabs(int index) +{ + for (int i = count() - 1; i > index; --i) + closeTab(i); + for (int i = index - 1; i >= 0; --i) + closeTab(i); +} + +void CWebTabWidget::closeTab(int index) +{ + if (CWebEngineView *view = webView(index)) { + bool hasFocus = view->hasFocus(); + removeTab(index); + if (hasFocus && count() > 0) + currentWebView()->setFocus(); + if (count() == 0) + createTab(); + view->deleteLater(); + } + if (count() <= 1) + tabBar()->setHidden(true); +} + +CWebEngineView *CWebTabWidget::webView(int index) const +{ + return qobject_cast(widget(index)); +} + +void CWebTabWidget::setupView(CWebEngineView *webView) +{ + QWebEnginePage *webPage = webView->page(); +// connect(webView, &CWebEngineView::titleChanged, [this, webView](const QString &title) { +// int index = indexOf(webView); +// if (index != -1) { +// setTabText(index, title); +// setTabToolTip(index, title); +// } +// }); +// connect(webView, &CWebEngineView::favIconChanged, [this, webView](const QIcon &icon) { +// int index = indexOf(webView); +// if (index != -1) +// setTabIcon(index, icon); +// }); + connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() { + int index = indexOf(webView); + if (index >= 0) + closeTab(index); + }); +} + +void CWebTabWidget::deleteAllCookie() +{ + for(int i = 0; i < count(); ++i) + { + if (CWebEngineView *view = webView(i)) + { + view->page()->profile()->cookieStore()->deleteAllCookies(); + } + } +} diff --git a/product/src/gui/plugin/WebBrowserWidget/CWebTabWidget.h b/product/src/gui/plugin/WebBrowserWidget/CWebTabWidget.h index 3a8c7bd6..6208d68b 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CWebTabWidget.h +++ b/product/src/gui/plugin/WebBrowserWidget/CWebTabWidget.h @@ -1,31 +1,31 @@ -#ifndef CWEBTABWIDGET_H -#define CWEBTABWIDGET_H - -#include -#include - -class CWebEngineView; -class CWebTabWidget : public QTabWidget -{ - Q_OBJECT -public: - explicit CWebTabWidget(QWidget *parent = Q_NULLPTR); - ~CWebTabWidget(); - - CWebEngineView *currentWebView() const; - virtual void setUrl(const QUrl &url); - virtual void updateCookie(); - -public slots: - CWebEngineView *createTab(); - CWebEngineView *createBackgroundTab(); - void closeOtherTabs(int index); - void closeTab(int index); - -private: - CWebEngineView *webView(int index) const; - void setupView(CWebEngineView *webView); - void deleteAllCookie(); -}; - -#endif // CWEBTABWIDGET_H +#ifndef CWEBTABWIDGET_H +#define CWEBTABWIDGET_H + +#include +#include + +class CWebEngineView; +class CWebTabWidget : public QTabWidget +{ + Q_OBJECT +public: + explicit CWebTabWidget(QWidget *parent = Q_NULLPTR); + ~CWebTabWidget(); + + CWebEngineView *currentWebView() const; + virtual void setUrl(const QUrl &url); + virtual void updateCookie(); + +public slots: + CWebEngineView *createTab(); + CWebEngineView *createBackgroundTab(); + void closeOtherTabs(int index); + void closeTab(int index); + +private: + CWebEngineView *webView(int index) const; + void setupView(CWebEngineView *webView); + void deleteAllCookie(); +}; + +#endif // CWEBTABWIDGET_H diff --git a/product/src/gui/plugin/WebBrowserWidget/WebBrowserWidget.pro b/product/src/gui/plugin/WebBrowserWidget/WebBrowserWidget.pro index dfe12b20..93a8ecd3 100644 --- a/product/src/gui/plugin/WebBrowserWidget/WebBrowserWidget.pro +++ b/product/src/gui/plugin/WebBrowserWidget/WebBrowserWidget.pro @@ -1,67 +1,67 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-11-13T14:55:16 -# -#------------------------------------------------- - -QT += core gui webenginewidgets - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = WebBrowserWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CBrowserWidget.cpp \ - CBrowserPluginWidget.cpp \ -# main.cpp \ - CWebEngineView.cpp \ - CBiTabWidget.cpp \ - CWebTabWidget.cpp \ - CBiCookieManage.cpp \ - CEnergyTabWidget.cpp - -HEADERS += \ - CBrowserWidget.h \ - CBrowserPluginWidget.h \ - CWebEngineView.h \ - CBiTabWidget.h \ - CWebTabWidget.h \ - CBiCookieManage.h \ - CEnergyTabWidget.h - -RESOURCES += \ - resource.qrc - -LIBS += \ - -llog4cplus \ - -lpub_logger_api \ - -lrdb_net_api \ - -lperm_mng_api \ - -lpub_sysinfo_api \ - -lpub_utility_api -#LIBS += -lnet_msg_bus_api - -include($$PWD/../../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2018-11-13T14:55:16 +# +#------------------------------------------------- + +QT += core gui webenginewidgets + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = WebBrowserWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CBrowserWidget.cpp \ + CBrowserPluginWidget.cpp \ +# main.cpp \ + CWebEngineView.cpp \ + CBiTabWidget.cpp \ + CWebTabWidget.cpp \ + CBiCookieManage.cpp \ + CEnergyTabWidget.cpp + +HEADERS += \ + CBrowserWidget.h \ + CBrowserPluginWidget.h \ + CWebEngineView.h \ + CBiTabWidget.h \ + CWebTabWidget.h \ + CBiCookieManage.h \ + CEnergyTabWidget.h + +RESOURCES += \ + resource.qrc + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lrdb_net_api \ + -lperm_mng_api \ + -lpub_sysinfo_api \ + -lpub_utility_api +#LIBS += -lnet_msg_bus_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/WebBrowserWidget/main.cpp b/product/src/gui/plugin/WebBrowserWidget/main.cpp index 7f89d6e4..ec4b71a4 100644 --- a/product/src/gui/plugin/WebBrowserWidget/main.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/main.cpp @@ -1,37 +1,37 @@ -#include -#include "pub_logger_api/logger.h" -#include "service/perm_mng_api/PermMngApi.h" -#include "net/net_msg_bus_api/MsgBusApi.h" -#include "CBrowserWidget.h" - -int main(int argc, char *argv[]) -{ - qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "5566"); - kbd_public::StartLogSystem("", "hmi"); - if (!(kbd_net::initMsgBus("HMI", "HMI"))) - { - return -1; - } - kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); - if(!perm || PERM_NORMAL != perm->PermDllInit()) - { - return -1; - } - if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) - { - return -1; - } - - QApplication app(argc, argv); - - CBrowserWidget w(NULL,false); - w.show(); - w.init(); - w.loadHtml("http://192.168.77.189:1120/platform/pageManage"); - - app.exec(); - kbd_net::releaseMsgBus(); - kbd_public::StopLogSystem(); - - return 0; -} +#include +#include "pub_logger_api/logger.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "CBrowserWidget.h" + +int main(int argc, char *argv[]) +{ + qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "5566"); + kbd_public::StartLogSystem("", "hmi"); + if (!(kbd_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + kbd_service::CPermMngApiPtr perm = kbd_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + QApplication app(argc, argv); + + CBrowserWidget w(NULL,false); + w.show(); + w.init(); + w.loadHtml("http://192.168.77.189:1120/platform/pageManage"); + + app.exec(); + kbd_net::releaseMsgBus(); + kbd_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/WebBrowserWidget/resource.qrc b/product/src/gui/plugin/WebBrowserWidget/resource.qrc index 11adc760..1e1f60db 100644 --- a/product/src/gui/plugin/WebBrowserWidget/resource.qrc +++ b/product/src/gui/plugin/WebBrowserWidget/resource.qrc @@ -1,8 +1,8 @@ - - - resource/report.png - resource/error.png - resource/html.png - resource/refresh.png - - + + + resource/report.png + resource/error.png + resource/html.png + resource/refresh.png + + diff --git a/product/src/gui/plugin/WorkTicket/CWorkTicketManage.cpp b/product/src/gui/plugin/WorkTicket/CWorkTicketManage.cpp index 9cf555b0..aca8822b 100644 --- a/product/src/gui/plugin/WorkTicket/CWorkTicketManage.cpp +++ b/product/src/gui/plugin/WorkTicket/CWorkTicketManage.cpp @@ -1,197 +1,197 @@ -#include "CWorkTicketManage.h" -#include "ui_CWorkTicketManage.h" -#include "WorkTicketWidget.h" -#include -#include -#include -#include "pub_utility_api/FileStyle.h" - -CWorkTicketManage::CWorkTicketManage(QWidget *parent, bool editMode) : - QWidget(parent), - ui(new Ui::CWorkTicketManage) -{ - ui->setupUi(this); - - initStyleSheet(); - initTempTable(); - - if(!editMode) - { - initTempTableInfo(); - } -} - -CWorkTicketManage::~CWorkTicketManage() -{ - delete ui; -} - -void CWorkTicketManage::initTempTable() -{ - ui->m_tempTable->setColumnCount(3); - ui->m_tempTable->setRowCount(0); - ui->m_tempTable->setColumnWidth(0, 150); - ui->m_tempTable->setColumnWidth(1, 150); - ui->m_tempTable->horizontalHeader()->setStretchLastSection(true); - ui->m_tempTable->setHorizontalHeaderLabels(QStringList() << tr("名称") << tr("类型") << tr("文件路径")); - ui->m_tempTable->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->m_tempTable->setSelectionMode(QAbstractItemView::SingleSelection); - ui->m_tempTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->m_tempTable->setAlternatingRowColors(true); -} - -void CWorkTicketManage::initTempTableInfo() -{ - readTempInfo(); - - ui->m_tempTable->clearContents(); - ui->m_tempTable->setRowCount(0); - QMap::const_iterator iter = m_tempMap.constBegin(); - for(; iter != m_tempMap.constEnd(); ++iter) - { - foreach (QString file, iter.value()) { - int row = ui->m_tempTable->rowCount(); - ui->m_tempTable->insertRow(row); - - QString pre = m_typeMap.value(iter.key()); - - QTableWidgetItem *name = new QTableWidgetItem(QDir(file).dirName()); - QTableWidgetItem *type = new QTableWidgetItem(iter.key()); - QTableWidgetItem *path = new QTableWidgetItem(QString(pre+"%1"+file).arg(QDir::separator())); - -// name->setTextAlignment(Qt::AlignCenter); -// type->setTextAlignment(Qt::AlignCenter); - - ui->m_tempTable->setItem(row, 0, name); - ui->m_tempTable->setItem(row, 1, type); - ui->m_tempTable->setItem(row, 2, path); - } - } -} - -void CWorkTicketManage::readTempInfo() -{ - m_tempMap.clear(); - QDir dir; - dir.setPath(QCoreApplication::applicationDirPath() + QString("%1..%1..%1data%1work_ticket%1template").arg(QDir::separator())); - - QStringList typeList; - QStringList fileList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - foreach (QString file, fileList) { - typeList.append(file); - } - - foreach (QString type, typeList) { - QDir temp = dir; - temp.cd(type); - QStringList fileList = temp.entryList(QDir::Files); - if(fileList.isEmpty()) - { - continue; - } - m_tempMap.insert(type, fileList); - m_typeMap.insert(type, temp.absolutePath()); - } -} - -bool CWorkTicketManage::omPermCheck() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - //LOGERROR("权限接口初始化失败!"); - return false; - } - std::string tmpStr = "FUNC_NOM_OM"; - if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) - { - return false; - } - return true; -} - -void CWorkTicketManage::on_m_ticket_clicked() -{ - int row = ui->m_tempTable->currentRow(); - if(row < 0) - { - QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); - return; - } - - QString name = ui->m_tempTable->item(row, 0)->text(); - QString type = ui->m_tempTable->item(row, 1)->text(); - WorkTicketWidget *ticket = new WorkTicketWidget(this); - connect(ticket, &WorkTicketWidget::modelRefresh, this, [=]{ui->widget->reFresh();}); - ticket->setAttribute(Qt::WA_DeleteOnClose); - QString error = ticket->reloadXlsx(QString(type+"%1"+name).arg(QDir::separator())); - if(!error.isEmpty()) - { - QMessageBox::information(this,tr("提示"),error); - return; - } - ticket->setWindowFlag(Qt::WindowMaximizeButtonHint); - ticket->setMinimumSize(1000,800); - ticket->setModal(true); - ticket->show(); -} - -void CWorkTicketManage::on_m_delete_clicked() -{ - if(false == omPermCheck()) - { - QMessageBox::information(this,tr("提示"),tr("当前登录用户无运维管理功能权限!"),QMessageBox::Ok); - return; - } - - int row = ui->m_tempTable->currentRow(); - if(row < 0) - { - QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); - return; - } - - QString path = ui->m_tempTable->item(row, 2)->text(); - if(QMessageBox::question(this,tr("确认删除"),tr("是否删除 %1 ?").arg(path),QMessageBox::Ok,QMessageBox::Cancel) - == QMessageBox::Ok) - { - QDir dir; - if(dir.remove(path)) - { - ui->m_tempTable->removeRow(row); -// QMessageBox::information(this,tr("提示"),tr("删除成功"),QMessageBox::Ok); - } - else - { - QMessageBox::information(this,tr("提示"),tr("删除失败"),QMessageBox::Ok); - } - } -} - -void CWorkTicketManage::initStyleSheet() -{ - QString qss = QString(); - std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; - QFile qssfile1(QString::fromStdString(strFullPath)); - qssfile1.open(QFile::ReadOnly); - if (qssfile1.isOpen()) - { - qss += QLatin1String(qssfile1.readAll()); - //setStyleSheet(qss); - qssfile1.close(); - } - - strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("workTicket.qss") ; - QFile qssfile2(QString::fromStdString(strFullPath)); - qssfile2.open(QFile::ReadOnly); - if (qssfile2.isOpen()) - { - qss += QLatin1String(qssfile2.readAll()); - //setStyleSheet(qss); - qssfile2.close(); - } - if(!qss.isEmpty()) - { - setStyleSheet(qss); - } -} +#include "CWorkTicketManage.h" +#include "ui_CWorkTicketManage.h" +#include "WorkTicketWidget.h" +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + +CWorkTicketManage::CWorkTicketManage(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CWorkTicketManage) +{ + ui->setupUi(this); + + initStyleSheet(); + initTempTable(); + + if(!editMode) + { + initTempTableInfo(); + } +} + +CWorkTicketManage::~CWorkTicketManage() +{ + delete ui; +} + +void CWorkTicketManage::initTempTable() +{ + ui->m_tempTable->setColumnCount(3); + ui->m_tempTable->setRowCount(0); + ui->m_tempTable->setColumnWidth(0, 150); + ui->m_tempTable->setColumnWidth(1, 150); + ui->m_tempTable->horizontalHeader()->setStretchLastSection(true); + ui->m_tempTable->setHorizontalHeaderLabels(QStringList() << tr("名称") << tr("类型") << tr("文件路径")); + ui->m_tempTable->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->m_tempTable->setSelectionMode(QAbstractItemView::SingleSelection); + ui->m_tempTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->m_tempTable->setAlternatingRowColors(true); +} + +void CWorkTicketManage::initTempTableInfo() +{ + readTempInfo(); + + ui->m_tempTable->clearContents(); + ui->m_tempTable->setRowCount(0); + QMap::const_iterator iter = m_tempMap.constBegin(); + for(; iter != m_tempMap.constEnd(); ++iter) + { + foreach (QString file, iter.value()) { + int row = ui->m_tempTable->rowCount(); + ui->m_tempTable->insertRow(row); + + QString pre = m_typeMap.value(iter.key()); + + QTableWidgetItem *name = new QTableWidgetItem(QDir(file).dirName()); + QTableWidgetItem *type = new QTableWidgetItem(iter.key()); + QTableWidgetItem *path = new QTableWidgetItem(QString(pre+"%1"+file).arg(QDir::separator())); + +// name->setTextAlignment(Qt::AlignCenter); +// type->setTextAlignment(Qt::AlignCenter); + + ui->m_tempTable->setItem(row, 0, name); + ui->m_tempTable->setItem(row, 1, type); + ui->m_tempTable->setItem(row, 2, path); + } + } +} + +void CWorkTicketManage::readTempInfo() +{ + m_tempMap.clear(); + QDir dir; + dir.setPath(QCoreApplication::applicationDirPath() + QString("%1..%1..%1data%1work_ticket%1template").arg(QDir::separator())); + + QStringList typeList; + QStringList fileList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + foreach (QString file, fileList) { + typeList.append(file); + } + + foreach (QString type, typeList) { + QDir temp = dir; + temp.cd(type); + QStringList fileList = temp.entryList(QDir::Files); + if(fileList.isEmpty()) + { + continue; + } + m_tempMap.insert(type, fileList); + m_typeMap.insert(type, temp.absolutePath()); + } +} + +bool CWorkTicketManage::omPermCheck() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + //LOGERROR("权限接口初始化失败!"); + return false; + } + std::string tmpStr = "FUNC_NOM_OM"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + return false; + } + return true; +} + +void CWorkTicketManage::on_m_ticket_clicked() +{ + int row = ui->m_tempTable->currentRow(); + if(row < 0) + { + QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); + return; + } + + QString name = ui->m_tempTable->item(row, 0)->text(); + QString type = ui->m_tempTable->item(row, 1)->text(); + WorkTicketWidget *ticket = new WorkTicketWidget(this); + connect(ticket, &WorkTicketWidget::modelRefresh, this, [=]{ui->widget->reFresh();}); + ticket->setAttribute(Qt::WA_DeleteOnClose); + QString error = ticket->reloadXlsx(QString(type+"%1"+name).arg(QDir::separator())); + if(!error.isEmpty()) + { + QMessageBox::information(this,tr("提示"),error); + return; + } + ticket->setWindowFlag(Qt::WindowMaximizeButtonHint); + ticket->setMinimumSize(1000,800); + ticket->setModal(true); + ticket->show(); +} + +void CWorkTicketManage::on_m_delete_clicked() +{ + if(false == omPermCheck()) + { + QMessageBox::information(this,tr("提示"),tr("当前登录用户无运维管理功能权限!"),QMessageBox::Ok); + return; + } + + int row = ui->m_tempTable->currentRow(); + if(row < 0) + { + QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); + return; + } + + QString path = ui->m_tempTable->item(row, 2)->text(); + if(QMessageBox::question(this,tr("确认删除"),tr("是否删除 %1 ?").arg(path),QMessageBox::Ok,QMessageBox::Cancel) + == QMessageBox::Ok) + { + QDir dir; + if(dir.remove(path)) + { + ui->m_tempTable->removeRow(row); +// QMessageBox::information(this,tr("提示"),tr("删除成功"),QMessageBox::Ok); + } + else + { + QMessageBox::information(this,tr("提示"),tr("删除失败"),QMessageBox::Ok); + } + } +} + +void CWorkTicketManage::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = kbd_public::CFileStyle::getPathOfStyleFile("workTicket.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} diff --git a/product/src/gui/plugin/WorkTicket/CWorkTicketManage.h b/product/src/gui/plugin/WorkTicket/CWorkTicketManage.h index 8ae9477d..10e04dd7 100644 --- a/product/src/gui/plugin/WorkTicket/CWorkTicketManage.h +++ b/product/src/gui/plugin/WorkTicket/CWorkTicketManage.h @@ -1,37 +1,37 @@ -#ifndef CWORKTICKETMANAGE_H -#define CWORKTICKETMANAGE_H - -#include -#include - -namespace Ui { -class CWorkTicketManage; -} - -class CWorkTicketManage : public QWidget -{ - Q_OBJECT - -public: - explicit CWorkTicketManage(QWidget *parent = 0, bool editMode = false); - ~CWorkTicketManage(); - -private slots: - void on_m_ticket_clicked(); - void on_m_delete_clicked(); - -private: - void initStyleSheet(); - void initTempTable(); - void initTempTableInfo(); - void readTempInfo(); - bool omPermCheck(); - -private: - Ui::CWorkTicketManage *ui; - - QMap m_tempMap; - QMap m_typeMap; -}; - -#endif // CWORKTICKETMANAGE_H +#ifndef CWORKTICKETMANAGE_H +#define CWORKTICKETMANAGE_H + +#include +#include + +namespace Ui { +class CWorkTicketManage; +} + +class CWorkTicketManage : public QWidget +{ + Q_OBJECT + +public: + explicit CWorkTicketManage(QWidget *parent = 0, bool editMode = false); + ~CWorkTicketManage(); + +private slots: + void on_m_ticket_clicked(); + void on_m_delete_clicked(); + +private: + void initStyleSheet(); + void initTempTable(); + void initTempTableInfo(); + void readTempInfo(); + bool omPermCheck(); + +private: + Ui::CWorkTicketManage *ui; + + QMap m_tempMap; + QMap m_typeMap; +}; + +#endif // CWORKTICKETMANAGE_H diff --git a/product/src/gui/plugin/WorkTicket/CWorkTicketManage.ui b/product/src/gui/plugin/WorkTicket/CWorkTicketManage.ui index 770c13e5..8d288434 100644 --- a/product/src/gui/plugin/WorkTicket/CWorkTicketManage.ui +++ b/product/src/gui/plugin/WorkTicket/CWorkTicketManage.ui @@ -1,137 +1,137 @@ - - - CWorkTicketManage - - - - 0 - 0 - 814 - 546 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - 1 - - - - 票库管理 - - - - 9 - - - 9 - - - 9 - - - 9 - - - 6 - - - - - - - - Qt::Horizontal - - - - 526 - 20 - - - - - - - - 开票 - - - - - - - 删除 - - - - - - - - 开票记录 - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - HistoryWidget - QWidget -
HistoryWidget.h
- 1 -
-
- - -
+ + + CWorkTicketManage + + + + 0 + 0 + 814 + 546 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 1 + + + + 票库管理 + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + + + + Qt::Horizontal + + + + 526 + 20 + + + + + + + + 开票 + + + + + + + 删除 + + + + + + + + 开票记录 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + HistoryWidget + QWidget +
HistoryWidget.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.cpp b/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.cpp index dfbe111f..24b547d1 100644 --- a/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.cpp +++ b/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.cpp @@ -1,27 +1,27 @@ -#include -#include "CWorkTicketPluginWidget.h" -#include "CWorkTicketManage.h" - -CWorkTicketPluginWidget::CWorkTicketPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CWorkTicketPluginWidget::~CWorkTicketPluginWidget() -{ - -} - -bool CWorkTicketPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec) -{ - Q_UNUSED(ptrVec) - CWorkTicketManage *pWidget = new CWorkTicketManage(parent,editMode); - *widget = (QWidget *)pWidget; - *workTicketWidget = (IPluginWidget *)pWidget; - return true; -} - -void CWorkTicketPluginWidget::release() -{ - -} +#include +#include "CWorkTicketPluginWidget.h" +#include "CWorkTicketManage.h" + +CWorkTicketPluginWidget::CWorkTicketPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CWorkTicketPluginWidget::~CWorkTicketPluginWidget() +{ + +} + +bool CWorkTicketPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CWorkTicketManage *pWidget = new CWorkTicketManage(parent,editMode); + *widget = (QWidget *)pWidget; + *workTicketWidget = (IPluginWidget *)pWidget; + return true; +} + +void CWorkTicketPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.h b/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.h index 5b514aa2..1a71c47c 100644 --- a/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.h +++ b/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.h @@ -1,22 +1,22 @@ -#ifndef CWORKTICKETPLUGINWIDGET_H -#define CWORKTICKETPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CWorkTicketPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CWorkTicketPluginWidget(QObject *parent = 0); - ~CWorkTicketPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec); - void release(); -}; - -#endif //CWORKTICKETPLUGINWIDGET_H - +#ifndef CWORKTICKETPLUGINWIDGET_H +#define CWORKTICKETPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CWorkTicketPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CWorkTicketPluginWidget(QObject *parent = 0); + ~CWorkTicketPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **workTicketWidget, QVector ptrVec); + void release(); +}; + +#endif //CWORKTICKETPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/WorkTicket/HistoryWidget.cpp b/product/src/gui/plugin/WorkTicket/HistoryWidget.cpp index c53d3281..098bd144 100644 --- a/product/src/gui/plugin/WorkTicket/HistoryWidget.cpp +++ b/product/src/gui/plugin/WorkTicket/HistoryWidget.cpp @@ -1,153 +1,153 @@ -#include "HistoryWidget.h" -#include "kbdtable.h" -#include -#include -#include -#include -#include -#include "../model_common/common.h" -#include "kbdtabledatamgr.h" -#include "kbddbdesign.h" -#include -#include -#include -#include "WorkTicketWidget.h" - -HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent) -{ - initLayout(); - initData(); -} - -void HistoryWidget::initLayout() -{ - QLabel *labelBegin = new QLabel(tr("开始时间"),this); - QLabel *labelEnd = new QLabel(tr("结束时间"),this); - m_dtBeging = new QDateTimeEdit(this); - m_dtEnd = new QDateTimeEdit(this); - QPushButton *btQuery = new QPushButton(tr("查询"),this); - QPushButton *btTicket = new QPushButton(tr("重开"),this); - btTicket->setObjectName("m_reTicket"); - m_table = new KbdTable(this); - m_table->setColumnWidth(0, 150); - m_table->setColumnWidth(1, 150); - m_table->horizontalHeader()->setStretchLastSection(true); - m_table->setSelectionBehavior(QAbstractItemView::SelectRows); - m_table->setSelectionMode(QAbstractItemView::SingleSelection); - m_table->setEditTriggers(QAbstractItemView::NoEditTriggers); - - QHBoxLayout *hLayout = new QHBoxLayout; - hLayout->addWidget(labelBegin); - hLayout->addWidget(m_dtBeging); - hLayout->addWidget(labelEnd); - hLayout->addWidget(m_dtEnd); - hLayout->addWidget(btQuery); - hLayout->addStretch(); - - QHBoxLayout *btnLayout = new QHBoxLayout; - btnLayout->addStretch(); - btnLayout->addWidget(btTicket); - - QVBoxLayout *vLayout = new QVBoxLayout; - vLayout->addLayout(hLayout); - vLayout->addWidget(m_table); - vLayout->addLayout(btnLayout); - setLayout(vLayout); - - connect(btQuery,SIGNAL(clicked(bool)),this,SLOT(onQuery())); - connect(btTicket,SIGNAL(clicked(bool)),this,SLOT(onTicket())); -} - -void HistoryWidget::initData() -{ - KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); - - //降序获取创建时间最前的500条 - QString filter = QString("%1 <> 0 ORDER BY %1 DESC LIMIT 500").arg(CN_CREATE_TIME); - KbdTableModel *model = KbdTableDataMgr::getInstance()->createModel( - Common::createViewName(TBL_HIS_WORK_TICKET,filter)); - m_table->setModel(model); - m_table->setColumnWidth(0, 150); - m_table->setColumnWidth(1, 150); - - QDateTime dt = QDateTime::currentDateTime(); - quint64 secs = dt.toSecsSinceEpoch(); - m_dtBeging->setDateTime(QDateTime::fromSecsSinceEpoch(secs - 24*60*60)); - m_dtEnd->setDateTime(QDateTime::fromSecsSinceEpoch(secs + 24*60*60)); -} - -void HistoryWidget::reFresh() -{ - if(m_table) - { - m_table->reFresh(); - m_table->setColumnWidth(0, 150); - m_table->setColumnWidth(1, 150); - } -} - -void HistoryWidget::onQuery() -{ - quint64 dt1Secs = m_dtBeging->dateTime().toSecsSinceEpoch(); - quint64 dt2Secs = m_dtEnd->dateTime().toSecsSinceEpoch(); - QString filter = QString("CREATE_TIME > '%1' AND CREATE_TIME < '%2' ORDER BY CREATE_TIME DESC LIMIT 10000") - .arg(dt1Secs).arg(dt2Secs); - - m_table->setModel(KbdTableDataMgr::getInstance()->createModel( - Common::createViewName(TBL_HIS_WORK_TICKET,filter))); - m_table->setColumnWidth(0, 150); - m_table->setColumnWidth(1, 150); - //最多加载1W条,超出则提示 - KbdDbDesign ds; - int count = 0; - bool isNULL = false; - QString sql = QString("SELECT count(*) FROM HIS_WORK_TICKET WHERE CREATE_TIME > '%1' AND CREATE_TIME < '%2';") - .arg(dt1Secs).arg(dt2Secs); - if(!ds.getMax(sql,count,isNULL)) - { - QMessageBox::information(this,tr("消息"),tr("链接数据库错误")); - return; - } - - if(count > 10000) - { - QMessageBox::information(this,tr("消息"),tr("历史数据过多!表格仅展示查询结果的10000条\n" - "更多数据查看,请缩小起始时间和结束时间之差")); - return; - } - -} - -void HistoryWidget::onTicket() -{ - QModelIndex index= m_table->currentIndex(); - if(index.row() < 0) - { - QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); - return; - } - - QString path = m_table->model()->data(m_table->model()->index(index.row(),2)).toString(); - QStringList list = path.split("/"); - if(list.length() < 2) - { - return; - } - QString name = list.takeLast(); - QString type = list.takeLast(); - - WorkTicketWidget *ticket = new WorkTicketWidget(this); - connect(ticket, &WorkTicketWidget::modelRefresh, this, [=]{reFresh();}); - ticket->setAttribute(Qt::WA_DeleteOnClose); - QString error = ticket->reloadXlsx(QString(type+"%1"+name).arg(QDir::separator()),true); - if(!error.isEmpty()) - { - QMessageBox::information(this,tr("提示"),error); - return; - } - ticket->setWindowFlag(Qt::WindowMaximizeButtonHint); - ticket->setMinimumSize(1000,800); - ticket->setSaveVisible(false); - ticket->setModal(true); - ticket->show(); -} +#include "HistoryWidget.h" +#include "kbdtable.h" +#include +#include +#include +#include +#include +#include "../model_common/common.h" +#include "kbdtabledatamgr.h" +#include "kbddbdesign.h" +#include +#include +#include +#include "WorkTicketWidget.h" + +HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent) +{ + initLayout(); + initData(); +} + +void HistoryWidget::initLayout() +{ + QLabel *labelBegin = new QLabel(tr("开始时间"),this); + QLabel *labelEnd = new QLabel(tr("结束时间"),this); + m_dtBeging = new QDateTimeEdit(this); + m_dtEnd = new QDateTimeEdit(this); + QPushButton *btQuery = new QPushButton(tr("查询"),this); + QPushButton *btTicket = new QPushButton(tr("重开"),this); + btTicket->setObjectName("m_reTicket"); + m_table = new KbdTable(this); + m_table->setColumnWidth(0, 150); + m_table->setColumnWidth(1, 150); + m_table->horizontalHeader()->setStretchLastSection(true); + m_table->setSelectionBehavior(QAbstractItemView::SelectRows); + m_table->setSelectionMode(QAbstractItemView::SingleSelection); + m_table->setEditTriggers(QAbstractItemView::NoEditTriggers); + + QHBoxLayout *hLayout = new QHBoxLayout; + hLayout->addWidget(labelBegin); + hLayout->addWidget(m_dtBeging); + hLayout->addWidget(labelEnd); + hLayout->addWidget(m_dtEnd); + hLayout->addWidget(btQuery); + hLayout->addStretch(); + + QHBoxLayout *btnLayout = new QHBoxLayout; + btnLayout->addStretch(); + btnLayout->addWidget(btTicket); + + QVBoxLayout *vLayout = new QVBoxLayout; + vLayout->addLayout(hLayout); + vLayout->addWidget(m_table); + vLayout->addLayout(btnLayout); + setLayout(vLayout); + + connect(btQuery,SIGNAL(clicked(bool)),this,SLOT(onQuery())); + connect(btTicket,SIGNAL(clicked(bool)),this,SLOT(onTicket())); +} + +void HistoryWidget::initData() +{ + KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); + + //降序获取创建时间最前的500条 + QString filter = QString("%1 <> 0 ORDER BY %1 DESC LIMIT 500").arg(CN_CREATE_TIME); + KbdTableModel *model = KbdTableDataMgr::getInstance()->createModel( + Common::createViewName(TBL_HIS_WORK_TICKET,filter)); + m_table->setModel(model); + m_table->setColumnWidth(0, 150); + m_table->setColumnWidth(1, 150); + + QDateTime dt = QDateTime::currentDateTime(); + quint64 secs = dt.toSecsSinceEpoch(); + m_dtBeging->setDateTime(QDateTime::fromSecsSinceEpoch(secs - 24*60*60)); + m_dtEnd->setDateTime(QDateTime::fromSecsSinceEpoch(secs + 24*60*60)); +} + +void HistoryWidget::reFresh() +{ + if(m_table) + { + m_table->reFresh(); + m_table->setColumnWidth(0, 150); + m_table->setColumnWidth(1, 150); + } +} + +void HistoryWidget::onQuery() +{ + quint64 dt1Secs = m_dtBeging->dateTime().toSecsSinceEpoch(); + quint64 dt2Secs = m_dtEnd->dateTime().toSecsSinceEpoch(); + QString filter = QString("CREATE_TIME > '%1' AND CREATE_TIME < '%2' ORDER BY CREATE_TIME DESC LIMIT 10000") + .arg(dt1Secs).arg(dt2Secs); + + m_table->setModel(KbdTableDataMgr::getInstance()->createModel( + Common::createViewName(TBL_HIS_WORK_TICKET,filter))); + m_table->setColumnWidth(0, 150); + m_table->setColumnWidth(1, 150); + //最多加载1W条,超出则提示 + KbdDbDesign ds; + int count = 0; + bool isNULL = false; + QString sql = QString("SELECT count(*) FROM HIS_WORK_TICKET WHERE CREATE_TIME > '%1' AND CREATE_TIME < '%2';") + .arg(dt1Secs).arg(dt2Secs); + if(!ds.getMax(sql,count,isNULL)) + { + QMessageBox::information(this,tr("消息"),tr("链接数据库错误")); + return; + } + + if(count > 10000) + { + QMessageBox::information(this,tr("消息"),tr("历史数据过多!表格仅展示查询结果的10000条\n" + "更多数据查看,请缩小起始时间和结束时间之差")); + return; + } + +} + +void HistoryWidget::onTicket() +{ + QModelIndex index= m_table->currentIndex(); + if(index.row() < 0) + { + QMessageBox::information(this,tr("提示"),tr("请选中一条记录!"),QMessageBox::Ok); + return; + } + + QString path = m_table->model()->data(m_table->model()->index(index.row(),2)).toString(); + QStringList list = path.split("/"); + if(list.length() < 2) + { + return; + } + QString name = list.takeLast(); + QString type = list.takeLast(); + + WorkTicketWidget *ticket = new WorkTicketWidget(this); + connect(ticket, &WorkTicketWidget::modelRefresh, this, [=]{reFresh();}); + ticket->setAttribute(Qt::WA_DeleteOnClose); + QString error = ticket->reloadXlsx(QString(type+"%1"+name).arg(QDir::separator()),true); + if(!error.isEmpty()) + { + QMessageBox::information(this,tr("提示"),error); + return; + } + ticket->setWindowFlag(Qt::WindowMaximizeButtonHint); + ticket->setMinimumSize(1000,800); + ticket->setSaveVisible(false); + ticket->setModal(true); + ticket->show(); +} diff --git a/product/src/gui/plugin/WorkTicket/HistoryWidget.h b/product/src/gui/plugin/WorkTicket/HistoryWidget.h index 46189391..585aa934 100644 --- a/product/src/gui/plugin/WorkTicket/HistoryWidget.h +++ b/product/src/gui/plugin/WorkTicket/HistoryWidget.h @@ -1,28 +1,28 @@ -#ifndef HISTORYWIDGET_H -#define HISTORYWIDGET_H - -#include - -class QDateTimeEdit; -class KbdTable; -class HistoryWidget : public QWidget -{ - Q_OBJECT -public: - explicit HistoryWidget(QWidget *parent = nullptr); - - void reFresh(); -private: - void initLayout(); - void initData(); - - QDateTimeEdit *m_dtBeging; - QDateTimeEdit *m_dtEnd; - KbdTable *m_table; - -private slots: - void onQuery(); - void onTicket(); -}; - -#endif // HISTORYWIDGET_H +#ifndef HISTORYWIDGET_H +#define HISTORYWIDGET_H + +#include + +class QDateTimeEdit; +class KbdTable; +class HistoryWidget : public QWidget +{ + Q_OBJECT +public: + explicit HistoryWidget(QWidget *parent = nullptr); + + void reFresh(); +private: + void initLayout(); + void initData(); + + QDateTimeEdit *m_dtBeging; + QDateTimeEdit *m_dtEnd; + KbdTable *m_table; + +private slots: + void onQuery(); + void onTicket(); +}; + +#endif // HISTORYWIDGET_H diff --git a/product/src/gui/plugin/WorkTicket/WorkTicket.pro b/product/src/gui/plugin/WorkTicket/WorkTicket.pro index 9557219e..50f2d0a6 100644 --- a/product/src/gui/plugin/WorkTicket/WorkTicket.pro +++ b/product/src/gui/plugin/WorkTicket/WorkTicket.pro @@ -1,69 +1,69 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-12-10T17:07:14 -# -#------------------------------------------------- - -QT += widgets sql - -TARGET = WorkTicket -TEMPLATE = lib - - -INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx \ - $$PWD/../../../../../platform/src/include/tools/model_common \ - $$PWD/../../../../../platform/src/include/tools/model_table - -LIBS += -lmodel_excel -LIBS += -lmodel_common -LIBS += -lmodel_table -LIBS += -llog4cplus -LIBS += -lpub_logger_api -LIBS += -lpub_utility_api -LIBS += -lperm_mng_api -LIBS += -lrdb_api -lrdb_net_api -LIBS += -lprotobuf -LIBS += -lsys_file_sync_api - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -SOURCES += \ - WorkTicketWidget.cpp \ - xlsxsheetmodel.cpp \ - CWorkTicketPluginWidget.cpp \ - CWorkTicketManage.cpp \ - HistoryWidget.cpp - -HEADERS += \ - WorkTicketWidget.h \ - xlsxsheetmodel.h \ - xlsxsheetmodel_p.h \ - CWorkTicketPluginWidget.h \ - CWorkTicketManage.h \ - HistoryWidget.h - -unix { - target.path = /usr/lib - INSTALLS += target -} - -FORMS += \ - CWorkTicketManage.ui - - -include($$PWD/../../../idl_files/idl_files.pri) - -exists($$PWD/../../../common.pri) { - include($$PWD/../../../common.pri) -}else { - error("FATAL error: connot find common.pri") +#------------------------------------------------- +# +# Project created by QtCreator 2018-12-10T17:07:14 +# +#------------------------------------------------- + +QT += widgets sql + +TARGET = WorkTicket +TEMPLATE = lib + + +INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx \ + $$PWD/../../../../../platform/src/include/tools/model_common \ + $$PWD/../../../../../platform/src/include/tools/model_table + +LIBS += -lmodel_excel +LIBS += -lmodel_common +LIBS += -lmodel_table +LIBS += -llog4cplus +LIBS += -lpub_logger_api +LIBS += -lpub_utility_api +LIBS += -lperm_mng_api +LIBS += -lrdb_api -lrdb_net_api +LIBS += -lprotobuf +LIBS += -lsys_file_sync_api + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + WorkTicketWidget.cpp \ + xlsxsheetmodel.cpp \ + CWorkTicketPluginWidget.cpp \ + CWorkTicketManage.cpp \ + HistoryWidget.cpp + +HEADERS += \ + WorkTicketWidget.h \ + xlsxsheetmodel.h \ + xlsxsheetmodel_p.h \ + CWorkTicketPluginWidget.h \ + CWorkTicketManage.h \ + HistoryWidget.h + +unix { + target.path = /usr/lib + INSTALLS += target +} + +FORMS += \ + CWorkTicketManage.ui + + +include($$PWD/../../../idl_files/idl_files.pri) + +exists($$PWD/../../../common.pri) { + include($$PWD/../../../common.pri) +}else { + error("FATAL error: connot find common.pri") } \ No newline at end of file diff --git a/product/src/gui/plugin/WorkTicket/WorkTicketWidget.cpp b/product/src/gui/plugin/WorkTicket/WorkTicketWidget.cpp index ae3dcab5..c302de7a 100644 --- a/product/src/gui/plugin/WorkTicket/WorkTicketWidget.cpp +++ b/product/src/gui/plugin/WorkTicket/WorkTicketWidget.cpp @@ -1,542 +1,542 @@ -#include "WorkTicketWidget.h" -#include -#include -#include -#include -#include -#include -#include "xlsxdocument.h" -#include "xlsxworksheet.h" -#include "xlsxcellrange.h" -#include "xlsxsheetmodel.h" -#include -#include -#include "HistoryWidget.h" -#include -#include "kbdtabledatamgr.h" -#include "../model_common/common.h" -#include -#include -#include -#include -#include -#include - -using namespace QXlsx; - - -WorkTicketWidget::WorkTicketWidget(QWidget *parent) : QDialog(parent) -{ - m_doc = NULL; - m_editFilePath = ""; - m_tempFilePath = ""; - initLayout(); - m_rtdbAccess = new kbd_dbms::CRdbAccess(); -// initTableModel(); -} - -WorkTicketWidget::~WorkTicketWidget() -{ - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; -} - -void WorkTicketWidget::initLayout() -{ - QVBoxLayout *vLayout = new QVBoxLayout; - m_tabXlsx = new QTabWidget(this); - - QHBoxLayout *hLayout = new QHBoxLayout; - m_sign = new QCheckBox(tr("电子签章"), this); - m_save = new QPushButton(tr("保存"),this); - m_btPrint = new QPushButton(tr("出票"),this); - m_save->setMinimumHeight(35); - m_btPrint->setMinimumHeight(35); - hLayout->addWidget(m_sign); - hLayout->addStretch(); - hLayout->addWidget(m_save); - hLayout->addSpacing(50); - hLayout->addWidget(m_btPrint); - hLayout->addStretch(); - hLayout->setContentsMargins(10,0,120,0); - - vLayout->addWidget(m_tabXlsx); - vLayout->addLayout(hLayout); - vLayout->addSpacing(15); - setLayout(vLayout); - vLayout->setContentsMargins(0,0,0,0); - setContentsMargins(0,0,0,0); - - connect(m_save,SIGNAL(clicked(bool)),this,SLOT(onSave())); - connect(m_btPrint,SIGNAL(clicked(bool)),this,SLOT(onPrint())); -} - -void WorkTicketWidget::initTableModel() -{ -// QSettings settings("KbdSoft.ZHJK","ISCS6000.tools"); -// KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::DirectLink, -// settings.value("login/user","root").toString(), -// settings.value("login/psw","kbdct@0755").toString(), -// settings.value("login/ip","192.168.190.128").toString(), -// settings.value("login/port","3306").toInt(), -// settings.value("login/dbname","ISCS6000").toString(), -// DataBaseInterface::MySql -// ); - KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); -} - -void WorkTicketWidget::elecSignature() -{ - QTableView *table; - QModelIndex index; - QString cell; - for(int i = 0; i < m_tabXlsx->count(); i++) - { - table = qobject_cast(m_tabXlsx->widget(i)); - if(table) - { - for(int row = 0; row < table->model()->rowCount(); row++) - { - for(int col = 0; col < table->model()->columnCount(); col++) - { - index = table->model()->index(row,col); - cell = table->model()->data(index).toString(); - //< (签章)翻译与工作票模板需匹配 - if(cell.endsWith(tr("(签章)"), Qt::CaseInsensitive)) - { - cell.replace(tr("(签章)"), ""); - int perm_id = readUserId(cell); - if(perm_id == -1) - { - continue; - } - QByteArray byte = readSignatureData(perm_id); - table->model()->setData(index, QString(byte), Qt::BackgroundRole); - } - } - } - } - } -} - -void WorkTicketWidget::setFiled(const QMap &mapFiled) -{ - //遍历TABLE - QTableView *table; - QModelIndex index; - QString cell; - for(int i = 0; i < m_tabXlsx->count(); i++) - { - table = qobject_cast(m_tabXlsx->widget(i)); - if(table) - { - for(int row = 0; row < table->model()->rowCount(); row++) - { - for(int col = 0; col < table->model()->columnCount(); col++) - { - index = table->model()->index(row,col); - cell = table->model()->data(index).toString(); - if(replaceFiled(mapFiled,cell)) - { - table->model()->setData(index,cell); - } - } - } - } - } - -} - -bool WorkTicketWidget::replaceFiled(const QMap &mapFiled, QString &content) -{ - bool ret = false; - foreach (QString key, mapFiled.keys()) { - if(content.contains(key)) - { - content.replace(key,mapFiled.value(key),Qt::CaseSensitive); - ret = true; - } - } - - return ret; -} - -QString WorkTicketWidget::copyTempToHistory(const QString &tempFileName) -{ - //FIX -// xx判断路径是否存在,不存在创建路径 - QStringList tempList = tempFileName.split(QDir::separator()); - tempList.removeLast(); - QString dirPath = Common::getIscsHome()+ "/data/work_ticket/history/" + tempList.join(QDir::separator()); - QDir dir(dirPath); - if(!dir.exists()) - { - if(!dir.mkpath(dirPath)) - return tr("创建目录失败: %1").arg(dirPath); - } - m_tempFilePath = Common::getIscsHome() + "/data/work_ticket/template/" + tempFileName; - QFileInfo info(m_tempFilePath); - m_editFilePath = dirPath + "/" + info.fileName(); - if(QFile::exists(m_editFilePath)) - { - if(!QFile::remove(m_editFilePath)) - { - QString tmp = m_editFilePath; - m_editFilePath = ""; - m_tempFilePath = ""; - return tr("请先关闭文件: %1").arg(tmp); - } - } - - if(!QFile::copy(m_tempFilePath,m_editFilePath)) - { - QString tmp = m_editFilePath; - m_editFilePath = ""; - m_tempFilePath = ""; - return tr("请先关闭文件: %1").arg(tmp); - } - - return ""; -} - -QString WorkTicketWidget::copyHisToHistory(const QString &tempFileName) -{ - QString dirPath = Common::getIscsHome()+ "/data/work_ticket/history/" + tempFileName; - if(!QFile::exists(dirPath)) - { - return tr("历史票不存在!").arg(tempFileName); - } - - m_tempFilePath = dirPath; - m_editFilePath = dirPath.section("_",0,-7) + ".xlsx"; - if(QFile::exists(m_editFilePath)) - { - if(!QFile::remove(m_editFilePath)) - { - QString tmp = m_editFilePath; - m_editFilePath = ""; - m_tempFilePath = ""; - return tr("请先关闭文件: %1").arg(tmp); - } - } - - if(!QFile::copy(m_tempFilePath,m_editFilePath)) - { - QString tmp = m_editFilePath; - m_editFilePath = ""; - m_tempFilePath = ""; - return tr("请先关闭文件: %1").arg(tmp); - } - return ""; -} - -bool WorkTicketWidget::updateUser() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - int UserId,UserGrpId,Level,LoginSec; - std::string InstanceName; - if(PERM_NORMAL != permMngPtr->CurUser(UserId,UserGrpId,Level,LoginSec,InstanceName)) - { - return false; - } - m_user = readUserAlias(UserId); - return true; -} - -bool WorkTicketWidget::omPermCheck() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) - { - LOGERROR("权限接口初始化失败!"); - return false; - } - std::string tmpStr = "FUNC_NOM_OM"; - if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) - { - return false; - } - return true; -} - -QString WorkTicketWidget::readUserAlias(int UserId) -{ - QString ret = QString(); - if(m_rtdbAccess->open("base", "rm_user_def")) - { - CTableLockGuard locker(*m_rtdbAccess); - CONDINFO conditionID; - memcpy(conditionID.name,"perm_id", strlen("perm_id")); - conditionID.logicalop = ATTRCOND_OR; - conditionID.relationop = ATTRCOND_EQU; - conditionID.conditionval = UserId; - - CRdbQueryResult result; - std::vector columns; - columns.push_back("perm_alias"); - if(m_rtdbAccess->select(conditionID, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType alias; - result.getColumnValue(nIndex, 0, alias); - ret = QString::fromStdString(alias.toStdString()); - } - } - } - - m_rtdbAccess->close(); - return ret; -} - -int WorkTicketWidget::readUserId(const QString &alias) -{ - int ret = -1; - if(m_rtdbAccess->open("base", "rm_user_def")) - { - CTableLockGuard locker(*m_rtdbAccess); - CONDINFO conditionID; - memcpy(conditionID.name, "perm_alias",strlen("perm_alias") ); - conditionID.logicalop = ATTRCOND_OR; - conditionID.relationop = ATTRCOND_EQU; - conditionID.conditionval = alias.toStdString(); - - CRdbQueryResult result; - std::vector columns; - columns.push_back("perm_id"); - if(m_rtdbAccess->select(conditionID, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - CVarType permId; - result.getColumnValue(nIndex, 0, permId); - ret = permId.toInt(); - } - } - } - - m_rtdbAccess->close(); - return ret; -} - -QByteArray WorkTicketWidget::readSignatureData(int perm_id) -{ - QString sql = QString("select * from rm_user_signature_info where USER_ID = '%1';").arg(perm_id); - QSqlQuery result; - KbdTableDataMgr::getInstance()->selectOnly(sql, result); - - QByteArray signData; - while(result.next()) - { - signData = result.value("DATA_BASE64").toString().toLatin1(); - } - return signData; -} - -QString WorkTicketWidget::reloadXlsx(const QString &tempFileName, bool isReTick) -{ - QString error; - if(isReTick) - { - error = copyHisToHistory(tempFileName); - if(!error.isEmpty()) - return error; - } - else - { - error = copyTempToHistory(tempFileName); - if(!error.isEmpty()) - return error; - } - //delete tab - QList widgets; - for(int i = 0; i < m_tabXlsx->count(); i++) - { - widgets << m_tabXlsx->widget(i); - } - m_tabXlsx->clear(); - foreach (QWidget *w, widgets) { - w->deleteLater(); - } - widgets.clear(); - if(m_doc != NULL) - { - m_doc->deleteLater(); - m_doc = NULL; - } - //load - m_tabXlsx->setTabPosition(QTabWidget::South); - m_doc = new Document(m_editFilePath,this); - - foreach (QString sheetName, m_doc->sheetNames()) { - Worksheet *sheet = dynamic_cast(m_doc->sheet(sheetName)); - if (sheet) { - QTableView *view = new QTableView(m_tabXlsx); - view->setModel(new SheetModel(sheet, view)); - foreach (CellRange range, sheet->mergedCells()) - { - view->setSpan(range.firstRow()-1, range.firstColumn()-1, range.rowCount(), range.columnCount()); - } - view->resizeColumnsToContents(); - m_tabXlsx->addTab(view, sheetName); - } - } - return ""; -} - -void WorkTicketWidget::setDev(const QString &devDesc, const QString &devNo, const QString &user) -{ - m_user = user; - QMap map; - map.insert("#DEV#",devDesc); - map.insert("#DEV_NO#",devNo); - setFiled(map); -} - -void WorkTicketWidget::setSaveVisible(bool visible) -{ - m_save->setVisible(visible); -} - -void WorkTicketWidget::onSave() -{ - if(false == omPermCheck()) - { - onMsg(tr("当前登录用户无运维管理功能权限!")); - return; - } - m_save->setEnabled(false); - QTimer::singleShot(1000,this,SLOT(onEnableSave())); - - if(m_tempFilePath.isEmpty()) - return; - - if(!m_doc->saveAs(m_tempFilePath)) - { - onMsg(tr("保存失败:%1").arg(m_tempFilePath)); - } - else - { - QDir dir(QCoreApplication::applicationDirPath()); - m_fileApi.commitLocalFileModify(dir.relativeFilePath(m_tempFilePath).toStdString()); - onMsg(tr("保存成功")); - } -} - -void WorkTicketWidget::onPrint() -{ - if(false == omPermCheck()) - { - onMsg(tr("当前登录用户无运维管理功能权限!")); - return; - } - - m_btPrint->setEnabled(false); - - if(m_editFilePath.isEmpty()) - { - onEnablePrint(); - return; - } - KbdTableModel *model = KbdTableDataMgr::getInstance()->createModel(TBL_HIS_WORK_TICKET); - if(model == NULL) - { - onEnablePrint(); - return; - } - - if(false == updateUser()) - { - onMsg(tr("获取当前登录用户失败!")); - onEnablePrint(); - return; - } - - QDateTime dt = QDateTime::currentDateTime(); - QFileInfo info(m_editFilePath); - QString saveFilePath = info.absolutePath() + "/"+info.baseName()+"_"+dt.toString("yyyy_MM_dd_hh_mm_ss")+"."+info.completeSuffix(); - //写入数据库 - bool success = false; - KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_EDIT); - QString retStr = KbdTableDataMgr::getInstance()->startTransaction(); - if(retStr.isEmpty()) //sucess - { - QStringList rowDatas = model->createDefaultValue(); - const ColMgrDataList& modelHisWorkCols = model->getHeadCols(); - rowDatas.replace(modelHisWorkCols.findCol(CN_CREATE_TIME),dt.toString(_TIME_FORMAT)); - rowDatas.replace(modelHisWorkCols.findCol(CN_REQUESTER),m_user); - rowDatas.replace(modelHisWorkCols.findCol(CN_FILE_PATH),saveFilePath); - - success = model->addRow(rowDatas,false); - - if(KbdTableDataMgr::getInstance()->commit()?false:((success=false)||true)) - { - onMsg(tr("事务执行失败!启动回滚")); - } - else - { - emit sendTicketAlarm(info.baseName()); - emit modelRefresh(); - } - } - else //fail - { - onMsg(retStr); - } - KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_SCAN); - - if(!success) - { - onMsg(tr("出票失败,请检查网络或者主数据库服务器连接是否异常!")); - onEnablePrint(); - return; - } - - //写入成功则保存 - //保存历史票时不保存电子签章 - if(!m_doc->saveAs(saveFilePath)) - { - onMsg(tr("出票失败:%1").arg(saveFilePath)); - } - else - { - QDir dir(QCoreApplication::applicationDirPath()); - m_fileApi.commitLocalFileModify(dir.relativeFilePath(saveFilePath).toStdString()); - - if(m_sign->isChecked()) - { - elecSignature(); - } - - if(!m_doc->saveAs(m_editFilePath)) - { - onMsg(tr("出票失败:%1").arg(m_editFilePath)); - } - } - - QDesktopServices::openUrl(QUrl::fromLocalFile(m_editFilePath)); - accept(); -} - -void WorkTicketWidget::onMsg(const QString &text) -{ - QMessageBox::information(this,tr("消息"),text); -} - -void WorkTicketWidget::onEnablePrint() -{ - m_btPrint->setEnabled(true); -} - -void WorkTicketWidget::onEnableSave() -{ - m_save->setEnabled(true); -} +#include "WorkTicketWidget.h" +#include +#include +#include +#include +#include +#include +#include "xlsxdocument.h" +#include "xlsxworksheet.h" +#include "xlsxcellrange.h" +#include "xlsxsheetmodel.h" +#include +#include +#include "HistoryWidget.h" +#include +#include "kbdtabledatamgr.h" +#include "../model_common/common.h" +#include +#include +#include +#include +#include +#include + +using namespace QXlsx; + + +WorkTicketWidget::WorkTicketWidget(QWidget *parent) : QDialog(parent) +{ + m_doc = NULL; + m_editFilePath = ""; + m_tempFilePath = ""; + initLayout(); + m_rtdbAccess = new kbd_dbms::CRdbAccess(); +// initTableModel(); +} + +WorkTicketWidget::~WorkTicketWidget() +{ + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; +} + +void WorkTicketWidget::initLayout() +{ + QVBoxLayout *vLayout = new QVBoxLayout; + m_tabXlsx = new QTabWidget(this); + + QHBoxLayout *hLayout = new QHBoxLayout; + m_sign = new QCheckBox(tr("电子签章"), this); + m_save = new QPushButton(tr("保存"),this); + m_btPrint = new QPushButton(tr("出票"),this); + m_save->setMinimumHeight(35); + m_btPrint->setMinimumHeight(35); + hLayout->addWidget(m_sign); + hLayout->addStretch(); + hLayout->addWidget(m_save); + hLayout->addSpacing(50); + hLayout->addWidget(m_btPrint); + hLayout->addStretch(); + hLayout->setContentsMargins(10,0,120,0); + + vLayout->addWidget(m_tabXlsx); + vLayout->addLayout(hLayout); + vLayout->addSpacing(15); + setLayout(vLayout); + vLayout->setContentsMargins(0,0,0,0); + setContentsMargins(0,0,0,0); + + connect(m_save,SIGNAL(clicked(bool)),this,SLOT(onSave())); + connect(m_btPrint,SIGNAL(clicked(bool)),this,SLOT(onPrint())); +} + +void WorkTicketWidget::initTableModel() +{ +// QSettings settings("KbdSoft.ZHJK","ISCS6000.tools"); +// KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::DirectLink, +// settings.value("login/user","root").toString(), +// settings.value("login/psw","kbdct@0755").toString(), +// settings.value("login/ip","192.168.190.128").toString(), +// settings.value("login/port","3306").toInt(), +// settings.value("login/dbname","ISCS6000").toString(), +// DataBaseInterface::MySql +// ); + KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::CenterLink); +} + +void WorkTicketWidget::elecSignature() +{ + QTableView *table; + QModelIndex index; + QString cell; + for(int i = 0; i < m_tabXlsx->count(); i++) + { + table = qobject_cast(m_tabXlsx->widget(i)); + if(table) + { + for(int row = 0; row < table->model()->rowCount(); row++) + { + for(int col = 0; col < table->model()->columnCount(); col++) + { + index = table->model()->index(row,col); + cell = table->model()->data(index).toString(); + //< (签章)翻译与工作票模板需匹配 + if(cell.endsWith(tr("(签章)"), Qt::CaseInsensitive)) + { + cell.replace(tr("(签章)"), ""); + int perm_id = readUserId(cell); + if(perm_id == -1) + { + continue; + } + QByteArray byte = readSignatureData(perm_id); + table->model()->setData(index, QString(byte), Qt::BackgroundRole); + } + } + } + } + } +} + +void WorkTicketWidget::setFiled(const QMap &mapFiled) +{ + //遍历TABLE + QTableView *table; + QModelIndex index; + QString cell; + for(int i = 0; i < m_tabXlsx->count(); i++) + { + table = qobject_cast(m_tabXlsx->widget(i)); + if(table) + { + for(int row = 0; row < table->model()->rowCount(); row++) + { + for(int col = 0; col < table->model()->columnCount(); col++) + { + index = table->model()->index(row,col); + cell = table->model()->data(index).toString(); + if(replaceFiled(mapFiled,cell)) + { + table->model()->setData(index,cell); + } + } + } + } + } + +} + +bool WorkTicketWidget::replaceFiled(const QMap &mapFiled, QString &content) +{ + bool ret = false; + foreach (QString key, mapFiled.keys()) { + if(content.contains(key)) + { + content.replace(key,mapFiled.value(key),Qt::CaseSensitive); + ret = true; + } + } + + return ret; +} + +QString WorkTicketWidget::copyTempToHistory(const QString &tempFileName) +{ + //FIX +// xx判断路径是否存在,不存在创建路径 + QStringList tempList = tempFileName.split(QDir::separator()); + tempList.removeLast(); + QString dirPath = Common::getIscsHome()+ "/data/work_ticket/history/" + tempList.join(QDir::separator()); + QDir dir(dirPath); + if(!dir.exists()) + { + if(!dir.mkpath(dirPath)) + return tr("创建目录失败: %1").arg(dirPath); + } + m_tempFilePath = Common::getIscsHome() + "/data/work_ticket/template/" + tempFileName; + QFileInfo info(m_tempFilePath); + m_editFilePath = dirPath + "/" + info.fileName(); + if(QFile::exists(m_editFilePath)) + { + if(!QFile::remove(m_editFilePath)) + { + QString tmp = m_editFilePath; + m_editFilePath = ""; + m_tempFilePath = ""; + return tr("请先关闭文件: %1").arg(tmp); + } + } + + if(!QFile::copy(m_tempFilePath,m_editFilePath)) + { + QString tmp = m_editFilePath; + m_editFilePath = ""; + m_tempFilePath = ""; + return tr("请先关闭文件: %1").arg(tmp); + } + + return ""; +} + +QString WorkTicketWidget::copyHisToHistory(const QString &tempFileName) +{ + QString dirPath = Common::getIscsHome()+ "/data/work_ticket/history/" + tempFileName; + if(!QFile::exists(dirPath)) + { + return tr("历史票不存在!").arg(tempFileName); + } + + m_tempFilePath = dirPath; + m_editFilePath = dirPath.section("_",0,-7) + ".xlsx"; + if(QFile::exists(m_editFilePath)) + { + if(!QFile::remove(m_editFilePath)) + { + QString tmp = m_editFilePath; + m_editFilePath = ""; + m_tempFilePath = ""; + return tr("请先关闭文件: %1").arg(tmp); + } + } + + if(!QFile::copy(m_tempFilePath,m_editFilePath)) + { + QString tmp = m_editFilePath; + m_editFilePath = ""; + m_tempFilePath = ""; + return tr("请先关闭文件: %1").arg(tmp); + } + return ""; +} + +bool WorkTicketWidget::updateUser() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + int UserId,UserGrpId,Level,LoginSec; + std::string InstanceName; + if(PERM_NORMAL != permMngPtr->CurUser(UserId,UserGrpId,Level,LoginSec,InstanceName)) + { + return false; + } + m_user = readUserAlias(UserId); + return true; +} + +bool WorkTicketWidget::omPermCheck() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string tmpStr = "FUNC_NOM_OM"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + return false; + } + return true; +} + +QString WorkTicketWidget::readUserAlias(int UserId) +{ + QString ret = QString(); + if(m_rtdbAccess->open("base", "rm_user_def")) + { + CTableLockGuard locker(*m_rtdbAccess); + CONDINFO conditionID; + memcpy(conditionID.name,"perm_id", strlen("perm_id")); + conditionID.logicalop = ATTRCOND_OR; + conditionID.relationop = ATTRCOND_EQU; + conditionID.conditionval = UserId; + + CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_alias"); + if(m_rtdbAccess->select(conditionID, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType alias; + result.getColumnValue(nIndex, 0, alias); + ret = QString::fromStdString(alias.toStdString()); + } + } + } + + m_rtdbAccess->close(); + return ret; +} + +int WorkTicketWidget::readUserId(const QString &alias) +{ + int ret = -1; + if(m_rtdbAccess->open("base", "rm_user_def")) + { + CTableLockGuard locker(*m_rtdbAccess); + CONDINFO conditionID; + memcpy(conditionID.name, "perm_alias",strlen("perm_alias") ); + conditionID.logicalop = ATTRCOND_OR; + conditionID.relationop = ATTRCOND_EQU; + conditionID.conditionval = alias.toStdString(); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_id"); + if(m_rtdbAccess->select(conditionID, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType permId; + result.getColumnValue(nIndex, 0, permId); + ret = permId.toInt(); + } + } + } + + m_rtdbAccess->close(); + return ret; +} + +QByteArray WorkTicketWidget::readSignatureData(int perm_id) +{ + QString sql = QString("select * from rm_user_signature_info where USER_ID = '%1';").arg(perm_id); + QSqlQuery result; + KbdTableDataMgr::getInstance()->selectOnly(sql, result); + + QByteArray signData; + while(result.next()) + { + signData = result.value("DATA_BASE64").toString().toLatin1(); + } + return signData; +} + +QString WorkTicketWidget::reloadXlsx(const QString &tempFileName, bool isReTick) +{ + QString error; + if(isReTick) + { + error = copyHisToHistory(tempFileName); + if(!error.isEmpty()) + return error; + } + else + { + error = copyTempToHistory(tempFileName); + if(!error.isEmpty()) + return error; + } + //delete tab + QList widgets; + for(int i = 0; i < m_tabXlsx->count(); i++) + { + widgets << m_tabXlsx->widget(i); + } + m_tabXlsx->clear(); + foreach (QWidget *w, widgets) { + w->deleteLater(); + } + widgets.clear(); + if(m_doc != NULL) + { + m_doc->deleteLater(); + m_doc = NULL; + } + //load + m_tabXlsx->setTabPosition(QTabWidget::South); + m_doc = new Document(m_editFilePath,this); + + foreach (QString sheetName, m_doc->sheetNames()) { + Worksheet *sheet = dynamic_cast(m_doc->sheet(sheetName)); + if (sheet) { + QTableView *view = new QTableView(m_tabXlsx); + view->setModel(new SheetModel(sheet, view)); + foreach (CellRange range, sheet->mergedCells()) + { + view->setSpan(range.firstRow()-1, range.firstColumn()-1, range.rowCount(), range.columnCount()); + } + view->resizeColumnsToContents(); + m_tabXlsx->addTab(view, sheetName); + } + } + return ""; +} + +void WorkTicketWidget::setDev(const QString &devDesc, const QString &devNo, const QString &user) +{ + m_user = user; + QMap map; + map.insert("#DEV#",devDesc); + map.insert("#DEV_NO#",devNo); + setFiled(map); +} + +void WorkTicketWidget::setSaveVisible(bool visible) +{ + m_save->setVisible(visible); +} + +void WorkTicketWidget::onSave() +{ + if(false == omPermCheck()) + { + onMsg(tr("当前登录用户无运维管理功能权限!")); + return; + } + m_save->setEnabled(false); + QTimer::singleShot(1000,this,SLOT(onEnableSave())); + + if(m_tempFilePath.isEmpty()) + return; + + if(!m_doc->saveAs(m_tempFilePath)) + { + onMsg(tr("保存失败:%1").arg(m_tempFilePath)); + } + else + { + QDir dir(QCoreApplication::applicationDirPath()); + m_fileApi.commitLocalFileModify(dir.relativeFilePath(m_tempFilePath).toStdString()); + onMsg(tr("保存成功")); + } +} + +void WorkTicketWidget::onPrint() +{ + if(false == omPermCheck()) + { + onMsg(tr("当前登录用户无运维管理功能权限!")); + return; + } + + m_btPrint->setEnabled(false); + + if(m_editFilePath.isEmpty()) + { + onEnablePrint(); + return; + } + KbdTableModel *model = KbdTableDataMgr::getInstance()->createModel(TBL_HIS_WORK_TICKET); + if(model == NULL) + { + onEnablePrint(); + return; + } + + if(false == updateUser()) + { + onMsg(tr("获取当前登录用户失败!")); + onEnablePrint(); + return; + } + + QDateTime dt = QDateTime::currentDateTime(); + QFileInfo info(m_editFilePath); + QString saveFilePath = info.absolutePath() + "/"+info.baseName()+"_"+dt.toString("yyyy_MM_dd_hh_mm_ss")+"."+info.completeSuffix(); + //写入数据库 + bool success = false; + KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_EDIT); + QString retStr = KbdTableDataMgr::getInstance()->startTransaction(); + if(retStr.isEmpty()) //sucess + { + QStringList rowDatas = model->createDefaultValue(); + const ColMgrDataList& modelHisWorkCols = model->getHeadCols(); + rowDatas.replace(modelHisWorkCols.findCol(CN_CREATE_TIME),dt.toString(_TIME_FORMAT)); + rowDatas.replace(modelHisWorkCols.findCol(CN_REQUESTER),m_user); + rowDatas.replace(modelHisWorkCols.findCol(CN_FILE_PATH),saveFilePath); + + success = model->addRow(rowDatas,false); + + if(KbdTableDataMgr::getInstance()->commit()?false:((success=false)||true)) + { + onMsg(tr("事务执行失败!启动回滚")); + } + else + { + emit sendTicketAlarm(info.baseName()); + emit modelRefresh(); + } + } + else //fail + { + onMsg(retStr); + } + KbdTableDataMgr::getInstance()->setRight(KbdTableDataMgr::MODEL_SCAN); + + if(!success) + { + onMsg(tr("出票失败,请检查网络或者主数据库服务器连接是否异常!")); + onEnablePrint(); + return; + } + + //写入成功则保存 + //保存历史票时不保存电子签章 + if(!m_doc->saveAs(saveFilePath)) + { + onMsg(tr("出票失败:%1").arg(saveFilePath)); + } + else + { + QDir dir(QCoreApplication::applicationDirPath()); + m_fileApi.commitLocalFileModify(dir.relativeFilePath(saveFilePath).toStdString()); + + if(m_sign->isChecked()) + { + elecSignature(); + } + + if(!m_doc->saveAs(m_editFilePath)) + { + onMsg(tr("出票失败:%1").arg(m_editFilePath)); + } + } + + QDesktopServices::openUrl(QUrl::fromLocalFile(m_editFilePath)); + accept(); +} + +void WorkTicketWidget::onMsg(const QString &text) +{ + QMessageBox::information(this,tr("消息"),text); +} + +void WorkTicketWidget::onEnablePrint() +{ + m_btPrint->setEnabled(true); +} + +void WorkTicketWidget::onEnableSave() +{ + m_save->setEnabled(true); +} diff --git a/product/src/gui/plugin/WorkTicket/WorkTicketWidget.h b/product/src/gui/plugin/WorkTicket/WorkTicketWidget.h index 9cc55910..7e7f270c 100644 --- a/product/src/gui/plugin/WorkTicket/WorkTicketWidget.h +++ b/product/src/gui/plugin/WorkTicket/WorkTicketWidget.h @@ -1,80 +1,80 @@ -#ifndef WORKTICKETWIDGET_H -#define WORKTICKETWIDGET_H -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" -#include "sys_file_sync_api/FilesyncApi.h" - -class QTabWidget; -namespace QXlsx { - class Document; -} -class QPushButton; -class QCheckBox; - -using namespace kbd_service; -using namespace kbd_dbms; -class WorkTicketWidget : public QDialog -{ - Q_OBJECT -public: - explicit WorkTicketWidget(QWidget *parent = nullptr); - ~WorkTicketWidget(); -public slots: - /** - * @brief reloadXlsx 加载excel表格 - * @param tempFileName ISCS_HOME/data/work_ticket/template 目录下的文件名 - * @param isReTick 是否重开 - * @return 错误描述 为空代表成功 - */ - QString reloadXlsx(const QString &tempFileName, bool isReTick = false); - /** - * @brief setDev 设置设备描述,设备编号,用户名 - * @param devDesc - * @param devNo - * @param user - */ - void setDev(const QString &devDesc,const QString &devNo,const QString &user); - - void setSaveVisible(bool visible); -signals: - void sendTicketAlarm(QString devDesc); - void modelRefresh(); -private: - void initLayout(); - void initTableModel(); - //电子签章转换 - void elecSignature(); - //设置占位符-值的键值对 - void setFiled(const QMap &mapFiled); - //对content中的内容,只要包含占位符,则替换掉,替换成功返回true - bool replaceFiled(const QMap &mapFiled, QString &content); - //拷贝模板文件到历史记录目录 - QString copyTempToHistory(const QString &tempFileName); - QString copyHisToHistory(const QString &tempFileName); - bool updateUser(); - //运维管理功能权限 - bool omPermCheck(); - QString readUserAlias(int UserId); - int readUserId(const QString &alias); - QByteArray readSignatureData(int perm_id); - QString m_user; - QString m_tempFilePath; - QString m_editFilePath; - QXlsx::Document *m_doc; - QTabWidget *m_tabXlsx; - QCheckBox *m_sign; - QPushButton *m_save; - QPushButton *m_btPrint; - kbd_dbms::CRdbAccess * m_rtdbAccess; - kbd_sys::FilesyncApi m_fileApi; - -private slots: - void onSave(); - void onPrint();//打印出票 - void onMsg(const QString &text); - void onEnablePrint(); - void onEnableSave(); -}; - -#endif // WORKTICKETWIDGET_H +#ifndef WORKTICKETWIDGET_H +#define WORKTICKETWIDGET_H +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "sys_file_sync_api/FilesyncApi.h" + +class QTabWidget; +namespace QXlsx { + class Document; +} +class QPushButton; +class QCheckBox; + +using namespace kbd_service; +using namespace kbd_dbms; +class WorkTicketWidget : public QDialog +{ + Q_OBJECT +public: + explicit WorkTicketWidget(QWidget *parent = nullptr); + ~WorkTicketWidget(); +public slots: + /** + * @brief reloadXlsx 加载excel表格 + * @param tempFileName ISCS_HOME/data/work_ticket/template 目录下的文件名 + * @param isReTick 是否重开 + * @return 错误描述 为空代表成功 + */ + QString reloadXlsx(const QString &tempFileName, bool isReTick = false); + /** + * @brief setDev 设置设备描述,设备编号,用户名 + * @param devDesc + * @param devNo + * @param user + */ + void setDev(const QString &devDesc,const QString &devNo,const QString &user); + + void setSaveVisible(bool visible); +signals: + void sendTicketAlarm(QString devDesc); + void modelRefresh(); +private: + void initLayout(); + void initTableModel(); + //电子签章转换 + void elecSignature(); + //设置占位符-值的键值对 + void setFiled(const QMap &mapFiled); + //对content中的内容,只要包含占位符,则替换掉,替换成功返回true + bool replaceFiled(const QMap &mapFiled, QString &content); + //拷贝模板文件到历史记录目录 + QString copyTempToHistory(const QString &tempFileName); + QString copyHisToHistory(const QString &tempFileName); + bool updateUser(); + //运维管理功能权限 + bool omPermCheck(); + QString readUserAlias(int UserId); + int readUserId(const QString &alias); + QByteArray readSignatureData(int perm_id); + QString m_user; + QString m_tempFilePath; + QString m_editFilePath; + QXlsx::Document *m_doc; + QTabWidget *m_tabXlsx; + QCheckBox *m_sign; + QPushButton *m_save; + QPushButton *m_btPrint; + kbd_dbms::CRdbAccess * m_rtdbAccess; + kbd_sys::FilesyncApi m_fileApi; + +private slots: + void onSave(); + void onPrint();//打印出票 + void onMsg(const QString &text); + void onEnablePrint(); + void onEnableSave(); +}; + +#endif // WORKTICKETWIDGET_H diff --git a/product/src/gui/plugin/WorkTicket/xlsxsheetmodel.cpp b/product/src/gui/plugin/WorkTicket/xlsxsheetmodel.cpp index 129ebddb..1a710770 100644 --- a/product/src/gui/plugin/WorkTicket/xlsxsheetmodel.cpp +++ b/product/src/gui/plugin/WorkTicket/xlsxsheetmodel.cpp @@ -1,215 +1,215 @@ -/**************************************************************************** -** Copyright (c) 2013-2014 Debao Zhang -** All right reserved. -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#include "xlsxsheetmodel.h" -#include "xlsxsheetmodel_p.h" -#include "xlsxworksheet.h" - -#include - -QT_BEGIN_NAMESPACE_XLSX - -SheetModelPrivate::SheetModelPrivate(SheetModel *p) - :q_ptr(p) -{ - -} - -/*! - * \class SheetModel - * - * Helper class for gui applicaiton user - * - * \note SheetModel indices start from 0, while Worksheet - * column/row indices start from 1. - */ - -/*! - * Creates a model object with the given \a sheet and \a parent. - */ -SheetModel::SheetModel(Worksheet *sheet, QObject *parent) - :QAbstractTableModel(parent), d_ptr(new SheetModelPrivate(this)) -{ - d_ptr->sheet = sheet; -} - -/*! - * Destroys the model. - */ -SheetModel::~SheetModel() -{ - delete d_ptr; -} - -int SheetModel::rowCount(const QModelIndex &/*parent*/) const -{ - Q_D(const SheetModel); - return d->sheet->dimension().lastRow(); -} - - -int SheetModel::columnCount(const QModelIndex &/*parent*/) const -{ - Q_D(const SheetModel); - return d->sheet->dimension().lastColumn(); -} - -Qt::ItemFlags SheetModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; -} - -QVariant SheetModel::data(const QModelIndex &index, int role) const -{ - Q_D(const SheetModel); - - if (!index.isValid()) - return QVariant(); - - Cell *cell = d->sheet->cellAt(index.row()+1, index.column()+1); - if (!cell) - return QVariant(); - QVariant userFriendlyValue = d->sheet->read(index.row()+1, index.column()+1); - - if (role == Qt::DisplayRole) { - if (cell->isDateTime()) - return userFriendlyValue; - return cell->value(); - } else if (role == Qt::EditRole) { - return userFriendlyValue; - } else if (role == Qt::TextAlignmentRole) { - Qt::Alignment align; - switch (cell->format().horizontalAlignment()) { - case Format::AlignLeft: - align |= Qt::AlignLeft; - break; - case Format::AlignRight: - align |= Qt::AlignRight; - break; - case Format::AlignHCenter: - align |= Qt::AlignHCenter; - break; - case Format::AlignHJustify: - align |= Qt::AlignJustify; - break; - default: - break; - } - switch (cell->format().verticalAlignment()) { - case Format::AlignTop: - align |= Qt::AlignTop; - break; - case Format::AlignBottom: - align |= Qt::AlignBottom; - break; - case Format::AlignVCenter: - align |= Qt::AlignVCenter; - break; - default: - break; - } - return QVariant(align); - } else if (role == Qt::FontRole) { - if (cell->format().hasFontData()) - return cell->format().font(); - } else if (role == Qt::ForegroundRole) { - if (cell->format().fontColor().isValid()) - return QBrush(cell->format().fontColor()); - } else if (role == Qt::BackgroundRole) { - if (cell->format().patternBackgroundColor().isValid()) - return QBrush(cell->format().patternBackgroundColor()); - } - - return QVariant(); -} - -/* - * Copy from xlsxutility.cpp, so this example don't depend on the xlsx-private - * This function should be removed once this class moved to the xlsx library. - */ -static QString col_to_name(int col_num) -{ - QString col_str; - - int remainder; - while (col_num) { - remainder = col_num % 26; - if (remainder == 0) - remainder = 26; - col_str.prepend(QChar('A'+remainder-1)); - col_num = (col_num - 1) / 26; - } - - return col_str; -} - -QVariant SheetModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::DisplayRole) { - if (orientation == Qt::Horizontal) - return col_to_name(section + 1); - else - return QString::number(section + 1); - } - return QVariant(); -} - -bool SheetModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_D(const SheetModel); - - if (!index.isValid()) - return false; - - if (role == Qt::EditRole) { - if (d->sheet->write(index.row()+1, index.column()+1, value) == 0) - return true; - } - else if(role == Qt::BackgroundRole){ - QImage image; - QByteArray data = QByteArray::fromBase64(QByteArray(value.toString().toLatin1())); - uchar* img = new uchar[data.size()]; - memcpy(img,data.data(),data.size()); - image.loadFromData(img,data.size()); - delete[] img; - if(d->sheet->insertImage(index.row(), index.column(), image)) - return true; - } - - return false; -} - -/*! - * Returns the sheet object. - */ -Worksheet *SheetModel::sheet() const -{ - Q_D(const SheetModel); - return d->sheet; -} - -QT_END_NAMESPACE_XLSX +/**************************************************************************** +** Copyright (c) 2013-2014 Debao Zhang +** All right reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ + +#include "xlsxsheetmodel.h" +#include "xlsxsheetmodel_p.h" +#include "xlsxworksheet.h" + +#include + +QT_BEGIN_NAMESPACE_XLSX + +SheetModelPrivate::SheetModelPrivate(SheetModel *p) + :q_ptr(p) +{ + +} + +/*! + * \class SheetModel + * + * Helper class for gui applicaiton user + * + * \note SheetModel indices start from 0, while Worksheet + * column/row indices start from 1. + */ + +/*! + * Creates a model object with the given \a sheet and \a parent. + */ +SheetModel::SheetModel(Worksheet *sheet, QObject *parent) + :QAbstractTableModel(parent), d_ptr(new SheetModelPrivate(this)) +{ + d_ptr->sheet = sheet; +} + +/*! + * Destroys the model. + */ +SheetModel::~SheetModel() +{ + delete d_ptr; +} + +int SheetModel::rowCount(const QModelIndex &/*parent*/) const +{ + Q_D(const SheetModel); + return d->sheet->dimension().lastRow(); +} + + +int SheetModel::columnCount(const QModelIndex &/*parent*/) const +{ + Q_D(const SheetModel); + return d->sheet->dimension().lastColumn(); +} + +Qt::ItemFlags SheetModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; +} + +QVariant SheetModel::data(const QModelIndex &index, int role) const +{ + Q_D(const SheetModel); + + if (!index.isValid()) + return QVariant(); + + Cell *cell = d->sheet->cellAt(index.row()+1, index.column()+1); + if (!cell) + return QVariant(); + QVariant userFriendlyValue = d->sheet->read(index.row()+1, index.column()+1); + + if (role == Qt::DisplayRole) { + if (cell->isDateTime()) + return userFriendlyValue; + return cell->value(); + } else if (role == Qt::EditRole) { + return userFriendlyValue; + } else if (role == Qt::TextAlignmentRole) { + Qt::Alignment align; + switch (cell->format().horizontalAlignment()) { + case Format::AlignLeft: + align |= Qt::AlignLeft; + break; + case Format::AlignRight: + align |= Qt::AlignRight; + break; + case Format::AlignHCenter: + align |= Qt::AlignHCenter; + break; + case Format::AlignHJustify: + align |= Qt::AlignJustify; + break; + default: + break; + } + switch (cell->format().verticalAlignment()) { + case Format::AlignTop: + align |= Qt::AlignTop; + break; + case Format::AlignBottom: + align |= Qt::AlignBottom; + break; + case Format::AlignVCenter: + align |= Qt::AlignVCenter; + break; + default: + break; + } + return QVariant(align); + } else if (role == Qt::FontRole) { + if (cell->format().hasFontData()) + return cell->format().font(); + } else if (role == Qt::ForegroundRole) { + if (cell->format().fontColor().isValid()) + return QBrush(cell->format().fontColor()); + } else if (role == Qt::BackgroundRole) { + if (cell->format().patternBackgroundColor().isValid()) + return QBrush(cell->format().patternBackgroundColor()); + } + + return QVariant(); +} + +/* + * Copy from xlsxutility.cpp, so this example don't depend on the xlsx-private + * This function should be removed once this class moved to the xlsx library. + */ +static QString col_to_name(int col_num) +{ + QString col_str; + + int remainder; + while (col_num) { + remainder = col_num % 26; + if (remainder == 0) + remainder = 26; + col_str.prepend(QChar('A'+remainder-1)); + col_num = (col_num - 1) / 26; + } + + return col_str; +} + +QVariant SheetModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::DisplayRole) { + if (orientation == Qt::Horizontal) + return col_to_name(section + 1); + else + return QString::number(section + 1); + } + return QVariant(); +} + +bool SheetModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_D(const SheetModel); + + if (!index.isValid()) + return false; + + if (role == Qt::EditRole) { + if (d->sheet->write(index.row()+1, index.column()+1, value) == 0) + return true; + } + else if(role == Qt::BackgroundRole){ + QImage image; + QByteArray data = QByteArray::fromBase64(QByteArray(value.toString().toLatin1())); + uchar* img = new uchar[data.size()]; + memcpy(img,data.data(),data.size()); + image.loadFromData(img,data.size()); + delete[] img; + if(d->sheet->insertImage(index.row(), index.column(), image)) + return true; + } + + return false; +} + +/*! + * Returns the sheet object. + */ +Worksheet *SheetModel::sheet() const +{ + Q_D(const SheetModel); + return d->sheet; +} + +QT_END_NAMESPACE_XLSX diff --git a/product/src/gui/plugin/WorkTicket/xlsxsheetmodel.h b/product/src/gui/plugin/WorkTicket/xlsxsheetmodel.h index 6d0798a0..b500ff3f 100644 --- a/product/src/gui/plugin/WorkTicket/xlsxsheetmodel.h +++ b/product/src/gui/plugin/WorkTicket/xlsxsheetmodel.h @@ -1,63 +1,63 @@ -/**************************************************************************** -** Copyright (c) 2013-2014 Debao Zhang -** All right reserved. -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#ifndef QXLSX_XLSXSHEETMODEL_H -#define QXLSX_XLSXSHEETMODEL_H - -#include "xlsxglobal.h" -#include - -QT_BEGIN_NAMESPACE_XLSX - -class Worksheet; -class SheetModelPrivate; - -class SheetModel : public QAbstractTableModel -{ - Q_OBJECT - Q_DECLARE_PRIVATE(SheetModel) -public: - explicit SheetModel(Worksheet *sheet, QObject *parent = 0); - ~SheetModel(); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex & index) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - - Worksheet *sheet() const; -signals: - -public slots: - -private: - SheetModelPrivate * const d_ptr; -}; - -QT_END_NAMESPACE_XLSX - -#endif // QXLSX_XLSXSHEETMODEL_H +/**************************************************************************** +** Copyright (c) 2013-2014 Debao Zhang +** All right reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ + +#ifndef QXLSX_XLSXSHEETMODEL_H +#define QXLSX_XLSXSHEETMODEL_H + +#include "xlsxglobal.h" +#include + +QT_BEGIN_NAMESPACE_XLSX + +class Worksheet; +class SheetModelPrivate; + +class SheetModel : public QAbstractTableModel +{ + Q_OBJECT + Q_DECLARE_PRIVATE(SheetModel) +public: + explicit SheetModel(Worksheet *sheet, QObject *parent = 0); + ~SheetModel(); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex & index) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Worksheet *sheet() const; +signals: + +public slots: + +private: + SheetModelPrivate * const d_ptr; +}; + +QT_END_NAMESPACE_XLSX + +#endif // QXLSX_XLSXSHEETMODEL_H diff --git a/product/src/gui/plugin/WorkTicket/xlsxsheetmodel_p.h b/product/src/gui/plugin/WorkTicket/xlsxsheetmodel_p.h index 83861a65..fe696747 100644 --- a/product/src/gui/plugin/WorkTicket/xlsxsheetmodel_p.h +++ b/product/src/gui/plugin/WorkTicket/xlsxsheetmodel_p.h @@ -1,56 +1,56 @@ -/**************************************************************************** -** Copyright (c) 2013-2014 Debao Zhang -** All right reserved. -** -** Permission is hereby granted, free of charge, to any person obtaining -** a copy of this software and associated documentation files (the -** "Software"), to deal in the Software without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Software, and to -** permit persons to whom the Software is furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be -** included in all copies or substantial portions of the Software. -** -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -** -****************************************************************************/ - -#ifndef XLSXSHEETMODEL_P_H -#define XLSXSHEETMODEL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt Xlsx API. It exists for the convenience -// of the Qt Xlsx. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include "xlsxsheetmodel.h" - -QT_BEGIN_NAMESPACE_XLSX - -class SheetModelPrivate -{ - Q_DECLARE_PUBLIC(SheetModel) -public: - SheetModelPrivate(SheetModel *p); - - Worksheet *sheet; - SheetModel *q_ptr; -}; - -QT_END_NAMESPACE_XLSX - -#endif // XLSXSHEETMODEL_P_H +/**************************************************************************** +** Copyright (c) 2013-2014 Debao Zhang +** All right reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ + +#ifndef XLSXSHEETMODEL_P_H +#define XLSXSHEETMODEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Xlsx API. It exists for the convenience +// of the Qt Xlsx. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include "xlsxsheetmodel.h" + +QT_BEGIN_NAMESPACE_XLSX + +class SheetModelPrivate +{ + Q_DECLARE_PUBLIC(SheetModel) +public: + SheetModelPrivate(SheetModel *p); + + Worksheet *sheet; + SheetModel *q_ptr; +}; + +QT_END_NAMESPACE_XLSX + +#endif // XLSXSHEETMODEL_P_H diff --git a/product/src/gui/plugin/iDongOpsWidget/CCfgParser.cpp b/product/src/gui/plugin/iDongOpsWidget/CCfgParser.cpp index b9c3f55e..81908828 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CCfgParser.cpp +++ b/product/src/gui/plugin/iDongOpsWidget/CCfgParser.cpp @@ -1,70 +1,70 @@ -#include "CCfgParser.h" -#include "pub_utility_api/CommonConfigParse.h" -#include -#include - - -//< GLODBL_CONFIG KEY -const char* CN_GLOBAL = "global" ; -const char *CN_IS_PERM_CHECKED = "is_perm_checked" ; -const char *CN_DEFAULT_USER = "default_user" ; -const char *CN_DEFAULT_PASSWD = "default_passwd" ; -const char *CN_SERVER_ADDRESS = "server_address" ; -const char *CN_SERVER_PORT = "server_port" ; -const char *CN_IS_HTTPS = "is_https" ; -const char *CN_IS_HEADER = "is_header" ; -const char *CN_IS_TITLE = "is_title" ; -const char *CN_IS_LEFTBAR = "is_leftbar" ; -const char *CN_IS_BUTTON = "is_button" ; -const char *CN_LOCAL_STATICPAGE_PATH = "local_staticpage_path" ; -const char *CN_ERR_PAGE = "err_page" ; -const char *CN_PERM_ERR_PAGE = "perm_err_page" ; - - -A_GLOBAL_CFG CCfgParser::g_global_cfg; -bool CCfgParser::g_isValid=false; - - -bool CCfgParser::loadGlobal(kbd_public::CCommonConfigParse &cfg) -{ - if( cfg.getBoolValue(CN_GLOBAL, CN_IS_PERM_CHECKED , g_global_cfg.is_perm_checked ) == kbdFailed){ LOGERROR( " is_perm_checked option parser err"); return false;} - if( cfg.getStringValue(CN_GLOBAL, CN_DEFAULT_USER , g_global_cfg.default_user ) == kbdFailed){ LOGERROR( " default_user option parser err"); return false;} - if( cfg.getStringValue(CN_GLOBAL, CN_DEFAULT_PASSWD , g_global_cfg.default_passwd ) == kbdFailed){ LOGERROR( " default_passwd option parser err"); return false;} - if( cfg.getStringValue(CN_GLOBAL, CN_SERVER_ADDRESS , g_global_cfg.server_address ) == kbdFailed){ LOGERROR( " server_address option parser err"); return false;} - if( cfg.getIntValue(CN_GLOBAL, CN_SERVER_PORT , g_global_cfg.server_port ) == kbdFailed){ LOGERROR( " server_port option parser err"); return false;} - if( cfg.getBoolValue(CN_GLOBAL, CN_IS_HTTPS , g_global_cfg.is_https ) == kbdFailed){ LOGERROR( " is_https option parser err"); return false;} - if( cfg.getBoolValue(CN_GLOBAL, CN_IS_HEADER , g_global_cfg.is_header ) == kbdFailed){ LOGERROR( " is_header option parser err"); return false;} - if( cfg.getBoolValue(CN_GLOBAL, CN_IS_TITLE , g_global_cfg.is_title ) == kbdFailed){ LOGERROR( " is_title option parser err"); return false;} - if( cfg.getBoolValue(CN_GLOBAL, CN_IS_LEFTBAR , g_global_cfg.is_leftbar ) == kbdFailed){ LOGERROR( " is_leftbar option parser err"); return false;} - if( cfg.getBoolValue(CN_GLOBAL, CN_IS_BUTTON , g_global_cfg.is_button ) == kbdFailed){ LOGERROR( " is_button option parser err"); return false;} - if( cfg.getStringValue(CN_GLOBAL, CN_LOCAL_STATICPAGE_PATH , g_global_cfg.local_static_page_path ) == kbdFailed){ LOGERROR( " local_staticpage_path option parser err"); return false;} - if( cfg.getStringValue(CN_GLOBAL, CN_ERR_PAGE , g_global_cfg.err_page ) == kbdFailed){ LOGERROR( " err_page option parser err"); return false;} - if( cfg.getStringValue(CN_GLOBAL, CN_PERM_ERR_PAGE , g_global_cfg.perm_err_page ) == kbdFailed){ LOGERROR( " perm_err_page option parser err"); return false;} - return true; -} - - -bool CCfgParser::isValid() -{ - return g_isValid; -} - -bool CCfgParser::loadCfg(const std::string &cfgPath) -{ - kbd_public::CCommonConfigParse cfgP; - if( cfgP.load(cfgPath) == kbdFailed) - { - LOGERROR("config failed to load, please check config syntax!"); - g_isValid = false; - return false; - } - - if(!loadGlobal(cfgP)) - { - LOGERROR("global options fail to parse, please check!"); - g_isValid = false; - return false; - } - g_isValid = true; - return true; -} +#include "CCfgParser.h" +#include "pub_utility_api/CommonConfigParse.h" +#include +#include + + +//< GLODBL_CONFIG KEY +const char* CN_GLOBAL = "global" ; +const char *CN_IS_PERM_CHECKED = "is_perm_checked" ; +const char *CN_DEFAULT_USER = "default_user" ; +const char *CN_DEFAULT_PASSWD = "default_passwd" ; +const char *CN_SERVER_ADDRESS = "server_address" ; +const char *CN_SERVER_PORT = "server_port" ; +const char *CN_IS_HTTPS = "is_https" ; +const char *CN_IS_HEADER = "is_header" ; +const char *CN_IS_TITLE = "is_title" ; +const char *CN_IS_LEFTBAR = "is_leftbar" ; +const char *CN_IS_BUTTON = "is_button" ; +const char *CN_LOCAL_STATICPAGE_PATH = "local_staticpage_path" ; +const char *CN_ERR_PAGE = "err_page" ; +const char *CN_PERM_ERR_PAGE = "perm_err_page" ; + + +A_GLOBAL_CFG CCfgParser::g_global_cfg; +bool CCfgParser::g_isValid=false; + + +bool CCfgParser::loadGlobal(kbd_public::CCommonConfigParse &cfg) +{ + if( cfg.getBoolValue(CN_GLOBAL, CN_IS_PERM_CHECKED , g_global_cfg.is_perm_checked ) == kbdFailed){ LOGERROR( " is_perm_checked option parser err"); return false;} + if( cfg.getStringValue(CN_GLOBAL, CN_DEFAULT_USER , g_global_cfg.default_user ) == kbdFailed){ LOGERROR( " default_user option parser err"); return false;} + if( cfg.getStringValue(CN_GLOBAL, CN_DEFAULT_PASSWD , g_global_cfg.default_passwd ) == kbdFailed){ LOGERROR( " default_passwd option parser err"); return false;} + if( cfg.getStringValue(CN_GLOBAL, CN_SERVER_ADDRESS , g_global_cfg.server_address ) == kbdFailed){ LOGERROR( " server_address option parser err"); return false;} + if( cfg.getIntValue(CN_GLOBAL, CN_SERVER_PORT , g_global_cfg.server_port ) == kbdFailed){ LOGERROR( " server_port option parser err"); return false;} + if( cfg.getBoolValue(CN_GLOBAL, CN_IS_HTTPS , g_global_cfg.is_https ) == kbdFailed){ LOGERROR( " is_https option parser err"); return false;} + if( cfg.getBoolValue(CN_GLOBAL, CN_IS_HEADER , g_global_cfg.is_header ) == kbdFailed){ LOGERROR( " is_header option parser err"); return false;} + if( cfg.getBoolValue(CN_GLOBAL, CN_IS_TITLE , g_global_cfg.is_title ) == kbdFailed){ LOGERROR( " is_title option parser err"); return false;} + if( cfg.getBoolValue(CN_GLOBAL, CN_IS_LEFTBAR , g_global_cfg.is_leftbar ) == kbdFailed){ LOGERROR( " is_leftbar option parser err"); return false;} + if( cfg.getBoolValue(CN_GLOBAL, CN_IS_BUTTON , g_global_cfg.is_button ) == kbdFailed){ LOGERROR( " is_button option parser err"); return false;} + if( cfg.getStringValue(CN_GLOBAL, CN_LOCAL_STATICPAGE_PATH , g_global_cfg.local_static_page_path ) == kbdFailed){ LOGERROR( " local_staticpage_path option parser err"); return false;} + if( cfg.getStringValue(CN_GLOBAL, CN_ERR_PAGE , g_global_cfg.err_page ) == kbdFailed){ LOGERROR( " err_page option parser err"); return false;} + if( cfg.getStringValue(CN_GLOBAL, CN_PERM_ERR_PAGE , g_global_cfg.perm_err_page ) == kbdFailed){ LOGERROR( " perm_err_page option parser err"); return false;} + return true; +} + + +bool CCfgParser::isValid() +{ + return g_isValid; +} + +bool CCfgParser::loadCfg(const std::string &cfgPath) +{ + kbd_public::CCommonConfigParse cfgP; + if( cfgP.load(cfgPath) == kbdFailed) + { + LOGERROR("config failed to load, please check config syntax!"); + g_isValid = false; + return false; + } + + if(!loadGlobal(cfgP)) + { + LOGERROR("global options fail to parse, please check!"); + g_isValid = false; + return false; + } + g_isValid = true; + return true; +} diff --git a/product/src/gui/plugin/iDongOpsWidget/CCfgParser.h b/product/src/gui/plugin/iDongOpsWidget/CCfgParser.h index 8b8f287a..92238499 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CCfgParser.h +++ b/product/src/gui/plugin/iDongOpsWidget/CCfgParser.h @@ -1,42 +1,42 @@ -#ifndef CCFGPARSER_H -#define CCFGPARSER_H -#include -#include "pub_utility_api/FileUtil.h" -#include "common/Common.h" -#include "idong_common.h" -#include "pub_utility_api/CommonConfigParse.h" -// 每个字段的含义可见sysconfig/his_amend_cfg.xml的注释部分 -typedef struct AMEND_GLOBAL_CONFIG -{ - bool is_perm_checked ; - std::string default_user ; - std::string default_passwd ; - std::string server_address ; - int server_port ; - bool is_https ; - bool is_header ; - bool is_title ; - bool is_leftbar ; - bool is_button ; - std::string local_static_page_path ; - std::string err_page ; - std::string perm_err_page ; -}A_GLOBAL_CFG; - -// proxy struct 数据结构 - - -class CCfgParser -{ -public: - static A_GLOBAL_CFG g_global_cfg; - static bool isValid(); - static bool loadCfg(const std::string& cfgPath = kbd_public::CFileUtil::getPathOfCfgFile(IDONG_CFG_FILENAME)); -private: - static bool loadGlobal( kbd_public::CCommonConfigParse &cfg); - static bool g_isValid; - -}; - -#endif // CCFGPARSER_H - +#ifndef CCFGPARSER_H +#define CCFGPARSER_H +#include +#include "pub_utility_api/FileUtil.h" +#include "common/Common.h" +#include "idong_common.h" +#include "pub_utility_api/CommonConfigParse.h" +// 每个字段的含义可见sysconfig/his_amend_cfg.xml的注释部分 +typedef struct AMEND_GLOBAL_CONFIG +{ + bool is_perm_checked ; + std::string default_user ; + std::string default_passwd ; + std::string server_address ; + int server_port ; + bool is_https ; + bool is_header ; + bool is_title ; + bool is_leftbar ; + bool is_button ; + std::string local_static_page_path ; + std::string err_page ; + std::string perm_err_page ; +}A_GLOBAL_CFG; + +// proxy struct 数据结构 + + +class CCfgParser +{ +public: + static A_GLOBAL_CFG g_global_cfg; + static bool isValid(); + static bool loadCfg(const std::string& cfgPath = kbd_public::CFileUtil::getPathOfCfgFile(IDONG_CFG_FILENAME)); +private: + static bool loadGlobal( kbd_public::CCommonConfigParse &cfg); + static bool g_isValid; + +}; + +#endif // CCFGPARSER_H + diff --git a/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.cpp b/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.cpp index 6d84b540..d59a0b78 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.cpp +++ b/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.cpp @@ -1,29 +1,29 @@ -#include -#include "CIDongOpsPluginWidget.h" -#include "CReportWidget.h" - -#include "CCfgParser.h" -#include "pub_logger_api/logger.h" -CIDongOpsPluginWidget::CIDongOpsPluginWidget(QObject *parent): QObject(parent) -{ - -} - -CIDongOpsPluginWidget::~CIDongOpsPluginWidget() -{ - -} - -bool CIDongOpsPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) -{ - CReportWidget *pWidget = new CReportWidget(parent,editMode); - *widget = (QWidget *)pWidget; - *reportWidget = (IPluginWidget *)pWidget; - if(!CCfgParser::loadCfg()) { LOGERROR("iDongOpsWidget parse error"); return false;} else{ LOGINFO("iDongOpsWidget parse succeed"); } - return true; -} - -void CIDongOpsPluginWidget::release() -{ - -} +#include +#include "CIDongOpsPluginWidget.h" +#include "CReportWidget.h" + +#include "CCfgParser.h" +#include "pub_logger_api/logger.h" +CIDongOpsPluginWidget::CIDongOpsPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CIDongOpsPluginWidget::~CIDongOpsPluginWidget() +{ + +} + +bool CIDongOpsPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec) +{ + CReportWidget *pWidget = new CReportWidget(parent,editMode); + *widget = (QWidget *)pWidget; + *reportWidget = (IPluginWidget *)pWidget; + if(!CCfgParser::loadCfg()) { LOGERROR("iDongOpsWidget parse error"); return false;} else{ LOGINFO("iDongOpsWidget parse succeed"); } + return true; +} + +void CIDongOpsPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.h b/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.h index 355bbec9..aeda95c6 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.h +++ b/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.h @@ -1,21 +1,21 @@ -#ifndef CREPORTPLUGINWIDGET_H -#define CREPORTPLUGINWIDGET_H - -#include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape - -class CIDongOpsPluginWidget : public QObject, public CPluginWidgetInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") - Q_INTERFACES(CPluginWidgetInterface) - -public: - CIDongOpsPluginWidget(QObject *parent = 0); - ~CIDongOpsPluginWidget(); - - bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); - void release(); -}; - -#endif // CREPORTPLUGINWIDGET_H +#ifndef CREPORTPLUGINWIDGET_H +#define CREPORTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CIDongOpsPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_INTERFACES(CPluginWidgetInterface) + +public: + CIDongOpsPluginWidget(QObject *parent = 0); + ~CIDongOpsPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **reportWidget, QVector ptrVec); + void release(); +}; + +#endif // CREPORTPLUGINWIDGET_H diff --git a/product/src/gui/plugin/iDongOpsWidget/CReportStackedWidget.cpp b/product/src/gui/plugin/iDongOpsWidget/CReportStackedWidget.cpp index b1e4b90a..b6862b75 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CReportStackedWidget.cpp +++ b/product/src/gui/plugin/iDongOpsWidget/CReportStackedWidget.cpp @@ -1,48 +1,48 @@ -#include "CReportStackedWidget.h" - -CReportStackedWidget::CReportStackedWidget(QWidget *parent) - :QStackedWidget(parent) -{ - init(); -} - -void CReportStackedWidget::init() -{ - view = new CReportWebView(this); - preview = new CReportWebView(this); - this->addWidget(view); - QWidget *previewWidget = new QWidget(this); - QPushButton *backToViewBtn = new QPushButton(this); - QVBoxLayout* vlay = new QVBoxLayout(this); - backToViewBtn->setText(tr("返回")); - vlay->setMargin(0); - vlay->addWidget(preview); - vlay->addWidget(backToViewBtn); - previewWidget->setLayout(vlay); - this->addWidget(previewWidget); - this->setCurrentIndex(0); - connect(backToViewBtn, &QPushButton::clicked, this, &CReportStackedWidget::slotBackBtnClicked); -} - -void CReportStackedWidget::slotBackBtnClicked() -{ - this->setCurrentIndex(0); - preview->load(QUrl("about:blank")); -} - -CReportWebView *CReportStackedWidget::getView(int index) -{ - if (index == 0) - { - return view; - } - else if (index == 1) - { - this->setCurrentIndex(1); - return preview; - } - else - { - return NULL; - } -} +#include "CReportStackedWidget.h" + +CReportStackedWidget::CReportStackedWidget(QWidget *parent) + :QStackedWidget(parent) +{ + init(); +} + +void CReportStackedWidget::init() +{ + view = new CReportWebView(this); + preview = new CReportWebView(this); + this->addWidget(view); + QWidget *previewWidget = new QWidget(this); + QPushButton *backToViewBtn = new QPushButton(this); + QVBoxLayout* vlay = new QVBoxLayout(this); + backToViewBtn->setText(tr("返回")); + vlay->setMargin(0); + vlay->addWidget(preview); + vlay->addWidget(backToViewBtn); + previewWidget->setLayout(vlay); + this->addWidget(previewWidget); + this->setCurrentIndex(0); + connect(backToViewBtn, &QPushButton::clicked, this, &CReportStackedWidget::slotBackBtnClicked); +} + +void CReportStackedWidget::slotBackBtnClicked() +{ + this->setCurrentIndex(0); + preview->load(QUrl("about:blank")); +} + +CReportWebView *CReportStackedWidget::getView(int index) +{ + if (index == 0) + { + return view; + } + else if (index == 1) + { + this->setCurrentIndex(1); + return preview; + } + else + { + return NULL; + } +} diff --git a/product/src/gui/plugin/iDongOpsWidget/CReportStackedWidget.h b/product/src/gui/plugin/iDongOpsWidget/CReportStackedWidget.h index 4d584796..5591a847 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CReportStackedWidget.h +++ b/product/src/gui/plugin/iDongOpsWidget/CReportStackedWidget.h @@ -1,23 +1,23 @@ -#ifndef CREPORTSTACKEDWIDGET_H -#define CREPORTSTACKEDWIDGET_H -#include "CReportWebView.h" -#include "CReportWidget.h" -#include -#include -#include -class CReportWebView; -class CReportStackedWidget: public QStackedWidget -{ - Q_OBJECT -public: - CReportStackedWidget(QWidget *parent = nullptr); - CReportWebView *view; - CReportWebView *preview; -public slots: - CReportWebView *getView(int index); -private: - void init(); - void slotBackBtnClicked(); -}; - -#endif // CREPORTSTACKEDWIDGET_H +#ifndef CREPORTSTACKEDWIDGET_H +#define CREPORTSTACKEDWIDGET_H +#include "CReportWebView.h" +#include "CReportWidget.h" +#include +#include +#include +class CReportWebView; +class CReportStackedWidget: public QStackedWidget +{ + Q_OBJECT +public: + CReportStackedWidget(QWidget *parent = nullptr); + CReportWebView *view; + CReportWebView *preview; +public slots: + CReportWebView *getView(int index); +private: + void init(); + void slotBackBtnClicked(); +}; + +#endif // CREPORTSTACKEDWIDGET_H diff --git a/product/src/gui/plugin/iDongOpsWidget/CReportWebView.cpp b/product/src/gui/plugin/iDongOpsWidget/CReportWebView.cpp index 50e4397e..7ad8ae5d 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CReportWebView.cpp +++ b/product/src/gui/plugin/iDongOpsWidget/CReportWebView.cpp @@ -1,24 +1,24 @@ -#include "CReportWebView.h" -#include -#include -#include - -CReportWebView::CReportWebView(QWidget *parent) - : QWebEngineView(parent) -{ - this->setContextMenuPolicy(Qt::NoContextMenu); -// this->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled,false); -// this->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); -// this->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); -} - -QWebEngineView *CReportWebView::createWindow(QWebEnginePage::WebWindowType type) -{ - CReportStackedWidget *StackedWidget = qobject_cast(parentWidget()); - if (!StackedWidget) - { - return nullptr; - } - return StackedWidget->getView(1); -} - +#include "CReportWebView.h" +#include +#include +#include + +CReportWebView::CReportWebView(QWidget *parent) + : QWebEngineView(parent) +{ + this->setContextMenuPolicy(Qt::NoContextMenu); +// this->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled,false); +// this->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); +// this->page()->profile()->setHttpCacheType(QWebEngineProfile::NoCache); +} + +QWebEngineView *CReportWebView::createWindow(QWebEnginePage::WebWindowType type) +{ + CReportStackedWidget *StackedWidget = qobject_cast(parentWidget()); + if (!StackedWidget) + { + return nullptr; + } + return StackedWidget->getView(1); +} + diff --git a/product/src/gui/plugin/iDongOpsWidget/CReportWebView.h b/product/src/gui/plugin/iDongOpsWidget/CReportWebView.h index 784ecd12..74655a47 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CReportWebView.h +++ b/product/src/gui/plugin/iDongOpsWidget/CReportWebView.h @@ -1,15 +1,15 @@ -#ifndef CREPORTWEBVIEW_H -#define CREPORTWEBVIEW_H - -#include -class CReportWebView : public QWebEngineView -{ - Q_OBJECT -public: - CReportWebView(QWidget *parent = nullptr); - -protected: - QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override; -}; - -#endif // CREPORTWEBVIEW_H +#ifndef CREPORTWEBVIEW_H +#define CREPORTWEBVIEW_H + +#include +class CReportWebView : public QWebEngineView +{ + Q_OBJECT +public: + CReportWebView(QWidget *parent = nullptr); + +protected: + QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override; +}; + +#endif // CREPORTWEBVIEW_H diff --git a/product/src/gui/plugin/iDongOpsWidget/CReportWidget.cpp b/product/src/gui/plugin/iDongOpsWidget/CReportWidget.cpp index 0028f55a..377fa175 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CReportWidget.cpp +++ b/product/src/gui/plugin/iDongOpsWidget/CReportWidget.cpp @@ -1,422 +1,422 @@ -#include "CReportWidget.h" -#include "pub_logger_api/logger.h" -#include -#include -#include -#include -#include -#include -#include - -CReportWidget::CReportWidget(QWidget *parent, bool editMode) - : QWidget(parent) -{ - m_updateTimer = NULL; - stackedWidget = NULL; - m_rtdbAccess = NULL; - if(editMode) - { - QLabel *label = new QLabel(this); - label->setPixmap(QPixmap(":/report")); - label->setScaledContents(true); - QGridLayout *lay = new QGridLayout(this); - lay->addWidget(label); - this->setLayout(lay); - } - else - { - init(); - if(!parseSiteMap()){ LOGERROR("SiteMap parse error"); } - } - -} - -CReportWidget::~CReportWidget() -{ - if(m_updateTimer) - { - m_updateTimer->stop(); - delete m_updateTimer; - m_updateTimer = NULL; - } - if(stackedWidget) - { - QWebEngineProfile * engineProfile = stackedWidget->view->page()->profile(); - engineProfile->clearHttpCache(); - QWebEngineCookieStore *cookie = engineProfile->cookieStore(); - cookie->deleteAllCookies(); - delete stackedWidget; - stackedWidget = NULL; - } - if(m_rtdbAccess != NULL) - { - delete m_rtdbAccess; - } - m_rtdbAccess = NULL; -} - - -void CReportWidget::init() -{ -// m_rtdbAccess = new kbd_dbms::CRdbAccess(); - QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); - QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); - stackedWidget = new CReportStackedWidget(this); - QHBoxLayout* hlay = new QHBoxLayout(this); - hlay->addWidget(stackedWidget); - hlay->setMargin(0); - this->setLayout(hlay); -// m_updateTimer = new QTimer(); -// m_updateTimer->setInterval(5000); -// connect(m_updateTimer, &QTimer::timeout, this, &CReportWidget::slotUpdateTime); - connect(stackedWidget->view, &QWebEngineView::loadFinished, this, &CReportWidget::slotLoadFinish); -// connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, -// this, &CReportWidget::handleDownloadRequest); - m_UsergId = -1; - m_isHTML = false; - m_changeAddr = false; - m_addrNum = 0; -// initSysInfo(); -} - -void CReportWidget::initSysInfo() -{ - if (createSysInfoInstance(m_sysInfoPtr)) - { - SNodeInfo LocalNode,ServerNode1,ServerNode2; - m_sysInfoPtr->getLocalNodeInfo(LocalNode); //获取当前节点信息 - int DomainId=LocalNode.nDomainId; //获取当前节点所属域ID - SAppInfo AppInfo; - m_sysInfoPtr->getAppInfoByName("COMAPP", AppInfo); - int AppId = AppInfo.nId; - SAppDeploy AppDeploy; - m_sysInfoPtr->getAppDeployById(DomainId,AppId,AppDeploy); //获取当前域公共应用部署信息 - std::string ServerNodeName1 = AppDeploy.strNode1; //获取当前域公共应用部署的第一个节点名 - m_sysInfoPtr->getNodeInfoByName(ServerNodeName1,ServerNode1); //获取公共应用部署的节点信息 - m_ServerAddr[0] = ServerNode1.strNic1Addr; //获取公共应用部署的节点IP地址 - m_ServerNode[0] = ServerNodeName1; - if(AppDeploy.strNode2 != "") - { - std::string ServerNodeName2 = AppDeploy.strNode2; - m_sysInfoPtr->getNodeInfoByName(ServerNodeName2,ServerNode2); - m_ServerAddr[1] = ServerNode2.strNic1Addr; - m_ServerNode[1] = ServerNodeName2; - m_changeAddr = true; - } - setNicAddr(AppId); - } -} - -void CReportWidget::setNicAddr(int appId) -{ - std::string ipAddr1 = ""; - std::string ipAddr2 = ""; - std::string node1 = ""; - std::string node2 = ""; - std::vector> vector = getRunRedundancyInfoByAppid(appId); - for(int i=0; i vec = vector.at(i); - std::string node_name = vec.at(0).toStdString(); - int is_active = vec.at(1).toInt(); - int is_master = vec.at(2).toInt(); - int is_slave = vec.at(3).toInt(); - std::string ip1 = vec.at(4).toStdString(); - int ip1_active = vec.at(5).toInt(); - std::string ip2 = vec.at(6).toStdString(); - int ip2_active = vec.at(7).toInt(); - - if(is_active != 1) - { - continue; - } - if(is_master == 1) - { - node1 = node_name; - if(ip1_active == 1) - ipAddr1 = ip1; - else if(ip2_active == 1) - ipAddr1 = ip2; - } - else if(is_slave == 1) - { - node2 = node_name; - if(ip1_active == 1) - ipAddr2 = ip1; - else if(ip2_active == 1) - ipAddr2 = ip2; - } - } - if(ipAddr1 == "" && ipAddr2 == "") - {} - else if(ipAddr1 == "") - { - std::string temp = getAnotherIp(node2); - m_ServerAddr[0] = temp; - m_ServerAddr[1] = ipAddr2; - } - else if(ipAddr2 == "") - { - std::string temp = getAnotherIp(node1); - m_ServerAddr[0] = ipAddr1; - m_ServerAddr[1] = temp; - } - else - { - m_ServerAddr[0] = ipAddr1; - m_ServerAddr[1] = ipAddr2; - } -} - -std::string CReportWidget::getAnotherIp(const std::string &node) -{ - std::string ret = ""; - if(node == m_ServerNode[0]) - { - ret = m_ServerAddr[1]; - } - else - { - ret = m_ServerAddr[0]; - } - return ret; -} - -std::vector> CReportWidget::getRunRedundancyInfoByAppid(int appId) -{ - std::vector> vector; - if(m_rtdbAccess->open("base", "sys_run_redundancy_info")) - { - kbd_dbms::CONDINFO condition; - memcpy(condition.name, "app_id", strlen("app_id")); - condition.logicalop = ATTRCOND_AND; - condition.relationop = ATTRCOND_EQU; - condition.conditionval = appId; - - std::vector vecCondInfo; - vecCondInfo.push_back(condition); - - kbd_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("node_name"); - columns.push_back("is_active"); - columns.push_back("is_master"); - columns.push_back("is_slave"); - columns.push_back("ip1"); - columns.push_back("ip1_active"); - columns.push_back("ip2"); - columns.push_back("ip2_active"); - - if(m_rtdbAccess->select(vecCondInfo, result, columns)) - { - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - std::vector temp; - kbd_dbms::CVarType node_name; - kbd_dbms::CVarType is_active; - kbd_dbms::CVarType is_master; - kbd_dbms::CVarType is_slave; - kbd_dbms::CVarType ip1; - kbd_dbms::CVarType ip1_active; - kbd_dbms::CVarType ip2; - kbd_dbms::CVarType ip2_active; - result.getColumnValue(nIndex, 0, node_name); - result.getColumnValue(nIndex, 1, is_active); - result.getColumnValue(nIndex, 2, is_master); - result.getColumnValue(nIndex, 3, is_slave); - result.getColumnValue(nIndex, 4, ip1); - result.getColumnValue(nIndex, 5, ip1_active); - result.getColumnValue(nIndex, 6, ip2); - result.getColumnValue(nIndex, 7, ip2_active); - temp.push_back(node_name); - temp.push_back(is_active); - temp.push_back(is_master); - temp.push_back(is_slave); - temp.push_back(ip1); - temp.push_back(ip1_active); - temp.push_back(ip2); - temp.push_back(ip2_active); - vector.push_back(temp); - } - } - m_rtdbAccess->close(); - } - return vector; -} - -void CReportWidget::updateUserInfo() -{ - m_permMngPtr = kbd_service::getPermMngInstance("base"); - m_permMngPtr->PermDllInit(); - if (m_permMngPtr != NULL) - { - int UserId,UsergId,Level,LoginSec; - std::string UserName; - m_permMngPtr->CurUser(UserId,UsergId,Level,LoginSec,UserName); //获取当前登陆用户的所属用户组ID - if (UsergId != m_UsergId) - { - m_UsergId = UsergId; - } - loadPage(); - } -} - -void CReportWidget::loadPage() -{ - m_isHTML = true; - if(m_browserMode == ViewMode) - { - QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum])+":1120/page/view.html"; - QUrl url(urlstr); - QUrlQuery query; - query.addQueryItem("userGroup", QString::number(m_UsergId)); - url.setQuery(query); - stackedWidget->view->load(url); - } - else if (m_browserMode == EditMode) - { - if(!checkReportEditPerm()) - { - std::string path = kbd_public::CFileUtil::getCurModuleDir(); - stackedWidget->view->load(QUrl::fromLocalFile(QString::fromStdString(path)+"../../data/report/PERM_FORBIT_EDIT.html")); - return; - } - QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum])+":1120/page/design.html"; - QUrl url(urlstr); - stackedWidget->view->load(url); - } -} - -void CReportWidget::slotUpdateTime() -{ - m_updateTimer->stop(); - if (m_changeAddr) - { - m_addrNum = 1 - m_addrNum; - } - loadPage(); -} - -void CReportWidget::slotLoadFinish(bool ok) -{ - if(m_isHTML) - { - if (!ok) - { - stackedWidget->view->load(QUrl::fromLocalFile(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) - + CCfgParser::g_global_cfg.local_static_page_path.c_str() - + CCfgParser::g_global_cfg.err_page.c_str() )); - } - } - m_isHTML = false; -} - -void CReportWidget::handleDownloadRequest(QWebEngineDownloadItem *download) -{ - QString path = QFileDialog::getSaveFileName(this, tr("导出报表"), download->path()); - if (!path.isEmpty()) - { - download->setPath(path); - download->accept(); - } -} - -void CReportWidget::switchMode(int mode) -{ - m_browserMode = (browserMode)mode; - // updateUserInfo(); -} - -bool CReportWidget::parseSiteMap(const std::string &jsonDir, const std::string &jsonFileName) -{ - QString filePath = (jsonDir + jsonFileName).c_str(); - QFile loadFile( filePath ); - if(!loadFile.open(QIODevice::ReadOnly)) - { - qDebug() << "could't open file 'idongops_sitemap.json'!"; - return false; - } - - QByteArray data = loadFile.readAll(); - loadFile.close(); - - QJsonParseError json_error; - QJsonDocument jsonDoc(QJsonDocument::fromJson(data, &json_error)); - - if(json_error.error != QJsonParseError::NoError) - { - qDebug() << "'sitemap.json' parse Error!"; - return false; - } - - QJsonObject root = jsonDoc.object(); - if(root.contains("items")) - { - QJsonArray itemArray = root.value("items").toArray(); - for(int nIndex(0); nIndex< itemArray.size(); nIndex++) - { - QJsonObject topLevelObject = itemArray[nIndex].toObject(); - - if(!topLevelObject.value("name").toString().isEmpty() && !topLevelObject.value("url").toString().isEmpty()) - { - m_mapName2Utl[topLevelObject.value("name").toString()] = topLevelObject.value("url").toString(); - } - } - } - return true; -} - -QString CReportWidget::getFirstUrl(const QString &baseUrl) -{ - isFirstLoaded = true; - return QStringLiteral("http://") + CCfgParser::g_global_cfg.server_address.c_str() + "/Account/AutoLogOn/?url=" - + QUrl::toPercentEncoding( QStringLiteral("http://") + CCfgParser::g_global_cfg.server_address.c_str() + baseUrl ) - + "&showHeader=" + ( CCfgParser::g_global_cfg.is_header ? "true":"false" ) - + "&showLeftbar=" + ( CCfgParser::g_global_cfg.is_leftbar ? "true":"false" ) - + "&showTitle=" + ( CCfgParser::g_global_cfg.is_title ?"true":"false" ) - + "&showBottom=" + ( CCfgParser::g_global_cfg.is_button?"true":"false" ) - + "&info=%5b%22%22%2c%22" - + CCfgParser::g_global_cfg.default_user.c_str() - + "%22%2c%22" - + CCfgParser::g_global_cfg.default_passwd.c_str() + "%22%5d" ; -} - -QString CReportWidget::getUrl(const QString &baseUrl) -{ - return QStringLiteral("http://") + CCfgParser::g_global_cfg.server_address.c_str() + baseUrl ; - -} - -void CReportWidget::loadPageByName(const QString &name) -{ - if(m_mapName2Utl.find(name) != m_mapName2Utl.end()) - { - LOGINFO(QString("loadPageByName %1--%2").arg(name).arg(m_mapName2Utl[name]).toStdString().c_str() ); - -// if(!isFirstLoaded) {stackedWidget->view->load( getFirstUrl(m_mapName2Utl[name]) );} -// else {stackedWidget->view->load( getUrl(m_mapName2Utl[name]) );} - stackedWidget->view->load( getFirstUrl(m_mapName2Utl[name]) ); - - m_isHTML = true; - } -} - -void CReportWidget::UserChanged() -{ -// updateUserInfo(); -} - -bool CReportWidget::checkReportEditPerm() -{ - kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); - if(permMngPtr != NULL) - { - permMngPtr->PermDllInit(); - std::string func = "FUNC_NOM_RPT_EDIT"; - if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &func)) - { - return true; - } - } - return false; -} +#include "CReportWidget.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include +#include +#include +#include + +CReportWidget::CReportWidget(QWidget *parent, bool editMode) + : QWidget(parent) +{ + m_updateTimer = NULL; + stackedWidget = NULL; + m_rtdbAccess = NULL; + if(editMode) + { + QLabel *label = new QLabel(this); + label->setPixmap(QPixmap(":/report")); + label->setScaledContents(true); + QGridLayout *lay = new QGridLayout(this); + lay->addWidget(label); + this->setLayout(lay); + } + else + { + init(); + if(!parseSiteMap()){ LOGERROR("SiteMap parse error"); } + } + +} + +CReportWidget::~CReportWidget() +{ + if(m_updateTimer) + { + m_updateTimer->stop(); + delete m_updateTimer; + m_updateTimer = NULL; + } + if(stackedWidget) + { + QWebEngineProfile * engineProfile = stackedWidget->view->page()->profile(); + engineProfile->clearHttpCache(); + QWebEngineCookieStore *cookie = engineProfile->cookieStore(); + cookie->deleteAllCookies(); + delete stackedWidget; + stackedWidget = NULL; + } + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; +} + + +void CReportWidget::init() +{ +// m_rtdbAccess = new kbd_dbms::CRdbAccess(); + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); + stackedWidget = new CReportStackedWidget(this); + QHBoxLayout* hlay = new QHBoxLayout(this); + hlay->addWidget(stackedWidget); + hlay->setMargin(0); + this->setLayout(hlay); +// m_updateTimer = new QTimer(); +// m_updateTimer->setInterval(5000); +// connect(m_updateTimer, &QTimer::timeout, this, &CReportWidget::slotUpdateTime); + connect(stackedWidget->view, &QWebEngineView::loadFinished, this, &CReportWidget::slotLoadFinish); +// connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, +// this, &CReportWidget::handleDownloadRequest); + m_UsergId = -1; + m_isHTML = false; + m_changeAddr = false; + m_addrNum = 0; +// initSysInfo(); +} + +void CReportWidget::initSysInfo() +{ + if (createSysInfoInstance(m_sysInfoPtr)) + { + SNodeInfo LocalNode,ServerNode1,ServerNode2; + m_sysInfoPtr->getLocalNodeInfo(LocalNode); //获取当前节点信息 + int DomainId=LocalNode.nDomainId; //获取当前节点所属域ID + SAppInfo AppInfo; + m_sysInfoPtr->getAppInfoByName("COMAPP", AppInfo); + int AppId = AppInfo.nId; + SAppDeploy AppDeploy; + m_sysInfoPtr->getAppDeployById(DomainId,AppId,AppDeploy); //获取当前域公共应用部署信息 + std::string ServerNodeName1 = AppDeploy.strNode1; //获取当前域公共应用部署的第一个节点名 + m_sysInfoPtr->getNodeInfoByName(ServerNodeName1,ServerNode1); //获取公共应用部署的节点信息 + m_ServerAddr[0] = ServerNode1.strNic1Addr; //获取公共应用部署的节点IP地址 + m_ServerNode[0] = ServerNodeName1; + if(AppDeploy.strNode2 != "") + { + std::string ServerNodeName2 = AppDeploy.strNode2; + m_sysInfoPtr->getNodeInfoByName(ServerNodeName2,ServerNode2); + m_ServerAddr[1] = ServerNode2.strNic1Addr; + m_ServerNode[1] = ServerNodeName2; + m_changeAddr = true; + } + setNicAddr(AppId); + } +} + +void CReportWidget::setNicAddr(int appId) +{ + std::string ipAddr1 = ""; + std::string ipAddr2 = ""; + std::string node1 = ""; + std::string node2 = ""; + std::vector> vector = getRunRedundancyInfoByAppid(appId); + for(int i=0; i vec = vector.at(i); + std::string node_name = vec.at(0).toStdString(); + int is_active = vec.at(1).toInt(); + int is_master = vec.at(2).toInt(); + int is_slave = vec.at(3).toInt(); + std::string ip1 = vec.at(4).toStdString(); + int ip1_active = vec.at(5).toInt(); + std::string ip2 = vec.at(6).toStdString(); + int ip2_active = vec.at(7).toInt(); + + if(is_active != 1) + { + continue; + } + if(is_master == 1) + { + node1 = node_name; + if(ip1_active == 1) + ipAddr1 = ip1; + else if(ip2_active == 1) + ipAddr1 = ip2; + } + else if(is_slave == 1) + { + node2 = node_name; + if(ip1_active == 1) + ipAddr2 = ip1; + else if(ip2_active == 1) + ipAddr2 = ip2; + } + } + if(ipAddr1 == "" && ipAddr2 == "") + {} + else if(ipAddr1 == "") + { + std::string temp = getAnotherIp(node2); + m_ServerAddr[0] = temp; + m_ServerAddr[1] = ipAddr2; + } + else if(ipAddr2 == "") + { + std::string temp = getAnotherIp(node1); + m_ServerAddr[0] = ipAddr1; + m_ServerAddr[1] = temp; + } + else + { + m_ServerAddr[0] = ipAddr1; + m_ServerAddr[1] = ipAddr2; + } +} + +std::string CReportWidget::getAnotherIp(const std::string &node) +{ + std::string ret = ""; + if(node == m_ServerNode[0]) + { + ret = m_ServerAddr[1]; + } + else + { + ret = m_ServerAddr[0]; + } + return ret; +} + +std::vector> CReportWidget::getRunRedundancyInfoByAppid(int appId) +{ + std::vector> vector; + if(m_rtdbAccess->open("base", "sys_run_redundancy_info")) + { + kbd_dbms::CONDINFO condition; + memcpy(condition.name, "app_id", strlen("app_id")); + condition.logicalop = ATTRCOND_AND; + condition.relationop = ATTRCOND_EQU; + condition.conditionval = appId; + + std::vector vecCondInfo; + vecCondInfo.push_back(condition); + + kbd_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("node_name"); + columns.push_back("is_active"); + columns.push_back("is_master"); + columns.push_back("is_slave"); + columns.push_back("ip1"); + columns.push_back("ip1_active"); + columns.push_back("ip2"); + columns.push_back("ip2_active"); + + if(m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + std::vector temp; + kbd_dbms::CVarType node_name; + kbd_dbms::CVarType is_active; + kbd_dbms::CVarType is_master; + kbd_dbms::CVarType is_slave; + kbd_dbms::CVarType ip1; + kbd_dbms::CVarType ip1_active; + kbd_dbms::CVarType ip2; + kbd_dbms::CVarType ip2_active; + result.getColumnValue(nIndex, 0, node_name); + result.getColumnValue(nIndex, 1, is_active); + result.getColumnValue(nIndex, 2, is_master); + result.getColumnValue(nIndex, 3, is_slave); + result.getColumnValue(nIndex, 4, ip1); + result.getColumnValue(nIndex, 5, ip1_active); + result.getColumnValue(nIndex, 6, ip2); + result.getColumnValue(nIndex, 7, ip2_active); + temp.push_back(node_name); + temp.push_back(is_active); + temp.push_back(is_master); + temp.push_back(is_slave); + temp.push_back(ip1); + temp.push_back(ip1_active); + temp.push_back(ip2); + temp.push_back(ip2_active); + vector.push_back(temp); + } + } + m_rtdbAccess->close(); + } + return vector; +} + +void CReportWidget::updateUserInfo() +{ + m_permMngPtr = kbd_service::getPermMngInstance("base"); + m_permMngPtr->PermDllInit(); + if (m_permMngPtr != NULL) + { + int UserId,UsergId,Level,LoginSec; + std::string UserName; + m_permMngPtr->CurUser(UserId,UsergId,Level,LoginSec,UserName); //获取当前登陆用户的所属用户组ID + if (UsergId != m_UsergId) + { + m_UsergId = UsergId; + } + loadPage(); + } +} + +void CReportWidget::loadPage() +{ + m_isHTML = true; + if(m_browserMode == ViewMode) + { + QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum])+":1120/page/view.html"; + QUrl url(urlstr); + QUrlQuery query; + query.addQueryItem("userGroup", QString::number(m_UsergId)); + url.setQuery(query); + stackedWidget->view->load(url); + } + else if (m_browserMode == EditMode) + { + if(!checkReportEditPerm()) + { + std::string path = kbd_public::CFileUtil::getCurModuleDir(); + stackedWidget->view->load(QUrl::fromLocalFile(QString::fromStdString(path)+"../../data/report/PERM_FORBIT_EDIT.html")); + return; + } + QString urlstr ="http://"+QString::fromStdString(m_ServerAddr[m_addrNum])+":1120/page/design.html"; + QUrl url(urlstr); + stackedWidget->view->load(url); + } +} + +void CReportWidget::slotUpdateTime() +{ + m_updateTimer->stop(); + if (m_changeAddr) + { + m_addrNum = 1 - m_addrNum; + } + loadPage(); +} + +void CReportWidget::slotLoadFinish(bool ok) +{ + if(m_isHTML) + { + if (!ok) + { + stackedWidget->view->load(QUrl::fromLocalFile(QString::fromStdString(kbd_public::CFileUtil::getCurModuleDir()) + + CCfgParser::g_global_cfg.local_static_page_path.c_str() + + CCfgParser::g_global_cfg.err_page.c_str() )); + } + } + m_isHTML = false; +} + +void CReportWidget::handleDownloadRequest(QWebEngineDownloadItem *download) +{ + QString path = QFileDialog::getSaveFileName(this, tr("导出报表"), download->path()); + if (!path.isEmpty()) + { + download->setPath(path); + download->accept(); + } +} + +void CReportWidget::switchMode(int mode) +{ + m_browserMode = (browserMode)mode; + // updateUserInfo(); +} + +bool CReportWidget::parseSiteMap(const std::string &jsonDir, const std::string &jsonFileName) +{ + QString filePath = (jsonDir + jsonFileName).c_str(); + QFile loadFile( filePath ); + if(!loadFile.open(QIODevice::ReadOnly)) + { + qDebug() << "could't open file 'idongops_sitemap.json'!"; + return false; + } + + QByteArray data = loadFile.readAll(); + loadFile.close(); + + QJsonParseError json_error; + QJsonDocument jsonDoc(QJsonDocument::fromJson(data, &json_error)); + + if(json_error.error != QJsonParseError::NoError) + { + qDebug() << "'sitemap.json' parse Error!"; + return false; + } + + QJsonObject root = jsonDoc.object(); + if(root.contains("items")) + { + QJsonArray itemArray = root.value("items").toArray(); + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + + if(!topLevelObject.value("name").toString().isEmpty() && !topLevelObject.value("url").toString().isEmpty()) + { + m_mapName2Utl[topLevelObject.value("name").toString()] = topLevelObject.value("url").toString(); + } + } + } + return true; +} + +QString CReportWidget::getFirstUrl(const QString &baseUrl) +{ + isFirstLoaded = true; + return QStringLiteral("http://") + CCfgParser::g_global_cfg.server_address.c_str() + "/Account/AutoLogOn/?url=" + + QUrl::toPercentEncoding( QStringLiteral("http://") + CCfgParser::g_global_cfg.server_address.c_str() + baseUrl ) + + "&showHeader=" + ( CCfgParser::g_global_cfg.is_header ? "true":"false" ) + + "&showLeftbar=" + ( CCfgParser::g_global_cfg.is_leftbar ? "true":"false" ) + + "&showTitle=" + ( CCfgParser::g_global_cfg.is_title ?"true":"false" ) + + "&showBottom=" + ( CCfgParser::g_global_cfg.is_button?"true":"false" ) + + "&info=%5b%22%22%2c%22" + + CCfgParser::g_global_cfg.default_user.c_str() + + "%22%2c%22" + + CCfgParser::g_global_cfg.default_passwd.c_str() + "%22%5d" ; +} + +QString CReportWidget::getUrl(const QString &baseUrl) +{ + return QStringLiteral("http://") + CCfgParser::g_global_cfg.server_address.c_str() + baseUrl ; + +} + +void CReportWidget::loadPageByName(const QString &name) +{ + if(m_mapName2Utl.find(name) != m_mapName2Utl.end()) + { + LOGINFO(QString("loadPageByName %1--%2").arg(name).arg(m_mapName2Utl[name]).toStdString().c_str() ); + +// if(!isFirstLoaded) {stackedWidget->view->load( getFirstUrl(m_mapName2Utl[name]) );} +// else {stackedWidget->view->load( getUrl(m_mapName2Utl[name]) );} + stackedWidget->view->load( getFirstUrl(m_mapName2Utl[name]) ); + + m_isHTML = true; + } +} + +void CReportWidget::UserChanged() +{ +// updateUserInfo(); +} + +bool CReportWidget::checkReportEditPerm() +{ + kbd_service::CPermMngApiPtr permMngPtr = kbd_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::string func = "FUNC_NOM_RPT_EDIT"; + if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &func)) + { + return true; + } + } + return false; +} diff --git a/product/src/gui/plugin/iDongOpsWidget/CReportWidget.h b/product/src/gui/plugin/iDongOpsWidget/CReportWidget.h index 5efa4870..c5994d7a 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CReportWidget.h +++ b/product/src/gui/plugin/iDongOpsWidget/CReportWidget.h @@ -1,85 +1,85 @@ -#ifndef CREPORTWIDGET_H -#define CREPORTWIDGET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dbms/rdb_api/CRdbAccess.h" - -#include "idong_common.h" -using namespace kbd_service; -using namespace kbd_public; -class CReportWebView; -class CReportStackedWidget; - -class CReportWidget : public QWidget -{ - Q_OBJECT - -public: - explicit CReportWidget(QWidget *parent, bool editMode); - ~CReportWidget(); - enum browserMode - { - ViewMode, - EditMode - }; - -public slots: - void UserChanged(); - void switchMode(int mode); - void loadPageByName(const QString &name); - -private: - bool parseSiteMap(const std::string& jsonDir= kbd_public::CFileUtil::getCurModuleDir() + CN_FilePath_Model, - const std::string& jsonFileName = IDONG_SITEMAP_FILENAME); - - QString getFirstUrl(const QString& baseUrl); - QString getUrl(const QString& baseUrl); - - CReportStackedWidget *stackedWidget; - kbd_dbms::CRdbAccess * m_rtdbAccess; - CPermMngApiPtr m_permMngPtr; - CSysInfoInterfacePtr m_sysInfoPtr; - QTimer * m_updateTimer; - std::string m_ServerNode[2]; - std::string m_ServerAddr[2]; - browserMode m_browserMode; - bool m_isHTML; - bool m_changeAddr; - int m_UsergId; - int m_addrNum; - void init(); - void initSysInfo(); - void setNicAddr(int appId); - std::string getAnotherIp(const std::string &node); - std::vector > getRunRedundancyInfoByAppid(int appId); - void updateUserInfo(); - void loadPage(); - void slotLoadFinish(bool ok); - void slotUpdateTime(); - void handleDownloadRequest(QWebEngineDownloadItem *download); - bool checkReportEditPerm(); - QMap m_mapName2Utl; - bool isFirstLoaded=false; -}; - - - - -#endif // CREPORTWIDGET_H +#ifndef CREPORTWIDGET_H +#define CREPORTWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" + +#include "idong_common.h" +using namespace kbd_service; +using namespace kbd_public; +class CReportWebView; +class CReportStackedWidget; + +class CReportWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CReportWidget(QWidget *parent, bool editMode); + ~CReportWidget(); + enum browserMode + { + ViewMode, + EditMode + }; + +public slots: + void UserChanged(); + void switchMode(int mode); + void loadPageByName(const QString &name); + +private: + bool parseSiteMap(const std::string& jsonDir= kbd_public::CFileUtil::getCurModuleDir() + CN_FilePath_Model, + const std::string& jsonFileName = IDONG_SITEMAP_FILENAME); + + QString getFirstUrl(const QString& baseUrl); + QString getUrl(const QString& baseUrl); + + CReportStackedWidget *stackedWidget; + kbd_dbms::CRdbAccess * m_rtdbAccess; + CPermMngApiPtr m_permMngPtr; + CSysInfoInterfacePtr m_sysInfoPtr; + QTimer * m_updateTimer; + std::string m_ServerNode[2]; + std::string m_ServerAddr[2]; + browserMode m_browserMode; + bool m_isHTML; + bool m_changeAddr; + int m_UsergId; + int m_addrNum; + void init(); + void initSysInfo(); + void setNicAddr(int appId); + std::string getAnotherIp(const std::string &node); + std::vector > getRunRedundancyInfoByAppid(int appId); + void updateUserInfo(); + void loadPage(); + void slotLoadFinish(bool ok); + void slotUpdateTime(); + void handleDownloadRequest(QWebEngineDownloadItem *download); + bool checkReportEditPerm(); + QMap m_mapName2Utl; + bool isFirstLoaded=false; +}; + + + + +#endif // CREPORTWIDGET_H diff --git a/product/src/gui/plugin/iDongOpsWidget/iDongOpsWidget.pro b/product/src/gui/plugin/iDongOpsWidget/iDongOpsWidget.pro index 15343ea5..ac04edd6 100644 --- a/product/src/gui/plugin/iDongOpsWidget/iDongOpsWidget.pro +++ b/product/src/gui/plugin/iDongOpsWidget/iDongOpsWidget.pro @@ -1,64 +1,64 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-11-13T14:55:16 -# -#------------------------------------------------- - -QT += core gui webenginewidgets xml - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = iDongOpsWidget -TEMPLATE = lib - -CONFIG += plugin - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - CReportWidget.cpp \ -# main.cpp \ - CReportWebView.cpp \ - CReportStackedWidget.cpp \ - CCfgParser.cpp \ - CIDongOpsPluginWidget.cpp - -HEADERS += \ - CReportWidget.h \ - CReportWebView.h \ - CReportStackedWidget.h \ - CCfgParser.h \ - idong_common.h \ - CIDongOpsPluginWidget.h - -RESOURCES += \ - resource.qrc - -LIBS += \ - -lboost_filesystem \ - -llog4cplus \ - -lpub_logger_api \ - -lperm_mng_api \ - -lpub_sysinfo_api \ - -lpub_utility_api \ - -lrdb_api - -#include($$PWD/../../idl_files/idl_files.pri) - -COMMON_PRI=$$PWD/../../../common.pri -exists($$COMMON_PRI) { - include($$COMMON_PRI) -}else { - error("FATAL error: can not find common.pri") -} - +#------------------------------------------------- +# +# Project created by QtCreator 2018-11-13T14:55:16 +# +#------------------------------------------------- + +QT += core gui webenginewidgets xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = iDongOpsWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + CReportWidget.cpp \ +# main.cpp \ + CReportWebView.cpp \ + CReportStackedWidget.cpp \ + CCfgParser.cpp \ + CIDongOpsPluginWidget.cpp + +HEADERS += \ + CReportWidget.h \ + CReportWebView.h \ + CReportStackedWidget.h \ + CCfgParser.h \ + idong_common.h \ + CIDongOpsPluginWidget.h + +RESOURCES += \ + resource.qrc + +LIBS += \ + -lboost_filesystem \ + -llog4cplus \ + -lpub_logger_api \ + -lperm_mng_api \ + -lpub_sysinfo_api \ + -lpub_utility_api \ + -lrdb_api + +#include($$PWD/../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/gui/plugin/iDongOpsWidget/idong_common.h b/product/src/gui/plugin/iDongOpsWidget/idong_common.h index 5f10efb9..0f05ab75 100644 --- a/product/src/gui/plugin/iDongOpsWidget/idong_common.h +++ b/product/src/gui/plugin/iDongOpsWidget/idong_common.h @@ -1,61 +1,61 @@ -#ifndef IDONG_COMMON_H -#define IDONG_COMMON_H - -#include -#include -#include - -#include - -const std::string CN_PROCESSNAME = "iDongOpsWidget"; - -#define OPT_DESC_APP "app" -#define OPT_DESC_HELP "help" - -//< 表名 -#define INST_DEF "stat_inst_def" - - -// rdb 列名和值 -#define INST_DEF_COL_PERIOD "period" -#define INST_DEF_COL_PERIOD_DISABLED_VALUE 0 - -#define COL_TRIGGER_METHOD "trigger_method" -#define COL_TRIGGER_METHOD_DISABLED_VALUE 0 -#define COL_TRIGGER_METHOD_PERIOD 1 //< 周期触发 -#define COL_TRIGGER_METHOD_TIMER 2 //< 定时触发 -#define COL_TRIGGER_METHOD_PARACHG 3 //< 输入变动触发 - -#define RT_ANA_TBL "analog" -#define RT_ACC_TBL "accuml" -#define RT_MIX_TBL "mix" -#define RT_DIG_TBL "digital" - - - -#define TEMPLATE_DEF_COL_TERMPLATE_TAG "template_tag" -#define TEMPLATE_PARA_COL_SORT "sort" - -#define COL_INST_TAG "inst_tag" -#define COL_GRP_TAG "para_grp_tag" -#define COL_SORT "sort" -#define COL_RANK "rank" -#define COL_RANK_TOP "1" -#define COL_RANK_SECOND "2" -#define COL_VALUE "value" -#define COL_STATUS "status" -#define COL_STATUS_VALUE_VALID 1 -#define COL_STATUS_VALUE_INVALID 0 -// 返回值 -#define kbdFailedRdb 2 // 内存库错误 - -#define valid_value 0 -#define invalid_value 1 - -const std::string IDONG_CFG_FILENAME = "idong_ops_cfg.xml"; -const std::string IDONG_SITEMAP_FILENAME = "idong_sitemap.json"; - -const std::string CN_FilePath_Model = "../../data/model/"; - - -#endif // IDONG_COMMON_H +#ifndef IDONG_COMMON_H +#define IDONG_COMMON_H + +#include +#include +#include + +#include + +const std::string CN_PROCESSNAME = "iDongOpsWidget"; + +#define OPT_DESC_APP "app" +#define OPT_DESC_HELP "help" + +//< 表名 +#define INST_DEF "stat_inst_def" + + +// rdb 列名和值 +#define INST_DEF_COL_PERIOD "period" +#define INST_DEF_COL_PERIOD_DISABLED_VALUE 0 + +#define COL_TRIGGER_METHOD "trigger_method" +#define COL_TRIGGER_METHOD_DISABLED_VALUE 0 +#define COL_TRIGGER_METHOD_PERIOD 1 //< 周期触发 +#define COL_TRIGGER_METHOD_TIMER 2 //< 定时触发 +#define COL_TRIGGER_METHOD_PARACHG 3 //< 输入变动触发 + +#define RT_ANA_TBL "analog" +#define RT_ACC_TBL "accuml" +#define RT_MIX_TBL "mix" +#define RT_DIG_TBL "digital" + + + +#define TEMPLATE_DEF_COL_TERMPLATE_TAG "template_tag" +#define TEMPLATE_PARA_COL_SORT "sort" + +#define COL_INST_TAG "inst_tag" +#define COL_GRP_TAG "para_grp_tag" +#define COL_SORT "sort" +#define COL_RANK "rank" +#define COL_RANK_TOP "1" +#define COL_RANK_SECOND "2" +#define COL_VALUE "value" +#define COL_STATUS "status" +#define COL_STATUS_VALUE_VALID 1 +#define COL_STATUS_VALUE_INVALID 0 +// 返回值 +#define kbdFailedRdb 2 // 内存库错误 + +#define valid_value 0 +#define invalid_value 1 + +const std::string IDONG_CFG_FILENAME = "idong_ops_cfg.xml"; +const std::string IDONG_SITEMAP_FILENAME = "idong_sitemap.json"; + +const std::string CN_FilePath_Model = "../../data/model/"; + + +#endif // IDONG_COMMON_H diff --git a/product/src/gui/plugin/iDongOpsWidget/resource.qrc b/product/src/gui/plugin/iDongOpsWidget/resource.qrc index 37e0be38..47245610 100644 --- a/product/src/gui/plugin/iDongOpsWidget/resource.qrc +++ b/product/src/gui/plugin/iDongOpsWidget/resource.qrc @@ -1,5 +1,5 @@ - - - opsIdx.png - - + + + opsIdx.png + + diff --git a/product/src/gui/plugin/plugin.pro b/product/src/gui/plugin/plugin.pro index 966b7467..aa529a4e 100644 --- a/product/src/gui/plugin/plugin.pro +++ b/product/src/gui/plugin/plugin.pro @@ -1,59 +1,59 @@ -#不要加上ordered,如有依赖需要,请用depends功能 - - -TEMPLATE=subdirs -SUBDIRS+= \ - IpcViewerWidget \ - DataOptWidget \ - AlarmWidget \ - EventWidget \ - WorkTicket \ - OrderManageWidget \ - NavigationWidget \ - TrendCurves \ - LinkCtrlWidget \ - SequenceWidget \ - SequenceManageWidget \ - ReportWidget \ - ConstCurves \ - AlarmStatisWidget \ - DevHisDataWidget \ - BriefReportWidget \ - ShiftWidget \ - DevRealDataWidget \ - RobotCtrlWidget \ - IpcPlusWidget \ - LoadStatWidget \ - FaultRecordWidget \ - IpcWallWidget \ - BIWidget \ - UserManageWidget \ - AlarmManageWidget \ - HtmlBrowserWidget \ - HmiRollWidget \ - ScheduleWidget \ - AlarmAnalyzeWidget \ - FbdEditorWidget \ - AlarmShieldWidget \ - iDongOpsWidget \ - RelaySettingWidget \ - AssetWidget \ - ButtonGroupWidget \ - PointRealDataWidget \ - InverseTimeLimit \ - BreadcrumbNavWidget \ - HangPanelWidget \ - SimOptWidget \ - FaultRecallRecordWidget \ - PointLockWidget \ - MediaWidget \ - LimitOptWidget \ - DevSpePointWidget \ - DocumentManageWidget \ - WaveAnalyzeWidget \ - ChanStatusWidget \ - SerialDevStatusWidget \ - WebBrowserWidget \ - BusbarTemperatureWidget - -SequenceManageWidget.depends = SequenceWidget +#不要加上ordered,如有依赖需要,请用depends功能 + + +TEMPLATE=subdirs +SUBDIRS+= \ + IpcViewerWidget \ + DataOptWidget \ + AlarmWidget \ + EventWidget \ + WorkTicket \ + OrderManageWidget \ + NavigationWidget \ + TrendCurves \ + LinkCtrlWidget \ + SequenceWidget \ + SequenceManageWidget \ + ReportWidget \ + ConstCurves \ + AlarmStatisWidget \ + DevHisDataWidget \ + BriefReportWidget \ + ShiftWidget \ + DevRealDataWidget \ + RobotCtrlWidget \ + IpcPlusWidget \ + LoadStatWidget \ + FaultRecordWidget \ + IpcWallWidget \ + BIWidget \ + UserManageWidget \ + AlarmManageWidget \ + HtmlBrowserWidget \ + HmiRollWidget \ + ScheduleWidget \ + AlarmAnalyzeWidget \ + FbdEditorWidget \ + AlarmShieldWidget \ + iDongOpsWidget \ + RelaySettingWidget \ + AssetWidget \ + ButtonGroupWidget \ + PointRealDataWidget \ + InverseTimeLimit \ + BreadcrumbNavWidget \ + HangPanelWidget \ + SimOptWidget \ + FaultRecallRecordWidget \ + PointLockWidget \ + MediaWidget \ + LimitOptWidget \ + DevSpePointWidget \ + DocumentManageWidget \ + WaveAnalyzeWidget \ + ChanStatusWidget \ + SerialDevStatusWidget \ + WebBrowserWidget \ + BusbarTemperatureWidget + +SequenceManageWidget.depends = SequenceWidget